summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-07-16 11:45:35 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-07-17 08:59:23 +0000
commit552906b0f222c5d5dd11b9fd73829d510980461a (patch)
tree3a11e6ed0538a81dd83b20cf3a4783e297f26d91 /chromium/third_party/blink/renderer
parent1b05827804eaf047779b597718c03e7d38344261 (diff)
downloadqtwebengine-chromium-552906b0f222c5d5dd11b9fd73829d510980461a.tar.gz
BASELINE: Update Chromium to 83.0.4103.122
Change-Id: Ie3a82f5bb0076eec2a7c6a6162326b4301ee291e Reviewed-by: Michael Brüning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer')
-rw-r--r--chromium/third_party/blink/renderer/.style.yapf2
-rw-r--r--chromium/third_party/blink/renderer/BUILD.gn12
-rw-r--r--chromium/third_party/blink/renderer/DEPS11
-rw-r--r--chromium/third_party/blink/renderer/bindings/BUILD.gn127
-rw-r--r--chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.md64
-rw-r--r--chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt9
-rw-r--r--chromium/third_party/blink/renderer/bindings/PRESUBMIT.py14
-rw-r--r--chromium/third_party/blink/renderer/bindings/bindings.gni22
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/BUILD.gn259
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/DEPS5
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/V8BindingDesign.md2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/active_script_wrappable.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h7
-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.cc5
-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.cc8
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_element_custom.cc83
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_event_target_custom.cc67
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_html_all_collection_custom.cc1
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_message_channel_custom.cc66
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_shadow_root_custom.cc50
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_window_custom.cc6
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/dictionary.h15
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/dictionary_helper_for_core.cc16
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/generated.gni239
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/generated_code_helper.cc101
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/generated_code_helper.h79
-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/idl_types.h281
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/idl_types_base.h6
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/idl_types_test.cc9
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc20
-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.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler.cc11
-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_handler_for_content_attribute.cc2
-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.cc50
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/local_window_proxy.h20
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/module_record.cc48
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/module_record.h46
-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/native_value_traits.h111
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.cc419
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h1204
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.cc22
-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/rejected_promises.cc1
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/remote_window_proxy.cc8
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/remote_window_proxy.h4
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/scheduled_action.cc8
-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.cc16
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_controller.h5
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc9
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition_data.h24
-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.h6
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property.h281
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_base.cc236
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_base.h98
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_test.cc84
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.cc10
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h21
-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_source_code.cc2
-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.cc5
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_streamer.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc40
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_value.cc4
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_value.h21
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/script_wrappable_v8_gc_integration_test.cc9
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.cc6
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h19
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_color_params.cc52
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_color_params.h12
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc9
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h49
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_fuzzer.cc10
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.cc13
-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_deserializer.cc39
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.h8
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc47
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.h6
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc76
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/source_location.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/to_v8_for_core.cc59
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h22
-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/use_counter_callback.cc87
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v0_custom_element_constructor_builder.cc6
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v0_custom_element_constructor_builder.h6
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc25
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h122
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc13
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_context_snapshot.cc12
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.cc52
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.h39
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc67
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_html_constructor.cc6
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc29
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_delegate.cc8
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_delegate.h6
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_object_builder.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_object_parser.cc3
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_object_parser.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_page_popup_controller_binding.cc2
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_persistent_value_vector.h76
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc35
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner_test.cc166
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/v8_set_return_value_for_core.h52
-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.cc11
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/window_proxy.cc29
-rw-r--r--chromium/third_party/blink/renderer/bindings/core/v8/window_proxy.h12
-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.cc29
-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.h10
-rw-r--r--chromium/third_party/blink/renderer/bindings/generated_in_core.gni1099
-rw-r--r--chromium/third_party/blink/renderer/bindings/generated_in_modules.gni1373
-rw-r--r--chromium/third_party/blink/renderer/bindings/idl_in_core.gni683
-rw-r--r--chromium/third_party/blink/renderer/bindings/idl_in_modules.gni1026
-rw-r--r--chromium/third_party/blink/renderer/bindings/modules/BUILD.gn13
-rw-r--r--chromium/third_party/blink/renderer/bindings/modules/v8/BUILD.gn39
-rw-r--r--chromium/third_party/blink/renderer/bindings/modules/v8/custom/custom.gni3
-rw-r--r--chromium/third_party/blink/renderer/bindings/modules/v8/custom/v8_extendable_message_event_custom.cc102
-rw-r--r--chromium/third_party/blink/renderer/bindings/modules/v8/generated.gni41
-rw-r--r--chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc164
-rw-r--r--chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.h8
-rw-r--r--chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc134
-rw-r--r--chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.h4
-rw-r--r--chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc85
-rw-r--r--chromium/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc9
-rw-r--r--chromium/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.h3
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/BUILD.gn4
-rwxr-xr-xchromium/third_party/blink/renderer/bindings/scripts/aggregate_generated_bindings.py23
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/.style.yapf1
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/__init__.py47
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py406
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/clang_format.py63
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node.py717
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node_cxx.py456
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node_cxx_test.py211
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node_test.py181
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_accumulator.py20
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_context.py158
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_expr.py54
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_format.py21
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_utils.py178
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/dictionary.py875
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/enumeration.py360
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py4405
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/mako_renderer.py107
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/name_style.py34
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/path_manager.py180
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/style_format.py107
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/bind_gen/union.py188
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/blink_idl_lexer.py25
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/blink_idl_parser.py56
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/blink_idl_parser_test.py2
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/build_web_idl_database.py17
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/code_generator.py88
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/code_generator_v8.py117
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/collect_idl_files.py18
-rwxr-xr-xchromium/third_party/blink/renderer/bindings/scripts/compute_global_objects.py30
-rwxr-xr-xchromium/third_party/blink/renderer/bindings/scripts/compute_interfaces_info_individual.py139
-rwxr-xr-xchromium/third_party/blink/renderer/bindings/scripts/compute_interfaces_info_overall.py90
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.py56
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.pydeps6
-rwxr-xr-xchromium/third_party/blink/renderer/bindings/scripts/generate_event_interfaces.py59
-rwxr-xr-xchromium/third_party/blink/renderer/bindings/scripts/generate_global_constructors.py91
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/generate_high_entropy_list.py137
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/generate_high_entropy_list.pydeps51
-rwxr-xr-xchromium/third_party/blink/renderer/bindings/scripts/generate_init_partial_interfaces.py47
-rwxr-xr-xchromium/third_party/blink/renderer/bindings/scripts/generate_origin_trial_features.py120
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/generate_v8_context_snapshot_external_references.py162
-rwxr-xr-xchromium/third_party/blink/renderer/bindings/scripts/idl_compiler.py60
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/idl_definitions.py324
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/idl_definitions_test.py2
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/idl_reader.py38
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/idl_types.py127
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/idl_types_test.py169
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/idl_validator.py20
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/interface_dependency_resolver.py137
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/overload_set_algorithm.py11
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/overload_set_algorithm_test.py5
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/scripts.gni16
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/utilities.py140
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/v8_attributes.py458
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/v8_callback_function.py53
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/v8_callback_interface.py76
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/v8_dictionary.py245
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/v8_globals.py1
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/v8_interface.py981
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/v8_methods.py522
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/v8_types.py677
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/v8_union.py82
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/v8_utilities.py162
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/.style.yapf1
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/__init__.py24
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/attribute.py2
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/callback_function.py2
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/callback_interface.py8
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/code_generator_info.py7
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/composition_parts.py23
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/constant.py10
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/constructor.py20
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/database.py45
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/demonstration_and_testing.idl2
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/dictionary.py4
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/enumeration.py2
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/exposure.py61
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/extended_attribute.py42
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/extended_attribute_test.py1
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/file_io.py17
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/function_like.py20
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/idl_compiler.py292
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/idl_type.py303
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/idl_type_test.py6
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/interface.py351
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/ir_builder.py96
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/ir_map.py4
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/make_copy.py4
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/migration_adapter.idl4
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/namespace.py10
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/operation.py53
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/union.py53
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/user_defined_type.py2
-rw-r--r--chromium/third_party/blink/renderer/bindings/scripts/web_idl/validator.py1
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/attributes.cc.tmpl28
-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.tmpl2
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/dictionary_v8.cc.tmpl15
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/dictionary_v8.h.tmpl2
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/interface.cc.tmpl35
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/interface.h.tmpl17
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/interface_base.cc.tmpl1
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/methods.cc.tmpl27
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/union_container.cc.tmpl6
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/union_container.h.tmpl2
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/PRESUBMIT.py41
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/aria_properties.py4
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/blinkbuild/PRESUBMIT.py6
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/blinkbuild/name_style_converter.py19
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/blinkbuild/name_style_converter_test.py247
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/cluster.py5
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/core/css/OWNERS5
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/core/css/css_properties.py124
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/core/css/field_alias_expander.py6
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/core/css/make_css_primitive_value_unit_trie.py8
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/core/css/make_css_property_names.py68
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/core/css/make_css_tokenizer_codepoints.py64
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/core/css/make_css_value_id_mappings.py42
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/core/css/make_css_value_keywords.py31
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/core/css/make_cssom_types.py6
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/core/css/make_media_feature_names.py7
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/core/css/make_media_features.py23
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/core/css/make_style_shorthands.py27
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/core/css/parser/make_atrule_names.py5
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/core/css/properties/make_css_property_instances.py16
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/core/css/properties/make_css_property_subclasses.py10
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.cc.tmpl22
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.h.tmpl15
-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_property_names.cc.tmpl4
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/core/css/templates/css_property_names.h.tmpl6
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/core/style/OWNERS5
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/core/style/computed_style_fields.py30
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/core/style/make_computed_style_base.py194
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/gperf.py25
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/hasher.py16
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/in_file.py49
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/in_file_unittest.py17
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/in_generator.py8
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/json5_generator.py81
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/json5_generator_unittest.py35
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/keyword_utils.py19
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/license.py1
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/make_document_policy_features.py38
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/make_document_policy_features_unittest.py31
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/make_document_policy_features_util.py37
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/make_element_factory.py55
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/make_element_lookup_trie.py10
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/make_element_type_helpers.py21
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/make_event_factory.py96
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/make_feature_policy_helper.py155
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/make_html_entity_table.py22
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/make_instrumenting_probes.py83
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/make_internal_runtime_flags.py8
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/make_internal_settings.py28
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/make_names.py19
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/make_origin_trials.py34
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/make_qualified_names.py67
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/make_runtime_features.py60
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/make_runtime_features_utilities.py111
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/make_runtime_features_utilities_unittest.py112
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/make_settings.py16
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/make_style_builder.py4
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/media_feature_symbol.py2
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/name_utilities.py3
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/rule_bison.py143
-rwxr-xr-xchromium/third_party/blink/renderer/build/scripts/run_with_pythonpath.py4
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/scripts.gni10
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/template_expander.py18
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/templates/document_policy_features.cc.tmpl43
-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.tmpl12
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/templates/element_type_helpers.h.tmpl12
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/templates/event_factory.cc.tmpl8
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/templates/feature_policy_helper.cc.tmpl50
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/templates/instrumenting_probes_inl.h.tmpl4
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/templates/internal_runtime_flags.h.tmpl4
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/templates/internal_runtime_flags.idl.tmpl2
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/templates/make_names.h.tmpl2
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/templates/origin_trials.cc.tmpl68
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/templates/runtime_enabled_features.cc.tmpl32
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/templates/runtime_enabled_features.h.tmpl32
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/templates/runtime_enabled_features_test_helpers.h.tmpl45
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/templates/web_origin_trials.cc.tmpl3
-rw-r--r--chromium/third_party/blink/renderer/build/scripts/update_css_ranking.py109
-rw-r--r--chromium/third_party/blink/renderer/config.gni10
-rw-r--r--chromium/third_party/blink/renderer/controller/BUILD.gn70
-rw-r--r--chromium/third_party/blink/renderer/controller/blink_initializer.cc25
-rw-r--r--chromium/third_party/blink/renderer/controller/crash_memory_metrics_reporter_impl.cc30
-rw-r--r--chromium/third_party/blink/renderer/controller/crash_memory_metrics_reporter_impl.h9
-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.h2
-rw-r--r--chromium/third_party/blink/renderer/controller/highest_pmf_reporter.cc26
-rw-r--r--chromium/third_party/blink/renderer/controller/highest_pmf_reporter.h2
-rw-r--r--chromium/third_party/blink/renderer/controller/highest_pmf_reporter_test.cc15
-rw-r--r--chromium/third_party/blink/renderer/controller/memory_usage_monitor.cc4
-rw-r--r--chromium/third_party/blink/renderer/controller/memory_usage_monitor_mac.cc127
-rw-r--r--chromium/third_party/blink/renderer/controller/memory_usage_monitor_mac.h25
-rw-r--r--chromium/third_party/blink/renderer/controller/memory_usage_monitor_posix.cc (renamed from chromium/third_party/blink/renderer/controller/memory_usage_monitor_android.cc)44
-rw-r--r--chromium/third_party/blink/renderer/controller/memory_usage_monitor_posix.h (renamed from chromium/third_party/blink/renderer/controller/memory_usage_monitor_android.h)51
-rw-r--r--chromium/third_party/blink/renderer/controller/memory_usage_monitor_posix_test.cc (renamed from chromium/third_party/blink/renderer/controller/memory_usage_monitor_android_test.cc)11
-rw-r--r--chromium/third_party/blink/renderer/controller/memory_usage_monitor_win.cc55
-rw-r--r--chromium/third_party/blink/renderer/controller/memory_usage_monitor_win.h25
-rw-r--r--chromium/third_party/blink/renderer/controller/oom_intervention_impl_test.cc15
-rw-r--r--chromium/third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator.cc120
-rw-r--r--chromium/third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator.h2
-rw-r--r--chromium/third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator_test.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/BUILD.gn292
-rw-r--r--chromium/third_party/blink/renderer/core/DEPS23
-rw-r--r--chromium/third_party/blink/renderer/core/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/core/accessibility/BUILD.gn5
-rw-r--r--chromium/third_party/blink/renderer/core/accessibility/apply_dark_mode.cc31
-rw-r--r--chromium/third_party/blink/renderer/core/accessibility/apply_dark_mode_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/accessibility/ax_object_cache.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/accessibility/ax_object_cache.h20
-rw-r--r--chromium/third_party/blink/renderer/core/accessibility/ax_object_cache_base.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/accessibility/ax_object_cache_base.h4
-rw-r--r--chromium/third_party/blink/renderer/core/animation/BUILD.gn8
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animatable.cc68
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animatable.h11
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animatable.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation.cc1081
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation.h169
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation.idl14
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_effect.cc52
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_effect.h16
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_effect.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_effect_owner.h3
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_effect_test.cc34
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_input_helpers.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_sim_test.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_test.cc248
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_test_helper.cc49
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_time_delta.h3
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_timeline.cc240
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_timeline.h87
-rw-r--r--chromium/third_party/blink/renderer/core/animation/animation_timeline.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/animation/basic_shape_interpolation_functions.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/animation/compositor_animations.cc66
-rw-r--r--chromium/third_party/blink/renderer/core/animation/compositor_animations.h10
-rw-r--r--chromium/third_party/blink/renderer/core/animation/compositor_animations_test.cc67
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_color.h7
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_double.h8
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_filter_operations.h8
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_transform.h8
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_value.h5
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/css_animation.cc73
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/css_animation.h78
-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.cc226
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/css_animations.h60
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/css_animations_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/css_transition.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css/css_transition.h41
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_angle_interpolation_type.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_border_image_length_box_interpolation_type.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_clip_interpolation_type.cc35
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc39
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_default_interpolation_type.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_default_interpolation_type.h10
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_image_list_interpolation_type.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_image_slice_interpolation_type.cc37
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_interpolation_environment.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_interpolation_environment.h29
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_interpolation_type.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_interpolation_type.h2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_interpolation_types_map.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_interpolation_types_map.h2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_length_list_interpolation_type.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_offset_rotate_interpolation_type.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_percentage_interpolation_type.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_ray_interpolation_type.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_resolution_interpolation_type.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_rotate_interpolation_type.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_scale_interpolation_type.cc39
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.cc104
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.h11
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_size_list_interpolation_type.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.cc33
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_time_interpolation_type.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_translate_interpolation_type.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_var_cycle_interpolation_type.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/animation/css_visibility_interpolation_type.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/animation/document_animation.h6
-rw-r--r--chromium/third_party/blink/renderer/core/animation/document_animation.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/document_animations.cc121
-rw-r--r--chromium/third_party/blink/renderer/core/animation/document_animations.h33
-rw-r--r--chromium/third_party/blink/renderer/core/animation/document_animations_test.cc142
-rw-r--r--chromium/third_party/blink/renderer/core/animation/document_timeline.cc161
-rw-r--r--chromium/third_party/blink/renderer/core/animation/document_timeline.h72
-rw-r--r--chromium/third_party/blink/renderer/core/animation/document_timeline.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/animation/document_timeline_test.cc60
-rw-r--r--chromium/third_party/blink/renderer/core/animation/effect_input.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/animation/effect_model.cc2
-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.cc39
-rw-r--r--chromium/third_party/blink/renderer/core/animation/effect_stack.h23
-rw-r--r--chromium/third_party/blink/renderer/core/animation/effect_stack_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/animation/element_animations.cc64
-rw-r--r--chromium/third_party/blink/renderer/core/animation/element_animations.h14
-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.h15
-rw-r--r--chromium/third_party/blink/renderer/core/animation/interpolable_filter.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/animation/interpolable_shadow.h2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/interpolable_value.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/animation/interpolable_value.h23
-rw-r--r--chromium/third_party/blink/renderer/core/animation/interpolable_value_test.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/animation/interpolation_effect_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/animation/invalidatable_interpolation.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/animation/invalidatable_interpolation.h11
-rw-r--r--chromium/third_party/blink/renderer/core/animation/keyframe.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/keyframe_effect.cc262
-rw-r--r--chromium/third_party/blink/renderer/core/animation/keyframe_effect.h43
-rw-r--r--chromium/third_party/blink/renderer/core/animation/keyframe_effect.idl9
-rw-r--r--chromium/third_party/blink/renderer/core/animation/keyframe_effect_model.h45
-rw-r--r--chromium/third_party/blink/renderer/core/animation/keyframe_effect_model_test.cc44
-rw-r--r--chromium/third_party/blink/renderer/core/animation/keyframe_effect_options.idl1
-rw-r--r--chromium/third_party/blink/renderer/core/animation/keyframe_effect_test.cc55
-rw-r--r--chromium/third_party/blink/renderer/core/animation/list_interpolation_functions.cc109
-rw-r--r--chromium/third_party/blink/renderer/core/animation/list_interpolation_functions.h10
-rw-r--r--chromium/third_party/blink/renderer/core/animation/list_interpolation_functions_test.cc58
-rw-r--r--chromium/third_party/blink/renderer/core/animation/non_interpolable_value.h6
-rw-r--r--chromium/third_party/blink/renderer/core/animation/path_interpolation_functions.cc38
-rw-r--r--chromium/third_party/blink/renderer/core/animation/pending_animations.cc52
-rw-r--r--chromium/third_party/blink/renderer/core/animation/pending_animations.h3
-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.cc197
-rw-r--r--chromium/third_party/blink/renderer/core/animation/scroll_timeline.h67
-rw-r--r--chromium/third_party/blink/renderer/core/animation/scroll_timeline.idl6
-rw-r--r--chromium/third_party/blink/renderer/core/animation/scroll_timeline_options.idl1
-rw-r--r--chromium/third_party/blink/renderer/core/animation/scroll_timeline_test.cc345
-rw-r--r--chromium/third_party/blink/renderer/core/animation/scroll_timeline_util.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/animation/scroll_timeline_util.h5
-rw-r--r--chromium/third_party/blink/renderer/core/animation/scroll_timeline_util_test.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/animation/size_interpolation_functions.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/animation/string_keyframe.h33
-rw-r--r--chromium/third_party/blink/renderer/core/animation/svg_angle_interpolation_type.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/animation/svg_integer_interpolation_type.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/animation/svg_integer_optional_integer_interpolation_type.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/animation/svg_interpolation_environment.h15
-rw-r--r--chromium/third_party/blink/renderer/core/animation/svg_interpolation_type.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/animation/svg_length_interpolation_type.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/animation/svg_length_list_interpolation_type.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/animation/svg_number_interpolation_type.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/animation/svg_number_list_interpolation_type.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/animation/svg_number_optional_number_interpolation_type.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/animation/svg_path_interpolation_type.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/svg_path_seg_interpolation_functions.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/animation/svg_point_list_interpolation_type.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/animation/svg_rect_interpolation_type.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/animation/svg_transform_list_interpolation_type.cc59
-rw-r--r--chromium/third_party/blink/renderer/core/animation/svg_value_interpolation_type.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/animation/timing.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/animation/timing.h49
-rw-r--r--chromium/third_party/blink/renderer/core/animation/timing_calculations.h6
-rw-r--r--chromium/third_party/blink/renderer/core/animation/timing_input.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/animation/timing_input_test.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/animation/transition_interpolation.h11
-rw-r--r--chromium/third_party/blink/renderer/core/animation/transition_keyframe.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/animation/transition_keyframe.h22
-rw-r--r--chromium/third_party/blink/renderer/core/animation/underlying_length_checker.h2
-rw-r--r--chromium/third_party/blink/renderer/core/animation/worklet_animation_controller.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/animation/worklet_animation_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/animation_frame/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/core/animation_frame/worker_animation_frame_provider.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/animation_frame/worker_animation_frame_provider.h2
-rw-r--r--chromium/third_party/blink/renderer/core/aom/accessible_node.cc305
-rw-r--r--chromium/third_party/blink/renderer/core/aom/accessible_node.h206
-rw-r--r--chromium/third_party/blink/renderer/core/aom/accessible_node.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/aom/accessible_node_list.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/aom/accessible_node_list.h7
-rw-r--r--chromium/third_party/blink/renderer/core/aom/accessible_node_list.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/aom/computed_accessible_node.cc119
-rw-r--r--chromium/third_party/blink/renderer/core/aom/computed_accessible_node.h82
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/clipboard_utilities.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/clipboard_utilities.h2
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/clipboard_utilities_test.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_object.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_object.h5
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_object_item.cc56
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_object_item.h19
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_object_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_transfer.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_transfer.h6
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/data_transfer.idl2
-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/data_transfer_test.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/raw_system_clipboard.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/raw_system_clipboard.h41
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/system_clipboard.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/clipboard/system_clipboard.h21
-rw-r--r--chromium/third_party/blink/renderer/core/content_capture/content_capture_manager.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/content_capture/content_capture_manager.h15
-rw-r--r--chromium/third_party/blink/renderer/core/content_capture/content_capture_task.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/content_capture/content_capture_task.h11
-rw-r--r--chromium/third_party/blink/renderer/core/content_capture/content_capture_test.cc28
-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.gni8
-rw-r--r--chromium/third_party/blink/renderer/core/core_idl_files.gni24
-rw-r--r--chromium/third_party/blink/renderer/core/core_initializer.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/BUILD.gn25
-rw-r--r--chromium/third_party/blink/renderer/core/css/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/active_style_sheets.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/css/active_style_sheets.h3
-rw-r--r--chromium/third_party/blink/renderer/core/css/active_style_sheets_test.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/css/affected_by_pseudo_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/css.dict4
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_axis_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_basic_shape_values.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_basic_shape_values.h8
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_border_image_slice_value.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_border_image_slice_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_color_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_computed_style_declaration.cc44
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_computed_style_declaration.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_computed_style_declaration_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_content_distribution_value.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_content_distribution_value.h3
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_counter_value.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_counter_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_crossfade_value.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_crossfade_value.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_cursor_image_value.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_cursor_image_value.h3
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_custom_ident_value.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_custom_ident_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_custom_property_declaration.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_custom_property_declaration.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_default_style_sheets.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_default_style_sheets.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_font_face.cc12
-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.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_font_face_source.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_font_face_source.h10
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_font_face_src_value.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_font_face_src_value.h12
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_font_family_value.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_font_family_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_font_feature_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_font_selector.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_font_selector.h10
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_font_style_range_value.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_font_style_range_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_font_variation_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_function_value.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.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_gradient_value.h85
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_grid_auto_repeat_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_grid_integer_repeat_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_grid_line_names_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_grid_template_areas_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_identifier_value.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_identifier_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_image_generator_value.h2
-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_set_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_image_value.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_image_value.h46
-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.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_inherited_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_initial_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_invalid_variable_value.h2
-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.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_keyframe_shorthand_value.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_keyframe_shorthand_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_keyframes_rule.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_keyframes_rule.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_layout_function_value.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_layout_function_value.h3
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_light_dark_color_pair.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_math_expression_node.cc61
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_math_expression_node.h19
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_math_function_value.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_math_function_value.h4
-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.h2
-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.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_numeric_literal_value.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_numeric_literal_value.h2
-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.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_page_rule_test.cc11
-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.cc69
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_paint_value.h10
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_paint_value_test.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_path_value.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_path_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_pending_interpolation_value.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_pending_interpolation_value.h61
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_pending_interpolation_value_test.cc54
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_pending_substitution_value.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_pending_substitution_value.h9
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_primitive_value.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_primitive_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_primitive_value_mappings.h51
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_properties.json5484
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_properties_ranking.json58
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_property_equality.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_property_name.h8
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_property_name_test.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_property_rule.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_property_rule.h2
-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.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_property_value_set.h48
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_quad_value.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_quad_value.h16
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_ray_value.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_ray_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_reflect_value.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_reflect_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_rule.cc36
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_rule.h36
-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_segmented_font_face.cc69
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_segmented_font_face.h11
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_selector.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_selector.h10
-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_selector_watch_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_shadow_value.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_shadow_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_string_value.cc2
-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.cc46
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_style_declaration.h17
-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.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_style_sheet.cc43
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_style_sheet.h14
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_style_sheet.idl10
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_style_sheet_test.cc78
-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_definition.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_test_helpers.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_test_helpers.h3
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_timing_function_value.h11
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_to_length_conversion_data.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_to_length_conversion_data.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_unicode_range_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_unset_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_uri_value.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_uri_value.h10
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_uri_value_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_value.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_value.h35
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_value_keywords.json538
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_value_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_value_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_value_pair.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_value_pair.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_value_pool.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_value_pool.h11
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_variable_data.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_variable_reference_value.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_variable_reference_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_viewport_rule.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/css_viewport_rule.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/computed_style_property_map.cc160
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/computed_style_property_map.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/computed_style_property_map_test.cc54
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/cross_thread_color_value.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/cross_thread_unsupported_value.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_keyword_value.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_math_invert.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_math_max.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_math_max.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_math_min.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_math_min.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_math_negate.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_math_product.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_math_sum.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_matrix_component.cc2
-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_matrix_component.idl4
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_numeric_array.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_numeric_array.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_numeric_type.idl11
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_numeric_value.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_numeric_value.h8
-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_perspective.idl5
-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_position_value.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_resource_value.h4
-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_rotate.idl7
-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_scale.idl5
-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.idl5
-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_x.idl7
-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_skew_y.idl7
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_style_image_value.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_style_image_value.h3
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_style_value.cc3
-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.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_transform_value.h10
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_transform_value.idl3
-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_translate.idl7
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_unit_value.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_unparsed_value.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_unparsed_value.h15
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_unparsed_value.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_unsupported_color_value.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_unsupported_color_value.h7
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_unsupported_color_value_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_unsupported_style_value.h20
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_url_image_value.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_url_image_value.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/css_variable_reference_value.idl3
-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_deferred_image.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_deferred_image.h7
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map.cc6
-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/paint_worklet_style_property_map_test.cc6
-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/prepopulated_computed_style_property_map_test.cc38
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/style_property_map.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/style_property_map.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/style_property_map.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/style_property_map_read_only_main_thread.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/css/cssom/style_value_factory.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/css/document_style_sheet_collection.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/document_style_sheet_collector.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/document_style_sheet_collector.h3
-rw-r--r--chromium/third_party/blink/renderer/core/css/dom_window_css.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/css/dom_window_css.h3
-rw-r--r--chromium/third_party/blink/renderer/core/css/drag_update_test.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/css/element_rule_collector.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/css/element_rule_collector.h10
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face.cc83
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face.h11
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face.idl8
-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.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face_set.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face_set.h24
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face_set_document.cc28
-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.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face_set_load_event.h5
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face_set_load_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face_set_worker.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/font_face_source.h3
-rw-r--r--chromium/third_party/blink/renderer/core/css/fullscreen.css7
-rw-r--r--chromium/third_party/blink/renderer/core/css/inline_css_style_declaration.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/css/inline_css_style_declaration.h10
-rw-r--r--chromium/third_party/blink/renderer/core/css/invalidation/invalidation_set.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/css/invalidation/invalidation_set_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/css/invalidation/pending_invalidations.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/css/invalidation/pending_invalidations.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/invalidation/pending_invalidations_test.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/css/invalidation/style_invalidator_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/css/local_font_face_source.cc20
-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/mathml.css30
-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_feature_overrides.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_list.cc39
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_list.h29
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_list.idl6
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_evaluator.cc36
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_evaluator.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_evaluator_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_exp.cc42
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_exp.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_list.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_list.h10
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_list_event.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_list_event.idl4
-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.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_matcher.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_matcher.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_matcher_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_query_set_test.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_value_change.h19
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_values.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_values.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_values_dynamic.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/media_values_dynamic.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/offscreen_font_selector.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/css/offscreen_font_selector.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/page_rule_collector.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/css/page_rule_collector.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.cc31
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css.proto985
-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.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_parser.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_parser_context.cc40
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_parser_context.h32
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_parser_fast_paths.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_parser_impl.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_parser_impl.h10
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_parser_selector.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_parser_token.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_parser_token.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_property_parser.cc57
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_property_parser.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.cc481
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_property_parser_helpers.h52
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_property_parser_test.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_proto_converter.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_selector_parser.cc64
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_selector_parser.h9
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_selector_parser_test.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_supports_parser.cc262
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_supports_parser.h108
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/css_supports_parser_test.cc390
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/font_variant_east_asian_parser.h24
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/font_variant_ligatures_parser.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/font_variant_numeric_parser.h10
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/media_condition_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/media_query_parser.cc47
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/media_query_parser.h25
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/sizes_attribute_parser.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/sizes_attribute_parser.h7
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/sizes_attribute_parser_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/sizes_math_function_parser.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/sizes_math_function_parser.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/parser/sizes_math_function_parser_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/computed_style_utils.cc283
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/computed_style_utils.h15
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/css_direction_aware_resolver.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/css_direction_aware_resolver.h1
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc394
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/css_parsing_utils.h65
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/css_parsing_utils_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/css_property.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/css_property.h38
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/css_property_ref.cc3
-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.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/css_unresolved_property.h13
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhand.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/custom_property.cc6
-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/custom_property_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc876
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/longhands/variable.h3
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/shorthand.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/properties/shorthands/shorthands_custom.cc116
-rw-r--r--chromium/third_party/blink/renderer/core/css/property_registration.cc17
-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.h2
-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.h8
-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.cc247
-rw-r--r--chromium/third_party/blink/renderer/core/css/remote_font_face_source.h27
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/cascade_expansion.cc189
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/cascade_expansion.h143
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/cascade_expansion_test.cc636
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/cascade_filter.h101
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/cascade_filter_test.cc121
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/cascade_interpolations.h61
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/cascade_interpolations_test.cc46
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/cascade_map.cc70
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/cascade_map.h58
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/cascade_map_test.cc230
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/cascade_origin.h38
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/cascade_priority.h107
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/cascade_priority_test.cc249
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/cascade_resolver.cc72
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/cascade_resolver.h115
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/css_property_priority.h25
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/css_variable_animator.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/css_variable_resolver.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/css_variable_resolver.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/css_variable_resolver_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/element_resolve_context.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/element_resolve_context.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/element_style_resources.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/element_style_resources.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/font_builder.cc50
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/font_builder.h13
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/font_builder_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/font_style_resolver.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/match_request.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/match_result.cc31
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/match_result.h67
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/match_result_test.cc236
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/matched_properties_cache.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/media_query_result.h16
-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/selector_filter_parent_scope.h9
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/selector_filter_parent_scope_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_adjuster.cc197
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_adjuster_test.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_animator.cc78
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_animator.h53
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc96
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_builder_converter.h19
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_cascade.cc663
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_cascade.h491
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc1225
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_resolver.cc1053
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_resolver.h43
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_resolver_state.h34
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc126
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_rule_usage_tracker.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/style_rule_usage_tracker.h7
-rw-r--r--chromium/third_party/blink/renderer/core/css/resolver/viewport_style_resolver.cc12
-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.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/rule_feature_set.h4
-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.cc58
-rw-r--r--chromium/third_party/blink/renderer/core/css/rule_set.h15
-rw-r--r--chromium/third_party/blink/renderer/core/css/rule_set_test.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/css/selector_checker.cc81
-rw-r--r--chromium/third_party/blink/renderer/core/css/selector_checker.h67
-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.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/selector_query_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/css/shadow_tree_style_sheet_collection.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_attribute_mutation_scope.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_change_reason.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_change_reason.h1
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_color.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_element.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_element_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_engine.cc306
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_engine.h49
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_engine_test.cc563
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_environment_variables_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_media.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_media.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_media.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_property_serializer.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_property_serializer.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_recalc_root.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_rule.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_rule.h33
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_rule_css_style_declaration.cc11
-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.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_rule_import.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_rule_keyframe.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_rule_keyframe.h2
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_rule_namespace.h6
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_sheet_candidate.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_sheet_candidate.h4
-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.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/css/style_sheet_contents.h4
-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/svg.css7
-rw-r--r--chromium/third_party/blink/renderer/core/css/threaded/font_object_threaded_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/css/threaded/text_renderer_threaded_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/css/tree_scope_style_sheet_collection.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/css/tree_scope_style_sheet_collection.h4
-rw-r--r--chromium/third_party/blink/renderer/core/css/vision_deficiency.cc73
-rw-r--r--chromium/third_party/blink/renderer/core/css/vision_deficiency.h26
-rw-r--r--chromium/third_party/blink/renderer/core/css/webxr_overlay.css26
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/BUILD.gn21
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/DEPS3
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/display_lock.dict5
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/display_lock_budget.cc50
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/display_lock_budget.h73
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/display_lock_budget_test.cc608
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/display_lock_context.cc883
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/display_lock_context.h233
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc771
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/display_lock_fuzzer.cc50
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc176
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/display_lock_utilities.h29
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/display_lock_utilities_test.cc44
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/render_subtree_activation_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/strict_yielding_display_lock_budget.cc76
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/strict_yielding_display_lock_budget.h42
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/unyielding_display_lock_budget.cc41
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/unyielding_display_lock_budget.h29
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/yielding_display_lock_budget.cc97
-rw-r--r--chromium/third_party/blink/renderer/core/display_lock/yielding_display_lock_budget.h48
-rw-r--r--chromium/third_party/blink/renderer/core/dom/BUILD.gn6
-rw-r--r--chromium/third_party/blink/renderer/core/dom/abort_controller.idl6
-rw-r--r--chromium/third_party/blink/renderer/core/dom/aria_attributes.idl1
-rw-r--r--chromium/third_party/blink/renderer/core/dom/aria_relationship_attributes.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/beforeunload_event_listener.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/character_data.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/dom/character_data.h5
-rw-r--r--chromium/third_party/blink/renderer/core/dom/child_frame_disconnector.h4
-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.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/dom/child_node_list.h11
-rw-r--r--chromium/third_party/blink/renderer/core/dom/class_collection.h11
-rw-r--r--chromium/third_party/blink/renderer/core/dom/comment.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/dom/container_node.cc98
-rw-r--r--chromium/third_party/blink/renderer/core/dom/container_node.h80
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document.cc2349
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document.h535
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document.idl9
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_fragment.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_init.cc188
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_init.h89
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_lifecycle.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_lifecycle.h9
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_or_shadow_root.h10
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_or_shadow_root.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_shutdown_notifier.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_shutdown_notifier.h29
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_shutdown_observer.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_shutdown_observer.h35
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_statistics_collector.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_statistics_collector_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_test.cc243
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_timing.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/dom/document_timing.h3
-rw-r--r--chromium/third_party/blink/renderer/core/dom/dom_exception.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/dom_implementation.cc114
-rw-r--r--chromium/third_party/blink/renderer/core/dom/dom_implementation.h4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/dom_string_map.h15
-rw-r--r--chromium/third_party/blink/renderer/core/dom/element.cc970
-rw-r--r--chromium/third_party/blink/renderer/core/dom/element.h184
-rw-r--r--chromium/third_party/blink/renderer/core/dom/element.idl27
-rw-r--r--chromium/third_party/blink/renderer/core/dom/element_data.cc53
-rw-r--r--chromium/third_party/blink/renderer/core/dom/element_data.h69
-rw-r--r--chromium/third_party/blink/renderer/core/dom/element_rare_data.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/dom/element_rare_data.h16
-rw-r--r--chromium/third_party/blink/renderer/core/dom/element_test.cc34
-rw-r--r--chromium/third_party/blink/renderer/core/dom/element_traversal.h43
-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.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/custom_event.h3
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/custom_event.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event.h12
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_dispatcher.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_dispatcher.h8
-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.h3
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_queue.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_queue.h6
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_target.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_target.h8
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_target.idl7
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_target_impl.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_target_impl.h4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/tree_scope_event_context.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/dom/first_letter_pseudo_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/dom/flat_tree_traversal_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/dom/global_event_handlers.h8
-rw-r--r--chromium/third_party/blink/renderer/core/dom/global_event_handlers.idl6
-rw-r--r--chromium/third_party/blink/renderer/core/dom/icon_url.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/dom/icon_url.h22
-rw-r--r--chromium/third_party/blink/renderer/core/dom/idle_deadline_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/dom/layout_tree_builder.h4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/live_node_list.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/dom/live_node_list.h11
-rw-r--r--chromium/third_party/blink/renderer/core/dom/live_node_list_base.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/mutation_observer.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/dom/mutation_observer.h5
-rw-r--r--chromium/third_party/blink/renderer/core/dom/mutation_observer.idl9
-rw-r--r--chromium/third_party/blink/renderer/core/dom/mutation_observer_interest_group.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/mutation_observer_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/dom/mutation_record.h4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/named_node_map.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node.cc340
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node.h243
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node.idl6
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node_child_removal_tracker.h7
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node_computed_style.h7
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node_lists_node_data.h16
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node_rare_data.cc54
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node_rare_data.h124
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node_test.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/dom/node_with_index.h4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/nth_index_cache.h6
-rw-r--r--chromium/third_party/blink/renderer/core/dom/nth_index_cache_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/processing_instruction.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/dom/pseudo_element.cc89
-rw-r--r--chromium/third_party/blink/renderer/core/dom/pseudo_element.h6
-rw-r--r--chromium/third_party/blink/renderer/core/dom/pseudo_element_data.h20
-rw-r--r--chromium/third_party/blink/renderer/core/dom/range.cc35
-rw-r--r--chromium/third_party/blink/renderer/core/dom/range.h6
-rw-r--r--chromium/third_party/blink/renderer/core/dom/range.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/dom/range_test.cc35
-rw-r--r--chromium/third_party/blink/renderer/core/dom/scriptable_document_parser.h8
-rw-r--r--chromium/third_party/blink/renderer/core/dom/scripted_animation_controller.cc135
-rw-r--r--chromium/third_party/blink/renderer/core/dom/scripted_animation_controller.h43
-rw-r--r--chromium/third_party/blink/renderer/core/dom/scripted_animation_controller_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller.h8
-rw-r--r--chromium/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/dom/shadow_dom_v0_test.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/dom/shadow_root.cc33
-rw-r--r--chromium/third_party/blink/renderer/core/dom/shadow_root.h30
-rw-r--r--chromium/third_party/blink/renderer/core/dom/shadow_root.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/dom/shadow_root_init.idl4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/slot_assignment_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/static_node_list.h11
-rw-r--r--chromium/third_party/blink/renderer/core/dom/static_range_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/dom/synchronous_mutation_notifier.cc68
-rw-r--r--chromium/third_party/blink/renderer/core/dom/synchronous_mutation_notifier.h49
-rw-r--r--chromium/third_party/blink/renderer/core/dom/synchronous_mutation_observer.cc36
-rw-r--r--chromium/third_party/blink/renderer/core/dom/synchronous_mutation_observer.h38
-rw-r--r--chromium/third_party/blink/renderer/core/dom/tag_collection.h37
-rw-r--r--chromium/third_party/blink/renderer/core/dom/text.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/dom/text_link_colors.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/dom/traversal_range.h8
-rw-r--r--chromium/third_party/blink/renderer/core/dom/tree_scope.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/dom/tree_scope_adopter.h12
-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.h1
-rw-r--r--chromium/third_party/blink/renderer/core/dom/v0_insertion_point.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/dom/whitespace_attacher.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/dom/whitespace_attacher.h4
-rw-r--r--chromium/third_party/blink/renderer/core/dom/whitespace_attacher_test.cc54
-rw-r--r--chromium/third_party/blink/renderer/core/dom/xml_document.h7
-rw-r--r--chromium/third_party/blink/renderer/core/editing/caret_display_item_client_test.cc39
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/apply_block_element_command.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/apply_block_element_command_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/apply_style_command.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/apply_style_command_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/break_blockquote_command.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc89
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc53
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/composite_edit_command_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/delete_selection_command.cc102
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/delete_selection_command.h4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/delete_selection_command_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/document_exec_command.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/editing_command_test.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/editing_state.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/editing_state.h1
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/editor_command.cc78
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/editor_command.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/format_block_command.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/indent_outdent_command.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/insert_incremental_text_command.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/insert_incremental_text_command.h8
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/insert_incremental_text_command_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/insert_into_text_node_command.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/insert_line_break_command.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/insert_list_command.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/insert_list_command_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/insert_text_command.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/insert_text_command_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/move_commands.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/move_commands_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc84
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/replace_selection_command.h10
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/replace_selection_command_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/split_text_node_command.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/style_commands.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/typing_command.cc53
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/typing_command.h6
-rw-r--r--chromium/third_party/blink/renderer/core/editing/commands/undo_step.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/compute_layer_selection.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/editing/compute_layer_selection_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/editing/dom_selection.cc52
-rw-r--r--chromium/third_party/blink/renderer/core/editing/dom_selection.h4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/drag_caret.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/editing_behavior.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/editing/editing_style.cc95
-rw-r--r--chromium/third_party/blink/renderer/core/editing/editing_style.h9
-rw-r--r--chromium/third_party/blink/renderer/core/editing/editing_utilities.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/editing/editing_utilities.h3
-rw-r--r--chromium/third_party/blink/renderer/core/editing/editing_utilities_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/editor.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/editing/editor.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/editor_key_bindings.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/editing/editor_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/editing/element_inner_text.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/editing/element_inner_text_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ephemeral_range.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ephemeral_range.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/find_buffer.cc272
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/find_buffer.h16
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/find_in_page_coordinates.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/find_task_controller.cc104
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/find_task_controller.h28
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/text_finder.cc86
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/text_finder.h17
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/text_finder_test.cc106
-rw-r--r--chromium/third_party/blink/renderer/core/editing/frame_caret_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/frame_selection.cc75
-rw-r--r--chromium/third_party/blink/renderer/core/editing/frame_selection.h13
-rw-r--r--chromium/third_party/blink/renderer/core/editing/frame_selection_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/editing/granularity_strategy_test.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/editing/hit_testing_bidi_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/edit_context.cc83
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/edit_context.h66
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/edit_context.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/ime_text_span.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/ime_text_span.h8
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/ime_text_span_test.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/input_method_controller.cc154
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/input_method_controller.h18
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc572
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/text_format_update_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/text_format_update_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/text_update_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/ime/text_update_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/inline_box_position_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/editing/inline_box_traversal.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/editing/iterators/character_iterator_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/iterators/fully_clipped_state_stack.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.h6
-rw-r--r--chromium/third_party/blink/renderer/core/editing/iterators/text_iterator.cc35
-rw-r--r--chromium/third_party/blink/renderer/core/editing/iterators/text_iterator.h12
-rw-r--r--chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.h5
-rw-r--r--chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_test.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.h4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/keyboard_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/layout_selection.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/editing/layout_selection.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/layout_selection_test.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/editing/link_selection_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/editing/local_caret_rect_bidi_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/local_caret_rect_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_list_impl_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_test.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/composition_marker.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/composition_marker.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/composition_marker_test.cc67
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc58
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/document_marker_controller.h7
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/document_marker_controller_test.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/styleable_marker.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/styleable_marker.h6
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.h8
-rw-r--r--chromium/third_party/blink/renderer/core/editing/markers/text_match_marker_list_impl.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/editing/position.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/position_iterator.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/editing/position_iterator.h4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/position_iterator_test.cc256
-rw-r--r--chromium/third_party/blink/renderer/core/editing/relocatable_position.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/relocatable_position_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/reveal_selection_scope.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection.idl6
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_adjuster_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_controller.cc55
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_controller.h12
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_controller_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_editor.cc59
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_editor.h22
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_modifier.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_modifier.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_modifier_line.cc38
-rw-r--r--chromium/third_party/blink/renderer/core/editing/selection_template.h1
-rw-r--r--chromium/third_party/blink/renderer/core/editing/serializers/create_markup_options.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/serializers/markup_accumulator.cc36
-rw-r--r--chromium/third_party/blink/renderer/core/editing/serializers/markup_accumulator.h3
-rw-r--r--chromium/third_party/blink/renderer/core/editing/serializers/markup_formatter.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/serializers/markup_formatter.h1
-rw-r--r--chromium/third_party/blink/renderer/core/editing/serializers/serialization.cc48
-rw-r--r--chromium/third_party/blink/renderer/core/editing/serializers/serialization.h4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/serializers/styled_markup_accumulator.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/editing/serializers/styled_markup_accumulator.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.h6
-rw-r--r--chromium/third_party/blink/renderer/core/editing/serializers/text_offset.h4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/cold_mode_spell_check_requester.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/hot_mode_spell_check_requester.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/hot_mode_spell_check_requester.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.h12
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller_test.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/spell_checker.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/editing/spellcheck/spell_checker_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/state_machines/state_machine_util.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/editing/state_machines/state_machine_util_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.cc34
-rw-r--r--chromium/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.h7
-rw-r--r--chromium/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller_test.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/editing/surrounding_text.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/surrounding_text_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/editing/testing/editing_test_base.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/editing/testing/selection_sample.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/editing/testing/selection_sample_test.cc38
-rw-r--r--chromium/third_party/blink/renderer/core/editing/text_offset_mapping.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/editing/text_offset_mapping_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/editing/visible_position_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/editing/visible_selection_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/visible_units_line.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/editing/visible_units_line_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/visible_units_sentence_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/editing/visible_units_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/visible_units_word_test.cc106
-rw-r--r--chromium/third_party/blink/renderer/core/editing/web_substring_util.mm15
-rw-r--r--chromium/third_party/blink/renderer/core/events/after_print_event.h4
-rw-r--r--chromium/third_party/blink/renderer/core/events/animation_event.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/events/animation_event.h5
-rw-r--r--chromium/third_party/blink/renderer/core/events/animation_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/events/animation_playback_event.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/events/animation_playback_event.h16
-rw-r--r--chromium/third_party/blink/renderer/core/events/animation_playback_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/events/application_cache_error_event.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/events/application_cache_error_event.h5
-rw-r--r--chromium/third_party/blink/renderer/core/events/application_cache_error_event.idl3
-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.h10
-rw-r--r--chromium/third_party/blink/renderer/core/events/clipboard_event.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/events/clipboard_event.h5
-rw-r--r--chromium/third_party/blink/renderer/core/events/clipboard_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/events/composition_event.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/events/composition_event.h5
-rw-r--r--chromium/third_party/blink/renderer/core/events/composition_event.idl14
-rw-r--r--chromium/third_party/blink/renderer/core/events/drag_event.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/events/drag_event.h10
-rw-r--r--chromium/third_party/blink/renderer/core/events/drag_event.idl4
-rw-r--r--chromium/third_party/blink/renderer/core/events/error_event.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/events/error_event.h15
-rw-r--r--chromium/third_party/blink/renderer/core/events/error_event.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/events/event_type_names.json511
-rw-r--r--chromium/third_party/blink/renderer/core/events/focus_event.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/events/focus_event.h11
-rw-r--r--chromium/third_party/blink/renderer/core/events/focus_event.idl2
-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.h10
-rw-r--r--chromium/third_party/blink/renderer/core/events/hash_change_event.h4
-rw-r--r--chromium/third_party/blink/renderer/core/events/hash_change_event.idl2
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/core/events/input_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/events/keyboard_event.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/events/keyboard_event.h13
-rw-r--r--chromium/third_party/blink/renderer/core/events/keyboard_event.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/events/message_event.cc88
-rw-r--r--chromium/third_party/blink/renderer/core/events/message_event.h33
-rw-r--r--chromium/third_party/blink/renderer/core/events/message_event.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/events/message_event_test.cc105
-rw-r--r--chromium/third_party/blink/renderer/core/events/mouse_event.cc36
-rw-r--r--chromium/third_party/blink/renderer/core/events/mouse_event.h59
-rw-r--r--chromium/third_party/blink/renderer/core/events/mouse_event.idl34
-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/mutation_event.idl16
-rw-r--r--chromium/third_party/blink/renderer/core/events/navigator_events.h3
-rw-r--r--chromium/third_party/blink/renderer/core/events/overscroll_event.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/events/overscroll_event.h5
-rw-r--r--chromium/third_party/blink/renderer/core/events/overscroll_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/events/page_transition_event.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/events/page_transition_event.h5
-rw-r--r--chromium/third_party/blink/renderer/core/events/page_transition_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/events/pointer_event.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/events/pointer_event.h15
-rw-r--r--chromium/third_party/blink/renderer/core/events/pointer_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/events/pointer_event_factory.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/events/pointer_event_factory.h9
-rw-r--r--chromium/third_party/blink/renderer/core/events/pointer_event_factory_test.cc6
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/core/events/pop_state_event.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/events/progress_event.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/events/progress_event.h5
-rw-r--r--chromium/third_party/blink/renderer/core/events/progress_event.idl4
-rw-r--r--chromium/third_party/blink/renderer/core/events/promise_rejection_event.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/events/promise_rejection_event.h5
-rw-r--r--chromium/third_party/blink/renderer/core/events/promise_rejection_event.idl3
-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.h11
-rw-r--r--chromium/third_party/blink/renderer/core/events/security_policy_violation_event.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/events/security_policy_violation_event.h15
-rw-r--r--chromium/third_party/blink/renderer/core/events/security_policy_violation_event.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/text_event.idl10
-rw-r--r--chromium/third_party/blink/renderer/core/events/touch_event.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/events/touch_event.h12
-rw-r--r--chromium/third_party/blink/renderer/core/events/touch_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/events/touch_event_context.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/events/touch_event_context.h4
-rw-r--r--chromium/third_party/blink/renderer/core/events/touch_event_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/events/transition_event.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/events/transition_event.h5
-rw-r--r--chromium/third_party/blink/renderer/core/events/transition_event.idl2
-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.h10
-rw-r--r--chromium/third_party/blink/renderer/core/events/ui_event.idl13
-rw-r--r--chromium/third_party/blink/renderer/core/events/ui_event_with_key_state.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/events/ui_event_with_key_state.h7
-rw-r--r--chromium/third_party/blink/renderer/core/events/visual_viewport_resize_event.h6
-rw-r--r--chromium/third_party/blink/renderer/core/events/visual_viewport_scroll_event.h6
-rw-r--r--chromium/third_party/blink/renderer/core/events/web_input_event_conversion.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/events/web_input_event_conversion.h10
-rw-r--r--chromium/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc253
-rw-r--r--chromium/third_party/blink/renderer/core/events/wheel_event.cc33
-rw-r--r--chromium/third_party/blink/renderer/core/events/wheel_event.h22
-rw-r--r--chromium/third_party/blink/renderer/core/events/wheel_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/BUILD.gn12
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/PausingAndFreezing.md12
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/agent.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/agent.h18
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/agent_metrics_collector.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/agent_metrics_collector.h2
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_notifier.cc78
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_notifier.h65
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_observer.cc63
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/execution_context.cc260
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/execution_context.h144
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.cc96
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h (renamed from chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h)84
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.cc (renamed from chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.cc)32
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h (renamed from chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.h)27
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer_test.cc (renamed from chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer_test.cc)78
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/remote_security_context.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/remote_security_context.h10
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/security_context.cc237
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/security_context.h128
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/security_context_init.cc522
-rw-r--r--chromium/third_party/blink/renderer/core/execution_context/security_context_init.h117
-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.gn15
-rw-r--r--chromium/third_party/blink/renderer/core/exported/local_frame_client_impl.cc272
-rw-r--r--chromium/third_party/blink/renderer/core/exported/local_frame_client_impl.h71
-rw-r--r--chromium/third_party/blink/renderer/core/exported/local_frame_client_impl_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/exported/prerendering_test.cc424
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_array_buffer.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_console_message.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc61
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.h8
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_disallow_transition_scope.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_disallow_transition_scope_test.cc62
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_document.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_document_loader_impl.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_document_loader_impl.h5
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_document_subresource_filter_test.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_document_test.cc166
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_dom_message_event.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_element.cc34
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_element_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_external_widget_impl.cc96
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_external_widget_impl.h62
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_form_control_element.cc38
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_form_element_observer_impl.cc8
-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.cc64
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_frame_content_dumper.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_frame_serializer.cc345
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_frame_serializer_sanitization_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_frame_test.cc1498
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_history_item.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_hit_test_result.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_image.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_image_test.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_input_method_controller_impl.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_input_method_controller_impl.h7
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_local_frame_client.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_local_frame_client_test.cc126
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_navigation_params.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_node.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_node_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_page_importance_signals.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.cc146
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.h52
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_performance.cc40
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc169
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_plugin_container_impl.h40
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_plugin_container_test.cc209
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_plugin_document.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc198
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_remote_frame_impl.h39
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_scoped_user_gesture.cc43
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_scoped_window_focus_allowed_indicator.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_scoped_window_focus_allowed_indicator_test.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_settings_impl.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_settings_impl.h1
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc92
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_shared_worker_impl.h11
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_user_gesture_indicator.cc60
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_view_impl.cc507
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_view_impl.h145
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_view_test.cc532
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/document_policy.dict17
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/document_policy_corpus/11
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/document_policy_corpus/21
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/document_policy_features.json593
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/document_policy_fuzzer.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/document_policy_parser.cc182
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/document_policy_parser.h33
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/document_policy_parser_test.cc175
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/dom_document_policy.h4
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/dom_feature_policy.cc7
-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.dict7
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/feature_policy_features.json551
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/feature_policy_helper.h23
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/feature_policy_parser.cc63
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/feature_policy_parser.h19
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/feature_policy_parser_delegate.h2
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/feature_policy_test.cc560
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/iframe_policy.h6
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/layout_animations_policy.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/layout_animations_policy.h6
-rw-r--r--chromium/third_party/blink/renderer/core/feature_policy/policy_test.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/BUILD.gn6
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/DEPS3
-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/blob_bytes_consumer_test.cc31
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/body.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/body.h8
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/body_stream_buffer.cc94
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/body_stream_buffer.h49
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc142
-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_tee_test.cc27
-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/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_header_list.h2
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_manager.cc67
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_manager.h11
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_request_data.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_request_data.h23
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_response_data.cc82
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_response_data.h19
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/fetch_response_data_test.cc33
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/form_data_bytes_consumer.cc14
-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.cc37
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/global_fetch.cc6
-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/headers.idl5
-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.cc17
-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.cc152
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/request.h10
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/request.idl10
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/request_init.idl1
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/request_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/response.cc65
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/response.h4
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/response.idl8
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/response_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/trust_token.idl34
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/trust_token_to_mojom.cc90
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/trust_token_to_mojom.h37
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/window_fetch.idl4
-rw-r--r--chromium/third_party/blink/renderer/core/fetch/worker_fetch.idl4
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/blob.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/blob.idl9
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/file.cc75
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/file.h29
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/file.idl3
-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_list_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/file_reader.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/file_reader.h12
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/file_reader.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/file_reader_loader.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/file_reader_loader.h4
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/file_reader_sync.idl6
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/file_test.cc82
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/public_url_manager.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/public_url_manager.h10
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/public_url_manager_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/fileapi/url_file_api.h3
-rw-r--r--chromium/third_party/blink/renderer/core/frame/BUILD.gn24
-rw-r--r--chromium/third_party/blink/renderer/core/frame/DEPS6
-rw-r--r--chromium/third_party/blink/renderer/core/frame/PRESUBMIT.py75
-rw-r--r--chromium/third_party/blink/renderer/core/frame/ad_tracker.cc54
-rw-r--r--chromium/third_party/blink/renderer/core/frame/ad_tracker.h20
-rw-r--r--chromium/third_party/blink/renderer/core/frame/ad_tracker_test.cc173
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/browser_controls.cc46
-rw-r--r--chromium/third_party/blink/renderer/core/frame/browser_controls.h8
-rw-r--r--chromium/third_party/blink/renderer/core/frame/browser_controls_test.cc333
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/content_security_policy.cc300
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/content_security_policy.h128
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/content_security_policy_fuzzer.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc1028
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/csp_directive.h5
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc219
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.h80
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc348
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/csp_source.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/csp_source.h4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/csp_violation_report_body.h16
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.cc38
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.h8
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/navigation_initiator_impl.cc53
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/navigation_initiator_impl.h16
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/require_trusted_types_for_directive.cc36
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/require_trusted_types_for_directive.h28
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/require_trusted_types_for_directive_test.cc31
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/source_list_directive.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/source_list_directive.h9
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/source_list_directive_test.cc119
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/string_list_directive.cc65
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/string_list_directive.h13
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/string_list_directive_test.cc56
-rw-r--r--chromium/third_party/blink/renderer/core/frame/dactyloscoper.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/deprecation.cc228
-rw-r--r--chromium/third_party/blink/renderer/core/frame/deprecation.h8
-rw-r--r--chromium/third_party/blink/renderer/core/frame/deprecation_report_body.h4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/device_single_window_event_controller.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/frame/device_single_window_event_controller.h4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/document_loading_rendering_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/frame/document_policy_violation_report_body.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/frame/document_policy_violation_report_body.h50
-rw-r--r--chromium/third_party/blink/renderer/core/frame/document_policy_violation_report_body.idl17
-rw-r--r--chromium/third_party/blink/renderer/core/frame/dom_timer.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/frame/dom_timer.h12
-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.cc12
-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.cc46
-rw-r--r--chromium/third_party/blink/renderer/core/frame/dom_window.h6
-rw-r--r--chromium/third_party/blink/renderer/core/frame/embedded_content_view.h4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/event_handler_registry.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/frame/event_handler_registry.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/feature_policy_violation_report_body.h6
-rw-r--r--chromium/third_party/blink/renderer/core/frame/find_in_page.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/frame/find_in_page.h13
-rw-r--r--chromium/third_party/blink/renderer/core/frame/find_in_page_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame.cc49
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame.h131
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_client.h5
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_console.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_console.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_overlay_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_owner.h16
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_serializer.cc85
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.cc320
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.h62
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_test.cc64
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_test_helpers.cc198
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_test_helpers.h75
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_view.cc101
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_view.h14
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_view_auto_size_info.cc19
-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/fullscreen_controller.cc86
-rw-r--r--chromium/third_party/blink/renderer/core/frame/fullscreen_controller.h8
-rw-r--r--chromium/third_party/blink/renderer/core/frame/history.cc65
-rw-r--r--chromium/third_party/blink/renderer/core/frame/history.h12
-rw-r--r--chromium/third_party/blink/renderer/core/frame/history.idl7
-rw-r--r--chromium/third_party/blink/renderer/core/frame/hosts_using_features.cc172
-rw-r--r--chromium/third_party/blink/renderer/core/frame/hosts_using_features.h93
-rw-r--r--chromium/third_party/blink/renderer/core/frame/intervention.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/frame/intervention_report_body.h4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_dom_window.cc376
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_dom_window.h92
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame.cc824
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame.h174
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame_client.h85
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame_test.cc78
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc276
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h123
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc323
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame_view.cc704
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame_view.h97
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame_view_test.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/frame/location.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/frame/location.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/location.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/location_report_body.h23
-rw-r--r--chromium/third_party/blink/renderer/core/frame/mhtml_loading_test.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigation_rate_limiter.cc5
-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.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigator.h11
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigator.idl2
-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.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigator_ua.h (renamed from chromium/third_party/blink/renderer/core/frame/navigator_user_agent.h)15
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigator_ua.idl (renamed from chromium/third_party/blink/renderer/core/frame/navigator_user_agent.idl)7
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigator_ua_brand_version.idl10
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigator_ua_data.cc94
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigator_ua_data.h56
-rw-r--r--chromium/third_party/blink/renderer/core/frame/navigator_ua_data.idl14
-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_agent.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/frame/overlay_interstitial_ad_detector.cc109
-rw-r--r--chromium/third_party/blink/renderer/core/frame/overlay_interstitial_ad_detector.h32
-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.cc54
-rw-r--r--chromium/third_party/blink/renderer/core/frame/pausable_script_executor.h10
-rw-r--r--chromium/third_party/blink/renderer/core/frame/performance_monitor.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/frame/performance_monitor.h4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/performance_monitor_test.cc6
-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.h4
-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.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_dom_window.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame.cc365
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame.h69
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame_client.h22
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame_client_impl.h10
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame_owner.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame_owner.h12
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame_view.cc126
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame_view.h10
-rw-r--r--chromium/third_party/blink/renderer/core/frame/report.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/frame/report.h4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/reporting_context.cc43
-rw-r--r--chromium/third_party/blink/renderer/core/frame/reporting_context.h11
-rw-r--r--chromium/third_party/blink/renderer/core/frame/reporting_context_test.cc16
-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.h8
-rw-r--r--chromium/third_party/blink/renderer/core/frame/reporting_observer.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/frame/resize_viewport_anchor.h6
-rw-r--r--chromium/third_party/blink/renderer/core/frame/root_frame_viewport.cc174
-rw-r--r--chromium/third_party/blink/renderer/core/frame/root_frame_viewport.h46
-rw-r--r--chromium/third_party/blink/renderer/core/frame/root_frame_viewport_test.cc191
-rw-r--r--chromium/third_party/blink/renderer/core/frame/rotation_viewport_anchor.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/frame/rotation_viewport_anchor.h8
-rw-r--r--chromium/third_party/blink/renderer/core/frame/rotation_viewport_anchor_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/sandbox_flags.cc88
-rw-r--r--chromium/third_party/blink/renderer/core/frame/sandbox_flags.h15
-rw-r--r--chromium/third_party/blink/renderer/core/frame/scheduling.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/frame/screen.cc129
-rw-r--r--chromium/third_party/blink/renderer/core/frame/screen.h18
-rw-r--r--chromium/third_party/blink/renderer/core/frame/screen.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/screen_orientation_controller.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/screen_orientation_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/settings.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/frame/settings.h6
-rw-r--r--chromium/third_party/blink/renderer/core/frame/settings.json556
-rw-r--r--chromium/third_party/blink/renderer/core/frame/settings_delegate.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/smart_clip.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/smart_clip.h2
-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/test_report_body.h3
-rw-r--r--chromium/third_party/blink/renderer/core/frame/ua_data_values.idl (renamed from chromium/third_party/blink/renderer/core/frame/user_agent.idl)9
-rw-r--r--chromium/third_party/blink/renderer/core/frame/use_counter_helper.cc51
-rw-r--r--chromium/third_party/blink/renderer/core/frame/use_counter_helper.h13
-rw-r--r--chromium/third_party/blink/renderer/core/frame/use_counter_helper_test.cc43
-rw-r--r--chromium/third_party/blink/renderer/core/frame/user_activation.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/frame/user_activation.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/visual_viewport.cc102
-rw-r--r--chromium/third_party/blink/renderer/core/frame/visual_viewport.h30
-rw-r--r--chromium/third_party/blink/renderer/core/frame/visual_viewport_test.cc254
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_frame_serializer_impl.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_frame_serializer_impl.h6
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_frame_widget_base.cc421
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_frame_widget_base.h189
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc177
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.h53
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc516
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h94
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_view_frame_widget.cc86
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_view_frame_widget.h44
-rw-r--r--chromium/third_party/blink/renderer/core/frame/window.idl42
-rw-r--r--chromium/third_party/blink/renderer/core/frame/window_event_handlers.h2
-rw-r--r--chromium/third_party/blink/renderer/core/frame/window_event_handlers.idl1
-rw-r--r--chromium/third_party/blink/renderer/core/frame/window_or_worker_global_scope.cc85
-rw-r--r--chromium/third_party/blink/renderer/core/frame/window_or_worker_global_scope.h29
-rw-r--r--chromium/third_party/blink/renderer/core/frame/window_or_worker_global_scope.idl17
-rw-r--r--chromium/third_party/blink/renderer/core/fullscreen/document_fullscreen.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/fullscreen/document_fullscreen.h4
-rw-r--r--chromium/third_party/blink/renderer/core/fullscreen/document_fullscreen.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/fullscreen/element_fullscreen.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/fullscreen/element_fullscreen.h7
-rw-r--r--chromium/third_party/blink/renderer/core/fullscreen/element_fullscreen.idl6
-rw-r--r--chromium/third_party/blink/renderer/core/fullscreen/fullscreen.cc130
-rw-r--r--chromium/third_party/blink/renderer/core/fullscreen/fullscreen.h25
-rw-r--r--chromium/third_party/blink/renderer/core/fullscreen/fullscreen_options.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/fullscreen/scoped_allow_fullscreen.h2
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/BUILD.gn1
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_matrix.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_matrix.h4
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_matrix.idl11
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_matrix_read_only.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_matrix_read_only.h8
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_matrix_read_only.idl10
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_matrix_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_point.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_point.idl6
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_point_read_only.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_point_read_only.idl8
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_quad.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_quad.h2
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_quad.idl9
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_rect.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_rect.idl10
-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.h12
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_rect_read_only.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_rect_read_only.h9
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/dom_rect_read_only.idl6
-rw-r--r--chromium/third_party/blink/renderer/core/geometry/geometry_util.h38
-rw-r--r--chromium/third_party/blink/renderer/core/html/BUILD.gn126
-rw-r--r--chromium/third_party/blink/renderer/core/html/DEPS5
-rw-r--r--chromium/third_party/blink/renderer/core/html/anchor_element_metrics.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/html/anchor_element_metrics.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/anchor_element_metrics_sender.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/html/anchor_element_metrics_sender.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/anchor_element_metrics_test.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/html/aria_properties.json52
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.h5
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_draw_listener.h6
-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_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_image_source.h16
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h1
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc207
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h9
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc212
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.h30
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/image_data.cc209
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/image_data.h27
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/image_data.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/image_data_test.cc66
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/image_element_base.cc85
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/image_element_base.h14
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/text_metrics.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/text_metrics.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/cross_origin_attribute.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element.h6
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element_definition.cc48
-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_test_helpers.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.idl4
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element_registry_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h5
-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.cc31
-rw-r--r--chromium/third_party/blink/renderer/core/html/custom/element_internals.h12
-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/document_all_name_collection.h12
-rw-r--r--chromium/third_party/blink/renderer/core/html/document_name_collection.h12
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/DEPS4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/base_button_input_type.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/base_button_input_type.h1
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/base_temporal_input_type.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/base_temporal_input_type.h3
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/base_text_input_type.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/clear_button_element.h6
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/color_chooser.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/color_chooser_client.h3
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.cc58
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.h10
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.h8
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/color_input_type.cc29
-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_input_type.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_input_type.h1
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.h1
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_edit_element.h16
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_field_element.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_field_element.h8
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_local_input_type.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_local_input_type.h1
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_numeric_field_element.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/date_time_numeric_field_element.h3
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser.h8
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser_test.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/external_popup_menu_test.cc38
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/file_input_type.cc98
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/file_input_type.h6
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/file_input_type_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/form_controller.cc17
-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.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/form_data.idl3
-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.idl5
-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/html_button_element.cc64
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_button_element.h7
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_data_list_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_data_list_element.h3
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_data_list_options_collection.h12
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_field_set_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_form_control_element.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_form_control_element.h23
-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_control_element_with_state.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_form_control_element_with_state.h16
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_form_controls_collection.h5
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_form_element.cc218
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_form_element.h23
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_input_element.cc210
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_input_element.h55
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_input_element.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_input_element_test.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_label_element.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_opt_group_element.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_opt_group_element.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_option_element.cc29
-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_option_element.idl8
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_options_collection.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_options_collection.h17
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_select_element.cc1211
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_select_element.h86
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_select_element_test.cc235
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_text_area_element.cc43
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/html_text_area_element.h1
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/image_input_type.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/image_input_type.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/input_type.cc111
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/input_type.h21
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/input_type_view.cc39
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/input_type_view.h19
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.h3
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/labels_node_list.h1
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/listed_element.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc76
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/menu_list_inner_element.h21
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/month_input_type.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/month_input_type.h1
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc75
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.h17
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/number_input_type.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/option_list.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/option_list.h10
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/option_list_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/password_input_type_test.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/picker_indicator_element.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/picker_indicator_element.h18
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.h1
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/radio_input_type.cc82
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/radio_input_type.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/range_input_type.cc19
-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/PRESUBMIT.py10
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/resources/calendarPicker.js928
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/resources/calendar_picker_refresh.css120
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/resources/colorSuggestionPicker.css10
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.css68
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.js273
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/resources/color_picker_common.js3
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/resources/datetimelocal_picker.js94
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/resources/listPicker.css10
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/resources/listPicker.js4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/resources/month_picker.js107
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/resources/suggestionPicker.css4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/resources/suggestionPicker.js3
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/resources/time_picker.css72
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/resources/time_picker.js421
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/search_input_type.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/search_input_type.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/select_type.cc1252
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/select_type.h84
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc36
-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.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/step_range.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/step_range.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/step_range_test.cc33
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/submit_event.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/submit_event.h33
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/submit_event.idl12
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/submit_event_init.idl9
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/text_control_element.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/text_control_element.h12
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/text_control_element_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc33
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/text_control_inner_elements.h9
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/text_field_input_type.cc48
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/text_field_input_type.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/text_input_type.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/time_input_type.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/time_input_type.h3
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/type_ahead_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/week_input_type.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/week_input_type.h1
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_all_collection.h6
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_anchor_element.cc71
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_area_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_area_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_attribute_names.json56
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_body_element.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_br_element.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_collection.cc41
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_collection.h14
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_content_element_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_dialog_element.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_div_element.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_document.h7
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_element.cc155
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_element.h47
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_embed_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_frame_element.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_frame_element_base.cc59
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_frame_element_base.h31
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_frame_element_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_frame_owner_element.cc74
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_frame_owner_element.h36
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_frame_set_element.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_hr_element.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_iframe_element.cc148
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_iframe_element.h21
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_iframe_element.idl6
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_iframe_element_test.cc74
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_image_element.cc95
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_image_element.h29
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_image_element.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_image_fallback_helper.cc53
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_image_fallback_helper.h5
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_image_loader.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_li_element.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_link_element.cc31
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_link_element.h6
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_link_element_test.cc64
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_map_element.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_marquee_element.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_meta_element.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_meta_element_test.cc86
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_meter_element.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_meter_element.h1
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_object_element.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_object_element_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_or_foreign_element.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_paragraph_element.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_param_element.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_plugin_element.cc58
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_plugin_element.h21
-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_script_element.cc62
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_script_element.h16
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_script_element.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_script_element_test.cc69
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_slot_element.cc41
-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_slot_element.idl8
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_slot_element_test.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_source_element.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_style_element.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_style_element.h6
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_summary_element.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_summary_element.h1
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_table_cell_element.h19
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_table_col_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_table_col_element.h20
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_table_element.cc42
-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.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_table_rows_collection.h6
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_tag_collection.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_tag_collection.h12
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_tag_names.json53
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_ulist_element.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_view_source_document.cc6
-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.cc131
-rw-r--r--chromium/third_party/blink/renderer/core/html/image_document.h22
-rw-r--r--chromium/third_party/blink/renderer/core/html/image_document_test.cc38
-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_state_resolver.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.h10
-rw-r--r--chromium/third_party/blink/renderer/core/html/imports/html_imports_controller.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/html/imports/link_import.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/keywords.json57
-rw-r--r--chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer.h4
-rw-r--r--chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer_test.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc35
-rw-r--r--chromium/third_party/blink/renderer/core/html/link_rel_attribute.cc47
-rw-r--r--chromium/third_party/blink/renderer/core/html/link_rel_attribute.h6
-rw-r--r--chromium/third_party/blink/renderer/core/html/link_rel_attribute_test.cc97
-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.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/html/list_item_ordinal.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/html/list_item_ordinal.h8
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/autoplay_policy.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc87
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper.h27
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_audio_element.h1
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_audio_element.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_media_element.cc215
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_media_element.h65
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc104
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_media_element_test.cc63
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_media_test_helper.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_media_test_helper.h3
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_video_element.cc237
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_video_element.h46
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_video_element_persistent_test.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_video_element_test.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.cc231
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.h23
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector_test.cc80
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/media_document.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/media_element_parser_helpers.cc39
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/media_element_parser_helpers.h11
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/media_source.cc (renamed from chromium/third_party/blink/renderer/core/html/media/html_media_source.cc)6
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/media_source.h (renamed from chromium/third_party/blink/renderer/core/html/media/html_media_source.h)34
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/video_auto_fullscreen_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/video_filling_viewport_test.cc33
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.cc (renamed from chromium/third_party/blink/renderer/core/html/media/video_request_animation_frame.cc)14
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.h42
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/video_request_animation_frame.h50
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/video_wake_lock.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/video_wake_lock.h15
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/video_wake_lock_test.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/BUILD.gn7
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/OWNERS3
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/background_html_parser.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/background_html_parser.h8
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/css_preload_scanner.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_construction_site.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_document_parser.cc120
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_document_parser.h23
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_document_parser_loading_test.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_document_parser_test.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_element_stack.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_element_stack.h1
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_formatting_element_list.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_formatting_element_list.h1
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_parser_idioms.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_parser_metrics.cc104
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_parser_metrics.h56
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_parser_metrics_test.cc256
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_parser_options.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_parser_options.h3
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_parser_scheduler.cc34
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_parser_scheduler.h17
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc38
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner_fuzzer.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc34
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_srcset_parser.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_srcset_parser_test.cc152
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_tokenizer.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_tokenizer_fuzzer.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.cc52
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/html_tree_builder_simulator.cc14
-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_scripting_flag_policy.h16
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/preload_request.cc34
-rw-r--r--chromium/third_party/blink/renderer/core/html/parser/preload_request.h39
-rw-r--r--chromium/third_party/blink/renderer/core/html/plugin_document.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/html/plugin_document.h9
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/html_portal_element.cc66
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/html_portal_element.h25
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/html_portal_element.idl4
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/html_portal_element_test.cc71
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/portal_activate_event.cc4
-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_activate_event.idl6
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/portal_contents.cc58
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/portal_contents.h6
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/portal_host.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/portal_host.h5
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/portal_host.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/html/portal/portal_post_message_helper.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/rel_list.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/html/resources/controls_refresh.css75
-rw-r--r--chromium/third_party/blink/renderer/core/html/resources/forced_colors.css59
-rw-r--r--chromium/third_party/blink/renderer/core/html/resources/html.css14
-rw-r--r--chromium/third_party/blink/renderer/core/html/resources/images/calendar_icon.svg4
-rw-r--r--chromium/third_party/blink/renderer/core/html/resources/images/time_icon.svg4
-rw-r--r--chromium/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.h2
-rw-r--r--chromium/third_party/blink/renderer/core/html/subresource_redirect_test.cc120
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/audio_track.h8
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/automatic_track_selection.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/cue_timeline.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/cue_timeline.h6
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/html_track_element.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/inband_text_track.h6
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/loadable_text_track.h11
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/text_track.h19
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/text_track_container.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/text_track_list.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/text_track_list_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/track_event.cc7
-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_event.idl4
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/track_list_base.h1
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/video_track.h8
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.h3
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/vtt/vtt_element.cc2
-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.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing.cc140
-rw-r--r--chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing.h28
-rw-r--r--chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing_test.cc233
-rw-r--r--chromium/third_party/blink/renderer/core/html/window_name_collection.h12
-rw-r--r--chromium/third_party/blink/renderer/core/imagebitmap/DEPS3
-rw-r--r--chromium/third_party/blink/renderer/core/imagebitmap/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc390
-rw-r--r--chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap.h75
-rw-r--r--chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.cc56
-rw-r--r--chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.h24
-rw-r--r--chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_source.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_source.h7
-rw-r--r--chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_test.cc107
-rw-r--r--chromium/third_party/blink/renderer/core/input/BUILD.gn7
-rw-r--r--chromium/third_party/blink/renderer/core/input/event_handler.cc257
-rw-r--r--chromium/third_party/blink/renderer/core/input/event_handler.h74
-rw-r--r--chromium/third_party/blink/renderer/core/input/event_handler_test.cc318
-rw-r--r--chromium/third_party/blink/renderer/core/input/event_handling_util.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/input/event_handling_util.h5
-rw-r--r--chromium/third_party/blink/renderer/core/input/fallback_cursor_event_manager.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/input/fallback_cursor_event_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/core/input/fallback_cursor_event_manager_test.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/input/gesture_manager.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/input/gesture_manager.h2
-rw-r--r--chromium/third_party/blink/renderer/core/input/input_device_capabilities.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/input/input_device_capabilities.h5
-rw-r--r--chromium/third_party/blink/renderer/core/input/input_device_capabilities.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/input/keyboard_event_manager.cc78
-rw-r--r--chromium/third_party/blink/renderer/core/input/keyboard_event_manager.h5
-rw-r--r--chromium/third_party/blink/renderer/core/input/mouse_event_manager.cc122
-rw-r--r--chromium/third_party/blink/renderer/core/input/mouse_event_manager.h21
-rw-r--r--chromium/third_party/blink/renderer/core/input/mouse_wheel_event_manager.cc40
-rw-r--r--chromium/third_party/blink/renderer/core/input/mouse_wheel_event_manager.h6
-rw-r--r--chromium/third_party/blink/renderer/core/input/overscroll_behavior_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/input/pointer_event_manager.cc37
-rw-r--r--chromium/third_party/blink/renderer/core/input/pointer_event_manager.h12
-rw-r--r--chromium/third_party/blink/renderer/core/input/pointer_event_manager_test.cc54
-rw-r--r--chromium/third_party/blink/renderer/core/input/scroll_manager.cc75
-rw-r--r--chromium/third_party/blink/renderer/core/input/scroll_manager.h10
-rw-r--r--chromium/third_party/blink/renderer/core/input/scroll_snap_test.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/input/touch.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/input/touch.h18
-rw-r--r--chromium/third_party/blink/renderer/core/input/touch.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/input/touch_action_test.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/input/touch_action_util.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/input/touch_event_manager.cc46
-rw-r--r--chromium/third_party/blink/renderer/core/input/touch_event_manager.h8
-rw-r--r--chromium/third_party/blink/renderer/core/input/touch_event_manager_test.cc2
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/BUILD.gn14
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/DEPS5
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/OWNERS2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/console_message.cc99
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/console_message.h48
-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.cc34
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/dev_tools_emulator.h13
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/dev_tools_host.cc8
-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.cc179
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/devtools_agent.h42
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/devtools_session.cc113
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/devtools_session.h40
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/dom_editor.cc23
-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.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/dom_patch_support.h6
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspect_tool_highlight.html31
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspect_tools.cc47
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspect_tools.h6
-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.h6
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc141
-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.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_application_cache_agent.h8
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_audits_agent.cc190
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_audits_agent.h17
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_base_agent.h8
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_css_agent.cc260
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_css_agent.h8
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc448
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_dom_agent.h11
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_dom_debugger_agent.cc71
-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.cc130
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h11
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_emulation_agent.cc135
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_emulation_agent.h6
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_highlight.cc15
-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_io_agent.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_issue.cc52
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_issue.h42
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_issue_storage.cc42
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_issue_storage.h38
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_layer_tree_agent.cc114
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_layer_tree_agent.h6
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_log_agent.cc35
-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.cc18
-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.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_memory_agent.h6
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_network_agent.cc214
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_network_agent.h4
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc155
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h6
-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.cc107
-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.cc148
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_performance_agent.h12
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_protocol_config.json6
-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.cc13
-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.cc66
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_style_sheet.h26
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_task_runner.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_task_runner.h1
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_trace_events.cc72
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/inspector_trace_events.h8
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.h2
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/locale_controller.cc67
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/locale_controller.h30
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/main_thread_debugger.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/main_thread_debugger_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/network_resources_data.cc45
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/network_resources_data.h27
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/protocol_parser_test.cc77
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/thread_debugger.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/v8_inspector_string.cc39
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/v8_inspector_string.h76
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/worker_inspector_controller.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/inspector/worker_inspector_controller.h4
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.cc74
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.h35
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc242
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_geometry.h52
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc75
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observation.h17
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc93
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer.h33
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer.idl9
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.cc94
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.h40
-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_init.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/intersection_observer/intersection_observer_test.cc323
-rw-r--r--chromium/third_party/blink/renderer/core/layout/BUILD.gn38
-rw-r--r--chromium/third_party/blink/renderer/core/layout/DEPS2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/api/line_layout_list_marker.h11
-rw-r--r--chromium/third_party/blink/renderer/core/layout/custom_scrollbar.cc63
-rw-r--r--chromium/third_party/blink/renderer/core/layout/custom_scrollbar.h11
-rw-r--r--chromium/third_party/blink/renderer/core/layout/flexible_box_algorithm.cc235
-rw-r--r--chromium/third_party/blink/renderer/core/layout/flexible_box_algorithm.h49
-rw-r--r--chromium/third_party/blink/renderer/core/layout/floating_objects.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/layout/floating_objects.h9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/generated_children.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/geometry/physical_offset.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/geometry/physical_rect.h9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/grid.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/grid_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc54
-rw-r--r--chromium/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.h6
-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_location.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/hit_test_location.h1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/hit_test_result.cc35
-rw-r--r--chromium/third_party/blink/renderer/core/layout/hit_test_result.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_block.cc179
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_block.h28
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_block_flow.cc542
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_block_flow.h44
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_block_flow_line.cc80
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_block_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_box.cc680
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_box.h195
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_box_model_object.cc59
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_box_model_object.h7
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_box_model_object_test.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_box_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_button.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_button.h7
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_counter.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_custom_scrollbar_part.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_custom_scrollbar_part.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.cc430
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.h20
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_details_marker.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_embedded_content.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_embedded_content.h9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_fieldset.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_fieldset.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_file_upload_control.cc155
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_file_upload_control.h23
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_flexible_box.cc134
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_flexible_box.h15
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_flexible_box_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_flow_thread.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_frame_set.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_frame_set.h14
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_geometry_map.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_geometry_map_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_grid.cc33
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_grid.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_html_canvas.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_html_canvas.h1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_iframe.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_image.cc39
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_image.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_image_resource.cc7
-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.cc7
-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.cc96
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_inline.h5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_inline_test.cc129
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_inside_list_marker.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_inside_list_marker.h33
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_list_box.cc156
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_list_box.h76
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_list_item.cc147
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_list_item.h15
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_list_marker.cc224
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_list_marker.h32
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_media.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_media.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_menu_list.cc374
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_menu_list.h127
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_multi_column_set.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_multi_column_set.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.h8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_object.cc468
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_object.h305
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_object_child_list.cc39
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_object_factory.cc58
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_object_factory.h9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_object_test.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_outside_list_marker.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_outside_list_marker.h33
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_replaced.cc72
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_replaced.h10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_replaced_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_ruby_base.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_ruby_text.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_search_field.cc78
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_search_field.h51
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_shift_tracker.cc226
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_shift_tracker.h52
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_shift_tracker_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_slider.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_slider.h17
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_slider_container.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_slider_container.h1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_state.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_state.h5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table.cc99
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table.h6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_caption.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_cell.cc36
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_cell.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_cell_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_col.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_col.h14
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_row.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_row.h7
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_section.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_section.h7
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_table_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_text.cc162
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_text.h15
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_text_combine.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_text_control.cc66
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_text_control.h42
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_text_control_multi_line.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_text_control_single_line.h21
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_text_control_single_line_test.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_text_control_test.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_text_fragment_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_text_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_theme.cc85
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_theme.h30
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_theme_default.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_theme_default.h11
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_theme_mac.h10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_theme_mac.mm292
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_theme_test.cc94
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_tree_as_text.cc37
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_video.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_video.h9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_view.cc83
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_view.h34
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_view_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_vtt_cue.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/line/abstract_inline_text_box.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/line/abstract_inline_text_box_test.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/layout/line/inline_box.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/layout/line/inline_box.h1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/map_coordinates_test.cc39
-rw-r--r--chromium/third_party/blink/renderer/core/layout/min_max_size_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/min_max_sizes.cc (renamed from chromium/third_party/blink/renderer/core/layout/min_max_size.cc)4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/min_max_sizes.h (renamed from chromium/third_party/blink/renderer/core/layout/min_max_size.h)20
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.cc205
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.h44
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.h53
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.cc35
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_constraints.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_constraints.h6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.h10
-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.cc77
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.h31
-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/fragment_result_options.idl1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/intrinsic_sizes.idl15
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/intrinsic_sizes_result_options.idl10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/layout_child.idl4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/layout_fragment.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/layout_ng_custom.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/layout_ng_custom.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.cc29
-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.idl4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope_proxy.cc12
-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.cc79
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.h8
-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/exclusions/ng_layout_opportunity.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/exclusions/ng_layout_opportunity.h10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_margin_strut.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/layout_ng_text_test.cc42
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.cc295
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.h36
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_baseline.cc89
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_baseline.h207
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_baseline_test.cc76
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.cc48
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_caret_rect.cc60
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc202
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h108
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item_test.cc57
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.cc31
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.cc113
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.h19
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc315
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h32
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h22
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc1024
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h301
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor_test.cc122
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item_result.h29
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc93
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h26
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc219
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.h28
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm_test.cc193
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc56
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h55
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_data.h6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc123
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc56
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h58
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc234
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h12
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker_test.cc192
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.cc368
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_truncator.h42
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.cc83
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h21
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h38
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment_test.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_end_effect.h20
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_fragment_builder.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_fragment_builder.h6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_offset.h8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.cc206
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.h10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/layout_ng_fieldset.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/layout_ng_fieldset.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/layout_ng_flexible_box.cc49
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/layout_ng_flexible_box.h5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc125
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.h15
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/layout_ng_progress.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/layout_ng_table_caption.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/layout_ng_table_cell.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/README.md9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_inside_list_marker.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_inside_list_marker.h13
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc399
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h40
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker.cc61
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker_image.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker_image.h5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.cc41
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.h (renamed from chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker.h)28
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/list_marker.cc256
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/list_marker.h71
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.cc60
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.h29
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block.cc46
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block.h29
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.cc323
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.h31
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_layout_utils.cc97
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_layout_utils.h54
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.cc180
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.h42
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_layout_algorithm.cc42
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_layout_algorithm.h31
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc70
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h36
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_absolute_utils_test.cc443
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.h5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_block_break_token.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_block_break_token.h28
-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.cc427
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h48
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm_test.cc133
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_block_node.cc358
-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.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_box_fragment.cc73
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_box_fragment.h37
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc182
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h67
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc119
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.h23
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc358
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space.cc37
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h339
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h75
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc64
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc434
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.h56
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc1517
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_flex_child_iterator.cc38
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_flex_child_iterator.h53
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc858
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.h30
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_floats_utils.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.cc212
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.h141
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator_test.cc808
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_fragmentation_test.cc197
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc44
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h13
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc69
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h42
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_layout_result.h48
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_layout_result_caching_test.cc331
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_layout_utils.cc55
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc257
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_length_utils.h153
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_length_utils_test.cc40
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc135
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.h7
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_outline_utils.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.cc264
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h79
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.cc135
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h14
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc78
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h105
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_space_utils.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/ng_text_decoration_offset.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/layout/scroll_anchor.cc9
-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.cc110
-rw-r--r--chromium/third_party/blink/renderer/core/layout/scrollbars_test.cc178
-rw-r--r--chromium/third_party/blink/renderer/core/layout/shapes/shape.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/layout/shapes/shape.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/shapes/shape_outside_info.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/BUILD.gn4
-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_container.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_container.h8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_filter_primitive.cc (renamed from chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter_primitive.cc)20
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_filter_primitive.h (renamed from chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter_primitive.h)34
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.h8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_hidden_container.h3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_image.cc56
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_image.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc56
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h5
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_path.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_path.h1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.h26
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.cc62
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.h37
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.cc91
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.h66
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_gradient.cc79
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_gradient.h16
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_linear_gradient.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_linear_gradient.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_paint_server.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_paint_server.h10
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc85
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.h4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_radial_gradient.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_radial_gradient.h2
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_root.h6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_root_test.cc33
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_shape.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_shape.h1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_text.cc82
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_text.h9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_text_path.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/line/svg_inline_flow_box.h8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/line/svg_inline_text_box.h7
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/line/svg_root_inline_box.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/line/svg_root_inline_box.h8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc41
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_layout_support.h9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_layout_tree_as_text.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_marker_data.cc122
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_marker_data.h17
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_resources.cc319
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_resources.h64
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_resources_cache.cc66
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_resources_cache.h15
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_resources_cycle_solver.cc95
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_resources_cycle_solver.h43
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_text_chunk_builder.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_text_chunk_builder.h6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_text_layout_attributes_builder.cc10
-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.cc42
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/svg_text_query.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/layout/table_layout_algorithm_auto.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/layout/table_layout_algorithm_fixed.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/layout/text_autosizer.cc64
-rw-r--r--chromium/third_party/blink/renderer/core/layout/text_autosizer.h14
-rw-r--r--chromium/third_party/blink/renderer/core/layout/text_autosizer_test.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/layout/visual_rect_mapping_test.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/loader/BUILD.gn9
-rw-r--r--chromium/third_party/blink/renderer/core/loader/DEPS3
-rw-r--r--chromium/third_party/blink/renderer/core/loader/alternate_signed_exchange_resource_info.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/loader/appcache/application_cache.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/loader/appcache/application_cache.h4
-rw-r--r--chromium/third_party/blink/renderer/core/loader/appcache/application_cache.idl1
-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.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/appcache/application_cache_host_for_frame.cc27
-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.cc58
-rw-r--r--chromium/third_party/blink/renderer/core/loader/base_fetch_context.h23
-rw-r--r--chromium/third_party/blink/renderer/core/loader/base_fetch_context_test.cc73
-rw-r--r--chromium/third_party/blink/renderer/core/loader/cookie_jar.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/loader/cookie_jar.h13
-rw-r--r--chromium/third_party/blink/renderer/core/loader/cross_thread_resource_timing_info_copier.cc50
-rw-r--r--chromium/third_party/blink/renderer/core/loader/cross_thread_resource_timing_info_copier.h29
-rw-r--r--chromium/third_party/blink/renderer/core/loader/document_load_timing.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/document_load_timing.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/document_loader.cc354
-rw-r--r--chromium/third_party/blink/renderer/core/loader/document_loader.h42
-rw-r--r--chromium/third_party/blink/renderer/core/loader/document_loader_test.cc59
-rw-r--r--chromium/third_party/blink/renderer/core/loader/empty_clients.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/loader/empty_clients.h118
-rw-r--r--chromium/third_party/blink/renderer/core/loader/font_preload_manager.cc215
-rw-r--r--chromium/third_party/blink/renderer/core/loader/font_preload_manager.h89
-rw-r--r--chromium/third_party/blink/renderer/core/loader/font_preload_manager_test.cc486
-rw-r--r--chromium/third_party/blink/renderer/core/loader/form_submission.cc169
-rw-r--r--chromium/third_party/blink/renderer/core/loader/form_submission.h24
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_fetch_context.cc406
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_fetch_context.h34
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc200
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_load_request.cc35
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_load_request.h30
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_loader.cc492
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_loader.h80
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_loader_types.h1
-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/history_item.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/history_item.h4
-rw-r--r--chromium/third_party/blink/renderer/core/loader/http_equiv.cc17
-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.cc149
-rw-r--r--chromium/third_party/blink/renderer/core/loader/image_loader.h38
-rw-r--r--chromium/third_party/blink/renderer/core/loader/interactive_detector.cc278
-rw-r--r--chromium/third_party/blink/renderer/core/loader/interactive_detector.h87
-rw-r--r--chromium/third_party/blink/renderer/core/loader/interactive_detector_test.cc296
-rw-r--r--chromium/third_party/blink/renderer/core/loader/lazy_image_helper.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/loader/link_loader.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/loader/link_loader.h6
-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.cc51
-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.cc105
-rw-r--r--chromium/third_party/blink/renderer/core/loader/mixed_content_checker.h26
-rw-r--r--chromium/third_party/blink/renderer/core/loader/mixed_content_checker_test.cc86
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.cc49
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.h9
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.cc48
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.h6
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/module_script_creation_params.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h15
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/module_script_fetcher.cc31
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/module_script_fetcher.h18
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/module_script_loader.h12
-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.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc35
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h14
-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.cc62
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.cc42
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/worker_module_script_fetcher.h7
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/worklet_module_script_fetcher.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/loader/modulescript/worklet_module_script_fetcher.h4
-rw-r--r--chromium/third_party/blink/renderer/core/loader/navigation_policy.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/loader/navigation_policy.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/navigation_policy_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/loader/ping_loader.cc45
-rw-r--r--chromium/third_party/blink/renderer/core/loader/ping_loader_test.cc43
-rw-r--r--chromium/third_party/blink/renderer/core/loader/prefetched_signed_exchange_manager.cc59
-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.cc146
-rw-r--r--chromium/third_party/blink/renderer/core/loader/preload_helper.h14
-rw-r--r--chromium/third_party/blink/renderer/core/loader/prerenderer_client.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/loader/prerenderer_client.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints.cc9
-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/previews_resource_loading_hints_test.cc39
-rw-r--r--chromium/third_party/blink/renderer/core/loader/private/frame_client_hints_preferences_context.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/private/frame_client_hints_preferences_context.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/private/prerender_client.h (renamed from chromium/third_party/blink/renderer/platform/prerender_client.h)8
-rw-r--r--chromium/third_party/blink/renderer/core/loader/private/prerender_handle.cc120
-rw-r--r--chromium/third_party/blink/renderer/core/loader/private/prerender_handle.h36
-rw-r--r--chromium/third_party/blink/renderer/core/loader/programmatic_scroll_test.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/loader/progress_tracker.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/loader/progress_tracker.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/progress_tracker_test.cc105
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.cc9
-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/document_resource.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/document_resource.h18
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/font_resource.cc74
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/font_resource.h6
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/font_resource_test.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/image_resource.cc28
-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.cc52
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/image_resource_content.h9
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/image_resource_info.h4
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/image_resource_test.cc154
-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.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/script_resource.h4
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/xsl_style_sheet_resource.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource_load_observer_for_frame.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/loader/subresource_filter.cc33
-rw-r--r--chromium/third_party/blink/renderer/core/loader/subresource_filter.h10
-rw-r--r--chromium/third_party/blink/renderer/core/loader/subresource_integrity_helper.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/loader/text_resource_decoder_builder.cc4
-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.cc70
-rw-r--r--chromium/third_party/blink/renderer/core/loader/threadable_loader.h2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/threadable_loader_test.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/loader/threaded_icon_loader.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/loader/threaded_icon_loader.h6
-rw-r--r--chromium/third_party/blink/renderer/core/loader/threaded_icon_loader_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/loader/web_associated_url_loader_impl.cc53
-rw-r--r--chromium/third_party/blink/renderer/core/loader/web_associated_url_loader_impl.h4
-rw-r--r--chromium/third_party/blink/renderer/core/loader/web_associated_url_loader_impl_test.cc35
-rw-r--r--chromium/third_party/blink/renderer/core/loader/worker_fetch_context.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/loader/worker_fetch_context.h13
-rw-r--r--chromium/third_party/blink/renderer/core/loader/worker_resource_timing_notifier_impl.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/loader/worker_resource_timing_notifier_impl.h7
-rw-r--r--chromium/third_party/blink/renderer/core/mathml/BUILD.gn6
-rw-r--r--chromium/third_party/blink/renderer/core/mathml/mathml_attribute_names.json56
-rw-r--r--chromium/third_party/blink/renderer/core/mathml/mathml_element.cc53
-rw-r--r--chromium/third_party/blink/renderer/core/mathml/mathml_element.h61
-rw-r--r--chromium/third_party/blink/renderer/core/mathml/mathml_fraction_element.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/mathml/mathml_fraction_element.h30
-rw-r--r--chromium/third_party/blink/renderer/core/mathml/mathml_row_element.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/mathml/mathml_row_element.h25
-rw-r--r--chromium/third_party/blink/renderer/core/mathml/mathml_space_element.cc65
-rw-r--r--chromium/third_party/blink/renderer/core/mathml/mathml_space_element.h35
-rw-r--r--chromium/third_party/blink/renderer/core/mathml/mathml_tag_names.json552
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits_test.cc7
-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.h6
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/message_channel.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/message_port.cc49
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/message_port.h17
-rw-r--r--chromium/third_party/blink/renderer/core/messaging/message_port.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/mojo/BUILD.gn12
-rw-r--r--chromium/third_party/blink/renderer/core/mojo/mojo.cc36
-rw-r--r--chromium/third_party/blink/renderer/core/mojo/mojo.h3
-rw-r--r--chromium/third_party/blink/renderer/core/mojo/mojo.idl8
-rw-r--r--chromium/third_party/blink/renderer/core/mojo/mojo_handle.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/mojo/mojo_handle.idl10
-rw-r--r--chromium/third_party/blink/renderer/core/mojo/mojo_watcher.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/mojo/mojo_watcher.h10
-rw-r--r--chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.cc97
-rw-r--r--chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.h27
-rw-r--r--chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.cc4
-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/mojo/test/mojo_interface_request_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc104
-rw-r--r--chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h10
-rw-r--r--chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.idl6
-rw-r--r--chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc109
-rw-r--r--chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context.h22
-rw-r--r--chromium/third_party/blink/renderer/core/origin_trials/origin_trial_context_test.cc97
-rw-r--r--chromium/third_party/blink/renderer/core/origin_trials/origin_trials.h14
-rw-r--r--chromium/third_party/blink/renderer/core/page/BUILD.gn8
-rw-r--r--chromium/third_party/blink/renderer/core/page/DEPS6
-rw-r--r--chromium/third_party/blink/renderer/core/page/autoscroll_controller.cc96
-rw-r--r--chromium/third_party/blink/renderer/core/page/autoscroll_controller.h14
-rw-r--r--chromium/third_party/blink/renderer/core/page/autoscroll_controller_test.cc92
-rw-r--r--chromium/third_party/blink/renderer/core/page/chrome_client.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/page/chrome_client.h82
-rw-r--r--chromium/third_party/blink/renderer/core/page/chrome_client_impl.cc381
-rw-r--r--chromium/third_party/blink/renderer/core/page/chrome_client_impl.h76
-rw-r--r--chromium/third_party/blink/renderer/core/page/chrome_client_impl_test.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/page/color_page_popup_controller.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/page/color_page_popup_controller.h26
-rw-r--r--chromium/third_party/blink/renderer/core/page/color_page_popup_controller.idl13
-rw-r--r--chromium/third_party/blink/renderer/core/page/context_menu_controller.cc41
-rw-r--r--chromium/third_party/blink/renderer/core/page/context_menu_controller.h4
-rw-r--r--chromium/third_party/blink/renderer/core/page/context_menu_controller_test.cc31
-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.cc50
-rw-r--r--chromium/third_party/blink/renderer/core/page/drag_controller.cc62
-rw-r--r--chromium/third_party/blink/renderer/core/page/drag_controller.h10
-rw-r--r--chromium/third_party/blink/renderer/core/page/drag_controller_test.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/page/drag_data.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/drag_image.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/page/drag_image.h2
-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/event_with_hit_test_results.h4
-rw-r--r--chromium/third_party/blink/renderer/core/page/focus_controller.cc171
-rw-r--r--chromium/third_party/blink/renderer/core/page/focus_controller.h25
-rw-r--r--chromium/third_party/blink/renderer/core/page/focus_controller_test.cc39
-rw-r--r--chromium/third_party/blink/renderer/core/page/frame_tree.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/page/frame_tree.h4
-rw-r--r--chromium/third_party/blink/renderer/core/page/link_highlight.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/page/link_highlight.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/page.cc151
-rw-r--r--chromium/third_party/blink/renderer/core/page/page.h36
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_animator.cc56
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_animator.h18
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_popup_client.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_popup_client.h10
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_popup_controller.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_popup_controller.h8
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_popup_controller.idl1
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_popup_supplement.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_popup_supplement.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_visibility_notifier.cc39
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_visibility_notifier.h45
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_visibility_observer.cc36
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_visibility_observer.h23
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_widget_delegate.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/page/page_widget_delegate.h4
-rw-r--r--chromium/third_party/blink/renderer/core/page/plugin_data.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/page/plugin_data.h6
-rw-r--r--chromium/third_party/blink/renderer/core/page/plugin_data_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/page/pointer_lock_controller.cc147
-rw-r--r--chromium/third_party/blink/renderer/core/page/pointer_lock_controller.h23
-rw-r--r--chromium/third_party/blink/renderer/core/page/print_context.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/page/print_context.h6
-rw-r--r--chromium/third_party/blink/renderer/core/page/print_context_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/DEPS6
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.h7
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor_test.cc123
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/fragment_anchor.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/fragment_anchor.h5
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/main_thread_scrolling_reasons_test.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/overscroll_controller.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/overscroll_controller.h4
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/root_scroller_controller.cc4
-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.cc248
-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_into_view_test.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scroll_metrics_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scroll_state.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scroll_state.h15
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scroll_state.idl2
-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/scrolling_coordinator.cc114
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h25
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_context.cc60
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_context.h38
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc (renamed from chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc)354
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc52
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/snap_coordinator.h23
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/snap_coordinator_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.cc94
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.h8
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_metrics_test.cc37
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc327
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_finder.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector.h3
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_test.cc95
-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.cc8
-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/slot_scoped_traversal_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/page/spatial_navigation.cc61
-rw-r--r--chromium/third_party/blink/renderer/core/page/spatial_navigation.h5
-rw-r--r--chromium/third_party/blink/renderer/core/page/spatial_navigation_controller.cc88
-rw-r--r--chromium/third_party/blink/renderer/core/page/spatial_navigation_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/page/spatial_navigation_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/page/touch_adjustment.cc4
-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.cc6
-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.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/page/validation_message_overlay_delegate_test.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/page/viewport_description.h22
-rw-r--r--chromium/third_party/blink/renderer/core/page/viewport_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/paint/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/DEPS7
-rw-r--r--chromium/third_party/blink/renderer/core/paint/README.md66
-rw-r--r--chromium/third_party/blink/renderer/core/paint/background_image_geometry.cc101
-rw-r--r--chromium/third_party/blink/renderer/core/paint/background_image_geometry.h11
-rw-r--r--chromium/third_party/blink/renderer/core/paint/block_flow_paint_invalidator.cc36
-rw-r--r--chromium/third_party/blink/renderer/core/paint/block_painter.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/paint/block_painter_test.cc260
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_border_painter.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_model_object_painter.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_model_object_painter.h4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_paint_invalidator.cc75
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_paint_invalidator_test.cc113
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_painter.cc76
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_painter.h12
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_painter_base.cc153
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_painter_base.h24
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_painter_test.cc148
-rw-r--r--chromium/third_party/blink/renderer/core/paint/clip_path_clipper.cc33
-rw-r--r--chromium/third_party/blink/renderer/core/paint/clip_path_clipper.h3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc270
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h34
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc201
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc34
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.h1
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc87
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc124
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.h1
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater_test.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_test.cc324
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_as_text.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.h1
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.h1
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc55
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h10
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor_test.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/paint/css_mask_painter.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/paint/custom_scrollbar_theme.cc44
-rw-r--r--chromium/third_party/blink/renderer/core/paint/custom_scrollbar_theme.h11
-rw-r--r--chromium/third_party/blink/renderer/core/paint/document_marker_painter.cc90
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ellipsis_box_painter.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/embedded_object_painter.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/filter_effect_builder.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h6
-rw-r--r--chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/paint/fragment_data.h17
-rw-r--r--chromium/third_party/blink/renderer/core/paint/frame_paint_timing.h2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/frame_painter.h2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/image_element_timing.cc65
-rw-r--r--chromium/third_party/blink/renderer/core/paint/image_element_timing.h15
-rw-r--r--chromium/third_party/blink/renderer/core/paint/image_element_timing_test.cc44
-rw-r--r--chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector.h5
-rw-r--r--chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector_test.cc183
-rw-r--r--chromium/third_party/blink/renderer/core/paint/image_painter.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/paint/inline_box_painter_base.h4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/inline_flow_box_painter.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/paint/inline_flow_box_painter.h6
-rw-r--r--chromium/third_party/blink/renderer/core/paint/inline_text_box_painter.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/paint/largest_contentful_paint_calculator.cc34
-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/line_box_list_painter.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/paint/link_highlight_impl.cc50
-rw-r--r--chromium/third_party/blink/renderer/core/paint/link_highlight_impl.h8
-rw-r--r--chromium/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc53
-rw-r--r--chromium/third_party/blink/renderer/core/paint/list_marker_painter.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/paint/multi_column_set_painter.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/README.md19
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc1377
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h233
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter_test.cc58
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_fieldset_painter.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_fieldset_painter.h1
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.h13
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.cc84
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.h45
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_mathml_painter.cc58
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_mathml_painter.h33
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc72
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h5
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_test.cc56
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_traversal.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_traversal_test.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc265
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.h8
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter_test.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_text_painter.cc46
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_text_painter.h8
-rw-r--r--chromium/third_party/blink/renderer/core/paint/nine_piece_image_painter.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/paint/object_paint_invalidator.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/object_paint_invalidator_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/paint/object_painter.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/object_painter_base.cc53
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc159
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_controller_paint_test.cc300
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_controller_paint_test.h16
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_info.h12
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_invalidator.cc187
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_invalidator.h9
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer.cc243
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer.h49
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_clipper_test.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_fragment.h3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_painter.cc231
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_painter.h4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc570
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc600
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h105
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc283
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_stacking_node.cc71
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_test.cc76
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_phase.h4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc561
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder.h26
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc450
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_property_tree_printer.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc138
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_timing.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_timing.h13
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_timing_detector.cc58
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_timing_detector.h45
-rw-r--r--chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc219
-rw-r--r--chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h10
-rw-r--r--chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk_test.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/paint/replaced_painter.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/paint/scoped_paint_state.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/scoped_paint_state.h16
-rw-r--r--chromium/third_party/blink/renderer/core/paint/scoped_svg_paint_state.cc106
-rw-r--r--chromium/third_party/blink/renderer/core/paint/scoped_svg_paint_state.h31
-rw-r--r--chromium/third_party/blink/renderer/core/paint/scrollable_area_painter.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/paint/scrollable_area_painter.h8
-rw-r--r--chromium/third_party/blink/renderer/core/paint/selection_painting_utils.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_container_painter.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_filter_painter.cc160
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_filter_painter.h27
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_foreign_object_painter.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_image_painter.cc52
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_inline_flow_box_painter.cc31
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_inline_text_box_painter.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_mask_painter.cc66
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_mask_painter.h15
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_model_object_painter.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_model_object_painter.h18
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_root_inline_box_painter.cc38
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_root_painter.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_shape_painter.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_shape_painter.h3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_text_painter.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_text_painter.h5
-rw-r--r--chromium/third_party/blink/renderer/core/paint/table_painter_test.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/paint/table_row_painter.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/paint/table_row_painter.h5
-rw-r--r--chromium/third_party/blink/renderer/core/paint/table_section_painter.cc4
-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_style.h6
-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.cc55
-rw-r--r--chromium/third_party/blink/renderer/core/paint/text_painter_base.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/paint/theme_painter.cc169
-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.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/paint/video_painter_test.cc82
-rw-r--r--chromium/third_party/blink/renderer/core/paint/view_painter.cc270
-rw-r--r--chromium/third_party/blink/renderer/core/paint/view_painter.h17
-rw-r--r--chromium/third_party/blink/renderer/core/paint/view_painter_test.cc230
-rw-r--r--chromium/third_party/blink/renderer/core/precompile_core.h12
-rw-r--r--chromium/third_party/blink/renderer/core/probe/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/core/probe/async_task_id.h7
-rw-r--r--chromium/third_party/blink/renderer/core/probe/core_probes.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/probe/core_probes.h11
-rw-r--r--chromium/third_party/blink/renderer/core/probe/core_probes.json59
-rw-r--r--chromium/third_party/blink/renderer/core/probe/core_probes.pidl6
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/BUILD.gn3
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observation.cc73
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observation.h13
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observer.cc100
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observer.h20
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observer.idl7
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observer_box_options.h12
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observer_controller.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observer_controller.h17
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observer_entry.cc103
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observer_entry.h27
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observer_entry.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observer_options.idl15
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observer_size.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observer_size.h32
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observer_size.idl12
-rw-r--r--chromium/third_party/blink/renderer/core/resize_observer/resize_observer_test.cc166
-rw-r--r--chromium/third_party/blink/renderer/core/scheduler_integration_tests/frame_throttling_test.cc155
-rw-r--r--chromium/third_party/blink/renderer/core/scheduler_integration_tests/scheduler_affecting_features_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/script/BUILD.gn30
-rw-r--r--chromium/third_party/blink/renderer/core/script/classic_pending_script.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/script/document_modulator_impl.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/script/document_modulator_impl.h3
-rw-r--r--chromium/third_party/blink/renderer/core/script/document_write_intervention.cc19
-rw-r--r--chromium/third_party/blink/renderer/core/script/dynamic_module_resolver.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h4
-rwxr-xr-xchromium/third_party/blink/renderer/core/script/generate_lapi_grdp.py153
-rw-r--r--chromium/third_party/blink/renderer/core/script/import_map.cc300
-rw-r--r--chromium/third_party/blink/renderer/core/script/import_map.h35
-rw-r--r--chromium/third_party/blink/renderer/core/script/js_module_script.h3
-rw-r--r--chromium/third_party/blink/renderer/core/script/layered_api.cc113
-rw-r--r--chromium/third_party/blink/renderer/core/script/layered_api.h57
-rw-r--r--chromium/third_party/blink/renderer/core/script/layered_api_module.h29
-rw-r--r--chromium/third_party/blink/renderer/core/script/layered_api_resources.h76
-rw-r--r--chromium/third_party/blink/renderer/core/script/layered_api_test.cc93
-rw-r--r--chromium/third_party/blink/renderer/core/script/mock_script_element_base.h7
-rw-r--r--chromium/third_party/blink/renderer/core/script/modulator.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/script/modulator.h14
-rw-r--r--chromium/third_party/blink/renderer/core/script/modulator_impl_base.cc93
-rw-r--r--chromium/third_party/blink/renderer/core/script/modulator_impl_base.h11
-rw-r--r--chromium/third_party/blink/renderer/core/script/module_map_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/script/module_record_resolver_impl.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/script/module_record_resolver_impl.h11
-rw-r--r--chromium/third_party/blink/renderer/core/script/module_script_test.cc206
-rw-r--r--chromium/third_party/blink/renderer/core/script/parsed_specifier.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/script/parsed_specifier.h4
-rw-r--r--chromium/third_party/blink/renderer/core/script/pending_import_map.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/.eslintrc.js341
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/PRESUBMIT.py34
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/README.md48
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/blank/index.mjs0
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/internal/reflection.mjs63
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/switch/README.md3
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/switch/face_utils.mjs56
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/switch/index.mjs221
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/switch/style.mjs304
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/switch/track.mjs70
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/toast/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/toast/index.mjs277
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/docs/README.md297
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/docs/roaming-slot.pngbin36729 -> 0 bytes
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/find-element.mjs104
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/index.mjs55
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/sets.mjs50
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/visibility-manager.mjs453
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/OWNERS5
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/async_iterator.mjs94
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/idb_utils.mjs107
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/index.mjs242
-rw-r--r--chromium/third_party/blink/renderer/core/script/resources/layered_api/resources.grdp23
-rw-r--r--chromium/third_party/blink/renderer/core/script/script.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/script/script.h3
-rw-r--r--chromium/third_party/blink/renderer/core/script/script_element_base.h9
-rw-r--r--chromium/third_party/blink/renderer/core/script/script_loader.cc86
-rw-r--r--chromium/third_party/blink/renderer/core/script/script_loader.h3
-rw-r--r--chromium/third_party/blink/renderer/core/script/script_runner.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/script/script_runner.h24
-rw-r--r--chromium/third_party/blink/renderer/core/script/script_runner_test.cc34
-rw-r--r--chromium/third_party/blink/renderer/core/script/value_wrapper_synthetic_module_script.cc50
-rw-r--r--chromium/third_party/blink/renderer/core/script/value_wrapper_synthetic_module_script.h7
-rw-r--r--chromium/third_party/blink/renderer/core/script/worker_modulator_impl.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/script/worker_modulator_impl.h3
-rw-r--r--chromium/third_party/blink/renderer/core/script/worklet_modulator_impl.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/script/worklet_modulator_impl.h3
-rw-r--r--chromium/third_party/blink/renderer/core/script/xml_parser_script_runner.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/BUILD.gn1
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/OWNERS2
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.cc7
-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_alignment.cc161
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_alignment.h62
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator.h4
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator_base.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator_base.h5
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.h6
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator_mac.h6
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator_mac.mm7
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_animator_test.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_test.cc (renamed from chromium/third_party/blink/renderer/core/scroll/scrolling_test.cc)66
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scroll_types.h77
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollable_area.cc238
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollable_area.h104
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollable_area_test.cc78
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar.cc76
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar.h17
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.h2
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_test_suite.h22
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme.cc74
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme.h42
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.h6
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura_test.cc104
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.h20
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.mm21
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.h9
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_mobile.h8
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_test.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h21
-rw-r--r--chromium/third_party/blink/renderer/core/scroll/web_scroll_into_view_params.cc122
-rw-r--r--chromium/third_party/blink/renderer/core/streams/PRESUBMIT.py9
-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.idl6
-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.h3
-rw-r--r--chromium/third_party/blink/renderer/core/streams/count_queuing_strategy.idl6
-rw-r--r--chromium/third_party/blink/renderer/core/streams/miscellaneous_operations.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/promise_handler.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/streams/queue_with_sizes.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/streams/queue_with_sizes.h1
-rw-r--r--chromium/third_party/blink/renderer/core/streams/queuing_strategy_common.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/readable_stream.idl6
-rw-r--r--chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller.h4
-rw-r--r--chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/streams/readable_stream_default_reader.idl9
-rw-r--r--chromium/third_party/blink/renderer/core/streams/readable_stream_reader.cc32
-rw-r--r--chromium/third_party/blink/renderer/core/streams/readable_stream_reader.h6
-rw-r--r--chromium/third_party/blink/renderer/core/streams/readable_stream_test.cc54
-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.h1
-rw-r--r--chromium/third_party/blink/renderer/core/streams/transferable_streams.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/streams/transferable_streams_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/streams/transform_stream.idl10
-rw-r--r--chromium/third_party/blink/renderer/core/streams/transform_stream_default_controller.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/streams/transform_stream_default_controller.h4
-rw-r--r--chromium/third_party/blink/renderer/core/streams/transform_stream_default_controller.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/streams/transform_stream_test.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/streams/underlying_sink_base.h24
-rw-r--r--chromium/third_party/blink/renderer/core/streams/underlying_sink_base.idl8
-rw-r--r--chromium/third_party/blink/renderer/core/streams/underlying_source_base.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/streams/underlying_source_base.h14
-rw-r--r--chromium/third_party/blink/renderer/core/streams/underlying_source_base.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/streams/writable_stream.cc96
-rw-r--r--chromium/third_party/blink/renderer/core/streams/writable_stream.h25
-rw-r--r--chromium/third_party/blink/renderer/core/streams/writable_stream.idl8
-rw-r--r--chromium/third_party/blink/renderer/core/streams/writable_stream_default_controller.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/streams/writable_stream_default_writer.cc143
-rw-r--r--chromium/third_party/blink/renderer/core/streams/writable_stream_default_writer.h10
-rw-r--r--chromium/third_party/blink/renderer/core/streams/writable_stream_default_writer.idl12
-rw-r--r--chromium/third_party/blink/renderer/core/streams/writable_stream_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/style/BUILD.gn1
-rw-r--r--chromium/third_party/blink/renderer/core/style/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/core/style/computed_style.cc182
-rw-r--r--chromium/third_party/blink/renderer/core/style/computed_style.h129
-rw-r--r--chromium/third_party/blink/renderer/core/style/computed_style_constants.h30
-rw-r--r--chromium/third_party/blink/renderer/core/style/computed_style_diff_functions.json522
-rw-r--r--chromium/third_party/blink/renderer/core/style/computed_style_extra_fields.json576
-rw-r--r--chromium/third_party/blink/renderer/core/style/computed_style_test.cc156
-rw-r--r--chromium/third_party/blink/renderer/core/style/content_data.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/style/content_data.h35
-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.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/style/filter_operation.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/style/filter_operation.h4
-rw-r--r--chromium/third_party/blink/renderer/core/style/filter_operations.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/style/filter_operations.h6
-rw-r--r--chromium/third_party/blink/renderer/core/style/grid_positions_resolver.cc125
-rw-r--r--chromium/third_party/blink/renderer/core/style/grid_positions_resolver.h4
-rw-r--r--chromium/third_party/blink/renderer/core/style/intrinsic_length.h58
-rw-r--r--chromium/third_party/blink/renderer/core/style/nine_piece_image.cc5
-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.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_difference.h56
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_difference_test.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_fetched_image.cc34
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_fetched_image.h5
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_fetched_image_set.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_fetched_image_set.h5
-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.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_generated_image.h5
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_image.h9
-rw-r--r--chromium/third_party/blink/renderer/core/style/style_pending_image.h5
-rw-r--r--chromium/third_party/blink/renderer/core/style/svg_computed_style.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/BUILD.gn2
-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_time.h13
-rw-r--r--chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.cc398
-rw-r--r--chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.h41
-rw-r--r--chromium/third_party/blink/renderer/core/svg/animation/smil_time_container_test.cc533
-rw-r--r--chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc308
-rw-r--r--chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element.h93
-rw-r--r--chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element_test.cc121
-rw-r--r--chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_fe_image.cc153
-rw-r--r--chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_fe_image.h20
-rw-r--r--chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc47
-rw-r--r--chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.h49
-rw-r--r--chromium/third_party/blink/renderer/core/svg/graphics/svg_image.cc137
-rw-r--r--chromium/third_party/blink/renderer/core/svg/graphics/svg_image.h14
-rw-r--r--chromium/third_party/blink/renderer/core/svg/graphics/svg_image_chrome_client.h12
-rw-r--r--chromium/third_party/blink/renderer/core/svg/graphics/svg_image_for_container.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/svg/graphics/svg_image_for_container.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/graphics/svg_image_test.cc32
-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.h6
-rw-r--r--chromium/third_party/blink/renderer/core/svg/properties/svg_list_property_helper.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/properties/svg_list_property_tear_off_helper.h10
-rw-r--r--chromium/third_party/blink/renderer/core/svg/properties/svg_property.h7
-rw-r--r--chromium/third_party/blink/renderer/core/svg/properties/svg_property_tear_off.h2
-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.cc5
-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.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_angle.h12
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animate_element.cc20
-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_animate_motion_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_angle.cc2
-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.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_color.h8
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration_base.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_href.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_href.h2
-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.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_animated_string.h2
-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_boolean.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.cc4
-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.cc2
-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_discard_element.cc49
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_discard_element.h52
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_discard_element.idl34
-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.h5
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_element.cc100
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_element.h66
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_element_rare_data.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_element_rare_data.h10
-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.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_blend_element.cc2
-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.cc7
-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.cc2
-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.cc2
-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.cc2
-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.cc7
-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.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_fe_light_element.h23
-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.cc2
-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.cc2
-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.cc16
-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.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.h8
-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_foreign_object_element_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_geometry_element.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_geometry_element.h19
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_gradient_element.cc8
-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.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_graphics_element.h15
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_image_element.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_image_element.h7
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_integer.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_integer.h8
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_integer_optional_integer.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_integer_optional_integer.h10
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_length.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_length.h13
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_length_context.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_length_context.h5
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_length_list.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_length_list.h8
-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.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_linear_gradient_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_marker_element.cc4
-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.cc4
-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.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_number.h8
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_number_list.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_number_list.h8
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_number_optional_number.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_number_optional_number.h10
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_path.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_path.h10
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_path_data.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_path_element.cc8
-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_path_parser.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_pattern_element.cc15
-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_point.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_point_list.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_point_list.h8
-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.h21
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_radial_gradient_element.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_radial_gradient_element.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_rect.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_rect.h8
-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.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_resource.h7
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_resource_client.h10
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_script_element.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_script_element.h10
-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_string.h2
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_string_list_tear_off.h10
-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.cc17
-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_tag_names.json51
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_tests.cc20
-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.cc26
-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.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_transform_list.h8
-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.h1
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_uri_reference.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_uri_reference.h4
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_use_element.cc194
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_use_element.h14
-rw-r--r--chromium/third_party/blink/renderer/core/svg/svg_use_element_test.cc12
-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/unsafe_svg_attribute_sanitization_test.cc20
-rw-r--r--chromium/third_party/blink/renderer/core/testing/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/core/testing/color_scheme_helper.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/testing/color_scheme_helper.h9
-rw-r--r--chromium/third_party/blink/renderer/core/testing/core_unit_test_helper.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/testing/core_unit_test_helper.h11
-rw-r--r--chromium/third_party/blink/renderer/core/testing/data/Ahem.woff2bin0 -> 1684 bytes
-rw-r--r--chromium/third_party/blink/renderer/core/testing/data/test_touch_link_highlight.html3
-rw-r--r--chromium/third_party/blink/renderer/core/testing/data/touch-action-on-inline.html2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/data/touch-action-on-text.html5
-rw-r--r--chromium/third_party/blink/renderer/core/testing/death_aware_script_wrappable.h6
-rw-r--r--chromium/third_party/blink/renderer/core/testing/dictionary_test.cc76
-rw-r--r--chromium/third_party/blink/renderer/core/testing/dictionary_test.h10
-rw-r--r--chromium/third_party/blink/renderer/core/testing/dictionary_test.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/testing/dummy_modulator.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/testing/dummy_modulator.h21
-rw-r--r--chromium/third_party/blink/renderer/core/testing/dummy_page_holder.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/testing/dummy_page_holder.h7
-rw-r--r--chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.cc104
-rw-r--r--chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.h56
-rw-r--r--chromium/third_party/blink/renderer/core/testing/fake_remote_frame_host.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/testing/fake_remote_frame_host.h7
-rw-r--r--chromium/third_party/blink/renderer/core/testing/fake_web_plugin.h11
-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_dictionary.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/testing/internal_settings.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/testing/internal_settings.h2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/internals.cc474
-rw-r--r--chromium/third_party/blink/renderer/core/testing/internals.h35
-rw-r--r--chromium/third_party/blink/renderer/core/testing/internals.idl34
-rw-r--r--chromium/third_party/blink/renderer/core/testing/mock_clipboard_host.cc146
-rw-r--r--chromium/third_party/blink/renderer/core/testing/mock_clipboard_host.h72
-rw-r--r--chromium/third_party/blink/renderer/core/testing/module_test_base.cc31
-rw-r--r--chromium/third_party/blink/renderer/core/testing/module_test_base.h38
-rw-r--r--chromium/third_party/blink/renderer/core/testing/null_execution_context.cc44
-rw-r--r--chromium/third_party/blink/renderer/core/testing/null_execution_context.h30
-rw-r--r--chromium/third_party/blink/renderer/core/testing/origin_trials_test.h2
-rw-r--r--chromium/third_party/blink/renderer/core/testing/page_test_base.cc64
-rw-r--r--chromium/third_party/blink/renderer/core/testing/page_test_base.h31
-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.cc36
-rw-r--r--chromium/third_party/blink/renderer/core/testing/sim/sim_compositor.h28
-rw-r--r--chromium/third_party/blink/renderer/core/testing/sim/sim_request.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/testing/sim/sim_request.h3
-rw-r--r--chromium/third_party/blink/renderer/core/testing/sim/sim_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/testing/sim/sim_test.h1
-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/type_conversions.h1
-rw-r--r--chromium/third_party/blink/renderer/core/testing/v8/web_core_test_support.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/testing/wait_for_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/timezone/DEPS2
-rw-r--r--chromium/third_party/blink/renderer/core/timezone/timezone_controller.cc44
-rw-r--r--chromium/third_party/blink/renderer/core/timezone/timezone_controller.h4
-rw-r--r--chromium/third_party/blink/renderer/core/timing/BUILD.gn2
-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_timing.cc16
-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/measure_memory/measure_memory.idl7
-rw-r--r--chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_breakdown.idl12
-rw-r--r--chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.cc224
-rw-r--r--chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.h37
-rw-r--r--chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_entry.idl11
-rw-r--r--chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_options.idl10
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance.cc194
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance.h17
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance.idl6
-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.cc14
-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.cc76
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_mark.h15
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_mark.idl9
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_mark_test.cc23
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_navigation_timing.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_navigation_timing.h11
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_observer.cc88
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_observer.h11
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_observer.idl5
-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_observer_init.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_observer_test.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_resource_timing.cc68
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_resource_timing.h22
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_resource_timing_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_server_timing.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_server_timing.h8
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_timing.cc143
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_timing.h42
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_user_timing.cc85
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_user_timing.h2
-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.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/timing/profiler_group.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/profiler_group_test.cc32
-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.h11
-rw-r--r--chromium/third_party/blink/renderer/core/timing/window_performance.cc39
-rw-r--r--chromium/third_party/blink/renderer/core/timing/window_performance.h11
-rw-r--r--chromium/third_party/blink/renderer/core/timing/window_performance_test.cc78
-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_html.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_script.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_script_url.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.cc35
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.h30
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.idl11
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.cc49
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.h11
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.idl18
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_options.idl7
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc548
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_types_util.h91
-rw-r--r--chromium/third_party/blink/renderer/core/trustedtypes/trusted_types_util_test.cc275
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/BUILD.gn7
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.cc124
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h250
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h4
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.cc100
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h98
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.cc80
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.h59
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/typed_array.h240
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h103
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc50
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h46
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h39
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h131
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/dom_array_piece.cc78
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/dom_array_piece.h53
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/dom_data_view.cc49
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/dom_data_view.h29
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.h46
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/dom_typed_array.cc42
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/dom_typed_array.h192
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/flexible_array_buffer_view.h69
-rw-r--r--chromium/third_party/blink/renderer/core/typed_arrays/typed_flexible_array_buffer_view.h39
-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.h6
-rw-r--r--chromium/third_party/blink/renderer/core/url/url.idl4
-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/url/url_search_params.idl5
-rw-r--r--chromium/third_party/blink/renderer/core/workers/README.md6
-rw-r--r--chromium/third_party/blink/renderer/core/workers/abstract_worker.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/workers/abstract_worker.h13
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker.cc153
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker.h19
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc79
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h12
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc51
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.h5
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.cc1
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.h2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/dedicated_worker_test.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/workers/global_scope_creation_params.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/workers/global_scope_creation_params.h9
-rw-r--r--chromium/third_party/blink/renderer/core/workers/installed_scripts_manager.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/workers/installed_scripts_manager.h1
-rw-r--r--chromium/third_party/blink/renderer/core/workers/main_thread_worklet_test.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.h8
-rw-r--r--chromium/third_party/blink/renderer/core/workers/shared_worker.cc60
-rw-r--r--chromium/third_party/blink/renderer/core/workers/shared_worker.h5
-rw-r--r--chromium/third_party/blink/renderer/core/workers/shared_worker.idl6
-rw-r--r--chromium/third_party/blink/renderer/core/workers/shared_worker_client.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/workers/shared_worker_client.h2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/shared_worker_client_holder.cc42
-rw-r--r--chromium/third_party/blink/renderer/core/workers/shared_worker_client_holder.h21
-rw-r--r--chromium/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc52
-rw-r--r--chromium/third_party/blink/renderer/core/workers/shared_worker_global_scope.h5
-rw-r--r--chromium/third_party/blink/renderer/core/workers/shared_worker_reporting_proxy.cc18
-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.cc5
-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.cc14
-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_object_proxy.h2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/threaded_worklet_test.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker.idl6
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_backing_thread.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_classic_script_loader.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_classic_script_loader.h15
-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.cc109
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_global_scope.h22
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_global_scope.idl3
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_module_tree_client.cc7
-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.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_navigator.h21
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_navigator.idl1
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc86
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h48
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_thread.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_thread.h40
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_thread_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worker_thread_test_helper.h14
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worklet.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worklet.h12
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worklet.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worklet_global_scope.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/workers/worklet_global_scope.h5
-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.cc8
-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/BUILD.gn18
-rw-r--r--chromium/third_party/blink/renderer/core/xml/DocumentXMLTreeViewer.css15
-rw-r--r--chromium/third_party/blink/renderer/core/xml/DocumentXMLTreeViewer.js480
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/core/xml/document_xslt.cc8
-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.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/xml/dom_parser.h13
-rw-r--r--chromium/third_party/blink/renderer/core/xml/dom_parser.idl5
-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.cc152
-rw-r--r--chromium/third_party/blink/renderer/core/xml/parser/xml_document_parser.h21
-rw-r--r--chromium/third_party/blink/renderer/core/xml/parser/xml_document_parser_scope.h2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/parser/xml_errors.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/parser/xml_errors.h2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xml_serializer.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xml_serializer.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_evaluator.idl6
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_expression.cc8
-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.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_expression_node.h12
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_functions.cc59
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_functions_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_grammar.y237
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_grammar_generated.cc1987
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_grammar_generated.h1485
-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_ns_resolver.h3
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_ns_resolver.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_parser.cc157
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_parser.h11
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_path.cc8
-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.cc27
-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.cc21
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_step.h4
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_util.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_util.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.h6
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xsl_style_sheet.h43
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xsl_style_sheet_libxslt.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xslt_processor.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xslt_processor.h2
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xslt_processor.idl6
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/xmlhttprequest/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/core/xmlhttprequest/main_thread_disallow_synchronous_xhr_scope.cc30
-rw-r--r--chromium/third_party/blink/renderer/core/xmlhttprequest/main_thread_disallow_synchronous_xhr_scope.h28
-rw-r--r--chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc122
-rw-r--r--chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h14
-rw-r--r--chromium/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.idl4
-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.gn56
-rw-r--r--chromium/third_party/blink/renderer/modules/DEPS4
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/accessibility_object_model_test.cc36
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_enums.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_enums.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc631
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.h29
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object_test.cc57
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_list_box.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_list_box_option.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc26
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.cc34
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.h14
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_mock_object.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.cc564
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.h38
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_object.cc439
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_object.h42
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc350
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h59
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_object_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_position.cc19
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_radio_input.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_radio_input.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc42
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h16
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc47
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.cc79
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/ax_validation_message.h2
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/idls.gni5
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc43
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.cc28
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.h25
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_test.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/list-ax-layout-ng-disabled.txt49
-rw-r--r--chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/list-ax-layout-ng.txt (renamed from chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/list-ax.txt)0
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.cc4
-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.cc2
-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.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/idls.gni12
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc120
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.h22
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.cc27
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc53
-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/DEPS4
-rw-r--r--chromium/third_party/blink/renderer/modules/app_banner/OWNERS2
-rw-r--r--chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.cc51
-rw-r--r--chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.h27
-rw-r--r--chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/app_banner/idls.gni12
-rw-r--r--chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/audio_output_devices/idls.gni5
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.cc4
-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_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader_test.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc64
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h20
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.cc26
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/idls.gni22
-rw-r--r--chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.cc9
-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/idls.gni21
-rw-r--r--chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_event.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.h13
-rw-r--r--chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.cc7
-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_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_sync/sync_event.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/background_sync/sync_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/background_sync/sync_manager.cc18
-rw-r--r--chromium/third_party/blink/renderer/modules/background_sync/sync_manager.h14
-rw-r--r--chromium/third_party/blink/renderer/modules/background_sync/sync_manager.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/badging/OWNERS7
-rw-r--r--chromium/third_party/blink/renderer/modules/badging/README.md25
-rw-r--r--chromium/third_party/blink/renderer/modules/badging/idls.gni8
-rw-r--r--chromium/third_party/blink/renderer/modules/badging/navigator_badge.cc78
-rw-r--r--chromium/third_party/blink/renderer/modules/badging/navigator_badge.h22
-rw-r--r--chromium/third_party/blink/renderer/modules/badging/navigator_badge.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/badging/worker_navigator_badge.idl16
-rw-r--r--chromium/third_party/blink/renderer/modules/battery/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/battery/battery_manager.cc18
-rw-r--r--chromium/third_party/blink/renderer/modules/battery/battery_manager.h15
-rw-r--r--chromium/third_party/blink/renderer/modules/battery/idls.gni7
-rw-r--r--chromium/third_party/blink/renderer/modules/battery/navigator_battery.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/battery/navigator_battery.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/beacon/idls.gni5
-rw-r--r--chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.h24
-rw-r--r--chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.cc138
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.h15
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h12
-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.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_error.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_error.h2
-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.h4
-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.cc132
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h23
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.cc60
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc33
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.cc36
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.h4
-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.gni27
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/PRESUBMIT.py6
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/constraints.py30
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/fuzz_integration_test.py10
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/fuzz_main_run.py73
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/fuzzer_helpers.py1
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/gatt_aliases.py3
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/parameter_fuzzer.py18
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/setup.py34
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/test_case_fuzzer.py8
-rw-r--r--chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/wbt_fakes.py57
-rw-r--r--chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc21
-rw-r--r--chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.idl7
-rw-r--r--chromium/third_party/blink/renderer/modules/broadcastchannel/idls.gni5
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache.cc60
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.cc21
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.idl4
-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_storage_error.cc61
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_error.h22
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache_test.cc17
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/cache_utils.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/global_cache_storage.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/idls.gni18
-rw-r--r--chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc126
-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.gn4
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc159
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h55
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.idl5
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc111
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h14
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_api_test.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc30
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h13
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc79
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.h14
-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.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/testing/internals_canvas_rendering_context_2d.cc18
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/testing/internals_canvas_rendering_context_2d.h24
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/testing/internals_canvas_rendering_context_2d.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas_fuzzer.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.cc19
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_support_webgl2_compute.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/idls.gni37
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module_support_webgl2_compute.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc126
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h26
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard.cc22
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.cc21
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard_item_options.idl (renamed from chromium/third_party/blink/renderer/modules/webgpu/gpu_extensions.idl)8
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc156
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.h26
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc30
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.h18
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc129
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.h34
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/idls.gni12
-rw-r--r--chromium/third_party/blink/renderer/modules/clipboard/navigator_clipboard.cc14
-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.idl7
-rw-r--r--chromium/third_party/blink/renderer/modules/compression/decompression_stream.idl7
-rw-r--r--chromium/third_party/blink/renderer/modules/compression/deflate_transformer.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/compression/idls.gni8
-rw-r--r--chromium/third_party/blink/renderer/modules/compression/inflate_transformer.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc47
-rw-r--r--chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/contacts_picker/idls.gni15
-rw-r--r--chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/content_index/content_index.cc45
-rw-r--r--chromium/third_party/blink/renderer/modules/content_index/content_index.h15
-rw-r--r--chromium/third_party/blink/renderer/modules/content_index/content_index.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/content_index/content_index_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/content_index/content_index_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/content_index/content_index_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/content_index/content_index_icon_loader.cc16
-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/idls.gni19
-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/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/DEPS3
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/README.md4
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.cc106
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.h22
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.cc38
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_set_options.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.idl4
-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.gni26
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/service_worker_global_scope_cookie_store.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/service_worker_registration_cookies.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/service_worker_registration_cookies.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/cookie_store/window_cookie_store.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/DEPS2
-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.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.h2
-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.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credential.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.cc25
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc90
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credential_metrics.cc (renamed from chromium/third_party/blink/renderer/modules/sms/sms_metrics.cc)10
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credential_metrics.h40
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credential_request_options.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc230
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container_test.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/federated_credential.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/federated_credential.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/idls.gni43
-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/otp_credential.cc23
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/otp_credential.h35
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/otp_credential.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/otp_credential_request_options.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/password_credential.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/credentialmanager/password_credential.idl5
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/crypto/BUILD.gn4
-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_histograms.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/crypto/crypto_key.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/crypto/crypto_result_impl.cc18
-rw-r--r--chromium/third_party/blink/renderer/modules/crypto/crypto_result_impl.h8
-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/idls.gni19
-rw-r--r--chromium/third_party/blink/renderer/modules/crypto/json_web_key.idl28
-rw-r--r--chromium/third_party/blink/renderer/modules/crypto/normalize_algorithm.cc395
-rw-r--r--chromium/third_party/blink/renderer/modules/crypto/normalize_algorithm.h23
-rw-r--r--chromium/third_party/blink/renderer/modules/crypto/rsa_other_primes_info.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/crypto/subtle_crypto.cc309
-rw-r--r--chromium/third_party/blink/renderer/modules/crypto/subtle_crypto.h42
-rw-r--r--chromium/third_party/blink/renderer/modules/crypto/subtle_crypto.idl25
-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.h4
-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/idls.gni13
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.cc67
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h25
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.cc26
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc11
-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/csspaint/paint_worklet_test.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc15
-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.cc4
-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.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.h16
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_acceleration.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_acceleration.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_rotation_rate.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_rotation_rate.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.cc9
-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.cc19
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_data.cc2
-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.cc22
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.h27
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.cc6
-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/idls.gni22
-rw-r--r--chromium/third_party/blink/renderer/modules/document_metadata/BUILD.gn12
-rw-r--r--chromium/third_party/blink/renderer/modules/document_metadata/DEPS3
-rw-r--r--chromium/third_party/blink/renderer/modules/document_metadata/OWNERS6
-rw-r--r--chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.h28
-rw-r--r--chromium/third_party/blink/renderer/modules/document_metadata/document_metadata_extractor.cc (renamed from chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.cc)68
-rw-r--r--chromium/third_party/blink/renderer/modules/document_metadata/document_metadata_extractor.h28
-rw-r--r--chromium/third_party/blink/renderer/modules/document_metadata/document_metadata_extractor_test.cc (renamed from chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor_test.cc)91
-rw-r--r--chromium/third_party/blink/renderer/modules/document_metadata/document_metadata_server.cc (renamed from chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_server.cc)18
-rw-r--r--chromium/third_party/blink/renderer/modules/document_metadata/document_metadata_server.h (renamed from chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_server.h)16
-rw-r--r--chromium/third_party/blink/renderer/modules/donottrack/idls.gni5
-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/idls.gni16
-rw-r--r--chromium/third_party/blink/renderer/modules/encoding/text_decoder.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/encoding/text_decoder.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/encoding/text_decoder.idl10
-rw-r--r--chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.cc24
-rw-r--r--chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.idl7
-rw-r--r--chromium/third_party/blink/renderer/modules/encoding/text_encoder.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/encoding/text_encoder.idl7
-rw-r--r--chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.idl7
-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.cc31
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/idls.gni26
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.idl4
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc131
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.h28
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.idl10
-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.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.cc47
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_media_capability.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc28
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.h15
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.cc2
-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.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc51
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/eventsource/event_source.cc32
-rw-r--r--chromium/third_party/blink/renderer/modules/eventsource/event_source.h19
-rw-r--r--chromium/third_party/blink/renderer/modules/eventsource/event_source.idl6
-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/eventsource/idls.gni7
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/BUILD.gn9
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/OWNERS4
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/web_ax_object.cc147
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/web_crypto_normalize.cc23
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/web_dom_file_system.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/web_testing_support.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/exported/web_user_media_request.cc137
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dedicated_worker_global_scope_file_system.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dev_tools_host_file_system.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/directory_entry.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/directory_entry.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/directory_entry.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/directory_entry_sync.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/directory_entry_sync.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/directory_reader.cc25
-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.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.h6
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc14
-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/dom_window_file_system.cc39
-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.h4
-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.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_writer.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_writer.h12
-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.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/idls.gni37
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/local_file_system.cc13
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/local_file_system.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/shared_worker_global_scope_file_system.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/sync_callback_helper.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/filesystem/window_file_system.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/BUILD.gn20
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/DEPS6
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/OWNERS6
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/README.md28
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/font_iterator.cc42
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/font_iterator.h35
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/font_iterator.idl14
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/font_iterator_entry.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/font_manager.cc50
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/font_manager.h31
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/font_manager.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/font_metadata.cc24
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/font_metadata.h53
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/font_metadata.idl14
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/idls.gni16
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/navigator_fonts.cc83
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/navigator_fonts.h28
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/navigator_fonts.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/font_access/worker_navigator_fonts.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/DEPS1
-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_axis_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_axis_event.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_button_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_button_event.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc13
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.idl5
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.h6
-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_list.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.cc18
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.h21
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/idls.gni22
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.cc26
-rw-r--r--chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc32
-rw-r--r--chromium/third_party/blink/renderer/modules/geolocation/geolocation.h13
-rw-r--r--chromium/third_party/blink/renderer/modules/geolocation/geolocation.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.cc24
-rw-r--r--chromium/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.h14
-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/idls.gni14
-rw-r--r--chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/hid/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/modules/hid/hid.cc44
-rw-r--r--chromium/third_party/blink/renderer/modules/hid/hid.h11
-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.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/hid/hid_connection_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/hid/hid_connection_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/hid/hid_device.cc40
-rw-r--r--chromium/third_party/blink/renderer/modules/hid/hid_device.h8
-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/idls.gni21
-rw-r--r--chromium/third_party/blink/renderer/modules/hid/navigator_hid.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/hid/navigator_hid.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/idle/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/modules/idle/idle_detector.cc24
-rw-r--r--chromium/third_party/blink/renderer/modules/idle/idle_detector.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/idle/idle_detector.idl7
-rw-r--r--chromium/third_party/blink/renderer/modules/idle/idle_state.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/idle/idle_state.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/idle/idls.gni10
-rw-r--r--chromium/third_party/blink/renderer/modules/image_downloader/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/modules/image_downloader/image_downloader_impl.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/image_downloader/image_downloader_impl.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/image_downloader/multi_resolution_image_resource_fetcher.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/image_downloader/multi_resolution_image_resource_fetcher.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/imagecapture/idls.gni15
-rw-r--r--chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/imagecapture/image_capture.h18
-rw-r--r--chromium/third_party/blink/renderer/modules/imagecapture/image_capture.idl5
-rw-r--r--chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.cc8
-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/BUILD.gn4
-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.cc18
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_any.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor_with_value.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc36
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_database.h28
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_database.idl4
-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_factory.cc50
-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_index.idl10
-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.cc28
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.idl18
-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.cc4
-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.idl2
-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.cc28
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.h24
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_request.cc74
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_request.h29
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc33
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc35
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_value.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_value.h15
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.h11
-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.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idls.gni34
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.cc70
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc104
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/mock_web_idb_factory.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/web_idb_factory.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/web_idb_factory_impl.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/web_idb_factory_impl.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/installation/DEPS3
-rw-r--r--chromium/third_party/blink/renderer/modules/installedapp/idls.gni7
-rw-r--r--chromium/third_party/blink/renderer/modules/installedapp/installed_app_controller.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/installedapp/installed_app_controller.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/installedapp/navigator_installed_app.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/installedapp/navigator_installed_app.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/keyboard/idls.gni10
-rw-r--r--chromium/third_party/blink/renderer/modules/keyboard/keyboard.cc13
-rw-r--r--chromium/third_party/blink/renderer/modules/keyboard/keyboard.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/keyboard/keyboard.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.cc32
-rw-r--r--chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.h10
-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.cc31
-rw-r--r--chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/keyboard/navigator_keyboard.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/keyboard/navigator_keyboard.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/launch/BUILD.gn6
-rw-r--r--chromium/third_party/blink/renderer/modules/launch/OWNERS6
-rw-r--r--chromium/third_party/blink/renderer/modules/launch/dom_window_launch_queue.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/launch/dom_window_launch_queue.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/launch/file_handling_expiry_impl.cc50
-rw-r--r--chromium/third_party/blink/renderer/modules/launch/file_handling_expiry_impl.h41
-rw-r--r--chromium/third_party/blink/renderer/modules/launch/idls.gni10
-rw-r--r--chromium/third_party/blink/renderer/modules/launch/launch_params.cc19
-rw-r--r--chromium/third_party/blink/renderer/modules/launch/launch_params.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/launch/launch_params.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/launch/launch_queue.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/locks/idls.gni19
-rw-r--r--chromium/third_party/blink/renderer/modules/locks/lock.cc26
-rw-r--r--chromium/third_party/blink/renderer/modules/locks/lock.h22
-rw-r--r--chromium/third_party/blink/renderer/modules/locks/lock_manager.cc44
-rw-r--r--chromium/third_party/blink/renderer/modules/locks/lock_manager.h19
-rw-r--r--chromium/third_party/blink/renderer/modules/locks/navigator_locks.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/OWNERS2
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/idls.gni5
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters_test.cc23
-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.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/manifest_manager.cc38
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/manifest_manager.h23
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/manifest_parser.cc119
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/manifest_parser.h48
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/manifest_parser_unittest.cc439
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters.cc31
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters_unittest.cc40
-rw-r--r--chromium/third_party/blink/renderer/modules/media/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/modules/media_capabilities/BUILD.gn6
-rw-r--r--chromium/third_party/blink/renderer/modules/media_capabilities/DEPS17
-rw-r--r--chromium/third_party/blink/renderer/modules/media_capabilities/idls.gni22
-rw-r--r--chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc433
-rw-r--r--chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.h101
-rw-r--r--chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities_fuzzer.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities_test.cc813
-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.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animation_event_listener.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc8
-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.cc10
-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_elements_helper.cc22
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.h4
-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.cc17
-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_picture_in_picture_button_element.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc17
-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_scrubbing_message_element.cc8
-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.cc38
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element_test.cc6
-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/elements/media_control_timeline_metrics.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.cc21
-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.cc18
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc45
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc74
-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.cc27
-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_orientation_lock_delegate_test.cc27
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.cc4
-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_rotate_to_fullscreen_delegate_test.cc83
-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/mediacapturefromelement/DEPS3
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/auto_canvas_draw_listener.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/auto_canvas_draw_listener.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler.cc228
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler.h36
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler_unittest.cc16
-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.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc46
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/idls.gni10
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/on_request_canvas_draw_listener.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediacapturefromelement/on_request_canvas_draw_listener.h4
-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/BUILD.gn1
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/OWNERS3
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_opus_encoder.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder.cc32
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder.h11
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder_unittest.cc28
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/h264_encoder.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/idls.gni13
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc52
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.h20
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.cc77
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h13
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler_unittest.cc167
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_unittest.cc57
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/track_recorder.h46
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/track_recorder_unittest.cc39
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/vea_encoder.cc22
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/vea_encoder.h19
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc113
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.h65
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder_unittest.cc31
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasession/DEPS2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasession/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasession/idls.gni18
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasession/media_metadata.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasession/media_metadata.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasession/media_metadata.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasession/media_metadata_sanitizer.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasession/media_session.cc65
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasession/media_session.h27
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasession/media_session_test.cc59
-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/mediasession/type_converters.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/idls.gni19
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/media_source.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.cc (renamed from chromium/third_party/blink/renderer/modules/mediasource/media_source.cc)171
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.h (renamed from chromium/third_party/blink/renderer/modules/mediasource/media_source.h)43
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/media_source_registry.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/media_source_registry.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/source_buffer.cc159
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/source_buffer.h21
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/source_buffer_list.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/source_buffer_list.h6
-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.idl3
-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/mediasource/track_default_list.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/url_media_source.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/url_media_source.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediasource/video_playback_quality.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn1
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.cc4
-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.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_request.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/idls.gni40
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/input_device_info.cc30
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/input_device_info.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc84
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_constraints_impl.h20
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_constraints_test.cc66
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_device_info.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_device_info.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_devices.cc94
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_devices.h27
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_devices.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_devices_test.cc142
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream.cc25
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_audio_processor.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_audio_processor_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.cc32
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.h24
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio.cc134
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio_test.cc276
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.cc13
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets_test.cc22
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_test.cc199
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content_test.cc227
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.cc26
-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.cc286
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.cc18
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.h4
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_event.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_renderer_factory_impl.cc53
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.cc47
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.idl3
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_event.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_source_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc25
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_track_test.cc91
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/media_track_constraint_set.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/mock_constraint_factory.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/mock_constraint_factory.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_registry.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_video_sink.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_video_sink.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/navigator_media_stream.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/navigator_user_media.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/navigator_user_media.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/overconstrained_error.idl5
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.cc137
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.h25
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/remote_media_stream_track_adapter.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/remote_media_stream_track_adapter.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/track_audio_renderer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_client.cc95
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_client.h25
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_client_test.cc180
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_controller.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_controller.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_processor.cc556
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_processor.h51
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_request.cc230
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/user_media_request.h74
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/video_track_adapter.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/video_track_adapter_unittest.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/web_media_stream_device_observer.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc220
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc77
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h33
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc107
-rw-r--r--chromium/third_party/blink/renderer/modules/mediastream/window_media_stream.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/modules_idl_files.gni1196
-rw-r--r--chromium/third_party/blink/renderer/modules/modules_initializer.cc38
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/BUILD.gn12
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/choose_file_system_entries_options.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/file_system_directory_handle.idl10
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/file_system_file_handle.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/file_system_handle.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/file_system_writable_file_stream.idl16
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/file_system_writer.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/idls.gni27
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.cc89
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.h13
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.cc66
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.h11
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_handle.cc27
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_handle.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_underlying_sink.cc274
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_underlying_sink.h74
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writable_file_stream.cc131
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writable_file_stream.h46
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.cc47
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.h15
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.cc60
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system_test.cc30
-rw-r--r--chromium/third_party/blink/renderer/modules/native_file_system/write_params.idl18
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/BUILD.gn20
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/DEPS3
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/OWNERS4
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/README.md59
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/global_native_io.cc91
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/global_native_io.h27
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/idls.gni14
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/native_io_file.cc403
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/native_io_file.h150
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/native_io_file.idl21
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.cc104
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.h69
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.idl21
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/native_io_manager.cc269
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/native_io_manager.h67
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/native_io_manager.idl28
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/window_native_io.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/native_io/worker_global_scope_native_io.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/navigatorcontentutils/idls.gni5
-rw-r--r--chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.cc31
-rw-r--r--chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.h2
-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/idls.gni12
-rw-r--r--chromium/third_party/blink/renderer/modules/netinfo/navigator_network_information.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/netinfo/navigator_network_information.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/netinfo/network_information.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/netinfo/network_information.h13
-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/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/README.md20
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/idls.gni19
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_error_event.cc35
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_error_event.h49
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_error_event.idl15
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_message.cc148
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_message.h13
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_message.idl5
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_message_init.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_reader.cc61
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_reader.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_reader.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_record.cc478
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_record.h73
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_record.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_record_init.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_scan_options.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_write_options.idl (renamed from chromium/third_party/blink/renderer/modules/nfc/ndef_push_options.idl)8
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_writer.cc108
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_writer.h22
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/ndef_writer.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.cc76
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.h22
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/nfc_proxy_test.cc43
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/nfc_type_converters.cc63
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/nfc_type_converters.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/nfc_utils.cc65
-rw-r--r--chromium/third_party/blink/renderer/modules/nfc/nfc_utils.h14
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/BUILD.gn5
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/idls.gni21
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification.cc25
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification.idl5
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_data.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_data_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_event.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_manager.cc27
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_manager.h16
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.cc23
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/notifications/timestamp_trigger.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/BUILD.gn8
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/DEPS2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/OWNERS11
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/abort_payment_event.cc4
-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_event.idl2
-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/abort_test.cc47
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/address_init.idl (renamed from chromium/third_party/blink/renderer/modules/payments/payment_address_init.idl)4
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/address_init_type_converter.cc (renamed from chromium/third_party/blink/renderer/modules/payments/payment_address_init_type_converter.cc)9
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/address_init_type_converter.h (renamed from chromium/third_party/blink/renderer/modules/payments/payment_address_init_type_converter.h)12
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/android_pay_method_data.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/android_pay_tokenization.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/basic_card_helper.cc39
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/basic_card_helper.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/basic_card_request.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.cc51
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.h25
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/can_make_payment_event_init.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.cc130
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.h34
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/can_make_payment_response.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/can_make_payment_test.cc58
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/complete_test.cc86
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/html_iframe_element_payments.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/html_iframe_element_payments.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/idls.gni51
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/merchant_validation_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/merchant_validation_event.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/merchant_validation_event_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/on_payment_response_test.cc120
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.cc4
-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_event_data_conversion.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_handler_response.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_handler_utils.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_instruments.cc101
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_instruments.h16
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_instruments.idl10
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_manager.cc28
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_manager.h11
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_manager.idl2
-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_method_change_event.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request.cc351
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request.h33
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request_details_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request_event.cc107
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request_event.h18
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request_event.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.cc31
-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_test.cc111
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_request_update_event_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_response.cc23
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_response.h15
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_response.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_response_test.cc29
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_state_resolver.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_test_helper.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payment_test_helper.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payments_validators.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/payments_validators_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/skip_to_gpay_utils.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/payments/skip_to_gpay_utils_test.cc2
-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.gn32
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/DEPS3
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/dtls_transport_proxy.cc1
-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/p2p_quic_crypto_config_factory_impl.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_stream_factory.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_stream_factory_impl.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_stream_factory_impl.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_impl.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_unittest.cc185
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.cc49
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_test.cc59
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/adapters/sctp_transport_proxy.cc1
-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.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.cc42
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.h25
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/idls.gni81
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source.cc87
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source_test.cc327
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.cc32
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.cc23
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h15
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_client.cc (renamed from chromium/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler_client.cc)31
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_client.h (renamed from chromium/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler_client.h)52
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc (renamed from chromium/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler.cc)133
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.h (renamed from chromium/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler.h)46
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc137
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h41
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc222
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h57
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker_test.cc40
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_configuration.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc81
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h27
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.idl1
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h10
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.cc100
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.h63
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.idl19
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_delegate.cc68
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_delegate.h72
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.cc88
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.h44
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink_test.cc182
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.cc88
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.h50
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source_test.cc104
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.cc91
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.h65
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.idl25
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.cc89
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.h72
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.cc88
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.h44
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink_test.cc192
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.cc74
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.h46
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source_test.cc106
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_error.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_error.h22
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_error.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.cc43
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h26
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc73
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h15
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_insertable_streams.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc533
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h124
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.idl36
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc538
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h100
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc87
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.cc30
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.h16
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event_init.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.cc4
-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_ice_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_test.cc166
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.cc4
-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_stream_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h14
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.idl5
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_contributing_source.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_encoding_parameters.idl14
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc253
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h57
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.cc96
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.h25
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl_test.cc24
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_send_parameters.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc305
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h46
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.cc220
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.h30
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl_test.cc13
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl.cc35
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl_test.cc35
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description.cc4
-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.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.h10
-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_report.cc30
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.h10
-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_stats_response.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_track_event.cc4
-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_track_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.h10
-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/test_webrtc_stats_report_obtainer.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/webrtc_audio_renderer_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.cc67
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/webrtc_set_description_observer_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/clipboard_permission_descriptor.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/idls.gni23
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/navigator_permissions.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/navigator_permissions.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/permission_descriptor.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/permission_status.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/permission_status.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/permission_utils.cc150
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/permission_utils.h19
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/permissions.cc167
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/permissions.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/testing/internals_permission.cc121
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/testing/internals_permission.h34
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/testing/internals_permission.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.cc2
-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/enter_picture_in_picture_event.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.idl5
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/html_element_picture_in_picture.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/html_element_picture_in_picture.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/idls.gni20
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc46
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h22
-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_window.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h18
-rw-r--r--chromium/third_party/blink/renderer/modules/plugins/dom_mime_type.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/plugins/dom_mime_type.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/plugins/dom_mime_type_array.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/plugins/dom_mime_type_array.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/plugins/dom_plugin.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/plugins/dom_plugin.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/plugins/dom_plugin_array.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/plugins/dom_plugin_array.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/plugins/idls.gni12
-rw-r--r--chromium/third_party/blink/renderer/modules/plugins/navigator_plugins.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/plugins/navigator_plugins.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/idls.gni21
-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.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_availability.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_availability.h18
-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.cc2
-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_availability_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection.cc60
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection.h16
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.cc4
-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_available_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.cc4
-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_close_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_controller.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_controller.h11
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_promise_property.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.cc48
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.h26
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_receiver_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_request.cc83
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_request.h14
-rw-r--r--chromium/third_party/blink/renderer/modules/presentation/presentation_request.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/idls.gni23
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_event.cc26
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_event.h11
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_manager.cc56
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_manager.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_manager.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_manager_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_message_data.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_client.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_client.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_type_converters.cc29
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_type_converters.h26
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_utils.cc23
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_utils.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_provider.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_subscription.cc22
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_subscription.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.cc4
-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_change_event.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_options.cc21
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_options.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.cc5
-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.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/deprecated_storage_info.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.cc31
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/dom_error.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/dom_error.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/dom_error.idl6
-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/idls.gni23
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/navigator_storage_quota.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/navigator_storage_quota.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/quota_utils.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/quota_utils.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/storage_estimate.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/storage_manager.cc36
-rw-r--r--chromium/third_party/blink/renderer/modules/quota/storage_manager.h6
-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/BUILD.gn (renamed from chromium/third_party/blink/renderer/modules/sms/BUILD.gn)14
-rw-r--r--chromium/third_party/blink/renderer/modules/remote_objects/DEPS3
-rw-r--r--chromium/third_party/blink/renderer/modules/remote_objects/remote_object.cc308
-rw-r--r--chromium/third_party/blink/renderer/modules/remote_objects/remote_object.h52
-rw-r--r--chromium/third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.cc124
-rw-r--r--chromium/third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.h100
-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/html_media_element_remote_playback.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/remoteplayback/html_media_element_remote_playback.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/remoteplayback/idls.gni7
-rw-r--r--chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc41
-rw-r--r--chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback_test.cc32
-rw-r--r--chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.cc96
-rw-r--r--chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.h30
-rw-r--r--chromium/third_party/blink/renderer/modules/scheduler/dom_task.cc98
-rw-r--r--chromium/third_party/blink/renderer/modules/scheduler/dom_task.h11
-rw-r--r--chromium/third_party/blink/renderer/modules/scheduler/dom_task_controller.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/scheduler/dom_task_signal.cc33
-rw-r--r--chromium/third_party/blink/renderer/modules/scheduler/dom_task_signal.h31
-rw-r--r--chromium/third_party/blink/renderer/modules/scheduler/idls.gni13
-rw-r--r--chromium/third_party/blink/renderer/modules/scheduler/scheduler.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/scheduler/scheduler_post_task_options.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/scheduler/task_controller.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/scheduler/task_signal.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_enumeration/BUILD.gn6
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_enumeration/global_screen_enumeration.cc (renamed from chromium/third_party/blink/renderer/modules/screen_enumeration/screen_manager.cc)45
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_enumeration/global_screen_enumeration.h31
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_enumeration/idls.gni5
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_enumeration/navigator_screen_manager.cc94
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_enumeration/navigator_screen_manager.h30
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_enumeration/navigator_screen_manager.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_enumeration/screen_enumeration.idl (renamed from chromium/third_party/blink/renderer/modules/screen_enumeration/screen_manager.idl)8
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_enumeration/screen_manager.h40
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_enumeration/worker_navigator_screen_manager.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_orientation/idls.gni7
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.cc32
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.h11
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.h9
-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.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/accelerometer.cc26
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/accelerometer.h16
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/accelerometer.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor_test.cc66
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/gyroscope.cc22
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/gyroscope.h14
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/gyroscope.idl7
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/idls.gni22
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/magnetometer.cc22
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/magnetometer.h14
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/magnetometer.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor.cc43
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor.h26
-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.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_error_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.cc5
-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.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.cc3
-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.h2
-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.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/BUILD.gn2
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/idls.gni23
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/navigator_serial.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial.cc85
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial.h22
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_connection_event.cc37
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_connection_event.h38
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_connection_event.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_connection_event_init.idl7
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_port.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_port_filter.idl10
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_port_request_options.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc38
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.h14
-rw-r--r--chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_source.cc5
-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/service_worker/BUILD.gn10
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/DEPS8
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/client.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/clients.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/cross_origin_resource_policy_checker.cc56
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/cross_origin_resource_policy_checker.h53
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/extendable_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.cc65
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.h29
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/fetch_event.cc25
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/fetch_event.h13
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/fetch_event.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc63
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.h21
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/idls.gni32
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/install_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/navigator_service_worker.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/navigator_service_worker.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.cc72
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.h16
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_event_queue.cc127
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_event_queue.h88
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_event_queue_test.cc115
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc370
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h45
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.idl1
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc18
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h1
-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.cc53
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.h17
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.cc18
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.h15
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc18
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc58
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/BUILD.gn6
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/DEPS2
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc63
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.idl7
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.cc62
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.h48
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.idl16
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/detected_face.cc22
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/detected_face.h34
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/detected_face.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/detected_text.cc25
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/detected_text.h39
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/detected_text.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/face_detector.cc30
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/face_detector.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/face_detector.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/idls.gni18
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/shape_detector.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/text_detector.cc28
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/text_detector.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/shapedetection/text_detector.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/sms/DEPS10
-rw-r--r--chromium/third_party/blink/renderer/modules/sms/OWNERS4
-rw-r--r--chromium/third_party/blink/renderer/modules/sms/README.md3
-rw-r--r--chromium/third_party/blink/renderer/modules/sms/navigator_sms.cc46
-rw-r--r--chromium/third_party/blink/renderer/modules/sms/navigator_sms.h41
-rw-r--r--chromium/third_party/blink/renderer/modules/sms/navigator_sms.idl14
-rw-r--r--chromium/third_party/blink/renderer/modules/sms/sms.cc19
-rw-r--r--chromium/third_party/blink/renderer/modules/sms/sms.h35
-rw-r--r--chromium/third_party/blink/renderer/modules/sms/sms.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/sms/sms_metrics.h38
-rw-r--r--chromium/third_party/blink/renderer/modules/sms/sms_receiver.cc145
-rw-r--r--chromium/third_party/blink/renderer/modules/sms/sms_receiver.h56
-rw-r--r--chromium/third_party/blink/renderer/modules/sms/sms_receiver.idl14
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/dom_window_speech_synthesis.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/dom_window_speech_synthesis.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/idls.gni34
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_grammar.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_grammar.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.cc4
-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_grammar_list.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition.cc41
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition.h16
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition.idl7
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition_alternative.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition_alternative.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition_error_event.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition_error_event.idl7
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.idl7
-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.cc58
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis.h31
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event.idl2
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.cc23
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis_voice.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/speech_synthesis_voice.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/speech/window_speech.idl10
-rw-r--r--chromium/third_party/blink/renderer/modules/srcobject/idls.gni5
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/cached_storage_area.cc644
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/cached_storage_area.h163
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/cached_storage_area_test.cc532
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/dom_window_storage.cc6
-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/idls.gni12
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.cc58
-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.cc27
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_area.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_controller.cc43
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_controller.h32
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_controller_test.cc68
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_event.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_event.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc74
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_namespace.h23
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_namespace_test.cc47
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/testing/fake_area_source.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/testing/mock_storage_area.cc58
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/testing/mock_storage_area.h117
-rw-r--r--chromium/third_party/blink/renderer/modules/vibration/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/modules/vibration/idls.gni7
-rw-r--r--chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.cc22
-rw-r--r--chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.h16
-rw-r--r--chromium/third_party/blink/renderer/modules/vibration/vibration_controller.cc21
-rw-r--r--chromium/third_party/blink/renderer/modules/vibration/vibration_controller.h14
-rw-r--r--chromium/third_party/blink/renderer/modules/video_raf/html_video_element_video_request_animation_frame.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/video_raf/video_request_animation_frame_impl.cc141
-rw-r--r--chromium/third_party/blink/renderer/modules/video_raf/video_request_animation_frame_impl.h56
-rw-r--r--chromium/third_party/blink/renderer/modules/video_rvfc/BUILD.gn (renamed from chromium/third_party/blink/renderer/modules/video_raf/BUILD.gn)6
-rw-r--r--chromium/third_party/blink/renderer/modules/video_rvfc/DEPS (renamed from chromium/third_party/blink/renderer/modules/video_raf/DEPS)3
-rw-r--r--chromium/third_party/blink/renderer/modules/video_rvfc/OWNERS2
-rw-r--r--chromium/third_party/blink/renderer/modules/video_rvfc/html_video_element_request_video_frame_callback.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/video_rvfc/idls.gni10
-rw-r--r--chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.cc271
-rw-r--r--chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.h93
-rw-r--r--chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl_test.cc383
-rw-r--r--chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_metadata.idl (renamed from chromium/third_party/blink/renderer/modules/video_raf/video_frame_metadata.idl)22
-rw-r--r--chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback.idl (renamed from chromium/third_party/blink/renderer/modules/video_raf/video_frame_request_callback.idl)2
-rw-r--r--chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.cc (renamed from chromium/third_party/blink/renderer/modules/video_raf/video_frame_request_callback_collection.cc)2
-rw-r--r--chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.h (renamed from chromium/third_party/blink/renderer/modules/video_raf/video_frame_request_callback_collection.h)11
-rw-r--r--chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection_test.cc (renamed from chromium/third_party/blink/renderer/modules/video_raf/video_frame_request_callback_collection_test.cc)16
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/idls.gni12
-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.cc101
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.h16
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.idl5
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager.cc18
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.cc16
-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/wake_lock/worker_navigator_wake_lock.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/analyser_node.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/analyser_node.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_basic_processor_handler.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_basic_processor_handler_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_buffer.cc32
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_buffer.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_buffer.idl21
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc8
-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_buffer_source_node.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc118
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_context.h38
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_context.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_context_autoplay_test.cc108
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_context_test.cc6
-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.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_node_input.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_node_input.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_node_input_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_param.cc19
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_param.h13
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_param_map.cc4
-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_param_timeline.cc18
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.idl7
-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.cc4
-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.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope_test.cc19
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc24
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread_test.cc17
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.cc80
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.h23
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/biquad_dsp_kernel.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.cc124
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/biquad_processor.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/biquad_processor.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/channel_merger_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/channel_merger_node.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/channel_splitter_node.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/channel_splitter_node.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.cc31
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/convolver_node.cc46
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/convolver_node.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/convolver_node_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/cross_thread_audio_worklet_processor_info.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/delay_node.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/delay_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/delay_node.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/gain_node.cc35
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/gain_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/gain_node.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/idls.gni75
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.cc58
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.idl9
-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_web_audio_agent.cc18
-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.cc36
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.cc17
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.cc13
-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/media_stream_audio_source_node.idl7
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.idl7
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc70
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc39
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/panner_node.cc41
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/panner_node.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/panner_node.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/periodic_wave.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/periodic_wave.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.cc44
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/script_processor_node_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.cc24
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_node.cc32
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_node.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_node.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/BUILD.gn44
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/DEPS9
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/OWNERS3
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/README.md9
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.cc64
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.h54
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.idl20
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk_test.cc58
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_config.idl21
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_metadata.h17
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/idls.gni30
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.cc158
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.h90
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.idl87
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_init.idl (renamed from chromium/third_party/blink/renderer/modules/nfc/ndef_error_event_init.idl)8
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_output_callback.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_frame.cc60
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_frame.h41
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_frame.idl17
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc62
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.cc121
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.h38
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader_writer_test.cc133
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.cc194
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.h42
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.idl14
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer_parameters.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/webcodecs/webcodecs_error_callback.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database_authorizer.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database_client.cc6
-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.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database_context.h11
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/database_manager.cc7
-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/database_tracker.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/dom_window_web_database.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/idls.gni17
-rw-r--r--chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_agent.cc18
-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.idl4
-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/web_database_host.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/BUILD.gn8
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/angle_instanced_arrays.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/angle_instanced_arrays.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_blend_min_max.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_blend_min_max.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_color_buffer_float.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_color_buffer_float.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_color_buffer_half_float.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_color_buffer_half_float.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_float_blend.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_float_blend.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_frag_depth.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_frag_depth.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_shader_texture_lod.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_shader_texture_lod.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_srgb.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_srgb.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_bptc.cc36
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_bptc.h26
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_bptc.idl15
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_rgtc.cc35
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_rgtc.h26
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_rgtc.idl15
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_texture_filter_anisotropic.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_texture_filter_anisotropic.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_texture_norm_16.cc30
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_texture_norm_16.h27
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ext_texture_norm_16.idl19
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/idls.gni94
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/oes_element_index_uint.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/oes_element_index_uint.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/oes_fbo_render_mipmap.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/oes_fbo_render_mipmap.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/oes_standard_derivatives.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/oes_standard_derivatives.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/oes_texture_float.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/oes_texture_float.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/oes_texture_float_linear.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/oes_texture_float_linear.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/oes_texture_half_float.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/oes_texture_half_float.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/oes_texture_half_float_linear.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/oes_texture_half_float_linear.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ovr_multiview_2.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/ovr_multiview_2.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.cc36
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc59
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h18
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc299
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h63
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_active_info.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_buffer.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_buffer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_color_buffer_float.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_color_buffer_float.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_astc.cc18
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_astc.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_astc.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc1.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc1.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_pvrtc.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_pvrtc.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc_srgb.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc_srgb.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_context_attribute_helpers.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.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_context_event.idl5
-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_debug_renderer_info.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_debug_renderer_info.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_debug_shaders.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_debug_shaders.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_depth_texture.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_depth_texture.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_draw_buffers.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_draw_buffers.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_draw_instanced_base_vertex_base_instance.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_draw_instanced_base_vertex_base_instance.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_extension.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_extension.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_extension_name.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_fence_sync.cc13
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_fence_sync.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.cc66
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.h15
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_lose_context.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_lose_context.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_multi_draw.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_multi_draw.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_multi_draw_instanced_base_vertex_base_instance.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_multi_draw_instanced_base_vertex_base_instance.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_program.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_program.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_query.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_query.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc81
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.h16
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc360
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h132
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_sampler.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_sampler.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_shader.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_shader.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_shader_precision_format.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_shader_precision_format.h4
-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_sync.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_texture.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_texture.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_timer_query_ext.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_timer_query_ext.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_uniform_location.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_uniform_location.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object.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_vertex_array_object_oes.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_oes.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_video_frame_metadata.cc23
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_video_frame_metadata.h49
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_video_frame_metadata.idl19
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.cc83
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.h15
-rw-r--r--chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/BUILD.gn6
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/client_validation.cc42
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/client_validation.h24
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc65
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/dawn_object.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/dawn_object.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu.h11
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc75
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.h15
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_descriptor.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_entry.idl (renamed from chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_binding.idl)2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_descriptor.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_entry.idl (renamed from chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_binding.idl)3
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_command_buffer.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_command_buffer.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc63
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_device.cc114
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_device.h29
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_device.idl7
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_device_descriptor.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_fence.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_fence.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_out_of_memory_error.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.cc156
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.cc34
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_sampler.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module.cc39
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module_descriptor.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc17
-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.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_descriptor.idl17
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_view.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_view.h2
-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.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/gpu_validation_error.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webgpu/idls.gni92
-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/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/idls.gni22
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_access.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_access.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_connection_event.cc4
-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_connection_event.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_dispatcher.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_input.cc4
-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.cc2
-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_message_event.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_output.cc33
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_output.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_port.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/midi_port.h10
-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.cc44
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/webrtc/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.cc40
-rw-r--r--chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_renderer.cc237
-rw-r--r--chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_renderer.h108
-rw-r--r--chromium/third_party/blink/renderer/modules/webshare/idls.gni7
-rw-r--r--chromium/third_party/blink/renderer/modules/webshare/navigator_share.cc57
-rw-r--r--chromium/third_party/blink/renderer/modules/webshare/navigator_share.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/webshare/navigator_share.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/webshare/navigator_share_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/close_event.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/close_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/dom_websocket.cc126
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/dom_websocket.h42
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc13
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/idls.gni16
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/inspector_websocket_events.cc4
-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/web_pepper_socket_impl.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket.idl6
-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.cc53
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h13
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc188
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_common.cc11
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_stream.cc63
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_stream.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_stream.idl9
-rw-r--r--chromium/third_party/blink/renderer/modules/websockets/websocket_stream_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/BUILD.gn13
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/idls.gni16
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.cc350
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.h168
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/incoming_stream_test.cc410
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/mock_web_transport_close_proxy.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/mock_web_transport_close_proxy.h29
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.cc412
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.h182
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream_test.cc419
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/quic_transport.cc449
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/quic_transport.h86
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/quic_transport.idl22
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/quic_transport_test.cc658
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/receive_stream.cc59
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/receive_stream.h36
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/receive_stream.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/send_stream.cc60
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/send_stream.h33
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/send_stream.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/stream_abort_info.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/webtransport/web_transport_close_proxy.h44
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/idls.gni31
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/navigator_usb.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/navigator_usb.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb.cc93
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb.h23
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb.idl4
-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_alternate_interface.idl3
-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_configuration.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_connection_event.cc4
-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_connection_event.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_device.cc108
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_device.h20
-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_endpoint.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_in_transfer_result.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_in_transfer_result.idl2
-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_interface.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_packet.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_packet.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_result.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_result.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_packet.idl2
-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/usb_isochronous_out_transfer_result.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_out_transfer_result.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/worklet/worklet_thread_test_common.cc17
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/BUILD.gn21
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/element_xr.h21
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/element_xr.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/idls.gni67
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/navigator_xr.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/navigator_xr.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/navigator_xr.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/type_converters.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_anchor.cc75
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_anchor.h34
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_anchor.idl5
-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.cc65
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.cc8
-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.cc105
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_cube_map.h42
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_cube_map.idl14
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_init.idl8
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.cc31
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.h42
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.idl17
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_frame.cc67
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_frame.h17
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_frame.idl7
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.cc74
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.cc14
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h11
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_grip_space.cc35
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_grip_space.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_hit_result.cc22
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_hit_result.h29
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_hit_result.idl7
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_hit_test_options_init.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.cc50
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.h23
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.idl5
-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.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_input_source.cc287
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_input_source.h34
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_input_source.idl2
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.idl4
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_light_estimation.cc38
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_light_estimation.h35
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_light_estimation.idl14
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_light_estimation_state.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_light_estimation_state.h29
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_light_estimation_state.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_light_estimation_state_init.idl (renamed from chromium/third_party/blink/renderer/modules/sms/sms_receiver_options.idl)6
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_light_probe.cc47
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_light_probe.h36
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_light_probe.idl15
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_object_space.h15
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_plane.cc80
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_plane.h24
-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.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_plane_detection_state.h4
-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.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_ray.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_ray.idl11
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_reference_space.cc111
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_reference_space.h32
-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.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_reference_space_event.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_reflection_probe.cc26
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_reflection_probe.h33
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_reflection_probe.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_render_state.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_render_state.h6
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_rigid_transform.cc7
-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_rigid_transform.idl5
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_session.cc451
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_session.h93
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_session.idl19
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_session_event.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_session_event.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_session_event.idl4
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_session_init.idl1
-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.cc122
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_space.h92
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_spherical_harmonics.cc38
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_spherical_harmonics.h35
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_spherical_harmonics.idl14
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_system.cc (renamed from chromium/third_party/blink/renderer/modules/xr/xr.cc)637
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_system.h (renamed from chromium/third_party/blink/renderer/modules/xr/xr.h)168
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_system.idl (renamed from chromium/third_party/blink/renderer/modules/xr/xr.idl)9
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_target_ray_space.cc114
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_target_ray_space.h15
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_test_utils.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_options_init.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_result.cc6
-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.cc11
-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_view.cc5
-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.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc46
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.idl6
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_world_information.cc30
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_world_information.h13
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_world_information.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.cc21
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.h9
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.idl3
-rw-r--r--chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state_init.idl1
-rw-r--r--chromium/third_party/blink/renderer/platform/BUILD.gn236
-rw-r--r--chromium/third_party/blink/renderer/platform/DEPS3
-rw-r--r--chromium/third_party/blink/renderer/platform/PRESUBMIT.py10
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/compositor_animation.cc19
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/compositor_animation.h15
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/compositor_animation_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/compositor_animation_timeline.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/compositor_animation_timeline.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/compositor_keyframe_model.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/compositor_keyframe_model.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/compositor_keyframe_model_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/compositor_transform_operations.cc16
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/timing_function.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/animation/timing_function.h27
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.cc61
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/audio_destination.cc144
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/audio_destination.h21
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/audio_destination_test.cc1
-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/equal_power_panner.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/ffmpeg/fft_frame_ffmpeg.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/fft_frame.cc78
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/fft_frame.h16
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/hrtf_panner.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/mac/fft_frame_mac.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/media_multi_channel_resampler.cc17
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/media_multi_channel_resampler.h14
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/multi_channel_resampler.cc122
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/multi_channel_resampler.h70
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/panner.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/panner.h13
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/pffft/fft_frame_pffft.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/audio/push_pull_fifo.cc14
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/active_script_wrappable_base.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/active_script_wrappable_base.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/blink_isolate/blink_isolate.cc22
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/blink_isolate/blink_isolate.h39
-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.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/callback_method_retriever.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/dictionary_base.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/dom_data_store.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/dom_data_store.h38
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/enumeration_base.h92
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/parkable_string.cc189
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/parkable_string.h134
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/parkable_string_manager.cc27
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/parkable_string_manager.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/parkable_string_test.cc41
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/runtime_call_stats.h14
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/script_promise_properties.h20
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/script_state.h38
-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.h23
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/shared_persistent.h129
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/to_v8.h24
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/union_base.h45
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_binding.h47
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_binding_macros.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_cross_origin_property_support.cc96
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_cross_origin_property_support.h65
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_interface_bridge.h99
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.cc27
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_private_property.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_set_return_value.cc61
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_set_return_value.h336
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/v8_value_or_script_wrappable_adapter.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/wrapper_type_info.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/wrapper_type_info.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/blob/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/blob/blob_data.cc23
-rw-r--r--chromium/third_party/blink/renderer/platform/blob/blob_data.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/blob/blob_data_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/blob/testing/fake_blob.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/blob/testing/fake_blob.h4
-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_notifier.h23
-rw-r--r--chromium/third_party/blink/renderer/platform/context_lifecycle_observer.cc33
-rw-r--r--chromium/third_party/blink/renderer/platform/context_lifecycle_observer.h41
-rw-r--r--chromium/third_party/blink/renderer/platform/crypto_result.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/cursor.cc316
-rw-r--r--chromium/third_party/blink/renderer/platform/cursor.h131
-rw-r--r--chromium/third_party/blink/renderer/platform/cursors.cc290
-rw-r--r--chromium/third_party/blink/renderer/platform/cursors.h88
-rw-r--r--chromium/third_party/blink/renderer/platform/disk_data_allocator.cc206
-rw-r--r--chromium/third_party/blink/renderer/platform/disk_data_allocator.h116
-rw-r--r--chromium/third_party/blink/renderer/platform/disk_data_allocator_test.cc266
-rw-r--r--chromium/third_party/blink/renderer/platform/disk_data_allocator_test_utils.h66
-rw-r--r--chromium/third_party/blink/renderer/platform/encrypted_media_request.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/OWNERS5
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/platform.cc37
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/url_conversion.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/video_capture/web_video_capture_impl_manager_test.cc20
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_blob_info.cc9
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_coalesced_input_event.cc50
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_crypto_algorithm.cc57
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_cursor_info.cc50
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_failing_url_loader_factory.cc88
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_font.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_gesture_event.cc155
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_http_body.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_icon_sizes_parser.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_icon_sizes_parser_test.cc72
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_input_event.cc83
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_isolate.cc13
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_media_stream_audio_sink.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_media_stream_source.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_media_stream_track.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_mouse_event.cc69
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_mouse_wheel_event.cc25
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_pointer_event.cc101
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_prerender.cc132
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_prerendering_support.cc52
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_resource_timing_info.cc99
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_resource_timing_info_test.cc128
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_rtc_peer_connection_handler_client.cc14
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_rtc_stats.cc9
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_runtime_features.cc93
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_touch_event.cc37
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_url_error.cc14
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_url_load_timing.cc216
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_url_request.cc131
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_url_request_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_url_response.cc31
-rw-r--r--chromium/third_party/blink/renderer/platform/exported/web_video_frame_submitter.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/file_metadata.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font.cc66
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font.h32
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_cache.cc21
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_cache.h23
-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_key.h27
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_cache_test.cc75
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc25
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_data.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_data_cache.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_description.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_description.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_description_test.cc72
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_fallback_iterator.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.cc74
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.h50
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_global_context.cc13
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_global_context.h32
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc26
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.h19
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/font_selector.h9
-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_unique_name_lookup_linux.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/mac/core_text_font_format_support.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/mac/font_cache_mac.mm62
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm5
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm129
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/opentype/font_format_check.cc23
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings.h18
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings_test.cc26
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support.cc19
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_stretch_data.h45
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.cc258
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.h120
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support_test.cc466
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/segmented_font_data.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shape_iterator.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc156
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.h32
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_fuzzer.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_cache.h19
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc92
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.h13
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.cc18
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.cc223
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.h59
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper_test.cc264
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/simple_font_data.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/skia/skia_text_metrics.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/web_font_decoder.cc45
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win.cc57
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win.h91
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/win/font_unique_name_lookup_win.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/float_point.h53
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/float_rect.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/float_rect.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/int_rect.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/layout_rect.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/layout_size.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/layout_unit.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/layout_unit_test.cc16
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/length.h18
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/length_functions.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/length_size.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/region.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/geometry/region.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/DEPS3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc452
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h180
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image_test.cc116
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/animation_worklet_mutator.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/begin_frame_provider.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/bitmap_image.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/bitmap_image.h12
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc99
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h23
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc129
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_color_params.cc42
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_color_params.h20
-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_heuristic_parameters.h67
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource.cc127
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource.h76
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc9
-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_host.cc17
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource_host.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc544
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h84
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc230
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/color_correction_test_utils.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/color_correction_test_utils.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/README.md2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/chunk_to_layer_mapper_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc32
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/layers_as_json.cc21
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/layers_as_json.h12
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc729
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h94
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc1827
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc125
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer_test.cc641
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc374
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.h70
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositor_element_id.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositor_filter_operations.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/compositor_filter_operations.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/contiguous_container.cc36
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/contiguous_container.h34
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/crossfade_generated_image.cc46
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/crossfade_generated_image.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc33
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/dark_mode_filter.h19
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder.cc37
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test_wo_platform.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/filters/fe_tile.cc17
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/filters/fe_tile.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/filters/fe_turbulence.cc8
-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.cc28
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/generated_image.h13
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc219
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h39
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test.cc68
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_test_helpers.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/graphics_context_3d_utils.cc86
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/graphics_context_3d_utils.h13
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc43
-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.cc119
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc6
-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.h32
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler_test.cc110
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc24
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider_test.cc28
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.cc35
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/xr_frame_transport.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.cc180
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.h46
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu_memory_buffer_image_copy.cc22
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gradient_generated_image.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gradient_generated_image.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_context.cc312
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_context.h68
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_layer.cc274
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_layer.h64
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_layer_client.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_layer_test.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/hit_test_rect.cc32
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/hit_test_rect.h39
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image.cc28
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image.h34
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image_decoder_wrapper.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/image_observer.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/intercepting_canvas.h55
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/logging_canvas.cc135
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/logging_canvas.h16
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/mailbox_texture_holder.cc196
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/mailbox_texture_holder.h83
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.cc49
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.h52
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/memory_managed_paint_recorder.cc41
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/memory_managed_paint_recorder.h50
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/README.md7
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.h38
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/display_item.cc22
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/display_item.h59
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/display_item_cache_skipper.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/display_item_client.h14
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/display_item_list.cc14
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/display_item_list.h22
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/display_item_raster_invalidator.cc21
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/display_item_raster_invalidator.h23
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/display_item_raster_invalidator_test.cc22
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/drawing_display_item.cc119
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h31
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/drawing_recorder.cc33
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h13
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/float_clip_rect.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc41
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h15
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.cc117
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h37
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_clip_cache.cc19
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_clip_cache.h25
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_test.cc412
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache.h13
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache_test.cc24
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/graphics_layer_display_item.cc63
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/graphics_layer_display_item.h47
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/hit_test_data.cc23
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/hit_test_data.h42
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/hit_test_display_item.cc38
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/hit_test_display_item.h43
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_artifact.cc103
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_artifact.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk.cc34
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk.h88
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk_subset.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker.cc143
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker.h49
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker_test.cc422
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller.cc342
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller.h161
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_debug_data.cc80
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.cc189
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.h58
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_property_node_test.cc18
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/paint_record_builder.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/property_tree_state.cc16
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/property_tree_state.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.cc61
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc64
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.h31
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc459
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/scoped_display_item_fragment.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_hint.h74
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_properties.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.cc80
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h88
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.cc36
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.h12
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item_test.cc155
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/subsequence_recorder.h14
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h14
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint_generated_image.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/paint_generated_image.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/placeholder_image.cc27
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/placeholder_image.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/placeholder_image_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/skia/skia_utils.cc29
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/skia/skia_utils.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/skia_texture_holder.cc149
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/skia_texture_holder.h60
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/squashing_disallowed_reasons.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/squashing_disallowed_reasons.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc76
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image.h84
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/surface_layer_bridge.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/texture_holder.h85
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/touch_action_rect.cc21
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/touch_action_rect.h31
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.cc76
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h19
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc100
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter_test.cc102
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/BUILD.gn52
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md4
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/DEPS3
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/asm/BUILD.gn24
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/blink_gc.h14
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/cancelable_task_scheduler_test.cc2
-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.h315
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/collection_support/heap_linked_stack.h (renamed from chromium/third_party/blink/renderer/platform/heap/heap_linked_stack.h)51
-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.h203
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/concurrent_marking_test.cc501
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/finalizer_traits.h25
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/garbage_collected.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/gc_info.cc46
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/gc_info.h118
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/gc_info_test.cc26
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap.cc297
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap.h201
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_allocator.h371
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_compact.cc29
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_compact.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_compact_test.cc149
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_page.cc235
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_page.h409
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.cc17
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.h164
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_stats_collector_test.cc141
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_test.cc464
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.cc13
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_test_utilities.h14
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_thread_test.cc29
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/heap_traits_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/incremental_marking_test.cc466
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/marking_verifier.cc35
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/marking_verifier.h24
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/marking_visitor.cc160
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/marking_visitor.h123
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/member.h68
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/minor_gc_test.cc295
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/page_memory.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/page_memory.h12
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/persistent.h15
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/persistent_node.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/persistent_node.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/persistent_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/thread_state.cc319
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/thread_state.h97
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/thread_state_scopes.h30
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/threading_traits.h34
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/trace_traits.h408
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/unified_heap_controller.cc22
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.cc63
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.h61
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/visitor.h142
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/weakness_marking_test.cc44
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/worklist.h77
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/worklist_test.cc15
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/write_barrier_perftest.cc40
-rw-r--r--chromium/third_party/blink/renderer/platform/heap_observer_list.h91
-rw-r--r--chromium/third_party/blink/renderer/platform/heap_observer_list_test.cc165
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/OWNERS2
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/image_decoder.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/image_frame_test.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder_test.cc33
-rw-r--r--chromium/third_party/blink/renderer/platform/image-encoders/image_encoder_utils.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/instrumentation/instance_counters.h45
-rw-r--r--chromium/third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.cc9
-rw-r--r--chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.h3
-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/instrumentation/tracing/traced_value.cc73
-rw-r--r--chromium/third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h24
-rw-r--r--chromium/third_party/blink/renderer/platform/instrumentation/tracing/traced_value_test.cc26
-rw-r--r--chromium/third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/lifecycle_context_test.cc192
-rw-r--r--chromium/third_party/blink/renderer/platform/lifecycle_notifier.h185
-rw-r--r--chromium/third_party/blink/renderer/platform/lifecycle_observer.h81
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/BUILD.gn4
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/DEPS9
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/cors/cors.cc29
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/cors/cors.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/cors/cors_test.cc25
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/DEPS2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/buffering_bytes_consumer.cc11
-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/buffering_bytes_consumer_test.cc21
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/bytes_consumer.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/cached_metadata_handler.h38
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.cc82
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences_test.cc54
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h12
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/fetch_context.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h10
-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/memory_cache_correctness_test.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache_test.cc60
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource.cc51
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource.h29
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_client.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.cc68
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc362
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h33
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc72
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_finish_observer.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc40
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h14
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler_test.cc32
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.cc84
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h23
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc175
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.h29
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_defer_loading_test.cc41
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_options.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h18
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_test.cc55
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.cc202
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_request.h164
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_request_test.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.cc28
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_response.h11
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h18
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.cc60
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.h25
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.h17
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler.cc13
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler_test.cc11
-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.cc33
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/trust_token_params_conversion.h30
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc353
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.h29
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/fetch/worker_resource_timing_notifier.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/subresource_integrity_test.cc7
-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/mock_fetch_context.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/testing/mock_resource.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/loader/testing/mock_resource.h2
-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.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/media/web_audio_source_provider_client.h40
-rw-r--r--chromium/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc75
-rw-r--r--chromium/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl_test.cc57
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/aec_dump_agent_impl.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/audio_service_audio_processor_proxy.cc13
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_constraints.cc (renamed from chromium/third_party/blink/renderer/platform/exported/web_media_constraints.cc)246
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_constraints.h326
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_deliverer.h158
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.cc39
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_track.cc (renamed from chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_track.cc)52
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h126
-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.h10
-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.cc56
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/media_stream_source.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/webaudio_destination_consumer.h47
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.cc9
-rw-r--r--chromium/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.h4
-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.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/DEPS5
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/big_string.typemap11
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/big_string_mojom_traits.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/blink_typemaps.gni22
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/geometry.typemap44
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits.cc73
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits.h68
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits_test.cc180
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h94
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set.h94
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set_test.cc179
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_test.cc176
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_remote.h95
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_remote_test.cc181
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set.h96
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set_test.cc214
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h25
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/kurl.typemap18
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/kurl_mojom_traits.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/security_origin.typemap17
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/security_origin_mojom_traits.h12
-rw-r--r--chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/network/BUILD.gn21
-rw-r--r--chromium/third_party/blink/renderer/platform/network/content_security_policy_parsers.cc13
-rw-r--r--chromium/third_party/blink/renderer/platform/network/content_security_policy_parsers.h11
-rw-r--r--chromium/third_party/blink/renderer/platform/network/encoded_form_data.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/network/encoded_form_data.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/network/http_header_set.h24
-rw-r--r--chromium/third_party/blink/renderer/platform/network/http_names.json54
-rw-r--r--chromium/third_party/blink/renderer/platform/network/http_parsers.cc18
-rw-r--r--chromium/third_party/blink/renderer/platform/network/mime/content_type.cc65
-rw-r--r--chromium/third_party/blink/renderer/platform/network/mime/content_type.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/network/mime/mime_type_registry.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/p2p/OWNERS3
-rw-r--r--chromium/third_party/blink/renderer/platform/p2p/filtering_network_manager.cc15
-rw-r--r--chromium/third_party/blink/renderer/platform/p2p/filtering_network_manager.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/p2p/filtering_network_manager_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/p2p/host_address_request.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/p2p/ipc_network_manager.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/p2p/ipc_socket_factory.cc27
-rw-r--r--chromium/third_party/blink/renderer/platform/p2p/mdns_responder_adapter.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/p2p/socket_client_impl.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/p2p/socket_dispatcher.cc22
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/DEPS2
-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_audio_stream_transformer.cc137
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_audio_stream_transformer.h84
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_audio_stream_transformer_test.cc105
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_video_stream_transformer.cc191
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_video_stream_transformer.h93
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_video_stream_transformer_test.cc140
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink_proxy.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink_proxy.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.cc22
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.h35
-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_peer_connection_handler_client.cc13
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_client.h94
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_platform.h174
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_receiver_platform.h28
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_sender_platform.h29
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_scoped_refptr_cross_thread_copier.h22
-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.cc90
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.h65
-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.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc40
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter_test.cc13
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_factory.cc132
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder.cc97
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_factory.cc80
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_factory.h7
-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.h75
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/two_keys_adapter_map_unittest.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc79
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.h18
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink_test.cc126
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.cc14
-rw-r--r--chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/platform.gni5
-rw-r--r--chromium/third_party/blink/renderer/platform/prerender.cc97
-rw-r--r--chromium/third_party/blink/renderer/platform/prerender.h108
-rw-r--r--chromium/third_party/blink/renderer/platform/runtime_enabled_features.json5485
-rw-r--r--chromium/third_party/blink/renderer/platform/runtime_enabled_features_test.cc275
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn18
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/DEPS1
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/cooperative_scheduling_manager.cc10
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc13
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/features.cc19
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/features.h30
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper.cc57
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper_unittest.cc28
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/pollable_thread_safe_flag.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/pollable_thread_safe_flag.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.cc15
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h19
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.cc5
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/thread_cpu_throttler.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/tracing_helper.h17
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/web_thread_scheduler.cc23
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/worker_pool.cc12
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.cc46
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.cc87
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.h67
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.cc14
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc174
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h19
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc376
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_status.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller_unittest.cc39
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper_unittest.cc14
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc118
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h56
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc588
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h18
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager_unittest.cc113
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/non_waking_time_domain.cc45
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/non_waking_time_domain.h38
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/pending_user_input.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_scheduling_priority.cc65
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/widget_scheduler.cc35
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/main_thread/widget_scheduler.h37
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/public/pending_user_input_type.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/public/web_scheduling_priority.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/public/worker_pool.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.cc31
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler_unittest.cc121
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler_unittest.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/supplementable.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/DEPS2
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/blink_fuzzer_test_support.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/empty_web_media_player.cc8
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/empty_web_media_player.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/font_test_helpers.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/paint_property_test_helpers.h39
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/paint_test_configurations.h30
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/shape_result_perf_test.cc64
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/shaping_line_breaker_perf_test.cc17
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/stub_graphics_layer_client.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/test_paint_artifact.cc102
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/test_paint_artifact.h35
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/testing_platform_support.cc34
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/testing_platform_support.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/unit_test_helpers.cc13
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/unit_test_helpers.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/url_test_helpers.cc14
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock.cc35
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock.h34
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.cc15
-rw-r--r--chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.h11
-rw-r--r--chromium/third_party/blink/renderer/platform/text/DEPS2
-rw-r--r--chromium/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/text/icu_error.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/text/locale_icu.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/text/locale_mac.mm3
-rw-r--r--chromium/third_party/blink/renderer/platform/text/locale_mac_test.mm12
-rw-r--r--chromium/third_party/blink/renderer/platform/text/locale_win.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/text/locale_win_test.cc26
-rw-r--r--chromium/third_party/blink/renderer/platform/text/text_direction.h15
-rw-r--r--chromium/third_party/blink/renderer/platform/theme_types.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/timer_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/matrix_transform_operation.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/matrix_transform_operation.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/perspective_transform_operation.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/perspective_transform_operation.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/rotate_transform_operation.cc13
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/rotate_transform_operation.h17
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/scale_transform_operation.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/scale_transform_operation.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/skew_transform_operation.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/skew_transform_operation.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/transform_operation.h5
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/translate_transform_operation.cc14
-rw-r--r--chromium/third_party/blink/renderer/platform/transforms/translate_transform_operation.h9
-rw-r--r--chromium/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc20
-rw-r--r--chromium/third_party/blink/renderer/platform/video_capture/video_capture_impl_test.cc23
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/DEPS4
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/kurl.cc25
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/kurl.h4
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/kurl_test.cc38
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/reporting_disposition.h17
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/security_origin.cc114
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/security_origin.h40
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/security_origin_test.cc137
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/security_policy.cc9
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/security_policy_test.cc91
-rw-r--r--chromium/third_party/blink/renderer/platform/weborigin/security_violation_reporting_policy.h17
-rw-r--r--chromium/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.cc42
-rw-r--r--chromium/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.h2
-rw-r--r--chromium/third_party/blink/renderer/platform/webrtc/webrtc_source.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.cc61
-rw-r--r--chromium/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter_test.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/frame_widget.cc11
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/frame_widget.h81
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/widget_base.cc79
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/widget_base.h75
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/widget_base_client.h41
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/BUILD.gn18
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/allocator/allocator.cc54
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/allocator/allocator.h218
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/allocator/atomic_operations_test.cc139
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.cc137
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/bit_field.h153
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/bit_field_test.cc105
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/construct_traits.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/cross_thread_copier.h44
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/cross_thread_functional.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/deque.h53
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/hash_counted_set.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/hash_map.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/hash_set.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/hash_table.h164
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/hash_traits.h34
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/linked_hash_set.h511
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/linked_hash_set_test.cc463
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/list_hash_set.h166
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/list_hash_set_test.cc98
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/lru_cache.h148
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/lru_cache_test.cc110
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/pod_interval.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/pod_interval_tree.h221
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/pod_interval_tree_test.cc37
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/pod_red_black_tree.h10
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/sanitizers.h24
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/shared_buffer.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/stack_util.cc3
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/testing/run_all_tests.cc2
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/string_builder.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/string_impl.cc9
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/string_impl.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/string_to_number.cc14
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/string_to_number.h8
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/string_view.h13
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/string_view_test.cc26
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/text_codec.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/text_codec_utf8.cc6
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/text_codec_utf8.h6
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/wtf_string.cc9
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/text/wtf_string.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/threading.cc4
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/threading.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/threading_primitives_test.cc1
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/vector.h153
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/vector_backed_linked_list.h597
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/vector_backed_linked_list_test.cc508
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/vector_test.cc20
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/wtf.cc13
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/wtf.h7
-rw-r--r--chromium/third_party/blink/renderer/platform/wtf/wtf_test_helper.h71
7373 files changed, 193648 insertions, 110743 deletions
diff --git a/chromium/third_party/blink/renderer/.style.yapf b/chromium/third_party/blink/renderer/.style.yapf
new file mode 100644
index 00000000000..557fa7bf84c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/.style.yapf
@@ -0,0 +1,2 @@
+[style]
+based_on_style = pep8
diff --git a/chromium/third_party/blink/renderer/BUILD.gn b/chromium/third_party/blink/renderer/BUILD.gn
index 0d02c49b449..6431181c63a 100644
--- a/chromium/third_party/blink/renderer/BUILD.gn
+++ b/chromium/third_party/blink/renderer/BUILD.gn
@@ -48,6 +48,10 @@ config("inside_blink") {
"-Wno-implicit-float-conversion",
"-Wno-implicit-int-conversion",
]
+
+ if (!is_chromeos || default_toolchain != "//build/toolchain/cros:target") {
+ cflags += [ "-Wno-enum-float-conversion" ]
+ }
}
}
@@ -120,6 +124,14 @@ config("config") {
"no-gc-finalized",
]
+ # Disallow members in stack allocated classes.
+ cflags += [
+ "-Xclang",
+ "-plugin-arg-blink-gc-plugin",
+ "-Xclang",
+ "no-members-in-stack-allocated",
+ ]
+
# Add arguments for enabled GC plugin options:
if (blink_gc_plugin_option_do_dump_graph) {
cflags += [
diff --git a/chromium/third_party/blink/renderer/DEPS b/chromium/third_party/blink/renderer/DEPS
index ce8f5571604..69dcee83cc0 100644
--- a/chromium/third_party/blink/renderer/DEPS
+++ b/chromium/third_party/blink/renderer/DEPS
@@ -1,5 +1,6 @@
include_rules = [
"+base/allocator/partition_allocator/partition_alloc.h",
+ "+base/allocator/partition_allocator/oom.h",
"+base/auto_reset.h",
"+base/bind.h",
"+base/bind_helpers.h",
@@ -20,6 +21,7 @@ include_rules = [
"+base/memory/ptr_util.h",
"+base/memory/weak_ptr.h",
"+base/metrics/field_trial_params.h",
+ "+base/metrics/histogram.h",
"+base/metrics/histogram_functions.h",
"+base/metrics/histogram_macros.h",
"+base/metrics/single_sample_metrics.h",
@@ -32,11 +34,16 @@ include_rules = [
"+base/sequenced_task_runner.h",
"+base/single_thread_task_runner.h",
"+base/stl_util.h",
+ "+base/strings/strcat.h",
"+base/synchronization",
"+base/sys_byteorder.h",
"+base/system/sys_info.h",
"+base/task/post_task.h",
+ "+base/task/thread_pool.h",
+ "+base/template_util.h",
+ "+base/test/gmock_callback_support.h",
"+base/test/metrics/histogram_tester.h",
+ "+base/test/mock_callback.h",
"+base/test/scoped_feature_list.h",
"+base/test/test_simple_task_runner.h",
"+base/thread_annotations.h",
@@ -52,8 +59,9 @@ include_rules = [
"+base/util/type_safety/strong_alias.h",
"+build",
"+components/crash/core/common/crash_key.h",
+ "+net/cookies",
+ "+net/http/structured_headers.h",
"+services/network/public/mojom",
- "+services/service_manager/public/cpp/interface_provider.h",
"+testing/gmock/include/gmock",
"+testing/gtest/include/gtest",
"+third_party/blink/public/platform",
@@ -64,6 +72,7 @@ include_rules = [
"-ui/base/l10n",
"-ui/base/resource",
+ "+ui/base/mojom/cursor_type.mojom-blink.h",
"+ui/events/keycodes/dom",
"+v8",
]
diff --git a/chromium/third_party/blink/renderer/bindings/BUILD.gn b/chromium/third_party/blink/renderer/bindings/BUILD.gn
index 1e914b49861..794fd018b39 100644
--- a/chromium/third_party/blink/renderer/bindings/BUILD.gn
+++ b/chromium/third_party/blink/renderer/bindings/BUILD.gn
@@ -3,11 +3,20 @@
# found in the LICENSE file.
import("//build/config/python.gni")
+import("//third_party/blink/renderer/bindings/bindings.gni")
+import("//third_party/blink/renderer/bindings/core/v8/generated.gni")
+import("//third_party/blink/renderer/bindings/generated_in_core.gni")
+import("//third_party/blink/renderer/bindings/generated_in_modules.gni")
+import("//third_party/blink/renderer/bindings/idl_in_core.gni")
+import("//third_party/blink/renderer/bindings/idl_in_modules.gni")
+import("//third_party/blink/renderer/bindings/modules/v8/generated.gni")
import("//third_party/blink/renderer/bindings/scripts/scripts.gni")
import("//third_party/blink/renderer/build/scripts/scripts.gni")
import("//third_party/blink/renderer/core/core_idl_files.gni")
import("//third_party/blink/renderer/modules/modules_idl_files.gni")
+visibility = [ "//third_party/blink/renderer/*" ]
+
action("interfaces_info") {
script = "$bindings_scripts_dir/compute_interfaces_info_overall.py"
@@ -15,9 +24,7 @@ action("interfaces_info") {
"$bindings_core_output_dir/interfaces_info_core.pickle",
"$bindings_modules_output_dir/interfaces_info_modules.pickle",
]
- outputs = [
- "$bindings_output_dir/interfaces_info.pickle",
- ]
+ outputs = [ "$bindings_output_dir/interfaces_info.pickle" ]
args = [
"--",
@@ -53,9 +60,7 @@ template("collect_idl_files") {
script = "${bindings_scripts_dir}/collect_idl_files.py"
inputs = invoker.inputs
- outputs = [
- invoker.output,
- ]
+ outputs = [ invoker.output ]
# List input file names in a temporary file.
response_file_contents = rebase_path(inputs, root_build_dir)
@@ -75,13 +80,21 @@ template("collect_idl_files") {
}
collect_idl_files("web_idl_in_core") {
- # All IDL files in 'core' component.
- inputs = core_static_interface_idl_files +
- core_generated_interface_idl_files + core_all_dependency_idl_files
+ component = "core"
+
+ inputs = static_idl_files_in_core
+ deps = []
- # The hack of "constructor attributes" for the old bindings generator is not
- # necessary for the new one.
- inputs -= core_global_constructors_generated_idl_files
+ inputs += get_path_info(
+ [
+ "$root_gen_dir/third_party/blink/renderer/core/testing/internal_runtime_flags.idl",
+ "$root_gen_dir/third_party/blink/renderer/core/testing/internal_settings_generated.idl",
+ ],
+ "abspath")
+ deps += [
+ "//third_party/blink/renderer/core:generated_testing_idls_internal_runtime_flags",
+ "//third_party/blink/renderer/core:generated_testing_idls_settings",
+ ]
# Supplemental IDL definitions to support the migration from the old bindings
# generator to the new one.
@@ -90,19 +103,14 @@ collect_idl_files("web_idl_in_core") {
# Additional IDL files to test and demonstrate the new IDL compiler.
inputs += [ "${bindings_scripts_dir}/web_idl/demonstration_and_testing.idl" ]
- component = "core"
output = "${bindings_output_dir}/web_idl_in_core.pickle"
- deps = [
- "//third_party/blink/renderer/core:generated_testing_idls_internal_runtime_flags",
- "//third_party/blink/renderer/core:generated_testing_idls_settings",
- ]
}
collect_idl_files("web_idl_in_modules") {
- # All IDL files in 'modules' component.
- inputs = modules_definition_idl_files + modules_static_interface_idl_files +
- modules_static_dependency_idl_files
component = "modules"
+
+ inputs = static_idl_files_in_modules
+
output = "${bindings_output_dir}/web_idl_in_modules.pickle"
}
@@ -119,9 +127,7 @@ action_with_pydeps("web_idl_database") {
runtime_enabled_features_test_file,
]
output_data_file = "${bindings_output_dir}/web_idl_database.pickle"
- outputs = [
- output_data_file,
- ]
+ outputs = [ output_data_file ]
args = [
"--output",
@@ -139,30 +145,73 @@ action_with_pydeps("web_idl_database") {
]
}
-action_with_pydeps("generate_bindings_example") {
- script = "${bindings_scripts_dir}/generate_bindings.py"
+group("generate_v8_bindings") {
+ public_deps = []
+ if (use_v8_bind_gen_for_dictionary) {
+ public_deps += [ ":generate_bindings_dictionary" ]
+ }
+}
+
+template("generate_bindings") {
+ action_with_pydeps(target_name) {
+ script = "${bindings_scripts_dir}/generate_bindings.py"
+
+ web_idl_database_outputs = get_target_outputs(":web_idl_database")
+ web_idl_database = web_idl_database_outputs[0]
+
+ inputs = [ web_idl_database ]
+ outputs = invoker.outputs
+
+ args = [
+ invoker.target,
+ "--web_idl_database",
+ rebase_path(web_idl_database, root_build_dir),
+ "--root_src_dir",
+ rebase_path("//", root_build_dir),
+ "--root_gen_dir",
+ rebase_path(root_gen_dir, root_build_dir),
+ "--output_core_reldir",
+ rebase_path("${bindings_output_dir}/core/v8/", root_gen_dir),
+ "--output_modules_reldir",
+ rebase_path("${bindings_output_dir}/modules/v8/", root_gen_dir),
+ ]
+
+ deps = [ ":web_idl_database" ]
+ }
+}
+
+if (use_v8_bind_gen_for_dictionary) {
+ generate_bindings("generate_bindings_dictionary") {
+ target = "dictionary"
+ outputs =
+ generated_core_dictionary_files + generated_modules_dictionary_files +
+ generated_core_testing_dictionary_files + generated_demo_files
+ }
+}
+
+generate_bindings("generate_bindings_enumeration") {
+ target = "enumeration"
+ outputs = generated_enumeration_sources_in_core +
+ generated_enumeration_sources_in_modules +
+ generated_enumeration_sources_for_testing_in_core
+}
+
+action_with_pydeps("generate_high_entropy_list") {
+ script = "${bindings_scripts_dir}/generate_high_entropy_list.py"
web_idl_database_outputs = get_target_outputs(":web_idl_database")
web_idl_database = web_idl_database_outputs[0]
- inputs = [
- web_idl_database,
- ]
- outputs = [
- "${bindings_output_dir}/core/v8/example_dictionary.cc",
- ]
+ inputs = [ web_idl_database ]
+ output_data_file = "${root_build_dir}/high_entropy_list.csv"
+ outputs = [ output_data_file ]
args = [
- "dictionary",
"--web_idl_database",
rebase_path(web_idl_database, root_build_dir),
- "--output_dir_core",
- rebase_path("${bindings_output_dir}/core/v8/", root_build_dir),
- "--output_dir_modules",
- rebase_path("${bindings_output_dir}/modules/v8/", root_build_dir),
+ "--output",
+ rebase_path(output_data_file, root_build_dir),
]
- deps = [
- ":web_idl_database",
- ]
+ deps = [ ":web_idl_database" ]
}
diff --git a/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.md b/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.md
index 6a1d6ba2314..1ed4cc30502 100644
--- a/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.md
+++ b/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.md
@@ -178,9 +178,9 @@ Calling the non-`[Clamp]` version of `setColor()` uses **ToUint8()** to coerce t
Calling the `[Clamp]` version of `setColor()` uses **clampTo()** to coerce the Numbers to octets. Hence calling `context.setColor(-1, 255, 257)` is equivalent to calling `setColorClamped(0, 255, 255)`.
-### [Constructor] _(i)_
+### [Constructor] _(i)_ _deprecated_
-Standard: [Constructor](https://heycam.github.io/webidl/#Constructor)
+`[Constructor]` is deprecated. Use [constructor operations](https://heycam.github.io/webidl/#idl-constructors) instead.
Summary: `[Constructor]` indicates that the interface should have a constructor, i.e. "new XXX()".
@@ -333,6 +333,18 @@ In the example above, named properties in `HTMLCollection` instances (such as th
The `[LegacyUnenumerableNamedProperties]` extended attribute must be used **only** in interfaces that support named properties.
+### [LegacyWindowAlias] _(i)_
+
+Standard: [LegacyWindowAlias](https://heycam.github.io/webidl/#LegacyWindowAlias)
+
+### [LegacyWindowAlias_Measure] _(i)_
+
+Summary: The same as `[Measure]` and `[MeasureAs]` but applied to the property exposed as `[LegacyWindowAlias]`. Unlike `[Measure]`, you can optionally provide the feature name like `[LegacyWindowAlias_Measure=FeatureName]`.
+
+### [LegacyWindowAlias_RuntimeEnabled] _(i)_
+
+Summary: The same as `[RuntimeEnabled]` but applied to the property exposed as `[LegacyWindowAlias]`.
+
### [NamedConstructor] _(i)_
Standard: [NamedConstructor](https://heycam.github.io/webidl/#NamedConstructor)
@@ -353,6 +365,14 @@ The semantics are the same as `[Constructor]`, except that the name changes: Jav
Whether you should allow an interface to have a named constructor or not depends on the spec of each interface.
+### [NamedConstructor_CallWith] _(i)_
+
+Summary: The same as `[CallWith]` but applied to the named constructors.
+
+### [NamedConstructor_RaisesException] _(i)_
+
+Summary: The same as `[RaisesException]` but applied to the named constructors.
+
### [NewObject] _(m)_
Standard: [NewObject](https://heycam.github.io/webidl/#NewObject)
@@ -521,6 +541,20 @@ void func([TreatNullAs=Emptytring] DOMString str);
Implementation: Given `[TreatNullAs=EmptyString]`, a JavaScript null is converted to a Blink empty string, for which `String::IsEmpty()` returns true, but `String::IsNull()` return false.
+### [StringContext=TrustedHTML|TrustedScript|TrustedScriptURL] _(t)_
+
+Standard: [TrustedType](https://w3c.github.io/webappsec-trusted-types/dist/spec/#!trustedtypes-extended-attribute)
+
+Summary: Indicate that a DOMString for HTMLs and scripts or USVString for script URLs is to be supplemented with additional Trusted Types enforcement logic.
+
+Usage: Must be specified on a DOMString or a USVString type.
+
+```webidl
+typedef [StringContext=TrustedHTML] DOMString TrustedString;
+attribute TrustedString str;
+void func(TrustedString str);
+```
+
### [Unforgeable] _(m,a)_
Standard: [Unforgeable](http://heycam.github.io/webidl/#Unforgeable)
@@ -743,7 +777,7 @@ Summary: They allow you to write bindings code manually as you like: full bindin
Custom bindings are _strongly discouraged_. They are likely to be buggy, a source of security holes, and represent a significant maintenance burden. Before using `[Custom]`, you should doubly consider if you really need custom bindings. You are recommended to modify code generators and add specialized extended attributes or special cases if necessary to avoid using `[Custom]`.
-Usage: `[Custom]` can be specified on methods or attributes. `[Custom=CallEpilogue]` can be specified on methods. `[Custom=Getter]` and `[Custom=Setter]` can be specified on attributes. `[Custom=A|B]` can be specified on interfaces, with various values (see below).
+Usage: `[Custom]` can be specified on methods or attributes. `[Custom=Getter]` and `[Custom=Setter]` can be specified on attributes. `[Custom=A|B]` can be specified on interfaces, with various values (see below).
On read only attributes (that are not `[Replaceable]`), `[Custom]` is equivalent to `[Custom=Getter]` (since there is no setter) and `[Custom=Getter]` is preferred.
@@ -761,7 +795,6 @@ The bindings generator largely _ignores_ the specified type information of `[Cus
Before explaining the details, let us clarify the relationship of these IDL attributes.
* `[Custom]` on a method indicates that you can write V8 custom bindings for the method.
-* `[Custom=CallEpilogue]` on a method indicates that the normal code is generated for the method, but with an extra call to an auxiliary custom bindings callback at the end.
* `[Custom=Getter]` or `[Custom=Setter]` on an attribute means custom bindings for the attribute getter or setter.
* `[Custom]` on an attribute means custom bindings for both the getter and the setter
@@ -770,7 +803,6 @@ Methods:
```webidl
interface XXX {
[Custom] void func();
- [Custom=CallEpilogue] void func2();
};
```
@@ -780,10 +812,6 @@ You can write custom bindings in third_party/blink/renderer/bindings/{core,modul
void V8XXX::FuncMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info) {
...;
}
-
-void V8XXX::Func2MethodEpilogueCustom(const v8::FunctionCallbackInfo<v8::Value>& info, V8XXX* impl) {
- ...;
-}
```
Attribute getter:
@@ -927,7 +955,7 @@ Usage: `[CustomElementCallbacks]` takes no arguments.
Summary: Denotes an API that exposes data that folks on the internet find useful for fingerprinting.
Attributes and methods marked as `[HighEntropy]` are known to be practically useful for [identifying particular clients](https://dev.chromium.org/Home/chromium-security/client-identification-mechanisms) on the web today.
-Both methods and attribute/constant getters annotated with this attribute are wired up to [`Dactyloscoper::Record`](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/blink/renderer/core/frame/use_counter.cc&q=Dactyloscoper::Record) for additional processing.
+Both methods and attribute/constant getters annotated with this attribute are wired up to [`Dactyloscoper::Record`](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/blink/renderer/core/frame/dactyloscoper.cc&q=Dactyloscoper::Record) for additional processing.
This attribute must be accompanied by either `[Measure]` or `[MeasureAs]`.
@@ -966,7 +994,11 @@ Summary: Measures usage of a specific feature via UseCounter.
In order to measure usage of specific features, Chrome submits anonymous statistics through the Histogram recording system for users who opt-in to sharing usage statistics. This extended attribute hooks up a specific feature to this measurement system.
-Usage: `[Measure]` can be specified on interfaces, methods, attributes, and constants. When specified on an interface usage of the constructor will be measured. The generated feature name must be added to [UseCounter::Feature](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/blink/renderer/platform/instrumentation/use_counter.h&q=%22enum%20Feature%22&sq=package:chromium&type=cs&l=61) (in [platform/instrumentation/use_counter.h](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/blink/renderer/platform/instrumentation/use_counter.h)).
+Usage: `[Measure]` can be specified on interfaces, methods, attributes, and constants.
+
+(_deprecated_) When specified on an interface usage of the constructor will be measured. This behavior could be changed in the future. Specify `[Measure]` on constructor operations instead.
+
+The generated feature name must be added to [UseCounter::Feature](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/blink/renderer/platform/instrumentation/use_counter.h&q=%22enum%20Feature%22&sq=package:chromium&type=cs&l=61) (in [platform/instrumentation/use_counter.h](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/blink/renderer/platform/instrumentation/use_counter.h)).
```webidl
[Measure] attribute Node interestingAttribute;
@@ -979,7 +1011,11 @@ Usage: `[Measure]` can be specified on interfaces, methods, attributes, and cons
Summary: Like `[Measure]`, but the feature name is provided as the extended attribute value.
This is similar to the standard `[DeprecateAs]` extended attribute, but does not display a deprecation warning.
-Usage: `[MeasureAs]` can be specified on interfaces, methods, attributes, and constants. The value must match one of the enumeration values in [UseCounter::Feature](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/blink/renderer/platform/instrumentation/use_counter.h&q=%22enum%20Feature%22&sq=package:chromium&type=cs&l=61) (in [platform/instrumentation/use_counter.h](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/blink/renderer/platform/instrumentation/use_counter.h)).
+Usage: `[MeasureAs]` can be specified on interfaces, methods, attributes, and constants.
+
+(_deprecated_) Specifying `[MeasureAs]` on interfaces is deprecated. Specify `[MeasureAs]` on constructor operations instead.
+
+The value must match one of the enumeration values in [UseCounter::Feature](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/blink/renderer/platform/instrumentation/use_counter.h&q=%22enum%20Feature%22&sq=package:chromium&type=cs&l=61) (in [platform/instrumentation/use_counter.h](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/blink/renderer/platform/instrumentation/use_counter.h)).
```webidl
[MeasureAs=AttributeWeAreInterestedIn] attribute Node interestingAttribute;
@@ -1370,7 +1406,9 @@ reads would leak cross-origin information.
With both `Getter` and `Setter`, allows both cross-origin reads and cross-origin
writes. This is used for the `Window.location` attribute.
-### [CustomConstructor] _(i)_
+### [CustomConstructor] _(i)_ _deprecated_
+
+`[CustomConstructor]` is deprecated. Use [constructor operations](https://heycam.github.io/webidl/#idl-constructors) with `[Custom]`.
Summary: They allow you to write custom bindings for constructors.
diff --git a/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt b/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt
index 20ddc719625..4bb4a418173 100644
--- a/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt
+++ b/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt
@@ -46,11 +46,12 @@ Constructor
ConstructorCallWith=ExecutionContext|ScriptState|Document
ContextEnabled=*
CrossOrigin=|Getter|Setter
-Custom=|Getter|Setter|LegacyCallAsFunction|PropertyGetter|PropertyEnumerator|PropertyQuery|CallPrologue|CallEpilogue
+Custom=|Getter|Setter|LegacyCallAsFunction|PropertyGetter|PropertyEnumerator|PropertyQuery
CustomConstructor
CustomElementCallbacks
DefaultValue=Undefined
DeprecateAs=*
+DisableInNewIDLCompiler
DoNotCheckConstants
DoNotTestNewObject
EnforceRange
@@ -64,6 +65,9 @@ ImmutablePrototype
ImplementedAs=*
LegacyTreatAsPartialInterface
LegacyUnenumerableNamedProperties
+LegacyWindowAlias=*
+LegacyWindowAlias_Measure=|*
+LegacyWindowAlias_RuntimeEnabled=*
LenientSetter
LenientThis
LogActivity=|GetterOnly|SetterOnly
@@ -72,6 +76,8 @@ NewObject
Measure
MeasureAs=*
NamedConstructor=*
+NamedConstructor_CallWith=Document
+NamedConstructor_RaisesException
NoInterfaceObject
NotEnumerable
OverrideBuiltins
@@ -97,6 +103,7 @@ SaveSameObject
SecureContext=|*
Serializable
SetterCallWith=ExecutionContext|Isolate|ScriptState
+StringContext=TrustedHTML|TrustedScript|TrustedScriptURL
Transferable
TreatNonObjectAsNull
TreatNullAs=EmptyString
diff --git a/chromium/third_party/blink/renderer/bindings/PRESUBMIT.py b/chromium/third_party/blink/renderer/bindings/PRESUBMIT.py
index 55537f3ebbb..ae541e0f0b9 100644
--- a/chromium/third_party/blink/renderer/bindings/PRESUBMIT.py
+++ b/chromium/third_party/blink/renderer/bindings/PRESUBMIT.py
@@ -25,7 +25,6 @@
# 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.
-
"""Blink bindings presubmit script
See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
@@ -33,11 +32,12 @@ for more details about the presubmit API built into gcl.
"""
# Make sure binding templates are considered as source files.
-WHITE_LIST = (r'.+\.tmpl$',)
+WHITE_LIST = (r'.+\.tmpl$', )
# Changes to v8/ do not change generated code or tests, so exclude from
# _RunBindingsTests
-BLACK_LIST = (r'.*\bv8[\\\/].*',)
+BLACK_LIST = (r'.*\bv8[\\\/].*', )
+
def _RunBindingsTests(input_api, output_api):
# Skip if nothing to do
@@ -54,7 +54,8 @@ def _RunBindingsTests(input_api, output_api):
pardir = input_api.os_path.pardir
run_bindings_tests_path = input_api.os_path.join(
- input_api.PresubmitLocalPath(), pardir, pardir, 'tools', 'run_bindings_tests.py')
+ input_api.PresubmitLocalPath(), pardir, pardir, 'tools',
+ 'run_bindings_tests.py')
cmd_name = 'run_bindings_tests.py'
if input_api.platform == 'win32':
# Windows needs some help.
@@ -64,10 +65,7 @@ def _RunBindingsTests(input_api, output_api):
if not input_api.verbose:
cmd.append('--suppress-diff')
test_cmd = input_api.Command(
- name=cmd_name,
- cmd=cmd,
- kwargs={},
- message=message_type)
+ name=cmd_name, cmd=cmd, kwargs={}, message=message_type)
if input_api.verbose:
print('Running ' + cmd_name)
return input_api.RunTests([test_cmd])
diff --git a/chromium/third_party/blink/renderer/bindings/bindings.gni b/chromium/third_party/blink/renderer/bindings/bindings.gni
index 7b70a23fa20..02709cbf62d 100644
--- a/chromium/third_party/blink/renderer/bindings/bindings.gni
+++ b/chromium/third_party/blink/renderer/bindings/bindings.gni
@@ -7,6 +7,12 @@
import("//third_party/blink/renderer/bindings/modules/v8/v8.gni")
+declare_args() {
+ # If this variable is set true, we use a new code generator to generate code
+ # of IDL dictionaries. See https://crbug.com/839389 for the details.
+ use_v8_bind_gen_for_dictionary = false
+}
+
bindings_core_v8_files =
get_path_info([
"core/v8/active_script_wrappable.cc",
@@ -15,18 +21,15 @@ bindings_core_v8_files =
"core/v8/array_value.h",
"core/v8/binding_security.cc",
"core/v8/binding_security.h",
+ "core/v8/boxed_v8_module.h",
"core/v8/callback_promise_adapter.h",
"core/v8/custom/v8_custom_xpath_ns_resolver.cc",
"core/v8/custom/v8_custom_xpath_ns_resolver.h",
"core/v8/custom/v8_dev_tools_host_custom.cc",
- "core/v8/custom/v8_element_custom.cc",
- "core/v8/custom/v8_event_target_custom.cc",
"core/v8/custom/v8_html_all_collection_custom.cc",
"core/v8/custom/v8_html_plugin_element_custom.cc",
- "core/v8/custom/v8_message_channel_custom.cc",
"core/v8/custom/v8_pop_state_event_custom.cc",
"core/v8/custom/v8_promise_rejection_event_custom.cc",
- "core/v8/custom/v8_shadow_root_custom.cc",
"core/v8/custom/v8_window_custom.cc",
"core/v8/custom/v8_xml_http_request_custom.cc",
"core/v8/custom_wrappable_adapter.cc",
@@ -40,6 +43,8 @@ bindings_core_v8_files =
"core/v8/idl_dictionary_base.h",
"core/v8/idl_types.h",
"core/v8/idl_types_base.h",
+ "core/v8/isolated_world_csp.cc",
+ "core/v8/isolated_world_csp.h",
"core/v8/iterable.h",
"core/v8/js_based_event_listener.cc",
"core/v8/js_based_event_listener.h",
@@ -52,10 +57,10 @@ bindings_core_v8_files =
"core/v8/local_window_proxy.cc",
"core/v8/local_window_proxy.h",
"core/v8/maplike.h",
- "core/v8/boxed_v8_module.h",
"core/v8/module_record.cc",
"core/v8/module_record.h",
"core/v8/native_value_traits.h",
+ "core/v8/native_value_traits_impl.cc",
"core/v8/native_value_traits_impl.h",
"core/v8/profiler_trace_builder.cc",
"core/v8/profiler_trace_builder.h",
@@ -71,8 +76,6 @@ bindings_core_v8_files =
"core/v8/scheduled_action.h",
"core/v8/script_controller.cc",
"core/v8/script_controller.h",
- "core/v8/isolated_world_csp.cc",
- "core/v8/isolated_world_csp.h",
"core/v8/script_custom_element_definition.cc",
"core/v8/script_custom_element_definition.h",
"core/v8/script_custom_element_definition_builder.cc",
@@ -87,8 +90,6 @@ bindings_core_v8_files =
"core/v8/script_promise.cc",
"core/v8/script_promise.h",
"core/v8/script_promise_property.h",
- "core/v8/script_promise_property_base.cc",
- "core/v8/script_promise_property_base.h",
"core/v8/script_promise_resolver.cc",
"core/v8/script_promise_resolver.h",
"core/v8/script_regexp.cc",
@@ -119,7 +120,6 @@ bindings_core_v8_files =
"core/v8/serialization/v8_script_value_serializer.h",
"core/v8/source_location.cc",
"core/v8/source_location.h",
- "core/v8/to_v8_for_core.cc",
"core/v8/to_v8_for_core.h",
"core/v8/use_counter_callback.cc",
"core/v8/use_counter_callback.h",
@@ -156,9 +156,9 @@ bindings_core_v8_files =
"core/v8/v8_object_parser.h",
"core/v8/v8_page_popup_controller_binding.cc",
"core/v8/v8_page_popup_controller_binding.h",
- "core/v8/v8_persistent_value_vector.h",
"core/v8/v8_script_runner.cc",
"core/v8/v8_script_runner.h",
+ "core/v8/v8_set_return_value_for_core.h",
"core/v8/v8_string_resource.h",
"core/v8/v8_throw_dom_exception.cc",
"core/v8/v8_throw_dom_exception.h",
diff --git a/chromium/third_party/blink/renderer/bindings/core/BUILD.gn b/chromium/third_party/blink/renderer/bindings/core/BUILD.gn
index ba48ea2e1ab..03ff1184055 100644
--- a/chromium/third_party/blink/renderer/bindings/core/BUILD.gn
+++ b/chromium/third_party/blink/renderer/bindings/core/BUILD.gn
@@ -34,7 +34,5 @@ generate_global_constructors("core_global_constructors_idls") {
basenames = core_global_constructors_original_interface_basenames
component = "core"
output_dir = blink_core_output_dir
- deps = [
- ":core_global_objects",
- ]
+ deps = [ ":core_global_objects" ]
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/BUILD.gn b/chromium/third_party/blink/renderer/bindings/core/v8/BUILD.gn
index 40e897c5ee4..a51d8751fa3 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/BUILD.gn
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/BUILD.gn
@@ -4,183 +4,25 @@
import("//testing/libfuzzer/fuzzer_test.gni")
import("//third_party/blink/renderer/bindings/bindings.gni")
+import("//third_party/blink/renderer/bindings/core/v8/generated.gni")
+import("//third_party/blink/renderer/bindings/generated_in_core.gni")
import("//third_party/blink/renderer/bindings/scripts/scripts.gni")
import("//third_party/blink/renderer/core/core.gni")
import("//third_party/blink/renderer/core/core_idl_files.gni")
visibility = [ "//third_party/blink/renderer/*" ]
-bindings_core_generated_union_type_files = [
- "$bindings_core_v8_output_dir/add_event_listener_options_or_boolean.cc",
- "$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/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",
- "$bindings_core_v8_output_dir/byte_string_sequence_sequence_or_byte_string_byte_string_record.h",
- "$bindings_core_v8_output_dir/composite_operation_or_auto_or_composite_operation_or_auto_sequence.cc",
- "$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/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",
- "$bindings_core_v8_output_dir/double_or_double_sequence.cc",
- "$bindings_core_v8_output_dir/double_or_double_sequence.h",
- "$bindings_core_v8_output_dir/double_or_double_or_null_sequence.cc",
- "$bindings_core_v8_output_dir/double_or_double_or_null_sequence.h",
- "$bindings_core_v8_output_dir/double_or_internal_enum.cc",
- "$bindings_core_v8_output_dir/double_or_internal_enum.h",
- "$bindings_core_v8_output_dir/double_or_scroll_timeline_auto_keyword.cc",
- "$bindings_core_v8_output_dir/double_or_scroll_timeline_auto_keyword.h",
- "$bindings_core_v8_output_dir/double_or_string.cc",
- "$bindings_core_v8_output_dir/double_or_string.h",
- "$bindings_core_v8_output_dir/double_or_string_or_string_sequence.cc",
- "$bindings_core_v8_output_dir/double_or_string_or_string_sequence.h",
- "$bindings_core_v8_output_dir/event_listener_options_or_boolean.cc",
- "$bindings_core_v8_output_dir/event_listener_options_or_boolean.h",
- "$bindings_core_v8_output_dir/file_or_usv_string.cc",
- "$bindings_core_v8_output_dir/file_or_usv_string.h",
- "$bindings_core_v8_output_dir/file_or_usv_string_or_form_data.cc",
- "$bindings_core_v8_output_dir/file_or_usv_string_or_form_data.h",
- "$bindings_core_v8_output_dir/float_or_string_element_record.cc",
- "$bindings_core_v8_output_dir/float_or_string_element_record.h",
- "$bindings_core_v8_output_dir/html_element_or_long.cc",
- "$bindings_core_v8_output_dir/html_element_or_long.h",
- "$bindings_core_v8_output_dir/image_bitmap_source.cc",
- "$bindings_core_v8_output_dir/image_bitmap_source.h",
- "$bindings_core_v8_output_dir/internal_enum_or_internal_enum_sequence.cc",
- "$bindings_core_v8_output_dir/internal_enum_or_internal_enum_sequence.h",
- "$bindings_core_v8_output_dir/html_option_element_or_html_opt_group_element.cc",
- "$bindings_core_v8_output_dir/html_option_element_or_html_opt_group_element.h",
- "$bindings_core_v8_output_dir/html_script_element_or_svg_script_element.cc",
- "$bindings_core_v8_output_dir/html_script_element_or_svg_script_element.h",
- "$bindings_core_v8_output_dir/node_list_or_element.cc",
- "$bindings_core_v8_output_dir/node_list_or_element.h",
- "$bindings_core_v8_output_dir/html_collection_or_element.cc",
- "$bindings_core_v8_output_dir/html_collection_or_element.h",
- "$bindings_core_v8_output_dir/media_list_or_string.cc",
- "$bindings_core_v8_output_dir/media_list_or_string.h",
- "$bindings_core_v8_output_dir/node_or_string_or_trusted_script.cc",
- "$bindings_core_v8_output_dir/node_or_string_or_trusted_script.h",
- "$bindings_core_v8_output_dir/radio_node_list_or_element.cc",
- "$bindings_core_v8_output_dir/radio_node_list_or_element.h",
- "$bindings_core_v8_output_dir/request_or_usv_string.cc",
- "$bindings_core_v8_output_dir/request_or_usv_string.h",
- "$bindings_core_v8_output_dir/scroll_into_view_options_or_boolean.cc",
- "$bindings_core_v8_output_dir/scroll_into_view_options_or_boolean.h",
- "$bindings_core_v8_output_dir/string_or_array_buffer.cc",
- "$bindings_core_v8_output_dir/string_or_array_buffer.h",
- "$bindings_core_v8_output_dir/string_or_array_buffer_or_array_buffer_view.cc",
- "$bindings_core_v8_output_dir/string_or_array_buffer_or_array_buffer_view.h",
- "$bindings_core_v8_output_dir/string_or_css_variable_reference_value.cc",
- "$bindings_core_v8_output_dir/string_or_css_variable_reference_value.h",
- "$bindings_core_v8_output_dir/string_or_double.cc",
- "$bindings_core_v8_output_dir/string_or_double.h",
- "$bindings_core_v8_output_dir/string_or_element_creation_options.cc",
- "$bindings_core_v8_output_dir/string_or_element_creation_options.h",
- "$bindings_core_v8_output_dir/string_or_performance_measure_options.cc",
- "$bindings_core_v8_output_dir/string_or_performance_measure_options.h",
- "$bindings_core_v8_output_dir/string_or_string_sequence.cc",
- "$bindings_core_v8_output_dir/string_or_string_sequence.h",
- "$bindings_core_v8_output_dir/string_or_trusted_html.cc",
- "$bindings_core_v8_output_dir/string_or_trusted_html.h",
- "$bindings_core_v8_output_dir/string_or_trusted_html_or_trusted_script_or_trusted_script_url.cc",
- "$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_treat_null_as_empty_string_or_trusted_script.cc",
- "$bindings_core_v8_output_dir/string_treat_null_as_empty_string_or_trusted_script.h",
- "$bindings_core_v8_output_dir/usv_string_sequence_sequence_or_usv_string_usv_string_record_or_usv_string.cc",
- "$bindings_core_v8_output_dir/usv_string_sequence_sequence_or_usv_string_usv_string_record_or_usv_string.h",
- "$bindings_core_v8_output_dir/unrestricted_double_or_keyframe_animation_options.cc",
- "$bindings_core_v8_output_dir/unrestricted_double_or_keyframe_animation_options.h",
- "$bindings_core_v8_output_dir/unrestricted_double_or_keyframe_effect_options.cc",
- "$bindings_core_v8_output_dir/unrestricted_double_or_keyframe_effect_options.h",
- "$bindings_core_v8_output_dir/unrestricted_double_or_string.cc",
- "$bindings_core_v8_output_dir/unrestricted_double_or_string.h",
- "$bindings_core_v8_output_dir/uint8_clamped_array_or_uint16_array_or_float32_array.cc",
- "$bindings_core_v8_output_dir/uint8_clamped_array_or_uint16_array_or_float32_array.h",
- "$bindings_core_v8_output_dir/video_track_or_audio_track_or_text_track.cc",
- "$bindings_core_v8_output_dir/video_track_or_audio_track_or_text_track.h",
-]
-
-generated_core_testing_callback_function_files = [
- "$bindings_core_v8_output_dir/v8_test_callback.cc",
- "$bindings_core_v8_output_dir/v8_test_callback.h",
- "$bindings_core_v8_output_dir/v8_test_enum_callback.cc",
- "$bindings_core_v8_output_dir/v8_test_enum_callback.h",
- "$bindings_core_v8_output_dir/v8_test_interface_callback.cc",
- "$bindings_core_v8_output_dir/v8_test_interface_callback.h",
- "$bindings_core_v8_output_dir/v8_test_receiver_object_callback.cc",
- "$bindings_core_v8_output_dir/v8_test_receiver_object_callback.h",
- "$bindings_core_v8_output_dir/v8_test_sequence_callback.cc",
- "$bindings_core_v8_output_dir/v8_test_sequence_callback.h",
-]
+blink_core_sources("generated") {
+ sources = generated_enumeration_sources_in_core
+ deps =
+ [ "//third_party/blink/renderer/bindings:generate_bindings_enumeration" ]
+}
-generated_core_callback_function_files = [
- "$bindings_core_v8_output_dir/v8_blob_callback.cc",
- "$bindings_core_v8_output_dir/v8_blob_callback.h",
- "$bindings_core_v8_output_dir/v8_create_html_callback.cc",
- "$bindings_core_v8_output_dir/v8_create_html_callback.h",
- "$bindings_core_v8_output_dir/v8_create_script_callback.cc",
- "$bindings_core_v8_output_dir/v8_create_script_callback.h",
- "$bindings_core_v8_output_dir/v8_create_url_callback.cc",
- "$bindings_core_v8_output_dir/v8_create_url_callback.h",
- "$bindings_core_v8_output_dir/v8_custom_element_adopted_callback.cc",
- "$bindings_core_v8_output_dir/v8_custom_element_adopted_callback.h",
- "$bindings_core_v8_output_dir/v8_custom_element_attribute_changed_callback.cc",
- "$bindings_core_v8_output_dir/v8_custom_element_attribute_changed_callback.h",
- "$bindings_core_v8_output_dir/v8_custom_element_constructor.cc",
- "$bindings_core_v8_output_dir/v8_custom_element_constructor.h",
- "$bindings_core_v8_output_dir/v8_custom_element_form_associated_callback.cc",
- "$bindings_core_v8_output_dir/v8_custom_element_form_associated_callback.h",
- "$bindings_core_v8_output_dir/v8_custom_element_form_disabled_callback.cc",
- "$bindings_core_v8_output_dir/v8_custom_element_form_disabled_callback.h",
- "$bindings_core_v8_output_dir/v8_custom_element_form_state_restore_callback.cc",
- "$bindings_core_v8_output_dir/v8_custom_element_form_state_restore_callback.h",
- "$bindings_core_v8_output_dir/v8_event_handler_non_null.cc",
- "$bindings_core_v8_output_dir/v8_event_handler_non_null.h",
- "$bindings_core_v8_output_dir/v8_for_each_iterator_callback.cc",
- "$bindings_core_v8_output_dir/v8_for_each_iterator_callback.h",
- "$bindings_core_v8_output_dir/v8_frame_request_callback.cc",
- "$bindings_core_v8_output_dir/v8_frame_request_callback.h",
- "$bindings_core_v8_output_dir/v8_function.cc",
- "$bindings_core_v8_output_dir/v8_function.h",
- "$bindings_core_v8_output_dir/v8_function_string_callback.cc",
- "$bindings_core_v8_output_dir/v8_function_string_callback.h",
- "$bindings_core_v8_output_dir/v8_idle_request_callback.cc",
- "$bindings_core_v8_output_dir/v8_idle_request_callback.h",
- "$bindings_core_v8_output_dir/v8_intersection_observer_callback.cc",
- "$bindings_core_v8_output_dir/v8_intersection_observer_callback.h",
- "$bindings_core_v8_output_dir/v8_layout_callback.cc",
- "$bindings_core_v8_output_dir/v8_layout_callback.h",
- "$bindings_core_v8_output_dir/v8_mojo_watch_callback.cc",
- "$bindings_core_v8_output_dir/v8_mojo_watch_callback.h",
- "$bindings_core_v8_output_dir/v8_mutation_callback.cc",
- "$bindings_core_v8_output_dir/v8_mutation_callback.h",
- "$bindings_core_v8_output_dir/v8_no_argument_constructor.cc",
- "$bindings_core_v8_output_dir/v8_no_argument_constructor.h",
- "$bindings_core_v8_output_dir/v8_performance_observer_callback.cc",
- "$bindings_core_v8_output_dir/v8_performance_observer_callback.h",
- "$bindings_core_v8_output_dir/v8_reporting_observer_callback.cc",
- "$bindings_core_v8_output_dir/v8_reporting_observer_callback.h",
- "$bindings_core_v8_output_dir/v8_resize_observer_callback.cc",
- "$bindings_core_v8_output_dir/v8_resize_observer_callback.h",
- "$bindings_core_v8_output_dir/v8_scroll_state_callback.cc",
- "$bindings_core_v8_output_dir/v8_scroll_state_callback.h",
- "$bindings_core_v8_output_dir/v8_void_function.cc",
- "$bindings_core_v8_output_dir/v8_void_function.h",
-]
+blink_core_sources("generated_for_testing") {
+ sources = generated_enumeration_sources_for_testing_in_core
+ deps =
+ [ "//third_party/blink/renderer/bindings:generate_bindings_enumeration" ]
+}
generate_origin_trial_features("bindings_core_origin_trial_features") {
sources =
@@ -194,26 +36,10 @@ generate_origin_trial_features("bindings_core_origin_trial_features") {
]
}
-if (is_win && is_official_build) {
- # On Windows Official release builds, we try to preserve symbol space.
- # is_official_build adds /GL option and /LTCG is automatically enabled in
- # link.exe. But link.exe cannot make binary smaller than its size limit from
- # many obj files for bindings_core_impl.lib.
- bindings_core_generated_interface_files =
- [ "$bindings_core_v8_output_dir/v8_generated_core_bindings.cc" ]
-} else {
- bindings_core_generated_interface_files =
- process_file_template(
- core_definition_idl_files,
- [
- "$bindings_core_v8_output_dir/v8_{{source_name_part}}.cc",
- "$bindings_core_v8_output_dir/v8_{{source_name_part}}.h",
- ])
-}
-
group("bindings_core_v8_generated") {
public_deps = [
":bindings_core_impl_generated",
+ "//third_party/blink/renderer/bindings:generate_v8_bindings",
]
if (is_win && is_official_build) {
public_deps += [ ":generate_bindings_core_v8_all_interfaces" ]
@@ -227,6 +53,10 @@ group("bindings_core_v8_generated") {
idl_compiler("generate_bindings_core_v8_interfaces") {
sources = core_definition_idl_files + core_testing_definition_idl_files +
generated_webcore_testing_idl_files
+ if (use_v8_bind_gen_for_dictionary) {
+ sources -= core_dictionary_idl_files
+ sources -= core_testing_dictionary_idl_files
+ }
output_dir = bindings_core_v8_output_dir
output_name_suffix = ""
target_component = "core"
@@ -234,17 +64,20 @@ idl_compiler("generate_bindings_core_v8_interfaces") {
aggregate_generated_bindings("generate_bindings_core_v8_all_interfaces") {
sources = core_definition_idl_files
- outputs = [
- "$bindings_core_v8_output_dir/v8_generated_core_bindings.cc",
- ]
+ if (use_v8_bind_gen_for_dictionary) {
+ sources -= core_dictionary_idl_files
+ }
+ outputs = [ "$bindings_core_v8_output_dir/v8_generated_core_bindings.cc" ]
component = "core"
- public_deps = [
- ":generate_bindings_core_v8_interfaces",
- ]
+ public_deps = [ ":generate_bindings_core_v8_interfaces" ]
}
idl_impl("bindings_core_impl_generated") {
- dict_idls = core_dictionary_idl_files + core_testing_dictionary_idl_files
+ if (use_v8_bind_gen_for_dictionary) {
+ dict_idls = []
+ } else {
+ dict_idls = core_dictionary_idl_files + core_testing_dictionary_idl_files
+ }
non_dict_outputs = bindings_core_generated_union_type_files +
generated_core_testing_callback_function_files +
generated_core_callback_function_files
@@ -252,29 +85,23 @@ idl_impl("bindings_core_impl_generated") {
target_component = "core"
}
-# Even though the idl_impl() call above generates .cpp and .h files for both
-# |core_dictionary_idl_files| and |core_testing_dictionary_idl_files|, we need
-# to do some manual processing because the generated files are used in
-# different targets.
-generated_core_testing_dictionary_files =
- process_file_template(
- core_testing_dictionary_idl_files,
- [
- "$blink_core_output_dir/testing/{{source_name_part}}.cc",
- "$blink_core_output_dir/testing/{{source_name_part}}.h",
- ])
-
# Compile the non-test sources generated above.
blink_core_sources("bindings_core_impl") {
_non_testing_sources = get_target_outputs(":bindings_core_impl_generated") -
- generated_core_testing_dictionary_files -
generated_core_testing_callback_function_files
+
+ _non_testing_sources += generated_core_dictionary_files
+ if (!use_v8_bind_gen_for_dictionary) {
+ _non_testing_sources -= generated_core_testing_dictionary_files
+ }
+
sources = _non_testing_sources + bindings_core_generated_interface_files +
get_target_outputs(":bindings_core_origin_trial_features")
deps = [
":bindings_core_origin_trial_features",
":bindings_core_v8_generated",
+ "//third_party/blink/renderer/bindings:generate_v8_bindings",
]
}
@@ -285,6 +112,19 @@ jumbo_source_set("testing") {
sources = generated_core_testing_dictionary_files +
generated_core_testing_callback_function_files
+ testing_idl_interface_files =
+ webcore_testing_idl_files + generated_webcore_testing_idl_files +
+ webcore_testing_idl_with_modules_dependency_files
+ if (!use_v8_bind_gen_for_dictionary) {
+ testing_idl_interface_files += core_testing_dictionary_idl_files
+ }
+ sources += process_file_template(
+ testing_idl_interface_files,
+ [
+ "$bindings_core_v8_output_dir/v8_{{source_name_part}}.cc",
+ "$bindings_core_v8_output_dir/v8_{{source_name_part}}.h",
+ ])
+
configs -= core_config_remove
configs += core_config_add + [ "//third_party/blink/renderer:inside_blink" ] -
[ "//third_party/blink/renderer/core:config" ]
@@ -292,6 +132,7 @@ jumbo_source_set("testing") {
deps = [
":bindings_core_v8_generated",
"//skia",
+ "//third_party/blink/renderer/bindings:generate_v8_bindings",
"//third_party/blink/renderer/core:all_generators",
"//third_party/blink/renderer/platform",
"//v8",
@@ -299,9 +140,7 @@ jumbo_source_set("testing") {
}
fuzzer_test("v8_serialized_script_value_fuzzer") {
- sources = [
- "serialization/serialized_script_value_fuzzer.cc",
- ]
+ sources = [ "serialization/serialized_script_value_fuzzer.cc" ]
seed_corpus = "serialization/fuzz_corpus"
deps = [
"//third_party/blink/renderer/core",
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/DEPS b/chromium/third_party/blink/renderer/bindings/core/v8/DEPS
index c386e5e6f34..70bead46be1 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/DEPS
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/DEPS
@@ -1,5 +1,8 @@
specific_include_rules = {
"script_promise_resolver_test.cc": [
"+base/run_loop.h",
- ]
+ ],
+ "serialized_script_value_fuzzer.cc": [
+ "+testing/libfuzzer/libfuzzer_exports.h",
+ ],
} \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/V8BindingDesign.md b/chromium/third_party/blink/renderer/bindings/core/v8/V8BindingDesign.md
index 6c483b89cd1..5567406c09f 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/V8BindingDesign.md
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/V8BindingDesign.md
@@ -227,7 +227,7 @@ As a result, we have multiple DOM wrapper storages in one isolate.
The mapping of the main world is written in `ScriptWrappable`.
If `ScriptWrappable::main_world_wrapper_` has a non-empty value, it is a DOM
wrapper of the C++ DOM object of the main world.
-The mapping of other worlds are written in `DOMWrapperMap`.
+The mapping of other worlds are written in `DOMDataStore`.
## DOM wrappers and contexts
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/active_script_wrappable.cc b/chromium/third_party/blink/renderer/bindings/core/v8/active_script_wrappable.cc
index 36bd89b0b5d..91170366183 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/active_script_wrappable.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/active_script_wrappable.cc
@@ -18,7 +18,7 @@ bool IsContextDestroyedForActiveScriptWrappable(
if (execution_context->IsContextDestroyed())
return true;
- if (const auto* doc = DynamicTo<Document>(execution_context)) {
+ if (const auto* doc = Document::DynamicFrom(execution_context)) {
// Not all Document objects have an ExecutionContext that is actually
// destroyed. In such cases we defer to the ContextDocument if possible.
// If no such Document exists we consider the ExecutionContext as
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h b/chromium/third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h
index 1ab999c2fa4..36661ca892a 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h
@@ -37,7 +37,8 @@ class ScriptWrappable;
//
// Since this pending activity will not keep the wrappable alive after the
// context is destroyed, it is common for ActiveScriptWrappable objects to also
-// derive from ContextLifecycleObserver to abort the activity at that time.
+// derive from ExecutionContextLifecycleObserver to abort the activity at that
+// time.
template <typename T>
class ActiveScriptWrappable : public ActiveScriptWrappableBase {
public:
@@ -54,7 +55,9 @@ class ActiveScriptWrappable : public ActiveScriptWrappableBase {
bool DispatchHasPendingActivity() const final {
return static_cast<const T*>(this)->HasPendingActivity();
}
- ScriptWrappable* ToScriptWrappable() final { return static_cast<T*>(this); }
+ const ScriptWrappable* ToScriptWrappable() const final {
+ return static_cast<const T*>(this);
+ }
private:
DISALLOW_COPY_AND_ASSIGN(ActiveScriptWrappable);
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 e5d11a33924..886b4701c5d 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(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
// 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 886cc4ec1b5..a071d23d646 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
@@ -36,6 +36,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/inspector/console_message.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -61,7 +62,7 @@ AtomicString V8CustomXPathNSResolver::lookupNamespaceURI(const String& prefix) {
if (lookup_namespace_uri_func.IsEmpty() && !resolver_->IsFunction()) {
LocalFrame* frame = ToLocalFrameIfNotDetached(script_state_->GetContext());
if (frame)
- frame->Console().AddMessage(ConsoleMessage::Create(
+ frame->Console().AddMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kError,
"XPathNSResolver does not have a lookupNamespaceURI method."));
@@ -93,7 +94,7 @@ AtomicString V8CustomXPathNSResolver::lookupNamespaceURI(const String& prefix) {
return return_string;
}
-void V8CustomXPathNSResolver::Trace(blink::Visitor* visitor) {
+void V8CustomXPathNSResolver::Trace(Visitor* visitor) {
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 76999822869..ea35df084e1 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 4d8db7bb9be..b25053ac80d 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,12 +153,8 @@ void V8DevToolsHost::ShowContextMenuAtPointMethodCustom(
if (info.Length() >= 4 && info[3]->IsObject()) {
document = V8HTMLDocument::ToImplWithTypeCheck(isolate, info[3]);
} else {
- v8::Local<v8::Object> window_wrapper =
- V8Window::FindInstanceInPrototypeChain(
- isolate->GetEnteredOrMicrotaskContext()->Global(), isolate);
- if (window_wrapper.IsEmpty())
- return;
- DOMWindow* window = V8Window::ToImpl(window_wrapper);
+ DOMWindow* window = V8Window::ToImplWithTypeCheck(
+ isolate, isolate->GetEnteredOrMicrotaskContext()->Global());
document = window ? To<LocalDOMWindow>(window)->document() : nullptr;
}
if (!document || !document->GetFrame())
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_element_custom.cc b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_element_custom.cc
deleted file mode 100644
index 081981b456c..00000000000
--- a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_element_custom.cc
+++ /dev/null
@@ -1,83 +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/bindings/core/v8/v8_element.h"
-
-#include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_trusted_html.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/platform/bindings/exception_state.h"
-
-namespace blink {
-
-// HTMLElement -----------------------------------------------------------------
-
-void V8Element::InnerHTMLAttributeSetterCustom(
- v8::Local<v8::Value> value,
- const v8::FunctionCallbackInfo<v8::Value>& info) {
- v8::Isolate* isolate = info.GetIsolate();
-
- v8::Local<v8::Object> holder = info.Holder();
-
- Element* impl = V8Element::ToImpl(holder);
-
- V0CustomElementProcessingStack::CallbackDeliveryScope delivery_scope;
-
- ExceptionState exception_state(isolate, ExceptionState::kSetterContext,
- "Element", "innerHTML");
- CEReactionsScope ce_reactions_scope;
-
- // Prepare the value to be set.
- StringOrTrustedHTML cpp_value;
- // This if statement is the only difference to the generated code and ensures
- // that only null but not undefined is treated as the empty string.
- // https://crbug.com/783916
- if (value->IsNull()) {
- cpp_value.SetString(String());
- } else {
- V8StringOrTrustedHTML::ToImpl(isolate, value, cpp_value,
- UnionTypeConversionMode::kNotNullable,
- exception_state);
- }
- if (exception_state.HadException())
- return;
-
- impl->setInnerHTML(cpp_value, exception_state);
-}
-
-void V8Element::OuterHTMLAttributeSetterCustom(
- v8::Local<v8::Value> value,
- const v8::FunctionCallbackInfo<v8::Value>& info) {
- v8::Isolate* isolate = info.GetIsolate();
-
- v8::Local<v8::Object> holder = info.Holder();
-
- Element* impl = V8Element::ToImpl(holder);
-
- V0CustomElementProcessingStack::CallbackDeliveryScope delivery_scope;
-
- ExceptionState exception_state(isolate, ExceptionState::kSetterContext,
- "Element", "outerHTML");
- CEReactionsScope ce_reactions_scope;
-
- // Prepare the value to be set.
- StringOrTrustedHTML cpp_value;
- // This if statement is the only difference to the generated code and ensures
- // that only null but not undefined is treated as the empty string.
- // https://crbug.com/783916
- if (value->IsNull()) {
- cpp_value.SetString(String());
- } else {
- V8StringOrTrustedHTML::ToImpl(isolate, value, cpp_value,
- UnionTypeConversionMode::kNotNullable,
- exception_state);
- }
- if (exception_state.HadException())
- return;
-
- impl->setOuterHTML(cpp_value, exception_state);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_event_target_custom.cc b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_event_target_custom.cc
deleted file mode 100644
index 11e21df8b22..00000000000
--- a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_event_target_custom.cc
+++ /dev/null
@@ -1,67 +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/bindings/core/v8/v8_event_target.h"
-
-#include "third_party/blink/renderer/bindings/core/v8/v8_window.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/web_feature.h"
-#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
-
-namespace blink {
-
-void V8EventTarget::AddEventListenerMethodPrologueCustom(
- const v8::FunctionCallbackInfo<v8::Value>& info,
- EventTarget*) {
- if (info.Length() >= 3 && info[2]->IsObject()) {
- UseCounter::Count(CurrentExecutionContext(info.GetIsolate()),
- WebFeature::kAddEventListenerThirdArgumentIsObject);
- }
- if (info.Length() >= 4) {
- UseCounter::Count(CurrentExecutionContext(info.GetIsolate()),
- WebFeature::kAddEventListenerFourArguments);
- }
-}
-
-void V8EventTarget::RemoveEventListenerMethodPrologueCustom(
- const v8::FunctionCallbackInfo<v8::Value>& info,
- EventTarget*) {
- if (info.Length() >= 3 && info[2]->IsObject()) {
- UseCounter::Count(CurrentExecutionContext(info.GetIsolate()),
- WebFeature::kRemoveEventListenerThirdArgumentIsObject);
- }
- if (info.Length() >= 4) {
- UseCounter::Count(CurrentExecutionContext(info.GetIsolate()),
- WebFeature::kRemoveEventListenerFourArguments);
- }
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_html_all_collection_custom.cc b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_html_all_collection_custom.cc
index 13d8a636ce4..801da460a42 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_html_all_collection_custom.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_html_all_collection_custom.cc
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_html_all_collection.h"
+#include "third_party/blink/renderer/bindings/core/v8/html_collection_or_element.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_message_channel_custom.cc b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_message_channel_custom.cc
deleted file mode 100644
index 8a162d0d385..00000000000
--- a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_message_channel_custom.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2009 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/bindings/core/v8/v8_message_channel.h"
-
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_message_port.h"
-#include "third_party/blink/renderer/core/messaging/message_channel.h"
-#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
-#include "third_party/blink/renderer/platform/bindings/v8_private_property.h"
-
-namespace blink {
-
-const V8PrivateProperty::SymbolKey kPrivatePropertyPort1;
-const V8PrivateProperty::SymbolKey kPrivatePropertyPort2;
-
-void V8MessageChannel::ConstructorCustom(
- const v8::FunctionCallbackInfo<v8::Value>& info) {
- v8::Isolate* isolate = info.GetIsolate();
-
- ExecutionContext* context = CurrentExecutionContext(isolate);
- auto* channel = MakeGarbageCollected<MessageChannel>(context);
-
- v8::Local<v8::Object> wrapper = info.Holder();
-
- // Create references from the MessageChannel wrapper to the two
- // MessagePort wrappers to make sure that the MessagePort wrappers
- // stay alive as long as the MessageChannel wrapper is around.
- V8PrivateProperty::GetSymbol(isolate, kPrivatePropertyPort1)
- .Set(wrapper, ToV8(channel->port1(), wrapper, isolate));
- V8PrivateProperty::GetSymbol(isolate, kPrivatePropertyPort2)
- .Set(wrapper, ToV8(channel->port2(), wrapper, isolate));
-
- V8SetReturnValue(info, V8DOMWrapper::AssociateObjectWithWrapper(
- isolate, channel, GetWrapperTypeInfo(), wrapper));
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_shadow_root_custom.cc b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_shadow_root_custom.cc
deleted file mode 100644
index 8a89c547551..00000000000
--- a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_shadow_root_custom.cc
+++ /dev/null
@@ -1,50 +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/bindings/core/v8/v8_shadow_root.h"
-
-#include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_trusted_html.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/platform/bindings/exception_state.h"
-
-namespace blink {
-
-// HTMLShadowRoot --------------------------------------------------------------
-
-void V8ShadowRoot::InnerHTMLAttributeSetterCustom(
- v8::Local<v8::Value> value,
- const v8::FunctionCallbackInfo<v8::Value>& info) {
- v8::Isolate* isolate = info.GetIsolate();
-
- v8::Local<v8::Object> holder = info.Holder();
-
- ShadowRoot* impl = V8ShadowRoot::ToImpl(holder);
-
- V0CustomElementProcessingStack::CallbackDeliveryScope delivery_scope;
-
- ExceptionState exception_state(isolate, ExceptionState::kSetterContext,
- "ShadowRoot", "innerHTML");
- CEReactionsScope ce_reactions_scope;
-
- // Prepare the value to be set.
- StringOrTrustedHTML cpp_value;
- // This if statement is the only difference to the generated code and ensures
- // that only null but not undefined is treated as the empty string.
- // https://crbug.com/783916
- if (value->IsNull()) {
- cpp_value.SetString(String());
- } else {
- V8StringOrTrustedHTML::ToImpl(isolate, value, cpp_value,
- UnionTypeConversionMode::kNotNullable,
- exception_state);
- }
- if (exception_state.HadException())
- return;
-
- impl->setInnerHTML(cpp_value, exception_state);
-}
-
-} // namespace blink
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 7a5b86fb3cc..00aacbd8a1d 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
@@ -269,11 +269,11 @@ void V8Window::NamedPropertyGetterCustom(
}
// Search named items in the document.
- Document* doc = To<LocalFrame>(frame)->GetDocument();
- if (!doc || !doc->IsHTMLDocument())
+ auto* doc = DynamicTo<HTMLDocument>(To<LocalFrame>(frame)->GetDocument());
+ if (!doc)
return;
- bool has_named_item = ToHTMLDocument(doc)->HasNamedItem(name);
+ bool has_named_item = doc->HasNamedItem(name);
bool has_id_item = doc->HasElementWithId(name);
if (!has_named_item && !has_id_item)
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/dictionary.h b/chromium/third_party/blink/renderer/bindings/core/v8/dictionary.h
index 6fc37eef2cc..3fbc777a5d0 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/dictionary.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/dictionary.h
@@ -26,6 +26,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_DICTIONARY_H_
#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_DICTIONARY_H_
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -44,9 +45,17 @@ class CORE_EXPORT Dictionary final {
public:
Dictionary() : isolate_(nullptr) {}
- Dictionary(v8::Isolate*,
- v8::Local<v8::Value> dictionary_object,
- ExceptionState&);
+ explicit Dictionary(v8::Isolate*,
+ v8::Local<v8::Value> dictionary_object,
+ ExceptionState&);
+ // ScriptValue can refer a V8 object, and such a ScriptValue can be
+ // converted into Dictionary without exceptions.
+ explicit Dictionary(const ScriptValue& script_value)
+ : isolate_(script_value.GetIsolate()) {
+ CHECK(script_value.IsObject());
+ dictionary_object_ = script_value.V8Value().As<v8::Object>();
+ value_type_ = ValueType::kObject;
+ }
Dictionary& operator=(const Dictionary&) = default;
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/dictionary_helper_for_core.cc b/chromium/third_party/blink/renderer/bindings/core/v8/dictionary_helper_for_core.cc
index a0319ea7d20..f08a0549aec 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/dictionary_helper_for_core.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/dictionary_helper_for_core.cc
@@ -24,6 +24,7 @@
*/
#include "third_party/blink/renderer/bindings/core/v8/array_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
#include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer_view.h"
@@ -198,18 +199,9 @@ bool DictionaryHelper::Get(const Dictionary& dictionary,
if (!dictionary.Get(key, v8_value))
return false;
- TrackBase* source = nullptr;
- if (v8_value->IsObject()) {
- v8::Local<v8::Object> wrapper = v8::Local<v8::Object>::Cast(v8_value);
-
- // FIXME: this will need to be changed so it can also return an AudioTrack
- // or a VideoTrack once we add them.
- v8::Local<v8::Object> track = V8TextTrack::FindInstanceInPrototypeChain(
- wrapper, dictionary.GetIsolate());
- if (!track.IsEmpty())
- source = V8TextTrack::ToImpl(track);
- }
- value = source;
+ // FIXME: this will need to be changed so it can also return an AudioTrack
+ // or a VideoTrack once we add them.
+ value = V8TextTrack::ToImplWithTypeCheck(dictionary.GetIsolate(), v8_value);
return true;
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/generated.gni b/chromium/third_party/blink/renderer/bindings/core/v8/generated.gni
new file mode 100644
index 00000000000..009405192df
--- /dev/null
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/generated.gni
@@ -0,0 +1,239 @@
+# 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.
+
+import("//third_party/blink/renderer/bindings/bindings.gni")
+import("//third_party/blink/renderer/bindings/scripts/scripts.gni")
+import("//third_party/blink/renderer/core/core.gni")
+import("//third_party/blink/renderer/core/core_idl_files.gni")
+
+bindings_core_generated_union_type_files = [
+ "$bindings_core_v8_output_dir/add_event_listener_options_or_boolean.cc",
+ "$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/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",
+ "$bindings_core_v8_output_dir/byte_string_sequence_sequence_or_byte_string_byte_string_record.h",
+ "$bindings_core_v8_output_dir/composite_operation_or_auto_or_composite_operation_or_auto_sequence.cc",
+ "$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/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",
+ "$bindings_core_v8_output_dir/double_or_css_numeric_value.h",
+ "$bindings_core_v8_output_dir/double_or_double_or_null_sequence.cc",
+ "$bindings_core_v8_output_dir/double_or_double_or_null_sequence.h",
+ "$bindings_core_v8_output_dir/double_or_double_sequence.cc",
+ "$bindings_core_v8_output_dir/double_or_double_sequence.h",
+ "$bindings_core_v8_output_dir/double_or_internal_enum.cc",
+ "$bindings_core_v8_output_dir/double_or_internal_enum.h",
+ "$bindings_core_v8_output_dir/double_or_scroll_timeline_auto_keyword.cc",
+ "$bindings_core_v8_output_dir/double_or_scroll_timeline_auto_keyword.h",
+ "$bindings_core_v8_output_dir/double_or_string.cc",
+ "$bindings_core_v8_output_dir/double_or_string.h",
+ "$bindings_core_v8_output_dir/double_or_string_or_string_sequence.cc",
+ "$bindings_core_v8_output_dir/double_or_string_or_string_sequence.h",
+ "$bindings_core_v8_output_dir/element_or_document.cc",
+ "$bindings_core_v8_output_dir/element_or_document.h",
+ "$bindings_core_v8_output_dir/event_listener_options_or_boolean.cc",
+ "$bindings_core_v8_output_dir/event_listener_options_or_boolean.h",
+ "$bindings_core_v8_output_dir/file_or_usv_string.cc",
+ "$bindings_core_v8_output_dir/file_or_usv_string.h",
+ "$bindings_core_v8_output_dir/file_or_usv_string_or_form_data.cc",
+ "$bindings_core_v8_output_dir/file_or_usv_string_or_form_data.h",
+ "$bindings_core_v8_output_dir/float_or_string_element_record.cc",
+ "$bindings_core_v8_output_dir/float_or_string_element_record.h",
+ "$bindings_core_v8_output_dir/html_collection_or_element.cc",
+ "$bindings_core_v8_output_dir/html_collection_or_element.h",
+ "$bindings_core_v8_output_dir/html_element_or_long.cc",
+ "$bindings_core_v8_output_dir/html_element_or_long.h",
+ "$bindings_core_v8_output_dir/html_option_element_or_html_opt_group_element.cc",
+ "$bindings_core_v8_output_dir/html_option_element_or_html_opt_group_element.h",
+ "$bindings_core_v8_output_dir/html_script_element_or_svg_script_element.cc",
+ "$bindings_core_v8_output_dir/html_script_element_or_svg_script_element.h",
+ "$bindings_core_v8_output_dir/image_bitmap_source.cc",
+ "$bindings_core_v8_output_dir/image_bitmap_source.h",
+ "$bindings_core_v8_output_dir/internal_enum_or_internal_enum_sequence.cc",
+ "$bindings_core_v8_output_dir/internal_enum_or_internal_enum_sequence.h",
+ "$bindings_core_v8_output_dir/media_list_or_string.cc",
+ "$bindings_core_v8_output_dir/media_list_or_string.h",
+ "$bindings_core_v8_output_dir/node_list_or_element.cc",
+ "$bindings_core_v8_output_dir/node_list_or_element.h",
+ "$bindings_core_v8_output_dir/node_or_string_or_trusted_script.cc",
+ "$bindings_core_v8_output_dir/node_or_string_or_trusted_script.h",
+ "$bindings_core_v8_output_dir/radio_node_list_or_element.cc",
+ "$bindings_core_v8_output_dir/radio_node_list_or_element.h",
+ "$bindings_core_v8_output_dir/request_or_usv_string.cc",
+ "$bindings_core_v8_output_dir/request_or_usv_string.h",
+ "$bindings_core_v8_output_dir/scroll_into_view_options_or_boolean.cc",
+ "$bindings_core_v8_output_dir/scroll_into_view_options_or_boolean.h",
+ "$bindings_core_v8_output_dir/string_or_array_buffer.cc",
+ "$bindings_core_v8_output_dir/string_or_array_buffer.h",
+ "$bindings_core_v8_output_dir/string_or_array_buffer_or_array_buffer_view.cc",
+ "$bindings_core_v8_output_dir/string_or_array_buffer_or_array_buffer_view.h",
+ "$bindings_core_v8_output_dir/string_or_css_variable_reference_value.cc",
+ "$bindings_core_v8_output_dir/string_or_css_variable_reference_value.h",
+ "$bindings_core_v8_output_dir/string_or_double.cc",
+ "$bindings_core_v8_output_dir/string_or_double.h",
+ "$bindings_core_v8_output_dir/string_or_element_creation_options.cc",
+ "$bindings_core_v8_output_dir/string_or_element_creation_options.h",
+ "$bindings_core_v8_output_dir/string_or_performance_measure_options.cc",
+ "$bindings_core_v8_output_dir/string_or_performance_measure_options.h",
+ "$bindings_core_v8_output_dir/string_or_string_sequence.cc",
+ "$bindings_core_v8_output_dir/string_or_string_sequence.h",
+ "$bindings_core_v8_output_dir/string_or_trusted_html_or_trusted_script_or_trusted_script_url.cc",
+ "$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_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",
+ "$bindings_core_v8_output_dir/string_or_worker_options.h",
+ "$bindings_core_v8_output_dir/string_treat_null_as_empty_string_or_trusted_script.cc",
+ "$bindings_core_v8_output_dir/string_treat_null_as_empty_string_or_trusted_script.h",
+ "$bindings_core_v8_output_dir/uint8_clamped_array_or_uint16_array_or_float32_array.cc",
+ "$bindings_core_v8_output_dir/uint8_clamped_array_or_uint16_array_or_float32_array.h",
+ "$bindings_core_v8_output_dir/unrestricted_double_or_keyframe_animation_options.cc",
+ "$bindings_core_v8_output_dir/unrestricted_double_or_keyframe_animation_options.h",
+ "$bindings_core_v8_output_dir/unrestricted_double_or_keyframe_effect_options.cc",
+ "$bindings_core_v8_output_dir/unrestricted_double_or_keyframe_effect_options.h",
+ "$bindings_core_v8_output_dir/unrestricted_double_or_string.cc",
+ "$bindings_core_v8_output_dir/unrestricted_double_or_string.h",
+ "$bindings_core_v8_output_dir/usv_string_sequence_sequence_or_usv_string_usv_string_record_or_usv_string.cc",
+ "$bindings_core_v8_output_dir/usv_string_sequence_sequence_or_usv_string_usv_string_record_or_usv_string.h",
+ "$bindings_core_v8_output_dir/video_track_or_audio_track_or_text_track.cc",
+ "$bindings_core_v8_output_dir/video_track_or_audio_track_or_text_track.h",
+]
+
+generated_core_testing_callback_function_files = [
+ "$bindings_core_v8_output_dir/v8_test_callback.cc",
+ "$bindings_core_v8_output_dir/v8_test_callback.h",
+ "$bindings_core_v8_output_dir/v8_test_enum_callback.cc",
+ "$bindings_core_v8_output_dir/v8_test_enum_callback.h",
+ "$bindings_core_v8_output_dir/v8_test_interface_callback.cc",
+ "$bindings_core_v8_output_dir/v8_test_interface_callback.h",
+ "$bindings_core_v8_output_dir/v8_test_receiver_object_callback.cc",
+ "$bindings_core_v8_output_dir/v8_test_receiver_object_callback.h",
+ "$bindings_core_v8_output_dir/v8_test_sequence_callback.cc",
+ "$bindings_core_v8_output_dir/v8_test_sequence_callback.h",
+]
+
+generated_core_callback_function_files = [
+ "$bindings_core_v8_output_dir/v8_blob_callback.cc",
+ "$bindings_core_v8_output_dir/v8_blob_callback.h",
+ "$bindings_core_v8_output_dir/v8_create_html_callback.cc",
+ "$bindings_core_v8_output_dir/v8_create_html_callback.h",
+ "$bindings_core_v8_output_dir/v8_create_script_callback.cc",
+ "$bindings_core_v8_output_dir/v8_create_script_callback.h",
+ "$bindings_core_v8_output_dir/v8_create_url_callback.cc",
+ "$bindings_core_v8_output_dir/v8_create_url_callback.h",
+ "$bindings_core_v8_output_dir/v8_custom_element_adopted_callback.cc",
+ "$bindings_core_v8_output_dir/v8_custom_element_adopted_callback.h",
+ "$bindings_core_v8_output_dir/v8_custom_element_attribute_changed_callback.cc",
+ "$bindings_core_v8_output_dir/v8_custom_element_attribute_changed_callback.h",
+ "$bindings_core_v8_output_dir/v8_custom_element_constructor.cc",
+ "$bindings_core_v8_output_dir/v8_custom_element_constructor.h",
+ "$bindings_core_v8_output_dir/v8_custom_element_form_associated_callback.cc",
+ "$bindings_core_v8_output_dir/v8_custom_element_form_associated_callback.h",
+ "$bindings_core_v8_output_dir/v8_custom_element_form_disabled_callback.cc",
+ "$bindings_core_v8_output_dir/v8_custom_element_form_disabled_callback.h",
+ "$bindings_core_v8_output_dir/v8_custom_element_form_state_restore_callback.cc",
+ "$bindings_core_v8_output_dir/v8_custom_element_form_state_restore_callback.h",
+ "$bindings_core_v8_output_dir/v8_event_handler_non_null.cc",
+ "$bindings_core_v8_output_dir/v8_event_handler_non_null.h",
+ "$bindings_core_v8_output_dir/v8_for_each_iterator_callback.cc",
+ "$bindings_core_v8_output_dir/v8_for_each_iterator_callback.h",
+ "$bindings_core_v8_output_dir/v8_frame_request_callback.cc",
+ "$bindings_core_v8_output_dir/v8_frame_request_callback.h",
+ "$bindings_core_v8_output_dir/v8_function.cc",
+ "$bindings_core_v8_output_dir/v8_function.h",
+ "$bindings_core_v8_output_dir/v8_function_string_callback.cc",
+ "$bindings_core_v8_output_dir/v8_function_string_callback.h",
+ "$bindings_core_v8_output_dir/v8_idle_request_callback.cc",
+ "$bindings_core_v8_output_dir/v8_idle_request_callback.h",
+ "$bindings_core_v8_output_dir/v8_intersection_observer_callback.cc",
+ "$bindings_core_v8_output_dir/v8_intersection_observer_callback.h",
+ "$bindings_core_v8_output_dir/v8_intrinsic_sizes_callback.cc",
+ "$bindings_core_v8_output_dir/v8_intrinsic_sizes_callback.h",
+ "$bindings_core_v8_output_dir/v8_layout_callback.cc",
+ "$bindings_core_v8_output_dir/v8_layout_callback.h",
+ "$bindings_core_v8_output_dir/v8_mojo_watch_callback.cc",
+ "$bindings_core_v8_output_dir/v8_mojo_watch_callback.h",
+ "$bindings_core_v8_output_dir/v8_mutation_callback.cc",
+ "$bindings_core_v8_output_dir/v8_mutation_callback.h",
+ "$bindings_core_v8_output_dir/v8_no_argument_constructor.cc",
+ "$bindings_core_v8_output_dir/v8_no_argument_constructor.h",
+ "$bindings_core_v8_output_dir/v8_performance_observer_callback.cc",
+ "$bindings_core_v8_output_dir/v8_performance_observer_callback.h",
+ "$bindings_core_v8_output_dir/v8_reporting_observer_callback.cc",
+ "$bindings_core_v8_output_dir/v8_reporting_observer_callback.h",
+ "$bindings_core_v8_output_dir/v8_resize_observer_callback.cc",
+ "$bindings_core_v8_output_dir/v8_resize_observer_callback.h",
+ "$bindings_core_v8_output_dir/v8_scroll_state_callback.cc",
+ "$bindings_core_v8_output_dir/v8_scroll_state_callback.h",
+ "$bindings_core_v8_output_dir/v8_void_function.cc",
+ "$bindings_core_v8_output_dir/v8_void_function.h",
+]
+
+if (is_win && is_official_build) {
+ # On Windows Official release builds, we try to preserve symbol space.
+ # is_official_build adds /GL option and /LTCG automatically in link.exe.
+ # But link.exe cannot make binary smaller than its size limit from
+ # many obj files for bindings_core_impl.lib.
+ bindings_core_generated_interface_files =
+ [ "$bindings_core_v8_output_dir/v8_generated_core_bindings.cc" ]
+} else {
+ _core_definition_idl_files = core_definition_idl_files
+ if (use_v8_bind_gen_for_dictionary) {
+ _core_definition_idl_files -= core_dictionary_idl_files
+ }
+ bindings_core_generated_interface_files =
+ process_file_template(
+ _core_definition_idl_files,
+ [
+ "$bindings_core_v8_output_dir/v8_{{source_name_part}}.cc",
+ "$bindings_core_v8_output_dir/v8_{{source_name_part}}.h",
+ ])
+}
+
+generated_core_dictionary_files = []
+generated_demo_files = []
+
+if (use_v8_bind_gen_for_dictionary) {
+ generated_core_dictionary_files +=
+ process_file_template(
+ core_dictionary_idl_files,
+ [
+ "$bindings_core_v8_output_dir/v8_{{source_name_part}}.cc",
+ "$bindings_core_v8_output_dir/v8_{{source_name_part}}.h",
+ ])
+
+ generated_core_testing_dictionary_files =
+ process_file_template(
+ core_testing_dictionary_idl_files,
+ [
+ "$bindings_core_v8_output_dir/v8_{{source_name_part}}.cc",
+ "$bindings_core_v8_output_dir/v8_{{source_name_part}}.h",
+ ])
+
+ # Generated file from demonstration_and_testing.idl, which won't be compiled.
+ generated_demo_files += [
+ "$bindings_core_v8_output_dir/v8_example_dictionary.cc",
+ "$bindings_core_v8_output_dir/v8_example_dictionary.h",
+ ]
+} else {
+ generated_core_testing_dictionary_files =
+ process_file_template(
+ core_testing_dictionary_idl_files,
+ [
+ "$blink_core_output_dir/testing/{{source_name_part}}.cc",
+ "$blink_core_output_dir/testing/{{source_name_part}}.h",
+ ])
+}
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 d455494dec7..59b2a13b12d 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
@@ -5,12 +5,15 @@
#include "third_party/blink/renderer/bindings/core/v8/generated_code_helper.h"
#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
-#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_element.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/execution_context/execution_context.h"
+#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/xml/dom_parser.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_context_data.h"
namespace blink {
@@ -29,13 +32,6 @@ void V8ConstructorAttributeGetter(
per_context_data->ConstructorForType(wrapper_type_info));
}
-v8::Local<v8::Value> V8Deserialize(v8::Isolate* isolate,
- SerializedScriptValue* value) {
- if (value)
- return value->Deserialize(isolate);
- return v8::Null(isolate);
-}
-
namespace {
enum class IgnorePause { kDontIgnore, kIgnore };
@@ -158,4 +154,93 @@ void V8SetReflectedNullableDOMStringAttribute(
impl->setAttribute(content_attr, cpp_value);
}
+namespace bindings {
+
+base::Optional<size_t> FindIndexInEnumStringTable(
+ v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ base::span<const char* const> enum_value_table,
+ const char* enum_type_name,
+ ExceptionState& exception_state) {
+ const String& str_value = NativeValueTraits<IDLStringV2>::NativeValue(
+ isolate, value, exception_state);
+ if (exception_state.HadException())
+ return base::nullopt;
+
+ base::Optional<size_t> index =
+ FindIndexInEnumStringTable(str_value, enum_value_table);
+
+ if (!index.has_value()) {
+ exception_state.ThrowTypeError("The provided value '" + str_value +
+ "' is not a valid enum value of type " +
+ enum_type_name + ".");
+ }
+ return index;
+}
+
+base::Optional<size_t> FindIndexInEnumStringTable(
+ const String& str_value,
+ base::span<const char* const> enum_value_table) {
+ for (size_t i = 0; i < enum_value_table.size(); ++i) {
+ if (Equal(str_value.Impl(), enum_value_table[i]))
+ return i;
+ }
+ return base::nullopt;
+}
+
+bool IsEsIterableObject(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ // https://heycam.github.io/webidl/#es-overloads
+ // step 9. Otherwise: if Type(V) is Object and ...
+ if (!value->IsObject())
+ return false;
+
+ // step 9.1. Let method be ? GetMethod(V, @@iterator).
+ // https://tc39.es/ecma262/#sec-getmethod
+ v8::TryCatch try_catch(isolate);
+ v8::Local<v8::Value> iterator_key = v8::Symbol::GetIterator(isolate);
+ v8::Local<v8::Value> iterator_value;
+ if (!value.As<v8::Object>()
+ ->Get(isolate->GetCurrentContext(), iterator_key)
+ .ToLocal(&iterator_value)) {
+ exception_state.RethrowV8Exception(try_catch.Exception());
+ return false;
+ }
+
+ if (iterator_value->IsNullOrUndefined())
+ return false;
+
+ if (!iterator_value->IsFunction()) {
+ exception_state.ThrowTypeError("@@iterator must be a function");
+ return false;
+ }
+
+ return true;
+}
+
+Document* ToDocumentFromExecutionContext(ExecutionContext* execution_context) {
+ return execution_context->ExecutingWindow()->document();
+}
+
+ExecutionContext* ExecutionContextFromV8Wrappable(const Range* range) {
+ return range->startContainer()->GetDocument().ToExecutionContext();
+}
+
+ExecutionContext* ExecutionContextFromV8Wrappable(const DOMParser* parser) {
+ return parser->GetDocument() ? parser->GetDocument()->ToExecutionContext()
+ : nullptr;
+}
+
+v8::Local<v8::Array> EnumerateIndexedProperties(v8::Isolate* isolate,
+ uint32_t length) {
+ Vector<v8::Local<v8::Value>> elements;
+ elements.ReserveCapacity(length);
+ for (uint32_t i = 0; i < length; ++i)
+ elements.UncheckedAppend(v8::Integer::New(isolate, i));
+ return v8::Array::New(isolate, elements.data(), elements.size());
+}
+
+} // namespace bindings
+
} // namespace blink
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 28acbe692a7..b461f479f72 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
@@ -2,35 +2,35 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// This file is for functions that are used only by generated code.
-// CAUTION:
-// All functions defined in this file should be used by generated code only.
-// If you want to use them from hand-written code, please find appropriate
-// location and move them to that location.
+// This file provides utilities to be used only by generated bindings code.
+//
+// CAUTION: Do not use this header outside generated bindings code.
#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_GENERATED_CODE_HELPER_H_
#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_GENERATED_CODE_HELPER_H_
+#include "third_party/blink/renderer/bindings/core/v8/idl_types.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_target.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"
namespace blink {
+class Document;
+class DOMParser;
+class ExecutionContext;
+class Range;
class QualifiedName;
class ScriptState;
-class SerializedScriptValue;
CORE_EXPORT void V8ConstructorAttributeGetter(
v8::Local<v8::Name> property_name,
const v8::PropertyCallbackInfo<v8::Value>&,
const WrapperTypeInfo*);
-CORE_EXPORT v8::Local<v8::Value> V8Deserialize(v8::Isolate*,
- SerializedScriptValue*);
-
// ExceptionToRejectPromiseScope converts a possible exception to a reject
// promise and returns the promise instead of throwing the exception.
//
@@ -96,6 +96,67 @@ void V8SetReflectedNullableDOMStringAttribute(
const v8::FunctionCallbackInfo<v8::Value>& info,
const QualifiedName& content_attr);
+namespace bindings {
+
+template <typename T, typename... ExtraArgs>
+typename IDLSequence<T>::ImplType VariadicArgumentsToNativeValues(
+ v8::Isolate* isolate,
+ const v8::FunctionCallbackInfo<v8::Value>& info,
+ int start_index,
+ ExceptionState& exception_state,
+ ExtraArgs... extra_args) {
+ using VectorType = typename IDLSequence<T>::ImplType;
+
+ const int length = info.Length();
+ if (start_index >= length)
+ return VectorType();
+
+ VectorType result;
+ result.ReserveInitialCapacity(length - start_index);
+ for (int i = start_index; i < length; ++i) {
+ result.UncheckedAppend(NativeValueTraits<T>::ArgumentValue(
+ isolate, i, info[i], exception_state, extra_args...));
+ if (exception_state.HadException())
+ return VectorType();
+ }
+ return std::move(result);
+}
+
+CORE_EXPORT base::Optional<size_t> FindIndexInEnumStringTable(
+ v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ base::span<const char* const> enum_value_table,
+ const char* enum_type_name,
+ ExceptionState& exception_state);
+
+CORE_EXPORT base::Optional<size_t> FindIndexInEnumStringTable(
+ const String& str_value,
+ base::span<const char* const> enum_value_table);
+
+CORE_EXPORT bool IsEsIterableObject(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state);
+
+CORE_EXPORT Document* ToDocumentFromExecutionContext(
+ ExecutionContext* execution_context);
+
+// This function is mostly used for EventTargets, and so this version is
+// inlined. The less commonly used overloads are defined in the .cc file.
+CORE_EXPORT inline ExecutionContext* ExecutionContextFromV8Wrappable(
+ const EventTarget* event_target) {
+ return event_target->GetExecutionContext();
+}
+CORE_EXPORT ExecutionContext* ExecutionContextFromV8Wrappable(
+ const Range* range);
+CORE_EXPORT ExecutionContext* ExecutionContextFromV8Wrappable(
+ const DOMParser* parser);
+
+CORE_EXPORT v8::Local<v8::Array> EnumerateIndexedProperties(
+ v8::Isolate* isolate,
+ uint32_t length);
+
+} // namespace bindings
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_GENERATED_CODE_HELPER_H_
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 81829b165bf..d2634225fc6 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(blink::Visitor* visitor) {}
+void IDLDictionaryBase::Trace(Visitor* visitor) {}
} // 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 5e20c3cff75..fb924d34f26 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(blink::Visitor*);
+ virtual void Trace(Visitor*);
protected:
IDLDictionaryBase() = default;
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/idl_types.h b/chromium/third_party/blink/renderer/bindings/core/v8/idl_types.h
index cb2cb9ab258..2974ff8c2aa 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/idl_types.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/idl_types.h
@@ -6,52 +6,102 @@
#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_IDL_TYPES_H_
#include <type_traits>
+
#include "base/optional.h"
+#include "base/template_util.h"
#include "base/time/time.h"
#include "third_party/blink/renderer/bindings/core/v8/idl_types_base.h"
#include "third_party/blink/renderer/bindings/core/v8/native_value_traits.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_string_resource.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
+class EventListener;
class ScriptPromise;
+class ScriptValue;
+
+// The type names below are named as "IDL" prefix + Web IDL type name.
+// https://heycam.github.io/webidl/#dfn-type-name
+
+// any
+struct IDLAny final : public IDLBaseHelper<ScriptValue> {};
-// Boolean
+// boolean
struct IDLBoolean final : public IDLBaseHelper<bool> {};
+// Integer types
+
+namespace bindings {
+
+enum class IDLIntegerConvMode {
+ kDefault,
+ kClamp,
+ kEnforceRange,
+};
+
+} // namespace bindings
+
+template <typename T,
+ bindings::IDLIntegerConvMode mode =
+ bindings::IDLIntegerConvMode::kDefault>
+struct IDLIntegerTypeBase final : public IDLBaseHelper<T> {};
+
// Integers
-struct IDLByte final : public IDLBaseHelper<int8_t> {};
-struct IDLOctet final : public IDLBaseHelper<uint8_t> {};
-struct IDLShort final : public IDLBaseHelper<int16_t> {};
-struct IDLUnsignedShort final : public IDLBaseHelper<uint16_t> {};
-struct IDLLong final : public IDLBaseHelper<int32_t> {};
-struct IDLUnsignedLong final : public IDLBaseHelper<uint32_t> {};
-struct IDLLongLong final : public IDLBaseHelper<int64_t> {};
-struct IDLUnsignedLongLong final : public IDLBaseHelper<uint64_t> {};
+using IDLByte = IDLIntegerTypeBase<int8_t>;
+using IDLOctet = IDLIntegerTypeBase<uint8_t>;
+using IDLShort = IDLIntegerTypeBase<int16_t>;
+using IDLUnsignedShort = IDLIntegerTypeBase<uint16_t>;
+using IDLLong = IDLIntegerTypeBase<int32_t>;
+using IDLUnsignedLong = IDLIntegerTypeBase<uint32_t>;
+using IDLLongLong = IDLIntegerTypeBase<int64_t>;
+using IDLUnsignedLongLong = IDLIntegerTypeBase<uint64_t>;
// [Clamp] Integers
-struct IDLByteClamp final : public IDLBaseHelper<int8_t> {};
-struct IDLOctetClamp final : public IDLBaseHelper<uint8_t> {};
-struct IDLShortClamp final : public IDLBaseHelper<int16_t> {};
-struct IDLUnsignedShortClamp final : public IDLBaseHelper<uint16_t> {};
-struct IDLLongClamp final : public IDLBaseHelper<int32_t> {};
-struct IDLUnsignedLongClamp final : public IDLBaseHelper<uint32_t> {};
-struct IDLLongLongClamp final : public IDLBaseHelper<int64_t> {};
-struct IDLUnsignedLongLongClamp final : public IDLBaseHelper<uint64_t> {};
+using IDLByteClamp =
+ IDLIntegerTypeBase<int8_t, bindings::IDLIntegerConvMode::kClamp>;
+using IDLOctetClamp =
+ IDLIntegerTypeBase<uint8_t, bindings::IDLIntegerConvMode::kClamp>;
+using IDLShortClamp =
+ IDLIntegerTypeBase<int16_t, bindings::IDLIntegerConvMode::kClamp>;
+using IDLUnsignedShortClamp =
+ IDLIntegerTypeBase<uint16_t, bindings::IDLIntegerConvMode::kClamp>;
+using IDLLongClamp =
+ IDLIntegerTypeBase<int32_t, bindings::IDLIntegerConvMode::kClamp>;
+using IDLUnsignedLongClamp =
+ IDLIntegerTypeBase<uint32_t, bindings::IDLIntegerConvMode::kClamp>;
+using IDLLongLongClamp =
+ IDLIntegerTypeBase<int64_t, bindings::IDLIntegerConvMode::kClamp>;
+using IDLUnsignedLongLongClamp =
+ IDLIntegerTypeBase<uint64_t, bindings::IDLIntegerConvMode::kClamp>;
// [EnforceRange] Integers
-struct IDLByteEnforceRange final : public IDLBaseHelper<int8_t> {};
-struct IDLOctetEnforceRange final : public IDLBaseHelper<uint8_t> {};
-struct IDLShortEnforceRange final : public IDLBaseHelper<int16_t> {};
-struct IDLUnsignedShortEnforceRange final : public IDLBaseHelper<uint16_t> {};
-struct IDLLongEnforceRange final : public IDLBaseHelper<int32_t> {};
-struct IDLUnsignedLongEnforceRange final : public IDLBaseHelper<uint32_t> {};
-struct IDLLongLongEnforceRange final : public IDLBaseHelper<int64_t> {};
-struct IDLUnsignedLongLongEnforceRange final : public IDLBaseHelper<uint64_t> {
-};
+using IDLByteEnforceRange =
+ IDLIntegerTypeBase<int8_t, bindings::IDLIntegerConvMode::kEnforceRange>;
+using IDLOctetEnforceRange =
+ IDLIntegerTypeBase<uint8_t, bindings::IDLIntegerConvMode::kEnforceRange>;
+using IDLShortEnforceRange =
+ IDLIntegerTypeBase<int16_t, bindings::IDLIntegerConvMode::kEnforceRange>;
+using IDLUnsignedShortEnforceRange =
+ IDLIntegerTypeBase<uint16_t, bindings::IDLIntegerConvMode::kEnforceRange>;
+using IDLLongEnforceRange =
+ IDLIntegerTypeBase<int32_t, bindings::IDLIntegerConvMode::kEnforceRange>;
+using IDLUnsignedLongEnforceRange =
+ IDLIntegerTypeBase<uint32_t, bindings::IDLIntegerConvMode::kEnforceRange>;
+using IDLLongLongEnforceRange =
+ IDLIntegerTypeBase<int64_t, bindings::IDLIntegerConvMode::kEnforceRange>;
+using IDLUnsignedLongLongEnforceRange =
+ IDLIntegerTypeBase<uint64_t, bindings::IDLIntegerConvMode::kEnforceRange>;
+
+// float
+struct IDLFloat final : public IDLBaseHelper<float> {};
+struct IDLUnrestrictedFloat final : public IDLBaseHelper<float> {};
+
+// double
+struct IDLDouble final : public IDLBaseHelper<double> {};
+struct IDLUnrestrictedDouble final : public IDLBaseHelper<double> {};
// Strings
// The "Base" classes are always templatized and require users to specify how JS
@@ -63,6 +113,16 @@ struct IDLStringBase final : public IDLBaseHelper<String> {};
template <V8StringResourceMode Mode>
struct IDLUSVStringBase final : public IDLBaseHelper<String> {};
+template <V8StringResourceMode Mode>
+struct IDLStringStringContextTrustedHTMLBase final
+ : public IDLBaseHelper<String> {};
+template <V8StringResourceMode Mode>
+struct IDLStringStringContextTrustedScriptBase final
+ : public IDLBaseHelper<String> {};
+template <V8StringResourceMode Mode>
+struct IDLUSVStringStringContextTrustedScriptURLBase final
+ : public IDLBaseHelper<String> {};
+
// Define non-template versions of the above for simplicity.
using IDLByteString = IDLByteStringBase<V8StringResourceMode::kDefaultMode>;
using IDLString = IDLStringBase<V8StringResourceMode::kDefaultMode>;
@@ -80,74 +140,143 @@ using IDLUSVStringOrNull =
using IDLStringTreatNullAsEmptyString =
IDLStringBase<V8StringResourceMode::kTreatNullAsEmptyString>;
-// Double
-struct IDLDouble final : public IDLBaseHelper<double> {};
-struct IDLUnrestrictedDouble final : public IDLBaseHelper<double> {};
+// [StringContext] Strings
+using IDLStringStringContextTrustedHTML =
+ IDLStringStringContextTrustedHTMLBase<V8StringResourceMode::kDefaultMode>;
+using IDLStringStringContextTrustedScript =
+ IDLStringStringContextTrustedScriptBase<V8StringResourceMode::kDefaultMode>;
+using IDLUSVStringStringContextTrustedScriptURL =
+ IDLUSVStringStringContextTrustedScriptURLBase<
+ V8StringResourceMode::kDefaultMode>;
+using IDLStringStringContextTrustedHTMLOrNull =
+ IDLStringStringContextTrustedHTMLBase<
+ V8StringResourceMode::kTreatNullAndUndefinedAsNullString>;
+using IDLStringStringContextTrustedScriptOrNull =
+ IDLStringStringContextTrustedScriptBase<
+ V8StringResourceMode::kTreatNullAndUndefinedAsNullString>;
+using IDLUSVStringStringContextTrustedScriptURLOrNull =
+ IDLUSVStringStringContextTrustedScriptURLBase<
+ V8StringResourceMode::kTreatNullAndUndefinedAsNullString>;
+using IDLStringStringContextTrustedHTMLTreatNullAsEmptyString =
+ IDLStringStringContextTrustedHTMLBase<
+ V8StringResourceMode::kTreatNullAsEmptyString>;
+using IDLStringStringContextTrustedScriptTreatNullAsEmptyString =
+ IDLStringStringContextTrustedScriptBase<
+ V8StringResourceMode::kTreatNullAsEmptyString>;
+using IDLUSVStringStringContextTrustedScriptURLTreatNullAsEmptyString =
+ IDLUSVStringStringContextTrustedScriptURLBase<
+ V8StringResourceMode::kTreatNullAsEmptyString>;
-// Float
-struct IDLFloat final : public IDLBaseHelper<float> {};
-struct IDLUnrestrictedFloat final : public IDLBaseHelper<float> {};
+// Strings for the new bindings generator
-// Nullable Date
-struct IDLDateOrNull final : public IDLBaseHelper<base::Optional<base::Time>> {
+namespace bindings {
+
+enum class IDLStringConvMode {
+ kDefault,
+ kNullable,
+ kTreatNullAsEmptyString,
};
-// Promise
+} // namespace bindings
+
+// ByteString
+template <bindings::IDLStringConvMode mode>
+struct IDLByteStringBaseV2 final : public IDLBaseHelper<String> {};
+using IDLByteStringV2 =
+ IDLByteStringBaseV2<bindings::IDLStringConvMode::kDefault>;
+
+// DOMString
+template <bindings::IDLStringConvMode mode>
+struct IDLStringBaseV2 final : public IDLBaseHelper<String> {};
+using IDLStringV2 = IDLStringBaseV2<bindings::IDLStringConvMode::kDefault>;
+using IDLStringTreatNullAsEmptyStringV2 =
+ IDLStringBaseV2<bindings::IDLStringConvMode::kTreatNullAsEmptyString>;
+
+// USVString
+template <bindings::IDLStringConvMode mode>
+struct IDLUSVStringBaseV2 final : public IDLBaseHelper<String> {};
+using IDLUSVStringV2 =
+ IDLUSVStringBaseV2<bindings::IDLStringConvMode::kDefault>;
+
+// [StringContext=TrustedHTML] DOMString
+template <bindings::IDLStringConvMode mode>
+struct IDLStringStringContextTrustedHTMLBaseV2 final
+ : public IDLBaseHelper<String> {};
+using IDLStringStringContextTrustedHTMLV2 =
+ IDLStringStringContextTrustedHTMLBaseV2<
+ bindings::IDLStringConvMode::kDefault>;
+using IDLStringStringContextTrustedHTMLTreatNullAsEmptyStringV2 =
+ IDLStringStringContextTrustedHTMLBaseV2<
+ bindings::IDLStringConvMode::kTreatNullAsEmptyString>;
+
+// [StringContext=TrustedScript] DOMString
+template <bindings::IDLStringConvMode mode>
+struct IDLStringStringContextTrustedScriptBaseV2 final
+ : public IDLBaseHelper<String> {};
+using IDLStringStringContextTrustedScriptV2 =
+ IDLStringStringContextTrustedScriptBaseV2<
+ bindings::IDLStringConvMode::kDefault>;
+using IDLStringStringContextTrustedScriptTreatNullAsEmptyStringV2 =
+ IDLStringStringContextTrustedScriptBaseV2<
+ bindings::IDLStringConvMode::kTreatNullAsEmptyString>;
+
+// [StringContext=TrustedScriptURL] USVString
+template <bindings::IDLStringConvMode mode>
+struct IDLUSVStringStringContextTrustedScriptURLBaseV2 final
+ : public IDLBaseHelper<String> {};
+using IDLUSVStringStringContextTrustedScriptURLV2 =
+ IDLUSVStringStringContextTrustedScriptURLBaseV2<
+ bindings::IDLStringConvMode::kDefault>;
+
+// object
+struct IDLObject final : public IDLBaseHelper<ScriptValue> {};
+
+// Promise types
struct IDLPromise final : public IDLBaseHelper<ScriptPromise> {};
-// Sequence
+// Sequence types
template <typename T>
struct IDLSequence final : public IDLBase {
- using ImplType = VectorOf<typename NativeValueTraits<T>::ImplType>;
+ using ImplType =
+ VectorOf<std::remove_pointer_t<typename NativeValueTraits<T>::ImplType>>;
};
-// Record
+// Frozen array types
+template <typename T>
+using IDLArray = IDLSequence<T>;
+
+// Record types
template <typename Key, typename Value>
struct IDLRecord final : public IDLBase {
- static_assert(std::is_same<Key, IDLByteString>::value ||
- std::is_same<Key, IDLString>::value ||
- std::is_same<Key, IDLUSVString>::value,
+ static_assert(std::is_same<typename Key::ImplType, String>::value,
"IDLRecord keys must be of a WebIDL string type");
+ static_assert(
+ std::is_same<typename NativeValueTraits<Key>::ImplType, String>::value,
+ "IDLRecord keys must be of a WebIDL string type");
- using ImplType =
- VectorOfPairs<String, typename NativeValueTraits<Value>::ImplType>;
+ using ImplType = VectorOfPairs<
+ String,
+ std::remove_pointer_t<typename NativeValueTraits<Value>::ImplType>>;
};
-// Nullable (T?).
-// https://heycam.github.io/webidl/#idl-nullable-type
-// Types without a built-in notion of nullability are mapped to
-// base::Optional<T>.
-template <typename InnerType, typename = void>
+// Nullable types
+template <typename T>
struct IDLNullable final : public IDLBase {
- private:
- using InnerTraits = NativeValueTraits<InnerType>;
- using InnerResultType =
- decltype(InnerTraits::NativeValue(std::declval<v8::Isolate*>(),
- v8::Local<v8::Value>(),
- std::declval<ExceptionState&>()));
-
- public:
- using ResultType = base::Optional<std::decay_t<InnerResultType>>;
- using ImplType = ResultType;
- static inline ResultType NullValue() { return base::nullopt; }
-};
-template <typename InnerType>
-struct IDLNullable<InnerType,
- decltype(void(NativeValueTraits<InnerType>::NullValue()))>
- final : public IDLBase {
- private:
- using InnerTraits = NativeValueTraits<InnerType>;
- using InnerResultType =
- decltype(InnerTraits::NativeValue(std::declval<v8::Isolate*>(),
- v8::Local<v8::Value>(),
- std::declval<ExceptionState&>()));
-
- public:
- using ResultType = InnerResultType;
- using ImplType = typename InnerTraits::ImplType;
- static inline ResultType NullValue() { return InnerTraits::NullValue(); }
+ using ImplType = std::conditional_t<
+ NativeValueTraits<T>::has_null_value,
+ typename NativeValueTraits<T>::ImplType,
+ base::Optional<typename NativeValueTraits<T>::ImplType>>;
};
+// Date
+struct IDLDate final : public IDLBaseHelper<base::Time> {};
+
+// EventHandler types
+struct IDLEventHandler final : public IDLBaseHelper<EventListener*> {};
+struct IDLOnBeforeUnloadEventHandler final
+ : public IDLBaseHelper<EventListener*> {};
+struct IDLOnErrorEventHandler final : public IDLBaseHelper<EventListener*> {};
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_IDL_TYPES_H_
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/idl_types_base.h b/chromium/third_party/blink/renderer/bindings/core/v8/idl_types_base.h
index b19962e8d11..86ea6d5dad8 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/idl_types_base.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/idl_types_base.h
@@ -7,8 +7,8 @@
namespace blink {
-// This is the base type for all WebIDL types, such as the ones defined in
-// IDLTypes.h. It is defined in a separate location to avoid circular header
+// This is the base type for all Web IDL types, such as the ones defined in
+// idl_types.h. It is defined in a separate location to avoid circular header
// inclusions when one only needs to check if a type inherits from IDLBase.
struct IDLBase {
using ImplType = void;
@@ -18,7 +18,7 @@ struct IDLBase {
// can inherit from IDLBaseHelper to avoid having to set ImplType on its own.
//
// Example:
-// struct MyType<double> final : public IDLBaseHelper<double> {};
+// struct IDLDouble final : public IDLBaseHelper<double> {};
template <typename T>
struct IDLBaseHelper : public IDLBase {
using ImplType = T;
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/idl_types_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/idl_types_test.cc
index 2e4af559d08..dcd7e9dfbdb 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/idl_types_test.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/idl_types_test.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
#include <type_traits>
+
#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_string_sequence.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_element.h"
@@ -142,14 +143,14 @@ static_assert(
static_assert(std::is_base_of<IDLBase, IDLNullable<IDLDouble>>::value,
"IDLNullable should have IDLBase as a base class");
-static_assert(std::is_same<IDLNullable<IDLDouble>::ResultType,
+static_assert(std::is_same<IDLNullable<IDLDouble>::ImplType,
base::Optional<double>>::value,
"double? corresponds to base::Optional<double>");
-static_assert(std::is_same<IDLNullable<Element>::ResultType, Element*>::value,
+static_assert(std::is_same<IDLNullable<Element>::ImplType, Element*>::value,
"Element? doesn't require a base::Optional<> wrapper");
-static_assert(std::is_same<IDLNullable<IDLString>::ResultType, String>::value,
+static_assert(std::is_same<IDLNullable<IDLString>::ImplType, String>::value,
"DOMString? doesn't require a base::Optional<> wrapper");
-static_assert(std::is_same<IDLNullable<StringOrStringSequence>::ResultType,
+static_assert(std::is_same<IDLNullable<StringOrStringSequence>::ImplType,
StringOrStringSequence>::value,
"(union type)? doesn't require a base::Optional<> wrapper");
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 efa7fbcdd02..0948f87a23b 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
@@ -7,6 +7,7 @@
#include <utility>
#include "base/logging.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"
@@ -41,7 +42,7 @@ class IsolatedWorldCSPDelegate final
DCHECK(security_origin_);
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(document_);
ContentSecurityPolicyDelegate::Trace(visitor);
}
@@ -50,6 +51,10 @@ class IsolatedWorldCSPDelegate final
return security_origin_.get();
}
+ SecureContextMode GetSecureContextMode() override {
+ return SecureContextMode::kSecureContext;
+ }
+
const KURL& Url() const override {
// This is used to populate violation data's violation url. See
// https://w3c.github.io/webappsec-csp/#violation-url.
@@ -67,7 +72,7 @@ class IsolatedWorldCSPDelegate final
// supported.
void SetSandboxFlags(SandboxFlags) override {}
void SetRequireTrustedTypes() override {}
- void AddInsecureRequestPolicy(WebInsecureRequestPolicy) override {}
+ void AddInsecureRequestPolicy(mojom::blink::InsecureRequestPolicy) override {}
// TODO(crbug.com/916885): Figure out if we want to support violation
// reporting for isolated world CSPs.
@@ -109,11 +114,12 @@ 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_, directive_text);
+ probe::ScriptExecutionBlockedByCSP(document_->ToExecutionContext(),
+ directive_text);
}
void DidAddContentSecurityPolicies(
- const blink::WebVector<WebContentSecurityPolicy>&) override {}
+ WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr>) override {}
private:
const Member<Document> document_;
@@ -184,9 +190,9 @@ ContentSecurityPolicy* IsolatedWorldCSP::CreateIsolatedWorldCSP(
csp->BindToDelegate(*delegate);
if (apply_policy) {
- csp->AddPolicyFromHeaderValue(policy,
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ csp->AddPolicyFromHeaderValue(
+ policy, network::mojom::ContentSecurityPolicyType::kEnforce,
+ network::mojom::ContentSecurityPolicySource::kHTTP);
}
return csp;
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 8cf18c135ad..fd1a59d3e0e 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(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
};
private:
@@ -160,7 +160,7 @@ class Iterable {
return next(script_state, exception_state);
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 9c6c74fbed7..c4afd9d0919 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
@@ -42,7 +42,7 @@ bool JSBasedEventListener::BelongsToTheCurrentWorld(
// outside of any v8 context; check if it belongs to the main world.
if (!isolate->InContext() && execution_context &&
execution_context->IsDocument()) {
- Document* document = To<Document>(execution_context);
+ Document* document = Document::From(execution_context);
if (document->Parser() && document->Parser()->IsParsing())
return GetWorld().IsMainWorld();
}
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 b5062cc0327..4c4d331451b 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
@@ -69,7 +69,7 @@ void JSEventHandler::InvokeInternal(EventTarget& event_target,
// WindowOrWorkerGlobalScope mixin. Otherwise, let special error event
// handling be false.
const bool special_error_event_handling =
- event.IsErrorEvent() && event.type() == event_type_names::kError &&
+ IsA<ErrorEvent>(event) && event.type() == event_type_names::kError &&
event.currentTarget()->IsWindowOrWorkerGlobalScope();
// Step 4. Process the Event object event as follows:
@@ -93,7 +93,7 @@ void JSEventHandler::InvokeInternal(EventTarget& event_target,
event_handler_->CallbackRelevantScriptState();
if (special_error_event_handling) {
- ErrorEvent* error_event = ToErrorEvent(&event);
+ auto* error_event = To<ErrorEvent>(&event);
// The error argument should be initialized to null for dedicated workers.
// https://html.spec.whatwg.org/C/#runtime-script-errors-2
@@ -174,13 +174,12 @@ void JSEventHandler::InvokeInternal(EventTarget& event_target,
// then return value will never be false, since in such cases
// return value will have been coerced into either null or a
// DOMString.
+ auto* before_unload_event = DynamicTo<BeforeUnloadEvent>(&event);
const bool is_beforeunload_event =
- event.IsBeforeUnloadEvent() &&
- event.type() == event_type_names::kBeforeunload;
+ before_unload_event && event.type() == event_type_names::kBeforeunload;
if (is_beforeunload_event) {
if (result_for_beforeunload) {
event.preventDefault();
- BeforeUnloadEvent* before_unload_event = ToBeforeUnloadEvent(&event);
if (before_unload_event->returnValue().IsEmpty())
before_unload_event->setReturnValue(result_for_beforeunload);
}
@@ -194,7 +193,7 @@ void JSEventHandler::InvokeInternal(EventTarget& event_target,
}
}
-void JSEventHandler::Trace(blink::Visitor* visitor) {
+void JSEventHandler::Trace(Visitor* visitor) {
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 4be91f0f4e5..20095badae2 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(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
// blink::EventListener overrides:
bool IsEventHandler() const final { return true; }
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.cc b/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.cc
index f9e910899fb..e5496e8b02e 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.cc
@@ -76,7 +76,7 @@ v8::Local<v8::Value> JSEventHandlerForContentAttribute::GetCompiledHandler(
window = event_target.ToLocalDOMWindow();
DCHECK(window);
document = window->document();
- DCHECK_EQ(document, To<Document>(execution_context_of_event_target));
+ DCHECK_EQ(document, Document::From(execution_context_of_event_target));
}
DCHECK(document);
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 0bcdc0b7afe..0a123db8bc5 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(blink::Visitor* visitor) {
+void JSEventListener::Trace(Visitor* visitor) {
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 13d6aa4894f..d4b17bf990a 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 8095edd988c..81457a2e2b5 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
@@ -30,7 +30,7 @@
#include "third_party/blink/renderer/bindings/core/v8/local_window_proxy.h"
-#include "third_party/blink/public/common/features.h"
+#include "base/debug/dump_without_crashing.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/to_v8_for_core.h"
@@ -60,8 +60,8 @@
#include "third_party/blink/renderer/platform/bindings/v8_private_property.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
+#include "third_party/blink/renderer/platform/weborigin/reporting_disposition.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
-#include "third_party/blink/renderer/platform/weborigin/security_violation_reporting_policy.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/text/string_operators.h"
#include "v8/include/v8.h"
@@ -74,34 +74,13 @@ constexpr char kGlobalProxyLabel[] = "WindowProxy::global_proxy_";
} // namespace
-void LocalWindowProxy::Trace(blink::Visitor* visitor) {
+void LocalWindowProxy::Trace(Visitor* visitor) {
visitor->Trace(script_state_);
WindowProxy::Trace(visitor);
}
-bool LocalWindowProxy::IsSetDetachedWindowReasonEnabled(
- v8::Context::DetachedWindowReason reason) {
- switch (reason) {
- case v8::Context::DetachedWindowReason::kWindowNotDetached:
- // This shouldn't happen, but if it does, it's always safe to clear the
- // reason.
- return true;
- case v8::Context::DetachedWindowReason::kDetachedWindowByNavigation:
- return base::FeatureList::IsEnabled(
- features::kSetDetachedWindowReasonByNavigation);
- case v8::Context::DetachedWindowReason::kDetachedWindowByClosing:
- return base::FeatureList::IsEnabled(
- features::kSetDetachedWindowReasonByClosing);
- case v8::Context::DetachedWindowReason::kDetachedWindowByOtherReason:
- return base::FeatureList::IsEnabled(
- features::kSetDetachedWindowReasonByOtherReason);
- }
-}
-
-void LocalWindowProxy::DisposeContext(
- Lifecycle next_status,
- FrameReuseStatus frame_reuse_status,
- v8::Context::DetachedWindowReason reason) {
+void LocalWindowProxy::DisposeContext(Lifecycle next_status,
+ FrameReuseStatus frame_reuse_status) {
DCHECK(next_status == Lifecycle::kV8MemoryIsForciblyPurged ||
next_status == Lifecycle::kGlobalObjectIsDetached ||
next_status == Lifecycle::kFrameIsDetached ||
@@ -148,10 +127,6 @@ void LocalWindowProxy::DisposeContext(
#endif
}
- if (IsSetDetachedWindowReasonEnabled(reason)) {
- context->SetDetachedWindowReason(reason);
- }
-
script_state_->DisposePerContextData();
// It's likely that disposing the context has created a lot of
// garbage. Notify V8 about this so it'll have a chance of cleaning
@@ -199,14 +174,9 @@ void LocalWindowProxy::Initialize() {
(world_->IsIsolatedWorld() &&
IsolatedWorldCSP::Get().HasContentSecurityPolicy(world_->GetWorldId()));
if (evaluate_csp_for_eval) {
- // Using 'false' here means V8 will always call back blink for every 'eval'
- // call being made. Blink executes CSP checks and returns whether or not
- // V8 can proceed. The callback is
- // V8Initializer::CodeGenerationCheckCallbackInMainThread().
- context->AllowCodeGenerationFromStrings(false);
-
ContentSecurityPolicy* csp =
GetFrame()->GetDocument()->GetContentSecurityPolicyForWorld();
+ context->AllowCodeGenerationFromStrings(!csp->ShouldCheckEval());
context->SetErrorMessageForCodeGenerationFromStrings(
V8String(GetIsolate(), csp->EvalDisabledErrorMessage()));
}
@@ -245,7 +215,8 @@ void LocalWindowProxy::CreateContext() {
CHECK(IsMainThread());
v8::ExtensionConfiguration extension_configuration =
- ScriptController::ExtensionsFor(GetFrame()->GetDocument());
+ ScriptController::ExtensionsFor(
+ GetFrame()->GetDocument()->ToExecutionContext());
v8::Local<v8::Context> context;
{
@@ -341,9 +312,8 @@ void LocalWindowProxy::SetupWindowPrototypeChain() {
// The global object, aka window wrapper object.
v8::Local<v8::Object> window_wrapper =
global_proxy->GetPrototype().As<v8::Object>();
- v8::Local<v8::Object> associated_wrapper =
- AssociateWithWrapper(window, wrapper_type_info, window_wrapper);
- DCHECK(associated_wrapper == window_wrapper);
+ V8DOMWrapper::SetNativeInfo(GetIsolate(), window_wrapper, wrapper_type_info,
+ window);
// The prototype object of Window interface.
v8::Local<v8::Object> window_prototype =
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 a76329182ec..4aabac58f11 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
@@ -37,6 +37,7 @@
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
#include "v8/include/v8.h"
@@ -49,7 +50,7 @@ class SecurityOrigin;
class LocalWindowProxy final : public WindowProxy {
public:
LocalWindowProxy(v8::Isolate*, LocalFrame&, scoped_refptr<DOMWrapperWorld>);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
v8::Local<v8::Context> ContextIfInitialized() const {
return script_state_ ? script_state_->GetContext()
@@ -69,11 +70,7 @@ class LocalWindowProxy final : public WindowProxy {
private:
bool IsLocal() const override { return true; }
void Initialize() override;
- void DisposeContext(Lifecycle next_status,
- FrameReuseStatus,
- v8::Context::DetachedWindowReason) override;
- static bool IsSetDetachedWindowReasonEnabled(
- v8::Context::DetachedWindowReason reason);
+ void DisposeContext(Lifecycle next_status, FrameReuseStatus) override;
// Creates a new v8::Context with the window wrapper object as the global
// object (aka the inner global). Note that the window wrapper and its
@@ -111,11 +108,12 @@ class LocalWindowProxy final : public WindowProxy {
Member<ScriptState> script_state_;
};
-DEFINE_TYPE_CASTS(LocalWindowProxy,
- WindowProxy,
- windowProxy,
- windowProxy->IsLocal(),
- windowProxy.IsLocal());
+template <>
+struct DowncastTraits<LocalWindowProxy> {
+ static bool AllowFrom(const WindowProxy& windowProxy) {
+ return windowProxy.IsLocal();
+ }
+};
} // namespace blink
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 31f20815c6a..f6389c8bcd9 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
@@ -3,7 +3,8 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/bindings/core/v8/module_record.h"
-
+#include "base/feature_list.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/bindings/core/v8/boxed_v8_module.h"
#include "third_party/blink/renderer/bindings/core/v8/referrer_script_info.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
@@ -18,6 +19,49 @@
namespace blink {
+// static
+ModuleEvaluationResult ModuleEvaluationResult::Empty() {
+ DCHECK(!base::FeatureList::IsEnabled(features::kTopLevelAwait));
+ return ModuleEvaluationResult(true, {});
+}
+
+// static
+ModuleEvaluationResult ModuleEvaluationResult::FromResult(
+ v8::Local<v8::Value> promise) {
+ DCHECK(base::FeatureList::IsEnabled(features::kTopLevelAwait) ||
+ promise.IsEmpty());
+ DCHECK(!base::FeatureList::IsEnabled(features::kTopLevelAwait) ||
+ promise->IsPromise());
+ return ModuleEvaluationResult(true, promise);
+}
+
+// static
+ModuleEvaluationResult ModuleEvaluationResult::FromException(
+ v8::Local<v8::Value> exception) {
+ DCHECK(!exception.IsEmpty());
+ return ModuleEvaluationResult(false, exception);
+}
+
+ModuleEvaluationResult& ModuleEvaluationResult::Escape(
+ ScriptState::EscapableScope* scope) {
+ value_ = scope->Escape(value_);
+ return *this;
+}
+
+v8::Local<v8::Value> ModuleEvaluationResult::GetException() const {
+ DCHECK(IsException());
+ DCHECK(!value_.IsEmpty());
+ return value_;
+}
+
+ScriptPromise ModuleEvaluationResult::GetPromise(
+ ScriptState* script_state) const {
+ DCHECK(base::FeatureList::IsEnabled(features::kTopLevelAwait));
+ DCHECK(IsSuccess());
+ DCHECK(!value_.IsEmpty());
+ return ScriptPromise(script_state, value_);
+}
+
ModuleRecordProduceCacheData::ModuleRecordProduceCacheData(
v8::Isolate* isolate,
SingleCachedMetadataHandler* cache_handler,
@@ -37,7 +81,7 @@ ModuleRecordProduceCacheData::ModuleRecordProduceCacheData(
}
}
-void ModuleRecordProduceCacheData::Trace(blink::Visitor* visitor) {
+void ModuleRecordProduceCacheData::Trace(Visitor* visitor) {
visitor->Trace(cache_handler_);
visitor->Trace(unbound_script_.UnsafeCast<v8::Value>());
}
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 fac8fdacfd1..a63f36736f7 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
@@ -23,6 +23,48 @@ class KURL;
class ScriptFetchOptions;
class ScriptState;
class ScriptValue;
+class ScriptPromise;
+
+// ModuleEvaluationResult encapsulates the result of a module evaluation.
+// - Without top-level-await
+// - succeed and not return a value, or
+// (IsSuccess() == true), no return value is available.
+// - throw any object.
+// (IsException() == true && GetException()) returns the thrown exception
+// - With top-level-await a module can either
+// - return a promise, or
+// (IsSuccess() == true && GetPromise()) returns a valid ScriptPromise())
+// - throw any object.
+// (IsException() == true && GetException()) returns the thrown exception
+class CORE_EXPORT ModuleEvaluationResult final {
+ STACK_ALLOCATED();
+
+ public:
+ ModuleEvaluationResult() = delete;
+ static ModuleEvaluationResult Empty();
+ static ModuleEvaluationResult FromResult(v8::Local<v8::Value> promise);
+ static ModuleEvaluationResult FromException(v8::Local<v8::Value> exception);
+
+ ModuleEvaluationResult(const ModuleEvaluationResult& value) = default;
+ ModuleEvaluationResult& operator=(const ModuleEvaluationResult& value) =
+ default;
+ ~ModuleEvaluationResult() = default;
+
+ ModuleEvaluationResult& Escape(ScriptState::EscapableScope* scope);
+
+ bool IsSuccess() const { return is_success_; }
+ bool IsException() const { return !is_success_; }
+
+ v8::Local<v8::Value> GetException() const;
+ ScriptPromise GetPromise(ScriptState* script_state) const;
+
+ private:
+ ModuleEvaluationResult(bool is_success, v8::Local<v8::Value> value)
+ : is_success_(is_success), value_(value) {}
+
+ bool is_success_;
+ v8::Local<v8::Value> value_;
+};
// ModuleRecordProduceCacheData is a parameter object for
// ModuleRecord::ProduceCache().
@@ -34,7 +76,7 @@ class CORE_EXPORT ModuleRecordProduceCacheData final
V8CodeCache::ProduceCacheOptions,
v8::Local<v8::Module>);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
SingleCachedMetadataHandler* CacheHandler() const { return cache_handler_; }
V8CodeCache::ProduceCacheOptions GetProduceCacheOptions() const {
@@ -78,7 +120,7 @@ class CORE_EXPORT ModuleRecord final {
v8::Local<v8::Module> record,
const KURL& source_url);
- // Returns exception, if any.
+ // Returns exception, if any
static ScriptValue Evaluate(ScriptState*,
v8::Local<v8::Module> record,
const KURL& source_url);
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 c27ff44bb55..cf87d038d28 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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(blink::Visitor* visitor) {
+void ModuleRecordTestModulator::Trace(Visitor* visitor) {
visitor->Trace(resolver_);
DummyModulator::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits.h b/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits.h
index 6b568ee242b..db3c7bcaa92 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits.h
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_NATIVE_VALUE_TRAITS_H_
#include <type_traits>
+
#include "third_party/blink/renderer/bindings/core/v8/idl_types_base.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "v8/include/v8.h"
@@ -14,33 +15,6 @@ namespace blink {
class ExceptionState;
-// NativeValueTraitsBase is supposed to be inherited by NativeValueTraits
-// classes. They serve as a way to hold the ImplType typedef without requiring
-// all NativeValueTraits specializations to declare it.
-//
-// The primary template below is used by NativeValueTraits specializations with
-// types that do not inherit from IDLBase, in which case it is assumed the type
-// of the specialization is also |ImplType|. The NativeValueTraitsBase
-// specialization is used for IDLBase-based types, which are supposed to have
-// their own |ImplType| typedefs.
-//
-// If present, |NullValue()| will be used when converting from the nullable type
-// T?, and should be used if the impl type has an existing "null" state. If not
-// present, WTF::Optional will be used to wrap the type.
-template <typename T, typename SFINAEHelper = void>
-struct NativeValueTraitsBase {
- using ImplType = T;
- STATIC_ONLY(NativeValueTraitsBase);
-};
-
-template <typename T>
-struct NativeValueTraitsBase<
- T,
- std::enable_if_t<std::is_base_of<IDLBase, T>::value>> {
- using ImplType = typename T::ImplType;
- STATIC_ONLY(NativeValueTraitsBase);
-};
-
// Primary template for NativeValueTraits. It is not supposed to be used
// directly: there needs to be a specialization for each type which represents
// a JavaScript type that will be converted to a C++ representation.
@@ -50,7 +24,7 @@ struct NativeValueTraitsBase<
// Example:
// template <>
// struct NativeValueTraits<IDLLong> : public NativeValueTraitsBase<IDLLong> {
-// static inline int32_t nativeValue(v8::Isolate* isolate,
+// static inline int32_t NativeValue(v8::Isolate* isolate,
// v8::Local<v8::Value> value,
// ExceptionState& exceptionState) {
// return toInt32(isolate, value, exceptionState, NormalConversion);
@@ -64,11 +38,90 @@ struct NativeValueTraits;
// NativeValue() method that takes the 3 arguments below.
//
// template <>
-// struct NativeValueTraits<T>: public NativeValueTraitsBase<T> {
+// struct NativeValueTraits<T> : public NativeValueTraitsBase<T> {
// static inline typename NativeValueTraitsBase<T>::ImplType
// NativeValue(v8::Isolate*, v8::Local<v8::Value>, ExceptionState&);
// };
+namespace bindings {
+
+template <typename T, typename = void>
+struct NativeValueTraitsHasIsNull : std::false_type {};
+
+template <typename T>
+struct NativeValueTraitsHasIsNull<
+ T,
+ base::void_t<decltype(std::declval<T>().IsNull())>> : std::true_type {};
+
+template <typename T>
+struct NativeValueTraitsHasNullValue {
+ // true if |T| supports IDL null value.
+ static constexpr bool value =
+ // ScriptValue, String, and union types have IsNull member function.
+ bindings::NativeValueTraitsHasIsNull<T>::value ||
+ // Pointer types have nullptr as IDL null value.
+ std::is_pointer<T>::value;
+};
+
+} // namespace bindings
+
+// NativeValueTraitsBase is supposed to be inherited by NativeValueTraits
+// classes. They serve as a way to hold the ImplType typedef without requiring
+// all NativeValueTraits specializations to declare it.
+//
+// The primary template below is used by NativeValueTraits specializations with
+// types that do not inherit from IDLBase, in which case it is assumed the type
+// of the specialization is also |ImplType|. The NativeValueTraitsBase
+// specialization is used for IDLBase-based types, which are supposed to have
+// their own |ImplType| typedefs.
+//
+// If present, |NullValue()| will be used when converting from the nullable type
+// T?, and should be used if the impl type has an existing "null" state. If not
+// present, WTF::Optional will be used to wrap the type.
+template <typename T, typename SFINAEHelper = void>
+struct NativeValueTraitsBase {
+ STATIC_ONLY(NativeValueTraitsBase);
+
+ using ImplType = T;
+
+ static constexpr bool has_null_value =
+ bindings::NativeValueTraitsHasNullValue<ImplType>::value;
+
+ template <typename... ExtraArgs>
+ static decltype(auto) ArgumentValue(v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state,
+ ExtraArgs... extra_args) {
+ return NativeValueTraits<std::remove_pointer_t<T>>::NativeValue(
+ isolate, value, exception_state,
+ std::forward<ExtraArgs>(extra_args)...);
+ }
+};
+
+template <typename T>
+struct NativeValueTraitsBase<
+ T,
+ std::enable_if_t<std::is_base_of<IDLBase, T>::value>> {
+ STATIC_ONLY(NativeValueTraitsBase);
+
+ using ImplType = typename T::ImplType;
+
+ static constexpr bool has_null_value =
+ bindings::NativeValueTraitsHasNullValue<ImplType>::value;
+
+ template <typename... ExtraArgs>
+ static decltype(auto) ArgumentValue(v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state,
+ ExtraArgs... extra_args) {
+ return NativeValueTraits<std::remove_pointer_t<T>>::NativeValue(
+ isolate, value, exception_state,
+ std::forward<ExtraArgs>(extra_args)...);
+ }
+};
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_NATIVE_VALUE_TRAITS_H_
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.cc b/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.cc
new file mode 100644
index 00000000000..8aa7e3264a2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.cc
@@ -0,0 +1,419 @@
+// 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/bindings/core/v8/native_value_traits_impl.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/js_event_handler.h"
+#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_big_int_64_array.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_big_uint_64_array.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_data_view.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_float32_array.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_float64_array.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_int16_array.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_int32_array.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_int8_array.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_uint16_array.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_uint32_array.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_uint8_array.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_uint8_clamped_array.h"
+#include "third_party/blink/renderer/core/typed_arrays/typed_flexible_array_buffer_view.h"
+#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
+
+namespace blink {
+
+namespace bindings {
+
+static_assert(static_cast<IntegerConversionConfiguration>(
+ IDLIntegerConvMode::kDefault) == kNormalConversion,
+ "IDLIntegerConvMode::kDefault == kNormalConversion");
+static_assert(static_cast<IntegerConversionConfiguration>(
+ IDLIntegerConvMode::kClamp) == kClamp,
+ "IDLIntegerConvMode::kClamp == kClamp");
+static_assert(static_cast<IntegerConversionConfiguration>(
+ IDLIntegerConvMode::kEnforceRange) == kEnforceRange,
+ "IDLIntegerConvMode::kEnforceRange == kEnforceRange");
+
+ScriptWrappable* NativeValueTraitsInterfaceNativeValue(
+ v8::Isolate* isolate,
+ const WrapperTypeInfo* wrapper_type_info,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (V8PerIsolateData::From(isolate)->HasInstance(wrapper_type_info, value))
+ return ToScriptWrappable(value.As<v8::Object>());
+
+ exception_state.ThrowTypeError(ExceptionMessages::FailedToConvertJSValue(
+ wrapper_type_info->interface_name));
+ return nullptr;
+}
+
+ScriptWrappable* NativeValueTraitsInterfaceArgumentValue(
+ v8::Isolate* isolate,
+ const WrapperTypeInfo* wrapper_type_info,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (V8PerIsolateData::From(isolate)->HasInstance(wrapper_type_info, value))
+ return ToScriptWrappable(value.As<v8::Object>());
+
+ exception_state.ThrowTypeError(ExceptionMessages::ArgumentNotOfType(
+ argument_index, wrapper_type_info->interface_name));
+ return nullptr;
+}
+
+ScriptWrappable* NativeValueTraitsInterfaceOrNullNativeValue(
+ v8::Isolate* isolate,
+ const WrapperTypeInfo* wrapper_type_info,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (V8PerIsolateData::From(isolate)->HasInstance(wrapper_type_info, value))
+ return ToScriptWrappable(value.As<v8::Object>());
+
+ if (value->IsNullOrUndefined())
+ return nullptr;
+
+ exception_state.ThrowTypeError(ExceptionMessages::FailedToConvertJSValue(
+ wrapper_type_info->interface_name));
+ return nullptr;
+}
+
+ScriptWrappable* NativeValueTraitsInterfaceOrNullArgumentValue(
+ v8::Isolate* isolate,
+ const WrapperTypeInfo* wrapper_type_info,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (V8PerIsolateData::From(isolate)->HasInstance(wrapper_type_info, value))
+ return ToScriptWrappable(value.As<v8::Object>());
+
+ if (value->IsNullOrUndefined())
+ return nullptr;
+
+ exception_state.ThrowTypeError(ExceptionMessages::ArgumentNotOfType(
+ argument_index, wrapper_type_info->interface_name));
+ return nullptr;
+}
+
+} // namespace bindings
+
+// Buffer source types
+
+namespace {
+
+enum class IDLBufferSourceTypeConvMode {
+ kDefault,
+ kNullable,
+};
+
+template <
+ typename T,
+ typename V8T,
+ IDLBufferSourceTypeConvMode mode = IDLBufferSourceTypeConvMode::kDefault>
+T* NativeValueTraitsBufferSourcePtrNativeValue(
+ v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ T* native_value = V8T::ToImplWithTypeCheck(isolate, value);
+ if (native_value)
+ return native_value;
+
+ if (mode == IDLBufferSourceTypeConvMode::kNullable) {
+ if (value->IsNullOrUndefined())
+ return nullptr;
+ }
+
+ exception_state.ThrowTypeError(ExceptionMessages::FailedToConvertJSValue(
+ V8T::GetWrapperTypeInfo()->interface_name));
+ return nullptr;
+}
+
+template <
+ typename T,
+ typename V8T,
+ IDLBufferSourceTypeConvMode mode = IDLBufferSourceTypeConvMode::kDefault>
+T* NativeValueTraitsBufferSourcePtrArgumentValue(
+ v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ T* native_value = V8T::ToImplWithTypeCheck(isolate, value);
+ if (native_value)
+ return native_value;
+
+ if (mode == IDLBufferSourceTypeConvMode::kNullable) {
+ if (value->IsNullOrUndefined())
+ return nullptr;
+ }
+
+ exception_state.ThrowTypeError(ExceptionMessages::ArgumentNotOfType(
+ argument_index, V8T::GetWrapperTypeInfo()->interface_name));
+ return nullptr;
+}
+
+template <
+ typename T,
+ typename V8T,
+ IDLBufferSourceTypeConvMode mode = IDLBufferSourceTypeConvMode::kDefault>
+NotShared<T> NativeValueTraitsBufferSourceNotSharedNativeValue(
+ v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ T* native_value = NativeValueTraitsBufferSourcePtrNativeValue<T, V8T, mode>(
+ isolate, value, exception_state);
+ if (!native_value)
+ return NotShared<T>();
+ if (native_value->IsShared()) {
+ exception_state.ThrowTypeError(
+ "The provided ArrayBufferView value must not be shared.");
+ return NotShared<T>();
+ }
+ return NotShared<T>(native_value);
+}
+
+template <
+ typename T,
+ typename V8T,
+ IDLBufferSourceTypeConvMode mode = IDLBufferSourceTypeConvMode::kDefault>
+NotShared<T> NativeValueTraitsBufferSourceNotSharedArgumentValue(
+ v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ T* native_value = NativeValueTraitsBufferSourcePtrArgumentValue<T, V8T, mode>(
+ isolate, argument_index, value, exception_state);
+ if (!native_value)
+ return NotShared<T>();
+ if (native_value->IsShared()) {
+ exception_state.ThrowTypeError(
+ "The provided ArrayBufferView value must not be shared.");
+ return NotShared<T>();
+ }
+ return NotShared<T>(native_value);
+}
+
+template <
+ typename T,
+ typename V8T,
+ IDLBufferSourceTypeConvMode mode = IDLBufferSourceTypeConvMode::kDefault>
+MaybeShared<T> NativeValueTraitsBufferSourceMaybeSharedNativeValue(
+ v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ return MaybeShared<T>(
+ NativeValueTraitsBufferSourcePtrNativeValue<T, V8T, mode>(
+ isolate, value, exception_state));
+}
+
+template <
+ typename T,
+ typename V8T,
+ IDLBufferSourceTypeConvMode mode = IDLBufferSourceTypeConvMode::kDefault>
+MaybeShared<T> NativeValueTraitsBufferSourceMaybeSharedArgumentValue(
+ v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ return MaybeShared<T>(
+ NativeValueTraitsBufferSourcePtrArgumentValue<T, V8T, mode>(
+ isolate, argument_index, value, exception_state));
+}
+
+template <
+ typename T,
+ typename V8T,
+ typename FLEXIBLE,
+ IDLBufferSourceTypeConvMode mode = IDLBufferSourceTypeConvMode::kDefault>
+FLEXIBLE NativeValueTraitsBufferSourceFlexibleArgumentValue(
+ v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (V8T::HasInstance(isolate, value))
+ return FLEXIBLE(value.As<v8::ArrayBufferView>());
+
+ if (mode == IDLBufferSourceTypeConvMode::kNullable) {
+ if (value->IsNullOrUndefined())
+ return FLEXIBLE();
+ }
+
+ exception_state.ThrowTypeError(ExceptionMessages::ArgumentNotOfType(
+ argument_index, V8T::GetWrapperTypeInfo()->interface_name));
+ return FLEXIBLE();
+}
+
+} // namespace
+
+DOMArrayBuffer* NativeValueTraits<DOMArrayBuffer>::NativeValue(
+ v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ return NativeValueTraitsBufferSourcePtrNativeValue<DOMArrayBuffer,
+ V8ArrayBuffer>(
+ isolate, value, exception_state);
+}
+
+DOMArrayBuffer* NativeValueTraits<DOMArrayBuffer>::ArgumentValue(
+ v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ return NativeValueTraitsBufferSourcePtrArgumentValue<DOMArrayBuffer,
+ V8ArrayBuffer>(
+ isolate, argument_index, value, exception_state);
+}
+
+DOMArrayBuffer* NativeValueTraits<IDLNullable<DOMArrayBuffer>>::NativeValue(
+ v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ return NativeValueTraitsBufferSourcePtrNativeValue<
+ DOMArrayBuffer, V8ArrayBuffer, IDLBufferSourceTypeConvMode::kNullable>(
+ isolate, value, exception_state);
+}
+
+DOMArrayBuffer* NativeValueTraits<IDLNullable<DOMArrayBuffer>>::ArgumentValue(
+ v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ return NativeValueTraitsBufferSourcePtrArgumentValue<
+ DOMArrayBuffer, V8ArrayBuffer, IDLBufferSourceTypeConvMode::kNullable>(
+ isolate, argument_index, value, exception_state);
+}
+
+#define DEFINE_NATIVE_VALUE_TRAITS_BUFFER_SOURCE_TYPE_NOT_SHARED(T, V8T) \
+ template <> \
+ CORE_EXPORT NotShared<T> NativeValueTraits<NotShared<T>>::NativeValue( \
+ v8::Isolate* isolate, v8::Local<v8::Value> value, \
+ ExceptionState& exception_state) { \
+ return NativeValueTraitsBufferSourceNotSharedNativeValue<T, V8T>( \
+ isolate, value, exception_state); \
+ } \
+ template <> \
+ CORE_EXPORT NotShared<T> NativeValueTraits<NotShared<T>>::ArgumentValue( \
+ v8::Isolate* isolate, int argument_index, v8::Local<v8::Value> value, \
+ ExceptionState& exception_state) { \
+ return NativeValueTraitsBufferSourceNotSharedArgumentValue<T, V8T>( \
+ isolate, argument_index, value, exception_state); \
+ } \
+ template <> \
+ CORE_EXPORT NotShared<T> \
+ NativeValueTraits<IDLNullable<NotShared<T>>>::NativeValue( \
+ v8::Isolate* isolate, v8::Local<v8::Value> value, \
+ ExceptionState& exception_state) { \
+ return NativeValueTraitsBufferSourceNotSharedNativeValue< \
+ T, V8T, IDLBufferSourceTypeConvMode::kNullable>(isolate, value, \
+ exception_state); \
+ } \
+ template <> \
+ CORE_EXPORT NotShared<T> \
+ NativeValueTraits<IDLNullable<NotShared<T>>>::ArgumentValue( \
+ v8::Isolate* isolate, int argument_index, v8::Local<v8::Value> value, \
+ ExceptionState& exception_state) { \
+ return NativeValueTraitsBufferSourceNotSharedArgumentValue< \
+ T, V8T, IDLBufferSourceTypeConvMode::kNullable>( \
+ isolate, argument_index, value, exception_state); \
+ }
+#define DEFINE_NATIVE_VALUE_TRAITS_BUFFER_SOURCE_TYPE_MAYBE_SHARED(T, V8T) \
+ template <> \
+ CORE_EXPORT MaybeShared<T> NativeValueTraits<MaybeShared<T>>::NativeValue( \
+ v8::Isolate* isolate, v8::Local<v8::Value> value, \
+ ExceptionState& exception_state) { \
+ return NativeValueTraitsBufferSourceMaybeSharedNativeValue<T, V8T>( \
+ isolate, value, exception_state); \
+ } \
+ template <> \
+ CORE_EXPORT MaybeShared<T> NativeValueTraits<MaybeShared<T>>::ArgumentValue( \
+ v8::Isolate* isolate, int argument_index, v8::Local<v8::Value> value, \
+ ExceptionState& exception_state) { \
+ return NativeValueTraitsBufferSourceMaybeSharedArgumentValue<T, V8T>( \
+ isolate, argument_index, value, exception_state); \
+ } \
+ template <> \
+ CORE_EXPORT MaybeShared<T> \
+ NativeValueTraits<IDLNullable<MaybeShared<T>>>::NativeValue( \
+ v8::Isolate* isolate, v8::Local<v8::Value> value, \
+ ExceptionState& exception_state) { \
+ return NativeValueTraitsBufferSourceMaybeSharedNativeValue< \
+ T, V8T, IDLBufferSourceTypeConvMode::kNullable>(isolate, value, \
+ exception_state); \
+ } \
+ template <> \
+ CORE_EXPORT MaybeShared<T> \
+ NativeValueTraits<IDLNullable<MaybeShared<T>>>::ArgumentValue( \
+ v8::Isolate* isolate, int argument_index, v8::Local<v8::Value> value, \
+ ExceptionState& exception_state) { \
+ return NativeValueTraitsBufferSourceMaybeSharedArgumentValue< \
+ T, V8T, IDLBufferSourceTypeConvMode::kNullable>( \
+ isolate, argument_index, value, exception_state); \
+ }
+#define DEFINE_NATIVE_VALUE_TRAITS_BUFFER_SOURCE_TYPE_FLEXIBLE(T, V8T, \
+ FLEXIBLE) \
+ template <> \
+ CORE_EXPORT FLEXIBLE NativeValueTraits<FLEXIBLE>::ArgumentValue( \
+ v8::Isolate* isolate, int argument_index, v8::Local<v8::Value> value, \
+ ExceptionState& exception_state) { \
+ return NativeValueTraitsBufferSourceFlexibleArgumentValue<T, V8T, \
+ FLEXIBLE>( \
+ isolate, argument_index, value, exception_state); \
+ } \
+ template <> \
+ CORE_EXPORT FLEXIBLE \
+ NativeValueTraits<IDLNullable<FLEXIBLE>>::ArgumentValue( \
+ v8::Isolate* isolate, int argument_index, v8::Local<v8::Value> value, \
+ ExceptionState& exception_state) { \
+ return NativeValueTraitsBufferSourceFlexibleArgumentValue< \
+ T, V8T, FLEXIBLE, IDLBufferSourceTypeConvMode::kNullable>( \
+ isolate, argument_index, value, exception_state); \
+ }
+#define DEFINE_NATIVE_VALUE_TRAITS_TYPED_ARRAY(T) \
+ DEFINE_NATIVE_VALUE_TRAITS_BUFFER_SOURCE_TYPE_NOT_SHARED(DOM##T, V8##T) \
+ DEFINE_NATIVE_VALUE_TRAITS_BUFFER_SOURCE_TYPE_MAYBE_SHARED(DOM##T, V8##T) \
+ DEFINE_NATIVE_VALUE_TRAITS_BUFFER_SOURCE_TYPE_FLEXIBLE(DOM##T, V8##T, \
+ Flexible##T)
+#define DEFINE_NATIVE_VALUE_TRAITS_DATA_VIEW(T) \
+ DEFINE_NATIVE_VALUE_TRAITS_BUFFER_SOURCE_TYPE_NOT_SHARED(DOM##T, V8##T) \
+ DEFINE_NATIVE_VALUE_TRAITS_BUFFER_SOURCE_TYPE_MAYBE_SHARED(DOM##T, V8##T)
+
+DEFINE_NATIVE_VALUE_TRAITS_TYPED_ARRAY(ArrayBufferView)
+DEFINE_NATIVE_VALUE_TRAITS_TYPED_ARRAY(Int8Array)
+DEFINE_NATIVE_VALUE_TRAITS_TYPED_ARRAY(Int16Array)
+DEFINE_NATIVE_VALUE_TRAITS_TYPED_ARRAY(Int32Array)
+DEFINE_NATIVE_VALUE_TRAITS_TYPED_ARRAY(Uint8Array)
+DEFINE_NATIVE_VALUE_TRAITS_TYPED_ARRAY(Uint8ClampedArray)
+DEFINE_NATIVE_VALUE_TRAITS_TYPED_ARRAY(Uint16Array)
+DEFINE_NATIVE_VALUE_TRAITS_TYPED_ARRAY(Uint32Array)
+DEFINE_NATIVE_VALUE_TRAITS_TYPED_ARRAY(BigInt64Array)
+DEFINE_NATIVE_VALUE_TRAITS_TYPED_ARRAY(BigUint64Array)
+DEFINE_NATIVE_VALUE_TRAITS_TYPED_ARRAY(Float32Array)
+DEFINE_NATIVE_VALUE_TRAITS_TYPED_ARRAY(Float64Array)
+DEFINE_NATIVE_VALUE_TRAITS_DATA_VIEW(DataView)
+
+// EventHandler
+EventListener* NativeValueTraits<IDLEventHandler>::NativeValue(
+ v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ return JSEventHandler::CreateOrNull(
+ value, JSEventHandler::HandlerType::kEventHandler);
+}
+
+EventListener* NativeValueTraits<IDLOnBeforeUnloadEventHandler>::NativeValue(
+ v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ return JSEventHandler::CreateOrNull(
+ value, JSEventHandler::HandlerType::kOnBeforeUnloadEventHandler);
+}
+
+EventListener* NativeValueTraits<IDLOnErrorEventHandler>::NativeValue(
+ v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ return JSEventHandler::CreateOrNull(
+ value, JSEventHandler::HandlerType::kOnErrorEventHandler);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h b/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h
index 2a0c8ac97d6..67abed0c547 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h
@@ -9,19 +9,77 @@
#include "third_party/blink/renderer/bindings/core/v8/native_value_traits.h"
#include "third_party/blink/renderer/bindings/core/v8/script_iterator.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/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_trusted_html.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_trusted_script.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_trusted_script_url.h"
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/trustedtypes/trusted_types_util.h"
+#include "third_party/blink/renderer/core/typed_arrays/dom_data_view.h"
+#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
+#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
class CallbackFunctionBase;
+class CallbackInterfaceBase;
+class EventListener;
+class FlexibleArrayBufferView;
+class IDLDictionaryBase;
+class ScriptWrappable;
+struct WrapperTypeInfo;
namespace bindings {
+
class DictionaryBase;
+class EnumerationBase;
+class UnionBase;
+
+CORE_EXPORT ScriptWrappable* NativeValueTraitsInterfaceNativeValue(
+ v8::Isolate* isolate,
+ const WrapperTypeInfo* wrapper_type_info,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state);
+
+CORE_EXPORT ScriptWrappable* NativeValueTraitsInterfaceArgumentValue(
+ v8::Isolate* isolate,
+ const WrapperTypeInfo* wrapper_type_info,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state);
+
+CORE_EXPORT ScriptWrappable* NativeValueTraitsInterfaceOrNullNativeValue(
+ v8::Isolate* isolate,
+ const WrapperTypeInfo* wrapper_type_info,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state);
+
+CORE_EXPORT ScriptWrappable* NativeValueTraitsInterfaceOrNullArgumentValue(
+ v8::Isolate* isolate,
+ const WrapperTypeInfo* wrapper_type_info,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state);
+
} // namespace bindings
-// Boolean
+// any
+template <>
+struct CORE_EXPORT NativeValueTraits<IDLAny>
+ : public NativeValueTraitsBase<IDLAny> {
+ static ScriptValue NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ return ScriptValue(isolate, value);
+ }
+};
+// IDLNullable<IDLAny> must not be used.
+template <>
+struct NativeValueTraits<IDLNullable<IDLAny>>;
+
+// boolean
template <>
struct CORE_EXPORT NativeValueTraits<IDLBoolean>
: public NativeValueTraitsBase<IDLBoolean> {
@@ -32,385 +90,671 @@ struct CORE_EXPORT NativeValueTraits<IDLBoolean>
}
};
-// Integers
+// Integer types
+#define DEFINE_NATIVE_VALUE_TRAITS_INTEGER_TYPE(T, Func) \
+ template <bindings::IDLIntegerConvMode mode> \
+ struct NativeValueTraits<IDLIntegerTypeBase<T, mode>> \
+ : public NativeValueTraitsBase<IDLIntegerTypeBase<T, mode>> { \
+ static T NativeValue(v8::Isolate* isolate, \
+ v8::Local<v8::Value> value, \
+ ExceptionState& exception_state) { \
+ return Func(isolate, value, \
+ static_cast<IntegerConversionConfiguration>(mode), \
+ exception_state); \
+ } \
+ }
+DEFINE_NATIVE_VALUE_TRAITS_INTEGER_TYPE(int8_t, ToInt8);
+DEFINE_NATIVE_VALUE_TRAITS_INTEGER_TYPE(uint8_t, ToUInt8);
+DEFINE_NATIVE_VALUE_TRAITS_INTEGER_TYPE(int16_t, ToInt16);
+DEFINE_NATIVE_VALUE_TRAITS_INTEGER_TYPE(uint16_t, ToUInt16);
+DEFINE_NATIVE_VALUE_TRAITS_INTEGER_TYPE(int32_t, ToInt32);
+DEFINE_NATIVE_VALUE_TRAITS_INTEGER_TYPE(uint32_t, ToUInt32);
+DEFINE_NATIVE_VALUE_TRAITS_INTEGER_TYPE(int64_t, ToInt64);
+DEFINE_NATIVE_VALUE_TRAITS_INTEGER_TYPE(uint64_t, ToUInt64);
+#undef DEFINE_NATIVE_VALUE_TRAITS_INTEGER_TYPE
+
+// Floats and doubles
template <>
-struct CORE_EXPORT NativeValueTraits<IDLByte>
- : public NativeValueTraitsBase<IDLByte> {
- static int8_t NativeValue(v8::Isolate* isolate,
+struct CORE_EXPORT NativeValueTraits<IDLDouble>
+ : public NativeValueTraitsBase<IDLDouble> {
+ static double NativeValue(v8::Isolate* isolate,
v8::Local<v8::Value> value,
ExceptionState& exception_state) {
- return ToInt8(isolate, value, kNormalConversion, exception_state);
+ return ToRestrictedDouble(isolate, value, exception_state);
}
};
template <>
-struct CORE_EXPORT NativeValueTraits<IDLOctet>
- : public NativeValueTraitsBase<IDLOctet> {
- static uint8_t NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToUInt8(isolate, value, kNormalConversion, exception_state);
+struct CORE_EXPORT NativeValueTraits<IDLUnrestrictedDouble>
+ : public NativeValueTraitsBase<IDLUnrestrictedDouble> {
+ static double NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ return ToDouble(isolate, value, exception_state);
}
};
template <>
-struct CORE_EXPORT NativeValueTraits<IDLShort>
- : public NativeValueTraitsBase<IDLShort> {
- static int16_t NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToInt16(isolate, value, kNormalConversion, exception_state);
+struct CORE_EXPORT NativeValueTraits<IDLFloat>
+ : public NativeValueTraitsBase<IDLFloat> {
+ static float NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ return ToRestrictedFloat(isolate, value, exception_state);
}
};
template <>
-struct CORE_EXPORT NativeValueTraits<IDLUnsignedShort>
- : public NativeValueTraitsBase<IDLUnsignedShort> {
- static uint16_t NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToUInt16(isolate, value, kNormalConversion, exception_state);
+struct CORE_EXPORT NativeValueTraits<IDLUnrestrictedFloat>
+ : public NativeValueTraitsBase<IDLUnrestrictedFloat> {
+ static float NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ return ToFloat(isolate, value, exception_state);
}
};
-template <>
-struct CORE_EXPORT NativeValueTraits<IDLLong>
- : public NativeValueTraitsBase<IDLLong> {
- static int32_t NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToInt32(isolate, value, kNormalConversion, exception_state);
- }
-};
+// Strings
+template <V8StringResourceMode mode>
+struct NativeValueTraits<IDLByteStringBase<mode>>
+ : public NativeValueTraitsBase<IDLByteStringBase<mode>> {
+ // http://heycam.github.io/webidl/#es-ByteString
+ static String NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ V8StringResource<mode> string_resource(value);
+ // 1. Let x be ToString(v)
+ if (!string_resource.Prepare(isolate, exception_state))
+ return String();
+ String x = string_resource;
+ // 2. If the value of any element of x is greater than 255, then throw a
+ // TypeError.
+ if (!x.ContainsOnlyLatin1OrEmpty()) {
+ exception_state.ThrowTypeError("Value is not a valid ByteString.");
+ return String();
+ }
-template <>
-struct CORE_EXPORT NativeValueTraits<IDLUnsignedLong>
- : public NativeValueTraitsBase<IDLUnsignedLong> {
- static uint32_t NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToUInt32(isolate, value, kNormalConversion, exception_state);
+ // 3. Return an IDL ByteString value whose length is the length of x, and
+ // where the value of each element is the value of the corresponding
+ // element of x.
+ // Blink: A ByteString is simply a String with a range constrained per
+ // the above, so this is the identity operation.
+ return x;
}
};
-template <>
-struct CORE_EXPORT NativeValueTraits<IDLLongLong>
- : public NativeValueTraitsBase<IDLLongLong> {
- static int64_t NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToInt64(isolate, value, kNormalConversion, exception_state);
+template <V8StringResourceMode mode>
+struct NativeValueTraits<IDLStringBase<mode>>
+ : public NativeValueTraitsBase<IDLStringBase<mode>> {
+ // https://heycam.github.io/webidl/#es-DOMString
+ static String NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ V8StringResource<mode> string(value);
+ if (!string.Prepare(isolate, exception_state))
+ return String();
+ return string;
}
};
-template <>
-struct CORE_EXPORT NativeValueTraits<IDLUnsignedLongLong>
- : public NativeValueTraitsBase<IDLUnsignedLongLong> {
- static uint64_t NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToUInt64(isolate, value, kNormalConversion, exception_state);
+template <V8StringResourceMode mode>
+struct NativeValueTraits<IDLStringStringContextTrustedHTMLBase<mode>>
+ : public NativeValueTraitsBase<
+ IDLStringStringContextTrustedHTMLBase<mode>> {
+ static String NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state,
+ ExecutionContext* execution_context) {
+ if (V8TrustedHTML::HasInstance(value, isolate)) {
+ TrustedHTML* trusted_value =
+ V8TrustedHTML::ToImpl(v8::Local<v8::Object>::Cast(value));
+ return trusted_value->toString();
+ } else {
+ V8StringResource<mode> string(value);
+ if (!string.Prepare(isolate, exception_state))
+ return String();
+ return TrustedTypesCheckForHTML(string, execution_context,
+ exception_state);
+ }
}
};
-// [Clamp] Integers
-template <>
-struct CORE_EXPORT NativeValueTraits<IDLByteClamp>
- : public NativeValueTraitsBase<IDLByte> {
- static int8_t NativeValue(v8::Isolate* isolate,
+template <V8StringResourceMode mode>
+struct NativeValueTraits<IDLStringStringContextTrustedScriptBase<mode>>
+ : public NativeValueTraitsBase<
+ IDLStringStringContextTrustedScriptBase<mode>> {
+ static String NativeValue(v8::Isolate* isolate,
v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToInt8(isolate, value, kClamp, exception_state);
+ ExceptionState& exception_state,
+ ExecutionContext* execution_context) {
+ if (V8TrustedScript::HasInstance(value, isolate)) {
+ TrustedScript* trusted_value =
+ V8TrustedScript::ToImpl(v8::Local<v8::Object>::Cast(value));
+ return trusted_value->toString();
+ } else {
+ V8StringResource<mode> string(value);
+ if (!string.Prepare(isolate, exception_state))
+ return String();
+ return TrustedTypesCheckForScript(string, execution_context,
+ exception_state);
+ }
}
};
-template <>
-struct CORE_EXPORT NativeValueTraits<IDLOctetClamp>
- : public NativeValueTraitsBase<IDLOctet> {
- static uint8_t NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToUInt8(isolate, value, kClamp, exception_state);
+template <V8StringResourceMode mode>
+struct NativeValueTraits<IDLUSVStringStringContextTrustedScriptURLBase<mode>>
+ : public NativeValueTraitsBase<
+ IDLUSVStringStringContextTrustedScriptURLBase<mode>> {
+ static String NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state,
+ ExecutionContext* execution_context) {
+ if (V8TrustedScriptURL::HasInstance(value, isolate)) {
+ TrustedScriptURL* trusted_value =
+ V8TrustedScriptURL::ToImpl(v8::Local<v8::Object>::Cast(value));
+ return trusted_value->toString();
+ } else {
+ V8StringResource<mode> string(value);
+ if (!string.Prepare(isolate, exception_state))
+ return String();
+ return TrustedTypesCheckForScriptURL(string, execution_context,
+ exception_state);
+ }
}
};
-template <>
-struct CORE_EXPORT NativeValueTraits<IDLShortClamp>
- : public NativeValueTraitsBase<IDLShort> {
- static int16_t NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToInt16(isolate, value, kClamp, exception_state);
+template <V8StringResourceMode mode>
+struct NativeValueTraits<IDLUSVStringBase<mode>>
+ : public NativeValueTraitsBase<IDLUSVStringBase<mode>> {
+ // http://heycam.github.io/webidl/#es-USVString
+ static String NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ // 1. Let string be the result of converting V to a DOMString.
+ V8StringResource<mode> string(value);
+ if (!string.Prepare(isolate, exception_state))
+ return String();
+ // 2. Return an IDL USVString value that is the result of converting string
+ // to a sequence of Unicode scalar values.
+ return ReplaceUnmatchedSurrogates(string);
}
};
-template <>
-struct CORE_EXPORT NativeValueTraits<IDLUnsignedShortClamp>
- : public NativeValueTraitsBase<IDLUnsignedShort> {
- static uint16_t NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToUInt16(isolate, value, kClamp, exception_state);
- }
-};
+// Strings for the new bindings generator
-template <>
-struct CORE_EXPORT NativeValueTraits<IDLLongClamp>
- : public NativeValueTraitsBase<IDLLong> {
- static int32_t NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToInt32(isolate, value, kClamp, exception_state);
- }
-};
+namespace bindings {
-template <>
-struct CORE_EXPORT NativeValueTraits<IDLUnsignedLongClamp>
- : public NativeValueTraitsBase<IDLUnsignedLong> {
- static uint32_t NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToUInt32(isolate, value, kClamp, exception_state);
+// ToBlinkString implements AtomicString- and String-specific conversions from
+// v8::String. NativeValueTraitsStringAdapter helps select the best conversion.
+//
+// Example:
+// void F(const AtomicString& s);
+// void G(const String& s);
+//
+// const NativeValueTraitsStringAdapter& x = ...;
+// F(x); // ToBlinkString<AtomicString> is used.
+// G(x); // ToBlinkString<String> is used.
+class CORE_EXPORT NativeValueTraitsStringAdapter {
+ public:
+ NativeValueTraitsStringAdapter() = default;
+ NativeValueTraitsStringAdapter(const NativeValueTraitsStringAdapter&) =
+ default;
+ NativeValueTraitsStringAdapter(NativeValueTraitsStringAdapter&&) = default;
+ explicit NativeValueTraitsStringAdapter(v8::Local<v8::String> value)
+ : v8_string_(value) {}
+ explicit NativeValueTraitsStringAdapter(const String& value)
+ : wtf_string_(value) {}
+ explicit NativeValueTraitsStringAdapter(int32_t value)
+ : wtf_string_(ToBlinkString(value)) {}
+
+ NativeValueTraitsStringAdapter& operator=(
+ const NativeValueTraitsStringAdapter&) = default;
+ NativeValueTraitsStringAdapter& operator=(NativeValueTraitsStringAdapter&&) =
+ default;
+ NativeValueTraitsStringAdapter& operator=(const String& value) {
+ v8_string_.Clear();
+ wtf_string_ = value;
+ return *this;
}
-};
-template <>
-struct CORE_EXPORT NativeValueTraits<IDLLongLongClamp>
- : public NativeValueTraitsBase<IDLLongLong> {
- static int64_t NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToInt64(isolate, value, kClamp, exception_state);
- }
-};
+ operator String() const { return ToString<String>(); }
+ operator AtomicString() const { return ToString<AtomicString>(); }
-template <>
-struct CORE_EXPORT NativeValueTraits<IDLUnsignedLongLongClamp>
- : public NativeValueTraitsBase<IDLUnsignedLongLong> {
- static uint64_t NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToUInt64(isolate, value, kClamp, exception_state);
+ private:
+ template <class StringType>
+ StringType ToString() const {
+ if (LIKELY(!v8_string_.IsEmpty()))
+ return ToBlinkString<StringType>(v8_string_, kExternalize);
+ return StringType(wtf_string_);
}
+
+ v8::Local<v8::String> v8_string_;
+ String wtf_string_;
};
-// [EnforceRange] Integers
-template <>
-struct CORE_EXPORT NativeValueTraits<IDLByteEnforceRange>
- : public NativeValueTraitsBase<IDLByte> {
- static int8_t NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToInt8(isolate, value, kEnforceRange, exception_state);
+} // namespace bindings
+
+template <bindings::IDLStringConvMode mode>
+struct NativeValueTraits<IDLByteStringBaseV2<mode>>
+ : public NativeValueTraitsBase<IDLByteStringBaseV2<mode>> {
+ // http://heycam.github.io/webidl/#es-ByteString
+ static bindings::NativeValueTraitsStringAdapter NativeValue(
+ v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (value->IsString() and value.As<v8::String>()->ContainsOnlyOneByte())
+ return bindings::NativeValueTraitsStringAdapter(value.As<v8::String>());
+ if (value->IsInt32()) {
+ return bindings::NativeValueTraitsStringAdapter(
+ value.As<v8::Int32>()->Value());
+ }
+
+ if (mode == bindings::IDLStringConvMode::kNullable) {
+ if (value->IsNullOrUndefined())
+ return bindings::NativeValueTraitsStringAdapter();
+ }
+
+ v8::TryCatch try_catch(isolate);
+ v8::Local<v8::String> v8_string;
+ if (!value->ToString(isolate->GetCurrentContext()).ToLocal(&v8_string)) {
+ exception_state.RethrowV8Exception(try_catch.Exception());
+ return bindings::NativeValueTraitsStringAdapter();
+ }
+ if (!v8_string->ContainsOnlyOneByte()) {
+ exception_state.ThrowTypeError(
+ "String contains non ISO-8859-1 code point.");
+ return bindings::NativeValueTraitsStringAdapter();
+ }
+ return bindings::NativeValueTraitsStringAdapter(v8_string);
}
};
template <>
-struct CORE_EXPORT NativeValueTraits<IDLOctetEnforceRange>
- : public NativeValueTraitsBase<IDLOctet> {
- static uint8_t NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToUInt8(isolate, value, kEnforceRange, exception_state);
+struct CORE_EXPORT NativeValueTraits<IDLNullable<IDLByteStringV2>>
+ : public NativeValueTraitsBase<IDLNullable<IDLByteStringV2>> {
+ static decltype(auto) NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ return NativeValueTraits<IDLByteStringBaseV2<
+ bindings::IDLStringConvMode::kNullable>>::NativeValue(isolate, value,
+ exception_state);
}
};
-template <>
-struct CORE_EXPORT NativeValueTraits<IDLShortEnforceRange>
- : public NativeValueTraitsBase<IDLShort> {
- static int16_t NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToInt16(isolate, value, kEnforceRange, exception_state);
+template <bindings::IDLStringConvMode mode>
+struct NativeValueTraits<IDLStringBaseV2<mode>>
+ : public NativeValueTraitsBase<IDLStringBaseV2<mode>> {
+ // https://heycam.github.io/webidl/#es-DOMString
+ static bindings::NativeValueTraitsStringAdapter NativeValue(
+ v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (value->IsString())
+ return bindings::NativeValueTraitsStringAdapter(value.As<v8::String>());
+ if (value->IsInt32()) {
+ return bindings::NativeValueTraitsStringAdapter(
+ value.As<v8::Int32>()->Value());
+ }
+
+ if (mode == bindings::IDLStringConvMode::kNullable) {
+ if (value->IsNullOrUndefined())
+ return bindings::NativeValueTraitsStringAdapter();
+ }
+ if (mode == bindings::IDLStringConvMode::kTreatNullAsEmptyString) {
+ if (value->IsNull())
+ return bindings::NativeValueTraitsStringAdapter(g_empty_string);
+ }
+
+ v8::TryCatch try_catch(isolate);
+ v8::Local<v8::String> v8_string;
+ if (!value->ToString(isolate->GetCurrentContext()).ToLocal(&v8_string)) {
+ exception_state.RethrowV8Exception(try_catch.Exception());
+ return bindings::NativeValueTraitsStringAdapter();
+ }
+ return bindings::NativeValueTraitsStringAdapter(v8_string);
}
};
template <>
-struct CORE_EXPORT NativeValueTraits<IDLUnsignedShortEnforceRange>
- : public NativeValueTraitsBase<IDLUnsignedShort> {
- static uint16_t NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToUInt16(isolate, value, kEnforceRange, exception_state);
+struct CORE_EXPORT NativeValueTraits<IDLNullable<IDLStringV2>>
+ : public NativeValueTraitsBase<IDLNullable<IDLStringV2>> {
+ static decltype(auto) NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ return NativeValueTraits<IDLStringBaseV2<
+ bindings::IDLStringConvMode::kNullable>>::NativeValue(isolate, value,
+ exception_state);
}
};
-template <>
-struct CORE_EXPORT NativeValueTraits<IDLLongEnforceRange>
- : public NativeValueTraitsBase<IDLLong> {
- static int32_t NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToInt32(isolate, value, kEnforceRange, exception_state);
+template <bindings::IDLStringConvMode mode>
+struct NativeValueTraits<IDLUSVStringBaseV2<mode>>
+ : public NativeValueTraitsBase<IDLUSVStringBaseV2<mode>> {
+ // http://heycam.github.io/webidl/#es-USVString
+ static bindings::NativeValueTraitsStringAdapter NativeValue(
+ v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ String string = NativeValueTraits<IDLStringBaseV2<mode>>::NativeValue(
+ isolate, value, exception_state);
+ if (exception_state.HadException())
+ return bindings::NativeValueTraitsStringAdapter();
+
+ return bindings::NativeValueTraitsStringAdapter(
+ ReplaceUnmatchedSurrogates(string));
}
};
template <>
-struct CORE_EXPORT NativeValueTraits<IDLUnsignedLongEnforceRange>
- : public NativeValueTraitsBase<IDLUnsignedLong> {
- static uint32_t NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToUInt32(isolate, value, kEnforceRange, exception_state);
+struct CORE_EXPORT NativeValueTraits<IDLNullable<IDLUSVStringV2>>
+ : public NativeValueTraitsBase<IDLNullable<IDLUSVStringV2>> {
+ static decltype(auto) NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ return NativeValueTraits<IDLUSVStringBaseV2<
+ bindings::IDLStringConvMode::kNullable>>::NativeValue(isolate, value,
+ exception_state);
}
};
-template <>
-struct CORE_EXPORT NativeValueTraits<IDLLongLongEnforceRange>
- : public NativeValueTraitsBase<IDLLongLong> {
- static int64_t NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToInt64(isolate, value, kEnforceRange, exception_state);
+template <bindings::IDLStringConvMode mode>
+struct NativeValueTraits<IDLStringStringContextTrustedHTMLBaseV2<mode>>
+ : public NativeValueTraitsBase<
+ IDLStringStringContextTrustedHTMLBaseV2<mode>> {
+ static String NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state,
+ ExecutionContext* execution_context) {
+ if (TrustedHTML* trusted_html =
+ V8TrustedHTML::ToImplWithTypeCheck(isolate, value)) {
+ return trusted_html->toString();
+ }
+
+ auto&& string = NativeValueTraits<IDLStringBaseV2<mode>>::NativeValue(
+ isolate, value, exception_state);
+ if (exception_state.HadException())
+ return String();
+ return TrustedTypesCheckForHTML(string, execution_context, exception_state);
}
};
template <>
-struct CORE_EXPORT NativeValueTraits<IDLUnsignedLongLongEnforceRange>
- : public NativeValueTraitsBase<IDLUnsignedLongLong> {
- static uint64_t NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToUInt64(isolate, value, kEnforceRange, exception_state);
+struct CORE_EXPORT
+ NativeValueTraits<IDLNullable<IDLStringStringContextTrustedHTMLV2>>
+ : public NativeValueTraitsBase<
+ IDLNullable<IDLStringStringContextTrustedHTMLV2>> {
+ static String NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state,
+ ExecutionContext* execution_context) {
+ return NativeValueTraits<IDLStringStringContextTrustedHTMLBaseV2<
+ bindings::IDLStringConvMode::kNullable>>::
+ NativeValue(isolate, value, exception_state, execution_context);
}
};
-// Strings
-template <V8StringResourceMode Mode>
-struct NativeValueTraits<IDLByteStringBase<Mode>>
- : public NativeValueTraitsBase<IDLByteStringBase<Mode>> {
- // http://heycam.github.io/webidl/#es-ByteString
+template <bindings::IDLStringConvMode mode>
+struct NativeValueTraits<IDLStringStringContextTrustedScriptBaseV2<mode>>
+ : public NativeValueTraitsBase<
+ IDLStringStringContextTrustedScriptBaseV2<mode>> {
static String NativeValue(v8::Isolate* isolate,
v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- V8StringResource<Mode> string_resource(value);
- // 1. Let x be ToString(v)
- if (!string_resource.Prepare(isolate, exception_state))
- return String();
- String x = string_resource;
- // 2. If the value of any element of x is greater than 255, then throw a
- // TypeError.
- if (!x.ContainsOnlyLatin1OrEmpty()) {
- exception_state.ThrowTypeError("Value is not a valid ByteString.");
- return String();
+ ExceptionState& exception_state,
+ ExecutionContext* execution_context) {
+ if (TrustedScript* trusted_script =
+ V8TrustedScript::ToImplWithTypeCheck(isolate, value)) {
+ return trusted_script->toString();
}
- // 3. Return an IDL ByteString value whose length is the length of x, and
- // where the value of each element is the value of the corresponding
- // element of x.
- // Blink: A ByteString is simply a String with a range constrained per
- // the above, so this is the identity operation.
- return x;
+ auto&& string = NativeValueTraits<IDLStringBaseV2<mode>>::NativeValue(
+ isolate, value, exception_state);
+ if (exception_state.HadException())
+ return String();
+ return TrustedTypesCheckForScript(string, execution_context,
+ exception_state);
}
-
- static String NullValue() { return String(); }
};
-template <V8StringResourceMode Mode>
-struct NativeValueTraits<IDLStringBase<Mode>>
- : public NativeValueTraitsBase<IDLStringBase<Mode>> {
- // https://heycam.github.io/webidl/#es-DOMString
+template <>
+struct CORE_EXPORT
+ NativeValueTraits<IDLNullable<IDLStringStringContextTrustedScriptV2>>
+ : public NativeValueTraitsBase<
+ IDLNullable<IDLStringStringContextTrustedScriptV2>> {
static String NativeValue(v8::Isolate* isolate,
v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- V8StringResource<Mode> string(value);
- if (!string.Prepare(isolate, exception_state))
- return String();
- return string;
+ ExceptionState& exception_state,
+ ExecutionContext* execution_context) {
+ return NativeValueTraits<IDLStringStringContextTrustedScriptBaseV2<
+ bindings::IDLStringConvMode::kNullable>>::
+ NativeValue(isolate, value, exception_state, execution_context);
}
-
- static String NullValue() { return String(); }
};
-template <V8StringResourceMode Mode>
-struct NativeValueTraits<IDLUSVStringBase<Mode>>
- : public NativeValueTraitsBase<IDLUSVStringBase<Mode>> {
- // http://heycam.github.io/webidl/#es-USVString
+template <bindings::IDLStringConvMode mode>
+struct NativeValueTraits<IDLUSVStringStringContextTrustedScriptURLBaseV2<mode>>
+ : public NativeValueTraitsBase<
+ IDLUSVStringStringContextTrustedScriptURLBaseV2<mode>> {
static String NativeValue(v8::Isolate* isolate,
v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- // 1. Let string be the result of converting V to a DOMString.
- V8StringResource<Mode> string(value);
- if (!string.Prepare(isolate, exception_state))
+ ExceptionState& exception_state,
+ ExecutionContext* execution_context) {
+ if (TrustedScriptURL* trusted_script_url =
+ V8TrustedScriptURL::ToImplWithTypeCheck(isolate, value)) {
+ return trusted_script_url->toString();
+ }
+
+ auto&& string = NativeValueTraits<IDLUSVStringBaseV2<mode>>::NativeValue(
+ isolate, value, exception_state);
+ if (exception_state.HadException())
return String();
- // 2. Return an IDL USVString value that is the result of converting string
- // to a sequence of Unicode scalar values.
- return ReplaceUnmatchedSurrogates(string);
+ return TrustedTypesCheckForScriptURL(string, execution_context,
+ exception_state);
}
-
- static String NullValue() { return String(); }
};
-// Floats and doubles
template <>
-struct CORE_EXPORT NativeValueTraits<IDLDouble>
- : public NativeValueTraitsBase<IDLDouble> {
- static double NativeValue(v8::Isolate* isolate,
+struct CORE_EXPORT
+ NativeValueTraits<IDLNullable<IDLUSVStringStringContextTrustedScriptURLV2>>
+ : public NativeValueTraitsBase<
+ IDLNullable<IDLUSVStringStringContextTrustedScriptURLV2>> {
+ static String NativeValue(v8::Isolate* isolate,
v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToRestrictedDouble(isolate, value, exception_state);
+ ExceptionState& exception_state,
+ ExecutionContext* execution_context) {
+ return NativeValueTraits<IDLUSVStringStringContextTrustedScriptURLBaseV2<
+ bindings::IDLStringConvMode::kNullable>>::
+ NativeValue(isolate, value, exception_state, execution_context);
}
};
+// Buffer source types
template <>
-struct CORE_EXPORT NativeValueTraits<IDLUnrestrictedDouble>
- : public NativeValueTraitsBase<IDLUnrestrictedDouble> {
- static double NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToDouble(isolate, value, exception_state);
- }
+struct CORE_EXPORT NativeValueTraits<DOMArrayBuffer>
+ : public NativeValueTraitsBase<DOMArrayBuffer*> {
+ static DOMArrayBuffer* NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state);
+
+ static DOMArrayBuffer* ArgumentValue(v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state);
+};
+template <>
+struct CORE_EXPORT NativeValueTraits<IDLNullable<DOMArrayBuffer>>
+ : public NativeValueTraitsBase<DOMArrayBuffer*> {
+ static DOMArrayBuffer* NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state);
+
+ static DOMArrayBuffer* ArgumentValue(v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state);
};
+template <typename T>
+struct NativeValueTraits<
+ NotShared<T>,
+ typename std::enable_if_t<std::is_base_of<DOMArrayBufferView, T>::value>>
+ : public NativeValueTraitsBase<NotShared<T>> {
+ static NotShared<T> NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state);
+
+ static NotShared<T> ArgumentValue(v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state);
+};
+template <typename T>
+struct NativeValueTraits<
+ IDLNullable<NotShared<T>>,
+ typename std::enable_if_t<std::is_base_of<DOMArrayBufferView, T>::value>>
+ : public NativeValueTraitsBase<NotShared<T>> {
+ static NotShared<T> NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state);
+
+ static NotShared<T> ArgumentValue(v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state);
+};
+
+template <typename T>
+struct NativeValueTraits<
+ MaybeShared<T>,
+ typename std::enable_if_t<std::is_base_of<DOMArrayBufferView, T>::value>>
+ : public NativeValueTraitsBase<MaybeShared<T>> {
+ static MaybeShared<T> NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state);
+
+ static MaybeShared<T> ArgumentValue(v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state);
+};
+template <typename T>
+struct NativeValueTraits<
+ IDLNullable<MaybeShared<T>>,
+ typename std::enable_if_t<std::is_base_of<DOMArrayBufferView, T>::value>>
+ : public NativeValueTraitsBase<MaybeShared<T>> {
+ static MaybeShared<T> NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state);
+
+ static MaybeShared<T> ArgumentValue(v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state);
+};
+
+template <typename T>
+struct NativeValueTraits<
+ T,
+ typename std::enable_if_t<
+ std::is_base_of<FlexibleArrayBufferView, T>::value>>
+ : public NativeValueTraitsBase<T> {
+ // FlexibleArrayBufferView must be used only as arguments.
+ static T NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) = delete;
+
+ static T ArgumentValue(v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state);
+};
+template <typename T>
+struct NativeValueTraits<
+ IDLNullable<T>,
+ typename std::enable_if_t<
+ std::is_base_of<FlexibleArrayBufferView, T>::value>>
+ : public NativeValueTraitsBase<T> {
+ // FlexibleArrayBufferView must be used only as arguments.
+ static T NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) = delete;
+
+ static T ArgumentValue(v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state);
+};
+
+// object
template <>
-struct CORE_EXPORT NativeValueTraits<IDLFloat>
- : public NativeValueTraitsBase<IDLFloat> {
- static float NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToRestrictedFloat(isolate, value, exception_state);
+struct CORE_EXPORT NativeValueTraits<IDLObject>
+ : public NativeValueTraitsBase<IDLObject> {
+ static ScriptValue NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (value->IsObject())
+ return ScriptValue(isolate, value);
+ exception_state.ThrowTypeError(
+ ExceptionMessages::FailedToConvertJSValue("object"));
+ return ScriptValue();
+ }
+
+ static ScriptValue ArgumentValue(v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (value->IsObject())
+ return ScriptValue(isolate, value);
+ exception_state.ThrowTypeError(
+ ExceptionMessages::ArgumentNotOfType(argument_index, "object"));
+ return ScriptValue();
}
};
template <>
-struct CORE_EXPORT NativeValueTraits<IDLUnrestrictedFloat>
- : public NativeValueTraitsBase<IDLUnrestrictedFloat> {
- static float NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToFloat(isolate, value, exception_state);
+struct CORE_EXPORT NativeValueTraits<IDLNullable<IDLObject>>
+ : public NativeValueTraitsBase<IDLNullable<IDLObject>> {
+ static ScriptValue NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (value->IsObject())
+ return ScriptValue(isolate, value);
+ if (value->IsNullOrUndefined())
+ return ScriptValue(isolate, v8::Null(isolate));
+ exception_state.ThrowTypeError(
+ ExceptionMessages::FailedToConvertJSValue("object"));
+ return ScriptValue();
+ }
+
+ static ScriptValue ArgumentValue(v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (value->IsObject())
+ return ScriptValue(isolate, value);
+ if (value->IsNullOrUndefined())
+ return ScriptValue(isolate, v8::Null(isolate));
+ exception_state.ThrowTypeError(
+ ExceptionMessages::ArgumentNotOfType(argument_index, "object"));
+ return ScriptValue();
}
};
-// Promises
+// Promise types
template <>
struct CORE_EXPORT NativeValueTraits<IDLPromise>
: public NativeValueTraitsBase<IDLPromise> {
static ScriptPromise NativeValue(v8::Isolate* isolate,
v8::Local<v8::Value> value,
ExceptionState& exception_state) {
- return NativeValue(isolate, value);
- }
-
- static ScriptPromise NativeValue(v8::Isolate* isolate,
- v8::Local<v8::Value> value) {
- return ScriptPromise::Cast(ScriptState::Current(isolate), value);
+ return ScriptPromise::Cast(ScriptState::From(isolate->GetCurrentContext()),
+ value);
}
};
-
-// Type-specific overloads
+// IDLNullable<IDLPromise> must not be used.
template <>
-struct CORE_EXPORT NativeValueTraits<IDLDateOrNull>
- : public NativeValueTraitsBase<IDLDateOrNull> {
- static base::Optional<base::Time> NativeValue(
- v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- ExceptionState& exception_state) {
- return ToCoreNullableDate(isolate, value, exception_state);
- }
-};
+struct NativeValueTraits<IDLNullable<IDLPromise>>;
-// Sequences
+// Sequence types
template <typename T>
struct NativeValueTraits<IDLSequence<T>>
: public NativeValueTraitsBase<IDLSequence<T>> {
@@ -538,7 +882,7 @@ struct NativeValueTraits<IDLSequence<T>>
}
};
-// Records
+// Record types
template <typename K, typename V>
struct NativeValueTraits<IDLRecord<K, V>>
: public NativeValueTraitsBase<IDLRecord<K, V>> {
@@ -662,13 +1006,127 @@ struct NativeValueTraits<IDLRecord<K, V>>
}
};
-// Dictionary
+// Callback function types
template <typename T>
struct NativeValueTraits<
T,
- typename std::enable_if<
- std::is_base_of<bindings::DictionaryBase, T>::value>::type>
- : public NativeValueTraitsBase<T> {
+ typename std::enable_if_t<std::is_base_of<CallbackFunctionBase, T>::value>>
+ : public NativeValueTraitsBase<T*> {
+ static T* NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (value->IsFunction())
+ return T::Create(value.As<v8::Function>());
+ exception_state.ThrowTypeError("The given value is not a function.");
+ return nullptr;
+ }
+
+ static T* ArgumentValue(v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (value->IsFunction())
+ return T::Create(value.As<v8::Function>());
+ exception_state.ThrowTypeError(
+ ExceptionMessages::ArgumentNotOfType(argument_index, "Function"));
+ return nullptr;
+ }
+};
+
+template <typename T>
+struct NativeValueTraits<
+ IDLNullable<T>,
+ typename std::enable_if_t<std::is_base_of<CallbackFunctionBase, T>::value>>
+ : public NativeValueTraitsBase<IDLNullable<T>> {
+ static T* NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (value->IsFunction())
+ return T::Create(value.As<v8::Function>());
+ if (value->IsNullOrUndefined())
+ return nullptr;
+ exception_state.ThrowTypeError("The given value is not a function.");
+ return nullptr;
+ }
+
+ static T* ArgumentValue(v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (value->IsFunction())
+ return T::Create(value.As<v8::Function>());
+ if (value->IsNullOrUndefined())
+ return nullptr;
+ exception_state.ThrowTypeError(
+ ExceptionMessages::ArgumentNotOfType(argument_index, "Function"));
+ return nullptr;
+ }
+};
+
+// Callback interface types
+template <typename T>
+struct NativeValueTraits<
+ T,
+ typename std::enable_if_t<std::is_base_of<CallbackInterfaceBase, T>::value>>
+ : public NativeValueTraitsBase<T*> {
+ static T* NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (value->IsObject())
+ return T::Create(value.As<v8::Object>());
+ exception_state.ThrowTypeError("The given value is not an object.");
+ return nullptr;
+ }
+
+ static T* ArgumentValue(v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (value->IsObject())
+ return T::Create(value.As<v8::Object>());
+ exception_state.ThrowTypeError(
+ ExceptionMessages::ArgumentNotOfType(argument_index, "Object"));
+ return nullptr;
+ }
+};
+
+template <typename T>
+struct NativeValueTraits<
+ IDLNullable<T>,
+ typename std::enable_if_t<std::is_base_of<CallbackInterfaceBase, T>::value>>
+ : public NativeValueTraitsBase<IDLNullable<T>> {
+ static T* NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (value->IsObject())
+ return T::Create(value.As<v8::Object>());
+ if (value->IsNullOrUndefined())
+ return nullptr;
+ exception_state.ThrowTypeError("The given value is not an object.");
+ return nullptr;
+ }
+
+ static T* ArgumentValue(v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (value->IsObject())
+ return T::Create(value.As<v8::Object>());
+ if (value->IsNullOrUndefined())
+ return nullptr;
+ exception_state.ThrowTypeError(
+ ExceptionMessages::ArgumentNotOfType(argument_index, "Object"));
+ return nullptr;
+ }
+};
+
+// Dictionary types
+template <typename T>
+struct NativeValueTraits<
+ T,
+ typename std::enable_if_t<
+ std::is_base_of<bindings::DictionaryBase, T>::value>>
+ : public NativeValueTraitsBase<T*> {
static T* NativeValue(v8::Isolate* isolate,
v8::Local<v8::Value> value,
ExceptionState& exception_state) {
@@ -676,42 +1134,218 @@ struct NativeValueTraits<
}
};
-// Callback functions
+template <typename T>
+struct NativeValueTraits<
+ IDLNullable<T>,
+ typename std::enable_if_t<std::is_base_of<IDLDictionaryBase, T>::value>>
+ : public NativeValueTraitsBase<IDLNullable<T>> {
+ static T* NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (value->IsObject())
+ return NativeValueTraits<T>::NativeValue(isolate, value, exception_state);
+ if (value->IsNullOrUndefined())
+ return nullptr;
+ exception_state.ThrowTypeError("The given value is not an object.");
+ return nullptr;
+ }
+
+ static T* ArgumentValue(v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (value->IsObject())
+ return NativeValueTraits<T>::NativeValue(isolate, value, exception_state);
+ if (value->IsNullOrUndefined())
+ return nullptr;
+ exception_state.ThrowTypeError(
+ ExceptionMessages::ArgumentNotOfType(argument_index, "Object"));
+ return nullptr;
+ }
+};
+
+// Enumeration types
template <typename T>
struct NativeValueTraits<
T,
- std::enable_if_t<std::is_base_of<CallbackFunctionBase, T>::value>>
+ typename std::enable_if_t<
+ std::is_base_of<bindings::EnumerationBase, T>::value>>
: public NativeValueTraitsBase<T> {
+ static T NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ return T::Create(isolate, value, exception_state);
+ }
+};
+
+// Interface types
+template <typename T>
+struct NativeValueTraits<
+ T,
+ typename std::enable_if_t<std::is_base_of<ScriptWrappable, T>::value>>
+ : public NativeValueTraitsBase<T*> {
static T* NativeValue(v8::Isolate* isolate,
v8::Local<v8::Value> value,
ExceptionState& exception_state) {
- // Not implemented because of no use case so far.
- CHECK(false)
- // Emit a message so that NativeValueTraitsImplTest.IDLCallbackFunction
- // test can confirm that it's hitting this specific failure. i.e.
- // the template resolution is working as expected.
- << "NativeValueTraits<CallbackFunctionBase>::NativeValue "
- << "is not yet implemented.";
- return nullptr;
+ return bindings::NativeValueTraitsInterfaceNativeValue(
+ isolate, T::GetStaticWrapperTypeInfo(), value, exception_state)
+ ->template ToImpl<T>();
+ }
+
+ static T* ArgumentValue(v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ return bindings::NativeValueTraitsInterfaceArgumentValue(
+ isolate, T::GetStaticWrapperTypeInfo(), argument_index, value,
+ exception_state)
+ ->template ToImpl<T>();
+ }
+};
+
+template <typename T>
+struct NativeValueTraits<
+ IDLNullable<T>,
+ typename std::enable_if_t<std::is_base_of<ScriptWrappable, T>::value>>
+ : public NativeValueTraitsBase<IDLNullable<T>> {
+ static T* NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ return bindings::NativeValueTraitsInterfaceOrNullNativeValue(
+ isolate, T::GetStaticWrapperTypeInfo(), value, exception_state)
+ ->template ToImpl<T>();
+ }
+
+ static T* ArgumentValue(v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ return bindings::NativeValueTraitsInterfaceOrNullArgumentValue(
+ isolate, T::GetStaticWrapperTypeInfo(), argument_index, value,
+ exception_state)
+ ->template ToImpl<T>();
+ }
+};
+
+// Union types
+template <typename T>
+struct NativeValueTraits<
+ T,
+ typename std::enable_if_t<std::is_base_of<bindings::UnionBase, T>::value>>
+ : public NativeValueTraitsBase<T> {
+ static T NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ return T::Create(isolate, value, exception_state);
}
};
-// Nullable
+// Nullable types
template <typename InnerType>
-struct NativeValueTraits<IDLNullable<InnerType>>
+struct NativeValueTraits<
+ IDLNullable<InnerType>,
+ typename std::enable_if_t<!NativeValueTraits<InnerType>::has_null_value>>
: public NativeValueTraitsBase<IDLNullable<InnerType>> {
// https://heycam.github.io/webidl/#es-nullable-type
- static typename IDLNullable<InnerType>::ResultType NativeValue(
+ using ImplType =
+ base::Optional<typename NativeValueTraits<InnerType>::ImplType>;
+
+ static ImplType NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (value->IsNullOrUndefined())
+ return base::nullopt;
+ return NativeValueTraits<InnerType>::NativeValue(isolate, value,
+ exception_state);
+ }
+
+ static ImplType ArgumentValue(v8::Isolate* isolate,
+ int argument_index,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (value->IsNullOrUndefined())
+ return base::nullopt;
+ return NativeValueTraits<InnerType>::ArgumentValue(isolate, argument_index,
+ value, exception_state);
+ }
+};
+// IDLNullable<IDLNullable<T>> must not be used.
+template <typename T>
+struct NativeValueTraits<IDLNullable<IDLNullable<T>>>;
+
+// IDLNullable<union types generated by the old bindings generator>
+// Migration adapter
+template <typename InnerType>
+struct NativeValueTraits<
+ IDLNullable<InnerType>,
+ base::void_t<decltype(NativeValueTraits<InnerType>::NullValue)>>
+ : public NativeValueTraitsBase<IDLNullable<InnerType>> {
+ static decltype(auto) NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) {
+ if (value->IsNullOrUndefined())
+ return NativeValueTraits<InnerType>::NullValue();
+ return NativeValueTraits<InnerType>::NativeValue(isolate, value,
+ exception_state);
+ }
+};
+
+// Date
+template <>
+struct CORE_EXPORT NativeValueTraits<IDLDate>
+ : public NativeValueTraitsBase<IDLDate> {
+ // IDLDate must be always used as IDLNullable<IDLDate>.
+ static base::Optional<base::Time> NativeValue(
v8::Isolate* isolate,
- v8::Local<v8::Value> v8_value,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state) = delete;
+};
+
+template <>
+struct CORE_EXPORT NativeValueTraits<IDLNullable<IDLDate>>
+ : public NativeValueTraitsBase<IDLNullable<IDLDate>> {
+ static base::Optional<base::Time> NativeValue(
+ v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
ExceptionState& exception_state) {
- if (v8_value->IsNullOrUndefined())
- return IDLNullable<InnerType>::NullValue();
- return NativeValueTraits<InnerType>::NativeValue(isolate, v8_value,
- exception_state);
+ return ToCoreNullableDate(isolate, value, exception_state);
}
};
+// EventHandler
+template <>
+struct CORE_EXPORT NativeValueTraits<IDLEventHandler>
+ : public NativeValueTraitsBase<IDLEventHandler> {
+ static EventListener* NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state);
+};
+
+template <>
+struct CORE_EXPORT NativeValueTraits<IDLOnBeforeUnloadEventHandler>
+ : public NativeValueTraitsBase<IDLOnBeforeUnloadEventHandler> {
+ static EventListener* NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state);
+};
+
+template <>
+struct CORE_EXPORT NativeValueTraits<IDLOnErrorEventHandler>
+ : public NativeValueTraitsBase<IDLOnErrorEventHandler> {
+ static EventListener* NativeValue(v8::Isolate* isolate,
+ v8::Local<v8::Value> value,
+ ExceptionState& exception_state);
+};
+
+// EventHandler and its family are nullable, so IDLNullable<IDLEventHandler>
+// must not be used.
+template <>
+struct NativeValueTraits<IDLNullable<IDLEventHandler>>;
+template <>
+struct NativeValueTraits<IDLNullable<IDLOnBeforeUnloadEventHandler>>;
+template <>
+struct NativeValueTraits<IDLNullable<IDLOnErrorEventHandler>>;
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_NATIVE_VALUE_TRAITS_IMPL_H_
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl_test.cc
index 7ea955c253d..7281eab8e0d 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl_test.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl_test.cc
@@ -46,17 +46,6 @@ TEST(NativeValueTraitsImplTest, IDLInterface) {
EXPECT_EQ(nullptr, internals);
}
-TEST(NativeValueTraitsImplTest, IDLCallbackFunction) {
- V8TestingScope scope;
- DummyExceptionStateForTesting exception_state;
- v8::Local<v8::Function> function =
- v8::Function::New(scope.GetContext(), nullptr).ToLocalChecked();
- ASSERT_DEATH_IF_SUPPORTED(
- NativeValueTraits<V8TestSequenceCallback>::NativeValue(
- scope.GetIsolate(), function, exception_state),
- "");
-}
-
TEST(NativeValueTraitsImplTest, IDLRecord) {
V8TestingScope scope;
{
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_test.cc
index 9ec7fc00c23..4f50455230a 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_test.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_test.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/bindings/core/v8/native_value_traits.h"
#include <type_traits>
+
#include "third_party/blink/renderer/bindings/core/v8/idl_types_base.h"
// No gtest tests; only static_assert checks.
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 1225f8b377c..fbf3ff83006 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
@@ -5,11 +5,11 @@
#include "third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.h"
#include "base/time/time.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_profiler_frame.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_profiler_sample.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_profiler_stack.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_profiler_trace.h"
#include "third_party/blink/renderer/core/timing/performance.h"
-#include "third_party/blink/renderer/core/timing/profiler_frame.h"
-#include "third_party/blink/renderer/core/timing/profiler_sample.h"
-#include "third_party/blink/renderer/core/timing/profiler_stack.h"
-#include "third_party/blink/renderer/core/timing/profiler_trace.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -25,11 +25,13 @@ ProfilerTrace* ProfilerTraceBuilder::FromProfile(
TRACE_EVENT0("blink", "ProfilerTraceBuilder::FromProfile");
ProfilerTraceBuilder* builder = MakeGarbageCollected<ProfilerTraceBuilder>(
script_state, allowed_origin, time_origin);
- for (int i = 0; i < profile->GetSamplesCount(); i++) {
- const auto* node = profile->GetSample(i);
- auto timestamp = base::TimeTicks() + base::TimeDelta::FromMicroseconds(
- profile->GetSampleTimestamp(i));
- builder->AddSample(node, timestamp);
+ if (profile) {
+ for (int i = 0; i < profile->GetSamplesCount(); i++) {
+ const auto* node = profile->GetSample(i);
+ auto timestamp = base::TimeTicks() + base::TimeDelta::FromMicroseconds(
+ profile->GetSampleTimestamp(i));
+ builder->AddSample(node, timestamp);
+ }
}
return builder->GetTrace();
}
@@ -41,7 +43,7 @@ ProfilerTraceBuilder::ProfilerTraceBuilder(ScriptState* script_state,
allowed_origin_(allowed_origin),
time_origin_(time_origin) {}
-void ProfilerTraceBuilder::Trace(blink::Visitor* visitor) {
+void ProfilerTraceBuilder::Trace(Visitor* visitor) {
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 ca5975ade93..2f02b90ba82 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(blink::Visitor*);
+ void Trace(Visitor*);
private:
// Adds a stack sample from V8 to the trace, performing necessary filtering
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 9f459d22d1c..31fe75f0aef 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
@@ -10,6 +10,7 @@
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_promise_rejection_event_init.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/events/promise_rejection_event.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/remote_window_proxy.cc b/chromium/third_party/blink/renderer/bindings/core/v8/remote_window_proxy.cc
index 60b86dd4b82..0b79324d8d5 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/remote_window_proxy.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/remote_window_proxy.cc
@@ -49,8 +49,7 @@ RemoteWindowProxy::RemoteWindowProxy(v8::Isolate* isolate,
: WindowProxy(isolate, frame, std::move(world)) {}
void RemoteWindowProxy::DisposeContext(Lifecycle next_status,
- FrameReuseStatus,
- v8::Context::DetachedWindowReason) {
+ FrameReuseStatus) {
DCHECK(next_status == Lifecycle::kV8MemoryIsForciblyPurged ||
next_status == Lifecycle::kGlobalObjectIsDetached ||
next_status == Lifecycle::kFrameIsDetached ||
@@ -146,9 +145,8 @@ void RemoteWindowProxy::SetupWindowPrototypeChain() {
// The global object, aka window wrapper object.
v8::Local<v8::Object> window_wrapper =
global_proxy->GetPrototype().As<v8::Object>();
- v8::Local<v8::Object> associated_wrapper =
- AssociateWithWrapper(window, wrapper_type_info, window_wrapper);
- DCHECK(associated_wrapper == window_wrapper);
+ V8DOMWrapper::SetNativeInfo(GetIsolate(), window_wrapper, wrapper_type_info,
+ window);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/remote_window_proxy.h b/chromium/third_party/blink/renderer/bindings/core/v8/remote_window_proxy.h
index b95e0b39ae9..0841c421bef 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/remote_window_proxy.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/remote_window_proxy.h
@@ -49,9 +49,7 @@ class RemoteWindowProxy final : public WindowProxy {
private:
void Initialize() override;
- void DisposeContext(Lifecycle next_status,
- FrameReuseStatus,
- v8::Context::DetachedWindowReason) override;
+ void DisposeContext(Lifecycle next_status, FrameReuseStatus) override;
// Creates a new v8::Context with the window wrapper object as the global
// object (aka the inner global). Note that the window wrapper and its
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 98ab44a845b..15c2ebe09f8 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
@@ -60,7 +60,7 @@ ScheduledAction::ScheduledAction(ScriptState* script_state,
if (script_state->World().IsWorkerWorld() ||
BindingSecurity::ShouldAllowAccessToFrame(
EnteredDOMWindow(script_state->GetIsolate()),
- To<Document>(target)->GetFrame(),
+ Document::From(target)->GetFrame(),
BindingSecurity::ErrorReportOption::kDoNotReport)) {
function_ = handler;
arguments_ = arguments;
@@ -77,7 +77,7 @@ ScheduledAction::ScheduledAction(ScriptState* script_state,
if (script_state->World().IsWorkerWorld() ||
BindingSecurity::ShouldAllowAccessToFrame(
EnteredDOMWindow(script_state->GetIsolate()),
- To<Document>(target)->GetFrame(),
+ Document::From(target)->GetFrame(),
BindingSecurity::ErrorReportOption::kDoNotReport)) {
code_ = handler;
} else {
@@ -121,7 +121,7 @@ void ScheduledAction::Execute(ExecutionContext* context) {
// determine if it is allowed. Enter the scope here.
ScriptState::Scope scope(script_state_->Get());
- if (auto* document = DynamicTo<Document>(context)) {
+ if (auto* document = Document::DynamicFrom(context)) {
LocalFrame* frame = document->GetFrame();
if (!frame) {
DVLOG(1) << "ScheduledAction::execute " << this << ": no frame";
@@ -139,7 +139,7 @@ void ScheduledAction::Execute(ExecutionContext* context) {
}
}
-void ScheduledAction::Trace(blink::Visitor* visitor) {
+void ScheduledAction::Trace(Visitor* visitor) {
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 36881ef1a5b..4f81e0c3800 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(blink::Visitor*);
+ void Trace(Visitor*);
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 363375fe315..aa5720bd81d 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
@@ -35,6 +35,7 @@
#include <memory>
#include <utility>
+#include "base/bind_helpers.h"
#include "third_party/blink/public/web/web_settings.h"
#include "third_party/blink/renderer/bindings/core/v8/referrer_script_info.h"
#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
@@ -71,7 +72,7 @@
namespace blink {
-void ScriptController::Trace(blink::Visitor* visitor) {
+void ScriptController::Trace(Visitor* visitor) {
visitor->Trace(frame_);
visitor->Trace(window_proxy_manager_);
}
@@ -129,8 +130,8 @@ v8::Local<v8::Value> ScriptController::ExecuteScriptAndReturnValue(
return result;
v8::MaybeLocal<v8::Value> maybe_result;
- maybe_result = V8ScriptRunner::RunCompiledScript(GetIsolate(), script,
- GetFrame()->GetDocument());
+ maybe_result = V8ScriptRunner::RunCompiledScript(
+ GetIsolate(), script, GetFrame()->GetDocument()->ToExecutionContext());
probe::ProduceCompilationCache(frame_, source, script);
V8CodeCache::ProduceCache(GetIsolate(), script, source,
produce_cache_options);
@@ -232,7 +233,7 @@ void ScriptController::UpdateDocument() {
void ScriptController::ExecuteJavaScriptURL(
const KURL& url,
- ContentSecurityPolicyDisposition check_main_world_csp) {
+ network::mojom::CSPDisposition check_main_world_csp) {
DCHECK(url.ProtocolIsJavaScript());
const int kJavascriptSchemeLength = sizeof("javascript:") - 1;
@@ -240,8 +241,9 @@ void ScriptController::ExecuteJavaScriptURL(
url.GetString(), DecodeURLMode::kUTF8OrIsomorphic);
bool should_bypass_main_world_content_security_policy =
- check_main_world_csp == kDoNotCheckContentSecurityPolicy ||
- ContentSecurityPolicy::ShouldBypassMainWorld(GetFrame()->GetDocument());
+ check_main_world_csp == network::mojom::CSPDisposition::DO_NOT_CHECK ||
+ ContentSecurityPolicy::ShouldBypassMainWorld(
+ GetFrame()->GetDocument()->ToExecutionContext());
if (!GetFrame()->GetPage())
return;
@@ -302,7 +304,7 @@ void ScriptController::ExecuteJavaScriptURL(
WebNavigationParams::FillStaticResponse(params.get(), "text/html", "UTF-8",
StringUTF8Adaptor(result));
GetFrame()->Loader().CommitNavigation(std::move(params), nullptr,
- base::DoNothing::Once(), true);
+ true /* is_javascript_url */);
}
void ScriptController::ExecuteScriptInMainWorld(
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 53dac106484..f0c8208e089 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
@@ -39,7 +39,6 @@
#include "third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
-#include "third_party/blink/renderer/platform/bindings/shared_persistent.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
#include "third_party/blink/renderer/platform/loader/fetch/script_fetch_options.h"
@@ -70,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(blink::Visitor*);
+ void Trace(Visitor*);
// This returns an initialized window proxy. (If the window proxy is not
// yet initialized, it's implicitly initialized at the first access.)
@@ -113,7 +112,7 @@ class CORE_EXPORT ScriptController final
const KURL& base_url,
SanitizeScriptErrors sanitize_script_errors);
- void ExecuteJavaScriptURL(const KURL&, ContentSecurityPolicyDisposition);
+ void ExecuteJavaScriptURL(const KURL&, network::mojom::CSPDisposition);
// Creates a new isolated world for DevTools with the given human readable
// |world_name| and returns it id or nullptr on failure.
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 075b20837c7..402e5370fd8 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
@@ -137,6 +137,7 @@ HTMLElement* ScriptCustomElementDefinition::HandleCreateElementSyncException(
HTMLElement* ScriptCustomElementDefinition::CreateAutonomousCustomElementSync(
Document& document,
const QualifiedName& tag_name) {
+ DCHECK(CustomElement::ShouldCreateCustomElement(tag_name)) << tag_name;
if (!script_state_->ContextIsValid())
return CustomElement::CreateFailedElement(document, tag_name);
ScriptState::Scope scope(script_state_);
@@ -219,15 +220,13 @@ bool ScriptCustomElementDefinition::RunConstructor(Element& element) {
if (try_catch.HasCaught())
return false;
- // To report InvalidStateError Exception, when the constructor returns some
- // different object
+ // Report a TypeError Exception if the constructor returns a different object.
if (result != &element) {
const String& message =
"custom element constructors must call super() first and must "
"not return a different object";
- v8::Local<v8::Value> exception = V8ThrowDOMException::CreateOrEmpty(
- script_state_->GetIsolate(), DOMExceptionCode::kInvalidStateError,
- message);
+ v8::Local<v8::Value> exception =
+ V8ThrowException::CreateTypeError(script_state_->GetIsolate(), message);
if (!exception.IsEmpty())
V8ScriptRunner::ReportException(isolate, exception);
return false;
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition_data.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition_data.h
index eab682e0532..286ae08e835 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition_data.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition_data.h
@@ -29,17 +29,19 @@ class ScriptCustomElementDefinitionData {
public:
ScriptCustomElementDefinitionData() {}
- Member<ScriptState> script_state_;
- Member<CustomElementRegistry> registry_;
- Member<V8CustomElementConstructor> constructor_;
- Member<V8VoidFunction> connected_callback_;
- Member<V8VoidFunction> disconnected_callback_;
- Member<V8CustomElementAdoptedCallback> adopted_callback_;
- Member<V8CustomElementAttributeChangedCallback> attribute_changed_callback_;
- Member<V8CustomElementFormAssociatedCallback> form_associated_callback_;
- Member<V8VoidFunction> form_reset_callback_;
- Member<V8CustomElementFormDisabledCallback> form_disabled_callback_;
- Member<V8CustomElementFormStateRestoreCallback> form_state_restore_callback_;
+ ScriptState* script_state_ = nullptr;
+ CustomElementRegistry* registry_ = nullptr;
+ V8CustomElementConstructor* constructor_ = nullptr;
+ V8VoidFunction* connected_callback_ = nullptr;
+ V8VoidFunction* disconnected_callback_ = nullptr;
+ V8CustomElementAdoptedCallback* adopted_callback_ = nullptr;
+ V8CustomElementAttributeChangedCallback* attribute_changed_callback_ =
+ nullptr;
+ V8CustomElementFormAssociatedCallback* form_associated_callback_ = nullptr;
+ V8VoidFunction* form_reset_callback_ = nullptr;
+ V8CustomElementFormDisabledCallback* form_disabled_callback_ = nullptr;
+ V8CustomElementFormStateRestoreCallback* form_state_restore_callback_ =
+ nullptr;
HashSet<AtomicString> observed_attributes_;
Vector<String> disabled_features_;
bool is_form_associated_ = false;
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 849ba6405ae..94f862354d0 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(blink::Visitor* visitor) {
+void ScriptFunction::Trace(Visitor* visitor) {
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 c9828700362..ed38826808e 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 25ec59b272e..f98cf313e7a 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(blink::Visitor* visitor) {
+ virtual void Trace(Visitor* visitor) {
visitor->Trace(resolver_);
visitor->Trace(values_);
}
@@ -95,7 +95,7 @@ class PromiseAllHandler final : public GarbageCollected<PromiseAllHandler> {
index_(index),
handler_(handler) {}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 fde92c9aeb2..6d317926d95 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
@@ -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(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
visitor->Trace(script_state_);
visitor->Trace(resolver_);
}
@@ -152,6 +152,10 @@ class CORE_EXPORT ScriptPromise final {
ScriptValue resolver_;
};
+ bool IsAssociatedWith(ScriptState* script_state) const {
+ return script_state == script_state_;
+ }
+
private:
static void IncreaseInstanceCount();
static void DecreaseInstanceCount();
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 c62e79e8dd5..7c83ee35246 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
@@ -8,8 +8,10 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
-#include "third_party/blink/renderer/bindings/core/v8/script_promise_property_base.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
namespace blink {
@@ -20,174 +22,163 @@ class ExecutionContext;
// attribute whose value is a Promise, and the same Promise must be
// returned each time.
//
-// ScriptPromiseProperty does not keep Promises or worlds alive to
-// deliver Promise resolution/rejection to them; the Promise
-// resolution/rejections are delivered if the holder's wrapper is
-// alive. This is achieved by keeping a weak reference from
-// ScriptPromiseProperty to the holder's wrapper, and references in
-// hidden values from the wrapper to the promise and resolver
-// (coincidentally the Resolver and Promise may be the same object,
-// but that is an implementation detail of v8.)
-//
-// ----> Resolver
-// /
-// ScriptPromiseProperty - - -> Holder Wrapper ----> Promise
-//
-// To avoid exposing the action of the garbage collector to script,
-// you should keep the wrapper alive as long as a promise may be
-// settled.
-//
-// To avoid clobbering hidden values, a holder should only have one
-// ScriptPromiseProperty object for a given name at a time. See reset.
-template <typename HolderType, typename ResolvedType, typename RejectedType>
-class ScriptPromiseProperty : public ScriptPromisePropertyBase {
+// Use ScriptPromise if the property is associated with only one world
+// (e.g., FetchEvent.preloadResponse). Use ScriptPromiseProperty if the property
+// can be accessed from multiple worlds (e.g., ServiceWorkerContainer.ready).
+template <typename ResolvedType, typename RejectedType>
+class ScriptPromiseProperty final
+ : public GarbageCollected<
+ ScriptPromiseProperty<ResolvedType, RejectedType>>,
+ public ExecutionContextClient {
+ USING_GARBAGE_COLLECTED_MIXIN(ScriptPromiseProperty);
+
public:
+ enum State {
+ kPending,
+ kResolved,
+ kRejected,
+ };
+
// Creates a ScriptPromiseProperty that will create Promises in
// the specified ExecutionContext for a property of 'holder'
// (typically ScriptPromiseProperty should be a member of the
// property holder).
- //
- // When implementing a ScriptPromiseProperty add the property name
- // to script_promise_properties.h and pass
- // ScriptPromiseProperty::Foo to create. The name must be unique
- // per kind of holder.
- template <typename PassHolderType>
- ScriptPromiseProperty(ExecutionContext*, PassHolderType, Name);
-
- ~ScriptPromiseProperty() override = default;
+ ScriptPromiseProperty(ExecutionContext* execution_context)
+ : ExecutionContextClient(execution_context) {}
+
+ ScriptPromise Promise(DOMWrapperWorld& world) {
+ if (!GetExecutionContext()) {
+ return ScriptPromise();
+ }
+
+ v8::HandleScope handle_scope(GetExecutionContext()->GetIsolate());
+ v8::Local<v8::Context> context = ToV8Context(GetExecutionContext(), world);
+ if (context.IsEmpty()) {
+ return ScriptPromise();
+ }
+ ScriptState* script_state = ScriptState::From(context);
+
+ for (const auto& promise : promises_) {
+ if (promise.IsAssociatedWith(script_state)) {
+ return promise;
+ }
+ }
+
+ ScriptState::Scope scope(script_state);
+
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ // ScriptPromiseResolver usually requires a caller to reject it before
+ // releasing, but ScriptPromiseProperty doesn't have such a requirement, so
+ // suppress the check forcibly.
+ resolver->SuppressDetachCheck();
+ ScriptPromise promise = resolver->Promise();
+ if (mark_as_handled_)
+ promise.MarkAsHandled();
+ switch (state_) {
+ case kPending:
+ resolvers_.push_back(resolver);
+ break;
+ case kResolved:
+ if (resolved_with_undefined_) {
+ resolver->Resolve();
+ } else {
+ resolver->Resolve(resolved_);
+ }
+ break;
+ case kRejected:
+ resolver->Reject(rejected_);
+ break;
+ }
+ promises_.push_back(promise);
+ return promise;
+ }
template <typename PassResolvedType>
- void Resolve(PassResolvedType);
+ void Resolve(PassResolvedType value) {
+ CHECK(!ScriptForbiddenScope::IsScriptForbidden());
+ DCHECK_EQ(GetState(), kPending);
+ if (!GetExecutionContext()) {
+ return;
+ }
+ state_ = kResolved;
+ resolved_ = value;
+ for (const Member<ScriptPromiseResolver>& resolver : resolvers_) {
+ resolver->Resolve(resolved_);
+ }
+ resolvers_.clear();
+ }
- void ResolveWithUndefined();
+ void ResolveWithUndefined() {
+ CHECK(!ScriptForbiddenScope::IsScriptForbidden());
+ DCHECK_EQ(GetState(), kPending);
+ if (!GetExecutionContext()) {
+ return;
+ }
+ state_ = kResolved;
+ resolved_with_undefined_ = true;
+ for (const Member<ScriptPromiseResolver>& resolver : resolvers_) {
+ resolver->Resolve();
+ }
+ resolvers_.clear();
+ }
template <typename PassRejectedType>
- void Reject(PassRejectedType);
+ void Reject(PassRejectedType value) {
+ CHECK(!ScriptForbiddenScope::IsScriptForbidden());
+ DCHECK_EQ(GetState(), kPending);
+ if (!GetExecutionContext()) {
+ return;
+ }
+ state_ = kRejected;
+ rejected_ = value;
+ for (const Member<ScriptPromiseResolver>& resolver : resolvers_) {
+ resolver->Reject(rejected_);
+ }
+ resolvers_.clear();
+ }
// Resets this property by unregistering the Promise property from the
// holder wrapper. Resets the internal state to Pending and clears the
// resolved and the rejected values.
- // This method keeps the holder object and the property name.
- void Reset();
+ void Reset() {
+ state_ = kPending;
+ resolved_ = ResolvedType();
+ rejected_ = RejectedType();
+ resolvers_.clear();
+ promises_.clear();
+ resolved_with_undefined_ = false;
+ }
+
+ // Mark generated promises as handled to avoid reporting unhandled rejections.
+ void MarkAsHandled() {
+ mark_as_handled_ = true;
+ for (auto& promise : promises_) {
+ promise.MarkAsHandled();
+ }
+ }
+
+ void Trace(Visitor* visitor) override {
+ TraceIfNeeded<ResolvedType>::Trace(visitor, resolved_);
+ TraceIfNeeded<RejectedType>::Trace(visitor, rejected_);
+ visitor->Trace(resolvers_);
+ visitor->Trace(promises_);
+ ExecutionContextClient::Trace(visitor);
+ }
- void Trace(blink::Visitor*) override;
+ State GetState() const { return state_; }
private:
- v8::Local<v8::Object> Holder(v8::Isolate*,
- v8::Local<v8::Object> creation_context) override;
- v8::Local<v8::Value> ResolvedValue(
- v8::Isolate*,
- v8::Local<v8::Object> creation_context) override;
- v8::Local<v8::Value> RejectedValue(
- v8::Isolate*,
- v8::Local<v8::Object> creation_context) override;
-
- HolderType holder_;
+ State state_ = kPending;
ResolvedType resolved_;
RejectedType rejected_;
+ HeapVector<Member<ScriptPromiseResolver>> resolvers_;
+ HeapVector<ScriptPromise> promises_;
bool resolved_with_undefined_ = false;
+ bool mark_as_handled_ = false;
DISALLOW_COPY_AND_ASSIGN(ScriptPromiseProperty);
};
-template <typename HolderType, typename ResolvedType, typename RejectedType>
-template <typename PassHolderType>
-ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::
- ScriptPromiseProperty(ExecutionContext* execution_context,
- PassHolderType holder,
- Name name)
- : ScriptPromisePropertyBase(execution_context, name), holder_(holder) {}
-
-template <typename HolderType, typename ResolvedType, typename RejectedType>
-template <typename PassResolvedType>
-void ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::Resolve(
- PassResolvedType value) {
- if (GetState() != kPending) {
- NOTREACHED();
- return;
- }
- CHECK(!ScriptForbiddenScope::IsScriptForbidden());
- if (!GetExecutionContext() || GetExecutionContext()->IsContextDestroyed())
- return;
- resolved_ = value;
- ResolveOrReject(kResolved);
-}
-
-template <typename HolderType, typename ResolvedType, typename RejectedType>
-void ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::
- ResolveWithUndefined() {
- if (GetState() != kPending) {
- NOTREACHED();
- return;
- }
- if (!GetExecutionContext() || GetExecutionContext()->IsContextDestroyed())
- return;
- resolved_with_undefined_ = true;
- ResolveOrReject(kResolved);
-}
-
-template <typename HolderType, typename ResolvedType, typename RejectedType>
-template <typename PassRejectedType>
-void ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::Reject(
- PassRejectedType value) {
- if (GetState() != kPending) {
- NOTREACHED();
- return;
- }
- if (!GetExecutionContext() || GetExecutionContext()->IsContextDestroyed())
- return;
- rejected_ = value;
- ResolveOrReject(kRejected);
-}
-
-template <typename HolderType, typename ResolvedType, typename RejectedType>
-v8::Local<v8::Object>
-ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::Holder(
- v8::Isolate* isolate,
- v8::Local<v8::Object> creation_context) {
- v8::Local<v8::Value> value = ToV8(holder_, creation_context, isolate);
- if (value.IsEmpty())
- return v8::Local<v8::Object>();
- return value.As<v8::Object>();
-}
-
-template <typename HolderType, typename ResolvedType, typename RejectedType>
-v8::Local<v8::Value>
-ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::ResolvedValue(
- v8::Isolate* isolate,
- v8::Local<v8::Object> creation_context) {
- DCHECK_EQ(GetState(), kResolved);
- if (!resolved_with_undefined_)
- return ToV8(resolved_, creation_context, isolate);
- return v8::Undefined(isolate);
-}
-
-template <typename HolderType, typename ResolvedType, typename RejectedType>
-v8::Local<v8::Value>
-ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::RejectedValue(
- v8::Isolate* isolate,
- v8::Local<v8::Object> creation_context) {
- DCHECK_EQ(GetState(), kRejected);
- return ToV8(rejected_, creation_context, isolate);
-}
-
-template <typename HolderType, typename ResolvedType, typename RejectedType>
-void ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::Reset() {
- ResetBase();
- resolved_ = ResolvedType();
- rejected_ = RejectedType();
- resolved_with_undefined_ = false;
-}
-
-template <typename HolderType, typename ResolvedType, typename RejectedType>
-void ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::Trace(
- Visitor* visitor) {
- TraceIfNeeded<HolderType>::Trace(visitor, holder_);
- TraceIfNeeded<ResolvedType>::Trace(visitor, resolved_);
- TraceIfNeeded<RejectedType>::Trace(visitor, rejected_);
- ScriptPromisePropertyBase::Trace(visitor);
-}
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_PROMISE_PROPERTY_H_
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_base.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_base.cc
deleted file mode 100644
index dc117d2bd9e..00000000000
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_base.cc
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright 2014 The Chromium 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/bindings/core/v8/script_promise_property_base.h"
-
-#include <memory>
-#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/platform/bindings/scoped_persistent.h"
-#include "third_party/blink/renderer/platform/bindings/script_state.h"
-
-namespace blink {
-
-ScriptPromisePropertyBase::ScriptPromisePropertyBase(
- ExecutionContext* execution_context,
- Name name)
- : ContextClient(execution_context),
- isolate_(execution_context->GetIsolate()),
- name_(name),
- state_(kPending) {}
-
-ScriptPromisePropertyBase::~ScriptPromisePropertyBase() {
- // TODO(haraken): Stop calling ClearWrappers here, as the dtor is invoked
- // during oilpan GC, but ClearWrappers potentially runs user script.
- ClearWrappers();
-}
-
-ScriptPromise ScriptPromisePropertyBase::Promise(DOMWrapperWorld& world) {
- if (!GetExecutionContext())
- return ScriptPromise();
-
- v8::HandleScope handle_scope(isolate_);
- v8::Local<v8::Context> context = ToV8Context(GetExecutionContext(), world);
- if (context.IsEmpty())
- return ScriptPromise();
- ScriptState* script_state = ScriptState::From(context);
- ScriptState::Scope scope(script_state);
-
- v8::Local<v8::Object> wrapper = EnsureHolderWrapper(script_state);
- DCHECK(wrapper->CreationContext() == context);
-
- v8::Local<v8::Value> cached_promise;
- if (PromiseSymbol().GetOrUndefined(wrapper).ToLocal(&cached_promise) &&
- cached_promise->IsPromise()) {
- return ScriptPromise(script_state, cached_promise);
- }
-
- // Create and cache the Promise
- v8::Local<v8::Promise::Resolver> resolver;
- if (!v8::Promise::Resolver::New(context).ToLocal(&resolver))
- return ScriptPromise();
- v8::Local<v8::Promise> promise = resolver->GetPromise();
- PromiseSymbol().Set(wrapper, promise);
-
- switch (state_) {
- case kPending:
- // Cache the resolver too
- ResolverSymbol().Set(wrapper, resolver);
- break;
- case kResolved:
- case kRejected:
- ResolveOrRejectInternal(resolver);
- break;
- }
-
- return ScriptPromise(script_state, promise);
-}
-
-void ScriptPromisePropertyBase::ResolveOrReject(State target_state) {
- DCHECK(GetExecutionContext());
- DCHECK_EQ(state_, kPending);
- DCHECK(target_state == kResolved || target_state == kRejected);
-
- state_ = target_state;
-
- v8::HandleScope handle_scope(isolate_);
- wtf_size_t i = 0;
- while (i < wrappers_.size()) {
- const std::unique_ptr<ScopedPersistent<v8::Object>>& persistent =
- wrappers_[i];
- if (persistent->IsEmpty()) {
- // wrapper has died.
- // Since v8 GC can run during the iteration and clear the reference,
- // we can't move this check out of the loop.
- wrappers_.EraseAt(i);
- continue;
- }
- v8::Local<v8::Object> wrapper = persistent->NewLocal(isolate_);
- ScriptState* script_state = ScriptState::From(wrapper->CreationContext());
- ScriptState::Scope scope(script_state);
-
- V8PrivateProperty::Symbol symbol = ResolverSymbol();
- DCHECK(symbol.HasValue(wrapper));
- v8::Local<v8::Value> resolver_value;
- if (!symbol.GetOrUndefined(wrapper).ToLocal(&resolver_value))
- return;
- symbol.DeleteProperty(wrapper);
- ResolveOrRejectInternal(
- v8::Local<v8::Promise::Resolver>::Cast(resolver_value));
- ++i;
- }
-}
-
-void ScriptPromisePropertyBase::ResetBase() {
- CheckThis();
- ClearWrappers();
- state_ = kPending;
-}
-
-void ScriptPromisePropertyBase::ResolveOrRejectInternal(
- v8::Local<v8::Promise::Resolver> resolver) {
- v8::Local<v8::Context> context = resolver->CreationContext();
- switch (state_) {
- case kPending:
- NOTREACHED();
- break;
- case kResolved:
- resolver->Resolve(context, ResolvedValue(isolate_, context->Global()))
- .ToChecked();
- break;
- case kRejected:
- resolver->Reject(context, RejectedValue(isolate_, context->Global()))
- .ToChecked();
- break;
- }
-}
-
-v8::Local<v8::Object> ScriptPromisePropertyBase::EnsureHolderWrapper(
- ScriptState* script_state) {
- v8::Local<v8::Context> context = script_state->GetContext();
- wtf_size_t i = 0;
- while (i < wrappers_.size()) {
- const std::unique_ptr<ScopedPersistent<v8::Object>>& persistent =
- wrappers_[i];
- if (persistent->IsEmpty()) {
- // wrapper has died.
- // Since v8 GC can run during the iteration and clear the reference,
- // we can't move this check out of the loop.
- wrappers_.EraseAt(i);
- continue;
- }
-
- v8::Local<v8::Object> wrapper = persistent->NewLocal(isolate_);
- if (wrapper->CreationContext() == context)
- return wrapper;
- ++i;
- }
- v8::Local<v8::Object> wrapper = Holder(isolate_, context->Global());
- std::unique_ptr<ScopedPersistent<v8::Object>> weak_persistent =
- std::make_unique<ScopedPersistent<v8::Object>>();
- weak_persistent->Set(isolate_, wrapper);
- weak_persistent->SetPhantom();
- wrappers_.push_back(std::move(weak_persistent));
- DCHECK(wrapper->CreationContext() == context);
- return wrapper;
-}
-
-void ScriptPromisePropertyBase::ClearWrappers() {
- CheckThis();
- CheckWrappers();
- v8::HandleScope handle_scope(isolate_);
- for (WeakPersistentSet::iterator i = wrappers_.begin(); i != wrappers_.end();
- ++i) {
- v8::Local<v8::Object> wrapper = (*i)->NewLocal(isolate_);
- if (!wrapper.IsEmpty()) {
- v8::Context::Scope scope(wrapper->CreationContext());
- // TODO(peria): Use deleteProperty() if http://crbug.com/v8/6227 is fixed.
-
- // Check whether the value has been set or not. Unfortunately, HasValue
- // cannot be used as it triggers regular ScriptForbiddenScope through V8
- // callbacks. GetOrUndefined avoids this because it does not enter a
- // proper scope in V8.
- v8::Local<v8::Value> cache;
- if (ResolverSymbol().GetOrUndefined(wrapper).ToLocal(&cache) &&
- !cache->IsUndefined()) {
- ResolverSymbol().Set(wrapper, v8::Undefined(isolate_));
- }
- if (PromiseSymbol().GetOrUndefined(wrapper).ToLocal(&cache) &&
- !cache->IsUndefined()) {
- PromiseSymbol().Set(wrapper, v8::Undefined(isolate_));
- }
- }
- }
- wrappers_.clear();
-}
-
-void ScriptPromisePropertyBase::CheckThis() {
- CHECK(this);
-}
-
-void ScriptPromisePropertyBase::CheckWrappers() {
- for (WeakPersistentSet::iterator i = wrappers_.begin(); i != wrappers_.end();
- ++i) {
- CHECK(*i);
- }
-}
-
-V8PrivateProperty::Symbol ScriptPromisePropertyBase::PromiseSymbol() {
- switch (name_) {
-#define P(Interface, Name) \
- case Name: \
- static const V8PrivateProperty::SymbolKey kPrivateProperty##Name##Promise; \
- return V8PrivateProperty::GetSymbol(isolate_, \
- kPrivateProperty##Name##Promise);
-
- SCRIPT_PROMISE_PROPERTIES(P)
-
-#undef P
- }
- NOTREACHED();
- return V8PrivateProperty::GetEmptySymbol();
-}
-
-V8PrivateProperty::Symbol ScriptPromisePropertyBase::ResolverSymbol() {
- switch (name_) {
-#define P(Interface, Name) \
- case Name: \
- static const V8PrivateProperty::SymbolKey \
- kPrivateProperty##Name##Resolver; \
- return V8PrivateProperty::GetSymbol(isolate_, \
- kPrivateProperty##Name##Resolver);
-
- SCRIPT_PROMISE_PROPERTIES(P)
-
-#undef P
- }
- NOTREACHED();
- return V8PrivateProperty::GetEmptySymbol();
-}
-
-void ScriptPromisePropertyBase::Trace(blink::Visitor* visitor) {
- ContextClient::Trace(visitor);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_base.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_base.h
deleted file mode 100644
index 11cb4eef85d..00000000000
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_base.h
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2014 The Chromium 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_BINDINGS_CORE_V8_SCRIPT_PROMISE_PROPERTY_BASE_H_
-#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_PROMISE_PROPERTY_BASE_H_
-
-#include <memory>
-
-#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/execution_context/context_lifecycle_observer.h"
-#include "third_party/blink/renderer/platform/bindings/scoped_persistent.h"
-#include "third_party/blink/renderer/platform/bindings/script_promise_properties.h"
-#include "third_party/blink/renderer/platform/bindings/v8_private_property.h"
-#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
-#include "v8/include/v8.h"
-
-namespace blink {
-
-class DOMWrapperWorld;
-class ExecutionContext;
-class ScriptState;
-
-// TODO(yhirano): Remove NOINLINE once we find the cause of crashes.
-class CORE_EXPORT ScriptPromisePropertyBase
- : public GarbageCollected<ScriptPromisePropertyBase>,
- public ContextClient {
- USING_GARBAGE_COLLECTED_MIXIN(ScriptPromisePropertyBase);
-
- public:
- virtual ~ScriptPromisePropertyBase();
-
- enum Name {
-#define P(Unused, Name) Name,
- SCRIPT_PROMISE_PROPERTIES(P)
-#undef P
- };
-
- enum State {
- kPending,
- kResolved,
- kRejected,
- };
- State GetState() const { return state_; }
-
- ScriptPromise Promise(DOMWrapperWorld&);
-
- void Trace(blink::Visitor*) override;
-
- protected:
- ScriptPromisePropertyBase(ExecutionContext*, Name);
-
- void ResolveOrReject(State target_state);
-
- // ScriptPromiseProperty overrides these to wrap the holder,
- // rejected value and resolved value. The
- // ScriptPromisePropertyBase caller will enter the V8Context for
- // the property's execution context and the world it is
- // creating/settling promises in; the implementation should use
- // this context.
- virtual v8::Local<v8::Object> Holder(
- v8::Isolate*,
- v8::Local<v8::Object> creation_context) = 0;
- virtual v8::Local<v8::Value> ResolvedValue(
- v8::Isolate*,
- v8::Local<v8::Object> creation_context) = 0;
- virtual v8::Local<v8::Value> RejectedValue(
- v8::Isolate*,
- v8::Local<v8::Object> creation_context) = 0;
-
- NOINLINE void ResetBase();
-
- private:
- typedef Vector<std::unique_ptr<ScopedPersistent<v8::Object>>>
- WeakPersistentSet;
-
- void ResolveOrRejectInternal(v8::Local<v8::Promise::Resolver>);
- v8::Local<v8::Object> EnsureHolderWrapper(ScriptState*);
- NOINLINE void ClearWrappers();
- // TODO(yhirano): Remove these functions once we find the cause of crashes.
- NOINLINE void CheckThis();
- NOINLINE void CheckWrappers();
-
- V8PrivateProperty::Symbol PromiseSymbol();
- V8PrivateProperty::Symbol ResolverSymbol();
-
- v8::Isolate* isolate_;
- Name name_;
- State state_;
-
- WeakPersistentSet wrappers_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_PROMISE_PROPERTY_BASE_H_
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 a64d5000304..c2dd607686e 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
@@ -76,22 +76,18 @@ class StubFunction : public ScriptFunction {
class GarbageCollectedHolder final : public GarbageCollectedScriptWrappable {
public:
typedef ScriptPromiseProperty<Member<GarbageCollectedScriptWrappable>,
- Member<GarbageCollectedScriptWrappable>,
Member<GarbageCollectedScriptWrappable>>
Property;
GarbageCollectedHolder(ExecutionContext* execution_context)
: GarbageCollectedScriptWrappable("holder"),
- property_(
- MakeGarbageCollected<Property>(execution_context,
- ToGarbageCollectedScriptWrappable(),
- Property::kReady)) {}
+ property_(MakeGarbageCollected<Property>(execution_context)) {}
Property* GetProperty() { return property_; }
GarbageCollectedScriptWrappable* ToGarbageCollectedScriptWrappable() {
return this;
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(property_);
GarbageCollectedScriptWrappable::Trace(visitor);
}
@@ -150,8 +146,8 @@ class ScriptPromisePropertyTestBase {
template <typename T>
ScriptValue Wrap(DOMWrapperWorld& world, const T& value) {
v8::HandleScope handle_scope(GetIsolate());
- ScriptState* script_state =
- ScriptState::From(ToV8Context(&GetDocument(), world));
+ ScriptState* script_state = ScriptState::From(
+ ToV8Context(GetDocument().ToExecutionContext(), world));
ScriptState::Scope scope(script_state);
return ScriptValue(
GetIsolate(),
@@ -173,7 +169,8 @@ class ScriptPromisePropertyGarbageCollectedTest
typedef GarbageCollectedHolder::Property Property;
ScriptPromisePropertyGarbageCollectedTest()
- : holder_(MakeGarbageCollected<GarbageCollectedHolder>(&GetDocument())) {}
+ : holder_(MakeGarbageCollected<GarbageCollectedHolder>(
+ GetDocument().ToExecutionContext())) {}
void ClearHolder() { holder_.Clear(); }
GarbageCollectedHolder* Holder() { return holder_; }
@@ -194,13 +191,9 @@ class ScriptPromisePropertyNonScriptWrappableResolutionTargetTest
public:
template <typename T>
void Test(const T& value, const char* expected, const char* file, int line) {
- typedef ScriptPromiseProperty<Member<GarbageCollectedScriptWrappable>, T,
- ToV8UndefinedGenerator>
- Property;
- Property* property = MakeGarbageCollected<Property>(
- &GetDocument(),
- MakeGarbageCollected<GarbageCollectedScriptWrappable>("holder"),
- Property::kReady);
+ typedef ScriptPromiseProperty<T, ToV8UndefinedGenerator> Property;
+ Property* property =
+ MakeGarbageCollected<Property>(GetDocument().ToExecutionContext());
size_t n_resolve_calls = 0;
ScriptValue actual_value;
String actual;
@@ -238,7 +231,7 @@ TEST_F(ScriptPromisePropertyGarbageCollectedTest,
{
ScriptState::Scope scope(MainScriptState());
EXPECT_EQ(v.V8Value().As<v8::Object>()->CreationContext(),
- ToV8Context(&GetDocument(), MainWorld()));
+ ToV8Context(GetDocument().ToExecutionContext(), MainWorld()));
}
EXPECT_EQ(Property::kPending, GetProperty()->GetState());
}
@@ -257,12 +250,12 @@ TEST_F(ScriptPromisePropertyGarbageCollectedTest,
{
ScriptState::Scope scope(OtherScriptState());
EXPECT_EQ(u.V8Value().As<v8::Object>()->CreationContext(),
- ToV8Context(&GetDocument(), OtherWorld()));
+ ToV8Context(GetDocument().ToExecutionContext(), OtherWorld()));
}
{
ScriptState::Scope scope(MainScriptState());
EXPECT_EQ(v.V8Value().As<v8::Object>()->CreationContext(),
- ToV8Context(&GetDocument(), MainWorld()));
+ ToV8Context(GetDocument().ToExecutionContext(), MainWorld()));
}
EXPECT_EQ(Property::kPending, GetProperty()->GetState());
}
@@ -283,12 +276,12 @@ TEST_F(ScriptPromisePropertyGarbageCollectedTest,
TEST_F(ScriptPromisePropertyGarbageCollectedTest,
Promise_DoesNotImpedeGarbageCollection) {
- ScriptValue holder_wrapper =
- Wrap(MainWorld(), Holder()->ToGarbageCollectedScriptWrappable());
-
Persistent<GCObservation> observation;
{
ScriptState::Scope scope(MainScriptState());
+ // Here we have a reference cylce between Holder() and the promise.
+ Holder()->GetProperty()->Resolve(Holder());
+
observation = MakeGarbageCollected<GCObservation>(
Promise(DOMWrapperWorld::MainWorld()).V8Value());
}
@@ -296,8 +289,8 @@ TEST_F(ScriptPromisePropertyGarbageCollectedTest,
Gc();
EXPECT_FALSE(observation->wasCollected());
- holder_wrapper.Clear();
ClearHolder();
+
Gc();
EXPECT_TRUE(observation->wasCollected());
}
@@ -478,12 +471,55 @@ TEST_F(ScriptPromisePropertyGarbageCollectedTest, Reset) {
v8::MicrotasksScope::PerformCheckpoint(GetIsolate());
EXPECT_EQ(1u, n_old_resolve_calls);
EXPECT_EQ(1u, n_new_reject_calls);
- EXPECT_NE(old_promise, new_promise);
+ // TODO(crbug.com/1029822): This EXPECT is failing on win-asan only. It's
+ // not clear how it could fail but all of the other expectations pass.
+ // EXPECT_NE(old_promise, new_promise);
EXPECT_EQ(Wrap(MainWorld(), old_value), old_actual);
EXPECT_EQ(Wrap(MainWorld(), new_value), new_actual);
EXPECT_NE(old_actual, new_actual);
}
+TEST_F(ScriptPromisePropertyGarbageCollectedTest, MarkAsHandled) {
+ {
+ // Unhandled promise.
+ ScriptState::Scope scope(MainScriptState());
+ ScriptPromise promise =
+ GetProperty()->Promise(DOMWrapperWorld::MainWorld());
+ GarbageCollectedScriptWrappable* reason =
+ MakeGarbageCollected<GarbageCollectedScriptWrappable>("reason");
+ GetProperty()->Reject(reason);
+ EXPECT_FALSE(promise.V8Value().As<v8::Promise>()->HasHandler());
+ }
+
+ GetProperty()->Reset();
+
+ {
+ // MarkAsHandled applies to newly created promises.
+ ScriptState::Scope scope(MainScriptState());
+ GetProperty()->MarkAsHandled();
+ ScriptPromise promise =
+ GetProperty()->Promise(DOMWrapperWorld::MainWorld());
+ GarbageCollectedScriptWrappable* reason =
+ MakeGarbageCollected<GarbageCollectedScriptWrappable>("reason");
+ GetProperty()->Reject(reason);
+ EXPECT_TRUE(promise.V8Value().As<v8::Promise>()->HasHandler());
+ }
+
+ GetProperty()->Reset();
+
+ {
+ // MarkAsHandled applies to previously vended promises.
+ ScriptState::Scope scope(MainScriptState());
+ ScriptPromise promise =
+ GetProperty()->Promise(DOMWrapperWorld::MainWorld());
+ GetProperty()->MarkAsHandled();
+ GarbageCollectedScriptWrappable* reason =
+ MakeGarbageCollected<GarbageCollectedScriptWrappable>("reason");
+ GetProperty()->Reject(reason);
+ EXPECT_TRUE(promise.V8Value().As<v8::Promise>()->HasHandler());
+ }
+}
+
TEST_F(ScriptPromisePropertyNonScriptWrappableResolutionTargetTest,
ResolveWithUndefined) {
Test(ToV8UndefinedGenerator(), "undefined", __FILE__, __LINE__);
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 835b86b9c93..eaadad2287b 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
@@ -17,7 +17,7 @@
namespace blink {
ScriptPromiseResolver::ScriptPromiseResolver(ScriptState* script_state)
- : ContextLifecycleObserver(ExecutionContext::From(script_state)),
+ : ExecutionContextLifecycleObserver(ExecutionContext::From(script_state)),
state_(kPending),
script_state_(script_state),
resolver_(script_state),
@@ -41,7 +41,7 @@ void ScriptPromiseResolver::Dispose() {
state_ == kDetached || !is_promise_called_ ||
!GetScriptState()->ContextIsValid() || !GetExecutionContext() ||
GetExecutionContext()->IsContextDestroyed();
- if (!is_properly_detached) {
+ if (!is_properly_detached && !suppress_detach_check_) {
// This is here to make it easier to track down which promise resolvers are
// being abandoned. See https://crbug.com/873980.
static crash_reporter::CrashKeyString<1024> trace_key(
@@ -54,8 +54,6 @@ void ScriptPromiseResolver::Dispose() {
}
#endif
deferred_resolve_task_.Cancel();
- resolver_.Clear();
- value_.Clear();
}
void ScriptPromiseResolver::Reject(ExceptionState& exception_state) {
@@ -118,11 +116,11 @@ void ScriptPromiseResolver::ResolveOrRejectDeferred() {
ResolveOrRejectImmediately();
}
-void ScriptPromiseResolver::Trace(blink::Visitor* visitor) {
+void ScriptPromiseResolver::Trace(Visitor* visitor) {
visitor->Trace(script_state_);
visitor->Trace(resolver_);
visitor->Trace(value_);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 929535af650..e9f6431d8b1 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
@@ -9,8 +9,8 @@
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/bindings/scoped_persistent.h"
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
@@ -29,7 +29,7 @@ namespace blink {
// functionalities.
// - A ScriptPromiseResolver retains a ScriptState. A caller
// can call resolve or reject from outside of a V8 context.
-// - This class is an ContextLifecycleObserver and keeps track of the
+// - This class is an ExecutionContextLifecycleObserver and keeps track of the
// associated ExecutionContext state. When it is stopped, resolve or reject
// will be ignored.
//
@@ -37,7 +37,7 @@ namespace blink {
// terminated). In such cases operations will silently fail.
class CORE_EXPORT ScriptPromiseResolver
: public GarbageCollected<ScriptPromiseResolver>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(ScriptPromiseResolver);
USING_PRE_FINALIZER(ScriptPromiseResolver, Dispose);
@@ -76,8 +76,8 @@ class CORE_EXPORT ScriptPromiseResolver
return resolver_.Promise();
}
- // ContextLifecycleObserver implementation.
- void ContextDestroyed(ExecutionContext*) override { Detach(); }
+ // ExecutionContextLifecycleObserver implementation.
+ void ContextDestroyed() override { Detach(); }
// Calling this function makes the resolver release its internal resources.
// That means the associated promise will never be resolved or rejected
@@ -85,11 +85,19 @@ class CORE_EXPORT ScriptPromiseResolver
// Do not call this function unless you truly need the behavior.
void Detach();
+ // Suppresses the check in Dispose. Do not use this function unless you truly
+ // need the behavior. Also consider using Detach().
+ void SuppressDetachCheck() {
+#if DCHECK_IS_ON()
+ suppress_detach_check_ = true;
+#endif
+ }
+
// Once this function is called this resolver stays alive while the
// promise is pending and the associated ExecutionContext isn't stopped.
void KeepAliveWhilePending();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
typedef ScriptPromise::InternalResolver Resolver;
@@ -157,6 +165,7 @@ class CORE_EXPORT ScriptPromiseResolver
#if DCHECK_IS_ON()
// True if promise() is called.
bool is_promise_called_ = false;
+ bool suppress_detach_check_ = false;
base::debug::StackTrace create_stack_trace_{8};
#endif
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 7d92626c7d8..aaf4f3e41a5 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
@@ -61,7 +61,7 @@ class ScriptPromiseResolverTest : public testing::Test {
return ToScriptStateForMainWorld(&page_holder_->GetFrame());
}
ExecutionContext* GetExecutionContext() const {
- return &page_holder_->GetDocument();
+ return page_holder_->GetDocument().ToExecutionContext();
}
v8::Isolate* GetIsolate() const { return GetScriptState()->GetIsolate(); }
};
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 afd83f83ae7..46148496dd4 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
@@ -104,7 +104,7 @@ ScriptSourceCode::ScriptSourceCode(const String& source,
ScriptSourceCode::~ScriptSourceCode() = default;
-void ScriptSourceCode::Trace(blink::Visitor* visitor) {
+void ScriptSourceCode::Trace(Visitor* visitor) {
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 8fe2bd4e487..eff28959c34 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
@@ -79,7 +79,7 @@ class CORE_EXPORT ScriptSourceCode final {
const KURL&);
~ScriptSourceCode();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
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 ced1a1bba80..248d559730e 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
@@ -501,8 +501,7 @@ bool ScriptStreamer::TryStartStreaming(
// they wait for more input.
// TODO(leszeks): Decrease the priority of these tasks where possible.
worker_pool::PostTask(
- FROM_HERE,
- {base::ThreadPool(), base::TaskPriority::USER_BLOCKING, base::MayBlock()},
+ FROM_HERE, {base::TaskPriority::USER_BLOCKING, base::MayBlock()},
CrossThreadBindOnce(RunScriptStreamingTask,
WTF::Passed(std::move(script_streaming_task)),
WrapCrossThreadPersistent(this),
@@ -554,7 +553,7 @@ void ScriptStreamer::Prefinalize() {
prefinalizer_called_ = true;
}
-void ScriptStreamer::Trace(blink::Visitor* visitor) {
+void ScriptStreamer::Trace(Visitor* visitor) {
visitor->Trace(script_resource_);
}
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 685112d599d..3818d966729 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
@@ -65,7 +65,7 @@ class CORE_EXPORT ScriptStreamer final
v8::ScriptCompiler::CompileOptions,
scoped_refptr<base::SingleThreadTaskRunner>);
~ScriptStreamer();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
// Create a script streamer which will stream the given ScriptResource into V8
// as it loads.
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 93db3b70169..50588ef4dbb 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
@@ -79,18 +79,30 @@ class NoopLoaderFactory final : public ResourceFetcher::LoaderFactory {
class NoopWebURLLoader final : public WebURLLoader {
public:
~NoopWebURLLoader() override = default;
- void LoadSynchronously(const WebURLRequest&,
- WebURLLoaderClient*,
- WebURLResponse&,
- base::Optional<WebURLError>&,
- WebData&,
- int64_t& encoded_data_length,
- int64_t& encoded_body_length,
- WebBlobInfo& downloaded_blob) override {
+ void LoadSynchronously(
+ std::unique_ptr<network::ResourceRequest> request,
+ scoped_refptr<WebURLRequest::ExtraData> request_extra_data,
+ int requestor_id,
+ bool download_to_network_cache_only,
+ bool pass_response_pipe_to_client,
+ bool no_mime_sniffing,
+ base::TimeDelta timeout_interval,
+ WebURLLoaderClient*,
+ WebURLResponse&,
+ base::Optional<WebURLError>&,
+ WebData&,
+ int64_t& encoded_data_length,
+ int64_t& encoded_body_length,
+ WebBlobInfo& downloaded_blob) override {
NOTREACHED();
}
- void LoadAsynchronously(const WebURLRequest&,
- WebURLLoaderClient*) override {}
+ void LoadAsynchronously(
+ std::unique_ptr<network::ResourceRequest> request,
+ scoped_refptr<WebURLRequest::ExtraData> request_extra_data,
+ int requestor_id,
+ bool download_to_network_cache_only,
+ bool no_mime_sniffing,
+ WebURLLoaderClient*) override {}
void SetDefersLoading(bool) override {}
void DidChangePriority(WebURLRequest::Priority, int) override {
NOTREACHED();
@@ -116,7 +128,7 @@ class ScriptStreamingTest : public testing::Test {
request.SetRequestContext(mojom::RequestContextType::SCRIPT);
resource_client_ = MakeGarbageCollected<TestResourceClient>();
- FetchParameters params(request);
+ FetchParameters params(std::move(request));
resource_ = ScriptResource::Fetch(params, fetcher, resource_client_,
ScriptResource::kAllowStreaming);
resource_->AddClient(resource_client_, loading_task_runner_.get());
@@ -196,8 +208,6 @@ class ScriptStreamingTest : public testing::Test {
// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
// currently unable to block and wait for the script streaming thread.
TEST_F(ScriptStreamingTest, DISABLED_CompilingStreamedScript) {
- return;
-
// Test that we can successfully compile a streamed script.
V8TestingScope scope;
resource_->StartStreaming(loading_task_runner_);
@@ -341,9 +351,9 @@ TEST_F(ScriptStreamingTest, DISABLED_SuppressingStreaming) {
SingleCachedMetadataHandler* cache_handler = resource_->CacheHandler();
EXPECT_TRUE(cache_handler);
+ cache_handler->DisableSendToPlatformForTesting();
cache_handler->SetCachedMetadata(V8CodeCache::TagForCodeCache(cache_handler),
- reinterpret_cast<const uint8_t*>("X"), 1,
- CachedMetadataHandler::kCacheLocally);
+ reinterpret_cast<const uint8_t*>("X"), 1);
AppendData("function foo() {");
AppendPadding();
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_value.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_value.cc
index ed52b29b0f2..ee44862eb50 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_value.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_value.cc
@@ -41,7 +41,7 @@ v8::Local<v8::Value> ScriptValue::V8Value() const {
return v8::Local<v8::Value>();
DCHECK(GetIsolate()->InContext());
- return value_->Get(ScriptState::From(isolate_->GetCurrentContext()));
+ return value_.Get(ScriptState::From(isolate_->GetCurrentContext()));
}
v8::Local<v8::Value> ScriptValue::V8ValueFor(
@@ -49,7 +49,7 @@ v8::Local<v8::Value> ScriptValue::V8ValueFor(
if (IsEmpty())
return v8::Local<v8::Value>();
- return value_->GetAcrossWorld(target_script_state);
+ return value_.GetAcrossWorld(target_script_state);
}
bool ScriptValue::ToString(String& result) const {
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 28bc1559763..6b828e17ba1 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
@@ -36,7 +36,6 @@
#include "third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
-#include "third_party/blink/renderer/platform/bindings/shared_persistent.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -72,18 +71,15 @@ class CORE_EXPORT ScriptValue final {
ScriptValue() = default;
ScriptValue(v8::Isolate* isolate, v8::Local<v8::Value> value)
- : isolate_(isolate),
- value_(SharedPersistent<v8::Value>::Create(isolate, value)) {
+ : isolate_(isolate), value_(isolate, value) {
DCHECK(isolate_);
}
template <typename T>
ScriptValue(v8::Isolate* isolate, v8::MaybeLocal<T> value)
: isolate_(isolate),
- value_(value.IsEmpty() ? nullptr
- : SharedPersistent<v8::Value>::Create(
- isolate,
- value.ToLocalChecked())) {
+ value_(isolate,
+ value.IsEmpty() ? v8::Local<T>() : value.ToLocalChecked()) {
DCHECK(isolate_);
}
@@ -103,7 +99,7 @@ class CORE_EXPORT ScriptValue final {
return value.IsEmpty();
if (value.IsEmpty())
return false;
- return *value_ == *value.value_;
+ return value_ == value.value_;
}
bool operator!=(const ScriptValue& value) const { return !operator==(value); }
@@ -140,11 +136,11 @@ class CORE_EXPORT ScriptValue final {
return !value.IsEmpty() && value->IsObject();
}
- bool IsEmpty() const { return !value_ || value_->IsEmpty(); }
+ bool IsEmpty() const { return value_.IsEmpty(); }
void Clear() {
isolate_ = nullptr;
- value_.reset();
+ value_.Reset();
}
v8::Local<v8::Value> V8Value() const;
@@ -157,12 +153,11 @@ class CORE_EXPORT ScriptValue final {
static ScriptValue CreateNull(v8::Isolate*);
- void Trace(Visitor* visitor) {}
+ void Trace(Visitor* visitor) { visitor->Trace(value_); }
private:
v8::Isolate* isolate_ = nullptr;
- // TODO(crbug.com/1029738): Use WorldSafeV8Reference once bug is fixed.
- scoped_refptr<SharedPersistent<v8::Value>> value_;
+ WorldSafeV8Reference<v8::Value> value_;
};
template <>
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_wrappable_v8_gc_integration_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_wrappable_v8_gc_integration_test.cc
index 3504c8ab487..28598580b25 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/script_wrappable_v8_gc_integration_test.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_wrappable_v8_gc_integration_test.cc
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h"
#include "third_party/blink/renderer/core/testing/death_aware_script_wrappable.h"
#include "third_party/blink/renderer/core/testing/gc_object_liveness_observer.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "v8/include/v8.h"
namespace blink {
@@ -31,7 +32,7 @@ TEST_F(ScriptWrappableV8GCIntegrationTest, V8ReportsLiveObjectsDuringFullGc) {
GCObjectLivenessObserver<DeathAwareScriptWrappable> observer;
{
v8::HandleScope handle_scope(GetIsolate());
- DeathAwareScriptWrappable* object = DeathAwareScriptWrappable::Create();
+ auto* object = MakeGarbageCollected<DeathAwareScriptWrappable>();
observer.Observe(object);
holder.Reset(GetIsolate(),
@@ -52,7 +53,7 @@ TEST_F(ScriptWrappableV8GCIntegrationTest,
GCObjectLivenessObserver<DeathAwareScriptWrappable> observer;
{
v8::HandleScope handle_scope(GetIsolate());
- DeathAwareScriptWrappable* object = DeathAwareScriptWrappable::Create();
+ auto* object = MakeGarbageCollected<DeathAwareScriptWrappable>();
observer.Observe(object);
v8::Local<v8::Value> wrapper =
@@ -85,7 +86,7 @@ TEST_F(ScriptWrappableV8GCIntegrationTest,
GCObjectLivenessObserver<DeathAwareScriptWrappable> observer;
{
v8::HandleScope handle_scope(GetIsolate());
- DeathAwareScriptWrappable* object = DeathAwareScriptWrappable::Create();
+ auto* object = MakeGarbageCollected<DeathAwareScriptWrappable>();
observer.Observe(object);
// Creates new V8 wrapper and associates it with global scope
@@ -109,7 +110,7 @@ TEST_F(ScriptWrappableV8GCIntegrationTest,
GCObjectLivenessObserver<DeathAwareScriptWrappable> observer;
{
v8::HandleScope handle_scope(GetIsolate());
- DeathAwareScriptWrappable* object = DeathAwareScriptWrappable::Create();
+ auto* object = MakeGarbageCollected<DeathAwareScriptWrappable>();
observer.Observe(object);
// Creates new V8 wrapper and associates it with global scope
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.cc b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.cc
index 0bc4266c16e..c45b8129c59 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.cc
@@ -6,12 +6,12 @@
#include "third_party/blink/public/mojom/messaging/user_activation_snapshot.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_post_message_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_window_post_message_options.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/frame.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
-#include "third_party/blink/renderer/core/frame/window_post_message_options.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
-#include "third_party/blink/renderer/core/messaging/post_message_options.h"
namespace blink {
@@ -96,7 +96,7 @@ PostMessageHelper::CreateUserActivationSnapshot(
if (LocalDOMWindow* dom_window = execution_context->ExecutingWindow()) {
if (LocalFrame* frame = dom_window->GetFrame()) {
return mojom::blink::UserActivationSnapshot::New(
- frame->HasBeenActivated(),
+ frame->HasStickyUserActivation(),
LocalFrame::HasTransientUserActivation(frame));
}
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h
index e021b8ea53a..a0eaa09214d 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h
@@ -102,15 +102,16 @@ enum SerializationTag {
// namedCurve:uint32_t
kRTCCertificateTag = 'k', // length:uint32_t, pemPrivateKey:WebCoreString,
// pemCertificate:WebCoreString
- kDetectedBarcodeTag =
- 'B', // raw_value:WebCoreString, bounding_box:DOMRectReadOnly,
- // format:String, corner_points:Point2D[length] ->
- // DetectedBarcode (ref)
- kDetectedFaceTag =
- 'F', // raw_value:WebCoreString, bounding_box:DOMRectReadOnly,
- // corner_points:Point2D[length] -> DetectedText (ref)
- kDetectedTextTag = 't', // bounding_box:DOMRectReadOnly,
- // landmarks:Landmark[length] -> DetectedFace (ref)
+ kRTCEncodedAudioFrameTag = 'A', // uint32_t -> transferred audio frame ID
+ kRTCEncodedVideoFrameTag = 'V', // uint32_t -> transferred video frame ID
+
+ // The following tags were used by the Shape Detection API implementation
+ // between M71 and M81. During these milestones, the API was always behind
+ // a flag. Usage was removed in https://crrev.com/c/2040378.
+ kDeprecatedDetectedBarcodeTag = 'B',
+ kDeprecatedDetectedFaceTag = 'F',
+ kDeprecatedDetectedTextTag = 't',
+
kDOMExceptionTag = 'x', // name:String,message:String,stack:String
kVersionTag = 0xFF // version:uint32_t -> Uses this as the file version.
};
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 d4ff2e3966c..ce665a4a177 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
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_color_params.h"
+#include "build/build_config.h"
+
namespace blink {
SerializedColorParams::SerializedColorParams()
@@ -27,18 +29,17 @@ SerializedColorParams::SerializedColorParams(CanvasColorParams color_params) {
color_space_ = SerializedColorSpace::kP3;
break;
}
- // todo(crbug/1021986) remove force_rgba in canvasColorParams
- if (color_params.GetForceRGBA() == CanvasForceRGBA::kForced) {
- pixel_format_ = SerializedPixelFormat::kForceRGBA8;
- } else {
- switch (color_params.PixelFormat()) {
- case CanvasPixelFormat::kRGBA8:
- pixel_format_ = SerializedPixelFormat::kRGBA8;
- break;
- case CanvasPixelFormat::kF16:
- pixel_format_ = SerializedPixelFormat::kF16;
- break;
- }
+
+ switch (color_params.PixelFormat()) {
+ case CanvasPixelFormat::kRGBA8:
+ pixel_format_ = SerializedPixelFormat::kRGBA8;
+ break;
+ case CanvasPixelFormat::kBGRA8:
+ pixel_format_ = SerializedPixelFormat::kBGRA8;
+ break;
+ case CanvasPixelFormat::kF16:
+ pixel_format_ = SerializedPixelFormat::kF16;
+ break;
}
opacity_mode_ = SerializedOpacityMode::kNonOpaque;
@@ -93,22 +94,31 @@ CanvasColorParams SerializedColorParams::GetCanvasColorParams() const {
break;
}
- // todo(crbug/1021986) remove force_rgba in canvasColorParams
- CanvasForceRGBA force_rgba = CanvasForceRGBA::kNotForced;
CanvasPixelFormat pixel_format = CanvasPixelFormat::kRGBA8;
- if (pixel_format_ == SerializedPixelFormat::kForceRGBA8) {
- force_rgba = CanvasForceRGBA::kForced;
- } else if (pixel_format_ == SerializedPixelFormat::kF16) {
- pixel_format = CanvasPixelFormat::kF16;
- } else if (pixel_format_ == SerializedPixelFormat::kRGBA8) {
- pixel_format = CanvasPixelFormat::kRGBA8;
+ switch (pixel_format_) {
+ case SerializedPixelFormat::kNative8_LegacyObsolete:
+#if defined(OS_ANDROID)
+ pixel_format = CanvasPixelFormat::kRGBA8;
+#else
+ pixel_format = CanvasPixelFormat::kBGRA8;
+#endif
+ break;
+ case SerializedPixelFormat::kRGBA8:
+ pixel_format = CanvasPixelFormat::kRGBA8;
+ break;
+ case SerializedPixelFormat::kBGRA8:
+ pixel_format = CanvasPixelFormat::kBGRA8;
+ break;
+ case SerializedPixelFormat::kF16:
+ pixel_format = CanvasPixelFormat::kF16;
+ break;
}
blink::OpacityMode opacity_mode = blink::kNonOpaque;
if (opacity_mode_ == SerializedOpacityMode::kOpaque)
opacity_mode = blink::kOpaque;
- return CanvasColorParams(color_space, pixel_format, opacity_mode, force_rgba);
+ return CanvasColorParams(color_space, pixel_format, opacity_mode);
}
CanvasColorSpace SerializedColorParams::GetColorSpace() const {
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 8820a9d8520..4c47c3af96a 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
@@ -46,13 +46,15 @@ enum class SerializedColorSpace : uint32_t {
};
// This enumeration specifies the values used to serialize CanvasPixelFormat.
-// todo(crbug/1021986) remove force_rgba in canvasColorParams and better reflect
-// logic of BGRA vs RGBA
enum class SerializedPixelFormat : uint32_t {
- kRGBA8 = 0,
+ // This is to preserve legacy object when Native was a possible enum state
+ // this will be resolved as either a RGB or BGR pixel format for
+ // canvas_color_params
+ kNative8_LegacyObsolete = 0,
kF16 = 1,
- kForceRGBA8 = 2,
- kLast = kForceRGBA8,
+ kRGBA8 = 2,
+ kBGRA8 = 3,
+ kLast = kBGRA8,
};
// This enumeration specifies the values used to serialize
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc
index c45aa72eb87..93ba68f8b2a 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc
@@ -532,6 +532,9 @@ bool SerializedScriptValue::ExtractTransferables(
ExceptionState& exception_state) {
// Validate the passed array of transferables.
wtf_size_t i = 0;
+ bool transferable_streams_enabled =
+ RuntimeEnabledFeatures::TransferableStreamsEnabled(
+ CurrentExecutionContext(isolate));
for (const auto& script_value : object_sequence) {
v8::Local<v8::Value> transferable_object = script_value.V8Value();
// Validation of non-null objects, per HTML5 spec 10.3.3.
@@ -611,7 +614,7 @@ bool SerializedScriptValue::ExtractTransferables(
return false;
}
transferables.offscreen_canvases.push_back(offscreen_canvas);
- } else if (RuntimeEnabledFeatures::TransferableStreamsEnabled() &&
+ } else if (transferable_streams_enabled &&
V8ReadableStream::HasInstance(transferable_object, isolate)) {
ReadableStream* stream = V8ReadableStream::ToImpl(
v8::Local<v8::Object>::Cast(transferable_object));
@@ -623,7 +626,7 @@ bool SerializedScriptValue::ExtractTransferables(
return false;
}
transferables.readable_streams.push_back(stream);
- } else if (RuntimeEnabledFeatures::TransferableStreamsEnabled() &&
+ } else if (transferable_streams_enabled &&
V8WritableStream::HasInstance(transferable_object, isolate)) {
WritableStream* stream = V8WritableStream::ToImpl(
v8::Local<v8::Object>::Cast(transferable_object));
@@ -635,7 +638,7 @@ bool SerializedScriptValue::ExtractTransferables(
return false;
}
transferables.writable_streams.push_back(stream);
- } else if (RuntimeEnabledFeatures::TransferableStreamsEnabled() &&
+ } else if (transferable_streams_enabled &&
V8TransformStream::HasInstance(transferable_object, isolate)) {
TransformStream* stream = V8TransformStream::ToImpl(
v8::Local<v8::Object>::Cast(transferable_object));
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h
index 419739f8d27..bbf10ef3135 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h
@@ -97,6 +97,7 @@ class CORE_EXPORT SerializedScriptValue
// Version 18: Add a list of key-value pairs for ImageBitmap and ImageData to
// support color space information, compression, etc.
// Version 19: Add DetectedBarcode, DetectedFace, and DetectedText support.
+ // Version 20: Remove DetectedBarcode, DetectedFace, and DetectedText support.
//
// The following versions cannot be used, in order to be able to
// deserialize version 0 SSVs. The class implementation has details.
@@ -109,7 +110,7 @@ class CORE_EXPORT SerializedScriptValue
//
// Recent changes are routinely reverted in preparation for branch, and this
// has been the cause of at least one bug in the past.
- static constexpr uint32_t kWireFormatVersion = 19;
+ static constexpr uint32_t kWireFormatVersion = 20;
// This enumeration specifies whether we're serializing a value for storage;
// e.g. when writing to IndexedDB. This corresponds to the forStorage flag of
@@ -176,7 +177,6 @@ class CORE_EXPORT SerializedScriptValue
public:
MessagePortArray* message_ports = nullptr;
const WebBlobInfoArray* blob_info = nullptr;
- bool read_wasm_from_stream = false;
};
v8::Local<v8::Value> Deserialize(v8::Isolate* isolate) {
return Deserialize(isolate, DeserializeOptions());
@@ -269,13 +269,41 @@ class CORE_EXPORT SerializedScriptValue
bool IsLockedToAgentCluster() const {
return !wasm_modules_.IsEmpty() ||
- !shared_array_buffers_contents_.IsEmpty();
+ !shared_array_buffers_contents_.IsEmpty() ||
+ std::any_of(attachments_.begin(), attachments_.end(),
+ [](const auto& entry) {
+ return entry.value->IsLockedToAgentCluster();
+ });
}
// Returns true after serializing script values that remote origins cannot
// access.
bool IsOriginCheckRequired() const;
+ // Derive from Attachments to define collections of objects to serialize in
+ // modules. They can be registered using GetOrCreateAttachment().
+ class Attachment {
+ public:
+ virtual ~Attachment() = default;
+ virtual bool IsLockedToAgentCluster() const = 0;
+ };
+
+ template <typename T>
+ T* GetOrCreateAttachment() {
+ auto result = attachments_.insert(&T::kAttachmentKey, std::unique_ptr<T>());
+ if (!result.stored_value->value)
+ result.stored_value->value = std::make_unique<T>();
+ return static_cast<T*>(result.stored_value->value.get());
+ }
+
+ template <typename T>
+ const T* GetAttachmentIfExists() const {
+ auto it = attachments_.find(&T::kAttachmentKey);
+ if (it == attachments_.end())
+ return nullptr;
+ return static_cast<T*>(it->value.get());
+ }
+
private:
friend class ScriptValueSerializer;
friend class V8ScriptValueSerializer;
@@ -325,6 +353,7 @@ class CORE_EXPORT SerializedScriptValue
MessagePort* AddStreamChannel(ExecutionContext*);
void CloneSharedArrayBuffers(SharedArrayBufferArray&);
+
DataBufferPtr data_buffer_;
size_t data_buffer_size_ = 0;
@@ -343,6 +372,7 @@ class CORE_EXPORT SerializedScriptValue
MojoScopedHandleArray mojo_handles_;
SharedArrayBufferContentsArray shared_array_buffers_contents_;
NativeFileSystemTokensArray native_file_system_tokens_;
+ HashMap<const void* const*, std::unique_ptr<Attachment>> attachments_;
bool has_registered_external_allocation_;
#if DCHECK_IS_ON()
@@ -350,19 +380,6 @@ class CORE_EXPORT SerializedScriptValue
#endif
};
-template <>
-struct NativeValueTraits<SerializedScriptValue>
- : public NativeValueTraitsBase<SerializedScriptValue> {
- CORE_EXPORT static inline scoped_refptr<SerializedScriptValue> NativeValue(
- v8::Isolate* isolate,
- v8::Local<v8::Value> value,
- const SerializedScriptValue::SerializeOptions& options,
- ExceptionState& exception_state) {
- return SerializedScriptValue::Serialize(isolate, value, options,
- exception_state);
- }
-};
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SERIALIZATION_SERIALIZED_SCRIPT_VALUE_H_
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_fuzzer.cc b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_fuzzer.cc
index 6cb85e3657d..f18c3de4708 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_fuzzer.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_fuzzer.cc
@@ -10,6 +10,7 @@
#include "base/numerics/safe_conversions.h"
#include "build/build_config.h"
+#include "testing/libfuzzer/libfuzzer_exports.h"
#include "third_party/blink/public/platform/web_blob_info.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/core/frame/settings.h"
@@ -47,9 +48,8 @@ int LLVMFuzzerInitialize(int* argc, char*** argv) {
g_blob_info_array = new WebBlobInfoArray();
g_blob_info_array->emplace_back(WebBlobInfo::BlobForTesting(
"d875dfc2-4505-461b-98fe-0cf6cc5eaf44", "text/plain", 12));
- g_blob_info_array->emplace_back(
- WebBlobInfo::FileForTesting("d875dfc2-4505-461b-98fe-0cf6cc5eaf44",
- "/native/path", "path", "text/plain"));
+ g_blob_info_array->emplace_back(WebBlobInfo::FileForTesting(
+ "d875dfc2-4505-461b-98fe-0cf6cc5eaf44", "path", "text/plain"));
return 0;
}
@@ -71,8 +71,8 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t data_size) {
if (hash & kFuzzMessagePorts) {
MessagePortArray* message_ports = MakeGarbageCollected<MessagePortArray>(3);
std::generate(message_ports->begin(), message_ports->end(), []() {
- auto* port =
- MakeGarbageCollected<MessagePort>(g_page_holder->GetDocument());
+ auto* port = MakeGarbageCollected<MessagePort>(
+ *g_page_holder->GetDocument().ToExecutionContext());
port->Entangle(mojo::MessagePipe().handle0);
return port;
});
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 2582bba8e27..a565ca00aee 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
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
@@ -33,18 +34,18 @@ UnpackedSerializedScriptValue::UnpackedSerializedScriptValue(
auto& image_bitmap_contents = value_->image_bitmap_contents_array_;
if (!image_bitmap_contents.IsEmpty()) {
image_bitmaps_.Grow(image_bitmap_contents.size());
- std::transform(image_bitmap_contents.begin(), image_bitmap_contents.end(),
- image_bitmaps_.begin(),
- [](scoped_refptr<StaticBitmapImage>& contents) {
- return ImageBitmap::Create(std::move(contents));
- });
+ std::transform(
+ image_bitmap_contents.begin(), image_bitmap_contents.end(),
+ image_bitmaps_.begin(), [](scoped_refptr<StaticBitmapImage>& contents) {
+ return MakeGarbageCollected<ImageBitmap>(std::move(contents));
+ });
image_bitmap_contents.clear();
}
}
UnpackedSerializedScriptValue::~UnpackedSerializedScriptValue() = default;
-void UnpackedSerializedScriptValue::Trace(blink::Visitor* visitor) {
+void UnpackedSerializedScriptValue::Trace(Visitor* visitor) {
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 cb97edb5ea9..9037cde7088 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(blink::Visitor*);
+ void Trace(Visitor*);
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_deserializer.cc b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc
index d08e5e12300..c4550b57592 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc
@@ -10,6 +10,7 @@
#include "third_party/blink/public/platform/web_blob_info.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_point_init.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/fileapi/blob.h"
@@ -18,7 +19,6 @@
#include "third_party/blink/renderer/core/geometry/dom_matrix.h"
#include "third_party/blink/renderer/core/geometry/dom_matrix_read_only.h"
#include "third_party/blink/renderer/core/geometry/dom_point.h"
-#include "third_party/blink/renderer/core/geometry/dom_point_init.h"
#include "third_party/blink/renderer/core/geometry/dom_point_read_only.h"
#include "third_party/blink/renderer/core/geometry/dom_quad.h"
#include "third_party/blink/renderer/core/geometry/dom_rect.h"
@@ -133,7 +133,6 @@ V8ScriptValueDeserializer::V8ScriptValueDeserializer(
transferred_message_ports_(options.message_ports),
blob_info_array_(options.blob_info) {
deserializer_.SetSupportsLegacyWireFormat(true);
- deserializer_.SetExpectInlineWasm(options.read_wasm_from_stream);
}
v8::Local<v8::Value> V8ScriptValueDeserializer::Deserialize() {
@@ -178,7 +177,7 @@ v8::Local<v8::Value> V8ScriptValueDeserializer::Deserialize() {
}
void V8ScriptValueDeserializer::Transfer() {
- if (RuntimeEnabledFeatures::TransferableStreamsEnabled()) {
+ if (TransferableStreamsEnabled()) {
// TODO(ricea): Make ExtendableMessageEvent store an
// UnpackedSerializedScriptValue like MessageEvent does, and then this
// special case won't be necessary.
@@ -221,7 +220,10 @@ bool V8ScriptValueDeserializer::ReadUTF8String(String* string) {
return false;
*string =
String::FromUTF8(reinterpret_cast<const LChar*>(utf8_data), utf8_length);
- return true;
+
+ // Decoding must have failed; this encoding does not distinguish between null
+ // and empty strings.
+ return !string->IsNull();
}
ScriptWrappable* V8ScriptValueDeserializer::ReadDOMObject(
@@ -293,7 +295,8 @@ ScriptWrappable* V8ScriptValueDeserializer::ReadDOMObject(
}
case kImageBitmapTag: {
SerializedColorSpace canvas_color_space = SerializedColorSpace::kSRGB;
- SerializedPixelFormat canvas_pixel_format = SerializedPixelFormat::kRGBA8;
+ SerializedPixelFormat canvas_pixel_format =
+ SerializedPixelFormat::kNative8_LegacyObsolete;
SerializedOpacityMode canvas_opacity_mode =
SerializedOpacityMode::kOpaque;
uint32_t origin_clean = 0, is_premultiplied = 0, width = 0, height = 0,
@@ -358,8 +361,8 @@ ScriptWrappable* V8ScriptValueDeserializer::ReadDOMObject(
// been deprecated.
return nullptr;
}
- return ImageBitmap::Create(pixels, width, height, is_premultiplied,
- origin_clean, color_params);
+ return MakeGarbageCollected<ImageBitmap>(
+ pixels, width, height, is_premultiplied, origin_clean, color_params);
}
case kImageBitmapTransferTag: {
uint32_t index = 0;
@@ -415,7 +418,7 @@ ScriptWrappable* V8ScriptValueDeserializer::ReadDOMObject(
}
SerializedColorParams color_params(
- canvas_color_space, SerializedPixelFormat::kRGBA8,
+ canvas_color_space, SerializedPixelFormat::kNative8_LegacyObsolete,
SerializedOpacityMode::kNonOpaque, image_data_storage_format);
ImageDataStorageFormat storage_format = color_params.GetStorageFormat();
base::CheckedNumeric<size_t> computed_byte_length = width;
@@ -543,7 +546,7 @@ ScriptWrappable* V8ScriptValueDeserializer::ReadDOMObject(
return canvas;
}
case kReadableStreamTransferTag: {
- if (!RuntimeEnabledFeatures::TransferableStreamsEnabled())
+ if (!TransferableStreamsEnabled())
return nullptr;
uint32_t index = 0;
if (!ReadUint32(&index) || !transferred_stream_ports_ ||
@@ -555,7 +558,7 @@ ScriptWrappable* V8ScriptValueDeserializer::ReadDOMObject(
exception_state);
}
case kWritableStreamTransferTag: {
- if (!RuntimeEnabledFeatures::TransferableStreamsEnabled())
+ if (!TransferableStreamsEnabled())
return nullptr;
uint32_t index = 0;
if (!ReadUint32(&index) || !transferred_stream_ports_ ||
@@ -567,7 +570,7 @@ ScriptWrappable* V8ScriptValueDeserializer::ReadDOMObject(
exception_state);
}
case kTransformStreamTransferTag: {
- if (!RuntimeEnabledFeatures::TransferableStreamsEnabled())
+ if (!TransferableStreamsEnabled())
return nullptr;
uint32_t index = 0;
if (!ReadUint32(&index) || !transferred_stream_ports_ ||
@@ -595,7 +598,8 @@ ScriptWrappable* V8ScriptValueDeserializer::ReadDOMObject(
!ReadUTF8String(&stack_unused)) {
return nullptr;
}
- return DOMException::Create(name, message);
+ // DOMException::Create takes its arguments in the opposite order.
+ return DOMException::Create(message, name);
}
default:
break;
@@ -652,9 +656,8 @@ File* V8ScriptValueDeserializer::ReadFileIndex() {
}
if (!blob_handle)
return nullptr;
- return File::CreateFromIndexedSerialization(info.FilePath(), info.FileName(),
- info.size(), info.LastModified(),
- blob_handle);
+ return File::CreateFromIndexedSerialization(info.FileName(), info.size(),
+ info.LastModified(), blob_handle);
}
DOMRectReadOnly* V8ScriptValueDeserializer::ReadDOMRectReadOnly() {
@@ -754,4 +757,10 @@ V8ScriptValueDeserializer::GetSharedArrayBufferFromId(v8::Isolate* isolate,
CHECK(shared_array_buffers_contents.IsEmpty());
return v8::MaybeLocal<v8::SharedArrayBuffer>();
}
+
+bool V8ScriptValueDeserializer::TransferableStreamsEnabled() const {
+ return RuntimeEnabledFeatures::TransferableStreamsEnabled(
+ ExecutionContext::From(script_state_));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.h b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.h
index af515f10808..cf8af825cb8 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.h
@@ -109,15 +109,17 @@ class CORE_EXPORT V8ScriptValueDeserializer
v8::Isolate*,
uint32_t) override;
- Member<ScriptState> script_state_;
- Member<UnpackedSerializedScriptValue> unpacked_value_;
+ bool TransferableStreamsEnabled() const;
+
+ ScriptState* script_state_;
+ UnpackedSerializedScriptValue* unpacked_value_;
scoped_refptr<SerializedScriptValue> serialized_script_value_;
v8::ValueDeserializer deserializer_;
// Message ports which were transferred in.
const MessagePortArray* transferred_message_ports_ = nullptr;
- Member<MessagePortArray> transferred_stream_ports_;
+ MessagePortArray* transferred_stream_ports_ = nullptr;
// Blob info for blobs stored by index.
const WebBlobInfoArray* blob_info_array_ = nullptr;
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 23bfce951fd..91fd8252151 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
@@ -185,7 +185,7 @@ void V8ScriptValueSerializer::FinalizeTransfer(
if (exception_state.HadException())
return;
- if (RuntimeEnabledFeatures::TransferableStreamsEnabled()) {
+ if (TransferableStreamsEnabled()) {
// Order matters here, because the order in which streams are added to the
// |stream_ports_| array must match the indexes which are calculated in
// WriteDOMObject().
@@ -261,7 +261,7 @@ bool V8ScriptValueSerializer::WriteDOMObject(ScriptWrappable* wrappable,
return false;
}
- auto* execution_context = ExecutionContext::From(script_state_.Get());
+ auto* execution_context = ExecutionContext::From(script_state_);
// If this ImageBitmap was transferred, it can be serialized by index.
size_t index = kNotFound;
if (transferables_)
@@ -520,7 +520,7 @@ bool V8ScriptValueSerializer::WriteDOMObject(ScriptWrappable* wrappable,
return true;
}
if (wrapper_type_info == V8ReadableStream::GetWrapperTypeInfo() &&
- RuntimeEnabledFeatures::TransferableStreamsEnabled()) {
+ TransferableStreamsEnabled()) {
ReadableStream* stream = wrappable->ToImpl<ReadableStream>();
size_t index = kNotFound;
if (transferables_)
@@ -544,7 +544,7 @@ bool V8ScriptValueSerializer::WriteDOMObject(ScriptWrappable* wrappable,
return true;
}
if (wrapper_type_info == V8WritableStream::GetWrapperTypeInfo() &&
- RuntimeEnabledFeatures::TransferableStreamsEnabled()) {
+ TransferableStreamsEnabled()) {
WritableStream* stream = wrappable->ToImpl<WritableStream>();
size_t index = kNotFound;
if (transferables_)
@@ -573,7 +573,7 @@ bool V8ScriptValueSerializer::WriteDOMObject(ScriptWrappable* wrappable,
return true;
}
if (wrapper_type_info == V8TransformStream::GetWrapperTypeInfo() &&
- RuntimeEnabledFeatures::TransferableStreamsEnabled()) {
+ TransferableStreamsEnabled()) {
TransformStream* stream = wrappable->ToImpl<TransformStream>();
size_t index = kNotFound;
if (transferables_)
@@ -628,12 +628,9 @@ bool V8ScriptValueSerializer::WriteFile(File* file,
if (blob_info_array_) {
size_t index = blob_info_array_->size();
DCHECK_LE(index, std::numeric_limits<uint32_t>::max());
- uint64_t size;
- base::Optional<base::Time> last_modified_time;
- file->CaptureSnapshot(size, last_modified_time);
- blob_info_array_->emplace_back(file->GetBlobDataHandle(), file->GetPath(),
- file->name(), file->type(),
- last_modified_time, size);
+ blob_info_array_->emplace_back(
+ file->GetBlobDataHandle(), file->name(), file->type(),
+ file->LastModifiedTimeForSerialization(), file->size());
WriteUint32(static_cast<uint32_t>(index));
} else {
WriteUTF8String(file->HasBackingFile() ? file->GetPath() : g_empty_string);
@@ -641,20 +638,15 @@ bool V8ScriptValueSerializer::WriteFile(File* file,
WriteUTF8String(file->webkitRelativePath());
WriteUTF8String(file->Uuid());
WriteUTF8String(file->type());
- // TODO(jsbell): metadata is unconditionally captured in the index case.
- // Why this inconsistency?
- if (file->HasValidSnapshotMetadata()) {
- WriteUint32(1);
- uint64_t size;
- base::Optional<base::Time> last_modified;
- file->CaptureSnapshot(size, last_modified);
- DCHECK_NE(size, std::numeric_limits<uint64_t>::max());
- WriteUint64(size);
- WriteDouble(last_modified ? last_modified->ToJsTimeIgnoringNull()
- : std::numeric_limits<double>::quiet_NaN());
- } else {
- WriteUint32(0);
- }
+ // Historically we sometimes wouldn't write metadata. This next integer was
+ // 1 or 0 to indicate if metadata is present. Now we always write metadata,
+ // hence always have this hardcoded 1.
+ WriteUint32(1);
+ WriteUint64(file->size());
+ base::Optional<base::Time> last_modified =
+ file->LastModifiedTimeForSerialization();
+ WriteDouble(last_modified ? last_modified->ToJsTimeIgnoringNull()
+ : std::numeric_limits<double>::quiet_NaN());
WriteUint32(file->GetUserVisibility() == File::kIsUserVisible ? 1 : 0);
}
return true;
@@ -790,4 +782,9 @@ void V8ScriptValueSerializer::FreeBufferMemory(void* buffer) {
return WTF::Partitions::BufferFree(buffer);
}
+bool V8ScriptValueSerializer::TransferableStreamsEnabled() const {
+ return RuntimeEnabledFeatures::TransferableStreamsEnabled(
+ ExecutionContext::From(script_state_));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.h b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.h
index cd57afeda3b..ab73504600c 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.h
@@ -47,6 +47,8 @@ class CORE_EXPORT V8ScriptValueSerializer
// DataCloneError message will be used.
virtual bool WriteDOMObject(ScriptWrappable*, ExceptionState&);
+ ScriptState* GetScriptState() const { return script_state_; }
+
void WriteTag(SerializationTag tag) {
uint8_t tag_byte = tag;
serializer_.WriteRawBytes(&tag_byte, 1);
@@ -106,7 +108,9 @@ class CORE_EXPORT V8ScriptValueSerializer
size_t* actual_size) override;
void FreeBufferMemory(void* buffer) override;
- Member<ScriptState> script_state_;
+ bool TransferableStreamsEnabled() const;
+
+ ScriptState* script_state_;
scoped_refptr<SerializedScriptValue> serialized_script_value_;
v8::ValueSerializer serializer_;
const Transferables* transferables_ = nullptr;
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 7308bc6ea16..9186a63377d 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
@@ -17,6 +17,7 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_blob.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_dom_matrix.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_init.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_read_only.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_dom_point.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_dom_point_init.h"
@@ -1015,7 +1016,7 @@ TEST(V8ScriptValueSerializerTest, RoundTripImageBitmap) {
// Make a 10x7 red ImageBitmap.
sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(10, 7);
surface->getCanvas()->clear(SK_ColorRED);
- ImageBitmap* image_bitmap = ImageBitmap::Create(
+ auto* image_bitmap = MakeGarbageCollected<ImageBitmap>(
UnacceleratedStaticBitmapImage::Create(surface->makeImageSnapshot()));
ASSERT_TRUE(image_bitmap->BitmapImage());
@@ -1047,7 +1048,7 @@ TEST(V8ScriptValueSerializerTest, RoundTripImageBitmapWithColorSpaceInfo) {
SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear, SkNamedGamut::kDCIP3));
sk_sp<SkSurface> surface = SkSurface::MakeRaster(info);
surface->getCanvas()->clear(SK_ColorRED);
- ImageBitmap* image_bitmap = ImageBitmap::Create(
+ auto* image_bitmap = MakeGarbageCollected<ImageBitmap>(
UnacceleratedStaticBitmapImage::Create(surface->makeImageSnapshot()));
ASSERT_TRUE(image_bitmap->BitmapImage());
@@ -1283,8 +1284,8 @@ TEST(V8ScriptValueSerializerTest, TransferImageBitmap) {
sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(10, 7);
surface->getCanvas()->clear(SK_ColorRED);
sk_sp<SkImage> image = surface->makeImageSnapshot();
- ImageBitmap* image_bitmap =
- ImageBitmap::Create(UnacceleratedStaticBitmapImage::Create(image));
+ auto* image_bitmap = MakeGarbageCollected<ImageBitmap>(
+ UnacceleratedStaticBitmapImage::Create(image));
ASSERT_TRUE(image_bitmap->BitmapImage());
v8::Local<v8::Value> wrapper = ToV8(image_bitmap, scope.GetScriptState());
@@ -1481,8 +1482,10 @@ TEST(V8ScriptValueSerializerTest, RoundTripFileNonNativeSnapshot) {
// Preserving behavior, filesystem URL is not preserved across cloning.
V8TestingScope scope;
KURL url("filesystem:http://example.com/isolated/hash/non-native-file");
+ FileMetadata metadata;
+ metadata.length = 0;
File* file =
- File::CreateForFileSystemFile(url, FileMetadata(), File::kIsUserVisible);
+ File::CreateForFileSystemFile(url, metadata, File::kIsUserVisible);
v8::Local<v8::Value> wrapper = ToV8(file, scope.GetScriptState());
v8::Local<v8::Value> result = RoundTrip(wrapper, scope);
ASSERT_TRUE(V8File::HasInstance(result, scope.GetIsolate()));
@@ -1650,10 +1653,13 @@ TEST(V8ScriptValueSerializerTest, RoundTripFileIndex) {
RoundTrip(wrapper, scope, nullptr, nullptr, &blob_info_array);
// As above, the resulting blob should be correct.
+ // The only users of the 'blob_info_array' version of serialization is
+ // IndexedDB, and the full path is not needed for that system - thus it is not
+ // sent in the round trip.
ASSERT_TRUE(V8File::HasInstance(result, scope.GetIsolate()));
File* new_file = V8File::ToImpl(result.As<v8::Object>());
- EXPECT_TRUE(new_file->HasBackingFile());
- EXPECT_EQ("/native/path", new_file->GetPath());
+ EXPECT_FALSE(new_file->HasBackingFile());
+ EXPECT_EQ("path", new_file->name());
EXPECT_TRUE(new_file->FileSystemURL().IsEmpty());
// The blob info array should also contain the details since it was serialized
@@ -1661,7 +1667,7 @@ TEST(V8ScriptValueSerializerTest, RoundTripFileIndex) {
ASSERT_EQ(1u, blob_info_array.size());
const WebBlobInfo& info = blob_info_array[0];
EXPECT_TRUE(info.IsFile());
- EXPECT_EQ("/native/path", info.FilePath());
+ EXPECT_EQ("path", info.FileName());
EXPECT_EQ(file->Uuid(), String(info.Uuid()));
}
@@ -1670,9 +1676,8 @@ TEST(V8ScriptValueSerializerTest, DecodeFileIndex) {
scoped_refptr<SerializedScriptValue> input =
SerializedValue({0xff, 0x09, 0x3f, 0x00, 0x65, 0x00});
WebBlobInfoArray blob_info_array;
- blob_info_array.emplace_back(
- WebBlobInfo::FileForTesting("d875dfc2-4505-461b-98fe-0cf6cc5eaf44",
- "/native/path", "path", "text/plain"));
+ blob_info_array.emplace_back(WebBlobInfo::FileForTesting(
+ "d875dfc2-4505-461b-98fe-0cf6cc5eaf44", "path", "text/plain"));
V8ScriptValueDeserializer::Options options;
options.blob_info = &blob_info_array;
V8ScriptValueDeserializer deserializer(scope.GetScriptState(), input,
@@ -1682,7 +1687,7 @@ TEST(V8ScriptValueSerializerTest, DecodeFileIndex) {
File* new_file = V8File::ToImpl(result.As<v8::Object>());
EXPECT_EQ("d875dfc2-4505-461b-98fe-0cf6cc5eaf44", new_file->Uuid());
EXPECT_EQ("text/plain", new_file->type());
- EXPECT_EQ("/native/path", new_file->GetPath());
+ EXPECT_TRUE(new_file->GetPath().IsEmpty());
EXPECT_EQ("path", new_file->name());
}
@@ -1696,9 +1701,8 @@ TEST(V8ScriptValueSerializerTest, DecodeFileIndexOutOfRange) {
}
{
WebBlobInfoArray blob_info_array;
- blob_info_array.emplace_back(
- WebBlobInfo::FileForTesting("d875dfc2-4505-461b-98fe-0cf6cc5eaf44",
- "/native/path", "path", "text/plain"));
+ blob_info_array.emplace_back(WebBlobInfo::FileForTesting(
+ "d875dfc2-4505-461b-98fe-0cf6cc5eaf44", "path", "text/plain"));
V8ScriptValueDeserializer::Options options;
options.blob_info = &blob_info_array;
V8ScriptValueDeserializer deserializer(scope.GetScriptState(), input,
@@ -1782,18 +1786,21 @@ TEST(V8ScriptValueSerializerTest, RoundTripFileListIndex) {
RoundTrip(wrapper, scope, nullptr, nullptr, &blob_info_array);
// FileList should be produced correctly.
+ // The only users of the 'blob_info_array' version of serialization is
+ // IndexedDB, and the full path is not needed for that system - thus it is not
+ // sent in the round trip.
ASSERT_TRUE(V8FileList::HasInstance(result, scope.GetIsolate()));
FileList* new_file_list = V8FileList::ToImpl(result.As<v8::Object>());
ASSERT_EQ(2u, new_file_list->length());
- EXPECT_EQ("/native/path", new_file_list->item(0)->GetPath());
- EXPECT_EQ("/native/path2", new_file_list->item(1)->GetPath());
+ EXPECT_EQ("path", new_file_list->item(0)->name());
+ EXPECT_EQ("path2", new_file_list->item(1)->name());
// And the blob info array should be populated.
ASSERT_EQ(2u, blob_info_array.size());
EXPECT_TRUE(blob_info_array[0].IsFile());
- EXPECT_EQ("/native/path", blob_info_array[0].FilePath());
+ EXPECT_EQ("path", blob_info_array[0].FileName());
EXPECT_TRUE(blob_info_array[1].IsFile());
- EXPECT_EQ("/native/path2", blob_info_array[1].FilePath());
+ EXPECT_EQ("path2", blob_info_array[1].FileName());
}
TEST(V8ScriptValueSerializerTest, DecodeEmptyFileListIndex) {
@@ -1829,9 +1836,8 @@ TEST(V8ScriptValueSerializerTest, DecodeFileListIndex) {
scoped_refptr<SerializedScriptValue> input =
SerializedValue({0xff, 0x09, 0x3f, 0x00, 0x4c, 0x01, 0x00, 0x00});
WebBlobInfoArray blob_info_array;
- blob_info_array.emplace_back(
- WebBlobInfo::FileForTesting("d875dfc2-4505-461b-98fe-0cf6cc5eaf44",
- "/native/path", "name", "text/plain"));
+ blob_info_array.emplace_back(WebBlobInfo::FileForTesting(
+ "d875dfc2-4505-461b-98fe-0cf6cc5eaf44", "name", "text/plain"));
V8ScriptValueDeserializer::Options options;
options.blob_info = &blob_info_array;
V8ScriptValueDeserializer deserializer(scope.GetScriptState(), input,
@@ -1840,7 +1846,7 @@ TEST(V8ScriptValueSerializerTest, DecodeFileListIndex) {
FileList* new_file_list = V8FileList::ToImpl(result.As<v8::Object>());
EXPECT_EQ(1u, new_file_list->length());
File* new_file = new_file_list->item(0);
- EXPECT_EQ("/native/path", new_file->GetPath());
+ EXPECT_TRUE(new_file->GetPath().IsEmpty());
EXPECT_EQ("name", new_file->name());
EXPECT_EQ("d875dfc2-4505-461b-98fe-0cf6cc5eaf44", new_file->Uuid());
EXPECT_EQ("text/plain", new_file->type());
@@ -1898,4 +1904,28 @@ TEST(V8ScriptValueSerializerTest, RoundTripReadableStream) {
EXPECT_FALSE(transferred->locked(script_state, ASSERT_NO_EXCEPTION));
}
+TEST(V8ScriptValueSerializerTest, RoundTripDOMException) {
+ V8TestingScope scope;
+ DOMException* exception =
+ DOMException::Create("message", "InvalidStateError");
+ v8::Local<v8::Value> wrapper =
+ ToV8(exception, scope.GetContext()->Global(), scope.GetIsolate());
+ v8::Local<v8::Value> result = RoundTrip(wrapper, scope);
+ ASSERT_TRUE(V8DOMException::HasInstance(result, scope.GetIsolate()));
+ DOMException* new_exception = V8DOMException::ToImpl(result.As<v8::Object>());
+ EXPECT_NE(exception, new_exception);
+ EXPECT_EQ(exception->code(), new_exception->code());
+ EXPECT_EQ(exception->name(), new_exception->name());
+ EXPECT_EQ(exception->message(), new_exception->message());
+}
+
+TEST(V8ScriptValueSerializerTest, DecodeDOMExceptionWithInvalidNameString) {
+ V8TestingScope scope;
+ scoped_refptr<SerializedScriptValue> input = SerializedValue(
+ {0xff, 0x13, 0xff, 0x0d, 0x5c, 0x78, 0x01, 0xff, 0x00, 0x00});
+ v8::Local<v8::Value> result =
+ V8ScriptValueDeserializer(scope.GetScriptState(), input).Deserialize();
+ EXPECT_TRUE(result->IsNull());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/source_location.cc b/chromium/third_party/blink/renderer/bindings/core/v8/source_location.cc
index 35c9508e12a..c7557695656 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/source_location.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/source_location.cc
@@ -56,7 +56,7 @@ std::unique_ptr<SourceLocation> SourceLocation::Capture(
return SourceLocation::CreateFromNonEmptyV8StackTrace(
std::move(stack_trace), 0);
- if (Document* document = DynamicTo<Document>(execution_context)) {
+ if (Document* document = Document::DynamicFrom(execution_context)) {
unsigned line_number = 0;
if (document->GetScriptableDocumentParser() &&
!document->IsInDocumentWrite()) {
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_for_core.cc b/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_for_core.cc
deleted file mode 100644
index 5e5ec0d9b34..00000000000
--- a/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_for_core.cc
+++ /dev/null
@@ -1,59 +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/bindings/core/v8/to_v8_for_core.h"
-
-#include "third_party/blink/renderer/bindings/core/v8/window_proxy.h"
-#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/dom/node.h"
-#include "third_party/blink/renderer/core/frame/dom_window.h"
-#include "third_party/blink/renderer/core/frame/frame.h"
-#include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
-
-namespace blink {
-
-v8::Local<v8::Value> ToV8(DOMWindow* window,
- v8::Local<v8::Object> creation_context,
- v8::Isolate* isolate) {
- RUNTIME_CALL_TIMER_SCOPE(isolate,
- RuntimeCallStats::CounterId::kToV8DOMWindow);
-
- // Notice that we explicitly ignore creationContext because the DOMWindow
- // has its own creationContext.
-
- if (UNLIKELY(!window))
- return v8::Null(isolate);
-
- // TODO(yukishiino): Get understanding of why it's possible to initialize
- // the context after the frame is detached. And then, remove the following
- // lines. See also https://crbug.com/712638 .
- Frame* frame = window->GetFrame();
- if (!frame)
- return v8::Local<v8::Object>();
-
- // TODO(yukishiino): Make this function always return the non-empty handle
- // even if the frame is detached because the global proxy must always exist
- // per spec.
- return frame->GetWindowProxy(DOMWrapperWorld::Current(isolate))
- ->GlobalProxyIfNotDetached();
-}
-
-v8::Local<v8::Value> ToV8(EventTarget* impl,
- v8::Local<v8::Object> creation_context,
- v8::Isolate* isolate) {
- if (UNLIKELY(!impl))
- return v8::Null(isolate);
-
- if (impl->InterfaceName() == event_target_names::kWindow)
- return ToV8(static_cast<DOMWindow*>(impl), creation_context, isolate);
- return ToV8(static_cast<ScriptWrappable*>(impl), creation_context, isolate);
-}
-
-v8::Local<v8::Value> ToV8(Node* node,
- v8::Local<v8::Object> creation_context,
- v8::Isolate* isolate) {
- return ToV8(static_cast<ScriptWrappable*>(node), creation_context, isolate);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h b/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h
index aa55d7c42ad..40ae6d6650b 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h
@@ -9,6 +9,7 @@
// handle. Call sites must check IsEmpty() before using return value.
#include "third_party/blink/renderer/bindings/core/v8/idl_dictionary_base.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/typed_arrays/array_buffer_view_helpers.h"
#include "third_party/blink/renderer/platform/bindings/to_v8.h"
@@ -18,18 +19,6 @@
namespace blink {
class Dictionary;
-class DOMWindow;
-class EventTarget;
-
-CORE_EXPORT v8::Local<v8::Value> ToV8(DOMWindow*,
- v8::Local<v8::Object> creation_context,
- v8::Isolate*);
-CORE_EXPORT v8::Local<v8::Value> ToV8(EventTarget*,
- v8::Local<v8::Object> creation_context,
- v8::Isolate*);
-CORE_EXPORT v8::Local<v8::Value> ToV8(Node* node,
- v8::Local<v8::Object> creation_context,
- v8::Isolate* isolate);
inline v8::Local<v8::Value> ToV8(const Dictionary& value,
v8::Local<v8::Object> creation_context,
@@ -62,6 +51,15 @@ inline v8::Local<v8::Value> ToV8(const IDLDictionaryBase* value,
return value->ToV8Impl(creation_context, isolate);
}
+// Promise
+
+inline v8::Local<v8::Value> ToV8(const ScriptPromise& value,
+ v8::Local<v8::Object> creation_context,
+ v8::Isolate* isolate) {
+ DCHECK(!value.IsEmpty());
+ return value.V8Value();
+}
+
// ScriptValue
inline v8::Local<v8::Value> ToV8(const ScriptValue& value,
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 ed09cf5afbe..924dfa2ba73 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(blink::Visitor* visitor) { visitor->Trace(script_wrappable_); }
+ void Trace(Visitor* visitor) { 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/use_counter_callback.cc b/chromium/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc
index 073900a86bb..e5f6133a874 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
@@ -5,11 +5,9 @@
#include "third_party/blink/renderer/bindings/core/v8/use_counter_callback.h"
#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/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
-#include "third_party/blink/renderer/platform/instrumentation/instance_counters.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
namespace blink {
@@ -21,7 +19,6 @@ void UseCounterCallback(v8::Isolate* isolate,
WebFeature blink_feature;
bool deprecated = false;
- bool detached_window_call = false;
switch (feature) {
case v8::Isolate::kUseAsm:
blink_feature = WebFeature::kUseAsm;
@@ -246,70 +243,36 @@ void UseCounterCallback(v8::Isolate* isolate,
case v8::Isolate::kSharedArrayBufferConstructed:
blink_feature = WebFeature::kV8SharedArrayBufferConstructed;
break;
- // The following 9 counters differ from the rest, because they're reported
- // to UKM using alternative mechanisms. The use counter logic doesn't work
- // on detached windows.
- // TODO(bartekn,chromium:1018156): Remove once not needed.
- case v8::Isolate::kCallInDetachedWindowByNavigation:
- InstanceCounters::IncrementCounter(
- InstanceCounters::kV8CallInDetachedWindowByNavigationCounter);
- detached_window_call = true;
- break;
- case v8::Isolate::kCallInDetachedWindowByNavigationAfter10s:
- InstanceCounters::IncrementCounter(
- InstanceCounters::kV8CallInDetachedWindowByNavigationAfter10sCounter);
- detached_window_call = true;
- break;
- case v8::Isolate::kCallInDetachedWindowByNavigationAfter1min:
- InstanceCounters::IncrementCounter(
- InstanceCounters::
- kV8CallInDetachedWindowByNavigationAfter1minCounter);
- detached_window_call = true;
- break;
- case v8::Isolate::kCallInDetachedWindowByClosing:
- InstanceCounters::IncrementCounter(
- InstanceCounters::kV8CallInDetachedWindowByClosingCounter);
- detached_window_call = true;
- break;
- case v8::Isolate::kCallInDetachedWindowByClosingAfter10s:
- InstanceCounters::IncrementCounter(
- InstanceCounters::kV8CallInDetachedWindowByClosingAfter10sCounter);
- detached_window_call = true;
- break;
- case v8::Isolate::kCallInDetachedWindowByClosingAfter1min:
- InstanceCounters::IncrementCounter(
- InstanceCounters::kV8CallInDetachedWindowByClosingAfter1minCounter);
- detached_window_call = true;
- break;
- case v8::Isolate::kCallInDetachedWindowByOtherReason:
- InstanceCounters::IncrementCounter(
- InstanceCounters::kV8CallInDetachedWindowByOtherReasonCounter);
- detached_window_call = true;
- break;
- case v8::Isolate::kCallInDetachedWindowByOtherReasonAfter10s:
- InstanceCounters::IncrementCounter(
- InstanceCounters::
- kV8CallInDetachedWindowByOtherReasonAfter10sCounter);
- detached_window_call = true;
- break;
- case v8::Isolate::kCallInDetachedWindowByOtherReasonAfter1min:
- InstanceCounters::IncrementCounter(
- InstanceCounters::
- kV8CallInDetachedWindowByOtherReasonAfter1minCounter);
- detached_window_call = true;
- break;
- // End of special case.
+ case v8::Isolate::kArrayPrototypeHasElements:
+ blink_feature = WebFeature::kV8ArrayPrototypeHasElements;
+ break;
+ case v8::Isolate::kObjectPrototypeHasElements:
+ blink_feature = WebFeature::kV8ObjectPrototypeHasElements;
+ break;
+ case v8::Isolate::kDisplayNames:
+ blink_feature = WebFeature::kDisplayNames;
+ break;
+ case v8::Isolate::kNumberFormatStyleUnit:
+ blink_feature = WebFeature::kNumberFormatStyleUnit;
+ break;
+ case v8::Isolate::kDateTimeFormatRange:
+ blink_feature = WebFeature::kDateTimeFormatRange;
+ break;
+ case v8::Isolate::kDateTimeFormatDateTimeStyle:
+ blink_feature = WebFeature::kDateTimeFormatDateTimeStyle;
+ break;
+ case v8::Isolate::kBreakIteratorTypeWord:
+ blink_feature = WebFeature::kBreakIteratorTypeWord;
+ break;
+ case v8::Isolate::kBreakIteratorTypeLine:
+ blink_feature = WebFeature::kBreakIteratorTypeLine;
+ break;
default:
// This can happen if V8 has added counters that this version of Blink
// does not know about. It's harmless.
return;
}
- if (detached_window_call) {
- // Detached window call counters are interesting only in the Document case.
- Document* document = DynamicTo<Document>(CurrentExecutionContext(isolate));
- if (document)
- document->RecordCallInDetachedWindow(feature);
- } else if (deprecated) {
+ if (deprecated) {
Deprecation::CountDeprecation(CurrentExecutionContext(isolate),
blink_feature);
} else {
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v0_custom_element_constructor_builder.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v0_custom_element_constructor_builder.cc
index 656dcfc82c3..35937f6e29d 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v0_custom_element_constructor_builder.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v0_custom_element_constructor_builder.cc
@@ -33,10 +33,10 @@
#include "third_party/blink/renderer/bindings/core/v8/string_or_element_creation_options.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_document.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_element_registration_options.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_html_element.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_svg_element.h"
#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/dom/element_registration_options.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/html/custom/v0_custom_element_definition.h"
#include "third_party/blink/renderer/core/html/custom/v0_custom_element_descriptor.h"
@@ -66,7 +66,7 @@ static void ConstructCustomElement(const v8::FunctionCallbackInfo<v8::Value>&);
V0CustomElementConstructorBuilder::V0CustomElementConstructorBuilder(
ScriptState* script_state,
const ElementRegistrationOptions* options)
- : script_state_(script_state), options_(options) {
+ : script_state_(script_state), options_(options), callbacks_(nullptr) {
DCHECK(script_state_->GetContext() ==
script_state_->GetIsolate()->GetCurrentContext());
}
@@ -167,7 +167,7 @@ V0CustomElementConstructorBuilder::CreateCallbacks() {
callbacks_ = MakeGarbageCollected<V8V0CustomElementLifecycleCallbacks>(
script_state_, prototype_, created, attached, detached,
attribute_changed);
- return callbacks_.Get();
+ return callbacks_;
}
v8::MaybeLocal<v8::Function>
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v0_custom_element_constructor_builder.h b/chromium/third_party/blink/renderer/bindings/core/v8/v0_custom_element_constructor_builder.h
index 8f5a806a673..7e02e872243 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v0_custom_element_constructor_builder.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v0_custom_element_constructor_builder.h
@@ -84,11 +84,11 @@ class V0CustomElementConstructorBuilder {
bool PrototypeIsValid(const AtomicString& type, ExceptionState&) const;
v8::MaybeLocal<v8::Function> RetrieveCallback(const char* name);
- Member<ScriptState> script_state_;
- Member<const ElementRegistrationOptions> options_;
+ ScriptState* script_state_;
+ const ElementRegistrationOptions* options_;
v8::Local<v8::Object> prototype_;
v8::Local<v8::Function> constructor_;
- Member<V8V0CustomElementLifecycleCallbacks> callbacks_;
+ V8V0CustomElementLifecycleCallbacks* callbacks_;
DISALLOW_COPY_AND_ASSIGN(V0CustomElementConstructorBuilder);
};
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc
index 90e9fe250c4..07688741b85 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc
@@ -640,14 +640,7 @@ XPathNSResolver* ToXPathNSResolver(ScriptState* script_state,
}
DOMWindow* ToDOMWindow(v8::Isolate* isolate, v8::Local<v8::Value> value) {
- if (value.IsEmpty() || !value->IsObject())
- return nullptr;
-
- v8::Local<v8::Object> window_wrapper = V8Window::FindInstanceInPrototypeChain(
- v8::Local<v8::Object>::Cast(value), isolate);
- if (!window_wrapper.IsEmpty())
- return V8Window::ToImpl(window_wrapper);
- return nullptr;
+ return V8Window::ToImplWithTypeCheck(isolate, value);
}
LocalDOMWindow* ToLocalDOMWindow(v8::Local<v8::Context> context) {
@@ -716,20 +709,12 @@ LocalFrame* ToLocalFrameIfNotDetached(v8::Local<v8::Context> context) {
void ToFlexibleArrayBufferView(v8::Isolate* isolate,
v8::Local<v8::Value> value,
- FlexibleArrayBufferView& result,
- void* storage) {
+ FlexibleArrayBufferView& result) {
if (!value->IsArrayBufferView()) {
result.Clear();
return;
}
- v8::Local<v8::ArrayBufferView> buffer = value.As<v8::ArrayBufferView>();
- if (!storage) {
- result.SetFull(V8ArrayBufferView::ToImpl(buffer));
- return;
- }
- size_t length = buffer->ByteLength();
- buffer->CopyContents(storage, length);
- result.SetSmall(storage, SafeCast<uint32_t>(length));
+ result.SetContents(value.As<v8::ArrayBufferView>());
}
static ScriptState* ToScriptStateImpl(LocalFrame* frame,
@@ -749,7 +734,7 @@ static ScriptState* ToScriptStateImpl(LocalFrame* frame,
v8::Local<v8::Context> ToV8Context(ExecutionContext* context,
DOMWrapperWorld& world) {
DCHECK(context);
- if (auto* document = DynamicTo<Document>(context)) {
+ if (auto* document = Document::DynamicFrom(context)) {
if (LocalFrame* frame = document->GetFrame())
return ToV8Context(frame, world);
} else if (auto* scope = DynamicTo<WorkerOrWorkletGlobalScope>(context)) {
@@ -785,7 +770,7 @@ v8::Local<v8::Context> ToV8ContextEvenIfDetached(LocalFrame* frame,
ScriptState* ToScriptState(ExecutionContext* context, DOMWrapperWorld& world) {
DCHECK(context);
- if (auto* document = DynamicTo<Document>(context)) {
+ if (auto* document = Document::DynamicFrom(context)) {
if (LocalFrame* frame = document->GetFrame())
return ToScriptState(frame, world);
} else if (auto* scope = DynamicTo<WorkerOrWorkletGlobalScope>(context)) {
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h
index 230f57ec377..9f802792cbb 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h
@@ -63,7 +63,6 @@ namespace blink {
// dependencies to core/.
class DOMWindow;
-class EventTarget;
class ExceptionState;
class ExecutionContext;
class FlexibleArrayBufferView;
@@ -82,88 +81,6 @@ enum class UnionTypeConversionMode {
kNotNullable,
};
-template <typename CallbackInfo>
-inline void V8SetReturnValue(const CallbackInfo& callback_info,
- DOMWindow* impl) {
- V8SetReturnValue(callback_info, ToV8(impl, callback_info.Holder(),
- callback_info.GetIsolate()));
-}
-
-template <typename CallbackInfo>
-inline void V8SetReturnValue(const CallbackInfo& callback_info,
- EventTarget* impl) {
- V8SetReturnValue(callback_info, ToV8(impl, callback_info.Holder(),
- callback_info.GetIsolate()));
-}
-
-template <typename CallbackInfo>
-inline void V8SetReturnValue(const CallbackInfo& callback_info, Node* impl) {
- V8SetReturnValue(callback_info, static_cast<ScriptWrappable*>(impl));
-}
-
-template <typename CallbackInfo>
-inline void V8SetReturnValueForMainWorld(const CallbackInfo& callback_info,
- DOMWindow* impl) {
- V8SetReturnValue(callback_info, ToV8(impl, callback_info.Holder(),
- callback_info.GetIsolate()));
-}
-
-template <typename CallbackInfo>
-inline void V8SetReturnValueForMainWorld(const CallbackInfo& callback_info,
- EventTarget* impl) {
- V8SetReturnValue(callback_info, ToV8(impl, callback_info.Holder(),
- callback_info.GetIsolate()));
-}
-
-template <typename CallbackInfo>
-inline void V8SetReturnValueForMainWorld(const CallbackInfo& callback_info,
- Node* impl) {
- // Since EventTarget has a special version of ToV8 and V8EventTarget.h
- // defines its own v8SetReturnValue family, which are slow, we need to
- // override them with optimized versions for Node and its subclasses.
- // Without this overload, V8SetReturnValueForMainWorld for Node would be
- // very slow.
- //
- // class hierarchy:
- // ScriptWrappable <-- EventTarget <--+-- Node <-- ...
- // +-- Window
- // overloads:
- // V8SetReturnValueForMainWorld(ScriptWrappable*)
- // Optimized and very fast.
- // V8SetReturnValueForMainWorld(EventTarget*)
- // Uses custom ToV8 function and slow.
- // V8SetReturnValueForMainWorld(Node*)
- // Optimized and very fast.
- // V8SetReturnValueForMainWorld(Window*)
- // Uses custom ToV8 function and slow.
- V8SetReturnValueForMainWorld(callback_info,
- static_cast<ScriptWrappable*>(impl));
-}
-
-template <typename CallbackInfo>
-inline void V8SetReturnValueFast(const CallbackInfo& callback_info,
- DOMWindow* impl,
- const ScriptWrappable*) {
- V8SetReturnValue(callback_info, ToV8(impl, callback_info.Holder(),
- callback_info.GetIsolate()));
-}
-
-template <typename CallbackInfo>
-inline void V8SetReturnValueFast(const CallbackInfo& callback_info,
- EventTarget* impl,
- const ScriptWrappable*) {
- V8SetReturnValue(callback_info, ToV8(impl, callback_info.Holder(),
- callback_info.GetIsolate()));
-}
-
-template <typename CallbackInfo>
-inline void V8SetReturnValueFast(const CallbackInfo& callback_info,
- Node* impl,
- const ScriptWrappable* wrappable) {
- V8SetReturnValueFast(callback_info, static_cast<ScriptWrappable*>(impl),
- wrappable);
-}
-
template <typename CallbackInfo, typename T>
inline void V8SetReturnValue(const CallbackInfo& callbackInfo,
NotShared<T> notShared) {
@@ -199,8 +116,8 @@ CORE_EXPORT void V8SetReturnValue(const v8::PropertyCallbackInfo<v8::Value>&,
// Conversion flags, used in toIntXX/toUIntXX.
enum IntegerConversionConfiguration {
kNormalConversion,
+ kClamp,
kEnforceRange,
- kClamp
};
// Convert a value to a boolean.
@@ -439,6 +356,33 @@ VectorOf<typename NativeValueTraits<IDLType>::ImplType> ToImplArguments(
return result;
}
+template <typename IDLType>
+VectorOf<typename NativeValueTraits<IDLType>::ImplType> ToImplArguments(
+ const v8::FunctionCallbackInfo<v8::Value>& info,
+ int start_index,
+ ExceptionState& exception_state,
+ ExecutionContext* execution_context) {
+ using TraitsType = NativeValueTraits<IDLType>;
+ using VectorType = VectorOf<typename TraitsType::ImplType>;
+
+ int length = info.Length();
+ VectorType result;
+ if (start_index < length) {
+ if (static_cast<size_t>(length - start_index) > VectorType::MaxCapacity()) {
+ exception_state.ThrowRangeError("Array length exceeds supported limit.");
+ return VectorType();
+ }
+ result.ReserveInitialCapacity(length - start_index);
+ for (int i = start_index; i < length; ++i) {
+ result.UncheckedAppend(TraitsType::NativeValue(
+ info.GetIsolate(), info[i], exception_state, execution_context));
+ if (exception_state.HadException())
+ return VectorType();
+ }
+ }
+ return result;
+}
+
// The functions below implement low-level abstract ES operations for dealing
// with iterators. Most code should use ScriptIterator instead.
//
@@ -503,13 +447,9 @@ CORE_EXPORT ScriptState* ToScriptStateForMainWorld(LocalFrame*);
// a context, if the window is currently being displayed in a Frame.
CORE_EXPORT LocalFrame* ToLocalFrameIfNotDetached(v8::Local<v8::Context>);
-// If 'storage' is non-null, it must be large enough to copy all bytes in the
-// array buffer view into it. Use allocateFlexibleArrayBufferStorage(v8Value)
-// to allocate it using alloca() in the callers stack frame.
CORE_EXPORT void ToFlexibleArrayBufferView(v8::Isolate*,
v8::Local<v8::Value>,
- FlexibleArrayBufferView&,
- void* storage = nullptr);
+ FlexibleArrayBufferView&);
CORE_EXPORT bool IsValidEnum(const String& value,
const char* const* valid_values,
@@ -522,10 +462,6 @@ CORE_EXPORT bool IsValidEnum(const Vector<String>& values,
const String& enum_name,
ExceptionState&);
-// Result values for platform object 'deleter' methods,
-// http://www.w3.org/TR/WebIDL/#delete
-enum DeleteResult { kDeleteSuccess, kDeleteReject, kDeleteUnknownProperty };
-
CORE_EXPORT v8::Local<v8::Value> FromJSONString(v8::Isolate*,
v8::Local<v8::Context>,
const String& stringified_json,
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 0dda57819a0..a29ede17964 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
@@ -235,10 +235,9 @@ static void ProduceCacheInternal(
code_cache_size_histogram.Count(cache_size_ratio);
}
cache_handler->ClearCachedMetadata(
- CachedMetadataHandler::kCacheLocally);
+ CachedMetadataHandler::kClearLocally);
cache_handler->SetCachedMetadata(
- V8CodeCache::TagForCodeCache(cache_handler), data, length,
- CachedMetadataHandler::kSendToPlatform);
+ V8CodeCache::TagForCodeCache(cache_handler), data, length);
}
TRACE_EVENT_END1(
@@ -296,10 +295,10 @@ uint32_t V8CodeCache::TagForTimeStamp(
void V8CodeCache::SetCacheTimeStamp(
SingleCachedMetadataHandler* cache_handler) {
uint64_t now_ms = base::TimeTicks::Now().since_origin().InMilliseconds();
- cache_handler->ClearCachedMetadata(CachedMetadataHandler::kCacheLocally);
- cache_handler->SetCachedMetadata(
- TagForTimeStamp(cache_handler), reinterpret_cast<uint8_t*>(&now_ms),
- sizeof(now_ms), CachedMetadataHandler::kSendToPlatform);
+ cache_handler->ClearCachedMetadata(CachedMetadataHandler::kClearLocally);
+ cache_handler->SetCachedMetadata(TagForTimeStamp(cache_handler),
+ reinterpret_cast<uint8_t*>(&now_ms),
+ sizeof(now_ms));
}
// static
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_context_snapshot.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_context_snapshot.cc
index 37e233dd487..fa32d0c5c48 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_context_snapshot.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_context_snapshot.cc
@@ -114,7 +114,7 @@ struct DataForDeserializer {
public:
DataForDeserializer(Document* document) : document(document) {}
- Member<Document> document;
+ Document* document;
// Figures if we failed the deserialization.
bool did_fail = false;
};
@@ -137,9 +137,9 @@ v8::Local<v8::Context> V8ContextSnapshot::CreateContextFromSnapshot(
v8::DeserializeInternalFieldsCallback(&DeserializeInternalField, &data);
v8::Local<v8::Context> context =
- v8::Context::FromSnapshot(isolate, index, callback,
- extension_configuration, global_proxy,
- document->GetMicrotaskQueue())
+ v8::Context::FromSnapshot(
+ isolate, index, callback, extension_configuration, global_proxy,
+ document->ToExecutionContext()->GetMicrotaskQueue())
.ToLocalChecked();
// In case we fail to deserialize v8::Context from snapshot,
@@ -209,7 +209,7 @@ bool V8ContextSnapshot::InstallConditionalFeatures(
// The below code handles window.document on the main world.
{
CHECK(document);
- DCHECK(document->IsHTMLDocument());
+ DCHECK(IsA<HTMLDocument>(document));
CHECK(document->ContainsWrapper());
v8::Local<v8::Object> document_wrapper =
ToV8(document, global_proxy, isolate).As<v8::Object>();
@@ -426,7 +426,7 @@ bool V8ContextSnapshot::CanCreateContextFromSnapshot(
// When creating a context for the main world from snapshot, we also need a
// HTMLDocument instance. If typeof window.document is not HTMLDocument, e.g.
// SVGDocument or XMLDocument, we can't create contexts from the snapshot.
- return !world.IsMainWorld() || document->IsHTMLDocument();
+ return !world.IsMainWorld() || IsA<HTMLDocument>(document);
}
void V8ContextSnapshot::EnsureInterfaceTemplatesForWorld(
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 739ba61e9f2..6809daa161c 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
@@ -689,9 +689,10 @@ void V8DOMConfiguration::InstallConstants(
v8::Local<v8::ObjectTemplate> prototype_template,
const ConstantConfiguration* constants,
size_t constant_count) {
- for (size_t i = 0; i < constant_count; ++i)
+ for (size_t i = 0; i < constant_count; ++i) {
InstallConstantInternal(isolate, interface_template, prototype_template,
constants[i]);
+ }
}
void V8DOMConfiguration::InstallConstant(
@@ -711,6 +712,41 @@ void V8DOMConfiguration::InstallConstant(
InstallConstantInternal(isolate, interface, prototype, constant);
}
+void V8DOMConfiguration::InstallConstants(
+ v8::Isolate* isolate,
+ v8::Local<v8::FunctionTemplate> interface_template,
+ v8::Local<v8::ObjectTemplate> prototype_template,
+ const ConstantCallbackConfiguration* constants,
+ size_t constant_count) {
+ for (size_t i = 0; i < constant_count; ++i) {
+ v8::Local<v8::String> name = V8AtomicString(isolate, constants[i].name);
+ interface_template->SetNativeDataProperty(
+ name, constants[i].getter, nullptr, v8::Local<v8::Value>(),
+ static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete),
+ v8::Local<v8::AccessorSignature>(), v8::DEFAULT,
+ v8::SideEffectType::kHasNoSideEffect,
+ v8::SideEffectType::kHasNoSideEffect);
+ prototype_template->SetNativeDataProperty(
+ name, constants[i].getter, nullptr, v8::Local<v8::Value>(),
+ static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete),
+ v8::Local<v8::AccessorSignature>(), v8::DEFAULT,
+ v8::SideEffectType::kHasNoSideEffect,
+ v8::SideEffectType::kHasNoSideEffect);
+ }
+}
+
+void V8DOMConfiguration::InstallConstants(
+ v8::Isolate* isolate,
+ v8::Local<v8::Function> interface_object,
+ v8::Local<v8::Object> prototype_object,
+ const V8DOMConfiguration::ConstantConfiguration* constants,
+ size_t constant_count) {
+ for (size_t i = 0; i < constant_count; ++i) {
+ InstallConstantInternal(isolate, interface_object, prototype_object,
+ constants[i]);
+ }
+}
+
void V8DOMConfiguration::InstallConstantWithGetter(
v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> interface_template,
@@ -752,6 +788,20 @@ void V8DOMConfiguration::InstallMethod(
interface_template, signature, method, world);
}
+void V8DOMConfiguration::InstallMethods(v8::Isolate* isolate,
+ const DOMWrapperWorld& world,
+ v8::Local<v8::Object> instance,
+ v8::Local<v8::Object> prototype,
+ v8::Local<v8::Function> interface,
+ v8::Local<v8::Signature> signature,
+ const MethodConfiguration* methods,
+ size_t method_count) {
+ for (size_t i = 0; i < method_count; ++i) {
+ InstallMethodInternal(isolate, instance, prototype, interface, signature,
+ methods[i], world);
+ }
+}
+
void V8DOMConfiguration::InstallMethod(v8::Isolate* isolate,
const DOMWrapperWorld& world,
v8::Local<v8::Object> instance,
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 488dc8864fc..da8b24c8dcb 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
@@ -228,6 +228,24 @@ class CORE_EXPORT V8DOMConfiguration final {
};
};
+ struct ConstantCallbackConfiguration {
+ DISALLOW_NEW();
+
+ public:
+ constexpr ConstantCallbackConfiguration(
+ const char* name,
+ v8::AccessorNameGetterCallback getter)
+ : name(name), getter(getter) {}
+ ConstantCallbackConfiguration(const ConstantCallbackConfiguration&) =
+ delete;
+
+ ConstantCallbackConfiguration& operator=(
+ const ConstantCallbackConfiguration&) = delete;
+
+ const char* const name;
+ const v8::AccessorNameGetterCallback getter;
+ };
+
// Constant installation
//
// installConstants and installConstant are used for simple constants. They
@@ -253,6 +271,19 @@ class CORE_EXPORT V8DOMConfiguration final {
v8::Local<v8::Object> prototype,
const ConstantConfiguration&);
+ static void InstallConstants(
+ v8::Isolate* isolate,
+ v8::Local<v8::FunctionTemplate> interface_template,
+ v8::Local<v8::ObjectTemplate> prototype_template,
+ const ConstantCallbackConfiguration*,
+ size_t constant_count);
+
+ static void InstallConstants(v8::Isolate* isolate,
+ v8::Local<v8::Function> interface_object,
+ v8::Local<v8::Object> prototype_object,
+ const ConstantConfiguration* constants,
+ size_t constant_count);
+
static void InstallConstantWithGetter(
v8::Isolate*,
v8::Local<v8::FunctionTemplate> interface_template,
@@ -335,6 +366,14 @@ class CORE_EXPORT V8DOMConfiguration final {
// If an empty handle is passed as |instance|, |prototype|, or |interface|,
// then that object is ignored and no properties are installed on that object.
+ static void InstallMethods(v8::Isolate*,
+ const DOMWrapperWorld&,
+ v8::Local<v8::Object> instance,
+ v8::Local<v8::Object> prototype,
+ v8::Local<v8::Function> interface,
+ v8::Local<v8::Signature>,
+ const MethodConfiguration*,
+ size_t method_count);
static void InstallMethod(v8::Isolate*,
const DOMWrapperWorld&,
v8::Local<v8::Object> instance,
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 392d0af6f74..be956230e10 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
@@ -177,29 +177,31 @@ class GC_PLUGIN_IGNORE(
void VisitTracedGlobalHandle(const v8::TracedGlobal<v8::Value>&) override;
// Visitor overrides.
- void VisitRoot(void*, TraceDescriptor, const base::Location&) final;
+ void VisitRoot(const void*, TraceDescriptor, const base::Location&) final;
void Visit(const TraceWrapperV8Reference<v8::Value>&) final;
- void Visit(void*, TraceDescriptor) final;
- void VisitBackingStoreStrongly(void*, void**, TraceDescriptor) final;
- void VisitBackingStoreWeakly(void*,
- void**,
+ void Visit(const void*, TraceDescriptor) final;
+ void VisitBackingStoreStrongly(const void*,
+ const void* const*,
+ TraceDescriptor) final;
+ void VisitBackingStoreWeakly(const void*,
+ const void* const*,
TraceDescriptor,
TraceDescriptor,
WeakCallback,
- void*) final;
- bool VisitEphemeronKeyValuePair(void*,
- void*,
+ const void*) final;
+ bool VisitEphemeronKeyValuePair(const void*,
+ const void*,
EphemeronTracingCallback,
EphemeronTracingCallback) final;
// Unused Visitor overrides.
- void VisitWeak(void* object,
- void* object_weak_ref,
+ void VisitWeak(const void* object,
+ const void* object_weak_ref,
TraceDescriptor desc,
WeakCallback callback) final {}
- void VisitBackingStoreOnly(void*, void**) final {}
- void RegisterBackingStoreCallback(void*, MovingObjectCallback) final {}
- void RegisterWeakCallback(WeakCallback, void*) final {}
+ void VisitBackingStoreOnly(const void*, const void* const*) final {}
+ void RegisterBackingStoreCallback(const void*, MovingObjectCallback) final {}
+ void RegisterWeakCallback(WeakCallback, const void*) final {}
private:
class ParentScope {
@@ -258,6 +260,12 @@ class GC_PLUGIN_IGNORE(
DCHECK(result.is_new_entry);
}
+ void AddRootEdge(State* destination, std::string edge_name) {
+ // State may represent root groups in which case there may exist multiple
+ // references to the same |destination|.
+ named_edges_.insert(destination, std::move(edge_name));
+ }
+
std::string EdgeName(State* destination) {
auto it = named_edges_.find(destination);
if (it != named_edges_.end())
@@ -575,7 +583,7 @@ void V8EmbedderGraphBuilder::BuildEmbedderGraph() {
void V8EmbedderGraphBuilder::VisitPersistentHandleInternal(
v8::Local<v8::Object> v8_value,
uint16_t class_id) {
- ScriptWrappable* traceable = ToScriptWrappable(v8_value);
+ const ScriptWrappable* traceable = ToScriptWrappable(v8_value);
if (!traceable)
return;
Graph::Node* wrapper = node_builder_->GraphNode(v8_value);
@@ -640,7 +648,7 @@ void V8EmbedderGraphBuilder::Visit(
}
}
-void V8EmbedderGraphBuilder::VisitRoot(void* object,
+void V8EmbedderGraphBuilder::VisitRoot(const void* object,
TraceDescriptor wrapper_descriptor,
const base::Location& location) {
// Extract edge name if |location| is set.
@@ -650,21 +658,21 @@ void V8EmbedderGraphBuilder::VisitRoot(void* object,
State* const current = GetOrCreateState(
traceable, HeapObjectHeader::FromPayload(traceable)->Name(),
parent->GetDomTreeState());
- parent->AddEdge(current, location.ToString());
+ parent->AddRootEdge(current, location.ToString());
}
Visit(object, wrapper_descriptor);
}
-void V8EmbedderGraphBuilder::Visit(void* object,
+void V8EmbedderGraphBuilder::Visit(const void* object,
TraceDescriptor wrapper_descriptor) {
if (trace_keys_scope_) {
trace_keys_scope_->SetKey(object);
return;
}
const void* traceable = wrapper_descriptor.base_object_payload;
- const GCInfo* info = GCInfoTable::Get().GCInfoFromIndex(
- HeapObjectHeader::FromPayload(traceable)->GcInfoIndex());
- HeapObjectName name = info->name(traceable);
+ const GCInfo& info =
+ GCInfo::From(HeapObjectHeader::FromPayload(traceable)->GcInfoIndex());
+ HeapObjectName name = info.name(traceable);
State* const parent = GetStateNotNull(current_parent_);
State* const current =
@@ -686,7 +694,7 @@ void V8EmbedderGraphBuilder::Visit(void* object,
current->UpdateDomTreeState(parent->GetDomTreeState());
if (!current->IsVisited()) {
- CreateAndPushVisitationItem(parent, current, traceable, info->trace);
+ CreateAndPushVisitationItem(parent, current, traceable, info.trace);
} else {
// Edge into an already processed subgraph.
if (current->HasNode()) {
@@ -718,21 +726,22 @@ void V8EmbedderGraphBuilder::AddEdge(State* parent, State* current) {
graph_->AddEdge(parent_node, current_node);
}
-void V8EmbedderGraphBuilder::VisitBackingStoreStrongly(void* object,
- void** object_slot,
- TraceDescriptor desc) {
+void V8EmbedderGraphBuilder::VisitBackingStoreStrongly(
+ const void* object,
+ const void* const* object_slot,
+ TraceDescriptor desc) {
if (!object)
return;
desc.callback(this, desc.base_object_payload);
}
void V8EmbedderGraphBuilder::VisitBackingStoreWeakly(
- void* object,
- void** object_slot,
+ const void* object,
+ const void* const* object_slot,
TraceDescriptor strong_desc,
TraceDescriptor weak_desc,
WeakCallback,
- void*) {
+ const void*) {
// Only ephemerons have weak callbacks.
if (weak_desc.callback) {
// Heap snapshot is always run after a GC so we know there are no dead
@@ -742,8 +751,8 @@ void V8EmbedderGraphBuilder::VisitBackingStoreWeakly(
}
bool V8EmbedderGraphBuilder::VisitEphemeronKeyValuePair(
- void* key,
- void* value,
+ const void* key,
+ const void* value,
EphemeronTracingCallback key_trace_callback,
EphemeronTracingCallback value_trace_callback) {
ephemeron_worklist_.push_back(std::unique_ptr<EphemeronItem>{
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_html_constructor.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_html_constructor.cc
index ea5352504bc..3fca5b22b2d 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_html_constructor.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_html_constructor.cc
@@ -83,7 +83,8 @@ void V8HTMLConstructor::HtmlConstructor(
} else {
// Customized built-in element
// 5. If local name is not valid for interface, throw TypeError
- if (htmlElementTypeForTag(local_name) != element_interface_name) {
+ if (htmlElementTypeForTag(local_name, window->document()) !=
+ element_interface_name) {
V8ThrowException::ThrowTypeError(isolate,
"Illegal constructor: localName does "
"not match the HTML element interface");
@@ -127,8 +128,7 @@ void V8HTMLConstructor::HtmlConstructor(
// During upgrade an element has invoked the same constructor
// before calling 'super' and that invocation has poached the
// element.
- exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
- "this instance is already constructed");
+ exception_state.ThrowTypeError("This instance is already constructed");
return;
}
}
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
index c69cfebccd7..696a6170a58 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
@@ -25,7 +25,9 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_initializer.h"
+#include <algorithm>
#include <memory>
+#include <utility>
#include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_macros.h"
@@ -65,15 +67,18 @@
#include "third_party/blink/renderer/core/script/modulator.h"
#include "third_party/blink/renderer/core/trustedtypes/trusted_types_util.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
+#include "third_party/blink/renderer/core/workers/worklet_global_scope.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
+#include "third_party/blink/renderer/platform/bindings/v8_dom_wrapper.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_context_data.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/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.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_violation_reporting_policy.h"
+#include "third_party/blink/renderer/platform/weborigin/reporting_disposition.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/sanitizers.h"
#include "third_party/blink/renderer/platform/wtf/stack_util.h"
@@ -92,7 +97,7 @@ static void ReportFatalErrorInMainThread(const char* location,
static void ReportOOMErrorInMainThread(const char* location, bool is_js_heap) {
DVLOG(1) << "V8 " << (is_js_heap ? "javascript" : "process") << " OOM: ("
<< location << ").";
- OOM_CRASH();
+ OOM_CRASH(0);
}
static String ExtractMessageForConsole(v8::Isolate* isolate,
@@ -157,7 +162,7 @@ void V8Initializer::MessageHandlerInMainThread(v8::Local<v8::Message> message,
SourceLocation::FromMessage(isolate, message, context);
if (message->ErrorLevel() != v8::Isolate::kMessageError) {
- context->AddConsoleMessage(ConsoleMessage::Create(
+ context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
MessageLevelFromNonFatalErrorLevel(message->ErrorLevel()),
ToCoreStringWithNullCheck(message->Get()), std::move(location)));
@@ -202,7 +207,7 @@ void V8Initializer::MessageHandlerInWorker(v8::Local<v8::Message> message,
SourceLocation::FromMessage(isolate, message, context);
if (message->ErrorLevel() != v8::Isolate::kMessageError) {
- context->AddConsoleMessage(ConsoleMessage::Create(
+ context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
MessageLevelFromNonFatalErrorLevel(message->ErrorLevel()),
ToCoreStringWithNullCheck(message->Get()), std::move(location)));
@@ -336,7 +341,9 @@ static void PromiseRejectHandlerInWorker(v8::PromiseRejectMessage data) {
return;
auto* script_controller =
- To<WorkerGlobalScope>(execution_context)->ScriptController();
+ execution_context->IsWorkerGlobalScope()
+ ? To<WorkerGlobalScope>(execution_context)->ScriptController()
+ : To<WorkletGlobalScope>(execution_context)->ScriptController();
DCHECK(script_controller);
PromiseRejectHandler(data, *script_controller->GetRejectedPromises(),
@@ -375,7 +382,7 @@ static bool ContentSecurityPolicyCodeGenerationCheck(
static_cast<size_t>(source_str.length()));
memcpy(snippet, *source_str, len * sizeof(UChar));
snippet[len] = 0;
- return policy->AllowEval(SecurityViolationReportingPolicy::kReport,
+ return policy->AllowEval(ReportingDisposition::kReport,
ContentSecurityPolicy::kWillThrowException,
snippet);
}
@@ -406,7 +413,7 @@ TrustedTypesCodeGenerationCheck(v8::Local<v8::Context> context,
return {false, v8::MaybeLocal<v8::String>()};
}
- String stringified_source = GetStringFromTrustedScript(
+ String stringified_source = TrustedTypesCheckForScript(
string_or_trusted_script, ToExecutionContext(context), exception_state);
if (exception_state.HadException()) {
exception_state.ClearException();
@@ -449,7 +456,7 @@ static bool WasmCodeGenerationCheckCallbackInMainThread(
v8::Local<v8::String> source) {
if (ExecutionContext* execution_context = ToExecutionContext(context)) {
if (ContentSecurityPolicy* policy =
- To<Document>(execution_context)->GetContentSecurityPolicy()) {
+ Document::From(execution_context)->GetContentSecurityPolicy()) {
v8::String::Value source_str(context->GetIsolate(), source);
UChar snippet[ContentSecurityPolicy::kMaxSampleLength + 1];
size_t len = std::min((sizeof(snippet) / sizeof(UChar)) - 1,
@@ -459,10 +466,10 @@ static bool WasmCodeGenerationCheckCallbackInMainThread(
// Wasm code generation is allowed if we have either the wasm-eval
// directive or the unsafe-eval directive. However, we only recognize
// wasm-eval for certain schemes
- return policy->AllowWasmEval(SecurityViolationReportingPolicy::kReport,
+ return policy->AllowWasmEval(ReportingDisposition::kReport,
ContentSecurityPolicy::kWillThrowException,
snippet) ||
- policy->AllowEval(SecurityViolationReportingPolicy::kReport,
+ policy->AllowEval(ReportingDisposition::kReport,
ContentSecurityPolicy::kWillThrowException,
snippet);
}
@@ -520,7 +527,7 @@ static bool WasmInstanceOverride(
if (!WTF::IsMainThread() || args.Length() < 1)
return false;
v8::Local<v8::Value> source = args[0];
- if (!source->IsWebAssemblyCompiledModule())
+ if (!source->IsWasmModuleObject())
return false;
v8::CompiledWasmModule compiled_module =
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 acd50fa35ae..e60cc9a0986 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
@@ -17,7 +17,7 @@ namespace blink {
V8IntersectionObserverDelegate::V8IntersectionObserverDelegate(
V8IntersectionObserverCallback* callback,
ScriptState* script_state)
- : ContextClient(ExecutionContext::From(script_state)),
+ : ExecutionContextClient(ExecutionContext::From(script_state)),
callback_(callback) {}
V8IntersectionObserverDelegate::~V8IntersectionObserverDelegate() = default;
@@ -29,13 +29,13 @@ void V8IntersectionObserverDelegate::Deliver(
}
ExecutionContext* V8IntersectionObserverDelegate::GetExecutionContext() const {
- return ContextClient::GetExecutionContext();
+ return ExecutionContextClient::GetExecutionContext();
}
-void V8IntersectionObserverDelegate::Trace(blink::Visitor* visitor) {
+void V8IntersectionObserverDelegate::Trace(Visitor* visitor) {
visitor->Trace(callback_);
IntersectionObserverDelegate::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 37f79c5260f..dc1faee0221 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
@@ -6,8 +6,8 @@
#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_INTERSECTION_OBSERVER_DELEGATE_H_
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_delegate.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
#include "third_party/blink/renderer/platform/bindings/scoped_persistent.h"
@@ -18,7 +18,7 @@ class V8IntersectionObserverCallback;
class V8IntersectionObserverDelegate final
: public IntersectionObserverDelegate,
- public ContextClient {
+ public ExecutionContextClient {
USING_GARBAGE_COLLECTED_MIXIN(V8IntersectionObserverDelegate);
public:
@@ -28,7 +28,7 @@ class V8IntersectionObserverDelegate final
ExecutionContext* GetExecutionContext() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
IntersectionObserver::DeliveryBehavior GetDeliveryBehavior() const override {
return IntersectionObserver::kPostTaskToDeliver;
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_object_builder.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_object_builder.h
index 6fd0c7498f7..022eb009fb0 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_object_builder.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_object_builder.h
@@ -47,7 +47,7 @@ class CORE_EXPORT V8ObjectBuilder final {
private:
void AddInternal(const StringView& name, v8::Local<v8::Value>);
- Member<ScriptState> script_state_;
+ ScriptState* script_state_;
v8::Local<v8::Object> object_;
};
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_object_parser.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_object_parser.cc
index 0efef7b3785..cb2fe11556e 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_object_parser.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_object_parser.cc
@@ -13,6 +13,7 @@ namespace blink {
bool V8ObjectParser::ParseCSSPropertyList(
v8::Local<v8::Context> context,
+ const ExecutionContext* execution_context,
v8::Local<v8::Object> constructor,
const AtomicString list_name,
Vector<CSSPropertyID>* native_properties,
@@ -37,7 +38,7 @@ bool V8ObjectParser::ParseCSSPropertyList(
return false;
for (const auto& property : properties) {
- CSSPropertyID property_id = cssPropertyID(property);
+ CSSPropertyID property_id = cssPropertyID(execution_context, property);
if (property_id == CSSPropertyID::kVariable) {
custom_properties->push_back(std::move(property));
} else if (property_id != CSSPropertyID::kInvalid) {
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_object_parser.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_object_parser.h
index 5d35e474cd0..66617f488eb 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_object_parser.h
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_object_parser.h
@@ -14,6 +14,7 @@
namespace blink {
class ExceptionState;
+class ExecutionContext;
class CORE_EXPORT V8ObjectParser final {
STATIC_ONLY(V8ObjectParser);
@@ -24,6 +25,7 @@ class CORE_EXPORT V8ObjectParser final {
// Vector<String> type. It does not fail if the list contains invalid CSS
// properties, to ensure forward compatibility.
static bool ParseCSSPropertyList(v8::Local<v8::Context>,
+ const ExecutionContext*,
v8::Local<v8::Object> constructor,
const AtomicString list_name,
Vector<CSSPropertyID>* native_properties,
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_page_popup_controller_binding.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_page_popup_controller_binding.cc
index 28e9efc8ec2..ce755f38d8d 100644
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_page_popup_controller_binding.cc
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_page_popup_controller_binding.cc
@@ -39,7 +39,7 @@ void PagePopupControllerAttributeGetterCallback(
void V8PagePopupControllerBinding::InstallPagePopupController(
v8::Local<v8::Context> context,
v8::Local<v8::Object> window_wrapper) {
- Document* document = DynamicTo<Document>(
+ Document* document = Document::DynamicFrom(
ToExecutionContext(window_wrapper->CreationContext()));
if (!document || !ContextFeatures::PagePopupEnabled(document))
return;
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_persistent_value_vector.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_persistent_value_vector.h
deleted file mode 100644
index be9646681ea..00000000000
--- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_persistent_value_vector.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2007-2009 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.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_PERSISTENT_VALUE_VECTOR_H_
-#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_PERSISTENT_VALUE_VECTOR_H_
-
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
-#include "v8/include/v8-util.h"
-#include "v8/include/v8.h"
-
-namespace blink {
-
-class WTFVectorPersistentValueVectorTraits {
- STATIC_ONLY(WTFVectorPersistentValueVectorTraits);
-
- public:
- typedef Vector<v8::PersistentContainerValue> Impl;
- static void Append(Impl* impl, v8::PersistentContainerValue value) {
- impl->push_back(value);
- }
- static bool IsEmpty(const Impl* impl) { return impl->IsEmpty(); }
- static size_t Size(const Impl* impl) { return impl->size(); }
- static v8::PersistentContainerValue Get(const Impl* impl, size_t i) {
- return (i < impl->size()) ? impl->at(static_cast<wtf_size_t>(i))
- : v8::kPersistentContainerNotFound;
- }
- static void ReserveCapacity(Impl* impl, size_t capacity) {
- impl->ReserveCapacity(static_cast<wtf_size_t>(capacity));
- }
- static void Clear(Impl* impl) { impl->clear(); }
-};
-
-template <class ValueType>
-class V8PersistentValueVector
- : public v8::PersistentValueVector<ValueType,
- WTFVectorPersistentValueVectorTraits> {
- DISALLOW_NEW();
-
- public:
- explicit V8PersistentValueVector(v8::Isolate* isolate)
- : v8::PersistentValueVector<ValueType,
- WTFVectorPersistentValueVectorTraits>(
- isolate) {}
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_PERSISTENT_VALUE_VECTOR_H_
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 4c9958be8fe..aa064565310 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
@@ -25,7 +25,9 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.h"
+#include "base/feature_list.h"
#include "build/build_config.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/bindings/core/v8/binding_security.h"
#include "third_party/blink/renderer/bindings/core/v8/referrer_script_info.h"
#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
@@ -57,6 +59,11 @@ namespace {
// This limit was arrived at arbitrarily. crbug.com/449744
const int kMaxRecursionDepth = 44;
+bool InDiscardExperiment() {
+ return base::FeatureList::IsEnabled(
+ blink::features::kDiscardCodeCacheAfterFirstUse);
+}
+
// In order to make sure all pending messages to be processed in
// v8::Function::Call, we don't call throwStackOverflowException
// directly. Instead, we create a v8::Function of
@@ -148,7 +155,12 @@ v8::MaybeLocal<v8::Script> CompileScriptInternal(
if (cached_data->rejected) {
cache_handler->ClearCachedMetadata(
- CachedMetadataHandler::kSendToPlatform);
+ CachedMetadataHandler::kClearPersistentStorage);
+ } else if (InDiscardExperiment()) {
+ // Experimentally free code cache from memory after first use. See
+ // http://crbug.com/1045052.
+ cache_handler->ClearCachedMetadata(
+ CachedMetadataHandler::kDiscardLocally);
}
if (cache_result) {
cache_result->consume_result = base::make_optional(
@@ -281,7 +293,12 @@ v8::MaybeLocal<v8::Module> V8ScriptRunner::CompileModule(
isolate, &source, compile_options, no_cache_reason);
if (cached_data->rejected) {
cache_handler->ClearCachedMetadata(
- CachedMetadataHandler::kSendToPlatform);
+ CachedMetadataHandler::kClearPersistentStorage);
+ } else if (InDiscardExperiment()) {
+ // Experimentally free code cache from memory after first use. See
+ // http://crbug.com/1045052.
+ cache_handler->ClearCachedMetadata(
+ CachedMetadataHandler::kDiscardLocally);
}
cache_result.consume_result = base::make_optional(
inspector_compile_script_event::V8CacheResult::ConsumeResult(
@@ -303,8 +320,8 @@ v8::MaybeLocal<v8::Value> V8ScriptRunner::RunCompiledScript(
v8::Local<v8::Script> script,
ExecutionContext* context) {
DCHECK(!script.IsEmpty());
- ScopedFrameBlamer frame_blamer(
- IsA<Document>(context) ? To<Document>(context)->GetFrame() : nullptr);
+ Document* document = Document::DynamicFrom(context);
+ ScopedFrameBlamer frame_blamer(document ? document->GetFrame() : nullptr);
v8::Local<v8::Value> script_name =
script->GetUnboundScript()->GetScriptName();
@@ -317,7 +334,7 @@ v8::MaybeLocal<v8::Value> V8ScriptRunner::RunCompiledScript(
if (GetMicrotasksScopeDepth(isolate, microtask_queue) > kMaxRecursionDepth)
return ThrowStackOverflowExceptionIfNeeded(isolate, microtask_queue);
- CHECK(!context->IsIteratingOverObservers());
+ CHECK(!context->ContextLifecycleObserverList().IsIteratingOverObservers());
// Run the script and keep track of the current recursion depth.
v8::MaybeLocal<v8::Value> result;
@@ -396,7 +413,7 @@ v8::MaybeLocal<v8::Value> V8ScriptRunner::CallAsConstructor(
if (depth >= kMaxRecursionDepth)
return ThrowStackOverflowExceptionIfNeeded(isolate, microtask_queue);
- CHECK(!context->IsIteratingOverObservers());
+ CHECK(!context->ContextLifecycleObserverList().IsIteratingOverObservers());
if (ScriptForbiddenScope::IsScriptForbidden()) {
ThrowScriptForbiddenException(isolate);
@@ -437,8 +454,8 @@ v8::MaybeLocal<v8::Value> V8ScriptRunner::CallFunction(
int argc,
v8::Local<v8::Value> args[],
v8::Isolate* isolate) {
- LocalFrame* frame =
- IsA<Document>(context) ? To<Document>(context)->GetFrame() : nullptr;
+ Document* document = Document::DynamicFrom(context);
+ LocalFrame* frame = document ? document->GetFrame() : nullptr;
ScopedFrameBlamer frame_blamer(frame);
TRACE_EVENT0("v8", "v8.callFunction");
RuntimeCallStatsScopedTracer rcs_scoped_tracer(isolate);
@@ -449,7 +466,7 @@ v8::MaybeLocal<v8::Value> V8ScriptRunner::CallFunction(
if (depth >= kMaxRecursionDepth)
return ThrowStackOverflowExceptionIfNeeded(isolate, microtask_queue);
- CHECK(!context->IsIteratingOverObservers());
+ CHECK(!context->ContextLifecycleObserverList().IsIteratingOverObservers());
if (ScriptForbiddenScope::IsScriptForbidden()) {
ThrowScriptForbiddenException(isolate);
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 021d7cab1c1..62ac47f1166 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
@@ -4,7 +4,10 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.h"
+#include "base/test/metrics/histogram_tester.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/bindings/core/v8/referrer_script_info.h"
#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
@@ -14,6 +17,7 @@
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/loader/fetch/cached_metadata.h"
#include "third_party/blink/renderer/platform/loader/fetch/cached_metadata_handler.h"
+#include "third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
#include "third_party/blink/renderer/platform/wtf/text/text_encoding.h"
@@ -113,10 +117,44 @@ class V8ScriptRunnerTest : public testing::Test {
protected:
static int counter_;
+ base::test::ScopedFeatureList feature_list_;
};
int V8ScriptRunnerTest::counter_ = 0;
+class HistogramCounter {
+ public:
+ explicit HistogramCounter(const base::HistogramTester& tester)
+ : tester_(tester) {}
+
+ int32_t GetTotal() { return GetSamples()->TotalCount(); }
+
+ int32_t GetPresent() { return GetCount(StateOnGet::kPresent); }
+
+ int32_t GetDataTypeMismatch() {
+ return GetCount(StateOnGet::kDataTypeMismatch);
+ }
+
+ int32_t GetWasNeverPresent() {
+ return GetCount(StateOnGet::kWasNeverPresent);
+ }
+
+ int32_t GetDiscarded() { return GetCount(StateOnGet::kWasDiscarded); }
+
+ private:
+ std::unique_ptr<base::HistogramSamples> GetSamples() {
+ return tester_.GetHistogramSamplesSinceCreation(
+ "Memory.Renderer.BlinkCachedMetadataGetResult");
+ }
+
+ int32_t GetCount(StateOnGet state) {
+ static_assert((std::is_same<int, base::HistogramBase::Sample>::value), "");
+ return GetSamples()->GetCount(static_cast<int>(state));
+ }
+
+ const base::HistogramTester& tester_;
+};
+
TEST_F(V8ScriptRunnerTest, resourcelessShouldPass) {
V8TestingScope scope;
ScriptSourceCode source_code(Code(), ScriptSourceLocationType::kInternal,
@@ -150,7 +188,9 @@ TEST_F(V8ScriptRunnerTest, codeOption) {
TagForCodeCache(another_resource->CacheHandler())));
}
-TEST_F(V8ScriptRunnerTest, consumeCodeOption) {
+TEST_F(V8ScriptRunnerTest, consumeCodeOptionWithoutDiscarding) {
+ feature_list_.InitAndDisableFeature(
+ blink::features::kDiscardCodeCacheAfterFirstUse);
V8TestingScope scope;
ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()),
ScriptStreamer::kScriptTooSmall);
@@ -181,25 +221,69 @@ TEST_F(V8ScriptRunnerTest, consumeCodeOption) {
EXPECT_TRUE(cache_handler->GetCachedMetadata(TagForCodeCache(cache_handler)));
}
-TEST_F(V8ScriptRunnerTest, produceAndConsumeCodeOption) {
+TEST_F(V8ScriptRunnerTest, consumeCodeOptionWithDiscarding) {
+ feature_list_.InitAndEnableFeature(
+ blink::features::kDiscardCodeCacheAfterFirstUse);
+ V8TestingScope scope;
+ ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()),
+ ScriptStreamer::kScriptTooSmall);
+ // Set timestamp to simulate a warm run.
+ SingleCachedMetadataHandler* cache_handler = source_code.CacheHandler();
+ SetCacheTimeStamp(cache_handler);
+
+ // Warm run - should produce code cache.
+ EXPECT_TRUE(CompileScript(scope.GetIsolate(), scope.GetScriptState(),
+ source_code, kV8CacheOptionsCode));
+
+ // Check the produced cache is for code cache.
+ EXPECT_TRUE(cache_handler->GetCachedMetadata(TagForCodeCache(cache_handler)));
+
+ // Hot run - should consume code cache.
+ base::HistogramTester tester;
+ HistogramCounter counter(tester);
+ v8::ScriptCompiler::CompileOptions compile_options;
+ V8CodeCache::ProduceCacheOptions produce_cache_options;
+ v8::ScriptCompiler::NoCacheReason no_cache_reason;
+ std::tie(compile_options, produce_cache_options, no_cache_reason) =
+ V8CodeCache::GetCompileOptions(kV8CacheOptionsDefault, source_code);
+ EXPECT_EQ(1, counter.GetTotal());
+ EXPECT_EQ(1, counter.GetPresent());
+ EXPECT_EQ(produce_cache_options,
+ V8CodeCache::ProduceCacheOptions::kNoProduceCache);
+ EXPECT_EQ(compile_options,
+ v8::ScriptCompiler::CompileOptions::kConsumeCodeCache);
+ EXPECT_TRUE(CompileScript(scope.GetIsolate(), scope.GetScriptState(),
+ source_code, compile_options, no_cache_reason,
+ produce_cache_options));
+ EXPECT_EQ(2, counter.GetTotal());
+ EXPECT_EQ(2, counter.GetPresent());
+ EXPECT_FALSE(
+ cache_handler->GetCachedMetadata(TagForCodeCache(cache_handler)));
+ EXPECT_EQ(3, counter.GetTotal());
+ EXPECT_EQ(1, counter.GetDiscarded());
+}
+
+TEST_F(V8ScriptRunnerTest, produceAndConsumeCodeOptionWithoutDiscarding) {
+ feature_list_.InitAndDisableFeature(
+ blink::features::kDiscardCodeCacheAfterFirstUse);
V8TestingScope scope;
ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()),
ScriptStreamer::kScriptTooSmall);
SingleCachedMetadataHandler* cache_handler = source_code.CacheHandler();
- // Cold run - should set the timestamp
+ // Cold run - should set the timestamp.
EXPECT_TRUE(CompileScript(scope.GetIsolate(), scope.GetScriptState(),
source_code, kV8CacheOptionsDefault));
EXPECT_TRUE(cache_handler->GetCachedMetadata(TagForTimeStamp(cache_handler)));
EXPECT_FALSE(
cache_handler->GetCachedMetadata(TagForCodeCache(cache_handler)));
- // Warm run - should produce code cache
+ // Warm run - should produce code cache.
EXPECT_TRUE(CompileScript(scope.GetIsolate(), scope.GetScriptState(),
source_code, kV8CacheOptionsDefault));
EXPECT_TRUE(cache_handler->GetCachedMetadata(TagForCodeCache(cache_handler)));
- // Hot run - should consume code cache
+ // Hot run - should consume code cache.
v8::ScriptCompiler::CompileOptions compile_options;
V8CodeCache::ProduceCacheOptions produce_cache_options;
v8::ScriptCompiler::NoCacheReason no_cache_reason;
@@ -215,6 +299,78 @@ TEST_F(V8ScriptRunnerTest, produceAndConsumeCodeOption) {
EXPECT_TRUE(cache_handler->GetCachedMetadata(TagForCodeCache(cache_handler)));
}
+TEST_F(V8ScriptRunnerTest, produceAndConsumeCodeOptionWithDiscarding) {
+ feature_list_.InitAndEnableFeature(
+ blink::features::kDiscardCodeCacheAfterFirstUse);
+ V8TestingScope scope;
+ ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()),
+ ScriptStreamer::kScriptTooSmall);
+ SingleCachedMetadataHandler* cache_handler = source_code.CacheHandler();
+
+ // Cold run - should set the timestamp.
+ EXPECT_TRUE(CompileScript(scope.GetIsolate(), scope.GetScriptState(),
+ source_code, kV8CacheOptionsDefault));
+ EXPECT_TRUE(cache_handler->GetCachedMetadata(TagForTimeStamp(cache_handler)));
+ EXPECT_FALSE(
+ cache_handler->GetCachedMetadata(TagForCodeCache(cache_handler)));
+
+ // Warm run - should produce code cache.
+ EXPECT_TRUE(CompileScript(scope.GetIsolate(), scope.GetScriptState(),
+ source_code, kV8CacheOptionsDefault));
+ EXPECT_TRUE(cache_handler->GetCachedMetadata(TagForCodeCache(cache_handler)));
+
+ // Hot run - should consume code cache.
+ v8::ScriptCompiler::CompileOptions compile_options;
+ V8CodeCache::ProduceCacheOptions produce_cache_options;
+ v8::ScriptCompiler::NoCacheReason no_cache_reason;
+ std::tie(compile_options, produce_cache_options, no_cache_reason) =
+ V8CodeCache::GetCompileOptions(kV8CacheOptionsDefault, source_code);
+ EXPECT_EQ(produce_cache_options,
+ V8CodeCache::ProduceCacheOptions::kNoProduceCache);
+ EXPECT_EQ(compile_options,
+ v8::ScriptCompiler::CompileOptions::kConsumeCodeCache);
+ EXPECT_TRUE(CompileScript(scope.GetIsolate(), scope.GetScriptState(),
+ source_code, compile_options, no_cache_reason,
+ produce_cache_options));
+ EXPECT_FALSE(
+ cache_handler->GetCachedMetadata(TagForCodeCache(cache_handler)));
+}
+
+TEST_F(V8ScriptRunnerTest, cacheRequestedBeforeProduced) {
+ feature_list_.InitAndEnableFeature(
+ blink::features::kDiscardCodeCacheAfterFirstUse);
+ V8TestingScope scope;
+ ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()),
+ ScriptStreamer::kScriptTooSmall);
+ SingleCachedMetadataHandler* cache_handler = source_code.CacheHandler();
+ base::HistogramTester tester;
+ HistogramCounter counter(tester);
+ EXPECT_FALSE(
+ cache_handler->GetCachedMetadata(TagForTimeStamp(cache_handler)));
+ EXPECT_EQ(1, counter.GetTotal());
+ EXPECT_EQ(1, counter.GetWasNeverPresent());
+}
+
+TEST_F(V8ScriptRunnerTest, cacheDataTypeMismatch) {
+ feature_list_.InitAndEnableFeature(
+ blink::features::kDiscardCodeCacheAfterFirstUse);
+ V8TestingScope scope;
+ ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()),
+ ScriptStreamer::kScriptTooSmall);
+ SingleCachedMetadataHandler* cache_handler = source_code.CacheHandler();
+ EXPECT_FALSE(
+ cache_handler->GetCachedMetadata(TagForTimeStamp(cache_handler)));
+ EXPECT_TRUE(CompileScript(scope.GetIsolate(), scope.GetScriptState(),
+ source_code, kV8CacheOptionsDefault));
+ EXPECT_TRUE(cache_handler->GetCachedMetadata(TagForTimeStamp(cache_handler)));
+ base::HistogramTester tester;
+ HistogramCounter counter(tester);
+ EXPECT_FALSE(
+ cache_handler->GetCachedMetadata(TagForCodeCache(cache_handler)));
+ EXPECT_EQ(1, counter.GetTotal());
+ EXPECT_EQ(1, counter.GetDataTypeMismatch());
+}
+
} // namespace
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_set_return_value_for_core.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_set_return_value_for_core.h
new file mode 100644
index 00000000000..cddc3bb9e09
--- /dev/null
+++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_set_return_value_for_core.h
@@ -0,0 +1,52 @@
+// 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_BINDINGS_CORE_V8_V8_SET_RETURN_VALUE_FOR_CORE_H_
+#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_SET_RETURN_VALUE_FOR_CORE_H_
+
+#include "third_party/blink/renderer/bindings/core/v8/js_event_handler.h"
+#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
+#include "third_party/blink/renderer/platform/bindings/v8_set_return_value.h"
+
+namespace blink {
+
+namespace bindings {
+
+class NativeValueTraitsStringAdapter;
+
+// String types
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info,
+ const NativeValueTraitsStringAdapter& value,
+ v8::Isolate* isolate,
+ V8ReturnValue::NonNullable) {
+ V8SetReturnValue(info, static_cast<String>(value), isolate,
+ V8ReturnValue::kNonNullable);
+}
+
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info,
+ const NativeValueTraitsStringAdapter& value,
+ v8::Isolate* isolate,
+ V8ReturnValue::Nullable) {
+ V8SetReturnValue(info, static_cast<String>(value), isolate,
+ V8ReturnValue::kNullable);
+}
+
+// EventListener
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info,
+ const EventListener* value,
+ v8::Isolate* isolate,
+ EventTarget* event_target) {
+ EventListener* event_listener = const_cast<EventListener*>(value);
+ info.GetReturnValue().Set(
+ JSEventHandler::AsV8Value(isolate, event_target, event_listener));
+}
+
+} // namespace bindings
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_SET_RETURN_VALUE_FOR_CORE_H_
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 8be8bd5828c..0c1f83bf067 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(blink::Visitor* visitor) {
+void V8V0CustomElementLifecycleCallbacks::Trace(Visitor* visitor) {
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 d7e117a2a9e..aef5ac99fad 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 70ab98f3ff4..6023c25e49a 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
@@ -211,8 +211,6 @@ class ExceptionToAbortStreamingScope {
RawResource* GetRawResource(ScriptState* script_state,
const String& url_string) {
- if (!RuntimeEnabledFeatures::WasmCodeCacheEnabled())
- return nullptr;
ExecutionContext* execution_context = ExecutionContext::From(script_state);
if (!execution_context)
return nullptr;
@@ -324,7 +322,10 @@ void StreamFromResponseCallback(
return;
}
- if (response->MimeType() != "application/wasm") {
+ // The spec explicitly disallows any extras on the Content-Type header,
+ // so we check against ContentType() rather than MimeType(), which
+ // implicitly strips extras.
+ if (response->ContentType().LowerASCII() != "application/wasm") {
exception_state.ThrowTypeError(
"Incorrect response MIME type. Expected 'application/wasm'.");
return;
@@ -351,6 +352,8 @@ void StreamFromResponseCallback(
}
String url = response->url();
+ const std::string& url_utf8 = url.Utf8();
+ streaming->SetUrl(url_utf8.c_str(), url_utf8.size());
RawResource* raw_resource = GetRawResource(script_state, url);
if (raw_resource) {
SingleCachedMetadataHandler* cache_handler =
@@ -379,7 +382,7 @@ void StreamFromResponseCallback(
"v8.wasm.moduleCacheInvalid",
TRACE_EVENT_SCOPE_THREAD);
cache_handler->ClearCachedMetadata(
- CachedMetadataHandler::kSendToPlatform);
+ CachedMetadataHandler::kClearPersistentStorage);
}
}
}
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 86076cb3f39..389dcd940e9 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(blink::Visitor* visitor) {
+void WindowProxy::Trace(Visitor* visitor) {
visitor->Trace(frame_);
}
@@ -65,24 +65,19 @@ void WindowProxy::ClearForClose() {
DisposeContext(lifecycle_ == Lifecycle::kV8MemoryIsForciblyPurged
? Lifecycle::kFrameIsDetachedAndV8MemoryIsPurged
: Lifecycle::kFrameIsDetached,
- kFrameWillNotBeReused,
- v8::Context::DetachedWindowReason::kDetachedWindowByClosing);
+ kFrameWillNotBeReused);
}
void WindowProxy::ClearForNavigation() {
- DisposeContext(Lifecycle::kGlobalObjectIsDetached, kFrameWillBeReused,
- v8::Context::kDetachedWindowByNavigation);
+ DisposeContext(Lifecycle::kGlobalObjectIsDetached, kFrameWillBeReused);
}
void WindowProxy::ClearForSwap() {
- // This happens on a navigation between local/remote source.
- DisposeContext(Lifecycle::kGlobalObjectIsDetached, kFrameWillNotBeReused,
- v8::Context::kDetachedWindowByNavigation);
+ DisposeContext(Lifecycle::kGlobalObjectIsDetached, kFrameWillNotBeReused);
}
void WindowProxy::ClearForV8MemoryPurge() {
- DisposeContext(Lifecycle::kV8MemoryIsForciblyPurged, kFrameWillNotBeReused,
- v8::Context::kDetachedWindowByOtherReason);
+ DisposeContext(Lifecycle::kV8MemoryIsForciblyPurged, kFrameWillNotBeReused);
}
v8::Local<v8::Object> WindowProxy::GlobalProxyIfNotDetached() {
@@ -165,18 +160,4 @@ void WindowProxy::InitializeIfNeeded() {
}
}
-v8::Local<v8::Object> WindowProxy::AssociateWithWrapper(
- DOMWindow* window,
- const WrapperTypeInfo* wrapper_type_info,
- v8::Local<v8::Object> wrapper) {
- if (world_->DomDataStore().Set(isolate_, window, wrapper_type_info,
- wrapper)) {
- WrapperTypeInfo::WrapperCreated();
- V8DOMWrapper::SetNativeInfo(isolate_, wrapper, wrapper_type_info, window);
- DCHECK(V8DOMWrapper::HasInternalFieldsSet(wrapper));
- }
- SECURITY_CHECK(ToScriptWrappable(wrapper) == window);
- return wrapper;
-}
-
} // namespace blink
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 777bb67e5f7..ce6aac22126 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
@@ -42,7 +42,6 @@ namespace blink {
class DOMWindow;
class Frame;
-struct WrapperTypeInfo;
// WindowProxy implements the split window model of a window for a frame. In the
// HTML standard, the split window model is composed of the Window interface
@@ -145,7 +144,7 @@ class WindowProxy : public GarbageCollected<WindowProxy> {
public:
virtual ~WindowProxy();
- virtual void Trace(blink::Visitor*);
+ virtual void Trace(Visitor*);
void InitializeIfNeeded();
@@ -256,14 +255,7 @@ class WindowProxy : public GarbageCollected<WindowProxy> {
virtual void Initialize() = 0;
- virtual void DisposeContext(Lifecycle next_status,
- FrameReuseStatus,
- v8::Context::DetachedWindowReason) = 0;
-
- WARN_UNUSED_RESULT v8::Local<v8::Object> AssociateWithWrapper(
- DOMWindow*,
- const WrapperTypeInfo*,
- v8::Local<v8::Object> wrapper);
+ virtual void DisposeContext(Lifecycle next_status, FrameReuseStatus) = 0;
v8::Isolate* GetIsolate() const { return isolate_; }
Frame* GetFrame() const { return frame_.Get(); }
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 b8054889808..ba9845625ea 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(blink::Visitor* visitor) {
+void WindowProxyManager::Trace(Visitor* visitor) {
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 51190eeb9f6..2022f70d723 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(blink::Visitor*);
+ void Trace(Visitor*);
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 1463b2baaf9..83db0d2cba8 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
@@ -66,6 +66,7 @@ class WorkerOrWorkletScriptController::ExecutionState final {
public:
explicit ExecutionState(WorkerOrWorkletScriptController* controller)
: had_exception(false),
+ error_event_from_imported_script_(nullptr),
controller_(controller),
outer_state_(controller->execution_state_) {
controller_->execution_state_ = this;
@@ -77,7 +78,7 @@ class WorkerOrWorkletScriptController::ExecutionState final {
String error_message;
std::unique_ptr<SourceLocation> location_;
ScriptValue exception;
- Member<ErrorEvent> error_event_from_imported_script_;
+ ErrorEvent* error_event_from_imported_script_;
// A ExecutionState context is stack allocated by
// WorkerOrWorkletScriptController::evaluate(), with the contoller using it
@@ -90,7 +91,7 @@ class WorkerOrWorkletScriptController::ExecutionState final {
//
// With Oilpan, |outer_state_| isn't traced. It'll be "up the stack"
// and its fields will be traced when scanning the stack.
- Member<WorkerOrWorkletScriptController> controller_;
+ WorkerOrWorkletScriptController* controller_;
ExecutionState* outer_state_;
};
@@ -257,8 +258,9 @@ void WorkerOrWorkletScriptController::Initialize(const KURL& url_for_debugger) {
// before WorkerOrWorkletScriptController::Initialize(). Therefore, we
// ignore the first call of PrepareForEvaluation() from
// WorkerGlobalScope::Initialize(), and call it here again.
- // TODO(nhiroki): Remove this workaround once off-the-main-thread worker
- // script fetch is enabled by default for all worker types.
+ // TODO(https://crbug.com/835717): Remove this workaround once
+ // off-the-main-thread worker script fetch is enabled by default for dedicated
+ // workers.
//
// - For worklets, there is no appropriate timing to call
// PrepareForEvaluation() other than here because worklets have various
@@ -267,8 +269,9 @@ void WorkerOrWorkletScriptController::Initialize(const KURL& url_for_debugger) {
// addModule() call in JS).
// TODO(nhiroki): Unify worklet initialization sequences, and move this to an
// appropriate place.
- if (global_scope_->GetOffMainThreadWorkerScriptFetchOption() ==
- OffMainThreadWorkerScriptFetchOption::kDisabled ||
+ if ((global_scope_->IsWorkerGlobalScope() &&
+ To<WorkerGlobalScope>(global_scope_.Get())
+ ->IsOffMainThreadScriptFetchDisabled()) ||
global_scope_->IsWorkletGlobalScope()) {
// This should be called after origin trial tokens are applied for
// OriginTrialContext in WorkerGlobalScope::Initialize() to install origin
@@ -282,13 +285,13 @@ void WorkerOrWorkletScriptController::Initialize(const KURL& url_for_debugger) {
void WorkerOrWorkletScriptController::PrepareForEvaluation() {
if (!IsContextInitialized()) {
- // For workers with off-the-main-thread worker script fetch, this can be
+ // For workers with on-the-main-thread worker script fetch, this can be
// called before WorkerOrWorkletScriptController::Initialize() via
// WorkerGlobalScope creation function. In this case, PrepareForEvaluation()
// calls this function again. See comments in PrepareForEvaluation().
DCHECK(global_scope_->IsWorkerGlobalScope());
- DCHECK_EQ(OffMainThreadWorkerScriptFetchOption::kDisabled,
- global_scope_->GetOffMainThreadWorkerScriptFetchOption());
+ DCHECK(To<WorkerGlobalScope>(global_scope_.Get())
+ ->IsOffMainThreadScriptFetchDisabled());
return;
}
DCHECK(!is_ready_to_evaluate_);
@@ -412,7 +415,8 @@ bool WorkerOrWorkletScriptController::Evaluate(
if (error_event) {
if (state.error_event_from_imported_script_) {
// Propagate inner error event outwards.
- *error_event = state.error_event_from_imported_script_.Release();
+ *error_event = state.error_event_from_imported_script_;
+ state.error_event_from_imported_script_ = nullptr;
return false;
}
if (sanitize_script_errors == SanitizeScriptErrors::kSanitize) {
@@ -426,7 +430,8 @@ bool WorkerOrWorkletScriptController::Evaluate(
DCHECK_EQ(sanitize_script_errors, SanitizeScriptErrors::kDoNotSanitize);
ErrorEvent* event = nullptr;
if (state.error_event_from_imported_script_) {
- event = state.error_event_from_imported_script_.Release();
+ event = state.error_event_from_imported_script_;
+ state.error_event_from_imported_script_ = nullptr;
} else {
event =
ErrorEvent::Create(state.error_message, state.location_->Clone(),
@@ -486,7 +491,7 @@ void WorkerOrWorkletScriptController::RethrowExceptionFromImportedScript(
error_event->error(script_state_).V8ValueFor(script_state_));
}
-void WorkerOrWorkletScriptController::Trace(blink::Visitor* visitor) {
+void WorkerOrWorkletScriptController::Trace(Visitor* visitor) {
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 b4d37783935..cca5d53e0c4 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(blink::Visitor*);
+ void Trace(Visitor*);
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 20b5677af71..41ea8d61481 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
@@ -57,9 +57,11 @@ class WorldSafeV8Reference final {
public:
WorldSafeV8Reference() = default;
- explicit WorldSafeV8Reference(v8::Isolate* isolate, v8::Local<V8Type> value)
- : v8_reference_(isolate, value) {
- DCHECK(!value.IsEmpty());
+ WorldSafeV8Reference(v8::Isolate* isolate, v8::Local<V8Type> value) {
+ if (value.IsEmpty())
+ return;
+
+ v8_reference_.Set(isolate, value);
// Basically, |world_| is a world when this V8 reference is created.
// However, when this V8 reference isn't created in context and value is
// object, we set |world_| to a value's creation cotext's world.
@@ -124,7 +126,7 @@ class WorldSafeV8Reference final {
bool IsEmpty() const { return v8_reference_.IsEmpty(); }
- void Trace(blink::Visitor* visitor) { visitor->Trace(v8_reference_); }
+ void Trace(Visitor* visitor) { 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
new file mode 100644
index 00000000000..ca15f1f2d16
--- /dev/null
+++ b/chromium/third_party/blink/renderer/bindings/generated_in_core.gni
@@ -0,0 +1,1099 @@
+# 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.
+
+generated_enumeration_sources_in_core = [
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_address_space.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_address_space.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_align_setting.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_align_setting.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_animation_play_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_animation_play_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_auto_keyword.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_auto_keyword.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_can_play_type_result.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_can_play_type_result.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_canvas_color_space.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_canvas_color_space.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_color_space_conversion.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_color_space_conversion.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_composite_operation.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_composite_operation.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_composite_operation_or_auto.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_composite_operation_or_auto.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_math_operator.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_math_operator.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_numeric_base_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_numeric_base_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_direction_setting.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_direction_setting.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_document_ready_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_document_ready_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_edit_context_enter_key_hint.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_edit_context_enter_key_hint.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_edit_context_input_mode.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_edit_context_input_mode.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_edit_context_input_panel_policy.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_edit_context_input_panel_policy.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_ending_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_ending_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_fill_mode.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_fill_mode.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_font_face_load_status.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_font_face_load_status.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_font_face_set_load_status.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_font_face_set_load_status.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_form_state_restore_mode.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_form_state_restore_mode.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_fullscreen_navigation_ui.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_fullscreen_navigation_ui.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_pixel_format.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_pixel_format.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_image_color_space.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_image_color_space.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_image_data_storage_format.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_image_data_storage_format.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_image_orientation.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_image_orientation.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_image_pixel_format.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_image_pixel_format.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo_scope.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo_scope.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_native_scroll_behavior.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_native_scroll_behavior.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_playback_direction.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_playback_direction.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_premultiply_alpha.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_premultiply_alpha.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_referrer_policy.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_referrer_policy.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_replace_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_replace_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_cache.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_cache.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_credentials.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_credentials.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_destination.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_destination.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_importance.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_importance.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_mode.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_mode.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_redirect.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_redirect.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_resize_observer_box_options.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_resize_observer_box_options.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_resize_quality.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_resize_quality.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_response_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_response_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_behavior.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_behavior.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_direction.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_direction.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_logical_position.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_logical_position.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_restoration.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_restoration.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_setting.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_setting.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_auto_keyword.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_auto_keyword.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_security_policy_violation_event_disposition.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_security_policy_violation_event_disposition.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_selection_mode.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_selection_mode.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_shadow_root_mode.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_shadow_root_mode.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_slot_assignment_mode.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_slot_assignment_mode.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_supported_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_supported_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text_track_kind.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text_track_kind.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text_track_mode.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text_track_mode.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_visibility_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_visibility_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_worker_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_worker_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_xml_http_request_response_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_xml_http_request_response_type.h",
+]
+
+generated_interface_sources_in_core = [
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_abort_controller.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_abort_controller.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_abort_signal.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_abort_signal.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_accessible_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_accessible_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_accessible_node_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_accessible_node_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_activate_invisible_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_activate_invisible_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_animation.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_animation.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_animation_effect.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_animation_effect.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_animation_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_animation_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_animation_playback_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_animation_playback_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_animation_timeline.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_animation_timeline.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_application_cache.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_application_cache.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_application_cache_error_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_application_cache_error_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_attr.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_attr.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_audio_track.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_audio_track.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_audio_track_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_audio_track_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_bar_prop.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_bar_prop.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_before_unload_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_before_unload_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_blob.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_blob.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_byte_length_queuing_strategy.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_byte_length_queuing_strategy.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_cdata_section.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_cdata_section.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_character_data.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_character_data.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_clipboard_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_clipboard_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_color_page_popup_controller.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_color_page_popup_controller.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_comment.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_comment.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_composition_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_composition_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_computed_accessible_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_computed_accessible_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_count_queuing_strategy.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_count_queuing_strategy.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_csp_violation_report_body.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_csp_violation_report_body.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_animation.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_animation.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_condition_rule.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_condition_rule.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_font_face_rule.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_font_face_rule.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_grouping_rule.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_grouping_rule.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_image_value.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_image_value.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_import_rule.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_import_rule.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_keyframe_rule.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_keyframe_rule.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_keyframes_rule.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_keyframes_rule.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_keyword_value.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_keyword_value.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_math_invert.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_math_invert.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_math_max.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_math_max.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_math_min.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_math_min.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_math_negate.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_math_negate.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_math_product.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_math_product.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_math_sum.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_math_sum.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_math_value.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_math_value.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_matrix_component.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_matrix_component.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_media_rule.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_media_rule.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_namespace_rule.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_namespace_rule.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_numeric_array.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_numeric_array.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_numeric_value.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_numeric_value.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_page_rule.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_page_rule.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_perspective.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_perspective.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_position_value.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_position_value.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_property_rule.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_property_rule.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_rotate.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_rotate.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_rule.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_rule.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_rule_list.cc",
+ "$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_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",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_skew_x.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_skew_y.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_skew_y.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_style_declaration.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_style_declaration.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_style_rule.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_style_rule.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_style_sheet.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_style_sheet.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_style_value.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_style_value.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_supports_rule.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_supports_rule.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_transform_component.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_transform_component.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_transform_value.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_transform_value.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_transition.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_transition.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_translate.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_translate.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_unit_value.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_unit_value.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_unparsed_value.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_unparsed_value.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_variable_reference_value.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_variable_reference_value.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_viewport_rule.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_viewport_rule.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_custom_element_registry.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_custom_element_registry.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_custom_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_custom_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_data_transfer.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_data_transfer.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_data_transfer_item.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_data_transfer_item.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_data_transfer_item_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_data_transfer_item_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dedicated_worker_global_scope.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dedicated_worker_global_scope.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_deprecation_report_body.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_deprecation_report_body.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dev_tools_host.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dev_tools_host.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_document.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_document.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_document_fragment.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_document_fragment.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_document_policy_violation_report_body.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_document_policy_violation_report_body.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_document_timeline.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_document_timeline.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_document_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_document_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_exception.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_implementation.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_implementation.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_matrix.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_matrix.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_read_only.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_read_only.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_parser.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_parser.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_point.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_point.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_point_read_only.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_point_read_only.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_quad.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_quad.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_rect.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_rect.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_rect_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_rect_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_rect_read_only.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_rect_read_only.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_string_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_string_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_string_map.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_string_map.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_token_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_token_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_drag_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_drag_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_edit_context.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_edit_context.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_element_internals.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_element_internals.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_error_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_error_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_event_target.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_event_target.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_external.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_external.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_feature_policy.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_feature_policy.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_feature_policy_violation_report_body.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_feature_policy_violation_report_body.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_file.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_file.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_file_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_file_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_file_reader.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_file_reader.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_file_reader_sync.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_file_reader_sync.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_focus_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_focus_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_font_face.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_font_face.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_font_face_set.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_font_face_set.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_font_face_set_load_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_font_face_set_load_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_form_data.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_form_data.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_form_data_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_form_data_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_fragment_directive.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_fragment_directive.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_hash_change_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_hash_change_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_headers.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_headers.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_history.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_history.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_all_collection.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_all_collection.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_anchor_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_anchor_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_area_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_area_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_audio_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_audio_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_base_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_base_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_body_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_body_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_br_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_br_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_button_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_button_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_canvas_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_canvas_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_collection.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_collection.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_content_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_content_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_data_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_data_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_data_list_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_data_list_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_details_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_details_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_dialog_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_dialog_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_directory_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_directory_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_div_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_div_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_dlist_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_dlist_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_document.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_document.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_embed_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_embed_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_field_set_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_field_set_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_font_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_font_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_form_controls_collection.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_form_controls_collection.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_form_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_form_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_frame_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_frame_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_frame_set_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_frame_set_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_head_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_head_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_heading_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_heading_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_hr_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_hr_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_html_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_html_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_iframe_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_iframe_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_image_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_image_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_input_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_input_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_label_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_label_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_legend_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_legend_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_li_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_li_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_link_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_link_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_map_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_map_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_marquee_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_marquee_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_media_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_media_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_menu_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_menu_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_meta_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_meta_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_meter_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_meter_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_mod_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_mod_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_object_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_object_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_olist_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_olist_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_opt_group_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_opt_group_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_option_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_option_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_options_collection.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_options_collection.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_output_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_output_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_paragraph_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_paragraph_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_param_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_param_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_picture_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_picture_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_portal_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_portal_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_pre_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_pre_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_progress_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_progress_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_quote_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_quote_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_script_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_script_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_select_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_select_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_shadow_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_shadow_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_slot_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_slot_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_source_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_source_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_span_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_span_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_style_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_style_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_table_caption_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_table_caption_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_table_cell_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_table_cell_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_table_col_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_table_col_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_table_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_table_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_table_row_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_table_row_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_table_section_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_table_section_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_template_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_template_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_text_area_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_text_area_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_time_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_time_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_title_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_title_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_track_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_track_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_ulist_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_ulist_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_unknown_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_unknown_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_video_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_html_video_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_idle_deadline.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_idle_deadline.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_image_bitmap.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_image_bitmap.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_image_data.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_image_data.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_input_device_capabilities.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_input_device_capabilities.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_input_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_input_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_inspector_overlay_host.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_inspector_overlay_host.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_entry.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_entry.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_intervention_report_body.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_intervention_report_body.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_intrinsic_sizes.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_intrinsic_sizes.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_iterator.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_iterator.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_keyboard_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_keyboard_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_keyframe_effect.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_keyframe_effect.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_largest_contentful_paint.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_largest_contentful_paint.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_layout_child.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_layout_child.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_layout_constraints.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_layout_constraints.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_layout_edges.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_layout_edges.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_layout_fragment.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_layout_fragment.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_layout_shift.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_layout_shift.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_layout_worklet_global_scope.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_layout_worklet_global_scope.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_location.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_location.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mathml_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mathml_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_media_error.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_media_error.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_media_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_media_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_media_query_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_media_query_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_media_query_list_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_media_query_list_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_memory_info.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_memory_info.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_message_channel.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_message_channel.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_message_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_message_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_message_port.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_message_port.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo_handle.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo_handle.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo_interface_interceptor.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo_interface_interceptor.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo_interface_request_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo_interface_request_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo_watcher.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo_watcher.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mouse_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mouse_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mutation_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mutation_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mutation_observer.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mutation_observer.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mutation_record.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mutation_record.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_named_node_map.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_named_node_map.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigator.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigator.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigator_ua_data.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigator_ua_data.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_node_iterator.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_node_iterator.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_node_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_node_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_offscreen_canvas.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_offscreen_canvas.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_overscroll_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_overscroll_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_page_popup_controller.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_page_popup_controller.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_page_transition_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_page_transition_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_element_timing.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_element_timing.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_entry.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_entry.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_event_timing.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_event_timing.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_long_task_timing.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_long_task_timing.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_mark.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_mark.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_measure.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_measure.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_navigation.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_navigation.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_navigation_timing.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_navigation_timing.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_observer.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_observer.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_observer_entry_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_observer_entry_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_paint_timing.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_paint_timing.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_resource_timing.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_resource_timing.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_server_timing.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_server_timing.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_timing.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_timing.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_pointer_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_pointer_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_pop_state_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_pop_state_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_portal_activate_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_portal_activate_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_portal_host.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_portal_host.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_processing_instruction.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_processing_instruction.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_profiler.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_profiler.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_progress_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_progress_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_promise_rejection_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_promise_rejection_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_radio_node_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_radio_node_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_range.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_range.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_readable_stream.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_readable_stream.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_readable_stream_default_controller.cc",
+ "$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",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_report_body.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_reporting_observer.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_reporting_observer.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_resize_observer.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_resize_observer.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_resize_observer_entry.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_resize_observer_entry.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_resize_observer_size.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_resize_observer_size.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_resource_progress_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_resource_progress_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_response.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_response.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scheduling.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scheduling.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_screen.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_screen.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_security_policy_violation_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_security_policy_violation_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_selection.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_selection.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_shadow_root.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_shadow_root.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_shared_worker.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_shared_worker.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_shared_worker_global_scope.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_shared_worker_global_scope.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_static_range.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_static_range.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_style_media.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_style_media.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_style_property_map.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_style_property_map.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_style_property_map_read_only.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_style_property_map_read_only.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_style_sheet.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_style_sheet.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_style_sheet_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_style_sheet_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_submit_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_submit_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_a_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_a_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_angle.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_angle.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animate_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animate_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animate_motion_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animate_motion_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animate_transform_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animate_transform_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_angle.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_angle.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_boolean.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_boolean.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_enumeration.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_enumeration.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_integer.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_integer.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_length.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_length.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_length_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_length_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_number.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_number.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_number_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_number_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_preserve_aspect_ratio.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_preserve_aspect_ratio.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_rect.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_rect.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_string.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_string.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_transform_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animated_transform_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animation_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_animation_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_circle_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_circle_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_clip_path_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_clip_path_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_component_transfer_function_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_component_transfer_function_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_defs_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_defs_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_desc_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_desc_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_ellipse_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_ellipse_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_blend_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_blend_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_color_matrix_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_color_matrix_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_component_transfer_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_component_transfer_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_composite_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_composite_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_convolve_matrix_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_convolve_matrix_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_diffuse_lighting_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_diffuse_lighting_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_displacement_map_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_displacement_map_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_distant_light_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_distant_light_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_drop_shadow_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_drop_shadow_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_flood_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_flood_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_func_a_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_func_a_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_func_b_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_func_b_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_func_g_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_func_g_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_func_r_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_func_r_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_gaussian_blur_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_gaussian_blur_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_image_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_image_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_merge_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_merge_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_merge_node_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_merge_node_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_morphology_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_morphology_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_offset_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_offset_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_point_light_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_point_light_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_specular_lighting_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_specular_lighting_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_spot_light_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_spot_light_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_tile_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_tile_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_turbulence_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_fe_turbulence_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_filter_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_filter_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_foreign_object_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_foreign_object_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_g_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_g_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_geometry_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_geometry_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_gradient_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_gradient_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_graphics_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_graphics_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_image_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_image_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_length.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_length.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_length_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_length_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_line_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_line_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_linear_gradient_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_linear_gradient_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_marker_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_marker_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_mask_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_mask_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_matrix.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_matrix.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_metadata_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_metadata_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_mpath_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_mpath_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_number.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_number.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_number_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_number_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_path_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_path_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_pattern_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_pattern_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_point.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_point.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_point_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_point_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_polygon_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_polygon_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_polyline_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_polyline_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_preserve_aspect_ratio.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_preserve_aspect_ratio.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_radial_gradient_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_radial_gradient_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_rect.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_rect.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_rect_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_rect_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_script_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_script_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_set_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_set_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_stop_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_stop_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_string_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_string_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_style_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_style_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_svg_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_svg_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_switch_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_switch_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_symbol_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_symbol_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_text_content_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_text_content_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_text_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_text_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_text_path_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_text_path_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_text_positioning_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_text_positioning_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_title_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_title_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_transform.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_transform.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_transform_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_transform_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_tspan_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_tspan_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_unit_types.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_unit_types.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_use_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_use_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_view_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_svg_view_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_task_attribution_timing.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_task_attribution_timing.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_test_report_body.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_test_report_body.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text_format_update_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text_format_update_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text_metrics.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text_metrics.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text_track.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text_track.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text_track_cue.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text_track_cue.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text_track_cue_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text_track_cue_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text_track_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text_track_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text_update_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text_update_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_time_ranges.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_time_ranges.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_touch.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_touch.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_touch_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_touch_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_touch_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_touch_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_track_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_track_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_transform_stream.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_transform_stream.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_transform_stream_default_controller.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_transform_stream_default_controller.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_transition_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_transition_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_tree_walker.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_tree_walker.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_trusted_html.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_trusted_html.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_trusted_script.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_trusted_script.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_trusted_script_url.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_trusted_script_url.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_trusted_type_policy.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_trusted_type_policy.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_trusted_type_policy_factory.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_trusted_type_policy_factory.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_ui_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_ui_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_underlying_sink_base.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_underlying_sink_base.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_underlying_source_base.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_underlying_source_base.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_url.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_url.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_url_search_params.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_url_search_params.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_user_activation.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_user_activation.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_validity_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_validity_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_video_track.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_video_track.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_video_track_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_video_track_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_visual_viewport.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_visual_viewport.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_vtt_cue.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_vtt_cue.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_vtt_region.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_vtt_region.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_wheel_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_wheel_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_window.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_window.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_worker.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_worker.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_worker_global_scope.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_worker_global_scope.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_worker_location.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_worker_location.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_worker_navigator.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_worker_navigator.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_worklet.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_worklet.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_worklet_global_scope.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_worklet_global_scope.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_writable_stream.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_writable_stream.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_writable_stream_default_controller.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_writable_stream_default_controller.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_writable_stream_default_writer.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_writable_stream_default_writer.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_xml_document.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_xml_document.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_xml_http_request.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_xml_http_request.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_xml_http_request_event_target.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_xml_http_request_event_target.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_xml_http_request_upload.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_xml_http_request_upload.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_xml_serializer.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_xml_serializer.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_xpath_evaluator.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_xpath_evaluator.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_xpath_expression.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_xpath_expression.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_xpath_ns_resolver.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_xpath_ns_resolver.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_xpath_result.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_xpath_result.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_xslt_processor.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_xslt_processor.h",
+]
+
+# Generated sources for testing
+
+generated_enumeration_sources_for_testing_in_core = [
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_food_enum.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_food_enum.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_internal_enum.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_internal_enum.h",
+]
+
+generated_interface_sources_for_testing_in_core = [
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_callback_function_test.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_callback_function_test.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_death_aware_script_wrappable.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_death_aware_script_wrappable.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dictionary_test.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dictionary_test.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_garbage_collected_script_wrappable.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_garbage_collected_script_wrappable.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_gc_observation.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_gc_observation.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_hit_test_layer_rect.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_hit_test_layer_rect.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_hit_test_layer_rect_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_hit_test_layer_rect_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_internal_runtime_flags.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_internal_runtime_flags.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_internal_settings.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_internal_settings.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_internal_settings_generated.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_internal_settings_generated.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_internals.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_internals.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_origin_trials_test.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_origin_trials_test.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_record_test.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_record_test.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_sequence_test.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_sequence_test.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_static_selection.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_static_selection.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_type_conversions.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_type_conversions.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_types_test.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_types_test.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_worker_internals.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_worker_internals.h",
+]
diff --git a/chromium/third_party/blink/renderer/bindings/generated_in_modules.gni b/chromium/third_party/blink/renderer/bindings/generated_in_modules.gni
new file mode 100644
index 00000000000..fac8c3dbc31
--- /dev/null
+++ b/chromium/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -0,0 +1,1373 @@
+# 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.
+
+generated_enumeration_sources_in_modules = [
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_app_banner_prompt_outcome.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_app_banner_prompt_outcome.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_append_mode.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_append_mode.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_attestation_conveyance_preference.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_attestation_conveyance_preference.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_context_latency_category.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_context_latency_category.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_context_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_context_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_authenticator_attachment.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_authenticator_attachment.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_automation_rate.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_automation_rate.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_background_fetch_failure_reason.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_background_fetch_failure_reason.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_background_fetch_result.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_background_fetch_result.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_barcode_format.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_barcode_format.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_binary_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_binary_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_biquad_filter_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_biquad_filter_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_canvas_fill_rule.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_canvas_fill_rule.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_canvas_pixel_format.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_canvas_pixel_format.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_canvas_power_preference.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_canvas_power_preference.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_channel_count_mode.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_channel_count_mode.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_channel_interpretation.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_channel_interpretation.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_choose_file_system_entries_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_choose_file_system_entries_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_client_lifecycle_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_client_lifecycle_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_client_lifecycle_state_query.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_client_lifecycle_state_query.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_client_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_client_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_connection_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_connection_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_contact_property.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_contact_property.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_content_category.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_content_category.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_context_frame_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_context_frame_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cookie_match_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cookie_match_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cookie_same_site.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cookie_same_site.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_credential_mediation_requirement.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_credential_mediation_requirement.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_distance_model_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_distance_model_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_effective_connection_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_effective_connection_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_encoded_video_chunk_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_encoded_video_chunk_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_end_of_stream_error.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_end_of_stream_error.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_fill_light_mode.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_fill_light_mode.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_haptic_actuator_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_haptic_actuator_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_haptic_effect_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_haptic_effect_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_haptics_result.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_haptics_result.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_mapping_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_mapping_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_address_mode.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_address_mode.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_binding_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_binding_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_blend_factor.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_blend_factor.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_blend_operation.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_blend_operation.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_compare_function.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_compare_function.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_cull_mode.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_cull_mode.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_error_filter.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_error_filter.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_filter_mode.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_filter_mode.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_front_face.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_front_face.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_index_format.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_index_format.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_input_step_mode.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_input_step_mode.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_load_op.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_load_op.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_power_preference.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_power_preference.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_primitive_topology.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_primitive_topology.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_stencil_operation.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_stencil_operation.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_store_op.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_store_op.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_aspect.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_aspect.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_component_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_component_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_dimension.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_dimension.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_format.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_format.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_view_dimension.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_view_dimension.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_vertex_format.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_vertex_format.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_unit_system.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_unit_system.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_cursor_direction.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_cursor_direction.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_data_loss_amount.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_data_loss_amount.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_observation_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_observation_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_request_ready_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_request_ready_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_transaction_durability.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_transaction_durability.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_transaction_mode.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_transaction_mode.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_image_smoothing_quality.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_image_smoothing_quality.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_landmark_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_landmark_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_local_coordinate_system.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_local_coordinate_system.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_lock_mode.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_lock_mode.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_decoding_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_decoding_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_device_kind.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_device_kind.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_encoding_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_encoding_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_key_message_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_key_message_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_key_session_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_key_session_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_key_status.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_key_status.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_keys_requirement.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_keys_requirement.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_session_action.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_session_action.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_session_playback_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_session_playback_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_stream_track_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_stream_track_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_metering_mode.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_metering_mode.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_port_connection_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_port_connection_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_port_device_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_port_device_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_port_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_port_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_notification_action_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_notification_action_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_notification_direction.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_notification_direction.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_notification_permission.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_notification_permission.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_offscreen_rendering_context_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_offscreen_rendering_context_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_orientation_lock_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_orientation_lock_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_orientation_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_orientation_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oscillator_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oscillator_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_over_sample_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_over_sample_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_panning_model_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_panning_model_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_payment_complete.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_payment_complete.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_payment_delegation.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_payment_delegation.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_payment_shipping_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_payment_shipping_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_permission_name.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_permission_name.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_permission_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_permission_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation_connection_close_reason.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation_connection_close_reason.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation_connection_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation_connection_state.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_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",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_permission_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_recording_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_recording_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_red_eye_reduction.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_red_eye_reduction.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_remote_playback_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_remote_playback_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_bundle_policy.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_bundle_policy.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_data_channel_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_data_channel_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_dtls_transport_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_dtls_transport_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_error_detail_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_error_detail_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_candidate_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_candidate_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_component.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_component.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_connection_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_connection_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_gathering_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_gathering_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_protocol.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_protocol.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_role.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_role.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_tcp_candidate_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_tcp_candidate_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_transport_policy.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_transport_policy.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_transport_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_transport_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_peer_connection_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_peer_connection_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_priority_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_priority_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_quic_role.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_quic_role.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_quic_stream_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_quic_stream_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_quic_transport_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_quic_transport_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtcp_mux_policy.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtcp_mux_policy.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_transceiver_direction.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_transceiver_direction.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_sctp_transport_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_sctp_transport_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_sdp_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_sdp_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_signaling_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_signaling_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_screen_idle_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_screen_idle_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sdp_semantics.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sdp_semantics.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_service_worker_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_service_worker_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_service_worker_update_via_cache.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_service_worker_update_via_cache.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_synthesis_error_code.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_synthesis_error_code.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_system_directory_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_system_directory_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_task_priority.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_task_priority.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_track_default_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_track_default_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_direction.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_direction.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_endpoint_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_endpoint_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_recipient.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_recipient.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_request_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_request_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_transfer_status.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_transfer_status.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_user_idle_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_user_idle_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_user_verification_requirement.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_user_verification_requirement.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_wake_lock_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_wake_lock_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_power_preference.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_power_preference.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_write_command_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_write_command_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_dom_overlay_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_dom_overlay_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_environment_blend_mode.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_environment_blend_mode.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_eye.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_eye.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_handedness.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_handedness.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_hit_test_trackable_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_hit_test_trackable_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_plane_orientation.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_plane_orientation.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_reference_space_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_reference_space_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_session_mode.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_session_mode.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_target_ray_mode.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_target_ray_mode.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_visibility_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_visibility_state.h",
+]
+
+generated_interface_sources_in_modules = [
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_abort_payment_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_abort_payment_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_absolute_orientation_sensor.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_absolute_orientation_sensor.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_accelerometer.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_accelerometer.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ambient_light_sensor.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ambient_light_sensor.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_analyser_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_analyser_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_angle_instanced_arrays.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_angle_instanced_arrays.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_animation_worklet_global_scope.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_animation_worklet_global_scope.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_buffer.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_buffer.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_buffer_source_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_buffer_source_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_context.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_context.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_destination_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_destination_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_listener.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_listener.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_param.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_param.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_param_map.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_param_map.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_processing_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_processing_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_scheduled_source_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_scheduled_source_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_track.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_track.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_worklet.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_worklet.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_worklet_global_scope.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_worklet_global_scope.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_worklet_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_worklet_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_worklet_processor.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_worklet_processor.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_authenticator_assertion_response.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_authenticator_assertion_response.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_authenticator_attestation_response.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_authenticator_attestation_response.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_authenticator_response.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_authenticator_response.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_background_fetch_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_background_fetch_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_background_fetch_manager.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_background_fetch_manager.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_background_fetch_record.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_background_fetch_record.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_background_fetch_registration.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_background_fetch_registration.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_background_fetch_update_ui_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_background_fetch_update_ui_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_barcode_detector.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_barcode_detector.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_base_audio_context.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_base_audio_context.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_battery_manager.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_battery_manager.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_before_install_prompt_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_before_install_prompt_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_biquad_filter_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_biquad_filter_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_blob_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_blob_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_advertising_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_advertising_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_characteristic_properties.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_characteristic_properties.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_device.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_device.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_le_scan.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_le_scan.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_manufacturer_data_map.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_manufacturer_data_map.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_remote_gatt_characteristic.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_remote_gatt_characteristic.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_remote_gatt_descriptor.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_remote_gatt_descriptor.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_remote_gatt_server.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_remote_gatt_server.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_remote_gatt_service.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_remote_gatt_service.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_service_data_map.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_service_data_map.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_uuid.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_uuid.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_broadcast_channel.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_broadcast_channel.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cache.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cache.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cache_storage.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cache_storage.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_can_make_payment_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_can_make_payment_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_canvas_capture_media_stream_track.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_canvas_capture_media_stream_track.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_canvas_gradient.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_canvas_gradient.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_canvas_pattern.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_canvas_pattern.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_canvas_rendering_context_2d.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_canvas_rendering_context_2d.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_channel_merger_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_channel_merger_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_channel_splitter_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_channel_splitter_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_client.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_client.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_clients.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_clients.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_clipboard.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_clipboard.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_clipboard_item.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_clipboard_item.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_close_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_close_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_compression_stream.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_compression_stream.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_constant_source_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_constant_source_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_contact_address.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_contact_address.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_contacts_manager.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_contacts_manager.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_content_index.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_content_index.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_content_index_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_content_index_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_convolver_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_convolver_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cookie_change_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cookie_change_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cookie_store.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cookie_store.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cookie_store_manager.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_cookie_store_manager.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_credential.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_credential.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_credentials_container.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_credentials_container.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_crypto.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_crypto.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_crypto_key.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_crypto_key.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_css.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_css.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_data_transfer_item.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_data_transfer_item.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_database.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_database.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_decompression_stream.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_decompression_stream.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_dedicated_worker_global_scope.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_dedicated_worker_global_scope.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_delay_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_delay_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_deprecated_storage_info.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_deprecated_storage_info.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_deprecated_storage_quota.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_deprecated_storage_quota.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_dev_tools_host.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_dev_tools_host.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_device_motion_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_device_motion_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_device_motion_event_acceleration.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_device_motion_event_acceleration.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_device_motion_event_rotation_rate.cc",
+ "$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_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",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_directory_entry_sync.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_directory_reader.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_directory_reader.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_directory_reader_sync.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_directory_reader_sync.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_document.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_document.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_dom_error.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_dom_error.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_dom_file_system.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_dom_file_system.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_dom_file_system_sync.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_dom_file_system_sync.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_dynamics_compressor_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_dynamics_compressor_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_element.cc",
+ "$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_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",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_entry_sync.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_event_source.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_event_source.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_blend_min_max.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_blend_min_max.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_color_buffer_float.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_color_buffer_float.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_color_buffer_half_float.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_color_buffer_half_float.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_disjoint_timer_query.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_disjoint_timer_query.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_disjoint_timer_query_webgl2.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_disjoint_timer_query_webgl2.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_float_blend.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_float_blend.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_frag_depth.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_frag_depth.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_shader_texture_lod.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_shader_texture_lod.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_srgb.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_srgb.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_texture_compression_bptc.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_texture_compression_bptc.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_texture_compression_rgtc.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_texture_compression_rgtc.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_texture_filter_anisotropic.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_texture_filter_anisotropic.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_texture_norm_16.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ext_texture_norm_16.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_extendable_cookie_change_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_extendable_cookie_change_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_extendable_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_extendable_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_extendable_message_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_extendable_message_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_face_detector.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_face_detector.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_federated_credential.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_federated_credential.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_fetch_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_fetch_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_entry.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_entry.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_entry_sync.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_entry_sync.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_system_directory_handle.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_system_directory_handle.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_system_file_handle.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_system_file_handle.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_system_handle.cc",
+ "$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",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_writer_sync.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_font_iterator.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_font_iterator.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_font_manager.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_font_manager.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_font_metadata.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_font_metadata.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gain_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gain_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_axis_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_axis_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_button.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_button.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_button_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_button_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_haptic_actuator.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_haptic_actuator.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_geolocation.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_geolocation.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_geolocation_coordinates.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_geolocation_coordinates.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_geolocation_position.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_geolocation_position.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_geolocation_position_error.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_geolocation_position_error.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_adapter.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_adapter.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_bind_group.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_bind_group.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_bind_group_layout.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_bind_group_layout.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_buffer.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_buffer.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_buffer_usage.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_buffer_usage.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_canvas_context.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_canvas_context.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_color_write.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_color_write.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_command_buffer.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_command_buffer.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_command_encoder.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_command_encoder.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_compute_pass_encoder.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_compute_pass_encoder.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_compute_pipeline.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_compute_pipeline.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_device.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_device.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_device_lost_info.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_device_lost_info.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_fence.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_fence.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_out_of_memory_error.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_out_of_memory_error.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_pipeline_layout.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_pipeline_layout.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_queue.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_queue.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_render_bundle.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_render_bundle.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_render_bundle_encoder.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_render_bundle_encoder.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_render_pass_encoder.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_render_pass_encoder.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_render_pipeline.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_render_pipeline.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_sampler.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_sampler.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_shader_module.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_shader_module.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_shader_stage.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_shader_stage.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_swap_chain.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_swap_chain.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_usage.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_usage.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_view.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_view.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_uncaptured_error_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_uncaptured_error_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_validation_error.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_validation_error.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gyroscope.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gyroscope.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_collection_info.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_collection_info.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_connection_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_connection_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_device.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_device.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_input_report_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_input_report_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_report_info.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_report_info.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_report_item.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hid_report_item.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_html_canvas_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_html_canvas_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_html_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_html_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_html_iframe_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_html_iframe_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_html_input_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_html_input_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_html_media_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_html_media_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_html_video_element.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_html_video_element.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_cursor.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_cursor.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_cursor_with_value.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_cursor_with_value.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_database.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_database.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_factory.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_factory.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_index.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_index.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_key_range.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_key_range.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_object_store.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_object_store.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_observation.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_observation.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_observer.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_observer.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_observer_changes.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_observer_changes.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_open_db_request.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_open_db_request.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_request.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_request.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_transaction.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_transaction.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_version_change_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_version_change_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idle_detector.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idle_detector.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idle_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idle_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_iir_filter_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_iir_filter_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_image_bitmap_rendering_context.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_image_bitmap_rendering_context.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_image_capture.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_image_capture.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_input_device_info.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_input_device_info.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_install_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_install_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_keyboard.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_keyboard.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_keyboard_layout_map.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_keyboard_layout_map.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_khr_parallel_shader_compile.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_khr_parallel_shader_compile.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_launch_params.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_launch_params.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_launch_queue.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_launch_queue.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_linear_acceleration_sensor.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_linear_acceleration_sensor.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_lock.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_lock.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_lock_manager.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_lock_manager.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_magnetometer.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_magnetometer.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_capabilities.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_capabilities.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_device_info.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_device_info.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_devices.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_devices.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_element_audio_source_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_element_audio_source_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_encrypted_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_encrypted_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_key_message_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_key_message_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_key_session.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_key_session.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_key_status_map.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_key_status_map.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_key_system_access.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_key_system_access.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_keys.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_keys.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_metadata.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_metadata.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_recorder.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_recorder.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_session.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_session.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_settings_range.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_settings_range.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_source.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_source.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_stream.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_stream.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_stream_audio_destination_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_stream_audio_destination_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_stream_audio_source_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_stream_audio_source_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_stream_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_stream_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_stream_track.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_stream_track.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_stream_track_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_media_stream_track_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_merchant_validation_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_merchant_validation_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_metadata.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_metadata.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_access.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_access.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_connection_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_connection_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_input.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_input.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_input_map.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_input_map.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_message_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_message_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_output.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_output.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_output_map.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_output_map.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_port.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_port.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_mime_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_mime_type.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_mime_type_array.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_mime_type_array.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_native_file_system_directory_iterator.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_native_file_system_directory_iterator.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_native_io_file.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_native_io_file.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_native_io_file_sync.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_native_io_file_sync.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_native_io_manager.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_native_io_manager.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_navigation_preload_manager.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_navigation_preload_manager.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_navigator.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_navigator.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_message.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_message.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_reader.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_reader.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_reading_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_reading_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_record.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_record.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_writer.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_writer.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_network_information.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_network_information.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_notification.cc",
+ "$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_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",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oes_fbo_render_mipmap.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oes_standard_derivatives.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oes_standard_derivatives.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oes_texture_float.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oes_texture_float.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oes_texture_float_linear.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oes_texture_float_linear.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oes_texture_half_float.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oes_texture_half_float.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oes_texture_half_float_linear.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oes_texture_half_float_linear.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oes_vertex_array_object.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oes_vertex_array_object.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_offline_audio_completion_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_offline_audio_completion_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_offline_audio_context.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_offline_audio_context.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_offscreen_canvas.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_offscreen_canvas.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_offscreen_canvas_rendering_context_2d.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_offscreen_canvas_rendering_context_2d.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_orientation_sensor.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_orientation_sensor.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oscillator_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oscillator_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_otp_credential.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_otp_credential.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_overconstrained_error.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_overconstrained_error.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ovr_multiview_2.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ovr_multiview_2.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_paint_rendering_context_2d.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_paint_rendering_context_2d.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_paint_size.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_paint_size.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_paint_worklet_global_scope.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_paint_worklet_global_scope.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_panner_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_panner_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_password_credential.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_password_credential.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_path_2d.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_path_2d.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_payment_address.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_payment_address.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_payment_instruments.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_payment_instruments.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_payment_manager.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_payment_manager.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_payment_method_change_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_payment_method_change_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_payment_request.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_payment_request.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_payment_request_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_payment_request_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_payment_request_update_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_payment_request_update_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_payment_response.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_payment_response.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_periodic_sync_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_periodic_sync_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_periodic_sync_manager.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_periodic_sync_manager.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_periodic_wave.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_periodic_wave.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_permission_status.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_permission_status.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_permissions.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_permissions.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_photo_capabilities.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_photo_capabilities.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_picture_in_picture_window.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_picture_in_picture_window.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_plugin.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_plugin.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_plugin_array.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_plugin_array.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation_availability.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation_availability.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation_connection.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation_connection.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation_connection_available_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation_connection_available_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation_connection_close_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation_connection_close_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation_connection_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation_connection_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation_receiver.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation_receiver.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation_request.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation_request.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_manager.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_manager.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_message_data.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_message_data.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_subscription.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_subscription.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_subscription_change_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_subscription_change_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_subscription_options.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_subscription_options.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_quic_transport.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_quic_transport.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_receive_stream.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_receive_stream.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_relative_orientation_sensor.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_relative_orientation_sensor.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_remote_playback.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_remote_playback.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_certificate.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_certificate.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_data_channel.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_data_channel.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_data_channel_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_data_channel_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_dtls_transport.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_dtls_transport.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_dtmf_sender.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_dtmf_sender.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_dtmf_tone_change_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_dtmf_tone_change_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_encoded_audio_frame.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_encoded_audio_frame.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_encoded_video_frame.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_encoded_video_frame.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_error.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_error.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_error_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_error_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_candidate.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_candidate.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_transport.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_transport.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_legacy_stats_report.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_legacy_stats_report.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_peer_connection.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_peer_connection.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_peer_connection_ice_error_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_peer_connection_ice_error_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_peer_connection_ice_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_peer_connection_ice_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_quic_stream.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_quic_stream.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_quic_stream_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_quic_stream_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_quic_transport.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_quic_transport.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_receiver.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_receiver.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_sender.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_sender.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_transceiver.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_transceiver.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_sctp_transport.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_sctp_transport.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_session_description.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_session_description.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_stats_report.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_stats_report.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_stats_response.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_stats_response.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_track_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_track_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_scheduler.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_scheduler.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_screen.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_screen.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_screen_orientation.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_screen_orientation.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_script_processor_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_script_processor_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_send_stream.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_send_stream.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sensor.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sensor.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sensor_error_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sensor_error_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_service_worker.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_service_worker.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_service_worker_container.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_service_worker_container.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_service_worker_global_scope.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_service_worker_global_scope.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_service_worker_registration.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_service_worker_registration.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_shadow_root.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_shadow_root.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_shared_worker_global_scope.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_shared_worker_global_scope.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_source_buffer.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_source_buffer.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_source_buffer_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_source_buffer_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_grammar.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_grammar.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_grammar_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_grammar_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_recognition.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_recognition.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_recognition_alternative.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_recognition_alternative.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_recognition_error_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_recognition_error_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_recognition_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_recognition_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_recognition_result.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_recognition_result.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_recognition_result_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_recognition_result_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_synthesis.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_synthesis.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_synthesis_error_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_synthesis_error_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_synthesis_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_synthesis_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_synthesis_utterance.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_synthesis_utterance.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_synthesis_voice.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_synthesis_voice.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sql_error.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sql_error.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sql_result_set.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sql_result_set.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sql_result_set_row_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sql_result_set_row_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sql_transaction.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sql_transaction.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_stereo_panner_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_stereo_panner_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_storage.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_storage.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_storage_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_storage_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_storage_manager.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_storage_manager.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_subtle_crypto.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_subtle_crypto.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sync_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sync_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sync_manager.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sync_manager.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_task_controller.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_task_controller.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_task_signal.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_task_signal.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_text_decoder.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_text_decoder.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_text_decoder_stream.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_text_decoder_stream.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_text_detector.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_text_detector.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_text_encoder.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_text_encoder.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_text_encoder_stream.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_text_encoder_stream.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_timestamp_trigger.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_timestamp_trigger.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_track_default.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_track_default.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_track_default_list.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_track_default_list.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_url.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_url.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_alternate_interface.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_alternate_interface.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_configuration.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_configuration.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_connection_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_connection_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_device.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_device.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_endpoint.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_endpoint.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_in_transfer_result.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_in_transfer_result.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_interface.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_interface.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_isochronous_in_transfer_packet.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_isochronous_in_transfer_packet.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_isochronous_in_transfer_result.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_isochronous_in_transfer_result.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_isochronous_out_transfer_packet.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_isochronous_out_transfer_packet.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_isochronous_out_transfer_result.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_isochronous_out_transfer_result.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_out_transfer_result.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_out_transfer_result.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_decoder.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_decoder.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_frame.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_frame.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_playback_quality.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_playback_quality.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_track.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_track.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_track_reader.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_track_reader.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_track_writer.cc",
+ "$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_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",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_wake_lock_sentinel.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_wave_shaper_node.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_wave_shaper_node.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl2_compute_rendering_context.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl2_compute_rendering_context.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl2_rendering_context.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl2_rendering_context.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_active_info.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_active_info.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_buffer.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_buffer.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_color_buffer_float.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_color_buffer_float.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_compressed_texture_astc.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_compressed_texture_astc.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_compressed_texture_etc.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_compressed_texture_etc.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_compressed_texture_etc1.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_compressed_texture_etc1.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_compressed_texture_pvrtc.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_compressed_texture_pvrtc.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_compressed_texture_s3tc.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_compressed_texture_s3tc.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_compressed_texture_s3tc_srgb.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_compressed_texture_s3tc_srgb.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_context_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_context_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_debug_renderer_info.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_debug_renderer_info.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_debug_shaders.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_debug_shaders.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_depth_texture.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_depth_texture.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_draw_buffers.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_draw_buffers.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_draw_instanced_base_vertex_base_instance.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_draw_instanced_base_vertex_base_instance.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_framebuffer.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_framebuffer.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_lose_context.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_lose_context.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_multi_draw.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_multi_draw.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_multi_draw_instanced_base_vertex_base_instance.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_multi_draw_instanced_base_vertex_base_instance.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_program.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_program.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_query.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_query.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_renderbuffer.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_renderbuffer.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_rendering_context.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_rendering_context.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_sampler.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_sampler.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_shader.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_shader.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_shader_precision_format.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_shader_precision_format.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_sync.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_sync.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_texture.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_texture.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_timer_query_ext.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_timer_query_ext.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_transform_feedback.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_transform_feedback.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_uniform_location.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_uniform_location.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_vertex_array_object.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_vertex_array_object.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_vertex_array_object_oes.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_vertex_array_object_oes.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_video_texture.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_video_texture.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_websocket.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_websocket.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_websocket_stream.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_websocket_stream.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_window.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_window.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_window_client.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_window_client.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_worker_global_scope.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_worker_global_scope.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_worker_navigator.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_worker_navigator.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_worklet_animation.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_worklet_animation.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_worklet_animation_effect.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_worklet_animation_effect.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_worklet_group_effect.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_worklet_group_effect.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_anchor.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_anchor.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_anchor_set.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_anchor_set.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_bounded_reference_space.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_bounded_reference_space.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_cube_map.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_cube_map.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_dom_overlay_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_dom_overlay_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_frame.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_frame.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_hit_test_result.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_hit_test_result.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_hit_test_source.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_hit_test_source.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_input_source.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_input_source.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_input_source_array.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_input_source_array.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_input_source_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_input_source_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_input_sources_change_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_input_sources_change_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_light_estimation.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_light_estimation.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_light_estimation_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_light_estimation_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_light_probe.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_light_probe.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_plane.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_plane.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_plane_detection_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_plane_detection_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_plane_set.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_plane_set.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_pose.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_pose.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_ray.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_ray.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_reference_space.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_reference_space.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_reference_space_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_reference_space_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_reflection_probe.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_reflection_probe.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_render_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_render_state.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_rigid_transform.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_rigid_transform.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_session.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_session.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_session_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_session_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_space.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_space.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_spherical_harmonics.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_spherical_harmonics.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_system.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_system.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_transient_input_hit_test_result.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_transient_input_hit_test_result.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_transient_input_hit_test_source.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_transient_input_hit_test_source.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_view.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_view.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_viewer_pose.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_viewer_pose.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_viewport.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_viewport.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_webgl_layer.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_webgl_layer.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_world_information.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_world_information.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_world_tracking_state.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_xr_world_tracking_state.h",
+]
+
+# Serial
+if (!is_android) {
+ generated_enumeration_sources_in_modules += [
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_parity_type.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_parity_type.h",
+ ]
+ generated_interface_sources_in_modules += [
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_serial.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_serial.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_serial_connection_event.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_serial_connection_event.h",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_serial_port.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_serial_port.h",
+ ]
+}
+
+generated_interface_sources_in_modules += [
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/init_idl_interfaces.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/init_idl_interfaces.h",
+]
+
+# Generated sources for testing
+
+generated_interface_sources_for_testing_in_modules = [
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_internals.cc",
+ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_internals.h",
+]
diff --git a/chromium/third_party/blink/renderer/bindings/idl_in_core.gni b/chromium/third_party/blink/renderer/bindings/idl_in_core.gni
new file mode 100644
index 00000000000..2b645e657fd
--- /dev/null
+++ b/chromium/third_party/blink/renderer/bindings/idl_in_core.gni
@@ -0,0 +1,683 @@
+# 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.
+
+# CAUTION: static_idl_files_in_core is used only by a new V8 bindings generator,
+# which is under development. You have to update core/core_idl_files.gni in
+# addition to this list.
+static_idl_files_in_core = get_path_info(
+ [
+ "//third_party/blink/renderer/core/animation/animatable.idl",
+ "//third_party/blink/renderer/core/animation/animation.idl",
+ "//third_party/blink/renderer/core/animation/animation_effect.idl",
+ "//third_party/blink/renderer/core/animation/animation_timeline.idl",
+ "//third_party/blink/renderer/core/animation/base_keyframe.idl",
+ "//third_party/blink/renderer/core/animation/base_property_indexed_keyframe.idl",
+ "//third_party/blink/renderer/core/animation/computed_effect_timing.idl",
+ "//third_party/blink/renderer/core/animation/css/css_animation.idl",
+ "//third_party/blink/renderer/core/animation/css/css_transition.idl",
+ "//third_party/blink/renderer/core/animation/document_animation.idl",
+ "//third_party/blink/renderer/core/animation/document_timeline.idl",
+ "//third_party/blink/renderer/core/animation/document_timeline_options.idl",
+ "//third_party/blink/renderer/core/animation/effect_timing.idl",
+ "//third_party/blink/renderer/core/animation/get_animations_options.idl",
+ "//third_party/blink/renderer/core/animation/keyframe_animation_options.idl",
+ "//third_party/blink/renderer/core/animation/keyframe_effect.idl",
+ "//third_party/blink/renderer/core/animation/keyframe_effect_options.idl",
+ "//third_party/blink/renderer/core/animation/optional_effect_timing.idl",
+ "//third_party/blink/renderer/core/animation/scroll_timeline.idl",
+ "//third_party/blink/renderer/core/animation/scroll_timeline_options.idl",
+ "//third_party/blink/renderer/core/aom/accessible_node.idl",
+ "//third_party/blink/renderer/core/aom/accessible_node_list.idl",
+ "//third_party/blink/renderer/core/aom/computed_accessible_node.idl",
+ "//third_party/blink/renderer/core/clipboard/data_transfer.idl",
+ "//third_party/blink/renderer/core/clipboard/data_transfer_item.idl",
+ "//third_party/blink/renderer/core/clipboard/data_transfer_item_list.idl",
+ "//third_party/blink/renderer/core/css/css.idl",
+ "//third_party/blink/renderer/core/css/css_condition_rule.idl",
+ "//third_party/blink/renderer/core/css/css_font_face_rule.idl",
+ "//third_party/blink/renderer/core/css/css_grouping_rule.idl",
+ "//third_party/blink/renderer/core/css/css_import_rule.idl",
+ "//third_party/blink/renderer/core/css/css_keyframe_rule.idl",
+ "//third_party/blink/renderer/core/css/css_keyframes_rule.idl",
+ "//third_party/blink/renderer/core/css/css_media_rule.idl",
+ "//third_party/blink/renderer/core/css/css_namespace_rule.idl",
+ "//third_party/blink/renderer/core/css/css_page_rule.idl",
+ "//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_style_declaration.idl",
+ "//third_party/blink/renderer/core/css/css_style_rule.idl",
+ "//third_party/blink/renderer/core/css/css_style_sheet.idl",
+ "//third_party/blink/renderer/core/css/css_style_sheet_init.idl",
+ "//third_party/blink/renderer/core/css/css_supports_rule.idl",
+ "//third_party/blink/renderer/core/css/css_viewport_rule.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_image_value.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_keyword_value.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_math_invert.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_math_max.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_math_min.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_math_negate.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_math_product.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_math_sum.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_math_value.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_matrix_component.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_matrix_component_options.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_numeric_array.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_numeric_type.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_numeric_value.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_perspective.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_position_value.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_rotate.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_scale.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_skew.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_skew_x.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_skew_y.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_style_value.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_transform_component.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_transform_value.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_translate.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_unit_value.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_unit_values.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_unparsed_value.idl",
+ "//third_party/blink/renderer/core/css/cssom/css_variable_reference_value.idl",
+ "//third_party/blink/renderer/core/css/cssom/element_computed_style_map.idl",
+ "//third_party/blink/renderer/core/css/cssom/style_property_map.idl",
+ "//third_party/blink/renderer/core/css/cssom/style_property_map_read_only.idl",
+ "//third_party/blink/renderer/core/css/cssom_string.idl",
+ "//third_party/blink/renderer/core/css/font_face.idl",
+ "//third_party/blink/renderer/core/css/font_face_descriptors.idl",
+ "//third_party/blink/renderer/core/css/font_face_set.idl",
+ "//third_party/blink/renderer/core/css/font_face_set_load_event.idl",
+ "//third_party/blink/renderer/core/css/font_face_set_load_event_init.idl",
+ "//third_party/blink/renderer/core/css/font_face_source.idl",
+ "//third_party/blink/renderer/core/css/media_list.idl",
+ "//third_party/blink/renderer/core/css/media_query_list.idl",
+ "//third_party/blink/renderer/core/css/media_query_list_event.idl",
+ "//third_party/blink/renderer/core/css/media_query_list_event_init.idl",
+ "//third_party/blink/renderer/core/css/property_definition.idl",
+ "//third_party/blink/renderer/core/css/property_registration.idl",
+ "//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",
+ "//third_party/blink/renderer/core/dom/aria_attributes.idl",
+ "//third_party/blink/renderer/core/dom/aria_relationship_attributes.idl",
+ "//third_party/blink/renderer/core/dom/attr.idl",
+ "//third_party/blink/renderer/core/dom/cdata_section.idl",
+ "//third_party/blink/renderer/core/dom/character_data.idl",
+ "//third_party/blink/renderer/core/dom/child_node.idl",
+ "//third_party/blink/renderer/core/dom/comment.idl",
+ "//third_party/blink/renderer/core/dom/common_definitions.idl",
+ "//third_party/blink/renderer/core/dom/document.idl",
+ "//third_party/blink/renderer/core/dom/document_and_element_event_handlers.idl",
+ "//third_party/blink/renderer/core/dom/document_fragment.idl",
+ "//third_party/blink/renderer/core/dom/document_or_shadow_root.idl",
+ "//third_party/blink/renderer/core/dom/document_type.idl",
+ "//third_party/blink/renderer/core/dom/dom_exception.idl",
+ "//third_party/blink/renderer/core/dom/dom_implementation.idl",
+ "//third_party/blink/renderer/core/dom/dom_string_list.idl",
+ "//third_party/blink/renderer/core/dom/dom_string_map.idl",
+ "//third_party/blink/renderer/core/dom/dom_token_list.idl",
+ "//third_party/blink/renderer/core/dom/element.idl",
+ "//third_party/blink/renderer/core/dom/element_creation_options.idl",
+ "//third_party/blink/renderer/core/dom/element_definition_options.idl",
+ "//third_party/blink/renderer/core/dom/element_registration_options.idl",
+ "//third_party/blink/renderer/core/dom/events/add_event_listener_options.idl",
+ "//third_party/blink/renderer/core/dom/events/custom_event.idl",
+ "//third_party/blink/renderer/core/dom/events/custom_event_init.idl",
+ "//third_party/blink/renderer/core/dom/events/event.idl",
+ "//third_party/blink/renderer/core/dom/events/event_init.idl",
+ "//third_party/blink/renderer/core/dom/events/event_listener.idl",
+ "//third_party/blink/renderer/core/dom/events/event_listener_options.idl",
+ "//third_party/blink/renderer/core/dom/events/event_modifier_init.idl",
+ "//third_party/blink/renderer/core/dom/events/event_target.idl",
+ "//third_party/blink/renderer/core/dom/frame_request_callback.idl",
+ "//third_party/blink/renderer/core/dom/function_string_callback.idl",
+ "//third_party/blink/renderer/core/dom/get_root_node_options.idl",
+ "//third_party/blink/renderer/core/dom/global_event_handlers.idl",
+ "//third_party/blink/renderer/core/dom/idle_deadline.idl",
+ "//third_party/blink/renderer/core/dom/idle_request_callback.idl",
+ "//third_party/blink/renderer/core/dom/idle_request_options.idl",
+ "//third_party/blink/renderer/core/dom/iterator.idl",
+ "//third_party/blink/renderer/core/dom/mutation_observer.idl",
+ "//third_party/blink/renderer/core/dom/mutation_observer_init.idl",
+ "//third_party/blink/renderer/core/dom/mutation_record.idl",
+ "//third_party/blink/renderer/core/dom/named_node_map.idl",
+ "//third_party/blink/renderer/core/dom/node.idl",
+ "//third_party/blink/renderer/core/dom/node_filter.idl",
+ "//third_party/blink/renderer/core/dom/node_iterator.idl",
+ "//third_party/blink/renderer/core/dom/node_list.idl",
+ "//third_party/blink/renderer/core/dom/non_document_type_child_node.idl",
+ "//third_party/blink/renderer/core/dom/non_element_parent_node.idl",
+ "//third_party/blink/renderer/core/dom/parent_node.idl",
+ "//third_party/blink/renderer/core/dom/pointer_lock_options.idl",
+ "//third_party/blink/renderer/core/dom/processing_instruction.idl",
+ "//third_party/blink/renderer/core/dom/range.idl",
+ "//third_party/blink/renderer/core/dom/shadow_root.idl",
+ "//third_party/blink/renderer/core/dom/shadow_root_init.idl",
+ "//third_party/blink/renderer/core/dom/static_range.idl",
+ "//third_party/blink/renderer/core/dom/text.idl",
+ "//third_party/blink/renderer/core/dom/tree_walker.idl",
+ "//third_party/blink/renderer/core/dom/void_function.idl",
+ "//third_party/blink/renderer/core/dom/xml_document.idl",
+ "//third_party/blink/renderer/core/editing/ime/edit_context.idl",
+ "//third_party/blink/renderer/core/editing/ime/edit_context_init.idl",
+ "//third_party/blink/renderer/core/editing/ime/text_format_update_event.idl",
+ "//third_party/blink/renderer/core/editing/ime/text_format_update_event_init.idl",
+ "//third_party/blink/renderer/core/editing/ime/text_update_event.idl",
+ "//third_party/blink/renderer/core/editing/ime/text_update_event_init.idl",
+ "//third_party/blink/renderer/core/editing/selection.idl",
+ "//third_party/blink/renderer/core/events/animation_event.idl",
+ "//third_party/blink/renderer/core/events/animation_event_init.idl",
+ "//third_party/blink/renderer/core/events/animation_playback_event.idl",
+ "//third_party/blink/renderer/core/events/animation_playback_event_init.idl",
+ "//third_party/blink/renderer/core/events/application_cache_error_event.idl",
+ "//third_party/blink/renderer/core/events/application_cache_error_event_init.idl",
+ "//third_party/blink/renderer/core/events/before_unload_event.idl",
+ "//third_party/blink/renderer/core/events/clipboard_event.idl",
+ "//third_party/blink/renderer/core/events/clipboard_event_init.idl",
+ "//third_party/blink/renderer/core/events/composition_event.idl",
+ "//third_party/blink/renderer/core/events/composition_event_init.idl",
+ "//third_party/blink/renderer/core/events/drag_event.idl",
+ "//third_party/blink/renderer/core/events/drag_event_init.idl",
+ "//third_party/blink/renderer/core/events/error_event.idl",
+ "//third_party/blink/renderer/core/events/error_event_init.idl",
+ "//third_party/blink/renderer/core/events/focus_event.idl",
+ "//third_party/blink/renderer/core/events/focus_event_init.idl",
+ "//third_party/blink/renderer/core/events/hash_change_event.idl",
+ "//third_party/blink/renderer/core/events/hash_change_event_init.idl",
+ "//third_party/blink/renderer/core/events/input_event.idl",
+ "//third_party/blink/renderer/core/events/input_event_init.idl",
+ "//third_party/blink/renderer/core/events/keyboard_event.idl",
+ "//third_party/blink/renderer/core/events/keyboard_event_init.idl",
+ "//third_party/blink/renderer/core/events/message_event.idl",
+ "//third_party/blink/renderer/core/events/message_event_init.idl",
+ "//third_party/blink/renderer/core/events/mouse_event.idl",
+ "//third_party/blink/renderer/core/events/mouse_event_init.idl",
+ "//third_party/blink/renderer/core/events/mutation_event.idl",
+ "//third_party/blink/renderer/core/events/navigator_events.idl",
+ "//third_party/blink/renderer/core/events/overscroll_event.idl",
+ "//third_party/blink/renderer/core/events/overscroll_event_init.idl",
+ "//third_party/blink/renderer/core/events/page_transition_event.idl",
+ "//third_party/blink/renderer/core/events/page_transition_event_init.idl",
+ "//third_party/blink/renderer/core/events/pointer_event.idl",
+ "//third_party/blink/renderer/core/events/pointer_event_init.idl",
+ "//third_party/blink/renderer/core/events/pop_state_event.idl",
+ "//third_party/blink/renderer/core/events/pop_state_event_init.idl",
+ "//third_party/blink/renderer/core/events/progress_event.idl",
+ "//third_party/blink/renderer/core/events/progress_event_init.idl",
+ "//third_party/blink/renderer/core/events/promise_rejection_event.idl",
+ "//third_party/blink/renderer/core/events/promise_rejection_event_init.idl",
+ "//third_party/blink/renderer/core/events/resource_progress_event.idl",
+ "//third_party/blink/renderer/core/events/security_policy_violation_event.idl",
+ "//third_party/blink/renderer/core/events/security_policy_violation_event_init.idl",
+ "//third_party/blink/renderer/core/events/text_event.idl",
+ "//third_party/blink/renderer/core/events/touch_event.idl",
+ "//third_party/blink/renderer/core/events/touch_event_init.idl",
+ "//third_party/blink/renderer/core/events/transition_event.idl",
+ "//third_party/blink/renderer/core/events/transition_event_init.idl",
+ "//third_party/blink/renderer/core/events/ui_event.idl",
+ "//third_party/blink/renderer/core/events/ui_event_init.idl",
+ "//third_party/blink/renderer/core/events/wheel_event.idl",
+ "//third_party/blink/renderer/core/events/wheel_event_init.idl",
+ "//third_party/blink/renderer/core/feature_policy/feature_policy.idl",
+ "//third_party/blink/renderer/core/fetch/body.idl",
+ "//third_party/blink/renderer/core/fetch/headers.idl",
+ "//third_party/blink/renderer/core/fetch/request.idl",
+ "//third_party/blink/renderer/core/fetch/request_init.idl",
+ "//third_party/blink/renderer/core/fetch/response.idl",
+ "//third_party/blink/renderer/core/fetch/response_init.idl",
+ "//third_party/blink/renderer/core/fetch/testing/internals_fetch.idl",
+ "//third_party/blink/renderer/core/fetch/testing/worker_internals_fetch.idl",
+ "//third_party/blink/renderer/core/fetch/trust_token.idl",
+ "//third_party/blink/renderer/core/fetch/window_fetch.idl",
+ "//third_party/blink/renderer/core/fetch/worker_fetch.idl",
+ "//third_party/blink/renderer/core/fileapi/blob.idl",
+ "//third_party/blink/renderer/core/fileapi/blob_property_bag.idl",
+ "//third_party/blink/renderer/core/fileapi/file.idl",
+ "//third_party/blink/renderer/core/fileapi/file_list.idl",
+ "//third_party/blink/renderer/core/fileapi/file_property_bag.idl",
+ "//third_party/blink/renderer/core/fileapi/file_reader.idl",
+ "//third_party/blink/renderer/core/fileapi/file_reader_sync.idl",
+ "//third_party/blink/renderer/core/fileapi/url_file_api.idl",
+ "//third_party/blink/renderer/core/frame/bar_prop.idl",
+ "//third_party/blink/renderer/core/frame/csp/csp_violation_report_body.idl",
+ "//third_party/blink/renderer/core/frame/deprecation_report_body.idl",
+ "//third_party/blink/renderer/core/frame/document_policy_violation_report_body.idl",
+ "//third_party/blink/renderer/core/frame/external.idl",
+ "//third_party/blink/renderer/core/frame/feature_policy_violation_report_body.idl",
+ "//third_party/blink/renderer/core/frame/fragment_directive.idl",
+ "//third_party/blink/renderer/core/frame/history.idl",
+ "//third_party/blink/renderer/core/frame/intervention_report_body.idl",
+ "//third_party/blink/renderer/core/frame/location.idl",
+ "//third_party/blink/renderer/core/frame/navigator.idl",
+ "//third_party/blink/renderer/core/frame/navigator_automation_information.idl",
+ "//third_party/blink/renderer/core/frame/navigator_concurrent_hardware.idl",
+ "//third_party/blink/renderer/core/frame/navigator_cookies.idl",
+ "//third_party/blink/renderer/core/frame/navigator_device_memory.idl",
+ "//third_party/blink/renderer/core/frame/navigator_id.idl",
+ "//third_party/blink/renderer/core/frame/navigator_language.idl",
+ "//third_party/blink/renderer/core/frame/navigator_on_line.idl",
+ "//third_party/blink/renderer/core/frame/navigator_scheduling.idl",
+ "//third_party/blink/renderer/core/frame/navigator_ua.idl",
+ "//third_party/blink/renderer/core/frame/navigator_ua_brand_version.idl",
+ "//third_party/blink/renderer/core/frame/navigator_ua_data.idl",
+ "//third_party/blink/renderer/core/frame/navigator_user_activation.idl",
+ "//third_party/blink/renderer/core/frame/report.idl",
+ "//third_party/blink/renderer/core/frame/report_body.idl",
+ "//third_party/blink/renderer/core/frame/reporting_observer.idl",
+ "//third_party/blink/renderer/core/frame/reporting_observer_options.idl",
+ "//third_party/blink/renderer/core/frame/scheduling.idl",
+ "//third_party/blink/renderer/core/frame/screen.idl",
+ "//third_party/blink/renderer/core/frame/scroll_into_view_options.idl",
+ "//third_party/blink/renderer/core/frame/scroll_options.idl",
+ "//third_party/blink/renderer/core/frame/scroll_to_options.idl",
+ "//third_party/blink/renderer/core/frame/test_report_body.idl",
+ "//third_party/blink/renderer/core/frame/ua_data_values.idl",
+ "//third_party/blink/renderer/core/frame/user_activation.idl",
+ "//third_party/blink/renderer/core/frame/visual_viewport.idl",
+ "//third_party/blink/renderer/core/frame/window.idl",
+ "//third_party/blink/renderer/core/frame/window_event_handlers.idl",
+ "//third_party/blink/renderer/core/frame/window_or_worker_global_scope.idl",
+ "//third_party/blink/renderer/core/frame/window_post_message_options.idl",
+ "//third_party/blink/renderer/core/fullscreen/document_fullscreen.idl",
+ "//third_party/blink/renderer/core/fullscreen/element_fullscreen.idl",
+ "//third_party/blink/renderer/core/fullscreen/fullscreen_options.idl",
+ "//third_party/blink/renderer/core/geometry/dom_matrix.idl",
+ "//third_party/blink/renderer/core/geometry/dom_matrix_2d_init.idl",
+ "//third_party/blink/renderer/core/geometry/dom_matrix_init.idl",
+ "//third_party/blink/renderer/core/geometry/dom_matrix_read_only.idl",
+ "//third_party/blink/renderer/core/geometry/dom_point.idl",
+ "//third_party/blink/renderer/core/geometry/dom_point_init.idl",
+ "//third_party/blink/renderer/core/geometry/dom_point_read_only.idl",
+ "//third_party/blink/renderer/core/geometry/dom_quad.idl",
+ "//third_party/blink/renderer/core/geometry/dom_quad_init.idl",
+ "//third_party/blink/renderer/core/geometry/dom_rect.idl",
+ "//third_party/blink/renderer/core/geometry/dom_rect_init.idl",
+ "//third_party/blink/renderer/core/geometry/dom_rect_list.idl",
+ "//third_party/blink/renderer/core/geometry/dom_rect_read_only.idl",
+ "//third_party/blink/renderer/core/html/assigned_nodes_options.idl",
+ "//third_party/blink/renderer/core/html/canvas/baselines.idl",
+ "//third_party/blink/renderer/core/html/canvas/html_canvas_element.idl",
+ "//third_party/blink/renderer/core/html/canvas/image_data.idl",
+ "//third_party/blink/renderer/core/html/canvas/image_data_color_settings.idl",
+ "//third_party/blink/renderer/core/html/canvas/image_encode_options.idl",
+ "//third_party/blink/renderer/core/html/canvas/text_metrics.idl",
+ "//third_party/blink/renderer/core/html/custom/custom_element_registry.idl",
+ "//third_party/blink/renderer/core/html/custom/element_internals.idl",
+ "//third_party/blink/renderer/core/html/custom/validity_state_flags.idl",
+ "//third_party/blink/renderer/core/html/event_handler.idl",
+ "//third_party/blink/renderer/core/html/focus_options.idl",
+ "//third_party/blink/renderer/core/html/forms/form_data.idl",
+ "//third_party/blink/renderer/core/html/forms/form_data_event.idl",
+ "//third_party/blink/renderer/core/html/forms/form_data_event_init.idl",
+ "//third_party/blink/renderer/core/html/forms/html_button_element.idl",
+ "//third_party/blink/renderer/core/html/forms/html_data_list_element.idl",
+ "//third_party/blink/renderer/core/html/forms/html_field_set_element.idl",
+ "//third_party/blink/renderer/core/html/forms/html_form_controls_collection.idl",
+ "//third_party/blink/renderer/core/html/forms/html_form_element.idl",
+ "//third_party/blink/renderer/core/html/forms/html_input_element.idl",
+ "//third_party/blink/renderer/core/html/forms/html_label_element.idl",
+ "//third_party/blink/renderer/core/html/forms/html_legend_element.idl",
+ "//third_party/blink/renderer/core/html/forms/html_opt_group_element.idl",
+ "//third_party/blink/renderer/core/html/forms/html_option_element.idl",
+ "//third_party/blink/renderer/core/html/forms/html_options_collection.idl",
+ "//third_party/blink/renderer/core/html/forms/html_output_element.idl",
+ "//third_party/blink/renderer/core/html/forms/html_select_element.idl",
+ "//third_party/blink/renderer/core/html/forms/html_text_area_element.idl",
+ "//third_party/blink/renderer/core/html/forms/radio_node_list.idl",
+ "//third_party/blink/renderer/core/html/forms/submit_event.idl",
+ "//third_party/blink/renderer/core/html/forms/submit_event_init.idl",
+ "//third_party/blink/renderer/core/html/forms/validity_state.idl",
+ "//third_party/blink/renderer/core/html/html_all_collection.idl",
+ "//third_party/blink/renderer/core/html/html_anchor_element.idl",
+ "//third_party/blink/renderer/core/html/html_area_element.idl",
+ "//third_party/blink/renderer/core/html/html_base_element.idl",
+ "//third_party/blink/renderer/core/html/html_body_element.idl",
+ "//third_party/blink/renderer/core/html/html_br_element.idl",
+ "//third_party/blink/renderer/core/html/html_collection.idl",
+ "//third_party/blink/renderer/core/html/html_content_element.idl",
+ "//third_party/blink/renderer/core/html/html_data_element.idl",
+ "//third_party/blink/renderer/core/html/html_details_element.idl",
+ "//third_party/blink/renderer/core/html/html_dialog_element.idl",
+ "//third_party/blink/renderer/core/html/html_directory_element.idl",
+ "//third_party/blink/renderer/core/html/html_div_element.idl",
+ "//third_party/blink/renderer/core/html/html_dlist_element.idl",
+ "//third_party/blink/renderer/core/html/html_document.idl",
+ "//third_party/blink/renderer/core/html/html_element.idl",
+ "//third_party/blink/renderer/core/html/html_embed_element.idl",
+ "//third_party/blink/renderer/core/html/html_font_element.idl",
+ "//third_party/blink/renderer/core/html/html_frame_element.idl",
+ "//third_party/blink/renderer/core/html/html_frame_set_element.idl",
+ "//third_party/blink/renderer/core/html/html_head_element.idl",
+ "//third_party/blink/renderer/core/html/html_heading_element.idl",
+ "//third_party/blink/renderer/core/html/html_hr_element.idl",
+ "//third_party/blink/renderer/core/html/html_html_element.idl",
+ "//third_party/blink/renderer/core/html/html_hyperlink_element_utils.idl",
+ "//third_party/blink/renderer/core/html/html_iframe_element.idl",
+ "//third_party/blink/renderer/core/html/html_image_element.idl",
+ "//third_party/blink/renderer/core/html/html_li_element.idl",
+ "//third_party/blink/renderer/core/html/html_link_element.idl",
+ "//third_party/blink/renderer/core/html/html_map_element.idl",
+ "//third_party/blink/renderer/core/html/html_marquee_element.idl",
+ "//third_party/blink/renderer/core/html/html_menu_element.idl",
+ "//third_party/blink/renderer/core/html/html_meta_element.idl",
+ "//third_party/blink/renderer/core/html/html_meter_element.idl",
+ "//third_party/blink/renderer/core/html/html_mod_element.idl",
+ "//third_party/blink/renderer/core/html/html_object_element.idl",
+ "//third_party/blink/renderer/core/html/html_olist_element.idl",
+ "//third_party/blink/renderer/core/html/html_or_foreign_element.idl",
+ "//third_party/blink/renderer/core/html/html_paragraph_element.idl",
+ "//third_party/blink/renderer/core/html/html_param_element.idl",
+ "//third_party/blink/renderer/core/html/html_picture_element.idl",
+ "//third_party/blink/renderer/core/html/html_pre_element.idl",
+ "//third_party/blink/renderer/core/html/html_progress_element.idl",
+ "//third_party/blink/renderer/core/html/html_quote_element.idl",
+ "//third_party/blink/renderer/core/html/html_script_element.idl",
+ "//third_party/blink/renderer/core/html/html_shadow_element.idl",
+ "//third_party/blink/renderer/core/html/html_slot_element.idl",
+ "//third_party/blink/renderer/core/html/html_source_element.idl",
+ "//third_party/blink/renderer/core/html/html_span_element.idl",
+ "//third_party/blink/renderer/core/html/html_style_element.idl",
+ "//third_party/blink/renderer/core/html/html_table_caption_element.idl",
+ "//third_party/blink/renderer/core/html/html_table_cell_element.idl",
+ "//third_party/blink/renderer/core/html/html_table_col_element.idl",
+ "//third_party/blink/renderer/core/html/html_table_element.idl",
+ "//third_party/blink/renderer/core/html/html_table_row_element.idl",
+ "//third_party/blink/renderer/core/html/html_table_section_element.idl",
+ "//third_party/blink/renderer/core/html/html_template_element.idl",
+ "//third_party/blink/renderer/core/html/html_time_element.idl",
+ "//third_party/blink/renderer/core/html/html_title_element.idl",
+ "//third_party/blink/renderer/core/html/html_ulist_element.idl",
+ "//third_party/blink/renderer/core/html/html_unknown_element.idl",
+ "//third_party/blink/renderer/core/html/media/html_audio_element.idl",
+ "//third_party/blink/renderer/core/html/media/html_media_element.idl",
+ "//third_party/blink/renderer/core/html/media/html_video_element.idl",
+ "//third_party/blink/renderer/core/html/media/media_error.idl",
+ "//third_party/blink/renderer/core/html/portal/html_portal_element.idl",
+ "//third_party/blink/renderer/core/html/portal/portal_activate_event.idl",
+ "//third_party/blink/renderer/core/html/portal/portal_activate_event_init.idl",
+ "//third_party/blink/renderer/core/html/portal/portal_activate_options.idl",
+ "//third_party/blink/renderer/core/html/portal/portal_host.idl",
+ "//third_party/blink/renderer/core/html/portal/window_portal_host.idl",
+ "//third_party/blink/renderer/core/html/time_ranges.idl",
+ "//third_party/blink/renderer/core/html/track/audio_track.idl",
+ "//third_party/blink/renderer/core/html/track/audio_track_list.idl",
+ "//third_party/blink/renderer/core/html/track/html_track_element.idl",
+ "//third_party/blink/renderer/core/html/track/text_track.idl",
+ "//third_party/blink/renderer/core/html/track/text_track_cue.idl",
+ "//third_party/blink/renderer/core/html/track/text_track_cue_list.idl",
+ "//third_party/blink/renderer/core/html/track/text_track_list.idl",
+ "//third_party/blink/renderer/core/html/track/track_event.idl",
+ "//third_party/blink/renderer/core/html/track/track_event_init.idl",
+ "//third_party/blink/renderer/core/html/track/video_track.idl",
+ "//third_party/blink/renderer/core/html/track/video_track_list.idl",
+ "//third_party/blink/renderer/core/html/track/vtt/vtt_cue.idl",
+ "//third_party/blink/renderer/core/html/track/vtt/vtt_region.idl",
+ "//third_party/blink/renderer/core/html/void_callback.idl",
+ "//third_party/blink/renderer/core/imagebitmap/image_bitmap.idl",
+ "//third_party/blink/renderer/core/imagebitmap/image_bitmap_options.idl",
+ "//third_party/blink/renderer/core/input/input_device_capabilities.idl",
+ "//third_party/blink/renderer/core/input/input_device_capabilities_init.idl",
+ "//third_party/blink/renderer/core/input/touch.idl",
+ "//third_party/blink/renderer/core/input/touch_init.idl",
+ "//third_party/blink/renderer/core/input/touch_list.idl",
+ "//third_party/blink/renderer/core/inspector/dev_tools_host.idl",
+ "//third_party/blink/renderer/core/inspector/inspector_overlay_host.idl",
+ "//third_party/blink/renderer/core/intersection_observer/intersection_observer.idl",
+ "//third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.idl",
+ "//third_party/blink/renderer/core/intersection_observer/intersection_observer_init.idl",
+ "//third_party/blink/renderer/core/invisible_dom/activate_invisible_event.idl",
+ "//third_party/blink/renderer/core/layout/ng/custom/css_layout_worklet.idl",
+ "//third_party/blink/renderer/core/layout/ng/custom/custom_layout_constraints_options.idl",
+ "//third_party/blink/renderer/core/layout/ng/custom/fragment_result_options.idl",
+ "//third_party/blink/renderer/core/layout/ng/custom/intrinsic_sizes.idl",
+ "//third_party/blink/renderer/core/layout/ng/custom/intrinsic_sizes_result_options.idl",
+ "//third_party/blink/renderer/core/layout/ng/custom/layout_child.idl",
+ "//third_party/blink/renderer/core/layout/ng/custom/layout_constraints.idl",
+ "//third_party/blink/renderer/core/layout/ng/custom/layout_edges.idl",
+ "//third_party/blink/renderer/core/layout/ng/custom/layout_fragment.idl",
+ "//third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.idl",
+ "//third_party/blink/renderer/core/loader/appcache/application_cache.idl",
+ "//third_party/blink/renderer/core/mathml/mathml_element.idl",
+ "//third_party/blink/renderer/core/messaging/message_channel.idl",
+ "//third_party/blink/renderer/core/messaging/message_port.idl",
+ "//third_party/blink/renderer/core/messaging/post_message_options.idl",
+ "//third_party/blink/renderer/core/mojo/mojo.idl",
+ "//third_party/blink/renderer/core/mojo/mojo_create_data_pipe_options.idl",
+ "//third_party/blink/renderer/core/mojo/mojo_create_data_pipe_result.idl",
+ "//third_party/blink/renderer/core/mojo/mojo_create_message_pipe_result.idl",
+ "//third_party/blink/renderer/core/mojo/mojo_create_shared_buffer_result.idl",
+ "//third_party/blink/renderer/core/mojo/mojo_discard_data_options.idl",
+ "//third_party/blink/renderer/core/mojo/mojo_duplicate_buffer_handle_options.idl",
+ "//third_party/blink/renderer/core/mojo/mojo_handle.idl",
+ "//third_party/blink/renderer/core/mojo/mojo_handle_signals.idl",
+ "//third_party/blink/renderer/core/mojo/mojo_map_buffer_result.idl",
+ "//third_party/blink/renderer/core/mojo/mojo_read_data_options.idl",
+ "//third_party/blink/renderer/core/mojo/mojo_read_data_result.idl",
+ "//third_party/blink/renderer/core/mojo/mojo_read_message_flags.idl",
+ "//third_party/blink/renderer/core/mojo/mojo_read_message_result.idl",
+ "//third_party/blink/renderer/core/mojo/mojo_watcher.idl",
+ "//third_party/blink/renderer/core/mojo/mojo_write_data_options.idl",
+ "//third_party/blink/renderer/core/mojo/mojo_write_data_result.idl",
+ "//third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.idl",
+ "//third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.idl",
+ "//third_party/blink/renderer/core/mojo/test/mojo_interface_request_event_init.idl",
+ "//third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.idl",
+ "//third_party/blink/renderer/core/page/color_page_popup_controller.idl",
+ "//third_party/blink/renderer/core/page/page_popup_controller.idl",
+ "//third_party/blink/renderer/core/page/scrolling/scroll_state.idl",
+ "//third_party/blink/renderer/core/page/scrolling/scroll_state_init.idl",
+ "//third_party/blink/renderer/core/resize_observer/resize_observer.idl",
+ "//third_party/blink/renderer/core/resize_observer/resize_observer_entry.idl",
+ "//third_party/blink/renderer/core/resize_observer/resize_observer_options.idl",
+ "//third_party/blink/renderer/core/resize_observer/resize_observer_size.idl",
+ "//third_party/blink/renderer/core/streams/byte_length_queuing_strategy.idl",
+ "//third_party/blink/renderer/core/streams/count_queuing_strategy.idl",
+ "//third_party/blink/renderer/core/streams/queuing_strategy_init.idl",
+ "//third_party/blink/renderer/core/streams/readable_stream.idl",
+ "//third_party/blink/renderer/core/streams/readable_stream_default_controller.idl",
+ "//third_party/blink/renderer/core/streams/readable_stream_default_reader.idl",
+ "//third_party/blink/renderer/core/streams/transform_stream.idl",
+ "//third_party/blink/renderer/core/streams/transform_stream_default_controller.idl",
+ "//third_party/blink/renderer/core/streams/underlying_sink_base.idl",
+ "//third_party/blink/renderer/core/streams/underlying_source_base.idl",
+ "//third_party/blink/renderer/core/streams/writable_stream.idl",
+ "//third_party/blink/renderer/core/streams/writable_stream_default_controller.idl",
+ "//third_party/blink/renderer/core/streams/writable_stream_default_writer.idl",
+ "//third_party/blink/renderer/core/svg/svg_a_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_angle.idl",
+ "//third_party/blink/renderer/core/svg/svg_animate_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_animate_motion_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_animate_transform_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_animated_angle.idl",
+ "//third_party/blink/renderer/core/svg/svg_animated_boolean.idl",
+ "//third_party/blink/renderer/core/svg/svg_animated_enumeration.idl",
+ "//third_party/blink/renderer/core/svg/svg_animated_integer.idl",
+ "//third_party/blink/renderer/core/svg/svg_animated_length.idl",
+ "//third_party/blink/renderer/core/svg/svg_animated_length_list.idl",
+ "//third_party/blink/renderer/core/svg/svg_animated_number.idl",
+ "//third_party/blink/renderer/core/svg/svg_animated_number_list.idl",
+ "//third_party/blink/renderer/core/svg/svg_animated_preserve_aspect_ratio.idl",
+ "//third_party/blink/renderer/core/svg/svg_animated_rect.idl",
+ "//third_party/blink/renderer/core/svg/svg_animated_string.idl",
+ "//third_party/blink/renderer/core/svg/svg_animated_transform_list.idl",
+ "//third_party/blink/renderer/core/svg/svg_animation_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_circle_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_clip_path_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_component_transfer_function_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_defs_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_desc_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_document.idl",
+ "//third_party/blink/renderer/core/svg/svg_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_ellipse_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_blend_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_component_transfer_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_composite_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_convolve_matrix_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_displacement_map_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_distant_light_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_flood_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_func_a_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_func_b_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_func_g_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_func_r_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_gaussian_blur_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_image_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_merge_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_merge_node_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_morphology_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_offset_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_point_light_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_spot_light_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_tile_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_fe_turbulence_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_filter_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.idl",
+ "//third_party/blink/renderer/core/svg/svg_fit_to_view_box.idl",
+ "//third_party/blink/renderer/core/svg/svg_foreign_object_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_g_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_geometry_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_gradient_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_graphics_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_image_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_length.idl",
+ "//third_party/blink/renderer/core/svg/svg_length_list.idl",
+ "//third_party/blink/renderer/core/svg/svg_line_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_linear_gradient_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_marker_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_mask_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_matrix.idl",
+ "//third_party/blink/renderer/core/svg/svg_metadata_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_mpath_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_number.idl",
+ "//third_party/blink/renderer/core/svg/svg_number_list.idl",
+ "//third_party/blink/renderer/core/svg/svg_path_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_pattern_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_point.idl",
+ "//third_party/blink/renderer/core/svg/svg_point_list.idl",
+ "//third_party/blink/renderer/core/svg/svg_polygon_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_polyline_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio.idl",
+ "//third_party/blink/renderer/core/svg/svg_radial_gradient_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_rect.idl",
+ "//third_party/blink/renderer/core/svg/svg_rect_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_script_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_set_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_stop_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_string_list.idl",
+ "//third_party/blink/renderer/core/svg/svg_style_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_svg_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_switch_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_symbol_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_tests.idl",
+ "//third_party/blink/renderer/core/svg/svg_text_content_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_text_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_text_path_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_text_positioning_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_title_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_transform.idl",
+ "//third_party/blink/renderer/core/svg/svg_transform_list.idl",
+ "//third_party/blink/renderer/core/svg/svg_tspan_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_unit_types.idl",
+ "//third_party/blink/renderer/core/svg/svg_uri_reference.idl",
+ "//third_party/blink/renderer/core/svg/svg_use_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_view_element.idl",
+ "//third_party/blink/renderer/core/svg/svg_zoom_and_pan.idl",
+ "//third_party/blink/renderer/core/testing/callback_function_test.idl",
+ "//third_party/blink/renderer/core/testing/death_aware_script_wrappable.idl",
+ "//third_party/blink/renderer/core/testing/dictionary_test.idl",
+ "//third_party/blink/renderer/core/testing/garbage_collected_script_wrappable.idl",
+ "//third_party/blink/renderer/core/testing/gc_observation.idl",
+ "//third_party/blink/renderer/core/testing/hit_test_layer_rect.idl",
+ "//third_party/blink/renderer/core/testing/hit_test_layer_rect_list.idl",
+ "//third_party/blink/renderer/core/testing/internal_dictionary.idl",
+ "//third_party/blink/renderer/core/testing/internal_dictionary_derived.idl",
+ "//third_party/blink/renderer/core/testing/internal_dictionary_derived_derived.idl",
+ "//third_party/blink/renderer/core/testing/internal_settings.idl",
+ "//third_party/blink/renderer/core/testing/internals.idl",
+ "//third_party/blink/renderer/core/testing/origin_trials_test.idl",
+ "//third_party/blink/renderer/core/testing/origin_trials_test_dictionary.idl",
+ "//third_party/blink/renderer/core/testing/origin_trials_test_partial.idl",
+ "//third_party/blink/renderer/core/testing/record_test.idl",
+ "//third_party/blink/renderer/core/testing/sequence_test.idl",
+ "//third_party/blink/renderer/core/testing/static_selection.idl",
+ "//third_party/blink/renderer/core/testing/type_conversions.idl",
+ "//third_party/blink/renderer/core/testing/union_types_test.idl",
+ "//third_party/blink/renderer/core/testing/worker_internals.idl",
+ "//third_party/blink/renderer/core/timing/dom_high_res_time_stamp.idl",
+ "//third_party/blink/renderer/core/timing/internals_profiler.idl",
+ "//third_party/blink/renderer/core/timing/largest_contentful_paint.idl",
+ "//third_party/blink/renderer/core/timing/layout_shift.idl",
+ "//third_party/blink/renderer/core/timing/measure_memory/measure_memory.idl",
+ "//third_party/blink/renderer/core/timing/measure_memory/measure_memory_breakdown.idl",
+ "//third_party/blink/renderer/core/timing/memory_info.idl",
+ "//third_party/blink/renderer/core/timing/performance.idl",
+ "//third_party/blink/renderer/core/timing/performance_element_timing.idl",
+ "//third_party/blink/renderer/core/timing/performance_entry.idl",
+ "//third_party/blink/renderer/core/timing/performance_entry_list.idl",
+ "//third_party/blink/renderer/core/timing/performance_event_timing.idl",
+ "//third_party/blink/renderer/core/timing/performance_long_task_timing.idl",
+ "//third_party/blink/renderer/core/timing/performance_mark.idl",
+ "//third_party/blink/renderer/core/timing/performance_mark_options.idl",
+ "//third_party/blink/renderer/core/timing/performance_measure.idl",
+ "//third_party/blink/renderer/core/timing/performance_measure_options.idl",
+ "//third_party/blink/renderer/core/timing/performance_navigation.idl",
+ "//third_party/blink/renderer/core/timing/performance_navigation_timing.idl",
+ "//third_party/blink/renderer/core/timing/performance_observer.idl",
+ "//third_party/blink/renderer/core/timing/performance_observer_entry_list.idl",
+ "//third_party/blink/renderer/core/timing/performance_observer_init.idl",
+ "//third_party/blink/renderer/core/timing/performance_paint_timing.idl",
+ "//third_party/blink/renderer/core/timing/performance_resource_timing.idl",
+ "//third_party/blink/renderer/core/timing/performance_server_timing.idl",
+ "//third_party/blink/renderer/core/timing/performance_timing.idl",
+ "//third_party/blink/renderer/core/timing/profiler.idl",
+ "//third_party/blink/renderer/core/timing/profiler_frame.idl",
+ "//third_party/blink/renderer/core/timing/profiler_init_options.idl",
+ "//third_party/blink/renderer/core/timing/profiler_sample.idl",
+ "//third_party/blink/renderer/core/timing/profiler_stack.idl",
+ "//third_party/blink/renderer/core/timing/profiler_trace.idl",
+ "//third_party/blink/renderer/core/timing/task_attribution_timing.idl",
+ "//third_party/blink/renderer/core/timing/window_performance.idl",
+ "//third_party/blink/renderer/core/timing/worker_global_scope_performance.idl",
+ "//third_party/blink/renderer/core/trustedtypes/trusted_html.idl",
+ "//third_party/blink/renderer/core/trustedtypes/trusted_script.idl",
+ "//third_party/blink/renderer/core/trustedtypes/trusted_script_url.idl",
+ "//third_party/blink/renderer/core/trustedtypes/trusted_type_policy.idl",
+ "//third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.idl",
+ "//third_party/blink/renderer/core/trustedtypes/trusted_type_policy_options.idl",
+ "//third_party/blink/renderer/core/url/url.idl",
+ "//third_party/blink/renderer/core/url/url_search_params.idl",
+ "//third_party/blink/renderer/core/workers/abstract_worker.idl",
+ "//third_party/blink/renderer/core/workers/dedicated_worker_global_scope.idl",
+ "//third_party/blink/renderer/core/workers/shared_worker.idl",
+ "//third_party/blink/renderer/core/workers/shared_worker_global_scope.idl",
+ "//third_party/blink/renderer/core/workers/worker.idl",
+ "//third_party/blink/renderer/core/workers/worker_global_scope.idl",
+ "//third_party/blink/renderer/core/workers/worker_location.idl",
+ "//third_party/blink/renderer/core/workers/worker_navigator.idl",
+ "//third_party/blink/renderer/core/workers/worker_options.idl",
+ "//third_party/blink/renderer/core/workers/worklet.idl",
+ "//third_party/blink/renderer/core/workers/worklet_global_scope.idl",
+ "//third_party/blink/renderer/core/workers/worklet_options.idl",
+ "//third_party/blink/renderer/core/xml/document_xpath_evaluator.idl",
+ "//third_party/blink/renderer/core/xml/dom_parser.idl",
+ "//third_party/blink/renderer/core/xml/xml_serializer.idl",
+ "//third_party/blink/renderer/core/xml/xpath_evaluator.idl",
+ "//third_party/blink/renderer/core/xml/xpath_expression.idl",
+ "//third_party/blink/renderer/core/xml/xpath_ns_resolver.idl",
+ "//third_party/blink/renderer/core/xml/xpath_result.idl",
+ "//third_party/blink/renderer/core/xml/xslt_processor.idl",
+ "//third_party/blink/renderer/core/xmlhttprequest/xml_http_request.idl",
+ "//third_party/blink/renderer/core/xmlhttprequest/xml_http_request_event_target.idl",
+ "//third_party/blink/renderer/core/xmlhttprequest/xml_http_request_upload.idl",
+ ],
+ "abspath")
diff --git a/chromium/third_party/blink/renderer/bindings/idl_in_modules.gni b/chromium/third_party/blink/renderer/bindings/idl_in_modules.gni
new file mode 100644
index 00000000000..6afb7031b22
--- /dev/null
+++ b/chromium/third_party/blink/renderer/bindings/idl_in_modules.gni
@@ -0,0 +1,1026 @@
+# 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/config.gni")
+
+# CAUTION: static_idl_files_in_modules is used only by a new V8 bindings
+# generator, which is under development. You have to update
+# modules/modules_idl_files.gni in addition to this list.
+static_idl_files_in_modules = get_path_info(
+ [
+ "//third_party/blink/renderer/modules/accessibility/testing/internals_accessibility.idl",
+ "//third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.idl",
+ "//third_party/blink/renderer/modules/animationworklet/css_animation_worklet.idl",
+ "//third_party/blink/renderer/modules/animationworklet/worklet_animation.idl",
+ "//third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.idl",
+ "//third_party/blink/renderer/modules/animationworklet/worklet_group_effect.idl",
+ "//third_party/blink/renderer/modules/app_banner/app_banner_prompt_result.idl",
+ "//third_party/blink/renderer/modules/app_banner/before_install_prompt_event.idl",
+ "//third_party/blink/renderer/modules/app_banner/before_install_prompt_event_init.idl",
+ "//third_party/blink/renderer/modules/app_banner/window_installation.idl",
+ "//third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.idl",
+ "//third_party/blink/renderer/modules/background_fetch/background_fetch_event.idl",
+ "//third_party/blink/renderer/modules/background_fetch/background_fetch_event_init.idl",
+ "//third_party/blink/renderer/modules/background_fetch/background_fetch_manager.idl",
+ "//third_party/blink/renderer/modules/background_fetch/background_fetch_options.idl",
+ "//third_party/blink/renderer/modules/background_fetch/background_fetch_record.idl",
+ "//third_party/blink/renderer/modules/background_fetch/background_fetch_registration.idl",
+ "//third_party/blink/renderer/modules/background_fetch/background_fetch_ui_options.idl",
+ "//third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.idl",
+ "//third_party/blink/renderer/modules/background_fetch/service_worker_global_scope_background_fetch.idl",
+ "//third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.idl",
+ "//third_party/blink/renderer/modules/background_sync/background_sync_options.idl",
+ "//third_party/blink/renderer/modules/background_sync/periodic_sync_event.idl",
+ "//third_party/blink/renderer/modules/background_sync/periodic_sync_event_init.idl",
+ "//third_party/blink/renderer/modules/background_sync/periodic_sync_manager.idl",
+ "//third_party/blink/renderer/modules/background_sync/service_worker_global_scope_sync.idl",
+ "//third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.idl",
+ "//third_party/blink/renderer/modules/background_sync/sync_event.idl",
+ "//third_party/blink/renderer/modules/background_sync/sync_event_init.idl",
+ "//third_party/blink/renderer/modules/background_sync/sync_manager.idl",
+ "//third_party/blink/renderer/modules/badging/navigator_badge.idl",
+ "//third_party/blink/renderer/modules/badging/worker_navigator_badge.idl",
+ "//third_party/blink/renderer/modules/battery/battery_manager.idl",
+ "//third_party/blink/renderer/modules/battery/navigator_battery.idl",
+ "//third_party/blink/renderer/modules/beacon/navigator_beacon.idl",
+ "//third_party/blink/renderer/modules/bluetooth/bluetooth.idl",
+ "//third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.idl",
+ "//third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event_init.idl",
+ "//third_party/blink/renderer/modules/bluetooth/bluetooth_characteristic_properties.idl",
+ "//third_party/blink/renderer/modules/bluetooth/bluetooth_device.idl",
+ "//third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.idl",
+ "//third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan_filter_init.idl",
+ "//third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan_options.idl",
+ "//third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.idl",
+ "//third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.idl",
+ "//third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.idl",
+ "//third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.idl",
+ "//third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.idl",
+ "//third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.idl",
+ "//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/broadcastchannel/broadcast_channel.idl",
+ "//third_party/blink/renderer/modules/cache_storage/cache.idl",
+ "//third_party/blink/renderer/modules/cache_storage/cache_query_options.idl",
+ "//third_party/blink/renderer/modules/cache_storage/cache_storage.idl",
+ "//third_party/blink/renderer/modules/cache_storage/multi_cache_query_options.idl",
+ "//third_party/blink/renderer/modules/cache_storage/window_cache_storage.idl",
+ "//third_party/blink/renderer/modules/cache_storage/worker_cache_storage.idl",
+ "//third_party/blink/renderer/modules/canvas/canvas2d/canvas_gradient.idl",
+ "//third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.idl",
+ "//third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.idl",
+ "//third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl",
+ "//third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_settings.idl",
+ "//third_party/blink/renderer/modules/canvas/canvas2d/hit_region_options.idl",
+ "//third_party/blink/renderer/modules/canvas/canvas2d/path_2d.idl",
+ "//third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl",
+ "//third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.idl",
+ "//third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl",
+ "//third_party/blink/renderer/modules/clipboard/clipboard.idl",
+ "//third_party/blink/renderer/modules/clipboard/clipboard_item.idl",
+ "//third_party/blink/renderer/modules/clipboard/clipboard_item_options.idl",
+ "//third_party/blink/renderer/modules/clipboard/navigator_clipboard.idl",
+ "//third_party/blink/renderer/modules/compression/compression_stream.idl",
+ "//third_party/blink/renderer/modules/compression/decompression_stream.idl",
+ "//third_party/blink/renderer/modules/contacts_picker/contact_address.idl",
+ "//third_party/blink/renderer/modules/contacts_picker/contact_info.idl",
+ "//third_party/blink/renderer/modules/contacts_picker/contacts_manager.idl",
+ "//third_party/blink/renderer/modules/contacts_picker/contacts_select_options.idl",
+ "//third_party/blink/renderer/modules/contacts_picker/navigator_contacts.idl",
+ "//third_party/blink/renderer/modules/content_index/content_description.idl",
+ "//third_party/blink/renderer/modules/content_index/content_icon_definition.idl",
+ "//third_party/blink/renderer/modules/content_index/content_index.idl",
+ "//third_party/blink/renderer/modules/content_index/content_index_event.idl",
+ "//third_party/blink/renderer/modules/content_index/content_index_event_init.idl",
+ "//third_party/blink/renderer/modules/content_index/service_worker_global_scope_content_index.idl",
+ "//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_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",
+ "//third_party/blink/renderer/modules/cookie_store/service_worker_registration_cookies.idl",
+ "//third_party/blink/renderer/modules/cookie_store/window_cookie_store.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/authentication_extensions_client_inputs.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/authentication_extensions_client_outputs.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/authenticator_assertion_response.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/authenticator_response.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/authenticator_selection_criteria.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/cable_authentication_data.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/cable_registration_data.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/collected_client_data.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/credential.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/credential_creation_options.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/credential_data.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/credential_request_options.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/credential_user_data.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/credentials_container.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/federated_credential.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/federated_credential_init.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/federated_credential_request_options.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/navigator_credentials.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/otp_credential.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/otp_credential_request_options.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/password_credential.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/password_credential_data.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/public_key_credential.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/public_key_credential_creation_options.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/public_key_credential_descriptor.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/public_key_credential_entity.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/public_key_credential_parameters.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/public_key_credential_request_options.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/public_key_credential_rp_entity.idl",
+ "//third_party/blink/renderer/modules/credentialmanager/public_key_credential_user_entity.idl",
+ "//third_party/blink/renderer/modules/crypto/crypto.idl",
+ "//third_party/blink/renderer/modules/crypto/crypto_key.idl",
+ "//third_party/blink/renderer/modules/crypto/json_web_key.idl",
+ "//third_party/blink/renderer/modules/crypto/rsa_other_primes_info.idl",
+ "//third_party/blink/renderer/modules/crypto/subtle_crypto.idl",
+ "//third_party/blink/renderer/modules/crypto/window_crypto.idl",
+ "//third_party/blink/renderer/modules/crypto/worker_global_scope_crypto.idl",
+ "//third_party/blink/renderer/modules/csspaint/css_paint_worklet.idl",
+ "//third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl",
+ "//third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d_settings.idl",
+ "//third_party/blink/renderer/modules/csspaint/paint_size.idl",
+ "//third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.idl",
+ "//third_party/blink/renderer/modules/device_orientation/device_motion_event.idl",
+ "//third_party/blink/renderer/modules/device_orientation/device_motion_event_acceleration.idl",
+ "//third_party/blink/renderer/modules/device_orientation/device_motion_event_acceleration_init.idl",
+ "//third_party/blink/renderer/modules/device_orientation/device_motion_event_init.idl",
+ "//third_party/blink/renderer/modules/device_orientation/device_motion_event_rotation_rate.idl",
+ "//third_party/blink/renderer/modules/device_orientation/device_motion_event_rotation_rate_init.idl",
+ "//third_party/blink/renderer/modules/device_orientation/device_orientation_event.idl",
+ "//third_party/blink/renderer/modules/device_orientation/device_orientation_event_init.idl",
+ "//third_party/blink/renderer/modules/device_orientation/window_device_motion.idl",
+ "//third_party/blink/renderer/modules/device_orientation/window_device_orientation.idl",
+ "//third_party/blink/renderer/modules/donottrack/navigator_do_not_track.idl",
+ "//third_party/blink/renderer/modules/encoding/text_decode_options.idl",
+ "//third_party/blink/renderer/modules/encoding/text_decoder.idl",
+ "//third_party/blink/renderer/modules/encoding/text_decoder_options.idl",
+ "//third_party/blink/renderer/modules/encoding/text_decoder_stream.idl",
+ "//third_party/blink/renderer/modules/encoding/text_encoder.idl",
+ "//third_party/blink/renderer/modules/encoding/text_encoder_encode_into_result.idl",
+ "//third_party/blink/renderer/modules/encoding/text_encoder_stream.idl",
+ "//third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.idl",
+ "//third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.idl",
+ "//third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event_init.idl",
+ "//third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.idl",
+ "//third_party/blink/renderer/modules/encryptedmedia/media_key_message_event_init.idl",
+ "//third_party/blink/renderer/modules/encryptedmedia/media_key_session.idl",
+ "//third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.idl",
+ "//third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.idl",
+ "//third_party/blink/renderer/modules/encryptedmedia/media_key_system_configuration.idl",
+ "//third_party/blink/renderer/modules/encryptedmedia/media_key_system_media_capability.idl",
+ "//third_party/blink/renderer/modules/encryptedmedia/media_keys.idl",
+ "//third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.idl",
+ "//third_party/blink/renderer/modules/encryptedmedia/media_keys_policy.idl",
+ "//third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.idl",
+ "//third_party/blink/renderer/modules/eventsource/event_source.idl",
+ "//third_party/blink/renderer/modules/eventsource/event_source_init.idl",
+ "//third_party/blink/renderer/modules/filesystem/data_transfer_item_file_system.idl",
+ "//third_party/blink/renderer/modules/filesystem/dedicated_worker_global_scope_file_system.idl",
+ "//third_party/blink/renderer/modules/filesystem/dev_tools_host_file_system.idl",
+ "//third_party/blink/renderer/modules/filesystem/directory_entry.idl",
+ "//third_party/blink/renderer/modules/filesystem/directory_entry_sync.idl",
+ "//third_party/blink/renderer/modules/filesystem/directory_reader.idl",
+ "//third_party/blink/renderer/modules/filesystem/directory_reader_sync.idl",
+ "//third_party/blink/renderer/modules/filesystem/dom_file_system.idl",
+ "//third_party/blink/renderer/modules/filesystem/dom_file_system_sync.idl",
+ "//third_party/blink/renderer/modules/filesystem/entries_callback.idl",
+ "//third_party/blink/renderer/modules/filesystem/entry.idl",
+ "//third_party/blink/renderer/modules/filesystem/entry_callback.idl",
+ "//third_party/blink/renderer/modules/filesystem/entry_sync.idl",
+ "//third_party/blink/renderer/modules/filesystem/error_callback.idl",
+ "//third_party/blink/renderer/modules/filesystem/file_callback.idl",
+ "//third_party/blink/renderer/modules/filesystem/file_entry.idl",
+ "//third_party/blink/renderer/modules/filesystem/file_entry_sync.idl",
+ "//third_party/blink/renderer/modules/filesystem/file_system_callback.idl",
+ "//third_party/blink/renderer/modules/filesystem/file_system_flags.idl",
+ "//third_party/blink/renderer/modules/filesystem/file_writer.idl",
+ "//third_party/blink/renderer/modules/filesystem/file_writer_callback.idl",
+ "//third_party/blink/renderer/modules/filesystem/file_writer_sync.idl",
+ "//third_party/blink/renderer/modules/filesystem/html_input_element_file_system.idl",
+ "//third_party/blink/renderer/modules/filesystem/metadata.idl",
+ "//third_party/blink/renderer/modules/filesystem/metadata_callback.idl",
+ "//third_party/blink/renderer/modules/filesystem/shared_worker_global_scope_file_system.idl",
+ "//third_party/blink/renderer/modules/filesystem/window_file_system.idl",
+ "//third_party/blink/renderer/modules/font_access/font_iterator.idl",
+ "//third_party/blink/renderer/modules/font_access/font_iterator_entry.idl",
+ "//third_party/blink/renderer/modules/font_access/font_manager.idl",
+ "//third_party/blink/renderer/modules/font_access/font_metadata.idl",
+ "//third_party/blink/renderer/modules/font_access/navigator_fonts.idl",
+ "//third_party/blink/renderer/modules/font_access/worker_navigator_fonts.idl",
+ "//third_party/blink/renderer/modules/gamepad/gamepad.idl",
+ "//third_party/blink/renderer/modules/gamepad/gamepad_axis_event.idl",
+ "//third_party/blink/renderer/modules/gamepad/gamepad_axis_event_init.idl",
+ "//third_party/blink/renderer/modules/gamepad/gamepad_button.idl",
+ "//third_party/blink/renderer/modules/gamepad/gamepad_button_event.idl",
+ "//third_party/blink/renderer/modules/gamepad/gamepad_button_event_init.idl",
+ "//third_party/blink/renderer/modules/gamepad/gamepad_effect_parameters.idl",
+ "//third_party/blink/renderer/modules/gamepad/gamepad_event.idl",
+ "//third_party/blink/renderer/modules/gamepad/gamepad_event_init.idl",
+ "//third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.idl",
+ "//third_party/blink/renderer/modules/gamepad/gamepad_list.idl",
+ "//third_party/blink/renderer/modules/gamepad/navigator_gamepad.idl",
+ "//third_party/blink/renderer/modules/geolocation/geolocation.idl",
+ "//third_party/blink/renderer/modules/geolocation/geolocation_coordinates.idl",
+ "//third_party/blink/renderer/modules/geolocation/geolocation_position.idl",
+ "//third_party/blink/renderer/modules/geolocation/geolocation_position_error.idl",
+ "//third_party/blink/renderer/modules/geolocation/navigator_geolocation.idl",
+ "//third_party/blink/renderer/modules/geolocation/position_options.idl",
+ "//third_party/blink/renderer/modules/hid/hid.idl",
+ "//third_party/blink/renderer/modules/hid/hid_collection_info.idl",
+ "//third_party/blink/renderer/modules/hid/hid_connection_event.idl",
+ "//third_party/blink/renderer/modules/hid/hid_connection_event_init.idl",
+ "//third_party/blink/renderer/modules/hid/hid_device.idl",
+ "//third_party/blink/renderer/modules/hid/hid_device_filter.idl",
+ "//third_party/blink/renderer/modules/hid/hid_device_request_options.idl",
+ "//third_party/blink/renderer/modules/hid/hid_input_report_event.idl",
+ "//third_party/blink/renderer/modules/hid/hid_report_info.idl",
+ "//third_party/blink/renderer/modules/hid/hid_report_item.idl",
+ "//third_party/blink/renderer/modules/hid/navigator_hid.idl",
+ "//third_party/blink/renderer/modules/idle/idle_detector.idl",
+ "//third_party/blink/renderer/modules/idle/idle_options.idl",
+ "//third_party/blink/renderer/modules/idle/idle_state.idl",
+ "//third_party/blink/renderer/modules/imagecapture/constrain_point_2d_parameters.idl",
+ "//third_party/blink/renderer/modules/imagecapture/image_capture.idl",
+ "//third_party/blink/renderer/modules/imagecapture/media_settings_range.idl",
+ "//third_party/blink/renderer/modules/imagecapture/photo_capabilities.idl",
+ "//third_party/blink/renderer/modules/imagecapture/photo_settings.idl",
+ "//third_party/blink/renderer/modules/imagecapture/point_2d.idl",
+ "//third_party/blink/renderer/modules/indexeddb/idb_cursor.idl",
+ "//third_party/blink/renderer/modules/indexeddb/idb_cursor_with_value.idl",
+ "//third_party/blink/renderer/modules/indexeddb/idb_database.idl",
+ "//third_party/blink/renderer/modules/indexeddb/idb_database_info.idl",
+ "//third_party/blink/renderer/modules/indexeddb/idb_factory.idl",
+ "//third_party/blink/renderer/modules/indexeddb/idb_index.idl",
+ "//third_party/blink/renderer/modules/indexeddb/idb_index_parameters.idl",
+ "//third_party/blink/renderer/modules/indexeddb/idb_key_range.idl",
+ "//third_party/blink/renderer/modules/indexeddb/idb_object_store.idl",
+ "//third_party/blink/renderer/modules/indexeddb/idb_object_store_parameters.idl",
+ "//third_party/blink/renderer/modules/indexeddb/idb_observation.idl",
+ "//third_party/blink/renderer/modules/indexeddb/idb_observer.idl",
+ "//third_party/blink/renderer/modules/indexeddb/idb_observer_changes.idl",
+ "//third_party/blink/renderer/modules/indexeddb/idb_observer_init.idl",
+ "//third_party/blink/renderer/modules/indexeddb/idb_open_db_request.idl",
+ "//third_party/blink/renderer/modules/indexeddb/idb_request.idl",
+ "//third_party/blink/renderer/modules/indexeddb/idb_transaction.idl",
+ "//third_party/blink/renderer/modules/indexeddb/idb_transaction_options.idl",
+ "//third_party/blink/renderer/modules/indexeddb/idb_version_change_event.idl",
+ "//third_party/blink/renderer/modules/indexeddb/idb_version_change_event_init.idl",
+ "//third_party/blink/renderer/modules/indexeddb/window_indexed_database.idl",
+ "//third_party/blink/renderer/modules/indexeddb/worker_global_scope_indexed_database.idl",
+ "//third_party/blink/renderer/modules/installedapp/navigator_installed_app.idl",
+ "//third_party/blink/renderer/modules/installedapp/related_application.idl",
+ "//third_party/blink/renderer/modules/keyboard/keyboard.idl",
+ "//third_party/blink/renderer/modules/keyboard/keyboard_layout_map.idl",
+ "//third_party/blink/renderer/modules/keyboard/navigator_keyboard.idl",
+ "//third_party/blink/renderer/modules/launch/dom_window_launch_queue.idl",
+ "//third_party/blink/renderer/modules/launch/launch_params.idl",
+ "//third_party/blink/renderer/modules/launch/launch_queue.idl",
+ "//third_party/blink/renderer/modules/locks/lock.idl",
+ "//third_party/blink/renderer/modules/locks/lock_info.idl",
+ "//third_party/blink/renderer/modules/locks/lock_manager.idl",
+ "//third_party/blink/renderer/modules/locks/lock_manager_snapshot.idl",
+ "//third_party/blink/renderer/modules/locks/lock_options.idl",
+ "//third_party/blink/renderer/modules/locks/navigator_locks.idl",
+ "//third_party/blink/renderer/modules/locks/worker_navigator_locks.idl",
+ "//third_party/blink/renderer/modules/manifest/image_resource.idl",
+ "//third_party/blink/renderer/modules/media_capabilities/audio_configuration.idl",
+ "//third_party/blink/renderer/modules/media_capabilities/key_system_track_configuration.idl",
+ "//third_party/blink/renderer/modules/media_capabilities/media_capabilities.idl",
+ "//third_party/blink/renderer/modules/media_capabilities/media_capabilities_decoding_info.idl",
+ "//third_party/blink/renderer/modules/media_capabilities/media_capabilities_info.idl",
+ "//third_party/blink/renderer/modules/media_capabilities/media_capabilities_key_system_configuration.idl",
+ "//third_party/blink/renderer/modules/media_capabilities/media_configuration.idl",
+ "//third_party/blink/renderer/modules/media_capabilities/media_decoding_configuration.idl",
+ "//third_party/blink/renderer/modules/media_capabilities/media_encoding_configuration.idl",
+ "//third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.idl",
+ "//third_party/blink/renderer/modules/media_capabilities/video_configuration.idl",
+ "//third_party/blink/renderer/modules/media_capabilities/worker_navigator_media_capabilities.idl",
+ "//third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.idl",
+ "//third_party/blink/renderer/modules/mediacapturefromelement/html_canvas_element_capture.idl",
+ "//third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.idl",
+ "//third_party/blink/renderer/modules/mediarecorder/blob_event.idl",
+ "//third_party/blink/renderer/modules/mediarecorder/blob_event_init.idl",
+ "//third_party/blink/renderer/modules/mediarecorder/media_recorder.idl",
+ "//third_party/blink/renderer/modules/mediarecorder/media_recorder_options.idl",
+ "//third_party/blink/renderer/modules/mediasession/media_image.idl",
+ "//third_party/blink/renderer/modules/mediasession/media_metadata.idl",
+ "//third_party/blink/renderer/modules/mediasession/media_metadata_init.idl",
+ "//third_party/blink/renderer/modules/mediasession/media_position_state.idl",
+ "//third_party/blink/renderer/modules/mediasession/media_session.idl",
+ "//third_party/blink/renderer/modules/mediasession/media_session_action_details.idl",
+ "//third_party/blink/renderer/modules/mediasession/media_session_seek_to_action_details.idl",
+ "//third_party/blink/renderer/modules/mediasession/navigator_media_session.idl",
+ "//third_party/blink/renderer/modules/mediasource/audio_track_source_buffer.idl",
+ "//third_party/blink/renderer/modules/mediasource/html_video_element_media_source.idl",
+ "//third_party/blink/renderer/modules/mediasource/media_source.idl",
+ "//third_party/blink/renderer/modules/mediasource/source_buffer.idl",
+ "//third_party/blink/renderer/modules/mediasource/source_buffer_list.idl",
+ "//third_party/blink/renderer/modules/mediasource/track_default.idl",
+ "//third_party/blink/renderer/modules/mediasource/track_default_list.idl",
+ "//third_party/blink/renderer/modules/mediasource/url_media_source.idl",
+ "//third_party/blink/renderer/modules/mediasource/video_playback_quality.idl",
+ "//third_party/blink/renderer/modules/mediasource/video_track_source_buffer.idl",
+ "//third_party/blink/renderer/modules/mediastream/constrain_boolean_parameters.idl",
+ "//third_party/blink/renderer/modules/mediastream/constrain_dom_string_parameters.idl",
+ "//third_party/blink/renderer/modules/mediastream/constrain_double_range.idl",
+ "//third_party/blink/renderer/modules/mediastream/constrain_long_range.idl",
+ "//third_party/blink/renderer/modules/mediastream/double_range.idl",
+ "//third_party/blink/renderer/modules/mediastream/input_device_info.idl",
+ "//third_party/blink/renderer/modules/mediastream/long_range.idl",
+ "//third_party/blink/renderer/modules/mediastream/media_device_info.idl",
+ "//third_party/blink/renderer/modules/mediastream/media_devices.idl",
+ "//third_party/blink/renderer/modules/mediastream/media_stream.idl",
+ "//third_party/blink/renderer/modules/mediastream/media_stream_constraints.idl",
+ "//third_party/blink/renderer/modules/mediastream/media_stream_event.idl",
+ "//third_party/blink/renderer/modules/mediastream/media_stream_event_init.idl",
+ "//third_party/blink/renderer/modules/mediastream/media_stream_track.idl",
+ "//third_party/blink/renderer/modules/mediastream/media_stream_track_content_hint.idl",
+ "//third_party/blink/renderer/modules/mediastream/media_stream_track_event.idl",
+ "//third_party/blink/renderer/modules/mediastream/media_stream_track_event_init.idl",
+ "//third_party/blink/renderer/modules/mediastream/media_track_capabilities.idl",
+ "//third_party/blink/renderer/modules/mediastream/media_track_constraint_set.idl",
+ "//third_party/blink/renderer/modules/mediastream/media_track_constraints.idl",
+ "//third_party/blink/renderer/modules/mediastream/media_track_settings.idl",
+ "//third_party/blink/renderer/modules/mediastream/media_track_supported_constraints.idl",
+ "//third_party/blink/renderer/modules/mediastream/navigator_media_stream.idl",
+ "//third_party/blink/renderer/modules/mediastream/navigator_user_media.idl",
+ "//third_party/blink/renderer/modules/mediastream/overconstrained_error.idl",
+ "//third_party/blink/renderer/modules/mediastream/testing/internals_media_stream.idl",
+ "//third_party/blink/renderer/modules/mediastream/window_media_stream.idl",
+ "//third_party/blink/renderer/modules/native_file_system/choose_file_system_entries_options.idl",
+ "//third_party/blink/renderer/modules/native_file_system/choose_file_system_entries_options_accepts.idl",
+ "//third_party/blink/renderer/modules/native_file_system/file_system_create_writer_options.idl",
+ "//third_party/blink/renderer/modules/native_file_system/file_system_directory_handle.idl",
+ "//third_party/blink/renderer/modules/native_file_system/file_system_file_handle.idl",
+ "//third_party/blink/renderer/modules/native_file_system/file_system_get_directory_options.idl",
+ "//third_party/blink/renderer/modules/native_file_system/file_system_get_file_options.idl",
+ "//third_party/blink/renderer/modules/native_file_system/file_system_handle.idl",
+ "//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/write_params.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",
+ "//third_party/blink/renderer/modules/native_io/window_native_io.idl",
+ "//third_party/blink/renderer/modules/native_io/worker_global_scope_native_io.idl",
+ "//third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.idl",
+ "//third_party/blink/renderer/modules/netinfo/navigator_network_information.idl",
+ "//third_party/blink/renderer/modules/netinfo/network_information.idl",
+ "//third_party/blink/renderer/modules/netinfo/testing/internals_net_info.idl",
+ "//third_party/blink/renderer/modules/netinfo/worker_navigator_network_information.idl",
+ "//third_party/blink/renderer/modules/nfc/ndef_message.idl",
+ "//third_party/blink/renderer/modules/nfc/ndef_message_init.idl",
+ "//third_party/blink/renderer/modules/nfc/ndef_reader.idl",
+ "//third_party/blink/renderer/modules/nfc/ndef_reading_event.idl",
+ "//third_party/blink/renderer/modules/nfc/ndef_reading_event_init.idl",
+ "//third_party/blink/renderer/modules/nfc/ndef_record.idl",
+ "//third_party/blink/renderer/modules/nfc/ndef_record_init.idl",
+ "//third_party/blink/renderer/modules/nfc/ndef_scan_options.idl",
+ "//third_party/blink/renderer/modules/nfc/ndef_write_options.idl",
+ "//third_party/blink/renderer/modules/nfc/ndef_writer.idl",
+ "//third_party/blink/renderer/modules/notifications/get_notification_options.idl",
+ "//third_party/blink/renderer/modules/notifications/notification.idl",
+ "//third_party/blink/renderer/modules/notifications/notification_action.idl",
+ "//third_party/blink/renderer/modules/notifications/notification_event.idl",
+ "//third_party/blink/renderer/modules/notifications/notification_event_init.idl",
+ "//third_party/blink/renderer/modules/notifications/notification_options.idl",
+ "//third_party/blink/renderer/modules/notifications/service_worker_global_scope_notifications.idl",
+ "//third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.idl",
+ "//third_party/blink/renderer/modules/notifications/timestamp_trigger.idl",
+ "//third_party/blink/renderer/modules/payments/abort_payment_event.idl",
+ "//third_party/blink/renderer/modules/payments/address_errors.idl",
+ "//third_party/blink/renderer/modules/payments/address_init.idl",
+ "//third_party/blink/renderer/modules/payments/android_pay_method_data.idl",
+ "//third_party/blink/renderer/modules/payments/basic_card_request.idl",
+ "//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/html_iframe_element_payments.idl",
+ "//third_party/blink/renderer/modules/payments/image_object.idl",
+ "//third_party/blink/renderer/modules/payments/merchant_validation_event.idl",
+ "//third_party/blink/renderer/modules/payments/merchant_validation_event_init.idl",
+ "//third_party/blink/renderer/modules/payments/payer_errors.idl",
+ "//third_party/blink/renderer/modules/payments/payment_address.idl",
+ "//third_party/blink/renderer/modules/payments/payment_app_service_worker_global_scope.idl",
+ "//third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.idl",
+ "//third_party/blink/renderer/modules/payments/payment_currency_amount.idl",
+ "//third_party/blink/renderer/modules/payments/payment_details_base.idl",
+ "//third_party/blink/renderer/modules/payments/payment_details_init.idl",
+ "//third_party/blink/renderer/modules/payments/payment_details_modifier.idl",
+ "//third_party/blink/renderer/modules/payments/payment_details_update.idl",
+ "//third_party/blink/renderer/modules/payments/payment_handler_response.idl",
+ "//third_party/blink/renderer/modules/payments/payment_instrument.idl",
+ "//third_party/blink/renderer/modules/payments/payment_instruments.idl",
+ "//third_party/blink/renderer/modules/payments/payment_item.idl",
+ "//third_party/blink/renderer/modules/payments/payment_manager.idl",
+ "//third_party/blink/renderer/modules/payments/payment_method_change_event.idl",
+ "//third_party/blink/renderer/modules/payments/payment_method_change_event_init.idl",
+ "//third_party/blink/renderer/modules/payments/payment_method_data.idl",
+ "//third_party/blink/renderer/modules/payments/payment_options.idl",
+ "//third_party/blink/renderer/modules/payments/payment_request.idl",
+ "//third_party/blink/renderer/modules/payments/payment_request_details_update.idl",
+ "//third_party/blink/renderer/modules/payments/payment_request_event.idl",
+ "//third_party/blink/renderer/modules/payments/payment_request_event_init.idl",
+ "//third_party/blink/renderer/modules/payments/payment_request_update_event.idl",
+ "//third_party/blink/renderer/modules/payments/payment_request_update_event_init.idl",
+ "//third_party/blink/renderer/modules/payments/payment_response.idl",
+ "//third_party/blink/renderer/modules/payments/payment_shipping_option.idl",
+ "//third_party/blink/renderer/modules/payments/payment_validation_errors.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_answer_options.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_certificate.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_configuration.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_data_channel.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event_init.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_data_channel_init.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_dtls_fingerprint.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.idl",
+ "//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_video_frame.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_error.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_error_event.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_error_event_init.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_error_init.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate_init.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate_pair.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_ice_gather_options.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_ice_parameters.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_ice_server.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_insertable_streams.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_legacy_stats_report.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_offer_answer_options.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_offer_options.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event_init.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event_init.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_quic_parameters.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event_init.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_read_result.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_write_parameters.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_stats.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_rtcp_parameters.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_rtp_capabilities.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_rtp_codec_capability.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_rtp_codec_parameters.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_rtp_coding_parameters.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_rtp_contributing_source.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_rtp_decoding_parameters.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_rtp_encoding_parameters.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_rtp_header_extension_capability.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_rtp_header_extension_parameters.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_rtp_parameters.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_rtp_receive_parameters.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_rtp_send_parameters.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_rtp_synchronization_source.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_init.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_session_description.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_session_description_init.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_stats_report.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_stats_response.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_track_event.idl",
+ "//third_party/blink/renderer/modules/peerconnection/rtc_track_event_init.idl",
+ "//third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_certificate.idl",
+ "//third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.idl",
+ "//third_party/blink/renderer/modules/permissions/clipboard_permission_descriptor.idl",
+ "//third_party/blink/renderer/modules/permissions/midi_permission_descriptor.idl",
+ "//third_party/blink/renderer/modules/permissions/navigator_permissions.idl",
+ "//third_party/blink/renderer/modules/permissions/permission_descriptor.idl",
+ "//third_party/blink/renderer/modules/permissions/permission_status.idl",
+ "//third_party/blink/renderer/modules/permissions/permissions.idl",
+ "//third_party/blink/renderer/modules/permissions/push_permission_descriptor.idl",
+ "//third_party/blink/renderer/modules/permissions/testing/internals_permission.idl",
+ "//third_party/blink/renderer/modules/permissions/wake_lock_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/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",
+ "//third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.idl",
+ "//third_party/blink/renderer/modules/picture_in_picture/shadow_root_picture_in_picture.idl",
+ "//third_party/blink/renderer/modules/plugins/mime_type.idl",
+ "//third_party/blink/renderer/modules/plugins/mime_type_array.idl",
+ "//third_party/blink/renderer/modules/plugins/navigator_plugins.idl",
+ "//third_party/blink/renderer/modules/plugins/plugin.idl",
+ "//third_party/blink/renderer/modules/plugins/plugin_array.idl",
+ "//third_party/blink/renderer/modules/presentation/navigator_presentation.idl",
+ "//third_party/blink/renderer/modules/presentation/presentation.idl",
+ "//third_party/blink/renderer/modules/presentation/presentation_availability.idl",
+ "//third_party/blink/renderer/modules/presentation/presentation_connection.idl",
+ "//third_party/blink/renderer/modules/presentation/presentation_connection_available_event.idl",
+ "//third_party/blink/renderer/modules/presentation/presentation_connection_available_event_init.idl",
+ "//third_party/blink/renderer/modules/presentation/presentation_connection_close_event.idl",
+ "//third_party/blink/renderer/modules/presentation/presentation_connection_close_event_init.idl",
+ "//third_party/blink/renderer/modules/presentation/presentation_connection_list.idl",
+ "//third_party/blink/renderer/modules/presentation/presentation_receiver.idl",
+ "//third_party/blink/renderer/modules/presentation/presentation_request.idl",
+ "//third_party/blink/renderer/modules/push_messaging/push_event.idl",
+ "//third_party/blink/renderer/modules/push_messaging/push_event_init.idl",
+ "//third_party/blink/renderer/modules/push_messaging/push_manager.idl",
+ "//third_party/blink/renderer/modules/push_messaging/push_message_data.idl",
+ "//third_party/blink/renderer/modules/push_messaging/push_subscription.idl",
+ "//third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.idl",
+ "//third_party/blink/renderer/modules/push_messaging/push_subscription_change_event_init.idl",
+ "//third_party/blink/renderer/modules/push_messaging/push_subscription_options.idl",
+ "//third_party/blink/renderer/modules/push_messaging/push_subscription_options_init.idl",
+ "//third_party/blink/renderer/modules/push_messaging/service_worker_global_scope_push.idl",
+ "//third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.idl",
+ "//third_party/blink/renderer/modules/quota/deprecated_storage_callbacks.idl",
+ "//third_party/blink/renderer/modules/quota/deprecated_storage_info.idl",
+ "//third_party/blink/renderer/modules/quota/deprecated_storage_quota.idl",
+ "//third_party/blink/renderer/modules/quota/dom_error.idl",
+ "//third_party/blink/renderer/modules/quota/navigator_storage_quota.idl",
+ "//third_party/blink/renderer/modules/quota/storage_estimate.idl",
+ "//third_party/blink/renderer/modules/quota/storage_manager.idl",
+ "//third_party/blink/renderer/modules/quota/storage_usage_details.idl",
+ "//third_party/blink/renderer/modules/quota/window_quota.idl",
+ "//third_party/blink/renderer/modules/quota/worker_navigator_storage_quota.idl",
+ "//third_party/blink/renderer/modules/remoteplayback/html_media_element_remote_playback.idl",
+ "//third_party/blink/renderer/modules/remoteplayback/remote_playback.idl",
+ "//third_party/blink/renderer/modules/scheduler/scheduler.idl",
+ "//third_party/blink/renderer/modules/scheduler/scheduler_post_task_options.idl",
+ "//third_party/blink/renderer/modules/scheduler/task_controller.idl",
+ "//third_party/blink/renderer/modules/scheduler/task_signal.idl",
+ "//third_party/blink/renderer/modules/scheduler/window_scheduler.idl",
+ "//third_party/blink/renderer/modules/screen_enumeration/screen_enumeration.idl",
+ "//third_party/blink/renderer/modules/screen_orientation/screen_orientation.idl",
+ "//third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.idl",
+ "//third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.idl",
+ "//third_party/blink/renderer/modules/sensor/accelerometer.idl",
+ "//third_party/blink/renderer/modules/sensor/ambient_light_sensor.idl",
+ "//third_party/blink/renderer/modules/sensor/gyroscope.idl",
+ "//third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.idl",
+ "//third_party/blink/renderer/modules/sensor/magnetometer.idl",
+ "//third_party/blink/renderer/modules/sensor/orientation_sensor.idl",
+ "//third_party/blink/renderer/modules/sensor/relative_orientation_sensor.idl",
+ "//third_party/blink/renderer/modules/sensor/sensor.idl",
+ "//third_party/blink/renderer/modules/sensor/sensor_error_event.idl",
+ "//third_party/blink/renderer/modules/sensor/sensor_error_event_init.idl",
+ "//third_party/blink/renderer/modules/sensor/sensor_options.idl",
+ "//third_party/blink/renderer/modules/sensor/spatial_sensor_options.idl",
+ "//third_party/blink/renderer/modules/service_worker/client.idl",
+ "//third_party/blink/renderer/modules/service_worker/client_query_options.idl",
+ "//third_party/blink/renderer/modules/service_worker/clients.idl",
+ "//third_party/blink/renderer/modules/service_worker/extendable_event.idl",
+ "//third_party/blink/renderer/modules/service_worker/extendable_event_init.idl",
+ "//third_party/blink/renderer/modules/service_worker/extendable_message_event.idl",
+ "//third_party/blink/renderer/modules/service_worker/extendable_message_event_init.idl",
+ "//third_party/blink/renderer/modules/service_worker/fetch_event.idl",
+ "//third_party/blink/renderer/modules/service_worker/fetch_event_init.idl",
+ "//third_party/blink/renderer/modules/service_worker/install_event.idl",
+ "//third_party/blink/renderer/modules/service_worker/navigation_preload_manager.idl",
+ "//third_party/blink/renderer/modules/service_worker/navigation_preload_state.idl",
+ "//third_party/blink/renderer/modules/service_worker/navigator_service_worker.idl",
+ "//third_party/blink/renderer/modules/service_worker/registration_options.idl",
+ "//third_party/blink/renderer/modules/service_worker/service_worker.idl",
+ "//third_party/blink/renderer/modules/service_worker/service_worker_container.idl",
+ "//third_party/blink/renderer/modules/service_worker/service_worker_global_scope.idl",
+ "//third_party/blink/renderer/modules/service_worker/service_worker_registration.idl",
+ "//third_party/blink/renderer/modules/service_worker/testing/internals_service_worker.idl",
+ "//third_party/blink/renderer/modules/service_worker/window_client.idl",
+ "//third_party/blink/renderer/modules/shapedetection/barcode_detector.idl",
+ "//third_party/blink/renderer/modules/shapedetection/barcode_detector_options.idl",
+ "//third_party/blink/renderer/modules/shapedetection/detected_barcode.idl",
+ "//third_party/blink/renderer/modules/shapedetection/detected_face.idl",
+ "//third_party/blink/renderer/modules/shapedetection/detected_text.idl",
+ "//third_party/blink/renderer/modules/shapedetection/face_detector.idl",
+ "//third_party/blink/renderer/modules/shapedetection/face_detector_options.idl",
+ "//third_party/blink/renderer/modules/shapedetection/landmark.idl",
+ "//third_party/blink/renderer/modules/shapedetection/text_detector.idl",
+ "//third_party/blink/renderer/modules/speech/speech_grammar.idl",
+ "//third_party/blink/renderer/modules/speech/speech_grammar_list.idl",
+ "//third_party/blink/renderer/modules/speech/speech_recognition.idl",
+ "//third_party/blink/renderer/modules/speech/speech_recognition_alternative.idl",
+ "//third_party/blink/renderer/modules/speech/speech_recognition_error_event.idl",
+ "//third_party/blink/renderer/modules/speech/speech_recognition_error_event_init.idl",
+ "//third_party/blink/renderer/modules/speech/speech_recognition_event.idl",
+ "//third_party/blink/renderer/modules/speech/speech_recognition_event_init.idl",
+ "//third_party/blink/renderer/modules/speech/speech_recognition_result.idl",
+ "//third_party/blink/renderer/modules/speech/speech_recognition_result_list.idl",
+ "//third_party/blink/renderer/modules/speech/speech_synthesis.idl",
+ "//third_party/blink/renderer/modules/speech/speech_synthesis_error_event.idl",
+ "//third_party/blink/renderer/modules/speech/speech_synthesis_error_event_init.idl",
+ "//third_party/blink/renderer/modules/speech/speech_synthesis_event.idl",
+ "//third_party/blink/renderer/modules/speech/speech_synthesis_event_init.idl",
+ "//third_party/blink/renderer/modules/speech/speech_synthesis_utterance.idl",
+ "//third_party/blink/renderer/modules/speech/speech_synthesis_voice.idl",
+ "//third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.idl",
+ "//third_party/blink/renderer/modules/speech/window_speech.idl",
+ "//third_party/blink/renderer/modules/speech/window_speech_synthesis.idl",
+ "//third_party/blink/renderer/modules/srcobject/html_media_element_src_object.idl",
+ "//third_party/blink/renderer/modules/storage/storage.idl",
+ "//third_party/blink/renderer/modules/storage/storage_event.idl",
+ "//third_party/blink/renderer/modules/storage/storage_event_init.idl",
+ "//third_party/blink/renderer/modules/storage/window_storage.idl",
+ "//third_party/blink/renderer/modules/vibration/navigator_vibration.idl",
+ "//third_party/blink/renderer/modules/vibration/testing/internals_vibration.idl",
+ "//third_party/blink/renderer/modules/video_rvfc/html_video_element_request_video_frame_callback.idl",
+ "//third_party/blink/renderer/modules/video_rvfc/video_frame_metadata.idl",
+ "//third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback.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",
+ "//third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.idl",
+ "//third_party/blink/renderer/modules/webaudio/analyser_node.idl",
+ "//third_party/blink/renderer/modules/webaudio/analyser_options.idl",
+ "//third_party/blink/renderer/modules/webaudio/audio_buffer.idl",
+ "//third_party/blink/renderer/modules/webaudio/audio_buffer_options.idl",
+ "//third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.idl",
+ "//third_party/blink/renderer/modules/webaudio/audio_buffer_source_options.idl",
+ "//third_party/blink/renderer/modules/webaudio/audio_context.idl",
+ "//third_party/blink/renderer/modules/webaudio/audio_context_options.idl",
+ "//third_party/blink/renderer/modules/webaudio/audio_destination_node.idl",
+ "//third_party/blink/renderer/modules/webaudio/audio_listener.idl",
+ "//third_party/blink/renderer/modules/webaudio/audio_node.idl",
+ "//third_party/blink/renderer/modules/webaudio/audio_node_options.idl",
+ "//third_party/blink/renderer/modules/webaudio/audio_param.idl",
+ "//third_party/blink/renderer/modules/webaudio/audio_param_descriptor.idl",
+ "//third_party/blink/renderer/modules/webaudio/audio_param_map.idl",
+ "//third_party/blink/renderer/modules/webaudio/audio_processing_event.idl",
+ "//third_party/blink/renderer/modules/webaudio/audio_processing_event_init.idl",
+ "//third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.idl",
+ "//third_party/blink/renderer/modules/webaudio/audio_timestamp.idl",
+ "//third_party/blink/renderer/modules/webaudio/audio_worklet.idl",
+ "//third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.idl",
+ "//third_party/blink/renderer/modules/webaudio/audio_worklet_node.idl",
+ "//third_party/blink/renderer/modules/webaudio/audio_worklet_node_options.idl",
+ "//third_party/blink/renderer/modules/webaudio/audio_worklet_processor.idl",
+ "//third_party/blink/renderer/modules/webaudio/base_audio_context.idl",
+ "//third_party/blink/renderer/modules/webaudio/biquad_filter_node.idl",
+ "//third_party/blink/renderer/modules/webaudio/biquad_filter_options.idl",
+ "//third_party/blink/renderer/modules/webaudio/channel_merger_node.idl",
+ "//third_party/blink/renderer/modules/webaudio/channel_merger_options.idl",
+ "//third_party/blink/renderer/modules/webaudio/channel_splitter_node.idl",
+ "//third_party/blink/renderer/modules/webaudio/channel_splitter_options.idl",
+ "//third_party/blink/renderer/modules/webaudio/constant_source_node.idl",
+ "//third_party/blink/renderer/modules/webaudio/constant_source_options.idl",
+ "//third_party/blink/renderer/modules/webaudio/convolver_node.idl",
+ "//third_party/blink/renderer/modules/webaudio/convolver_options.idl",
+ "//third_party/blink/renderer/modules/webaudio/delay_node.idl",
+ "//third_party/blink/renderer/modules/webaudio/delay_options.idl",
+ "//third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.idl",
+ "//third_party/blink/renderer/modules/webaudio/dynamics_compressor_options.idl",
+ "//third_party/blink/renderer/modules/webaudio/gain_node.idl",
+ "//third_party/blink/renderer/modules/webaudio/gain_options.idl",
+ "//third_party/blink/renderer/modules/webaudio/iir_filter_node.idl",
+ "//third_party/blink/renderer/modules/webaudio/iir_filter_options.idl",
+ "//third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.idl",
+ "//third_party/blink/renderer/modules/webaudio/media_element_audio_source_options.idl",
+ "//third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.idl",
+ "//third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.idl",
+ "//third_party/blink/renderer/modules/webaudio/media_stream_audio_source_options.idl",
+ "//third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.idl",
+ "//third_party/blink/renderer/modules/webaudio/offline_audio_completion_event_init.idl",
+ "//third_party/blink/renderer/modules/webaudio/offline_audio_context.idl",
+ "//third_party/blink/renderer/modules/webaudio/offline_audio_context_options.idl",
+ "//third_party/blink/renderer/modules/webaudio/oscillator_node.idl",
+ "//third_party/blink/renderer/modules/webaudio/oscillator_options.idl",
+ "//third_party/blink/renderer/modules/webaudio/panner_node.idl",
+ "//third_party/blink/renderer/modules/webaudio/panner_options.idl",
+ "//third_party/blink/renderer/modules/webaudio/periodic_wave.idl",
+ "//third_party/blink/renderer/modules/webaudio/periodic_wave_constraints.idl",
+ "//third_party/blink/renderer/modules/webaudio/periodic_wave_options.idl",
+ "//third_party/blink/renderer/modules/webaudio/script_processor_node.idl",
+ "//third_party/blink/renderer/modules/webaudio/stereo_panner_node.idl",
+ "//third_party/blink/renderer/modules/webaudio/stereo_panner_options.idl",
+ "//third_party/blink/renderer/modules/webaudio/testing/internals_web_audio.idl",
+ "//third_party/blink/renderer/modules/webaudio/wave_shaper_node.idl",
+ "//third_party/blink/renderer/modules/webaudio/wave_shaper_options.idl",
+ "//third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.idl",
+ "//third_party/blink/renderer/modules/webcodecs/encoded_video_config.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_frame.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",
+ "//third_party/blink/renderer/modules/webcodecs/webcodecs_error_callback.idl",
+ "//third_party/blink/renderer/modules/webdatabase/database.idl",
+ "//third_party/blink/renderer/modules/webdatabase/sql_error.idl",
+ "//third_party/blink/renderer/modules/webdatabase/sql_result_set.idl",
+ "//third_party/blink/renderer/modules/webdatabase/sql_result_set_row_list.idl",
+ "//third_party/blink/renderer/modules/webdatabase/sql_statement_callback.idl",
+ "//third_party/blink/renderer/modules/webdatabase/sql_statement_error_callback.idl",
+ "//third_party/blink/renderer/modules/webdatabase/sql_transaction.idl",
+ "//third_party/blink/renderer/modules/webdatabase/sql_transaction_callback.idl",
+ "//third_party/blink/renderer/modules/webdatabase/sql_transaction_error_callback.idl",
+ "//third_party/blink/renderer/modules/webdatabase/window_web_database.idl",
+ "//third_party/blink/renderer/modules/webgl/angle_instanced_arrays.idl",
+ "//third_party/blink/renderer/modules/webgl/ext_blend_min_max.idl",
+ "//third_party/blink/renderer/modules/webgl/ext_color_buffer_float.idl",
+ "//third_party/blink/renderer/modules/webgl/ext_color_buffer_half_float.idl",
+ "//third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.idl",
+ "//third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.idl",
+ "//third_party/blink/renderer/modules/webgl/ext_float_blend.idl",
+ "//third_party/blink/renderer/modules/webgl/ext_frag_depth.idl",
+ "//third_party/blink/renderer/modules/webgl/ext_shader_texture_lod.idl",
+ "//third_party/blink/renderer/modules/webgl/ext_srgb.idl",
+ "//third_party/blink/renderer/modules/webgl/ext_texture_compression_bptc.idl",
+ "//third_party/blink/renderer/modules/webgl/ext_texture_compression_rgtc.idl",
+ "//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_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",
+ "//third_party/blink/renderer/modules/webgl/oes_texture_float.idl",
+ "//third_party/blink/renderer/modules/webgl/oes_texture_float_linear.idl",
+ "//third_party/blink/renderer/modules/webgl/oes_texture_half_float.idl",
+ "//third_party/blink/renderer/modules/webgl/oes_texture_half_float_linear.idl",
+ "//third_party/blink/renderer/modules/webgl/oes_vertex_array_object.idl",
+ "//third_party/blink/renderer/modules/webgl/ovr_multiview_2.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl2_rendering_context.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_active_info.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_buffer.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_color_buffer_float.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_compressed_texture_astc.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc1.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_compressed_texture_pvrtc.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc_srgb.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_context_attributes.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_context_event.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_context_event_init.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_debug_renderer_info.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_debug_shaders.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_depth_texture.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_draw_buffers.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_draw_instanced_base_vertex_base_instance.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_framebuffer.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_lose_context.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_multi_draw.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_multi_draw_instanced_base_vertex_base_instance.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_program.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_query.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_renderbuffer.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_rendering_context.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_sampler.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_shader.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_shader_precision_format.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_sync.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_texture.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_timer_query_ext.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_transform_feedback.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_uniform_location.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_vertex_array_object.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_oes.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl_video_texture.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_adapter.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_bind_group.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_bind_group_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_bind_group_entry.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_entry.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_blend_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_buffer.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_buffer_binding.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_buffer_copy_view.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_buffer_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_buffer_usage.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_canvas_context.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_color_dict.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_color_state_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_color_write.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_command_buffer.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_command_buffer_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_command_encoder.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_command_encoder_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_compute_pass_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_depth_stencil_state_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_device.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_device_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_extent_3d_dict.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_fence.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_fence_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_image_bitmap_copy_view.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_limits.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_object_descriptor_base.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_origin_2d_dict.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_origin_3d_dict.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_out_of_memory_error.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_pipeline_descriptor_base.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_programmable_stage_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_queue.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_rasterization_state_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_render_bundle.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_render_bundle_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_render_encoder_base.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_render_pass_color_attachment_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_render_pass_depth_stencil_attachment_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_render_pass_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_render_pipeline_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_request_adapter_options.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_sampler.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_sampler_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_shader_module.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_shader_module_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_shader_stage.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_stencil_state_face_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_swap_chain.idl",
+ "//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_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_texture_usage.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_texture_view.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_texture_view_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event_init.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_validation_error.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_vertex_attribute_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_vertex_buffer_layout_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/gpu_vertex_state_descriptor.idl",
+ "//third_party/blink/renderer/modules/webgpu/navigator_gpu.idl",
+ "//third_party/blink/renderer/modules/webgpu/worker_navigator_gpu.idl",
+ "//third_party/blink/renderer/modules/webmidi/midi_access.idl",
+ "//third_party/blink/renderer/modules/webmidi/midi_connection_event.idl",
+ "//third_party/blink/renderer/modules/webmidi/midi_connection_event_init.idl",
+ "//third_party/blink/renderer/modules/webmidi/midi_input.idl",
+ "//third_party/blink/renderer/modules/webmidi/midi_input_map.idl",
+ "//third_party/blink/renderer/modules/webmidi/midi_message_event.idl",
+ "//third_party/blink/renderer/modules/webmidi/midi_message_event_init.idl",
+ "//third_party/blink/renderer/modules/webmidi/midi_options.idl",
+ "//third_party/blink/renderer/modules/webmidi/midi_output.idl",
+ "//third_party/blink/renderer/modules/webmidi/midi_output_map.idl",
+ "//third_party/blink/renderer/modules/webmidi/midi_port.idl",
+ "//third_party/blink/renderer/modules/webmidi/navigator_web_midi.idl",
+ "//third_party/blink/renderer/modules/webshare/navigator_share.idl",
+ "//third_party/blink/renderer/modules/webshare/share_data.idl",
+ "//third_party/blink/renderer/modules/websockets/close_event.idl",
+ "//third_party/blink/renderer/modules/websockets/close_event_init.idl",
+ "//third_party/blink/renderer/modules/websockets/websocket.idl",
+ "//third_party/blink/renderer/modules/websockets/websocket_close_info.idl",
+ "//third_party/blink/renderer/modules/websockets/websocket_connection.idl",
+ "//third_party/blink/renderer/modules/websockets/websocket_stream.idl",
+ "//third_party/blink/renderer/modules/websockets/websocket_stream_options.idl",
+ "//third_party/blink/renderer/modules/webtransport/incoming_stream.idl",
+ "//third_party/blink/renderer/modules/webtransport/outgoing_stream.idl",
+ "//third_party/blink/renderer/modules/webtransport/quic_transport.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",
+ "//third_party/blink/renderer/modules/webtransport/web_transport_close_info.idl",
+ "//third_party/blink/renderer/modules/webusb/navigator_usb.idl",
+ "//third_party/blink/renderer/modules/webusb/usb.idl",
+ "//third_party/blink/renderer/modules/webusb/usb_alternate_interface.idl",
+ "//third_party/blink/renderer/modules/webusb/usb_configuration.idl",
+ "//third_party/blink/renderer/modules/webusb/usb_connection_event.idl",
+ "//third_party/blink/renderer/modules/webusb/usb_connection_event_init.idl",
+ "//third_party/blink/renderer/modules/webusb/usb_control_transfer_parameters.idl",
+ "//third_party/blink/renderer/modules/webusb/usb_device.idl",
+ "//third_party/blink/renderer/modules/webusb/usb_device_filter.idl",
+ "//third_party/blink/renderer/modules/webusb/usb_device_request_options.idl",
+ "//third_party/blink/renderer/modules/webusb/usb_endpoint.idl",
+ "//third_party/blink/renderer/modules/webusb/usb_in_transfer_result.idl",
+ "//third_party/blink/renderer/modules/webusb/usb_interface.idl",
+ "//third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_packet.idl",
+ "//third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_result.idl",
+ "//third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_packet.idl",
+ "//third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_result.idl",
+ "//third_party/blink/renderer/modules/webusb/usb_out_transfer_result.idl",
+ "//third_party/blink/renderer/modules/webusb/worker_navigator_usb.idl",
+ "//third_party/blink/renderer/modules/xr/element_xr.idl",
+ "//third_party/blink/renderer/modules/xr/navigator_xr.idl",
+ "//third_party/blink/renderer/modules/xr/xr_anchor.idl",
+ "//third_party/blink/renderer/modules/xr/xr_anchor_set.idl",
+ "//third_party/blink/renderer/modules/xr/xr_bounded_reference_space.idl",
+ "//third_party/blink/renderer/modules/xr/xr_cube_map.idl",
+ "//third_party/blink/renderer/modules/xr/xr_dom_overlay_init.idl",
+ "//third_party/blink/renderer/modules/xr/xr_dom_overlay_state.idl",
+ "//third_party/blink/renderer/modules/xr/xr_frame.idl",
+ "//third_party/blink/renderer/modules/xr/xr_frame_request_callback.idl",
+ "//third_party/blink/renderer/modules/xr/xr_hit_test_options_init.idl",
+ "//third_party/blink/renderer/modules/xr/xr_hit_test_result.idl",
+ "//third_party/blink/renderer/modules/xr/xr_hit_test_source.idl",
+ "//third_party/blink/renderer/modules/xr/xr_input_source.idl",
+ "//third_party/blink/renderer/modules/xr/xr_input_source_array.idl",
+ "//third_party/blink/renderer/modules/xr/xr_input_source_event.idl",
+ "//third_party/blink/renderer/modules/xr/xr_input_source_event_init.idl",
+ "//third_party/blink/renderer/modules/xr/xr_input_sources_change_event.idl",
+ "//third_party/blink/renderer/modules/xr/xr_input_sources_change_event_init.idl",
+ "//third_party/blink/renderer/modules/xr/xr_light_estimation.idl",
+ "//third_party/blink/renderer/modules/xr/xr_light_estimation_state.idl",
+ "//third_party/blink/renderer/modules/xr/xr_light_estimation_state_init.idl",
+ "//third_party/blink/renderer/modules/xr/xr_light_probe.idl",
+ "//third_party/blink/renderer/modules/xr/xr_plane.idl",
+ "//third_party/blink/renderer/modules/xr/xr_plane_detection_state.idl",
+ "//third_party/blink/renderer/modules/xr/xr_plane_detection_state_init.idl",
+ "//third_party/blink/renderer/modules/xr/xr_plane_set.idl",
+ "//third_party/blink/renderer/modules/xr/xr_pose.idl",
+ "//third_party/blink/renderer/modules/xr/xr_ray.idl",
+ "//third_party/blink/renderer/modules/xr/xr_reference_space.idl",
+ "//third_party/blink/renderer/modules/xr/xr_reference_space_event.idl",
+ "//third_party/blink/renderer/modules/xr/xr_reference_space_event_init.idl",
+ "//third_party/blink/renderer/modules/xr/xr_reflection_probe.idl",
+ "//third_party/blink/renderer/modules/xr/xr_render_state.idl",
+ "//third_party/blink/renderer/modules/xr/xr_render_state_init.idl",
+ "//third_party/blink/renderer/modules/xr/xr_rigid_transform.idl",
+ "//third_party/blink/renderer/modules/xr/xr_session.idl",
+ "//third_party/blink/renderer/modules/xr/xr_session_event.idl",
+ "//third_party/blink/renderer/modules/xr/xr_session_event_init.idl",
+ "//third_party/blink/renderer/modules/xr/xr_session_init.idl",
+ "//third_party/blink/renderer/modules/xr/xr_space.idl",
+ "//third_party/blink/renderer/modules/xr/xr_spherical_harmonics.idl",
+ "//third_party/blink/renderer/modules/xr/xr_system.idl",
+ "//third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_options_init.idl",
+ "//third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_result.idl",
+ "//third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.idl",
+ "//third_party/blink/renderer/modules/xr/xr_view.idl",
+ "//third_party/blink/renderer/modules/xr/xr_viewer_pose.idl",
+ "//third_party/blink/renderer/modules/xr/xr_viewport.idl",
+ "//third_party/blink/renderer/modules/xr/xr_webgl_layer.idl",
+ "//third_party/blink/renderer/modules/xr/xr_webgl_layer_init.idl",
+ "//third_party/blink/renderer/modules/xr/xr_world_information.idl",
+ "//third_party/blink/renderer/modules/xr/xr_world_tracking_state.idl",
+ "//third_party/blink/renderer/modules/xr/xr_world_tracking_state_init.idl",
+ ],
+ "abspath")
+
+# Serial
+if (!is_android) {
+ static_idl_files_in_modules += get_path_info(
+ [
+ "//third_party/blink/renderer/modules/serial/navigator_serial.idl",
+ "//third_party/blink/renderer/modules/serial/serial.idl",
+ "//third_party/blink/renderer/modules/serial/serial_connection_event.idl",
+ "//third_party/blink/renderer/modules/serial/serial_connection_event_init.idl",
+ "//third_party/blink/renderer/modules/serial/serial_input_signals.idl",
+ "//third_party/blink/renderer/modules/serial/serial_options.idl",
+ "//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_request_options.idl",
+ "//third_party/blink/renderer/modules/serial/worker_navigator_serial.idl",
+ ],
+ "abspath")
+}
+
+# WebGL2
+if (support_webgl2_compute_context) {
+ static_idl_files_in_modules += get_path_info(
+ [
+ "//third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_support_webgl2_compute.idl",
+ "//third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module_support_webgl2_compute.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.idl",
+ "//third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.idl",
+ ],
+ "abspath")
+} else {
+ static_idl_files_in_modules += get_path_info(
+ [
+ "//third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.idl",
+ "//third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.idl",
+ ],
+ "abspath")
+}
diff --git a/chromium/third_party/blink/renderer/bindings/modules/BUILD.gn b/chromium/third_party/blink/renderer/bindings/modules/BUILD.gn
index d0ff4117cff..4d47a971b0e 100644
--- a/chromium/third_party/blink/renderer/bindings/modules/BUILD.gn
+++ b/chromium/third_party/blink/renderer/bindings/modules/BUILD.gn
@@ -39,7 +39,6 @@ generate_event_interfaces("modules_bindings_generated_event_interfaces") {
"//third_party/blink/renderer/modules/mediarecorder/blob_event.idl",
"//third_party/blink/renderer/modules/mediastream/media_stream_event.idl",
"//third_party/blink/renderer/modules/mediastream/media_stream_track_event.idl",
- "//third_party/blink/renderer/modules/nfc/ndef_error_event.idl",
"//third_party/blink/renderer/modules/nfc/ndef_reading_event.idl",
"//third_party/blink/renderer/modules/notifications/notification_event.idl",
"//third_party/blink/renderer/modules/payments/abort_payment_event.idl",
@@ -87,9 +86,7 @@ generate_event_interfaces("modules_bindings_generated_event_interfaces") {
make_event_factory("event_modules") {
visibility = [ ":*" ]
in_files = [ "$blink_modules_output_dir/event_interface_modules_names.json5" ]
- outputs = [
- "$blink_modules_output_dir/event_modules_factory.cc",
- ]
+ outputs = [ "$blink_modules_output_dir/event_modules_factory.cc" ]
deps = make_core_generated_deps + [ "//third_party/blink/renderer/bindings/modules:modules_bindings_generated_event_interfaces" ]
}
@@ -127,9 +124,7 @@ compute_global_objects("modules_global_objects") {
sources = modules_idl_files
sources_generated = [ "$bindings_core_output_dir/global_objects_core.pickle" ]
output_file = "$bindings_modules_output_dir/global_objects_modules.pickle"
- deps = [
- "//third_party/blink/renderer/bindings/core:core_global_objects",
- ]
+ deps = [ "//third_party/blink/renderer/bindings/core:core_global_objects" ]
}
generate_global_constructors("modules_global_constructors_idls") {
@@ -140,9 +135,7 @@ generate_global_constructors("modules_global_constructors_idls") {
basenames = modules_global_constructors_original_interface_basenames
component = "modules"
output_dir = blink_modules_output_dir
- deps = [
- ":modules_global_objects",
- ]
+ deps = [ ":modules_global_objects" ]
}
# Compile the sources produced above. This will get linked into "modules".
diff --git a/chromium/third_party/blink/renderer/bindings/modules/v8/BUILD.gn b/chromium/third_party/blink/renderer/bindings/modules/v8/BUILD.gn
index 7f20ac335de..0d451eff74d 100644
--- a/chromium/third_party/blink/renderer/bindings/modules/v8/BUILD.gn
+++ b/chromium/third_party/blink/renderer/bindings/modules/v8/BUILD.gn
@@ -2,12 +2,20 @@
# 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/bindings/bindings.gni")
+import("//third_party/blink/renderer/bindings/generated_in_modules.gni")
import("//third_party/blink/renderer/bindings/modules/v8/generated.gni")
import("//third_party/blink/renderer/bindings/scripts/scripts.gni")
import("//third_party/blink/renderer/modules/modules.gni")
import("//third_party/blink/renderer/modules/modules_idl_files.gni")
-visibility = [ "//third_party/blink/*" ]
+visibility = [ "//third_party/blink/renderer/*" ]
+
+blink_modules_sources("generated") {
+ sources = generated_enumeration_sources_in_modules
+ deps =
+ [ "//third_party/blink/renderer/bindings:generate_bindings_enumeration" ]
+}
group("bindings_modules_v8_generated") {
public_deps = [
@@ -17,18 +25,26 @@ group("bindings_modules_v8_generated") {
":generate_bindings_modules_v8_partial_interfaces",
":generate_bindings_modules_v8_partial_interfaces_for_testing",
":generate_v8_context_snapshot_external_references",
+ "//third_party/blink/renderer/bindings:generate_v8_bindings",
]
}
idl_compiler("generate_bindings_modules_v8_interfaces") {
sources = modules_definition_idl_files
+ if (use_v8_bind_gen_for_dictionary) {
+ sources -= modules_dictionary_idl_files
+ }
output_dir = bindings_modules_v8_output_dir
output_name_suffix = ""
target_component = "modules"
}
idl_impl("bindings_modules_impl_generated") {
- dict_idls = modules_dictionary_idl_files
+ if (use_v8_bind_gen_for_dictionary) {
+ dict_idls = []
+ } else {
+ dict_idls = modules_dictionary_idl_files
+ }
non_dict_outputs = bindings_modules_generated_union_type_files +
generated_modules_callback_function_files
non_dict_output_dir = bindings_modules_v8_output_dir
@@ -64,12 +80,8 @@ generate_origin_trial_features("bindings_modules_origin_trial_features") {
action("bindings_modules_v8_generated_init_partial") {
script = "$bindings_scripts_dir/generate_init_partial_interfaces.py"
- inputs = [
- "$bindings_output_dir/interfaces_info.pickle",
- ]
- outputs = [
- bindings_modules_generated_init_partial_interfaces_file,
- ]
+ inputs = [ "$bindings_output_dir/interfaces_info.pickle" ]
+ outputs = [ bindings_modules_generated_init_partial_interfaces_file ]
# Put the IDL file list in a response file to avoid command-line limits.
response_file_contents =
@@ -83,9 +95,7 @@ action("bindings_modules_v8_generated_init_partial") {
root_build_dir),
]
- deps = [
- "//third_party/blink/renderer/bindings:interfaces_info",
- ]
+ deps = [ "//third_party/blink/renderer/bindings:interfaces_info" ]
}
# Note that this intentionally depends on the generator target of the mojom
@@ -121,10 +131,13 @@ blink_modules_sources("bindings_modules_impl") {
get_target_outputs(":bindings_modules_v8_generated_init_partial") +
get_target_outputs(":bindings_modules_origin_trial_features")
+ sources += generated_modules_dictionary_files
+
deps = [
":bindings_modules_origin_trial_features",
":bindings_modules_v8_generated",
":generate_mojo_bindings",
+ "//third_party/blink/renderer/bindings:generate_v8_bindings",
"//third_party/blink/renderer/modules/mediarecorder:buildflags",
"//third_party/dawn/src/dawn:dawn_headers",
]
@@ -137,9 +150,7 @@ action("generate_v8_context_snapshot_external_references") {
output = bindings_generated_v8_context_snapshot_external_references_file
inputs = idl_files + [ script ]
- outputs = [
- output,
- ]
+ outputs = [ output ]
response_file_contents = rebase_path(idl_files, root_build_dir)
args = [
diff --git a/chromium/third_party/blink/renderer/bindings/modules/v8/custom/custom.gni b/chromium/third_party/blink/renderer/bindings/modules/v8/custom/custom.gni
index d47363301a6..2b8700cd118 100644
--- a/chromium/third_party/blink/renderer/bindings/modules/v8/custom/custom.gni
+++ b/chromium/third_party/blink/renderer/bindings/modules/v8/custom/custom.gni
@@ -3,5 +3,4 @@
# found in the LICENSE file.
# Make the files absolute so they can be imported to anywhere.
-bindings_modules_v8_custom_files =
- get_path_info([ "v8_extendable_message_event_custom.cc" ], "abspath")
+bindings_modules_v8_custom_files = get_path_info([], "abspath")
diff --git a/chromium/third_party/blink/renderer/bindings/modules/v8/custom/v8_extendable_message_event_custom.cc b/chromium/third_party/blink/renderer/bindings/modules/v8/custom/v8_extendable_message_event_custom.cc
deleted file mode 100644
index 43f29083f27..00000000000
--- a/chromium/third_party/blink/renderer/bindings/modules/v8/custom/v8_extendable_message_event_custom.cc
+++ /dev/null
@@ -1,102 +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/bindings/modules/v8/v8_extendable_message_event.h"
-
-#include "third_party/blink/renderer/bindings/modules/v8/v8_extendable_message_event_init.h"
-#include "third_party/blink/renderer/core/events/message_event.h"
-#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
-
-namespace blink {
-
-void V8ExtendableMessageEvent::ConstructorCustom(
- const v8::FunctionCallbackInfo<v8::Value>& info) {
- v8::Isolate* isolate = info.GetIsolate();
- ExceptionState exception_state(isolate, ExceptionState::kConstructionContext,
- "ExtendableMessageEvent");
- if (UNLIKELY(info.Length() < 1)) {
- exception_state.ThrowTypeError(
- ExceptionMessages::NotEnoughArguments(1, info.Length()));
- return;
- }
-
- V8StringResource<> type = info[0];
- if (!type.Prepare())
- return;
-
- ExtendableMessageEventInit* event_init_dict =
- ExtendableMessageEventInit::Create();
- if (!IsUndefinedOrNull(info[1])) {
- if (!info[1]->IsObject()) {
- exception_state.ThrowTypeError(
- "parameter 2 ('eventInitDict') is not an object.");
- return;
- }
- V8ExtendableMessageEventInit::ToImpl(isolate, info[1], event_init_dict,
- exception_state);
- if (exception_state.HadException())
- return;
- }
-
- ExtendableMessageEvent* impl =
- ExtendableMessageEvent::Create(type, event_init_dict);
- v8::Local<v8::Object> wrapper = info.Holder();
- wrapper = impl->AssociateWithWrapper(
- isolate, V8ExtendableMessageEvent::GetWrapperTypeInfo(), wrapper);
-
- // TODO(bashi): Workaround for http://crbug.com/529941. We need to store
- // |data| as a private value to avoid cyclic references.
- if (event_init_dict->hasData()) {
- v8::Local<v8::Value> v8_data = event_init_dict->data().V8Value();
- V8PrivateProperty::GetSymbol(isolate,
- kPrivatePropertyMessageEventCachedData)
- .Set(wrapper, v8_data);
- if (DOMWrapperWorld::Current(isolate).IsIsolatedWorld()) {
- impl->SetSerializedData(
- SerializedScriptValue::SerializeAndSwallowExceptions(isolate,
- v8_data));
- }
- }
- V8SetReturnValue(info, wrapper);
-}
-
-void V8ExtendableMessageEvent::DataAttributeGetterCustom(
- const v8::FunctionCallbackInfo<v8::Value>& info) {
- ExtendableMessageEvent* event =
- V8ExtendableMessageEvent::ToImpl(info.Holder());
- v8::Isolate* isolate = info.GetIsolate();
- auto private_cached_data = V8PrivateProperty::GetSymbol(
- isolate, kPrivatePropertyMessageEventCachedData);
- v8::Local<v8::Value> result;
- if (private_cached_data.GetOrUndefined(info.Holder()).ToLocal(&result) &&
- !result->IsUndefined()) {
- V8SetReturnValue(info, result);
- return;
- }
-
- v8::Local<v8::Value> data;
- if (SerializedScriptValue* serialized_value = event->SerializedData()) {
- MessagePortArray ports = event->ports();
- SerializedScriptValue::DeserializeOptions options;
- options.message_ports = &ports;
- data = serialized_value->Deserialize(isolate, options);
- } else if (DOMWrapperWorld::Current(isolate).IsIsolatedWorld()) {
- v8::Local<v8::Value> main_world_data;
- if (private_cached_data.GetFromMainWorld(event).ToLocal(&main_world_data) &&
- !main_world_data->IsUndefined()) {
- // TODO(bashi): Enter the main world's ScriptState::Scope while
- // serializing the main world's value.
- event->SetSerializedData(
- SerializedScriptValue::SerializeAndSwallowExceptions(
- info.GetIsolate(), main_world_data));
- data = event->SerializedData()->Deserialize(isolate);
- }
- }
- if (data.IsEmpty())
- data = v8::Null(isolate);
- private_cached_data.Set(info.Holder(), data);
- V8SetReturnValue(info, data);
-}
-
-} // namespace blink
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 c0c91059fed..a090ea5085c 100644
--- a/chromium/third_party/blink/renderer/bindings/modules/v8/generated.gni
+++ b/chromium/third_party/blink/renderer/bindings/modules/v8/generated.gni
@@ -4,6 +4,7 @@
import("//build/config/chrome_build.gni")
import("//third_party/blink/renderer/bindings/bindings.gni")
+import("//third_party/blink/renderer/bindings/scripts/scripts.gni")
import("//third_party/blink/renderer/core/core_idl_files.gni")
import("//third_party/blink/renderer/modules/modules_idl_files.gni")
@@ -16,14 +17,16 @@ bindings_modules_generated_init_partial_interfaces_file =
bindings_modules_generated_union_type_files = [
"$bindings_modules_v8_output_dir/animation_effect_or_animation_effect_sequence.cc",
"$bindings_modules_v8_output_dir/animation_effect_or_animation_effect_sequence.h",
- "$bindings_modules_v8_output_dir/array_buffer_or_array_buffer_view_or_dictionary.cc",
- "$bindings_modules_v8_output_dir/array_buffer_or_array_buffer_view_or_dictionary.h",
+ "$bindings_modules_v8_output_dir/array_buffer_or_array_buffer_view_or_blob_or_usv_string_or_write_params.cc",
+ "$bindings_modules_v8_output_dir/array_buffer_or_array_buffer_view_or_blob_or_usv_string_or_write_params.h",
+ "$bindings_modules_v8_output_dir/array_buffer_or_array_buffer_view_or_json_web_key.cc",
+ "$bindings_modules_v8_output_dir/array_buffer_or_array_buffer_view_or_json_web_key.h",
"$bindings_modules_v8_output_dir/array_buffer_or_array_buffer_view_or_string.cc",
"$bindings_modules_v8_output_dir/array_buffer_or_array_buffer_view_or_string.h",
"$bindings_modules_v8_output_dir/array_buffer_or_array_buffer_view_or_usv_string.cc",
"$bindings_modules_v8_output_dir/array_buffer_or_array_buffer_view_or_usv_string.h",
- "$bindings_modules_v8_output_dir/array_buffer_view_or_blob_or_string_or_form_data.cc",
- "$bindings_modules_v8_output_dir/array_buffer_view_or_blob_or_string_or_form_data.h",
+ "$bindings_modules_v8_output_dir/array_buffer_view_or_blob_or_string_or_form_data_or_readable_stream.cc",
+ "$bindings_modules_v8_output_dir/array_buffer_view_or_blob_or_string_or_form_data_or_readable_stream.h",
"$bindings_modules_v8_output_dir/audio_context_latency_category_or_double.cc",
"$bindings_modules_v8_output_dir/audio_context_latency_category_or_double.h",
"$bindings_modules_v8_output_dir/boolean_or_constrain_boolean_parameters.cc",
@@ -34,8 +37,6 @@ bindings_modules_generated_union_type_files = [
"$bindings_modules_v8_output_dir/canvas_image_source.h",
"$bindings_modules_v8_output_dir/client_or_service_worker_or_message_port.cc",
"$bindings_modules_v8_output_dir/client_or_service_worker_or_message_port.h",
- "$bindings_modules_v8_output_dir/dictionary_or_string.cc",
- "$bindings_modules_v8_output_dir/dictionary_or_string.h",
"$bindings_modules_v8_output_dir/document_timeline_or_scroll_timeline.cc",
"$bindings_modules_v8_output_dir/document_timeline_or_scroll_timeline.h",
"$bindings_modules_v8_output_dir/dom_exception_or_overconstrained_error.cc",
@@ -44,18 +45,18 @@ bindings_modules_generated_union_type_files = [
"$bindings_modules_v8_output_dir/double_or_constrain_double_range.h",
"$bindings_modules_v8_output_dir/double_sequence_or_gpu_color_dict.cc",
"$bindings_modules_v8_output_dir/double_sequence_or_gpu_color_dict.h",
- "$bindings_modules_v8_output_dir/worklet_animation_effect_or_worklet_group_effect.cc",
- "$bindings_modules_v8_output_dir/worklet_animation_effect_or_worklet_group_effect.h",
"$bindings_modules_v8_output_dir/float32_array_or_float64_array_or_dom_matrix.cc",
"$bindings_modules_v8_output_dir/float32_array_or_float64_array_or_dom_matrix.h",
- "$bindings_modules_v8_output_dir/gpu_out_of_memory_error_or_gpu_validation_error.cc",
- "$bindings_modules_v8_output_dir/gpu_out_of_memory_error_or_gpu_validation_error.h",
+ "$bindings_modules_v8_output_dir/gpu_buffer_or_array_buffer.cc",
+ "$bindings_modules_v8_output_dir/gpu_buffer_or_array_buffer.h",
"$bindings_modules_v8_output_dir/gpu_load_op_or_double_sequence_or_gpu_color_dict.cc",
"$bindings_modules_v8_output_dir/gpu_load_op_or_double_sequence_or_gpu_color_dict.h",
"$bindings_modules_v8_output_dir/gpu_load_op_or_float.cc",
"$bindings_modules_v8_output_dir/gpu_load_op_or_float.h",
"$bindings_modules_v8_output_dir/gpu_load_op_or_unsigned_long.cc",
"$bindings_modules_v8_output_dir/gpu_load_op_or_unsigned_long.h",
+ "$bindings_modules_v8_output_dir/gpu_out_of_memory_error_or_gpu_validation_error.cc",
+ "$bindings_modules_v8_output_dir/gpu_out_of_memory_error_or_gpu_validation_error.h",
"$bindings_modules_v8_output_dir/gpu_sampler_or_gpu_texture_view_or_gpu_buffer_binding.cc",
"$bindings_modules_v8_output_dir/gpu_sampler_or_gpu_texture_view_or_gpu_buffer_binding.h",
"$bindings_modules_v8_output_dir/html_canvas_element_or_offscreen_canvas.cc",
@@ -70,6 +71,8 @@ bindings_modules_generated_union_type_files = [
"$bindings_modules_v8_output_dir/long_or_constrain_long_range.h",
"$bindings_modules_v8_output_dir/media_stream_track_or_string.cc",
"$bindings_modules_v8_output_dir/media_stream_track_or_string.h",
+ "$bindings_modules_v8_output_dir/object_or_string.cc",
+ "$bindings_modules_v8_output_dir/object_or_string.h",
"$bindings_modules_v8_output_dir/offscreen_rendering_context.cc",
"$bindings_modules_v8_output_dir/offscreen_rendering_context.h",
"$bindings_modules_v8_output_dir/password_credential_data_or_html_form_element.cc",
@@ -102,6 +105,8 @@ bindings_modules_generated_union_type_files = [
"$bindings_modules_v8_output_dir/unsigned_long_sequence_or_gpu_origin_3d_dict.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",
+ "$bindings_modules_v8_output_dir/worklet_animation_effect_or_worklet_group_effect.h",
]
generated_modules_callback_function_files = [
@@ -155,11 +160,27 @@ 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_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",
+ "$bindings_modules_v8_output_dir/v8_web_codecs_error_callback.h",
"$bindings_modules_v8_output_dir/v8_xr_frame_request_callback.cc",
"$bindings_modules_v8_output_dir/v8_xr_frame_request_callback.h",
]
bindings_generated_v8_context_snapshot_external_references_file =
"$bindings_modules_v8_output_dir/v8_context_snapshot_external_references.cc"
+
+generated_modules_dictionary_files = []
+
+if (use_v8_bind_gen_for_dictionary) {
+ generated_modules_dictionary_files +=
+ process_file_template(
+ modules_dictionary_idl_files,
+ [
+ "$bindings_modules_v8_output_dir/v8_{{source_name_part}}.cc",
+ "$bindings_modules_v8_output_dir/v8_{{source_name_part}}.h",
+ ])
+}
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 d52684807ba..7b07f628307 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
@@ -14,15 +14,14 @@
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/crypto/crypto_key.h"
#include "third_party/blink/renderer/modules/filesystem/dom_file_system.h"
-#include "third_party/blink/renderer/modules/imagecapture/point_2d.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_file_handle.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_certificate.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.h"
-#include "third_party/blink/renderer/modules/shapedetection/detected_barcode.h"
-#include "third_party/blink/renderer/modules/shapedetection/detected_face.h"
-#include "third_party/blink/renderer/modules/shapedetection/detected_text.h"
-#include "third_party/blink/renderer/modules/shapedetection/landmark.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_delegate.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.h"
namespace blink {
@@ -70,65 +69,10 @@ ScriptWrappable* V8ScriptValueDeserializerForModules::ReadDOMObject(
return nullptr;
return MakeGarbageCollected<RTCCertificate>(std::move(certificate));
}
- case kDetectedBarcodeTag: {
- String raw_value;
- if (!ReadUTF8String(&raw_value))
- return nullptr;
- DOMRectReadOnly* bounding_box = ReadDOMRectReadOnly();
- if (!bounding_box)
- return nullptr;
- // TODO(crbug.com/938663): add deserialization for |format|.
- shape_detection::mojom::BarcodeFormat format =
- shape_detection::mojom::BarcodeFormat::UNKNOWN;
- uint32_t corner_points_length;
- if (!ReadUint32(&corner_points_length))
- return nullptr;
- HeapVector<Member<Point2D>> corner_points;
- for (uint32_t i = 0; i < corner_points_length; i++) {
- Point2D* point = Point2D::Create();
- if (!ReadPoint2D(point))
- return nullptr;
- corner_points.push_back(point);
- }
- return MakeGarbageCollected<DetectedBarcode>(raw_value, bounding_box,
- format, corner_points);
- }
- case kDetectedFaceTag: {
- DOMRectReadOnly* bounding_box = ReadDOMRectReadOnly();
- if (!bounding_box)
- return nullptr;
- uint32_t landmarks_length;
- if (!ReadUint32(&landmarks_length))
- return nullptr;
- HeapVector<Member<Landmark>> landmarks;
- for (uint32_t i = 0; i < landmarks_length; i++) {
- Landmark* landmark = Landmark::Create();
- if (!ReadLandmark(landmark))
- return nullptr;
- landmarks.push_back(landmark);
- }
- return MakeGarbageCollected<DetectedFace>(bounding_box, landmarks);
- }
- case kDetectedTextTag: {
- String raw_value;
- if (!ReadUTF8String(&raw_value))
- return nullptr;
- DOMRectReadOnly* bounding_box = ReadDOMRectReadOnly();
- if (!bounding_box)
- return nullptr;
- uint32_t corner_points_length;
- if (!ReadUint32(&corner_points_length))
- return nullptr;
- HeapVector<Member<Point2D>> corner_points;
- for (uint32_t i = 0; i < corner_points_length; i++) {
- Point2D* point = Point2D::Create();
- if (!ReadPoint2D(point))
- return nullptr;
- corner_points.push_back(point);
- }
- return MakeGarbageCollected<DetectedText>(raw_value, bounding_box,
- corner_points);
- }
+ case kRTCEncodedAudioFrameTag:
+ return ReadRTCEncodedAudioFrame();
+ case kRTCEncodedVideoFrameTag:
+ return ReadRTCEncodedVideoFrame();
default:
break;
}
@@ -363,38 +307,11 @@ CryptoKey* V8ScriptValueDeserializerForModules::ReadCryptoKey() {
return MakeGarbageCollected<CryptoKey>(key);
}
-bool V8ScriptValueDeserializerForModules::ReadLandmark(Landmark* landmark) {
- String type;
- if (!ReadUTF8String(&type))
- return false;
- uint32_t locations_length;
- if (!ReadUint32(&locations_length))
- return false;
- HeapVector<Member<Point2D>> locations;
- for (uint32_t i = 0; i < locations_length; i++) {
- Point2D* location = Point2D::Create();
- if (!ReadPoint2D(location))
- return false;
- locations.push_back(location);
- }
- landmark->setType(type);
- landmark->setLocations(locations);
- return true;
-}
-
-bool V8ScriptValueDeserializerForModules::ReadPoint2D(Point2D* point) {
- double x = 0, y = 0;
- if (!ReadDouble(&x) || !ReadDouble(&y))
- return false;
- point->setX(x);
- point->setY(y);
- return true;
-}
-
NativeFileSystemHandle*
V8ScriptValueDeserializerForModules::ReadNativeFileSystemHandle(
SerializationTag tag) {
- if (!RuntimeEnabledFeatures::CloneableNativeFileSystemHandlesEnabled()) {
+ if (!RuntimeEnabledFeatures::CloneableNativeFileSystemHandlesEnabled(
+ ExecutionContext::From(GetScriptState()))) {
return nullptr;
}
@@ -410,12 +327,19 @@ V8ScriptValueDeserializerForModules::ReadNativeFileSystemHandle(
if (token_index >= tokens_array.size()) {
return nullptr;
}
- mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken> token(
+
+ // IndexedDB code assumes that deserializing a SSV is non-destructive. So
+ // rather than consuming the token here instead we clone it.
+ mojo::Remote<mojom::blink::NativeFileSystemTransferToken> token(
std::move(tokens_array[token_index]));
if (!token) {
return nullptr;
}
+ mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken> token_clone;
+ token->Clone(token_clone.InitWithNewPipeAndPassReceiver());
+ tokens_array[token_index] = std::move(token_clone);
+
// Use the NativeFileSystemManager to redeem the token to clone the
// FileSystemHandle.
ExecutionContext* execution_context =
@@ -431,7 +355,7 @@ V8ScriptValueDeserializerForModules::ReadNativeFileSystemHandle(
mojo::PendingRemote<mojom::blink::NativeFileSystemFileHandle> file_handle;
native_file_system_manager->GetFileHandleFromToken(
- std::move(token), file_handle.InitWithNewPipeAndPassReceiver());
+ token.Unbind(), file_handle.InitWithNewPipeAndPassReceiver());
return MakeGarbageCollected<NativeFileSystemFileHandle>(
execution_context, name, std::move(file_handle));
@@ -441,7 +365,7 @@ V8ScriptValueDeserializerForModules::ReadNativeFileSystemHandle(
directory_handle;
native_file_system_manager->GetDirectoryHandleFromToken(
- std::move(token), directory_handle.InitWithNewPipeAndPassReceiver());
+ token.Unbind(), directory_handle.InitWithNewPipeAndPassReceiver());
return MakeGarbageCollected<NativeFileSystemDirectoryHandle>(
execution_context, name, std::move(directory_handle));
@@ -453,4 +377,52 @@ V8ScriptValueDeserializerForModules::ReadNativeFileSystemHandle(
}
}
+RTCEncodedAudioFrame*
+V8ScriptValueDeserializerForModules::ReadRTCEncodedAudioFrame() {
+ if (!RuntimeEnabledFeatures::RTCInsertableStreamsEnabled(
+ ExecutionContext::From(GetScriptState()))) {
+ return nullptr;
+ }
+
+ uint32_t index;
+ if (!ReadUint32(&index))
+ return nullptr;
+
+ const auto* attachment =
+ GetSerializedScriptValue()
+ ->GetAttachmentIfExists<RTCEncodedAudioFramesAttachment>();
+ if (!attachment)
+ return nullptr;
+
+ const auto& frames = attachment->EncodedAudioFrames();
+ if (index >= frames.size())
+ return nullptr;
+
+ return MakeGarbageCollected<RTCEncodedAudioFrame>(frames[index]);
+}
+
+RTCEncodedVideoFrame*
+V8ScriptValueDeserializerForModules::ReadRTCEncodedVideoFrame() {
+ if (!RuntimeEnabledFeatures::RTCInsertableStreamsEnabled(
+ ExecutionContext::From(GetScriptState()))) {
+ return nullptr;
+ }
+
+ uint32_t index;
+ if (!ReadUint32(&index))
+ return nullptr;
+
+ const auto* attachment =
+ GetSerializedScriptValue()
+ ->GetAttachmentIfExists<RTCEncodedVideoFramesAttachment>();
+ if (!attachment)
+ return nullptr;
+
+ const auto& frames = attachment->EncodedVideoFrames();
+ if (index >= frames.size())
+ return nullptr;
+
+ return MakeGarbageCollected<RTCEncodedVideoFrame>(frames[index]);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.h b/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.h
index c1277c72034..fd08855f9be 100644
--- a/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.h
+++ b/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.h
@@ -11,9 +11,9 @@
namespace blink {
class CryptoKey;
-class Landmark;
class NativeFileSystemHandle;
-class Point2D;
+class RTCEncodedAudioFrame;
+class RTCEncodedVideoFrame;
// Extends V8ScriptValueSerializer with support for modules/ types.
class MODULES_EXPORT V8ScriptValueDeserializerForModules final
@@ -45,9 +45,9 @@ class MODULES_EXPORT V8ScriptValueDeserializerForModules final
return true;
}
CryptoKey* ReadCryptoKey();
- bool ReadLandmark(Landmark* landmark);
- bool ReadPoint2D(Point2D* point);
NativeFileSystemHandle* ReadNativeFileSystemHandle(SerializationTag tag);
+ RTCEncodedAudioFrame* ReadRTCEncodedAudioFrame();
+ RTCEncodedVideoFrame* ReadRTCEncodedVideoFrame();
};
} // namespace blink
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 4907145c5c5..2e88d05de51 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
@@ -12,15 +12,18 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_dom_rect_read_only.h"
#include "third_party/blink/renderer/bindings/modules/v8/serialization/web_crypto_sub_tags.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_crypto_key.h"
-#include "third_party/blink/renderer/bindings/modules/v8/v8_detected_barcode.h"
-#include "third_party/blink/renderer/bindings/modules/v8/v8_detected_face.h"
-#include "third_party/blink/renderer/bindings/modules/v8/v8_detected_text.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_dom_file_system.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_file_system_directory_handle.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_file_system_file_handle.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_landmark.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_point_2d.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_certificate.h"
-#include "third_party/blink/renderer/modules/imagecapture/point_2d.h"
-#include "third_party/blink/renderer/modules/shapedetection/landmark.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_encoded_audio_frame.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_encoded_video_frame.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_delegate.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
namespace blink {
@@ -56,25 +59,15 @@ bool V8ScriptValueSerializerForModules::WriteDOMObject(
return true;
}
if (wrapper_type_info == V8FileSystemFileHandle::GetWrapperTypeInfo() &&
- RuntimeEnabledFeatures::CloneableNativeFileSystemHandlesEnabled()) {
- if (IsForStorage()) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kDataCloneError,
- "A NativeFileSystemFileHandle can not be serialized for storage.");
- return false;
- }
+ RuntimeEnabledFeatures::CloneableNativeFileSystemHandlesEnabled(
+ ExecutionContext::From(GetScriptState()))) {
return WriteNativeFileSystemHandle(
kNativeFileSystemFileHandleTag,
wrappable->ToImpl<NativeFileSystemHandle>());
}
if (wrapper_type_info == V8FileSystemDirectoryHandle::GetWrapperTypeInfo() &&
- RuntimeEnabledFeatures::CloneableNativeFileSystemHandlesEnabled()) {
- if (IsForStorage()) {
- exception_state.ThrowDOMException(DOMExceptionCode::kDataCloneError,
- "A NativeFileSystemDirectoryHandle can "
- "not be serialized for storage.");
- return false;
- }
+ RuntimeEnabledFeatures::CloneableNativeFileSystemHandlesEnabled(
+ ExecutionContext::From(GetScriptState()))) {
return WriteNativeFileSystemHandle(
kNativeFileSystemDirectoryHandleTag,
wrappable->ToImpl<NativeFileSystemHandle>());
@@ -87,62 +80,27 @@ bool V8ScriptValueSerializerForModules::WriteDOMObject(
WriteUTF8String(pem.certificate().c_str());
return true;
}
- if (wrapper_type_info == V8DetectedBarcode::GetWrapperTypeInfo()) {
- DetectedBarcode* detected_barcode = wrappable->ToImpl<DetectedBarcode>();
- WriteTag(kDetectedBarcodeTag);
- WriteUTF8String(detected_barcode->rawValue());
- DOMRectReadOnly* bounding_box = detected_barcode->boundingBox();
- WriteDouble(bounding_box->x());
- WriteDouble(bounding_box->y());
- WriteDouble(bounding_box->width());
- WriteDouble(bounding_box->height());
- const HeapVector<Member<Point2D>>& corner_points =
- detected_barcode->cornerPoints();
- WriteUint32(static_cast<uint32_t>(corner_points.size()));
- for (const auto& corner_point : corner_points) {
- WriteDouble(corner_point->x());
- WriteDouble(corner_point->y());
- }
- return true;
- }
- if (wrapper_type_info == V8DetectedFace::GetWrapperTypeInfo()) {
- DetectedFace* detected_face = wrappable->ToImpl<DetectedFace>();
- WriteTag(kDetectedFaceTag);
- DOMRectReadOnly* bounding_box = detected_face->boundingBox();
- WriteDouble(bounding_box->x());
- WriteDouble(bounding_box->y());
- WriteDouble(bounding_box->width());
- WriteDouble(bounding_box->height());
- const HeapVector<Member<Landmark>>& landmarks = detected_face->landmarks();
- WriteUint32(static_cast<uint32_t>(landmarks.size()));
- for (const auto& landmark : landmarks) {
- WriteUTF8String(landmark->type());
- const HeapVector<Member<Point2D>>& locations = landmark->locations();
- WriteUint32(static_cast<uint32_t>(locations.size()));
- for (const auto& location : locations) {
- WriteDouble(location->x());
- WriteDouble(location->y());
- }
+ if (wrapper_type_info == V8RTCEncodedAudioFrame::GetWrapperTypeInfo() &&
+ RuntimeEnabledFeatures::RTCInsertableStreamsEnabled(
+ ExecutionContext::From(GetScriptState()))) {
+ if (IsForStorage()) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kDataCloneError,
+ "An RTCEncodedAudioFrame cannot be "
+ "serialized for storage.");
+ return false;
}
- return true;
+ return WriteRTCEncodedAudioFrame(wrappable->ToImpl<RTCEncodedAudioFrame>());
}
- if (wrapper_type_info == V8DetectedText::GetWrapperTypeInfo()) {
- DetectedText* detected_text = wrappable->ToImpl<DetectedText>();
- WriteTag(kDetectedTextTag);
- WriteUTF8String(detected_text->rawValue());
- DOMRectReadOnly* bounding_box = detected_text->boundingBox();
- WriteDouble(bounding_box->x());
- WriteDouble(bounding_box->y());
- WriteDouble(bounding_box->width());
- WriteDouble(bounding_box->height());
- const HeapVector<Member<Point2D>>& corner_points =
- detected_text->cornerPoints();
- WriteUint32(static_cast<uint32_t>(corner_points.size()));
- for (const auto& corner_point : corner_points) {
- WriteDouble(corner_point->x());
- WriteDouble(corner_point->y());
+ if (wrapper_type_info == V8RTCEncodedVideoFrame::GetWrapperTypeInfo() &&
+ RuntimeEnabledFeatures::RTCInsertableStreamsEnabled(
+ ExecutionContext::From(GetScriptState()))) {
+ if (IsForStorage()) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kDataCloneError,
+ "An RTCEncodedVideoFrame cannot be "
+ "serialized for storage.");
+ return false;
}
- return true;
+ return WriteRTCEncodedVideoFrame(wrappable->ToImpl<RTCEncodedVideoFrame>());
}
return false;
}
@@ -183,6 +141,10 @@ uint32_t AlgorithmIdForWireFormat(WebCryptoAlgorithmId id) {
return kHkdfTag;
case kWebCryptoAlgorithmIdPbkdf2:
return kPbkdf2Tag;
+ // TODO(crbug.com/1032821): Handle them explicitly for Lint.
+ case kWebCryptoAlgorithmIdEd25519:
+ case kWebCryptoAlgorithmIdX25519:
+ return 0;
}
NOTREACHED() << "Unknown algorithm ID " << id;
return 0;
@@ -338,4 +300,32 @@ bool V8ScriptValueSerializerForModules::WriteNativeFileSystemHandle(
return true;
}
+bool V8ScriptValueSerializerForModules::WriteRTCEncodedAudioFrame(
+ RTCEncodedAudioFrame* audio_frame) {
+ auto* attachment =
+ GetSerializedScriptValue()
+ ->GetOrCreateAttachment<RTCEncodedAudioFramesAttachment>();
+ auto& frames = attachment->EncodedAudioFrames();
+ frames.push_back(audio_frame->Delegate());
+ const uint32_t index = static_cast<uint32_t>(frames.size() - 1);
+
+ WriteTag(kRTCEncodedAudioFrameTag);
+ WriteUint32(index);
+ return true;
+}
+
+bool V8ScriptValueSerializerForModules::WriteRTCEncodedVideoFrame(
+ RTCEncodedVideoFrame* video_frame) {
+ auto* attachment =
+ GetSerializedScriptValue()
+ ->GetOrCreateAttachment<RTCEncodedVideoFramesAttachment>();
+ auto& frames = attachment->EncodedVideoFrames();
+ frames.push_back(video_frame->Delegate());
+ const uint32_t index = static_cast<uint32_t>(frames.size() - 1);
+
+ WriteTag(kRTCEncodedVideoFrameTag);
+ WriteUint32(index);
+ return true;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.h b/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.h
index 6405202e0cb..eda1434b359 100644
--- a/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.h
+++ b/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.h
@@ -12,6 +12,8 @@
namespace blink {
class NativeFileSystemHandle;
+class RTCEncodedAudioFrame;
+class RTCEncodedVideoFrame;
class WebCryptoKey;
// Extends V8ScriptValueSerializer with support for modules/ types.
@@ -32,6 +34,8 @@ class MODULES_EXPORT V8ScriptValueSerializerForModules final
bool WriteNativeFileSystemHandle(
SerializationTag tag,
NativeFileSystemHandle* native_file_system_handle);
+ bool WriteRTCEncodedAudioFrame(RTCEncodedAudioFrame*);
+ bool WriteRTCEncodedVideoFrame(RTCEncodedVideoFrame*);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc b/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc
index 7dfcc8274d6..6e3442cc80e 100644
--- a/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc
+++ b/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc
@@ -20,18 +20,13 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_dom_rect_read_only.h"
#include "third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_crypto_key.h"
-#include "third_party/blink/renderer/bindings/modules/v8/v8_detected_barcode.h"
-#include "third_party/blink/renderer/bindings/modules/v8/v8_detected_face.h"
-#include "third_party/blink/renderer/bindings/modules/v8/v8_detected_text.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_dom_file_system.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_certificate.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/modules/crypto/crypto_result_impl.h"
#include "third_party/blink/renderer/modules/filesystem/dom_file_system.h"
-#include "third_party/blink/renderer/modules/imagecapture/point_2d.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_certificate.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.h"
-#include "third_party/blink/renderer/modules/shapedetection/landmark.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
@@ -985,85 +980,5 @@ TEST(V8ScriptValueSerializerForModulesTest, DecodeInvalidDOMFileSystem) {
->IsNull());
}
-TEST(V8ScriptValueSerializerForModulesTest, DecodeDetectedBarcode) {
- V8TestingScope scope;
- ScriptState* script_state = scope.GetScriptState();
- scoped_refptr<SerializedScriptValue> input = SerializedValue(
- {0xff, 0x13, 0xff, 0x0d, 0x5c, 'B', 0x04, 0x74, 0x65, 0x78, 0x74, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40});
- v8::Local<v8::Value> result =
- V8ScriptValueDeserializerForModules(script_state, input).Deserialize();
- ASSERT_TRUE(V8DetectedBarcode::HasInstance(result, scope.GetIsolate()));
- DetectedBarcode* detected_barcode =
- V8DetectedBarcode::ToImpl(result.As<v8::Object>());
- EXPECT_EQ("text", detected_barcode->rawValue());
- DOMRectReadOnly* bounding_box = detected_barcode->boundingBox();
- EXPECT_EQ(1, bounding_box->x());
- EXPECT_EQ(2, bounding_box->y());
- EXPECT_EQ(3, bounding_box->width());
- EXPECT_EQ(4, bounding_box->height());
- const HeapVector<Member<Point2D>>& corner_points =
- detected_barcode->cornerPoints();
- EXPECT_EQ(1u, corner_points.size());
- EXPECT_EQ(1, corner_points[0]->x());
- EXPECT_EQ(2, corner_points[0]->y());
-}
-
-TEST(V8ScriptValueSerializerForModulesTest, DecodeDetectedFace) {
- V8TestingScope scope;
- ScriptState* script_state = scope.GetScriptState();
- scoped_refptr<SerializedScriptValue> input = SerializedValue(
- {0xff, 0x13, 0xff, 0x0d, 0x5c, 'F', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x40, 0x01, 0x03, 0x65, 0x79, 0x65, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40});
- v8::Local<v8::Value> result =
- V8ScriptValueDeserializerForModules(script_state, input).Deserialize();
- ASSERT_TRUE(V8DetectedFace::HasInstance(result, scope.GetIsolate()));
- DetectedFace* detected_face = V8DetectedFace::ToImpl(result.As<v8::Object>());
- DOMRectReadOnly* bounding_box = detected_face->boundingBox();
- EXPECT_EQ(1, bounding_box->x());
- EXPECT_EQ(2, bounding_box->y());
- EXPECT_EQ(3, bounding_box->width());
- EXPECT_EQ(4, bounding_box->height());
- const HeapVector<Member<Landmark>>& landmarks = detected_face->landmarks();
- EXPECT_EQ(1u, landmarks.size());
- EXPECT_EQ("eye", landmarks[0]->type());
- const HeapVector<Member<Point2D>>& locations = landmarks[0]->locations();
- EXPECT_EQ(1u, locations.size());
- EXPECT_EQ(1, locations[0]->x());
- EXPECT_EQ(2, locations[0]->y());
-}
-
-TEST(V8ScriptValueSerializerForModulesTest, DecodeDetectedText) {
- V8TestingScope scope;
- ScriptState* script_state = scope.GetScriptState();
- scoped_refptr<SerializedScriptValue> input = SerializedValue(
- {0xff, 0x13, 0xff, 0x0d, 0x5c, 't', 0x04, 0x74, 0x65, 0x78, 0x74, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40});
- v8::Local<v8::Value> result =
- V8ScriptValueDeserializerForModules(script_state, input).Deserialize();
- ASSERT_TRUE(V8DetectedText::HasInstance(result, scope.GetIsolate()));
- DetectedText* detected_text = V8DetectedText::ToImpl(result.As<v8::Object>());
- EXPECT_EQ("text", detected_text->rawValue());
- DOMRectReadOnly* bounding_box = detected_text->boundingBox();
- EXPECT_EQ(1, bounding_box->x());
- EXPECT_EQ(2, bounding_box->y());
- EXPECT_EQ(3, bounding_box->width());
- EXPECT_EQ(4, bounding_box->height());
- const HeapVector<Member<Point2D>>& corner_points =
- detected_text->cornerPoints();
- EXPECT_EQ(1u, corner_points.size());
- EXPECT_EQ(1, corner_points[0]->x());
- EXPECT_EQ(2, corner_points[0]->y());
-}
-
} // namespace
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc b/chromium/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc
index d2b27a0289b..03110a4c22c 100644
--- a/chromium/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc
+++ b/chromium/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc
@@ -540,9 +540,12 @@ static v8::Local<v8::Value> DeserializeIDBValueData(v8::Isolate* isolate,
scoped_refptr<SerializedScriptValue> serialized_value =
value->CreateSerializedValue();
+
+ serialized_value->NativeFileSystemTokens() =
+ std::move(const_cast<IDBValue*>(value)->NativeFileSystemTokens());
+
SerializedScriptValue::DeserializeOptions options;
options.blob_info = &value->BlobInfo();
- options.read_wasm_from_stream = true;
// deserialize() returns null when serialization fails. This is sub-optimal
// because IndexedDB values can be null, so an application cannot distinguish
@@ -758,8 +761,7 @@ bool CanInjectIDBKeyIntoScriptValue(v8::Isolate* isolate,
ScriptValue DeserializeScriptValue(ScriptState* script_state,
SerializedScriptValue* serialized_value,
- const Vector<WebBlobInfo>* blob_info,
- bool read_wasm_from_stream) {
+ const Vector<WebBlobInfo>* blob_info) {
v8::Isolate* isolate = script_state->GetIsolate();
v8::HandleScope handle_scope(isolate);
if (!serialized_value)
@@ -767,7 +769,6 @@ ScriptValue DeserializeScriptValue(ScriptState* script_state,
SerializedScriptValue::DeserializeOptions options;
options.blob_info = blob_info;
- options.read_wasm_from_stream = read_wasm_from_stream;
return ScriptValue(isolate, serialized_value->Deserialize(isolate, options));
}
diff --git a/chromium/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.h b/chromium/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.h
index 78321321dab..3a44e6c38e8 100644
--- a/chromium/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.h
+++ b/chromium/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.h
@@ -34,8 +34,7 @@ MODULES_EXPORT bool CanInjectIDBKeyIntoScriptValue(v8::Isolate*,
const IDBKeyPath&);
ScriptValue DeserializeScriptValue(ScriptState*,
SerializedScriptValue*,
- const Vector<WebBlobInfo>*,
- bool read_wasm_from_stream);
+ const Vector<WebBlobInfo>*);
#if DCHECK_IS_ON()
void AssertPrimaryKeyValidOrInjectable(ScriptState*, const IDBValue*);
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/BUILD.gn b/chromium/third_party/blink/renderer/bindings/scripts/BUILD.gn
index 8868829c30d..a6cc71426b1 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/BUILD.gn
+++ b/chromium/third_party/blink/renderer/bindings/scripts/BUILD.gn
@@ -37,9 +37,7 @@ action("cached_jinja_templates") {
# Dummy file to track dependency.
stamp_file = "$bindings_scripts_output_dir/cached_jinja_templates.stamp"
- outputs = [
- stamp_file,
- ]
+ outputs = [ stamp_file ]
args = [
rebase_path(bindings_scripts_output_dir, root_build_dir),
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/aggregate_generated_bindings.py b/chromium/third_party/blink/renderer/bindings/scripts/aggregate_generated_bindings.py
index e8a1fd2c9a9..71283002ba8 100755
--- a/chromium/third_party/blink/renderer/bindings/scripts/aggregate_generated_bindings.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/aggregate_generated_bindings.py
@@ -31,7 +31,6 @@
# Copyright (c) 2009 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-
"""Generates a .cpp file that includes all V8 binding .cpp files for interfaces.
It is expected to preserve symbol space, and to be acceptable to make static
@@ -47,6 +46,8 @@ Usage:
Design doc: http://www.chromium.org/developers/design-documents/idl-build
"""
+from __future__ import print_function
+
import errno
import optparse
import os
@@ -86,32 +87,35 @@ COPYRIGHT_TEMPLATE = """/*
*/
"""
+
def parse_options():
parser = optparse.OptionParser()
parser.add_option('--component')
options, args = parser.parse_args()
if len(args) < 2:
- raise Exception('Expected 2 filenames; one is for input, and the other is for output.')
+ raise Exception(
+ 'Expected 2 filenames; one is for input, and the other is for output.'
+ )
return options, args
def generate_content(component, basenames):
# Add fixed content.
- output = [COPYRIGHT_TEMPLATE,
- '#define NO_IMPLICIT_ATOMICSTRING\n\n']
+ output = [COPYRIGHT_TEMPLATE, '#define NO_IMPLICIT_ATOMICSTRING\n\n']
basenames.sort()
- output.extend('#include "third_party/blink/renderer/bindings/%s/v8/v8_%s.cc"\n' %
- (component, to_snake_case(basename)) for basename in basenames)
+ output.extend(
+ '#include "third_party/blink/renderer/bindings/%s/v8/v8_%s.cc"\n' %
+ (component, to_snake_case(basename)) for basename in basenames)
return ''.join(output)
def write_content(content, output_file_name):
parent_path, file_name = os.path.split(output_file_name)
if not os.path.exists(parent_path):
- print 'Creating directory: %s' % parent_path
+ print('Creating directory: %s' % parent_path)
os.makedirs(parent_path)
with open(output_file_name, 'w') as f:
f.write(content)
@@ -121,8 +125,9 @@ def main():
options, filenames = parse_options()
component = options.component
idl_filenames = read_idl_files_list_from_file(filenames[0])
- basenames = [idl_filename_to_basename(file_path)
- for file_path in idl_filenames]
+ basenames = [
+ idl_filename_to_basename(file_path) for file_path in idl_filenames
+ ]
file_contents = generate_content(component, basenames)
write_content(file_contents, filenames[1])
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/.style.yapf b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/.style.yapf
index 0169b9a6487..2ae9158e446 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/.style.yapf
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/.style.yapf
@@ -1,3 +1,4 @@
[style]
# https://www.chromium.org/blink/coding-style
based_on_style = pep8
+column_limit = 79
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 94a51e669b6..ab16bdb63da 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
@@ -3,7 +3,6 @@
# found in the LICENSE file.
import os.path
-import platform
import sys
@@ -13,9 +12,10 @@ def _setup_sys_path():
expected_path = 'third_party/blink/renderer/bindings/scripts/bind_gen/'
this_dir = os.path.dirname(__file__)
- root_dir = os.path.join(this_dir, *(['..'] * expected_path.count('/')))
+ root_dir = os.path.abspath(
+ os.path.join(this_dir, *(['..'] * expected_path.count('/'))))
- sys.path = [
+ module_dirs = (
# //third_party/blink/renderer/bindings/scripts/web_idl
os.path.join(root_dir, 'third_party', 'blink', 'renderer', 'bindings',
'scripts'),
@@ -24,37 +24,34 @@ def _setup_sys_path():
'scripts'),
# //third_party/mako/mako
os.path.join(root_dir, 'third_party', 'mako'),
- ] + sys.path
+ )
+ for module_dir in reversed(module_dirs):
+ # Preserve sys.path[0] as is.
+ # https://docs.python.org/3/library/sys.html?highlight=path[0]#sys.path
+ sys.path.insert(1, module_dir)
_setup_sys_path()
-
-from . import clang_format
+from . import style_format
from .dictionary import generate_dictionaries
+from .enumeration import generate_enumerations
from .interface import generate_interfaces
from .path_manager import PathManager
+from .union import generate_unions
-def _setup_clang_format():
- expected_path = 'third_party/blink/renderer/bindings/scripts/bind_gen/'
-
- this_dir = os.path.dirname(__file__)
- root_dir = os.path.join(this_dir, *(['..'] * expected_path.count('/')))
-
- # //third_party/depot_tools/clang-format
- command_name = ('clang-format.bat'
- if platform.system() == 'Windows' else 'clang-format')
- command_path = os.path.abspath(
- os.path.join(root_dir, 'third_party', 'depot_tools', command_name))
-
- clang_format.init(command_path=command_path)
-
-
-def init(output_dirs):
+def init(root_src_dir, root_gen_dir, component_reldirs):
"""
Args:
- output_dirs: Pairs of component and output directory.
+ root_src_dir: Project's root directory, which corresponds to "//" in GN.
+ root_gen_dir: Root directory of generated files, which corresponds to
+ "//out/Default/gen" in GN.
+ component_reldirs: Pairs of component and output directory.
"""
- _setup_clang_format()
- PathManager.init(output_dirs)
+ style_format.init(root_src_dir)
+
+ PathManager.init(
+ root_src_dir=root_src_dir,
+ root_gen_dir=root_gen_dir,
+ component_reldirs=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 22438ad3c9f..495a813c64f 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
@@ -5,12 +5,13 @@
import web_idl
from . import name_style
-from .code_node import CodeNode
+from .code_node import Likeliness
from .code_node import SymbolDefinitionNode
from .code_node import SymbolNode
-from .code_node import SymbolScopeNode
from .code_node import TextNode
-from .code_node import UnlikelyExitNode
+from .code_node_cxx import CxxIfElseNode
+from .code_node_cxx import CxxLikelyIfNode
+from .code_node_cxx import CxxUnlikelyIfNode
from .codegen_format import format_template as _format
@@ -18,17 +19,32 @@ def blink_class_name(idl_definition):
"""
Returns the class name of Blink implementation.
"""
- try:
- class_name = idl_definition.extended_attributes.get(
- "ImplementedAs").value
- except:
- class_name = idl_definition.identifier
-
+ class_name = idl_definition.code_generator_info.receiver_implemented_as
+ if class_name:
+ return class_name
+
+ assert idl_definition.identifier[0].isupper()
+ # Do not apply |name_style.class_| in order to respect the original name
+ # (Web spec'ed name) as much as possible. For example, |interface EXTsRGB|
+ # is implemented as |class EXTsRGB|, not as |ExtSRgb| nor |ExtsRgb|.
if isinstance(idl_definition,
- (web_idl.CallbackFunction, web_idl.CallbackInterface)):
- return name_style.class_("v8", class_name)
+ (web_idl.CallbackFunction, web_idl.CallbackInterface,
+ web_idl.Enumeration)):
+ return "V8{}".format(idl_definition.identifier)
else:
- return name_style.class_(class_name)
+ return idl_definition.identifier
+
+
+def v8_bridge_class_name(idl_definition):
+ """
+ Returns the name of V8-from/to-Blink bridge class.
+ """
+ assert isinstance(idl_definition, (web_idl.Namespace, web_idl.Interface))
+
+ assert idl_definition.identifier[0].isupper()
+ # Do not apply |name_style.class_| due to the same reason as
+ # |blink_class_name|.
+ return "V8{}".format(idl_definition.identifier)
def blink_type_info(idl_type):
@@ -39,10 +55,11 @@ def blink_type_info(idl_type):
member_t: The type of a member variable. E.g. T => Member<T>
ref_t: The type of a local variable that references to an already-existing
value. E.g. String => String&
+ const_ref_t: A const-qualified reference type.
value_t: The type of a variable that behaves as a value. E.g. String =>
String
- is_nullable: True if the Blink implementation type can represent IDL null
- value by itself.
+ has_null_value: True if the Blink implementation type can represent IDL
+ null value by itself without use of base::Optional<T>.
"""
assert isinstance(idl_type, web_idl.IdlType)
@@ -51,13 +68,16 @@ def blink_type_info(idl_type):
typename,
member_fmt="{}",
ref_fmt="{}",
+ const_ref_fmt="const {}",
value_fmt="{}",
- is_nullable=False):
+ has_null_value=False):
+ self.typename = typename
self.member_t = member_fmt.format(typename)
self.ref_t = ref_fmt.format(typename)
+ self.const_ref_t = const_ref_fmt.format(typename)
self.value_t = value_fmt.format(typename)
# Whether Blink impl type can represent IDL null or not.
- self.is_nullable = is_nullable
+ self.has_null_value = has_null_value
real_type = idl_type.unwrap(typedef=True)
@@ -77,69 +97,150 @@ def blink_type_info(idl_type):
"double": "double",
"unrestricted double": "double",
}
- return TypeInfo(cxx_type[real_type.keyword_typename])
+ return TypeInfo(
+ cxx_type[real_type.keyword_typename], const_ref_fmt="{}")
if real_type.is_string:
- return TypeInfo("String", ref_fmt="{}&", is_nullable=True)
+ return TypeInfo(
+ "String",
+ ref_fmt="{}&",
+ const_ref_fmt="const {}&",
+ value_fmt="bindings::NativeValueTraitsStringAdapter",
+ has_null_value=True)
+
+ if real_type.is_array_buffer:
+ assert "AllowShared" not in real_type.extended_attributes
+ return TypeInfo(
+ 'DOM{}'.format(real_type.keyword_typename),
+ member_fmt="Member<{}>",
+ ref_fmt="{}*",
+ const_ref_fmt="const {}*",
+ value_fmt="{}*",
+ has_null_value=True)
+
+ if real_type.is_buffer_source_type:
+ if "FlexibleArrayBufferView" in real_type.extended_attributes:
+ assert "AllowShared" in real_type.extended_attributes
+ return TypeInfo(
+ "Flexible{}".format(real_type.keyword_typename),
+ member_fmt="void",
+ ref_fmt="{}",
+ const_ref_fmt="const {}",
+ value_fmt="{}",
+ has_null_value=True)
+ elif "AllowShared" in real_type.extended_attributes:
+ return TypeInfo(
+ "MaybeShared<DOM{}>".format(real_type.keyword_typename),
+ has_null_value=True)
+ else:
+ return TypeInfo(
+ "NotShared<DOM{}>".format(real_type.keyword_typename),
+ has_null_value=True)
if real_type.is_symbol:
assert False, "Blink does not support/accept IDL symbol type."
if real_type.is_any or real_type.is_object:
- return TypeInfo("ScriptValue", ref_fmt="{}&", is_nullable=True)
+ return TypeInfo(
+ "ScriptValue",
+ ref_fmt="{}&",
+ const_ref_fmt="const {}&",
+ has_null_value=True)
if real_type.is_void:
assert False, "Blink does not support/accept IDL void type."
+ if real_type.is_enumeration:
+ blink_impl_type = blink_class_name(real_type.type_definition_object)
+ return TypeInfo(blink_impl_type)
+
if real_type.type_definition_object is not None:
- type_def_obj = real_type.type_definition_object
- blink_impl_type = (
- type_def_obj.code_generator_info.receiver_implemented_as
- or name_style.class_(type_def_obj.identifier))
+ blink_impl_type = blink_class_name(real_type.type_definition_object)
return TypeInfo(
blink_impl_type,
member_fmt="Member<{}>",
ref_fmt="{}*",
+ const_ref_fmt="const {}*",
value_fmt="{}*",
- is_nullable=True)
+ has_null_value=True)
if (real_type.is_sequence or real_type.is_frozen_array
or real_type.is_variadic):
- element_type = blink_type_info(real_type.element_type)
+ element_type = real_type.element_type
+ element_type_info = blink_type_info(real_type.element_type)
+ if element_type.type_definition_object is not None:
+ # In order to support recursive IDL data structures, we have to
+ # avoid recursive C++ header inclusions and utilize C++ forward
+ # declarations. Since |VectorOf| requires complete type
+ # definition, |HeapVector<Member<T>>| is preferred as it
+ # requires only forward declaration.
+ vector_fmt = "HeapVector<Member<{}>>"
+ else:
+ vector_fmt = "VectorOf<{}>"
return TypeInfo(
- "VectorOf<{}>".format(element_type.value_t), ref_fmt="{}&")
+ vector_fmt.format(element_type_info.typename),
+ ref_fmt="{}&",
+ const_ref_fmt="const {}&")
if real_type.is_record:
key_type = blink_type_info(real_type.key_type)
value_type = blink_type_info(real_type.value_type)
return TypeInfo(
- "VectorOfPairs<{}, {}>".format(key_type.value_t,
- value_type.value_t),
- ref_fmt="{}&")
+ "VectorOfPairs<{}, {}>".format(key_type.typename,
+ value_type.typename),
+ ref_fmt="{}&",
+ const_ref_fmt="const {}&")
if real_type.is_promise:
- return TypeInfo("ScriptPromise", ref_fmt="{}&")
+ return TypeInfo(
+ "ScriptPromise", ref_fmt="{}&", const_ref_fmt="const {}&")
if real_type.is_union:
- return TypeInfo("ToBeImplementedUnion")
+ blink_impl_type = blink_class_name(real_type.union_definition_object)
+ return TypeInfo(
+ blink_impl_type,
+ ref_fmt="{}&",
+ const_ref_fmt="const {}&",
+ has_null_value=True)
if real_type.is_nullable:
inner_type = blink_type_info(real_type.inner_type)
- if inner_type.is_nullable:
+ if inner_type.has_null_value:
return inner_type
return TypeInfo(
- "base::Optional<{}>".format(inner_type.value_t), ref_fmt="{}&")
+ "base::Optional<{}>".format(inner_type.value_t),
+ ref_fmt="{}&",
+ const_ref_fmt="const {}&")
+
+ assert False, "Unknown type: {}".format(idl_type.syntactic_form)
def native_value_tag(idl_type):
"""Returns the tag type of NativeValueTraits."""
assert isinstance(idl_type, web_idl.IdlType)
+ if idl_type.is_typedef:
+ if idl_type.identifier in ("EventHandler",
+ "OnBeforeUnloadEventHandler",
+ "OnErrorEventHandler"):
+ return "IDL{}".format(idl_type.identifier)
+
real_type = idl_type.unwrap(typedef=True)
- if (real_type.is_boolean or real_type.is_numeric or real_type.is_string
- or real_type.is_any or real_type.is_object):
- return "IDL{}".format(real_type.type_name)
+ if (real_type.is_boolean or real_type.is_numeric or real_type.is_any
+ or real_type.is_object):
+ return "IDL{}".format(
+ idl_type.type_name_with_extended_attribute_key_values)
+
+ if real_type.is_string:
+ return "IDL{}V2".format(
+ idl_type.type_name_with_extended_attribute_key_values)
+
+ if real_type.is_array_buffer:
+ return blink_type_info(real_type).typename
+
+ if real_type.is_buffer_source_type:
+ return blink_type_info(real_type).value_t
if real_type.is_symbol:
assert False, "Blink does not support/accept IDL symbol type."
@@ -147,13 +248,16 @@ def native_value_tag(idl_type):
if real_type.is_void:
assert False, "Blink does not support/accept IDL void type."
- if real_type.type_definition_object is not None:
- return blink_type_info(real_type).value_t
+ if real_type.type_definition_object:
+ return blink_class_name(real_type.type_definition_object)
if real_type.is_sequence:
return "IDLSequence<{}>".format(
native_value_tag(real_type.element_type))
+ if real_type.is_frozen_array:
+ return "IDLArray<{}>".format(native_value_tag(real_type.element_type))
+
if real_type.is_record:
return "IDLRecord<{}, {}>".format(
native_value_tag(real_type.key_type),
@@ -168,10 +272,140 @@ def native_value_tag(idl_type):
if real_type.is_nullable:
return "IDLNullable<{}>".format(native_value_tag(real_type.inner_type))
+ assert False, "Unknown type: {}".format(idl_type.syntactic_form)
+
+
+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.
+ assignment_value: Used as "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)
+ assert isinstance(assignment_value, str)
+ self.initializer = initializer
+ self.is_initializer_lightweight = is_initializer_lightweight
+ self.assignment_value = assignment_value
+
+ if idl_type.unwrap(typedef=True).is_union:
+ union_type = idl_type.unwrap(typedef=True)
+ member_type = None
+ for member_type in union_type.flattened_member_types:
+ if default_value.is_type_compatible_with(member_type):
+ member_type = member_type
+ break
+ assert member_type is not None
+
+ union_class_name = blink_class_name(union_type.union_definition_object)
+ member_default_expr = make_default_value_expr(member_type,
+ default_value)
+ if default_value.idl_type.is_nullable:
+ initializer = 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
+ return DefaultValueExpr(
+ initializer=initializer,
+ is_initializer_lightweight=False,
+ assignment_value=assignment_value)
+
+ type_info = blink_type_info(idl_type)
+
+ is_initializer_lightweight = False
+ if default_value.idl_type.is_nullable:
+ if idl_type.unwrap().type_definition_object is not None:
+ initializer = "nullptr"
+ is_initializer_lightweight = True
+ assignment_value = "nullptr"
+ elif idl_type.unwrap().is_string:
+ initializer = None # String::IsNull() by default
+ assignment_value = "String()"
+ elif idl_type.unwrap().is_buffer_source_type:
+ initializer = "nullptr"
+ is_initializer_lightweight = True
+ assignment_value = "nullptr"
+ elif type_info.value_t == "ScriptValue":
+ initializer = None # ScriptValue::IsEmpty() by default
+ assignment_value = "ScriptValue()"
+ elif idl_type.unwrap().is_union:
+ initializer = 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"
+ elif default_value.idl_type.is_sequence:
+ initializer = 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
+ assignment_value = value
+ elif default_value.idl_type.is_boolean:
+ value = "true" if default_value.value else "false"
+ initializer = value
+ is_initializer_lightweight = True
+ assignment_value = value
+ elif default_value.idl_type.is_integer:
+ initializer = default_value.literal
+ is_initializer_lightweight = True
+ assignment_value = default_value.literal
+ elif default_value.idl_type.is_floating_point_numeric:
+ if default_value.value == float("NaN"):
+ value_fmt = "std::numeric_limits<{type}>::quiet_NaN()"
+ elif default_value.value == float("Infinity"):
+ value_fmt = "std::numeric_limits<{type}>::infinity()"
+ elif default_value.value == float("-Infinity"):
+ value_fmt = "-std::numeric_limits<{type}>::infinity()"
+ else:
+ value_fmt = "{value}"
+ value = value_fmt.format(
+ type=type_info.value_t, value=default_value.literal)
+ initializer = value
+ is_initializer_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
+ 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)
+ else:
+ assert False
+ else:
+ assert False
+
+ return DefaultValueExpr(
+ initializer=initializer,
+ is_initializer_lightweight=is_initializer_lightweight,
+ assignment_value=assignment_value)
+
def make_v8_to_blink_value(blink_var_name,
v8_value_expr,
idl_type,
+ argument_index=None,
default_value=None):
"""
Returns a SymbolNode whose definition converts a v8::Value to a Blink value.
@@ -179,23 +413,71 @@ def make_v8_to_blink_value(blink_var_name,
assert isinstance(blink_var_name, str)
assert isinstance(v8_value_expr, str)
assert isinstance(idl_type, web_idl.IdlType)
+ assert (argument_index is None or isinstance(argument_index, (int, long)))
assert (default_value is None
or isinstance(default_value, web_idl.LiteralConstant))
- pattern = (
- "const auto& ${{{_1}}} = NativeValueTraits<{_2}>::NativeValue({_3});")
- _1 = blink_var_name
- _2 = native_value_tag(idl_type)
- _3 = ["${isolate}", v8_value_expr, "${exception_state}"]
- text = _format(pattern, _1=_1, _2=_2, _3=", ".join(_3))
+ T = TextNode
+ F = lambda *args, **kwargs: T(_format(*args, **kwargs))
def create_definition(symbol_node):
- return SymbolDefinitionNode(symbol_node, [
- TextNode(text),
- UnlikelyExitNode(
- cond=TextNode("${exception_state}.HadException()"),
- body=SymbolScopeNode([TextNode("return;")])),
- ])
+ if argument_index is None:
+ func_name = "NativeValue"
+ arguments = ["${isolate}", v8_value_expr, "${exception_state}"]
+ else:
+ func_name = "ArgumentValue"
+ arguments = [
+ "${isolate}",
+ str(argument_index),
+ v8_value_expr,
+ "${exception_state}",
+ ]
+ if "StringContext" in idl_type.effective_annotations:
+ arguments.append("${execution_context_of_document_tree}")
+ blink_value_expr = _format(
+ "NativeValueTraits<{_1}>::{_2}({_3})",
+ _1=native_value_tag(idl_type),
+ _2=func_name,
+ _3=", ".join(arguments))
+
+ if default_value is None:
+ return SymbolDefinitionNode(symbol_node, [
+ F("auto&& ${{{}}} = {};", blink_var_name, blink_value_expr),
+ CxxUnlikelyIfNode(
+ cond="${exception_state}.HadException()",
+ body=T("return;")),
+ ])
+
+ nodes = []
+ type_info = blink_type_info(idl_type)
+ default_expr = make_default_value_expr(idl_type, default_value)
+ if default_expr.is_initializer_lightweight:
+ nodes.append(
+ F("{} ${{{}}}{{{}}};", type_info.value_t, blink_var_name,
+ default_expr.initializer))
+ else:
+ nodes.append(F("{} ${{{}}};", type_info.value_t, blink_var_name))
+ assignment = [
+ F("${{{}}} = {};", blink_var_name, blink_value_expr),
+ CxxUnlikelyIfNode(
+ cond="${exception_state}.HadException()", body=T("return;")),
+ ]
+ if (default_expr.initializer is None
+ or default_expr.is_initializer_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))
+ return SymbolDefinitionNode(symbol_node, nodes)
return SymbolNode(blink_var_name, definition_constructor=create_definition)
@@ -211,18 +493,26 @@ def make_v8_to_blink_value_variadic(blink_var_name, v8_array,
assert isinstance(v8_array_start_index, (int, long))
assert isinstance(idl_type, web_idl.IdlType)
- pattern = "const auto& ${{{_1}}} = ToImplArguments<{_2}>({_3});"
- _1 = blink_var_name
- _2 = native_value_tag(idl_type.element_type)
- _3 = [v8_array, str(v8_array_start_index), "${exception_state}"]
- text = _format(pattern, _1=_1, _2=_2, _3=", ".join(_3))
+ pattern = ("auto&& ${{{_1}}} = "
+ "bindings::VariadicArgumentsToNativeValues<{_2}>({_3});")
+ arguments = [
+ "${isolate}", v8_array,
+ str(v8_array_start_index), "${exception_state}"
+ ]
+ if "StringContext" in idl_type.element_type.effective_annotations:
+ arguments.append("${execution_context_of_document_tree}")
+ text = _format(
+ pattern,
+ _1=blink_var_name,
+ _2=native_value_tag(idl_type.element_type),
+ _3=", ".join(arguments))
def create_definition(symbol_node):
return SymbolDefinitionNode(symbol_node, [
TextNode(text),
- UnlikelyExitNode(
- cond=TextNode("${exception_state}.HadException()"),
- body=SymbolScopeNode([TextNode("return;")])),
+ CxxUnlikelyIfNode(
+ cond="${exception_state}.HadException()",
+ body=TextNode("return;")),
])
return SymbolNode(blink_var_name, definition_constructor=create_definition)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/clang_format.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/clang_format.py
deleted file mode 100644
index ac060bc80da..00000000000
--- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/clang_format.py
+++ /dev/null
@@ -1,63 +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.
-
-import os.path
-import subprocess
-
-_clang_format_command_path = None
-
-
-def init(command_path):
- """
- Args:
- command_path: Path to the clang_format command.
- """
- assert isinstance(command_path, str)
- assert os.path.exists(command_path)
-
- global _clang_format_command_path
- assert _clang_format_command_path is None
- _clang_format_command_path = command_path
-
-
-def clang_format(contents, filename=None):
- command_line = [_clang_format_command_path]
- if filename is not None:
- command_line.append('-assume-filename={}'.format(filename))
-
- proc = subprocess.Popen(
- command_line, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
- stdout_output, stderr_output = proc.communicate(input=contents)
- exit_code = proc.wait()
-
- return ClangFormatResult(
- stdout_output=stdout_output,
- stderr_output=stderr_output,
- exit_code=exit_code,
- filename=filename)
-
-
-class ClangFormatResult(object):
- def __init__(self, stdout_output, stderr_output, exit_code, filename):
- self._stdout_output = stdout_output
- self._stderr_output = stderr_output
- self._exit_code = exit_code
- self._filename = filename
-
- @property
- def did_succeed(self):
- return self._exit_code == 0
-
- @property
- def contents(self):
- assert self.did_succeed
- return self._stdout_output
-
- @property
- def error_message(self):
- return self._stderr_output
-
- @property
- def filename(self):
- return self._filename
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node.py
index 53fe4fe1fce..2e29538399c 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node.py
@@ -8,11 +8,34 @@ provides a collection of the classes that represent code nodes independent from
specific bindings, such as ECMAScript bindings.
"""
-import copy
-
from .codegen_accumulator import CodeGenAccumulator
from .codegen_format import format_template
from .mako_renderer import MakoRenderer
+from .mako_renderer import MakoTemplate
+
+
+def render_code_node(code_node):
+ """
+ Renders |code_node| and turns it into text letting |code_node| apply all
+ necessary changes (side effects). Returns the resulting text.
+ """
+ assert isinstance(code_node, CodeNode)
+ assert code_node.outer is None
+
+ renderer = code_node.renderer
+ accumulator = code_node.accumulator
+
+ accumulated_size = accumulator.total_size()
+ while True:
+ prev_accumulated_size = accumulated_size
+ renderer.reset()
+ code_node.render(renderer)
+ accumulated_size = accumulator.total_size()
+ if (renderer.is_rendering_complete()
+ and accumulated_size == prev_accumulated_size):
+ break
+
+ return renderer.to_text()
class Likeliness(object):
@@ -58,10 +81,15 @@ class CodeNode(object):
"""
def __init__(self):
- # Symbols used in generated code, but not yet defined. See also
- # SymbolNode. Code symbols are accumulated in order from the first
- # appearance to the last. This order affects the insertion order of
- # SymbolDefinitionNodes at SymbolScopeNode.
+ # List of SymbolNodes that are defined at this point of rendering.
+ # Used to determine whether a certain symbol is already defined by
+ # this point of rendering.
+ self.defined_code_symbols = []
+
+ # List of SymbolNodes that are not yet defined at this point of
+ # rendering. SymbolNodes are accumulated in order of their first
+ # appearance. The order affects the insertion order of
+ # SymbolDefinitionNodes.
self.undefined_code_symbols = []
# Dict from a SymbolNode to a set of tuples of SymbolScopeNodes
@@ -89,7 +117,7 @@ class CodeNode(object):
# (Scope1, Scope2A, Scope3), # [1]
# (Scope1, Scope2B), # [4]
# ])
- self.undefined_code_symbols_scope_chains = {}
+ self.symbol_to_scope_chains = {}
_gensym_seq_id = 0
@@ -135,11 +163,18 @@ class CodeNode(object):
self._prev = None
# Mako's template text, bindings dict
- self._template_text = template_text
- self._template_vars = {}
+ if template_text is None:
+ self._template = None
+ else:
+ self._template = MakoTemplate(template_text)
+
+ # Template variable bindings
+ self._own_template_vars = None
+ self._base_template_vars = None
+ self._cached_template_vars = None
self._accumulator = None # CodeGenAccumulator
- self._accumulate_requests = []
+ self._accumulate_requests = None
self._renderer = None # MakoRenderer
@@ -151,36 +186,42 @@ class CodeNode(object):
def __str__(self):
"""
- Renders this CodeNode object into a Mako template. This is supposed to
- be used in a Mako template as ${code_node}.
+ Renders this CodeNode object directly into the renderer's text buffer
+ and always returns the empty string. This is because it's faster to
+ accumulate the rendering result directly in a single text buffer than
+ making a lot of string pieces and concatenating them.
+
+ This function is supposed to be used in a Mako template as ${code_node}.
"""
- return self.render()
+ renderer = self.renderer
+ assert renderer
- def render(self):
+ self.render(renderer)
+ return ""
+
+ def render(self, renderer):
"""
Renders this CodeNode object as a text string and also propagates
updates to related CodeNode objects. As this method has side-effects
not only to this object but also other related objects, the resulting
text may change on each invocation.
"""
- assert self.renderer
-
last_render_state = self._render_state
self._render_state = CodeNode._RenderState()
self._is_rendering = True
try:
- text = self._render(
- renderer=self.renderer, last_render_state=last_render_state)
+ self._render(
+ renderer=renderer, last_render_state=last_render_state)
finally:
self._is_rendering = False
if self._accumulate_requests:
- assert self.accumulator
+ accumulator = self.accumulator
+ assert accumulator
for request in self._accumulate_requests:
- request(self.accumulator)
-
- return text
+ request(accumulator)
+ self._accumulate_requests = None
def _render(self, renderer, last_render_state):
"""
@@ -189,10 +230,9 @@ class CodeNode(object):
Only limited subclasses may override this method.
"""
- assert self._template_text is not None
- return renderer.render(
+ renderer.render(
caller=self,
- template_text=self._template_text,
+ template=self._template,
template_vars=self.template_vars)
@property
@@ -223,65 +263,112 @@ class CodeNode(object):
assert isinstance(prev, CodeNode) or prev is None
self._prev = prev
- @property
- def upstream_of_scope(self):
- """
- Returns the upstream CodeNode in the same or outer scope. Only the set
- of recursively-collected |upstream_of_scope|s can bring symbol
- definitions effective to this node.
- """
- if self.prev is None:
- return self.outer
-
- node = self.prev
- while isinstance(node, SequenceNode):
+ def outer_scope(self):
+ """Returns the outer scope closest to this scope or None."""
+ node = self.outer
+ while node is not None:
if isinstance(node, SymbolScopeNode):
- return node.upstream_of_scope
- if not node:
- break
- node = node[-1]
+ return node
+ node = node.outer
+ return None
+
+ def outermost(self):
+ """Returns the outermost node, i.e. the node whose |outer| is None."""
+ node = self
+ while node.outer is not None:
+ node = node.outer
return node
+ def inclusive_outers(self):
+ """
+ Returns a list of outer nodes including this node in order from this
+ node to the outermost node.
+ """
+ outers = []
+ node = self
+ while node is not None:
+ outers.append(node)
+ node = node.outer
+ return outers
+
@property
def template_vars(self):
"""
Returns the template variable bindings available at this point, i.e.
bound at this node or outer nodes.
- CAUTION: Do not modify the returned dict. This method may return the
- original dict in a CodeNode.
+ CAUTION: This accessor caches the result. This accessor must not be
+ called during construction of a code node tree.
"""
- if not self.outer:
- return self._template_vars
+ if self._cached_template_vars is not None:
+ return self._cached_template_vars
- if not self._template_vars:
- return self.outer.template_vars
+ outers = self.inclusive_outers()
+ bindings = None
- binds = copy.copy(self.outer.template_vars)
- for name, value in self._template_vars.iteritems():
- assert name not in binds, (
- "Duplicated template variable binding: {}".format(name))
- binds[name] = value
- return binds
+ for node in outers:
+ if node.base_template_vars is not None:
+ bindings = dict(node.base_template_vars)
+ break
+ if bindings is None:
+ bindings = {}
+
+ for node in outers:
+ if node.own_template_vars is None:
+ continue
+ for name, value in node.own_template_vars.items():
+ assert name not in bindings, (
+ "Duplicated template variable binding: {}".format(name))
+ bindings[name] = value
+
+ self._cached_template_vars = bindings
+ return self._cached_template_vars
+
+ @property
+ def own_template_vars(self):
+ """Returns the template variables bound at this code node."""
+ return self._own_template_vars
def add_template_var(self, name, value):
- assert name not in self._template_vars, (
+ if self._own_template_vars is None:
+ self._own_template_vars = {}
+ assert isinstance(name, str)
+ assert name not in self._own_template_vars, (
"Duplicated template variable binding: {}".format(name))
if isinstance(value, CodeNode):
value.set_outer(self)
- self._template_vars[name] = value
+ self._own_template_vars[name] = value
def add_template_vars(self, template_vars):
assert isinstance(template_vars, dict)
- for name, value in template_vars.iteritems():
+ for name, value in template_vars.items():
self.add_template_var(name, value)
@property
+ def base_template_vars(self):
+ """
+ Returns the base template variables if it's set at this code node.
+
+ The base template variables are a set of template variables that of
+ the innermost code node takes effect. It means that the base template
+ variables are layered and shadowable.
+ """
+ return self._base_template_vars
+
+ def set_base_template_vars(self, template_vars):
+ assert isinstance(template_vars, dict)
+ for name, value in template_vars.items():
+ assert isinstance(name, str)
+ assert not isinstance(value, CodeNode)
+ assert self._base_template_vars is None
+ self._base_template_vars = template_vars
+
+ @property
def accumulator(self):
# Always consistently use the accumulator of the root node.
- if self.outer is not None:
- return self.outer.accumulator
- return self._accumulator
+ if self.outer is None:
+ return self._accumulator
+ return self.outermost().accumulator
def set_accumulator(self, accumulator):
assert isinstance(accumulator, CodeGenAccumulator)
@@ -294,15 +381,16 @@ class CodeNode(object):
argument of self.accumulator.
"""
assert callable(request)
+ if self._accumulate_requests is None:
+ self._accumulate_requests = []
self._accumulate_requests.append(request)
@property
def renderer(self):
- # Always use the renderer of the root node in order not to mix renderers
- # during rendering of a single code node tree.
- if self.outer is not None:
- return self.outer.renderer
- return self._renderer
+ # Always consistently use the renderer of the root node.
+ if self.outer is None:
+ return self._renderer
+ return self.outermost().renderer
def set_renderer(self, renderer):
assert isinstance(renderer, MakoRenderer)
@@ -319,53 +407,68 @@ class CodeNode(object):
assert not self._is_rendering
return self._render_state
- def is_code_symbol_defined(self, symbol_node):
- """
- Returns True if |symbol_node| is defined at this point or upstream.
- """
- if self.outer:
- return self.upstream_of_scope.is_code_symbol_defined(symbol_node)
- return False
-
- def is_code_symbol_registered(self, symbol_node):
- """
- Returns True if |symbol_node| is registered and available for use at
- this point. See also |SymbolScopeNode.register_code_symbol|.
- """
- if self.outer is not None:
- return self.outer.is_code_symbol_registered(symbol_node)
- return False
-
- def on_undefined_code_symbol_found(self, symbol_node, symbol_scope_chain):
- """Receives a report of use of an undefined symbol node."""
+ def on_code_symbol_referenced(self, symbol_node, symbol_scope_chain):
+ """Receives a report of use of a symbol node."""
assert isinstance(symbol_node, SymbolNode)
assert isinstance(symbol_scope_chain, tuple)
assert all(
isinstance(scope, SymbolScopeNode) for scope in symbol_scope_chain)
- state = self.current_render_state
- if symbol_node not in state.undefined_code_symbols:
- state.undefined_code_symbols.append(symbol_node)
- state.undefined_code_symbols_scope_chains.setdefault(
+ self.current_render_state.symbol_to_scope_chains.setdefault(
symbol_node, set()).add(symbol_scope_chain)
+class EmptyNode(CodeNode):
+ """Represents the zero-length text and renders nothing."""
+
+ def __init__(self):
+ CodeNode.__init__(self)
+
+ def _render(self, renderer, last_render_state):
+ pass
+
+
class LiteralNode(CodeNode):
"""
Represents a literal text, which will be rendered as is without any template
- magic applied.
+ magic applied. The given literal text object will be stringified on each
+ rendering.
"""
def __init__(self, literal_text):
- literal_text_gensym = CodeNode.gensym()
- template_text = format_template(
- "${{{literal_text}}}", literal_text=literal_text_gensym)
- template_vars = {literal_text_gensym: literal_text}
+ CodeNode.__init__(self)
- CodeNode.__init__(
- self, template_text=template_text, template_vars=template_vars)
+ self._literal_text = literal_text
+
+ def _render(self, renderer, last_render_state):
+ renderer.push_caller(self)
+ try:
+ renderer.render_text(str(self._literal_text))
+ finally:
+ renderer.pop_caller()
+
+
+def TextNode(template_text):
+ """
+ Represents a template text node.
+ TextNode is designed to be a leaf node of a code node tree. TextNode
+ represents a template text while LiteralNode represents a literal text.
+ All template magics will be applied to |template_text|.
-class TextNode(CodeNode):
+ This function is pretending to be a CodeNode subclass and instantiates one
+ of text-ish code node subclass depending on the content of |template_text|.
+ """
+ assert isinstance(template_text, str)
+
+ if "$" in template_text or "%" in template_text:
+ return _TextNode(template_text)
+ elif template_text:
+ return LiteralNode(template_text)
+ else:
+ return EmptyNode()
+
+
+class _TextNode(CodeNode):
"""
Represents a template text node.
@@ -404,7 +507,7 @@ class CompositeNode(CodeNode):
gensym = CodeNode.gensym()
gensym_args.append("${{{}}}".format(gensym))
template_vars[gensym] = arg
- for key, value in kwargs.iteritems():
+ for key, value in kwargs.items():
assert isinstance(key, (int, long, str))
assert isinstance(value, (CodeNode, int, long, str))
gensym = CodeNode.gensym()
@@ -425,31 +528,27 @@ class ListNode(CodeNode):
except that addition and removal of None have no effect.
"""
- def __init__(self, code_nodes=None, separator=" ", separator_last=""):
+ def __init__(self, code_nodes=None, separator="\n", head="", tail=""):
+ """
+ Args:
+ code_nodes: A list of CodeNode to be rendered.
+ separator: A str inserted between code nodes.
+ head:
+ tail: The head and tail sections that will be rendered iff the
+ content list is not empty.
+ """
assert isinstance(separator, str)
- assert isinstance(separator_last, str)
-
- element_nodes_gensym = CodeNode.gensym()
- element_nodes = []
- template_text = format_template(
- """\
-% for node in {element_nodes}:
-${node}\\
-% if not loop.last:
-{separator}\\
-% endif
-% endfor
-{separator_last}\\
-""",
- element_nodes=element_nodes_gensym,
- separator=separator,
- separator_last=separator_last)
- template_vars = {element_nodes_gensym: element_nodes}
+ assert isinstance(head, str)
+ assert isinstance(tail, str)
- CodeNode.__init__(
- self, template_text=template_text, template_vars=template_vars)
+ CodeNode.__init__(self)
- self._element_nodes = element_nodes
+ self._element_nodes = []
+ self._separator = separator
+ self._head = head
+ self._tail = tail
+
+ self._will_skip_separator = False
if code_nodes is not None:
self.extend(code_nodes)
@@ -463,6 +562,26 @@ ${node}\\
def __len__(self):
return len(self._element_nodes)
+ def _render(self, renderer, last_render_state):
+ renderer.push_caller(self)
+ try:
+ if self._element_nodes:
+ renderer.render_text(self._head)
+ self._will_skip_separator = True
+ for node in self._element_nodes:
+ if self._will_skip_separator:
+ self._will_skip_separator = False
+ else:
+ renderer.render_text(self._separator)
+ node.render(renderer)
+ if self._element_nodes:
+ renderer.render_text(self._tail)
+ finally:
+ renderer.pop_caller()
+
+ def skip_separator(self):
+ self._will_skip_separator = True
+
def append(self, node):
if node is None:
return
@@ -523,25 +642,30 @@ class SequenceNode(ListNode):
and provides the points where SymbolDefinitionNodes can be inserted.
"""
- def __init__(self, code_nodes=None, separator="\n", separator_last=""):
+ def __init__(self, code_nodes=None, separator="\n", head="", tail=""):
ListNode.__init__(
self,
code_nodes=code_nodes,
separator=separator,
- separator_last=separator_last)
+ head=head,
+ tail=tail)
+
+ self._to_be_removed = []
def _render(self, renderer, last_render_state):
- duplicates = []
- for element_node in self:
- if (isinstance(element_node, SymbolDefinitionNode)
- and element_node.is_duplicated()):
- duplicates.append(element_node)
- for element_node in duplicates:
- self.remove(element_node)
-
- return super(SequenceNode, self)._render(
+ if self._to_be_removed:
+ for node in self._to_be_removed:
+ self.remove(node)
+ self._to_be_removed = []
+
+ super(SequenceNode, self)._render(
renderer=renderer, last_render_state=last_render_state)
+ def schedule_to_remove(self, node):
+ """Schedules a task to remove the |node| in the next rendering cycle."""
+ assert node in self
+ self._to_be_removed.append(node)
+
class SymbolScopeNode(SequenceNode):
"""
@@ -551,52 +675,72 @@ class SymbolScopeNode(SequenceNode):
insert corresponding SymbolDefinitionNodes appropriately.
"""
- def __init__(self, code_nodes=None, separator="\n", separator_last=""):
+ def __init__(self, code_nodes=None, separator="\n", head="", tail=""):
SequenceNode.__init__(
self,
code_nodes=code_nodes,
separator=separator,
- separator_last=separator_last)
+ head=head,
+ tail=tail)
self._likeliness = Likeliness.ALWAYS
self._registered_code_symbols = set()
def _render(self, renderer, last_render_state):
for symbol_node in last_render_state.undefined_code_symbols:
- if (self.is_code_symbol_registered(symbol_node)
- and not self.is_code_symbol_defined(symbol_node)):
+ assert self.is_code_symbol_registered(symbol_node)
+ if not self.is_code_symbol_defined(symbol_node):
self._insert_symbol_definition(symbol_node, last_render_state)
- return super(SymbolScopeNode, self)._render(
+ super(SymbolScopeNode, self)._render(
renderer=renderer, last_render_state=last_render_state)
+ if self.current_render_state.undefined_code_symbols:
+ renderer.invalidate_rendering_result()
+
def _insert_symbol_definition(self, symbol_node, last_render_state):
- def count_by_likeliness(render_state):
- counts = {
- Likeliness.UNLIKELY: 0,
- Likeliness.LIKELY: 0,
- Likeliness.ALWAYS: 0,
- }
-
- scope_chains = (render_state.undefined_code_symbols_scope_chains.
- get(symbol_node))
+ DIRECT_USES = "u"
+ DIRECT_CHILD_SCOPES = "s"
+ ANALYSIS_RESULT_KEYS = (
+ # Number of direct uses in this scope
+ DIRECT_USES,
+ # Number of direct child scopes
+ DIRECT_CHILD_SCOPES,
+ # Number of direct child scopes per likeliness
+ Likeliness.ALWAYS,
+ Likeliness.LIKELY,
+ Likeliness.UNLIKELY,
+ )
+
+ def analyze_symbol_usage(render_state):
+ counts = dict.fromkeys(ANALYSIS_RESULT_KEYS, 0)
+
+ scope_chains = render_state.symbol_to_scope_chains.get(symbol_node)
if not scope_chains:
return counts
self_index = iter(scope_chains).next().index(self)
scope_chains = map(
lambda scope_chain: scope_chain[self_index + 1:], scope_chains)
+ scope_to_likeliness = {}
for scope_chain in scope_chains:
if not scope_chain:
- counts[Likeliness.ALWAYS] += 1
+ counts[DIRECT_USES] += 1
else:
likeliness = min(
map(lambda scope: scope.likeliness, scope_chain))
- counts[likeliness] += 1
+ scope = scope_chain[0]
+ scope_to_likeliness[scope] = max(
+ likeliness, scope_to_likeliness.get(scope, likeliness))
+ for likeliness in scope_to_likeliness.values():
+ counts[DIRECT_CHILD_SCOPES] += 1
+ counts[likeliness] += 1
return counts
def likeliness_at(render_state):
- counts = count_by_likeliness(render_state)
+ counts = analyze_symbol_usage(render_state)
+ if counts[DIRECT_USES] >= 1:
+ return Likeliness.ALWAYS
for likeliness in (Likeliness.ALWAYS, Likeliness.LIKELY,
Likeliness.UNLIKELY):
if counts[likeliness] > 0:
@@ -616,21 +760,32 @@ class SymbolScopeNode(SequenceNode):
return True
return False
- counts = count_by_likeliness(last_render_state)
- if counts[Likeliness.ALWAYS] >= 1:
+ counts = analyze_symbol_usage(last_render_state)
+ if counts[DIRECT_USES] >= 1:
did_insert = insert_before_threshold(self, Likeliness.UNLIKELY)
assert did_insert
- elif counts[Likeliness.LIKELY] >= 2:
+ elif counts[DIRECT_CHILD_SCOPES] == 1:
+ pass # Let the child SymbolScopeNode do the work.
+ elif counts[Likeliness.ALWAYS] + counts[Likeliness.LIKELY] >= 2:
did_insert = insert_before_threshold(self, Likeliness.LIKELY)
assert did_insert
else:
- pass # Do nothing and let descendant SymbolScopeNodes do the work.
+ pass # Let descendant SymbolScopeNodes do the work.
def is_code_symbol_registered(self, symbol_node):
+ """
+ Returns True if |symbol_node| is registered and available for use within
+ this scope.
+ """
+ assert isinstance(symbol_node, SymbolNode)
+
if symbol_node in self._registered_code_symbols:
return True
- return super(SymbolScopeNode,
- self).is_code_symbol_registered(symbol_node)
+
+ outer = self.outer_scope()
+ if outer is None:
+ return False
+ return outer.is_code_symbol_registered(symbol_node)
def register_code_symbol(self, symbol_node):
"""Registers a SymbolNode and makes it available in this scope."""
@@ -655,6 +810,33 @@ class SymbolScopeNode(SequenceNode):
assert isinstance(likeliness, Likeliness.Level)
self._likeliness = likeliness
+ def is_code_symbol_defined(self, symbol_node):
+ """
+ Returns True if |symbol_node| is defined in this scope by the moment
+ when the method is called.
+ """
+ assert isinstance(symbol_node, SymbolNode)
+
+ if symbol_node in self.current_render_state.defined_code_symbols:
+ return True
+
+ outer = self.outer_scope()
+ if outer is None:
+ return False
+ return outer.is_code_symbol_defined(symbol_node)
+
+ def on_code_symbol_defined(self, symbol_node):
+ """Receives a report that a symbol gets defined."""
+ assert isinstance(symbol_node, SymbolNode)
+ self.current_render_state.defined_code_symbols.append(symbol_node)
+
+ def on_undefined_code_symbol_found(self, symbol_node):
+ """Receives a report of use of an undefined symbol node."""
+ assert isinstance(symbol_node, SymbolNode)
+ state = self.current_render_state
+ if symbol_node not in state.undefined_code_symbols:
+ state.undefined_code_symbols.append(symbol_node)
+
class SymbolNode(CodeNode):
"""
@@ -676,19 +858,14 @@ class SymbolNode(CodeNode):
given.
"""
assert isinstance(name, str) and name
- assert (template_text is not None
- or definition_constructor is not None)
- assert template_text is None or definition_constructor is None
- if template_text is not None:
- assert isinstance(template_text, str)
- if definition_constructor is not None:
- assert callable(definition_constructor)
CodeNode.__init__(self)
self._name = name
if template_text is not None:
+ assert isinstance(template_text, str)
+ assert definition_constructor is None
def constructor(symbol_node):
return SymbolDefinitionNode(
@@ -697,19 +874,34 @@ class SymbolNode(CodeNode):
self._definition_constructor = constructor
else:
+ assert template_text is None
+ assert callable(definition_constructor)
+
self._definition_constructor = definition_constructor
def _render(self, renderer, last_render_state):
+ self._request_symbol_definition(renderer)
+
+ renderer.render_text(self.name)
+
+ def request_symbol_definition(self):
+ self._request_symbol_definition(self.renderer)
+
+ def _request_symbol_definition(self, renderer):
symbol_scope_chain = tuple(
filter(lambda node: isinstance(node, SymbolScopeNode),
renderer.callers_from_first_to_last))
for caller in renderer.callers_from_last_to_first:
- if caller.is_code_symbol_defined(self):
+ caller.on_code_symbol_referenced(self, symbol_scope_chain)
+ if caller is self.outer:
break
- caller.on_undefined_code_symbol_found(self, symbol_scope_chain)
- return self.name
+ if not symbol_scope_chain[-1].is_code_symbol_defined(self):
+ for scope in reversed(symbol_scope_chain):
+ scope.on_undefined_code_symbol_found(self)
+ if scope is self.outer:
+ break
@property
def name(self):
@@ -719,7 +911,7 @@ class SymbolNode(CodeNode):
"""Creates a new definition node."""
node = self._definition_constructor(self)
assert isinstance(node, SymbolDefinitionNode)
- assert node.is_code_symbol_defined(self)
+ assert node.target_symbol is self
return node
@@ -739,195 +931,18 @@ class SymbolDefinitionNode(SequenceNode):
self._symbol_node = symbol_node
def _render(self, renderer, last_render_state):
- if self.is_duplicated():
- return ""
-
- return super(SymbolDefinitionNode, self)._render(
- renderer=renderer, last_render_state=last_render_state)
-
- def is_code_symbol_defined(self, symbol_node):
- if symbol_node is self._symbol_node:
- return True
- return super(SymbolDefinitionNode,
- self).is_code_symbol_defined(symbol_node)
-
- def is_duplicated(self):
- return self.upstream_of_scope.is_code_symbol_defined(self._symbol_node)
-
-
-class ConditionalNode(CodeNode):
- """
- This is the base class of code nodes that directly contain conditional
- execution. Not all the code nodes inside this node will be executed.
- """
-
-
-class CaseBranchNode(ConditionalNode):
- """
- Represents a set of nodes that will be conditionally executed.
-
- This node mostly follows the concept of 'cond' in Lisp, which is a chain of
- if - else if - else if - ... - else.
- """
-
- def __init__(self, clause_nodes):
- # clause_nodes = [
- # (conditional_node1, body_node1, likeliness1),
- # (conditional_node2, body_node2, likeliness2),
- # ...,
- # (None, body_nodeN, likelinessN), # Corresponds to 'else { ... }'
- # ]
- assert False
-
-
-class ConditionalExitNode(ConditionalNode):
- """
- Represents a conditional node that always exits whenever the condition
- meets. It's not supposed that the body node does not exit. Equivalent to
-
- if (CONDITIONAL) { BODY }
-
- where BODY ends with a return statement.
- """
-
- def __init__(self, cond, body, body_likeliness):
- assert isinstance(cond, CodeNode)
- assert isinstance(body, SymbolScopeNode)
- assert isinstance(body_likeliness, Likeliness.Level)
-
- gensyms = {
- "conditional": CodeNode.gensym(),
- "body": CodeNode.gensym(),
- }
- template_text = format_template(
- """\
-if (${{{conditional}}}) {{
- ${{{body}}}
-}}\\
-""", **gensyms)
- template_vars = {
- gensyms["conditional"]: cond,
- gensyms["body"]: body,
- }
-
- ConditionalNode.__init__(
- self, template_text=template_text, template_vars=template_vars)
-
- self._cond_node = cond
- self._body_node = body
- self._body_node.set_likeliness(body_likeliness)
-
-
-class LikelyExitNode(ConditionalExitNode):
- """
- Represents a conditional exit node where it's likely that the condition
- meets.
- """
-
- def __init__(self, cond, body):
- ConditionalExitNode.__init__(
- self, cond=cond, body=body, body_likeliness=Likeliness.LIKELY)
-
-
-class UnlikelyExitNode(ConditionalExitNode):
- """
- Represents a conditional exit node where it's unlikely that the condition
- meets.
- """
-
- def __init__(self, cond, body):
- ConditionalExitNode.__init__(
- self, cond=cond, body=body, body_likeliness=Likeliness.UNLIKELY)
-
-
-class FunctionDefinitionNode(CodeNode):
- """Represents a function definition."""
-
- def __init__(self,
- name,
- arg_decls,
- return_type,
- member_initializer_list=None,
- local_vars=None,
- body=None,
- comment=None):
- """
- Args:
- name: Function name node, which may include nested-name-specifier
- (i.e. 'namespace_name::' and/or 'type_name::').
- arg_decls: List of argument declaration nodes.
- return_type: Return type node.
- member_initializer_list: List of initializer nodes.
- local_vars: List of SymbolNodes that can be used in the function
- body.
- body: Function body node (of type SymbolScopeNode).
- comment: Function header comment node.
- """
- assert isinstance(name, CodeNode)
- assert isinstance(arg_decls, (list, tuple))
- assert all(isinstance(arg_decl, CodeNode) for arg_decl in arg_decls)
- assert isinstance(return_type, CodeNode)
- if member_initializer_list is None:
- member_initializer_list = []
- assert isinstance(member_initializer_list, (list, tuple))
- assert all(
- isinstance(initializer, CodeNode)
- for initializer in member_initializer_list)
- if local_vars is None:
- local_vars = []
- assert isinstance(local_vars, (list, tuple))
- assert all(
- isinstance(local_var, SymbolNode) for local_var in local_vars)
- if body is None:
- body = SymbolScopeNode()
- assert isinstance(body, CodeNode)
- if comment is None:
- comment = LiteralNode("")
- assert isinstance(comment, CodeNode)
-
- gensyms = {
- "name": CodeNode.gensym(),
- "arg_decls": CodeNode.gensym(),
- "return_type": CodeNode.gensym(),
- "member_initializer_list": CodeNode.gensym(),
- "body": CodeNode.gensym(),
- "comment": CodeNode.gensym(),
- }
-
- maybe_colon = " : " if member_initializer_list else ""
-
- template_text = format_template(
- """\
-${{{comment}}}
-${{{return_type}}} ${{{name}}}(${{{arg_decls}}})\
-{maybe_colon}${{{member_initializer_list}}} {{
- ${{{body}}}
-}}\\
-""",
- maybe_colon=maybe_colon,
- **gensyms)
- template_vars = {
- gensyms["name"]:
- name,
- gensyms["arg_decls"]:
- ListNode(arg_decls, separator=", "),
- gensyms["return_type"]:
- return_type,
- gensyms["member_initializer_list"]:
- ListNode(member_initializer_list, separator=", "),
- gensyms["body"]:
- body,
- gensyms["comment"]:
- comment,
- }
-
- CodeNode.__init__(
- self, template_text=template_text, template_vars=template_vars)
+ scope = self.outer_scope()
+ if scope.is_code_symbol_defined(self._symbol_node):
+ assert isinstance(self.outer, SequenceNode)
+ self.outer.schedule_to_remove(self)
+ self.outer.skip_separator()
+ return
- self._body_node = body
+ scope.on_code_symbol_defined(self._symbol_node)
- self._body_node.register_code_symbols(local_vars)
+ super(SymbolDefinitionNode, self)._render(
+ renderer=renderer, last_render_state=last_render_state)
@property
- def body(self):
- return self._body_node
+ def target_symbol(self):
+ return self._symbol_node
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
new file mode 100644
index 00000000000..b52c867c855
--- /dev/null
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node_cxx.py
@@ -0,0 +1,456 @@
+# 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 module provides C++ language specific implementations of
+code_node.CodeNode.
+"""
+
+from .code_node import CodeNode
+from .code_node import CompositeNode
+from .code_node import Likeliness
+from .code_node import ListNode
+from .code_node import SymbolScopeNode
+from .code_node import TextNode
+from .codegen_expr import CodeGenExpr
+from .codegen_format import format_template
+
+
+class CxxBlockNode(CompositeNode):
+ def __init__(self, body):
+ template_format = (
+ "{{\n" #
+ " {body}\n"
+ "}}")
+
+ CompositeNode.__init__(
+ self,
+ template_format,
+ body=_to_symbol_scope_node(body, Likeliness.ALWAYS))
+
+
+class CxxIfNode(CompositeNode):
+ def __init__(self, cond, body, likeliness):
+ template_format = (
+ "if ({cond}) {{\n" #
+ " {body}\n"
+ "}}")
+
+ CompositeNode.__init__(
+ self,
+ template_format,
+ cond=_to_conditional_node(cond),
+ body=_to_symbol_scope_node(body, likeliness))
+
+
+class CxxIfElseNode(CompositeNode):
+ def __init__(self, cond, then, then_likeliness, else_, else_likeliness):
+ template_format = (
+ "if ({cond}) {{\n" #
+ " {then}\n"
+ "}} else {{\n"
+ " {else_}\n"
+ "}}")
+
+ CompositeNode.__init__(
+ self,
+ template_format,
+ cond=_to_conditional_node(cond),
+ then=_to_symbol_scope_node(then, then_likeliness),
+ else_=_to_symbol_scope_node(else_, else_likeliness))
+
+
+class CxxLikelyIfNode(CxxIfNode):
+ def __init__(self, cond, body):
+ CxxIfNode.__init__(self, cond, body, Likeliness.LIKELY)
+
+
+class CxxUnlikelyIfNode(CxxIfNode):
+ def __init__(self, cond, body):
+ CxxIfNode.__init__(self, cond, body, Likeliness.UNLIKELY)
+
+
+class CxxMultiBranchesNode(CodeNode):
+ class _Clause(object):
+ def __init__(self, cond, body):
+ assert isinstance(cond, (CodeNode, bool))
+ assert isinstance(body, SymbolScopeNode)
+ self.cond = cond
+ self.body = body
+
+ def __init__(self):
+ clauses_gensym = CodeNode.gensym()
+ clauses = []
+ template_text = format_template(
+ """\
+% for {clause} in {clauses}:
+% if not loop.first:
+ else \\
+% endif
+% if {clause}.cond is not False:
+% if {clause}.cond is not True:
+if (${{{clause}.cond}}) \\
+% endif
+{{
+ ${{{clause}.body}}
+}}\\
+% if {clause}.cond is True:
+ <% break %>
+% endif
+% endif
+% endfor\
+""",
+ clause=CodeNode.gensym(),
+ clauses=clauses_gensym)
+ template_vars = {clauses_gensym: clauses}
+
+ CodeNode.__init__(
+ self, template_text=template_text, template_vars=template_vars)
+
+ self._clauses = clauses
+
+ def append(self, cond, body, likeliness=Likeliness.LIKELY):
+ if cond is None:
+ cond = False
+ elif isinstance(cond, CodeGenExpr):
+ if cond.is_always_true:
+ cond = True
+ elif cond.is_always_false:
+ cond = False
+
+ if not isinstance(cond, bool):
+ cond = _to_conditional_node(cond)
+ body = _to_symbol_scope_node(body, likeliness)
+
+ if isinstance(cond, CodeNode):
+ cond.set_outer(self)
+ body.set_outer(self)
+
+ self._clauses.append(self._Clause(cond, body))
+
+
+class CxxBreakableBlockNode(CompositeNode):
+ def __init__(self, body, likeliness=Likeliness.LIKELY):
+ template_format = ("do {{ // Dummy loop for use of 'break'.\n"
+ " {body}\n"
+ "}} while (false);")
+
+ CompositeNode.__init__(
+ self,
+ template_format,
+ body=_to_symbol_scope_node(body, likeliness))
+
+
+class CxxFuncDeclNode(CompositeNode):
+ def __init__(self,
+ name,
+ arg_decls,
+ return_type,
+ template_params=None,
+ static=False,
+ explicit=False,
+ constexpr=False,
+ const=False,
+ override=False,
+ default=False,
+ delete=False):
+ """
+ Args:
+ name: Function name.
+ arg_decls: List of argument declarations.
+ return_type: Return type.
+ template_params: List of template parameters or None.
+ static: True makes this a static function.
+ explicit: True makes this an explicit constructor.
+ constexpr: True makes this a constexpr function.
+ const: True makes this a const function.
+ override: True makes this an overriding function.
+ default: True makes this have the default implementation.
+ delete: True makes this function be deleted.
+ """
+ assert isinstance(static, bool)
+ assert isinstance(explicit, bool)
+ assert isinstance(constexpr, bool)
+ assert isinstance(const, bool)
+ assert isinstance(override, bool)
+ assert isinstance(default, bool)
+ assert isinstance(delete, bool)
+ assert not (default and delete)
+
+ template_format = ("{template}"
+ "{static}{explicit}{constexpr}"
+ "{return_type} "
+ "{name}({arg_decls})"
+ "{const}"
+ "{override}"
+ "{default_or_delete}"
+ ";")
+
+ if template_params is None:
+ template = ""
+ else:
+ template = "template <{}>\n".format(", ".join(template_params))
+
+ static = "static " if static else ""
+ explicit = "explicit " if explicit else ""
+ constexpr = "constexpr " if constexpr else ""
+ const = " const" if const else ""
+ override = " override" if override else ""
+
+ if default:
+ default_or_delete = " = default"
+ elif delete:
+ default_or_delete = " = delete"
+ else:
+ default_or_delete = ""
+
+ CompositeNode.__init__(
+ self,
+ template_format,
+ name=_to_maybe_text_node(name),
+ arg_decls=ListNode(
+ map(_to_maybe_text_node, arg_decls), separator=", "),
+ return_type=_to_maybe_text_node(return_type),
+ template=template,
+ static=static,
+ explicit=explicit,
+ constexpr=constexpr,
+ const=const,
+ override=override,
+ default_or_delete=default_or_delete)
+
+
+class CxxFuncDefNode(CompositeNode):
+ def __init__(self,
+ name,
+ arg_decls,
+ return_type,
+ class_name=None,
+ template_params=None,
+ static=False,
+ inline=False,
+ explicit=False,
+ constexpr=False,
+ const=False,
+ override=False,
+ member_initializer_list=None):
+ """
+ Args:
+ name: Function name.
+ arg_decls: List of argument declarations.
+ return_type: Return type.
+ class_name: Class name to be used as nested-name-specifier.
+ template_params: List of template parameters or None.
+ static: True makes this a static function.
+ inline: True makes this an inline function.
+ explicit: True makes this an explicit constructor.
+ constexpr: True makes this a constexpr function.
+ const: True makes this a const function.
+ override: True makes this an overriding function.
+ member_initializer_list: List of member initializers.
+ """
+ assert isinstance(static, bool)
+ assert isinstance(inline, bool)
+ assert isinstance(explicit, bool)
+ assert isinstance(constexpr, bool)
+ assert isinstance(const, bool)
+ assert isinstance(override, bool)
+
+ template_format = ("{template}"
+ "{static}{inline}{explicit}{constexpr}"
+ "{return_type} "
+ "{class_name}{name}({arg_decls})"
+ "{const}"
+ "{override}"
+ "{member_initializer_list} {{\n"
+ " {body}\n"
+ "}}")
+
+ if class_name is None:
+ class_name = ""
+ else:
+ class_name = ListNode([_to_maybe_text_node(class_name)], tail="::")
+
+ if template_params is None:
+ template = ""
+ else:
+ template = "template <{}>\n".format(", ".join(template_params))
+
+ static = "static " if static else ""
+ inline = "inline " if inline else ""
+ explicit = "explicit " if explicit else ""
+ constexpr = "constexpr " if constexpr else ""
+ const = " const" if const else ""
+ override = " override" if override else ""
+
+ if member_initializer_list is None:
+ member_initializer_list = ""
+ else:
+ member_initializer_list = ListNode(
+ map(_to_maybe_text_node, member_initializer_list),
+ separator=", ",
+ head=" : ")
+
+ self._body_node = SymbolScopeNode()
+
+ CompositeNode.__init__(
+ self,
+ template_format,
+ name=_to_maybe_text_node(name),
+ arg_decls=ListNode(
+ map(_to_maybe_text_node, arg_decls), separator=", "),
+ return_type=_to_maybe_text_node(return_type),
+ class_name=class_name,
+ template=template,
+ static=static,
+ inline=inline,
+ explicit=explicit,
+ constexpr=constexpr,
+ const=const,
+ override=override,
+ member_initializer_list=member_initializer_list,
+ body=self._body_node)
+
+ @property
+ def body(self):
+ return self._body_node
+
+
+class CxxClassDefNode(CompositeNode):
+ def __init__(self, name, base_class_names=None, final=False, export=None):
+ """
+ Args:
+ name: The class name to be defined.
+ base_class_names: The list of base class names.
+ final: True makes this a final class.
+ export: Class export annotation.
+ """
+ assert isinstance(final, bool)
+
+ template_format = ("class{export} {name}{final}{base_clause} {{\n"
+ " {top_section}\n"
+ " {public_section}\n"
+ " {protected_section}\n"
+ " {private_section}\n"
+ " {bottom_section}\n"
+ "}};")
+
+ if export is None:
+ export = ""
+ else:
+ export = ListNode([_to_maybe_text_node(export)], head=" ")
+
+ final = " final" if final else ""
+
+ if base_class_names is None:
+ base_clause = ""
+ else:
+ base_specifier_list = [
+ CompositeNode(
+ "public {base_class_name}",
+ base_class_name=_to_maybe_text_node(base_class_name))
+ for base_class_name in base_class_names
+ ]
+ base_clause = ListNode(
+ base_specifier_list, separator=", ", head=" : ")
+
+ self._top_section = ListNode(tail="\n")
+ self._public_section = ListNode(head="public:\n", tail="\n")
+ self._protected_section = ListNode(head="protected:\n", tail="\n")
+ self._private_section = ListNode(head="private:\n", tail="\n")
+ self._bottom_section = ListNode()
+
+ CompositeNode.__init__(
+ self,
+ template_format,
+ name=_to_maybe_text_node(name),
+ base_clause=base_clause,
+ final=final,
+ export=export,
+ top_section=self._top_section,
+ public_section=self._public_section,
+ protected_section=self._protected_section,
+ private_section=self._private_section,
+ bottom_section=self._bottom_section)
+
+ @property
+ def top_section(self):
+ return self._top_section
+
+ @property
+ def public_section(self):
+ return self._public_section
+
+ @property
+ def protected_section(self):
+ return self._protected_section
+
+ @property
+ def private_section(self):
+ return self._private_section
+
+ @property
+ def bottom_section(self):
+ return self._bottom_section
+
+
+class CxxNamespaceNode(CompositeNode):
+ def __init__(self, name="", body=None):
+ template_format = ("namespace {name} {{\n"
+ "\n"
+ "{body}\n"
+ "\n"
+ "}} // namespace {name}")
+
+ if body is None:
+ self._body = ListNode()
+ else:
+ self._body = _to_list_node(body)
+
+ CompositeNode.__init__(
+ self, template_format, name=name, body=self._body)
+
+ @property
+ def body(self):
+ return self._body
+
+
+def _to_conditional_node(cond):
+ if isinstance(cond, CodeNode):
+ return cond
+ if isinstance(cond, CodeGenExpr):
+ return TextNode(cond.to_text())
+ if isinstance(cond, str):
+ return TextNode(cond)
+ assert False
+
+
+def _to_list_node(node):
+ if isinstance(node, ListNode):
+ return node
+ if isinstance(node, CodeNode):
+ return ListNode([node])
+ if isinstance(node, (list, tuple)):
+ return ListNode(node)
+ assert False
+
+
+def _to_maybe_text_node(node):
+ if isinstance(node, CodeNode):
+ return node
+ if isinstance(node, str):
+ return TextNode(node)
+ assert False
+
+
+def _to_symbol_scope_node(node, likeliness):
+ if isinstance(node, SymbolScopeNode):
+ pass
+ elif isinstance(node, CodeNode):
+ node = SymbolScopeNode([node])
+ elif isinstance(node, (list, tuple)):
+ node = SymbolScopeNode(node)
+ else:
+ assert False
+ node.set_likeliness(likeliness)
+ return node
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node_cxx_test.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node_cxx_test.py
new file mode 100644
index 00000000000..a18f304eadb
--- /dev/null
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node_cxx_test.py
@@ -0,0 +1,211 @@
+# 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.
+
+import unittest
+
+from .code_node import SymbolNode
+from .code_node import SymbolScopeNode
+from .code_node import TextNode
+from .code_node import render_code_node
+from .code_node_cxx import CxxClassDefNode
+from .code_node_cxx import CxxFuncDefNode
+from .code_node_cxx import CxxLikelyIfNode
+from .code_node_cxx import CxxUnlikelyIfNode
+from .codegen_accumulator import CodeGenAccumulator
+from .mako_renderer import MakoRenderer
+
+
+class CodeNodeCxxTest(unittest.TestCase):
+ def setUp(self):
+ super(CodeNodeCxxTest, self).setUp()
+ self.addTypeEqualityFunc(str, self.assertMultiLineEqual)
+
+ def assertRenderResult(self, node, expected):
+ if node.renderer is None:
+ node.set_renderer(MakoRenderer())
+ if node.accumulator is None:
+ node.set_accumulator(CodeGenAccumulator())
+
+ def simplify(text):
+ return "\n".join(
+ [" ".join(line.split()) for line in text.split("\n")])
+
+ actual = simplify(render_code_node(node))
+ expected = simplify(expected)
+
+ self.assertEqual(actual, expected)
+
+ def test_symbol_definition_with_branches(self):
+ root = SymbolScopeNode()
+
+ root.register_code_symbols([
+ SymbolNode("var1", "int ${var1} = 1;"),
+ SymbolNode("var2", "int ${var2} = 2;"),
+ SymbolNode("var3", "int ${var3} = 3;"),
+ SymbolNode("var4", "int ${var4} = 4;"),
+ SymbolNode("var5", "int ${var5} = 5;"),
+ SymbolNode("var6", "int ${var6} = 6;"),
+ ])
+
+ root.extend([
+ TextNode("${var1};"),
+ CxxUnlikelyIfNode(
+ cond=TextNode("${var2}"),
+ body=[
+ TextNode("${var3};"),
+ TextNode("return ${var4};"),
+ ]),
+ CxxLikelyIfNode(
+ cond=TextNode("${var5}"), body=[
+ TextNode("return ${var6};"),
+ ]),
+ TextNode("${var3};"),
+ ])
+
+ self.assertRenderResult(
+ root, """\
+int var1 = 1;
+var1;
+int var2 = 2;
+int var3 = 3;
+if (var2) {
+ var3;
+ int var4 = 4;
+ return var4;
+}
+int var5 = 5;
+if (var5) {
+ int var6 = 6;
+ return var6;
+}
+var3;\
+""")
+
+ def test_symbol_definition_with_nested_branches(self):
+ root = SymbolScopeNode()
+
+ root.register_code_symbols([
+ SymbolNode("var1", "int ${var1} = 1;"),
+ SymbolNode("var2", "int ${var2} = 2;"),
+ SymbolNode("var3", "int ${var3} = 3;"),
+ SymbolNode("var4", "int ${var4} = 4;"),
+ SymbolNode("var5", "int ${var5} = 5;"),
+ SymbolNode("var6", "int ${var6} = 6;"),
+ ])
+
+ root.extend([
+ CxxUnlikelyIfNode(
+ cond=TextNode("false"),
+ body=[
+ CxxUnlikelyIfNode(
+ cond=TextNode("false"),
+ body=[
+ TextNode("return ${var1};"),
+ ]),
+ TextNode("return;"),
+ ]),
+ CxxLikelyIfNode(
+ cond=TextNode("true"),
+ body=[
+ CxxLikelyIfNode(
+ cond=TextNode("true"),
+ body=[
+ TextNode("return ${var2};"),
+ ]),
+ TextNode("return;"),
+ ]),
+ ])
+
+ self.assertRenderResult(
+ root, """\
+if (false) {
+ if (false) {
+ int var1 = 1;
+ return var1;
+ }
+ return;
+}
+if (true) {
+ if (true) {
+ int var2 = 2;
+ return var2;
+ }
+ return;
+}\
+""")
+
+ def test_function_definition_minimum(self):
+ root = CxxFuncDefNode(
+ name="blink::bindings::func", arg_decls=[], return_type="void")
+
+ self.assertRenderResult(root, """\
+void blink::bindings::func() {
+
+}\
+""")
+
+ def test_function_definition_full(self):
+ root = CxxFuncDefNode(
+ name="blink::bindings::func",
+ arg_decls=["int arg1", "int arg2"],
+ return_type="void",
+ const=True,
+ override=True,
+ member_initializer_list=[
+ "member1(0)",
+ "member2(\"str\")",
+ ])
+
+ root.body.register_code_symbols([
+ SymbolNode("var1", "int ${var1} = 1;"),
+ SymbolNode("var2", "int ${var2} = 2;"),
+ ])
+
+ root.body.extend([
+ CxxUnlikelyIfNode(
+ cond=TextNode("${var1}"), body=[TextNode("return ${var1};")]),
+ TextNode("return ${var2};"),
+ ])
+
+ self.assertRenderResult(
+ root, """\
+void blink::bindings::func(int arg1, int arg2) const override\
+ : member1(0), member2("str") {
+ int var1 = 1;
+ if (var1) {
+ return var1;
+ }
+ int var2 = 2;
+ return var2;
+}\
+""")
+
+ def test_class_definition(self):
+ root = CxxClassDefNode("X", ["A", "B"], final=True)
+
+ root.public_section.extend([
+ TextNode("void m1();"),
+ TextNode("void m2();"),
+ ])
+ root.private_section.extend([
+ TextNode("int m1_;"),
+ TextNode("int m2_;"),
+ ])
+
+ self.assertRenderResult(
+ root, """\
+class X final : public A, public B {
+
+ public:
+ void m1();
+ void m2();
+
+
+ private:
+ int m1_;
+ int m2_;
+
+
+};\
+""")
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node_test.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node_test.py
index de94c59f49e..24756d58e94 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node_test.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node_test.py
@@ -4,15 +4,13 @@
import unittest
-from .code_node import FunctionDefinitionNode
-from .code_node import LikelyExitNode
-from .code_node import LiteralNode
from .code_node import ListNode
+from .code_node import LiteralNode
from .code_node import SymbolNode
from .code_node import SymbolScopeNode
from .code_node import TextNode
-from .code_node import UnlikelyExitNode
-from .codegen_utils import render_code_node
+from .code_node import render_code_node
+from .codegen_accumulator import CodeGenAccumulator
from .mako_renderer import MakoRenderer
@@ -24,6 +22,8 @@ class CodeNodeTest(unittest.TestCase):
def assertRenderResult(self, node, expected):
if node.renderer is None:
node.set_renderer(MakoRenderer())
+ if node.accumulator is None:
+ node.set_accumulator(CodeGenAccumulator())
def simplify(text):
return "\n".join(
@@ -75,6 +75,14 @@ class CodeNodeTest(unittest.TestCase):
root.remove(root[-1])
self.assertRenderResult(root, "2,3,5")
+ def test_list_node_head_and_tail(self):
+ self.assertRenderResult(ListNode(), "")
+ self.assertRenderResult(ListNode(head="head"), "")
+ self.assertRenderResult(ListNode(tail="tail"), "")
+ self.assertRenderResult(
+ ListNode([TextNode("-content-")], head="head", tail="tail"),
+ "head-content-tail")
+
def test_nested_sequence(self):
"""Tests nested ListNodes."""
root = ListNode(separator=",")
@@ -96,7 +104,7 @@ class CodeNodeTest(unittest.TestCase):
Tests that use of SymbolNode inserts necessary SymbolDefinitionNode
appropriately.
"""
- root = SymbolScopeNode(separator_last="\n")
+ root = SymbolScopeNode(tail="\n")
root.register_code_symbols([
SymbolNode("var1", "int ${var1} = ${var2} + ${var3};"),
@@ -118,164 +126,6 @@ int var1 = var2 + var3;
(void)var1;
""")
- def test_symbol_definition_with_exit_branches(self):
- root = SymbolScopeNode(separator_last="\n")
-
- root.register_code_symbols([
- SymbolNode("var1", "int ${var1} = 1;"),
- SymbolNode("var2", "int ${var2} = 2;"),
- SymbolNode("var3", "int ${var3} = 3;"),
- SymbolNode("var4", "int ${var4} = 4;"),
- SymbolNode("var5", "int ${var5} = 5;"),
- SymbolNode("var6", "int ${var6} = 6;"),
- ])
-
- root.extend([
- TextNode("${var1};"),
- UnlikelyExitNode(
- cond=TextNode("${var2}"),
- body=SymbolScopeNode([
- TextNode("${var3};"),
- TextNode("return ${var4};"),
- ])),
- LikelyExitNode(
- cond=TextNode("${var5}"),
- body=SymbolScopeNode([
- TextNode("return ${var6};"),
- ])),
- TextNode("${var3};"),
- ])
-
- self.assertRenderResult(
- root, """\
-int var1 = 1;
-var1;
-int var2 = 2;
-int var3 = 3;
-if (var2) {
- var3;
- int var4 = 4;
- return var4;
-}
-int var5 = 5;
-if (var5) {
- int var6 = 6;
- return var6;
-}
-var3;
-""")
-
- def test_symbol_definition_with_nested_exit_branches(self):
- root = SymbolScopeNode(separator_last="\n")
-
- root.register_code_symbols([
- SymbolNode("var1", "int ${var1} = 1;"),
- SymbolNode("var2", "int ${var2} = 2;"),
- SymbolNode("var3", "int ${var3} = 3;"),
- SymbolNode("var4", "int ${var4} = 4;"),
- SymbolNode("var5", "int ${var5} = 5;"),
- SymbolNode("var6", "int ${var6} = 6;"),
- ])
-
- root.extend([
- UnlikelyExitNode(
- cond=LiteralNode("false"),
- body=SymbolScopeNode([
- UnlikelyExitNode(
- cond=LiteralNode("false"),
- body=SymbolScopeNode([
- TextNode("return ${var1};"),
- ])),
- LiteralNode("return;"),
- ])),
- LikelyExitNode(
- cond=LiteralNode("true"),
- body=SymbolScopeNode([
- LikelyExitNode(
- cond=LiteralNode("true"),
- body=SymbolScopeNode([
- TextNode("return ${var2};"),
- ])),
- LiteralNode("return;"),
- ])),
- ])
-
- self.assertRenderResult(
- root, """\
-if (false) {
- if (false) {
- int var1 = 1;
- return var1;
- }
- return;
-}
-if (true) {
- if (true) {
- int var2 = 2;
- return var2;
- }
- return;
-}
-""")
-
- def test_function_definition_minimum(self):
- root = SymbolScopeNode(separator_last="\n")
- root.append(
- FunctionDefinitionNode(
- name=LiteralNode("blink::bindings::func"),
- arg_decls=[],
- return_type=LiteralNode("void")))
-
- self.assertRenderResult(root, """\
-
-void blink::bindings::func() {
-
-}
-""")
-
- def test_function_definition_full(self):
- root = SymbolScopeNode(separator_last="\n")
-
- local_vars = [
- SymbolNode("var1", "int ${var1} = 1;"),
- SymbolNode("var2", "int ${var2} = 2;"),
- ]
-
- func_body = SymbolScopeNode([
- UnlikelyExitNode(
- cond=TextNode("${var1}"),
- body=SymbolScopeNode([TextNode("return ${var1};")])),
- TextNode("return ${var2};"),
- ])
-
- root.append(
- FunctionDefinitionNode(
- name=LiteralNode("blink::bindings::func"),
- arg_decls=[LiteralNode("int arg1"),
- LiteralNode("int arg2")],
- return_type=LiteralNode("void"),
- member_initializer_list=[
- LiteralNode("member1(0)"),
- LiteralNode("member2(\"str\")")
- ],
- local_vars=local_vars,
- body=func_body,
- comment=LiteralNode("// comment1\n// comment2")))
-
- self.assertRenderResult(
- root, """\
-// comment1
-// comment2
-void blink::bindings::func(int arg1, int arg2) : member1(0), member2("str") {
- int var1 = 1;
- if (var1) {
- return var1;
- }
- int var2 = 2;
- return var2;
-}
-""")
-
def test_template_error_handling(self):
renderer = MakoRenderer()
root = SymbolScopeNode()
@@ -288,7 +138,8 @@ void blink::bindings::func(int arg1, int arg2) : member1(0), member2("str") {
]))
with self.assertRaises(NameError):
- root.render()
+ renderer.reset()
+ root.render(renderer)
callers_on_error = list(renderer.callers_on_error)
self.assertEqual(len(callers_on_error), 3)
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 910c4bb185e..f72e41a7421 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
@@ -14,6 +14,12 @@ class CodeGenAccumulator(object):
self._include_headers = set()
# Forward declarations of C++ class
self._class_decls = set()
+ # Forward declarations of C++ struct
+ self._struct_decls = set()
+
+ def total_size(self):
+ return (len(self.include_headers) + len(self.class_decls) + len(
+ self.struct_decls))
@property
def include_headers(self):
@@ -42,3 +48,17 @@ class CodeGenAccumulator(object):
@staticmethod
def require_class_decls(class_names):
return lambda accumulator: accumulator.add_class_decls(class_names)
+
+ @property
+ 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)
+
+ @staticmethod
+ def require_struct_decls(struct_names):
+ return lambda accumulator: accumulator.add_struct_decls(struct_names)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_context.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_context.py
index 8b06e878898..ae9defa40a2 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_context.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_context.py
@@ -4,7 +4,10 @@
import copy
+import web_idl
+
from . import name_style
+from .codegen_format import NonRenderable
from .path_manager import PathManager
@@ -20,8 +23,26 @@ class CodeGenContext(object):
# "for_world" attribute values
MAIN_WORLD = "main"
+ NON_MAIN_WORLDS = "other"
ALL_WORLDS = "all"
+ # "v8_callback_type" attribute values
+ #
+ # void (*)(const v8::FunctionCallbackInfo<v8::Value>&)
+ V8_FUNCTION_CALLBACK = "v8::FunctionCallback"
+ # void (*)(v8::Local<v8::Name>,
+ # const v8::PropertyCallbackInfo<v8::Value>&)
+ V8_ACCESSOR_NAME_GETTER_CALLBACK = "v8::AccessorNameGetterCallback"
+ # void (*)(v8::Local<v8::Name>, v8::Local<v8::Value>,
+ # const v8::PropertyCallbackInfo<void>&)
+ V8_ACCESSOR_NAME_SETTER_CALLBACK = "v8::AccessorNameSetterCallback"
+ # void (*)(v8::Local<v8::Name>, v8::Local<v8::Value>,
+ # const v8::PropertyCallbackInfo<v8::Value>&)
+ V8_GENERIC_NAMED_PROPERTY_SETTER_CALLBACK = (
+ "v8::GenericNamedPropertySetterCallback")
+ # Others
+ V8_OTHER_CALLBACK = "other callback type"
+
@classmethod
def init(cls):
"""Initialize the class. Must be called exactly once."""
@@ -49,11 +70,31 @@ class CodeGenContext(object):
"constructor": None,
"constructor_group": None,
"dict_member": None,
+ "exposed_construct": None,
+ "legacy_window_alias": None,
"operation": None,
"operation_group": None,
+ # Special member-ish definition
+ "indexed_property_getter": None,
+ "indexed_property_setter": None,
+ "named_property_getter": None,
+ "named_property_setter": None,
+ "named_property_deleter": None,
+ "stringifier": None,
+
+ # The names of the class being generated and its base class.
+ "base_class_name": None,
+ "class_name": None,
+
# Main world or all worlds
+ # Used via [PerWorldBindings] to optimize the code path of the main
+ # world.
"for_world": cls.ALL_WORLDS,
+
+ # Type of V8 callback function which implements IDL attribute,
+ # IDL operation, etc.
+ "v8_callback_type": cls.V8_FUNCTION_CALLBACK
}
# List of computational attribute names
@@ -69,11 +110,10 @@ class CodeGenContext(object):
"member_like",
"property_",
"return_type",
- "v8_class",
)
# Define public readonly properties of this class.
- for attr in cls._context_attrs.iterkeys():
+ for attr in cls._context_attrs.keys():
def make_get():
_attr = cls._internal_attr(attr)
@@ -92,11 +132,11 @@ class CodeGenContext(object):
def __init__(self, **kwargs):
assert CodeGenContext._was_initialized
- for arg in kwargs.iterkeys():
+ for arg in kwargs.keys():
assert arg in self._context_attrs, "Unknown argument: {}".format(
arg)
- for attr, default_value in self._context_attrs.iteritems():
+ for attr, default_value in self._context_attrs.items():
value = kwargs[attr] if attr in kwargs else default_value
assert (default_value is None
or type(value) is type(default_value)), (
@@ -108,13 +148,13 @@ class CodeGenContext(object):
Returns a copy of this context applying the updates given as the
arguments.
"""
- for arg in kwargs.iterkeys():
+ for arg in kwargs.keys():
assert arg in self._context_attrs, "Unknown argument: {}".format(
arg)
new_object = copy.copy(self)
- for attr, new_value in kwargs.iteritems():
+ for attr, new_value in kwargs.items():
old_value = getattr(self, attr)
assert old_value is None or type(new_value) is type(old_value), (
"Type mismatch at argument: {}".format(attr))
@@ -131,15 +171,17 @@ class CodeGenContext(object):
"""
bindings = {}
- for attr in self._context_attrs.iterkeys():
+ for attr in self._context_attrs.keys():
value = getattr(self, attr)
- if value is not None:
- bindings[attr] = value
+ if value is None:
+ value = NonRenderable(attr)
+ bindings[attr] = value
for attr in self._computational_attrs:
value = getattr(self, attr)
- if value is not None:
- bindings[attr.strip("_")] = value
+ if value is None:
+ value = NonRenderable(attr)
+ bindings[attr.strip("_")] = value
return bindings
@@ -149,8 +191,18 @@ class CodeGenContext(object):
or self.namespace)
@property
+ def does_override_idl_return_type(self):
+ # Blink implementation returns in a type different from the IDL type.
+ # Namely, IndexedPropertySetterResult, NamedPropertySetterResult, and
+ # NamedPropertyDeleterResult are returned ignoring the operation's
+ # return type.
+ return (self.indexed_property_setter or self.named_property_setter
+ or self.named_property_deleter)
+
+ @property
def function_like(self):
- return (self.callback_function or self.constructor or self.operation)
+ return (self.callback_function or self.constructor or self.operation
+ or self._indexed_or_named_property)
@property
def idl_definition(self):
@@ -161,9 +213,9 @@ class CodeGenContext(object):
@property
def idl_location(self):
idl_def = self.member_like or self.idl_definition
- if idl_def:
+ if idl_def and not isinstance(idl_def, web_idl.Union):
location = idl_def.debug_info.location
- text = PathManager.relpath_to_project_root(location.filepath)
+ text = location.filepath
if location.line_number is not None:
text += ":{}".format(location.line_number)
return text
@@ -185,15 +237,16 @@ class CodeGenContext(object):
@property
def is_return_by_argument(self):
+ if self.does_override_idl_return_type:
+ return False
if self.return_type is None:
- return None
- return_type = self.return_type.unwrap()
- return return_type.is_dictionary or return_type.is_union
+ return False
+ return self.return_type.unwrap().is_union
@property
def may_throw_exception(self):
if not self.member_like:
- return None
+ return False
ext_attr = self.member_like.extended_attributes.get("RaisesException")
if not ext_attr:
return False
@@ -204,28 +257,77 @@ class CodeGenContext(object):
@property
def member_like(self):
return (self.attribute or self.constant or self.constructor
- or self.dict_member or self.operation)
+ or self.dict_member or self.operation
+ or self._indexed_or_named_property)
@property
def property_(self):
+ if self.stringifier:
+ return _StringifierProperty(self.stringifier)
+
return (self.attribute or self.constant or self.constructor_group
- or self.dict_member or self.operation_group)
+ or self.dict_member
+ or (self.legacy_window_alias or self.exposed_construct)
+ or self.operation_group or self._indexed_or_named_property)
@property
def return_type(self):
if self.attribute_get:
return self.attribute.idl_type
- if self.callback_function:
- return self.callback_function.return_type
- if self.operation:
- return self.operation.return_type
+ function_like = self.function_like
+ if function_like:
+ return function_like.return_type
return None
@property
- def v8_class(self):
- if not self.idl_definition:
- return None
- return name_style.class_("v8", self.idl_definition.identifier)
+ def _indexed_or_named_property(self):
+ return (self.indexed_property_getter or self.indexed_property_setter
+ or self.named_property_getter or self.named_property_setter
+ or self.named_property_deleter)
CodeGenContext.init()
+
+
+class _PropertyBase(object):
+ def __init__(self, identifier, extended_attributes, owner, debug_info):
+ assert isinstance(identifier, web_idl.Identifier)
+ assert identifier
+ assert isinstance(extended_attributes, web_idl.ExtendedAttributes)
+ assert isinstance(debug_info, web_idl.DebugInfo)
+
+ self._identifier = identifier
+ self._extended_attributes = extended_attributes
+ self._owner = owner
+ self._debug_info = debug_info
+
+ @property
+ def identifier(self):
+ return self._identifier
+
+ @property
+ def extended_attributes(self):
+ return self._extended_attributes
+
+ @property
+ def owner(self):
+ return self._owner
+
+ @property
+ def debug_info(self):
+ return self._debug_info
+
+
+class _StringifierProperty(_PropertyBase):
+ def __init__(self, stringifier):
+ if stringifier.attribute:
+ extended_attributes = stringifier.attribute.extended_attributes
+ else:
+ extended_attributes = stringifier.operation.extended_attributes
+
+ _PropertyBase.__init__(
+ self,
+ identifier=web_idl.Identifier("toString"),
+ extended_attributes=extended_attributes,
+ owner=stringifier.owner,
+ debug_info=stringifier.debug_info)
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 de9fb61d764..e1b6c8b1b08 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
@@ -4,7 +4,6 @@
import web_idl
-
_CODE_GEN_EXPR_PASS_KEY = object()
@@ -144,18 +143,22 @@ def expr_uniq(terms):
return uniq_terms
-def expr_from_exposure(exposure, in_global=None):
+def expr_from_exposure(exposure, global_names=None):
"""
Args:
- exposure: web_idl.Exposure
- in_global: A global name of [Exposed] that the ExecutionContext is
- supposed to be / represent.
+ exposure: web_idl.Exposure of the target construct.
+ global_names: When specified, it's taken into account that the global
+ object implements |global_names|.
"""
assert isinstance(exposure, web_idl.Exposure)
- assert in_global is None or isinstance(in_global, str)
+ assert (global_names is None
+ or (isinstance(global_names, (list, tuple))
+ and all(isinstance(name, str) for name in global_names)))
def ref_enabled(feature):
- return _Expr("RuntimeEnabledFeatures::{}Enabled()".format(feature))
+ arg = "${execution_context}" if feature.is_context_dependent else ""
+ return _Expr("RuntimeEnabledFeatures::{}Enabled({})".format(
+ feature, arg))
top_terms = [_Expr(True)]
@@ -172,22 +175,26 @@ def expr_from_exposure(exposure, in_global=None):
"Worker": "IsWorkerGlobalScope",
"Worklet": "IsWorkletGlobalScope",
}
- in_globals = set()
- if in_global:
- in_globals.add(in_global)
- for category_name in ("Worker", "Worklet"):
- if in_global.endswith(category_name):
- in_globals.add(category_name)
exposed_terms = []
- for entry in exposure.global_names_and_features:
- terms = []
- if entry.global_name not in in_globals:
+ if global_names:
+ matched_global_count = 0
+ for entry in exposure.global_names_and_features:
+ if entry.global_name not in global_names:
+ continue
+ matched_global_count += 1
+ if entry.feature:
+ exposed_terms.append(ref_enabled(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 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))
@@ -198,13 +205,14 @@ def expr_from_exposure(exposure, in_global=None):
# [SecureContext]
if exposure.only_in_secure_contexts is True:
- top_terms.append(_Expr("${in_secure_context}"))
+ top_terms.append(_Expr("${is_in_secure_context}"))
elif exposure.only_in_secure_contexts is False:
top_terms.append(_Expr(True))
else:
terms = map(ref_enabled, exposure.only_in_secure_contexts)
top_terms.append(
- expr_or([_Expr("${in_secure_context}"),
- expr_not(expr_and(terms))]))
+ expr_or(
+ [_Expr("${is_in_secure_context}"),
+ expr_not(expr_and(terms))]))
return expr_and(top_terms)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_format.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_format.py
index 3b215153021..87d26eec3ca 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_format.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_format.py
@@ -27,7 +27,7 @@ class _TemplateFormatter(string.Formatter):
return args[key]
assert isinstance(key, str)
if not key:
- # Before Python 3.1, when a positional argument specifier is
+ # Prior to Python 3.1, when a positional argument specifier is
# omitted, |format_string="{}"| produces |key=""|. Should be
# removed once Python2 gets retired.
index = self._template_formatter_indexing_count_
@@ -37,3 +37,22 @@ class _TemplateFormatter(string.Formatter):
return kwargs[key]
else:
return "{" + key + "}"
+
+
+class NonRenderable(object):
+ """
+ Represents a non-renderable object.
+
+ Unlike a template variable bound to None, which is a valid Python value,
+ this object raises an exception when rendered, just like an unbound template
+ variable.
+ """
+
+ def __init__(self, error_message="Undefined"):
+ self._error_message = error_message
+
+ def __bool__(self):
+ raise NameError(self._error_message)
+
+ def __str__(self):
+ raise NameError(self._error_message)
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 2635adbafae..7021f1a618c 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
@@ -4,10 +4,14 @@
import web_idl
-from .clang_format import clang_format
+from . import name_style
+from . import style_format
+from .blink_v8_bridge import blink_type_info
from .code_node import CodeNode
+from .code_node import EmptyNode
from .code_node import LiteralNode
from .code_node import SequenceNode
+from .code_node import render_code_node
from .codegen_accumulator import CodeGenAccumulator
from .path_manager import PathManager
@@ -20,6 +24,25 @@ def make_copyright_header():
""")
+def make_forward_declarations(accumulator):
+ assert isinstance(accumulator, CodeGenAccumulator)
+
+ class ForwardDeclarations(object):
+ def __init__(self, accumulator):
+ self._accumulator = accumulator
+
+ def __str__(self):
+ return "\n".join([
+ "class {};".format(class_name)
+ for class_name in sorted(self._accumulator.class_decls)
+ ] + [
+ "struct {};".format(struct_name)
+ for struct_name in sorted(self._accumulator.struct_decls)
+ ])
+
+ return LiteralNode(ForwardDeclarations(accumulator))
+
+
def make_header_include_directives(accumulator):
assert isinstance(accumulator, CodeGenAccumulator)
@@ -36,6 +59,23 @@ def make_header_include_directives(accumulator):
return LiteralNode(HeaderIncludeDirectives(accumulator))
+def component_export(component):
+ assert isinstance(component, web_idl.Component)
+
+ return name_style.macro(component, "EXPORT")
+
+
+def component_export_header(component):
+ assert isinstance(component, web_idl.Component)
+
+ if component == "core":
+ return "third_party/blink/renderer/core/core_export.h"
+ elif component == "modules":
+ return "third_party/blink/renderer/modules/modules_export.h"
+ else:
+ assert False
+
+
def enclose_with_header_guard(code_node, header_guard):
assert isinstance(code_node, CodeNode)
assert isinstance(header_guard, str)
@@ -43,93 +83,64 @@ def enclose_with_header_guard(code_node, header_guard):
return SequenceNode([
LiteralNode("#ifndef {}".format(header_guard)),
LiteralNode("#define {}".format(header_guard)),
- LiteralNode(""),
+ EmptyNode(),
code_node,
- LiteralNode(""),
+ EmptyNode(),
LiteralNode("#endif // {}".format(header_guard)),
])
-def enclose_with_namespace(code_node, namespace):
- assert isinstance(code_node, CodeNode)
- assert isinstance(namespace, str)
-
- return SequenceNode([
- LiteralNode("namespace {} {{".format(namespace)),
- LiteralNode(""),
- code_node,
- LiteralNode(""),
- LiteralNode("}} // namespace {}".format(namespace)),
- ])
-
-
-def traverse_idl_types(idl_definition, callback):
+def collect_include_headers_of_idl_types(idl_types):
"""
- Traverses in the given |idl_definition| to find all the web_idl.IdlType used
- in the IDL definition. Invokes |callback| with each web_idl.IdlType.
+ Returns a set of header paths that are required by |idl_types|.
"""
- assert callable(callback)
-
- def get(obj, attr):
- try:
- return getattr(obj, attr)
- except:
- return ()
-
- xs = (get(idl_definition, "attributes") + get(idl_definition, "constants")
- + get(idl_definition, "own_members") + (idl_definition, ))
- for x in xs:
- idl_type = get(x, "idl_type")
- if idl_type:
- callback(idl_type)
-
- xs = (get(idl_definition, "constructors") + get(idl_definition,
- "operations"))
- for x in xs:
- for argument in x.arguments:
- callback(argument.idl_type)
- if x.return_type is not None:
- callback(x.return_type)
-
- xs = get(idl_definition, "flattened_member_types")
- for x in xs:
- callback(x)
-
-
-def collect_include_headers(idl_definition):
- """
- Returns a list of include headers that are required by generated bindings of
- |idl_definition|.
- """
- type_def_objs = set()
-
- def collect_type_def_obj(idl_type):
- type_def_obj = idl_type.unwrap().type_definition_object
- if type_def_obj is not None:
- type_def_objs.add(type_def_obj)
-
- traverse_idl_types(idl_definition, collect_type_def_obj)
-
header_paths = set()
- for type_def_obj in type_def_objs:
- if isinstance(type_def_obj, web_idl.Enumeration):
- continue
- header_paths.add(PathManager(type_def_obj).blink_path(ext="h"))
-
- return header_paths
+ 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)
-def render_code_node(code_node):
- """
- Renders |code_node| and turns it into text letting |code_node| apply all
- necessary changes (side effects). Returns the resulting text.
- """
- prev = "_"
- current = ""
- while current != prev:
- prev = current
- current = str(code_node)
- return current
+ return header_paths
def write_code_node_to_file(code_node, filepath):
@@ -139,7 +150,12 @@ def write_code_node_to_file(code_node, filepath):
rendered_text = render_code_node(code_node)
- format_result = clang_format(rendered_text, filename=filepath)
+ format_result = style_format.auto_format(rendered_text, filename=filepath)
+ if not format_result.did_succeed:
+ raise RuntimeError("Style-formatting failed: filename = {filename}\n"
+ "---- stderr ----\n"
+ "{stderr}:".format(
+ filename=format_result.filename,
+ stderr=format_result.error_message))
- with open(filepath, "w") as output_file:
- output_file.write(format_result.contents)
+ web_idl.file_io.write_to_file_if_changed(filepath, format_result.contents)
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 9f2cfae5a15..baeeebbb697 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
@@ -9,20 +9,35 @@ import web_idl
from . import name_style
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 .code_node import FunctionDefinitionNode
+from .code_node import Likeliness
+from .code_node import ListNode
from .code_node import SequenceNode
+from .code_node import SymbolNode
from .code_node import SymbolScopeNode
from .code_node import TextNode
+from .code_node_cxx import CxxClassDefNode
+from .code_node_cxx import CxxFuncDeclNode
+from .code_node_cxx import CxxFuncDefNode
+from .code_node_cxx import CxxIfElseNode
+from .code_node_cxx import CxxLikelyIfNode
+from .code_node_cxx import CxxNamespaceNode
+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 enclose_with_namespace
+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
from .codegen_utils import make_copyright_header
+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 .path_manager import PathManager
_DICT_MEMBER_PRESENCE_PREDICATES = {
"ScriptValue": "{}.IsEmpty()",
@@ -71,178 +86,337 @@ def _member_presence_expr(member):
return _format(_DICT_MEMBER_PRESENCE_PREDICATES[blink_type], _1)
-def make_dict_member_get_def(cg_context):
+def bind_member_iteration_local_vars(code_node):
+ local_vars = [
+ SymbolNode(
+ "current_context", "v8::Local<v8::Context> ${current_context} = "
+ "${isolate}->GetCurrentContext();"),
+ SymbolNode(
+ "member_names", "const auto* ${member_names} = "
+ "GetV8MemberNames(${isolate}).data();"),
+ SymbolNode(
+ "is_in_secure_context", "const bool ${is_in_secure_context} = "
+ "${execution_context}->IsSecureContext();"),
+ ]
+
+ # Execution context
+ node = SymbolNode(
+ "execution_context", "ExecutionContext* ${execution_context} = "
+ "ToExecutionContext(${current_context});")
+ node.accumulate(
+ CodeGenAccumulator.require_include_headers([
+ "third_party/blink/renderer/core/execution_context/execution_context.h"
+ ]))
+ local_vars.append(node)
+
+ code_node.register_code_symbols(local_vars)
+
+
+def _make_include_headers(cg_context):
assert isinstance(cg_context, CodeGenContext)
- T = TextNode
+ dictionary = cg_context.dictionary
- member = cg_context.dict_member
+ header_includes = set()
+ source_includes = set()
- func_name = "{}::{}".format(
- blink_class_name(cg_context.dictionary),
- _blink_member_name(member).get_api)
- func_def = FunctionDefinitionNode(
- name=T(func_name),
- arg_decls=[],
- return_type=T(blink_type_info(member.idl_type).ref_t))
+ if dictionary.inherited:
+ header_includes.add(
+ PathManager(dictionary.inherited).api_path(ext="h"))
+ else:
+ header_includes.add(
+ "third_party/blink/renderer/platform/bindings/dictionary_base.h")
+
+ header_includes.update([
+ component_export_header(dictionary.components[0]),
+ "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",
+ ])
+ source_includes.update([
+ "third_party/blink/renderer/platform/bindings/exception_messages.h",
+ "third_party/blink/renderer/platform/bindings/exception_state.h",
+ "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h",
+ "third_party/blink/renderer/platform/heap/visitor.h",
+ ])
- body = func_def.body
- body.add_template_vars(cg_context.template_bindings())
+ header_includes.update(
+ collect_include_headers_of_idl_types(
+ [member.idl_type for member in dictionary.own_members]))
- _1 = _blink_member_name(member).has_api
- body.append(T(_format("DCHECK({_1}());", _1=_1)))
+ return header_includes, source_includes
- _1 = _blink_member_name(member).value_var
- body.append(T(_format("return {_1};", _1=_1)))
- return func_def
+def _make_forward_declarations(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+
+ dictionary = cg_context.dictionary
+
+ header_class_fwd_decls = set([
+ "ExceptionState",
+ "Visitor",
+ ])
+ header_struct_fwd_decls = set()
+
+ source_class_fwd_decls = set()
+ source_struct_fwd_decls = set()
+
+ return (header_class_fwd_decls, header_struct_fwd_decls,
+ source_class_fwd_decls, source_struct_fwd_decls)
-def make_dict_member_has_def(cg_context):
+def make_dict_member_get(cg_context):
assert isinstance(cg_context, CodeGenContext)
- T = TextNode
+ member = cg_context.dict_member
+ blink_member_name = _blink_member_name(member)
+ name = blink_member_name.get_api
+ blink_type = blink_type_info(member.idl_type)
+
+ decls = ListNode()
+ defs = ListNode()
+
+ func_def = CxxFuncDefNode(
+ name=name,
+ arg_decls=[],
+ return_type=blink_type.const_ref_t,
+ const=True)
+ decls.append(func_def)
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ func_def.body.extend([
+ TextNode(_format("DCHECK({}());", blink_member_name.has_api)),
+ 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)
+ decls.append(func_def)
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ func_def.body.extend([
+ TextNode(_format("DCHECK({}());", blink_member_name.has_api)),
+ TextNode(_format("return {};", blink_member_name.value_var)),
+ ])
+
+ return decls, defs
+
+
+def make_dict_member_has(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
member = cg_context.dict_member
- func_name = "{}::{}".format(
- blink_class_name(cg_context.dictionary),
- _blink_member_name(member).has_api)
- func_def = FunctionDefinitionNode(
- name=T(func_name), arg_decls=[], return_type=T("bool"))
+ decls = ListNode()
+ defs = ListNode()
+ func_def = CxxFuncDefNode(
+ name=_blink_member_name(member).has_api,
+ arg_decls=[],
+ return_type="bool",
+ const=True)
+ decls.append(func_def)
+ func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
_1 = _member_presence_expr(member)
- body.append(T(_format("return {_1};", _1=_1)))
+ body.append(TextNode(_format("return {_1};", _1=_1)))
- return func_def
+ return decls, defs
-def make_dict_member_set_def(cg_context):
+def make_dict_member_set(cg_context):
assert isinstance(cg_context, CodeGenContext)
T = TextNode
member = cg_context.dict_member
+ blink_member_name = _blink_member_name(member)
+ real_type = member.idl_type.unwrap(typedef=True)
+ type_info = blink_type_info(real_type)
+
+ decls = ListNode()
+ defs = ListNode()
+
+ template_func_def = CxxFuncDefNode(
+ name=blink_member_name.set_api,
+ arg_decls=["T&& value"],
+ return_type="void",
+ template_params=["typename T"])
+ decls.append(template_func_def)
+
+ # This setter with the explicit type declaration makes it possible to set
+ # the dictionary member with uniform initialization (especially aggregate
+ # initialization), e.g. setIntVector({3, 1, 4, 1, 5}).
+ move_func_decl = CxxFuncDeclNode(
+ name=blink_member_name.set_api,
+ arg_decls=[_format("{}&&", type_info.member_t)],
+ return_type="void")
+ decls.append(move_func_decl)
+
+ move_func_def = CxxFuncDefNode(
+ name=blink_member_name.set_api,
+ arg_decls=[_format("{}&& value", type_info.member_t)],
+ return_type="void",
+ class_name=cg_context.class_name)
+ defs.append(move_func_def)
+
+ _1 = blink_member_name.value_var
+ template_func_def.body.append(
+ T(_format("{_1} = std::forward<T>(value);", _1=_1)))
+ move_func_def.body.append(T(_format("{_1} = value;", _1=_1)))
+
+ if _does_use_presence_flag(member):
+ set_presense_expr = _format("{} = true;",
+ blink_member_name.presence_var)
+ template_func_def.body.append(T(set_presense_expr))
+ move_func_def.body.append(T(set_presense_expr))
+
+ # Migration Adapter
+ if (real_type.is_nullable and
+ blink_type_info(real_type).typename.startswith("base::Optional")):
+ to_null_func_def = CxxFuncDefNode(
+ name=_format("{}ToNull", blink_member_name.set_api),
+ arg_decls=[],
+ return_type="void")
+ decls.append(to_null_func_def)
+ to_null_func_def.set_base_template_vars(cg_context.template_bindings())
+ to_null_func_def.body.append(
+ T(_format("{}(base::nullopt);", blink_member_name.set_api)))
+
+ return decls, defs
+
+
+def make_dict_member_vars(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
- func_name = "{}::{}".format(
- blink_class_name(cg_context.dictionary),
- _blink_member_name(member).set_api)
- func_def = FunctionDefinitionNode(
- name=T(func_name),
- arg_decls=[
- T(_format("{} value",
- blink_type_info(member.idl_type).ref_t))
- ],
- return_type=T("void"))
+ member = cg_context.dict_member
- body = func_def.body
- body.add_template_vars(cg_context.template_bindings())
+ default_value_initializer = ""
+ if member.default_value:
+ default_expr = make_default_value_expr(member.idl_type,
+ member.default_value)
+ if default_expr.initializer is not None:
+ default_value_initializer = _format("{{{}}}",
+ default_expr.initializer)
- _1 = _blink_member_name(member).value_var
- body.append(T(_format("{_1} = value;", _1=_1)))
+ _1 = blink_type_info(member.idl_type).member_t
+ _2 = _blink_member_name(member).value_var
+ _3 = default_value_initializer
+ value_var_def = TextNode(_format("{_1} {_2}{_3};", _1=_1, _2=_2, _3=_3))
if _does_use_presence_flag(member):
_1 = _blink_member_name(member).presence_var
- body.append(T(_format("{_1} = true;", _1=_1)))
+ presense_var_def = TextNode(_format("bool {_1} = false;", _1=_1))
+ else:
+ presense_var_def = None
- return func_def
+ return value_var_def, presense_var_def
-def make_get_v8_dict_member_names_def(cg_context):
+def make_get_v8_dict_member_names_func(cg_context):
assert isinstance(cg_context, CodeGenContext)
- T = TextNode
-
dictionary = cg_context.dictionary
-
- func_name = _format("{}::GetV8MemberNames",
- blink_class_name(cg_context.dictionary))
- func_def = FunctionDefinitionNode(
- name=T(func_name),
- arg_decls=[T("v8::Isolate* isolate")],
- return_type=T("const v8::Eternal<v8::Name>*"),
- comment=T("// static"))
-
+ name = "GetV8MemberNames"
+ arg_decls = ["v8::Isolate* isolate"]
+ return_type = "const base::span<const v8::Eternal<v8::Name>>"
+
+ func_decl = CxxFuncDeclNode(
+ name=name, arg_decls=arg_decls, return_type=return_type, static=True)
+ func_def = CxxFuncDefNode(
+ name=name,
+ class_name=cg_context.class_name,
+ arg_decls=arg_decls,
+ return_type=return_type)
+ func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
- pattern = ("static const char* kKeyStrings[] = {{{_1}}};")
- _1 = ", ".join(
- _format("\"{}\"", member.identifier) for member in dictionary.members)
- body.extend([
- T(_format(pattern, _1=_1)),
- T("return V8PerIsolateData::From(isolate)"
- "->FindOrCreateEternalNameCache("
- "kKeyStrings, kKeyStrings, base::size(kKeyStrings));")
- ])
+ if dictionary.own_members:
+ pattern = "static const char* kKeyStrings[] = {{{_1}}};"
+ _1 = ", ".join(
+ _format("\"{}\"", member.identifier)
+ for member in dictionary.own_members)
+ body.extend([
+ TextNode(_format(pattern, _1=_1)),
+ TextNode("return V8PerIsolateData::From(isolate)"
+ "->FindOrCreateEternalNameCache(kKeyStrings, "
+ "kKeyStrings);"),
+ ])
+ else:
+ body.append(TextNode("return {};"))
- return func_def
+ return func_decl, func_def
-def make_fill_with_dict_members_def(cg_context):
+def make_fill_with_dict_members_func(cg_context):
assert isinstance(cg_context, CodeGenContext)
- T = TextNode
-
dictionary = cg_context.dictionary
-
- func_name = _format(
- "{_1}::FillWithMembers", _1=blink_class_name(dictionary))
- func_def = FunctionDefinitionNode(
- name=T(func_name),
- arg_decls=[
- T("v8::Isolate* isolate"),
- T("v8::Local<v8::Object> creation_context"),
- T("v8::Local<v8::Object> v8_dictionary"),
- ],
- return_type=T("bool"))
-
+ name = "FillWithMembers"
+ arg_decls = [
+ "v8::Isolate* isolate",
+ "v8::Local<v8::Object> creation_context",
+ "v8::Local<v8::Object> v8_dictionary",
+ ]
+ return_type = "bool"
+
+ 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
- body.add_template_vars(cg_context.template_bindings())
if dictionary.inherited:
text = """\
if (!BaseClass::FillWithMembers(isolate, creation_context, v8_dictionary)) {
return false;
}"""
- body.append(T(text))
+ body.append(TextNode(text))
body.append(
- T("return FillWithOwnMembers("
- "isolate, creation_context, v8_dictionary)"))
+ TextNode("return FillWithOwnMembers("
+ "isolate, creation_context, v8_dictionary);"))
- return func_def
+ return func_decl, func_def
-def make_fill_with_own_dict_members_def(cg_context):
+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
-
- func_name = _format(
- "{_1}::FillWithOwnMembers", _1=blink_class_name(dictionary))
- func_def = FunctionDefinitionNode(
- name=T(func_name),
- arg_decls=[
- T("v8::Isolate* isolate"),
- T("v8::Local<v8::Object> creation_context"),
- T("v8::Local<v8::Object> v8_dictionary")
- ],
- return_type=T("bool"))
-
+ name = "FillWithOwnMembers"
+ arg_decls = [
+ "v8::Isolate* isolate",
+ "v8::Local<v8::Object> creation_context",
+ "v8::Local<v8::Object> v8_dictionary",
+ ]
+ return_type = "bool"
+
+ func_decl = CxxFuncDeclNode(
+ name=name, arg_decls=arg_decls, return_type=return_type, const=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
- body.add_template_vars(cg_context.template_bindings())
-
- text = """\
-const v8::Eternal<v8::Name>* member_names = GetV8MemberNames(isolate);
-v8::Local<v8::Context> current_context = isolate->GetCurrentContext();"""
- body.append(T(text))
+ body.add_template_var("isolate", "isolate")
+ bind_member_iteration_local_vars(body)
- # TODO(peria): Support runtime enabled / origin trial members.
for key_index, member in enumerate(own_members):
_1 = _blink_member_name(member).has_api
_2 = key_index
@@ -251,8 +425,8 @@ v8::Local<v8::Context> current_context = isolate->GetCurrentContext();"""
if ({_1}()) {{
if (!v8_dictionary
->CreateDataProperty(
- current_context,
- member_names[{_2}].Get(isolate),
+ ${current_context},
+ ${member_names}[{_2}].Get(isolate),
ToV8({_3}(), creation_context, isolate))
.ToChecked()) {{
return false;
@@ -263,133 +437,162 @@ if ({_1}()) {{
conditional = expr_from_exposure(member.exposure)
if not conditional.is_always_true:
- node = SequenceNode([
- T(_format("if ({}) {{", conditional.to_text())),
- node,
- T("}"),
- ])
+ node = CxxLikelyIfNode(cond=conditional, body=node)
body.append(node)
body.append(T("return true;"))
- return func_def
+ return func_decl, func_def
-def make_dict_create_def(cg_context):
+def make_dict_create_funcs(cg_context):
assert isinstance(cg_context, CodeGenContext)
- T = TextNode
-
- dictionary = cg_context.dictionary
- class_name = blink_class_name(dictionary)
-
- func_def = FunctionDefinitionNode(
- name=T(_format("{_1}::Create", _1=class_name)),
- arg_decls=[
- T("v8::Isolate* isolate"),
- T("v8::Local<v8::Object> v8_dictionary"),
- T("ExceptionState& exception_state"),
- ],
- return_type=T(_format("{_1}*", _1=class_name)),
- comment=T("// static"))
-
- body = func_def.body
- body.add_template_vars(cg_context.template_bindings())
-
- pattern = """\
-{_1}* dictionary = MakeGarbageCollected<{_1}>();
-dictionary->FillMembers(isolate, v8_dictionary, exception_state);
+ 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;"""
- body.append(T(_format(pattern, _1=class_name)))
+return dictionary;"""))
- return func_def
+ decls = ListNode([
+ default_create_def,
+ create_decl,
+ ])
+ defs = ListNode([
+ create_def,
+ ])
+ return decls, defs
-def make_fill_dict_members_def(cg_context):
+
+def make_fill_dict_members_func(cg_context):
assert isinstance(cg_context, CodeGenContext)
T = TextNode
dictionary = cg_context.dictionary
- class_name = blink_class_name(dictionary)
own_members = dictionary.own_members
required_own_members = list(
member for member in own_members if member.is_required)
-
- func_name = _format("{_1}::FillMembers", _1=class_name)
- func_def = FunctionDefinitionNode(
- name=T(func_name),
- arg_decls=[
- T("v8::Isolate* isolate"),
- T("v8::Local<v8::Object> v8_dictionary"),
- T("ExceptionState& exception_state"),
- ],
- return_type=T("void"))
-
- body = func_def.body
- body.add_template_vars(cg_context.template_bindings())
-
- text = "if (v8_dictionary->IsUndefinedOrNull()) { return; }"
- if len(required_own_members) > 0:
- text = """\
-if (v8_dictionary->IsUndefinedOrNull()) {
- exception_state.ThrowError(ExceptionMessages::FailedToConstruct(
+ name = "FillMembers"
+ arg_decls = [
+ "v8::Isolate* isolate",
+ "v8::Local<v8::Value> v8_value",
+ "ExceptionState& exception_state",
+ ]
+ return_type = "void"
+
+ func_decl = CxxFuncDeclNode(
+ name=name, arg_decls=arg_decls, return_type=return_type)
+ func_def = CxxFuncDefNode(
+ name=name,
+ class_name=cg_context.class_name,
+ arg_decls=arg_decls,
+ return_type=return_type)
+ func_def.set_base_template_vars(cg_context.template_bindings())
+
+ if required_own_members:
+ check_required_members_node = T("""\
+if (v8_value->IsNullOrUndefined()) {
+ exception_state.ThrowTypeError(ExceptionMessages::FailedToConstruct(
"${dictionary.identifier}",
"has required members, but null/undefined was passed."));
return;
-}"""
- body.append(T(text))
+}""")
+ else:
+ check_required_members_node = T("""\
+if (v8_value->IsNullOrUndefined()) {
+ return;
+}""")
# [PermissiveDictionaryConversion]
if "PermissiveDictionaryConversion" in dictionary.extended_attributes:
- text = """\
-if (!v8_dictionary->IsObject()) {
+ permissive_conversion_node = T("""\
+if (!v8_value->IsObject()) {
// [PermissiveDictionaryConversion]
return;
-}"""
+}""")
else:
- text = """\
-if (!v8_dictionary->IsObject()) {
+ permissive_conversion_node = T("""\
+if (!v8_value->IsObject()) {
exception_state.ThrowTypeError(
ExceptionMessages::FailedToConstruct(
"${dictionary.identifier}", "The value is not of type Object"));
return;
-}"""
- body.append(T(text))
+}""")
- body.append(
- T("FillMembersInternal(isolate, v8_dictionary, exception_state);"))
+ call_internal_func_node = T("""\
+FillMembersInternal(isolate, v8_value.As<v8::Object>(), exception_state);""")
- return func_def
+ func_def.body.extend([
+ check_required_members_node,
+ permissive_conversion_node,
+ call_internal_func_node,
+ ])
+
+ return func_decl, func_def
-def make_fill_dict_members_internal_def(cg_context):
+def make_fill_dict_members_internal_func(cg_context):
assert isinstance(cg_context, CodeGenContext)
T = TextNode
dictionary = cg_context.dictionary
own_members = dictionary.own_members
- class_name = blink_class_name(dictionary)
-
- func_name = _format("{_1}::FillMembersInternal", _1=class_name)
- func_def = FunctionDefinitionNode(
- name=T(func_name),
- arg_decls=[
- T("v8::Isolate* isolate"),
- T("v8::Local<v8::Object> v8_dictionary"),
- T("ExceptionState& exception_state"),
- ],
- return_type=T("void"))
-
+ name = "FillMembersInternal"
+ arg_decls = [
+ "v8::Isolate* isolate",
+ "v8::Local<v8::Object> v8_dictionary",
+ "ExceptionState& exception_state",
+ ]
+ return_type = "void"
+ func_decl = CxxFuncDeclNode(
+ name=name, arg_decls=arg_decls, return_type=return_type)
+ func_def = CxxFuncDefNode(
+ name=name,
+ class_name=cg_context.class_name,
+ arg_decls=arg_decls,
+ return_type=return_type)
+ func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
- body.add_template_vars(cg_context.template_bindings())
body.add_template_var("isolate", "isolate")
body.add_template_var("exception_state", "exception_state")
+ bind_member_iteration_local_vars(body)
+ body.register_code_symbols([
+ SymbolNode("try_block", "v8::TryCatch ${try_block}(${isolate});"),
+ SymbolNode("v8_value", "v8::Local<v8::Value> ${v8_value};"),
+ ])
if dictionary.inherited:
text = """\
@@ -400,20 +603,10 @@ if (${exception_state}.HadException()) {
"""
body.append(T(text))
- body.extend([
- T("const v8::Eternal<v8::Name>* member_names = "
- "GetV8MemberNames(${isolate});"),
- T("v8::TryCatch try_block(${isolate});"),
- T("v8::Local<v8::Context> current_context = "
- "${isolate}->GetCurrentContext();"),
- T("v8::Local<v8::Value> v8_value;"),
- ])
-
- # TODO(peria): Support origin-trials and runtime enabled features.
for key_index, member in enumerate(own_members):
body.append(make_fill_own_dict_member(key_index, member))
- return func_def
+ return func_decl, func_def
def make_fill_own_dict_member(key_index, member):
@@ -423,116 +616,266 @@ def make_fill_own_dict_member(key_index, member):
T = TextNode
pattern = """
-if (!v8_dictionary->Get(current_context, member_names[{_1}].Get(${isolate}))
- .ToLocal(&v8_memer)) {{
- ${exception_state}.RethrowV8Exception(try_block.Exception());
+if (!<% try_block %>v8_dictionary->Get(${current_context}, ${member_names}[{_1}].Get(${isolate}))
+ .ToLocal(&${v8_value})) {{
+ ${exception_state}.RethrowV8Exception(${try_block}.Exception());
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))
+ 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)))
- throw_if_required_member_is_missing_node = None
if member.is_required:
- pattern = """\
+ exception_pattern = """\
${exception_state}.ThrowTypeError(
ExceptionMessages::FailedToGet(
- "{_1}", "${{dictionary.identifier}}",
+ "{}", "${{dictionary.identifier}}",
"Required member is undefined."));
"""
- throw_if_required_member_is_missing_node = T(
- _format(pattern, _1=member.identifier))
+
+ 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)
+ else:
+ check_and_fill_node = CxxLikelyIfNode(
+ cond="!${v8_value}->IsUndefined()", body=api_call_node)
node = SequenceNode([
get_v8_value_node,
- T("if (!v8_value->IsUndefined()) {"),
- api_call_node,
- T("} else {") if throw_if_required_member_is_missing_node else None,
- throw_if_required_member_is_missing_node,
- T("}"),
+ check_and_fill_node,
])
conditional = expr_from_exposure(member.exposure)
if not conditional.is_always_true:
- node = SequenceNode([
- T(_format("if ({}) {{", conditional.to_text())),
- node,
- T("}"),
- ])
+ node = CxxLikelyIfNode(cond=conditional, body=node)
return node
-def make_dict_trace_def(cg_context):
+def make_dict_trace_func(cg_context):
assert isinstance(cg_context, CodeGenContext)
T = TextNode
dictionary = cg_context.dictionary
own_members = dictionary.own_members
- class_name = blink_class_name(dictionary)
-
- func_def = FunctionDefinitionNode(
- name=T(_format("{_1}::Trace", _1=class_name)),
- arg_decls=[
- T("Visitor* visitor"),
- ],
- return_type=T("void"))
-
+ name = "Trace"
+ 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_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
- body.add_template_vars(cg_context.template_bindings())
- def trace_member_node(member):
+ def make_trace_member_node(member):
pattern = "TraceIfNeeded<{_1}>::Trace(visitor, {_2});"
_1 = blink_type_info(member.idl_type).member_t
_2 = _blink_member_name(member).value_var
- return T(_format(pattern, _1=_1, _2=_2))
-
- body.extend(map(trace_member_node, own_members))
+ return TextNode(_format(pattern, _1=_1, _2=_2))
- if dictionary.inherited:
- body.append(T("BaseClass::Trace(visitor);"))
-
- return func_def
-
-
-def generate_dictionaries(web_idl_database, output_dirs):
- dictionary = web_idl_database.find("MediaDecodingConfiguration")
- filename = "example_dictionary.cc"
- filepath = os.path.join(output_dirs['core'], filename)
+ body.extend(map(make_trace_member_node, own_members))
+ body.append(TextNode("BaseClass::Trace(visitor);"))
- cg_context = CodeGenContext(dictionary=dictionary)
+ return func_decl, func_def
- root_node = SymbolScopeNode(separator_last="\n")
- root_node.set_renderer(MakoRenderer())
- code_node = SequenceNode()
+def generate_dictionary(dictionary):
+ assert len(dictionary.components) == 1, (
+ "We don't support partial dictionaries across components yet.")
+ component = dictionary.components[0]
- code_node.extend([
- make_get_v8_dict_member_names_def(cg_context),
- make_dict_create_def(cg_context),
- make_fill_dict_members_def(cg_context),
- make_fill_dict_members_internal_def(cg_context),
- make_fill_with_dict_members_def(cg_context),
- make_fill_with_own_dict_members_def(cg_context),
- make_dict_trace_def(cg_context),
- ])
-
- for member in dictionary.own_members:
- code_node.extend([
- make_dict_member_get_def(cg_context.make_copy(dict_member=member)),
- make_dict_member_has_def(cg_context.make_copy(dict_member=member)),
- make_dict_member_set_def(cg_context.make_copy(dict_member=member)),
+ path_manager = PathManager(dictionary)
+ class_name = name_style.class_(blink_class_name(dictionary))
+ if dictionary.inherited:
+ base_class_name = blink_class_name(dictionary.inherited)
+ else:
+ base_class_name = "bindings::DictionaryBase"
+
+ cg_context = CodeGenContext(
+ dictionary=dictionary,
+ class_name=class_name,
+ base_class_name=base_class_name)
+
+ # Filepaths
+ basename = "dictionary_example"
+ header_path = path_manager.api_path(filename=basename, ext="h")
+ source_path = path_manager.api_path(filename=basename, ext="cc")
+
+ # Root nodes
+ header_node = ListNode(tail="\n")
+ header_node.set_accumulator(CodeGenAccumulator())
+ header_node.set_renderer(MakoRenderer())
+ source_node = ListNode(tail="\n")
+ source_node.set_accumulator(CodeGenAccumulator())
+ source_node.set_renderer(MakoRenderer())
+
+ # Namespaces
+ header_blink_ns = CxxNamespaceNode(name_style.namespace("blink"))
+ 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.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)
+
+ # Constructor and destructor
+ constructor_decl = CxxFuncDeclNode(
+ name=cg_context.class_name, arg_decls=[], return_type="", default=True)
+ destructor_decl = CxxFuncDeclNode(
+ name="~${class_name}", arg_decls=[], return_type="", default=True)
+
+ # Fill with members (Blink -> V8 conversion)
+ (fill_with_members_decl,
+ fill_with_members_def) = make_fill_with_dict_members_func(cg_context)
+ (fill_with_own_members_decl, fill_with_own_members_def
+ ) = make_fill_with_own_dict_members_func(cg_context)
+
+ # Fill members (V8 -> Blink conversion)
+ (fill_members_decl,
+ fill_members_def) = make_fill_dict_members_func(cg_context)
+ (fill_members_internal_decl, fill_members_internal_def
+ ) = make_fill_dict_members_internal_func(cg_context)
+
+ # Misc. functions
+ (get_v8_member_names_decl,
+ get_v8_member_names_def) = make_get_v8_dict_member_names_func(cg_context)
+ trace_decl, trace_def = make_dict_trace_func(cg_context)
+
+ member_accessor_decls = ListNode()
+ member_accessor_defs = ListNode()
+ member_value_var_defs = ListNode()
+ member_presense_var_defs = ListNode()
+ for member in cg_context.dictionary.own_members:
+ member_context = cg_context.make_copy(dict_member=member)
+ get_decls, get_defs = make_dict_member_get(member_context)
+ 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)
+ member_accessor_decls.extend([
+ TextNode(""),
+ get_decls,
+ has_decls,
+ set_decls,
])
-
- root_node.extend([
+ member_accessor_defs.extend([
+ TextNode(""),
+ get_defs,
+ has_defs,
+ set_defs,
+ ])
+ member_value_var_defs.append(value_var_def)
+ member_presense_var_defs.append(presense_var_def)
+
+ # Header part (copyright, include directives, and forward declarations)
+ header_includes, source_includes = _make_include_headers(cg_context)
+ header_node.accumulator.add_include_headers(header_includes)
+ source_node.accumulator.add_include_headers(source_includes)
+
+ (header_class_fwd_decls, header_struct_fwd_decls, source_class_fwd_decls,
+ source_struct_fwd_decls) = _make_forward_declarations(cg_context)
+ header_node.accumulator.add_class_decls(header_class_fwd_decls)
+ header_node.accumulator.add_struct_decls(header_struct_fwd_decls)
+ source_node.accumulator.add_class_decls(source_class_fwd_decls)
+ source_node.accumulator.add_struct_decls(source_struct_fwd_decls)
+
+ header_node.extend([
+ make_copyright_header(),
+ TextNode(""),
+ enclose_with_header_guard(
+ ListNode([
+ make_header_include_directives(header_node.accumulator),
+ TextNode(""),
+ header_blink_ns,
+ ]), name_style.header_guard(header_path)),
+ ])
+ header_blink_ns.body.extend([
+ make_forward_declarations(header_node.accumulator),
+ TextNode(""),
+ ])
+ source_node.extend([
make_copyright_header(),
TextNode(""),
- enclose_with_namespace(code_node, name_style.namespace("blink")),
+ TextNode("#include \"{}\"".format(header_path)),
+ TextNode(""),
+ make_header_include_directives(source_node.accumulator),
+ TextNode(""),
+ source_blink_ns,
+ ])
+ source_blink_ns.body.extend([
+ make_forward_declarations(source_node.accumulator),
+ TextNode(""),
+ ])
+
+ # Assemble the parts.
+ header_blink_ns.body.append(class_def)
+ class_def.public_section.extend([
+ create_decl,
+ constructor_decl,
+ destructor_decl,
+ TextNode(""),
+ trace_decl,
+ TextNode(""),
+ member_accessor_decls,
+ ])
+ class_def.protected_section.extend([
+ fill_with_members_decl,
+ TextNode(""),
+ fill_members_internal_decl,
+ ])
+ class_def.private_section.extend([
+ get_v8_member_names_decl,
+ TextNode(""),
+ fill_with_own_members_decl,
+ TextNode(""),
+ fill_members_decl,
+ TextNode(""),
+ member_value_var_defs,
+ TextNode(""),
+ member_presense_var_defs,
+ ])
+ source_blink_ns.body.extend([
+ get_v8_member_names_def,
+ TextNode(""),
+ create_def,
+ TextNode(""),
+ fill_with_members_def,
+ TextNode(""),
+ fill_with_own_members_def,
+ TextNode(""),
+ fill_members_def,
+ TextNode(""),
+ fill_members_internal_def,
+ TextNode(""),
+ member_accessor_defs,
+ TextNode(""),
+ trace_def,
])
- write_code_node_to_file(root_node, filepath)
+ # Write down to the files.
+ write_code_node_to_file(header_node, path_manager.gen_path_to(header_path))
+ write_code_node_to_file(source_node, path_manager.gen_path_to(source_path))
+
+
+def generate_dictionaries(web_idl_database):
+ dictionary = web_idl_database.find("RTCQuicStreamWriteParameters")
+ 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
new file mode 100644
index 00000000000..3401ff9de18
--- /dev/null
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/enumeration.py
@@ -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.
+
+from . import name_style
+from .blink_v8_bridge import blink_class_name
+from .code_node import EmptyNode
+from .code_node import ListNode
+from .code_node import TextNode
+from .code_node_cxx import CxxClassDefNode
+from .code_node_cxx import CxxFuncDeclNode
+from .code_node_cxx import CxxFuncDefNode
+from .code_node_cxx import CxxNamespaceNode
+from .codegen_accumulator import CodeGenAccumulator
+from .codegen_context import CodeGenContext
+from .codegen_format import format_template as _format
+from .codegen_utils import component_export
+from .codegen_utils import component_export_header
+from .codegen_utils import enclose_with_header_guard
+from .codegen_utils import make_copyright_header
+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 .path_manager import PathManager
+
+
+def make_factory_method(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+
+ T = TextNode
+
+ factory_method_def = CxxFuncDefNode(
+ name="Create",
+ arg_decls=[
+ "v8::Isolate* isolate",
+ "v8::Local<v8::Value> value",
+ "ExceptionState& exception_state",
+ ],
+ return_type="${class_name}",
+ static=True)
+ factory_method_def.set_base_template_vars(cg_context.template_bindings())
+
+ factory_method_def.body.extend([
+ T("const auto& result = bindings::FindIndexInEnumStringTable("
+ "isolate, value, string_table_, \"${enumeration.identifier}\", "
+ "exception_state);"),
+ T("return result.has_value() ? "
+ "${class_name}(static_cast<Enum>(result.value())) : "
+ "${class_name}();"),
+ ])
+
+ return factory_method_def, None
+
+
+def make_constructors(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+
+ T = TextNode
+
+ class_name = cg_context.class_name
+
+ decls = ListNode([
+ CxxFuncDeclNode(
+ name=class_name,
+ arg_decls=[],
+ return_type="",
+ constexpr=True,
+ default=True),
+ CxxFuncDefNode(
+ name=class_name,
+ arg_decls=["Enum value"],
+ return_type="",
+ explicit=True,
+ constexpr=True,
+ member_initializer_list=[
+ "${base_class_name}("
+ "static_cast<enum_int_t>(value), "
+ "string_table_[static_cast<enum_int_t>(value)])"
+ ]),
+ CxxFuncDeclNode(
+ name=class_name,
+ arg_decls=["const ${class_name}&"],
+ return_type="",
+ constexpr=True,
+ default=True),
+ CxxFuncDeclNode(
+ name=class_name,
+ arg_decls=["${class_name}&&"],
+ return_type="",
+ constexpr=True,
+ default=True),
+ CxxFuncDeclNode(
+ name="~${class_name}", arg_decls=[], return_type="", default=True),
+ ])
+
+ defs = ListNode([
+ T("static_assert("
+ "std::is_trivially_copyable<${class_name}>::value, \"\");"),
+ ])
+ defs.set_base_template_vars(cg_context.template_bindings())
+
+ return decls, defs
+
+
+def make_assignment_operators(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+
+ decls = ListNode([
+ CxxFuncDeclNode(
+ name="operator=",
+ arg_decls=["const ${class_name}&"],
+ return_type="${class_name}&",
+ default=True),
+ CxxFuncDeclNode(
+ name="operator=",
+ arg_decls=["${class_name}&&"],
+ return_type="${class_name}&",
+ default=True),
+ ])
+ defs = ListNode()
+
+ # Migration adapter
+ func_decl = CxxFuncDeclNode(
+ name="operator=",
+ arg_decls=["const String&"],
+ return_type="${class_name}&")
+ func_def = CxxFuncDefNode(
+ name="operator=",
+ arg_decls=["const String& str_value"],
+ return_type="${class_name}&",
+ class_name=cg_context.class_name)
+ decls.append(func_decl)
+ defs.append(func_def)
+
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ func_def.body.append(
+ TextNode("""\
+const auto& index =
+ bindings::FindIndexInEnumStringTable(str_value, string_table_);
+CHECK(index.has_value());
+return operator=(${class_name}(static_cast<Enum>(index.value())));
+"""))
+
+ return decls, defs
+
+
+def make_equality_operators(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+
+ func1_def = CxxFuncDefNode(
+ name="operator==",
+ arg_decls=["const ${class_name}& lhs", "${class_name}::Enum rhs"],
+ return_type="bool",
+ inline=True)
+ func1_def.set_base_template_vars(cg_context.template_bindings())
+ func1_def.body.append(TextNode("return lhs.AsEnum() == rhs;"))
+
+ func2_def = CxxFuncDefNode(
+ name="operator==",
+ arg_decls=["${class_name}::Enum lhs", "const ${class_name}& rhs"],
+ return_type="bool",
+ inline=True)
+ func2_def.set_base_template_vars(cg_context.template_bindings())
+ func2_def.body.append(TextNode("return lhs == rhs.AsEnum();"))
+
+ decls = ListNode([func1_def, EmptyNode(), func2_def])
+
+ # Migration adapter
+ func3_def = CxxFuncDefNode(
+ name="operator==",
+ arg_decls=["const ${class_name}& lhs", "const String& rhs"],
+ return_type="bool",
+ inline=True)
+ func3_def.set_base_template_vars(cg_context.template_bindings())
+ func3_def.body.append(TextNode("return lhs.AsString() == rhs;"))
+
+ func4_def = CxxFuncDefNode(
+ name="operator==",
+ arg_decls=["const String& lhs", "const ${class_name}& rhs"],
+ return_type="bool",
+ inline=True)
+ func4_def.set_base_template_vars(cg_context.template_bindings())
+ func4_def.body.append(TextNode("return lhs == rhs.AsString();"))
+
+ decls.extend([EmptyNode(), func3_def, EmptyNode(), func4_def])
+
+ return decls, None
+
+
+def make_as_enum_function(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+
+ func_def = CxxFuncDefNode(
+ name="AsEnum", arg_decls=[], return_type="Enum", const=True)
+ func_def.body.append(TextNode("return static_cast<Enum>(GetEnumValue());"))
+
+ return func_def, None
+
+
+def make_nested_enum_class_def(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+
+ enum_values = [
+ TextNode(name_style.constant(value))
+ for value in cg_context.enumeration.values
+ ]
+
+ return ListNode([
+ TextNode("enum class Enum : enum_int_t {"),
+ ListNode(enum_values, separator=", "),
+ TextNode("};"),
+ ])
+
+
+def make_enum_string_table(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+
+ str_values = [
+ TextNode("\"{}\"".format(value))
+ for value in cg_context.enumeration.values
+ ]
+
+ decls = ListNode([
+ TextNode("static constexpr const char* const string_table_[] = {"),
+ ListNode(str_values, separator=", "),
+ TextNode("};"),
+ ])
+
+ defs = TextNode("const char* const ${class_name}::string_table_[];")
+ defs.set_base_template_vars(cg_context.template_bindings())
+
+ return decls, defs
+
+
+def generate_enumeration(enumeration):
+ path_manager = PathManager(enumeration)
+ assert path_manager.api_component == path_manager.impl_component
+ api_component = path_manager.api_component
+
+ # Class names
+ class_name = blink_class_name(enumeration)
+
+ cg_context = CodeGenContext(
+ enumeration=enumeration,
+ class_name=class_name,
+ base_class_name="bindings::EnumerationBase")
+
+ # Filepaths
+ header_path = path_manager.api_path(ext="h")
+ source_path = path_manager.api_path(ext="cc")
+
+ # Root nodes
+ header_node = ListNode(tail="\n")
+ header_node.set_accumulator(CodeGenAccumulator())
+ header_node.set_renderer(MakoRenderer())
+ source_node = ListNode(tail="\n")
+ source_node.set_accumulator(CodeGenAccumulator())
+ source_node.set_renderer(MakoRenderer())
+
+ # Namespaces
+ header_blink_ns = CxxNamespaceNode(name_style.namespace("blink"))
+ 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.set_base_template_vars(cg_context.template_bindings())
+
+ # Implementation parts
+ factory_decls, factory_defs = make_factory_method(cg_context)
+ ctor_decls, ctor_defs = make_constructors(cg_context)
+ assign_decls, assign_defs = make_assignment_operators(cg_context)
+ equal_decls, equal_defs = make_equality_operators(cg_context)
+ nested_enum_class_def = make_nested_enum_class_def(cg_context)
+ table_decls, table_defs = make_enum_string_table(cg_context)
+ as_enum_decl, as_enum_def = make_as_enum_function(cg_context)
+
+ # Header part (copyright, include directives, and forward declarations)
+ header_node.extend([
+ make_copyright_header(),
+ EmptyNode(),
+ enclose_with_header_guard(
+ ListNode([
+ make_header_include_directives(header_node.accumulator),
+ EmptyNode(),
+ header_blink_ns,
+ ]), name_style.header_guard(header_path)),
+ ])
+ header_blink_ns.body.extend([
+ make_forward_declarations(header_node.accumulator),
+ EmptyNode(),
+ ])
+ source_node.extend([
+ make_copyright_header(),
+ EmptyNode(),
+ TextNode("#include \"{}\"".format(header_path)),
+ EmptyNode(),
+ make_header_include_directives(source_node.accumulator),
+ EmptyNode(),
+ source_blink_ns,
+ ])
+ source_blink_ns.body.extend([
+ make_forward_declarations(source_node.accumulator),
+ EmptyNode(),
+ ])
+ header_node.accumulator.add_include_headers([
+ component_export_header(api_component),
+ "third_party/blink/renderer/bindings/core/v8/generated_code_helper.h",
+ "third_party/blink/renderer/platform/bindings/enumeration_base.h",
+ ])
+
+ # Assemble the parts.
+ header_blink_ns.body.append(class_def)
+ header_blink_ns.body.append(EmptyNode())
+
+ class_def.public_section.append(nested_enum_class_def)
+ class_def.public_section.append(EmptyNode())
+
+ class_def.public_section.append(factory_decls)
+ class_def.public_section.append(EmptyNode())
+ source_blink_ns.body.append(factory_defs)
+ source_blink_ns.body.append(EmptyNode())
+
+ class_def.private_section.append(table_decls)
+ class_def.private_section.append(EmptyNode())
+ source_blink_ns.body.append(table_defs)
+ source_blink_ns.body.append(EmptyNode())
+
+ class_def.public_section.append(ctor_decls)
+ class_def.public_section.append(EmptyNode())
+ source_blink_ns.body.append(ctor_defs)
+ source_blink_ns.body.append(EmptyNode())
+
+ class_def.public_section.append(assign_decls)
+ class_def.public_section.append(EmptyNode())
+ source_blink_ns.body.append(assign_defs)
+ source_blink_ns.body.append(EmptyNode())
+
+ class_def.public_section.append(as_enum_decl)
+ class_def.public_section.append(EmptyNode())
+ source_blink_ns.body.append(as_enum_def)
+ source_blink_ns.body.append(EmptyNode())
+
+ header_blink_ns.body.append(equal_decls)
+ header_blink_ns.body.append(EmptyNode())
+ source_blink_ns.body.append(equal_defs)
+ source_blink_ns.body.append(EmptyNode())
+
+ # Write down to the files.
+ write_code_node_to_file(header_node, path_manager.gen_path_to(header_path))
+ write_code_node_to_file(source_node, path_manager.gen_path_to(source_path))
+
+
+def generate_enumerations(web_idl_database):
+ for enumeration in web_idl_database.enumerations:
+ 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 03b2a99a629..9d2ce6944de 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,6 +3,7 @@
# found in the LICENSE file.
import itertools
+import multiprocessing
import os.path
import web_idl
@@ -12,26 +13,184 @@ from .blink_v8_bridge import blink_class_name
from .blink_v8_bridge import blink_type_info
from .blink_v8_bridge import make_v8_to_blink_value
from .blink_v8_bridge import make_v8_to_blink_value_variadic
-from .code_node import CodeNode
-from .code_node import FunctionDefinitionNode
-from .code_node import LiteralNode
+from .blink_v8_bridge import v8_bridge_class_name
+from .code_node import EmptyNode
+from .code_node import ListNode
from .code_node import SequenceNode
from .code_node import SymbolDefinitionNode
from .code_node import SymbolNode
from .code_node import SymbolScopeNode
from .code_node import TextNode
-from .code_node import UnlikelyExitNode
+from .code_node_cxx import CxxBlockNode
+from .code_node_cxx import CxxBreakableBlockNode
+from .code_node_cxx import CxxClassDefNode
+from .code_node_cxx import CxxFuncDeclNode
+from .code_node_cxx import CxxFuncDefNode
+from .code_node_cxx import CxxLikelyIfNode
+from .code_node_cxx import CxxMultiBranchesNode
+from .code_node_cxx import CxxNamespaceNode
+from .code_node_cxx import CxxUnlikelyIfNode
from .codegen_accumulator import CodeGenAccumulator
from .codegen_context import CodeGenContext
+from .codegen_expr import CodeGenExpr
from .codegen_expr import expr_from_exposure
from .codegen_expr import expr_or
from .codegen_format import format_template as _format
-from .codegen_utils import collect_include_headers
-from .codegen_utils import enclose_with_namespace
+from .codegen_utils import component_export
+from .codegen_utils import component_export_header
+from .codegen_utils import enclose_with_header_guard
from .codegen_utils import make_copyright_header
+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 .path_manager import PathManager
+
+
+def _is_none_or_str(arg):
+ return arg is None or isinstance(arg, str)
+
+
+def backward_compatible_api_func(cg_context):
+ """
+ Returns the Blink function name compatible with the old bindings generator.
+ """
+ assert isinstance(cg_context, CodeGenContext)
+
+ name = (cg_context.member_like.code_generator_info.property_implemented_as
+ or cg_context.member_like.identifier
+ or cg_context.property_.identifier)
+
+ if cg_context.attribute_get:
+ # modules/webaudio/biquad_filter_node.idl has readonly attribute "Q"
+ # and somehow it's implemented as "q" in Blink.
+ if name == "Q":
+ name = "q"
+
+ if cg_context.attribute_set:
+ tokens = name_style.raw.tokenize(name)
+ if tokens[0] in ("IDL", "css", "xml"):
+ tokens[0] = tokens[0].upper()
+ else:
+ tokens[0] = tokens[0].capitalize()
+ tokens.insert(0, "set")
+ name = "".join(tokens)
+
+ if cg_context.indexed_property_getter and not name:
+ name = "AnonymousIndexedGetter"
+ if cg_context.indexed_property_setter and not name:
+ name = "AnonymousIndexedSetter"
+ if cg_context.named_property_getter and not name:
+ name = "AnonymousNamedGetter"
+ if cg_context.named_property_setter and not name:
+ name = "AnonymousNamedSetter"
+ if cg_context.named_property_deleter and not name:
+ name = "AnonymousNamedDeleter"
+
+ return name
+
+
+def callback_function_name(cg_context,
+ overload_index=None,
+ for_cross_origin=False):
+ assert isinstance(cg_context, CodeGenContext)
+
+ def _cxx_name(name):
+ """
+ Returns a property name that the bindings generator can use in
+ generated code.
+
+ Note that Web IDL allows '-' (hyphen-minus) and '_' (low line) in
+ identifiers but C++ does not allow or recommend them. This function
+ encodes these characters.
+ """
+ # In Python3, we can use str.maketrans and str.translate.
+ #
+ # We're optimistic about name conflict. It's highly unlikely that
+ # these replacements will cause a conflict.
+ assert "Dec45" not in name
+ assert "Dec95" not in name
+ name = name.replace("-", "Dec45")
+ name = name.replace("_", "Dec95")
+ return name
+
+ if cg_context.constant:
+ property_name = cg_context.property_.identifier
+ else:
+ property_name = _cxx_name(cg_context.property_.identifier)
+
+ if cg_context.attribute_get:
+ kind = "AttributeGet"
+ elif cg_context.attribute_set:
+ kind = "AttributeSet"
+ elif cg_context.constant:
+ kind = "Constant"
+ elif cg_context.constructor_group:
+ property_name = ""
+ kind = "Constructor"
+ elif cg_context.exposed_construct:
+ if cg_context.legacy_window_alias:
+ kind = "LegacyWindowAlias"
+ else:
+ kind = "ExposedConstruct"
+ elif cg_context.operation_group:
+ kind = "Operation"
+ elif cg_context.stringifier:
+ kind = "Operation"
+
+ if for_cross_origin:
+ suffix = "CrossOrigin"
+ elif overload_index is not None:
+ suffix = "Overload{}".format(overload_index + 1)
+ else:
+ suffix = "Callback"
+
+ if cg_context.for_world == CodeGenContext.MAIN_WORLD:
+ world_suffix = "ForMainWorld"
+ elif cg_context.for_world == CodeGenContext.NON_MAIN_WORLDS:
+ world_suffix = "ForNonMainWorlds"
+ elif cg_context.for_world == CodeGenContext.ALL_WORLDS:
+ world_suffix = ""
+
+ return name_style.func(property_name, kind, suffix, world_suffix)
+
+
+def constant_name(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+ assert cg_context.constant
+
+ property_name = cg_context.property_.identifier.lower()
+
+ kind = "Constant"
+
+ return name_style.constant(kind, property_name)
+
+
+def custom_function_name(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+
+ if cg_context.named_property_getter:
+ return "NamedPropertyGetterCustom"
+ if cg_context.named_property_setter:
+ return "NamedPropertySetterCustom"
+ if cg_context.named_property_deleter:
+ return "NamedPropertyDeleterCustom"
+
+ if cg_context.attribute_get:
+ suffix = "AttributeGetterCustom"
+ elif cg_context.attribute_set:
+ suffix = "AttributeSetterCustom"
+ elif cg_context.operation_group:
+ suffix = "MethodCustom"
+ else:
+ assert False
+
+ return name_style.func(cg_context.property_.identifier, suffix)
+
+
+# ----------------------------------------------------------------------------
+# Callback functions
+# ----------------------------------------------------------------------------
def bind_blink_api_arguments(code_node, cg_context):
@@ -43,7 +202,7 @@ def bind_blink_api_arguments(code_node, cg_context):
if cg_context.attribute_set:
name = "arg1_value"
- v8_value = "${info}[0]"
+ v8_value = "${v8_property_value}"
code_node.register_code_symbol(
make_v8_to_blink_value(name, v8_value,
cg_context.attribute.idl_type))
@@ -58,8 +217,12 @@ def bind_blink_api_arguments(code_node, cg_context):
else:
v8_value = "${{info}}[{}]".format(argument.index)
code_node.register_code_symbol(
- make_v8_to_blink_value(name, v8_value, argument.idl_type,
- argument.default_value))
+ make_v8_to_blink_value(
+ name,
+ v8_value,
+ argument.idl_type,
+ argument_index=index,
+ default_value=argument.default_value))
def bind_callback_local_vars(code_node, cg_context):
@@ -73,17 +236,15 @@ def bind_callback_local_vars(code_node, cg_context):
template_vars = {}
local_vars.extend([
+ S("blink_property_name",
+ ("const AtomicString& ${blink_property_name} = "
+ "ToCoreAtomicString(${v8_property_name}.As<v8::String>());")),
S("class_like_name", ("const char* const ${class_like_name} = "
"\"${class_like.identifier}\";")),
S("current_context", ("v8::Local<v8::Context> ${current_context} = "
"${isolate}->GetCurrentContext();")),
- S("current_execution_context",
- ("ExecutionContext* ${current_execution_context} = "
- "ExecutionContext::From(${current_script_state});")),
S("current_script_state", ("ScriptState* ${current_script_state} = "
"ScriptState::From(${current_context});")),
- S("execution_context", ("ExecutionContext* ${execution_context} = "
- "ExecutionContext::From(${script_state});")),
S("isolate", "v8::Isolate* ${isolate} = ${info}.GetIsolate();"),
S("per_context_data", ("V8PerContextData* ${per_context_data} = "
"${script_state}->PerContextData();")),
@@ -101,7 +262,8 @@ def bind_callback_local_vars(code_node, cg_context):
])
is_receiver_context = (cg_context.member_like
- and not cg_context.member_like.is_static)
+ and not cg_context.member_like.is_static
+ and not cg_context.constructor)
# creation_context
pattern = "const v8::Local<v8::Context>& ${creation_context} = {_1};"
@@ -119,6 +281,24 @@ def bind_callback_local_vars(code_node, cg_context):
if is_receiver_context else "${current_script_state}")
local_vars.append(S("script_state", _format(pattern, _1=_1)))
+ # execution_context
+ node = S("execution_context", ("ExecutionContext* ${execution_context} = "
+ "ExecutionContext::From(${script_state});"))
+ node.accumulate(
+ CodeGenAccumulator.require_include_headers([
+ "third_party/blink/renderer/core/execution_context/execution_context.h"
+ ]))
+ local_vars.append(node)
+
+ # execution_context_of_document_tree
+ pattern = "ExecutionContext* ${execution_context_of_document_tree} = {_1};"
+ if is_receiver_context:
+ _1 = "bindings::ExecutionContextFromV8Wrappable(${blink_receiver})"
+ else:
+ _1 = "${execution_context}" # of the current context
+ text = _format(pattern, _1=_1)
+ local_vars.append(S("execution_context_of_document_tree", text))
+
# exception_state_context_type
pattern = (
"const ExceptionState::ContextType ${exception_state_context_type} = "
@@ -129,6 +309,16 @@ def bind_callback_local_vars(code_node, cg_context):
_1 = "ExceptionState::kSetterContext"
elif cg_context.constructor:
_1 = "ExceptionState::kConstructionContext"
+ elif cg_context.indexed_property_getter:
+ _1 = "ExceptionState::kIndexedGetterContext"
+ elif cg_context.indexed_property_setter:
+ _1 = "ExceptionState::kIndexedSetterContext"
+ elif cg_context.named_property_getter:
+ _1 = "ExceptionState::kGetterContext"
+ elif cg_context.named_property_setter:
+ _1 = "ExceptionState::kSetterContext"
+ elif cg_context.named_property_deleter:
+ _1 = "ExceptionState::kDeletionContext"
else:
_1 = "ExceptionState::kExecutionContext"
local_vars.append(
@@ -138,8 +328,9 @@ def bind_callback_local_vars(code_node, cg_context):
pattern = "ExceptionState ${exception_state}({_1});{_2}"
_1 = [
"${isolate}", "${exception_state_context_type}", "${class_like_name}",
- "${property_name}"
]
+ if cg_context.property_ and cg_context.property_.identifier:
+ _1.append("${property_name}")
_2 = ""
if cg_context.return_type and cg_context.return_type.unwrap().is_promise:
_2 = ("\n"
@@ -154,26 +345,174 @@ def bind_callback_local_vars(code_node, cg_context):
# [ImplementedAs=LocalDOMWindow] instead of [ImplementedAs=DOMWindow],
# and [CrossOrigin] properties should be implemented specifically with
# DOMWindow class. Then, we'll have less hacks.
- if "CrossOrigin" in cg_context.member_like.extended_attributes:
+ if (not cg_context.member_like or
+ "CrossOrigin" in cg_context.member_like.extended_attributes):
text = ("DOMWindow* ${blink_receiver} = "
- "${v8_class}::ToBlinkUnsafe(${v8_receiver});")
+ "${class_name}::ToWrappableUnsafe(${v8_receiver});")
else:
text = ("LocalDOMWindow* ${blink_receiver} = To<LocalDOMWindow>("
- "${v8_class}::ToBlinkUnsafe(${v8_receiver}));")
+ "${class_name}::ToWrappableUnsafe(${v8_receiver}));")
else:
pattern = ("{_1}* ${blink_receiver} = "
- "${v8_class}::ToBlinkUnsafe(${v8_receiver});")
+ "${class_name}::ToWrappableUnsafe(${v8_receiver});")
_1 = blink_class_name(cg_context.class_like)
text = _format(pattern, _1=_1)
local_vars.append(S("blink_receiver", text))
+ # v8_property_value
+ if cg_context.v8_callback_type == CodeGenContext.V8_FUNCTION_CALLBACK:
+ # In case of V8_ACCESSOR_NAME_SETTER_CALLBACK, |v8_property_value| is
+ # defined as an argument. In case of V8_FUNCTION_CALLBACK (of IDL
+ # attribute set function), |info[0]| is the value to be set.
+ local_vars.append(
+ S("v8_property_value",
+ "v8::Local<v8::Value> ${v8_property_value} = ${info}[0];"))
+
code_node.register_code_symbols(local_vars)
code_node.add_template_vars(template_vars)
-def _make_blink_api_call(cg_context, num_of_args=None):
+def _make_reflect_content_attribute_key(code_node, cg_context):
+ assert isinstance(code_node, SymbolScopeNode)
+ assert isinstance(cg_context, CodeGenContext)
+
+ name = (cg_context.attribute.extended_attributes.value_of("Reflect")
+ or cg_context.attribute.identifier.lower())
+ if cg_context.attribute_get and name in ("class", "id", "name"):
+ return None
+
+ if cg_context.class_like.identifier.startswith("SVG"):
+ namespace = "svg_names"
+ code_node.accumulate(
+ CodeGenAccumulator.require_include_headers(
+ ["third_party/blink/renderer/core/svg_names.h"]))
+ else:
+ namespace = "html_names"
+ code_node.accumulate(
+ CodeGenAccumulator.require_include_headers(
+ ["third_party/blink/renderer/core/html_names.h"]))
+ return "{}::{}".format(namespace, name_style.constant(name, "attr"))
+
+
+def _make_reflect_accessor_func_name(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+ assert cg_context.attribute_get or cg_context.attribute_set
+
+ if cg_context.attribute_get:
+ name = (cg_context.attribute.extended_attributes.value_of("Reflect")
+ or cg_context.attribute.identifier.lower())
+ if name in ("class", "id", "name"):
+ return name_style.func("get", name, "attribute")
+
+ if "URL" in cg_context.attribute.extended_attributes:
+ return "GetURLAttribute"
+
+ FAST_ACCESSORS = {
+ "boolean": ("FastHasAttribute", "SetBooleanAttribute"),
+ "long": ("GetIntegralAttribute", "SetIntegralAttribute"),
+ "unsigned long": ("GetUnsignedIntegralAttribute",
+ "SetUnsignedIntegralAttribute"),
+ }
+ idl_type = cg_context.attribute.idl_type.unwrap()
+ accessors = FAST_ACCESSORS.get(idl_type.keyword_typename)
+ if accessors:
+ return accessors[0 if cg_context.attribute_get else 1]
+
+ if (idl_type.is_interface
+ and idl_type.type_definition_object.does_implement("Element")):
+ if cg_context.attribute_get:
+ return "GetElementAttribute"
+ else:
+ return "SetElementAttribute"
+
+ if idl_type.element_type:
+ element_type = idl_type.element_type.unwrap()
+ if (element_type.is_interface and
+ element_type.type_definition_object.does_implement("Element")):
+ if cg_context.attribute_get:
+ return "GetElementArrayAttribute"
+ else:
+ return "SetElementArrayAttribute"
+
+ if cg_context.attribute_get:
+ return "FastGetAttribute"
+ else:
+ return "setAttribute"
+
+
+def _make_reflect_process_keyword_state(cg_context):
+ # https://html.spec.whatwg.org/C/#keywords-and-enumerated-attributes
+
+ assert isinstance(cg_context, CodeGenContext)
+ assert cg_context.attribute_get or cg_context.attribute_set
+
+ T = TextNode
+ F = lambda *args, **kwargs: T(_format(*args, **kwargs))
+
+ if not cg_context.attribute_get:
+ return None
+
+ ext_attrs = cg_context.attribute.extended_attributes
+ keywords = ext_attrs.values_of("ReflectOnly")
+ missing_default = ext_attrs.value_of("ReflectMissing")
+ empty_default = ext_attrs.value_of("ReflectEmpty")
+ invalid_default = ext_attrs.value_of("ReflectInvalid")
+
+ def constant(keyword):
+ if not keyword:
+ return "g_empty_atom"
+ return "keywords::{}".format(name_style.constant(keyword))
+
+ branches = CxxMultiBranchesNode()
+ branches.accumulate(
+ CodeGenAccumulator.require_include_headers(
+ ["third_party/blink/renderer/core/keywords.h"]))
+ nodes = [
+ T("// [ReflectOnly]"),
+ T("const AtomicString reflect_value(${return_value}.LowerASCII());"),
+ branches,
+ ]
+
+ if missing_default is not None:
+ branches.append(
+ cond="reflect_value.IsNull()",
+ body=F("${return_value} = {};", constant(missing_default)))
+ elif cg_context.return_type.unwrap(nullable=False).is_nullable:
+ branches.append(
+ cond="reflect_value.IsNull()",
+ body=T("// Null string to IDL null."))
+
+ if empty_default is not None:
+ branches.append(
+ cond="reflect_value.IsEmpty()",
+ body=F("${return_value} = {};", constant(empty_default)))
+
+ expr = " || ".join(
+ map(lambda keyword: "reflect_value == {}".format(constant(keyword)),
+ keywords))
+ branches.append(cond=expr, body=T("${return_value} = reflect_value;"))
+
+ if invalid_default is not None:
+ branches.append(
+ cond=True,
+ body=F("${return_value} = {};", constant(invalid_default)))
+ else:
+ branches.append(
+ cond=True, body=F("${return_value} = {};", constant("")))
+
+ return SequenceNode(nodes)
+
+
+def _make_blink_api_call(code_node,
+ cg_context,
+ num_of_args=None,
+ overriding_args=None):
+ assert isinstance(code_node, SymbolScopeNode)
assert isinstance(cg_context, CodeGenContext)
assert num_of_args is None or isinstance(num_of_args, (int, long))
+ assert (overriding_args is None
+ or (isinstance(overriding_args, (list, tuple))
+ and all(isinstance(arg, str) for arg in overriding_args)))
arguments = []
ext_attrs = cg_context.member_like.extended_attributes
@@ -187,8 +526,24 @@ def _make_blink_api_call(cg_context, num_of_args=None):
arguments.append("${script_state}")
if "ExecutionContext" in values:
arguments.append("${execution_context}")
+ if "Document" in values:
+ arguments.append(
+ "*bindings::ToDocumentFromExecutionContext(${execution_context})")
- if cg_context.attribute_get:
+ code_generator_info = cg_context.member_like.code_generator_info
+ is_partial = code_generator_info.defined_in_partial
+ if (is_partial and
+ not (cg_context.constructor or cg_context.member_like.is_static)):
+ arguments.append("*${blink_receiver}")
+
+ if "Reflect" in ext_attrs: # [Reflect]
+ key = _make_reflect_content_attribute_key(code_node, cg_context)
+ if key:
+ arguments.append(key)
+
+ if overriding_args is not None:
+ arguments.extend(overriding_args)
+ elif cg_context.attribute_get:
pass
elif cg_context.attribute_set:
arguments.append("${arg1_value}")
@@ -205,86 +560,106 @@ def _make_blink_api_call(cg_context, num_of_args=None):
if cg_context.may_throw_exception:
arguments.append("${exception_state}")
- code_generator_info = cg_context.member_like.code_generator_info
-
- func_name = (code_generator_info.property_implemented_as
- or name_style.api_func(cg_context.member_like.identifier))
- if cg_context.attribute_set:
- func_name = name_style.api_func("set", func_name)
+ func_name = backward_compatible_api_func(cg_context)
+ if cg_context.constructor:
+ func_name = "Create"
+ if "Reflect" in ext_attrs: # [Reflect]
+ func_name = _make_reflect_accessor_func_name(cg_context)
- is_partial_or_mixin = (code_generator_info.defined_in_partial
- or code_generator_info.defined_in_mixin)
- if cg_context.member_like.is_static or is_partial_or_mixin:
+ if (cg_context.constructor or cg_context.member_like.is_static
+ or is_partial):
class_like = cg_context.member_like.owner_mixin or cg_context.class_like
class_name = (code_generator_info.receiver_implemented_as
or name_style.class_(class_like.identifier))
func_designator = "{}::{}".format(class_name, func_name)
- if not cg_context.member_like.is_static:
- arguments.insert(0, "*${blink_receiver}")
else:
func_designator = _format("${blink_receiver}->{}", func_name)
return _format("{_1}({_2})", _1=func_designator, _2=", ".join(arguments))
-def bind_return_value(code_node, cg_context):
+def bind_return_value(code_node, cg_context, overriding_args=None):
assert isinstance(code_node, SymbolScopeNode)
assert isinstance(cg_context, CodeGenContext)
+ assert (overriding_args is None
+ or (isinstance(overriding_args, (list, tuple))
+ and all(isinstance(arg, str) for arg in overriding_args)))
T = TextNode
+ F = lambda *args, **kwargs: T(_format(*args, **kwargs))
def create_definition(symbol_node):
- api_calls = []
- arguments = (cg_context.function_like.arguments
- if cg_context.function_like else [])
- for index, arg in enumerate(arguments):
- if arg.is_optional and not arg.default_value:
- api_calls.append((index, _make_blink_api_call(
- cg_context, index)))
- api_calls.append((None, _make_blink_api_call(cg_context)))
+ api_calls = [] # Pairs of (num_of_args, api_call_text)
+ if overriding_args is None:
+ arguments = (cg_context.function_like.arguments
+ if cg_context.function_like else [])
+ for index, arg in enumerate(arguments):
+ if arg.is_optional and not arg.default_value:
+ api_calls.append((index,
+ _make_blink_api_call(
+ code_node, cg_context, index)))
+ api_calls.append((None, _make_blink_api_call(
+ code_node, cg_context)))
+ else:
+ api_calls.append((None,
+ _make_blink_api_call(
+ code_node,
+ cg_context,
+ overriding_args=overriding_args)))
nodes = []
- is_return_type_void = cg_context.return_type.unwrap().is_void
- if not is_return_type_void:
+ is_return_type_void = ((not cg_context.return_type
+ or cg_context.return_type.unwrap().is_void) and
+ not cg_context.does_override_idl_return_type)
+ if not (is_return_type_void
+ or cg_context.does_override_idl_return_type):
return_type = blink_type_info(cg_context.return_type).value_t
if len(api_calls) == 1:
_, api_call = api_calls[0]
if is_return_type_void:
- nodes.append(T(_format("{};", api_call)))
+ nodes.append(F("{};", api_call))
elif cg_context.is_return_by_argument:
- nodes.append(T(_format("{} ${return_value};", return_type)))
- nodes.append(T(_format("{};", api_call)))
+ nodes.append(F("{} ${return_value};", return_type))
+ nodes.append(F("{};", api_call))
+ elif "ReflectOnly" in cg_context.member_like.extended_attributes:
+ # [ReflectOnly]
+ nodes.append(F("auto ${return_value} = {};", api_call))
else:
- nodes.append(
- T(_format("const auto& ${return_value} = {};", api_call)))
+ nodes.append(F("auto&& ${return_value} = {};", api_call))
else:
- branches = SymbolScopeNode()
+ branches = SequenceNode()
for index, api_call in api_calls:
if is_return_type_void or cg_context.is_return_by_argument:
- assignment = api_call
+ assignment = "{};".format(api_call)
else:
- assignment = _format("${return_value} = {}", api_call)
+ assignment = _format("${return_value} = {};", api_call)
if index is not None:
- pattern = ("if (${info}[{index}]->IsUndefined()) {{\n"
- " {assignment};\n"
- " break;\n"
- "}}")
+ branches.append(
+ CxxLikelyIfNode(
+ cond=_format("${info}[{}]->IsUndefined()", index),
+ body=[
+ T(assignment),
+ T("break;"),
+ ]))
else:
- pattern = "{assignment};"
- text = _format(pattern, index=index, assignment=assignment)
- branches.append(T(text))
+ branches.append(T(assignment))
if not is_return_type_void:
- nodes.append(T(_format("{} ${return_value};", return_type)))
- nodes.append(T("do { // Dummy loop for use of 'break'"))
- nodes.append(branches)
- nodes.append(T("} while (false);"))
+ nodes.append(F("{} ${return_value};", return_type))
+ nodes.append(CxxBreakableBlockNode(branches))
if cg_context.may_throw_exception:
nodes.append(
- UnlikelyExitNode(
- cond=T("${exception_state}.HadException()"),
- body=SymbolScopeNode([T("return;")])))
+ CxxUnlikelyIfNode(
+ cond="${exception_state}.HadException()",
+ body=T("return;")))
+
+ if "ReflectOnly" in cg_context.member_like.extended_attributes:
+ # [ReflectOnly]
+ node = _make_reflect_process_keyword_state(cg_context)
+ if node:
+ nodes.append(EmptyNode())
+ nodes.append(node)
return SymbolDefinitionNode(symbol_node, nodes)
@@ -292,35 +667,81 @@ def bind_return_value(code_node, cg_context):
SymbolNode("return_value", definition_constructor=create_definition))
-def bind_v8_set_return_value(code_node, cg_context):
- assert isinstance(code_node, SymbolScopeNode)
+def make_bindings_trace_event(cg_context):
assert isinstance(cg_context, CodeGenContext)
- pattern = "{_1}({_2});"
- _1 = "V8SetReturnValue"
- _2 = ["${info}", "${return_value}"]
+ event_name = "{}.{}".format(cg_context.class_like.identifier,
+ cg_context.property_.identifier)
+ if cg_context.attribute_get:
+ event_name = "{}.{}".format(event_name, "get")
+ elif cg_context.attribute_set:
+ event_name = "{}.{}".format(event_name, "set")
+ elif cg_context.constructor_group:
+ event_name = "{}.{}".format(cg_context.class_like.identifier,
+ "constructor")
- return_type = cg_context.return_type.unwrap(nullable=True, typedef=True)
- if return_type.is_void:
- # Render a SymbolNode |return_value| discarding the content text, and
- # let a symbol definition be added.
- pattern = "<% str(return_value) %>"
- elif (cg_context.for_world == cg_context.MAIN_WORLD
- and return_type.is_interface):
- _1 = "V8SetReturnValueForMainWorld"
- elif return_type.is_interface:
- _2.append("${creation_context_object}")
+ return TextNode("BLINK_BINDINGS_TRACE_EVENT(\"{}\");".format(event_name))
- text = _format(pattern, _1=_1, _2=", ".join(_2))
- code_node.add_template_var("v8_set_return_value", TextNode(text))
+def make_check_argument_length(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
-_callback_common_binders = (
- bind_blink_api_arguments,
- bind_callback_local_vars,
- bind_return_value,
- bind_v8_set_return_value,
-)
+ T = TextNode
+ F = lambda *args, **kwargs: T(_format(*args, **kwargs))
+
+ if cg_context.v8_callback_type != CodeGenContext.V8_FUNCTION_CALLBACK:
+ return None
+
+ if cg_context.attribute_get:
+ num_of_required_args = 0
+ elif cg_context.attribute_set:
+ idl_type = cg_context.attribute.idl_type
+ if not (idl_type.does_include_nullable_or_dict
+ or idl_type.unwrap().is_any or
+ "TreatNonObjectAsNull" in idl_type.unwrap().extended_attributes
+ or "PutForwards" in cg_context.attribute.extended_attributes
+ or "Replaceable" in cg_context.attribute.extended_attributes):
+ # ES undefined in ${v8_property_value} will cause a TypeError
+ # anyway, so omit the check against the number of arguments.
+ return None
+ num_of_required_args = 1
+ elif cg_context.function_like:
+ num_of_required_args = (
+ cg_context.function_like.num_of_required_arguments)
+ else:
+ assert False
+
+ if num_of_required_args == 0:
+ return None
+
+ return CxxUnlikelyIfNode(
+ cond=_format("UNLIKELY(${info}.Length() < {})", num_of_required_args),
+ body=[
+ F(("${exception_state}.ThrowTypeError("
+ "ExceptionMessages::NotEnoughArguments"
+ "({}, ${info}.Length()));"), num_of_required_args),
+ T("return;"),
+ ])
+
+
+def make_check_constructor_call(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+
+ T = TextNode
+
+ return SequenceNode([
+ CxxUnlikelyIfNode(
+ cond="!${info}.IsConstructCall()",
+ body=T("${exception_state}.ThrowTypeError("
+ "ExceptionMessages::ConstructorNotCallableAsFunction("
+ "${class_like_name}));\n"
+ "return;")),
+ CxxLikelyIfNode(
+ cond=("ConstructorMode::Current(${isolate}) == "
+ "ConstructorMode::kWrapExistingObject"),
+ body=T("bindings::V8SetReturnValue(${info}, ${v8_receiver});\n"
+ "return;")),
+ ])
def make_check_receiver(cg_context):
@@ -332,24 +753,22 @@ def make_check_receiver(cg_context):
and "LenientThis" in cg_context.attribute.extended_attributes):
return SequenceNode([
T("// [LenientThis]"),
- UnlikelyExitNode(
- cond=T(
- "!${v8_class}::HasInstance(${v8_receiver}, ${isolate})"),
- body=SymbolScopeNode([T("return;")])),
+ CxxUnlikelyIfNode(
+ cond="!${class_name}::HasInstance(${isolate}, ${v8_receiver})",
+ body=T("return;")),
])
- if cg_context.return_type.unwrap().is_promise:
+ if cg_context.return_type and cg_context.return_type.unwrap().is_promise:
return SequenceNode([
T("// Promise returning function: "
"Convert a TypeError to a reject promise."),
- UnlikelyExitNode(
- cond=T(
- "!${v8_class}::HasInstance(${v8_receiver}, ${isolate})"),
- body=SymbolScopeNode([
+ CxxUnlikelyIfNode(
+ cond="!${class_name}::HasInstance(${isolate}, ${v8_receiver})",
+ body=[
T("${exception_state}.ThrowTypeError("
"\"Illegal invocation\");"),
- T("return;")
- ])),
+ T("return;"),
+ ])
])
return None
@@ -368,27 +787,47 @@ def make_check_security_of_return_value(cg_context):
web_feature = _format(
"WebFeature::{}",
name_style.constant("CrossOrigin", cg_context.class_like.identifier,
- cg_context.member_like.identifier))
- use_counter = _format(
- "UseCounter::Count(${current_execution_context}, {});", web_feature)
+ cg_context.property_.identifier))
+ use_counter = _format("UseCounter::Count(${execution_context}, {});",
+ web_feature)
cond = T("!BindingSecurity::ShouldAllowAccessTo("
"ToLocalDOMWindow(${current_context}), ${return_value}, "
"BindingSecurity::ErrorReportOption::kDoNotReport)")
- body = SymbolScopeNode([
+ body = [
T(use_counter),
- T("V8SetReturnValueNull(${info});\n"
+ T("bindings::V8SetReturnValue(${info}, nullptr);\n"
"return;"),
- ])
- return SequenceNode([
+ ]
+ node = SequenceNode([
T("// [CheckSecurity=ReturnValue]"),
- UnlikelyExitNode(cond=cond, body=body),
+ CxxUnlikelyIfNode(cond=cond, body=body),
])
+ node.accumulate(
+ CodeGenAccumulator.require_include_headers([
+ "third_party/blink/renderer/bindings/core/v8/binding_security.h",
+ "third_party/blink/renderer/core/frame/web_feature.h",
+ "third_party/blink/renderer/platform/instrumentation/use_counter.h",
+ ]))
+ return node
+
+
+def make_cooperative_scheduling_safepoint(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+
+ node = TextNode("scheduler::CooperativeSchedulingManager::Instance()"
+ "->Safepoint();")
+ node.accumulate(
+ CodeGenAccumulator.require_include_headers([
+ "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
+ ]))
+ return node
def make_log_activity(cg_context):
assert isinstance(cg_context, CodeGenContext)
- ext_attrs = cg_context.member_like.extended_attributes
+ target = cg_context.member_like or cg_context.property_
+ ext_attrs = target.extended_attributes
if "LogActivity" not in ext_attrs:
return None
target = ext_attrs.value_of("LogActivity")
@@ -414,10 +853,10 @@ def make_log_activity(cg_context):
if cg_context.attribute_get:
_1 = "LogGetter"
_4 = ""
- if cg_context.attribute_set:
+ elif cg_context.attribute_set:
_1 = "LogSetter"
- _4 = ", ${info}[0]"
- if cg_context.operation_group:
+ _4 = ", ${v8_property_value}"
+ elif cg_context.operation_group:
_1 = "LogMethod"
_4 = ", ${info}"
body = _format(pattern, _1=_1, _2=_2, _3=_3, _4=_4)
@@ -426,22 +865,13 @@ def make_log_activity(cg_context):
node = TextNode(_format(pattern, _1=cond, _2=body))
node.accumulate(
CodeGenAccumulator.require_include_headers([
- "third_party/blink/renderer/"
- "platform/bindings/v8_dom_activity_logger.h",
+ "third_party/blink/renderer/platform/bindings/v8_dom_activity_logger.h",
+ "third_party/blink/renderer/platform/bindings/v8_per_context_data.h",
]))
return node
-def _make_overloaded_function_name(function_like):
- if isinstance(function_like, web_idl.Constructor):
- return name_style.func("constructor", "overload",
- function_like.overload_index + 1)
- else:
- return name_style.func(function_like.identifier, "op", "overload",
- function_like.overload_index + 1)
-
-
-def _make_overload_dispatcher_per_arg_size(items):
+def _make_overload_dispatcher_per_arg_size(cg_context, items):
"""
https://heycam.github.io/webidl/#dfn-overload-resolution-algorithm
@@ -454,6 +884,12 @@ def _make_overload_dispatcher_per_arg_size(items):
exists a case that overload resolution will fail, i.e. a bailout that
throws a TypeError is necessary.
"""
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(items, (list, tuple))
+ assert all(
+ isinstance(item, web_idl.OverloadGroup.EffectiveOverloadItem)
+ for item in items)
+
# Variables shared with nested functions
if len(items) > 1:
arg_index = web_idl.OverloadGroup.distinguishing_argument_index(items)
@@ -496,7 +932,8 @@ def _make_overload_dispatcher_per_arg_size(items):
def make_node(pattern):
value = _format("${info}[{}]", arg_index)
- func_name = _make_overloaded_function_name(func_like)
+ func_name = callback_function_name(cg_context,
+ func_like.overload_index)
return TextNode(_format(pattern, value=value, func_name=func_name))
def dispatch_if(expr):
@@ -509,11 +946,7 @@ def _make_overload_dispatcher_per_arg_size(items):
node = make_node(pattern)
conditional = expr_from_exposure(func_like.exposure)
if not conditional.is_always_true:
- node = SymbolScopeNode([
- TextNode("if (" + conditional.to_text() + ") {"),
- node,
- TextNode("}"),
- ])
+ node = CxxUnlikelyIfNode(cond=conditional, body=node)
dispatcher_nodes.append(node)
return expr is True and conditional.is_always_true
@@ -528,8 +961,7 @@ def _make_overload_dispatcher_per_arg_size(items):
dispatch_if("{value}->IsUndefined()")
# 12.3. if V is null or undefined, ...
- func_like = find(
- lambda t, u: t.does_include_nullable_type or u.is_dictionary)
+ func_like = find(lambda t, u: t.does_include_nullable_or_dict)
if func_like:
dispatch_if("{value}->IsNullOrUndefined()")
@@ -541,27 +973,19 @@ def _make_overload_dispatcher_per_arg_size(items):
# Attempt to match from most derived to least derived.
for func_like, idl_type in sorted(
find_all_interfaces(), key=inheritance_length, reverse=True):
- cgc = CodeGenContext(
- interface=idl_type.unwrap().type_definition_object)
+ v8_bridge_name = v8_bridge_class_name(
+ idl_type.unwrap().type_definition_object)
dispatch_if(
- _format("{}::HasInstance(${isolate}, {value})", cgc.v8_class))
+ _format("{}::HasInstance(${isolate}, {value})", v8_bridge_name))
+ # V8 specific optimization: BufferSource = ArrayBufferView or ArrayBuffer
is_typedef_name = lambda t, name: t.is_typedef and t.identifier == name
- func_like_a = find(
- lambda t, u: is_typedef_name(t.unwrap(typedef=False),
- "ArrayBufferView"))
- func_like_b = find(
+ func_like = find(
lambda t, u: is_typedef_name(t.unwrap(typedef=False), "BufferSource"))
- if func_like_a or func_like_b:
- # V8 specific optimization: ArrayBufferView
- if func_like_a:
- func_like = func_like_a
- dispatch_if("{value}->IsArrayBufferView()")
- if func_like_b:
- func_like = func_like_b
- dispatch_if("{value}->IsArrayBufferView() || "
- "{value}->IsArrayBuffer() || "
- "{value}->IsSharedArrayBuffer()")
+ if func_like:
+ dispatch_if("{value}->IsArrayBufferView() || "
+ "{value}->IsArrayBuffer() || "
+ "{value}->IsSharedArrayBuffer()")
else:
# 12.5. if Type(V) is Object, V has an [[ArrayBufferData]] internal
# slot, ...
@@ -570,16 +994,24 @@ def _make_overload_dispatcher_per_arg_size(items):
dispatch_if("{value}->IsArrayBuffer() || "
"{value}->IsSharedArrayBuffer()")
- # 12.6. if Type(V) is Object, V has a [[DataView]] internal slot, ...
- func_like = find(lambda t, u: u.is_data_view)
+ # V8 specific optimization: ArrayBufferView
+ func_like = find(lambda t, u: u.is_array_buffer_view)
if func_like:
- dispatch_if("{value}->IsDataView()")
+ dispatch_if("{value}->IsArrayBufferView()")
- # 12.7. if Type(V) is Object, V has a [[TypedArrayName]] internal slot,
- # ...
- func_like = find(lambda t, u: u.is_typed_array_type)
+ # 12.6. if Type(V) is Object, V has a [[DataView]] internal slot, ...
+ func_like = find(lambda t, u: u.is_data_view)
+ if func_like:
+ dispatch_if("{value}->IsDataView()")
+
+ # 12.7. if Type(V) is Object, V has a [[TypedArrayName]] internal slot, ...
+ typed_array_types = ("Int8Array", "Int16Array", "Int32Array", "Uint8Array",
+ "Uint16Array", "Uint32Array", "Uint8ClampedArray",
+ "Float32Array", "Float64Array")
+ for typed_array_type in typed_array_types:
+ func_like = find(lambda t, u: u.keyword_typename == typed_array_type)
if func_like:
- dispatch_if("{value}->IsTypedArray()")
+ dispatch_if(_format("{value}->Is{}()", typed_array_type))
# 12.8. if IsCallable(V) is true, ...
func_like = find(lambda t, u: u.is_callback_function)
@@ -653,46 +1085,32 @@ def make_overload_dispatcher(cg_context):
for arg_size, items in items_grouped_by_arg_size:
items = list(items)
- node, can_fail = _make_overload_dispatcher_per_arg_size(items)
+ node, can_fail = _make_overload_dispatcher_per_arg_size(
+ cg_context, items)
if arg_size > 0:
- node = SymbolScopeNode([
- T("if (${info}.Length() >= " + str(arg_size) + ") {"),
- node,
- T("break;") if can_fail else None,
- T("}"),
- ])
+ node = CxxLikelyIfNode(
+ cond=_format("${info}.Length() >= {}", arg_size),
+ body=[node, T("break;") if can_fail else None])
did_use_break = did_use_break or can_fail
- terms = map(
- lambda item: expr_from_exposure(item.function_like.exposure),
- items)
- conditional = expr_or(terms)
+ conditional = expr_or(
+ map(lambda item: expr_from_exposure(item.function_like.exposure),
+ items))
if not conditional.is_always_true:
- node = SymbolScopeNode([
- T("if (" + conditional.to_text() + ") {"),
- node,
- T("}"),
- ])
+ node = CxxUnlikelyIfNode(cond=conditional, body=node)
branches.append(node)
if did_use_break:
- branches = SymbolScopeNode([
- T("do { // Dummy loop for use of 'break'"),
- branches,
- T("} while (false);"),
- ])
- # Make the entire branches an indivisible chunk so that SymbolDefinitionNode
- # will not be inserted in-between.
- branches = LiteralNode(branches)
+ branches = CxxBreakableBlockNode(branches)
if not did_use_break and arg_size == 0 and conditional.is_always_true:
return branches
return SequenceNode([
branches,
- T(""),
+ EmptyNode(),
T("${exception_state}.ThrowTypeError"
"(\"Overload resolution failed.\");\n"
"return;"),
@@ -702,7 +1120,8 @@ def make_overload_dispatcher(cg_context):
def make_report_deprecate_as(cg_context):
assert isinstance(cg_context, CodeGenContext)
- name = cg_context.member_like.extended_attributes.value_of("DeprecateAs")
+ target = cg_context.member_like or cg_context.property_
+ name = target.extended_attributes.value_of("DeprecateAs")
if not name:
return None
@@ -712,16 +1131,16 @@ def make_report_deprecate_as(cg_context):
_1 = name
node = TextNode(_format(pattern, _1=_1))
node.accumulate(
- CodeGenAccumulator.require_include_headers([
- "third_party/blink/renderer/core/frame/deprecation.h",
- ]))
+ CodeGenAccumulator.require_include_headers(
+ ["third_party/blink/renderer/core/frame/deprecation.h"]))
return node
def make_report_measure_as(cg_context):
assert isinstance(cg_context, CodeGenContext)
- ext_attrs = cg_context.member_like.extended_attributes
+ target = cg_context.member_like or cg_context.property_
+ ext_attrs = target.extended_attributes
if not ("Measure" in ext_attrs or "MeasureAs" in ext_attrs):
assert "HighEntropy" not in ext_attrs, "{}: {}".format(
cg_context.idl_location_and_name,
@@ -736,9 +1155,11 @@ def make_report_measure_as(cg_context):
suffix = "_AttributeSetter"
elif cg_context.constructor:
suffix = "_Constructor"
+ elif cg_context.exposed_construct:
+ suffix = "_ConstructorGetter"
elif cg_context.operation:
suffix = "_Method"
- name = cg_context.member_like.extended_attributes.value_of("MeasureAs")
+ name = ext_attrs.value_of("MeasureAs") or ext_attrs.value_of("Measure")
if name:
name = "k{}".format(name)
elif cg_context.constructor:
@@ -746,7 +1167,7 @@ def make_report_measure_as(cg_context):
else:
name = "kV8{}_{}{}".format(
cg_context.class_like.identifier,
- name_style.raw.upper_camel_case(cg_context.member_like.identifier),
+ name_style.raw.upper_camel_case(cg_context.property_.identifier),
suffix)
node = SequenceNode()
@@ -770,9 +1191,8 @@ def make_report_measure_as(cg_context):
_1 = name
node.append(TextNode(_format(pattern, _1=_1)))
node.accumulate(
- CodeGenAccumulator.require_include_headers([
- "third_party/blink/renderer/core/frame/dactyloscoper.h",
- ]))
+ CodeGenAccumulator.require_include_headers(
+ ["third_party/blink/renderer/core/frame/dactyloscoper.h"]))
return node
@@ -786,13 +1206,13 @@ def make_return_value_cache_return_early(cg_context):
return TextNode("""\
// [CachedAttribute]
static const V8PrivateProperty::SymbolKey kPrivatePropertyCachedAttribute;
-auto v8_private_cached_attribute =
+auto&& v8_private_cached_attribute =
V8PrivateProperty::GetSymbol(${isolate}, kPrivatePropertyCachedAttribute);
-if (!impl->""" + pred + """()) {
+if (!${blink_receiver}->""" + pred + """()) {
v8::Local<v8::Value> v8_value;
if (v8_private_cached_attribute.GetOrUndefined(${v8_receiver})
.ToLocal(&v8_value) && !v8_value->IsUndefined()) {
- V8SetReturnValue(${info}, v8_value);
+ bindings::V8SetReturnValue(${info}, v8_value);
return;
}
}""")
@@ -801,13 +1221,13 @@ if (!impl->""" + pred + """()) {
return TextNode("""\
// [SaveSameObject]
static const V8PrivateProperty::SymbolKey kPrivatePropertySaveSameObject;
-auto v8_private_save_same_object =
+auto&& v8_private_save_same_object =
V8PrivateProperty::GetSymbol(${isolate}, kPrivatePropertySaveSameObject);
{
v8::Local<v8::Value> v8_value;
if (v8_private_save_same_object.GetOrUndefined(${v8_receiver})
.ToLocal(&v8_value) && !v8_value->IsUndefined()) {
- V8SetReturnValue(${info}, v8_value);
+ bindings::V8SetReturnValue(${info}, v8_value);
return;
}
}""")
@@ -827,63 +1247,266 @@ def make_return_value_cache_update_value(cg_context):
"(${v8_receiver}, ${info}.GetReturnValue().Get());")
-def make_runtime_call_timer_scope(cg_context):
+def make_runtime_call_timer_scope(cg_context, overriding_name=None):
assert isinstance(cg_context, CodeGenContext)
+ assert _is_none_or_str(overriding_name)
+
+ target = cg_context.member_like or cg_context.property_
- pattern = "RUNTIME_CALL_TIMER_SCOPE{_1}(${isolate}, {_2});"
- _1 = "_DISABLED_BY_DEFAULT"
suffix = ""
if cg_context.attribute_get:
suffix = "_Getter"
elif cg_context.attribute_set:
suffix = "_Setter"
- counter = cg_context.member_like.extended_attributes.value_of(
- "RuntimeCallStatsCounter")
+ elif cg_context.exposed_construct:
+ suffix = "_ConstructorGetterCallback"
+
+ counter = (target and
+ target.extended_attributes.value_of("RuntimeCallStatsCounter"))
if counter:
- _2 = "k{}{}".format(counter, suffix)
+ macro_name = "RUNTIME_CALL_TIMER_SCOPE"
+ counter_name = "RuntimeCallStats::CounterId::k{}{}".format(
+ counter, suffix)
else:
- _2 = "\"Blink_{}_{}{}\"".format(
- blink_class_name(cg_context.class_like),
- cg_context.member_like.identifier, suffix)
- node = TextNode(_format(pattern, _1=_1, _2=_2))
- node.accumulate(
+ macro_name = "RUNTIME_CALL_TIMER_SCOPE_DISABLED_BY_DEFAULT"
+ counter_name = "\"Blink_{}_{}{}\"".format(
+ blink_class_name(cg_context.class_like), overriding_name
+ or target.identifier, suffix)
+
+ return TextNode(
+ _format(
+ "{macro_name}(${info}.GetIsolate(), {counter_name});",
+ macro_name=macro_name,
+ counter_name=counter_name))
+
+
+def make_steps_of_ce_reactions(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+ assert (cg_context.attribute_set or cg_context.operation
+ or cg_context.indexed_property_setter
+ or cg_context.named_property_setter
+ or cg_context.named_property_deleter)
+
+ T = TextNode
+
+ nodes = []
+
+ ext_attrs = cg_context.member_like.extended_attributes
+ if "CustomElementCallbacks" in ext_attrs or "Reflect" in ext_attrs:
+ if "CustomElementCallbacks" in ext_attrs:
+ nodes.append(T("// [CustomElementCallbacks]"))
+ elif "Reflect" in ext_attrs:
+ nodes.append(T("// [Reflect]"))
+ nodes.append(
+ T("V0CustomElementProcessingStack::CallbackDeliveryScope "
+ "v0_custom_element_scope;"))
+
+ if "CEReactions" in ext_attrs:
+ nodes.append(T("// [CEReactions]"))
+ nodes.append(T("CEReactionsScope ce_reactions_scope;"))
+
+ if not nodes:
+ return None
+
+ nodes = SequenceNode(nodes)
+ nodes.accumulate(
CodeGenAccumulator.require_include_headers([
- "third_party/blink/renderer/platform/bindings/runtime_call_stats.h",
+ "third_party/blink/renderer/core/html/custom/ce_reactions_scope.h",
+ "third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.h"
]))
- return node
+ return nodes
-def make_attribute_get_callback_def(cg_context, function_name):
+def make_steps_of_put_forwards(cg_context):
assert isinstance(cg_context, CodeGenContext)
- assert isinstance(function_name, str)
T = TextNode
- cg_context = cg_context.make_copy(attribute_get=True)
+ return SequenceNode([
+ T("// [PutForwards]"),
+ T("v8::Local<v8::Value> target;"),
+ T("if (!${v8_receiver}->Get(${current_context}, "
+ "V8AtomicString(${isolate}, ${property_name}))"
+ ".ToLocal(&target)) {\n"
+ " return;\n"
+ "}"),
+ CxxUnlikelyIfNode(
+ cond="!target->IsObject()",
+ body=[
+ T("${exception_state}.ThrowTypeError("
+ "\"The attribute value is not an object\");"),
+ T("return;"),
+ ]),
+ T("bool did_set;"),
+ T("if (!target.As<v8::Object>()->Set(${current_context}, "
+ "V8AtomicString(${isolate}, "
+ "\"${attribute.extended_attributes.value_of(\"PutForwards\")}\""
+ "), ${v8_property_value}).To(&did_set)) {{\n"
+ " return;\n"
+ "}}"),
+ ])
+
+
+def make_steps_of_replaceable(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+
+ T = TextNode
+
+ return SequenceNode([
+ T("// [Replaceable]"),
+ T("bool did_create;"),
+ T("if (!${v8_receiver}->CreateDataProperty(${current_context}, "
+ "V8AtomicString(${isolate}, ${property_name}), "
+ "${v8_property_value}).To(&did_create)) {\n"
+ " return;\n"
+ "}"),
+ ])
+
+
+def make_v8_set_return_value(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+
+ T = TextNode
+
+ if cg_context.does_override_idl_return_type:
+ return T("bindings::V8SetReturnValue(${info}, ${return_value});")
+
+ if not cg_context.return_type or cg_context.return_type.unwrap().is_void:
+ # Request a SymbolNode |return_value| to define itself without
+ # rendering any text.
+ return T("<% return_value.request_symbol_definition() %>")
+
+ operation = cg_context.operation
+ if operation and (operation.is_setter or operation.is_deleter):
+ # Blink implementation returns in a type different from the IDL type.
+ # Namely, IndexedPropertySetterResult, NamedPropertySetterResult, and
+ # NamedPropertyDeleterResult are returned ignoring the operation's
+ # return type.
+ return T("bindings::V8SetReturnValue(${info}, ${return_value});")
+
+ return_type = cg_context.return_type
+ if return_type.is_typedef:
+ if return_type.identifier in ("EventHandler",
+ "OnBeforeUnloadEventHandler",
+ "OnErrorEventHandler"):
+ return T("bindings::V8SetReturnValue(${info}, ${return_value}, "
+ "${isolate}, ${blink_receiver});")
+
+ 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});")
+
+ if return_type_body.is_string:
+ args = ["${info}", "${return_value}", "${isolate}"]
+ if return_type.is_nullable:
+ args.append("bindings::V8ReturnValue::kNullable")
+ else:
+ args.append("bindings::V8ReturnValue::kNonNullable")
+ return T("bindings::V8SetReturnValue({});".format(", ".join(args)))
+
+ if return_type_body.is_interface:
+ args = ["${info}", "${return_value}"]
+ if cg_context.for_world == cg_context.MAIN_WORLD:
+ args.append("bindings::V8ReturnValue::kMainWorld")
+ elif cg_context.constructor or cg_context.member_like.is_static:
+ args.append("${creation_context}")
+ else:
+ args.append("${blink_receiver}")
+ return T("bindings::V8SetReturnValue({});".format(", ".join(args)))
+
+ if return_type.is_frozen_array:
+ return T("bindings::V8SetReturnValue(${info}, FreezeV8Object(ToV8("
+ "${return_value}, ${creation_context_object}, ${isolate}), "
+ "${isolate}));")
+
+ if return_type.is_promise:
+ return T("bindings::V8SetReturnValue"
+ "(${info}, ${return_value}.V8Value());")
- func_def = FunctionDefinitionNode(
- name=T(function_name),
- arg_decls=[T("const v8::FunctionCallbackInfo<v8::Value>& info")],
- return_type=T("void"))
+ return T("bindings::V8SetReturnValue(${info}, "
+ "ToV8(${return_value}, ${creation_context_object}, ${isolate}));")
+
+def _make_empty_callback_def(cg_context, function_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+
+ if cg_context.v8_callback_type == CodeGenContext.V8_FUNCTION_CALLBACK:
+ arg_decls = ["const v8::FunctionCallbackInfo<v8::Value>& info"]
+ arg_names = ["info"]
+ elif (cg_context.v8_callback_type == CodeGenContext.
+ V8_ACCESSOR_NAME_GETTER_CALLBACK):
+ arg_decls = [
+ "v8::Local<v8::Name> v8_property_name",
+ "const v8::PropertyCallbackInfo<v8::Value>& info",
+ ]
+ arg_names = ["v8_property_name", "info"]
+ elif (cg_context.v8_callback_type == CodeGenContext.
+ V8_ACCESSOR_NAME_SETTER_CALLBACK):
+ arg_decls = [
+ "v8::Local<v8::Name> v8_property_name",
+ "v8::Local<v8::Value> v8_property_value",
+ "const v8::PropertyCallbackInfo<void>& info",
+ ]
+ arg_names = ["v8_property_name", "v8_property_value", "info"]
+ elif (cg_context.v8_callback_type == CodeGenContext.
+ V8_GENERIC_NAMED_PROPERTY_SETTER_CALLBACK):
+ arg_decls = [
+ "v8::Local<v8::Name> v8_property_name",
+ "v8::Local<v8::Value> v8_property_value",
+ "const v8::PropertyCallbackInfo<v8::Value>& info",
+ ]
+ arg_names = ["v8_property_name", "v8_property_value", "info"]
+
+ func_def = CxxFuncDefNode(
+ name=function_name, arg_decls=arg_decls, return_type="void")
+ func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
- body.add_template_var("info", "info")
- body.add_template_vars(cg_context.template_bindings())
- for bind in _callback_common_binders:
- bind(body, cg_context)
+ for arg_name in arg_names:
+ body.add_template_var(arg_name, arg_name)
+
+ bind_callback_local_vars(body, cg_context)
+ if cg_context.attribute or cg_context.function_like:
+ bind_blink_api_arguments(body, cg_context)
+ bind_return_value(body, cg_context)
+
+ return func_def
+
+
+def make_attribute_get_callback_def(cg_context, function_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+
+ func_def = _make_empty_callback_def(cg_context, function_name)
+ body = func_def.body
body.extend([
make_runtime_call_timer_scope(cg_context),
+ make_bindings_trace_event(cg_context),
make_report_deprecate_as(cg_context),
make_report_measure_as(cg_context),
make_log_activity(cg_context),
- T(""),
+ EmptyNode(),
+ ])
+
+ if "Getter" in cg_context.property_.extended_attributes.values_of(
+ "Custom"):
+ text = _format("${class_name}::{}(${info});",
+ custom_function_name(cg_context))
+ body.append(TextNode(text))
+ return func_def
+
+ body.extend([
make_check_receiver(cg_context),
make_return_value_cache_return_early(cg_context),
- T(""),
+ EmptyNode(),
make_check_security_of_return_value(cg_context),
- T("${v8_set_return_value}"),
+ make_v8_set_return_value(cg_context),
make_return_value_cache_update_value(cg_context),
])
@@ -894,59 +1517,263 @@ def make_attribute_set_callback_def(cg_context, function_name):
assert isinstance(cg_context, CodeGenContext)
assert isinstance(function_name, str)
- return None
+ ext_attrs = cg_context.attribute.extended_attributes
+ if cg_context.attribute.is_readonly and not any(
+ ext_attr in ext_attrs
+ for ext_attr in ("LenientSetter", "PutForwards", "Replaceable")):
+ return None
+ func_def = _make_empty_callback_def(cg_context, function_name)
+ body = func_def.body
-def make_operation_function_def(cg_context, function_name):
+ if "LenientSetter" in ext_attrs:
+ body.append(TextNode("// [LenientSetter]"))
+ return func_def
+
+ body.extend([
+ make_runtime_call_timer_scope(cg_context),
+ make_bindings_trace_event(cg_context),
+ make_report_deprecate_as(cg_context),
+ make_report_measure_as(cg_context),
+ make_log_activity(cg_context),
+ EmptyNode(),
+ ])
+
+ if "Setter" in cg_context.property_.extended_attributes.values_of(
+ "Custom"):
+ text = _format("${class_name}::{}(${v8_property_value}, ${info});",
+ custom_function_name(cg_context))
+ body.append(TextNode(text))
+ return func_def
+
+ body.extend([
+ make_check_receiver(cg_context),
+ make_check_argument_length(cg_context),
+ EmptyNode(),
+ ])
+
+ if "PutForwards" in ext_attrs:
+ body.append(make_steps_of_put_forwards(cg_context))
+ return func_def
+
+ if "Replaceable" in ext_attrs:
+ body.append(make_steps_of_replaceable(cg_context))
+ return func_def
+
+ body.extend([
+ make_steps_of_ce_reactions(cg_context),
+ EmptyNode(),
+ make_v8_set_return_value(cg_context),
+ ])
+
+ return func_def
+
+
+def make_constant_callback_def(cg_context, function_name):
assert isinstance(cg_context, CodeGenContext)
assert isinstance(function_name, str)
- T = TextNode
+ logging_nodes = SequenceNode([
+ make_report_deprecate_as(cg_context),
+ make_report_measure_as(cg_context),
+ make_log_activity(cg_context),
+ ])
+ if not logging_nodes:
+ return None
- func_def = FunctionDefinitionNode(
- name=T(function_name),
- arg_decls=[T("const v8::FunctionCallbackInfo<v8::Value>& info")],
- return_type=T("void"))
+ func_def = _make_empty_callback_def(cg_context, function_name)
+ body = func_def.body
+ v8_set_return_value = _format(
+ "bindings::V8SetReturnValue(${info}, ${class_name}::{});",
+ constant_name(cg_context))
+ body.extend([
+ make_runtime_call_timer_scope(cg_context),
+ make_bindings_trace_event(cg_context),
+ logging_nodes,
+ EmptyNode(),
+ TextNode(v8_set_return_value),
+ ])
+
+ return func_def
+
+
+def make_constant_constant_def(cg_context, constant_name):
+ # IDL constant's C++ constant definition
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(constant_name, str)
+
+ constant_type = blink_type_info(cg_context.constant.idl_type).value_t
+ return TextNode("static constexpr {type} {name} = {value};".format(
+ type=constant_type,
+ name=constant_name,
+ value=cg_context.constant.value.literal))
+
+
+def make_overload_dispatcher_function_def(cg_context, function_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+
+ func_def = _make_empty_callback_def(cg_context, function_name)
body = func_def.body
- body.add_template_var("info", "info")
- body.add_template_vars(cg_context.template_bindings())
- for bind in _callback_common_binders:
- bind(body, cg_context)
+ if cg_context.operation_group:
+ body.append(make_operation_entry(cg_context))
+ body.append(EmptyNode())
+ body.append(make_cooperative_scheduling_safepoint(cg_context))
+ body.append(EmptyNode())
- body.extend([
+ if cg_context.constructor_group:
+ body.append(make_constructor_entry(cg_context))
+ body.append(EmptyNode())
+
+ body.append(make_overload_dispatcher(cg_context))
+
+ return func_def
+
+
+def make_constructor_entry(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+
+ return SequenceNode([
make_runtime_call_timer_scope(cg_context),
+ make_bindings_trace_event(cg_context),
+ EmptyNode(),
+ make_check_constructor_call(cg_context),
+ ])
+
+
+def make_constructor_function_def(cg_context, function_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+
+ T = TextNode
+
+ func_def = _make_empty_callback_def(cg_context, function_name)
+ body = func_def.body
+
+ if len(cg_context.constructor_group) == 1:
+ body.append(make_constructor_entry(cg_context))
+ body.append(EmptyNode())
+
+ body.extend([
make_report_deprecate_as(cg_context),
make_report_measure_as(cg_context),
make_log_activity(cg_context),
- T(""),
- make_check_receiver(cg_context),
- T(""),
- T("${v8_set_return_value}"),
+ EmptyNode(),
+ make_check_argument_length(cg_context),
+ EmptyNode(),
])
+ if "HTMLConstructor" in cg_context.constructor.extended_attributes:
+ body.append(T("// [HTMLConstructor]"))
+ text = _format(
+ "V8HTMLConstructor::HtmlConstructor("
+ "${info}, *${class_name}::GetWrapperTypeInfo(), "
+ "HTMLElementType::{});",
+ name_style.constant(cg_context.class_like.identifier))
+ body.append(T(text))
+ else:
+ body.append(
+ T("v8::Local<v8::Object> v8_wrapper = "
+ "${return_value}->AssociateWithWrapper(${isolate}, "
+ "${class_name}::GetWrapperTypeInfo(), ${v8_receiver});"))
+ body.append(T("bindings::V8SetReturnValue(${info}, v8_wrapper);"))
+
return func_def
-def make_overload_dispatcher_function_def(cg_context, function_name):
+def make_constructor_callback_def(cg_context, function_name):
assert isinstance(cg_context, CodeGenContext)
assert isinstance(function_name, str)
- T = TextNode
+ constructor_group = cg_context.constructor_group
+
+ if len(constructor_group) == 1:
+ return make_constructor_function_def(
+ cg_context.make_copy(constructor=constructor_group[0]),
+ function_name)
+
+ node = SequenceNode()
+ for constructor in constructor_group:
+ cgc = cg_context.make_copy(constructor=constructor)
+ node.extend([
+ make_constructor_function_def(
+ cgc, callback_function_name(cgc, constructor.overload_index)),
+ EmptyNode(),
+ ])
+ node.append(
+ make_overload_dispatcher_function_def(cg_context, function_name))
+ return node
- func_def = FunctionDefinitionNode(
- name=T(function_name),
- arg_decls=[T("const v8::FunctionCallbackInfo<v8::Value>& info")],
- return_type=T("void"))
+def make_exposed_construct_callback_def(cg_context, function_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+
+ func_def = _make_empty_callback_def(cg_context, function_name)
body = func_def.body
- body.add_template_var("info", "info")
- body.add_template_vars(cg_context.template_bindings())
- bind_callback_local_vars(body, cg_context)
+ v8_set_return_value = _format(
+ "bindings::V8SetReturnValue"
+ "(${info}, {}::GetWrapperTypeInfo(), "
+ "bindings::V8ReturnValue::kInterfaceObject);",
+ v8_bridge_class_name(cg_context.exposed_construct))
+ body.extend([
+ make_runtime_call_timer_scope(cg_context),
+ make_bindings_trace_event(cg_context),
+ make_report_deprecate_as(cg_context),
+ make_report_measure_as(cg_context),
+ make_log_activity(cg_context),
+ EmptyNode(),
+ TextNode(v8_set_return_value),
+ ])
- body.append(make_overload_dispatcher(cg_context))
+ return func_def
+
+
+def make_operation_entry(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+
+ return SequenceNode([
+ make_runtime_call_timer_scope(cg_context),
+ make_bindings_trace_event(cg_context),
+ ])
+
+
+def make_operation_function_def(cg_context, function_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+
+ func_def = _make_empty_callback_def(cg_context, function_name)
+ body = func_def.body
+
+ if not cg_context.operation_group or len(cg_context.operation_group) == 1:
+ body.append(make_operation_entry(cg_context))
+ body.append(EmptyNode())
+
+ body.extend([
+ make_report_deprecate_as(cg_context),
+ make_report_measure_as(cg_context),
+ make_log_activity(cg_context),
+ EmptyNode(),
+ ])
+
+ if "Custom" in cg_context.property_.extended_attributes:
+ text = _format("${class_name}::{}(${info});",
+ custom_function_name(cg_context))
+ body.append(TextNode(text))
+ return func_def
+
+ body.extend([
+ make_check_receiver(cg_context),
+ make_check_argument_length(cg_context),
+ EmptyNode(),
+ make_steps_of_ce_reactions(cg_context),
+ EmptyNode(),
+ make_check_security_of_return_value(cg_context),
+ make_v8_set_return_value(cg_context),
+ ])
return func_def
@@ -955,7 +1782,10 @@ def make_operation_callback_def(cg_context, function_name):
assert isinstance(cg_context, CodeGenContext)
assert isinstance(function_name, str)
- operation_group = cg_context.constructor_group or cg_context.operation_group
+ operation_group = cg_context.operation_group
+
+ assert (not ("Custom" in operation_group.extended_attributes)
+ or len(operation_group) == 1)
if len(operation_group) == 1:
return make_operation_function_def(
@@ -963,16 +1793,938 @@ def make_operation_callback_def(cg_context, function_name):
node = SequenceNode()
for operation in operation_group:
- node.append(
+ cgc = cg_context.make_copy(operation=operation)
+ node.extend([
make_operation_function_def(
- cg_context.make_copy(operation=operation),
- _make_overloaded_function_name(operation)))
+ cgc, callback_function_name(cgc, operation.overload_index)),
+ EmptyNode(),
+ ])
node.append(
make_overload_dispatcher_function_def(cg_context, function_name))
return node
-def bind_template_installer_local_vars(code_node, cg_context):
+def make_indexed_property_getter_callback(cg_context, function_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+
+ arg_decls = [
+ "uint32_t index",
+ "const v8::PropertyCallbackInfo<v8::Value>& info",
+ ]
+ return_type = "void"
+
+ func_decl = CxxFuncDeclNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ static=True)
+
+ func_def = CxxFuncDefNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ class_name=cg_context.class_name)
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ body = func_def.body
+ body.add_template_var("index", "index")
+ body.add_template_var("info", "info")
+ bind_callback_local_vars(body, cg_context)
+ bind_return_value(body, cg_context, overriding_args=["${index}"])
+
+ body.extend([
+ make_runtime_call_timer_scope(cg_context, "IndexedPropertyGetter"),
+ EmptyNode(),
+ make_v8_set_return_value(cg_context),
+ ])
+
+ return func_decl, func_def
+
+
+def make_indexed_property_setter_callback(cg_context, function_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+
+ if cg_context.indexed_property_setter is None:
+ return None, None
+
+ arg_decls = [
+ "uint32_t index",
+ "v8::Local<v8::Value> v8_value",
+ "const v8::PropertyCallbackInfo<v8::Value>& info",
+ ]
+ return_type = "void"
+
+ func_decl = CxxFuncDeclNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ static=True)
+
+ func_def = CxxFuncDefNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ class_name=cg_context.class_name)
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ body = func_def.body
+ body.add_template_var("index", "index")
+ body.add_template_var("v8_value", "v8_value")
+ body.add_template_var("info", "info")
+ bind_callback_local_vars(body, cg_context)
+ bind_return_value(
+ body, cg_context, overriding_args=["${index}", "${blink_value}"])
+ body.register_code_symbol(
+ make_v8_to_blink_value(
+ "blink_value",
+ "${v8_value}",
+ cg_context.indexed_property_setter.arguments[1].idl_type,
+ argument_index=2))
+
+ body.extend([
+ make_runtime_call_timer_scope(cg_context, "IndexedPropertySetter"),
+ EmptyNode(),
+ make_steps_of_ce_reactions(cg_context),
+ EmptyNode(),
+ make_v8_set_return_value(cg_context),
+ ])
+
+ return func_decl, func_def
+
+
+def make_indexed_property_definer_callback(cg_context, function_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+
+ arg_decls = [
+ "uint32_t index",
+ "const v8::PropertyDescriptor& desc",
+ "const v8::PropertyCallbackInfo<v8::Value>& info",
+ ]
+ return_type = "void"
+
+ func_decl = CxxFuncDeclNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ static=True)
+
+ func_def = CxxFuncDefNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ class_name=cg_context.class_name)
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ body = func_def.body
+ body.add_template_var("index", "index")
+ body.add_template_var("desc", "desc")
+ body.add_template_var("info", "info")
+ bind_callback_local_vars(body, cg_context)
+
+ body.append(
+ TextNode("""\
+// https://heycam.github.io/webidl/#legacy-platform-object-defineownproperty
+// 3.8.3. [[DefineOwnProperty]]
+// step 1.1. If the result of calling IsDataDescriptor(Desc) is false, then
+// return false.
+if (desc.has_get() || desc.has_set()) {
+ bindings::V8SetReturnValue(${info}, nullptr);
+ if (${info}.ShouldThrowOnError()) {
+ ExceptionState exception_state(${info}.GetIsolate(),
+ ExceptionState::kIndexedSetterContext,
+ "${interface.identifier}");
+ exception_state.ThrowTypeError("Accessor properties are not allowed.");
+ }
+ return;
+}
+"""))
+
+ writable = bool(
+ cg_context.interface.indexed_and_named_properties.indexed_setter)
+ if writable:
+ body.append(
+ TextNode("""\
+// step 1.3. Invoke the indexed property setter with P and Desc.[[Value]].
+//
+// Return nothing and fall back to
+// ${class_name}::IndexedPropertySetterCallback."""))
+ else:
+ body.append(
+ TextNode("""\
+// step 1.2. If O does not implement an interface with an indexed property
+// setter, then return false.
+bindings::V8SetReturnValue(${info}, nullptr);
+if (${info}.ShouldThrowOnError()) {
+ ExceptionState exception_state(${info}.GetIsolate(),
+ ExceptionState::kIndexedSetterContext,
+ "${interface.identifier}");
+ exception_state.ThrowTypeError("Index property setter is not supported.");
+ return;
+}"""))
+
+ return func_decl, func_def
+
+
+def make_indexed_property_descriptor_callback(cg_context, function_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+
+ arg_decls = [
+ "uint32_t index",
+ "const v8::PropertyCallbackInfo<v8::Value>& info",
+ ]
+ return_type = "void"
+
+ func_decl = CxxFuncDeclNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ static=True)
+
+ func_def = CxxFuncDefNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ class_name=cg_context.class_name)
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ body = func_def.body
+ body.add_template_var("index", "index")
+ body.add_template_var("info", "info")
+ bind_callback_local_vars(body, cg_context)
+
+ pattern = """\
+// https://heycam.github.io/webidl/#LegacyPlatformObjectGetOwnProperty
+// Steps 1.1. to 1.2. are covered here: we rely on
+// IndexedPropertyGetterCallback() to call the getter function and check
+// that |index| is a valid property index, in which case it will have set
+// info.GetReturnValue() to something other than undefined.
+${class_name}::IndexedPropertyGetterCallback(${index}, ${info});
+v8::Local<v8::Value> v8_value = ${info}.GetReturnValue().Get();
+if (v8_value->IsUndefined())
+ return;
+
+// 1.2.5. Let |desc| be a newly created Property Descriptor with no fields.
+// 1.2.6. Set desc.[[Value]] to the result of converting value to an
+// ECMAScript value.
+// 1.2.7. If O implements an interface with an indexed property setter,
+// then set desc.[[Writable]] to true, otherwise set it to false.
+v8::PropertyDescriptor desc(v8_value, /*writable=*/{cxx_writable});
+// 1.2.8. Set desc.[[Enumerable]] and desc.[[Configurable]] to true.
+desc.set_enumerable(true);
+desc.set_configurable(true);
+// 1.2.9. Return |desc|.
+bindings::V8SetReturnValue(${info}, desc);"""
+ writable = bool(
+ cg_context.interface.indexed_and_named_properties.indexed_setter)
+ cxx_writable = "true" if writable else "false"
+ body.append(TextNode(_format(pattern, cxx_writable=cxx_writable)))
+
+ return func_decl, func_def
+
+
+def make_indexed_property_enumerator_callback(cg_context, function_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+
+ arg_decls = ["const v8::PropertyCallbackInfo<v8::Array>& info"]
+ return_type = "void"
+
+ func_decl = CxxFuncDeclNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ static=True)
+
+ func_def = CxxFuncDefNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ class_name=cg_context.class_name)
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ body = func_def.body
+ body.add_template_var("info", "info")
+ bind_callback_local_vars(body, cg_context)
+
+ body.append(
+ TextNode("""\
+uint32_t length = ${blink_receiver}->length();
+v8::Local<v8::Array> array =
+ bindings::EnumerateIndexedProperties(${isolate}, length);
+bindings::V8SetReturnValue(${info}, array);"""))
+
+ return func_decl, func_def
+
+
+def make_named_property_getter_callback(cg_context, function_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+
+ arg_decls = [
+ "v8::Local<v8::Name> v8_property_name",
+ "const v8::PropertyCallbackInfo<v8::Value>& info",
+ ]
+ return_type = "void"
+
+ func_decl = CxxFuncDeclNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ static=True)
+
+ func_def = CxxFuncDefNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ class_name=cg_context.class_name)
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ body = func_def.body
+ body.add_template_var("v8_property_name", "v8_property_name")
+ body.add_template_var("info", "info")
+ bind_callback_local_vars(body, cg_context)
+ bind_return_value(
+ body, cg_context, overriding_args=["${blink_property_name}"])
+
+ body.extend([
+ make_runtime_call_timer_scope(cg_context, "NamedPropertyGetter"),
+ EmptyNode(),
+ ])
+
+ if "Custom" in cg_context.named_property_getter.extended_attributes:
+ text = _format("${class_name}::{}(${blink_property_name}, ${info});",
+ custom_function_name(cg_context))
+ body.append(TextNode(text))
+ else:
+ body.append(make_v8_set_return_value(cg_context))
+
+ return func_decl, func_def
+
+
+def make_named_property_setter_callback(cg_context, function_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+
+ if cg_context.named_property_setter is None:
+ return None, None
+
+ arg_decls = [
+ "v8::Local<v8::Name> v8_property_name",
+ "v8::Local<v8::Value> v8_property_value",
+ "const v8::PropertyCallbackInfo<v8::Value>& info",
+ ]
+ return_type = "void"
+
+ func_decl = CxxFuncDeclNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ static=True)
+
+ func_def = CxxFuncDefNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ class_name=cg_context.class_name)
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ body = func_def.body
+ body.add_template_var("v8_property_name", "v8_property_name")
+ body.add_template_var("v8_property_value", "v8_property_value")
+ body.add_template_var("info", "info")
+ bind_callback_local_vars(body, cg_context)
+ bind_return_value(
+ body,
+ cg_context,
+ overriding_args=["${blink_property_name}", "${blink_value}"])
+ body.register_code_symbol(
+ make_v8_to_blink_value(
+ "blink_value",
+ "${v8_property_value}",
+ cg_context.named_property_setter.arguments[1].idl_type,
+ argument_index=2))
+
+ body.extend([
+ make_runtime_call_timer_scope(cg_context, "NamedPropertySetter"),
+ EmptyNode(),
+ ])
+
+ if "Custom" in cg_context.named_property_setter.extended_attributes:
+ text = _format(
+ "${class_name}::{}"
+ "(${blink_property_name}, ${v8_property_value}, ${info});",
+ custom_function_name(cg_context))
+ body.append(TextNode(text))
+ else:
+ body.extend([
+ make_steps_of_ce_reactions(cg_context),
+ EmptyNode(),
+ make_v8_set_return_value(cg_context),
+ ])
+
+ return func_decl, func_def
+
+
+def make_named_property_deleter_callback(cg_context, function_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+
+ if cg_context.named_property_deleter is None:
+ return None, None
+
+ arg_decls = [
+ "v8::Local<v8::Name> v8_property_name",
+ "const v8::PropertyCallbackInfo<v8::Boolean>& info",
+ ]
+ return_type = "void"
+
+ func_decl = CxxFuncDeclNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ static=True)
+
+ func_def = CxxFuncDefNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ class_name=cg_context.class_name)
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ body = func_def.body
+ body.add_template_var("v8_property_name", "v8_property_name")
+ body.add_template_var("info", "info")
+ bind_callback_local_vars(body, cg_context)
+ bind_return_value(
+ body, cg_context, overriding_args=["${blink_property_name}"])
+
+ body.extend([
+ make_runtime_call_timer_scope(cg_context),
+ EmptyNode(),
+ ])
+
+ if "Custom" in cg_context.named_property_deleter.extended_attributes:
+ text = _format("${class_name}::{}(${blink_property_name}, ${info});",
+ custom_function_name(cg_context))
+ body.append(TextNode(text))
+ else:
+ body.extend([
+ make_steps_of_ce_reactions(cg_context),
+ EmptyNode(),
+ make_v8_set_return_value(cg_context),
+ ])
+
+ return func_decl, func_def
+
+
+def make_named_property_definer_callback(cg_context, function_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+
+ arg_decls = [
+ "v8::Local<v8::Name> v8_property_name",
+ "const v8::PropertyDescriptor& desc",
+ "const v8::PropertyCallbackInfo<v8::Value>& info",
+ ]
+ return_type = "void"
+
+ func_decl = CxxFuncDeclNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ static=True)
+
+ func_def = CxxFuncDefNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ class_name=cg_context.class_name)
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ body = func_def.body
+ body.add_template_var("v8_property_name", "v8_property_name")
+ body.add_template_var("desc", "desc")
+ body.add_template_var("info", "info")
+ bind_callback_local_vars(body, cg_context)
+
+ body.append(
+ TextNode("""\
+// https://heycam.github.io/webidl/#legacy-platform-object-defineownproperty
+// 3.8.3. [[DefineOwnProperty]]
+// step 2.2.2.1. If the result of calling IsDataDescriptor(Desc) is false,
+// then return false.
+if (desc.has_get() || desc.has_set()) {
+ bindings::V8SetReturnValue(${info}, nullptr);
+ if (${info}.ShouldThrowOnError()) {
+ ExceptionState exception_state(${info}.GetIsolate(),
+ ExceptionState::kSetterContext,
+ "${interface.identifier}");
+ exception_state.ThrowTypeError("Accessor properties are not allowed.");
+ }
+ return;
+}
+"""))
+
+ writable = bool(
+ cg_context.interface.indexed_and_named_properties.named_setter)
+ if writable:
+ body.append(
+ TextNode("""\
+// step 2.2.2. Invoke the named property setter with P and Desc.[[Value]].
+//
+// Return nothing and fall back to
+// ${class_name}::NamedPropertySetterCallback."""))
+ else:
+ body.append(
+ TextNode("""\
+// step 2.2.1. If creating is false and O does not implement an interface
+// with a named property setter, then return false.
+bindings::V8SetReturnValue(${info}, nullptr);
+if (${info}.ShouldThrowOnError()) {
+ ExceptionState exception_state(${info}.GetIsolate(),
+ ExceptionState::kSetterContext,
+ "${interface.identifier}");
+ exception_state.ThrowTypeError("Named property setter is not supported.");
+ return;
+}"""))
+
+ return func_decl, func_def
+
+
+def make_named_property_descriptor_callback(cg_context, function_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+
+ arg_decls = [
+ "v8::Local<v8::Name> v8_property_name",
+ "const v8::PropertyCallbackInfo<v8::Value>& info",
+ ]
+ return_type = "void"
+
+ func_decl = CxxFuncDeclNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ static=True)
+
+ func_def = CxxFuncDefNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ class_name=cg_context.class_name)
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ body = func_def.body
+ body.add_template_var("v8_property_name", "v8_property_name")
+ body.add_template_var("info", "info")
+ bind_callback_local_vars(body, cg_context)
+
+ pattern = """\
+// https://heycam.github.io/webidl/#LegacyPlatformObjectGetOwnProperty
+// Steps 2.1. is covered here: we rely on
+// NamedPropertyGetterCallback() to call the getter function and check
+// that |v8_property_name| is a valid property name, in which case it will
+// have set info.GetReturnValue() to something other than undefined.
+${class_name}::NamedPropertyGetterCallback(${v8_property_name}, ${info});
+v8::Local<v8::Value> v8_value = ${info}.GetReturnValue().Get();
+if (v8_value->IsUndefined())
+ return;
+
+// 2.1.5. Let |desc| be a newly created Property Descriptor with no fields.
+// 2.1.6. Set desc.[[Value]] to the result of converting value to an
+// ECMAScript value.
+// 2.1.7. If O implements an interface with a named property setter, then
+// set desc.[[Writable]] to true, otherwise set it to false.
+v8::PropertyDescriptor desc(v8_value, /*writable=*/{cxx_writable});
+// 2.1.8. If O implements an interface with the
+// [LegacyUnenumerableNamedProperties] extended attribute, then set
+// desc.[[Enumerable]] to false, otherwise set it to true.
+desc.set_enumerable({cxx_enumerable});
+// 2.1.9. Set desc.[[Configurable]] to true.
+desc.set_configurable(true);
+// 1.2.9. Return |desc|.
+bindings::V8SetReturnValue(${info}, desc);"""
+ props = cg_context.interface.indexed_and_named_properties
+ writable = bool(props.named_setter)
+ cxx_writable = "true" if writable else "false"
+ enumerable = props.is_named_property_enumerable
+ cxx_enumerable = "true" if enumerable else "false"
+ body.append(
+ TextNode(
+ _format(
+ pattern,
+ cxx_writable=cxx_writable,
+ cxx_enumerable=cxx_enumerable)))
+
+ return func_decl, func_def
+
+
+def make_named_property_enumerator_callback(cg_context, function_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+
+ if not (cg_context.interface.indexed_and_named_properties.
+ is_named_property_enumerable):
+ return None, None
+
+ arg_decls = ["const v8::PropertyCallbackInfo<v8::Array>& info"]
+ return_type = "void"
+
+ func_decl = CxxFuncDeclNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ static=True)
+
+ func_def = CxxFuncDefNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ class_name=cg_context.class_name)
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ body = func_def.body
+ body.add_template_var("info", "info")
+ bind_callback_local_vars(body, cg_context)
+
+ body.append(
+ TextNode("""\
+Vector<String> blink_property_names;
+${blink_receiver}->NamedPropertyEnumerator(
+ blink_property_names, ${exception_state});
+if (${exception_state}.HadException())
+ return;
+bindings::V8SetReturnValue(
+ ${info},
+ ToV8(blink_property_names, ${creation_context_object}, ${isolate}));
+"""))
+
+ return func_decl, func_def
+
+
+def make_stringifier_callback_def(cg_context, function_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+
+ if cg_context.stringifier.attribute:
+ return make_attribute_get_callback_def(
+ cg_context.make_copy(
+ attribute=cg_context.stringifier.attribute,
+ attribute_get=True), function_name)
+ elif cg_context.stringifier.operation:
+ return make_operation_function_def(
+ cg_context.make_copy(operation=cg_context.stringifier.operation),
+ function_name)
+ assert False
+
+
+# ----------------------------------------------------------------------------
+# Callback functions of cross origin properties
+# ----------------------------------------------------------------------------
+
+
+def make_cross_origin_access_check_callback(cg_context, function_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+
+ func_def = CxxFuncDefNode(
+ name=function_name,
+ arg_decls=[
+ "v8::Local<v8::Context> accessing_context",
+ "v8::Local<v8::Object> accessed_object",
+ "v8::Local<v8::Value> unused_data",
+ ],
+ return_type="bool")
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ body = func_def.body
+ body.add_template_var("accessing_context", "accessing_context")
+ body.add_template_var("accessed_object", "accessed_object")
+ bind_callback_local_vars(body, cg_context)
+
+ if cg_context.interface.identifier == "Window":
+ blink_class = "DOMWindow"
+ else:
+ blink_class = blink_class_name(cg_context.interface)
+ body.extend([
+ TextNode(
+ _format(
+ "{blink_class}* blink_accessed_object = "
+ "${class_name}::ToWrappableUnsafe(${accessed_object});",
+ blink_class=blink_class)),
+ TextNode("return BindingSecurity::ShouldAllowAccessTo("
+ "ToLocalDOMWindow(${accessing_context}), "
+ "blink_accessed_object, "
+ "BindingSecurity::ErrorReportOption::kDoNotReport);"),
+ ])
+
+ return func_def
+
+
+def make_cross_origin_property_getter_callback(cg_context, function_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+
+ func_def = CxxFuncDefNode(
+ name=function_name,
+ arg_decls=[
+ "v8::Local<v8::Name> v8_property_name",
+ "const v8::PropertyCallbackInfo<v8::Value>& info",
+ ],
+ return_type="void")
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ body = func_def.body
+ body.add_template_var("v8_property_name", "v8_property_name")
+ body.add_template_var("info", "info")
+ bind_callback_local_vars(body, cg_context)
+
+ string_case_body = []
+ string_case_body.append(
+ TextNode("""\
+for (const auto& attribute : kCrossOriginAttributeTable) {
+ if (${blink_property_name} != attribute.name)
+ continue;
+ if (UNLIKELY(!attribute.get_value)) {
+ BindingSecurity::FailedAccessCheckFor(
+ ${info}.GetIsolate(),
+ ${class_name}::GetWrapperTypeInfo(),
+ ${info}.This());
+ return;
+ }
+ return attribute.get_value(${v8_property_name}, ${info});
+}
+for (const auto& operation : kCrossOriginOperationTable) {
+ if (${blink_property_name} != operation.name)
+ continue;
+ v8::Local<v8::Function> function;
+ if (bindings::GetCrossOriginFunction(
+ ${info}.GetIsolate(), operation.callback, operation.func_length,
+ ${class_name}::GetWrapperTypeInfo())
+ .ToLocal(&function)) {
+ bindings::V8SetReturnValue(${info}, function);
+ }
+ return;
+}
+% if interface.identifier == "Window":
+
+// Window object's document-tree child browsing context name property set
+//
+// TODO(yukishiino): Update the following hard-coded call to an appropriate
+// one.
+V8Window::NamedPropertyGetterCustom(${blink_property_name}, ${info});
+if (!${info}.GetReturnValue().Get()->IsUndefined())
+ return;
+% endif"""))
+
+ body.extend([
+ make_runtime_call_timer_scope(cg_context, "CrossOriginPropertyGetter"),
+ EmptyNode(),
+ CxxLikelyIfNode(
+ cond="${v8_property_name}->IsString()", body=string_case_body),
+ EmptyNode(),
+ TextNode("""\
+// 7.2.3.2 CrossOriginPropertyFallback ( P )
+// https://html.spec.whatwg.org/C/#crossoriginpropertyfallback-(-p-)
+if (bindings::IsSupportedInCrossOriginPropertyFallback(
+ ${info}.GetIsolate(), ${v8_property_name})) {
+ return ${info}.GetReturnValue().SetUndefined();
+}
+BindingSecurity::FailedAccessCheckFor(
+ ${info}.GetIsolate(),
+ ${class_name}::GetWrapperTypeInfo(),
+ ${info}.This());"""),
+ ])
+
+ return func_def
+
+
+def make_cross_origin_property_setter_callback(cg_context, function_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+
+ func_def = CxxFuncDefNode(
+ name=function_name,
+ arg_decls=[
+ "v8::Local<v8::Name> v8_property_name",
+ "v8::Local<v8::Value> v8_property_value",
+ "const v8::PropertyCallbackInfo<v8::Value>& info",
+ ],
+ return_type="void")
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ body = func_def.body
+ body.add_template_var("v8_property_name", "v8_property_name")
+ body.add_template_var("v8_property_value", "v8_property_value")
+ body.add_template_var("info", "info")
+ bind_callback_local_vars(body, cg_context)
+
+ string_case_body = []
+ string_case_body.append(
+ TextNode("""\
+for (const auto& attribute : kCrossOriginAttributeTable) {
+ if (${blink_property_name} == attribute.name && attribute.set_value) {
+ return attribute.set_value(
+ ${v8_property_name}, ${v8_property_value}, ${info});
+ }
+}"""))
+
+ body.extend([
+ make_runtime_call_timer_scope(cg_context, "CrossOriginPropertySetter"),
+ EmptyNode(),
+ CxxLikelyIfNode(
+ cond="${v8_property_name}->IsString()", body=string_case_body),
+ EmptyNode(),
+ TextNode("""\
+BindingSecurity::FailedAccessCheckFor(
+ ${info}.GetIsolate(),
+ ${class_name}::GetWrapperTypeInfo(),
+ ${info}.This());"""),
+ ])
+
+ return func_def
+
+
+def make_cross_origin_property_descriptor_callback(cg_context, function_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+
+ func_def = CxxFuncDefNode(
+ name=function_name,
+ arg_decls=[
+ "v8::Local<v8::Name> v8_property_name",
+ "const v8::PropertyCallbackInfo<v8::Value>& info",
+ ],
+ return_type="void")
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ body = func_def.body
+ body.add_template_var("v8_property_name", "v8_property_name")
+ body.add_template_var("info", "info")
+ bind_callback_local_vars(body, cg_context)
+
+ string_case_body = []
+ string_case_body.append(
+ TextNode("""\
+// 7.2.3.4 CrossOriginGetOwnPropertyHelper ( O, P )
+// https://html.spec.whatwg.org/C/#crossorigingetownpropertyhelper-(-o,-p-)
+for (const auto& attribute : kCrossOriginAttributeTable) {
+ if (${blink_property_name} != attribute.name)
+ continue;
+ v8::Local<v8::Value> get;
+ v8::Local<v8::Value> set;
+ if (!bindings::GetCrossOriginFunctionOrUndefined(
+ ${info}.GetIsolate(), attribute.get_callback, 0,
+ ${class_name}::GetWrapperTypeInfo())
+ .ToLocal(&get) ||
+ !bindings::GetCrossOriginFunctionOrUndefined(
+ ${info}.GetIsolate(), attribute.set_callback, 1,
+ ${class_name}::GetWrapperTypeInfo())
+ .ToLocal(&set)) {
+ return;
+ }
+ v8::PropertyDescriptor desc(get, set);
+ desc.set_enumerable(false);
+ desc.set_configurable(true);
+ return;
+}
+for (const auto& operation : kCrossOriginOperationTable) {
+ if (${blink_property_name} != operation.name)
+ continue;
+ v8::Local<v8::Function> function;
+ if (!bindings::GetCrossOriginFunction(
+ ${info}.GetIsolate(), operation.callback, operation.func_length,
+ ${class_name}::GetWrapperTypeInfo())
+ .ToLocal(&function)) {
+ return;
+ }
+ v8::PropertyDescriptor desc(function, /*writable=*/false);
+ desc.set_enumerable(false);
+ desc.set_configurable(true);
+ bindings::V8SetReturnValue(${info}, desc);
+ return;
+}
+% if interface.identifier == "Window":
+
+// Window object's document-tree child browsing context name property set
+//
+// TODO(yukishiino): Update the following hard-coded call to an appropriate
+// one.
+V8Window::NamedPropertyGetterCustom(${blink_property_name}, ${info});
+if (!${info}.GetReturnValue().Get()->IsUndefined()) {
+ v8::PropertyDescriptor desc(${info}.GetReturnValue().Get(),
+ /*writable=*/false);
+ desc.set_enumerable(false);
+ desc.set_configurable(true);
+ bindings::V8SetReturnValue(${info}, desc);
+ return;
+}
+% endif"""))
+
+ body.extend([
+ CxxLikelyIfNode(
+ cond="${v8_property_name}->IsString()", body=string_case_body),
+ EmptyNode(),
+ TextNode("""\
+// 7.2.3.2 CrossOriginPropertyFallback ( P )
+// https://html.spec.whatwg.org/C/#crossoriginpropertyfallback-(-p-)
+if (bindings::IsSupportedInCrossOriginPropertyFallback(
+ ${info}.GetIsolate(), ${v8_property_name})) {
+ v8::PropertyDescriptor desc(v8::Undefined(${info}.GetIsolate()),
+ /*writable=*/false);
+ desc.set_enumerable(false);
+ desc.set_configurable(true);
+ bindings::V8SetReturnValue(${info}, desc);
+ return;
+}
+BindingSecurity::FailedAccessCheckFor(
+ ${info}.GetIsolate(),
+ ${class_name}::GetWrapperTypeInfo(),
+ ${info}.This());"""),
+ ])
+
+ return func_def
+
+
+def make_cross_origin_property_enumerator_callback(cg_context, function_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+
+ func_def = CxxFuncDefNode(
+ name=function_name,
+ arg_decls=["const v8::PropertyCallbackInfo<v8::Array>& info"],
+ return_type="void")
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ body = func_def.body
+ body.add_template_var("info", "info")
+ bind_callback_local_vars(body, cg_context)
+
+ body.append(
+ TextNode("""\
+bindings::V8SetReturnValue(
+ ${info},
+ bindings::EnumerateCrossOriginProperties(
+ ${isolate},
+ kCrossOriginAttributeTable,
+ kCrossOriginOperationTable));"""))
+
+ return func_def
+
+
+# ----------------------------------------------------------------------------
+# Installer functions
+# ----------------------------------------------------------------------------
+
+# FN = function name
+FN_INSTALL_INTERFACE_TEMPLATE = name_style.func("InstallInterfaceTemplate")
+FN_INSTALL_UNCONDITIONAL_PROPS = name_style.func(
+ "InstallUnconditionalProperties")
+FN_INSTALL_CONTEXT_INDEPENDENT_PROPS = name_style.func(
+ "InstallContextIndependentProperties")
+FN_INSTALL_CONTEXT_DEPENDENT_PROPS = name_style.func(
+ "InstallContextDependentProperties")
+
+# TP = trampoline name
+TP_INSTALL_INTERFACE_TEMPLATE = name_style.member_var(
+ "install_interface_template_func")
+TP_INSTALL_UNCONDITIONAL_PROPS = name_style.member_var(
+ "install_unconditional_props_func")
+TP_INSTALL_CONTEXT_INDEPENDENT_PROPS = name_style.member_var(
+ "install_context_independent_props_func")
+TP_INSTALL_CONTEXT_DEPENDENT_PROPS = name_style.member_var(
+ "install_context_dependent_props_func")
+
+
+def bind_installer_local_vars(code_node, cg_context):
assert isinstance(code_node, SymbolScopeNode)
assert isinstance(cg_context, CodeGenContext)
@@ -984,17 +2736,36 @@ def bind_template_installer_local_vars(code_node, cg_context):
S("instance_template",
("v8::Local<v8::ObjectTemplate> ${instance_template} = "
"${interface_template}->InstanceTemplate();")),
+ S("interface_template",
+ ("v8::Local<v8::FunctionTemplate> ${interface_template} = "
+ "${wrapper_type_info}->DomTemplate(${isolate}, ${world});")),
+ S("is_in_secure_context",
+ ("const bool ${is_in_secure_context} = "
+ "${execution_context}->IsSecureContext();")),
+ S("isolate", "v8::Isolate* ${isolate} = ${v8_context}->GetIsolate();"),
S("prototype_template",
("v8::Local<v8::ObjectTemplate> ${prototype_template} = "
"${interface_template}->PrototypeTemplate();")),
+ S("script_state",
+ "ScriptState* ${script_state} = ScriptState::From(${v8_context});"),
S("signature",
("v8::Local<v8::Signature> ${signature} = "
"v8::Signature::New(${isolate}, ${interface_template});")),
S("wrapper_type_info",
("const WrapperTypeInfo* const ${wrapper_type_info} = "
- "${v8_class}::GetWrapperTypeInfo();")),
+ "${class_name}::GetWrapperTypeInfo();")),
])
+ # execution_context
+ node = S("execution_context", ("ExecutionContext* ${execution_context} = "
+ "ExecutionContext::From(${script_state});"))
+ node.accumulate(
+ CodeGenAccumulator.require_include_headers([
+ "third_party/blink/renderer/core/execution_context/execution_context.h"
+ ]))
+ local_vars.append(node)
+
+ # parent_interface_template
pattern = (
"v8::Local<v8::FunctionTemplate> ${parent_interface_template}{_1};")
_1 = (" = ${wrapper_type_info}->parent_class->dom_template_function"
@@ -1003,105 +2774,2093 @@ def bind_template_installer_local_vars(code_node, cg_context):
_1 = ""
local_vars.append(S("parent_interface_template", _format(pattern, _1=_1)))
- code_node.register_code_symbols(local_vars)
+ # Arguments have priority over local vars.
+ template_vars = code_node.template_vars
+ for symbol_node in local_vars:
+ if symbol_node.name not in template_vars:
+ code_node.register_code_symbol(symbol_node)
+
+
+def _make_property_entry_v8_property_attribute(property_):
+ values = []
+ if "NotEnumerable" in property_.extended_attributes:
+ values.append("v8::DontEnum")
+ if "Unforgeable" in property_.extended_attributes:
+ values.append("v8::DontDelete")
+ if not values:
+ values.append("v8::None")
+ return "static_cast<v8::PropertyAttribute>({})".format(" | ".join(values))
+
+
+def _make_property_entry_on_which_object(property_):
+ ON_INSTANCE = "V8DOMConfiguration::kOnInstance"
+ ON_PROTOTYPE = "V8DOMConfiguration::kOnPrototype"
+ ON_INTERFACE = "V8DOMConfiguration::kOnInterface"
+ if isinstance(property_, web_idl.Constant):
+ return ON_INTERFACE
+ if hasattr(property_, "is_static") and property_.is_static:
+ return ON_INTERFACE
+ if "Global" in property_.owner.extended_attributes:
+ return ON_INSTANCE
+ if "Unforgeable" in property_.extended_attributes:
+ return ON_INSTANCE
+ return ON_PROTOTYPE
+
+
+def _make_property_entry_check_receiver(property_):
+ if ("LenientThis" in property_.extended_attributes
+ or (isinstance(property_, web_idl.Attribute)
+ and property_.idl_type.unwrap().is_promise)
+ or (isinstance(property_, web_idl.OverloadGroup)
+ and property_[0].return_type.unwrap().is_promise)):
+ return "V8DOMConfiguration::kDoNotCheckHolder"
+ else:
+ return "V8DOMConfiguration::kCheckHolder"
-def make_install_interface_template_def(cg_context):
- assert isinstance(cg_context, CodeGenContext)
+def _make_property_entry_has_side_effect(property_):
+ if property_.extended_attributes.value_of("Affects") == "Nothing":
+ return "V8DOMConfiguration::kHasNoSideEffect"
+ else:
+ return "V8DOMConfiguration::kHasSideEffect"
+
+
+def _make_property_entry_world(world):
+ if world == CodeGenContext.MAIN_WORLD:
+ return "V8DOMConfiguration::kMainWorld"
+ if world == CodeGenContext.NON_MAIN_WORLDS:
+ return "V8DOMConfiguration::kNonMainWorlds"
+ if world == CodeGenContext.ALL_WORLDS:
+ return "V8DOMConfiguration::kAllWorlds"
+ assert False
+
+
+def _make_property_entry_constant_type_and_value_format(property_):
+ idl_type = property_.idl_type.unwrap()
+ if (idl_type.keyword_typename == "long long"
+ or idl_type.keyword_typename == "unsigned long long"):
+ assert False, "64-bit constants are not yet supported."
+ if idl_type.keyword_typename == "unsigned long":
+ return ("V8DOMConfiguration::kConstantTypeUnsignedLong",
+ "static_cast<int>({value})")
+ if idl_type.is_integer:
+ return ("V8DOMConfiguration::kConstantTypeLong",
+ "static_cast<int>({value})")
+ if idl_type.is_floating_point_numeric:
+ return ("V8DOMConfiguration::kConstantTypeDouble",
+ "static_cast<double>({value})")
+ assert False, "Unsupported type: {}".format(idl_type.syntactic_form)
+
+
+def _make_attribute_registration_table(table_name, attribute_entries):
+ assert isinstance(table_name, str)
+ assert isinstance(attribute_entries, (list, tuple))
+ assert all(
+ isinstance(entry, _PropEntryAttribute) for entry in attribute_entries)
T = TextNode
- func_def = FunctionDefinitionNode(
- name=T("InstallInterfaceTemplate"),
- arg_decls=[
- T("v8::Isolate* isolate"),
- T("const DOMWrapperWorld& world"),
- T("v8::Local<v8::FunctionTemplate> interface_template"),
- ],
- return_type=T("void"))
+ entry_nodes = []
+ for entry in attribute_entries:
+ pattern = ("{{"
+ "\"{property_name}\", "
+ "{attribute_get_callback}, "
+ "{attribute_set_callback}, "
+ "V8PrivateProperty::kNoCachedAccessor, "
+ "{v8_property_attribute}, "
+ "{on_which_object}, "
+ "{check_receiver}, "
+ "{has_side_effect}, "
+ "V8DOMConfiguration::kAlwaysCallGetter, "
+ "{world}"
+ "}},")
+ text = _format(
+ pattern,
+ property_name=entry.property_.identifier,
+ attribute_get_callback=entry.attr_get_callback_name,
+ attribute_set_callback=(entry.attr_set_callback_name or "nullptr"),
+ v8_property_attribute=_make_property_entry_v8_property_attribute(
+ entry.property_),
+ on_which_object=_make_property_entry_on_which_object(
+ entry.property_),
+ check_receiver=_make_property_entry_check_receiver(
+ entry.property_),
+ has_side_effect=_make_property_entry_has_side_effect(
+ entry.property_),
+ world=_make_property_entry_world(entry.world))
+ entry_nodes.append(T(text))
+
+ return ListNode([
+ T("static constexpr V8DOMConfiguration::AccessorConfiguration " +
+ table_name + "[] = {"),
+ ListNode(entry_nodes),
+ T("};"),
+ ])
- body = func_def.body
- body.add_template_var("isolate", "isolate")
- body.add_template_var("world", "world")
- body.add_template_var("interface_template", "interface_template")
- body.add_template_vars(cg_context.template_bindings())
- binders = [
- bind_template_installer_local_vars,
+def _make_constant_callback_registration_table(table_name, constant_entries):
+ assert isinstance(table_name, str)
+ assert isinstance(constant_entries, (list, tuple))
+ assert all(
+ isinstance(entry, _PropEntryConstant)
+ and isinstance(entry.const_callback_name, str)
+ for entry in constant_entries)
+
+ T = TextNode
+
+ entry_nodes = []
+ for entry in constant_entries:
+ pattern = ("{{" "\"{property_name}\", " "{constant_callback}" "}},")
+ text = _format(
+ pattern,
+ property_name=entry.property_.identifier,
+ constant_callback=entry.const_callback_name)
+ entry_nodes.append(T(text))
+
+ return ListNode([
+ T("static constexpr V8DOMConfiguration::ConstantCallbackConfiguration "
+ + table_name + "[] = {"),
+ ListNode(entry_nodes),
+ T("};"),
+ ])
+
+
+def _make_constant_value_registration_table(table_name, constant_entries):
+ assert isinstance(table_name, str)
+ assert isinstance(constant_entries, (list, tuple))
+ assert all(
+ isinstance(entry, _PropEntryConstant)
+ and entry.const_callback_name is None for entry in constant_entries)
+
+ T = TextNode
+
+ entry_nodes = []
+ for entry in constant_entries:
+ pattern = ("{{"
+ "\"{property_name}\", "
+ "{constant_type}, "
+ "{constant_value}"
+ "}},")
+ constant_type, constant_value_fmt = (
+ _make_property_entry_constant_type_and_value_format(
+ entry.property_))
+ constant_value = _format(
+ constant_value_fmt, value=entry.const_constant_name)
+ text = _format(
+ pattern,
+ property_name=entry.property_.identifier,
+ constant_type=constant_type,
+ constant_value=constant_value)
+ entry_nodes.append(T(text))
+
+ return ListNode([
+ T("static constexpr V8DOMConfiguration::ConstantConfiguration " +
+ table_name + "[] = {"),
+ ListNode(entry_nodes),
+ T("};"),
+ ])
+
+
+def _make_exposed_construct_registration_table(table_name,
+ exposed_construct_entries):
+ assert isinstance(table_name, str)
+ assert isinstance(exposed_construct_entries, (list, tuple))
+ assert all(
+ isinstance(entry, _PropEntryExposedConstruct)
+ for entry in exposed_construct_entries)
+
+ T = TextNode
+
+ entry_nodes = []
+ for entry in exposed_construct_entries:
+ pattern = ("{{"
+ "\"{property_name}\", "
+ "{exposed_construct_callback}, "
+ "nullptr, "
+ "static_cast<v8::PropertyAttribute>(v8::DontEnum), "
+ "V8DOMConfiguration::kOnInstance, "
+ "V8DOMConfiguration::kDoNotCheckHolder, "
+ "V8DOMConfiguration::kHasNoSideEffect, "
+ "V8DOMConfiguration::kAlwaysCallGetter, "
+ "{world}"
+ "}}, ")
+ text = _format(
+ pattern,
+ property_name=entry.property_.identifier,
+ exposed_construct_callback=entry.prop_callback_name,
+ world=_make_property_entry_world(entry.world))
+ entry_nodes.append(T(text))
+
+ return ListNode([
+ T("static constexpr V8DOMConfiguration::AttributeConfiguration " +
+ table_name + "[] = {"),
+ ListNode(entry_nodes),
+ T("};"),
+ ])
+
+
+def _make_operation_registration_table(table_name, operation_entries):
+ assert isinstance(table_name, str)
+ assert isinstance(operation_entries, (list, tuple))
+ assert all(
+ isinstance(entry, _PropEntryOperationGroup)
+ for entry in operation_entries)
+
+ T = TextNode
+
+ entry_nodes = []
+ for entry in operation_entries:
+ pattern = ("{{"
+ "\"{property_name}\", "
+ "{operation_callback}, "
+ "{function_length}, "
+ "{v8_property_attribute}, "
+ "{on_which_object}, "
+ "{check_receiver}, "
+ "V8DOMConfiguration::kDoNotCheckAccess, "
+ "{has_side_effect}, "
+ "{world}"
+ "}}, ")
+ text = _format(
+ pattern,
+ property_name=entry.property_.identifier,
+ operation_callback=entry.op_callback_name,
+ function_length=entry.op_func_length,
+ v8_property_attribute=_make_property_entry_v8_property_attribute(
+ entry.property_),
+ on_which_object=_make_property_entry_on_which_object(
+ entry.property_),
+ check_receiver=_make_property_entry_check_receiver(
+ entry.property_),
+ has_side_effect=_make_property_entry_has_side_effect(
+ entry.property_),
+ world=_make_property_entry_world(entry.world))
+ entry_nodes.append(T(text))
+
+ return ListNode([
+ T("static constexpr V8DOMConfiguration::MethodConfiguration " +
+ table_name + "[] = {"),
+ ListNode(entry_nodes),
+ T("};"),
+ ])
+
+
+class _PropEntryBase(object):
+ def __init__(self, is_context_dependent, exposure_conditional, world,
+ property_):
+ assert isinstance(is_context_dependent, bool)
+ assert isinstance(exposure_conditional, CodeGenExpr)
+
+ self.is_context_dependent = is_context_dependent
+ self.exposure_conditional = exposure_conditional
+ self.world = world
+ self.property_ = property_
+
+
+class _PropEntryAttribute(_PropEntryBase):
+ def __init__(self, is_context_dependent, exposure_conditional, world,
+ attribute, attr_get_callback_name, attr_set_callback_name):
+ assert isinstance(attr_get_callback_name, str)
+ assert _is_none_or_str(attr_set_callback_name)
+
+ _PropEntryBase.__init__(self, is_context_dependent,
+ exposure_conditional, world, attribute)
+ self.attr_get_callback_name = attr_get_callback_name
+ self.attr_set_callback_name = attr_set_callback_name
+
+
+class _PropEntryConstant(_PropEntryBase):
+ def __init__(self, is_context_dependent, exposure_conditional, world,
+ constant, const_callback_name, const_constant_name):
+ assert _is_none_or_str(const_callback_name)
+ assert isinstance(const_constant_name, str)
+
+ _PropEntryBase.__init__(self, is_context_dependent,
+ exposure_conditional, world, constant)
+ self.const_callback_name = const_callback_name
+ self.const_constant_name = const_constant_name
+
+
+class _PropEntryConstructorGroup(_PropEntryBase):
+ def __init__(self, is_context_dependent, exposure_conditional, world,
+ constructor_group, ctor_callback_name, ctor_func_length):
+ assert isinstance(ctor_callback_name, str)
+ assert isinstance(ctor_func_length, (int, long))
+
+ _PropEntryBase.__init__(self, is_context_dependent,
+ exposure_conditional, world, constructor_group)
+ self.ctor_callback_name = ctor_callback_name
+ self.ctor_func_length = ctor_func_length
+
+
+class _PropEntryExposedConstruct(_PropEntryBase):
+ def __init__(self, is_context_dependent, exposure_conditional, world,
+ exposed_construct, prop_callback_name):
+ assert isinstance(prop_callback_name, str)
+
+ _PropEntryBase.__init__(self, is_context_dependent,
+ exposure_conditional, world, exposed_construct)
+ self.prop_callback_name = prop_callback_name
+
+
+class _PropEntryOperationGroup(_PropEntryBase):
+ def __init__(self, is_context_dependent, exposure_conditional, world,
+ operation_group, op_callback_name, op_func_length):
+ assert isinstance(op_callback_name, str)
+ assert isinstance(op_func_length, (int, long))
+
+ _PropEntryBase.__init__(self, is_context_dependent,
+ exposure_conditional, world, operation_group)
+ self.op_callback_name = op_callback_name
+ self.op_func_length = op_func_length
+
+
+def _make_property_entries_and_callback_defs(
+ cg_context, attribute_entries, constant_entries, constructor_entries,
+ exposed_construct_entries, operation_entries):
+ """
+ Creates intermediate objects to help property installation and also makes
+ code nodes of callback functions.
+
+ Args:
+ attribute_entries:
+ constructor_entries:
+ exposed_construct_entries:
+ operation_entries:
+ Output parameters to store the intermediate objects.
+ """
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(attribute_entries, list)
+ assert isinstance(constant_entries, list)
+ assert isinstance(constructor_entries, list)
+ assert isinstance(exposed_construct_entries, list)
+ assert isinstance(operation_entries, list)
+
+ interface = cg_context.interface
+ global_names = interface.extended_attributes.values_of("Global")
+
+ callback_def_nodes = ListNode()
+
+ def iterate(members, callback):
+ for member in members:
+ is_context_dependent = member.exposure.is_context_dependent(
+ global_names)
+ exposure_conditional = expr_from_exposure(member.exposure,
+ global_names)
+
+ if "PerWorldBindings" in member.extended_attributes:
+ worlds = (CodeGenContext.MAIN_WORLD,
+ CodeGenContext.NON_MAIN_WORLDS)
+ else:
+ worlds = (CodeGenContext.ALL_WORLDS, )
+
+ for world in worlds:
+ callback(member, is_context_dependent, exposure_conditional,
+ world)
+
+ def process_attribute(attribute, is_context_dependent,
+ exposure_conditional, world):
+ cgc_attr = cg_context.make_copy(attribute=attribute, for_world=world)
+ cgc = cgc_attr.make_copy(attribute_get=True)
+ attr_get_callback_name = callback_function_name(cgc)
+ attr_get_callback_node = make_attribute_get_callback_def(
+ cgc, attr_get_callback_name)
+ cgc = cgc_attr.make_copy(attribute_set=True)
+ attr_set_callback_name = callback_function_name(cgc)
+ attr_set_callback_node = make_attribute_set_callback_def(
+ cgc, attr_set_callback_name)
+ if attr_set_callback_node is None:
+ attr_set_callback_name = None
+
+ callback_def_nodes.extend([
+ attr_get_callback_node,
+ EmptyNode(),
+ attr_set_callback_node,
+ EmptyNode(),
+ ])
+
+ attribute_entries.append(
+ _PropEntryAttribute(
+ is_context_dependent=is_context_dependent,
+ exposure_conditional=exposure_conditional,
+ world=world,
+ attribute=attribute,
+ attr_get_callback_name=attr_get_callback_name,
+ attr_set_callback_name=attr_set_callback_name))
+
+ def process_constant(constant, is_context_dependent, exposure_conditional,
+ world):
+ cgc = cg_context.make_copy(
+ constant=constant,
+ for_world=world,
+ v8_callback_type=CodeGenContext.V8_ACCESSOR_NAME_GETTER_CALLBACK)
+ const_callback_name = callback_function_name(cgc)
+ const_callback_node = make_constant_callback_def(
+ cgc, const_callback_name)
+ if const_callback_node is None:
+ const_callback_name = None
+ # IDL constant's C++ constant name
+ const_constant_name = _format("${class_name}::{}", constant_name(cgc))
+
+ callback_def_nodes.extend([
+ const_callback_node,
+ EmptyNode(),
+ ])
+
+ constant_entries.append(
+ _PropEntryConstant(
+ is_context_dependent=is_context_dependent,
+ exposure_conditional=exposure_conditional,
+ world=world,
+ constant=constant,
+ const_callback_name=const_callback_name,
+ const_constant_name=const_constant_name))
+
+ def process_constructor_group(constructor_group, is_context_dependent,
+ exposure_conditional, world):
+ cgc = cg_context.make_copy(
+ constructor_group=constructor_group, for_world=world)
+ ctor_callback_name = callback_function_name(cgc)
+ ctor_callback_node = make_constructor_callback_def(
+ cgc, ctor_callback_name)
+
+ callback_def_nodes.extend([
+ ctor_callback_node,
+ EmptyNode(),
+ ])
+
+ constructor_entries.append(
+ _PropEntryConstructorGroup(
+ is_context_dependent=is_context_dependent,
+ exposure_conditional=exposure_conditional,
+ world=world,
+ constructor_group=constructor_group,
+ ctor_callback_name=ctor_callback_name,
+ ctor_func_length=(
+ constructor_group.min_num_of_required_arguments)))
+
+ def process_exposed_construct(exposed_construct, is_context_dependent,
+ exposure_conditional, world):
+ if isinstance(exposed_construct, web_idl.LegacyWindowAlias):
+ cgc = cg_context.make_copy(
+ exposed_construct=exposed_construct.original,
+ legacy_window_alias=exposed_construct,
+ for_world=world,
+ v8_callback_type=CodeGenContext.
+ V8_ACCESSOR_NAME_GETTER_CALLBACK)
+ else:
+ cgc = cg_context.make_copy(
+ exposed_construct=exposed_construct,
+ for_world=world,
+ v8_callback_type=CodeGenContext.
+ V8_ACCESSOR_NAME_GETTER_CALLBACK)
+ prop_callback_name = callback_function_name(cgc)
+ prop_callback_node = make_exposed_construct_callback_def(
+ cgc, prop_callback_name)
+
+ callback_def_nodes.extend([
+ prop_callback_node,
+ EmptyNode(),
+ ])
+
+ exposed_construct_entries.append(
+ _PropEntryExposedConstruct(
+ is_context_dependent=is_context_dependent,
+ exposure_conditional=exposure_conditional,
+ world=world,
+ exposed_construct=exposed_construct,
+ prop_callback_name=prop_callback_name))
+
+ def process_operation_group(operation_group, is_context_dependent,
+ exposure_conditional, world):
+ cgc = cg_context.make_copy(
+ operation_group=operation_group, for_world=world)
+ op_callback_name = callback_function_name(cgc)
+ op_callback_node = make_operation_callback_def(cgc, op_callback_name)
+
+ callback_def_nodes.extend([
+ op_callback_node,
+ EmptyNode(),
+ ])
+
+ operation_entries.append(
+ _PropEntryOperationGroup(
+ is_context_dependent=is_context_dependent,
+ exposure_conditional=exposure_conditional,
+ world=world,
+ operation_group=operation_group,
+ op_callback_name=op_callback_name,
+ op_func_length=operation_group.min_num_of_required_arguments))
+
+ def process_stringifier(_, is_context_dependent, exposure_conditional,
+ world):
+ cgc = cg_context.make_copy(
+ stringifier=interface.stringifier, for_world=world)
+ op_callback_name = callback_function_name(cgc)
+ op_callback_node = make_stringifier_callback_def(cgc, op_callback_name)
+
+ callback_def_nodes.extend([
+ op_callback_node,
+ EmptyNode(),
+ ])
+
+ operation_entries.append(
+ _PropEntryOperationGroup(
+ is_context_dependent=is_context_dependent,
+ exposure_conditional=exposure_conditional,
+ world=world,
+ operation_group=cgc.property_,
+ op_callback_name=op_callback_name,
+ op_func_length=0))
+
+ iterate(interface.attributes, process_attribute)
+ iterate(interface.constants, process_constant)
+ iterate(interface.constructor_groups, process_constructor_group)
+ iterate(interface.exposed_constructs, process_exposed_construct)
+ iterate(interface.legacy_window_aliases, process_exposed_construct)
+ iterate(interface.operation_groups, process_operation_group)
+ if interface.stringifier:
+ iterate([interface.stringifier.operation], process_stringifier)
+
+ return callback_def_nodes
+
+
+def make_install_interface_template(
+ cg_context, function_name, class_name, trampoline_var_name,
+ constructor_entries, indexed_and_named_property_install_nodes,
+ cross_origin_property_install_nodes, install_unconditional_func_name,
+ install_context_independent_func_name):
+ """
+ Returns:
+ A triplet of CodeNode of:
+ - function declaration
+ - function definition
+ - trampoline function definition (from the API class to the
+ implementation class), which is supposed to be defined inline
+ """
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+ assert _is_none_or_str(class_name)
+ assert _is_none_or_str(trampoline_var_name)
+ assert isinstance(constructor_entries, (list, tuple))
+ assert all(
+ isinstance(entry, _PropEntryConstructorGroup)
+ for entry in constructor_entries)
+ assert isinstance(indexed_and_named_property_install_nodes, SequenceNode)
+ assert isinstance(cross_origin_property_install_nodes, SequenceNode)
+ assert _is_none_or_str(install_unconditional_func_name)
+ assert _is_none_or_str(install_context_independent_func_name)
+
+ T = TextNode
+
+ arg_decls = [
+ "v8::Isolate* isolate",
+ "const DOMWrapperWorld& world",
+ "v8::Local<v8::FunctionTemplate> interface_template",
]
- for bind in binders:
- bind(body, cg_context)
+ return_type = "void"
+
+ if trampoline_var_name is None:
+ trampoline_def = None
+ else:
+ trampoline_def = CxxFuncDefNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ static=True)
+ trampoline_def.body.append(
+ TextNode(
+ _format("return {}(isolate, world, interface_template);",
+ trampoline_var_name)))
+
+ func_decl = CxxFuncDeclNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ static=True)
+
+ func_def = CxxFuncDefNode(
+ name=function_name,
+ class_name=class_name,
+ arg_decls=arg_decls,
+ return_type=return_type)
+ func_def.set_base_template_vars(cg_context.template_bindings())
+
+ body = func_def.body
+ body.add_template_vars({
+ "isolate": "isolate",
+ "world": "world",
+ "interface_template": "interface_template",
+ })
+ bind_installer_local_vars(body, cg_context)
body.extend([
T("V8DOMConfiguration::InitializeDOMInterfaceTemplate("
"${isolate}, ${interface_template}, "
"${wrapper_type_info}->interface_name, ${parent_interface_template}, "
"kV8DefaultWrapperInternalFieldCount);"),
+ EmptyNode(),
])
- if cg_context.class_like.constructor_groups:
+ for entry in constructor_entries:
+ set_callback = _format("${interface_template}->SetCallHandler({});",
+ entry.ctor_callback_name)
+ set_length = _format("${interface_template}->SetLength({});",
+ entry.ctor_func_length)
+ if entry.world == CodeGenContext.MAIN_WORLD:
+ body.append(
+ CxxLikelyIfNode(
+ cond="${world}.IsMainWorld()",
+ body=[T(set_callback), T(set_length)]))
+ elif entry.world == CodeGenContext.NON_MAIN_WORLDS:
+ body.append(
+ CxxLikelyIfNode(
+ cond="!${world}.IsMainWorld()",
+ body=[T(set_callback), T(set_length)]))
+ elif entry.world == CodeGenContext.ALL_WORLDS:
+ body.extend([T(set_callback), T(set_length)])
+ else:
+ assert False
+ body.append(EmptyNode())
+
+ if cross_origin_property_install_nodes:
body.extend([
- T("${interface_template}->SetCallHandler(ConstructorCallback);"),
- T("${interface_template}->SetLength("
- "${class_like.constructor_groups[0]"
- ".min_num_of_required_arguments});"),
+ cross_origin_property_install_nodes,
+ EmptyNode(),
])
- return func_def
+ if cg_context.class_like.identifier == "Location":
+ body.append(
+ T("""\
+// https://html.spec.whatwg.org/C/#the-location-interface
+// To create a Location object, run these steps:
+// step 3. Let valueOf be location's relevant
+// Realm.[[Intrinsics]].[[%ObjProto_valueOf%]].
+// step 3. Perform ! location.[[DefineOwnProperty]]("valueOf",
+// { [[Value]]: valueOf, [[Writable]]: false, [[Enumerable]]: false,
+// [[Configurable]]: false }).
+${instance_template}->SetIntrinsicDataProperty(
+ V8AtomicString(${isolate}, "valueOf"),
+ v8::kObjProto_valueOf,
+ static_cast<v8::PropertyAttribute>(
+ int(v8::ReadOnly) | int(v8::DontEnum) | int(v8::DontDelete)));
+// step 4. Perform ! location.[[DefineOwnProperty]](@@toPrimitive,
+// { [[Value]]: undefined, [[Writable]]: false, [[Enumerable]]: false,
+// [[Configurable]]: false }).
+${instance_template}->Set(
+ v8::Symbol::GetToPrimitive(${isolate}),
+ v8::Undefined(${isolate}),
+ static_cast<v8::PropertyAttribute>(
+ int(v8::ReadOnly) | int(v8::DontEnum) | int(v8::DontDelete)));
+"""))
+
+ if indexed_and_named_property_install_nodes:
+ body.extend([
+ indexed_and_named_property_install_nodes,
+ EmptyNode(),
+ ])
+ if ("Global" in cg_context.class_like.extended_attributes
+ or cg_context.class_like.identifier == "Location"):
+ if "Global" in cg_context.class_like.extended_attributes:
+ body.append(T("// [Global]"))
+ if cg_context.class_like.identifier == "Location":
+ body.append(T("// Location exotic object"))
+ body.extend([
+ T("${instance_template}->SetImmutableProto();"),
+ T("${prototype_template}->SetImmutableProto();"),
+ EmptyNode(),
+ ])
+
+ if cg_context.class_like.identifier == "HTMLAllCollection":
+ body.extend([
+ T("// HTMLAllCollection"),
+ T("// https://html.spec.whatwg.org/C/"
+ "#the-htmlallcollection-interface"),
+ T("${instance_template}->SetCallAsFunctionHandler"
+ "(${class_name}::LegacyCallCustom);"),
+ T("${instance_template}->MarkAsUndetectable();"),
+ EmptyNode(),
+ ])
+
+ func_call_pattern = ("{}(${isolate}, ${world}, ${instance_template}, "
+ "${prototype_template}, ${interface_template});")
+ if install_unconditional_func_name:
+ func_call = _format(func_call_pattern, install_unconditional_func_name)
+ body.append(T(func_call))
+ if install_context_independent_func_name:
+ func_call = _format(func_call_pattern,
+ install_context_independent_func_name)
+ body.append(T(func_call))
-def generate_interfaces(web_idl_database, output_dirs):
- filename = "v8_example_interface.cc"
- filepath = os.path.join(output_dirs['core'], filename)
+ return func_decl, func_def, trampoline_def
- interface = web_idl_database.find("TestNamespace")
- cg_context = CodeGenContext(interface=interface)
+def make_install_properties(cg_context, function_name, class_name,
+ trampoline_var_name, is_context_dependent,
+ attribute_entries, constant_entries,
+ exposed_construct_entries, operation_entries):
+ """
+ Returns:
+ A triplet of CodeNode of:
+ - function declaration
+ - function definition
+ - trampoline function definition (from the API class to the
+ implementation class), which is supposed to be defined inline
+ """
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+ assert _is_none_or_str(class_name)
+ 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)
+ assert isinstance(constant_entries, (list, tuple))
+ assert all(
+ isinstance(entry, _PropEntryConstant) for entry in constant_entries)
+ assert isinstance(exposed_construct_entries, (list, tuple))
+ assert all(
+ isinstance(entry, _PropEntryExposedConstruct)
+ for entry in exposed_construct_entries)
+ assert isinstance(operation_entries, (list, tuple))
+ assert all(
+ isinstance(entry, _PropEntryOperationGroup)
+ for entry in operation_entries)
+
+ if not (attribute_entries or constant_entries or exposed_construct_entries
+ or operation_entries):
+ return None, None, None
+
+ if is_context_dependent:
+ arg_decls = [
+ "v8::Local<v8::Context> context",
+ "const DOMWrapperWorld& world",
+ "v8::Local<v8::Object> instance_object",
+ "v8::Local<v8::Object> prototype_object",
+ "v8::Local<v8::Function> interface_object",
+ ]
+ else:
+ 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",
+ ]
+ return_type = "void"
+
+ if trampoline_var_name is None:
+ trampoline_def = None
+ else:
+ trampoline_def = CxxFuncDefNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ static=True)
+ if is_context_dependent:
+ args = [
+ "context",
+ "world",
+ "instance_object",
+ "prototype_object",
+ "interface_object",
+ ]
+ else:
+ args = [
+ "isolate",
+ "world",
+ "instance_template",
+ "prototype_template",
+ "interface_template",
+ ]
+ text = _format(
+ "return {func}({args});",
+ func=trampoline_var_name,
+ args=", ".join(args))
+ trampoline_def.body.append(TextNode(text))
+
+ func_decl = CxxFuncDeclNode(
+ name=function_name,
+ arg_decls=arg_decls,
+ return_type=return_type,
+ static=True)
+
+ func_def = CxxFuncDefNode(
+ name=function_name,
+ class_name=class_name,
+ arg_decls=arg_decls,
+ return_type=return_type)
+ func_def.set_base_template_vars(cg_context.template_bindings())
- root_node = SymbolScopeNode(separator_last="\n")
- root_node.set_accumulator(CodeGenAccumulator())
- root_node.set_renderer(MakoRenderer())
+ body = func_def.body
+ if is_context_dependent:
+ body.add_template_vars({
+ "v8_context": "context", # 'context' is reserved by Mako.
+ "world": "world",
+ "instance_object": "instance_object",
+ "prototype_object": "prototype_object",
+ "interface_object": "interface_object",
+ })
+ else:
+ body.add_template_vars({
+ "isolate": "isolate",
+ "world": "world",
+ "instance_template": "instance_template",
+ "prototype_template": "prototype_template",
+ "interface_template": "interface_template",
+ })
+ bind_installer_local_vars(body, cg_context)
+
+ def group_by_condition(entries):
+ 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:
+ conditional_to_entries.setdefault(entry.exposure_conditional,
+ []).append(entry)
+ return unconditional_entries, conditional_to_entries
+
+ def install_properties(table_name, target_entries, make_table_func,
+ installer_call_text):
+ unconditional_entries, conditional_to_entries = group_by_condition(
+ target_entries)
+ if unconditional_entries:
+ body.append(
+ CxxBlockNode([
+ make_table_func(table_name, unconditional_entries),
+ TextNode(installer_call_text),
+ ]))
+ body.append(EmptyNode())
+ for conditional, entries in conditional_to_entries.items():
+ body.append(
+ CxxUnlikelyIfNode(
+ cond=conditional,
+ body=[
+ make_table_func(table_name, entries),
+ TextNode(installer_call_text),
+ ]))
+ body.append(EmptyNode())
+
+ table_name = "kAttributeTable"
+ if is_context_dependent:
+ installer_call_text = (
+ "V8DOMConfiguration::InstallAccessors(${isolate}, ${world}, "
+ "${instance_object}, ${prototype_object}, ${interface_object}, "
+ "${signature}, kAttributeTable, base::size(kAttributeTable));")
+ else:
+ installer_call_text = (
+ "V8DOMConfiguration::InstallAccessors(${isolate}, ${world}, "
+ "${instance_template}, ${prototype_template}, "
+ "${interface_template}, ${signature}, "
+ "kAttributeTable, base::size(kAttributeTable));")
+ install_properties(table_name, attribute_entries,
+ _make_attribute_registration_table, installer_call_text)
+
+ table_name = "kConstantCallbackTable"
+ if is_context_dependent:
+ installer_call_text = (
+ "V8DOMConfiguration::InstallConstants(${isolate}, "
+ "${interface_object}, ${prototype_object}, "
+ "kConstantCallbackTable, base::size(kConstantCallbackTable));")
+ else:
+ installer_call_text = (
+ "V8DOMConfiguration::InstallConstants(${isolate}, "
+ "${interface_template}, ${prototype_template}, "
+ "kConstantCallbackTable, base::size(kConstantCallbackTable));")
+ constant_callback_entries = filter(lambda entry: entry.const_callback_name,
+ constant_entries)
+ install_properties(table_name, constant_callback_entries,
+ _make_constant_callback_registration_table,
+ installer_call_text)
+
+ table_name = "kConstantValueTable"
+ if is_context_dependent:
+ installer_call_text = (
+ "V8DOMConfiguration::InstallConstants(${isolate}, "
+ "${interface_object}, ${prototype_object}, "
+ "kConstantValueTable, base::size(kConstantValueTable));")
+ else:
+ installer_call_text = (
+ "V8DOMConfiguration::InstallConstants(${isolate}, "
+ "${interface_template}, ${prototype_template}, "
+ "kConstantValueTable, base::size(kConstantValueTable));")
+ constant_value_entries = filter(
+ lambda entry: not entry.const_callback_name, constant_entries)
+ install_properties(table_name, constant_value_entries,
+ _make_constant_value_registration_table,
+ installer_call_text)
+
+ table_name = "kExposedConstructTable"
+ if is_context_dependent:
+ installer_call_text = (
+ "V8DOMConfiguration::InstallAttributes(${isolate}, ${world}, "
+ "${instance_object}, ${prototype_object}, "
+ "kExposedConstructTable, base::size(kExposedConstructTable));")
+ else:
+ installer_call_text = (
+ "V8DOMConfiguration::InstallAttributes(${isolate}, ${world}, "
+ "${instance_template}, ${prototype_template}, "
+ "kExposedConstructTable, base::size(kExposedConstructTable));")
+ install_properties(table_name, exposed_construct_entries,
+ _make_exposed_construct_registration_table,
+ installer_call_text)
+
+ table_name = "kOperationTable"
+ if is_context_dependent:
+ installer_call_text = (
+ "V8DOMConfiguration::InstallMethods(${isolate}, ${world}, "
+ "${instance_object}, ${prototype_object}, ${interface_object}, "
+ "${signature}, kOperationTable, base::size(kOperationTable));")
+ else:
+ installer_call_text = (
+ "V8DOMConfiguration::InstallMethods(${isolate}, ${world}, "
+ "${instance_template}, ${prototype_template}, "
+ "${interface_template}, ${signature}, "
+ "kOperationTable, base::size(kOperationTable));")
+ install_properties(table_name, operation_entries,
+ _make_operation_registration_table, installer_call_text)
- root_node.accumulator.add_include_headers(
- collect_include_headers(interface))
+ return func_decl, func_def, trampoline_def
- code_node = SequenceNode()
- for attribute in interface.attributes:
- func_name = name_style.func(attribute.identifier,
- "AttributeGetCallback")
- code_node.append(
- make_attribute_get_callback_def(
- cg_context.make_copy(attribute=attribute), func_name))
- func_name = name_style.func(attribute.identifier,
- "AttributeSetCallback")
- code_node.append(
- make_attribute_set_callback_def(
- cg_context.make_copy(attribute=attribute), func_name))
-
- for constructor_group in interface.constructor_groups:
- func_name = name_style.func("ConstructorCallback")
- code_node.append(
- make_operation_callback_def(
- cg_context.make_copy(constructor_group=constructor_group),
- func_name))
+def make_indexed_and_named_property_callbacks_and_install_nodes(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+ func_decls = ListNode()
+ func_defs = ListNode()
+ install_nodes = SequenceNode()
+
+ interface = cg_context.interface
+ if not (interface and interface.indexed_and_named_properties):
+ return func_decls, func_defs, install_nodes
+ props = interface.indexed_and_named_properties
+
+ def add_callback(func_decl, func_def):
+ func_decls.append(func_decl)
+ if func_def:
+ func_defs.append(func_def)
+ func_defs.append(EmptyNode())
+
+ def most_derived_interface(*interfaces):
+ key = lambda interface: len(interface.inclusive_inherited_interfaces)
+ return sorted(filter(None, interfaces), key=key)[-1]
+
+ cg_context = cg_context.make_copy(
+ v8_callback_type=CodeGenContext.V8_OTHER_CALLBACK)
+
+ if props.own_indexed_getter or props.own_indexed_setter:
+ add_callback(*make_indexed_property_getter_callback(
+ cg_context.make_copy(indexed_property_getter=props.indexed_getter),
+ "IndexedPropertyGetterCallback"))
+ add_callback(*make_indexed_property_setter_callback(
+ cg_context.make_copy(indexed_property_setter=props.indexed_setter),
+ "IndexedPropertySetterCallback"))
+ add_callback(*make_indexed_property_definer_callback(
+ cg_context, "IndexedPropertyDefinerCallback"))
+ add_callback(*make_indexed_property_descriptor_callback(
+ cg_context, "IndexedPropertyDescriptorCallback"))
+ add_callback(*make_indexed_property_enumerator_callback(
+ cg_context, "IndexedPropertyEnumeratorCallback"))
+
+ if props.has_indexed_properties:
+ impl_bridge = v8_bridge_class_name(
+ most_derived_interface(
+ props.indexed_getter.owner,
+ props.indexed_setter and props.indexed_setter.owner,
+ ))
+ flags = []
+ if (props.indexed_getter.extended_attributes.value_of("Affects") ==
+ "Nothing"):
+ flags.append("v8::PropertyHandlerFlags::kHasNoSideEffect")
+ else:
+ flags.append("v8::PropertyHandlerFlags::kNone")
+ property_handler_flags = flags[0]
+ pattern = """\
+// Indexed properties
+${instance_template}->SetHandler(
+ v8::IndexedPropertyHandlerConfiguration(
+ {impl_bridge}::IndexedPropertyGetterCallback,
+% if interface.indexed_and_named_properties.indexed_setter:
+ {impl_bridge}::IndexedPropertySetterCallback,
+% else:
+ nullptr, // setter
+% endif
+ {impl_bridge}::IndexedPropertyDescriptorCallback,
+ nullptr, // deleter
+ {impl_bridge}::IndexedPropertyEnumeratorCallback,
+ {impl_bridge}::IndexedPropertyDefinerCallback,
+ v8::Local<v8::Value>(),
+ {property_handler_flags}));"""
+ install_nodes.append(
+ TextNode(
+ _format(
+ pattern,
+ impl_bridge=impl_bridge,
+ property_handler_flags=property_handler_flags)))
+
+ if (props.own_named_getter or props.own_named_setter
+ or props.own_named_deleter):
+ add_callback(*make_named_property_getter_callback(
+ cg_context.make_copy(named_property_getter=props.named_getter),
+ "NamedPropertyGetterCallback"))
+ add_callback(*make_named_property_setter_callback(
+ cg_context.make_copy(named_property_setter=props.named_setter),
+ "NamedPropertySetterCallback"))
+ add_callback(*make_named_property_deleter_callback(
+ cg_context.make_copy(named_property_deleter=props.named_deleter),
+ "NamedPropertyDeleterCallback"))
+ add_callback(*make_named_property_definer_callback(
+ cg_context, "NamedPropertyDefinerCallback"))
+ add_callback(*make_named_property_descriptor_callback(
+ cg_context, "NamedPropertyDescriptorCallback"))
+ add_callback(*make_named_property_enumerator_callback(
+ cg_context, "NamedPropertyEnumeratorCallback"))
+
+ if props.has_named_properties:
+ impl_bridge = v8_bridge_class_name(
+ most_derived_interface(
+ props.named_getter.owner,
+ props.named_setter and props.named_setter.owner,
+ props.named_deleter and props.named_deleter.owner,
+ ))
+ flags = ["v8::PropertyHandlerFlags::kOnlyInterceptStrings"]
+ if "OverrideBuiltins" not in interface.extended_attributes:
+ flags.append("v8::PropertyHandlerFlags::kNonMasking")
+ if (props.named_getter.extended_attributes.value_of("Affects") ==
+ "Nothing"):
+ flags.append("v8::PropertyHandlerFlags::kHasNoSideEffect")
+ property_handler_flags = (
+ "static_cast<v8::PropertyHandlerFlags>({})".format(" | ".join(
+ map(lambda flag: "int({})".format(flag), flags))))
+ pattern = """\
+// Named properties
+${instance_template}->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(
+ {impl_bridge}::NamedPropertyGetterCallback,
+% if interface.indexed_and_named_properties.named_setter:
+ {impl_bridge}::NamedPropertySetterCallback,
+% else:
+ nullptr, // setter
+% endif
+ {impl_bridge}::NamedPropertyDescriptorCallback,
+% if interface.indexed_and_named_properties.named_deleter:
+ {impl_bridge}::NamedPropertyDeleterCallback,
+% else:
+ nullptr, // deleter
+% endif
+% if interface.indexed_and_named_properties.is_named_property_enumerable:
+ {impl_bridge}::NamedPropertyEnumeratorCallback,
+% else:
+ nullptr, // enumerator
+% endif
+ {impl_bridge}::NamedPropertyDefinerCallback,
+ v8::Local<v8::Value>(),
+ {property_handler_flags}));"""
+ install_nodes.append(
+ TextNode(
+ _format(
+ pattern,
+ impl_bridge=impl_bridge,
+ property_handler_flags=property_handler_flags)))
+
+ return func_decls, func_defs, install_nodes
+
+
+def make_cross_origin_property_callbacks_and_install_nodes(
+ cg_context, attribute_entries, operation_entries):
+ assert isinstance(cg_context, CodeGenContext)
+
+ callback_defs = []
+ install_nodes = SequenceNode()
+
+ CROSS_ORIGIN_INTERFACES = ("Window", "Location")
+ if cg_context.interface.identifier not in CROSS_ORIGIN_INTERFACES:
+ return callback_defs, install_nodes
+
+ entry_nodes = []
+ for entry in attribute_entries:
+ attribute = entry.property_
+ if "CrossOrigin" not in attribute.extended_attributes:
+ continue
+ assert entry.world == CodeGenContext.ALL_WORLDS
+ values = attribute.extended_attributes.values_of("CrossOrigin")
+ get_func = "nullptr"
+ set_func = "nullptr"
+ get_value = "nullptr"
+ set_value = "nullptr"
+ if not values or "Getter" in values:
+ get_func = entry.attr_get_callback_name
+ cgc = cg_context.make_copy(
+ attribute=attribute,
+ attribute_get=True,
+ v8_callback_type=(
+ CodeGenContext.V8_ACCESSOR_NAME_GETTER_CALLBACK))
+ get_value = callback_function_name(cgc, for_cross_origin=True)
+ func_def = make_attribute_get_callback_def(cgc, get_value)
+ callback_defs.extend([func_def, EmptyNode()])
+ if (not values or "Setter" in values) and entry.attr_set_callback_name:
+ set_func = entry.attr_set_callback_name
+ cgc = cg_context.make_copy(
+ attribute=attribute,
+ attribute_set=True,
+ v8_callback_type=(
+ CodeGenContext.V8_GENERIC_NAMED_PROPERTY_SETTER_CALLBACK))
+ set_value = callback_function_name(cgc, for_cross_origin=True)
+ func_def = make_attribute_set_callback_def(cgc, set_value)
+ callback_defs.extend([func_def, EmptyNode()])
+ pattern = ("{{\"{property_name}\", "
+ "{get_func}, {set_func}, {get_value}, {set_value}}},")
+ entry_nodes.append(
+ TextNode(
+ _format(
+ pattern,
+ property_name=attribute.identifier,
+ get_func=get_func,
+ set_func=set_func,
+ get_value=get_value,
+ set_value=set_value)))
+ callback_defs.append(
+ ListNode([
+ TextNode("constexpr bindings::CrossOriginAttributeTableEntry "
+ "kCrossOriginAttributeTable[] = {"),
+ ListNode(entry_nodes),
+ TextNode("};"),
+ EmptyNode(),
+ ]))
+
+ entry_nodes = []
+ for entry in operation_entries:
+ operation_group = entry.property_
+ if "CrossOrigin" not in operation_group.extended_attributes:
+ continue
+ assert entry.world == CodeGenContext.ALL_WORLDS
+ entry_nodes.append(
+ TextNode(
+ _format(
+ "{{\"{property_name}\", {op_callback}, {op_func_length}}},",
+ property_name=operation_group.identifier,
+ op_callback=entry.op_callback_name,
+ op_func_length=entry.op_func_length)))
+ callback_defs.append(
+ ListNode([
+ TextNode("constexpr bindings::CrossOriginOperationTableEntry "
+ "kCrossOriginOperationTable[] = {"),
+ ListNode(entry_nodes),
+ TextNode("};"),
+ EmptyNode(),
+ ]))
+
+ cg_context = cg_context.make_copy(
+ v8_callback_type=CodeGenContext.V8_OTHER_CALLBACK)
+
+ callback_defs.extend([
+ make_cross_origin_access_check_callback(
+ cg_context, "CrossOriginAccessCheckCallback"),
+ EmptyNode(),
+ make_cross_origin_property_getter_callback(
+ cg_context, "CrossOriginPropertyGetterCallback"),
+ EmptyNode(),
+ make_cross_origin_property_setter_callback(
+ cg_context, "CrossOriginPropertySetterCallback"),
+ EmptyNode(),
+ make_cross_origin_property_descriptor_callback(
+ cg_context, "CrossOriginPropertyDescriptorCallback"),
+ EmptyNode(),
+ make_cross_origin_property_enumerator_callback(
+ cg_context, "CrossOriginPropertyEnumeratorCallback"),
+ ])
+
+ text = """\
+// Cross origin properties
+${instance_template}->SetAccessCheckCallbackAndHandler(
+ CrossOriginAccessCheckCallback,
+ v8::NamedPropertyHandlerConfiguration(
+ CrossOriginPropertyGetterCallback,
+ CrossOriginPropertySetterCallback,
+ CrossOriginPropertyDescriptorCallback,
+ nullptr, // deleter
+ CrossOriginPropertyEnumeratorCallback,
+ nullptr, // definer,
+ v8::Local<v8::Value>(),
+ v8::PropertyHandlerFlags::kNone),
+% if interface.indexed_and_named_properties and \
+ interface.indexed_and_named_properties.has_indexed_properties:
+ // Reuse non-cross origin indexed property callbacks.
+ v8::IndexedPropertyHandlerConfiguration(
+ ${class_name}::IndexedPropertyGetterCallback,
+ nullptr, // setter
+ ${class_name}::IndexedPropertyDescriptorCallback,
+ nullptr, // deleter
+ ${class_name}::IndexedPropertyEnumeratorCallback,
+ nullptr, // definer
+ v8::Local<v8::Value>(),
+ v8::PropertyHandlerFlags::kNone),
+% else:
+ v8::IndexedPropertyHandlerConfiguration(
+ nullptr, // getter
+ nullptr, // setter
+ nullptr, // descriptor
+ nullptr, // deleter
+ nullptr, // enumerator
+ nullptr, // definer
+ v8::Local<v8::Value>(),
+ v8::PropertyHandlerFlags::kNone),
+% endif
+ v8::Local<v8::Value>());"""
+ install_nodes.append(TextNode(text))
+ install_nodes.accumulate(
+ CodeGenAccumulator.require_include_headers([
+ "third_party/blink/renderer/bindings/core/v8/binding_security.h",
+ "third_party/blink/renderer/platform/bindings/v8_cross_origin_property_support.h",
+ ]))
+
+ return callback_defs, install_nodes
+
+
+def make_cross_component_init(
+ cg_context, function_name, class_name, has_unconditional_props,
+ has_context_independent_props, has_context_dependent_props):
+ """
+ Returns:
+ A triplet of CodeNode of:
+ - function declaration
+ - function definition
+ - trampoline member variable definitions
+ """
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+ assert isinstance(class_name, str)
+ assert isinstance(has_unconditional_props, bool)
+ assert isinstance(has_context_independent_props, bool)
+ assert isinstance(has_context_dependent_props, bool)
+
+ T = TextNode
+ F = lambda *args, **kwargs: T(_format(*args, **kwargs))
+
+ def filter_four_trampolines(nodes):
+ assert len(nodes) == 4
+ flags = (True, has_unconditional_props, has_context_independent_props,
+ has_context_dependent_props)
+ return [node for node, flag in zip(nodes, flags) if flag]
+
+ trampoline_var_decls = ListNode(
+ filter_four_trampolines([
+ F("static InstallInterfaceTemplateFuncType {};",
+ TP_INSTALL_INTERFACE_TEMPLATE),
+ F("static InstallUnconditionalPropertiesFuncType {};",
+ TP_INSTALL_UNCONDITIONAL_PROPS),
+ F("static InstallContextIndependentPropertiesFuncType {};",
+ TP_INSTALL_CONTEXT_INDEPENDENT_PROPS),
+ F("static InstallContextDependentPropertiesFuncType {};",
+ TP_INSTALL_CONTEXT_DEPENDENT_PROPS),
+ ]))
+
+ trampoline_var_defs = ListNode(
+ filter_four_trampolines([
+ F(("${class_name}::InstallInterfaceTemplateFuncType "
+ "${class_name}::{} = nullptr;"), TP_INSTALL_INTERFACE_TEMPLATE),
+ F(("${class_name}::InstallUnconditionalPropertiesFuncType "
+ "${class_name}::{} = nullptr;"),
+ TP_INSTALL_UNCONDITIONAL_PROPS),
+ F(("${class_name}::InstallContextIndependentPropertiesFuncType "
+ "${class_name}::{} = nullptr;"),
+ TP_INSTALL_CONTEXT_INDEPENDENT_PROPS),
+ F(("${class_name}::InstallContextDependentPropertiesFuncType "
+ "${class_name}::{} = nullptr;"),
+ TP_INSTALL_CONTEXT_DEPENDENT_PROPS),
+ ]))
+ trampoline_var_defs.set_base_template_vars(cg_context.template_bindings())
+
+ func_decl = CxxFuncDeclNode(
+ name=function_name, arg_decls=[], return_type="void", static=True)
+
+ func_def = CxxFuncDefNode(
+ name=function_name,
+ class_name=class_name,
+ arg_decls=[],
+ return_type="void")
+ func_def.set_base_template_vars(cg_context.template_bindings())
+
+ body = func_def.body
+ body.extend(
+ filter_four_trampolines([
+ F("${class_name}::{} = {};", TP_INSTALL_INTERFACE_TEMPLATE,
+ FN_INSTALL_INTERFACE_TEMPLATE),
+ F("${class_name}::{} = {};", TP_INSTALL_UNCONDITIONAL_PROPS,
+ FN_INSTALL_UNCONDITIONAL_PROPS),
+ F("${class_name}::{} = {};", TP_INSTALL_CONTEXT_INDEPENDENT_PROPS,
+ FN_INSTALL_CONTEXT_INDEPENDENT_PROPS),
+ F("${class_name}::{} = {};", TP_INSTALL_CONTEXT_DEPENDENT_PROPS,
+ FN_INSTALL_CONTEXT_DEPENDENT_PROPS),
+ ]))
+
+ return func_decl, func_def, trampoline_var_decls, trampoline_var_defs
+
+
+# ----------------------------------------------------------------------------
+# WrapperTypeInfo
+# ----------------------------------------------------------------------------
+
+# FN = function name
+FN_GET_WRAPPER_TYPE_INFO = name_style.func("GetWrapperTypeInfo")
+
+# MN = member name
+MN_WRAPPER_TYPE_INFO = name_style.member_var("wrapper_type_info_")
+
+
+def make_wrapper_type_info(cg_context, function_name, member_var_name,
+ install_context_dependent_func_name):
+ assert isinstance(cg_context, CodeGenContext)
+ assert isinstance(function_name, str)
+ assert isinstance(member_var_name, str)
+ assert _is_none_or_str(install_context_dependent_func_name)
+
+ func_def = CxxFuncDefNode(
+ name=function_name,
+ arg_decls=[],
+ return_type="constexpr const WrapperTypeInfo*",
+ static=True)
+ func_def.set_base_template_vars(cg_context.template_bindings())
+ func_def.body.append(TextNode("return &{};".format(member_var_name)))
+
+ member_var_def = TextNode(
+ "static const WrapperTypeInfo {};".format(member_var_name))
+
+ pattern = """\
+// Migration adapter
+v8::Local<v8::FunctionTemplate> ${class_name}::DomTemplate(
+ v8::Isolate* isolate,
+ const DOMWrapperWorld& world) {{
+ return V8DOMConfiguration::DomClassTemplate(
+ isolate, world,
+ const_cast<WrapperTypeInfo*>(${class_name}::GetWrapperTypeInfo()),
+ ${class_name}::InstallInterfaceTemplate);
+}}
+
+const WrapperTypeInfo ${class_name}::wrapper_type_info_{{
+ gin::kEmbedderBlink,
+ ${class_name}::DomTemplate,
+ {install_context_dependent_func},
+ "${{class_like.identifier}}",
+ {wrapper_type_info_of_inherited},
+ {wrapper_type_prototype},
+ {wrapper_class_id},
+ {active_script_wrappable_inheritance},
+}};"""
+ class_like = cg_context.class_like
+ install_context_dependent_func = (
+ "${class_name}::InstallContextDependentAdapter"
+ if install_context_dependent_func_name else "nullptr")
+ if class_like.inherited:
+ wrapper_type_info_of_inherited = "{}::GetWrapperTypeInfo()".format(
+ v8_bridge_class_name(class_like.inherited))
+ else:
+ wrapper_type_info_of_inherited = "nullptr"
+ wrapper_type_prototype = ("WrapperTypeInfo::kWrapperTypeObjectPrototype"
+ if isinstance(class_like, web_idl.Interface) else
+ "WrapperTypeInfo::kWrapperTypeNoPrototype")
+ wrapper_class_id = ("WrapperTypeInfo::kNodeClassId"
+ if class_like.does_implement("Node") else
+ "WrapperTypeInfo::kObjectClassId")
+ active_script_wrappable_inheritance = (
+ "WrapperTypeInfo::kInheritFromActiveScriptWrappable"
+ if class_like.code_generator_info.is_active_script_wrappable else
+ "WrapperTypeInfo::kNotInheritFromActiveScriptWrappable")
+ text = _format(
+ pattern,
+ install_context_dependent_func=install_context_dependent_func,
+ wrapper_type_info_of_inherited=wrapper_type_info_of_inherited,
+ wrapper_type_prototype=wrapper_type_prototype,
+ wrapper_class_id=wrapper_class_id,
+ active_script_wrappable_inheritance=active_script_wrappable_inheritance
+ )
+ bridge_wrapper_type_info_def = TextNode(text)
+
+ blink_class = blink_class_name(class_like)
+ pattern = ("const WrapperTypeInfo& {blink_class}::wrapper_type_info_ = "
+ "${class_name}::wrapper_type_info_;")
+ blink_wrapper_type_info_def = TextNode(
+ _format(pattern, blink_class=blink_class))
+
+ if class_like.code_generator_info.is_active_script_wrappable:
+ pattern = """\
+// [ActiveScriptWrappable]
+static_assert(
+ std::is_base_of<ActiveScriptWrappableBase, {blink_class}>::value,
+ "{blink_class} does not inherit from ActiveScriptWrappable<> despite "
+ "the IDL has [ActiveScriptWrappable] extended attribute.");
+static_assert(
+ !std::is_same<decltype(&{blink_class}::HasPendingActivity),
+ decltype(&ScriptWrappable::HasPendingActivity)>::value,
+ "{blink_class} is not overriding hasPendingActivity() despite "
+ "the IDL has [ActiveScriptWrappable] extended attribute.");"""
+ else:
+ pattern = """\
+// non-[ActiveScriptWrappable]
+static_assert(
+ !std::is_base_of<ActiveScriptWrappableBase, {blink_class}>::value,
+ "{blink_class} inherits from ActiveScriptWrappable<> without "
+ "[ActiveScriptWrappable] extended attribute.");
+static_assert(
+ std::is_same<decltype(&{blink_class}::HasPendingActivity),
+ decltype(&ScriptWrappable::HasPendingActivity)>::value,
+ "{blink_class} is overriding hasPendingActivity() without "
+ "[ActiveScriptWrappable] extended attribute.");"""
+ check_active_script_wrappable = TextNode(
+ _format(pattern, blink_class=blink_class))
+
+ wrapper_type_info_def = ListNode([
+ bridge_wrapper_type_info_def,
+ EmptyNode(),
+ blink_wrapper_type_info_def,
+ EmptyNode(),
+ check_active_script_wrappable,
+ ])
+ wrapper_type_info_def.set_base_template_vars(
+ cg_context.template_bindings())
+
+ return func_def, member_var_def, wrapper_type_info_def
+
+
+# ----------------------------------------------------------------------------
+# Main functions
+# ----------------------------------------------------------------------------
+
+
+def _collect_include_headers(interface):
+ headers = set(interface.code_generator_info.blink_headers)
+
+ def collect_from_idl_type(idl_type):
+ idl_type.apply_to_all_composing_elements(add_include_headers)
+
+ def add_include_headers(idl_type):
+ # ScriptPromise doesn't require any header for the result type.
+ if idl_type.is_promise:
+ raise StopIteration(idl_type.syntactic_form)
+
+ type_def_obj = idl_type.type_definition_object
+ if type_def_obj is not None:
+ headers.add(PathManager(type_def_obj).api_path(ext="h"))
+ if isinstance(type_def_obj, web_idl.Interface):
+ headers.add(PathManager(type_def_obj).blink_path(ext="h"))
+ raise StopIteration(idl_type.syntactic_form)
+
+ union_def_obj = idl_type.union_definition_object
+ if union_def_obj is not None:
+ headers.add(PathManager(union_def_obj).api_path(ext="h"))
+
+ for attribute in interface.attributes:
+ collect_from_idl_type(attribute.idl_type)
+ for constructor in interface.constructors:
+ for argument in constructor.arguments:
+ collect_from_idl_type(argument.idl_type)
+ for operation in interface.operations:
+ collect_from_idl_type(operation.return_type)
+ for argument in operation.arguments:
+ collect_from_idl_type(argument.idl_type)
+
+ for exposed_construct in interface.exposed_constructs:
+ headers.add(PathManager(exposed_construct).api_path(ext="h"))
+ for legacy_window_alias in interface.legacy_window_aliases:
+ headers.add(
+ PathManager(legacy_window_alias.original).api_path(ext="h"))
+
+ path_manager = PathManager(interface)
+ headers.discard(path_manager.api_path(ext="h"))
+ headers.discard(path_manager.impl_path(ext="h"))
+
+ # TODO(yukishiino): Window interface should be
+ # [ImplementedAs=LocalDOMWindow] instead of [ImplementedAs=DOMWindow], and
+ # [CrossOrigin] properties should be implemented specifically with
+ # DOMWindow class. Then, we'll have less hacks.
+ if interface.identifier == "Window":
+ headers.add("third_party/blink/renderer/core/frame/local_dom_window.h")
+
+ return headers
+
+
+def generate_interface(interface):
+ path_manager = PathManager(interface)
+ api_component = path_manager.api_component
+ impl_component = path_manager.impl_component
+ is_cross_components = path_manager.is_cross_components
+
+ # Class names
+ api_class_name = v8_bridge_class_name(interface)
+ if is_cross_components:
+ impl_class_name = "{}::Impl".format(api_class_name)
+ else:
+ impl_class_name = api_class_name
+
+ cg_context = CodeGenContext(interface=interface, class_name=api_class_name)
+
+ # Filepaths
+ api_header_path = path_manager.api_path(ext="h")
+ api_source_path = path_manager.api_path(ext="cc")
+ if is_cross_components:
+ impl_header_path = path_manager.impl_path(ext="h")
+ impl_source_path = path_manager.impl_path(ext="cc")
+
+ # Root nodes
+ api_header_node = ListNode(tail="\n")
+ api_header_node.set_accumulator(CodeGenAccumulator())
+ api_header_node.set_renderer(MakoRenderer())
+ api_source_node = ListNode(tail="\n")
+ api_source_node.set_accumulator(CodeGenAccumulator())
+ api_source_node.set_renderer(MakoRenderer())
+ if is_cross_components:
+ impl_header_node = ListNode(tail="\n")
+ impl_header_node.set_accumulator(CodeGenAccumulator())
+ impl_header_node.set_renderer(MakoRenderer())
+ impl_source_node = ListNode(tail="\n")
+ impl_source_node.set_accumulator(CodeGenAccumulator())
+ impl_source_node.set_renderer(MakoRenderer())
+ else:
+ impl_header_node = api_header_node
+ impl_source_node = api_source_node
+
+ # Namespaces
+ api_header_blink_ns = CxxNamespaceNode(name_style.namespace("blink"))
+ api_source_blink_ns = CxxNamespaceNode(name_style.namespace("blink"))
+ if is_cross_components:
+ impl_header_blink_ns = CxxNamespaceNode(name_style.namespace("blink"))
+ impl_source_blink_ns = CxxNamespaceNode(name_style.namespace("blink"))
+ else:
+ impl_header_blink_ns = api_header_blink_ns
+ impl_source_blink_ns = api_source_blink_ns
+
+ # Class definitions
+ api_class_def = CxxClassDefNode(
+ cg_context.class_name,
+ base_class_names=[
+ _format("bindings::V8InterfaceBridge<${class_name}, {}>",
+ blink_class_name(interface)),
+ ],
+ final=True,
+ export=component_export(api_component))
+ 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))))
+ if is_cross_components:
+ impl_class_def = CxxClassDefNode(
+ impl_class_name,
+ final=True,
+ export=component_export(impl_component))
+ impl_class_def.set_base_template_vars(cg_context.template_bindings())
+ api_class_def.public_section.extend([
+ TextNode("// Cross-component implementation class"),
+ TextNode("class Impl;"),
+ EmptyNode(),
+ ])
+ else:
+ impl_class_def = api_class_def
+
+ # Constants
+ constant_defs = ListNode()
+ for constant in interface.constants:
+ cgc = cg_context.make_copy(constant=constant)
+ constant_defs.append(
+ make_constant_constant_def(cgc, constant_name(cgc)))
+
+ # Custom callback implementations
+ custom_callback_impl_decls = ListNode()
+
+ def add_custom_callback_impl_decl(**params):
+ arg_decls = params.pop("arg_decls")
+ name = params.pop("name", None)
+ if name is None:
+ name = custom_function_name(cg_context.make_copy(**params))
+ custom_callback_impl_decls.append(
+ CxxFuncDeclNode(
+ name=name,
+ arg_decls=arg_decls,
+ return_type="void",
+ static=True))
+
+ if interface.identifier == "HTMLAllCollection":
+ add_custom_callback_impl_decl(
+ name=name_style.func("LegacyCallCustom"),
+ arg_decls=["const v8::FunctionCallbackInfo<v8::Value>&"])
+ for attribute in interface.attributes:
+ custom_values = attribute.extended_attributes.values_of("Custom")
+ is_cross_origin = "CrossOrigin" in attribute.extended_attributes
+ cross_origin_values = attribute.extended_attributes.values_of(
+ "CrossOrigin")
+ if "Getter" in custom_values:
+ add_custom_callback_impl_decl(
+ attribute=attribute,
+ attribute_get=True,
+ arg_decls=["const v8::FunctionCallbackInfo<v8::Value>&"])
+ if is_cross_origin and (not cross_origin_values
+ or "Getter" in cross_origin_values):
+ add_custom_callback_impl_decl(
+ attribute=attribute,
+ attribute_get=True,
+ arg_decls=["const v8::PropertyCallbackInfo<v8::Value>&"])
+ if "Setter" in custom_values:
+ add_custom_callback_impl_decl(
+ attribute=attribute,
+ attribute_set=True,
+ arg_decls=[
+ "v8::Local<v8::Value>",
+ "const v8::FunctionCallbackInfo<v8::Value>&",
+ ])
+ if is_cross_origin and (not cross_origin_values
+ or "Setter" in cross_origin_values):
+ add_custom_callback_impl_decl(
+ attribute=attribute,
+ attribute_set=True,
+ arg_decls=[
+ "v8::Local<v8::Value>",
+ "const v8::PropertyCallbackInfo<v8::Value>&",
+ ])
for operation_group in interface.operation_groups:
- func_name = name_style.func(operation_group.identifier,
- "OperationCallback")
- code_node.append(
- make_operation_callback_def(
- cg_context.make_copy(operation_group=operation_group),
- func_name))
+ if "Custom" in operation_group.extended_attributes:
+ add_custom_callback_impl_decl(
+ operation_group=operation_group,
+ arg_decls=["const v8::FunctionCallbackInfo<v8::Value>&"])
+ if interface.indexed_and_named_properties:
+ props = interface.indexed_and_named_properties
+ operation = props.own_named_getter
+ if operation and "Custom" in operation.extended_attributes:
+ add_custom_callback_impl_decl(
+ named_property_getter=operation,
+ arg_decls=[
+ "const AtomicString& property_name",
+ "const v8::PropertyCallbackInfo<v8::Value>&",
+ ])
+ operation = props.own_named_setter
+ if operation and "Custom" in operation.extended_attributes:
+ add_custom_callback_impl_decl(
+ named_property_setter=operation,
+ arg_decls=[
+ "const AtomicString& property_name",
+ "v8::Local<v8::Value> v8_property_value",
+ "const v8::PropertyCallbackInfo<v8::Value>&",
+ ])
+ operation = props.own_named_deleter
+ if operation and "Custom" in operation.extended_attributes:
+ add_custom_callback_impl_decl(
+ named_property_deleter=operation,
+ arg_decls=[
+ "const AtomicString& property_name",
+ "const v8::PropertyCallbackInfo<v8::Value>&",
+ ])
+
+ # Cross-component trampolines
+ if is_cross_components:
+ # tp_ = trampoline name
+ tp_install_interface_template = TP_INSTALL_INTERFACE_TEMPLATE
+ tp_install_unconditional_props = TP_INSTALL_UNCONDITIONAL_PROPS
+ tp_install_context_independent_props = (
+ TP_INSTALL_CONTEXT_INDEPENDENT_PROPS)
+ tp_install_context_dependent_props = TP_INSTALL_CONTEXT_DEPENDENT_PROPS
+ else:
+ tp_install_interface_template = None
+ tp_install_unconditional_props = None
+ tp_install_context_independent_props = None
+ tp_install_context_dependent_props = None
+
+ # Callback functions
+ attribute_entries = []
+ constant_entries = []
+ constructor_entries = []
+ exposed_construct_entries = []
+ operation_entries = []
+ callback_defs = _make_property_entries_and_callback_defs(
+ cg_context,
+ attribute_entries=attribute_entries,
+ constant_entries=constant_entries,
+ constructor_entries=constructor_entries,
+ exposed_construct_entries=exposed_construct_entries,
+ operation_entries=operation_entries)
+
+ # Indexed and named properties
+ (indexed_and_named_property_decls, indexed_and_named_property_defs,
+ indexed_and_named_property_install_nodes) = (
+ make_indexed_and_named_property_callbacks_and_install_nodes(
+ cg_context))
+
+ # Cross origin properties
+ (cross_origin_property_callback_defs,
+ cross_origin_property_install_nodes) = (
+ make_cross_origin_property_callbacks_and_install_nodes(
+ cg_context, attribute_entries, operation_entries))
+ callback_defs.extend(cross_origin_property_callback_defs)
+
+ # Installer functions
+ is_unconditional = lambda entry: entry.exposure_conditional.is_always_true
+ is_context_dependent = lambda entry: entry.is_context_dependent
+ is_context_independent = (
+ lambda e: not is_context_dependent(e) and not is_unconditional(e))
+ (install_unconditional_props_decl, install_unconditional_props_def,
+ install_unconditional_props_trampoline) = make_install_properties(
+ cg_context,
+ FN_INSTALL_UNCONDITIONAL_PROPS,
+ class_name=impl_class_name,
+ 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,
+ exposed_construct_entries),
+ operation_entries=filter(is_unconditional, operation_entries))
+ (install_context_independent_props_decl,
+ install_context_independent_props_def,
+ install_context_independent_props_trampoline) = make_install_properties(
+ cg_context,
+ FN_INSTALL_CONTEXT_INDEPENDENT_PROPS,
+ class_name=impl_class_name,
+ 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,
+ exposed_construct_entries),
+ operation_entries=filter(is_context_independent, operation_entries))
+ (install_context_dependent_props_decl, install_context_dependent_props_def,
+ install_context_dependent_props_trampoline) = make_install_properties(
+ cg_context,
+ FN_INSTALL_CONTEXT_DEPENDENT_PROPS,
+ class_name=impl_class_name,
+ 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,
+ exposed_construct_entries),
+ operation_entries=filter(is_context_dependent, operation_entries))
+ (install_interface_template_decl, install_interface_template_def,
+ install_interface_template_trampoline) = make_install_interface_template(
+ cg_context,
+ FN_INSTALL_INTERFACE_TEMPLATE,
+ class_name=impl_class_name,
+ trampoline_var_name=tp_install_interface_template,
+ constructor_entries=constructor_entries,
+ indexed_and_named_property_install_nodes=(
+ indexed_and_named_property_install_nodes),
+ cross_origin_property_install_nodes=(
+ cross_origin_property_install_nodes),
+ install_unconditional_func_name=(install_unconditional_props_def
+ and FN_INSTALL_UNCONDITIONAL_PROPS),
+ install_context_independent_func_name=(
+ install_context_independent_props_def
+ and FN_INSTALL_CONTEXT_INDEPENDENT_PROPS))
+ installer_function_decls = ListNode([
+ install_interface_template_decl,
+ install_unconditional_props_decl,
+ install_context_independent_props_decl,
+ install_context_dependent_props_decl,
+ ])
+ installer_function_defs = ListNode([
+ install_interface_template_def,
+ EmptyNode(),
+ install_unconditional_props_def,
+ EmptyNode(),
+ install_context_independent_props_def,
+ EmptyNode(),
+ install_context_dependent_props_def,
+ ])
+ installer_function_trampolines = ListNode([
+ install_interface_template_trampoline,
+ install_unconditional_props_trampoline,
+ install_context_independent_props_trampoline,
+ install_context_dependent_props_trampoline,
+ ])
+
+ # WrapperTypeInfo
+ (get_wrapper_type_info_def, wrapper_type_info_var_def,
+ wrapper_type_info_init) = make_wrapper_type_info(
+ cg_context,
+ FN_GET_WRAPPER_TYPE_INFO,
+ MN_WRAPPER_TYPE_INFO,
+ install_context_dependent_func_name=(
+ install_context_dependent_props_def
+ and FN_INSTALL_CONTEXT_DEPENDENT_PROPS))
+
+ # Cross-component trampolines
+ if is_cross_components:
+ (cross_component_init_decl, cross_component_init_def,
+ trampoline_var_decls,
+ trampoline_var_defs) = make_cross_component_init(
+ cg_context,
+ "Init",
+ class_name=impl_class_name,
+ has_unconditional_props=bool(
+ install_unconditional_props_trampoline),
+ has_context_independent_props=bool(
+ install_context_independent_props_trampoline),
+ has_context_dependent_props=bool(
+ install_context_dependent_props_trampoline))
+
+ # Header part (copyright, include directives, and forward declarations)
+ api_header_node.extend([
+ make_copyright_header(),
+ EmptyNode(),
+ enclose_with_header_guard(
+ ListNode([
+ make_header_include_directives(api_header_node.accumulator),
+ EmptyNode(),
+ api_header_blink_ns,
+ ]), name_style.header_guard(api_header_path)),
+ ])
+ api_header_blink_ns.body.extend([
+ make_forward_declarations(api_header_node.accumulator),
+ EmptyNode(),
+ ])
+ api_source_node.extend([
+ make_copyright_header(),
+ EmptyNode(),
+ TextNode("#include \"{}\"".format(api_header_path)),
+ EmptyNode(),
+ make_header_include_directives(api_source_node.accumulator),
+ EmptyNode(),
+ api_source_blink_ns,
+ ])
+ api_source_blink_ns.body.extend([
+ make_forward_declarations(api_source_node.accumulator),
+ EmptyNode(),
+ ])
+ if is_cross_components:
+ impl_header_node.extend([
+ make_copyright_header(),
+ EmptyNode(),
+ enclose_with_header_guard(
+ ListNode([
+ make_header_include_directives(
+ impl_header_node.accumulator),
+ EmptyNode(),
+ impl_header_blink_ns,
+ ]), name_style.header_guard(impl_header_path)),
+ ])
+ impl_header_blink_ns.body.extend([
+ make_forward_declarations(impl_header_node.accumulator),
+ EmptyNode(),
+ ])
+ impl_source_node.extend([
+ make_copyright_header(),
+ EmptyNode(),
+ TextNode("#include \"{}\"".format(impl_header_path)),
+ EmptyNode(),
+ make_header_include_directives(impl_source_node.accumulator),
+ EmptyNode(),
+ impl_source_blink_ns,
+ ])
+ impl_source_blink_ns.body.extend([
+ make_forward_declarations(impl_source_node.accumulator),
+ EmptyNode(),
+ ])
+ api_header_node.accumulator.add_include_headers([
+ interface.code_generator_info.blink_headers[0],
+ component_export_header(api_component),
+ "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"))
+ if is_cross_components:
+ impl_header_node.accumulator.add_include_headers([
+ api_header_path,
+ component_export_header(impl_component),
+ ])
+ impl_source_node.accumulator.add_include_headers([
+ "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h",
+ "third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.h",
+ "third_party/blink/renderer/bindings/core/v8/v8_set_return_value_for_core.h",
+ "third_party/blink/renderer/platform/bindings/exception_messages.h",
+ "third_party/blink/renderer/platform/bindings/runtime_call_stats.h",
+ "third_party/blink/renderer/platform/bindings/v8_binding.h",
+ ])
+ impl_source_node.accumulator.add_include_headers(
+ _collect_include_headers(interface))
+ if interface.constructor_groups:
+ impl_source_node.accumulator.add_include_headers([
+ "third_party/blink/renderer/platform/bindings/v8_object_constructor.h",
+ ])
+
+ # Assemble the parts.
+ api_header_blink_ns.body.append(api_class_def)
+ if is_cross_components:
+ impl_header_blink_ns.body.append(impl_class_def)
+
+ api_class_def.public_section.append(get_wrapper_type_info_def)
+ api_class_def.public_section.append(EmptyNode())
+ api_class_def.public_section.extend([
+ TextNode("// Migration adapter"),
+ TextNode("static v8::Local<v8::FunctionTemplate> DomTemplate("
+ "v8::Isolate* isolate, "
+ "const DOMWrapperWorld& world);"),
+ EmptyNode(),
+ ])
+ api_class_def.private_section.append(wrapper_type_info_var_def)
+ api_class_def.private_section.append(EmptyNode())
+ api_source_blink_ns.body.extend([
+ wrapper_type_info_init,
+ EmptyNode(),
+ ])
+
+ if is_cross_components:
+ api_class_def.public_section.append(installer_function_trampolines)
+ api_class_def.private_section.extend([
+ TextNode("// Cross-component trampolines"),
+ trampoline_var_decls,
+ EmptyNode(),
+ ])
+ api_source_blink_ns.body.extend([
+ TextNode("// Cross-component trampolines"),
+ trampoline_var_defs,
+ EmptyNode(),
+ ])
+ impl_class_def.public_section.append(cross_component_init_decl)
+ impl_class_def.private_section.append(installer_function_decls)
+ impl_source_blink_ns.body.extend([
+ cross_component_init_def,
+ EmptyNode(),
+ ])
+ else:
+ api_class_def.public_section.append(installer_function_decls)
+ api_class_def.public_section.append(EmptyNode())
+
+ if constant_defs:
+ api_class_def.public_section.extend([
+ TextNode("// Constants"),
+ constant_defs,
+ EmptyNode(),
+ ])
+
+ if custom_callback_impl_decls:
+ api_class_def.public_section.extend([
+ TextNode("// Custom callback implementations"),
+ custom_callback_impl_decls,
+ EmptyNode(),
+ ])
+
+ if indexed_and_named_property_decls:
+ api_class_def.public_section.extend([
+ TextNode("// Indexed properties and named properties"),
+ indexed_and_named_property_decls,
+ EmptyNode(),
+ ])
+
+ impl_source_blink_ns.body.extend([
+ CxxNamespaceNode(name="", body=callback_defs),
+ EmptyNode(),
+ installer_function_defs,
+ EmptyNode(),
+ indexed_and_named_property_defs,
+ EmptyNode(),
+ ])
- code_node.append(make_install_interface_template_def(cg_context))
+ # Write down to the files.
+ write_code_node_to_file(api_header_node,
+ path_manager.gen_path_to(api_header_path))
+ write_code_node_to_file(api_source_node,
+ path_manager.gen_path_to(api_source_path))
+ if path_manager.is_cross_components:
+ write_code_node_to_file(impl_header_node,
+ path_manager.gen_path_to(impl_header_path))
+ write_code_node_to_file(impl_source_node,
+ path_manager.gen_path_to(impl_source_path))
+
+
+def generate_init_idl_interfaces(web_idl_database):
+ # Filepaths
+ header_path = PathManager.component_path("modules",
+ "init_idl_interfaces.h")
+ source_path = PathManager.component_path("modules",
+ "init_idl_interfaces.cc")
+
+ # Root nodes
+ header_node = ListNode(tail="\n")
+ header_node.set_accumulator(CodeGenAccumulator())
+ header_node.set_renderer(MakoRenderer())
+ source_node = ListNode(tail="\n")
+ source_node.set_accumulator(CodeGenAccumulator())
+ source_node.set_renderer(MakoRenderer())
+
+ # Namespaces
+ header_blink_ns = CxxNamespaceNode(name_style.namespace("blink"))
+ source_blink_ns = CxxNamespaceNode(name_style.namespace("blink"))
+ header_bindings_ns = CxxNamespaceNode(name_style.namespace("bindings"))
+ source_bindings_ns = CxxNamespaceNode(name_style.namespace("bindings"))
+ header_blink_ns.body.append(header_bindings_ns)
+ source_blink_ns.body.append(source_bindings_ns)
+
+ # Function nodes
+ func_decl = CxxFuncDeclNode(
+ name="InitIDLInterfaces", arg_decls=[], return_type="void")
+ func_def = CxxFuncDefNode(
+ name="InitIDLInterfaces", arg_decls=[], return_type="void")
+ header_bindings_ns.body.extend([
+ TextNode("""\
+// Initializes cross-component trampolines of IDL interface implementations.\
+"""),
+ func_decl,
+ ])
+ source_bindings_ns.body.append(func_def)
- root_node.extend([
+ # Assemble the parts.
+ header_node.extend([
+ make_copyright_header(),
+ EmptyNode(),
+ enclose_with_header_guard(
+ ListNode([
+ make_header_include_directives(header_node.accumulator),
+ EmptyNode(),
+ header_blink_ns,
+ ]), name_style.header_guard(header_path)),
+ ])
+ source_node.extend([
make_copyright_header(),
- TextNode(""),
- make_header_include_directives(root_node.accumulator),
- TextNode(""),
- enclose_with_namespace(code_node, name_style.namespace("blink")),
+ EmptyNode(),
+ TextNode("#include \"{}\"".format(header_path)),
+ EmptyNode(),
+ make_header_include_directives(source_node.accumulator),
+ EmptyNode(),
+ source_blink_ns,
])
- write_code_node_to_file(root_node, filepath)
+ init_calls = []
+ for interface in web_idl_database.interfaces:
+ # 'Internals' is the only test-only interface that needs
+ # cross-component trampoline initialization.
+ if interface.identifier == "Internals":
+ continue
+
+ path_manager = PathManager(interface)
+ if path_manager.is_cross_components:
+ source_node.accumulator.add_include_header(
+ path_manager.impl_path(ext="h"))
+
+ class_name = v8_bridge_class_name(interface)
+ init_calls.append(_format("{}::Impl::Init();", class_name))
+ for init_call in sorted(init_calls):
+ func_def.body.append(TextNode(init_call))
+
+ # Write down to the files.
+ write_code_node_to_file(header_node, path_manager.gen_path_to(header_path))
+ write_code_node_to_file(source_node, path_manager.gen_path_to(source_path))
+
+
+def generate_interfaces(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(generate_interface,
+ web_idl_database.interfaces).get(timeout_in_sec)
+
+ generate_init_idl_interfaces(web_idl_database)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/mako_renderer.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/mako_renderer.py
index f75b959c3df..b4c70553863 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/mako_renderer.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/mako_renderer.py
@@ -4,59 +4,91 @@
import sys
-import mako.lookup
+import mako.runtime
import mako.template
+import mako.util
+_MAKO_TEMPLATE_PASS_KEY = object()
-class MakoRenderer(object):
- """Represents a renderer object implemented with Mako templates."""
- def __init__(self, template_dirs=None):
- self._template_params = {
+class MakoTemplate(object):
+ """Represents a compiled template object."""
+
+ _mako_template_cache = {}
+
+ def __init__(self, template_text):
+ assert isinstance(template_text, str)
+
+ template_params = {
"strict_undefined": True,
}
- self._template_lookup = mako.lookup.TemplateLookup(
- directories=template_dirs, **self._template_params)
+ template = self._mako_template_cache.get(template_text)
+ if template is None:
+ template = mako.template.Template(
+ text=template_text, **template_params)
+ self._mako_template_cache[template_text] = template
+ self._template = template
+
+ def mako_template(self, pass_key=None):
+ assert pass_key is _MAKO_TEMPLATE_PASS_KEY
+ return self._template
+
+class MakoRenderer(object):
+ """Represents a renderer object implemented with Mako templates."""
+
+ def __init__(self):
+ self._text_buffer = None
+ self._is_invalidated = False
self._caller_stack = []
self._caller_stack_on_error = []
- def render(self,
- caller,
- template_path=None,
- template_text=None,
- template_vars=None):
+ def reset(self):
+ """
+ Resets the rendering states of this object. Must be called before
+ the first call to |render| or |render_text|.
+ """
+ self._text_buffer = mako.util.FastEncodingBuffer()
+ self._is_invalidated = False
+
+ def is_rendering_complete(self):
+ return not (self._is_invalidated or self._text_buffer is None
+ or self._caller_stack)
+
+ def invalidate_rendering_result(self):
+ self._is_invalidated = True
+
+ def to_text(self):
+ """Returns the rendering result."""
+ assert self._text_buffer is not None
+ return self._text_buffer.getvalue()
+
+ def render(self, caller, template, template_vars):
"""
Renders the template with variable bindings.
It's okay to invoke |render| method recursively and |caller| is pushed
- onto the call stack, which is accessible via |callers| and |last_caller|
- methods.
+ onto the call stack, which is accessible via
+ |callers_from_first_to_last| method, etc.
Args:
- template_path: A filepath to a template file.
- template_text: A text content to be used as a template. Either of
- |template_path| or |template_text| must be specified.
- template_vars: Template variable bindings.
caller: An object to be pushed onto the call stack.
+ template: A MakoTemplate.
+ template_vars: A dict of template variable bindings.
"""
-
- assert template_path is not None or template_text is not None
- assert template_path is None or template_text is None
- assert isinstance(template_vars, dict)
assert caller is not None
+ assert isinstance(template, MakoTemplate)
+ assert isinstance(template_vars, dict)
self._caller_stack.append(caller)
try:
- if template_path is not None:
- template = self._template_lookup.get_template(template_path)
- elif template_text is not None:
- template = mako.template.Template(
- text=template_text, **self._template_params)
-
- text = template.render(**template_vars)
+ mako_template = template.mako_template(
+ pass_key=_MAKO_TEMPLATE_PASS_KEY)
+ mako_context = mako.runtime.Context(self._text_buffer,
+ **template_vars)
+ mako_template.render_context(mako_context)
except:
# Print stacktrace of template rendering.
sys.stderr.write("\n")
@@ -64,9 +96,9 @@ class MakoRenderer(object):
sys.stderr.write(" * name: {}, type: {}\n".format(
_guess_caller_name(self.last_caller), type(self.last_caller)))
sys.stderr.write(" * depth: {}, module_id: {}\n".format(
- len(self._caller_stack), template.module_id))
+ len(self._caller_stack), mako_template.module_id))
sys.stderr.write("---- template source ----\n")
- sys.stderr.write(template.source)
+ sys.stderr.write(mako_template.source)
# Save the error state at the deepest call.
current = self._caller_stack
@@ -82,7 +114,16 @@ class MakoRenderer(object):
finally:
self._caller_stack.pop()
- return text
+ def render_text(self, text):
+ """Renders a plain text as is."""
+ assert isinstance(text, str)
+ self._text_buffer.write(text)
+
+ def push_caller(self, caller):
+ self._caller_stack.append(caller)
+
+ def pop_caller(self):
+ self._caller_stack.pop()
@property
def callers_from_first_to_last(self):
@@ -125,7 +166,7 @@ def _guess_caller_name(caller):
"""Returns the best-guessed name of |caller|."""
try:
# Outer CodeNode may have a binding to the caller.
- for name, value in caller.outer.template_vars.iteritems():
+ for name, value in caller.outer.template_vars.items():
if value is caller:
return name
try:
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/name_style.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/name_style.py
index 137de2b88d3..36a858cecbb 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/name_style.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/name_style.py
@@ -14,7 +14,7 @@ xxx_f(format_string, *args, **kwargs):
The name is formatted with the given format string and arguments.
"""
-from blinkbuild.name_style_converter import NameStyleConverter
+from blinkbuild import name_style_converter
def api_func(*args):
@@ -132,19 +132,29 @@ def namespace_f(format_string, *args, **kwargs):
def _concat(style_func, args):
assert callable(style_func)
- return style_func(" ".join(map(str, args)))
+ return style_func(" ".join(map(_tokenize, args)))
def _format(style_func, format_string, *args, **kwargs):
assert callable(style_func)
assert isinstance(format_string, str)
- args = map(style_func, map(str, args))
- for key, value in kwargs.iteritems():
- kwargs[key] = style_func(str(value))
+ args = map(style_func, map(_tokenize, args))
+ for key, value in kwargs.items():
+ kwargs[key] = style_func(_tokenize(value))
return format_string.format(*args, **kwargs)
+def _tokenize(s):
+ s = str(s)
+ if "_" in s and s.isupper():
+ # NameStyleConverter doesn't treat "ABC_DEF" as two tokens of "abc" and
+ # "def" while treating "abc_def" as "abc" and "def". Help
+ # NameStyleConverter by lowering the string.
+ return s.lower()
+ return s
+
+
class raw(object):
"""
Namespace to provide (unrecommended) raw controls on case conversions.
@@ -152,21 +162,27 @@ class raw(object):
This class is pretending to be a module.
"""
+ _NameStyleConverter = name_style_converter.NameStyleConverter
+
def __init__(self):
assert False
@staticmethod
+ def tokenize(name):
+ return name_style_converter.tokenize_name(name)
+
+ @staticmethod
def snake_case(name):
- return NameStyleConverter(name).to_snake_case()
+ return raw._NameStyleConverter(name).to_snake_case()
@staticmethod
def upper_camel_case(name):
- return NameStyleConverter(name).to_upper_camel_case()
+ return raw._NameStyleConverter(name).to_upper_camel_case()
@staticmethod
def lower_camel_case(name):
- return NameStyleConverter(name).to_lower_camel_case()
+ return raw._NameStyleConverter(name).to_lower_camel_case()
@staticmethod
def macro_case(name):
- return NameStyleConverter(name).to_macro_case()
+ return raw._NameStyleConverter(name).to_macro_case()
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 b6997d71e65..47d6c08b8ee 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
@@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import os.path
import posixpath
import web_idl
@@ -12,7 +13,16 @@ from .blink_v8_bridge import blink_class_name
class PathManager(object):
"""
- Provides a variety of paths such as Blink headers and output files.
+ Provides a variety of paths such as Blink headers and output files. Unless
+ explicitly specified, returned paths are relative to the project's root
+ directory or the root directory of generated files, e.g.
+ "third_party/blink/renderer/..."
+
+ Relative paths are represented in POSIX style so that it fits nicely in
+ generated code, e.g. #include "third_party/blink/renderer/...", while
+ absolute paths are represented in a platform-specific style so that it works
+ well with a platform-specific notion, e.g. a drive letter in Windows path
+ such as "C:\\chromium\\src\\...".
About output files, there are two cases.
- cross-components case:
@@ -26,36 +36,72 @@ class PathManager(object):
_is_initialized = False
@classmethod
- def init(cls, output_dirs):
+ def init(cls, root_src_dir, root_gen_dir, component_reldirs):
"""
Args:
- output_dirs: Pairs of component and output directory.
+ root_src_dir: Project's root directory, which corresponds to "//"
+ in GN.
+ root_gen_dir: Root directory of generated files, which corresponds
+ to "//out/Default/gen" in GN.
+ component_reldirs: Pairs of component and output directory relative
+ to |root_gen_dir|.
"""
assert not cls._is_initialized
- assert isinstance(output_dirs, dict)
- cls._output_dirs = output_dirs
+ assert isinstance(root_src_dir, str)
+ assert isinstance(root_gen_dir, str)
+ assert isinstance(component_reldirs, dict)
+
cls._blink_path_prefix = posixpath.sep + posixpath.join(
"third_party", "blink", "renderer", "")
+
+ cls._root_src_dir = os.path.abspath(root_src_dir)
+ cls._root_gen_dir = os.path.abspath(root_gen_dir)
+ cls._component_reldirs = {
+ component: posixpath.normpath(rel_dir)
+ for component, rel_dir in component_reldirs.items()
+ }
cls._is_initialized = True
@classmethod
- def relpath_to_project_root(cls, path):
- index = path.find(cls._blink_path_prefix)
- if index < 0:
- assert path.startswith(cls._blink_path_prefix[1:])
- return path
- return path[index + 1:]
+ def component_path(cls, component, filepath):
+ """
+ Returns the relative path to |filepath| in |component|'s directory.
+ """
+ assert cls._is_initialized, cls._REQUIRE_INIT_MESSAGE
+ return posixpath.join(cls._component_reldirs[component], filepath)
+
+ @classmethod
+ def gen_path_to(cls, path):
+ """
+ Returns the absolute path of |path| that must be relative to the root
+ directory of generated files.
+ """
+ assert cls._is_initialized, cls._REQUIRE_INIT_MESSAGE
+ return os.path.abspath(os.path.join(cls._root_gen_dir, path))
+
+ @classmethod
+ def src_path_to(cls, path):
+ """
+ Returns the absolute path of |path| that must be relative to the
+ project root directory.
+ """
+ assert cls._is_initialized, cls._REQUIRE_INIT_MESSAGE
+ return os.path.abspath(os.path.join(cls._root_src_dir, path))
def __init__(self, idl_definition):
assert self._is_initialized, self._REQUIRE_INIT_MESSAGE
- idl_path = idl_definition.debug_info.location.filepath
- self._idl_basepath, _ = posixpath.splitext(idl_path)
- self._idl_dir, self._idl_basename = posixpath.split(self._idl_basepath)
-
- components = sorted(idl_definition.components)
+ components = sorted(idl_definition.components) # "core" < "modules"
- if len(components) == 1:
+ if len(components) == 0:
+ assert isinstance(idl_definition, web_idl.Union)
+ # Unions of built-in types, e.g. DoubleOrString, do not have a
+ # component.
+ self._is_cross_components = False
+ default_component = web_idl.Component("core")
+ self._api_component = default_component
+ self._impl_component = default_component
+ elif len(components) == 1:
component = components[0]
self._is_cross_components = False
self._api_component = component
@@ -64,37 +110,36 @@ class PathManager(object):
assert components[0] == "core"
assert components[1] == "modules"
self._is_cross_components = True
- self._api_component = "core"
- self._impl_component = "modules"
+ # Union does not have to support cross-component code generation
+ # because clients of IDL union must be on an upper or same layer to
+ # any of union members.
+ if isinstance(idl_definition, web_idl.Union):
+ self._api_component = components[1]
+ else:
+ self._api_component = components[0]
+ self._impl_component = components[1]
else:
assert False
- self._api_dir = self._output_dirs[self._api_component]
- self._impl_dir = self._output_dirs[self._impl_component]
- self._out_basename = name_style.file("v8", idl_definition.identifier)
-
- if isinstance(idl_definition,
- (web_idl.CallbackFunction, web_idl.CallbackInterface)):
- self._blink_dir = self._api_dir
- else:
- self._blink_dir = self._idl_dir
- self._blink_basename = name_style.file(
- blink_class_name(idl_definition))
-
- @property
- def idl_dir(self):
- return self._idl_dir
-
- def blink_path(self, filename=None, ext=None):
- """
- Returns a path to a Blink implementation file relative to the project
- root directory, e.g. "third_party/blink/renderer/..."
- """
- return self.relpath_to_project_root(
- self._join(
- dirpath=self._blink_dir,
- filename=(filename or self._blink_basename),
- ext=ext))
+ self._api_dir = self._component_reldirs[self._api_component]
+ self._impl_dir = self._component_reldirs[self._impl_component]
+ self._api_basename = name_style.file("v8", idl_definition.identifier)
+ self._impl_basename = name_style.file("v8", idl_definition.identifier)
+ # TODO(peria, yukishiino): Add "v8" prefix to union's files. Trying to
+ # produce the same filepaths with the old bindings generator for the
+ # time being.
+ if isinstance(idl_definition, web_idl.Union):
+ union_class_name = idl_definition.identifier
+ union_filepath = _BACKWARD_COMPATIBLE_UNION_FILEPATHS.get(
+ union_class_name, union_class_name)
+ self._api_basename = name_style.file(union_filepath)
+ self._impl_basename = name_style.file(union_filepath)
+
+ if not isinstance(idl_definition, web_idl.Union):
+ idl_path = idl_definition.debug_info.location.filepath
+ self._blink_dir = posixpath.dirname(idl_path)
+ self._blink_basename = name_style.file(
+ blink_class_name(idl_definition))
@property
def is_cross_components(self):
@@ -111,7 +156,7 @@ class PathManager(object):
def api_path(self, filename=None, ext=None):
return self._join(
dirpath=self.api_dir,
- filename=(filename or self._out_basename),
+ filename=(filename or self._api_basename),
ext=ext)
@property
@@ -125,7 +170,17 @@ class PathManager(object):
def impl_path(self, filename=None, ext=None):
return self._join(
dirpath=self.impl_dir,
- filename=(filename or self._out_basename),
+ filename=(filename or self._impl_basename),
+ ext=ext)
+
+ @property
+ def blink_dir(self):
+ return self._blink_dir
+
+ def blink_path(self, filename=None, ext=None):
+ return self._join(
+ dirpath=self.blink_dir,
+ filename=(filename or self._blink_basename),
ext=ext)
@staticmethod
@@ -133,3 +188,34 @@ class PathManager(object):
if ext is not None:
filename = posixpath.extsep.join([filename, ext])
return posixpath.join(dirpath, filename)
+
+
+# A hack to make the filepaths to generated IDL unions compatible with the old
+# bindings generator.
+#
+# Copied from |shorten_union_name| defined in
+# //third_party/blink/renderer/bindings/scripts/utilities.py
+_BACKWARD_COMPATIBLE_UNION_FILEPATHS = {
+ # modules/canvas2d/CanvasRenderingContext2D.idl
+ "CSSImageValueOrHTMLImageElementOrSVGImageElementOrHTMLVideoElementOrHTMLCanvasElementOrImageBitmapOrOffscreenCanvas":
+ "CanvasImageSource",
+ # modules/canvas/htmlcanvas/html_canvas_element_module_support_webgl2_compute.idl
+ "CanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrWebGL2ComputeRenderingContextOrImageBitmapRenderingContextOrGPUCanvasContext":
+ "RenderingContext",
+ # modules/canvas/htmlcanvas/html_canvas_element_module.idl
+ "CanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrImageBitmapRenderingContextOrGPUCanvasContext":
+ "RenderingContext",
+ # core/frame/window_or_worker_global_scope.idl
+ "HTMLImageElementOrSVGImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrImageBitmapOrOffscreenCanvas":
+ "ImageBitmapSource",
+ # bindings/tests/idls/core/TestTypedefs.idl
+ "NodeOrLongSequenceOrEventOrXMLHttpRequestOrStringOrStringByteStringOrNodeListRecord":
+ "NestedUnionType",
+ # modules/canvas/offscreencanvas/offscreen_canvas_module_support_webgl2_compute.idl.
+ # Due to offscreen_canvas_module_support_webgl2_compute.idl and offscreen_canvas_module.idl are exclusive in modules_idl_files.gni, they have same shorten name.
+ "OffscreenCanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrWebGL2ComputeRenderingContextOrImageBitmapRenderingContext":
+ "OffscreenRenderingContext",
+ # modules/canvas/offscreencanvas/offscreen_canvas_module.idl
+ "OffscreenCanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrImageBitmapRenderingContext":
+ "OffscreenRenderingContext",
+}
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/style_format.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/style_format.py
new file mode 100644
index 00000000000..dc3493cc394
--- /dev/null
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/style_format.py
@@ -0,0 +1,107 @@
+# 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.
+
+import os.path
+import subprocess
+import sys
+
+_clang_format_command_path = None
+_gn_command_path = None
+
+
+def init(root_src_dir):
+ global _clang_format_command_path
+ global _gn_command_path
+
+ assert _clang_format_command_path is None
+ assert _gn_command_path is None
+
+ root_src_dir = os.path.abspath(root_src_dir)
+
+ # Determine //buildtools/<platform>/ directory
+ if sys.platform.startswith("linux"):
+ platform = "linux64"
+ exe_suffix = ""
+ elif sys.platform.startswith("darwin"):
+ platform = "mac"
+ exe_suffix = ""
+ elif sys.platform.startswith(("cygwin", "win")):
+ platform = "win"
+ exe_suffix = ".exe"
+ else:
+ assert False, "Unknown platform: {}".format(sys.platform)
+ buildtools_platform_dir = os.path.join(root_src_dir, "buildtools",
+ platform)
+
+ # //buildtools/<platform>/clang-format
+ _clang_format_command_path = os.path.join(
+ buildtools_platform_dir, "clang-format{}".format(exe_suffix))
+
+ # //buildtools/<platform>/gn
+ _gn_command_path = os.path.join(buildtools_platform_dir,
+ "gn{}".format(exe_suffix))
+
+
+def auto_format(contents, filename):
+ assert isinstance(filename, str)
+
+ _, ext = os.path.splitext(filename)
+ if ext in (".gn", ".gni"):
+ return gn_format(contents, filename)
+
+ return clang_format(contents, filename)
+
+
+def clang_format(contents, filename=None):
+ command_line = [_clang_format_command_path]
+ if filename is not None:
+ command_line.append('-assume-filename={}'.format(filename))
+
+ return _invoke_format_command(command_line, filename, contents)
+
+
+def gn_format(contents, filename=None):
+ command_line = [_gn_command_path, "format", "--stdin"]
+ if filename is not None:
+ command_line.append('-assume-filename={}'.format(filename))
+
+ return _invoke_format_command(command_line, filename, contents)
+
+
+def _invoke_format_command(command_line, filename, contents):
+ proc = subprocess.Popen(
+ command_line, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+ stdout_output, stderr_output = proc.communicate(input=contents)
+ exit_code = proc.wait()
+
+ return StyleFormatResult(
+ stdout_output=stdout_output,
+ stderr_output=stderr_output,
+ exit_code=exit_code,
+ filename=filename)
+
+
+class StyleFormatResult(object):
+ def __init__(self, stdout_output, stderr_output, exit_code, filename):
+ self._stdout_output = stdout_output
+ self._stderr_output = stderr_output
+ self._exit_code = exit_code
+ self._filename = filename
+
+ @property
+ def did_succeed(self):
+ return self._exit_code == 0
+
+ @property
+ def contents(self):
+ assert self.did_succeed
+ return self._stdout_output
+
+ @property
+ def error_message(self):
+ return self._stderr_output
+
+ @property
+ def filename(self):
+ return self._filename
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/union.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/union.py
new file mode 100644
index 00000000000..18c9d64f92d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/union.py
@@ -0,0 +1,188 @@
+# 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 os.path
+
+import web_idl
+
+from . import name_style
+from .blink_v8_bridge import blink_type_info
+from .code_node import ListNode
+from .code_node import TextNode
+from .code_node_cxx import CxxClassDefNode
+from .code_node_cxx import CxxFuncDeclNode
+from .code_node_cxx import CxxNamespaceNode
+from .codegen_accumulator import CodeGenAccumulator
+from .codegen_context import CodeGenContext
+from .codegen_format import format_template as _format
+from .codegen_utils import component_export
+from .codegen_utils import enclose_with_header_guard
+from .codegen_utils import make_copyright_header
+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 .path_manager import PathManager
+
+
+def _member_type_name(idl_type):
+ assert isinstance(idl_type, web_idl.IdlType)
+
+ class MemberTypeName(object):
+ def __init__(self, idl_type):
+ type_name = idl_type.type_name
+ self.old_is_api = name_style.func("Is", type_name)
+ self.old_get_api = name_style.func("GetAs", type_name)
+ self.old_set_api = name_style.func("Set", type_name)
+ # C++ data member that holds a union member. The prefix "um"
+ # stands for "Union Member."
+ self.member_var = name_style.member_var("um", type_name)
+
+ return MemberTypeName(idl_type)
+
+
+def make_union_constructor_defs(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+
+ class_name = cg_context.class_name
+
+ return ListNode([
+ CxxFuncDeclNode(
+ name=class_name, arg_decls=[], return_type="", default=True),
+ CxxFuncDeclNode(
+ name=class_name,
+ arg_decls=["const ${class_name}&"],
+ return_type="",
+ default=True),
+ CxxFuncDeclNode(
+ name=class_name,
+ arg_decls=["${class_name}&&"],
+ return_type="",
+ default=True),
+ CxxFuncDeclNode(
+ name="~${class_name}",
+ arg_decls=[],
+ return_type="",
+ override=True,
+ default=True),
+ ])
+
+
+def make_union_member_type_enum(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+
+ T = TextNode
+ F = lambda *args, **kwargs: T(_format(*args, **kwargs))
+
+ union = cg_context.union
+ node = ListNode()
+ enum_members = ListNode(separator=", ")
+
+ node.extend([
+ T("enum class MemberType {"),
+ enum_members,
+ T("};"),
+ T("MemberType active_member_type_ = MemberType::kEmpty;"),
+ ])
+
+ enum_members.append(T("kEmpty"))
+ for idl_type in union.flattened_member_types:
+ enum_members.append(T(name_style.constant(idl_type.type_name)))
+ if union.does_include_nullable_type:
+ enum_members.append(T("kNull"))
+
+ return node
+
+
+def make_union_member_vars(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+
+ T = TextNode
+ F = lambda *args, **kwargs: T(_format(*args, **kwargs))
+
+ union = cg_context.union
+ node = ListNode()
+
+ node.append(
+ T("""\
+// C++ data members that hold union members. The prefix "um" stands
+// for "Union Member."\
+"""))
+ for idl_type in union.flattened_member_types:
+ _1 = blink_type_info(idl_type).member_t
+ _2 = _member_type_name(idl_type).member_var
+ node.append(F("{_1} {_2};", _1=_1, _2=_2))
+
+ return node
+
+
+def make_union_class_def(cg_context):
+ assert isinstance(cg_context, CodeGenContext)
+
+ T = TextNode
+
+ union = cg_context.union
+ component = union.components[0]
+
+ class_def = CxxClassDefNode(
+ cg_context.class_name, export=component_export(component))
+ class_def.set_base_template_vars(cg_context.template_bindings())
+
+ public_section = class_def.public_section
+ public_section.extend([
+ make_union_constructor_defs(cg_context),
+ T(""),
+ CxxFuncDeclNode(
+ name="Trace", arg_decls=["Visitor*"], return_type="void"),
+ ])
+
+ class_def.private_section.extend([
+ make_union_member_type_enum(cg_context),
+ T(""),
+ make_union_member_vars(cg_context),
+ ])
+
+ return class_def
+
+
+def generate_union(union):
+ path_manager = PathManager(union)
+ class_name = union.identifier
+ cg_context = CodeGenContext(union=union, class_name=class_name)
+
+ filename = "union_example.h"
+ header_path = path_manager.api_path(filename=filename)
+
+ header_node = ListNode(tail="\n")
+ header_node.set_accumulator(CodeGenAccumulator())
+ header_node.set_renderer(MakoRenderer())
+
+ header_blink_ns = CxxNamespaceNode(name_style.namespace("blink"))
+
+ class_def = make_union_class_def(cg_context)
+
+ header_node.extend([
+ make_copyright_header(),
+ TextNode(""),
+ enclose_with_header_guard(
+ ListNode([
+ make_header_include_directives(header_node.accumulator),
+ TextNode(""),
+ header_blink_ns,
+ ]), name_style.header_guard(header_path)),
+ ])
+ header_blink_ns.body.extend([
+ make_forward_declarations(header_node.accumulator),
+ TextNode(""),
+ ])
+
+ header_blink_ns.body.append(class_def)
+
+ # Write down to the files.
+ write_code_node_to_file(header_node, path_manager.gen_path_to(header_path))
+
+
+def generate_unions(web_idl_database):
+ union = list(web_idl_database.union_types)[0]
+ generate_union(union)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/blink_idl_lexer.py b/chromium/third_party/blink/renderer/bindings/scripts/blink_idl_lexer.py
index c14b1451115..d041f1dc23f 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/blink_idl_lexer.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/blink_idl_lexer.py
@@ -25,7 +25,6 @@
# 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.
-
"""Lexer for Blink IDL.
The lexer uses the PLY (Python Lex-Yacc) library to build a tokenizer which
@@ -54,12 +53,15 @@ http://www.chromium.org/developers/design-documents/idl-compiler#TOC-Front-end
# Disable attribute validation, as lint can't import parent class to check
# pylint: disable=E1101
+from __future__ import print_function
+
import os.path
import sys
# PLY is in Chromium src/third_party/ply
module_path, module_name = os.path.split(__file__)
-third_party = os.path.join(module_path, os.pardir, os.pardir, os.pardir, os.pardir)
+third_party = os.path.join(module_path, os.pardir, os.pardir, os.pardir,
+ os.pardir)
# Insert at front to override system libraries, and after path[0] == script dir
sys.path.insert(1, third_party)
from ply import lex
@@ -73,7 +75,10 @@ LEXTAB = 'lextab'
class BlinkIDLLexer(IDLLexer):
- def __init__(self, debug=False, optimize=True, outputdir=None,
+ def __init__(self,
+ debug=False,
+ optimize=True,
+ outputdir=None,
rewrite_tables=False):
if debug:
# Turn off optimization and caching to help debugging
@@ -103,21 +108,23 @@ class BlinkIDLLexer(IDLLexer):
# error checking), and also allows use of Python's optimized mode.
# See: Optimized Mode
# http://www.dabeaz.com/ply/ply.html#ply_nn15
- self._lexobj = lex.lex(object=self,
- debug=debug,
- optimize=optimize,
- lextab=lextab,
- outputdir=outputdir)
+ self._lexobj = lex.lex(
+ object=self,
+ debug=debug,
+ optimize=optimize,
+ lextab=lextab,
+ outputdir=outputdir)
################################################################################
+
def main(argv):
# If file itself executed, build and cache lex table
try:
outputdir = argv[1]
except IndexError as err:
- print 'Usage: %s OUTPUT_DIR' % argv[0]
+ print('Usage: %s OUTPUT_DIR' % argv[0])
return 1
# Important: rewrite_tables=True causes the cache file to be deleted if it
# exists, thus making sure that PLY doesn't load it instead of regenerating
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/blink_idl_parser.py b/chromium/third_party/blink/renderer/bindings/scripts/blink_idl_parser.py
index a0c2054f7ff..0361deed5df 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/blink_idl_parser.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/blink_idl_parser.py
@@ -25,7 +25,6 @@
# 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.
-
"""Parser for Blink IDL.
The parser uses the PLY (Python Lex-Yacc) library to build a set of parsing
@@ -55,18 +54,22 @@ http://www.chromium.org/developers/design-documents/idl-compiler#TOC-Front-end
# pylint: disable=E1101
#
+from __future__ import print_function
+
import os.path
import sys
# PLY is in Chromium src/third_party/ply
module_path, module_name = os.path.split(__file__)
-third_party = os.path.join(module_path, os.pardir, os.pardir, os.pardir, os.pardir)
+third_party = os.path.join(module_path, os.pardir, os.pardir, os.pardir,
+ os.pardir)
# Insert at front to override system libraries, and after path[0] == script dir
sys.path.insert(1, third_party)
from ply import yacc
# Base parser is in Chromium src/tools/idl_parser
-tools_dir = os.path.join(module_path, os.pardir, os.pardir, os.pardir, os.pardir, os.pardir, 'tools')
+tools_dir = os.path.join(module_path, os.pardir, os.pardir, os.pardir,
+ os.pardir, os.pardir, 'tools')
sys.path.append(tools_dir)
from idl_parser.idl_parser import IDLParser # pylint: disable=import-error
from idl_parser.idl_parser import ParseFile as parse_file
@@ -76,16 +79,21 @@ import blink_idl_lexer
class BlinkIDLParser(IDLParser):
- def __init__(self,
- # common parameters
- debug=False,
- # local parameters
- rewrite_tables=False,
- # idl_parser parameters
- lexer=None, verbose=False, mute_error=False,
- # yacc parameters
- outputdir='', optimize=True, write_tables=False,
- picklefile=None):
+ def __init__(
+ self,
+ # common parameters
+ debug=False,
+ # local parameters
+ rewrite_tables=False,
+ # idl_parser parameters
+ lexer=None,
+ verbose=False,
+ mute_error=False,
+ # yacc parameters
+ outputdir='',
+ optimize=True,
+ write_tables=False,
+ picklefile=None):
if debug:
# Turn off optimization and caching, and write out tables,
# to help debugging
@@ -94,16 +102,16 @@ class BlinkIDLParser(IDLParser):
picklefile = None
write_tables = True
if outputdir:
- picklefile = picklefile or os.path.join(outputdir, 'parsetab.pickle')
+ picklefile = picklefile or os.path.join(outputdir,
+ 'parsetab.pickle')
if rewrite_tables:
try:
os.unlink(picklefile)
except OSError:
pass
- lexer = lexer or BlinkIDLLexer(debug=debug,
- outputdir=outputdir,
- optimize=optimize)
+ lexer = lexer or BlinkIDLLexer(
+ debug=debug, outputdir=outputdir, optimize=optimize)
self.lexer = lexer
self.tokens = lexer.KnownTokens()
# Optimized mode substantially decreases startup time (by disabling
@@ -115,11 +123,12 @@ class BlinkIDLParser(IDLParser):
# as we don't need to modify sys.path; virtually identical speed.
# See: CHANGES, Version 3.2
# http://ply.googlecode.com/svn/trunk/CHANGES
- self.yaccobj = yacc.yacc(module=self,
- debug=debug,
- optimize=optimize,
- write_tables=write_tables,
- picklefile=picklefile)
+ self.yaccobj = yacc.yacc(
+ module=self,
+ debug=debug,
+ optimize=optimize,
+ write_tables=write_tables,
+ picklefile=picklefile)
# See IDLParser.__init__() why we set defaulted_states.
self.yaccobj.defaulted_states = {}
self.parse_debug = debug
@@ -134,12 +143,13 @@ class BlinkIDLParser(IDLParser):
################################################################################
+
def main(argv):
# If file itself executed, cache lex/parse tables
try:
outputdir = argv[1]
except IndexError as err:
- print 'Usage: %s OUTPUT_DIR' % argv[0]
+ print('Usage: %s OUTPUT_DIR' % argv[0])
return 1
blink_idl_lexer.main(argv)
# Important: rewrite_tables=True causes the cache file to be deleted if it
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/blink_idl_parser_test.py b/chromium/third_party/blink/renderer/bindings/scripts/blink_idl_parser_test.py
index 309b463dba9..df0719c519e 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/blink_idl_parser_test.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/blink_idl_parser_test.py
@@ -3,7 +3,6 @@
# found in the LICENSE file.
# pylint: disable=no-member,relative-import
-
"""Unit tests for blink_idl_parser.py."""
import unittest
@@ -12,7 +11,6 @@ from blink_idl_parser import BlinkIDLParser
class BlinkIDLParserTest(unittest.TestCase):
-
def test_missing_semicolon_between_definitions(self):
# No semicolon after enum definition.
text = '''enum TestEnum { "value" } dictionary TestDictionary {};'''
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/build_web_idl_database.py b/chromium/third_party/blink/renderer/bindings/scripts/build_web_idl_database.py
index a277ddb0ccb..3629e9c51ba 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/build_web_idl_database.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/build_web_idl_database.py
@@ -1,7 +1,6 @@
# 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.
-
"""
Builds Web IDL database.
@@ -17,11 +16,13 @@ import web_idl
def parse_options():
parser = optparse.OptionParser()
- parser.add_option('--output', type='string',
- help="filepath of the resulting database")
- parser.add_option('--runtime_enabled_features', type='string',
- action='append',
- help="filepath to runtime_enabled_features.json5")
+ parser.add_option(
+ '--output', type='string', help="filepath of the resulting database")
+ parser.add_option(
+ '--runtime_enabled_features',
+ type='string',
+ action='append',
+ help="filepath to runtime_enabled_features.json5")
options, args = parser.parse_args()
required_option_names = ('output', 'runtime_enabled_features')
@@ -47,8 +48,8 @@ def main():
was_error_reported[0] = True
sys.stderr.writelines([message, "\n"])
- database = web_idl.build_database(filepaths=filepaths,
- report_error=report_error)
+ database = web_idl.build_database(
+ filepaths=filepaths, report_error=report_error)
if was_error_reported[0]:
sys.exit("Aborted due to error.")
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/code_generator.py b/chromium/third_party/blink/renderer/bindings/scripts/code_generator.py
index 1905aa85e5a..adbc4876d97 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/code_generator.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/code_generator.py
@@ -3,9 +3,10 @@
# found in the LICENSE file.
# pylint: disable=import-error,print-statement,relative-import
-
"""Plumbing for a Jinja-based code generator, including CodeGeneratorBase, a base class for all generators."""
+from __future__ import print_function
+
import os
import posixpath
import re
@@ -17,9 +18,10 @@ from v8_interface import constant_filters
from v8_types import set_component_dirs
from v8_methods import method_filters
from v8_utilities import capitalize
-from utilities import (idl_filename_to_component, is_valid_component_dependency,
- format_remove_duplicates, format_blink_cpp_source_code,
- to_snake_case, normalize_path)
+from utilities import (idl_filename_to_component,
+ is_valid_component_dependency, format_remove_duplicates,
+ format_blink_cpp_source_code, to_snake_case,
+ normalize_path)
import v8_utilities
# Path handling for libraries and templates
@@ -31,10 +33,10 @@ import v8_utilities
# is regenerated, which causes a race condition and breaks concurrent build,
# since some compile processes will try to read the partially written cache.
MODULE_PATH, _ = os.path.split(os.path.realpath(__file__))
-THIRD_PARTY_DIR = os.path.normpath(os.path.join(
- MODULE_PATH, os.pardir, os.pardir, os.pardir, os.pardir))
-TEMPLATES_DIR = os.path.normpath(os.path.join(
- MODULE_PATH, os.pardir, 'templates'))
+THIRD_PARTY_DIR = os.path.normpath(
+ os.path.join(MODULE_PATH, os.pardir, os.pardir, os.pardir, os.pardir))
+TEMPLATES_DIR = os.path.normpath(
+ os.path.join(MODULE_PATH, os.pardir, 'templates'))
# jinja2 is in chromium's third_party directory.
# Insert at 1 so at front to override system libraries, and
@@ -47,15 +49,15 @@ def generate_indented_conditional(code, conditional):
# Indent if statement to level of original code
indent = re.match(' *', code).group(0)
return ('%sif (%s) {\n' % (indent, conditional) +
- ' %s\n' % '\n '.join(code.splitlines()) +
- '%s}\n' % indent)
+ ' %s\n' % '\n '.join(code.splitlines()) + '%s}\n' % indent)
# [Exposed]
def exposed_if(code, exposed_test):
if not exposed_test:
return code
- return generate_indented_conditional(code, 'execution_context && (%s)' % exposed_test)
+ return generate_indented_conditional(
+ code, 'execution_context && (%s)' % exposed_test)
# [SecureContext]
@@ -66,7 +68,9 @@ def secure_context_if(code, secure_context_test):
# [RuntimeEnabled]
-def origin_trial_enabled_if(code, origin_trial_feature_name, execution_context=None):
+def origin_trial_enabled_if(code,
+ origin_trial_feature_name,
+ execution_context=None):
if not origin_trial_feature_name:
return code
@@ -94,14 +98,23 @@ def initialize_jinja_env(cache_dir):
lstrip_blocks=True, # so can indent control flow tags
trim_blocks=True)
jinja_env.filters.update({
- 'blink_capitalize': capitalize,
- 'exposed': exposed_if,
- 'format_blink_cpp_source_code': format_blink_cpp_source_code,
- 'format_remove_duplicates': format_remove_duplicates,
- 'origin_trial_enabled': origin_trial_enabled_if,
- 'runtime_enabled': runtime_enabled_if,
- 'runtime_enabled_function': v8_utilities.runtime_enabled_function,
- 'secure_context': secure_context_if})
+ 'blink_capitalize':
+ capitalize,
+ 'exposed':
+ exposed_if,
+ 'format_blink_cpp_source_code':
+ format_blink_cpp_source_code,
+ 'format_remove_duplicates':
+ format_remove_duplicates,
+ 'origin_trial_enabled':
+ origin_trial_enabled_if,
+ 'runtime_enabled':
+ runtime_enabled_if,
+ 'runtime_enabled_function':
+ v8_utilities.runtime_enabled_function,
+ 'secure_context':
+ secure_context_if
+ })
jinja_env.filters.update(constant_filters())
jinja_env.filters.update(method_filters())
return jinja_env
@@ -109,10 +122,12 @@ def initialize_jinja_env(cache_dir):
_BLINK_RELATIVE_PATH_PREFIXES = ('bindings/', 'core/', 'modules/', 'platform/')
+
def normalize_and_sort_includes(include_paths):
normalized_include_paths = set()
for include_path in include_paths:
- match = re.search(r'/gen/(third_party/blink/.*)$', posixpath.abspath(include_path))
+ match = re.search(r'/gen/(third_party/blink/.*)$',
+ posixpath.abspath(include_path))
if match:
include_path = match.group(1)
elif include_path.startswith(_BLINK_RELATIVE_PATH_PREFIXES):
@@ -133,6 +148,7 @@ def render_template(template, context):
class CodeGeneratorBase(object):
"""Base class for jinja-powered jinja template generation.
"""
+
def __init__(self, generator_name, info_provider, cache_dir, output_dir):
self.generator_name = generator_name
self.info_provider = info_provider
@@ -150,13 +166,19 @@ class CodeGeneratorBase(object):
IdlType.set_dictionaries(interfaces_info['dictionaries'])
IdlType.set_enums(self.info_provider.enumerations)
IdlType.set_callback_functions(self.info_provider.callback_functions)
- IdlType.set_implemented_as_interfaces(interfaces_info['implemented_as_interfaces'])
- IdlType.set_garbage_collected_types(interfaces_info['garbage_collected_interfaces'])
+ IdlType.set_implemented_as_interfaces(
+ interfaces_info['implemented_as_interfaces'])
+ IdlType.set_garbage_collected_types(
+ interfaces_info['garbage_collected_interfaces'])
IdlType.set_garbage_collected_types(interfaces_info['dictionaries'])
set_component_dirs(interfaces_info['component_dirs'])
- def render_templates(self, include_paths, header_template, cpp_template,
- context, component=None):
+ def render_templates(self,
+ include_paths,
+ header_template,
+ cpp_template,
+ context,
+ component=None):
context['code_generator'] = self.generator_name
# Add includes for any dependencies
@@ -167,8 +189,10 @@ class CodeGeneratorBase(object):
includes.add(include_path)
cpp_includes = set(context.get('cpp_includes', []))
- context['cpp_includes'] = normalize_and_sort_includes(cpp_includes | includes)
- context['header_includes'] = normalize_and_sort_includes(context['header_includes'])
+ context['cpp_includes'] = normalize_and_sort_includes(cpp_includes
+ | includes)
+ context['header_includes'] = normalize_and_sort_includes(
+ context['header_includes'])
header_text = render_template(header_template, context)
cpp_text = render_template(cpp_template, context)
@@ -194,14 +218,16 @@ def main(argv):
cache_dir = argv[1]
dummy_filename = argv[2]
except IndexError:
- print 'Usage: %s CACHE_DIR DUMMY_FILENAME' % argv[0]
+ print('Usage: %s CACHE_DIR DUMMY_FILENAME' % argv[0])
return 1
# Cache templates
jinja_env = initialize_jinja_env(cache_dir)
- template_filenames = [filename for filename in os.listdir(TEMPLATES_DIR)
- # Skip .svn, directories, etc.
- if filename.endswith(('.tmpl', '.txt'))]
+ template_filenames = [
+ filename for filename in os.listdir(TEMPLATES_DIR)
+ # Skip .svn, directories, etc.
+ if filename.endswith(('.tmpl', '.txt'))
+ ]
for template_filename in template_filenames:
jinja_env.get_template(template_filename)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/code_generator_v8.py b/chromium/third_party/blink/renderer/bindings/scripts/code_generator_v8.py
index 95564bab6e8..f296d486a3c 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/code_generator_v8.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/code_generator_v8.py
@@ -27,7 +27,6 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# pylint: disable=import-error,print-statement,relative-import
-
"""Generate Blink V8 bindings (.h and .cpp files).
If run itself, caches Jinja templates (and creates dummy file for build,
@@ -61,14 +60,15 @@ import v8_union
from v8_utilities import build_basename, cpp_name
from utilities import idl_filename_to_component, is_testing_target, shorten_union_name, to_header_guard, to_snake_case
-
# Make sure extension is .py, not .pyc or .pyo, so doesn't depend on caching
MODULE_PYNAME = os.path.splitext(os.path.basename(__file__))[0] + '.py'
+
def depending_union_type(idl_type):
"""Returns the union type name if the given idl_type depends on a
union type.
"""
+
def find_base_type(current_type):
if current_type.is_array_or_sequence_type:
return find_base_type(current_type.element_type)
@@ -79,6 +79,7 @@ def depending_union_type(idl_type):
if current_type.is_nullable:
return find_base_type(current_type.inner_type)
return current_type
+
base_type = find_base_type(idl_type)
if base_type.is_union_type:
return base_type
@@ -94,7 +95,7 @@ class TypedefResolver(Visitor):
def resolve(self, definitions, definition_name):
"""Traverse definitions and resolves typedefs with the actual types."""
self.typedefs = {}
- for name, typedef in self.info_provider.typedefs.iteritems():
+ for name, typedef in self.info_provider.typedefs.items():
self.typedefs[name] = typedef.idl_type
self.additional_header_includes = set()
definitions.accept(self)
@@ -122,7 +123,8 @@ class TypedefResolver(Visitor):
union_type = depending_union_type(resolved_idl_type)
if union_type:
self.additional_header_includes.add(
- self.info_provider.include_path_for_union_types(union_type))
+ self.info_provider.include_path_for_union_types(
+ union_type))
# Need to re-assign the attribute, not just mutate idl_type, since
# type(idl_type) may change.
setattr(typed_object, attribute_name, resolved_idl_type)
@@ -135,7 +137,8 @@ class CodeGeneratorV8Base(CodeGeneratorBase):
"""Base class for v8 bindings generator and IDL dictionary impl generator"""
def __init__(self, info_provider, cache_dir, output_dir):
- CodeGeneratorBase.__init__(self, MODULE_PYNAME, info_provider, cache_dir, output_dir)
+ CodeGeneratorBase.__init__(self, MODULE_PYNAME, info_provider,
+ cache_dir, output_dir)
self.typedef_resolver = TypedefResolver(info_provider)
def generate_code(self, definitions, definition_name):
@@ -158,13 +161,16 @@ class CodeGeneratorV8Base(CodeGeneratorBase):
class CodeGeneratorV8(CodeGeneratorV8Base):
def __init__(self, info_provider, cache_dir, output_dir):
- CodeGeneratorV8Base.__init__(self, info_provider, cache_dir, output_dir)
+ CodeGeneratorV8Base.__init__(self, info_provider, cache_dir,
+ output_dir)
def output_paths(self, definition_name):
- header_path = posixpath.join(self.output_dir, self.get_output_filename(
- definition_name, '.h', prefix='v8_'))
- cpp_path = posixpath.join(self.output_dir, self.get_output_filename(
- definition_name, '.cc', prefix='v8_'))
+ header_path = posixpath.join(
+ self.output_dir,
+ self.get_output_filename(definition_name, '.h', prefix='v8_'))
+ cpp_path = posixpath.join(
+ self.output_dir,
+ self.get_output_filename(definition_name, '.cc', prefix='v8_'))
return header_path, cpp_path
def generate_code_internal(self, definitions, definition_name):
@@ -196,31 +202,39 @@ class CodeGeneratorV8(CodeGeneratorV8Base):
interface_name += 'Partial'
assert component == 'core'
component = 'modules'
- include_paths = interface_info.get('dependencies_other_component_include_paths')
+ include_paths = interface_info.get(
+ 'dependencies_other_component_include_paths')
else:
header_template_filename = 'interface.h.tmpl'
cpp_template_filename = 'interface.cc.tmpl'
interface_context = v8_interface.interface_context
component_info = self.info_provider.component_info
- template_context = interface_context(interface, definitions.interfaces, component_info)
- includes.update(interface_info.get('cpp_includes', {}).get(component, set()))
+ template_context = interface_context(interface, definitions.interfaces,
+ component_info)
+ includes.update(
+ interface_info.get('cpp_includes', {}).get(component, set()))
if not interface.is_partial and not is_testing_target(full_path):
- template_context['header_includes'].add(self.info_provider.include_path_for_export)
- template_context['exported'] = self.info_provider.specifier_for_export
+ template_context['header_includes'].add(
+ self.info_provider.include_path_for_export)
+ template_context['exported'] = \
+ self.info_provider.specifier_for_export
# Add the include for interface itself
if IdlType(interface_name).is_typed_array:
- template_context['header_includes'].add('core/typed_arrays/dom_typed_array.h')
+ template_context['header_includes'].add(
+ 'core/typed_arrays/dom_typed_array.h')
elif interface.is_callback:
pass
else:
- template_context['header_includes'].add(interface_info['include_path'])
+ template_context['header_includes'].add(
+ interface_info['include_path'])
template_context['header_includes'].update(
interface_info.get('additional_header_includes', []))
header_path, cpp_path = self.output_paths(interface_name)
this_include_header_path = self.normalize_this_header_path(header_path)
template_context['this_include_header_path'] = this_include_header_path
- template_context['header_guard'] = to_header_guard(this_include_header_path)
+ template_context['header_guard'] = to_header_guard(
+ this_include_header_path)
header_template = self.jinja_env.get_template(header_template_filename)
cpp_template = self.jinja_env.get_template(cpp_template_filename)
header_text, cpp_text = self.render_templates(
@@ -245,12 +259,15 @@ class CodeGeneratorV8(CodeGeneratorV8Base):
# Add the include for interface itself
template_context['header_includes'].add(interface_info['include_path'])
if not is_testing_target(interface_info.get('full_path')):
- template_context['header_includes'].add(self.info_provider.include_path_for_export)
- template_context['exported'] = self.info_provider.specifier_for_export
+ template_context['header_includes'].add(
+ self.info_provider.include_path_for_export)
+ template_context['exported'] = \
+ self.info_provider.specifier_for_export
header_path, cpp_path = self.output_paths(dictionary_name)
this_include_header_path = self.normalize_this_header_path(header_path)
template_context['this_include_header_path'] = this_include_header_path
- template_context['header_guard'] = to_header_guard(this_include_header_path)
+ template_context['header_guard'] = to_header_guard(
+ this_include_header_path)
header_text, cpp_text = self.render_templates(
include_paths, header_template, cpp_template, template_context)
return (
@@ -261,15 +278,16 @@ class CodeGeneratorV8(CodeGeneratorV8Base):
class CodeGeneratorDictionaryImpl(CodeGeneratorV8Base):
def __init__(self, info_provider, cache_dir, output_dir):
- CodeGeneratorV8Base.__init__(self, info_provider, cache_dir, output_dir)
+ CodeGeneratorV8Base.__init__(self, info_provider, cache_dir,
+ output_dir)
def output_paths(self, definition_name, interface_info):
output_dir = posixpath.join(self.output_dir,
interface_info['relative_dir'])
- header_path = posixpath.join(output_dir,
- self.get_output_filename(definition_name, '.h'))
- cpp_path = posixpath.join(output_dir,
- self.get_output_filename(definition_name, '.cc'))
+ header_path = posixpath.join(
+ output_dir, self.get_output_filename(definition_name, '.h'))
+ cpp_path = posixpath.join(
+ output_dir, self.get_output_filename(definition_name, '.cc'))
return header_path, cpp_path
def generate_code_internal(self, definitions, definition_name):
@@ -284,14 +302,18 @@ class CodeGeneratorDictionaryImpl(CodeGeneratorV8Base):
dictionary, interfaces_info)
include_paths = interface_info.get('dependencies_include_paths')
if not is_testing_target(interface_info.get('full_path')):
- template_context['exported'] = self.info_provider.specifier_for_export
- template_context['header_includes'].add(self.info_provider.include_path_for_export)
+ template_context['exported'] = \
+ self.info_provider.specifier_for_export
+ template_context['header_includes'].add(
+ self.info_provider.include_path_for_export)
template_context['header_includes'].update(
interface_info.get('additional_header_includes', []))
- header_path, cpp_path = self.output_paths(definition_name, interface_info)
+ header_path, cpp_path = self.output_paths(definition_name,
+ interface_info)
this_include_header_path = self.normalize_this_header_path(header_path)
template_context['this_include_header_path'] = this_include_header_path
- template_context['header_guard'] = to_header_guard(this_include_header_path)
+ template_context['header_guard'] = to_header_guard(
+ this_include_header_path)
header_text, cpp_text = self.render_templates(
include_paths, header_template, cpp_template, template_context)
return (
@@ -306,15 +328,17 @@ class CodeGeneratorUnionType(CodeGeneratorBase):
CodeGeneratorDictionaryImpl. It assumes that all union types are already
collected. It doesn't process idl files directly.
"""
+
def __init__(self, info_provider, cache_dir, output_dir, target_component):
- CodeGeneratorBase.__init__(self, MODULE_PYNAME, info_provider, cache_dir, output_dir)
+ CodeGeneratorBase.__init__(self, MODULE_PYNAME, info_provider,
+ cache_dir, output_dir)
self.target_component = target_component
# The code below duplicates parts of TypedefResolver. We do not use it
# directly because IdlUnionType is not a type defined in
# idl_definitions.py. What we do instead is to resolve typedefs in
# _generate_container_code() whenever a new union file is generated.
self.typedefs = {}
- for name, typedef in self.info_provider.typedefs.iteritems():
+ for name, typedef in self.info_provider.typedefs.items():
self.typedefs[name] = typedef.idl_type
def _generate_container_code(self, union_type):
@@ -322,7 +346,8 @@ class CodeGeneratorUnionType(CodeGeneratorBase):
union_type = union_type.resolve_typedefs(self.typedefs)
header_template = self.jinja_env.get_template('union_container.h.tmpl')
cpp_template = self.jinja_env.get_template('union_container.cc.tmpl')
- template_context = v8_union.container_context(union_type, self.info_provider)
+ template_context = v8_union.container_context(union_type,
+ self.info_provider)
template_context['header_includes'].append(
self.info_provider.include_path_for_export)
template_context['exported'] = self.info_provider.specifier_for_export
@@ -331,7 +356,8 @@ class CodeGeneratorUnionType(CodeGeneratorBase):
cpp_path = posixpath.join(self.output_dir, '%s.cc' % snake_base_name)
this_include_header_path = self.normalize_this_header_path(header_path)
template_context['this_include_header_path'] = this_include_header_path
- template_context['header_guard'] = to_header_guard(this_include_header_path)
+ template_context['header_guard'] = to_header_guard(
+ this_include_header_path)
header_text, cpp_text = self.render_templates(
[], header_template, cpp_template, template_context)
return (
@@ -368,18 +394,22 @@ class CodeGeneratorUnionType(CodeGeneratorBase):
class CodeGeneratorCallbackFunction(CodeGeneratorBase):
def __init__(self, info_provider, cache_dir, output_dir, target_component):
- CodeGeneratorBase.__init__(self, MODULE_PYNAME, info_provider, cache_dir, output_dir)
+ CodeGeneratorBase.__init__(self, MODULE_PYNAME, info_provider,
+ cache_dir, output_dir)
self.target_component = target_component
self.typedef_resolver = TypedefResolver(info_provider)
def generate_code_internal(self, callback_function, path):
- self.typedef_resolver.resolve(callback_function, callback_function.name)
- header_template = self.jinja_env.get_template('callback_function.h.tmpl')
+ self.typedef_resolver.resolve(callback_function,
+ callback_function.name)
+ header_template = self.jinja_env.get_template(
+ 'callback_function.h.tmpl')
cpp_template = self.jinja_env.get_template('callback_function.cc.tmpl')
template_context = v8_callback_function.callback_function_context(
callback_function)
if not is_testing_target(path):
- template_context['exported'] = self.info_provider.specifier_for_export
+ template_context['exported'] = \
+ self.info_provider.specifier_for_export
template_context['header_includes'].append(
self.info_provider.include_path_for_export)
@@ -388,14 +418,16 @@ class CodeGeneratorCallbackFunction(CodeGeneratorBase):
for argument in callback_function.arguments:
if argument.idl_type.is_union_type:
template_context['header_includes'].append(
- self.info_provider.include_path_for_union_types(argument.idl_type))
+ self.info_provider.include_path_for_union_types(
+ argument.idl_type))
snake_base_name = to_snake_case('V8%s' % callback_function.name)
header_path = posixpath.join(self.output_dir, '%s.h' % snake_base_name)
cpp_path = posixpath.join(self.output_dir, '%s.cc' % snake_base_name)
this_include_header_path = self.normalize_this_header_path(header_path)
template_context['this_include_header_path'] = this_include_header_path
- template_context['header_guard'] = to_header_guard(this_include_header_path)
+ template_context['header_guard'] = to_header_guard(
+ this_include_header_path)
header_text, cpp_text = self.render_templates(
[], header_template, cpp_template, template_context)
return (
@@ -409,12 +441,13 @@ class CodeGeneratorCallbackFunction(CodeGeneratorBase):
if not callback_functions:
return ()
outputs = set()
- for callback_function_dict in callback_functions.itervalues():
+ for callback_function_dict in callback_functions.values():
if callback_function_dict['component_dir'] != self.target_component:
continue
callback_function = callback_function_dict['callback_function']
if 'Custom' in callback_function.extended_attributes:
continue
path = callback_function_dict['full_path']
- outputs.update(self.generate_code_internal(callback_function, path))
+ outputs.update(
+ self.generate_code_internal(callback_function, path))
return outputs
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/collect_idl_files.py b/chromium/third_party/blink/renderer/bindings/scripts/collect_idl_files.py
index c6922e536fc..082a545fc51 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/collect_idl_files.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/collect_idl_files.py
@@ -1,7 +1,6 @@
# 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.
-
"""
Collects Web IDL definitions in IDL files into a Python object per Blink
component.
@@ -16,18 +15,21 @@ import blink_idl_parser
import utilities
import web_idl
-
_VALID_COMPONENTS = ('core', 'modules')
def parse_options():
parser = optparse.OptionParser()
- parser.add_option('--idl-list-file', type='string',
- help="a file path which lists IDL file paths to process")
- parser.add_option('--component', type='choice', choices=_VALID_COMPONENTS,
- help="specify a component name")
- parser.add_option('--output', type='string',
- help="the output file path")
+ parser.add_option(
+ '--idl-list-file',
+ type='string',
+ help="a file path which lists IDL file paths to process")
+ parser.add_option(
+ '--component',
+ type='choice',
+ choices=_VALID_COMPONENTS,
+ help="specify a component name")
+ parser.add_option('--output', type='string', help="the output file path")
options, args = parser.parse_args()
if options.idl_list_file is None:
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/compute_global_objects.py b/chromium/third_party/blink/renderer/bindings/scripts/compute_global_objects.py
index 78d74f825be..7fa1c022a15 100755
--- a/chromium/third_party/blink/renderer/bindings/scripts/compute_global_objects.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/compute_global_objects.py
@@ -3,7 +3,6 @@
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-
"""Compute global objects.
Global objects are defined by interfaces with [Global] on
@@ -30,13 +29,16 @@ def parse_options():
usage = 'Usage: %prog [options] [GlobalObjects.pickle]'
parser = optparse.OptionParser(usage=usage)
parser.add_option('--idl-files-list', help='file listing IDL files')
- parser.add_option('--global-objects-component-files', action='append',
- help='optionally preceeded input pickle filename.')
+ parser.add_option(
+ '--global-objects-component-files',
+ action='append',
+ help='optionally preceeded input pickle filename.')
options, args = parser.parse_args()
if options.idl_files_list is None:
- parser.error('Must specify a file listing IDL files using --idl-files-list.')
+ parser.error(
+ 'Must specify a file listing IDL files using --idl-files-list.')
if options.global_objects_component_files is None:
options.global_objects_component_files = []
if len(args) != 1:
@@ -46,7 +48,7 @@ def parse_options():
def dict_union(dicts):
- return dict((k, v) for d in dicts for k, v in d.iteritems())
+ return dict((k, v) for d in dicts for k, v in d.items())
def idl_file_to_global_names(idl_filename):
@@ -58,22 +60,25 @@ def idl_file_to_global_names(idl_filename):
"""
full_path = os.path.realpath(idl_filename)
idl_file_contents = get_file_contents(full_path)
- extended_attributes = get_interface_extended_attributes_from_idl(idl_file_contents)
+ extended_attributes = get_interface_extended_attributes_from_idl(
+ idl_file_contents)
interface_name = get_first_interface_name_from_idl(idl_file_contents)
if 'Global' not in extended_attributes:
return
global_value = extended_attributes['Global']
if not global_value:
- raise ValueError('[Global] must take an indentifier or an identifier list.\n' +
- full_path)
+ raise ValueError(
+ '[Global] must take an indentifier or an identifier list.\n' +
+ full_path)
return map(str.strip, global_value.strip('()').split(','))
def idl_files_to_interface_name_global_names(idl_files):
"""Yields pairs (interface_name, global_names) found in IDL files."""
for idl_filename in idl_files:
- interface_name = get_first_interface_name_from_idl(get_file_contents(idl_filename))
+ interface_name = get_first_interface_name_from_idl(
+ get_file_contents(idl_filename))
global_names = idl_file_to_global_names(idl_filename)
if global_names:
yield interface_name, global_names
@@ -81,19 +86,20 @@ def idl_files_to_interface_name_global_names(idl_files):
################################################################################
+
def main():
options, args = parse_options()
output_global_objects_filename = args.pop()
interface_name_global_names = dict_union(
existing_interface_name_global_names
- for existing_interface_name_global_names
- in read_pickle_files(options.global_objects_component_files))
+ for existing_interface_name_global_names in read_pickle_files(
+ options.global_objects_component_files))
# File paths of input IDL files are passed in a file, which is generated at
# GN time. It is OK because the target IDL files themselves are static.
idl_files = read_file_to_list(options.idl_files_list)
interface_name_global_names.update(
- idl_files_to_interface_name_global_names(idl_files))
+ idl_files_to_interface_name_global_names(idl_files))
write_pickle_file(output_global_objects_filename,
interface_name_global_names)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/compute_interfaces_info_individual.py b/chromium/third_party/blink/renderer/bindings/scripts/compute_interfaces_info_individual.py
index 4930013a526..01c23ba15f7 100755
--- a/chromium/third_party/blink/renderer/bindings/scripts/compute_interfaces_info_individual.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/compute_interfaces_info_individual.py
@@ -27,7 +27,6 @@
# 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.
-
"""Compute global interface information for individual IDL files.
Auxiliary module for compute_interfaces_info_overall, which consolidates
@@ -58,7 +57,6 @@ from utilities import to_snake_case
from utilities import read_pickle_file
from utilities import write_pickle_file
-
module_path = os.path.dirname(__file__)
source_path = os.path.normpath(os.path.join(module_path, os.pardir, os.pardir))
gen_path = os.path.join('gen', 'blink')
@@ -74,15 +72,21 @@ def parse_options():
parser = optparse.OptionParser(usage=usage)
parser.add_option('--cache-directory', help='cache directory')
parser.add_option('--idl-files-list', help='file listing IDL files')
- parser.add_option('--interfaces-info-file', help='interface info pickle file')
- parser.add_option('--component-info-file', help='component wide info pickle file')
- parser.add_option('--runtime-enabled-features-file', help='runtime-enabled features pickle file')
+ parser.add_option(
+ '--interfaces-info-file', help='interface info pickle file')
+ parser.add_option(
+ '--component-info-file', help='component wide info pickle file')
+ parser.add_option(
+ '--runtime-enabled-features-file',
+ help='runtime-enabled features pickle file')
options, args = parser.parse_args()
if options.interfaces_info_file is None:
- parser.error('Must specify an output file using --interfaces-info-file.')
+ parser.error(
+ 'Must specify an output file using --interfaces-info-file.')
if options.idl_files_list is None:
- parser.error('Must specify a file listing IDL files using --idl-files-list.')
+ parser.error(
+ 'Must specify a file listing IDL files using --idl-files-list.')
return options, args
@@ -90,6 +94,7 @@ def parse_options():
# Computations
################################################################################
+
def relative_dir_posix(idl_filename, base_path):
"""Returns relative path to the directory of idl_file in POSIX format."""
relative_path_local = os.path.relpath(idl_filename, base_path)
@@ -109,7 +114,8 @@ def include_path(idl_filename, implemented_as=None):
relative_dir = relative_dir_posix(idl_filename, source_path)
# IDL file basename is used even if only a partial interface file
- output_file_basename = implemented_as or idl_filename_to_basename(idl_filename)
+ output_file_basename = implemented_as or idl_filename_to_basename(
+ idl_filename)
output_file_basename = to_snake_case(output_file_basename)
return posixpath.join(relative_dir, output_file_basename + '.h')
@@ -133,9 +139,9 @@ def get_includes_from_definitions(definitions, definition_name):
def get_put_forward_interfaces_from_definition(definition):
- return sorted(set(attribute.idl_type.base_type
- for attribute in definition.attributes
- if 'PutForwards' in attribute.extended_attributes))
+ return sorted(
+ set(attribute.idl_type.base_type for attribute in definition.attributes
+ if 'PutForwards' in attribute.extended_attributes))
def get_unforgeable_attributes_from_definition(definition):
@@ -145,6 +151,7 @@ def get_unforgeable_attributes_from_definition(definition):
def collect_union_types_from_definitions(definitions):
"""Traverse definitions and collect all union types."""
+
class UnionTypeCollector(Visitor):
def collect(self, definitions):
self._union_types = set()
@@ -165,13 +172,14 @@ def collect_union_types_from_definitions(definitions):
class InterfaceInfoCollector(object):
"""A class that collects interface information from idl files."""
+
def __init__(self, cache_directory=None):
- self.reader = IdlReader(interfaces_info=None, outputdir=cache_directory)
+ self.reader = IdlReader(
+ interfaces_info=None, outputdir=cache_directory)
self.interfaces_info = {}
self.partial_interface_files = defaultdict(lambda: {
'full_paths': [],
- 'include_paths': [],
- })
+ 'include_paths': [], })
self.enumerations = {}
self.union_types = set()
self.typedefs = {}
@@ -196,6 +204,7 @@ class InterfaceInfoCollector(object):
def collect_info(self, idl_filename):
"""Reads an idl file and collects information which is required by the
binding code generation."""
+
def collect_unforgeable_attributes(definition, idl_filename):
"""Collects [Unforgeable] attributes so that we can define them on
sub-interfaces later. The resulting structure is as follows.
@@ -205,17 +214,21 @@ class InterfaceInfoCollector(object):
}
"""
interface_info = {}
- unforgeable_attributes = get_unforgeable_attributes_from_definition(definition)
+ unforgeable_attributes = get_unforgeable_attributes_from_definition(
+ definition)
if not unforgeable_attributes:
return interface_info
if definition.is_partial:
- interface_basename = idl_filename_to_interface_name(idl_filename)
+ interface_basename = idl_filename_to_interface_name(
+ idl_filename)
# TODO(yukishiino): [PartialInterfaceImplementedAs] is treated
# in interface_dependency_resolver.transfer_extended_attributes.
# Come up with a better way to keep them consistent.
for attr in unforgeable_attributes:
- attr.extended_attributes['PartialInterfaceImplementedAs'] = definition.extended_attributes.get('ImplementedAs', interface_basename)
+ attr.extended_attributes[
+ 'PartialInterfaceImplementedAs'] = definition.extended_attributes.get(
+ 'ImplementedAs', interface_basename)
interface_info['unforgeable_attributes'] = unforgeable_attributes
return interface_info
@@ -224,7 +237,8 @@ class InterfaceInfoCollector(object):
this_union_types = collect_union_types_from_definitions(definitions)
self.union_types.update(this_union_types)
self.typedefs.update(definitions.typedefs)
- for callback_function_name, callback_function in definitions.callback_functions.iteritems():
+ for callback_function_name, callback_function in \
+ definitions.callback_functions.items():
# Set 'component_dir' to specify a directory that callback function files belong to
self.callback_functions[callback_function_name] = {
'callback_function': callback_function,
@@ -239,10 +253,12 @@ class InterfaceInfoCollector(object):
self.enumerations.update(definitions.enumerations)
if definitions.interfaces:
- definition = next(definitions.interfaces.itervalues())
+ definition = next(iter(definitions.interfaces.values()))
interface_info = {
- 'is_callback_interface': definition.is_callback,
- 'is_dictionary': False,
+ 'is_callback_interface':
+ definition.is_callback,
+ 'is_dictionary':
+ False,
# Interfaces that are referenced (used as types) and that we
# introspect during code generation (beyond interface-level
# data ([ImplementedAs], is_callback_interface, ancestors, and
@@ -250,10 +266,11 @@ class InterfaceInfoCollector(object):
# These cause rebuilds of referrers, due to the dependency,
# so these should be minimized; currently only targets of
# [PutForwards].
- 'referenced_interfaces': get_put_forward_interfaces_from_definition(definition),
+ 'referenced_interfaces':
+ get_put_forward_interfaces_from_definition(definition),
}
elif definitions.dictionaries:
- definition = next(definitions.dictionaries.itervalues())
+ definition = next(iter(definitions.dictionaries.values()))
interface_info = {
'is_callback_interface': False,
'is_dictionary': True,
@@ -267,8 +284,9 @@ class InterfaceInfoCollector(object):
# Remember [Unforgeable] attributes.
if definitions.interfaces:
- merge_dict_recursively(self.interfaces_info[definition.name],
- collect_unforgeable_attributes(definition, idl_filename))
+ merge_dict_recursively(
+ self.interfaces_info[definition.name],
+ collect_unforgeable_attributes(definition, idl_filename))
component = idl_filename_to_component(idl_filename)
extended_attributes = definition.extended_attributes
@@ -284,7 +302,8 @@ class InterfaceInfoCollector(object):
partial_include_paths = []
if this_include_path:
partial_include_paths.append(this_include_path)
- self.add_paths_to_partials_dict(definition.name, full_path, partial_include_paths)
+ self.add_paths_to_partials_dict(definition.name, full_path,
+ partial_include_paths)
# Collects C++ header paths which should be included from generated
# .cpp files. The resulting structure is as follows.
# interfaces_info[interface_name] = {
@@ -297,7 +316,9 @@ class InterfaceInfoCollector(object):
if this_include_path:
merge_dict_recursively(
self.interfaces_info[definition.name],
- {'cpp_includes': {component: set([this_include_path])}})
+ {'cpp_includes': {
+ component: set([this_include_path])
+ }})
return
# 'includes' statements can be included in either the file for the
@@ -307,20 +328,31 @@ class InterfaceInfoCollector(object):
definitions, definition.name)
interface_info.update({
- 'extended_attributes': extended_attributes,
- 'full_path': full_path,
- 'union_types': this_union_types,
- 'implemented_as': implemented_as,
- 'included_by_interfaces': includes_interfaces,
- 'including_mixins': includes_mixins,
- 'include_path': this_include_path,
- # FIXME: temporary private field, while removing old treatement of
- # 'implements': http://crbug.com/360435
- 'is_legacy_treat_as_partial_interface': 'LegacyTreatAsPartialInterface' in extended_attributes,
- 'parent': definition.parent,
- 'relative_dir': relative_dir_posix(idl_filename, source_path),
+ 'extended_attributes':
+ extended_attributes,
+ 'full_path':
+ full_path,
+ 'union_types':
+ this_union_types,
+ 'implemented_as':
+ implemented_as,
+ 'included_by_interfaces':
+ includes_interfaces,
+ 'including_mixins':
+ includes_mixins,
+ 'include_path':
+ this_include_path,
+ # FIXME: temporary private field, while removing old
+ # treatement of 'implements': http://crbug.com/360435
+ 'is_legacy_treat_as_partial_interface':
+ 'LegacyTreatAsPartialInterface' in extended_attributes,
+ 'parent':
+ definition.parent,
+ 'relative_dir':
+ relative_dir_posix(idl_filename, source_path),
})
- merge_dict_recursively(self.interfaces_info[definition.name], interface_info)
+ merge_dict_recursively(self.interfaces_info[definition.name],
+ interface_info)
def get_info_as_dict(self):
"""Returns info packaged as a dict."""
@@ -334,17 +366,23 @@ class InterfaceInfoCollector(object):
def get_component_info_as_dict(self, runtime_enabled_features):
"""Returns component wide information as a dict."""
return {
- 'callback_functions': self.callback_functions,
- 'enumerations': dict((enum.name, enum.values)
- for enum in self.enumerations.values()),
- 'runtime_enabled_features': runtime_enabled_features,
- 'typedefs': self.typedefs,
- 'union_types': self.union_types,
+ 'callback_functions':
+ self.callback_functions,
+ 'enumerations':
+ dict((enum.name, enum.values)
+ for enum in self.enumerations.values()),
+ 'runtime_enabled_features':
+ runtime_enabled_features,
+ 'typedefs':
+ self.typedefs,
+ 'union_types':
+ self.union_types,
}
################################################################################
+
def main():
options, _ = parse_options()
@@ -360,9 +398,12 @@ def main():
write_pickle_file(options.interfaces_info_file,
info_collector.get_info_as_dict())
- runtime_enabled_features = read_pickle_file(options.runtime_enabled_features_file)
- write_pickle_file(options.component_info_file,
- info_collector.get_component_info_as_dict(runtime_enabled_features))
+ runtime_enabled_features = read_pickle_file(
+ options.runtime_enabled_features_file)
+ write_pickle_file(
+ options.component_info_file,
+ info_collector.get_component_info_as_dict(runtime_enabled_features))
+
if __name__ == '__main__':
sys.exit(main())
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/compute_interfaces_info_overall.py b/chromium/third_party/blink/renderer/bindings/scripts/compute_interfaces_info_overall.py
index a3e0484a1f8..235cf0f914a 100755
--- a/chromium/third_party/blink/renderer/bindings/scripts/compute_interfaces_info_overall.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/compute_interfaces_info_overall.py
@@ -27,7 +27,6 @@
# 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.
-
"""Compute global interface information, including public information, dependencies, and inheritance.
Computed data is stored in a global variable, |interfaces_info|, and written as
@@ -104,10 +103,11 @@ interfaces_info = {}
# Auxiliary variables (not visible to future build steps)
partial_interface_files = defaultdict(lambda: {
'full_paths': [],
- 'include_paths': [],
-})
+ 'include_paths': [], })
parent_interfaces = {}
-inherited_extended_attributes_by_interface = {} # interface name -> extended attributes
+
+# interface name -> extended attributes
+inherited_extended_attributes_by_interface = {}
class IdlInterfaceFileNotFoundError(Exception):
@@ -127,12 +127,12 @@ def dict_of_dicts_of_lists_update_or_append(existing, other):
Needed for merging partial_interface_files across components.
"""
- for key, value in other.iteritems():
+ for key, value in other.items():
if key not in existing:
existing[key] = value
continue
existing_value = existing[key]
- for inner_key, inner_value in value.iteritems():
+ for inner_key, inner_value in value.items():
existing_value[inner_key].extend(inner_value)
@@ -140,25 +140,33 @@ def dict_of_dicts_of_lists_update_or_append(existing, other):
# Computations
################################################################################
+
def compute_inheritance_info(interface_name):
- """Compute inheritance information, namely ancestors and inherited extended attributes."""
+ """Compute inheritance information, namely ancestors and inherited
+ extended attributes.
+ """
+
def generate_ancestors(interface_name):
while interface_name in parent_interfaces:
interface_name = parent_interfaces[interface_name]
yield interface_name
ancestors = list(generate_ancestors(interface_name))
- inherited_extended_attributes = inherited_extended_attributes_by_interface[interface_name]
+ inherited_extended_attributes = \
+ inherited_extended_attributes_by_interface[interface_name]
for ancestor in ancestors:
# Ancestors may not be present, notably if an ancestor is a generated
# IDL file and we are running this script from run_bindings_tests.py,
# where we don't generate these files.
- ancestor_extended_attributes = inherited_extended_attributes_by_interface.get(ancestor, {})
+ ancestor_extended_attributes = \
+ inherited_extended_attributes_by_interface.get(ancestor, {})
inherited_extended_attributes.update(ancestor_extended_attributes)
interfaces_info[interface_name].update({
- 'ancestors': ancestors,
- 'inherited_extended_attributes': inherited_extended_attributes,
+ 'ancestors':
+ ancestors,
+ 'inherited_extended_attributes':
+ inherited_extended_attributes,
})
@@ -170,8 +178,9 @@ def compute_global_type_info():
garbage_collected_interfaces = set()
callback_interfaces = set()
- for interface_name, interface_info in interfaces_info.iteritems():
- component_dirs[interface_name] = idl_filename_to_component(interface_info['full_path'])
+ for interface_name, interface_info in interfaces_info.items():
+ component_dirs[interface_name] = idl_filename_to_component(
+ interface_info['full_path'])
if interface_info['ancestors']:
ancestors[interface_name] = interface_info['ancestors']
@@ -180,16 +189,19 @@ def compute_global_type_info():
if interface_info['is_dictionary']:
dictionaries[interface_name] = interface_info['is_dictionary']
if interface_info['implemented_as']:
- implemented_as_interfaces[interface_name] = interface_info['implemented_as']
+ implemented_as_interfaces[interface_name] = \
+ interface_info['implemented_as']
- inherited_extended_attributes = interface_info['inherited_extended_attributes']
+ inherited_extended_attributes = \
+ interface_info['inherited_extended_attributes']
garbage_collected_interfaces.add(interface_name)
interfaces_info['ancestors'] = ancestors
interfaces_info['callback_interfaces'] = callback_interfaces
interfaces_info['dictionaries'] = dictionaries
interfaces_info['implemented_as_interfaces'] = implemented_as_interfaces
- interfaces_info['garbage_collected_interfaces'] = garbage_collected_interfaces
+ interfaces_info['garbage_collected_interfaces'] = \
+ garbage_collected_interfaces
interfaces_info['component_dirs'] = component_dirs
@@ -205,15 +217,14 @@ def compute_interfaces_info_overall(info_individuals):
# partial interfaces are used to *extend* interfaces.
# We thus need to update or append if already present
dict_of_dicts_of_lists_update_or_append(
- partial_interface_files, info['partial_interface_files'])
+ partial_interface_files, info['partial_interface_files'])
# Record inheritance information individually
- for interface_name, interface_info in interfaces_info.iteritems():
+ for interface_name, interface_info in interfaces_info.items():
extended_attributes = interface_info['extended_attributes']
inherited_extended_attributes_by_interface[interface_name] = dict(
- (key, value)
- for key, value in extended_attributes.iteritems()
- if key in INHERITED_EXTENDED_ATTRIBUTES)
+ (key, value) for key, value in extended_attributes.items()
+ if key in INHERITED_EXTENDED_ATTRIBUTES)
parent = interface_info['parent']
if parent:
parent_interfaces[interface_name] = parent
@@ -230,26 +241,32 @@ def compute_interfaces_info_overall(info_individuals):
# 'includes').
# Note that moving an 'includes' statement between files does not change the
# info itself (or hence cause a rebuild)!
- for mixin_name, interface_info in interfaces_info.iteritems():
+ for mixin_name, interface_info in interfaces_info.items():
for interface_name in interface_info['included_by_interfaces']:
- interfaces_info[interface_name]['including_mixins'].append(mixin_name)
+ interfaces_info[interface_name]['including_mixins'].append(
+ mixin_name)
del interface_info['included_by_interfaces']
# An IDL file's dependencies are partial interface files that extend it,
# and files for other interfaces that this interfaces include.
- for interface_name, interface_info in interfaces_info.iteritems():
+ for interface_name, interface_info in interfaces_info.items():
partial_interface_paths = partial_interface_files[interface_name]
partial_interfaces_full_paths = partial_interface_paths['full_paths']
# Partial interface definitions each need an include, as they are
# implemented in separate classes from the main interface.
- partial_interfaces_include_paths = partial_interface_paths['include_paths']
+ partial_interfaces_include_paths = \
+ partial_interface_paths['include_paths']
mixins = interface_info['including_mixins']
try:
mixins_info = [interfaces_info[mixin] for mixin in mixins]
except KeyError as key_name:
- raise IdlInterfaceFileNotFoundError('Could not find the IDL file where the following mixin is defined: %s' % key_name)
- mixins_full_paths = [mixin_info['full_path'] for mixin_info in mixins_info]
+ raise IdlInterfaceFileNotFoundError(
+ 'Could not find the IDL file where the following mixin is defined: %s'
+ % key_name)
+ mixins_full_paths = [
+ mixin_info['full_path'] for mixin_info in mixins_info
+ ]
# Mixins don't need include files, as this is handled in the Blink
# implementation (they are implemented on |impl| itself, hence header
# declaration is included in the interface class).
@@ -258,7 +275,8 @@ def compute_interfaces_info_overall(info_individuals):
# https://crbug.com/360435
mixins_include_paths = [
mixin_info['include_path'] for mixin_info in mixins_info
- if mixin_info['is_legacy_treat_as_partial_interface']]
+ if mixin_info['is_legacy_treat_as_partial_interface']
+ ]
dependencies_full_paths = mixins_full_paths
dependencies_include_paths = mixins_include_paths
@@ -274,23 +292,26 @@ def compute_interfaces_info_overall(info_individuals):
dependencies_other_component_full_paths.append(full_path)
for include_path in partial_interfaces_include_paths:
- partial_interface_component = idl_filename_to_component(include_path)
+ partial_interface_component = idl_filename_to_component(
+ include_path)
if component == partial_interface_component:
dependencies_include_paths.append(include_path)
else:
dependencies_other_component_include_paths.append(include_path)
interface_info.update({
- 'dependencies_full_paths': dependencies_full_paths,
- 'dependencies_include_paths': dependencies_include_paths,
+ 'dependencies_full_paths':
+ dependencies_full_paths,
+ 'dependencies_include_paths':
+ dependencies_include_paths,
'dependencies_other_component_full_paths':
- dependencies_other_component_full_paths,
+ dependencies_other_component_full_paths,
'dependencies_other_component_include_paths':
- dependencies_other_component_include_paths,
+ dependencies_other_component_include_paths,
})
# Clean up temporary private information
- for interface_info in interfaces_info.itervalues():
+ for interface_info in interfaces_info.values():
del interface_info['extended_attributes']
del interface_info['union_types']
del interface_info['is_legacy_treat_as_partial_interface']
@@ -302,6 +323,7 @@ def compute_interfaces_info_overall(info_individuals):
################################################################################
+
def main():
_, args = parse_options()
# args = Input1, Input2, ..., Output
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 71bfb0383b4..51c66c38c5e 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.py
@@ -1,7 +1,6 @@
# 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.
-
"""
Runs the bindings code generator for the given tasks.
"""
@@ -9,22 +8,40 @@ Runs the bindings code generator for the given tasks.
import optparse
import sys
-import bind_gen
import web_idl
+import bind_gen
def parse_options():
parser = optparse.OptionParser(usage="%prog [options] TASK...")
- parser.add_option('--web_idl_database', type='string',
- help="filepath of the input database")
- parser.add_option('--output_dir_core', type='string',
- help="outout directory for 'core' component")
- parser.add_option('--output_dir_modules', type='string',
- help="outout directory for 'modules' component")
+ parser.add_option(
+ "--web_idl_database",
+ type="string",
+ help="filepath of the input database")
+ parser.add_option(
+ "--root_src_dir",
+ type="string",
+ help='root directory of chromium project, i.e. "//"')
+ parser.add_option(
+ "--root_gen_dir",
+ type="string",
+ help='root directory of generated code files, i.e. '
+ '"//out/Default/gen"')
+ parser.add_option(
+ "--output_core_reldir",
+ type="string",
+ help='output directory for "core" component relative to '
+ 'root_gen_dir')
+ parser.add_option(
+ "--output_modules_reldir",
+ type="string",
+ help='output directory for "modules" component relative '
+ 'to root_gen_dir')
options, args = parser.parse_args()
- required_option_names = (
- 'web_idl_database', 'output_dir_core', 'output_dir_modules')
+ required_option_names = ("web_idl_database", "root_src_dir",
+ "root_gen_dir", "output_core_reldir",
+ "output_modules_reldir")
for opt_name in required_option_names:
if getattr(options, opt_name) is None:
parser.error("--{} is a required option.".format(opt_name))
@@ -40,24 +57,29 @@ def main():
dispatch_table = {
'dictionary': bind_gen.generate_dictionaries,
+ 'enumeration': bind_gen.generate_enumerations,
'interface': bind_gen.generate_interfaces,
+ 'union': bind_gen.generate_unions,
}
for task in tasks:
if task not in dispatch_table:
sys.exit("Unknown task: {}".format(task))
- web_idl_database = web_idl.Database.read_from_file(options.web_idl_database)
- output_dirs = {
- web_idl.Component('core'): options.output_dir_core,
- web_idl.Component('modules'): options.output_dir_modules,
+ web_idl_database = web_idl.Database.read_from_file(
+ options.web_idl_database)
+ component_reldirs = {
+ web_idl.Component('core'): options.output_core_reldir,
+ web_idl.Component('modules'): options.output_modules_reldir,
}
- bind_gen.init(output_dirs)
+ bind_gen.init(
+ root_src_dir=options.root_src_dir,
+ root_gen_dir=options.root_gen_dir,
+ component_reldirs=component_reldirs)
for task in tasks:
- dispatch_table[task](web_idl_database=web_idl_database,
- output_dirs=output_dirs)
+ dispatch_table[task](web_idl_database=web_idl_database)
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 c4edf6a2c2a..e2b7256dbb0 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.pydeps
+++ b/chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.pydeps
@@ -10,7 +10,6 @@
../../../../mako/mako/ext/__init__.py
../../../../mako/mako/filters.py
../../../../mako/mako/lexer.py
-../../../../mako/mako/lookup.py
../../../../mako/mako/parsetree.py
../../../../mako/mako/pygen.py
../../../../mako/mako/pyparser.py
@@ -31,18 +30,21 @@
../../build/scripts/blinkbuild/name_style_converter.py
bind_gen/__init__.py
bind_gen/blink_v8_bridge.py
-bind_gen/clang_format.py
bind_gen/code_node.py
+bind_gen/code_node_cxx.py
bind_gen/codegen_accumulator.py
bind_gen/codegen_context.py
bind_gen/codegen_expr.py
bind_gen/codegen_format.py
bind_gen/codegen_utils.py
bind_gen/dictionary.py
+bind_gen/enumeration.py
bind_gen/interface.py
bind_gen/mako_renderer.py
bind_gen/name_style.py
bind_gen/path_manager.py
+bind_gen/style_format.py
+bind_gen/union.py
generate_bindings.py
web_idl/__init__.py
web_idl/argument.py
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/generate_event_interfaces.py b/chromium/third_party/blink/renderer/bindings/scripts/generate_event_interfaces.py
index 62cee43cf39..32120e11e65 100755
--- a/chromium/third_party/blink/renderer/bindings/scripts/generate_event_interfaces.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/generate_event_interfaces.py
@@ -27,7 +27,6 @@
# 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.
-
"""Generate event interfaces .json5 file (EventInterfaces.json5).
The event interfaces .json5 file contains a list of all Event interfaces, i.e.,
@@ -54,21 +53,29 @@ EXPORTED_EXTENDED_ATTRIBUTES = (
'RuntimeEnabled',
)
module_path = os.path.dirname(os.path.realpath(__file__))
-REPO_ROOT_DIR = os.path.normpath(os.path.join(module_path, os.pardir, os.pardir,
- os.pardir, os.pardir, os.pardir))
+REPO_ROOT_DIR = os.path.normpath(
+ os.path.join(module_path, os.pardir, os.pardir, os.pardir, os.pardir,
+ os.pardir))
def parse_options():
parser = OptionParser()
- parser.add_option('--event-idl-files-list', help='file listing event IDL files')
+ parser.add_option(
+ '--event-idl-files-list', help='file listing event IDL files')
parser.add_option('--event-interfaces-file', help='output file')
- parser.add_option('--suffix', help='specify a suffix to the namespace, i.e., "Modules". Default is None.')
+ parser.add_option(
+ '--suffix',
+ help=
+ 'specify a suffix to the namespace, i.e., "Modules". Default is None.')
options, args = parser.parse_args()
if options.event_idl_files_list is None:
- parser.error('Must specify a file listing event IDL files using --event-idl-files-list.')
+ parser.error(
+ 'Must specify a file listing event IDL files using --event-idl-files-list.'
+ )
if options.event_interfaces_file is None:
- parser.error('Must specify an output file using --event-interfaces-file.')
+ parser.error(
+ 'Must specify an output file using --event-interfaces-file.')
if args:
parser.error('No arguments allowed, but %d given.' % len(args))
return options
@@ -76,35 +83,30 @@ def parse_options():
def write_event_interfaces_file(event_idl_files, destination_filename, suffix):
def interface_line(full_path):
- relative_dir_local = os.path.dirname(os.path.relpath(full_path, REPO_ROOT_DIR))
+ relative_dir_local = os.path.dirname(
+ os.path.relpath(full_path, REPO_ROOT_DIR))
relative_dir_posix = relative_dir_local.replace(os.sep, posixpath.sep)
idl_file_contents = get_file_contents(full_path)
interface_name = get_first_interface_name_from_idl(idl_file_contents)
- extended_attributes = get_interface_extended_attributes_from_idl(idl_file_contents)
- extended_attributes_list = [
- (name, extended_attributes[name])
- for name in EXPORTED_EXTENDED_ATTRIBUTES
- if name in extended_attributes]
+ extended_attributes = get_interface_extended_attributes_from_idl(
+ idl_file_contents)
+ extended_attributes_list = [(name, extended_attributes[name])
+ for name in EXPORTED_EXTENDED_ATTRIBUTES
+ if name in extended_attributes]
return (relative_dir_posix, interface_name, extended_attributes_list)
- lines = [
- '{',
- 'metadata: {',
- ' namespace: "event_interface_names",'
- ]
+ lines = ['{', 'metadata: {', ' namespace: "event_interface_names",']
if suffix:
lines.append(' suffix: "' + suffix + '",')
lines.append(' export: "%s_EXPORT",' % suffix.upper())
else:
lines.append(' export: "CORE_EXPORT",')
- lines.extend([
- '},',
- 'data: ['
- ])
- interface_lines = [interface_line(event_idl_file)
- for event_idl_file in event_idl_files]
+ lines.extend(['},', 'data: ['])
+ interface_lines = [
+ interface_line(event_idl_file) for event_idl_file in event_idl_files
+ ]
interface_lines.sort()
for relative_dir, name, attributes in interface_lines:
lines.extend([
@@ -117,20 +119,17 @@ def write_event_interfaces_file(event_idl_files, destination_filename, suffix):
value += 'Enabled'
lines.append(' %s: "%s",' % (param, value))
lines.append(' },')
- lines.extend([
- ']',
- '}'
- ])
+ lines.extend([']', '}'])
write_file('\n'.join(lines), destination_filename)
################################################################################
+
def main():
options = parse_options()
event_idl_files = read_file_to_list(options.event_idl_files_list)
- write_event_interfaces_file(event_idl_files,
- options.event_interfaces_file,
+ write_event_interfaces_file(event_idl_files, options.event_interfaces_file,
options.suffix)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/generate_global_constructors.py b/chromium/third_party/blink/renderer/bindings/scripts/generate_global_constructors.py
index 57b677409ba..987f737caf2 100755
--- a/chromium/third_party/blink/renderer/bindings/scripts/generate_global_constructors.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/generate_global_constructors.py
@@ -3,7 +3,6 @@
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-
"""Generates interface properties on global objects.
Concretely these are implemented as "constructor attributes", meaning
@@ -41,22 +40,26 @@ from v8_utilities import EXPOSED_EXECUTION_CONTEXT_METHOD
interface_name_to_global_names = {}
global_name_to_constructors = defaultdict(list)
-
HEADER_FORMAT = """// Stub header file for {{idl_basename}}
-// Required because the IDL compiler assumes that a corresponding header file
-// exists for each IDL file.
+// Required because the IDL compiler assumes that a corresponding header
+// file exists for each IDL file.
"""
+
def parse_options():
parser = optparse.OptionParser()
parser.add_option('--idl-files-list', help='file listing IDL files')
- parser.add_option('--global-objects-file', help='pickle file of global objects')
+ parser.add_option(
+ '--global-objects-file', help='pickle file of global objects')
options, args = parser.parse_args()
if options.idl_files_list is None:
- parser.error('Must specify a file listing IDL files using --idl-files-list.')
+ parser.error(
+ 'Must specify a file listing IDL files using --idl-files-list.')
if options.global_objects_file is None:
- parser.error('Must specify a pickle file of global objects using --global-objects-file.')
+ parser.error(
+ 'Must specify a pickle file of global objects using --global-objects-file.'
+ )
return options, args
@@ -75,16 +78,17 @@ def interface_name_to_constructors(interface_name):
def record_global_constructors(idl_filename):
full_path = os.path.realpath(idl_filename)
idl_file_contents = get_file_contents(full_path)
- extended_attributes = get_interface_extended_attributes_from_idl(idl_file_contents)
+ extended_attributes = get_interface_extended_attributes_from_idl(
+ idl_file_contents)
interface_name = get_first_interface_name_from_idl(idl_file_contents)
# An interface property is produced for every non-callback interface
# that does not have [NoInterfaceObject].
# http://heycam.github.io/webidl/#es-interfaces
- if (not should_generate_impl_file_from_idl(idl_file_contents) or
- is_non_legacy_callback_interface_from_idl(idl_file_contents) or
- is_interface_mixin_from_idl(idl_file_contents) or
- 'NoInterfaceObject' in extended_attributes):
+ if (not should_generate_impl_file_from_idl(idl_file_contents)
+ or is_non_legacy_callback_interface_from_idl(idl_file_contents)
+ or is_interface_mixin_from_idl(idl_file_contents)
+ or 'NoInterfaceObject' in extended_attributes):
return
exposed_arguments = get_interface_exposed_arguments(idl_file_contents)
@@ -92,31 +96,40 @@ def record_global_constructors(idl_filename):
# Exposed(Arguments) case
for argument in exposed_arguments:
if 'RuntimeEnabled' in extended_attributes:
- raise ValueError('RuntimeEnabled should not be used with Exposed(Arguments)')
+ raise ValueError(
+ 'RuntimeEnabled should not be used with Exposed(Arguments)'
+ )
attributes = extended_attributes.copy()
attributes['RuntimeEnabled'] = argument['runtime_enabled']
- new_constructors_list = generate_global_constructors_list(interface_name, attributes)
- global_name_to_constructors[argument['exposed']].extend(new_constructors_list)
+ new_constructors_list = generate_global_constructors_list(
+ interface_name, attributes)
+ global_name_to_constructors[argument['exposed']].extend(
+ new_constructors_list)
else:
# Exposed=env or Exposed=(env1,...) case
exposed_value = extended_attributes.get('Exposed', 'Window')
- exposed_global_names = map(str.strip, exposed_value.strip('()').split(','))
- new_constructors_list = generate_global_constructors_list(interface_name, extended_attributes)
+ exposed_global_names = map(str.strip,
+ exposed_value.strip('()').split(','))
+ new_constructors_list = generate_global_constructors_list(
+ interface_name, extended_attributes)
for name in exposed_global_names:
global_name_to_constructors[name].extend(new_constructors_list)
def generate_global_constructors_list(interface_name, extended_attributes):
extended_attributes_list = [
- name + (('=' + extended_attributes[name]) if extended_attributes[name] else '')
- for name in 'RuntimeEnabled', 'ContextEnabled', 'SecureContext'
- if name in extended_attributes]
+ name + (('=' + extended_attributes[name])
+ if extended_attributes[name] else '')
+ for name in ['RuntimeEnabled', 'ContextEnabled', 'SecureContext']
+ if name in extended_attributes
+ ]
if extended_attributes_list:
extended_string = '[%s] ' % ', '.join(extended_attributes_list)
else:
extended_string = ''
- attribute_string = 'attribute {interface_name}Constructor {interface_name}'.format(interface_name=interface_name)
+ attribute_string = 'attribute {interface_name}Constructor {interface_name}'.format(
+ interface_name=interface_name)
attributes_list = [extended_string + attribute_string]
# In addition to the usual interface property, for every [NamedConstructor]
@@ -129,30 +142,36 @@ def generate_global_constructors_list(interface_name, extended_attributes):
constructor_name = re.sub(r'\(.*', '', named_constructor)
# Note the reduplicated 'ConstructorConstructor'
# FIXME: rename to NamedConstructor
- attribute_string = 'attribute %sConstructorConstructor %s' % (interface_name, constructor_name)
+ attribute_string = 'attribute %sConstructorConstructor %s' % (
+ interface_name, constructor_name)
attributes_list.append(extended_string + attribute_string)
return attributes_list
-def write_global_constructors_partial_interface(interface_name, idl_filename, constructor_attributes_list):
+def write_global_constructors_partial_interface(interface_name, idl_filename,
+ constructor_attributes_list):
idl_basename = os.path.basename(idl_filename)
basename = os.path.splitext(idl_basename)[0]
# FIXME: replace this with a simple Jinja template
- lines = (['[\n',
- ' ImplementedAs=%s\n' % basename,
- '] partial interface %s {\n' % interface_name] +
- [' %s;\n' % constructor_attribute
- # FIXME: sort by interface name (not first by extended attributes)
- for constructor_attribute in sorted(constructor_attributes_list)] +
- ['};\n'])
+ lines = ([
+ '[\n',
+ ' ImplementedAs=%s\n' % basename,
+ '] partial interface %s {\n' % interface_name
+ ] + [
+ ' %s;\n' % constructor_attribute
+ # FIXME: sort by interface name (not first by extended attributes)
+ for constructor_attribute in sorted(constructor_attributes_list)
+ ] + ['};\n'])
write_file(''.join(lines), idl_filename)
header_filename = os.path.splitext(idl_filename)[0] + '.h'
- write_file(HEADER_FORMAT.format(idl_basename=idl_basename), header_filename)
+ write_file(
+ HEADER_FORMAT.format(idl_basename=idl_basename), header_filename)
################################################################################
+
def main():
options, args = parse_options()
@@ -167,7 +186,8 @@ def main():
interface_name_idl_filename = [(args[i], args[i + 1])
for i in range(0, len(args), 2)]
- interface_name_to_global_names.update(read_pickle_file(options.global_objects_file))
+ interface_name_to_global_names.update(
+ read_pickle_file(options.global_objects_file))
for idl_filename in idl_files:
record_global_constructors(idl_filename)
@@ -176,7 +196,8 @@ def main():
known_global_names = EXPOSED_EXECUTION_CONTEXT_METHOD.keys()
exposed_global_names = frozenset(global_name_to_constructors)
if not exposed_global_names.issubset(known_global_names):
- unknown_global_names = exposed_global_names.difference(known_global_names)
+ unknown_global_names = exposed_global_names.difference(
+ known_global_names)
raise ValueError('The following global names were used in '
'[Exposed=xxx] but do not match any global names: %s'
% list(unknown_global_names))
@@ -185,8 +206,8 @@ def main():
# global interface.
for interface_name, idl_filename in interface_name_idl_filename:
constructors = interface_name_to_constructors(interface_name)
- write_global_constructors_partial_interface(
- interface_name, idl_filename, constructors)
+ write_global_constructors_partial_interface(interface_name,
+ idl_filename, constructors)
if __name__ == '__main__':
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/generate_high_entropy_list.py b/chromium/third_party/blink/renderer/bindings/scripts/generate_high_entropy_list.py
new file mode 100644
index 00000000000..a247e0032ac
--- /dev/null
+++ b/chromium/third_party/blink/renderer/bindings/scripts/generate_high_entropy_list.py
@@ -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.
+"""
+Generate of table of APIs and their attributes based on the WebIDL database.
+
+The columns of the table are as follows:
+
+ * interface : Name of interface.
+ * name : Member name. Will be empty for interfaces.
+ * entity_type : One of 'interface', 'namespace', 'const', 'attribute',
+ 'operation', 'constructor', 'stringifier', 'iterable',
+ 'maplike', 'setlike', 'dictionary'
+ * idl_type : Type of the object. For function-like entries, this is the
+ type of the return value. Note that the type is stripped
+ of nullable unions.
+ * syntactic_form : Human readable idl_type.
+ * use_counter : If usage is being measured, this is the UseCounter.
+ * secure_context : 'True' if the [SecureContext] extended attribute is
+ present. Empty otherwise.
+ * high_entropy : 'True' if the [HighEntropy] extended attribute is present.
+ Empty otherwise.
+"""
+
+import optparse
+from io import BytesIO
+from csv import DictWriter
+
+from utilities import write_file
+from v8_utilities import capitalize
+import web_idl
+
+
+def parse_options():
+ parser = optparse.OptionParser(usage="%prog [options]")
+ parser.add_option(
+ "--web_idl_database",
+ type="string",
+ help="filepath of the input database")
+ parser.add_option(
+ "--output", type="string", help="filepath of output file")
+ options, args = parser.parse_args()
+
+ required_option_names = ("web_idl_database", "output")
+ for opt_name in required_option_names:
+ if getattr(options, opt_name) is None:
+ parser.error("--{} is a required option.".format(opt_name))
+
+ return options, args
+
+
+def get_idl_type_name(idl_type):
+ assert isinstance(idl_type, web_idl.IdlType)
+ unwrapped_type = idl_type.unwrap()
+ return unwrapped_type.type_name, unwrapped_type.syntactic_form
+
+
+def true_or_nothing(v):
+ return 'True' if v else ''
+
+
+def record(csv_writer, entity):
+ interface = ''
+ name = ''
+ entity_type = ''
+ use_counter = ''
+ secure_context = ''
+ high_entropy = ''
+ idl_type = ''
+ syntactic_form = ''
+
+ secure_context = ('SecureContext' in entity.extended_attributes)
+ high_entropy = ('HighEntropy' in entity.extended_attributes)
+
+ if 'Measure' in entity.extended_attributes:
+ use_counter = capitalize(entity.identifier)
+ if not isinstance(entity, web_idl.Interface):
+ use_counter = (
+ capitalize(entity.owner.identifier) + '_' + use_counter)
+ elif 'MeasureAs' in entity.extended_attributes:
+ use_counter = entity.extended_attributes.value_of('MeasureAs')
+
+ if isinstance(entity, web_idl.Interface):
+ interface = entity.identifier
+ name = ''
+ entity_type = 'interface'
+ else:
+ interface = entity.owner.identifier
+ name = entity.identifier
+
+ if isinstance(entity, web_idl.Attribute):
+ entity_type = 'attribute'
+ idl_type, syntactic_form = get_idl_type_name(entity.idl_type)
+ elif isinstance(entity, web_idl.Operation):
+ entity_type = 'operation'
+ idl_type, syntactic_form = get_idl_type_name(entity.return_type)
+ elif isinstance(entity, web_idl.Constant):
+ entity_type = 'constant'
+ idl_type, syntactic_form = get_idl_type_name(entity.idl_type)
+ else:
+ assert False, "Unexpected IDL construct"
+ csv_writer.writerow({
+ 'interface': interface,
+ 'name': name,
+ 'entity_type': entity_type,
+ 'idl_type': idl_type,
+ 'syntactic_form': syntactic_form,
+ 'use_counter': use_counter,
+ 'secure_context': true_or_nothing(secure_context),
+ 'high_entropy': true_or_nothing(high_entropy)
+ })
+
+
+def main():
+ options, _ = parse_options()
+ with BytesIO() as out_buffer:
+ csv_writer = DictWriter(
+ out_buffer,
+ fieldnames=[
+ 'interface', 'name', 'entity_type', 'idl_type',
+ 'syntactic_form', 'use_counter', 'secure_context',
+ 'high_entropy'
+ ])
+ csv_writer.writeheader()
+
+ web_idl_database = web_idl.Database.read_from_file(
+ options.web_idl_database)
+ for interface in web_idl_database.interfaces:
+ record(csv_writer, interface)
+ for entity in (interface.attributes + interface.operations +
+ interface.constants):
+ record(csv_writer, entity)
+ write_file(out_buffer.getvalue(), options.output)
+
+
+if __name__ == '__main__':
+ main()
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
new file mode 100644
index 00000000000..1d9e7f3b75a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/bindings/scripts/generate_high_entropy_list.pydeps
@@ -0,0 +1,51 @@
+# 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
+generate_high_entropy_list.py
+idl_definitions.py
+idl_types.py
+utilities.py
+v8_globals.py
+v8_utilities.py
+web_idl/__init__.py
+web_idl/argument.py
+web_idl/ast_group.py
+web_idl/attribute.py
+web_idl/callback_function.py
+web_idl/callback_interface.py
+web_idl/code_generator_info.py
+web_idl/composition_parts.py
+web_idl/constant.py
+web_idl/constructor.py
+web_idl/database.py
+web_idl/database_builder.py
+web_idl/dictionary.py
+web_idl/enumeration.py
+web_idl/exposure.py
+web_idl/extended_attribute.py
+web_idl/file_io.py
+web_idl/function_like.py
+web_idl/idl_compiler.py
+web_idl/idl_type.py
+web_idl/includes.py
+web_idl/interface.py
+web_idl/ir_builder.py
+web_idl/ir_map.py
+web_idl/literal_constant.py
+web_idl/make_copy.py
+web_idl/namespace.py
+web_idl/operation.py
+web_idl/reference.py
+web_idl/runtime_enabled_features.py
+web_idl/typedef.py
+web_idl/union.py
+web_idl/user_defined_type.py
+web_idl/validator.py
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/generate_init_partial_interfaces.py b/chromium/third_party/blink/renderer/bindings/scripts/generate_init_partial_interfaces.py
index 0e44fe91b66..fca4d565c96 100755
--- a/chromium/third_party/blink/renderer/bindings/scripts/generate_init_partial_interfaces.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/generate_init_partial_interfaces.py
@@ -2,11 +2,14 @@
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-
-"""Generate initPartialInterfacesInModules(), which registers partial interfaces in modules to core interfaces."""
+"""Generate initPartialInterfacesInModules(), which registers partial
+interfaces in modules to core interfaces.
+"""
# pylint: disable=relative-import
+from __future__ import print_function
+
from optparse import OptionParser
import os
import posixpath
@@ -19,7 +22,6 @@ from utilities import should_generate_impl_file_from_idl
from utilities import write_file
from v8_utilities import build_basename
-
_COPYRIGHT = """// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -41,15 +43,18 @@ void InitPartialInterfacesInModules() {
def parse_options():
usage = 'Usage: %prog [options]'
parser = OptionParser(usage=usage)
- parser.add_option('--idl-files-list',
- help='a text file containing the IDL file paths, so the command line doesn\'t exceed OS length limits.')
+ parser.add_option(
+ '--idl-files-list',
+ help='a text file containing the IDL file paths, so the command '
+ 'line doesn\'t exceed OS length limits.')
parser.add_option('--output')
options, args = parser.parse_args()
if options.output is None:
parser.error('Must specify output file using --output.')
if options.idl_files_list is None:
- parser.error('Must specify a list of IDL files using --idl-files-list.')
+ parser.error(
+ 'Must specify a list of IDL files using --idl-files-list.')
return options
@@ -59,10 +64,10 @@ def extract_meta_data(file_paths):
for file_path in file_paths:
if not file_path.endswith('.idl'):
- print 'WARNING: non-IDL file passed: "%s"' % file_path
+ print('WARNING: non-IDL file passed: "%s"' % file_path)
continue
if not os.path.exists(file_path):
- print 'WARNING: file not found: "%s"' % file_path
+ print('WARNING: file not found: "%s"' % file_path)
continue
idl_file_contents = get_file_contents(file_path)
@@ -86,20 +91,22 @@ def main():
idl_file_names = read_idl_files_list_from_file(options.idl_files_list)
meta_data_list = extract_meta_data(idl_file_names)
- interface_names = ['V8%sPartial' % meta_data['basename']
- for meta_data in meta_data_list]
+ interface_names = [
+ 'V8%sPartial' % meta_data['basename'] for meta_data in meta_data_list
+ ]
interface_names.sort()
- includes = ['#include "third_party/blink/renderer/bindings/modules/v8/%s.h"' %
- build_basename(interface_name)
- for interface_name in interface_names]
- initialize_calls = [' %s::Initialize();' % interface_name
- for interface_name in interface_names]
-
- content = _INIT_PARTIAL_INTERFACE % (
- _COPYRIGHT,
- '\n'.join(includes),
- '\n'.join(initialize_calls))
+ includes = [
+ '#include "third_party/blink/renderer/bindings/modules/v8/%s.h"' %
+ build_basename(interface_name) for interface_name in interface_names
+ ]
+ initialize_calls = [
+ ' %s::Initialize();' % interface_name
+ for interface_name in interface_names
+ ]
+
+ content = _INIT_PARTIAL_INTERFACE % (_COPYRIGHT, '\n'.join(includes),
+ '\n'.join(initialize_calls))
write_file(content, options.output)
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 0ec3953411b..c2b40844ad1 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
@@ -25,9 +25,9 @@ from v8_utilities import (binding_header_filename, v8_class_name,
# Make sure extension is .py, not .pyc or .pyo, so doesn't depend on caching
MODULE_PYNAME = os.path.splitext(os.path.basename(__file__))[0] + '.py'
-
-OriginTrialInterfaceInfo = namedtuple('OriginTrialInterfaceInfo', [
- 'name', 'v8_class', 'v8_class_or_partial', 'is_global'])
+OriginTrialInterfaceInfo = namedtuple(
+ 'OriginTrialInterfaceInfo',
+ ['name', 'v8_class', 'v8_class_or_partial', 'is_global'])
def get_install_functions(interfaces, feature_names):
@@ -38,15 +38,14 @@ def get_install_functions(interfaces, feature_names):
feature_names is a list of strings, containing names of features which can
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}
- for feature_name in feature_names
- for interface_info in 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
+ } for feature_name in feature_names for interface_info in interfaces]
def get_origin_trial_feature_names_from_interface(interface, runtime_features):
@@ -78,7 +77,8 @@ def interface_is_global(interface):
return 'Global' in interface.extended_attributes
-def origin_trial_features_info(info_provider, reader, idl_filenames, target_component):
+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
the conditional features defined on them.
@@ -95,10 +95,13 @@ def origin_trial_features_info(info_provider, reader, idl_filenames, target_comp
for idl_filename in idl_filenames:
interface, includes = read_idl_file(reader, idl_filename)
- feature_names = get_origin_trial_feature_names_from_interface(interface, runtime_features)
+ feature_names = get_origin_trial_feature_names_from_interface(
+ interface, runtime_features)
# If this interface is a mixin, we don't generate V8 bindings code for
# it.
+ # TODO(crbug.com/1061995): This incorrectly ignores includes in the
+ # mixin idl like "SomeInterface includes MixinInterface".
if interface.is_mixin:
continue
@@ -109,7 +112,8 @@ def origin_trial_features_info(info_provider, reader, idl_filenames, target_comp
mixin, _ = read_idl_file(
reader,
info_provider.interfaces_info[include.mixin].get('full_path'))
- feature_names |= get_origin_trial_feature_names_from_interface(mixin, runtime_features)
+ feature_names |= get_origin_trial_feature_names_from_interface(
+ mixin, runtime_features)
feature_names = list(feature_names)
if feature_names:
@@ -118,28 +122,29 @@ def origin_trial_features_info(info_provider, reader, idl_filenames, target_comp
# For partial interfaces, we need to generate different
# |include_files| if the parent interface is in a different
# component.
- parent_interface_info = info_provider.interfaces_info[interface.name]
+ parent_interface_info = \
+ info_provider.interfaces_info[interface.name]
parent_interface, _ = read_idl_file(
reader, parent_interface_info.get('full_path'))
is_global = is_global or interface_is_global(parent_interface)
parent_component = idl_filename_to_component(
parent_interface_info.get('full_path'))
if interface.is_partial and target_component != parent_component:
- include_files.add('bindings/%s/v8/%s' %
- (parent_component, binding_header_filename(interface.name)))
- include_files.add('bindings/%s/v8/%s' %
- (target_component, binding_header_filename(interface.name + 'Partial')))
+ include_files.add('bindings/%s/v8/%s' % (
+ parent_component, binding_header_filename(interface.name)))
+ include_files.add(
+ 'bindings/%s/v8/%s' %
+ (target_component,
+ binding_header_filename(interface.name + 'Partial')))
else:
- include_files.add('bindings/%s/v8/%s' %
- (target_component, binding_header_filename(interface.name)))
+ include_files.add('bindings/%s/v8/%s' % (
+ target_component, binding_header_filename(interface.name)))
# If this is a partial interface in the same component as
# its parent, then treat it as a non-partial interface.
interface.is_partial = False
- interface_info = OriginTrialInterfaceInfo(interface.name,
- v8_class_name(interface),
- v8_class_name_or_partial(
- interface),
- is_global)
+ interface_info = OriginTrialInterfaceInfo(
+ interface.name, v8_class_name(interface),
+ v8_class_name_or_partial(interface), is_global)
for feature_name in feature_names:
features_for_type[interface_info].add(feature_name)
types_for_feature[feature_name].add(interface_info)
@@ -171,21 +176,28 @@ def origin_trial_features_context(generator_name, feature_info):
# For each interface, collect a list of bindings installation functions to
# call, organized by conditional feature.
- context['installers_by_interface'] = [
- {'name': interface_info.name,
- 'is_global': interface_info.is_global,
- 'v8_class': interface_info.v8_class,
- 'installers': get_install_functions([interface_info], feature_names)}
- for interface_info, feature_names in features_for_type.items()]
+ context['installers_by_interface'] = [{
+ 'name':
+ interface_info.name,
+ 'is_global':
+ interface_info.is_global,
+ 'v8_class':
+ interface_info.v8_class,
+ 'installers':
+ get_install_functions([interface_info], feature_names)
+ } for interface_info, feature_names in features_for_type.items()]
context['installers_by_interface'].sort(key=lambda x: x['name'])
# For each conditional feature, collect a list of bindings installation
# functions to call, organized by interface.
- context['installers_by_feature'] = [
- {'name': feature_name,
- 'name_constant': 'OriginTrialFeature::k%s' % feature_name,
- 'installers': get_install_functions(interfaces, [feature_name])}
- for feature_name, interfaces in types_for_feature.items()]
+ context['installers_by_feature'] = [{
+ 'name':
+ feature_name,
+ 'name_constant':
+ 'OriginTrialFeature::k%s' % feature_name,
+ 'installers':
+ get_install_functions(interfaces, [feature_name])
+ } for feature_name, interfaces in types_for_feature.items()]
context['installers_by_feature'].sort(key=lambda x: x['name'])
return context
@@ -193,14 +205,16 @@ def origin_trial_features_context(generator_name, feature_info):
def parse_options():
parser = optparse.OptionParser()
- parser.add_option('--cache-directory',
- help='cache directory, defaults to output directory')
+ parser.add_option(
+ '--cache-directory',
+ help='cache directory, defaults to output directory')
parser.add_option('--output-directory')
parser.add_option('--info-dir')
- parser.add_option('--target-component',
- type='choice',
- choices=['core', 'modules'],
- help='target component to generate code')
+ parser.add_option(
+ '--target-component',
+ type='choice',
+ choices=['core', 'modules'],
+ help='target component to generate code')
parser.add_option('--idl-files-list')
options, _ = parser.parse_args()
@@ -215,23 +229,25 @@ def generate_origin_trial_features(info_provider, options, idl_filenames):
# Extract the bidirectional mapping of conditional features <-> interfaces
# from the global info provider and the supplied list of IDL files.
- feature_info = origin_trial_features_info(info_provider,
- reader, idl_filenames,
- options.target_component)
+ feature_info = origin_trial_features_info(
+ info_provider, reader, idl_filenames, options.target_component)
# Convert that mapping into the context required for the Jinja2 templates.
- template_context = origin_trial_features_context(
- MODULE_PYNAME, feature_info)
+ template_context = origin_trial_features_context(MODULE_PYNAME,
+ feature_info)
file_basename = 'origin_trial_features_for_%s' % options.target_component
# Generate and write out the header file
- header_text = render_template(jinja_env.get_template(file_basename + '.h.tmpl'), template_context)
- header_path = posixpath.join(options.output_directory, file_basename + '.h')
+ header_text = render_template(
+ jinja_env.get_template(file_basename + '.h.tmpl'), template_context)
+ header_path = posixpath.join(options.output_directory,
+ file_basename + '.h')
write_file(header_text, header_path)
# Generate and write out the implementation file
- cpp_text = render_template(jinja_env.get_template(file_basename + '.cc.tmpl'), template_context)
+ cpp_text = render_template(
+ jinja_env.get_template(file_basename + '.cc.tmpl'), template_context)
cpp_path = posixpath.join(options.output_directory, file_basename + '.cc')
write_file(cpp_text, cpp_path)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/generate_v8_context_snapshot_external_references.py b/chromium/third_party/blink/renderer/bindings/scripts/generate_v8_context_snapshot_external_references.py
index 3fc8a81a152..4f23b299d0d 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/generate_v8_context_snapshot_external_references.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/generate_v8_context_snapshot_external_references.py
@@ -17,14 +17,14 @@ import v8_interface
import v8_types
import v8_utilities
-
INCLUDES = frozenset([
'third_party/blink/renderer/bindings/core/v8/generated_code_helper.h',
'third_party/blink/renderer/bindings/core/v8/v8_html_document.h',
'third_party/blink/renderer/bindings/core/v8/v8_initializer.h',
'third_party/blink/renderer/bindings/core/v8/v8_window.h',
'third_party/blink/renderer/platform/bindings/v8_object_constructor.h',
- 'v8/include/v8.h'])
+ 'v8/include/v8.h'
+])
TEMPLATE_FILE = 'external_reference_table.cc.tmpl'
@@ -39,22 +39,27 @@ SNAPSHOTTED_INTERFACES = frozenset([
def parse_args():
parser = argparse.ArgumentParser()
- parser.add_argument('--idl-files-list', type=str, required=True,
- help='file listing IDL files')
- parser.add_argument('--output', type=str, required=True,
- help='output file path')
- parser.add_argument('--info-dir', type=str, required=True,
- help='directory contains component info')
- parser.add_argument('--cache-dir', type=str, required=True,
- help='cache directory')
- parser.add_argument('--target-component', type=str, required=True,
- help='target component')
+ parser.add_argument(
+ '--idl-files-list',
+ type=str,
+ required=True,
+ help='file listing IDL files')
+ parser.add_argument(
+ '--output', type=str, required=True, help='output file path')
+ parser.add_argument(
+ '--info-dir',
+ type=str,
+ required=True,
+ help='directory contains component info')
+ parser.add_argument(
+ '--cache-dir', type=str, required=True, help='cache directory')
+ parser.add_argument(
+ '--target-component', type=str, required=True, help='target component')
return parser.parse_known_args()
# This class creates a Jinja template context about an interface.
class InterfaceTemplateContextBuilder(object):
-
def __init__(self, opts, info_provider):
self._opts = opts
self._info_provider = info_provider
@@ -64,12 +69,14 @@ class InterfaceTemplateContextBuilder(object):
assert component in ['core', 'modules']
- name = '%s%s' % (v8_utilities.cpp_name(interface), 'Partial' if interface.is_partial else '')
+ name = '%s%s' % (v8_utilities.cpp_name(interface),
+ 'Partial' if interface.is_partial else '')
# Constructors
has_constructor_callback = False
if not interface.is_partial:
- constructors = any(constructor.name == 'Constructor' for constructor in interface.constructors)
+ constructors = any(constructor.name == 'Constructor'
+ for constructor in interface.constructors)
custom_constructors = interface.custom_constructors
html_constructor = 'HTMLConstructor' in interface.extended_attributes
has_constructor_callback = constructors or custom_constructors or html_constructor
@@ -86,9 +93,13 @@ class InterfaceTemplateContextBuilder(object):
named_property_getter = None
component_info = self._info_provider.component_info
if interface.name in SNAPSHOTTED_INTERFACES:
- attributes = [v8_attributes.attribute_context(interface, attribute, interfaces, component_info)
- for attribute in interface.attributes]
- methods = v8_interface.methods_context(interface, component_info)['methods']
+ attributes = [
+ v8_attributes.attribute_context(interface, attribute,
+ interfaces, component_info)
+ for attribute in interface.attributes
+ ]
+ methods = v8_interface.methods_context(interface,
+ component_info)['methods']
is_global = 'Global' in interface.extended_attributes
named_property_getter = v8_interface.property_getter(
@@ -97,37 +108,68 @@ class InterfaceTemplateContextBuilder(object):
interface.indexed_property_getter, ['index'])
if not interface.is_partial:
- has_security_check = ('CheckSecurity' in interface.extended_attributes and
- interface.name != 'EventTarget')
- has_cross_origin_named_getter = (any(method['is_cross_origin'] for method in methods) or
- any(attribute['has_cross_origin_getter'] for attribute in attributes))
- has_cross_origin_named_setter = any(attribute['has_cross_origin_setter'] for attribute in attributes)
- has_cross_origin_indexed_getter = indexed_property_getter and indexed_property_getter['is_cross_origin']
- has_cross_origin_named_enum = has_cross_origin_named_getter or has_cross_origin_named_setter
- if named_property_getter and named_property_getter['is_cross_origin']:
+ has_security_check = (
+ 'CheckSecurity' in interface.extended_attributes
+ and interface.name != 'EventTarget')
+ has_cross_origin_named_getter = (
+ any(method['is_cross_origin'] for method in methods)
+ or any(attribute['has_cross_origin_getter']
+ for attribute in attributes))
+ has_cross_origin_named_setter = any(
+ attribute['has_cross_origin_setter']
+ for attribute in attributes)
+ has_cross_origin_indexed_getter = (
+ indexed_property_getter
+ and indexed_property_getter['is_cross_origin'])
+ has_cross_origin_named_enum = has_cross_origin_named_getter \
+ or has_cross_origin_named_setter
+ if (named_property_getter
+ and named_property_getter['is_cross_origin']):
has_cross_origin_named_getter = True
return {
- 'attributes': attributes,
- 'component': component,
- 'has_constructor_callback': has_constructor_callback,
- 'has_cross_origin_named_getter': has_cross_origin_named_getter,
- 'has_cross_origin_named_setter': has_cross_origin_named_setter,
- 'has_cross_origin_named_enumerator': has_cross_origin_named_enum,
- 'has_cross_origin_indexed_getter': has_cross_origin_indexed_getter,
- 'has_security_check': has_security_check,
- 'indexed_property_getter': indexed_property_getter,
- 'indexed_property_setter': v8_interface.property_setter(interface.indexed_property_setter, interface),
- 'indexed_property_deleter': v8_interface.property_deleter(interface.indexed_property_deleter),
- 'internal_namespace': v8_interface.internal_namespace(interface),
- 'is_partial': interface.is_partial,
- 'methods': methods,
- 'name': name,
- 'named_constructor': v8_interface.named_constructor_context(interface),
- 'named_property_getter': named_property_getter,
- 'named_property_setter': v8_interface.property_setter(interface.named_property_setter, interface),
- 'named_property_deleter': v8_interface.property_deleter(interface.named_property_deleter),
- 'v8_class': v8_utilities.v8_class_name_or_partial(interface),
+ 'attributes':
+ attributes,
+ 'component':
+ component,
+ 'has_constructor_callback':
+ has_constructor_callback,
+ 'has_cross_origin_named_getter':
+ has_cross_origin_named_getter,
+ 'has_cross_origin_named_setter':
+ has_cross_origin_named_setter,
+ 'has_cross_origin_named_enumerator':
+ has_cross_origin_named_enum,
+ 'has_cross_origin_indexed_getter':
+ has_cross_origin_indexed_getter,
+ 'has_security_check':
+ has_security_check,
+ 'indexed_property_getter':
+ indexed_property_getter,
+ 'indexed_property_setter':
+ v8_interface.property_setter(interface.indexed_property_setter,
+ interface),
+ 'indexed_property_deleter':
+ v8_interface.property_deleter(interface.indexed_property_deleter),
+ 'internal_namespace':
+ v8_interface.internal_namespace(interface),
+ 'is_partial':
+ interface.is_partial,
+ 'methods':
+ methods,
+ 'name':
+ name,
+ 'named_constructor':
+ v8_interface.named_constructor_context(interface),
+ 'named_property_getter':
+ named_property_getter,
+ 'named_property_setter':
+ v8_interface.property_setter(interface.named_property_setter,
+ interface),
+ 'named_property_deleter':
+ v8_interface.property_deleter(interface.named_property_deleter),
+ 'v8_class':
+ v8_utilities.v8_class_name_or_partial(interface),
}
@@ -136,11 +178,11 @@ class ExternalReferenceTableGenerator(object):
def __init__(self, opts, info_provider):
self._opts = opts
self._info_provider = info_provider
- self._reader = IdlReader(
- info_provider.interfaces_info, opts.cache_dir)
+ self._reader = IdlReader(info_provider.interfaces_info, opts.cache_dir)
self._interface_contexts = {}
self._include_files = set(INCLUDES)
- v8_types.set_component_dirs(info_provider.interfaces_info['component_dirs'])
+ v8_types.set_component_dirs(
+ info_provider.interfaces_info['component_dirs'])
# Creates a Jinja context from an IDL file.
def process_idl_file(self, idl_filename):
@@ -162,19 +204,25 @@ class ExternalReferenceTableGenerator(object):
# Non legacy callback interface does not provide V8 callbacks.
if interface.is_callback:
return len(interface.constants) > 0
- if v8_utilities.runtime_enabled_feature_name(interface, runtime_features):
+ if v8_utilities.runtime_enabled_feature_name(
+ interface, runtime_features):
return False
if 'Exposed' not in interface.extended_attributes:
return True
- return any(exposure.exposed == 'Window' and exposure.runtime_enabled is None
- for exposure in interface.extended_attributes['Exposed'])
+ return any(
+ exposure.exposed == 'Window'
+ and exposure.runtime_enabled is None
+ for exposure in interface.extended_attributes['Exposed'])
if not has_impl(interface):
return
- context_builder = InterfaceTemplateContextBuilder(self._opts, self._info_provider)
- context = context_builder.create_interface_context(interface, component, interfaces)
- name = '%s%s' % (interface.name, 'Partial' if interface.is_partial else '')
+ context_builder = InterfaceTemplateContextBuilder(
+ self._opts, self._info_provider)
+ context = context_builder.create_interface_context(
+ interface, component, interfaces)
+ name = '%s%s' % (interface.name,
+ 'Partial' if interface.is_partial else '')
self._interface_contexts[name] = context
# Do not include unnecessary header files.
@@ -213,8 +261,8 @@ class ExternalReferenceTableGenerator(object):
def main():
opts, _ = parse_args()
# TODO(peria): get rid of |info_provider|
- info_provider = create_component_info_provider(
- opts.info_dir, opts.target_component)
+ info_provider = create_component_info_provider(opts.info_dir,
+ opts.target_component)
generator = ExternalReferenceTableGenerator(opts, info_provider)
idl_files = utilities.read_idl_files_list_from_file(opts.idl_files_list)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/idl_compiler.py b/chromium/third_party/blink/renderer/bindings/scripts/idl_compiler.py
index d4f4f54ecd4..94ba1bd4750 100755
--- a/chromium/third_party/blink/renderer/bindings/scripts/idl_compiler.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/idl_compiler.py
@@ -26,7 +26,6 @@
# 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.
-
"""Compile an .idl file to Blink V8 bindings (.h and .cpp files).
Design doc: https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/bindings/IDLCompiler.md
@@ -49,22 +48,23 @@ from utilities import write_file
def parse_options():
parser = OptionParser()
- parser.add_option('--cache-directory',
- help='cache directory, defaults to output directory')
- parser.add_option('--generate-impl',
- action='store_true', default=False)
- parser.add_option('--read-idl-list-from-file',
- action='store_true', default=False)
+ parser.add_option(
+ '--cache-directory',
+ help='cache directory, defaults to output directory')
+ parser.add_option('--generate-impl', action='store_true', default=False)
+ parser.add_option(
+ '--read-idl-list-from-file', action='store_true', default=False)
parser.add_option('--output-directory')
parser.add_option('--impl-output-directory')
parser.add_option('--info-dir')
# FIXME: We should always explicitly specify --target-component and
# remove the default behavior.
- parser.add_option('--target-component',
- type='choice',
- choices=['core', 'modules'],
- help='target component to generate code, defaults to '
- 'component of input idl file')
+ parser.add_option(
+ '--target-component',
+ type='choice',
+ choices=['core', 'modules'],
+ help='target component to generate code, defaults to '
+ 'component of input idl file')
# ensure output comes last, so command line easy to parse via regexes
parser.disable_interspersed_args()
@@ -72,7 +72,9 @@ def parse_options():
if options.output_directory is None:
parser.error('Must specify output directory using --output-directory.')
if len(args) != 1:
- parser.error('Must specify exactly 1 input file as argument, but %d given.' % len(args))
+ parser.error(
+ 'Must specify exactly 1 input file as argument, but %d given.' %
+ len(args))
idl_filename = os.path.realpath(args[0])
return options, idl_filename
@@ -83,8 +85,11 @@ class IdlCompiler(object):
"""
__metaclass__ = abc.ABCMeta
- def __init__(self, output_directory, cache_directory=None,
- code_generator_class=None, info_provider=None,
+ def __init__(self,
+ output_directory,
+ cache_directory=None,
+ code_generator_class=None,
+ info_provider=None,
target_component=None):
"""
Args:
@@ -99,9 +104,8 @@ class IdlCompiler(object):
self.output_directory = output_directory
self.target_component = target_component
self.reader = IdlReader(info_provider.interfaces_info, cache_directory)
- self.code_generator = code_generator_class(self.info_provider,
- self.cache_directory,
- self.output_directory)
+ self.code_generator = code_generator_class(
+ self.info_provider, self.cache_directory, self.output_directory)
def compile_and_write(self, idl_filename):
definitions = self.reader.read_idl_definitions(idl_filename)
@@ -149,11 +153,9 @@ def generate_dictionary_impl(code_generator_class, info_provider, options,
def generate_union_type_containers(code_generator_class, info_provider,
options):
- generator = code_generator_class(
- info_provider,
- options.cache_directory,
- options.output_directory,
- options.target_component)
+ generator = code_generator_class(info_provider, options.cache_directory,
+ options.output_directory,
+ options.target_component)
output_code_list = generator.generate_code()
for output_path, output_code in output_code_list:
write_file(output_code, output_path)
@@ -161,11 +163,9 @@ def generate_union_type_containers(code_generator_class, info_provider,
def generate_callback_function_impl(code_generator_class, info_provider,
options):
- generator = code_generator_class(
- info_provider,
- options.cache_directory,
- options.output_directory,
- options.target_component)
+ generator = code_generator_class(info_provider, options.cache_directory,
+ options.output_directory,
+ options.target_component)
output_code_list = generator.generate_code()
for output_path, output_code in output_code_list:
write_file(output_code, output_path)
@@ -173,8 +173,8 @@ def generate_callback_function_impl(code_generator_class, info_provider,
def main():
options, input_filename = parse_options()
- info_provider = create_component_info_provider(
- options.info_dir, options.target_component)
+ info_provider = create_component_info_provider(options.info_dir,
+ options.target_component)
if options.generate_impl or options.read_idl_list_from_file:
# |input_filename| should be a file which contains a list of IDL
# dictionary paths.
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 27c6b032902..11f6846eef2 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/idl_definitions.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/idl_definitions.py
@@ -27,7 +27,6 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# pylint: disable=relative-import
-
"""Blink IDL Intermediate Representation (IR) classes.
Classes are primarily constructors, which build an IdlDefinitions object
@@ -73,11 +72,11 @@ from idl_types import IdlUnionType
SPECIAL_KEYWORD_LIST = ['GETTER', 'SETTER', 'DELETER']
-
################################################################################
# TypedObject
################################################################################
+
class TypedObject(object):
"""Object with a type, such as an Attribute or Operation (return value).
@@ -85,13 +84,14 @@ class TypedObject(object):
by the TypedefResolver before passing data to the code generator.
"""
__metaclass__ = abc.ABCMeta
- idl_type_attributes = ('idl_type',)
+ idl_type_attributes = ('idl_type', )
################################################################################
# Definitions (main container class)
################################################################################
+
class IdlDefinitions(object):
def __init__(self, node):
"""Args: node: AST root node, class == 'File'"""
@@ -123,7 +123,8 @@ class IdlDefinitions(object):
self.enumerations[enumeration.name] = enumeration
elif child_class == 'Callback':
callback_function = IdlCallbackFunction(child)
- self.callback_functions[callback_function.name] = callback_function
+ self.callback_functions[callback_function.
+ name] = callback_function
elif child_class == 'Includes':
self.includes.append(IdlIncludes(child))
elif child_class == 'Dictionary':
@@ -136,22 +137,22 @@ class IdlDefinitions(object):
def accept(self, visitor):
visitor.visit_definitions(self)
- for interface in self.interfaces.itervalues():
+ for interface in self.interfaces.values():
interface.accept(visitor)
- for callback_function in self.callback_functions.itervalues():
+ for callback_function in self.callback_functions.values():
callback_function.accept(visitor)
- for dictionary in self.dictionaries.itervalues():
+ for dictionary in self.dictionaries.values():
dictionary.accept(visitor)
- for enumeration in self.enumerations.itervalues():
+ for enumeration in self.enumerations.values():
enumeration.accept(visitor)
for include in self.includes:
include.accept(visitor)
- for typedef in self.typedefs.itervalues():
+ for typedef in self.typedefs.values():
typedef.accept(visitor)
def update(self, other):
"""Update with additional IdlDefinitions."""
- for interface_name, new_interface in other.interfaces.iteritems():
+ for interface_name, new_interface in other.interfaces.items():
if not new_interface.is_partial:
# Add as new interface
self.interfaces[interface_name] = new_interface
@@ -162,8 +163,8 @@ class IdlDefinitions(object):
self.interfaces[interface_name].merge(new_interface)
except KeyError:
raise Exception('Tried to merge partial interface for {0}, '
- 'but no existing interface by that name'
- .format(interface_name))
+ 'but no existing interface by that name'.
+ format(interface_name))
# Merge callbacks and enumerations
self.enumerations.update(other.enumerations)
@@ -174,6 +175,7 @@ class IdlDefinitions(object):
# Callback Functions
################################################################################
+
class IdlCallbackFunction(TypedObject):
def __init__(self, node):
children = node.GetChildren()
@@ -185,12 +187,14 @@ class IdlCallbackFunction(TypedObject):
if num_children == 3:
ext_attributes_node = children[2]
self.extended_attributes = (
- ext_attributes_node_to_extended_attributes(ext_attributes_node))
+ ext_attributes_node_to_extended_attributes(ext_attributes_node)
+ )
else:
self.extended_attributes = {}
arguments_node_class = arguments_node.GetClass()
if arguments_node_class != 'Arguments':
- raise ValueError('Expected Arguments node, got %s' % arguments_node_class)
+ raise ValueError(
+ 'Expected Arguments node, got %s' % arguments_node_class)
self.name = node.GetName()
self.idl_type = type_node_to_type(type_node)
@@ -206,6 +210,7 @@ class IdlCallbackFunction(TypedObject):
# Dictionary
################################################################################
+
class IdlDictionary(object):
def __init__(self, node):
self.extended_attributes = {}
@@ -258,6 +263,7 @@ class IdlDictionaryMember(TypedObject):
# Enumerations
################################################################################
+
class IdlEnum(object):
def __init__(self, node):
self.name = node.GetName()
@@ -273,8 +279,9 @@ class IdlEnum(object):
# Typedefs
################################################################################
+
class IdlTypedef(object):
- idl_type_attributes = ('idl_type',)
+ idl_type_attributes = ('idl_type', )
def __init__(self, node):
self.name = node.GetName()
@@ -288,6 +295,7 @@ class IdlTypedef(object):
# Interfaces
################################################################################
+
class IdlInterface(object):
def __init__(self, node):
self.attributes = []
@@ -315,6 +323,14 @@ class IdlInterface(object):
has_indexed_property_getter = False
has_integer_typed_length = False
+ # These are used to support both constructor operations and old style
+ # [Constructor] extended attributes. Ideally we should do refactoring
+ # for constructor code generation but we will use a new code generator
+ # soon so this kind of workaround should be fine.
+ constructor_operations = []
+ custom_constructor_operations = []
+ constructor_operations_extended_attributes = {}
+
def is_blacklisted_attribute_type(idl_type):
return idl_type.is_callback_function or \
idl_type.is_dictionary or \
@@ -327,14 +343,17 @@ class IdlInterface(object):
if child_class == 'Attribute':
attr = IdlAttribute(child)
if is_blacklisted_attribute_type(attr.idl_type):
- raise ValueError('Type "%s" cannot be used as an attribute.' % attr.idl_type)
+ raise ValueError(
+ 'Type "%s" cannot be used as an attribute.' %
+ attr.idl_type)
if attr.idl_type.is_integer_type and attr.name == 'length':
has_integer_typed_length = True
self.attributes.append(attr)
elif child_class == 'Const':
self.constants.append(IdlConstant(child))
elif child_class == 'ExtAttributes':
- extended_attributes = ext_attributes_node_to_extended_attributes(child)
+ extended_attributes = ext_attributes_node_to_extended_attributes(
+ child)
self.constructors, self.custom_constructors = (
extended_attributes_to_constructors(extended_attributes))
clear_constructor_attributes(extended_attributes)
@@ -347,6 +366,20 @@ class IdlInterface(object):
elif str(op.arguments[0].idl_type) == 'DOMString':
self.has_named_property_getter = True
self.operations.append(op)
+ elif child_class == 'Constructor':
+ operation = constructor_operation_from_node(child)
+ if operation.is_custom:
+ custom_constructor_operations.append(operation.constructor)
+ else:
+ # Check extended attributes consistency when we previously
+ # handle constructor operations.
+ if constructor_operations:
+ check_constructor_operations_extended_attributes(
+ constructor_operations_extended_attributes,
+ operation.extended_attributes)
+ constructor_operations.append(operation.constructor)
+ constructor_operations_extended_attributes.update(
+ operation.extended_attributes)
elif child_class == 'Inherit':
self.parent = child.GetName()
elif child_class == 'Stringifier':
@@ -362,7 +395,9 @@ class IdlInterface(object):
raise ValueError('Unrecognized node class: %s' % child_class)
if len(filter(None, [self.iterable, self.maplike, self.setlike])) > 1:
- raise ValueError('Interface can only have one of iterable<>, maplike<> and setlike<>.')
+ raise ValueError(
+ 'Interface can only have one of iterable<>, maplike<> and setlike<>.'
+ )
# TODO(rakuco): This validation logic should be in v8_interface according to bashi@.
# At the moment, doing so does not work because several IDL files are partial Window
@@ -370,19 +405,39 @@ class IdlInterface(object):
# to prevent these partial interfaces from resetting has_named_property to False.
if 'LegacyUnenumerableNamedProperties' in self.extended_attributes and \
not self.has_named_property_getter:
- raise ValueError('[LegacyUnenumerableNamedProperties] can be used only in interfaces '
- 'that support named properties.')
+ raise ValueError(
+ '[LegacyUnenumerableNamedProperties] can be used only in interfaces '
+ 'that support named properties.')
if has_integer_typed_length and has_indexed_property_getter:
self.has_indexed_elements = True
else:
if self.iterable is not None and self.iterable.key_type is None:
- raise ValueError('Value iterators (iterable<V>) must be accompanied by an indexed '
- 'property getter and an integer-typed length attribute.')
+ raise ValueError(
+ 'Value iterators (iterable<V>) must be accompanied by an indexed '
+ 'property getter and an integer-typed length attribute.')
if 'Unforgeable' in self.extended_attributes:
raise ValueError('[Unforgeable] cannot appear on interfaces.')
+ if constructor_operations or custom_constructor_operations:
+ if self.constructors or self.custom_constructors:
+ raise ValueError('Detected mixed [Constructor] and consructor '
+ 'operations. Do not use both in a single '
+ 'interface.')
+ extended_attributes = (
+ convert_constructor_operations_extended_attributes(
+ constructor_operations_extended_attributes))
+ if any(name in extended_attributes.keys()
+ for name in self.extended_attributes.keys()):
+ raise ValueError('Detected mixed extended attributes for '
+ 'both [Constructor] and constructor '
+ 'operations. Do not use both in a single '
+ 'interface')
+ self.constructors = constructor_operations
+ self.custom_constructors = custom_constructor_operations
+ self.extended_attributes.update(extended_attributes)
+
def accept(self, visitor):
visitor.visit_interface(self)
for attribute in self.attributes:
@@ -423,9 +478,11 @@ class IdlInterface(object):
# Attributes
################################################################################
+
class IdlAttribute(TypedObject):
def __init__(self, node=None):
- self.is_read_only = bool(node.GetProperty('READONLY')) if node else False
+ self.is_read_only = bool(
+ node.GetProperty('READONLY')) if node else False
self.is_static = bool(node.GetProperty('STATIC')) if node else False
self.name = node.GetName() if node else None
self.idl_type = None
@@ -441,12 +498,15 @@ class IdlAttribute(TypedObject):
if child_class == 'Type':
self.idl_type = type_node_to_type(child)
elif child_class == 'ExtAttributes':
- self.extended_attributes = ext_attributes_node_to_extended_attributes(child)
+ self.extended_attributes = ext_attributes_node_to_extended_attributes(
+ child)
else:
- raise ValueError('Unrecognized node class: %s' % child_class)
+ raise ValueError(
+ 'Unrecognized node class: %s' % child_class)
if 'Unforgeable' in self.extended_attributes and self.is_static:
- raise ValueError('[Unforgeable] cannot appear on static attributes.')
+ raise ValueError(
+ '[Unforgeable] cannot appear on static attributes.')
def accept(self, visitor):
visitor.visit_attribute(self)
@@ -456,6 +516,7 @@ class IdlAttribute(TypedObject):
# Constants
################################################################################
+
class IdlConstant(TypedObject):
def __init__(self, node):
children = node.GetChildren()
@@ -479,7 +540,8 @@ class IdlConstant(TypedObject):
if num_children == 3:
ext_attributes_node = children[2]
- self.extended_attributes = ext_attributes_node_to_extended_attributes(ext_attributes_node)
+ self.extended_attributes = ext_attributes_node_to_extended_attributes(
+ ext_attributes_node)
else:
self.extended_attributes = {}
@@ -491,6 +553,7 @@ class IdlConstant(TypedObject):
# Literals
################################################################################
+
class IdlLiteral(object):
def __init__(self, idl_type, value):
self.idl_type = idl_type
@@ -548,6 +611,7 @@ def default_node_to_idl_literal(node):
# Operations
################################################################################
+
class IdlOperation(TypedObject):
def __init__(self, node=None):
self.arguments = []
@@ -579,12 +643,14 @@ class IdlOperation(TypedObject):
elif child_class == 'Type':
self.idl_type = type_node_to_type(child)
elif child_class == 'ExtAttributes':
- self.extended_attributes = ext_attributes_node_to_extended_attributes(child)
+ self.extended_attributes = ext_attributes_node_to_extended_attributes(
+ child)
else:
raise ValueError('Unrecognized node class: %s' % child_class)
if 'Unforgeable' in self.extended_attributes and self.is_static:
- raise ValueError('[Unforgeable] cannot appear on static operations.')
+ raise ValueError(
+ '[Unforgeable] cannot appear on static operations.')
@classmethod
def constructor_from_arguments_node(cls, name, arguments_node):
@@ -604,6 +670,7 @@ class IdlOperation(TypedObject):
# Arguments
################################################################################
+
class IdlArgument(TypedObject):
def __init__(self, node=None):
self.extended_attributes = {}
@@ -624,11 +691,14 @@ class IdlArgument(TypedObject):
if child_class == 'Type':
self.idl_type = type_node_to_type(child)
elif child_class == 'ExtAttributes':
- self.extended_attributes = ext_attributes_node_to_extended_attributes(child)
+ self.extended_attributes = ext_attributes_node_to_extended_attributes(
+ child)
elif child_class == 'Argument':
child_name = child.GetName()
if child_name != '...':
- raise ValueError('Unrecognized Argument node; expected "...", got "%s"' % child_name)
+ raise ValueError(
+ 'Unrecognized Argument node; expected "...", got "%s"'
+ % child_name)
self.is_variadic = bool(child.GetProperty('ELLIPSIS'))
elif child_class == 'Default':
self.default_value = default_node_to_idl_literal(child)
@@ -653,6 +723,7 @@ def arguments_node_to_arguments(node):
# Stringifiers
################################################################################
+
class IdlStringifier(object):
def __init__(self, node):
self.attribute = None
@@ -668,7 +739,8 @@ class IdlStringifier(object):
if operation.name:
self.operation = operation
elif child_class == 'ExtAttributes':
- self.extended_attributes = ext_attributes_node_to_extended_attributes(child)
+ self.extended_attributes = ext_attributes_node_to_extended_attributes(
+ child)
else:
raise ValueError('Unrecognized node class: %s' % child_class)
@@ -683,6 +755,7 @@ class IdlStringifier(object):
# Iterable, Maplike, Setlike
################################################################################
+
class IdlIterableOrMaplikeOrSetlike(TypedObject):
def __init__(self, node):
self.extended_attributes = {}
@@ -691,7 +764,8 @@ class IdlIterableOrMaplikeOrSetlike(TypedObject):
for child in node.GetChildren():
child_class = child.GetClass()
if child_class == 'ExtAttributes':
- self.extended_attributes = ext_attributes_node_to_extended_attributes(child)
+ self.extended_attributes = ext_attributes_node_to_extended_attributes(
+ child)
elif child_class == 'Type':
self.type_children.append(child)
else:
@@ -711,7 +785,8 @@ class IdlIterable(IdlIterableOrMaplikeOrSetlike):
self.key_type = type_node_to_type(self.type_children[0])
self.value_type = type_node_to_type(self.type_children[1])
else:
- raise ValueError('Unexpected number of type children: %d' % len(self.type_children))
+ raise ValueError('Unexpected number of type children: %d' % len(
+ self.type_children))
del self.type_children
def accept(self, visitor):
@@ -730,7 +805,8 @@ class IdlMaplike(IdlIterableOrMaplikeOrSetlike):
self.key_type = type_node_to_type(self.type_children[0])
self.value_type = type_node_to_type(self.type_children[1])
else:
- raise ValueError('Unexpected number of children: %d' % len(self.type_children))
+ raise ValueError(
+ 'Unexpected number of children: %d' % len(self.type_children))
del self.type_children
def accept(self, visitor):
@@ -738,7 +814,7 @@ class IdlMaplike(IdlIterableOrMaplikeOrSetlike):
class IdlSetlike(IdlIterableOrMaplikeOrSetlike):
- idl_type_attributes = ('value_type',)
+ idl_type_attributes = ('value_type', )
def __init__(self, node):
super(IdlSetlike, self).__init__(node)
@@ -748,7 +824,8 @@ class IdlSetlike(IdlIterableOrMaplikeOrSetlike):
if len(self.type_children) == 1:
self.value_type = type_node_to_type(self.type_children[0])
else:
- raise ValueError('Unexpected number of children: %d' % len(self.type_children))
+ raise ValueError(
+ 'Unexpected number of children: %d' % len(self.type_children))
del self.type_children
def accept(self, visitor):
@@ -759,6 +836,7 @@ class IdlSetlike(IdlIterableOrMaplikeOrSetlike):
# Includes statements
################################################################################
+
class IdlIncludes(object):
def __init__(self, node):
self.interface = node.GetName()
@@ -772,12 +850,14 @@ class IdlIncludes(object):
# Extended attributes
################################################################################
+
class Exposure:
"""An Exposure holds one Exposed or RuntimeEnabled condition.
Each exposure has two properties: exposed and runtime_enabled.
Exposure(e, r) corresponds to [Exposed(e r)]. Exposure(e) corresponds to
[Exposed=e].
"""
+
def __init__(self, exposed, runtime_enabled=None):
self.exposed = exposed
self.runtime_enabled = runtime_enabled
@@ -801,8 +881,7 @@ def ext_attributes_node_to_extended_attributes(node):
# overloading, and thus are stored in temporary lists.
# However, Named Constructors cannot be overloaded, and thus do not have
# a list.
- # FIXME: move Constructor logic into separate function, instead of modifying
- # extended attributes in-place.
+ # TODO(bashi): Remove |constructors| and |custom_constructors|.
constructors = []
custom_constructors = []
extended_attributes = {}
@@ -812,7 +891,9 @@ def ext_attributes_node_to_extended_attributes(node):
if not children:
return None
if len(children) > 1:
- raise ValueError('ExtAttributes node with %s children, expected at most 1' % len(children))
+ raise ValueError(
+ 'ExtAttributes node with %s children, expected at most 1' %
+ len(children))
return children[0]
extended_attribute_node_list = node.GetChildren()
@@ -821,25 +902,29 @@ def ext_attributes_node_to_extended_attributes(node):
child = child_node(extended_attribute_node)
child_class = child and child.GetClass()
if name == 'Constructor':
- if child_class and child_class != 'Arguments':
- raise ValueError('Constructor only supports Arguments as child, but has child of class: %s' % child_class)
- constructors.append(child)
+ raise ValueError('[Constructor] is deprecated. Use constructor '
+ 'operations')
elif name == 'CustomConstructor':
- if child_class and child_class != 'Arguments':
- raise ValueError('[CustomConstructor] only supports Arguments as child, but has child of class: %s' % child_class)
- custom_constructors.append(child)
+ raise ValueError('[CustomConstructor] is deprecated. Use '
+ 'constructor operations with [Custom]')
elif name == 'NamedConstructor':
if child_class and child_class != 'Call':
- raise ValueError('[NamedConstructor] only supports Call as child, but has child of class: %s' % child_class)
+ raise ValueError(
+ '[NamedConstructor] only supports Call as child, but has child of class: %s'
+ % child_class)
extended_attributes[name] = child
elif name == 'Exposed':
if child_class and child_class != 'Arguments':
- raise ValueError('[Exposed] only supports Arguments as child, but has child of class: %s' % child_class)
+ raise ValueError(
+ '[Exposed] only supports Arguments as child, but has child of class: %s'
+ % child_class)
exposures = []
if child_class == 'Arguments':
- exposures = [Exposure(exposed=str(arg.idl_type),
- runtime_enabled=arg.name)
- for arg in arguments_node_to_arguments(child)]
+ exposures = [
+ Exposure(
+ exposed=str(arg.idl_type), runtime_enabled=arg.name)
+ for arg in arguments_node_to_arguments(child)
+ ]
else:
value = extended_attribute_node.GetProperty('VALUE')
if type(value) is str:
@@ -848,7 +933,8 @@ def ext_attributes_node_to_extended_attributes(node):
exposures = [Exposure(exposed=v) for v in value]
extended_attributes[name] = exposures
elif child:
- raise ValueError('ExtAttributes node with unexpected children: %s' % name)
+ raise ValueError(
+ 'ExtAttributes node with unexpected children: %s' % name)
else:
value = extended_attribute_node.GetProperty('VALUE')
extended_attributes[name] = value
@@ -869,15 +955,21 @@ def extended_attributes_to_constructors(extended_attributes):
Auxiliary function for IdlInterface.__init__.
"""
+ # TODO(bashi): Remove 'Constructors' and 'CustomConstructors'.
+
constructor_list = extended_attributes.get('Constructors', [])
constructors = [
- IdlOperation.constructor_from_arguments_node('Constructor', arguments_node)
- for arguments_node in constructor_list]
+ IdlOperation.constructor_from_arguments_node('Constructor',
+ arguments_node)
+ for arguments_node in constructor_list
+ ]
custom_constructor_list = extended_attributes.get('CustomConstructors', [])
custom_constructors = [
- IdlOperation.constructor_from_arguments_node('CustomConstructor', arguments_node)
- for arguments_node in custom_constructor_list]
+ IdlOperation.constructor_from_arguments_node('CustomConstructor',
+ arguments_node)
+ for arguments_node in custom_constructor_list
+ ]
if 'NamedConstructor' in extended_attributes:
# FIXME: support overloaded named constructors, and make homogeneous
@@ -886,15 +978,102 @@ def extended_attributes_to_constructors(extended_attributes):
extended_attributes['NamedConstructor'] = call_node.GetName()
children = call_node.GetChildren()
if len(children) != 1:
- raise ValueError('NamedConstructor node expects 1 child, got %s.' % len(children))
+ raise ValueError('NamedConstructor node expects 1 child, got %s.' %
+ len(children))
arguments_node = children[0]
- named_constructor = IdlOperation.constructor_from_arguments_node('NamedConstructor', arguments_node)
+ named_constructor = IdlOperation.constructor_from_arguments_node(
+ 'NamedConstructor', arguments_node)
# FIXME: should return named_constructor separately; appended for Perl
constructors.append(named_constructor)
return constructors, custom_constructors
+class ConstructorOperation(object):
+ """Represents a constructor operation. This is a tentative object used to
+ create constructors in IdlInterface.
+ """
+
+ def __init__(self, constructor, extended_attributes, is_custom):
+ self.constructor = constructor
+ self.extended_attributes = extended_attributes
+ self.is_custom = is_custom
+
+
+def constructor_operation_from_node(node):
+ """Creates a ConstructorOperation from the given |node|.
+ """
+
+ arguments_node = None
+ extended_attributes = {}
+
+ for child in node.GetChildren():
+ child_class = child.GetClass()
+ if child_class == 'Arguments':
+ arguments_node = child
+ elif child_class == 'ExtAttributes':
+ extended_attributes = ext_attributes_node_to_extended_attributes(
+ child)
+ else:
+ raise ValueError('Unrecognized node class: %s' % child_class)
+
+ if not arguments_node:
+ raise ValueError('Expected Arguments node for constructor operation')
+
+ if 'Custom' in extended_attributes:
+ if extended_attributes['Custom']:
+ raise ValueError('[Custom] should not have a value on constructor '
+ 'operations')
+ del extended_attributes['Custom']
+ constructor = IdlOperation.constructor_from_arguments_node(
+ 'CustomConstructor', arguments_node)
+ return ConstructorOperation(
+ constructor, extended_attributes, is_custom=True)
+ else:
+ constructor = IdlOperation.constructor_from_arguments_node(
+ 'Constructor', arguments_node)
+ return ConstructorOperation(
+ constructor, extended_attributes, is_custom=False)
+
+
+def check_constructor_operations_extended_attributes(current_attrs, new_attrs):
+ """Raises a ValueError if two extended attribute lists have different values
+ of constructor related attributes.
+ """
+
+ attrs_to_check = ['CallWith', 'RaisesException']
+ for attr in attrs_to_check:
+ if current_attrs.get(attr) != new_attrs.get(attr):
+ raise ValueError('[{}] should have the same value on all '
+ 'constructor operations'.format(attr))
+
+
+def convert_constructor_operations_extended_attributes(extended_attributes):
+ """Converts extended attributes specified on constructor operations to
+ extended attributes for an interface definition (e.g. [ConstructorCallWith])
+ """
+
+ converted = {}
+ for name, value in extended_attributes.items():
+ if name == "CallWith":
+ converted["ConstructorCallWith"] = value
+ elif name == "RaisesException":
+ if value:
+ raise ValueError(
+ '[RaisesException] should not have a value on '
+ 'constructor operations')
+ converted["RaisesException"] = 'Constructor'
+ elif name == "MeasureAs":
+ converted["MeasureAs"] = value
+ elif name == "Measure":
+ converted["Measure"] = None
+ else:
+ raise ValueError(
+ '[{}] is not supported on constructor operations'.format(name))
+
+ return converted
+
+
def clear_constructor_attributes(extended_attributes):
# Deletes Constructor*s* (plural), sets Constructor (singular)
if 'Constructors' in extended_attributes:
@@ -909,14 +1088,17 @@ def clear_constructor_attributes(extended_attributes):
# Types
################################################################################
+
def type_node_to_type(node):
children = node.GetChildren()
if len(children) != 1 and len(children) != 2:
- raise ValueError('Type node expects 1 or 2 child(ren), got %d.' % len(children))
+ raise ValueError(
+ 'Type node expects 1 or 2 child(ren), got %d.' % len(children))
base_type = type_node_inner_to_type(children[0])
if len(children) == 2:
- extended_attributes = ext_attributes_node_to_extended_attributes(children[1])
+ extended_attributes = ext_attributes_node_to_extended_attributes(
+ children[1])
base_type = IdlAnnotatedType(base_type, extended_attributes)
if node.GetProperty('NULLABLE'):
@@ -950,21 +1132,25 @@ def type_node_inner_to_type(node):
def record_node_to_type(node):
children = node.GetChildren()
if len(children) != 2:
- raise ValueError('record<K,V> node expects exactly 2 children, got %d' % (len(children)))
+ raise ValueError('record<K,V> node expects exactly 2 children, got %d'
+ % (len(children)))
key_child = children[0]
value_child = children[1]
if key_child.GetClass() != 'StringType':
raise ValueError('Keys in record<K,V> nodes must be string types.')
if value_child.GetClass() != 'Type':
- raise ValueError('Unrecognized node class for record<K,V> value: %s' % value_child.GetClass())
- return IdlRecordType(IdlType(key_child.GetName()), type_node_to_type(value_child))
+ raise ValueError('Unrecognized node class for record<K,V> value: %s' %
+ value_child.GetClass())
+ return IdlRecordType(
+ IdlType(key_child.GetName()), type_node_to_type(value_child))
def sequence_node_to_type(node):
children = node.GetChildren()
class_name = node.GetClass()
if len(children) != 1:
- raise ValueError('%s node expects exactly 1 child, got %s' % (class_name, len(children)))
+ raise ValueError('%s node expects exactly 1 child, got %s' %
+ (class_name, len(children)))
sequence_child = children[0]
sequence_child_class = sequence_child.GetClass()
if sequence_child_class != 'Type':
@@ -984,7 +1170,8 @@ def sequence_node_to_type(node):
def typedef_node_to_type(node):
children = node.GetChildren()
if len(children) != 1:
- raise ValueError('Typedef node with %s children, expected 1' % len(children))
+ raise ValueError(
+ 'Typedef node with %s children, expected 1' % len(children))
child = children[0]
child_class = child.GetClass()
if child_class != 'Type':
@@ -993,8 +1180,10 @@ def typedef_node_to_type(node):
def union_type_node_to_idl_union_type(node):
- member_types = [type_node_to_type(member_type_node)
- for member_type_node in node.GetChildren()]
+ member_types = [
+ type_node_to_type(member_type_node)
+ for member_type_node in node.GetChildren()
+ ]
return IdlUnionType(member_types)
@@ -1002,6 +1191,7 @@ def union_type_node_to_idl_union_type(node):
# Visitor
################################################################################
+
class Visitor(object):
"""Abstract visitor class for IDL definitions traverse."""
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/idl_definitions_test.py b/chromium/third_party/blink/renderer/bindings/scripts/idl_definitions_test.py
index 78dd7320744..e2a91843a9a 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/idl_definitions_test.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/idl_definitions_test.py
@@ -3,7 +3,6 @@
# found in the LICENSE file.
# pylint: disable=import-error,print-statement,relative-import
-
"""Unit tests for idl_definitions.py."""
import unittest
@@ -12,7 +11,6 @@ from idl_definitions import IdlAttribute
class IdlAttributeTest(unittest.TestCase):
-
def test_no_params(self):
try:
IdlAttribute()
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/idl_reader.py b/chromium/third_party/blink/renderer/bindings/scripts/idl_reader.py
index 3b0895ed5b5..8d72865a6ca 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/idl_reader.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/idl_reader.py
@@ -25,7 +25,6 @@
# 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.
-
"""Read an IDL file or complete IDL interface, producing an IdlDefinitions object.
Design doc:
@@ -56,28 +55,28 @@ def validate_blink_idl_definitions(idl_filename, idl_file_basename,
definitions. There is no filename convention in this case.
- Otherwise, an IDL file is invalid.
"""
- targets = (definitions.interfaces.values() +
- definitions.dictionaries.values())
+ targets = (
+ definitions.interfaces.values() + definitions.dictionaries.values())
number_of_targets = len(targets)
if number_of_targets > 1:
raise Exception(
- 'Expected exactly 1 definition in file {0}, but found {1}'
- .format(idl_filename, number_of_targets))
+ 'Expected exactly 1 definition in file {0}, but found {1}'.format(
+ idl_filename, number_of_targets))
if number_of_targets == 0:
- number_of_definitions = (
- len(definitions.enumerations) + len(definitions.typedefs) +
- len(definitions.callback_functions))
+ number_of_definitions = (len(definitions.enumerations) + len(
+ definitions.typedefs) + len(definitions.callback_functions))
if number_of_definitions == 0:
- raise Exception(
- 'No definition found in %s' % idl_filename)
+ raise Exception('No definition found in %s. (Missing semicolon?)' %
+ idl_filename)
return
target = targets[0]
if target.is_partial:
return
- if target.name != idl_file_basename and to_snake_case(target.name) != idl_file_basename:
+ if (target.name != idl_file_basename
+ and to_snake_case(target.name) != idl_file_basename):
raise Exception(
- 'Definition name "{0}" disagrees with IDL file basename "{1}".'
- .format(target.name, idl_file_basename))
+ 'Definition name "{0}" disagrees with IDL file basename "{1}".'.
+ format(target.name, idl_file_basename))
class IdlReader(object):
@@ -86,7 +85,8 @@ class IdlReader(object):
self.interfaces_info = interfaces_info
if interfaces_info:
- self.interface_dependency_resolver = InterfaceDependencyResolver(interfaces_info, self)
+ self.interface_dependency_resolver = InterfaceDependencyResolver(
+ interfaces_info, self)
else:
self.interface_dependency_resolver = None
@@ -105,7 +105,8 @@ class IdlReader(object):
if not definitions.interfaces:
return {component: definitions}
- return self.interface_dependency_resolver.resolve_dependencies(definitions, component)
+ return self.interface_dependency_resolver.resolve_dependencies(
+ definitions, component)
def read_idl_file(self, idl_filename):
"""Returns an IdlDefinitions object for an IDL file, without any dependencies.
@@ -119,15 +120,16 @@ class IdlReader(object):
idl_file_basename, _ = os.path.splitext(os.path.basename(idl_filename))
definitions = IdlDefinitions(ast)
- validate_blink_idl_definitions(
- idl_filename, idl_file_basename, definitions)
+ validate_blink_idl_definitions(idl_filename, idl_file_basename,
+ definitions)
# Validate extended attributes
if not self.extended_attribute_validator:
return definitions
try:
- self.extended_attribute_validator.validate_extended_attributes(definitions)
+ self.extended_attribute_validator.validate_extended_attributes(
+ definitions)
except IDLInvalidExtendedAttributeError as error:
raise IDLInvalidExtendedAttributeError("""
IDL ATTRIBUTE ERROR in file:
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/idl_types.py b/chromium/third_party/blink/renderer/bindings/scripts/idl_types.py
index acb20cf69e0..cd4f0c3513b 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/idl_types.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/idl_types.py
@@ -18,7 +18,6 @@ IdlTypes are picklable because we store them in interfaces_info.
from collections import defaultdict
-
################################################################################
# IDL types
################################################################################
@@ -35,24 +34,26 @@ INTEGER_TYPES = frozenset([
'long long',
'unsigned long long',
])
-NUMERIC_TYPES = (INTEGER_TYPES | frozenset([
- # http://www.w3.org/TR/WebIDL/#dfn-numeric-type
- 'float',
- 'unrestricted float',
- 'double',
- 'unrestricted double',
-]))
+NUMERIC_TYPES = (
+ INTEGER_TYPES | frozenset([
+ # http://www.w3.org/TR/WebIDL/#dfn-numeric-type
+ 'float',
+ 'unrestricted float',
+ 'double',
+ 'unrestricted double',
+ ]))
# http://www.w3.org/TR/WebIDL/#dfn-primitive-type
PRIMITIVE_TYPES = (frozenset(['boolean']) | NUMERIC_TYPES)
-BASIC_TYPES = (PRIMITIVE_TYPES | frozenset([
- # Built-in, non-composite, non-object data types
- # http://heycam.github.io/webidl/#idl-types
- 'DOMString',
- 'ByteString',
- 'USVString',
- # http://heycam.github.io/webidl/#idl-types
- 'void',
-]))
+BASIC_TYPES = (
+ PRIMITIVE_TYPES | frozenset([
+ # Built-in, non-composite, non-object data types
+ # http://heycam.github.io/webidl/#idl-types
+ 'DOMString',
+ 'ByteString',
+ 'USVString',
+ # http://heycam.github.io/webidl/#idl-types
+ 'void',
+ ]))
TYPE_NAMES = {
# http://heycam.github.io/webidl/#dfn-type-name
'any': 'Any',
@@ -84,8 +85,10 @@ STRING_TYPES = frozenset([
])
EXTENDED_ATTRIBUTES_APPLICABLE_TO_TYPES = frozenset([
+ 'AllowShared',
'Clamp',
'EnforceRange',
+ 'StringContext',
'TreatNullAs',
])
@@ -95,9 +98,10 @@ EXTENDED_ATTRIBUTES_APPLICABLE_TO_TYPES = frozenset([
ancestors = defaultdict(list) # interface_name -> ancestors
+
def inherits_interface(interface_name, ancestor_name):
- return (interface_name == ancestor_name or
- ancestor_name in ancestors[interface_name])
+ return (interface_name == ancestor_name
+ or ancestor_name in ancestors[interface_name])
def set_ancestors(new_ancestors):
@@ -105,11 +109,12 @@ def set_ancestors(new_ancestors):
class IdlTypeBase(object):
- """Base class for IdlType, IdlUnionType, IdlArrayOrSequenceType and IdlNullableType."""
+ """Base class for IdlType, IdlUnionType, IdlArrayOrSequenceType
+ and IdlNullableType.
+ """
def __str__(self):
- raise NotImplementedError(
- '__str__() should be defined in subclasses')
+ raise NotImplementedError('__str__() should be defined in subclasses')
def __getattr__(self, name):
# Default undefined attributes to None (analogous to Jinja variables).
@@ -131,6 +136,7 @@ class IdlTypeBase(object):
# IdlType
################################################################################
+
class IdlType(IdlTypeBase):
# FIXME: incorporate Nullable, etc.
# to support types like short?[] vs. short[]?, instead of treating these
@@ -184,8 +190,8 @@ class IdlType(IdlTypeBase):
@property
def is_enum(self):
- # FIXME: add an IdlEnumType class and a resolve_enums step at end of
- # IdlDefinitions constructor
+ # FIXME: add an IdlEnumType class and a resolve_enums step
+ # at end of IdlDefinitions constructor
return self.name in IdlType.enums
@property
@@ -218,13 +224,10 @@ class IdlType(IdlTypeBase):
# http://www.w3.org/TR/WebIDL/#idl-types
# http://www.w3.org/TR/WebIDL/#idl-interface
# In C++ these are RefPtr types.
- return not(self.is_basic_type or
- self.is_callback_function or
- self.is_dictionary or
- self.is_enum or
- self.name == 'Any' or
- self.name == 'Object' or
- self.name == 'Promise') # Promise will be basic in future
+ return not (self.is_basic_type or self.is_callback_function
+ or self.is_dictionary or self.is_enum or self.name == 'Any'
+ or self.name == 'Object' or self.name == 'Promise'
+ ) # Promise will be basic in future
@property
def is_string_type(self):
@@ -256,15 +259,22 @@ class IdlType(IdlTypeBase):
cls.enums.update(new_enums)
def resolve_typedefs(self, typedefs):
- # This function either returns |self| or a different object.
- # FIXME: Rename typedefs_resolved().
- return typedefs.get(self.base_type, self)
+ base_type = self.base_type
+ if base_type in typedefs:
+ resolved_type = typedefs[base_type]
+ if resolved_type.base_type in typedefs:
+ raise ValueError("We can't typedef a typedef'ed type.")
+ # For the case that the resolved type contains other typedef'ed
+ # type(s).
+ return resolved_type.resolve_typedefs(typedefs)
+ return self
################################################################################
# IdlUnionType
################################################################################
+
class IdlUnionType(IdlTypeBase):
# http://heycam.github.io/webidl/#idl-union
# IdlUnionType has __hash__() and __eq__() methods because they are stored
@@ -274,7 +284,8 @@ class IdlUnionType(IdlTypeBase):
self.member_types = member_types
def __str__(self):
- return '(' + ' or '.join(str(member_type) for member_type in self.member_types) + ')'
+ return '(' + ' or '.join(
+ str(member_type) for member_type in self.member_types) + ')'
def __hash__(self):
return hash(self.name)
@@ -296,14 +307,16 @@ class IdlUnionType(IdlTypeBase):
https://heycam.github.io/webidl/#dfn-flattened-union-member-types
"""
- # We cannot use a set directly because each member is an IdlTypeBase-derived class, and
- # comparing two objects of the same type is not the same as comparing their names. In
- # other words:
+ # We cannot use a set directly because each member is an
+ # IdlTypeBase-derived class, and comparing two objects of the
+ # same type is not the same as comparing their names.
+ # In other words:
# x = IdlType('ByteString')
# y = IdlType('ByteString')
# x == y # False
# x.name == y.name # True
- # |flattened_members|'s keys are type names, the values are type |objects.
+ # |flattened_members|'s keys are type names, the values are type
+ # |objects|.
# We assume we can use two IDL objects of the same type interchangeably.
flattened_members = {}
for member in self.member_types:
@@ -344,8 +357,8 @@ class IdlUnionType(IdlTypeBase):
@property
def string_member_type(self):
return self.single_matching_member_type(
- lambda member_type: (member_type.is_string_type or
- member_type.is_enum))
+ lambda member_type: (member_type.is_string_type or member_type.is_enum)
+ )
@property
def numeric_member_type(self):
@@ -383,7 +396,8 @@ class IdlUnionType(IdlTypeBase):
def resolve_typedefs(self, typedefs):
self.member_types = [
member_type.resolve_typedefs(typedefs)
- for member_type in self.member_types]
+ for member_type in self.member_types
+ ]
return self
def idl_types(self):
@@ -397,6 +411,7 @@ class IdlUnionType(IdlTypeBase):
# IdlArrayOrSequenceType, IdlSequenceType, IdlFrozenArrayType
################################################################################
+
# TODO(bashi): Rename this like "IdlArrayTypeBase" or something.
class IdlArrayOrSequenceType(IdlTypeBase):
"""Base class for array-like types."""
@@ -479,6 +494,7 @@ class IdlFrozenArrayType(IdlArrayOrSequenceType):
# IdlRecordType
################################################################################
+
class IdlRecordType(IdlTypeBase):
def __init__(self, key_type, value_type):
super(IdlRecordType, self).__init__()
@@ -523,6 +539,7 @@ class IdlRecordType(IdlTypeBase):
# IdlNullableType
################################################################################
+
# https://heycam.github.io/webidl/#idl-nullable-type
class IdlNullableType(IdlTypeBase):
def __init__(self, inner_type):
@@ -599,9 +616,11 @@ class IdlNullableType(IdlTypeBase):
# IdlAnnotatedType
################################################################################
+
class IdlAnnotatedType(IdlTypeBase):
"""IdlAnnoatedType represents an IDL type with extended attributes.
- [Clamp], [EnforceRange], and [TreatNullAs] are applicable to types.
+ [Clamp], [EnforceRange], [StringContext], and [TreatNullAs] are applicable
+ to types.
https://heycam.github.io/webidl/#idl-annotated-types
"""
@@ -612,11 +631,18 @@ class IdlAnnotatedType(IdlTypeBase):
if any(key not in EXTENDED_ATTRIBUTES_APPLICABLE_TO_TYPES
for key in extended_attributes):
- raise ValueError('Extended attributes not applicable to types: %s' % self)
+ raise ValueError(
+ 'Extended attributes not applicable to types: %s' % self)
+
+ if ('StringContext' in extended_attributes
+ and inner_type.base_type not in ['DOMString', 'USVString']):
+ raise ValueError(
+ 'StringContext is only applicable to string types.')
def __str__(self):
- annotation = ', '.join((key + ('' if val is None else '=' + val))
- for key, val in self.extended_attributes.iteritems())
+ annotation = ', '.join(
+ (key + ('' if val is None else '=' + val))
+ for key, val in self.extended_attributes.items())
return '[%s] %s' % (annotation, str(self.inner_type))
def __getattr__(self, name):
@@ -637,9 +663,14 @@ class IdlAnnotatedType(IdlTypeBase):
return True
@property
+ def has_string_context(self):
+ return 'StringContext' in self.extended_attributes
+
+ @property
def name(self):
- annotation = ''.join((key + ('' if val is None else val))
- for key, val in sorted(self.extended_attributes.iteritems()))
+ annotation = ''.join(
+ (key + ('' if val is None else val))
+ for key, val in sorted(self.extended_attributes.items()))
return self.inner_type.name + annotation
def resolve_typedefs(self, typedefs):
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/idl_types_test.py b/chromium/third_party/blink/renderer/bindings/scripts/idl_types_test.py
index 2948ca9922f..519fbcf84e8 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/idl_types_test.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/idl_types_test.py
@@ -3,7 +3,6 @@
# found in the LICENSE file.
# pylint: disable=import-error,print-statement,relative-import
-
"""Unit tests for idl_types.py."""
import unittest
@@ -16,7 +15,6 @@ from idl_types import IdlUnionType
class IdlTypeTest(unittest.TestCase):
-
def test_is_void(self):
idl_type = IdlType('void')
self.assertTrue(idl_type.is_void)
@@ -25,7 +23,6 @@ class IdlTypeTest(unittest.TestCase):
class IdlRecordTypeTest(unittest.TestCase):
-
def test_idl_types(self):
idl_type = IdlRecordType(IdlType('USVString'), IdlType('long'))
idl_types = list(idl_type.idl_types())
@@ -33,21 +30,28 @@ class IdlRecordTypeTest(unittest.TestCase):
self.assertIs(idl_types[0], idl_type)
self.assertEqual(idl_types[1].name, 'USVString')
self.assertEqual(idl_types[2].name, 'Long')
- self.assertListEqual(list(idl_type.idl_types()),
- [idl_type, idl_type.key_type, idl_type.value_type])
+ self.assertListEqual(
+ list(idl_type.idl_types()),
+ [idl_type, idl_type.key_type, idl_type.value_type])
- idl_type = IdlRecordType(IdlType('DOMString'), IdlSequenceType(IdlType('unrestricted float')))
+ idl_type = IdlRecordType(
+ IdlType('DOMString'), IdlSequenceType(
+ IdlType('unrestricted float')))
idl_types = list(idl_type.idl_types())
self.assertEqual(len(idl_types), 4)
self.assertIs(idl_types[0], idl_type)
self.assertEqual(idl_types[1].name, 'String')
self.assertEqual(idl_types[2].name, 'UnrestrictedFloatSequence')
self.assertEqual(idl_types[3].name, 'UnrestrictedFloat')
- self.assertListEqual(list(idl_type.idl_types()),
- [idl_type, idl_type.key_type, idl_type.value_type, idl_type.value_type.element_type])
-
- idl_type = IdlRecordType(IdlType('ByteString'),
- IdlRecordType(IdlType('DOMString'), IdlType('octet')))
+ self.assertListEqual(
+ list(idl_type.idl_types()), [
+ idl_type, idl_type.key_type, idl_type.value_type,
+ idl_type.value_type.element_type
+ ])
+
+ idl_type = IdlRecordType(
+ IdlType('ByteString'),
+ IdlRecordType(IdlType('DOMString'), IdlType('octet')))
idl_types = list(idl_type.idl_types())
self.assertEqual(len(idl_types), 5)
self.assertIs(idl_types[0], idl_type)
@@ -55,38 +59,48 @@ class IdlRecordTypeTest(unittest.TestCase):
self.assertEqual(idl_types[2].name, 'StringOctetRecord')
self.assertEqual(idl_types[3].name, 'String')
self.assertEqual(idl_types[4].name, 'Octet')
- self.assertListEqual(list(idl_type.idl_types()),
- [idl_type, idl_type.key_type, idl_type.value_type, idl_type.value_type.key_type,
- idl_type.value_type.value_type])
+ self.assertListEqual(
+ list(idl_type.idl_types()), [
+ idl_type, idl_type.key_type, idl_type.value_type,
+ idl_type.value_type.key_type, idl_type.value_type.value_type
+ ])
def test_is_record(self):
idl_type = IdlType('USVString')
self.assertFalse(idl_type.is_record_type)
- idl_type = IdlSequenceType(IdlRecordType(IdlType('DOMString'), IdlType('byte')))
+ idl_type = IdlSequenceType(
+ IdlRecordType(IdlType('DOMString'), IdlType('byte')))
self.assertFalse(idl_type.is_record_type)
idl_type = IdlRecordType(IdlType('USVString'), IdlType('long'))
self.assertTrue(idl_type.is_record_type)
- idl_type = IdlRecordType(IdlType('USVString'), IdlSequenceType(IdlType('boolean')))
+ idl_type = IdlRecordType(
+ IdlType('USVString'), IdlSequenceType(IdlType('boolean')))
self.assertTrue(idl_type.is_record_type)
def test_name(self):
idl_type = IdlRecordType(IdlType('ByteString'), IdlType('octet'))
self.assertEqual(idl_type.name, 'ByteStringOctetRecord')
- idl_type = IdlRecordType(IdlType('USVString'), IdlSequenceType(IdlType('double')))
+ idl_type = IdlRecordType(
+ IdlType('USVString'), IdlSequenceType(IdlType('double')))
self.assertEqual(idl_type.name, 'USVStringDoubleSequenceRecord')
- idl_type = IdlRecordType(IdlType('DOMString'),
- IdlRecordType(IdlType('ByteString'),
- IdlSequenceType(IdlType('unsigned short'))))
- self.assertEqual(idl_type.name, 'StringByteStringUnsignedShortSequenceRecordRecord')
+ idl_type = IdlRecordType(
+ IdlType('DOMString'),
+ IdlRecordType(
+ IdlType('ByteString'),
+ IdlSequenceType(IdlType('unsigned short'))))
+ self.assertEqual(idl_type.name,
+ 'StringByteStringUnsignedShortSequenceRecordRecord')
class IdlUnionTypeTest(unittest.TestCase):
-
def test_flattened_member_types(self):
- # We are only testing the algorithm here, so we do create some ambiguous union types.
+ # We are only testing the algorithm here, so we do create some
+ # ambiguous union types.
def compare_flattened_members(actual, expected):
- """Compare a set of IDL types by name, as the objects are different"""
+ """Compare a set of IDL types by name, as the objects
+ are different
+ """
actual_names = set([member.name for member in actual])
expected_names = set([member.name for member in expected])
self.assertEqual(actual_names, expected_names)
@@ -96,46 +110,80 @@ class IdlUnionTypeTest(unittest.TestCase):
idl_type.flattened_member_types,
set([IdlType('long'), IdlType('SomeInterface')]))
- idl_type = IdlUnionType([IdlUnionType([IdlType('ByteString'), IdlType('float')]),
- IdlType('boolean')])
+ idl_type = IdlUnionType([
+ IdlUnionType([IdlType('ByteString'),
+ IdlType('float')]),
+ IdlType('boolean')
+ ])
compare_flattened_members(
idl_type.flattened_member_types,
- set([IdlType('float'), IdlType('boolean'), IdlType('ByteString')]))
-
- idl_type = IdlUnionType([IdlUnionType([IdlType('ByteString'), IdlType('DOMString')]),
- IdlType('DOMString')])
+ set([IdlType('float'),
+ IdlType('boolean'),
+ IdlType('ByteString')]))
+
+ idl_type = IdlUnionType([
+ IdlUnionType([IdlType('ByteString'),
+ IdlType('DOMString')]),
+ IdlType('DOMString')
+ ])
compare_flattened_members(
idl_type.flattened_member_types,
- set([IdlType('DOMString'), IdlType('ByteString')]))
+ set([IdlType('DOMString'),
+ IdlType('ByteString')]))
idl_type = IdlUnionType(
- [IdlNullableType(IdlType('ByteString')), IdlType('byte')])
+ [IdlNullableType(IdlType('ByteString')),
+ IdlType('byte')])
compare_flattened_members(
idl_type.flattened_member_types,
set([IdlType('ByteString'), IdlType('byte')]))
- idl_type = IdlUnionType(
- [IdlNullableType(IdlType('ByteString')), IdlType('byte'),
- IdlUnionType([IdlType('ByteString'), IdlType('float')])])
+ idl_type = IdlUnionType([
+ IdlNullableType(IdlType('ByteString')),
+ IdlType('byte'),
+ IdlUnionType([IdlType('ByteString'),
+ IdlType('float')])
+ ])
self.assertEqual(len(idl_type.flattened_member_types), 3)
compare_flattened_members(
idl_type.flattened_member_types,
- set([IdlType('ByteString'), IdlType('byte'), IdlType('float')]))
-
- # From the example in the spec: "the flattened member types of the union type (Node or (sequence<long> or Event) or
- # (XMLHttpRequest or DOMString)? or sequence<(sequence<double> or NodeList)>) are the six types Node, sequence<long>,
- # Event, XMLHttpRequest, DOMString and sequence<(sequence<double> or NodeList)>"
- idl_type = IdlUnionType(
- [IdlType('Node'),
- IdlUnionType([IdlSequenceType(IdlType('long')), IdlType('Event')]),
- IdlNullableType(IdlUnionType([IdlType('XMLHttpRequest'), IdlType('DOMString')])),
- IdlSequenceType(IdlUnionType([IdlSequenceType(IdlType('double')), IdlType('NodeList')]))])
+ set([IdlType('ByteString'),
+ IdlType('byte'),
+ IdlType('float')]))
+
+ # From the example in the spec: "the flattened member types of the
+ # union type (Node or (sequence<long> or Event) or
+ # (XMLHttpRequest or DOMString)? or
+ # sequence<(sequence<double> or NodeList)>) are the six types Node,
+ # sequence<long>, Event, XMLHttpRequest, DOMString and
+ # sequence<(sequence<double> or NodeList)>"
+ idl_type = IdlUnionType([
+ IdlType('Node'),
+ IdlUnionType([IdlSequenceType(IdlType('long')),
+ IdlType('Event')]),
+ IdlNullableType(
+ IdlUnionType([IdlType('XMLHttpRequest'),
+ IdlType('DOMString')])),
+ IdlSequenceType(
+ IdlUnionType(
+ [IdlSequenceType(IdlType('double')),
+ IdlType('NodeList')]))
+ ])
self.assertEqual(len(idl_type.flattened_member_types), 6)
compare_flattened_members(
idl_type.flattened_member_types,
- set([IdlType('Node'), IdlSequenceType(IdlType('long')), IdlType('Event'),
- IdlType('XMLHttpRequest'), IdlType('DOMString'),
- IdlSequenceType(IdlUnionType([IdlSequenceType(IdlType('double')), IdlType('NodeList')]))]))
+ set([
+ IdlType('Node'),
+ IdlSequenceType(IdlType('long')),
+ IdlType('Event'),
+ IdlType('XMLHttpRequest'),
+ IdlType('DOMString'),
+ IdlSequenceType(
+ IdlUnionType([
+ IdlSequenceType(IdlType('double')),
+ IdlType('NodeList')
+ ]))
+ ]))
def test_resolve_typedefs(self):
# This is a simplification of the typedef mechanism to avoid having to
@@ -147,13 +195,17 @@ class IdlUnionTypeTest(unittest.TestCase):
}
# (long long or MyBooleanType)
- union = IdlUnionType([IdlType('long long'), IdlType('MyBooleanType')]).resolve_typedefs(typedefs)
+ union = IdlUnionType(
+ [IdlType('long long'),
+ IdlType('MyBooleanType')]).resolve_typedefs(typedefs)
self.assertEqual(union.name, 'LongLongOrBoolean')
self.assertEqual(union.member_types[0].name, 'LongLong')
self.assertEqual(union.member_types[1].name, 'Boolean')
# (Foo or SomeInterfaceT)
- union = IdlUnionType([IdlType('Foo'), IdlType('SomeInterfaceT')]).resolve_typedefs(typedefs)
+ union = IdlUnionType(
+ [IdlType('Foo'),
+ IdlType('SomeInterfaceT')]).resolve_typedefs(typedefs)
self.assertEqual(union.name, 'UnsignedShortOrMyInterface')
self.assertEqual(union.member_types[0].name, 'UnsignedShort')
self.assertEqual(union.member_types[1].name, 'MyInterface')
@@ -161,16 +213,19 @@ class IdlUnionTypeTest(unittest.TestCase):
# (Foo or sequence<(MyBooleanType or double)>)
union = IdlUnionType([
IdlType('Foo'),
- IdlSequenceType(IdlUnionType([IdlType('MyBooleanType'),
- IdlType('double')]))]).resolve_typedefs(typedefs)
+ IdlSequenceType(
+ IdlUnionType([IdlType('MyBooleanType'),
+ IdlType('double')]))
+ ]).resolve_typedefs(typedefs)
self.assertEqual(union.name, 'UnsignedShortOrBooleanOrDoubleSequence')
self.assertEqual(union.member_types[0].name, 'UnsignedShort')
self.assertEqual(union.member_types[1].name, 'BooleanOrDoubleSequence')
- self.assertEqual(union.member_types[1].element_type.name, 'BooleanOrDouble')
- self.assertEqual(union.member_types[1].element_type.member_types[0].name,
- 'Boolean')
- self.assertEqual(union.member_types[1].element_type.member_types[1].name,
- 'Double')
+ self.assertEqual(union.member_types[1].element_type.name,
+ 'BooleanOrDouble')
+ self.assertEqual(
+ union.member_types[1].element_type.member_types[0].name, 'Boolean')
+ self.assertEqual(
+ union.member_types[1].element_type.member_types[1].name, 'Double')
self.assertEqual(2, len(union.flattened_member_types))
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/idl_validator.py b/chromium/third_party/blink/renderer/bindings/scripts/idl_validator.py
index 85de1cc1d83..64e84ef7da1 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/idl_validator.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/idl_validator.py
@@ -25,13 +25,11 @@
# 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.
-
"""Validate extended attributes.
Design doc: http://www.chromium.org/developers/design-documents/idl-compiler#TOC-Extended-attribute-validation
"""
-
import os.path
import re
@@ -42,6 +40,7 @@ EXTENDED_ATTRIBUTES_RELATIVE_PATH = os.path.join('bindings',
EXTENDED_ATTRIBUTES_FILENAME = os.path.join(source_path,
EXTENDED_ATTRIBUTES_RELATIVE_PATH)
+
class IDLInvalidExtendedAttributeError(Exception):
pass
@@ -52,7 +51,7 @@ class IDLExtendedAttributeValidator(object):
def validate_extended_attributes(self, definitions):
# FIXME: this should be done when parsing the file, rather than after.
- for interface in definitions.interfaces.itervalues():
+ for interface in definitions.interfaces.values():
self.validate_extended_attributes_node(interface)
for attribute in interface.attributes:
self.validate_extended_attributes_node(attribute)
@@ -60,18 +59,17 @@ class IDLExtendedAttributeValidator(object):
self.validate_extended_attributes_node(operation)
for argument in operation.arguments:
self.validate_extended_attributes_node(argument)
- for dictionary in definitions.dictionaries.itervalues():
+ for dictionary in definitions.dictionaries.values():
self.validate_extended_attributes_node(dictionary)
for member in dictionary.members:
self.validate_extended_attributes_node(member)
- for callback_function in definitions.callback_functions.itervalues():
+ for callback_function in definitions.callback_functions.values():
self.validate_extended_attributes_node(callback_function)
for argument in callback_function.arguments:
self.validate_extended_attributes_node(argument)
-
def validate_extended_attributes_node(self, node):
- for name, values_string in node.extended_attributes.iteritems():
+ for name, values_string in node.extended_attributes.items():
self.validate_name_values_string(name, values_string)
def validate_name_values_string(self, name, values_string):
@@ -106,7 +104,9 @@ def read_extended_attributes_file():
if not line or line.startswith('#'):
continue
name, _, values_string = map(str.strip, line.partition('='))
- value_list = [value.strip() for value in values_string.split('|')]
+ value_list = [
+ value.strip() for value in values_string.split('|')
+ ]
yield name, value_list
valid_extended_attributes = {}
@@ -114,6 +114,6 @@ def read_extended_attributes_file():
if not value_list:
valid_extended_attributes[name] = set([None])
continue
- valid_extended_attributes[name] = set([value if value else None
- for value in value_list])
+ valid_extended_attributes[name] = set(
+ [value if value else None for value in value_list])
return valid_extended_attributes
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/interface_dependency_resolver.py b/chromium/third_party/blink/renderer/bindings/scripts/interface_dependency_resolver.py
index ebd88a668ec..030ca1c9f9c 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/interface_dependency_resolver.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/interface_dependency_resolver.py
@@ -25,7 +25,6 @@
# 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.
-
"""Resolve interface dependencies, producing a merged IdlDefinitions object.
This library computes interface dependencies (partial interfaces and
@@ -102,7 +101,7 @@ class InterfaceDependencyResolver(object):
'this definition: %s, because this should '
'have a dictionary.' % definitions.idl_name)
- target_interface = next(definitions.interfaces.itervalues())
+ target_interface = next(iter(definitions.interfaces.values()))
interface_name = target_interface.name
interface_info = self.interfaces_info[interface_name]
@@ -111,34 +110,36 @@ class InterfaceDependencyResolver(object):
interface_info['inherited_extended_attributes'])
resolved_definitions = merge_interface_dependencies(
- definitions,
- component,
- target_interface,
+ definitions, component, target_interface,
interface_info['dependencies_full_paths'] +
interface_info['dependencies_other_component_full_paths'],
self.reader)
- inherit_unforgeable_attributes(resolved_definitions, self.interfaces_info)
+ inherit_unforgeable_attributes(resolved_definitions,
+ self.interfaces_info)
- for referenced_interface_name in interface_info['referenced_interfaces']:
+ for referenced_interface_name in \
+ interface_info['referenced_interfaces']:
referenced_definitions = self.reader.read_idl_definitions(
self.interfaces_info[referenced_interface_name]['full_path'])
for referenced_component in referenced_definitions:
- if not is_valid_component_dependency(component, referenced_component):
+ if not is_valid_component_dependency(component,
+ referenced_component):
raise Exception('This definitions: %s is defined in %s '
'but reference interface:%s is defined '
- 'in %s' % (definitions.idl_name,
- component,
+ 'in %s' % (definitions.idl_name, component,
referenced_interface_name,
referenced_component))
- resolved_definitions[component].update(referenced_definitions[component])
+ resolved_definitions[component].update(
+ referenced_definitions[component])
return resolved_definitions
-def merge_interface_dependencies(definitions, component, target_interface, dependency_idl_filenames, reader):
+def merge_interface_dependencies(definitions, component, target_interface,
+ dependency_idl_filenames, reader):
"""Merge dependencies ('partial interface' and 'implements') in dependency_idl_filenames into target_interface.
Args:
@@ -158,9 +159,11 @@ def merge_interface_dependencies(definitions, component, target_interface, depen
# Sort so order consistent, so can compare output from run to run.
for dependency_idl_filename in sorted(dependency_idl_filenames):
dependency_definitions = reader.read_idl_file(dependency_idl_filename)
- dependency_component = idl_filename_to_component(dependency_idl_filename)
+ dependency_component = idl_filename_to_component(
+ dependency_idl_filename)
- dependency_interface = next(dependency_definitions.interfaces.itervalues())
+ dependency_interface = next(
+ iter(dependency_definitions.interfaces.values()))
transfer_extended_attributes(dependency_interface,
dependency_idl_filename)
@@ -176,12 +179,13 @@ def merge_interface_dependencies(definitions, component, target_interface, depen
# However,
# - A partial interface defined in core cannot update
# the original interface defined in modules.
- if not is_valid_component_dependency(dependency_component, component):
- raise Exception('The partial interface:%s in %s cannot update '
- 'the original interface:%s in %s' % (dependency_interface.name,
- dependency_component,
- target_interface.name,
- component))
+ if not is_valid_component_dependency(dependency_component,
+ component):
+ raise Exception(
+ 'The partial interface:%s in %s cannot update '
+ 'the original interface:%s in %s' %
+ (dependency_interface.name, dependency_component,
+ target_interface.name, component))
if dependency_component in resolved_definitions:
# When merging a new partial interfaces, should not overwrite
@@ -189,12 +193,16 @@ def merge_interface_dependencies(definitions, component, target_interface, depen
# interface.
# See also the below "if 'ImplementedAs' not in ... " line's
# comment.
- dependency_interface.extended_attributes.pop('ImplementedAs', None)
- resolved_definitions[dependency_component].update(dependency_definitions)
+ dependency_interface.extended_attributes.pop(
+ 'ImplementedAs', None)
+ resolved_definitions[dependency_component].update(
+ dependency_definitions)
continue
- dependency_interface.extended_attributes.update(target_interface.extended_attributes)
- assert target_interface == definitions.interfaces[dependency_interface.name]
+ dependency_interface.extended_attributes.update(
+ target_interface.extended_attributes)
+ assert target_interface == \
+ definitions.interfaces[dependency_interface.name]
# A partial interface should use its original interface's
# ImplementedAs. If the original interface doesn't have,
# remove ImplementedAs defined in the partial interface.
@@ -208,7 +216,8 @@ def merge_interface_dependencies(definitions, component, target_interface, depen
# files correctly. ImplementedAs should not be allowed in
# partial interfaces.
if 'ImplementedAs' not in target_interface.extended_attributes:
- dependency_interface.extended_attributes.pop('ImplementedAs', None)
+ dependency_interface.extended_attributes.pop(
+ 'ImplementedAs', None)
dependency_interface.original_interface = target_interface
target_interface.partial_interfaces.append(dependency_interface)
resolved_definitions[dependency_component] = dependency_definitions
@@ -221,20 +230,21 @@ def merge_interface_dependencies(definitions, component, target_interface, depen
# - An interface defined in core cannot include an interface mixin
# defined in modules.
if not dependency_interface.is_mixin:
- raise Exception('The interface:%s cannot include '
- 'the non-mixin interface: %s.' % (
- target_interface.name,
- dependency_interface.name))
-
- if not is_valid_component_dependency(component, dependency_component):
- raise Exception('The interface:%s in %s cannot include '
- 'the interface mixin:%s in %s.' % (
- target_interface.name,
- component,
- dependency_interface.name,
- dependency_component))
-
- resolved_definitions[component].update(dependency_definitions) # merges partial interfaces
+ raise Exception(
+ 'The interface:%s cannot include '
+ 'the non-mixin interface: %s.' %
+ (target_interface.name, dependency_interface.name))
+
+ if not is_valid_component_dependency(component,
+ dependency_component):
+ raise Exception(
+ 'The interface:%s in %s cannot include '
+ 'the interface mixin:%s in %s.' %
+ (target_interface.name, component,
+ dependency_interface.name, dependency_component))
+
+ # merges partial interfaces
+ resolved_definitions[component].update(dependency_definitions)
# Mixins are also merged into the target interface, so Code
# Generator can just iterate over one list (and not need to handle
# 'includes' itself).
@@ -243,7 +253,8 @@ def merge_interface_dependencies(definitions, component, target_interface, depen
return resolved_definitions
-def transfer_extended_attributes(dependency_interface, dependency_idl_filename):
+def transfer_extended_attributes(dependency_interface,
+ dependency_idl_filename):
"""Transfer extended attributes from dependency interface onto members.
Merging consists of storing certain interface-level data in extended
@@ -263,7 +274,8 @@ def transfer_extended_attributes(dependency_interface, dependency_idl_filename):
if key not in dependency_interface.extended_attributes:
continue
- merged_extended_attributes[key] = dependency_interface.extended_attributes[key]
+ merged_extended_attributes[key] = \
+ dependency_interface.extended_attributes[key]
# Remove the merged attributes from the original dependency interface.
# This ensures that if other dependency interfaces are merged onto this
# one, its extended_attributes do not leak through
@@ -307,11 +319,14 @@ def transfer_extended_attributes(dependency_interface, dependency_idl_filename):
attributes[key] = value
for attribute in dependency_interface.attributes:
- update_attributes(attribute.extended_attributes, merged_extended_attributes)
+ update_attributes(attribute.extended_attributes,
+ merged_extended_attributes)
for constant in dependency_interface.constants:
- update_attributes(constant.extended_attributes, merged_extended_attributes)
+ update_attributes(constant.extended_attributes,
+ merged_extended_attributes)
for operation in dependency_interface.operations:
- update_attributes(operation.extended_attributes, merged_extended_attributes)
+ update_attributes(operation.extended_attributes,
+ merged_extended_attributes)
def inherit_unforgeable_attributes(resolved_definitions, interfaces_info):
@@ -322,35 +337,47 @@ def inherit_unforgeable_attributes(resolved_definitions, interfaces_info):
'referenced_interfaces' and 'cpp_includes' in |interfaces_info| are updated
accordingly.
"""
+
def collect_unforgeable_attributes_in_ancestors(interface_name, component):
if not interface_name:
# unforgeable_attributes, referenced_interfaces, cpp_includes
return [], [], set()
interface = interfaces_info[interface_name]
- unforgeable_attributes, referenced_interfaces, cpp_includes = collect_unforgeable_attributes_in_ancestors(interface.get('parent'), component)
+ unforgeable_attributes, referenced_interfaces, cpp_includes = \
+ collect_unforgeable_attributes_in_ancestors(
+ interface.get('parent'), component)
this_unforgeable = interface.get('unforgeable_attributes', [])
for attr in this_unforgeable:
if attr.defined_in is None:
attr.defined_in = interface_name
unforgeable_attributes.extend(this_unforgeable)
- this_referenced = [attr.idl_type.base_type for attr in this_unforgeable
- if attr.idl_type.base_type in
- interface.get('referenced_interfaces', [])]
+ this_referenced = [
+ attr.idl_type.base_type for attr in this_unforgeable
+ if attr.idl_type.base_type in interface.get(
+ 'referenced_interfaces', [])
+ ]
referenced_interfaces.extend(this_referenced)
- cpp_includes.update(interface.get('cpp_includes', {}).get(component, {}))
+ cpp_includes.update(
+ interface.get('cpp_includes', {}).get(component, {}))
return unforgeable_attributes, referenced_interfaces, cpp_includes
- for component, definitions in resolved_definitions.iteritems():
- for interface_name, interface in definitions.interfaces.iteritems():
+ for component, definitions in resolved_definitions.items():
+ for interface_name, interface in definitions.interfaces.items():
interface_info = interfaces_info[interface_name]
- inherited_unforgeable_attributes, referenced_interfaces, cpp_includes = collect_unforgeable_attributes_in_ancestors(interface_info.get('parent'), component)
+ inherited_unforgeable_attributes, referenced_interfaces, cpp_includes = \
+ collect_unforgeable_attributes_in_ancestors(
+ interface_info.get('parent'), component)
# This loop may process the same interface many times, so it's
# possible that we're adding the same attributes twice or more.
# So check if there is a duplicate.
for attr in inherited_unforgeable_attributes:
if attr not in interface.attributes:
interface.attributes.append(attr)
- referenced_interfaces.extend(interface_info.get('referenced_interfaces', []))
- interface_info['referenced_interfaces'] = sorted(set(referenced_interfaces))
+ referenced_interfaces.extend(
+ interface_info.get('referenced_interfaces', []))
+ interface_info['referenced_interfaces'] = sorted(
+ set(referenced_interfaces))
merge_dict_recursively(interface_info,
- {'cpp_includes': {component: cpp_includes}})
+ {'cpp_includes': {
+ component: cpp_includes
+ }})
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/overload_set_algorithm.py b/chromium/third_party/blink/renderer/bindings/scripts/overload_set_algorithm.py
index 351ca8e40ed..309de695493 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/overload_set_algorithm.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/overload_set_algorithm.py
@@ -182,11 +182,12 @@ def method_overloads_by_name(methods):
"""Returns generator of overloaded methods by name: [name, [method]]"""
# Filter to only methods that are actually overloaded
method_counts = Counter(method['name'] for method in methods)
- overloaded_method_names = set(name
- for name, count in method_counts.iteritems()
- if count > 1)
- overloaded_methods = [method for method in methods
- if method['name'] in overloaded_method_names]
+ overloaded_method_names = set(
+ name for name, count in method_counts.items() if count > 1)
+ overloaded_methods = [
+ method for method in methods
+ if method['name'] in overloaded_method_names
+ ]
# Group by name (generally will be defined together, but not necessarily)
return sort_and_groupby(overloaded_methods, itemgetter('name'))
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/overload_set_algorithm_test.py b/chromium/third_party/blink/renderer/bindings/scripts/overload_set_algorithm_test.py
index 44ccd2095b1..3a94c06e615 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/overload_set_algorithm_test.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/overload_set_algorithm_test.py
@@ -3,12 +3,14 @@
# found in the LICENSE file.
# pylint: disable=import-error,print-statement,relative-import,protected-access
-
"""Unit tests for overload_set_algorithm.py."""
import unittest
from overload_set_algorithm import effective_overload_set
+# disabling yapf formating for complex data, see
+# https://github.com/google/yapf#why-does-yapf-destroy-my-awesome-formatting
+# yapf: disable
class EffectiveOverloadSetTest(unittest.TestCase):
def test_example_in_comments(self):
@@ -334,3 +336,4 @@ class EffectiveOverloadSetTest(unittest.TestCase):
())]
self.assertEqual(effective_overload_set(operation_list), overload_set)
+# yapf: enable
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/scripts.gni b/chromium/third_party/blink/renderer/bindings/scripts/scripts.gni
index 00a0b2a5ce5..9f1b79be3e6 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/scripts.gni
+++ b/chromium/third_party/blink/renderer/bindings/scripts/scripts.gni
@@ -125,9 +125,7 @@ template("generate_event_interfaces") {
output_file =
"$root_gen_dir/third_party/blink/renderer/" + invoker.output_file
- outputs = [
- output_file,
- ]
+ outputs = [ output_file ]
script = "//third_party/blink/renderer/bindings/scripts/generate_event_interfaces.py"
args = [
@@ -161,7 +159,9 @@ template("idl_compiler") {
# "import site" to speed up startup. Figure out if we need this and do
# something similar (not really expressible in GN now).
_script = "//third_party/blink/renderer/bindings/scripts/idl_compiler.py"
- _inputs = idl_lexer_parser_files + idl_compiler_files # to be explicit (covered by parsetab)
+ _inputs =
+ idl_lexer_parser_files + idl_compiler_files # to be explicit (covered by
+ # parsetab)
_inputs += [
"$bindings_scripts_output_dir/lextab.py",
"$bindings_scripts_output_dir/parsetab.pickle",
@@ -250,7 +250,9 @@ template("idl_impl") {
idl_files_list = "$target_gen_dir/${target_name}_file_list.tmp"
write_file(idl_files_list, rebase_path(invoker.dict_idls, root_build_dir))
- inputs = idl_lexer_parser_files + idl_compiler_files # to be explicit (covered by parsetab)
+ inputs =
+ idl_lexer_parser_files + idl_compiler_files # to be explicit (covered
+ # by parsetab)
inputs += [
"$bindings_scripts_output_dir/lextab.py",
"$bindings_scripts_output_dir/parsetab.pickle",
@@ -342,9 +344,7 @@ template("compute_global_objects") {
idl_files_list,
] + invoker.sources_generated + invoker.sources
- outputs = [
- invoker.output_file,
- ]
+ outputs = [ invoker.output_file ]
args = [
"--idl-files-list",
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/utilities.py b/chromium/third_party/blink/renderer/bindings/scripts/utilities.py
index ebca696912d..1dc06544585 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/utilities.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/utilities.py
@@ -1,24 +1,25 @@
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-
"""Utility functions (file reading, simple IDL parsing by regexes) for IDL build.
Design doc: http://www.chromium.org/developers/design-documents/idl-build
"""
import os
-import cPickle as pickle
import re
import shlex
-import string
import subprocess
import sys
-sys.path.append(os.path.join(os.path.dirname(__file__),
- '..', '..', 'build', 'scripts'))
-from blinkbuild.name_style_converter import NameStyleConverter
+if sys.version_info.major == 2:
+ import cPickle as pickle
+else:
+ import pickle
+sys.path.append(
+ os.path.join(os.path.dirname(__file__), '..', '..', 'build', 'scripts'))
+from blinkbuild.name_style_converter import NameStyleConverter
KNOWN_COMPONENTS = frozenset(['core', 'modules'])
KNOWN_COMPONENTS_WITH_TESTING = frozenset(['core', 'modules', 'testing'])
@@ -29,7 +30,8 @@ def idl_filename_to_basename(idl_filename):
return os.path.splitext(os.path.basename(idl_filename))[0]
-def idl_filename_to_component_with_known_components(idl_filename, known_components):
+def idl_filename_to_component_with_known_components(idl_filename,
+ known_components):
path = os.path.dirname(os.path.realpath(idl_filename))
while path:
dirname, basename = os.path.split(path)
@@ -42,11 +44,13 @@ def idl_filename_to_component_with_known_components(idl_filename, known_componen
def idl_filename_to_component(idl_filename):
- return idl_filename_to_component_with_known_components(idl_filename, KNOWN_COMPONENTS)
+ return idl_filename_to_component_with_known_components(
+ idl_filename, KNOWN_COMPONENTS)
def is_testing_target(idl_filename):
- component = idl_filename_to_component_with_known_components(idl_filename, KNOWN_COMPONENTS_WITH_TESTING)
+ component = idl_filename_to_component_with_known_components(
+ idl_filename, KNOWN_COMPONENTS_WITH_TESTING)
return component == 'testing'
@@ -69,6 +73,7 @@ class ComponentInfoProvider(object):
"""Base class of information provider which provides component-specific
information.
"""
+
def __init__(self):
pass
@@ -176,11 +181,14 @@ class ComponentInfoProviderModules(ComponentInfoProvider):
def union_types(self):
# Remove duplicate union types from component_info_modules to avoid
# generating multiple container generation.
- return self._component_info_modules['union_types'] - self._component_info_core['union_types']
+ return (self._component_info_modules['union_types'] -
+ self._component_info_core['union_types'])
def include_path_for_union_types(self, union_type):
- core_union_type_names = [core_union_type.name for core_union_type
- in self._component_info_core['union_types']]
+ core_union_type_names = [
+ core_union_type.name
+ for core_union_type in self._component_info_core['union_types']
+ ]
name = shorten_union_name(union_type)
if union_type.name in core_union_type_names:
return 'bindings/core/v8/%s.h' % to_snake_case(name)
@@ -201,7 +209,8 @@ class ComponentInfoProviderModules(ComponentInfoProvider):
def load_interfaces_info_overall_pickle(info_dir):
- with open(os.path.join(info_dir, 'interfaces_info.pickle')) as interface_info_file:
+ with open(os.path.join(info_dir,
+ 'interfaces_info.pickle')) as interface_info_file:
return pickle.load(interface_info_file)
@@ -210,7 +219,7 @@ def merge_dict_recursively(target, diff):
|target| will be updated with |diff|. Part of |diff| may be re-used in
|target|.
"""
- for key, value in diff.iteritems():
+ for key, value in diff.items():
if key not in target:
target[key] = value
elif type(value) == dict:
@@ -227,19 +236,26 @@ def merge_dict_recursively(target, diff):
def create_component_info_provider_core(info_dir):
interfaces_info = load_interfaces_info_overall_pickle(info_dir)
- with open(os.path.join(info_dir, 'core', 'component_info_core.pickle')) as component_info_file:
+ with open(
+ os.path.join(info_dir, 'core',
+ 'component_info_core.pickle')) as component_info_file:
component_info = pickle.load(component_info_file)
return ComponentInfoProviderCore(interfaces_info, component_info)
def create_component_info_provider_modules(info_dir):
interfaces_info = load_interfaces_info_overall_pickle(info_dir)
- with open(os.path.join(info_dir, 'core', 'component_info_core.pickle')) as component_info_file:
+ with open(
+ os.path.join(info_dir, 'core',
+ 'component_info_core.pickle')) as component_info_file:
component_info_core = pickle.load(component_info_file)
- with open(os.path.join(info_dir, 'modules', 'component_info_modules.pickle')) as component_info_file:
+ with open(
+ os.path.join(
+ info_dir, 'modules',
+ 'component_info_modules.pickle')) as component_info_file:
component_info_modules = pickle.load(component_info_file)
- return ComponentInfoProviderModules(
- interfaces_info, component_info_core, component_info_modules)
+ return ComponentInfoProviderModules(interfaces_info, component_info_core,
+ component_info_modules)
def create_component_info_provider(info_dir, component):
@@ -255,6 +271,7 @@ def create_component_info_provider(info_dir, component):
# Basic file reading/writing
################################################################################
+
def get_file_contents(filename):
with open(filename) as f:
return f.read()
@@ -270,7 +287,11 @@ def resolve_cygpath(cygdrive_names):
if not cygdrive_names:
return []
cmd = ['cygpath', '-f', '-', '-wa']
- process = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ process = subprocess.Popen(
+ cmd,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
idl_file_names = []
for file_name in cygdrive_names:
process.stdin.write('%s\n' % file_name)
@@ -285,10 +306,14 @@ def read_idl_files_list_from_file(filename):
"""Similar to read_file_to_list, but also resolves cygpath."""
with open(filename) as input_file:
file_names = sorted(shlex.split(input_file))
- idl_file_names = [file_name for file_name in file_names
- if not file_name.startswith('/cygdrive')]
- cygdrive_names = [file_name for file_name in file_names
- if file_name.startswith('/cygdrive')]
+ idl_file_names = [
+ file_name for file_name in file_names
+ if not file_name.startswith('/cygdrive')
+ ]
+ cygdrive_names = [
+ file_name for file_name in file_names
+ if file_name.startswith('/cygdrive')
+ ]
idl_file_names.extend(resolve_cygpath(cygdrive_names))
return idl_file_names
@@ -299,7 +324,7 @@ def read_pickle_files(pickle_filenames):
def read_pickle_file(pickle_filename):
- with open(pickle_filename) as pickle_file:
+ with open(pickle_filename, 'rb') as pickle_file:
return pickle.load(pickle_file)
@@ -311,12 +336,12 @@ def write_file(new_text, destination_filename):
return
destination_dirname = os.path.dirname(destination_filename)
- if not os.path.exists(destination_dirname):
+ if destination_dirname and not os.path.exists(destination_dirname):
os.makedirs(destination_dirname)
# Write file in binary so that when run on Windows, line endings are not
# converted
with open(destination_filename, 'wb') as destination_file:
- destination_file.write(new_text)
+ destination_file.write(new_text.encode('utf-8'))
def write_pickle_file(pickle_filename, data):
@@ -329,7 +354,7 @@ def write_pickle_file(pickle_filename, data):
except Exception:
# If trouble unpickling, overwrite
pass
- with open(pickle_filename, 'w') as pickle_file:
+ with open(pickle_filename, 'wb') as pickle_file:
pickle.dump(data, pickle_file)
@@ -342,6 +367,7 @@ def write_pickle_file(pickle_filename, data):
# Leading and trailing context (e.g. following '{') used to avoid false matches.
################################################################################
+
def is_non_legacy_callback_interface_from_idl(file_contents):
"""Returns True if the specified IDL is a non-legacy callback interface."""
match = re.search(r'callback\s+interface\s+\w+\s*{', file_contents)
@@ -378,20 +404,24 @@ def match_interface_extended_attributes_and_name_from_idl(file_contents):
r'(\w+)\s*'
r'(:\s*\w+\s*)?'
r'{',
- file_contents, flags=re.DOTALL)
+ file_contents,
+ flags=re.DOTALL)
return match
def get_interface_extended_attributes_from_idl(file_contents):
- match = match_interface_extended_attributes_and_name_from_idl(file_contents)
+ match = match_interface_extended_attributes_and_name_from_idl(
+ file_contents)
if not match or not match.group(1):
return {}
extended_attributes_string = match.group(1).strip()
- parts = [extended_attribute.strip()
- for extended_attribute in re.split(',', extended_attributes_string)
- # Discard empty parts, which may exist due to trailing comma
- if extended_attribute.strip()]
+ parts = [
+ extended_attribute.strip()
+ for extended_attribute in re.split(',', extended_attributes_string)
+ # Discard empty parts, which may exist due to trailing comma
+ if extended_attribute.strip()
+ ]
# Joins |parts| with commas as far as the parences are not balanced,
# and then converts a (joined) term to a dict entry.
@@ -406,14 +436,15 @@ def get_interface_extended_attributes_from_idl(file_contents):
if parences < 0 or square_brackets < 0:
raise ValueError('You have more close braces than open braces.')
if parences == 0 and square_brackets == 0:
- name, _, value = map(string.strip, concatenated.partition('='))
+ name, _, value = map(str.strip, concatenated.partition('='))
extended_attributes[name] = value
concatenated = None
return extended_attributes
def get_interface_exposed_arguments(file_contents):
- match = match_interface_extended_attributes_and_name_from_idl(file_contents)
+ match = match_interface_extended_attributes_and_name_from_idl(
+ file_contents)
if not match or not match.group(1):
return None
@@ -422,15 +453,19 @@ def get_interface_exposed_arguments(file_contents):
if not match:
return None
arguments = []
- for argument in map(string.strip, match.group(1).split(',')):
+ for argument in map(str.strip, match.group(1).split(',')):
exposed, runtime_enabled = argument.split()
- arguments.append({'exposed': exposed, 'runtime_enabled': runtime_enabled})
+ arguments.append({
+ 'exposed': exposed,
+ 'runtime_enabled': runtime_enabled
+ })
return arguments
def get_first_interface_name_from_idl(file_contents):
- match = match_interface_extended_attributes_and_name_from_idl(file_contents)
+ match = match_interface_extended_attributes_and_name_from_idl(
+ file_contents)
if match:
return match.group(3)
return None
@@ -442,21 +477,28 @@ def get_first_interface_name_from_idl(file_contents):
def shorten_union_name(union_type):
aliases = {
# modules/canvas2d/CanvasRenderingContext2D.idl
- 'CSSImageValueOrHTMLImageElementOrSVGImageElementOrHTMLVideoElementOrHTMLCanvasElementOrImageBitmapOrOffscreenCanvas': 'CanvasImageSource',
+ 'CSSImageValueOrHTMLImageElementOrSVGImageElementOrHTMLVideoElementOrHTMLCanvasElementOrImageBitmapOrOffscreenCanvas':
+ 'CanvasImageSource',
# modules/canvas/htmlcanvas/html_canvas_element_module_support_webgl2_compute.idl
# Due to html_canvas_element_module_support_webgl2_compute.idl and html_canvas_element_module.idl are exclusive in modules_idl_files.gni, they have same shorten name.
- 'CanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrWebGL2ComputeRenderingContextOrImageBitmapRenderingContextOrGPUCanvasContext': 'RenderingContext',
+ 'CanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrWebGL2ComputeRenderingContextOrImageBitmapRenderingContextOrGPUCanvasContext':
+ 'RenderingContext',
# modules/canvas/htmlcanvas/html_canvas_element_module.idl
- 'CanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrImageBitmapRenderingContextOrGPUCanvasContext': 'RenderingContext',
+ 'CanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrImageBitmapRenderingContextOrGPUCanvasContext':
+ 'RenderingContext',
# core/frame/window_or_worker_global_scope.idl
- 'HTMLImageElementOrSVGImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrImageBitmapOrOffscreenCanvas': 'ImageBitmapSource',
+ 'HTMLImageElementOrSVGImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrImageBitmapOrOffscreenCanvas':
+ 'ImageBitmapSource',
# bindings/tests/idls/core/TestTypedefs.idl
- 'NodeOrLongSequenceOrEventOrXMLHttpRequestOrStringOrStringByteStringOrNodeListRecord': 'NestedUnionType',
+ 'NodeOrLongSequenceOrEventOrXMLHttpRequestOrStringOrStringByteStringOrNodeListRecord':
+ 'NestedUnionType',
# modules/canvas/offscreencanvas/offscreen_canvas_module_support_webgl2_compute.idl.
# Due to offscreen_canvas_module_support_webgl2_compute.idl and offscreen_canvas_module.idl are exclusive in modules_idl_files.gni, they have same shorten name.
- 'OffscreenCanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrWebGL2ComputeRenderingContextOrImageBitmapRenderingContext': 'OffscreenRenderingContext',
+ 'OffscreenCanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrWebGL2ComputeRenderingContextOrImageBitmapRenderingContext':
+ 'OffscreenRenderingContext',
# modules/canvas/offscreencanvas/offscreen_canvas_module.idl
- 'OffscreenCanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrImageBitmapRenderingContext': 'OffscreenRenderingContext',
+ 'OffscreenCanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrImageBitmapRenderingContext':
+ 'OffscreenRenderingContext',
}
idl_type = union_type
@@ -563,7 +605,8 @@ def format_blink_cpp_source_code(text):
if was_open_brace:
# No empty line just after an open brace.
pass
- elif match and match.group('first') == '}' and 'namespace' not in line:
+ elif (match and match.group('first') == '}'
+ and 'namespace' not in line):
# No empty line just before a closing brace.
pass
else:
@@ -578,7 +621,8 @@ def format_blink_cpp_source_code(text):
match = re_last_brace.search(line)
else:
match = None
- was_open_brace = (match and match.group('last') == '{' and 'namespace' not in line)
+ was_open_brace = (match and match.group('last') == '{'
+ and 'namespace' not in line)
# Let |'\n'.join| emit the last newline.
if output:
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 e58cc6148f5..26fbd984024 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/v8_attributes.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_attributes.py
@@ -27,7 +27,6 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# pylint: disable=relative-import
-
"""Generate template values for attributes.
Extends IdlType with property |constructor_type_name|.
@@ -38,17 +37,23 @@ Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
import os
import sys
-sys.path.append(os.path.join(os.path.dirname(__file__),
- '..', '..', 'build', 'scripts'))
+sys.path.append(
+ os.path.join(os.path.dirname(__file__), '..', '..', 'build', 'scripts'))
from blinkbuild.name_style_converter import NameStyleConverter
import idl_types
from idl_types import inherits_interface
from v8_globals import includes
import v8_types
import v8_utilities
-from v8_utilities import (cpp_name_or_partial, capitalize, cpp_name, has_extended_attribute,
- has_extended_attribute_value, scoped_name, strip_suffix,
- uncapitalize, extended_attribute_value_as_list, is_unforgeable)
+from v8_utilities import capitalize
+from v8_utilities import cpp_encoded_property_name
+from v8_utilities import cpp_name
+from v8_utilities import extended_attribute_value_as_list
+from v8_utilities import has_extended_attribute_value
+from v8_utilities import is_unforgeable
+from v8_utilities import scoped_name
+from v8_utilities import strip_suffix
+from v8_utilities import uncapitalize
from blinkbuild.name_style_converter import NameStyleConverter
@@ -73,14 +78,14 @@ def attribute_context(interface, attribute, interfaces, component_info):
idl_type.add_includes_for_type(extended_attributes)
if idl_type.enum_values:
includes.add('core/inspector/console_message.h')
+ includes.add('platform/heap/heap.h')
# [CheckSecurity]
is_cross_origin = 'CrossOrigin' in extended_attributes
- is_check_security_for_receiver = (
- has_extended_attribute_value(interface, 'CheckSecurity', 'Receiver') and
- is_cross_origin)
- is_check_security_for_return_value = (
- has_extended_attribute_value(attribute, 'CheckSecurity', 'ReturnValue'))
+ is_check_security_for_receiver = (has_extended_attribute_value(
+ interface, 'CheckSecurity', 'Receiver') and is_cross_origin)
+ is_check_security_for_return_value = (has_extended_attribute_value(
+ attribute, 'CheckSecurity', 'ReturnValue'))
if is_check_security_for_receiver or is_check_security_for_return_value:
includes.add('bindings/core/v8/binding_security.h')
if is_check_security_for_return_value:
@@ -93,7 +98,8 @@ def attribute_context(interface, attribute, interfaces, component_info):
# TODO(yukishiino): Constructors are much like methods although constructors
# are not methods. Constructors must be data-type properties, and we can
# support them as a kind of methods.
- constructor_type = idl_type.constructor_type_name if is_constructor_attribute(attribute) else None
+ constructor_type = idl_type.constructor_type_name if is_constructor_attribute(
+ attribute) else None
# [CEReactions]
is_ce_reactions = 'CEReactions' in extended_attributes
if is_ce_reactions:
@@ -111,11 +117,17 @@ def attribute_context(interface, attribute, interfaces, component_info):
includes.add('core/html/custom/v0_custom_element_processing_stack.h')
# [PerWorldBindings]
if 'PerWorldBindings' in extended_attributes:
- assert idl_type.is_wrapper_type or 'LogActivity' in extended_attributes, '[PerWorldBindings] should only be used with wrapper types: %s.%s' % (interface.name, attribute.name)
+ assert idl_type.is_wrapper_type or 'LogActivity' in \
+ extended_attributes, \
+ '[PerWorldBindings] should only be used with wrapper types: %s.%s' % \
+ (interface.name, attribute.name)
# [SaveSameObject]
- is_save_same_object = (
- 'SameObject' in attribute.extended_attributes and
- 'SaveSameObject' in attribute.extended_attributes)
+ is_save_same_object = ('SameObject' in attribute.extended_attributes and
+ 'SaveSameObject' in attribute.extended_attributes)
+
+ # [StringContext]
+ if idl_type.has_string_context:
+ includes.add('bindings/core/v8/generated_code_helper.h')
# [CachedAccessor]
is_cached_accessor = 'CachedAccessor' in extended_attributes
@@ -124,40 +136,29 @@ def attribute_context(interface, attribute, interfaces, component_info):
is_lenient_setter = 'LenientSetter' in extended_attributes
# [CachedAttribute]
- cached_attribute_validation_method = extended_attributes.get('CachedAttribute')
+ cached_attribute_validation_method = extended_attributes.get(
+ 'CachedAttribute')
keep_alive_for_gc = is_keep_alive_for_gc(interface, attribute)
- does_generate_getter = (
- not has_custom_getter(attribute) and
- not constructor_type
- )
+ does_generate_getter = (not has_custom_getter(attribute)
+ and not constructor_type)
does_generate_setter = (
- has_setter(interface, attribute) and
- not (has_custom_setter(attribute) or is_lenient_setter)
- )
-
- use_private_property_in_getter = (
- does_generate_getter and (
- cached_attribute_validation_method or
- is_save_same_object or
- keep_alive_for_gc
- )
- )
- use_private_property_in_setter = (
- does_generate_setter and
- cached_attribute_validation_method
- )
+ has_setter(interface, attribute)
+ and not (has_custom_setter(attribute) or is_lenient_setter))
+
+ use_private_property_in_getter = (does_generate_getter
+ and (cached_attribute_validation_method
+ or is_save_same_object
+ or keep_alive_for_gc))
+ use_private_property_in_setter = (does_generate_setter
+ and cached_attribute_validation_method)
private_property_is_shared_between_getter_and_setter = (
- use_private_property_in_getter and
- use_private_property_in_setter
- )
-
- does_use_private_property = (
- use_private_property_in_getter or
- use_private_property_in_setter or
- is_cached_accessor
- )
+ use_private_property_in_getter and use_private_property_in_setter)
+
+ does_use_private_property = (use_private_property_in_getter
+ or use_private_property_in_setter
+ or is_cached_accessor)
if does_use_private_property:
includes.add('platform/bindings/v8_private_property.h')
@@ -178,29 +179,50 @@ def attribute_context(interface, attribute, interfaces, component_info):
runtime_features = component_info['runtime_enabled_features']
+ internal_name = cpp_encoded_property_name(attribute)
+
+ cpp_type = idl_type.cpp_type
+ if idl_type.is_explicit_nullable:
+ cpp_type = v8_types.cpp_template_type('base::Optional', cpp_type)
+
context = {
- 'activity_logging_world_list_for_getter': v8_utilities.activity_logging_world_list(attribute, 'Getter'), # [ActivityLogging]
- 'activity_logging_world_list_for_setter': v8_utilities.activity_logging_world_list(attribute, 'Setter'), # [ActivityLogging]
- 'activity_logging_world_check': v8_utilities.activity_logging_world_check(attribute), # [ActivityLogging]
- 'cached_accessor_name': '%s%sCachedAccessor' % (interface.name, attribute.name.capitalize()),
- 'cached_attribute_validation_method': cached_attribute_validation_method,
- 'camel_case_name': NameStyleConverter(attribute.name).to_upper_camel_case(),
- 'constructor_type': constructor_type,
- 'context_enabled_feature_name': v8_utilities.context_enabled_feature_name(attribute),
+ # [ActivityLogging]
+ 'activity_logging_world_list_for_getter':
+ v8_utilities.activity_logging_world_list(attribute, 'Getter'),
+ # [ActivityLogging]
+ 'activity_logging_world_list_for_setter':
+ v8_utilities.activity_logging_world_list(attribute, 'Setter'),
+ # [ActivityLogging]
+ 'activity_logging_world_check':
+ v8_utilities.activity_logging_world_check(attribute),
+ 'cached_accessor_name':
+ '%s%sCachedAccessor' % (interface.name, attribute.name.capitalize()),
+ 'cached_attribute_validation_method':
+ cached_attribute_validation_method,
+ 'camel_case_name':
+ NameStyleConverter(internal_name).to_upper_camel_case(),
+ 'constructor_type':
+ constructor_type,
+ 'context_enabled_feature_name':
+ v8_utilities.context_enabled_feature_name(attribute),
'cpp_name': cpp_name(attribute),
- 'cpp_type': idl_type.cpp_type,
+ 'cpp_type': cpp_type,
'cpp_type_initializer': idl_type.cpp_type_initializer,
'deprecate_as': deprecate_as,
'does_generate_getter': does_generate_getter,
'does_generate_setter': does_generate_setter,
'enum_type': idl_type.enum_type,
'enum_values': idl_type.enum_values,
- 'exposed_test': v8_utilities.exposed(attribute, interface), # [Exposed]
- 'getter_has_no_side_effect': has_extended_attribute_value(attribute, 'Affects', 'Nothing'),
+ # [Exposed]
+ 'exposed_test':
+ v8_utilities.exposed(attribute, interface),
+ 'getter_has_no_side_effect':
+ has_extended_attribute_value(attribute, 'Affects', 'Nothing'),
'has_cross_origin_getter':
has_extended_attribute_value(attribute, 'CrossOrigin', None) or
has_extended_attribute_value(attribute, 'CrossOrigin', 'Getter'),
- 'has_cross_origin_setter': has_extended_attribute_value(attribute, 'CrossOrigin', 'Setter'),
+ 'has_cross_origin_setter':
+ has_extended_attribute_value(attribute, 'CrossOrigin', 'Setter'),
'has_custom_getter': has_custom_getter(attribute),
'has_custom_setter': has_custom_setter(attribute),
'has_promise_type': idl_type.name == 'Promise',
@@ -208,11 +230,14 @@ def attribute_context(interface, attribute, interfaces, component_info):
'high_entropy': high_entropy,
'idl_type': str(idl_type),
'is_cached_accessor': is_cached_accessor,
- 'is_call_with_execution_context': has_extended_attribute_value(attribute, 'CallWith', 'ExecutionContext'),
- 'is_call_with_script_state': has_extended_attribute_value(attribute, 'CallWith', 'ScriptState'),
+ 'is_call_with_execution_context':
+ has_extended_attribute_value(attribute, 'CallWith', 'ExecutionContext'),
+ 'is_call_with_script_state':
+ has_extended_attribute_value(attribute, 'CallWith', 'ScriptState'),
'is_ce_reactions': is_ce_reactions,
'is_check_security_for_receiver': is_check_security_for_receiver,
- 'is_check_security_for_return_value': is_check_security_for_return_value,
+ 'is_check_security_for_return_value':
+ is_check_security_for_return_value,
'is_custom_element_callbacks': is_custom_element_callbacks,
# TODO(yukishiino): Make all DOM attributes accessor-type properties.
'is_data_type_property': is_data_type_property(interface, attribute),
@@ -242,9 +267,11 @@ def attribute_context(interface, attribute, interfaces, component_info):
'on_instance': v8_utilities.on_instance(interface, attribute),
'on_interface': v8_utilities.on_interface(interface, attribute),
'on_prototype': v8_utilities.on_prototype(interface, attribute),
+ # [RuntimeEnabled] for origin trial
'origin_trial_feature_name':
- v8_utilities.origin_trial_feature_name(attribute, runtime_features), # [RuntimeEnabled] for origin trial
- 'private_property_is_shared_between_getter_and_setter': private_property_is_shared_between_getter_and_setter,
+ v8_utilities.origin_trial_feature_name(attribute, runtime_features),
+ 'private_property_is_shared_between_getter_and_setter':
+ private_property_is_shared_between_getter_and_setter,
'property_attributes': property_attributes(interface, attribute),
'reflect_empty': cpp_content_attribute_value_name(
interface, extended_attributes.get('ReflectEmpty')),
@@ -253,9 +280,11 @@ def attribute_context(interface, attribute, interfaces, component_info):
'reflect_missing': cpp_content_attribute_value_name(
interface, extended_attributes.get('ReflectMissing')),
'reflect_only': reflect_only,
+ # [RuntimeEnabled] if not in origin trial
'runtime_enabled_feature_name':
- v8_utilities.runtime_enabled_feature_name(attribute, runtime_features), # [RuntimeEnabled] if not in origin trial
- 'secure_context_test': v8_utilities.secure_context(attribute, interface), # [SecureContext]
+ v8_utilities.runtime_enabled_feature_name(attribute, runtime_features),
+ # [SecureContext]
+ 'secure_context_test': v8_utilities.secure_context(attribute, interface),
'use_output_parameter_for_result': idl_type.use_output_parameter_for_result,
'world_suffixes': (
['', 'ForMainWorld']
@@ -275,28 +304,38 @@ def attribute_context(interface, attribute, interfaces, component_info):
# for them here.
if is_cross_origin:
if context['has_cross_origin_setter'] and context['has_custom_setter']:
- raise Exception('[CrossOrigin] and [Custom] are incompatible on the same setter: %s.%s', interface.name, attribute.name)
+ raise Exception(
+ '[CrossOrigin] and [Custom] are incompatible on the same setter: %s.%s',
+ interface.name, attribute.name)
if context['is_per_world_bindings']:
- raise Exception('[CrossOrigin] and [PerWorldBindings] are incompatible: %s.%s', interface.name, attribute.name)
+ raise Exception(
+ '[CrossOrigin] and [PerWorldBindings] are incompatible: %s.%s',
+ interface.name, attribute.name)
if context['constructor_type']:
- raise Exception('[CrossOrigin] cannot be used for constructors: %s.%s', interface.name, attribute.name)
+ raise Exception(
+ '[CrossOrigin] cannot be used for constructors: %s.%s',
+ interface.name, attribute.name)
return context
def runtime_call_stats_context(interface, attribute, context):
includes.add('platform/bindings/runtime_call_stats.h')
- generic_counter_name = 'Blink_' + v8_utilities.cpp_name(interface) + '_' + attribute.name
- (counter, extended_attribute_defined) = v8_utilities.rcs_counter_name(attribute, generic_counter_name)
+ generic_counter_name = (
+ 'Blink_' + v8_utilities.cpp_name(interface) + '_' + attribute.name)
+ (counter, extended_attribute_defined) = v8_utilities.rcs_counter_name(
+ attribute, generic_counter_name)
runtime_call_stats = {
- 'extended_attribute_defined': extended_attribute_defined,
- 'getter_counter': '%s_Getter' % counter,
- 'setter_counter': '%s_Setter' % counter,
- 'constructor_getter_callback_counter': '%s_ConstructorGetterCallback' % generic_counter_name,
+ 'extended_attribute_defined':
+ extended_attribute_defined,
+ 'getter_counter':
+ '%s_Getter' % counter,
+ 'setter_counter':
+ '%s_Setter' % counter,
+ 'constructor_getter_callback_counter':
+ '%s_ConstructorGetterCallback' % generic_counter_name,
}
- context.update({
- 'runtime_call_stats': runtime_call_stats
- })
+ context.update({'runtime_call_stats': runtime_call_stats})
def is_origin_trial_enabled(attribute):
@@ -308,46 +347,51 @@ def is_secure_context(attribute):
def filter_accessors(attributes):
- return [attribute for attribute in attributes if
- not (attribute['exposed_test'] or
- is_secure_context(attribute) or
- attribute['context_enabled_feature_name'] or
- is_origin_trial_enabled(attribute) or
- attribute['runtime_enabled_feature_name']) and
- not attribute['is_data_type_property']]
+ return [
+ attribute for attribute in attributes
+ if not (attribute['exposed_test'] or is_secure_context(attribute)
+ or attribute['context_enabled_feature_name']
+ or is_origin_trial_enabled(attribute)
+ or attribute['runtime_enabled_feature_name'])
+ and not attribute['is_data_type_property']
+ ]
def is_data_attribute(attribute):
- return (not (attribute['exposed_test'] or
- is_secure_context(attribute) or
- attribute['context_enabled_feature_name'] or
- is_origin_trial_enabled(attribute) or
- attribute['runtime_enabled_feature_name']) and
- attribute['is_data_type_property'])
+ return (not (attribute['exposed_test'] or is_secure_context(attribute)
+ or attribute['context_enabled_feature_name']
+ or is_origin_trial_enabled(attribute)
+ or attribute['runtime_enabled_feature_name'])
+ and attribute['is_data_type_property'])
def filter_data_attributes(attributes):
- return [attribute for attribute in attributes if is_data_attribute(attribute)]
+ return [
+ attribute for attribute in attributes if is_data_attribute(attribute)
+ ]
def filter_runtime_enabled(attributes):
- return [attribute for attribute in attributes if
- not (attribute['exposed_test'] or
- is_secure_context(attribute)) and
- attribute['runtime_enabled_feature_name']]
+ return [
+ attribute for attribute in attributes
+ if not (attribute['exposed_test'] or is_secure_context(attribute))
+ and attribute['runtime_enabled_feature_name']
+ ]
def filter_conditionally_enabled(attributes):
- return [attribute for attribute in attributes if
- attribute['exposed_test'] or
- (is_secure_context(attribute) and
- not is_origin_trial_enabled(attribute))]
+ return [
+ attribute for attribute in attributes
+ if attribute['exposed_test'] or (is_secure_context(
+ attribute) and not is_origin_trial_enabled(attribute))
+ ]
################################################################################
# Getter
################################################################################
+
def getter_context(interface, attribute, context):
idl_type = attribute.idl_type
base_idl_type = idl_type.base_type
@@ -360,51 +404,68 @@ def getter_context(interface, attribute, context):
# exceptions), we need to use a local variable.
# FIXME: check if compilers are smart enough to inline this, and if so,
# always use a local variable (for readability and CG simplicity).
- if (idl_type.is_explicit_nullable or
- base_idl_type == 'EventHandler' or
- 'CachedAttribute' in extended_attributes or
- 'ReflectOnly' in extended_attributes or
- context['is_keep_alive_for_gc'] or
- context['is_getter_raises_exception']):
+ if (idl_type.is_explicit_nullable or base_idl_type == 'EventHandler'
+ or 'CachedAttribute' in extended_attributes
+ or 'ReflectOnly' in extended_attributes
+ or context['is_keep_alive_for_gc']
+ or context['is_getter_raises_exception']):
context['cpp_value_original'] = cpp_value
cpp_value = 'cpp_value'
def v8_set_return_value_statement(for_main_world=False):
- if context['is_keep_alive_for_gc'] or 'CachedAttribute' in extended_attributes:
+ if (context['is_keep_alive_for_gc']
+ or 'CachedAttribute' in extended_attributes):
return 'V8SetReturnValue(info, v8_value)'
+ if idl_type.is_explicit_nullable:
+ cpp_return_value = 'cpp_value.value()'
+ if idl_type.is_frozen_array:
+ cpp_return_value = 'FreezeV8Object(ToV8(cpp_value.value(), info.Holder(), info.GetIsolate()), info.GetIsolate())'
+ return 'V8SetReturnValue(info, {})'.format(cpp_return_value)
return idl_type.v8_set_return_value(
- cpp_value, extended_attributes=extended_attributes, script_wrappable='impl',
- for_main_world=for_main_world, is_static=attribute.is_static)
+ cpp_value,
+ extended_attributes=extended_attributes,
+ script_wrappable='impl',
+ for_main_world=for_main_world,
+ is_static=attribute.is_static)
cpp_value_to_script_wrappable = cpp_value
if idl_type.is_array_buffer_view_or_typed_array:
cpp_value_to_script_wrappable += '.View()'
context.update({
- 'cpp_value': cpp_value,
- 'cpp_value_to_script_wrappable': cpp_value_to_script_wrappable,
- 'cpp_value_to_v8_value': idl_type.cpp_value_to_v8_value(
- cpp_value=cpp_value, creation_context='holder',
+ 'cpp_value':
+ cpp_value,
+ 'cpp_value_to_script_wrappable':
+ cpp_value_to_script_wrappable,
+ 'cpp_value_to_v8_value':
+ idl_type.cpp_value_to_v8_value(
+ cpp_value=cpp_value,
+ creation_context='holder',
extended_attributes=extended_attributes),
- 'v8_set_return_value_for_main_world': v8_set_return_value_statement(for_main_world=True),
- 'v8_set_return_value': v8_set_return_value_statement(),
+ 'v8_set_return_value_for_main_world':
+ v8_set_return_value_statement(for_main_world=True),
+ 'v8_set_return_value':
+ v8_set_return_value_statement(),
})
+
def getter_expression(interface, attribute, context):
- arguments = []
- this_getter_base_name = getter_base_name(interface, attribute, arguments)
+ extra_arguments = []
+ this_getter_base_name = getter_base_name(interface, attribute,
+ extra_arguments)
getter_name = scoped_name(interface, attribute, this_getter_base_name)
- arguments.extend(v8_utilities.call_with_arguments(
- attribute.extended_attributes.get('CallWith')))
+ arguments = []
+ arguments.extend(
+ v8_utilities.call_with_arguments(
+ 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
- if ('PartialInterfaceImplementedAs' in attribute.extended_attributes and
- not attribute.is_static):
+ if ('PartialInterfaceImplementedAs' in attribute.extended_attributes
+ and not attribute.is_static):
arguments.append('*impl')
- if attribute.idl_type.is_explicit_nullable:
- arguments.append('is_null')
+ arguments.extend(extra_arguments)
if context['is_getter_raises_exception']:
arguments.append('exception_state')
if attribute.idl_type.use_output_parameter_for_result:
@@ -413,8 +474,8 @@ def getter_expression(interface, attribute, context):
expression = '%s(%s)' % (getter_name, ', '.join(arguments))
# Needed to handle getter expressions returning Type& as the
# use site for |expression| expects Type*.
- if (attribute.idl_type.is_interface_type and len(arguments) == 0 and
- not attribute.idl_type.is_array_buffer_view_or_typed_array):
+ if (attribute.idl_type.is_interface_type and len(arguments) == 0
+ and not attribute.idl_type.is_array_buffer_view_or_typed_array):
return 'WTF::GetPtr(%s)' % expression
return expression
@@ -435,7 +496,8 @@ def getter_base_name(interface, attribute, arguments):
return name if 'ImplementedAs' in extended_attributes \
else uncapitalize(name)
- content_attribute_name = extended_attributes['Reflect'] or attribute.name.lower()
+ content_attribute_name = (extended_attributes['Reflect']
+ or attribute.name.lower())
if content_attribute_name in ['class', 'id', 'name']:
# Special-case for performance optimization.
return 'Get%sAttribute' % content_attribute_name.capitalize()
@@ -459,28 +521,31 @@ def is_keep_alive_for_gc(interface, attribute):
extended_attributes = attribute.extended_attributes
if attribute.is_static:
return False
+ if idl_type.is_array_buffer_or_view:
+ return False
return (
# For readonly attributes, for performance reasons we keep the attribute
# wrapper alive while the owner wrapper is alive, because the attribute
# never changes.
- (attribute.is_read_only and
- idl_type.is_wrapper_type and
- # There are some exceptions, however:
- not(
- # Node lifetime is managed by object grouping.
- inherits_interface(interface.name, 'Node') or
- inherits_interface(base_idl_type, 'Node') or
- # A self-reference is unnecessary.
- attribute.name == 'self' or
- # FIXME: Remove these hard-coded hacks.
- base_idl_type in ['EventTarget', 'Window'] or
- base_idl_type.startswith(('HTML', 'SVG')))))
+ (
+ attribute.is_read_only and idl_type.is_wrapper_type and
+ # There are some exceptions, however:
+ not (
+ # Node lifetime is managed by object grouping.
+ inherits_interface(interface.name, 'Node')
+ or inherits_interface(base_idl_type, 'Node') or
+ # A self-reference is unnecessary.
+ attribute.name == 'self' or
+ # FIXME: Remove these hard-coded hacks.
+ base_idl_type in ['EventTarget', 'Window']
+ or base_idl_type.startswith(('HTML', 'SVG')))))
################################################################################
# Setter
################################################################################
+
def setter_context(interface, attribute, interfaces, context):
if 'PutForwards' in attribute.extended_attributes:
# Make sure the target interface and attribute exist.
@@ -488,8 +553,7 @@ def setter_context(interface, attribute, interfaces, context):
target_attribute_name = attribute.extended_attributes['PutForwards']
interface = interfaces[target_interface_name]
try:
- next(candidate
- for candidate in interface.attributes
+ next(candidate for candidate in interface.attributes
if candidate.name == target_attribute_name)
except StopIteration:
raise Exception('[PutForward] target not found:\n'
@@ -504,8 +568,8 @@ def setter_context(interface, attribute, interfaces, context):
# exception.
context['cpp_setter'] = (
'if (info.Holder()->CreateDataProperty(' +
- 'info.GetIsolate()->GetCurrentContext(), property_name, v8_value).IsNothing())' +
- '\n return')
+ 'info.GetIsolate()->GetCurrentContext(), ' +
+ 'property_name, v8_value).IsNothing())' + '\n return')
return
extended_attributes = attribute.extended_attributes
@@ -513,8 +577,8 @@ def setter_context(interface, attribute, interfaces, context):
# [RaisesException], [RaisesException=Setter]
is_setter_raises_exception = (
- 'RaisesException' in extended_attributes and
- extended_attributes['RaisesException'] in [None, 'Setter'])
+ 'RaisesException' in extended_attributes
+ and extended_attributes['RaisesException'] in [None, 'Setter'])
has_type_checking_interface = idl_type.is_wrapper_type
@@ -524,27 +588,36 @@ def setter_context(interface, attribute, interfaces, context):
# [CEReactions, Reflect, RuntimeEnabled],
# * the type is boolean, DOMString, or DOMString?, and
# * the interface inherits from 'Element'.
- if ('Reflect' in extended_attributes and
- 'CEReactions' in extended_attributes and
- str(idl_type) in ('boolean', 'DOMString', 'DOMString?') and
- inherits_interface(interface.name, 'Element')):
- if (len(extended_attributes) == 2 or
- (len(extended_attributes) == 3 and 'RuntimeEnabled' in extended_attributes)):
+ if ('Reflect' in extended_attributes
+ and 'CEReactions' in extended_attributes
+ and str(idl_type) in ('boolean', 'DOMString', 'DOMString?')
+ and inherits_interface(interface.name, 'Element')):
+ if (len(extended_attributes) == 2
+ or (len(extended_attributes) == 3
+ and 'RuntimeEnabled' in extended_attributes)):
use_common_reflection_setter = True
context.update({
'has_setter_exception_state':
- is_setter_raises_exception or has_type_checking_interface or
- idl_type.v8_conversion_needs_exception_state,
- 'has_type_checking_interface': has_type_checking_interface,
- 'is_setter_call_with_execution_context': has_extended_attribute_value(
- attribute, 'SetterCallWith', 'ExecutionContext'),
- 'is_setter_call_with_script_state': has_extended_attribute_value(
- attribute, 'SetterCallWith', 'ScriptState'),
- 'is_setter_raises_exception': is_setter_raises_exception,
- 'use_common_reflection_setter': use_common_reflection_setter,
- 'v8_value_to_local_cpp_value': idl_type.v8_value_to_local_cpp_value(
- extended_attributes, 'v8_value', 'cpp_value',
+ is_setter_raises_exception or has_type_checking_interface
+ or idl_type.v8_conversion_needs_exception_state,
+ 'has_type_checking_interface':
+ has_type_checking_interface,
+ 'is_setter_call_with_execution_context':
+ has_extended_attribute_value(attribute, 'SetterCallWith',
+ 'ExecutionContext'),
+ 'is_setter_call_with_script_state':
+ has_extended_attribute_value(attribute, 'SetterCallWith',
+ 'ScriptState'),
+ 'is_setter_raises_exception':
+ is_setter_raises_exception,
+ 'use_common_reflection_setter':
+ use_common_reflection_setter,
+ 'v8_value_to_local_cpp_value':
+ idl_type.v8_value_to_local_cpp_value(
+ extended_attributes,
+ 'v8_value',
+ 'cpp_value',
code_generation_target='attribute_set'),
})
@@ -555,18 +628,21 @@ def setter_context(interface, attribute, interfaces, context):
def setter_expression(interface, attribute, context):
extended_attributes = attribute.extended_attributes
arguments = v8_utilities.call_with_arguments(
- extended_attributes.get('SetterCallWith') or
- extended_attributes.get('CallWith'))
+ extended_attributes.get('SetterCallWith')
+ or extended_attributes.get('CallWith'))
- this_setter_base_name = setter_base_name(interface, attribute, arguments)
+ extra_arguments = []
+ this_setter_base_name = setter_base_name(interface, attribute,
+ extra_arguments)
setter_name = scoped_name(interface, attribute, this_setter_base_name)
# 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
- if ('PartialInterfaceImplementedAs' in extended_attributes and
- not attribute.is_static):
+ if ('PartialInterfaceImplementedAs' in extended_attributes
+ and not attribute.is_static):
arguments.append('*impl')
+ arguments.extend(extra_arguments)
idl_type = attribute.idl_type
if idl_type.base_type == 'EventHandler':
handler_type = 'kEventHandler'
@@ -574,25 +650,21 @@ def setter_expression(interface, attribute, context):
handler_type = 'kOnErrorEventHandler'
elif attribute.name == 'onbeforeunload':
handler_type = 'kOnBeforeUnloadEventHandler'
- arguments.append(
- 'JSEventHandler::CreateOrNull(' +
- 'v8_value, ' +
- 'JSEventHandler::HandlerType::' + handler_type +
- ')')
- elif idl_type.base_type == 'SerializedScriptValue':
- arguments.append('std::move(cpp_value)')
+ arguments.append('JSEventHandler::CreateOrNull(' + 'v8_value, ' +
+ 'JSEventHandler::HandlerType::' + handler_type + ')')
else:
arguments.append('cpp_value')
- if idl_type.is_explicit_nullable:
- arguments.append('is_null')
if context['is_setter_raises_exception']:
arguments.append('exception_state')
if context['use_common_reflection_setter']:
attr_name = scoped_content_attribute_name(interface, attribute)
if idl_type.base_type == 'boolean':
setter_name = 'V8SetReflectedBooleanAttribute'
- arguments = ['info', '"%s"' % interface.name,
- '"%s"' % attribute.name, attr_name]
+ arguments = [
+ 'info',
+ '"%s"' % interface.name,
+ '"%s"' % attribute.name, attr_name
+ ]
elif idl_type.base_type == 'DOMString':
if idl_type.is_nullable:
setter_name = 'V8SetReflectedNullableDOMStringAttribute'
@@ -626,8 +698,10 @@ def setter_base_name(interface, attribute, arguments):
def scoped_content_attribute_name(interface, attribute):
- content_attribute_name = attribute.extended_attributes['Reflect'] or attribute.name.lower()
- symbol_name = 'k' + NameStyleConverter(content_attribute_name).to_upper_camel_case()
+ content_attribute_name = (attribute.extended_attributes['Reflect']
+ or attribute.name.lower())
+ symbol_name = 'k' + NameStyleConverter(
+ content_attribute_name).to_upper_camel_case()
if interface.name.startswith('SVG'):
namespace = 'svg_names'
includes.add('core/svg_names.h')
@@ -650,25 +724,26 @@ def cpp_content_attribute_value_name(interface, value):
# Attribute configuration
################################################################################
+
# Property descriptor's {writable: boolean}
def is_writable(attribute):
- return (not attribute.is_read_only or
- any(keyword in attribute.extended_attributes for keyword in [
- 'PutForwards', 'Replaceable', 'LenientSetter']))
+ return (not attribute.is_read_only or any(
+ keyword in attribute.extended_attributes
+ for keyword in ['PutForwards', 'Replaceable', 'LenientSetter']))
def is_data_type_property(interface, attribute):
if 'CachedAccessor' in attribute.extended_attributes:
return False
- return (is_constructor_attribute(attribute) or
- 'CrossOrigin' in attribute.extended_attributes)
+ return (is_constructor_attribute(attribute)
+ or 'CrossOrigin' in attribute.extended_attributes)
# [PutForwards], [Replaceable], [LenientSetter]
def has_setter(interface, attribute):
- if (is_data_type_property(interface, attribute) and
- (is_constructor_attribute(attribute) or
- 'Replaceable' in attribute.extended_attributes)):
+ if (is_data_type_property(interface, attribute)
+ and (is_constructor_attribute(attribute)
+ or 'Replaceable' in attribute.extended_attributes)):
return False
return is_writable(attribute)
@@ -678,8 +753,8 @@ def has_setter(interface, attribute):
def property_attributes(interface, attribute):
extended_attributes = attribute.extended_attributes
property_attributes_list = []
- if ('NotEnumerable' in extended_attributes or
- is_constructor_attribute(attribute)):
+ if ('NotEnumerable' in extended_attributes
+ or is_constructor_attribute(attribute)):
property_attributes_list.append('v8::DontEnum')
if is_unforgeable(attribute):
property_attributes_list.append('v8::DontDelete')
@@ -691,16 +766,15 @@ def property_attributes(interface, attribute):
# [Custom], [Custom=Getter]
def has_custom_getter(attribute):
extended_attributes = attribute.extended_attributes
- return ('Custom' in extended_attributes and
- extended_attributes['Custom'] in [None, 'Getter'])
+ return ('Custom' in extended_attributes
+ and extended_attributes['Custom'] in [None, 'Getter'])
# [Custom], [Custom=Setter]
def has_custom_setter(attribute):
extended_attributes = attribute.extended_attributes
- return (not attribute.is_read_only and
- 'Custom' in extended_attributes and
- extended_attributes['Custom'] in [None, 'Setter'])
+ return (not attribute.is_read_only and 'Custom' in extended_attributes
+ and extended_attributes['Custom'] in [None, 'Setter'])
################################################################################
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/v8_callback_function.py b/chromium/third_party/blink/renderer/bindings/scripts/v8_callback_function.py
index bdd5965ca9d..76de914834a 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/v8_callback_function.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_callback_function.py
@@ -1,7 +1,6 @@
# 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.
-
"""Generate template values for a callback function.
Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
@@ -43,15 +42,24 @@ def callback_function_context(callback_function):
# the moment, the two are being defined because their values may change
# in the future (e.g. if we support [ImplementedAs=] in callback
# functions).
- 'callback_function_name': callback_function.name,
- 'cpp_class': 'V8%s' % callback_function.name,
- 'cpp_includes': sorted(includes),
- 'forward_declarations': sorted(forward_declarations(callback_function)),
- 'header_includes': sorted(CALLBACK_FUNCTION_H_INCLUDES),
- 'idl_type': idl_type_str,
- 'is_treat_non_object_as_null': 'TreatNonObjectAsNull' in callback_function.extended_attributes,
- 'native_value_traits_tag': v8_types.idl_type_to_native_value_traits_tag(idl_type),
- 'return_cpp_type': idl_type.cpp_type,
+ 'callback_function_name':
+ callback_function.name,
+ 'cpp_class':
+ 'V8%s' % callback_function.name,
+ 'cpp_includes':
+ sorted(includes),
+ 'forward_declarations':
+ sorted(forward_declarations(callback_function)),
+ 'header_includes':
+ sorted(CALLBACK_FUNCTION_H_INCLUDES),
+ 'idl_type':
+ idl_type_str,
+ 'is_treat_non_object_as_null':
+ 'TreatNonObjectAsNull' in callback_function.extended_attributes,
+ 'native_value_traits_tag':
+ v8_types.idl_type_to_native_value_traits_tag(idl_type),
+ 'return_cpp_type':
+ idl_type.cpp_type,
}
context.update(arguments_context(callback_function.arguments))
@@ -78,14 +86,21 @@ def arguments_context(arguments):
def argument_context(argument):
idl_type = argument.idl_type
return {
- 'cpp_value_to_v8_value': idl_type.cpp_value_to_v8_value(
- argument.name, isolate='GetIsolate()',
+ 'cpp_value_to_v8_value':
+ idl_type.cpp_value_to_v8_value(
+ argument.name,
+ isolate='GetIsolate()',
creation_context='argument_creation_context'),
- 'enum_type': idl_type.enum_type,
- 'enum_values': idl_type.enum_values,
- 'is_variadic': argument.is_variadic,
- 'name': argument.name,
- 'v8_name': 'v8_%s' % argument.name,
+ 'enum_type':
+ idl_type.enum_type,
+ 'enum_values':
+ idl_type.enum_values,
+ 'is_variadic':
+ argument.is_variadic,
+ 'name':
+ argument.name,
+ 'v8_name':
+ 'v8_%s' % argument.name,
}
def argument_cpp_type(argument):
@@ -98,7 +113,9 @@ def arguments_context(arguments):
else:
return cpp_type
- argument_declarations = ['bindings::V8ValueOrScriptWrappableAdapter callback_this_value']
+ argument_declarations = [
+ 'bindings::V8ValueOrScriptWrappableAdapter callback_this_value'
+ ]
argument_declarations.extend(
'%s %s' % (argument_cpp_type(argument), argument.name)
for argument in arguments)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/v8_callback_interface.py b/chromium/third_party/blink/renderer/bindings/scripts/v8_callback_interface.py
index e4580fd9319..973a1edde51 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/v8_callback_interface.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_callback_interface.py
@@ -25,7 +25,6 @@
# 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.
-
"""Generate template values for a callback interface.
Extends IdlTypeBase with property |callback_cpp_type|.
@@ -69,10 +68,12 @@ def _cpp_type(idl_type):
# Callbacks use raw pointers, so raw_type=True
raw_cpp_type = idl_type.cpp_type_args(raw_type=True)
# Pass containers and dictionaries to callback method by const reference rather than by value
- if raw_cpp_type.startswith(('Vector', 'HeapVector')) or idl_type.is_dictionary:
+ if (raw_cpp_type.startswith(('Vector', 'HeapVector'))
+ or idl_type.is_dictionary):
return 'const %s&' % raw_cpp_type
return raw_cpp_type
+
IdlTypeBase.callback_cpp_type = property(_cpp_type)
@@ -90,9 +91,8 @@ def callback_interface_context(callback_interface, _, component_info):
# https://heycam.github.io/webidl/#dfn-single-operation-callback-interface
is_single_operation = True
- if (callback_interface.parent or
- len(callback_interface.attributes) > 0 or
- len(callback_interface.operations) == 0):
+ if (callback_interface.parent or len(callback_interface.attributes) > 0
+ or len(callback_interface.operations) == 0):
is_single_operation = False
else:
operations = callback_interface.operations
@@ -103,18 +103,30 @@ def callback_interface_context(callback_interface, _, component_info):
break
return {
- 'constants': [constant_context(constant, callback_interface, component_info)
- for constant in callback_interface.constants],
- 'cpp_class': callback_interface.name,
- 'do_not_check_constants': 'DoNotCheckConstants' in callback_interface.extended_attributes,
- 'forward_declarations': sorted(forward_declarations(callback_interface)),
- 'header_includes': header_includes,
- 'interface_name': callback_interface.name,
- 'is_legacy_callback_interface': is_legacy_callback_interface,
- 'is_single_operation_callback_interface': is_single_operation,
- 'methods': [method_context(operation)
- for operation in callback_interface.operations],
- 'v8_class': v8_utilities.v8_class_name(callback_interface),
+ 'constants': [
+ constant_context(constant, callback_interface, component_info)
+ for constant in callback_interface.constants
+ ],
+ 'cpp_class':
+ callback_interface.name,
+ 'do_not_check_constants':
+ 'DoNotCheckConstants' in callback_interface.extended_attributes,
+ 'forward_declarations':
+ sorted(forward_declarations(callback_interface)),
+ 'header_includes':
+ header_includes,
+ 'interface_name':
+ callback_interface.name,
+ 'is_legacy_callback_interface':
+ is_legacy_callback_interface,
+ 'is_single_operation_callback_interface':
+ is_single_operation,
+ 'methods': [
+ method_context(operation)
+ for operation in callback_interface.operations
+ ],
+ 'v8_class':
+ v8_utilities.v8_class_name(callback_interface),
}
@@ -150,10 +162,14 @@ def method_context(operation):
add_includes_for_operation(operation)
context = {
- 'cpp_type': idl_type.callback_cpp_type,
- 'idl_type': idl_type_str,
- 'name': operation.name,
- 'native_value_traits_tag': v8_types.idl_type_to_native_value_traits_tag(idl_type),
+ 'cpp_type':
+ idl_type.callback_cpp_type,
+ 'idl_type':
+ idl_type_str,
+ 'name':
+ operation.name,
+ 'native_value_traits_tag':
+ v8_types.idl_type_to_native_value_traits_tag(idl_type),
}
context.update(arguments_context(operation.arguments))
return context
@@ -162,18 +178,24 @@ def method_context(operation):
def arguments_context(arguments):
def argument_context(argument):
return {
- 'cpp_value_to_v8_value': argument.idl_type.cpp_value_to_v8_value(
- argument.name, isolate='GetIsolate()',
+ 'cpp_value_to_v8_value':
+ argument.idl_type.cpp_value_to_v8_value(
+ argument.name,
+ isolate='GetIsolate()',
creation_context='argument_creation_context'),
- 'name': argument.name,
- 'v8_name': 'v8_' + argument.name,
+ 'name':
+ argument.name,
+ 'v8_name':
+ 'v8_' + argument.name,
}
- argument_declarations = ['bindings::V8ValueOrScriptWrappableAdapter callback_this_value']
+ argument_declarations = [
+ 'bindings::V8ValueOrScriptWrappableAdapter callback_this_value'
+ ]
argument_declarations.extend(
'%s %s' % (argument.idl_type.callback_cpp_type, argument.name)
for argument in arguments)
- return {
+ return {
'argument_declarations': argument_declarations,
'arguments': [argument_context(argument) for argument in arguments],
}
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 5beb8a3a1ac..c799496ec88 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/v8_dictionary.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_dictionary.py
@@ -1,21 +1,21 @@
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-
"""Generate template contexts of dictionaries for both v8 bindings and
implementation classes that are used by blink's core/modules.
"""
-import operator
+from blinkbuild.name_style_converter import NameStyleConverter
from idl_types import IdlType
from utilities import to_snake_case
from v8_globals import includes
+from v8_utilities import has_extended_attribute_value
+import operator
import v8_types
import v8_utilities
-from v8_utilities import has_extended_attribute_value
-
DICTIONARY_H_INCLUDES = frozenset([
+ 'base/containers/span.h',
'bindings/core/v8/native_value_traits.h',
'bindings/core/v8/to_v8_for_core.h',
'bindings/core/v8/v8_binding_for_core.h',
@@ -30,24 +30,24 @@ DICTIONARY_CPP_INCLUDES = frozenset([
def getter_name_for_dictionary_member(member):
name = v8_utilities.cpp_name(member)
- return name
+ return NameStyleConverter(name).to_lower_camel_case()
def setter_name_for_dictionary_member(member):
- name = v8_utilities.cpp_name(member)
- return 'set%s' % v8_utilities.capitalize(name)
+ name = 'set_{}'.format(v8_utilities.cpp_name(member))
+ return NameStyleConverter(name).to_lower_camel_case()
def null_setter_name_for_dictionary_member(member):
if member.idl_type.is_nullable:
- name = v8_utilities.cpp_name(member)
- return 'set%sToNull' % v8_utilities.capitalize(name)
+ name = 'set_{}_to_null'.format(v8_utilities.cpp_name(member))
+ return NameStyleConverter(name).to_lower_camel_case()
return None
def has_method_name_for_dictionary_member(member):
- name = v8_utilities.cpp_name(member)
- return 'has%s' % v8_utilities.capitalize(name)
+ name = NameStyleConverter('has_' + v8_utilities.cpp_name(member))
+ return name.to_lower_camel_case()
def unwrap_nullable_if_needed(idl_type):
@@ -58,6 +58,7 @@ def unwrap_nullable_if_needed(idl_type):
# Context for V8 bindings
+
def dictionary_context(dictionary, interfaces_info, component_info):
includes.clear()
includes.update(DICTIONARY_CPP_INCLUDES)
@@ -66,9 +67,11 @@ def dictionary_context(dictionary, interfaces_info, component_info):
raise Exception(
'Dictionary cannot be RuntimeEnabled: %s' % dictionary.name)
- members = [member_context(dictionary, member, component_info)
- for member in sorted(dictionary.members,
- key=operator.attrgetter('name'))]
+ members = [
+ member_context(dictionary, member, component_info)
+ for member in sorted(
+ dictionary.members, key=operator.attrgetter('name'))
+ ]
for member in members:
if member['runtime_enabled_feature_name']:
@@ -85,15 +88,22 @@ def dictionary_context(dictionary, interfaces_info, component_info):
cpp_class = v8_utilities.cpp_name(dictionary)
context = {
- 'cpp_class': cpp_class,
- 'has_origin_trial_members': has_origin_trial_members,
- 'header_includes': set(DICTIONARY_H_INCLUDES),
- 'members': members,
- 'required_member_names': sorted([member.name
- for member in dictionary.members
- if member.is_required]),
- 'use_permissive_dictionary_conversion': 'PermissiveDictionaryConversion' in dictionary.extended_attributes,
- 'v8_class': v8_types.v8_type(cpp_class),
+ 'cpp_class':
+ cpp_class,
+ 'has_origin_trial_members':
+ has_origin_trial_members,
+ 'header_includes':
+ set(DICTIONARY_H_INCLUDES),
+ 'members':
+ members,
+ 'required_member_names':
+ sorted([
+ member.name for member in dictionary.members if member.is_required
+ ]),
+ 'use_permissive_dictionary_conversion':
+ 'PermissiveDictionaryConversion' in dictionary.extended_attributes,
+ 'v8_class':
+ v8_types.v8_type(cpp_class),
}
if dictionary.parent:
IdlType(dictionary.parent).add_includes_for_type()
@@ -126,8 +136,8 @@ def member_context(_, member, component_info):
# states for some types for memory usage and performance.
# For types whose |has_explicit_presence| is True, we provide explicit
# states of presence.
- has_explicit_presence = (
- idl_type.is_nullable and idl_type.inner_type.is_interface_type)
+ has_explicit_presence = (idl_type.is_nullable
+ and idl_type.inner_type.is_interface_type)
def default_values():
if not member.default_value:
@@ -138,7 +148,8 @@ def member_context(_, member, component_info):
cpp_default_value = unwrapped_idl_type.literal_cpp_value(
member.default_value)
v8_default_value = unwrapped_idl_type.cpp_value_to_v8_value(
- cpp_value=cpp_default_value, isolate='isolate',
+ cpp_value=cpp_default_value,
+ isolate='isolate',
creation_context='creationContext')
return cpp_default_value, v8_default_value
@@ -148,48 +159,78 @@ def member_context(_, member, component_info):
v8_value = snake_case_name + "_value"
has_value_or_default = snake_case_name + "_has_value_or_default"
getter_name = getter_name_for_dictionary_member(member)
- is_deprecated_dictionary = unwrapped_idl_type.name == 'Dictionary'
runtime_features = component_info['runtime_enabled_features']
return {
- 'cpp_default_value': cpp_default_value,
- 'cpp_type': unwrapped_idl_type.cpp_type,
- 'cpp_value': cpp_value,
- 'cpp_value_to_v8_value': unwrapped_idl_type.cpp_value_to_v8_value(
- cpp_value='impl->%s()' % getter_name, isolate='isolate',
+ 'cpp_default_value':
+ cpp_default_value,
+ 'cpp_type':
+ unwrapped_idl_type.cpp_type,
+ 'cpp_value':
+ cpp_value,
+ 'cpp_value_to_v8_value':
+ unwrapped_idl_type.cpp_value_to_v8_value(
+ cpp_value='impl->%s()' % getter_name,
+ isolate='isolate',
creation_context='creationContext',
extended_attributes=extended_attributes),
- 'deprecate_as': v8_utilities.deprecate_as(member),
- 'enum_type': idl_type.enum_type,
- 'enum_values': idl_type.enum_values,
- 'getter_name': getter_name,
- 'has_explicit_presence': has_explicit_presence,
- 'has_method_name': has_method_name_for_dictionary_member(member),
- 'idl_type': idl_type.base_type,
- 'is_callback_function_type': idl_type.is_callback_function,
- 'is_interface_type': idl_type.is_interface_type and not is_deprecated_dictionary,
- 'is_nullable': idl_type.is_nullable,
- 'is_object': unwrapped_idl_type.name == 'Object' or is_deprecated_dictionary,
- 'is_string_type': idl_type.preprocessed_type.is_string_type,
- 'is_required': member.is_required,
- 'name': member.name,
+ 'deprecate_as':
+ v8_utilities.deprecate_as(member),
+ 'enum_type':
+ idl_type.enum_type,
+ 'enum_values':
+ idl_type.enum_values,
+ 'getter_name':
+ getter_name,
+ 'has_explicit_presence':
+ has_explicit_presence,
+ 'has_method_name':
+ has_method_name_for_dictionary_member(member),
+ 'idl_type':
+ idl_type.base_type,
+ 'is_callback_function_type':
+ idl_type.is_callback_function,
+ 'is_interface_type':
+ idl_type.is_interface_type,
+ 'is_nullable':
+ idl_type.is_nullable,
+ 'is_object':
+ unwrapped_idl_type.name == 'Object',
+ 'is_string_type':
+ idl_type.preprocessed_type.is_string_type,
+ 'is_required':
+ member.is_required,
+ 'name':
+ member.name,
+ # [RuntimeEnabled] for origin trial
'origin_trial_feature_name':
- v8_utilities.origin_trial_feature_name(member, runtime_features), # [RuntimeEnabled] for origin trial
+ v8_utilities.origin_trial_feature_name(member, runtime_features),
+ # [RuntimeEnabled] if not in origin trial
'runtime_enabled_feature_name':
- v8_utilities.runtime_enabled_feature_name(member, runtime_features), # [RuntimeEnabled] if not in origin trial
- 'setter_name': setter_name_for_dictionary_member(member),
- 'has_value_or_default': has_value_or_default,
- 'null_setter_name': null_setter_name_for_dictionary_member(member),
- 'v8_default_value': v8_default_value,
- 'v8_value': v8_value,
- 'v8_value_to_local_cpp_value': idl_type.v8_value_to_local_cpp_value(
- extended_attributes, v8_value, cpp_value, isolate='isolate',
+ v8_utilities.runtime_enabled_feature_name(member, runtime_features),
+ 'setter_name':
+ setter_name_for_dictionary_member(member),
+ 'has_value_or_default':
+ has_value_or_default,
+ 'null_setter_name':
+ null_setter_name_for_dictionary_member(member),
+ 'v8_default_value':
+ v8_default_value,
+ 'v8_value':
+ v8_value,
+ 'v8_value_to_local_cpp_value':
+ idl_type.v8_value_to_local_cpp_value(
+ extended_attributes,
+ v8_value,
+ cpp_value,
+ isolate='isolate',
use_exception_state=True),
}
# Context for implementation classes
+
def dictionary_impl_context(dictionary, interfaces_info):
def remove_duplicate_members(members):
# When [ImplementedAs] is used, cpp_name can conflict. For example,
@@ -202,14 +243,17 @@ def dictionary_impl_context(dictionary, interfaces_info):
if duplicated_member and duplicated_member != member:
raise Exception('Member name conflict: %s' % cpp_name)
members_dict[cpp_name] = member
- return sorted(members_dict.values(), key=lambda member: member['cpp_name'])
+ return sorted(
+ members_dict.values(), key=lambda member: member['cpp_name'])
includes.clear()
header_forward_decls = set()
header_includes = set(['platform/heap/handle.h'])
- members = [member_impl_context(member, interfaces_info,
- header_includes, header_forward_decls)
- for member in dictionary.members]
+ members = [
+ member_impl_context(member, interfaces_info, header_includes,
+ header_forward_decls)
+ for member in dictionary.members
+ ]
members = remove_duplicate_members(members)
context = {
'header_forward_decls': header_forward_decls,
@@ -218,8 +262,9 @@ def dictionary_impl_context(dictionary, interfaces_info):
'members': members,
}
if dictionary.parent:
- context['parent_cpp_class'] = v8_utilities.cpp_name_from_interfaces_info(
- dictionary.parent, interfaces_info)
+ context['parent_cpp_class'] = \
+ v8_utilities.cpp_name_from_interfaces_info(dictionary.parent,
+ interfaces_info)
parent_interface_info = interfaces_info.get(dictionary.parent)
if parent_interface_info:
context['header_includes'].add(
@@ -241,8 +286,8 @@ def member_impl_context(member, interfaces_info, header_includes,
# states for some types for memory usage and performance.
# For types whose |has_explicit_presence| is True, we provide explicit
# states of presence.
- has_explicit_presence = (
- member.idl_type.is_nullable and member.idl_type.inner_type.is_interface_type)
+ has_explicit_presence = (member.idl_type.is_nullable
+ and member.idl_type.inner_type.is_interface_type)
nullable_indicator_name = None
if not idl_type.cpp_type_has_null_value or has_explicit_presence:
@@ -256,50 +301,66 @@ def member_impl_context(member, interfaces_info, header_includes,
if idl_type.name == 'Any':
return '!({0}_.IsEmpty() || {0}_.IsUndefined())'.format(cpp_name)
if idl_type.name == 'Object':
- return '!({0}_.IsEmpty() || {0}_.IsNull() || {0}_.IsUndefined())'.format(cpp_name)
- if idl_type.name == 'Dictionary':
- return '!%s_.IsUndefinedOrNull()' % cpp_name
- return '%s_' % cpp_name
+ return '!({0}_.IsEmpty() || {0}_.IsNull() || {0}_.IsUndefined())'.format(
+ cpp_name)
+ return '!!%s_' % cpp_name
cpp_default_value = None
if member.default_value:
if not member.default_value.is_null or has_explicit_presence:
- cpp_default_value = idl_type.literal_cpp_value(member.default_value)
+ cpp_default_value = idl_type.literal_cpp_value(
+ member.default_value)
forward_decl_name = idl_type.impl_forward_declaration_name
if forward_decl_name:
includes.update(idl_type.impl_includes_for_type(interfaces_info))
header_forward_decls.add(forward_decl_name)
else:
- header_includes.update(idl_type.impl_includes_for_type(interfaces_info))
+ header_includes.update(
+ idl_type.impl_includes_for_type(interfaces_info))
setter_value = 'value'
- if idl_type.is_array_buffer_view_or_typed_array:
- setter_value += '.View()'
-
non_null_type = idl_type.inner_type if idl_type.is_nullable else idl_type
- setter_inline = 'inline ' if (
- non_null_type.is_basic_type or
- non_null_type.is_enum or
- non_null_type.is_wrapper_type) else ''
+ setter_inline = 'inline ' if (non_null_type.is_basic_type
+ or non_null_type.is_enum
+ or non_null_type.is_wrapper_type) else ''
extended_attributes = member.extended_attributes
return {
- 'cpp_default_value': cpp_default_value,
- 'cpp_name': cpp_name,
- 'has_explicit_presence': has_explicit_presence,
- 'getter_expression': cpp_name + '_',
- 'getter_name': getter_name_for_dictionary_member(member),
- 'has_method_expression': has_method_expression(),
- 'has_method_name': has_method_name_for_dictionary_member(member),
- 'is_nullable': 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),
- '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),
- 'setter_inline': setter_inline,
- 'setter_name': setter_name_for_dictionary_member(member),
- 'setter_value': setter_value,
+ 'cpp_default_value':
+ cpp_default_value,
+ 'cpp_name':
+ cpp_name,
+ 'has_explicit_presence':
+ has_explicit_presence,
+ 'getter_expression':
+ cpp_name + '_',
+ 'getter_name':
+ getter_name_for_dictionary_member(member),
+ 'has_method_expression':
+ has_method_expression(),
+ 'has_method_name':
+ has_method_name_for_dictionary_member(member),
+ 'is_nullable':
+ 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),
+ '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),
+ 'setter_inline':
+ setter_inline,
+ 'setter_name':
+ setter_name_for_dictionary_member(member),
+ 'setter_value':
+ setter_value,
}
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/v8_globals.py b/chromium/third_party/blink/renderer/bindings/scripts/v8_globals.py
index 55ed25722ed..49fb86151e3 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/v8_globals.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_globals.py
@@ -25,7 +25,6 @@
# 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.
-
"""Module to share global variables (includes and interfaces) across modules."""
includes = set()
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 39ab8717569..02f604dee9d 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/v8_interface.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_interface.py
@@ -28,7 +28,6 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# pylint: disable=relative-import
-
"""Generate template values for an interface.
Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
@@ -37,8 +36,8 @@ import os
import sys
from operator import or_
-sys.path.append(os.path.join(os.path.dirname(__file__),
- '..', '..', 'build', 'scripts'))
+sys.path.append(
+ os.path.join(os.path.dirname(__file__), '..', '..', 'build', 'scripts'))
from blinkbuild.name_style_converter import NameStyleConverter
from idl_definitions import IdlAttribute, IdlOperation, IdlArgument
from idl_types import IdlType, inherits_interface
@@ -50,11 +49,9 @@ from v8_globals import includes
import v8_methods
import v8_types
import v8_utilities
-from v8_utilities import (binding_header_filename, context_enabled_feature_name,
- cpp_name_or_partial, cpp_name,
- has_extended_attribute_value,
- runtime_enabled_feature_name)
-
+from v8_utilities import (
+ binding_header_filename, context_enabled_feature_name, cpp_name_or_partial,
+ cpp_name, has_extended_attribute_value, runtime_enabled_feature_name)
INTERFACE_H_INCLUDES = frozenset([
'bindings/core/v8/generated_code_helper.h',
@@ -68,6 +65,7 @@ INTERFACE_H_INCLUDES = frozenset([
])
INTERFACE_CPP_INCLUDES = frozenset([
'base/memory/scoped_refptr.h',
+ 'bindings/core/v8/native_value_traits_impl.h',
'bindings/core/v8/v8_dom_configuration.h',
'core/execution_context/execution_context.h',
'platform/scheduler/public/cooperative_scheduling_manager.h',
@@ -79,34 +77,42 @@ INTERFACE_CPP_INCLUDES = frozenset([
def filter_has_constant_configuration(constants):
- return [constant for constant in constants if
- not constant['measure_as'] and
- not constant['deprecate_as'] and
- not constant['runtime_enabled_feature_name'] and
- not constant['origin_trial_feature_name']]
+ return [
+ constant for constant in constants
+ if not constant['measure_as'] and not constant['deprecate_as']
+ and not constant['runtime_enabled_feature_name']
+ and not constant['origin_trial_feature_name']
+ ]
def filter_has_special_getter(constants):
- return [constant for constant in constants if
- constant['measure_as'] or
- constant['deprecate_as']]
+ return [
+ constant for constant in constants
+ if constant['measure_as'] or constant['deprecate_as']
+ ]
def filter_runtime_enabled(constants):
- return [constant for constant in constants if
- constant['runtime_enabled_feature_name']]
+ return [
+ constant for constant in constants
+ if constant['runtime_enabled_feature_name']
+ ]
def filter_origin_trial_enabled(constants):
- return [constant for constant in constants if
- constant['origin_trial_feature_name']]
+ return [
+ constant for constant in constants
+ if constant['origin_trial_feature_name']
+ ]
def constant_filters():
- return {'has_constant_configuration': filter_has_constant_configuration,
- 'has_special_getter': filter_has_special_getter,
- 'runtime_enabled_constants': filter_runtime_enabled,
- 'origin_trial_enabled_constants': filter_origin_trial_enabled}
+ return {
+ 'has_constant_configuration': filter_has_constant_configuration,
+ 'has_special_getter': filter_has_special_getter,
+ 'runtime_enabled_constants': filter_runtime_enabled,
+ 'origin_trial_enabled_constants': filter_origin_trial_enabled
+ }
def origin_trial_features(interface, constants, attributes, methods):
@@ -128,26 +134,40 @@ def origin_trial_features(interface, constants, attributes, methods):
# Collect all members visible on this interface with a defined origin trial
origin_trial_constants = member_filter(constants)
origin_trial_attributes = member_filter(attributes)
- origin_trial_methods = member_filter([method for method in methods
- if v8_methods.method_is_visible(method, interface.is_partial) and
- not v8_methods.custom_registration(method)])
+ origin_trial_methods = member_filter([
+ method for method in methods
+ if v8_methods.method_is_visible(method, interface.is_partial)
+ and not v8_methods.custom_registration(method)
+ ])
- feature_names = set([member[KEY] for member in origin_trial_constants + origin_trial_attributes + origin_trial_methods])
+ feature_names = set([
+ member[KEY] for member in origin_trial_constants +
+ origin_trial_attributes + origin_trial_methods
+ ])
# Construct the list of dictionaries. 'needs_instance' will be true if any
# member for the feature has 'on_instance' defined as true.
- features = [{'name': name,
- 'constants': member_filter_by_name(origin_trial_constants, name),
- 'attributes': member_filter_by_name(origin_trial_attributes, name),
- 'methods': member_filter_by_name(origin_trial_methods, name)}
- for name in feature_names]
+ features = [{
+ 'name':
+ name,
+ 'constants':
+ member_filter_by_name(origin_trial_constants, name),
+ 'attributes':
+ member_filter_by_name(origin_trial_attributes, name),
+ 'methods':
+ member_filter_by_name(origin_trial_methods, name)
+ } for name in feature_names]
for feature in features:
- members = feature['constants'] + feature['attributes'] + feature['methods']
- feature['needs_instance'] = any(member.get('on_instance', False) for member in members)
+ members = feature['constants'] + feature['attributes'] + feature[
+ 'methods']
+ feature['needs_instance'] = any(
+ member.get('on_instance', False) for member in members)
# TODO(chasej): Need to handle method overloads? e.g.
# (method['overloads']['secure_context_test_all'] if 'overloads' in method else method['secure_context_test'])
- feature['needs_secure_context'] = any(member.get('secure_context_test', False) for member in members)
- feature['needs_context'] = feature['needs_secure_context'] or any(member.get('exposed_test', False) for member in members)
+ feature['needs_secure_context'] = any(
+ member.get('secure_context_test', False) for member in members)
+ feature['needs_context'] = feature['needs_secure_context'] or any(
+ member.get('exposed_test', False) for member in members)
if features:
includes.add('platform/bindings/script_state.h')
@@ -166,7 +186,10 @@ def context_enabled_features(attributes):
KEY = 'context_enabled_feature_name' # pylint: disable=invalid-name
def member_filter(members):
- return sorted([member for member in members if member.get(KEY) and not member.get('exposed_test')])
+ return sorted([
+ member for member in members
+ if member.get(KEY) and not member.get('exposed_test')
+ ])
def member_filter_by_name(members, name):
return [member for member in members if member[KEY] == name]
@@ -174,10 +197,14 @@ def context_enabled_features(attributes):
# Collect all members visible on this interface with a defined origin trial
context_enabled_attributes = member_filter(attributes)
feature_names = set([member[KEY] for member in context_enabled_attributes])
- features = [{'name': name,
- 'attributes': member_filter_by_name(context_enabled_attributes, name),
- 'needs_instance': False}
- for name in feature_names]
+ features = [{
+ 'name':
+ name,
+ 'attributes':
+ member_filter_by_name(context_enabled_attributes, name),
+ 'needs_instance':
+ False
+ } for name in feature_names]
if features:
includes.add('platform/bindings/script_state.h')
return features
@@ -186,13 +213,20 @@ def context_enabled_features(attributes):
def runtime_call_stats_context(interface):
counter_prefix = 'Blink_' + v8_utilities.cpp_name(interface) + '_'
return {
- 'constructor_counter': counter_prefix + 'Constructor',
- 'cross_origin_named_getter_counter': counter_prefix + 'CrossOriginNamedGetter',
- 'cross_origin_named_setter_counter': counter_prefix + 'CrossOriginNamedSetter',
- 'indexed_property_getter_counter': counter_prefix + 'IndexedPropertyGetter',
- 'named_property_getter_counter': counter_prefix + 'NamedPropertyGetter',
- 'named_property_query_counter': counter_prefix + 'NamedPropertyQuery',
- 'named_property_setter_counter': counter_prefix + 'NamedPropertySetter',
+ 'constructor_counter':
+ counter_prefix + 'Constructor',
+ 'cross_origin_named_getter_counter':
+ counter_prefix + 'CrossOriginNamedGetter',
+ 'cross_origin_named_setter_counter':
+ counter_prefix + 'CrossOriginNamedSetter',
+ 'indexed_property_getter_counter':
+ counter_prefix + 'IndexedPropertyGetter',
+ 'named_property_getter_counter':
+ counter_prefix + 'NamedPropertyGetter',
+ 'named_property_query_counter':
+ counter_prefix + 'NamedPropertyQuery',
+ 'named_property_setter_counter':
+ counter_prefix + 'NamedPropertySetter',
}
@@ -220,11 +254,13 @@ def interface_context(interface, interfaces, component_info):
parent_interface = None
is_event_target = False
# partial interface needs the definition of its original interface.
- includes.add('bindings/core/v8/%s' % binding_header_filename(interface.name))
+ includes.add(
+ 'bindings/core/v8/%s' % binding_header_filename(interface.name))
else:
parent_interface = interface.parent
if parent_interface:
- header_includes.update(v8_types.includes_for_interface(parent_interface))
+ header_includes.update(
+ v8_types.includes_for_interface(parent_interface))
is_event_target = inherits_interface(interface.name, 'EventTarget')
extended_attributes = interface.extended_attributes
@@ -235,19 +271,18 @@ def interface_context(interface, interfaces, component_info):
includes.update(('bindings/core/v8/v8_array_buffer.h',
'bindings/core/v8/v8_shared_array_buffer.h'))
if interface.name == 'ArrayBufferView':
- includes.update((
- 'bindings/core/v8/v8_int8_array.h',
- 'bindings/core/v8/v8_int16_array.h',
- 'bindings/core/v8/v8_int32_array.h',
- 'bindings/core/v8/v8_uint8_array.h',
- 'bindings/core/v8/v8_uint8_clamped_array.h',
- 'bindings/core/v8/v8_uint16_array.h',
- 'bindings/core/v8/v8_uint32_array.h',
- 'bindings/core/v8/v8_big_int_64_array.h',
- 'bindings/core/v8/v8_big_uint_64_array.h',
- 'bindings/core/v8/v8_float32_array.h',
- 'bindings/core/v8/v8_float64_array.h',
- 'bindings/core/v8/v8_data_view.h'))
+ includes.update(('bindings/core/v8/v8_int8_array.h',
+ 'bindings/core/v8/v8_int16_array.h',
+ 'bindings/core/v8/v8_int32_array.h',
+ 'bindings/core/v8/v8_uint8_array.h',
+ 'bindings/core/v8/v8_uint8_clamped_array.h',
+ 'bindings/core/v8/v8_uint16_array.h',
+ 'bindings/core/v8/v8_uint32_array.h',
+ 'bindings/core/v8/v8_big_int_64_array.h',
+ 'bindings/core/v8/v8_big_uint_64_array.h',
+ 'bindings/core/v8/v8_float32_array.h',
+ 'bindings/core/v8/v8_float64_array.h',
+ 'bindings/core/v8/v8_data_view.h'))
# [ActiveScriptWrappable]
active_scriptwrappable = 'ActiveScriptWrappable' in extended_attributes
@@ -266,12 +301,14 @@ def interface_context(interface, interfaces, component_info):
# as in the WebIDL spec?
is_immutable_prototype = is_global or 'ImmutablePrototype' in extended_attributes
- wrapper_class_id = ('kNodeClassId' if inherits_interface(interface.name, 'Node') else 'kObjectClassId')
+ wrapper_class_id = ('kNodeClassId' if inherits_interface(
+ interface.name, 'Node') else 'kObjectClassId')
# [LegacyUnenumerableNamedProperties]
# pylint: disable=C0103
- has_legacy_unenumerable_named_properties = (interface.has_named_property_getter and
- 'LegacyUnenumerableNamedProperties' in extended_attributes)
+ has_legacy_unenumerable_named_properties = (
+ interface.has_named_property_getter
+ and 'LegacyUnenumerableNamedProperties' in extended_attributes)
v8_class_name = v8_utilities.v8_class_name(interface)
cpp_class_name = cpp_name(interface)
@@ -280,55 +317,93 @@ def interface_context(interface, interfaces, component_info):
# TODO(peria): Generate the target list from 'Window' and 'HTMLDocument'.
needs_runtime_enabled_installer = v8_class_name in [
- 'V8Window', 'V8HTMLDocument', 'V8Document', 'V8Node', 'V8EventTarget']
+ 'V8Window', 'V8HTMLDocument', 'V8Document', 'V8Node', 'V8EventTarget'
+ ]
runtime_features = component_info['runtime_enabled_features']
context = {
- 'active_scriptwrappable': active_scriptwrappable,
- 'context_enabled_feature_name': context_enabled_feature_name(interface), # [ContextEnabled]
- 'cpp_class': cpp_class_name,
- 'cpp_class_or_partial': cpp_class_name_or_partial,
- 'is_gc_type': True,
+ 'active_scriptwrappable':
+ active_scriptwrappable,
+ 'context_enabled_feature_name':
+ context_enabled_feature_name(interface), # [ContextEnabled]
+ 'cpp_class':
+ cpp_class_name,
+ 'cpp_class_or_partial':
+ cpp_class_name_or_partial,
+ 'is_gc_type':
+ True,
# FIXME: Remove 'EventTarget' special handling, http://crbug.com/383699
- 'has_access_check_callbacks': (is_check_security and
- interface.name != 'EventTarget'),
- 'has_custom_legacy_call_as_function': has_extended_attribute_value(interface, 'Custom', 'LegacyCallAsFunction'), # [Custom=LegacyCallAsFunction]
- 'has_legacy_unenumerable_named_properties': has_legacy_unenumerable_named_properties,
- 'has_partial_interface': len(interface.partial_interfaces) > 0,
- 'header_includes': header_includes,
- 'interface_name': interface.name,
- 'internal_namespace': internal_namespace(interface),
- 'is_array_buffer_or_view': is_array_buffer_or_view,
- 'is_check_security': is_check_security,
- 'is_event_target': is_event_target,
- 'is_global': is_global,
- 'is_immutable_prototype': is_immutable_prototype,
- 'is_node': inherits_interface(interface.name, 'Node'),
- 'is_partial': interface.is_partial,
- 'is_typed_array_type': is_typed_array_type,
- 'measure_as': v8_utilities.measure_as(interface, None), # [MeasureAs]
- 'needs_runtime_enabled_installer': needs_runtime_enabled_installer,
- 'origin_trial_feature_name': v8_utilities.origin_trial_feature_name(interface, runtime_features),
- 'parent_interface': parent_interface,
- 'pass_cpp_type': cpp_name(interface) + '*',
- 'runtime_call_stats': runtime_call_stats_context(interface),
- 'runtime_enabled_feature_name': runtime_enabled_feature_name(interface, runtime_features), # [RuntimeEnabled]
- 'snake_case_v8_class': NameStyleConverter(v8_class_name).to_snake_case(),
- 'v8_class': v8_class_name,
- 'v8_class_or_partial': v8_class_name_or_partial,
- 'wrapper_class_id': wrapper_class_id,
+ 'has_access_check_callbacks': (is_check_security
+ and interface.name != 'EventTarget'),
+ # [Custom=LegacyCallAsFunction]
+ 'has_custom_legacy_call_as_function':
+ has_extended_attribute_value(interface, 'Custom',
+ 'LegacyCallAsFunction'),
+ 'has_legacy_unenumerable_named_properties':
+ has_legacy_unenumerable_named_properties,
+ 'has_partial_interface':
+ len(interface.partial_interfaces) > 0,
+ 'header_includes':
+ header_includes,
+ 'interface_name':
+ interface.name,
+ 'internal_namespace':
+ internal_namespace(interface),
+ 'is_array_buffer_or_view':
+ is_array_buffer_or_view,
+ 'is_check_security':
+ is_check_security,
+ 'is_event_target':
+ is_event_target,
+ 'is_global':
+ is_global,
+ 'is_immutable_prototype':
+ is_immutable_prototype,
+ 'is_node':
+ inherits_interface(interface.name, 'Node'),
+ 'is_partial':
+ interface.is_partial,
+ 'is_typed_array_type':
+ is_typed_array_type,
+ # [MeasureAs]
+ 'measure_as':
+ v8_utilities.measure_as(interface, None),
+ 'needs_runtime_enabled_installer':
+ needs_runtime_enabled_installer,
+ 'origin_trial_feature_name':
+ v8_utilities.origin_trial_feature_name(interface, runtime_features),
+ 'parent_interface':
+ parent_interface,
+ 'pass_cpp_type':
+ cpp_name(interface) + '*',
+ 'runtime_call_stats':
+ runtime_call_stats_context(interface),
+ # [RuntimeEnabled]
+ 'runtime_enabled_feature_name':
+ runtime_enabled_feature_name(interface, runtime_features),
+ 'snake_case_v8_class':
+ NameStyleConverter(v8_class_name).to_snake_case(),
+ 'v8_class':
+ v8_class_name,
+ 'v8_class_or_partial':
+ v8_class_name_or_partial,
+ 'wrapper_class_id':
+ wrapper_class_id,
}
# Constructors
- constructors = [constructor_context(interface, constructor)
- for constructor in interface.constructors
- # FIXME: shouldn't put named constructors with constructors
- # (currently needed for Perl compatibility)
- # Handle named constructors separately
- if constructor.name == 'Constructor']
+ constructors = [
+ constructor_context(interface, constructor)
+ for constructor in interface.constructors
+ # FIXME: shouldn't put named constructors with constructors
+ # (currently needed for Perl compatibility)
+ # Handle named constructors separately
+ if constructor.name == 'Constructor'
+ ]
if len(constructors) > 1:
- context['constructor_overloads'] = overloads_context(interface, constructors)
+ context['constructor_overloads'] = overloads_context(
+ interface, constructors)
# [CustomConstructor]
custom_constructors = [{ # Only needed for computing interface length
@@ -340,8 +415,9 @@ def interface_context(interface, interfaces, component_info):
has_html_constructor = 'HTMLConstructor' in extended_attributes
# https://html.spec.whatwg.org/C/#html-element-constructors
if has_html_constructor:
- if ('Constructor' in extended_attributes or
- 'NoInterfaceObject' in extended_attributes or interface.is_mixin):
+ if ('Constructor' in extended_attributes
+ or 'NoInterfaceObject' in extended_attributes
+ or interface.is_mixin):
raise Exception('[HTMLConstructor] cannot be specified with '
'[Constructor] or [NoInterfaceObject], or on '
'a mixin : %s' % interface.name)
@@ -363,21 +439,27 @@ def interface_context(interface, interfaces, component_info):
includes.add('core/frame/local_dom_window.h')
elif 'Measure' in extended_attributes or 'MeasureAs' in extended_attributes:
if not interface.is_partial:
- raise Exception('[Measure] or [MeasureAs] specified for interface without a constructor: '
- '%s' % interface.name)
+ raise Exception(
+ '[Measure] or [MeasureAs] specified for interface without a constructor: '
+ '%s' % interface.name)
# [ConstructorCallWith=Document]
- if has_extended_attribute_value(interface, 'ConstructorCallWith', 'Document'):
+ if has_extended_attribute_value(interface, 'ConstructorCallWith',
+ 'Document'):
includes.add('core/dom/document.h')
# [Unscopable] attributes and methods
unscopables = []
for attribute in interface.attributes:
if 'Unscopable' in attribute.extended_attributes:
- unscopables.append((attribute.name, runtime_enabled_feature_name(attribute, runtime_features)))
+ unscopables.append((attribute.name,
+ runtime_enabled_feature_name(
+ attribute, runtime_features)))
for method in interface.operations:
if 'Unscopable' in method.extended_attributes:
- unscopables.append((method.name, runtime_enabled_feature_name(method, runtime_features)))
+ unscopables.append((method.name,
+ runtime_enabled_feature_name(
+ method, runtime_features)))
# [CEReactions]
setter_or_deleters = (
@@ -386,49 +468,77 @@ def interface_context(interface, interfaces, component_info):
interface.named_property_setter,
interface.named_property_deleter,
)
- has_ce_reactions = any(setter_or_deleter and 'CEReactions' in setter_or_deleter.extended_attributes
- for setter_or_deleter in setter_or_deleters)
+ has_ce_reactions = any(
+ setter_or_deleter
+ and 'CEReactions' in setter_or_deleter.extended_attributes
+ for setter_or_deleter in setter_or_deleters)
if has_ce_reactions:
includes.add('core/html/custom/ce_reactions_scope.h')
context.update({
- 'constructors': constructors,
- 'has_custom_constructor': bool(custom_constructors),
- 'has_html_constructor': has_html_constructor,
+ 'constructors':
+ constructors,
+ 'has_custom_constructor':
+ bool(custom_constructors),
+ 'has_html_constructor':
+ has_html_constructor,
'interface_length':
- interface_length(constructors + custom_constructors),
- 'is_constructor_raises_exception': extended_attributes.get('RaisesException') == 'Constructor', # [RaisesException=Constructor]
- 'named_constructor': named_constructor,
- 'unscopables': sorted(unscopables),
+ interface_length(constructors + custom_constructors),
+ # [RaisesException=Constructor]
+ 'is_constructor_raises_exception':
+ extended_attributes.get('RaisesException') == 'Constructor',
+ 'named_constructor':
+ named_constructor,
+ 'unscopables':
+ sorted(unscopables),
})
# Constants
context.update({
- 'constants': [constant_context(constant, interface, component_info) for constant in interface.constants],
- 'do_not_check_constants': 'DoNotCheckConstants' in extended_attributes,
+ 'constants': [
+ constant_context(constant, interface, component_info)
+ for constant in interface.constants
+ ],
+ 'do_not_check_constants':
+ 'DoNotCheckConstants' in extended_attributes,
})
# Attributes
attributes = attributes_context(interface, interfaces, component_info)
context.update({
- 'attributes': attributes,
+ 'attributes':
+ attributes,
# Elements in attributes are broken in following members.
- 'accessors': v8_attributes.filter_accessors(attributes),
- 'data_attributes': v8_attributes.filter_data_attributes(attributes),
- 'runtime_enabled_attributes': v8_attributes.filter_runtime_enabled(attributes),
+ 'accessors':
+ v8_attributes.filter_accessors(attributes),
+ 'data_attributes':
+ v8_attributes.filter_data_attributes(attributes),
+ 'runtime_enabled_attributes':
+ v8_attributes.filter_runtime_enabled(attributes),
})
# Conditionally enabled attributes
- conditionally_enabled_attributes = v8_attributes.filter_conditionally_enabled(attributes)
- conditional_attributes = [attr for attr in conditionally_enabled_attributes if not attr['constructor_type']]
- conditional_interface_objects = [attr for attr in conditionally_enabled_attributes if attr['constructor_type']]
+ conditionally_enabled_attributes = v8_attributes.filter_conditionally_enabled(
+ attributes)
+ conditional_attributes = [
+ attr for attr in conditionally_enabled_attributes
+ if not attr['constructor_type']
+ ]
+ conditional_interface_objects = [
+ attr for attr in conditionally_enabled_attributes
+ if attr['constructor_type']
+ ]
has_conditional_secure_attributes = any( # pylint: disable=invalid-name
- v8_attributes.is_secure_context(attr) for attr in conditionally_enabled_attributes)
+ v8_attributes.is_secure_context(attr)
+ for attr in conditionally_enabled_attributes)
context.update({
- 'conditional_attributes': conditional_attributes,
- 'conditional_interface_objects': conditional_interface_objects,
- 'has_conditional_secure_attributes': has_conditional_secure_attributes,
+ 'conditional_attributes':
+ conditional_attributes,
+ 'conditional_interface_objects':
+ conditional_interface_objects,
+ 'has_conditional_secure_attributes':
+ has_conditional_secure_attributes,
})
# Methods
@@ -436,22 +546,24 @@ def interface_context(interface, interfaces, component_info):
methods = context['methods']
# Conditionally enabled methods
- conditional_methods = v8_methods.filter_conditionally_enabled(methods, interface.is_partial)
+ conditional_methods = v8_methods.filter_conditionally_enabled(
+ methods, interface.is_partial)
has_conditional_secure_methods = any( # pylint: disable=invalid-name
v8_methods.is_secure_context(method) for method in conditional_methods)
context.update({
'has_conditional_secure_methods':
- has_conditional_secure_methods,
- 'conditional_methods': conditional_methods,
+ has_conditional_secure_methods,
+ 'conditional_methods':
+ conditional_methods,
})
# Window.idl in Blink has indexed properties, but the spec says Window
# interface doesn't have indexed properties, instead the WindowProxy exotic
# object has indexed properties. Thus, Window interface must not support
# iterators.
- has_array_iterator = (not interface.is_partial and
- interface.has_indexed_elements and
- interface.name != 'Window')
+ has_array_iterator = (not interface.is_partial
+ and interface.has_indexed_elements
+ and interface.name != 'Window')
context.update({
'has_array_iterator': has_array_iterator,
'iterable': interface.iterable,
@@ -464,27 +576,38 @@ def interface_context(interface, interfaces, component_info):
v8_class_name_or_partial + '::InstallConditionalFeatures')
context.update({
- 'install_conditional_features_func': install_conditional_features_func,
+ 'install_conditional_features_func':
+ install_conditional_features_func,
})
context.update({
- 'indexed_property_getter': property_getter(interface.indexed_property_getter, ['index']),
- 'indexed_property_setter': property_setter(interface.indexed_property_setter, interface),
- 'indexed_property_deleter': property_deleter(interface.indexed_property_deleter),
- 'is_override_builtins': 'OverrideBuiltins' in extended_attributes,
- 'named_property_getter': property_getter(interface.named_property_getter, ['name']),
- 'named_property_setter': property_setter(interface.named_property_setter, interface),
- 'named_property_deleter': property_deleter(interface.named_property_deleter),
+ 'indexed_property_getter':
+ property_getter(interface.indexed_property_getter, ['index']),
+ 'indexed_property_setter':
+ property_setter(interface.indexed_property_setter, interface),
+ 'indexed_property_deleter':
+ property_deleter(interface.indexed_property_deleter),
+ 'is_override_builtins':
+ 'OverrideBuiltins' in extended_attributes,
+ 'named_property_getter':
+ property_getter(interface.named_property_getter, ['name']),
+ 'named_property_setter':
+ property_setter(interface.named_property_setter, interface),
+ 'named_property_deleter':
+ property_deleter(interface.named_property_deleter),
})
context.update({
- 'has_named_properties_object': is_global and context['named_property_getter'],
+ 'has_named_properties_object':
+ is_global and context['named_property_getter'],
})
# Origin Trials and ContextEnabled features
context.update({
'optional_features':
- sorted(origin_trial_features(interface, context['constants'], context['attributes'], context['methods']) +
- context_enabled_features(context['attributes'])),
+ sorted(
+ origin_trial_features(interface, context['constants'],
+ context['attributes'], context['methods']) +
+ context_enabled_features(context['attributes'])),
})
if context['optional_features']:
includes.add('platform/bindings/v8_per_context_data.h')
@@ -510,17 +633,23 @@ def interface_context(interface, interfaces, component_info):
has_cross_origin_named_enumerator = has_cross_origin_named_getter or has_cross_origin_named_setter # pylint: disable=invalid-name
- if context['named_property_getter'] and context['named_property_getter']['is_cross_origin']:
+ if (context['named_property_getter']
+ and context['named_property_getter']['is_cross_origin']):
has_cross_origin_named_getter = True
- if context['indexed_property_getter'] and context['indexed_property_getter']['is_cross_origin']:
+ if context['indexed_property_getter'] and context[
+ 'indexed_property_getter']['is_cross_origin']:
has_cross_origin_indexed_getter = True
context.update({
- 'has_cross_origin_named_getter': has_cross_origin_named_getter,
- 'has_cross_origin_named_setter': has_cross_origin_named_setter,
- 'has_cross_origin_named_enumerator': has_cross_origin_named_enumerator,
- 'has_cross_origin_indexed_getter': has_cross_origin_indexed_getter,
+ 'has_cross_origin_named_getter':
+ has_cross_origin_named_getter,
+ 'has_cross_origin_named_setter':
+ has_cross_origin_named_setter,
+ 'has_cross_origin_named_enumerator':
+ has_cross_origin_named_enumerator,
+ 'has_cross_origin_indexed_getter':
+ has_cross_origin_indexed_getter,
})
return context
@@ -538,15 +667,19 @@ def attributes_context(interface, interfaces, component_info):
A list of attribute contexts
"""
- attributes = [v8_attributes.attribute_context(interface, attribute, interfaces, component_info)
- for attribute in interface.attributes]
+ attributes = [
+ v8_attributes.attribute_context(interface, attribute, interfaces,
+ component_info)
+ for attribute in interface.attributes
+ ]
- has_conditional_attributes = any(attribute['exposed_test'] for attribute in attributes)
+ has_conditional_attributes = any(
+ attribute['exposed_test'] for attribute in attributes)
if has_conditional_attributes and interface.is_partial:
raise Exception(
'Conditional attributes between partial interfaces in modules '
- 'and the original interfaces(%s) in core are not allowed.'
- % interface.name)
+ 'and the original interfaces(%s) in core are not allowed.' %
+ interface.name)
# See also comment in methods_context.
if not interface.is_partial and (interface.maplike or interface.setlike):
@@ -559,8 +692,9 @@ def attributes_context(interface, interfaces, component_info):
size_attribute.idl_type = IdlType('unsigned long')
size_attribute.is_read_only = True
size_attribute.extended_attributes['NotEnumerable'] = None
- attributes.append(v8_attributes.attribute_context(
- interface, size_attribute, interfaces, component_info))
+ attributes.append(
+ v8_attributes.attribute_context(interface, size_attribute,
+ interfaces, component_info))
return attributes
@@ -583,21 +717,32 @@ def methods_context(interface, component_info):
methods = []
if interface.original_interface:
- methods.extend([v8_methods.method_context(interface, operation, component_info, is_visible=False)
- for operation in interface.original_interface.operations
- if operation.name])
- methods.extend([v8_methods.method_context(interface, method, component_info)
- for method in interface.operations
- if method.name]) # Skip anonymous special operations (methods)
+ methods.extend([
+ v8_methods.method_context(
+ interface, operation, component_info, is_visible=False)
+ for operation in interface.original_interface.operations
+ if operation.name
+ ])
+ methods.extend([
+ v8_methods.method_context(interface, method, component_info)
+ for method in interface.operations if method.name
+ ]) # Skip anonymous special operations (methods)
if interface.partial_interfaces:
- assert len(interface.partial_interfaces) == len(set(interface.partial_interfaces))
+ assert len(interface.partial_interfaces) == len(
+ set(interface.partial_interfaces))
for partial_interface in interface.partial_interfaces:
- methods.extend([v8_methods.method_context(interface, operation, component_info, is_visible=False)
- for operation in partial_interface.operations
- if operation.name])
+ methods.extend([
+ v8_methods.method_context(
+ interface, operation, component_info, is_visible=False)
+ for operation in partial_interface.operations if operation.name
+ ])
compute_method_overloads_context(interface, methods)
- def generated_method(return_type, name, arguments=None, extended_attributes=None, implemented_as=None):
+ def generated_method(return_type,
+ name,
+ arguments=None,
+ extended_attributes=None,
+ implemented_as=None):
operation = IdlOperation()
operation.idl_type = return_type
operation.name = name
@@ -610,7 +755,10 @@ def methods_context(interface, component_info):
operation.extended_attributes['ImplementedAs'] = implemented_as
return v8_methods.method_context(interface, operation, component_info)
- def generated_argument(idl_type, name, is_optional=False, extended_attributes=None):
+ def generated_argument(idl_type,
+ name,
+ is_optional=False,
+ extended_attributes=None):
argument = IdlArgument()
argument.idl_type = idl_type
argument.name = name
@@ -630,23 +778,30 @@ def methods_context(interface, component_info):
# need to support iterator overloads between interface and
# partial interface definitions.
# http://heycam.github.io/webidl/#idl-overloading
- if (not interface.is_partial and (
- interface.iterable or interface.maplike or interface.setlike or
- interface.has_indexed_elements)):
+ if (not interface.is_partial
+ and (interface.iterable or interface.maplike or interface.setlike
+ or interface.has_indexed_elements)):
used_extended_attributes = {}
if interface.iterable:
- used_extended_attributes.update(interface.iterable.extended_attributes)
+ used_extended_attributes.update(
+ interface.iterable.extended_attributes)
elif interface.maplike:
- used_extended_attributes.update(interface.maplike.extended_attributes)
+ used_extended_attributes.update(
+ interface.maplike.extended_attributes)
elif interface.setlike:
- used_extended_attributes.update(interface.setlike.extended_attributes)
+ used_extended_attributes.update(
+ interface.setlike.extended_attributes)
if 'RaisesException' in used_extended_attributes:
- raise ValueError('[RaisesException] is implied for iterable<>/maplike<>/setlike<>')
+ raise ValueError(
+ '[RaisesException] is implied for iterable<>/maplike<>/setlike<>'
+ )
if 'CallWith' in used_extended_attributes:
- raise ValueError('[CallWith=ScriptState] is implied for iterable<>/maplike<>/setlike<>')
+ raise ValueError(
+ '[CallWith=ScriptState] is implied for iterable<>/maplike<>/setlike<>'
+ )
used_extended_attributes.update({
'RaisesException': None,
@@ -666,7 +821,8 @@ def methods_context(interface, component_info):
implemented_as=implemented_as)
if not interface.has_indexed_elements:
- iterator_method = generated_iterator_method('iterator', implemented_as='GetIterator')
+ iterator_method = generated_iterator_method(
+ 'iterator', implemented_as='GetIterator')
if interface.iterable or interface.maplike or interface.setlike:
non_overridable_methods = []
@@ -681,68 +837,101 @@ def methods_context(interface, component_info):
if not is_value_iterator:
if not interface.setlike:
iterator_method_alias = 'entries'
- entries_or_values_method = generated_iterator_method('values')
+ entries_or_values_method = generated_iterator_method(
+ 'values')
else:
iterator_method_alias = 'values'
- entries_or_values_method = generated_iterator_method('entries')
+ entries_or_values_method = generated_iterator_method(
+ 'entries')
non_overridable_methods.extend([
generated_iterator_method('keys'),
entries_or_values_method,
# void forEach(ForEachIteratorCallback callback, [DefaultValue=Undefined] optional any thisArg)
- generated_method(IdlType('void'), 'forEach',
- arguments=[generated_argument(IdlType('ForEachIteratorCallback'), 'callback'),
- generated_argument(IdlType('any'), 'thisArg',
- is_optional=True,
- extended_attributes={'DefaultValue': 'Undefined'})],
- extended_attributes=forEach_extended_attributes),
+ generated_method(
+ IdlType('void'),
+ 'forEach',
+ arguments=[
+ generated_argument(
+ IdlType('ForEachIteratorCallback'),
+ 'callback'),
+ generated_argument(
+ IdlType('any'),
+ 'thisArg',
+ is_optional=True,
+ extended_attributes={
+ 'DefaultValue': 'Undefined'
+ })
+ ],
+ extended_attributes=forEach_extended_attributes),
])
if interface.maplike:
- key_argument = generated_argument(interface.maplike.key_type, 'key')
- value_argument = generated_argument(interface.maplike.value_type, 'value')
+ key_argument = generated_argument(interface.maplike.key_type,
+ 'key')
+ value_argument = generated_argument(
+ interface.maplike.value_type, 'value')
non_overridable_methods.extend([
- generated_method(IdlType('boolean'), 'has',
- arguments=[key_argument],
- extended_attributes=used_extended_attributes),
- generated_method(IdlType('any'), 'get',
- arguments=[key_argument],
- extended_attributes=used_extended_attributes),
+ generated_method(
+ IdlType('boolean'),
+ 'has',
+ arguments=[key_argument],
+ extended_attributes=used_extended_attributes),
+ generated_method(
+ IdlType('any'),
+ 'get',
+ arguments=[key_argument],
+ extended_attributes=used_extended_attributes),
])
if not interface.maplike.is_read_only:
overridable_methods.extend([
- generated_method(IdlType('void'), 'clear',
- extended_attributes=used_extended_attributes),
- generated_method(IdlType('boolean'), 'delete',
- arguments=[key_argument],
- extended_attributes=used_extended_attributes),
- generated_method(IdlType(interface.name), 'set',
- arguments=[key_argument, value_argument],
- extended_attributes=used_extended_attributes),
+ generated_method(
+ IdlType('void'),
+ 'clear',
+ extended_attributes=used_extended_attributes),
+ generated_method(
+ IdlType('boolean'),
+ 'delete',
+ arguments=[key_argument],
+ extended_attributes=used_extended_attributes),
+ generated_method(
+ IdlType(interface.name),
+ 'set',
+ arguments=[key_argument, value_argument],
+ extended_attributes=used_extended_attributes),
])
if interface.setlike:
- value_argument = generated_argument(interface.setlike.value_type, 'value')
+ value_argument = generated_argument(
+ interface.setlike.value_type, 'value')
non_overridable_methods.extend([
- generated_method(IdlType('boolean'), 'has',
- arguments=[value_argument],
- extended_attributes=used_extended_attributes),
+ generated_method(
+ IdlType('boolean'),
+ 'has',
+ arguments=[value_argument],
+ extended_attributes=used_extended_attributes),
])
if not interface.setlike.is_read_only:
overridable_methods.extend([
- generated_method(IdlType(interface.name), 'add',
- arguments=[value_argument],
- extended_attributes=used_extended_attributes),
- generated_method(IdlType('void'), 'clear',
- extended_attributes=used_extended_attributes),
- generated_method(IdlType('boolean'), 'delete',
- arguments=[value_argument],
- extended_attributes=used_extended_attributes),
+ generated_method(
+ IdlType(interface.name),
+ 'add',
+ arguments=[value_argument],
+ extended_attributes=used_extended_attributes),
+ generated_method(
+ IdlType('void'),
+ 'clear',
+ extended_attributes=used_extended_attributes),
+ generated_method(
+ IdlType('boolean'),
+ 'delete',
+ arguments=[value_argument],
+ extended_attributes=used_extended_attributes),
])
methods_by_name = {}
@@ -776,11 +965,12 @@ def methods_context(interface, component_info):
implemented_as = stringifier.operation.name
else:
implemented_as = 'toString'
- methods.append(generated_method(
- return_type=IdlType('DOMString'),
- name='toString',
- extended_attributes=stringifier_ext_attrs,
- implemented_as=implemented_as))
+ methods.append(
+ generated_method(
+ return_type=IdlType('DOMString'),
+ name='toString',
+ extended_attributes=stringifier_ext_attrs,
+ implemented_as=implemented_as))
for method in methods:
# The value of the Function object’s “length” property is a Number
@@ -794,7 +984,8 @@ def methods_context(interface, component_info):
# enabled overloads are actually enabled, so length may be incorrect.
# E.g., [RuntimeEnabled=Foo] void f(); void f(long x);
# should have length 1 if Foo is not enabled, but length 0 if it is.
- method['length'] = (method['overloads']['length'] if 'overloads' in method else
+ method['length'] = (method['overloads']['length']
+ if 'overloads' in method else
method['number_of_required_arguments'])
return {
@@ -822,22 +1013,36 @@ def constant_context(constant, interface, component_info):
runtime_features = component_info['runtime_enabled_features']
return {
- 'camel_case_name': NameStyleConverter(constant.name).to_upper_camel_case(),
- 'cpp_class': extended_attributes.get('PartialInterfaceImplementedAs'),
- 'cpp_type': constant.idl_type.cpp_type,
- 'deprecate_as': v8_utilities.deprecate_as(constant), # [DeprecateAs]
- 'idl_type': constant.idl_type.name,
- 'measure_as': v8_utilities.measure_as(constant, interface), # [MeasureAs]
- 'high_entropy': v8_utilities.high_entropy(constant), # [HighEntropy]
- 'name': constant.name,
- 'origin_trial_feature_name': v8_utilities.origin_trial_feature_name(constant,
- runtime_features), # [RuntimeEnabled] for origin trial
+ 'camel_case_name':
+ NameStyleConverter(constant.name).to_upper_camel_case(),
+ 'cpp_class':
+ extended_attributes.get('PartialInterfaceImplementedAs'),
+ 'cpp_type':
+ constant.idl_type.cpp_type,
+ 'deprecate_as':
+ v8_utilities.deprecate_as(constant), # [DeprecateAs]
+ 'idl_type':
+ constant.idl_type.name,
+ 'measure_as':
+ v8_utilities.measure_as(constant, interface), # [MeasureAs]
+ 'high_entropy':
+ v8_utilities.high_entropy(constant), # [HighEntropy]
+ 'name':
+ constant.name,
+ # [RuntimeEnabled] for origin trial
+ 'origin_trial_feature_name':
+ v8_utilities.origin_trial_feature_name(constant, runtime_features),
# FIXME: use 'reflected_name' as correct 'name'
- 'rcs_counter': 'Blink_' + v8_utilities.cpp_name(interface) + '_' + constant.name + '_ConstantGetter',
- 'reflected_name': extended_attributes.get('Reflect', reflected_name(constant.name)),
- 'runtime_enabled_feature_name': runtime_enabled_feature_name(constant,
- runtime_features), # [RuntimeEnabled] if not in origin trial
- 'value': constant.value,
+ 'rcs_counter':
+ 'Blink_' + v8_utilities.cpp_name(interface) + '_' + constant.name +
+ '_ConstantGetter',
+ 'reflected_name':
+ extended_attributes.get('Reflect', reflected_name(constant.name)),
+ # [RuntimeEnabled] if not in origin trial
+ 'runtime_enabled_feature_name':
+ runtime_enabled_feature_name(constant, runtime_features),
+ 'value':
+ constant.value,
}
@@ -845,6 +1050,7 @@ def constant_context(constant, interface, component_info):
# Overloads
################################################################################
+
def compute_method_overloads_context(interface, methods):
# Regular methods
compute_method_overloads_context_by_type(
@@ -870,7 +1076,8 @@ def compute_method_overloads_context_by_type(interface, methods):
# package necessary information into |method.overloads| for that method.
overloads[-1]['overloads'] = overloads_context(interface, overloads)
overloads[-1]['overloads']['name'] = name
- overloads[-1]['overloads']['camel_case_name'] = NameStyleConverter(name).to_upper_camel_case()
+ overloads[-1]['overloads']['camel_case_name'] = NameStyleConverter(
+ name).to_upper_camel_case()
def overloads_context(interface, overloads):
@@ -887,8 +1094,10 @@ def overloads_context(interface, overloads):
# 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 '
- 'overloaded methods: %s.%s' % (interface.name, overloads[0]['name']))
+ raise Exception(
+ '[RuntimeEnabled] for origin trial cannot be specified on '
+ 'overloaded methods: %s.%s' % (interface.name,
+ overloads[0]['name']))
effective_overloads_by_length = effective_overload_set_by_length(overloads)
lengths = [length for length, _ in effective_overloads_by_length]
@@ -907,7 +1116,8 @@ def overloads_context(interface, overloads):
# runtime enabled, in which case we need to have a runtime determined
# Function.length.
shortest_overloads = effective_overloads_by_length[0][1]
- if (all(method.get('runtime_enabled_feature_name')
+ if (all(
+ method.get('runtime_enabled_feature_name')
for method, _, _ in shortest_overloads)):
# Generate a list of (length, runtime_enabled_feature_names) tuples.
runtime_determined_lengths = []
@@ -921,19 +1131,21 @@ def overloads_context(interface, overloads):
break
runtime_determined_lengths.append(
(length, sorted(runtime_enabled_feature_names)))
- function_length = ('%s::%sMethodLength()'
- % (internal_namespace(interface), camel_case_name))
+ function_length = ('%s::%sMethodLength()' % (
+ internal_namespace(interface), camel_case_name))
# Check if all overloads with the longest required arguments list are
# runtime enabled, in which case we need to have a runtime determined
# maximum distinguishing argument index.
longest_overloads = effective_overloads_by_length[-1][1]
- if (not common_value(overloads, 'runtime_enabled_feature_name') and
- all(method.get('runtime_enabled_feature_name')
+ if (not common_value(overloads, 'runtime_enabled_feature_name')
+ and all(
+ method.get('runtime_enabled_feature_name')
for method, _, _ in longest_overloads)):
# Generate a list of (length, runtime_enabled_feature_name) tuples.
runtime_determined_maxargs = []
- for length, effective_overloads in reversed(effective_overloads_by_length):
+ for length, effective_overloads in reversed(
+ effective_overloads_by_length):
runtime_enabled_feature_names = set(
method['runtime_enabled_feature_name']
for method, _, _ in effective_overloads
@@ -944,15 +1156,17 @@ def overloads_context(interface, overloads):
break
runtime_determined_maxargs.append(
(length, sorted(runtime_enabled_feature_names)))
- maxarg = ('%s::%sMethodMaxArg()' %
- (internal_namespace(interface), camel_case_name))
+ maxarg = ('%s::%sMethodMaxArg()' % (internal_namespace(interface),
+ camel_case_name))
# Check and fail if overloads disagree about whether the return type
# is a Promise or not.
- promise_overload_count = sum(1 for method in overloads if method.get('returns_promise'))
+ promise_overload_count = sum(
+ 1 for method in overloads if method.get('returns_promise'))
if promise_overload_count not in (0, len(overloads)):
- raise ValueError('Overloads of %s have conflicting Promise/non-Promise types'
- % (name))
+ raise ValueError(
+ 'Overloads of %s have conflicting Promise/non-Promise types' %
+ (name))
has_overload_visible = False
has_overload_not_visible = False
@@ -969,30 +1183,45 @@ def overloads_context(interface, overloads):
has_partial_overloads = has_overload_visible and has_overload_not_visible
return {
- 'deprecate_all_as': common_value(overloads, 'deprecate_as'), # [DeprecateAs]
- 'exposed_test_all': common_value(overloads, 'exposed_test'), # [Exposed]
- 'length': function_length,
- 'length_tests_methods': length_tests_methods(effective_overloads_by_length),
+ 'deprecate_all_as':
+ common_value(overloads, 'deprecate_as'), # [DeprecateAs]
+ 'exposed_test_all':
+ common_value(overloads, 'exposed_test'), # [Exposed]
+ 'length':
+ function_length,
+ 'length_tests_methods':
+ length_tests_methods(effective_overloads_by_length),
# 1. Let maxarg be the length of the longest type list of the
# entries in S.
- 'maxarg': maxarg,
- 'measure_all_as': common_value(overloads, 'measure_as'), # [MeasureAs]
- 'returns_promise_all': promise_overload_count > 0,
- 'runtime_determined_lengths': runtime_determined_lengths,
- 'runtime_determined_maxargs': runtime_determined_maxargs,
- 'runtime_enabled_all': common_value(overloads, 'runtime_enabled_feature_name'), # [RuntimeEnabled]
- 'secure_context_test_all': common_value(overloads, 'secure_context_test'), # [SecureContext]
- 'valid_arities': (lengths
- # Only need to report valid arities if there is a gap in the
- # sequence of possible lengths, otherwise invalid length means
- # "not enough arguments".
- if lengths[-1] - lengths[0] != len(lengths) - 1 else None),
- 'visible': has_overload_visible,
- 'has_partial_overloads': has_partial_overloads,
+ 'maxarg':
+ maxarg,
+ 'measure_all_as':
+ common_value(overloads, 'measure_as'), # [MeasureAs]
+ 'returns_promise_all':
+ promise_overload_count > 0,
+ 'runtime_determined_lengths':
+ runtime_determined_lengths,
+ 'runtime_determined_maxargs':
+ runtime_determined_maxargs,
+ # [RuntimeEnabled]
+ 'runtime_enabled_all':
+ common_value(overloads, 'runtime_enabled_feature_name'),
+ # [SecureContext]
+ 'secure_context_test_all':
+ common_value(overloads, 'secure_context_test'),
+ 'valid_arities': (
+ lengths
+ # Only need to report valid arities if there is a gap in the
+ # sequence of possible lengths, otherwise invalid length means
+ # "not enough arguments".
+ if lengths[-1] - lengths[0] != len(lengths) - 1 else None),
+ 'visible':
+ has_overload_visible,
+ 'has_partial_overloads':
+ has_partial_overloads,
}
-
def distinguishing_argument_index(entries):
"""Returns the distinguishing argument index for a sequence of entries.
@@ -1017,9 +1246,10 @@ def distinguishing_argument_index(entries):
return idl_type.inner_type.name
return idl_type.name
- type_lists = [tuple(typename_without_nullable(idl_type)
- for idl_type in entry[1])
- for entry in entries]
+ type_lists = [
+ tuple(typename_without_nullable(idl_type) for idl_type in entry[1])
+ for entry in entries
+ ]
type_list_length = len(type_lists[0])
# Only applicable for entries that “[have] a given type list length”
assert all(len(type_list) == type_list_length for type_list in type_lists)
@@ -1039,8 +1269,8 @@ def distinguishing_argument_index(entries):
# “In addition, for each index j, where j is less than the
# distinguishing argument index for a given type list length, the types
# at index j in all of the entries’ type lists must be the same”
- index = next(i for i, types in enumerate(types_by_index)
- if len(types) > 1)
+ index = next(
+ i for i, types in enumerate(types_by_index) if len(types) > 1)
except StopIteration:
raise ValueError('No distinguishing index found for %s, length %s:\n'
'All entries have the same type list:\n'
@@ -1055,15 +1285,16 @@ def distinguishing_argument_index(entries):
raise ValueError(
'Invalid optionality lists for %s, length %s:\n'
'Optionality lists differ below distinguishing argument index %s:\n'
- '%s'
- % (name, type_list_length, index, set(initial_optionality_lists)))
+ '%s' % (name, type_list_length, index,
+ set(initial_optionality_lists)))
# Check distinguishability
# http://heycam.github.io/webidl/#dfn-distinguishable
# Use names to check for distinct types, since objects are distinct
# FIXME: check distinguishability more precisely, for validation
- distinguishing_argument_type_names = [type_list[index]
- for type_list in type_lists]
+ distinguishing_argument_type_names = [
+ type_list[index] for type_list in type_lists
+ ]
if (len(set(distinguishing_argument_type_names)) !=
len(distinguishing_argument_type_names)):
raise ValueError('Types in distinguishing argument are not distinct:\n'
@@ -1100,8 +1331,9 @@ def resolution_tests_methods(effective_overloads):
Returns:
[(test, method)]
"""
- methods = [effective_overload[0]
- for effective_overload in effective_overloads]
+ methods = [
+ effective_overload[0] for effective_overload in effective_overloads
+ ]
if len(methods) == 1:
# If only one method with a given length, no test needed
yield 'true', methods[0]
@@ -1251,9 +1483,8 @@ def resolution_tests_methods(effective_overloads):
# ...
try:
method = next(method for idl_type, method in idl_types_methods
- if idl_type.is_callback_interface or
- idl_type.is_dictionary or idl_type.name == 'Dictionary' or
- idl_type.is_record_type)
+ if idl_type.is_callback_interface
+ or idl_type.is_dictionary or idl_type.is_record_type)
test = '%s->IsObject()' % cpp_value
yield test, method
except StopIteration:
@@ -1288,9 +1519,10 @@ def resolution_tests_methods(effective_overloads):
# • a string type
# ...
try:
- method = next(method for idl_type, method in idl_types_methods
- if idl_type.is_string_type or idl_type.is_enum
- or (idl_type.is_union_type and idl_type.string_member_type))
+ method = next(
+ method for idl_type, method in idl_types_methods
+ if idl_type.is_string_type or idl_type.is_enum or (
+ idl_type.is_union_type and idl_type.string_member_type))
yield 'true', method
except StopIteration:
pass
@@ -1322,6 +1554,7 @@ def resolution_tests_methods(effective_overloads):
# Utility functions
################################################################################
+
def common(dicts, f):
"""Returns common result of f across an iterable of dicts, or None.
@@ -1361,6 +1594,7 @@ def internal_namespace(interface):
# Constructors
################################################################################
+
# [Constructor]
def constructor_context(interface, constructor):
# [RaisesException=Constructor]
@@ -1369,39 +1603,46 @@ def constructor_context(interface, constructor):
argument_contexts = [
v8_methods.argument_context(interface, constructor, argument, index)
- for index, argument in enumerate(constructor.arguments)]
+ for index, argument in enumerate(constructor.arguments)
+ ]
return {
- 'arguments': argument_contexts,
- 'cpp_type': cpp_name(interface) + '*',
- 'cpp_value': v8_methods.cpp_value(
- interface, constructor, len(constructor.arguments)),
+ 'arguments':
+ argument_contexts,
+ 'cpp_type':
+ cpp_name(interface) + '*',
+ 'cpp_value':
+ v8_methods.cpp_value(interface, constructor,
+ len(constructor.arguments)),
'has_exception_state':
- is_constructor_raises_exception or
- any(argument for argument in constructor.arguments
- if argument.idl_type.name == 'SerializedScriptValue' or
- argument.idl_type.v8_conversion_needs_exception_state),
+ is_constructor_raises_exception
+ or any(argument for argument in constructor.arguments
+ if argument.idl_type.v8_conversion_needs_exception_state),
'has_optional_argument_without_default_value':
- any(True for argument_context in argument_contexts
- if argument_context['is_optional_without_default_value']),
+ any(True for argument_context in argument_contexts
+ if argument_context['is_optional_without_default_value']),
'is_call_with_document':
- # [ConstructorCallWith=Document]
- has_extended_attribute_value(interface,
- 'ConstructorCallWith', 'Document'),
+ # [ConstructorCallWith=Document]
+ has_extended_attribute_value(interface, 'ConstructorCallWith',
+ 'Document'),
'is_call_with_execution_context':
- # [ConstructorCallWith=ExecutionContext]
- has_extended_attribute_value(interface,
- 'ConstructorCallWith', 'ExecutionContext'),
+ # [ConstructorCallWith=ExecutionContext]
+ has_extended_attribute_value(interface, 'ConstructorCallWith',
+ 'ExecutionContext'),
'is_call_with_script_state':
- # [ConstructorCallWith=ScriptState]
- has_extended_attribute_value(
- interface, 'ConstructorCallWith', 'ScriptState'),
- 'is_constructor': True,
- 'is_named_constructor': False,
- 'is_raises_exception': is_constructor_raises_exception,
+ # [ConstructorCallWith=ScriptState]
+ has_extended_attribute_value(interface, 'ConstructorCallWith',
+ 'ScriptState'),
+ 'is_constructor':
+ True,
+ 'is_named_constructor':
+ False,
+ 'is_raises_exception':
+ is_constructor_raises_exception,
'number_of_required_arguments':
- number_of_required_arguments(constructor),
- 'rcs_counter': 'Blink_' + v8_utilities.cpp_name(interface) + '_ConstructorCallback'
+ number_of_required_arguments(constructor),
+ 'rcs_counter':
+ 'Blink_' + v8_utilities.cpp_name(interface) + '_ConstructorCallback'
}
@@ -1424,8 +1665,10 @@ def named_constructor_context(interface):
def number_of_required_arguments(constructor):
- return len([argument for argument in constructor.arguments
- if not (argument.is_optional or argument.is_variadic)])
+ return len([
+ argument for argument in constructor.arguments
+ if not (argument.is_optional or argument.is_variadic)
+ ])
def interface_length(constructors):
@@ -1441,6 +1684,7 @@ def interface_length(constructors):
# http://heycam.github.io/webidl/#idl-special-operations
################################################################################
+
def property_getter(getter, cpp_arguments):
if not getter:
return None
@@ -1455,10 +1699,12 @@ def property_getter(getter, cpp_arguments):
return ''
extended_attributes = getter.extended_attributes
- has_no_side_effect = v8_utilities.has_extended_attribute_value(getter, 'Affects', 'Nothing')
+ has_no_side_effect = v8_utilities.has_extended_attribute_value(
+ getter, 'Affects', 'Nothing')
idl_type = getter.idl_type
idl_type.add_includes_for_type(extended_attributes)
- is_call_with_script_state = v8_utilities.has_extended_attribute_value(getter, 'CallWith', 'ScriptState')
+ is_call_with_script_state = v8_utilities.has_extended_attribute_value(
+ getter, 'CallWith', 'ScriptState')
is_raises_exception = 'RaisesException' in extended_attributes
use_output_parameter_for_result = idl_type.use_output_parameter_for_result
@@ -1475,27 +1721,41 @@ def property_getter(getter, cpp_arguments):
cpp_value = '%s(%s)' % (cpp_method_name, ', '.join(cpp_arguments))
return {
- 'cpp_type': idl_type.cpp_type,
- 'cpp_value': cpp_value,
- 'has_no_side_effect': has_no_side_effect,
- 'is_call_with_script_state': is_call_with_script_state,
- 'is_cross_origin': 'CrossOrigin' in extended_attributes,
+ 'cpp_type':
+ idl_type.cpp_type,
+ 'cpp_value':
+ cpp_value,
+ 'has_no_side_effect':
+ has_no_side_effect,
+ 'is_call_with_script_state':
+ is_call_with_script_state,
+ 'is_cross_origin':
+ 'CrossOrigin' in extended_attributes,
'is_custom':
- 'Custom' in extended_attributes and
- (not extended_attributes['Custom'] or
- has_extended_attribute_value(getter, 'Custom', 'PropertyGetter')),
- 'is_custom_property_enumerator': has_extended_attribute_value(
- getter, 'Custom', 'PropertyEnumerator'),
- 'is_custom_property_query': has_extended_attribute_value(
- getter, 'Custom', 'PropertyQuery'),
+ 'Custom' in extended_attributes and
+ (not extended_attributes['Custom']
+ or has_extended_attribute_value(getter, 'Custom', 'PropertyGetter')),
+ 'is_custom_property_enumerator':
+ has_extended_attribute_value(getter, 'Custom', 'PropertyEnumerator'),
+ 'is_custom_property_query':
+ has_extended_attribute_value(getter, 'Custom', 'PropertyQuery'),
# TODO(rakuco): [NotEnumerable] does not make sense here and is only
# used in non-standard IDL operations. We need to get rid of them.
- 'is_enumerable': 'NotEnumerable' not in extended_attributes,
- 'is_null_expression': is_null_expression(idl_type),
- 'is_raises_exception': is_raises_exception,
- 'name': cpp_name(getter),
- 'use_output_parameter_for_result': use_output_parameter_for_result,
- 'v8_set_return_value': idl_type.v8_set_return_value('result', extended_attributes=extended_attributes, script_wrappable='impl'),
+ 'is_enumerable':
+ 'NotEnumerable' not in extended_attributes,
+ 'is_null_expression':
+ is_null_expression(idl_type),
+ 'is_raises_exception':
+ is_raises_exception,
+ 'name':
+ cpp_name(getter),
+ 'use_output_parameter_for_result':
+ use_output_parameter_for_result,
+ 'v8_set_return_value':
+ idl_type.v8_set_return_value(
+ 'result',
+ extended_attributes=extended_attributes,
+ script_wrappable='impl'),
}
@@ -1506,25 +1766,35 @@ def property_setter(setter, interface):
extended_attributes = setter.extended_attributes
idl_type = setter.arguments[1].idl_type
idl_type.add_includes_for_type(extended_attributes)
- is_call_with_script_state = v8_utilities.has_extended_attribute_value(setter, 'CallWith', 'ScriptState')
+ is_call_with_script_state = v8_utilities.has_extended_attribute_value(
+ setter, 'CallWith', 'ScriptState')
is_raises_exception = 'RaisesException' in extended_attributes
is_ce_reactions = 'CEReactions' in extended_attributes
has_type_checking_interface = idl_type.is_wrapper_type
return {
- 'has_exception_state': (is_raises_exception or
- idl_type.v8_conversion_needs_exception_state),
- 'has_type_checking_interface': has_type_checking_interface,
- 'idl_type': idl_type.base_type,
- 'is_call_with_script_state': is_call_with_script_state,
- 'is_ce_reactions': is_ce_reactions,
- 'is_custom': 'Custom' in extended_attributes,
- 'is_nullable': idl_type.is_nullable,
- 'is_raises_exception': is_raises_exception,
- 'name': cpp_name(setter),
- 'v8_value_to_local_cpp_value': idl_type.v8_value_to_local_cpp_value(
- extended_attributes, 'v8_value', 'property_value'),
+ 'has_exception_state':
+ (is_raises_exception or idl_type.v8_conversion_needs_exception_state),
+ 'has_type_checking_interface':
+ has_type_checking_interface,
+ 'idl_type':
+ idl_type.base_type,
+ 'is_call_with_script_state':
+ is_call_with_script_state,
+ 'is_ce_reactions':
+ is_ce_reactions,
+ 'is_custom':
+ 'Custom' in extended_attributes,
+ 'is_nullable':
+ idl_type.is_nullable,
+ 'is_raises_exception':
+ is_raises_exception,
+ 'name':
+ cpp_name(setter),
+ 'v8_value_to_local_cpp_value':
+ idl_type.v8_value_to_local_cpp_value(extended_attributes, 'v8_value',
+ 'property_value'),
}
@@ -1533,7 +1803,8 @@ def property_deleter(deleter):
return None
extended_attributes = deleter.extended_attributes
- is_call_with_script_state = v8_utilities.has_extended_attribute_value(deleter, 'CallWith', 'ScriptState')
+ is_call_with_script_state = v8_utilities.has_extended_attribute_value(
+ deleter, 'CallWith', 'ScriptState')
is_ce_reactions = 'CEReactions' in extended_attributes
return {
'is_call_with_script_state': is_call_with_script_state,
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/v8_methods.py b/chromium/third_party/blink/renderer/bindings/scripts/v8_methods.py
index 07fcc8d0f8e..22f9a93432c 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/v8_methods.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_methods.py
@@ -25,7 +25,6 @@
# 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.
-
"""Generate template values for methods.
Extends IdlArgument with property |default_cpp_value|.
@@ -37,8 +36,8 @@ Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
import os
import sys
-sys.path.append(os.path.join(os.path.dirname(__file__),
- '..', '..', 'build', 'scripts'))
+sys.path.append(
+ os.path.join(os.path.dirname(__file__), '..', '..', 'build', 'scripts'))
from blinkbuild.name_style_converter import NameStyleConverter
from idl_definitions import IdlArgument, IdlOperation
from idl_types import IdlTypeBase, IdlUnionType, inherits_interface
@@ -50,7 +49,9 @@ from v8_utilities import (has_extended_attribute_value, is_unforgeable)
def method_is_visible(method, interface_is_partial):
if 'overloads' in method:
- return method['overloads']['visible'] and not (method['overloads']['has_partial_overloads'] and interface_is_partial)
+ return method['overloads']['visible'] and not (
+ method['overloads']['has_partial_overloads']
+ and interface_is_partial)
return method['visible'] and 'overload_index' not in method
@@ -59,19 +60,23 @@ def is_origin_trial_enabled(method):
def is_secure_context(method):
- return bool(method['overloads']['secure_context_test_all'] if 'overloads' in method else method['secure_context_test'])
+ return bool(method['overloads']['secure_context_test_all'] if 'overloads'
+ in method else method['secure_context_test'])
def is_conditionally_enabled(method):
- exposed = method['overloads']['exposed_test_all'] if 'overloads' in method else method['exposed_test']
+ exposed = method['overloads']['exposed_test_all'] \
+ if 'overloads' in method else method['exposed_test']
return exposed or is_secure_context(method)
def filter_conditionally_enabled(methods, interface_is_partial):
- return [method for method in methods if (
- method_is_visible(method, interface_is_partial) and
- is_conditionally_enabled(method) and
- not is_origin_trial_enabled(method))]
+ return [
+ method for method in methods
+ if (method_is_visible(method, interface_is_partial)
+ and is_conditionally_enabled(method)
+ and not is_origin_trial_enabled(method))
+ ]
def custom_registration(method):
@@ -81,48 +86,65 @@ def custom_registration(method):
if method['is_cross_origin']:
return True
if 'overloads' in method:
- return (method['overloads']['runtime_determined_lengths'] or
- (method['overloads']['runtime_enabled_all'] and not is_conditionally_enabled(method)))
- return method['runtime_enabled_feature_name'] and not is_conditionally_enabled(method)
+ return (method['overloads']['runtime_determined_lengths']
+ or (method['overloads']['runtime_enabled_all']
+ and not is_conditionally_enabled(method)))
+ return method[
+ 'runtime_enabled_feature_name'] and not is_conditionally_enabled(
+ method)
def filter_custom_registration(methods, interface_is_partial):
- return [method for method in methods if (
- method_is_visible(method, interface_is_partial) and custom_registration(method))]
+ return [
+ method for method in methods
+ if (method_is_visible(method, interface_is_partial)
+ and custom_registration(method))
+ ]
def filter_method_configuration(methods, interface_is_partial):
- return [method for method in methods if
- method_is_visible(method, interface_is_partial) and
- not is_origin_trial_enabled(method) and
- not is_conditionally_enabled(method) and
- not custom_registration(method)]
+ return [
+ method for method in methods
+ if method_is_visible(method, interface_is_partial)
+ and not is_origin_trial_enabled(method)
+ and not is_conditionally_enabled(method)
+ and not custom_registration(method)
+ ]
def method_filters():
- return {'custom_registration': filter_custom_registration,
- 'has_method_configuration': filter_method_configuration}
+ return {
+ 'custom_registration': filter_custom_registration,
+ 'has_method_configuration': filter_method_configuration
+ }
def use_local_result(method):
extended_attributes = method.extended_attributes
idl_type = method.idl_type
- return (has_extended_attribute_value(method, 'CallWith', 'ScriptState') or
- 'NewObject' in extended_attributes or
- 'RaisesException' in extended_attributes or
- idl_type.is_union_type or
- idl_type.is_dictionary or
- idl_type.is_explicit_nullable)
+ return (has_extended_attribute_value(method, 'CallWith', 'ScriptState')
+ or 'NewObject' in extended_attributes
+ or 'RaisesException' in extended_attributes
+ or idl_type.is_union_type or idl_type.is_dictionary
+ or idl_type.is_explicit_nullable)
def runtime_call_stats_context(interface, method):
includes.add('platform/bindings/runtime_call_stats.h')
- generic_counter_name = 'Blink_' + v8_utilities.cpp_name(interface) + '_' + method.name
- (method_counter, extended_attribute_defined) = v8_utilities.rcs_counter_name(method, generic_counter_name)
+ generic_counter_name = (
+ 'Blink_' + v8_utilities.cpp_name(interface) + '_' + method.name)
+ (method_counter, extended_attribute_defined) = \
+ v8_utilities.rcs_counter_name(method, generic_counter_name)
+ trace_event_name = interface.name + '.' + method.name
return {
- 'extended_attribute_defined': extended_attribute_defined,
- 'method_counter': method_counter,
- 'origin_safe_method_getter_counter': generic_counter_name + '_OriginSafeMethodGetter'
+ 'extended_attribute_defined':
+ extended_attribute_defined,
+ 'method_counter':
+ method_counter,
+ 'origin_safe_method_getter_counter':
+ generic_counter_name + '_OriginSafeMethodGetter',
+ 'trace_event_name':
+ trace_event_name,
}
@@ -138,18 +160,19 @@ def method_context(interface, method, component_info, is_visible=True):
this_cpp_value = cpp_value(interface, method, len(arguments))
- is_call_with_script_state = has_extended_attribute_value(method, 'CallWith', 'ScriptState')
- is_call_with_this_value = has_extended_attribute_value(method, 'CallWith', 'ThisValue')
+ is_call_with_script_state = has_extended_attribute_value(
+ method, 'CallWith', 'ScriptState')
+ is_call_with_this_value = has_extended_attribute_value(
+ method, 'CallWith', 'ThisValue')
if is_call_with_script_state or is_call_with_this_value:
includes.add('platform/bindings/script_state.h')
# [CheckSecurity]
is_cross_origin = 'CrossOrigin' in extended_attributes
- is_check_security_for_receiver = (
- has_extended_attribute_value(interface, 'CheckSecurity', 'Receiver') and
- not is_cross_origin)
- is_check_security_for_return_value = (
- has_extended_attribute_value(method, 'CheckSecurity', 'ReturnValue'))
+ is_check_security_for_receiver = (has_extended_attribute_value(
+ interface, 'CheckSecurity', 'Receiver') and not is_cross_origin)
+ is_check_security_for_return_value = (has_extended_attribute_value(
+ method, 'CheckSecurity', 'ReturnValue'))
if is_check_security_for_receiver or is_check_security_for_return_value:
includes.add('bindings/core/v8/binding_security.h')
if is_check_security_for_return_value:
@@ -164,8 +187,6 @@ def method_context(interface, method, component_info, is_visible=True):
includes.add('core/html/custom/v0_custom_element_processing_stack.h')
is_raises_exception = 'RaisesException' in extended_attributes
- is_custom_call_prologue = has_extended_attribute_value(method, 'Custom', 'CallPrologue')
- is_custom_call_epilogue = has_extended_attribute_value(method, 'Custom', 'CallEpilogue')
if 'LenientThis' in extended_attributes:
raise Exception('[LenientThis] is not supported for operations.')
@@ -180,89 +201,142 @@ def method_context(interface, method, component_info, is_visible=True):
includes.add('platform/bindings/v8_per_context_data.h')
argument_contexts = [
- argument_context(interface, method, argument, index, is_visible=is_visible)
- for index, argument in enumerate(arguments)]
+ argument_context(
+ interface, method, argument, index, is_visible=is_visible)
+ for index, argument in enumerate(arguments)
+ ]
runtime_features = component_info['runtime_enabled_features']
return {
- 'activity_logging_world_list': v8_utilities.activity_logging_world_list(method), # [ActivityLogging]
- 'arguments': argument_contexts,
- 'camel_case_name': NameStyleConverter(name).to_upper_camel_case(),
- 'cpp_type': (v8_types.cpp_template_type('base::Optional', idl_type.cpp_type)
- if idl_type.is_explicit_nullable
- else v8_types.cpp_type(idl_type, extended_attributes=extended_attributes)),
- 'cpp_value': this_cpp_value,
- 'cpp_type_initializer': idl_type.cpp_type_initializer,
- 'high_entropy': v8_utilities.high_entropy(method), # [HighEntropy]
- 'deprecate_as': v8_utilities.deprecate_as(method), # [DeprecateAs]
- 'do_not_test_new_object': 'DoNotTestNewObject' in extended_attributes,
- 'exposed_test': v8_utilities.exposed(method, interface), # [Exposed]
+ 'activity_logging_world_list':
+ v8_utilities.activity_logging_world_list(method), # [ActivityLogging]
+ 'arguments':
+ argument_contexts,
+ 'camel_case_name':
+ NameStyleConverter(name).to_upper_camel_case(),
+ 'cpp_type':
+ (v8_types.cpp_template_type('base::Optional', idl_type.cpp_type)
+ if idl_type.is_explicit_nullable else v8_types.cpp_type(
+ idl_type, extended_attributes=extended_attributes)),
+ 'cpp_value':
+ this_cpp_value,
+ 'cpp_type_initializer':
+ idl_type.cpp_type_initializer,
+ 'high_entropy':
+ v8_utilities.high_entropy(method), # [HighEntropy]
+ 'deprecate_as':
+ v8_utilities.deprecate_as(method), # [DeprecateAs]
+ 'do_not_test_new_object':
+ 'DoNotTestNewObject' in extended_attributes,
+ 'exposed_test':
+ v8_utilities.exposed(method, interface), # [Exposed]
'has_exception_state':
- is_raises_exception or
- is_check_security_for_receiver or
- any(argument for argument in arguments
- if (argument.idl_type.name == 'SerializedScriptValue' or
- argument_conversion_needs_exception_state(method, argument))),
+ is_raises_exception or is_check_security_for_receiver or any(
+ argument for argument in arguments
+ if argument_conversion_needs_exception_state(method, argument)),
'has_optional_argument_without_default_value':
- any(True for argument_context in argument_contexts
- if argument_context['is_optional_without_default_value']),
- 'idl_type': idl_type.base_type,
- 'is_call_with_execution_context': has_extended_attribute_value(method, 'CallWith', 'ExecutionContext'),
- 'is_call_with_script_state': is_call_with_script_state,
- 'is_call_with_this_value': is_call_with_this_value,
- 'is_ce_reactions': is_ce_reactions,
- 'is_check_security_for_receiver': is_check_security_for_receiver,
- 'is_check_security_for_return_value': is_check_security_for_return_value,
- 'is_cross_origin': 'CrossOrigin' in extended_attributes,
- 'is_custom': 'Custom' in extended_attributes and
- not (is_custom_call_prologue or is_custom_call_epilogue),
- 'is_custom_call_prologue': is_custom_call_prologue,
- 'is_custom_call_epilogue': is_custom_call_epilogue,
- 'is_custom_element_callbacks': is_custom_element_callbacks,
- 'is_explicit_nullable': idl_type.is_explicit_nullable,
- 'is_new_object': 'NewObject' in extended_attributes,
+ any(True for argument_context in argument_contexts
+ if argument_context['is_optional_without_default_value']),
+ 'idl_type':
+ idl_type.base_type,
+ 'is_call_with_execution_context':
+ has_extended_attribute_value(method, 'CallWith', 'ExecutionContext'),
+ 'is_call_with_script_state':
+ is_call_with_script_state,
+ 'is_call_with_this_value':
+ is_call_with_this_value,
+ 'is_ce_reactions':
+ is_ce_reactions,
+ 'is_check_security_for_receiver':
+ is_check_security_for_receiver,
+ 'is_check_security_for_return_value':
+ is_check_security_for_return_value,
+ 'is_cross_origin':
+ 'CrossOrigin' in extended_attributes,
+ 'is_custom':
+ 'Custom' in extended_attributes,
+ 'is_custom_element_callbacks':
+ is_custom_element_callbacks,
+ 'is_explicit_nullable':
+ idl_type.is_explicit_nullable,
+ 'is_new_object':
+ 'NewObject' in extended_attributes,
'is_partial_interface_member':
- 'PartialInterfaceImplementedAs' in extended_attributes,
- 'is_per_world_bindings': 'PerWorldBindings' in extended_attributes,
- 'is_raises_exception': is_raises_exception,
- 'is_static': is_static,
- 'is_unforgeable': is_unforgeable(method),
- 'is_variadic': arguments and arguments[-1].is_variadic,
- 'measure_as': v8_utilities.measure_as(method, interface), # [MeasureAs]
- 'name': name,
- 'number_of_arguments': len(arguments),
- 'number_of_required_arguments': len([
+ 'PartialInterfaceImplementedAs' in extended_attributes,
+ 'is_per_world_bindings':
+ 'PerWorldBindings' in extended_attributes,
+ 'is_raises_exception':
+ is_raises_exception,
+ 'is_static':
+ is_static,
+ 'is_unforgeable':
+ is_unforgeable(method),
+ 'is_variadic':
+ arguments and arguments[-1].is_variadic,
+ 'measure_as':
+ v8_utilities.measure_as(method, interface), # [MeasureAs]
+ 'name':
+ name,
+ 'number_of_arguments':
+ len(arguments),
+ 'number_of_required_arguments':
+ len([
argument for argument in arguments
- if not (argument.is_optional or argument.is_variadic)]),
- 'number_of_required_or_variadic_arguments': len([
- argument for argument in arguments
- if not argument.is_optional]),
- 'on_instance': v8_utilities.on_instance(interface, method),
- 'on_interface': v8_utilities.on_interface(interface, method),
- 'on_prototype': v8_utilities.on_prototype(interface, method),
+ if not (argument.is_optional or argument.is_variadic)
+ ]),
+ 'number_of_required_or_variadic_arguments':
+ len([argument for argument in arguments if not argument.is_optional]),
+ 'on_instance':
+ v8_utilities.on_instance(interface, method),
+ 'on_interface':
+ v8_utilities.on_interface(interface, method),
+ 'on_prototype':
+ v8_utilities.on_prototype(interface, method),
+ # [RuntimeEnabled] for origin trial
'origin_trial_feature_name':
- v8_utilities.origin_trial_feature_name(method, runtime_features), # [RuntimeEnabled] for origin trial
- 'property_attributes': property_attributes(interface, method),
- 'returns_promise': method.returns_promise,
- 'runtime_call_stats': runtime_call_stats_context(interface, method),
+ v8_utilities.origin_trial_feature_name(method, runtime_features),
+ 'property_attributes':
+ property_attributes(interface, method),
+ 'returns_promise':
+ method.returns_promise,
+ 'runtime_call_stats':
+ runtime_call_stats_context(interface, method),
+ # [RuntimeEnabled] if not in origin trial
'runtime_enabled_feature_name':
- v8_utilities.runtime_enabled_feature_name(method, runtime_features), # [RuntimeEnabled] if not in origin trial
- 'secure_context_test': v8_utilities.secure_context(method, interface), # [SecureContext]
- 'side_effect_type': side_effect_type, # [Affects]
- 'snake_case_name': NameStyleConverter(name).to_snake_case(),
- 'use_output_parameter_for_result': idl_type.use_output_parameter_for_result,
- 'use_local_result': use_local_result(method),
- 'v8_set_return_value': v8_set_return_value(interface.name, method, this_cpp_value),
- 'v8_set_return_value_for_main_world': v8_set_return_value(interface.name, method, this_cpp_value, for_main_world=True),
- 'visible': is_visible,
- 'world_suffixes': ['', 'ForMainWorld'] if 'PerWorldBindings' in extended_attributes else [''], # [PerWorldBindings],
+ v8_utilities.runtime_enabled_feature_name(method, runtime_features),
+ # [SecureContext]
+ 'secure_context_test':
+ v8_utilities.secure_context(method, interface),
+ # [Affects]
+ 'side_effect_type':
+ side_effect_type,
+ 'snake_case_name':
+ NameStyleConverter(name).to_snake_case(),
+ 'use_output_parameter_for_result':
+ idl_type.use_output_parameter_for_result,
+ 'use_local_result':
+ use_local_result(method),
+ 'v8_set_return_value':
+ v8_set_return_value(interface.name, method, this_cpp_value),
+ 'v8_set_return_value_for_main_world':
+ v8_set_return_value(
+ interface.name, method, this_cpp_value, for_main_world=True),
+ 'visible':
+ is_visible,
+ 'world_suffixes':
+ ['', 'ForMainWorld'] if 'PerWorldBindings' in extended_attributes else
+ [''], # [PerWorldBindings],
}
def argument_context(interface, method, argument, index, is_visible=True):
extended_attributes = argument.extended_attributes
idl_type = argument.idl_type
+ if idl_type.has_string_context:
+ includes.add(
+ 'third_party/blink/renderer/bindings/core/v8/generated_code_helper.h'
+ )
if is_visible:
idl_type.add_includes_for_type(extended_attributes)
this_cpp_value = cpp_value(interface, method, index)
@@ -271,52 +345,77 @@ def argument_context(interface, method, argument, index, is_visible=True):
has_type_checking_interface = idl_type.is_wrapper_type
set_default_value = argument.set_default_value
- this_cpp_type = idl_type.cpp_type_args(extended_attributes=extended_attributes,
- raw_type=True,
- used_as_variadic_argument=argument.is_variadic)
+ this_cpp_type = idl_type.cpp_type_args(
+ extended_attributes=extended_attributes,
+ raw_type=True,
+ used_as_variadic_argument=argument.is_variadic)
snake_case_name = NameStyleConverter(argument.name).to_snake_case()
context = {
- 'cpp_type': (
- v8_types.cpp_template_type('base::Optional', this_cpp_type)
- if idl_type.is_explicit_nullable and not argument.is_variadic
- else this_cpp_type),
- 'cpp_value': this_cpp_value,
+ 'cpp_type': (v8_types.cpp_template_type(
+ 'base::Optional', this_cpp_type) if idl_type.is_explicit_nullable
+ and not argument.is_variadic else this_cpp_type),
+ 'cpp_value':
+ this_cpp_value,
# FIXME: check that the default value's type is compatible with the argument's
- 'enum_type': idl_type.enum_type,
- 'enum_values': idl_type.enum_values,
- 'handle': '%s_handle' % snake_case_name,
+ 'enum_type':
+ idl_type.enum_type,
+ 'enum_values':
+ idl_type.enum_values,
+ 'handle':
+ '%s_handle' % snake_case_name,
# TODO(peria): remove once [DefaultValue] removed and just use
# argument.default_value. https://crbug.com/924419
- 'has_default': 'DefaultValue' in extended_attributes or set_default_value,
- 'has_type_checking_interface': has_type_checking_interface,
+ 'has_default':
+ 'DefaultValue' in extended_attributes or set_default_value,
+ 'has_type_checking_interface':
+ has_type_checking_interface,
# Dictionary is special-cased, but arrays and sequences shouldn't be
- 'idl_type': idl_type.base_type,
- 'idl_type_object': idl_type,
- 'index': index,
- 'is_callback_function': idl_type.is_callback_function,
- 'is_callback_interface': idl_type.is_callback_interface,
+ 'idl_type':
+ idl_type.base_type,
+ 'idl_type_object':
+ idl_type,
+ 'index':
+ index,
+ 'is_callback_function':
+ idl_type.is_callback_function,
+ 'is_callback_interface':
+ idl_type.is_callback_interface,
# FIXME: Remove generic 'Dictionary' special-casing
- 'is_dictionary': idl_type.is_dictionary or idl_type.base_type == 'Dictionary',
- 'is_explicit_nullable': idl_type.is_explicit_nullable,
- 'is_nullable': idl_type.is_nullable,
- 'is_optional': argument.is_optional,
- 'is_variadic': argument.is_variadic,
- 'is_variadic_wrapper_type': is_variadic_wrapper_type,
- 'is_wrapper_type': idl_type.is_wrapper_type,
- 'local_cpp_variable': snake_case_name,
- 'name': argument.name,
- 'set_default_value': set_default_value,
- 'use_permissive_dictionary_conversion': 'PermissiveDictionaryConversion' in extended_attributes,
- 'v8_set_return_value': v8_set_return_value(interface.name, method, this_cpp_value),
- 'v8_set_return_value_for_main_world': v8_set_return_value(interface.name, method, this_cpp_value, for_main_world=True),
- 'v8_value_to_local_cpp_value': v8_value_to_local_cpp_value(interface.name, method, argument, index),
+ 'is_dictionary':
+ idl_type.is_dictionary,
+ 'is_explicit_nullable':
+ idl_type.is_explicit_nullable,
+ 'is_nullable':
+ idl_type.is_nullable,
+ 'is_optional':
+ argument.is_optional,
+ 'is_variadic':
+ argument.is_variadic,
+ 'is_variadic_wrapper_type':
+ is_variadic_wrapper_type,
+ 'is_wrapper_type':
+ idl_type.is_wrapper_type,
+ 'local_cpp_variable':
+ snake_case_name,
+ 'name':
+ argument.name,
+ 'set_default_value':
+ set_default_value,
+ 'use_permissive_dictionary_conversion':
+ 'PermissiveDictionaryConversion' in extended_attributes,
+ 'v8_set_return_value':
+ v8_set_return_value(interface.name, method, this_cpp_value),
+ 'v8_set_return_value_for_main_world':
+ v8_set_return_value(
+ interface.name, method, this_cpp_value, for_main_world=True),
+ 'v8_value_to_local_cpp_value':
+ v8_value_to_local_cpp_value(interface.name, method, argument, index),
}
context.update({
'is_optional_without_default_value':
- context['is_optional'] and
- not context['has_default'] and
- not context['is_dictionary'] and
- not context['is_callback_interface'],
+ context['is_optional'] and not context['has_default']
+ and not context['is_dictionary']
+ and not context['is_callback_interface'],
})
return context
@@ -325,13 +424,15 @@ def argument_context(interface, method, argument, index, is_visible=True):
# Value handling
################################################################################
+
def cpp_value(interface, method, number_of_arguments):
# Truncate omitted optional arguments
arguments = method.arguments[:number_of_arguments]
cpp_arguments = []
if method.is_constructor:
- call_with_values = interface.extended_attributes.get('ConstructorCallWith')
+ call_with_values = interface.extended_attributes.get(
+ 'ConstructorCallWith')
else:
call_with_values = method.extended_attributes.get('CallWith')
cpp_arguments.extend(v8_utilities.call_with_arguments(call_with_values))
@@ -339,20 +440,12 @@ def cpp_value(interface, method, number_of_arguments):
# 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
- if ('PartialInterfaceImplementedAs' in method.extended_attributes and
- not method.is_static):
+ if ('PartialInterfaceImplementedAs' in method.extended_attributes
+ and not method.is_static):
cpp_arguments.append('*impl')
for argument in arguments:
variable_name = NameStyleConverter(argument.name).to_snake_case()
- if argument.idl_type.base_type == 'SerializedScriptValue':
- cpp_arguments.append('std::move(%s)' % variable_name)
- else:
- cpp_arguments.append(variable_name)
-
- if ('RaisesException' in method.extended_attributes or
- (method.is_constructor and
- has_extended_attribute_value(interface, 'RaisesException', 'Constructor'))):
- cpp_arguments.append('exception_state')
+ cpp_arguments.append(variable_name)
# If a method returns an IDL dictionary or union type, the return value is
# passed as an argument to impl classes.
@@ -360,6 +453,11 @@ def cpp_value(interface, method, number_of_arguments):
if idl_type and idl_type.use_output_parameter_for_result:
cpp_arguments.append('result')
+ if ('RaisesException' in method.extended_attributes
+ or (method.is_constructor and has_extended_attribute_value(
+ interface, 'RaisesException', 'Constructor'))):
+ cpp_arguments.append('exception_state')
+
if method.name == 'Constructor':
base_name = 'Create'
elif method.name == 'NamedConstructor':
@@ -371,7 +469,10 @@ def cpp_value(interface, method, number_of_arguments):
return '%s(%s)' % (cpp_method_name, ', '.join(cpp_arguments))
-def v8_set_return_value(interface_name, method, cpp_value, for_main_world=False):
+def v8_set_return_value(interface_name,
+ method,
+ cpp_value,
+ for_main_world=False):
idl_type = method.idl_type
extended_attributes = method.extended_attributes
if not idl_type or idl_type.name == 'void':
@@ -386,75 +487,61 @@ def v8_set_return_value(interface_name, method, cpp_value, for_main_world=False)
else:
cpp_value = 'result'
- script_wrappable = 'impl' if inherits_interface(interface_name, 'Node') else ''
- return idl_type.v8_set_return_value(cpp_value, extended_attributes, script_wrappable=script_wrappable, for_main_world=for_main_world, is_static=method.is_static)
+ script_wrappable = 'impl' if inherits_interface(interface_name,
+ 'Node') else ''
+ return idl_type.v8_set_return_value(
+ cpp_value,
+ extended_attributes,
+ script_wrappable=script_wrappable,
+ for_main_world=for_main_world,
+ is_static=method.is_static)
-def v8_value_to_local_cpp_variadic_value(argument, index):
+def v8_value_to_local_cpp_variadic_value(argument,
+ index,
+ for_constructor_callback=False):
assert argument.is_variadic
- idl_type = v8_types.native_value_traits_type_name(argument.idl_type,
- argument.extended_attributes, True)
-
+ idl_type = v8_types.native_value_traits_type_name(
+ argument.idl_type, argument.extended_attributes, True)
+ execution_context_if_needed = ''
+ if argument.idl_type.has_string_context:
+ execution_context_if_needed = ', bindings::ExecutionContextFromV8Wrappable(impl)'
+ if for_constructor_callback:
+ execution_context_if_needed = ', CurrentExecutionContext(info.GetIsolate())'
+ assign_expression = 'ToImplArguments<%s>(info, %s, exception_state%s)' % (
+ idl_type, index, execution_context_if_needed)
return {
- 'assign_expression': 'ToImplArguments<%s>(info, %s, exception_state)' % (idl_type, index),
+ 'assign_expression': assign_expression,
'check_expression': 'exception_state.HadException()',
'cpp_name': NameStyleConverter(argument.name).to_snake_case(),
'declare_variable': False,
}
-def v8_value_to_local_cpp_ssv_value(extended_attributes, idl_type, v8_value, variable_name, for_storage):
- this_cpp_type = idl_type.cpp_type_args(extended_attributes=extended_attributes, raw_type=True)
-
- storage_policy = 'kForStorage' if for_storage else 'kNotForStorage'
- arguments = ', '.join([
- 'info.GetIsolate()',
- v8_value,
- '{ssv}::SerializeOptions({ssv}::{storage_policy})',
- 'exception_state'
- ])
- cpp_expression_format = 'NativeValueTraits<{ssv}>::NativeValue(%s)' % arguments
- this_cpp_value = cpp_expression_format.format(
- ssv='SerializedScriptValue',
- storage_policy=storage_policy
- )
-
- return {
- 'assign_expression': this_cpp_value,
- 'check_expression': 'exception_state.HadException()',
- 'cpp_type': this_cpp_type,
- 'cpp_name': variable_name,
- 'declare_variable': False,
- }
-
-
def v8_value_to_local_cpp_value(interface_name, method, argument, index):
extended_attributes = argument.extended_attributes
idl_type = argument.idl_type
name = NameStyleConverter(argument.name).to_snake_case()
v8_value = 'info[{index}]'.format(index=index)
-
- # History.pushState and History.replaceState are explicitly specified as
- # serializing the value for storage. The default is to not serialize for
- # storage. See https://html.spec.whatwg.org/C/#dom-history-pushstate
- if idl_type.name == 'SerializedScriptValue':
- for_storage = (interface_name == 'History' and
- method.name in ('pushState', 'replaceState'))
- return v8_value_to_local_cpp_ssv_value(extended_attributes, idl_type,
- v8_value, name,
- for_storage=for_storage)
+ for_constructor_callback = method.name == 'Constructor'
if argument.is_variadic:
- return v8_value_to_local_cpp_variadic_value(argument, index)
- return idl_type.v8_value_to_local_cpp_value(extended_attributes, v8_value,
- name, declare_variable=False,
- use_exception_state=method.returns_promise)
+ return v8_value_to_local_cpp_variadic_value(
+ argument, index, for_constructor_callback=for_constructor_callback)
+ return idl_type.v8_value_to_local_cpp_value(
+ extended_attributes,
+ v8_value,
+ name,
+ declare_variable=False,
+ use_exception_state=method.returns_promise,
+ for_constructor_callback=for_constructor_callback)
################################################################################
# Auxiliary functions
################################################################################
+
# [NotEnumerable], [Unforgeable]
def property_attributes(interface, method):
extended_attributes = method.extended_attributes
@@ -481,7 +568,8 @@ def argument_set_default_value(argument):
raise Exception('invalid default value for dictionary type')
if idl_type.is_array_or_sequence_type:
if default_value.value != '[]':
- raise Exception('invalid default value for sequence type: %s' % default_value.value)
+ raise Exception('invalid default value for sequence type: %s' %
+ default_value.value)
# Nothing to do when we set an empty sequence as default value, but we
# need to return non-empty value so that we don't generate method calls
# without this argument.
@@ -489,11 +577,14 @@ def argument_set_default_value(argument):
if idl_type.is_union_type:
if argument.default_value.is_null:
if not idl_type.includes_nullable_type:
- raise Exception('invalid default value for union type: null for %s'
- % idl_type.name)
+ raise Exception(
+ 'invalid default value for union type: null for %s' %
+ idl_type.name)
# Union container objects are "null" initially.
return '/* null default value */'
- if isinstance(default_value.value, basestring):
+ if default_value.value == "{}":
+ member_type = idl_type.dictionary_member_type
+ elif isinstance(default_value.value, basestring):
member_type = idl_type.string_member_type
elif isinstance(default_value.value, (int, float)):
member_type = idl_type.numeric_member_type
@@ -502,27 +593,28 @@ def argument_set_default_value(argument):
else:
member_type = None
if member_type is None:
- raise Exception('invalid default value for union type: %r for %s'
- % (default_value.value, idl_type.name))
+ raise Exception('invalid default value for union type: %r for %s' %
+ (default_value.value, idl_type.name))
member_type_name = (member_type.inner_type.name
- if member_type.is_nullable else
- member_type.name)
+ if member_type.is_nullable else member_type.name)
return '%s.Set%s(%s)' % (variable_name, member_type_name,
member_type.literal_cpp_value(default_value))
return '%s = %s' % (variable_name,
idl_type.literal_cpp_value(default_value))
+
IdlArgument.set_default_value = property(argument_set_default_value)
def method_returns_promise(method):
return method.idl_type and method.idl_type.name == 'Promise'
+
IdlOperation.returns_promise = property(method_returns_promise)
def argument_conversion_needs_exception_state(method, argument):
idl_type = argument.idl_type
- return (idl_type.v8_conversion_needs_exception_state or
- argument.is_variadic or
- (method.returns_promise and idl_type.is_string_type))
+ return (idl_type.v8_conversion_needs_exception_state
+ or argument.is_variadic
+ or (method.returns_promise and idl_type.is_string_type))
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 5b7aae6f0fd..a2007d860b9 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/v8_types.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_types.py
@@ -27,7 +27,6 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# pylint: disable=relative-import
-
"""Functions for type handling and type conversion (Blink/C++ <-> V8/JS).
Extends IdlType and IdlUnionType with V8-specific properties, methods, and
@@ -41,6 +40,7 @@ Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
import posixpath
+from idl_types import IdlAnnotatedType
from idl_types import IdlArrayOrSequenceType
from idl_types import IdlNullableType
from idl_types import IdlRecordType
@@ -52,16 +52,13 @@ import v8_attributes # for IdlType.constructor_type_name
from v8_globals import includes
from v8_utilities import binding_header_filename, extended_attribute_value_contains
-
################################################################################
# V8-specific handling of IDL types
################################################################################
NON_WRAPPER_TYPES = frozenset([
- 'Dictionary',
'EventHandler',
'NodeFilter',
- 'SerializedScriptValue',
])
TYPED_ARRAY_TYPES = frozenset([
'Float32Array',
@@ -76,15 +73,15 @@ TYPED_ARRAY_TYPES = frozenset([
'BigInt64Array',
'BigUint64Array',
])
-ARRAY_BUFFER_VIEW_AND_TYPED_ARRAY_TYPES = TYPED_ARRAY_TYPES.union(frozenset([
- 'ArrayBufferView'
-]))
-ARRAY_BUFFER_AND_VIEW_TYPES = TYPED_ARRAY_TYPES.union(frozenset([
- 'ArrayBuffer',
- 'ArrayBufferView',
- 'DataView',
- 'SharedArrayBuffer',
-]))
+ARRAY_BUFFER_VIEW_AND_TYPED_ARRAY_TYPES = TYPED_ARRAY_TYPES.union(
+ frozenset(['ArrayBufferView']))
+ARRAY_BUFFER_AND_VIEW_TYPES = TYPED_ARRAY_TYPES.union(
+ frozenset([
+ 'ArrayBuffer',
+ 'ArrayBufferView',
+ 'DataView',
+ '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.
@@ -105,10 +102,8 @@ IdlType.is_typed_array = property(
lambda self: self.base_type in TYPED_ARRAY_TYPES)
IdlType.is_wrapper_type = property(
- lambda self: (self.is_interface_type and
- not self.is_callback_interface and
- self.base_type not in NON_WRAPPER_TYPES))
-
+ lambda self: (self.is_interface_type and not self.is_callback_interface and self.base_type not in NON_WRAPPER_TYPES)
+)
################################################################################
# C++ types
@@ -129,13 +124,13 @@ CPP_INTEGER_CONVERSION_RULES = {
'unsigned long long': 'uint64_t',
}
CPP_SPECIAL_CONVERSION_RULES = {
- 'Dictionary': 'Dictionary',
'EventHandler': 'EventListener*',
'Promise': 'ScriptPromise',
'ScriptValue': 'ScriptValue',
# FIXME: Eliminate custom bindings for XPathNSResolver http://crbug.com/345529
'XPathNSResolver': 'XPathNSResolver*',
'boolean': 'bool',
+ 'object': 'ScriptValue',
'unrestricted double': 'double',
'unrestricted float': 'float',
}
@@ -154,11 +149,18 @@ def string_resource_mode(idl_type):
treat_null_as = idl_type.extended_attributes.get('TreatNullAs')
if treat_null_as == 'EmptyString':
return 'kTreatNullAsEmptyString'
- raise ValueError('Unknown value for [TreatNullAs]: %s' % treat_null_as)
+ elif treat_null_as:
+ raise ValueError(
+ 'Unknown value for [TreatNullAs]: %s' % treat_null_as)
return ''
-def cpp_type(idl_type, extended_attributes=None, raw_type=False, used_as_rvalue_type=False, used_as_variadic_argument=False, used_in_cpp_sequence=False):
+def cpp_type(idl_type,
+ extended_attributes=None,
+ raw_type=False,
+ used_as_rvalue_type=False,
+ used_as_variadic_argument=False,
+ used_in_cpp_sequence=False):
"""Returns C++ type corresponding to IDL type.
|idl_type| argument is of type IdlType, while return value is a string
@@ -198,9 +200,12 @@ def cpp_type(idl_type, extended_attributes=None, raw_type=False, used_as_rvalue_
# integrated null state that can be distinguished from a present but
# empty dictionary. It's unclear whether this will ever come up in
# real spec WebIDL.
- raise NotImplementedError('Sequences of nullable dictionary, sequence or record types are not yet supported.')
+ raise NotImplementedError(
+ 'Sequences of nullable dictionary, sequence or record types are not yet supported.'
+ )
return 'base::Optional<%s>' % inner_type.cpp_type_args(
- extended_attributes, raw_type, used_as_rvalue_type, used_as_variadic_argument, used_in_cpp_sequence)
+ extended_attributes, raw_type, used_as_rvalue_type,
+ used_as_variadic_argument, used_in_cpp_sequence)
# Array or sequence types
if used_as_variadic_argument:
@@ -208,18 +213,23 @@ def cpp_type(idl_type, extended_attributes=None, raw_type=False, used_as_rvalue_
else:
native_array_element_type = idl_type.native_array_element_type
if native_array_element_type:
- vector_type = cpp_ptr_type('Vector', 'HeapVector', native_array_element_type.is_traceable)
- vector_template_type = cpp_template_type(vector_type, native_array_element_type.cpp_type_args(used_in_cpp_sequence=True))
+ vector_type = cpp_ptr_type('Vector', 'HeapVector',
+ native_array_element_type.is_traceable)
+ vector_template_type = cpp_template_type(
+ vector_type,
+ native_array_element_type.cpp_type_args(used_in_cpp_sequence=True))
if used_as_rvalue_type:
return 'const %s&' % vector_template_type
return vector_template_type
# Record types.
if idl_type.is_record_type:
- vector_type = cpp_ptr_type('Vector', 'HeapVector', idl_type.value_type.is_traceable)
- value_type = idl_type.value_type.cpp_type_args(used_in_cpp_sequence=True)
- vector_template_type = cpp_template_type(vector_type,
- 'std::pair<String, %s>' % value_type)
+ vector_type = cpp_ptr_type('Vector', 'HeapVector',
+ idl_type.value_type.is_traceable)
+ value_type = idl_type.value_type.cpp_type_args(
+ used_in_cpp_sequence=True)
+ vector_template_type = cpp_template_type(
+ vector_type, 'std::pair<String, %s>' % value_type)
if used_as_rvalue_type:
return 'const %s&' % vector_template_type
return vector_template_type
@@ -234,9 +244,9 @@ def cpp_type(idl_type, extended_attributes=None, raw_type=False, used_as_rvalue_
if base_idl_type in CPP_SPECIAL_CONVERSION_RULES:
return CPP_SPECIAL_CONVERSION_RULES[base_idl_type]
- if base_idl_type == 'SerializedScriptValue':
- return 'scoped_refptr<%s>' % base_idl_type
if idl_type.is_string_type:
+ if idl_type.has_string_context:
+ return 'String'
if not raw_type:
return 'const String&' if used_as_rvalue_type else 'String'
return 'V8StringResource<%s>' % string_resource_mode(idl_type)
@@ -244,13 +254,12 @@ def cpp_type(idl_type, extended_attributes=None, raw_type=False, used_as_rvalue_
if base_idl_type == 'ArrayBufferView' and 'FlexibleArrayBufferView' in extended_attributes:
return 'FlexibleArrayBufferView'
if base_idl_type in TYPED_ARRAY_TYPES and 'FlexibleArrayBufferView' in extended_attributes:
- return 'Flexible' + base_idl_type + 'View'
- if base_idl_type in ARRAY_BUFFER_VIEW_AND_TYPED_ARRAY_TYPES:
- if not used_in_cpp_sequence:
- if 'AllowShared' in extended_attributes:
- return cpp_template_type('MaybeShared', idl_type.implemented_as)
- else:
- return cpp_template_type('NotShared', idl_type.implemented_as)
+ return 'Flexible' + base_idl_type
+ if base_idl_type in ARRAY_BUFFER_VIEW_AND_TYPED_ARRAY_TYPES or base_idl_type == 'DataView':
+ if 'AllowShared' in extended_attributes:
+ return cpp_template_type('MaybeShared', idl_type.implemented_as)
+ else:
+ return cpp_template_type('NotShared', idl_type.implemented_as)
if idl_type.is_interface_type or idl_type.is_dictionary:
implemented_as_class = idl_type.implemented_as
if raw_type or not used_in_cpp_sequence:
@@ -267,8 +276,9 @@ def cpp_type(idl_type, extended_attributes=None, raw_type=False, used_as_rvalue_
if idl_type.is_nullable:
return idl_type.inner_type.name
return idl_type.name
- idl_type_name = 'Or'.join(member_cpp_name(member)
- for member in idl_type.member_types)
+
+ idl_type_name = 'Or'.join(
+ member_cpp_name(member) for member in idl_type.member_types)
return 'const %s&' % idl_type_name if used_as_rvalue_type else idl_type_name
if idl_type.is_callback_function:
v8_type_name = 'V8' + base_idl_type
@@ -295,15 +305,16 @@ def cpp_type_initializer(idl_type):
if idl_type.native_array_element_type:
return ''
+ if idl_type.is_explicit_nullable:
+ return ''
if idl_type.is_numeric_type:
return ' = 0'
if base_idl_type == 'boolean':
return ' = false'
- if (base_idl_type in NON_WRAPPER_TYPES or
- base_idl_type in CPP_SPECIAL_CONVERSION_RULES or
- base_idl_type == 'any' or
- idl_type.is_string_type or
- idl_type.is_enum):
+ if (base_idl_type in NON_WRAPPER_TYPES
+ or base_idl_type in CPP_SPECIAL_CONVERSION_RULES
+ or base_idl_type == 'any' or idl_type.is_string_type
+ or idl_type.is_enum):
return ''
return ' = nullptr'
@@ -314,7 +325,6 @@ IdlTypeBase.cpp_type_initializer = property(cpp_type_initializer)
IdlTypeBase.cpp_type_args = cpp_type
IdlUnionType.cpp_type_initializer = ''
-
IdlArrayOrSequenceType.native_array_element_type = property(
lambda self: self.element_type)
@@ -358,9 +368,9 @@ def implemented_as(idl_type):
IdlType.implemented_as = property(implemented_as)
IdlType.set_implemented_as_interfaces = classmethod(
- lambda cls, new_implemented_as_interfaces:
- cls.implemented_as_interfaces.update(new_implemented_as_interfaces))
-
+ lambda cls, new_implemented_as_interfaces: \
+ cls.implemented_as_interfaces.update(new_implemented_as_interfaces)
+)
# [GarbageCollected]
IdlType.garbage_collected_types = set()
@@ -369,8 +379,9 @@ IdlType.is_garbage_collected = property(
lambda self: self.base_type in IdlType.garbage_collected_types)
IdlType.set_garbage_collected_types = classmethod(
- lambda cls, new_garbage_collected_types:
- cls.garbage_collected_types.update(new_garbage_collected_types))
+ lambda cls, new_garbage_collected_types: \
+ cls.garbage_collected_types.update(new_garbage_collected_types)
+)
def is_gc_type(idl_type):
@@ -381,7 +392,9 @@ IdlTypeBase.is_gc_type = property(is_gc_type)
def is_traceable(idl_type):
- return idl_type.is_garbage_collected or idl_type.is_callback_function or idl_type.cpp_type in ('ScriptValue', 'ScriptPromise')
+ return (idl_type.is_garbage_collected or idl_type.is_callback_function
+ or idl_type.cpp_type in ('ScriptValue', 'ScriptPromise'))
+
IdlTypeBase.is_traceable = property(is_traceable)
IdlUnionType.is_traceable = property(lambda self: True)
@@ -392,34 +405,39 @@ IdlRecordType.is_traceable = property(
IdlNullableType.is_traceable = property(
lambda self: self.inner_type.is_traceable)
-
################################################################################
# Includes
################################################################################
INCLUDES_FOR_TYPE = {
- 'object': set(),
- 'ArrayBufferView': set(['bindings/core/v8/v8_array_buffer_view.h',
- 'core/typed_arrays/array_buffer_view_helpers.h',
- 'core/typed_arrays/flexible_array_buffer_view.h']),
- 'Dictionary': set(['bindings/core/v8/dictionary.h']),
- 'EventHandler': set(['bindings/core/v8/js_event_handler.h']),
- 'HTMLCollection': set(['bindings/core/v8/v8_html_collection.h',
- 'core/dom/class_collection.h',
- 'core/dom/tag_collection.h',
- 'core/html/html_collection.h',
- 'core/html/html_table_rows_collection.h',
- 'core/html/forms/html_data_list_options_collection.h',
- 'core/html/forms/html_form_controls_collection.h']),
- 'NodeList': set(['bindings/core/v8/v8_node_list.h',
- 'core/dom/name_node_list.h',
- 'core/dom/node_list.h',
- 'core/dom/static_node_list.h',
- 'core/html/forms/labels_node_list.h']),
- 'Promise': set(['bindings/core/v8/script_promise.h']),
- 'SerializedScriptValue': set(['bindings/core/v8/serialization/serialized_script_value.h',
- 'bindings/core/v8/serialization/serialized_script_value_factory.h']),
- 'ScriptValue': set(['bindings/core/v8/script_value.h']),
+ 'object':
+ set(['bindings/core/v8/script_value.h']),
+ 'ArrayBufferView':
+ set([
+ 'bindings/core/v8/v8_array_buffer_view.h',
+ 'core/typed_arrays/array_buffer_view_helpers.h',
+ 'core/typed_arrays/flexible_array_buffer_view.h'
+ ]),
+ 'EventHandler':
+ set(['bindings/core/v8/js_event_handler.h']),
+ 'HTMLCollection':
+ set([
+ 'bindings/core/v8/v8_html_collection.h', 'core/dom/class_collection.h',
+ 'core/dom/tag_collection.h', 'core/html/html_collection.h',
+ 'core/html/html_table_rows_collection.h',
+ 'core/html/forms/html_data_list_options_collection.h',
+ 'core/html/forms/html_form_controls_collection.h'
+ ]),
+ 'NodeList':
+ set([
+ 'bindings/core/v8/v8_node_list.h', 'core/dom/name_node_list.h',
+ 'core/dom/node_list.h', 'core/dom/static_node_list.h',
+ 'core/html/forms/labels_node_list.h'
+ ]),
+ 'Promise':
+ set(['bindings/core/v8/script_promise.h']),
+ 'ScriptValue':
+ set(['bindings/core/v8/script_value.h']),
}
@@ -433,11 +451,15 @@ def includes_for_type(idl_type, extended_attributes=None):
return INCLUDES_FOR_TYPE[base_idl_type]
if base_idl_type in TYPED_ARRAY_TYPES:
return INCLUDES_FOR_TYPE['ArrayBufferView'].union(
- set(['bindings/%s/v8/%s' % (component_dir[base_idl_type], binding_header_filename(base_idl_type))])
- )
+ set([
+ 'bindings/%s/v8/%s' % (component_dir[base_idl_type],
+ binding_header_filename(base_idl_type))
+ ]))
if idl_type.is_basic_type:
- return set(['bindings/core/v8/idl_types.h',
- 'bindings/core/v8/native_value_traits_impl.h'])
+ return set([
+ 'bindings/core/v8/idl_types.h',
+ 'bindings/core/v8/native_value_traits_impl.h'
+ ])
if base_idl_type.endswith('ConstructorConstructor'):
# FIXME: rename to NamedConstructor
# FIXME: replace with a [NamedConstructorAttribute] extended attribute
@@ -445,41 +467,55 @@ def includes_for_type(idl_type, extended_attributes=None):
# and these do not have header files, as they are part of the generated
# bindings for the interface
return set()
- if (base_idl_type.endswith('Constructor') and
- base_idl_type not in _CALLBACK_CONSTRUCTORS):
+ if (base_idl_type.endswith('Constructor')
+ and base_idl_type not in _CALLBACK_CONSTRUCTORS):
# FIXME: replace with a [ConstructorAttribute] extended attribute
base_idl_type = idl_type.constructor_type_name
if idl_type.is_custom_callback_function:
return set()
if idl_type.is_callback_function:
component = IdlType.callback_functions[base_idl_type]['component_dir']
- return set(['bindings/%s/v8/%s' % (component, binding_header_filename(base_idl_type))])
+ return set([
+ 'bindings/%s/v8/%s' % (component,
+ binding_header_filename(base_idl_type))
+ ])
if base_idl_type not in component_dir:
return set()
- return set(['bindings/%s/v8/%s' % (component_dir[base_idl_type],
- binding_header_filename(base_idl_type))])
+ return set([
+ 'bindings/%s/v8/%s' % (component_dir[base_idl_type],
+ binding_header_filename(base_idl_type))
+ ])
+
IdlType.includes_for_type = includes_for_type
def includes_for_union_type(idl_type, extended_attributes=None):
- return set.union(*[member_type.includes_for_type(extended_attributes)
- for member_type in idl_type.member_types])
+ return set.union(*[
+ member_type.includes_for_type(extended_attributes)
+ for member_type in idl_type.member_types
+ ])
+
IdlUnionType.includes_for_type = includes_for_union_type
def includes_for_array_or_sequence_type(idl_type, extended_attributes=None):
- return set.union(set(['bindings/core/v8/idl_types.h',
- 'bindings/core/v8/native_value_traits_impl.h']),
- idl_type.element_type.includes_for_type(extended_attributes))
+ return set.union(
+ set([
+ 'bindings/core/v8/idl_types.h',
+ 'bindings/core/v8/native_value_traits_impl.h'
+ ]), idl_type.element_type.includes_for_type(extended_attributes))
+
IdlArrayOrSequenceType.includes_for_type = includes_for_array_or_sequence_type
def includes_for_record_type(idl_type, extended_attributes=None):
- return set.union(idl_type.key_type.includes_for_type(extended_attributes),
- idl_type.value_type.includes_for_type(extended_attributes))
+ return set.union(
+ idl_type.key_type.includes_for_type(extended_attributes),
+ idl_type.value_type.includes_for_type(extended_attributes))
+
IdlRecordType.includes_for_type = includes_for_record_type
@@ -487,6 +523,7 @@ IdlRecordType.includes_for_type = includes_for_record_type
def add_includes_for_type(idl_type, extended_attributes=None):
includes.update(idl_type.includes_for_type(extended_attributes))
+
IdlTypeBase.add_includes_for_type = add_includes_for_type
@@ -504,8 +541,8 @@ def impl_includes_for_type(idl_type, interfaces_info):
idl_type = idl_type.preprocessed_type
native_array_element_type = idl_type.native_array_element_type
if native_array_element_type:
- includes_for_type.update(impl_includes_for_type(
- native_array_element_type, interfaces_info))
+ includes_for_type.update(
+ impl_includes_for_type(native_array_element_type, interfaces_info))
includes_for_type.add('platform/wtf/vector.h')
base_idl_type = idl_type.base_type
@@ -513,24 +550,31 @@ def impl_includes_for_type(idl_type, interfaces_info):
includes_for_type.add('platform/wtf/text/wtf_string.h')
if idl_type.is_callback_function:
component = IdlType.callback_functions[base_idl_type]['component_dir']
- return set(['bindings/%s/v8/%s' % (component, binding_header_filename(base_idl_type))])
+ return set([
+ 'bindings/%s/v8/%s' % (component,
+ binding_header_filename(base_idl_type))
+ ])
if base_idl_type in interfaces_info:
interface_info = interfaces_info[base_idl_type]
includes_for_type.add(interface_info['include_path'])
if base_idl_type in INCLUDES_FOR_TYPE:
includes_for_type.update(INCLUDES_FOR_TYPE[base_idl_type])
if idl_type.is_array_buffer_view_or_typed_array:
- return set(['core/typed_arrays/dom_typed_array.h',
- 'core/typed_arrays/array_buffer_view_helpers.h'])
+ return set([
+ 'core/typed_arrays/dom_typed_array.h',
+ 'core/typed_arrays/array_buffer_view_helpers.h'
+ ])
return includes_for_type
def impl_includes_for_type_union(idl_type, interfaces_info):
includes_for_type = set()
for member_type in idl_type.member_types:
- includes_for_type.update(member_type.impl_includes_for_type(interfaces_info))
+ includes_for_type.update(
+ member_type.impl_includes_for_type(interfaces_info))
return includes_for_type
+
IdlTypeBase.impl_includes_for_type = impl_includes_for_type
IdlUnionType.impl_includes_for_type = impl_includes_for_type_union
@@ -549,7 +593,6 @@ def impl_forward_declaration_name(idl_type):
IdlTypeBase.impl_forward_declaration_name = property(
impl_forward_declaration_name)
-
component_dir = {}
@@ -566,49 +609,55 @@ def set_component_dirs(new_component_dirs):
# to introduce any performance regressions.
V8_VALUE_TO_CPP_VALUE = {
# Basic
- 'DOMString': '{v8_value}',
+ 'DOMString':
+ '{v8_value}',
# Interface types
- 'FlexibleArrayBufferView': 'ToFlexibleArrayBufferView({isolate}, {v8_value}, {variable_name}, allocateFlexibleArrayBufferViewStorage({v8_value}))',
- 'Promise': 'ScriptPromise::Cast(ScriptState::Current({isolate}), {v8_value})',
- 'ScriptValue': 'ScriptValue({isolate}, {v8_value})',
- 'Window': 'ToDOMWindow({isolate}, {v8_value})',
- 'XPathNSResolver': 'ToXPathNSResolver(ScriptState::Current({isolate}), {v8_value})',
+ 'FlexibleArrayBufferView':
+ 'ToFlexibleArrayBufferView({isolate}, {v8_value}, {variable_name})',
+ 'Promise':
+ 'ScriptPromise::Cast(ScriptState::Current({isolate}), {v8_value})',
+ 'ScriptValue':
+ 'ScriptValue({isolate}, {v8_value})',
+ 'Window':
+ 'ToDOMWindow({isolate}, {v8_value})',
+ 'XPathNSResolver':
+ 'ToXPathNSResolver(ScriptState::Current({isolate}), {v8_value})',
}
def v8_conversion_needs_exception_state(idl_type):
- return (idl_type.is_numeric_type or
- idl_type.is_enum or
- idl_type.is_dictionary or
- idl_type.is_array_buffer_view_or_typed_array or
- idl_type.name in ('Boolean', 'ByteString', 'Dictionary', 'USVString', 'SerializedScriptValue'))
+ return (idl_type.is_numeric_type or idl_type.is_enum
+ or idl_type.is_dictionary
+ or idl_type.is_array_buffer_view_or_typed_array
+ or idl_type.has_string_context or
+ idl_type.name in ('Boolean', 'ByteString', 'Object', 'USVString'))
+
-IdlType.v8_conversion_needs_exception_state = property(v8_conversion_needs_exception_state)
+IdlType.v8_conversion_needs_exception_state = property(
+ v8_conversion_needs_exception_state)
+IdlAnnotatedType.v8_conversion_needs_exception_state = property(
+ v8_conversion_needs_exception_state)
IdlArrayOrSequenceType.v8_conversion_needs_exception_state = True
IdlRecordType.v8_conversion_needs_exception_state = True
IdlUnionType.v8_conversion_needs_exception_state = True
-
-TRIVIAL_CONVERSIONS = frozenset([
- 'any',
- 'boolean',
- 'Dictionary',
- 'NodeFilter',
- 'XPathNSResolver',
- 'Promise'
-])
+TRIVIAL_CONVERSIONS = frozenset(
+ ['any', 'boolean', 'NodeFilter', 'XPathNSResolver', 'Promise'])
def v8_conversion_is_trivial(idl_type):
# The conversion is a simple expression that returns the converted value and
# cannot raise an exception.
- return (idl_type.base_type in TRIVIAL_CONVERSIONS or
- idl_type.is_wrapper_type)
+ return (idl_type.base_type in TRIVIAL_CONVERSIONS
+ or idl_type.is_wrapper_type)
+
IdlType.v8_conversion_is_trivial = property(v8_conversion_is_trivial)
-def native_value_traits_type_name(idl_type, extended_attributes, in_sequence_or_record=False):
+def native_value_traits_type_name(idl_type,
+ extended_attributes,
+ in_sequence_or_record=False):
idl_type = idl_type.preprocessed_type
if idl_type.is_string_type:
@@ -617,24 +666,25 @@ def native_value_traits_type_name(idl_type, extended_attributes, in_sequence_or_
# attribute and nullable string types.
name = 'IDL%s' % idl_type.name
elif idl_type.is_nullable:
- inner_type = native_value_traits_type_name(idl_type.inner_type, extended_attributes)
- # IDLNullable is only required for sequences and such.
- # The IDL compiler already has special cases for nullable operation
+ inner_type = idl_type.inner_type
+ inner_type_nvt_type = native_value_traits_type_name(
+ inner_type, extended_attributes)
+ # The IDL compiler has special cases to handle some nullable types in operation
# parameters, dictionary fields, etc.
- if in_sequence_or_record:
- name = 'IDLNullable<%s>' % native_value_traits_type_name(idl_type.inner_type,
- extended_attributes)
+ if in_sequence_or_record or inner_type.name == 'Object':
+ name = 'IDLNullable<%s>' % inner_type_nvt_type
else:
- name = inner_type
+ name = inner_type_nvt_type
elif idl_type.native_array_element_type:
- name = 'IDLSequence<%s>' % native_value_traits_type_name(idl_type.native_array_element_type,
- extended_attributes, True)
+ name = 'IDLSequence<%s>' % native_value_traits_type_name(
+ idl_type.native_array_element_type, extended_attributes, True)
elif idl_type.is_record_type:
- name = 'IDLRecord<%s, %s>' % (native_value_traits_type_name(idl_type.key_type,
- extended_attributes),
- native_value_traits_type_name(idl_type.value_type,
- extended_attributes, True))
- elif idl_type.is_basic_type or idl_type.name == 'Promise':
+ name = 'IDLRecord<%s, %s>' % (native_value_traits_type_name(
+ idl_type.key_type, extended_attributes),
+ native_value_traits_type_name(
+ idl_type.value_type,
+ extended_attributes, True))
+ elif idl_type.is_basic_type or idl_type.name in ['Object', 'Promise']:
name = 'IDL%s' % idl_type.name
elif idl_type.implemented_as is not None:
name = idl_type.implemented_as
@@ -643,7 +693,8 @@ def native_value_traits_type_name(idl_type, extended_attributes, in_sequence_or_
return name
-def v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, variable_name, isolate):
+def v8_value_to_cpp_value(idl_type, extended_attributes, v8_value,
+ variable_name, isolate, for_constructor_callback):
if idl_type.name == 'void':
return ''
@@ -653,45 +704,58 @@ def v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, variable_name
if 'FlexibleArrayBufferView' in extended_attributes:
if base_idl_type not in ARRAY_BUFFER_VIEW_AND_TYPED_ARRAY_TYPES:
- raise ValueError('Unrecognized base type for extended attribute "FlexibleArrayBufferView": %s' % (idl_type.base_type))
+ raise ValueError(
+ 'Unrecognized base type for extended attribute "FlexibleArrayBufferView": %s'
+ % (idl_type.base_type))
if 'AllowShared' not in extended_attributes:
- raise ValueError('"FlexibleArrayBufferView" extended attribute requires "AllowShared" on %s' % (idl_type.base_type))
+ raise ValueError(
+ '"FlexibleArrayBufferView" extended attribute requires "AllowShared" on %s'
+ % (idl_type.base_type))
base_idl_type = 'FlexibleArrayBufferView'
if 'AllowShared' in extended_attributes and not idl_type.is_array_buffer_view_or_typed_array:
- raise ValueError('Unrecognized base type for extended attribute "AllowShared": %s' % (idl_type.base_type))
+ raise ValueError(
+ 'Unrecognized base type for extended attribute "AllowShared": %s' %
+ (idl_type.base_type))
if idl_type.is_integer_type:
arguments = ', '.join([v8_value, 'exception_state'])
- elif base_idl_type == 'SerializedScriptValue':
- arguments = ', '.join([
- v8_value,
- 'SerializedScriptValue::SerializeOptions(SerializedScriptValue::kNotForStorage)',
- 'exception_state'])
elif idl_type.v8_conversion_needs_exception_state:
arguments = ', '.join([v8_value, 'exception_state'])
else:
arguments = v8_value
- if base_idl_type in V8_VALUE_TO_CPP_VALUE:
+ if idl_type.has_string_context:
+ execution_context = 'bindings::ExecutionContextFromV8Wrappable(impl)'
+ if for_constructor_callback:
+ execution_context = 'CurrentExecutionContext(info.GetIsolate())'
+ cpp_expression_format = 'NativeValueTraits<IDL%s>::NativeValue(%s, %s, exception_state, %s)' % (
+ idl_type.name, isolate, v8_value, execution_context)
+ elif base_idl_type in V8_VALUE_TO_CPP_VALUE:
cpp_expression_format = V8_VALUE_TO_CPP_VALUE[base_idl_type]
elif idl_type.name == 'ArrayBuffer':
cpp_expression_format = (
'{v8_value}->Is{idl_type}() ? '
- 'V8{idl_type}::ToImpl(v8::Local<v8::{idl_type}>::Cast({v8_value})) : 0')
- elif idl_type.is_array_buffer_view_or_typed_array:
- this_cpp_type = idl_type.cpp_type_args(extended_attributes=extended_attributes)
+ 'V8{idl_type}::ToImpl(v8::Local<v8::{idl_type}>::Cast({v8_value})) : 0'
+ )
+ elif idl_type.is_array_buffer_view_or_typed_array or base_idl_type == 'DataView':
+ this_cpp_type = idl_type.cpp_type_args(
+ extended_attributes=extended_attributes)
if 'AllowShared' in extended_attributes:
- cpp_expression_format = ('ToMaybeShared<%s>({isolate}, {v8_value}, exception_state)' % this_cpp_type)
+ cpp_expression_format = (
+ 'ToMaybeShared<%s>({isolate}, {v8_value}, exception_state)' %
+ this_cpp_type)
else:
- cpp_expression_format = ('ToNotShared<%s>({isolate}, {v8_value}, exception_state)' % this_cpp_type)
-
+ cpp_expression_format = (
+ 'ToNotShared<%s>({isolate}, {v8_value}, exception_state)' %
+ this_cpp_type)
elif idl_type.is_union_type:
nullable = 'UnionTypeConversionMode::kNullable' if idl_type.includes_nullable_type \
else 'UnionTypeConversionMode::kNotNullable'
# We need to consider the moving of the null through the union in order
# to generate the correct V8* class name.
- this_cpp_type = idl_type.cpp_type_args(extended_attributes=extended_attributes)
+ this_cpp_type = idl_type.cpp_type_args(
+ extended_attributes=extended_attributes)
cpp_expression_format = '%s::ToImpl({isolate}, {v8_value}, {variable_name}, %s, exception_state)' % \
(v8_type(this_cpp_type), nullable)
elif idl_type.use_output_parameter_for_result:
@@ -701,26 +765,47 @@ def v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, variable_name
elif idl_type.v8_conversion_needs_exception_state:
# Effectively, this if branch means everything with v8_conversion_needs_exception_state == True
# except for unions and dictionary interfaces.
- base_idl_type = native_value_traits_type_name(idl_type, extended_attributes)
+ base_idl_type = native_value_traits_type_name(idl_type,
+ extended_attributes)
cpp_expression_format = (
- 'NativeValueTraits<{idl_type}>::NativeValue({isolate}, {arguments})')
+ 'NativeValueTraits<{idl_type}>::NativeValue({isolate}, {arguments})'
+ )
else:
cpp_expression_format = (
'V8{idl_type}::ToImplWithTypeCheck({isolate}, {v8_value})')
- return cpp_expression_format.format(arguments=arguments, idl_type=base_idl_type, v8_value=v8_value, variable_name=variable_name, isolate=isolate)
+ return cpp_expression_format.format(
+ arguments=arguments,
+ idl_type=base_idl_type,
+ v8_value=v8_value,
+ variable_name=variable_name,
+ isolate=isolate)
# FIXME: this function should be refactored, as this takes too many flags.
-def v8_value_to_local_cpp_value(idl_type, extended_attributes, v8_value, variable_name, declare_variable=True,
- isolate='info.GetIsolate()', bailout_return_value=None, use_exception_state=False,
- code_generation_target=None):
+def v8_value_to_local_cpp_value(idl_type,
+ extended_attributes,
+ v8_value,
+ variable_name,
+ declare_variable=True,
+ isolate='info.GetIsolate()',
+ bailout_return_value=None,
+ use_exception_state=False,
+ code_generation_target=None,
+ for_constructor_callback=False):
"""Returns an expression that converts a V8 value to a C++ value and stores it as a local value."""
- this_cpp_type = idl_type.cpp_type_args(extended_attributes=extended_attributes, raw_type=True)
+ this_cpp_type = idl_type.cpp_type_args(
+ extended_attributes=extended_attributes, raw_type=True)
idl_type = idl_type.preprocessed_type
- cpp_value = v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, variable_name, isolate)
+ cpp_value = v8_value_to_cpp_value(
+ idl_type,
+ extended_attributes,
+ v8_value,
+ variable_name,
+ isolate,
+ for_constructor_callback=for_constructor_callback)
# Optional expression that returns a value to be assigned to the local variable.
assign_expression = None
@@ -734,7 +819,9 @@ def v8_value_to_local_cpp_value(idl_type, extended_attributes, v8_value, variabl
if 'FlexibleArrayBufferView' in extended_attributes:
if idl_type.base_type not in ARRAY_BUFFER_VIEW_AND_TYPED_ARRAY_TYPES:
- raise ValueError('Unrecognized base type for extended attribute "FlexibleArrayBufferView": %s' % (idl_type.base_type))
+ raise ValueError(
+ 'Unrecognized base type for extended attribute "FlexibleArrayBufferView": %s'
+ % (idl_type.base_type))
set_expression = cpp_value
elif idl_type.is_string_type or idl_type.v8_conversion_needs_exception_state:
# Types for which conversion can fail and that need error handling.
@@ -756,7 +843,8 @@ def v8_value_to_local_cpp_value(idl_type, extended_attributes, v8_value, variabl
check_expression = '!%s.Prepare()' % variable_name
elif not idl_type.v8_conversion_is_trivial and not idl_type.is_callback_function:
return {
- 'error_message': 'no V8 -> C++ conversion for IDL type: %s' % idl_type.name
+ 'error_message':
+ 'no V8 -> C++ conversion for IDL type: %s' % idl_type.name
}
else:
assign_expression = cpp_value
@@ -766,10 +854,12 @@ def v8_value_to_local_cpp_value(idl_type, extended_attributes, v8_value, variabl
if (idl_type.is_explicit_nullable
and code_generation_target == 'attribute_set'):
- assign_expression = (
- "is_null "
- "? {cpp_type}() "
- ": {expr}".format(cpp_type=this_cpp_type, expr=assign_expression))
+ this_cpp_type = cpp_template_type('base::Optional', this_cpp_type)
+ expr = '{cpp_type}({expr})'.format(
+ cpp_type=this_cpp_type, expr=assign_expression)
+ assign_expression = ("is_null "
+ "? base::nullopt "
+ ": {expr}".format(expr=expr))
return {
'assign_expression': assign_expression,
@@ -791,25 +881,28 @@ def use_output_parameter_for_result(idl_type):
"""
return idl_type.is_union_type
-IdlTypeBase.use_output_parameter_for_result = property(use_output_parameter_for_result)
+IdlTypeBase.use_output_parameter_for_result = property(
+ use_output_parameter_for_result)
################################################################################
# C++ -> V8
################################################################################
+
def preprocess_idl_type(idl_type):
if idl_type.is_nullable:
return IdlNullableType(idl_type.inner_type.preprocessed_type)
if idl_type.is_enum:
# Enumerations are internally DOMStrings
return IdlType('DOMString')
- if idl_type.base_type in ['any', 'object'] or idl_type.is_custom_callback_function:
+ if idl_type.base_type == 'any' or idl_type.is_custom_callback_function:
return IdlType('ScriptValue')
if idl_type.is_callback_function:
return idl_type
return idl_type
+
IdlTypeBase.preprocessed_type = property(preprocess_idl_type)
@@ -830,8 +923,8 @@ def preprocess_idl_type_and_value(idl_type, cpp_value, extended_attributes):
# [0, 2^31). When a value isn't in this range, a default value (or 0)
# should be returned instead.
extended_attributes = extended_attributes or {}
- if ('Reflect' in extended_attributes and
- idl_type.base_type in ['unsigned long', 'unsigned short']):
+ if ('Reflect' in extended_attributes
+ and idl_type.base_type in ['unsigned long', 'unsigned short']):
cpp_value = cpp_value.replace('GetUnsignedIntegralAttribute',
'GetIntegralAttribute')
cpp_value = 'std::max(0, static_cast<int>(%s))' % cpp_value
@@ -873,11 +966,10 @@ def v8_conversion_type(idl_type, extended_attributes):
if idl_type.is_nullable:
return 'StringOrNull'
return base_idl_type
- if idl_type.is_basic_type or base_idl_type == 'ScriptValue':
+ if idl_type.is_basic_type:
return base_idl_type
- # Generic dictionary type
- if base_idl_type == 'Dictionary':
- return 'Dictionary'
+ if base_idl_type in ['object', 'ScriptValue']:
+ return 'ScriptValue'
# Data type with potential additional includes
if base_idl_type in V8_SET_RETURN_VALUE: # Special V8SetReturnValue treatment
@@ -886,44 +978,68 @@ def v8_conversion_type(idl_type, extended_attributes):
# Pointer type
return 'DOMWrapper'
-IdlTypeBase.v8_conversion_type = v8_conversion_type
+IdlTypeBase.v8_conversion_type = v8_conversion_type
V8_SET_RETURN_VALUE = {
- 'boolean': 'V8SetReturnValueBool(info, {cpp_value})',
- 'DOMString': 'V8SetReturnValueString(info, {cpp_value}, info.GetIsolate())',
- 'ByteString': 'V8SetReturnValueString(info, {cpp_value}, info.GetIsolate())',
- 'USVString': 'V8SetReturnValueString(info, {cpp_value}, info.GetIsolate())',
- 'StringOrNull': 'V8SetReturnValueStringOrNull(info, {cpp_value}, info.GetIsolate())',
- 'void': '',
+ 'boolean':
+ 'V8SetReturnValueBool(info, {cpp_value})',
+ 'DOMString':
+ 'V8SetReturnValueString(info, {cpp_value}, info.GetIsolate())',
+ 'ByteString':
+ 'V8SetReturnValueString(info, {cpp_value}, info.GetIsolate())',
+ 'USVString':
+ 'V8SetReturnValueString(info, {cpp_value}, info.GetIsolate())',
+ 'StringOrNull':
+ 'V8SetReturnValueStringOrNull(info, {cpp_value}, info.GetIsolate())',
+ 'void':
+ '',
# All the int types below are converted to (u)int32_t in the V8SetReturnValue{Int,Unsigned}() calls.
# The 64-bit int types have already been converted to double when V8_SET_RETURN_VALUE is used, so they are not
# listed here.
- 'int8_t': 'V8SetReturnValueInt(info, {cpp_value})',
- 'int16_t': 'V8SetReturnValueInt(info, {cpp_value})',
- 'int32_t': 'V8SetReturnValueInt(info, {cpp_value})',
- 'uint8_t': 'V8SetReturnValueUnsigned(info, {cpp_value})',
- 'uint16_t': 'V8SetReturnValueUnsigned(info, {cpp_value})',
- 'uint32_t': 'V8SetReturnValueUnsigned(info, {cpp_value})',
+ 'int8_t':
+ 'V8SetReturnValueInt(info, {cpp_value})',
+ 'int16_t':
+ 'V8SetReturnValueInt(info, {cpp_value})',
+ 'int32_t':
+ 'V8SetReturnValueInt(info, {cpp_value})',
+ 'uint8_t':
+ 'V8SetReturnValueUnsigned(info, {cpp_value})',
+ 'uint16_t':
+ 'V8SetReturnValueUnsigned(info, {cpp_value})',
+ 'uint32_t':
+ 'V8SetReturnValueUnsigned(info, {cpp_value})',
# No special V8SetReturnValue* function (set value directly)
- 'float': 'V8SetReturnValue(info, {cpp_value})',
- 'unrestricted float': 'V8SetReturnValue(info, {cpp_value})',
- 'double': 'V8SetReturnValue(info, {cpp_value})',
- 'unrestricted double': 'V8SetReturnValue(info, {cpp_value})',
+ 'float':
+ 'V8SetReturnValue(info, {cpp_value})',
+ 'unrestricted float':
+ 'V8SetReturnValue(info, {cpp_value})',
+ 'double':
+ 'V8SetReturnValue(info, {cpp_value})',
+ 'unrestricted double':
+ 'V8SetReturnValue(info, {cpp_value})',
# No special V8SetReturnValue* function, but instead convert value to V8
# and then use general V8SetReturnValue.
- 'sequence': 'V8SetReturnValue(info, {cpp_value})',
- 'FrozenArray': 'V8SetReturnValue(info, {cpp_value})',
- 'EventHandler': 'V8SetReturnValue(info, {cpp_value})',
- 'NodeFilter': 'V8SetReturnValue(info, {cpp_value})',
- 'ScriptValue': 'V8SetReturnValue(info, {cpp_value})',
- 'SerializedScriptValue': 'V8SetReturnValue(info, {cpp_value})',
+ 'sequence':
+ 'V8SetReturnValue(info, {cpp_value})',
+ 'FrozenArray':
+ 'V8SetReturnValue(info, {cpp_value})',
+ 'EventHandler':
+ 'V8SetReturnValue(info, {cpp_value})',
+ 'NodeFilter':
+ 'V8SetReturnValue(info, {cpp_value})',
+ 'ScriptValue':
+ 'V8SetReturnValue(info, {cpp_value})',
# Records.
- 'Record': 'V8SetReturnValue(info, ToV8({cpp_value}, info.Holder(), info.GetIsolate()))',
+ 'Record':
+ 'V8SetReturnValue(info, ToV8({cpp_value}, info.Holder(), info.GetIsolate()))',
# DOMWrapper
- 'DOMWrapperForMainWorld': 'V8SetReturnValueForMainWorld(info, {cpp_value})',
- 'DOMWrapperFast': 'V8SetReturnValueFast(info, {cpp_value}, {script_wrappable})',
- 'DOMWrapperDefault': 'V8SetReturnValue(info, {cpp_value})',
+ 'DOMWrapperForMainWorld':
+ 'V8SetReturnValueForMainWorld(info, {cpp_value})',
+ 'DOMWrapperFast':
+ 'V8SetReturnValueFast(info, {cpp_value}, {script_wrappable})',
+ 'DOMWrapperDefault':
+ 'V8SetReturnValue(info, {cpp_value})',
# If [CheckSecurity=ReturnValue] is specified, the returned object must be
# wrapped in its own realm, which can be different from the realm of the
# receiver object.
@@ -935,34 +1051,42 @@ V8_SET_RETURN_VALUE = {
# contentWindow(). Note that DOMWindow* has its own realm and there is no
# need to pass |creationContext| in for ToV8(DOMWindow*).
# Window.frameElement is implemented with [Custom].
- 'DOMWrapperAcrossContext': (
- 'V8SetReturnValue(info, ToV8({cpp_value}, ' +
- 'ToV8(impl->contentWindow(), v8::Local<v8::Object>(), ' +
- 'info.GetIsolate()).As<v8::Object>(), info.GetIsolate()))'),
+ 'DOMWrapperAcrossContext':
+ ('V8SetReturnValue(info, ToV8({cpp_value}, ' +
+ 'ToV8(impl->contentWindow(), v8::Local<v8::Object>(), ' +
+ 'info.GetIsolate()).As<v8::Object>(), info.GetIsolate()))'),
# Note that static attributes and operations do not check whether |this| is
# an instance of the interface nor |this|'s creation context is the same as
# the current context. So we must always use the current context as the
# creation context of the DOM wrapper for the return value.
- 'DOMWrapperStatic': 'V8SetReturnValue(info, {cpp_value}, info.GetIsolate()->GetCurrentContext()->Global())',
- # Generic dictionary type
- 'Dictionary': 'V8SetReturnValue(info, {cpp_value})',
- 'DictionaryStatic': '#error not implemented yet',
+ 'DOMWrapperStatic':
+ 'V8SetReturnValue(info, {cpp_value}, info.GetIsolate()->GetCurrentContext()->Global())',
# Nullable dictionaries
- 'NullableDictionary': 'V8SetReturnValue(info, result)',
- 'NullableDictionaryStatic': 'V8SetReturnValue(info, result, info.GetIsolate()->GetCurrentContext()->Global())',
+ 'NullableDictionary':
+ 'V8SetReturnValue(info, result)',
+ 'NullableDictionaryStatic':
+ 'V8SetReturnValue(info, result, info.GetIsolate()->GetCurrentContext()->Global())',
# Union types or dictionaries
- 'DictionaryOrUnion': 'V8SetReturnValue(info, result)',
- 'DictionaryOrUnionStatic': 'V8SetReturnValue(info, result, info.GetIsolate()->GetCurrentContext()->Global())',
+ 'DictionaryOrUnion':
+ 'V8SetReturnValue(info, result)',
+ 'DictionaryOrUnionStatic':
+ 'V8SetReturnValue(info, result, info.GetIsolate()->GetCurrentContext()->Global())',
}
-def v8_set_return_value(idl_type, cpp_value, extended_attributes=None, script_wrappable='', for_main_world=False, is_static=False):
+def v8_set_return_value(idl_type,
+ cpp_value,
+ extended_attributes=None,
+ script_wrappable='',
+ for_main_world=False,
+ is_static=False):
"""Returns a statement that converts a C++ value to a V8 value and sets it as a return value.
"""
+
def dom_wrapper_conversion_type():
- if ('CheckSecurity' in extended_attributes and
- extended_attribute_value_contains(
+ if ('CheckSecurity' in extended_attributes
+ and extended_attribute_value_contains(
extended_attributes['CheckSecurity'], 'ReturnValue')):
return 'DOMWrapperAcrossContext'
if is_static:
@@ -973,59 +1097,81 @@ def v8_set_return_value(idl_type, cpp_value, extended_attributes=None, script_wr
return 'DOMWrapperForMainWorld'
return 'DOMWrapperFast'
- idl_type, cpp_value = preprocess_idl_type_and_value(idl_type, cpp_value, extended_attributes)
+ idl_type, cpp_value = preprocess_idl_type_and_value(
+ idl_type, cpp_value, extended_attributes)
this_v8_conversion_type = idl_type.v8_conversion_type(extended_attributes)
# SetReturn-specific overrides
if this_v8_conversion_type in ('EventHandler', 'NodeFilter', 'ScriptValue',
- 'SerializedScriptValue', 'sequence', 'FrozenArray'):
+ 'sequence', 'FrozenArray'):
# Convert value to V8 and then use general V8SetReturnValue
- cpp_value = idl_type.cpp_value_to_v8_value(cpp_value, extended_attributes=extended_attributes)
+ cpp_value = idl_type.cpp_value_to_v8_value(
+ cpp_value, extended_attributes=extended_attributes)
if this_v8_conversion_type == 'DOMWrapper':
this_v8_conversion_type = dom_wrapper_conversion_type()
- if is_static and this_v8_conversion_type in ('Dictionary', 'NullableDictionary', 'DictionaryOrUnion'):
+ if is_static and this_v8_conversion_type in ('NullableDictionary',
+ 'DictionaryOrUnion'):
this_v8_conversion_type += 'Static'
format_string = V8_SET_RETURN_VALUE[this_v8_conversion_type]
- statement = format_string.format(cpp_value=cpp_value, script_wrappable=script_wrappable)
+ statement = format_string.format(
+ cpp_value=cpp_value, script_wrappable=script_wrappable)
return statement
IdlTypeBase.v8_set_return_value = v8_set_return_value
-
CPP_VALUE_TO_V8_VALUE = {
# Built-in types
- 'DOMString': 'V8String({isolate}, {cpp_value})',
- 'ByteString': 'V8String({isolate}, {cpp_value})',
- 'USVString': 'V8String({isolate}, {cpp_value})',
- 'boolean': 'v8::Boolean::New({isolate}, {cpp_value})',
+ 'DOMString':
+ 'V8String({isolate}, {cpp_value})',
+ 'ByteString':
+ 'V8String({isolate}, {cpp_value})',
+ 'USVString':
+ 'V8String({isolate}, {cpp_value})',
+ 'boolean':
+ 'v8::Boolean::New({isolate}, {cpp_value})',
# All the int types below are converted to (u)int32_t in the v8::Integer::New*() calls.
# The 64-bit int types have already been converted to double when CPP_VALUE_TO_V8_VALUE is used, so they are not
# listed here.
- 'int8_t': 'v8::Integer::New({isolate}, {cpp_value})',
- 'int16_t': 'v8::Integer::New({isolate}, {cpp_value})',
- 'int32_t': 'v8::Integer::New({isolate}, {cpp_value})',
- 'uint8_t': 'v8::Integer::NewFromUnsigned({isolate}, {cpp_value})',
- 'uint16_t': 'v8::Integer::NewFromUnsigned({isolate}, {cpp_value})',
- 'uint32_t': 'v8::Integer::NewFromUnsigned({isolate}, {cpp_value})',
- 'float': 'v8::Number::New({isolate}, {cpp_value})',
- 'unrestricted float': 'v8::Number::New({isolate}, {cpp_value})',
- 'double': 'v8::Number::New({isolate}, {cpp_value})',
- 'unrestricted double': 'v8::Number::New({isolate}, {cpp_value})',
- 'StringOrNull': ('({cpp_value}.IsNull() ? ' +
- 'v8::Null({isolate}).As<v8::Value>() : ' +
- 'V8String({isolate}, {cpp_value}).As<v8::Value>())'),
+ 'int8_t':
+ 'v8::Integer::New({isolate}, {cpp_value})',
+ 'int16_t':
+ 'v8::Integer::New({isolate}, {cpp_value})',
+ 'int32_t':
+ 'v8::Integer::New({isolate}, {cpp_value})',
+ 'uint8_t':
+ 'v8::Integer::NewFromUnsigned({isolate}, {cpp_value})',
+ 'uint16_t':
+ 'v8::Integer::NewFromUnsigned({isolate}, {cpp_value})',
+ 'uint32_t':
+ 'v8::Integer::NewFromUnsigned({isolate}, {cpp_value})',
+ 'float':
+ 'v8::Number::New({isolate}, {cpp_value})',
+ 'unrestricted float':
+ 'v8::Number::New({isolate}, {cpp_value})',
+ 'double':
+ 'v8::Number::New({isolate}, {cpp_value})',
+ 'unrestricted double':
+ 'v8::Number::New({isolate}, {cpp_value})',
+ 'StringOrNull':
+ ('({cpp_value}.IsNull() ? ' + 'v8::Null({isolate}).As<v8::Value>() : ' +
+ 'V8String({isolate}, {cpp_value}).As<v8::Value>())'),
# Special cases
- 'Dictionary': '{cpp_value}.V8Value()',
- 'EventHandler': 'JSEventHandler::AsV8Value({isolate}, impl, {cpp_value})',
- 'NodeFilter': 'ToV8({cpp_value}, {creation_context}, {isolate})',
- 'Record': 'ToV8({cpp_value}, {creation_context}, {isolate})',
- 'ScriptValue': '{cpp_value}.V8Value()',
- 'SerializedScriptValue': 'V8Deserialize({isolate}, {cpp_value}.get())',
+ 'EventHandler':
+ 'JSEventHandler::AsV8Value({isolate}, impl, {cpp_value})',
+ 'NodeFilter':
+ 'ToV8({cpp_value}, {creation_context}, {isolate})',
+ 'Record':
+ 'ToV8({cpp_value}, {creation_context}, {isolate})',
+ 'ScriptValue':
+ '{cpp_value}.V8Value()',
# General
- 'sequence': 'ToV8({cpp_value}, {creation_context}, {isolate})',
- 'FrozenArray': 'FreezeV8Object(ToV8({cpp_value}, {creation_context}, {isolate}), {isolate})',
- 'DOMWrapper': 'ToV8({cpp_value}, {creation_context}, {isolate})',
+ 'sequence':
+ 'ToV8({cpp_value}, {creation_context}, {isolate})',
+ 'FrozenArray':
+ 'FreezeV8Object(ToV8({cpp_value}, {creation_context}, {isolate}), {isolate})',
+ 'DOMWrapper':
+ 'ToV8({cpp_value}, {creation_context}, {isolate})',
# Passing nullable dictionaries isn't a pattern currently used
# anywhere in the web platform, and more work would be needed in
# the code generator to distinguish between passing null, and
@@ -1036,19 +1182,29 @@ CPP_VALUE_TO_V8_VALUE = {
# nullable dictionary type.
#
# Union types or dictionaries
- 'DictionaryOrUnion': 'ToV8({cpp_value}, {creation_context}, {isolate})',
+ 'DictionaryOrUnion':
+ 'ToV8({cpp_value}, {creation_context}, {isolate})',
}
-def cpp_value_to_v8_value(idl_type, cpp_value, isolate='info.GetIsolate()', creation_context='info.Holder()', extended_attributes=None):
+def cpp_value_to_v8_value(idl_type,
+ cpp_value,
+ isolate='info.GetIsolate()',
+ creation_context='info.Holder()',
+ extended_attributes=None):
"""Returns an expression that converts a C++ value to a V8 value."""
# the isolate parameter is needed for callback interfaces
- idl_type, cpp_value = preprocess_idl_type_and_value(idl_type, cpp_value, extended_attributes)
+ idl_type, cpp_value = preprocess_idl_type_and_value(
+ idl_type, cpp_value, extended_attributes)
this_v8_conversion_type = idl_type.v8_conversion_type(extended_attributes)
format_string = CPP_VALUE_TO_V8_VALUE[this_v8_conversion_type]
- statement = format_string.format(cpp_value=cpp_value, isolate=isolate, creation_context=creation_context)
+ statement = format_string.format(
+ cpp_value=cpp_value,
+ isolate=isolate,
+ creation_context=creation_context)
return statement
+
IdlTypeBase.cpp_value_to_v8_value = cpp_value_to_v8_value
@@ -1096,7 +1252,6 @@ IdlType.literal_cpp_value = literal_cpp_value
IdlUnionType.literal_cpp_value = union_literal_cpp_value
IdlArrayOrSequenceType.literal_cpp_value = array_or_sequence_literal_cpp_value
-
_IDL_TYPE_TO_NATIVE_VALUE_TRAITS_TAG_MAP = {
'DOMString': 'IDLString',
'USVString': 'IDLUSVString',
@@ -1133,15 +1288,13 @@ def cpp_type_has_null_value(idl_type):
# - Interface types and Dictionary types represent null as a null pointer.
# - Union types, as thier container classes can represent null value.
# - 'Object' and 'any' type. We use ScriptValue for object type.
- return (idl_type.is_string_type
- or idl_type.is_enum
- or idl_type.is_interface_type
- or idl_type.is_callback_interface
+ return (idl_type.is_string_type or idl_type.is_enum
+ or idl_type.is_interface_type or idl_type.is_callback_interface
or idl_type.is_callback_function
- or idl_type.is_custom_callback_function
- or idl_type.is_dictionary
- or idl_type.is_union_type
- or idl_type.base_type == 'object' or idl_type.base_type == 'any')
+ or idl_type.is_custom_callback_function or idl_type.is_dictionary
+ or idl_type.is_union_type or idl_type.base_type == 'object'
+ or idl_type.base_type == 'any')
+
IdlTypeBase.cpp_type_has_null_value = property(cpp_type_has_null_value)
@@ -1156,6 +1309,7 @@ def is_explicit_nullable(idl_type):
# we use base::Optional<T> or similar explicit ways to represent a null value.
return idl_type.is_nullable and not idl_type.is_implicit_nullable
+
IdlTypeBase.is_implicit_nullable = property(is_implicit_nullable)
IdlUnionType.is_implicit_nullable = False
IdlTypeBase.is_explicit_nullable = property(is_explicit_nullable)
@@ -1165,6 +1319,7 @@ def includes_nullable_type_union(idl_type):
# http://heycam.github.io/webidl/#dfn-includes-a-nullable-type
return idl_type.number_of_nullable_member_types == 1
+
IdlTypeBase.includes_nullable_type = False
IdlNullableType.includes_nullable_type = True
IdlUnionType.includes_nullable_type = property(includes_nullable_type_union)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/v8_union.py b/chromium/third_party/blink/renderer/bindings/scripts/v8_union.py
index ffacd12235c..54d50871d5a 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/v8_union.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_union.py
@@ -6,9 +6,9 @@ from utilities import to_snake_case
import v8_types
import v8_utilities
-
UNION_CPP_INCLUDES = frozenset([
'base/stl_util.h',
+ 'bindings/core/v8/native_value_traits_impl.h',
'bindings/core/v8/to_v8_for_core.h',
])
@@ -21,7 +21,6 @@ UNION_H_INCLUDES = frozenset([
'platform/heap/handle.h',
])
-
cpp_includes = set()
header_forward_decls = set()
header_includes = set()
@@ -47,7 +46,8 @@ def container_context(union_type, info_provider):
object_type = None
record_type = None
string_type = None
- for member in sorted(union_type.flattened_member_types, key=lambda m: m.name):
+ for member in sorted(
+ union_type.flattened_member_types, key=lambda m: m.name):
context = member_context(member, info_provider)
members.append(context)
if member.base_type == 'ArrayBuffer':
@@ -66,8 +66,7 @@ def container_context(union_type, info_provider):
if array_or_sequence_type:
raise Exception('%s is ambiguous.' % union_type.name)
array_or_sequence_type = context
- # "Dictionary" is an object, rather than an IDL dictionary.
- elif member.base_type == 'Dictionary':
+ elif member.base_type == 'object':
if object_type or record_type:
raise Exception('%s is ambiguous.' % union_type.name)
object_type = context
@@ -84,14 +83,17 @@ def container_context(union_type, info_provider):
elif member is union_type.string_member_type:
string_type = context
else:
- raise Exception('%s is not supported as an union member.' % member.name)
+ raise Exception(
+ '%s is not supported as an union member.' % member.name)
# Nullable restriction checks
nullable_members = union_type.number_of_nullable_member_types
if nullable_members > 1:
- raise Exception('%s contains more than one nullable members' % union_type.name)
+ raise Exception(
+ '%s contains more than one nullable members' % union_type.name)
if dictionary_type and nullable_members == 1:
- raise Exception('%s has a dictionary and a nullable member' % union_type.name)
+ raise Exception(
+ '%s has a dictionary and a nullable member' % union_type.name)
cpp_class = union_type.cpp_type
return {
@@ -119,8 +121,8 @@ def container_context(union_type, info_provider):
def _update_includes_and_forward_decls(member, info_provider):
interface_info = info_provider.interfaces_info.get(member.name, None)
if interface_info:
- cpp_includes.update(interface_info.get(
- 'dependencies_include_paths', []))
+ cpp_includes.update(
+ interface_info.get('dependencies_include_paths', []))
# We need complete types for IDL dictionaries in union containers.
if member.is_dictionary or member.is_array_buffer_view_or_typed_array:
header_includes.update(member.includes_for_type())
@@ -130,15 +132,18 @@ def _update_includes_and_forward_decls(member, info_provider):
else:
if member.is_record_type:
_update_includes_and_forward_decls(member.key_type, info_provider)
- _update_includes_and_forward_decls(member.value_type, info_provider)
+ _update_includes_and_forward_decls(member.value_type,
+ info_provider)
elif member.is_array_or_sequence_type:
- _update_includes_and_forward_decls(member.element_type, info_provider)
+ _update_includes_and_forward_decls(member.element_type,
+ info_provider)
cpp_includes.add('bindings/core/v8/script_iterator.h')
elif member.is_union_type:
# Reaching this block means we have a union that is inside a
# record or sequence.
header_forward_decls.add(member.name)
- cpp_includes.update([info_provider.include_path_for_union_types(member)])
+ cpp_includes.update(
+ [info_provider.include_path_for_union_types(member)])
cpp_includes.update(member.includes_for_type())
@@ -146,7 +151,8 @@ def member_context(member, info_provider):
_update_includes_and_forward_decls(member, info_provider)
if member.is_nullable:
member = member.inner_type
- type_name = (member.inner_type if member.is_annotated_type else member).name
+ type_name = (member.inner_type
+ if member.is_annotated_type else member).name
# When converting a sequence or frozen array, we need to call the GetMethod(V, @@iterator)
# ES abstract operation and then use the result of that call to create a sequence from an
# iterable. For the purposes of this method, it means we need to pass |script_iterator|
@@ -156,21 +162,37 @@ def member_context(member, info_provider):
else:
v8_value_name = 'v8_value'
return {
- 'cpp_name': to_snake_case(v8_utilities.cpp_name(member)),
- 'cpp_type': member.cpp_type_args(used_in_cpp_sequence=True),
- 'cpp_local_type': member.cpp_type,
- 'cpp_value_to_v8_value': member.cpp_value_to_v8_value(
- cpp_value='impl.GetAs%s()' % type_name, isolate='isolate',
+ 'cpp_name':
+ to_snake_case(v8_utilities.cpp_name(member)),
+ 'cpp_type':
+ member.cpp_type_args(used_in_cpp_sequence=True),
+ 'cpp_local_type':
+ member.cpp_type,
+ 'cpp_value_to_v8_value':
+ member.cpp_value_to_v8_value(
+ cpp_value='impl.GetAs%s()' % type_name,
+ isolate='isolate',
creation_context='creationContext'),
- 'enum_type': member.enum_type,
- 'enum_values': member.enum_values,
- 'is_array_buffer_or_view_type': member.is_array_buffer_or_view,
- 'is_array_buffer_view_or_typed_array': member.is_array_buffer_view_or_typed_array,
- 'is_traceable': member.is_traceable,
- 'rvalue_cpp_type': member.cpp_type_args(used_as_rvalue_type=True),
- 'specific_type_enum': 'k' + member.name,
- 'type_name': type_name,
- 'v8_value_to_local_cpp_value': member.v8_value_to_local_cpp_value(
- {}, v8_value_name, 'cpp_value', isolate='isolate',
- use_exception_state=True)
+ 'enum_type':
+ member.enum_type,
+ 'enum_values':
+ member.enum_values,
+ 'is_array_buffer_or_view_type':
+ member.is_array_buffer_or_view,
+ 'is_array_buffer_view_or_typed_array':
+ member.is_array_buffer_view_or_typed_array,
+ 'is_traceable':
+ member.is_traceable,
+ 'rvalue_cpp_type':
+ member.cpp_type_args(used_as_rvalue_type=True),
+ 'specific_type_enum':
+ 'k' + member.name,
+ 'type_name':
+ type_name,
+ 'v8_value_to_local_cpp_value':
+ member.v8_value_to_local_cpp_value({},
+ v8_value_name,
+ 'cpp_value',
+ isolate='isolate',
+ use_exception_state=True)
}
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 ec31d27da23..d6a53c6538a 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/v8_utilities.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_utilities.py
@@ -25,7 +25,6 @@
# 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.
-
"""Functions shared by various parts of the code generator.
Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
@@ -56,15 +55,15 @@ ACRONYMS = [
'XSLT',
]
-
################################################################################
# Extended attribute parsing
################################################################################
+
def extended_attribute_value_contains(extended_attribute_value, key):
- return (extended_attribute_value == key or
- (isinstance(extended_attribute_value, list) and
- key in extended_attribute_value))
+ return (extended_attribute_value == key
+ or (isinstance(extended_attribute_value, list)
+ and key in extended_attribute_value))
def has_extended_attribute(definition_or_member, extended_attribute_list):
@@ -74,8 +73,8 @@ def has_extended_attribute(definition_or_member, extended_attribute_list):
def has_extended_attribute_value(definition_or_member, name, value):
extended_attributes = definition_or_member.extended_attributes
- return (name in extended_attributes and
- extended_attribute_value_contains(extended_attributes[name], value))
+ return (name in extended_attributes and extended_attribute_value_contains(
+ extended_attributes[name], value))
def extended_attribute_value_as_list(definition_or_member, name):
@@ -92,6 +91,7 @@ def extended_attribute_value_as_list(definition_or_member, name):
# String handling
################################################################################
+
def capitalize(name):
"""Capitalize first letter or initial acronym (used in setter names)."""
for acronym in ACRONYMS:
@@ -126,14 +126,16 @@ def runtime_enabled_function(name):
# C++
################################################################################
+
def scoped_name(interface, definition, base_name):
# partial interfaces are implemented as separate classes, with their members
# implemented as static member functions
- partial_interface_implemented_as = definition.extended_attributes.get('PartialInterfaceImplementedAs')
+ partial_interface_implemented_as = definition.extended_attributes.get(
+ 'PartialInterfaceImplementedAs')
if partial_interface_implemented_as:
return '%s::%s' % (partial_interface_implemented_as, base_name)
- if (definition.is_static or
- definition.name in ('Constructor', 'NamedConstructor')):
+ if (definition.is_static
+ or definition.name in ('Constructor', 'NamedConstructor')):
return '%s::%s' % (cpp_name(interface), base_name)
return 'impl->%s' % base_name
@@ -168,6 +170,7 @@ def binding_header_filename(name):
# Specific extended attributes
################################################################################
+
# [ActivityLogging]
def activity_logging_world_list(member, access_type=''):
"""Returns a set of world suffixes for which a definition member has activity logging, for specified access type.
@@ -198,8 +201,8 @@ def activity_logging_world_check(member):
extended_attributes = member.extended_attributes
if 'LogActivity' not in extended_attributes:
return False
- if ('PerWorldBindings' not in extended_attributes and
- 'LogAllWorlds' not in extended_attributes):
+ if ('PerWorldBindings' not in extended_attributes
+ and 'LogAllWorlds' not in extended_attributes):
return True
return False
@@ -225,16 +228,17 @@ CALL_WITH_VALUES = [
def call_with_arguments(call_with_values):
if not call_with_values:
return []
- return [CALL_WITH_ARGUMENTS[value]
- for value in CALL_WITH_VALUES
- if extended_attribute_value_contains(call_with_values, value)]
+ return [
+ CALL_WITH_ARGUMENTS[value] for value in CALL_WITH_VALUES
+ if extended_attribute_value_contains(call_with_values, value)
+ ]
# [Constructor], [NamedConstructor]
def is_constructor_attribute(member):
# TODO(yukishiino): replace this with [Constructor] and [NamedConstructor] extended attribute
- return (type(member) == IdlAttribute and
- member.idl_type.name.endswith('Constructor'))
+ return (type(member) == IdlAttribute
+ and member.idl_type.name.endswith('Constructor'))
# [DeprecateAs]
@@ -260,7 +264,6 @@ EXPOSED_EXECUTION_CONTEXT_METHOD = {
'Worklet': 'IsWorkletGlobalScope',
}
-
EXPOSED_WORKERS = set([
'DedicatedWorker',
'SharedWorker',
@@ -270,6 +273,7 @@ EXPOSED_WORKERS = set([
class ExposureSet:
"""An ExposureSet is a collection of Exposure instructions."""
+
def __init__(self, exposures=None):
self.exposures = set(exposures) if exposures else set()
@@ -301,9 +305,10 @@ class ExposureSet:
@staticmethod
def _code(exposure):
condition = ('execution_context->%s()' %
- EXPOSED_EXECUTION_CONTEXT_METHOD[exposure.exposed])
+ EXPOSED_EXECUTION_CONTEXT_METHOD[exposure.exposed])
if exposure.runtime_enabled is not None:
- runtime_enabled = (runtime_enabled_function(exposure.runtime_enabled))
+ runtime_enabled = (runtime_enabled_function(
+ exposure.runtime_enabled))
return '({0} && {1})'.format(condition, runtime_enabled)
return condition
@@ -338,7 +343,9 @@ def exposed(member, interface):
# Methods must not be exposed to a broader scope than their interface.
if not exposure_set.issubset(interface_exposure_set):
- raise ValueError('Interface members\' exposure sets must be a subset of the interface\'s.')
+ raise ValueError(
+ 'Interface members\' exposure sets must be a subset of the interface\'s.'
+ )
return exposure_set.code()
@@ -349,9 +356,9 @@ def secure_context(member, interface):
to the current context. Requires that the surrounding code defines an |is_secure_context|
variable prior to this check."""
member_is_secure_context = 'SecureContext' in member.extended_attributes
- interface_is_secure_context = ((member.defined_in is None or
- member.defined_in == interface.name) and
- 'SecureContext' in interface.extended_attributes)
+ interface_is_secure_context = (
+ (member.defined_in is None or member.defined_in == interface.name)
+ and 'SecureContext' in interface.extended_attributes)
if not (member_is_secure_context or interface_is_secure_context):
return None
@@ -361,12 +368,14 @@ def secure_context(member, interface):
if member_is_secure_context:
conditional = member.extended_attributes['SecureContext']
if conditional:
- conditions.append('!{}'.format(runtime_enabled_function(conditional)))
+ conditions.append('!{}'.format(
+ runtime_enabled_function(conditional)))
if interface_is_secure_context:
conditional = interface.extended_attributes['SecureContext']
if conditional:
- conditions.append('!{}'.format(runtime_enabled_function(conditional)))
+ conditions.append('!{}'.format(
+ runtime_enabled_function(conditional)))
return ' || '.join(conditions)
@@ -381,7 +390,8 @@ def cpp_name(definition_or_member):
#
# [1] https://heycam.github.io/webidl/#prod-identifier
if '-' in definition_or_member.name:
- return NameStyleConverter(definition_or_member.name).to_lower_camel_case()
+ return NameStyleConverter(
+ definition_or_member.name).to_lower_camel_case()
return definition_or_member.name
@@ -396,6 +406,25 @@ def cpp_name_or_partial(interface):
return cpp_class_name
+def cpp_encoded_property_name(member):
+ """
+ Returns a property name that the bindings generator can use in generated
+ code internally.
+
+ Note that Web IDL allows '-' (hyphen-minus) and '_' (low line) in
+ identifiers but C++ does not allow or recommend them. This function
+ encodes these characters.
+ """
+ property_name = member.name
+ # We're optimistic about name conflict. It's highly unlikely that these
+ # replacements will cause a conflict.
+ assert "Dec45" not in property_name
+ assert "Dec95" not in property_name
+ property_name = property_name.replace("-", "Dec45")
+ property_name = property_name.replace("_", "Dec95")
+ return property_name
+
+
# [MeasureAs]
def measure_as(definition_or_member, interface):
extended_attributes = definition_or_member.extended_attributes
@@ -408,7 +437,8 @@ def measure_as(definition_or_member, interface):
includes.add('platform/instrumentation/use_counter.h')
measure_as_name = capitalize(definition_or_member.name)
if interface is not None:
- measure_as_name = '%s_%s' % (capitalize(interface.name), measure_as_name)
+ measure_as_name = '%s_%s' % (capitalize(interface.name),
+ measure_as_name)
return lambda suffix: 'V8%s_%s' % (measure_as_name, suffix)
return None
@@ -418,10 +448,11 @@ def high_entropy(definition_or_member):
extended_attributes = definition_or_member.extended_attributes
if 'HighEntropy' in extended_attributes:
includes.add('core/frame/dactyloscoper.h')
- if not ('Measure' in extended_attributes or 'MeasureAs' in extended_attributes):
- raise Exception('%s specified [HighEntropy], but does not include '
- 'either [Measure] or [MeasureAs]'
- % definition_or_member.name)
+ if not ('Measure' in extended_attributes
+ or 'MeasureAs' in extended_attributes):
+ raise Exception(
+ '%s specified [HighEntropy], but does not include '
+ 'either [Measure] or [MeasureAs]' % definition_or_member.name)
return True
return False
@@ -440,7 +471,8 @@ def origin_trial_feature_name(definition_or_member, runtime_features):
"""
extended_attributes = definition_or_member.extended_attributes
feature_name = extended_attributes.get('RuntimeEnabled')
- if feature_name and _is_origin_trial_feature(feature_name, runtime_features):
+ if feature_name and _is_origin_trial_feature(feature_name,
+ runtime_features):
return feature_name
@@ -448,7 +480,8 @@ def origin_trial_function_call(feature_name, execution_context=None):
"""Returns a function call to determine if an origin trial is enabled."""
return 'RuntimeEnabledFeatures::{feature_name}Enabled({context})'.format(
feature_name=feature_name,
- context=execution_context if execution_context else "execution_context")
+ context=execution_context
+ if execution_context else "execution_context")
# [ContextEnabled]
@@ -470,7 +503,8 @@ def rcs_counter_name(member, generic_counter_name):
def runtime_enabled_feature_name(definition_or_member, runtime_features):
extended_attributes = definition_or_member.extended_attributes
feature_name = extended_attributes.get('RuntimeEnabled')
- if feature_name and not _is_origin_trial_feature(feature_name, runtime_features):
+ if feature_name and not _is_origin_trial_feature(feature_name,
+ runtime_features):
includes.add('platform/runtime_enabled_features.h')
return feature_name
@@ -502,8 +536,8 @@ def on_instance(interface, member):
if is_constructor_attribute(member):
return True
- if ('Global' in interface.extended_attributes or
- 'Unforgeable' in member.extended_attributes):
+ if ('Global' in interface.extended_attributes
+ or 'Unforgeable' in member.extended_attributes):
return True
return False
@@ -532,8 +566,8 @@ def on_prototype(interface, member):
if is_constructor_attribute(member):
return False
- if ('Global' in interface.extended_attributes or
- 'Unforgeable' in member.extended_attributes):
+ if ('Global' in interface.extended_attributes
+ or 'Unforgeable' in member.extended_attributes):
return False
return True
@@ -556,16 +590,15 @@ def on_interface(interface, member):
# http://heycam.github.io/webidl/#idl-indexed-properties
################################################################################
+
def indexed_property_getter(interface):
try:
# Find indexed property getter, if present; has form:
# getter TYPE [OPTIONAL_IDENTIFIER](unsigned long ARG1)
return next(
- method
- for method in interface.operations
- if ('getter' in method.specials and
- len(method.arguments) == 1 and
- str(method.arguments[0].idl_type) == 'unsigned long'))
+ method for method in interface.operations
+ if ('getter' in method.specials and len(method.arguments) == 1
+ and str(method.arguments[0].idl_type) == 'unsigned long'))
except StopIteration:
return None
@@ -575,11 +608,9 @@ def indexed_property_setter(interface):
# Find indexed property setter, if present; has form:
# setter RETURN_TYPE [OPTIONAL_IDENTIFIER](unsigned long ARG1, ARG_TYPE ARG2)
return next(
- method
- for method in interface.operations
- if ('setter' in method.specials and
- len(method.arguments) == 2 and
- str(method.arguments[0].idl_type) == 'unsigned long'))
+ method for method in interface.operations
+ if ('setter' in method.specials and len(method.arguments) == 2
+ and str(method.arguments[0].idl_type) == 'unsigned long'))
except StopIteration:
return None
@@ -589,11 +620,9 @@ def indexed_property_deleter(interface):
# Find indexed property deleter, if present; has form:
# deleter TYPE [OPTIONAL_IDENTIFIER](unsigned long ARG)
return next(
- method
- for method in interface.operations
- if ('deleter' in method.specials and
- len(method.arguments) == 1 and
- str(method.arguments[0].idl_type) == 'unsigned long'))
+ method for method in interface.operations
+ if ('deleter' in method.specials and len(method.arguments) == 1
+ and str(method.arguments[0].idl_type) == 'unsigned long'))
except StopIteration:
return None
@@ -603,16 +632,15 @@ def indexed_property_deleter(interface):
# http://heycam.github.io/webidl/#idl-named-properties
################################################################################
+
def named_property_getter(interface):
try:
# Find named property getter, if present; has form:
# getter TYPE [OPTIONAL_IDENTIFIER](DOMString ARG1)
getter = next(
- method
- for method in interface.operations
- if ('getter' in method.specials and
- len(method.arguments) == 1 and
- str(method.arguments[0].idl_type) == 'DOMString'))
+ method for method in interface.operations
+ if ('getter' in method.specials and len(method.arguments) == 1
+ and str(method.arguments[0].idl_type) == 'DOMString'))
getter.name = getter.name or 'AnonymousNamedGetter'
return getter
except StopIteration:
@@ -624,11 +652,9 @@ def named_property_setter(interface):
# Find named property setter, if present; has form:
# setter RETURN_TYPE [OPTIONAL_IDENTIFIER](DOMString ARG1, ARG_TYPE ARG2)
return next(
- method
- for method in interface.operations
- if ('setter' in method.specials and
- len(method.arguments) == 2 and
- str(method.arguments[0].idl_type) == 'DOMString'))
+ method for method in interface.operations
+ if ('setter' in method.specials and len(method.arguments) == 2
+ and str(method.arguments[0].idl_type) == 'DOMString'))
except StopIteration:
return None
@@ -638,11 +664,9 @@ def named_property_deleter(interface):
# Find named property deleter, if present; has form:
# deleter TYPE [OPTIONAL_IDENTIFIER](DOMString ARG)
return next(
- method
- for method in interface.operations
- if ('deleter' in method.specials and
- len(method.arguments) == 1 and
- str(method.arguments[0].idl_type) == 'DOMString'))
+ method for method in interface.operations
+ if ('deleter' in method.specials and len(method.arguments) == 1
+ and str(method.arguments[0].idl_type) == 'DOMString'))
except StopIteration:
return None
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/.style.yapf b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/.style.yapf
index 0169b9a6487..2ae9158e446 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/.style.yapf
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/.style.yapf
@@ -1,3 +1,4 @@
[style]
# https://www.chromium.org/blink/coding-style
based_on_style = pep8
+column_limit = 79
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/__init__.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/__init__.py
index 4dacc398b45..387fef30bff 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/__init__.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/__init__.py
@@ -12,8 +12,10 @@ def _setup_sys_path():
expected_path = 'third_party/blink/renderer/bindings/scripts/web_idl/'
this_dir = os.path.dirname(__file__)
- root_dir = os.path.join(this_dir, *(['..'] * expected_path.count('/')))
- sys.path = [
+ root_dir = os.path.abspath(
+ os.path.join(this_dir, *(['..'] * expected_path.count('/'))))
+
+ module_dirs = (
# //third_party/blink/renderer/build/scripts/blinkbuild
os.path.join(root_dir, 'third_party', 'blink', 'renderer', 'build',
'scripts'),
@@ -23,17 +25,23 @@ def _setup_sys_path():
os.path.join(root_dir, 'third_party', 'pyjson5', 'src'),
# //tools/idl_parser
os.path.join(root_dir, 'tools'),
- ] + sys.path
+ )
+ for module_dir in reversed(module_dirs):
+ # Preserve sys.path[0] as is.
+ # https://docs.python.org/3/library/sys.html?highlight=path[0]#sys.path
+ sys.path.insert(1, module_dir)
_setup_sys_path()
-
+from . import file_io
from .ast_group import AstGroup
from .attribute import Attribute
from .callback_function import CallbackFunction
from .callback_interface import CallbackInterface
from .composition_parts import Component
+from .composition_parts import DebugInfo
+from .composition_parts import Identifier
from .constant import Constant
from .constructor import Constructor
from .constructor import ConstructorGroup
@@ -43,10 +51,18 @@ from .dictionary import Dictionary
from .dictionary import DictionaryMember
from .enumeration import Enumeration
from .exposure import Exposure
+from .extended_attribute import ExtendedAttribute
+from .extended_attribute import ExtendedAttributes
from .function_like import FunctionLike
from .function_like import OverloadGroup
from .idl_type import IdlType
+from .interface import IndexedAndNamedProperties
from .interface import Interface
+from .interface import Iterable
+from .interface import LegacyWindowAlias
+from .interface import Maplike
+from .interface import Setlike
+from .interface import Stringifier
from .literal_constant import LiteralConstant
from .namespace import Namespace
from .operation import Operation
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/attribute.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/attribute.py
index 1d3f9d74fc1..467e1006463 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/attribute.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/attribute.py
@@ -55,7 +55,7 @@ class Attribute(WithIdentifier, WithExtendedAttributes, WithCodeGeneratorInfo,
ir = make_copy(ir)
WithIdentifier.__init__(self, ir)
- WithExtendedAttributes.__init__(self, ir)
+ WithExtendedAttributes.__init__(self, ir, readonly=True)
WithCodeGeneratorInfo.__init__(self, ir, readonly=True)
WithExposure.__init__(self, ir, readonly=True)
WithOwner.__init__(self, owner)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/callback_function.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/callback_function.py
index 3536a9e67c6..b82196d6b7b 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/callback_function.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/callback_function.py
@@ -47,7 +47,7 @@ class CallbackFunction(UserDefinedType, FunctionLike, WithExtendedAttributes,
ir = make_copy(ir)
UserDefinedType.__init__(self, ir.identifier)
FunctionLike.__init__(self, ir)
- WithExtendedAttributes.__init__(self, ir)
+ WithExtendedAttributes.__init__(self, ir, readonly=True)
WithCodeGeneratorInfo.__init__(self, ir, readonly=True)
WithComponent.__init__(self, ir, readonly=True)
WithDebugInfo.__init__(self, ir)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/callback_interface.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/callback_interface.py
index e3792d16520..42249966d1c 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/callback_interface.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/callback_interface.py
@@ -52,17 +52,19 @@ class CallbackInterface(UserDefinedType, WithExtendedAttributes,
self.attributes = []
self.constants = constants
- self.operations = operations
- self.operation_groups = []
self.constructors = []
self.constructor_groups = []
+ self.named_constructors = []
+ self.named_constructor_groups = []
+ self.operations = operations
+ self.operation_groups = []
def __init__(self, ir):
assert isinstance(ir, CallbackInterface.IR)
ir = make_copy(ir)
UserDefinedType.__init__(self, ir.identifier)
- WithExtendedAttributes.__init__(self, ir)
+ WithExtendedAttributes.__init__(self, ir, readonly=True)
WithCodeGeneratorInfo.__init__(self, ir, readonly=True)
WithComponent.__init__(self, ir, readonly=True)
WithDebugInfo.__init__(self, ir)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/code_generator_info.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/code_generator_info.py
index 98a491d27b2..9c1d2784440 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/code_generator_info.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/code_generator_info.py
@@ -5,8 +5,11 @@
# The list of attributes that CodeGeneratorInfo supports. CodeGeneratorInfo's
# attributes are auto-generated from this list because they're boilerplated.
_CODE_GENERATOR_INFO_ATTRIBUTES = (
- 'defined_in_mixin',
- 'defined_in_partial',
+ 'blink_headers',
+ 'defined_in_mixin', # [LegacyTreatAsPartialInterface] makes this False
+ 'defined_in_partial', # [LegacyTreatAsPartialInterface] makes this True
+ 'is_active_script_wrappable',
+ 'is_legacy_unenumerable_named_properties',
'property_implemented_as',
'receiver_implemented_as',
)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/composition_parts.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/composition_parts.py
index a999bca7d7e..29add032724 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/composition_parts.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/composition_parts.py
@@ -2,11 +2,14 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import posixpath
+
from .code_generator_info import CodeGeneratorInfo
from .code_generator_info import CodeGeneratorInfoMutable
from .exposure import Exposure
from .exposure import ExposureMutable
from .extended_attribute import ExtendedAttributes
+from .extended_attribute import ExtendedAttributesMutable
class Identifier(str):
@@ -31,14 +34,18 @@ class WithIdentifier(object):
class WithExtendedAttributes(object):
"""Implements |extended_attributes| as a readonly attribute."""
- def __init__(self, extended_attributes=None):
+ def __init__(self, extended_attributes=None, readonly=False):
if isinstance(extended_attributes, WithExtendedAttributes):
extended_attributes = extended_attributes.extended_attributes
elif extended_attributes is None:
extended_attributes = ExtendedAttributes()
assert isinstance(extended_attributes, ExtendedAttributes)
- self._extended_attributes = extended_attributes
+ if readonly:
+ self._extended_attributes = ExtendedAttributes(extended_attributes)
+ else:
+ self._extended_attributes = ExtendedAttributesMutable(
+ extended_attributes)
@property
def extended_attributes(self):
@@ -133,10 +140,22 @@ class WithComponent(object):
class Location(object):
+ _blink_path_prefix = posixpath.sep + posixpath.join(
+ 'third_party', 'blink', 'renderer', '')
+
def __init__(self, filepath=None, line_number=None, position=None):
assert filepath is None or isinstance(filepath, str)
assert line_number is None or isinstance(line_number, int)
assert position is None or isinstance(position, int)
+
+ # idl_parser produces paths based on the working directory, which may
+ # not be the project root directory, e.g. "../../third_party/blink/...".
+ # Canonicalize the paths heuristically.
+ if filepath is not None:
+ index = filepath.find(self._blink_path_prefix)
+ if index >= 0:
+ filepath = filepath[index + 1:]
+
self._filepath = filepath
self._line_number = line_number
self._position = position # Position number in a file
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/constant.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/constant.py
index 3a4a85ea710..c54fef0b472 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/constant.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/constant.py
@@ -50,7 +50,7 @@ class Constant(WithIdentifier, WithExtendedAttributes, WithCodeGeneratorInfo,
ir = make_copy(ir)
WithIdentifier.__init__(self, ir)
- WithExtendedAttributes.__init__(self, ir)
+ WithExtendedAttributes.__init__(self, ir, readonly=True)
WithCodeGeneratorInfo.__init__(self, ir, readonly=True)
WithExposure.__init__(self, ir, readonly=True)
WithOwner.__init__(self, owner)
@@ -67,6 +67,14 @@ class Constant(WithIdentifier, WithExtendedAttributes, WithCodeGeneratorInfo,
return self._idl_type
@property
+ def is_static(self):
+ return True
+
+ @property
+ def is_readonly(self):
+ return True
+
+ @property
def value(self):
"""Returns the value."""
return self._value
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/constructor.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/constructor.py
index 486ee910d11..ceacd261c7c 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/constructor.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/constructor.py
@@ -27,14 +27,16 @@ class Constructor(FunctionLike, WithExtendedAttributes, WithCodeGeneratorInfo,
class IR(FunctionLike.IR, WithExtendedAttributes, WithCodeGeneratorInfo,
WithExposure, WithOwnerMixin, WithComponent, WithDebugInfo):
def __init__(self,
+ identifier,
arguments,
return_type,
extended_attributes=None,
component=None,
debug_info=None):
+ assert identifier is None or isinstance(identifier, Identifier)
FunctionLike.IR.__init__(
self,
- identifier=Identifier('constructor'),
+ identifier=(identifier or Identifier('constructor')),
arguments=arguments,
return_type=return_type)
WithExtendedAttributes.__init__(self, extended_attributes)
@@ -48,7 +50,7 @@ class Constructor(FunctionLike, WithExtendedAttributes, WithCodeGeneratorInfo,
assert isinstance(ir, Constructor.IR)
FunctionLike.__init__(self, ir)
- WithExtendedAttributes.__init__(self, ir)
+ WithExtendedAttributes.__init__(self, ir, readonly=True)
WithCodeGeneratorInfo.__init__(self, ir, readonly=True)
WithExposure.__init__(self, ir, readonly=True)
WithOwner.__init__(self, owner)
@@ -57,22 +59,25 @@ class Constructor(FunctionLike, WithExtendedAttributes, WithCodeGeneratorInfo,
WithDebugInfo.__init__(self, ir)
-class ConstructorGroup(OverloadGroup, WithCodeGeneratorInfo, WithExposure,
- WithOwner, WithComponent, WithDebugInfo):
+class ConstructorGroup(OverloadGroup, WithExtendedAttributes,
+ WithCodeGeneratorInfo, WithExposure, WithOwner,
+ WithComponent, WithDebugInfo):
"""
- Represents a group of constructors for an interface.
+ Represents a group of constructors of an interface.
The number of constructors in this group may be 1 or 2+. In the latter
case, the constructors are overloaded.
"""
- class IR(OverloadGroup.IR, WithCodeGeneratorInfo, WithExposure,
- WithDebugInfo):
+ class IR(OverloadGroup.IR, WithExtendedAttributes, WithCodeGeneratorInfo,
+ WithExposure, WithDebugInfo):
def __init__(self,
constructors,
+ extended_attributes=None,
code_generator_info=None,
debug_info=None):
OverloadGroup.IR.__init__(self, constructors)
+ WithExtendedAttributes.__init__(self, extended_attributes)
WithCodeGeneratorInfo.__init__(self, code_generator_info)
WithExposure.__init__(self)
WithDebugInfo.__init__(self, debug_info)
@@ -92,6 +97,7 @@ class ConstructorGroup(OverloadGroup, WithCodeGeneratorInfo, WithExposure,
ir = make_copy(ir)
OverloadGroup.__init__(self, functions=constructors)
+ WithExtendedAttributes.__init__(self, ir, readonly=True)
WithCodeGeneratorInfo.__init__(self, ir, readonly=True)
WithExposure.__init__(self, ir, readonly=True)
WithOwner.__init__(self, owner)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/database.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/database.py
index b9ecfe5632e..c92cf48eb2a 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/database.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/database.py
@@ -48,17 +48,17 @@ class DatabaseBody(object):
)
@classmethod
- def itervalues(cls):
+ def values(cls):
return cls._ALL_ENTRIES.__iter__()
def __init__(self):
self._defs = {}
- for kind in DatabaseBody.Kind.itervalues():
+ for kind in DatabaseBody.Kind.values():
self._defs[kind] = {}
def register(self, kind, user_defined_type):
assert isinstance(user_defined_type, (Typedef, Union, UserDefinedType))
- assert kind in DatabaseBody.Kind.itervalues()
+ assert kind in DatabaseBody.Kind.values()
try:
self.find_by_identifier(user_defined_type.identifier)
assert False, user_defined_type.identifier
@@ -67,7 +67,7 @@ class DatabaseBody(object):
self._defs[kind][user_defined_type.identifier] = user_defined_type
def find_by_identifier(self, identifier):
- for defs_per_kind in self._defs.itervalues():
+ for defs_per_kind in self._defs.values():
if identifier in defs_per_kind:
return defs_per_kind[identifier]
raise KeyError(identifier)
@@ -107,6 +107,26 @@ class Database(object):
return self._impl.find_by_identifier(identifier)
@property
+ def callback_functions(self):
+ """Returns all callback functions."""
+ return self._view_by_kind(Database._Kind.CALLBACK_FUNCTION)
+
+ @property
+ def callback_interfaces(self):
+ """Returns all callback interfaces."""
+ return self._view_by_kind(Database._Kind.CALLBACK_INTERFACE)
+
+ @property
+ def dictionaries(self):
+ """Returns all dictionaries."""
+ return self._view_by_kind(Database._Kind.DICTIONARY)
+
+ @property
+ def enumerations(self):
+ """Returns all enumerations."""
+ return self._view_by_kind(Database._Kind.ENUMERATION)
+
+ @property
def interfaces(self):
"""
Returns all interfaces.
@@ -121,26 +141,11 @@ class Database(object):
return self._view_by_kind(Database._Kind.INTERFACE_MIXIN)
@property
- def dictionaries(self):
- """Returns all dictionaries."""
- return self._view_by_kind(Database._Kind.DICTIONARY)
-
- @property
def namespaces(self):
"""Returns all namespaces."""
return self._view_by_kind(Database._Kind.NAMESPACE)
@property
- def callback_functions(self):
- """Returns all callback functions."""
- return self._view_by_kind(Database._Kind.CALLBACK_FUNCTION)
-
- @property
- def callback_interfaces(self):
- """Returns all callback interfaces."""
- return self._view_by_kind(Database._Kind.CALLBACK_INTERFACE)
-
- @property
def typedefs(self):
"""Returns all typedef definitions."""
return self._view_by_kind(Database._Kind.TYPEDEF)
@@ -151,4 +156,4 @@ class Database(object):
return self._view_by_kind(Database._Kind.UNION)
def _view_by_kind(self, kind):
- return self._impl.find_by_kind(kind).viewvalues()
+ return self._impl.find_by_kind(kind).values()
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/demonstration_and_testing.idl b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/demonstration_and_testing.idl
index 1f94e76ad3b..766bfe7a7cf 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/demonstration_and_testing.idl
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/demonstration_and_testing.idl
@@ -12,7 +12,7 @@
Exposed=Window
] interface TestInterfaceConstructor {
constructor();
- constructor(DOMString arg1);
+ [HTMLConstructor] constructor(DOMString arg1);
[Custom] constructor(Node node);
[RuntimeEnabled=TestFeature1] constructor(long num);
};
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/dictionary.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/dictionary.py
index 1f536e99b0d..01d2cdedcd6 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/dictionary.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/dictionary.py
@@ -62,7 +62,7 @@ class Dictionary(UserDefinedType, WithExtendedAttributes,
ir = make_copy(ir)
UserDefinedType.__init__(self, ir.identifier)
- WithExtendedAttributes.__init__(self, ir)
+ WithExtendedAttributes.__init__(self, ir, readonly=True)
WithCodeGeneratorInfo.__init__(self, ir, readonly=True)
WithExposure.__init__(self, ir, readonly=True)
WithComponent.__init__(self, ir, readonly=True)
@@ -143,7 +143,7 @@ class DictionaryMember(WithIdentifier, WithExtendedAttributes,
ir = make_copy(ir)
WithIdentifier.__init__(self, ir)
- WithExtendedAttributes.__init__(self, ir)
+ WithExtendedAttributes.__init__(self, ir, readonly=True)
WithCodeGeneratorInfo.__init__(self, ir, readonly=True)
WithExposure.__init__(self, ir, readonly=True)
WithOwner.__init__(self, owner)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/enumeration.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/enumeration.py
index b402d14c2d7..f141e86e05d 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/enumeration.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/enumeration.py
@@ -42,7 +42,7 @@ class Enumeration(UserDefinedType, WithExtendedAttributes,
ir = make_copy(ir)
UserDefinedType.__init__(self, ir.identifier)
- WithExtendedAttributes.__init__(self, ir)
+ WithExtendedAttributes.__init__(self, ir, readonly=True)
WithCodeGeneratorInfo.__init__(self, ir, readonly=True)
WithComponent.__init__(self, ir, readonly=True)
WithDebugInfo.__init__(self, ir)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/exposure.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/exposure.py
index 266b7388a18..46e2e45af49 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/exposure.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/exposure.py
@@ -5,13 +5,29 @@
from .runtime_enabled_features import RuntimeEnabledFeatures
+class _Feature(str):
+ """Represents a runtime-enabled feature."""
+
+ def __init__(self, value):
+ str.__init__(self, value)
+ self._is_context_dependent = (
+ RuntimeEnabledFeatures.is_context_dependent(self))
+
+ @property
+ def is_context_dependent(self):
+ return self._is_context_dependent
+
+
class _GlobalNameAndFeature(object):
def __init__(self, global_name, feature=None):
assert isinstance(global_name, str)
assert feature is None or isinstance(feature, str)
self._global_name = global_name
- self._feature = feature
+ if feature is None:
+ self._feature = None
+ else:
+ self._feature = _Feature(feature)
@property
def global_name(self):
@@ -23,6 +39,8 @@ class _GlobalNameAndFeature(object):
class Exposure(object):
+ """Represents a set of conditions under which the construct is exposed."""
+
def __init__(self, other=None):
assert other is None or isinstance(other, Exposure)
@@ -94,6 +112,34 @@ class Exposure(object):
return False
return self._only_in_secure_contexts
+ def is_context_dependent(self, global_names=None):
+ """
+ Returns True if the exposure of this construct depends on a context.
+
+ Args:
+ global_names: When specified, it's taken into account that the
+ global object implements |global_names|.
+ """
+ assert (global_names is None
+ or (isinstance(global_names, (list, tuple))
+ and all(isinstance(name, str) for name in global_names)))
+
+ if (self.context_dependent_runtime_enabled_features
+ or self.context_enabled_features
+ or self.only_in_secure_contexts):
+ return True
+
+ if not global_names:
+ return bool(self.global_names_and_features)
+
+ is_context_dependent = False
+ for entry in self.global_names_and_features:
+ if entry.global_name not in global_names:
+ continue
+ if entry.feature and entry.feature.is_context_dependent:
+ is_context_dependent = True
+ return is_context_dependent
+
class ExposureMutable(Exposure):
def __init__(self):
@@ -118,11 +164,12 @@ class ExposureMutable(Exposure):
def add_runtime_enabled_feature(self, name):
assert isinstance(name, str)
- if RuntimeEnabledFeatures.is_context_dependent(name):
- self._context_dependent_runtime_enabled_features.append(name)
+ feature = _Feature(name)
+ if feature.is_context_dependent:
+ self._context_dependent_runtime_enabled_features.append(feature)
else:
- self._context_independent_runtime_enabled_features.append(name)
- self._runtime_enabled_features.append(name)
+ self._context_independent_runtime_enabled_features.append(feature)
+ self._runtime_enabled_features.append(feature)
def add_context_enabled_feature(self, name):
assert isinstance(name, str)
@@ -136,6 +183,6 @@ class ExposureMutable(Exposure):
if isinstance(value, bool):
self._only_in_secure_contexts = value
elif isinstance(value, str):
- self._only_in_secure_contexts = (value, )
+ self._only_in_secure_contexts = (_Feature(value), )
else:
- self._only_in_secure_contexts = tuple(value)
+ self._only_in_secure_contexts = tuple(map(_Feature, value))
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/extended_attribute.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/extended_attribute.py
index ee6967af9b1..36eec862f47 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/extended_attribute.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/extended_attribute.py
@@ -169,10 +169,12 @@ class ExtendedAttributes(object):
"""
def __init__(self, extended_attributes=None):
- assert extended_attributes is None or (isinstance(
- extended_attributes, (list, tuple)) and all(
- isinstance(attr, ExtendedAttribute)
- for attr in extended_attributes))
+ assert (extended_attributes is None
+ or isinstance(extended_attributes, ExtendedAttributes)
+ or (isinstance(extended_attributes, (list, tuple)) and all(
+ isinstance(attr, ExtendedAttribute)
+ for attr in extended_attributes)))
+
sorted_ext_attrs = sorted(
extended_attributes or [], key=lambda x: x.key)
@@ -181,8 +183,15 @@ class ExtendedAttributes(object):
for key, ext_attrs in itertools.groupby(
sorted_ext_attrs, key=lambda x: x.key)
}
+ self._keys = None
+ self._length = None
+ self._on_ext_attrs_updated()
+
+ def _on_ext_attrs_updated(self):
self._keys = tuple(sorted(self._ext_attrs.keys()))
- self._length = len(sorted_ext_attrs)
+ self._length = 0
+ for ext_attrs in self._ext_attrs.values():
+ self._length += len(ext_attrs)
@classmethod
def equals(cls, lhs, rhs):
@@ -256,3 +265,26 @@ class ExtendedAttributes(object):
"""Returns self.get(key).values if the key exists or an empty list."""
ext_attr = self.get(key)
return ext_attr.values if ext_attr else ()
+
+ def _append(self, ext_attr):
+ assert isinstance(ext_attr, ExtendedAttribute)
+
+ if ext_attr.key not in self._ext_attrs:
+ self._ext_attrs[ext_attr.key] = (ext_attr, )
+ else:
+ self._ext_attrs[ext_attr.key] = (tuple(
+ sorted(
+ self._ext_attrs[ext_attr.key] + (ext_attr, ),
+ key=lambda x: x.syntactic_form)))
+ self._on_ext_attrs_updated()
+
+
+class ExtendedAttributesMutable(ExtendedAttributes):
+ def __getstate__(self):
+ assert False, "ExtendedAttributesMutable must not be pickled."
+
+ def __setstate__(self, state):
+ assert False, "ExtendedAttributesMutable must not be pickled."
+
+ def append(self, ext_attr):
+ self._append(ext_attr)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/extended_attribute_test.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/extended_attribute_test.py
index b4d4876ec74..2e4144f0477 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/extended_attribute_test.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/extended_attribute_test.py
@@ -1,7 +1,6 @@
# 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.
-
"""Unit tests for extended_attributes.py."""
import unittest
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/file_io.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/file_io.py
index 9136a41a3b0..19e3327a8fb 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/file_io.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/file_io.py
@@ -3,14 +3,19 @@
# found in the LICENSE file.
import os
-import pickle
+import sys
+
+if sys.version_info.major == 2:
+ import cPickle as pickle # 'cPickle' is faster than 'pickle' on Py2
+else:
+ import pickle
def read_pickle_file(filepath):
"""
Reads the content of the file as a pickled object.
"""
- with open(filepath, 'r') as file_obj:
+ with open(filepath, 'rb') as file_obj:
return pickle.load(file_obj)
@@ -30,7 +35,7 @@ def write_to_file_if_changed(filepath, contents):
Returns True if the data is written to the file, and False if skipped.
"""
try:
- with open(filepath, 'r') as file_obj:
+ with open(filepath, 'rb') as file_obj:
old_contents = file_obj.read()
except (OSError, EnvironmentError):
pass
@@ -38,6 +43,10 @@ def write_to_file_if_changed(filepath, contents):
if contents == old_contents:
return False
os.remove(filepath)
- with open(filepath, 'w') as file_obj:
+
+ if not os.path.exists(os.path.dirname(filepath)):
+ os.makedirs(os.path.dirname(filepath))
+
+ with open(filepath, 'wb') as file_obj:
file_obj.write(contents)
return True
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/function_like.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/function_like.py
index 223a93fa09b..648c70d803d 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/function_like.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/function_like.py
@@ -242,11 +242,10 @@ class OverloadGroup(WithIdentifier):
# step 1. If one type includes a nullable type and the other type either
# includes a nullable type, is a union type with flattened member
# types including a dictionary type, or is a dictionary type, ...
- type1_nullable = (idl_type1.does_include_nullable_type
- or idl_type1.unwrap().is_dictionary)
- type2_nullable = (idl_type2.does_include_nullable_type
- or idl_type2.unwrap().is_dictionary)
- if type1_nullable and type2_nullable:
+ if ((idl_type1.does_include_nullable_type
+ and idl_type2.does_include_nullable_or_dict)
+ or (idl_type2.does_include_nullable_type
+ and idl_type1.does_include_nullable_or_dict)):
return False
type1 = idl_type1.unwrap()
@@ -272,6 +271,9 @@ class OverloadGroup(WithIdentifier):
return True
# step 4. Consider the two "innermost" types ...
+ def is_string_type(idl_type):
+ return idl_type.is_string or idl_type.is_enumeration
+
def is_interface_like(idl_type):
return idl_type.is_interface or idl_type.is_buffer_source_type
@@ -292,11 +294,11 @@ class OverloadGroup(WithIdentifier):
return not type2.is_boolean
if type1.is_numeric:
return not type2.is_numeric
- if type1.is_string:
- return not type2.is_string
+ if is_string_type(type1):
+ return not is_string_type(type2)
if type1.is_object:
- return (type2.is_boolean or type2.is_numeric or type2.is_string
- or type2.is_symbol)
+ return (type2.is_boolean or type2.is_numeric
+ or is_string_type(type2) or type2.is_symbol)
if type1.is_symbol:
return not type2.is_symbol
if is_interface_like(type1):
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/idl_compiler.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/idl_compiler.py
index 847ba334683..e7c2cd0f615 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/idl_compiler.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/idl_compiler.py
@@ -4,6 +4,9 @@
import functools
import itertools
+import posixpath
+
+from blinkbuild.name_style_converter import NameStyleConverter
from .callback_function import CallbackFunction
from .callback_interface import CallbackInterface
@@ -13,8 +16,12 @@ from .database import Database
from .database import DatabaseBody
from .dictionary import Dictionary
from .enumeration import Enumeration
+from .exposure import ExposureMutable
+from .extended_attribute import ExtendedAttribute
+from .extended_attribute import ExtendedAttributesMutable
from .idl_type import IdlTypeFactory
from .interface import Interface
+from .interface import LegacyWindowAlias
from .ir_map import IRMap
from .make_copy import make_copy
from .namespace import Namespace
@@ -76,9 +83,15 @@ class IdlCompiler(object):
assert not self._did_run
self._did_run = True
+ # Remove the interface members that are specific to the old bindings
+ # generator, i.e. that are not necessary for (or even harmful to) the
+ # new bindings generator.
+ self._remove_legacy_interface_members()
+
# Merge partial definitions.
self._record_defined_in_partial_and_mixin()
self._propagate_extattrs_per_idl_fragment()
+ self._determine_blink_headers()
self._merge_partial_interface_likes()
self._merge_partial_dictionaries()
# Merge mixins.
@@ -88,10 +101,15 @@ class IdlCompiler(object):
# Process inheritances.
self._process_interface_inheritances()
+ self._copy_named_constructor_extattrs()
+
# Make groups of overloaded functions including inherited ones.
self._group_overloaded_functions()
+ self._propagate_extattrs_to_overload_group()
self._calculate_group_exposure()
+ self._fill_exposed_constructs()
+
self._sort_dictionary_members()
# Updates on IRs are finished. Create API objects.
@@ -107,6 +125,28 @@ class IdlCompiler(object):
return Database(self._db)
+ def _maybe_make_copy(self, ir):
+ # You can make this function return make_copy(ir) for debugging
+ # purpose, etc.
+ return ir # Skip copying as an optimization.
+
+ def _remove_legacy_interface_members(self):
+ old_irs = self._ir_map.irs_of_kinds(
+ IRMap.IR.Kind.INTERFACE, IRMap.IR.Kind.INTERFACE_MIXIN,
+ IRMap.IR.Kind.PARTIAL_INTERFACE,
+ IRMap.IR.Kind.PARTIAL_INTERFACE_MIXIN)
+
+ not_disabled = (
+ lambda x: 'DisableInNewIDLCompiler' not in x.extended_attributes)
+
+ self._ir_map.move_to_new_phase()
+
+ for old_ir in old_irs:
+ new_ir = make_copy(old_ir)
+ self._ir_map.add(new_ir)
+ new_ir.attributes = filter(not_disabled, new_ir.attributes)
+ new_ir.operations = filter(not_disabled, new_ir.operations)
+
def _record_defined_in_partial_and_mixin(self):
old_irs = self._ir_map.irs_of_kinds(
IRMap.IR.Kind.DICTIONARY, IRMap.IR.Kind.INTERFACE,
@@ -118,13 +158,19 @@ class IdlCompiler(object):
self._ir_map.move_to_new_phase()
for old_ir in old_irs:
- new_ir = make_copy(old_ir)
+ new_ir = self._maybe_make_copy(old_ir)
self._ir_map.add(new_ir)
+ is_partial = False
+ is_mixin = False
+ if 'LegacyTreatAsPartialInterface' in new_ir.extended_attributes:
+ is_partial = True
+ elif hasattr(new_ir, 'is_partial') and new_ir.is_partial:
+ is_partial = True
+ elif hasattr(new_ir, 'is_mixin') and new_ir.is_mixin:
+ is_mixin = True
for member in new_ir.iter_all_members():
- member.code_generator_info.set_defined_in_partial(
- hasattr(new_ir, 'is_partial') and new_ir.is_partial)
- member.code_generator_info.set_defined_in_mixin(
- hasattr(new_ir, 'is_mixin') and new_ir.is_mixin)
+ member.code_generator_info.set_defined_in_partial(is_partial)
+ member.code_generator_info.set_defined_in_mixin(is_mixin)
def _propagate_extattrs_per_idl_fragment(self):
def propagate_extattr(extattr_key_and_attr_name,
@@ -164,14 +210,14 @@ class IdlCompiler(object):
if not hasattr(ir, 'iter_all_members'):
return
if (only_to_members_of_partial_or_mixin
- and ((hasattr(ir, 'is_partial') and ir.is_partial) or
- (hasattr(ir, 'is_mixin') and ir.is_mixin))):
+ and not ((hasattr(ir, 'is_partial') and ir.is_partial) or
+ (hasattr(ir, 'is_mixin') and ir.is_mixin))):
return
for member in ir.iter_all_members():
apply_to(member)
def process_interface_like(ir):
- ir = make_copy(ir)
+ ir = self._maybe_make_copy(ir)
self._ir_map.add(ir)
propagate = functools.partial(propagate_extattr, ir=ir)
@@ -207,6 +253,33 @@ class IdlCompiler(object):
map(process_interface_like, old_irs)
+ def _determine_blink_headers(self):
+ irs = self._ir_map.irs_of_kinds(
+ IRMap.IR.Kind.INTERFACE, IRMap.IR.Kind.INTERFACE_MIXIN,
+ IRMap.IR.Kind.NAMESPACE, IRMap.IR.Kind.PARTIAL_INTERFACE,
+ IRMap.IR.Kind.PARTIAL_INTERFACE_MIXIN,
+ IRMap.IR.Kind.PARTIAL_NAMESPACE)
+
+ self._ir_map.move_to_new_phase()
+
+ for old_ir in irs:
+ new_ir = self._maybe_make_copy(old_ir)
+ self._ir_map.add(new_ir)
+
+ if (new_ir.is_mixin and 'LegacyTreatAsPartialInterface' not in
+ new_ir.extended_attributes):
+ continue
+
+ basepath, _ = posixpath.splitext(
+ new_ir.debug_info.location.filepath)
+ dirpath, filename = posixpath.split(basepath)
+ impl_class = new_ir.extended_attributes.value_of('ImplementedAs')
+ if impl_class:
+ filename = NameStyleConverter(impl_class).to_snake_case()
+ header = posixpath.join(dirpath,
+ posixpath.extsep.join([filename, 'h']))
+ new_ir.code_generator_info.set_blink_headers([header])
+
def _merge_partial_interface_likes(self):
irs = self._ir_map.irs_of_kinds(IRMap.IR.Kind.INTERFACE,
IRMap.IR.Kind.INTERFACE_MIXIN,
@@ -231,7 +304,7 @@ class IdlCompiler(object):
self._ir_map.move_to_new_phase()
- for identifier, old_dictionary in old_dictionaries.iteritems():
+ for identifier, old_dictionary in old_dictionaries.items():
new_dictionary = make_copy(old_dictionary)
self._ir_map.add(new_dictionary)
for partial_dictionary in old_partial_dictionaries.get(
@@ -248,7 +321,7 @@ class IdlCompiler(object):
self._ir_map.move_to_new_phase()
for old_ir in mixins:
- new_ir = make_copy(old_ir)
+ new_ir = self._maybe_make_copy(old_ir)
self._ir_map.add(new_ir)
ref_to_mixin = self._ref_to_idl_def_factory.create(
new_ir.identifier)
@@ -263,7 +336,7 @@ class IdlCompiler(object):
ir_sets_to_merge = [(interface, [
mixins[include.mixin_identifier]
for include in includes.get(identifier, [])
- ]) for identifier, interface in interfaces.iteritems()]
+ ]) for identifier, interface in interfaces.items()]
self._ir_map.move_to_new_phase()
@@ -275,33 +348,56 @@ class IdlCompiler(object):
self._ir_map.add(new_ir)
for ir in irs_to_be_merged:
to_be_merged = make_copy(ir)
- new_ir.add_components(to_be_merged.components)
+ if new_ir.is_mixin == to_be_merged.is_mixin:
+ new_ir.add_components(to_be_merged.components)
new_ir.debug_info.add_locations(
to_be_merged.debug_info.all_locations)
new_ir.attributes.extend(to_be_merged.attributes)
new_ir.constants.extend(to_be_merged.constants)
new_ir.operations.extend(to_be_merged.operations)
- def _process_interface_inheritances(self):
- def is_own_member(member):
- return 'Unforgeable' in member.extended_attributes
+ new_ir_headers = new_ir.code_generator_info.blink_headers
+ to_be_merged_headers = (
+ to_be_merged.code_generator_info.blink_headers)
+ if (new_ir_headers is not None
+ and to_be_merged_headers is not None):
+ new_ir_headers.extend(to_be_merged_headers)
- def create_inheritance_stack(obj, table):
+ def _process_interface_inheritances(self):
+ def create_inheritance_chain(obj, table):
if obj.inherited is None:
return [obj]
- return [obj] + create_inheritance_stack(
+ return [obj] + create_inheritance_chain(
table[obj.inherited.identifier], table)
+ inherited_ext_attrs = (
+ # (IDL extended attribute to be inherited,
+ # CodeGeneratorInfoMutable's set function)
+ ('ActiveScriptWrappable', 'set_is_active_script_wrappable'),
+ ('LegacyUnenumerableNamedProperties',
+ 'set_is_legacy_unenumerable_named_properties'),
+ )
+
+ def is_own_member(member):
+ return 'Unforgeable' in member.extended_attributes
+
old_interfaces = self._ir_map.find_by_kind(IRMap.IR.Kind.INTERFACE)
self._ir_map.move_to_new_phase()
- for old_interface in old_interfaces.itervalues():
+ for old_interface in old_interfaces.values():
new_interface = make_copy(old_interface)
self._ir_map.add(new_interface)
- inheritance_stack = create_inheritance_stack(
+ inheritance_chain = create_inheritance_chain(
old_interface, old_interfaces)
- for interface in inheritance_stack[1:]:
+
+ for interface in inheritance_chain:
+ for ext_attr, set_func in inherited_ext_attrs:
+ if ext_attr in interface.extended_attributes:
+ getattr(new_interface.code_generator_info,
+ set_func)(True)
+
+ for interface in inheritance_chain[1:]:
new_interface.attributes.extend([
make_copy(attribute) for attribute in interface.attributes
if is_own_member(attribute)
@@ -311,6 +407,28 @@ class IdlCompiler(object):
if is_own_member(operation)
])
+ def _copy_named_constructor_extattrs(self):
+ old_irs = self._ir_map.irs_of_kind(IRMap.IR.Kind.INTERFACE)
+
+ self._ir_map.move_to_new_phase()
+
+ def copy_extattrs(ext_attrs, ir):
+ if 'NamedConstructor_CallWith' in ext_attrs:
+ ir.extended_attributes.append(
+ ExtendedAttribute(
+ key='CallWith',
+ values=ext_attrs.values_of(
+ 'NamedConstructor_CallWith')))
+ if 'NamedConstructor_RaisesException' in ext_attrs:
+ ir.extended_attributes.append(
+ ExtendedAttribute(key='RaisesException'))
+
+ for old_ir in old_irs:
+ new_ir = self._maybe_make_copy(old_ir)
+ self._ir_map.add(new_ir)
+ for named_constructor_ir in new_ir.named_constructors:
+ copy_extattrs(new_ir.extended_attributes, named_constructor_ir)
+
def _group_overloaded_functions(self):
old_irs = self._ir_map.irs_of_kinds(IRMap.IR.Kind.CALLBACK_INTERFACE,
IRMap.IR.Kind.INTERFACE,
@@ -320,8 +438,9 @@ class IdlCompiler(object):
for old_ir in old_irs:
assert not old_ir.constructor_groups
+ assert not old_ir.named_constructor_groups
assert not old_ir.operation_groups
- new_ir = make_copy(old_ir)
+ new_ir = self._maybe_make_copy(old_ir)
self._ir_map.add(new_ir)
sort_key = lambda x: x.identifier
new_ir.constructor_groups = [
@@ -329,6 +448,12 @@ class IdlCompiler(object):
for identifier, constructors in itertools.groupby(
sorted(new_ir.constructors, key=sort_key), key=sort_key)
]
+ new_ir.named_constructor_groups = [
+ ConstructorGroup.IR(constructors=list(constructors))
+ for identifier, constructors in itertools.groupby(
+ sorted(new_ir.named_constructors, key=sort_key),
+ key=sort_key)
+ ]
new_ir.operation_groups = [
OperationGroup.IR(operations=list(operations))
for identifier, operations in itertools.groupby(
@@ -336,6 +461,33 @@ class IdlCompiler(object):
if identifier
]
+ def _propagate_extattrs_to_overload_group(self):
+ ANY_OF = ('CrossOrigin', 'Custom', 'LenientThis', 'NotEnumerable',
+ 'PerWorldBindings', 'SecureContext', 'Unforgeable',
+ 'Unscopable')
+
+ old_irs = self._ir_map.irs_of_kinds(IRMap.IR.Kind.INTERFACE,
+ IRMap.IR.Kind.NAMESPACE)
+
+ self._ir_map.move_to_new_phase()
+
+ for old_ir in old_irs:
+ new_ir = self._maybe_make_copy(old_ir)
+ self._ir_map.add(new_ir)
+
+ for group in itertools.chain(new_ir.constructor_groups,
+ new_ir.named_constructor_groups,
+ new_ir.operation_groups):
+ for key in ANY_OF:
+ if any(key in overload.extended_attributes
+ for overload in group):
+ group.extended_attributes.append(
+ ExtendedAttribute(key=key))
+ if all((overload.extended_attributes.value_of('Affects') ==
+ 'Nothing') for overload in group):
+ group.extended_attributes.append(
+ ExtendedAttribute(key='Affects', values='Nothing'))
+
def _calculate_group_exposure(self):
old_irs = self._ir_map.irs_of_kinds(IRMap.IR.Kind.INTERFACE,
IRMap.IR.Kind.NAMESPACE)
@@ -343,10 +495,12 @@ class IdlCompiler(object):
self._ir_map.move_to_new_phase()
for old_ir in old_irs:
- new_ir = make_copy(old_ir)
+ new_ir = self._maybe_make_copy(old_ir)
self._ir_map.add(new_ir)
- for group in new_ir.constructor_groups + new_ir.operation_groups:
+ for group in itertools.chain(new_ir.constructor_groups,
+ new_ir.named_constructor_groups,
+ new_ir.operation_groups):
exposures = map(lambda overload: overload.exposure, group)
# [Exposed]
@@ -393,6 +547,66 @@ class IdlCompiler(object):
]))
group.exposure.set_only_in_secure_contexts(flag_names)
+ def _fill_exposed_constructs(self):
+ old_interfaces = self._ir_map.irs_of_kind(IRMap.IR.Kind.INTERFACE)
+ old_namespaces = self._ir_map.irs_of_kind(IRMap.IR.Kind.NAMESPACE)
+
+ def make_legacy_window_alias(ir):
+ ext_attrs = ir.extended_attributes
+ identifier = Identifier(ext_attrs.value_of('LegacyWindowAlias'))
+ original = self._ref_to_idl_def_factory.create(ir.identifier)
+ extended_attributes = ExtendedAttributesMutable()
+ exposure = ExposureMutable()
+ if 'LegacyWindowAlias_Measure' in ext_attrs:
+ extended_attributes.append(
+ ExtendedAttribute(
+ key='Measure',
+ values=ext_attrs.value_of(
+ 'LegacyWindowAlias_Measure')))
+ if 'LegacyWindowAlias_RuntimeEnabled' in ext_attrs:
+ feature_name = ext_attrs.value_of(
+ 'LegacyWindowAlias_RuntimeEnabled')
+ extended_attributes.append(
+ ExtendedAttribute(
+ key='RuntimeEnabled', values=feature_name))
+ exposure.add_runtime_enabled_feature(feature_name)
+ return LegacyWindowAlias(
+ identifier=identifier,
+ original=original,
+ extended_attributes=extended_attributes,
+ exposure=exposure)
+
+ exposed_map = {} # global name: [construct's identifier...]
+ legacy_window_aliases = []
+ for ir in itertools.chain(old_interfaces, old_namespaces):
+ for pair in ir.exposure.global_names_and_features:
+ exposed_map.setdefault(pair.global_name,
+ []).append(ir.identifier)
+ if 'LegacyWindowAlias' in ir.extended_attributes:
+ legacy_window_aliases.append(make_legacy_window_alias(ir))
+
+ self._ir_map.move_to_new_phase()
+
+ for old_ir in old_interfaces:
+ new_ir = self._maybe_make_copy(old_ir)
+ self._ir_map.add(new_ir)
+
+ assert not new_ir.exposed_constructs
+ global_names = new_ir.extended_attributes.values_of('Global')
+ if not global_names:
+ continue
+ constructs = set()
+ for global_name in global_names:
+ constructs.update(exposed_map.get(global_name, []))
+ new_ir.exposed_constructs = map(
+ self._ref_to_idl_def_factory.create, sorted(constructs))
+
+ assert not new_ir.legacy_window_aliases
+ if new_ir.identifier != 'Window':
+ continue
+ new_ir.legacy_window_aliases = sorted(
+ legacy_window_aliases, key=lambda x: x.identifier)
+
def _sort_dictionary_members(self):
"""Sorts dictionary members in alphabetical order."""
old_irs = self._ir_map.irs_of_kind(IRMap.IR.Kind.DICTIONARY)
@@ -400,7 +614,7 @@ class IdlCompiler(object):
self._ir_map.move_to_new_phase()
for old_ir in old_irs:
- new_ir = make_copy(old_ir)
+ new_ir = self._maybe_make_copy(old_ir)
self._ir_map.add(new_ir)
new_ir.own_members.sort(key=lambda x: x.identifier)
@@ -455,9 +669,10 @@ class IdlCompiler(object):
idl_def = StubUserDefinedType(ref.identifier)
if isinstance(idl_def, UserDefinedType):
idl_type = self._idl_type_factory.definition_type(
- user_defined_type=idl_def)
+ reference_type=ref, user_defined_type=idl_def)
elif isinstance(idl_def, Typedef):
- idl_type = self._idl_type_factory.typedef_type(typedef=idl_def)
+ idl_type = self._idl_type_factory.typedef_type(
+ reference_type=ref, typedef=idl_def)
else:
assert False
ref.set_target_object(idl_type)
@@ -478,12 +693,20 @@ class IdlCompiler(object):
Returns an unique (but meaningless) key. Returns the same key for
the identical union types.
"""
- key_pieces = sorted([
- idl_type.syntactic_form
- for idl_type in union_type.flattened_member_types
- ])
- if union_type.does_include_nullable_type:
- key_pieces.append('type null') # something unique
+ # TODO(peria, yukishiino): Produce unique union names. Trying to
+ # produce the names compatible to the old bindings generator for
+ # the time being.
+ key_pieces = []
+
+ def flatten_member_types(idl_type):
+ idl_type = idl_type.unwrap()
+ if idl_type.is_union:
+ for member_type in idl_type.member_types:
+ flatten_member_types(member_type)
+ else:
+ key_pieces.append(idl_type.syntactic_form)
+
+ flatten_member_types(union_type)
return '|'.join(key_pieces)
grouped_unions = {} # {unique key: list of union types}
@@ -493,16 +716,15 @@ class IdlCompiler(object):
grouped_typedefs = {} # {unique key: list of typedefs to the union}
all_typedefs = self._db.find_by_kind(DatabaseBody.Kind.TYPEDEF)
- for typedef in all_typedefs.itervalues():
+ for typedef in all_typedefs.values():
if not typedef.idl_type.is_union:
continue
key = unique_key(typedef.idl_type)
grouped_typedefs.setdefault(key, []).append(typedef)
- for key, union_types in grouped_unions.iteritems():
+ for key, union_types in grouped_unions.items():
self._db.register(
DatabaseBody.Kind.UNION,
Union(
- Identifier(key), # dummy identifier
union_types=union_types,
typedef_backrefs=grouped_typedefs.get(key, [])))
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/idl_type.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/idl_type.py
index 8c63a4998bd..1d7ae802659 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/idl_type.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/idl_type.py
@@ -2,7 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import exceptions
import functools
from blinkbuild.name_style_converter import NameStyleConverter
@@ -48,13 +47,8 @@ class IdlTypeFactory(object):
def __init__(self):
self._idl_types = []
# Factory to initialize instances of ReferenceType.
- attrs_to_be_proxied = (
- set(RefById.get_all_attributes(IdlType)).difference(
- # attributes not to be proxied
- set(('debug_info', 'extended_attributes', 'is_optional',
- 'optionality'))))
self._ref_by_id_factory = RefByIdFactory(
- target_attrs_with_priority=attrs_to_be_proxied)
+ target_attrs_with_priority=RefById.get_all_attributes(IdlType))
# |_is_frozen| is initially False and you can create new instances of
# IdlType. The first invocation of |for_each| freezes the factory and
# you can no longer create a new instance of IdlType.
@@ -167,7 +161,8 @@ class IdlType(WithExtendedAttributes, WithDebugInfo):
pass_key=None):
assert isinstance(is_optional, bool)
assert pass_key is _IDL_TYPE_PASS_KEY
- WithExtendedAttributes.__init__(self, extended_attributes)
+ WithExtendedAttributes.__init__(
+ self, extended_attributes, readonly=True)
WithDebugInfo.__init__(self, debug_info)
self._is_optional = is_optional
@@ -182,7 +177,7 @@ class IdlType(WithExtendedAttributes, WithDebugInfo):
return not self == other
def __hash__(self):
- raise exceptions.NotImplementedError()
+ raise NotImplementedError()
def make_copy(self, memo):
return self
@@ -192,7 +187,7 @@ class IdlType(WithExtendedAttributes, WithDebugInfo):
"""
Returns a text representation of the type in the form of Web IDL syntax.
"""
- raise exceptions.NotImplementedError()
+ raise NotImplementedError()
@property
def type_name(self):
@@ -201,7 +196,23 @@ class IdlType(WithExtendedAttributes, WithDebugInfo):
https://heycam.github.io/webidl/#dfn-type-name
Note that a type name is not necessarily unique.
"""
- raise exceptions.NotImplementedError()
+ return '{}{}'.format(
+ self.type_name_without_extended_attributes, ''.join(
+ sorted(self.effective_annotations.keys())))
+
+ @property
+ def type_name_with_extended_attribute_key_values(self):
+ name_pieces = []
+ name_pieces.append(self.type_name_without_extended_attributes)
+ annotations = self.effective_annotations
+ for key in sorted(annotations.keys()):
+ name_pieces.append(key)
+ name_pieces.extend(annotations.values_of(key))
+ return ''.join(name_pieces)
+
+ @property
+ def type_name_without_extended_attributes(self):
+ raise NotImplementedError()
@property
def keyword_typename(self):
@@ -220,8 +231,16 @@ class IdlType(WithExtendedAttributes, WithDebugInfo):
In case of x.apply_to_all_composing_elements(callback), |callback| will
be recursively called back on x, x.inner_type, x.element_type,
x.result_type.original_type, etc. if any.
+
+ If |callback| raises a StopIteration, then this function stops
+ traversing deeper than this type (inner type, etc.), however, siblings
+ are still traversed. E.g. For record<K, V>, raising a StopIteration at
+ K doesn't prevent from traversing V.
"""
- callback(self)
+ try:
+ callback(self)
+ except StopIteration:
+ return
def unwrap(self, nullable=None, typedef=None, variadic=None):
"""
@@ -231,6 +250,7 @@ class IdlType(WithExtendedAttributes, WithDebugInfo):
Args:
nullable:
typedef:
+ variadic:
All these arguments take tri-state value: True, False, or None.
True unwraps that type, False stops unwrapping that type. All
of specified arguments' values must be consistent, and mixture
@@ -245,25 +265,51 @@ class IdlType(WithExtendedAttributes, WithDebugInfo):
}
value_counts = {None: 0, False: 0, True: 0}
- for value in switches.itervalues():
+ for value in switches.values():
assert value is None or isinstance(value, bool)
value_counts[value] += 1
assert value_counts[False] == 0 or value_counts[True] == 0, (
"Specify only True or False arguments. Unspecified arguments are "
"automatically set to the opposite value.")
default = value_counts[True] == 0
- for arg, value in switches.iteritems():
+ for arg, value in switches.items():
if value is None:
switches[arg] = default
return self._unwrap(switches)
@property
+ def effective_annotations(self):
+ """
+ Returns the extended attributes associated with this IDL type.
+ https://heycam.github.io/webidl/#idl-type-extended-attribute-associated-with
+
+ For example, given the following IDL fragments,
+
+ typedef [ExtAttr1] long NewLong;
+ void f([ExtAttr2] NewLong arg);
+
+ arg.idl_type.extended_attributes returns [ExtAttr2],
+ arg.idl_type.unwrap().extended_attributes returns [ExtAttr1], and
+ arg.idl_type.effective_annotations returns [ExtAttr1, ExtAttr2].
+ """
+ return self.extended_attributes
+
+ @property
def does_include_nullable_type(self):
"""
- Returns True if |self| includes a nulllable type.
+ Returns True if this type includes a nulllable type.
https://heycam.github.io/webidl/#dfn-includes-a-nullable-type
- @return bool
+ """
+ return False
+
+ @property
+ def does_include_nullable_or_dict(self):
+ """
+ Returns True if this type includes a nullable type or a dictionary type.
+
+ IdlType's own definition of "includes a dictionary type" just follows
+ the definition of "includes a nullable type".
"""
return False
@@ -307,6 +353,11 @@ class IdlType(WithExtendedAttributes, WithDebugInfo):
return False
@property
+ def is_array_buffer_view(self):
+ """Returns True if this is ArrayBufferView."""
+ return False
+
+ @property
def is_data_view(self):
"""Returns True if this is DataView."""
return False
@@ -414,11 +465,6 @@ class IdlType(WithExtendedAttributes, WithDebugInfo):
return False
@property
- def is_annotated(self):
- """Returns True if this is annotated."""
- return bool(self.extended_attributes)
-
- @property
def is_optional(self):
"""
Returns True if this type is used for a non-required dictionary member
@@ -506,6 +552,15 @@ class IdlType(WithExtendedAttributes, WithDebugInfo):
"""
return None
+ @property
+ def union_definition_object(self):
+ """
+ Returns an object that represents an union or None.
+
+ Note that a returned object is not an IdlType. It's of type Union.
+ """
+ return None
+
def _format_syntactic_form(self, syntactic_form_inner):
"""Helper function to implement |syntactic_form|."""
optional_form = 'optional ' if self.is_optional else ''
@@ -514,11 +569,6 @@ class IdlType(WithExtendedAttributes, WithDebugInfo):
return '{}{}{}'.format(optional_form, ext_attr_form,
syntactic_form_inner)
- def _format_type_name(self, type_name_inner):
- """Helper function to implement |type_name|."""
- return '{}{}'.format(type_name_inner, ''.join(
- sorted(self.extended_attributes.keys())))
-
def _unwrap(self, switches):
return self
@@ -539,7 +589,17 @@ class SimpleType(IdlType):
_TYPED_ARRAY_TYPES = ('Int8Array', 'Int16Array', 'Int32Array',
'Uint8Array', 'Uint16Array', 'Uint32Array',
'Uint8ClampedArray', 'Float32Array', 'Float64Array')
- _BUFFER_SOURCE_TYPES = ('ArrayBuffer', 'DataView') + _TYPED_ARRAY_TYPES
+ # ArrayBufferView is not defined as a buffer source type in Web IDL, it's
+ # defined as an union type of all typed array types. However, practically
+ # it's much more convenient and reasonable for most of (if not all) use
+ # cases to treat ArrayBufferView as a buffer source type than as an union
+ # type.
+ # https://heycam.github.io/webidl/#ArrayBufferView
+ #
+ # Note that BufferSource is an union type as defined in Web IDL.
+ # https://heycam.github.io/webidl/#BufferSource
+ _BUFFER_SOURCE_TYPES = (
+ ('ArrayBuffer', 'ArrayBufferView', 'DataView') + _TYPED_ARRAY_TYPES)
_MISC_TYPES = ('any', 'boolean', 'object', 'symbol', 'void')
_VALID_TYPES = set(_NUMERIC_TYPES + _STRING_TYPES + _BUFFER_SOURCE_TYPES +
_MISC_TYPES)
@@ -567,16 +627,14 @@ class SimpleType(IdlType):
def __hash__(self):
return hash(self._name)
- # IdlType overrides
@property
def syntactic_form(self):
return self._format_syntactic_form(self._name)
@property
- def type_name(self):
+ def type_name_without_extended_attributes(self):
name = 'String' if self._name == 'DOMString' else self._name
- return self._format_type_name(
- NameStyleConverter(name).to_upper_camel_case())
+ return NameStyleConverter(name).to_upper_camel_case()
@property
def keyword_typename(self):
@@ -611,6 +669,10 @@ class SimpleType(IdlType):
return self._name == 'ArrayBuffer'
@property
+ def is_array_buffer_view(self):
+ return self._name == 'ArrayBufferView'
+
+ @property
def is_data_view(self):
return self._name == 'DataView'
@@ -672,6 +734,9 @@ class ReferenceType(IdlType, RefById):
def __hash__(self):
return hash(self.identifier)
+ def _unwrap(self, switches):
+ return self.target_object._unwrap(switches)
+
class DefinitionType(IdlType, WithIdentifier):
"""
@@ -682,14 +747,14 @@ class DefinitionType(IdlType, WithIdentifier):
TypedefType and UnionType respectively.
"""
- def __init__(self,
- user_defined_type,
- debug_info=None,
- pass_key=None):
+ def __init__(self, reference_type, user_defined_type, pass_key=None):
+ assert isinstance(reference_type, ReferenceType)
assert isinstance(user_defined_type, UserDefinedType)
IdlType.__init__(
self,
- debug_info=debug_info,
+ is_optional=reference_type.is_optional,
+ extended_attributes=reference_type.extended_attributes,
+ debug_info=reference_type.debug_info,
pass_key=pass_key)
WithIdentifier.__init__(self, user_defined_type.identifier)
self._type_definition_object = user_defined_type
@@ -701,20 +766,19 @@ class DefinitionType(IdlType, WithIdentifier):
def __hash__(self):
return hash(self.identifier)
- # IdlType overrides
@property
def syntactic_form(self):
- assert not self.extended_attributes
- assert not self.is_optional
- return self.identifier
+ return self._format_syntactic_form(self.identifier)
@property
- def type_name(self):
- assert not self.extended_attributes
- assert not self.is_optional
+ def type_name_without_extended_attributes(self):
return self.identifier
@property
+ def does_include_nullable_or_dict(self):
+ return self.is_dictionary
+
+ @property
def is_interface(self):
return self.type_definition_object.is_interface
@@ -750,14 +814,14 @@ class TypedefType(IdlType, WithIdentifier):
can track down the typedef'ed type to |original_type|.
"""
- def __init__(self,
- typedef,
- debug_info=None,
- pass_key=None):
+ def __init__(self, reference_type, typedef, pass_key=None):
+ assert isinstance(reference_type, ReferenceType)
assert isinstance(typedef, Typedef)
IdlType.__init__(
self,
- debug_info=debug_info,
+ is_optional=reference_type.is_optional,
+ extended_attributes=reference_type.extended_attributes,
+ debug_info=reference_type.debug_info,
pass_key=pass_key)
WithIdentifier.__init__(self, typedef.identifier)
self._typedef = typedef
@@ -769,28 +833,40 @@ class TypedefType(IdlType, WithIdentifier):
def __hash__(self):
return hash(self.identifier)
- # IdlType overrides
@property
def syntactic_form(self):
- assert not self.extended_attributes
- assert not self.is_optional
- return self.identifier
+ return self._format_syntactic_form(self.identifier)
@property
- def type_name(self):
- assert not self.extended_attributes
- assert not self.is_optional
- return self.original_type.type_name
+ def type_name_without_extended_attributes(self):
+ return self.original_type.type_name_without_extended_attributes
def apply_to_all_composing_elements(self, callback):
- callback(self)
+ try:
+ callback(self)
+ except StopIteration:
+ return
self.original_type.apply_to_all_composing_elements(callback)
@property
+ def effective_annotations(self):
+ original_annotations = self.original_type.effective_annotations
+ if not self.extended_attributes:
+ return original_annotations
+ if not original_annotations:
+ return self.extended_attributes
+ return ExtendedAttributes(
+ list(self.extended_attributes) + list(original_annotations))
+
+ @property
def does_include_nullable_type(self):
return self.original_type.does_include_nullable_type
@property
+ def does_include_nullable_or_dict(self):
+ return self.original_type.does_include_nullable_or_dict
+
+ @property
def is_typedef(self):
return True
@@ -827,9 +903,11 @@ class _ArrayLikeType(IdlType):
def __hash__(self):
return hash((self.__class__, self.element_type))
- # IdlType overrides
def apply_to_all_composing_elements(self, callback):
- callback(self)
+ try:
+ callback(self)
+ except StopIteration:
+ return
self.element_type.apply_to_all_composing_elements(callback)
@property
@@ -854,16 +932,14 @@ class SequenceType(_ArrayLikeType):
debug_info=debug_info,
pass_key=pass_key)
- # IdlType overrides
@property
def syntactic_form(self):
return self._format_syntactic_form('sequence<{}>'.format(
self.element_type.syntactic_form))
@property
- def type_name(self):
- return self._format_type_name('{}Sequence'.format(
- self.element_type.type_name))
+ def type_name_without_extended_attributes(self):
+ return '{}Sequence'.format(self.element_type.type_name)
@property
def is_sequence(self):
@@ -887,16 +963,14 @@ class FrozenArrayType(_ArrayLikeType):
debug_info=debug_info,
pass_key=pass_key)
- # IdlType overrides
@property
def syntactic_form(self):
return self._format_syntactic_form('FrozenArray<{}>'.format(
self.element_type.syntactic_form))
@property
- def type_name(self):
- return self._format_type_name('{}Array'.format(
- self.element_type.type_name))
+ def type_name_without_extended_attributes(self):
+ return '{}Array'.format(self.element_type.type_name)
@property
def is_frozen_array(self):
@@ -906,17 +980,10 @@ class FrozenArrayType(_ArrayLikeType):
class VariadicType(_ArrayLikeType):
"""Represents a type used for variadic arguments."""
- def __init__(self,
- element_type,
- debug_info=None,
- pass_key=None):
+ def __init__(self, element_type, debug_info=None, pass_key=None):
_ArrayLikeType.__init__(
- self,
- element_type,
- debug_info=debug_info,
- pass_key=pass_key)
+ self, element_type, debug_info=debug_info, pass_key=pass_key)
- # IdlType overrides
@property
def syntactic_form(self):
assert not self.extended_attributes
@@ -924,10 +991,11 @@ class VariadicType(_ArrayLikeType):
return '{}...'.format(self.element_type.syntactic_form)
@property
- def type_name(self):
+ def type_name_without_extended_attributes(self):
# Blink-specific expansion of type name
# The type name of a variadic type is the concatenation of the type
# name of the element type and the string "Variadic".
+ assert not self.extended_attributes
return '{}Variadic'.format(self.element_type.type_name)
@property
@@ -968,19 +1036,21 @@ class RecordType(IdlType):
def __hash__(self):
return hash((self.__class__, self.key_type, self.value_type))
- # IdlType overrides
@property
def syntactic_form(self):
return self._format_syntactic_form('record<{}, {}>'.format(
self.key_type.syntactic_form, self.value_type.syntactic_form))
@property
- def type_name(self):
- return self._format_type_name('{}{}Record'.format(
- self.key_type.type_name, self.value_type.type_name))
+ def type_name_without_extended_attributes(self):
+ return '{}{}Record'.format(self.key_type.type_name,
+ self.value_type.type_name)
def apply_to_all_composing_elements(self, callback):
- callback(self)
+ try:
+ callback(self)
+ except StopIteration:
+ return
self.key_type.apply_to_all_composing_elements(callback)
self.value_type.apply_to_all_composing_elements(callback)
@@ -1022,19 +1092,20 @@ class PromiseType(IdlType):
def __hash__(self):
return hash((self.__class__, self.result_type))
- # IdlType overrides
@property
def syntactic_form(self):
return self._format_syntactic_form('Promise<{}>'.format(
self.result_type.syntactic_form))
@property
- def type_name(self):
- return self._format_type_name('{}Promise'.format(
- self.result_type.type_name))
+ def type_name_without_extended_attributes(self):
+ return '{}Promise'.format(self.result_type.type_name)
def apply_to_all_composing_elements(self, callback):
- callback(self)
+ try:
+ callback(self)
+ except StopIteration:
+ return
self.result_type.apply_to_all_composing_elements(callback)
@property
@@ -1043,10 +1114,7 @@ class PromiseType(IdlType):
@property
def result_type(self):
- """
- Returns the result type.
- @return IdlType
- """
+ """Returns the result type."""
return self._result_type
@@ -1068,6 +1136,7 @@ class UnionType(IdlType):
debug_info=debug_info,
pass_key=pass_key)
self._member_types = tuple(member_types)
+ self._union_definition_object = None
def __eq__(self, other):
"""
@@ -1089,19 +1158,20 @@ class UnionType(IdlType):
functools.reduce(lambda x, idl_type: x + hash(idl_type),
self.member_types, 0)))
- # IdlType overrides
@property
def syntactic_form(self):
return self._format_syntactic_form('({})'.format(' or '.join(
[member.syntactic_form for member in self.member_types])))
@property
- def type_name(self):
- return self._format_type_name('Or'.join(
- [member.type_name for member in self.member_types]))
+ def type_name_without_extended_attributes(self):
+ return 'Or'.join([member.type_name for member in self.member_types])
def apply_to_all_composing_elements(self, callback):
- callback(self)
+ try:
+ callback(self)
+ except StopIteration:
+ return
for member_type in self.member_types:
member_type.apply_to_all_composing_elements(callback)
@@ -1111,6 +1181,11 @@ class UnionType(IdlType):
member.does_include_nullable_type for member in self.member_types)
@property
+ def does_include_nullable_or_dict(self):
+ return any(member.does_include_nullable_or_dict
+ for member in self.member_types)
+
+ @property
def is_union(self):
return True
@@ -1134,6 +1209,17 @@ class UnionType(IdlType):
return set(flatten(self))
+ @property
+ def union_definition_object(self):
+ return self._union_definition_object
+
+ def set_union_definition_object(self, union_definition_object):
+ # In Python2, we need to avoid circular imports.
+ from .union import Union
+ assert isinstance(union_definition_object, Union)
+ assert self._union_definition_object is None
+ self._union_definition_object = union_definition_object
+
class NullableType(IdlType):
"""https://heycam.github.io/webidl/#idl-nullable-type"""
@@ -1160,35 +1246,44 @@ class NullableType(IdlType):
def __hash__(self):
return hash((self.__class__, self.inner_type))
- # IdlType overrides
@property
def syntactic_form(self):
assert not self.extended_attributes
return '{}?'.format(self.inner_type.syntactic_form)
@property
- def type_name(self):
- assert not self.extended_attributes
+ def type_name_without_extended_attributes(self):
# https://heycam.github.io/webidl/#idl-annotated-types
# Web IDL seems not supposing a case of [X] ([Y] Type)?, i.e. something
# like [X] nullable<[Y] Type>, which should turn into "TypeYOrNullX".
#
# In case of '[Clamp] long?', it's interpreted as '([Clamp] long)?' but
# the type name must be "LongOrNullClamp" instead of "LongClampOrNull".
- name = self.inner_type.type_name
- ext_attrs = ''.join(sorted(self.inner_type.extended_attributes.keys()))
- sep_index = len(name) - len(ext_attrs)
- return '{}OrNull{}'.format(name[0:sep_index], name[sep_index:])
+ assert not self.extended_attributes
+ return '{}OrNull'.format(
+ self.inner_type.type_name_without_extended_attributes)
def apply_to_all_composing_elements(self, callback):
- callback(self)
+ try:
+ callback(self)
+ except StopIteration:
+ return
self.inner_type.apply_to_all_composing_elements(callback)
@property
+ def effective_annotations(self):
+ assert not self.extended_attributes
+ return self.inner_type.effective_annotations
+
+ @property
def does_include_nullable_type(self):
return True
@property
+ def does_include_nullable_or_dict(self):
+ return True
+
+ @property
def is_nullable(self):
return True
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/idl_type_test.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/idl_type_test.py
index b8e71989991..b3d097a7442 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/idl_type_test.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/idl_type_test.py
@@ -54,7 +54,7 @@ class IdlTypesTest(unittest.TestCase):
ext_attrs = ExtendedAttributes([ExtendedAttribute('Clamp')])
annotated_type = factory.simple_type(
'short', extended_attributes=ext_attrs)
- self.assertTrue(annotated_type.is_annotated)
+ self.assertTrue(annotated_type.extended_attributes)
self.assertTrue(annotated_type.is_numeric)
optional_type = factory.simple_type('DOMString', is_optional=True)
@@ -63,7 +63,7 @@ class IdlTypesTest(unittest.TestCase):
annotated_optional = factory.simple_type(
'long', is_optional=True, extended_attributes=ext_attrs)
- self.assertTrue(annotated_optional.is_annotated)
+ self.assertTrue(annotated_optional.extended_attributes)
self.assertTrue(annotated_optional.is_optional)
self.assertTrue(annotated_optional.is_numeric)
@@ -83,7 +83,7 @@ class IdlTypesTest(unittest.TestCase):
'void': 'Void',
'symbol': 'Symbol',
}
- for name, expect in type_names.iteritems():
+ for name, expect in type_names.items():
self.assertEqual(expect, factory.simple_type(name).type_name)
short_type = factory.simple_type('short')
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/interface.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/interface.py
index f3f81408a0e..ae67aab3fc9 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/interface.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/interface.py
@@ -9,6 +9,7 @@ from .composition_parts import WithComponent
from .composition_parts import WithDebugInfo
from .composition_parts import WithExposure
from .composition_parts import WithExtendedAttributes
+from .composition_parts import WithIdentifier
from .composition_parts import WithOwner
from .constant import Constant
from .constructor import Constructor
@@ -37,7 +38,9 @@ class Interface(UserDefinedType, WithExtendedAttributes, WithCodeGeneratorInfo,
attributes=None,
constants=None,
constructors=None,
+ named_constructors=None,
operations=None,
+ indexed_and_named_properties=None,
stringifier=None,
iterable=None,
maplike=None,
@@ -52,7 +55,11 @@ class Interface(UserDefinedType, WithExtendedAttributes, WithCodeGeneratorInfo,
assert constants is None or isinstance(constants, (list, tuple))
assert constructors is None or isinstance(constructors,
(list, tuple))
+ assert named_constructors is None or isinstance(
+ named_constructors, (list, tuple))
assert operations is None or isinstance(operations, (list, tuple))
+ assert indexed_and_named_properties is None or isinstance(
+ indexed_and_named_properties, IndexedAndNamedProperties.IR)
assert stringifier is None or isinstance(stringifier,
Stringifier.IR)
assert iterable is None or isinstance(iterable, Iterable)
@@ -62,6 +69,7 @@ class Interface(UserDefinedType, WithExtendedAttributes, WithCodeGeneratorInfo,
attributes = attributes or []
constants = constants or []
constructors = constructors or []
+ named_constructors = named_constructors or []
operations = operations or []
assert all(
isinstance(attribute, Attribute.IR)
@@ -72,6 +80,9 @@ class Interface(UserDefinedType, WithExtendedAttributes, WithCodeGeneratorInfo,
isinstance(constructor, Constructor.IR)
for constructor in constructors)
assert all(
+ isinstance(named_constructor, Constructor.IR)
+ for named_constructor in named_constructors)
+ assert all(
isinstance(operation, Operation.IR)
for operation in operations)
@@ -100,8 +111,13 @@ class Interface(UserDefinedType, WithExtendedAttributes, WithCodeGeneratorInfo,
self.constants = list(constants)
self.constructors = list(constructors)
self.constructor_groups = []
+ self.named_constructors = list(named_constructors)
+ self.named_constructor_groups = []
self.operations = list(operations)
self.operation_groups = []
+ self.exposed_constructs = []
+ self.legacy_window_aliases = []
+ self.indexed_and_named_properties = indexed_and_named_properties
self.stringifier = stringifier
self.iterable = iterable
self.maplike = maplike
@@ -114,6 +130,8 @@ class Interface(UserDefinedType, WithExtendedAttributes, WithCodeGeneratorInfo,
yield constant
for constructor in self.constructors:
yield constructor
+ for named_constructor in self.named_constructors:
+ yield named_constructor
for operation in self.operations:
yield operation
@@ -123,7 +141,7 @@ class Interface(UserDefinedType, WithExtendedAttributes, WithCodeGeneratorInfo,
ir = make_copy(ir)
UserDefinedType.__init__(self, ir.identifier)
- WithExtendedAttributes.__init__(self, ir)
+ WithExtendedAttributes.__init__(self, ir, readonly=True)
WithCodeGeneratorInfo.__init__(self, ir, readonly=True)
WithExposure.__init__(self, ir, readonly=True)
WithComponent.__init__(self, ir, readonly=True)
@@ -144,24 +162,43 @@ class Interface(UserDefinedType, WithExtendedAttributes, WithCodeGeneratorInfo,
])
self._constructor_groups = tuple([
ConstructorGroup(
- constructor_group_ir,
- filter(
- lambda x: x.identifier == constructor_group_ir.identifier,
- self._constructors),
- owner=self) for constructor_group_ir in ir.constructor_groups
+ group_ir,
+ filter(lambda x: x.identifier == group_ir.identifier,
+ self._constructors),
+ owner=self) for group_ir in ir.constructor_groups
])
assert len(self._constructor_groups) <= 1
+ self._named_constructors = tuple([
+ Constructor(named_constructor_ir, owner=self)
+ for named_constructor_ir in ir.named_constructors
+ ])
+ self._named_constructor_groups = tuple([
+ ConstructorGroup(
+ group_ir,
+ filter(lambda x: x.identifier == group_ir.identifier,
+ self._named_constructors),
+ owner=self) for group_ir in ir.named_constructor_groups
+ ])
self._operations = tuple([
Operation(operation_ir, owner=self)
for operation_ir in ir.operations
])
self._operation_groups = tuple([
OperationGroup(
- operation_group_ir,
- filter(lambda x: x.identifier == operation_group_ir.identifier,
+ group_ir,
+ filter(lambda x: x.identifier == group_ir.identifier,
self._operations),
- owner=self) for operation_group_ir in ir.operation_groups
+ owner=self) for group_ir in ir.operation_groups
])
+ self._exposed_constructs = tuple(ir.exposed_constructs)
+ self._legacy_window_aliases = tuple(ir.legacy_window_aliases)
+ self._indexed_and_named_properties = None
+ if ir.indexed_and_named_properties:
+ operations = filter(
+ lambda x: x.is_indexed_or_named_property_operation,
+ self._operations)
+ self._indexed_and_named_properties = IndexedAndNamedProperties(
+ ir.indexed_and_named_properties, operations, owner=self)
self._stringifier = None
if ir.stringifier:
operations = filter(lambda x: x.is_stringifier, self._operations)
@@ -205,6 +242,17 @@ class Interface(UserDefinedType, WithExtendedAttributes, WithCodeGeneratorInfo,
interface = interface.inherited
return result
+ def does_implement(self, identifier):
+ """
+ Returns True if this is or inherits from the given interface.
+ """
+ assert isinstance(identifier, str)
+
+ for interface in self.inclusive_inherited_interfaces:
+ if interface.identifier == identifier:
+ return True
+ return False
+
@property
def attributes(self):
"""
@@ -232,6 +280,16 @@ class Interface(UserDefinedType, WithExtendedAttributes, WithCodeGeneratorInfo,
return self._constructor_groups
@property
+ def named_constructors(self):
+ """Returns named constructors."""
+ return self._named_constructors
+
+ @property
+ def named_constructor_groups(self):
+ """Returns groups of overloaded named constructors."""
+ return self._named_constructor_groups
+
+ @property
def operations(self):
"""
Returns all operations, including special operations without an
@@ -254,38 +312,22 @@ class Interface(UserDefinedType, WithExtendedAttributes, WithCodeGeneratorInfo,
return self._operation_groups
@property
- def named_constructor(self):
- """Returns a named constructor or None."""
- assert False, "Not implemented yet."
-
- @property
- def exposed_interfaces(self):
+ def exposed_constructs(self):
"""
- Returns a tuple of interfaces that are exposed to this interface, if
- this is a global interface. Returns None otherwise.
+ Returns a list of the constructs that are exposed on this global object.
"""
- assert False, "Not implemented yet."
+ return tuple(
+ map(lambda ref: ref.target_object, self._exposed_constructs))
- # Special operations
@property
- def indexed_property_handler(self):
- """
- Returns a set of handlers (getter/setter/deleter) for the indexed
- property.
- @return IndexedPropertyHandler?
- """
- # TODO: Include anonymous handlers of ancestors. https://crbug.com/695972
- assert False, "Not implemented yet."
+ def legacy_window_aliases(self):
+ """Returns a list of properties exposed as [LegacyWindowAlias]."""
+ return self._legacy_window_aliases
@property
- def named_property_handler(self):
- """
- Returns a set of handlers (getter/setter/deleter) for the named
- property.
- @return NamedPropertyHandler?
- """
- # TODO: Include anonymous handlers of ancestors. https://crbug.com/695972
- assert False, "Not implemented yet."
+ def indexed_and_named_properties(self):
+ """Returns a IndexedAndNamedProperties or None."""
+ return self._indexed_and_named_properties
@property
def stringifier(self):
@@ -313,6 +355,183 @@ class Interface(UserDefinedType, WithExtendedAttributes, WithCodeGeneratorInfo,
return True
+class LegacyWindowAlias(WithIdentifier, WithExtendedAttributes, WithExposure):
+ """
+ Represents a property exposed on a Window object as [LegacyWindowAlias].
+ """
+
+ def __init__(self, identifier, original, extended_attributes, exposure):
+ assert isinstance(original, RefById)
+
+ WithIdentifier.__init__(self, identifier)
+ WithExtendedAttributes.__init__(
+ self, extended_attributes, readonly=True)
+ WithExposure.__init__(self, exposure, readonly=True)
+
+ self._original = original
+
+ @property
+ def original(self):
+ """Returns the original object of this alias."""
+ return self._original.target_object
+
+
+class IndexedAndNamedProperties(WithOwner, WithDebugInfo):
+ """
+ Represents a set of indexed/named getter/setter/deleter.
+
+ https://heycam.github.io/webidl/#idl-indexed-properties
+ https://heycam.github.io/webidl/#idl-named-properties
+ """
+
+ class IR(WithDebugInfo):
+ def __init__(self, operations, debug_info=None):
+ assert isinstance(operations, (list, tuple))
+ assert all(
+ isinstance(operation, Operation.IR)
+ for operation in operations)
+
+ WithDebugInfo.__init__(self, debug_info)
+
+ self.indexed_getter = None
+ self.indexed_setter = None
+ self.named_getter = None
+ self.named_setter = None
+ self.named_deleter = None
+
+ for operation in operations:
+ arg1_type = operation.arguments[0].idl_type
+ if arg1_type.is_integer:
+ if operation.is_getter:
+ assert self.indexed_getter is None
+ self.indexed_getter = operation
+ elif operation.is_setter:
+ assert self.indexed_setter is None
+ self.indexed_setter = operation
+ else:
+ assert False
+ elif arg1_type.is_string:
+ if operation.is_getter:
+ assert self.named_getter is None
+ self.named_getter = operation
+ elif operation.is_setter:
+ assert self.named_setter is None
+ self.named_setter = operation
+ elif operation.is_deleter:
+ assert self.named_deleter is None
+ self.named_deleter = operation
+ else:
+ assert False
+ else:
+ assert False
+
+ def __init__(self, ir, operations, owner):
+ assert isinstance(ir, IndexedAndNamedProperties.IR)
+ assert isinstance(operations, (list, tuple))
+ assert all(
+ isinstance(operation, Operation) for operation in operations)
+
+ WithOwner.__init__(self, owner)
+ WithDebugInfo.__init__(self, ir)
+
+ self._own_indexed_getter = None
+ self._own_indexed_setter = None
+ self._own_named_getter = None
+ self._own_named_setter = None
+ self._own_named_deleter = None
+
+ for operation in operations:
+ arg1_type = operation.arguments[0].idl_type
+ if arg1_type.is_integer:
+ if operation.is_getter:
+ assert self._own_indexed_getter is None
+ self._own_indexed_getter = operation
+ elif operation.is_setter:
+ assert self._own_indexed_setter is None
+ self._own_indexed_setter = operation
+ else:
+ assert False
+ elif arg1_type.is_string:
+ if operation.is_getter:
+ assert self._own_named_getter is None
+ self._own_named_getter = operation
+ elif operation.is_setter:
+ assert self._own_named_setter is None
+ self._own_named_setter = operation
+ elif operation.is_deleter:
+ assert self._own_named_deleter is None
+ self._own_named_deleter = operation
+ else:
+ assert False
+ else:
+ assert False
+
+ @property
+ def has_indexed_properties(self):
+ return self.indexed_getter or self.indexed_setter
+
+ @property
+ def has_named_properties(self):
+ return self.named_getter or self.named_setter or self.named_deleter
+
+ @property
+ def is_named_property_enumerable(self):
+ named_getter = self.named_getter
+ return bool(named_getter
+ and 'NotEnumerable' not in named_getter.extended_attributes
+ and 'LegacyUnenumerableNamedProperties' not in self.owner.
+ extended_attributes)
+
+ @property
+ def indexed_getter(self):
+ return self._find_accessor('own_indexed_getter')
+
+ @property
+ def indexed_setter(self):
+ return self._find_accessor('own_indexed_setter')
+
+ @property
+ def named_getter(self):
+ return self._find_accessor('own_named_getter')
+
+ @property
+ def named_setter(self):
+ return self._find_accessor('own_named_setter')
+
+ @property
+ def named_deleter(self):
+ return self._find_accessor('own_named_deleter')
+
+ @property
+ def own_indexed_getter(self):
+ return self._own_indexed_getter
+
+ @property
+ def own_indexed_setter(self):
+ return self._own_indexed_setter
+
+ @property
+ def own_named_getter(self):
+ return self._own_named_getter
+
+ @property
+ def own_named_setter(self):
+ return self._own_named_setter
+
+ @property
+ def own_named_deleter(self):
+ return self._own_named_deleter
+
+ def _find_accessor(self, attr):
+ for interface in self.owner.inclusive_inherited_interfaces:
+ props = interface.indexed_and_named_properties
+ if props:
+ accessor = getattr(props, attr)
+ if accessor:
+ return accessor
+ return None
+
+
class Stringifier(WithOwner, WithDebugInfo):
"""https://heycam.github.io/webidl/#idl-stringifiers"""
@@ -349,10 +568,7 @@ class Stringifier(WithOwner, WithDebugInfo):
class Iterable(WithDebugInfo):
"""https://heycam.github.io/webidl/#idl-iterable"""
- def __init__(self,
- key_type=None,
- value_type=None,
- debug_info=None):
+ def __init__(self, key_type=None, value_type=None, debug_info=None):
assert key_type is None or isinstance(key_type, IdlType)
# iterable is declared in either form of
# iterable<value_type>
@@ -423,10 +639,7 @@ class Maplike(WithDebugInfo):
class Setlike(WithDebugInfo):
"""https://heycam.github.io/webidl/#idl-setlike"""
- def __init__(self,
- value_type,
- is_readonly=False,
- debug_info=None):
+ def __init__(self, value_type, is_readonly=False, debug_info=None):
assert isinstance(value_type, IdlType)
assert isinstance(is_readonly, bool)
@@ -450,55 +663,3 @@ class Setlike(WithDebugInfo):
@return bool
"""
return self._is_readonly
-
-
-class IndexedPropertyHandler(object):
- @property
- def getter(self):
- """
- Returns an Operation for indexed property getter.
- @return Operation?
- """
- assert False, "Not implemented yet."
-
- @property
- def setter(self):
- """
- Returns an Operation for indexed property setter.
- @return Operation?
- """
- assert False, "Not implemented yet."
-
- @property
- def deleter(self):
- """
- Returns an Operation for indexed property deleter.
- @return Operation?
- """
- assert False, "Not implemented yet."
-
-
-class NamedPropertyHandler(object):
- @property
- def getter(self):
- """
- Returns an Operation for named property getter.
- @return Operation?
- """
- assert False, "Not implemented yet."
-
- @property
- def setter(self):
- """
- Returns an Operation for named property setter.
- @return Operation?
- """
- assert False, "Not implemented yet."
-
- @property
- def deleter(self):
- """
- Returns an Operation for named property deleter.
- @return Operation?
- """
- assert False, "Not implemented yet."
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/ir_builder.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/ir_builder.py
index bc69ffff13e..5f2fe5f13aa 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/ir_builder.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/ir_builder.py
@@ -20,6 +20,7 @@ from .extended_attribute import ExtendedAttribute
from .extended_attribute import ExtendedAttributes
from .idl_type import IdlTypeFactory
from .includes import Includes
+from .interface import IndexedAndNamedProperties
from .interface import Interface
from .interface import Iterable
from .interface import Maplike
@@ -114,6 +115,7 @@ class _IRBuilder(object):
constants = []
constructors = []
operations = []
+ indexed_and_named_property_operations = []
for member in members:
if isinstance(member, Attribute.IR):
attributes.append(member)
@@ -122,16 +124,24 @@ class _IRBuilder(object):
elif isinstance(member, Constructor.IR):
constructors.append(member)
elif isinstance(member, Operation.IR):
- if member.identifier:
- operations.append(member)
+ operations.append(member)
+ if member.is_getter or member.is_setter or member.is_deleter:
+ indexed_and_named_property_operations.append(member)
else:
assert False
+ named_constructors = self._build_named_constructors(node)
+
+ indexed_and_named_properties = None
+ if indexed_and_named_property_operations:
+ indexed_and_named_properties = IndexedAndNamedProperties.IR(
+ indexed_and_named_property_operations,
+ self._build_debug_info(node))
+
if stringifier:
operations.append(stringifier.operation)
if stringifier.attribute:
attributes.append(stringifier.attribute)
- # TODO(peria): Create indexed/named property handlers from |operations|.
return Interface.IR(
identifier=identifier,
@@ -141,7 +151,9 @@ class _IRBuilder(object):
attributes=attributes,
constants=constants,
constructors=constructors,
+ named_constructors=named_constructors,
operations=operations,
+ indexed_and_named_properties=indexed_and_named_properties,
stringifier=stringifier,
iterable=iterable,
maplike=maplike,
@@ -189,7 +201,7 @@ class _IRBuilder(object):
idl_type = self._take_type(child_nodes)
extended_attributes = self._take_extended_attributes(
child_nodes) or fallback_extended_attributes
- assert len(child_nodes) == 0
+ assert not child_nodes
return Attribute.IR(
identifier=Identifier(node.GetName()),
idl_type=idl_type,
@@ -223,10 +235,11 @@ class _IRBuilder(object):
arguments = self._take_arguments(child_nodes)
extended_attributes = self._take_extended_attributes(
child_nodes) or fallback_extended_attributes
- assert len(child_nodes) == 0
+ assert not child_nodes
return_type = self._idl_type_factory.reference_type(
interface_identifier)
return Constructor.IR(
+ identifier=None,
arguments=arguments,
return_type=return_type,
extended_attributes=extended_attributes,
@@ -239,12 +252,15 @@ class _IRBuilder(object):
return_type = self._take_type(child_nodes)
extended_attributes = self._take_extended_attributes(
child_nodes) or fallback_extended_attributes
- assert len(child_nodes) == 0
+ assert not child_nodes
return Operation.IR(
identifier=Identifier(node.GetName()),
arguments=arguments,
return_type=return_type,
is_static=bool(node.GetProperty('STATIC')),
+ is_getter=bool(node.GetProperty('GETTER')),
+ is_setter=bool(node.GetProperty('SETTER')),
+ is_deleter=bool(node.GetProperty('DELETER')),
extended_attributes=extended_attributes,
component=self._component,
debug_info=self._build_debug_info(node))
@@ -257,6 +273,37 @@ class _IRBuilder(object):
}
return build_functions[node.GetClass()](node)
+ def _build_named_constructors(self, node):
+ assert node.GetClass() == 'Interface'
+ named_constructors = []
+
+ for child in node.GetChildren():
+ if child.GetClass() == 'ExtAttributes':
+ interface_ext_attrs = child.GetChildren()
+ break
+ else:
+ return named_constructors
+
+ for ext_attr in interface_ext_attrs:
+ if ext_attr.GetName() != 'NamedConstructor':
+ continue
+ call_node = ext_attr.GetChildren()[0]
+ assert call_node.GetClass() == 'Call'
+ child_nodes = list(call_node.GetChildren())
+ arguments = self._take_arguments(child_nodes)
+ return_type = self._idl_type_factory.reference_type(
+ Identifier(node.GetName()))
+ assert not child_nodes
+ named_constructors.append(
+ Constructor.IR(
+ identifier=Identifier(call_node.GetName()),
+ arguments=arguments,
+ return_type=return_type,
+ component=self._component,
+ debug_info=self._build_debug_info(node)))
+
+ return named_constructors
+
def _build_dictionary(self, node):
child_nodes = list(node.GetChildren())
inherited = self._take_inheritance(child_nodes)
@@ -280,7 +327,7 @@ class _IRBuilder(object):
idl_type = self._take_type(child_nodes, is_optional=(not is_required))
default_value = self._take_default_value(child_nodes)
extended_attributes = self._take_extended_attributes(child_nodes)
- assert len(child_nodes) == 0
+ assert not child_nodes
return DictionaryMember.IR(
identifier=Identifier(node.GetName()),
@@ -319,7 +366,7 @@ class _IRBuilder(object):
arguments = self._take_arguments(child_nodes)
return_type = self._take_type(child_nodes)
extended_attributes = self._take_extended_attributes(child_nodes)
- assert len(child_nodes) == 0
+ assert not child_nodes
return CallbackFunction.IR(
identifier=Identifier(node.GetName()),
arguments=arguments,
@@ -343,7 +390,7 @@ class _IRBuilder(object):
def _build_typedef(self, node):
child_nodes = list(node.GetChildren())
idl_type = self._take_type(child_nodes)
- assert len(child_nodes) == 0
+ assert not child_nodes
return Typedef.IR(
identifier=Identifier(node.GetName()),
@@ -375,7 +422,7 @@ class _IRBuilder(object):
is_variadic=is_variadic,
extended_attributes=extended_attributes)
default_value = self._take_default_value(child_nodes)
- assert len(child_nodes) == 0
+ assert not child_nodes
return Argument.IR(
identifier=Identifier(node.GetName()),
index=index,
@@ -408,21 +455,27 @@ class _IRBuilder(object):
key = node.GetName()
values = node.GetProperty('VALUE', default=None)
arguments = None
-
- # Drop constructors as they do not fit in ExtendedAttribute which
- # doesn't support IdlType.
- if key in ('Constructor', 'CustomConstructor', 'NamedConstructor'):
- return None
+ name = None
child_nodes = node.GetChildren()
if child_nodes:
assert len(child_nodes) == 1
- assert child_nodes[0].GetClass() == 'Arguments'
- arguments = map(build_extattr_argument,
- child_nodes[0].GetChildren())
+ child = child_nodes[0]
+ if child.GetClass() == 'Arguments':
+ arguments = map(build_extattr_argument,
+ child.GetChildren())
+ elif child.GetClass() == 'Call':
+ assert len(child.GetChildren()) == 1
+ grand_child = child.GetChildren()[0]
+ assert grand_child.GetClass() == 'Arguments'
+ # ExtendedAttribute is not designed to represent an
+ # operation, especially a complicated argument list.
+ # Discard the arguments.
+ arguments = ()
+ name = child.GetName()
return ExtendedAttribute(
- key=key, values=values, arguments=arguments)
+ key=key, values=values, arguments=arguments, name=name)
def build_extattr_argument(node):
assert node.GetClass() == 'Argument'
@@ -469,7 +522,7 @@ class _IRBuilder(object):
debug_info=self._build_debug_info(node))
def _build_literal_constant(self, node):
- assert len(node.GetChildren()) == 0
+ assert not node.GetChildren()
type_token = node.GetProperty('TYPE')
value_token = node.GetProperty('VALUE')
@@ -523,7 +576,7 @@ class _IRBuilder(object):
value = dict()
literal = '{}'
else:
- assert False, 'Unknown literal type: {}'.format(type_token)
+ assert False, "Unknown literal type: {}".format(type_token)
return LiteralConstant(idl_type=idl_type, value=value, literal=literal)
@@ -688,6 +741,7 @@ class _IRBuilder(object):
buffer_source_types = set([
'ArrayBuffer',
+ 'ArrayBufferView', # Blink-specific ArrayBufferView definition
'DataView',
'Int8Array',
'Int16Array',
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/ir_map.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/ir_map.py
index 4651900f8a6..91806523243 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/ir_map.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/ir_map.py
@@ -190,11 +190,11 @@ class IRMap(object):
"""Returns a flattened list of IRs of the given kind."""
if IRMap.IR.Kind.does_support_multiple_defs(kind):
accumulated = []
- for irs in self.find_by_kind(kind).itervalues():
+ for irs in self.find_by_kind(kind).values():
accumulated.extend(irs)
return accumulated
else:
- return self.find_by_kind(kind).itervalues()
+ return list(self.find_by_kind(kind).values())
def irs_of_kinds(self, *kinds):
"""
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/make_copy.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/make_copy.py
index b9a22ebfaaf..a7a2b11f3f0 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/make_copy.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/make_copy.py
@@ -48,11 +48,11 @@ def make_copy(obj, memo=None):
if isinstance(obj, dict):
return memoize(
cls([(make_copy(key, memo), make_copy(value, memo))
- for key, value in obj.iteritems()]))
+ for key, value in obj.items()]))
if hasattr(obj, '__dict__'):
copy = memoize(cls.__new__(cls))
- for name, value in obj.__dict__.iteritems():
+ for name, value in obj.__dict__.items():
setattr(copy, name, make_copy(value, memo))
return copy
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/migration_adapter.idl b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/migration_adapter.idl
index 38eacc2cfdf..7ede71f3a06 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/migration_adapter.idl
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/migration_adapter.idl
@@ -8,10 +8,6 @@
// and the *.idl files get updated to be spec conformant, almost all (if not
// really all) the followings will be gone.
-typedef object SerializedScriptValue;
-
-typedef object? Dictionary;
-
typedef EventHandlerNonNull? EventHandler;
typedef DOMMatrix DOMMatrixConstructor;
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/namespace.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/namespace.py
index c00d88890cc..6c146122bdf 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/namespace.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/namespace.py
@@ -60,10 +60,13 @@ class Namespace(UserDefinedType, WithExtendedAttributes, WithCodeGeneratorInfo,
WithDebugInfo.__init__(self, debug_info)
self.is_partial = is_partial
+ self.is_mixin = False
self.attributes = list(attributes)
self.constants = list(constants)
self.constructors = []
self.constructor_groups = []
+ self.named_constructors = []
+ self.named_constructor_groups = []
self.operations = list(operations)
self.operation_groups = []
@@ -81,7 +84,7 @@ class Namespace(UserDefinedType, WithExtendedAttributes, WithCodeGeneratorInfo,
ir = make_copy(ir)
UserDefinedType.__init__(self, ir.identifier)
- WithExtendedAttributes.__init__(self, ir)
+ WithExtendedAttributes.__init__(self, ir, readonly=True)
WithCodeGeneratorInfo.__init__(self, ir, readonly=True)
WithExposure.__init__(self, ir, readonly=True)
WithComponent.__init__(self, ir, readonly=True)
@@ -140,3 +143,8 @@ class Namespace(UserDefinedType, WithExtendedAttributes, WithCodeGeneratorInfo,
def operation_groups(self):
"""Returns a list of OperationGroups."""
return self._operation_groups
+
+ @property
+ def exposed_constructs(self):
+ """Returns exposed constructs."""
+ return ()
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/operation.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/operation.py
index d4c66a00041..7613451d93e 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/operation.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/operation.py
@@ -32,9 +32,17 @@ class Operation(FunctionLike, WithExtendedAttributes, WithCodeGeneratorInfo,
arguments,
return_type,
is_static=False,
+ is_getter=False,
+ is_setter=False,
+ is_deleter=False,
extended_attributes=None,
component=None,
debug_info=None):
+ assert isinstance(is_getter, bool)
+ assert isinstance(is_setter, bool)
+ assert isinstance(is_deleter, bool)
+ assert is_getter + is_setter + is_deleter <= 1 # At most 1 True
+
FunctionLike.IR.__init__(
self,
identifier=identifier,
@@ -48,13 +56,16 @@ class Operation(FunctionLike, WithExtendedAttributes, WithCodeGeneratorInfo,
WithComponent.__init__(self, component)
WithDebugInfo.__init__(self, debug_info)
+ self.is_getter = is_getter
+ self.is_setter = is_setter
+ self.is_deleter = is_deleter
self.is_stringifier = False
def __init__(self, ir, owner):
assert isinstance(ir, Operation.IR)
FunctionLike.__init__(self, ir)
- WithExtendedAttributes.__init__(self, ir)
+ WithExtendedAttributes.__init__(self, ir, readonly=True)
WithCodeGeneratorInfo.__init__(self, ir, readonly=True)
WithExposure.__init__(self, ir, readonly=True)
WithOwner.__init__(self, owner)
@@ -62,15 +73,44 @@ class Operation(FunctionLike, WithExtendedAttributes, WithCodeGeneratorInfo,
WithComponent.__init__(self, ir, readonly=True)
WithDebugInfo.__init__(self, ir)
+ self._is_getter = ir.is_getter
+ self._is_setter = ir.is_setter
+ self._is_deleter = ir.is_deleter
self._is_stringifier = ir.is_stringifier
@property
+ def is_special_operation(self):
+ return (self.is_getter or self.is_setter or self.is_deleter
+ or self.is_stringifier)
+
+ @property
+ def is_indexed_or_named_property_operation(self):
+ """
+ Returns True if this is an indexed or named property special operation
+ (one of getter, setter, or deleter).
+ """
+ return self.is_getter or self.is_setter or self.is_deleter
+
+ @property
+ def is_getter(self):
+ return self._is_getter
+
+ @property
+ def is_setter(self):
+ return self._is_setter
+
+ @property
+ def is_deleter(self):
+ return self._is_deleter
+
+ @property
def is_stringifier(self):
return self._is_stringifier
-class OperationGroup(OverloadGroup, WithCodeGeneratorInfo, WithExposure,
- WithOwner, WithComponent, WithDebugInfo):
+class OperationGroup(OverloadGroup, WithExtendedAttributes,
+ WithCodeGeneratorInfo, WithExposure, WithOwner,
+ WithComponent, WithDebugInfo):
"""
Represents a group of operations with the same identifier.
@@ -78,13 +118,15 @@ class OperationGroup(OverloadGroup, WithCodeGeneratorInfo, WithExposure,
the operations are overloaded.
"""
- class IR(OverloadGroup.IR, WithCodeGeneratorInfo, WithExposure,
- WithDebugInfo):
+ class IR(OverloadGroup.IR, WithExtendedAttributes, WithCodeGeneratorInfo,
+ WithExposure, WithDebugInfo):
def __init__(self,
operations,
+ extended_attributes=None,
code_generator_info=None,
debug_info=None):
OverloadGroup.IR.__init__(self, operations)
+ WithExtendedAttributes.__init__(self, extended_attributes)
WithCodeGeneratorInfo.__init__(self, code_generator_info)
WithExposure.__init__(self)
WithDebugInfo.__init__(self, debug_info)
@@ -103,6 +145,7 @@ class OperationGroup(OverloadGroup, WithCodeGeneratorInfo, WithExposure,
ir = make_copy(ir)
OverloadGroup.__init__(self, functions=operations)
+ WithExtendedAttributes.__init__(self, ir, readonly=True)
WithCodeGeneratorInfo.__init__(self, ir, readonly=True)
WithExposure.__init__(self, ir, readonly=True)
WithOwner.__init__(self, owner)
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/union.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/union.py
index 02f00b111ca..9bb06e94cd9 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/union.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/union.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.
+from .composition_parts import Identifier
+from .composition_parts import WithCodeGeneratorInfo
from .composition_parts import WithComponent
from .composition_parts import WithDebugInfo
from .composition_parts import WithIdentifier
@@ -9,7 +11,8 @@ from .idl_type import IdlType
from .typedef import Typedef
-class Union(WithIdentifier, WithComponent, WithDebugInfo):
+class Union(WithIdentifier, WithCodeGeneratorInfo, WithComponent,
+ WithDebugInfo):
"""
Union class makes a group of union types with the same flattened member
types and the same result whether it includes a nullable type or not.
@@ -28,7 +31,7 @@ class Union(WithIdentifier, WithComponent, WithDebugInfo):
expected to define an implementation class for each Union instance.
"""
- def __init__(self, identifier, union_types, typedef_backrefs):
+ def __init__(self, union_types, typedef_backrefs):
"""
Args:
union_types: Union types of which this object consists. All types
@@ -56,6 +59,7 @@ class Union(WithIdentifier, WithComponent, WithDebugInfo):
assert union_type.flattened_member_types == flattened_members
assert (union_type.does_include_nullable_type ==
does_include_nullable_type)
+ union_type.set_union_definition_object(self)
for direct_member in union_type.member_types:
if direct_member.is_nullable:
nullable_members.add(direct_member)
@@ -68,16 +72,49 @@ class Union(WithIdentifier, WithComponent, WithDebugInfo):
components = set()
- def collect_components(idl_type):
- user_defined_type = idl_type.type_definition_object
- if user_defined_type:
- components.update(user_defined_type.components)
+ def collect_primary_component(idl_type):
+ type_definition_object = idl_type.type_definition_object
+ if type_definition_object and type_definition_object.components:
+ components.add(type_definition_object.components[0])
for idl_type in flattened_members:
- idl_type.apply_to_all_composing_elements(collect_components)
+ idl_type.apply_to_all_composing_elements(collect_primary_component)
+ # Make this union type look defined in 'modules' if the union type is
+ # used in 'modules' in order to keep the backward compatibility with
+ # the old bindings generator.
+ is_defined_in_core = False
+ is_defined_in_modules = False
+ for idl_type in union_types:
+ filepath = idl_type.debug_info.location.filepath
+ if filepath.startswith('third_party/blink/renderer/core/'):
+ is_defined_in_core = True
+ if filepath.startswith('third_party/blink/renderer/modules/'):
+ is_defined_in_modules = True
+ if not is_defined_in_core and is_defined_in_modules:
+ from .composition_parts import Component
+ components.add(Component('modules'))
+
+ # TODO(peria, yukishiino): Produce unique union names. Trying to
+ # produce the names compatible to the old bindings generator for the
+ # time being.
+ #
+ # type_names = sorted(
+ # [idl_type.type_name for idl_type in flattened_members])
+ def backward_compatible_member_name(idl_type):
+ name = idl_type.unwrap().type_name
+ if name == 'StringTreatNullAs':
+ return 'StringTreatNullAsEmptyString'
+ else:
+ return name
+
+ identifier = Identifier('Or'.join([
+ backward_compatible_member_name(idl_type)
+ for idl_type in union_types[0].member_types
+ ]))
WithIdentifier.__init__(self, identifier)
- WithComponent.__init__(self, sorted(components))
+ WithCodeGeneratorInfo.__init__(self, readonly=True)
+ WithComponent.__init__(self, sorted(components), readonly=True)
WithDebugInfo.__init__(self)
# Sort improves reproducibility.
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/user_defined_type.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/user_defined_type.py
index 30837f2f31e..e7858c07ad6 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/user_defined_type.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/user_defined_type.py
@@ -45,4 +45,4 @@ class UserDefinedType(WithIdentifier):
class StubUserDefinedType(UserDefinedType, WithComponent):
def __init__(self, identifier):
UserDefinedType.__init__(self, identifier)
- WithComponent.__init__(self, components=[])
+ WithComponent.__init__(self, [])
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/validator.py b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/validator.py
index d9f15672f20..cb0290909b8 100644
--- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/validator.py
+++ b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/validator.py
@@ -24,6 +24,7 @@ def _all_function_likes(ir_map):
IRMap.IR.Kind.INTERFACE, IRMap.IR.Kind.NAMESPACE)
for ir in irs:
accumulated.extend(ir.constructors)
+ accumulated.extend(ir.named_constructors)
accumulated.extend(ir.operations)
accumulated.extend(ir_map.irs_of_kinds(IRMap.IR.Kind.CALLBACK_FUNCTION))
return accumulated
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 d616eaab473..1db515ece09 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/attributes.cc.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/attributes.cc.tmpl
@@ -138,9 +138,6 @@ const v8::FunctionCallbackInfo<v8::Value>& info
{% if attribute.is_getter_raises_exception %}
{{define_exception_state}}
{% endif %}
- {% if attribute.is_explicit_nullable %}
- bool is_null = false;
- {% endif %}
{% if attribute.cpp_value_original %}
{{attribute.cpp_type}} {{attribute.cpp_value}}({{attribute.cpp_value_original}});
@@ -163,19 +160,23 @@ const v8::FunctionCallbackInfo<v8::Value>& info
| trim | indent(2)}}
{% endif %}
- {% if attribute.cached_attribute_validation_method %}
- // [CachedAttribute]
- v8::Local<v8::Value> v8_value({{attribute.cpp_value_to_v8_value}});
- property_symbol.Set(holder, v8_value);
- {% endif %}
-
{% if attribute.is_explicit_nullable %}
- if (is_null) {
+ if (!{{attribute.cpp_value}}.has_value()) {
+ {% if attribute.cached_attribute_validation_method %}
+ // [CachedAttribute]
+ property_symbol.Set(holder, v8::Null(info.GetIsolate()));
+ {% endif %}
V8SetReturnValueNull(info);
return;
}
{% endif %}
+ {% if attribute.cached_attribute_validation_method %}
+ // [CachedAttribute]
+ v8::Local<v8::Value> v8_value({{attribute.cpp_value_to_v8_value}});
+ property_symbol.Set(holder, v8_value);
+ {% endif %}
+
{% if attribute.is_keep_alive_for_gc %}
// Keep the wrapper object for the return value alive as long as |this|
// object is alive in order to save creation time of the wrapper object.
@@ -440,9 +441,10 @@ static void {{attribute.camel_case_name}}AttributeSetter{{world_suffix}}(
if (!IsValidEnum(cpp_value, kValidValues, base::size(kValidValues),
"{{attribute.enum_type}}", dummy_exception_state)) {
ExecutionContext::ForCurrentRealm(info)->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning,
- dummy_exception_state.Message()));
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning,
+ dummy_exception_state.Message()));
return;
}
}
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 7af94dccb47..f533b68857a 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(blink::Visitor* visitor) {
+void {{cpp_class}}::Trace(Visitor* visitor) {
{% 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 c4a5c7a23c0..36079ed77ad 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,7 +38,7 @@ class {{exported}}{{cpp_class}} : public {{parent_cpp_class}} {
{% endfor %}
v8::Local<v8::Value> ToV8Impl(v8::Local<v8::Object>, v8::Isolate*) const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
{% for member in members if member.nullable_indicator_name %}
diff --git a/chromium/third_party/blink/renderer/bindings/templates/dictionary_v8.cc.tmpl b/chromium/third_party/blink/renderer/bindings/templates/dictionary_v8.cc.tmpl
index 17fabe160a3..0add9c45a38 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/dictionary_v8.cc.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/dictionary_v8.cc.tmpl
@@ -11,14 +11,14 @@
namespace blink {
{% if members %}
-static const v8::Eternal<v8::Name>* eternal{{v8_class}}Keys(v8::Isolate* isolate) {
+static const base::span<const v8::Eternal<v8::Name>>
+eternal{{v8_class}}Keys(v8::Isolate* isolate) {
static const char* const kKeys[] = {
{% for member in members %}
"{{member.name}}",
{% endfor %}
};
- return V8PerIsolateData::From(isolate)->FindOrCreateEternalNameCache(
- kKeys, kKeys, base::size(kKeys));
+ return V8PerIsolateData::From(isolate)->FindOrCreateEternalNameCache(kKeys, kKeys);
}
{% endif %}
@@ -51,7 +51,7 @@ void {{v8_class}}::ToImpl(v8::Isolate* isolate, v8::Local<v8::Value> v8_value, {
{# Declare local variables only when the dictionary has members to avoid unused variable warnings. #}
{% if members %}
- const v8::Eternal<v8::Name>* keys = eternal{{v8_class}}Keys(isolate);
+ const auto* keys = eternal{{v8_class}}Keys(isolate).data();
v8::TryCatch block(isolate);
v8::Local<v8::Context> context = isolate->GetCurrentContext();
{% if has_origin_trial_members %}
@@ -101,11 +101,6 @@ void {{v8_class}}::ToImpl(v8::Isolate* isolate, v8::Local<v8::Value> v8_value, {
{{declare_enum_validation_variable(member.enum_values) | trim | indent}}
if (!IsValidEnum({{member.cpp_value}}, kValidValues, base::size(kValidValues), "{{member.enum_type}}", exception_state))
return;
- {% elif member.is_object %}
- if (!{{member.cpp_value}}.IsObject()) {
- exception_state.ThrowTypeError("member {{member.name}} is not an object.");
- return;
- }
{% endif %}
impl->{{member.setter_name}}({{member.cpp_value}});
}
@@ -133,7 +128,7 @@ bool toV8{{cpp_class}}(const {{cpp_class}}* impl, v8::Local<v8::Object> dictiona
{% endif %}
{% if members %}
- const v8::Eternal<v8::Name>* keys = eternal{{v8_class}}Keys(isolate);
+ const auto* keys = eternal{{v8_class}}Keys(isolate).data();
v8::Local<v8::Context> context = isolate->GetCurrentContext();
auto create_property = [dictionary, context, keys, isolate](
diff --git a/chromium/third_party/blink/renderer/bindings/templates/dictionary_v8.h.tmpl b/chromium/third_party/blink/renderer/bindings/templates/dictionary_v8.h.tmpl
index 0a0cfa748c1..6b0b2a7c761 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/dictionary_v8.h.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/dictionary_v8.h.tmpl
@@ -30,7 +30,7 @@ inline void V8SetReturnValue(const CallbackInfo& callbackInfo, {{cpp_class}}* im
}
template <>
-struct NativeValueTraits<{{cpp_class}}> : public NativeValueTraitsBase<{{cpp_class}}> {
+struct NativeValueTraits<{{cpp_class}}> : public NativeValueTraitsBase<{{cpp_class}}*> {
{{exported}}static {{cpp_class}}* NativeValue(v8::Isolate*, v8::Local<v8::Value>, ExceptionState&);
};
diff --git a/chromium/third_party/blink/renderer/bindings/templates/interface.cc.tmpl b/chromium/third_party/blink/renderer/bindings/templates/interface.cc.tmpl
index a0d2dc5fe75..b8f328b7817 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/interface.cc.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/interface.cc.tmpl
@@ -110,12 +110,12 @@ static void IndexedPropertySetter(
{% if setter.is_raises_exception %}
{% set setter_arguments = setter_arguments + ['exception_state'] %}
{% endif %}
- bool result = impl->{{setter_name}}({{setter_arguments | join(', ')}});
+ IndexedPropertySetterResult result = impl->{{setter_name}}({{setter_arguments | join(', ')}});
{% if setter.is_raises_exception %}
if (exception_state.HadException())
return;
{% endif %}
- if (!result)
+ if (result == IndexedPropertySetterResult::kDidNotIntercept)
return;
V8SetReturnValue(info, v8_value);
}
@@ -303,14 +303,14 @@ static void IndexedPropertyDeleter(
{% if deleter.is_raises_exception %}
{% set deleter_arguments = deleter_arguments + ['exception_state'] %}
{% endif %}
- DeleteResult result = impl->{{deleter_name}}({{deleter_arguments | join(', ')}});
+ NamedPropertyDeleterResult result = impl->{{deleter_name}}({{deleter_arguments | join(', ')}});
{% if deleter.is_raises_exception %}
if (exception_state.HadException())
return;
{% endif %}
- if (result == kDeleteUnknownProperty)
+ if (result == NamedPropertyDeleterResult::kDidNotIntercept)
return;
- V8SetReturnValue(info, result == kDeleteSuccess);
+ V8SetReturnValue(info, result == NamedPropertyDeleterResult::kDeleted);
}
{% endif %}
@@ -494,12 +494,12 @@ static void NamedPropertySetter(
{% if setter.is_raises_exception %}
{% set setter_arguments = setter_arguments + ['exception_state'] %}
{% endif %}
- bool result = impl->{{setter_name}}({{setter_arguments | join(', ')}});
+ NamedPropertySetterResult result = impl->{{setter_name}}({{setter_arguments | join(', ')}});
{% if setter.is_raises_exception %}
if (exception_state.HadException())
return;
{% endif %}
- if (!result)
+ if (result == NamedPropertySetterResult::kDidNotIntercept)
return;
V8SetReturnValue(info, v8_value);
}
@@ -563,14 +563,14 @@ static void NamedPropertyDeleter(
{% if deleter.is_raises_exception %}
{% set deleter_arguments = deleter_arguments + ['exception_state'] %}
{% endif %}
- DeleteResult result = impl->{{deleter_name}}({{deleter_arguments | join(', ')}});
+ NamedPropertyDeleterResult result = impl->{{deleter_name}}({{deleter_arguments | join(', ')}});
{% if deleter.is_raises_exception %}
if (exception_state.HadException())
return;
{% endif %}
- if (result == kDeleteUnknownProperty)
+ if (result == NamedPropertyDeleterResult::kDidNotIntercept)
return;
- V8SetReturnValue(info, result == kDeleteSuccess);
+ V8SetReturnValue(info, result == NamedPropertyDeleterResult::kDeleted);
}
{% endif %}
@@ -1208,21 +1208,6 @@ v8::Local<v8::Object> {{v8_class}}::FindInstanceInPrototypeChain(
{##############################################################################}
-{% block native_value_traits %}
-{{cpp_class}}* NativeValueTraits<{{cpp_class}}>::NativeValue(
- v8::Isolate* isolate, v8::Local<v8::Value> value, ExceptionState& exception_state) {
- {{cpp_class}}* native_value = {{v8_class}}::ToImplWithTypeCheck(isolate, value);
- if (!native_value) {
- exception_state.ThrowTypeError(ExceptionMessages::FailedToConvertJSValue(
- "{{interface_name}}"));
- }
- return native_value;
-}
-
-{% endblock %}
-
-
-{##############################################################################}
{% block partial_interface %}
{% if has_partial_interface %}
{% if needs_runtime_enabled_installer %}
diff --git a/chromium/third_party/blink/renderer/bindings/templates/interface.h.tmpl b/chromium/third_party/blink/renderer/bindings/templates/interface.h.tmpl
index f84c11618b2..cd96099294e 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/interface.h.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/interface.h.tmpl
@@ -39,6 +39,11 @@ class {{v8_class}} {
STATIC_ONLY({{v8_class}});
public:
{% if is_array_buffer_or_view %}
+ // Migration adapter
+ {{exported}}static bool HasInstance(v8::Isolate*, v8::Local<v8::Value> value) {
+ return value->Is{{interface_name}}();
+ }
+
{{exported}}static {{cpp_class}}* ToImpl(v8::Local<v8::Object> object);
{% else %}
{{exported}}static bool HasInstance(v8::Local<v8::Value>, v8::Isolate*);
@@ -65,12 +70,6 @@ class {{v8_class}} {
{% if method.is_custom %}
static void {{method.camel_case_name}}MethodCustom(const v8::FunctionCallbackInfo<v8::Value>&);
{% endif %}
- {% if method.is_custom_call_prologue %}
- static void {{method.camel_case_name}}MethodPrologueCustom(const v8::FunctionCallbackInfo<v8::Value>&, {{cpp_class}}*);
- {% endif %}
- {% if method.is_custom_call_epilogue %}
- static void {{method.camel_case_name}}MethodEpilogueCustom(const v8::FunctionCallbackInfo<v8::Value>&, {{cpp_class}}*);
- {% endif %}
{% endfor %}
{% if has_custom_constructor %}
static void ConstructorCustom(const v8::FunctionCallbackInfo<v8::Value>&);
@@ -309,12 +308,6 @@ class {{v8_class}} {
};
template <>
-struct NativeValueTraits<{{cpp_class}}> : public NativeValueTraitsBase<{{cpp_class}}> {
- {{exported}}static {{cpp_class}}* NativeValue(v8::Isolate*, v8::Local<v8::Value>, ExceptionState&);
- {{exported}}static {{cpp_class}}* NullValue() { return nullptr; }
-};
-
-template <>
struct V8TypeOf<{{cpp_class}}> {
typedef {{v8_class}} Type;
};
diff --git a/chromium/third_party/blink/renderer/bindings/templates/interface_base.cc.tmpl b/chromium/third_party/blink/renderer/bindings/templates/interface_base.cc.tmpl
index 17661d9b976..0dff254e373 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/interface_base.cc.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/interface_base.cc.tmpl
@@ -894,7 +894,6 @@ void {{v8_class_or_partial}}::Install{{feature.name}}(ScriptState* script_state)
{% block has_instance %}{% endblock %}
{% block to_impl %}{% endblock %}
{% block to_impl_with_type_check %}{% endblock %}
-{% block native_value_traits %}{% endblock %}
{##############################################################################}
{% block install_conditional_features %}
{% from 'attributes.cc.tmpl' import install_conditional_attributes,
diff --git a/chromium/third_party/blink/renderer/bindings/templates/methods.cc.tmpl b/chromium/third_party/blink/renderer/bindings/templates/methods.cc.tmpl
index 9c974038366..0546286b2db 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/methods.cc.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/methods.cc.tmpl
@@ -9,6 +9,10 @@ RUNTIME_CALL_TIMER_SCOPE(info.GetIsolate(), RuntimeCallStats::CounterId::{{count
RUNTIME_CALL_TIMER_SCOPE_DISABLED_BY_DEFAULT(info.GetIsolate(), "{{counter}}");
{% endmacro %}
+{% macro trace_event(name) %}
+BLINK_BINDINGS_TRACE_EVENT("{{name}}");
+{% endmacro %}
+
{% macro generate_method(method, world_suffix) %}
static void {{method.camel_case_name}}{{method.overload_index}}Method{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info) {
{% filter format_remove_duplicates([
@@ -201,20 +205,6 @@ if (!info[{{argument.index}}]->IsNullOrUndefined() && !info[{{argument.index}}]-
if (!info[{{argument.index}}]->IsNullOrUndefined()) {
{{v8_value_to_local_cpp_value(argument) | trim | indent(2)}}
}
-{% elif argument.idl_type == 'object' %}
-if (info[{{argument.index}}]->IsObject()) {
- {{v8_value_to_local_cpp_value(argument)}}
-{% if argument.is_nullable %}
-} else if (info[{{argument.index}}]->IsNullOrUndefined()) {
- {{argument.local_cpp_variable}} = ScriptValue(info.GetIsolate(), v8::Null(info.GetIsolate()));
-{% elif argument.is_optional %}
-} else if (info[{{argument.index}}]->IsUndefined()) {
- {{argument.local_cpp_variable}} = ScriptValue(info.GetIsolate(), v8::Undefined(info.GetIsolate()));
-{% endif %}
-} else {
- {{throw_argument_error(method, argument, "parameter %(index)d ('%(name)s') is not an object.")}}
- return;
-}
{% else %}{# argument is something else #}
{{v8_value_to_local_cpp_value(argument)}}
{% endif %}{# end of the dispatch by the argument type #}
@@ -249,9 +239,6 @@ if (!{{argument.local_cpp_variable}}.IsUndefinedOrNull() && !{{argument.local_cp
{######################################}
{% macro cpp_method_call(method, v8_set_return_value, cpp_value) %}
-{% if method.is_custom_call_prologue %}
-{{v8_class}}::{{method.camel_case_name}}MethodPrologueCustom(info, impl);
-{% endif %}
{# Local variables #}
{% if method.is_call_with_execution_context %}
{# [ConstructorCallWith=ExecutionContext] or [CallWith=ExecutionContext] #}
@@ -266,7 +253,7 @@ ExecutionContext* execution_context = ExecutionContext::ForRelevantRealm(info);
{% endif %}
{% if method.is_call_with_document %}
{# [ConstructorCallWith=Document] #}
-Document& document = *To<Document>(ToExecutionContext(
+Document& document = *Document::From(ToExecutionContext(
info.NewTarget().As<v8::Object>()->CreationContext()));
{% endif %}
{# Call #}
@@ -309,9 +296,6 @@ else
{{v8_set_return_value}};
{% endif %}
{%- endif %}{# None for void #}
-{% if method.is_custom_call_epilogue %}
-{{v8_class}}::{{method.camel_case_name}}MethodEpilogueCustom(info, impl);
-{% endif %}
{% endmacro %}
@@ -467,6 +451,7 @@ if ({{test}}) {
{##############################################################################}
{% macro method_callback(method, world_suffix) %}
void {{v8_class_or_partial}}::{{method.camel_case_name}}MethodCallback{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ {{ trace_event(method.runtime_call_stats.trace_event_name) | trim | indent(2) }}
{% if method.runtime_call_stats.extended_attribute_defined %}
{{ runtime_timer_scope(method.runtime_call_stats.method_counter) | trim | indent(2) }}
{% else %}
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 d8afd2729d4..0599b20b16c 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
@@ -47,11 +47,7 @@ void {{cpp_class}}::Set{{member.type_name}}({{member.rvalue_cpp_type}} value) {
return;
}
{% endif %}
- {% if member.is_array_buffer_view_or_typed_array %}
- {{member.cpp_name}}_ = {{member.cpp_type}}(value.View());
- {% else %}
{{member.cpp_name}}_ = value;
- {% endif %}
type_ = SpecificType::{{member.specific_type_enum}};
}
@@ -66,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(blink::Visitor* visitor) {
+void {{cpp_class}}::Trace(Visitor* visitor) {
{% 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 1c7971d16bc..f2463c68930 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(blink::Visitor*);
+ void Trace(Visitor*);
private:
enum class SpecificType {
diff --git a/chromium/third_party/blink/renderer/build/scripts/PRESUBMIT.py b/chromium/third_party/blink/renderer/build/scripts/PRESUBMIT.py
index 7df85584ae4..8c5b3eb3c36 100644
--- a/chromium/third_party/blink/renderer/build/scripts/PRESUBMIT.py
+++ b/chromium/third_party/blink/renderer/build/scripts/PRESUBMIT.py
@@ -2,8 +2,11 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+
def _GenerateTestCommand(input_api, output_api, file_name, affected_list):
- if not input_api.AffectedFiles(file_filter=lambda x: input_api.FilterSourceFile(x, white_list=affected_list)):
+ if not input_api.AffectedFiles(
+ file_filter=
+ lambda x: input_api.FilterSourceFile(x, white_list=affected_list)):
return None
if input_api.is_committing:
@@ -11,8 +14,8 @@ def _GenerateTestCommand(input_api, output_api, file_name, affected_list):
else:
message_type = output_api.PresubmitPromptWarning
- test_path = input_api.os_path.join(
- input_api.PresubmitLocalPath(), file_name)
+ test_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
+ file_name)
if input_api.is_windows:
cmd = [input_api.python_executable, test_path]
else:
@@ -22,30 +25,38 @@ def _GenerateTestCommand(input_api, output_api, file_name, affected_list):
# during import.
env = input_api.environ.copy()
import_path = [
- input_api.os_path.join(input_api.change.RepositoryRoot(), 'third_party')
+ input_api.os_path.join(input_api.change.RepositoryRoot(),
+ 'third_party')
]
if env.get('PYTHONPATH'):
import_path.append(env.get('PYTHONPATH'))
env['PYTHONPATH'] = input_api.os_path.pathsep.join(import_path)
test_cmd = input_api.Command(
- name=file_name,
- cmd=cmd,
- kwargs={'env': env},
- message=message_type)
+ name=file_name, cmd=cmd, kwargs={'env': env}, message=message_type)
return test_cmd
def _RunTests(input_api, output_api):
- tests = [
- {'file_name': 'json5_generator_unittest.py', 'affected_list': [r'.*json5_generator.*', r'.*\btests[\\\/].*']},
- {'file_name': 'make_runtime_features_utilities_unittest.py', 'affected_list': [r'.*make_runtime_features_utilities.*']},
- # {'file_name': 'make_origin_trials_unittest.py', 'affected_list': [r'.*make_origin_trials.*', r'.*make_runtime_features.*', r'.*\btests[\\\/]runtime_enabled_features.*']},
- ]
+ tests = [{
+ 'file_name': 'json5_generator_unittest.py',
+ 'affected_list': [r'.*json5_generator.*', r'.*\btests[\\\/].*']
+ },
+ {
+ 'file_name': 'make_runtime_features_utilities_unittest.py',
+ 'affected_list': [r'.*make_runtime_features_utilities.*']
+ },
+ {
+ 'file_name': 'make_document_policy_features_unittest.py',
+ 'affected_list': [r'.*make_document_policy_features.*']
+ }]
test_commands = []
for test in tests:
- test_commands.append(_GenerateTestCommand(input_api, output_api, test['file_name'], test['affected_list']))
- return input_api.RunTests([command for command in test_commands if command])
+ test_commands.append(
+ _GenerateTestCommand(input_api, output_api, test['file_name'],
+ test['affected_list']))
+ return input_api.RunTests(
+ [command for command in test_commands if command])
def CheckChangeOnUpload(input_api, output_api):
diff --git a/chromium/third_party/blink/renderer/build/scripts/aria_properties.py b/chromium/third_party/blink/renderer/build/scripts/aria_properties.py
index bca80493236..742e7c27c2e 100644
--- a/chromium/third_party/blink/renderer/build/scripts/aria_properties.py
+++ b/chromium/third_party/blink/renderer/build/scripts/aria_properties.py
@@ -6,8 +6,8 @@ import os
import os.path
import sys
-PYJSON5_DIR = os.path.join(os.path.dirname(__file__),
- '..', '..', '..', '..', 'pyjson5', 'src')
+PYJSON5_DIR = os.path.join(
+ os.path.dirname(__file__), '..', '..', '..', '..', 'pyjson5', 'src')
sys.path.insert(0, PYJSON5_DIR)
import json5 # pylint: disable=import-error
diff --git a/chromium/third_party/blink/renderer/build/scripts/blinkbuild/PRESUBMIT.py b/chromium/third_party/blink/renderer/build/scripts/blinkbuild/PRESUBMIT.py
index 393539ef97e..75dda00cbfc 100644
--- a/chromium/third_party/blink/renderer/build/scripts/blinkbuild/PRESUBMIT.py
+++ b/chromium/third_party/blink/renderer/build/scripts/blinkbuild/PRESUBMIT.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.
+from __future__ import print_function
+
def _RunBindingsTests(input_api, output_api):
pardir = input_api.os_path.pardir
@@ -13,8 +15,8 @@ def _RunBindingsTests(input_api, output_api):
print('Running ' + cmd_name)
else:
cmd.append('--suppress-diff')
- test_cmd = input_api.Command(name=cmd_name, cmd=cmd,
- kwargs={}, message=output_api.PresubmitError)
+ test_cmd = input_api.Command(
+ name=cmd_name, cmd=cmd, kwargs={}, message=output_api.PresubmitError)
return input_api.RunTests([test_cmd])
diff --git a/chromium/third_party/blink/renderer/build/scripts/blinkbuild/name_style_converter.py b/chromium/third_party/blink/renderer/build/scripts/blinkbuild/name_style_converter.py
index c1ce71410de..dd1978df233 100644
--- a/chromium/third_party/blink/renderer/build/scripts/blinkbuild/name_style_converter.py
+++ b/chromium/third_party/blink/renderer/build/scripts/blinkbuild/name_style_converter.py
@@ -59,12 +59,16 @@ SPECIAL_TOKENS = [
'2D',
'AX',
'FE',
+ 'JS',
'V0',
'V8',
'v8',
+ 'XR',
]
-_SPECIAL_TOKENS_WITH_NUMBERS = [token for token in SPECIAL_TOKENS if re.search(r'[0-9]', token)]
+_SPECIAL_TOKENS_WITH_NUMBERS = [
+ token for token in SPECIAL_TOKENS if re.search(r'[0-9]', token)
+]
# Applying _TOKEN_PATTERNS repeatedly should capture any sequence of a-z, A-Z,
# 0-9.
@@ -78,7 +82,8 @@ _TOKEN_PATTERNS = [
'[0-9]+',
]
-_TOKEN_RE = re.compile(r'(' + '|'.join(SPECIAL_TOKENS + _TOKEN_PATTERNS) + r')')
+_TOKEN_RE = re.compile(r'(' + '|'.join(SPECIAL_TOKENS + _TOKEN_PATTERNS) +
+ r')')
def tokenize_name(name):
@@ -101,7 +106,8 @@ def tokenize_name(name):
# In case |name| is written in lowerCamelCase, we try to match special
# tokens that contains numbers ignoring cases only at the first step.
tokens = []
- match = re.search(r'^(' + '|'.join(_SPECIAL_TOKENS_WITH_NUMBERS) + r')', name, re.IGNORECASE)
+ match = re.search(r'^(' + '|'.join(_SPECIAL_TOKENS_WITH_NUMBERS) + r')',
+ name, re.IGNORECASE)
if match:
tokens.append(match.group(0))
name = name[match.end(0):]
@@ -132,6 +138,10 @@ class NameStyleConverter(object):
def __eq__(self, other):
return self.original == other.original
+ # If __eq__() is defined then a custom __hash__() needs to be defined.
+ def __hash__(self):
+ return hash(self.original)
+
def to_snake_case(self):
"""Snake case is the file and variable name style per Google C++ Style
Guide:
@@ -170,7 +180,8 @@ class NameStyleConverter(object):
"""
if not self.tokens:
return ''
- return self.tokens[0].lower() + ''.join([token[0].upper() + token[1:] for token in self.tokens[1:]])
+ return self.tokens[0].lower() + ''.join(
+ [token[0].upper() + token[1:] for token in self.tokens[1:]])
def to_macro_case(self):
"""Macro case is the macro name style per Google C++ Style Guide:
diff --git a/chromium/third_party/blink/renderer/build/scripts/blinkbuild/name_style_converter_test.py b/chromium/third_party/blink/renderer/build/scripts/blinkbuild/name_style_converter_test.py
index 85ba650b3ee..5102efa57e1 100644
--- a/chromium/third_party/blink/renderer/build/scripts/blinkbuild/name_style_converter_test.py
+++ b/chromium/third_party/blink/renderer/build/scripts/blinkbuild/name_style_converter_test.py
@@ -3,7 +3,6 @@
# found in the LICENSE file.
# pylint: disable=import-error,print-statement,relative-import,protected-access
-
"""Unit tests for name_style_converter.py."""
import unittest
@@ -29,116 +28,178 @@ class SmartTokenizerTest(unittest.TestCase):
self.assertEqual(tokenize_name('foo2'), ['foo', '2'])
def test_tricky_cases(self):
- self.assertEqual(tokenize_name('XMLHttpRequest'), ['XML', 'Http', 'Request'])
+ self.assertEqual(
+ tokenize_name('XMLHttpRequest'), ['XML', 'Http', 'Request'])
self.assertEqual(tokenize_name('HTMLElement'), ['HTML', 'Element'])
- self.assertEqual(tokenize_name('WebGLRenderingContext'),
- ['WebGL', 'Rendering', 'Context'])
+ self.assertEqual(
+ tokenize_name('WebGLRenderingContext'),
+ ['WebGL', 'Rendering', 'Context'])
- self.assertEqual(tokenize_name('CanvasRenderingContext2D'),
- ['Canvas', 'Rendering', 'Context', '2D'])
- self.assertEqual(tokenize_name('CanvasRenderingContext2DAPITest'),
- ['Canvas', 'Rendering', 'Context', '2D', 'API', 'Test'])
+ self.assertEqual(
+ tokenize_name('CanvasRenderingContext2D'),
+ ['Canvas', 'Rendering', 'Context', '2D'])
+ self.assertEqual(
+ tokenize_name('CanvasRenderingContext2DAPITest'),
+ ['Canvas', 'Rendering', 'Context', '2D', 'API', 'Test'])
- self.assertEqual(tokenize_name('SVGSVGElement'), ['SVG', 'SVG', 'Element'])
+ self.assertEqual(
+ tokenize_name('SVGSVGElement'), ['SVG', 'SVG', 'Element'])
- self.assertEqual(tokenize_name('CanvasRenderingContext2D'),
- ['Canvas', 'Rendering', 'Context', '2D'])
+ self.assertEqual(
+ tokenize_name('CanvasRenderingContext2D'),
+ ['Canvas', 'Rendering', 'Context', '2D'])
- self.assertEqual(tokenize_name('CSSURLImageValue'), ['CSS', 'URL', 'Image', 'Value'])
- self.assertEqual(tokenize_name('CSSPropertyAPID'), ['CSS', 'Property', 'API', 'D'])
- self.assertEqual(tokenize_name('AXARIAGridCell'), ['AX', 'ARIA', 'Grid', 'Cell'])
+ self.assertEqual(
+ tokenize_name('CSSURLImageValue'),
+ ['CSS', 'URL', 'Image', 'Value'])
+ self.assertEqual(
+ tokenize_name('CSSPropertyAPID'), ['CSS', 'Property', 'API', 'D'])
+ self.assertEqual(
+ tokenize_name('AXARIAGridCell'), ['AX', 'ARIA', 'Grid', 'Cell'])
self.assertEqual(tokenize_name('CDATASection'), ['CDATA', 'Section'])
self.assertEqual(tokenize_name('ASCIICType'), ['ASCII', 'CType'])
- self.assertEqual(tokenize_name('HTMLDListElement'), ['HTML', 'DList', 'Element'])
- self.assertEqual(tokenize_name('HTMLOListElement'), ['HTML', 'OList', 'Element'])
- self.assertEqual(tokenize_name('HTMLIFrameElement'), ['HTML', 'IFrame', 'Element'])
- self.assertEqual(tokenize_name('HTMLPlugInElement'), ['HTML', 'PlugIn', 'Element'])
+ self.assertEqual(
+ tokenize_name('HTMLDListElement'), ['HTML', 'DList', 'Element'])
+ self.assertEqual(
+ tokenize_name('HTMLOListElement'), ['HTML', 'OList', 'Element'])
+ self.assertEqual(
+ tokenize_name('HTMLIFrameElement'), ['HTML', 'IFrame', 'Element'])
+ self.assertEqual(
+ tokenize_name('HTMLPlugInElement'), ['HTML', 'PlugIn', 'Element'])
# No special handling for OptGroup, FieldSet, and TextArea.
- self.assertEqual(tokenize_name('HTMLOptGroupElement'), ['HTML', 'Opt', 'Group', 'Element'])
- self.assertEqual(tokenize_name('HTMLFieldSetElement'), ['HTML', 'Field', 'Set', 'Element'])
- self.assertEqual(tokenize_name('HTMLTextAreaElement'), ['HTML', 'Text', 'Area', 'Element'])
+ self.assertEqual(
+ tokenize_name('HTMLOptGroupElement'),
+ ['HTML', 'Opt', 'Group', 'Element'])
+ self.assertEqual(
+ tokenize_name('HTMLFieldSetElement'),
+ ['HTML', 'Field', 'Set', 'Element'])
+ self.assertEqual(
+ tokenize_name('HTMLTextAreaElement'),
+ ['HTML', 'Text', 'Area', 'Element'])
self.assertEqual(tokenize_name('Path2D'), ['Path', '2D'])
self.assertEqual(tokenize_name('Point2D'), ['Point', '2D'])
- self.assertEqual(tokenize_name('CanvasRenderingContext2DState'),
- ['Canvas', 'Rendering', 'Context', '2D', 'State'])
- self.assertEqual(tokenize_name('Accelerated2dCanvas'), ['Accelerated', '2d', 'Canvas'])
-
- self.assertEqual(tokenize_name('RTCDTMFSender'), ['RTC', 'DTMF', 'Sender'])
-
- self.assertEqual(tokenize_name('WebGLCompressedTextureS3TCsRGB'),
- ['WebGL', 'Compressed', 'Texture', 'S3TC', 'sRGB'])
- self.assertEqual(tokenize_name('WebGL2CompressedTextureETC1'),
- ['WebGL2', 'Compressed', 'Texture', 'ETC1'])
+ self.assertEqual(
+ tokenize_name('CanvasRenderingContext2DState'),
+ ['Canvas', 'Rendering', 'Context', '2D', 'State'])
+ self.assertEqual(
+ tokenize_name('Accelerated2dCanvas'),
+ ['Accelerated', '2d', 'Canvas'])
+
+ self.assertEqual(
+ tokenize_name('RTCDTMFSender'), ['RTC', 'DTMF', 'Sender'])
+
+ self.assertEqual(
+ tokenize_name('WebGLCompressedTextureS3TCsRGB'),
+ ['WebGL', 'Compressed', 'Texture', 'S3TC', 'sRGB'])
+ self.assertEqual(
+ tokenize_name('WebGL2CompressedTextureETC1'),
+ ['WebGL2', 'Compressed', 'Texture', 'ETC1'])
self.assertEqual(tokenize_name('EXTsRGB'), ['EXT', 'sRGB'])
# 'PVRTC' contains a special token 'RTC', but it should be a
# single token.
- self.assertEqual(tokenize_name('WebGLCompressedTexturePVRTC'),
- ['WebGL', 'Compressed', 'Texture', 'PVRTC'])
-
- self.assertEqual(tokenize_name('SVGFEBlendElement'), ['SVG', 'FE', 'Blend', 'Element'])
- self.assertEqual(tokenize_name('SVGMPathElement'), ['SVG', 'MPath', 'Element'])
- self.assertEqual(tokenize_name('SVGTSpanElement'), ['SVG', 'TSpan', 'Element'])
- self.assertEqual(tokenize_name('SVGURIReference'), ['SVG', 'URI', 'Reference'])
-
- self.assertEqual(tokenize_name('UTF16TextIterator'), ['UTF16', 'Text', 'Iterator'])
+ self.assertEqual(
+ tokenize_name('WebGLCompressedTexturePVRTC'),
+ ['WebGL', 'Compressed', 'Texture', 'PVRTC'])
+
+ self.assertEqual(
+ tokenize_name('SVGFEBlendElement'),
+ ['SVG', 'FE', 'Blend', 'Element'])
+ self.assertEqual(
+ tokenize_name('SVGMPathElement'), ['SVG', 'MPath', 'Element'])
+ self.assertEqual(
+ tokenize_name('SVGTSpanElement'), ['SVG', 'TSpan', 'Element'])
+ self.assertEqual(
+ tokenize_name('SVGURIReference'), ['SVG', 'URI', 'Reference'])
+
+ self.assertEqual(
+ tokenize_name('UTF16TextIterator'), ['UTF16', 'Text', 'Iterator'])
self.assertEqual(tokenize_name('UTF8Decoder'), ['UTF8', 'Decoder'])
self.assertEqual(tokenize_name('Uint8Array'), ['Uint8', 'Array'])
- self.assertEqual(tokenize_name('DOMWindowBase64'), ['DOM', 'Window', 'Base64'])
- self.assertEqual(tokenize_name('TextCodecLatin1'), ['Text', 'Codec', 'Latin1'])
- self.assertEqual(tokenize_name('V8BindingForCore'), ['V8', 'Binding', 'For', 'Core'])
+ self.assertEqual(
+ tokenize_name('DOMWindowBase64'), ['DOM', 'Window', 'Base64'])
+ self.assertEqual(
+ tokenize_name('TextCodecLatin1'), ['Text', 'Codec', 'Latin1'])
+ self.assertEqual(
+ tokenize_name('V8BindingForCore'),
+ ['V8', 'Binding', 'For', 'Core'])
self.assertEqual(tokenize_name('V8DOMRect'), ['V8', 'DOM', 'Rect'])
- self.assertEqual(tokenize_name('String16MojomTraits'), ['String16', 'Mojom', 'Traits'])
-
- self.assertEqual(tokenize_name('V0InsertionPoint'), ['V0', 'Insertion', 'Point'])
- self.assertEqual(tokenize_name('ShadowDOMV0Test'), ['Shadow', 'DOM', 'V0', 'Test'])
- self.assertEqual(tokenize_name('ElementShadowV0'), ['Element', 'Shadow', 'V0'])
- self.assertEqual(tokenize_name('StubChromeClientForSPv2'),
- ['Stub', 'Chrome', 'Client', 'For', 'SPv2'])
-
- self.assertEqual(tokenize_name('SQLiteAuthorizer'), ['SQLite', 'Authorizer'])
- self.assertEqual(tokenize_name('XPathEvaluator'), ['XPath', 'Evaluator'])
-
- self.assertEqual(tokenize_name('IsXHTMLDocument'), ['Is', 'XHTML', 'Document'])
- self.assertEqual(tokenize_name('isHTMLDocument'), ['is', 'HTML', 'Document'])
+ self.assertEqual(
+ tokenize_name('String16MojomTraits'),
+ ['String16', 'Mojom', 'Traits'])
+
+ self.assertEqual(
+ tokenize_name('V0InsertionPoint'), ['V0', 'Insertion', 'Point'])
+ self.assertEqual(
+ tokenize_name('ShadowDOMV0Test'), ['Shadow', 'DOM', 'V0', 'Test'])
+ self.assertEqual(
+ tokenize_name('ElementShadowV0'), ['Element', 'Shadow', 'V0'])
+ self.assertEqual(
+ tokenize_name('StubChromeClientForSPv2'),
+ ['Stub', 'Chrome', 'Client', 'For', 'SPv2'])
+
+ self.assertEqual(
+ tokenize_name('SQLiteAuthorizer'), ['SQLite', 'Authorizer'])
+ self.assertEqual(
+ tokenize_name('XPathEvaluator'), ['XPath', 'Evaluator'])
+
+ self.assertEqual(
+ tokenize_name('IsXHTMLDocument'), ['Is', 'XHTML', 'Document'])
+ self.assertEqual(
+ tokenize_name('isHTMLDocument'), ['is', 'HTML', 'Document'])
self.assertEqual(tokenize_name('matrix3d'), ['matrix', '3d'])
- self.assertEqual(tokenize_name('uint8ArrayMember'), ['uint8', 'Array', 'Member'])
+ self.assertEqual(
+ tokenize_name('uint8ArrayMember'), ['uint8', 'Array', 'Member'])
self.assertEqual(tokenize_name('webgl2Element'), ['webgl2', 'Element'])
self.assertEqual(tokenize_name('webGL2Element'), ['webGL2', 'Element'])
self.assertEqual(tokenize_name('xssError'), ['xss', 'Error'])
self.assertEqual(tokenize_name('FileURLs'), ['File', 'URLs'])
+ self.assertEqual(
+ tokenize_name('XRDOMOverlay'), ['XR', 'DOM', 'Overlay'])
+
def test_ignoring_characters(self):
self.assertEqual(tokenize_name('Animation.idl'), ['Animation', 'idl'])
- self.assertEqual(tokenize_name('-webkit-appearance'), ['webkit', 'appearance'])
+ self.assertEqual(
+ tokenize_name('-webkit-appearance'), ['webkit', 'appearance'])
self.assertEqual(tokenize_name(' foo_bar!#"$'), ['foo', 'bar'])
class NameStyleConverterTest(unittest.TestCase):
def test_original(self):
- self.assertEqual(NameStyleConverter('-webkit-appearance').original, '-webkit-appearance')
+ self.assertEqual(
+ NameStyleConverter('-webkit-appearance').original,
+ '-webkit-appearance')
def test_snake_case(self):
converter = NameStyleConverter('HTMLElement')
self.assertEqual(converter.to_snake_case(), 'html_element')
- self.assertEqual(NameStyleConverter('FileURLs').to_snake_case(), 'file_urls')
+ self.assertEqual(
+ NameStyleConverter('FileURLs').to_snake_case(), 'file_urls')
def test_to_class_data_member(self):
converter = NameStyleConverter('HTMLElement')
self.assertEqual(converter.to_class_data_member(), 'html_element_')
- self.assertEqual(converter.to_class_data_member(prefix='is'), 'is_html_element_')
- self.assertEqual(converter.to_class_data_member(suffix='enabled'), 'html_element_enabled_')
- self.assertEqual(converter.to_class_data_member(prefix='is', suffix='enabled'), 'is_html_element_enabled_')
- self.assertEqual(converter.to_class_data_member(prefix='fooBar', suffix='V0V8'), 'foobar_html_element_v0v8_')
+ self.assertEqual(
+ converter.to_class_data_member(prefix='is'), 'is_html_element_')
+ self.assertEqual(
+ converter.to_class_data_member(suffix='enabled'),
+ 'html_element_enabled_')
+ self.assertEqual(
+ converter.to_class_data_member(prefix='is', suffix='enabled'),
+ 'is_html_element_enabled_')
+ self.assertEqual(
+ converter.to_class_data_member(prefix='fooBar', suffix='V0V8'),
+ 'foobar_html_element_v0v8_')
def test_upper_camel_case(self):
converter = NameStyleConverter('someSuperThing')
@@ -146,7 +207,8 @@ class NameStyleConverterTest(unittest.TestCase):
converter = NameStyleConverter('SVGElement')
self.assertEqual(converter.to_upper_camel_case(), 'SVGElement')
converter = NameStyleConverter('cssExternalScannerPreload')
- self.assertEqual(converter.to_upper_camel_case(), 'CSSExternalScannerPreload')
+ self.assertEqual(converter.to_upper_camel_case(),
+ 'CSSExternalScannerPreload')
converter = NameStyleConverter('xpathExpression')
self.assertEqual(converter.to_upper_camel_case(), 'XPathExpression')
converter = NameStyleConverter('feDropShadow')
@@ -154,9 +216,14 @@ class NameStyleConverterTest(unittest.TestCase):
def test_to_class_name(self):
self.assertEqual(NameStyleConverter('').to_class_name(), '')
- self.assertEqual(NameStyleConverter('').to_class_name(prefix='s', suffix='d'), 'SD')
- self.assertEqual(NameStyleConverter('').to_class_name(prefix='style', suffix='data'), 'StyleData')
- self.assertEqual(NameStyleConverter('foo').to_class_name(prefix='style', suffix='data'), 'StyleFooData')
+ self.assertEqual(
+ NameStyleConverter('').to_class_name(prefix='s', suffix='d'), 'SD')
+ self.assertEqual(
+ NameStyleConverter('').to_class_name(
+ prefix='style', suffix='data'), 'StyleData')
+ self.assertEqual(
+ NameStyleConverter('foo').to_class_name(
+ prefix='style', suffix='data'), 'StyleFooData')
self.assertEqual(NameStyleConverter('xpath').to_class_name(), 'XPath')
def test_to_function_name(self):
@@ -164,11 +231,17 @@ class NameStyleConverterTest(unittest.TestCase):
self.assertEqual(converter.to_function_name(), 'FooBar')
self.assertEqual(converter.to_function_name(prefix='is'), 'IsFooBar')
self.assertEqual(converter.to_function_name(suffix='BAZ'), 'FooBarBaz')
- self.assertEqual(converter.to_function_name(prefix='IS', suffix='baz'), 'IsFooBarBaz')
- self.assertEqual(converter.to_function_name(prefix='prefixPrefix', suffix=['a', 'b']), 'PrefixprefixFooBarAB')
+ self.assertEqual(
+ converter.to_function_name(prefix='IS', suffix='baz'),
+ 'IsFooBarBaz')
+ self.assertEqual(
+ converter.to_function_name(
+ prefix='prefixPrefix', suffix=['a', 'b']),
+ 'PrefixprefixFooBarAB')
def test_to_enum_value(self):
- self.assertEqual(NameStyleConverter('fooBar').to_enum_value(), 'kFooBar')
+ self.assertEqual(
+ NameStyleConverter('fooBar').to_enum_value(), 'kFooBar')
def test_lower_camel_case(self):
converter = NameStyleConverter('someSuperThing')
@@ -180,7 +253,8 @@ class NameStyleConverterTest(unittest.TestCase):
converter = NameStyleConverter('-webkit-margin-start')
self.assertEqual(converter.to_lower_camel_case(), 'webkitMarginStart')
converter = NameStyleConverter('Accelerated2dCanvas')
- self.assertEqual(converter.to_lower_camel_case(), 'accelerated2dCanvas')
+ self.assertEqual(converter.to_lower_camel_case(),
+ 'accelerated2dCanvas')
def test_macro_case(self):
converter = NameStyleConverter('WebGLBaz2D')
@@ -188,15 +262,30 @@ class NameStyleConverterTest(unittest.TestCase):
def test_all_cases(self):
converter = NameStyleConverter('SVGScriptElement')
- self.assertEqual(converter.to_all_cases(), {
- 'snake_case': 'svg_script_element',
- 'upper_camel_case': 'SVGScriptElement',
- 'macro_case': 'SVG_SCRIPT_ELEMENT',
- })
+ self.assertEqual(
+ converter.to_all_cases(), {
+ 'snake_case': 'svg_script_element',
+ 'upper_camel_case': 'SVGScriptElement',
+ 'macro_case': 'SVG_SCRIPT_ELEMENT',
+ })
def test_to_header_guard(self):
- converter = NameStyleConverter('third_party/blink/renderer/bindings/modules/v8/v8_path_2d.h')
- self.assertEqual(converter.to_header_guard(), 'THIRD_PARTY_BLINK_RENDERER_BINDINGS_MODULES_V8_V8_PATH_2D_H_')
+ converter = NameStyleConverter(
+ 'third_party/blink/renderer/bindings/modules/v8/v8_path_2d.h')
+ self.assertEqual(
+ converter.to_header_guard(),
+ 'THIRD_PARTY_BLINK_RENDERER_BINDINGS_MODULES_V8_V8_PATH_2D_H_')
+
+ def test_equality(self):
+ a_1 = NameStyleConverter('a')
+ a_2 = NameStyleConverter('a')
+ c = NameStyleConverter('c')
+
+ self.assertEqual(a_1, a_2)
+ self.assertNotEqual(a_1, c)
+ self.assertEqual(hash(a_1), hash(a_2))
+ self.assertNotEqual(hash(a_1), hash(c))
+
if __name__ == '__main__':
unittest.main()
diff --git a/chromium/third_party/blink/renderer/build/scripts/cluster.py b/chromium/third_party/blink/renderer/build/scripts/cluster.py
index 7799f3d732c..20f06646f66 100644
--- a/chromium/third_party/blink/renderer/build/scripts/cluster.py
+++ b/chromium/third_party/blink/renderer/build/scripts/cluster.py
@@ -17,7 +17,7 @@ def l2_pairwise_distance(v1, v2):
dist_mat = [[0 for _ in range(ncol)] for _ in range(nrow)]
for i in range(nrow):
for j in range(ncol):
- dist_mat[i][j] = math.sqrt((v1[i] - v2[j]) ** 2)
+ dist_mat[i][j] = math.sqrt((v1[i] - v2[j])**2)
return dist_mat
@@ -66,7 +66,8 @@ def k_means(x_input, n_cluster=3, n_iter=100, n_tries=10):
for j in range(n_cluster):
if count[j] == 0:
- centers = sorted([rand.uniform(0.0, 100.0) for i in range(n_cluster)])
+ centers = sorted(
+ [rand.uniform(0.0, 100.0) for i in range(n_cluster)])
failed = True
break
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/OWNERS b/chromium/third_party/blink/renderer/build/scripts/core/css/OWNERS
index 89abcdb932e..dbb9dfd2ab6 100644
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/OWNERS
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/OWNERS
@@ -1,7 +1,2 @@
file://third_party/blink/renderer/core/css/OWNERS
-andruud@chromium.org
-futhark@chromium.org
-
-# TEAM: layout-dev@chromium.org
-# COMPONENT: Blink>CSS
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 6d4956ef5d2..1c3cfe3579a 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
@@ -6,19 +6,14 @@
from blinkbuild.name_style_converter import NameStyleConverter
from core.css.field_alias_expander import FieldAliasExpander
import json5_generator
+from make_origin_trials import OriginTrialsWriter
from name_utilities import enum_key_for_css_property, id_for_css_property
from name_utilities import enum_key_for_css_property_alias, id_for_css_property_alias
-
# These values are converted using CSSPrimitiveValue in the setter function,
# if applicable.
PRIMITIVE_TYPES = [
- 'short',
- 'unsigned short',
- 'int',
- 'unsigned int',
- 'unsigned',
- 'float',
+ 'short', 'unsigned short', 'int', 'unsigned int', 'unsigned', 'float',
'LineClampValue'
]
@@ -53,21 +48,32 @@ def check_property_parameters(property_to_check):
if property_to_check['alias_for']:
assert not property_to_check['is_internal'], \
'Internal aliases is not supported'
+ if property_to_check['valid_for_first_letter']:
+ assert not property_to_check['longhands'], \
+ 'Shorthand %s should not be marked as valid_for_first_letter' % \
+ property_to_check['name']
+ if property_to_check['valid_for_cue']:
+ assert not property_to_check['longhands'], \
+ 'Shorthand %s should not be marked as valid_for_cue' % \
+ property_to_check['name']
+ if property_to_check['valid_for_marker']:
+ assert not property_to_check['longhands'], \
+ 'Shorthand %s should not be marked as valid_for_marker' % \
+ property_to_check['name']
class CSSProperties(object):
def __init__(self, file_paths):
- assert len(file_paths) >= 2, \
- "CSSProperties at least needs both css_properties.json5 and \
- computed_style_field_aliases.json5 to function"
+ assert len(file_paths) >= 3, \
+ "CSSProperties at least needs both css_properties.json5, \
+ computed_style_field_aliases.json5 and \
+ runtime_enabled_features.json5 to function"
# computed_style_field_aliases.json5. Used to expand out parameters used
# in the various generators for ComputedStyle.
self._field_alias_expander = FieldAliasExpander(file_paths[1])
- # CSSPropertyValueMetadata assumes that there are at most 1024
- # properties + aliases.
- self._alias_offset = 512
+ self._alias_offset = 1024
# 0: CSSPropertyID::kInvalid
# 1: CSSPropertyID::kVariable
self._first_enum_value = 2
@@ -85,7 +91,15 @@ class CSSProperties(object):
css_properties_file = json5_generator.Json5File.load_from_files(
[file_paths[0]])
self._default_parameters = css_properties_file.parameters
- self.add_properties(css_properties_file.name_dictionaries)
+ # Map of feature name -> origin trial feature name
+ origin_trial_features = {}
+ # TODO(crbug/1031309): Refactor OriginTrialsWriter to reuse logic here.
+ origin_trials_writer = OriginTrialsWriter([file_paths[2]], "")
+ for feature in origin_trials_writer.origin_trial_features:
+ origin_trial_features[str(feature['name'])] = True
+
+ self.add_properties(css_properties_file.name_dictionaries,
+ origin_trial_features)
assert self._first_enum_value + len(self._properties_by_id) < \
self._alias_offset, \
@@ -96,28 +110,33 @@ class CSSProperties(object):
# Process extra files passed in.
self._extra_fields = []
- for i in range(2, len(file_paths)):
+ for i in range(3, len(file_paths)):
fields = json5_generator.Json5File.load_from_files(
- [file_paths[i]],
- default_parameters=self._default_parameters)
+ [file_paths[i]], default_parameters=self._default_parameters)
self._extra_fields.extend(fields.name_dictionaries)
for field in self._extra_fields:
self.expand_parameters(field)
- def add_properties(self, properties):
+ def add_properties(self, properties, origin_trial_features):
for property_ in properties:
self._properties_by_name[property_['name'].original] = property_
for property_ in properties:
self.expand_visited(property_)
+ property_['in_origin_trial'] = False
+ self.expand_origin_trials(property_, origin_trial_features)
+ self.expand_surrogate(property_)
self._aliases = [
- property_ for property_ in properties if property_['alias_for']]
+ property_ for property_ in properties if property_['alias_for']
+ ]
self._shorthands = [
- property_ for property_ in properties if property_['longhands']]
+ property_ for property_ in properties if property_['longhands']
+ ]
self._longhands = [
- property_ for property_ in properties if (
- not property_['alias_for'] and not property_['longhands'])]
+ property_ for property_ in properties
+ if (not property_['alias_for'] and not property_['longhands'])
+ ]
# Sort the properties by priority, then alphabetically. Ensure that
# the resulting order is deterministic.
@@ -159,6 +178,12 @@ class CSSProperties(object):
self._properties_including_aliases = self._longhands + \
self._shorthands + self._aliases
+ def expand_origin_trials(self, property_, origin_trial_features):
+ if not property_['runtime_flag']:
+ return
+ if property_['runtime_flag'] in origin_trial_features:
+ property_['in_origin_trial'] = True
+
def expand_visited(self, property_):
if not property_['visited_property_for']:
return
@@ -172,18 +197,30 @@ class CSSProperties(object):
'A property may not have multiple visited properties'
unvisited_property['visited_property'] = property_
+ def expand_surrogate(self, property_):
+ if not property_['surrogate_for']:
+ return
+ assert property_['surrogate_for'] in self._properties_by_name, \
+ 'surrogate_for must name a property'
+ # Upgrade 'surrogate_for' to property reference.
+ property_['surrogate_for'] = self._properties_by_name[
+ property_['surrogate_for']]
+
def expand_aliases(self):
for i, alias in enumerate(self._aliases):
assert not alias['runtime_flag'], \
"Property '{}' is an alias with a runtime_flag, "\
"but runtime flags do not currently work for aliases.".format(
alias['name'])
- aliased_property = self._properties_by_id[
- id_for_css_property(alias['alias_for'])]
+ aliased_property = self._properties_by_id[id_for_css_property(
+ alias['alias_for'])]
+ aliased_property.setdefault('aliases', [])
+ aliased_property['aliases'].append(alias['name'].original)
updated_alias = aliased_property.copy()
updated_alias['name'] = alias['name']
updated_alias['alias_for'] = alias['alias_for']
- updated_alias['aliased_property'] = aliased_property['name'].to_upper_camel_case()
+ updated_alias['aliased_property'] = aliased_property[
+ 'name'].to_upper_camel_case()
updated_alias['property_id'] = id_for_css_property_alias(
alias['name'])
updated_alias['enum_key'] = enum_key_for_css_property_alias(
@@ -217,23 +254,26 @@ class CSSProperties(object):
set_if_none(property_, 'name_for_methods', method_name)
set_if_none(property_, 'type_name', 'E' + method_name)
set_if_none(
- property_,
- 'getter',
- method_name if simple_type_name != method_name else 'Get' + method_name)
+ property_, 'getter', method_name
+ if simple_type_name != method_name else 'Get' + method_name)
set_if_none(property_, 'setter', 'Set' + method_name)
if property_['inherited']:
- property_['is_inherited_setter'] = 'Set' + method_name + 'IsInherited'
+ property_['is_inherited_setter'] = (
+ 'Set' + method_name + 'IsInherited')
+ property_['is_animation_property'] = (
+ property_['priority'] == 'Animation')
# Figure out whether this property should have style builders at all.
# E.g. shorthands do not get style builders.
- property_['style_builder_declare'] = (property_['is_property'] and
- not property_['longhands'])
+ property_['style_builder_declare'] = (property_['is_property']
+ and not property_['longhands'])
# Figure out whether we should generate style builder implementations.
for x in ['initial', 'inherit', 'value']:
suppressed = x in property_['style_builder_custom_functions']
declared = property_['style_builder_declare']
- property_['style_builder_generate_%s' % x] = declared and not suppressed
+ property_['style_builder_generate_%s' % x] = (declared
+ and not suppressed)
# Expand StyleBuilderConverter params where necessary.
if property_['type_name'] in PRIMITIVE_TYPES:
@@ -241,7 +281,8 @@ class CSSProperties(object):
else:
set_if_none(property_, 'converter', 'CSSIdentifierValue')
- assert not property_['alias_for'], 'Use expand_aliases to expand aliases'
+ assert not property_['alias_for'], \
+ 'Use expand_aliases to expand aliases'
if not property_['longhands']:
property_['superclass'] = 'Longhand'
property_['namespace_group'] = 'Longhand'
@@ -254,13 +295,13 @@ class CSSProperties(object):
self._field_alias_expander.expand_field_alias(property_)
type_name = property_['type_name']
- if (property_['field_template'] == 'keyword' or
- property_['field_template'] == 'multi_keyword'):
+ if (property_['field_template'] == 'keyword'
+ or property_['field_template'] == 'multi_keyword'):
default_value = (type_name + '::' + NameStyleConverter(
property_['default_value']).to_enum_value())
- elif (property_['field_template'] == 'external' or
- property_['field_template'] == 'primitive' or
- property_['field_template'] == 'pointer'):
+ elif (property_['field_template'] == 'external'
+ or property_['field_template'] == 'primitive'
+ or property_['field_template'] == 'pointer'):
default_value = property_['default_value']
else:
assert property_['field_template'] == 'monotonic_flag', \
@@ -289,7 +330,8 @@ class CSSProperties(object):
assert 'resolver' in options, 'resolver option is required'
assert 'physical_group' in options, 'physical_group option is required'
options['resolver_name'] = NameStyleConverter(options['resolver'])
- options['physical_group_name'] = NameStyleConverter(options['physical_group'])
+ options['physical_group_name'] = NameStyleConverter(
+ options['physical_group'])
@property
def default_parameters(self):
@@ -313,7 +355,9 @@ class CSSProperties(object):
@property
def longhands_including_aliases(self):
- return self._longhands + [x for x in self._aliases if not x['longhands']]
+ return self._longhands + [
+ x for x in self._aliases if not x['longhands']
+ ]
@property
def properties_by_id(self):
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/field_alias_expander.py b/chromium/third_party/blink/renderer/build/scripts/core/css/field_alias_expander.py
index d4b4cf8f3a6..d714d5b3f5e 100644
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/field_alias_expander.py
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/field_alias_expander.py
@@ -13,10 +13,12 @@ class FieldAliasExpander(object):
should point to core/css/computed_style_field_aliases.json5) and uses that to
inform which fields in a given property should be set.
"""
+
def __init__(self, file_path):
loaded_file = json5_generator.Json5File.load_from_files([file_path])
- self._field_aliases = dict([(alias["name"], alias)
- for alias in loaded_file.name_dictionaries])
+ self._field_aliases = dict([
+ (alias["name"], alias) for alias in loaded_file.name_dictionaries
+ ])
def expand_field_alias(self, property_):
"""
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/make_css_primitive_value_unit_trie.py b/chromium/third_party/blink/renderer/build/scripts/core/css/make_css_primitive_value_unit_trie.py
index 318d1136300..16edce10957 100755
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/make_css_primitive_value_unit_trie.py
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/make_css_primitive_value_unit_trie.py
@@ -12,13 +12,17 @@ class UnitTrieWriter(json5_generator.Writer):
def __init__(self, json5_file_paths, output_dir):
super(UnitTrieWriter, self).__init__(json5_file_paths, output_dir)
- self._units = {entry['name'].original: entry['unit_type'] for entry in self.json5_file.name_dictionaries}
+ self._units = {
+ entry['name'].original: entry['unit_type']
+ for entry in self.json5_file.name_dictionaries
+ }
self._outputs = {
'css_primitive_value_unit_trie.cc': self.generate_implementation
}
- @template_expander.use_jinja('core/css/templates/css_primitive_value_unit_trie.cc.tmpl')
+ @template_expander.use_jinja(
+ 'core/css/templates/css_primitive_value_unit_trie.cc.tmpl')
def generate_implementation(self):
return {
'input_files': self._input_files,
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/make_css_property_names.py b/chromium/third_party/blink/renderer/build/scripts/core/css/make_css_property_names.py
index 016215cb904..e20639af8cb 100755
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/make_css_property_names.py
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/make_css_property_names.py
@@ -11,7 +11,8 @@ class CSSPropertyNamesWriter(json5_generator.Writer):
file_basename = "css_property_names"
def __init__(self, json5_file_path, output_dir):
- super(CSSPropertyNamesWriter, self).__init__(json5_file_path, output_dir)
+ super(CSSPropertyNamesWriter, self).__init__(json5_file_path,
+ output_dir)
self._outputs = {
(self.file_basename + ".h"): self.generate_header,
(self.file_basename + ".cc"): self.generate_implementation,
@@ -24,32 +25,40 @@ class CSSPropertyNamesWriter(json5_generator.Writer):
def _array_item(self, property_):
return " CSSPropertyID::%(enum_key)s," % property_
- @template_expander.use_jinja('core/css/templates/css_property_names.h.tmpl')
+ @template_expander.use_jinja(
+ 'core/css/templates/css_property_names.h.tmpl')
def generate_header(self):
return {
- 'alias_offset': self._css_properties.alias_offset,
- 'class_name': self.class_name,
- 'property_enums': "\n".join(map(
- self._enum_declaration,
- self._css_properties.properties_including_aliases)),
- 'property_aliases': "\n".join(
- map(self._array_item, self._css_properties.aliases)),
- 'first_property_id': self._css_properties.first_property_id,
+ 'alias_offset':
+ self._css_properties.alias_offset,
+ 'class_name':
+ self.class_name,
+ 'property_enums':
+ "\n".join(
+ map(self._enum_declaration,
+ self._css_properties.properties_including_aliases)),
+ 'property_aliases':
+ "\n".join(map(self._array_item, self._css_properties.aliases)),
+ 'first_property_id':
+ self._css_properties.first_property_id,
'properties_count':
- len(self._css_properties.properties_including_aliases),
- 'last_property_id': self._css_properties.last_property_id,
+ len(self._css_properties.properties_including_aliases),
+ 'last_property_id':
+ self._css_properties.last_property_id,
'last_unresolved_property_id':
- self._css_properties.last_unresolved_property_id,
+ self._css_properties.last_unresolved_property_id,
'max_name_length':
- max(map(len, self._css_properties.properties_by_id)),
+ max(map(len, self._css_properties.properties_by_id)),
}
- @gperf.use_jinja_gperf_template('core/css/templates/css_property_names.cc.tmpl',
- ['-Q', 'CSSPropStringPool'])
+ @gperf.use_jinja_gperf_template(
+ 'core/css/templates/css_property_names.cc.tmpl',
+ ['-Q', 'CSSPropStringPool'])
def generate_implementation(self):
enum_value_to_name = {}
for property_ in self._css_properties.properties_including_aliases:
- enum_value_to_name[property_['enum_value']] = property_['name'].original
+ enum_value_to_name[property_['enum_value']] = \
+ property_['name'].original
property_offsets = []
property_names = []
current_offset = 0
@@ -64,7 +73,8 @@ class CSSPropertyNamesWriter(json5_generator.Writer):
css_name_and_enum_pairs = [
(property_['name'].original,
'static_cast<int>(CSSPropertyID::' + property_['enum_key'] + ')')
- for property_ in self._css_properties.properties_including_aliases]
+ for property_ in self._css_properties.properties_including_aliases
+ ]
property_keys = [
property_['enum_key']
@@ -72,15 +82,21 @@ class CSSPropertyNamesWriter(json5_generator.Writer):
]
return {
- 'class_name': 'CSSPropertyNames',
- 'file_basename': self.file_basename,
- 'property_keys': property_keys,
- 'property_names': property_names,
- 'property_offsets': property_offsets,
+ 'class_name':
+ 'CSSPropertyNames',
+ 'file_basename':
+ self.file_basename,
+ 'property_keys':
+ property_keys,
+ 'property_names':
+ property_names,
+ 'property_offsets':
+ property_offsets,
'property_to_enum_map':
- '\n'.join('%s, %s' % property_
- for property_ in css_name_and_enum_pairs),
- 'gperf_path': self.gperf_path,
+ '\n'.join(
+ '%s, %s' % property_ for property_ in css_name_and_enum_pairs),
+ 'gperf_path':
+ self.gperf_path,
}
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/make_css_tokenizer_codepoints.py b/chromium/third_party/blink/renderer/build/scripts/core/css/make_css_tokenizer_codepoints.py
index a51c5917d33..3c76325cdbb 100755
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/make_css_tokenizer_codepoints.py
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/make_css_tokenizer_codepoints.py
@@ -27,31 +27,32 @@ const unsigned codePointsNumber = {array_size};
def token_type(i):
- codepoints = {'(': 'LeftParenthesis',
- ')': 'RightParenthesis',
- '[': 'LeftBracket',
- ']': 'RightBracket',
- '{': 'LeftBrace',
- '}': 'RightBrace',
- '+': 'PlusOrFullStop',
- '.': 'PlusOrFullStop',
- '-': 'HyphenMinus',
- '*': 'Asterisk',
- '<': 'LessThan',
- ',': 'Comma',
- '/': 'Solidus',
- '\\': 'ReverseSolidus',
- ':': 'Colon',
- ';': 'SemiColon',
- '#': 'Hash',
- '^': 'CircumflexAccent',
- '$': 'DollarSign',
- '|': 'VerticalLine',
- '~': 'Tilde',
- '@': 'CommercialAt',
- 'u': 'LetterU',
- 'U': 'LetterU',
- }
+ codepoints = {
+ '(': 'LeftParenthesis',
+ ')': 'RightParenthesis',
+ '[': 'LeftBracket',
+ ']': 'RightBracket',
+ '{': 'LeftBrace',
+ '}': 'RightBrace',
+ '+': 'PlusOrFullStop',
+ '.': 'PlusOrFullStop',
+ '-': 'HyphenMinus',
+ '*': 'Asterisk',
+ '<': 'LessThan',
+ ',': 'Comma',
+ '/': 'Solidus',
+ '\\': 'ReverseSolidus',
+ ':': 'Colon',
+ ';': 'SemiColon',
+ '#': 'Hash',
+ '^': 'CircumflexAccent',
+ '$': 'DollarSign',
+ '|': 'VerticalLine',
+ '~': 'Tilde',
+ '@': 'CommercialAt',
+ 'u': 'LetterU',
+ 'U': 'LetterU',
+ }
c = chr(i)
if c in codepoints:
return codepoints[c]
@@ -79,10 +80,15 @@ class MakeCSSTokenizerCodePointsWriter(in_generator.Writer):
def generate(self):
array_size = 128 # SCHAR_MAX + 1
- token_lines = [' &CSSTokenizer::%s,' % token_type(i)
- if token_type(i) else ' 0,'
- for i in range(array_size)]
- return CPP_TEMPLATE.format(array_size=array_size, token_lines='\n'.join(token_lines), module_pyname=module_pyname)
+ token_lines = [
+ ' &CSSTokenizer::%s,' % token_type(i)
+ if token_type(i) else ' 0,' for i in range(array_size)
+ ]
+ return CPP_TEMPLATE.format(
+ array_size=array_size,
+ token_lines='\n'.join(token_lines),
+ module_pyname=module_pyname)
+
if __name__ == '__main__':
in_generator.Maker(MakeCSSTokenizerCodePointsWriter).main(sys.argv)
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/make_css_value_id_mappings.py b/chromium/third_party/blink/renderer/build/scripts/core/css/make_css_value_id_mappings.py
index 8613f539fa4..996b82dc46f 100755
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/make_css_value_id_mappings.py
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/make_css_value_id_mappings.py
@@ -40,8 +40,8 @@ def _find_continuous_segment(numbers):
for i in range(len(number_list_sorted) - 1):
# continuous segment is a segment which the number in pair is 1 unit
# more than the previous pair
- if (number_list_sorted[i + 1][0] - number_list_sorted[i][0] != 1
- or number_list_sorted[i + 1][1] - number_list_sorted[i][1] != 1):
+ if (number_list_sorted[i + 1][0] - number_list_sorted[i][0] != 1 or
+ number_list_sorted[i + 1][1] - number_list_sorted[i][1] != 1):
segments.append(i + 1)
segments.append(len(number_list_sorted))
return segments, number_list_sorted
@@ -62,7 +62,8 @@ def _find_largest_segment(segments):
return max(segment_list, key=lambda x: x[1] - x[0])
-def _find_enum_longest_continuous_segment(property_, name_to_position_dictionary):
+def _find_enum_longest_continuous_segment(property_,
+ name_to_position_dictionary):
"""Find the longest continuous segment in the list of keywords
Finding the continuous segment will allows us to do the subtraction
between keywords so that the distance between 2 keywords in this
@@ -85,7 +86,9 @@ def _find_enum_longest_continuous_segment(property_, name_to_position_dictionary
segment. Enums in the segment will be computed in default clause.
"""
property_enum_order = range(len(property_['keywords']))
- css_enum_order = [name_to_position_dictionary[x] for x in property_['keywords']]
+ css_enum_order = [
+ name_to_position_dictionary[x] for x in property_['keywords']
+ ]
enum_pair_list = zip(css_enum_order, property_enum_order)
enum_segment, enum_pair_list = _find_continuous_segment(enum_pair_list)
longest_segment = _find_largest_segment(enum_segment)
@@ -99,11 +102,13 @@ def _find_enum_longest_continuous_segment(property_, name_to_position_dictionary
class CSSValueIDMappingsWriter(make_style_builder.StyleBuilderWriter):
def __init__(self, json5_file_paths, output_dir):
- super(CSSValueIDMappingsWriter, self).__init__(json5_file_paths, output_dir)
+ super(CSSValueIDMappingsWriter, self).__init__(json5_file_paths,
+ output_dir)
self._outputs = {
- 'css_value_id_mappings_generated.h': self.generate_css_value_mappings,
+ 'css_value_id_mappings_generated.h':
+ self.generate_css_value_mappings,
}
- self.css_values_dictionary_file = json5_file_paths[2]
+ self.css_values_dictionary_file = json5_file_paths[3]
css_properties = self.css_properties.longhands
# We sort the enum values based on each value's position in
# the keywords as listed in css_properties.json5. This will ensure that if there is a continuous
@@ -112,26 +117,30 @@ class CSSValueIDMappingsWriter(make_style_builder.StyleBuilderWriter):
# css_properties.json5 and we can get the longest continuous segment.
# Thereby reduce the switch case statement to the minimum.
css_properties = keyword_utils.sort_keyword_properties_by_canonical_order(
- css_properties, json5_file_paths[2], self.default_parameters)
+ css_properties, json5_file_paths[3], self.default_parameters)
- @template_expander.use_jinja('core/css/templates/css_value_id_mappings_generated.h.tmpl')
+ @template_expander.use_jinja(
+ 'core/css/templates/css_value_id_mappings_generated.h.tmpl')
def generate_css_value_mappings(self):
mappings = {}
include_paths = set()
css_values_dictionary = json5_generator.Json5File.load_from_files(
[self.css_values_dictionary_file],
- default_parameters=self.default_parameters
- ).name_dictionaries
- name_to_position_dictionary = dict(zip([x['name'].original for x in css_values_dictionary],
- range(len(css_values_dictionary))))
+ default_parameters=self.default_parameters).name_dictionaries
+ name_to_position_dictionary = dict(
+ zip([x['name'].original for x in css_values_dictionary],
+ range(len(css_values_dictionary))))
for property_ in self.css_properties.properties_including_aliases:
include_paths.update(property_['include_paths'])
if property_['field_template'] == 'multi_keyword':
mappings[property_['type_name']] = {
- 'default_value': property_['default_value'],
- 'mapping': [enum_key_for_css_keyword(k)
- for k in property_['keywords']],
+ 'default_value':
+ property_['default_value'],
+ 'mapping': [
+ enum_key_for_css_keyword(k)
+ for k in property_['keywords']
+ ],
}
elif property_['field_template'] == 'keyword':
enum_pair_list, enum_segment, p_segment = _find_enum_longest_continuous_segment(
@@ -151,5 +160,6 @@ class CSSValueIDMappingsWriter(make_style_builder.StyleBuilderWriter):
'mappings': mappings,
}
+
if __name__ == '__main__':
json5_generator.Maker(CSSValueIDMappingsWriter).main()
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/make_css_value_keywords.py b/chromium/third_party/blink/renderer/build/scripts/core/css/make_css_value_keywords.py
index 077bb9a1762..eabb6aeeaa5 100755
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/make_css_value_keywords.py
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/make_css_value_keywords.py
@@ -33,14 +33,21 @@ class CSSValueKeywordsWriter(json5_generator.Writer):
'value keywords should have the prefix "-internal-".'
self._keyword_count = len(self._value_keywords) + first_keyword_id
- @template_expander.use_jinja('core/css/templates/css_value_keywords.h.tmpl')
+ @template_expander.use_jinja(
+ 'core/css/templates/css_value_keywords.h.tmpl')
def generate_header(self):
return {
- 'value_keywords': self._value_keywords,
- 'value_keywords_count': self._keyword_count,
+ 'value_keywords':
+ self._value_keywords,
+ 'value_keywords_count':
+ self._keyword_count,
'max_value_keyword_length':
- max(len(keyword['name'].original) for keyword in self._value_keywords),
- 'header_guard': self.make_header_guard(self._relative_output_dir + self._FILE_BASENAME + '.h')
+ max(
+ len(keyword['name'].original)
+ for keyword in self._value_keywords),
+ 'header_guard':
+ self.make_header_guard(self._relative_output_dir +
+ self._FILE_BASENAME + '.h')
}
def _value_keywords_with_mode(self, mode):
@@ -60,14 +67,18 @@ class CSSValueKeywordsWriter(json5_generator.Writer):
current_offset += len(keyword["name"].original) + 1
return {
- 'value_keywords': self._value_keywords,
- 'value_keyword_offsets': keyword_offsets,
+ 'value_keywords':
+ self._value_keywords,
+ 'value_keyword_offsets':
+ keyword_offsets,
'ua_sheet_mode_values_keywords':
- self._value_keywords_with_mode('UASheet'),
+ self._value_keywords_with_mode('UASheet'),
'quirks_mode_or_ua_sheet_mode_values_keywords':
- self._value_keywords_with_mode('QuirksOrUASheet'),
- 'gperf_path': self.gperf_path,
+ self._value_keywords_with_mode('QuirksOrUASheet'),
+ 'gperf_path':
+ self.gperf_path,
}
+
if __name__ == "__main__":
json5_generator.Maker(CSSValueKeywordsWriter).main()
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/make_cssom_types.py b/chromium/third_party/blink/renderer/build/scripts/core/css/make_cssom_types.py
index e16d7a3e894..ef5c5f57bca 100755
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/make_cssom_types.py
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/make_cssom_types.py
@@ -15,6 +15,7 @@ class CSSOMTypesWriter(json5_generator.Writer):
utility methods for determining whether a given CSSStyleValue is valid
for a given CSS property. The header files live in core/css/cssom.
"""
+
def __init__(self, json5_file_paths, output_dir):
super(CSSOMTypesWriter, self).__init__([], output_dir)
@@ -30,8 +31,8 @@ class CSSOMTypesWriter(json5_generator.Writer):
property_['typedom_types'] = types
# Generate CSSValueID values from keywords.
- property_['keywordIDs'] = map(
- enum_key_for_css_keyword, property_['keywords'])
+ property_['keywordIDs'] = map(enum_key_for_css_keyword,
+ property_['keywords'])
self._outputs = {
'cssom_types.cc': self.generate_types,
@@ -52,5 +53,6 @@ class CSSOMTypesWriter(json5_generator.Writer):
'properties': self._properties,
}
+
if __name__ == '__main__':
json5_generator.Maker(CSSOMTypesWriter).main()
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/make_media_feature_names.py b/chromium/third_party/blink/renderer/build/scripts/core/css/make_media_feature_names.py
index e58585b91b5..6ae5b44f8b8 100755
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/make_media_feature_names.py
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/make_media_feature_names.py
@@ -10,11 +10,12 @@ import media_feature_symbol
class MakeMediaFeatureNamesWriter(make_names.MakeNamesWriter):
-
def __init__(self, json5_file_path, output_dir):
- super(MakeMediaFeatureNamesWriter, self).__init__(json5_file_path, output_dir)
+ super(MakeMediaFeatureNamesWriter, self).__init__(
+ json5_file_path, output_dir)
MakeMediaFeatureNamesWriter.filters['symbol'] = (
- media_feature_symbol.getMediaFeatureSymbolWithSuffix('MediaFeature'))
+ media_feature_symbol.getMediaFeatureSymbolWithSuffix(
+ 'MediaFeature'))
if __name__ == "__main__":
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/make_media_features.py b/chromium/third_party/blink/renderer/build/scripts/core/css/make_media_features.py
index 7e8aeecfa45..5ea622f7b29 100755
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/make_media_features.py
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/make_media_features.py
@@ -16,26 +16,35 @@ class MakeMediaFeaturesWriter(json5_generator.Writer):
'export': '',
}
filters = {
- 'symbol': media_feature_symbol.getMediaFeatureSymbolWithSuffix(''),
+ 'symbol':
+ media_feature_symbol.getMediaFeatureSymbolWithSuffix(''),
# symbol[1:] removes the leading 'k' produced by the above function.
- 'to_function_name': lambda symbol: NameStyleConverter(symbol[1:]).to_function_name(),
+ 'to_function_name':
+ lambda symbol: NameStyleConverter(symbol[1:]).to_function_name(),
}
def __init__(self, json5_file_path, output_dir):
- super(MakeMediaFeaturesWriter, self).__init__(json5_file_path, output_dir)
+ super(MakeMediaFeaturesWriter, self).__init__(json5_file_path,
+ output_dir)
self._outputs = {
('media_features.h'): self.generate_header,
}
self._template_context = {
- 'entries': self.json5_file.name_dictionaries,
- 'input_files': self._input_files,
- 'header_guard': self.make_header_guard(self._relative_output_dir + 'media_features.h')
+ 'entries':
+ self.json5_file.name_dictionaries,
+ 'input_files':
+ self._input_files,
+ 'header_guard':
+ self.make_header_guard(self._relative_output_dir +
+ 'media_features.h')
}
- @template_expander.use_jinja('core/css/templates/media_features.h.tmpl', filters=filters)
+ @template_expander.use_jinja(
+ 'core/css/templates/media_features.h.tmpl', filters=filters)
def generate_header(self):
return self._template_context
+
if __name__ == '__main__':
json5_generator.Maker(MakeMediaFeaturesWriter).main()
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 3a18d15ac1a..a3cab6f8bb4 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
@@ -43,9 +43,9 @@ class StylePropertyShorthandWriter(json5_generator.Writer):
self._input_files = json5_file_paths
self._outputs = {
(self._FILE_BASENAME + '.cc'):
- self.generate_style_property_shorthand_cpp,
+ self.generate_style_property_shorthand_cpp,
(self._FILE_BASENAME + '.h'):
- self.generate_style_property_shorthand_h
+ self.generate_style_property_shorthand_h
}
json5_properties = css_properties.CSSProperties(json5_file_paths)
@@ -53,10 +53,10 @@ class StylePropertyShorthandWriter(json5_generator.Writer):
self._longhand_dictionary = defaultdict(list)
for property_ in json5_properties.shorthands:
- property_['longhand_enum_keys'] = map(
- enum_key_for_css_property, property_['longhands'])
- property_['longhand_property_ids'] = map(
- id_for_css_property, property_['longhands'])
+ property_['longhand_enum_keys'] = map(enum_key_for_css_property,
+ property_['longhands'])
+ property_['longhand_property_ids'] = map(id_for_css_property,
+ property_['longhands'])
for longhand_enum_key in property_['longhand_enum_keys']:
self._longhand_dictionary[longhand_enum_key].append(property_)
@@ -64,8 +64,8 @@ class StylePropertyShorthandWriter(json5_generator.Writer):
# Sort first by number of longhands in decreasing order, then
# alphabetically
longhands.sort(
- key=lambda property_: (
- -len(property_['longhand_property_ids']), property_['name'].original)
+ key=
+ lambda property_: (-len(property_['longhand_property_ids']), property_['name'].original)
)
@template_expander.use_jinja(
@@ -81,10 +81,15 @@ class StylePropertyShorthandWriter(json5_generator.Writer):
'core/css/templates/style_property_shorthand.h.tmpl')
def generate_style_property_shorthand_h(self):
return {
- 'input_files': self._input_files,
- 'properties': self._shorthands,
- 'header_guard': self.make_header_guard(self._relative_output_dir + self._FILE_BASENAME + '.h')
+ 'input_files':
+ self._input_files,
+ 'properties':
+ self._shorthands,
+ 'header_guard':
+ self.make_header_guard(self._relative_output_dir +
+ self._FILE_BASENAME + '.h')
}
+
if __name__ == '__main__':
json5_generator.Maker(StylePropertyShorthandWriter).main()
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/parser/make_atrule_names.py b/chromium/third_party/blink/renderer/build/scripts/core/css/parser/make_atrule_names.py
index 2a7d636556e..57af289c474 100755
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/parser/make_atrule_names.py
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/parser/make_atrule_names.py
@@ -13,6 +13,7 @@ class AtRuleNamesWriter(json5_generator.Writer):
Generates AtRuleNames. This class provides utility methods for parsing
@rules (e.g. @font-face, @viewport, etc)
"""
+
def __init__(self, json5_file_paths, output_dir):
super(AtRuleNamesWriter, self).__init__(json5_file_paths, output_dir)
@@ -36,8 +37,7 @@ class AtRuleNamesWriter(json5_generator.Writer):
self._character_offsets.append(chars_used)
chars_used += len(descriptor['name'].original)
self._longest_name_length = max(
- len(descriptor['name'].original),
- len(descriptor['alias']),
+ len(descriptor['name'].original), len(descriptor['alias']),
self._longest_name_length)
@template_expander.use_jinja(
@@ -59,5 +59,6 @@ class AtRuleNamesWriter(json5_generator.Writer):
'gperf_path': self.gperf_path
}
+
if __name__ == '__main__':
json5_generator.Maker(AtRuleNamesWriter).main()
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/properties/make_css_property_instances.py b/chromium/third_party/blink/renderer/build/scripts/core/css/properties/make_css_property_instances.py
index 3d408bba282..75030ac577e 100755
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/properties/make_css_property_instances.py
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/properties/make_css_property_instances.py
@@ -9,8 +9,12 @@ import template_expander
from collections import namedtuple
from core.css import css_properties
+
class PropertyClassData(
- namedtuple('PropertyClassData', 'enum_key,enum_value,property_id,classname,namespace_group,filename')):
+ namedtuple(
+ 'PropertyClassData',
+ 'enum_key,enum_value,property_id,classname,namespace_group,filename'
+ )):
pass
@@ -19,17 +23,16 @@ class CSSPropertyInstancesWriter(json5_generator.Writer):
super(CSSPropertyInstancesWriter, self).__init__([], output_dir)
self._input_files = json5_file_paths
self._outputs = {
- 'css_property_instances.h': self.generate_property_instances_header,
+ 'css_property_instances.h':
+ self.generate_property_instances_header,
'css_property_instances.cc':
- self.generate_property_instances_implementation
+ self.generate_property_instances_implementation
}
# These files are no longer generated. If the files are present from
# a previous build, we remove them. This avoids accidentally #including
# a stale generated header.
self._cleanup = set([
- 'css_property.cc',
- 'css_property.h',
- 'css_unresolved_property.cc',
+ 'css_property.cc', 'css_property.h', 'css_unresolved_property.cc',
'css_unresolved_property.h'
])
@@ -85,5 +88,6 @@ class CSSPropertyInstancesWriter(json5_generator.Writer):
'alias_classes_by_property_id': self._alias_classes_by_id,
}
+
if __name__ == '__main__':
json5_generator.Maker(CSSPropertyInstancesWriter).main()
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/properties/make_css_property_subclasses.py b/chromium/third_party/blink/renderer/build/scripts/core/css/properties/make_css_property_subclasses.py
index e56e8aa9d82..2730c966a06 100755
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/properties/make_css_property_subclasses.py
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/properties/make_css_property_subclasses.py
@@ -17,8 +17,8 @@ CSS_PROPERTIES_CC_TMPL = 'core/css/properties/templates/css_properties.cc.tmpl'
class CSSPropertiesWriter(json5_generator.Writer):
def __init__(self, json5_file_paths, output_dir):
super(CSSPropertiesWriter, self).__init__([], output_dir)
- assert len(json5_file_paths) == 3,\
- ('CSSPropertiesWriter requires 3 input json5 files, ' +
+ assert len(json5_file_paths) == 4,\
+ ('CSSPropertiesWriter requires 4 input json5 files, ' +
'got {}.'.format(len(json5_file_paths)))
self._css_properties = css_properties.CSSProperties(json5_file_paths)
@@ -26,9 +26,10 @@ class CSSPropertiesWriter(json5_generator.Writer):
# Map of property method name -> (return_type, parameters)
self._property_methods = {}
property_methods = json5_generator.Json5File.load_from_files(
- [json5_file_paths[2]])
+ [json5_file_paths[3]])
for property_method in property_methods.name_dictionaries:
- self._property_methods[property_method['name'].original] = property_method
+ self._property_methods[property_method['name'].
+ original] = property_method
all_properties = self._css_properties.properties_including_aliases
@@ -86,5 +87,6 @@ class CSSPropertiesWriter(json5_generator.Writer):
'is_longhand': False,
}
+
if __name__ == '__main__':
json5_generator.Maker(CSSPropertiesWriter).main()
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.cc.tmpl b/chromium/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.cc.tmpl
index 2118a3c88f0..b902908c055 100644
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.cc.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.cc.tmpl
@@ -22,6 +22,7 @@
#include "third_party/blink/renderer/core/css/resolver/font_builder.h"
#include "third_party/blink/renderer/core/css/resolver/style_builder_converter.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style/style_svg_resource.h"
#include "third_party/blink/renderer/core/style/svg_computed_style.h"
@@ -35,7 +36,7 @@ namespace {{namespace}} {
{% set is_alias = property.alias_for %}
// {{property.name}}
- {% if property.is_internal or property.runtime_flag %}
+ {% if property.is_internal or property.runtime_flag and not property.in_origin_trial%}
CSSExposure {{class_name}}::Exposure() const {
{% if property.runtime_flag %}
if (!RuntimeEnabledFeatures::{{property.runtime_flag}}Enabled())
@@ -49,6 +50,14 @@ CSSExposure {{class_name}}::Exposure() const {
}
{% endif %}
+ {% if property.in_origin_trial %}
+CSSExposure {{class_name}}::Exposure(const ExecutionContext* execution_context) const {
+ if (!RuntimeEnabledFeatures::{{property.runtime_flag}}Enabled(execution_context))
+ return CSSExposure::kNone;
+ return CSSExposure::kWeb;
+}
+ {% endif %}
+
const char* {{class_name}}::GetPropertyName() const {
return "{{property.name}}";
}
@@ -73,10 +82,21 @@ const CSSProperty* {{class_name}}::GetUnvisitedProperty() const {
}
{% endif %}
+ {% if property.surrogate_for %}
+const CSSProperty* {{class_name}}::SurrogateFor(TextDirection direction,
+ blink::WritingMode writing_mode) const {
+ return &GetCSSProperty{{property.surrogate_for.name.to_upper_camel_case()}}();
+}
+ {% endif %}
{% if property.direction_aware_options %}
{% set options = property.direction_aware_options %}
{% set resolver_name = options.resolver_name.to_upper_camel_case() %}
{% set physical_group_name = options.physical_group_name.to_upper_camel_case() %}
+const CSSProperty* {{class_name}}::SurrogateFor(TextDirection direction,
+ blink::WritingMode writing_mode) const {
+ return &ResolveDirectionAwareProperty(direction, writing_mode);
+}
+
const CSSProperty& {{class_name}}::ResolveDirectionAwareProperty(
TextDirection direction,
blink::WritingMode writing_mode) const {
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.h.tmpl b/chromium/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.h.tmpl
index e5f3f97399d..d4ea23428b5 100644
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.h.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/properties/templates/css_properties.h.tmpl
@@ -29,6 +29,7 @@ namespace {{namespace}} {
{% for property in properties %}
{% set class_name = property.name.to_upper_camel_case() %}
{% set is_alias = property.alias_for %}
+{% set is_surrogate = property.surrogate_for or property.direction_aware_options %}
{% set property_id = 'CSSPropertyID::' + property.enum_key %}
{% set separator = '\'' + (property.separator or '\\0') + '\'' %}
{% set flags = [
@@ -40,6 +41,12 @@ namespace {{namespace}} {
(property.visited and 'kVisited' or ''),
(property.is_internal and 'kInternal' or ''),
(property.affected_by_forced_colors and 'kIsAffectedByForcedColors' or ''),
+ (property.is_animation_property and 'kAnimation' or ''),
+ (property.valid_for_first_letter and 'kValidForFirstLetter' or ''),
+ (property.valid_for_cue and 'kValidForCue' or ''),
+ (property.valid_for_marker and 'kValidForMarker' or ''),
+ (is_surrogate and 'kSurrogate' or ''),
+ (property.font and 'kAffectsFont' or ''),
] | reject('==', '') | join(' | ') %}
{% set ctor_args = (not is_alias and [property_id, flags, separator] or []) %}
// {{property.name}}
@@ -49,9 +56,12 @@ class {{class_name}} final : public {{property.superclass}} {
const char* GetPropertyName() const override;
const WTF::AtomicString& GetPropertyNameAtomicString() const override;
const char* GetJSPropertyName() const override;
- {% if property.is_internal or property.runtime_flag %}
+ {% if property.is_internal or property.runtime_flag and not property.in_origin_trial%}
CSSExposure Exposure() const override;
{% endif %}
+ {% if property.in_origin_trial %}
+ CSSExposure Exposure(const ExecutionContext*) const override;
+ {% endif %}
{% if not is_alias %}
{% if not property.affected_by_all %}
bool IsAffectedByAll() const override { return false; }
@@ -66,6 +76,9 @@ class {{class_name}} final : public {{property.superclass}} {
{% if property.unvisited_property %}
const CSSProperty* GetUnvisitedProperty() const override;
{% endif %}
+ {% if property.surrogate_for or property.direction_aware_options %}
+ const CSSProperty* SurrogateFor(TextDirection, blink::WritingMode) const override;
+ {% endif %}
{% for property_method in property.property_methods %}
{{property_method.return_type}} {{property_method.name}}{{property_method.parameters}} const override;
{% endfor %}
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 9c9142d93f4..17f94e9efac 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
@@ -143,7 +143,7 @@ To<Longhand>(resolved_property).{{apply_call}};
{# Check for equality in case we can bail out before creating a new NinePieceImage. #}
{% if modifier_type == 'Outset' %}
if (style_building_utils::BorderImageLengthMatchesAllSides(current_image.Outset(),
- BorderImageLength(Length::Fixed(0))))
+ BorderImageLength(0)))
return;
{% elif modifier_type == 'Repeat' %}
if (current_image.HorizontalRule() == kStretchImageRule &&
@@ -172,7 +172,7 @@ To<Longhand>(resolved_property).{{apply_call}};
{% endif %}
NinePieceImage image(current_image);
{% if modifier_type == 'Outset' %}
- image.SetOutset(Length::Fixed(0));
+ image.SetOutset(0);
{% elif modifier_type == 'Repeat' %}
image.SetHorizontalRule(kStretchImageRule);
image.SetVerticalRule(kStretchImageRule);
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/templates/css_property_names.cc.tmpl b/chromium/third_party/blink/renderer/build/scripts/core/css/templates/css_property_names.cc.tmpl
index 9134acd36f7..e85ab80e94f 100644
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/templates/css_property_names.cc.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/templates/css_property_names.cc.tmpl
@@ -40,9 +40,9 @@ const Property* FindProperty(const char* str, unsigned int len) {
return {{class_name}}Hash::findPropertyImpl(str, len);
}
-CSSPropertyID cssPropertyID(const String& string)
+CSSPropertyID cssPropertyID(const ExecutionContext* execution_context, const String& string)
{
- return resolveCSSPropertyID(unresolvedCSSPropertyID(string));
+ return resolveCSSPropertyID(unresolvedCSSPropertyID(execution_context, string));
}
mojom::blink::CSSSampleId GetCSSSampleId(CSSPropertyID id) {
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/css/templates/css_property_names.h.tmpl b/chromium/third_party/blink/renderer/build/scripts/core/css/templates/css_property_names.h.tmpl
index a6995d6c04d..da7252fe948 100644
--- a/chromium/third_party/blink/renderer/build/scripts/core/css/templates/css_property_names.h.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/core/css/templates/css_property_names.h.tmpl
@@ -17,6 +17,8 @@ class String;
namespace blink {
+class ExecutionContext;
+
enum class CSSPropertyID {
kInvalid = 0,
kVariable = 1,
@@ -66,9 +68,9 @@ inline CSSPropertyID resolveCSSPropertyID(CSSPropertyID id)
inline bool isPropertyAlias(CSSPropertyID id) { return static_cast<int>(id) & {{alias_offset}}; }
-CSSPropertyID CORE_EXPORT unresolvedCSSPropertyID(const WTF::String&);
+CSSPropertyID CORE_EXPORT unresolvedCSSPropertyID(const ExecutionContext*, const WTF::String&);
-CSSPropertyID CORE_EXPORT cssPropertyID(const WTF::String&);
+CSSPropertyID CORE_EXPORT cssPropertyID(const ExecutionContext*, const WTF::String&);
class CSSPropertyIDList {
STACK_ALLOCATED();
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/style/OWNERS b/chromium/third_party/blink/renderer/build/scripts/core/style/OWNERS
index 44d94a9f509..59049c360d9 100644
--- a/chromium/third_party/blink/renderer/build/scripts/core/style/OWNERS
+++ b/chromium/third_party/blink/renderer/build/scripts/core/style/OWNERS
@@ -1,7 +1,2 @@
file://third_party/blink/renderer/core/style/OWNERS
-andruud@chromium.org
-futhark@chromium.org
-
-# TEAM: layout-dev@chromium.org
-# COMPONENT: Blink>CSS
diff --git a/chromium/third_party/blink/renderer/build/scripts/core/style/computed_style_fields.py b/chromium/third_party/blink/renderer/build/scripts/core/style/computed_style_fields.py
index f7bf935109e..6de3f6a365c 100644
--- a/chromium/third_party/blink/renderer/build/scripts/core/style/computed_style_fields.py
+++ b/chromium/third_party/blink/renderer/build/scripts/core/style/computed_style_fields.py
@@ -35,6 +35,7 @@ class Group(object):
fields: List of Field instances stored directly under this group.
parent: The parent group, or None if this is the root group.
"""
+
def __init__(self, name, subgroups, fields):
self.name = name
self.subgroups = subgroups
@@ -45,12 +46,11 @@ class Group(object):
self.type_name = converter.to_class_name(prefix='style', suffix='data')
self.member_name = converter.to_class_data_member(suffix='data')
self.num_32_bit_words_for_bit_fields = _num_32_bit_words_for_bit_fields(
- field for field in fields if field.is_bit_field
- )
+ field for field in fields if field.is_bit_field)
# Recursively get all the fields in the subgroups as well
- self.all_fields = _flatten_list(
- subgroup.all_fields for subgroup in subgroups) + fields
+ self.all_fields = _flatten_list(subgroup.all_fields
+ for subgroup in subgroups) + fields
# Ensure that all fields/subgroups on this group link to it
for field in fields:
@@ -75,10 +75,12 @@ class Group(object):
class Enum(object):
"""Represents a generated enum in ComputedStyleBaseConstants."""
+
def __init__(self, type_name, keywords, is_set):
self.type_name = type_name
- self.values = [NameStyleConverter(keyword).to_enum_value()
- for keyword in keywords]
+ self.values = [
+ NameStyleConverter(keyword).to_enum_value() for keyword in keywords
+ ]
self.is_set = is_set
@@ -92,6 +94,7 @@ class DiffGroup(object):
expressions: List of expression that are on this group that need to
be diffed.
"""
+
def __init__(self, group):
self.group = group
self.subgroups = []
@@ -155,11 +158,15 @@ class Field(object):
# Method names
self.getter_method_name = getter_method_name
self.setter_method_name = setter_method_name
- self.internal_getter_method_name = name_source.to_function_name(suffix='internal')
- self.internal_mutable_method_name = name_source.to_function_name(prefix='mutable', suffix='internal')
- self.internal_setter_method_name = NameStyleConverter(setter_method_name).to_function_name(suffix='internal')
+ self.internal_getter_method_name = name_source.to_function_name(
+ suffix='internal')
+ self.internal_mutable_method_name = name_source.to_function_name(
+ prefix='mutable', suffix='internal')
+ self.internal_setter_method_name = NameStyleConverter(
+ setter_method_name).to_function_name(suffix='internal')
self.initial_method_name = initial_method_name
- self.resetter_method_name = name_source.to_function_name(prefix='reset')
+ self.resetter_method_name = name_source.to_function_name(
+ prefix='reset')
self.computed_style_custom_functions = computed_style_custom_functions
# Only bitfields have sizes.
self.is_bit_field = self.size is not None
@@ -176,6 +183,7 @@ class Field(object):
assert self.is_inherited or not self.is_independent, \
'Only inherited fields can be independent'
- self.is_inherited_method_name = name_source.to_function_name(suffix=['is', 'inherited'])
+ self.is_inherited_method_name = name_source.to_function_name(
+ suffix=['is', 'inherited'])
assert len(kwargs) == 0, \
'Unexpected arguments provided to Field: ' + str(kwargs)
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 053e15072f3..492ff31435c 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
@@ -29,6 +29,7 @@ ALIGNMENT_ORDER = [
'ScaleTransformOperation',
'RotateTransformOperation',
'TranslateTransformOperation',
+ 'base::Optional<IntSize>',
'double',
# Aligns like a pointer (can be 32 or 64 bits)
'NamedGridLinesMap',
@@ -88,6 +89,7 @@ ALIGNMENT_ORDER = [
# FIXME: Improve documentation and add docstrings.
+
def _flatten_list(x):
"""Flattens a list of lists into a single list."""
return list(chain.from_iterable(x))
@@ -109,6 +111,7 @@ def _create_groups(properties):
Returns:
Group: The root group of the tree. The name of the group is set to None.
"""
+
# We first convert properties into a dictionary structure. Each dictionary
# represents a group. The None key corresponds to the fields directly stored
# on that group. The other keys map from group name to another dictionary.
@@ -127,8 +130,9 @@ def _create_groups(properties):
def _dict_to_group(name, group_dict):
fields_in_current_group = group_dict.pop(None)
subgroups = [
- _dict_to_group(subgroup_name, subgroup_dict) for subgroup_name,
- subgroup_dict in group_dict.items()]
+ _dict_to_group(subgroup_name, subgroup_dict)
+ for subgroup_name, subgroup_dict in group_dict.items()
+ ]
return Group(name, subgroups, _reorder_fields(fields_in_current_group))
root_group_dict = {None: []}
@@ -171,32 +175,32 @@ def _list_field_dependencies(entries_with_field_dependencies):
return field_dependencies
-def _create_diff_groups(fields_to_diff,
- methods_to_diff,
- predicates_to_test,
+def _create_diff_groups(fields_to_diff, methods_to_diff, predicates_to_test,
root_group):
diff_group = DiffGroup(root_group)
- field_dependencies = _list_field_dependencies(
- methods_to_diff + predicates_to_test)
+ field_dependencies = _list_field_dependencies(methods_to_diff +
+ predicates_to_test)
for subgroup in root_group.subgroups:
- if any(field.property_name in (fields_to_diff + field_dependencies)
- for field in subgroup.all_fields):
- diff_group.subgroups.append(_create_diff_groups(
- fields_to_diff, methods_to_diff, predicates_to_test, subgroup))
+ if any(
+ field.property_name in (fields_to_diff + field_dependencies)
+ for field in subgroup.all_fields):
+ diff_group.subgroups.append(
+ _create_diff_groups(fields_to_diff, methods_to_diff,
+ predicates_to_test, subgroup))
for entry in fields_to_diff:
for field in root_group.fields:
if not field.is_inherited_flag and entry == field.property_name:
diff_group.fields.append(field)
for entry in methods_to_diff:
for field in root_group.fields:
- if (not field.is_inherited_flag and
- field.property_name in entry['field_dependencies'] and
- entry['method'] not in diff_group.expressions):
+ if (not field.is_inherited_flag
+ and field.property_name in entry['field_dependencies']
+ and entry['method'] not in diff_group.expressions):
diff_group.expressions.append(entry['method'])
for entry in predicates_to_test:
for field in root_group.fields:
- if (not field.is_inherited_flag and
- field.property_name in entry['field_dependencies']
+ if (not field.is_inherited_flag
+ and field.property_name in entry['field_dependencies']
and entry['predicate'] not in diff_group.predicates):
diff_group.predicates.append(entry['predicate'])
return diff_group
@@ -208,10 +212,12 @@ def _create_enums(properties):
for property_ in properties:
# Only generate enums for keyword properties that do not
# require includes.
- if (property_['field_template'] in ('keyword', 'multi_keyword') and
- len(property_['include_paths']) == 0):
- enum = Enum(property_['type_name'], property_['keywords'],
- is_set=(property_['field_template'] == 'multi_keyword'))
+ if (property_['field_template'] in ('keyword', 'multi_keyword')
+ and len(property_['include_paths']) == 0):
+ enum = Enum(
+ property_['type_name'],
+ property_['keywords'],
+ is_set=(property_['field_template'] == 'multi_keyword'))
if property_['field_template'] == 'multi_keyword':
assert property_['keywords'][0] == 'none', \
"First keyword in a 'multi_keyword' field must be " \
@@ -290,7 +296,9 @@ def _create_inherited_flag_field(property_):
Create the field used for an inheritance fast path from an independent CSS
property, and return the Field object.
"""
- name_for_methods = NameStyleConverter(property_['name_for_methods']).to_function_name(suffix=['is', 'inherited'])
+ name_for_methods = NameStyleConverter(
+ property_['name_for_methods']).to_function_name(
+ suffix=['is', 'inherited'])
name_source = NameStyleConverter(name_for_methods)
return Field(
'inherited_flag',
@@ -365,8 +373,10 @@ def _reorder_non_bit_fields(non_bit_fields):
assert field.alignment_type in ALIGNMENT_ORDER, \
"Type {} has unknown alignment. Please update ALIGNMENT_ORDER " \
"to include it.".format(field.name)
- return list(sorted(
- non_bit_fields, key=lambda f: ALIGNMENT_ORDER.index(f.alignment_type)))
+ return list(
+ sorted(
+ non_bit_fields,
+ key=lambda f: ALIGNMENT_ORDER.index(f.alignment_type)))
def _reorder_fields(fields):
@@ -378,12 +388,12 @@ def _reorder_fields(fields):
non_bit_fields = [field for field in fields if not field.is_bit_field]
# Non bit fields go first, then the bit fields.
- return _reorder_non_bit_fields(
- non_bit_fields) + _reorder_bit_fields(bit_fields)
+ return _reorder_non_bit_fields(non_bit_fields) + _reorder_bit_fields(
+ bit_fields)
-def _get_properties_ranking_using_partition_rule(
- properties_ranking, partition_rule):
+def _get_properties_ranking_using_partition_rule(properties_ranking,
+ partition_rule):
"""Take the contents of the properties ranking file and produce a dictionary
of css properties with their group number based on the partition_rule
@@ -398,13 +408,31 @@ def _get_properties_ranking_using_partition_rule(
"""
return dict(
zip(properties_ranking, [
- bisect.bisect_left(
- partition_rule, float(i) / len(properties_ranking)) + 1
- for i in range(len(properties_ranking))]))
+ bisect.bisect_left(partition_rule,
+ float(i) / len(properties_ranking)) + 1
+ for i in range(len(properties_ranking))
+ ]))
+
+
+def _best_rank(prop, ranking_map):
+ """Return the best ranking value for the specified property.
+
+ This function collects ranking values for not only the property's real name
+ but also its aliases, and returns the best (lower is better) value.
+ If no ranking values for the property is available, this returns -1.
+ """
+ worst_rank = max(ranking_map.values()) + 1
+ best_rank = ranking_map.get(prop["name"].original, worst_rank)
+ for alias_name in prop.get("aliases", []):
+ best_rank = min(best_rank, ranking_map.get(alias_name, worst_rank))
+ return best_rank if best_rank != worst_rank else -1
-def _evaluate_rare_non_inherited_group(properties, properties_ranking,
- num_layers, partition_rule=None):
+
+def _evaluate_rare_non_inherited_group(properties,
+ properties_ranking,
+ num_layers,
+ partition_rule=None):
"""Re-evaluate the grouping of RareNonInherited groups based on each
property's popularity.
@@ -417,42 +445,42 @@ def _evaluate_rare_non_inherited_group(properties, properties_ranking,
"""
if partition_rule is None:
partition_rule = [
- 1.0 * (i + 1) / num_layers for i in range(num_layers)]
+ 1.0 * (i + 1) / num_layers for i in range(num_layers)
+ ]
assert num_layers == len(partition_rule), \
"Length of rule and num_layers mismatch"
layers_name = [
"rare-non-inherited-usage-less-than-{}-percent".format(
- int(round(partition_rule[i] * 100)))
- for i in range(num_layers)
+ int(round(partition_rule[i] * 100))) for i in range(num_layers)
]
properties_ranking = _get_properties_ranking_using_partition_rule(
properties_ranking, partition_rule)
for property_ in properties:
- if (property_["field_group"] is not None and
- "*" in property_["field_group"]
- and not property_["inherited"] and
- property_["name"].original in properties_ranking):
+ rank = _best_rank(property_, properties_ranking)
+ if (property_["field_group"] is not None
+ and "*" in property_["field_group"]
+ and not property_["inherited"] and rank >= 0):
assert property_["field_group"] == "*", \
"The property {} will be automatically assigned a group, " \
"please put '*' as the field_group".format(property_['name'])
- property_["field_group"] = "->".join(
- layers_name[0:properties_ranking[property_["name"].original]])
- elif property_["field_group"] is not None and \
- "*" in property_["field_group"] and \
- not property_["inherited"] and \
- property_["name"].original not in properties_ranking:
+ property_["field_group"] = "->".join(layers_name[0:rank])
+ elif (property_["field_group"] is not None
+ and "*" in property_["field_group"]
+ and not property_["inherited"] and rank < 0):
group_tree = property_["field_group"].split("->")[1:]
group_tree = [layers_name[0], layers_name[0] + "-sub"] + group_tree
property_["field_group"] = "->".join(group_tree)
-def _evaluate_rare_inherit_group(properties, properties_ranking,
- num_layers, partition_rule=None):
+def _evaluate_rare_inherit_group(properties,
+ properties_ranking,
+ num_layers,
+ partition_rule=None):
"""Re-evaluate the grouping of RareInherited groups based on each property's
popularity.
@@ -473,24 +501,21 @@ def _evaluate_rare_inherit_group(properties, properties_ranking,
layers_name = [
"rare-inherited-usage-less-than-{}-percent".format(
- int(round(partition_rule[i] * 100)))
- for i in range(num_layers)
+ int(round(partition_rule[i] * 100))) for i in range(num_layers)
]
properties_ranking = _get_properties_ranking_using_partition_rule(
properties_ranking, partition_rule)
for property_ in properties:
- if property_["field_group"] is not None and \
- "*" in property_["field_group"] \
- and property_["inherited"] and \
- property_["name"].original in properties_ranking:
- property_["field_group"] = "->".join(
- layers_name[0:properties_ranking[property_["name"].original]])
- elif property_["field_group"] is not None and \
- "*" in property_["field_group"] \
- and property_["inherited"] and \
- property_["name"].original not in properties_ranking:
+ rank = _best_rank(property_, properties_ranking)
+ if (property_["field_group"] is not None
+ and "*" in property_["field_group"] and property_["inherited"]
+ and rank >= 0):
+ property_["field_group"] = "->".join(layers_name[0:rank])
+ elif (property_["field_group"] is not None
+ and "*" in property_["field_group"] and property_["inherited"]
+ and rank < 0):
group_tree = property_["field_group"].split("->")[1:]
group_tree = [layers_name[0], layers_name[0] + "-sub"] + group_tree
property_["field_group"] = "->".join(group_tree)
@@ -502,10 +527,10 @@ class ComputedStyleBaseWriter(json5_generator.Writer):
self._input_files = json5_file_paths
- # Reads css_properties.json5, computed_style_field_aliases.json5 and
- # computed_style_extra_fields.json5
+ # Reads css_properties.json5, computed_style_field_aliases.json5,
+ # runtime_enabled_features.json5 and computed_style_extra_fields.json5
self._css_properties = css_properties.CSSProperties(
- json5_file_paths[0:3])
+ json5_file_paths[0:4])
# We sort the enum values based on each value's position in
# the keywords as listed in css_properties.json5. This will ensure that
@@ -515,8 +540,7 @@ class ComputedStyleBaseWriter(json5_generator.Writer):
# css_properties.json5 and we can get the longest continuous segment.
# Thereby reduce the switch case statement to the minimum.
properties = keyword_utils.sort_keyword_properties_by_canonical_order(
- self._css_properties.longhands,
- json5_file_paths[4],
+ self._css_properties.longhands, json5_file_paths[5],
self.default_parameters)
self._properties = properties + self._css_properties.extra_fields
@@ -524,41 +548,43 @@ class ComputedStyleBaseWriter(json5_generator.Writer):
# Organise fields into a tree structure where the root group
# is ComputedStyleBase.
- group_parameters = dict([
- (conf["name"], conf["cumulative_distribution"]) for conf in
- json5_generator.Json5File.load_from_files(
- [json5_file_paths[6]]).name_dictionaries])
+ group_parameters = dict(
+ [(conf["name"], conf["cumulative_distribution"])
+ for conf in json5_generator.Json5File.load_from_files(
+ [json5_file_paths[7]]).name_dictionaries])
properties_ranking = [
- x["name"].original for x in json5_generator.Json5File.load_from_files(
- [json5_file_paths[5]]).name_dictionaries
+ x["name"].original for x in json5_generator.Json5File.
+ load_from_files([json5_file_paths[6]]).name_dictionaries
]
_evaluate_rare_non_inherited_group(
- self._properties,
- properties_ranking,
+ self._properties, properties_ranking,
len(group_parameters["rare_non_inherited_properties_rule"]),
group_parameters["rare_non_inherited_properties_rule"])
_evaluate_rare_inherit_group(
- self._properties,
- properties_ranking,
+ self._properties, properties_ranking,
len(group_parameters["rare_inherited_properties_rule"]),
group_parameters["rare_inherited_properties_rule"])
self._root_group = _create_groups(self._properties)
self._diff_functions_map = _create_diff_groups_map(
json5_generator.Json5File.load_from_files(
- [json5_file_paths[3]]).name_dictionaries,
- self._root_group)
+ [json5_file_paths[4]]).name_dictionaries, self._root_group)
self._include_paths = _get_include_paths(self._properties)
self._outputs = {
- 'computed_style_base.h': self.generate_base_computed_style_h,
- 'computed_style_base.cc': self.generate_base_computed_style_cpp,
+ 'computed_style_base.h':
+ self.generate_base_computed_style_h,
+ 'computed_style_base.cc':
+ self.generate_base_computed_style_cpp,
'computed_style_base_constants.h':
- self.generate_base_computed_style_constants,
+ self.generate_base_computed_style_constants,
}
@template_expander.use_jinja(
- 'core/style/templates/computed_style_base.h.tmpl', tests={'in': lambda a, b: a in b})
+ 'core/style/templates/computed_style_base.h.tmpl',
+ tests={
+ 'in': lambda a, b: a in b
+ })
def generate_base_computed_style_h(self):
return {
'input_files': self._input_files,
@@ -571,7 +597,9 @@ class ComputedStyleBaseWriter(json5_generator.Writer):
@template_expander.use_jinja(
'core/style/templates/computed_style_base.cc.tmpl',
- tests={'in': lambda a, b: a in b})
+ tests={
+ 'in': lambda a, b: a in b
+ })
def generate_base_computed_style_cpp(self):
return {
'input_files': self._input_files,
@@ -582,7 +610,8 @@ class ComputedStyleBaseWriter(json5_generator.Writer):
'diff_functions_map': self._diff_functions_map,
}
- @template_expander.use_jinja('core/style/templates/computed_style_base_constants.h.tmpl')
+ @template_expander.use_jinja(
+ 'core/style/templates/computed_style_base_constants.h.tmpl')
def generate_base_computed_style_constants(self):
return {
'input_files': self._input_files,
@@ -590,5 +619,6 @@ class ComputedStyleBaseWriter(json5_generator.Writer):
'enums': self._generated_enums,
}
+
if __name__ == '__main__':
json5_generator.Maker(ComputedStyleBaseWriter).main()
diff --git a/chromium/third_party/blink/renderer/build/scripts/gperf.py b/chromium/third_party/blink/renderer/build/scripts/gperf.py
index ad15e68853b..5ee49056be4 100644
--- a/chromium/third_party/blink/renderer/build/scripts/gperf.py
+++ b/chromium/third_party/blink/renderer/build/scripts/gperf.py
@@ -38,7 +38,15 @@ def generate_gperf(gperf_path, gperf_input, gperf_args):
# -Wimplicit-fallthrough needs an explicit fallthrough statement,
# so replace gperf's /*FALLTHROUGH*/ comment with the statement.
# https://savannah.gnu.org/bugs/index.php?53029
- gperf_output = gperf_output.replace('/*FALLTHROUGH*/', ' FALLTHROUGH;')
+ gperf_output = gperf_output.replace('/*FALLTHROUGH*/',
+ ' FALLTHROUGH;')
+ # -Wpointer-to-int-cast warns about casting pointers to smaller ints
+ # Replace {(int)(long)&(foo), bar} with
+ # {static_cast<int>(reinterpret_cast<uintptr_t>(&(foo)), bar}
+ gperf_output = re.sub(
+ r'\(int\)\(long\)(.*?),',
+ r'static_cast<int>(reinterpret_cast<uintptr_t>(\1)),',
+ gperf_output)
script = 'third_party/blink/renderer/build/scripts/gperf.py'
return '// Generated by %s\n' % script + gperf_output
except OSError:
@@ -53,16 +61,19 @@ def use_jinja_gperf_template(template_path, gperf_extra_args=None):
assert 'gperf_path' in parameters, 'Must specify gperf_path in ' \
'template map returned from decorated function'
gperf_path = parameters['gperf_path']
- gperf_input = template_expander.apply_template(template_path,
- parameters)
+ gperf_input = template_expander.apply_template(
+ template_path, parameters)
gperf_args = ['--key-positions=*', '-P', '-n']
gperf_args.extend(['-m', '50']) # Pick best of 50 attempts.
- gperf_args.append('-D') # Allow duplicate hashes -> More compact code.
+ # Allow duplicate hashes -> More compact code.
+ gperf_args.append('-D')
if gperf_extra_args:
gperf_args.extend(gperf_extra_args)
return generate_gperf(gperf_path, gperf_input, gperf_args)
- generator_internal.func_name = generator.func_name
+
+ generator_internal.__name__ = generator.__name__
return generator_internal
+
return wrapper
@@ -83,7 +94,9 @@ def main():
gperf_args.remove(infile)
open(args.output_file, 'wb').write(
- generate_gperf(gperf_path, open(infile).read(), gperf_args))
+ generate_gperf(gperf_path,
+ open(infile).read(), gperf_args))
+
if __name__ == '__main__':
main()
diff --git a/chromium/third_party/blink/renderer/build/scripts/hasher.py b/chromium/third_party/blink/renderer/build/scripts/hasher.py
index a608fb7321f..2b356fd495d 100644
--- a/chromium/third_party/blink/renderer/build/scripts/hasher.py
+++ b/chromium/third_party/blink/renderer/build/scripts/hasher.py
@@ -20,18 +20,24 @@
# We've modified Victor's version to output hash values that match WTFString,
# which involves using a specific seed and some different constants.
+import sys
+
+if sys.version_info.major != 2:
+ long = int
+
+
class uint32_t(long):
def __rshift__(self, other):
- return uint32_t(long.__rshift__(self, other) & ((1L << 32) - 1))
+ return uint32_t(long.__rshift__(self, other) & ((1 << 32) - 1))
def __lshift__(self, other):
- return uint32_t(long.__lshift__(self, other) & ((1L << 32) - 1))
+ return uint32_t(long.__lshift__(self, other) & ((1 << 32) - 1))
def __add__(self, other):
- return uint32_t(long.__add__(self, other) & ((1L << 32) - 1))
+ return uint32_t(long.__add__(self, other) & ((1 << 32) - 1))
def __xor__(self, other):
- return uint32_t(long.__xor__(self, other) & ((1L << 32) - 1))
+ return uint32_t(long.__xor__(self, other) & ((1 << 32) - 1))
def hash(string):
@@ -46,7 +52,7 @@ def hash(string):
if not string:
return 0
- result = uint32_t(0x9E3779B9L)
+ result = uint32_t(0x9E3779B9)
length = len(string)
remainder = length & 1
length >>= 1
diff --git a/chromium/third_party/blink/renderer/build/scripts/in_file.py b/chromium/third_party/blink/renderer/build/scripts/in_file.py
index bcdf793e358..28adc050f1e 100644
--- a/chromium/third_party/blink/renderer/build/scripts/in_file.py
+++ b/chromium/third_party/blink/renderer/build/scripts/in_file.py
@@ -26,6 +26,8 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+from __future__ import print_function
+
import copy
import os
@@ -45,30 +47,40 @@ import os
# Parsing produces an array of dictionaries:
# [ { 'name' : 'name1', 'arg' :' value', arg2=['value2', 'value3'] }
+
def _is_comment(line):
return line.startswith("//") or line.startswith("#")
+
class InFile(object):
- def __init__(self, file_paths, lines, defaults, valid_values=None, default_parameters=None):
+ def __init__(self,
+ file_paths,
+ lines,
+ defaults,
+ valid_values=None,
+ default_parameters=None):
self.file_paths = file_paths
self.name_dictionaries = []
- self.parameters = copy.deepcopy(default_parameters if default_parameters else {})
+ self.parameters = copy.deepcopy(
+ default_parameters if default_parameters else {})
self._defaults = defaults
- self._valid_values = copy.deepcopy(valid_values if valid_values else {})
+ self._valid_values = copy.deepcopy(
+ valid_values if valid_values else {})
self._parse(map(str.strip, lines))
@classmethod
- def load_from_files(self, file_paths, defaults, valid_values, default_parameters):
+ def load_from_files(self, file_paths, defaults, valid_values,
+ default_parameters):
lines = []
for path in file_paths:
assert path.endswith(".in")
with open(os.path.abspath(path)) as in_file:
lines += in_file.readlines()
- return InFile(file_paths, lines, defaults, valid_values, default_parameters)
+ return InFile(file_paths, lines, defaults, valid_values,
+ default_parameters)
def _is_sequence(self, arg):
- return (not hasattr(arg, "strip")
- and hasattr(arg, "__getitem__")
+ return (not hasattr(arg, "strip") and hasattr(arg, "__getitem__")
or hasattr(arg, "__iter__"))
def _parse(self, lines):
@@ -86,19 +98,20 @@ class InFile(object):
entry = self._parse_line(line)
name = entry['name']
if name in indices:
- entry = self._merge_entries(entry, self.name_dictionaries[indices[name]])
+ entry = self._merge_entries(
+ entry, self.name_dictionaries[indices[name]])
entry['name'] = name
self.name_dictionaries[indices[name]] = entry
else:
indices[name] = len(self.name_dictionaries)
self.name_dictionaries.append(entry)
-
def _merge_entries(self, one, two):
merged = {}
for key in one:
if key not in two:
- self._fatal("Expected key '%s' not found in entry: %s" % (key, two))
+ self._fatal(
+ "Expected key '%s' not found in entry: %s" % (key, two))
if one[key] and two[key]:
val_one = one[key]
val_two = two[key]
@@ -128,7 +141,9 @@ class InFile(object):
else:
name, value = line, True
if not name in self.parameters:
- self._fatal("Unknown parameter: '%s' in line:\n%s\nKnown parameters: %s" % (name, line, self.parameters.keys()))
+ self._fatal(
+ "Unknown parameter: '%s' in line:\n%s\nKnown parameters: %s" %
+ (name, line, self.parameters.keys()))
self.parameters[name] = value
def _parse_line(self, line):
@@ -139,17 +154,21 @@ class InFile(object):
args_list = ' '.join(parts[1:]).strip().split(',')
for arg_string in args_list:
arg_string = arg_string.strip()
- if not arg_string: # Ignore empty args
+ if not arg_string: # Ignore empty args
continue
if '=' in arg_string:
arg_name, arg_value = arg_string.split('=')
else:
arg_name, arg_value = arg_string, True
if arg_name not in self._defaults:
- self._fatal("Unknown argument: '%s' in line:\n%s\nKnown arguments: %s" % (arg_name, line, self._defaults.keys()))
+ self._fatal(
+ "Unknown argument: '%s' in line:\n%s\nKnown arguments: %s"
+ % (arg_name, line, self._defaults.keys()))
valid_values = self._valid_values.get(arg_name)
if valid_values and arg_value not in valid_values:
- self._fatal("Unknown value: '%s' in line:\n%s\nKnown values: %s" % (arg_value, line, valid_values))
+ self._fatal(
+ "Unknown value: '%s' in line:\n%s\nKnown values: %s" %
+ (arg_value, line, valid_values))
if self._is_sequence(args[arg_name]):
args[arg_name].extend(self._parse_value_sequence(arg_value))
else:
@@ -158,5 +177,5 @@ class InFile(object):
def _fatal(self, message):
# FIXME: This should probably raise instead of exit(1)
- print message
+ print(message)
exit(1)
diff --git a/chromium/third_party/blink/renderer/build/scripts/in_file_unittest.py b/chromium/third_party/blink/renderer/build/scripts/in_file_unittest.py
index 45229034717..eb93ee502f2 100755
--- a/chromium/third_party/blink/renderer/build/scripts/in_file_unittest.py
+++ b/chromium/third_party/blink/renderer/build/scripts/in_file_unittest.py
@@ -31,6 +31,7 @@ import unittest
from in_file import InFile
+
class InFileTest(unittest.TestCase):
def test_basic_parse(self):
contents = """
@@ -44,8 +45,16 @@ name2
}
in_file = InFile(['test_basic_parse.in'], lines, defaults, None)
expected_values = [
- {'name': 'name1', 'arg': 'value', 'arg2': ['value2', 'value3']},
- {'name': 'name2', 'arg': None, 'arg2': []},
+ {
+ 'name': 'name1',
+ 'arg': 'value',
+ 'arg2': ['value2', 'value3']
+ },
+ {
+ 'name': 'name2',
+ 'arg': None,
+ 'arg2': []
+ },
]
self.assertEquals(in_file.name_dictionaries, expected_values)
@@ -65,7 +74,9 @@ name2
'namespace': '',
'fruit': False,
}
- in_file = InFile(['test_with_parameters.in'], lines, defaults,
+ in_file = InFile(['test_with_parameters.in'],
+ lines,
+ defaults,
default_parameters=default_parameters)
expected_parameters = {
'namespace': 'TestNamespace',
diff --git a/chromium/third_party/blink/renderer/build/scripts/in_generator.py b/chromium/third_party/blink/renderer/build/scripts/in_generator.py
index 34e0c974910..e46740a2e85 100644
--- a/chromium/third_party/blink/renderer/build/scripts/in_generator.py
+++ b/chromium/third_party/blink/renderer/build/scripts/in_generator.py
@@ -26,6 +26,8 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+from __future__ import print_function
+
import os
import os.path
import shlex
@@ -79,7 +81,9 @@ class Writer(GenericWriter):
if isinstance(in_files, basestring):
in_files = [in_files]
if in_files:
- self.in_file = InFile.load_from_files(in_files, self.defaults, self.valid_values, self.default_parameters)
+ self.in_file = InFile.load_from_files(in_files, self.defaults,
+ self.valid_values,
+ self.default_parameters)
else:
self.in_file = None
@@ -92,7 +96,7 @@ class Maker(object):
script_name = os.path.basename(argv[0])
args = argv[1:]
if len(args) < 1:
- print "USAGE: %s INPUT_FILES" % script_name
+ print("USAGE: %s INPUT_FILES" % script_name)
exit(1)
parser = optparse.OptionParser()
diff --git a/chromium/third_party/blink/renderer/build/scripts/json5_generator.py b/chromium/third_party/blink/renderer/build/scripts/json5_generator.py
index 8bd0c7ab8f9..2977f7be622 100644
--- a/chromium/third_party/blink/renderer/build/scripts/json5_generator.py
+++ b/chromium/third_party/blink/renderer/build/scripts/json5_generator.py
@@ -1,7 +1,6 @@
# 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.
-
"""Generic generator for configuration files in JSON5 format.
The configuration file is expected to contain either a data array or a data map,
@@ -97,28 +96,38 @@ def _merge_doc(doc, doc2):
def _is_valid(valid_values, value, valid_keys=None):
if type(value) == str and all([type(i) == str for i in valid_values]):
- return any([(value == valid) or (re.match("^" + valid + "$", value) is not None)
+ return any([(value == valid)
+ or (re.match("^" + valid + "$", value) is not None)
for valid in valid_values])
elif isinstance(value, dict):
assert valid_keys, "'valid_keys' must be declared when using a dict value"
return all([(key in valid_keys or key == "default")
and (val in valid_values or val == "")
- for key, val in value.iteritems()])
+ for key, val in value.items()])
else:
return value in valid_values
class Json5File(object):
- def __init__(self, file_paths, doc, default_metadata=None, default_parameters=None):
+ def __init__(self,
+ file_paths,
+ doc,
+ default_metadata=None,
+ default_parameters=None):
self.file_paths = file_paths
self.name_dictionaries = []
- self.metadata = copy.deepcopy(default_metadata if default_metadata else {})
- self.parameters = copy.deepcopy(default_parameters if default_parameters else {})
+ self.metadata = copy.deepcopy(
+ default_metadata if default_metadata else {})
+ self.parameters = copy.deepcopy(
+ default_parameters if default_parameters else {})
self._defaults = {}
self._process(doc)
@classmethod
- def load_from_files(cls, file_paths, default_metadata=None, default_parameters=None):
+ def load_from_files(cls,
+ file_paths,
+ default_metadata=None,
+ default_parameters=None):
merged_doc = dict()
for path in file_paths:
assert path.endswith(".json5")
@@ -128,7 +137,8 @@ class Json5File(object):
merged_doc = doc
else:
_merge_doc(merged_doc, doc)
- return Json5File(file_paths, merged_doc, default_metadata, default_parameters)
+ return Json5File(file_paths, merged_doc, default_metadata,
+ default_parameters)
def _process(self, doc):
# Process optional metadata map entries.
@@ -174,14 +184,14 @@ class Json5File(object):
if not self.parameters:
entry.update(item)
return entry
- assert "name" not in self.parameters, "The parameter 'name' is reserved, use a different name."
+ assert "name" not in self.parameters, \
+ "The parameter 'name' is reserved, use a different name."
entry["name"] = NameStyleConverter(item.pop("name"))
# Validate parameters if it's specified.
for key, value in item.items():
if key not in self.parameters:
- raise Exception(
- "Unknown parameter: '%s'\nKnown params: %s" %
- (key, self.parameters.keys()))
+ raise Exception("Unknown parameter: '%s'\nKnown params: %s" %
+ (key, self.parameters.keys()))
assert self.parameters[key] is not None, \
"Specification for parameter 'key' cannot be None. Use {} instead."
self._validate_parameter(self.parameters[key], value)
@@ -203,19 +213,50 @@ class Json5File(object):
for item in value:
if not _is_valid(valid_values, item):
raise Exception("Unknown value: '%s'\nValid values: %s, \
- Please change your value to a valid value" % (item, valid_values))
+ Please change your value to a valid value" %
+ (item, valid_values))
elif not _is_valid(valid_values, value, valid_keys):
message = "Unknown value: '%s'\nValid values: %s, \
- Please change your value to a valid value" % (value, valid_values)
+ Please change your value to a valid value" % (value,
+ valid_values)
if isinstance(value, dict):
- message = "Unknown key or value in: %s\nPlease choose your keys and values from the list below:\n \
- Valid keys: %s\nValid values: %s" % (value, valid_keys, valid_values)
+ message = ("Unknown key or value in: %s\n" \
+ "Please choose your keys and values from the list below:\n" \
+ "Valid keys: %s\nValid values: %s" %
+ (value, valid_keys, valid_values))
raise Exception(message)
def merge_from(self, doc):
self._process(doc)
+def reject_duplicates(entries):
+ assert isinstance(entries, list), 'The data should be a list.'
+ name_dict = {}
+ for entry in entries:
+ name = entry['name'].original
+ if name in name_dict:
+ raise Exception(
+ 'The data contains multiple entries for "%s".' % name)
+ name_dict[name] = entry
+
+
+def remove_duplicates(entries):
+ assert isinstance(entries, list), 'The data should be a list.'
+ name_dict = {}
+ filtered_list = []
+ for entry in entries:
+ name = entry['name'].original
+ if name in name_dict:
+ if entry != name_dict[name]:
+ raise Exception(
+ 'Duplicated entries for "%s" must be identical.' % name)
+ else:
+ name_dict[name] = entry
+ filtered_list.append(entry)
+ return filtered_list
+
+
class Writer(object):
# Subclasses should override.
class_name = None
@@ -232,12 +273,12 @@ class Writer(object):
self._cleanup = set()
self.gperf_path = None
if json5_files:
- self.json5_file = Json5File.load_from_files(json5_files,
- self.default_metadata,
- self.default_parameters)
+ self.json5_file = Json5File.load_from_files(
+ json5_files, self.default_metadata, self.default_parameters)
match = re.search(r'\bgen[\\/]', output_dir)
if match:
- self._relative_output_dir = output_dir[match.end():].replace(os.path.sep, '/') + '/'
+ self._relative_output_dir = output_dir[match.end():].replace(
+ os.path.sep, '/') + '/'
else:
self._relative_output_dir = ''
diff --git a/chromium/third_party/blink/renderer/build/scripts/json5_generator_unittest.py b/chromium/third_party/blink/renderer/build/scripts/json5_generator_unittest.py
index 04f01b90d24..7ae4c830fae 100644
--- a/chromium/third_party/blink/renderer/build/scripts/json5_generator_unittest.py
+++ b/chromium/third_party/blink/renderer/build/scripts/json5_generator_unittest.py
@@ -25,33 +25,49 @@ class CleanupWriter(Writer):
super(CleanupWriter, self).__init__([], output_dir)
self._cleanup = cleanup
+
class Json5FileTest(unittest.TestCase):
def path_of_test_file(self, file_name):
return os.path.join(
os.path.dirname(os.path.realpath(__file__)), 'tests', file_name)
def test_valid_dict_value_parse(self):
- actual = Json5File.load_from_files([self.path_of_test_file(
- 'json5_generator_valid_dict_value.json5')]).name_dictionaries
- expected = [
- {'name': 'item1', 'param1': {'keys': 'valid', 'random': 'values'}},
- {'name': 'item2', 'param1': {'random': 'values', 'default': 'valid'}}
- ]
+ actual = Json5File.load_from_files([
+ self.path_of_test_file('json5_generator_valid_dict_value.json5')
+ ]).name_dictionaries
+ expected = [{
+ 'name': 'item1',
+ 'param1': {
+ 'keys': 'valid',
+ 'random': 'values'
+ }
+ }, {
+ 'name': 'item2',
+ 'param1': {
+ 'random': 'values',
+ 'default': 'valid'
+ }
+ }]
self.assertEqual(len(actual), len(expected))
for exp, act in zip(expected, actual):
self.assertDictEqual(exp['param1'], act['param1'])
def test_no_valid_keys(self):
with self.assertRaises(AssertionError):
- Json5File.load_from_files([self.path_of_test_file('json5_generator_no_valid_keys.json5')])
+ Json5File.load_from_files([
+ self.path_of_test_file('json5_generator_no_valid_keys.json5')
+ ])
def test_value_not_in_valid_values(self):
with self.assertRaises(Exception):
- Json5File.load_from_files([self.path_of_test_file('json5_generator_invalid_value.json5')])
+ Json5File.load_from_files([
+ self.path_of_test_file('json5_generator_invalid_value.json5')
+ ])
def test_key_not_in_valid_keys(self):
with self.assertRaises(Exception):
- Json5File.load_from_files([self.path_of_test_file('json5_generator_invalid_key.json5')])
+ Json5File.load_from_files(
+ [self.path_of_test_file('json5_generator_invalid_key.json5')])
def test_cleanup_multiple_files(self):
with tmp_dir() as tmp:
@@ -95,5 +111,6 @@ class Json5FileTest(unittest.TestCase):
CleanupWriter(tmp, set(['file1.h', 'file2.h'])).cleanup_files(tmp)
self.assertFalse(os.path.exists(path1))
+
if __name__ == "__main__":
unittest.main()
diff --git a/chromium/third_party/blink/renderer/build/scripts/keyword_utils.py b/chromium/third_party/blink/renderer/build/scripts/keyword_utils.py
index 6212887b742..8a424d0aa76 100644
--- a/chromium/third_party/blink/renderer/build/scripts/keyword_utils.py
+++ b/chromium/third_party/blink/renderer/build/scripts/keyword_utils.py
@@ -5,8 +5,10 @@
import json5_generator
-def sort_keyword_properties_by_canonical_order(css_properties, css_value_keywords_file, json5_file_parameters):
- """Sort all keyword CSS properties by the order of the keyword in css_value_keywords.json5
+def sort_keyword_properties_by_canonical_order(
+ css_properties, css_value_keywords_file, json5_file_parameters):
+ """Sort all keyword CSS properties by the order of the keyword in
+ css_value_keywords.json5
Args:
css_properties: css_properties excluding extra fields.
@@ -18,12 +20,15 @@ def sort_keyword_properties_by_canonical_order(css_properties, css_value_keyword
"""
css_values_dictionary = json5_generator.Json5File.load_from_files(
[css_value_keywords_file],
- default_parameters=json5_file_parameters
- ).name_dictionaries
+ default_parameters=json5_file_parameters).name_dictionaries
css_values_dictionary = [x['name'].original for x in css_values_dictionary]
- name_to_position_dictionary = dict(zip(css_values_dictionary, range(len(css_values_dictionary))))
+ name_to_position_dictionary = dict(
+ zip(css_values_dictionary, range(len(css_values_dictionary))))
for css_property in css_properties:
- if css_property['field_template'] == 'keyword' and len(css_property['include_paths']) == 0:
- css_property['keywords'] = sorted(css_property['keywords'], key=lambda x: name_to_position_dictionary[x])
+ if css_property['field_template'] == 'keyword' and len(
+ css_property['include_paths']) == 0:
+ css_property['keywords'] = sorted(
+ css_property['keywords'],
+ key=lambda x: name_to_position_dictionary[x])
return css_properties
diff --git a/chromium/third_party/blink/renderer/build/scripts/license.py b/chromium/third_party/blink/renderer/build/scripts/license.py
index 692e6dd4bc9..23f5ba7bb96 100644
--- a/chromium/third_party/blink/renderer/build/scripts/license.py
+++ b/chromium/third_party/blink/renderer/build/scripts/license.py
@@ -29,6 +29,7 @@
# FIXME: We should either not use license blocks in generated files
# or we should read this from some central license file.
+
def license_for_generated_cpp():
return """// Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
diff --git a/chromium/third_party/blink/renderer/build/scripts/make_document_policy_features.py b/chromium/third_party/blink/renderer/build/scripts/make_document_policy_features.py
new file mode 100644
index 00000000000..0d67abdad41
--- /dev/null
+++ b/chromium/third_party/blink/renderer/build/scripts/make_document_policy_features.py
@@ -0,0 +1,38 @@
+# 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 json5_generator
+import template_expander
+from make_document_policy_features_util import parse_default_value
+
+
+class DocumentPolicyFeatureWriter(json5_generator.Writer):
+ file_basename = 'document_policy_features'
+
+ def __init__(self, json5_file_path, output_dir):
+ super(DocumentPolicyFeatureWriter, self).__init__(
+ json5_file_path, output_dir)
+
+ @template_expander.use_jinja(
+ 'templates/' + self.file_basename + '.cc.tmpl')
+ def generate_implementation():
+ return {
+ 'header_guard':
+ self.make_header_guard(self._relative_output_dir +
+ self.file_basename + '.h'),
+ 'input_files':
+ self._input_files,
+ 'features':
+ self.json5_file.name_dictionaries,
+ 'parse_default_value':
+ parse_default_value
+ }
+
+ self._outputs = {
+ self.file_basename + '.cc': generate_implementation,
+ }
+
+
+if __name__ == '__main__':
+ json5_generator.Maker(DocumentPolicyFeatureWriter).main()
diff --git a/chromium/third_party/blink/renderer/build/scripts/make_document_policy_features_unittest.py b/chromium/third_party/blink/renderer/build/scripts/make_document_policy_features_unittest.py
new file mode 100644
index 00000000000..4c361580e14
--- /dev/null
+++ b/chromium/third_party/blink/renderer/build/scripts/make_document_policy_features_unittest.py
@@ -0,0 +1,31 @@
+# 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 unittest
+
+from make_document_policy_features_util import parse_default_value
+
+
+class MakeDocumentPolicyFeaturesTest(unittest.TestCase):
+ def test_parse_default_value(self):
+ self.assertEqual(
+ parse_default_value("max", "DecDouble"),
+ "PolicyValue::CreateMaxPolicyValue(mojom::PolicyValueType::kDecDouble)"
+ )
+ self.assertEqual(
+ parse_default_value("min", "DecDouble"),
+ "PolicyValue::CreateMinPolicyValue(mojom::PolicyValueType::kDecDouble)"
+ )
+ self.assertEqual(
+ parse_default_value("false", "Bool"), "PolicyValue(false)")
+ self.assertEqual(
+ parse_default_value("0.5", "DecDouble"),
+ "PolicyValue(0.5, mojom::PolicyValueType::kDecDouble)")
+
+ with self.assertRaises(ValueError):
+ parse_default_value("max", "NotImplemented")
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/chromium/third_party/blink/renderer/build/scripts/make_document_policy_features_util.py b/chromium/third_party/blink/renderer/build/scripts/make_document_policy_features_util.py
new file mode 100644
index 00000000000..9a6264652b4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/build/scripts/make_document_policy_features_util.py
@@ -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.
+
+
+def parse_default_value(default_value,
+ value_type,
+ recognized_types=('Bool', 'DecDouble'),
+ single_ctor_param_types=('Bool')):
+ """ Parses default_value string to actual usable C++ expression.
+ @param default_value_str: default_value field specified in document_policy_features.json5
+ @param value_type: value_type field specified in document_policy_features.json5
+ @param recognized_types: types that are valid for value_type
+ @param single_ctor_param_types: types with single param PolicyValue constructor
+ - Bool corresponds to PolicyValue(bool) which only has one constructor param
+ - DecDouble and IncDouble both take an extra constructor param for value_type
+ in constructor PolicyValue(double, mojom::PolicyValueType)
+ @returns: a C++ expression that has type mojom::PolicyValue
+ """
+ if (value_type not in recognized_types):
+ raise ValueError("{} is not recognized as valid value_type({})".format(
+ value_type, recognized_types))
+
+ policy_value_type = "mojom::PolicyValueType::k{}".format(value_type)
+
+ if default_value == 'max':
+ return "PolicyValue::CreateMaxPolicyValue({})".format(
+ policy_value_type)
+ if default_value == 'min':
+ return "PolicyValue::CreateMinPolicyValue({})".format(
+ policy_value_type)
+
+ # types that have only one corresponding PolicyValueType
+ if value_type in single_ctor_param_types:
+ return "PolicyValue({})".format(default_value)
+ else:
+ return "PolicyValue({}, {})".format(default_value, policy_value_type)
diff --git a/chromium/third_party/blink/renderer/build/scripts/make_element_factory.py b/chromium/third_party/blink/renderer/build/scripts/make_element_factory.py
index 6158af32dab..bb3e5f48066 100755
--- a/chromium/third_party/blink/renderer/build/scripts/make_element_factory.py
+++ b/chromium/third_party/blink/renderer/build/scripts/make_element_factory.py
@@ -48,23 +48,29 @@ class MakeElementFactoryWriter(MakeQualifiedNamesWriter):
'noTypeHelpers': {},
'runtimeEnabled': {},
}
- default_metadata = dict(MakeQualifiedNamesWriter.default_metadata, **{
- 'fallbackInterfaceName': '',
- 'fallbackJSInterfaceName': '',
- })
+ default_metadata = dict(
+ MakeQualifiedNamesWriter.default_metadata, **{
+ 'fallbackInterfaceName': '',
+ 'fallbackJSInterfaceName': '',
+ })
filters = MakeQualifiedNamesWriter.filters
def __init__(self, json5_file_paths, output_dir):
- super(MakeElementFactoryWriter, self).__init__(json5_file_paths, output_dir)
+ super(MakeElementFactoryWriter, self).__init__(json5_file_paths,
+ output_dir)
basename = self.namespace.lower() + '_element_factory'
self._outputs.update({
- (basename + '.h'): self.generate_factory_header,
- (basename + '.cc'): self.generate_factory_implementation,
+ (basename + '.h'):
+ self.generate_factory_header,
+ (basename + '.cc'):
+ self.generate_factory_implementation,
})
- fallback_interface = self.tags_json5_file.metadata['fallbackInterfaceName'].strip('"')
- fallback_js_interface = self.tags_json5_file.metadata['fallbackJSInterfaceName'].strip('"') or fallback_interface
+ fallback_interface = self.tags_json5_file.metadata[
+ 'fallbackInterfaceName'].strip('"')
+ fallback_js_interface = self.tags_json5_file.metadata[
+ 'fallbackJSInterfaceName'].strip('"') or fallback_interface
interface_counts = defaultdict(int)
tags = self._template_context['tags']
@@ -72,27 +78,33 @@ class MakeElementFactoryWriter(MakeQualifiedNamesWriter):
tag['has_js_interface'] = self._has_js_interface(tag)
tag['js_interface'] = self._js_interface(tag)
tag['interface'] = self._interface(tag)
- tag['interface_header'] = '%s/%s.h' % (
- self._interface_header_dir(tag),
- self.get_file_basename(tag['interface']))
+ tag['interface_header'] = '%s/%s.h' % (self._interface_header_dir(
+ tag), self.get_file_basename(tag['interface']))
interface_counts[tag['interface']] += 1
for tag in tags:
- tag['multipleTagNames'] = (interface_counts[tag['interface']] > 1 or tag['interface'] == fallback_interface)
+ tag['multipleTagNames'] = (interface_counts[tag['interface']] > 1
+ or
+ tag['interface'] == fallback_interface)
self._template_context.update({
- 'fallback_interface': fallback_interface,
- 'fallback_interface_header': self.get_file_basename(
- fallback_interface) + '.h',
- 'fallback_js_interface': fallback_js_interface,
- 'input_files': self._input_files,
+ 'fallback_interface':
+ fallback_interface,
+ 'fallback_interface_header':
+ self.get_file_basename(fallback_interface) + '.h',
+ 'fallback_js_interface':
+ fallback_js_interface,
+ 'input_files':
+ self._input_files,
})
- @template_expander.use_jinja('templates/element_factory.h.tmpl', filters=filters)
+ @template_expander.use_jinja(
+ 'templates/element_factory.h.tmpl', filters=filters)
def generate_factory_header(self):
return self._template_context
- @template_expander.use_jinja('templates/element_factory.cc.tmpl', filters=filters)
+ @template_expander.use_jinja(
+ 'templates/element_factory.cc.tmpl', filters=filters)
def generate_factory_implementation(self):
return self._template_context
@@ -111,7 +123,8 @@ class MakeElementFactoryWriter(MakeQualifiedNamesWriter):
return self._interface(tag)
def _has_js_interface(self, tag):
- return not tag['noConstructor'] and self._js_interface(tag) != ('%sElement' % self.namespace)
+ return not tag['noConstructor'] and self._js_interface(tag) != (
+ '%sElement' % self.namespace)
def _interface_header_dir(self, tag):
if tag['interfaceHeaderDir']:
diff --git a/chromium/third_party/blink/renderer/build/scripts/make_element_lookup_trie.py b/chromium/third_party/blink/renderer/build/scripts/make_element_lookup_trie.py
index f370fd553de..8ae7e676ea7 100755
--- a/chromium/third_party/blink/renderer/build/scripts/make_element_lookup_trie.py
+++ b/chromium/third_party/blink/renderer/build/scripts/make_element_lookup_trie.py
@@ -43,6 +43,7 @@ class ElementLookupTrieWriter(json5_generator.Writer):
'interfaceHeaderDir': {},
'interfaceName': {},
'noConstructor': {},
+ 'noTypeHelpers': {},
'runtimeEnabled': {},
}
default_metadata = {
@@ -55,11 +56,13 @@ class ElementLookupTrieWriter(json5_generator.Writer):
'namespaceURI': '',
}
filters = {
- 'symbol': lambda symbol: 'k' + NameStyleConverter(symbol).to_upper_camel_case()
+ 'symbol':
+ lambda symbol: 'k' + NameStyleConverter(symbol).to_upper_camel_case()
}
def __init__(self, json5_file_paths, output_dir):
- super(ElementLookupTrieWriter, self).__init__(json5_file_paths, output_dir)
+ super(ElementLookupTrieWriter, self).__init__(json5_file_paths,
+ output_dir)
self._tags = {}
for entry in self.json5_file.name_dictionaries:
self._tags[entry['name'].original] = entry['name'].original
@@ -77,7 +80,8 @@ class ElementLookupTrieWriter(json5_generator.Writer):
'namespace': self._namespace,
}
- @template_expander.use_jinja('templates/element_lookup_trie.cc.tmpl', filters=filters)
+ @template_expander.use_jinja(
+ 'templates/element_lookup_trie.cc.tmpl', filters=filters)
def generate_implementation(self):
return {
'input_files': self._input_files,
diff --git a/chromium/third_party/blink/renderer/build/scripts/make_element_type_helpers.py b/chromium/third_party/blink/renderer/build/scripts/make_element_type_helpers.py
index 057a1be1fe8..29a43f31777 100755
--- a/chromium/third_party/blink/renderer/build/scripts/make_element_type_helpers.py
+++ b/chromium/third_party/blink/renderer/build/scripts/make_element_type_helpers.py
@@ -12,6 +12,7 @@ import template_expander
from blinkbuild.name_style_converter import NameStyleConverter
+
def _symbol(tag):
return 'k' + tag['name'].to_upper_camel_case()
@@ -43,10 +44,12 @@ class MakeElementTypeHelpersWriter(json5_generator.Writer):
}
def __init__(self, json5_file_path, output_dir):
- super(MakeElementTypeHelpersWriter, self).__init__(json5_file_path, output_dir)
+ super(MakeElementTypeHelpersWriter, self).__init__(
+ json5_file_path, output_dir)
self.namespace = self.json5_file.metadata['namespace'].strip('"')
- self.fallback_interface = self.json5_file.metadata['fallbackInterfaceName'].strip('"')
+ self.fallback_interface = self.json5_file.metadata[
+ 'fallbackInterfaceName'].strip('"')
assert self.namespace, 'A namespace is required.'
@@ -57,7 +60,8 @@ class MakeElementTypeHelpersWriter(json5_generator.Writer):
}
base_element_header = 'third_party/blink/renderer/core/{}/{}_element.h'.format(
- self.namespace.lower(), NameStyleConverter(self.namespace).to_snake_case())
+ self.namespace.lower(),
+ NameStyleConverter(self.namespace).to_snake_case())
self._template_context = {
'base_element_header': base_element_header,
'cpp_namespace': self.namespace.lower() + '_names',
@@ -79,13 +83,17 @@ class MakeElementTypeHelpersWriter(json5_generator.Writer):
elements.add(tag['js_interface'])
for tag in tags:
- tag['multipleTagNames'] = (interface_counts[tag['interface']] > 1 or tag['interface'] == self.fallback_interface)
+ tag['multipleTagNames'] = (
+ interface_counts[tag['interface']] > 1
+ or tag['interface'] == self.fallback_interface)
- @template_expander.use_jinja("templates/element_type_helpers.h.tmpl", filters=filters)
+ @template_expander.use_jinja(
+ "templates/element_type_helpers.h.tmpl", filters=filters)
def generate_helper_header(self):
return self._template_context
- @template_expander.use_jinja("templates/element_type_helpers.cc.tmpl", filters=filters)
+ @template_expander.use_jinja(
+ "templates/element_type_helpers.cc.tmpl", filters=filters)
def generate_helper_implementation(self):
return self._template_context
@@ -98,5 +106,6 @@ class MakeElementTypeHelpersWriter(json5_generator.Writer):
name = 'Html'
return '%s%sElement' % (self.namespace, name)
+
if __name__ == "__main__":
json5_generator.Maker(MakeElementTypeHelpersWriter).main()
diff --git a/chromium/third_party/blink/renderer/build/scripts/make_event_factory.py b/chromium/third_party/blink/renderer/build/scripts/make_event_factory.py
index b102fb44c33..a7ceb4518d4 100755
--- a/chromium/third_party/blink/renderer/build/scripts/make_event_factory.py
+++ b/chromium/third_party/blink/renderer/build/scripts/make_event_factory.py
@@ -27,6 +27,8 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+from __future__ import print_function
+
import os.path
import sys
@@ -41,15 +43,10 @@ import template_expander
#
# https://dom.spec.whatwg.org/#dom-document-createevent
def create_event_ignore_case_list(name):
- return (name == 'HTMLEvents'
- or name == 'Event'
- or name == 'Events'
- or name.startswith('UIEvent')
- or name.startswith('CustomEvent')
- or name == 'KeyboardEvent'
- or name == 'MessageEvent'
- or name.startswith('MouseEvent')
- or name == 'TouchEvent')
+ return (name == 'HTMLEvents' or name == 'Event' or name == 'Events'
+ or name.startswith('UIEvent') or name.startswith('CustomEvent')
+ or name == 'KeyboardEvent' or name == 'MessageEvent'
+ or name.startswith('MouseEvent') or name == 'TouchEvent')
# All events on the following list are matched case-insensitively in createEvent
@@ -59,28 +56,17 @@ def create_event_ignore_case_list(name):
# to the spec and moved to the above list (causing them to be matched
# case-insensitively) or be deprecated/removed.
def create_event_ignore_case_and_measure_list(name):
- return (name == 'AnimationEvent'
- or name == 'BeforeUnloadEvent'
- or name == 'CloseEvent'
- or name == 'CompositionEvent'
- or name == 'DeviceMotionEvent'
- or name == 'DeviceOrientationEvent'
- or name == 'DragEvent'
- or name == 'ErrorEvent'
- or name == 'FocusEvent'
- or name == 'HashChangeEvent'
- or name == 'IDBVersionChangeEvent'
- or name == 'KeyboardEvents'
- or name == 'MutationEvent'
- or name == 'MutationEvents'
- or name == 'PageTransitionEvent'
- or name == 'PopStateEvent'
- or name == 'StorageEvent'
- or name == 'SVGEvents'
- or name == 'TextEvent'
- or name == 'TrackEvent'
- or name == 'TransitionEvent'
- or name == 'WebGLContextEvent'
+ return (name == 'AnimationEvent' or name == 'BeforeUnloadEvent'
+ or name == 'CloseEvent' or name == 'CompositionEvent'
+ or name == 'DeviceMotionEvent' or name == 'DeviceOrientationEvent'
+ or name == 'DragEvent' or name == 'ErrorEvent'
+ or name == 'FocusEvent' or name == 'HashChangeEvent'
+ or name == 'IDBVersionChangeEvent' or name == 'KeyboardEvents'
+ or name == 'MutationEvent' or name == 'MutationEvents'
+ or name == 'PageTransitionEvent' or name == 'PopStateEvent'
+ or name == 'StorageEvent' or name == 'SVGEvents'
+ or name == 'TextEvent' or name == 'TrackEvent'
+ or name == 'TransitionEvent' or name == 'WebGLContextEvent'
or name == 'WheelEvent')
@@ -103,48 +89,56 @@ class EventFactoryWriter(json5_generator.Writer):
'cpp_name': name_utilities.cpp_name,
'name': lambda entry: entry['name'].original,
'create_event_ignore_case_list': create_event_ignore_case_list,
- 'create_event_ignore_case_and_measure_list': create_event_ignore_case_and_measure_list,
'measure_name': measure_name,
}
def __init__(self, json5_file_path, output_dir):
super(EventFactoryWriter, self).__init__(json5_file_path, output_dir)
self.namespace = self.json5_file.metadata['namespace'].strip('"')
- assert self.namespace == 'event_interface_names', 'namespace field should be "event_interface_names".'
+ assert self.namespace == 'event_interface_names', \
+ 'namespace field should be "event_interface_names".'
self.suffix = self.json5_file.metadata['suffix'].strip('"')
snake_suffix = (self.suffix.lower() + '_') if self.suffix else ''
self._outputs = {
- ('event_%sfactory.cc' % snake_suffix): self.generate_implementation,
+ ('event_%sfactory.cc' % snake_suffix):
+ self.generate_implementation,
}
def _fatal(self, message):
- print 'FATAL ERROR: ' + message
+ print('FATAL ERROR: ' + message)
exit(1)
def _headers_header_include_path(self, entry):
path = entry['interfaceHeaderDir']
- if len(path):
- path += '/'
- return path + self.get_file_basename(name_utilities.cpp_name(entry)) + '.h'
+ if not path:
+ return None
+ return path + '/' + self.get_file_basename(
+ name_utilities.cpp_name(entry)) + '.h'
def _headers_header_includes(self, entries):
- includes = dict()
- for entry in entries:
- cpp_name = name_utilities.cpp_name(entry)
- # Avoid duplicate includes.
- if cpp_name in includes:
- continue
- includes[cpp_name] = self._headers_header_include_path(entry)
- return sorted(includes.values())
-
- @template_expander.use_jinja('templates/event_factory.cc.tmpl', filters=filters)
+ includes = {
+ 'third_party/blink/renderer/core/execution_context/execution_context.h',
+ 'third_party/blink/renderer/core/frame/deprecation.h',
+ 'third_party/blink/renderer/platform/instrumentation/use_counter.h',
+ 'third_party/blink/renderer/platform/runtime_enabled_features.h',
+ }
+ includes.update(map(self._headers_header_include_path, entries))
+ return sorted([x for x in includes if x])
+
+ @template_expander.use_jinja(
+ 'templates/event_factory.cc.tmpl', filters=filters)
def generate_implementation(self):
+ target_events = [
+ event for event in self.json5_file.name_dictionaries if
+ (create_event_ignore_case_list(event['name'].original) or
+ create_event_ignore_case_and_measure_list(event['name'].original))
+ ]
return {
- 'include_header_paths': self._headers_header_includes(
- self.json5_file.name_dictionaries),
+ 'include_header_paths':
+ self._headers_header_includes(target_events),
'input_files': self._input_files,
'suffix': self.suffix,
- 'events': self.json5_file.name_dictionaries,
+ 'events': target_events,
}
diff --git a/chromium/third_party/blink/renderer/build/scripts/make_feature_policy_helper.py b/chromium/third_party/blink/renderer/build/scripts/make_feature_policy_helper.py
index 578904050a1..caa85e5d434 100644
--- a/chromium/third_party/blink/renderer/build/scripts/make_feature_policy_helper.py
+++ b/chromium/third_party/blink/renderer/build/scripts/make_feature_policy_helper.py
@@ -2,117 +2,78 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import make_runtime_features_utilities as util
import json5_generator
import template_expander
+from collections import defaultdict
+from make_runtime_features_utilities import origin_trials
class FeaturePolicyFeatureWriter(json5_generator.Writer):
file_basename = 'feature_policy_helper'
def __init__(self, json5_file_path, output_dir):
- super(FeaturePolicyFeatureWriter, self).__init__(json5_file_path, output_dir)
- self._outputs = {
- (self.file_basename + '.cc'): self.generate_implementation,
- }
-
- self._features = self.json5_file.name_dictionaries
- # Set runtime and feature policy features
- self._runtime_features = []
- self._feature_policy_features = []
- for feature in self._features:
+ super(FeaturePolicyFeatureWriter, self).__init__(
+ json5_file_path, output_dir)
+ runtime_features = []
+ feature_policy_features = []
+ # Note: there can be feature with same 'name' attribute in
+ # document_policy_features and in feature_policy_features.
+ # They are supposed to have the same 'depends_on' attribute.
+ # However, their feature_policy_name and document_policy_name
+ # might be different.
+ document_policy_features = []
+
+ for feature in self.json5_file.name_dictionaries:
if feature['feature_policy_name']:
- self._feature_policy_features.append(feature)
+ feature_policy_features.append(feature)
+ elif feature['document_policy_name']:
+ document_policy_features.append(feature)
else:
- self._runtime_features.append(feature)
-
- self._convert_runtime_name_to_feature()
- self._set_in_origin_trial()
- self._runtime_to_feature_policy_map = self._make_runtime_to_feature_policy_map()
- self._origin_trial_dependency_map = self._make_origin_trial_dependency_map()
- self._header_guard = self.make_header_guard(self._relative_output_dir + self.file_basename + '.h')
-
- # Replaces runtime names in 'depends_on' list to feature objects.
- def _convert_runtime_name_to_feature(self):
- name_to_runtime_feature_map = {}
- for feature in self._runtime_features:
- name_to_runtime_feature_map[str(feature['name'])] = feature
-
- def replace_name_with_object(name):
- assert name in name_to_runtime_feature_map, name + ' is not a runtime feature.'
- return name_to_runtime_feature_map[name]
-
- for feature in self._feature_policy_features:
- feature['depends_on'] = map(replace_name_with_object, feature['depends_on'])
-
- # Returns a map of runtime features (not in origin trial) to the feature
- # policy features that depend on them. The maps is used to generate
- # DefaultFeatureNameMap().
- def _make_runtime_to_feature_policy_map(self):
- runtime_to_feature_policy_map = {}
- for feature in self._feature_policy_features:
- # Filter out all the ones not in OT.
- for dependant in [runtime_feature for runtime_feature
- in feature['depends_on']
- if not runtime_feature['in_origin_trial']]:
- dependant_name = str(dependant['name'])
- if dependant_name not in runtime_to_feature_policy_map:
- runtime_to_feature_policy_map[dependant_name] = [feature]
- else:
- runtime_to_feature_policy_map[dependant_name].append(feature)
- return runtime_to_feature_policy_map
-
- # Returns a map of feature policy features that depend on OT features to
- # their dependencies. The map is used to generate DisabledByOriginTrial().
- def _make_origin_trial_dependency_map(self):
- origin_trial_dependency_map = {}
- for feature in [fp_feature for fp_feature
- in self._feature_policy_features
- if fp_feature['in_origin_trial']]:
- feature_name = str(feature['name'])
- # Only go through the dependencies that are in an origin trial.
- for dependant in [runtime_feature for runtime_feature
- in feature['depends_on']
- if runtime_feature['in_origin_trial']]:
- if feature_name in origin_trial_dependency_map:
- origin_trial_dependency_map[feature_name].append(dependant)
+ runtime_features.append(feature)
+
+ origin_trials_set = origin_trials(runtime_features)
+ fp_origin_trial_dependency_map = defaultdict(list)
+ dp_origin_trial_dependency_map = defaultdict(list)
+ runtime_to_feature_policy_map = defaultdict(list)
+ runtime_to_document_policy_map = defaultdict(list)
+ for feature in feature_policy_features + document_policy_features:
+ for dependency in feature['depends_on']:
+ if str(dependency) in origin_trials_set:
+ if feature['feature_policy_name']:
+ fp_origin_trial_dependency_map[feature['name']].append(
+ dependency)
+ else:
+ dp_origin_trial_dependency_map[feature['name']].append(
+ dependency)
else:
- origin_trial_dependency_map[feature_name] = [dependant]
- return origin_trial_dependency_map
+ if feature['feature_policy_name']:
+ runtime_to_feature_policy_map[dependency].append(
+ feature['name'])
+ else:
+ runtime_to_document_policy_map[dependency].append(
+ feature['name'])
- # Sets the 'in_origin_trial' flag for features. A feature is in an origin
- # trial if either itself or one of its dependencies are in an origin trial.
- def _set_in_origin_trial(self):
- # |_dependency_graph| is used to keep the 'depends_on' relationship
- # for the runtime features defined in "runtime_enabled_features.json5".
- self._dependency_graph = util.init_graph(self._runtime_features)
- for feature in self._runtime_features:
- for dependant_name in feature['depends_on']:
- assert dependant_name in self._dependency_graph, dependant_name + ' is not a feature.'
- self._dependency_graph[dependant_name].append(str(feature['name']))
- util.check_if_dependency_graph_contains_cycle(self._dependency_graph)
- util.set_origin_trials_features(self._runtime_features, self._dependency_graph)
- # Set the flag for feature policy features as well.
- for feature in self._feature_policy_features:
- feature['in_origin_trial'] = False
- if any([runtime_feature['in_origin_trial'] for
- runtime_feature in feature['depends_on']]):
- feature['in_origin_trial'] = True
-
- def _template_inputs(self):
- return {
- 'feature_policy_features': self._feature_policy_features,
- 'header_guard': self._header_guard,
- 'input_files': self._input_files,
- 'runtime_features': self._runtime_features,
- 'runtime_to_feature_policy_map': self._runtime_to_feature_policy_map,
- 'origin_trial_dependency_map': self._origin_trial_dependency_map,
+ self._outputs = {
+ self.file_basename + '.cc':
+ template_expander.use_jinja('templates/' +
+ self.file_basename + '.cc.tmpl')(lambda: {
+ 'header_guard': self.make_header_guard(
+ self._relative_output_dir +
+ self.file_basename + '.h'),
+ 'input_files': self._input_files,
+ 'feature_policy_features': feature_policy_features,
+ 'document_policy_features': document_policy_features,
+ 'fp_origin_trial_dependency_map':
+ fp_origin_trial_dependency_map,
+ 'dp_origin_trial_dependency_map':
+ dp_origin_trial_dependency_map,
+ 'runtime_to_feature_policy_map':
+ runtime_to_feature_policy_map,
+ 'runtime_to_document_policy_map':
+ runtime_to_document_policy_map
+ }),
}
- @template_expander.use_jinja('templates/' + file_basename + '.cc.tmpl')
- def generate_implementation(self):
- return self._template_inputs()
-
if __name__ == '__main__':
json5_generator.Maker(FeaturePolicyFeatureWriter).main()
diff --git a/chromium/third_party/blink/renderer/build/scripts/make_html_entity_table.py b/chromium/third_party/blink/renderer/build/scripts/make_html_entity_table.py
index 6d52be70e29..f02bb2afffc 100755
--- a/chromium/third_party/blink/renderer/build/scripts/make_html_entity_table.py
+++ b/chromium/third_party/blink/renderer/build/scripts/make_html_entity_table.py
@@ -26,7 +26,6 @@
# 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.
-
"""This python script creates the raw data that is our entity
database. The representation is one string database containing all
strings we could need, and then a mapping from offset+length -> entity
@@ -55,16 +54,20 @@ def offset_table_entry(offset):
def check_ascii(entity_string):
for ch in entity_string:
code = ord(ch)
- assert 0 <= code <= 127, (ch + " is not ASCII. Need to change type " +
- "of storage from LChar to UChar to support " +
- "this entity.")
+ assert 0 <= code <= 127, (
+ ch + " is not ASCII. Need to change type " +
+ "of storage from LChar to UChar to support " + "this entity.")
def main():
program_name = os.path.basename(__file__)
if len(sys.argv) < 4 or sys.argv[1] != "-o":
- # Python 3, change to: print("Usage: %s -o OUTPUT_FILE INPUT_FILE" % program_name, file=sys.stderr)
- sys.stderr.write("Usage: %s -o OUTPUT_FILE INPUT_FILE\n" % program_name)
+ # Python 3, change to:
+ # print(
+ # "Usage: %s -o OUTPUT_FILE INPUT_FILE" % program_name,
+ # file=sys.stderr)
+ sys.stderr.write(
+ "Usage: %s -o OUTPUT_FILE INPUT_FILE\n" % program_name)
exit(1)
output_path = sys.argv[2]
@@ -153,7 +156,8 @@ namespace {
all_data += data_to_add
output_file.write("'")
entity_offset += len(data_to_add)
- assert len(entry) == 2, "We will use slot [2] in the list for the offset."
+ assert len(
+ entry) == 2, "We will use slot [2] in the list for the offset."
assert this_offset < 32768 # Stored in a 16 bit short.
entry.append(this_offset)
@@ -166,7 +170,8 @@ namespace {
index[starting_letter] = offset
output_file.write("""
-static const HTMLEntityTableEntry staticEntityTable[%s] = {\n""" % entity_count)
+static const HTMLEntityTableEntry staticEntityTable[%s] = {\n""" %
+ entity_count)
for entry in entries:
values = entry[VALUE].split(' ')
@@ -233,5 +238,6 @@ const HTMLEntityTableEntry* HTMLEntityTable::LastEntry()
}
""" % entity_count)
+
if __name__ == "__main__":
main()
diff --git a/chromium/third_party/blink/renderer/build/scripts/make_instrumenting_probes.py b/chromium/third_party/blink/renderer/build/scripts/make_instrumenting_probes.py
index b5df60637eb..1b43f5786a8 100644
--- a/chromium/third_party/blink/renderer/build/scripts/make_instrumenting_probes.py
+++ b/chromium/third_party/blink/renderer/build/scripts/make_instrumenting_probes.py
@@ -18,7 +18,8 @@ import sys
# is regenerated, which causes a race condition and breaks concurrent build,
# since some compile processes will try to read the partially written cache.
_MODULE_PATH, _ = os.path.split(os.path.realpath(__file__))
-_THIRD_PARTY_DIR = os.path.normpath(os.path.join(_MODULE_PATH, os.pardir, os.pardir, os.pardir, os.pardir))
+_THIRD_PARTY_DIR = os.path.normpath(
+ os.path.join(_MODULE_PATH, os.pardir, os.pardir, os.pardir, os.pardir))
# jinja2 is in chromium's third_party directory.
# Insert at 1 so at front to override system libraries, and
# after path[0] == invoking script dir
@@ -57,16 +58,22 @@ def agent_config(config, agent_name, field):
def agent_name_to_class(config, agent_name):
return agent_config(config, agent_name, "class") or agent_name
+
def agent_name_to_include(config, agent_name):
- include_path = agent_config(config, agent_name, "include_path") or config["settings"]["include_path"]
+ include_path = agent_config(
+ config, agent_name,
+ "include_path") or config["settings"]["include_path"]
agent_class = agent_name_to_class(config, agent_name)
- include_file = os.path.join(include_path, NameStyleConverter(agent_class).to_snake_case() + ".h")
+ include_file = os.path.join(
+ include_path,
+ NameStyleConverter(agent_class).to_snake_case() + ".h")
return include_file.replace("dev_tools", "devtools")
def initialize_jinja_env(config, cache_dir):
jinja_env = jinja2.Environment(
- loader=jinja2.FileSystemLoader(os.path.join(_MODULE_PATH, "templates")),
+ loader=jinja2.FileSystemLoader(
+ os.path.join(_MODULE_PATH, "templates")),
# Bytecode cache is not concurrency-safe unless pre-cached:
# if pre-cached this is read-only, but writing creates a race condition.
bytecode_cache=jinja2.FileSystemBytecodeCache(cache_dir),
@@ -74,10 +81,15 @@ def initialize_jinja_env(config, cache_dir):
lstrip_blocks=True, # so can indent control flow tags
trim_blocks=True)
jinja_env.filters.update({
- "to_snake_case": to_snake_case,
- "to_singular": to_singular,
- "agent_name_to_class": partial(agent_name_to_class, config),
- "agent_name_to_include": partial(agent_name_to_include, config)})
+ "to_snake_case":
+ to_snake_case,
+ "to_singular":
+ to_singular,
+ "agent_name_to_class":
+ partial(agent_name_to_class, config),
+ "agent_name_to_include":
+ partial(agent_name_to_include, config)
+ })
jinja_env.add_extension('jinja2.ext.loopcontrols')
return jinja_env
@@ -91,12 +103,15 @@ def match_and_consume(pattern, source):
def load_model_from_idl(source):
source = re.sub(r"//.*", "", source) # Remove line comments
- source = re.sub(r"/\*(.|\n)*?\*/", "", source, re.MULTILINE) # Remove block comments
- source = re.sub(r"\]\s*?\n\s*", "] ", source) # Merge the method annotation with the next line
+ # Remove block comments
+ source = re.sub(r"/\*(.|\n)*?\*/", "", source, re.MULTILINE)
+ # Merge the method annotation with the next line
+ source = re.sub(r"\]\s*?\n\s*", "] ", source)
source = source.strip()
model = []
while len(source):
- match, source = match_and_consume(r"interface\s(\w*)\s?\{([^\{]*)\}", source)
+ match, source = match_and_consume(r"interface\s(\w*)\s?\{([^\{]*)\}",
+ source)
if not match:
sys.stderr.write("Cannot parse %s\n" % source[:100])
sys.exit(1)
@@ -133,8 +148,11 @@ class Method(object):
if not self.is_scoped and match.group(1) != "void":
raise Exception("Instant probe must return void: %s" % self.name)
- # Splitting parameters by a comma, assuming that attribute lists contain no more than one attribute.
- self.params = map(Parameter, map(str.strip, match.group(3).split(",")))
+ # Splitting parameters by a comma, assuming that attribute
+ # lists contain no more than one attribute.
+ self.params = list(
+ map(Parameter, map(str.strip,
+ match.group(3).split(","))))
class Parameter(object):
@@ -144,11 +162,12 @@ class Parameter(object):
if match:
self.options.append(match.group(1))
- parts = map(str.strip, source.split("="))
+ parts = list(map(str.strip, source.split("=")))
self.default_value = parts[1] if len(parts) != 1 else None
param_decl = parts[0]
- min_type_tokens = 2 if re.match("(const|unsigned long) ", param_decl) else 1
+ min_type_tokens = 2 if re.match("(const|unsigned long) ",
+ param_decl) else 1
if len(param_decl.split(" ")) > min_type_tokens:
parts = param_decl.split(" ")
@@ -165,14 +184,13 @@ class Parameter(object):
def build_param_name(param_type):
- return "param_" + NameStyleConverter(re.match(r"(const |scoped_refptr<)?(\w*)", param_type).group(2)).to_snake_case()
+ return "param_" + NameStyleConverter(
+ re.match(r"(const |scoped_refptr<)?(\w*)",
+ param_type).group(2)).to_snake_case()
def load_config(file_name):
- default_config = {
- "settings": {},
- "observers": {}
- }
+ default_config = {"settings": {}, "observers": {}}
if not file_name:
return default_config
with open(file_name) as config_file:
@@ -184,7 +202,8 @@ def build_observers(config, files):
for f in files:
probes = set([probe.name for probe in f.declarations])
if all_pidl_probes & probes:
- raise Exception("Multiple probe declarations: %s" % all_pidl_probes & probes)
+ raise Exception(
+ "Multiple probe declarations: %s" % all_pidl_probes & probes)
all_pidl_probes |= probes
all_observers = set()
@@ -196,7 +215,8 @@ def build_observers(config, files):
for probe in observer["probes"]:
unused_probes.discard(probe)
if probe not in all_pidl_probes:
- raise Exception('Probe %s is not declared in PIDL file' % probe)
+ raise Exception(
+ 'Probe %s is not declared in PIDL file' % probe)
observers_by_probe.setdefault(probe, set()).add(observer_name)
if unused_probes:
raise Exception("Unused probes: %s" % unused_probes)
@@ -215,7 +235,8 @@ def main():
try:
arg_options, arg_values = cmdline_parser.parse_args()
if len(arg_values) != 1:
- raise ValueError("Exactly one plain argument expected (found %s)" % len(arg_values))
+ raise ValueError("Exactly one plain argument expected (found %s)" %
+ len(arg_values))
input_path = arg_values[0]
output_dirpath = arg_options.output_dir
if not output_dirpath:
@@ -224,7 +245,8 @@ def main():
except ValueError:
# Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html
exc = sys.exc_info()[1]
- sys.stderr.write("Failed to parse command-line arguments: %s\n\n" % exc)
+ sys.stderr.write(
+ "Failed to parse command-line arguments: %s\n\n" % exc)
sys.stderr.write("Usage: <script> [options] <probes.pidl>\n")
sys.stderr.write("Options:\n")
sys.stderr.write("\t--config <config_file.json5>\n")
@@ -233,7 +255,8 @@ def main():
match = re.search(r"\bgen[\\/]", output_dirpath)
if match:
- output_path_in_gen_dir = output_dirpath[match.end():].replace(os.path.sep, '/') + '/'
+ output_path_in_gen_dir = output_dirpath[match.end():].replace(
+ os.path.sep, '/') + '/'
else:
output_path_in_gen_dir = ''
@@ -249,7 +272,8 @@ def main():
"files": files,
"agents": build_observers(config, files),
"config": config,
- "method_name": lambda name: NameStyleConverter(name).to_function_name(),
+ "method_name":
+ lambda name: NameStyleConverter(name).to_function_name(),
"name": NameStyleConverter(base_name).to_upper_camel_case(),
"header": base_name,
"input_files": [os.path.basename(input_path)],
@@ -266,18 +290,21 @@ def main():
sink_h_template = jinja_env.get_template(template_context["template_file"])
sink_h_file_name = to_singular(base_name) + "_sink.h"
sink_h_file = open(output_dirpath + "/" + sink_h_file_name, "w")
- template_context["header_guard"] = NameStyleConverter(output_path_in_gen_dir + "/" + sink_h_file_name).to_header_guard()
+ template_context["header_guard"] = NameStyleConverter(
+ output_path_in_gen_dir + "/" + sink_h_file_name).to_header_guard()
sink_h_file.write(sink_h_template.render(template_context))
sink_h_file.close()
for f in files:
template_context["file"] = f
template_context["template_file"] = "/instrumenting_probes_inl.h.tmpl"
- template_context["header_guard"] = NameStyleConverter(output_path_in_gen_dir + "/" + f.header_name).to_header_guard()
+ template_context["header_guard"] = NameStyleConverter(
+ output_path_in_gen_dir + "/" + f.header_name).to_header_guard()
h_template = jinja_env.get_template(template_context["template_file"])
h_file = open(output_dirpath + "/" + f.header_name, "w")
h_file.write(h_template.render(template_context))
h_file.close()
+
if __name__ == "__main__":
main()
diff --git a/chromium/third_party/blink/renderer/build/scripts/make_internal_runtime_flags.py b/chromium/third_party/blink/renderer/build/scripts/make_internal_runtime_flags.py
index 8b7413fbac1..3ea26d77100 100755
--- a/chromium/third_party/blink/renderer/build/scripts/make_internal_runtime_flags.py
+++ b/chromium/third_party/blink/renderer/build/scripts/make_internal_runtime_flags.py
@@ -38,12 +38,14 @@ import template_expander
# We want exactly the same parsing as RuntimeFeatureWriter
# but generate different files.
-class InternalRuntimeFlagsWriter(make_runtime_features.BaseRuntimeFeatureWriter):
+class InternalRuntimeFlagsWriter(
+ make_runtime_features.BaseRuntimeFeatureWriter):
class_name = 'InternalRuntimeFlags'
file_basename = 'internal_runtime_flags'
def __init__(self, json5_file_path, output_dir):
- super(InternalRuntimeFlagsWriter, self).__init__(json5_file_path, output_dir)
+ super(InternalRuntimeFlagsWriter, self).__init__(
+ json5_file_path, output_dir)
self._outputs = {
'internal_runtime_flags.idl': self.generate_idl,
'internal_runtime_flags.h': self.generate_header,
@@ -54,7 +56,6 @@ class InternalRuntimeFlagsWriter(make_runtime_features.BaseRuntimeFeatureWriter)
return {
'features': self._features,
'input_files': self._input_files,
- 'standard_features': self._standard_features,
}
@template_expander.use_jinja('templates/internal_runtime_flags.h.tmpl')
@@ -63,7 +64,6 @@ class InternalRuntimeFlagsWriter(make_runtime_features.BaseRuntimeFeatureWriter)
'features': self._features,
'feature_sets': self._feature_sets(),
'input_files': self._input_files,
- 'standard_features': self._standard_features,
'header_guard': self._header_guard,
}
diff --git a/chromium/third_party/blink/renderer/build/scripts/make_internal_settings.py b/chromium/third_party/blink/renderer/build/scripts/make_internal_settings.py
index 8d12f653635..148fe6d2565 100755
--- a/chromium/third_party/blink/renderer/build/scripts/make_internal_settings.py
+++ b/chromium/third_party/blink/renderer/build/scripts/make_internal_settings.py
@@ -43,9 +43,11 @@ class MakeInternalSettingsWriter(json5_generator.Writer):
_FILE_BASENAME = 'internal_settings_generated'
def __init__(self, json5_file_path, output_dir):
- super(MakeInternalSettingsWriter, self).__init__(json5_file_path, output_dir)
+ super(MakeInternalSettingsWriter, self).__init__(
+ json5_file_path, output_dir)
- self.json5_file.name_dictionaries.sort(key=lambda entry: entry['name'].original)
+ self.json5_file.name_dictionaries.sort(
+ key=lambda entry: entry['name'].original)
self._outputs = {
(self._FILE_BASENAME + '.h'): self.generate_header,
@@ -53,21 +55,29 @@ class MakeInternalSettingsWriter(json5_generator.Writer):
(self._FILE_BASENAME + '.idl'): self.generate_idl,
}
self._template_context = {
- 'input_files': self._input_files,
- 'primary_header_name': 'internal_settings_generated.h',
- 'settings': self.json5_file.name_dictionaries,
- 'header_guard': self.make_header_guard(self._relative_output_dir + self._FILE_BASENAME + '.h')
+ 'input_files':
+ self._input_files,
+ 'primary_header_name':
+ 'internal_settings_generated.h',
+ 'settings':
+ self.json5_file.name_dictionaries,
+ 'header_guard':
+ self.make_header_guard(self._relative_output_dir +
+ self._FILE_BASENAME + '.h')
}
- @template_expander.use_jinja('templates/internal_settings_generated.h.tmpl', filters=filters)
+ @template_expander.use_jinja(
+ 'templates/internal_settings_generated.h.tmpl', filters=filters)
def generate_header(self):
return self._template_context
- @template_expander.use_jinja('templates/internal_settings_generated.cc.tmpl', filters=filters)
+ @template_expander.use_jinja(
+ 'templates/internal_settings_generated.cc.tmpl', filters=filters)
def generate_implementation(self):
return self._template_context
- @template_expander.use_jinja('templates/internal_settings_generated.idl.tmpl', filters=filters)
+ @template_expander.use_jinja(
+ 'templates/internal_settings_generated.idl.tmpl', filters=filters)
def generate_idl(self):
return self._template_context
diff --git a/chromium/third_party/blink/renderer/build/scripts/make_names.py b/chromium/third_party/blink/renderer/build/scripts/make_names.py
index dba17c66a1d..3f7520a7ec6 100755
--- a/chromium/third_party/blink/renderer/build/scripts/make_names.py
+++ b/chromium/third_party/blink/renderer/build/scripts/make_names.py
@@ -48,10 +48,12 @@ class MakeNamesWriter(json5_generator.Writer):
'ImplementedAs': {},
# This is not used in make_names,py, but used in make_event_factory.py.
'interfaceHeaderDir': {},
- 'RuntimeEnabled': {}, # What should we do for runtime-enabled features?
+ # What should we do for runtime-enabled features?
+ 'RuntimeEnabled': {},
'Symbol': {},
}
default_metadata = {
+ 'allowDuplicates': False,
'export': '',
'namespace': '',
'suffix': '',
@@ -77,6 +79,13 @@ class MakeNamesWriter(json5_generator.Writer):
'"%s" is specified in %s.' %
(namespace, json5_file_path))
+ entries = self.json5_file.name_dictionaries
+ if self.json5_file.metadata['allowDuplicates']:
+ entries = json5_generator.remove_duplicates(entries)
+ else:
+ json5_generator.reject_duplicates(entries)
+ entries.sort(key=lambda x: _symbol(x))
+
basename, _ = os.path.splitext(os.path.basename(json5_file_path[0]))
self._outputs = {
(basename + '.h'): self.generate_header,
@@ -87,17 +96,19 @@ class MakeNamesWriter(json5_generator.Writer):
'namespace': namespace,
'suffix': suffix,
'export': export,
- 'entries': self.json5_file.name_dictionaries,
+ 'entries': entries,
'header_guard': self.make_header_guard(qualified_header),
'input_files': self._input_files,
'this_include_path': qualified_header,
}
- @template_expander.use_jinja("templates/make_names.h.tmpl", filters=filters)
+ @template_expander.use_jinja(
+ "templates/make_names.h.tmpl", filters=filters)
def generate_header(self):
return self._template_context
- @template_expander.use_jinja("templates/make_names.cc.tmpl", filters=filters)
+ @template_expander.use_jinja(
+ "templates/make_names.cc.tmpl", filters=filters)
def generate_implementation(self):
return self._template_context
diff --git a/chromium/third_party/blink/renderer/build/scripts/make_origin_trials.py b/chromium/third_party/blink/renderer/build/scripts/make_origin_trials.py
index 15dc91c5f54..db5b93a998e 100755
--- a/chromium/third_party/blink/renderer/build/scripts/make_origin_trials.py
+++ b/chromium/third_party/blink/renderer/build/scripts/make_origin_trials.py
@@ -47,20 +47,27 @@ class OriginTrialsWriter(make_runtime_features.BaseRuntimeFeatureWriter):
}
self._implied_mappings = self._make_implied_mappings()
self._trial_to_features_map = self._make_trial_to_features_map()
+ self._max_features_per_trial = max(
+ len(features) for features in self._trial_to_features_map.values())
self._set_trial_types()
+ @property
+ def origin_trial_features(self):
+ return self._origin_trial_features
+
def _make_implied_mappings(self):
# Set up the implied_by relationships between trials.
implied_mappings = dict()
- for implied_feature in (
- feature for feature in self._origin_trial_features
- if feature['origin_trial_feature_name'] and feature['implied_by']):
+ for implied_feature in (feature
+ for feature in self._origin_trial_features
+ if feature['origin_trial_feature_name']
+ and feature['implied_by']):
# An origin trial can only be implied by other features that also
# have a trial defined.
implied_by_trials = []
for implied_by_name in implied_feature['implied_by']:
- if any(implied_by_name == feature['name'].original and
- feature['origin_trial_feature_name']
+ if any(implied_by_name == feature['name'].original
+ and feature['origin_trial_feature_name']
for feature in self._origin_trial_features):
implied_by_trials.append(implied_by_name)
@@ -80,8 +87,10 @@ class OriginTrialsWriter(make_runtime_features.BaseRuntimeFeatureWriter):
def _make_trial_to_features_map(self):
trial_feature_mappings = {}
- for feature in [feature for feature in self._origin_trial_features
- if feature['origin_trial_feature_name']]:
+ for feature in [
+ feature for feature in self._origin_trial_features
+ if feature['origin_trial_feature_name']
+ ]:
trial_name = feature['origin_trial_feature_name']
if trial_name in trial_feature_mappings:
trial_feature_mappings[trial_name].append(feature)
@@ -92,11 +101,15 @@ class OriginTrialsWriter(make_runtime_features.BaseRuntimeFeatureWriter):
def _set_trial_types(self):
for feature in self._origin_trial_features:
trial_type = feature['origin_trial_type']
- if feature['origin_trial_allows_insecure'] and trial_type != 'deprecation':
+ if feature[
+ 'origin_trial_allows_insecure'] and trial_type != 'deprecation':
raise Exception('Origin trial must have type deprecation to '
- 'specify origin_trial_allows_insecure: %s' % feature['name'])
+ 'specify origin_trial_allows_insecure: %s' %
+ feature['name'])
if trial_type:
- feature['origin_trial_type'] = name_utilities._upper_camel_case(trial_type)
+ feature[
+ 'origin_trial_type'] = name_utilities._upper_camel_case(
+ trial_type)
@template_expander.use_jinja('templates/' + file_basename + '.cc.tmpl')
def generate_implementation(self):
@@ -105,6 +118,7 @@ class OriginTrialsWriter(make_runtime_features.BaseRuntimeFeatureWriter):
'origin_trial_features': self._origin_trial_features,
'implied_origin_trial_features': self._implied_mappings,
'trial_to_features_map': self._trial_to_features_map,
+ 'max_features_per_trial': self._max_features_per_trial,
'input_files': self._input_files,
}
diff --git a/chromium/third_party/blink/renderer/build/scripts/make_qualified_names.py b/chromium/third_party/blink/renderer/build/scripts/make_qualified_names.py
index 1b3bdaa039b..bb5c73eb4b9 100755
--- a/chromium/third_party/blink/renderer/build/scripts/make_qualified_names.py
+++ b/chromium/third_party/blink/renderer/build/scripts/make_qualified_names.py
@@ -60,7 +60,9 @@ class MakeQualifiedNamesWriter(json5_generator.Writer):
def __init__(self, json5_file_paths, output_dir):
super(MakeQualifiedNamesWriter, self).__init__(None, output_dir)
self._input_files = copy.copy(json5_file_paths)
- assert len(json5_file_paths) <= 3, 'MakeQualifiedNamesWriter requires at most 3 in files, got %d.' % len(json5_file_paths)
+ assert len(json5_file_paths) <= 3, \
+ 'MakeQualifiedNamesWriter requires at most 3 in files, got %d.' % \
+ len(json5_file_paths)
# Input files are in a strict order with more optional files *first*:
# 1) ARIA properties
@@ -75,52 +77,75 @@ class MakeQualifiedNamesWriter(json5_generator.Writer):
if len(json5_file_paths) >= 2:
tags_json5_filename = json5_file_paths.pop(0)
- self.tags_json5_file = Json5File.load_from_files([tags_json5_filename], self.default_metadata, self.default_parameters)
+ self.tags_json5_file = Json5File.load_from_files(
+ [tags_json5_filename], self.default_metadata,
+ self.default_parameters)
else:
self.tags_json5_file = None
- self.attrs_json5_file = Json5File.load_from_files([json5_file_paths.pop()], self.default_metadata, self.default_parameters)
+ self.attrs_json5_file = Json5File.load_from_files(
+ [json5_file_paths.pop()], self.default_metadata,
+ self.default_parameters)
if self.aria_reader is not None:
- self.attrs_json5_file.merge_from(self.aria_reader.attributes_list())
+ self.attrs_json5_file.merge_from(
+ self.aria_reader.attributes_list())
self.namespace = self._metadata('namespace')
cpp_namespace = self.namespace.lower() + '_names'
namespace_prefix = self._metadata('namespacePrefix') or 'k'
namespace_uri = self._metadata('namespaceURI')
- use_namespace_for_attrs = self.attrs_json5_file.metadata['attrsNullNamespace'] is None
+ use_namespace_for_attrs = self.attrs_json5_file.metadata[
+ 'attrsNullNamespace'] is None
self._outputs = {
(self.namespace.lower() + "_names.h"): self.generate_header,
- (self.namespace.lower() + "_names.cc"): self.generate_implementation,
+ (self.namespace.lower() + "_names.cc"):
+ self.generate_implementation,
}
- qualified_header = self._relative_output_dir + self.namespace.lower() + '_names.h'
+ qualified_header = self._relative_output_dir + self.namespace.lower(
+ ) + '_names.h'
self._template_context = {
- 'attrs': self.attrs_json5_file.name_dictionaries,
- 'cpp_namespace': cpp_namespace,
- 'export': self._metadata('export'),
- 'header_guard': self.make_header_guard(qualified_header),
- 'input_files': self._input_files,
- 'namespace': self.namespace,
- 'namespace_prefix': namespace_prefix,
- 'namespace_uri': namespace_uri,
- 'tags': self.tags_json5_file.name_dictionaries if self.tags_json5_file else [],
- 'this_include_path': qualified_header,
- 'use_namespace_for_attrs': use_namespace_for_attrs,
+ 'attrs':
+ self.attrs_json5_file.name_dictionaries,
+ 'cpp_namespace':
+ cpp_namespace,
+ 'export':
+ self._metadata('export'),
+ 'header_guard':
+ self.make_header_guard(qualified_header),
+ 'input_files':
+ self._input_files,
+ 'namespace':
+ self.namespace,
+ 'namespace_prefix':
+ namespace_prefix,
+ 'namespace_uri':
+ namespace_uri,
+ 'tags':
+ self.tags_json5_file.name_dictionaries
+ if self.tags_json5_file else [],
+ 'this_include_path':
+ qualified_header,
+ 'use_namespace_for_attrs':
+ use_namespace_for_attrs,
}
def _metadata(self, name):
metadata = self.attrs_json5_file.metadata[name].strip('"')
if self.tags_json5_file:
- assert metadata == self.tags_json5_file.metadata[name].strip('"'), 'Both files must have the same %s.' % name
+ assert metadata == self.tags_json5_file.metadata[name].strip(
+ '"'), 'Both files must have the same %s.' % name
return metadata
- @template_expander.use_jinja('templates/make_qualified_names.h.tmpl', filters=filters)
+ @template_expander.use_jinja(
+ 'templates/make_qualified_names.h.tmpl', filters=filters)
def generate_header(self):
return self._template_context
- @template_expander.use_jinja('templates/make_qualified_names.cc.tmpl', filters=filters)
+ @template_expander.use_jinja(
+ 'templates/make_qualified_names.cc.tmpl', filters=filters)
def generate_implementation(self):
return self._template_context
diff --git a/chromium/third_party/blink/renderer/build/scripts/make_runtime_features.py b/chromium/third_party/blink/renderer/build/scripts/make_runtime_features.py
index b5fb70f72e2..cafe8d94a8e 100755
--- a/chromium/third_party/blink/renderer/build/scripts/make_runtime_features.py
+++ b/chromium/third_party/blink/renderer/build/scripts/make_runtime_features.py
@@ -28,10 +28,14 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import copy
-import cPickle as pickle
import os
import sys
+if sys.version_info.major == 2:
+ import cPickle as pickle
+else:
+ import pickle
+
from blinkbuild.name_style_converter import NameStyleConverter
import make_runtime_features_utilities as util
import json5_generator
@@ -47,44 +51,39 @@ class BaseRuntimeFeatureWriter(json5_generator.Writer):
file_basename = None
def __init__(self, json5_file_path, output_dir):
- super(BaseRuntimeFeatureWriter, self).__init__(json5_file_path, output_dir)
+ super(BaseRuntimeFeatureWriter, self).__init__(json5_file_path,
+ output_dir)
# Subclasses should add generated output files and their contents to this dict.
self._outputs = {}
assert self.file_basename
self._features = self.json5_file.name_dictionaries
- # Dependency graph specified by 'depends_on' attribute.
- self._dependency_graph = util.init_graph(self._features)
+ origin_trial_set = util.origin_trials(self._features)
+
# Make sure the resulting dictionaries have all the keys we expect.
for feature in self._features:
- feature['data_member_name'] = self._data_member_name(feature['name'])
- # Most features just check their is_foo_enabled_ bool
- # but some depend on or are implied by other bools.
- enabled_condition = feature['data_member_name']
- assert not feature['implied_by'] or not feature['depends_on'], 'Only one of implied_by and depends_on is allowed'
- for implied_by_name in feature['implied_by']:
- enabled_condition += ' || ' + self._data_member_name(implied_by_name)
- for dependant_name in feature['depends_on']:
- assert dependant_name in self._dependency_graph, dependant_name + ' is not a feature.'
- self._dependency_graph[dependant_name].append(str(feature['name']))
- enabled_condition += ' && ' + self._data_member_name(dependant_name)
- feature['enabled_condition'] = enabled_condition
+ feature['in_origin_trial'] = str(
+ feature['name']) in origin_trial_set
+ feature['data_member_name'] = self._data_member_name(
+ feature['name'])
# If 'status' is a dict, add the values for all the not-mentioned platforms too.
if isinstance(feature['status'], dict):
- feature['status'] = self._status_with_all_platforms(feature['status'])
+ feature['status'] = self._status_with_all_platforms(
+ feature['status'])
# Specify the type of status
- feature['status_type'] = "dict" if isinstance(feature['status'], dict) else "str"
-
- util.check_if_dependency_graph_contains_cycle(self._dependency_graph)
- util.set_origin_trials_features(self._features, self._dependency_graph)
+ feature['status_type'] = "dict" if isinstance(
+ feature['status'], dict) else "str"
- self._standard_features = [feature for feature in self._features if not feature['custom']]
- self._origin_trial_features = [feature for feature in self._features if feature['in_origin_trial']]
- self._header_guard = self.make_header_guard(self._relative_output_dir + self.file_basename + '.h')
+ self._origin_trial_features = [
+ feature for feature in self._features if feature['in_origin_trial']
+ ]
+ self._header_guard = self.make_header_guard(self._relative_output_dir +
+ self.file_basename + '.h')
@staticmethod
def _data_member_name(str_or_converter):
- converter = NameStyleConverter(str_or_converter) if type(str_or_converter) is str else str_or_converter
+ converter = NameStyleConverter(str_or_converter) if type(
+ str_or_converter) is str else str_or_converter
return converter.to_class_data_member(prefix='is', suffix='enabled')
def _feature_sets(self):
@@ -123,7 +122,8 @@ class RuntimeFeatureWriter(BaseRuntimeFeatureWriter):
def _write_features_to_pickle_file(self, platform_output_dir):
# TODO(yashard): Get the file path from args instead of hardcoding it.
- file_name = os.path.join(platform_output_dir, '..', 'build', 'scripts', 'runtime_enabled_features.pickle')
+ file_name = os.path.join(platform_output_dir, '..', 'build', 'scripts',
+ 'runtime_enabled_features.pickle')
features_map = {}
for feature in self._features:
features_map[str(feature['name'])] = {
@@ -147,7 +147,6 @@ class RuntimeFeatureWriter(BaseRuntimeFeatureWriter):
'feature_sets': self._feature_sets(),
'platforms': self._platforms(),
'input_files': self._input_files,
- 'standard_features': self._standard_features,
'origin_trial_controlled_features': self._origin_trial_features,
'header_guard': self._header_guard,
}
@@ -166,8 +165,11 @@ class RuntimeFeatureTestHelpersWriter(BaseRuntimeFeatureWriter):
file_basename = 'runtime_enabled_features_test_helpers'
def __init__(self, json5_file_path, output_dir):
- super(RuntimeFeatureTestHelpersWriter, self).__init__(json5_file_path, output_dir)
- self._outputs = {('testing/' + self.file_basename + '.h'): self.generate_header}
+ super(RuntimeFeatureTestHelpersWriter, self).__init__(
+ json5_file_path, output_dir)
+ self._outputs = {
+ ('testing/' + self.file_basename + '.h'): self.generate_header
+ }
def _template_inputs(self):
return {
diff --git a/chromium/third_party/blink/renderer/build/scripts/make_runtime_features_utilities.py b/chromium/third_party/blink/renderer/build/scripts/make_runtime_features_utilities.py
index 8c6a5437ffd..df67bea4c98 100644
--- a/chromium/third_party/blink/renderer/build/scripts/make_runtime_features_utilities.py
+++ b/chromium/third_party/blink/renderer/build/scripts/make_runtime_features_utilities.py
@@ -2,48 +2,89 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+from collections import defaultdict
-def init_graph(features):
- graph = {}
- for feature in features:
- graph[str(feature['name'])] = []
- return graph
+def _error_message(message, feature, other_feature=None):
+ message = 'runtime_enabled_features.json5: {}: {}'.format(feature, message)
+ if other_feature:
+ message += ': {}'.format(other_feature)
+ return message
-def check_if_dependency_graph_contains_cycle(graph):
- state = {}
- visited, done = 0, 1
- def dfs(node):
- state[node] = visited
- for neighbor in graph.get(node, []):
- neighbor_state = state.get(neighbor)
- if neighbor_state == visited:
- raise Exception('Detected cycle in feature dependencies.')
- if neighbor_state == done:
- continue
- dfs(neighbor)
- state[node] = done
-
- for feature in graph:
- if feature not in state:
- dfs(feature)
-
-
-# Marks a feature to be in origin trials if
-# one of its dependencies is in origin trials.
-def set_origin_trials_features(features, graph):
- in_origin_trial = set()
+def _validate_runtime_features_graph(features):
+ """
+ Raises AssertionError when sanity check failed.
+ @param features: a List[Dict]. See origin_trials().
+ @returns None
+ """
+ feature_pool = {str(f['name']) for f in features}
+ origin_trial_pool = {
+ str(f['name'])
+ for f in features if f['origin_trial_feature_name']
+ }
+ for f in features:
+ assert not f['implied_by'] or not f['depends_on'], _error_message(
+ 'Only one of implied_by and depends_on is allowed', f['name'])
+ for d in f['depends_on']:
+ assert d in feature_pool, _error_message(
+ 'Depends on non-existent-feature', f['name'], d)
+ for i in f['implied_by']:
+ assert i in feature_pool, _error_message(
+ 'Implied by non-existent-feature', f['name'], i)
+ assert f['origin_trial_feature_name'] or i not in origin_trial_pool, \
+ _error_message(
+ 'A feature must be in origin trial if implied by an origin trial feature',
+ f['name'], i)
+
+ graph = {
+ str(feature['name']): feature['depends_on'] + feature['implied_by']
+ for feature in features
+ }
+ path = set()
+
+ def has_cycle(vertex):
+ path.add(vertex)
+ for neighbor in graph[vertex]:
+ if neighbor in path or has_cycle(neighbor):
+ return True
+ path.remove(vertex)
+ return False
+
+ for f in features:
+ assert not has_cycle(str(f['name'])), _error_message(
+ 'Cycle found in depends_on/implied_by graph', f['name'])
+
+
+def origin_trials(features):
+ """
+ This function returns all features that are in origin trial.
+ The dependency is considered in origin trial if itself is in origin trial
+ or any of its dependencies are in origin trial. Propagate dependency
+ tag use DFS can find all features that are in origin trial.
+
+ @param features: a List[Dict]. Each Dict must have keys 'name',
+ 'depends_on', 'implied_by' and 'origin_trial_feature_name'
+ (see runtime_enabled_features.json5).
+ @returns Set[str(runtime feature name)]
+ """
+ _validate_runtime_features_graph(features)
+
+ origin_trials_set = set()
+
+ graph = defaultdict(list)
+ for feature in features:
+ for dependency in feature['depends_on']:
+ graph[dependency].append(str(feature['name']))
def dfs(node):
- in_origin_trial.add(node)
- for neighbor in graph[node]:
- if neighbor not in in_origin_trial:
- dfs(neighbor)
+ origin_trials_set.add(node)
+ for dependent in graph[node]:
+ if dependent not in origin_trials_set:
+ dfs(dependent)
for feature in features:
if feature['origin_trial_feature_name']:
dfs(str(feature['name']))
- # Set 'in_origin_trial' for each feature.
- for feature in features:
- feature['in_origin_trial'] = True if str(feature['name']) in in_origin_trial else False
+
+ return origin_trials_set
diff --git a/chromium/third_party/blink/renderer/build/scripts/make_runtime_features_utilities_unittest.py b/chromium/third_party/blink/renderer/build/scripts/make_runtime_features_utilities_unittest.py
index 7e0be812cad..0f46950d782 100644
--- a/chromium/third_party/blink/renderer/build/scripts/make_runtime_features_utilities_unittest.py
+++ b/chromium/third_party/blink/renderer/build/scripts/make_runtime_features_utilities_unittest.py
@@ -8,59 +8,81 @@ import make_runtime_features_utilities as util
from blinkbuild.name_style_converter import NameStyleConverter
+def _feature(name,
+ depends_on=[],
+ implied_by=[],
+ origin_trial_feature_name=None):
+ return {
+ 'name': name,
+ 'depends_on': depends_on,
+ 'implied_by': implied_by,
+ 'origin_trial_feature_name': origin_trial_feature_name
+ }
+
+
class MakeRuntimeFeaturesUtilitiesTest(unittest.TestCase):
- def test_cycle_in_dependency(self):
+ def test_cycle(self):
# Cycle: 'c' => 'd' => 'e' => 'c'
- graph = {
- 'a': ['b'],
- 'b': [],
- 'c': ['a', 'd'],
- 'd': ['e'],
- 'e': ['c']
- }
- with self.assertRaises(Exception):
- util.check_if_dependency_graph_contains_cycle(graph)
+ with self.assertRaisesRegexp(
+ AssertionError, 'Cycle found in depends_on/implied_by graph'):
+ util.origin_trials([
+ _feature('a', depends_on=['b']),
+ _feature('b'),
+ _feature('c', implied_by=['a', 'd']),
+ _feature('d', depends_on=['e']),
+ _feature('e', implied_by=['c'])
+ ])
- def test_in_origin_trials_flag(self):
- features = [
- {'name': NameStyleConverter('a'), 'depends_on': [], 'origin_trial_feature_name': None},
- {'name': NameStyleConverter('b'), 'depends_on': ['a'], 'origin_trial_feature_name': 'OriginTrials'},
- {'name': NameStyleConverter('c'), 'depends_on': ['b'], 'origin_trial_feature_name': None},
- {'name': NameStyleConverter('d'), 'depends_on': ['b'], 'origin_trial_feature_name': None},
- {'name': NameStyleConverter('e'), 'depends_on': ['d'], 'origin_trial_feature_name': None},
- ]
- graph = {
- 'a': ['b'],
- 'b': ['c', 'd'],
- 'c': [],
- 'd': ['e'],
- 'e': []
- }
- results = [
- {'name': NameStyleConverter('a'), 'in_origin_trial': False},
- {'name': NameStyleConverter('b'), 'depends_on': ['a'],
- 'origin_trial_feature_name': 'OriginTrials', 'in_origin_trial': True},
- {'name': NameStyleConverter('c'), 'depends_on': ['b'], 'in_origin_trial': True},
- {'name': NameStyleConverter('d'), 'depends_on': ['b'], 'in_origin_trial': True},
- {'name': NameStyleConverter('e'), 'depends_on': ['d'], 'in_origin_trial': True},
- ]
+ def test_bad_dependency(self):
+ with self.assertRaisesRegexp(AssertionError,
+ 'a: Depends on non-existent-feature: x'):
+ util.origin_trials([_feature('a', depends_on=['x'])])
+
+ def test_bad_implication(self):
+ with self.assertRaisesRegexp(AssertionError,
+ 'a: Implied by non-existent-feature: x'):
+ util.origin_trials([_feature('a', implied_by=['x'])])
+ with self.assertRaisesRegexp(
+ AssertionError,
+ 'a: A feature must be in origin trial if implied by an origin trial feature: b'
+ ):
+ util.origin_trials([
+ _feature('a', implied_by=['b']),
+ _feature('b', origin_trial_feature_name='b')
+ ])
- util.set_origin_trials_features(features, graph)
- self.assertEqual(len(features), len(results))
- for feature, result in zip(features, results):
- self.assertEqual(result['in_origin_trial'], feature['in_origin_trial'])
+ def test_both_dependency_and_implication(self):
+ with self.assertRaisesRegexp(
+ AssertionError,
+ 'c: Only one of implied_by and depends_on is allowed'):
+ util.origin_trials([
+ _feature('a'),
+ _feature('b'),
+ _feature('c', depends_on=['a'], implied_by=['b'])
+ ])
- def test_init_graph(self):
+ def test_origin_trials(self):
features = [
- {'name': NameStyleConverter('a')},
- {'name': NameStyleConverter('b')},
- {'name': NameStyleConverter('c')},
+ _feature(NameStyleConverter('a')),
+ _feature(
+ NameStyleConverter('b'),
+ depends_on=['a'],
+ origin_trial_feature_name='b'),
+ _feature(NameStyleConverter('c'), depends_on=['b']),
+ _feature(NameStyleConverter('d'), depends_on=['b']),
+ _feature(NameStyleConverter('e'), depends_on=['d'])
]
+ self.assertSetEqual(util.origin_trials(features), {'b', 'c', 'd', 'e'})
- graph = util.init_graph(features)
- self.assertEqual(len(features), len(graph))
- for node in graph:
- self.assertEqual(len(graph[node]), 0)
+ features = [
+ _feature('a'),
+ _feature('b', depends_on=['x', 'y']),
+ _feature('c', depends_on=['y', 'z']),
+ _feature('x', depends_on=['a']),
+ _feature('y', depends_on=['x'], origin_trial_feature_name='y'),
+ _feature('z', depends_on=['y'])
+ ]
+ self.assertSetEqual(util.origin_trials(features), {'b', 'c', 'y', 'z'})
if __name__ == "__main__":
diff --git a/chromium/third_party/blink/renderer/build/scripts/make_settings.py b/chromium/third_party/blink/renderer/build/scripts/make_settings.py
index b463bee6e48..59e0a2ba7ec 100755
--- a/chromium/third_party/blink/renderer/build/scripts/make_settings.py
+++ b/chromium/third_party/blink/renderer/build/scripts/make_settings.py
@@ -65,18 +65,24 @@ class MakeSettingsWriter(json5_generator.Writer):
def __init__(self, json5_file_path, output_dir):
super(MakeSettingsWriter, self).__init__(json5_file_path, output_dir)
- self.json5_file.name_dictionaries.sort(key=lambda entry: entry['name'].original)
+ self.json5_file.name_dictionaries.sort(
+ key=lambda entry: entry['name'].original)
self._outputs = {
('settings_macros.h'): self.generate_macros,
}
self._template_context = {
- 'input_files': self._input_files,
- 'settings': self.json5_file.name_dictionaries,
- 'header_guard': self.make_header_guard(self._relative_output_dir + 'settings_macros.h')
+ 'input_files':
+ self._input_files,
+ 'settings':
+ self.json5_file.name_dictionaries,
+ 'header_guard':
+ self.make_header_guard(self._relative_output_dir +
+ 'settings_macros.h')
}
- @template_expander.use_jinja('templates/settings_macros.h.tmpl', filters=filters)
+ @template_expander.use_jinja(
+ 'templates/settings_macros.h.tmpl', filters=filters)
def generate_macros(self):
return self._template_context
diff --git a/chromium/third_party/blink/renderer/build/scripts/make_style_builder.py b/chromium/third_party/blink/renderer/build/scripts/make_style_builder.py
index fe097454f5b..bf88ea56694 100755
--- a/chromium/third_party/blink/renderer/build/scripts/make_style_builder.py
+++ b/chromium/third_party/blink/renderer/build/scripts/make_style_builder.py
@@ -33,6 +33,7 @@ import types
from core.css import css_properties
import json5_generator
+
def calculate_apply_functions_to_declare(property_):
property_['should_declare_functions'] = \
not property_['longhands'] \
@@ -40,8 +41,8 @@ def calculate_apply_functions_to_declare(property_):
property_['use_property_class_in_stylebuilder'] = \
property_['should_declare_functions']
-class StyleBuilderWriter(json5_generator.Writer):
+class StyleBuilderWriter(json5_generator.Writer):
def __init__(self, json5_file_paths, output_dir):
super(StyleBuilderWriter, self).__init__([], output_dir)
@@ -56,5 +57,6 @@ class StyleBuilderWriter(json5_generator.Writer):
def css_properties(self):
return self._json5_properties
+
if __name__ == '__main__':
json5_generator.Maker(StyleBuilderWriter).main()
diff --git a/chromium/third_party/blink/renderer/build/scripts/media_feature_symbol.py b/chromium/third_party/blink/renderer/build/scripts/media_feature_symbol.py
index 10d8a10f354..423c96ba126 100644
--- a/chromium/third_party/blink/renderer/build/scripts/media_feature_symbol.py
+++ b/chromium/third_party/blink/renderer/build/scripts/media_feature_symbol.py
@@ -2,7 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-
from blinkbuild.name_style_converter import NameStyleConverter
@@ -16,4 +15,5 @@ def mediaFeatureSymbol(entry, suffix):
def getMediaFeatureSymbolWithSuffix(suffix):
def returnedFunction(entry):
return mediaFeatureSymbol(entry, suffix)
+
return returnedFunction
diff --git a/chromium/third_party/blink/renderer/build/scripts/name_utilities.py b/chromium/third_party/blink/renderer/build/scripts/name_utilities.py
index abbc49bcca8..b476f328d4d 100644
--- a/chromium/third_party/blink/renderer/build/scripts/name_utilities.py
+++ b/chromium/third_party/blink/renderer/build/scripts/name_utilities.py
@@ -66,5 +66,6 @@ def id_for_css_property_alias(property_name):
def _upper_camel_case(property_name):
- converter = NameStyleConverter(property_name) if isinstance(property_name, str) else property_name
+ converter = NameStyleConverter(property_name) if isinstance(
+ property_name, str) else property_name
return converter.to_upper_camel_case()
diff --git a/chromium/third_party/blink/renderer/build/scripts/rule_bison.py b/chromium/third_party/blink/renderer/build/scripts/rule_bison.py
index 2fd397c88ee..26a7bb30233 100755
--- a/chromium/third_party/blink/renderer/build/scripts/rule_bison.py
+++ b/chromium/third_party/blink/renderer/build/scripts/rule_bison.py
@@ -33,8 +33,8 @@
# found in the LICENSE file.
# usage: rule_bison.py INPUT_FILE OUTPUT_DIR BISON_EXE
-# INPUT_FILE is a path to either XPathGrammar.y.
-# OUTPUT_DIR is where the bison-generated .cpp and .h files should be placed.
+# INPUT_FILE is a path to *.y such as xpath_grammar.y.
+# OUTPUT_DIR is where the bison-generated .cc and .h files should be placed.
import errno
import os
@@ -44,73 +44,72 @@ import sys
from blinkbuild.name_style_converter import NameStyleConverter
-assert len(sys.argv) == 4 or len(sys.argv) == 5
-
-inputFile = sys.argv[1]
-outputDir = sys.argv[2]
-bisonExe = sys.argv[3]
-
-pathToBison = os.path.split(bisonExe)[0]
-if pathToBison:
- # Make sure this path is in the path so that it can find its auxiliary
- # binaries (in particular, m4). To avoid other 'm4's being found, insert
- # at head, rather than tail.
- os.environ['PATH'] = pathToBison + os.pathsep + os.environ['PATH']
-
-inputName = os.path.basename(inputFile)
-assert inputName == 'xpath_grammar.y'
-prefix = {'xpath_grammar.y': 'xpathyy'}[inputName]
-
-(inputRoot, inputExt) = os.path.splitext(inputName)
-
-# The generated .h will be in a different location depending on the bison
-# version.
-outputHTries = [
- os.path.join(outputDir, inputRoot + '.cpp.h'),
- os.path.join(outputDir, inputRoot + '.hpp'),
- os.path.join(outputDir, inputRoot + '.hh'),
-]
-
-for outputHTry in outputHTries:
- try:
- os.unlink(outputHTry)
- except OSError, e:
- if e.errno != errno.ENOENT:
- raise
-
-outputCpp = os.path.join(outputDir, inputRoot + '.cc')
-
-returnCode = subprocess.call([bisonExe, '-d', '-p', prefix, inputFile, '-o', outputCpp])
-assert returnCode == 0
-
-# Find the name that bison used for the generated header file.
-outputHTmp = None
-for outputHTry in outputHTries:
- try:
- os.stat(outputHTry)
- outputHTmp = outputHTry
- break
- except OSError, e:
- if e.errno != errno.ENOENT:
- raise
-
-assert outputHTmp != None
-
-# Read the header file in under the generated name and remove it.
-outputHFile = open(outputHTmp)
-outputHContents = outputHFile.read()
-outputHFile.close()
-os.unlink(outputHTmp)
-
-# Rewrite the generated header with #include guards.
-outputH = os.path.join(outputDir, inputRoot + '.h')
-
-outputHInGen = outputH.replace('gen/', '')
-headerGuard = NameStyleConverter(outputHInGen).to_header_guard()
-
-outputHFile = open(outputH, 'w')
-print >>outputHFile, '#ifndef %s' % headerGuard
-print >>outputHFile, '#define %s' % headerGuard
-print >>outputHFile, outputHContents
-print >>outputHFile, '#endif // %s' % headerGuard
-outputHFile.close()
+
+def modify_file(path, prefix_lines, suffix_lines, replace_list=[]):
+ prefix_lines = map(lambda s: s + '\n', prefix_lines)
+ suffix_lines = map(lambda s: s + '\n', suffix_lines)
+ with open(path, 'r') as f:
+ old_lines = f.readlines()
+ for i in range(len(old_lines)):
+ for src, dest in replace_list:
+ old_lines[i] = old_lines[i].replace(src, dest)
+ new_lines = prefix_lines + old_lines + suffix_lines
+ with open(path, 'w') as f:
+ f.writelines(new_lines)
+
+
+def main():
+ assert len(sys.argv) == 4
+
+ input_file = sys.argv[1]
+ output_dir = sys.argv[2]
+ bison_exe = sys.argv[3]
+
+ path_to_bison = os.path.split(bison_exe)[0]
+ if path_to_bison:
+ # Make sure this path is in the path so that it can find its auxiliary
+ # binaries (in particular, m4). To avoid other 'm4's being found, insert
+ # at head, rather than tail.
+ os.environ['PATH'] = path_to_bison + os.pathsep + os.environ['PATH']
+
+ input_name = os.path.basename(input_file)
+
+ # Output name without directory and extension.
+ output_basename = os.path.splitext(input_name)[0] + '_generated'
+
+ output_cc = os.path.join(output_dir, output_basename + '.cc')
+ BISON_HEADER_EXT = '.hh'
+ original_output_h = os.path.join(output_dir,
+ output_basename + BISON_HEADER_EXT)
+
+ return_code = subprocess.call(
+ [bison_exe, '-d', input_file, '-o', output_cc])
+ assert return_code == 0
+ # If the file doesn't exist, this raise an OSError.
+ os.stat(original_output_h)
+
+ # The generated files contain references to the original "foo.hh" for
+ # #include and #line. We replace them with "foo.h".
+ common_replace_list = [(output_basename + BISON_HEADER_EXT,
+ output_basename + '.h')]
+
+ # Rewrite the generated header with #include guards.
+ CLANG_FORMAT_DISABLE_LINE = "// clang-format off"
+ output_h = os.path.join(output_dir, output_basename + '.h')
+ header_guard = NameStyleConverter(output_h).to_header_guard()
+ modify_file(
+ original_output_h, [
+ CLANG_FORMAT_DISABLE_LINE,
+ '#ifndef %s' % header_guard,
+ '#define %s' % header_guard
+ ], ['#endif // %s' % header_guard],
+ replace_list=common_replace_list)
+ os.rename(original_output_h, output_h)
+
+ modify_file(
+ output_cc, [CLANG_FORMAT_DISABLE_LINE], [],
+ replace_list=common_replace_list)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/chromium/third_party/blink/renderer/build/scripts/run_with_pythonpath.py b/chromium/third_party/blink/renderer/build/scripts/run_with_pythonpath.py
index 9da708d0eeb..c6ea8aa746c 100755
--- a/chromium/third_party/blink/renderer/build/scripts/run_with_pythonpath.py
+++ b/chromium/third_party/blink/renderer/build/scripts/run_with_pythonpath.py
@@ -19,9 +19,11 @@ def main():
env = os.environ.copy()
if len(python_paths) > 0:
- existing_pp = (os.pathsep + env['PYTHONPATH']) if 'PYTHONPATH' in env else ''
+ existing_pp = (
+ os.pathsep + env['PYTHONPATH']) if 'PYTHONPATH' in env else ''
env['PYTHONPATH'] = os.pathsep.join(python_paths) + existing_pp
sys.exit(subprocess.call([sys.executable] + args, env=env))
+
if __name__ == '__main__':
main()
diff --git a/chromium/third_party/blink/renderer/build/scripts/scripts.gni b/chromium/third_party/blink/renderer/build/scripts/scripts.gni
index ca3a57615a3..7da4412ccb3 100644
--- a/chromium/third_party/blink/renderer/build/scripts/scripts.gni
+++ b/chromium/third_party/blink/renderer/build/scripts/scripts.gni
@@ -71,13 +71,10 @@ make_trie_helpers_files =
# on Posix we want to run the system one on the path.
if (host_os == "win") {
gperf_exe = rebase_path("//third_party/gperf/bin/gperf.exe", root_build_dir)
- bison_exe = rebase_path("//third_party/bison/bin/bison.exe", root_build_dir)
} else if (is_mac) {
gperf_exe = mac_bin_path + "gperf"
- bison_exe = mac_bin_path + "bison"
} else {
gperf_exe = "gperf"
- bison_exe = "bison"
}
# Templates --------------------------------------------------------------------
@@ -85,8 +82,8 @@ if (host_os == "win") {
_blink_gen_dir = "$root_gen_dir/third_party/blink/renderer"
make_core_generated_deps = [
- "//third_party/blink/renderer/core:generated_testing_idls",
"//third_party/blink/renderer/core:core_event_interfaces",
+ "//third_party/blink/renderer/core:generated_testing_idls",
]
# A wrapper for python scripts. This adds the following paths to PYTHONPATH,
@@ -96,9 +93,7 @@ make_core_generated_deps = [
template("blink_python_runner") {
action(target_name) {
script = "$_scripts_dir/run_with_pythonpath.py"
- sources = [
- invoker.script,
- ]
+ sources = [ invoker.script ]
if (defined(invoker.sources)) {
sources += invoker.sources
}
@@ -223,6 +218,7 @@ template("css_properties") {
in_files = [
"css/css_properties.json5",
"css/computed_style_field_aliases.json5",
+ "../platform/runtime_enabled_features.json5",
]
if (defined(invoker.in_files)) {
in_files += invoker.in_files
diff --git a/chromium/third_party/blink/renderer/build/scripts/template_expander.py b/chromium/third_party/blink/renderer/build/scripts/template_expander.py
index 2cf3ad6a098..6e23970028b 100644
--- a/chromium/third_party/blink/renderer/build/scripts/template_expander.py
+++ b/chromium/third_party/blink/renderer/build/scripts/template_expander.py
@@ -32,7 +32,11 @@ import sys
import jinja2
-def apply_template(template_path, params, filters=None, tests=None, template_cache=None):
+def apply_template(template_path,
+ params,
+ filters=None,
+ tests=None,
+ template_cache=None):
template = None
if filters is None and tests is None and template_cache is not None:
@@ -62,8 +66,14 @@ def use_jinja(template_path, filters=None, tests=None, template_cache=None):
def real_decorator(generator):
def generator_internal(*args, **kwargs):
parameters = generator(*args, **kwargs)
- return apply_template(template_path, parameters, filters=filters,
- tests=tests, template_cache=template_cache)
- generator_internal.func_name = generator.func_name
+ return apply_template(
+ template_path,
+ parameters,
+ filters=filters,
+ tests=tests,
+ template_cache=template_cache)
+
+ generator_internal.__name__ = generator.__name__
return generator_internal
+
return real_decorator
diff --git a/chromium/third_party/blink/renderer/build/scripts/templates/document_policy_features.cc.tmpl b/chromium/third_party/blink/renderer/build/scripts/templates/document_policy_features.cc.tmpl
new file mode 100644
index 00000000000..a98433a965d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/build/scripts/templates/document_policy_features.cc.tmpl
@@ -0,0 +1,43 @@
+{% from 'templates/macros.tmpl' import license, source_files_for_generated_file %}
+{{license()}}
+
+{{ source_files_for_generated_file(template_file, input_files) }}
+
+#include "base/no_destructor.h"
+#include "third_party/blink/public/common/feature_policy/document_policy_features.h"
+#include "third_party/blink/public/common/feature_policy/policy_value.h"
+#include "third_party/blink/public/mojom/feature_policy/policy_value.mojom.h"
+#include "third_party/blink/public/mojom/feature_policy/document_policy_feature.mojom.h"
+
+
+namespace blink {
+
+const DocumentPolicyFeatureInfoMap& GetDocumentPolicyFeatureInfoMap() {
+ static const base::NoDestructor<DocumentPolicyFeatureInfoMap> feature_info_map({
+ {%- for feature in features %}
+ {
+ mojom::DocumentPolicyFeature::k{{feature.name}},
+ {
+ "{{feature.document_policy_name}}",
+ "{{feature.value_name}}",
+ {{parse_default_value(feature.default_value, feature.value_type)}}
+ }
+ },
+ {%- endfor %}
+ });
+ return *feature_info_map;
+}
+
+const DocumentPolicyNameFeatureMap& GetDocumentPolicyNameFeatureMap() {
+ static const base::NoDestructor<DocumentPolicyNameFeatureMap> name_feature_map([] {
+ DocumentPolicyNameFeatureMap map;
+ for (const auto& entry : GetDocumentPolicyFeatureInfoMap())
+ map.emplace(entry.second.feature_name, entry.first);
+ return map;
+ }());
+ return *name_feature_map;
+}
+
+} // namespace blink
+
+
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 6ed62df03e6..eb1fd35ec87 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())
+ if (!RuntimeEnabledFeatures::{{tag.runtimeEnabled}}Enabled(&document))
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 9951adb809f..ea03ce43776 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
@@ -30,9 +30,13 @@ HTMLTypeMap CreateHTMLTypeMap() {
return html_type_map;
}
-HTMLElementType htmlElementTypeForTag(const AtomicString& tagName) {
+static const HTMLTypeMap& GetHTMLTypeMap() {
DEFINE_STATIC_LOCAL(const HTMLTypeMap, html_type_map, (CreateHTMLTypeMap()));
+ return html_type_map;
+}
+HTMLElementType htmlElementTypeForTag(const AtomicString& tagName, const Document* document) {
+ const auto& html_type_map = GetHTMLTypeMap();
auto it = html_type_map.find(tagName);
if (it == html_type_map.end())
return HTMLElementType::kHTMLUnknownElement;
@@ -40,7 +44,7 @@ HTMLElementType htmlElementTypeForTag(const AtomicString& tagName) {
{% for tag in tags|sort %}
{% if tag.runtimeEnabled %}
if (tagName == "{{tag.name}}") {
- if (!RuntimeEnabledFeatures::{{tag.runtimeEnabled}}Enabled()) {
+ if (!RuntimeEnabledFeatures::{{tag.runtimeEnabled}}Enabled(document)) {
return HTMLElementType::kHTMLUnknownElement;
}
}
@@ -48,5 +52,9 @@ HTMLElementType htmlElementTypeForTag(const AtomicString& tagName) {
{% endfor %}
return it->value;
}
+
+bool IsKnownBuiltinTagName(const AtomicString& tag_name) {
+ return GetHTMLTypeMap().Contains(tag_name);
+}
{% endif %}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/build/scripts/templates/element_type_helpers.h.tmpl b/chromium/third_party/blink/renderer/build/scripts/templates/element_type_helpers.h.tmpl
index d7e5599ca86..1b5297d52dc 100644
--- a/chromium/third_party/blink/renderer/build/scripts/templates/element_type_helpers.h.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/templates/element_type_helpers.h.tmpl
@@ -11,6 +11,9 @@
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
+
+class Document;
+
// Type checking.
{% for tag in tags|sort if not tag.multipleTagNames and not tag.noTypeHelpers %}
class {{tag.interface}};
@@ -26,6 +29,9 @@ template <>
struct DowncastTraits<{{tag.interface}}> {
static bool AllowFrom(const Element& element) {
{% if tag.runtimeEnabled %}
+ // If the following line doesn't compile, your feature may vary by context,
+ // in which case you'll need to write your own type helpers that can
+ // distinguish elements without relying solely on tag name.
if (!RuntimeEnabledFeatures::{{tag.runtimeEnabled}}Enabled())
return false;
{% endif %}
@@ -50,9 +56,11 @@ enum class HTMLElementType {
// The corresponding HTMLElement type for the tag name will be returned
// Do NOT use this function with SVG tag names and SVGElements
// If tagName is an undefined html tag name HTMLUnknownElement is returned
-HTMLElementType htmlElementTypeForTag(const AtomicString& tagName);
+HTMLElementType htmlElementTypeForTag(const AtomicString& tagName, const Document*);
+
+bool IsKnownBuiltinTagName(const AtomicString& tag_name);
{% endif %}
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_{{namespace|upper}}_ELEMENT_TYPE_HELPERS_H_ \ No newline at end of file
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_{{namespace|upper}}_ELEMENT_TYPE_HELPERS_H_
diff --git a/chromium/third_party/blink/renderer/build/scripts/templates/event_factory.cc.tmpl b/chromium/third_party/blink/renderer/build/scripts/templates/event_factory.cc.tmpl
index 97d7aee7562..1d4397fdffb 100644
--- a/chromium/third_party/blink/renderer/build/scripts/templates/event_factory.cc.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/templates/event_factory.cc.tmpl
@@ -9,21 +9,15 @@
#include "third_party/blink/renderer/core/events/event_factory.h"
{% endif %}
-#include "third_party/blink/renderer/core/frame/deprecation.h"
{% for header_path in include_header_paths %}
#include "{{header_path}}"
{% endfor %}
-#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
Event* Event{{suffix}}Factory::Create(ExecutionContext* executionContext, const String& type) {
- {% for event in events if event|name|create_event_ignore_case_list or event|name|create_event_ignore_case_and_measure_list %}
- {% if event|name|create_event_ignore_case_list or event|name|create_event_ignore_case_and_measure_list %}
+ {% for event in events %}
if (DeprecatedEqualIgnoringCase(type, "{{event|name}}"){% if event.RuntimeEnabled %} && RuntimeEnabledFeatures::{{event.RuntimeEnabled}}(){% endif %}) {
- {% else %}
- if (type == "{{event|name}}"{% if event.RuntimeEnabled %} && RuntimeEnabledFeatures::{{event.RuntimeEnabled}}(){% endif %}) {
- {% endif %}
{% if not event|name|create_event_ignore_case_list %}
UseCounter::Count(executionContext, WebFeature::k{{event|name|measure_name}});
{% endif %}
diff --git a/chromium/third_party/blink/renderer/build/scripts/templates/feature_policy_helper.cc.tmpl b/chromium/third_party/blink/renderer/build/scripts/templates/feature_policy_helper.cc.tmpl
index 13202e6c1c0..6a7d4426455 100644
--- a/chromium/third_party/blink/renderer/build/scripts/templates/feature_policy_helper.cc.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/templates/feature_policy_helper.cc.tmpl
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/feature_policy/feature_policy_helper.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.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/origin_trials/origin_trials.h"
@@ -32,16 +33,16 @@ const FeatureNameMap& GetDefaultFeatureNameMap() {
DEFINE_STATIC_LOCAL(FeatureNameMap, default_feature_name_map, ());
if (default_feature_name_map.IsEmpty()) {
{% for feature in feature_policy_features %}
- {% if not feature.depends_on or feature.in_origin_trial %}
+ {% if not feature.depends_on or feature.name in fp_origin_trial_dependency_map %}
default_feature_name_map.Set(k{{feature.name}}PolicyName,
mojom::FeaturePolicyFeature::k{{feature.name}});
{% endif %}
{% endfor %}
- {% for runtime_feature_name, FP_features in runtime_to_feature_policy_map.items() %}
+ {% for runtime_feature_name, dependent_features in runtime_to_feature_policy_map.items() | sort %}
if (RuntimeEnabledFeatures::{{runtime_feature_name}}Enabled()) {
- {% for feature in FP_features %}
- default_feature_name_map.Set(k{{feature.name}}PolicyName,
- mojom::FeaturePolicyFeature::k{{feature.name}});
+ {% for feature in dependent_features %}
+ default_feature_name_map.Set(k{{feature}}PolicyName,
+ mojom::FeaturePolicyFeature::k{{feature}});
{% endfor %}
}
{% endfor %}
@@ -49,14 +50,49 @@ const FeatureNameMap& GetDefaultFeatureNameMap() {
return default_feature_name_map;
}
+const DocumentPolicyFeatureSet& GetAvailableDocumentPolicyFeatures() {
+ DEFINE_STATIC_LOCAL(DocumentPolicyFeatureSet, features, ());
+ if (features.IsEmpty()) {
+ {% for feature in document_policy_features %}
+ {% if not feature.depends_on or feature.name in dp_origin_trial_dependency_map %}
+ features.insert(mojom::DocumentPolicyFeature::k{{feature.name}});
+ {% endif %}
+ {% endfor %}
+ {% for runtime_feature_name, dependent_features in runtime_to_document_policy_map.items() | sort %}
+ if (RuntimeEnabledFeatures::{{runtime_feature_name}}Enabled()) {
+ {% for feature in dependent_features %}
+ features.insert(mojom::DocumentPolicyFeature::k{{feature}});
+ {% endfor %}
+ }
+ {% endfor %}
+ }
+ return features;
+}
+
+// If any of the origin trial runtime feature is enabled, returns false,
+// i.e. the feature is considered enabled by origin trial.
bool DisabledByOriginTrial(const String& feature_name,
FeatureContext* feature_context) {
- {% for feature_name, dependencies in origin_trial_dependency_map.items() %}
+ {% for feature_name, dependencies in fp_origin_trial_dependency_map.items() | sort %}
if (feature_name == k{{feature_name}}PolicyName) {
return
{%- for dependency in dependencies %}
{%- if not loop.first %} &&{% endif %}
- !RuntimeEnabledFeatures::{{dependency.name}}Enabled(feature_context)
+ !RuntimeEnabledFeatures::{{dependency}}Enabled(feature_context)
+ {%- endfor %};
+ }
+ {% endfor %}
+ return false;
+}
+
+bool DisabledByOriginTrial(mojom::blink::DocumentPolicyFeature feature,
+ FeatureContext* feature_context) {
+ {% for feature_name, dependencies in dp_origin_trial_dependency_map.items() | sort %}
+ if (feature == mojom::DocumentPolicyFeature::k{{feature_name}}) {
+ return
+ {%- for dependency in dependencies %}
+ {%- if not loop.first %} &&{% endif %}
+ !RuntimeEnabledFeatures::{{dependency}}Enabled(feature_context)
{%- endfor %};
}
{% endfor %}
diff --git a/chromium/third_party/blink/renderer/build/scripts/templates/instrumenting_probes_inl.h.tmpl b/chromium/third_party/blink/renderer/build/scripts/templates/instrumenting_probes_inl.h.tmpl
index 1c7ab5881ba..c10b8a23c26 100644
--- a/chromium/third_party/blink/renderer/build/scripts/templates/instrumenting_probes_inl.h.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/templates/instrumenting_probes_inl.h.tmpl
@@ -49,9 +49,9 @@ class {{export_symbol}} {{probe.name}} : public ProbeBase {
public:
explicit {{probe.name}}({{ params_decl(probe) }});
~{{probe.name}}();
- Member<{{sink_class}}> probe_sink;
+ {{sink_class}}* probe_sink = nullptr;
{% for param in probe.params %}
- {{param.member_type}} {{param.name}};
+ {{param.type}} {{param.name}};
{% endfor %}
};
diff --git a/chromium/third_party/blink/renderer/build/scripts/templates/internal_runtime_flags.h.tmpl b/chromium/third_party/blink/renderer/build/scripts/templates/internal_runtime_flags.h.tmpl
index 5fc7be243b6..39a28e3f1c2 100644
--- a/chromium/third_party/blink/renderer/build/scripts/templates/internal_runtime_flags.h.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/templates/internal_runtime_flags.h.tmpl
@@ -25,13 +25,13 @@ class InternalRuntimeFlags : public ScriptWrappable {
// These are reset between web tests from Internals::resetToConsistentState
// using RuntimeEnabledFeatures::Backup.
- {% for feature in standard_features if feature.settable_from_internals %}
+ {% for feature in features if feature.settable_from_internals %}
void set{{feature.name}}Enabled(bool isEnabled) {
RuntimeEnabledFeatures::Set{{feature.name}}Enabled(isEnabled);
}
{% endfor %}
- {% for feature in standard_features %}
+ {% for feature in features %}
bool {{feature.name.to_lower_camel_case()}}Enabled() {
{% if feature.in_origin_trial %}
return RuntimeEnabledFeatures::{{feature.name}}EnabledByRuntimeFlag();
diff --git a/chromium/third_party/blink/renderer/build/scripts/templates/internal_runtime_flags.idl.tmpl b/chromium/third_party/blink/renderer/build/scripts/templates/internal_runtime_flags.idl.tmpl
index 5728a76e968..2489df60379 100644
--- a/chromium/third_party/blink/renderer/build/scripts/templates/internal_runtime_flags.idl.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/templates/internal_runtime_flags.idl.tmpl
@@ -4,7 +4,7 @@
{{source_files_for_generated_file(template_file, input_files)}}
interface InternalRuntimeFlags {
- {% for feature in standard_features %}
+ {% for feature in features %}
{%+ if feature.condition %}[Conditional={{feature.condition}}] {% endif -%}
{% if feature.settable_from_internals %}
attribute boolean {{feature.name.to_lower_camel_case()}}Enabled;
diff --git a/chromium/third_party/blink/renderer/build/scripts/templates/make_names.h.tmpl b/chromium/third_party/blink/renderer/build/scripts/templates/make_names.h.tmpl
index 6b624979d16..f6dd475efb3 100644
--- a/chromium/third_party/blink/renderer/build/scripts/templates/make_names.h.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/templates/make_names.h.tmpl
@@ -19,7 +19,7 @@
namespace blink {
namespace {{namespace}} {
-{% for entry in entries|sort %}
+{% for entry in entries %}
{{symbol_export}}extern const WTF::AtomicString& {{entry|symbol}};
{% endfor %}
diff --git a/chromium/third_party/blink/renderer/build/scripts/templates/origin_trials.cc.tmpl b/chromium/third_party/blink/renderer/build/scripts/templates/origin_trials.cc.tmpl
index 9787ab39a5d..6dfbb285075 100644
--- a/chromium/third_party/blink/renderer/build/scripts/templates/origin_trials.cc.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/templates/origin_trials.cc.tmpl
@@ -5,49 +5,45 @@
#include "third_party/blink/renderer/core/origin_trials/origin_trials.h"
+#include <algorithm>
+#include <array>
+#include <iterator>
+#include "base/stl_util.h"
#include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
-#include "third_party/blink/renderer/platform/wtf/hash_map.h"
namespace blink {
-using TrialToFeaturesMap = HashMap<String, Vector<OriginTrialFeature>>;
-
namespace {
-const TrialToFeaturesMap& GetTrialToFeaturesMap() {
- // The object needs to be thread-safe because service workers can call this
- // function as well.
- DEFINE_THREAD_SAFE_STATIC_LOCAL(TrialToFeaturesMap, trial_to_features_map, ());
- if (trial_to_features_map.IsEmpty()) {
+static constexpr size_t kMaxFeaturesPerTrial = {{max_features_per_trial}};
+static constexpr struct {
+ const char* trial_name;
+ unsigned feature_count;
+ std::array<OriginTrialFeature, kMaxFeaturesPerTrial> features;
+} kTrialToFeaturesMap[] = {
{% for trial_name, features_list in trial_to_features_map.items() %}
- trial_to_features_map.Set("{{trial_name}}",
- Vector<OriginTrialFeature>({
- {%- for trial_feature in features_list %}
-OriginTrialFeature::k{{trial_feature.name}},
- {%- endfor %}
- }));
+ { "{{trial_name}}", {{features_list|length}}, { {%- for trial_feature in features_list %}OriginTrialFeature::k{{trial_feature.name}}, {%- endfor %} } },
{% endfor %}
// For testing
- trial_to_features_map.Set("This trial does not exist",
- Vector<OriginTrialFeature>({OriginTrialFeature::kNonExisting}));
- }
- return trial_to_features_map;
-}
+ { "This trial does not exist", 1, { OriginTrialFeature::kNonExisting } },
+};
} // namespace
-bool origin_trials::IsTrialValid(const String& trial_name) {
- return GetTrialToFeaturesMap().Contains(trial_name);
+bool origin_trials::IsTrialValid(const StringView& trial_name) {
+ return std::any_of(
+ std::begin(kTrialToFeaturesMap), std::end(kTrialToFeaturesMap),
+ [&](const auto& entry) { return entry.trial_name == trial_name; });
}
-bool origin_trials::IsTrialEnabledForInsecureContext(const String& trial_name) {
- {% for feature in origin_trial_features if feature.origin_trial_allows_insecure %}
- if (trial_name == "{{feature.origin_trial_feature_name}}") {
- return true;
- }
+bool origin_trials::IsTrialEnabledForInsecureContext(const StringView& trial_name) {
+ static const char* const kEnabledForInsecureContext[] = {
+ {% for trial in origin_trial_features|selectattr('origin_trial_allows_insecure')|map(attribute='origin_trial_feature_name')|unique %}
+ "{{trial}}",
{% endfor %}
- return false;
+ };
+ return base::Contains(kEnabledForInsecureContext, trial_name);
}
OriginTrialType origin_trials::GetTrialType(OriginTrialFeature feature) {
@@ -61,15 +57,21 @@ OriginTrialType origin_trials::GetTrialType(OriginTrialFeature feature) {
}
}
-const Vector<OriginTrialFeature>& origin_trials::FeaturesForTrial(const String& trial_name) {
- DCHECK(IsTrialValid(trial_name));
- return GetTrialToFeaturesMap().find(trial_name)->value;
+
+base::span<const OriginTrialFeature> origin_trials::FeaturesForTrial(
+ const StringView& trial_name) {
+ auto it = std::find_if(
+ std::begin(kTrialToFeaturesMap), std::end(kTrialToFeaturesMap),
+ [&](const auto& entry) { return entry.trial_name == trial_name; });
+ DCHECK(it != std::end(kTrialToFeaturesMap));
+ return {it->features.begin(), it->feature_count};
}
-Vector<OriginTrialFeature> origin_trials::GetImpliedFeatures(OriginTrialFeature feature) {
+base::span<const OriginTrialFeature> origin_trials::GetImpliedFeatures(
+ OriginTrialFeature feature) {
{% for implied_by_name, implied_list in implied_origin_trial_features.items() %}
if (feature == OriginTrialFeature::k{{implied_by_name}}) {
- Vector<OriginTrialFeature> implied_features = {
+ static constexpr OriginTrialFeature implied_features[] = {
{%- for implied_name in implied_list %}
OriginTrialFeature::k{{implied_name}},
{%- endfor %}
@@ -77,7 +79,7 @@ OriginTrialFeature::k{{implied_name}},
return implied_features;
}
{% endfor %}
- return Vector<OriginTrialFeature>();
+ return {};
}
bool origin_trials::FeatureEnabledForOS(OriginTrialFeature feature) {
diff --git a/chromium/third_party/blink/renderer/build/scripts/templates/runtime_enabled_features.cc.tmpl b/chromium/third_party/blink/renderer/build/scripts/templates/runtime_enabled_features.cc.tmpl
index 379e58c9441..ca5cbd86227 100644
--- a/chromium/third_party/blink/renderer/build/scripts/templates/runtime_enabled_features.cc.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/templates/runtime_enabled_features.cc.tmpl
@@ -13,19 +13,15 @@
namespace blink {
RuntimeEnabledFeatures::Backup::Backup()
- : {% for feature in standard_features -%}
-{% if feature.in_origin_trial %}
- {{feature.name.to_class_data_member()}}(RuntimeEnabledFeatures::{{feature.name}}EnabledByRuntimeFlag())
-{% else %}
- {{feature.name.to_class_data_member()}}(RuntimeEnabledFeatures::{{feature.name}}Enabled())
-{% endif %}
+ : {% for feature in features -%}
+ {{feature.data_member_name}}(RuntimeEnabledFeatures::{{feature.data_member_name}})
{%- if not loop.last %},
{%+ endif -%}
{% endfor %} {}
void RuntimeEnabledFeatures::Backup::Restore() {
- {% for feature in standard_features %}
- RuntimeEnabledFeatures::Set{{feature.name}}Enabled({{feature.name.to_class_data_member()}});
+ {% for feature in features %}
+ RuntimeEnabledFeatures::{{feature.data_member_name}} = {{feature.data_member_name}};
{% endfor %}
}
@@ -71,7 +67,7 @@ void RuntimeEnabledFeatures::SetFeatureEnabledFromString(
const char* name;
bool* setting;
} kFeatures[] = {
- {% for feature in standard_features %}
+ {% for feature in features %}
{"{{feature.name}}", &{{feature.data_member_name}}},
{% endfor %}
};
@@ -91,20 +87,24 @@ bool RuntimeEnabledFeatures::{{feature.name}}Enabled(const FeatureContext* conte
if (!RuntimeEnabledFeatures::{{depends_on}}Enabled(context))
return false;
{% endfor %}
- if (RuntimeEnabledFeatures::{{feature.name}}EnabledByRuntimeFlag())
+ {% for implied_by in feature.implied_by %}
+ if (RuntimeEnabledFeatures::{{implied_by}}Enabled(context))
+ return true;
+ {% endfor %}
+ if ({{feature.data_member_name}})
return true;
-{% if not feature.origin_trial_feature_name %}
+ {% if not feature.origin_trial_feature_name %}
// The feature does not have an origin trial name and its runtime flag
// is not enabled.
return false;
-{% else %}
+ {% else %}
return context && context->FeatureEnabled(OriginTrialFeature::k{{feature.name}});
-{% endif %}
+ {% endif %}
}
{% endfor %}
-{% for feature in standard_features %}
+{% for feature in features %}
{% if feature.status_type == 'str' %}
bool RuntimeEnabledFeatures::{{feature.data_member_name}} = {{'true' if feature.status == 'stable' else 'false'}};
{% endif %}
@@ -113,7 +113,7 @@ bool RuntimeEnabledFeatures::{{feature.data_member_name}} = {{'true' if feature.
// Platform-dependent features
{% for platform in platforms %}
#if defined(OS_{{platform | upper}})
-{% for feature in standard_features %}
+{% for feature in features %}
{% if feature.status_type == 'dict' %}
bool RuntimeEnabledFeatures::{{feature.data_member_name}} = {{'true' if feature.status[platform] == 'stable' else 'false'}};
{% endif %}
@@ -128,7 +128,7 @@ bool RuntimeEnabledFeatures::{{feature.data_member_name}} = {{'true' if feature.
!defined(OS_{{platform | upper}})
{%- endfor %}
-{% for feature in standard_features %}
+{% for feature in features %}
{% if feature.status_type == 'dict' %}
bool RuntimeEnabledFeatures::{{feature.data_member_name}} = {{'true' if feature.status['default'] == 'stable' else 'false'}};
{% endif %}
diff --git a/chromium/third_party/blink/renderer/build/scripts/templates/runtime_enabled_features.h.tmpl b/chromium/third_party/blink/renderer/build/scripts/templates/runtime_enabled_features.h.tmpl
index 1f821a29d97..4ea32aa9626 100644
--- a/chromium/third_party/blink/renderer/build/scripts/templates/runtime_enabled_features.h.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/templates/runtime_enabled_features.h.tmpl
@@ -48,8 +48,8 @@ class PLATFORM_EXPORT RuntimeEnabledFeatures {
void Restore();
private:
- {% for feature in standard_features %}
- bool {{feature.name.to_class_data_member()}};
+ {% for feature in features %}
+ bool {{feature.data_member_name}};
{% endfor %}
};
@@ -62,13 +62,19 @@ class PLATFORM_EXPORT RuntimeEnabledFeatures {
{% for feature in features %}
{% if not feature.in_origin_trial %}
- {% if feature.custom %}
- static bool {{feature.name}}Enabled();
- {% else %}
static void Set{{feature.name}}Enabled(bool enabled) { {{feature.data_member_name}} = enabled; }
- static bool {{feature.name}}Enabled() { return {{feature.enabled_condition}}; }
- static bool {{feature.name}}Enabled(const FeatureContext*) { return {{feature.enabled_condition}}; }
- {% endif %}
+ static bool {{feature.name}}Enabled() {
+ {% for depends_on in feature.depends_on %}
+ if (!{{depends_on}}Enabled())
+ return false;
+ {% endfor %}
+ {% for implied_by in feature.implied_by %}
+ if ({{implied_by}}Enabled())
+ return true;
+ {% endfor %}
+ return {{feature.data_member_name}};
+ }
+ static bool {{feature.name}}Enabled(const FeatureContext*) { return {{feature.name}}Enabled(); }
{% endif %}
{% endfor %}
@@ -84,18 +90,16 @@ class PLATFORM_EXPORT RuntimeEnabledFeatures {
// feature is enabled in a given context.
{% for feature in origin_trial_controlled_features %}
- {% if feature.custom %}
- static bool {{feature.name}}EnabledByRuntimeFlag();
- {% else %}
static void Set{{feature.name}}Enabled(bool enabled) { {{feature.data_member_name}} = enabled; }
- static bool {{feature.name}}EnabledByRuntimeFlag() { return {{feature.enabled_condition}}; }
- {% endif %}
+ static bool {{feature.name}}EnabledByRuntimeFlag() { return {{feature.name}}Enabled(nullptr); }
static bool {{feature.name}}Enabled(const FeatureContext*);
{% endfor %}
private:
- {% for feature in standard_features %}
+ friend class RuntimeEnabledFeaturesTestHelpers;
+
+ {% for feature in features %}
static bool {{feature.data_member_name}};
{% endfor %}
};
diff --git a/chromium/third_party/blink/renderer/build/scripts/templates/runtime_enabled_features_test_helpers.h.tmpl b/chromium/third_party/blink/renderer/build/scripts/templates/runtime_enabled_features_test_helpers.h.tmpl
index fc528180c8c..1c78938c6bb 100644
--- a/chromium/third_party/blink/renderer/build/scripts/templates/runtime_enabled_features_test_helpers.h.tmpl
+++ b/chromium/third_party/blink/renderer/build/scripts/templates/runtime_enabled_features_test_helpers.h.tmpl
@@ -11,33 +11,32 @@
namespace blink {
-template <bool (&getter)(), void (&setter)(bool)>
-class ScopedRuntimeEnabledFeatureForTest {
+// Don't use this class directly. Use Scoped*ForTest instead.
+class RuntimeEnabledFeaturesTestHelpers {
public:
- ScopedRuntimeEnabledFeatureForTest(bool enabled)
- : enabled_(enabled), original_(getter()) {
- setter(enabled);
- }
-
- ~ScopedRuntimeEnabledFeatureForTest() {
- CHECK_EQ(enabled_, getter());
- setter(original_);
- }
-
- private:
- bool enabled_;
- bool original_;
+ template <bool& data_member>
+ class ScopedRuntimeEnabledFeature {
+ public:
+ ScopedRuntimeEnabledFeature(bool enabled)
+ : enabled_(enabled), original_(data_member) { data_member = enabled; }
+ ~ScopedRuntimeEnabledFeature() {
+ CHECK_EQ(enabled_, data_member);
+ data_member = original_;
+ }
+ private:
+ bool enabled_;
+ bool original_;
+ };
+
+ {% for feature in features %}
+ using Scoped{{feature.name}} = ScopedRuntimeEnabledFeature<
+ RuntimeEnabledFeatures::{{feature.data_member_name}}>;
+ {% endfor %}
};
{% for feature in features %}
-typedef ScopedRuntimeEnabledFeatureForTest<
-{% if feature.in_origin_trial %}
- RuntimeEnabledFeatures::{{feature.name}}EnabledByRuntimeFlag,
-{% else %}
- RuntimeEnabledFeatures::{{feature.name}}Enabled,
-{% endif %}
- RuntimeEnabledFeatures::Set{{feature.name}}Enabled>
- Scoped{{feature.name}}ForTest;
+using Scoped{{feature.name}}ForTest =
+ RuntimeEnabledFeaturesTestHelpers::Scoped{{feature.name}};
{% endfor %}
} // namespace blink
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 3253a627439..83a54424e3c 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,8 +16,7 @@ bool WebOriginTrials::isTrialEnabled(const WebDocument* web_document, const WebS
if (!web_document) return false;
if (!origin_trials::IsTrialValid(trial))
return false;
- const Vector<OriginTrialFeature>& features = origin_trials::FeaturesForTrial(trial);
- for (OriginTrialFeature feature : features) {
+ for (OriginTrialFeature feature : origin_trials::FeaturesForTrial(trial)) {
switch (feature) {
{% for feature in features %}
{% if feature.origin_trial_feature_name %}
diff --git a/chromium/third_party/blink/renderer/build/scripts/update_css_ranking.py b/chromium/third_party/blink/renderer/build/scripts/update_css_ranking.py
index 262fc1590d1..22d5f72e023 100644
--- a/chromium/third_party/blink/renderer/build/scripts/update_css_ranking.py
+++ b/chromium/third_party/blink/renderer/build/scripts/update_css_ranking.py
@@ -14,7 +14,6 @@ import cluster
import json5_generator
import math
-
CSS_RANKING_API = "http://www.chromestatus.com/data/csspopularity"
CSS_RANKING_FILE = "../../core/css/css_properties_ranking.json5"
CSS_PROPERTIES = "../../core/css/css_properties.json5"
@@ -39,18 +38,27 @@ def update_css_ranking(css_ranking_file, css_ranking_api):
"""
css_ranking = json.loads(urllib2.urlopen(css_ranking_api).read())
css_ranking_content = {"properties": {}, "data": []}
- css_ranking_content["data"] = [property_["property_name"] for property_ in
- sorted(css_ranking, key=lambda x: -float(x["day_percentage"]))]
+ css_ranking_content["data"] = [
+ property_["property_name"] for property_ in sorted(
+ css_ranking, key=lambda x: -float(x["day_percentage"]))
+ ]
reformat_properties_name(css_ranking_content["data"])
with open(css_ranking_file, "w") as fw:
- fw.write("// The popularity ranking of all css properties the first properties is the most\n")
- fw.write("// used property according to: https://www.chromestatus.com/metrics/css/popularity\n")
+ fw.write(
+ "// The popularity ranking of all css properties the first properties is the most\n"
+ )
+ fw.write(
+ "// used property according to: https://www.chromestatus.com/metrics/css/popularity\n"
+ )
json.dump(css_ranking_content, fw, indent=4, sort_keys=False)
-def find_partition_rule(css_property_set, all_properties, n_cluster, transform=lambda x: x):
+def find_partition_rule(css_property_set,
+ all_properties,
+ n_cluster,
+ transform=lambda x: x):
"""Find partition rule for a set of CSS property based on its popularity
Args:
@@ -64,9 +72,13 @@ def find_partition_rule(css_property_set, all_properties, n_cluster, transform=l
Returns:
partition rule for css_property_set
"""
- _, cluster_alloc, _ = cluster.k_means([transform(p[1]) for p in css_property_set], n_cluster=n_cluster)
- return [all_properties[css_property_set[i][0]] for i in range(len(cluster_alloc) - 1)
- if cluster_alloc[i] != cluster_alloc[i + 1]] + [1.0]
+ _, cluster_alloc, _ = cluster.k_means(
+ [transform(p[1]) for p in css_property_set], n_cluster=n_cluster)
+ return [
+ all_properties[css_property_set[i][0]]
+ for i in range(len(cluster_alloc) - 1)
+ if cluster_alloc[i] != cluster_alloc[i + 1]
+ ] + [1.0]
def produce_partition_rule(config_file, css_ranking_api):
@@ -77,42 +89,61 @@ def produce_partition_rule(config_file, css_ranking_api):
css_ranking_api: url to CSS ranking api
"""
- css_ranking = sorted(json.loads(urllib2.urlopen(css_ranking_api).read()),
- key=lambda x: -x["day_percentage"])
+ css_ranking = sorted(
+ json.loads(urllib2.urlopen(css_ranking_api).read()),
+ key=lambda x: -x["day_percentage"])
total_css_properties = len(css_ranking)
- css_ranking_dictionary = dict([(x["property_name"], x["day_percentage"] * 100) for x in css_ranking])
- css_ranking_cdf = dict(zip([x["property_name"] for x in css_ranking],
- [float(i) / total_css_properties for i in range(total_css_properties)]))
- css_properties = json5_generator.Json5File.load_from_files([CSS_PROPERTIES]).name_dictionaries
-
- rare_non_inherited_properties = sorted([(x["name"].original, css_ranking_dictionary[x["name"].original])
- for x in css_properties if not x["inherited"]
- and x["field_group"] is not None
- and "*" in x["field_group"]
- and x["name"].original in css_ranking_dictionary],
- key=lambda x: -x[1])
- rare_inherited_properties = sorted([(x["name"].original, css_ranking_dictionary[x["name"].original])
- for x in css_properties if x["inherited"]
- and x["field_group"] is not None
- and "*" in x["field_group"]
- and x["name"].original in css_ranking_dictionary],
- key=lambda x: -x[1])
-
- rni_properties_rule = find_partition_rule(rare_non_inherited_properties,
- css_ranking_cdf, n_cluster=3)
-
- ri_properties_rule = find_partition_rule(rare_inherited_properties,
- css_ranking_cdf,
- n_cluster=2, transform=lambda x: math.log(x + 10e-6))
+ css_ranking_dictionary = dict(
+ [(x["property_name"], x["day_percentage"] * 100) for x in css_ranking])
+ css_ranking_cdf = dict(
+ zip([x["property_name"] for x in css_ranking], [
+ float(i) / total_css_properties
+ for i in range(total_css_properties)
+ ]))
+ css_properties = json5_generator.Json5File.load_from_files(
+ [CSS_PROPERTIES]).name_dictionaries
+
+ rare_non_inherited_properties = sorted(
+ [(x["name"].original, css_ranking_dictionary[x["name"].original])
+ for x in css_properties
+ if not x["inherited"] and x["field_group"] is not None and "*" in
+ x["field_group"] and x["name"].original in css_ranking_dictionary],
+ key=lambda x: -x[1])
+ rare_inherited_properties = sorted(
+ [(x["name"].original, css_ranking_dictionary[x["name"].original])
+ for x in css_properties
+ if x["inherited"] and x["field_group"] is not None and "*" in
+ x["field_group"] and x["name"].original in css_ranking_dictionary],
+ key=lambda x: -x[1])
+
+ rni_properties_rule = find_partition_rule(
+ rare_non_inherited_properties, css_ranking_cdf, n_cluster=3)
+
+ ri_properties_rule = find_partition_rule(
+ rare_inherited_properties,
+ css_ranking_cdf,
+ n_cluster=2,
+ transform=lambda x: math.log(x + 10e-6))
with open(config_file, 'w') as fw:
- fw.write("// The grouping parameter is a cumulative distribution over the whole set of ranked\n")
+ fw.write(
+ "// The grouping parameter is a cumulative distribution " \
+ "over the whole set of ranked\n"
+ )
fw.write("// CSS properties.\n")
json.dump({
"parameters": {},
- "data": [{"name": "rare_non_inherited_properties_rule", "cumulative_distribution": rni_properties_rule},
- {"name": "rare_inherited_properties_rule", "cumulative_distribution": ri_properties_rule}]
- }, fw, indent=4)
+ "data": [{
+ "name": "rare_non_inherited_properties_rule",
+ "cumulative_distribution": rni_properties_rule
+ },
+ {
+ "name": "rare_inherited_properties_rule",
+ "cumulative_distribution": ri_properties_rule
+ }]
+ },
+ fw,
+ indent=4)
if __name__ == '__main__':
diff --git a/chromium/third_party/blink/renderer/config.gni b/chromium/third_party/blink/renderer/config.gni
index fd71bcc12c1..44be63445b8 100644
--- a/chromium/third_party/blink/renderer/config.gni
+++ b/chromium/third_party/blink/renderer/config.gni
@@ -61,16 +61,6 @@ if (use_webaudio_pffft) {
feature_defines_list += [ "WTF_USE_WEBAUDIO_PFFFT=1" ]
}
-if (blink_symbol_level == 0 && is_win && symbol_level != 0) {
- # If we use no_symbols on Windows when symbol_level is not zero then no
- # PDB will be generated but ninja will be expecting one. This would mean
- # that the build would always be dirty. Using minimal_symbols in this
- # situation keeps the build times fast (roughly identical to no_symbols)
- # while still generating a PDB to keep ninja happy (and it gives us proper
- # call stacks).
- blink_symbol_level = 1
-}
-
if (blink_symbol_level == 2) {
blink_symbols_config = [ "//build/config/compiler:symbols" ]
} else if (blink_symbol_level == 1) {
diff --git a/chromium/third_party/blink/renderer/controller/BUILD.gn b/chromium/third_party/blink/renderer/controller/BUILD.gn
index afb22594902..ea7f0d6dbda 100644
--- a/chromium/third_party/blink/renderer/controller/BUILD.gn
+++ b/chromium/third_party/blink/renderer/controller/BUILD.gn
@@ -45,27 +45,51 @@ jumbo_component("controller") {
"memory_usage_monitor.h",
]
+ if (is_linux) {
+ sources += [
+ "memory_usage_monitor_posix.cc",
+ "memory_usage_monitor_posix.h",
+ ]
+ deps += [ "//third_party/blink/public/mojom:memory_usage_monitor_linux_mojo_bindings_blink" ]
+ }
if (is_android) {
sources += [
"crash_memory_metrics_reporter_impl.cc",
"crash_memory_metrics_reporter_impl.h",
- "highest_pmf_reporter.cc",
- "highest_pmf_reporter.h",
- "memory_usage_monitor_android.cc",
- "memory_usage_monitor_android.h",
+ "memory_usage_monitor_posix.cc",
+ "memory_usage_monitor_posix.h",
"oom_intervention_impl.cc",
"oom_intervention_impl.h",
- "user_level_memory_pressure_signal_generator.cc",
- "user_level_memory_pressure_signal_generator.h",
+ ]
+ }
+ if (is_win) {
+ sources += [
+ "memory_usage_monitor_win.cc",
+ "memory_usage_monitor_win.h",
]
}
if (is_mac) {
+ sources += [
+ "memory_usage_monitor_mac.cc",
+ "memory_usage_monitor_mac.h",
+ ]
libs = [
"AppKit.framework",
"Foundation.framework",
]
}
+ # HighestPmfReporter depends on MemoryUsageMonitor and MemoryUsageMonitor
+ # depends on platform specific code. Explicitly specify supported platforms.
+ if (is_linux || is_win || is_android || is_mac) {
+ sources += [
+ "highest_pmf_reporter.cc",
+ "highest_pmf_reporter.h",
+ "user_level_memory_pressure_signal_generator.cc",
+ "user_level_memory_pressure_signal_generator.h",
+ ]
+ }
+
configs -= [ "//build/config/compiler:default_symbols" ]
configs += blink_symbols_config
}
@@ -84,15 +108,11 @@ group("webkit_unit_tests") {
visibility = [] # Allow re-assignment of list.
visibility = [ "*" ]
testonly = true
- deps = [
- ":blink_unittests",
- ]
+ deps = [ ":blink_unittests" ]
}
test("blink_unittests") {
- deps = [
- ":blink_unittests_sources",
- ]
+ deps = [ ":blink_unittests_sources" ]
data_deps = [
":blink_unittests_data",
@@ -114,9 +134,7 @@ test("blink_unittests") {
}
test("blink_perf_tests") {
- deps = [
- ":blink_perf_tests_sources",
- ]
+ deps = [ ":blink_perf_tests_sources" ]
}
jumbo_source_set("blink_perf_tests_sources") {
@@ -124,9 +142,7 @@ jumbo_source_set("blink_perf_tests_sources") {
visibility = [ "*" ]
testonly = true
- sources = [
- "tests/run_all_tests.cc",
- ]
+ sources = [ "tests/run_all_tests.cc" ]
deps = [
":controller",
@@ -147,20 +163,26 @@ jumbo_source_set("blink_unittests_sources") {
visibility = [ "*" ]
testonly = true
- sources = [
- "tests/run_all_tests.cc",
- ]
+ sources = [ "tests/run_all_tests.cc" ]
sources += bindings_unittest_files
+ if (is_linux) {
+ sources += [ "memory_usage_monitor_posix_test.cc" ]
+ }
if (is_android) {
sources += [
- "highest_pmf_reporter_test.cc",
- "memory_usage_monitor_android_test.cc",
- "memory_usage_monitor_test.cc",
+ "memory_usage_monitor_posix_test.cc",
"oom_intervention_impl_test.cc",
"user_level_memory_pressure_signal_generator_test.cc",
]
}
+ if (is_linux || is_android || is_mac || is_win) {
+ sources += [
+ "highest_pmf_reporter_test.cc",
+ "memory_usage_monitor_test.cc",
+ ]
+ }
+
deps = [
":controller",
"//base",
diff --git a/chromium/third_party/blink/renderer/controller/blink_initializer.cc b/chromium/third_party/blink/renderer/controller/blink_initializer.cc
index e9d7093a868..174f3d1d4ac 100644
--- a/chromium/third_party/blink/renderer/controller/blink_initializer.cc
+++ b/chromium/third_party/blink/renderer/controller/blink_initializer.cc
@@ -62,8 +62,16 @@
#if defined(OS_ANDROID)
#include "third_party/blink/renderer/controller/crash_memory_metrics_reporter_impl.h"
-#include "third_party/blink/renderer/controller/highest_pmf_reporter.h"
#include "third_party/blink/renderer/controller/oom_intervention_impl.h"
+#endif
+
+#if defined(OS_LINUX)
+#include "third_party/blink/renderer/controller/memory_usage_monitor_posix.h"
+#endif
+
+#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_MACOSX) || \
+ defined(OS_WIN)
+#include "third_party/blink/renderer/controller/highest_pmf_reporter.h"
#include "third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator.h"
#endif
@@ -133,12 +141,16 @@ void InitializeCommon(Platform* platform, mojo::BinderMap* binders) {
MemoryAblationExperiment::MaybeStartForRenderer(task_runner);
#if defined(OS_ANDROID)
- // Initialize UserLevelMemoryPressureSignalGenerator so it starts monitoring.
- UserLevelMemoryPressureSignalGenerator::Instance();
-
// Initialize CrashMemoryMetricsReporterImpl in order to assure that memory
// allocation does not happen in OnOOMCallback.
CrashMemoryMetricsReporterImpl::Instance();
+#endif
+
+#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_MACOSX) || \
+ defined(OS_WIN)
+ // Initialize UserLevelMemoryPressureSignalGenerator so it starts monitoring.
+ if (UserLevelMemoryPressureSignalGenerator::Enabled())
+ UserLevelMemoryPressureSignalGenerator::Instance();
// Start reporting the highest private memory footprint after the first
// navigation.
@@ -180,6 +192,11 @@ void BlinkInitializer::RegisterInterfaces(mojo::BinderMap& binders) {
&CrashMemoryMetricsReporterImpl::Bind)),
main_thread->GetTaskRunner());
#endif
+#if defined(OS_LINUX)
+ binders.Add(ConvertToBaseRepeatingCallback(
+ CrossThreadBindRepeating(&MemoryUsageMonitorPosix::Bind)),
+ main_thread->GetTaskRunner());
+#endif
binders.Add(ConvertToBaseRepeatingCallback(
CrossThreadBindRepeating(&BlinkLeakDetector::Create)),
diff --git a/chromium/third_party/blink/renderer/controller/crash_memory_metrics_reporter_impl.cc b/chromium/third_party/blink/renderer/controller/crash_memory_metrics_reporter_impl.cc
index 68b99c49c1f..1c39a7c9c69 100644
--- a/chromium/third_party/blink/renderer/controller/crash_memory_metrics_reporter_impl.cc
+++ b/chromium/third_party/blink/renderer/controller/crash_memory_metrics_reporter_impl.cc
@@ -9,9 +9,7 @@
#include "base/allocator/partition_allocator/oom_callback.h"
#include "base/metrics/histogram_macros.h"
#include "base/process/memory.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/renderer/controller/memory_usage_monitor_android.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
@@ -38,50 +36,54 @@ CrashMemoryMetricsReporterImpl::CrashMemoryMetricsReporterImpl() {
CrashMemoryMetricsReporterImpl::OnOOMCallback);
}
-CrashMemoryMetricsReporterImpl::~CrashMemoryMetricsReporterImpl() = default;
+CrashMemoryMetricsReporterImpl::~CrashMemoryMetricsReporterImpl() {
+ MemoryUsageMonitor::Instance().RemoveObserver(this);
+}
void CrashMemoryMetricsReporterImpl::SetSharedMemory(
base::UnsafeSharedMemoryRegion shared_metrics_buffer) {
// This method should be called only once per process.
DCHECK(!shared_metrics_mapping_.IsValid());
shared_metrics_mapping_ = shared_metrics_buffer.Map();
+ MemoryUsageMonitor::Instance().AddObserver(this);
}
void CrashMemoryMetricsReporterImpl::OnMemoryPing(MemoryUsage usage) {
- WriteIntoSharedMemory(
- CrashMemoryMetricsReporterImpl::MemoryUsageToMetrics(usage));
+ DCHECK(IsMainThread());
+ last_reported_metrics_ =
+ CrashMemoryMetricsReporterImpl::MemoryUsageToMetrics(usage);
+ WriteIntoSharedMemory();
}
-void CrashMemoryMetricsReporterImpl::WriteIntoSharedMemory(
- const OomInterventionMetrics& metrics) {
+void CrashMemoryMetricsReporterImpl::WriteIntoSharedMemory() {
if (!shared_metrics_mapping_.IsValid())
return;
auto* metrics_shared =
shared_metrics_mapping_.GetMemoryAs<OomInterventionMetrics>();
- memcpy(metrics_shared, &metrics, sizeof(OomInterventionMetrics));
+ *metrics_shared = last_reported_metrics_;
}
void CrashMemoryMetricsReporterImpl::OnOOMCallback() {
// TODO(yuzus: Support allocation failures on other threads as well.
if (!IsMainThread())
return;
+ CrashMemoryMetricsReporterImpl& instance =
+ CrashMemoryMetricsReporterImpl::Instance();
// If shared_metrics_mapping_ is not set, it means OnNoMemory happened before
// initializing render process host sets the shared memory.
- if (!CrashMemoryMetricsReporterImpl::Instance()
- .shared_metrics_mapping_.IsValid())
+ if (!instance.shared_metrics_mapping_.IsValid())
return;
// Else, we can send the allocation_failed bool.
- OomInterventionMetrics metrics;
// TODO(yuzus): Report this UMA on all the platforms. Currently this is only
// reported on Android.
- metrics.allocation_failed = 1; // true
- CrashMemoryMetricsReporterImpl::Instance().WriteIntoSharedMemory(metrics);
+ instance.last_reported_metrics_.allocation_failed = 1; // true
+ instance.WriteIntoSharedMemory();
}
// static
OomInterventionMetrics CrashMemoryMetricsReporterImpl::MemoryUsageToMetrics(
MemoryUsage usage) {
- OomInterventionMetrics metrics = {};
+ OomInterventionMetrics metrics;
DCHECK(!std::isnan(usage.private_footprint_bytes));
DCHECK(!std::isnan(usage.swap_bytes));
diff --git a/chromium/third_party/blink/renderer/controller/crash_memory_metrics_reporter_impl.h b/chromium/third_party/blink/renderer/controller/crash_memory_metrics_reporter_impl.h
index 811c5b1350b..5fe84f1692f 100644
--- a/chromium/third_party/blink/renderer/controller/crash_memory_metrics_reporter_impl.h
+++ b/chromium/third_party/blink/renderer/controller/crash_memory_metrics_reporter_impl.h
@@ -31,9 +31,6 @@ class CONTROLLER_EXPORT CrashMemoryMetricsReporterImpl
void SetSharedMemory(
base::UnsafeSharedMemoryRegion shared_metrics_buffer) override;
- // MemoryUsageMonitor::Observer:
- void OnMemoryPing(MemoryUsage) override;
-
// This method tracks when an allocation failure occurs. It should be hooked
// into all platform allocation failure handlers in a process such as
// base::TerminateBecauseOutOfMemory() and OOM_CRASH() in Partition Alloc.
@@ -47,8 +44,12 @@ class CONTROLLER_EXPORT CrashMemoryMetricsReporterImpl
private:
FRIEND_TEST_ALL_PREFIXES(OomInterventionImplTest, CalculateProcessFootprint);
- void WriteIntoSharedMemory(const OomInterventionMetrics& metrics);
+ // MemoryUsageMonitor::Observer:
+ void OnMemoryPing(MemoryUsage) override;
+
+ void WriteIntoSharedMemory();
+ OomInterventionMetrics last_reported_metrics_;
base::WritableSharedMemoryMapping shared_metrics_mapping_;
mojo::Receiver<mojom::blink::CrashMemoryMetricsReporter> receiver_{this};
};
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 2072995af8c..f32bf44463b 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
@@ -125,7 +125,7 @@ void DevToolsFrontendImpl::DestroyOnHostGone() {
GetSupplementable()->RemoveSupplement<DevToolsFrontendImpl>();
}
-void DevToolsFrontendImpl::Trace(blink::Visitor* visitor) {
+void DevToolsFrontendImpl::Trace(Visitor* visitor) {
visitor->Trace(devtools_host_);
Supplement<LocalFrame>::Trace(visitor);
}
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 ce7c49f2cbb..a5f4f6d4e96 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
@@ -68,7 +68,7 @@ class DevToolsFrontendImpl final
mojo::PendingAssociatedReceiver<mojom::blink::DevToolsFrontend>);
~DevToolsFrontendImpl() override;
void DidClearWindowObject();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void DestroyOnHostGone();
diff --git a/chromium/third_party/blink/renderer/controller/highest_pmf_reporter.cc b/chromium/third_party/blink/renderer/controller/highest_pmf_reporter.cc
index 3223c13d2b6..dce920f0708 100644
--- a/chromium/third_party/blink/renderer/controller/highest_pmf_reporter.cc
+++ b/chromium/third_party/blink/renderer/controller/highest_pmf_reporter.cc
@@ -65,7 +65,10 @@ HighestPmfReporter::HighestPmfReporter(
MemoryUsageMonitor::Instance().AddObserver(this);
}
-bool HighestPmfReporter::HasNavigationAlreadyStarted() const {
+bool HighestPmfReporter::FirstNavigationStarted() {
+ if (first_navigation_detected_)
+ return false;
+
for (Page* page : Page::OrdinaryPages()) {
Frame* frame = page->MainFrame();
if (!frame)
@@ -79,19 +82,17 @@ bool HighestPmfReporter::HasNavigationAlreadyStarted() const {
if (!loader)
continue;
- if (!loader->GetTiming().NavigationStart().is_null())
+ if (!loader->GetTiming().NavigationStart().is_null()) {
+ first_navigation_detected_ = true;
return true;
+ }
}
return false;
}
void HighestPmfReporter::OnMemoryPing(MemoryUsage usage) {
- if (!first_navigation_detected_) {
- if (!HasNavigationAlreadyStarted())
- return;
-
- first_navigation_detected_ = true;
-
+ DCHECK(IsMainThread());
+ if (FirstNavigationStarted()) {
task_runner_->PostDelayedTask(
FROM_HERE,
WTF::Bind(&HighestPmfReporter::OnReportMetrics, WTF::Unretained(this)),
@@ -105,13 +106,18 @@ void HighestPmfReporter::OnMemoryPing(MemoryUsage usage) {
peak_resident_bytes_at_current_highest_pmf_ = usage.peak_resident_bytes;
webpage_counts_at_current_highest_pmf_ = Page::OrdinaryPages().size();
- // TODO(tasak): Need to report the highest private memory footprint
- // while a renderer is alive.
+ // TODO(tasak): Report the highest memory footprint throughout renderer's
+ // lifetime.
}
void HighestPmfReporter::OnReportMetrics() {
+ DCHECK(IsMainThread());
ReportMetrics();
+ // The following code is not accurate, because OnReportMetrics will be late
+ // when renderer is slow (e.g. caused by near-OOM or heavy tasks is running
+ // or ...). However such signal getting late by minutes is unlikely, so it's
+ // ok to say "this is good enough".
current_highest_pmf_ = 0.0;
peak_resident_bytes_at_current_highest_pmf_ = 0.0;
webpage_counts_at_current_highest_pmf_ = 0;
diff --git a/chromium/third_party/blink/renderer/controller/highest_pmf_reporter.h b/chromium/third_party/blink/renderer/controller/highest_pmf_reporter.h
index 36c0063906b..b7b535720ee 100644
--- a/chromium/third_party/blink/renderer/controller/highest_pmf_reporter.h
+++ b/chromium/third_party/blink/renderer/controller/highest_pmf_reporter.h
@@ -41,7 +41,7 @@ class CONTROLLER_EXPORT HighestPmfReporter
void OnReportMetrics();
// Make the following methods virtual for testing.
- virtual bool HasNavigationAlreadyStarted() const;
+ virtual bool FirstNavigationStarted();
virtual void ReportMetrics();
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
diff --git a/chromium/third_party/blink/renderer/controller/highest_pmf_reporter_test.cc b/chromium/third_party/blink/renderer/controller/highest_pmf_reporter_test.cc
index d3d52b2edef..38591f96ff1 100644
--- a/chromium/third_party/blink/renderer/controller/highest_pmf_reporter_test.cc
+++ b/chromium/third_party/blink/renderer/controller/highest_pmf_reporter_test.cc
@@ -21,11 +21,10 @@ class MockHighestPmfReporter : public HighestPmfReporter {
MockHighestPmfReporter(
scoped_refptr<base::TestMockTimeTaskRunner> task_runner_for_testing,
const base::TickClock* clock)
- : HighestPmfReporter(task_runner_for_testing, clock),
- navigation_started_(false) {}
+ : HighestPmfReporter(task_runner_for_testing, clock) {}
~MockHighestPmfReporter() override = default;
- void NotifyNavigationStart() { navigation_started_ = true; }
+ void NotifyNavigationStart() { first_navigation_started_ = true; }
const std::vector<double>& GetReportedHighestPmf() const {
return reported_highest_pmf_;
@@ -48,14 +47,18 @@ class MockHighestPmfReporter : public HighestPmfReporter {
reported_webpage_count_.push_back(webpage_counts_at_current_highest_pmf_);
}
- bool HasNavigationAlreadyStarted() const override {
- return navigation_started_;
+ bool FirstNavigationStarted() override {
+ if (!first_navigation_started_)
+ return false;
+
+ first_navigation_started_ = false;
+ return true;
}
std::vector<double> reported_highest_pmf_;
std::vector<double> reported_peak_rss_;
std::vector<unsigned> reported_webpage_count_;
- bool navigation_started_;
+ bool first_navigation_started_ = false;
};
namespace peak_memory_reporter_test {
diff --git a/chromium/third_party/blink/renderer/controller/memory_usage_monitor.cc b/chromium/third_party/blink/renderer/controller/memory_usage_monitor.cc
index ee61472b1e6..7ed800c74b0 100644
--- a/chromium/third_party/blink/renderer/controller/memory_usage_monitor.cc
+++ b/chromium/third_party/blink/renderer/controller/memory_usage_monitor.cc
@@ -7,6 +7,7 @@
#include "base/test/test_mock_time_task_runner.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
namespace blink {
@@ -16,7 +17,8 @@ constexpr base::TimeDelta kPingInterval = base::TimeDelta::FromSeconds(1);
}
MemoryUsageMonitor::MemoryUsageMonitor() {
- timer_.SetTaskRunner(Thread::MainThread()->GetTaskRunner());
+ timer_.SetTaskRunner(
+ Thread::MainThread()->Scheduler()->NonWakingTaskRunner());
}
MemoryUsageMonitor::MemoryUsageMonitor(
diff --git a/chromium/third_party/blink/renderer/controller/memory_usage_monitor_mac.cc b/chromium/third_party/blink/renderer/controller/memory_usage_monitor_mac.cc
new file mode 100644
index 00000000000..4cfe4638bba
--- /dev/null
+++ b/chromium/third_party/blink/renderer/controller/memory_usage_monitor_mac.cc
@@ -0,0 +1,127 @@
+// 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/controller/memory_usage_monitor_mac.h"
+
+#include <mach/mach.h>
+#include <mach/mach_vm.h>
+
+#include "base/mac/mac_util.h"
+#include "third_party/blink/public/platform/platform.h"
+
+namespace blink {
+
+// The following code is copied from
+// //services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_mac.cc
+// to use task_info API.
+namespace {
+#if !defined(MAC_OS_X_VERSION_10_11) || \
+ MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_11
+// The |phys_footprint| field was introduced in 10.11.
+struct ChromeTaskVMInfo {
+ mach_vm_size_t virtual_size;
+ integer_t region_count;
+ integer_t page_size;
+ mach_vm_size_t resident_size;
+ mach_vm_size_t resident_size_peak;
+ mach_vm_size_t device;
+ mach_vm_size_t device_peak;
+ mach_vm_size_t internal;
+ mach_vm_size_t internal_peak;
+ mach_vm_size_t external;
+ mach_vm_size_t external_peak;
+ mach_vm_size_t reusable;
+ mach_vm_size_t reusable_peak;
+ mach_vm_size_t purgeable_volatile_pmap;
+ mach_vm_size_t purgeable_volatile_resident;
+ mach_vm_size_t purgeable_volatile_virtual;
+ mach_vm_size_t compressed;
+ mach_vm_size_t compressed_peak;
+ mach_vm_size_t compressed_lifetime;
+ mach_vm_size_t phys_footprint;
+};
+#else
+using ChromeTaskVMInfo = task_vm_info;
+#endif // MAC_OS_X_VERSION_10_11
+
+// Don't simply use sizeof(task_vm_info) / sizeof(natural_t):
+// In the 10.15 SDK, this structure is 87 32-bit words long, and in
+// mach_types.defs:
+//
+// type task_info_t = array[*:87] of integer_t;
+//
+// However in the 10.14 SDK, this structure is 42 32-bit words, and in
+// mach_types.defs:
+//
+// type task_info_t = array[*:52] of integer_t;
+//
+// As a result, the 10.15 SDK's task_vm_info won't fit inside the 10.14 SDK's
+// task_info_t, so the *rest of the system* (on 10.14 and earlier) can't handle
+// calls that request the full 10.15 structure. We have to request a prefix of
+// it that 10.14 and earlier can handle by limiting the length we request. The
+// rest of the fields just get ignored, but we don't use them anyway.
+
+constexpr mach_msg_type_number_t ChromeTaskVMInfoCount =
+ TASK_VM_INFO_REV2_COUNT;
+
+// The count field is in units of natural_t, which is the machine's word size
+// (64 bits on all modern machines), but the task_info_t array is in units of
+// integer_t, which is 32 bits.
+constexpr mach_msg_type_number_t MAX_MIG_SIZE_FOR_1014 =
+ 52 / (sizeof(natural_t) / sizeof(integer_t));
+static_assert(ChromeTaskVMInfoCount <= MAX_MIG_SIZE_FOR_1014,
+ "task_vm_info must be small enough for 10.14 MIG interfaces");
+
+static MemoryUsageMonitor* g_instance_for_testing = nullptr;
+
+} // namespace
+
+// static
+MemoryUsageMonitor& MemoryUsageMonitor::Instance() {
+ DEFINE_STATIC_LOCAL(MemoryUsageMonitorMac, monitor, ());
+ return g_instance_for_testing ? *g_instance_for_testing : monitor;
+}
+
+// static
+void MemoryUsageMonitor::SetInstanceForTesting(MemoryUsageMonitor* instance) {
+ g_instance_for_testing = instance;
+}
+
+bool MemoryUsageMonitorMac::CalculateProcessMemoryFootprint(
+ uint64_t* private_footprint) {
+ // The following code is copied from OSMetrics::FillOSMemoryDump defined in
+ // //services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_mac.cc
+ ChromeTaskVMInfo task_vm_info;
+ mach_msg_type_number_t count = ChromeTaskVMInfoCount;
+ kern_return_t result =
+ task_info(mach_task_self(), TASK_VM_INFO,
+ reinterpret_cast<task_info_t>(&task_vm_info), &count);
+ if (result != KERN_SUCCESS)
+ return false;
+
+ uint64_t internal_bytes = task_vm_info.internal;
+ uint64_t compressed_bytes = task_vm_info.compressed;
+ uint64_t phys_footprint_bytes = 0;
+
+ if (count == ChromeTaskVMInfoCount) {
+ phys_footprint_bytes = task_vm_info.phys_footprint;
+ }
+
+ // The following code is copied from CalculatePrivateFootprintKB defined in
+ // //services/resource_coordinator/memory_instrumentation/queued_request_dispatcher.cc
+ if (base::mac::IsAtLeastOS10_12()) {
+ *private_footprint = phys_footprint_bytes;
+ } else {
+ *private_footprint = internal_bytes + compressed_bytes;
+ }
+ return true;
+}
+
+void MemoryUsageMonitorMac::GetProcessMemoryUsage(MemoryUsage& usage) {
+ uint64_t private_footprint;
+ if (CalculateProcessMemoryFootprint(&private_footprint))
+ usage.private_footprint_bytes = static_cast<double>(private_footprint);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/controller/memory_usage_monitor_mac.h b/chromium/third_party/blink/renderer/controller/memory_usage_monitor_mac.h
new file mode 100644
index 00000000000..79b2a2e0de0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/controller/memory_usage_monitor_mac.h
@@ -0,0 +1,25 @@
+// 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_CONTROLLER_MEMORY_USAGE_MONITOR_MAC_H_
+#define THIRD_PARTY_BLINK_RENDERER_CONTROLLER_MEMORY_USAGE_MONITOR_MAC_H_
+
+#include "third_party/blink/renderer/controller/controller_export.h"
+#include "third_party/blink/renderer/controller/memory_usage_monitor.h"
+
+namespace blink {
+
+// MemoryUsageMonitor implementation for Mac platform.
+class CONTROLLER_EXPORT MemoryUsageMonitorMac : public MemoryUsageMonitor {
+ public:
+ MemoryUsageMonitorMac() = default;
+
+ private:
+ void GetProcessMemoryUsage(MemoryUsage&) override;
+ static bool CalculateProcessMemoryFootprint(uint64_t* private_footprint);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CONTROLLER_MEMORY_USAGE_MONITOR_MAC_H_
diff --git a/chromium/third_party/blink/renderer/controller/memory_usage_monitor_android.cc b/chromium/third_party/blink/renderer/controller/memory_usage_monitor_posix.cc
index b32ded504e9..8558d53deeb 100644
--- a/chromium/third_party/blink/renderer/controller/memory_usage_monitor_android.cc
+++ b/chromium/third_party/blink/renderer/controller/memory_usage_monitor_posix.cc
@@ -2,11 +2,12 @@
// 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/controller/memory_usage_monitor_android.h"
+#include "third_party/blink/renderer/controller/memory_usage_monitor_posix.h"
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
+#include <utility>
#include "third_party/blink/public/platform/platform.h"
@@ -25,12 +26,17 @@ bool ReadFileContents(int fd, base::span<char> contents) {
static MemoryUsageMonitor* g_instance_for_testing = nullptr;
+MemoryUsageMonitorPosix& GetMemoryUsageMonitor() {
+ DEFINE_STATIC_LOCAL(MemoryUsageMonitorPosix, monitor, ());
+ return monitor;
+}
+
} // namespace
// static
MemoryUsageMonitor& MemoryUsageMonitor::Instance() {
- DEFINE_STATIC_LOCAL(MemoryUsageMonitorAndroid, monitor, ());
- return g_instance_for_testing ? *g_instance_for_testing : monitor;
+ return g_instance_for_testing ? *g_instance_for_testing
+ : GetMemoryUsageMonitor();
}
// static
@@ -41,7 +47,7 @@ void MemoryUsageMonitor::SetInstanceForTesting(MemoryUsageMonitor* instance) {
// Since the measurement is done every second in background, optimizations are
// in place to get just the metrics we need from the proc files. So, this
// calculation exists here instead of using the cross-process memory-infra code.
-bool MemoryUsageMonitorAndroid::CalculateProcessMemoryFootprint(
+bool MemoryUsageMonitorPosix::CalculateProcessMemoryFootprint(
int statm_fd,
int status_fd,
uint64_t* private_footprint,
@@ -87,9 +93,10 @@ bool MemoryUsageMonitorAndroid::CalculateProcessMemoryFootprint(
return true;
}
-void MemoryUsageMonitorAndroid::GetProcessMemoryUsage(MemoryUsage& usage) {
+void MemoryUsageMonitorPosix::GetProcessMemoryUsage(MemoryUsage& usage) {
+#if defined(OS_ANDROID)
ResetFileDescriptors();
-
+#endif
if (!statm_fd_.is_valid() || !status_fd_.is_valid())
return;
uint64_t private_footprint, swap, vm_size, vm_hwm_size;
@@ -103,7 +110,8 @@ void MemoryUsageMonitorAndroid::GetProcessMemoryUsage(MemoryUsage& usage) {
}
}
-void MemoryUsageMonitorAndroid::ResetFileDescriptors() {
+#if defined(OS_ANDROID)
+void MemoryUsageMonitorPosix::ResetFileDescriptors() {
if (file_descriptors_reset_)
return;
file_descriptors_reset_ = true;
@@ -114,12 +122,26 @@ void MemoryUsageMonitorAndroid::ResetFileDescriptors() {
if (!status_fd_.is_valid())
status_fd_.reset(open("/proc/self/status", O_RDONLY));
}
-
-void MemoryUsageMonitorAndroid::ReplaceFileDescriptorsForTesting(
- base::File statm_file,
- base::File status_file) {
+#endif
+
+void MemoryUsageMonitorPosix::SetProcFiles(base::File statm_file,
+ base::File status_file) {
+ DCHECK(statm_file.IsValid());
+ DCHECK(status_file.IsValid());
+ DCHECK_EQ(-1, statm_fd_.get());
+ DCHECK_EQ(-1, status_fd_.get());
statm_fd_.reset(statm_file.TakePlatformFile());
status_fd_.reset(status_file.TakePlatformFile());
}
+#if defined(OS_LINUX)
+// static
+void MemoryUsageMonitorPosix::Bind(
+ mojo::PendingReceiver<mojom::blink::MemoryUsageMonitorLinux> receiver) {
+ // This should be called only once per process on RenderProcessWillLaunch.
+ DCHECK(!GetMemoryUsageMonitor().receiver_.is_bound());
+ GetMemoryUsageMonitor().receiver_.Bind(std::move(receiver));
+}
+#endif
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/controller/memory_usage_monitor_android.h b/chromium/third_party/blink/renderer/controller/memory_usage_monitor_posix.h
index 417577f77b1..29527098d69 100644
--- a/chromium/third_party/blink/renderer/controller/memory_usage_monitor_android.h
+++ b/chromium/third_party/blink/renderer/controller/memory_usage_monitor_posix.h
@@ -2,26 +2,43 @@
// 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_CONTROLLER_MEMORY_USAGE_MONITOR_ANDROID_H_
-#define THIRD_PARTY_BLINK_RENDERER_CONTROLLER_MEMORY_USAGE_MONITOR_ANDROID_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CONTROLLER_MEMORY_USAGE_MONITOR_POSIX_H_
+#define THIRD_PARTY_BLINK_RENDERER_CONTROLLER_MEMORY_USAGE_MONITOR_POSIX_H_
#include "base/files/file.h"
#include "base/files/scoped_file.h"
+#include "build/build_config.h"
+#include "mojo/public/cpp/bindings/receiver.h"
#include "third_party/blink/renderer/controller/controller_export.h"
#include "third_party/blink/renderer/controller/memory_usage_monitor.h"
+#if defined(OS_LINUX)
+#include "third_party/blink/public/mojom/memory_usage_monitor_linux.mojom-blink.h"
+#endif
+
namespace blink {
-class CONTROLLER_EXPORT MemoryUsageMonitorAndroid : public MemoryUsageMonitor {
+// MemoryUsageMonitor implementation for Android and Linux.
+class CONTROLLER_EXPORT MemoryUsageMonitorPosix
+ : public MemoryUsageMonitor
+#if defined(OS_LINUX)
+ ,
+ public mojom::blink::MemoryUsageMonitorLinux
+#endif
+{
public:
- MemoryUsageMonitorAndroid() = default;
+ MemoryUsageMonitorPosix() = default;
- void ReplaceFileDescriptorsForTesting(base::File statm_file,
- base::File status_file);
+#if defined(OS_LINUX)
+ static void Bind(
+ mojo::PendingReceiver<mojom::blink::MemoryUsageMonitorLinux> receiver);
+#endif
private:
+ FRIEND_TEST_ALL_PREFIXES(MemoryUsageMonitorPosixTest,
+ CalculateProcessFootprint);
+
friend class CrashMemoryMetricsReporterImpl;
- void ResetFileDescriptors();
void GetProcessMemoryUsage(MemoryUsage&) override;
static bool CalculateProcessMemoryFootprint(int statm_fd,
int status_fd,
@@ -30,13 +47,29 @@ class CONTROLLER_EXPORT MemoryUsageMonitorAndroid : public MemoryUsageMonitor {
uint64_t* vm_size,
uint64_t* vm_hwm_size);
+#if defined(OS_LINUX)
+ // mojom::MemoryUsageMonitorLinux implementations:
+ void SetProcFiles(base::File statm_file, base::File status_file) override;
+#endif
+
+#if defined(OS_ANDROID)
+ void ResetFileDescriptors();
+ // For Android, SetProcFiles is used only for testing.
+ void SetProcFiles(base::File statm_file, base::File status_file);
+
bool file_descriptors_reset_ = false;
+#endif
+
// The file descriptor to current process proc files. The files are kept open
- // when detection is on to reduce measurement overhead.
+ // for the whole lifetime of the renderer.
base::ScopedFD statm_fd_;
base::ScopedFD status_fd_;
+
+#if defined(OS_LINUX)
+ mojo::Receiver<mojom::blink::MemoryUsageMonitorLinux> receiver_{this};
+#endif
};
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_CONTROLLER_MEMORY_USAGE_MONITOR_ANDROID_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CONTROLLER_MEMORY_USAGE_MONITOR_POSIX_H_
diff --git a/chromium/third_party/blink/renderer/controller/memory_usage_monitor_android_test.cc b/chromium/third_party/blink/renderer/controller/memory_usage_monitor_posix_test.cc
index ebf0a75d63c..63916234d9b 100644
--- a/chromium/third_party/blink/renderer/controller/memory_usage_monitor_android_test.cc
+++ b/chromium/third_party/blink/renderer/controller/memory_usage_monitor_posix_test.cc
@@ -2,17 +2,19 @@
// 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/controller/memory_usage_monitor_android.h"
+#include "third_party/blink/renderer/controller/memory_usage_monitor_posix.h"
#include <unistd.h>
+#include <utility>
#include "base/files/file_util.h"
+#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace blink {
-TEST(MemoryUsageMonitorAndroidTest, CalculateProcessFootprint) {
- MemoryUsageMonitorAndroid monitor;
+TEST(MemoryUsageMonitorPosixTest, CalculateProcessFootprint) {
+ MemoryUsageMonitorPosix monitor;
const char kStatusFile[] =
"First: 1\n"
@@ -41,8 +43,7 @@ TEST(MemoryUsageMonitorAndroidTest, CalculateProcessFootprint) {
base::File status_file(status_path,
base::File::FLAG_OPEN | base::File::FLAG_READ);
- monitor.ReplaceFileDescriptorsForTesting(std::move(statm_file),
- std::move(status_file));
+ monitor.SetProcFiles(std::move(statm_file), std::move(status_file));
MemoryUsage usage = monitor.GetCurrentMemoryUsage();
EXPECT_EQ(expected_private_footprint_kb,
diff --git a/chromium/third_party/blink/renderer/controller/memory_usage_monitor_win.cc b/chromium/third_party/blink/renderer/controller/memory_usage_monitor_win.cc
new file mode 100644
index 00000000000..fdd640c9f9c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/controller/memory_usage_monitor_win.cc
@@ -0,0 +1,55 @@
+// 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/controller/memory_usage_monitor_win.h"
+
+#include <windows.h> // Must be in front of other Windows header files.
+
+#include <psapi.h>
+#include <tchar.h>
+
+#include "third_party/blink/public/platform/platform.h"
+
+namespace blink {
+
+namespace {
+
+static MemoryUsageMonitor* g_instance_for_testing = nullptr;
+
+} // namespace
+
+// static
+MemoryUsageMonitor& MemoryUsageMonitor::Instance() {
+ DEFINE_STATIC_LOCAL(MemoryUsageMonitorWin, monitor, ());
+ return g_instance_for_testing ? *g_instance_for_testing : monitor;
+}
+
+// static
+void MemoryUsageMonitor::SetInstanceForTesting(MemoryUsageMonitor* instance) {
+ g_instance_for_testing = instance;
+}
+
+// CalculateProcessMemoryFootprint is generated from:
+// - CalculatePrivateFootprintKb defined in
+// //services/resource_coordinator/memory_instrumentation/queued_request_dispatcher.cc
+// - OSMetrics::FillOSMemoryDump defined in
+// //services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_win.cc
+bool MemoryUsageMonitorWin::CalculateProcessMemoryFootprint(
+ uint64_t* private_footprint) {
+ PROCESS_MEMORY_COUNTERS_EX pmc;
+ if (!::GetProcessMemoryInfo(::GetCurrentProcess(),
+ reinterpret_cast<PROCESS_MEMORY_COUNTERS*>(&pmc),
+ sizeof(pmc)))
+ return false;
+ *private_footprint = pmc.PrivateUsage;
+ return true;
+}
+
+void MemoryUsageMonitorWin::GetProcessMemoryUsage(MemoryUsage& usage) {
+ uint64_t private_footprint;
+ if (CalculateProcessMemoryFootprint(&private_footprint))
+ usage.private_footprint_bytes = static_cast<double>(private_footprint);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/controller/memory_usage_monitor_win.h b/chromium/third_party/blink/renderer/controller/memory_usage_monitor_win.h
new file mode 100644
index 00000000000..f83a5f997af
--- /dev/null
+++ b/chromium/third_party/blink/renderer/controller/memory_usage_monitor_win.h
@@ -0,0 +1,25 @@
+// 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_CONTROLLER_MEMORY_USAGE_MONITOR_WIN_H_
+#define THIRD_PARTY_BLINK_RENDERER_CONTROLLER_MEMORY_USAGE_MONITOR_WIN_H_
+
+#include "third_party/blink/renderer/controller/controller_export.h"
+#include "third_party/blink/renderer/controller/memory_usage_monitor.h"
+
+namespace blink {
+
+// Memory usage monitor implementation for Windows.
+class CONTROLLER_EXPORT MemoryUsageMonitorWin : public MemoryUsageMonitor {
+ public:
+ MemoryUsageMonitorWin() = default;
+
+ private:
+ void GetProcessMemoryUsage(MemoryUsage&) override;
+ static bool CalculateProcessMemoryFootprint(uint64_t* private_footprint);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CONTROLLER_MEMORY_USAGE_MONITOR_WIN_H_
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 20cd0976c44..7fc38dd1f29 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
@@ -12,7 +12,6 @@
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/oom_intervention/oom_intervention_types.h"
#include "third_party/blink/renderer/controller/crash_memory_metrics_reporter_impl.h"
@@ -264,13 +263,9 @@ TEST_F(OomInterventionImplTest, V1DetectionAdsNavigation) {
WebViewImpl* web_view = web_view_helper_.InitializeAndLoad("about:blank");
Page* page = web_view->MainFrameImpl()->GetFrame()->GetPage();
- web_view->MainFrameImpl()
- ->GetFrame()
- ->GetDocument()
- ->body()
- ->SetInnerHTMLFromString(
- "<iframe name='ad' src='data:text/html,'></iframe><iframe "
- "name='non-ad' src='data:text/html,'>");
+ web_view->MainFrameImpl()->GetFrame()->GetDocument()->body()->setInnerHTML(
+ "<iframe name='ad' src='data:text/html,'></iframe><iframe "
+ "name='non-ad' src='data:text/html,'>");
WebFrame* ad_iframe = web_view_helper_.LocalMainFrame()->FindFrameByName(
WebString::FromUTF8("ad"));
@@ -319,9 +314,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()->ExecutionContext::IsContextDestroyed());
+ EXPECT_FALSE(frame->GetDocument()->IsContextDestroyed());
RunDetection(true, true, true);
- EXPECT_TRUE(frame->GetDocument()->ExecutionContext::IsContextDestroyed());
+ EXPECT_TRUE(frame->GetDocument()->IsContextDestroyed());
}
TEST_F(OomInterventionImplTest, ReducedMemoryMetricReporting) {
diff --git a/chromium/third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator.cc b/chromium/third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator.cc
index c9709678931..7053b7bfa00 100644
--- a/chromium/third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator.cc
+++ b/chromium/third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator.cc
@@ -23,32 +23,68 @@ namespace {
constexpr double kDefaultMemoryThresholdMB =
std::numeric_limits<double>::infinity();
-constexpr base::FeatureParam<double> k512MBDeviceMemoryThresholdParam{
- &blink::features::kUserLevelMemoryPressureSignal,
- "param_512mb_device_memory_threshold_mb", kDefaultMemoryThresholdMB};
+double MemoryThresholdParamOf512MbDevices() {
+ static const base::FeatureParam<double> k512MBDeviceMemoryThresholdParam{
+ &blink::features::kUserLevelMemoryPressureSignal,
+ "param_512mb_device_memory_threshold_mb", kDefaultMemoryThresholdMB};
+ return k512MBDeviceMemoryThresholdParam.Get();
+}
-constexpr base::FeatureParam<double> k1GBDeviceMemoryThresholdParam{
- &blink::features::kUserLevelMemoryPressureSignal,
- "param_1gb_device_memory_threshold_mb", kDefaultMemoryThresholdMB};
+double MemoryThresholdParamOf1GbDevices() {
+ static const base::FeatureParam<double> k1GBDeviceMemoryThresholdParam{
+ &blink::features::kUserLevelMemoryPressureSignal,
+ "param_1gb_device_memory_threshold_mb", kDefaultMemoryThresholdMB};
+ return k1GBDeviceMemoryThresholdParam.Get();
+}
-constexpr base::FeatureParam<double> k2GBDeviceMemoryThresholdParam{
- &blink::features::kUserLevelMemoryPressureSignal,
- "param_2gb_device_memory_threshold_mb", kDefaultMemoryThresholdMB};
+double MemoryThresholdParamOf2GbDevices() {
+ static const base::FeatureParam<double> k2GBDeviceMemoryThresholdParam{
+ &blink::features::kUserLevelMemoryPressureSignal,
+ "param_2gb_device_memory_threshold_mb", kDefaultMemoryThresholdMB};
+ return k2GBDeviceMemoryThresholdParam.Get();
+}
-constexpr base::FeatureParam<double> k3GBDeviceMemoryThresholdParam{
- &blink::features::kUserLevelMemoryPressureSignal,
- "param_3gb_device_memory_threshold_mb", kDefaultMemoryThresholdMB};
+double MemoryThresholdParamOf3GbDevices() {
+ static const base::FeatureParam<double> k3GBDeviceMemoryThresholdParam{
+ &blink::features::kUserLevelMemoryPressureSignal,
+ "param_3gb_device_memory_threshold_mb", kDefaultMemoryThresholdMB};
+ return k3GBDeviceMemoryThresholdParam.Get();
+}
-constexpr base::FeatureParam<double> k4GBDeviceMemoryThresholdParam{
- &blink::features::kUserLevelMemoryPressureSignal,
- "param_4gb_device_memory_threshold_mb", kDefaultMemoryThresholdMB};
+double MemoryThresholdParamOf4GbDevices() {
+ static const base::FeatureParam<double> k4GBDeviceMemoryThresholdParam{
+ &blink::features::kUserLevelMemoryPressureSignal,
+ "param_4gb_device_memory_threshold_mb", kDefaultMemoryThresholdMB};
+ return k4GBDeviceMemoryThresholdParam.Get();
+}
-// Minimum time interval between generated memory pressure signals.
constexpr double kDefaultMinimumIntervalSeconds = 10 * 60;
-constexpr base::FeatureParam<double> kMinimumIntervalSeconds{
- &blink::features::kUserLevelMemoryPressureSignal, "minimum_interval_s",
- kDefaultMinimumIntervalSeconds};
+// Minimum time interval between generated memory pressure signals.
+base::TimeDelta MinimumIntervalSeconds() {
+ static const base::FeatureParam<double> kMinimumIntervalSeconds{
+ &blink::features::kUserLevelMemoryPressureSignal, "minimum_interval_s",
+ kDefaultMinimumIntervalSeconds};
+ return base::TimeDelta::FromSeconds(kMinimumIntervalSeconds.Get());
+}
+
+double MemoryThresholdParam() {
+ int64_t physical_memory = base::SysInfo::AmountOfPhysicalMemory();
+ double memory_threshold_mb = kDefaultMemoryThresholdMB;
+
+ if (physical_memory > 3.1 * 1024 * 1024 * 1024)
+ memory_threshold_mb = MemoryThresholdParamOf4GbDevices();
+ else if (physical_memory > 2.1 * 1024 * 1024 * 1024)
+ memory_threshold_mb = MemoryThresholdParamOf3GbDevices();
+ else if (physical_memory > 1.1 * 1024 * 1024 * 1024)
+ memory_threshold_mb = MemoryThresholdParamOf2GbDevices();
+ else if (physical_memory > 600 * 1024 * 1024)
+ memory_threshold_mb = MemoryThresholdParamOf1GbDevices();
+ else
+ memory_threshold_mb = MemoryThresholdParamOf512MbDevices();
+
+ return memory_threshold_mb;
+}
} // namespace
@@ -59,37 +95,31 @@ UserLevelMemoryPressureSignalGenerator::Instance() {
return generator;
}
+// static
+bool UserLevelMemoryPressureSignalGenerator::Enabled() {
+ if (!base::FeatureList::IsEnabled(
+ blink::features::kUserLevelMemoryPressureSignal))
+ return false;
+
+ // Can be disabled for certain device classes by setting the field param to an
+ // empty string.
+ return !std::isinf(MemoryThresholdParam());
+}
+
UserLevelMemoryPressureSignalGenerator::UserLevelMemoryPressureSignalGenerator()
- : delayed_report_timer_(
+ : memory_threshold_mb_(MemoryThresholdParam()),
+ minimum_interval_(MinimumIntervalSeconds()),
+ delayed_report_timer_(
Thread::MainThread()->GetTaskRunner(),
this,
&UserLevelMemoryPressureSignalGenerator::OnTimerFired),
clock_(base::DefaultTickClock::GetInstance()) {
- int64_t physical_memory = base::SysInfo::AmountOfPhysicalMemory();
- if (physical_memory > 3.1 * 1024 * 1024 * 1024)
- memory_threshold_mb_ = k4GBDeviceMemoryThresholdParam.Get();
- else if (physical_memory > 2.1 * 1024 * 1024 * 1024)
- memory_threshold_mb_ = k3GBDeviceMemoryThresholdParam.Get();
- else if (physical_memory > 1.1 * 1024 * 1024 * 1024)
- memory_threshold_mb_ = k2GBDeviceMemoryThresholdParam.Get();
- else if (physical_memory > 600 * 1024 * 1024)
- memory_threshold_mb_ = k1GBDeviceMemoryThresholdParam.Get();
- else
- memory_threshold_mb_ = k512MBDeviceMemoryThresholdParam.Get();
-
- minimum_interval_ =
- base::TimeDelta::FromSeconds(kMinimumIntervalSeconds.Get());
+ DCHECK(base::FeatureList::IsEnabled(
+ blink::features::kUserLevelMemoryPressureSignal));
+ DCHECK(!std::isinf(memory_threshold_mb_));
- // Can be disabled for certain device classes by setting the field param to an
- // empty string.
- bool enabled = base::FeatureList::IsEnabled(
- blink::features::kUserLevelMemoryPressureSignal) &&
- !std::isinf(memory_threshold_mb_);
- if (enabled) {
- monitoring_ = true;
- MemoryUsageMonitor::Instance().AddObserver(this);
- ThreadScheduler::Current()->AddRAILModeObserver(this);
- }
+ MemoryUsageMonitor::Instance().AddObserver(this);
+ ThreadScheduler::Current()->AddRAILModeObserver(this);
}
UserLevelMemoryPressureSignalGenerator::
@@ -116,7 +146,7 @@ void UserLevelMemoryPressureSignalGenerator::OnMemoryPing(MemoryUsage usage) {
if (usage.private_footprint_bytes / 1024 / 1024 < memory_threshold_mb_)
return;
base::TimeDelta elapsed = clock_->NowTicks() - last_generated_;
- if (elapsed >= base::TimeDelta::FromSeconds(kMinimumIntervalSeconds.Get()))
+ if (elapsed >= MinimumIntervalSeconds())
Generate(usage);
}
diff --git a/chromium/third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator.h b/chromium/third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator.h
index 1720fc18be9..3bd01768cf0 100644
--- a/chromium/third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator.h
+++ b/chromium/third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator.h
@@ -31,6 +31,7 @@ class CONTROLLER_EXPORT UserLevelMemoryPressureSignalGenerator
public:
// Returns the shared instance.
static UserLevelMemoryPressureSignalGenerator& Instance();
+ static bool Enabled();
UserLevelMemoryPressureSignalGenerator();
~UserLevelMemoryPressureSignalGenerator() override;
@@ -55,7 +56,6 @@ class CONTROLLER_EXPORT UserLevelMemoryPressureSignalGenerator
// MemoryUsageMonitor::Observer:
void OnMemoryPing(MemoryUsage) override;
- bool monitoring_ = false;
bool is_loading_ = false;
base::TimeTicks last_generated_;
double memory_threshold_mb_;
diff --git a/chromium/third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator_test.cc b/chromium/third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator_test.cc
index c8fb8e36fbe..3041ff6512d 100644
--- a/chromium/third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator_test.cc
+++ b/chromium/third_party/blink/renderer/controller/user_level_memory_pressure_signal_generator_test.cc
@@ -6,6 +6,7 @@
#include "base/test/scoped_feature_list.h"
#include "base/test/test_mock_time_task_runner.h"
+#include "build/build_config.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
@@ -90,7 +91,14 @@ class UserLevelMemoryPressureSignalGeneratorTest : public testing::Test {
constexpr double kMemoryThresholdBytes = 1024 * 1024 * 1024;
-TEST_F(UserLevelMemoryPressureSignalGeneratorTest, GeneratesWhenOverThreshold) {
+// Flaky on Android, see crbug/1054788.
+#if defined(OS_ANDROID)
+#define MAYBE_GeneratesWhenOverThreshold DISABLED_GeneratesWhenOverThreshold
+#else
+#define MAYBE_GeneratesWhenOverThreshold GeneratesWhenOverThreshold
+#endif
+TEST_F(UserLevelMemoryPressureSignalGeneratorTest,
+ MAYBE_GeneratesWhenOverThreshold) {
{
std::unique_ptr<MockMemoryUsageMonitor> mock_memory_usage_monitor =
std::make_unique<MockMemoryUsageMonitor>();
@@ -98,6 +106,8 @@ TEST_F(UserLevelMemoryPressureSignalGeneratorTest, GeneratesWhenOverThreshold) {
mock_memory_usage_monitor.get());
MockUserLevelMemoryPressureSignalGenerator generator;
generator.SetTickClockForTesting(test_task_runner_->GetMockTickClock());
+ // Ensure we are not loading as no signals are sent during a loading phase.
+ generator.OnRAILModeChanged(RAILMode::kAnimation);
{
EXPECT_CALL(generator, Generate(_)).Times(0);
MemoryUsage usage;
@@ -127,7 +137,13 @@ TEST_F(UserLevelMemoryPressureSignalGeneratorTest, GeneratesWhenOverThreshold) {
}
}
-TEST_F(UserLevelMemoryPressureSignalGeneratorTest, GenerationPauses) {
+// Flaky on Android, see crbug/1058178.
+#if defined(OS_ANDROID)
+#define MAYBE_GenerationPauses DISABLED_GenerationPauses
+#else
+#define MAYBE_GenerationPauses GenerationPauses
+#endif
+TEST_F(UserLevelMemoryPressureSignalGeneratorTest, MAYBE_GenerationPauses) {
{
std::unique_ptr<MockMemoryUsageMonitor> mock_memory_usage_monitor =
std::make_unique<MockMemoryUsageMonitor>();
@@ -135,6 +151,8 @@ TEST_F(UserLevelMemoryPressureSignalGeneratorTest, GenerationPauses) {
mock_memory_usage_monitor.get());
MockUserLevelMemoryPressureSignalGenerator generator;
generator.SetTickClockForTesting(test_task_runner_->GetMockTickClock());
+ // Ensure we are not loading as no signals are sent during a loading phase.
+ generator.OnRAILModeChanged(RAILMode::kAnimation);
{
MemoryUsage usage;
usage.v8_bytes = 0;
diff --git a/chromium/third_party/blink/renderer/core/BUILD.gn b/chromium/third_party/blink/renderer/core/BUILD.gn
index 1c2e3e6e287..e9ef6e2aca7 100644
--- a/chromium/third_party/blink/renderer/core/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/BUILD.gn
@@ -73,6 +73,7 @@ source_set("generated") {
"//skia",
"//third_party/blink/renderer/bindings/core/v8:bindings_core_origin_trial_features",
"//third_party/blink/renderer/bindings/core/v8:bindings_core_v8_generated",
+ "//third_party/blink/renderer/bindings/core/v8:generated",
"//third_party/blink/renderer/core/inspector:generated",
"//third_party/blink/renderer/core/probe:generated",
"//third_party/iccjpeg",
@@ -94,6 +95,7 @@ source_set("generated") {
source_set("prerequisites") {
public_deps = [
"//services/network/public/cpp:cpp",
+ "//services/network/public/mojom",
"//services/service_manager/public/cpp",
"//skia",
"//third_party/angle:translator",
@@ -111,6 +113,7 @@ source_set("prerequisites") {
"//third_party/ots",
"//third_party/snappy",
"//third_party/zlib",
+ "//ui/base:features",
"//ui/base/ime/mojom",
"//ui/display/mojom:mojom_blink",
"//ui/events:dom_keycode_converter",
@@ -215,23 +218,12 @@ component("core") {
"//v8",
]
deps = [
+ "//components/paint_preview/common",
"//third_party/blink/public/common",
"//third_party/blink/renderer/platform",
"//third_party/blink/renderer/platform/wtf",
]
- if (is_win && is_debug && is_component_build && current_cpu == "x64") {
- # Incremental linking fails when the .ilk file gets too large.
- # 64-bit debug builds with full symbols trigger this problem, so we turn
- # off incremental linking in that configuration.
- # For fastest builds, use component release builds without debug
- # information.
- # VC++ bug filed for 64-bit debug incremental link failures:
- # https://connect.microsoft.com/VisualStudio/feedback/details/2846790
- configs -= [ "//build/config/win:default_incremental_linking" ]
- configs += [ "//build/config/win:no_incremental_linking" ]
- }
-
public_configs = [ ":core_include_dirs" ]
if (is_mac) {
@@ -255,6 +247,8 @@ jumbo_source_set("testing") {
":core",
":generated_testing_idls",
"//third_party/blink/renderer/bindings/core/v8:testing",
+ "//ui/base/cursor",
+ "//ui/base/mojom:cursor_type_blink",
]
sources = [
@@ -293,6 +287,8 @@ jumbo_source_set("testing") {
"testing/internal_settings.h",
"testing/internals.cc",
"testing/internals.h",
+ "testing/mock_clipboard_host.cc",
+ "testing/mock_clipboard_host.h",
"testing/mock_hyphenation.cc",
"testing/mock_hyphenation.h",
"testing/null_execution_context.cc",
@@ -319,19 +315,6 @@ jumbo_source_set("testing") {
"timing/internals_profiler.cc",
"timing/internals_profiler.h",
]
-
- # Compile the sources produced by these IDL file lists.
- testing_idl_files =
- webcore_testing_idl_files + core_testing_dictionary_idl_files +
- generated_webcore_testing_idl_files +
- webcore_testing_idl_with_modules_dependency_files
-
- sources += process_file_template(
- testing_idl_files,
- [
- "$bindings_core_v8_output_dir/v8_{{source_name_part}}.cc",
- "$bindings_core_v8_output_dir/v8_{{source_name_part}}.h",
- ])
}
# core_bindings_generated ------------------------------------------------------
@@ -374,6 +357,7 @@ generate_event_interfaces("core_event_interfaces") {
"events/ui_event.idl",
"events/wheel_event.idl",
"html/forms/form_data_event.idl",
+ "html/forms/submit_event.idl",
"html/track/track_event.idl",
"invisible_dom/activate_invisible_event.idl",
"mojo/test/mojo_interface_request_event.idl",
@@ -400,9 +384,7 @@ blink_python_runner("generated_settings_macros") {
"../build/scripts/templates/settings_macros.h.tmpl",
"frame/settings.json5",
]
- outputs = [
- "$blink_core_output_dir/settings_macros.h",
- ]
+ outputs = [ "$blink_core_output_dir/settings_macros.h" ]
args = [
rebase_path("frame/settings.json5", root_build_dir),
@@ -461,9 +443,7 @@ css_properties("make_core_generated_computed_style_initial_values") {
script = "../build/scripts/core/style/make_computed_style_initial_values.py"
in_files = [ "style/computed_style_extra_fields.json5" ]
other_inputs = [ "../build/scripts/core/style/templates/computed_style_initial_values.h.tmpl" ]
- outputs = [
- "$blink_core_output_dir/style/computed_style_initial_values.h",
- ]
+ outputs = [ "$blink_core_output_dir/style/computed_style_initial_values.h" ]
}
css_properties("make_core_generated_computed_style_base") {
@@ -503,9 +483,7 @@ css_properties("make_core_generated_css_value_id_mappings") {
"../build/scripts/core/css/templates/css_value_id_mappings_generated.h.tmpl",
"../build/scripts/keyword_utils.py",
]
- outputs = [
- "$blink_core_output_dir/css/css_value_id_mappings_generated.h",
- ]
+ outputs = [ "$blink_core_output_dir/css/css_value_id_mappings_generated.h" ]
}
css_properties("make_core_generated_css_property_instances") {
@@ -525,7 +503,6 @@ css_properties("make_core_generated_css_subclasses") {
"../build/scripts/core/css/properties/make_css_property_subclasses.py"
in_files = [ "css/properties/css_property_methods.json5" ]
other_inputs = [
- "css/css_properties.json5",
"../build/scripts/core/css/properties/templates/css_properties.h.tmpl",
"../build/scripts/core/css/properties/templates/css_properties.cc.tmpl",
]
@@ -574,9 +551,7 @@ code_generator("make_core_generated_media_features") {
other_inputs =
scripts_for_json5_files + [ "../build/scripts/media_feature_symbol.py" ]
templates = [ "../build/scripts/core/css/templates/media_features.h.tmpl" ]
- outputs = [
- "$blink_core_output_dir/css/media_features.h",
- ]
+ outputs = [ "$blink_core_output_dir/css/media_features.h" ]
}
css_properties("make_core_generated_style_property_shorthand") {
@@ -700,9 +675,7 @@ process_json5_files("make_core_generated_svg_element_type_helpers") {
in_files = [ "svg/svg_tag_names.json5" ]
other_inputs = make_element_type_helpers_files
- outputs = [
- "$blink_core_output_dir/svg_element_type_helpers.h",
- ]
+ outputs = [ "$blink_core_output_dir/svg_element_type_helpers.h" ]
}
# make_event_factory -----------------------------------------------------------
@@ -712,9 +685,7 @@ make_event_factory("make_core_generated_event_factory") {
"$blink_core_output_dir/event_interface_names.json5",
"events/event_interface_aliases.json5",
]
- outputs = [
- "$blink_core_output_dir/event_factory.cc",
- ]
+ outputs = [ "$blink_core_output_dir/event_factory.cc" ]
}
# make_names -------------------------------------------------------------------
@@ -807,12 +778,8 @@ action("make_core_generated_html_entity_table") {
visibility = [ ":*" ]
script = "../build/scripts/make_html_entity_table.py"
- inputs = [
- "html/parser/html_entity_names.csv",
- ]
- outputs = [
- "$blink_core_output_dir/html_entity_table.cc",
- ]
+ inputs = [ "html/parser/html_entity_names.csv" ]
+ outputs = [ "$blink_core_output_dir/html_entity_table.cc" ]
args = [ "-o" ] + rebase_path(outputs, root_build_dir)
args += rebase_path(inputs, root_build_dir)
@@ -825,9 +792,7 @@ blink_python_runner("make_core_generated_css_tokenizer_codepoints") {
visibility = [ ":*" ]
script = "../build/scripts/core/css/make_css_tokenizer_codepoints.py"
- outputs = [
- "$blink_core_output_dir/css/css_tokenizer_codepoints.cc",
- ]
+ outputs = [ "$blink_core_output_dir/css/css_tokenizer_codepoints.cc" ]
args = [
"--output_dir",
@@ -847,9 +812,7 @@ blink_python_runner("make_core_generated_css_primitive_value_unit_trie") {
input_file,
"../build/scripts/core/css/templates/css_primitive_value_unit_trie.cc.tmpl",
]
- outputs = [
- "$blink_core_output_dir/css/css_primitive_value_unit_trie.cc",
- ]
+ outputs = [ "$blink_core_output_dir/css/css_primitive_value_unit_trie.cc" ]
args = [
rebase_path(input_file, root_build_dir),
@@ -866,17 +829,18 @@ blink_python_runner("make_core_generated_feature_policy_helper") {
inputs = scripts_for_json5_files + [
"../build/scripts/make_feature_policy_helper.py",
"./feature_policy/feature_policy_features.json5",
+ "./feature_policy/document_policy_features.json5",
"../platform/runtime_enabled_features.json5",
"../build/scripts/templates/feature_policy_helper.cc.tmpl",
]
- outputs = [
- "$blink_core_output_dir/feature_policy/feature_policy_helper.cc",
- ]
+ outputs = [ "$blink_core_output_dir/feature_policy/feature_policy_helper.cc" ]
args = [
rebase_path("../platform/runtime_enabled_features.json5", root_build_dir),
rebase_path("./feature_policy/feature_policy_features.json5",
root_build_dir),
+ rebase_path("./feature_policy/document_policy_features.json5",
+ root_build_dir),
"--output_dir",
"$rel_blink_core_gen_dir/feature_policy",
]
@@ -915,9 +879,7 @@ blink_python_runner("make_core_generated_origin_trials") {
"../platform/runtime_enabled_features.json5",
"../build/scripts/templates/origin_trials.cc.tmpl",
]
- outputs = [
- "$blink_core_output_dir/origin_trials/origin_trials.cc",
- ]
+ outputs = [ "$blink_core_output_dir/origin_trials/origin_trials.cc" ]
args = [
rebase_path("../platform/runtime_enabled_features.json5", root_build_dir),
@@ -933,9 +895,7 @@ blink_python_runner("make_core_generated_web_origin_trials") {
"../platform/runtime_enabled_features.json5",
"../build/scripts/templates/web_origin_trials.cc.tmpl",
]
- outputs = [
- "$blink_core_output_dir/exported/web_origin_trials.cc",
- ]
+ outputs = [ "$blink_core_output_dir/exported/web_origin_trials.cc" ]
args = [
rebase_path("../platform/runtime_enabled_features.json5", root_build_dir),
@@ -944,37 +904,19 @@ blink_python_runner("make_core_generated_web_origin_trials") {
]
}
-action_foreach("make_core_generated_bison") {
- script = "../build/scripts/rule_bison.py"
- sources = [
- "xml/xpath_grammar.y",
- ]
- outputs = [
- "$blink_core_output_dir/{{source_name_part}}.cc",
- "$blink_core_output_dir/{{source_name_part}}.h",
- ]
- args = [
- "{{source}}",
- rel_blink_core_gen_dir,
- bison_exe,
- ]
-
- deps = make_core_generated_deps
-}
-
# Targets from above that generate outputs that need to be compiled.
# All sources declared as outputs from these targets will be compiled into one
# target.
targets_generating_sources = [
":make_core_generated_atrule_names",
- ":make_core_generated_bison",
- ":make_core_generated_css_primitive_value_unit_trie",
- ":make_core_generated_computed_style_initial_values",
":make_core_generated_computed_style_base",
- ":make_core_generated_css_subclasses",
- ":make_core_generated_css_property_names",
+ ":make_core_generated_computed_style_initial_values",
+ ":make_core_generated_css_primitive_value_unit_trie",
":make_core_generated_css_property_instances",
+ ":make_core_generated_css_property_names",
+ ":make_core_generated_css_subclasses",
":make_core_generated_css_value_id_mappings",
+ ":make_core_generated_css_value_keywords",
":make_core_generated_cssom_types",
":make_core_generated_event_factory",
":make_core_generated_event_names",
@@ -983,26 +925,25 @@ targets_generating_sources = [
":make_core_generated_feature_policy_helper",
":make_core_generated_html_element_factory",
":make_core_generated_html_element_lookup_trie",
+ ":make_core_generated_html_element_type_helpers",
":make_core_generated_html_entity_table",
":make_core_generated_html_tokenizer_names",
":make_core_generated_input_type_names",
":make_core_generated_keywords",
- ":make_core_generated_mathml_names",
":make_core_generated_mathml_element_type_helpers",
+ ":make_core_generated_mathml_names",
":make_core_generated_media_feature_names",
+ ":make_core_generated_media_features",
":make_core_generated_media_type_names",
- ":make_core_generated_performance_entry_names",
":make_core_generated_origin_trials",
+ ":make_core_generated_performance_entry_names",
":make_core_generated_style_property_shorthand",
+ ":make_core_generated_svg_element_type_helpers",
":make_core_generated_svg_names",
":make_core_generated_web_origin_trials",
":make_core_generated_xlink_names",
":make_core_generated_xml_names",
":make_core_generated_xml_ns_names",
- ":make_core_generated_html_element_type_helpers",
- ":make_core_generated_css_value_keywords",
- ":make_core_generated_media_features",
- ":make_core_generated_svg_element_type_helpers",
]
group("all_generators") {
@@ -1111,7 +1052,6 @@ jumbo_source_set("unit_tests") {
"css/css_uri_value_test.cc",
"css/css_value_test_helper.h",
"css/mock_css_paint_image_generator.h",
- "display_lock/display_lock_budget_test.cc",
"display_lock/display_lock_context_test.cc",
"display_lock/display_lock_utilities_test.cc",
"dom/attr_test.cc",
@@ -1148,11 +1088,12 @@ jumbo_source_set("unit_tests") {
"editing/finder/text_finder_test.cc",
"editing/keyboard_test.cc",
"editing/link_selection_test.cc",
+ "events/message_event_test.cc",
"events/pointer_event_factory_test.cc",
"events/touch_event_test.cc",
"events/web_input_event_conversion_test.cc",
"execution_context/agent_metrics_collector_test.cc",
- "execution_context/context_lifecycle_state_observer_test.cc",
+ "execution_context/execution_context_lifecycle_state_observer_test.cc",
"exported/local_frame_client_impl_test.cc",
"exported/prerendering_test.cc",
"exported/web_document_subresource_filter_test.cc",
@@ -1166,6 +1107,7 @@ jumbo_source_set("unit_tests") {
"exported/web_frame_serializer_test_helper.h",
"exported/web_frame_test.cc",
"exported/web_image_test.cc",
+ "exported/web_local_frame_client_test.cc",
"exported/web_meaningful_layouts_test.cc",
"exported/web_node_test.cc",
"exported/web_plugin_container_test.cc",
@@ -1174,6 +1116,7 @@ jumbo_source_set("unit_tests") {
"exported/web_searchable_form_data_test.cc",
"exported/web_selector_test.cc",
"exported/web_view_test.cc",
+ "feature_policy/document_policy_parser_test.cc",
"feature_policy/feature_policy_test.cc",
"feature_policy/policy_test.cc",
"fetch/blob_bytes_consumer_test.cc",
@@ -1197,7 +1140,9 @@ jumbo_source_set("unit_tests") {
"frame/csp/csp_directive_list_test.cc",
"frame/csp/csp_source_test.cc",
"frame/csp/media_list_directive_test.cc",
+ "frame/csp/require_trusted_types_for_directive_test.cc",
"frame/csp/source_list_directive_test.cc",
+ "frame/csp/string_list_directive_test.cc",
"frame/deprecation_report_body_test.cc",
"frame/document_loading_rendering_test.cc",
"frame/dom_timer_test.cc",
@@ -1218,95 +1163,11 @@ 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",
"geometry/dom_matrix_test.cc",
- "html/anchor_element_metrics_sender_test.cc",
- "html/anchor_element_metrics_test.cc",
- "html/canvas/canvas_async_blob_creator_test.cc",
- "html/canvas/canvas_font_cache_test.cc",
- "html/canvas/html_canvas_element_test.cc",
- "html/canvas/image_data_test.cc",
- "html/custom/custom_element_definition_test.cc",
- "html/custom/custom_element_descriptor_test.cc",
- "html/custom/custom_element_reaction_queue_test.cc",
- "html/custom/custom_element_reaction_stack_test.cc",
- "html/custom/custom_element_reaction_test_helpers.h",
- "html/custom/custom_element_registry_test.cc",
- "html/custom/custom_element_test.cc",
- "html/custom/custom_element_test_helpers.cc",
- "html/custom/custom_element_test_helpers.h",
- "html/custom/custom_element_upgrade_sorter_test.cc",
- "html/forms/email_input_type_test.cc",
- "html/forms/external_date_time_chooser_test.cc",
- "html/forms/external_popup_menu_test.cc",
- "html/forms/file_input_type_test.cc",
- "html/forms/form_controller_test.cc",
- "html/forms/form_data_test.cc",
- "html/forms/html_data_list_element_test.cc",
- "html/forms/html_form_control_element_test.cc",
- "html/forms/html_form_element_test.cc",
- "html/forms/html_input_element_test.cc",
- "html/forms/html_output_element_test.cc",
- "html/forms/html_select_element_test.cc",
- "html/forms/html_text_area_element_test.cc",
- "html/forms/internal_popup_menu_test.cc",
- "html/forms/option_list_test.cc",
- "html/forms/password_input_type_test.cc",
- "html/forms/step_range_test.cc",
- "html/forms/text_control_element_test.cc",
- "html/forms/type_ahead_test.cc",
- "html/html_content_element_test.cc",
- "html/html_dimension_test.cc",
- "html/html_element_test.cc",
- "html/html_embed_element_test.cc",
- "html/html_frame_element_test.cc",
- "html/html_iframe_element_test.cc",
- "html/html_image_element_test.cc",
- "html/html_link_element_sizes_attribute_test.cc",
- "html/html_link_element_test.cc",
- "html/html_meta_element_test.cc",
- "html/html_object_element_test.cc",
- "html/html_plugin_element_test.cc",
- "html/html_slot_element_test.cc",
- "html/html_table_row_element_test.cc",
- "html/image_document_test.cc",
- "html/imports/html_import_sheets_test.cc",
- "html/lazy_load_frame_observer_test.cc",
- "html/lazy_load_image_observer_test.cc",
- "html/link_element_loading_test.cc",
- "html/link_rel_attribute_test.cc",
- "html/media/autoplay_uma_helper_test.cc",
- "html/media/html_media_element_event_listeners_test.cc",
- "html/media/html_media_element_test.cc",
- "html/media/html_media_test_helper.cc",
- "html/media/html_media_test_helper.h",
- "html/media/html_video_element_persistent_test.cc",
- "html/media/html_video_element_test.cc",
- "html/media/media_custom_controls_fullscreen_detector_test.cc",
- "html/media/video_auto_fullscreen_test.cc",
- "html/media/video_filling_viewport_test.cc",
- "html/media/video_wake_lock_test.cc",
- "html/parser/atomic_html_token_test.cc",
- "html/parser/compact_html_token_test.cc",
- "html/parser/html_document_parser_loading_test.cc",
- "html/parser/html_document_parser_test.cc",
- "html/parser/html_entity_parser_test.cc",
- "html/parser/html_parser_idioms_test.cc",
- "html/parser/html_preload_scanner_document_test.cc",
- "html/parser/html_preload_scanner_test.cc",
- "html/parser/html_resource_preloader_test.cc",
- "html/parser/html_srcset_parser_test.cc",
- "html/parser/html_tokenizer_test.cc",
- "html/parser/html_tree_builder_simulator_test.cc",
- "html/parser/html_view_source_parser_test.cc",
- "html/parser/text_resource_decoder_test.cc",
- "html/shadow/progress_shadow_element_test.cc",
- "html/time_ranges_test.cc",
- "html/track/text_track_list_test.cc",
- "html/track/vtt/buffered_line_reader_test.cc",
- "html/track/vtt/vtt_scanner_test.cc",
"imagebitmap/image_bitmap_test.cc",
"input/event_handler_test.cc",
"input/fallback_cursor_event_manager_test.cc",
@@ -1369,7 +1230,6 @@ jumbo_source_set("unit_tests") {
"layout/ng/geometry/ng_box_strut_test.cc",
"layout/ng/geometry/ng_static_position_test.cc",
"layout/ng/inline/layout_ng_text_test.cc",
- "layout/ng/inline/ng_baseline_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",
@@ -1391,6 +1251,8 @@ jumbo_source_set("unit_tests") {
"layout/ng/ng_column_layout_algorithm_test.cc",
"layout/ng/ng_constraint_space_builder_test.cc",
"layout/ng/ng_fieldset_layout_algorithm_test.cc",
+ "layout/ng/ng_fragment_child_iterator_test.cc",
+ "layout/ng/ng_fragmentation_test.cc",
"layout/ng/ng_inline_layout_test.cc",
"layout/ng/ng_layout_result_caching_test.cc",
"layout/ng/ng_layout_test.h",
@@ -1413,6 +1275,7 @@ jumbo_source_set("unit_tests") {
"loader/base_fetch_context_test.cc",
"loader/document_load_timing_test.cc",
"loader/document_loader_test.cc",
+ "loader/font_preload_manager_test.cc",
"loader/frame_fetch_context_test.cc",
"loader/frame_resource_fetcher_properties_test.cc",
"loader/idleness_detector_test.cc",
@@ -1460,10 +1323,11 @@ jumbo_source_set("unit_tests") {
"page/scrolling/scroll_into_view_test.cc",
"page/scrolling/scroll_metrics_test.cc",
"page/scrolling/scroll_state_test.cc",
- "page/scrolling/scrolling_coordinator_test.cc",
+ "page/scrolling/scrolling_test.cc",
"page/scrolling/snap_coordinator_test.cc",
"page/scrolling/text_fragment_anchor_metrics_test.cc",
"page/scrolling/text_fragment_anchor_test.cc",
+ "page/scrolling/text_fragment_selector_test.cc",
"page/slot_scoped_traversal_test.cc",
"page/spatial_navigation_test.cc",
"page/touch_adjustment_test.cc",
@@ -1527,7 +1391,6 @@ jumbo_source_set("unit_tests") {
"scheduler_integration_tests/virtual_time_test.cc",
"script/document_modulator_impl_test.cc",
"script/dynamic_module_resolver_test.cc",
- "script/layered_api_test.cc",
"script/mock_script_element_base.h",
"script/module_map_test.cc",
"script/module_record_resolver_impl_test.cc",
@@ -1550,6 +1413,8 @@ jumbo_source_set("unit_tests") {
"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",
"svg/graphics/svg_image_test.cc",
"svg/svg_foreign_object_element_test.cc",
"svg/svg_path_parser_test.cc",
@@ -1594,6 +1459,10 @@ jumbo_source_set("unit_tests") {
"xml/xpath_functions_test.cc",
]
+ if (is_debug || dcheck_always_on) {
+ sources += [ "exported/web_disallow_transition_scope_test.cc" ]
+ }
+
configs += [
":blink_core_pch",
"//third_party/blink/renderer:config",
@@ -1603,6 +1472,7 @@ jumbo_source_set("unit_tests") {
deps = [
":core",
":unit_test_support",
+ "//components/paint_preview/common:common",
"//mojo/public/cpp/system",
"//skia:skcms",
"//testing/gmock",
@@ -1613,11 +1483,12 @@ jumbo_source_set("unit_tests") {
"//third_party/blink/renderer/core/css: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",
+ "//ui/base/mojom:cursor_type_blink",
]
- data_deps = [
- ":unit_tests_data",
- ]
+ data_deps = [ ":unit_tests_data" ]
# FIXME: Enable mojo unittests on Android after fixing data dependency.
# crbug.com/741925
@@ -1628,7 +1499,7 @@ jumbo_source_set("unit_tests") {
if (!is_mac) {
sources += [
"scroll/scroll_animator_test.cc",
- "scroll/scrolling_test.cc",
+ "scroll/scroll_test.cc",
]
}
@@ -1648,9 +1519,7 @@ group("unit_tests_data") {
jumbo_source_set("perf_tests") {
testonly = true
- sources = [
- "layout/visual_rect_mapping_perftest.cc",
- ]
+ sources = [ "layout/visual_rect_mapping_perftest.cc" ]
configs += [
":blink_core_pch",
@@ -1672,6 +1541,8 @@ jumbo_source_set("unit_test_support") {
sources = [
"testing/core_unit_test_helper.cc",
"testing/core_unit_test_helper.h",
+ "testing/module_test_base.cc",
+ "testing/module_test_base.h",
"testing/page_test_base.cc",
"testing/page_test_base.h",
"testing/scoped_fake_plugin_registry.cc",
@@ -1693,9 +1564,7 @@ jumbo_source_set("unit_test_support") {
# Fuzzer for blink::StyleSheetContents
fuzzer_test("stylesheet_contents_fuzzer") {
- sources = [
- "css/style_sheet_contents_fuzzer.cc",
- ]
+ sources = [ "css/style_sheet_contents_fuzzer.cc" ]
deps = [
":core",
"../platform:blink_fuzzer_test_support",
@@ -1707,9 +1576,7 @@ fuzzer_test("stylesheet_contents_fuzzer") {
# Fuzzer for blink::CSSParserFastPaths
fuzzer_test("css_parser_fast_paths_fuzzer") {
- sources = [
- "css/parser/css_parser_fast_paths_fuzzer.cc",
- ]
+ sources = [ "css/parser/css_parser_fast_paths_fuzzer.cc" ]
deps = [
":core",
"../platform:blink_fuzzer_test_support",
@@ -1733,9 +1600,7 @@ fuzzer_test("html_preload_scanner_fuzzer") {
# Fuzzer for blink::ContentSecurityPolicy.
fuzzer_test("content_security_policy_fuzzer") {
- sources = [
- "frame/csp/content_security_policy_fuzzer.cc",
- ]
+ sources = [ "frame/csp/content_security_policy_fuzzer.cc" ]
deps = [
":core",
"//third_party/blink/renderer/platform:blink_fuzzer_test_support",
@@ -1760,16 +1625,12 @@ fuzzer_test("css_parser_proto_fuzzer") {
}
proto_library("css_proto") {
- sources = [
- "css/parser/css.proto",
- ]
+ sources = [ "css/parser/css.proto" ]
}
# Fuzzers for blink::FeaturePolicy.
fuzzer_test("feature_policy_fuzzer") {
- sources = [
- "feature_policy/feature_policy_fuzzer.cc",
- ]
+ sources = [ "feature_policy/feature_policy_fuzzer.cc" ]
deps = [
"//third_party/blink/renderer/platform:blink_fuzzer_test_support",
"//third_party/icu",
@@ -1780,9 +1641,7 @@ fuzzer_test("feature_policy_fuzzer") {
}
fuzzer_test("feature_policy_attr_fuzzer") {
- sources = [
- "feature_policy/feature_policy_attr_fuzzer.cc",
- ]
+ sources = [ "feature_policy/feature_policy_attr_fuzzer.cc" ]
deps = [
"//third_party/blink/renderer/platform:blink_fuzzer_test_support",
"//third_party/icu",
@@ -1793,9 +1652,7 @@ fuzzer_test("feature_policy_attr_fuzzer") {
}
fuzzer_test("feature_policy_value_fuzzer") {
- sources = [
- "feature_policy/feature_policy_value_fuzzer.cc",
- ]
+ sources = [ "feature_policy/feature_policy_value_fuzzer.cc" ]
deps = [
"//third_party/blink/renderer/platform:blink_fuzzer_test_support",
"//third_party/icu",
@@ -1803,3 +1660,14 @@ fuzzer_test("feature_policy_value_fuzzer") {
dict = "//third_party/blink/renderer/core/feature_policy/feature_policy_value.dict"
seed_corpus = "//third_party/blink/renderer/core/feature_policy/feature_policy_value_corpus"
}
+
+fuzzer_test("document_policy_fuzzer") {
+ sources = [ "feature_policy/document_policy_fuzzer.cc" ]
+ deps = [
+ "//third_party/blink/renderer/platform:blink_fuzzer_test_support",
+ "//third_party/icu",
+ ]
+ dict = "//third_party/blink/renderer/core/feature_policy/document_policy.dict"
+ seed_corpus =
+ "//third_party/blink/renderer/core/feature_policy/document_policy_corpus"
+}
diff --git a/chromium/third_party/blink/renderer/core/DEPS b/chromium/third_party/blink/renderer/core/DEPS
index 422b53676f9..391a21202df 100644
--- a/chromium/third_party/blink/renderer/core/DEPS
+++ b/chromium/third_party/blink/renderer/core/DEPS
@@ -11,6 +11,7 @@ include_rules = [
"+base/memory/scoped_policy.h",
"+base/memory/scoped_refptr.h",
"+base/metrics/field_trial_params.h",
+ "+base/numerics/ranges.h",
"+base/strings/stringprintf.h",
"+base/synchronization/waitable_event.h",
"+base/task/sequence_manager/task_time_observer.h",
@@ -25,6 +26,7 @@ include_rules = [
"+cc/animation/scroll_offset_animations.h",
"+cc/animation/scroll_offset_animation_curve.h",
"+cc/animation/scroll_state.h",
+ "+cc/animation/scroll_timeline.h",
"+cc/base/region.h",
"+cc/input/browser_controls_state.h",
"+cc/input/event_listener_properties.h",
@@ -46,11 +48,14 @@ include_rules = [
"+cc/layers/scrollbar_layer_base.h",
"+cc/layers/surface_layer.h",
"+cc/metrics/begin_main_frame_metrics.h",
+ "+cc/metrics/frame_sequence_tracker.h",
"+cc/paint/display_item_list.h",
"+cc/paint/paint_canvas.h",
"+cc/paint/paint_flags.h",
+ "+cc/paint/paint_image.h",
"+cc/paint/paint_worklet_input.h",
"+cc/trees/browser_controls_params.h",
+ "+cc/trees/layer_tree_host.h",
"+cc/trees/paint_holding_commit_trigger.h",
"+components/performance_manager/public/mojom/coordination_unit.mojom-blink.h",
"+gpu/config/gpu_feature_info.h",
@@ -59,11 +64,14 @@ include_rules = [
"+mojo/public/cpp/base",
"+mojo/public/cpp/bindings",
"+mojo/public/cpp/system",
+ "+mojo/public/mojom/base",
+ "+services/data_decoder/public/mojom/resource_snapshot_for_web_bundle.mojom-blink.h",
"+services/device/public/mojom/wake_lock.mojom-blink.h",
"+services/metrics/public",
"+services/network/public/cpp/cors/cors_error_status.h",
"+services/network/public/cpp/features.h",
"+services/network/public/cpp/request_mode.h",
+ "+services/network/public/cpp/request_destination.h",
"+services/network/public/cpp/shared_url_loader_factory.h",
"+services/resource_coordinator/public/mojom/coordination_unit.mojom-blink.h",
"+services/service_manager/public",
@@ -79,9 +87,11 @@ include_rules = [
"+third_party/blink/renderer/core",
"-third_party/blink/renderer/modules",
"+third_party/skia/include",
+ "+ui/base/cursor/cursor.h",
"+ui/base/ime/mojom/ime_types.mojom-blink.h",
"+ui/base/ime/mojom/ime_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",
@@ -115,6 +125,9 @@ specific_include_rules = {
"+url/url_util.h"
],
"data_object_item.cc" : [ "+ui/gfx/codec" ],
+ "chrome_client.h" : [
+ "+components/viz/common/surfaces/frame_sink_id.h",
+ ],
"clipboard_utilities.cc" : [ "+net/base/escape.h" ],
"find_in_page.cc" : [
"+third_party/blink/renderer/core/frame/web_local_frame_impl.h",
@@ -122,6 +135,10 @@ specific_include_rules = {
"find_task_controller.cc" : [
"+third_party/blink/renderer/core/frame/web_local_frame_impl.h",
],
+ # TODO(darin): Remove once onion-souping is complete for prerendering.
+ "prerenderer_client.cc" : [
+ "+third_party/blink/renderer/core/frame/web_local_frame_impl.h",
+ ],
"html_media_element_test.cc": [
"+base/test/gtest_util.h",
],
@@ -130,5 +147,9 @@ specific_include_rules = {
],
"html_canvas_painter_test.cc": [
"+components/viz/test/test_context_provider.h",
- ]
+ ],
+ "document.cc" : [
+ "+net/base/registry_controlled_domains/registry_controlled_domain.h",
+ ],
+ "(computed_style|computed_style_test)\.cc" : [ "+ui/base/ui_base_features.h" ]
}
diff --git a/chromium/third_party/blink/renderer/core/OWNERS b/chromium/third_party/blink/renderer/core/OWNERS
index 06fbc77b235..dfb113db703 100644
--- a/chromium/third_party/blink/renderer/core/OWNERS
+++ b/chromium/third_party/blink/renderer/core/OWNERS
@@ -44,6 +44,7 @@ kenneth.r.christiansen@intel.com
kinuko@chromium.org
kojii@chromium.org
kouhei@chromium.org
+masonfreed@chromium.org
mkwst@chromium.org
mstensho@chromium.org
# nainar reviews changes in core/css,core/style
diff --git a/chromium/third_party/blink/renderer/core/accessibility/BUILD.gn b/chromium/third_party/blink/renderer/core/accessibility/BUILD.gn
index b0cf9a5499e..e5c0007e403 100644
--- a/chromium/third_party/blink/renderer/core/accessibility/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/accessibility/BUILD.gn
@@ -12,14 +12,11 @@ blink_core_sources("accessibility") {
"ax_context.h",
"ax_object_cache.cc",
"ax_object_cache.h",
- "ax_object_cache_base.cc",
"ax_object_cache_base.h",
"axid.h",
]
}
blink_core_tests("unit_tests") {
- sources = [
- "apply_dark_mode_test.cc",
- ]
+ sources = [ "apply_dark_mode_test.cc" ]
}
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 2fd3d71b79b..88164f47a8d 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
@@ -39,17 +39,10 @@ bool HasLightBackground(const LayoutView& root) {
kBrightnessThreshold;
}
-bool IsDarkModeEnabled(const Settings& frame_settings) {
- static bool isDarkModeEnabledByFeatureFlag =
- features::kForceDarkInversionMethodParam.Get() !=
- ForceDarkInversionMethod::kUseBlinkSettings;
- return isDarkModeEnabledByFeatureFlag || frame_settings.GetDarkModeEnabled();
-}
-
DarkModeInversionAlgorithm GetMode(const Settings& frame_settings) {
switch (features::kForceDarkInversionMethodParam.Get()) {
case ForceDarkInversionMethod::kUseBlinkSettings:
- return frame_settings.GetDarkModeInversionAlgorithm();
+ return frame_settings.GetForceDarkModeInversionAlgorithm();
case ForceDarkInversionMethod::kCielabBased:
return DarkModeInversionAlgorithm::kInvertLightnessLAB;
case ForceDarkInversionMethod::kHslBased:
@@ -62,7 +55,7 @@ DarkModeInversionAlgorithm GetMode(const Settings& frame_settings) {
DarkModeImagePolicy GetImagePolicy(const Settings& frame_settings) {
switch (features::kForceDarkImageBehaviorParam.Get()) {
case ForceDarkImageBehavior::kUseBlinkSettings:
- return frame_settings.GetDarkModeImagePolicy();
+ return frame_settings.GetForceDarkModeImagePolicy();
case ForceDarkImageBehavior::kInvertNone:
return DarkModeImagePolicy::kFilterNone;
case ForceDarkImageBehavior::kInvertSelectively:
@@ -74,8 +67,9 @@ int GetTextBrightnessThreshold(const Settings& frame_settings) {
const int flag_value = base::GetFieldTrialParamByFeatureAsInt(
features::kForceWebContentsDarkMode,
features::kForceDarkTextLightnessThresholdParam.name, -1);
- return flag_value >= 0 ? flag_value
- : frame_settings.GetDarkModeTextBrightnessThreshold();
+ return flag_value >= 0
+ ? flag_value
+ : frame_settings.GetForceDarkModeTextBrightnessThreshold();
}
int GetBackgroundBrightnessThreshold(const Settings& frame_settings) {
@@ -84,7 +78,7 @@ int GetBackgroundBrightnessThreshold(const Settings& frame_settings) {
features::kForceDarkBackgroundLightnessThresholdParam.name, -1);
return flag_value >= 0
? flag_value
- : frame_settings.GetDarkModeBackgroundBrightnessThreshold();
+ : frame_settings.GetForceDarkModeBackgroundBrightnessThreshold();
}
DarkModeSettings GetEnabledSettings(const Settings& frame_settings) {
@@ -96,9 +90,10 @@ DarkModeSettings GetEnabledSettings(const Settings& frame_settings) {
settings.background_brightness_threshold =
GetBackgroundBrightnessThreshold(frame_settings);
- settings.grayscale = frame_settings.GetDarkModeGrayscale();
- settings.contrast = frame_settings.GetDarkModeContrast();
- settings.image_grayscale_percent = frame_settings.GetDarkModeImageGrayscale();
+ settings.grayscale = frame_settings.GetForceDarkModeGrayscale();
+ settings.contrast = frame_settings.GetForceDarkModeContrast();
+ settings.image_grayscale_percent =
+ frame_settings.GetForceDarkModeImageGrayscale();
return settings;
}
@@ -112,9 +107,9 @@ DarkModeSettings GetDisabledSettings() {
DarkModeSettings BuildDarkModeSettings(const Settings& frame_settings,
const LayoutView& root) {
- if (IsDarkModeEnabled(frame_settings) &&
- ShouldApplyDarkModeFilterToPage(frame_settings.GetDarkModePagePolicy(),
- root)) {
+ if (frame_settings.GetForceDarkModeEnabled() &&
+ ShouldApplyDarkModeFilterToPage(
+ frame_settings.GetForceDarkModePagePolicy(), root)) {
return GetEnabledSettings(frame_settings);
}
return GetDisabledSettings();
diff --git a/chromium/third_party/blink/renderer/core/accessibility/apply_dark_mode_test.cc b/chromium/third_party/blink/renderer/core/accessibility/apply_dark_mode_test.cc
index 405e1b11055..544b31bc871 100644
--- a/chromium/third_party/blink/renderer/core/accessibility/apply_dark_mode_test.cc
+++ b/chromium/third_party/blink/renderer/core/accessibility/apply_dark_mode_test.cc
@@ -65,10 +65,9 @@ TEST_F(ApplyDarkModeCheckTest, MetaColorSchemeDark) {
ScopedCSSColorSchemeForTest css_feature_scope(true);
ScopedMetaColorSchemeForTest meta_feature_scope(true);
GetDocument().GetSettings()->SetForceDarkModeEnabled(true);
- ColorSchemeHelper color_scheme_helper;
- color_scheme_helper.SetPreferredColorScheme(GetDocument(),
- PreferredColorScheme::kDark);
- GetDocument().head()->SetInnerHTMLFromString(R"HTML(
+ ColorSchemeHelper color_scheme_helper(GetDocument());
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kDark);
+ GetDocument().head()->setInnerHTML(R"HTML(
<meta name="color-scheme" content="dark">
)HTML");
UpdateAllLifecyclePhasesForTest();
diff --git a/chromium/third_party/blink/renderer/core/accessibility/ax_object_cache.cc b/chromium/third_party/blink/renderer/core/accessibility/ax_object_cache.cc
index e991372de7d..c6c41f5b1f3 100644
--- a/chromium/third_party/blink/renderer/core/accessibility/ax_object_cache.cc
+++ b/chromium/third_party/blink/renderer/core/accessibility/ax_object_cache.cc
@@ -56,11 +56,6 @@ AXObjectCache* AXObjectCache::Create(Document& document) {
return create_function_(document);
}
-AXObjectCache::AXObjectCache(Document& document)
- : ContextLifecycleObserver(document.GetExecutionContext()) {}
-
-AXObjectCache::~AXObjectCache() = default;
-
namespace {
typedef HashSet<String, CaseFoldingHash> ARIAWidgetSet;
@@ -141,8 +136,4 @@ bool AXObjectCache::IsInsideFocusableElementOrARIAWidget(const Node& node) {
return false;
}
-void AXObjectCache::Trace(blink::Visitor* visitor) {
- ContextLifecycleObserver::Trace(visitor);
-}
-
} // namespace blink
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 750d20f69fb..f0993e9a254 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
@@ -42,20 +42,16 @@ class HTMLCanvasElement;
class HTMLOptionElement;
class HTMLSelectElement;
class IntPoint;
-class LayoutMenuList;
class LayoutRect;
class LineLayoutItem;
class LocalFrameView;
-class CORE_EXPORT AXObjectCache : public GarbageCollected<AXObjectCache>,
- public ContextLifecycleObserver {
- USING_GARBAGE_COLLECTED_MIXIN(AXObjectCache);
-
+class CORE_EXPORT AXObjectCache : public GarbageCollected<AXObjectCache> {
public:
static AXObjectCache* Create(Document&);
- virtual ~AXObjectCache();
- void Trace(blink::Visitor*) override;
+ virtual ~AXObjectCache() = default;
+ virtual void Trace(Visitor*) {}
virtual void Dispose() = 0;
@@ -102,10 +98,10 @@ class CORE_EXPORT AXObjectCache : public GarbageCollected<AXObjectCache>,
virtual void HandleTextMarkerDataAdded(Node* start, Node* end) = 0;
virtual void HandleTextFormControlChanged(Node*) = 0;
virtual void HandleValueChanged(Node*) = 0;
- virtual void HandleUpdateActiveMenuOption(LayoutMenuList*,
+ virtual void HandleUpdateActiveMenuOption(LayoutObject*,
int option_index) = 0;
- virtual void DidShowMenuListPopup(LayoutMenuList*) = 0;
- virtual void DidHideMenuListPopup(LayoutMenuList*) = 0;
+ virtual void DidShowMenuListPopup(LayoutObject*) = 0;
+ virtual void DidHideMenuListPopup(LayoutObject*) = 0;
virtual void HandleLoadComplete(Document*) = 0;
virtual void HandleLayoutComplete(Document*) = 0;
virtual void HandleClicked(Node*) = 0;
@@ -113,7 +109,7 @@ class CORE_EXPORT AXObjectCache : public GarbageCollected<AXObjectCache>,
const Element* form_control) = 0;
// Handle any notifications which arrived while layout was dirty.
- virtual void ProcessUpdatesAfterLayout(Document&) = 0;
+ virtual void ProcessDeferredAccessibilityEvents(Document&) = 0;
// Changes to virtual Accessibility Object Model nodes.
virtual void HandleAttributeChanged(const QualifiedName& attr_name,
@@ -153,7 +149,7 @@ class CORE_EXPORT AXObjectCache : public GarbageCollected<AXObjectCache>,
private:
friend class AXObjectCacheBase;
- AXObjectCache(Document&);
+ AXObjectCache() = default;
static AXObjectCacheCreateFunction create_function_;
DISALLOW_COPY_AND_ASSIGN(AXObjectCache);
diff --git a/chromium/third_party/blink/renderer/core/accessibility/ax_object_cache_base.cc b/chromium/third_party/blink/renderer/core/accessibility/ax_object_cache_base.cc
deleted file mode 100644
index 6aad63fec25..00000000000
--- a/chromium/third_party/blink/renderer/core/accessibility/ax_object_cache_base.cc
+++ /dev/null
@@ -1,17 +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/accessibility/ax_object_cache_base.h"
-
-#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
-#include "third_party/blink/renderer/core/core_export.h"
-
-namespace blink {
-
-AXObjectCacheBase::~AXObjectCacheBase() = default;
-
-AXObjectCacheBase::AXObjectCacheBase(Document& document)
- : AXObjectCache(document) {}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/accessibility/ax_object_cache_base.h b/chromium/third_party/blink/renderer/core/accessibility/ax_object_cache_base.h
index c8534be8f5a..8e52e3ee2a0 100644
--- a/chromium/third_party/blink/renderer/core/accessibility/ax_object_cache_base.h
+++ b/chromium/third_party/blink/renderer/core/accessibility/ax_object_cache_base.h
@@ -24,13 +24,13 @@ class AXObject;
// new public API methods or similar) and remove this class.
class CORE_EXPORT AXObjectCacheBase : public AXObjectCache {
public:
- ~AXObjectCacheBase() override;
+ ~AXObjectCacheBase() override = default;
virtual AXObject* Get(const Node*) = 0;
virtual AXObject* GetOrCreate(LayoutObject*) = 0;
protected:
- AXObjectCacheBase(Document&);
+ AXObjectCacheBase() = default;
DISALLOW_COPY_AND_ASSIGN(AXObjectCacheBase);
};
diff --git a/chromium/third_party/blink/renderer/core/animation/BUILD.gn b/chromium/third_party/blink/renderer/core/animation/BUILD.gn
index 927a1189430..d2a6c96563d 100644
--- a/chromium/third_party/blink/renderer/core/animation/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/animation/BUILD.gn
@@ -33,6 +33,7 @@ blink_core_sources("animation") {
"animation_input_helpers.h",
"animation_time_delta.cc",
"animation_time_delta.h",
+ "animation_timeline.cc",
"animation_timeline.h",
"basic_shape_interpolation_functions.cc",
"basic_shape_interpolation_functions.h",
@@ -91,6 +92,8 @@ blink_core_sources("animation") {
"css_image_list_interpolation_type.h",
"css_image_slice_interpolation_type.cc",
"css_image_slice_interpolation_type.h",
+ "css_interpolation_environment.cc",
+ "css_interpolation_environment.h",
"css_interpolation_type.cc",
"css_interpolation_type.h",
"css_interpolation_types_map.cc",
@@ -263,9 +266,7 @@ blink_core_sources("animation") {
"worklet_animation_controller.h",
]
- deps = [
- ":buildflags",
- ]
+ deps = [ ":buildflags" ]
}
blink_core_tests("unit_tests") {
@@ -280,6 +281,7 @@ blink_core_tests("unit_tests") {
"compositor_animations_test.cc",
"css/css_animations_test.cc",
"css/css_transition_data_test.cc",
+ "document_animations_test.cc",
"document_timeline_test.cc",
"effect_input_test.cc",
"effect_stack_test.cc",
diff --git a/chromium/third_party/blink/renderer/core/animation/animatable.cc b/chromium/third_party/blink/renderer/core/animation/animatable.cc
index 88fc2ef60e7..6d6466339df 100644
--- a/chromium/third_party/blink/renderer/core/animation/animatable.cc
+++ b/chromium/third_party/blink/renderer/core/animation/animatable.cc
@@ -5,7 +5,10 @@
#include "third_party/blink/renderer/core/animation/animatable.h"
#include "third_party/blink/renderer/bindings/core/v8/unrestricted_double_or_keyframe_animation_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/unrestricted_double_or_keyframe_effect_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_get_animations_options.h"
#include "third_party/blink/renderer/core/animation/animation.h"
+#include "third_party/blink/renderer/core/animation/document_animations.h"
#include "third_party/blink/renderer/core/animation/document_timeline.h"
#include "third_party/blink/renderer/core/animation/effect_input.h"
#include "third_party/blink/renderer/core/animation/effect_model.h"
@@ -27,7 +30,7 @@ namespace {
// the |element.animate| API is used to animate a CSS property which is blocked
// by the feature policy 'layout-animations'.
void ReportFeaturePolicyViolationsIfNecessary(
- const Document& document,
+ const ExecutionContext& context,
const KeyframeEffectModelBase& effect) {
for (const auto& property_handle : effect.Properties()) {
if (!property_handle.IsCSSProperty())
@@ -35,11 +38,22 @@ void ReportFeaturePolicyViolationsIfNecessary(
const auto& css_property = property_handle.GetCSSProperty();
if (LayoutAnimationsPolicy::AffectedCSSProperties().Contains(
&css_property)) {
- LayoutAnimationsPolicy::ReportViolation(css_property, document);
+ LayoutAnimationsPolicy::ReportViolation(css_property, context);
}
}
}
+UnrestrictedDoubleOrKeyframeEffectOptions CoerceEffectOptions(
+ UnrestrictedDoubleOrKeyframeAnimationOptions options) {
+ if (options.IsKeyframeAnimationOptions()) {
+ return UnrestrictedDoubleOrKeyframeEffectOptions::FromKeyframeEffectOptions(
+ options.GetAsKeyframeAnimationOptions());
+ } else {
+ return UnrestrictedDoubleOrKeyframeEffectOptions::FromUnrestrictedDouble(
+ options.GetAsUnrestrictedDouble());
+ }
+}
+
} // namespace
Animation* Animatable::animate(
@@ -47,25 +61,16 @@ Animation* Animatable::animate(
const ScriptValue& keyframes,
const UnrestrictedDoubleOrKeyframeAnimationOptions& options,
ExceptionState& exception_state) {
- EffectModel::CompositeOperation composite = EffectModel::kCompositeReplace;
- if (options.IsKeyframeAnimationOptions()) {
- composite = EffectModel::StringToCompositeOperation(
- options.GetAsKeyframeAnimationOptions()->composite())
- .value();
- }
-
Element* element = GetAnimationTarget();
- KeyframeEffectModelBase* effect = EffectInput::Convert(
- element, keyframes, composite, script_state, exception_state);
+ KeyframeEffect* effect =
+ KeyframeEffect::Create(script_state, element, keyframes,
+ CoerceEffectOptions(options), exception_state);
if (exception_state.HadException())
return nullptr;
- Timing timing =
- TimingInput::Convert(options, &element->GetDocument(), exception_state);
- if (exception_state.HadException())
- return nullptr;
-
- Animation* animation = animateInternal(*element, effect, timing);
+ ReportFeaturePolicyViolationsIfNecessary(*element->GetExecutionContext(),
+ *effect->Model());
+ Animation* animation = element->GetDocument().Timeline().Play(effect);
if (options.IsKeyframeAnimationOptions())
animation->setId(options.GetAsKeyframeAnimationOptions()->id());
return animation;
@@ -75,12 +80,14 @@ Animation* Animatable::animate(ScriptState* script_state,
const ScriptValue& keyframes,
ExceptionState& exception_state) {
Element* element = GetAnimationTarget();
- KeyframeEffectModelBase* effect =
- EffectInput::Convert(element, keyframes, EffectModel::kCompositeReplace,
- script_state, exception_state);
+ KeyframeEffect* effect =
+ KeyframeEffect::Create(script_state, element, keyframes, exception_state);
if (exception_state.HadException())
return nullptr;
- return animateInternal(*element, effect, Timing());
+
+ ReportFeaturePolicyViolationsIfNecessary(*element->GetExecutionContext(),
+ *effect->Model());
+ return element->GetDocument().Timeline().Play(effect);
}
HeapVector<Member<Animation>> Animatable::getAnimations(
@@ -97,12 +104,14 @@ HeapVector<Member<Animation>> Animatable::getAnimations(
return animations;
for (const auto& animation :
- element->GetDocument().Timeline().getAnimations()) {
+ element->GetDocument().GetDocumentAnimations().getAnimations(
+ element->GetTreeScope())) {
DCHECK(animation->effect());
- Element* target = ToKeyframeEffect(animation->effect())->target();
+ // TODO(gtsteel) make this use the idl properties
+ Element* target = To<KeyframeEffect>(animation->effect())->EffectTarget();
if (element == target || (use_subtree && element->contains(target))) {
- // DocumentTimeline::getAnimations should only give us animations that are
- // either current or in effect.
+ // DocumentAnimations::getAnimations should only give us animations that
+ // are either current or in effect.
DCHECK(animation->effect()->IsCurrent() ||
animation->effect()->IsInEffect());
animations.push_back(animation);
@@ -111,13 +120,4 @@ HeapVector<Member<Animation>> Animatable::getAnimations(
return animations;
}
-Animation* Animatable::animateInternal(Element& element,
- KeyframeEffectModelBase* effect,
- const Timing& timing) {
- ReportFeaturePolicyViolationsIfNecessary(element.GetDocument(), *effect);
- auto* keyframe_effect =
- MakeGarbageCollected<KeyframeEffect>(&element, effect, timing);
- return element.GetDocument().Timeline().Play(keyframe_effect);
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/animatable.h b/chromium/third_party/blink/renderer/core/animation/animatable.h
index 3b568266aef..041953e4ea4 100644
--- a/chromium/third_party/blink/renderer/core/animation/animatable.h
+++ b/chromium/third_party/blink/renderer/core/animation/animatable.h
@@ -31,7 +31,6 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATABLE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATABLE_H_
-#include "third_party/blink/renderer/core/animation/get_animations_options.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/heap/member.h"
@@ -41,11 +40,10 @@ namespace blink {
class Animation;
class ExceptionState;
class Element;
-class KeyframeEffectModelBase;
+class GetAnimationsOptions;
class ScriptState;
class ScriptValue;
class UnrestrictedDoubleOrKeyframeAnimationOptions;
-struct Timing;
// https://drafts.csswg.org/web-animations-1/#the-animatable-interface-mixin
class CORE_EXPORT Animatable {
@@ -63,13 +61,6 @@ class CORE_EXPORT Animatable {
HeapVector<Member<Animation>> getAnimations(
GetAnimationsOptions* options = nullptr);
-
- private:
- FRIEND_TEST_ALL_PREFIXES(AnimationSimTest, CustomPropertyBaseComputedStyle);
-
- static Animation* animateInternal(Element&,
- KeyframeEffectModelBase*,
- const Timing&);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/animatable.idl b/chromium/third_party/blink/renderer/core/animation/animatable.idl
index 9d4327680d0..1101e4c996e 100644
--- a/chromium/third_party/blink/renderer/core/animation/animatable.idl
+++ b/chromium/third_party/blink/renderer/core/animation/animatable.idl
@@ -31,7 +31,7 @@
// https://drafts.csswg.org/web-animations/#the-animatable-interface-mixin
interface mixin Animatable {
[CallWith=ScriptState, Measure, RaisesException] Animation animate(object? keyframes, optional (unrestricted double or KeyframeAnimationOptions) options);
- [RuntimeEnabled=WebAnimationsAPI] sequence<Animation> getAnimations(optional GetAnimationsOptions options);
+ [RuntimeEnabled=WebAnimationsAPI] sequence<Animation> getAnimations(optional GetAnimationsOptions options = {});
};
// https://drafts.csswg.org/web-animations-1/#extensions-to-the-element-interface
diff --git a/chromium/third_party/blink/renderer/core/animation/animation.cc b/chromium/third_party/blink/renderer/core/animation/animation.cc
index e63dd12a36c..56a74a8418a 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation.cc
+++ b/chromium/third_party/blink/renderer/core/animation/animation.cc
@@ -39,19 +39,25 @@
#include "third_party/blink/renderer/core/animation/animation_timeline.h"
#include "third_party/blink/renderer/core/animation/css/css_animations.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/animation/keyframe_effect.h"
#include "third_party/blink/renderer/core/animation/pending_animations.h"
#include "third_party/blink/renderer/core/animation/scroll_timeline.h"
+#include "third_party/blink/renderer/core/animation/scroll_timeline_util.h"
+#include "third_party/blink/renderer/core/css/properties/css_property_ref.h"
+#include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
#include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
#include "third_party/blink/renderer/core/events/animation_playback_event.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/web_feature.h"
#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation.h"
+#include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.h"
#include "third_party/blink/renderer/platform/bindings/microtask.h"
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
@@ -64,6 +70,8 @@ namespace blink {
namespace {
+enum PseudoPriority { kNone, kMarker, kBefore, kOther, kAfter };
+
unsigned NextSequenceNumber() {
static unsigned next = 0;
return ++next;
@@ -89,6 +97,40 @@ double Min(base::Optional<double> a, double b) {
return b;
}
+PseudoPriority ConvertStringtoPriority(const String& pseudo) {
+ if (pseudo.IsNull())
+ return PseudoPriority::kNone;
+ if (pseudo == "::marker")
+ return PseudoPriority::kMarker;
+ if (pseudo == "::before")
+ return PseudoPriority::kBefore;
+ if (pseudo == "::after")
+ return PseudoPriority::kAfter;
+ return PseudoPriority::kOther;
+}
+
+Animation::AnimationClassPriority AnimationPriority(
+ const Animation& animation) {
+ // According to the spec:
+ // https://drafts.csswg.org/web-animations/#animation-class,
+ // CSS tranisiton has a lower composite order than the CSS animation, and CSS
+ // animation has a lower composite order than other animations. Thus,CSS
+ // transitions are to appear before CSS animations and CSS animations are to
+ // appear before other animations
+ // TODO: When animations are disassociated from their element they are sorted
+ // by their sequence number, i.e. kDefaultPriority. See
+ // https://drafts.csswg.org/css-animations-2/#animation-composite-order and
+ // https://drafts.csswg.org/css-transitions-2/#animation-composite-order
+ Animation::AnimationClassPriority priority;
+ if (animation.IsCSSTransition() && animation.IsOwned())
+ priority = Animation::AnimationClassPriority::kCssTransitionPriority;
+ else if (animation.IsCSSAnimation() && animation.IsOwned())
+ priority = Animation::AnimationClassPriority::kCssAnimationPriority;
+ else
+ priority = Animation::AnimationClassPriority::kDefaultPriority;
+ return priority;
+}
+
void RecordCompositorAnimationFailureReasons(
CompositorAnimations::FailureReasons failure_reasons) {
// UMA_HISTOGRAM_ENUMERATION requires that the enum_max must be strictly
@@ -120,22 +162,22 @@ Animation* Animation::Create(AnimationEffect* effect,
AnimationTimeline* timeline,
ExceptionState& exception_state) {
DCHECK(timeline);
- if (!timeline->IsDocumentTimeline() && !timeline->IsScrollTimeline()) {
+ if (!IsA<DocumentTimeline>(timeline) && !timeline->IsScrollTimeline()) {
exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
"Invalid timeline. Animation requires a "
"DocumentTimeline or ScrollTimeline");
return nullptr;
}
- DCHECK(timeline->IsDocumentTimeline() || timeline->IsScrollTimeline());
+ DCHECK(IsA<DocumentTimeline>(timeline) || timeline->IsScrollTimeline());
- return MakeGarbageCollected<Animation>(
- timeline->GetDocument()->ContextDocument(), timeline, effect);
+ auto* context = timeline->GetDocument()->GetExecutionContext();
+ return MakeGarbageCollected<Animation>(context, timeline, effect);
}
Animation* Animation::Create(ExecutionContext* execution_context,
AnimationEffect* effect,
ExceptionState& exception_state) {
- Document* document = To<Document>(execution_context);
+ Document* document = To<LocalDOMWindow>(execution_context)->document();
return Create(effect, &document->Timeline(), exception_state);
}
@@ -155,8 +197,7 @@ Animation* Animation::Create(ExecutionContext* execution_context,
Animation::Animation(ExecutionContext* execution_context,
AnimationTimeline* timeline,
AnimationEffect* content)
- : ContextLifecycleObserver(execution_context),
- internal_play_state_(kIdle),
+ : ExecutionContextLifecycleObserver(execution_context),
reported_play_state_(kIdle),
playback_rate_(1),
start_time_(),
@@ -164,7 +205,7 @@ Animation::Animation(ExecutionContext* execution_context,
sequence_number_(NextSequenceNumber()),
content_(content),
timeline_(timeline),
- paused_(false),
+ replace_state_(kActive),
is_paused_for_testing_(false),
is_composited_animation_disabled_for_testing_(false),
pending_pause_(false),
@@ -176,8 +217,6 @@ Animation::Animation(ExecutionContext* execution_context,
compositor_state_(nullptr),
compositor_pending_(false),
compositor_group_(0),
- current_time_pending_(false),
- state_is_being_updated_(false),
effect_suppressed_(false) {
if (content_) {
if (content_->GetAnimation()) {
@@ -186,14 +225,15 @@ Animation::Animation(ExecutionContext* execution_context,
}
content_->Attach(this);
}
- document_ =
- timeline_ ? timeline_->GetDocument() : To<Document>(execution_context);
+ document_ = timeline_ ? timeline_->GetDocument()
+ : To<LocalDOMWindow>(execution_context)->document();
DCHECK(document_);
- TickingTimeline().AnimationAttached(this);
- if (timeline_ && timeline_->IsScrollTimeline())
+ if (timeline_)
timeline_->AnimationAttached(this);
- AttachCompositorTimeline();
+ else
+ document_->Timeline().AnimationAttached(this);
+
probe::DidCreateAnimation(document_, sequence_number_);
}
@@ -203,7 +243,7 @@ Animation::~Animation() {
}
void Animation::Dispose() {
- if (timeline_ && timeline_->IsScrollTimeline())
+ if (timeline_)
timeline_->AnimationDetached(this);
DestroyCompositorAnimation();
// If the DocumentTimeline and its Animation objects are
@@ -221,38 +261,21 @@ bool Animation::Limited(base::Optional<double> current_time) const {
(EffectivePlaybackRate() > 0 && current_time >= EffectEnd());
}
-Document* Animation::GetDocument() {
+Document* Animation::GetDocument() const {
return document_;
}
-double Animation::TimelineTime() const {
- if (timeline_)
- return timeline_->CurrentTime().value_or(NullValue());
- return NullValue();
-}
-
-DocumentTimeline& Animation::TickingTimeline() {
- // Active animations are tracked and ticked through the timeline attached to
- // the animation's document.
- // TODO(crbug.com/916117): Reconsider how animations are tracked and ticked.
- return document_->Timeline();
+base::Optional<double> Animation::TimelineTime() const {
+ return timeline_ ? timeline_->CurrentTime() : base::nullopt;
}
// https://drafts.csswg.org/web-animations/#setting-the-current-time-of-an-animation.
-void Animation::setCurrentTime(double new_current_time,
- bool is_null,
- ExceptionState& exception_state) {
- // TODO(crbug.com/916117): Implement setting current time for scroll-linked
- // animations.
- if (timeline_ && timeline_->IsScrollTimeline()) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kNotSupportedError,
- "Scroll-linked WebAnimation currently does not support setting"
- " current time.");
- return;
- }
-
- if (is_null) {
+void Animation::setCurrentTimeForBinding(
+ base::Optional<double> new_current_time,
+ ExceptionState& exception_state) {
+ // TODO(crbug.com/924159): Update this after we add support for inactive
+ // timelines and unresolved timeline.currentTime
+ if (!new_current_time) {
// If the current time is resolved, then throw a TypeError.
if (CurrentTimeInternal()) {
exception_state.ThrowTypeError(
@@ -261,11 +284,11 @@ void Animation::setCurrentTime(double new_current_time,
return;
}
- SetCurrentTimeInternal(MillisecondsToSeconds(new_current_time));
+ SetCurrentTimeInternal(MillisecondsToSeconds(new_current_time.value()));
// Synchronously resolve pending pause task.
if (pending_pause_) {
- hold_time_ = MillisecondsToSeconds(new_current_time);
+ hold_time_ = MillisecondsToSeconds(new_current_time.value());
ApplyPendingPlaybackRate();
start_time_ = base::nullopt;
pending_pause_ = false;
@@ -273,22 +296,31 @@ void Animation::setCurrentTime(double new_current_time,
ResolvePromiseMaybeAsync(ready_promise_.Get());
}
- // TODO(crbug.com/960944): Deprecate use of legacy flags.
- if (PlayStateInternal() == kIdle)
- paused_ = true;
- current_time_pending_ = false;
- internal_play_state_ = kUnset;
-
// Update the finished state.
UpdateFinishedState(UpdateType::kDiscontinuous, NotificationType::kAsync);
SetCompositorPending(/*effect_changed=*/false);
- internal_play_state_ = CalculateExtendedPlayState();
// Notify of potential state change.
NotifyProbe();
}
+void Animation::setCurrentTimeForBinding(double new_current_time,
+ bool is_null,
+ ExceptionState& exception_state) {
+ setCurrentTimeForBinding(
+ is_null ? base::nullopt : base::make_optional(new_current_time),
+ exception_state);
+}
+
+void Animation::setCurrentTime(double new_current_time,
+ bool is_null,
+ ExceptionState& exception_state) {
+ setCurrentTimeForBinding(
+ is_null ? base::nullopt : base::make_optional(new_current_time),
+ exception_state);
+}
+
// https://drafts.csswg.org/web-animations/#setting-the-current-time-of-an-animation
// See steps for silently setting the current time. The preliminary step of
// handling an unresolved time are to be handled by the caller.
@@ -317,69 +349,10 @@ void Animation::SetCurrentTimeInternal(double new_current_time) {
SetOutdated();
}
-// TODO(crbug.com/960944): Deprecate. This method is only called by methods that
-// are pending refactoring to align with the web-animation spec.
-void Animation::SetCurrentTimeInternal(double new_current_time,
- TimingUpdateReason reason) {
- DCHECK(std::isfinite(new_current_time));
-
- bool outdated = false;
- bool is_limited = Limited(new_current_time);
- bool is_held = paused_ || !playback_rate_ || is_limited || !start_time_;
- if (is_held) {
- // We only need to update the animation if the seek changes the hold time.
- if (!hold_time_ || hold_time_ != new_current_time)
- outdated = true;
- hold_time_ = new_current_time;
- if (paused_ || !playback_rate_) {
- start_time_ = base::nullopt;
- } else if (is_limited && !start_time_ &&
- reason == kTimingUpdateForAnimationFrame) {
- start_time_ = CalculateStartTime(new_current_time);
- }
- } else {
- hold_time_ = base::nullopt;
- start_time_ = CalculateStartTime(new_current_time);
- finished_ = false;
- outdated = true;
- }
-
- previous_current_time_ = base::nullopt;
-
- if (outdated) {
- SetOutdated();
- }
-}
-
-// Update timing to reflect updated animation clock due to tick
-void Animation::UpdateCurrentTimingState(TimingUpdateReason reason) {
- bool idle = internal_play_state_ == kIdle;
- bool has_active_timeline = timeline_ && timeline_->IsActive();
- if (idle || !has_active_timeline || !playback_rate_)
- return;
-
- if (hold_time_) {
- base::Optional<double> new_current_time = hold_time_;
- if (internal_play_state_ == kFinished && start_time_ && timeline_) {
- // Add hystersis due to floating point error accumulation
- base::Optional<double> current_time = CalculateCurrentTime();
- DCHECK(current_time);
- if (!Limited(current_time.value() + 0.001 * playback_rate_)) {
- // The current time became unlimited, eg. due to a backwards
- // seek of the timeline.
- new_current_time = current_time;
- } else if (!Limited(hold_time_)) {
- // The hold time became unlimited, eg. due to the effect
- // becoming longer.
- new_current_time =
- clampTo<double>(current_time.value(), 0, EffectEnd());
- }
- }
- DCHECK(new_current_time);
- SetCurrentTimeInternal(new_current_time.value(), reason);
- } else if (Limited(CalculateCurrentTime())) {
- hold_time_ = playback_rate_ < 0 ? 0 : EffectEnd();
- }
+base::Optional<double> Animation::startTime() const {
+ return start_time_
+ ? base::make_optional(SecondsToMilliseconds(start_time_.value()))
+ : base::nullopt;
}
double Animation::startTime(bool& is_null) const {
@@ -388,19 +361,8 @@ double Animation::startTime(bool& is_null) const {
return result.value_or(0);
}
-base::Optional<double> Animation::startTime() const {
- return start_time_ ? base::make_optional(start_time_.value() * 1000)
- : base::nullopt;
-}
-
-double Animation::currentTime(bool& is_null) {
- double result = currentTime();
- is_null = std::isnan(result);
- return result;
-}
-
// https://drafts.csswg.org/web-animations/#the-current-time-of-an-animation
-double Animation::currentTime() {
+base::Optional<double> Animation::currentTimeForBinding() const {
// 1. If the animation’s hold time is resolved,
// The current time is the animation’s hold time.
if (hold_time_.has_value())
@@ -411,23 +373,38 @@ double Animation::currentTime() {
// * the associated timeline is inactive, or
// * the animation’s start time is unresolved.
// The current time is an unresolved time value.
- if (!timeline_ || !timeline_->IsActive() || !start_time_) {
- return NullValue();
- }
+ if (!timeline_ || !timeline_->IsActive() || !start_time_)
+ return base::nullopt;
// 3. Otherwise,
// current time = (timeline time - start time) × playback rate
base::Optional<double> timeline_time = timeline_->CurrentTimeSeconds();
- // TODO(crbug.com/916117): Handle NaN values for scroll linked animations.
- if (!timeline_time) {
- DCHECK(timeline_->IsScrollTimeline());
- return 0;
- }
+
+ // An active timeline should always have a value, and since inactive timeline
+ // is handled in step 2 above, make sure that timeline_time has a value.
+ DCHECK(timeline_time.has_value());
+
double current_time =
(timeline_time.value() - start_time_.value()) * playback_rate_;
return SecondsToMilliseconds(current_time);
}
+double Animation::currentTimeForBinding(bool& is_null) {
+ base::Optional<double> result = currentTimeForBinding();
+ is_null = !result;
+ return result.value_or(0);
+}
+
+double Animation::currentTime() const {
+ return currentTimeForBinding().value_or(Timing::NullValue());
+}
+
+double Animation::currentTime(bool& is_null) {
+ base::Optional<double> result = currentTimeForBinding();
+ is_null = !result;
+ return result.value_or(0);
+}
+
base::Optional<double> Animation::CurrentTimeInternal() const {
return hold_time_ ? hold_time_ : CalculateCurrentTime();
}
@@ -438,10 +415,19 @@ base::Optional<double> Animation::UnlimitedCurrentTime() const {
: CalculateCurrentTime();
}
+String Animation::playState() const {
+ return PlayStateString();
+}
+
bool Animation::PreCommit(
int compositor_group,
const PaintArtifactCompositor* paint_artifact_compositor,
bool start_on_compositor) {
+ // TODO(crbug.com/916117): Revisit this condition as part of handling
+ // inactive timelines work.
+ if (timeline_ && timeline_->IsScrollTimeline() && !timeline_->IsActive())
+ return false;
+
bool soft_change =
compositor_state_ &&
(Paused() || compositor_state_->playback_rate != EffectivePlaybackRate());
@@ -503,6 +489,71 @@ void Animation::PostCommit(double timeline_time) {
}
}
+bool Animation::HasLowerCompositeOrdering(
+ const Animation* animation1,
+ const Animation* animation2,
+ CompareAnimationsOrdering compare_animation_type) {
+ AnimationClassPriority priority1 = AnimationPriority(*animation1);
+ AnimationClassPriority priority2 = AnimationPriority(*animation2);
+ if (priority1 != priority2)
+ return priority1 < priority2;
+
+ // If the the animation class is CssAnimation or CssTransition, then first
+ // compare the owning element of animation1 and animation2, sort two of them
+ // by tree order of their conrresponding owning element
+ // The specs:
+ // https://drafts.csswg.org/css-animations-2/#animation-composite-order
+ // https://drafts.csswg.org/css-transitions-2/#animation-composite-order
+ if (priority1 != kDefaultPriority && animation1->effect() &&
+ animation2->effect()) {
+ // TODO(crbug.com/1043778): Implement and use OwningElement on CSSAnimation
+ // and CSSTransition.
+ auto* effect1 = DynamicTo<KeyframeEffect>(animation1->effect());
+ auto* effect2 = DynamicTo<KeyframeEffect>(animation2->effect());
+ Element* target1 = effect1->target();
+ Element* target2 = effect2->target();
+
+ // The tree position comparison would take a longer time, thus affec the
+ // performance. We only do it when it comes to getAnimation.
+ if (*target1 != *target2) {
+ if (compare_animation_type == CompareAnimationsOrdering::kTreeOrder) {
+ return target1->compareDocumentPosition(target2) &
+ Node::kDocumentPositionFollowing;
+ } else {
+ return target1 < target2;
+ }
+ }
+
+ // A pseudo-element has a higher composite ordering than its originating
+ // element, but lower than the originating element's children.
+ // Two pseudo-elements sharing the same originating element are sorted
+ // as follows:
+ // ::marker
+ // ::before
+ // other pseudo-elements (ordered by selector)
+ // ::after
+ const String& pseudo1 = effect1->pseudoElement();
+ const String& pseudo2 = effect2->pseudoElement();
+ PseudoPriority priority1 = ConvertStringtoPriority(pseudo1);
+ PseudoPriority priority2 = ConvertStringtoPriority(pseudo2);
+
+ if (priority1 != priority2)
+ return priority1 < priority2;
+ if (priority1 == kOther && pseudo1 != pseudo2)
+ return CodeUnitCompareLessThan(pseudo1, pseudo2);
+
+ // For two animatiions with the same target (including the pseudo-element
+ // selector) compare the SequenceNumber for now.
+ // TODO(crbug.com/1045835): Sort animation1 and animation2 based on their
+ // position in the computed value of "animation-name" property for
+ // CSSAnimations and transition property for CSSTransitions.
+ return animation1->SequenceNumber() < animation2->SequenceNumber();
+ }
+ // If the anmiations are not-CSS WebAnimation just compare them via generation
+ // time/ sequence number.
+ return animation1->SequenceNumber() < animation2->SequenceNumber();
+}
+
void Animation::NotifyReady(double ready_time) {
// Complete the pending updates prior to updating the compositor state in
// order to ensure a correct start time for the compositor state without the
@@ -518,15 +569,6 @@ void Animation::NotifyReady(double ready_time) {
compositor_state_->start_time = start_time_;
}
- // Avoid marking this animation as outdated needlessly when a start time is
- // notified. TODO(crbug.com/960944): Remove the need for clearing the
- // outdated flag once PlayStateUpdateScope and UpdateCurrentTimingState have
- // been removed.
- ClearOutdated();
-
- // TODO(crbug.com/960944): deprecate use of these flags.
- internal_play_state_ = CalculateExtendedPlayState();
-
// Notify of change to play state.
NotifyProbe();
}
@@ -535,22 +577,13 @@ void Animation::NotifyReady(double ready_time) {
// Refer to Step 8.3 'pending play task' in
// https://drafts.csswg.org/web-animations/#playing-an-animation-section.
void Animation::CommitPendingPlay(double ready_time) {
- DCHECK(!IsNull(ready_time));
+ DCHECK(!Timing::IsNull(ready_time));
DCHECK(start_time_ || hold_time_);
DCHECK(pending_play_);
pending_play_ = false;
- current_time_pending_ = false;
// Update hold and start time.
- if (timeline_ && timeline_->IsScrollTimeline()) {
- // Special handling for scroll timelines. The start time is always zero
- // when the animation is playing. This forces the current time to match
- // the timeline time. TODO(crbug.com/916117): Resolve in spec.
- start_time_ = 0;
- ApplyPendingPlaybackRate();
- if (playback_rate_ != 0)
- hold_time_ = base::nullopt;
- } else if (hold_time_) {
+ if (hold_time_) {
// A: If animation’s hold time is resolved,
// A.1. Apply any pending playback rate on animation.
// A.2. Let new start time be the result of evaluating:
@@ -606,9 +639,6 @@ void Animation::CommitPendingPlay(double ready_time) {
// Refer to step 7 'pending pause task' in
// https://drafts.csswg.org/web-animations-1/#pausing-an-animation-section
void Animation::CommitPendingPause(double ready_time) {
- // TODO(crbug.com/960944): Deprecate.
- internal_play_state_ = kUnset;
-
DCHECK(pending_pause_);
pending_pause_ = false;
@@ -639,11 +669,11 @@ void Animation::CommitPendingPause(double ready_time) {
bool Animation::Affects(const Element& element,
const CSSProperty& property) const {
- if (!content_ || !content_->IsKeyframeEffect())
+ const auto* effect = DynamicTo<KeyframeEffect>(content_.Get());
+ if (!effect)
return false;
- const KeyframeEffect* effect = ToKeyframeEffect(content_.Get());
- return (effect->target() == &element) &&
+ return (effect->EffectTarget() == &element) &&
effect->Affects(PropertyHandle(property));
}
@@ -664,17 +694,18 @@ base::Optional<double> Animation::CalculateCurrentTime() const {
if (!start_time_ || !timeline_ || !timeline_->IsActive())
return base::nullopt;
base::Optional<double> timeline_time = timeline_->CurrentTimeSeconds();
- // TODO(crbug.com/916117): Handle NaN time for scroll-linked animations.
+
if (!timeline_time) {
- DCHECK(timeline_->IsScrollTimeline());
+ // timeline_time can be null only when the timeline is inactive
+ DCHECK(!timeline_->IsActive());
return base::nullopt;
}
+
return (timeline_time.value() - start_time_.value()) * playback_rate_;
}
// https://drafts.csswg.org/web-animations/#setting-the-start-time-of-an-animation
-void Animation::setStartTime(double start_time_ms,
- bool is_null,
+void Animation::setStartTime(base::Optional<double> start_time_ms,
ExceptionState& exception_state) {
// TODO(crbug.com/916117): Implement setting start time for scroll-linked
// animations.
@@ -701,7 +732,7 @@ void Animation::setStartTime(double start_time_ms,
// This preserves the invariant that when we don’t have an active timeline it
// is only possible to set either the start time or the animation’s current
// time.
- if (!timeline_time && !is_null)
+ if (!timeline_time && start_time_ms)
hold_time_ = base::nullopt;
// 3. Let previous current time be animation’s current time.
@@ -712,8 +743,8 @@ void Animation::setStartTime(double start_time_ms,
// 5. Set animation’s start time to new start time.
base::Optional<double> new_start_time;
- if (!is_null)
- new_start_time = MillisecondsToSeconds(start_time_ms);
+ if (start_time_ms)
+ new_start_time = MillisecondsToSeconds(start_time_ms.value());
start_time_ = new_start_time;
// 6. Update animation’s hold time based on the first matching condition from
@@ -731,14 +762,9 @@ void Animation::setStartTime(double start_time_ms,
hold_time_ = previous_current_time;
}
- // TODO(crbug.com/960944): prune use of legacy flags.
- paused_ = hold_time_.has_value();
- current_time_pending_ = false;
- internal_play_state_ = kUnset;
-
// 7. If animation has a pending play task or a pending pause task, cancel
// that task and resolve animation’s current ready promise with animation.
- if (pending()) {
+ if (PendingInternal()) {
pending_pause_ = false;
pending_play_ = false;
if (ready_promise_ &&
@@ -751,9 +777,6 @@ void Animation::setStartTime(double start_time_ms,
// synchronously notify flag set to false (async).
UpdateFinishedState(UpdateType::kDiscontinuous, NotificationType::kAsync);
- // TODO(crbug.com/960944): prune use of legacy flags.
- internal_play_state_ = CalculateExtendedPlayState();
-
// Update user agent.
base::Optional<double> new_current_time = CurrentTimeInternal();
if (previous_current_time != new_current_time) {
@@ -768,6 +791,13 @@ void Animation::setStartTime(double start_time_ms,
NotifyProbe();
}
+void Animation::setStartTime(double start_time_ms,
+ bool is_null,
+ ExceptionState& exception_state) {
+ setStartTime(is_null ? base::nullopt : base::make_optional(start_time_ms),
+ exception_state);
+}
+
// https://drafts.csswg.org/web-animations-1/#setting-the-associated-effect
void Animation::setEffect(AnimationEffect* new_effect) {
// 1. Let old effect be the current associated effect of animation, if any.
@@ -806,11 +836,72 @@ void Animation::setEffect(AnimationEffect* new_effect) {
SetCompositorPending(/*effect_change=*/true);
- // TODO(crbug.com/960944): Deprecate use of these flags.
- internal_play_state_ = CalculateExtendedPlayState();
-
// Notify of a potential state change.
NotifyProbe();
+
+ // The effect is no longer associated with CSS properties.
+ if (new_effect) {
+ new_effect->SetIgnoreCssTimingProperties();
+ if (KeyframeEffect* keyframe_effect = DynamicTo<KeyframeEffect>(new_effect))
+ keyframe_effect->SetIgnoreCSSKeyframes();
+ }
+
+ // The remaining steps are for handling CSS animation and transition events.
+ // Both use an event delegate to dispatch events, which must be reattached to
+ // the new effect.
+
+ // When the animation no longer has an associated effect, calls to
+ // Animation::Update will no longer update the animation timing and,
+ // consequently, do not trigger animation or transition events.
+ // Each transitionrun or transitionstart requires a corresponding
+ // transitionend or transitioncancel.
+ // https://drafts.csswg.org/css-transitions-2/#event-dispatch
+ // Similarly, each animationstart requires a corresponding animationend or
+ // animationcancel.
+ // https://drafts.csswg.org/css-animations-2/#event-dispatch
+ AnimationEffect::EventDelegate* old_event_delegate =
+ old_effect ? old_effect->GetEventDelegate() : nullptr;
+ if (!new_effect && old_effect && old_event_delegate) {
+ // If the animation|transition has no target effect, the timing phase is set
+ // according to the first matching condition from below:
+ // If the current time is unresolved,
+ // The timing phase is ‘idle’.
+ // If current time < 0,
+ // The timing phase is ‘before’.
+ // Otherwise,
+ // The timing phase is ‘after’.
+ base::Optional<double> current_time = CurrentTimeInternal();
+ Timing::Phase phase;
+ if (!current_time)
+ phase = Timing::kPhaseNone;
+ else if (current_time < 0)
+ phase = Timing::kPhaseBefore;
+ else
+ phase = Timing::kPhaseAfter;
+ old_event_delegate->OnEventCondition(*old_effect, phase);
+ return;
+ }
+
+ if (!new_effect || !old_effect)
+ return;
+
+ // Use the original target for event targeting.
+ Element* target = To<KeyframeEffect>(old_effect)->target();
+ if (!target)
+ return;
+
+ // Attach an event delegate to the new effect.
+ AnimationEffect::EventDelegate* new_event_delegate =
+ CreateEventDelegate(target, old_event_delegate);
+ new_effect->SetEventDelegate(new_event_delegate);
+
+ // Force an update to the timing model to ensure correct ordering of
+ // animation or transition events.
+ Update(kTimingUpdateOnDemand);
+}
+
+String Animation::PlayStateString() const {
+ return PlayStateString(CalculateAnimationPlayState());
}
const char* Animation::PlayStateString(AnimationPlayState play_state) {
@@ -831,25 +922,6 @@ const char* Animation::PlayStateString(AnimationPlayState play_state) {
}
}
-// TODO(crbug.com/960944): Deprecate.
-Animation::AnimationPlayState Animation::PlayStateInternal() const {
- DCHECK_NE(internal_play_state_, kUnset);
- return internal_play_state_;
-}
-
-// TODO(crbug.com/960944): Deprecate.
-Animation::AnimationPlayState Animation::CalculateExtendedPlayState() const {
- if (paused_ && !current_time_pending_)
- return kPaused;
- if (internal_play_state_ == kIdle)
- return kIdle;
- if (current_time_pending_ || (!start_time_ && playback_rate_ != 0))
- return kPending;
- if (Limited())
- return kFinished;
- return kRunning;
-}
-
// https://drafts.csswg.org/web-animations/#play-states
Animation::AnimationPlayState Animation::CalculateAnimationPlayState() const {
// 1. All of the following conditions are true:
@@ -857,7 +929,7 @@ Animation::AnimationPlayState Animation::CalculateAnimationPlayState() const {
// * animation does not have either a pending play task or a pending pause
// task,
// then idle.
- if (!CurrentTimeInternal() && !pending())
+ if (!CurrentTimeInternal() && !PendingInternal())
return kIdle;
// 2. Either of the following conditions are true:
@@ -881,17 +953,36 @@ Animation::AnimationPlayState Animation::CalculateAnimationPlayState() const {
return kRunning;
}
-bool Animation::pending() const {
+bool Animation::PendingInternal() const {
return pending_pause_ || pending_play_;
}
+bool Animation::pending() const {
+ return PendingInternal();
+}
+
// https://drafts.csswg.org/web-animations-1/#reset-an-animations-pending-tasks.
void Animation::ResetPendingTasks() {
- ApplyPendingPlaybackRate();
- pending_pause_ = false;
+ // 1. If animation does not have a pending play task or a pending pause task,
+ // abort this procedure.
+ if (!PendingInternal())
+ return;
+
+ // 2. If animation has a pending play task, cancel that task.
+ // 3. If animation has a pending pause task, cancel that task.
pending_play_ = false;
- // TODO(crbug.com/960944): Fix handling of ready promise to align with the
- // web-animtions spec.
+ pending_pause_ = false;
+
+ // 4. Apply any pending playback rate on animation.
+ ApplyPendingPlaybackRate();
+
+ // 5. Reject animation’s current ready promise with a DOMException named
+ // "AbortError".
+ // 6. Let animation’s current ready promise be the result of creating a new
+ // resolved Promise object with value animation in the relevant Realm of
+ // animation.
+ if (ready_promise_)
+ RejectAndResetPromiseMaybeAsync(ready_promise_.Get());
}
// ----------------------------------------------
@@ -952,10 +1043,6 @@ void Animation::pause(ExceptionState& exception_state) {
pending_pause_ = true;
pending_play_ = false;
- // TODO(crbug.com/958433): Deprecate.
- paused_ = true;
- internal_play_state_ = kUnset;
-
SetOutdated();
SetCompositorPending(false);
@@ -964,9 +1051,6 @@ void Animation::pause(ExceptionState& exception_state) {
// notify flag set to false.
UpdateFinishedState(UpdateType::kContinuous, NotificationType::kAsync);
- // TODO(crbug.com/958433): Deprecate.
- internal_play_state_ = CalculateExtendedPlayState();
-
NotifyProbe();
}
@@ -1022,9 +1106,24 @@ void Animation::PlayInternal(AutoRewind auto_rewind,
// Set animation’s hold time to zero.
double effective_playback_rate = EffectivePlaybackRate();
base::Optional<double> current_time = CurrentTimeInternal();
+
+ // TODO(crbug.com/1012073): This should be able to be extracted into a
+ // function in AnimationTimeline that each child class can override for their
+ // own special behavior.
+ double initial_hold_time = 0;
+ if (timeline_ && timeline_->IsScrollTimeline() && timeline_->IsActive()) {
+ base::Optional<double> timeline_time = timeline_->CurrentTimeSeconds();
+ if (timeline_time) {
+ // TODO(crbug.com/924159): Once inactive timelines are supported we need
+ // to re-evaluate if it is desired behavior to adjust the hold time when
+ // playback rate is set before play().
+ initial_hold_time = timeline_time.value() * effective_playback_rate;
+ }
+ }
+
if (effective_playback_rate > 0 && auto_rewind == AutoRewind::kEnabled &&
(!current_time || current_time < 0 || current_time >= EffectEnd())) {
- hold_time_ = 0;
+ hold_time_ = initial_hold_time;
} else if (effective_playback_rate < 0 &&
auto_rewind == AutoRewind::kEnabled &&
(!current_time || current_time <= 0 ||
@@ -1035,9 +1134,9 @@ void Animation::PlayInternal(AutoRewind auto_rewind,
"Cannot play reversed Animation with infinite target effect end.");
return;
}
- hold_time_ = EffectEnd();
+ hold_time_ = initial_hold_time + EffectEnd();
} else if (effective_playback_rate == 0 && !current_time) {
- hold_time_ = 0;
+ hold_time_ = initial_hold_time;
}
// 4. If animation has a pending play task or a pending pause task,
@@ -1068,9 +1167,6 @@ void Animation::PlayInternal(AutoRewind auto_rewind,
// 8. Schedule a task to run as soon as animation is ready.
pending_play_ = true;
finished_ = false;
- // TODO(crbug.com/960944): Deprecate paused_ and internal_play_state_ flags.
- paused_ = false;
- internal_play_state_ = kUnset;
SetOutdated();
SetCompositorPending(/*effect_changed=*/false);
@@ -1080,9 +1176,6 @@ void Animation::PlayInternal(AutoRewind auto_rewind,
// Boolean valued arguments replaced with enumerated values for clarity.
UpdateFinishedState(UpdateType::kContinuous, NotificationType::kAsync);
- // TODO(crbug.com/960944): Deprecate.
- internal_play_state_ = CalculateExtendedPlayState();
-
// Notify change to pending play or finished state.
NotifyProbe();
}
@@ -1118,19 +1211,14 @@ void Animation::reverse(ExceptionState& exception_state) {
if (pending_playback_rate_.value() == -0)
pending_playback_rate_ = 0;
- // TODO(crbug.com/960944): Deprecate use of this flag.
- current_time_pending_ = true;
-
// 4. Run the steps to play an animation for animation with the auto-rewind
// flag set to true.
// If the steps to play an animation throw an exception, set animation’s
// pending playback rate to original pending playback rate and propagate
// the exception.
PlayInternal(AutoRewind::kEnabled, exception_state);
- if (exception_state.HadException()) {
+ if (exception_state.HadException())
pending_playback_rate_ = original_pending_playback_rate;
- current_time_pending_ = false;
- }
}
// ----------------------------------------------
@@ -1173,15 +1261,8 @@ void Animation::finish(ExceptionState& exception_state) {
ResolvePromiseMaybeAsync(ready_promise_.Get());
}
- // TODO(crbug.com/960944): Cleanup use of legacy flags.
- paused_ = false;
- current_time_pending_ = false;
- internal_play_state_ = kUnset;
- ResetPendingTasks();
-
SetOutdated();
UpdateFinishedState(UpdateType::kDiscontinuous, NotificationType::kSync);
- internal_play_state_ = CalculateExtendedPlayState();
// Notify of change to finished state.
NotifyProbe();
@@ -1201,8 +1282,8 @@ void Animation::UpdateFinishedState(UpdateType update_type,
if (unconstrained_current_time && start_time_ && !pending_play_ &&
!pending_pause_) {
// Can seek outside the bounds of the active effect. Set the hold time to
- // the unconstrained value of the current time in the even that this update
- // this the result of explicitly setting the current time and the new time
+ // the unconstrained value of the current time in the event that this update
+ // is the result of explicitly setting the current time and the new time
// is out of bounds. An update due to a time tick should not snap the hold
// value back to the boundary if previously set outside the normal effect
// boundary. The value of previous current time is used to retain this
@@ -1266,7 +1347,7 @@ void Animation::AsyncFinishMicrotask() {
// transition was only temporary.
if (pending_finish_notification_) {
// A pending play or pause must resolve before the finish promise.
- if (pending() && timeline_)
+ if (PendingInternal() && timeline_)
NotifyReady(timeline_->CurrentTimeSeconds().value_or(0));
CommitFinishNotification();
}
@@ -1292,9 +1373,6 @@ void Animation::CommitFinishNotification() {
// 3. Create an AnimationPlaybackEvent, finishEvent.
QueueFinishedEvent();
-
- // TODO(crbug.com/960944) Deprecate following flags.
- internal_play_state_ = kFinished;
}
// https://drafts.csswg.org/web-animations/#setting-the-playback-rate-of-an-animation
@@ -1320,7 +1398,7 @@ void Animation::updatePlaybackRate(double playback_rate,
//
// 3a If animation has a pending play task or a pending pause task,
// Abort these steps.
- if (pending())
+ if (PendingInternal())
return;
switch (play_state) {
@@ -1353,18 +1431,21 @@ void Animation::updatePlaybackRate(double playback_rate,
timeline_ ? timeline_->CurrentTimeSeconds() : base::nullopt;
if (playback_rate) {
if (timeline_time) {
- start_time_ =
- (timeline_time && unconstrained_current_time)
- ? ValueOrUnresolved((timeline_time.value() -
- unconstrained_current_time.value()) /
- playback_rate)
- : base::nullopt;
+ start_time_ = (timeline_time && unconstrained_current_time)
+ ? base::make_optional<double>(
+ (timeline_time.value() -
+ unconstrained_current_time.value()) /
+ playback_rate)
+ : base::nullopt;
}
} else {
start_time_ = timeline_time;
}
ApplyPendingPlaybackRate();
UpdateFinishedState(UpdateType::kContinuous, NotificationType::kAsync);
+ SetCompositorPending(false);
+ SetOutdated();
+ NotifyProbe();
break;
}
@@ -1372,8 +1453,6 @@ void Animation::updatePlaybackRate(double playback_rate,
// Run the procedure to play an animation for animation with the
// auto-rewind flag set to false.
case kRunning:
- // TODO(crbug.com/960944): Deprecate use of current_time_pending_ flag.
- current_time_pending_ = true;
PlayInternal(AutoRewind::kDisabled, exception_state);
break;
@@ -1386,8 +1465,10 @@ void Animation::updatePlaybackRate(double playback_rate,
ScriptPromise Animation::finished(ScriptState* script_state) {
if (!finished_promise_) {
finished_promise_ = MakeGarbageCollected<AnimationPromise>(
- ExecutionContext::From(script_state), this,
- AnimationPromise::kFinished);
+ ExecutionContext::From(script_state));
+ // Do not report unhandled rejections of the finished promise.
+ finished_promise_->MarkAsHandled();
+
// Defer resolving the finished promise if the finish notification task is
// pending. The finished state could change before the next microtask
// checkpoint.
@@ -1399,10 +1480,17 @@ ScriptPromise Animation::finished(ScriptState* script_state) {
}
ScriptPromise Animation::ready(ScriptState* script_state) {
+ // Check for a pending state change prior to checking the ready promise, since
+ // the pending check may force a style flush, which in turn could trigger a
+ // reset of the ready promise when resolving a change to the
+ // animationPlayState style.
+ bool is_pending = pending();
if (!ready_promise_) {
ready_promise_ = MakeGarbageCollected<AnimationPromise>(
- ExecutionContext::From(script_state), this, AnimationPromise::kReady);
- if (!pending())
+ ExecutionContext::From(script_state));
+ // Do not report unhandled rejections of the ready promise.
+ ready_promise_->MarkAsHandled();
+ if (!is_pending)
ready_promise_->Resolve(this);
}
return ready_promise_->Promise(script_state->World());
@@ -1413,28 +1501,33 @@ const AtomicString& Animation::InterfaceName() const {
}
ExecutionContext* Animation::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
bool Animation::HasPendingActivity() const {
bool has_pending_promise =
finished_promise_ &&
- finished_promise_->GetState() == ScriptPromisePropertyBase::kPending;
+ finished_promise_->GetState() == AnimationPromise::kPending;
- return pending_finished_event_ || has_pending_promise ||
+ return pending_finished_event_ || pending_cancelled_event_ ||
+ pending_remove_event_ || has_pending_promise ||
(!finished_ && HasEventListeners(event_type_names::kFinish));
}
-void Animation::ContextDestroyed(ExecutionContext*) {
- PlayStateUpdateScope update_scope(*this, kTimingUpdateOnDemand);
-
+void Animation::ContextDestroyed() {
finished_ = true;
pending_finished_event_ = nullptr;
+ pending_cancelled_event_ = nullptr;
+ pending_remove_event_ = nullptr;
}
DispatchEventResult Animation::DispatchEventInternal(Event& event) {
if (pending_finished_event_ == &event)
pending_finished_event_ = nullptr;
+ if (pending_cancelled_event_ == &event)
+ pending_cancelled_event_ = nullptr;
+ if (pending_remove_event_ == &event)
+ pending_remove_event_ = nullptr;
return EventTargetWithInlineData::DispatchEventInternal(event);
}
@@ -1455,15 +1548,8 @@ void Animation::ApplyPendingPlaybackRate() {
void Animation::setPlaybackRate(double playback_rate,
ExceptionState& exception_state) {
- // TODO(crbug.com/916117): Implement setting playback rate for scroll-linked
- // animations.
- if (timeline_ && timeline_->IsScrollTimeline()) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kNotSupportedError,
- "Scroll-linked WebAnimation currently does not support setting"
- " playback rate.");
- return;
- }
+ // TODO(crbug.com/924159): Update this after we add support for inactive
+ // timelines and unresolved timeline.currentTime
base::Optional<double> start_time_before = start_time_;
@@ -1476,7 +1562,7 @@ void Animation::setPlaybackRate(double playback_rate,
pending_playback_rate_ = base::nullopt;
double previous_current_time = currentTime();
playback_rate_ = playback_rate;
- if (!IsNull(previous_current_time)) {
+ if (!Timing::IsNull(previous_current_time)) {
setCurrentTime(previous_current_time, false, exception_state);
}
@@ -1489,6 +1575,8 @@ void Animation::setPlaybackRate(double playback_rate,
}
SetCompositorPending(false);
+ SetOutdated();
+ NotifyProbe();
}
void Animation::ClearOutdated() {
@@ -1496,7 +1584,7 @@ void Animation::ClearOutdated() {
return;
outdated_ = false;
if (timeline_)
- TickingTimeline().ClearOutdatedAnimation(this);
+ timeline_->ClearOutdatedAnimation(this);
}
void Animation::SetOutdated() {
@@ -1504,12 +1592,12 @@ void Animation::SetOutdated() {
return;
outdated_ = true;
if (timeline_)
- TickingTimeline().SetOutdatedAnimation(this);
+ timeline_->SetOutdatedAnimation(this);
}
void Animation::ForceServiceOnNextFrame() {
if (timeline_)
- TickingTimeline().Wake();
+ timeline_->ScheduleServiceOnNextFrame();
}
CompositorAnimations::FailureReasons
@@ -1517,10 +1605,10 @@ Animation::CheckCanStartAnimationOnCompositor(
const PaintArtifactCompositor* paint_artifact_compositor) const {
CompositorAnimations::FailureReasons reasons =
CheckCanStartAnimationOnCompositorInternal();
- if (content_ && content_->IsKeyframeEffect()) {
- reasons |= ToKeyframeEffect(content_.Get())
- ->CheckCanStartAnimationOnCompositor(
- paint_artifact_compositor, playback_rate_);
+
+ if (auto* keyframe_effect = DynamicTo<KeyframeEffect>(content_.Get())) {
+ reasons |= keyframe_effect->CheckCanStartAnimationOnCompositor(
+ paint_artifact_compositor, playback_rate_);
}
return reasons;
}
@@ -1541,6 +1629,9 @@ Animation::CheckCanStartAnimationOnCompositorInternal() const {
if (EffectivePlaybackRate() == 0)
reasons |= CompositorAnimations::kInvalidAnimationOrEffect;
+ if (!CurrentTimeInternal())
+ reasons |= CompositorAnimations::kInvalidAnimationOrEffect;
+
// Cannot composite an infinite duration animation with a negative playback
// rate. TODO(crbug.com/1029167): Fix calculation of compositor timing to
// enable compositing provided the iteration duration is finite. Having an
@@ -1553,13 +1644,13 @@ Animation::CheckCanStartAnimationOnCompositorInternal() const {
// reason to composite it. Additionally, mutating the timeline playback rate
// is a debug feature available via devtools; we don't support this on the
// compositor currently and there is no reason to do so.
- if (!timeline_ || (timeline_->IsDocumentTimeline() &&
- ToDocumentTimeline(timeline_)->PlaybackRate() != 1))
+ auto* document_timeline = DynamicTo<DocumentTimeline>(*timeline_);
+ if (!document_timeline || document_timeline->PlaybackRate() != 1)
reasons |= CompositorAnimations::kInvalidAnimationOrEffect;
// An Animation without an effect cannot produce a visual, so there is no
// reason to composite it.
- if (!content_ || !content_->IsKeyframeEffect())
+ if (!IsA<KeyframeEffect>(content_.Get()))
reasons |= CompositorAnimations::kInvalidAnimationOrEffect;
// An Animation that is not playing will not produce a visual, so there is no
@@ -1578,7 +1669,7 @@ void Animation::StartAnimationOnCompositor(
const PaintArtifactCompositor* paint_artifact_compositor) {
DCHECK_EQ(CheckCanStartAnimationOnCompositor(paint_artifact_compositor),
CompositorAnimations::kNoFailure);
- DCHECK(timeline_->IsDocumentTimeline());
+ DCHECK(IsA<DocumentTimeline>(*timeline_));
bool reversed = EffectivePlaybackRate() < 0;
@@ -1591,30 +1682,31 @@ void Animation::StartAnimationOnCompositor(
// the playback rate preserve current time even if the start time is set.
// Asynchronous updates have an associated pending play or pending pause
// task associated with them.
- if (start_time_ && !pending()) {
- start_time =
- ToDocumentTimeline(timeline_)->ZeroTime().since_origin().InSecondsF() +
- start_time_.value();
+ if (start_time_ && !PendingInternal()) {
+ start_time = To<DocumentTimeline>(*timeline_)
+ .ZeroTime()
+ .since_origin()
+ .InSecondsF() +
+ start_time_.value();
if (reversed) {
start_time =
start_time.value() - (EffectEnd() / fabs(EffectivePlaybackRate()));
}
} else {
base::Optional<double> current_time = CurrentTimeInternal();
- if (current_time) {
- time_offset =
- reversed ? EffectEnd() - current_time.value() : current_time.value();
- time_offset = time_offset / fabs(EffectivePlaybackRate());
- } else {
- time_offset = NullValue();
- }
+ DCHECK(current_time);
+ time_offset =
+ reversed ? EffectEnd() - current_time.value() : current_time.value();
+ time_offset = time_offset / fabs(EffectivePlaybackRate());
}
- DCHECK(!start_time || !IsNull(start_time.value()));
+ DCHECK(!start_time || !Timing::IsNull(start_time.value()));
DCHECK_NE(compositor_group_, 0);
- DCHECK(ToKeyframeEffect(content_.Get()));
- ToKeyframeEffect(content_.Get())
- ->StartAnimationOnCompositor(compositor_group_, start_time, time_offset,
+ DCHECK(To<KeyframeEffect>(content_.Get()));
+ DCHECK(std::isfinite(time_offset));
+ To<KeyframeEffect>(content_.Get())
+ ->StartAnimationOnCompositor(compositor_group_, start_time,
+ base::TimeDelta::FromSecondsD(time_offset),
EffectivePlaybackRate());
}
@@ -1645,7 +1737,8 @@ void Animation::SetCompositorPending(bool effect_changed) {
// sync them. This can happen if the blink side animation was started, the
// compositor side hadn't started on its side yet, and then the blink side
// start time was cleared (e.g. by setting current time).
- if (pending() || !compositor_state_ || compositor_state_->effect_changed ||
+ if (PendingInternal() || !compositor_state_ ||
+ compositor_state_->effect_changed ||
compositor_state_->playback_rate != EffectivePlaybackRate() ||
compositor_state_->start_time != start_time_ ||
!compositor_state_->start_time || !start_time_) {
@@ -1656,7 +1749,7 @@ void Animation::SetCompositorPending(bool effect_changed) {
void Animation::CancelAnimationOnCompositor() {
if (HasActiveAnimationsOnCompositor()) {
- ToKeyframeEffect(content_.Get())
+ To<KeyframeEffect>(content_.Get())
->CancelAnimationOnCompositor(GetCompositorAnimation());
}
@@ -1666,22 +1759,22 @@ void Animation::CancelAnimationOnCompositor() {
void Animation::RestartAnimationOnCompositor() {
if (!HasActiveAnimationsOnCompositor())
return;
- if (ToKeyframeEffect(content_.Get())
+ if (To<KeyframeEffect>(content_.Get())
->CancelAnimationOnCompositor(GetCompositorAnimation()))
SetCompositorPending(true);
}
void Animation::CancelIncompatibleAnimationsOnCompositor() {
- if (content_ && content_->IsKeyframeEffect())
- ToKeyframeEffect(content_.Get())
- ->CancelIncompatibleAnimationsOnCompositor();
+ if (auto* keyframe_effect = DynamicTo<KeyframeEffect>(content_.Get()))
+ keyframe_effect->CancelIncompatibleAnimationsOnCompositor();
}
bool Animation::HasActiveAnimationsOnCompositor() {
- if (!content_ || !content_->IsKeyframeEffect())
+ auto* keyframe_effect = DynamicTo<KeyframeEffect>(content_.Get());
+ if (!keyframe_effect)
return false;
- return ToKeyframeEffect(content_.Get())->HasActiveAnimationsOnCompositor();
+ return keyframe_effect->HasActiveAnimationsOnCompositor();
}
// Update current time of the animation. Refer to step 1 in:
@@ -1737,8 +1830,9 @@ bool Animation::Update(TimingUpdateReason reason) {
void Animation::QueueFinishedEvent() {
const AtomicString& event_type = event_type_names::kFinish;
if (GetExecutionContext() && HasEventListeners(event_type)) {
- double event_current_time =
- SecondsToMilliseconds(CurrentTimeInternal().value_or(NullValue()));
+ base::Optional<double> event_current_time = CurrentTimeInternal();
+ if (event_current_time)
+ event_current_time = SecondsToMilliseconds(event_current_time.value());
// TODO(crbug.com/916117): Handle NaN values for scroll-linked animations.
pending_finished_event_ = MakeGarbageCollected<AnimationPlaybackEvent>(
event_type, event_current_time, TimelineTime());
@@ -1795,18 +1889,9 @@ base::Optional<AnimationTimeDelta> Animation::TimeToEffectChange() {
}
void Animation::cancel() {
- // TODO(crbug.com/916117): Get rid of internal_play_state_.
- internal_play_state_ = kUnset;
+ double current_time_before_cancel = CurrentTimeInternal().value_or(0);
AnimationPlayState initial_play_state = CalculateAnimationPlayState();
if (initial_play_state != kIdle) {
- if (pending()) {
- // TODO(crbug.com/916117): Rejecting the ready promise should be performed
- // inside reset pending tasks once aligned with the spec.
- // TODO(crbug.com/1013351): Add test for rejection and reset of cancel
- // promise. Requires further cleanup of PlayStateUpdateScope.
- if (ready_promise_)
- RejectAndResetPromiseMaybeAsync(ready_promise_.Get());
- }
ResetPendingTasks();
if (finished_promise_) {
@@ -1818,7 +1903,7 @@ void Animation::cancel() {
const AtomicString& event_type = event_type_names::kCancel;
if (GetExecutionContext() && HasEventListeners(event_type)) {
- double event_current_time = NullValue();
+ base::Optional<double> event_current_time = base::nullopt;
// TODO(crbug.com/916117): Handle NaN values for scroll-linked
// animations.
pending_cancelled_event_ = MakeGarbageCollected<AnimationPlaybackEvent>(
@@ -1836,39 +1921,23 @@ void Animation::cancel() {
hold_time_ = base::nullopt;
start_time_ = base::nullopt;
- // TODO(crbug.com/958433): Phase out the use of these variables, which are not
- // in the spec.
- paused_ = false;
- internal_play_state_ = kIdle;
- current_time_pending_ = false;
-
// Apply changes synchronously.
SetCompositorPending(/*effect_changed=*/false);
SetOutdated();
// Force dispatch of canceled event.
- ForceServiceOnNextFrame();
+ if (content_)
+ content_->SetCancelTime(current_time_before_cancel);
+ Update(kTimingUpdateOnDemand);
// Notify of change to canceled state.
NotifyProbe();
}
-void Animation::BeginUpdatingState() {
- // Nested calls are not allowed!
- DCHECK(!state_is_being_updated_);
- state_is_being_updated_ = true;
-}
-
-void Animation::EndUpdatingState() {
- DCHECK(state_is_being_updated_);
- state_is_being_updated_ = false;
-}
-
void Animation::CreateCompositorAnimation() {
if (Platform::Current()->IsThreadedAnimationEnabled() &&
!compositor_animation_) {
compositor_animation_ = CompositorAnimationHolder::Create(this);
- DCHECK(compositor_animation_);
AttachCompositorTimeline();
}
@@ -1886,23 +1955,59 @@ void Animation::DestroyCompositorAnimation() {
}
void Animation::AttachCompositorTimeline() {
- if (compositor_animation_) {
- CompositorAnimationTimeline* timeline =
- timeline_ ? ToDocumentTimeline(timeline_)->CompositorTimeline()
- : nullptr;
- if (timeline)
- timeline->AnimationAttached(*this);
- }
+ DCHECK(compositor_animation_);
+
+ // Register ourselves on the compositor timeline. This will cause our cc-side
+ // animation animation to be registered.
+ CompositorAnimationTimeline* compositor_timeline =
+ timeline_ ? timeline_->EnsureCompositorTimeline() : nullptr;
+ if (!compositor_timeline)
+ return;
+
+ compositor_timeline->AnimationAttached(*this);
+ if (compositor_timeline->GetAnimationTimeline()->IsScrollTimeline())
+ document_->AttachCompositorTimeline(compositor_timeline);
}
void Animation::DetachCompositorTimeline() {
- if (compositor_animation_) {
- CompositorAnimationTimeline* timeline =
- timeline_ ? ToDocumentTimeline(timeline_)->CompositorTimeline()
- : nullptr;
- if (timeline)
- timeline->AnimationDestroyed(*this);
- }
+ DCHECK(compositor_animation_);
+
+ CompositorAnimationTimeline* compositor_timeline =
+ timeline_ ? timeline_->CompositorTimeline() : nullptr;
+ if (!compositor_timeline)
+ return;
+
+ compositor_timeline->AnimationDestroyed(*this);
+
+ if (compositor_timeline->GetAnimationTimeline()->IsScrollTimeline())
+ document_->DetachCompositorTimeline(compositor_timeline);
+}
+
+void Animation::UpdateCompositorScrollTimeline() {
+ if (!compositor_animation_ || !timeline_)
+ return;
+ Node* scroll_source = To<ScrollTimeline>(*timeline_).ResolvedScrollSource();
+ LayoutBox* box = scroll_source ? scroll_source->GetLayoutBox() : nullptr;
+
+ base::Optional<double> start_scroll_offset;
+ base::Optional<double> end_scroll_offset;
+ if (box) {
+ double current_offset;
+ double max_offset;
+ To<ScrollTimeline>(*timeline_)
+ .GetCurrentAndMaxOffset(box, current_offset, max_offset);
+
+ double resolved_start_scroll_offset = 0;
+ double resolved_end_scroll_offset = max_offset;
+ To<ScrollTimeline>(*timeline_)
+ .ResolveScrollStartAndEnd(box, max_offset, resolved_start_scroll_offset,
+ resolved_end_scroll_offset);
+ start_scroll_offset = resolved_start_scroll_offset;
+ end_scroll_offset = resolved_end_scroll_offset;
+ }
+ compositor_animation_->GetAnimation()->UpdateScrollTimeline(
+ scroll_timeline_util::GetCompositorScrollElementId(scroll_source),
+ start_scroll_offset, end_scroll_offset);
}
void Animation::AttachCompositedLayers() {
@@ -1910,9 +2015,9 @@ void Animation::AttachCompositedLayers() {
return;
DCHECK(content_);
- DCHECK(content_->IsKeyframeEffect());
+ DCHECK(IsA<KeyframeEffect>(*content_));
- ToKeyframeEffect(content_.Get())->AttachCompositedLayers();
+ To<KeyframeEffect>(content_.Get())->AttachCompositedLayers();
}
void Animation::DetachCompositedLayers() {
@@ -1926,80 +2031,6 @@ void Animation::NotifyAnimationStarted(double monotonic_time, int group) {
monotonic_time, group);
}
-Animation::PlayStateUpdateScope::PlayStateUpdateScope(
- Animation& animation,
- TimingUpdateReason reason,
- CompositorPendingChange compositor_pending_change)
- : animation_(animation),
- initial_play_state_(animation_->PlayStateInternal()),
- compositor_pending_change_(compositor_pending_change) {
- DCHECK_NE(initial_play_state_, kUnset);
- animation_->BeginUpdatingState();
- animation_->UpdateCurrentTimingState(reason);
-}
-
-Animation::PlayStateUpdateScope::~PlayStateUpdateScope() {
- AnimationPlayState old_play_state = initial_play_state_;
- AnimationPlayState new_play_state = animation_->CalculateExtendedPlayState();
- animation_->internal_play_state_ = new_play_state;
-
- // Ordering is important, the ready promise should resolve/reject before
- // the finished promise.
- if (animation_->ready_promise_ && new_play_state != old_play_state) {
- // Transitioning to an idle state is handled in cancel().
- DCHECK(new_play_state != kIdle);
-
- if (old_play_state == kPending) {
- animation_->ResetPendingTasks();
- if (animation_->ready_promise_->GetState() == AnimationPromise::kPending)
- animation_->ResolvePromiseMaybeAsync(animation_->ready_promise_.Get());
- } else if (new_play_state == kPending) {
- if (animation_->ready_promise_->GetState() != AnimationPromise::kPending)
- animation_->ready_promise_->Reset();
- }
- }
-
- if (animation_->finished_promise_ && new_play_state != old_play_state) {
- // Transitioning to an idle state is handled in cancel().
- DCHECK(new_play_state != kIdle);
-
- if (new_play_state == kFinished) {
- animation_->ResetPendingTasks();
- animation_->ResolvePromiseMaybeAsync(animation_->finished_promise_.Get());
- } else if (old_play_state == kFinished) {
- animation_->finished_promise_->Reset();
- }
- }
-
- if (old_play_state != new_play_state &&
- (old_play_state == kIdle || new_play_state == kIdle)) {
- animation_->SetOutdated();
- }
-
-#if DCHECK_IS_ON()
- // Verify that current time is up to date.
- animation_->CurrentTimeInternal();
-#endif
-
- switch (compositor_pending_change_) {
- case kSetCompositorPending:
- animation_->SetCompositorPending();
- break;
- case kSetCompositorPendingWithEffectChanged:
- animation_->SetCompositorPending(true);
- break;
- case kDoNotSetCompositorPending:
- break;
- default:
- NOTREACHED();
- break;
- }
- animation_->EndUpdatingState();
-
- // Play state may have changed.
- animation_->NotifyProbe();
-}
-
void Animation::AddedEventListener(
const AtomicString& event_type,
RegisteredEventListener& registered_listener) {
@@ -2020,8 +2051,9 @@ void Animation::PauseForTesting(double pause_time) {
if (HasActiveAnimationsOnCompositor()) {
base::Optional<double> current_time = CurrentTimeInternal();
DCHECK(current_time);
- ToKeyframeEffect(content_.Get())
- ->PauseAnimationForTestingOnCompositor(current_time.value());
+ To<KeyframeEffect>(content_.Get())
+ ->PauseAnimationForTestingOnCompositor(
+ base::TimeDelta::FromSecondsD(current_time.value()));
}
// Do not wait for animation ready to lock in the hold time. Otherwise,
@@ -2046,10 +2078,11 @@ void Animation::DisableCompositedAnimationForTesting() {
}
void Animation::InvalidateKeyframeEffect(const TreeScope& tree_scope) {
- if (!content_ || !content_->IsKeyframeEffect())
+ auto* keyframe_effect = DynamicTo<KeyframeEffect>(content_.Get());
+ if (!keyframe_effect)
return;
- Element* target = ToKeyframeEffect(content_.Get())->target();
+ Element* target = keyframe_effect->EffectTarget();
// TODO(alancutter): Remove dependency of this function on CSSAnimations.
// This function makes the incorrect assumption that the animation uses
@@ -2096,10 +2129,10 @@ void Animation::RejectAndResetPromiseMaybeAsync(AnimationPromise* promise) {
void Animation::NotifyProbe() {
AnimationPlayState old_play_state = reported_play_state_;
AnimationPlayState new_play_state =
- pending() ? kPending : CalculateAnimationPlayState();
+ PendingInternal() ? kPending : CalculateAnimationPlayState();
if (old_play_state != new_play_state) {
- if (!pending()) {
+ if (!PendingInternal()) {
probe::AnimationPlayStateChanged(document_, this, old_play_state,
new_play_state);
}
@@ -2124,17 +2157,201 @@ void Animation::NotifyProbe() {
}
}
-void Animation::Trace(blink::Visitor* visitor) {
+// -------------------------------------
+// Replacement of animations
+// -------------------------------------
+
+// https://drafts.csswg.org/web-animations-1/#removing-replaced-animations
+bool Animation::IsReplaceable() {
+ // An animation is replaceable if all of the following conditions are true:
+
+ // 1. The existence of the animation is not prescribed by markup. That is, it
+ // is not a CSS animation with an owning element, nor a CSS transition with
+ // an owning element.
+ if (IsCSSAnimation() || IsCSSTransition()) {
+ // TODO(crbug.com/981905): Add OwningElement method to Animation and
+ // override in CssAnimations and CssTransitions. Only bail here if the
+ // animation has an owning element.
+ return false;
+ }
+
+ // 2. The animation's play state is finished.
+ if (CalculateAnimationPlayState() != kFinished)
+ return false;
+
+ // 3. The animation's replace state is not removed.
+ if (replace_state_ == kRemoved)
+ return false;
+
+ // 4. The animation is associated with a monotonically increasing timeline.
+ if (!timeline_ || timeline_->IsScrollTimeline())
+ return false;
+
+ // 5. The animation has an associated effect.
+ if (!content_ || !content_->IsKeyframeEffect())
+ return false;
+
+ // 6. The animation's associated effect is in effect.
+ if (!content_->IsInEffect())
+ return false;
+
+ // 7. The animation's associated effect has an effect target.
+ Element* target = To<KeyframeEffect>(content_.Get())->target();
+ if (!target)
+ return false;
+
+ return true;
+}
+
+// https://drafts.csswg.org/web-animations-1/#removing-replaced-animations
+void Animation::RemoveReplacedAnimation() {
+ DCHECK(IsReplaceable());
+
+ // To remove a replaced animation, perform the following steps:
+ // 1. Set animation’s replace state to removed.
+ // 2. Create an AnimationPlaybackEvent, removeEvent.
+ // 3. Set removeEvent’s type attribute to remove.
+ // 4. Set removeEvent’s currentTime attribute to the current time of
+ // animation.
+ // 5. Set removeEvent’s timelineTime attribute to the current time of the
+ // timeline with which animation is associated.
+ //
+ // If animation has a document for timing, then append removeEvent to its
+ // document for timing's pending animation event queue along with its target,
+ // animation. For the scheduled event time, use the result of applying the
+ // procedure to convert timeline time to origin-relative time to the current
+ // time of the timeline with which animation is associated.
+ replace_state_ = kRemoved;
+ const AtomicString& event_type = event_type_names::kRemove;
+ if (GetExecutionContext() && HasEventListeners(event_type)) {
+ base::Optional<double> event_current_time = CurrentTimeInternal();
+ if (event_current_time)
+ event_current_time = SecondsToMilliseconds(event_current_time.value());
+ pending_remove_event_ = MakeGarbageCollected<AnimationPlaybackEvent>(
+ event_type, event_current_time, TimelineTime());
+ pending_remove_event_->SetTarget(this);
+ pending_remove_event_->SetCurrentTarget(this);
+ document_->EnqueueAnimationFrameEvent(pending_remove_event_);
+ }
+
+ // Force timing update to clear the effect.
+ if (content_)
+ content_->Invalidate();
+ Update(kTimingUpdateOnDemand);
+}
+
+void Animation::persist() {
+ if (replace_state_ == kPersisted)
+ return;
+
+ replace_state_ = kPersisted;
+
+ // Force timing update to reapply the effect.
+ if (content_)
+ content_->Invalidate();
+ Update(kTimingUpdateOnDemand);
+}
+
+String Animation::replaceState() {
+ switch (replace_state_) {
+ case kActive:
+ return "active";
+
+ case kRemoved:
+ return "removed";
+
+ case kPersisted:
+ return "persisted";
+
+ default:
+ NOTREACHED();
+ return "";
+ }
+}
+
+// https://drafts.csswg.org/web-animations-1/#dom-animation-commitstyles
+void Animation::commitStyles(ExceptionState& exception_state) {
+ Element* target = content_ && content_->IsKeyframeEffect()
+ ? To<KeyframeEffect>(effect())->target()
+ : nullptr;
+
+ // 1. If target is not an element capable of having a style attribute
+ // (for example, it is a pseudo-element or is an element in a document
+ // format for which style attributes are not defined) throw a
+ // "NoModificationAllowedError" DOMException and abort these steps.
+ if (!target || !target->IsStyledElement() ||
+ !To<KeyframeEffect>(effect())->pseudoElement().IsEmpty()) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNoModificationAllowedError,
+ "Animation not associated with a styled target element");
+ return;
+ }
+ // 2. If, after applying any pending style changes, target is not being
+ // rendered, throw an "InvalidStateError" DOMException and abort these
+ // steps.
+ target->GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
+ if (!target->GetLayoutObject()) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Target element is not rendered.");
+ return;
+ }
+
+ // 3. Let inline style be the result of getting the CSS declaration block
+ // corresponding to target’s style attribute. If target does not have a
+ // style attribute, let inline style be a new empty CSS declaration block
+ // with the readonly flag unset and owner node set to target.
+ CSSStyleDeclaration* inline_style = target->style();
+
+ // 4. Let targeted properties be the set of physical longhand properties
+ // that are a target property for at least one animation effect
+ // associated with animation whose effect target is target.
+ PropertyHandleSet animation_properties =
+ To<KeyframeEffect>(effect())->Model()->Properties();
+
+ // 5. For each property, property, in targeted properties:
+ // 5.1 Let partialEffectStack be a copy of the effect stack for property
+ // on target.
+ // 5.2 If animation’s replace state is removed, add all animation effects
+ // associated with animation whose effect target is target and which
+ // include property as a target property to partialEffectStack.
+ // 5.3 Remove from partialEffectStack any animation effects whose
+ // associated animation has a higher composite order than animation.
+ // 5.4 Let effect value be the result of calculating the result of
+ // partialEffectStack for property using target’s computed style
+ // (see § 5.4.3 Calculating the result of an effect stack).
+ // 5.5 Set a CSS declaration property for effect value in inline style.
+ // 6. Update style attribute for inline style.
+ ActiveInterpolationsMap interpolations_map =
+ To<KeyframeEffect>(effect())->InterpolationsForCommitStyles();
+ StyleResolver& resolver = target->GetDocument().EnsureStyleResolver();
+ scoped_refptr<ComputedStyle> style =
+ resolver.StyleForInterpolations(*target, interpolations_map);
+
+ for (const auto& property : animation_properties) {
+ if (!property.IsCSSProperty())
+ continue;
+
+ CSSPropertyRef ref(property.GetCSSPropertyName(), target->GetDocument());
+ const CSSValue* value = ref.GetProperty().CSSValueFromComputedStyle(
+ *style, target->GetLayoutObject(), false);
+ inline_style->setProperty(target->GetExecutionContext(),
+ property.GetCSSPropertyName().ToAtomicString(),
+ value->CssText(), "", ASSERT_NO_EXCEPTION);
+ }
+}
+
+void Animation::Trace(Visitor* visitor) {
visitor->Trace(content_);
visitor->Trace(document_);
visitor->Trace(timeline_);
visitor->Trace(pending_finished_event_);
visitor->Trace(pending_cancelled_event_);
+ visitor->Trace(pending_remove_event_);
visitor->Trace(finished_promise_);
visitor->Trace(ready_promise_);
visitor->Trace(compositor_animation_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
Animation::CompositorAnimationHolder*
diff --git a/chromium/third_party/blink/renderer/core/animation/animation.h b/chromium/third_party/blink/renderer/core/animation/animation.h
index 0b0a00d5ae4..a71d09d7af4 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation.h
+++ b/chromium/third_party/blink/renderer/core/animation/animation.h
@@ -41,14 +41,12 @@
#include "third_party/blink/renderer/bindings/core/v8/script_promise_property.h"
#include "third_party/blink/renderer/core/animation/animation_effect.h"
#include "third_party/blink/renderer/core/animation/animation_effect_owner.h"
-#include "third_party/blink/renderer/core/animation/animation_timeline.h"
#include "third_party/blink/renderer/core/animation/compositor_animations.h"
-#include "third_party/blink/renderer/core/animation/document_timeline.h"
#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/dom_exception.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation_client.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation_delegate.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -62,15 +60,17 @@ class Element;
class ExceptionState;
class PaintArtifactCompositor;
class TreeScope;
+class AnimationTimeline;
class CORE_EXPORT Animation : public EventTargetWithInlineData,
public ActiveScriptWrappable<Animation>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public CompositorAnimationDelegate,
public CompositorAnimationClient,
public AnimationEffectOwner {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(Animation);
+ USING_PRE_FINALIZER(Animation, Dispose);
public:
enum AnimationPlayState {
@@ -82,6 +82,24 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData,
kFinished
};
+ // https://drafts.csswg.org/web-animations/#animation-replace-state
+ enum ReplaceState { kActive, kRemoved, kPersisted };
+
+ // Priority for sorting getAnimation by Animation class, arranged from lowest
+ // priority to highest priority as per spec:
+ // https://drafts.csswg.org/web-animations/#dom-document-getanimations
+ enum AnimationClassPriority {
+ kCssTransitionPriority,
+ kCssAnimationPriority,
+ kDefaultPriority
+ };
+
+ // kTreeOrder uses the order in the DOM to determine animations' relative
+ // position.
+ // kPointerOrder simply compares Element pointers and determine animations'
+ // relative position.
+ enum CompareAnimationsOrdering { kTreeOrder, kPointerOrder };
+
static Animation* Create(AnimationEffect*,
AnimationTimeline*,
ExceptionState& = ASSERT_NO_EXCEPTION);
@@ -101,6 +119,9 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData,
virtual bool IsCSSAnimation() const { return false; }
virtual bool IsCSSTransition() const { return false; }
+ virtual Element* OwningElement() const { return nullptr; }
+ virtual void ClearOwningElement() {}
+ bool IsOwned() const { return OwningElement(); }
// Returns whether the animation is finished.
bool Update(TimingUpdateReason);
@@ -121,25 +142,44 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData,
void cancel();
+ base::Optional<double> currentTimeForBinding() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ double currentTimeForBinding(bool& is_null); // DEPRECATED
+ void setCurrentTimeForBinding(base::Optional<double> new_current_time,
+ ExceptionState& exception_state);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ void setCurrentTimeForBinding(double new_current_time, // DEPRECATED
+ bool is_null,
+ ExceptionState& exception_state);
+
+ double currentTime() const;
double currentTime(bool& is_null);
- double currentTime();
void setCurrentTime(double new_current_time,
bool is_null,
ExceptionState& = ASSERT_NO_EXCEPTION);
+
base::Optional<double> UnlimitedCurrentTime() const;
// https://drafts.csswg.org/web-animations/#play-states
+ String PlayStateString() const;
static const char* PlayStateString(AnimationPlayState);
AnimationPlayState CalculateAnimationPlayState() const;
- String playState() const {
- return PlayStateString(CalculateAnimationPlayState());
- }
- bool pending() const;
+ // As a web exposed API, playState must update style and layout if the play
+ // state may be affected by it (see CSSAnimation::playState), whereas
+ // PlayStateString can be used to query the current play state.
+ virtual String playState() const;
+
+ bool PendingInternal() const;
+
+ // As a web exposed API, pending must update style and layout if the pending
+ // status may be affected by it (see CSSAnimation::pending), whereas
+ // PendingInternal can be used to query the current pending status.
+ virtual bool pending() const;
- void pause(ExceptionState& = ASSERT_NO_EXCEPTION);
- void play(ExceptionState& = ASSERT_NO_EXCEPTION);
- void reverse(ExceptionState& = ASSERT_NO_EXCEPTION);
+ virtual void pause(ExceptionState& = ASSERT_NO_EXCEPTION);
+ virtual void play(ExceptionState& = ASSERT_NO_EXCEPTION);
+ virtual void reverse(ExceptionState& = ASSERT_NO_EXCEPTION);
void finish(ExceptionState& = ASSERT_NO_EXCEPTION);
void updatePlaybackRate(double playback_rate,
ExceptionState& = ASSERT_NO_EXCEPTION);
@@ -161,21 +201,25 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData,
DEFINE_ATTRIBUTE_EVENT_LISTENER(finish, kFinish)
DEFINE_ATTRIBUTE_EVENT_LISTENER(cancel, kCancel)
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(remove, kRemove)
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
bool HasPendingActivity() const final;
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
double playbackRate() const;
void setPlaybackRate(double, ExceptionState& = ASSERT_NO_EXCEPTION);
AnimationTimeline* timeline() { return timeline_; }
- Document* GetDocument();
+ Document* GetDocument() const;
- double startTime(bool& is_null) const;
base::Optional<double> startTime() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ double startTime(bool& is_null) const; // DEPRECATED
base::Optional<double> StartTimeInternal() const { return start_time_; }
- void setStartTime(double,
+ virtual void setStartTime(base::Optional<double>, ExceptionState&);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ void setStartTime(double, // DEPRECATED
bool is_null,
ExceptionState& = ASSERT_NO_EXCEPTION);
@@ -225,36 +269,57 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData,
void PostCommit(double timeline_time);
unsigned SequenceNumber() const override { return sequence_number_; }
+
int CompositorGroup() const { return compositor_group_; }
- static bool HasLowerPriority(const Animation* animation1,
- const Animation* animation2) {
- return animation1->SequenceNumber() < animation2->SequenceNumber();
- }
+ static bool HasLowerCompositeOrdering(
+ const Animation* animation1,
+ const Animation* animation2,
+ CompareAnimationsOrdering compare_animation_type);
bool EffectSuppressed() const override { return effect_suppressed_; }
void SetEffectSuppressed(bool);
void InvalidateKeyframeEffect(const TreeScope&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
bool CompositorPendingForTesting() const { return compositor_pending_; }
+ // Methods for handling removal and persistence of animations.
+ bool IsReplaceable();
+ void RemoveReplacedAnimation();
+ void persist();
+ String replaceState();
+ void commitStyles(ExceptionState& = ASSERT_NO_EXCEPTION);
+ bool ReplaceStateRemoved() const override {
+ return replace_state_ == kRemoved;
+ }
+ bool ReplaceStateActive() const { return replace_state_ == kActive; }
+
+ // Overridden for CSS animations to force pending animation properties to be
+ // applied. This step is required before any web animation API calls that
+ // 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,
RegisteredEventListener&) override;
+ base::Optional<double> CurrentTimeInternal() const;
+ virtual AnimationEffect::EventDelegate* CreateEventDelegate(
+ Element* target,
+ const AnimationEffect::EventDelegate* old_event_delegate) {
+ return nullptr;
+ }
private:
- // TODO(crbug.com/960944): Deprecate. This version of the play state is not to
- // spec due to the inclusion of a 'pending' state. Whether or not an animation
- // is pending is separate from the actual play state.
- AnimationPlayState PlayStateInternal() const;
-
- base::Optional<double> CurrentTimeInternal() const;
void SetCurrentTimeInternal(double new_current_time);
- void SetCurrentTimeInternal(double new_current_time, TimingUpdateReason);
void ClearOutdated();
void ForceServiceOnNextFrame();
@@ -268,21 +333,9 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData,
double EffectivePlaybackRate() const;
void ApplyPendingPlaybackRate();
- // https://drafts.csswg.org/web-animations/#play-states
- // Per spec the viable states are: idle, running, paused and finished.
- // Our implementation has an additional state called 'pending' which serves a
- // similar purpose to micro-tasks in the spec. This additional state is for
- // internal flow control only and should not be reported via
- // animation.playState.
- // TODO(crbug.com/958433): Deprecate this method in favor of the
- // spec-compliant GetPlayState().
- AnimationPlayState CalculateExtendedPlayState() const;
-
base::Optional<double> CalculateStartTime(double current_time) const;
base::Optional<double> CalculateCurrentTime() const;
- void UpdateCurrentTimingState(TimingUpdateReason);
-
void BeginUpdatingState();
void EndUpdatingState();
@@ -300,7 +353,6 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData,
void NotifyAnimationAborted(double monotonic_time, int group) override {}
using AnimationPromise = ScriptPromiseProperty<Member<Animation>,
- Member<Animation>,
Member<DOMException>>;
void ResolvePromiseMaybeAsync(AnimationPromise*);
void RejectAndResetPromise(AnimationPromise*);
@@ -324,8 +376,7 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData,
void PlayInternal(AutoRewind auto_rewind, ExceptionState& exception_state);
void ResetPendingTasks();
- double TimelineTime() const;
- DocumentTimeline& TickingTimeline();
+ base::Optional<double> TimelineTime() const;
void ScheduleAsyncFinish();
void AsyncFinishMicrotask();
@@ -336,11 +387,6 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData,
String id_;
- // Extended play state with additional pending state for managing timing of
- // micro-tasks.
- // TODO(crbug.com/958433): Phase out this version of the play state. Should
- // just need the reported play state.
- AnimationPlayState internal_play_state_;
// Extended play state reported to dev tools. This play state has an
// additional pending state that is not part of the spec by expected by dev
// tools.
@@ -365,8 +411,9 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData,
Member<Document> document_;
Member<AnimationTimeline> timeline_;
- // Reflects all pausing, including via pauseForTesting().
- bool paused_;
+ ReplaceState replace_state_;
+
+ // Testing flags.
bool is_paused_for_testing_;
bool is_composited_animation_disabled_for_testing_;
@@ -390,6 +437,8 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData,
Member<Event> pending_cancelled_event_;
+ Member<Event> pending_remove_event_;
+
// TODO(crbug.com/960944): Consider reintroducing kPause and cleanup use of
// mutually exclusive pending_play_ and pending_pause_ flags.
enum CompositorAction { kNone, kStart };
@@ -418,21 +467,6 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData,
kDoNotSetCompositorPending,
};
- class PlayStateUpdateScope {
- STACK_ALLOCATED();
-
- public:
- PlayStateUpdateScope(Animation&,
- TimingUpdateReason,
- CompositorPendingChange = kSetCompositorPending);
- ~PlayStateUpdateScope();
-
- private:
- Member<Animation> animation_;
- AnimationPlayState initial_play_state_;
- CompositorPendingChange compositor_pending_change_;
- };
-
// CompositorAnimation objects need to eagerly sever their connection to their
// Animation delegate; use a separate 'holder' on-heap object to accomplish
// that.
@@ -447,7 +481,7 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData,
void Detach();
- void Trace(blink::Visitor* visitor) { visitor->Trace(animation_); }
+ void Trace(Visitor* visitor) { visitor->Trace(animation_); }
CompositorAnimation* GetAnimation() const {
return compositor_animation_.get();
@@ -469,9 +503,6 @@ class CORE_EXPORT Animation : public EventTargetWithInlineData,
Member<CompositorAnimationHolder> compositor_animation_;
- bool current_time_pending_;
- bool state_is_being_updated_;
-
bool effect_suppressed_;
FRIEND_TEST_ALL_PREFIXES(AnimationAnimationTestCompositeAfterPaint,
diff --git a/chromium/third_party/blink/renderer/core/animation/animation.idl b/chromium/third_party/blink/renderer/core/animation/animation.idl
index 79acca95bda..88a3b8763e8 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation.idl
+++ b/chromium/third_party/blink/renderer/core/animation/animation.idl
@@ -32,30 +32,34 @@
enum AnimationPlayState { "idle", "pending", "running", "paused", "finished" };
+enum ReplaceState { "active", "removed", "persisted" };
+
[
Exposed=Window,
- Constructor(optional AnimationEffect? effect = null, optional AnimationTimeline? timeline),
- ConstructorCallWith=ExecutionContext,
- RaisesException=Constructor,
ActiveScriptWrappable
] interface Animation : EventTarget {
+ [CallWith=ExecutionContext, RaisesException] constructor(optional AnimationEffect? effect = null, optional AnimationTimeline? timeline);
[Measure] attribute AnimationEffect? effect;
// TODO(suzyh): Make timeline mutable.
[RuntimeEnabled=WebAnimationsAPI] readonly attribute AnimationTimeline? timeline;
[Measure, RaisesException=Setter] attribute double? startTime;
- [Measure, RaisesException=Setter] attribute double? currentTime;
+ [Measure, RaisesException=Setter, ImplementedAs=currentTimeForBinding] attribute double? currentTime;
[Measure, RaisesException=Setter] attribute double playbackRate;
[Measure] readonly attribute AnimationPlayState playState;
+ [RuntimeEnabled=WebAnimationsAPI, Measure] readonly attribute ReplaceState replaceState;
[Measure] readonly attribute boolean pending;
+ [RuntimeEnabled=WebAnimationsAPI, Measure, RaisesException] void commitStyles();
[Measure, RaisesException] void finish();
[Measure, RaisesException] void play();
[Measure, RaisesException] void pause();
[Measure, RaisesException] void reverse();
[Measure, RaisesException] void updatePlaybackRate(double playback_rate);
+ [RuntimeEnabled=WebAnimationsAPI, Measure] void persist();
[Measure] attribute DOMString id;
[Measure] void cancel();
[Measure] attribute EventHandler onfinish;
[Measure] attribute EventHandler oncancel;
+ [RuntimeEnabled=WebAnimationsAPI, Measure] attribute EventHandler onremove;
[RuntimeEnabled=WebAnimationsAPI, CallWith=ScriptState] readonly attribute Promise<Animation> finished;
[RuntimeEnabled=WebAnimationsAPI, CallWith=ScriptState] readonly attribute Promise<Animation> ready;
-}; \ No newline at end of file
+};
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 261632951ec..4fb89c5c873 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation_effect.cc
+++ b/chromium/third_party/blink/renderer/core/animation/animation_effect.cc
@@ -30,10 +30,11 @@
#include "third_party/blink/renderer/core/animation/animation_effect.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_computed_effect_timing.h"
+#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/computed_effect_timing.h"
-#include "third_party/blink/renderer/core/animation/optional_effect_timing.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"
@@ -44,24 +45,57 @@ AnimationEffect::AnimationEffect(const Timing& timing,
: owner_(nullptr),
timing_(timing),
event_delegate_(event_delegate),
- calculated_(),
- needs_update_(true) {
+ needs_update_(true),
+ cancel_time_(0) {
timing_.AssertValid();
}
void AnimationEffect::UpdateSpecifiedTiming(const Timing& timing) {
- // FIXME: Test whether the timing is actually different?
- timing_ = timing;
+ if (!timing_.HasTimingOverrides()) {
+ timing_ = timing;
+ } else {
+ // Style changes that are overridden due to an explicit call to
+ // AnimationEffect.updateTiming are not applied.
+ if (!timing_.HasTimingOverride(Timing::kOverrideStartDelay))
+ timing_.start_delay = timing.start_delay;
+
+ if (!timing_.HasTimingOverride(Timing::kOverrideDirection))
+ timing_.direction = timing.direction;
+
+ if (!timing_.HasTimingOverride(Timing::kOverrideDuration))
+ timing_.iteration_duration = timing.iteration_duration;
+
+ if (!timing_.HasTimingOverride(Timing::kOverrideEndDelay))
+ timing_.end_delay = timing.end_delay;
+
+ if (!timing_.HasTimingOverride(Timing::kOverideFillMode))
+ timing_.fill_mode = timing.fill_mode;
+
+ if (!timing_.HasTimingOverride(Timing::kOverrideIterationCount))
+ timing_.iteration_count = timing.iteration_count;
+
+ if (!timing_.HasTimingOverride(Timing::kOverrideIterationStart))
+ timing_.iteration_start = timing.iteration_start;
+
+ if (!timing_.HasTimingOverride(Timing::kOverrideTimingFunction))
+ timing_.timing_function = timing.timing_function;
+ }
InvalidateAndNotifyOwner();
}
+void AnimationEffect::SetIgnoreCssTimingProperties() {
+ timing_.SetTimingOverride(Timing::kOverrideAll);
+}
+
EffectTiming* AnimationEffect::getTiming() const {
+ if (const Animation* animation = GetAnimation())
+ animation->FlushPendingUpdates();
return SpecifiedTiming().ConvertToEffectTiming();
}
ComputedEffectTiming* AnimationEffect::getComputedTiming() const {
return SpecifiedTiming().getComputedTiming(EnsureCalculated(),
- IsKeyframeEffect());
+ IsA<KeyframeEffect>(this));
}
void AnimationEffect::updateTiming(OptionalEffectTiming* optional_timing,
@@ -91,7 +125,7 @@ void AnimationEffect::UpdateInheritedTime(base::Optional<double> inherited_time,
const base::Optional<double> local_time = inherited_time;
if (needs_update) {
Timing::CalculatedTiming calculated = SpecifiedTiming().CalculateTimings(
- local_time, direction, IsKeyframeEffect(), playback_rate);
+ local_time, direction, IsA<KeyframeEffect>(this), playback_rate);
const bool was_canceled = calculated.phase != calculated_.phase &&
calculated.phase == Timing::kPhaseNone;
@@ -145,7 +179,7 @@ const Animation* AnimationEffect::GetAnimation() const {
return owner_ ? owner_->GetAnimation() : nullptr;
}
-void AnimationEffect::Trace(blink::Visitor* visitor) {
+void AnimationEffect::Trace(Visitor* visitor) {
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 79196027d2c..8e25ca4cebb 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation_effect.h
+++ b/chromium/third_party/blink/renderer/core/animation/animation_effect.h
@@ -72,7 +72,9 @@ class CORE_EXPORT AnimationEffect : public ScriptWrappable {
virtual ~EventDelegate() = default;
virtual bool RequiresIterationEvents(const AnimationEffect&) = 0;
virtual void OnEventCondition(const AnimationEffect&, Timing::Phase) = 0;
- virtual void Trace(blink::Visitor* visitor) {}
+ virtual bool IsAnimationEventDelegate() const { return false; }
+ virtual bool IsTransitionEventDelegate() const { return false; }
+ virtual void Trace(Visitor* visitor) {}
};
~AnimationEffect() override = default;
@@ -97,17 +99,22 @@ class CORE_EXPORT AnimationEffect : public ScriptWrappable {
return EnsureCalculated().time_to_reverse_effect_change;
}
double LocalTime() const {
- return EnsureCalculated().local_time.value_or(NullValue());
+ return EnsureCalculated().local_time.value_or(Timing::NullValue());
}
const Timing& SpecifiedTiming() const { return timing_; }
void UpdateSpecifiedTiming(const Timing&);
+ void SetIgnoreCssTimingProperties();
+
EventDelegate* GetEventDelegate() { return event_delegate_; }
+ void SetEventDelegate(EventDelegate* delegate) { event_delegate_ = delegate; }
EffectTiming* getTiming() const;
ComputedEffectTiming* getComputedTiming() const;
void updateTiming(OptionalEffectTiming*,
ExceptionState& = ASSERT_NO_EXCEPTION);
+ double GetCancelTime() const { return cancel_time_; }
+ void SetCancelTime(double cancel_time) { cancel_time_ = cancel_time; }
// Attach/Detach the AnimationEffect from its owning animation.
virtual void Attach(AnimationEffectOwner* owner) { owner_ = owner; }
@@ -118,7 +125,7 @@ class CORE_EXPORT AnimationEffect : public ScriptWrappable {
const Animation* GetAnimationForTesting() const { return GetAnimation(); }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
explicit AnimationEffect(const Timing&, EventDelegate* = nullptr);
@@ -148,7 +155,7 @@ class CORE_EXPORT AnimationEffect : public ScriptWrappable {
virtual AnimationTimeDelta CalculateTimeToEffectChange(
bool forwards,
base::Optional<double> local_time,
- double time_to_next_iteration) const = 0;
+ AnimationTimeDelta time_to_next_iteration) const = 0;
const Animation* GetAnimation() const;
Animation* GetAnimation();
@@ -160,6 +167,7 @@ class CORE_EXPORT AnimationEffect : public ScriptWrappable {
mutable Timing::CalculatedTiming calculated_;
mutable bool needs_update_;
mutable base::Optional<double> last_update_time_;
+ double cancel_time_;
const Timing::CalculatedTiming& EnsureCalculated() const;
};
diff --git a/chromium/third_party/blink/renderer/core/animation/animation_effect.idl b/chromium/third_party/blink/renderer/core/animation/animation_effect.idl
index bf779a5e8bf..64683b9dd60 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation_effect.idl
+++ b/chromium/third_party/blink/renderer/core/animation/animation_effect.idl
@@ -34,5 +34,5 @@
interface AnimationEffect {
EffectTiming getTiming();
ComputedEffectTiming getComputedTiming();
- [RaisesException] void updateTiming(optional OptionalEffectTiming timing);
+ [RaisesException] void updateTiming(optional OptionalEffectTiming timing = {});
};
diff --git a/chromium/third_party/blink/renderer/core/animation/animation_effect_owner.h b/chromium/third_party/blink/renderer/core/animation/animation_effect_owner.h
index aa99a2dbd3f..5c6cc9d9d9a 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation_effect_owner.h
+++ b/chromium/third_party/blink/renderer/core/animation/animation_effect_owner.h
@@ -34,6 +34,9 @@ class AnimationEffectOwner : public GarbageCollectedMixin {
// to be updated or not.
virtual bool EffectSuppressed() const = 0;
+ // Returns true if this is a replaced animation that has been removed.
+ virtual bool ReplaceStateRemoved() const = 0;
+
// Notifies the owning animation that the effect has been invalidated, and any
// cached information regarding it may need to be invalidated. This can
// happen e.g. if the timing information changes or the keyframes change.
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 f6af3f88363..186961d7308 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
@@ -32,9 +32,9 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_computed_effect_timing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_optional_effect_timing.h"
#include "third_party/blink/renderer/core/animation/animation_effect_owner.h"
-#include "third_party/blink/renderer/core/animation/computed_effect_timing.h"
-#include "third_party/blink/renderer/core/animation/optional_effect_timing.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
@@ -49,6 +49,7 @@ class MockAnimationEffectOwner
MOCK_CONST_METHOD0(Playing, bool());
MOCK_CONST_METHOD0(IsEventDispatchAllowed, bool());
MOCK_CONST_METHOD0(EffectSuppressed, bool());
+ MOCK_CONST_METHOD0(ReplaceStateRemoved, bool());
MOCK_METHOD0(EffectInvalidated, void());
MOCK_METHOD0(UpdateIfNecessary, void());
MOCK_METHOD0(GetAnimation, Animation*());
@@ -96,11 +97,12 @@ class TestAnimationEffect : public AnimationEffect {
AnimationTimeDelta CalculateTimeToEffectChange(
bool forwards,
base::Optional<double> local_time,
- double time_to_next_iteration) const override {
- DCHECK(!local_time || !IsNull(local_time.value()));
+ AnimationTimeDelta time_to_next_iteration) const override {
+ DCHECK(!local_time || !Timing::IsNull(local_time.value()));
local_time_ = local_time;
- time_to_next_iteration_ = ValueOrUnresolved(time_to_next_iteration);
- return AnimationTimeDelta::FromSecondsD(-1);
+ time_to_next_iteration_ = time_to_next_iteration;
+ return AnimationTimeDelta::FromSecondsD(
+ std::numeric_limits<double>::infinity());
}
double TakeLocalTime() {
DCHECK(local_time_);
@@ -109,13 +111,13 @@ class TestAnimationEffect : public AnimationEffect {
return result;
}
- base::Optional<double> TakeTimeToNextIteration() {
- const base::Optional<double> result = time_to_next_iteration_;
+ base::Optional<AnimationTimeDelta> TakeTimeToNextIteration() {
+ const base::Optional<AnimationTimeDelta> result = time_to_next_iteration_;
time_to_next_iteration_.reset();
return result;
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(event_delegate_);
AnimationEffect::Trace(visitor);
}
@@ -123,7 +125,7 @@ class TestAnimationEffect : public AnimationEffect {
private:
Member<TestAnimationEffectEventDelegate> event_delegate_;
mutable base::Optional<double> local_time_;
- mutable base::Optional<double> time_to_next_iteration_;
+ mutable base::Optional<AnimationTimeDelta> time_to_next_iteration_;
};
TEST(AnimationAnimationEffectTest, Sanity) {
@@ -696,24 +698,24 @@ TEST(AnimationAnimationEffectTest, TimeToEffectChange) {
animation_node->UpdateInheritedTime(0);
EXPECT_EQ(0, animation_node->TakeLocalTime());
- base::Optional<double> time_to_next_iteration =
+ base::Optional<AnimationTimeDelta> time_to_next_iteration =
animation_node->TakeTimeToNextIteration();
EXPECT_TRUE(time_to_next_iteration);
- EXPECT_TRUE(std::isinf(time_to_next_iteration.value()));
+ EXPECT_TRUE(time_to_next_iteration->is_max());
// Normal iteration.
animation_node->UpdateInheritedTime(1.75);
EXPECT_EQ(1.75, animation_node->TakeLocalTime());
time_to_next_iteration = animation_node->TakeTimeToNextIteration();
EXPECT_TRUE(time_to_next_iteration);
- EXPECT_NEAR(0.05, time_to_next_iteration.value(), 0.000000000000001);
+ EXPECT_NEAR(0.05, time_to_next_iteration->InSecondsF(), 0.000000000000001);
// Reverse iteration.
animation_node->UpdateInheritedTime(2.75);
EXPECT_EQ(2.75, animation_node->TakeLocalTime());
time_to_next_iteration = animation_node->TakeTimeToNextIteration();
EXPECT_TRUE(time_to_next_iteration);
- EXPECT_NEAR(0.05, time_to_next_iteration.value(), 0.000000000000001);
+ EXPECT_NEAR(0.05, time_to_next_iteration->InSecondsF(), 0.000000000000001);
// Item ends before iteration finishes.
animation_node->UpdateInheritedTime(3.4);
@@ -721,7 +723,7 @@ TEST(AnimationAnimationEffectTest, TimeToEffectChange) {
EXPECT_EQ(3.4, animation_node->TakeLocalTime());
time_to_next_iteration = animation_node->TakeTimeToNextIteration();
EXPECT_TRUE(time_to_next_iteration);
- EXPECT_TRUE(std::isinf(time_to_next_iteration.value()));
+ EXPECT_TRUE(time_to_next_iteration->is_max());
// Item has finished.
animation_node->UpdateInheritedTime(3.5);
@@ -729,7 +731,7 @@ TEST(AnimationAnimationEffectTest, TimeToEffectChange) {
EXPECT_EQ(3.5, animation_node->TakeLocalTime());
time_to_next_iteration = animation_node->TakeTimeToNextIteration();
EXPECT_TRUE(time_to_next_iteration);
- EXPECT_TRUE(std::isinf(time_to_next_iteration.value()));
+ EXPECT_TRUE(time_to_next_iteration->is_max());
}
TEST(AnimationAnimationEffectTest, UpdateTiming) {
diff --git a/chromium/third_party/blink/renderer/core/animation/animation_input_helpers.cc b/chromium/third_party/blink/renderer/core/animation/animation_input_helpers.cc
index 99816032fc2..5e3181f717a 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation_input_helpers.cc
+++ b/chromium/third_party/blink/renderer/core/animation/animation_input_helpers.cc
@@ -79,7 +79,7 @@ CSSPropertyID AnimationInputHelpers::KeyframeAttributeToCSSProperty(
builder.Append('-');
builder.Append(property[i]);
}
- return cssPropertyID(builder.ToString());
+ return cssPropertyID(document.GetExecutionContext(), builder.ToString());
}
CSSPropertyID AnimationInputHelpers::KeyframeAttributeToPresentationAttribute(
@@ -91,9 +91,9 @@ CSSPropertyID AnimationInputHelpers::KeyframeAttributeToPresentationAttribute(
String unprefixed_property = RemoveSVGPrefix(property);
if (SVGElement::IsAnimatableCSSProperty(QualifiedName(
- g_null_atom, AtomicString(unprefixed_property), g_null_atom)))
- return cssPropertyID(unprefixed_property);
-
+ g_null_atom, AtomicString(unprefixed_property), g_null_atom))) {
+ return cssPropertyID(element->GetExecutionContext(), unprefixed_property);
+ }
return CSSPropertyID::kInvalid;
}
diff --git a/chromium/third_party/blink/renderer/core/animation/animation_sim_test.cc b/chromium/third_party/blink/renderer/core/animation/animation_sim_test.cc
index dfd11a33638..02dd56510e9 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation_sim_test.cc
+++ b/chromium/third_party/blink/renderer/core/animation/animation_sim_test.cc
@@ -3,7 +3,8 @@
// found in the LICENSE file.
#include "third_party/blink/public/web/web_script_source.h"
-#include "third_party/blink/renderer/core/animation/animatable.h"
+#include "third_party/blink/renderer/core/animation/document_timeline.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/animation/string_keyframe.h"
#include "third_party/blink/renderer/core/css/css_style_sheet.h"
@@ -34,9 +35,7 @@ TEST_F(AnimationSimTest, CustomPropertyBaseComputedStyle) {
// animation.
ScopedCSSVariables2ForTest css_variables2(true);
- ScopedCSSAdditiveAnimationsForTest css_additive_animation(true);
- ScopedStackedCSSPropertyAnimationsForTest stacked_css_property_animation(
- true);
+ ScopedWebAnimationsAPIForTest web_animations(true);
SimRequest main_resource("https://example.com/", "text/html");
LoadURL("https://example.com/");
@@ -55,8 +54,8 @@ TEST_F(AnimationSimTest, CustomPropertyBaseComputedStyle) {
DummyExceptionStateForTesting exception_state;
// target.style.setProperty('--x', '100%');
- target->style()->setProperty(&GetDocument(), "--x", "100%", g_empty_string,
- exception_state);
+ target->style()->setProperty(GetDocument().GetExecutionContext(), "--x",
+ "100%", g_empty_string, exception_state);
EXPECT_FALSE(exception_state.HadException());
// target.animate({'--x': '100%'}, 1000);
@@ -68,17 +67,19 @@ TEST_F(AnimationSimTest, CustomPropertyBaseComputedStyle) {
keyframes.push_back(keyframe);
Timing timing;
timing.iteration_duration = AnimationTimeDelta::FromSecondsD(1);
- Animatable::animateInternal(
- *target, MakeGarbageCollected<StringKeyframeEffectModel>(keyframes),
+
+ auto* keyframe_effect = MakeGarbageCollected<KeyframeEffect>(
+ target, MakeGarbageCollected<StringKeyframeEffectModel>(keyframes),
timing);
+ target->GetDocument().Timeline().Play(keyframe_effect);
// This sets the baseComputedStyle on the animation exit frame.
Compositor().BeginFrame(1);
Compositor().BeginFrame(1);
// target.style.setProperty('--x', '0%');
- target->style()->setProperty(&GetDocument(), "--x", "0%", g_empty_string,
- exception_state);
+ target->style()->setProperty(GetDocument().GetExecutionContext(), "--x", "0%",
+ g_empty_string, exception_state);
EXPECT_FALSE(exception_state.HadException());
// target.animate({'--x': '100%'}, 1000);
@@ -90,9 +91,11 @@ TEST_F(AnimationSimTest, CustomPropertyBaseComputedStyle) {
keyframes.push_back(std::move(keyframe));
timing = Timing();
timing.iteration_duration = AnimationTimeDelta::FromSecondsD(1);
- Animatable::animateInternal(
- *target, MakeGarbageCollected<StringKeyframeEffectModel>(keyframes),
+
+ keyframe_effect = MakeGarbageCollected<KeyframeEffect>(
+ target, MakeGarbageCollected<StringKeyframeEffectModel>(keyframes),
timing);
+ target->GetDocument().Timeline().Play(keyframe_effect);
// This (previously) would not clear the existing baseComputedStyle and would
// crash on the equality assertion in the exit frame when it tried to update
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 a1278f2c461..3fa3a8e4784 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation_test.cc
+++ b/chromium/third_party/blink/renderer/core/animation/animation_test.cc
@@ -35,6 +35,9 @@
#include "base/bits.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/core/v8/double_or_scroll_timeline_auto_keyword.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_optional_effect_timing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_options.h"
#include "third_party/blink/renderer/core/animation/animation_clock.h"
#include "third_party/blink/renderer/core/animation/css/compositor_keyframe_double.h"
#include "third_party/blink/renderer/core/animation/css_number_interpolation_type.h"
@@ -44,6 +47,7 @@
#include "third_party/blink/renderer/core/animation/keyframe_effect_model.h"
#include "third_party/blink/renderer/core/animation/pending_animations.h"
#include "third_party/blink/renderer/core/animation/scroll_timeline.h"
+#include "third_party/blink/renderer/core/animation/timing.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
@@ -134,6 +138,10 @@ class AnimationAnimationTestNoCompositing : public RenderingTest {
SetBodyInnerHTML("<div id='target'></div>");
+ MakeCompositedAnimation();
+ }
+
+ void MakeCompositedAnimation() {
// Create a compositable animation; in this case opacity from 1 to 0.
Timing timing;
timing.iteration_duration = AnimationTimeDelta::FromSecondsD(30);
@@ -171,9 +179,12 @@ class AnimationAnimationTestNoCompositing : public RenderingTest {
StringKeyframeVector());
}
- KeyframeEffect* MakeAnimation(double duration = 30) {
+ KeyframeEffect* MakeAnimation(
+ double duration = 30,
+ Timing::FillMode fill_mode = Timing::FillMode::AUTO) {
Timing timing;
timing.iteration_duration = AnimationTimeDelta::FromSecondsD(duration);
+ timing.fill_mode = fill_mode;
return MakeGarbageCollected<KeyframeEffect>(nullptr, MakeEmptyEffectModel(),
timing);
}
@@ -203,6 +214,13 @@ class AnimationAnimationTestNoCompositing : public RenderingTest {
Microtask::PerformCheckpoint(V8PerIsolateData::MainThreadIsolate());
}
+ void SimulateFrameForScrollAnimations() {
+ // Advance time by 100 ms.
+ auto new_time = GetAnimationClock().CurrentTime() +
+ base::TimeDelta::FromMilliseconds(100);
+ GetPage().Animator().ServiceScriptedAnimations(new_time);
+ }
+
Persistent<DocumentTimeline> timeline;
Persistent<Animation> animation;
@@ -1029,10 +1047,12 @@ TEST_F(AnimationAnimationTestNoCompositing, AttachedAnimations) {
EXPECT_TRUE(element->GetElementAnimations()->Animations().IsEmpty());
}
-TEST_F(AnimationAnimationTestNoCompositing, HasLowerPriority) {
+TEST_F(AnimationAnimationTestNoCompositing, HasLowerCompositeOrdering) {
Animation* animation1 = timeline->Play(nullptr);
Animation* animation2 = timeline->Play(nullptr);
- EXPECT_TRUE(Animation::HasLowerPriority(animation1, animation2));
+ EXPECT_TRUE(Animation::HasLowerCompositeOrdering(
+ animation1, animation2,
+ Animation::CompareAnimationsOrdering::kPointerOrder));
}
TEST_F(AnimationAnimationTestNoCompositing, PlayAfterCancel) {
@@ -1133,6 +1153,45 @@ TEST_F(AnimationAnimationTestNoCompositing, PauseAfterCancel) {
EXPECT_FALSE(animation->startTime());
}
+// crbug.com/1052217
+TEST_F(AnimationAnimationTestNoCompositing, SetPlaybackRateAfterFinish) {
+ animation->setEffect(MakeAnimation(30, Timing::FillMode::FORWARDS));
+ animation->finish();
+ animation->Update(kTimingUpdateOnDemand);
+ EXPECT_EQ("finished", animation->playState());
+ EXPECT_EQ(base::nullopt, animation->TimeToEffectChange());
+
+ // Reversing a finished animation marks the animation as outdated. Required
+ // to recompute the time to next interval.
+ animation->setPlaybackRate(-1);
+ EXPECT_EQ("running", animation->playState());
+ EXPECT_EQ(animation->playbackRate(), -1);
+ EXPECT_TRUE(animation->Outdated());
+ animation->Update(kTimingUpdateOnDemand);
+ EXPECT_EQ(0, animation->TimeToEffectChange()->InSecondsF());
+ EXPECT_FALSE(animation->Outdated());
+}
+
+TEST_F(AnimationAnimationTestNoCompositing, UpdatePlaybackRateAfterFinish) {
+ animation->setEffect(MakeAnimation(30, Timing::FillMode::FORWARDS));
+ animation->finish();
+ animation->Update(kTimingUpdateOnDemand);
+ EXPECT_EQ("finished", animation->playState());
+ EXPECT_EQ(base::nullopt, animation->TimeToEffectChange());
+
+ // Reversing a finished animation marks the animation as outdated. Required
+ // to recompute the time to next interval. The pending playback rate is
+ // immediately applied when updatePlaybackRate is called on a non-running
+ // animation.
+ animation->updatePlaybackRate(-1);
+ EXPECT_EQ("running", animation->playState());
+ EXPECT_EQ(animation->playbackRate(), -1);
+ EXPECT_TRUE(animation->Outdated());
+ animation->Update(kTimingUpdateOnDemand);
+ EXPECT_EQ(0, animation->TimeToEffectChange()->InSecondsF());
+ EXPECT_FALSE(animation->Outdated());
+}
+
TEST_F(AnimationAnimationTestCompositeAfterPaint,
NoCompositeWithoutCompositedElementId) {
SetBodyInnerHTML(
@@ -1269,7 +1328,7 @@ TEST_F(AnimationAnimationTestCompositing, PreCommitRecordsHistograms) {
SecureContextMode::kInsecureContext,
nullptr);
- ToKeyframeEffect(animation->effect())
+ To<KeyframeEffect>(animation->effect())
->SetKeyframes({start_keyframe, end_keyframe});
UpdateAllLifecyclePhasesForTest();
{
@@ -1282,6 +1341,22 @@ TEST_F(AnimationAnimationTestCompositing, PreCommitRecordsHistograms) {
}
}
+// crbug.com/990000.
+TEST_F(AnimationAnimationTestCompositing, ReplaceCompositedAnimation) {
+ const std::string histogram_name =
+ "Blink.Animation.CompositedAnimationFailureReason";
+
+ // Start with a composited animation.
+ ResetWithCompositedAnimation();
+ ASSERT_TRUE(animation->HasActiveAnimationsOnCompositor());
+
+ // Replace the animation. The new animation should not be incompatible and
+ // therefore able to run on the compositor.
+ animation->cancel();
+ MakeCompositedAnimation();
+ ASSERT_TRUE(animation->HasActiveAnimationsOnCompositor());
+}
+
TEST_F(AnimationAnimationTestCompositing, SetKeyframesCausesCompositorPending) {
ResetWithCompositedAnimation();
@@ -1307,11 +1382,26 @@ TEST_F(AnimationAnimationTestCompositing, SetKeyframesCausesCompositorPending) {
keyframes.push_back(start_keyframe);
keyframes.push_back(end_keyframe);
- ToKeyframeEffect(animation->effect())->SetKeyframes(keyframes);
+ To<KeyframeEffect>(animation->effect())->SetKeyframes(keyframes);
EXPECT_TRUE(animation->CompositorPendingForTesting());
}
+// crbug.com/1057076
+// Infinite duration animations should not run on the compositor.
+TEST_F(AnimationAnimationTestCompositing, InfiniteDurationAnimation) {
+ ResetWithCompositedAnimation();
+ EXPECT_EQ(CompositorAnimations::kNoFailure,
+ animation->CheckCanStartAnimationOnCompositor(nullptr));
+
+ OptionalEffectTiming* effect_timing = OptionalEffectTiming::Create();
+ effect_timing->setDuration(UnrestrictedDoubleOrString::FromUnrestrictedDouble(
+ std::numeric_limits<double>::infinity()));
+ animation->effect()->updateTiming(effect_timing);
+ EXPECT_EQ(CompositorAnimations::kEffectHasUnsupportedTimingParameters,
+ animation->CheckCanStartAnimationOnCompositor(nullptr));
+}
+
// Verifies correctness of scroll linked animation current and start times in
// various animation states.
TEST_F(AnimationAnimationTestNoCompositing, ScrollLinkedAnimationCreation) {
@@ -1328,7 +1418,8 @@ TEST_F(AnimationAnimationTestNoCompositing, ScrollLinkedAnimationCreation) {
LayoutBoxModelObject* scroller =
ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller"));
PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea();
- scrollable_area->SetScrollOffset(ScrollOffset(0, 20), kProgrammaticScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 20),
+ mojom::blink::ScrollType::kProgrammatic);
ScrollTimelineOptions* options = ScrollTimelineOptions::Create();
DoubleOrScrollTimelineAutoKeyword time_range =
DoubleOrScrollTimelineAutoKeyword::FromDouble(100);
@@ -1353,7 +1444,7 @@ TEST_F(AnimationAnimationTestNoCompositing, ScrollLinkedAnimationCreation) {
// Verify start and current times in Pending state.
scroll_animation->startTime(is_null);
EXPECT_TRUE(is_null);
- EXPECT_EQ(0, scroll_animation->currentTime(is_null));
+ EXPECT_EQ(20, scroll_animation->currentTime(is_null));
EXPECT_FALSE(is_null);
UpdateAllLifecyclePhasesForTest();
@@ -1364,7 +1455,9 @@ TEST_F(AnimationAnimationTestNoCompositing, ScrollLinkedAnimationCreation) {
EXPECT_FALSE(is_null);
// Verify current time after scroll.
- scrollable_area->SetScrollOffset(ScrollOffset(0, 40), kProgrammaticScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 40),
+ mojom::blink::ScrollType::kProgrammatic);
+ SimulateFrameForScrollAnimations();
EXPECT_EQ(40, scroll_animation->currentTime(is_null));
EXPECT_FALSE(is_null);
}
@@ -1487,4 +1580,143 @@ TEST_F(AnimationAnimationTestNoCompositing,
EXPECT_FALSE(animation->HasPendingActivity());
}
+class AnimationPendingAnimationsTest : public RenderingTest {
+ public:
+ AnimationPendingAnimationsTest()
+ : RenderingTest(MakeGarbageCollected<SingleChildLocalFrameClient>()) {}
+
+ enum CompositingMode { kComposited, kNonComposited };
+
+ void SetUp() override {
+ EnableCompositing();
+ RenderingTest::SetUp();
+ GetDocument().GetAnimationClock().ResetTimeForTesting();
+ timeline = GetDocument().Timeline();
+ timeline->ResetForTesting();
+ }
+
+ Animation* MakeAnimation(const char* target, CompositingMode mode) {
+ 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);
+
+ Animation* animation = timeline->Play(
+ MakeGarbageCollected<KeyframeEffect>(element, model, timing));
+
+ if (mode == kNonComposited) {
+ // Having a playback rate of zero is one of several ways to force an
+ // animation to be non-composited.
+ animation->updatePlaybackRate(0);
+ }
+
+ return animation;
+ }
+
+ bool Update() {
+ UpdateAllLifecyclePhasesForTest();
+ GetDocument().GetAnimationClock().UpdateTime(base::TimeTicks());
+ return GetDocument().GetPendingAnimations().Update(nullptr, true);
+ }
+
+ void NotifyAnimationStarted(Animation* animation) {
+ animation->GetDocument()
+ ->GetPendingAnimations()
+ .NotifyCompositorAnimationStarted(0, animation->CompositorGroup());
+ }
+
+ void restartAnimation(Animation* animation) {
+ animation->cancel();
+ animation->play();
+ }
+
+ Persistent<DocumentTimeline> timeline;
+};
+
+TEST_F(AnimationPendingAnimationsTest, PendingAnimationStartSynchronization) {
+ RunDocumentLifecycle();
+ SetBodyInnerHTML("<div id='foo'></div><div id='bar'></div>");
+
+ Persistent<Animation> animA = MakeAnimation("foo", kComposited);
+ Persistent<Animation> animB = MakeAnimation("bar", kNonComposited);
+
+ // B's start time synchronized with A's start time.
+ EXPECT_TRUE(Update());
+ EXPECT_TRUE(animA->pending());
+ EXPECT_TRUE(animB->pending());
+ EXPECT_TRUE(animA->HasActiveAnimationsOnCompositor());
+ EXPECT_FALSE(animB->HasActiveAnimationsOnCompositor());
+ NotifyAnimationStarted(animA);
+ EXPECT_FALSE(animA->pending());
+ EXPECT_FALSE(animB->pending());
+}
+
+TEST_F(AnimationPendingAnimationsTest,
+ PendingAnimationCancelUnblocksSynchronizedStart) {
+ RunDocumentLifecycle();
+ SetBodyInnerHTML("<div id='foo'></div><div id='bar'></div>");
+
+ Persistent<Animation> animA = MakeAnimation("foo", kComposited);
+ Persistent<Animation> animB = MakeAnimation("bar", kNonComposited);
+
+ EXPECT_TRUE(Update());
+ EXPECT_TRUE(animA->pending());
+ EXPECT_TRUE(animB->pending());
+ animA->cancel();
+
+ // Animation A no longer blocks B from starting.
+ EXPECT_FALSE(Update());
+ EXPECT_FALSE(animB->pending());
+}
+
+TEST_F(AnimationPendingAnimationsTest,
+ PendingAnimationOnlySynchronizeStartsOfNewlyPendingAnimations) {
+ RunDocumentLifecycle();
+ SetBodyInnerHTML(
+ "<div id='foo'></div><div id='bar'></div><div id='baz'></div>");
+
+ Persistent<Animation> animA = MakeAnimation("foo", kComposited);
+ Persistent<Animation> animB = MakeAnimation("bar", kNonComposited);
+
+ // This test simulates the conditions in crbug.com/666710. The start of a
+ // non-composited animation is deferred in order to synchronize with a
+ // composited animation, which is canceled before it starts. Subsequent frames
+ // produce new composited animations which prevented the non-composited
+ // animation from ever starting. Non-composited animations should not be
+ // synchronize with new composited animations if queued up in a prior call to
+ // PendingAnimations::Update.
+ EXPECT_TRUE(Update());
+ EXPECT_TRUE(animA->pending());
+ EXPECT_TRUE(animB->pending());
+ animA->cancel();
+
+ Persistent<Animation> animC = MakeAnimation("baz", kComposited);
+ Persistent<Animation> animD = MakeAnimation("bar", kNonComposited);
+
+ EXPECT_TRUE(Update());
+ // B's is unblocked despite newly created composited animation.
+ EXPECT_FALSE(animB->pending());
+ EXPECT_TRUE(animC->pending());
+ // D's start time is synchronized with C's start.
+ EXPECT_TRUE(animD->pending());
+ NotifyAnimationStarted(animC);
+ EXPECT_FALSE(animC->pending());
+ EXPECT_FALSE(animD->pending());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/animation_test_helper.cc b/chromium/third_party/blink/renderer/core/animation/animation_test_helper.cc
index a7bf2c27990..88cc4e0ac9a 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation_test_helper.cc
+++ b/chromium/third_party/blink/renderer/core/animation/animation_test_helper.cc
@@ -8,7 +8,6 @@
#include "third_party/blink/renderer/core/animation/css_interpolation_environment.h"
#include "third_party/blink/renderer/core/animation/css_interpolation_types_map.h"
#include "third_party/blink/renderer/core/animation/invalidatable_interpolation.h"
-#include "third_party/blink/renderer/core/css/css_pending_interpolation_value.h"
#include "third_party/blink/renderer/core/css/resolver/style_cascade.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -17,39 +16,6 @@
namespace blink {
-namespace {
-
-class TestAnimator : public StyleCascade::Animator {
- STACK_ALLOCATED();
-
- public:
- TestAnimator(StyleResolverState& state,
- StyleCascade& cascade,
- CSSInterpolationTypesMap& map,
- const ActiveInterpolations& interpolations)
- : state_(state),
- cascade_(cascade),
- map_(map),
- interpolations_(interpolations) {}
-
- void Apply(const CSSProperty&,
- const cssvalue::CSSPendingInterpolationValue& value,
- StyleCascade::Resolver& resolver) override {
- // Ignore CSSProperty here. We assume this function is only called once
- // for each invocation of EnsureInterpolatedValueCached.
- CSSInterpolationEnvironment environment(map_, state_, &cascade_, &resolver);
- InvalidatableInterpolation::ApplyStack(interpolations_, environment);
- }
-
- private:
- StyleResolverState& state_;
- StyleCascade& cascade_;
- CSSInterpolationTypesMap& map_;
- const ActiveInterpolations& interpolations_;
-};
-
-} // namespace
-
void SetV8ObjectPropertyAsString(v8::Isolate* isolate,
v8::Local<v8::Object> object,
const StringView& name,
@@ -80,20 +46,19 @@ void EnsureInterpolatedValueCached(const ActiveInterpolations& interpolations,
auto style = ComputedStyle::Create();
StyleResolverState state(document, *element, style.get(), style.get());
state.SetStyle(style);
- CSSInterpolationTypesMap map(state.GetDocument().GetPropertyRegistry(),
- state.GetDocument());
if (RuntimeEnabledFeatures::CSSCascadeEnabled()) {
// We must apply the animation effects via StyleCascade when the cascade
// is enabled.
StyleCascade cascade(state);
- auto type = cssvalue::CSSPendingInterpolationValue::Type::kCSSProperty;
- auto* pending = cssvalue::CSSPendingInterpolationValue::Create(type);
- auto origin = StyleCascade::Origin::kAuthor;
- cascade.Add(*CSSPropertyName::From("--unused"), pending, origin);
- TestAnimator animator(state, cascade, map, interpolations);
- cascade.Apply(animator);
+ ActiveInterpolationsMap map;
+ map.Set(PropertyHandle("--unused"), interpolations);
+
+ cascade.AddInterpolations(&map, CascadeOrigin::kAnimation);
+ cascade.Apply();
} else {
+ CSSInterpolationTypesMap map(state.GetDocument().GetPropertyRegistry(),
+ state.GetDocument());
CSSInterpolationEnvironment environment(map, state, nullptr);
InvalidatableInterpolation::ApplyStack(interpolations, environment);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/animation_time_delta.h b/chromium/third_party/blink/renderer/core/animation/animation_time_delta.h
index b1af4e69a8e..7984cebe254 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation_time_delta.h
+++ b/chromium/third_party/blink/renderer/core/animation/animation_time_delta.h
@@ -69,6 +69,9 @@ class CORE_EXPORT AnimationTimeDelta {
AnimationTimeDelta& operator+=(AnimationTimeDelta other) {
return *this = (*this + other);
}
+ AnimationTimeDelta operator-(AnimationTimeDelta other) const {
+ return AnimationTimeDelta(delta_ - other.delta_);
+ }
template <typename T>
AnimationTimeDelta operator*(T a) const {
return AnimationTimeDelta(delta_ * a);
diff --git a/chromium/third_party/blink/renderer/core/animation/animation_timeline.cc b/chromium/third_party/blink/renderer/core/animation/animation_timeline.cc
new file mode 100644
index 00000000000..df6a5297fe7
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/animation/animation_timeline.cc
@@ -0,0 +1,240 @@
+// 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/animation/animation_timeline.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/dom/document.h"
+#include "third_party/blink/renderer/core/dom/element.h"
+#include "third_party/blink/renderer/core/frame/local_frame_view.h"
+#include "third_party/blink/renderer/core/page/page.h"
+
+namespace blink {
+
+AnimationTimeline::AnimationTimeline(Document* document)
+ : document_(document), outdated_animation_count_(0) {
+ document_->GetDocumentAnimations().AddTimeline(*this);
+}
+
+void AnimationTimeline::AnimationAttached(Animation* animation) {
+ DCHECK(!animations_.Contains(animation));
+ animations_.insert(animation);
+}
+
+void AnimationTimeline::AnimationDetached(Animation* animation) {
+ animations_.erase(animation);
+ animations_needing_update_.erase(animation);
+ if (animation->Outdated())
+ outdated_animation_count_--;
+}
+
+bool CompareAnimations(const Member<Animation>& left,
+ const Member<Animation>& right) {
+ // This uses pointer order comparision because it is less expensive and
+ // element order doesn't affect the animation result(http://crbug.com/1047316)
+ return Animation::HasLowerCompositeOrdering(
+ left.Get(), right.Get(),
+ Animation::CompareAnimationsOrdering::kPointerOrder);
+}
+
+double AnimationTimeline::currentTime(bool& is_null) {
+ base::Optional<base::TimeDelta> result = CurrentPhaseAndTime().time;
+
+ is_null = !result.has_value();
+ return result ? result->InMillisecondsF()
+ : std::numeric_limits<double>::quiet_NaN();
+}
+
+double AnimationTimeline::currentTime() {
+ base::Optional<base::TimeDelta> result = CurrentPhaseAndTime().time;
+ return result ? result->InMillisecondsF()
+ : std::numeric_limits<double>::quiet_NaN();
+}
+
+base::Optional<double> AnimationTimeline::CurrentTime() {
+ base::Optional<base::TimeDelta> result = CurrentPhaseAndTime().time;
+ return result ? base::make_optional(result->InMillisecondsF())
+ : base::nullopt;
+}
+
+base::Optional<double> AnimationTimeline::CurrentTimeSeconds() {
+ base::Optional<base::TimeDelta> result = CurrentPhaseAndTime().time;
+ return result ? base::make_optional(result->InSecondsF()) : base::nullopt;
+}
+
+String AnimationTimeline::phase() {
+ switch (CurrentPhaseAndTime().phase) {
+ case TimelinePhase::kInactive:
+ return "inactive";
+ case TimelinePhase::kBefore:
+ return "before";
+ case TimelinePhase::kActive:
+ return "active";
+ case TimelinePhase::kAfter:
+ return "after";
+ }
+}
+
+void AnimationTimeline::ClearOutdatedAnimation(Animation* animation) {
+ DCHECK(!animation->Outdated());
+ outdated_animation_count_--;
+}
+
+bool AnimationTimeline::NeedsAnimationTimingUpdate() {
+ PhaseAndTime current_phase_and_time = CurrentPhaseAndTime();
+ if (current_phase_and_time == last_current_phase_and_time_)
+ return false;
+
+ // We allow |last_current_phase_and_time_| to advance here when there
+ // are no animations to allow animations spawned during style
+ // recalc to not invalidate this flag.
+ if (animations_needing_update_.IsEmpty())
+ last_current_phase_and_time_ = current_phase_and_time;
+
+ return !animations_needing_update_.IsEmpty();
+}
+
+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;
+ }
+
+ last_current_phase_and_time_ = current_phase_and_time;
+
+ HeapVector<Member<Animation>> animations;
+ animations.ReserveInitialCapacity(animations_needing_update_.size());
+ for (Animation* animation : animations_needing_update_)
+ animations.push_back(animation);
+
+ std::sort(animations.begin(), animations.end(), CompareAnimations);
+
+ for (Animation* animation : animations) {
+ if (!animation->Update(reason)) {
+ animations_needing_update_.erase(animation);
+ continue;
+ }
+ if (maybe_update_compositor_scroll_timeline)
+ animation->UpdateCompositorScrollTimeline();
+ }
+
+ DCHECK_EQ(outdated_animation_count_, 0U);
+ DCHECK(last_current_phase_and_time_ == CurrentPhaseAndTime());
+
+#if DCHECK_IS_ON()
+ for (const auto& animation : animations_needing_update_)
+ DCHECK(!animation->Outdated());
+#endif
+ // Explicitly free the backing store to avoid memory regressions.
+ // TODO(bikineev): Revisit when young generation is done.
+ animations.clear();
+
+ if (RuntimeEnabledFeatures::WebAnimationsAPIEnabled() &&
+ reason == kTimingUpdateForAnimationFrame) {
+ RemoveReplacedAnimations();
+ }
+}
+
+// https://drafts.csswg.org/web-animations-1/#removing-replaced-animations
+void AnimationTimeline::RemoveReplacedAnimations() {
+ // Group replaceable animations by target element.
+ HeapHashMap<Member<Element>, Member<HeapVector<Member<Animation>>>>
+ replaceable_animations;
+ for (Animation* animation : animations_) {
+ // Initial conditions for removal:
+ // * has an associated animation effect whose effect target is a descendant
+ // of doc, and
+ // * is replaceable
+ if (!animation->IsReplaceable())
+ continue;
+ DCHECK(animation->effect());
+ Element* target = To<KeyframeEffect>(animation->effect())->target();
+ DCHECK(target);
+ if (target->GetDocument() != animation->GetDocument())
+ continue;
+
+ auto inserted = replaceable_animations.insert(target, nullptr);
+ if (inserted.is_new_entry) {
+ inserted.stored_value->value =
+ MakeGarbageCollected<HeapVector<Member<Animation>>>();
+ }
+ inserted.stored_value->value->push_back(animation);
+ }
+
+ HeapVector<Member<Animation>> animations_to_remove;
+ for (auto& elem_it : replaceable_animations) {
+ HeapVector<Member<Animation>>* animations = elem_it.value;
+
+ // Only elements with multiple animations in the replaceable state need to
+ // be checked.
+ if (animations->size() == 1)
+ continue;
+
+ // By processing in decreasing order by priority, we can perform a single
+ // pass for discovery of replaced properties.
+ std::sort(animations->begin(), animations->end(), CompareAnimations);
+ PropertyHandleSet replaced_properties;
+ for (auto anim_it = animations->rbegin(); anim_it != animations->rend();
+ anim_it++) {
+ // Remaining conditions for removal:
+ // * has a replace state of active, and
+ // * for which there exists for each target property of every animation
+ // effect associated with animation, an animation effect associated with
+ // a replaceable animation with a higher composite order than animation
+ // that includes the same target property.
+
+ // Only active animations can be removed. We still need to go through
+ // the process of iterating over properties if not removable to update
+ // the set of properties being replaced.
+ bool replace = (*anim_it)->ReplaceStateActive();
+ PropertyHandleSet animation_properties =
+ To<KeyframeEffect>((*anim_it)->effect())->Model()->Properties();
+ for (const auto& property : animation_properties) {
+ auto inserted = replaced_properties.insert(property);
+ if (inserted.is_new_entry) {
+ // Top-most compositor order animation affecting this property.
+ replace = false;
+ }
+ }
+ if (replace)
+ animations_to_remove.push_back(*anim_it);
+ }
+ }
+
+ // The list of animations for removal is constructed in reverse composite
+ // ordering for efficiency. Flip the ordering to ensure that events are
+ // dispatched in composite order.
+ // TODO(crbug.com/981905): Add test for ordering once onremove is implemented.
+ for (auto it = animations_to_remove.rbegin();
+ it != animations_to_remove.rend(); it++) {
+ (*it)->RemoveReplacedAnimation();
+ }
+}
+
+void AnimationTimeline::SetOutdatedAnimation(Animation* animation) {
+ DCHECK(animation->Outdated());
+ outdated_animation_count_++;
+ animations_needing_update_.insert(animation);
+ if (IsActive() && !document_->GetPage()->Animator().IsServicingAnimations())
+ ScheduleServiceOnNextFrame();
+}
+
+void AnimationTimeline::ScheduleServiceOnNextFrame() {
+ if (document_->View())
+ document_->View()->ScheduleAnimation();
+}
+
+void AnimationTimeline::Trace(Visitor* visitor) {
+ visitor->Trace(document_);
+ visitor->Trace(animations_needing_update_);
+ visitor->Trace(animations_);
+ ScriptWrappable::Trace(visitor);
+}
+
+} // namespace blink
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 747f3b4a6cc..1c024f2ecc4 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation_timeline.h
+++ b/chromium/third_party/blink/renderer/core/animation/animation_timeline.h
@@ -5,34 +5,42 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATION_TIMELINE_H_
#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"
namespace blink {
-class Animation;
class Document;
+enum class TimelinePhase { kInactive, kBefore, kActive, kAfter };
+
class CORE_EXPORT AnimationTimeline : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
+ struct PhaseAndTime {
+ TimelinePhase phase;
+ base::Optional<base::TimeDelta> time;
+ bool operator==(const PhaseAndTime& other) const {
+ return phase == other.phase && time == other.time;
+ }
+ bool operator!=(const PhaseAndTime& other) const {
+ return !(*this == other);
+ }
+ };
+
+ AnimationTimeline(Document*);
~AnimationTimeline() override = default;
- virtual double currentTime(bool&) = 0;
+ double currentTime(bool& is_null);
+ double currentTime();
+ base::Optional<double> CurrentTime();
+ base::Optional<double> CurrentTimeSeconds();
- base::Optional<double> CurrentTime() {
- bool is_null;
- double current_time_ms = currentTime(is_null);
- return is_null ? base::nullopt : base::make_optional(current_time_ms);
- }
-
- base::Optional<double> CurrentTimeSeconds() {
- base::Optional<double> current_time_ms = CurrentTime();
- if (current_time_ms)
- return current_time_ms.value() / 1000;
- return current_time_ms;
- }
+ String phase();
virtual bool IsDocumentTimeline() const { return false; }
virtual bool IsScrollTimeline() const { return false; }
@@ -46,9 +54,54 @@ class CORE_EXPORT AnimationTimeline : public ScriptWrappable {
// Changing scroll-linked animation start_time initialization is under
// consideration here: https://github.com/w3c/csswg-drafts/issues/2075.
virtual base::Optional<base::TimeDelta> InitialStartTimeForAnimations() = 0;
- virtual Document* GetDocument() = 0;
- virtual void AnimationAttached(Animation*) = 0;
- virtual void AnimationDetached(Animation*) = 0;
+ Document* GetDocument() { return document_; }
+ virtual void AnimationAttached(Animation*);
+ virtual void AnimationDetached(Animation*);
+
+ // Updates animation timing.
+ virtual void ServiceAnimations(TimingUpdateReason);
+ // Schedules next animations timing update.
+ virtual void ScheduleNextService() = 0;
+ // Schedules animation timing update on next frame.
+ virtual void ScheduleServiceOnNextFrame();
+
+ virtual bool NeedsAnimationTimingUpdate();
+ virtual bool HasAnimations() const { return !animations_.IsEmpty(); }
+ virtual bool HasOutdatedAnimation() const {
+ return outdated_animation_count_ > 0;
+ }
+ void SetOutdatedAnimation(Animation*);
+ void ClearOutdatedAnimation(Animation*);
+
+ virtual wtf_size_t AnimationsNeedingUpdateCount() const {
+ return animations_needing_update_.size();
+ }
+ const HeapHashSet<WeakMember<Animation>>& GetAnimations() const {
+ return animations_;
+ }
+
+ CompositorAnimationTimeline* CompositorTimeline() const {
+ return compositor_timeline_.get();
+ }
+ virtual CompositorAnimationTimeline* EnsureCompositorTimeline() = 0;
+
+ void Trace(Visitor*) override;
+
+ protected:
+ virtual PhaseAndTime CurrentPhaseAndTime() = 0;
+ void RemoveReplacedAnimations();
+
+ Member<Document> document_;
+ unsigned outdated_animation_count_;
+ // Animations which will be updated on the next frame
+ // i.e. current, in effect, or had timing changed
+ HeapHashSet<Member<Animation>> animations_needing_update_;
+ // All animations attached to this timeline.
+ HeapHashSet<WeakMember<Animation>> animations_;
+
+ std::unique_ptr<CompositorAnimationTimeline> compositor_timeline_;
+
+ base::Optional<PhaseAndTime> last_current_phase_and_time_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/animation_timeline.idl b/chromium/third_party/blink/renderer/core/animation/animation_timeline.idl
index cf19ed3f89b..19013b3dd53 100644
--- a/chromium/third_party/blink/renderer/core/animation/animation_timeline.idl
+++ b/chromium/third_party/blink/renderer/core/animation/animation_timeline.idl
@@ -4,9 +4,12 @@
// https://drafts.csswg.org/web-animations/#the-animationtimeline-interface
+enum TimelinePhase { "inactive", "before", "active", "after" };
[
RuntimeEnabled=WebAnimationsAPI,
Exposed=Window
] interface AnimationTimeline {
- readonly attribute double? currentTime;
+ // TODO(crbug.com/1060971): Remove ImplementedAs.
+ [ImplementedAs=CurrentTime] readonly attribute double? currentTime;
+ [RuntimeEnabled=ScrollTimeline] readonly attribute TimelinePhase phase;
};
diff --git a/chromium/third_party/blink/renderer/core/animation/basic_shape_interpolation_functions.cc b/chromium/third_party/blink/renderer/core/animation/basic_shape_interpolation_functions.cc
index 8fd7531003f..ed8acf133da 100644
--- a/chromium/third_party/blink/renderer/core/animation/basic_shape_interpolation_functions.cc
+++ b/chromium/third_party/blink/renderer/core/animation/basic_shape_interpolation_functions.cc
@@ -69,7 +69,15 @@ class BasicShapeNonInterpolableValue : public NonInterpolableValue {
};
DEFINE_NON_INTERPOLABLE_VALUE_TYPE(BasicShapeNonInterpolableValue);
-DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(BasicShapeNonInterpolableValue);
+template <>
+struct DowncastTraits<BasicShapeNonInterpolableValue> {
+ static bool AllowFrom(const NonInterpolableValue* value) {
+ return value && AllowFrom(*value);
+ }
+ static bool AllowFrom(const NonInterpolableValue& value) {
+ return value.GetType() == BasicShapeNonInterpolableValue::static_type_;
+ }
+};
namespace {
@@ -216,7 +224,7 @@ scoped_refptr<BasicShape> CreateBasicShape(
const InterpolableValue& interpolable_value,
const CSSToLengthConversionData& conversion_data) {
scoped_refptr<BasicShapeCircle> circle = BasicShapeCircle::Create();
- const InterpolableList& list = ToInterpolableList(interpolable_value);
+ const auto& list = To<InterpolableList>(interpolable_value);
circle->SetCenterX(
CreateCoordinate(*list.Get(kCircleCenterXIndex), conversion_data));
circle->SetCenterY(
@@ -289,7 +297,7 @@ scoped_refptr<BasicShape> CreateBasicShape(
const InterpolableValue& interpolable_value,
const CSSToLengthConversionData& conversion_data) {
scoped_refptr<BasicShapeEllipse> ellipse = BasicShapeEllipse::Create();
- const InterpolableList& list = ToInterpolableList(interpolable_value);
+ const auto& list = To<InterpolableList>(interpolable_value);
ellipse->SetCenterX(
CreateCoordinate(*list.Get(kEllipseCenterXIndex), conversion_data));
ellipse->SetCenterY(
@@ -408,7 +416,7 @@ scoped_refptr<BasicShape> CreateBasicShape(
const InterpolableValue& interpolable_value,
const CSSToLengthConversionData& conversion_data) {
scoped_refptr<BasicShapeInset> inset = BasicShapeInset::Create();
- const InterpolableList& list = ToInterpolableList(interpolable_value);
+ const auto& list = To<InterpolableList>(interpolable_value);
inset->SetTop(To<InterpolableLength>(*list.Get(kInsetTopIndex))
.CreateLength(conversion_data, kValueRangeAll));
inset->SetRight(To<InterpolableLength>(*list.Get(kInsetRightIndex))
@@ -473,7 +481,7 @@ scoped_refptr<BasicShape> CreateBasicShape(
const CSSToLengthConversionData& conversion_data) {
scoped_refptr<BasicShapePolygon> polygon = BasicShapePolygon::Create();
polygon->SetWindRule(non_interpolable_value.GetWindRule());
- const InterpolableList& list = ToInterpolableList(interpolable_value);
+ const auto& list = To<InterpolableList>(interpolable_value);
wtf_size_t size = non_interpolable_value.size();
DCHECK_EQ(list.length(), size);
DCHECK_EQ(size % 2, 0U);
@@ -538,8 +546,8 @@ InterpolationValue basic_shape_interpolation_functions::MaybeConvertBasicShape(
std::unique_ptr<InterpolableValue>
basic_shape_interpolation_functions::CreateNeutralValue(
const NonInterpolableValue& untyped_non_interpolable_value) {
- const BasicShapeNonInterpolableValue& non_interpolable_value =
- ToBasicShapeNonInterpolableValue(untyped_non_interpolable_value);
+ const auto& non_interpolable_value =
+ To<BasicShapeNonInterpolableValue>(untyped_non_interpolable_value);
switch (non_interpolable_value.GetShapeType()) {
case BasicShape::kBasicShapeCircleType:
return circle_functions::CreateNeutralValue();
@@ -558,16 +566,16 @@ basic_shape_interpolation_functions::CreateNeutralValue(
bool basic_shape_interpolation_functions::ShapesAreCompatible(
const NonInterpolableValue& a,
const NonInterpolableValue& b) {
- return ToBasicShapeNonInterpolableValue(a).IsCompatibleWith(
- ToBasicShapeNonInterpolableValue(b));
+ return To<BasicShapeNonInterpolableValue>(a).IsCompatibleWith(
+ To<BasicShapeNonInterpolableValue>(b));
}
scoped_refptr<BasicShape> basic_shape_interpolation_functions::CreateBasicShape(
const InterpolableValue& interpolable_value,
const NonInterpolableValue& untyped_non_interpolable_value,
const CSSToLengthConversionData& conversion_data) {
- const BasicShapeNonInterpolableValue& non_interpolable_value =
- ToBasicShapeNonInterpolableValue(untyped_non_interpolable_value);
+ const auto& non_interpolable_value =
+ To<BasicShapeNonInterpolableValue>(untyped_non_interpolable_value);
switch (non_interpolable_value.GetShapeType()) {
case BasicShape::kBasicShapeCircleType:
return circle_functions::CreateBasicShape(interpolable_value,
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 98c38324791..bdb1f1b8a41 100644
--- a/chromium/third_party/blink/renderer/core/animation/compositor_animations.cc
+++ b/chromium/third_party/blink/renderer/core/animation/compositor_animations.cc
@@ -74,7 +74,7 @@ bool ConsiderAnimationAsIncompatible(const Animation& animation,
if (&animation == &animation_to_add)
return false;
- if (animation.pending())
+ if (animation.PendingInternal())
return true;
switch (animation.CalculateAnimationPlayState()) {
@@ -84,7 +84,9 @@ bool ConsiderAnimationAsIncompatible(const Animation& animation,
return true;
case Animation::kPaused:
case Animation::kFinished:
- if (Animation::HasLowerPriority(&animation, &animation_to_add)) {
+ if (Animation::HasLowerCompositeOrdering(
+ &animation, &animation_to_add,
+ Animation::CompareAnimationsOrdering::kPointerOrder)) {
return effect_to_add.AffectedByUnderlyingAnimations();
}
return true;
@@ -188,8 +190,7 @@ CompositorAnimations::CheckCanStartEffectOnCompositor(
const PaintArtifactCompositor* paint_artifact_compositor,
double animation_playback_rate) {
FailureReasons reasons = kNoFailure;
- const KeyframeEffectModelBase& keyframe_effect =
- ToKeyframeEffectModelBase(effect);
+ const auto& keyframe_effect = To<KeyframeEffectModelBase>(effect);
LayoutObject* layout_object = target_element.GetLayoutObject();
if (paint_artifact_compositor) {
@@ -238,7 +239,7 @@ CompositorAnimations::CheckCanStartEffectOnCompositor(
case CSSPropertyID::kTranslate:
case CSSPropertyID::kTransform:
if (keyframe->GetCompositorKeyframeValue() &&
- ToCompositorKeyframeTransform(
+ To<CompositorKeyframeTransform>(
keyframe->GetCompositorKeyframeValue())
->GetTransformOperations()
.DependsOnBoxSize()) {
@@ -247,7 +248,7 @@ CompositorAnimations::CheckCanStartEffectOnCompositor(
break;
case CSSPropertyID::kFilter:
if (keyframe->GetCompositorKeyframeValue() &&
- ToCompositorKeyframeFilterOperations(
+ To<CompositorKeyframeFilterOperations>(
keyframe->GetCompositorKeyframeValue())
->Operations()
.HasFilterThatMovesPixels()) {
@@ -275,8 +276,10 @@ CompositorAnimations::CheckCanStartEffectOnCompositor(
layout_object->GetDocument()))
reasons |= kUnsupportedCSSProperty;
// TODO: Add support for keyframes containing different types
- if (keyframes.front()->GetCompositorKeyframeValue()->GetType() !=
- keyframe_value->GetType()) {
+ if (!keyframes.front() ||
+ !keyframes.front()->GetCompositorKeyframeValue() ||
+ keyframes.front()->GetCompositorKeyframeValue()->GetType() !=
+ keyframe_value->GetType()) {
reasons |= kMixedKeyframeValueTypes;
}
} else {
@@ -335,7 +338,8 @@ CompositorAnimations::CheckCanStartEffectOnCompositor(
}
CompositorTiming out;
- if (!ConvertTimingForCompositor(timing, 0, out, animation_playback_rate)) {
+ if (!ConvertTimingForCompositor(timing, base::TimeDelta(), out,
+ animation_playback_rate)) {
reasons |= kEffectHasUnsupportedTimingParameters;
}
@@ -441,7 +445,7 @@ void CompositorAnimations::StartAnimationOnCompositor(
const Element& element,
int group,
base::Optional<double> start_time,
- double time_offset,
+ base::TimeDelta time_offset,
const Timing& timing,
const Animation* animation,
CompositorAnimation& compositor_animation,
@@ -456,8 +460,7 @@ void CompositorAnimations::StartAnimationOnCompositor(
nullptr, animation_playback_rate),
kNoFailure);
- const KeyframeEffectModelBase& keyframe_effect =
- ToKeyframeEffectModelBase(effect);
+ const auto& keyframe_effect = To<KeyframeEffectModelBase>(effect);
Vector<std::unique_ptr<CompositorKeyframeModel>> keyframe_models;
GetAnimationOnCompositor(element, timing, group, start_time, time_offset,
@@ -492,7 +495,7 @@ void CompositorAnimations::PauseAnimationForTestingOnCompositor(
const Element& element,
const Animation& animation,
int id,
- double pause_time) {
+ base::TimeDelta pause_time) {
DCHECK_EQ(CheckCanStartElementOnCompositor(element), kNoFailure);
CompositorAnimation* compositor_animation =
animation.GetCompositorAnimation();
@@ -539,7 +542,7 @@ void CompositorAnimations::AttachCompositedLayers(
bool CompositorAnimations::ConvertTimingForCompositor(
const Timing& timing,
- double time_offset,
+ base::TimeDelta time_offset,
CompositorTiming& out,
double animation_playback_rate) {
timing.AssertValid();
@@ -552,16 +555,25 @@ bool CompositorAnimations::ConvertTimingForCompositor(
return false;
if (!timing.iteration_duration || !timing.iteration_count ||
- timing.iteration_duration->is_zero())
+ timing.iteration_duration->is_zero() ||
+ timing.iteration_duration->is_max())
return false;
- out.adjusted_iteration_count =
- std::isfinite(timing.iteration_count) ? timing.iteration_count : -1;
+ // Compositor's time offset is positive for seeking into the animation.
+ DCHECK(animation_playback_rate);
+ out.scaled_time_offset = -base::TimeDelta::FromSecondsD(
+ timing.start_delay / animation_playback_rate) +
+ time_offset;
+ // Start delay is effectively +/- infinity.
+ if (out.scaled_time_offset.is_max() || out.scaled_time_offset.is_min())
+ return false;
+
+ out.adjusted_iteration_count = std::isfinite(timing.iteration_count)
+ ? timing.iteration_count
+ : std::numeric_limits<double>::infinity();
out.scaled_duration = timing.iteration_duration.value();
out.direction = timing.direction;
- // Compositor's time offset is positive for seeking into the animation.
- out.scaled_time_offset =
- -timing.start_delay / animation_playback_rate + time_offset;
+
out.playback_rate = animation_playback_rate;
out.fill_mode = timing.fill_mode == Timing::FillMode::AUTO
? Timing::FillMode::NONE
@@ -569,9 +581,9 @@ bool CompositorAnimations::ConvertTimingForCompositor(
out.iteration_start = timing.iteration_start;
DCHECK_GT(out.scaled_duration, AnimationTimeDelta());
- DCHECK(std::isfinite(out.scaled_time_offset));
DCHECK(out.adjusted_iteration_count > 0 ||
- out.adjusted_iteration_count == -1);
+ out.adjusted_iteration_count ==
+ std::numeric_limits<double>::infinity());
DCHECK(std::isfinite(out.playback_rate) && out.playback_rate);
DCHECK_GE(out.iteration_start, 0);
@@ -588,7 +600,7 @@ void AddKeyframeToCurve(CompositorFilterAnimationCurve& curve,
CompositorFilterKeyframe filter_keyframe(
keyframe->Offset(),
builder.BuildFilterOperations(
- ToCompositorKeyframeFilterOperations(value)->Operations()),
+ To<CompositorKeyframeFilterOperations>(value)->Operations()),
keyframe_timing_function);
curve.AddKeyframe(filter_keyframe);
}
@@ -598,7 +610,7 @@ void AddKeyframeToCurve(CompositorFloatAnimationCurve& curve,
const CompositorKeyframeValue* value,
const TimingFunction& keyframe_timing_function) {
CompositorFloatKeyframe float_keyframe(
- keyframe->Offset(), ToCompositorKeyframeDouble(value)->ToDouble(),
+ keyframe->Offset(), To<CompositorKeyframeDouble>(value)->ToDouble(),
keyframe_timing_function);
curve.AddKeyframe(float_keyframe);
}
@@ -608,7 +620,7 @@ void AddKeyframeToCurve(CompositorColorAnimationCurve& curve,
const CompositorKeyframeValue* value,
const TimingFunction& keyframe_timing_function) {
CompositorColorKeyframe color_keyframe(
- keyframe->Offset(), ToCompositorKeyframeColor(value)->ToColor(),
+ keyframe->Offset(), To<CompositorKeyframeColor>(value)->ToColor(),
keyframe_timing_function);
curve.AddKeyframe(color_keyframe);
}
@@ -619,7 +631,7 @@ void AddKeyframeToCurve(CompositorTransformAnimationCurve& curve,
const TimingFunction& keyframe_timing_function) {
CompositorTransformOperations ops;
ToCompositorTransformOperations(
- ToCompositorKeyframeTransform(value)->GetTransformOperations(), &ops);
+ To<CompositorKeyframeTransform>(value)->GetTransformOperations(), &ops);
CompositorTransformKeyframe transform_keyframe(
keyframe->Offset(), std::move(ops), keyframe_timing_function);
@@ -651,7 +663,7 @@ void CompositorAnimations::GetAnimationOnCompositor(
const Timing& timing,
int group,
base::Optional<double> start_time,
- double time_offset,
+ base::TimeDelta time_offset,
const KeyframeEffectModelBase& effect,
Vector<std::unique_ptr<CompositorKeyframeModel>>& keyframe_models,
double animation_playback_rate) {
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 33c7f698c8f..85aa7a2c2e9 100644
--- a/chromium/third_party/blink/renderer/core/animation/compositor_animations.h
+++ b/chromium/third_party/blink/renderer/core/animation/compositor_animations.h
@@ -113,7 +113,7 @@ class CORE_EXPORT CompositorAnimations {
const Element&,
int group,
base::Optional<double> start_time,
- double time_offset,
+ base::TimeDelta time_offset,
const Timing&,
const Animation*,
CompositorAnimation&,
@@ -126,14 +126,14 @@ class CORE_EXPORT CompositorAnimations {
static void PauseAnimationForTestingOnCompositor(const Element&,
const Animation&,
int id,
- double pause_time);
+ base::TimeDelta pause_time);
static void AttachCompositedLayers(Element&, CompositorAnimation*);
struct CompositorTiming {
Timing::PlaybackDirection direction;
AnimationTimeDelta scaled_duration;
- double scaled_time_offset;
+ base::TimeDelta scaled_time_offset;
double adjusted_iteration_count;
double playback_rate;
Timing::FillMode fill_mode;
@@ -141,7 +141,7 @@ class CORE_EXPORT CompositorAnimations {
};
static bool ConvertTimingForCompositor(const Timing&,
- double time_offset,
+ base::TimeDelta time_offset,
CompositorTiming& out,
double animation_playback_rate);
@@ -150,7 +150,7 @@ class CORE_EXPORT CompositorAnimations {
const Timing&,
int group,
base::Optional<double> start_time,
- double time_offset,
+ base::TimeDelta time_offset,
const KeyframeEffectModelBase&,
Vector<std::unique_ptr<CompositorKeyframeModel>>& animations,
double animation_playback_rate);
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 3dae9900487..28975a1cf5e 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
@@ -55,6 +55,7 @@
#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/frame/frame_test_helpers.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/layout/layout_object.h"
#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
@@ -171,7 +172,8 @@ class AnimationCompositorAnimationsTest : public PaintTestConfigurations,
public:
bool ConvertTimingForCompositor(const Timing& t,
CompositorAnimations::CompositorTiming& out) {
- return CompositorAnimations::ConvertTimingForCompositor(t, 0, out, 1);
+ return CompositorAnimations::ConvertTimingForCompositor(
+ t, base::TimeDelta(), out, 1);
}
CompositorAnimations::FailureReasons CanStartEffectOnCompositor(
@@ -206,8 +208,8 @@ class AnimationCompositorAnimationsTest : public PaintTestConfigurations,
Vector<std::unique_ptr<CompositorKeyframeModel>>& keyframe_models,
double animation_playback_rate) {
CompositorAnimations::GetAnimationOnCompositor(
- *element_, timing, 0, base::nullopt, 0, effect, keyframe_models,
- animation_playback_rate);
+ *element_, timing, 0, base::nullopt, base::TimeDelta(), effect,
+ keyframe_models, animation_playback_rate);
}
CompositorAnimations::FailureReasons
@@ -217,7 +219,7 @@ class AnimationCompositorAnimationsTest : public PaintTestConfigurations,
Keyframe* second = frame->CloneWithOffset(1);
frames.push_back(frame);
- frames.push_back(ToStringKeyframe(second));
+ frames.push_back(To<StringKeyframe>(second));
return CanStartEffectOnCompositor(
timing_, *MakeGarbageCollected<StringKeyframeEffectModel>(frames));
}
@@ -299,8 +301,8 @@ class AnimationCompositorAnimationsTest : public PaintTestConfigurations,
void SetCustomProperty(const String& name, const String& value) {
DummyExceptionStateForTesting exception_state;
- element_->style()->setProperty(&GetDocument(), name, value, g_empty_string,
- exception_state);
+ element_->style()->setProperty(GetDocument().GetExecutionContext(), name,
+ value, g_empty_string, exception_state);
EXPECT_FALSE(exception_state.HadException());
EXPECT_TRUE(element_->style()->getPropertyValue(name));
}
@@ -466,7 +468,7 @@ class AnimationCompositorAnimationsTest : public PaintTestConfigurations,
DCHECK_EQ(keyframe_timing_function->GetType(),
TimingFunction::Type::CUBIC_BEZIER);
const auto& cubic_timing_function =
- ToCubicBezierTimingFunction(*keyframe_timing_function);
+ To<CubicBezierTimingFunction>(*keyframe_timing_function);
EXPECT_EQ(cubic_timing_function.GetEaseType(), ease_type);
}
@@ -485,13 +487,14 @@ class AnimationCompositorAnimationsTest : public PaintTestConfigurations,
LocalFrame* GetFrame() const { return helper_.LocalMainFrame()->GetFrame(); }
void BeginFrame() {
- helper_.GetWebView()->MainFrameWidget()->BeginFrame(
- base::TimeTicks::Now(), false /* record_main_frame_metrics */);
+ helper_.GetWebView()
+ ->MainFrameWidgetBase()
+ ->SynchronouslyCompositeForTesting(base::TimeTicks::Now());
}
void ForceFullCompositingUpdate() {
helper_.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
}
private:
@@ -699,11 +702,11 @@ TEST_P(AnimationCompositorAnimationsTest,
timing_.start_delay = 2.0;
EXPECT_TRUE(ConvertTimingForCompositor(timing_, compositor_timing_));
- EXPECT_DOUBLE_EQ(-2.0, compositor_timing_.scaled_time_offset);
+ EXPECT_DOUBLE_EQ(-2.0, compositor_timing_.scaled_time_offset.InSecondsF());
timing_.start_delay = -2.0;
EXPECT_TRUE(ConvertTimingForCompositor(timing_, compositor_timing_));
- EXPECT_DOUBLE_EQ(2.0, compositor_timing_.scaled_time_offset);
+ EXPECT_DOUBLE_EQ(2.0, compositor_timing_.scaled_time_offset.InSecondsF());
}
TEST_P(AnimationCompositorAnimationsTest,
@@ -724,14 +727,16 @@ TEST_P(AnimationCompositorAnimationsTest,
timing_.iteration_count = std::numeric_limits<double>::infinity();
EXPECT_TRUE(ConvertTimingForCompositor(timing_, compositor_timing_));
- EXPECT_EQ(-1, compositor_timing_.adjusted_iteration_count);
+ EXPECT_EQ(std::numeric_limits<double>::infinity(),
+ compositor_timing_.adjusted_iteration_count);
timing_.iteration_count = std::numeric_limits<double>::infinity();
timing_.iteration_duration = AnimationTimeDelta::FromSecondsD(5);
timing_.start_delay = -6.0;
EXPECT_TRUE(ConvertTimingForCompositor(timing_, compositor_timing_));
- EXPECT_DOUBLE_EQ(6.0, compositor_timing_.scaled_time_offset);
- EXPECT_EQ(-1, compositor_timing_.adjusted_iteration_count);
+ EXPECT_DOUBLE_EQ(6.0, compositor_timing_.scaled_time_offset.InSecondsF());
+ EXPECT_EQ(std::numeric_limits<double>::infinity(),
+ compositor_timing_.adjusted_iteration_count);
}
TEST_P(AnimationCompositorAnimationsTest,
@@ -741,12 +746,12 @@ TEST_P(AnimationCompositorAnimationsTest,
timing_.start_delay = 6.0;
EXPECT_TRUE(ConvertTimingForCompositor(timing_, compositor_timing_));
- EXPECT_DOUBLE_EQ(-6.0, compositor_timing_.scaled_time_offset);
+ EXPECT_DOUBLE_EQ(-6.0, compositor_timing_.scaled_time_offset.InSecondsF());
EXPECT_DOUBLE_EQ(4.0, compositor_timing_.adjusted_iteration_count);
timing_.start_delay = -6.0;
EXPECT_TRUE(ConvertTimingForCompositor(timing_, compositor_timing_));
- EXPECT_DOUBLE_EQ(6.0, compositor_timing_.scaled_time_offset);
+ EXPECT_DOUBLE_EQ(6.0, compositor_timing_.scaled_time_offset.InSecondsF());
EXPECT_DOUBLE_EQ(4.0, compositor_timing_.adjusted_iteration_count);
timing_.start_delay = 21.0;
@@ -780,7 +785,7 @@ TEST_P(AnimationCompositorAnimationsTest,
timing_.iteration_duration = AnimationTimeDelta::FromSecondsD(5);
timing_.start_delay = -6.0;
EXPECT_TRUE(ConvertTimingForCompositor(timing_, compositor_timing_));
- EXPECT_DOUBLE_EQ(6.0, compositor_timing_.scaled_time_offset);
+ EXPECT_DOUBLE_EQ(6.0, compositor_timing_.scaled_time_offset.InSecondsF());
EXPECT_EQ(4, compositor_timing_.adjusted_iteration_count);
EXPECT_EQ(compositor_timing_.direction,
Timing::PlaybackDirection::ALTERNATE_NORMAL);
@@ -790,7 +795,7 @@ TEST_P(AnimationCompositorAnimationsTest,
timing_.iteration_duration = AnimationTimeDelta::FromSecondsD(5);
timing_.start_delay = -11.0;
EXPECT_TRUE(ConvertTimingForCompositor(timing_, compositor_timing_));
- EXPECT_DOUBLE_EQ(11.0, compositor_timing_.scaled_time_offset);
+ EXPECT_DOUBLE_EQ(11.0, compositor_timing_.scaled_time_offset.InSecondsF());
EXPECT_EQ(4, compositor_timing_.adjusted_iteration_count);
EXPECT_EQ(compositor_timing_.direction,
Timing::PlaybackDirection::ALTERNATE_NORMAL);
@@ -800,7 +805,7 @@ TEST_P(AnimationCompositorAnimationsTest,
timing_.iteration_duration = AnimationTimeDelta::FromSecondsD(5);
timing_.start_delay = -6.0;
EXPECT_TRUE(ConvertTimingForCompositor(timing_, compositor_timing_));
- EXPECT_DOUBLE_EQ(6.0, compositor_timing_.scaled_time_offset);
+ EXPECT_DOUBLE_EQ(6.0, compositor_timing_.scaled_time_offset.InSecondsF());
EXPECT_EQ(4, compositor_timing_.adjusted_iteration_count);
EXPECT_EQ(compositor_timing_.direction,
Timing::PlaybackDirection::ALTERNATE_REVERSE);
@@ -810,7 +815,7 @@ TEST_P(AnimationCompositorAnimationsTest,
timing_.iteration_duration = AnimationTimeDelta::FromSecondsD(5);
timing_.start_delay = -11.0;
EXPECT_TRUE(ConvertTimingForCompositor(timing_, compositor_timing_));
- EXPECT_DOUBLE_EQ(11.0, compositor_timing_.scaled_time_offset);
+ EXPECT_DOUBLE_EQ(11.0, compositor_timing_.scaled_time_offset.InSecondsF());
EXPECT_EQ(4, compositor_timing_.adjusted_iteration_count);
EXPECT_EQ(compositor_timing_.direction,
Timing::PlaybackDirection::ALTERNATE_REVERSE);
@@ -1573,7 +1578,7 @@ TEST_P(AnimationCompositorAnimationsTest,
EXPECT_EQ(curve_timing_function->GetType(),
TimingFunction::Type::CUBIC_BEZIER);
const auto& cubic_timing_function =
- ToCubicBezierTimingFunction(*curve_timing_function);
+ To<CubicBezierTimingFunction>(*curve_timing_function);
EXPECT_EQ(cubic_timing_function.GetEaseType(),
CubicBezierTimingFunction::EaseType::CUSTOM);
EXPECT_EQ(cubic_timing_function.X1(), 1.0);
@@ -1757,7 +1762,9 @@ namespace {
void UpdateDummyTransformNode(ObjectPaintProperties& properties,
CompositingReasons reasons) {
- TransformPaintPropertyNode::State state;
+ // Initialize with TransformationMatrix() to avoid 2d translation optimization
+ // in case of transform animation.
+ TransformPaintPropertyNode::State state{TransformationMatrix()};
state.direct_compositing_reasons = reasons;
properties.UpdateTransform(TransformPaintPropertyNode::Root(),
std::move(state));
@@ -1846,7 +1853,6 @@ TEST_P(AnimationCompositorAnimationsTest, TrackRafAnimation) {
// iterations and the other that ends after 10.
for (int i = 0; i < 9; i++) {
BeginFrame();
- ForceFullCompositingUpdate();
EXPECT_TRUE(host->CurrentFrameHadRAF());
EXPECT_TRUE(host->NextFrameHasPendingRAF());
}
@@ -1854,13 +1860,11 @@ TEST_P(AnimationCompositorAnimationsTest, TrackRafAnimation) {
// On the 10th iteration, there should be a current rAF, but no more pending
// rAFs.
BeginFrame();
- ForceFullCompositingUpdate();
EXPECT_TRUE(host->CurrentFrameHadRAF());
EXPECT_FALSE(host->NextFrameHasPendingRAF());
// On the 11th iteration, there should be no more rAFs firing.
BeginFrame();
- ForceFullCompositingUpdate();
EXPECT_FALSE(host->CurrentFrameHadRAF());
EXPECT_FALSE(host->NextFrameHasPendingRAF());
}
@@ -1874,7 +1878,6 @@ TEST_P(AnimationCompositorAnimationsTest, TrackRafAnimationTimeout) {
// The test file executes a rAF, which fires a setTimeout for the next rAF.
// Even with setTimeout(func, 0), the next rAF is not considered pending.
BeginFrame();
- ForceFullCompositingUpdate();
EXPECT_TRUE(host->CurrentFrameHadRAF());
EXPECT_FALSE(host->NextFrameHasPendingRAF());
}
@@ -1885,7 +1888,6 @@ TEST_P(AnimationCompositorAnimationsTest, TrackRafAnimationNoneRegistered) {
// Run a full frame after loading the test data so that scripted animations
// are serviced and data propagated.
BeginFrame();
- ForceFullCompositingUpdate();
// The HTML does not have any rAFs.
cc::AnimationHost* host =
@@ -1895,7 +1897,6 @@ TEST_P(AnimationCompositorAnimationsTest, TrackRafAnimationNoneRegistered) {
// And still shouldn't after another frame.
BeginFrame();
- ForceFullCompositingUpdate();
EXPECT_FALSE(host->CurrentFrameHadRAF());
EXPECT_FALSE(host->NextFrameHasPendingRAF());
}
@@ -1931,7 +1932,7 @@ TEST_P(AnimationCompositorAnimationsTest, CompositedTransformAnimation) {
// Make sure the animation is started on the compositor.
EXPECT_EQ(CheckCanStartElementOnCompositor(*target),
CompositorAnimations::kNoFailure);
- EXPECT_EQ(document->Timeline().PendingAnimationsCount(), 1u);
+ EXPECT_EQ(document->Timeline().AnimationsNeedingUpdateCount(), 1u);
cc::AnimationHost* host = document->View()->GetCompositorAnimationHost();
EXPECT_EQ(host->MainThreadAnimationsCount(), 0u);
EXPECT_EQ(host->CompositedAnimationsCount(), 1u);
@@ -1968,7 +1969,7 @@ TEST_P(AnimationCompositorAnimationsTest, CompositedScaleAnimation) {
// Make sure the animation is started on the compositor.
EXPECT_EQ(CheckCanStartElementOnCompositor(*target),
CompositorAnimations::kNoFailure);
- EXPECT_EQ(document->Timeline().PendingAnimationsCount(), 1u);
+ EXPECT_EQ(document->Timeline().AnimationsNeedingUpdateCount(), 1u);
cc::AnimationHost* host = document->View()->GetCompositorAnimationHost();
EXPECT_EQ(host->MainThreadAnimationsCount(), 0u);
EXPECT_EQ(host->CompositedAnimationsCount(), 1u);
@@ -2003,7 +2004,7 @@ TEST_P(AnimationCompositorAnimationsTest,
EXPECT_TRUE(cc_transform->has_potential_animation);
EXPECT_TRUE(cc_transform->is_currently_animating);
// Make sure the animation is started on the compositor.
- EXPECT_EQ(document->Timeline().PendingAnimationsCount(), 1u);
+ EXPECT_EQ(document->Timeline().AnimationsNeedingUpdateCount(), 1u);
cc::AnimationHost* host = document->View()->GetCompositorAnimationHost();
EXPECT_EQ(host->MainThreadAnimationsCount(), 0u);
EXPECT_EQ(host->CompositedAnimationsCount(), 1u);
@@ -2053,7 +2054,7 @@ TEST_P(AnimationCompositorAnimationsTest,
Element* target = document->getElementById("dots");
EXPECT_TRUE(CheckCanStartElementOnCompositor(*target) &
CompositorAnimations::kTargetHasInvalidCompositingState);
- EXPECT_EQ(document->Timeline().PendingAnimationsCount(), 4u);
+ EXPECT_EQ(document->Timeline().AnimationsNeedingUpdateCount(), 4u);
cc::AnimationHost* host = document->View()->GetCompositorAnimationHost();
EXPECT_EQ(host->MainThreadAnimationsCount(), 4u);
EXPECT_EQ(host->CompositedAnimationsCount(), 0u);
diff --git a/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_color.h b/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_color.h
index c84381b14c5..362d7b89f75 100644
--- a/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_color.h
+++ b/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_color.h
@@ -25,7 +25,12 @@ class CORE_EXPORT CompositorKeyframeColor final
SkColor color_;
};
-DEFINE_COMPOSITOR_KEYFRAME_VALUE_TYPE_CASTS(CompositorKeyframeColor, IsColor());
+template <>
+struct DowncastTraits<CompositorKeyframeColor> {
+ static bool AllowFrom(const CompositorKeyframeValue& value) {
+ return value.IsColor();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_double.h b/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_double.h
index 94e9fbfcc52..83be42ab243 100644
--- a/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_double.h
+++ b/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_double.h
@@ -24,8 +24,12 @@ class CORE_EXPORT CompositorKeyframeDouble final
double number_;
};
-DEFINE_COMPOSITOR_KEYFRAME_VALUE_TYPE_CASTS(CompositorKeyframeDouble,
- IsDouble());
+template <>
+struct DowncastTraits<CompositorKeyframeDouble> {
+ static bool AllowFrom(const CompositorKeyframeValue& value) {
+ return value.IsDouble();
+ }
+};
} // namespace blink
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 f4b5925a8d1..8c79da72aea 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
@@ -34,8 +34,12 @@ class CompositorKeyframeFilterOperations final
Member<FilterOperationsWrapper> operation_wrapper_;
};
-DEFINE_COMPOSITOR_KEYFRAME_VALUE_TYPE_CASTS(CompositorKeyframeFilterOperations,
- IsFilterOperations());
+template <>
+struct DowncastTraits<CompositorKeyframeFilterOperations> {
+ static bool AllowFrom(const CompositorKeyframeValue& value) {
+ return value.IsFilterOperations();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_transform.h b/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_transform.h
index 58c86ee46d8..ebc3e562aae 100644
--- a/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_transform.h
+++ b/chromium/third_party/blink/renderer/core/animation/css/compositor_keyframe_transform.h
@@ -31,8 +31,12 @@ class CORE_EXPORT CompositorKeyframeTransform final
const double zoom_;
};
-DEFINE_COMPOSITOR_KEYFRAME_VALUE_TYPE_CASTS(CompositorKeyframeTransform,
- IsTransform());
+template <>
+struct DowncastTraits<CompositorKeyframeTransform> {
+ static bool AllowFrom(const CompositorKeyframeValue& value) {
+ return value.IsTransform();
+ }
+};
} // namespace blink
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 6823c1515e7..f45325902e1 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
@@ -34,11 +34,6 @@ class CORE_EXPORT CompositorKeyframeValue
virtual Type GetType() const = 0;
};
-
-#define DEFINE_COMPOSITOR_KEYFRAME_VALUE_TYPE_CASTS(thisType, predicate) \
- DEFINE_TYPE_CASTS(thisType, CompositorKeyframeValue, value, \
- value->predicate, value.predicate)
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_COMPOSITOR_KEYFRAME_VALUE_H_
diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_animation.cc b/chromium/third_party/blink/renderer/core/animation/css/css_animation.cc
index 62de5d55766..a6724f1e76e 100644
--- a/chromium/third_party/blink/renderer/core/animation/css/css_animation.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css/css_animation.cc
@@ -3,6 +3,10 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/core/animation/css/css_animation.h"
+#include "third_party/blink/renderer/core/animation/animation.h"
+#include "third_party/blink/renderer/core/animation/css/css_animations.h"
+#include "third_party/blink/renderer/core/animation/keyframe_effect.h"
+#include "third_party/blink/renderer/core/dom/document.h"
namespace blink {
@@ -11,6 +15,73 @@ CSSAnimation::CSSAnimation(ExecutionContext* execution_context,
AnimationEffect* content,
const String& animation_name)
: Animation(execution_context, timeline, content),
- animation_name_(animation_name) {}
+ animation_name_(animation_name),
+ ignore_css_play_state_(false) {
+ // The owning_element does not always equal to the target element of an
+ // animation. The following spec gives an example:
+ // https://drafts.csswg.org/css-animations-2/#owning-element-section
+ owning_element_ = To<KeyframeEffect>(effect())->target();
+}
+
+String CSSAnimation::playState() const {
+ FlushStyles();
+ return Animation::playState();
+}
+
+bool CSSAnimation::pending() const {
+ FlushStyles();
+ return Animation::pending();
+}
+
+void CSSAnimation::pause(ExceptionState& exception_state) {
+ Animation::pause(exception_state);
+ if (exception_state.HadException())
+ return;
+ ignore_css_play_state_ = true;
+}
+
+void CSSAnimation::play(ExceptionState& exception_state) {
+ Animation::play(exception_state);
+ if (exception_state.HadException())
+ return;
+ ignore_css_play_state_ = true;
+}
+
+void CSSAnimation::reverse(ExceptionState& exception_state) {
+ PlayStateTransitionScope scope(*this);
+ Animation::reverse(exception_state);
+}
+
+void CSSAnimation::setStartTime(base::Optional<double> start_time_ms,
+ ExceptionState& exception_state) {
+ PlayStateTransitionScope scope(*this);
+ Animation::setStartTime(start_time_ms, exception_state);
+}
+
+AnimationEffect::EventDelegate* CSSAnimation::CreateEventDelegate(
+ Element* target,
+ const AnimationEffect::EventDelegate* old_event_delegate) {
+ return CSSAnimations::CreateEventDelegate(target, animation_name_,
+ old_event_delegate);
+}
+
+void CSSAnimation::FlushStyles() const {
+ // TODO(1043778): Flush is likely not required once the CSSAnimation is
+ // disassociated from its owning element.
+ if (GetDocument())
+ GetDocument()->UpdateStyleAndLayoutTree();
+}
+
+CSSAnimation::PlayStateTransitionScope::PlayStateTransitionScope(
+ CSSAnimation& animation)
+ : animation_(animation) {
+ was_paused_ = animation_.Paused();
+}
+
+CSSAnimation::PlayStateTransitionScope::~PlayStateTransitionScope() {
+ bool is_paused = animation_.Paused();
+ if (was_paused_ != is_paused)
+ animation_.ignore_css_play_state_ = true;
+}
} // namespace blink
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 3f7d0ecb8d7..b9ac74010a6 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
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/animation/animation.h"
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/dom/element.h"
namespace blink {
@@ -22,17 +23,82 @@ class CORE_EXPORT CSSAnimation : public Animation {
bool IsCSSAnimation() const final { return true; }
+ void ClearOwningElement() final { owning_element_ = nullptr; }
+ Element* OwningElement() const override { return owning_element_; }
+
const String& animationName() const { return animation_name_; }
+ // Animation overrides.
+ // Various operations may affect the computed values of properties on
+ // elements. User agents may, as an optimization, defer recomputing these
+ // values until it becomes necessary; however, all operations included in the
+ // programming interfaces defined in the web-animations and css-animations
+ // specifications, must produce a result consistent with having fully
+ // processed any such pending changes to computed values. Notably, changes
+ // to animation-play-state and display:none must update the play state.
+ // https://drafts.csswg.org/css-animations-2/#requirements-on-pending-style-changes
+ String playState() const override;
+ bool pending() const override;
+
+ // Explicit calls to the web-animation API that update the play state are
+ // conditionally sticky and override the animation-play-state style.
+ void pause(ExceptionState& = ASSERT_NO_EXCEPTION) override;
+ void play(ExceptionState& = ASSERT_NO_EXCEPTION) override;
+ void reverse(ExceptionState& = ASSERT_NO_EXCEPTION) override;
+ void setStartTime(base::Optional<double>, ExceptionState&) override;
+
+ // When set, subsequent changes to animation-play-state no longer affect the
+ // play state.
+ // 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 {
+ Animation::Trace(visitor);
+ visitor->Trace(owning_element_);
+ }
+
+ // Force pending animation properties to be applied, as these may alter the
+ // animation. This step is required before any web animation API calls that
+ // depends on computed values.
+ void FlushPendingUpdates() const override { FlushStyles(); }
+
+ protected:
+ AnimationEffect::EventDelegate* CreateEventDelegate(
+ Element* target,
+ const AnimationEffect::EventDelegate* old_event_delegate) override;
+
private:
- String animation_name_;
+ void FlushStyles() const;
+
+ class PlayStateTransitionScope {
+ STACK_ALLOCATED();
+
+ public:
+ explicit PlayStateTransitionScope(CSSAnimation& animation);
+ ~PlayStateTransitionScope();
+
+ private:
+ CSSAnimation& animation_;
+ bool was_paused_;
+ };
+
+ AtomicString animation_name_;
+
+ // When set, the web-animation API is overruling the animation-play-state
+ // style.
+ bool ignore_css_play_state_;
+ // The owning element of an animation refers to the element or pseudo-element
+ // whose animation-name property was applied that generated the animation
+ // The spec: https://drafts.csswg.org/css-animations-2/#owning-element-section
+ Member<Element> owning_element_;
};
-DEFINE_TYPE_CASTS(CSSAnimation,
- Animation,
- animation,
- animation->IsCSSAnimation(),
- animation.IsCSSAnimation());
+template <>
+struct DowncastTraits<CSSAnimation> {
+ static bool AllowFrom(const Animation& animation) {
+ return animation.IsCSSAnimation();
+ }
+};
} // namespace blink
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 bc051a4a598..1d9d400ae0c 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
@@ -40,7 +40,7 @@ class NewCSSAnimation {
style_rule_version(this->style_rule->Version()),
play_state_list(play_state_list) {}
- void Trace(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
visitor->Trace(effect);
visitor->Trace(style_rule);
}
@@ -72,7 +72,7 @@ class UpdatedCSSAnimation {
style_rule_version(this->style_rule->Version()),
play_state_list(play_state_list) {}
- void Trace(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
visitor->Trace(animation);
visitor->Trace(effect);
visitor->Trace(style_rule);
@@ -179,7 +179,7 @@ class CORE_EXPORT CSSAnimationUpdate final {
public:
NewTransition();
~NewTransition();
- void Trace(blink::Visitor* visitor) { visitor->Trace(effect); }
+ void Trace(Visitor* visitor) { visitor->Trace(effect); }
PropertyHandle property = HashTraits<blink::PropertyHandle>::EmptyValue();
scoped_refptr<const ComputedStyle> from;
@@ -251,7 +251,7 @@ class CORE_EXPORT CSSAnimationUpdate final {
updated_compositor_keyframes_.IsEmpty();
}
- void Trace(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
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 15b851721a6..7708587c3a0 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
@@ -34,6 +34,7 @@
#include <bitset>
#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_computed_effect_timing.h"
#include "third_party/blink/renderer/core/animation/animation.h"
#include "third_party/blink/renderer/core/animation/compositor_animations.h"
#include "third_party/blink/renderer/core/animation/css/compositor_keyframe_value_factory.h"
@@ -138,7 +139,7 @@ StringKeyframeEffectModel* CreateKeyframeEffectModel(
// The last keyframe specified at a given offset is used.
for (wtf_size_t j = 1; j < offsets.size(); ++j) {
keyframes.push_back(
- ToStringKeyframe(keyframe->CloneWithOffset(offsets[j])));
+ To<StringKeyframe>(keyframe->CloneWithOffset(offsets[j])));
}
}
@@ -203,7 +204,7 @@ StringKeyframeEffectModel* CreateKeyframeEffectModel(
std::unique_ptr<TypedInterpolationValue> SampleAnimation(
Animation* animation,
double inherited_time) {
- KeyframeEffect* effect = ToKeyframeEffect(animation->effect());
+ auto* effect = To<KeyframeEffect>(animation->effect());
auto* inert_animation_for_sampling = MakeGarbageCollected<InertEffect>(
effect->Model(), effect->SpecifiedTiming(), false, inherited_time);
HeapVector<Member<Interpolation>> sample;
@@ -213,7 +214,7 @@ std::unique_ptr<TypedInterpolationValue> SampleAnimation(
DCHECK_LE(sample.size(), 1u);
if (sample.IsEmpty())
return nullptr;
- return ToTransitionInterpolation(*sample.at(0)).GetInterpolatedValue();
+ return To<TransitionInterpolation>(*sample.at(0)).GetInterpolatedValue();
}
// Returns the start time of an animation given the start delay. A negative
@@ -222,6 +223,37 @@ AnimationTimeDelta StartTimeFromDelay(double start_delay) {
return AnimationTimeDelta::FromSecondsD(start_delay < 0 ? -start_delay : 0);
}
+// Timing functions for computing elapsed time of an event.
+
+AnimationTimeDelta IntervalStart(const AnimationEffect& effect) {
+ const double start_delay = effect.SpecifiedTiming().start_delay;
+ const double active_duration = effect.SpecifiedTiming().ActiveDuration();
+ return AnimationTimeDelta::FromSecondsD(
+ std::fmax(std::fmin(-start_delay, active_duration), 0.0));
+}
+
+AnimationTimeDelta IntervalEnd(const AnimationEffect& effect) {
+ const double start_delay = effect.SpecifiedTiming().start_delay;
+ const double end_delay = effect.SpecifiedTiming().end_delay;
+ const double active_duration = effect.SpecifiedTiming().ActiveDuration();
+ const double target_effect_end =
+ std::max(start_delay + active_duration + end_delay, 0.0);
+ return AnimationTimeDelta::FromSecondsD(std::max(
+ std::min(target_effect_end - start_delay, active_duration), 0.0));
+}
+
+AnimationTimeDelta IterationElapsedTime(const AnimationEffect& effect,
+ double previous_iteration) {
+ const double current_iteration = effect.CurrentIteration().value();
+ const double iteration_boundary = (previous_iteration > current_iteration)
+ ? current_iteration + 1
+ : current_iteration;
+ const double iteration_start = effect.SpecifiedTiming().iteration_start;
+ const AnimationTimeDelta iteration_duration =
+ effect.SpecifiedTiming().iteration_duration.value();
+ return iteration_duration * (iteration_boundary - iteration_start);
+}
+
} // namespace
CSSAnimations::CSSAnimations() = default;
@@ -233,13 +265,13 @@ const KeyframeEffectModelBase* GetKeyframeEffectModelBase(
if (!effect)
return nullptr;
const EffectModel* model = nullptr;
- if (effect->IsKeyframeEffect())
- model = ToKeyframeEffect(effect)->Model();
- else if (effect->IsInertEffect())
- model = ToInertEffect(effect)->Model();
+ if (auto* keyframe_effect = DynamicTo<KeyframeEffect>(effect))
+ model = keyframe_effect->Model();
+ else if (auto* inert_effect = DynamicTo<InertEffect>(effect))
+ model = inert_effect->Model();
if (!model || !model->IsKeyframeEffectModel())
return nullptr;
- return ToKeyframeEffectModelBase(model);
+ return To<KeyframeEffectModelBase>(model);
}
} // namespace
@@ -388,12 +420,25 @@ void CSSAnimations::CalculateAnimationUpdate(CSSAnimationUpdate& update,
if (existing_animation) {
cancel_running_animation_flags[existing_animation_index] = false;
- Animation* animation = existing_animation->animation.Get();
+ CSSAnimation* animation =
+ DynamicTo<CSSAnimation>(existing_animation->animation.Get());
const bool was_paused =
CSSTimingData::GetRepeated(existing_animation->play_state_list,
i) == EAnimPlayState::kPaused;
+ // Explicit calls to web-animation play controls override changes to
+ // play state via the animation-play-state style. Ensure that the new
+ // play state based on animation-play-state differs from the current
+ // play state and that the change is not blocked by a sticky state.
+ bool toggle_pause_state = false;
+ if (is_paused != was_paused && !animation->getIgnoreCSSPlayState()) {
+ if (animation->Paused() && !is_paused)
+ toggle_pause_state = true;
+ else if (animation->Playing() && is_paused)
+ toggle_pause_state = true;
+ }
+
if (keyframes_rule != existing_animation->style_rule ||
keyframes_rule->Version() !=
existing_animation->style_rule_version ||
@@ -409,7 +454,7 @@ void CSSAnimations::CalculateAnimationUpdate(CSSAnimationUpdate& update,
timing, is_paused, animation->UnlimitedCurrentTime()),
specified_timing, keyframes_rule,
animation_data->PlayStateList());
- if (is_paused != was_paused)
+ if (toggle_pause_state)
update.ToggleAnimationIndexPaused(existing_animation_index);
}
} else {
@@ -437,6 +482,35 @@ void CSSAnimations::CalculateAnimationUpdate(CSSAnimationUpdate& update,
CalculateAnimationActiveInterpolations(update, animating_element);
}
+AnimationEffect::EventDelegate* CSSAnimations::CreateEventDelegate(
+ Element* element,
+ const PropertyHandle& property_handle,
+ const AnimationEffect::EventDelegate* old_event_delegate) {
+ const CSSAnimations::TransitionEventDelegate* old_transition_delegate =
+ DynamicTo<CSSAnimations::TransitionEventDelegate>(old_event_delegate);
+ Timing::Phase previous_phase =
+ old_transition_delegate ? old_transition_delegate->getPreviousPhase()
+ : Timing::kPhaseNone;
+ return MakeGarbageCollected<TransitionEventDelegate>(element, property_handle,
+ previous_phase);
+}
+
+AnimationEffect::EventDelegate* CSSAnimations::CreateEventDelegate(
+ Element* element,
+ const AtomicString& animation_name,
+ const AnimationEffect::EventDelegate* old_event_delegate) {
+ const CSSAnimations::AnimationEventDelegate* old_animation_delegate =
+ DynamicTo<CSSAnimations::AnimationEventDelegate>(old_event_delegate);
+ Timing::Phase previous_phase =
+ old_animation_delegate ? old_animation_delegate->getPreviousPhase()
+ : Timing::kPhaseNone;
+ base::Optional<double> previous_iteration =
+ old_animation_delegate ? old_animation_delegate->getPreviousIteration()
+ : base::nullopt;
+ return MakeGarbageCollected<AnimationEventDelegate>(
+ element, animation_name, previous_phase, previous_iteration);
+}
+
void CSSAnimations::SnapshotCompositorKeyframes(
Element& element,
CSSAnimationUpdate& update,
@@ -481,13 +555,18 @@ void CSSAnimations::MaybeApplyPendingUpdate(Element* element) {
for (wtf_size_t paused_index :
pending_update_.AnimationIndicesWithPauseToggled()) {
- Animation& animation = *running_animations_[paused_index]->animation;
- if (animation.Paused())
- animation.Unpause();
- else
- animation.pause();
- if (animation.Outdated())
- animation.Update(kTimingUpdateOnDemand);
+ CSSAnimation* animation = DynamicTo<CSSAnimation>(
+ running_animations_[paused_index]->animation.Get());
+
+ if (animation->Paused()) {
+ animation->Unpause();
+ animation->resetIgnoreCSSPlayState();
+ } else {
+ animation->pause();
+ animation->resetIgnoreCSSPlayState();
+ }
+ if (animation->Outdated())
+ animation->Update(kTimingUpdateOnDemand);
}
for (const auto& animation : pending_update_.UpdatedCompositorKeyframes())
@@ -495,8 +574,9 @@ void CSSAnimations::MaybeApplyPendingUpdate(Element* element) {
for (const auto& entry : pending_update_.AnimationsWithUpdates()) {
if (entry.animation->effect()) {
- KeyframeEffect* effect = ToKeyframeEffect(entry.animation->effect());
- effect->SetModel(entry.effect->Model());
+ auto* effect = To<KeyframeEffect>(entry.animation->effect());
+ if (!effect->GetIgnoreCSSKeyframes())
+ effect->SetModel(entry.effect->Model());
effect->UpdateSpecifiedTiming(entry.effect->SpecifiedTiming());
}
@@ -510,7 +590,10 @@ void CSSAnimations::MaybeApplyPendingUpdate(Element* element) {
cancelled_indices[i] < cancelled_indices[i + 1]);
Animation& animation =
*running_animations_[cancelled_indices[i]]->animation;
- animation.cancel();
+ animation.ClearOwningElement();
+ if (animation.IsCSSAnimation() &&
+ !DynamicTo<CSSAnimation>(animation)->getIgnoreCSSPlayState())
+ animation.cancel();
animation.Update(kTimingUpdateOnDemand);
running_animations_.EraseAt(cancelled_indices[i]);
}
@@ -524,11 +607,12 @@ void CSSAnimations::MaybeApplyPendingUpdate(Element* element) {
KeyframeEffect::kDefaultPriority, event_delegate);
auto* animation = MakeGarbageCollected<CSSAnimation>(
- element->GetDocument().ContextDocument(),
- &(element->GetDocument().Timeline()), effect, entry.name);
+ element->GetExecutionContext(), &(element->GetDocument().Timeline()),
+ effect, entry.name);
animation->play();
if (inert_animation->Paused())
animation->pause();
+ animation->resetIgnoreCSSPlayState();
animation->Update(kTimingUpdateOnDemand);
running_animations_.push_back(
@@ -546,19 +630,20 @@ void CSSAnimations::MaybeApplyPendingUpdate(Element* element) {
DCHECK(transitions_.Contains(property));
Animation* animation = transitions_.Take(property).animation;
- KeyframeEffect* effect = ToKeyframeEffect(animation->effect());
+ auto* effect = To<KeyframeEffect>(animation->effect());
if (effect && effect->HasActiveAnimationsOnCompositor(property) &&
pending_update_.NewTransitions().find(property) !=
pending_update_.NewTransitions().end() &&
!animation->Limited()) {
retargeted_compositor_transitions.insert(property);
}
+ animation->ClearOwningElement();
animation->cancel();
// after cancelation, transitions must be downgraded or they'll fail
// to be considered when retriggering themselves. This can happen if
// the transition is captured through getAnimations then played.
- if (animation->effect() && animation->effect()->IsKeyframeEffect())
- ToKeyframeEffect(animation->effect())->DowngradeToNormal();
+ if (auto* effect = DynamicTo<KeyframeEffect>(animation->effect()))
+ effect->DowngradeToNormal();
animation->Update(kTimingUpdateOnDemand);
}
@@ -567,8 +652,8 @@ void CSSAnimations::MaybeApplyPendingUpdate(Element* element) {
if (transitions_.Contains(property)) {
Animation* animation = transitions_.Take(property).animation;
// Transition must be downgraded
- if (animation->effect() && animation->effect()->IsKeyframeEffect())
- ToKeyframeEffect(animation->effect())->DowngradeToNormal();
+ if (auto* effect = DynamicTo<KeyframeEffect>(animation->effect()))
+ effect->DowngradeToNormal();
}
}
@@ -594,8 +679,8 @@ void CSSAnimations::MaybeApplyPendingUpdate(Element* element) {
element, model, inert_animation->SpecifiedTiming(),
KeyframeEffect::kTransitionPriority, event_delegate);
auto* animation = MakeGarbageCollected<CSSTransition>(
- element->GetDocument().ContextDocument(),
- &(element->GetDocument().Timeline()), transition_effect, property);
+ element->GetExecutionContext(), &(element->GetDocument().Timeline()),
+ transition_effect, property);
animation->play();
@@ -656,8 +741,8 @@ void CSSAnimations::CalculateTransitionUpdateForProperty(
return;
}
state.update.CancelTransition(property);
- KeyframeEffect* effect =
- ToKeyframeEffect(running_transition->animation->effect());
+ auto* effect =
+ To<KeyframeEffect>(running_transition->animation->effect());
if (effect && effect->HasActiveAnimationsOnCompositor())
retargeted_compositor_transition = running_transition;
DCHECK(!state.animating_element->GetElementAnimations() ||
@@ -701,8 +786,8 @@ void CSSAnimations::CalculateTransitionUpdateForProperty(
double inherited_time = old_start_time.has_value()
? state.animating_element->GetDocument()
.Timeline()
- .CurrentTimeInternal()
- ->InSecondsF() -
+ .CurrentTimeSeconds()
+ .value() -
old_start_time.value()
: 0;
std::unique_ptr<TypedInterpolationValue> retargeted_start = SampleAnimation(
@@ -1131,46 +1216,71 @@ void CSSAnimations::AnimationEventDelegate::OnEventCondition(
const base::Optional<double> current_iteration =
animation_node.CurrentIteration();
- if (previous_phase_ != current_phase &&
- (current_phase == Timing::kPhaseActive ||
- current_phase == Timing::kPhaseAfter) &&
- (previous_phase_ == Timing::kPhaseNone ||
- previous_phase_ == Timing::kPhaseBefore)) {
- const double start_delay = animation_node.SpecifiedTiming().start_delay;
- const auto& elapsed_time =
- AnimationTimeDelta::FromSecondsD(start_delay < 0 ? -start_delay : 0);
+ // See http://drafts.csswg.org/css-animations-2/#event-dispatch
+ // When multiple events are dispatched for a single phase transition,
+ // the animationstart event is to be dispatched before the animationend
+ // event.
+
+ // The following phase transitions trigger an animationstart event:
+ // idle or before --> active or after
+ // after --> active or before
+ const bool phase_change = previous_phase_ != current_phase;
+ const bool was_idle_or_before = (previous_phase_ == Timing::kPhaseNone ||
+ previous_phase_ == Timing::kPhaseBefore);
+ const bool is_active_or_after = (current_phase == Timing::kPhaseActive ||
+ current_phase == Timing::kPhaseAfter);
+ const bool is_active_or_before = (current_phase == Timing::kPhaseActive ||
+ current_phase == Timing::kPhaseBefore);
+ const bool was_after = (previous_phase_ == Timing::kPhaseAfter);
+ if (phase_change && ((was_idle_or_before && is_active_or_after) ||
+ (was_after && is_active_or_before))) {
+ AnimationTimeDelta elapsed_time =
+ was_after ? IntervalEnd(animation_node) : IntervalStart(animation_node);
MaybeDispatch(Document::kAnimationStartListener,
event_type_names::kAnimationstart, elapsed_time);
}
- if (current_phase == Timing::kPhaseActive &&
- previous_phase_ == current_phase &&
+ // The following phase transitions trigger an animationend event:
+ // idle, before or active--> after
+ // active or after--> before
+ const bool was_active_or_after = (previous_phase_ == Timing::kPhaseActive ||
+ previous_phase_ == Timing::kPhaseAfter);
+ const bool is_after = (current_phase == Timing::kPhaseAfter);
+ const bool is_before = (current_phase == Timing::kPhaseBefore);
+ if (phase_change && (is_after || (was_active_or_after && is_before))) {
+ AnimationTimeDelta elapsed_time =
+ is_after ? IntervalEnd(animation_node) : IntervalStart(animation_node);
+ MaybeDispatch(Document::kAnimationEndListener,
+ event_type_names::kAnimationend, elapsed_time);
+ }
+
+ if (phase_change && current_phase == Timing::kPhaseNone) {
+ // TODO(crbug.com/1059968): Determine if animation direction or playback
+ // rate factor into the calculation of the elapsed time.
+ double cancel_time = animation_node.GetCancelTime();
+ MaybeDispatch(Document::kAnimationCancelListener,
+ event_type_names::kAnimationcancel,
+ AnimationTimeDelta::FromSecondsD(cancel_time));
+ }
+
+ if (!phase_change && current_phase == Timing::kPhaseActive &&
previous_iteration_ != current_iteration) {
// We fire only a single event for all iterations that terminate
// between a single pair of samples. See http://crbug.com/275263. For
// compatibility with the existing implementation, this event uses
// the elapsedTime for the first iteration in question.
- DCHECK(previous_iteration_);
+ DCHECK(previous_iteration_ && current_iteration);
const AnimationTimeDelta elapsed_time =
- animation_node.SpecifiedTiming().iteration_duration.value() *
- (previous_iteration_.value() + 1);
+ IterationElapsedTime(animation_node, previous_iteration_.value());
MaybeDispatch(Document::kAnimationIterationListener,
event_type_names::kAnimationiteration, elapsed_time);
}
- if (current_phase == Timing::kPhaseAfter &&
- previous_phase_ != Timing::kPhaseAfter) {
- MaybeDispatch(Document::kAnimationEndListener,
- event_type_names::kAnimationend,
- AnimationTimeDelta::FromSecondsD(
- animation_node.SpecifiedTiming().ActiveDuration()));
- }
-
- previous_phase_ = current_phase;
previous_iteration_ = current_iteration;
+ previous_phase_ = current_phase;
}
-void CSSAnimations::AnimationEventDelegate::Trace(blink::Visitor* visitor) {
+void CSSAnimations::AnimationEventDelegate::Trace(Visitor* visitor) {
visitor->Trace(animation_target_);
AnimationEffect::EventDelegate::Trace(visitor);
}
@@ -1269,7 +1379,7 @@ void CSSAnimations::TransitionEventDelegate::EnqueueEvent(
GetDocument().EnqueueAnimationFrameEvent(event);
}
-void CSSAnimations::TransitionEventDelegate::Trace(blink::Visitor* visitor) {
+void CSSAnimations::TransitionEventDelegate::Trace(Visitor* visitor) {
visitor->Trace(transition_target_);
AnimationEffect::EventDelegate::Trace(visitor);
}
@@ -1349,7 +1459,7 @@ bool CSSAnimations::IsAnimatingCustomProperties(
IsCustomPropertyHandle);
}
-void CSSAnimations::Trace(blink::Visitor* visitor) {
+void CSSAnimations::Trace(Visitor* visitor) {
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 159ad96550e..b6b99f74c68 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
@@ -75,6 +75,16 @@ class CORE_EXPORT CSSAnimations final {
const ComputedStyle* parent_style,
bool was_viewport_changed);
+ static AnimationEffect::EventDelegate* CreateEventDelegate(
+ Element* element,
+ const PropertyHandle& property_handle,
+ const AnimationEffect::EventDelegate* old_event_delegate);
+
+ static AnimationEffect::EventDelegate* CreateEventDelegate(
+ Element* element,
+ const AtomicString& animation_name,
+ const AnimationEffect::EventDelegate* old_event_delegate);
+
// Specifies whether to process custom or standard CSS properties.
enum class PropertyPass { kCustom, kStandard };
static void CalculateTransitionUpdate(CSSAnimationUpdate&,
@@ -99,7 +109,7 @@ class CORE_EXPORT CSSAnimations final {
}
void Cancel();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
class RunningAnimation final : public GarbageCollected<RunningAnimation> {
@@ -121,7 +131,7 @@ class CORE_EXPORT CSSAnimations final {
specified_timing = update.specified_timing;
}
- void Trace(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
visitor->Trace(animation);
visitor->Trace(style_rule);
}
@@ -139,7 +149,7 @@ class CORE_EXPORT CSSAnimations final {
DISALLOW_NEW();
public:
- void Trace(blink::Visitor* visitor) { visitor->Trace(animation); }
+ void Trace(Visitor* visitor) { visitor->Trace(animation); }
Member<Animation> animation;
scoped_refptr<const ComputedStyle> from;
@@ -164,7 +174,7 @@ class CORE_EXPORT CSSAnimations final {
public:
CSSAnimationUpdate& update;
- Member<const Element> animating_element;
+ const Element* animating_element = nullptr;
const ComputedStyle& old_style;
const ComputedStyle& style;
scoped_refptr<const ComputedStyle> cloned_style;
@@ -198,13 +208,25 @@ class CORE_EXPORT CSSAnimations final {
class AnimationEventDelegate final : public AnimationEffect::EventDelegate {
public:
- AnimationEventDelegate(Element* animation_target, const AtomicString& name)
+ AnimationEventDelegate(
+ Element* animation_target,
+ const AtomicString& name,
+ Timing::Phase previous_phase = Timing::kPhaseNone,
+ base::Optional<double> previous_iteration = base::nullopt)
: animation_target_(animation_target),
name_(name),
- previous_phase_(Timing::kPhaseNone) {}
+ previous_phase_(previous_phase),
+ previous_iteration_(previous_iteration) {}
bool RequiresIterationEvents(const AnimationEffect&) override;
void OnEventCondition(const AnimationEffect&, Timing::Phase) override;
- void Trace(blink::Visitor*) override;
+
+ bool IsAnimationEventDelegate() const override { return true; }
+ Timing::Phase getPreviousPhase() const { return previous_phase_; }
+ base::Optional<double> getPreviousIteration() const {
+ return previous_iteration_;
+ }
+
+ void Trace(Visitor*) override;
private:
const Element& AnimationTarget() const { return *animation_target_; }
@@ -223,15 +245,19 @@ class CORE_EXPORT CSSAnimations final {
class TransitionEventDelegate final : public AnimationEffect::EventDelegate {
public:
TransitionEventDelegate(Element* transition_target,
- const PropertyHandle& property)
+ const PropertyHandle& property,
+ Timing::Phase previous_phase = Timing::kPhaseNone)
: transition_target_(transition_target),
property_(property),
- previous_phase_(Timing::kPhaseNone) {}
+ previous_phase_(previous_phase) {}
bool RequiresIterationEvents(const AnimationEffect&) override {
return false;
}
void OnEventCondition(const AnimationEffect&, Timing::Phase) override;
- void Trace(blink::Visitor*) override;
+ bool IsTransitionEventDelegate() const override { return true; }
+ Timing::Phase getPreviousPhase() const { return previous_phase_; }
+
+ void Trace(Visitor*) override;
private:
void EnqueueEvent(const WTF::AtomicString& type,
@@ -250,6 +276,20 @@ class CORE_EXPORT CSSAnimations final {
DISALLOW_COPY_AND_ASSIGN(CSSAnimations);
};
+template <>
+struct DowncastTraits<CSSAnimations::AnimationEventDelegate> {
+ static bool AllowFrom(const AnimationEffect::EventDelegate& delegate) {
+ return delegate.IsAnimationEventDelegate();
+ }
+};
+
+template <>
+struct DowncastTraits<CSSAnimations::TransitionEventDelegate> {
+ static bool AllowFrom(const AnimationEffect::EventDelegate& delegate) {
+ return delegate.IsTransitionEventDelegate();
+ }
+};
+
} // namespace blink
#endif
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 a1d95df3681..876df39501e 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
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/animation/css/css_animations.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"
#include "third_party/blink/renderer/core/animation/element_animations.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
diff --git a/chromium/third_party/blink/renderer/core/animation/css/css_transition.cc b/chromium/third_party/blink/renderer/core/animation/css/css_transition.cc
index d5169534fa4..4c422485122 100644
--- a/chromium/third_party/blink/renderer/core/animation/css/css_transition.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css/css_transition.cc
@@ -4,6 +4,10 @@
#include "third_party/blink/renderer/core/animation/css/css_transition.h"
+#include "third_party/blink/renderer/core/animation/css/css_animations.h"
+#include "third_party/blink/renderer/core/animation/keyframe_effect.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+
namespace blink {
CSSTransition::CSSTransition(ExecutionContext* execution_context,
@@ -11,10 +15,29 @@ CSSTransition::CSSTransition(ExecutionContext* execution_context,
AnimationEffect* content,
const PropertyHandle& transition_property)
: Animation(execution_context, timeline, content),
- transition_property_(transition_property) {}
+ transition_property_(transition_property) {
+ // The owning_element does not always equal to the target element of an
+ // animation.
+ owning_element_ = To<KeyframeEffect>(effect())->target();
+}
AtomicString CSSTransition::transitionProperty() const {
return transition_property_.GetCSSPropertyName().ToAtomicString();
}
+String CSSTransition::playState() const {
+ // TODO(1043778): Flush is likely not required once the CSSTransition is
+ // disassociated from its owning element.
+ if (GetDocument())
+ GetDocument()->UpdateStyleAndLayoutTree();
+ return Animation::playState();
+}
+
+AnimationEffect::EventDelegate* CSSTransition::CreateEventDelegate(
+ Element* target,
+ const AnimationEffect::EventDelegate* old_event_delegate) {
+ return CSSAnimations::CreateEventDelegate(target, transition_property_,
+ old_event_delegate);
+}
+
} // 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 483b2f0e1cb..07b5debd496 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
@@ -6,7 +6,9 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_CSS_TRANSITION_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/core/dom/element.h"
namespace blink {
@@ -21,20 +23,47 @@ class CORE_EXPORT CSSTransition : public Animation {
bool IsCSSTransition() const final { return true; }
+ void ClearOwningElement() final { owning_element_ = nullptr; }
+ Element* OwningElement() const override { return owning_element_; }
+
AtomicString transitionProperty() const;
const CSSProperty& TransitionCSSProperty() const {
return transition_property_.GetCSSProperty();
}
+ // Animation overrides.
+ // Various operations may affect the computed values of properties on
+ // elements. User agents may, as an optimization, defer recomputing these
+ // values until it becomes necessary; however, all operations included in the
+ // programming interfaces defined in the web-animations and css-transitions
+ // specifications, must produce a result consistent with having fully
+ // processed any such pending changes to computed values. Notably, setting
+ // 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 {
+ Animation::Trace(visitor);
+ visitor->Trace(owning_element_);
+ }
+
+ protected:
+ AnimationEffect::EventDelegate* CreateEventDelegate(
+ Element* target,
+ const AnimationEffect::EventDelegate* old_event_delegate) override;
+
private:
PropertyHandle transition_property_;
+ // The owning element of a transition refers to the element or pseudo-element
+ // to which the transition-property property was applied that generated the
+ // animation.
+ Member<Element> owning_element_;
+};
+template <>
+struct DowncastTraits<CSSTransition> {
+ static bool AllowFrom(const Animation& animation) {
+ return animation.IsCSSTransition();
+ }
};
-
-DEFINE_TYPE_CASTS(CSSTransition,
- Animation,
- animation,
- animation->IsCSSTransition(),
- animation.IsCSSTransition());
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/css_angle_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_angle_interpolation_type.cc
index 832abb898d7..df1685aa060 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_angle_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_angle_interpolation_type.cc
@@ -30,7 +30,7 @@ const CSSValue* CSSAngleInterpolationType::CreateCSSValue(
const InterpolableValue& value,
const NonInterpolableValue*,
const StyleResolverState&) const {
- return CSSNumericLiteralValue::Create(ToInterpolableNumber(value).Value(),
+ return CSSNumericLiteralValue::Create(To<InterpolableNumber>(value).Value(),
CSSPrimitiveValue::UnitType::kDegrees);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/css_border_image_length_box_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_border_image_length_box_interpolation_type.cc
index fb5cbf71cc1..22e7218df0c 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_border_image_length_box_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_border_image_length_box_interpolation_type.cc
@@ -98,8 +98,16 @@ class CSSBorderImageLengthBoxSideNonInterpolableValue
DEFINE_NON_INTERPOLABLE_VALUE_TYPE(
CSSBorderImageLengthBoxSideNonInterpolableValue);
-DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(
- CSSBorderImageLengthBoxSideNonInterpolableValue);
+template <>
+struct DowncastTraits<CSSBorderImageLengthBoxSideNonInterpolableValue> {
+ static bool AllowFrom(const NonInterpolableValue* value) {
+ return value && AllowFrom(*value);
+ }
+ static bool AllowFrom(const NonInterpolableValue& value) {
+ return value.GetType() ==
+ CSSBorderImageLengthBoxSideNonInterpolableValue::static_type_;
+ }
+};
namespace {
@@ -134,9 +142,11 @@ SideType GetSideType(const NonInterpolableValue* side) {
// In cases where LengthInterpolationFunctions is not used to convert the
// value (kAuto, kNumber), we will always have a non-interpolable value of
// type CSSBorderImageLengthBoxSideNonInterpolableValue.
- if (!side || !IsCSSBorderImageLengthBoxSideNonInterpolableValue(side))
+ auto* non_interpolable =
+ DynamicTo<CSSBorderImageLengthBoxSideNonInterpolableValue>(side);
+ if (!side || !non_interpolable)
return SideType::kLength;
- return ToCSSBorderImageLengthBoxSideNonInterpolableValue(*side).GetSideType();
+ return non_interpolable->GetSideType();
}
struct SideTypes {
@@ -154,7 +164,7 @@ struct SideTypes {
}
explicit SideTypes(const InterpolationValue& underlying) {
const auto& non_interpolable_list =
- ToNonInterpolableList(*underlying.non_interpolable_value);
+ To<NonInterpolableList>(*underlying.non_interpolable_value);
DCHECK_EQ(kSideIndexCount, non_interpolable_list.length());
type[kSideTop] = GetSideType(non_interpolable_list.Get(0));
type[kSideRight] = GetSideType(non_interpolable_list.Get(1));
@@ -375,14 +385,14 @@ void CSSBorderImageLengthBoxInterpolationType::ApplyStandardPropertyValue(
const InterpolableValue& interpolable_value,
const NonInterpolableValue* non_interpolable_value,
StyleResolverState& state) const {
- const InterpolableList& list = ToInterpolableList(interpolable_value);
- const NonInterpolableList& non_interpolable_list =
- ToNonInterpolableList(*non_interpolable_value);
+ const auto& list = To<InterpolableList>(interpolable_value);
+ const auto& non_interpolable_list =
+ To<NonInterpolableList>(*non_interpolable_value);
const auto& convert_side = [&list, &non_interpolable_list,
&state](wtf_size_t index) -> BorderImageLength {
switch (GetSideType(non_interpolable_list.Get(index))) {
case SideType::kNumber:
- return clampTo<double>(ToInterpolableNumber(list.Get(index))->Value(),
+ return clampTo<double>(To<InterpolableNumber>(list.Get(index))->Value(),
0);
case SideType::kAuto:
return Length::Auto();
diff --git a/chromium/third_party/blink/renderer/core/animation/css_clip_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_clip_interpolation_type.cc
index f73e0c33b74..1a816361073 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_clip_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_clip_interpolation_type.cc
@@ -111,7 +111,15 @@ class CSSClipNonInterpolableValue : public NonInterpolableValue {
};
DEFINE_NON_INTERPOLABLE_VALUE_TYPE(CSSClipNonInterpolableValue);
-DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(CSSClipNonInterpolableValue);
+template <>
+struct DowncastTraits<CSSClipNonInterpolableValue> {
+ static bool AllowFrom(const NonInterpolableValue* value) {
+ return value && AllowFrom(*value);
+ }
+ static bool AllowFrom(const NonInterpolableValue& value) {
+ return value.GetType() == CSSClipNonInterpolableValue::static_type_;
+ }
+};
class UnderlyingAutosChecker
: public CSSInterpolationType::CSSConversionChecker {
@@ -123,7 +131,7 @@ class UnderlyingAutosChecker
static ClipAutos GetUnderlyingAutos(const InterpolationValue& underlying) {
if (!underlying)
return ClipAutos();
- return ToCSSClipNonInterpolableValue(*underlying.non_interpolable_value)
+ return To<CSSClipNonInterpolableValue>(*underlying.non_interpolable_value)
.GetClipAutos();
}
@@ -238,11 +246,12 @@ CSSClipInterpolationType::MaybeConvertStandardPropertyUnderlyingValue(
PairwiseInterpolationValue CSSClipInterpolationType::MaybeMergeSingles(
InterpolationValue&& start,
InterpolationValue&& end) const {
- const ClipAutos& start_autos =
- ToCSSClipNonInterpolableValue(*start.non_interpolable_value)
+ const auto& start_autos =
+ To<CSSClipNonInterpolableValue>(*start.non_interpolable_value)
+ .GetClipAutos();
+ const auto& end_autos =
+ To<CSSClipNonInterpolableValue>(*end.non_interpolable_value)
.GetClipAutos();
- const ClipAutos& end_autos =
- ToCSSClipNonInterpolableValue(*end.non_interpolable_value).GetClipAutos();
if (start_autos != end_autos)
return nullptr;
return PairwiseInterpolationValue(std::move(start.interpolable_value),
@@ -255,12 +264,12 @@ void CSSClipInterpolationType::Composite(
double underlying_fraction,
const InterpolationValue& value,
double interpolation_fraction) const {
- const ClipAutos& underlying_autos =
- ToCSSClipNonInterpolableValue(
+ const auto& underlying_autos =
+ To<CSSClipNonInterpolableValue>(
*underlying_value_owner.Value().non_interpolable_value)
.GetClipAutos();
- const ClipAutos& autos =
- ToCSSClipNonInterpolableValue(*value.non_interpolable_value)
+ const auto& autos =
+ To<CSSClipNonInterpolableValue>(*value.non_interpolable_value)
.GetClipAutos();
if (underlying_autos == autos)
underlying_value_owner.MutableValue().interpolable_value->ScaleAndAdd(
@@ -273,9 +282,9 @@ void CSSClipInterpolationType::ApplyStandardPropertyValue(
const InterpolableValue& interpolable_value,
const NonInterpolableValue* non_interpolable_value,
StyleResolverState& state) const {
- const ClipAutos& autos =
- ToCSSClipNonInterpolableValue(non_interpolable_value)->GetClipAutos();
- const InterpolableList& list = ToInterpolableList(interpolable_value);
+ const auto& autos =
+ To<CSSClipNonInterpolableValue>(non_interpolable_value)->GetClipAutos();
+ const auto& list = To<InterpolableList>(interpolable_value);
const auto& convert_index = [&list, &state](bool is_auto, wtf_size_t index) {
if (is_auto)
return Length::Auto();
diff --git a/chromium/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc
index 1b38fa5ae7d..469d4c0b8da 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_color_interpolation_type.cc
@@ -114,16 +114,16 @@ Color CSSColorInterpolationType::ResolveInterpolableColor(
const StyleResolverState& state,
bool is_visited,
bool is_text_decoration) {
- const InterpolableList& list = ToInterpolableList(interpolable_color);
+ const auto& list = To<InterpolableList>(interpolable_color);
DCHECK_EQ(list.length(), kInterpolableColorIndexCount);
- double red = ToInterpolableNumber(list.Get(kRed))->Value();
- double green = ToInterpolableNumber(list.Get(kGreen))->Value();
- double blue = ToInterpolableNumber(list.Get(kBlue))->Value();
- double alpha = ToInterpolableNumber(list.Get(kAlpha))->Value();
+ double red = To<InterpolableNumber>(list.Get(kRed))->Value();
+ double green = To<InterpolableNumber>(list.Get(kGreen))->Value();
+ double blue = To<InterpolableNumber>(list.Get(kBlue))->Value();
+ double alpha = To<InterpolableNumber>(list.Get(kAlpha))->Value();
if (double currentcolor_fraction =
- ToInterpolableNumber(list.Get(kCurrentcolor))->Value()) {
+ To<InterpolableNumber>(list.Get(kCurrentcolor))->Value()) {
auto current_color_getter = is_visited
? ColorPropertyFunctions::GetVisitedColor
: ColorPropertyFunctions::GetUnvisitedColor;
@@ -146,16 +146,16 @@ Color CSSColorInterpolationType::ResolveInterpolableColor(
}
const TextLinkColors& colors = state.GetDocument().GetTextLinkColors();
if (double webkit_activelink_fraction =
- ToInterpolableNumber(list.Get(kWebkitActivelink))->Value())
+ To<InterpolableNumber>(list.Get(kWebkitActivelink))->Value())
AddPremultipliedColor(red, green, blue, alpha, webkit_activelink_fraction,
colors.ActiveLinkColor());
if (double webkit_link_fraction =
- ToInterpolableNumber(list.Get(kWebkitLink))->Value())
+ To<InterpolableNumber>(list.Get(kWebkitLink))->Value())
AddPremultipliedColor(
red, green, blue, alpha, webkit_link_fraction,
is_visited ? colors.VisitedLinkColor() : colors.LinkColor());
if (double quirk_inherit_fraction =
- ToInterpolableNumber(list.Get(kQuirkInherit))->Value())
+ To<InterpolableNumber>(list.Get(kQuirkInherit))->Value())
AddPremultipliedColor(red, green, blue, alpha, quirk_inherit_fraction,
colors.TextColor());
@@ -274,7 +274,7 @@ void CSSColorInterpolationType::ApplyStandardPropertyValue(
const InterpolableValue& interpolable_value,
const NonInterpolableValue*,
StyleResolverState& state) const {
- const InterpolableList& color_pair = ToInterpolableList(interpolable_value);
+ const auto& color_pair = To<InterpolableList>(interpolable_value);
DCHECK_EQ(color_pair.length(), kInterpolableColorPairIndexCount);
ColorPropertyFunctions::SetUnvisitedColor(
CssProperty(), *state.Style(),
@@ -292,7 +292,7 @@ const CSSValue* CSSColorInterpolationType::CreateCSSValue(
const InterpolableValue& interpolable_value,
const NonInterpolableValue*,
const StyleResolverState& state) const {
- const InterpolableList& color_pair = ToInterpolableList(interpolable_value);
+ const auto& color_pair = To<InterpolableList>(interpolable_value);
Color color = ResolveInterpolableColor(*color_pair.Get(kUnvisited), state);
return cssvalue::CSSColorValue::Create(color.Rgb());
}
@@ -304,26 +304,23 @@ void CSSColorInterpolationType::Composite(
double interpolation_fraction) const {
DCHECK(!underlying_value_owner.Value().non_interpolable_value);
DCHECK(!value.non_interpolable_value);
- InterpolableList& underlying_list = ToInterpolableList(
+ auto& underlying_list = To<InterpolableList>(
*underlying_value_owner.MutableValue().interpolable_value);
- const InterpolableList& other_list =
- ToInterpolableList(*value.interpolable_value);
+ const auto& other_list = To<InterpolableList>(*value.interpolable_value);
// Both lists should have kUnvisited and kVisited.
DCHECK(underlying_list.length() == kInterpolableColorPairIndexCount);
DCHECK(other_list.length() == kInterpolableColorPairIndexCount);
for (wtf_size_t i = 0; i < underlying_list.length(); i++) {
- InterpolableList& underlying =
- ToInterpolableList(*underlying_list.GetMutable(i));
- const InterpolableList& other = ToInterpolableList(*other_list.Get(i));
+ auto& underlying = To<InterpolableList>(*underlying_list.GetMutable(i));
+ const auto& other = To<InterpolableList>(*other_list.Get(i));
DCHECK(underlying.length() == kInterpolableColorIndexCount);
DCHECK(other.length() == kInterpolableColorIndexCount);
for (wtf_size_t j = 0; j < underlying.length(); j++) {
DCHECK(underlying.Get(j)->IsNumber());
DCHECK(other.Get(j)->IsNumber());
- InterpolableNumber& underlying_number =
- ToInterpolableNumber(*underlying.GetMutable(j));
- const InterpolableNumber& other_number =
- ToInterpolableNumber(*other.Get(j));
+ auto& underlying_number =
+ To<InterpolableNumber>(*underlying.GetMutable(j));
+ const auto& other_number = To<InterpolableNumber>(*other.Get(j));
if (j != kAlpha || underlying_number.Value() != other_number.Value())
underlying_number.ScaleAndAdd(underlying_fraction, other_number);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc
index 1a787a8f962..509839e11f3 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc
@@ -56,11 +56,9 @@ const CSSValue* CSSCustomListInterpolationType::CreateCSSValue(
const InterpolableValue& interpolable_value,
const NonInterpolableValue* non_interpolable_value,
const StyleResolverState& state) const {
- const InterpolableList& interpolable_list =
- ToInterpolableList(interpolable_value);
- const NonInterpolableList* non_interpolable_list =
- non_interpolable_value ? &ToNonInterpolableList(*non_interpolable_value)
- : nullptr;
+ const auto& interpolable_list = To<InterpolableList>(interpolable_value);
+ const auto* non_interpolable_list =
+ DynamicTo<NonInterpolableList>(*non_interpolable_value);
CSSValueList* list = nullptr;
diff --git a/chromium/third_party/blink/renderer/core/animation/css_default_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_default_interpolation_type.cc
index be7a9bada05..f6de4f0034e 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_default_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_default_interpolation_type.cc
@@ -23,7 +23,7 @@ InterpolationValue CSSDefaultInterpolationType::MaybeConvertSingle(
const InterpolationEnvironment& environment,
const InterpolationValue&,
ConversionCheckers&) const {
- const CSSValue* css_value = ToCSSPropertySpecificKeyframe(keyframe).Value();
+ const CSSValue* css_value = To<CSSPropertySpecificKeyframe>(keyframe).Value();
if (!css_value) {
DCHECK(keyframe.IsNeutral());
@@ -31,7 +31,7 @@ InterpolationValue CSSDefaultInterpolationType::MaybeConvertSingle(
}
if (RuntimeEnabledFeatures::CSSCascadeEnabled()) {
- css_value = ToCSSInterpolationEnvironment(environment)
+ css_value = To<CSSInterpolationEnvironment>(environment)
.Resolve(GetProperty(), css_value);
if (!css_value)
return nullptr;
@@ -45,11 +45,12 @@ void CSSDefaultInterpolationType::Apply(
const InterpolableValue&,
const NonInterpolableValue* non_interpolable_value,
InterpolationEnvironment& environment) const {
- DCHECK(ToCSSDefaultNonInterpolableValue(non_interpolable_value)->CssValue());
+ DCHECK(
+ To<CSSDefaultNonInterpolableValue>(non_interpolable_value)->CssValue());
StyleBuilder::ApplyProperty(
GetProperty().GetCSSPropertyName(),
- ToCSSInterpolationEnvironment(environment).GetState(),
- *ToCSSDefaultNonInterpolableValue(non_interpolable_value)->CssValue());
+ To<CSSInterpolationEnvironment>(environment).GetState(),
+ *To<CSSDefaultNonInterpolableValue>(non_interpolable_value)->CssValue());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/css_default_interpolation_type.h b/chromium/third_party/blink/renderer/core/animation/css_default_interpolation_type.h
index 941b2cae903..501fc9c4f09 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_default_interpolation_type.h
+++ b/chromium/third_party/blink/renderer/core/animation/css_default_interpolation_type.h
@@ -30,7 +30,15 @@ class CORE_EXPORT CSSDefaultNonInterpolableValue : public NonInterpolableValue {
Persistent<const CSSValue> css_value_;
};
-DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(CSSDefaultNonInterpolableValue);
+template <>
+struct DowncastTraits<CSSDefaultNonInterpolableValue> {
+ static bool AllowFrom(const NonInterpolableValue* value) {
+ return value && AllowFrom(*value);
+ }
+ static bool AllowFrom(const NonInterpolableValue& value) {
+ return value.GetType() == CSSDefaultNonInterpolableValue::static_type_;
+ }
+};
// Never supports pairwise conversion while always supporting single conversion.
// A catch all default for CSSValue interpolation.
diff --git a/chromium/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc
index 1c8e68fa394..06caf9e7dec 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc
@@ -63,8 +63,8 @@ class UnderlyingFilterListChecker
bool IsValid(const StyleResolverState&,
const InterpolationValue& underlying) const final {
- const InterpolableList& underlying_list =
- ToInterpolableList(*underlying.interpolable_value);
+ const auto& underlying_list =
+ To<InterpolableList>(*underlying.interpolable_value);
if (underlying_list.length() != types_.size())
return false;
for (wtf_size_t i = 0; i < types_.size(); i++) {
@@ -129,8 +129,8 @@ class AlwaysInvalidateChecker
InterpolationValue CSSFilterListInterpolationType::MaybeConvertNeutral(
const InterpolationValue& underlying,
ConversionCheckers& conversion_checkers) const {
- const InterpolableList* interpolable_list =
- ToInterpolableList(underlying.interpolable_value.get());
+ const auto* interpolable_list =
+ To<InterpolableList>(underlying.interpolable_value.get());
conversion_checkers.push_back(
std::make_unique<UnderlyingFilterListChecker>(interpolable_list));
// The neutral value for composition for a filter list is the empty list, as
@@ -191,10 +191,9 @@ CSSFilterListInterpolationType::MaybeConvertStandardPropertyUnderlyingValue(
PairwiseInterpolationValue CSSFilterListInterpolationType::MaybeMergeSingles(
InterpolationValue&& start,
InterpolationValue&& end) const {
- InterpolableList& start_interpolable_list =
- ToInterpolableList(*start.interpolable_value);
- InterpolableList& end_interpolable_list =
- ToInterpolableList(*end.interpolable_value);
+ auto& start_interpolable_list =
+ To<InterpolableList>(*start.interpolable_value);
+ auto& end_interpolable_list = To<InterpolableList>(*end.interpolable_value);
wtf_size_t start_length = start_interpolable_list.length();
wtf_size_t end_length = end_interpolable_list.length();
@@ -252,8 +251,7 @@ void CSSFilterListInterpolationType::ApplyStandardPropertyValue(
const InterpolableValue& interpolable_value,
const NonInterpolableValue* non_interpolable_value,
StyleResolverState& state) const {
- const InterpolableList& interpolable_list =
- ToInterpolableList(interpolable_value);
+ const auto& interpolable_list = To<InterpolableList>(interpolable_value);
wtf_size_t length = interpolable_list.length();
FilterOperations filter_operations;
@@ -290,9 +288,9 @@ CSSFilterListInterpolationType::PreInterpolationCompositeIfNeeded(
return nullptr;
auto interpolable_list = std::unique_ptr<InterpolableList>(
- ToInterpolableList(value.interpolable_value.release()));
- const InterpolableList& underlying_list =
- ToInterpolableList(*underlying.interpolable_value);
+ To<InterpolableList>(value.interpolable_value.release()));
+ const auto& underlying_list =
+ To<InterpolableList>(*underlying.interpolable_value);
if (composite == EffectModel::CompositeOperation::kCompositeAdd) {
return PerformAdditiveComposition(std::move(interpolable_list),
diff --git a/chromium/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc
index 6262ba25091..1db1e64c2e6 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc
@@ -41,12 +41,21 @@ class CSSFontVariationSettingsNonInterpolableValue
DEFINE_NON_INTERPOLABLE_VALUE_TYPE(
CSSFontVariationSettingsNonInterpolableValue);
-DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(
- CSSFontVariationSettingsNonInterpolableValue);
+template <>
+struct DowncastTraits<CSSFontVariationSettingsNonInterpolableValue> {
+ static bool AllowFrom(const NonInterpolableValue* value) {
+ return value && AllowFrom(*value);
+ }
+ static bool AllowFrom(const NonInterpolableValue& value) {
+ return value.GetType() ==
+ CSSFontVariationSettingsNonInterpolableValue::static_type_;
+ }
+};
static const Vector<AtomicString> GetTags(
const NonInterpolableValue& non_interpolable_value) {
- return ToCSSFontVariationSettingsNonInterpolableValue(non_interpolable_value)
+ return To<CSSFontVariationSettingsNonInterpolableValue>(
+ non_interpolable_value)
.Tags();
}
@@ -194,7 +203,7 @@ void CSSFontVariationSettingsInterpolationType::ApplyStandardPropertyValue(
const InterpolableValue& interpolable_value,
const NonInterpolableValue* non_interpolable_value,
StyleResolverState& state) const {
- const InterpolableList& numbers = ToInterpolableList(interpolable_value);
+ const auto& numbers = To<InterpolableList>(interpolable_value);
const Vector<AtomicString>& tags = GetTags(*non_interpolable_value);
DCHECK_EQ(numbers.length(), tags.size());
@@ -205,7 +214,7 @@ void CSSFontVariationSettingsInterpolationType::ApplyStandardPropertyValue(
for (wtf_size_t i = 0; i < length; ++i) {
settings->Append(FontVariationAxis(
tags[i],
- clampTo<float>(ToInterpolableNumber(numbers.Get(i))->Value())));
+ clampTo<float>(To<InterpolableNumber>(numbers.Get(i))->Value())));
}
state.GetFontBuilder().SetVariationSettings(settings);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.cc
index b3c5a38e541..9870c5ec5db 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_font_weight_interpolation_type.cc
@@ -109,7 +109,7 @@ void CSSFontWeightInterpolationType::ApplyStandardPropertyValue(
const NonInterpolableValue*,
StyleResolverState& state) const {
state.GetFontBuilder().SetWeight(FontSelectionValue(
- clampTo(ToInterpolableNumber(interpolable_value).Value(),
+ clampTo(To<InterpolableNumber>(interpolable_value).Value(),
MinWeightValue(), MaxWeightValue())));
}
diff --git a/chromium/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc
index 4d48e5a6384..b7d1d7c02f0 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc
@@ -79,15 +79,21 @@ class CSSImageNonInterpolableValue : public NonInterpolableValue {
};
DEFINE_NON_INTERPOLABLE_VALUE_TYPE(CSSImageNonInterpolableValue);
-DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(CSSImageNonInterpolableValue);
+template <>
+struct DowncastTraits<CSSImageNonInterpolableValue> {
+ static bool AllowFrom(const NonInterpolableValue* value) {
+ return value && AllowFrom(*value);
+ }
+ static bool AllowFrom(const NonInterpolableValue& value) {
+ return value.GetType() == CSSImageNonInterpolableValue::static_type_;
+ }
+};
scoped_refptr<CSSImageNonInterpolableValue> CSSImageNonInterpolableValue::Merge(
scoped_refptr<const NonInterpolableValue> start,
scoped_refptr<const NonInterpolableValue> end) {
- const CSSImageNonInterpolableValue& start_image_pair =
- ToCSSImageNonInterpolableValue(*start);
- const CSSImageNonInterpolableValue& end_image_pair =
- ToCSSImageNonInterpolableValue(*end);
+ const auto& start_image_pair = To<CSSImageNonInterpolableValue>(*start);
+ const auto& end_image_pair = To<CSSImageNonInterpolableValue>(*end);
DCHECK(start_image_pair.is_single_);
DCHECK(end_image_pair.is_single_);
return Create(start_image_pair.start_, end_image_pair.end_);
@@ -115,9 +121,10 @@ PairwiseInterpolationValue
CSSImageInterpolationType::StaticMergeSingleConversions(
InterpolationValue&& start,
InterpolationValue&& end) {
- if (!ToCSSImageNonInterpolableValue(*start.non_interpolable_value)
+ if (!To<CSSImageNonInterpolableValue>(*start.non_interpolable_value)
.IsSingle() ||
- !ToCSSImageNonInterpolableValue(*end.non_interpolable_value).IsSingle()) {
+ !To<CSSImageNonInterpolableValue>(*end.non_interpolable_value)
+ .IsSingle()) {
return nullptr;
}
return PairwiseInterpolationValue(
@@ -137,8 +144,8 @@ const CSSValue* CSSImageInterpolationType::CreateCSSValue(
const CSSValue* CSSImageInterpolationType::StaticCreateCSSValue(
const InterpolableValue& interpolable_value,
const NonInterpolableValue* non_interpolable_value) {
- return ToCSSImageNonInterpolableValue(non_interpolable_value)
- ->Crossfade(ToInterpolableNumber(interpolable_value).Value());
+ return To<CSSImageNonInterpolableValue>(non_interpolable_value)
+ ->Crossfade(To<InterpolableNumber>(interpolable_value).Value());
}
StyleImage* CSSImageInterpolationType::ResolveStyleImage(
@@ -154,8 +161,8 @@ StyleImage* CSSImageInterpolationType::ResolveStyleImage(
bool CSSImageInterpolationType::EqualNonInterpolableValues(
const NonInterpolableValue* a,
const NonInterpolableValue* b) {
- return ToCSSImageNonInterpolableValue(*a).Equals(
- ToCSSImageNonInterpolableValue(*b));
+ return To<CSSImageNonInterpolableValue>(*a).Equals(
+ To<CSSImageNonInterpolableValue>(*b));
}
class UnderlyingImageChecker
diff --git a/chromium/third_party/blink/renderer/core/animation/css_image_list_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_image_list_interpolation_type.cc
index 9acb1cfe08e..52fc77278e9 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_image_list_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_image_list_interpolation_type.cc
@@ -167,12 +167,11 @@ void CSSImageListInterpolationType::ApplyStandardPropertyValue(
const InterpolableValue& interpolable_value,
const NonInterpolableValue* non_interpolable_value,
StyleResolverState& state) const {
- const InterpolableList& interpolable_list =
- ToInterpolableList(interpolable_value);
+ const auto& interpolable_list = To<InterpolableList>(interpolable_value);
const wtf_size_t length = interpolable_list.length();
DCHECK_GT(length, 0U);
- const NonInterpolableList& non_interpolable_list =
- ToNonInterpolableList(*non_interpolable_value);
+ const auto& non_interpolable_list =
+ To<NonInterpolableList>(*non_interpolable_value);
DCHECK_EQ(non_interpolable_list.length(), length);
StyleImageList* image_list = MakeGarbageCollected<StyleImageList>(length);
for (wtf_size_t i = 0; i < length; i++) {
diff --git a/chromium/third_party/blink/renderer/core/animation/css_image_slice_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_image_slice_interpolation_type.cc
index 2686262fef4..b12aaa626ea 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_image_slice_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_image_slice_interpolation_type.cc
@@ -84,7 +84,15 @@ class CSSImageSliceNonInterpolableValue : public NonInterpolableValue {
};
DEFINE_NON_INTERPOLABLE_VALUE_TYPE(CSSImageSliceNonInterpolableValue);
-DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(CSSImageSliceNonInterpolableValue);
+template <>
+struct DowncastTraits<CSSImageSliceNonInterpolableValue> {
+ static bool AllowFrom(const NonInterpolableValue* value) {
+ return value && AllowFrom(*value);
+ }
+ static bool AllowFrom(const NonInterpolableValue& value) {
+ return value.GetType() == CSSImageSliceNonInterpolableValue::static_type_;
+ }
+};
namespace {
@@ -96,7 +104,7 @@ class UnderlyingSliceTypesChecker
static SliceTypes GetUnderlyingSliceTypes(
const InterpolationValue& underlying) {
- return ToCSSImageSliceNonInterpolableValue(
+ return To<CSSImageSliceNonInterpolableValue>(
*underlying.non_interpolable_value)
.Types();
}
@@ -226,11 +234,12 @@ CSSImageSliceInterpolationType::MaybeConvertStandardPropertyUnderlyingValue(
PairwiseInterpolationValue CSSImageSliceInterpolationType::MaybeMergeSingles(
InterpolationValue&& start,
InterpolationValue&& end) const {
- const SliceTypes& start_slice_types =
- ToCSSImageSliceNonInterpolableValue(*start.non_interpolable_value)
+ const auto& start_slice_types =
+ To<CSSImageSliceNonInterpolableValue>(*start.non_interpolable_value)
+ .Types();
+ const auto& end_slice_types =
+ To<CSSImageSliceNonInterpolableValue>(*end.non_interpolable_value)
.Types();
- const SliceTypes& end_slice_types =
- ToCSSImageSliceNonInterpolableValue(*end.non_interpolable_value).Types();
if (start_slice_types != end_slice_types)
return nullptr;
@@ -245,12 +254,12 @@ void CSSImageSliceInterpolationType::Composite(
double underlying_fraction,
const InterpolationValue& value,
double interpolation_fraction) const {
- const SliceTypes& underlying_types =
- ToCSSImageSliceNonInterpolableValue(
+ const auto& underlying_types =
+ To<CSSImageSliceNonInterpolableValue>(
*underlying_value_owner.Value().non_interpolable_value)
.Types();
- const SliceTypes& types =
- ToCSSImageSliceNonInterpolableValue(*value.non_interpolable_value)
+ const auto& types =
+ To<CSSImageSliceNonInterpolableValue>(*value.non_interpolable_value)
.Types();
if (underlying_types == types)
@@ -265,12 +274,12 @@ void CSSImageSliceInterpolationType::ApplyStandardPropertyValue(
const NonInterpolableValue* non_interpolable_value,
StyleResolverState& state) const {
ComputedStyle& style = *state.Style();
- const InterpolableList& list = ToInterpolableList(interpolable_value);
- const SliceTypes& types =
- ToCSSImageSliceNonInterpolableValue(non_interpolable_value)->Types();
+ const auto& list = To<InterpolableList>(interpolable_value);
+ const auto& types =
+ To<CSSImageSliceNonInterpolableValue>(non_interpolable_value)->Types();
const auto& convert_side = [&types, &list, &style](wtf_size_t index) {
float value =
- clampTo<float>(ToInterpolableNumber(list.Get(index))->Value(), 0);
+ clampTo<float>(To<InterpolableNumber>(list.Get(index))->Value(), 0);
return types.is_number[index] ? Length::Fixed(value * style.EffectiveZoom())
: Length::Percent(value);
};
diff --git a/chromium/third_party/blink/renderer/core/animation/css_interpolation_environment.cc b/chromium/third_party/blink/renderer/core/animation/css_interpolation_environment.cc
new file mode 100644
index 00000000000..bb8bb38fdbc
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/animation/css_interpolation_environment.cc
@@ -0,0 +1,25 @@
+// 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_interpolation_environment.h"
+
+#include "third_party/blink/renderer/core/animation/property_handle.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_resolver.h"
+#include "third_party/blink/renderer/core/css/resolver/style_cascade.h"
+
+namespace blink {
+
+const CSSValue* CSSInterpolationEnvironment::Resolve(
+ const PropertyHandle& property,
+ const CSSValue* value) const {
+ DCHECK(RuntimeEnabledFeatures::CSSCascadeEnabled());
+ DCHECK(cascade_);
+ DCHECK(cascade_resolver_);
+ if (!value)
+ return value;
+ return cascade_->Resolve(property.GetCSSPropertyName(), *value,
+ *cascade_resolver_);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/css_interpolation_environment.h b/chromium/third_party/blink/renderer/core/animation/css_interpolation_environment.h
index 789ee655a65..7e15b15fbe4 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_interpolation_environment.h
+++ b/chromium/third_party/blink/renderer/core/animation/css_interpolation_environment.h
@@ -6,13 +6,14 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_CSS_INTERPOLATION_ENVIRONMENT_H_
#include "third_party/blink/renderer/core/animation/interpolation_environment.h"
-#include "third_party/blink/renderer/core/css/resolver/style_cascade.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h"
namespace blink {
+class CascadeResolver;
class ComputedStyle;
class CSSVariableResolver;
+class StyleCascade;
class CSSInterpolationEnvironment : public InterpolationEnvironment {
public:
@@ -27,7 +28,7 @@ class CSSInterpolationEnvironment : public InterpolationEnvironment {
explicit CSSInterpolationEnvironment(const InterpolationTypesMap& map,
StyleResolverState& state,
StyleCascade* cascade,
- StyleCascade::Resolver* cascade_resolver)
+ CascadeResolver* cascade_resolver)
: InterpolationEnvironment(map),
state_(&state),
style_(state.Style()),
@@ -67,30 +68,22 @@ class CSSInterpolationEnvironment : public InterpolationEnvironment {
}
// TODO(crbug.com/985023): This effective violates const.
- const CSSValue* Resolve(const PropertyHandle& property,
- const CSSValue* value) const {
- DCHECK(RuntimeEnabledFeatures::CSSCascadeEnabled());
- DCHECK(cascade_);
- DCHECK(cascade_resolver_);
- if (!value)
- return value;
- return cascade_->Resolve(property.GetCSSPropertyName(), *value,
- *cascade_resolver_);
- }
+ const CSSValue* Resolve(const PropertyHandle&, const CSSValue*) const;
private:
StyleResolverState* state_ = nullptr;
const ComputedStyle* style_ = nullptr;
CSSVariableResolver* variable_resolver_ = nullptr;
StyleCascade* cascade_ = nullptr;
- StyleCascade::Resolver* cascade_resolver_ = nullptr;
+ CascadeResolver* cascade_resolver_ = nullptr;
};
-DEFINE_TYPE_CASTS(CSSInterpolationEnvironment,
- InterpolationEnvironment,
- value,
- value->IsCSS(),
- value.IsCSS());
+template <>
+struct DowncastTraits<CSSInterpolationEnvironment> {
+ static bool AllowFrom(const InterpolationEnvironment& value) {
+ return value.IsCSS();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/css_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_interpolation_type.cc
index 5cde658ee51..fcc56d7d292 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_interpolation_type.cc
@@ -39,7 +39,7 @@ class ResolvedVariableChecker : public CSSInterpolationType::ConversionChecker {
private:
bool IsValid(const InterpolationEnvironment& environment,
const InterpolationValue&) const final {
- const auto& css_environment = ToCSSInterpolationEnvironment(environment);
+ const auto& css_environment = To<CSSInterpolationEnvironment>(environment);
// TODO(alancutter): Just check the variables referenced instead of doing a
// full CSSValue resolve.
bool omit_animation_tainted = false;
@@ -101,7 +101,7 @@ class ResolvedRegisteredCustomPropertyChecker
private:
bool IsValid(const InterpolationEnvironment& environment,
const InterpolationValue&) const final {
- const auto& css_environment = ToCSSInterpolationEnvironment(environment);
+ const auto& css_environment = To<CSSInterpolationEnvironment>(environment);
scoped_refptr<CSSVariableData> resolved_tokens = nullptr;
if (RuntimeEnabledFeatures::CSSCascadeEnabled()) {
const CSSValue* resolved = css_environment.Resolve(
@@ -111,7 +111,7 @@ class ResolvedRegisteredCustomPropertyChecker
} else {
DCHECK(css_environment.HasVariableResolver());
bool cycle_detected = false;
- resolved_tokens = ToCSSInterpolationEnvironment(environment)
+ resolved_tokens = To<CSSInterpolationEnvironment>(environment)
.VariableResolver()
.ResolveCustomPropertyAnimationKeyframe(
*declaration_, cycle_detected);
@@ -153,9 +153,8 @@ InterpolationValue CSSInterpolationType::MaybeConvertSingleInternal(
const InterpolationEnvironment& environment,
const InterpolationValue& underlying,
ConversionCheckers& conversion_checkers) const {
- const CSSValue* value = ToCSSPropertySpecificKeyframe(keyframe).Value();
- const CSSInterpolationEnvironment& css_environment =
- ToCSSInterpolationEnvironment(environment);
+ const CSSValue* value = To<CSSPropertySpecificKeyframe>(keyframe).Value();
+ const auto& css_environment = To<CSSInterpolationEnvironment>(environment);
const StyleResolverState& state = css_environment.GetState();
if (!value)
@@ -200,8 +199,7 @@ InterpolationValue CSSInterpolationType::MaybeConvertCustomPropertyDeclaration(
const CSSCustomPropertyDeclaration& declaration,
const InterpolationEnvironment& environment,
ConversionCheckers& conversion_checkers) const {
- const CSSInterpolationEnvironment& css_environment =
- ToCSSInterpolationEnvironment(environment);
+ const auto& css_environment = To<CSSInterpolationEnvironment>(environment);
const StyleResolverState& state = css_environment.GetState();
const AtomicString& name = declaration.GetName();
@@ -268,7 +266,7 @@ InterpolationValue CSSInterpolationType::MaybeConvertCustomPropertyDeclaration(
InterpolationValue CSSInterpolationType::MaybeConvertUnderlyingValue(
const InterpolationEnvironment& environment) const {
const ComputedStyle& style =
- ToCSSInterpolationEnvironment(environment).Style();
+ To<CSSInterpolationEnvironment>(environment).Style();
if (!GetProperty().IsCSSCustomProperty()) {
return MaybeConvertStandardPropertyUnderlyingValue(style);
}
@@ -290,7 +288,7 @@ void CSSInterpolationType::Apply(
const NonInterpolableValue* non_interpolable_value,
InterpolationEnvironment& environment) const {
StyleResolverState& state =
- ToCSSInterpolationEnvironment(environment).GetState();
+ To<CSSInterpolationEnvironment>(environment).GetState();
if (GetProperty().IsCSSCustomProperty()) {
ApplyCustomPropertyValue(interpolable_value, non_interpolable_value, state);
diff --git a/chromium/third_party/blink/renderer/core/animation/css_interpolation_type.h b/chromium/third_party/blink/renderer/core/animation/css_interpolation_type.h
index f829d118286..f1e9bfb1d58 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_interpolation_type.h
+++ b/chromium/third_party/blink/renderer/core/animation/css_interpolation_type.h
@@ -22,7 +22,7 @@ class CORE_EXPORT CSSInterpolationType : public InterpolationType {
public:
bool IsValid(const InterpolationEnvironment& environment,
const InterpolationValue& underlying) const final {
- return IsValid(ToCSSInterpolationEnvironment(environment).GetState(),
+ return IsValid(To<CSSInterpolationEnvironment>(environment).GetState(),
underlying);
}
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 dd06b170d99..422d13f7ed3 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
@@ -59,7 +59,7 @@ CSSInterpolationTypesMap::CSSInterpolationTypesMap(
const Document& document)
: registry_(registry) {
allow_all_animations_ = document.IsFeatureEnabled(
- blink::mojom::FeaturePolicyFeature::kLayoutAnimations);
+ blink::mojom::blink::FeaturePolicyFeature::kLayoutAnimations);
}
static const PropertyRegistration* GetRegistration(
@@ -91,7 +91,7 @@ const InterpolationTypes& CSSInterpolationTypesMap::Get(
// Custom property interpolation types may change over time so don't trust the
// applicableTypesMap without checking the registry.
if (registry_ && property.IsCSSCustomProperty()) {
- const auto* registration = GetRegistration(registry_.Get(), property);
+ const auto* registration = GetRegistration(registry_, property);
if (registration) {
if (found_entry) {
applicable_types_map.erase(entry);
@@ -351,7 +351,7 @@ const InterpolationTypes& CSSInterpolationTypesMap::Get(
std::make_unique<CSSTransformInterpolationType>(used_property));
break;
case CSSPropertyID::kVariable:
- DCHECK_EQ(GetRegistration(registry_.Get(), property), nullptr);
+ DCHECK_EQ(GetRegistration(registry_, property), nullptr);
break;
default:
DCHECK(!css_property.IsInterpolable());
diff --git a/chromium/third_party/blink/renderer/core/animation/css_interpolation_types_map.h b/chromium/third_party/blink/renderer/core/animation/css_interpolation_types_map.h
index fefbce3576e..e334c11b8e0 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_interpolation_types_map.h
+++ b/chromium/third_party/blink/renderer/core/animation/css_interpolation_types_map.h
@@ -30,7 +30,7 @@ class CORE_EXPORT CSSInterpolationTypesMap : public InterpolationTypesMap {
const PropertyRegistration&);
private:
- Member<const PropertyRegistry> registry_;
+ const PropertyRegistry* registry_;
bool allow_all_animations_;
};
diff --git a/chromium/third_party/blink/renderer/core/animation/css_length_list_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_length_list_interpolation_type.cc
index 07864c91aa4..d05ce01f00f 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_length_list_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_length_list_interpolation_type.cc
@@ -164,12 +164,11 @@ void CSSLengthListInterpolationType::ApplyStandardPropertyValue(
const InterpolableValue& interpolable_value,
const NonInterpolableValue* non_interpolable_value,
StyleResolverState& state) const {
- const InterpolableList& interpolable_list =
- ToInterpolableList(interpolable_value);
+ const auto& interpolable_list = To<InterpolableList>(interpolable_value);
const wtf_size_t length = interpolable_list.length();
DCHECK_GT(length, 0U);
- const NonInterpolableList& non_interpolable_list =
- ToNonInterpolableList(*non_interpolable_value);
+ const auto& non_interpolable_list =
+ To<NonInterpolableList>(*non_interpolable_value);
DCHECK_EQ(non_interpolable_list.length(), length);
Vector<Length> result(length);
for (wtf_size_t i = 0; i < length; i++) {
diff --git a/chromium/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc
index 54893a3ecd2..e24be066dc7 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_number_interpolation_type.cc
@@ -38,7 +38,7 @@ const CSSValue* CSSNumberInterpolationType::CreateCSSValue(
const InterpolableValue& value,
const NonInterpolableValue*,
const StyleResolverState&) const {
- double number = ToInterpolableNumber(value).Value();
+ double number = To<InterpolableNumber>(value).Value();
return CSSNumericLiteralValue::Create(
round_to_integer_ ? round(number) : number,
CSSPrimitiveValue::UnitType::kNumber);
@@ -105,7 +105,7 @@ void CSSNumberInterpolationType::ApplyStandardPropertyValue(
const NonInterpolableValue*,
StyleResolverState& state) const {
double clamped_number = NumberPropertyFunctions::ClampNumber(
- CssProperty(), ToInterpolableNumber(interpolable_value).Value());
+ CssProperty(), To<InterpolableNumber>(interpolable_value).Value());
if (!NumberPropertyFunctions::SetNumber(CssProperty(), *state.Style(),
clamped_number)) {
StyleBuilder::ApplyProperty(
diff --git a/chromium/third_party/blink/renderer/core/animation/css_offset_rotate_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_offset_rotate_interpolation_type.cc
index eb886c3a73b..3b9596ed57b 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_offset_rotate_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_offset_rotate_interpolation_type.cc
@@ -36,7 +36,16 @@ class CSSOffsetRotationNonInterpolableValue : public NonInterpolableValue {
};
DEFINE_NON_INTERPOLABLE_VALUE_TYPE(CSSOffsetRotationNonInterpolableValue);
-DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(CSSOffsetRotationNonInterpolableValue);
+template <>
+struct DowncastTraits<CSSOffsetRotationNonInterpolableValue> {
+ static bool AllowFrom(const NonInterpolableValue* value) {
+ return value && AllowFrom(*value);
+ }
+ static bool AllowFrom(const NonInterpolableValue& value) {
+ return value.GetType() ==
+ CSSOffsetRotationNonInterpolableValue::static_type_;
+ }
+};
namespace {
@@ -49,9 +58,10 @@ class UnderlyingRotationTypeChecker
bool IsValid(const StyleResolverState&,
const InterpolationValue& underlying) const final {
- return underlying_rotation_type_ == ToCSSOffsetRotationNonInterpolableValue(
- *underlying.non_interpolable_value)
- .RotationType();
+ return underlying_rotation_type_ ==
+ To<CSSOffsetRotationNonInterpolableValue>(
+ *underlying.non_interpolable_value)
+ .RotationType();
}
private:
@@ -86,7 +96,7 @@ InterpolationValue CSSOffsetRotateInterpolationType::MaybeConvertNeutral(
const InterpolationValue& underlying,
ConversionCheckers& conversion_checkers) const {
OffsetRotationType underlying_rotation_type =
- ToCSSOffsetRotationNonInterpolableValue(
+ To<CSSOffsetRotationNonInterpolableValue>(
*underlying.non_interpolable_value)
.RotationType();
conversion_checkers.push_back(std::make_unique<UnderlyingRotationTypeChecker>(
@@ -121,10 +131,10 @@ PairwiseInterpolationValue CSSOffsetRotateInterpolationType::MaybeMergeSingles(
InterpolationValue&& start,
InterpolationValue&& end) const {
const OffsetRotationType& start_type =
- ToCSSOffsetRotationNonInterpolableValue(*start.non_interpolable_value)
+ To<CSSOffsetRotationNonInterpolableValue>(*start.non_interpolable_value)
.RotationType();
const OffsetRotationType& end_type =
- ToCSSOffsetRotationNonInterpolableValue(*end.non_interpolable_value)
+ To<CSSOffsetRotationNonInterpolableValue>(*end.non_interpolable_value)
.RotationType();
if (start_type != end_type)
return nullptr;
@@ -145,11 +155,11 @@ void CSSOffsetRotateInterpolationType::Composite(
const InterpolationValue& value,
double interpolation_fraction) const {
const OffsetRotationType& underlying_type =
- ToCSSOffsetRotationNonInterpolableValue(
+ To<CSSOffsetRotationNonInterpolableValue>(
*underlying_value_owner.Value().non_interpolable_value)
.RotationType();
const OffsetRotationType& rotation_type =
- ToCSSOffsetRotationNonInterpolableValue(*value.non_interpolable_value)
+ To<CSSOffsetRotationNonInterpolableValue>(*value.non_interpolable_value)
.RotationType();
if (underlying_type == rotation_type) {
underlying_value_owner.MutableValue().interpolable_value->ScaleAndAdd(
@@ -164,8 +174,8 @@ void CSSOffsetRotateInterpolationType::ApplyStandardPropertyValue(
const NonInterpolableValue* non_interpolable_value,
StyleResolverState& state) const {
state.Style()->SetOffsetRotate(StyleOffsetRotation(
- clampTo<float>(ToInterpolableNumber(interpolable_value).Value()),
- ToCSSOffsetRotationNonInterpolableValue(*non_interpolable_value)
+ clampTo<float>(To<InterpolableNumber>(interpolable_value).Value()),
+ To<CSSOffsetRotationNonInterpolableValue>(*non_interpolable_value)
.RotationType()));
}
diff --git a/chromium/third_party/blink/renderer/core/animation/css_percentage_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_percentage_interpolation_type.cc
index 46408b17701..0164fad1a17 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_percentage_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_percentage_interpolation_type.cc
@@ -30,7 +30,7 @@ const CSSValue* CSSPercentageInterpolationType::CreateCSSValue(
const NonInterpolableValue*,
const StyleResolverState&) const {
return CSSNumericLiteralValue::Create(
- ToInterpolableNumber(value).Value(),
+ To<InterpolableNumber>(value).Value(),
CSSPrimitiveValue::UnitType::kPercentage);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/css_ray_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_ray_interpolation_type.cc
index 76f6140f6f2..0b736423173 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_ray_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_ray_interpolation_type.cc
@@ -57,7 +57,15 @@ class CSSRayNonInterpolableValue : public NonInterpolableValue {
};
DEFINE_NON_INTERPOLABLE_VALUE_TYPE(CSSRayNonInterpolableValue);
-DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(CSSRayNonInterpolableValue);
+template <>
+struct DowncastTraits<CSSRayNonInterpolableValue> {
+ static bool AllowFrom(const NonInterpolableValue* value) {
+ return value && AllowFrom(*value);
+ }
+ static bool AllowFrom(const NonInterpolableValue& value) {
+ return value.GetType() == CSSRayNonInterpolableValue::static_type_;
+ }
+};
namespace {
@@ -78,7 +86,7 @@ class UnderlyingRayModeChecker
bool IsValid(const StyleResolverState&,
const InterpolationValue& underlying) const final {
return mode_ ==
- ToCSSRayNonInterpolableValue(*underlying.non_interpolable_value)
+ To<CSSRayNonInterpolableValue>(*underlying.non_interpolable_value)
.Mode();
}
@@ -113,10 +121,10 @@ void CSSRayInterpolationType::ApplyStandardPropertyValue(
const InterpolableValue& interpolable_value,
const NonInterpolableValue* non_interpolable_value,
StyleResolverState& state) const {
- const CSSRayNonInterpolableValue& ray_non_interpolable_value =
- ToCSSRayNonInterpolableValue(*non_interpolable_value);
+ const auto& ray_non_interpolable_value =
+ To<CSSRayNonInterpolableValue>(*non_interpolable_value);
state.Style()->SetOffsetPath(
- StyleRay::Create(ToInterpolableNumber(interpolable_value).Value(),
+ StyleRay::Create(To<InterpolableNumber>(interpolable_value).Value(),
ray_non_interpolable_value.Mode().Size(),
ray_non_interpolable_value.Mode().Contain()));
}
@@ -127,11 +135,11 @@ void CSSRayInterpolationType::Composite(
const InterpolationValue& value,
double interpolation_fraction) const {
const RayMode& underlying_mode =
- ToCSSRayNonInterpolableValue(
+ To<CSSRayNonInterpolableValue>(
*underlying_value_owner.Value().non_interpolable_value)
.Mode();
const RayMode& ray_mode =
- ToCSSRayNonInterpolableValue(*value.non_interpolable_value).Mode();
+ To<CSSRayNonInterpolableValue>(*value.non_interpolable_value).Mode();
if (underlying_mode == ray_mode) {
underlying_value_owner.MutableValue().interpolable_value->ScaleAndAdd(
underlying_fraction, *value.interpolable_value);
@@ -144,7 +152,7 @@ InterpolationValue CSSRayInterpolationType::MaybeConvertNeutral(
const InterpolationValue& underlying,
ConversionCheckers& conversion_checkers) const {
const RayMode& underlying_mode =
- ToCSSRayNonInterpolableValue(*underlying.non_interpolable_value).Mode();
+ To<CSSRayNonInterpolableValue>(*underlying.non_interpolable_value).Mode();
conversion_checkers.push_back(
std::make_unique<UnderlyingRayModeChecker>(underlying_mode));
return CreateValue(0, underlying_mode);
@@ -176,9 +184,9 @@ PairwiseInterpolationValue CSSRayInterpolationType::MaybeMergeSingles(
InterpolationValue&& start,
InterpolationValue&& end) const {
const RayMode& start_mode =
- ToCSSRayNonInterpolableValue(*start.non_interpolable_value).Mode();
+ To<CSSRayNonInterpolableValue>(*start.non_interpolable_value).Mode();
const RayMode& end_mode =
- ToCSSRayNonInterpolableValue(*end.non_interpolable_value).Mode();
+ To<CSSRayNonInterpolableValue>(*end.non_interpolable_value).Mode();
if (start_mode != end_mode)
return nullptr;
return PairwiseInterpolationValue(std::move(start.interpolable_value),
diff --git a/chromium/third_party/blink/renderer/core/animation/css_resolution_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_resolution_interpolation_type.cc
index 14756aa9f08..726f787966e 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_resolution_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_resolution_interpolation_type.cc
@@ -31,7 +31,7 @@ const CSSValue* CSSResolutionInterpolationType::CreateCSSValue(
const NonInterpolableValue*,
const StyleResolverState&) const {
return CSSNumericLiteralValue::Create(
- ToInterpolableNumber(value).Value(),
+ To<InterpolableNumber>(value).Value(),
CSSPrimitiveValue::UnitType::kDotsPerPixel);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/css_rotate_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_rotate_interpolation_type.cc
index cf28f051802..ec70e75ac0f 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_rotate_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_rotate_interpolation_type.cc
@@ -140,7 +140,15 @@ class CSSRotateNonInterpolableValue : public NonInterpolableValue {
};
DEFINE_NON_INTERPOLABLE_VALUE_TYPE(CSSRotateNonInterpolableValue);
-DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(CSSRotateNonInterpolableValue);
+template <>
+struct DowncastTraits<CSSRotateNonInterpolableValue> {
+ static bool AllowFrom(const NonInterpolableValue* value) {
+ return value && AllowFrom(*value);
+ }
+ static bool AllowFrom(const NonInterpolableValue& value) {
+ return value.GetType() == CSSRotateNonInterpolableValue::static_type_;
+ }
+};
namespace {
@@ -219,7 +227,7 @@ CSSRotateInterpolationType::PreInterpolationCompositeIfNeeded(
EffectModel::CompositeOperation,
ConversionCheckers&) const {
value.non_interpolable_value = CSSRotateNonInterpolableValue::CreateAdditive(
- ToCSSRotateNonInterpolableValue(*value.non_interpolable_value));
+ To<CSSRotateNonInterpolableValue>(*value.non_interpolable_value));
return value;
}
@@ -230,8 +238,8 @@ PairwiseInterpolationValue CSSRotateInterpolationType::MaybeMergeSingles(
std::make_unique<InterpolableNumber>(0),
std::make_unique<InterpolableNumber>(1),
CSSRotateNonInterpolableValue::Create(
- ToCSSRotateNonInterpolableValue(*start.non_interpolable_value),
- ToCSSRotateNonInterpolableValue(*end.non_interpolable_value)));
+ To<CSSRotateNonInterpolableValue>(*start.non_interpolable_value),
+ To<CSSRotateNonInterpolableValue>(*end.non_interpolable_value)));
}
InterpolationValue
@@ -245,12 +253,12 @@ void CSSRotateInterpolationType::Composite(
double underlying_fraction,
const InterpolationValue& value,
double interpolation_fraction) const {
- const CSSRotateNonInterpolableValue& underlying_non_interpolable_value =
- ToCSSRotateNonInterpolableValue(
+ const auto& underlying_non_interpolable_value =
+ To<CSSRotateNonInterpolableValue>(
*underlying_value_owner.Value().non_interpolable_value);
- const CSSRotateNonInterpolableValue& non_interpolable_value =
- ToCSSRotateNonInterpolableValue(*value.non_interpolable_value);
- double progress = ToInterpolableNumber(*value.interpolable_value).Value();
+ const auto& non_interpolable_value =
+ To<CSSRotateNonInterpolableValue>(*value.non_interpolable_value);
+ double progress = To<InterpolableNumber>(*value.interpolable_value).Value();
underlying_value_owner.MutableValue().non_interpolable_value =
underlying_non_interpolable_value.Composite(non_interpolable_value,
progress);
@@ -260,9 +268,9 @@ void CSSRotateInterpolationType::ApplyStandardPropertyValue(
const InterpolableValue& interpolable_value,
const NonInterpolableValue* untyped_non_interpolable_value,
StyleResolverState& state) const {
- double progress = ToInterpolableNumber(interpolable_value).Value();
- const CSSRotateNonInterpolableValue& non_interpolable_value =
- ToCSSRotateNonInterpolableValue(*untyped_non_interpolable_value);
+ double progress = To<InterpolableNumber>(interpolable_value).Value();
+ const auto& non_interpolable_value =
+ To<CSSRotateNonInterpolableValue>(*untyped_non_interpolable_value);
OptionalRotation rotation = non_interpolable_value.SlerpedRotation(progress);
if (rotation.IsNone()) {
state.Style()->SetRotate(nullptr);
diff --git a/chromium/third_party/blink/renderer/core/animation/css_scale_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_scale_interpolation_type.cc
index 3efeb2bc6b0..9da7670ecb9 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_scale_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_scale_interpolation_type.cc
@@ -27,14 +27,14 @@ struct Scale {
Init(1, 1, 1, true);
}
explicit Scale(const InterpolableValue& value) {
- const InterpolableList& list = ToInterpolableList(value);
+ const auto& list = To<InterpolableList>(value);
if (list.length() == 0) {
Init(1, 1, 1, true);
return;
}
- Init(ToInterpolableNumber(*list.Get(0)).Value(),
- ToInterpolableNumber(*list.Get(1)).Value(),
- ToInterpolableNumber(*list.Get(2)).Value(), false);
+ Init(To<InterpolableNumber>(*list.Get(0)).Value(),
+ To<InterpolableNumber>(*list.Get(1)).Value(),
+ To<InterpolableNumber>(*list.Get(2)).Value(), false);
}
void Init(double x, double y, double z, bool is_value_none) {
@@ -130,7 +130,15 @@ class CSSScaleNonInterpolableValue : public NonInterpolableValue {
};
DEFINE_NON_INTERPOLABLE_VALUE_TYPE(CSSScaleNonInterpolableValue);
-DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(CSSScaleNonInterpolableValue);
+template <>
+struct DowncastTraits<CSSScaleNonInterpolableValue> {
+ static bool AllowFrom(const NonInterpolableValue* value) {
+ return value && AllowFrom(*value);
+ }
+ static bool AllowFrom(const NonInterpolableValue& value) {
+ return value.GetType() == CSSScaleNonInterpolableValue::static_type_;
+ }
+};
InterpolationValue Scale::CreateInterpolationValue() const {
if (is_none) {
@@ -199,7 +207,7 @@ InterpolationValue CSSScaleInterpolationType::PreInterpolationCompositeIfNeeded(
EffectModel::CompositeOperation,
ConversionCheckers&) const {
value.non_interpolable_value = CSSScaleNonInterpolableValue::CreateAdditive(
- ToCSSScaleNonInterpolableValue(*value.non_interpolable_value));
+ To<CSSScaleNonInterpolableValue>(*value.non_interpolable_value));
return value;
}
@@ -207,9 +215,9 @@ PairwiseInterpolationValue CSSScaleInterpolationType::MaybeMergeSingles(
InterpolationValue&& start,
InterpolationValue&& end) const {
wtf_size_t start_list_length =
- ToInterpolableList(*start.interpolable_value).length();
+ To<InterpolableList>(*start.interpolable_value).length();
wtf_size_t end_list_length =
- ToInterpolableList(*end.interpolable_value).length();
+ To<InterpolableList>(*end.interpolable_value).length();
if (start_list_length < end_list_length)
start.interpolable_value = CreateScaleIdentity();
else if (end_list_length < start_list_length)
@@ -218,8 +226,8 @@ PairwiseInterpolationValue CSSScaleInterpolationType::MaybeMergeSingles(
return PairwiseInterpolationValue(
std::move(start.interpolable_value), std::move(end.interpolable_value),
CSSScaleNonInterpolableValue::Merge(
- ToCSSScaleNonInterpolableValue(*start.non_interpolable_value),
- ToCSSScaleNonInterpolableValue(*end.non_interpolable_value)));
+ To<CSSScaleNonInterpolableValue>(*start.non_interpolable_value),
+ To<CSSScaleNonInterpolableValue>(*end.non_interpolable_value)));
}
InterpolationValue
@@ -233,22 +241,21 @@ void CSSScaleInterpolationType::Composite(
double underlying_fraction,
const InterpolationValue& value,
double interpolation_fraction) const {
- if (ToInterpolableList(
+ if (To<InterpolableList>(
*underlying_value_owner.MutableValue().interpolable_value)
.length() == 0) {
underlying_value_owner.MutableValue().interpolable_value =
CreateScaleIdentity();
}
- const CSSScaleNonInterpolableValue& metadata =
- ToCSSScaleNonInterpolableValue(*value.non_interpolable_value);
+ const auto& metadata =
+ To<CSSScaleNonInterpolableValue>(*value.non_interpolable_value);
DCHECK(metadata.IsStartAdditive() || metadata.IsEndAdditive());
- InterpolableList& underlying_list = ToInterpolableList(
+ auto& underlying_list = To<InterpolableList>(
*underlying_value_owner.MutableValue().interpolable_value);
for (wtf_size_t i = 0; i < 3; i++) {
- InterpolableNumber& underlying =
- ToInterpolableNumber(*underlying_list.GetMutable(i));
+ auto& underlying = To<InterpolableNumber>(*underlying_list.GetMutable(i));
double start = metadata.Start().array[i] *
(metadata.IsStartAdditive() ? underlying.Value() : 1);
diff --git a/chromium/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.cc
index 32e5a119674..af72365dff6 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.cc
@@ -102,6 +102,15 @@ InterpolationValue CSSShadowListInterpolationType::MaybeConvertInherit(
state.ParentStyle()->EffectiveZoom());
}
+class AlwaysInvalidateChecker
+ : public CSSInterpolationType::CSSConversionChecker {
+ public:
+ bool IsValid(const StyleResolverState& state,
+ const InterpolationValue& underlying) const final {
+ return false;
+ }
+};
+
InterpolationValue CSSShadowListInterpolationType::MaybeConvertValue(
const CSSValue& value,
const StyleResolverState*,
@@ -147,21 +156,16 @@ void CSSShadowListInterpolationType::Composite(
double underlying_fraction,
const InterpolationValue& value,
double interpolation_fraction) const {
- ListInterpolationFunctions::Composite(
- underlying_value_owner, underlying_fraction, *this, value,
- ListInterpolationFunctions::LengthMatchingStrategy::kPadToLargest,
- WTF::BindRepeating(InterpolableShadow::CompatibleForCompositing),
- WTF::BindRepeating(
- ListInterpolationFunctions::VerifyNoNonInterpolableValues),
- WTF::BindRepeating(InterpolableShadow::Composite));
+ // We do our compositing behavior in |PreInterpolationCompositeIfNeeded|; see
+ // the documentation on that method.
+ underlying_value_owner.Set(*this, value);
}
static scoped_refptr<ShadowList> CreateShadowList(
const InterpolableValue& interpolable_value,
const NonInterpolableValue* non_interpolable_value,
const StyleResolverState& state) {
- const InterpolableList& interpolable_list =
- ToInterpolableList(interpolable_value);
+ const auto& interpolable_list = To<InterpolableList>(interpolable_value);
wtf_size_t length = interpolable_list.length();
if (length == 0)
return nullptr;
@@ -191,4 +195,86 @@ void CSSShadowListInterpolationType::ApplyStandardPropertyValue(
}
}
+InterpolationValue
+CSSShadowListInterpolationType::PreInterpolationCompositeIfNeeded(
+ InterpolationValue value,
+ const InterpolationValue& underlying,
+ EffectModel::CompositeOperation composite,
+ ConversionCheckers& conversion_checkers) const {
+ // Due to the post-interpolation composite optimization, the interpolation
+ // stack aggressively caches interpolated values. When we are doing
+ // pre-interpolation compositing, this can cause us to bake-in the composited
+ // result even when the underlying value is changing. This checker is a hack
+ // to disable that caching in this case.
+ // TODO(crbug.com/1009230): Remove this once our interpolation code isn't
+ // caching composited values.
+ conversion_checkers.push_back(std::make_unique<AlwaysInvalidateChecker>());
+ auto interpolable_list = std::unique_ptr<InterpolableList>(
+ To<InterpolableList>(value.interpolable_value.release()));
+ if (composite == EffectModel::CompositeOperation::kCompositeAdd) {
+ return PerformAdditiveComposition(std::move(interpolable_list), underlying);
+ }
+ DCHECK_EQ(composite, EffectModel::CompositeOperation::kCompositeAccumulate);
+ return PerformAccumulativeComposition(std::move(interpolable_list),
+ std::move(underlying));
+}
+
+InterpolationValue CSSShadowListInterpolationType::PerformAdditiveComposition(
+ std::unique_ptr<InterpolableList> interpolable_list,
+ const InterpolationValue& underlying) const {
+ // Per the spec, addition of shadow lists is defined as concatenation.
+ // https://drafts.csswg.org/web-animations/#combining-shadow-lists
+ const InterpolableList& underlying_list =
+ To<InterpolableList>(*underlying.interpolable_value);
+ auto composited_list = std::make_unique<InterpolableList>(
+ underlying_list.length() + interpolable_list->length());
+ for (wtf_size_t i = 0; i < composited_list->length(); i++) {
+ if (i < underlying_list.length()) {
+ composited_list->Set(i, underlying_list.Get(i)->Clone());
+ } else {
+ composited_list->Set(
+ i, interpolable_list->Get(i - underlying_list.length())->Clone());
+ }
+ }
+ return InterpolationValue(std::move(composited_list),
+ underlying.non_interpolable_value);
+}
+
+InterpolationValue
+CSSShadowListInterpolationType::PerformAccumulativeComposition(
+ std::unique_ptr<InterpolableList> interpolable_list,
+ const InterpolationValue& underlying) const {
+ // Per the spec, accumulation of shadow lists operates on pairwise addition of
+ // the underlying components.
+ // https://drafts.csswg.org/web-animations/#combining-shadow-lists
+ const InterpolableList& underlying_list =
+ To<InterpolableList>(*underlying.interpolable_value);
+ wtf_size_t length = interpolable_list->length();
+ wtf_size_t underlying_length = underlying_list.length();
+ // If any of the shadow style(inset or normal) value don't match, fallback to
+ // replace behavior.
+ for (wtf_size_t i = 0; i < underlying_length && i < length; i++) {
+ if (To<InterpolableShadow>(underlying_list.Get(i))->GetShadowStyle() !=
+ To<InterpolableShadow>(interpolable_list->Get(i))->GetShadowStyle()) {
+ return InterpolationValue(std::move(interpolable_list));
+ }
+ }
+
+ // Otherwise, arithmetically combine the matching prefix of the lists then
+ // concatenate the remainder of the longer one.
+ wtf_size_t max_length = std::max(length, underlying_length);
+ auto composited_list = std::make_unique<InterpolableList>(max_length);
+ for (wtf_size_t i = 0; i < max_length; i++) {
+ if (i < underlying_length) {
+ composited_list->Set(i, underlying_list.Get(i)->Clone());
+ if (i < length)
+ composited_list->GetMutable(i)->Add(*interpolable_list->Get(i));
+ } else {
+ composited_list->Set(i, interpolable_list->Get(i)->Clone());
+ }
+ }
+ return InterpolationValue(std::move(composited_list),
+ underlying.non_interpolable_value);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.h b/chromium/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.h
index 552115741fa..c1254e99b12 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.h
+++ b/chromium/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.h
@@ -42,6 +42,17 @@ class CSSShadowListInterpolationType : public CSSInterpolationType {
PairwiseInterpolationValue MaybeMergeSingles(
InterpolationValue&& start,
InterpolationValue&& end) const final;
+ InterpolationValue PreInterpolationCompositeIfNeeded(
+ InterpolationValue value,
+ const InterpolationValue& underlying,
+ EffectModel::CompositeOperation,
+ ConversionCheckers&) const final;
+ InterpolationValue PerformAdditiveComposition(
+ std::unique_ptr<InterpolableList> interpolable_list,
+ const InterpolationValue& underlying) const;
+ InterpolationValue PerformAccumulativeComposition(
+ std::unique_ptr<InterpolableList> interpolable_list,
+ const InterpolationValue& underlying) const;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/css_size_list_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_size_list_interpolation_type.cc
index 7ae4e5109b0..829c2921e6e 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_size_list_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_size_list_interpolation_type.cc
@@ -30,7 +30,7 @@ class UnderlyingSizeListChecker
bool IsValid(const StyleResolverState&,
const InterpolationValue& underlying) const final {
const auto& underlying_list =
- ToNonInterpolableList(*underlying.non_interpolable_value);
+ To<NonInterpolableList>(*underlying.non_interpolable_value);
wtf_size_t underlying_length = underlying_list.length();
if (underlying_length != underlying_list_->length())
return false;
@@ -105,7 +105,7 @@ InterpolationValue CSSSizeListInterpolationType::MaybeConvertNeutral(
const InterpolationValue& underlying,
ConversionCheckers& conversion_checkers) const {
const auto& underlying_list =
- ToNonInterpolableList(*underlying.non_interpolable_value);
+ To<NonInterpolableList>(*underlying.non_interpolable_value);
conversion_checkers.push_back(
std::make_unique<UnderlyingSizeListChecker>(underlying_list));
return ListInterpolationFunctions::CreateList(
@@ -175,9 +175,9 @@ void CSSSizeListInterpolationType::ApplyStandardPropertyValue(
const InterpolableValue& interpolable_value,
const NonInterpolableValue* non_interpolable_value,
StyleResolverState& state) const {
- const auto& interpolable_list = ToInterpolableList(interpolable_value);
+ const auto& interpolable_list = To<InterpolableList>(interpolable_value);
const auto& non_interpolable_list =
- ToNonInterpolableList(*non_interpolable_value);
+ To<NonInterpolableList>(*non_interpolable_value);
wtf_size_t length = interpolable_list.length();
DCHECK_EQ(length, non_interpolable_list.length());
DCHECK_EQ(length % 2, 0ul);
diff --git a/chromium/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.cc
index 05174e233ec..97cdbac1515 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.cc
@@ -65,7 +65,15 @@ class CSSTextIndentNonInterpolableValue : public NonInterpolableValue {
};
DEFINE_NON_INTERPOLABLE_VALUE_TYPE(CSSTextIndentNonInterpolableValue);
-DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(CSSTextIndentNonInterpolableValue);
+template <>
+struct DowncastTraits<CSSTextIndentNonInterpolableValue> {
+ static bool AllowFrom(const NonInterpolableValue* value) {
+ return value && AllowFrom(*value);
+ }
+ static bool AllowFrom(const NonInterpolableValue& value) {
+ return value.GetType() == CSSTextIndentNonInterpolableValue::static_type_;
+ }
+};
namespace {
@@ -76,7 +84,7 @@ class UnderlyingIndentModeChecker
bool IsValid(const StyleResolverState&,
const InterpolationValue& underlying) const final {
- return mode_ == ToCSSTextIndentNonInterpolableValue(
+ return mode_ == To<CSSTextIndentNonInterpolableValue>(
*underlying.non_interpolable_value)
.Mode();
}
@@ -120,7 +128,7 @@ InterpolationValue CSSTextIndentInterpolationType::MaybeConvertNeutral(
const InterpolationValue& underlying,
ConversionCheckers& conversion_checkers) const {
IndentMode mode =
- ToCSSTextIndentNonInterpolableValue(*underlying.non_interpolable_value)
+ To<CSSTextIndentNonInterpolableValue>(*underlying.non_interpolable_value)
.Mode();
conversion_checkers.push_back(
std::make_unique<UnderlyingIndentModeChecker>(mode));
@@ -185,10 +193,10 @@ CSSTextIndentInterpolationType::MaybeConvertStandardPropertyUnderlyingValue(
PairwiseInterpolationValue CSSTextIndentInterpolationType::MaybeMergeSingles(
InterpolationValue&& start,
InterpolationValue&& end) const {
- const CSSTextIndentNonInterpolableValue& start_non_interpolable_value =
- ToCSSTextIndentNonInterpolableValue(*start.non_interpolable_value);
- const CSSTextIndentNonInterpolableValue& end_non_interpolable_value =
- ToCSSTextIndentNonInterpolableValue(*end.non_interpolable_value);
+ const auto& start_non_interpolable_value =
+ To<CSSTextIndentNonInterpolableValue>(*start.non_interpolable_value);
+ const auto& end_non_interpolable_value =
+ To<CSSTextIndentNonInterpolableValue>(*end.non_interpolable_value);
if (start_non_interpolable_value.Mode() != end_non_interpolable_value.Mode())
return nullptr;
@@ -207,11 +215,11 @@ void CSSTextIndentInterpolationType::Composite(
const InterpolationValue& value,
double interpolation_fraction) const {
const IndentMode& underlying_mode =
- ToCSSTextIndentNonInterpolableValue(
+ To<CSSTextIndentNonInterpolableValue>(
*underlying_value_owner.Value().non_interpolable_value)
.Mode();
- const CSSTextIndentNonInterpolableValue& non_interpolable_value =
- ToCSSTextIndentNonInterpolableValue(*value.non_interpolable_value);
+ const auto& non_interpolable_value =
+ To<CSSTextIndentNonInterpolableValue>(*value.non_interpolable_value);
const IndentMode& mode = non_interpolable_value.Mode();
if (underlying_mode != mode) {
@@ -227,9 +235,8 @@ void CSSTextIndentInterpolationType::ApplyStandardPropertyValue(
const InterpolableValue& interpolable_value,
const NonInterpolableValue* non_interpolable_value,
StyleResolverState& state) const {
- const CSSTextIndentNonInterpolableValue&
- css_text_indent_non_interpolable_value =
- ToCSSTextIndentNonInterpolableValue(*non_interpolable_value);
+ const auto& css_text_indent_non_interpolable_value =
+ To<CSSTextIndentNonInterpolableValue>(*non_interpolable_value);
ComputedStyle& style = *state.Style();
style.SetTextIndent(
To<InterpolableLength>(interpolable_value)
diff --git a/chromium/third_party/blink/renderer/core/animation/css_time_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_time_interpolation_type.cc
index 6f41dba301a..7e9a7d2d5d6 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_time_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_time_interpolation_type.cc
@@ -30,7 +30,7 @@ const CSSValue* CSSTimeInterpolationType::CreateCSSValue(
const InterpolableValue& value,
const NonInterpolableValue*,
const StyleResolverState&) const {
- return CSSNumericLiteralValue::Create(ToInterpolableNumber(value).Value(),
+ return CSSNumericLiteralValue::Create(To<InterpolableNumber>(value).Value(),
CSSPrimitiveValue::UnitType::kSeconds);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/css_translate_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_translate_interpolation_type.cc
index e4675fd0b17..55bce0b724f 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_translate_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_translate_interpolation_type.cc
@@ -23,7 +23,7 @@ InterpolationValue CreateNoneValue() {
}
bool IsNoneValue(const InterpolationValue& value) {
- return ToInterpolableList(*value.interpolable_value).length() == 0;
+ return To<InterpolableList>(*value.interpolable_value).length() == 0;
}
class InheritedTranslateChecker
@@ -141,8 +141,9 @@ PairwiseInterpolationValue CSSTranslateInterpolationType::MaybeMergeSingles(
InterpolationValue&& start,
InterpolationValue&& end) const {
size_t start_list_length =
- ToInterpolableList(*start.interpolable_value).length();
- size_t end_list_length = ToInterpolableList(*end.interpolable_value).length();
+ To<InterpolableList>(*start.interpolable_value).length();
+ size_t end_list_length =
+ To<InterpolableList>(*end.interpolable_value).length();
if (start_list_length < end_list_length)
start.interpolable_value = CreateTranslateIdentity();
else if (end_list_length < start_list_length)
@@ -181,7 +182,7 @@ void CSSTranslateInterpolationType::ApplyStandardPropertyValue(
const InterpolableValue& interpolable_value,
const NonInterpolableValue*,
StyleResolverState& state) const {
- const InterpolableList& list = ToInterpolableList(interpolable_value);
+ const auto& list = To<InterpolableList>(interpolable_value);
if (list.length() == 0) {
state.Style()->SetTranslate(nullptr);
return;
diff --git a/chromium/third_party/blink/renderer/core/animation/css_var_cycle_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_var_cycle_interpolation_type.cc
index e596f3534d8..6ae83a184c7 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_var_cycle_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_var_cycle_interpolation_type.cc
@@ -28,7 +28,7 @@ class CycleChecker : public InterpolationType::ConversionChecker {
private:
bool IsValid(const InterpolationEnvironment& environment,
const InterpolationValue&) const final {
- const auto& css_environment = ToCSSInterpolationEnvironment(environment);
+ const auto& css_environment = To<CSSInterpolationEnvironment>(environment);
bool cycle_detected = false;
if (RuntimeEnabledFeatures::CSSCascadeEnabled()) {
cycle_detected = !css_environment.Resolve(
@@ -61,13 +61,13 @@ InterpolationValue CSSVarCycleInterpolationType::MaybeConvertSingle(
const InterpolationValue& underlying,
ConversionCheckers& conversion_checkers) const {
const auto& declaration = *To<CSSCustomPropertyDeclaration>(
- ToCSSPropertySpecificKeyframe(keyframe).Value());
+ To<CSSPropertySpecificKeyframe>(keyframe).Value());
DCHECK_EQ(GetProperty().CustomPropertyName(), declaration.GetName());
if (!declaration.Value() || !declaration.Value()->NeedsVariableResolution()) {
return nullptr;
}
- const auto& css_environment = ToCSSInterpolationEnvironment(environment);
+ const auto& css_environment = To<CSSInterpolationEnvironment>(environment);
bool cycle_detected = false;
if (RuntimeEnabledFeatures::CSSCascadeEnabled()) {
@@ -114,7 +114,7 @@ PairwiseInterpolationValue CSSVarCycleInterpolationType::MaybeConvertPairwise(
InterpolationValue CSSVarCycleInterpolationType::MaybeConvertUnderlyingValue(
const InterpolationEnvironment& environment) const {
const ComputedStyle& style =
- ToCSSInterpolationEnvironment(environment).Style();
+ To<CSSInterpolationEnvironment>(environment).Style();
DCHECK(!style.GetVariableData(GetProperty().CustomPropertyName()) ||
!style.GetVariableData(GetProperty().CustomPropertyName())
->NeedsVariableResolution());
@@ -127,7 +127,7 @@ void CSSVarCycleInterpolationType::Apply(
InterpolationEnvironment& environment) const {
StyleBuilder::ApplyProperty(
GetProperty().GetCSSPropertyName(),
- ToCSSInterpolationEnvironment(environment).GetState(),
+ To<CSSInterpolationEnvironment>(environment).GetState(),
*MakeGarbageCollected<CSSCustomPropertyDeclaration>(
GetProperty().CustomPropertyName(), CSSValueID::kUnset));
}
diff --git a/chromium/third_party/blink/renderer/core/animation/css_visibility_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/css_visibility_interpolation_type.cc
index d0153dd94a8..f3156672400 100644
--- a/chromium/third_party/blink/renderer/core/animation/css_visibility_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/css_visibility_interpolation_type.cc
@@ -49,7 +49,15 @@ class CSSVisibilityNonInterpolableValue : public NonInterpolableValue {
};
DEFINE_NON_INTERPOLABLE_VALUE_TYPE(CSSVisibilityNonInterpolableValue);
-DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(CSSVisibilityNonInterpolableValue);
+template <>
+struct DowncastTraits<CSSVisibilityNonInterpolableValue> {
+ static bool AllowFrom(const NonInterpolableValue* value) {
+ return value && AllowFrom(*value);
+ }
+ static bool AllowFrom(const NonInterpolableValue& value) {
+ return value.GetType() == CSSVisibilityNonInterpolableValue::static_type_;
+ }
+};
class UnderlyingVisibilityChecker
: public CSSInterpolationType::CSSConversionChecker {
@@ -64,10 +72,10 @@ class UnderlyingVisibilityChecker
bool IsValid(const StyleResolverState&,
const InterpolationValue& underlying) const final {
double underlying_fraction =
- ToInterpolableNumber(*underlying.interpolable_value).Value();
- EVisibility underlying_visibility =
- ToCSSVisibilityNonInterpolableValue(*underlying.non_interpolable_value)
- .Visibility(underlying_fraction);
+ To<InterpolableNumber>(*underlying.interpolable_value).Value();
+ EVisibility underlying_visibility = To<CSSVisibilityNonInterpolableValue>(
+ *underlying.non_interpolable_value)
+ .Visibility(underlying_fraction);
return visibility_ == underlying_visibility;
}
@@ -100,9 +108,9 @@ InterpolationValue CSSVisibilityInterpolationType::MaybeConvertNeutral(
const InterpolationValue& underlying,
ConversionCheckers& conversion_checkers) const {
double underlying_fraction =
- ToInterpolableNumber(*underlying.interpolable_value).Value();
+ To<InterpolableNumber>(*underlying.interpolable_value).Value();
EVisibility underlying_visibility =
- ToCSSVisibilityNonInterpolableValue(*underlying.non_interpolable_value)
+ To<CSSVisibilityNonInterpolableValue>(*underlying.non_interpolable_value)
.Visibility(underlying_fraction);
conversion_checkers.push_back(
std::make_unique<UnderlyingVisibilityChecker>(underlying_visibility));
@@ -156,10 +164,10 @@ PairwiseInterpolationValue CSSVisibilityInterpolationType::MaybeMergeSingles(
InterpolationValue&& start,
InterpolationValue&& end) const {
EVisibility start_visibility =
- ToCSSVisibilityNonInterpolableValue(*start.non_interpolable_value)
+ To<CSSVisibilityNonInterpolableValue>(*start.non_interpolable_value)
.Visibility();
EVisibility end_visibility =
- ToCSSVisibilityNonInterpolableValue(*end.non_interpolable_value)
+ To<CSSVisibilityNonInterpolableValue>(*end.non_interpolable_value)
.Visibility();
// One side must be "visible".
// Spec: https://drafts.csswg.org/css-transitions/#animtype-visibility
@@ -188,9 +196,9 @@ void CSSVisibilityInterpolationType::ApplyStandardPropertyValue(
StyleResolverState& state) const {
// Visibility interpolation has been deferred to application time here due to
// its non-linear behaviour.
- double fraction = ToInterpolableNumber(interpolable_value).Value();
+ double fraction = To<InterpolableNumber>(interpolable_value).Value();
EVisibility visibility =
- ToCSSVisibilityNonInterpolableValue(non_interpolable_value)
+ To<CSSVisibilityNonInterpolableValue>(non_interpolable_value)
->Visibility(fraction);
state.Style()->SetVisibility(visibility);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/document_animation.h b/chromium/third_party/blink/renderer/core/animation/document_animation.h
index 33c5eedfb4e..0b51df67301 100644
--- a/chromium/third_party/blink/renderer/core/animation/document_animation.h
+++ b/chromium/third_party/blink/renderer/core/animation/document_animation.h
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_DOCUMENT_ANIMATION_H_
#include "third_party/blink/renderer/core/animation/animation.h"
-#include "third_party/blink/renderer/core/animation/document_timeline.h"
+#include "third_party/blink/renderer/core/animation/document_animations.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -19,10 +19,6 @@ class DocumentAnimation {
static DocumentTimeline* timeline(Document& document) {
return &document.Timeline();
}
-
- static HeapVector<Member<Animation>> getAnimations(Document& document) {
- return document.Timeline().getAnimations();
- }
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/document_animation.idl b/chromium/third_party/blink/renderer/core/animation/document_animation.idl
index abefa7fc922..7a3eabb053d 100644
--- a/chromium/third_party/blink/renderer/core/animation/document_animation.idl
+++ b/chromium/third_party/blink/renderer/core/animation/document_animation.idl
@@ -9,6 +9,4 @@
RuntimeEnabled=WebAnimationsAPI
] partial interface Document {
readonly attribute DocumentTimeline timeline;
-
- sequence<Animation> getAnimations();
};
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 4376625fea0..104c0de08b5 100644
--- a/chromium/third_party/blink/renderer/core/animation/document_animations.cc
+++ b/chromium/third_party/blink/renderer/core/animation/document_animations.cc
@@ -32,70 +32,139 @@
#include "cc/animation/animation_host.h"
#include "third_party/blink/renderer/core/animation/animation_clock.h"
-#include "third_party/blink/renderer/core/animation/document_timeline.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/pending_animations.h"
#include "third_party/blink/renderer/core/animation/worklet_animation_controller.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/dom/node.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/page/page.h"
+#include "third_party/blink/renderer/core/page/page_animator.h"
namespace blink {
namespace {
-void UpdateAnimationTiming(Document& document, TimingUpdateReason reason) {
- document.Timeline().ServiceAnimations(reason);
+void UpdateAnimationTiming(
+ Document& document,
+ HeapHashSet<WeakMember<AnimationTimeline>>& timelines,
+ TimingUpdateReason reason) {
+ for (auto& timeline : timelines)
+ timeline->ServiceAnimations(reason);
document.GetWorkletAnimationController().UpdateAnimationTimings(reason);
}
+bool CompareAnimations(const Member<Animation>& left,
+ const Member<Animation>& right) {
+ return Animation::HasLowerCompositeOrdering(
+ left.Get(), right.Get(),
+ Animation::CompareAnimationsOrdering::kTreeOrder);
+}
} // namespace
-void DocumentAnimations::UpdateAnimationTimingForAnimationFrame(
- Document& document) {
- UpdateAnimationTiming(document, kTimingUpdateForAnimationFrame);
+DocumentAnimations::DocumentAnimations(Document* document)
+ : document_(document) {}
+
+void DocumentAnimations::AddTimeline(AnimationTimeline& timeline) {
+ timelines_.insert(&timeline);
+}
+
+void DocumentAnimations::UpdateAnimationTimingForAnimationFrame() {
+ UpdateAnimationTiming(*document_, timelines_, kTimingUpdateForAnimationFrame);
}
-bool DocumentAnimations::NeedsAnimationTimingUpdate(const Document& document) {
- return document.Timeline().HasOutdatedAnimation() ||
- document.Timeline().NeedsAnimationTimingUpdate();
+bool DocumentAnimations::NeedsAnimationTimingUpdate() {
+ for (auto& timeline : timelines_) {
+ if (timeline->HasOutdatedAnimation() ||
+ timeline->NeedsAnimationTimingUpdate())
+ return true;
+ }
+ return false;
}
-void DocumentAnimations::UpdateAnimationTimingIfNeeded(Document& document) {
- if (NeedsAnimationTimingUpdate(document))
- UpdateAnimationTiming(document, kTimingUpdateOnDemand);
+void DocumentAnimations::UpdateAnimationTimingIfNeeded() {
+ if (NeedsAnimationTimingUpdate())
+ UpdateAnimationTiming(*document_, timelines_, kTimingUpdateOnDemand);
}
void DocumentAnimations::UpdateAnimations(
- Document& document,
DocumentLifecycle::LifecycleState required_lifecycle_state,
const PaintArtifactCompositor* paint_artifact_compositor) {
- DCHECK(document.Lifecycle().GetState() >= required_lifecycle_state);
+ DCHECK(document_->Lifecycle().GetState() >= required_lifecycle_state);
- if (document.GetPendingAnimations().Update(paint_artifact_compositor)) {
- DCHECK(document.View());
- document.View()->ScheduleAnimation();
+ if (document_->GetPendingAnimations().Update(paint_artifact_compositor)) {
+ DCHECK(document_->View());
+ document_->View()->ScheduleAnimation();
}
- if (document.View()) {
+ if (document_->View()) {
if (cc::AnimationHost* host =
- document.View()->GetCompositorAnimationHost()) {
+ document_->View()->GetCompositorAnimationHost()) {
wtf_size_t total_animations_count = 0;
- if (document.Timeline().HasAnimations()) {
- total_animations_count = document.Timeline().PendingAnimationsCount();
+ for (auto& timeline : timelines_) {
+ if (timeline->HasAnimations())
+ total_animations_count += timeline->AnimationsNeedingUpdateCount();
}
+
// In the CompositorTimingHistory::DidDraw where we know that there is
// visual update, we will use document.CurrentFrameHadRAF as a signal to
// record UMA or not.
host->SetAnimationCounts(total_animations_count,
- document.CurrentFrameHadRAF(),
- document.NextFrameHasPendingRAF());
+ document_->CurrentFrameHadRAF(),
+ document_->NextFrameHasPendingRAF());
}
}
- document.GetWorkletAnimationController().UpdateAnimationStates();
+ document_->GetWorkletAnimationController().UpdateAnimationStates();
+ for (auto& timeline : timelines_)
+ timeline->ScheduleNextService();
+}
+
+HeapVector<Member<Animation>> DocumentAnimations::getAnimations(
+ const TreeScope& tree_scope) {
+ // This method implements the Document::getAnimations method defined in the
+ // web-animations-1 spec.
+ // https://drafts.csswg.org/web-animations-1/#dom-document-getanimations
+ // TODO(crbug.com/1046916): refactoring work to create a shared implementation
+ // of getAnimations for Documents and ShadowRoots.
+ document_->UpdateStyleAndLayoutTree();
+ HeapVector<Member<Animation>> animations;
+ if (document_->GetPage())
+ animations = document_->GetPage()->Animator().GetAnimations(tree_scope);
+ else
+ GetAnimationsTargetingTreeScope(animations, tree_scope);
+
+ std::sort(animations.begin(), animations.end(), CompareAnimations);
+ return animations;
+}
- document.Timeline().ScheduleNextService();
+void DocumentAnimations::Trace(Visitor* visitor) {
+ visitor->Trace(document_);
+ visitor->Trace(timelines_);
}
+void DocumentAnimations::GetAnimationsTargetingTreeScope(
+ HeapVector<Member<Animation>>& animations,
+ const TreeScope& tree_scope) {
+ // This method follows the timelines in a given docmuent and append all the
+ // animations to the reference animations.
+ for (auto& timeline : timelines_) {
+ for (const auto& animation : timeline->GetAnimations()) {
+ if (animation->ReplaceStateRemoved())
+ continue;
+ if (!animation->effect() || (!animation->effect()->IsCurrent() &&
+ !animation->effect()->IsInEffect())) {
+ continue;
+ }
+ auto* effect = DynamicTo<KeyframeEffect>(animation->effect());
+ Element* target = effect->target();
+ if (!target || !target->isConnected())
+ continue;
+ if (&tree_scope != &target->GetTreeScope())
+ continue;
+ animations.push_back(animation);
+ }
+ }
+}
} // namespace blink
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 18704dd4ee7..2627b129bfb 100644
--- a/chromium/third_party/blink/renderer/core/animation/document_animations.h
+++ b/chromium/third_party/blink/renderer/core/animation/document_animations.h
@@ -31,31 +31,42 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_DOCUMENT_ANIMATIONS_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_DOCUMENT_ANIMATIONS_H_
-#include "base/optional.h"
-#include "third_party/blink/renderer/core/css/css_property_names.h"
+#include "third_party/blink/renderer/core/animation/animation.h"
#include "third_party/blink/renderer/core/dom/document_lifecycle.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "third_party/blink/renderer/platform/heap/member.h"
namespace blink {
+class AnimationTimeline;
class Document;
class PaintArtifactCompositor;
-class DocumentAnimations {
- STATIC_ONLY(DocumentAnimations);
-
+class CORE_EXPORT DocumentAnimations final
+ : public GarbageCollected<DocumentAnimations> {
public:
- static void UpdateAnimationTimingForAnimationFrame(Document&);
- static bool NeedsAnimationTimingUpdate(const Document&);
- static void UpdateAnimationTimingIfNeeded(Document&);
+ DocumentAnimations(Document*);
+ ~DocumentAnimations() = default;
+
+ void AddTimeline(AnimationTimeline&);
+ void UpdateAnimationTimingForAnimationFrame();
+ bool NeedsAnimationTimingUpdate();
+ void UpdateAnimationTimingIfNeeded();
+ void GetAnimationsTargetingTreeScope(HeapVector<Member<Animation>>&,
+ const TreeScope&);
// Updates existing animations as part of generating a new (document
// lifecycle) frame. Note that this considers and updates state for
// both composited and non-composited animations.
- static void UpdateAnimations(
- Document&,
+ void UpdateAnimations(
DocumentLifecycle::LifecycleState required_lifecycle_state,
const PaintArtifactCompositor* paint_artifact_compositor);
+
+ HeapVector<Member<Animation>> getAnimations(const TreeScope&);
+ void Trace(Visitor*);
+
+ private:
+ Member<Document> document_;
+ HeapHashSet<WeakMember<AnimationTimeline>> timelines_;
};
} // namespace blink
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
new file mode 100644
index 00000000000..f0ebf9c3dda
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/animation/document_animations_test.cc
@@ -0,0 +1,142 @@
+// 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/animation/document_animations.h"
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/animation/animation_timeline.h"
+#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
+#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
+#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
+#include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.h"
+
+using ::testing::_;
+using ::testing::Mock;
+using ::testing::Return;
+
+namespace blink {
+
+class MockAnimationTimeline : public AnimationTimeline {
+ public:
+ MockAnimationTimeline(Document* document) : AnimationTimeline(document) {}
+
+ MOCK_CONST_METHOD0(IsActive, bool());
+ MOCK_METHOD0(InitialStartTimeForAnimations,
+ base::Optional<base::TimeDelta>());
+ MOCK_METHOD0(NeedsAnimationTimingUpdate, bool());
+ MOCK_CONST_METHOD0(HasOutdatedAnimation, bool());
+ MOCK_CONST_METHOD0(HasAnimations, bool());
+ MOCK_METHOD1(ServiceAnimations, void(TimingUpdateReason));
+ MOCK_CONST_METHOD0(AnimationsNeedingUpdateCount, wtf_size_t());
+ MOCK_METHOD0(ScheduleNextService, void());
+ MOCK_METHOD0(EnsureCompositorTimeline, CompositorAnimationTimeline*());
+
+ void Trace(Visitor* visitor) override { AnimationTimeline::Trace(visitor); }
+
+ protected:
+ MOCK_METHOD0(CurrentPhaseAndTime, PhaseAndTime());
+};
+
+class DocumentAnimationsTest : public RenderingTest {
+ protected:
+ DocumentAnimationsTest()
+ : RenderingTest(MakeGarbageCollected<SingleChildLocalFrameClient>()) {}
+
+ void SetUp() override {
+ EnableCompositing();
+ RenderingTest::SetUp();
+ helper_.Initialize(nullptr, nullptr, nullptr);
+ document = helper_.LocalMainFrame()->GetFrame()->GetDocument();
+ UpdateAllLifecyclePhasesForTest();
+ }
+
+ void TearDown() override {
+ document.Release();
+ ThreadState::Current()->CollectAllGarbageForTesting();
+ }
+
+ void UpdateAllLifecyclePhasesForTest() {
+ document->View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
+ document->View()->RunPostLifecycleSteps();
+ }
+
+ Persistent<Document> document;
+
+ private:
+ frame_test_helpers::WebViewHelper helper_;
+};
+
+// Test correctness of DocumentAnimations::NeedsAnimationTimingUpdate.
+TEST_F(DocumentAnimationsTest, NeedsAnimationTimingUpdate) {
+ // 1. Test that if all timelines don't require timing update,
+ // DocumentAnimations::NeedsAnimationTimingUpdate returns false.
+ MockAnimationTimeline* timeline1 =
+ MakeGarbageCollected<MockAnimationTimeline>(document);
+ MockAnimationTimeline* timeline2 =
+ MakeGarbageCollected<MockAnimationTimeline>(document);
+
+ EXPECT_CALL(*timeline1, HasOutdatedAnimation()).WillOnce(Return(false));
+ EXPECT_CALL(*timeline1, NeedsAnimationTimingUpdate()).WillOnce(Return(false));
+ EXPECT_CALL(*timeline2, HasOutdatedAnimation()).WillOnce(Return(false));
+ EXPECT_CALL(*timeline2, NeedsAnimationTimingUpdate()).WillOnce(Return(false));
+
+ EXPECT_FALSE(document->GetDocumentAnimations().NeedsAnimationTimingUpdate());
+
+ Mock::VerifyAndClearExpectations(timeline1);
+ Mock::VerifyAndClearExpectations(timeline2);
+
+ // 2. Test that if at least one timeline requires timing update,
+ // DocumentAnimations::NeedsAnimationTimingUpdate returns true.
+ EXPECT_CALL(*timeline2, HasOutdatedAnimation()).WillRepeatedly(Return(false));
+ EXPECT_CALL(*timeline2, NeedsAnimationTimingUpdate())
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(*timeline1, HasOutdatedAnimation()).WillRepeatedly(Return(true));
+ EXPECT_CALL(*timeline1, NeedsAnimationTimingUpdate())
+ .WillRepeatedly(Return(false));
+
+ EXPECT_TRUE(document->GetDocumentAnimations().NeedsAnimationTimingUpdate());
+}
+
+// Test correctness of
+// DocumentAnimations::UpdateAnimationTimingForAnimationFrame.
+TEST_F(DocumentAnimationsTest, UpdateAnimationTimingServicesAllTimelines) {
+ // Test that all timelines are traversed to perform timing update.
+ MockAnimationTimeline* timeline1 =
+ MakeGarbageCollected<MockAnimationTimeline>(document);
+ MockAnimationTimeline* timeline2 =
+ MakeGarbageCollected<MockAnimationTimeline>(document);
+
+ EXPECT_CALL(*timeline1, ServiceAnimations(_));
+ EXPECT_CALL(*timeline2, ServiceAnimations(_));
+
+ document->GetDocumentAnimations().UpdateAnimationTimingForAnimationFrame();
+}
+
+// Test correctness of DocumentAnimations::UpdateAnimations.
+TEST_F(DocumentAnimationsTest, UpdateAnimationsUpdatesAllTimelines) {
+ // Test that all timelines are traversed to schedule next service.
+ MockAnimationTimeline* timeline1 =
+ MakeGarbageCollected<MockAnimationTimeline>(document);
+ MockAnimationTimeline* timeline2 =
+ MakeGarbageCollected<MockAnimationTimeline>(document);
+
+ UpdateAllLifecyclePhasesForTest();
+
+ EXPECT_CALL(*timeline1, HasAnimations()).WillOnce(Return(true));
+ EXPECT_CALL(*timeline2, HasAnimations()).WillOnce(Return(true));
+ EXPECT_CALL(*timeline1, AnimationsNeedingUpdateCount()).WillOnce(Return(3));
+ EXPECT_CALL(*timeline2, AnimationsNeedingUpdateCount()).WillOnce(Return(2));
+ EXPECT_CALL(*timeline1, ScheduleNextService());
+ EXPECT_CALL(*timeline2, ScheduleNextService());
+
+ document->GetDocumentAnimations().UpdateAnimations(
+ DocumentLifecycle::kPaintClean, nullptr);
+
+ // Verify that animations count is correctly updated on animation host.
+ cc::AnimationHost* host = document->View()->GetCompositorAnimationHost();
+ EXPECT_EQ(5u, host->MainThreadAnimationsCount());
+}
+
+} // namespace blink
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 e3747c68043..63dd9e7451f 100644
--- a/chromium/third_party/blink/renderer/core/animation/document_timeline.cc
+++ b/chromium/third_party/blink/renderer/core/animation/document_timeline.cc
@@ -29,30 +29,18 @@
*/
#include "third_party/blink/renderer/core/animation/document_timeline.h"
-
-#include <algorithm>
#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_document_timeline_options.h"
#include "third_party/blink/renderer/core/animation/animation.h"
#include "third_party/blink/renderer/core/animation/animation_clock.h"
#include "third_party/blink/renderer/core/animation/animation_effect.h"
-#include "third_party/blink/renderer/core/animation/document_timeline_options.h"
-#include "third_party/blink/renderer/core/animation/element_animations.h"
-#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/loader/document_loader.h"
-#include "third_party/blink/renderer/core/page/page.h"
-#include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
namespace blink {
namespace {
-bool CompareAnimations(const Member<Animation>& left,
- const Member<Animation>& right) {
- return Animation::HasLowerPriority(left.Get(), right.Get());
-}
-
// Returns the current animation time for a given |document|. This is
// the animation clock time capped to be at least this document's
// ZeroTime() such that the animation time is never negative when converted.
@@ -78,7 +66,7 @@ const double DocumentTimeline::kMinimumDelay = 0.04;
DocumentTimeline* DocumentTimeline::Create(
ExecutionContext* execution_context,
const DocumentTimelineOptions* options) {
- Document* document = To<Document>(execution_context);
+ Document* document = Document::From(execution_context);
return MakeGarbageCollected<DocumentTimeline>(
document, base::TimeDelta::FromMillisecondsD(options->originTime()),
nullptr);
@@ -87,19 +75,17 @@ DocumentTimeline* DocumentTimeline::Create(
DocumentTimeline::DocumentTimeline(Document* document,
base::TimeDelta origin_time,
PlatformTiming* timing)
- : document_(document),
+ : AnimationTimeline(document),
origin_time_(origin_time),
zero_time_(base::TimeTicks() + origin_time_),
zero_time_initialized_(false),
- outdated_animation_count_(0),
playback_rate_(1) {
if (!timing)
timing_ = MakeGarbageCollected<DocumentTimelineTiming>(this);
else
timing_ = timing;
-
if (Platform::Current()->IsThreadedAnimationEnabled())
- compositor_timeline_ = std::make_unique<CompositorAnimationTimeline>();
+ EnsureCompositorTimeline();
DCHECK(document);
}
@@ -119,12 +105,6 @@ DocumentTimeline::InitialStartTimeForAnimations() {
return base::nullopt;
}
-void DocumentTimeline::AnimationAttached(Animation* animation) {
- DCHECK_EQ(&animation->GetDocument()->Timeline(), this);
- DCHECK(!animations_.Contains(animation));
- animations_.insert(animation);
-}
-
Animation* DocumentTimeline::Play(AnimationEffect* child) {
Animation* animation = Animation::Create(child, this);
DCHECK(animations_.Contains(animation));
@@ -135,63 +115,6 @@ Animation* DocumentTimeline::Play(AnimationEffect* child) {
return animation;
}
-HeapVector<Member<Animation>> DocumentTimeline::getAnimations() {
- // This method implements the Document::getAnimations method defined in the
- // web-animations-1 spec.
- // https://drafts.csswg.org/web-animations-1/#dom-document-getanimations
- document_->UpdateStyleAndLayoutTree();
- HeapVector<Member<Animation>> animations;
- for (const auto& animation : animations_) {
- if (!animation->effect() || (!animation->effect()->IsCurrent() &&
- !animation->effect()->IsInEffect())) {
- continue;
- }
- if (animation->effect()->IsKeyframeEffect()) {
- Element* target = ToKeyframeEffect(animation->effect())->target();
- if (!target || !target->isConnected() ||
- document_ != target->GetDocument()) {
- continue;
- }
- }
- animations.push_back(animation);
- }
- std::sort(animations.begin(), animations.end(), CompareAnimations);
- return animations;
-}
-
-void DocumentTimeline::Wake() {
- timing_->ServiceOnNextFrame();
-}
-
-void DocumentTimeline::ServiceAnimations(TimingUpdateReason reason) {
- TRACE_EVENT0("blink", "DocumentTimeline::serviceAnimations");
-
- last_current_time_internal_ = CurrentTimeInternal();
-
- HeapVector<Member<Animation>> animations;
- animations.ReserveInitialCapacity(animations_needing_update_.size());
- for (Animation* animation : animations_needing_update_)
- animations.push_back(animation);
-
- std::sort(animations.begin(), animations.end(), Animation::HasLowerPriority);
-
- for (Animation* animation : animations) {
- if (!animation->Update(reason))
- animations_needing_update_.erase(animation);
- }
-
- DCHECK_EQ(outdated_animation_count_, 0U);
- DCHECK(last_current_time_internal_ == CurrentTimeInternal());
-
-#if DCHECK_IS_ON()
- for (const auto& animation : animations_needing_update_)
- DCHECK(!animation->Outdated());
-#endif
- // Explicitly free the backing store to avoid memory regressions.
- // TODO(bikineev): Revisit when young generation is done.
- animations.clear();
-}
-
void DocumentTimeline::ScheduleNextService() {
DCHECK_EQ(outdated_animation_count_, 0U);
@@ -212,7 +135,7 @@ void DocumentTimeline::ScheduleNextService() {
return;
double next_effect_delay = time_to_next_effect.value().InSecondsF();
if (next_effect_delay < kMinimumDelay) {
- timing_->ServiceOnNextFrame();
+ ScheduleServiceOnNextFrame();
} else {
timing_->WakeAfter(
base::TimeDelta::FromSecondsD(next_effect_delay - kMinimumDelay));
@@ -226,12 +149,7 @@ void DocumentTimeline::DocumentTimelineTiming::WakeAfter(
timer_.StartOneShot(duration, FROM_HERE);
}
-void DocumentTimeline::DocumentTimelineTiming::ServiceOnNextFrame() {
- if (timeline_->document_->View())
- timeline_->document_->View()->ScheduleAnimation();
-}
-
-void DocumentTimeline::DocumentTimelineTiming::Trace(blink::Visitor* visitor) {
+void DocumentTimeline::DocumentTimelineTiming::Trace(Visitor* visitor) {
visitor->Trace(timeline_);
DocumentTimeline::PlatformTiming::Trace(visitor);
}
@@ -249,41 +167,23 @@ void DocumentTimeline::ResetForTesting() {
zero_time_ = base::TimeTicks() + origin_time_;
zero_time_initialized_ = true;
playback_rate_ = 1;
- last_current_time_internal_.reset();
+ last_current_phase_and_time_.reset();
}
void DocumentTimeline::SetTimingForTesting(PlatformTiming* timing) {
timing_ = timing;
}
-double DocumentTimeline::currentTime(bool& is_null) {
- base::Optional<base::TimeDelta> result = CurrentTimeInternal();
-
- is_null = !result.has_value();
- return result.has_value() ? result->InMillisecondsF()
- : std::numeric_limits<double>::quiet_NaN();
-}
-
-base::Optional<base::TimeDelta> DocumentTimeline::CurrentTimeInternal() {
+AnimationTimeline::PhaseAndTime DocumentTimeline::CurrentPhaseAndTime() {
if (!IsActive()) {
- return base::nullopt;
+ return {TimelinePhase::kInactive, /*current_time*/ base::nullopt};
}
base::Optional<base::TimeDelta> result =
playback_rate_ == 0
? ZeroTime().since_origin()
: (CurrentAnimationTime(GetDocument()) - ZeroTime()) * playback_rate_;
- return result;
-}
-
-double DocumentTimeline::currentTime() {
- base::Optional<base::TimeDelta> result = CurrentTimeInternal();
- return result.has_value() ? result->InMillisecondsF()
- : std::numeric_limits<double>::quiet_NaN();
-}
-
-double DocumentTimeline::EffectiveTime() {
- return CurrentTimeInternal().value_or(base::TimeDelta()).InSecondsF();
+ return {TimelinePhase::kActive, result};
}
void DocumentTimeline::PauseAnimationsForTesting(double pause_time) {
@@ -292,36 +192,10 @@ void DocumentTimeline::PauseAnimationsForTesting(double pause_time) {
ServiceAnimations(kTimingUpdateOnDemand);
}
-bool DocumentTimeline::NeedsAnimationTimingUpdate() {
- if (CurrentTimeInternal() == last_current_time_internal_)
- return false;
-
- // We allow |last_current_time_internal_| to advance here when there
- // are no animations to allow animations spawned during style
- // recalc to not invalidate this flag.
- if (animations_needing_update_.IsEmpty())
- last_current_time_internal_ = CurrentTimeInternal();
-
- return !animations_needing_update_.IsEmpty();
-}
-
-void DocumentTimeline::ClearOutdatedAnimation(Animation* animation) {
- DCHECK(!animation->Outdated());
- outdated_animation_count_--;
-}
-
-void DocumentTimeline::SetOutdatedAnimation(Animation* animation) {
- DCHECK(animation->Outdated());
- outdated_animation_count_++;
- animations_needing_update_.insert(animation);
- if (IsActive() && !document_->GetPage()->Animator().IsServicingAnimations())
- timing_->ServiceOnNextFrame();
-}
-
void DocumentTimeline::SetPlaybackRate(double playback_rate) {
if (!IsActive())
return;
- base::TimeDelta current_time = CurrentTimeInternal().value();
+ base::TimeDelta current_time = CurrentPhaseAndTime().time.value();
playback_rate_ = playback_rate;
zero_time_ = playback_rate == 0 ? base::TimeTicks() + current_time
: CurrentAnimationTime(GetDocument()) -
@@ -348,11 +222,16 @@ void DocumentTimeline::InvalidateKeyframeEffects(const TreeScope& tree_scope) {
animation->InvalidateKeyframeEffect(tree_scope);
}
-void DocumentTimeline::Trace(blink::Visitor* visitor) {
- visitor->Trace(document_);
+CompositorAnimationTimeline* DocumentTimeline::EnsureCompositorTimeline() {
+ if (compositor_timeline_)
+ return compositor_timeline_.get();
+
+ compositor_timeline_ = std::make_unique<CompositorAnimationTimeline>();
+ return compositor_timeline_.get();
+}
+
+void DocumentTimeline::Trace(Visitor* visitor) {
visitor->Trace(timing_);
- visitor->Trace(animations_needing_update_);
- visitor->Trace(animations_);
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 2a3354026a5..2aa7eef4917 100644
--- a/chromium/third_party/blink/renderer/core/animation/document_timeline.h
+++ b/chromium/third_party/blink/renderer/core/animation/document_timeline.h
@@ -34,23 +34,14 @@
#include <memory>
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/public/platform/task_type.h"
-#include "third_party/blink/renderer/core/animation/animation_effect.h"
#include "third_party/blink/renderer/core/animation/animation_timeline.h"
-#include "third_party/blink/renderer/core/animation/effect_model.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/element.h"
-#include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.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/timer.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
class Animation;
class AnimationEffect;
-class Document;
class DocumentTimelineOptions;
// DocumentTimeline is constructed and owned by Document, and tied to its
@@ -63,9 +54,8 @@ class CORE_EXPORT DocumentTimeline : public AnimationTimeline {
public:
// Calls DocumentTimeline's wake() method after duration seconds.
virtual void WakeAfter(base::TimeDelta duration) = 0;
- virtual void ServiceOnNextFrame() = 0;
virtual ~PlatformTiming() = default;
- virtual void Trace(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
};
// Web Animations API IDL constructor
@@ -79,56 +69,36 @@ class CORE_EXPORT DocumentTimeline : public AnimationTimeline {
bool IsDocumentTimeline() const final { return true; }
- void ServiceAnimations(TimingUpdateReason);
- void ScheduleNextService();
+ void ScheduleNextService() override;
Animation* Play(AnimationEffect*);
- HeapVector<Member<Animation>> getAnimations();
-
- void AnimationAttached(Animation*) override;
- // animations_ is a map of weak members so there is no need to explicitly
- // clean it up.
- void AnimationDetached(Animation*) override {}
bool IsActive() const override;
base::Optional<base::TimeDelta> InitialStartTimeForAnimations() override;
bool HasPendingUpdates() const {
return !animations_needing_update_.IsEmpty();
}
- wtf_size_t PendingAnimationsCount() const {
- return animations_needing_update_.size();
- }
+
base::TimeTicks ZeroTime();
- double currentTime(bool& is_null) override;
- double currentTime();
- base::Optional<base::TimeDelta> CurrentTimeInternal();
- double EffectiveTime();
void PauseAnimationsForTesting(double);
void SetAllCompositorPending(bool source_changed = false);
- void SetOutdatedAnimation(Animation*);
- void ClearOutdatedAnimation(Animation*);
- bool HasOutdatedAnimation() const { return outdated_animation_count_ > 0; }
- bool NeedsAnimationTimingUpdate();
void InvalidateKeyframeEffects(const TreeScope&);
void SetPlaybackRate(double);
double PlaybackRate() const;
- CompositorAnimationTimeline* CompositorTimeline() const {
- return compositor_timeline_.get();
- }
-
- Document* GetDocument() override { return document_.Get(); }
- void Wake();
void ResetForTesting();
void SetTimingForTesting(PlatformTiming* timing);
- bool HasAnimations() { return !animations_.IsEmpty(); }
- void Trace(blink::Visitor*) override;
+ CompositorAnimationTimeline* EnsureCompositorTimeline() override;
+
+ void Trace(Visitor*) override;
+
+ protected:
+ PhaseAndTime CurrentPhaseAndTime() override;
private:
- Member<Document> document_;
// Origin time for the timeline relative to the time origin of the document.
// Provided when the timeline is constructed. See
// https://drafts.csswg.org/web-animations/#dom-documenttimelineoptions-origintime.
@@ -137,11 +107,6 @@ class CORE_EXPORT DocumentTimeline : public AnimationTimeline {
// origin of the document.
base::TimeTicks zero_time_;
bool zero_time_initialized_;
- unsigned outdated_animation_count_;
- // Animations which will be updated on the next frame
- // i.e. current, in effect, or had timing changed
- HeapHashSet<Member<Animation>> animations_needing_update_;
- HeapHashSet<WeakMember<Animation>> animations_;
double playback_rate_;
@@ -149,9 +114,6 @@ class CORE_EXPORT DocumentTimeline : public AnimationTimeline {
static const double kMinimumDelay;
Member<PlatformTiming> timing_;
- base::Optional<base::TimeDelta> last_current_time_internal_;
-
- std::unique_ptr<CompositorAnimationTimeline> compositor_timeline_;
class DocumentTimelineTiming final : public PlatformTiming {
public:
@@ -165,11 +127,10 @@ class CORE_EXPORT DocumentTimeline : public AnimationTimeline {
}
void WakeAfter(base::TimeDelta duration) override;
- void ServiceOnNextFrame() override;
- void TimerFired(TimerBase*) { timeline_->Wake(); }
+ void TimerFired(TimerBase*) { timeline_->ScheduleServiceOnNextFrame(); }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<DocumentTimeline> timeline_;
@@ -179,11 +140,12 @@ class CORE_EXPORT DocumentTimeline : public AnimationTimeline {
friend class AnimationDocumentTimelineTest;
};
-DEFINE_TYPE_CASTS(DocumentTimeline,
- AnimationTimeline,
- timeline,
- timeline->IsDocumentTimeline(),
- timeline.IsDocumentTimeline());
+template <>
+struct DowncastTraits<DocumentTimeline> {
+ static bool AllowFrom(const AnimationTimeline& timeline) {
+ return timeline.IsDocumentTimeline();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/document_timeline.idl b/chromium/third_party/blink/renderer/core/animation/document_timeline.idl
index 4244b5a8e16..54c03af3913 100644
--- a/chromium/third_party/blink/renderer/core/animation/document_timeline.idl
+++ b/chromium/third_party/blink/renderer/core/animation/document_timeline.idl
@@ -5,9 +5,8 @@
// https://drafts.csswg.org/web-animations/#the-documenttimeline-interface
[
- Constructor(optional DocumentTimelineOptions options),
- ConstructorCallWith=ExecutionContext,
RuntimeEnabled=WebAnimationsAPI,
Exposed=Window
] interface DocumentTimeline : AnimationTimeline {
+ [CallWith=ExecutionContext] constructor(optional DocumentTimelineOptions options = {});
};
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 602ff26fc60..d759e6e921f 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
@@ -42,6 +42,7 @@
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/qualified_name.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
+#include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -59,13 +60,33 @@ namespace blink {
class MockPlatformTiming : public DocumentTimeline::PlatformTiming {
public:
MOCK_METHOD1(WakeAfter, void(base::TimeDelta));
- MOCK_METHOD0(ServiceOnNextFrame, void());
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
DocumentTimeline::PlatformTiming::Trace(visitor);
}
};
+class TestDocumentTimeline : public DocumentTimeline {
+ public:
+ TestDocumentTimeline(Document* document)
+ : DocumentTimeline(document, base::TimeDelta(), nullptr),
+ schedule_next_service_called_(false) {}
+ void ScheduleServiceOnNextFrame() override {
+ DocumentTimeline::ScheduleServiceOnNextFrame();
+ schedule_next_service_called_ = true;
+ }
+ void Trace(Visitor* visitor) override { DocumentTimeline::Trace(visitor); }
+ bool ScheduleNextServiceCalled() const {
+ return schedule_next_service_called_;
+ }
+ void ResetScheduleNextServiceCalled() {
+ schedule_next_service_called_ = false;
+ }
+
+ private:
+ bool schedule_next_service_called_;
+};
+
class AnimationDocumentTimelineTest : public PageTestBase {
protected:
void SetUp() override {
@@ -75,8 +96,9 @@ class AnimationDocumentTimelineTest : public PageTestBase {
GetAnimationClock().SetAllowedToDynamicallyUpdateTime(false);
element =
MakeGarbageCollected<Element>(QualifiedName::Null(), document.Get());
+ document->Timeline().ResetForTesting();
platform_timing = MakeGarbageCollected<MockPlatformTiming>();
- timeline = document->Timeline();
+ timeline = MakeGarbageCollected<TestDocumentTimeline>(document);
timeline->SetTimingForTesting(platform_timing);
timeline->ResetForTesting();
@@ -104,12 +126,10 @@ class AnimationDocumentTimelineTest : public PageTestBase {
Persistent<Document> document;
Persistent<Element> element;
- Persistent<DocumentTimeline> timeline;
+ Persistent<TestDocumentTimeline> timeline;
Timing timing;
Persistent<MockPlatformTiming> platform_timing;
- void Wake() { timeline->Wake(); }
-
double MinimumDelay() { return DocumentTimeline::kMinimumDelay; }
};
@@ -173,18 +193,16 @@ TEST_F(AnimationDocumentTimelineTest, ZeroTime) {
EXPECT_EQ(2000, timeline->currentTime());
}
-// EffectiveTime is identical to currentTime/1000 except that it returns 0
-// when the timeline is inactive.
-TEST_F(AnimationDocumentTimelineTest, EffectiveTime) {
+TEST_F(AnimationDocumentTimelineTest, CurrentTimeSeconds) {
GetAnimationClock().UpdateTime(TimeTicksFromMillisecondsD(2000));
- EXPECT_EQ(2, timeline->EffectiveTime());
+ EXPECT_EQ(2, timeline->CurrentTimeSeconds().value());
EXPECT_EQ(2000, timeline->currentTime());
auto* document_without_frame = MakeGarbageCollected<Document>();
auto* inactive_timeline = MakeGarbageCollected<DocumentTimeline>(
document_without_frame, base::TimeDelta(), platform_timing);
- EXPECT_EQ(0, inactive_timeline->EffectiveTime());
+ EXPECT_FALSE(inactive_timeline->CurrentTimeSeconds());
EXPECT_NAN(inactive_timeline->currentTime());
bool is_null = false;
inactive_timeline->currentTime(is_null);
@@ -207,8 +225,8 @@ TEST_F(AnimationDocumentTimelineTest, PlaybackRateNormal) {
TEST_F(AnimationDocumentTimelineTest, PlaybackRateNormalWithOriginTime) {
base::TimeDelta origin_time = base::TimeDelta::FromMilliseconds(-1000);
- timeline = MakeGarbageCollected<DocumentTimeline>(document.Get(), origin_time,
- platform_timing);
+ DocumentTimeline* timeline = MakeGarbageCollected<DocumentTimeline>(
+ document.Get(), origin_time, platform_timing);
timeline->ResetForTesting();
EXPECT_EQ(1.0, timeline->PlaybackRate());
@@ -244,8 +262,8 @@ TEST_F(AnimationDocumentTimelineTest, PlaybackRatePause) {
TEST_F(AnimationDocumentTimelineTest, PlaybackRatePauseWithOriginTime) {
base::TimeDelta origin_time = base::TimeDelta::FromMilliseconds(-1000);
- timeline = MakeGarbageCollected<DocumentTimeline>(document.Get(), origin_time,
- platform_timing);
+ DocumentTimeline* timeline = MakeGarbageCollected<DocumentTimeline>(
+ document.Get(), origin_time, platform_timing);
timeline->ResetForTesting();
EXPECT_EQ(base::TimeTicks() + origin_time, timeline->ZeroTime());
@@ -307,7 +325,7 @@ TEST_F(AnimationDocumentTimelineTest, PlaybackRateFast) {
}
TEST_F(AnimationDocumentTimelineTest, PlaybackRateFastWithOriginTime) {
- timeline = MakeGarbageCollected<DocumentTimeline>(
+ DocumentTimeline* timeline = MakeGarbageCollected<DocumentTimeline>(
document.Get(), base::TimeDelta::FromSeconds(-1000), platform_timing);
timeline->ResetForTesting();
@@ -369,11 +387,11 @@ TEST_F(AnimationDocumentTimelineTest, DelayBeforeAnimationStart) {
MinimumDelay() - 1.5)));
UpdateClockAndService(1500);
- EXPECT_CALL(*platform_timing, ServiceOnNextFrame());
- Wake();
+ timeline->ScheduleServiceOnNextFrame();
- EXPECT_CALL(*platform_timing, ServiceOnNextFrame());
+ timeline->ResetScheduleNextServiceCalled();
UpdateClockAndService(4980);
+ EXPECT_TRUE(timeline->ScheduleNextServiceCalled());
}
TEST_F(AnimationDocumentTimelineTest, UseAnimationAfterTimelineDeref) {
@@ -387,7 +405,7 @@ TEST_F(AnimationDocumentTimelineTest, PlayAfterDocumentDeref) {
timing.iteration_duration = AnimationTimeDelta::FromSecondsD(2);
timing.start_delay = 5;
- timeline = &document->Timeline();
+ DocumentTimeline* timeline = &document->Timeline();
document = nullptr;
auto* keyframe_effect = MakeGarbageCollected<KeyframeEffect>(
@@ -439,7 +457,7 @@ TEST_F(AnimationDocumentTimelineRealTimeTest,
document->Loader()->GetTiming().ReferenceMonotonicTime().is_null());
base::TimeDelta origin_time = base::TimeDelta::FromSeconds(1000);
- timeline =
+ DocumentTimeline* timeline =
MakeGarbageCollected<DocumentTimeline>(document.Get(), origin_time);
timeline->SetPlaybackRate(0.5);
EXPECT_EQ(origin_time * 2,
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 990c2cfe536..27d54a63e4f 100644
--- a/chromium/third_party/blink/renderer/core/animation/effect_input.cc
+++ b/chromium/third_party/blink/renderer/core/animation/effect_input.cc
@@ -39,8 +39,6 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_base_keyframe.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_base_property_indexed_keyframe.h"
#include "third_party/blink/renderer/core/animation/animation_input_helpers.h"
-#include "third_party/blink/renderer/core/animation/base_keyframe.h"
-#include "third_party/blink/renderer/core/animation/base_property_indexed_keyframe.h"
#include "third_party/blink/renderer/core/animation/compositor_animations.h"
#include "third_party/blink/renderer/core/animation/css/css_animations.h"
#include "third_party/blink/renderer/core/animation/keyframe_effect_model.h"
@@ -49,6 +47,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/frame/frame_console.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/inspector/console_message.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
@@ -102,10 +101,12 @@ void SetKeyframeValue(Element* element,
style_sheet_contents);
if (!set_result.did_parse && execution_context) {
if (document.GetFrame()) {
- document.GetFrame()->Console().AddMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning,
- "Invalid keyframe value for property " + property + ": " + value));
+ document.GetFrame()->Console().AddMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning,
+ "Invalid keyframe value for property " + property + ": " +
+ value));
}
}
return;
@@ -126,9 +127,9 @@ void SetKeyframeValue(Element* element,
}
bool ValidatePartialKeyframes(const StringKeyframeVector& keyframes) {
- // CSSAdditiveAnimationsEnabled guards both additive animations and allowing
+ // WebAnimationsAPIEnabled guards both additive animations and allowing
// partial (implicit) keyframes.
- if (RuntimeEnabledFeatures::CSSAdditiveAnimationsEnabled())
+ if (RuntimeEnabledFeatures::WebAnimationsAPIEnabled())
return true;
// An implicit keyframe is inserted in the below cases. Note that the 'first'
@@ -182,7 +183,7 @@ EffectModel::CompositeOperation ResolveCompositeOperationForKeyframe(
StringKeyframe* keyframe) {
bool additive_composite = composite == EffectModel::kCompositeAdd ||
composite == EffectModel::kCompositeAccumulate;
- if (!RuntimeEnabledFeatures::CSSAdditiveAnimationsEnabled() &&
+ if (!RuntimeEnabledFeatures::WebAnimationsAPIEnabled() &&
keyframe->HasCssProperty() && additive_composite) {
return EffectModel::kCompositeReplace;
}
@@ -669,7 +670,7 @@ KeyframeEffectModelBase* EffectInput::Convert(
auto* keyframe_effect_model = MakeGarbageCollected<StringKeyframeEffectModel>(
parsed_keyframes, composite, LinearTimingFunction::Shared());
- if (!RuntimeEnabledFeatures::CSSAdditiveAnimationsEnabled()) {
+ if (!RuntimeEnabledFeatures::WebAnimationsAPIEnabled()) {
// This should be enforced by the parsing code.
DCHECK(!HasAdditiveCompositeCSSKeyframe(
keyframe_effect_model->GetPropertySpecificKeyframeGroups()));
@@ -698,9 +699,9 @@ StringKeyframeVector EffectInput::ParseKeyframesArgument(
return {};
// TODO(crbug.com/816934): Get spec to specify what parsing context to use.
- Document& document =
- element ? element->GetDocument()
- : *To<Document>(ExecutionContext::From(script_state));
+ Document& document = element
+ ? element->GetDocument()
+ : *LocalDOMWindow::From(script_state)->document();
StringKeyframeVector parsed_keyframes;
if (script_iterator.IsNull()) {
diff --git a/chromium/third_party/blink/renderer/core/animation/effect_model.cc b/chromium/third_party/blink/renderer/core/animation/effect_model.cc
index 4504d18f645..a876304d633 100644
--- a/chromium/third_party/blink/renderer/core/animation/effect_model.cc
+++ b/chromium/third_party/blink/renderer/core/animation/effect_model.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/core/animation/effect_model.h"
-#include "third_party/blink/renderer/core/animation/keyframe_effect_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_keyframe_effect_options.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
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 5b6941783b1..7b39d2cc016 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(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
};
} // 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 27f9f233e9f..38a142175c6 100644
--- a/chromium/third_party/blink/renderer/core/animation/effect_stack.cc
+++ b/chromium/third_party/blink/renderer/core/animation/effect_stack.cc
@@ -59,22 +59,18 @@ void CopyToActiveInterpolationsMap(
// effect erases everything that came before it, so we must clear the stack
// when that happens.
const bool allow_stacked_effects =
- RuntimeEnabledFeatures::StackedCSSPropertyAnimationsEnabled() ||
+ RuntimeEnabledFeatures::WebAnimationsAPIEnabled() ||
!property.IsCSSProperty() || property.IsPresentationAttribute();
const bool effect_depends_on_underlying_value =
interpolation->IsInvalidatableInterpolation() &&
- ToInvalidatableInterpolation(*interpolation).DependsOnUnderlyingValue();
+ To<InvalidatableInterpolation>(*interpolation.Get())
+ .DependsOnUnderlyingValue();
if (!allow_stacked_effects || !effect_depends_on_underlying_value)
active_interpolations.clear();
active_interpolations.push_back(interpolation);
}
}
-bool CompareSampledEffects(const Member<SampledEffect>& sampled_effect1,
- const Member<SampledEffect>& sampled_effect2) {
- DCHECK(sampled_effect1 && sampled_effect2);
- return sampled_effect1->SequenceNumber() < sampled_effect2->SequenceNumber();
-}
void CopyNewAnimationsToActiveInterpolationsMap(
const HeapVector<Member<const InertEffect>>& new_animations,
@@ -90,6 +86,21 @@ void CopyNewAnimationsToActiveInterpolationsMap(
} // namespace
+bool EffectStack::CompareSampledEffects(
+ const Member<SampledEffect>& sampled_effect1,
+ const Member<SampledEffect>& sampled_effect2) {
+ if (sampled_effect1->Effect() && sampled_effect2->Effect()) {
+ Animation* animation1 = sampled_effect1->Effect()->GetAnimation();
+ Animation* animation2 = sampled_effect2->Effect()->GetAnimation();
+ if (animation1 && animation2) {
+ return Animation::HasLowerCompositeOrdering(
+ animation1, animation2,
+ Animation::CompareAnimationsOrdering::kPointerOrder);
+ }
+ }
+ return sampled_effect1->SequenceNumber() < sampled_effect2->SequenceNumber();
+}
+
EffectStack::EffectStack() = default;
bool EffectStack::HasActiveAnimationsOnCompositor(
@@ -118,16 +129,24 @@ ActiveInterpolationsMap EffectStack::ActiveInterpolations(
const HeapVector<Member<const InertEffect>>* new_animations,
const HeapHashSet<Member<const Animation>>* suppressed_animations,
KeyframeEffect::Priority priority,
- PropertyHandleFilter property_handle_filter) {
+ PropertyHandleFilter property_handle_filter,
+ KeyframeEffect* partial_effect_stack_cutoff) {
ActiveInterpolationsMap result;
if (effect_stack) {
HeapVector<Member<SampledEffect>>& sampled_effects =
effect_stack->sampled_effects_;
+ effect_stack->RemoveRedundantSampledEffects();
std::sort(sampled_effects.begin(), sampled_effects.end(),
CompareSampledEffects);
- effect_stack->RemoveRedundantSampledEffects();
+ bool reached_cuttoff = false;
for (const auto& sampled_effect : sampled_effects) {
+ if (reached_cuttoff)
+ break;
+ if (partial_effect_stack_cutoff &&
+ sampled_effect->Effect() == partial_effect_stack_cutoff)
+ reached_cuttoff = true;
+
if (sampled_effect->GetPriority() != priority ||
// TODO(majidvp): Instead of accessing the effect's animation move the
// check inside KeyframeEffect. http://crbug.com/812410
@@ -167,7 +186,7 @@ void EffectStack::RemoveRedundantSampledEffects() {
sampled_effects_.Shrink(new_size);
}
-void EffectStack::Trace(blink::Visitor* visitor) {
+void EffectStack::Trace(Visitor* visitor) {
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 b101ce520fd..416ab8ad404 100644
--- a/chromium/third_party/blink/renderer/core/animation/effect_stack.h
+++ b/chromium/third_party/blink/renderer/core/animation/effect_stack.h
@@ -57,19 +57,34 @@ class CORE_EXPORT EffectStack {
void Add(SampledEffect* sampled_effect) {
sampled_effects_.push_back(sampled_effect);
}
+ static bool CompareSampledEffects(const Member<SampledEffect>&,
+ const Member<SampledEffect>&);
bool IsEmpty() const { return sampled_effects_.IsEmpty(); }
bool HasActiveAnimationsOnCompositor(const PropertyHandle&) const;
using PropertyHandleFilter = bool (*)(const PropertyHandle&);
bool AffectsProperties(PropertyHandleFilter) const;
+
+ // Produces a map of properties to active effects.
+ // |effect_stack| contains the sequence of sample effects for an element.
+ // |new_animations| is an optional list of animations to be explicitly added
+ // to the active animations map.
+ // |suppressed_animations| is an optional list of animations to ignore.
+ // |priority| is for matching the effect priority and may be kDefaultPriority
+ // or kTransitionPriority.
+ // |property_handle_filter| is an optional filter for determining which
+ // properties to include in the interpolations map.
+ // |partial_effect_stack_cutoff| is an optional cutoff point, used to create
+ // a partial effect stack.
static ActiveInterpolationsMap ActiveInterpolations(
- EffectStack*,
+ EffectStack* effect_stack,
const HeapVector<Member<const InertEffect>>* new_animations,
const HeapHashSet<Member<const Animation>>* suppressed_animations,
- KeyframeEffect::Priority,
- PropertyHandleFilter = nullptr);
+ KeyframeEffect::Priority priority,
+ PropertyHandleFilter property_handle_filter = nullptr,
+ KeyframeEffect* partial_effect_stack_cutoff = nullptr);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
void RemoveRedundantSampledEffects();
diff --git a/chromium/third_party/blink/renderer/core/animation/effect_stack_test.cc b/chromium/third_party/blink/renderer/core/animation/effect_stack_test.cc
index ef4d234f2b1..4f4a13bc386 100644
--- a/chromium/third_party/blink/renderer/core/animation/effect_stack_test.cc
+++ b/chromium/third_party/blink/renderer/core/animation/effect_stack_test.cc
@@ -82,8 +82,8 @@ class AnimationEffectStackTest : public PageTestBase {
active_interpolations.at(PropertyHandle(GetCSSPropertyFontSize()));
EnsureInterpolatedValueCached(interpolations, GetDocument(), element);
- const TypedInterpolationValue* typed_value =
- ToInvalidatableInterpolation(*interpolations.at(0))
+ const auto* typed_value =
+ To<InvalidatableInterpolation>(*interpolations.at(0))
.GetCachedValueForTesting();
// font-size is stored as an |InterpolableLength|; here we assume pixels.
EXPECT_TRUE(typed_value->GetInterpolableValue().IsLength());
@@ -97,12 +97,13 @@ class AnimationEffectStackTest : public PageTestBase {
active_interpolations.at(PropertyHandle(GetCSSPropertyZIndex()));
EnsureInterpolatedValueCached(interpolations, GetDocument(), element);
- const TypedInterpolationValue* typed_value =
- ToInvalidatableInterpolation(*interpolations.at(0))
+ const auto* typed_value =
+ To<InvalidatableInterpolation>(*interpolations.at(0))
.GetCachedValueForTesting();
// z-index is stored as a straight number value.
EXPECT_TRUE(typed_value->GetInterpolableValue().IsNumber());
- return ToInterpolableNumber(&typed_value->GetInterpolableValue())->Value();
+ return To<InterpolableNumber>(&typed_value->GetInterpolableValue())
+ ->Value();
}
Persistent<DocumentTimeline> timeline;
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 375a6d86458..57d14159850 100644
--- a/chromium/third_party/blink/renderer/core/animation/element_animations.cc
+++ b/chromium/third_party/blink/renderer/core/animation/element_animations.cc
@@ -53,29 +53,6 @@ void UpdateAnimationFlagsForEffect(const KeyframeEffect& effect,
style.SetHasCurrentBackdropFilterAnimation(true);
}
-#if DCHECK_IS_ON()
-// Under certain conditions ComputedStyle::operator==() may return false for
-// differences that are permitted during an animation.
-bool ShouldCheckComputedStyles(const ComputedStyle& base_computed_style,
- const ComputedStyle& computed_style) {
- // The FontFaceCache version number may be increased without forcing a style
- // recalc (see crbug.com/471079).
- if (!base_computed_style.GetFont().IsFallbackValid())
- return false;
- // Images use instance equality rather than value equality (see
- // crbug.com/781461).
- for (CSSPropertyID id :
- {CSSPropertyID::kBackgroundImage, CSSPropertyID::kWebkitMaskImage}) {
- if (!CSSPropertyEquality::PropertiesEqual(
- PropertyHandle(CSSProperty::Get(id)), base_computed_style,
- computed_style)) {
- return false;
- }
- }
- return true;
-}
-#endif // DCHECK_IS_ON()
-
} // namespace
ElementAnimations::ElementAnimations() : animation_style_change_(false) {}
@@ -87,8 +64,8 @@ void ElementAnimations::UpdateAnimationFlags(ComputedStyle& style) {
const Animation& animation = *entry.key;
DCHECK(animation.effect());
// FIXME: Needs to consider AnimationGroup once added.
- DCHECK(animation.effect()->IsKeyframeEffect());
- const KeyframeEffect& effect = *ToKeyframeEffect(animation.effect());
+ DCHECK(IsA<KeyframeEffect>(animation.effect()));
+ const auto& effect = *To<KeyframeEffect>(animation.effect());
if (!effect.IsCurrent())
continue;
UpdateAnimationFlagsForEffect(effect, style);
@@ -129,43 +106,36 @@ void ElementAnimations::RestartAnimationOnCompositor() {
entry.key->RestartAnimationOnCompositor();
}
-void ElementAnimations::Trace(blink::Visitor* visitor) {
+void ElementAnimations::Trace(Visitor* visitor) {
visitor->Trace(css_animations_);
visitor->Trace(effect_stack_);
visitor->Trace(animations_);
visitor->Trace(worklet_animations_);
}
+bool ElementAnimations::IsBaseComputedStyleUsable() const {
+ if (has_important_overrides_)
+ return false;
+ if (has_font_affecting_animation_ && base_computed_style_ &&
+ base_computed_style_->HasFontRelativeUnits()) {
+ return false;
+ }
+ return true;
+}
+
const ComputedStyle* ElementAnimations::BaseComputedStyle() const {
-// When DCHECK is on we lie and claim to never have a base computed style
-// stored. This allows us to check that an invariant holds; see the comments in
-// |UpdateBaseComputedStyle|.
-#if !DCHECK_IS_ON()
- if (IsAnimationStyleChange())
+ if (IsAnimationStyleChange() && IsBaseComputedStyleUsable())
return base_computed_style_.get();
-#endif
return nullptr;
}
void ElementAnimations::UpdateBaseComputedStyle(
const ComputedStyle* computed_style) {
DCHECK(computed_style);
- if (!IsAnimationStyleChange()) {
+ if (!IsAnimationStyleChange() || !IsBaseComputedStyleUsable()) {
base_computed_style_ = nullptr;
return;
}
-#if DCHECK_IS_ON()
- // The invariant in the base computed style optimization is that as long as
- // |IsAnimationStyleChange| is true, the computed style that would be
- // generated by the style resolver is equivalent to the one we hold
- // internally. To ensure this we disable the optimization when DCHECKs are
- // enabled, but keep the internal base computed style and make sure the
- // equivalency holds here.
- if (base_computed_style_ && computed_style &&
- ShouldCheckComputedStyles(*base_computed_style_, *computed_style)) {
- DCHECK(*base_computed_style_ == *computed_style);
- }
-#endif
base_computed_style_ = ComputedStyle::Clone(*computed_style);
}
@@ -177,8 +147,8 @@ bool ElementAnimations::AnimationsPreserveAxisAlignment() const {
for (const auto& entry : animations_) {
const Animation& animation = *entry.key;
DCHECK(animation.effect());
- DCHECK(animation.effect()->IsKeyframeEffect());
- const KeyframeEffect& effect = *ToKeyframeEffect(animation.effect());
+ DCHECK(IsA<KeyframeEffect>(animation.effect()));
+ const auto& effect = *To<KeyframeEffect>(animation.effect());
if (!effect.AnimationsPreserveAxisAlignment())
return false;
}
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 acefc4ee920..9dded60358b 100644
--- a/chromium/third_party/blink/renderer/core/animation/element_animations.h
+++ b/chromium/third_party/blink/renderer/core/animation/element_animations.h
@@ -79,6 +79,8 @@ class CORE_EXPORT ElementAnimations final
void SetAnimationStyleChange(bool animation_style_change) {
animation_style_change_ = animation_style_change;
}
+ void SetHasImportantOverrides() { has_important_overrides_ = true; }
+ void SetHasFontAffectingAnimation() { has_font_affecting_animation_ = true; }
const ComputedStyle* BaseComputedStyle() const;
void UpdateBaseComputedStyle(const ComputedStyle*);
@@ -86,10 +88,11 @@ class CORE_EXPORT ElementAnimations final
bool AnimationsPreserveAxisAlignment() const;
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
bool IsAnimationStyleChange() const { return animation_style_change_; }
+ bool IsBaseComputedStyleUsable() const;
EffectStack effect_stack_;
CSSAnimations css_animations_;
@@ -103,6 +106,15 @@ class CORE_EXPORT ElementAnimations final
// change from the running animations) and use that during style recalc,
// applying only the animation changes on top of it.
bool animation_style_change_;
+ // This is true when there's an !important declaration that overrides an
+ // animation effect. In this case, we can not use the base computed style
+ // optimization, since we have no way of knowing the cascade origins used
+ // to construct the various parts of the base style.
+ bool has_important_overrides_ = false;
+ // If a font-affecting property is undergoing an animation, we can't use
+ // the base computed style optimization, because font-relative units
+ // (such as 'em') present in the base should respond to the animation.
+ bool has_font_affecting_animation_ = false;
scoped_refptr<ComputedStyle> base_computed_style_;
// CSSAnimations checks if a style change is due to animation.
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 d808645801a..5ddff918d27 100644
--- a/chromium/third_party/blink/renderer/core/animation/inert_effect.cc
+++ b/chromium/third_party/blink/renderer/core/animation/inert_effect.cc
@@ -60,11 +60,11 @@ void InertEffect::Sample(HeapVector<Member<Interpolation>>& result) const {
AnimationTimeDelta InertEffect::CalculateTimeToEffectChange(
bool,
base::Optional<double>,
- double) const {
+ AnimationTimeDelta) const {
return AnimationTimeDelta::Max();
}
-void InertEffect::Trace(blink::Visitor* visitor) {
+void InertEffect::Trace(Visitor* visitor) {
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 3b656259ac6..4be0330981b 100644
--- a/chromium/third_party/blink/renderer/core/animation/inert_effect.h
+++ b/chromium/third_party/blink/renderer/core/animation/inert_effect.h
@@ -53,14 +53,14 @@ class CORE_EXPORT InertEffect final : public AnimationEffect {
bool IsInertEffect() const final { return true; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
void UpdateChildrenAndEffects() const override {}
AnimationTimeDelta CalculateTimeToEffectChange(
bool forwards,
base::Optional<double> inherited_time,
- double time_to_next_iteration) const override;
+ AnimationTimeDelta time_to_next_iteration) const override;
private:
Member<KeyframeEffectModelBase> model_;
@@ -68,11 +68,12 @@ class CORE_EXPORT InertEffect final : public AnimationEffect {
base::Optional<double> inherited_time_;
};
-DEFINE_TYPE_CASTS(InertEffect,
- AnimationEffect,
- animationEffect,
- animationEffect->IsInertEffect(),
- animationEffect.IsInertEffect());
+template <>
+struct DowncastTraits<InertEffect> {
+ static bool AllowFrom(const AnimationEffect& animationEffect) {
+ return animationEffect.IsInertEffect();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/interpolable_filter.cc b/chromium/third_party/blink/renderer/core/animation/interpolable_filter.cc
index 9e9df379b59..91a602f957e 100644
--- a/chromium/third_party/blink/renderer/core/animation/interpolable_filter.cc
+++ b/chromium/third_party/blink/renderer/core/animation/interpolable_filter.cc
@@ -173,7 +173,7 @@ FilterOperation* InterpolableFilter::CreateFilterOperation(
case FilterOperation::SATURATE:
case FilterOperation::SEPIA: {
double value =
- ClampParameter(ToInterpolableNumber(*value_).Value(), type_);
+ ClampParameter(To<InterpolableNumber>(*value_).Value(), type_);
return MakeGarbageCollected<BasicColorMatrixFilterOperation>(value,
type_);
}
@@ -183,7 +183,7 @@ FilterOperation* InterpolableFilter::CreateFilterOperation(
case FilterOperation::INVERT:
case FilterOperation::OPACITY: {
double value =
- ClampParameter(ToInterpolableNumber(*value_).Value(), type_);
+ ClampParameter(To<InterpolableNumber>(*value_).Value(), type_);
return MakeGarbageCollected<BasicComponentTransferFilterOperation>(value,
type_);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/interpolable_shadow.h b/chromium/third_party/blink/renderer/core/animation/interpolable_shadow.h
index bdc200f4ce8..ddbd104c5bd 100644
--- a/chromium/third_party/blink/renderer/core/animation/interpolable_shadow.h
+++ b/chromium/third_party/blink/renderer/core/animation/interpolable_shadow.h
@@ -50,7 +50,7 @@ class InterpolableShadow : public InterpolableValue {
double underlying_fraction,
const InterpolableValue&,
const NonInterpolableValue*);
-
+ ShadowStyle GetShadowStyle() const { return shadow_style_; }
// Convert this InterpolableShadow back into a ShadowData class, usually to be
// applied to the style after interpolating it.
ShadowData CreateShadowData(const StyleResolverState&) const;
diff --git a/chromium/third_party/blink/renderer/core/animation/interpolable_value.cc b/chromium/third_party/blink/renderer/core/animation/interpolable_value.cc
index 272c70dad4f..cd96b8511d2 100644
--- a/chromium/third_party/blink/renderer/core/animation/interpolable_value.cc
+++ b/chromium/third_party/blink/renderer/core/animation/interpolable_value.cc
@@ -9,11 +9,11 @@
namespace blink {
bool InterpolableNumber::Equals(const InterpolableValue& other) const {
- return value_ == ToInterpolableNumber(other).value_;
+ return value_ == To<InterpolableNumber>(other).value_;
}
bool InterpolableList::Equals(const InterpolableValue& other) const {
- const InterpolableList& other_list = ToInterpolableList(other);
+ const auto& other_list = To<InterpolableList>(other);
if (length() != other_list.length())
return false;
for (wtf_size_t i = 0; i < length(); i++) {
@@ -31,8 +31,8 @@ void InterpolableNumber::AssertCanInterpolateWith(
void InterpolableNumber::Interpolate(const InterpolableValue& to,
const double progress,
InterpolableValue& result) const {
- const InterpolableNumber& to_number = ToInterpolableNumber(to);
- InterpolableNumber& result_number = ToInterpolableNumber(result);
+ const auto& to_number = To<InterpolableNumber>(to);
+ auto& result_number = To<InterpolableNumber>(result);
if (progress == 0 || value_ == to_number.value_)
result_number.value_ = value_;
@@ -46,14 +46,14 @@ void InterpolableNumber::Interpolate(const InterpolableValue& to,
void InterpolableList::AssertCanInterpolateWith(
const InterpolableValue& other) const {
DCHECK(other.IsList());
- DCHECK_EQ(ToInterpolableList(other).length(), length());
+ DCHECK_EQ(To<InterpolableList>(other).length(), length());
}
void InterpolableList::Interpolate(const InterpolableValue& to,
const double progress,
InterpolableValue& result) const {
- const InterpolableList& to_list = ToInterpolableList(to);
- InterpolableList& result_list = ToInterpolableList(result);
+ const auto& to_list = To<InterpolableList>(to);
+ auto& result_list = To<InterpolableList>(result);
for (wtf_size_t i = 0; i < length(); i++) {
DCHECK(values_[i]);
@@ -80,11 +80,11 @@ void InterpolableList::Scale(double scale) {
}
void InterpolableNumber::Add(const InterpolableValue& other) {
- value_ += ToInterpolableNumber(other).value_;
+ value_ += To<InterpolableNumber>(other).value_;
}
void InterpolableList::Add(const InterpolableValue& other) {
- const InterpolableList& other_list = ToInterpolableList(other);
+ const auto& other_list = To<InterpolableList>(other);
DCHECK_EQ(other_list.length(), length());
for (wtf_size_t i = 0; i < length(); i++)
values_[i]->Add(*other_list.values_[i]);
@@ -92,7 +92,7 @@ void InterpolableList::Add(const InterpolableValue& other) {
void InterpolableList::ScaleAndAdd(double scale,
const InterpolableValue& other) {
- const InterpolableList& other_list = ToInterpolableList(other);
+ const auto& other_list = To<InterpolableList>(other);
DCHECK_EQ(other_list.length(), length());
for (wtf_size_t i = 0; i < length(); i++)
values_[i]->ScaleAndAdd(scale, *other_list.values_[i]);
diff --git a/chromium/third_party/blink/renderer/core/animation/interpolable_value.h b/chromium/third_party/blink/renderer/core/animation/interpolable_value.h
index 2301fd0174f..0a846d2f464 100644
--- a/chromium/third_party/blink/renderer/core/animation/interpolable_value.h
+++ b/chromium/third_party/blink/renderer/core/animation/interpolable_value.h
@@ -11,6 +11,7 @@
#include "base/memory/ptr_util.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/casting.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
@@ -151,16 +152,18 @@ class CORE_EXPORT InterpolableList : public InterpolableValue {
Vector<std::unique_ptr<InterpolableValue>> values_;
};
-DEFINE_TYPE_CASTS(InterpolableNumber,
- InterpolableValue,
- value,
- value->IsNumber(),
- value.IsNumber());
-DEFINE_TYPE_CASTS(InterpolableList,
- InterpolableValue,
- value,
- value->IsList(),
- value.IsList());
+template <>
+struct DowncastTraits<InterpolableNumber> {
+ static bool AllowFrom(const InterpolableValue& value) {
+ return value.IsNumber();
+ }
+};
+template <>
+struct DowncastTraits<InterpolableList> {
+ static bool AllowFrom(const InterpolableValue& value) {
+ return value.IsList();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/interpolable_value_test.cc b/chromium/third_party/blink/renderer/core/animation/interpolable_value_test.cc
index 0bdb331d530..3ac40d45040 100644
--- a/chromium/third_party/blink/renderer/core/animation/interpolable_value_test.cc
+++ b/chromium/third_party/blink/renderer/core/animation/interpolable_value_test.cc
@@ -32,7 +32,7 @@ class AnimationInterpolableValueTest : public testing::Test {
std::unique_ptr<TypedInterpolationValue> interpolated_value =
i->GetInterpolatedValue();
EXPECT_TRUE(interpolated_value);
- return ToInterpolableNumber(interpolated_value->GetInterpolableValue())
+ return To<InterpolableNumber>(interpolated_value->GetInterpolableValue())
.Value();
}
@@ -74,11 +74,11 @@ TEST_F(AnimationInterpolableValueTest, SimpleList) {
std::unique_ptr<InterpolableValue> interpolated_value =
InterpolateLists(std::move(list_a), std::move(list_b), 0.3);
- const InterpolableList& out_list = ToInterpolableList(*interpolated_value);
+ const auto& out_list = To<InterpolableList>(*interpolated_value);
- EXPECT_FLOAT_EQ(30, ToInterpolableNumber(out_list.Get(0))->Value());
- EXPECT_FLOAT_EQ(-30.6f, ToInterpolableNumber(out_list.Get(1))->Value());
- EXPECT_FLOAT_EQ(104.35f, ToInterpolableNumber(out_list.Get(2))->Value());
+ EXPECT_FLOAT_EQ(30, To<InterpolableNumber>(out_list.Get(0))->Value());
+ EXPECT_FLOAT_EQ(-30.6f, To<InterpolableNumber>(out_list.Get(1))->Value());
+ EXPECT_FLOAT_EQ(104.35f, To<InterpolableNumber>(out_list.Get(2))->Value());
}
TEST_F(AnimationInterpolableValueTest, NestedList) {
@@ -98,13 +98,13 @@ TEST_F(AnimationInterpolableValueTest, NestedList) {
std::unique_ptr<InterpolableValue> interpolated_value =
InterpolateLists(std::move(list_a), std::move(list_b), 0.5);
- const InterpolableList& out_list = ToInterpolableList(*interpolated_value);
+ const auto& out_list = To<InterpolableList>(*interpolated_value);
- EXPECT_FLOAT_EQ(50, ToInterpolableNumber(out_list.Get(0))->Value());
+ EXPECT_FLOAT_EQ(50, To<InterpolableNumber>(out_list.Get(0))->Value());
EXPECT_FLOAT_EQ(
- 75, ToInterpolableNumber(ToInterpolableList(out_list.Get(1))->Get(0))
+ 75, To<InterpolableNumber>(To<InterpolableList>(out_list.Get(1))->Get(0))
->Value());
- EXPECT_FLOAT_EQ(0.5, ToInterpolableNumber(out_list.Get(2))->Value());
+ EXPECT_FLOAT_EQ(0.5, To<InterpolableNumber>(out_list.Get(2))->Value());
}
TEST_F(AnimationInterpolableValueTest, ScaleAndAddNumbers) {
@@ -132,9 +132,9 @@ TEST_F(AnimationInterpolableValueTest, ScaleAndAddLists) {
add_list->Set(1, std::make_unique<InterpolableNumber>(2));
add_list->Set(2, std::make_unique<InterpolableNumber>(3));
ScaleAndAdd(*base_list, 2, *add_list);
- EXPECT_FLOAT_EQ(11, ToInterpolableNumber(base_list->Get(0))->Value());
- EXPECT_FLOAT_EQ(22, ToInterpolableNumber(base_list->Get(1))->Value());
- EXPECT_FLOAT_EQ(33, ToInterpolableNumber(base_list->Get(2))->Value());
+ EXPECT_FLOAT_EQ(11, To<InterpolableNumber>(base_list->Get(0))->Value());
+ EXPECT_FLOAT_EQ(22, To<InterpolableNumber>(base_list->Get(1))->Value());
+ EXPECT_FLOAT_EQ(33, To<InterpolableNumber>(base_list->Get(2))->Value());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/interpolation_effect_test.cc b/chromium/third_party/blink/renderer/core/animation/interpolation_effect_test.cc
index a38dbb29da9..0bdf8fe0fca 100644
--- a/chromium/third_party/blink/renderer/core/animation/interpolation_effect_test.cc
+++ b/chromium/third_party/blink/renderer/core/animation/interpolation_effect_test.cc
@@ -14,10 +14,10 @@ namespace blink {
namespace {
double GetInterpolableNumber(Interpolation* value) {
- TransitionInterpolation* interpolation = ToTransitionInterpolation(value);
+ auto* interpolation = To<TransitionInterpolation>(value);
std::unique_ptr<TypedInterpolationValue> interpolated_value =
interpolation->GetInterpolatedValue();
- return ToInterpolableNumber(interpolated_value->GetInterpolableValue())
+ return To<InterpolableNumber>(interpolated_value->GetInterpolableValue())
.Value();
}
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 ca3994dbbac..ec3f4236565 100644
--- a/chromium/third_party/blink/renderer/core/animation/invalidatable_interpolation.cc
+++ b/chromium/third_party/blink/renderer/core/animation/invalidatable_interpolation.cc
@@ -200,13 +200,13 @@ void InvalidatableInterpolation::SetFlagIfInheritUsed(
if (!property_.IsCSSProperty() && !property_.IsPresentationAttribute())
return;
StyleResolverState& state =
- ToCSSInterpolationEnvironment(environment).GetState();
+ To<CSSInterpolationEnvironment>(environment).GetState();
if (!state.ParentStyle())
return;
const CSSValue* start_value =
- ToCSSPropertySpecificKeyframe(*start_keyframe_).Value();
+ To<CSSPropertySpecificKeyframe>(*start_keyframe_).Value();
const CSSValue* end_value =
- ToCSSPropertySpecificKeyframe(*end_keyframe_).Value();
+ To<CSSPropertySpecificKeyframe>(*end_keyframe_).Value();
if ((start_value && start_value->IsInheritedValue()) ||
(end_value && end_value->IsInheritedValue())) {
state.ParentStyle()->SetHasExplicitlyInheritedProperties();
@@ -231,8 +231,8 @@ void InvalidatableInterpolation::ApplyStack(
// Compute the underlying value to composite onto.
UnderlyingValueOwner underlying_value_owner;
- const InvalidatableInterpolation& first_interpolation =
- ToInvalidatableInterpolation(*interpolations.at(starting_index));
+ const auto& first_interpolation =
+ To<InvalidatableInterpolation>(*interpolations.at(starting_index));
first_interpolation.EnsureValidInterpolationTypes(environment);
if (first_interpolation.DependsOnUnderlyingValue()) {
underlying_value_owner.Set(
@@ -258,8 +258,8 @@ void InvalidatableInterpolation::ApplyStack(
// Composite interpolations onto the underlying value.
bool should_apply = false;
for (wtf_size_t i = starting_index; i < interpolations.size(); i++) {
- const InvalidatableInterpolation& current_interpolation =
- ToInvalidatableInterpolation(*interpolations.at(i));
+ const auto& current_interpolation =
+ To<InvalidatableInterpolation>(*interpolations.at(i));
DCHECK(current_interpolation.DependsOnUnderlyingValue());
current_interpolation.EnsureValidInterpolationTypes(environment);
const TypedInterpolationValue* current_value =
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 d644929bd04..83e3f18f393 100644
--- a/chromium/third_party/blink/renderer/core/animation/invalidatable_interpolation.h
+++ b/chromium/third_party/blink/renderer/core/animation/invalidatable_interpolation.h
@@ -98,11 +98,12 @@ class CORE_EXPORT InvalidatableInterpolation : public Interpolation {
mutable std::unique_ptr<TypedInterpolationValue> cached_value_;
};
-DEFINE_TYPE_CASTS(InvalidatableInterpolation,
- Interpolation,
- value,
- value->IsInvalidatableInterpolation(),
- value.IsInvalidatableInterpolation());
+template <>
+struct DowncastTraits<InvalidatableInterpolation> {
+ static bool AllowFrom(const Interpolation& value) {
+ return value.IsInvalidatableInterpolation();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe.cc b/chromium/third_party/blink/renderer/core/animation/keyframe.cc
index a6b48a5cb75..22fba719cf0 100644
--- a/chromium/third_party/blink/renderer/core/animation/keyframe.cc
+++ b/chromium/third_party/blink/renderer/core/animation/keyframe.cc
@@ -16,7 +16,7 @@ Keyframe::PropertySpecificKeyframe::PropertySpecificKeyframe(
scoped_refptr<TimingFunction> easing,
EffectModel::CompositeOperation composite)
: offset_(offset), easing_(std::move(easing)), composite_(composite) {
- DCHECK(!IsNull(offset));
+ DCHECK(!Timing::IsNull(offset));
if (!easing_)
easing_ = LinearTimingFunction::Shared();
}
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 f821ad84ef0..cb7772fe0db 100644
--- a/chromium/third_party/blink/renderer/core/animation/keyframe_effect.cc
+++ b/chromium/third_party/blink/renderer/core/animation/keyframe_effect.cc
@@ -39,56 +39,96 @@
#include "third_party/blink/renderer/core/animation/timing_input.h"
#include "third_party/blink/renderer/core/dom/element.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/frame/web_feature.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/svg/svg_element.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/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
+namespace {
+
+// Verifies that a pseudo-element selector lexes and canonicalizes legacy forms
+bool ValidateAndCanonicalizePseudo(String& selector) {
+ if (selector.IsNull()) {
+ return true;
+ } else if (selector.StartsWith("::")) {
+ return true;
+ } else if (selector == ":before") {
+ selector = "::before";
+ return true;
+ } else if (selector == ":after") {
+ selector = "::after";
+ return true;
+ } else if (selector == ":first-letter") {
+ selector = "::first-letter";
+ return true;
+ } else if (selector == ":first-line") {
+ selector = "::first-line";
+ return true;
+ }
+ return false;
+}
+
+} // namespace
+
KeyframeEffect* KeyframeEffect::Create(
ScriptState* script_state,
Element* element,
const ScriptValue& keyframes,
const UnrestrictedDoubleOrKeyframeEffectOptions& options,
ExceptionState& exception_state) {
- if (element) {
- UseCounter::Count(
- element->GetDocument(),
- WebFeature::kAnimationConstructorKeyframeListEffectObjectTiming);
- }
Document* document = element ? &element->GetDocument() : nullptr;
Timing timing = TimingInput::Convert(options, document, exception_state);
if (exception_state.HadException())
return nullptr;
EffectModel::CompositeOperation composite = EffectModel::kCompositeReplace;
+ String pseudo = String();
if (options.IsKeyframeEffectOptions()) {
- composite = EffectModel::StringToCompositeOperation(
- options.GetAsKeyframeEffectOptions()->composite())
- .value();
+ auto* effect_options = options.GetAsKeyframeEffectOptions();
+ composite =
+ EffectModel::StringToCompositeOperation(effect_options->composite())
+ .value();
+ if (RuntimeEnabledFeatures::WebAnimationsAPIEnabled() &&
+ !effect_options->pseudoElement().IsEmpty()) {
+ pseudo = effect_options->pseudoElement();
+ if (!ValidateAndCanonicalizePseudo(pseudo)) {
+ // TODO(gtsteel): update when
+ // https://github.com/w3c/csswg-drafts/issues/4586 resolves
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kSyntaxError,
+ "A valid pseudo-selector must be null or start with ::.");
+ }
+ }
}
KeyframeEffectModelBase* model = EffectInput::Convert(
element, keyframes, composite, script_state, exception_state);
if (exception_state.HadException())
return nullptr;
- return MakeGarbageCollected<KeyframeEffect>(element, model, timing);
+ KeyframeEffect* effect =
+ MakeGarbageCollected<KeyframeEffect>(element, model, timing);
+
+ if (!pseudo.IsEmpty()) {
+ effect->target_pseudo_ = pseudo;
+ if (element) {
+ element->GetDocument().UpdateStyleAndLayoutTreeForNode(element);
+ effect->effect_target_ =
+ element->GetPseudoElement(CSSSelector::ParsePseudoId(pseudo));
+ }
+ }
+ return effect;
}
KeyframeEffect* KeyframeEffect::Create(ScriptState* script_state,
Element* element,
const ScriptValue& keyframes,
ExceptionState& exception_state) {
- if (element) {
- UseCounter::Count(
- element->GetDocument(),
- WebFeature::kAnimationConstructorKeyframeListEffectNoTiming);
- }
KeyframeEffectModelBase* model =
EffectInput::Convert(element, keyframes, EffectModel::kCompositeReplace,
script_state, exception_state);
@@ -102,7 +142,7 @@ KeyframeEffect* KeyframeEffect::Create(ScriptState* script_state,
ExceptionState& exception_state) {
Timing new_timing = source->SpecifiedTiming();
KeyframeEffectModelBase* model = source->Model()->Clone();
- return MakeGarbageCollected<KeyframeEffect>(source->target(), model,
+ return MakeGarbageCollected<KeyframeEffect>(source->EffectTarget(), model,
new_timing, source->GetPriority(),
source->GetEventDelegate());
}
@@ -113,24 +153,67 @@ KeyframeEffect::KeyframeEffect(Element* target,
Priority priority,
EventDelegate* event_delegate)
: AnimationEffect(timing, event_delegate),
- target_(target),
+ effect_target_(target),
+ target_element_(target),
+ target_pseudo_(),
model_(model),
sampled_effect_(nullptr),
- priority_(priority) {
+ priority_(priority),
+ ignore_css_keyframes_(false) {
DCHECK(model_);
+
+ // fix target for css animations and transitions
+ if (target && target->IsPseudoElement()) {
+ target_element_ = target->parentElement();
+ DCHECK(!target_element_->IsPseudoElement());
+ target_pseudo_ = target->tagName();
+ }
}
KeyframeEffect::~KeyframeEffect() = default;
-void KeyframeEffect::setTarget(Element* target) {
- if (target_ == target)
- return;
+void KeyframeEffect::setTarget(Element* new_target) {
+ DCHECK(!new_target || !new_target->IsPseudoElement());
+ target_element_ = new_target;
+ RefreshTarget();
+}
- DetachTarget(GetAnimation());
- target_ = target;
- AttachTarget(GetAnimation());
+const String& KeyframeEffect::pseudoElement() const {
+ return target_pseudo_;
+}
- InvalidateAndNotifyOwner();
+void KeyframeEffect::setPseudoElement(String pseudo,
+ ExceptionState& exception_state) {
+ if (ValidateAndCanonicalizePseudo(pseudo)) {
+ target_pseudo_ = pseudo;
+ } else {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kSyntaxError,
+ "A valid pseudo-selector must be null or start with ::.");
+ }
+
+ RefreshTarget();
+}
+
+void KeyframeEffect::RefreshTarget() {
+ Element* new_target;
+ if (!target_element_) {
+ new_target = nullptr;
+ } else if (target_pseudo_.IsEmpty()) {
+ new_target = target_element_;
+ } else {
+ target_element_->GetDocument().UpdateStyleAndLayoutTreeForNode(
+ target_element_);
+ PseudoId pseudoId = CSSSelector::ParsePseudoId(target_pseudo_);
+ new_target = target_element_->GetPseudoElement(pseudoId);
+ }
+
+ if (new_target != effect_target_) {
+ DetachTarget(GetAnimation());
+ effect_target_ = new_target;
+ AttachTarget(GetAnimation());
+ InvalidateAndNotifyOwner();
+ }
}
String KeyframeEffect::composite() const {
@@ -147,6 +230,9 @@ void KeyframeEffect::setComposite(String composite_string) {
HeapVector<ScriptValue> KeyframeEffect::getKeyframes(
ScriptState* script_state) {
+ if (Animation* animation = GetAnimation())
+ animation->FlushPendingUpdates();
+
HeapVector<ScriptValue> computed_keyframes;
if (!model_->HasFrames())
return computed_keyframes;
@@ -174,21 +260,17 @@ HeapVector<ScriptValue> KeyframeEffect::getKeyframes(
void KeyframeEffect::setKeyframes(ScriptState* script_state,
const ScriptValue& keyframes,
ExceptionState& exception_state) {
- // TODO(crbug.com/799061): Support TransitionKeyframeEffectModel. This will
- // require a lot of work as the setKeyframes API can mutate a transition
- // Animation into a 'normal' one with multiple properties.
- if (!Model()->IsStringKeyframeEffectModel()) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kNotSupportedError,
- "Calling setKeyframes on CSS Transitions is not yet supported");
- return;
- }
-
StringKeyframeVector new_keyframes = EffectInput::ParseKeyframesArgument(
target(), keyframes, script_state, exception_state);
if (exception_state.HadException())
return;
+ ignore_css_keyframes_ = true;
+
+ if (auto* model = DynamicTo<TransitionKeyframeEffectModel>(Model()))
+ SetModel(model->CloneAsEmptyStringKeyframeModel());
+
+ DCHECK(Model()->IsStringKeyframeEffectModel());
SetKeyframes(new_keyframes);
}
@@ -196,7 +278,7 @@ void KeyframeEffect::SetKeyframes(StringKeyframeVector keyframes) {
Model()->SetComposite(
EffectInput::ResolveCompositeOperation(Model()->Composite(), keyframes));
- ToStringKeyframeEffectModel(Model())->SetFrames(keyframes);
+ To<StringKeyframeEffectModel>(Model())->SetFrames(keyframes);
// Changing the keyframes will invalidate any sampled effect, as well as
// potentially affect the effect owner.
@@ -226,10 +308,11 @@ KeyframeEffect::CheckCanStartAnimationOnCompositor(
// There would be no reason to composite an effect that has no target; it has
// no visual result.
- if (!target_) {
+ if (!effect_target_) {
reasons |= CompositorAnimations::kInvalidAnimationOrEffect;
} else {
- if (target_->GetComputedStyle() && target_->GetComputedStyle()->HasOffset())
+ if (effect_target_->GetComputedStyle() &&
+ effect_target_->GetComputedStyle()->HasOffset())
reasons |= CompositorAnimations::kTargetHasCSSOffset;
// Do not put transforms on compositor if more than one of them are defined
@@ -238,7 +321,7 @@ KeyframeEffect::CheckCanStartAnimationOnCompositor(
reasons |= CompositorAnimations::kTargetHasMultipleTransformProperties;
reasons |= CompositorAnimations::CheckCanStartAnimationOnCompositor(
- SpecifiedTiming(), *target_, GetAnimation(), *Model(),
+ SpecifiedTiming(), *effect_target_, GetAnimation(), *Model(),
paint_artifact_compositor, animation_playback_rate);
}
@@ -248,7 +331,7 @@ KeyframeEffect::CheckCanStartAnimationOnCompositor(
void KeyframeEffect::StartAnimationOnCompositor(
int group,
base::Optional<double> start_time,
- double current_time,
+ base::TimeDelta time_offset,
double animation_playback_rate,
CompositorAnimation* compositor_animation) {
DCHECK(!HasActiveAnimationsOnCompositor());
@@ -259,11 +342,11 @@ void KeyframeEffect::StartAnimationOnCompositor(
compositor_animation = GetAnimation()->GetCompositorAnimation();
DCHECK(compositor_animation);
- DCHECK(target_);
+ DCHECK(effect_target_);
DCHECK(Model());
CompositorAnimations::StartAnimationOnCompositor(
- *target_, group, start_time, current_time, SpecifiedTiming(),
+ *effect_target_, group, start_time, time_offset, SpecifiedTiming(),
GetAnimation(), *compositor_animation, *Model(),
compositor_keyframe_model_ids_, animation_playback_rate);
DCHECK(!compositor_keyframe_model_ids_.IsEmpty());
@@ -282,41 +365,43 @@ bool KeyframeEffect::CancelAnimationOnCompositor(
CompositorAnimation* compositor_animation) {
if (!HasActiveAnimationsOnCompositor())
return false;
- if (!target_ || !target_->GetLayoutObject())
+ if (!effect_target_ || !effect_target_->GetLayoutObject())
return false;
for (const auto& compositor_keyframe_model_id :
compositor_keyframe_model_ids_) {
CompositorAnimations::CancelAnimationOnCompositor(
- *target_, compositor_animation, compositor_keyframe_model_id);
+ *effect_target_, compositor_animation, compositor_keyframe_model_id);
}
compositor_keyframe_model_ids_.clear();
return true;
}
void KeyframeEffect::CancelIncompatibleAnimationsOnCompositor() {
- if (target_ && GetAnimation() && model_->HasFrames()) {
+ if (effect_target_ && GetAnimation() && model_->HasFrames()) {
CompositorAnimations::CancelIncompatibleAnimationsOnCompositor(
- *target_, *GetAnimation(), *Model());
+ *effect_target_, *GetAnimation(), *Model());
}
}
-void KeyframeEffect::PauseAnimationForTestingOnCompositor(double pause_time) {
+void KeyframeEffect::PauseAnimationForTestingOnCompositor(
+ base::TimeDelta pause_time) {
DCHECK(HasActiveAnimationsOnCompositor());
- if (!target_ || !target_->GetLayoutObject())
+ if (!effect_target_ || !effect_target_->GetLayoutObject())
return;
DCHECK(GetAnimation());
for (const auto& compositor_keyframe_model_id :
compositor_keyframe_model_ids_) {
CompositorAnimations::PauseAnimationForTestingOnCompositor(
- *target_, *GetAnimation(), compositor_keyframe_model_id, pause_time);
+ *effect_target_, *GetAnimation(), compositor_keyframe_model_id,
+ pause_time);
}
}
void KeyframeEffect::AttachCompositedLayers() {
- DCHECK(target_);
+ DCHECK(effect_target_);
DCHECK(GetAnimation());
CompositorAnimations::AttachCompositedLayers(
- *target_, GetAnimation()->GetCompositorAnimation());
+ *effect_target_, GetAnimation()->GetCompositorAnimation());
}
bool KeyframeEffect::HasAnimation() const {
@@ -327,8 +412,9 @@ bool KeyframeEffect::HasPlayingAnimation() const {
return owner_ && owner_->Playing();
}
-void KeyframeEffect::Trace(blink::Visitor* visitor) {
- visitor->Trace(target_);
+void KeyframeEffect::Trace(Visitor* visitor) {
+ visitor->Trace(effect_target_);
+ visitor->Trace(target_element_);
visitor->Trace(model_);
visitor->Trace(sampled_effect_);
AnimationEffect::Trace(visitor);
@@ -345,7 +431,7 @@ bool KeyframeEffect::AnimationsPreserveAxisAlignment(
continue;
DCHECK(value->IsTransform());
const auto& transform_operations =
- ToCompositorKeyframeTransform(value)->GetTransformOperations();
+ To<CompositorKeyframeTransform>(value)->GetTransformOperations();
if (!transform_operations.PreservesAxisAlignment())
return false;
}
@@ -381,7 +467,7 @@ EffectModel::CompositeOperation KeyframeEffect::CompositeInternal() const {
void KeyframeEffect::ApplyEffects() {
DCHECK(IsInEffect());
- if (!target_ || !model_->HasFrames())
+ if (!effect_target_ || !model_->HasFrames())
return;
if (GetAnimation() && HasIncompatibleStyle()) {
@@ -406,7 +492,8 @@ void KeyframeEffect::ApplyEffects() {
MakeGarbageCollected<SampledEffect>(this, owner_->SequenceNumber());
sampled_effect->MutableInterpolations().swap(interpolations);
sampled_effect_ = sampled_effect;
- target_->EnsureElementAnimations().GetEffectStack().Add(sampled_effect);
+ effect_target_->EnsureElementAnimations().GetEffectStack().Add(
+ sampled_effect);
changed = true;
} else {
return;
@@ -414,8 +501,8 @@ void KeyframeEffect::ApplyEffects() {
}
if (changed) {
- target_->SetNeedsAnimationStyleRecalc();
- auto* svg_element = DynamicTo<SVGElement>(target_.Get());
+ effect_target_->SetNeedsAnimationStyleRecalc();
+ auto* svg_element = DynamicTo<SVGElement>(effect_target_.Get());
if (RuntimeEnabledFeatures::WebAnimationsSVGEnabled() && svg_element)
svg_element->SetWebAnimationsPending();
}
@@ -428,8 +515,8 @@ void KeyframeEffect::ClearEffects() {
sampled_effect_ = nullptr;
if (GetAnimation())
GetAnimation()->RestartAnimationOnCompositor();
- target_->SetNeedsAnimationStyleRecalc();
- auto* svg_element = DynamicTo<SVGElement>(target_.Get());
+ effect_target_->SetNeedsAnimationStyleRecalc();
+ auto* svg_element = DynamicTo<SVGElement>(effect_target_.Get());
if (RuntimeEnabledFeatures::WebAnimationsSVGEnabled() && svg_element)
svg_element->ClearWebAnimatedAttributes();
Invalidate();
@@ -439,7 +526,8 @@ void KeyframeEffect::UpdateChildrenAndEffects() const {
if (!model_->HasFrames())
return;
DCHECK(owner_);
- if (IsInEffect() && !owner_->EffectSuppressed())
+ if (IsInEffect() && !owner_->EffectSuppressed() &&
+ !owner_->ReplaceStateRemoved())
const_cast<KeyframeEffect*>(this)->ApplyEffects();
else
const_cast<KeyframeEffect*>(this)->ClearEffects();
@@ -456,18 +544,18 @@ void KeyframeEffect::Detach() {
}
void KeyframeEffect::AttachTarget(Animation* animation) {
- if (!target_ || !animation)
+ if (!effect_target_ || !animation)
return;
- target_->EnsureElementAnimations().Animations().insert(animation);
- target_->SetNeedsAnimationStyleRecalc();
- auto* svg_element = DynamicTo<SVGElement>(target_.Get());
+ effect_target_->EnsureElementAnimations().Animations().insert(animation);
+ effect_target_->SetNeedsAnimationStyleRecalc();
+ auto* svg_element = DynamicTo<SVGElement>(effect_target_.Get());
if (RuntimeEnabledFeatures::WebAnimationsSVGEnabled() && svg_element)
svg_element->SetWebAnimationsPending();
}
void KeyframeEffect::DetachTarget(Animation* animation) {
- if (target_ && animation)
- target_->GetElementAnimations()->Animations().erase(animation);
+ if (effect_target_ && animation)
+ effect_target_->GetElementAnimations()->Animations().erase(animation);
// If we have sampled this effect previously, we need to purge that state.
// ClearEffects takes care of clearing the cached sampled effect, informing
// the target that it needs to refresh its style, and doing any necessary
@@ -478,7 +566,7 @@ void KeyframeEffect::DetachTarget(Animation* animation) {
AnimationTimeDelta KeyframeEffect::CalculateTimeToEffectChange(
bool forwards,
base::Optional<double> local_time,
- double time_to_next_iteration) const {
+ AnimationTimeDelta time_to_next_iteration) const {
const double start_time = SpecifiedTiming().start_delay;
const double end_time_minus_end_delay =
start_time + SpecifiedTiming().ActiveDuration();
@@ -501,8 +589,8 @@ AnimationTimeDelta KeyframeEffect::CalculateTimeToEffectChange(
// Need service to apply fill / fire events.
const double time_to_end = after_time - local_time.value();
if (RequiresIterationEvents()) {
- return AnimationTimeDelta::FromSecondsD(
- std::min(time_to_end, time_to_next_iteration));
+ return std::min(AnimationTimeDelta::FromSecondsD(time_to_end),
+ time_to_next_iteration);
}
return AnimationTimeDelta::FromSecondsD(time_to_end);
}
@@ -528,11 +616,11 @@ AnimationTimeDelta KeyframeEffect::CalculateTimeToEffectChange(
// and a motion path or other transform properties
// has been introduced on the element
bool KeyframeEffect::HasIncompatibleStyle() const {
- if (!target_->GetComputedStyle())
+ if (!effect_target_->GetComputedStyle())
return false;
if (HasActiveAnimationsOnCompositor()) {
- if (target_->GetComputedStyle()->HasOffset()) {
+ if (effect_target_->GetComputedStyle()->HasOffset()) {
static const auto** properties = TransformProperties();
for (size_t i = 0; i < num_transform_properties; i++) {
if (Affects(PropertyHandle(*properties[i])))
@@ -546,19 +634,39 @@ bool KeyframeEffect::HasIncompatibleStyle() const {
}
bool KeyframeEffect::HasMultipleTransformProperties() const {
- if (!target_->GetComputedStyle())
+ if (!effect_target_->GetComputedStyle())
return false;
unsigned transform_property_count = 0;
- if (target_->GetComputedStyle()->HasTransformOperations())
+ if (effect_target_->GetComputedStyle()->HasTransformOperations())
transform_property_count++;
- if (target_->GetComputedStyle()->Rotate())
+ if (effect_target_->GetComputedStyle()->Rotate())
transform_property_count++;
- if (target_->GetComputedStyle()->Scale())
+ if (effect_target_->GetComputedStyle()->Scale())
transform_property_count++;
- if (target_->GetComputedStyle()->Translate())
+ if (effect_target_->GetComputedStyle()->Translate())
transform_property_count++;
return transform_property_count > 1;
}
+ActiveInterpolationsMap KeyframeEffect::InterpolationsForCommitStyles() {
+ // If the associated animation has been removed, it needs to be temporarily
+ // reintroduced to the effect stack in order to be including in the
+ // interpolations map.
+ bool removed = owner_->ReplaceStateRemoved();
+ if (removed)
+ ApplyEffects();
+
+ ActiveInterpolationsMap results = EffectStack::ActiveInterpolations(
+ &target()->GetElementAnimations()->GetEffectStack(),
+ /*new_animations=*/nullptr,
+ /*suppressed_animations=*/nullptr, kDefaultPriority,
+ /*property_pass_filter=*/nullptr, this);
+
+ if (removed)
+ ClearEffects();
+
+ return results;
+}
+
} // namespace blink
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 c217c28c283..b7a09035e07 100644
--- a/chromium/third_party/blink/renderer/core/animation/keyframe_effect.h
+++ b/chromium/third_party/blink/renderer/core/animation/keyframe_effect.h
@@ -77,8 +77,13 @@ class CORE_EXPORT KeyframeEffect final : public AnimationEffect {
bool IsKeyframeEffect() const override { return true; }
// IDL implementation.
- Element* target() const { return target_; }
+
+ // Returns the target element. If the animation targets a pseudo-element,
+ // this returns the originating element.
+ Element* target() const { return target_element_; }
void setTarget(Element*);
+ const String& pseudoElement() const;
+ void setPseudoElement(String, ExceptionState&);
String composite() const;
void setComposite(String);
HeapVector<ScriptValue> getKeyframes(ScriptState*);
@@ -86,6 +91,9 @@ class CORE_EXPORT KeyframeEffect final : public AnimationEffect {
const ScriptValue& keyframes,
ExceptionState&);
+ // Returns blink's representation of the effect target.
+ // This can be a blink::PseudoElement which should not be web-exposed.
+ Element* EffectTarget() const { return effect_target_; }
void SetKeyframes(StringKeyframeVector keyframes);
bool Affects(const PropertyHandle&) const;
@@ -105,14 +113,14 @@ class CORE_EXPORT KeyframeEffect final : public AnimationEffect {
// Must only be called once.
void StartAnimationOnCompositor(int group,
base::Optional<double> start_time,
- double time_offset,
+ base::TimeDelta time_offset,
double animation_playback_rate,
CompositorAnimation* = nullptr);
bool HasActiveAnimationsOnCompositor() const;
bool HasActiveAnimationsOnCompositor(const PropertyHandle&) const;
bool CancelAnimationOnCompositor(CompositorAnimation*);
void CancelIncompatibleAnimationsOnCompositor();
- void PauseAnimationForTestingOnCompositor(double pause_time);
+ void PauseAnimationForTestingOnCompositor(base::TimeDelta pause_time);
void AttachCompositedLayers();
@@ -121,10 +129,17 @@ class CORE_EXPORT KeyframeEffect final : public AnimationEffect {
bool HasAnimation() const;
bool HasPlayingAnimation() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
bool AnimationsPreserveAxisAlignment() const;
+ ActiveInterpolationsMap InterpolationsForCommitStyles();
+
+ // Explicitly setting the keyframes via KeyfrfameEffect.setFrames or
+ // Animation.effect block subseuqent changes via CSS keyframe rules.
+ bool GetIgnoreCSSKeyframes() { return ignore_css_keyframes_; }
+ void SetIgnoreCSSKeyframes() { ignore_css_keyframes_ = true; }
+
private:
EffectModel::CompositeOperation CompositeInternal() const;
@@ -135,29 +150,35 @@ class CORE_EXPORT KeyframeEffect final : public AnimationEffect {
void Detach() override;
void AttachTarget(Animation*);
void DetachTarget(Animation*);
+ void RefreshTarget();
AnimationTimeDelta CalculateTimeToEffectChange(
bool forwards,
base::Optional<double> inherited_time,
- double time_to_next_iteration) const override;
+ AnimationTimeDelta time_to_next_iteration) const override;
bool HasIncompatibleStyle() const;
bool HasMultipleTransformProperties() const;
bool AnimationsPreserveAxisAlignment(const PropertyHandle&) const;
- Member<Element> target_;
+ Member<Element> effect_target_;
+ Member<Element> target_element_;
+ String target_pseudo_;
Member<KeyframeEffectModelBase> model_;
Member<SampledEffect> sampled_effect_;
Priority priority_;
Vector<int> compositor_keyframe_model_ids_;
+
+ bool ignore_css_keyframes_;
};
-DEFINE_TYPE_CASTS(KeyframeEffect,
- AnimationEffect,
- animationNode,
- animationNode->IsKeyframeEffect(),
- animationNode.IsKeyframeEffect());
+template <>
+struct DowncastTraits<KeyframeEffect> {
+ static bool AllowFrom(const AnimationEffect& animationNode) {
+ return animationNode.IsKeyframeEffect();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe_effect.idl b/chromium/third_party/blink/renderer/core/animation/keyframe_effect.idl
index c1e196c6aee..50694064a02 100644
--- a/chromium/third_party/blink/renderer/core/animation/keyframe_effect.idl
+++ b/chromium/third_party/blink/renderer/core/animation/keyframe_effect.idl
@@ -33,13 +33,12 @@
enum CompositeOperation { "replace", "add", "accumulate" };
[
- Exposed=Window,
- Constructor(Element? target, object? keyframes, optional (unrestricted double or KeyframeEffectOptions) options),
- Constructor(KeyframeEffect source),
- ConstructorCallWith=ScriptState,
- RaisesException=Constructor
+ Exposed=Window
] interface KeyframeEffect : AnimationEffect {
+ [CallWith=ScriptState, RaisesException, Measure] constructor(Element? target, object? keyframes, optional (unrestricted double or KeyframeEffectOptions) options);
+ [CallWith=ScriptState, RaisesException, Measure] constructor(KeyframeEffect source);
attribute Element? target;
+ [RuntimeEnabled=WebAnimationsAPI, RaisesException=Setter] attribute CSSOMString? pseudoElement;
[RuntimeEnabled=WebAnimationsAPI] attribute CompositeOperation composite;
[CallWith=ScriptState, RuntimeEnabled=WebAnimationsAPI] sequence<object> getKeyframes();
[CallWith=ScriptState, RaisesException, RuntimeEnabled=WebAnimationsAPI] void setKeyframes(object? keyframes);
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 54224d18644..7ad2414d2cf 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
@@ -234,6 +234,12 @@ class KeyframeEffectModel final : public KeyframeEffectModelBase {
keyframes, composite_, default_keyframe_easing_);
}
+ KeyframeEffectModel<StringKeyframe>* CloneAsEmptyStringKeyframeModel() {
+ HeapVector<Member<StringKeyframe>> empty_keyframes;
+ return MakeGarbageCollected<KeyframeEffectModel<StringKeyframe>>(
+ empty_keyframes, composite_, default_keyframe_easing_);
+ }
+
private:
bool IsStringKeyframeEffectModel() const override { return false; }
bool IsTransitionKeyframeEffectModel() const override { return false; }
@@ -253,35 +259,38 @@ using TransitionKeyframeVector = TransitionKeyframeEffectModel::KeyframeVector;
using TransitionPropertySpecificKeyframeVector =
TransitionKeyframeEffectModel::PropertySpecificKeyframeVector;
-DEFINE_TYPE_CASTS(KeyframeEffectModelBase,
- EffectModel,
- value,
- value->IsKeyframeEffectModel(),
- value.IsKeyframeEffectModel());
-DEFINE_TYPE_CASTS(StringKeyframeEffectModel,
- KeyframeEffectModelBase,
- value,
- value->IsStringKeyframeEffectModel(),
- value.IsStringKeyframeEffectModel());
-DEFINE_TYPE_CASTS(TransitionKeyframeEffectModel,
- KeyframeEffectModelBase,
- value,
- value->IsTransitionKeyframeEffectModel(),
- value.IsTransitionKeyframeEffectModel());
+template <>
+struct DowncastTraits<KeyframeEffectModelBase> {
+ static bool AllowFrom(const EffectModel& value) {
+ return value.IsKeyframeEffectModel();
+ }
+};
+template <>
+struct DowncastTraits<StringKeyframeEffectModel> {
+ static bool AllowFrom(const KeyframeEffectModelBase& value) {
+ return value.IsStringKeyframeEffectModel();
+ }
+};
+template <>
+struct DowncastTraits<TransitionKeyframeEffectModel> {
+ static bool AllowFrom(const KeyframeEffectModelBase& value) {
+ return value.IsTransitionKeyframeEffectModel();
+ }
+};
inline const StringKeyframeEffectModel* ToStringKeyframeEffectModel(
const EffectModel* base) {
- return ToStringKeyframeEffectModel(ToKeyframeEffectModelBase(base));
+ return To<StringKeyframeEffectModel>(To<KeyframeEffectModelBase>(base));
}
inline StringKeyframeEffectModel* ToStringKeyframeEffectModel(
EffectModel* base) {
- return ToStringKeyframeEffectModel(ToKeyframeEffectModelBase(base));
+ return To<StringKeyframeEffectModel>(To<KeyframeEffectModelBase>(base));
}
inline TransitionKeyframeEffectModel* ToTransitionKeyframeEffectModel(
EffectModel* base) {
- return ToTransitionKeyframeEffectModel(ToKeyframeEffectModelBase(base));
+ return To<TransitionKeyframeEffectModel>(To<KeyframeEffectModelBase>(base));
}
template <>
diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model_test.cc b/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model_test.cc
index 9cb0caa9cd9..8b030e80a60 100644
--- a/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model_test.cc
+++ b/chromium/third_party/blink/renderer/core/animation/keyframe_effect_model_test.cc
@@ -68,8 +68,8 @@ class AnimationKeyframeEffectModel : public PageTestBase {
interpolations.push_back(interpolation_value);
EnsureInterpolatedValueCached(interpolations, GetDocument(), element);
- const TypedInterpolationValue* typed_value =
- ToInvalidatableInterpolation(interpolation_value)
+ const auto* typed_value =
+ To<InvalidatableInterpolation>(interpolation_value)
->GetCachedValueForTesting();
// Length values are stored as an |InterpolableLength|; here we assume
// pixels.
@@ -89,15 +89,15 @@ class AnimationKeyframeEffectModel : public PageTestBase {
interpolations.push_back(interpolation_value);
EnsureInterpolatedValueCached(interpolations, GetDocument(), element);
- const TypedInterpolationValue* typed_value =
- ToInvalidatableInterpolation(interpolation_value)
+ const auto* typed_value =
+ To<InvalidatableInterpolation>(interpolation_value)
->GetCachedValueForTesting();
const NonInterpolableValue* non_interpolable_value =
typed_value->GetNonInterpolableValue();
- ASSERT_TRUE(IsCSSDefaultNonInterpolableValue(non_interpolable_value));
+ ASSERT_TRUE(IsA<CSSDefaultNonInterpolableValue>(non_interpolable_value));
const CSSValue* css_value =
- ToCSSDefaultNonInterpolableValue(non_interpolable_value)->CssValue();
+ To<CSSDefaultNonInterpolableValue>(non_interpolable_value)->CssValue();
EXPECT_EQ(expected_value, css_value->CssText());
}
@@ -151,8 +151,8 @@ const PropertySpecificKeyframeVector& ConstructEffectAndGetKeyframes(
StringKeyframeVector keyframes =
KeyframesAtZeroAndOne(property_name, zero_value, one_value);
- element->style()->setProperty(document, property_name, zero_value,
- g_empty_string, exception_state);
+ element->style()->setProperty(document->GetExecutionContext(), property_name,
+ zero_value, g_empty_string, exception_state);
auto* effect = MakeGarbageCollected<StringKeyframeEffectModel>(keyframes);
@@ -167,8 +167,7 @@ const PropertySpecificKeyframeVector& ConstructEffectAndGetKeyframes(
void ExpectProperty(CSSPropertyID property,
Interpolation* interpolation_value) {
- InvalidatableInterpolation* interpolation =
- ToInvalidatableInterpolation(interpolation_value);
+ auto* interpolation = To<InvalidatableInterpolation>(interpolation_value);
const PropertyHandle& property_handle = interpolation->GetProperty();
ASSERT_TRUE(property_handle.IsCSSProperty());
ASSERT_EQ(property, property_handle.GetCSSProperty().PropertyID());
@@ -177,8 +176,8 @@ void ExpectProperty(CSSPropertyID property,
Interpolation* FindValue(HeapVector<Member<Interpolation>>& values,
CSSPropertyID id) {
for (auto& value : values) {
- const PropertyHandle& property =
- ToInvalidatableInterpolation(value)->GetProperty();
+ const auto& property =
+ To<InvalidatableInterpolation>(value.Get())->GetProperty();
if (property.IsCSSProperty() &&
property.GetCSSProperty().PropertyID() == id)
return value;
@@ -707,15 +706,16 @@ TEST_F(AnimationKeyframeEffectModel, CompositorSnapshotUpdateCustomProperty) {
// Test value holds the correct number type
EXPECT_TRUE(value);
EXPECT_TRUE(value->IsDouble());
- EXPECT_EQ(ToCompositorKeyframeDouble(value)->ToDouble(), 100);
+ EXPECT_EQ(To<CompositorKeyframeDouble>(value)->ToDouble(), 100);
}
TEST_F(AnimationKeyframeEffectModel, CompositorUpdateColorProperty) {
ScopedOffMainThreadCSSPaintForTest off_main_thread_css_paint(true);
DummyExceptionStateForTesting exception_state;
- element->style()->setProperty(&GetDocument(), "color", "rgb(0, 255, 0)",
- g_empty_string, exception_state);
+ element->style()->setProperty(GetDocument().GetExecutionContext(), "color",
+ "rgb(0, 255, 0)", g_empty_string,
+ exception_state);
// Compositor keyframe value available after snapshot
const CompositorKeyframeValue* value_rgb =
@@ -752,22 +752,22 @@ TEST_F(AnimationKeyframeEffectModel, CompositorUpdateColorProperty) {
// Test rgb color input
EXPECT_TRUE(value_rgb);
EXPECT_TRUE(value_rgb->IsColor());
- EXPECT_EQ(ToCompositorKeyframeColor(value_rgb)->ToColor(), SK_ColorGREEN);
+ EXPECT_EQ(To<CompositorKeyframeColor>(value_rgb)->ToColor(), SK_ColorGREEN);
// Test hsl color input
EXPECT_TRUE(value_hsl);
EXPECT_TRUE(value_hsl->IsColor());
- EXPECT_EQ(ToCompositorKeyframeColor(value_hsl)->ToColor(), SK_ColorGREEN);
+ EXPECT_EQ(To<CompositorKeyframeColor>(value_hsl)->ToColor(), SK_ColorGREEN);
// Test named color input
EXPECT_TRUE(value_name);
EXPECT_TRUE(value_name->IsColor());
- EXPECT_EQ(ToCompositorKeyframeColor(value_name)->ToColor(), SK_ColorGREEN);
+ EXPECT_EQ(To<CompositorKeyframeColor>(value_name)->ToColor(), SK_ColorGREEN);
// Test hex color input
EXPECT_TRUE(value_hex);
EXPECT_TRUE(value_hex->IsColor());
- EXPECT_EQ(ToCompositorKeyframeColor(value_hex)->ToColor(), SK_ColorGREEN);
+ EXPECT_EQ(To<CompositorKeyframeColor>(value_hex)->ToColor(), SK_ColorGREEN);
// currentcolor is a CSSIdentifierValue not a color
EXPECT_FALSE(value_curr);
@@ -780,11 +780,13 @@ TEST_F(AnimationKeyframeEffectModel, CompositorUpdateColorProperty) {
EXPECT_TRUE(value_mixed0);
EXPECT_TRUE(value_mixed0->IsColor());
- EXPECT_EQ(ToCompositorKeyframeColor(value_mixed0)->ToColor(), SK_ColorBLACK);
+ EXPECT_EQ(To<CompositorKeyframeColor>(value_mixed0)->ToColor(),
+ SK_ColorBLACK);
EXPECT_TRUE(value_mixed1);
EXPECT_TRUE(value_mixed1->IsColor());
- EXPECT_EQ(ToCompositorKeyframeColor(value_mixed1)->ToColor(), SK_ColorGREEN);
+ EXPECT_EQ(To<CompositorKeyframeColor>(value_mixed1)->ToColor(),
+ SK_ColorGREEN);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe_effect_options.idl b/chromium/third_party/blink/renderer/core/animation/keyframe_effect_options.idl
index 6146f880056..0df789d3e3d 100644
--- a/chromium/third_party/blink/renderer/core/animation/keyframe_effect_options.idl
+++ b/chromium/third_party/blink/renderer/core/animation/keyframe_effect_options.idl
@@ -7,4 +7,5 @@
dictionary KeyframeEffectOptions : EffectTiming {
// TODO(alancutter): Implement iterationComposite
CompositeOperation composite = "replace";
+ CSSOMString? pseudoElement = null;
};
diff --git a/chromium/third_party/blink/renderer/core/animation/keyframe_effect_test.cc b/chromium/third_party/blink/renderer/core/animation/keyframe_effect_test.cc
index 2223f1590a2..6c17ea87b02 100644
--- a/chromium/third_party/blink/renderer/core/animation/keyframe_effect_test.cc
+++ b/chromium/third_party/blink/renderer/core/animation/keyframe_effect_test.cc
@@ -9,15 +9,15 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/unrestricted_double_or_keyframe_effect_options.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_effect_timing.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_keyframe_effect_options.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
+#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_clock.h"
#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/effect_timing.h"
#include "third_party/blink/renderer/core/animation/keyframe_effect_model.h"
-#include "third_party/blink/renderer/core/animation/optional_effect_timing.h"
#include "third_party/blink/renderer/core/animation/timing.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
@@ -138,11 +138,11 @@ TEST_F(AnimationKeyframeEffectV8Test, CanCreateAnAnimation) {
EXPECT_EQ(1, keyframes[1]->CheckedOffset());
const CSSValue& keyframe1_width =
- ToStringKeyframe(keyframes[0])
- ->CssPropertyValue(PropertyHandle(GetCSSPropertyWidth()));
+ To<StringKeyframe>(*keyframes[0])
+ .CssPropertyValue(PropertyHandle(GetCSSPropertyWidth()));
const CSSValue& keyframe2_width =
- ToStringKeyframe(keyframes[1])
- ->CssPropertyValue(PropertyHandle(GetCSSPropertyWidth()));
+ To<StringKeyframe>(*keyframes[1])
+ .CssPropertyValue(PropertyHandle(GetCSSPropertyWidth()));
EXPECT_EQ("100px", keyframe1_width.CssText());
EXPECT_EQ("0px", keyframe2_width.CssText());
@@ -163,9 +163,8 @@ TEST_F(AnimationKeyframeEffectV8Test, SetAndRetrieveEffectComposite) {
SetV8ObjectPropertyAsString(scope.GetIsolate(), effect_options, "composite",
"add");
KeyframeEffectOptions* effect_options_dictionary =
- KeyframeEffectOptions::Create();
- V8KeyframeEffectOptions::ToImpl(scope.GetIsolate(), effect_options,
- effect_options_dictionary, exception_state);
+ NativeValueTraits<KeyframeEffectOptions>::NativeValue(
+ scope.GetIsolate(), effect_options, exception_state);
EXPECT_FALSE(exception_state.HadException());
ScriptValue js_keyframes = ScriptValue::CreateNull(scope.GetIsolate());
@@ -189,9 +188,8 @@ TEST_F(AnimationKeyframeEffectV8Test, KeyframeCompositeOverridesEffect) {
SetV8ObjectPropertyAsString(scope.GetIsolate(), effect_options, "composite",
"add");
KeyframeEffectOptions* effect_options_dictionary =
- KeyframeEffectOptions::Create();
- V8KeyframeEffectOptions::ToImpl(scope.GetIsolate(), effect_options,
- effect_options_dictionary, exception_state);
+ NativeValueTraits<KeyframeEffectOptions>::NativeValue(
+ scope.GetIsolate(), effect_options, exception_state);
EXPECT_FALSE(exception_state.HadException());
HeapVector<ScriptValue> blink_keyframes = {
@@ -258,11 +256,10 @@ TEST_F(AnimationKeyframeEffectV8Test, SpecifiedGetters) {
"reverse");
SetV8ObjectPropertyAsString(scope.GetIsolate(), timing_input, "easing",
"ease-in-out");
- KeyframeEffectOptions* timing_input_dictionary =
- KeyframeEffectOptions::Create();
DummyExceptionStateForTesting exception_state;
- V8KeyframeEffectOptions::ToImpl(scope.GetIsolate(), timing_input,
- timing_input_dictionary, exception_state);
+ KeyframeEffectOptions* timing_input_dictionary =
+ NativeValueTraits<KeyframeEffectOptions>::NativeValue(
+ scope.GetIsolate(), timing_input, exception_state);
EXPECT_FALSE(exception_state.HadException());
KeyframeEffect* animation = CreateAnimationFromOption(
@@ -287,12 +284,10 @@ TEST_F(AnimationKeyframeEffectV8Test, SpecifiedDurationGetter) {
v8::Object::New(scope.GetIsolate());
SetV8ObjectPropertyAsNumber(scope.GetIsolate(), timing_input_with_duration,
"duration", 2.5);
- KeyframeEffectOptions* timing_input_dictionary_with_duration =
- KeyframeEffectOptions::Create();
DummyExceptionStateForTesting exception_state;
- V8KeyframeEffectOptions::ToImpl(
- scope.GetIsolate(), timing_input_with_duration,
- timing_input_dictionary_with_duration, exception_state);
+ KeyframeEffectOptions* timing_input_dictionary_with_duration =
+ NativeValueTraits<KeyframeEffectOptions>::NativeValue(
+ scope.GetIsolate(), timing_input_with_duration, exception_state);
EXPECT_FALSE(exception_state.HadException());
KeyframeEffect* animation_with_duration =
@@ -308,10 +303,8 @@ TEST_F(AnimationKeyframeEffectV8Test, SpecifiedDurationGetter) {
v8::Local<v8::Object> timing_input_no_duration =
v8::Object::New(scope.GetIsolate());
KeyframeEffectOptions* timing_input_dictionary_no_duration =
- KeyframeEffectOptions::Create();
- V8KeyframeEffectOptions::ToImpl(scope.GetIsolate(), timing_input_no_duration,
- timing_input_dictionary_no_duration,
- exception_state);
+ NativeValueTraits<KeyframeEffectOptions>::NativeValue(
+ scope.GetIsolate(), timing_input_no_duration, exception_state);
EXPECT_FALSE(exception_state.HadException());
KeyframeEffect* animation_no_duration =
@@ -326,16 +319,18 @@ TEST_F(AnimationKeyframeEffectV8Test, SpecifiedDurationGetter) {
}
TEST_F(AnimationKeyframeEffectV8Test, SetKeyframesAdditiveCompositeOperation) {
- ScopedCSSAdditiveAnimationsForTest css_additive_animation(false);
+ // AnimationWorklet also needs to be disabled since it depends on
+ // WebAnimationsAPI and prevents us from turning it off if enabled.
+ ScopedAnimationWorkletForTest no_animation_worklet(false);
+ ScopedWebAnimationsAPIForTest no_web_animations(false);
V8TestingScope scope;
ScriptState* script_state = scope.GetScriptState();
ScriptValue js_keyframes = ScriptValue::CreateNull(scope.GetIsolate());
v8::Local<v8::Object> timing_input = v8::Object::New(scope.GetIsolate());
- KeyframeEffectOptions* timing_input_dictionary =
- KeyframeEffectOptions::Create();
DummyExceptionStateForTesting exception_state;
- V8KeyframeEffectOptions::ToImpl(scope.GetIsolate(), timing_input,
- timing_input_dictionary, exception_state);
+ KeyframeEffectOptions* timing_input_dictionary =
+ NativeValueTraits<KeyframeEffectOptions>::NativeValue(
+ scope.GetIsolate(), timing_input, exception_state);
ASSERT_FALSE(exception_state.HadException());
// Since there are no CSS-targeting keyframes, we can create a KeyframeEffect
diff --git a/chromium/third_party/blink/renderer/core/animation/list_interpolation_functions.cc b/chromium/third_party/blink/renderer/core/animation/list_interpolation_functions.cc
index 146f840c0e8..67aa7437a29 100644
--- a/chromium/third_party/blink/renderer/core/animation/list_interpolation_functions.cc
+++ b/chromium/third_party/blink/renderer/core/animation/list_interpolation_functions.cc
@@ -32,16 +32,16 @@ class UnderlyingItemValue : public UnderlyingValue {
: underlying_list_(underlying_list), builder_(builder), index_(index) {}
InterpolableValue& MutableInterpolableValue() final {
- return *ToInterpolableList(underlying_list_.MutableInterpolableValue())
+ return *To<InterpolableList>(underlying_list_.MutableInterpolableValue())
.GetMutable(index_);
}
void SetInterpolableValue(
std::unique_ptr<InterpolableValue> interpolable_value) final {
- ToInterpolableList(underlying_list_.MutableInterpolableValue())
+ To<InterpolableList>(underlying_list_.MutableInterpolableValue())
.Set(index_, std::move(interpolable_value));
}
const NonInterpolableValue* GetNonInterpolableValue() const final {
- return ToNonInterpolableList(*underlying_list_.GetNonInterpolableValue())
+ return To<NonInterpolableList>(*underlying_list_.GetNonInterpolableValue())
.Get(index_);
}
void SetNonInterpolableValue(
@@ -65,10 +65,8 @@ bool ListInterpolationFunctions::EqualValues(
if (!a || !b)
return false;
- const InterpolableList& interpolable_list_a =
- ToInterpolableList(*a.interpolable_value);
- const InterpolableList& interpolable_list_b =
- ToInterpolableList(*b.interpolable_value);
+ const auto& interpolable_list_a = To<InterpolableList>(*a.interpolable_value);
+ const auto& interpolable_list_b = To<InterpolableList>(*b.interpolable_value);
if (interpolable_list_a.length() != interpolable_list_b.length())
return false;
@@ -77,10 +75,10 @@ bool ListInterpolationFunctions::EqualValues(
if (length == 0)
return true;
- const NonInterpolableList& non_interpolable_list_a =
- ToNonInterpolableList(*a.non_interpolable_value);
- const NonInterpolableList& non_interpolable_list_b =
- ToNonInterpolableList(*b.non_interpolable_value);
+ const auto& non_interpolable_list_a =
+ To<NonInterpolableList>(*a.non_interpolable_value);
+ const auto& non_interpolable_list_b =
+ To<NonInterpolableList>(*b.non_interpolable_value);
for (wtf_size_t i = 0; i < length; i++) {
if (!equal_non_interpolable_values(non_interpolable_list_a.Get(i),
@@ -123,9 +121,9 @@ PairwiseInterpolationValue ListInterpolationFunctions::MaybeMergeSingles(
LengthMatchingStrategy length_matching_strategy,
MergeSingleItemConversionsCallback merge_single_item_conversions) {
const wtf_size_t start_length =
- ToInterpolableList(*start.interpolable_value).length();
+ To<InterpolableList>(*start.interpolable_value).length();
const wtf_size_t end_length =
- ToInterpolableList(*end.interpolable_value).length();
+ To<InterpolableList>(*end.interpolable_value).length();
if (length_matching_strategy ==
ListInterpolationFunctions::LengthMatchingStrategy::kEqual &&
@@ -164,25 +162,31 @@ PairwiseInterpolationValue ListInterpolationFunctions::MaybeMergeSingles(
Vector<scoped_refptr<const NonInterpolableValue>>
result_non_interpolable_values(final_length);
- InterpolableList& start_interpolable_list =
- ToInterpolableList(*start.interpolable_value);
- InterpolableList& end_interpolable_list =
- ToInterpolableList(*end.interpolable_value);
- const NonInterpolableList& start_non_interpolable_list =
- ToNonInterpolableList(*start.non_interpolable_value);
- const NonInterpolableList& end_non_interpolable_list =
- ToNonInterpolableList(*end.non_interpolable_value);
-
+ auto& start_interpolable_list =
+ To<InterpolableList>(*start.interpolable_value);
+ auto& end_interpolable_list = To<InterpolableList>(*end.interpolable_value);
+ const auto* start_non_interpolable_list =
+ To<NonInterpolableList>(start.non_interpolable_value.get());
+ const auto* end_non_interpolable_list =
+ To<NonInterpolableList>(end.non_interpolable_value.get());
+ const wtf_size_t start_non_interpolable_length =
+ start_non_interpolable_list ? start_non_interpolable_list->length() : 0;
+ const wtf_size_t end_non_interpolable_length =
+ end_non_interpolable_list ? end_non_interpolable_list->length() : 0;
for (wtf_size_t i = 0; i < final_length; i++) {
if (length_matching_strategy ==
LengthMatchingStrategy::kLowestCommonMultiple ||
(i < start_length && i < end_length)) {
InterpolationValue start_merge(
start_interpolable_list.Get(i % start_length)->Clone(),
- start_non_interpolable_list.Get(i % start_length));
+ start_non_interpolable_list ? start_non_interpolable_list->Get(
+ i % start_non_interpolable_length)
+ : nullptr);
InterpolationValue end_merge(
end_interpolable_list.Get(i % end_length)->Clone(),
- end_non_interpolable_list.Get(i % end_length));
+ end_non_interpolable_list
+ ? end_non_interpolable_list->Get(i % end_non_interpolable_length)
+ : nullptr);
PairwiseInterpolationValue result = merge_single_item_conversions.Run(
std::move(start_merge), std::move(end_merge));
if (!result)
@@ -201,18 +205,23 @@ PairwiseInterpolationValue ListInterpolationFunctions::MaybeMergeSingles(
i, start_interpolable_list.Get(i)->Clone());
result_end_interpolable_list->Set(
i, start_interpolable_list.Get(i)->CloneAndZero());
- result_non_interpolable_values[i] = start_non_interpolable_list.Get(i);
+ result_non_interpolable_values[i] =
+ (i < start_non_interpolable_length)
+ ? start_non_interpolable_list->Get(i)
+ : nullptr;
} else {
DCHECK_LT(i, end_length);
result_start_interpolable_list->Set(
i, end_interpolable_list.Get(i)->CloneAndZero());
result_end_interpolable_list->Set(
i, end_interpolable_list.Get(i)->Clone());
- result_non_interpolable_values[i] = end_non_interpolable_list.Get(i);
+ result_non_interpolable_values[i] =
+ (i < end_non_interpolable_length)
+ ? end_non_interpolable_list->Get(i)
+ : nullptr;
}
}
}
-
return PairwiseInterpolationValue(
std::move(result_start_interpolable_list),
std::move(result_end_interpolable_list),
@@ -220,10 +229,9 @@ PairwiseInterpolationValue ListInterpolationFunctions::MaybeMergeSingles(
}
static void RepeatToLength(InterpolationValue& value, wtf_size_t length) {
- InterpolableList& interpolable_list =
- ToInterpolableList(*value.interpolable_value);
- const NonInterpolableList& non_interpolable_list =
- ToNonInterpolableList(*value.non_interpolable_value);
+ auto& interpolable_list = To<InterpolableList>(*value.interpolable_value);
+ const auto& non_interpolable_list =
+ To<NonInterpolableList>(*value.non_interpolable_value);
wtf_size_t current_length = interpolable_list.length();
DCHECK_GT(current_length, 0U);
if (current_length == length)
@@ -249,15 +257,14 @@ static void RepeatToLength(InterpolationValue& value, wtf_size_t length) {
// CloneAndZero-ing the additional items from length_value into value.
static void PadToSameLength(InterpolationValue& value,
const InterpolationValue& length_value) {
- InterpolableList& interpolable_list =
- ToInterpolableList(*value.interpolable_value);
- const NonInterpolableList& non_interpolable_list =
- ToNonInterpolableList(*value.non_interpolable_value);
+ auto& interpolable_list = To<InterpolableList>(*value.interpolable_value);
+ const auto& non_interpolable_list =
+ To<NonInterpolableList>(*value.non_interpolable_value);
const wtf_size_t current_length = interpolable_list.length();
- InterpolableList& target_interpolable_list =
- ToInterpolableList(*length_value.interpolable_value);
- const NonInterpolableList& target_non_interpolable_list =
- ToNonInterpolableList(*length_value.non_interpolable_value);
+ auto& target_interpolable_list =
+ To<InterpolableList>(*length_value.interpolable_value);
+ const auto& target_non_interpolable_list =
+ To<NonInterpolableList>(*length_value.non_interpolable_value);
const wtf_size_t target_length = target_interpolable_list.length();
DCHECK_LT(current_length, target_length);
auto new_interpolable_list =
@@ -341,11 +348,11 @@ void ListInterpolationFunctions::Composite(
non_interpolable_values_are_compatible,
CompositeItemCallback composite_item) {
const wtf_size_t underlying_length =
- ToInterpolableList(*underlying_value_owner.Value().interpolable_value)
+ To<InterpolableList>(*underlying_value_owner.Value().interpolable_value)
.length();
- const InterpolableList& interpolable_list =
- ToInterpolableList(*value.interpolable_value);
+ const auto& interpolable_list =
+ To<InterpolableList>(*value.interpolable_value);
const wtf_size_t value_length = interpolable_list.length();
if (length_matching_strategy ==
@@ -372,7 +379,7 @@ void ListInterpolationFunctions::Composite(
MatchLengths(underlying_length, value_length, length_matching_strategy);
if (!InterpolableListsAreCompatible(
- ToInterpolableList(
+ To<InterpolableList>(
*underlying_value_owner.Value().interpolable_value),
interpolable_list, final_length, length_matching_strategy,
interpolable_values_are_compatible)) {
@@ -380,10 +387,10 @@ void ListInterpolationFunctions::Composite(
return;
}
- const NonInterpolableList& non_interpolable_list =
- ToNonInterpolableList(*value.non_interpolable_value);
+ const auto& non_interpolable_list =
+ To<NonInterpolableList>(*value.non_interpolable_value);
if (!NonInterpolableListsAreCompatible(
- ToNonInterpolableList(
+ To<NonInterpolableList>(
*underlying_value_owner.Value().non_interpolable_value),
non_interpolable_list, final_length, length_matching_strategy,
non_interpolable_values_are_compatible)) {
@@ -414,8 +421,8 @@ void ListInterpolationFunctions::Composite(
DCHECK_EQ(value_length, final_length);
PadToSameLength(underlying_value, value);
}
- InterpolableList& underlying_interpolable_list =
- ToInterpolableList(*underlying_value.interpolable_value);
+ auto& underlying_interpolable_list =
+ To<InterpolableList>(*underlying_value.interpolable_value);
NonInterpolableList::AutoBuilder builder(underlying_value_owner);
@@ -434,7 +441,7 @@ void ListInterpolationFunctions::Composite(
NonInterpolableList::AutoBuilder::AutoBuilder(UnderlyingValue& underlying_value)
: underlying_value_(underlying_value) {
DCHECK(underlying_value.GetNonInterpolableValue());
- DCHECK(IsNonInterpolableList(underlying_value_.GetNonInterpolableValue()));
+ DCHECK(IsA<NonInterpolableList>(underlying_value_.GetNonInterpolableValue()));
}
NonInterpolableList::AutoBuilder::~AutoBuilder() {
@@ -443,7 +450,7 @@ NonInterpolableList::AutoBuilder::~AutoBuilder() {
if (!list_.size())
return;
const auto& non_interpolable_list =
- ToNonInterpolableList(*underlying_value_.GetNonInterpolableValue());
+ To<NonInterpolableList>(*underlying_value_.GetNonInterpolableValue());
DCHECK_EQ(non_interpolable_list.length(), list_.size());
underlying_value_.SetNonInterpolableValue(
NonInterpolableList::Create(std::move(list_)));
@@ -455,7 +462,7 @@ void NonInterpolableList::AutoBuilder::Set(
// Copy list on first call to Set.
if (!list_.size()) {
const auto& non_interpolable_list =
- ToNonInterpolableList(*underlying_value_.GetNonInterpolableValue());
+ To<NonInterpolableList>(*underlying_value_.GetNonInterpolableValue());
wtf_size_t underlying_length = non_interpolable_list.length();
for (wtf_size_t i = 0; i < underlying_length; ++i)
list_.push_back(non_interpolable_list.Get(i));
diff --git a/chromium/third_party/blink/renderer/core/animation/list_interpolation_functions.h b/chromium/third_party/blink/renderer/core/animation/list_interpolation_functions.h
index 1cd58ff70ef..82d035e4a71 100644
--- a/chromium/third_party/blink/renderer/core/animation/list_interpolation_functions.h
+++ b/chromium/third_party/blink/renderer/core/animation/list_interpolation_functions.h
@@ -128,7 +128,15 @@ class CORE_EXPORT NonInterpolableList : public NonInterpolableValue {
Vector<scoped_refptr<const NonInterpolableValue>> list_;
};
-DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(NonInterpolableList);
+template <>
+struct DowncastTraits<NonInterpolableList> {
+ static bool AllowFrom(const NonInterpolableValue* value) {
+ return value && AllowFrom(*value);
+ }
+ static bool AllowFrom(const NonInterpolableValue& value) {
+ return value.GetType() == NonInterpolableList::static_type_;
+ }
+};
template <typename CreateItemCallback>
InterpolationValue ListInterpolationFunctions::CreateList(
diff --git a/chromium/third_party/blink/renderer/core/animation/list_interpolation_functions_test.cc b/chromium/third_party/blink/renderer/core/animation/list_interpolation_functions_test.cc
index 23ac9fa3caa..09218341b00 100644
--- a/chromium/third_party/blink/renderer/core/animation/list_interpolation_functions_test.cc
+++ b/chromium/third_party/blink/renderer/core/animation/list_interpolation_functions_test.cc
@@ -219,12 +219,12 @@ TEST(ListInterpolationFunctionsTest, EqualCompositeSameLengths) {
WTF::BindRepeating(NonInterpolableValuesAreCompatible),
WTF::BindRepeating(Composite));
- const auto& result = ToInterpolableList(*owner.Value().interpolable_value);
+ const auto& result = To<InterpolableList>(*owner.Value().interpolable_value);
ASSERT_EQ(result.length(), 3u);
- EXPECT_EQ(ToInterpolableNumber(result.Get(0))->Value(), 2.0);
- EXPECT_EQ(ToInterpolableNumber(result.Get(1))->Value(), 4.0);
- EXPECT_EQ(ToInterpolableNumber(result.Get(2))->Value(), 6.0);
+ EXPECT_EQ(To<InterpolableNumber>(result.Get(0))->Value(), 2.0);
+ EXPECT_EQ(To<InterpolableNumber>(result.Get(1))->Value(), 4.0);
+ EXPECT_EQ(To<InterpolableNumber>(result.Get(2))->Value(), 6.0);
}
// Two lists of different lengths are not interpolable, so we expect the
@@ -246,11 +246,11 @@ TEST(ListInterpolationFunctionsTest, EqualCompositeDifferentLengths) {
WTF::BindRepeating(NonInterpolableValuesAreCompatible),
WTF::BindRepeating(Composite));
- const auto& result = ToInterpolableList(*owner.Value().interpolable_value);
+ const auto& result = To<InterpolableList>(*owner.Value().interpolable_value);
ASSERT_EQ(result.length(), 2u);
- EXPECT_EQ(ToInterpolableNumber(result.Get(0))->Value(), 4.0);
- EXPECT_EQ(ToInterpolableNumber(result.Get(1))->Value(), 5.0);
+ EXPECT_EQ(To<InterpolableNumber>(result.Get(0))->Value(), 4.0);
+ EXPECT_EQ(To<InterpolableNumber>(result.Get(1))->Value(), 5.0);
}
// If one (or more) of the element pairs are incompatible, the list as a whole
@@ -276,12 +276,12 @@ TEST(ListInterpolationFunctionsTest,
WTF::BindRepeating(NonInterpolableValuesAreCompatible),
WTF::BindRepeating(Composite));
- const auto& result = ToInterpolableList(*owner.Value().interpolable_value);
+ const auto& result = To<InterpolableList>(*owner.Value().interpolable_value);
ASSERT_EQ(result.length(), 3u);
- EXPECT_EQ(ToInterpolableNumber(result.Get(0))->Value(), 4.0);
- EXPECT_EQ(ToInterpolableNumber(result.Get(1))->Value(), 5.0);
- EXPECT_EQ(ToInterpolableNumber(result.Get(2))->Value(), 6.0);
+ EXPECT_EQ(To<InterpolableNumber>(result.Get(0))->Value(), 4.0);
+ EXPECT_EQ(To<InterpolableNumber>(result.Get(1))->Value(), 5.0);
+ EXPECT_EQ(To<InterpolableNumber>(result.Get(2))->Value(), 6.0);
}
// If one (or more) of the element pairs are incompatible, the list as a whole
@@ -304,24 +304,24 @@ TEST(ListInterpolationFunctionsTest,
WTF::BindRepeating(NonInterpolableValuesAreCompatible),
WTF::BindRepeating(Composite));
- const auto& result = ToInterpolableList(*owner.Value().interpolable_value);
+ const auto& result = To<InterpolableList>(*owner.Value().interpolable_value);
ASSERT_EQ(result.length(), 3u);
- EXPECT_EQ(ToInterpolableNumber(result.Get(0))->Value(), 4.0);
- EXPECT_EQ(ToInterpolableNumber(result.Get(1))->Value(), 5.0);
- EXPECT_EQ(ToInterpolableNumber(result.Get(2))->Value(), 6.0);
+ EXPECT_EQ(To<InterpolableNumber>(result.Get(0))->Value(), 4.0);
+ EXPECT_EQ(To<InterpolableNumber>(result.Get(1))->Value(), 5.0);
+ EXPECT_EQ(To<InterpolableNumber>(result.Get(2))->Value(), 6.0);
}
TEST(ListInterpolationFunctionsTest, BuilderNoModify) {
auto list = CreateNonInterpolableList({1, 2, 3});
- auto& before = ToNonInterpolableList(*list.non_interpolable_value);
+ auto& before = To<NonInterpolableList>(*list.non_interpolable_value);
{
TestUnderlyingValue underlying_value(list);
NonInterpolableList::AutoBuilder builder(underlying_value);
}
- auto& after = ToNonInterpolableList(*list.non_interpolable_value);
+ auto& after = To<NonInterpolableList>(*list.non_interpolable_value);
EXPECT_EQ(&before, &after);
ASSERT_EQ(3u, before.length());
@@ -332,7 +332,7 @@ TEST(ListInterpolationFunctionsTest, BuilderNoModify) {
TEST(ListInterpolationFunctionsTest, BuilderModifyFirst) {
auto list = CreateNonInterpolableList({1, 2, 3});
- auto& before = ToNonInterpolableList(*list.non_interpolable_value);
+ auto& before = To<NonInterpolableList>(*list.non_interpolable_value);
{
TestUnderlyingValue underlying_value(list);
@@ -340,7 +340,7 @@ TEST(ListInterpolationFunctionsTest, BuilderModifyFirst) {
builder.Set(0, TestNonInterpolableValue::Create(4));
}
- auto& after = ToNonInterpolableList(*list.non_interpolable_value);
+ auto& after = To<NonInterpolableList>(*list.non_interpolable_value);
EXPECT_NE(&before, &after);
ASSERT_EQ(3u, after.length());
@@ -351,7 +351,7 @@ TEST(ListInterpolationFunctionsTest, BuilderModifyFirst) {
TEST(ListInterpolationFunctionsTest, BuilderModifyMiddle) {
auto list = CreateNonInterpolableList({1, 2, 3});
- auto& before = ToNonInterpolableList(*list.non_interpolable_value);
+ auto& before = To<NonInterpolableList>(*list.non_interpolable_value);
{
TestUnderlyingValue underlying_value(list);
@@ -359,7 +359,7 @@ TEST(ListInterpolationFunctionsTest, BuilderModifyMiddle) {
builder.Set(1, TestNonInterpolableValue::Create(4));
}
- auto& after = ToNonInterpolableList(*list.non_interpolable_value);
+ auto& after = To<NonInterpolableList>(*list.non_interpolable_value);
EXPECT_NE(&before, &after);
ASSERT_EQ(3u, after.length());
@@ -370,7 +370,7 @@ TEST(ListInterpolationFunctionsTest, BuilderModifyMiddle) {
TEST(ListInterpolationFunctionsTest, BuilderModifyLast) {
auto list = CreateNonInterpolableList({1, 2, 3});
- auto& before = ToNonInterpolableList(*list.non_interpolable_value);
+ auto& before = To<NonInterpolableList>(*list.non_interpolable_value);
{
TestUnderlyingValue underlying_value(list);
@@ -378,7 +378,7 @@ TEST(ListInterpolationFunctionsTest, BuilderModifyLast) {
builder.Set(2, TestNonInterpolableValue::Create(4));
}
- auto& after = ToNonInterpolableList(*list.non_interpolable_value);
+ auto& after = To<NonInterpolableList>(*list.non_interpolable_value);
EXPECT_NE(&before, &after);
ASSERT_EQ(3u, after.length());
@@ -389,7 +389,7 @@ TEST(ListInterpolationFunctionsTest, BuilderModifyLast) {
TEST(ListInterpolationFunctionsTest, BuilderModifyAll) {
auto list = CreateNonInterpolableList({1, 2, 3});
- auto& before = ToNonInterpolableList(*list.non_interpolable_value);
+ auto& before = To<NonInterpolableList>(*list.non_interpolable_value);
{
TestUnderlyingValue underlying_value(list);
@@ -399,7 +399,7 @@ TEST(ListInterpolationFunctionsTest, BuilderModifyAll) {
builder.Set(2, TestNonInterpolableValue::Create(6));
}
- auto& after = ToNonInterpolableList(*list.non_interpolable_value);
+ auto& after = To<NonInterpolableList>(*list.non_interpolable_value);
EXPECT_NE(&before, &after);
ASSERT_EQ(3u, after.length());
@@ -410,7 +410,7 @@ TEST(ListInterpolationFunctionsTest, BuilderModifyAll) {
TEST(ListInterpolationFunctionsTest, BuilderModifyReverse) {
auto list = CreateNonInterpolableList({1, 2, 3, 4, 5});
- auto& before = ToNonInterpolableList(*list.non_interpolable_value);
+ auto& before = To<NonInterpolableList>(*list.non_interpolable_value);
{
TestUnderlyingValue underlying_value(list);
@@ -419,7 +419,7 @@ TEST(ListInterpolationFunctionsTest, BuilderModifyReverse) {
builder.Set(1, TestNonInterpolableValue::Create(7));
}
- auto& after = ToNonInterpolableList(*list.non_interpolable_value);
+ auto& after = To<NonInterpolableList>(*list.non_interpolable_value);
EXPECT_NE(&before, &after);
ASSERT_EQ(5u, after.length());
@@ -432,7 +432,7 @@ TEST(ListInterpolationFunctionsTest, BuilderModifyReverse) {
TEST(ListInterpolationFunctionsTest, BuilderModifyListWithOneItem) {
auto list = CreateNonInterpolableList({1});
- auto& before = ToNonInterpolableList(*list.non_interpolable_value);
+ auto& before = To<NonInterpolableList>(*list.non_interpolable_value);
{
TestUnderlyingValue underlying_value(list);
@@ -440,7 +440,7 @@ TEST(ListInterpolationFunctionsTest, BuilderModifyListWithOneItem) {
builder.Set(0, TestNonInterpolableValue::Create(4));
}
- auto& after = ToNonInterpolableList(*list.non_interpolable_value);
+ auto& after = To<NonInterpolableList>(*list.non_interpolable_value);
EXPECT_NE(&before, &after);
EXPECT_EQ(4, ToTestNonInterpolableValue(*after.Get(0)).GetValue());
diff --git a/chromium/third_party/blink/renderer/core/animation/non_interpolable_value.h b/chromium/third_party/blink/renderer/core/animation/non_interpolable_value.h
index a570f8aa8e3..0e6e9ef8948 100644
--- a/chromium/third_party/blink/renderer/core/animation/non_interpolable_value.h
+++ b/chromium/third_party/blink/renderer/core/animation/non_interpolable_value.h
@@ -29,12 +29,6 @@ class NonInterpolableValue : public RefCounted<NonInterpolableValue> {
#define DEFINE_NON_INTERPOLABLE_VALUE_TYPE(T) \
NonInterpolableValue::Type T::static_type_ = &T::static_type_
-#define DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(T) \
- inline bool Is##T(const NonInterpolableValue* value) { \
- return !value || value->GetType() == T::static_type_; \
- } \
- DEFINE_TYPE_CASTS(T, NonInterpolableValue, value, Is##T(value), Is##T(&value))
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_NON_INTERPOLABLE_VALUE_H_
diff --git a/chromium/third_party/blink/renderer/core/animation/path_interpolation_functions.cc b/chromium/third_party/blink/renderer/core/animation/path_interpolation_functions.cc
index 3260e29303b..4331bcc6f5c 100644
--- a/chromium/third_party/blink/renderer/core/animation/path_interpolation_functions.cc
+++ b/chromium/third_party/blink/renderer/core/animation/path_interpolation_functions.cc
@@ -41,7 +41,15 @@ class SVGPathNonInterpolableValue : public NonInterpolableValue {
};
DEFINE_NON_INTERPOLABLE_VALUE_TYPE(SVGPathNonInterpolableValue);
-DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(SVGPathNonInterpolableValue);
+template <>
+struct DowncastTraits<SVGPathNonInterpolableValue> {
+ static bool AllowFrom(const NonInterpolableValue* value) {
+ return value && AllowFrom(*value);
+ }
+ static bool AllowFrom(const NonInterpolableValue& value) {
+ return value.GetType() == SVGPathNonInterpolableValue::static_type_;
+ }
+};
enum PathComponentIndex : unsigned {
kPathArgsIndex,
@@ -110,7 +118,7 @@ class UnderlyingPathSegTypesChecker
static const Vector<SVGPathSegType>& GetPathSegTypes(
const InterpolationValue& underlying) {
- return ToSVGPathNonInterpolableValue(*underlying.non_interpolable_value)
+ return To<SVGPathNonInterpolableValue>(*underlying.non_interpolable_value)
.PathSegTypes();
}
@@ -128,9 +136,10 @@ InterpolationValue PathInterpolationFunctions::MaybeConvertNeutral(
conversion_checkers.push_back(
UnderlyingPathSegTypesChecker::Create(underlying));
auto result = std::make_unique<InterpolableList>(kPathComponentIndexCount);
- result->Set(kPathArgsIndex, ToInterpolableList(*underlying.interpolable_value)
- .Get(kPathArgsIndex)
- ->CloneAndZero());
+ result->Set(kPathArgsIndex,
+ To<InterpolableList>(*underlying.interpolable_value)
+ .Get(kPathArgsIndex)
+ ->CloneAndZero());
result->Set(kPathNeutralIndex, std::make_unique<InterpolableNumber>(1));
return InterpolationValue(std::move(result),
underlying.non_interpolable_value.get());
@@ -153,10 +162,11 @@ PairwiseInterpolationValue PathInterpolationFunctions::MaybeMergeSingles(
InterpolationValue&& start,
InterpolationValue&& end) {
const Vector<SVGPathSegType>& start_types =
- ToSVGPathNonInterpolableValue(*start.non_interpolable_value)
+ To<SVGPathNonInterpolableValue>(*start.non_interpolable_value)
.PathSegTypes();
const Vector<SVGPathSegType>& end_types =
- ToSVGPathNonInterpolableValue(*end.non_interpolable_value).PathSegTypes();
+ To<SVGPathNonInterpolableValue>(*end.non_interpolable_value)
+ .PathSegTypes();
if (start_types.size() == 0 || !PathSegTypesMatch(start_types, end_types))
return nullptr;
@@ -170,9 +180,9 @@ void PathInterpolationFunctions::Composite(
double underlying_fraction,
const InterpolationType& type,
const InterpolationValue& value) {
- const InterpolableList& list = ToInterpolableList(*value.interpolable_value);
+ const auto& list = To<InterpolableList>(*value.interpolable_value);
double neutral_component =
- ToInterpolableNumber(list.Get(kPathNeutralIndex))->Value();
+ To<InterpolableNumber>(list.Get(kPathNeutralIndex))->Value();
if (neutral_component == 0) {
underlying_value_owner.Set(type, value);
@@ -180,10 +190,10 @@ void PathInterpolationFunctions::Composite(
}
DCHECK(PathSegTypesMatch(
- ToSVGPathNonInterpolableValue(
+ To<SVGPathNonInterpolableValue>(
*underlying_value_owner.Value().non_interpolable_value)
.PathSegTypes(),
- ToSVGPathNonInterpolableValue(*value.non_interpolable_value)
+ To<SVGPathNonInterpolableValue>(*value.non_interpolable_value)
.PathSegTypes()));
underlying_value_owner.MutableValue().interpolable_value->ScaleAndAdd(
neutral_component, *value.interpolable_value);
@@ -197,9 +207,9 @@ std::unique_ptr<SVGPathByteStream> PathInterpolationFunctions::AppliedValue(
std::unique_ptr<SVGPathByteStream> path_byte_stream =
std::make_unique<SVGPathByteStream>();
InterpolatedSVGPathSource source(
- ToInterpolableList(
- *ToInterpolableList(interpolable_value).Get(kPathArgsIndex)),
- ToSVGPathNonInterpolableValue(non_interpolable_value)->PathSegTypes());
+ To<InterpolableList>(
+ *To<InterpolableList>(interpolable_value).Get(kPathArgsIndex)),
+ To<SVGPathNonInterpolableValue>(non_interpolable_value)->PathSegTypes());
SVGPathByteStreamBuilder builder(*path_byte_stream);
svg_path_parser::ParsePath(source, builder);
return path_byte_stream;
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 a0aae084ca5..bdc657ed8b6 100644
--- a/chromium/third_party/blink/renderer/core/animation/pending_animations.cc
+++ b/chromium/third_party/blink/renderer/core/animation/pending_animations.cc
@@ -49,7 +49,14 @@ void PendingAnimations::Add(Animation* animation) {
document->View()->ScheduleAnimation();
bool visible = document->GetPage() && document->GetPage()->IsPageVisible();
- if (!visible && !timer_.IsActive()) {
+ if (!visible && !timer_.IsActive() &&
+ // TODO(crbug.com/916117): Firing a timer for animations linked to
+ // inactive timelines creates an unnecessary cycle of unsuccessfully
+ // starting such animations. Instead, let the animation frame call
+ // PendingAnimations::Update when the timeline becomes active.
+ // Revisit this condition and add a test as part of inactive timeline
+ // implementation.
+ animation->timeline() && animation->timeline()->IsActive()) {
timer_.StartOneShot(base::TimeDelta(), FROM_HERE);
}
}
@@ -73,16 +80,21 @@ bool PendingAnimations::Update(
if (animation->PreCommit(animation->startTime() ? 1 : compositor_group,
paint_artifact_compositor, start_on_compositor)) {
if (animation->HasActiveAnimationsOnCompositor() &&
- !had_compositor_animation) {
+ !had_compositor_animation && !animation->startTime()) {
started_synchronized_on_compositor = true;
}
- if (!animation->timeline() || !animation->timeline()->IsActive())
+ // TODO(crbug.com/916117): Revisit this condition as part of handling
+ // inactive timelines work.
+ if (!animation->timeline() || !animation->timeline()->IsActive()) {
+ DCHECK(!animation->timeline() ||
+ !animation->timeline()->IsScrollTimeline());
continue;
+ }
if (animation->Playing() && !animation->startTime()) {
waiting_for_start_time.push_back(animation.Get());
- } else if (animation->pending()) {
+ } else if (animation->PendingInternal()) {
// A pending animation that is not waiting on a start time does not need
// to be synchronized with animations that are starting up. Nonetheless,
// it needs to notify the animation to resolve the ready promise and
@@ -99,6 +111,7 @@ bool PendingAnimations::Update(
// remaining synchronized animations need to wait for the synchronized
// start time. Otherwise they may start immediately.
if (started_synchronized_on_compositor) {
+ FlushWaitingNonCompositedAnimations();
waiting_for_compositor_animation_start_.AppendVector(
waiting_for_start_time);
} else {
@@ -118,7 +131,6 @@ bool PendingAnimations::Update(
}
DCHECK(pending_.IsEmpty());
- DCHECK(start_on_compositor || deferred.IsEmpty());
for (auto& animation : deferred)
animation->SetCompositorPending();
DCHECK_EQ(pending_.size(), deferred.size());
@@ -152,7 +164,7 @@ void PendingAnimations::NotifyCompositorAnimationStarted(
animations.swap(waiting_for_compositor_animation_start_);
for (auto animation : animations) {
- if (animation->startTime() || !animation->pending() ||
+ if (animation->startTime() || !animation->PendingInternal() ||
!animation->timeline() || !animation->timeline()->IsActive()) {
// Already started or no longer relevant.
continue;
@@ -162,9 +174,9 @@ void PendingAnimations::NotifyCompositorAnimationStarted(
waiting_for_compositor_animation_start_.push_back(animation);
continue;
}
- DCHECK(animation->timeline()->IsDocumentTimeline());
+ DCHECK(IsA<DocumentTimeline>(animation->timeline()));
animation->NotifyReady(monotonic_animation_start_time -
- ToDocumentTimeline(animation->timeline())
+ To<DocumentTimeline>(animation->timeline())
->ZeroTime()
.since_origin()
.InSecondsF());
@@ -182,7 +194,29 @@ int PendingAnimations::NextCompositorGroup() {
return compositor_group_;
}
-void PendingAnimations::Trace(blink::Visitor* visitor) {
+void PendingAnimations::FlushWaitingNonCompositedAnimations() {
+ if (waiting_for_compositor_animation_start_.IsEmpty())
+ return;
+
+ // Start any main thread animations that were scheduled to wait on
+ // compositor synchronization from a previous frame. Otherwise, an
+ // continuous influx of new composited animations could delay the start
+ // of non-composited animations indefinitely (crbug.com/666710).
+ HeapVector<Member<Animation>> animations;
+ animations.swap(waiting_for_compositor_animation_start_);
+ for (auto& animation : animations) {
+ if (animation->HasActiveAnimationsOnCompositor()) {
+ waiting_for_compositor_animation_start_.push_back(animation);
+ } else {
+ // TODO(crbug.com/916117): Handle start time of scroll-linked
+ // animations.
+ animation->NotifyReady(
+ animation->timeline()->CurrentTimeSeconds().value_or(0));
+ }
+ }
+}
+
+void PendingAnimations::Trace(Visitor* visitor) {
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 b3fd5373d25..010ccffb26f 100644
--- a/chromium/third_party/blink/renderer/core/animation/pending_animations.h
+++ b/chromium/third_party/blink/renderer/core/animation/pending_animations.h
@@ -93,11 +93,12 @@ class CORE_EXPORT PendingAnimations final
void NotifyCompositorAnimationStarted(double monotonic_animation_start_time,
int compositor_group = 0);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
void TimerFired(TimerBase*) { Update(nullptr, false); }
int NextCompositorGroup();
+ void FlushWaitingNonCompositedAnimations();
HeapVector<Member<Animation>> pending_;
HeapVector<Member<Animation>> waiting_for_compositor_animation_start_;
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 89472a8b0bd..be5a56deb86 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(blink::Visitor* visitor) {
+void SampledEffect::Trace(Visitor* visitor) {
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 48ac6f9b144..8ba125df07a 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(blink::Visitor*);
+ void Trace(Visitor*);
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 d225bcf3e9b..39d1891e984 100644
--- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline.cc
+++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline.cc
@@ -4,7 +4,10 @@
#include "third_party/blink/renderer/core/animation/scroll_timeline.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_options.h"
+#include "third_party/blink/renderer/core/animation/scroll_timeline_util.h"
#include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h"
+#include "third_party/blink/renderer/core/css/parser/css_parser_context.h"
#include "third_party/blink/renderer/core/css/parser/css_tokenizer.h"
#include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
@@ -18,6 +21,14 @@
namespace blink {
namespace {
+using ScrollTimelineSet =
+ HeapHashMap<WeakMember<Node>, HeapHashSet<WeakMember<ScrollTimeline>>>;
+ScrollTimelineSet& GetScrollTimelineSet() {
+ DEFINE_STATIC_LOCAL(Persistent<ScrollTimelineSet>, set,
+ (MakeGarbageCollected<ScrollTimelineSet>()));
+ return *set;
+}
+
using ActiveScrollTimelineSet = HeapHashCountedSet<WeakMember<Node>>;
ActiveScrollTimelineSet& GetActiveScrollTimelineSet() {
DEFINE_STATIC_LOCAL(Persistent<ActiveScrollTimelineSet>, set,
@@ -46,11 +57,13 @@ bool StringToScrollDirection(String scroll_direction,
return false;
}
-bool StringToScrollOffset(String scroll_offset, CSSPrimitiveValue** result) {
+bool StringToScrollOffset(String scroll_offset,
+ const CSSParserContext& context,
+ CSSPrimitiveValue** result) {
CSSTokenizer tokenizer(scroll_offset);
const auto tokens = tokenizer.TokenizeToEOF();
CSSParserTokenRange range(tokens);
- CSSValue* value = css_parsing_utils::ConsumeScrollOffset(range);
+ CSSValue* value = css_parsing_utils::ConsumeScrollOffset(range, context);
if (!value)
return false;
@@ -79,6 +92,10 @@ ScrollTimeline* ScrollTimeline::Create(Document& document,
? options->scrollSource()
: document.scrollingElement();
+ // TODO(xiaochengh): Try reusing an existing context in document.
+ const CSSParserContext* context =
+ MakeGarbageCollected<CSSParserContext>(document);
+
ScrollDirection orientation;
if (!StringToScrollDirection(options->orientation(), orientation)) {
exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
@@ -87,14 +104,15 @@ ScrollTimeline* ScrollTimeline::Create(Document& document,
}
CSSPrimitiveValue* start_scroll_offset = nullptr;
- if (!StringToScrollOffset(options->startScrollOffset(),
+ if (!StringToScrollOffset(options->startScrollOffset(), *context,
&start_scroll_offset)) {
exception_state.ThrowTypeError("Invalid startScrollOffset");
return nullptr;
}
CSSPrimitiveValue* end_scroll_offset = nullptr;
- if (!StringToScrollOffset(options->endScrollOffset(), &end_scroll_offset)) {
+ if (!StringToScrollOffset(options->endScrollOffset(), *context,
+ &end_scroll_offset)) {
exception_state.ThrowTypeError("Invalid endScrollOffset");
return nullptr;
}
@@ -109,8 +127,7 @@ ScrollTimeline* ScrollTimeline::Create(Document& document,
return MakeGarbageCollected<ScrollTimeline>(
&document, scroll_source, orientation, start_scroll_offset,
- end_scroll_offset, options->timeRange().GetAsDouble(),
- Timing::StringToFillMode(options->fill()));
+ end_scroll_offset, options->timeRange().GetAsDouble());
}
ScrollTimeline::ScrollTimeline(Document* document,
@@ -118,38 +135,53 @@ ScrollTimeline::ScrollTimeline(Document* document,
ScrollDirection orientation,
CSSPrimitiveValue* start_scroll_offset,
CSSPrimitiveValue* end_scroll_offset,
- double time_range,
- Timing::FillMode fill)
- : document_(document),
+ double time_range)
+ : AnimationTimeline(document),
scroll_source_(scroll_source),
resolved_scroll_source_(ResolveScrollSource(scroll_source_)),
orientation_(orientation),
start_scroll_offset_(start_scroll_offset),
end_scroll_offset_(end_scroll_offset),
- time_range_(time_range),
- fill_(fill) {}
+ time_range_(time_range) {
+ if (resolved_scroll_source_) {
+ ScrollTimelineSet& set = GetScrollTimelineSet();
+ if (!set.Contains(resolved_scroll_source_)) {
+ set.insert(resolved_scroll_source_,
+ HeapHashSet<WeakMember<ScrollTimeline>>());
+ }
+ auto it = set.find(resolved_scroll_source_);
+ it->value.insert(this);
+ }
+ SnapshotState();
+}
bool ScrollTimeline::IsActive() const {
+ return phase_and_time_snapshotted_.phase != TimelinePhase::kInactive;
+}
+
+void ScrollTimeline::Invalidate() {
+ ScheduleNextService();
+}
+
+bool ScrollTimeline::ComputeIsActive() const {
LayoutBox* layout_box = resolved_scroll_source_
? resolved_scroll_source_->GetLayoutBox()
: nullptr;
- return layout_box && layout_box->HasOverflowClip();
+ return layout_box && layout_box->HasOverflowClip() &&
+ layout_box->GetScrollableArea();
}
-// Scroll-linked animations are initialized with the start time of zero.
-base::Optional<base::TimeDelta>
-ScrollTimeline::InitialStartTimeForAnimations() {
- return base::TimeDelta();
+AnimationTimeline::PhaseAndTime ScrollTimeline::CurrentPhaseAndTime() {
+ return phase_and_time_snapshotted_;
}
-double ScrollTimeline::currentTime(bool& is_null) {
- is_null = true;
-
+AnimationTimeline::PhaseAndTime ScrollTimeline::ComputeCurrentPhaseAndTime()
+ const {
// 1. If scroll timeline is inactive, return an unresolved time value.
// https://github.com/WICG/scroll-animations/issues/31
// https://wicg.github.io/scroll-animations/#current-time-algorithm
- if (!IsActive()) {
- return std::numeric_limits<double>::quiet_NaN();
+ if (!ComputeIsActive()) {
+ return {TimelinePhase::kInactive, /*current_time*/ base::nullopt};
}
LayoutBox* layout_box = resolved_scroll_source_->GetLayoutBox();
// 2. Otherwise, let current scroll offset be the current scroll offset of
@@ -164,46 +196,55 @@ double ScrollTimeline::currentTime(bool& is_null) {
ResolveScrollStartAndEnd(layout_box, max_offset, resolved_start_scroll_offset,
resolved_end_scroll_offset);
+ // TODO(crbug.com/1060384): Once the spec has been updated to state what the
+ // expected result is when startScrollOffset >= endScrollOffset, we might need
+ // to add a special case here. See
+ // https://github.com/WICG/scroll-animations/issues/20
+
// 3. If current scroll offset is less than startScrollOffset:
if (current_offset < resolved_start_scroll_offset) {
- // Return an unresolved time value if fill is none or forwards.
- if (fill_ == Timing::FillMode::NONE || fill_ == Timing::FillMode::FORWARDS)
- return std::numeric_limits<double>::quiet_NaN();
-
- // Otherwise, return 0.
- is_null = false;
- return 0;
+ return {TimelinePhase::kBefore, base::TimeDelta()};
}
// 4. If current scroll offset is greater than or equal to endScrollOffset:
if (current_offset >= resolved_end_scroll_offset) {
- // If endScrollOffset is less than the maximum scroll offset of scrollSource
- // in orientation and fill is none or backwards, return an unresolved time
- // value.
- if (resolved_end_scroll_offset < max_offset &&
- (fill_ == Timing::FillMode::NONE ||
- fill_ == Timing::FillMode::BACKWARDS)) {
- return std::numeric_limits<double>::quiet_NaN();
- }
-
- // Otherwise, return the effective time range.
- is_null = false;
- return time_range_;
- }
-
- // This is not by the spec, but avoids a negative current time.
- // See https://github.com/WICG/scroll-animations/issues/20
- if (resolved_start_scroll_offset >= resolved_end_scroll_offset) {
- return std::numeric_limits<double>::quiet_NaN();
+ return {TimelinePhase::kAfter,
+ base::TimeDelta::FromMillisecondsD(time_range_)};
}
// 5. Return the result of evaluating the following expression:
// ((current scroll offset - startScrollOffset) /
// (endScrollOffset - startScrollOffset)) * effective time range
- is_null = false;
- return ((current_offset - resolved_start_scroll_offset) /
- (resolved_end_scroll_offset - resolved_start_scroll_offset)) *
- time_range_;
+ base::Optional<base::TimeDelta> calculated_current_time =
+ base::TimeDelta::FromMillisecondsD(
+ ((current_offset - resolved_start_scroll_offset) /
+ (resolved_end_scroll_offset - resolved_start_scroll_offset)) *
+ time_range_);
+ return {TimelinePhase::kActive, calculated_current_time};
+}
+
+// Scroll-linked animations are initialized with the start time of zero.
+base::Optional<base::TimeDelta>
+ScrollTimeline::InitialStartTimeForAnimations() {
+ return base::TimeDelta();
+}
+
+void ScrollTimeline::ServiceAnimations(TimingUpdateReason reason) {
+ // Snapshot timeline state once at top of animation frame.
+ if (reason == kTimingUpdateForAnimationFrame)
+ SnapshotState();
+ AnimationTimeline::ServiceAnimations(reason);
+}
+
+void ScrollTimeline::ScheduleNextService() {
+ if (AnimationsNeedingUpdateCount() == 0)
+ return;
+ if (ComputeCurrentPhaseAndTime() != last_current_phase_and_time_)
+ ScheduleServiceOnNextFrame();
+}
+
+void ScrollTimeline::SnapshotState() {
+ phase_and_time_snapshotted_ = ComputeCurrentPhaseAndTime();
}
Element* ScrollTimeline::scrollSource() {
@@ -238,22 +279,18 @@ void ScrollTimeline::timeRange(DoubleOrScrollTimelineAutoKeyword& result) {
result.SetDouble(time_range_);
}
-String ScrollTimeline::fill() {
- return Timing::FillModeString(fill_);
-}
-
void ScrollTimeline::GetCurrentAndMaxOffset(const LayoutBox* layout_box,
double& current_offset,
double& max_offset) const {
DCHECK(layout_box);
+ DCHECK(layout_box->GetScrollableArea());
// Depending on the writing-mode and direction, the scroll origin shifts and
// the scroll offset may be negative. The easiest way to deal with this is to
// use only the magnitude of the scroll offset, and compare it to (max_offset
// - min_offset).
PaintLayerScrollableArea* scrollable_area = layout_box->GetScrollableArea();
- if (!scrollable_area)
- return;
+
// Using the absolute value of the scroll offset only makes sense if either
// the max or min scroll offset for a given axis is 0. This should be
// guaranteed by the scroll origin code, but these DCHECKs ensure that.
@@ -316,22 +353,19 @@ void ScrollTimeline::ResolveScrollStartAndEnd(
}
}
-void ScrollTimeline::AnimationAttached(Animation*) {
+void ScrollTimeline::WorkletAnimationAttached() {
if (!resolved_scroll_source_)
return;
-
GetActiveScrollTimelineSet().insert(resolved_scroll_source_);
}
-void ScrollTimeline::AnimationDetached(Animation*) {
+void ScrollTimeline::WorkletAnimationDetached() {
if (!resolved_scroll_source_)
return;
-
GetActiveScrollTimelineSet().erase(resolved_scroll_source_);
}
-void ScrollTimeline::Trace(blink::Visitor* visitor) {
- visitor->Trace(document_);
+void ScrollTimeline::Trace(Visitor* visitor) {
visitor->Trace(scroll_source_);
visitor->Trace(resolved_scroll_source_);
visitor->Trace(start_scroll_offset_);
@@ -340,9 +374,44 @@ void ScrollTimeline::Trace(blink::Visitor* visitor) {
}
bool ScrollTimeline::HasActiveScrollTimeline(Node* node) {
- ActiveScrollTimelineSet& set = GetActiveScrollTimelineSet();
+ ActiveScrollTimelineSet& worklet_animations_set =
+ GetActiveScrollTimelineSet();
+ auto worklet_animations_it = worklet_animations_set.find(node);
+ if (worklet_animations_it != worklet_animations_set.end() &&
+ worklet_animations_it->value > 0)
+ return true;
+
+ ScrollTimelineSet& set = GetScrollTimelineSet();
auto it = set.find(node);
- return it != set.end() && it->value > 0;
+ if (it == set.end())
+ return false;
+
+ for (auto& timeline : it->value) {
+ if (timeline->HasAnimations())
+ return true;
+ }
+ return false;
+}
+
+void ScrollTimeline::Invalidate(Node* node) {
+ ScrollTimelineSet& set = GetScrollTimelineSet();
+ auto it = set.find(node);
+
+ if (it == set.end())
+ return;
+
+ for (auto& timeline : it->value) {
+ timeline->Invalidate();
+ }
+}
+
+CompositorAnimationTimeline* ScrollTimeline::EnsureCompositorTimeline() {
+ if (compositor_timeline_)
+ return compositor_timeline_.get();
+
+ compositor_timeline_ = std::make_unique<CompositorAnimationTimeline>(
+ scroll_timeline_util::ToCompositorScrollTimeline(this));
+ return compositor_timeline_.get();
}
} // 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 31eaab0b90e..d04aedd1146 100644
--- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline.h
+++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline.h
@@ -6,16 +6,16 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SCROLL_TIMELINE_H_
#include "third_party/blink/renderer/core/animation/animation_timeline.h"
-#include "third_party/blink/renderer/core/animation/scroll_timeline_options.h"
#include "third_party/blink/renderer/core/animation/timing.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/core/dom/element.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 DoubleOrScrollTimelineAutoKeyword;
+class ScrollTimelineOptions;
+
// Implements the ScrollTimeline concept from the Scroll-linked Animations spec.
//
// A ScrollTimeline is a special form of AnimationTimeline whose time values are
@@ -25,7 +25,7 @@ namespace blink {
// control the conversion of scroll amount to time output.
//
// Spec: https://wicg.github.io/scroll-animations/#scroll-timelines
-class CORE_EXPORT ScrollTimeline final : public AnimationTimeline {
+class CORE_EXPORT ScrollTimeline : public AnimationTimeline {
DEFINE_WRAPPERTYPEINFO();
public:
@@ -45,26 +45,25 @@ class CORE_EXPORT ScrollTimeline final : public AnimationTimeline {
ScrollDirection,
CSSPrimitiveValue*,
CSSPrimitiveValue*,
- double,
- Timing::FillMode);
+ double);
// AnimationTimeline implementation.
- double currentTime(bool& is_null) final;
bool IsScrollTimeline() const override { return true; }
- Document* GetDocument() override { return document_; }
// ScrollTimeline is not active if scrollSource is null, does not currently
// have a CSS layout box, or if its layout box is not a scroll container.
// https://github.com/WICG/scroll-animations/issues/31
bool IsActive() const override;
base::Optional<base::TimeDelta> InitialStartTimeForAnimations() override;
+ void ServiceAnimations(TimingUpdateReason) override;
+ void ScheduleNextService() override;
+
// IDL API implementation.
Element* scrollSource();
String orientation();
String startScrollOffset();
String endScrollOffset();
void timeRange(DoubleOrScrollTimelineAutoKeyword&);
- String fill();
// Returns the Node that should actually have the ScrollableArea (if one
// exists). This can differ from |scrollSource| when |scroll_source_| is the
@@ -73,7 +72,6 @@ class CORE_EXPORT ScrollTimeline final : public AnimationTimeline {
Node* ResolvedScrollSource() const { return resolved_scroll_source_; }
ScrollDirection GetOrientation() const { return orientation_; }
- Timing::FillMode GetFillMode() const { return fill_; }
void GetCurrentAndMaxOffset(const LayoutBox*,
double& current_offset,
@@ -82,35 +80,58 @@ class CORE_EXPORT ScrollTimeline final : public AnimationTimeline {
double max_offset,
double& resolved_start_scroll_offset,
double& resolved_end_scroll_offset) const;
+ // Invalidates scroll timeline as a result of scroller properties change.
+ // This may lead the timeline to request a new animation frame.
+ virtual void Invalidate();
- // Must be called when this ScrollTimeline is attached/detached from an
- // animation.
- void AnimationAttached(Animation*) override;
- void AnimationDetached(Animation*) override;
+ CompositorAnimationTimeline* EnsureCompositorTimeline() 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
+ // number of worklet animations attached to the scroll timeline for updating
+ // compositing state.
+ void WorkletAnimationAttached();
+ void WorkletAnimationDetached();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
static bool HasActiveScrollTimeline(Node* node);
+ // Invalidates scroll timelines with a given scroller node.
+ // Called when scroller properties, affecting scroll timeline state, change.
+ // These properties are scroller offset, content size, viewport size,
+ // overflow, adding and removal of scrollable area.
+ static void Invalidate(Node* node);
+
+ protected:
+ PhaseAndTime CurrentPhaseAndTime() override;
private:
- Member<Document> document_;
+ // https://wicg.github.io/scroll-animations/#avoiding-cycles
+ // Snapshots scroll timeline current time and phase.
+ // Called once per animation frame.
+ void SnapshotState();
+ bool ComputeIsActive() const;
+ PhaseAndTime ComputeCurrentPhaseAndTime() const;
+
// 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_;
Member<Node> resolved_scroll_source_;
-
ScrollDirection orientation_;
Member<CSSPrimitiveValue> start_scroll_offset_;
Member<CSSPrimitiveValue> end_scroll_offset_;
double time_range_;
- Timing::FillMode fill_;
+
+ // Snapshotted value produced by the last SnapshotState call.
+ PhaseAndTime phase_and_time_snapshotted_;
};
-DEFINE_TYPE_CASTS(ScrollTimeline,
- AnimationTimeline,
- value,
- value->IsScrollTimeline(),
- value.IsScrollTimeline());
+template <>
+struct DowncastTraits<ScrollTimeline> {
+ static bool AllowFrom(const AnimationTimeline& value) {
+ return value.IsScrollTimeline();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline.idl b/chromium/third_party/blink/renderer/core/animation/scroll_timeline.idl
index bd0cd9c86a0..11650883814 100644
--- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline.idl
+++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline.idl
@@ -5,17 +5,13 @@
// https://wicg.github.io/scroll-animations/#scrolltimeline-interface
[
- Constructor(optional ScrollTimelineOptions options),
- ConstructorCallWith=Document,
- MeasureAs=ScrollTimelineConstructor,
- RaisesException=Constructor,
RuntimeEnabled=ScrollTimeline,
Exposed=Window
] interface ScrollTimeline : AnimationTimeline {
+ [CallWith=Document, RaisesException, MeasureAs=ScrollTimelineConstructor] constructor(optional ScrollTimelineOptions options = {});
readonly attribute Element? scrollSource;
readonly attribute ScrollDirection orientation;
readonly attribute DOMString startScrollOffset;
readonly attribute DOMString endScrollOffset;
readonly attribute (double or ScrollTimelineAutoKeyword) timeRange;
- readonly attribute FillMode fill;
};
diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_options.idl b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_options.idl
index aef61713958..74e907227c7 100644
--- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_options.idl
+++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_options.idl
@@ -19,5 +19,4 @@ dictionary ScrollTimelineOptions {
DOMString startScrollOffset = "auto";
DOMString endScrollOffset = "auto";
(double or ScrollTimelineAutoKeyword) timeRange = "auto";
- FillMode fill = "none";
};
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 beef1184689..d7047bde6f5 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
@@ -5,6 +5,10 @@
#include "third_party/blink/renderer/core/animation/scroll_timeline.h"
#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/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"
#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/testing/core_unit_test_helper.h"
@@ -18,6 +22,45 @@ class ScrollTimelineTest : public RenderingTest {
EnableCompositing();
RenderingTest::SetUp();
}
+
+ public:
+ void SimulateFrame() {
+ // Advance time by 100 ms.
+ auto new_time = GetAnimationClock().CurrentTime() +
+ base::TimeDelta::FromMilliseconds(100);
+ GetPage().Animator().ServiceScriptedAnimations(new_time);
+ }
+};
+
+class TestScrollTimeline : public ScrollTimeline {
+ public:
+ TestScrollTimeline(
+ Document* document,
+ Element* scroll_source,
+ CSSPrimitiveValue* start_scroll_offset =
+ CSSNumericLiteralValue::Create(10.0,
+ CSSPrimitiveValue::UnitType::kPixels),
+ CSSPrimitiveValue* end_scroll_offset =
+ CSSNumericLiteralValue::Create(90.0,
+ CSSPrimitiveValue::UnitType::kPixels))
+ : ScrollTimeline(document,
+ scroll_source,
+ ScrollTimeline::Vertical,
+ start_scroll_offset,
+ end_scroll_offset,
+ 100.0),
+ next_service_scheduled_(false) {}
+
+ void ScheduleServiceOnNextFrame() override {
+ ScrollTimeline::ScheduleServiceOnNextFrame();
+ next_service_scheduled_ = true;
+ }
+ void Trace(Visitor* visitor) override { ScrollTimeline::Trace(visitor); }
+ bool NextServiceScheduled() const { return next_service_scheduled_; }
+ void ResetNextServiceScheduled() { next_service_scheduled_ = false; }
+
+ private:
+ bool next_service_scheduled_;
};
TEST_F(ScrollTimelineTest, CurrentTimeIsNullIfScrollSourceIsNotScrollable) {
@@ -72,20 +115,52 @@ TEST_F(ScrollTimelineTest,
ScrollTimeline* scroll_timeline =
ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION);
- bool current_time_is_null = false;
- scrollable_area->SetScrollOffset(ScrollOffset(0, 5), kProgrammaticScroll);
- scroll_timeline->currentTime(current_time_is_null);
- EXPECT_TRUE(current_time_is_null);
+ bool current_time_is_null = true;
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 5),
+ mojom::blink::ScrollType::kProgrammatic);
+ // Simulate a new animation frame which allows the timeline to compute new
+ // current time.
+ SimulateFrame();
+ double current_time = scroll_timeline->currentTime(current_time_is_null);
+ EXPECT_FALSE(current_time_is_null);
+ EXPECT_EQ(current_time, 0);
+ EXPECT_EQ("before", scroll_timeline->phase());
current_time_is_null = true;
- scrollable_area->SetScrollOffset(ScrollOffset(0, 50), kProgrammaticScroll);
- scroll_timeline->currentTime(current_time_is_null);
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 10),
+ mojom::blink::ScrollType::kProgrammatic);
+ SimulateFrame();
+ current_time = scroll_timeline->currentTime(current_time_is_null);
+ EXPECT_FALSE(current_time_is_null);
+ EXPECT_EQ(current_time, 0);
+ EXPECT_EQ("active", scroll_timeline->phase());
+
+ current_time_is_null = true;
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 50),
+ mojom::blink::ScrollType::kProgrammatic);
+ SimulateFrame();
+ current_time = scroll_timeline->currentTime(current_time_is_null);
+ EXPECT_FALSE(current_time_is_null);
+ EXPECT_EQ(current_time, 50);
+ EXPECT_EQ("active", scroll_timeline->phase());
+
+ current_time_is_null = true;
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 90),
+ mojom::blink::ScrollType::kProgrammatic);
+ SimulateFrame();
+ current_time = scroll_timeline->currentTime(current_time_is_null);
EXPECT_FALSE(current_time_is_null);
+ EXPECT_EQ(current_time, time_range.GetAsDouble());
+ EXPECT_EQ("after", scroll_timeline->phase());
- current_time_is_null = false;
- scrollable_area->SetScrollOffset(ScrollOffset(0, 100), kProgrammaticScroll);
+ current_time_is_null = true;
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 100),
+ mojom::blink::ScrollType::kProgrammatic);
+ SimulateFrame();
scroll_timeline->currentTime(current_time_is_null);
- EXPECT_TRUE(current_time_is_null);
+ EXPECT_FALSE(current_time_is_null);
+ EXPECT_EQ(current_time, time_range.GetAsDouble());
+ EXPECT_EQ("after", scroll_timeline->phase());
EXPECT_TRUE(scroll_timeline->IsActive());
}
@@ -117,13 +192,89 @@ TEST_F(ScrollTimelineTest,
ScrollTimeline* scroll_timeline =
ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION);
- bool current_time_is_null = false;
- scrollable_area->SetScrollOffset(ScrollOffset(0, 50), kProgrammaticScroll);
- scroll_timeline->currentTime(current_time_is_null);
- EXPECT_TRUE(current_time_is_null);
+ bool current_time_is_null = true;
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 20),
+ mojom::blink::ScrollType::kProgrammatic);
+ // Simulate a new animation frame which allows the timeline to compute new
+ // current time.
+ SimulateFrame();
+ double current_time = scroll_timeline->currentTime(current_time_is_null);
+ EXPECT_FALSE(current_time_is_null);
+ EXPECT_EQ(0, current_time);
+ EXPECT_EQ("before", scroll_timeline->phase());
+
+ current_time_is_null = true;
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 60),
+ mojom::blink::ScrollType::kProgrammatic);
+ SimulateFrame();
+ current_time = scroll_timeline->currentTime(current_time_is_null);
+ EXPECT_FALSE(current_time_is_null);
+ EXPECT_EQ(0, current_time);
+ EXPECT_EQ("before", scroll_timeline->phase());
+
+ current_time_is_null = true;
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 100),
+ mojom::blink::ScrollType::kProgrammatic);
+ SimulateFrame();
+ current_time = scroll_timeline->currentTime(current_time_is_null);
+ EXPECT_FALSE(current_time_is_null);
+ EXPECT_EQ(time_range.GetAsDouble(), current_time);
+ EXPECT_EQ("after", scroll_timeline->phase());
EXPECT_TRUE(scroll_timeline->IsActive());
}
+TEST_F(ScrollTimelineTest, PhasesAreCorrectWhenUsingOffsets) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #scroller { overflow: scroll; width: 100px; height: 100px; }
+ #spacer { height: 1000px; }
+ </style>
+ <div id='scroller'>
+ <div id ='spacer'></div>
+ </div>
+ )HTML");
+
+ LayoutBoxModelObject* scroller =
+ ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller"));
+ ASSERT_TRUE(scroller);
+ ASSERT_TRUE(scroller->HasOverflowClip());
+ PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea();
+ ASSERT_TRUE(scrollable_area);
+ ScrollTimelineOptions* options = ScrollTimelineOptions::Create();
+ DoubleOrScrollTimelineAutoKeyword time_range =
+ DoubleOrScrollTimelineAutoKeyword::FromDouble(100);
+ options->setTimeRange(time_range);
+ options->setScrollSource(GetElementById("scroller"));
+ options->setStartScrollOffset("10px");
+ options->setEndScrollOffset("90px");
+ ScrollTimeline* scroll_timeline =
+ ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION);
+
+ EXPECT_EQ(scroll_timeline->phase(), "before");
+
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 10),
+ mojom::blink::ScrollType::kProgrammatic);
+ // Simulate a new animation frame which allows the timeline to compute new
+ // current phase and time.
+ SimulateFrame();
+ EXPECT_EQ(scroll_timeline->phase(), "active");
+
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 50),
+ mojom::blink::ScrollType::kProgrammatic);
+ SimulateFrame();
+ EXPECT_EQ(scroll_timeline->phase(), "active");
+
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 90),
+ mojom::blink::ScrollType::kProgrammatic);
+ SimulateFrame();
+ EXPECT_EQ(scroll_timeline->phase(), "after");
+
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 100),
+ mojom::blink::ScrollType::kProgrammatic);
+ SimulateFrame();
+ EXPECT_EQ(scroll_timeline->phase(), "after");
+}
+
TEST_F(ScrollTimelineTest,
UsingDocumentScrollingElementShouldCorrectlyResolveToDocument) {
SetBodyInnerHTML(R"HTML(
@@ -191,17 +342,173 @@ TEST_F(ScrollTimelineTest, AttachOrDetachAnimationWithNullScrollSource) {
Element* scroll_source = nullptr;
CSSPrimitiveValue* start_scroll_offset = nullptr;
CSSPrimitiveValue* end_scroll_offset = nullptr;
- ScrollTimeline* scroll_timeline = MakeGarbageCollected<ScrollTimeline>(
- &GetDocument(), scroll_source, ScrollTimeline::Block, start_scroll_offset,
- end_scroll_offset, 100, Timing::FillMode::NONE);
+ Persistent<ScrollTimeline> scroll_timeline =
+ MakeGarbageCollected<ScrollTimeline>(
+ &GetDocument(), scroll_source, ScrollTimeline::Block,
+ start_scroll_offset, end_scroll_offset, 100);
// Sanity checks.
ASSERT_EQ(scroll_timeline->scrollSource(), nullptr);
ASSERT_EQ(scroll_timeline->ResolvedScrollSource(), nullptr);
- // These calls should be no-ops in this mode, and shouldn't crash.
- scroll_timeline->AnimationAttached(nullptr);
- scroll_timeline->AnimationDetached(nullptr);
+ 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);
+ EXPECT_EQ(1u, scroll_timeline->GetAnimations().size());
+ EXPECT_TRUE(scroll_timeline->GetAnimations().Contains(animation));
+
+ animation = nullptr;
+ ThreadState::Current()->CollectAllGarbageForTesting();
+ EXPECT_EQ(0u, scroll_timeline->GetAnimations().size());
+}
+
+TEST_F(ScrollTimelineTest, ScheduleFrameOnlyWhenScrollOffsetChanges) {
+ 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");
+ TestScrollTimeline* scroll_timeline =
+ MakeGarbageCollected<TestScrollTimeline>(&GetDocument(),
+ scroller_element);
+
+ 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();
+
+ // Validate that no frame is scheduled when there is no scroll change.
+ scroll_timeline->ResetNextServiceScheduled();
+ scroll_timeline->ScheduleNextService();
+ EXPECT_FALSE(scroll_timeline->NextServiceScheduled());
+
+ // Validate that frame is scheduled when scroll changes.
+ scroll_timeline->ResetNextServiceScheduled();
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 30),
+ mojom::blink::ScrollType::kProgrammatic);
+ scroll_timeline->ScheduleNextService();
+ EXPECT_TRUE(scroll_timeline->NextServiceScheduled());
+}
+
+// This test verifies scenario when scroll timeline is updated as a result of
+// layout run. In this case the expectation is that at the end of paint
+// lifecycle phase scroll timeline schedules a new frame that runs animations
+// update.
+TEST_F(ScrollTimelineTest, ScheduleFrameWhenScrollerLayoutChanges) {
+ 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");
+ TestScrollTimeline* scroll_timeline =
+ MakeGarbageCollected<TestScrollTimeline>(&GetDocument(), scroller_element,
+ nullptr, nullptr);
+ 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();
+ // Validate that frame is scheduled when scroller layout changes.
+ Element* spacer_element = GetElementById("spacer");
+ spacer_element->setAttribute(html_names::kStyleAttr, "height:1000px;");
+ 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) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #scroller { overflow: scroll; width: 100px; height: 100px; }
+ #spacer { height: 1000px; }
+ </style>
+ <div id='scroller'>
+ <div id ='spacer'></div>
+ </div>
+ )HTML");
+
+ LayoutBoxModelObject* scroller =
+ ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller"));
+ ASSERT_TRUE(scroller);
+ ASSERT_TRUE(scroller->HasOverflowClip());
+ PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea();
+ ASSERT_TRUE(scrollable_area);
+ ScrollTimelineOptions* options = ScrollTimelineOptions::Create();
+ DoubleOrScrollTimelineAutoKeyword time_range =
+ DoubleOrScrollTimelineAutoKeyword::FromDouble(100);
+ options->setTimeRange(time_range);
+ options->setScrollSource(GetElementById("scroller"));
+
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 5),
+ mojom::blink::ScrollType::kProgrammatic);
+
+ ScrollTimeline* scroll_timeline =
+ ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION);
+
+ bool current_time_is_null = false;
+ double time_before = scroll_timeline->currentTime(current_time_is_null);
+ ASSERT_FALSE(current_time_is_null);
+
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 10),
+ mojom::blink::ScrollType::kProgrammatic);
+ // Verify that the current time didn't change before there is a new animation
+ // frame.
+ EXPECT_EQ(time_before, scroll_timeline->currentTime(current_time_is_null));
+ ASSERT_FALSE(current_time_is_null);
+
+ // Simulate a new animation frame which allows the timeline to compute a new
+ // current time.
+ SimulateFrame();
+
+ // Verify that current time did change in the new animation frame.
+ EXPECT_NE(time_before, scroll_timeline->currentTime(current_time_is_null));
+ ASSERT_FALSE(current_time_is_null);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util.cc b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util.cc
index 906fb06cd0f..5a4600b419b 100644
--- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util.cc
+++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util.cc
@@ -6,6 +6,7 @@
#include "third_party/blink/renderer/bindings/core/v8/double_or_scroll_timeline_auto_keyword.h"
#include "third_party/blink/renderer/core/animation/animation_timeline.h"
+#include "third_party/blink/renderer/core/animation/document_timeline.h"
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
@@ -14,12 +15,12 @@ namespace blink {
namespace scroll_timeline_util {
-std::unique_ptr<CompositorScrollTimeline> ToCompositorScrollTimeline(
+scoped_refptr<CompositorScrollTimeline> ToCompositorScrollTimeline(
AnimationTimeline* timeline) {
- if (!timeline || timeline->IsDocumentTimeline())
+ if (!timeline || IsA<DocumentTimeline>(timeline))
return nullptr;
- ScrollTimeline* scroll_timeline = ToScrollTimeline(timeline);
+ auto* scroll_timeline = To<ScrollTimeline>(timeline);
Node* scroll_source = scroll_timeline->ResolvedScrollSource();
base::Optional<CompositorElementId> element_id =
GetCompositorScrollElementId(scroll_source);
@@ -29,7 +30,8 @@ std::unique_ptr<CompositorScrollTimeline> ToCompositorScrollTimeline(
// TODO(smcgruer): Handle 'auto' time range value.
DCHECK(time_range.IsDouble());
- LayoutBox* box = scroll_source ? scroll_source->GetLayoutBox() : nullptr;
+ LayoutBox* box =
+ scroll_timeline->IsActive() ? scroll_source->GetLayoutBox() : nullptr;
CompositorScrollTimeline::ScrollDirection orientation = ConvertOrientation(
scroll_timeline->GetOrientation(), box ? box->Style() : nullptr);
@@ -50,9 +52,9 @@ std::unique_ptr<CompositorScrollTimeline> ToCompositorScrollTimeline(
end_scroll_offset = resolved_end_scroll_offset;
}
- return std::make_unique<CompositorScrollTimeline>(
+ return CompositorScrollTimeline::Create(
element_id, orientation, start_scroll_offset, end_scroll_offset,
- time_range.GetAsDouble(), scroll_timeline->GetFillMode());
+ time_range.GetAsDouble());
}
base::Optional<CompositorElementId> GetCompositorScrollElementId(
diff --git a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util.h b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util.h
index a1111278ccd..c17846b8b89 100644
--- a/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util.h
+++ b/chromium/third_party/blink/renderer/core/animation/scroll_timeline_util.h
@@ -8,12 +8,15 @@
#include <memory>
#include "base/optional.h"
+#include "cc/animation/scroll_timeline.h"
#include "third_party/blink/renderer/core/animation/scroll_timeline.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation.h"
namespace blink {
+using CompositorScrollTimeline = cc::ScrollTimeline;
+
class AnimationTimeline;
class ComputedStyle;
class Node;
@@ -22,7 +25,7 @@ namespace scroll_timeline_util {
// Converts the input timeline to the compositor representation of a
// ScrollTimeline. Returns nullptr if the input is not a ScrollTimeline.
-std::unique_ptr<CompositorScrollTimeline> CORE_EXPORT
+scoped_refptr<CompositorScrollTimeline> CORE_EXPORT
ToCompositorScrollTimeline(AnimationTimeline*);
// Retrieves the 'scroll' compositor element id for the input node, or
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 6d05f7e5bcd..58aa61f101b 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
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/animation/scroll_timeline_util.h"
#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_timeline.h"
#include "third_party/blink/renderer/core/html/html_div_element.h"
#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
@@ -51,7 +52,7 @@ TEST_F(ScrollTimelineUtilTest, ToCompositorScrollTimeline) {
ScrollTimeline* timeline =
ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION);
- std::unique_ptr<CompositorScrollTimeline> compositor_timeline =
+ scoped_refptr<CompositorScrollTimeline> compositor_timeline =
ToCompositorScrollTimeline(timeline);
EXPECT_EQ(compositor_timeline->GetActiveIdForTest(), base::nullopt);
EXPECT_EQ(compositor_timeline->GetPendingIdForTest(), element_id);
@@ -83,9 +84,9 @@ TEST_F(ScrollTimelineUtilTest, ToCompositorScrollTimelineNullScrollSource) {
CSSPrimitiveValue* end_scroll_offset = nullptr;
ScrollTimeline* timeline = MakeGarbageCollected<ScrollTimeline>(
&GetDocument(), scroll_source, ScrollTimeline::Block, start_scroll_offset,
- end_scroll_offset, 100, Timing::FillMode::NONE);
+ end_scroll_offset, 100);
- std::unique_ptr<CompositorScrollTimeline> compositor_timeline =
+ scoped_refptr<CompositorScrollTimeline> compositor_timeline =
ToCompositorScrollTimeline(timeline);
ASSERT_TRUE(compositor_timeline.get());
EXPECT_EQ(compositor_timeline->GetPendingIdForTest(), base::nullopt);
@@ -103,7 +104,7 @@ TEST_F(ScrollTimelineUtilTest, ToCompositorScrollTimelineNullLayoutBox) {
ScrollTimeline* timeline =
ScrollTimeline::Create(GetDocument(), options, ASSERT_NO_EXCEPTION);
- std::unique_ptr<CompositorScrollTimeline> compositor_timeline =
+ scoped_refptr<CompositorScrollTimeline> compositor_timeline =
ToCompositorScrollTimeline(timeline);
EXPECT_TRUE(compositor_timeline.get());
// Here we just want to test the start/end scroll offset.
diff --git a/chromium/third_party/blink/renderer/core/animation/size_interpolation_functions.cc b/chromium/third_party/blink/renderer/core/animation/size_interpolation_functions.cc
index a2fca4909be..156dc07a69f 100644
--- a/chromium/third_party/blink/renderer/core/animation/size_interpolation_functions.cc
+++ b/chromium/third_party/blink/renderer/core/animation/size_interpolation_functions.cc
@@ -54,7 +54,15 @@ class CSSSizeNonInterpolableValue : public NonInterpolableValue {
};
DEFINE_NON_INTERPOLABLE_VALUE_TYPE(CSSSizeNonInterpolableValue);
-DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(CSSSizeNonInterpolableValue);
+template <>
+struct DowncastTraits<CSSSizeNonInterpolableValue> {
+ static bool AllowFrom(const NonInterpolableValue* value) {
+ return value && AllowFrom(*value);
+ }
+ static bool AllowFrom(const NonInterpolableValue& value) {
+ return value.GetType() == CSSSizeNonInterpolableValue::static_type_;
+ }
+};
static InterpolationValue ConvertKeyword(CSSValueID keyword) {
return InterpolationValue(std::make_unique<InterpolableList>(0),
@@ -134,7 +142,7 @@ PairwiseInterpolationValue SizeInterpolationFunctions::MaybeMergeSingles(
InterpolationValue SizeInterpolationFunctions::CreateNeutralValue(
const NonInterpolableValue* non_interpolable_value) {
- auto& size = ToCSSSizeNonInterpolableValue(*non_interpolable_value);
+ auto& size = To<CSSSizeNonInterpolableValue>(*non_interpolable_value);
if (size.IsKeyword())
return ConvertKeyword(size.Keyword());
return WrapConvertedLength(
@@ -144,8 +152,8 @@ InterpolationValue SizeInterpolationFunctions::CreateNeutralValue(
bool SizeInterpolationFunctions::NonInterpolableValuesAreCompatible(
const NonInterpolableValue* a,
const NonInterpolableValue* b) {
- const auto& size_a = ToCSSSizeNonInterpolableValue(*a);
- const auto& size_b = ToCSSSizeNonInterpolableValue(*b);
+ const auto& size_a = To<CSSSizeNonInterpolableValue>(*a);
+ const auto& size_b = To<CSSSizeNonInterpolableValue>(*b);
if (size_a.IsKeyword() != size_b.IsKeyword())
return false;
if (size_a.IsKeyword())
@@ -159,7 +167,7 @@ void SizeInterpolationFunctions::Composite(
const InterpolableValue& interpolable_value,
const NonInterpolableValue* non_interpolable_value) {
const auto& size_non_interpolable_value =
- ToCSSSizeNonInterpolableValue(*non_interpolable_value);
+ To<CSSSizeNonInterpolableValue>(*non_interpolable_value);
if (size_non_interpolable_value.IsKeyword())
return;
underlying_value.MutableInterpolableValue().ScaleAndAdd(underlying_fraction,
@@ -184,8 +192,10 @@ FillSize SizeInterpolationFunctions::CreateFillSize(
const InterpolableValue& interpolable_value_b,
const NonInterpolableValue* non_interpolable_value_b,
const CSSToLengthConversionData& conversion_data) {
- const auto& side_a = ToCSSSizeNonInterpolableValue(*non_interpolable_value_a);
- const auto& side_b = ToCSSSizeNonInterpolableValue(*non_interpolable_value_b);
+ const auto& side_a =
+ To<CSSSizeNonInterpolableValue>(*non_interpolable_value_a);
+ const auto& side_b =
+ To<CSSSizeNonInterpolableValue>(*non_interpolable_value_b);
if (side_a.IsKeyword()) {
switch (side_a.Keyword()) {
case CSSValueID::kCover:
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 87c9a03937c..31cdb962583 100644
--- a/chromium/third_party/blink/renderer/core/animation/string_keyframe.h
+++ b/chromium/third_party/blink/renderer/core/animation/string_keyframe.h
@@ -194,21 +194,24 @@ class CORE_EXPORT StringKeyframe : public Keyframe {
using CSSPropertySpecificKeyframe = StringKeyframe::CSSPropertySpecificKeyframe;
using SVGPropertySpecificKeyframe = StringKeyframe::SVGPropertySpecificKeyframe;
-DEFINE_TYPE_CASTS(StringKeyframe,
- Keyframe,
- value,
- value->IsStringKeyframe(),
- value.IsStringKeyframe());
-DEFINE_TYPE_CASTS(CSSPropertySpecificKeyframe,
- Keyframe::PropertySpecificKeyframe,
- value,
- value->IsCSSPropertySpecificKeyframe(),
- value.IsCSSPropertySpecificKeyframe());
-DEFINE_TYPE_CASTS(SVGPropertySpecificKeyframe,
- Keyframe::PropertySpecificKeyframe,
- value,
- value->IsSVGPropertySpecificKeyframe(),
- value.IsSVGPropertySpecificKeyframe());
+template <>
+struct DowncastTraits<StringKeyframe> {
+ static bool AllowFrom(const Keyframe& value) {
+ return value.IsStringKeyframe();
+ }
+};
+template <>
+struct DowncastTraits<CSSPropertySpecificKeyframe> {
+ static bool AllowFrom(const Keyframe::PropertySpecificKeyframe& value) {
+ return value.IsCSSPropertySpecificKeyframe();
+ }
+};
+template <>
+struct DowncastTraits<SVGPropertySpecificKeyframe> {
+ static bool AllowFrom(const Keyframe::PropertySpecificKeyframe& value) {
+ return value.IsSVGPropertySpecificKeyframe();
+ }
+};
} // namespace blink
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 053572bd423..e75b6a06490 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,16 +19,17 @@ InterpolationValue SVGAngleInterpolationType::MaybeConvertNeutral(
InterpolationValue SVGAngleInterpolationType::MaybeConvertSVGValue(
const SVGPropertyBase& svg_value) const {
- if (ToSVGAngle(svg_value).OrientType()->EnumValue() != kSVGMarkerOrientAngle)
+ if (To<SVGAngle>(svg_value).OrientType()->EnumValue() !=
+ kSVGMarkerOrientAngle)
return nullptr;
return InterpolationValue(
- std::make_unique<InterpolableNumber>(ToSVGAngle(svg_value).Value()));
+ std::make_unique<InterpolableNumber>(To<SVGAngle>(svg_value).Value()));
}
SVGPropertyBase* SVGAngleInterpolationType::AppliedSVGValue(
const InterpolableValue& interpolable_value,
const NonInterpolableValue*) const {
- double double_value = ToInterpolableNumber(interpolable_value).Value();
+ double double_value = To<InterpolableNumber>(interpolable_value).Value();
auto* result = MakeGarbageCollected<SVGAngle>();
result->NewValueSpecifiedUnits(SVGAngle::kSvgAngletypeDeg, double_value);
return result;
diff --git a/chromium/third_party/blink/renderer/core/animation/svg_integer_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/svg_integer_interpolation_type.cc
index a7ca4bc446a..b7c87682f6b 100644
--- a/chromium/third_party/blink/renderer/core/animation/svg_integer_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/svg_integer_interpolation_type.cc
@@ -21,13 +21,13 @@ InterpolationValue SVGIntegerInterpolationType::MaybeConvertSVGValue(
if (svg_value.GetType() != kAnimatedInteger)
return nullptr;
return InterpolationValue(
- std::make_unique<InterpolableNumber>(ToSVGInteger(svg_value).Value()));
+ std::make_unique<InterpolableNumber>(To<SVGInteger>(svg_value).Value()));
}
SVGPropertyBase* SVGIntegerInterpolationType::AppliedSVGValue(
const InterpolableValue& interpolable_value,
const NonInterpolableValue*) const {
- double value = ToInterpolableNumber(interpolable_value).Value();
+ double value = To<InterpolableNumber>(interpolable_value).Value();
return MakeGarbageCollected<SVGInteger>(round(value));
}
diff --git a/chromium/third_party/blink/renderer/core/animation/svg_integer_optional_integer_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/svg_integer_optional_integer_interpolation_type.cc
index 896f7dfa9de..d8d805986a4 100644
--- a/chromium/third_party/blink/renderer/core/animation/svg_integer_optional_integer_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/svg_integer_optional_integer_interpolation_type.cc
@@ -29,8 +29,8 @@ SVGIntegerOptionalIntegerInterpolationType::MaybeConvertSVGValue(
if (svg_value.GetType() != kAnimatedIntegerOptionalInteger)
return nullptr;
- const SVGIntegerOptionalInteger& integer_optional_integer =
- ToSVGIntegerOptionalInteger(svg_value);
+ const auto& integer_optional_integer =
+ To<SVGIntegerOptionalInteger>(svg_value);
auto result = std::make_unique<InterpolableList>(2);
result->Set(0, std::make_unique<InterpolableNumber>(
integer_optional_integer.FirstInteger()->Value()));
@@ -41,13 +41,13 @@ SVGIntegerOptionalIntegerInterpolationType::MaybeConvertSVGValue(
static SVGInteger* ToPositiveInteger(const InterpolableValue* number) {
return MakeGarbageCollected<SVGInteger>(
- clampTo<int>(round(ToInterpolableNumber(number)->Value()), 1));
+ clampTo<int>(round(To<InterpolableNumber>(number)->Value()), 1));
}
SVGPropertyBase* SVGIntegerOptionalIntegerInterpolationType::AppliedSVGValue(
const InterpolableValue& interpolable_value,
const NonInterpolableValue*) const {
- const InterpolableList& list = ToInterpolableList(interpolable_value);
+ const auto& list = To<InterpolableList>(interpolable_value);
return MakeGarbageCollected<SVGIntegerOptionalInteger>(
ToPositiveInteger(list.Get(0)), ToPositiveInteger(list.Get(1)));
}
diff --git a/chromium/third_party/blink/renderer/core/animation/svg_interpolation_environment.h b/chromium/third_party/blink/renderer/core/animation/svg_interpolation_environment.h
index 62787f9fe3a..bc588f791b8 100644
--- a/chromium/third_party/blink/renderer/core/animation/svg_interpolation_environment.h
+++ b/chromium/third_party/blink/renderer/core/animation/svg_interpolation_environment.h
@@ -39,15 +39,16 @@ class SVGInterpolationEnvironment : public InterpolationEnvironment {
}
private:
- Member<SVGElement> svg_element_ = nullptr;
- Member<const SVGPropertyBase> svg_base_value_ = nullptr;
+ SVGElement* svg_element_ = nullptr;
+ const SVGPropertyBase* svg_base_value_ = nullptr;
};
-DEFINE_TYPE_CASTS(SVGInterpolationEnvironment,
- InterpolationEnvironment,
- value,
- value->IsSVG(),
- value.IsSVG());
+template <>
+struct DowncastTraits<SVGInterpolationEnvironment> {
+ static bool AllowFrom(const InterpolationEnvironment& value) {
+ return value.IsSVG();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/svg_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/svg_interpolation_type.cc
index 64b757a154a..885cae5dad5 100644
--- a/chromium/third_party/blink/renderer/core/animation/svg_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/svg_interpolation_type.cc
@@ -19,24 +19,24 @@ InterpolationValue SVGInterpolationType::MaybeConvertSingle(
if (keyframe.IsNeutral())
return MaybeConvertNeutral(underlying, conversion_checkers);
- SVGPropertyBase* svg_value =
- ToSVGInterpolationEnvironment(environment)
+ auto* svg_value =
+ To<SVGInterpolationEnvironment>(environment)
.SvgBaseValue()
- .CloneForAnimation(ToSVGPropertySpecificKeyframe(keyframe).Value());
+ .CloneForAnimation(To<SVGPropertySpecificKeyframe>(keyframe).Value());
return MaybeConvertSVGValue(*svg_value);
}
InterpolationValue SVGInterpolationType::MaybeConvertUnderlyingValue(
const InterpolationEnvironment& environment) const {
return MaybeConvertSVGValue(
- ToSVGInterpolationEnvironment(environment).SvgBaseValue());
+ To<SVGInterpolationEnvironment>(environment).SvgBaseValue());
}
void SVGInterpolationType::Apply(
const InterpolableValue& interpolable_value,
const NonInterpolableValue* non_interpolable_value,
InterpolationEnvironment& environment) const {
- ToSVGInterpolationEnvironment(environment)
+ To<SVGInterpolationEnvironment>(environment)
.SvgElement()
.SetWebAnimatedAttribute(
Attribute(),
diff --git a/chromium/third_party/blink/renderer/core/animation/svg_length_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/svg_length_interpolation_type.cc
index 5a3a95a7219..dc82ebe01ca 100644
--- a/chromium/third_party/blink/renderer/core/animation/svg_length_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/svg_length_interpolation_type.cc
@@ -70,7 +70,7 @@ InterpolationValue SVGLengthInterpolationType::MaybeConvertSVGValue(
if (svg_value.GetType() != kAnimatedLength)
return nullptr;
- return MaybeConvertSVGLength(ToSVGLength(svg_value));
+ return MaybeConvertSVGLength(To<SVGLength>(svg_value));
}
SVGPropertyBase* SVGLengthInterpolationType::AppliedSVGValue(
@@ -85,7 +85,7 @@ void SVGLengthInterpolationType::Apply(
const InterpolableValue& interpolable_value,
const NonInterpolableValue* non_interpolable_value,
InterpolationEnvironment& environment) const {
- SVGElement& element = ToSVGInterpolationEnvironment(environment).SvgElement();
+ auto& element = To<SVGInterpolationEnvironment>(environment).SvgElement();
SVGLengthContext length_context(&element);
element.SetWebAnimatedAttribute(
Attribute(),
diff --git a/chromium/third_party/blink/renderer/core/animation/svg_length_list_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/svg_length_list_interpolation_type.cc
index 60c98413217..51e2037232c 100644
--- a/chromium/third_party/blink/renderer/core/animation/svg_length_list_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/svg_length_list_interpolation_type.cc
@@ -38,7 +38,7 @@ InterpolationValue SVGLengthListInterpolationType::MaybeConvertSVGValue(
if (svg_value.GetType() != kAnimatedLengthList)
return nullptr;
- const SVGLengthList& length_list = ToSVGLengthList(svg_value);
+ const auto& length_list = To<SVGLengthList>(svg_value);
auto result = std::make_unique<InterpolableList>(length_list.length());
for (wtf_size_t i = 0; i < length_list.length(); i++) {
InterpolationValue component =
@@ -54,8 +54,9 @@ PairwiseInterpolationValue SVGLengthListInterpolationType::MaybeMergeSingles(
InterpolationValue&& start,
InterpolationValue&& end) const {
wtf_size_t start_length =
- ToInterpolableList(*start.interpolable_value).length();
- wtf_size_t end_length = ToInterpolableList(*end.interpolable_value).length();
+ To<InterpolableList>(*start.interpolable_value).length();
+ wtf_size_t end_length =
+ To<InterpolableList>(*end.interpolable_value).length();
if (start_length != end_length)
return nullptr;
return InterpolationType::MaybeMergeSingles(std::move(start), std::move(end));
@@ -67,10 +68,10 @@ void SVGLengthListInterpolationType::Composite(
const InterpolationValue& value,
double interpolation_fraction) const {
wtf_size_t start_length =
- ToInterpolableList(*underlying_value_owner.Value().interpolable_value)
+ To<InterpolableList>(*underlying_value_owner.Value().interpolable_value)
.length();
wtf_size_t end_length =
- ToInterpolableList(*value.interpolable_value).length();
+ To<InterpolableList>(*value.interpolable_value).length();
if (start_length == end_length)
InterpolationType::Composite(underlying_value_owner, underlying_fraction,
@@ -91,11 +92,11 @@ void SVGLengthListInterpolationType::Apply(
const InterpolableValue& interpolable_value,
const NonInterpolableValue* non_interpolable_value,
InterpolationEnvironment& environment) const {
- SVGElement& element = ToSVGInterpolationEnvironment(environment).SvgElement();
+ auto& element = To<SVGInterpolationEnvironment>(environment).SvgElement();
SVGLengthContext length_context(&element);
auto* result = MakeGarbageCollected<SVGLengthList>(unit_mode_);
- const InterpolableList& list = ToInterpolableList(interpolable_value);
+ const auto& list = To<InterpolableList>(interpolable_value);
for (wtf_size_t i = 0; i < list.length(); i++) {
result->Append(SVGLengthInterpolationType::ResolveInterpolableSVGLength(
*list.Get(i), length_context, unit_mode_, negative_values_forbidden_));
diff --git a/chromium/third_party/blink/renderer/core/animation/svg_number_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/svg_number_interpolation_type.cc
index bf2cf3a68a4..4843e9082b8 100644
--- a/chromium/third_party/blink/renderer/core/animation/svg_number_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/svg_number_interpolation_type.cc
@@ -32,14 +32,14 @@ InterpolationValue SVGNumberInterpolationType::MaybeConvertSVGValue(
if (svg_value.GetType() != kAnimatedNumber)
return nullptr;
return InterpolationValue(
- std::make_unique<InterpolableNumber>(ToSVGNumber(svg_value).Value()));
+ std::make_unique<InterpolableNumber>(To<SVGNumber>(svg_value).Value()));
}
SVGPropertyBase* SVGNumberInterpolationType::AppliedSVGValue(
const InterpolableValue& interpolable_value,
const NonInterpolableValue*) const {
float value =
- clampTo<float>(ToInterpolableNumber(interpolable_value).Value());
+ clampTo<float>(To<InterpolableNumber>(interpolable_value).Value());
return MakeGarbageCollected<SVGNumber>(is_non_negative_ && value < 0 ? 0
: value);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/svg_number_list_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/svg_number_list_interpolation_type.cc
index a20d97e7137..2f772021a31 100644
--- a/chromium/third_party/blink/renderer/core/animation/svg_number_list_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/svg_number_list_interpolation_type.cc
@@ -36,7 +36,7 @@ InterpolationValue SVGNumberListInterpolationType::MaybeConvertSVGValue(
if (svg_value.GetType() != kAnimatedNumberList)
return nullptr;
- const SVGNumberList& number_list = ToSVGNumberList(svg_value);
+ const SVGNumberList& number_list = To<SVGNumberList>(svg_value);
auto result = std::make_unique<InterpolableList>(number_list.length());
for (wtf_size_t i = 0; i < number_list.length(); i++) {
result->Set(
@@ -48,8 +48,9 @@ InterpolationValue SVGNumberListInterpolationType::MaybeConvertSVGValue(
PairwiseInterpolationValue SVGNumberListInterpolationType::MaybeMergeSingles(
InterpolationValue&& start,
InterpolationValue&& end) const {
- size_t start_length = ToInterpolableList(*start.interpolable_value).length();
- size_t end_length = ToInterpolableList(*end.interpolable_value).length();
+ size_t start_length =
+ To<InterpolableList>(*start.interpolable_value).length();
+ size_t end_length = To<InterpolableList>(*end.interpolable_value).length();
if (start_length != end_length)
return nullptr;
return InterpolationType::MaybeMergeSingles(std::move(start), std::move(end));
@@ -57,7 +58,7 @@ PairwiseInterpolationValue SVGNumberListInterpolationType::MaybeMergeSingles(
static void PadWithZeroes(std::unique_ptr<InterpolableValue>& list_pointer,
wtf_size_t padded_length) {
- InterpolableList& list = ToInterpolableList(*list_pointer);
+ auto& list = To<InterpolableList>(*list_pointer);
if (list.length() >= padded_length)
return;
@@ -76,14 +77,14 @@ void SVGNumberListInterpolationType::Composite(
double underlying_fraction,
const InterpolationValue& value,
double interpolation_fraction) const {
- const InterpolableList& list = ToInterpolableList(*value.interpolable_value);
+ const auto& list = To<InterpolableList>(*value.interpolable_value);
- if (ToInterpolableList(*underlying_value_owner.Value().interpolable_value)
+ if (To<InterpolableList>(*underlying_value_owner.Value().interpolable_value)
.length() <= list.length())
PadWithZeroes(underlying_value_owner.MutableValue().interpolable_value,
list.length());
- InterpolableList& underlying_list = ToInterpolableList(
+ auto& underlying_list = To<InterpolableList>(
*underlying_value_owner.MutableValue().interpolable_value);
DCHECK_GE(underlying_list.length(), list.length());
@@ -99,10 +100,10 @@ SVGPropertyBase* SVGNumberListInterpolationType::AppliedSVGValue(
const InterpolableValue& interpolable_value,
const NonInterpolableValue*) const {
auto* result = MakeGarbageCollected<SVGNumberList>();
- const InterpolableList& list = ToInterpolableList(interpolable_value);
+ const auto& list = To<InterpolableList>(interpolable_value);
for (wtf_size_t i = 0; i < list.length(); i++) {
result->Append(MakeGarbageCollected<SVGNumber>(
- ToInterpolableNumber(list.Get(i))->Value()));
+ To<InterpolableNumber>(list.Get(i))->Value()));
}
return result;
}
diff --git a/chromium/third_party/blink/renderer/core/animation/svg_number_optional_number_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/svg_number_optional_number_interpolation_type.cc
index ca685ba6eb7..366f617e1a5 100644
--- a/chromium/third_party/blink/renderer/core/animation/svg_number_optional_number_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/svg_number_optional_number_interpolation_type.cc
@@ -29,8 +29,7 @@ SVGNumberOptionalNumberInterpolationType::MaybeConvertSVGValue(
if (svg_value.GetType() != kAnimatedNumberOptionalNumber)
return nullptr;
- const SVGNumberOptionalNumber& number_optional_number =
- ToSVGNumberOptionalNumber(svg_value);
+ const auto& number_optional_number = To<SVGNumberOptionalNumber>(svg_value);
auto result = std::make_unique<InterpolableList>(2);
result->Set(0, std::make_unique<InterpolableNumber>(
number_optional_number.FirstNumber()->Value()));
@@ -42,12 +41,12 @@ SVGNumberOptionalNumberInterpolationType::MaybeConvertSVGValue(
SVGPropertyBase* SVGNumberOptionalNumberInterpolationType::AppliedSVGValue(
const InterpolableValue& interpolable_value,
const NonInterpolableValue*) const {
- const InterpolableList& list = ToInterpolableList(interpolable_value);
+ const auto& list = To<InterpolableList>(interpolable_value);
return MakeGarbageCollected<SVGNumberOptionalNumber>(
MakeGarbageCollected<SVGNumber>(
- ToInterpolableNumber(list.Get(0))->Value()),
+ To<InterpolableNumber>(list.Get(0))->Value()),
MakeGarbageCollected<SVGNumber>(
- ToInterpolableNumber(list.Get(1))->Value()));
+ To<InterpolableNumber>(list.Get(1))->Value()));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/svg_path_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/svg_path_interpolation_type.cc
index 439938b3ae9..7fa8e9603e0 100644
--- a/chromium/third_party/blink/renderer/core/animation/svg_path_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/svg_path_interpolation_type.cc
@@ -16,7 +16,7 @@ InterpolationValue SVGPathInterpolationType::MaybeConvertSVGValue(
return nullptr;
return PathInterpolationFunctions::ConvertValue(
- ToSVGPath(svg_value).ByteStream(),
+ To<SVGPath>(svg_value).ByteStream(),
PathInterpolationFunctions::PreserveCoordinates);
}
diff --git a/chromium/third_party/blink/renderer/core/animation/svg_path_seg_interpolation_functions.cc b/chromium/third_party/blink/renderer/core/animation/svg_path_seg_interpolation_functions.cc
index bb14de36d58..582006ecefc 100644
--- a/chromium/third_party/blink/renderer/core/animation/svg_path_seg_interpolation_functions.cc
+++ b/chromium/third_party/blink/renderer/core/animation/svg_path_seg_interpolation_functions.cc
@@ -20,7 +20,7 @@ std::unique_ptr<InterpolableNumber> ConsumeControlAxis(double value,
float ConsumeInterpolableControlAxis(const InterpolableValue* number,
bool is_absolute,
double current_value) {
- double value = ToInterpolableNumber(number)->Value();
+ double value = To<InterpolableNumber>(number)->Value();
return clampTo<float>(is_absolute ? value : value - current_value);
}
@@ -37,7 +37,7 @@ float ConsumeInterpolableCoordinateAxis(const InterpolableValue* number,
bool is_absolute,
double& current_value) {
double previous_value = current_value;
- current_value = ToInterpolableNumber(number)->Value();
+ current_value = To<InterpolableNumber>(number)->Value();
return clampTo<float>(is_absolute ? current_value
: current_value - previous_value);
}
@@ -85,7 +85,7 @@ PathSegmentData ConsumeInterpolableSingleCoordinate(
const InterpolableValue& value,
SVGPathSegType seg_type,
PathCoordinates& coordinates) {
- const InterpolableList& list = ToInterpolableList(value);
+ const auto& list = To<InterpolableList>(value);
bool is_absolute = IsAbsolutePathSegType(seg_type);
PathSegmentData segment;
segment.command = seg_type;
@@ -127,7 +127,7 @@ std::unique_ptr<InterpolableValue> ConsumeCurvetoCubic(
PathSegmentData ConsumeInterpolableCurvetoCubic(const InterpolableValue& value,
SVGPathSegType seg_type,
PathCoordinates& coordinates) {
- const InterpolableList& list = ToInterpolableList(value);
+ const auto& list = To<InterpolableList>(value);
bool is_absolute = IsAbsolutePathSegType(seg_type);
PathSegmentData segment;
segment.command = seg_type;
@@ -166,7 +166,7 @@ PathSegmentData ConsumeInterpolableCurvetoQuadratic(
const InterpolableValue& value,
SVGPathSegType seg_type,
PathCoordinates& coordinates) {
- const InterpolableList& list = ToInterpolableList(value);
+ const auto& list = To<InterpolableList>(value);
bool is_absolute = IsAbsolutePathSegType(seg_type);
PathSegmentData segment;
segment.command = seg_type;
@@ -201,7 +201,7 @@ std::unique_ptr<InterpolableValue> ConsumeArc(const PathSegmentData& segment,
PathSegmentData ConsumeInterpolableArc(const InterpolableValue& value,
SVGPathSegType seg_type,
PathCoordinates& coordinates) {
- const InterpolableList& list = ToInterpolableList(value);
+ const auto& list = To<InterpolableList>(value);
bool is_absolute = IsAbsolutePathSegType(seg_type);
PathSegmentData segment;
segment.command = seg_type;
@@ -209,11 +209,11 @@ PathSegmentData ConsumeInterpolableArc(const InterpolableValue& value,
list.Get(0), is_absolute, coordinates.current_x));
segment.target_point.SetY(ConsumeInterpolableCoordinateAxis(
list.Get(1), is_absolute, coordinates.current_y));
- segment.ArcRadii().SetX(ToInterpolableNumber(list.Get(2))->Value());
- segment.ArcRadii().SetY(ToInterpolableNumber(list.Get(3))->Value());
- segment.SetArcAngle(ToInterpolableNumber(list.Get(4))->Value());
- segment.arc_large = ToInterpolableNumber(list.Get(5))->Value() >= 0.5;
- segment.arc_sweep = ToInterpolableNumber(list.Get(6))->Value() >= 0.5;
+ segment.ArcRadii().SetX(To<InterpolableNumber>(list.Get(2))->Value());
+ segment.ArcRadii().SetY(To<InterpolableNumber>(list.Get(3))->Value());
+ segment.SetArcAngle(To<InterpolableNumber>(list.Get(4))->Value());
+ segment.arc_large = To<InterpolableNumber>(list.Get(5))->Value() >= 0.5;
+ segment.arc_sweep = To<InterpolableNumber>(list.Get(6))->Value() >= 0.5;
return segment;
}
@@ -275,7 +275,7 @@ PathSegmentData ConsumeInterpolableCurvetoCubicSmooth(
const InterpolableValue& value,
SVGPathSegType seg_type,
PathCoordinates& coordinates) {
- const InterpolableList& list = ToInterpolableList(value);
+ const auto& list = To<InterpolableList>(value);
bool is_absolute = IsAbsolutePathSegType(seg_type);
PathSegmentData segment;
segment.command = seg_type;
diff --git a/chromium/third_party/blink/renderer/core/animation/svg_point_list_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/svg_point_list_interpolation_type.cc
index 86b32f0abb8..a608927ed7f 100644
--- a/chromium/third_party/blink/renderer/core/animation/svg_point_list_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/svg_point_list_interpolation_type.cc
@@ -37,7 +37,7 @@ InterpolationValue SVGPointListInterpolationType::MaybeConvertSVGValue(
if (svg_value.GetType() != kAnimatedPoints)
return nullptr;
- const SVGPointList& point_list = ToSVGPointList(svg_value);
+ const auto& point_list = To<SVGPointList>(svg_value);
auto result = std::make_unique<InterpolableList>(point_list.length() * 2);
for (wtf_size_t i = 0; i < point_list.length(); i++) {
const SVGPoint& point = *point_list.at(i);
@@ -52,8 +52,9 @@ PairwiseInterpolationValue SVGPointListInterpolationType::MaybeMergeSingles(
InterpolationValue&& start,
InterpolationValue&& end) const {
wtf_size_t start_length =
- ToInterpolableList(*start.interpolable_value).length();
- wtf_size_t end_length = ToInterpolableList(*end.interpolable_value).length();
+ To<InterpolableList>(*start.interpolable_value).length();
+ wtf_size_t end_length =
+ To<InterpolableList>(*end.interpolable_value).length();
if (start_length != end_length)
return nullptr;
@@ -66,10 +67,10 @@ void SVGPointListInterpolationType::Composite(
const InterpolationValue& value,
double interpolation_fraction) const {
wtf_size_t start_length =
- ToInterpolableList(*underlying_value_owner.Value().interpolable_value)
+ To<InterpolableList>(*underlying_value_owner.Value().interpolable_value)
.length();
wtf_size_t end_length =
- ToInterpolableList(*value.interpolable_value).length();
+ To<InterpolableList>(*value.interpolable_value).length();
if (start_length == end_length)
InterpolationType::Composite(underlying_value_owner, underlying_fraction,
value, interpolation_fraction);
@@ -82,12 +83,12 @@ SVGPropertyBase* SVGPointListInterpolationType::AppliedSVGValue(
const NonInterpolableValue*) const {
auto* result = MakeGarbageCollected<SVGPointList>();
- const InterpolableList& list = ToInterpolableList(interpolable_value);
+ const auto& list = To<InterpolableList>(interpolable_value);
DCHECK_EQ(list.length() % 2, 0U);
for (wtf_size_t i = 0; i < list.length(); i += 2) {
FloatPoint point =
- FloatPoint(ToInterpolableNumber(list.Get(i))->Value(),
- ToInterpolableNumber(list.Get(i + 1))->Value());
+ FloatPoint(To<InterpolableNumber>(list.Get(i))->Value(),
+ To<InterpolableNumber>(list.Get(i + 1))->Value());
result->Append(MakeGarbageCollected<SVGPoint>(point));
}
diff --git a/chromium/third_party/blink/renderer/core/animation/svg_rect_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/svg_rect_interpolation_type.cc
index 39ad3523616..ffc5753df72 100644
--- a/chromium/third_party/blink/renderer/core/animation/svg_rect_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/svg_rect_interpolation_type.cc
@@ -36,7 +36,7 @@ InterpolationValue SVGRectInterpolationType::MaybeConvertSVGValue(
if (svg_value.GetType() != kAnimatedRect)
return nullptr;
- const SVGRect& rect = ToSVGRect(svg_value);
+ const auto& rect = To<SVGRect>(svg_value);
auto result = std::make_unique<InterpolableList>(kRectComponentIndexCount);
result->Set(kRectX, std::make_unique<InterpolableNumber>(rect.X()));
result->Set(kRectY, std::make_unique<InterpolableNumber>(rect.Y()));
@@ -48,12 +48,12 @@ InterpolationValue SVGRectInterpolationType::MaybeConvertSVGValue(
SVGPropertyBase* SVGRectInterpolationType::AppliedSVGValue(
const InterpolableValue& interpolable_value,
const NonInterpolableValue*) const {
- const InterpolableList& list = ToInterpolableList(interpolable_value);
+ const auto& list = To<InterpolableList>(interpolable_value);
auto* result = MakeGarbageCollected<SVGRect>();
- result->SetX(ToInterpolableNumber(list.Get(kRectX))->Value());
- result->SetY(ToInterpolableNumber(list.Get(kRectY))->Value());
- result->SetWidth(ToInterpolableNumber(list.Get(kRectWidth))->Value());
- result->SetHeight(ToInterpolableNumber(list.Get(kRectHeight))->Value());
+ result->SetX(To<InterpolableNumber>(list.Get(kRectX))->Value());
+ result->SetY(To<InterpolableNumber>(list.Get(kRectY))->Value());
+ result->SetWidth(To<InterpolableNumber>(list.Get(kRectWidth))->Value());
+ result->SetHeight(To<InterpolableNumber>(list.Get(kRectHeight))->Value());
return result;
}
diff --git a/chromium/third_party/blink/renderer/core/animation/svg_transform_list_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/svg_transform_list_interpolation_type.cc
index 56bcdeb1e24..ae44164e112 100644
--- a/chromium/third_party/blink/renderer/core/animation/svg_transform_list_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/svg_transform_list_interpolation_type.cc
@@ -43,7 +43,15 @@ class SVGTransformNonInterpolableValue : public NonInterpolableValue {
};
DEFINE_NON_INTERPOLABLE_VALUE_TYPE(SVGTransformNonInterpolableValue);
-DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(SVGTransformNonInterpolableValue);
+template <>
+struct DowncastTraits<SVGTransformNonInterpolableValue> {
+ static bool AllowFrom(const NonInterpolableValue* value) {
+ return value && AllowFrom(*value);
+ }
+ static bool AllowFrom(const NonInterpolableValue& value) {
+ return value.GetType() == SVGTransformNonInterpolableValue::static_type_;
+ }
+};
namespace {
@@ -57,12 +65,12 @@ std::unique_ptr<InterpolableValue> TranslateToInterpolableValue(
}
SVGTransform* TranslateFromInterpolableValue(const InterpolableValue& value) {
- const InterpolableList& list = ToInterpolableList(value);
+ const auto& list = To<InterpolableList>(value);
auto* transform =
MakeGarbageCollected<SVGTransform>(SVGTransformType::kTranslate);
- transform->SetTranslate(ToInterpolableNumber(list.Get(0))->Value(),
- ToInterpolableNumber(list.Get(1))->Value());
+ transform->SetTranslate(To<InterpolableNumber>(list.Get(0))->Value(),
+ To<InterpolableNumber>(list.Get(1))->Value());
return transform;
}
@@ -76,12 +84,12 @@ std::unique_ptr<InterpolableValue> ScaleToInterpolableValue(
}
SVGTransform* ScaleFromInterpolableValue(const InterpolableValue& value) {
- const InterpolableList& list = ToInterpolableList(value);
+ const auto& list = To<InterpolableList>(value);
auto* transform =
MakeGarbageCollected<SVGTransform>(SVGTransformType::kScale);
- transform->SetScale(ToInterpolableNumber(list.Get(0))->Value(),
- ToInterpolableNumber(list.Get(1))->Value());
+ transform->SetScale(To<InterpolableNumber>(list.Get(0))->Value(),
+ To<InterpolableNumber>(list.Get(1))->Value());
return transform;
}
@@ -96,13 +104,13 @@ std::unique_ptr<InterpolableValue> RotateToInterpolableValue(
}
SVGTransform* RotateFromInterpolableValue(const InterpolableValue& value) {
- const InterpolableList& list = ToInterpolableList(value);
+ const auto& list = To<InterpolableList>(value);
auto* transform =
MakeGarbageCollected<SVGTransform>(SVGTransformType::kRotate);
- transform->SetRotate(ToInterpolableNumber(list.Get(0))->Value(),
- ToInterpolableNumber(list.Get(1))->Value(),
- ToInterpolableNumber(list.Get(2))->Value());
+ transform->SetRotate(To<InterpolableNumber>(list.Get(0))->Value(),
+ To<InterpolableNumber>(list.Get(1))->Value(),
+ To<InterpolableNumber>(list.Get(2))->Value());
return transform;
}
@@ -114,7 +122,7 @@ std::unique_ptr<InterpolableValue> SkewXToInterpolableValue(
SVGTransform* SkewXFromInterpolableValue(const InterpolableValue& value) {
auto* transform =
MakeGarbageCollected<SVGTransform>(SVGTransformType::kSkewx);
- transform->SetSkewX(ToInterpolableNumber(value).Value());
+ transform->SetSkewX(To<InterpolableNumber>(value).Value());
return transform;
}
@@ -126,7 +134,7 @@ std::unique_ptr<InterpolableValue> SkewYToInterpolableValue(
SVGTransform* SkewYFromInterpolableValue(const InterpolableValue& value) {
auto* transform =
MakeGarbageCollected<SVGTransform>(SVGTransformType::kSkewy);
- transform->SetSkewY(ToInterpolableNumber(value).Value());
+ transform->SetSkewY(To<InterpolableNumber>(value).Value());
return transform;
}
@@ -175,7 +183,7 @@ SVGTransform* FromInterpolableValue(const InterpolableValue& value,
const Vector<SVGTransformType>& GetTransformTypes(
const InterpolationValue& value) {
- return ToSVGTransformNonInterpolableValue(*value.non_interpolable_value)
+ return To<SVGTransformNonInterpolableValue>(*value.non_interpolable_value)
.TransformTypes();
}
@@ -214,15 +222,15 @@ InterpolationValue SVGTransformListInterpolationType::MaybeConvertNeutral(
InterpolationValue SVGTransformListInterpolationType::MaybeConvertSVGValue(
const SVGPropertyBase& svg_value) const {
- if (svg_value.GetType() != kAnimatedTransformList)
+ const auto* svg_list = DynamicTo<SVGTransformList>(svg_value);
+ if (!svg_list)
return nullptr;
- const SVGTransformList& svg_list = ToSVGTransformList(svg_value);
- auto result = std::make_unique<InterpolableList>(svg_list.length());
+ auto result = std::make_unique<InterpolableList>(svg_list->length());
Vector<SVGTransformType> transform_types;
- for (wtf_size_t i = 0; i < svg_list.length(); i++) {
- const SVGTransform* transform = svg_list.at(i);
+ for (wtf_size_t i = 0; i < svg_list->length(); i++) {
+ const SVGTransform* transform = svg_list->at(i);
SVGTransformType transform_type(transform->TransformType());
if (transform_type == SVGTransformType::kMatrix) {
// TODO(ericwilligers): Support matrix interpolation.
@@ -256,10 +264,11 @@ InterpolationValue SVGTransformListInterpolationType::MaybeConvertSingle(
}
if (!keyframe.IsNeutral()) {
- SVGPropertyBase* svg_value =
- ToSVGInterpolationEnvironment(environment)
+ auto* svg_value =
+ To<SVGInterpolationEnvironment>(environment)
.SvgBaseValue()
- .CloneForAnimation(ToSVGPropertySpecificKeyframe(keyframe).Value());
+ .CloneForAnimation(
+ To<SVGPropertySpecificKeyframe>(keyframe).Value());
InterpolationValue value = MaybeConvertSVGValue(*svg_value);
if (!value)
return nullptr;
@@ -270,7 +279,7 @@ InterpolationValue SVGTransformListInterpolationType::MaybeConvertSingle(
auto interpolable_list = std::make_unique<InterpolableList>(types.size());
wtf_size_t interpolable_list_index = 0;
for (auto& part : interpolable_parts) {
- InterpolableList& list = ToInterpolableList(*part);
+ auto& list = To<InterpolableList>(*part);
for (wtf_size_t i = 0; i < list.length(); ++i) {
interpolable_list->Set(interpolable_list_index,
std::move(list.GetMutable(i)));
@@ -286,9 +295,9 @@ SVGPropertyBase* SVGTransformListInterpolationType::AppliedSVGValue(
const InterpolableValue& interpolable_value,
const NonInterpolableValue* non_interpolable_value) const {
auto* result = MakeGarbageCollected<SVGTransformList>();
- const InterpolableList& list = ToInterpolableList(interpolable_value);
+ const auto& list = To<InterpolableList>(interpolable_value);
const Vector<SVGTransformType>& transform_types =
- ToSVGTransformNonInterpolableValue(non_interpolable_value)
+ To<SVGTransformNonInterpolableValue>(non_interpolable_value)
->TransformTypes();
for (wtf_size_t i = 0; i < list.length(); ++i)
result->Append(FromInterpolableValue(*list.Get(i), transform_types.at(i)));
diff --git a/chromium/third_party/blink/renderer/core/animation/svg_value_interpolation_type.cc b/chromium/third_party/blink/renderer/core/animation/svg_value_interpolation_type.cc
index 5792ea7e0e9..9c463a64ce8 100644
--- a/chromium/third_party/blink/renderer/core/animation/svg_value_interpolation_type.cc
+++ b/chromium/third_party/blink/renderer/core/animation/svg_value_interpolation_type.cc
@@ -31,7 +31,15 @@ class SVGValueNonInterpolableValue : public NonInterpolableValue {
};
DEFINE_NON_INTERPOLABLE_VALUE_TYPE(SVGValueNonInterpolableValue);
-DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(SVGValueNonInterpolableValue);
+template <>
+struct DowncastTraits<SVGValueNonInterpolableValue> {
+ static bool AllowFrom(const NonInterpolableValue* value) {
+ return value && AllowFrom(*value);
+ }
+ static bool AllowFrom(const NonInterpolableValue& value) {
+ return value.GetType() == SVGValueNonInterpolableValue::static_type_;
+ }
+};
InterpolationValue SVGValueInterpolationType::MaybeConvertSVGValue(
const SVGPropertyBase& value) const {
@@ -45,7 +53,7 @@ InterpolationValue SVGValueInterpolationType::MaybeConvertSVGValue(
SVGPropertyBase* SVGValueInterpolationType::AppliedSVGValue(
const InterpolableValue&,
const NonInterpolableValue* non_interpolable_value) const {
- return ToSVGValueNonInterpolableValue(*non_interpolable_value).SvgValue();
+ return To<SVGValueNonInterpolableValue>(*non_interpolable_value).SvgValue();
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/timing.cc b/chromium/third_party/blink/renderer/core/animation/timing.cc
index a6d37088824..ea3e60d22e3 100644
--- a/chromium/third_party/blink/renderer/core/animation/timing.cc
+++ b/chromium/third_party/blink/renderer/core/animation/timing.cc
@@ -4,8 +4,8 @@
#include "third_party/blink/renderer/core/animation/timing.h"
-#include "third_party/blink/renderer/core/animation/computed_effect_timing.h"
-#include "third_party/blink/renderer/core/animation/effect_timing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_computed_effect_timing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_effect_timing.h"
#include "third_party/blink/renderer/core/animation/timing_calculations.h"
namespace blink {
@@ -186,7 +186,7 @@ Timing::CalculatedTiming Timing::CalculateTimings(
current_direction_is_forwards,
timing_function);
- double time_to_next_iteration = std::numeric_limits<double>::infinity();
+ AnimationTimeDelta time_to_next_iteration = AnimationTimeDelta::Max();
// Conditionally compute the time to next iteration, which is only
// applicable if the iteration duration is non-zero.
if (iteration_duration) {
@@ -203,9 +203,12 @@ Timing::CalculatedTiming Timing::CalculateTimings(
// active_time cannot be null if iteration_time is not null.
DCHECK(active_time);
time_to_next_iteration =
- iteration_duration - iteration_time->InSecondsF();
- if (active_duration - active_time->InSecondsF() < time_to_next_iteration)
- time_to_next_iteration = std::numeric_limits<double>::infinity();
+ AnimationTimeDelta::FromSecondsD(iteration_duration) -
+ iteration_time.value();
+ if (AnimationTimeDelta::FromSecondsD(active_duration) -
+ active_time.value() <
+ time_to_next_iteration)
+ time_to_next_iteration = AnimationTimeDelta::Max();
}
}
diff --git a/chromium/third_party/blink/renderer/core/animation/timing.h b/chromium/third_party/blink/renderer/core/animation/timing.h
index e3d386eeb2d..18cfd2127fc 100644
--- a/chromium/third_party/blink/renderer/core/animation/timing.h
+++ b/chromium/third_party/blink/renderer/core/animation/timing.h
@@ -45,18 +45,6 @@ namespace blink {
class EffectTiming;
class ComputedEffectTiming;
-static inline bool IsNull(double value) {
- return std::isnan(value);
-}
-
-static inline double NullValue() {
- return std::numeric_limits<double>::quiet_NaN();
-}
-
-static inline base::Optional<double> ValueOrUnresolved(double a) {
- return IsNull(a) ? base::nullopt : base::Optional<double>(a);
-}
-
struct CORE_EXPORT Timing {
USING_FAST_MALLOC(Timing);
@@ -75,9 +63,27 @@ struct CORE_EXPORT Timing {
kBackwards,
};
+ // Timing properties set via AnimationEffect.updateTiming override their
+ // corresponding CSS properties.
+ enum AnimationTimingOverride {
+ kOverrideNode = 0,
+ kOverrideDirection = 1,
+ kOverrideDuration = 1 << 1,
+ kOverrideEndDelay = 1 << 2,
+ kOverideFillMode = 1 << 3,
+ kOverrideIterationCount = 1 << 4,
+ kOverrideIterationStart = 1 << 5,
+ kOverrideStartDelay = 1 << 6,
+ kOverrideTimingFunction = 1 << 7,
+ kOverrideAll = (1 << 8) - 1
+ };
+
using FillMode = CompositorKeyframeModel::FillMode;
using PlaybackDirection = CompositorKeyframeModel::Direction;
+ static bool IsNull(double value) { return std::isnan(value); }
+ static double NullValue() { return std::numeric_limits<double>::quiet_NaN(); }
+
static String FillModeString(FillMode);
static FillMode StringToFillMode(const String&);
static String PlaybackDirectionString(PlaybackDirection);
@@ -90,7 +96,8 @@ struct CORE_EXPORT Timing {
iteration_count(1),
iteration_duration(base::nullopt),
direction(PlaybackDirection::NORMAL),
- timing_function(LinearTimingFunction::Shared()) {}
+ timing_function(LinearTimingFunction::Shared()),
+ timing_overrides(kOverrideNode) {}
void AssertValid() const {
DCHECK(std::isfinite(start_delay));
@@ -125,6 +132,16 @@ struct CORE_EXPORT Timing {
bool operator!=(const Timing& other) const { return !(*this == other); }
+ // Explicit changes to animation timing through the web animations API,
+ // override timing changes due to CSS style.
+ void SetTimingOverride(AnimationTimingOverride override) {
+ timing_overrides |= override;
+ }
+ bool HasTimingOverride(AnimationTimingOverride override) {
+ return timing_overrides & override;
+ }
+ bool HasTimingOverrides() { return timing_overrides != kOverrideNode; }
+
double start_delay;
double end_delay;
FillMode fill_mode;
@@ -135,6 +152,10 @@ struct CORE_EXPORT Timing {
PlaybackDirection direction;
scoped_refptr<TimingFunction> timing_function;
+ // Mask of timing attributes that are set by calls to
+ // AnimationEffect.updateTiming. Once set, these attributes ignore changes
+ // based on the CSS style.
+ uint16_t timing_overrides;
struct CalculatedTiming {
DISALLOW_NEW();
@@ -149,7 +170,7 @@ struct CORE_EXPORT Timing {
AnimationTimeDelta::Max();
AnimationTimeDelta time_to_reverse_effect_change =
AnimationTimeDelta::Max();
- double time_to_next_iteration = std::numeric_limits<double>::infinity();
+ AnimationTimeDelta time_to_next_iteration = AnimationTimeDelta::Max();
};
CalculatedTiming CalculateTimings(base::Optional<double> local_time,
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 5880c5363f7..370e9a3f8fa 100644
--- a/chromium/third_party/blink/renderer/core/animation/timing_calculations.h
+++ b/chromium/third_party/blink/renderer/core/animation/timing_calculations.h
@@ -55,14 +55,14 @@ inline bool EndsOnIterationBoundary(double iteration_count,
} // namespace
static inline double MultiplyZeroAlwaysGivesZero(double x, double y) {
- DCHECK(!IsNull(x));
- DCHECK(!IsNull(y));
+ DCHECK(!Timing::IsNull(x));
+ DCHECK(!Timing::IsNull(y));
return x && y ? x * y : 0;
}
static inline double MultiplyZeroAlwaysGivesZero(AnimationTimeDelta x,
double y) {
- DCHECK(!IsNull(y));
+ DCHECK(!Timing::IsNull(y));
return x.is_zero() || y == 0 ? 0 : (x * y).InSecondsF();
}
diff --git a/chromium/third_party/blink/renderer/core/animation/timing_input.cc b/chromium/third_party/blink/renderer/core/animation/timing_input.cc
index 13ee259b599..f98e49ecb4a 100644
--- a/chromium/third_party/blink/renderer/core/animation/timing_input.cc
+++ b/chromium/third_party/blink/renderer/core/animation/timing_input.cc
@@ -6,11 +6,11 @@
#include "third_party/blink/renderer/bindings/core/v8/unrestricted_double_or_keyframe_animation_options.h"
#include "third_party/blink/renderer/bindings/core/v8/unrestricted_double_or_keyframe_effect_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_effect_timing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_keyframe_effect_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_optional_effect_timing.h"
#include "third_party/blink/renderer/core/animation/animation_effect.h"
#include "third_party/blink/renderer/core/animation/animation_input_helpers.h"
-#include "third_party/blink/renderer/core/animation/effect_timing.h"
-#include "third_party/blink/renderer/core/animation/keyframe_effect_options.h"
-#include "third_party/blink/renderer/core/animation/optional_effect_timing.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
namespace blink {
@@ -164,30 +164,37 @@ bool TimingInput::Update(Timing& timing,
if (input->hasDelay()) {
DCHECK(std::isfinite(input->delay()));
changed |= UpdateValueIfChanged(timing.start_delay, input->delay() / 1000);
+ timing.SetTimingOverride(Timing::kOverrideStartDelay);
}
if (input->hasEndDelay()) {
DCHECK(std::isfinite(input->endDelay()));
changed |= UpdateValueIfChanged(timing.end_delay, input->endDelay() / 1000);
+ timing.SetTimingOverride(Timing::kOverrideEndDelay);
}
if (input->hasFill()) {
changed |= UpdateValueIfChanged(timing.fill_mode,
Timing::StringToFillMode(input->fill()));
+ timing.SetTimingOverride(Timing::kOverideFillMode);
}
if (input->hasIterationStart()) {
changed |=
UpdateValueIfChanged(timing.iteration_start, input->iterationStart());
+ timing.SetTimingOverride(Timing::kOverrideIterationStart);
}
if (input->hasIterations()) {
changed |=
UpdateValueIfChanged(timing.iteration_count, input->iterations());
+ timing.SetTimingOverride(Timing::kOverrideIterationCount);
}
if (input->hasDuration()) {
changed |= UpdateValueIfChanged(
timing.iteration_duration, ConvertIterationDuration(input->duration()));
+ timing.SetTimingOverride(Timing::kOverrideDuration);
}
if (input->hasDirection()) {
changed |= UpdateValueIfChanged(
timing.direction, ConvertPlaybackDirection(input->direction()));
+ timing.SetTimingOverride(Timing::kOverrideDirection);
}
if (timing_function) {
// We need to compare the timing functions by underlying value to see if
@@ -195,8 +202,8 @@ bool TimingInput::Update(Timing& timing,
// UpdateValueIfChanged.
changed |= (*timing.timing_function != *timing_function);
timing.timing_function = timing_function;
+ timing.SetTimingOverride(Timing::kOverrideTimingFunction);
}
-
return changed;
}
diff --git a/chromium/third_party/blink/renderer/core/animation/timing_input_test.cc b/chromium/third_party/blink/renderer/core/animation/timing_input_test.cc
index 0b2487d5d53..3ab294441d0 100644
--- a/chromium/third_party/blink/renderer/core/animation/timing_input_test.cc
+++ b/chromium/third_party/blink/renderer/core/animation/timing_input_test.cc
@@ -50,18 +50,16 @@ Timing AnimationTimingInputTest::ApplyTimingInputNumber(
Timing result;
if (is_keyframeeffectoptions) {
KeyframeEffectOptions* timing_input_dictionary =
- KeyframeEffectOptions::Create();
- V8KeyframeEffectOptions::ToImpl(isolate, timing_input,
- timing_input_dictionary, exception_state);
+ NativeValueTraits<KeyframeEffectOptions>::NativeValue(
+ isolate, timing_input, exception_state);
UnrestrictedDoubleOrKeyframeEffectOptions timing_input =
UnrestrictedDoubleOrKeyframeEffectOptions::FromKeyframeEffectOptions(
timing_input_dictionary);
result = TimingInput::Convert(timing_input, GetDocument(), exception_state);
} else {
KeyframeAnimationOptions* timing_input_dictionary =
- KeyframeAnimationOptions::Create();
- V8KeyframeAnimationOptions::ToImpl(
- isolate, timing_input, timing_input_dictionary, exception_state);
+ NativeValueTraits<KeyframeAnimationOptions>::NativeValue(
+ isolate, timing_input, exception_state);
UnrestrictedDoubleOrKeyframeAnimationOptions timing_input =
UnrestrictedDoubleOrKeyframeAnimationOptions::
FromKeyframeAnimationOptions(timing_input_dictionary);
@@ -85,18 +83,16 @@ Timing AnimationTimingInputTest::ApplyTimingInputString(
Timing result;
if (is_keyframeeffectoptions) {
KeyframeEffectOptions* timing_input_dictionary =
- KeyframeEffectOptions::Create();
- V8KeyframeEffectOptions::ToImpl(isolate, timing_input,
- timing_input_dictionary, exception_state);
+ NativeValueTraits<KeyframeEffectOptions>::NativeValue(
+ isolate, timing_input, exception_state);
UnrestrictedDoubleOrKeyframeEffectOptions timing_input =
UnrestrictedDoubleOrKeyframeEffectOptions::FromKeyframeEffectOptions(
timing_input_dictionary);
result = TimingInput::Convert(timing_input, GetDocument(), exception_state);
} else {
KeyframeAnimationOptions* timing_input_dictionary =
- KeyframeAnimationOptions::Create();
- V8KeyframeAnimationOptions::ToImpl(
- isolate, timing_input, timing_input_dictionary, exception_state);
+ NativeValueTraits<KeyframeAnimationOptions>::NativeValue(
+ isolate, timing_input, exception_state);
UnrestrictedDoubleOrKeyframeAnimationOptions timing_input =
UnrestrictedDoubleOrKeyframeAnimationOptions::
FromKeyframeAnimationOptions(timing_input_dictionary);
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 62e7b92fc77..e87dd4ba911 100644
--- a/chromium/third_party/blink/renderer/core/animation/transition_interpolation.h
+++ b/chromium/third_party/blink/renderer/core/animation/transition_interpolation.h
@@ -98,11 +98,12 @@ class CORE_EXPORT TransitionInterpolation : public Interpolation {
mutable std::unique_ptr<InterpolableValue> cached_interpolable_value_;
};
-DEFINE_TYPE_CASTS(TransitionInterpolation,
- Interpolation,
- value,
- value->IsTransitionInterpolation(),
- value.IsTransitionInterpolation());
+template <>
+struct DowncastTraits<TransitionInterpolation> {
+ static bool AllowFrom(const Interpolation& value) {
+ return value.IsTransitionInterpolation();
+ }
+};
} // namespace blink
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 47a28c5f6a9..a26bc65b634 100644
--- a/chromium/third_party/blink/renderer/core/animation/transition_keyframe.cc
+++ b/chromium/third_party/blink/renderer/core/animation/transition_keyframe.cc
@@ -54,8 +54,7 @@ Interpolation*
TransitionKeyframe::PropertySpecificKeyframe::CreateInterpolation(
const PropertyHandle& property,
const Keyframe::PropertySpecificKeyframe& other_super_class) const {
- const PropertySpecificKeyframe& other =
- ToTransitionPropertySpecificKeyframe(other_super_class);
+ const auto& other = To<TransitionPropertySpecificKeyframe>(other_super_class);
DCHECK(value_->GetType() == other.value_->GetType());
return MakeGarbageCollected<TransitionInterpolation>(
property, value_->GetType(), value_->Value().Clone(),
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 220700793c2..9a21096c312 100644
--- a/chromium/third_party/blink/renderer/core/animation/transition_keyframe.h
+++ b/chromium/third_party/blink/renderer/core/animation/transition_keyframe.h
@@ -109,16 +109,18 @@ class CORE_EXPORT TransitionKeyframe : public Keyframe {
using TransitionPropertySpecificKeyframe =
TransitionKeyframe::PropertySpecificKeyframe;
-DEFINE_TYPE_CASTS(TransitionKeyframe,
- Keyframe,
- value,
- value->IsTransitionKeyframe(),
- value.IsTransitionKeyframe());
-DEFINE_TYPE_CASTS(TransitionPropertySpecificKeyframe,
- Keyframe::PropertySpecificKeyframe,
- value,
- value->IsTransitionPropertySpecificKeyframe(),
- value.IsTransitionPropertySpecificKeyframe());
+template <>
+struct DowncastTraits<TransitionKeyframe> {
+ static bool AllowFrom(const Keyframe& value) {
+ return value.IsTransitionKeyframe();
+ }
+};
+template <>
+struct DowncastTraits<TransitionPropertySpecificKeyframe> {
+ static bool AllowFrom(const Keyframe::PropertySpecificKeyframe& value) {
+ return value.IsTransitionPropertySpecificKeyframe();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/animation/underlying_length_checker.h b/chromium/third_party/blink/renderer/core/animation/underlying_length_checker.h
index ba7d0b61ca7..badae96ef7c 100644
--- a/chromium/third_party/blink/renderer/core/animation/underlying_length_checker.h
+++ b/chromium/third_party/blink/renderer/core/animation/underlying_length_checker.h
@@ -21,7 +21,7 @@ class UnderlyingLengthChecker : public InterpolationType::ConversionChecker {
static wtf_size_t GetUnderlyingLength(const InterpolationValue& underlying) {
if (!underlying)
return 0;
- return ToInterpolableList(*underlying.interpolable_value).length();
+ return To<InterpolableList>(*underlying.interpolable_value).length();
}
bool IsValid(const InterpolationEnvironment&,
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 4b73d0a4fd9..b690076cf33 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
@@ -86,7 +86,7 @@ void WorkletAnimationController::ScrollSourceCompositingStateChanged(
DCHECK(ScrollTimeline::HasActiveScrollTimeline(node));
for (const auto& animation : animations_.Values()) {
if (animation->GetTimeline()->IsScrollTimeline() &&
- ToScrollTimeline(animation->GetTimeline())->scrollSource() == node) {
+ To<ScrollTimeline>(animation->GetTimeline())->scrollSource() == node) {
InvalidateAnimation(*animation);
}
}
@@ -160,7 +160,7 @@ void WorkletAnimationController::ApplyAnimationTimings(
animation->Update(reason);
}
-void WorkletAnimationController::Trace(blink::Visitor* visitor) {
+void WorkletAnimationController::Trace(Visitor* visitor) {
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 8e49013398d..175098293a2 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(blink::Visitor*);
+ void Trace(Visitor*);
private:
void MutateAnimations();
diff --git a/chromium/third_party/blink/renderer/core/animation_frame/BUILD.gn b/chromium/third_party/blink/renderer/core/animation_frame/BUILD.gn
index 5d6265cbaec..4ad9db73e15 100644
--- a/chromium/third_party/blink/renderer/core/animation_frame/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/animation_frame/BUILD.gn
@@ -9,7 +9,5 @@ blink_core_sources("animation_frame") {
"worker_animation_frame_provider.cc",
"worker_animation_frame_provider.h",
]
- deps = [
- "//mojo/public/cpp/bindings:bindings",
- ]
+ deps = [ "//mojo/public/cpp/bindings:bindings" ]
}
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 6152182b7c0..36fd6aaae50 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
@@ -83,7 +83,7 @@ void WorkerAnimationFrameProvider::DeregisterOffscreenCanvas(
}
}
-void WorkerAnimationFrameProvider::Trace(blink::Visitor* visitor) {
+void WorkerAnimationFrameProvider::Trace(Visitor* visitor) {
visitor->Trace(callback_collection_);
visitor->Trace(context_);
}
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 fdb656bd702..939883ce2df 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
@@ -36,7 +36,7 @@ class CORE_EXPORT WorkerAnimationFrameProvider
int RegisterCallback(FrameRequestCallbackCollection::FrameCallback* callback);
void CancelCallback(int id);
- void Trace(blink::Visitor* visitor);
+ void Trace(Visitor* visitor);
// BeginFrameProviderClient
void BeginFrame(const viz::BeginFrameArgs&) override;
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 901ccc59656..2e1cb679398 100644
--- a/chromium/third_party/blink/renderer/core/aom/accessible_node.cc
+++ b/chromium/third_party/blink/renderer/core/aom/accessible_node.cc
@@ -66,9 +66,6 @@ QualifiedName GetCorrespondingARIAAttribute(AOMRelationProperty property) {
case AOMRelationProperty::kActiveDescendant:
return html_names::kAriaActivedescendantAttr;
break;
- case AOMRelationProperty::kDetails:
- return html_names::kAriaDetailsAttr;
- break;
case AOMRelationProperty::kErrorMessage:
return html_names::kAriaErrormessageAttr;
break;
@@ -83,6 +80,9 @@ QualifiedName GetCorrespondingARIAAttribute(AOMRelationListProperty property) {
case AOMRelationListProperty::kDescribedBy:
return html_names::kAriaDescribedbyAttr;
break;
+ case AOMRelationListProperty::kDetails:
+ return html_names::kAriaDetailsAttr;
+ break;
case AOMRelationListProperty::kControls:
return html_names::kAriaControlsAttr;
break;
@@ -297,6 +297,17 @@ bool AccessibleNode::GetProperty(Element* element,
}
template <typename P, typename T>
+static base::Optional<T> FindPropertyValue(
+ P property,
+ const Vector<std::pair<P, T>>& properties) {
+ for (const auto& item : properties) {
+ if (item.first == property)
+ return item.second;
+ }
+ return base::nullopt;
+}
+
+template <typename P, typename T>
static T FindPropertyValue(P property,
bool& is_null,
const Vector<std::pair<P, T>>& properties,
@@ -311,6 +322,38 @@ static T FindPropertyValue(P property,
return default_value;
}
+base::Optional<bool> AccessibleNode::GetProperty(
+ AOMBooleanProperty property) const {
+ return FindPropertyValue(property, boolean_properties_);
+}
+
+// static
+base::Optional<int32_t> AccessibleNode::GetProperty(Element* element,
+ AOMIntProperty property) {
+ if (!element || !element->ExistingAccessibleNode())
+ return base::nullopt;
+ return FindPropertyValue(property,
+ element->ExistingAccessibleNode()->int_properties_);
+}
+
+// static
+base::Optional<uint32_t> AccessibleNode::GetProperty(Element* element,
+ AOMUIntProperty property) {
+ if (!element || !element->ExistingAccessibleNode())
+ return base::nullopt;
+ return FindPropertyValue(property,
+ element->ExistingAccessibleNode()->uint_properties_);
+}
+
+// static
+base::Optional<float> AccessibleNode::GetProperty(Element* element,
+ AOMFloatProperty property) {
+ if (!element || !element->ExistingAccessibleNode())
+ return base::nullopt;
+ return FindPropertyValue(
+ property, element->ExistingAccessibleNode()->float_properties_);
+}
+
bool AccessibleNode::GetProperty(AOMBooleanProperty property,
bool& is_null) const {
is_null = true;
@@ -556,6 +599,15 @@ void AccessibleNode::setActiveDescendant(AccessibleNode* active_descendant) {
NotifyAttributeChanged(html_names::kAriaActivedescendantAttr);
}
+base::Optional<bool> AccessibleNode::atomic() const {
+ return GetProperty(AOMBooleanProperty::kAtomic);
+}
+
+void AccessibleNode::setAtomic(base::Optional<bool> value) {
+ SetBooleanProperty(AOMBooleanProperty::kAtomic, value);
+ NotifyAttributeChanged(html_names::kAriaAtomicAttr);
+}
+
bool AccessibleNode::atomic(bool& is_null) const {
return GetProperty(AOMBooleanProperty::kAtomic, is_null);
}
@@ -574,6 +626,15 @@ void AccessibleNode::setAutocomplete(const AtomicString& autocomplete) {
NotifyAttributeChanged(html_names::kAriaAutocompleteAttr);
}
+base::Optional<bool> AccessibleNode::busy() const {
+ return GetProperty(AOMBooleanProperty::kBusy);
+}
+
+void AccessibleNode::setBusy(base::Optional<bool> value) {
+ SetBooleanProperty(AOMBooleanProperty::kBusy, value);
+ NotifyAttributeChanged(html_names::kAriaBusyAttr);
+}
+
bool AccessibleNode::busy(bool& is_null) const {
return GetProperty(AOMBooleanProperty::kBusy, is_null);
}
@@ -592,6 +653,15 @@ void AccessibleNode::setChecked(const AtomicString& checked) {
NotifyAttributeChanged(html_names::kAriaCheckedAttr);
}
+base::Optional<int32_t> AccessibleNode::colCount() const {
+ return GetProperty(element_, AOMIntProperty::kColCount);
+}
+
+void AccessibleNode::setColCount(base::Optional<int32_t> value) {
+ SetIntProperty(AOMIntProperty::kColCount, value);
+ NotifyAttributeChanged(html_names::kAriaColcountAttr);
+}
+
int32_t AccessibleNode::colCount(bool& is_null) const {
return GetProperty(element_, AOMIntProperty::kColCount, is_null);
}
@@ -601,6 +671,15 @@ void AccessibleNode::setColCount(int32_t col_count, bool is_null) {
NotifyAttributeChanged(html_names::kAriaColcountAttr);
}
+base::Optional<uint32_t> AccessibleNode::colIndex() const {
+ return GetProperty(element_, AOMUIntProperty::kColIndex);
+}
+
+void AccessibleNode::setColIndex(base::Optional<uint32_t> value) {
+ SetUIntProperty(AOMUIntProperty::kColIndex, value);
+ NotifyAttributeChanged(html_names::kAriaColindexAttr);
+}
+
uint32_t AccessibleNode::colIndex(bool& is_null) const {
return GetProperty(element_, AOMUIntProperty::kColIndex, is_null);
}
@@ -610,6 +689,15 @@ void AccessibleNode::setColIndex(uint32_t col_index, bool is_null) {
NotifyAttributeChanged(html_names::kAriaColindexAttr);
}
+base::Optional<uint32_t> AccessibleNode::colSpan() const {
+ return GetProperty(element_, AOMUIntProperty::kColSpan);
+}
+
+void AccessibleNode::setColSpan(base::Optional<uint32_t> value) {
+ SetUIntProperty(AOMUIntProperty::kColSpan, value);
+ NotifyAttributeChanged(html_names::kAriaColspanAttr);
+}
+
uint32_t AccessibleNode::colSpan(bool& is_null) const {
return GetProperty(element_, AOMUIntProperty::kColSpan, is_null);
}
@@ -655,15 +743,24 @@ void AccessibleNode::setDescription(const AtomicString& description) {
NotifyAttributeChanged(html_names::kAriaDescriptionAttr);
}
-AccessibleNode* AccessibleNode::details() const {
- return GetProperty(element_, AOMRelationProperty::kDetails);
+AccessibleNodeList* AccessibleNode::details() const {
+ return GetProperty(element_, AOMRelationListProperty::kDetails);
}
-void AccessibleNode::setDetails(AccessibleNode* details) {
- SetRelationProperty(AOMRelationProperty::kDetails, details);
+void AccessibleNode::setDetails(AccessibleNodeList* details) {
+ SetRelationListProperty(AOMRelationListProperty::kDetails, details);
NotifyAttributeChanged(html_names::kAriaDetailsAttr);
}
+base::Optional<bool> AccessibleNode::disabled() const {
+ return GetProperty(AOMBooleanProperty::kDisabled);
+}
+
+void AccessibleNode::setDisabled(base::Optional<bool> value) {
+ SetBooleanProperty(AOMBooleanProperty::kDisabled, value);
+ NotifyAttributeChanged(html_names::kAriaDisabledAttr);
+}
+
bool AccessibleNode::disabled(bool& is_null) const {
return GetProperty(AOMBooleanProperty::kDisabled, is_null);
}
@@ -682,6 +779,15 @@ void AccessibleNode::setErrorMessage(AccessibleNode* error_message) {
NotifyAttributeChanged(html_names::kAriaErrormessageAttr);
}
+base::Optional<bool> AccessibleNode::expanded() const {
+ return GetProperty(AOMBooleanProperty::kExpanded);
+}
+
+void AccessibleNode::setExpanded(base::Optional<bool> value) {
+ SetBooleanProperty(AOMBooleanProperty::kExpanded, value);
+ NotifyAttributeChanged(html_names::kAriaExpandedAttr);
+}
+
bool AccessibleNode::expanded(bool& is_null) const {
return GetProperty(AOMBooleanProperty::kExpanded, is_null);
}
@@ -709,6 +815,15 @@ void AccessibleNode::setHasPopUp(const AtomicString& has_popup) {
NotifyAttributeChanged(html_names::kAriaHaspopupAttr);
}
+base::Optional<bool> AccessibleNode::hidden() const {
+ return GetProperty(AOMBooleanProperty::kHidden);
+}
+
+void AccessibleNode::setHidden(base::Optional<bool> value) {
+ SetBooleanProperty(AOMBooleanProperty::kHidden, value);
+ NotifyAttributeChanged(html_names::kAriaHiddenAttr);
+}
+
bool AccessibleNode::hidden(bool& is_null) const {
return GetProperty(AOMBooleanProperty::kHidden, is_null);
}
@@ -754,6 +869,15 @@ void AccessibleNode::setLabeledBy(AccessibleNodeList* labeled_by) {
NotifyAttributeChanged(html_names::kAriaLabelledbyAttr);
}
+base::Optional<uint32_t> AccessibleNode::level() const {
+ return GetProperty(element_, AOMUIntProperty::kLevel);
+}
+
+void AccessibleNode::setLevel(base::Optional<uint32_t> value) {
+ SetUIntProperty(AOMUIntProperty::kLevel, value);
+ NotifyAttributeChanged(html_names::kAriaLevelAttr);
+}
+
uint32_t AccessibleNode::level(bool& is_null) const {
return GetProperty(element_, AOMUIntProperty::kLevel, is_null);
}
@@ -772,6 +896,15 @@ void AccessibleNode::setLive(const AtomicString& live) {
NotifyAttributeChanged(html_names::kAriaLiveAttr);
}
+base::Optional<bool> AccessibleNode::modal() const {
+ return GetProperty(AOMBooleanProperty::kModal);
+}
+
+void AccessibleNode::setModal(base::Optional<bool> value) {
+ SetBooleanProperty(AOMBooleanProperty::kModal, value);
+ NotifyAttributeChanged(html_names::kAriaModalAttr);
+}
+
bool AccessibleNode::modal(bool& is_null) const {
return GetProperty(AOMBooleanProperty::kModal, is_null);
}
@@ -781,6 +914,15 @@ void AccessibleNode::setModal(bool modal, bool is_null) {
NotifyAttributeChanged(html_names::kAriaModalAttr);
}
+base::Optional<bool> AccessibleNode::multiline() const {
+ return GetProperty(AOMBooleanProperty::kMultiline);
+}
+
+void AccessibleNode::setMultiline(base::Optional<bool> value) {
+ SetBooleanProperty(AOMBooleanProperty::kMultiline, value);
+ NotifyAttributeChanged(html_names::kAriaMultilineAttr);
+}
+
bool AccessibleNode::multiline(bool& is_null) const {
return GetProperty(AOMBooleanProperty::kMultiline, is_null);
}
@@ -790,6 +932,15 @@ void AccessibleNode::setMultiline(bool multiline, bool is_null) {
NotifyAttributeChanged(html_names::kAriaMultilineAttr);
}
+base::Optional<bool> AccessibleNode::multiselectable() const {
+ return GetProperty(AOMBooleanProperty::kMultiselectable);
+}
+
+void AccessibleNode::setMultiselectable(base::Optional<bool> value) {
+ SetBooleanProperty(AOMBooleanProperty::kMultiselectable, value);
+ NotifyAttributeChanged(html_names::kAriaMultiselectableAttr);
+}
+
bool AccessibleNode::multiselectable(bool& is_null) const {
return GetProperty(AOMBooleanProperty::kMultiselectable, is_null);
}
@@ -827,6 +978,15 @@ void AccessibleNode::setPlaceholder(const AtomicString& placeholder) {
NotifyAttributeChanged(html_names::kAriaPlaceholderAttr);
}
+base::Optional<uint32_t> AccessibleNode::posInSet() const {
+ return GetProperty(element_, AOMUIntProperty::kPosInSet);
+}
+
+void AccessibleNode::setPosInSet(base::Optional<uint32_t> value) {
+ SetUIntProperty(AOMUIntProperty::kPosInSet, value);
+ NotifyAttributeChanged(html_names::kAriaPosinsetAttr);
+}
+
uint32_t AccessibleNode::posInSet(bool& is_null) const {
return GetProperty(element_, AOMUIntProperty::kPosInSet, is_null);
}
@@ -845,6 +1005,15 @@ void AccessibleNode::setPressed(const AtomicString& pressed) {
NotifyAttributeChanged(html_names::kAriaPressedAttr);
}
+base::Optional<bool> AccessibleNode::readOnly() const {
+ return GetProperty(AOMBooleanProperty::kReadOnly);
+}
+
+void AccessibleNode::setReadOnly(base::Optional<bool> value) {
+ SetBooleanProperty(AOMBooleanProperty::kReadOnly, value);
+ NotifyAttributeChanged(html_names::kAriaReadonlyAttr);
+}
+
bool AccessibleNode::readOnly(bool& is_null) const {
return GetProperty(AOMBooleanProperty::kReadOnly, is_null);
}
@@ -863,6 +1032,15 @@ void AccessibleNode::setRelevant(const AtomicString& relevant) {
NotifyAttributeChanged(html_names::kAriaRelevantAttr);
}
+base::Optional<bool> AccessibleNode::required() const {
+ return GetProperty(AOMBooleanProperty::kRequired);
+}
+
+void AccessibleNode::setRequired(base::Optional<bool> value) {
+ SetBooleanProperty(AOMBooleanProperty::kRequired, value);
+ NotifyAttributeChanged(html_names::kAriaRequiredAttr);
+}
+
bool AccessibleNode::required(bool& is_null) const {
return GetProperty(AOMBooleanProperty::kRequired, is_null);
}
@@ -890,6 +1068,15 @@ void AccessibleNode::setRoleDescription(const AtomicString& role_description) {
NotifyAttributeChanged(html_names::kAriaRoledescriptionAttr);
}
+base::Optional<int32_t> AccessibleNode::rowCount() const {
+ return GetProperty(element_, AOMIntProperty::kRowCount);
+}
+
+void AccessibleNode::setRowCount(base::Optional<int32_t> value) {
+ SetIntProperty(AOMIntProperty::kRowCount, value);
+ NotifyAttributeChanged(html_names::kAriaRowcountAttr);
+}
+
int32_t AccessibleNode::rowCount(bool& is_null) const {
return GetProperty(element_, AOMIntProperty::kRowCount, is_null);
}
@@ -899,6 +1086,15 @@ void AccessibleNode::setRowCount(int32_t row_count, bool is_null) {
NotifyAttributeChanged(html_names::kAriaRowcountAttr);
}
+base::Optional<uint32_t> AccessibleNode::rowIndex() const {
+ return GetProperty(element_, AOMUIntProperty::kRowIndex);
+}
+
+void AccessibleNode::setRowIndex(base::Optional<uint32_t> value) {
+ SetUIntProperty(AOMUIntProperty::kRowIndex, value);
+ NotifyAttributeChanged(html_names::kAriaRowindexAttr);
+}
+
uint32_t AccessibleNode::rowIndex(bool& is_null) const {
return GetProperty(element_, AOMUIntProperty::kRowIndex, is_null);
}
@@ -908,6 +1104,15 @@ void AccessibleNode::setRowIndex(uint32_t row_index, bool is_null) {
NotifyAttributeChanged(html_names::kAriaRowindexAttr);
}
+base::Optional<uint32_t> AccessibleNode::rowSpan() const {
+ return GetProperty(element_, AOMUIntProperty::kRowSpan);
+}
+
+void AccessibleNode::setRowSpan(base::Optional<uint32_t> value) {
+ SetUIntProperty(AOMUIntProperty::kRowSpan, value);
+ NotifyAttributeChanged(html_names::kAriaRowspanAttr);
+}
+
uint32_t AccessibleNode::rowSpan(bool& is_null) const {
return GetProperty(element_, AOMUIntProperty::kRowSpan, is_null);
}
@@ -917,6 +1122,15 @@ void AccessibleNode::setRowSpan(uint32_t row_span, bool is_null) {
NotifyAttributeChanged(html_names::kAriaRowspanAttr);
}
+base::Optional<bool> AccessibleNode::selected() const {
+ return GetProperty(AOMBooleanProperty::kSelected);
+}
+
+void AccessibleNode::setSelected(base::Optional<bool> value) {
+ SetBooleanProperty(AOMBooleanProperty::kSelected, value);
+ NotifyAttributeChanged(html_names::kAriaSelectedAttr);
+}
+
bool AccessibleNode::selected(bool& is_null) const {
return GetProperty(AOMBooleanProperty::kSelected, is_null);
}
@@ -926,6 +1140,15 @@ void AccessibleNode::setSelected(bool selected, bool is_null) {
NotifyAttributeChanged(html_names::kAriaSelectedAttr);
}
+base::Optional<int32_t> AccessibleNode::setSize() const {
+ return GetProperty(element_, AOMIntProperty::kSetSize);
+}
+
+void AccessibleNode::setSetSize(base::Optional<int32_t> value) {
+ SetIntProperty(AOMIntProperty::kSetSize, value);
+ NotifyAttributeChanged(html_names::kAriaSetsizeAttr);
+}
+
int32_t AccessibleNode::setSize(bool& is_null) const {
return GetProperty(element_, AOMIntProperty::kSetSize, is_null);
}
@@ -944,6 +1167,15 @@ void AccessibleNode::setSort(const AtomicString& sort) {
NotifyAttributeChanged(html_names::kAriaSortAttr);
}
+base::Optional<float> AccessibleNode::valueMax() const {
+ return GetProperty(element_, AOMFloatProperty::kValueMax);
+}
+
+void AccessibleNode::setValueMax(base::Optional<float> value) {
+ SetFloatProperty(AOMFloatProperty::kValueMax, value);
+ NotifyAttributeChanged(html_names::kAriaValuemaxAttr);
+}
+
float AccessibleNode::valueMax(bool& is_null) const {
return GetProperty(element_, AOMFloatProperty::kValueMax, is_null);
}
@@ -953,6 +1185,15 @@ void AccessibleNode::setValueMax(float value_max, bool is_null) {
NotifyAttributeChanged(html_names::kAriaValuemaxAttr);
}
+base::Optional<float> AccessibleNode::valueMin() const {
+ return GetProperty(element_, AOMFloatProperty::kValueMin);
+}
+
+void AccessibleNode::setValueMin(base::Optional<float> value) {
+ SetFloatProperty(AOMFloatProperty::kValueMin, value);
+ NotifyAttributeChanged(html_names::kAriaValueminAttr);
+}
+
float AccessibleNode::valueMin(bool& is_null) const {
return GetProperty(element_, AOMFloatProperty::kValueMin, is_null);
}
@@ -962,6 +1203,15 @@ void AccessibleNode::setValueMin(float value_min, bool is_null) {
NotifyAttributeChanged(html_names::kAriaValueminAttr);
}
+base::Optional<float> AccessibleNode::valueNow() const {
+ return GetProperty(element_, AOMFloatProperty::kValueNow);
+}
+
+void AccessibleNode::setValueNow(base::Optional<float> value) {
+ SetFloatProperty(AOMFloatProperty::kValueNow, value);
+ NotifyAttributeChanged(html_names::kAriaValuenowAttr);
+}
+
float AccessibleNode::valueNow(bool& is_null) const {
return GetProperty(element_, AOMFloatProperty::kValueNow, is_null);
}
@@ -1122,6 +1372,45 @@ void AccessibleNode::SetRelationListProperty(AOMRelationListProperty property,
template <typename P, typename T>
static void SetProperty(P property,
+ base::Optional<T> value,
+ Vector<std::pair<P, T>>& properties) {
+ for (wtf_size_t i = 0; i < properties.size(); i++) {
+ auto& item = properties[i];
+ if (item.first == property) {
+ if (value.has_value())
+ item.second = value.value();
+ else
+ properties.EraseAt(i);
+ return;
+ }
+ }
+
+ if (value.has_value())
+ properties.push_back(std::make_pair(property, value.value()));
+}
+
+void AccessibleNode::SetBooleanProperty(AOMBooleanProperty property,
+ base::Optional<bool> value) {
+ SetProperty(property, value, boolean_properties_);
+}
+
+void AccessibleNode::SetIntProperty(AOMIntProperty property,
+ base::Optional<int32_t> value) {
+ SetProperty(property, value, int_properties_);
+}
+
+void AccessibleNode::SetUIntProperty(AOMUIntProperty property,
+ base::Optional<uint32_t> value) {
+ SetProperty(property, value, uint_properties_);
+}
+
+void AccessibleNode::SetFloatProperty(AOMFloatProperty property,
+ base::Optional<float> value) {
+ SetProperty(property, value, float_properties_);
+}
+
+template <typename P, typename T>
+static void SetProperty(P property,
T value,
bool is_null,
Vector<std::pair<P, T>>& properties) {
@@ -1189,7 +1478,7 @@ AXObjectCache* AccessibleNode::GetAXObjectCache() {
return GetDocument()->ExistingAXObjectCache();
}
-void AccessibleNode::Trace(blink::Visitor* visitor) {
+void AccessibleNode::Trace(Visitor* visitor) {
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 6ef76b77b8e..840b41f90b3 100644
--- a/chromium/third_party/blink/renderer/core/aom/accessible_node.h
+++ b/chromium/third_party/blink/renderer/core/aom/accessible_node.h
@@ -70,12 +70,12 @@ enum class AOMUIntProperty {
enum class AOMRelationProperty {
kActiveDescendant,
- kDetails,
kErrorMessage,
};
enum class AOMRelationListProperty {
kDescribedBy,
+ kDetails,
kControls,
kFlowTo,
kLabeledBy,
@@ -141,11 +141,17 @@ class CORE_EXPORT AccessibleNode : public EventTargetWithInlineData {
HeapVector<Member<Element>>&);
// Returns the given boolean property.
- bool GetProperty(AOMBooleanProperty, bool& is_null) const;
+ base::Optional<bool> GetProperty(AOMBooleanProperty) const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ bool GetProperty(AOMBooleanProperty, bool& is_null) const; // DEPRECATED
// Returns the value of the given property if the
// Element has an AccessibleNode. Sets |isNull| if the property and
// attribute are not present.
+ static base::Optional<int32_t> GetProperty(Element*, AOMIntProperty);
+ static base::Optional<uint32_t> GetProperty(Element*, AOMUIntProperty);
+ static base::Optional<float> GetProperty(Element*, AOMFloatProperty);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
static float GetProperty(Element*, AOMFloatProperty, bool& is_null);
static int32_t GetProperty(Element*, AOMIntProperty, bool& is_null);
static uint32_t GetProperty(Element*, AOMUIntProperty, bool& is_null);
@@ -201,26 +207,41 @@ class CORE_EXPORT AccessibleNode : public EventTargetWithInlineData {
AccessibleNode* activeDescendant() const;
void setActiveDescendant(AccessibleNode*);
- bool atomic(bool& is_null) const;
- void setAtomic(bool, bool is_null);
+ base::Optional<bool> atomic() const;
+ void setAtomic(base::Optional<bool>);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ bool atomic(bool& is_null) const; // DEPRECATED
+ void setAtomic(bool, bool is_null); // DEPRECATED
AtomicString autocomplete() const;
void setAutocomplete(const AtomicString&);
- bool busy(bool& is_null) const;
- void setBusy(bool, bool is_null);
+ base::Optional<bool> busy() const;
+ void setBusy(base::Optional<bool>);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ bool busy(bool& is_null) const; // DEPRECATED
+ void setBusy(bool, bool is_null); // DEPRECATED
AtomicString checked() const;
void setChecked(const AtomicString&);
- int32_t colCount(bool& is_null) const;
- void setColCount(int32_t, bool is_null);
+ base::Optional<int32_t> colCount() const;
+ void setColCount(base::Optional<int32_t>);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ int32_t colCount(bool& is_null) const; // DEPRECATED
+ void setColCount(int32_t, bool is_null); // DEPRECATED
- uint32_t colIndex(bool& is_null) const;
- void setColIndex(uint32_t, bool is_null);
+ base::Optional<uint32_t> colIndex() const;
+ void setColIndex(base::Optional<uint32_t>);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ uint32_t colIndex(bool& is_null) const; // DEPRECATED
+ void setColIndex(uint32_t, bool is_null); // DEPRECATED
- uint32_t colSpan(bool& is_null) const;
- void setColSpan(uint32_t, bool is_null);
+ base::Optional<uint32_t> colSpan() const;
+ void setColSpan(base::Optional<uint32_t>);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ uint32_t colSpan(bool& is_null) const; // DEPRECATED
+ void setColSpan(uint32_t, bool is_null); // DEPRECATED
AccessibleNodeList* controls() const;
void setControls(AccessibleNodeList*);
@@ -234,17 +255,23 @@ class CORE_EXPORT AccessibleNode : public EventTargetWithInlineData {
AtomicString description() const;
void setDescription(const AtomicString&);
- AccessibleNode* details() const;
- void setDetails(AccessibleNode*);
+ AccessibleNodeList* details() const;
+ void setDetails(AccessibleNodeList*);
- bool disabled(bool& is_null) const;
- void setDisabled(bool, bool is_null);
+ base::Optional<bool> disabled() const;
+ void setDisabled(base::Optional<bool>);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ bool disabled(bool& is_null) const; // DEPRECATED
+ void setDisabled(bool, bool is_null); // DEPRECATED
AccessibleNode* errorMessage() const;
void setErrorMessage(AccessibleNode*);
- bool expanded(bool& is_null) const;
- void setExpanded(bool, bool is_null);
+ base::Optional<bool> expanded() const;
+ void setExpanded(base::Optional<bool>);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ bool expanded(bool& is_null) const; // DEPRECATED
+ void setExpanded(bool, bool is_null); // DEPRECATED
AccessibleNodeList* flowTo() const;
void setFlowTo(AccessibleNodeList*);
@@ -252,8 +279,11 @@ class CORE_EXPORT AccessibleNode : public EventTargetWithInlineData {
AtomicString hasPopUp() const;
void setHasPopUp(const AtomicString&);
- bool hidden(bool& is_null) const;
- void setHidden(bool, bool is_null);
+ base::Optional<bool> hidden() const;
+ void setHidden(base::Optional<bool>);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ bool hidden(bool& is_null) const; // DEPRECATED
+ void setHidden(bool, bool is_null); // DEPRECATED
AtomicString invalid() const;
void setInvalid(const AtomicString&);
@@ -267,20 +297,32 @@ class CORE_EXPORT AccessibleNode : public EventTargetWithInlineData {
AccessibleNodeList* labeledBy();
void setLabeledBy(AccessibleNodeList*);
- uint32_t level(bool& is_null) const;
- void setLevel(uint32_t, bool is_null);
+ base::Optional<uint32_t> level() const;
+ void setLevel(base::Optional<uint32_t>);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ uint32_t level(bool& is_null) const; // DEPRECATED
+ void setLevel(uint32_t, bool is_null); // DEPRECATED
AtomicString live() const;
void setLive(const AtomicString&);
- bool modal(bool& is_null) const;
- void setModal(bool, bool is_null);
+ base::Optional<bool> modal() const;
+ void setModal(base::Optional<bool>);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ bool modal(bool& is_null) const; // DEPRECATED
+ void setModal(bool, bool is_null); // DEPRECATED
- bool multiline(bool& is_null) const;
- void setMultiline(bool, bool is_null);
+ base::Optional<bool> multiline() const;
+ void setMultiline(base::Optional<bool>);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ bool multiline(bool& is_null) const; // DEPRECATED
+ void setMultiline(bool, bool is_null); // DEPRECATED
- bool multiselectable(bool& is_null) const;
- void setMultiselectable(bool, bool is_null);
+ base::Optional<bool> multiselectable() const;
+ void setMultiselectable(base::Optional<bool>);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ bool multiselectable(bool& is_null) const; // DEPRECATED
+ void setMultiselectable(bool, bool is_null); // DEPRECATED
AtomicString orientation() const;
void setOrientation(const AtomicString&);
@@ -291,20 +333,29 @@ class CORE_EXPORT AccessibleNode : public EventTargetWithInlineData {
AtomicString placeholder() const;
void setPlaceholder(const AtomicString&);
- uint32_t posInSet(bool& is_null) const;
- void setPosInSet(uint32_t, bool is_null);
+ base::Optional<uint32_t> posInSet() const;
+ void setPosInSet(base::Optional<uint32_t>);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ uint32_t posInSet(bool& is_null) const; // DEPRECATED
+ void setPosInSet(uint32_t, bool is_null); // DEPRECATED
AtomicString pressed() const;
void setPressed(const AtomicString&);
- bool readOnly(bool& is_null) const;
- void setReadOnly(bool, bool is_null);
+ base::Optional<bool> readOnly() const;
+ void setReadOnly(base::Optional<bool>);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ bool readOnly(bool& is_null) const; // DEPRECATED
+ void setReadOnly(bool, bool is_null); // DEPRECATED
AtomicString relevant() const;
void setRelevant(const AtomicString&);
- bool required(bool& is_null) const;
- void setRequired(bool, bool is_null);
+ base::Optional<bool> required() const;
+ void setRequired(base::Optional<bool>);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ bool required(bool& is_null) const; // DEPRECATED
+ void setRequired(bool, bool is_null); // DEPRECATED
AtomicString role() const;
void setRole(const AtomicString&);
@@ -312,32 +363,56 @@ class CORE_EXPORT AccessibleNode : public EventTargetWithInlineData {
AtomicString roleDescription() const;
void setRoleDescription(const AtomicString&);
- int32_t rowCount(bool& is_null) const;
- void setRowCount(int32_t, bool is_null);
-
- uint32_t rowIndex(bool& is_null) const;
- void setRowIndex(uint32_t, bool is_null);
-
- uint32_t rowSpan(bool& is_null) const;
- void setRowSpan(uint32_t, bool is_null);
-
- bool selected(bool& is_null) const;
- void setSelected(bool, bool is_null);
-
- int32_t setSize(bool& is_null) const;
- void setSetSize(int32_t, bool is_null);
+ base::Optional<int32_t> rowCount() const;
+ void setRowCount(base::Optional<int32_t>);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ int32_t rowCount(bool& is_null) const; // DEPRECATED
+ void setRowCount(int32_t, bool is_null); // DEPRECATED
+
+ base::Optional<uint32_t> rowIndex() const;
+ void setRowIndex(base::Optional<uint32_t>);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ uint32_t rowIndex(bool& is_null) const; // DEPRECATED
+ void setRowIndex(uint32_t, bool is_null); // DEPRECATED
+
+ base::Optional<uint32_t> rowSpan() const;
+ void setRowSpan(base::Optional<uint32_t>);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ uint32_t rowSpan(bool& is_null) const; // DEPRECATED
+ void setRowSpan(uint32_t, bool is_null); // DEPRECATED
+
+ base::Optional<bool> selected() const;
+ void setSelected(base::Optional<bool>);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ bool selected(bool& is_null) const; // DEPRECATED
+ void setSelected(bool, bool is_null); // DEPRECATED
+
+ base::Optional<int32_t> setSize() const;
+ void setSetSize(base::Optional<int32_t>);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ int32_t setSize(bool& is_null) const; // DEPRECATED
+ void setSetSize(int32_t, bool is_null); // DEPRECATED
AtomicString sort() const;
void setSort(const AtomicString&);
- float valueMax(bool& is_null) const;
- void setValueMax(float, bool is_null);
+ base::Optional<float> valueMax() const;
+ void setValueMax(base::Optional<float>);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ float valueMax(bool& is_null) const; // DEPRECATED
+ void setValueMax(float, bool is_null); // DEPRECATED
- float valueMin(bool& is_null) const;
- void setValueMin(float, bool is_null);
+ base::Optional<float> valueMin() const;
+ void setValueMin(base::Optional<float>);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ float valueMin(bool& is_null) const; // DEPRECATED
+ void setValueMin(float, bool is_null); // DEPRECATED
- float valueNow(bool& is_null) const;
- void setValueNow(float, bool is_null);
+ base::Optional<float> valueNow() const;
+ void setValueNow(base::Optional<float>);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ float valueNow(bool& is_null) const; // DEPRECATED
+ void setValueNow(float, bool is_null); // DEPRECATED
AtomicString valueText() const;
void setValueText(const AtomicString&);
@@ -359,7 +434,7 @@ class CORE_EXPORT AccessibleNode : public EventTargetWithInlineData {
DEFINE_ATTRIBUTE_EVENT_LISTENER(accessiblescrollintoview,
kAccessiblescrollintoview)
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
friend class AccessibleNodeList;
@@ -374,10 +449,23 @@ class CORE_EXPORT AccessibleNode : public EventTargetWithInlineData {
void SetStringProperty(AOMStringProperty, const AtomicString&);
void SetRelationProperty(AOMRelationProperty, AccessibleNode*);
void SetRelationListProperty(AOMRelationListProperty, AccessibleNodeList*);
- void SetBooleanProperty(AOMBooleanProperty, bool value, bool is_null);
- void SetFloatProperty(AOMFloatProperty, float value, bool is_null);
- void SetUIntProperty(AOMUIntProperty, uint32_t value, bool is_null);
- void SetIntProperty(AOMIntProperty, int32_t value, bool is_null);
+ void SetBooleanProperty(AOMBooleanProperty, base::Optional<bool> value);
+ void SetIntProperty(AOMIntProperty, base::Optional<int32_t> value);
+ void SetUIntProperty(AOMUIntProperty, base::Optional<uint32_t> value);
+ void SetFloatProperty(AOMFloatProperty, base::Optional<float> value);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ void SetBooleanProperty(AOMBooleanProperty,
+ bool value,
+ bool is_null); // DEPRECATED
+ void SetFloatProperty(AOMFloatProperty,
+ float value,
+ bool is_null); // DEPRECATED
+ void SetUIntProperty(AOMUIntProperty,
+ uint32_t value,
+ bool is_null); // DEPRECATED
+ void SetIntProperty(AOMIntProperty,
+ int32_t value,
+ bool is_null); // DEPRECATED
void NotifyAttributeChanged(const blink::QualifiedName&);
AXObjectCache* GetAXObjectCache();
diff --git a/chromium/third_party/blink/renderer/core/aom/accessible_node.idl b/chromium/third_party/blink/renderer/core/aom/accessible_node.idl
index e74c43d78c3..b8e78529c4b 100644
--- a/chromium/third_party/blink/renderer/core/aom/accessible_node.idl
+++ b/chromium/third_party/blink/renderer/core/aom/accessible_node.idl
@@ -6,10 +6,9 @@
// Explainer: https://github.com/WICG/aom/blob/master/explainer.md
// Spec: https://wicg.github.io/aom/spec/
[
- Constructor,
- ConstructorCallWith=Document,
RuntimeEnabled=AccessibilityObjectModel
] interface AccessibleNode : EventTarget {
+ [CallWith=Document] constructor();
attribute AccessibleNode? activeDescendant;
attribute boolean? atomic;
attribute DOMString? autocomplete;
@@ -21,7 +20,7 @@
attribute AccessibleNodeList? controls;
attribute DOMString? current;
attribute AccessibleNodeList? describedBy;
- attribute AccessibleNode? details;
+ attribute AccessibleNodeList? details;
attribute boolean? disabled;
attribute AccessibleNode? errorMessage;
attribute boolean? expanded;
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 602afc4e62d..de6ea7a0d26 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
@@ -71,15 +71,16 @@ void AccessibleNodeList::remove(int index) {
nodes_.EraseAt(index);
}
-bool AccessibleNodeList::AnonymousIndexedSetter(unsigned index,
- AccessibleNode* node,
- ExceptionState& state) {
+IndexedPropertySetterResult AccessibleNodeList::AnonymousIndexedSetter(
+ unsigned index,
+ AccessibleNode* node,
+ ExceptionState& state) {
if (!node) {
remove(index);
- return true;
+ return IndexedPropertySetterResult::kIntercepted;
}
if (index >= kMaxItems)
- return false;
+ return IndexedPropertySetterResult::kDidNotIntercept;
if (index >= nodes_.size()) {
wtf_size_t old_size = nodes_.size();
nodes_.resize(index + 1);
@@ -87,7 +88,7 @@ bool AccessibleNodeList::AnonymousIndexedSetter(unsigned index,
nodes_[i] = nullptr;
}
nodes_[index] = node;
- return true;
+ return IndexedPropertySetterResult::kIntercepted;
}
unsigned AccessibleNodeList::length() const {
@@ -105,7 +106,7 @@ void AccessibleNodeList::NotifyChanged() {
owner.second->OnRelationListChanged(owner.first);
}
-void AccessibleNodeList::Trace(blink::Visitor* visitor) {
+void AccessibleNodeList::Trace(Visitor* visitor) {
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 af44c5d68c2..e6b5bd1be45 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
@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
namespace blink {
@@ -32,11 +33,13 @@ class CORE_EXPORT AccessibleNodeList : public ScriptWrappable {
AccessibleNode* item(unsigned offset) const;
void add(AccessibleNode*, AccessibleNode* = nullptr);
void remove(int index);
- bool AnonymousIndexedSetter(unsigned, AccessibleNode*, ExceptionState&);
+ IndexedPropertySetterResult AnonymousIndexedSetter(unsigned,
+ AccessibleNode*,
+ ExceptionState&);
unsigned length() const;
void setLength(unsigned);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void NotifyChanged();
diff --git a/chromium/third_party/blink/renderer/core/aom/accessible_node_list.idl b/chromium/third_party/blink/renderer/core/aom/accessible_node_list.idl
index ec9a2b107ae..68573677e95 100644
--- a/chromium/third_party/blink/renderer/core/aom/accessible_node_list.idl
+++ b/chromium/third_party/blink/renderer/core/aom/accessible_node_list.idl
@@ -6,9 +6,9 @@
// Explainer: https://github.com/WICG/aom/blob/master/explainer.md
// Spec: https://wicg.github.io/aom/spec/
[
- Constructor(optional sequence<AccessibleNode> nodes = []),
RuntimeEnabled=AccessibilityObjectModel
] interface AccessibleNodeList {
+ constructor(optional sequence<AccessibleNode> nodes = []);
attribute unsigned long length;
getter AccessibleNode? item(unsigned long index);
[RaisesException] setter void (unsigned long index, AccessibleNode node);
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 53893963b84..e6ea86dd66e 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(resolver_);
FrameRequestCallbackCollection::FrameCallback::Trace(visitor);
}
@@ -56,7 +56,7 @@ ScriptPromise ComputedAccessibleNodePromiseResolver::Promise() {
return resolver_->Promise();
}
-void ComputedAccessibleNodePromiseResolver::Trace(blink::Visitor* visitor) {
+void ComputedAccessibleNodePromiseResolver::Trace(Visitor* visitor) {
visitor->Trace(element_);
visitor->Trace(resolver_);
}
@@ -94,7 +94,8 @@ void ComputedAccessibleNodePromiseResolver::UpdateTreeAndResolve() {
}
Document& document = element_->GetDocument();
- document.View()->UpdateLifecycleToCompositingCleanPlusScrolling();
+ document.View()->UpdateLifecycleToCompositingCleanPlusScrolling(
+ DocumentUpdateReason::kAccessibility);
AXObjectCache& cache = ax_context_->GetAXObjectCache();
AXID ax_id = cache.GetAXID(element_);
@@ -113,7 +114,93 @@ ComputedAccessibleNode::ComputedAccessibleNode(AXID ax_id,
document_(document),
ax_context_(std::make_unique<AXContext>(*document)) {}
-ComputedAccessibleNode::~ComputedAccessibleNode() {}
+base::Optional<bool> ComputedAccessibleNode::atomic() const {
+ return GetBoolAttribute(WebAOMBoolAttribute::AOM_ATTR_ATOMIC);
+}
+
+base::Optional<bool> ComputedAccessibleNode::busy() const {
+ return GetBoolAttribute(WebAOMBoolAttribute::AOM_ATTR_BUSY);
+}
+
+base::Optional<bool> ComputedAccessibleNode::disabled() const {
+ return GetBoolAttribute(WebAOMBoolAttribute::AOM_ATTR_DISABLED);
+}
+
+base::Optional<bool> ComputedAccessibleNode::readOnly() const {
+ return GetBoolAttribute(WebAOMBoolAttribute::AOM_ATTR_READONLY);
+}
+
+base::Optional<bool> ComputedAccessibleNode::expanded() const {
+ return GetBoolAttribute(WebAOMBoolAttribute::AOM_ATTR_EXPANDED);
+}
+
+base::Optional<bool> ComputedAccessibleNode::modal() const {
+ return GetBoolAttribute(WebAOMBoolAttribute::AOM_ATTR_MODAL);
+}
+
+base::Optional<bool> ComputedAccessibleNode::multiline() const {
+ return GetBoolAttribute(WebAOMBoolAttribute::AOM_ATTR_MULTILINE);
+}
+
+base::Optional<bool> ComputedAccessibleNode::multiselectable() const {
+ return GetBoolAttribute(WebAOMBoolAttribute::AOM_ATTR_MULTISELECTABLE);
+}
+
+base::Optional<bool> ComputedAccessibleNode::required() const {
+ return GetBoolAttribute(WebAOMBoolAttribute::AOM_ATTR_REQUIRED);
+}
+
+base::Optional<bool> ComputedAccessibleNode::selected() const {
+ return GetBoolAttribute(WebAOMBoolAttribute::AOM_ATTR_SELECTED);
+}
+
+base::Optional<int32_t> ComputedAccessibleNode::colCount() const {
+ return GetIntAttribute(WebAOMIntAttribute::AOM_ATTR_COLUMN_COUNT);
+}
+
+base::Optional<int32_t> ComputedAccessibleNode::colIndex() const {
+ return GetIntAttribute(WebAOMIntAttribute::AOM_ATTR_COLUMN_INDEX);
+}
+
+base::Optional<int32_t> ComputedAccessibleNode::colSpan() const {
+ return GetIntAttribute(WebAOMIntAttribute::AOM_ATTR_COLUMN_SPAN);
+}
+
+base::Optional<int32_t> ComputedAccessibleNode::level() const {
+ return GetIntAttribute(WebAOMIntAttribute::AOM_ATTR_HIERARCHICAL_LEVEL);
+}
+
+base::Optional<int32_t> ComputedAccessibleNode::posInSet() const {
+ return GetIntAttribute(WebAOMIntAttribute::AOM_ATTR_POS_IN_SET);
+}
+
+base::Optional<int32_t> ComputedAccessibleNode::rowCount() const {
+ return GetIntAttribute(WebAOMIntAttribute::AOM_ATTR_ROW_COUNT);
+}
+
+base::Optional<int32_t> ComputedAccessibleNode::rowIndex() const {
+ return GetIntAttribute(WebAOMIntAttribute::AOM_ATTR_ROW_INDEX);
+}
+
+base::Optional<int32_t> ComputedAccessibleNode::rowSpan() const {
+ return GetIntAttribute(WebAOMIntAttribute::AOM_ATTR_ROW_SPAN);
+}
+
+base::Optional<int32_t> ComputedAccessibleNode::setSize() const {
+ return GetIntAttribute(WebAOMIntAttribute::AOM_ATTR_SET_SIZE);
+}
+
+base::Optional<float> ComputedAccessibleNode::valueMax() const {
+ return GetFloatAttribute(WebAOMFloatAttribute::AOM_ATTR_VALUE_MAX);
+}
+
+base::Optional<float> ComputedAccessibleNode::valueMin() const {
+ return GetFloatAttribute(WebAOMFloatAttribute::AOM_ATTR_VALUE_MIN);
+}
+
+base::Optional<float> ComputedAccessibleNode::valueNow() const {
+ return GetFloatAttribute(WebAOMFloatAttribute::AOM_ATTR_VALUE_NOW);
+}
bool ComputedAccessibleNode::atomic(bool& is_null) const {
return GetBoolAttribute(WebAOMBoolAttribute::AOM_ATTR_ATOMIC, is_null);
@@ -298,6 +385,30 @@ ComputedAccessibleNode* ComputedAccessibleNode::nextSibling() const {
return document_->GetOrCreateComputedAccessibleNode(sibling_ax_id, tree_);
}
+base::Optional<bool> ComputedAccessibleNode::GetBoolAttribute(
+ WebAOMBoolAttribute attr) const {
+ bool value;
+ if (tree_->GetBoolAttributeForAXNode(ax_id_, attr, &value))
+ return value;
+ return base::nullopt;
+}
+
+base::Optional<int32_t> ComputedAccessibleNode::GetIntAttribute(
+ WebAOMIntAttribute attr) const {
+ int32_t value;
+ if (tree_->GetIntAttributeForAXNode(ax_id_, attr, &value))
+ return value;
+ return base::nullopt;
+}
+
+base::Optional<float> ComputedAccessibleNode::GetFloatAttribute(
+ WebAOMFloatAttribute attr) const {
+ float value;
+ if (tree_->GetFloatAttributeForAXNode(ax_id_, attr, &value))
+ return value;
+ return base::nullopt;
+}
+
bool ComputedAccessibleNode::GetBoolAttribute(WebAOMBoolAttribute attr,
bool& is_null) const {
bool out;
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 ef81643b71e..027d68e72ff 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(blink::Visitor*);
+ void Trace(Visitor*);
private:
void UpdateTreeAndResolve();
@@ -48,35 +48,61 @@ class ComputedAccessibleNode : public ScriptWrappable {
public:
ComputedAccessibleNode(AXID, WebComputedAXTree*, Document*);
- ~ComputedAccessibleNode() override;
+ ~ComputedAccessibleNode() override = default;
void Trace(Visitor*) override;
// TODO(meredithl): add accessors for state properties.
- bool atomic(bool& is_null) const;
- bool busy(bool& is_null) const;
- bool disabled(bool& is_null) const;
- bool readOnly(bool& is_null) const;
- bool expanded(bool& is_null) const;
- bool modal(bool& is_null) const;
- bool multiline(bool& is_null) const;
- bool multiselectable(bool& is_null) const;
- bool required(bool& is_null) const;
- bool selected(bool& is_null) const;
-
- int32_t colCount(bool& is_null) const;
- int32_t colIndex(bool& is_null) const;
- int32_t colSpan(bool& is_null) const;
- int32_t level(bool& is_null) const;
- int32_t posInSet(bool& is_null) const;
- int32_t rowCount(bool& is_null) const;
- int32_t rowIndex(bool& is_null) const;
- int32_t rowSpan(bool& is_null) const;
- int32_t setSize(bool& is_null) const;
-
- float valueMax(bool& is_null) const;
- float valueMin(bool& is_null) const;
- float valueNow(bool& is_null) const;
+ base::Optional<bool> atomic() const;
+ base::Optional<bool> busy() const;
+ base::Optional<bool> disabled() const;
+ base::Optional<bool> readOnly() const;
+ base::Optional<bool> expanded() const;
+ base::Optional<bool> modal() const;
+ base::Optional<bool> multiline() const;
+ base::Optional<bool> multiselectable() const;
+ base::Optional<bool> required() const;
+ base::Optional<bool> selected() const;
+
+ base::Optional<int32_t> colCount() const;
+ base::Optional<int32_t> colIndex() const;
+ base::Optional<int32_t> colSpan() const;
+ base::Optional<int32_t> level() const;
+ base::Optional<int32_t> posInSet() const;
+ base::Optional<int32_t> rowCount() const;
+ base::Optional<int32_t> rowIndex() const;
+ base::Optional<int32_t> rowSpan() const;
+ base::Optional<int32_t> setSize() const;
+
+ base::Optional<float> valueMax() const;
+ base::Optional<float> valueMin() const;
+ base::Optional<float> valueNow() const;
+
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ bool atomic(bool& is_null) const; // DEPRECATED
+ bool busy(bool& is_null) const; // DEPRECATED
+ bool disabled(bool& is_null) const; // DEPRECATED
+ bool readOnly(bool& is_null) const; // DEPRECATED
+ bool expanded(bool& is_null) const; // DEPRECATED
+ bool modal(bool& is_null) const; // DEPRECATED
+ bool multiline(bool& is_null) const; // DEPRECATED
+ bool multiselectable(bool& is_null) const; // DEPRECATED
+ bool required(bool& is_null) const; // DEPRECATED
+ bool selected(bool& is_null) const; // DEPRECATED
+
+ int32_t colCount(bool& is_null) const; // DEPRECATED
+ int32_t colIndex(bool& is_null) const; // DEPRECATED
+ int32_t colSpan(bool& is_null) const; // DEPRECATED
+ int32_t level(bool& is_null) const; // DEPRECATED
+ int32_t posInSet(bool& is_null) const; // DEPRECATED
+ int32_t rowCount(bool& is_null) const; // DEPRECATED
+ int32_t rowIndex(bool& is_null) const; // DEPRECATED
+ int32_t rowSpan(bool& is_null) const; // DEPRECATED
+ int32_t setSize(bool& is_null) const; // DEPRECATED
+
+ float valueMax(bool& is_null) const; // DEPRECATED
+ float valueMin(bool& is_null) const; // DEPRECATED
+ float valueNow(bool& is_null) const; // DEPRECATED
const String autocomplete() const;
const String checked() const;
@@ -96,6 +122,10 @@ class ComputedAccessibleNode : public ScriptWrappable {
ScriptPromise ensureUpToDate(ScriptState*);
private:
+ base::Optional<bool> GetBoolAttribute(WebAOMBoolAttribute) const;
+ base::Optional<int32_t> GetIntAttribute(WebAOMIntAttribute) const;
+ base::Optional<float> GetFloatAttribute(WebAOMFloatAttribute) const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
bool GetBoolAttribute(WebAOMBoolAttribute, bool& is_null) const;
int32_t GetIntAttribute(WebAOMIntAttribute, bool& is_null) const;
float GetFloatAttribute(WebAOMFloatAttribute, bool& is_null) const;
diff --git a/chromium/third_party/blink/renderer/core/clipboard/BUILD.gn b/chromium/third_party/blink/renderer/core/clipboard/BUILD.gn
index ac9cff9c19a..42ebb6d6fc5 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/clipboard/BUILD.gn
@@ -24,6 +24,8 @@ blink_core_sources("clipboard") {
"dragged_isolated_file_system.cc",
"dragged_isolated_file_system.h",
"paste_mode.h",
+ "raw_system_clipboard.cc",
+ "raw_system_clipboard.h",
"system_clipboard.cc",
"system_clipboard.h",
]
diff --git a/chromium/third_party/blink/renderer/core/clipboard/clipboard_utilities.cc b/chromium/third_party/blink/renderer/core/clipboard/clipboard_utilities.cc
index b7628cf5dcd..45e0b1b4327 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/clipboard_utilities.cc
+++ b/chromium/third_party/blink/renderer/core/clipboard/clipboard_utilities.cc
@@ -31,10 +31,13 @@
#include "third_party/blink/renderer/core/clipboard/clipboard_utilities.h"
#include "net/base/escape.h"
+#include "third_party/blink/renderer/platform/image-encoders/image_encoder.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.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"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/skia/include/encode/SkPngEncoder.h"
namespace blink {
@@ -90,4 +93,28 @@ String URLToImageMarkup(const KURL& url, const String& title) {
return builder.ToString();
}
+String BitmapToImageMarkup(const SkBitmap& bitmap) {
+ if (bitmap.isNull())
+ return String();
+
+ // Encode bitmap to Vector<uint8_t> on the main thread.
+ SkPixmap pixmap;
+ bitmap.peekPixels(&pixmap);
+
+ // Set encoding options to favor speed over size.
+ SkPngEncoder::Options options;
+ options.fZLibLevel = 1;
+ options.fFilterFlags = SkPngEncoder::FilterFlag::kNone;
+
+ Vector<uint8_t> png_data;
+ if (!ImageEncoder::Encode(&png_data, pixmap, options))
+ return String();
+
+ StringBuilder markup;
+ markup.Append("<img src=\"data:image/png;base64,");
+ markup.Append(Base64Encode(png_data));
+ markup.Append("\" alt=\"\"/>");
+ return markup.ToString();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/clipboard/clipboard_utilities.h b/chromium/third_party/blink/renderer/core/clipboard/clipboard_utilities.h
index 623c77322ac..25709b7664c 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/clipboard_utilities.h
+++ b/chromium/third_party/blink/renderer/core/clipboard/clipboard_utilities.h
@@ -35,6 +35,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
+#include "third_party/skia/include/core/SkBitmap.h"
namespace blink {
@@ -44,6 +45,7 @@ CORE_EXPORT void ReplaceNewlinesWithWindowsStyleNewlines(String&);
CORE_EXPORT void ReplaceNBSPWithSpace(String&);
CORE_EXPORT String ConvertURIListToURL(const String& uri_list);
CORE_EXPORT String URLToImageMarkup(const KURL&, const String& title);
+CORE_EXPORT String BitmapToImageMarkup(const SkBitmap& bitmap);
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/clipboard/clipboard_utilities_test.cc b/chromium/third_party/blink/renderer/core/clipboard/clipboard_utilities_test.cc
index a0338751287..4aabc435c74 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/clipboard_utilities_test.cc
+++ b/chromium/third_party/blink/renderer/core/clipboard/clipboard_utilities_test.cc
@@ -43,4 +43,17 @@ TEST(ClipboardUtilitiesTest, URLToImageMarkupEmbeddedNull) {
String(kTitleWithNull, sizeof(kTitleWithNull) - 1)));
}
+TEST(ClipboardUtilitiesTest, BitmapToImageMarkupEmpty) {
+ SkBitmap bitmap;
+ EXPECT_TRUE(BitmapToImageMarkup(bitmap).IsNull());
+}
+
+TEST(ClipboardUtilitiesTest, BitmapToImageMarkup) {
+ SkBitmap bitmap;
+ bitmap.allocPixels(SkImageInfo::MakeN32Premul(10, 5));
+ EXPECT_EQ(
+ R"HTML(<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAFCAYAAAB8ZH1oAAAADElEQVQYGWNgGEYAAADNAAGVVebMAAAAAElFTkSuQmCC" alt=""/>)HTML",
+ BitmapToImageMarkup(bitmap));
+}
+
} // namespace blink
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 ecdb6e3c740..c285880a76f 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/data_object.cc
+++ b/chromium/third_party/blink/renderer/core/clipboard/data_object.cc
@@ -42,18 +42,19 @@
namespace blink {
-DataObject* DataObject::CreateFromClipboard(PasteMode paste_mode) {
+// static
+DataObject* DataObject::CreateFromClipboard(SystemClipboard* system_clipboard,
+ PasteMode paste_mode) {
DataObject* data_object = Create();
#if DCHECK_IS_ON()
HashSet<String> types_seen;
#endif
- uint64_t sequence_number = SystemClipboard::GetInstance().SequenceNumber();
- for (const String& type :
- SystemClipboard::GetInstance().ReadAvailableTypes()) {
+ uint64_t sequence_number = system_clipboard->SequenceNumber();
+ for (const String& type : system_clipboard->ReadAvailableTypes()) {
if (paste_mode == PasteMode::kPlainTextOnly && type != kMimeTypeTextPlain)
continue;
- data_object->item_list_.push_back(
- DataObjectItem::CreateFromClipboard(type, sequence_number));
+ data_object->item_list_.push_back(DataObjectItem::CreateFromClipboard(
+ system_clipboard, type, sequence_number));
#if DCHECK_IS_ON()
DCHECK(types_seen.insert(type).is_new_entry);
#endif
@@ -61,12 +62,14 @@ DataObject* DataObject::CreateFromClipboard(PasteMode paste_mode) {
return data_object;
}
+// static
DataObject* DataObject::CreateFromString(const String& data) {
DataObject* data_object = Create();
data_object->Add(data, kMimeTypeTextPlain);
return data_object;
}
+// static
DataObject* DataObject::Create() {
return MakeGarbageCollected<DataObject>();
}
@@ -276,12 +279,13 @@ void DataObject::NotifyItemListChanged() const {
observer->OnItemListChanged();
}
-void DataObject::Trace(blink::Visitor* visitor) {
+void DataObject::Trace(Visitor* visitor) {
visitor->Trace(item_list_);
visitor->Trace(observers_);
Supplementable<DataObject>::Trace(visitor);
}
+// static
DataObject* DataObject::Create(WebDragData data) {
DataObject* data_object = Create();
bool has_file_system = false;
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 3e666e2eee1..aabc378fefa 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/data_object.h
+++ b/chromium/third_party/blink/renderer/core/clipboard/data_object.h
@@ -43,6 +43,7 @@
namespace blink {
class KURL;
+class SystemClipboard;
class WebDragData;
enum class PasteMode;
@@ -62,7 +63,7 @@ class CORE_EXPORT DataObject : public GarbageCollected<DataObject>,
virtual void OnItemListChanged() = 0;
};
- static DataObject* CreateFromClipboard(PasteMode);
+ static DataObject* CreateFromClipboard(SystemClipboard*, PasteMode);
static DataObject* CreateFromString(const String&);
static DataObject* Create();
static DataObject* Create(WebDragData);
@@ -123,7 +124,7 @@ class CORE_EXPORT DataObject : public GarbageCollected<DataObject>,
// whenever the underlying item_list_ changes.
void AddObserver(Observer*);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 5016284659b..8445a955220 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
@@ -41,6 +41,7 @@
namespace blink {
+// static
DataObjectItem* DataObjectItem::CreateFromString(const String& type,
const String& data) {
DataObjectItem* item =
@@ -49,6 +50,7 @@ DataObjectItem* DataObjectItem::CreateFromString(const String& type,
return item;
}
+// static
DataObjectItem* DataObjectItem::CreateFromFile(File* file) {
DataObjectItem* item =
MakeGarbageCollected<DataObjectItem>(kFileKind, file->type());
@@ -56,6 +58,7 @@ DataObjectItem* DataObjectItem::CreateFromFile(File* file) {
return item;
}
+// static
DataObjectItem* DataObjectItem::CreateFromFileWithFileSystemId(
File* file,
const String& file_system_id) {
@@ -66,6 +69,7 @@ DataObjectItem* DataObjectItem::CreateFromFileWithFileSystemId(
return item;
}
+// static
DataObjectItem* DataObjectItem::CreateFromURL(const String& url,
const String& title) {
DataObjectItem* item =
@@ -75,6 +79,7 @@ DataObjectItem* DataObjectItem::CreateFromURL(const String& url,
return item;
}
+// static
DataObjectItem* DataObjectItem::CreateFromHTML(const String& html,
const KURL& base_url) {
DataObjectItem* item =
@@ -84,6 +89,7 @@ DataObjectItem* DataObjectItem::CreateFromHTML(const String& html,
return item;
}
+// static
DataObjectItem* DataObjectItem::CreateFromSharedBuffer(
scoped_refptr<SharedBuffer> buffer,
const KURL& source_url,
@@ -100,26 +106,37 @@ DataObjectItem* DataObjectItem::CreateFromSharedBuffer(
return item;
}
-DataObjectItem* DataObjectItem::CreateFromClipboard(const String& type,
- uint64_t sequence_number) {
+// static
+DataObjectItem* DataObjectItem::CreateFromClipboard(
+ SystemClipboard* system_clipboard,
+ const String& type,
+ uint64_t sequence_number) {
if (type == kMimeTypeImagePng) {
- return MakeGarbageCollected<DataObjectItem>(kFileKind, type,
- sequence_number);
+ return MakeGarbageCollected<DataObjectItem>(
+ kFileKind, type, sequence_number, system_clipboard);
}
- return MakeGarbageCollected<DataObjectItem>(kStringKind, type,
- sequence_number);
+ return MakeGarbageCollected<DataObjectItem>(
+ kStringKind, type, sequence_number, system_clipboard);
}
DataObjectItem::DataObjectItem(ItemKind kind, const String& type)
- : source_(kInternalSource), kind_(kind), type_(type), sequence_number_(0) {}
+ : source_(kInternalSource),
+ kind_(kind),
+ type_(type),
+ sequence_number_(0),
+ system_clipboard_(nullptr) {}
DataObjectItem::DataObjectItem(ItemKind kind,
const String& type,
- uint64_t sequence_number)
+ uint64_t sequence_number,
+ SystemClipboard* system_clipboard)
: source_(kClipboardSource),
kind_(kind),
type_(type),
- sequence_number_(sequence_number) {}
+ sequence_number_(sequence_number),
+ system_clipboard_(system_clipboard) {
+ DCHECK(system_clipboard_);
+}
File* DataObjectItem::GetAsFile() const {
if (Kind() != kFileKind)
@@ -137,8 +154,8 @@ File* DataObjectItem::GetAsFile() const {
DCHECK_EQ(source_, kClipboardSource);
if (GetType() == kMimeTypeImagePng) {
- SkBitmap bitmap = SystemClipboard::GetInstance().ReadImage(
- mojom::ClipboardBuffer::kStandard);
+ SkBitmap bitmap =
+ system_clipboard_->ReadImage(mojom::ClipboardBuffer::kStandard);
SkPixmap pixmap;
bitmap.peekPixels(&pixmap);
@@ -175,21 +192,19 @@ String DataObjectItem::GetAsString() const {
String data;
// This is ugly but there's no real alternative.
if (type_ == kMimeTypeTextPlain) {
- data = SystemClipboard::GetInstance().ReadPlainText();
+ data = system_clipboard_->ReadPlainText();
} else if (type_ == kMimeTypeTextRTF) {
- data = SystemClipboard::GetInstance().ReadRTF();
+ data = system_clipboard_->ReadRTF();
} else if (type_ == kMimeTypeTextHTML) {
KURL ignored_source_url;
unsigned ignored;
- data = SystemClipboard::GetInstance().ReadHTML(ignored_source_url, ignored,
- ignored);
+ data = system_clipboard_->ReadHTML(ignored_source_url, ignored, ignored);
} else {
- data = SystemClipboard::GetInstance().ReadCustomData(type_);
+ data = system_clipboard_->ReadCustomData(type_);
}
- return SystemClipboard::GetInstance().SequenceNumber() == sequence_number_
- ? data
- : String();
+ return system_clipboard_->SequenceNumber() == sequence_number_ ? data
+ : String();
}
bool DataObjectItem::IsFilename() const {
@@ -207,8 +222,9 @@ String DataObjectItem::FileSystemId() const {
return file_system_id_;
}
-void DataObjectItem::Trace(blink::Visitor* visitor) {
+void DataObjectItem::Trace(Visitor* visitor) {
visitor->Trace(file_);
+ visitor->Trace(system_clipboard_);
}
} // namespace blink
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 07f92814f06..69843abb6d2 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
@@ -40,6 +40,8 @@
namespace blink {
+class SystemClipboard;
+
class CORE_EXPORT DataObjectItem final
: public GarbageCollected<DataObjectItem> {
public:
@@ -61,13 +63,15 @@ class CORE_EXPORT DataObjectItem final
const KURL&,
const String& file_extension,
const AtomicString& content_disposition);
- static DataObjectItem* CreateFromClipboard(const String& type,
+ static DataObjectItem* CreateFromClipboard(SystemClipboard* system_clipboard,
+ const String& type,
uint64_t sequence_number);
- explicit DataObjectItem(ItemKind, const String& type);
- explicit DataObjectItem(ItemKind,
- const String& type,
- uint64_t sequence_number);
+ DataObjectItem(ItemKind kind, const String& type);
+ DataObjectItem(ItemKind,
+ const String& type,
+ uint64_t sequence_number,
+ SystemClipboard* system_clipboard);
ItemKind Kind() const { return kind_; }
String GetType() const { return type_; }
@@ -85,7 +89,7 @@ class CORE_EXPORT DataObjectItem final
bool HasFileSystemId() const;
String FileSystemId() const;
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
enum DataSource {
@@ -107,6 +111,9 @@ class CORE_EXPORT DataObjectItem final
uint64_t sequence_number_; // Only valid when |source_| == PasteboardSource.
String file_system_id_; // Only valid when |file_| is backed by FileEntry.
+
+ // Access to the global system clipboard.
+ Member<SystemClipboard> system_clipboard_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/clipboard/data_object_test.cc b/chromium/third_party/blink/renderer/core/clipboard/data_object_test.cc
index f1a313a129f..455adfabf87 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/data_object_test.cc
+++ b/chromium/third_party/blink/renderer/core/clipboard/data_object_test.cc
@@ -128,8 +128,10 @@ TEST_F(DataObjectTest, fileSystemId) {
data_object_->AddFilename(file_path, String(), String());
data_object_->AddFilename(file_path, String(), "fileSystemIdForFilename");
+ FileMetadata metadata;
+ metadata.length = 0;
data_object_->Add(
- File::CreateForFileSystemFile(url, FileMetadata(), File::kIsUserVisible),
+ File::CreateForFileSystemFile(url, metadata, File::kIsUserVisible),
"fileSystemIdForFileSystemFile");
ASSERT_EQ(3U, data_object_->length());
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 907a8628443..047fb1945e0 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/data_transfer.cc
+++ b/chromium/third_party/blink/renderer/core/clipboard/data_transfer.cc
@@ -93,7 +93,8 @@ class DraggedNodeImageBuilder {
DCHECK_EQ(dom_tree_version_, node_->GetDocument().DomTreeVersion());
#endif
// Construct layout object for |node_| with pseudo class "-webkit-drag"
- local_frame_->View()->UpdateAllLifecyclePhasesExceptPaint();
+ local_frame_->View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kDragImage);
LayoutObject* const dragged_layout_object = node_->GetLayoutObject();
if (!dragged_layout_object)
return nullptr;
@@ -148,8 +149,8 @@ class DraggedNodeImageBuilder {
}
private:
- const Member<LocalFrame> local_frame_;
- const Member<Node> node_;
+ LocalFrame* const local_frame_;
+ Node* const node_;
#if DCHECK_IS_ON()
const uint64_t dom_tree_version_;
#endif
@@ -203,11 +204,11 @@ static String ConvertDragOperationToEffectAllowed(DragOperation op) {
}
// We provide the IE clipboard types (URL and Text), and the clipboard types
-// specified in the WHATWG Web Applications 1.0 draft see
-// http://www.whatwg.org/specs/web-apps/current-work/ Section 6.3.5.3
+// specified in the HTML spec. See
+// https://html.spec.whatwg.org/multipage/dnd.html#the-datatransfer-interface
static String NormalizeType(const String& type,
bool* convert_to_url = nullptr) {
- String clean_type = type.StripWhiteSpace().DeprecatedLower();
+ String clean_type = type.StripWhiteSpace().LowerASCII();
if (clean_type == kMimeTypeText ||
clean_type.StartsWith(kMimeTypeTextPlainEtc))
return kMimeTypeTextPlain;
@@ -219,6 +220,7 @@ static String NormalizeType(const String& type,
return clean_type;
}
+// static
DataTransfer* DataTransfer::Create() {
DataTransfer* data = Create(
kCopyAndPaste, DataTransferAccessPolicy::kWritable, DataObject::Create());
@@ -227,6 +229,7 @@ DataTransfer* DataTransfer::Create() {
return data;
}
+// static
DataTransfer* DataTransfer::Create(DataTransferType type,
DataTransferAccessPolicy policy,
DataObject* data_object) {
@@ -677,7 +680,7 @@ String ConvertDragOperationToDropZoneOperation(DragOperation operation) {
}
}
-void DataTransfer::Trace(blink::Visitor* visitor) {
+void DataTransfer::Trace(Visitor* visitor) {
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 67d3be7239a..06c596b39e7 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/data_transfer.h
+++ b/chromium/third_party/blink/renderer/core/clipboard/data_transfer.h
@@ -72,9 +72,7 @@ class CORE_EXPORT DataTransfer final : public ScriptWrappable,
DataTransferAccessPolicy,
DataObject*);
- explicit DataTransfer(DataTransferType,
- DataTransferAccessPolicy,
- DataObject*);
+ DataTransfer(DataTransferType, DataTransferAccessPolicy, DataObject*);
~DataTransfer() override;
bool IsForCopyAndPaste() const { return transfer_type_ == kCopyAndPaste; }
@@ -158,7 +156,7 @@ class CORE_EXPORT DataTransfer final : public ScriptWrappable,
const PropertyTreeState&);
static std::unique_ptr<DragImage> NodeImage(LocalFrame&, Node&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void setDragImage(ImageResourceContent*, Node*, const IntPoint&);
diff --git a/chromium/third_party/blink/renderer/core/clipboard/data_transfer.idl b/chromium/third_party/blink/renderer/core/clipboard/data_transfer.idl
index 96b269f04ec..7209dd85b96 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/data_transfer.idl
+++ b/chromium/third_party/blink/renderer/core/clipboard/data_transfer.idl
@@ -29,9 +29,9 @@
// https://html.spec.whatwg.org/C/#the-datatransfer-interface
[
- Constructor,
Exposed=Window
] interface DataTransfer {
+ constructor();
attribute DOMString dropEffect;
attribute DOMString effectAllowed;
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 3d7b7a108f4..459ace940b3 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(blink::Visitor* visitor) {
+void DataTransferItem::Trace(Visitor* visitor) {
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 8e0fd0fd9ec..eb8bb1372dc 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 9645ec71863..b7e0bbfcc3c 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(blink::Visitor* visitor) {
+void DataTransferItemList::Trace(Visitor* visitor) {
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 0c0df5f7832..40619a675b9 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<DataTransfer> data_transfer_;
diff --git a/chromium/third_party/blink/renderer/core/clipboard/data_transfer_test.cc b/chromium/third_party/blink/renderer/core/clipboard/data_transfer_test.cc
index 4674a8ab9c3..57627202f37 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/data_transfer_test.cc
+++ b/chromium/third_party/blink/renderer/core/clipboard/data_transfer_test.cc
@@ -135,8 +135,8 @@ TEST_F(DataTransferTest, NodeImageUnderScrollOffset) {
const int scroll_amount = 10;
LocalFrameView* frame_view = GetDocument().View();
- frame_view->LayoutViewport()->SetScrollOffset(ScrollOffset(0, scroll_amount),
- kProgrammaticScroll);
+ frame_view->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, scroll_amount), mojom::blink::ScrollType::kProgrammatic);
// The first div should be offset by the scroll offset.
Element& first = *GetDocument().getElementById("first");
@@ -176,8 +176,8 @@ TEST_F(DataTransferTest, NodeImageSizeWithPageScaleFactor) {
// page scale factor.
const int scroll_amount = 10;
LocalFrameView* frame_view = GetDocument().View();
- frame_view->LayoutViewport()->SetScrollOffset(ScrollOffset(0, scroll_amount),
- kProgrammaticScroll);
+ frame_view->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, scroll_amount), mojom::blink::ScrollType::kProgrammatic);
const auto image_with_offset = DataTransfer::NodeImage(GetFrame(), node);
EXPECT_EQ(
IntSize(node_width * page_scale_factor, node_height * page_scale_factor),
@@ -207,8 +207,8 @@ TEST_F(DataTransferTest, NodeImageSizeWithPageScaleFactorTooLarge) {
// page scale factor.
const int scroll_amount = 10;
LocalFrameView* frame_view = GetDocument().View();
- frame_view->LayoutViewport()->SetScrollOffset(ScrollOffset(0, scroll_amount),
- kProgrammaticScroll);
+ frame_view->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, scroll_amount), mojom::blink::ScrollType::kProgrammatic);
const auto image_with_offset = DataTransfer::NodeImage(GetFrame(), node);
EXPECT_EQ(IntSize(node_width * page_scale_factor,
(node_height - scroll_amount) * page_scale_factor),
@@ -272,8 +272,8 @@ TEST_F(DataTransferTest, NodeImageFullyOffscreen) {
const int scroll_amount = 800;
LocalFrameView* frame_view = GetDocument().View();
- frame_view->LayoutViewport()->SetScrollOffset(ScrollOffset(0, scroll_amount),
- kProgrammaticScroll);
+ frame_view->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, scroll_amount), mojom::blink::ScrollType::kProgrammatic);
Element& target = *GetDocument().getElementById("target");
const auto image = DataTransfer::NodeImage(GetFrame(), target);
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
new file mode 100644
index 00000000000..0e1d95a0252
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/clipboard/raw_system_clipboard.cc
@@ -0,0 +1,25 @@
+// 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/clipboard/raw_system_clipboard.h"
+
+#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
+
+namespace blink {
+
+RawSystemClipboard::RawSystemClipboard(LocalFrame* frame) {
+ frame->GetBrowserInterfaceBroker().GetInterface(
+ clipboard_.BindNewPipeAndPassReceiver());
+}
+
+void RawSystemClipboard::Write(const String& type, mojo_base::BigBuffer data) {
+ clipboard_->Write(type, std::move(data));
+}
+
+void RawSystemClipboard::CommitWrite() {
+ clipboard_->CommitWrite();
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..eba190f4673
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/clipboard/raw_system_clipboard.h
@@ -0,0 +1,41 @@
+// 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_CLIPBOARD_RAW_SYSTEM_CLIPBOARD_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_CLIPBOARD_RAW_SYSTEM_CLIPBOARD_H_
+
+#include "mojo/public/cpp/bindings/remote.h" // For mojo::Remote<T>
+#include "third_party/blink/public/mojom/clipboard/raw_clipboard.mojom-blink.h"
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
+
+// RawSystemClipboard:
+// - is a singleton.
+// - provides read/write access of unsanitized, platform-specific data.
+// - mediates between async clipboard and mojom::RawClipboardHost.
+//
+// All calls to Write() must be followed by a call to CommitWrite().
+namespace blink {
+
+class LocalFrame;
+
+class CORE_EXPORT RawSystemClipboard final
+ : public GarbageCollected<RawSystemClipboard> {
+ public:
+ explicit RawSystemClipboard(LocalFrame* frame);
+
+ RawSystemClipboard(const RawSystemClipboard&) = delete;
+ RawSystemClipboard& operator=(const RawSystemClipboard&) = delete;
+
+ void Write(const String& type, mojo_base::BigBuffer data);
+ void CommitWrite();
+ void Trace(Visitor*) {}
+
+ private:
+ mojo::Remote<mojom::blink::RawClipboardHost> clipboard_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CLIPBOARD_RAW_SYSTEM_CLIPBOARD_H_
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 601ec0d8971..905739a4b40 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/system_clipboard.cc
+++ b/chromium/third_party/blink/renderer/core/clipboard/system_clipboard.cc
@@ -7,13 +7,15 @@
#include "base/memory/scoped_refptr.h"
#include "build/build_config.h"
#include "mojo/public/cpp/system/platform_handle.h"
-#include "third_party/blink/public/platform/interface_provider.h"
+#include "third_party/blink/public/common/browser_interface_broker_proxy.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_drag_data.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/renderer/core/clipboard/clipboard_mime_types.h"
#include "third_party/blink/renderer/core/clipboard/clipboard_utilities.h"
#include "third_party/blink/renderer/core/clipboard/data_object.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
@@ -29,14 +31,8 @@ String NonNullString(const String& string) {
} // namespace
-// static
-SystemClipboard& SystemClipboard::GetInstance() {
- DEFINE_STATIC_LOCAL(SystemClipboard, clipboard, ());
- return clipboard;
-}
-
-SystemClipboard::SystemClipboard() {
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+SystemClipboard::SystemClipboard(LocalFrame* frame) {
+ frame->GetBrowserInterfaceBroker().GetInterface(
clipboard_.BindNewPipeAndPassReceiver());
}
@@ -156,6 +152,12 @@ SkBitmap SystemClipboard::ReadImage(mojom::ClipboardBuffer buffer) {
return image;
}
+String SystemClipboard::ReadImageAsImageMarkup(
+ mojom::blink::ClipboardBuffer buffer) {
+ SkBitmap bitmap = ReadImage(buffer);
+ return BitmapToImageMarkup(bitmap);
+}
+
void SystemClipboard::WriteImageWithTag(Image* image,
const KURL& url,
const String& title) {
@@ -213,11 +215,11 @@ void SystemClipboard::WriteDataObject(DataObject* data_object) {
WebDragData data = data_object->ToWebDragData();
for (const WebDragData::Item& item : data.Items()) {
if (item.storage_type == WebDragData::Item::kStorageTypeString) {
- if (item.string_type == blink::kMimeTypeTextPlain) {
+ if (item.string_type == kMimeTypeTextPlain) {
clipboard_->WriteText(NonNullString(item.string_data));
- } else if (item.string_type == blink::kMimeTypeTextHTML) {
+ } else if (item.string_type == kMimeTypeTextHTML) {
clipboard_->WriteHtml(NonNullString(item.string_data), KURL());
- } else if (item.string_type != blink::kMimeTypeDownloadURL) {
+ } else if (item.string_type != kMimeTypeDownloadURL) {
custom_data.insert(item.string_type, NonNullString(item.string_data));
}
}
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 5b9e6cd3656..71a11cb6ffa 100644
--- a/chromium/third_party/blink/renderer/core/clipboard/system_clipboard.h
+++ b/chromium/third_party/blink/renderer/core/clipboard/system_clipboard.h
@@ -8,6 +8,7 @@
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/clipboard/clipboard.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -17,18 +18,20 @@ namespace blink {
class DataObject;
class Image;
class KURL;
+class LocalFrame;
-// This singleton provides read/write access to the system clipboard,
-// mediating between core classes and mojom::ClipboardHost.
+// SystemClipboard:
+// - is a singleton.
+// - provides sanitized, platform-neutral read/write access to the clipboard.
+// - mediates between core classes and mojom::ClipboardHost.
+//
// All calls to write functions must be followed by a call to CommitWrite().
-class CORE_EXPORT SystemClipboard {
- USING_FAST_MALLOC(SystemClipboard);
-
+class CORE_EXPORT SystemClipboard final
+ : public GarbageCollected<SystemClipboard> {
public:
- static SystemClipboard& GetInstance();
-
enum SmartReplaceOption { kCanSmartReplace, kCannotSmartReplace };
+ explicit SystemClipboard(LocalFrame* frame);
uint64_t SequenceNumber();
bool IsSelectionMode() const;
void SetSelectionMode(bool);
@@ -55,6 +58,7 @@ class CORE_EXPORT SystemClipboard {
String ReadRTF();
SkBitmap ReadImage(mojom::ClipboardBuffer);
+ String ReadImageAsImageMarkup(mojom::blink::ClipboardBuffer);
// Write the image and its associated tag (bookmark/HTML types).
void WriteImageWithTag(Image*, const KURL&, const String& title);
@@ -68,8 +72,9 @@ class CORE_EXPORT SystemClipboard {
// the OS clipboard.
void CommitWrite();
+ void Trace(Visitor*) {}
+
private:
- SystemClipboard();
bool IsValidBufferType(mojom::ClipboardBuffer);
mojo::Remote<mojom::blink::ClipboardHost> clipboard_;
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 c0e166ff3a2..082500fc4d4 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
@@ -5,7 +5,6 @@
#include "third_party/blink/renderer/core/content_capture/content_capture_manager.h"
#include "third_party/blink/renderer/core/content_capture/sent_nodes.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/layout/layout_text.h"
@@ -20,27 +19,25 @@ ContentCaptureManager::ContentCaptureManager(LocalFrame& local_frame_root)
ContentCaptureManager::~ContentCaptureManager() = default;
-DOMNodeId ContentCaptureManager::GetNodeId(Node& node) {
+void ContentCaptureManager::ScheduleTaskIfNeeded() {
if (first_node_holder_created_) {
ScheduleTask(ContentCaptureTask::ScheduleReason::kContentChange);
} else {
ScheduleTask(ContentCaptureTask::ScheduleReason::kFirstContentChange);
first_node_holder_created_ = true;
}
- return DOMNodeIds::IdForNode(&node);
}
void ContentCaptureManager::ScheduleTask(
ContentCaptureTask::ScheduleReason reason) {
- if (!content_capture_idle_task_.get()) {
+ if (!content_capture_idle_task_) {
content_capture_idle_task_ = CreateContentCaptureTask();
}
content_capture_idle_task_->Schedule(reason);
}
-scoped_refptr<ContentCaptureTask>
-ContentCaptureManager::CreateContentCaptureTask() {
- return base::MakeRefCounted<ContentCaptureTask>(*local_frame_root_,
+ContentCaptureTask* ContentCaptureManager::CreateContentCaptureTask() {
+ return MakeGarbageCollected<ContentCaptureTask>(*local_frame_root_,
*task_session_);
}
@@ -63,6 +60,7 @@ void ContentCaptureManager::OnNodeTextChanged(Node& node) {
}
void ContentCaptureManager::Trace(Visitor* visitor) {
+ visitor->Trace(content_capture_idle_task_);
visitor->Trace(local_frame_root_);
visitor->Trace(task_session_);
visitor->Trace(sent_nodes_);
@@ -71,7 +69,7 @@ void ContentCaptureManager::Trace(Visitor* visitor) {
void ContentCaptureManager::Shutdown() {
if (content_capture_idle_task_) {
content_capture_idle_task_->Shutdown();
- content_capture_idle_task_.reset();
+ content_capture_idle_task_ = nullptr;
}
}
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 9d374aa9777..c27016600e9 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
@@ -24,11 +24,8 @@ class CORE_EXPORT ContentCaptureManager
explicit ContentCaptureManager(LocalFrame& local_frame_root);
virtual ~ContentCaptureManager();
- // Creates and returns NodeHolder for the given |node|, and schedules
- // ContentCaptureTask if it isn't already scheduled.
- // Can't use const Node& for parameter, because |node| is passed to
- // DOMNodeIds::IdForNode(Node*).
- DOMNodeId GetNodeId(Node& node);
+ // Schedules ContentCaptureTask if it isn't already scheduled.
+ void ScheduleTaskIfNeeded();
// Invokes when the |node_holder| asscociated LayoutText will be destroyed.
void OnLayoutTextWillBeDestroyed(const Node& node);
@@ -42,21 +39,21 @@ class CORE_EXPORT ContentCaptureManager
// Invokes when the local_frame_root shutdown.
void Shutdown();
- virtual void Trace(blink::Visitor*);
+ virtual void Trace(Visitor*);
ContentCaptureTask* GetContentCaptureTaskForTesting() const {
- return content_capture_idle_task_.get();
+ return content_capture_idle_task_;
}
protected:
- virtual scoped_refptr<ContentCaptureTask> CreateContentCaptureTask();
+ virtual ContentCaptureTask* CreateContentCaptureTask();
TaskSession& GetTaskSessionForTesting() const { return *task_session_; }
private:
void NotifyNodeDetached(const Node& node);
void ScheduleTask(ContentCaptureTask::ScheduleReason reason);
- scoped_refptr<ContentCaptureTask> content_capture_idle_task_;
+ Member<ContentCaptureTask> content_capture_idle_task_;
Member<LocalFrame> local_frame_root_;
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 bc6300e2866..0d9b43bf30d 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
@@ -268,4 +268,9 @@ void ContentCaptureTask::CancelTaskForTesting() {
delay_task_->Stop();
}
+void ContentCaptureTask::Trace(Visitor* visitor) {
+ visitor->Trace(local_frame_root_);
+ visitor->Trace(task_session_);
+}
+
} // namespace blink
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 1064b7bc9ee..f00e9fb26b3 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
@@ -24,9 +24,8 @@ class LocalFrame;
// This class is used to capture the on-screen content and send them out
// through WebContentCaptureClient.
-class CORE_EXPORT ContentCaptureTask : public RefCounted<ContentCaptureTask> {
- USING_FAST_MALLOC(ContentCaptureTask);
-
+class CORE_EXPORT ContentCaptureTask
+ : public GarbageCollected<ContentCaptureTask> {
public:
enum class ScheduleReason {
kFirstContentChange,
@@ -69,6 +68,8 @@ class CORE_EXPORT ContentCaptureTask : public RefCounted<ContentCaptureTask> {
base::TimeDelta GetTaskNextFireIntervalForTesting() const;
void CancelTaskForTesting();
+ void Trace(Visitor*);
+
protected:
// All protected data and methods are for testing purpose.
// Return true if the task should pause.
@@ -103,8 +104,8 @@ class CORE_EXPORT ContentCaptureTask : public RefCounted<ContentCaptureTask> {
// Indicates if there is content change since last run.
bool has_content_change_ = false;
- UntracedMember<LocalFrame> local_frame_root_;
- UntracedMember<TaskSession> task_session_;
+ Member<LocalFrame> local_frame_root_;
+ Member<TaskSession> task_session_;
std::unique_ptr<TaskRunnerTimer<ContentCaptureTask>> delay_task_;
TaskState task_state_ = TaskState::kStop;
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 930c04892ea..e0577afd83f 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
@@ -8,6 +8,7 @@
#include "third_party/blink/public/web/web_content_capture_client.h"
#include "third_party/blink/public/web/web_content_holder.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h"
+#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
@@ -119,21 +120,26 @@ class ContentCaptureManagerTestHelper : public ContentCaptureManager {
LocalFrame& local_frame_root,
WebContentCaptureClientTestHelper& content_capture_client)
: ContentCaptureManager(local_frame_root) {
- content_capture_task_ = base::MakeRefCounted<ContentCaptureTaskTestHelper>(
+ content_capture_task_ = MakeGarbageCollected<ContentCaptureTaskTestHelper>(
local_frame_root, GetTaskSessionForTesting(), content_capture_client);
}
- scoped_refptr<ContentCaptureTaskTestHelper> GetContentCaptureTask() {
+ ContentCaptureTaskTestHelper* GetContentCaptureTask() {
return content_capture_task_;
}
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(content_capture_task_);
+ ContentCaptureManager::Trace(visitor);
+ }
+
protected:
- scoped_refptr<ContentCaptureTask> CreateContentCaptureTask() override {
+ ContentCaptureTask* CreateContentCaptureTask() override {
return content_capture_task_;
}
private:
- scoped_refptr<ContentCaptureTaskTestHelper> content_capture_task_;
+ Member<ContentCaptureTaskTestHelper> content_capture_task_;
};
class ContentCaptureLocalFrameClientHelper : public EmptyLocalFrameClient {
@@ -192,7 +198,8 @@ class ContentCaptureTest : public PageTestBase {
Element* div_element = GetElementById("d1");
div_element->appendChild(element);
UpdateAllLifecyclePhasesForTest();
- created_node_id_ = GetContentCaptureManager()->GetNodeId(*node);
+ GetContentCaptureManager()->ScheduleTaskIfNeeded();
+ created_node_id_ = DOMNodeIds::IdForNode(node);
Vector<DOMNodeId> captured_content{created_node_id_};
content_capture_manager_->GetContentCaptureTask()
->SetCapturedContentForTesting(captured_content);
@@ -206,7 +213,7 @@ class ContentCaptureTest : public PageTestBase {
return content_capture_client_.get();
}
- scoped_refptr<ContentCaptureTaskTestHelper> GetContentCaptureTask() const {
+ ContentCaptureTaskTestHelper* GetContentCaptureTask() const {
return GetContentCaptureManager()->GetContentCaptureTask();
}
@@ -268,7 +275,8 @@ class ContentCaptureTest : public PageTestBase {
CHECK(layout_object);
CHECK(layout_object->IsText());
nodes_.push_back(node);
- node_ids_.push_back(GetContentCaptureManager()->GetNodeId(*node));
+ GetContentCaptureManager()->ScheduleTaskIfNeeded();
+ node_ids_.push_back(DOMNodeIds::IdForNode(node));
}
}
@@ -523,7 +531,7 @@ TEST_F(ContentCaptureTest, TaskHistogramReporter) {
TEST_F(ContentCaptureTest, RescheduleTask) {
// This test assumes test runs much faster than task's long delay which is 5s.
- scoped_refptr<ContentCaptureTaskTestHelper> task = GetContentCaptureTask();
+ Persistent<ContentCaptureTaskTestHelper> task = GetContentCaptureTask();
task->CancelTaskForTesting();
EXPECT_TRUE(task->GetTaskNextFireIntervalForTesting().is_zero());
task->Schedule(ContentCaptureTask::ScheduleReason::kContentChange);
@@ -540,7 +548,7 @@ TEST_F(ContentCaptureTest, RescheduleTask) {
TEST_F(ContentCaptureTest, NotRescheduleTask) {
// This test assumes test runs much faster than task's long delay which is 5s.
- scoped_refptr<ContentCaptureTaskTestHelper> task = GetContentCaptureTask();
+ Persistent<ContentCaptureTaskTestHelper> task = GetContentCaptureTask();
task->CancelTaskForTesting();
EXPECT_TRUE(task->GetTaskNextFireIntervalForTesting().is_zero());
task->Schedule(ContentCaptureTask::ScheduleReason::kContentChange);
@@ -663,7 +671,7 @@ class ContentCaptureSimTest : public SimTest {
auto* child_frame =
To<HTMLIFrameElement>(GetDocument().getElementById("frame"));
child_document_ = child_frame->contentDocument();
- child_document_->UpdateStyleAndLayout();
+ child_document_->UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Compositor().BeginFrame();
InitMainFrameNodeHolders();
InitChildFrameNodeHolders(*child_document_);
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 b814501ffc4..d183c29ee79 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(blink::Visitor* visitor) {
+void SentNodes::Trace(Visitor* visitor) {
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 17ea8e54e15..7848cb6fa54 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(blink::Visitor*);
+ void Trace(Visitor*);
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 ce4ae094187..c1f9585c76e 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(blink::Visitor* visitor) {
+void TaskSession::DocumentSession::Trace(Visitor* visitor) {
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(blink::Visitor* visitor) {
+void TaskSession::Trace(Visitor* visitor) {
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 80c2864c079..abf429fc29a 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(blink::Visitor*);
+ void Trace(Visitor*);
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(blink::Visitor*);
+ void Trace(Visitor*);
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 48533e9795d..c48154d19be 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(blink::Visitor* visitor) {
+void ContextFeatureSettings::Trace(Visitor* visitor) {
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 7e4ab3ad257..174066de6c6 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 b7df7c9e685..e9c5f45ac04 100644
--- a/chromium/third_party/blink/renderer/core/core.gni
+++ b/chromium/third_party/blink/renderer/core/core.gni
@@ -62,16 +62,12 @@ template("blink_core_sources") {
# invoker defined it.
visibility = [ "//third_party/blink/renderer/core/*" ]
- deps = [
- "//third_party/blink/renderer/core:prerequisites",
- ]
+ deps = [ "//third_party/blink/renderer/core:prerequisites" ]
if (defined(invoker.deps)) {
deps += invoker.deps
}
- public_deps = [
- "//third_party/blink/renderer/core:all_generators",
- ]
+ public_deps = [ "//third_party/blink/renderer/core:all_generators" ]
if (defined(invoker.public_deps)) {
public_deps += invoker.public_deps
}
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 cbefd9c9bda..31ae21cfbd2 100644
--- a/chromium/third_party/blink/renderer/core/core_idl_files.gni
+++ b/chromium/third_party/blink/renderer/core/core_idl_files.gni
@@ -117,7 +117,6 @@ core_idl_files =
"dom/dom_token_list.idl",
"dom/document_fragment.idl",
"dom/document_type.idl",
- "dom/element.idl",
"dom/idle_deadline.idl",
"dom/iterator.idl",
"dom/mutation_observer.idl",
@@ -187,12 +186,14 @@ core_idl_files =
"frame/bar_prop.idl",
"frame/csp/csp_violation_report_body.idl",
"frame/deprecation_report_body.idl",
+ "frame/document_policy_violation_report_body.idl",
"frame/external.idl",
"frame/feature_policy_violation_report_body.idl",
"frame/fragment_directive.idl",
"frame/history.idl",
"frame/intervention_report_body.idl",
"frame/location.idl",
+ "frame/navigator_ua_data.idl",
"frame/report.idl",
"frame/report_body.idl",
"frame/reporting_observer.idl",
@@ -286,6 +287,7 @@ core_idl_files =
"html/forms/html_output_element.idl",
"html/forms/html_select_element.idl",
"html/forms/html_text_area_element.idl",
+ "html/forms/submit_event.idl",
"html/forms/radio_node_list.idl",
"html/forms/validity_state.idl",
"html/media/html_audio_element.idl",
@@ -311,6 +313,7 @@ core_idl_files =
"intersection_observer/intersection_observer.idl",
"intersection_observer/intersection_observer_entry.idl",
"invisible_dom/activate_invisible_event.idl",
+ "layout/ng/custom/intrinsic_sizes.idl",
"layout/ng/custom/layout_constraints.idl",
"layout/ng/custom/layout_edges.idl",
"layout/ng/custom/layout_fragment.idl",
@@ -325,10 +328,12 @@ core_idl_files =
"mojo/mojo_watcher.idl",
"mojo/test/mojo_interface_interceptor.idl",
"mojo/test/mojo_interface_request_event.idl",
+ "page/color_page_popup_controller.idl",
"page/page_popup_controller.idl",
"page/scrolling/scroll_state.idl",
"resize_observer/resize_observer.idl",
"resize_observer/resize_observer_entry.idl",
+ "resize_observer/resize_observer_size.idl",
"streams/byte_length_queuing_strategy.idl",
"streams/count_queuing_strategy.idl",
"streams/readable_stream.idl",
@@ -364,7 +369,6 @@ core_idl_files =
"svg/svg_component_transfer_function_element.idl",
"svg/svg_defs_element.idl",
"svg/svg_desc_element.idl",
- "svg/svg_discard_element.idl",
"svg/svg_element.idl",
"svg/svg_ellipse_element.idl",
"svg/svg_fe_blend_element.idl",
@@ -499,6 +503,7 @@ core_idl_with_modules_dependency_files =
"clipboard/data_transfer_item.idl",
"css/css.idl",
"dom/document.idl",
+ "dom/element.idl",
"dom/shadow_root.idl",
"frame/navigator.idl",
"frame/screen.idl",
@@ -553,8 +558,8 @@ core_dependency_idl_files =
"frame/navigator_language.idl",
"frame/navigator_on_line.idl",
"frame/navigator_scheduling.idl",
+ "frame/navigator_ua.idl",
"frame/navigator_user_activation.idl",
- "frame/navigator_user_agent.idl",
"frame/window_event_handlers.idl",
"frame/window_or_worker_global_scope.idl",
"fullscreen/document_fullscreen.idl",
@@ -657,13 +662,14 @@ core_dictionary_idl_files =
"events/wheel_event_init.idl",
"fetch/request_init.idl",
"fetch/response_init.idl",
+ "fetch/trust_token.idl",
"fileapi/blob_property_bag.idl",
"fileapi/file_property_bag.idl",
+ "frame/navigator_ua_brand_version.idl",
"frame/reporting_observer_options.idl",
"frame/scroll_into_view_options.idl",
"frame/scroll_options.idl",
"frame/scroll_to_options.idl",
- "frame/user_agent.idl",
"frame/window_post_message_options.idl",
"fullscreen/fullscreen_options.idl",
"geometry/dom_matrix_2d_init.idl",
@@ -678,6 +684,7 @@ core_dictionary_idl_files =
"html/canvas/image_encode_options.idl",
"html/custom/validity_state_flags.idl",
"html/forms/form_data_event_init.idl",
+ "html/forms/submit_event_init.idl",
"html/portal/portal_activate_event_init.idl",
"html/portal/portal_activate_options.idl",
"html/track/track_event_init.idl",
@@ -685,8 +692,10 @@ core_dictionary_idl_files =
"input/input_device_capabilities_init.idl",
"input/touch_init.idl",
"intersection_observer/intersection_observer_init.idl",
+ "frame/ua_data_values.idl",
"layout/ng/custom/custom_layout_constraints_options.idl",
"layout/ng/custom/fragment_result_options.idl",
+ "layout/ng/custom/intrinsic_sizes_result_options.idl",
"messaging/post_message_options.idl",
"mojo/mojo_create_data_pipe_options.idl",
"mojo/mojo_create_data_pipe_result.idl",
@@ -704,10 +713,10 @@ core_dictionary_idl_files =
"mojo/mojo_write_data_result.idl",
"mojo/test/mojo_interface_request_event_init.idl",
"page/scrolling/scroll_state_init.idl",
+ "resize_observer/resize_observer_options.idl",
"streams/queuing_strategy_init.idl",
"timing/measure_memory/measure_memory.idl",
- "timing/measure_memory/measure_memory_entry.idl",
- "timing/measure_memory/measure_memory_options.idl",
+ "timing/measure_memory/measure_memory_breakdown.idl",
"timing/performance_mark_options.idl",
"timing/performance_measure_options.idl",
"timing/performance_observer_init.idl",
@@ -788,7 +797,8 @@ core_static_dependency_idl_files =
core_dependency_idl_files + webcore_testing_dependency_idl_files
# Generated IDL files
-core_generated_interface_idl_files = generated_webcore_testing_idl_files # interfaces
+core_generated_interface_idl_files =
+ generated_webcore_testing_idl_files # interfaces
core_generated_dependency_idl_files =
core_global_constructors_generated_idl_files # partial interfaces
diff --git a/chromium/third_party/blink/renderer/core/core_initializer.cc b/chromium/third_party/blink/renderer/core/core_initializer.cc
index 82b8f94210f..cb5ad15a22e 100644
--- a/chromium/third_party/blink/renderer/core/core_initializer.cc
+++ b/chromium/third_party/blink/renderer/core/core_initializer.cc
@@ -59,8 +59,6 @@
#include "third_party/blink/renderer/platform/font_family_names.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h"
#include "third_party/blink/renderer/platform/network/http_names.h"
-#include "third_party/blink/renderer/platform/weborigin/kurl.h"
-#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string_table.h"
@@ -136,8 +134,6 @@ void CoreInitializer::Initialize() {
style_change_extra_data::Init();
- KURL::Initialize();
- SchemeRegistry::Initialize();
SecurityPolicy::Init();
RegisterEventFactory();
diff --git a/chromium/third_party/blink/renderer/core/css/BUILD.gn b/chromium/third_party/blink/renderer/core/css/BUILD.gn
index bda1f9c8be2..183fd3f3789 100644
--- a/chromium/third_party/blink/renderer/core/css/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/css/BUILD.gn
@@ -128,8 +128,6 @@ blink_core_sources("css") {
"css_paint_value.h",
"css_path_value.cc",
"css_path_value.h",
- "css_pending_interpolation_value.cc",
- "css_pending_interpolation_value.h",
"css_pending_substitution_value.cc",
"css_pending_substitution_value.h",
"css_primitive_value.cc",
@@ -368,6 +366,7 @@ blink_core_sources("css") {
"media_query_list_listener.h",
"media_query_matcher.cc",
"media_query_matcher.h",
+ "media_value_change.h",
"media_values.cc",
"media_values.h",
"media_values_cached.cc",
@@ -468,6 +467,16 @@ blink_core_sources("css") {
"pseudo_style_request.h",
"remote_font_face_source.cc",
"remote_font_face_source.h",
+ "resolver/cascade_expansion.cc",
+ "resolver/cascade_expansion.h",
+ "resolver/cascade_filter.h",
+ "resolver/cascade_interpolations.h",
+ "resolver/cascade_map.cc",
+ "resolver/cascade_map.h",
+ "resolver/cascade_origin.h",
+ "resolver/cascade_priority.h",
+ "resolver/cascade_resolver.cc",
+ "resolver/cascade_resolver.h",
"resolver/css_property_priority.h",
"resolver/css_to_style_map.cc",
"resolver/css_to_style_map.h",
@@ -497,8 +506,6 @@ blink_core_sources("css") {
"resolver/selector_filter_parent_scope.h",
"resolver/style_adjuster.cc",
"resolver/style_adjuster.h",
- "resolver/style_animator.cc",
- "resolver/style_animator.h",
"resolver/style_builder.cc",
"resolver/style_builder.h",
"resolver/style_builder_converter.cc",
@@ -580,6 +587,8 @@ blink_core_sources("css") {
"style_traversal_root.h",
"tree_scope_style_sheet_collection.cc",
"tree_scope_style_sheet_collection.h",
+ "vision_deficiency.cc",
+ "vision_deficiency.h",
"zoom_adjusted_pixel_value.h",
]
}
@@ -596,7 +605,6 @@ blink_core_tests("unit_tests") {
"css_math_expression_node_test.cc",
"css_page_rule_test.cc",
"css_paint_value_test.cc",
- "css_pending_interpolation_value_test.cc",
"css_primitive_value_test.cc",
"css_property_name_test.cc",
"css_property_value_set_test.cc",
@@ -605,6 +613,7 @@ blink_core_tests("unit_tests") {
"css_style_declaration_test.cc",
"css_style_sheet_test.cc",
"css_syntax_string_parser_test.cc",
+ "cssom/computed_style_property_map_test.cc",
"cssom/cross_thread_style_value_test.cc",
"cssom/css_math_invert_test.cc",
"cssom/css_math_negate_test.cc",
@@ -636,6 +645,7 @@ blink_core_tests("unit_tests") {
"parser/css_parser_token_test.cc",
"parser/css_property_parser_test.cc",
"parser/css_selector_parser_test.cc",
+ "parser/css_supports_parser_test.cc",
"parser/css_tokenizer_test.cc",
"parser/media_condition_test.cc",
"parser/sizes_attribute_parser_test.cc",
@@ -645,6 +655,11 @@ blink_core_tests("unit_tests") {
"properties/css_property_ref_test.cc",
"properties/css_property_test.cc",
"properties/longhands/custom_property_test.cc",
+ "resolver/cascade_expansion_test.cc",
+ "resolver/cascade_filter_test.cc",
+ "resolver/cascade_interpolations_test.cc",
+ "resolver/cascade_map_test.cc",
+ "resolver/cascade_priority_test.cc",
"resolver/css_variable_data_test.cc",
"resolver/css_variable_resolver_test.cc",
"resolver/font_builder_test.cc",
diff --git a/chromium/third_party/blink/renderer/core/css/OWNERS b/chromium/third_party/blink/renderer/core/css/OWNERS
index d1eb1c37ec5..a007a39a025 100644
--- a/chromium/third_party/blink/renderer/core/css/OWNERS
+++ b/chromium/third_party/blink/renderer/core/css/OWNERS
@@ -2,6 +2,7 @@ alancutter@chromium.org
andruud@chromium.org
ericwilligers@chromium.org
futhark@chromium.org
+xiaochengh@chromium.org
# TEAM: layout-dev@chromium.org
# COMPONENT: Blink>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 71b74cf2c96..99fcc338130 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
@@ -70,7 +70,8 @@ void AbstractPropertySetCSSStyleDeclaration::setCSSText(
String AbstractPropertySetCSSStyleDeclaration::getPropertyValue(
const String& property_name) {
- CSSPropertyID property_id = cssPropertyID(property_name);
+ CSSPropertyID property_id =
+ cssPropertyID(GetExecutionContext(), property_name);
if (!isValidCSSPropertyID(property_id))
return String();
if (property_id == CSSPropertyID::kVariable)
@@ -80,7 +81,8 @@ String AbstractPropertySetCSSStyleDeclaration::getPropertyValue(
String AbstractPropertySetCSSStyleDeclaration::getPropertyPriority(
const String& property_name) {
- CSSPropertyID property_id = cssPropertyID(property_name);
+ CSSPropertyID property_id =
+ cssPropertyID(GetExecutionContext(), property_name);
if (!isValidCSSPropertyID(property_id))
return String();
@@ -94,7 +96,8 @@ String AbstractPropertySetCSSStyleDeclaration::getPropertyPriority(
String AbstractPropertySetCSSStyleDeclaration::GetPropertyShorthand(
const String& property_name) {
- CSSPropertyID property_id = cssPropertyID(property_name);
+ CSSPropertyID property_id =
+ cssPropertyID(GetExecutionContext(), property_name);
// Custom properties don't have shorthands, so we can ignore them here.
if (!isValidCSSPropertyID(property_id) ||
@@ -108,7 +111,8 @@ String AbstractPropertySetCSSStyleDeclaration::GetPropertyShorthand(
bool AbstractPropertySetCSSStyleDeclaration::IsPropertyImplicit(
const String& property_name) {
- CSSPropertyID property_id = cssPropertyID(property_name);
+ CSSPropertyID property_id =
+ cssPropertyID(GetExecutionContext(), property_name);
// Custom properties don't have shorthands, so we can ignore them here.
if (property_id < firstCSSProperty)
@@ -122,7 +126,8 @@ void AbstractPropertySetCSSStyleDeclaration::setProperty(
const String& value,
const String& priority,
ExceptionState& exception_state) {
- CSSPropertyID property_id = unresolvedCSSPropertyID(property_name);
+ CSSPropertyID property_id =
+ unresolvedCSSPropertyID(execution_context, property_name);
if (!isValidCSSPropertyID(property_id))
return;
@@ -138,7 +143,8 @@ void AbstractPropertySetCSSStyleDeclaration::setProperty(
String AbstractPropertySetCSSStyleDeclaration::removeProperty(
const String& property_name,
ExceptionState& exception_state) {
- CSSPropertyID property_id = cssPropertyID(property_name);
+ CSSPropertyID property_id =
+ cssPropertyID(GetExecutionContext(), property_name);
if (!isValidCSSPropertyID(property_id))
return String();
@@ -170,7 +176,8 @@ AbstractPropertySetCSSStyleDeclaration::GetPropertyCSSValueInternal(
const CSSValue*
AbstractPropertySetCSSStyleDeclaration::GetPropertyCSSValueInternal(
AtomicString custom_property_name) {
- DCHECK_EQ(CSSPropertyID::kVariable, cssPropertyID(custom_property_name));
+ DCHECK_EQ(CSSPropertyID::kVariable,
+ cssPropertyID(GetExecutionContext(), custom_property_name));
return PropertySet().GetPropertyCSSValue(custom_property_name);
}
@@ -212,11 +219,6 @@ void AbstractPropertySetCSSStyleDeclaration::SetPropertyInternal(
if (!did_change)
return;
- Element* parent = ParentElement();
- if (parent) {
- parent->GetDocument().GetStyleEngine().AttributeChangedForElement(
- html_names::kStyleAttr, *parent);
- }
mutation_scope.EnqueueMutationRecord();
}
@@ -233,7 +235,7 @@ bool AbstractPropertySetCSSStyleDeclaration::CssPropertyMatches(
return PropertySet().PropertyMatches(property_id, property_value);
}
-void AbstractPropertySetCSSStyleDeclaration::Trace(blink::Visitor* visitor) {
+void AbstractPropertySetCSSStyleDeclaration::Trace(Visitor* visitor) {
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 e6e7d68239f..2d4ce8c5cc4 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
@@ -42,8 +42,10 @@ class AbstractPropertySetCSSStyleDeclaration : public CSSStyleDeclaration {
public:
virtual Element* ParentElement() const { return nullptr; }
StyleSheetContents* ContextStyleSheet() const;
+ AbstractPropertySetCSSStyleDeclaration(ExecutionContext* context)
+ : CSSStyleDeclaration(context) {}
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
CSSRule* parentRule() const override { return nullptr; }
diff --git a/chromium/third_party/blink/renderer/core/css/active_style_sheets.cc b/chromium/third_party/blink/renderer/core/css/active_style_sheets.cc
index 1359ffeda38..3c9209e0847 100644
--- a/chromium/third_party/blink/renderer/core/css/active_style_sheets.cc
+++ b/chromium/third_party/blink/renderer/core/css/active_style_sheets.cc
@@ -124,22 +124,4 @@ ActiveSheetsChange CompareActiveStyleSheets(
: kActiveSheetsChanged;
}
-bool ClearMediaQueryDependentRuleSets(
- const ActiveStyleSheetVector& active_style_sheets) {
- bool needs_active_style_update = false;
- for (const auto& active_sheet : active_style_sheets) {
- if (const MediaQuerySet* media_queries =
- active_sheet.first->MediaQueries()) {
- if (!media_queries->QueryVector().IsEmpty())
- needs_active_style_update = true;
- }
- StyleSheetContents* contents = active_sheet.first->Contents();
- if (contents->HasMediaQueries()) {
- needs_active_style_update = true;
- contents->ClearRuleSet();
- }
- }
- return needs_active_style_update;
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/active_style_sheets.h b/chromium/third_party/blink/renderer/core/css/active_style_sheets.h
index 42fdcf28225..47f3ae5d58c 100644
--- a/chromium/third_party/blink/renderer/core/css/active_style_sheets.h
+++ b/chromium/third_party/blink/renderer/core/css/active_style_sheets.h
@@ -27,9 +27,6 @@ CompareActiveStyleSheets(const ActiveStyleSheetVector& old_style_sheets,
const ActiveStyleSheetVector& new_style_sheets,
HeapHashSet<Member<RuleSet>>& changed_rule_sets);
-bool ClearMediaQueryDependentRuleSets(
- const ActiveStyleSheetVector& active_style_sheets);
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_ACTIVE_STYLE_SHEETS_H_
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 eb111cd6ea6..4f38ad0a53a 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
@@ -6,6 +6,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_shadow_root_init.h"
#include "third_party/blink/renderer/core/css/css_style_sheet.h"
#include "third_party/blink/renderer/core/css/media_query_evaluator.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_context.h"
@@ -14,7 +15,6 @@
#include "third_party/blink/renderer/core/css/style_sheet_contents.h"
#include "third_party/blink/renderer/core/css/style_sheet_list.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
-#include "third_party/blink/renderer/core/dom/shadow_root_init.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
@@ -402,7 +402,7 @@ TEST_F(ActiveStyleSheetsTest, CompareActiveStyleSheets_AddRemoveNonMatchingMQ) {
CSSStyleSheet* sheet1 = CreateSheet();
scoped_refptr<MediaQuerySet> mq =
- MediaQueryParser::ParseMediaQuerySet("(min-width: 9000px)");
+ MediaQueryParser::ParseMediaQuerySet("(min-width: 9000px)", nullptr);
sheet1->SetMediaQueries(mq);
sheet1->MatchesMediaQueries(MediaQueryEvaluator());
@@ -436,7 +436,7 @@ TEST_F(ApplyRulesetsTest, AddUniversalRuleToDocument) {
}
TEST_F(ApplyRulesetsTest, AddUniversalRuleToShadowTree) {
- GetDocument().body()->SetInnerHTMLFromString("<div id=host></div>");
+ GetDocument().body()->setInnerHTML("<div id=host></div>");
Element* host = GetElementById("host");
ASSERT_TRUE(host);
@@ -475,7 +475,7 @@ TEST_F(ApplyRulesetsTest, AddFontFaceRuleToDocument) {
}
TEST_F(ApplyRulesetsTest, AddFontFaceRuleToShadowTree) {
- GetDocument().body()->SetInnerHTMLFromString("<div id=host></div>");
+ GetDocument().body()->setInnerHTML("<div id=host></div>");
Element* host = GetElementById("host");
ASSERT_TRUE(host);
@@ -500,14 +500,13 @@ TEST_F(ApplyRulesetsTest, AddFontFaceRuleToShadowTree) {
}
TEST_F(ApplyRulesetsTest, RemoveSheetFromShadowTree) {
- GetDocument().body()->SetInnerHTMLFromString("<div id=host></div>");
+ GetDocument().body()->setInnerHTML("<div id=host></div>");
Element* host = GetElementById("host");
ASSERT_TRUE(host);
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString(
- "<style>::slotted(#dummy){color:pink}</style>");
+ shadow_root.setInnerHTML("<style>::slotted(#dummy){color:pink}</style>");
UpdateAllLifecyclePhasesForTest();
EXPECT_TRUE(GetStyleEngine().TreeBoundaryCrossingScopes().IsEmpty());
diff --git a/chromium/third_party/blink/renderer/core/css/affected_by_pseudo_test.cc b/chromium/third_party/blink/renderer/core/css/affected_by_pseudo_test.cc
index 13e12573a9b..60f1e2bc241 100644
--- a/chromium/third_party/blink/renderer/core/css/affected_by_pseudo_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/affected_by_pseudo_test.cc
@@ -29,8 +29,7 @@ class AffectedByPseudoTest : public PageTestBase {
};
void AffectedByPseudoTest::SetHtmlInnerHTML(const char* html_content) {
- GetDocument().documentElement()->SetInnerHTMLFromString(
- String::FromUTF8(html_content));
+ GetDocument().documentElement()->setInnerHTML(String::FromUTF8(html_content));
UpdateAllLifecyclePhasesForTest();
}
diff --git a/chromium/third_party/blink/renderer/core/css/css.dict b/chromium/third_party/blink/renderer/core/css/css.dict
index 10741b6011f..25069da47a2 100644
--- a/chromium/third_party/blink/renderer/core/css/css.dict
+++ b/chromium/third_party/blink/renderer/core/css/css.dict
@@ -923,6 +923,9 @@
"fieldtext"
"canvas"
"canvastext"
+"jis-b5"
+"jis-b4"
+"hidden-matchable"
# at-rules
"@charset"
@@ -1354,6 +1357,7 @@
"stroke-repeat"
"stroke-size"
"stroke-width"
+"subtree-visibility"
"suffix"
"symbols"
"system"
diff --git a/chromium/third_party/blink/renderer/core/css/css_axis_value.h b/chromium/third_party/blink/renderer/core/css/css_axis_value.h
index 910f55f5601..70017c2f9b2 100644
--- a/chromium/third_party/blink/renderer/core/css/css_axis_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_axis_value.h
@@ -25,7 +25,7 @@ class CSSAxisValue : public CSSValueList {
double Z() const;
- void TraceAfterDispatch(blink::Visitor* visitor) {
+ void TraceAfterDispatch(blink::Visitor* visitor) const {
CSSValueList::TraceAfterDispatch(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_basic_shape_values.cc b/chromium/third_party/blink/renderer/core/css/css_basic_shape_values.cc
index 8c8aa51739e..2de790b7acb 100644
--- a/chromium/third_party/blink/renderer/core/css/css_basic_shape_values.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_basic_shape_values.cc
@@ -143,7 +143,8 @@ bool CSSBasicShapeCircleValue::Equals(
DataEquivalent(radius_, other.radius_);
}
-void CSSBasicShapeCircleValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSBasicShapeCircleValue::TraceAfterDispatch(
+ blink::Visitor* visitor) const {
visitor->Trace(center_x_);
visitor->Trace(center_y_);
visitor->Trace(radius_);
@@ -226,7 +227,8 @@ bool CSSBasicShapeEllipseValue::Equals(
DataEquivalent(radius_y_, other.radius_y_);
}
-void CSSBasicShapeEllipseValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSBasicShapeEllipseValue::TraceAfterDispatch(
+ blink::Visitor* visitor) const {
visitor->Trace(center_x_);
visitor->Trace(center_y_);
visitor->Trace(radius_x_);
@@ -287,7 +289,8 @@ bool CSSBasicShapePolygonValue::Equals(
return CompareCSSValueVector(values_, other.values_);
}
-void CSSBasicShapePolygonValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSBasicShapePolygonValue::TraceAfterDispatch(
+ blink::Visitor* visitor) const {
visitor->Trace(values_);
CSSValue::TraceAfterDispatch(visitor);
}
@@ -435,7 +438,8 @@ bool CSSBasicShapeInsetValue::Equals(
DataEquivalent(bottom_left_radius_, other.bottom_left_radius_);
}
-void CSSBasicShapeInsetValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSBasicShapeInsetValue::TraceAfterDispatch(
+ blink::Visitor* visitor) const {
visitor->Trace(top_);
visitor->Trace(right_);
visitor->Trace(bottom_);
diff --git a/chromium/third_party/blink/renderer/core/css/css_basic_shape_values.h b/chromium/third_party/blink/renderer/core/css/css_basic_shape_values.h
index 027d2841bfa..bfadef67f45 100644
--- a/chromium/third_party/blink/renderer/core/css/css_basic_shape_values.h
+++ b/chromium/third_party/blink/renderer/core/css/css_basic_shape_values.h
@@ -58,7 +58,7 @@ class CSSBasicShapeCircleValue final : public CSSValue {
void SetCenterY(CSSValue* center_y) { center_y_ = center_y; }
void SetRadius(CSSValue* radius) { radius_ = radius; }
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
Member<CSSValue> center_x_;
@@ -84,7 +84,7 @@ class CSSBasicShapeEllipseValue final : public CSSValue {
void SetRadiusX(CSSValue* radius_x) { radius_x_ = radius_x; }
void SetRadiusY(CSSValue* radius_y) { radius_y_ = radius_y; }
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
Member<CSSValue> center_x_;
@@ -116,7 +116,7 @@ class CSSBasicShapePolygonValue final : public CSSValue {
String CustomCSSText() const;
bool Equals(const CSSBasicShapePolygonValue&) const;
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
HeapVector<Member<CSSPrimitiveValue>> values_;
@@ -180,7 +180,7 @@ class CSSBasicShapeInsetValue final : public CSSValue {
String CustomCSSText() const;
bool Equals(const CSSBasicShapeInsetValue&) const;
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
Member<CSSPrimitiveValue> top_;
diff --git a/chromium/third_party/blink/renderer/core/css/css_border_image_slice_value.cc b/chromium/third_party/blink/renderer/core/css/css_border_image_slice_value.cc
index a762bdeb656..d18e899527c 100644
--- a/chromium/third_party/blink/renderer/core/css/css_border_image_slice_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_border_image_slice_value.cc
@@ -51,7 +51,8 @@ bool CSSBorderImageSliceValue::Equals(
return fill_ == other.fill_ && DataEquivalent(slices_, other.slices_);
}
-void CSSBorderImageSliceValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSBorderImageSliceValue::TraceAfterDispatch(
+ blink::Visitor* visitor) const {
visitor->Trace(slices_);
CSSValue::TraceAfterDispatch(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_border_image_slice_value.h b/chromium/third_party/blink/renderer/core/css/css_border_image_slice_value.h
index 27468d6ac8b..6438b0c97a6 100644
--- a/chromium/third_party/blink/renderer/core/css/css_border_image_slice_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_border_image_slice_value.h
@@ -46,7 +46,7 @@ class CSSBorderImageSliceValue : public CSSValue {
bool Equals(const CSSBorderImageSliceValue&) const;
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
// These four values are used to make "cuts" in the border image. They can be
diff --git a/chromium/third_party/blink/renderer/core/css/css_color_value.h b/chromium/third_party/blink/renderer/core/css/css_color_value.h
index c752b9a4189..2b4d16bd070 100644
--- a/chromium/third_party/blink/renderer/core/css/css_color_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_color_value.h
@@ -32,7 +32,7 @@ class CORE_EXPORT CSSColorValue : public CSSValue {
return color_ == other.color_;
}
- 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_computed_style_declaration.cc b/chromium/third_party/blink/renderer/core/css/css_computed_style_declaration.cc
index 729b37a3af3..4df6327a8ee 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
@@ -157,9 +157,7 @@ const CSSPropertyID kComputedPropertyArray[] = {
CSSPropertyID::kRowGap, CSSPropertyID::kWebkitHighlight,
CSSPropertyID::kHyphens, CSSPropertyID::kWebkitHyphenateCharacter,
CSSPropertyID::kWebkitLineBreak, CSSPropertyID::kWebkitLineClamp,
- CSSPropertyID::kWebkitLocale, CSSPropertyID::kWebkitMarginBeforeCollapse,
- CSSPropertyID::kWebkitMarginAfterCollapse,
- CSSPropertyID::kWebkitMaskBoxImage,
+ CSSPropertyID::kWebkitLocale, CSSPropertyID::kWebkitMaskBoxImage,
CSSPropertyID::kWebkitMaskBoxImageOutset,
CSSPropertyID::kWebkitMaskBoxImageRepeat,
CSSPropertyID::kWebkitMaskBoxImageSlice,
@@ -205,7 +203,7 @@ const CSSPropertyID kComputedPropertyArray[] = {
CSSPropertyID::kCy, CSSPropertyID::kX, CSSPropertyID::kY, CSSPropertyID::kR,
CSSPropertyID::kRx, CSSPropertyID::kRy, CSSPropertyID::kTranslate,
CSSPropertyID::kRotate, CSSPropertyID::kScale, CSSPropertyID::kCaretColor,
- CSSPropertyID::kLineBreak};
+ CSSPropertyID::kLineBreak, CSSPropertyID::kMathStyle};
CSSValueID CssIdentifierForFontSizeKeyword(int keyword_size) {
DCHECK_NE(keyword_size, 0);
@@ -228,11 +226,13 @@ void LogUnimplementedPropertyID(const CSSProperty& property) {
} // namespace
const Vector<const CSSProperty*>&
-CSSComputedStyleDeclaration::ComputableProperties() {
+CSSComputedStyleDeclaration::ComputableProperties(
+ const ExecutionContext* execution_context) {
DEFINE_STATIC_LOCAL(Vector<const CSSProperty*>, properties, ());
if (properties.IsEmpty()) {
CSSProperty::FilterWebExposedCSSPropertiesIntoVector(
- kComputedPropertyArray, base::size(kComputedPropertyArray), properties);
+ execution_context, kComputedPropertyArray,
+ base::size(kComputedPropertyArray), properties);
}
return properties;
}
@@ -241,7 +241,8 @@ CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(
Node* n,
bool allow_visited_style,
const String& pseudo_element_name)
- : node_(n),
+ : CSSStyleDeclaration(n ? n->GetExecutionContext() : nullptr),
+ node_(n),
pseudo_element_specifier_(
CSSSelector::ParsePseudoId(pseudo_element_name)),
allow_visited_style_(allow_visited_style) {}
@@ -250,7 +251,8 @@ CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration() = default;
String CSSComputedStyleDeclaration::cssText() const {
StringBuilder result;
- static const Vector<const CSSProperty*>& properties = ComputableProperties();
+ static const Vector<const CSSProperty*>& properties =
+ ComputableProperties(GetExecutionContext());
for (unsigned i = 0; i < properties.size(); i++) {
if (i)
@@ -277,7 +279,7 @@ CSSComputedStyleDeclaration::GetFontSizeCSSValuePreferringKeyword() const {
if (!node_)
return nullptr;
- node_->GetDocument().UpdateStyleAndLayout();
+ node_->GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
const ComputedStyle* style =
node_->EnsureComputedStyle(pseudo_element_specifier_);
@@ -387,7 +389,8 @@ const CSSValue* CSSComputedStyleDeclaration::GetPropertyCSSValue(
CSSProperty::Get(property_name.Id()).IsLayoutDependentProperty();
if (is_layout_dependent_property ||
document.GetStyleEngine().HasViewportDependentMediaQueries()) {
- owner->GetDocument().UpdateStyleAndLayout();
+ owner->GetDocument().UpdateStyleAndLayout(
+ DocumentUpdateReason::kJavaScript);
// The style recalc could have caused the styled node to be discarded or
// replaced if it was a PseudoElement so we need to update it.
styled_node = StyledNode();
@@ -408,7 +411,8 @@ const CSSValue* CSSComputedStyleDeclaration::GetPropertyCSSValue(
const ComputedStyle* style = ComputeComputedStyle();
if (property_class.IsLayoutDependent(style, layout_object)) {
- document.UpdateStyleAndLayoutForNode(styled_node);
+ document.UpdateStyleAndLayoutForNode(styled_node,
+ DocumentUpdateReason::kJavaScript);
styled_node = StyledNode();
style = ComputeComputedStyle();
layout_object = StyledLayoutObject();
@@ -444,14 +448,15 @@ String CSSComputedStyleDeclaration::GetPropertyValue(
unsigned CSSComputedStyleDeclaration::length() const {
if (!node_ || !node_->InActiveDocument())
return 0;
- return ComputableProperties().size();
+ return ComputableProperties(GetExecutionContext()).size();
}
String CSSComputedStyleDeclaration::item(unsigned i) const {
if (i >= length())
return "";
- return ComputableProperties()[i]->GetPropertyNameString();
+ return ComputableProperties(GetExecutionContext())[i]
+ ->GetPropertyNameString();
}
bool CSSComputedStyleDeclaration::CssPropertyMatches(
@@ -461,7 +466,8 @@ bool CSSComputedStyleDeclaration::CssPropertyMatches(
(property_value.IsPrimitiveValue() ||
property_value.IsIdentifierValue()) &&
node_) {
- node_->GetDocument().UpdateStyleAndLayout();
+ // This is only used by editing code.
+ node_->GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
const ComputedStyle* style =
node_->EnsureComputedStyle(pseudo_element_specifier_);
if (style && style->GetFontDescription().KeywordSize()) {
@@ -478,7 +484,7 @@ bool CSSComputedStyleDeclaration::CssPropertyMatches(
MutableCSSPropertyValueSet* CSSComputedStyleDeclaration::CopyProperties()
const {
- return CopyPropertiesInSet(ComputableProperties());
+ return CopyPropertiesInSet(ComputableProperties(GetExecutionContext()));
}
MutableCSSPropertyValueSet* CSSComputedStyleDeclaration::CopyPropertiesInSet(
@@ -501,7 +507,8 @@ CSSRule* CSSComputedStyleDeclaration::parentRule() const {
String CSSComputedStyleDeclaration::getPropertyValue(
const String& property_name) {
- CSSPropertyID property_id = cssPropertyID(property_name);
+ CSSPropertyID property_id =
+ cssPropertyID(GetExecutionContext(), property_name);
if (!isValidCSSPropertyID(property_id))
return String();
if (property_id == CSSPropertyID::kVariable) {
@@ -561,7 +568,8 @@ const CSSValue* CSSComputedStyleDeclaration::GetPropertyCSSValueInternal(
const CSSValue* CSSComputedStyleDeclaration::GetPropertyCSSValueInternal(
AtomicString custom_property_name) {
- DCHECK_EQ(CSSPropertyID::kVariable, cssPropertyID(custom_property_name));
+ DCHECK_EQ(CSSPropertyID::kVariable,
+ cssPropertyID(GetExecutionContext(), custom_property_name));
return GetPropertyCSSValue(custom_property_name);
}
@@ -584,7 +592,7 @@ void CSSComputedStyleDeclaration::SetPropertyInternal(
"' property is read-only.");
}
-void CSSComputedStyleDeclaration::Trace(blink::Visitor* visitor) {
+void CSSComputedStyleDeclaration::Trace(Visitor* visitor) {
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 0b699ed9794..e0a5730871c 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
@@ -34,6 +34,7 @@
namespace blink {
class ExceptionState;
+class ExecutionContext;
class LayoutObject;
class MutableCSSPropertyValueSet;
class Node;
@@ -42,7 +43,8 @@ class ComputedStyle;
class CORE_EXPORT CSSComputedStyleDeclaration final
: public CSSStyleDeclaration {
public:
- static const Vector<const CSSProperty*>& ComputableProperties();
+ static const Vector<const CSSProperty*>& ComputableProperties(
+ const ExecutionContext*);
CSSComputedStyleDeclaration(Node*,
bool allow_visited_style = false,
@@ -69,7 +71,7 @@ class CORE_EXPORT CSSComputedStyleDeclaration final
unsigned length() const override;
String item(unsigned index) const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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_computed_style_declaration_test.cc b/chromium/third_party/blink/renderer/core/css/css_computed_style_declaration_test.cc
index 31e4f24b328..88479844002 100644
--- a/chromium/third_party/blink/renderer/core/css/css_computed_style_declaration_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_computed_style_declaration_test.cc
@@ -13,7 +13,7 @@ namespace blink {
class CSSComputedStyleDeclarationTest : public PageTestBase {};
TEST_F(CSSComputedStyleDeclarationTest, CleanAncestorsNoRecalc) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<div id=dirty></div>
<div>
<div id=target style='color:green'></div>
@@ -34,7 +34,7 @@ TEST_F(CSSComputedStyleDeclarationTest, CleanAncestorsNoRecalc) {
}
TEST_F(CSSComputedStyleDeclarationTest, CleanShadowAncestorsNoRecalc) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<div id=dirty></div>
<div id=host></div>
)HTML");
@@ -43,7 +43,7 @@ TEST_F(CSSComputedStyleDeclarationTest, CleanShadowAncestorsNoRecalc) {
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString(R"HTML(
+ shadow_root.setInnerHTML(R"HTML(
<div id=target style='color:green'></div>
)HTML");
@@ -62,7 +62,7 @@ TEST_F(CSSComputedStyleDeclarationTest, CleanShadowAncestorsNoRecalc) {
}
TEST_F(CSSComputedStyleDeclarationTest, NeedsAdjacentStyleRecalc) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
#a + #b { color: green }
</style>
diff --git a/chromium/third_party/blink/renderer/core/css/css_content_distribution_value.cc b/chromium/third_party/blink/renderer/core/css/css_content_distribution_value.cc
index ec16589d085..e0c21b841b0 100644
--- a/chromium/third_party/blink/renderer/core/css/css_content_distribution_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_content_distribution_value.cc
@@ -19,8 +19,6 @@ CSSContentDistributionValue::CSSContentDistributionValue(
position_(position),
overflow_(overflow) {}
-CSSContentDistributionValue::~CSSContentDistributionValue() = default;
-
String CSSContentDistributionValue::CustomCSSText() const {
CSSValueList* list = CSSValueList::CreateSpaceSeparated();
diff --git a/chromium/third_party/blink/renderer/core/css/css_content_distribution_value.h b/chromium/third_party/blink/renderer/core/css/css_content_distribution_value.h
index 5254d95649d..6b96107d732 100644
--- a/chromium/third_party/blink/renderer/core/css/css_content_distribution_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_content_distribution_value.h
@@ -19,7 +19,6 @@ class CSSContentDistributionValue : public CSSValue {
CSSContentDistributionValue(CSSValueID distribution,
CSSValueID position,
CSSValueID overflow);
- ~CSSContentDistributionValue();
CSSValueID Distribution() const { return distribution_; }
@@ -31,7 +30,7 @@ class CSSContentDistributionValue : public CSSValue {
bool Equals(const CSSContentDistributionValue&) const;
- 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_counter_value.cc b/chromium/third_party/blink/renderer/core/css/css_counter_value.cc
index af96186fe2d..34f1f796232 100644
--- a/chromium/third_party/blink/renderer/core/css/css_counter_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_counter_value.cc
@@ -33,7 +33,7 @@ String CSSCounterValue::CustomCSSText() const {
return result.ToString();
}
-void CSSCounterValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSCounterValue::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(identifier_);
visitor->Trace(list_style_);
visitor->Trace(separator_);
diff --git a/chromium/third_party/blink/renderer/core/css/css_counter_value.h b/chromium/third_party/blink/renderer/core/css/css_counter_value.h
index 6c5e9b6866e..004b56844de 100644
--- a/chromium/third_party/blink/renderer/core/css/css_counter_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_counter_value.h
@@ -52,7 +52,7 @@ class CSSCounterValue : public CSSValue {
String CustomCSSText() const;
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
Member<CSSCustomIdentValue> identifier_; // string
diff --git a/chromium/third_party/blink/renderer/core/css/css_crossfade_value.cc b/chromium/third_party/blink/renderer/core/css/css_crossfade_value.cc
index 171afb923b5..5051a541852 100644
--- a/chromium/third_party/blink/renderer/core/css/css_crossfade_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_crossfade_value.cc
@@ -176,14 +176,12 @@ FloatSize CSSCrossfadeValue::FixedSize(
FloatSize from_image_size(from_image->Size());
FloatSize to_image_size(to_image->Size());
- if (from_image->IsSVGImage()) {
- from_image_size =
- ToSVGImage(from_image)->ConcreteObjectSize(default_object_size);
+ if (auto* from_svg_image = DynamicTo<SVGImage>(from_image)) {
+ from_image_size = from_svg_image->ConcreteObjectSize(default_object_size);
}
- if (to_image->IsSVGImage()) {
- to_image_size =
- ToSVGImage(to_image)->ConcreteObjectSize(default_object_size);
+ if (auto* to_svg_image = DynamicTo<SVGImage>(to_image)) {
+ to_image_size = to_svg_image->ConcreteObjectSize(default_object_size);
}
// Rounding issues can cause transitions between images of equal size to
@@ -252,13 +250,13 @@ scoped_refptr<Image> CSSCrossfadeValue::GetImage(
scoped_refptr<Image> from_image_ref(from_image);
scoped_refptr<Image> to_image_ref(to_image);
- if (from_image->IsSVGImage()) {
- from_image_ref = SVGImageForContainer::Create(
- ToSVGImage(from_image), size, 1, UrlForCSSValue(*from_value_));
+ if (auto* from_svg_image = DynamicTo<SVGImage>(from_image)) {
+ from_image_ref = SVGImageForContainer::Create(from_svg_image, size, 1,
+ UrlForCSSValue(*from_value_));
}
- if (to_image->IsSVGImage()) {
- to_image_ref = SVGImageForContainer::Create(ToSVGImage(to_image), size, 1,
+ if (auto* to_svg_image = DynamicTo<SVGImage>(to_image)) {
+ to_image_ref = SVGImageForContainer::Create(to_svg_image, size, 1,
UrlForCSSValue(*to_value_));
}
@@ -311,7 +309,7 @@ bool CSSCrossfadeValue::Equals(const CSSCrossfadeValue& other) const {
DataEquivalent(percentage_value_, other.percentage_value_);
}
-void CSSCrossfadeValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSCrossfadeValue::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(from_value_);
visitor->Trace(to_value_);
visitor->Trace(percentage_value_);
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 3b0e9ed9aa1..35bc6bb011d 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
@@ -71,7 +71,7 @@ class CORE_EXPORT CSSCrossfadeValue final : public CSSImageGeneratorValue {
CSSCrossfadeValue* ComputedCSSValue(const ComputedStyle&,
bool allow_visited_style);
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
void Dispose();
@@ -84,7 +84,7 @@ class CORE_EXPORT CSSCrossfadeValue final : public CSSImageGeneratorValue {
: owner_value_(owner_value), ready_(false) {}
~CrossfadeSubimageObserverProxy() override = default;
- void Trace(blink::Visitor* visitor) { visitor->Trace(owner_value_); }
+ void Trace(Visitor* visitor) { visitor->Trace(owner_value_); }
void ImageChanged(ImageResourceContent*, CanDeferInvalidation) override;
bool WillRenderImage() override;
diff --git a/chromium/third_party/blink/renderer/core/css/css_cursor_image_value.cc b/chromium/third_party/blink/renderer/core/css/css_cursor_image_value.cc
index fd8abed813f..913c7b602b4 100644
--- a/chromium/third_party/blink/renderer/core/css/css_cursor_image_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_cursor_image_value.cc
@@ -38,8 +38,6 @@ CSSCursorImageValue::CSSCursorImageValue(const CSSValue& image_value,
DCHECK(image_value.IsImageValue() || image_value.IsImageSetValue());
}
-CSSCursorImageValue::~CSSCursorImageValue() = default;
-
String CSSCursorImageValue::CustomCSSText() const {
StringBuilder result;
result.Append(image_value_->CssText());
@@ -59,7 +57,7 @@ bool CSSCursorImageValue::Equals(const CSSCursorImageValue& other) const {
DataEquivalent(image_value_, other.image_value_);
}
-void CSSCursorImageValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSCursorImageValue::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(image_value_);
CSSValue::TraceAfterDispatch(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_cursor_image_value.h b/chromium/third_party/blink/renderer/core/css/css_cursor_image_value.h
index 14b39797ba1..8fd4c478274 100644
--- a/chromium/third_party/blink/renderer/core/css/css_cursor_image_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_cursor_image_value.h
@@ -34,7 +34,6 @@ class CSSCursorImageValue : public CSSValue {
CSSCursorImageValue(const CSSValue& image_value,
bool hot_spot_specified,
const IntPoint& hot_spot);
- ~CSSCursorImageValue();
bool HotSpotSpecified() const { return hot_spot_specified_; }
const IntPoint& HotSpot() const { return hot_spot_; }
@@ -44,7 +43,7 @@ class CSSCursorImageValue : public CSSValue {
bool Equals(const CSSCursorImageValue&) const;
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
Member<const CSSValue> image_value_;
diff --git a/chromium/third_party/blink/renderer/core/css/css_custom_ident_value.cc b/chromium/third_party/blink/renderer/core/css/css_custom_ident_value.cc
index 257cc010d9e..b3927288c98 100644
--- a/chromium/third_party/blink/renderer/core/css/css_custom_ident_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_custom_ident_value.cc
@@ -31,7 +31,7 @@ String CSSCustomIdentValue::CustomCSSText() const {
return builder.ToString();
}
-void CSSCustomIdentValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSCustomIdentValue::TraceAfterDispatch(blink::Visitor* visitor) const {
CSSValue::TraceAfterDispatch(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_custom_ident_value.h b/chromium/third_party/blink/renderer/core/css/css_custom_ident_value.h
index d60d893ba43..0179c94cdc2 100644
--- a/chromium/third_party/blink/renderer/core/css/css_custom_ident_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_custom_ident_value.h
@@ -36,7 +36,7 @@ class CORE_EXPORT CSSCustomIdentValue : public CSSValue {
: string_ == other.string_;
}
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
AtomicString string_;
diff --git a/chromium/third_party/blink/renderer/core/css/css_custom_property_declaration.cc b/chromium/third_party/blink/renderer/core/css/css_custom_property_declaration.cc
index f0e2f8732a1..887cbed4537 100644
--- a/chromium/third_party/blink/renderer/core/css/css_custom_property_declaration.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_custom_property_declaration.cc
@@ -8,7 +8,8 @@
namespace blink {
-void CSSCustomPropertyDeclaration::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSCustomPropertyDeclaration::TraceAfterDispatch(
+ blink::Visitor* visitor) const {
CSSValue::TraceAfterDispatch(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_custom_property_declaration.h b/chromium/third_party/blink/renderer/core/css/css_custom_property_declaration.h
index 57cbd75d1fc..f7d09e70029 100644
--- a/chromium/third_party/blink/renderer/core/css/css_custom_property_declaration.h
+++ b/chromium/third_party/blink/renderer/core/css/css_custom_property_declaration.h
@@ -50,7 +50,7 @@ class CORE_EXPORT CSSCustomPropertyDeclaration : public CSSValue {
return this == &other;
}
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
const AtomicString name_;
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 99aa87f59c7..35b4ac04a48 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
@@ -128,6 +128,7 @@ void CSSDefaultStyleSheets::PrepareForLeakDetection() {
media_controls_style_sheet_.Clear();
text_track_style_sheet_.Clear();
fullscreen_style_sheet_.Clear();
+ webxr_overlay_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();
@@ -282,6 +283,20 @@ void CSSDefaultStyleSheets::SetMediaControlsStyleSheetLoader(
media_controls_style_sheet_loader_.swap(loader);
}
+bool CSSDefaultStyleSheets::EnsureDefaultStyleSheetForXrOverlay() {
+ if (webxr_overlay_style_sheet_)
+ return false;
+
+ webxr_overlay_style_sheet_ = ParseUASheet(
+ UncompressResourceAsASCIIString(IDR_UASTYLE_WEBXR_OVERLAY_CSS));
+ default_style_->AddRulesFromSheet(webxr_overlay_style_sheet_, ScreenEval());
+ default_print_style_->AddRulesFromSheet(webxr_overlay_style_sheet_,
+ PrintEval());
+ default_forced_color_style_->AddRulesFromSheet(webxr_overlay_style_sheet_,
+ ForcedColorsEval());
+ return true;
+}
+
void CSSDefaultStyleSheets::EnsureDefaultStyleSheetForFullscreen() {
if (fullscreen_style_sheet_)
return;
@@ -295,7 +310,7 @@ void CSSDefaultStyleSheets::EnsureDefaultStyleSheetForFullscreen() {
ScreenEval());
}
-void CSSDefaultStyleSheets::Trace(blink::Visitor* visitor) {
+void CSSDefaultStyleSheets::Trace(Visitor* visitor) {
visitor->Trace(default_style_);
visitor->Trace(default_quirks_style_);
visitor->Trace(default_print_style_);
@@ -311,6 +326,7 @@ void CSSDefaultStyleSheets::Trace(blink::Visitor* visitor) {
visitor->Trace(media_controls_style_sheet_);
visitor->Trace(text_track_style_sheet_);
visitor->Trace(fullscreen_style_sheet_);
+ visitor->Trace(webxr_overlay_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 7efd4b60cda..d46f6d86a1a 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
@@ -44,6 +44,7 @@ class CSSDefaultStyleSheets final
CSSDefaultStyleSheets();
bool EnsureDefaultStyleSheetsForElement(const Element&);
+ bool EnsureDefaultStyleSheetForXrOverlay();
void EnsureDefaultStyleSheetForFullscreen();
RuleSet* DefaultStyle() { return default_style_.Get(); }
@@ -87,7 +88,7 @@ class CSSDefaultStyleSheets final
return media_controls_style_sheet_loader_.get();
}
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
void InitializeDefaultStyles();
@@ -108,6 +109,7 @@ class CSSDefaultStyleSheets final
Member<StyleSheetContents> media_controls_style_sheet_;
Member<StyleSheetContents> text_track_style_sheet_;
Member<StyleSheetContents> fullscreen_style_sheet_;
+ Member<StyleSheetContents> webxr_overlay_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 6824c185f60..8794978bc9b 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
@@ -32,6 +32,7 @@
#include "third_party/blink/renderer/core/css/font_face_set_document.h"
#include "third_party/blink/renderer/core/css/font_face_set_worker.h"
#include "third_party/blink/renderer/core/css/remote_font_face_source.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/platform/fonts/font_description.h"
#include "third_party/blink/renderer/platform/fonts/simple_font_data.h"
@@ -214,9 +215,12 @@ void CSSFontFace::SetLoadStatus(FontFace::LoadStatusType new_status) {
if (segmented_font_faces_.IsEmpty() || !font_face_->GetExecutionContext())
return;
- if (auto* document = DynamicTo<Document>(font_face_->GetExecutionContext())) {
- if (new_status == FontFace::kLoading)
- FontFaceSetDocument::From(*document)->BeginFontLoading(font_face_);
+ if (auto* window =
+ DynamicTo<LocalDOMWindow>(font_face_->GetExecutionContext())) {
+ if (new_status == FontFace::kLoading) {
+ FontFaceSetDocument::From(*window->document())
+ ->BeginFontLoading(font_face_);
+ }
} else if (auto* scope = DynamicTo<WorkerGlobalScope>(
font_face_->GetExecutionContext())) {
if (new_status == FontFace::kLoading)
@@ -224,7 +228,7 @@ void CSSFontFace::SetLoadStatus(FontFace::LoadStatusType new_status) {
}
}
-void CSSFontFace::Trace(blink::Visitor* visitor) {
+void CSSFontFace::Trace(Visitor* visitor) {
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 9f7f7bd14c6..1c725193245 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
@@ -82,7 +82,7 @@ class CORE_EXPORT CSSFontFace final : public GarbageCollected<CSSFontFace> {
bool HadBlankText() { return IsValid() && sources_.front()->HadBlankText(); }
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
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 b3bab3958d1..5e01733b0ba 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(blink::Visitor* visitor) {
+void CSSFontFaceRule::Trace(Visitor* visitor) {
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 ddb5d457350..6db949a54f4 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,7 +46,7 @@ class CSSFontFaceRule final : public CSSRule {
StyleRuleFontFace* StyleRule() const { return font_face_rule_.Get(); }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
CSSRule::Type type() const override { return kFontFaceRule; }
diff --git a/chromium/third_party/blink/renderer/core/css/css_font_face_source.cc b/chromium/third_party/blink/renderer/core/css/css_font_face_source.cc
index b89ad0455aa..50844267eac 100644
--- a/chromium/third_party/blink/renderer/core/css/css_font_face_source.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_font_face_source.cc
@@ -84,7 +84,7 @@ scoped_refptr<SimpleFontData> CSSFontFaceSource::GetFontData(
void CSSFontFaceSource::PruneOldestIfNeeded() {
if (font_cache_key_age.size() > kMaxCachedFontData) {
DCHECK_EQ(font_cache_key_age.size() - 1, kMaxCachedFontData);
- FontCacheKey& key = font_cache_key_age.back();
+ const FontCacheKey& key = font_cache_key_age.back();
auto font_data_entry = font_data_table_.Take(key);
font_cache_key_age.pop_back();
DCHECK_EQ(font_cache_key_age.size(), kMaxCachedFontData);
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 7c898d8426c..c0d4dcf95b3 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
@@ -74,7 +74,7 @@ class CORE_EXPORT CSSFontFaceSource
virtual bool HadBlankText() { return false; }
virtual void PaintRequested() {}
- virtual void Trace(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
protected:
CSSFontFaceSource() = default;
@@ -85,12 +85,8 @@ class CORE_EXPORT CSSFontFaceSource
private:
void PruneOldestIfNeeded();
- using FontDataTable = HashMap<FontCacheKey,
- scoped_refptr<SimpleFontData>,
- FontCacheKeyHash,
- FontCacheKeyTraits>;
- using FontCacheKeyAgeList =
- LinkedHashSet<FontCacheKey, FontCacheKeyHash, FontCacheKeyTraits>;
+ using FontDataTable = HashMap<FontCacheKey, scoped_refptr<SimpleFontData>>;
+ using FontCacheKeyAgeList = LinkedHashSet<FontCacheKey>;
FontDataTable font_data_table_;
FontCacheKeyAgeList font_cache_key_age;
diff --git a/chromium/third_party/blink/renderer/core/css/css_font_face_src_value.cc b/chromium/third_party/blink/renderer/core/css/css_font_face_src_value.cc
index f63019f8f2b..75f347ac69e 100644
--- a/chromium/third_party/blink/renderer/core/css/css_font_face_src_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_font_face_src_value.cc
@@ -90,7 +90,7 @@ FontResource& CSSFontFaceSrcValue::Fetch(ExecutionContext* context,
resource_request.SetReferrerString(referrer_.referrer);
ResourceLoaderOptions options;
options.initiator_info.name = fetch_initiator_type_names::kCSS;
- FetchParameters params(resource_request, options);
+ FetchParameters params(std::move(resource_request), options);
if (base::FeatureList::IsEnabled(
features::kWebFontsCacheAwareTimeoutAdaption)) {
params.SetCacheAwareLoadingEnabled(kIsCacheAwareLoadingEnabled);
@@ -137,7 +137,9 @@ void CSSFontFaceSrcValue::RestoreCachedResourceIfNeeded(
fetched_->GetResource()->Options().content_security_policy_option);
context->Fetcher()->EmulateLoadStartedForInspector(
fetched_->GetResource(), KURL(resource_url),
- mojom::RequestContextType::FONT, fetch_initiator_type_names::kCSS);
+ mojom::RequestContextType::FONT,
+ network::mojom::RequestDestination::kFont,
+ fetch_initiator_type_names::kCSS);
}
bool CSSFontFaceSrcValue::Equals(const CSSFontFaceSrcValue& other) const {
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 437e88d7fd7..b51006a53bc 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
@@ -44,7 +44,7 @@ class CORE_EXPORT CSSFontFaceSrcValue : public CSSValue {
const String& specified_resource,
const String& absolute_resource,
const Referrer& referrer,
- ContentSecurityPolicyDisposition should_check_content_security_policy,
+ network::mojom::CSPDisposition should_check_content_security_policy,
OriginClean origin_clean) {
return MakeGarbageCollected<CSSFontFaceSrcValue>(
specified_resource, absolute_resource, referrer, false,
@@ -52,7 +52,7 @@ class CORE_EXPORT CSSFontFaceSrcValue : public CSSValue {
}
static CSSFontFaceSrcValue* CreateLocal(
const String& absolute_resource,
- ContentSecurityPolicyDisposition should_check_content_security_policy,
+ network::mojom::CSPDisposition should_check_content_security_policy,
OriginClean origin_clean) {
return MakeGarbageCollected<CSSFontFaceSrcValue>(
g_empty_string, absolute_resource, Referrer(), true,
@@ -64,7 +64,7 @@ class CORE_EXPORT CSSFontFaceSrcValue : public CSSValue {
const String& absolute_resource,
const Referrer& referrer,
bool local,
- ContentSecurityPolicyDisposition should_check_content_security_policy,
+ network::mojom::CSPDisposition should_check_content_security_policy,
OriginClean origin_clean)
: CSSValue(kFontFaceSrcClass),
absolute_resource_(absolute_resource),
@@ -91,7 +91,7 @@ class CORE_EXPORT CSSFontFaceSrcValue : public CSSValue {
bool Equals(const CSSFontFaceSrcValue&) const;
- void TraceAfterDispatch(blink::Visitor* visitor) {
+ void TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(fetched_);
CSSValue::TraceAfterDispatch(visitor);
}
@@ -104,7 +104,7 @@ class CORE_EXPORT CSSFontFaceSrcValue : public CSSValue {
String format_;
const Referrer referrer_;
const bool is_local_;
- const ContentSecurityPolicyDisposition should_check_content_security_policy_;
+ const network::mojom::CSPDisposition should_check_content_security_policy_;
const OriginClean origin_clean_;
class FontResourceHelper : public GarbageCollected<FontResourceHelper>,
@@ -117,7 +117,7 @@ class CORE_EXPORT CSSFontFaceSrcValue : public CSSValue {
SetResource(resource, task_runner);
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
FontResourceClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_font_family_value.cc b/chromium/third_party/blink/renderer/core/css/css_font_family_value.cc
index 99e4f96e486..e503a32a530 100644
--- a/chromium/third_party/blink/renderer/core/css/css_font_family_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_font_family_value.cc
@@ -29,7 +29,7 @@ String CSSFontFamilyValue::CustomCSSText() const {
return SerializeFontFamily(string_);
}
-void CSSFontFamilyValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSFontFamilyValue::TraceAfterDispatch(blink::Visitor* visitor) const {
CSSValue::TraceAfterDispatch(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_font_family_value.h b/chromium/third_party/blink/renderer/core/css/css_font_family_value.h
index 197efeb0512..0b2dfb03765 100644
--- a/chromium/third_party/blink/renderer/core/css/css_font_family_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_font_family_value.h
@@ -25,7 +25,7 @@ class CORE_EXPORT CSSFontFamilyValue : public CSSValue {
return string_ == other.string_;
}
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
friend class CSSValuePool;
diff --git a/chromium/third_party/blink/renderer/core/css/css_font_feature_value.h b/chromium/third_party/blink/renderer/core/css/css_font_feature_value.h
index aa7db9ed283..3eb15cdd55c 100644
--- a/chromium/third_party/blink/renderer/core/css/css_font_feature_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_font_feature_value.h
@@ -42,7 +42,7 @@ class CSSFontFeatureValue : public CSSValue {
bool Equals(const CSSFontFeatureValue&) const;
- 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_font_selector.cc b/chromium/third_party/blink/renderer/core/css/css_font_selector.cc
index 1859ab2c578..7708bc41cfa 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
@@ -168,7 +168,20 @@ void CSSFontSelector::ReportFailedFontFamilyMatch(
font_family_name);
}
-void CSSFontSelector::Trace(blink::Visitor* visitor) {
+void CSSFontSelector::ReportSuccessfulLocalFontMatch(
+ const AtomicString& font_name) {
+ DCHECK(document_);
+ document_->GetFontMatchingMetrics()->ReportSuccessfulLocalFontMatch(
+ font_name);
+}
+
+void CSSFontSelector::ReportFailedLocalFontMatch(
+ const AtomicString& font_name) {
+ DCHECK(document_);
+ document_->GetFontMatchingMetrics()->ReportFailedLocalFontMatch(font_name);
+}
+
+void CSSFontSelector::Trace(Visitor* visitor) {
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 cfcdacf4dae..62baf6b8639 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
@@ -55,6 +55,10 @@ class CORE_EXPORT CSSFontSelector : public FontSelector {
void ReportFailedFontFamilyMatch(
const AtomicString& font_family_name) override;
+ void ReportSuccessfulLocalFontMatch(const AtomicString& font_name) override;
+
+ void ReportFailedLocalFontMatch(const AtomicString& font_name) override;
+
scoped_refptr<FontData> GetFontData(const FontDescription&,
const AtomicString&) override;
void WillUseFontData(const FontDescription&,
@@ -74,7 +78,9 @@ class CORE_EXPORT CSSFontSelector : public FontSelector {
void RegisterForInvalidationCallbacks(FontSelectorClient*) override;
void UnregisterForInvalidationCallbacks(FontSelectorClient*) override;
- ExecutionContext* GetExecutionContext() const override { return document_; }
+ ExecutionContext* GetExecutionContext() const override {
+ return document_ ? document_->GetExecutionContext() : nullptr;
+ }
FontFaceCache* GetFontFaceCache() override { return &font_face_cache_; }
const GenericFontFamilySettings& GetGenericFontFamilySettings() const {
@@ -82,7 +88,7 @@ class CORE_EXPORT CSSFontSelector : public FontSelector {
}
void UpdateGenericFontFamilySettings(Document&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
void DispatchInvalidationCallbacks();
diff --git a/chromium/third_party/blink/renderer/core/css/css_font_style_range_value.cc b/chromium/third_party/blink/renderer/core/css/css_font_style_range_value.cc
index 17e54db1193..336ac799cad 100644
--- a/chromium/third_party/blink/renderer/core/css/css_font_style_range_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_font_style_range_value.cc
@@ -48,7 +48,7 @@ bool CSSFontStyleRangeValue::Equals(const CSSFontStyleRangeValue& other) const {
*oblique_values_ == *other.oblique_values_;
}
-void CSSFontStyleRangeValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSFontStyleRangeValue::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(font_style_value_);
visitor->Trace(oblique_values_);
CSSValue::TraceAfterDispatch(visitor);
diff --git a/chromium/third_party/blink/renderer/core/css/css_font_style_range_value.h b/chromium/third_party/blink/renderer/core/css/css_font_style_range_value.h
index 0427b30b7dc..a68c764ee6e 100644
--- a/chromium/third_party/blink/renderer/core/css/css_font_style_range_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_font_style_range_value.h
@@ -55,7 +55,7 @@ class CSSFontStyleRangeValue final : public CSSValue {
bool Equals(const CSSFontStyleRangeValue&) const;
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
Member<const CSSIdentifierValue> font_style_value_;
diff --git a/chromium/third_party/blink/renderer/core/css/css_font_variation_value.h b/chromium/third_party/blink/renderer/core/css/css_font_variation_value.h
index bce8e1dd992..5488e515b1b 100644
--- a/chromium/third_party/blink/renderer/core/css/css_font_variation_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_font_variation_value.h
@@ -22,7 +22,7 @@ class CSSFontVariationValue : public CSSValue {
bool Equals(const CSSFontVariationValue&) const;
- 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_function_value.h b/chromium/third_party/blink/renderer/core/css/css_function_value.h
index 2ecd2e5eb17..2ce074cba83 100644
--- a/chromium/third_party/blink/renderer/core/css/css_function_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_function_value.h
@@ -23,7 +23,7 @@ class CSSFunctionValue : public CSSValueList {
}
CSSValueID FunctionType() const { return value_id_; }
- void TraceAfterDispatch(blink::Visitor* visitor) {
+ void TraceAfterDispatch(blink::Visitor* visitor) const {
CSSValueList::TraceAfterDispatch(visitor);
}
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 b727d8caf33..6d2707464c7 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(blink::Visitor* visitor) {
+void CSSGlobalRuleSet::Trace(Visitor* visitor) {
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 c45dc4075ca..db894a07540 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(blink::Visitor*);
+ void Trace(Visitor*);
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 2ecac6e8760..14af20c6624 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
@@ -48,6 +48,7 @@
#include "third_party/blink/renderer/platform/graphics/gradient_generated_image.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/heap/heap.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -107,7 +108,7 @@ bool CSSGradientColorStop::IsCacheable() const {
!To<CSSNumericLiteralValue>(*offset_).IsFontRelativeLength();
}
-void CSSGradientColorStop::Trace(blink::Visitor* visitor) {
+void CSSGradientColorStop::Trace(Visitor* visitor) {
visitor->Trace(offset_);
visitor->Trace(color_);
}
@@ -341,7 +342,6 @@ void CSSGradientValue::AddComputedStops(
case CSSValueID::kWebkitLink:
case CSSValueID::kWebkitActivelink:
case CSSValueID::kWebkitFocusRingColor:
- case CSSValueID::kInternalRootColor:
break;
case CSSValueID::kCurrentcolor:
if (allow_visited_style) {
@@ -390,7 +390,8 @@ bool NormalizeAndAddStops(const Vector<GradientStop>& stops,
const float first_offset = stops.front().offset;
const float last_offset = stops.back().offset;
- const float span = last_offset - first_offset;
+ const float span =
+ std::min(last_offset - first_offset, std::numeric_limits<float>::max());
if (fabs(span) < std::numeric_limits<float>::epsilon()) {
// All stops are coincident -> use a single clamped offset value.
@@ -410,7 +411,9 @@ bool NormalizeAndAddStops(const Vector<GradientStop>& stops,
DCHECK_GT(span, 0);
for (wtf_size_t i = 0; i < stops.size(); ++i) {
- const float normalized_offset = (stops[i].offset - first_offset) / span;
+ const auto relative_offset = std::min(stops[i].offset - first_offset,
+ std::numeric_limits<float>::max()),
+ normalized_offset = relative_offset / span;
// stop offsets should be monotonically increasing in [0 , 1]
DCHECK_GE(normalized_offset, 0);
@@ -772,7 +775,7 @@ Vector<Color> CSSGradientValue::GetStopColors(
return stop_colors;
}
-void CSSGradientValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSGradientValue::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(stops_);
CSSImageGeneratorValue::TraceAfterDispatch(visitor);
}
@@ -1004,12 +1007,15 @@ scoped_refptr<Gradient> CSSLinearGradientValue::CreateGradient(
}
bool CSSLinearGradientValue::Equals(const CSSLinearGradientValue& other) const {
- if (gradient_type_ == kCSSDeprecatedLinearGradient)
- return other.gradient_type_ == gradient_type_ &&
- DataEquivalent(first_x_, other.first_x_) &&
+ if (gradient_type_ != other.gradient_type_)
+ return false;
+
+ if (gradient_type_ == kCSSDeprecatedLinearGradient) {
+ return DataEquivalent(first_x_, other.first_x_) &&
DataEquivalent(first_y_, other.first_y_) &&
DataEquivalent(second_x_, other.second_x_) &&
DataEquivalent(second_y_, other.second_y_) && stops_ == other.stops_;
+ }
if (repeating_ != other.repeating_)
return false;
@@ -1045,7 +1051,7 @@ CSSLinearGradientValue* CSSLinearGradientValue::ComputedCSSValue(
return result;
}
-void CSSLinearGradientValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSLinearGradientValue::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(first_x_);
visitor->Trace(first_y_);
visitor->Trace(second_x_);
@@ -1442,7 +1448,7 @@ CSSRadialGradientValue* CSSRadialGradientValue::ComputedCSSValue(
return result;
}
-void CSSRadialGradientValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSRadialGradientValue::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(first_x_);
visitor->Trace(first_y_);
visitor->Trace(second_x_);
@@ -1516,13 +1522,13 @@ bool CSSConicGradientValue::Equals(const CSSConicGradientValue& other) const {
CSSConicGradientValue* CSSConicGradientValue::ComputedCSSValue(
const ComputedStyle& style,
bool allow_visited_style) {
- CSSConicGradientValue* result = CSSConicGradientValue::Create(
+ auto* result = MakeGarbageCollected<CSSConicGradientValue>(
x_, y_, from_angle_, repeating_ ? kRepeating : kNonRepeating);
result->AddComputedStops(style, allow_visited_style, stops_);
return result;
}
-void CSSConicGradientValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSConicGradientValue::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(x_);
visitor->Trace(y_);
visitor->Trace(from_angle_);
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 b31412a80de..54f88df9102 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(blink::Visitor*);
+ void Trace(Visitor*);
Member<const CSSPrimitiveValue> offset_; // percentage | length | angle
Member<const CSSValue> color_;
@@ -119,7 +119,7 @@ class CSSGradientValue : public CSSImageGeneratorValue {
Vector<Color> GetStopColors(const Document&, const ComputedStyle&) const;
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
struct GradientDesc;
@@ -183,7 +183,7 @@ class CSSLinearGradientValue final : public CSSGradientValue {
CSSLinearGradientValue* ComputedCSSValue(const ComputedStyle&,
bool allow_visited_style);
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
// Any of these may be null.
@@ -196,33 +196,6 @@ class CSSLinearGradientValue final : public CSSGradientValue {
class CSSRadialGradientValue final : public CSSGradientValue {
public:
- static CSSGradientValue* Create(
- const CSSValue* first_x,
- const CSSValue* first_y,
- const CSSPrimitiveValue* first_radius,
- const CSSValue* second_x,
- const CSSValue* second_y,
- const CSSPrimitiveValue* second_radius,
- CSSGradientRepeat repeat,
- CSSGradientType gradient_type = kCSSRadialGradient) {
- return MakeGarbageCollected<CSSRadialGradientValue>(
- first_x, first_y, first_radius, second_x, second_y, second_radius,
- nullptr, nullptr, nullptr, nullptr, repeat, gradient_type);
- }
-
- static CSSGradientValue* Create(const CSSValue* center_x,
- const CSSValue* center_y,
- const CSSIdentifierValue* shape,
- const CSSIdentifierValue* sizing_behavior,
- const CSSPrimitiveValue* horizontal_size,
- const CSSPrimitiveValue* vertical_size,
- CSSGradientRepeat repeat,
- CSSGradientType gradient_type) {
- return MakeGarbageCollected<CSSRadialGradientValue>(
- center_x, center_y, nullptr, center_x, center_y, nullptr, shape,
- sizing_behavior, horizontal_size, vertical_size, repeat, gradient_type);
- }
-
CSSRadialGradientValue(const CSSValue* first_x,
const CSSValue* first_y,
const CSSPrimitiveValue* first_radius,
@@ -247,6 +220,46 @@ class CSSRadialGradientValue final : public CSSGradientValue {
end_horizontal_size_(horizontal_size),
end_vertical_size_(vertical_size) {}
+ CSSRadialGradientValue(const CSSValue* first_x,
+ const CSSValue* first_y,
+ const CSSPrimitiveValue* first_radius,
+ const CSSValue* second_x,
+ const CSSValue* second_y,
+ const CSSPrimitiveValue* second_radius,
+ CSSGradientRepeat repeat,
+ CSSGradientType gradient_type = kCSSRadialGradient)
+ : CSSGradientValue(kRadialGradientClass, repeat, gradient_type),
+ first_x_(first_x),
+ first_y_(first_y),
+ second_x_(second_x),
+ second_y_(second_y),
+ first_radius_(first_radius),
+ second_radius_(second_radius),
+ shape_(nullptr),
+ sizing_behavior_(nullptr),
+ end_horizontal_size_(nullptr),
+ end_vertical_size_(nullptr) {}
+
+ CSSRadialGradientValue(const CSSValue* center_x,
+ const CSSValue* center_y,
+ const CSSIdentifierValue* shape,
+ const CSSIdentifierValue* sizing_behavior,
+ const CSSPrimitiveValue* horizontal_size,
+ const CSSPrimitiveValue* vertical_size,
+ CSSGradientRepeat repeat,
+ CSSGradientType gradient_type)
+ : CSSGradientValue(kRadialGradientClass, repeat, gradient_type),
+ first_x_(center_x),
+ first_y_(center_y),
+ second_x_(center_x),
+ second_y_(center_y),
+ first_radius_(nullptr),
+ second_radius_(nullptr),
+ shape_(shape),
+ sizing_behavior_(sizing_behavior),
+ end_horizontal_size_(horizontal_size),
+ end_vertical_size_(vertical_size) {}
+
String CustomCSSText() const;
void SetShape(CSSIdentifierValue* val) { shape_ = val; }
@@ -268,7 +281,7 @@ class CSSRadialGradientValue final : public CSSGradientValue {
CSSRadialGradientValue* ComputedCSSValue(const ComputedStyle&,
bool allow_visited_style);
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
// Any of these may be null.
@@ -292,14 +305,6 @@ class CSSRadialGradientValue final : public CSSGradientValue {
class CSSConicGradientValue final : public CSSGradientValue {
public:
- static CSSConicGradientValue* Create(const CSSValue* x,
- const CSSValue* y,
- const CSSPrimitiveValue* from_angle,
- CSSGradientRepeat repeat) {
- return MakeGarbageCollected<CSSConicGradientValue>(x, y, from_angle,
- repeat);
- }
-
CSSConicGradientValue(const CSSValue* x,
const CSSValue* y,
const CSSPrimitiveValue* from_angle,
@@ -322,7 +327,7 @@ class CSSConicGradientValue final : public CSSGradientValue {
CSSConicGradientValue* ComputedCSSValue(const ComputedStyle&,
bool allow_visited_style);
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
// Any of these may be null.
diff --git a/chromium/third_party/blink/renderer/core/css/css_grid_auto_repeat_value.h b/chromium/third_party/blink/renderer/core/css/css_grid_auto_repeat_value.h
index 93f2f907582..44dd00b644b 100644
--- a/chromium/third_party/blink/renderer/core/css/css_grid_auto_repeat_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_grid_auto_repeat_value.h
@@ -38,7 +38,7 @@ class CSSGridAutoRepeatValue : public CSSValueList {
CSSValueID AutoRepeatID() const { return auto_repeat_id_; }
- void TraceAfterDispatch(blink::Visitor* visitor) {
+ void TraceAfterDispatch(blink::Visitor* visitor) const {
CSSValueList::TraceAfterDispatch(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_grid_integer_repeat_value.h b/chromium/third_party/blink/renderer/core/css/css_grid_integer_repeat_value.h
index 0e862020831..e7b5c8b5627 100644
--- a/chromium/third_party/blink/renderer/core/css/css_grid_integer_repeat_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_grid_integer_repeat_value.h
@@ -33,7 +33,7 @@ class CSSGridIntegerRepeatValue : public CSSValueList {
size_t Repetitions() const { return repetitions_; }
- void TraceAfterDispatch(blink::Visitor* visitor) {
+ void TraceAfterDispatch(blink::Visitor* visitor) const {
CSSValueList::TraceAfterDispatch(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_grid_line_names_value.h b/chromium/third_party/blink/renderer/core/css/css_grid_line_names_value.h
index 8fa3bfb2245..2986ed8fc33 100644
--- a/chromium/third_party/blink/renderer/core/css/css_grid_line_names_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_grid_line_names_value.h
@@ -43,7 +43,7 @@ class CSSGridLineNamesValue : public CSSValueList {
String CustomCSSText() const;
- void TraceAfterDispatch(blink::Visitor* visitor) {
+ void TraceAfterDispatch(blink::Visitor* visitor) const {
CSSValueList::TraceAfterDispatch(visitor);
}
};
diff --git a/chromium/third_party/blink/renderer/core/css/css_grid_template_areas_value.h b/chromium/third_party/blink/renderer/core/css/css_grid_template_areas_value.h
index a847793d299..69e7b35f552 100644
--- a/chromium/third_party/blink/renderer/core/css/css_grid_template_areas_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_grid_template_areas_value.h
@@ -54,7 +54,7 @@ class CSSGridTemplateAreasValue : public CSSValue {
bool Equals(const CSSGridTemplateAreasValue&) const;
- 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_grouping_rule.cc b/chromium/third_party/blink/renderer/core/css/css_grouping_rule.cc
index 89df799a8f8..34a76e9d048 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(blink::Visitor* visitor) {
+void CSSGroupingRule::Trace(Visitor* visitor) {
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 a404726ceb0..a23859069c8 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
CSSGroupingRule(StyleRuleGroup* group_rule, CSSStyleSheet* parent);
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 90096e591e2..0498875affd 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,13 +57,13 @@ CSSIdentifierValue::CSSIdentifierValue(const Length& length)
case Length::kCalculated:
case Length::kDeviceWidth:
case Length::kDeviceHeight:
- case Length::kMaxSizeNone:
+ case Length::kNone:
NOTREACHED();
break;
}
}
-void CSSIdentifierValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSIdentifierValue::TraceAfterDispatch(blink::Visitor* visitor) const {
CSSValue::TraceAfterDispatch(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_identifier_value.h b/chromium/third_party/blink/renderer/core/css/css_identifier_value.h
index 669b9a42b22..585a5ec06f1 100644
--- a/chromium/third_party/blink/renderer/core/css/css_identifier_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_identifier_value.h
@@ -59,7 +59,7 @@ class CORE_EXPORT CSSIdentifierValue : public CSSValue {
return CssValueIDToPlatformEnum<T>(value_id_);
}
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
CSSValueID value_id_;
diff --git a/chromium/third_party/blink/renderer/core/css/css_image_generator_value.h b/chromium/third_party/blink/renderer/core/css/css_image_generator_value.h
index 94180496d71..2d6f9b3fa22 100644
--- a/chromium/third_party/blink/renderer/core/css/css_image_generator_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_image_generator_value.h
@@ -108,7 +108,7 @@ class CORE_EXPORT CSSImageGeneratorValue : public CSSValue {
bool IsUsingCustomProperty(const AtomicString& custom_property_name,
const Document&) const;
- 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_image_set_value.cc b/chromium/third_party/blink/renderer/core/css/css_image_set_value.cc
index 5e1fd09a024..6a9f23a83df 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
@@ -120,7 +120,7 @@ StyleImage* CSSImageSetValue::CacheImage(
options.initiator_info.name = parser_mode_ == kUASheetMode
? fetch_initiator_type_names::kUacss
: fetch_initiator_type_names::kCSS;
- FetchParameters params(resource_request, options);
+ FetchParameters params(std::move(resource_request), options);
if (cross_origin != kCrossOriginAttributeNotSet) {
params.SetCrossOriginAccessControl(document.GetSecurityOrigin(),
@@ -174,7 +174,7 @@ bool CSSImageSetValue::HasFailedOrCanceledSubresources() const {
return true;
}
-void CSSImageSetValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSImageSetValue::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(cached_image_);
CSSValueList::TraceAfterDispatch(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_image_set_value.h b/chromium/third_party/blink/renderer/core/css/css_image_set_value.h
index de879b89b1e..846cebf49a0 100644
--- a/chromium/third_party/blink/renderer/core/css/css_image_set_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_image_set_value.h
@@ -65,7 +65,7 @@ class CSSImageSetValue : public CSSValueList {
bool HasFailedOrCanceledSubresources() const;
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
protected:
ImageWithScale BestImageForScaleFactor(float scale_factor);
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 06f072c9188..118e1179436 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
@@ -20,6 +20,7 @@
#include "third_party/blink/renderer/core/css/css_image_value.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/web/web_local_frame_client.h"
#include "third_party/blink/renderer/core/css/css_markup.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -32,6 +33,7 @@
#include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
+#include "third_party/blink/renderer/platform/network/network_state_notifier.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
@@ -40,8 +42,8 @@ namespace blink {
CSSImageValue::CSSImageValue(const AtomicString& raw_value,
const KURL& url,
const Referrer& referrer,
- StyleImage* image,
- OriginClean origin_clean)
+ OriginClean origin_clean,
+ StyleImage* image)
: CSSValue(kImageClass),
relative_url_(raw_value),
referrer_(referrer),
@@ -73,7 +75,7 @@ StyleImage* CSSImageValue::CacheImage(
options.initiator_info.name = initiator_name_.IsEmpty()
? fetch_initiator_type_names::kCSS
: initiator_name_;
- FetchParameters params(resource_request, options);
+ FetchParameters params(std::move(resource_request), options);
if (cross_origin != kCrossOriginAttributeNotSet) {
params.SetCrossOriginAccessControl(document.GetSecurityOrigin(),
@@ -92,6 +94,14 @@ StyleImage* CSSImageValue::CacheImage(
params.SetLazyImageDeferred();
}
+ if (base::FeatureList::IsEnabled(blink::features::kSubresourceRedirect) &&
+ params.Url().ProtocolIsInHTTPFamily() &&
+ GetNetworkStateNotifier().SaveDataEnabled()) {
+ auto& resource_request = params.MutableResourceRequest();
+ resource_request.SetPreviewsState(resource_request.GetPreviewsState() |
+ WebURLRequest::kSubresourceRedirectOn);
+ }
+
if (origin_clean_ != OriginClean::kTrue)
params.SetFromOriginDirtyStyleSheet(true);
@@ -140,7 +150,7 @@ bool CSSImageValue::KnownToBeOpaque(const Document& document,
: false;
}
-void CSSImageValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSImageValue::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(cached_image_);
CSSValue::TraceAfterDispatch(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_image_value.h b/chromium/third_party/blink/renderer/core/css/css_image_value.h
index b8ab4d34e76..39469eeb232 100644
--- a/chromium/third_party/blink/renderer/core/css/css_image_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_image_value.h
@@ -39,42 +39,11 @@ class ComputedStyle;
class CORE_EXPORT CSSImageValue : public CSSValue {
public:
- static CSSImageValue* Create(const KURL& url,
- OriginClean origin_clean,
- StyleImage* image = nullptr) {
- return Create(url.GetString(), url, Referrer(), origin_clean, image);
- }
- static CSSImageValue* Create(const AtomicString& relative_url,
- const KURL& absolute_url,
- OriginClean origin_clean,
- StyleImage* image = nullptr) {
- return Create(relative_url, absolute_url, Referrer(), origin_clean, image);
- }
- static CSSImageValue* Create(const String& raw_value,
- const KURL& url,
- const Referrer& referrer,
- OriginClean origin_clean,
- StyleImage* image = nullptr) {
- return Create(AtomicString(raw_value), url, referrer, origin_clean, image);
- }
- static CSSImageValue* Create(const AtomicString& raw_value,
- const KURL& url,
- const Referrer& referrer,
- OriginClean origin_clean,
- StyleImage* image = nullptr) {
- return MakeGarbageCollected<CSSImageValue>(raw_value, url, referrer, image,
- origin_clean);
- }
- static CSSImageValue* Create(const AtomicString& absolute_url,
- OriginClean origin_clean) {
- return MakeGarbageCollected<CSSImageValue>(absolute_url, origin_clean);
- }
-
CSSImageValue(const AtomicString& raw_value,
const KURL&,
const Referrer&,
- StyleImage*,
- OriginClean origin_clean);
+ OriginClean origin_clean,
+ StyleImage* image = nullptr);
CSSImageValue(const AtomicString& absolute_url, OriginClean origin_clean);
~CSSImageValue();
@@ -104,17 +73,20 @@ class CORE_EXPORT CSSImageValue : public CSSValue {
bool KnownToBeOpaque(const Document&, const ComputedStyle&) const;
CSSImageValue* ValueWithURLMadeAbsolute() const {
- return Create(KURL(absolute_url_), origin_clean_, cached_image_.Get());
+ return MakeGarbageCollected<CSSImageValue>(
+ absolute_url_, KURL(absolute_url_), Referrer(), origin_clean_,
+ cached_image_.Get());
}
CSSImageValue* Clone() const {
- return Create(relative_url_, KURL(absolute_url_), origin_clean_,
- cached_image_.Get());
+ return MakeGarbageCollected<CSSImageValue>(
+ relative_url_, KURL(absolute_url_), Referrer(), origin_clean_,
+ cached_image_.Get());
}
void SetInitiator(const AtomicString& name) { initiator_name_ = name; }
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
void RestoreCachedResourceIfNeeded(const Document&) const;
private:
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 9413dd71dbe..685275588ec 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(blink::Visitor* visitor) {
+void CSSImportRule::Trace(Visitor* visitor) {
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 495482badeb..9ea04d4d3d7 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,7 +45,7 @@ class CSSImportRule final : public CSSRule {
MediaList* media() const;
CSSStyleSheet* styleSheet() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
CSSRule::Type type() const override { return kImportRule; }
diff --git a/chromium/third_party/blink/renderer/core/css/css_inherited_value.h b/chromium/third_party/blink/renderer/core/css/css_inherited_value.h
index e9d9352259b..b249c963243 100644
--- a/chromium/third_party/blink/renderer/core/css/css_inherited_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_inherited_value.h
@@ -39,7 +39,7 @@ class CORE_EXPORT CSSInheritedValue : public CSSValue {
bool Equals(const CSSInheritedValue&) 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_initial_value.h b/chromium/third_party/blink/renderer/core/css/css_initial_value.h
index ef3e4194b42..0e2aebdbeb1 100644
--- a/chromium/third_party/blink/renderer/core/css/css_initial_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_initial_value.h
@@ -38,7 +38,7 @@ class CORE_EXPORT CSSInitialValue : public CSSValue {
bool Equals(const CSSInitialValue&) 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_invalid_variable_value.h b/chromium/third_party/blink/renderer/core/css/css_invalid_variable_value.h
index 504244f1209..eb40dcbc02e 100644
--- a/chromium/third_party/blink/renderer/core/css/css_invalid_variable_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_invalid_variable_value.h
@@ -23,7 +23,7 @@ class CORE_EXPORT CSSInvalidVariableValue : public CSSValue {
bool Equals(const CSSInvalidVariableValue&) 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_keyframe_rule.cc b/chromium/third_party/blink/renderer/core/css/css_keyframe_rule.cc
index c17bbbf3d0d..0887f7a2d14 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(blink::Visitor* visitor) {
+void CSSKeyframeRule::Trace(Visitor* visitor) {
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 70e5fcb015c..56fcc1053eb 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,7 +52,7 @@ class CSSKeyframeRule final : public CSSRule {
CSSStyleDeclaration* style() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
CSSRule::Type type() const override { return kKeyframeRule; }
diff --git a/chromium/third_party/blink/renderer/core/css/css_keyframe_shorthand_value.cc b/chromium/third_party/blink/renderer/core/css/css_keyframe_shorthand_value.cc
index 7311cb6aa55..6196eeffbcb 100644
--- a/chromium/third_party/blink/renderer/core/css/css_keyframe_shorthand_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_keyframe_shorthand_value.cc
@@ -43,7 +43,8 @@ String CSSKeyframeShorthandValue::CustomCSSText() const {
return properties_->GetPropertyValue(shorthand_);
}
-void CSSKeyframeShorthandValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSKeyframeShorthandValue::TraceAfterDispatch(
+ blink::Visitor* visitor) const {
visitor->Trace(properties_);
CSSValue::TraceAfterDispatch(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_keyframe_shorthand_value.h b/chromium/third_party/blink/renderer/core/css/css_keyframe_shorthand_value.h
index 43f849f4553..d1ea40020a2 100644
--- a/chromium/third_party/blink/renderer/core/css/css_keyframe_shorthand_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_keyframe_shorthand_value.h
@@ -45,7 +45,7 @@ class CSSKeyframeShorthandValue : public CSSValue {
return shorthand_ == other.shorthand_ && properties_ == other.properties_;
}
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
// The shorthand property that these longhands belonged to.
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 ef11909d71e..734b890df4a 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
@@ -74,7 +74,7 @@ int StyleRuleKeyframes::FindKeyframeIndex(const String& key) const {
return -1;
}
-void StyleRuleKeyframes::TraceAfterDispatch(blink::Visitor* visitor) {
+void StyleRuleKeyframes::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(keyframes_);
StyleRuleBase::TraceAfterDispatch(visitor);
}
@@ -200,7 +200,7 @@ void CSSKeyframesRule::Reattach(StyleRuleBase* rule) {
keyframes_rule_ = To<StyleRuleKeyframes>(rule);
}
-void CSSKeyframesRule::Trace(blink::Visitor* visitor) {
+void CSSKeyframesRule::Trace(Visitor* visitor) {
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 a17f15ef4a4..4313c2ea27a 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
@@ -64,7 +64,7 @@ class StyleRuleKeyframes final : public StyleRuleBase {
return MakeGarbageCollected<StyleRuleKeyframes>(*this);
}
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
void StyleChanged() { version_++; }
unsigned Version() const { return version_; }
@@ -114,7 +114,7 @@ class CSSKeyframesRule final : public CSSRule {
void StyleChanged() { keyframes_rule_->StyleChanged(); }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
CSSRule::Type type() const override { return kKeyframesRule; }
diff --git a/chromium/third_party/blink/renderer/core/css/css_layout_function_value.cc b/chromium/third_party/blink/renderer/core/css/css_layout_function_value.cc
index 4bebf888ce5..ada6eafc779 100644
--- a/chromium/third_party/blink/renderer/core/css/css_layout_function_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_layout_function_value.cc
@@ -14,8 +14,6 @@ CSSLayoutFunctionValue::CSSLayoutFunctionValue(CSSCustomIdentValue* name,
bool is_inline)
: CSSValue(kLayoutFunctionClass), name_(name), is_inline_(is_inline) {}
-CSSLayoutFunctionValue::~CSSLayoutFunctionValue() = default;
-
String CSSLayoutFunctionValue::CustomCSSText() const {
StringBuilder result;
if (is_inline_)
@@ -34,7 +32,7 @@ bool CSSLayoutFunctionValue::Equals(const CSSLayoutFunctionValue& other) const {
return GetName() == other.GetName() && IsInline() == other.IsInline();
}
-void CSSLayoutFunctionValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSLayoutFunctionValue::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(name_);
CSSValue::TraceAfterDispatch(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_layout_function_value.h b/chromium/third_party/blink/renderer/core/css/css_layout_function_value.h
index e3dc3760b7f..853110df141 100644
--- a/chromium/third_party/blink/renderer/core/css/css_layout_function_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_layout_function_value.h
@@ -19,14 +19,13 @@ namespace cssvalue {
class CSSLayoutFunctionValue : public CSSValue {
public:
CSSLayoutFunctionValue(CSSCustomIdentValue* name, bool is_inline);
- ~CSSLayoutFunctionValue();
String CustomCSSText() const;
AtomicString GetName() const;
bool IsInline() const { return is_inline_; }
bool Equals(const CSSLayoutFunctionValue&) const;
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
Member<CSSCustomIdentValue> name_;
diff --git a/chromium/third_party/blink/renderer/core/css/css_light_dark_color_pair.h b/chromium/third_party/blink/renderer/core/css/css_light_dark_color_pair.h
index 84737f5e29c..994dc1b35fa 100644
--- a/chromium/third_party/blink/renderer/core/css/css_light_dark_color_pair.h
+++ b/chromium/third_party/blink/renderer/core/css/css_light_dark_color_pair.h
@@ -14,7 +14,7 @@ class CORE_EXPORT CSSLightDarkColorPair : public CSSValuePair {
CSSLightDarkColorPair(const CSSValue* first, const CSSValue* second)
: CSSValuePair(kLightDarkColorPairClass, first, second) {}
String CustomCSSText() const;
- void TraceAfterDispatch(blink::Visitor* visitor) {
+ void TraceAfterDispatch(blink::Visitor* visitor) const {
CSSValuePair::TraceAfterDispatch(visitor);
}
};
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 4e6fa5e20e4..b274e03e1fe 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
@@ -147,7 +147,9 @@ CSSMathExpressionNumericLiteral* CSSMathExpressionNumericLiteral::Create(
CSSMathExpressionNumericLiteral::CSSMathExpressionNumericLiteral(
const CSSNumericLiteralValue* value,
bool is_integer)
- : CSSMathExpressionNode(UnitCategory(value->GetType()), is_integer),
+ : CSSMathExpressionNode(UnitCategory(value->GetType()),
+ is_integer,
+ false /* has_comparisons*/),
value_(value) {}
bool CSSMathExpressionNumericLiteral::IsZero() const {
@@ -269,7 +271,7 @@ bool CSSMathExpressionNumericLiteral::IsComputationallyIndependent() const {
return value_->IsComputationallyIndependent();
}
-void CSSMathExpressionNumericLiteral::Trace(blink::Visitor* visitor) {
+void CSSMathExpressionNumericLiteral::Trace(Visitor* visitor) {
visitor->Trace(value_);
CSSMathExpressionNode::Trace(visitor);
}
@@ -473,8 +475,10 @@ CSSMathExpressionBinaryOperation::CSSMathExpressionBinaryOperation(
const CSSMathExpressionNode* right_side,
CSSMathOperator op,
CalculationCategory category)
- : CSSMathExpressionNode(category,
- IsIntegerResult(left_side, right_side, op)),
+ : CSSMathExpressionNode(
+ category,
+ IsIntegerResult(left_side, right_side, op),
+ left_side->HasComparisons() || right_side->HasComparisons()),
left_side_(left_side),
right_side_(right_side),
operator_(op) {}
@@ -735,7 +739,7 @@ CSSPrimitiveValue::UnitType CSSMathExpressionBinaryOperation::ResolvedUnitType()
return CSSPrimitiveValue::UnitType::kUnknown;
}
-void CSSMathExpressionBinaryOperation::Trace(blink::Visitor* visitor) {
+void CSSMathExpressionBinaryOperation::Trace(Visitor* visitor) {
visitor->Trace(left_side_);
visitor->Trace(right_side_);
CSSMathExpressionNode::Trace(visitor);
@@ -816,11 +820,13 @@ CSSMathExpressionVariadicOperation::CSSMathExpressionVariadicOperation(
bool is_integer_result,
Operands&& operands,
CSSMathOperator op)
- : CSSMathExpressionNode(category, is_integer_result),
+ : CSSMathExpressionNode(category,
+ is_integer_result,
+ true /* has_comparisons */),
operands_(std::move(operands)),
operator_(op) {}
-void CSSMathExpressionVariadicOperation::Trace(blink::Visitor* visitor) {
+void CSSMathExpressionVariadicOperation::Trace(Visitor* visitor) {
visitor->Trace(operands_);
CSSMathExpressionNode::Trace(visitor);
}
@@ -926,7 +932,7 @@ CSSMathExpressionVariadicOperation::ToCalculationExpression(
const CSSToLengthConversionData& data) const {
Vector<scoped_refptr<const CalculationExpressionNode>> operands;
operands.ReserveCapacity(operands_.size());
- for (const auto operand : operands_)
+ for (const auto& operand : operands_)
operands.push_back(operand->ToCalculationExpression(data));
auto expression_type = operator_ == CSSMathOperator::kMin
? CalculationExpressionComparisonNode::Type::kMin
@@ -977,6 +983,9 @@ bool CSSMathExpressionVariadicOperation::operator==(
CSSPrimitiveValue::UnitType
CSSMathExpressionVariadicOperation::ResolvedUnitType() const {
+ if (Category() == kCalcNumber)
+ return CSSPrimitiveValue::UnitType::kNumber;
+
CSSPrimitiveValue::UnitType result = operands_.front()->ResolvedUnitType();
if (result == CSSPrimitiveValue::UnitType::kUnknown)
return CSSPrimitiveValue::UnitType::kUnknown;
@@ -1083,8 +1092,14 @@ class CSSMathExpressionNodeParser {
auto* nested = CSSMathExpressionVariadicOperation::Create(
{val_operand, max_operand}, CSSMathOperator::kMin);
+ if (!nested)
+ return nullptr;
+
auto* result = CSSMathExpressionVariadicOperation::Create(
{min_operand, nested}, CSSMathOperator::kMax);
+ if (!result)
+ return nullptr;
+
result->SetIsClamp();
return result;
}
@@ -1123,22 +1138,20 @@ class CSSMathExpressionNodeParser {
return result;
}
- if (RuntimeEnabledFeatures::CSSComparisonFunctionsEnabled()) {
- if (tokens.Peek().GetType() == kFunctionToken) {
- CSSValueID function_id = tokens.Peek().FunctionId();
- CSSParserTokenRange inner_range = tokens.ConsumeBlock();
- tokens.ConsumeWhitespace();
- inner_range.ConsumeWhitespace();
- switch (function_id) {
- case CSSValueID::kMin:
- return ParseMinOrMax(inner_range, CSSMathOperator::kMin, depth);
- case CSSValueID::kMax:
- return ParseMinOrMax(inner_range, CSSMathOperator::kMax, depth);
- case CSSValueID::kClamp:
- return ParseClamp(inner_range, depth);
- default:
- break;
- }
+ if (tokens.Peek().GetType() == kFunctionToken) {
+ CSSValueID function_id = tokens.Peek().FunctionId();
+ CSSParserTokenRange inner_range = tokens.ConsumeBlock();
+ tokens.ConsumeWhitespace();
+ inner_range.ConsumeWhitespace();
+ switch (function_id) {
+ case CSSValueID::kMin:
+ return ParseMinOrMax(inner_range, CSSMathOperator::kMin, depth);
+ case CSSValueID::kMax:
+ return ParseMinOrMax(inner_range, CSSMathOperator::kMax, depth);
+ case CSSValueID::kClamp:
+ return ParseClamp(inner_range, depth);
+ default:
+ break;
}
}
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 ce486ec1732..b1e932b61dc 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
@@ -136,6 +136,8 @@ class CORE_EXPORT CSSMathExpressionNode
bool IsNestedCalc() const { return is_nested_calc_; }
void SetIsNestedCalc() { is_nested_calc_ = true; }
+ bool HasComparisons() const { return has_comparisons_; }
+
#if DCHECK_IS_ON()
// There's a subtle issue in comparing two percentages, e.g., min(10%, 20%).
// It doesn't always resolve into 10%, because the reference value may be
@@ -144,17 +146,22 @@ class CORE_EXPORT CSSMathExpressionNode
virtual bool InvolvesPercentageComparisons() const = 0;
#endif
- virtual void Trace(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
protected:
- CSSMathExpressionNode(CalculationCategory category, bool is_integer)
- : category_(category), is_integer_(is_integer) {
+ CSSMathExpressionNode(CalculationCategory category,
+ bool is_integer,
+ bool has_comparisons)
+ : category_(category),
+ is_integer_(is_integer),
+ has_comparisons_(has_comparisons) {
DCHECK_NE(category, kCalcOther);
}
CalculationCategory category_;
bool is_integer_;
bool is_nested_calc_ = false;
+ bool has_comparisons_;
};
class CORE_EXPORT CSSMathExpressionNumericLiteral final
@@ -190,7 +197,7 @@ class CORE_EXPORT CSSMathExpressionNumericLiteral final
bool IsComputationallyIndependent() const final;
bool operator==(const CSSMathExpressionNode& other) const final;
CSSPrimitiveValue::UnitType ResolvedUnitType() const final;
- void Trace(blink::Visitor* visitor) final;
+ void Trace(Visitor* visitor) final;
#if DCHECK_IS_ON()
bool InvolvesPercentageComparisons() const final;
@@ -248,7 +255,7 @@ class CORE_EXPORT CSSMathExpressionBinaryOperation final
String CustomCSSText() const final;
bool operator==(const CSSMathExpressionNode& exp) const final;
CSSPrimitiveValue::UnitType ResolvedUnitType() const final;
- void Trace(blink::Visitor* visitor) final;
+ void Trace(Visitor* visitor) final;
#if DCHECK_IS_ON()
bool InvolvesPercentageComparisons() const final;
@@ -316,7 +323,7 @@ class CSSMathExpressionVariadicOperation final : public CSSMathExpressionNode {
bool IsComputationallyIndependent() const final;
bool operator==(const CSSMathExpressionNode& other) const final;
CSSPrimitiveValue::UnitType ResolvedUnitType() const final;
- void Trace(blink::Visitor* visitor) final;
+ void Trace(Visitor* visitor) final;
#if DCHECK_IS_ON()
bool InvolvesPercentageComparisons() const final;
diff --git a/chromium/third_party/blink/renderer/core/css/css_math_function_value.cc b/chromium/third_party/blink/renderer/core/css/css_math_function_value.cc
index 49986ea7099..7df858df8df 100644
--- a/chromium/third_party/blink/renderer/core/css/css_math_function_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_math_function_value.cc
@@ -17,7 +17,7 @@ struct SameSizeAsCSSMathFunctionValue : CSSPrimitiveValue {
};
ASSERT_SIZE(CSSMathFunctionValue, SameSizeAsCSSMathFunctionValue);
-void CSSMathFunctionValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSMathFunctionValue::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(expression_);
CSSPrimitiveValue::TraceAfterDispatch(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_math_function_value.h b/chromium/third_party/blink/renderer/core/css/css_math_function_value.h
index 73316aa2244..b098693ac2d 100644
--- a/chromium/third_party/blink/renderer/core/css/css_math_function_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_math_function_value.h
@@ -88,7 +88,9 @@ class CORE_EXPORT CSSMathFunctionValue : public CSSPrimitiveValue {
String CustomCSSText() const;
bool Equals(const CSSMathFunctionValue& other) const;
- void TraceAfterDispatch(blink::Visitor* visitor);
+ bool HasComparisons() const { return expression_->HasComparisons(); }
+
+ void TraceAfterDispatch(blink::Visitor* visitor) const;
private:
bool IsNonNegative() const { return is_non_negative_math_function_; }
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 0376f057120..5faf76aff09 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(blink::Visitor* visitor) {
+void CSSMediaRule::Trace(Visitor* visitor) {
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 ebb6fd1531e..50f9702c144 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,7 +44,7 @@ class CSSMediaRule final : public CSSConditionRule {
MediaList* media() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
CSSRule::Type type() const override { return 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 637c00aaccd..0a61e2ff288 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(blink::Visitor* visitor) {
+void CSSNamespaceRule::Trace(Visitor* visitor) {
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 7f20d9e986e..e0091f8399f 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,7 +25,7 @@ class CSSNamespaceRule final : public CSSRule {
AtomicString namespaceURI() const;
AtomicString prefix() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
CSSRule::Type type() const override { return kNamespaceRule; }
diff --git a/chromium/third_party/blink/renderer/core/css/css_numeric_literal_value.cc b/chromium/third_party/blink/renderer/core/css/css_numeric_literal_value.cc
index 368f0797ee5..41e34deda2e 100644
--- a/chromium/third_party/blink/renderer/core/css/css_numeric_literal_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_numeric_literal_value.cc
@@ -17,7 +17,7 @@ struct SameSizeAsCSSNumericLiteralValue : CSSPrimitiveValue {
};
ASSERT_SIZE(CSSNumericLiteralValue, SameSizeAsCSSNumericLiteralValue);
-void CSSNumericLiteralValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSNumericLiteralValue::TraceAfterDispatch(blink::Visitor* visitor) const {
CSSPrimitiveValue::TraceAfterDispatch(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_numeric_literal_value.h b/chromium/third_party/blink/renderer/core/css/css_numeric_literal_value.h
index 640873434aa..d07cbeaf4fc 100644
--- a/chromium/third_party/blink/renderer/core/css/css_numeric_literal_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_numeric_literal_value.h
@@ -63,7 +63,7 @@ class CORE_EXPORT CSSNumericLiteralValue : public CSSPrimitiveValue {
String CustomCSSText() const;
bool Equals(const CSSNumericLiteralValue& other) const;
- void TraceAfterDispatch(blink::Visitor* visitor);
+ void TraceAfterDispatch(blink::Visitor* visitor) const;
private:
double num_;
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 bcac8e854af..6367cb9ad82 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(blink::Visitor* visitor) {
+void CSSPageRule::Trace(Visitor* visitor) {
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 650b48c382b..036a147cbd7 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,7 +49,7 @@ class CORE_EXPORT CSSPageRule final : public CSSRule {
String selectorText() const;
void setSelectorText(const ExecutionContext*, const String&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
CSSRule::Type type() const override { return 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 9682ef70d62..98332f42628 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
@@ -6,7 +6,7 @@
#include "third_party/blink/renderer/core/css/css_rule_list.h"
#include "third_party/blink/renderer/core/css/css_test_helpers.h"
-#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/testing/null_execution_context.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -36,21 +36,22 @@ TEST(CSSPageRule, selectorText) {
auto* page_rule = To<CSSPageRule>(sheet.CssRules()->item(0));
EXPECT_EQ(":left", page_rule->selectorText());
+ auto* context = MakeGarbageCollected<NullExecutionContext>();
// set invalid page selector.
- page_rule->setSelectorText(&sheet.GetDocument(), ":hover");
+ page_rule->setSelectorText(context, ":hover");
EXPECT_EQ(":left", page_rule->selectorText());
// set invalid page selector.
- page_rule->setSelectorText(&sheet.GetDocument(), "right { bla");
+ page_rule->setSelectorText(context, "right { bla");
EXPECT_EQ(":left", page_rule->selectorText());
// set page pseudo class selector.
- page_rule->setSelectorText(&sheet.GetDocument(), ":right");
+ page_rule->setSelectorText(context, ":right");
EXPECT_EQ(":right", page_rule->selectorText());
// set page type selector.
- page_rule->setSelectorText(&sheet.GetDocument(), "namedpage");
+ page_rule->setSelectorText(context, "namedpage");
EXPECT_EQ("namedpage", 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 e3449d7b945..39e0a0839d0 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(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
};
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(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/css_paint_value.cc b/chromium/third_party/blink/renderer/core/css/css_paint_value.cc
index e2571f0dc67..0a997825dfc 100644
--- a/chromium/third_party/blink/renderer/core/css/css_paint_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_paint_value.cc
@@ -21,14 +21,19 @@
namespace blink {
-CSSPaintValue::CSSPaintValue(CSSCustomIdentValue* name)
+CSSPaintValue::CSSPaintValue(CSSCustomIdentValue* name,
+ bool threaded_compositing_enabled)
: CSSImageGeneratorValue(kPaintClass),
name_(name),
paint_image_generator_observer_(MakeGarbageCollected<Observer>(this)),
off_thread_paint_state_(
- RuntimeEnabledFeatures::OffMainThreadCSSPaintEnabled()
- ? OffThreadPaintState::kUnknown
- : OffThreadPaintState::kMainThread) {}
+ (!threaded_compositing_enabled ||
+ !RuntimeEnabledFeatures::OffMainThreadCSSPaintEnabled())
+ ? OffThreadPaintState::kMainThread
+ : OffThreadPaintState::kUnknown) {}
+
+CSSPaintValue::CSSPaintValue(CSSCustomIdentValue* name)
+ : CSSPaintValue(name, Thread::CompositorThread()) {}
CSSPaintValue::CSSPaintValue(
CSSCustomIdentValue* name,
@@ -57,34 +62,38 @@ String CSSPaintValue::GetName() const {
const Vector<CSSPropertyID>* CSSPaintValue::NativeInvalidationProperties(
const Document& document) const {
- if (!generators_.Contains(&document))
+ const CSSPaintImageGenerator* generator = generators_.at(&document);
+ if (!generator)
return nullptr;
- return &(generators_.at(&document)->NativeInvalidationProperties());
+ return &generator->NativeInvalidationProperties();
}
const Vector<AtomicString>* CSSPaintValue::CustomInvalidationProperties(
const Document& document) const {
- if (!generators_.Contains(&document))
+ const CSSPaintImageGenerator* generator = generators_.at(&document);
+ if (!generator)
return nullptr;
- return &(generators_.at(&document)->CustomInvalidationProperties());
+ return &generator->CustomInvalidationProperties();
}
bool CSSPaintValue::IsUsingCustomProperty(
const AtomicString& custom_property_name,
const Document& document) const {
- if (!generators_.Contains(&document) ||
- !generators_.at(&document)->IsImageGeneratorReady())
+ const CSSPaintImageGenerator* generator = generators_.at(&document);
+ if (!generator || !generator->IsImageGeneratorReady())
return false;
- return generators_.at(&document)->CustomInvalidationProperties().Contains(
+ return generator->CustomInvalidationProperties().Contains(
custom_property_name);
}
-void CSSPaintValue::CreateGeneratorForTesting(const Document& document) {
- if (!generators_.Contains(&document)) {
- generators_.insert(
- &document, CSSPaintImageGenerator::Create(
- GetName(), document, paint_image_generator_observer_));
+CSSPaintImageGenerator& CSSPaintValue::EnsureGenerator(
+ const Document& document) {
+ auto& generator = generators_.insert(&document, nullptr).stored_value->value;
+ if (!generator) {
+ generator = CSSPaintImageGenerator::Create(GetName(), document,
+ paint_image_generator_observer_);
}
+ return *generator;
}
scoped_refptr<Image> CSSPaintValue::GetImage(
@@ -97,16 +106,12 @@ scoped_refptr<Image> CSSPaintValue::GetImage(
if (style.InsideLink() != EInsideLink::kNotInsideLink)
return nullptr;
- if (!generators_.Contains(&document)) {
- generators_.insert(
- &document, CSSPaintImageGenerator::Create(
- GetName(), document, paint_image_generator_observer_));
- }
+ CSSPaintImageGenerator& generator = EnsureGenerator(document);
// If the generator isn't ready yet, we have nothing to paint. Our
// |paint_image_generator_observer_| will cause us to be called again once the
// generator is ready.
- if (!generators_.at(&document)->IsImageGeneratorReady())
+ if (!generator.IsImageGeneratorReady())
return nullptr;
if (!ParseInputArguments(document))
@@ -138,10 +143,10 @@ scoped_refptr<Image> CSSPaintValue::GetImage(
// ElementId, then create one for it.
layout_object.GetMutableForPainting().EnsureId();
- Vector<CSSPropertyID> native_properties =
- generators_.at(&document)->NativeInvalidationProperties();
- Vector<AtomicString> custom_properties =
- generators_.at(&document)->CustomInvalidationProperties();
+ const Vector<CSSPropertyID>& native_properties =
+ generator.NativeInvalidationProperties();
+ const Vector<AtomicString>& custom_properties =
+ generator.CustomInvalidationProperties();
float zoom = layout_object.StyleRef().EffectiveZoom();
CompositorPaintWorkletInput::PropertyKeys input_property_keys;
auto style_data = PaintWorkletStylePropertyMap::BuildCrossThreadData(
@@ -161,16 +166,15 @@ scoped_refptr<Image> CSSPaintValue::GetImage(
scoped_refptr<PaintWorkletInput> input =
base::MakeRefCounted<PaintWorkletInput>(
GetName(), target_size, zoom, device_scale_factor,
- generators_.at(&document)->WorkletId(),
- std::move(style_data.value()),
+ generator.WorkletId(), std::move(style_data.value()),
std::move(cross_thread_input_arguments),
std::move(input_property_keys));
return PaintWorkletDeferredImage::Create(std::move(input), target_size);
}
}
- return generators_.at(&document)->Paint(
- client, target_size, parsed_input_arguments_, device_scale_factor);
+ return generator.Paint(client, target_size, parsed_input_arguments_,
+ device_scale_factor);
}
void CSSPaintValue::BuildInputArgumentValues(
@@ -236,7 +240,8 @@ void CSSPaintValue::PaintImageGeneratorReady() {
bool CSSPaintValue::KnownToBeOpaque(const Document& document,
const ComputedStyle&) const {
- return generators_.at(&document) && !generators_.at(&document)->HasAlpha();
+ const CSSPaintImageGenerator* generator = generators_.at(&document);
+ return generator && !generator->HasAlpha();
}
bool CSSPaintValue::Equals(const CSSPaintValue& other) const {
@@ -244,7 +249,7 @@ bool CSSPaintValue::Equals(const CSSPaintValue& other) const {
CustomCSSText() == other.CustomCSSText();
}
-void CSSPaintValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSPaintValue::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(name_);
visitor->Trace(generators_);
visitor->Trace(paint_image_generator_observer_);
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 fcf98c8a0ed..06d1cced1e7 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
@@ -20,6 +20,7 @@ namespace blink {
class CORE_EXPORT CSSPaintValue : public CSSImageGeneratorValue {
public:
explicit CSSPaintValue(CSSCustomIdentValue* name);
+ CSSPaintValue(CSSCustomIdentValue* name, bool threaded_compositing_enabled);
CSSPaintValue(CSSCustomIdentValue* name,
Vector<scoped_refptr<CSSVariableData>>&);
~CSSPaintValue();
@@ -65,10 +66,12 @@ class CORE_EXPORT CSSPaintValue : public CSSImageGeneratorValue {
bool IsUsingCustomProperty(const AtomicString& custom_property_name,
const Document&) const;
- void CreateGeneratorForTesting(const Document& document);
+ void CreateGeneratorForTesting(const Document& document) {
+ EnsureGenerator(document);
+ }
unsigned NumberOfGeneratorsForTesting() const { return generators_.size(); }
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
class Observer final : public CSSPaintImageGenerator::Observer {
@@ -76,7 +79,7 @@ class CORE_EXPORT CSSPaintValue : public CSSImageGeneratorValue {
explicit Observer(CSSPaintValue* owner_value) : owner_value_(owner_value) {}
~Observer() override = default;
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(owner_value_);
CSSPaintImageGenerator::Observer::Trace(visitor);
}
@@ -88,6 +91,7 @@ class CORE_EXPORT CSSPaintValue : public CSSImageGeneratorValue {
DISALLOW_COPY_AND_ASSIGN(Observer);
};
+ CSSPaintImageGenerator& EnsureGenerator(const Document&);
void PaintImageGeneratorReady();
bool ParseInputArguments(const Document&);
diff --git a/chromium/third_party/blink/renderer/core/css/css_paint_value_test.cc b/chromium/third_party/blink/renderer/core/css/css_paint_value_test.cc
index 702fb41eb57..2b4fb80a730 100644
--- a/chromium/third_party/blink/renderer/core/css/css_paint_value_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_paint_value_test.cc
@@ -89,7 +89,7 @@ TEST_P(CSSPaintValueTest, ReportingCompositedUMA) {
const ComputedStyle& style = *target->Style();
auto* ident = MakeGarbageCollected<CSSCustomIdentValue>("testpainter");
- CSSPaintValue* paint_value = MakeGarbageCollected<CSSPaintValue>(ident);
+ CSSPaintValue* paint_value = MakeGarbageCollected<CSSPaintValue>(ident, true);
// Mark the generator as ready - GetImage should succeed when
// OffMainThreadCSSPaint is enabled.
ON_CALL(*mock_generator, IsImageGeneratorReady()).WillByDefault(Return(true));
@@ -135,7 +135,7 @@ TEST_P(CSSPaintValueTest, ReportingNonCompositedUMA) {
LayoutObject* target = GetLayoutObjectByElementId("target");
auto style = ComputedStyle::Create();
auto* ident = MakeGarbageCollected<CSSCustomIdentValue>("testpainter");
- CSSPaintValue* paint_value = MakeGarbageCollected<CSSPaintValue>(ident);
+ CSSPaintValue* paint_value = MakeGarbageCollected<CSSPaintValue>(ident, true);
StyleGeneratedImage* style_image =
MakeGarbageCollected<StyleGeneratedImage>(*paint_value);
style->SetBorderImageSource(style_image);
@@ -187,7 +187,7 @@ TEST_P(CSSPaintValueTest, DelayPaintUntilGeneratorReady) {
const ComputedStyle& style = *target->Style();
auto* ident = MakeGarbageCollected<CSSCustomIdentValue>("testpainter");
- CSSPaintValue* paint_value = MakeGarbageCollected<CSSPaintValue>(ident);
+ CSSPaintValue* paint_value = MakeGarbageCollected<CSSPaintValue>(ident, true);
// Initially the generator is not ready, so GetImage should fail (and no paint
// should happen).
@@ -220,7 +220,7 @@ TEST_P(CSSPaintValueTest, GetImageCalledOnMultipleDocuments) {
const ComputedStyle& style = *target->Style();
auto* ident = MakeGarbageCollected<CSSCustomIdentValue>("testpainter");
- CSSPaintValue* paint_value = MakeGarbageCollected<CSSPaintValue>(ident);
+ CSSPaintValue* paint_value = MakeGarbageCollected<CSSPaintValue>(ident, true);
EXPECT_EQ(paint_value->NumberOfGeneratorsForTesting(), 0u);
paint_value->GetImage(*target, GetDocument(), style, target_size);
@@ -238,7 +238,7 @@ TEST_P(CSSPaintValueTest, NativeInvalidationPropertiesWithNoGenerator) {
SetBodyInnerHTML(R"HTML(<div id="target"></div>)HTML");
auto* ident = MakeGarbageCollected<CSSCustomIdentValue>("testpainter");
- CSSPaintValue* paint_value = MakeGarbageCollected<CSSPaintValue>(ident);
+ CSSPaintValue* paint_value = MakeGarbageCollected<CSSPaintValue>(ident, true);
EXPECT_EQ(paint_value->NumberOfGeneratorsForTesting(), 0u);
// There is no generator, so returning a nullptr.
@@ -249,7 +249,7 @@ TEST_P(CSSPaintValueTest, CustomInvalidationPropertiesWithNoGenerator) {
SetBodyInnerHTML(R"HTML(<div id="target"></div>)HTML");
auto* ident = MakeGarbageCollected<CSSCustomIdentValue>("testpainter");
- CSSPaintValue* paint_value = MakeGarbageCollected<CSSPaintValue>(ident);
+ CSSPaintValue* paint_value = MakeGarbageCollected<CSSPaintValue>(ident, true);
EXPECT_EQ(paint_value->NumberOfGeneratorsForTesting(), 0u);
// There is no generator, so returning a nullptr.
@@ -278,7 +278,7 @@ TEST_P(CSSPaintValueTest, PrintingMustFallbackToMainThread) {
const ComputedStyle& style = *target->Style();
auto* ident = MakeGarbageCollected<CSSCustomIdentValue>("testpainter");
- CSSPaintValue* paint_value = MakeGarbageCollected<CSSPaintValue>(ident);
+ CSSPaintValue* paint_value = MakeGarbageCollected<CSSPaintValue>(ident, true);
ON_CALL(*mock_generator, IsImageGeneratorReady()).WillByDefault(Return(true));
// This PW can be composited, so we should only fall back to main once, in
@@ -319,7 +319,7 @@ TEST_P(CSSPaintValueTest, DoNotPaintForLink) {
ASSERT_NE(style.InsideLink(), EInsideLink::kNotInsideLink);
auto* ident = MakeGarbageCollected<CSSCustomIdentValue>("linkpainter");
- CSSPaintValue* paint_value = MakeGarbageCollected<CSSPaintValue>(ident);
+ CSSPaintValue* paint_value = MakeGarbageCollected<CSSPaintValue>(ident, true);
EXPECT_FALSE(paint_value->GetImage(*target, GetDocument(), style,
FloatSize(100, 100)));
}
@@ -347,14 +347,14 @@ TEST_P(CSSPaintValueTest, DoNotPaintWhenAncestorHasLink) {
ASSERT_NE(style.InsideLink(), EInsideLink::kNotInsideLink);
auto* ident = MakeGarbageCollected<CSSCustomIdentValue>("linkpainter");
- CSSPaintValue* paint_value = MakeGarbageCollected<CSSPaintValue>(ident);
+ CSSPaintValue* paint_value = MakeGarbageCollected<CSSPaintValue>(ident, true);
EXPECT_FALSE(paint_value->GetImage(*target, GetDocument(), style,
FloatSize(100, 100)));
}
TEST_P(CSSPaintValueTest, BuildInputArgumentValuesNotCrash) {
auto* ident = MakeGarbageCollected<CSSCustomIdentValue>("testpainter");
- CSSPaintValue* paint_value = MakeGarbageCollected<CSSPaintValue>(ident);
+ CSSPaintValue* paint_value = MakeGarbageCollected<CSSPaintValue>(ident, true);
ASSERT_EQ(paint_value->GetParsedInputArgumentsForTesting(), nullptr);
Vector<std::unique_ptr<CrossThreadStyleValue>> cross_thread_input_arguments;
diff --git a/chromium/third_party/blink/renderer/core/css/css_path_value.cc b/chromium/third_party/blink/renderer/core/css/css_path_value.cc
index 9e8982f54cd..3c1ae0b679d 100644
--- a/chromium/third_party/blink/renderer/core/css/css_path_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_path_value.cc
@@ -53,7 +53,7 @@ bool CSSPathValue::Equals(const CSSPathValue& other) const {
return ByteStream() == other.ByteStream();
}
-void CSSPathValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSPathValue::TraceAfterDispatch(blink::Visitor* visitor) const {
CSSValue::TraceAfterDispatch(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_path_value.h b/chromium/third_party/blink/renderer/core/css/css_path_value.h
index 6ff0f908a7a..ee3d8128071 100644
--- a/chromium/third_party/blink/renderer/core/css/css_path_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_path_value.h
@@ -33,7 +33,7 @@ class CSSPathValue : public CSSValue {
bool Equals(const CSSPathValue&) const;
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
const SVGPathByteStream& ByteStream() const {
return style_path_->ByteStream();
diff --git a/chromium/third_party/blink/renderer/core/css/css_pending_interpolation_value.cc b/chromium/third_party/blink/renderer/core/css/css_pending_interpolation_value.cc
deleted file mode 100644
index d9756e104f9..00000000000
--- a/chromium/third_party/blink/renderer/core/css/css_pending_interpolation_value.cc
+++ /dev/null
@@ -1,19 +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/css/css_pending_interpolation_value.h"
-#include "third_party/blink/renderer/core/css/css_value_pool.h"
-
-namespace blink {
-namespace cssvalue {
-
-CSSPendingInterpolationValue* CSSPendingInterpolationValue::Create(Type type) {
- return CssValuePool().PendingInterpolationValue(type);
-}
-
-CSSPendingInterpolationValue::CSSPendingInterpolationValue(Type type)
- : CSSValue(kPendingInterpolationClass), type_(type) {}
-
-} // namespace cssvalue
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/css_pending_interpolation_value.h b/chromium/third_party/blink/renderer/core/css/css_pending_interpolation_value.h
deleted file mode 100644
index cc8ee8371e6..00000000000
--- a/chromium/third_party/blink/renderer/core/css/css_pending_interpolation_value.h
+++ /dev/null
@@ -1,61 +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_CSS_CSS_PENDING_INTERPOLATION_VALUE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_PENDING_INTERPOLATION_VALUE_H_
-
-#include "third_party/blink/renderer/core/css/css_property_name.h"
-#include "third_party/blink/renderer/core/css/css_value.h"
-#include "third_party/blink/renderer/platform/wtf/casting.h"
-
-namespace blink {
-
-namespace cssvalue {
-
-// A CSSPendingInterpolationValue represents a value which we don't yet know
-// what is, but we know that it's the result of an ongoing interpolation.
-// It is a way for interpolations to participate in the cascade, without
-// knowing the exact value cascade-time.
-//
-// See StyleCascade::Animator for more information.
-class CORE_EXPORT CSSPendingInterpolationValue : public CSSValue {
- public:
- enum class Type {
- kCSSProperty,
- kPresentationAttribute,
- };
-
- static CSSPendingInterpolationValue* Create(Type);
- CSSPendingInterpolationValue(Type);
-
- bool IsCSSProperty() const { return type_ == Type::kCSSProperty; }
- bool IsPresentationAttribute() const {
- return type_ == Type::kPresentationAttribute;
- }
- bool Equals(const CSSPendingInterpolationValue& v) const {
- return type_ == v.type_;
- }
-
- String CustomCSSText() const { return ""; }
-
- void TraceAfterDispatch(blink::Visitor* visitor) {
- CSSValue::TraceAfterDispatch(visitor);
- }
-
- private:
- Type type_;
-};
-
-} // namespace cssvalue
-
-template <>
-struct DowncastTraits<cssvalue::CSSPendingInterpolationValue> {
- static bool AllowFrom(const CSSValue& value) {
- return value.IsPendingInterpolationValue();
- }
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_PENDING_INTERPOLATION_VALUE_H_
diff --git a/chromium/third_party/blink/renderer/core/css/css_pending_interpolation_value_test.cc b/chromium/third_party/blink/renderer/core/css/css_pending_interpolation_value_test.cc
deleted file mode 100644
index 649b2864377..00000000000
--- a/chromium/third_party/blink/renderer/core/css/css_pending_interpolation_value_test.cc
+++ /dev/null
@@ -1,54 +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/css/css_pending_interpolation_value.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/core/css/css_test_helpers.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-namespace {
-
-using Type = cssvalue::CSSPendingInterpolationValue::Type;
-
-cssvalue::CSSPendingInterpolationValue* Create(Type type) {
- return cssvalue::CSSPendingInterpolationValue::Create(type);
-}
-
-TEST(CSSPendingInterpolationValueTest, Create) {
- EXPECT_TRUE(Create(Type::kCSSProperty));
- EXPECT_TRUE(Create(Type::kPresentationAttribute));
-}
-
-TEST(CSSPendingInterpolationValueTest, Pool) {
- const auto* value1 = Create(Type::kCSSProperty);
- const auto* value2 = Create(Type::kCSSProperty);
- const auto* value3 = Create(Type::kPresentationAttribute);
- const auto* value4 = Create(Type::kPresentationAttribute);
- EXPECT_EQ(value1, value2);
- EXPECT_EQ(value3, value4);
- EXPECT_NE(value1, value4);
-}
-
-TEST(CSSPendingInterpolationValueTest, Equals) {
- const auto* value1 = Create(Type::kCSSProperty);
- const auto* value2 = Create(Type::kCSSProperty);
- const auto* value3 = Create(Type::kPresentationAttribute);
- const auto* value4 = Create(Type::kPresentationAttribute);
- EXPECT_TRUE(value1->Equals(*value2));
- EXPECT_TRUE(value2->Equals(*value1));
- EXPECT_TRUE(value3->Equals(*value4));
- EXPECT_TRUE(value4->Equals(*value3));
- EXPECT_FALSE(value1->Equals(*value4));
- EXPECT_FALSE(value4->Equals(*value1));
-}
-
-TEST(CSSPendingInterpolationValueTest, CustomCSSText) {
- EXPECT_EQ("", Create(Type::kCSSProperty)->CustomCSSText());
- EXPECT_EQ("", Create(Type::kPresentationAttribute)->CustomCSSText());
-}
-
-} // namespace
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/css_pending_substitution_value.cc b/chromium/third_party/blink/renderer/core/css/css_pending_substitution_value.cc
index c2a141e970c..40bf775cf6a 100644
--- a/chromium/third_party/blink/renderer/core/css/css_pending_substitution_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_pending_substitution_value.cc
@@ -7,7 +7,8 @@
namespace blink {
namespace cssvalue {
-void CSSPendingSubstitutionValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSPendingSubstitutionValue::TraceAfterDispatch(
+ blink::Visitor* visitor) const {
CSSValue::TraceAfterDispatch(visitor);
visitor->Trace(shorthand_value_);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_pending_substitution_value.h b/chromium/third_party/blink/renderer/core/css/css_pending_substitution_value.h
index 70b27184c0c..7af6162f99a 100644
--- a/chromium/third_party/blink/renderer/core/css/css_pending_substitution_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_pending_substitution_value.h
@@ -15,13 +15,6 @@ namespace cssvalue {
class CSSPendingSubstitutionValue : public CSSValue {
public:
- static CSSPendingSubstitutionValue* Create(
- CSSPropertyID shorthand_property_id,
- CSSVariableReferenceValue* shorthand_value) {
- return MakeGarbageCollected<CSSPendingSubstitutionValue>(
- shorthand_property_id, shorthand_value);
- }
-
CSSPendingSubstitutionValue(CSSPropertyID shorthand_property_id,
CSSVariableReferenceValue* shorthand_value)
: CSSValue(kPendingSubstitutionValueClass),
@@ -39,7 +32,7 @@ class CSSPendingSubstitutionValue : public CSSValue {
}
String CustomCSSText() const;
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
CSSPropertyID shorthand_property_id_;
diff --git a/chromium/third_party/blink/renderer/core/css/css_primitive_value.cc b/chromium/third_party/blink/renderer/core/css/css_primitive_value.cc
index 62f98677db1..0c6378150cd 100644
--- a/chromium/third_party/blink/renderer/core/css/css_primitive_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_primitive_value.cc
@@ -553,7 +553,7 @@ String CSSPrimitiveValue::CustomCSSText() const {
return To<CSSNumericLiteralValue>(this)->CustomCSSText();
}
-void CSSPrimitiveValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSPrimitiveValue::TraceAfterDispatch(blink::Visitor* visitor) const {
CSSValue::TraceAfterDispatch(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_primitive_value.h b/chromium/third_party/blink/renderer/core/css/css_primitive_value.h
index b1eb925177d..2cfe667e733 100644
--- a/chromium/third_party/blink/renderer/core/css/css_primitive_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_primitive_value.h
@@ -248,7 +248,7 @@ class CORE_EXPORT CSSPrimitiveValue : public CSSValue {
String CustomCSSText() const;
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
static UnitType CanonicalUnitTypeForCategory(UnitCategory);
static double ConversionToCanonicalUnitsScaleFactor(UnitType);
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 e49b90bfff3..21bba087219 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
@@ -226,6 +226,9 @@ inline CSSIdentifierValue::CSSIdentifierValue(ControlPart e)
case kNoControlPart:
value_id_ = CSSValueID::kNone;
break;
+ case kAutoPart:
+ value_id_ = CSSValueID::kAuto;
+ break;
case kCheckboxPart:
value_id_ = CSSValueID::kCheckbox;
break;
@@ -305,8 +308,10 @@ template <>
inline ControlPart CSSIdentifierValue::ConvertTo() const {
if (value_id_ == CSSValueID::kNone)
return kNoControlPart;
+ if (value_id_ == CSSValueID::kAuto)
+ return kAutoPart;
return ControlPart(static_cast<int>(value_id_) -
- static_cast<int>(CSSValueID::kCheckbox) + 1);
+ static_cast<int>(CSSValueID::kCheckbox) + kCheckboxPart);
}
template <>
@@ -1425,31 +1430,31 @@ template <>
inline TouchAction CSSIdentifierValue::ConvertTo() const {
switch (value_id_) {
case CSSValueID::kNone:
- return TouchAction::kTouchActionNone;
+ return TouchAction::kNone;
case CSSValueID::kAuto:
- return TouchAction::kTouchActionAuto;
+ return TouchAction::kAuto;
case CSSValueID::kPanLeft:
- return TouchAction::kTouchActionPanLeft;
+ return TouchAction::kPanLeft;
case CSSValueID::kPanRight:
- return TouchAction::kTouchActionPanRight;
+ return TouchAction::kPanRight;
case CSSValueID::kPanX:
- return TouchAction::kTouchActionPanX;
+ return TouchAction::kPanX;
case CSSValueID::kPanUp:
- return TouchAction::kTouchActionPanUp;
+ return TouchAction::kPanUp;
case CSSValueID::kPanDown:
- return TouchAction::kTouchActionPanDown;
+ return TouchAction::kPanDown;
case CSSValueID::kPanY:
- return TouchAction::kTouchActionPanY;
+ return TouchAction::kPanY;
case CSSValueID::kManipulation:
- return TouchAction::kTouchActionManipulation;
+ return TouchAction::kManipulation;
case CSSValueID::kPinchZoom:
- return TouchAction::kTouchActionPinchZoom;
+ return TouchAction::kPinchZoom;
default:
break;
}
NOTREACHED();
- return TouchAction::kTouchActionNone;
+ return TouchAction::kNone;
}
template <>
@@ -1756,16 +1761,17 @@ inline OverflowAlignment CSSIdentifierValue::ConvertTo() const {
}
template <>
-inline CSSIdentifierValue::CSSIdentifierValue(ScrollBehavior behavior)
+inline CSSIdentifierValue::CSSIdentifierValue(
+ mojom::blink::ScrollBehavior behavior)
: CSSValue(kIdentifierClass) {
switch (behavior) {
- case kScrollBehaviorAuto:
+ case mojom::blink::ScrollBehavior::kAuto:
value_id_ = CSSValueID::kAuto;
break;
- case kScrollBehaviorSmooth:
+ case mojom::blink::ScrollBehavior::kSmooth:
value_id_ = CSSValueID::kSmooth;
break;
- case kScrollBehaviorInstant:
+ case mojom::blink::ScrollBehavior::kInstant:
// Behavior 'instant' is only allowed in ScrollOptions arguments passed to
// CSSOM scroll APIs.
NOTREACHED();
@@ -1773,17 +1779,17 @@ inline CSSIdentifierValue::CSSIdentifierValue(ScrollBehavior behavior)
}
template <>
-inline ScrollBehavior CSSIdentifierValue::ConvertTo() const {
+inline mojom::blink::ScrollBehavior CSSIdentifierValue::ConvertTo() const {
switch (GetValueID()) {
case CSSValueID::kAuto:
- return kScrollBehaviorAuto;
+ return mojom::blink::ScrollBehavior::kAuto;
case CSSValueID::kSmooth:
- return kScrollBehaviorSmooth;
+ return mojom::blink::ScrollBehavior::kSmooth;
default:
break;
}
NOTREACHED();
- return kScrollBehaviorAuto;
+ return mojom::blink::ScrollBehavior::kAuto;
}
template <>
@@ -1951,6 +1957,9 @@ inline CSSIdentifierValue::CSSIdentifierValue(TextUnderlinePosition position)
case kTextUnderlinePositionAuto:
value_id_ = CSSValueID::kAuto;
break;
+ case kTextUnderlinePositionFromFont:
+ value_id_ = CSSValueID::kFromFont;
+ break;
case kTextUnderlinePositionUnder:
value_id_ = CSSValueID::kUnder;
break;
@@ -1968,6 +1977,8 @@ inline TextUnderlinePosition CSSIdentifierValue::ConvertTo() const {
switch (GetValueID()) {
case CSSValueID::kAuto:
return kTextUnderlinePositionAuto;
+ case CSSValueID::kFromFont:
+ return kTextUnderlinePositionFromFont;
case CSSValueID::kUnder:
return kTextUnderlinePositionUnder;
case CSSValueID::kLeft:
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 277d775e0c2..6ec7f584d08 100644
--- a/chromium/third_party/blink/renderer/core/css/css_properties.json5
+++ b/chromium/third_party/blink/renderer/core/css/css_properties.json5
@@ -354,12 +354,32 @@
physical_group: {
valid_type: "str",
valid_values: ["border", "border-color", "border-style", "border-width",
- "inset", "intrinsic-size", "margin", "max-size",
+ "inset", "margin", "max-size",
"min-size", "overflow", "padding", "scroll-margin",
"scroll-padding", "size", "visited-border-color"],
}
},
+ // - surrogate_for: "other-property"
+ //
+ // A surrogate is a property which acts like another property. Unlike an
+ // alias (which is resolved as parse-time), a surrogate exists alongside
+ // the original in the parsed rule, and in the cascade.
+ //
+ // However, surrogates modify the same fields on ComputedStyle. Examples of
+ // surrogates are:
+ //
+ // * -webkit-writing-mode (surrogate of writing-mode)
+ // * inline-size (surrogate for width, or height)
+ // * All css-logical propeties in general
+ //
+ // Note that for properties that use direction_aware_options,
+ // 'surrogate_for' should not be set, as the mapping is determined at
+ // run-time (depending og e.g. 'direction').
+ surrogate_for: {
+ valid_type: "str",
+ },
+
// - priority: "High"
// The priority level for computing the property. Valid values are
// "Animation" (highest), "High" and "Low". Properties with the same
@@ -404,6 +424,30 @@
default: false,
valid_type: "bool",
},
+
+ // - valid_for_first_letter: true
+ //
+ // https://drafts.csswg.org/css-pseudo-4/#first-letter-styling
+ valid_for_first_letter: {
+ default: false,
+ valid_type: "bool",
+ },
+
+ // - valid_for_cue: true
+ //
+ // https://w3c.github.io/webvtt/#the-cue-pseudo-element
+ valid_for_cue: {
+ default: false,
+ valid_type: "bool",
+ },
+
+ // - valid_for_marker: true
+ //
+ // https://drafts.csswg.org/css-pseudo-4/#marker-pseudo
+ valid_for_marker: {
+ default: false,
+ valid_type: "bool",
+ },
},
// Members in the data objects should appear in the same order as in the
@@ -422,6 +466,7 @@
priority: "Animation",
typedom_types: ["Time"],
separator: ",",
+ valid_for_marker: true,
},
{
name: "animation-direction",
@@ -435,6 +480,7 @@
},
priority: "Animation",
separator: ",",
+ valid_for_marker: true,
},
{
name: "animation-duration",
@@ -447,6 +493,7 @@
priority: "Animation",
typedom_types: ["Time"],
separator: ",",
+ valid_for_marker: true,
},
{
name: "animation-fill-mode",
@@ -459,6 +506,7 @@
keywords: ["none", "forwards", "backwards", "both"],
typedom_types: ["Keyword"],
separator: ",",
+ valid_for_marker: true,
},
{
name: "animation-iteration-count",
@@ -473,6 +521,7 @@
keywords: ["infinite"],
typedom_types: ["Keyword", "Number"],
separator: ",",
+ valid_for_marker: true,
},
{
name: "animation-name",
@@ -484,7 +533,8 @@
priority: "Animation",
keywords: ["none"],
typedom_types: ["Keyword"],
- separator: ","
+ separator: ",",
+ valid_for_marker: true,
},
{
name: "animation-play-state",
@@ -497,6 +547,7 @@
keywords: ["running", "paused"],
typedom_types: ["Keyword"],
separator: ",",
+ valid_for_marker: true,
},
{
name: "animation-timing-function",
@@ -521,6 +572,7 @@
],
typedom_types: ["Keyword"],
separator: ",",
+ valid_for_marker: true,
},
{
name: "transition-delay",
@@ -532,6 +584,7 @@
priority: "Animation",
typedom_types: ["Time"],
separator: ",",
+ valid_for_marker: true,
},
{
name: "transition-duration",
@@ -543,6 +596,7 @@
attribute: "Duration",
},
priority: "Animation",
+ valid_for_marker: true,
},
{
name: "transition-property",
@@ -553,7 +607,8 @@
},
priority: "Animation",
keywords: ["none"],
- typedom_types: ["Keyword"]
+ typedom_types: ["Keyword"],
+ valid_for_marker: true,
},
{
name: "transition-timing-function",
@@ -577,6 +632,7 @@
"step-end"],
typedom_types: ["Keyword"],
separator: ",",
+ valid_for_marker: true,
},
// High Priority and all other font properties.
@@ -598,6 +654,9 @@
keywords: ["currentcolor"],
typedom_types: ["Keyword"],
affected_by_forced_colors: true,
+ valid_for_first_letter: true,
+ valid_for_cue: true,
+ valid_for_marker: true,
},
{
name: "direction",
@@ -612,6 +671,7 @@
type_name: "TextDirection",
style_builder_custom_functions: ["value"],
priority: "High",
+ valid_for_marker: true,
},
{
name: "font-family",
@@ -623,6 +683,9 @@
type_name: "FontDescription::FamilyDescription",
converter: "ConvertFontFamily",
priority: "High",
+ valid_for_first_letter: true,
+ valid_for_cue: true,
+ valid_for_marker: true,
},
{
name: "font-kerning",
@@ -634,6 +697,8 @@
priority: "High",
keywords: ["auto", "normal", "none"],
typedom_types: ["Keyword"],
+ valid_for_first_letter: true,
+ valid_for_marker: true,
},
{
name: "font-optical-sizing",
@@ -644,7 +709,9 @@
type_name: "OpticalSizing",
priority: "High",
keywords: ["auto", "none"],
- typedom_types: ["Keyword"]
+ typedom_types: ["Keyword"],
+ valid_for_first_letter: true,
+ valid_for_marker: true,
},
{
name: "font-size",
@@ -657,7 +724,10 @@
converter: "ConvertFontSize",
priority: "High",
keywords: ["xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "xxx-large", "larger", "smaller", "-webkit-xxx-large"],
- typedom_types: ["Keyword", "Length", "Percentage"]
+ typedom_types: ["Keyword", "Length", "Percentage"],
+ valid_for_first_letter: true,
+ valid_for_cue: true,
+ valid_for_marker: true,
},
{
name: "font-size-adjust",
@@ -670,7 +740,9 @@
converter: "ConvertFontSizeAdjust",
priority: "High",
keywords: ["none"],
- typedom_types: ["Keyword", "Number"]
+ typedom_types: ["Keyword", "Number"],
+ valid_for_first_letter: true,
+ valid_for_marker: true,
},
{
name: "font-stretch",
@@ -685,7 +757,10 @@
"normal", "ultra-condensed", "extra-condensed", "condensed",
"semi-condensed", "semi-expanded", "expanded", "extra-expanded", "ultra-expanded"
],
- typedom_types: ["Keyword", "Percentage"]
+ typedom_types: ["Keyword", "Percentage"],
+ valid_for_first_letter: true,
+ valid_for_cue: true,
+ valid_for_marker: true,
},
{
name: "font-style",
@@ -698,6 +773,9 @@
priority: "High",
keywords: ["normal", "italic", "oblique"],
typedom_types: ["Keyword"],
+ valid_for_first_letter: true,
+ valid_for_cue: true,
+ valid_for_marker: true,
},
{
name: "font-variant-ligatures",
@@ -715,6 +793,8 @@
"no-contextual"
],
typedom_types: ["Keyword"],
+ valid_for_first_letter: true,
+ valid_for_marker: true,
},
{
name: "font-variant-caps",
@@ -729,6 +809,8 @@
"all-petite-caps", "unicase", "titling-caps"
],
typedom_types: ["Keyword"],
+ valid_for_first_letter: true,
+ valid_for_marker: true,
},
{
name: "font-variant-east-asian",
@@ -743,6 +825,8 @@
"traditional", "full-width", "proportional-width", "ruby"
],
typedom_types: ["Keyword"],
+ valid_for_first_letter: true,
+ valid_for_marker: true,
},
{
name: "font-variant-numeric",
@@ -758,6 +842,8 @@
"slashed-zero"
],
typedom_types: ["Keyword"],
+ valid_for_first_letter: true,
+ valid_for_marker: true,
},
{
name: "font-weight",
@@ -770,7 +856,10 @@
converter: "ConvertFontWeight",
priority: "High",
keywords: ["normal", "bold", "bolder", "lighter"],
- typedom_types: ["Keyword", "Number"]
+ typedom_types: ["Keyword", "Number"],
+ valid_for_first_letter: true,
+ valid_for_cue: true,
+ valid_for_marker: true,
},
{
name: "font-feature-settings",
@@ -783,6 +872,8 @@
priority: "High",
keywords: ["normal"],
typedom_types: ["Keyword"],
+ valid_for_first_letter: true,
+ valid_for_marker: true,
},
{
name: "font-variation-settings",
@@ -794,7 +885,10 @@
converter: "ConvertFontVariationSettings",
priority: "High",
keywords: ["normal"],
- typedom_types: ["Keyword"]
+ typedom_types: ["Keyword"],
+ valid_for_first_letter: true,
+ valid_for_cue: true,
+ valid_for_marker: true,
},
{
name: "-webkit-font-smoothing",
@@ -803,6 +897,7 @@
font: true,
type_name: "FontSmoothingMode",
priority: "High",
+ valid_for_first_letter: true,
},
{
name: "forced-color-adjust",
@@ -864,6 +959,7 @@
type_name: "WritingMode",
style_builder_custom_functions: ["value"],
priority: "High",
+ surrogate_for: "writing-mode",
},
{
name: "text-rendering",
@@ -924,6 +1020,19 @@
converter: "ConvertSelfOrDefaultAlignmentData",
},
{
+ name: "aspect-ratio",
+ property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+ interpolable: false,
+ field_group: "box",
+ field_template: "external",
+ keywords: ["auto"],
+ default_value: "base::nullopt",
+ type_name: "base::Optional<IntSize>",
+ converter: "ConvertAspectRatio",
+ include_paths: ["third_party/blink/renderer/platform/geometry/length_size.h"],
+ runtime_flag: "CSSAspectRatioProperty"
+ },
+ {
name: "backdrop-filter",
property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
interpolable: true,
@@ -958,6 +1067,8 @@
style_builder_template_args: {
fill_type: "Attachment",
},
+ valid_for_first_letter: true,
+ valid_for_cue: true,
},
{
name: "background-blend-mode",
@@ -974,6 +1085,7 @@
fill_type: "BlendMode",
fill_type_getter: "GetBlendMode",
},
+ valid_for_first_letter: true,
},
{
name: "background-clip",
@@ -985,6 +1097,8 @@
style_builder_template_args: {
fill_type: "Clip",
},
+ valid_for_first_letter: true,
+ valid_for_cue: true,
},
{
name: "background-color",
@@ -1004,6 +1118,8 @@
initial_color: "ComputedStyleInitialValues::InitialBackgroundColor",
},
affected_by_forced_colors: true,
+ valid_for_first_letter: true,
+ valid_for_cue: true,
},
{
name: "background-image",
@@ -1017,6 +1133,8 @@
fill_type: "Image",
fill_type_getter: "GetImage",
},
+ valid_for_first_letter: true,
+ valid_for_cue: true,
},
{
name: "background-origin",
@@ -1028,6 +1146,8 @@
style_builder_template_args: {
fill_type: "Origin",
},
+ valid_for_first_letter: true,
+ valid_for_cue: true,
},
{
name: "background-position-x",
@@ -1037,6 +1157,8 @@
style_builder_template_args: {
fill_type: "PositionX",
},
+ valid_for_first_letter: true,
+ valid_for_cue: true,
},
{
name: "background-position-y",
@@ -1046,6 +1168,8 @@
style_builder_template_args: {
fill_type: "PositionY",
},
+ valid_for_first_letter: true,
+ valid_for_cue: true,
},
{
name: "background-repeat-x",
@@ -1053,6 +1177,8 @@
style_builder_template_args: {
fill_type: "RepeatX",
},
+ valid_for_first_letter: true,
+ valid_for_cue: true,
},
{
name: "background-repeat-y",
@@ -1060,6 +1186,8 @@
style_builder_template_args: {
fill_type: "RepeatY",
},
+ valid_for_first_letter: true,
+ valid_for_cue: true,
},
{
name: "background-size",
@@ -1072,6 +1200,8 @@
style_builder_template_args: {
fill_type: "Size",
},
+ valid_for_first_letter: true,
+ valid_for_cue: true,
},
{
name: "baseline-shift",
@@ -1097,6 +1227,7 @@
converter: "ConvertStyleColor",
style_builder_template: "color",
affected_by_forced_colors: true,
+ valid_for_first_letter: true,
},
{
name: "border-bottom-left-radius",
@@ -1109,6 +1240,7 @@
type_name: "LengthSize",
converter: "ConvertRadius",
typedom_types: ["Length", "Percentage"],
+ valid_for_first_letter: true,
},
{
name: "border-bottom-right-radius",
@@ -1121,6 +1253,7 @@
type_name: "LengthSize",
converter: "ConvertRadius",
typedom_types: ["Length", "Percentage"],
+ valid_for_first_letter: true,
},
{
name: "border-bottom-style",
@@ -1134,6 +1267,7 @@
typedom_types: ["Keyword"],
default_value: "none",
type_name: "EBorderStyle",
+ valid_for_first_letter: true,
},
{
name: "border-bottom-width",
@@ -1148,6 +1282,7 @@
type_name: "LayoutUnit",
computed_style_custom_functions: ["getter", "setter"],
converter: "ConvertBorderWidth",
+ valid_for_first_letter: true,
},
{
name: "border-collapse",
@@ -1168,6 +1303,7 @@
style_builder_template_args: {
modifier_type: "Outset",
},
+ valid_for_first_letter: true,
},
{
name: "border-image-repeat",
@@ -1178,6 +1314,7 @@
style_builder_template_args: {
modifier_type: "Repeat",
},
+ valid_for_first_letter: true,
},
{
name: "border-image-slice",
@@ -1188,6 +1325,7 @@
style_builder_template_args: {
modifier_type: "Slice",
},
+ valid_for_first_letter: true,
},
{
name: "border-image-source",
@@ -1196,6 +1334,7 @@
keywords: ["none"],
typedom_types: ["Keyword", "Image"],
style_builder_custom_functions: ["value"],
+ valid_for_first_letter: true,
},
{
name: "border-image-width",
@@ -1207,6 +1346,7 @@
style_builder_template_args: {
modifier_type: "Width",
},
+ valid_for_first_letter: true,
},
{
name: "border-left-color",
@@ -1223,6 +1363,7 @@
converter: "ConvertStyleColor",
style_builder_template: "color",
affected_by_forced_colors: true,
+ valid_for_first_letter: true,
},
{
name: "border-left-style",
@@ -1236,6 +1377,7 @@
typedom_types: ["Keyword"],
default_value: "none",
type_name: "EBorderStyle",
+ valid_for_first_letter: true,
},
{
name: "border-left-width",
@@ -1250,6 +1392,7 @@
type_name: "LayoutUnit",
computed_style_custom_functions: ["getter", "setter"],
converter: "ConvertBorderWidth",
+ valid_for_first_letter: true,
},
{
name: "border-right-color",
@@ -1266,6 +1409,7 @@
converter: "ConvertStyleColor",
style_builder_template: "color",
affected_by_forced_colors: true,
+ valid_for_first_letter: true,
},
{
name: "border-right-style",
@@ -1279,6 +1423,7 @@
typedom_types: ["Keyword"],
default_value: "none",
type_name: "EBorderStyle",
+ valid_for_first_letter: true,
},
{
name: "border-right-width",
@@ -1293,6 +1438,7 @@
type_name: "LayoutUnit",
computed_style_custom_functions: ["getter", "setter"],
converter: "ConvertBorderWidth",
+ valid_for_first_letter: true,
},
{
name: "border-top-color",
@@ -1309,6 +1455,7 @@
converter: "ConvertStyleColor",
style_builder_template: "color",
affected_by_forced_colors: true,
+ valid_for_first_letter: true,
},
{
name: "border-top-left-radius",
@@ -1321,6 +1468,7 @@
type_name: "LengthSize",
converter: "ConvertRadius",
typedom_types: ["Length", "Percentage"],
+ valid_for_first_letter: true,
},
{
name: "border-top-right-radius",
@@ -1333,6 +1481,7 @@
type_name: "LengthSize",
converter: "ConvertRadius",
typedom_types: ["Length", "Percentage"],
+ valid_for_first_letter: true,
},
{
name: "border-top-style",
@@ -1346,6 +1495,7 @@
typedom_types: ["Keyword"],
default_value: "none",
type_name: "EBorderStyle",
+ valid_for_first_letter: true,
},
{
name: "border-top-width",
@@ -1360,6 +1510,7 @@
type_name: "LayoutUnit",
computed_style_custom_functions: ["getter", "setter"],
converter: "ConvertBorderWidth",
+ valid_for_first_letter: true,
},
{
name: "bottom",
@@ -1387,6 +1538,7 @@
keywords: ["none"],
typedom_types: ["Keyword"],
affected_by_forced_colors: true,
+ valid_for_first_letter: true,
},
{
name: "box-sizing",
@@ -1572,6 +1724,19 @@
typedom_types: ["Keyword"],
},
{
+ name: "contain-intrinsic-size",
+ property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+ interpolable: true,
+ field_group: "box",
+ field_template: "external",
+ keywords: ["auto"],
+ default_value: "LengthSize(Length::Auto(), Length::Auto())",
+ type_name: "LengthSize",
+ converter: "ConvertIntrinsicSize",
+ include_paths: ["third_party/blink/renderer/platform/geometry/length_size.h"],
+ runtime_flag: "CSSIntrinsicSize"
+ },
+ {
name: "content",
property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
field_group: "*",
@@ -1583,6 +1748,7 @@
type_name: "ContentData",
computed_style_custom_functions: ["getter", "setter"],
style_builder_custom_functions: ["initial", "inherit", "value"],
+ valid_for_marker: true,
},
{
name: "counter-increment",
@@ -1783,6 +1949,7 @@
default_value: "none",
name_for_methods: "Floating",
type_name: "EFloat",
+ valid_for_first_letter: true,
},
{
name: "flood-color",
@@ -1975,56 +2142,12 @@
runtime_flag: "ImageOrientation",
field_group: "*",
field_template: "primitive",
- default_value: "false",
+ default_value: "true",
name_for_methods: "RespectImageOrientation",
type_name: "bool",
converter: "ConvertImageOrientation",
},
{
- name: "intrinsic-block-size",
- property_methods: ["ParseSingleValue"],
- direction_aware_options: {
- resolver: "block",
- physical_group: "intrinsic-size"
- },
- runtime_flag: "CSSIntrinsicSize"
- },
- {
- name: "intrinsic-height",
- property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
- interpolable: true,
- field_group: "box",
- field_template: "external",
- keywords: ["auto", "legacy"],
- default_value: "IntrinsicLength()",
- type_name: "IntrinsicLength",
- converter: "ConvertIntrinsicLength",
- include_paths: ["third_party/blink/renderer/core/style/intrinsic_length.h"],
- runtime_flag: "CSSIntrinsicSize"
- },
- {
- name: "intrinsic-inline-size",
- property_methods: ["ParseSingleValue"],
- direction_aware_options: {
- resolver: "inline",
- physical_group: "intrinsic-size"
- },
- runtime_flag: "CSSIntrinsicSize"
- },
- {
- name: "intrinsic-width",
- property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
- interpolable: true,
- field_group: "box",
- field_template: "external",
- keywords: ["auto", "legacy"],
- default_value: "IntrinsicLength()",
- type_name: "IntrinsicLength",
- converter: "ConvertIntrinsicLength",
- include_paths: ["third_party/blink/renderer/core/style/intrinsic_length.h"],
- runtime_flag: "CSSIntrinsicSize"
- },
- {
name: "isolation",
property_methods: ["CSSValueFromComputedStyleInternal"],
field_group: "*",
@@ -2082,7 +2205,8 @@
inherited: true,
converter: "ConvertSpacing",
keywords: ["normal"],
- typedom_types: ["Keyword", "Length"]
+ typedom_types: ["Keyword", "Length"],
+ valid_for_first_letter: true,
},
{
name: "lighting-color",
@@ -2105,7 +2229,9 @@
computed_style_custom_functions: ["getter"],
converter: "ConvertLineHeight",
keywords: ["normal"],
- typedom_types: ["Keyword", "Length", "Number", "Percentage"]
+ typedom_types: ["Keyword", "Length", "Number", "Percentage"],
+ valid_for_first_letter: true,
+ valid_for_cue: true,
},
{
name: "line-height-step",
@@ -2177,7 +2303,8 @@
converter: "ConvertQuirkyLength",
computed_style_custom_functions: ["setter"],
keywords: ["auto"],
- typedom_types: ["Keyword", "Length", "Percentage"]
+ typedom_types: ["Keyword", "Length", "Percentage"],
+ valid_for_first_letter: true,
},
{
name: "margin-left",
@@ -2190,7 +2317,8 @@
converter: "ConvertQuirkyLength",
computed_style_custom_functions: ["setter"],
keywords: ["auto"],
- typedom_types: ["Keyword", "Length", "Percentage"]
+ typedom_types: ["Keyword", "Length", "Percentage"],
+ valid_for_first_letter: true,
},
{
name: "margin-right",
@@ -2203,7 +2331,8 @@
converter: "ConvertQuirkyLength",
computed_style_custom_functions: ["setter"],
keywords: ["auto"],
- typedom_types: ["Keyword", "Length", "Percentage"]
+ typedom_types: ["Keyword", "Length", "Percentage"],
+ valid_for_first_letter: true,
},
{
name: "margin-top",
@@ -2216,7 +2345,8 @@
converter: "ConvertQuirkyLength",
computed_style_custom_functions: ["setter"],
keywords: ["auto"],
- typedom_types: ["Keyword", "Length", "Percentage"]
+ typedom_types: ["Keyword", "Length", "Percentage"],
+ valid_for_first_letter: true,
},
{
name: "marker-end",
@@ -2271,6 +2401,17 @@
keywords: ["luminance", "alpha"],
typedom_types: ["Keyword"]
},
+ // TODO(rbuis): should be moved to high priority later.
+ {
+ name: "math-style",
+ property_methods: ["CSSValueFromComputedStyleInternal"],
+ field_template: "keyword",
+ inherited: true,
+ keywords: ["inline", "display"],
+ typedom_types: ["Keyword"],
+ default_value: "inline",
+ runtime_flag: "CSSMathStyle"
+ },
{
name: "max-height",
property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
@@ -2278,7 +2419,7 @@
interpolable: true,
field_group: "box",
field_template: "<length>",
- default_value: "Length::MaxSizeNone()",
+ default_value: "Length::None()",
converter: "ConvertLengthMaxSizing",
keywords: ["none"],
typedom_types: ["Keyword", "Length", "Percentage"]
@@ -2290,7 +2431,7 @@
interpolable: true,
field_group: "box",
field_template: "<length>",
- default_value: "Length::MaxSizeNone()",
+ default_value: "Length::None()",
converter: "ConvertLengthMaxSizing",
keywords: ["none"],
typedom_types: ["Keyword", "Length", "Percentage"]
@@ -2430,7 +2571,9 @@
default_value: "1.0",
type_name: "float",
computed_style_custom_functions: ["setter"],
- typedom_types: ["Number"]
+ typedom_types: ["Number"],
+ valid_for_first_letter: true,
+ valid_for_cue: true,
},
{
name: "order",
@@ -2444,6 +2587,17 @@
typedom_types: ["Number"]
},
{
+ // This property is used for testing with origin trial intergration only.
+ // It should never be web-exposed.
+ name: "origin-trial-test-property",
+ property_methods: ["CSSValueFromComputedStyleInternal"],
+ field_template: "keyword",
+ default_value: "normal",
+ keywords: ["normal", "none"],
+ typedom_types: ["Keyword"],
+ runtime_flag: "OriginTrialsSampleAPI"
+ },
+ {
name: "orphans",
property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
interpolable: true,
@@ -2470,6 +2624,7 @@
converter: "ConvertStyleColor",
style_builder_template: "color",
affected_by_forced_colors: true,
+ valid_for_cue: true,
},
{
name: "outline-offset",
@@ -2482,6 +2637,7 @@
computed_style_custom_functions: ["getter"],
converter: "ConvertComputedLength<int>",
typedom_types: ["Length"],
+ valid_for_cue: true,
},
{
name: "outline-style",
@@ -2496,6 +2652,7 @@
default_value: "none",
type_name: "EBorderStyle",
style_builder_custom_functions: ["initial", "inherit", "value"],
+ valid_for_cue: true,
},
{
name: "outline-width",
@@ -2510,6 +2667,7 @@
converter: "ConvertLineWidth<unsigned short>",
keywords: ["thin", "medium", "thick"],
typedom_types: ["Keyword", "Length"],
+ valid_for_cue: true,
},
{
name: "overflow-anchor",
@@ -2612,7 +2770,8 @@
default_value: "Length::Fixed()",
converter: "ConvertLength",
computed_style_custom_functions: ["setter"],
- typedom_types: ["Keyword", "Length", "Percentage"]
+ typedom_types: ["Keyword", "Length", "Percentage"],
+ valid_for_first_letter: true,
},
{
name: "padding-left",
@@ -2624,7 +2783,8 @@
default_value: "Length::Fixed()",
converter: "ConvertLength",
computed_style_custom_functions: ["setter"],
- typedom_types: ["Keyword", "Length", "Percentage"]
+ typedom_types: ["Keyword", "Length", "Percentage"],
+ valid_for_first_letter: true,
},
{
name: "padding-right",
@@ -2636,7 +2796,8 @@
default_value: "Length::Fixed()",
converter: "ConvertLength",
computed_style_custom_functions: ["setter"],
- typedom_types: ["Keyword", "Length", "Percentage"]
+ typedom_types: ["Keyword", "Length", "Percentage"],
+ valid_for_first_letter: true,
},
{
name: "padding-top",
@@ -2648,7 +2809,20 @@
default_value: "Length::Fixed()",
converter: "ConvertLength",
computed_style_custom_functions: ["setter"],
- typedom_types: ["Keyword", "Length", "Percentage"]
+ typedom_types: ["Keyword", "Length", "Percentage"],
+ valid_for_first_letter: true,
+ },
+ {
+ name: "page",
+ field_group: "*",
+ property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+ converter: "ConvertPage",
+ type_name: "AtomicString",
+ default_value: "AtomicString()",
+ field_template: "external",
+ keywords: ["auto"],
+ typedom_types: ["Keyword"],
+ runtime_flag: "NamedPages"
},
{
name: "paint-order",
@@ -2724,18 +2898,13 @@
typedom_types: ["Keyword"]
},
{
- name: "render-subtree",
+ name: "subtree-visibility",
property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
- field_group: "*",
- field_size: 3,
- field_template: "multi_keyword",
- keywords: ["none", "invisible", "skip-activation", "skip-viewport-activation"],
- default_value: "none",
- name_for_methods: "RenderSubtree",
- type_name: "RenderSubtreeFlags",
- converter: "ConvertFlags<RenderSubtreeFlags>",
+ field_template: "keyword",
+ keywords: ["visible", "auto", "hidden", "hidden-matchable"],
+ default_value: "visible",
typedom_types: ["Keyword"],
- runtime_flag: "CSSRenderSubtree"
+ runtime_flag: "CSSSubtreeVisibility"
},
{
name: "resize",
@@ -2792,8 +2961,8 @@
field_group: "*",
field_size: 2, // FIXME: Convert this to a keyword field
field_template: "primitive",
- default_value: "kScrollBehaviorAuto",
- type_name: "ScrollBehavior",
+ default_value: "mojom::blink::ScrollBehavior::kAuto",
+ type_name: "mojom::blink::ScrollBehavior",
keywords: ["auto", "smooth"],
typedom_types: ["Keyword"],
},
@@ -3238,6 +3407,7 @@
typedom_types: ["Keyword"],
default_value: "none",
name_for_methods: "TextCombine",
+ valid_for_marker: true,
},
{
name: "text-decoration-color",
@@ -3253,6 +3423,8 @@
converter: "ConvertStyleColor",
style_builder_template: "color",
affected_by_forced_colors: true,
+ valid_for_first_letter: true,
+ valid_for_cue: true,
},
{
name: "text-decoration-line",
@@ -3265,6 +3437,8 @@
name_for_methods: "TextDecoration",
type_name: "TextDecoration",
converter: "ConvertFlags<TextDecoration>",
+ valid_for_first_letter: true,
+ valid_for_cue: true,
},
{
name: "text-decoration-skip-ink",
@@ -3275,6 +3449,8 @@
keywords: ["none", "auto"],
typedom_types: ["Keyword"],
default_value: "auto",
+ valid_for_first_letter: true,
+ valid_for_cue: true,
},
{
name: "text-decoration-style",
@@ -3284,6 +3460,8 @@
keywords: ["solid", "double", "dotted", "dashed", "wavy"],
typedom_types: ["Keyword"],
default_value: "solid",
+ valid_for_first_letter: true,
+ valid_for_cue: true,
},
{
name: "text-indent",
@@ -3308,7 +3486,8 @@
default_value: "auto",
getter: "GetTextJustify",
type_name: "TextJustify",
- typedom_types: ["Keyword"]
+ typedom_types: ["Keyword"],
+ valid_for_first_letter: true,
},
{
name: "text-overflow",
@@ -3334,6 +3513,8 @@
keywords: ["none"],
typedom_types: ["Keyword"],
affected_by_forced_colors: true,
+ valid_for_first_letter: true,
+ valid_for_cue: true,
},
{
name: "text-size-adjust",
@@ -3359,20 +3540,22 @@
keywords: ["capitalize", "uppercase", "lowercase", "none"],
typedom_types: ["Keyword"],
default_value: "none",
+ valid_for_first_letter: true,
},
{
name: "text-underline-position",
property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
inherited: true,
field_group: "*",
- field_size: 3,
+ field_size: 4,
field_template: "primitive",
default_value: "kTextUnderlinePositionAuto",
name_for_methods: "TextUnderlinePosition",
type_name: "unsigned",
converter: "ConvertTextUnderlinePosition",
- keywords: ["auto", "under", "left", "right"],
+ keywords: ["auto", "from-font", "under", "left", "right"],
typedom_types: ["Keyword"],
+ valid_for_first_letter: true,
},
{
name: "top",
@@ -3393,7 +3576,7 @@
field_size: 6, // FIXME: Make this use "kTouchActionBits".
field_template: "primitive",
include_paths: ["third_party/blink/renderer/platform/graphics/touch_action.h"],
- default_value: "TouchAction::kTouchActionAuto",
+ default_value: "TouchAction::kAuto",
type_name: "TouchAction",
converter: "ConvertFlags<blink::TouchAction>",
keywords: ["auto", "none", "pan-x", "pan-left", "pan-right", "pan-y", "pan-up", "pan-down", "pinch-zoom", "manipulation"],
@@ -3501,6 +3684,7 @@
typedom_types: ["Keyword"],
default_value: "normal",
type_name: "UnicodeBidi",
+ valid_for_marker: true,
},
{
name: "vector-effect",
@@ -3516,6 +3700,7 @@
style_builder_custom_functions: ["inherit", "value"],
typedom_types: ["Keyword", "Length", "Percentage"],
keywords: ["baseline", "sub", "super", "text-top", "text-bottom", "middle"],
+ valid_for_first_letter: true,
},
{
name: "visibility",
@@ -3527,6 +3712,8 @@
keywords: ["visible", "hidden", "collapse"],
typedom_types: ["Keyword"],
default_value: "visible",
+ valid_for_first_letter: true,
+ valid_for_cue: true,
},
{
name: "x",
@@ -3575,11 +3762,13 @@
name_for_methods: "HorizontalBorderSpacing",
type_name: "short",
converter: "ConvertComputedLength<short>",
+ valid_for_first_letter: true,
},
{
name: "-webkit-border-image",
property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
style_builder_custom_functions: ["value"],
+ valid_for_first_letter: true,
},
{
name: "-webkit-border-vertical-spacing",
@@ -3592,6 +3781,7 @@
name_for_methods: "VerticalBorderSpacing",
type_name: "short",
converter: "ConvertComputedLength<short>",
+ valid_for_first_letter: true,
},
// For valid values of box-align see
// http://www.w3.org/TR/2009/WD-css3-flexbox-20090723/#alignment
@@ -3822,36 +4012,6 @@
type_name: "int",
},
{
- name: "-webkit-margin-after-collapse",
- property_methods: ["CSSValueFromComputedStyleInternal"],
- field_group: "*",
- field_template: "keyword",
- keywords: ["collapse", "separate", "discard"],
- default_value: "collapse",
- type_name: "EMarginCollapse",
- },
- {
- name: "-webkit-margin-before-collapse",
- property_methods: ["CSSValueFromComputedStyleInternal"],
- field_group: "*",
- field_template: "keyword",
- keywords: ["collapse", "separate", "discard"],
- default_value: "collapse",
- type_name: "EMarginCollapse",
- },
- {
- name: "-webkit-margin-bottom-collapse",
- property_methods: ["CSSValueFromComputedStyleInternal"],
- name_for_methods: "MarginAfterCollapse",
- type_name: "EMarginCollapse",
- },
- {
- name: "-webkit-margin-top-collapse",
- property_methods: ["CSSValueFromComputedStyleInternal"],
- name_for_methods: "MarginBeforeCollapse",
- type_name: "EMarginCollapse",
- },
- {
name: "-webkit-mask-box-image-outset",
property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
interpolable: true,
@@ -4159,6 +4319,8 @@
],
typedom_types: ["Keyword"],
default_value: "normal",
+ valid_for_cue: true,
+ valid_for_marker: true,
},
{
name: "widows",
@@ -4211,7 +4373,8 @@
converter: "ConvertSpacing",
keywords: ["normal"],
typedom_types: ["normal"],
- typedom_types: ["Keyword", "Length"]
+ typedom_types: ["Keyword", "Length"],
+ valid_for_first_letter: true,
},
{
name: "z-index",
@@ -4297,7 +4460,8 @@
physical_group: "margin",
},
typedom_types: ["Length", "Percentage"],
- keywords: ["auto"]
+ keywords: ["auto"],
+ valid_for_first_letter: true,
},
{
name: "margin-inline-end",
@@ -4308,7 +4472,8 @@
physical_group: "margin",
},
typedom_types: ["Length", "Percentage"],
- keywords: ["auto"]
+ keywords: ["auto"],
+ valid_for_first_letter: true,
},
{
name: "margin-block-start",
@@ -4319,7 +4484,8 @@
physical_group: "margin",
},
typedom_types: ["Length", "Percentage"],
- keywords: ["auto"]
+ keywords: ["auto"],
+ valid_for_first_letter: true,
},
{
name: "margin-block-end",
@@ -4330,7 +4496,8 @@
physical_group: "margin",
},
typedom_types: ["Length", "Percentage"],
- keywords: ["auto"]
+ keywords: ["auto"],
+ valid_for_first_letter: true,
},
{
name: "padding-inline-start",
@@ -4379,6 +4546,7 @@
resolver: "inline-start",
physical_group: "border-width",
},
+ valid_for_first_letter: true,
},
{
name: "border-inline-start-style",
@@ -4386,6 +4554,7 @@
resolver: "inline-start",
physical_group: "border-style",
},
+ valid_for_first_letter: true,
},
{
name: "border-inline-start-color",
@@ -4394,6 +4563,7 @@
resolver: "inline-start",
physical_group: "border-color",
},
+ valid_for_first_letter: true,
},
{
name: "border-inline-end-width",
@@ -4402,6 +4572,7 @@
resolver: "inline-end",
physical_group: "border-width",
},
+ valid_for_first_letter: true,
},
{
name: "border-inline-end-style",
@@ -4409,6 +4580,7 @@
resolver: "inline-end",
physical_group: "border-style",
},
+ valid_for_first_letter: true,
},
{
name: "border-inline-end-color",
@@ -4417,6 +4589,7 @@
resolver: "inline-end",
physical_group: "border-color",
},
+ valid_for_first_letter: true,
},
{
name: "border-block-start-width",
@@ -4425,6 +4598,7 @@
resolver: "block-start",
physical_group: "border-width",
},
+ valid_for_first_letter: true,
},
{
name: "border-block-start-style",
@@ -4432,6 +4606,7 @@
resolver: "block-start",
physical_group: "border-style",
},
+ valid_for_first_letter: true,
},
{
name: "border-block-start-color",
@@ -4440,6 +4615,7 @@
resolver: "block-start",
physical_group: "border-color",
},
+ valid_for_first_letter: true,
},
{
name: "border-block-end-width",
@@ -4448,6 +4624,7 @@
resolver: "block-end",
physical_group: "border-width",
},
+ valid_for_first_letter: true,
},
{
name: "border-block-end-style",
@@ -4455,6 +4632,7 @@
resolver: "block-end",
physical_group: "border-style",
},
+ valid_for_first_letter: true,
},
{
name: "border-block-end-color",
@@ -4463,6 +4641,7 @@
resolver: "block-end",
physical_group: "border-color",
},
+ valid_for_first_letter: true,
},
{
name: "inset-inline-start",
@@ -4621,11 +4800,6 @@
style_builder_template: "empty",
},
{
- name: "page",
- property_methods: ["ParseSingleValue"],
- style_builder_template: "empty",
- },
- {
name: "-webkit-font-size-delta",
property_methods: ["ParseSingleValue"],
style_builder_template: "empty",
@@ -5033,12 +5207,6 @@
runtime_flag: "CSSLogical",
},
{
- name: "intrinsic-size",
- longhands: ["intrinsic-width", "intrinsic-height"],
- property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
- runtime_flag: "CSSIntrinsicSize"
- },
- {
name: "list-style",
longhands: ["list-style-position", "list-style-image", "list-style-type"],
property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
@@ -5215,13 +5383,6 @@
property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
},
{
- name: "-webkit-margin-collapse",
- longhands: [
- "-webkit-margin-before-collapse", "-webkit-margin-after-collapse"
- ],
- property_methods: ["ParseShorthand"],
- },
- {
name: "-webkit-mask",
longhands: [
"-webkit-mask-image", "-webkit-mask-position-x",
@@ -5274,6 +5435,10 @@
computed_style_custom_functions: ["getter", "setter"],
style_builder_custom_functions: ["initial", "inherit", "value"],
priority: "High",
+ affected_by_forced_colors: true,
+ valid_for_first_letter: true,
+ valid_for_cue: true,
+ valid_for_marker: true,
},
{
name: "-internal-visited-caret-color",
@@ -5304,6 +5469,7 @@
computed_style_custom_functions: ["getter","setter"],
converter: "ConvertStyleColor",
style_builder_template: "visited_color",
+ affected_by_forced_colors: true,
},
{
name: "-internal-visited-background-color",
@@ -5320,6 +5486,9 @@
style_builder_template_args: {
initial_color: "ComputedStyleInitialValues::InitialBackgroundColor",
},
+ affected_by_forced_colors: true,
+ valid_for_first_letter: true,
+ valid_for_cue: true,
},
{
name: "-internal-visited-border-left-color",
@@ -5333,6 +5502,8 @@
computed_style_custom_functions: ["getter", "setter"],
converter: "ConvertStyleColor",
style_builder_template: "visited_color",
+ affected_by_forced_colors: true,
+ valid_for_first_letter: true,
},
{
name: "-internal-visited-border-right-color",
@@ -5346,6 +5517,8 @@
computed_style_custom_functions: ["getter", "setter"],
converter: "ConvertStyleColor",
style_builder_template: "visited_color",
+ affected_by_forced_colors: true,
+ valid_for_first_letter: true,
},
{
name: "-internal-visited-border-top-color",
@@ -5359,6 +5532,8 @@
computed_style_custom_functions: ["getter", "setter"],
converter: "ConvertStyleColor",
style_builder_template: "visited_color",
+ affected_by_forced_colors: true,
+ valid_for_first_letter: true,
},
{
name: "-internal-visited-border-bottom-color",
@@ -5372,6 +5547,8 @@
computed_style_custom_functions: ["getter", "setter"],
converter: "ConvertStyleColor",
style_builder_template: "visited_color",
+ affected_by_forced_colors: true,
+ valid_for_first_letter: true,
},
{
name: "-internal-visited-border-inline-start-color",
@@ -5381,6 +5558,7 @@
resolver: "inline-start",
physical_group: "visited-border-color",
},
+ valid_for_first_letter: true,
},
{
name: "-internal-visited-border-inline-end-color",
@@ -5390,6 +5568,7 @@
resolver: "inline-end",
physical_group: "visited-border-color",
},
+ valid_for_first_letter: true,
},
{
name: "-internal-visited-border-block-start-color",
@@ -5399,6 +5578,7 @@
resolver: "block-start",
physical_group: "visited-border-color",
},
+ valid_for_first_letter: true,
},
{
name: "-internal-visited-border-block-end-color",
@@ -5408,6 +5588,7 @@
resolver: "block-end",
physical_group: "visited-border-color",
},
+ valid_for_first_letter: true,
},
{
name: "-internal-visited-fill",
@@ -5419,6 +5600,7 @@
setter: "SetInternalVisitedFillPaint",
getter: "FillPaint",
converter: "ConvertSVGPaint",
+ affected_by_forced_colors: true,
},
{
name: "-internal-visited-outline-color",
@@ -5432,6 +5614,8 @@
computed_style_custom_functions: ["getter", "setter"],
converter: "ConvertStyleColor",
style_builder_template: "visited_color",
+ affected_by_forced_colors: true,
+ valid_for_cue: true,
},
{
name: "-internal-visited-stroke",
@@ -5443,6 +5627,7 @@
setter: "SetInternalVisitedStrokePaint",
getter: "StrokePaint",
converter: "ConvertSVGPaint",
+ affected_by_forced_colors: true,
},
{
name: "-internal-visited-text-decoration-color",
@@ -5456,6 +5641,9 @@
computed_style_custom_functions: ["getter", "setter"],
converter: "ConvertStyleColor",
style_builder_template: "visited_color",
+ affected_by_forced_colors: true,
+ valid_for_first_letter: true,
+ valid_for_cue: true,
},
{
name: "-internal-visited-text-emphasis-color",
@@ -5473,6 +5661,7 @@
style_builder_template_args: {
initial_color: "StyleColor::CurrentColor",
},
+ affected_by_forced_colors: true,
},
{
name: "-internal-visited-text-fill-color",
@@ -5518,6 +5707,29 @@
field_group: "*",
priority: "High",
style_builder_custom_functions: ["initial", "inherit", "value"],
+ surrogate_for: "zoom",
+ },
+
+ // Name: -internal-empty-line-height:
+ // Value: none | fabricated
+ // If the element is inline or contains visible text, this property has
+ // no effect.
+ //
+ // 'none'
+ // The box's intrinsic height is 0, and it defines no baseline.
+ // 'fabricated'
+ // The box has intrinsic height and baseline, computed from the current
+ // font metrics.
+ {
+ name: "-internal-empty-line-height",
+ property_methods: ["ParseSingleValue" ],
+ inherited: false,
+ field_group: "*",
+ field_template: "primitive",
+ type_name: "bool",
+ default_value: "false",
+ name_for_methods: "HasLineIfEmpty",
+ converter: "ConvertInternalEmptyLineHeight",
},
// Aliases; these map to the same CSSPropertyID
diff --git a/chromium/third_party/blink/renderer/core/css/css_properties_ranking.json5 b/chromium/third_party/blink/renderer/core/css/css_properties_ranking.json5
index b954fa18522..92919e7e046 100644
--- a/chromium/third_party/blink/renderer/core/css/css_properties_ranking.json5
+++ b/chromium/third_party/blink/renderer/core/css/css_properties_ranking.json5
@@ -380,7 +380,6 @@
"-webkit-padding-end",
"column-rule-width",
"vector-effect",
- "-webkit-margin-top-collapse",
"background-repeat-y",
"text-orientation",
"-webkit-text-emphasis-color",
@@ -464,12 +463,10 @@
"transform-box",
"-webkit-mask-box-image-width",
"scroll-padding-left",
- "-webkit-margin-after-collapse",
"-webkit-mask-box-image-source",
"-webkit-mask-box-image-repeat",
"-webkit-mask-box-image-slice",
"-webkit-mask-box-image-outset",
- "-webkit-margin-before-collapse",
"-webkit-column-rule-color",
"font-variation-settings",
"max-inline-size",
@@ -484,7 +481,6 @@
"scroll-snap-margin",
"-webkit-box-flex-group",
"-webkit-column-break-after",
- "-webkit-margin-bottom-collapse",
"scroll-padding-bottom",
"scroll-padding-right",
"scroll-snap-margin-top",
@@ -511,7 +507,6 @@
"scroll-snap-margin-inline-start",
"place-items",
"place-self",
- "-webkit-margin-collapse",
"-webkit-column-rule-width",
"font-optical-sizing",
"-webkit-border-end-color",
@@ -698,7 +693,8 @@
"border-inline-width",
"inset-block-start",
"syntax",
- "render-subtree",
+ "subtree-visibility",
+ "origin-trial-test-property",
],
"properties": {}
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_property_equality.cc b/chromium/third_party/blink/renderer/core/css/css_property_equality.cc
index da0c5c74ec0..6146932fc66 100644
--- a/chromium/third_party/blink/renderer/core/css/css_property_equality.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_property_equality.cc
@@ -383,10 +383,10 @@ bool CSSPropertyEquality::PropertiesEqual(const PropertyHandle& property,
case CSSPropertyID::kZIndex:
return a.HasAutoZIndex() == b.HasAutoZIndex() &&
(a.HasAutoZIndex() || a.ZIndex() == b.ZIndex());
- case CSSPropertyID::kIntrinsicWidth:
- return a.IntrinsicWidth() == b.IntrinsicWidth();
- case CSSPropertyID::kIntrinsicHeight:
- return a.IntrinsicHeight() == b.IntrinsicHeight();
+ case CSSPropertyID::kContainIntrinsicSize:
+ return a.ContainIntrinsicSize() == b.ContainIntrinsicSize();
+ case CSSPropertyID::kAspectRatio:
+ return a.AspectRatio() == b.AspectRatio();
default:
NOTREACHED();
return true;
diff --git a/chromium/third_party/blink/renderer/core/css/css_property_name.h b/chromium/third_party/blink/renderer/core/css/css_property_name.h
index 64d34c47200..e8f7a46a250 100644
--- a/chromium/third_party/blink/renderer/core/css/css_property_name.h
+++ b/chromium/third_party/blink/renderer/core/css/css_property_name.h
@@ -12,6 +12,8 @@
namespace blink {
+class ExecutionContext;
+
// This class may be used to represent the name of any valid CSS property,
// including custom properties.
class CORE_EXPORT CSSPropertyName {
@@ -29,8 +31,10 @@ class CORE_EXPORT CSSPropertyName {
DCHECK(!custom_property_name.IsNull());
}
- static base::Optional<CSSPropertyName> From(const String& value) {
- const CSSPropertyID property_id = cssPropertyID(value);
+ static base::Optional<CSSPropertyName> From(
+ const ExecutionContext* execution_context,
+ const String& value) {
+ const CSSPropertyID property_id = cssPropertyID(execution_context, value);
if (property_id == CSSPropertyID::kInvalid)
return base::nullopt;
if (property_id == CSSPropertyID::kVariable)
diff --git a/chromium/third_party/blink/renderer/core/css/css_property_name_test.cc b/chromium/third_party/blink/renderer/core/css/css_property_name_test.cc
index 771484377bb..b3d5b72728e 100644
--- a/chromium/third_party/blink/renderer/core/css/css_property_name_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_property_name_test.cc
@@ -3,13 +3,13 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/core/css/css_property_name.h"
-#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/css/properties/css_property.h"
+#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
namespace blink {
-class CSSPropertyNameTest : public testing::Test {
+class CSSPropertyNameTest : public PageTestBase {
public:
CSSPropertyName Empty() const {
return CSSPropertyName(CSSPropertyName::kEmptyValue);
@@ -61,14 +61,20 @@ TEST_F(CSSPropertyNameTest, OperatorEquals) {
}
TEST_F(CSSPropertyNameTest, From) {
- EXPECT_TRUE(CSSPropertyName::From("color"));
- EXPECT_TRUE(CSSPropertyName::From("--x"));
- EXPECT_FALSE(CSSPropertyName::From("notaproperty"));
- EXPECT_FALSE(CSSPropertyName::From("-not-a-property"));
-
- EXPECT_EQ(*CSSPropertyName::From("color"),
- CSSPropertyName(CSSPropertyID::kColor));
- EXPECT_EQ(*CSSPropertyName::From("--x"), CSSPropertyName("--x"));
+ EXPECT_TRUE(
+ CSSPropertyName::From(GetDocument().GetExecutionContext(), "color"));
+ EXPECT_TRUE(
+ CSSPropertyName::From(GetDocument().GetExecutionContext(), "--x"));
+ EXPECT_FALSE(CSSPropertyName::From(GetDocument().GetExecutionContext(),
+ "notaproperty"));
+ EXPECT_FALSE(CSSPropertyName::From(GetDocument().GetExecutionContext(),
+ "-not-a-property"));
+
+ EXPECT_EQ(
+ *CSSPropertyName::From(GetDocument().GetExecutionContext(), "color"),
+ CSSPropertyName(CSSPropertyID::kColor));
+ EXPECT_EQ(*CSSPropertyName::From(GetDocument().GetExecutionContext(), "--x"),
+ CSSPropertyName("--x"));
}
TEST_F(CSSPropertyNameTest, FromNativeCSSProperty) {
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 643b1e86cb3..8910daf28af 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
@@ -40,7 +40,7 @@ void CSSPropertyRule::Reattach(StyleRuleBase* rule) {
properties_cssom_wrapper_->Reattach(property_rule_->MutableProperties());
}
-void CSSPropertyRule::Trace(blink::Visitor* visitor) {
+void CSSPropertyRule::Trace(Visitor* visitor) {
visitor->Trace(property_rule_);
visitor->Trace(properties_cssom_wrapper_);
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 e977bb35fdc..2b5f55aea45 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
@@ -27,7 +27,7 @@ class CSSPropertyRule final : public CSSRule {
CSSStyleDeclaration* style() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
CSSRule::Type type() const override { return 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 f7dac058925..f33d3c6a593 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(blink::Visitor* visitor) { visitor->Trace(child_rules); }
+ void Trace(Visitor* visitor) { 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 730ddf8eb2d..dc8f65aebc0 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(blink::Visitor* visitor) { visitor->Trace(value_); }
+ void Trace(Visitor* visitor) { 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 2b5940ed826..94d083ccecb 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
@@ -33,6 +33,7 @@
#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/wtf/size_assertions.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#ifndef NDEBUG
@@ -105,8 +106,6 @@ ImmutableCSSPropertyValueSet::ImmutableCSSPropertyValueSet(
}
}
-ImmutableCSSPropertyValueSet::~ImmutableCSSPropertyValueSet() = default;
-
// Convert property into an uint16_t for comparison with metadata's property id
// to avoid the compiler converting it to an int multiple times in a loop.
static uint16_t GetConvertedCSSPropertyID(CSSPropertyID property_id) {
@@ -171,7 +170,8 @@ template CORE_EXPORT int ImmutableCSSPropertyValueSet::FindPropertyIndex(
template CORE_EXPORT int ImmutableCSSPropertyValueSet::FindPropertyIndex(
AtRuleDescriptorID) const;
-void ImmutableCSSPropertyValueSet::TraceAfterDispatch(blink::Visitor* visitor) {
+void ImmutableCSSPropertyValueSet::TraceAfterDispatch(
+ blink::Visitor* visitor) const {
const Member<const CSSValue>* values = ValueArray();
for (unsigned i = 0; i < array_size_; i++)
visitor->Trace(values[i]);
@@ -247,7 +247,7 @@ template CORE_EXPORT const CSSValue* CSSPropertyValueSet::GetPropertyCSSValue<
template CORE_EXPORT const CSSValue*
CSSPropertyValueSet::GetPropertyCSSValue<AtomicString>(AtomicString) const;
-void CSSPropertyValueSet::Trace(blink::Visitor* visitor) {
+void CSSPropertyValueSet::Trace(Visitor* visitor) {
if (is_mutable_)
To<MutableCSSPropertyValueSet>(this)->TraceAfterDispatch(visitor);
else
@@ -604,7 +604,8 @@ MutableCSSPropertyValueSet* CSSPropertyValueSet::CopyPropertiesInSet(
list.size());
}
-CSSStyleDeclaration* MutableCSSPropertyValueSet::EnsureCSSStyleDeclaration() {
+CSSStyleDeclaration* MutableCSSPropertyValueSet::EnsureCSSStyleDeclaration(
+ ExecutionContext* execution_context) {
// FIXME: get rid of this weirdness of a CSSStyleDeclaration inside of a
// style property set.
if (cssom_wrapper_) {
@@ -613,7 +614,8 @@ CSSStyleDeclaration* MutableCSSPropertyValueSet::EnsureCSSStyleDeclaration() {
DCHECK(!cssom_wrapper_->ParentElement());
return cssom_wrapper_.Get();
}
- cssom_wrapper_ = MakeGarbageCollected<PropertySetCSSStyleDeclaration>(*this);
+ cssom_wrapper_ = MakeGarbageCollected<PropertySetCSSStyleDeclaration>(
+ execution_context, *this);
return cssom_wrapper_.Get();
}
@@ -637,7 +639,8 @@ template CORE_EXPORT int MutableCSSPropertyValueSet::FindPropertyIndex(
template CORE_EXPORT int MutableCSSPropertyValueSet::FindPropertyIndex(
AtomicString) const;
-void MutableCSSPropertyValueSet::TraceAfterDispatch(blink::Visitor* visitor) {
+void MutableCSSPropertyValueSet::TraceAfterDispatch(
+ blink::Visitor* visitor) const {
visitor->Trace(cssom_wrapper_);
visitor->Trace(property_vector_);
CSSPropertyValueSet::TraceAfterDispatch(visitor);
@@ -654,11 +657,9 @@ unsigned CSSPropertyValueSet::AverageSizeInBytes() {
// See the function above if you need to update this.
struct SameSizeAsCSSPropertyValueSet final
: public GarbageCollected<SameSizeAsCSSPropertyValueSet> {
- unsigned bitfield;
+ uint32_t bitfield;
};
-static_assert(sizeof(CSSPropertyValueSet) ==
- sizeof(SameSizeAsCSSPropertyValueSet),
- "CSSPropertyValueSet should stay small");
+ASSERT_SIZE(CSSPropertyValueSet, SameSizeAsCSSPropertyValueSet);
#ifndef NDEBUG
void CSSPropertyValueSet::ShowStyle() {
@@ -666,6 +667,6 @@ void CSSPropertyValueSet::ShowStyle() {
}
#endif
-void CSSLazyPropertyParser::Trace(blink::Visitor* visitor) {}
+void CSSLazyPropertyParser::Trace(Visitor* visitor) {}
} // 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 a16b05b588f..303fc5dccda 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
@@ -37,6 +37,7 @@
namespace blink {
class CSSStyleDeclaration;
+class ExecutionContext;
class ImmutableCSSPropertyValueSet;
class MutableCSSPropertyValueSet;
class StyleSheetContents;
@@ -81,7 +82,7 @@ class CORE_EXPORT CSSPropertyValueSet
private:
const CSSValue& PropertyValue() const;
- Member<const CSSPropertyValueSet> property_set_;
+ const CSSPropertyValueSet* property_set_;
unsigned index_;
};
@@ -137,29 +138,28 @@ class CORE_EXPORT CSSPropertyValueSet
bool PropertyMatches(CSSPropertyID, const CSSValue&) const;
- void Trace(blink::Visitor*);
- void TraceAfterDispatch(blink::Visitor* visitor) {}
+ void Trace(Visitor*);
+ void TraceAfterDispatch(blink::Visitor* visitor) const {}
protected:
enum { kMaxArraySize = (1 << 28) - 1 };
- CSSPropertyValueSet(CSSParserMode css_parser_mode)
- : css_parser_mode_(css_parser_mode), is_mutable_(true), array_size_(0) {}
+ explicit CSSPropertyValueSet(CSSParserMode css_parser_mode)
+ : array_size_(0), css_parser_mode_(css_parser_mode), is_mutable_(true) {}
CSSPropertyValueSet(CSSParserMode css_parser_mode,
unsigned immutable_array_size)
- : css_parser_mode_(css_parser_mode), is_mutable_(false) {
- // Avoid min()/max() from std here in the header, because that would require
- // inclusion of <algorithm>, which is slow to compile.
- if (immutable_array_size < unsigned(kMaxArraySize))
- array_size_ = immutable_array_size;
- else
- array_size_ = unsigned(kMaxArraySize);
- }
-
- unsigned css_parser_mode_ : 3;
- mutable unsigned is_mutable_ : 1;
- unsigned array_size_ : 28;
+ // Avoid min()/max() from std here in the header, because that would
+ // require inclusion of <algorithm>, which is slow to compile.
+ : array_size_((immutable_array_size < unsigned(kMaxArraySize))
+ ? immutable_array_size
+ : unsigned(kMaxArraySize)),
+ css_parser_mode_(css_parser_mode),
+ is_mutable_(false) {}
+
+ const uint32_t array_size_ : 28;
+ const uint32_t css_parser_mode_ : 3;
+ const uint32_t is_mutable_ : 1;
friend class PropertySetCSSStyleDeclaration;
DISALLOW_COPY_AND_ASSIGN(CSSPropertyValueSet);
@@ -171,7 +171,7 @@ class CSSLazyPropertyParser : public GarbageCollected<CSSLazyPropertyParser> {
CSSLazyPropertyParser() = default;
virtual ~CSSLazyPropertyParser() = default;
virtual CSSPropertyValueSet* ParseProperties() = 0;
- virtual void Trace(blink::Visitor*);
+ virtual void Trace(Visitor*);
DISALLOW_COPY_AND_ASSIGN(CSSLazyPropertyParser);
};
@@ -182,7 +182,6 @@ class CORE_EXPORT ALIGNAS(alignof(Member<const CSSValue>))
ImmutableCSSPropertyValueSet(const CSSPropertyValue*,
unsigned count,
CSSParserMode);
- ~ImmutableCSSPropertyValueSet();
static ImmutableCSSPropertyValueSet*
Create(const CSSPropertyValue* properties, unsigned count, CSSParserMode);
@@ -195,7 +194,7 @@ class CORE_EXPORT ALIGNAS(alignof(Member<const CSSValue>))
template <typename T> // CSSPropertyID or AtomicString
int FindPropertyIndex(T property) const;
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
};
inline const Member<const CSSValue>* ImmutableCSSPropertyValueSet::ValueArray()
@@ -277,12 +276,13 @@ class CORE_EXPORT MutableCSSPropertyValueSet : public CSSPropertyValueSet {
SecureContextMode,
StyleSheetContents* context_style_sheet);
- CSSStyleDeclaration* EnsureCSSStyleDeclaration();
+ CSSStyleDeclaration* EnsureCSSStyleDeclaration(
+ ExecutionContext* execution_context);
template <typename T> // CSSPropertyID or AtomicString
int FindPropertyIndex(T property) const;
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
bool RemovePropertyAtIndex(int, String* return_text);
@@ -309,7 +309,7 @@ struct DowncastTraits<MutableCSSPropertyValueSet> {
inline const CSSPropertyValueMetadata&
CSSPropertyValueSet::PropertyReference::PropertyMetadata() const {
if (auto* mutable_property_set =
- DynamicTo<MutableCSSPropertyValueSet>(property_set_.Get())) {
+ DynamicTo<MutableCSSPropertyValueSet>(property_set_)) {
return mutable_property_set->property_vector_.at(index_).Metadata();
}
return To<ImmutableCSSPropertyValueSet>(*property_set_)
@@ -319,7 +319,7 @@ CSSPropertyValueSet::PropertyReference::PropertyMetadata() const {
inline const CSSValue& CSSPropertyValueSet::PropertyReference::PropertyValue()
const {
if (auto* mutable_property_set =
- DynamicTo<MutableCSSPropertyValueSet>(property_set_.Get())) {
+ DynamicTo<MutableCSSPropertyValueSet>(property_set_)) {
return *mutable_property_set->property_vector_.at(index_).Value();
}
return *To<ImmutableCSSPropertyValueSet>(*property_set_).ValueArray()[index_];
diff --git a/chromium/third_party/blink/renderer/core/css/css_quad_value.cc b/chromium/third_party/blink/renderer/core/css/css_quad_value.cc
index 21a7c604baa..5ecec7e7d35 100644
--- a/chromium/third_party/blink/renderer/core/css/css_quad_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_quad_value.cc
@@ -37,7 +37,7 @@ String CSSQuadValue::CustomCSSText() const {
return result.ToString();
}
-void CSSQuadValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSQuadValue::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(top_);
visitor->Trace(right_);
visitor->Trace(bottom_);
diff --git a/chromium/third_party/blink/renderer/core/css/css_quad_value.h b/chromium/third_party/blink/renderer/core/css/css_quad_value.h
index 0f5c9c7ef26..711b74bdce7 100644
--- a/chromium/third_party/blink/renderer/core/css/css_quad_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_quad_value.h
@@ -32,12 +32,6 @@ class CORE_EXPORT CSSQuadValue : public CSSValue {
public:
enum TypeForSerialization { kSerializeAsRect, kSerializeAsQuad };
- static CSSQuadValue* Create(CSSValue* value,
- TypeForSerialization serialization_type) {
- return MakeGarbageCollected<CSSQuadValue>(value, value, value, value,
- serialization_type);
- }
-
CSSQuadValue(CSSValue* top,
CSSValue* right,
CSSValue* bottom,
@@ -50,6 +44,14 @@ class CORE_EXPORT CSSQuadValue : public CSSValue {
bottom_(bottom),
left_(left) {}
+ CSSQuadValue(CSSValue* value, TypeForSerialization serialization_type)
+ : CSSValue(kQuadClass),
+ serialization_type_(serialization_type),
+ top_(value),
+ right_(value),
+ bottom_(value),
+ left_(value) {}
+
CSSValue* Top() const { return top_.Get(); }
CSSValue* Right() const { return right_.Get(); }
CSSValue* Bottom() const { return bottom_.Get(); }
@@ -66,7 +68,7 @@ class CORE_EXPORT CSSQuadValue : public CSSValue {
DataEquivalent(bottom_, other.bottom_);
}
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
TypeForSerialization serialization_type_;
diff --git a/chromium/third_party/blink/renderer/core/css/css_ray_value.cc b/chromium/third_party/blink/renderer/core/css/css_ray_value.cc
index d54da15730c..65fac431d66 100644
--- a/chromium/third_party/blink/renderer/core/css/css_ray_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_ray_value.cc
@@ -36,7 +36,7 @@ bool CSSRayValue::Equals(const CSSRayValue& other) const {
DataEquivalent(contain_, other.contain_);
}
-void CSSRayValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSRayValue::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(angle_);
visitor->Trace(size_);
visitor->Trace(contain_);
diff --git a/chromium/third_party/blink/renderer/core/css/css_ray_value.h b/chromium/third_party/blink/renderer/core/css/css_ray_value.h
index dd642cd7777..ea27a1dcd4f 100644
--- a/chromium/third_party/blink/renderer/core/css/css_ray_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_ray_value.h
@@ -29,7 +29,7 @@ class CSSRayValue : public CSSValue {
bool Equals(const CSSRayValue&) const;
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
Member<const CSSPrimitiveValue> angle_;
diff --git a/chromium/third_party/blink/renderer/core/css/css_reflect_value.cc b/chromium/third_party/blink/renderer/core/css/css_reflect_value.cc
index 7974b2364fe..4d92d4296c5 100644
--- a/chromium/third_party/blink/renderer/core/css/css_reflect_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_reflect_value.cc
@@ -44,7 +44,7 @@ bool CSSReflectValue::Equals(const CSSReflectValue& other) const {
DataEquivalent(mask_, other.mask_);
}
-void CSSReflectValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSReflectValue::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(direction_);
visitor->Trace(offset_);
visitor->Trace(mask_);
diff --git a/chromium/third_party/blink/renderer/core/css/css_reflect_value.h b/chromium/third_party/blink/renderer/core/css/css_reflect_value.h
index 50e206b421a..1b6e5749a59 100644
--- a/chromium/third_party/blink/renderer/core/css/css_reflect_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_reflect_value.h
@@ -55,7 +55,7 @@ class CSSReflectValue : public CSSValue {
bool Equals(const CSSReflectValue&) const;
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
Member<CSSIdentifierValue> direction_;
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 15d3d4da2a2..9559c41c90f 100644
--- a/chromium/third_party/blink/renderer/core/css/css_rule.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_rule.cc
@@ -31,12 +31,21 @@ struct SameSizeAsCSSRule : public GarbageCollected<SameSizeAsCSSRule>,
public ScriptWrappable {
~SameSizeAsCSSRule() override;
unsigned char bitfields;
- void* pointer_union;
+ Member<ScriptWrappable> member;
+#if !DCHECK_IS_ON()
+ static_assert(sizeof(Member<ScriptWrappable>) == sizeof(void*),
+ "Increasing size of Member increases size of CSSRule");
+#endif // DCHECK_IS_ON()
};
static_assert(sizeof(CSSRule) == sizeof(SameSizeAsCSSRule),
"CSSRule should stay small");
+CSSRule::CSSRule(CSSStyleSheet* parent)
+ : has_cached_selector_text_(false),
+ parent_is_rule_(false),
+ parent_(parent) {}
+
const CSSParserContext* CSSRule::ParserContext(
SecureContextMode secure_context_mode) const {
CSSStyleSheet* style_sheet = parentStyleSheet();
@@ -46,25 +55,26 @@ const CSSParserContext* CSSRule::ParserContext(
void CSSRule::SetParentStyleSheet(CSSStyleSheet* style_sheet) {
parent_is_rule_ = false;
- parent_style_sheet_ = style_sheet;
- MarkingVisitor::WriteBarrier(parent_style_sheet_);
+ parent_ = style_sheet;
}
void CSSRule::SetParentRule(CSSRule* rule) {
parent_is_rule_ = true;
- parent_rule_ = rule;
- MarkingVisitor::WriteBarrier(parent_rule_);
+ parent_ = rule;
}
-void CSSRule::Trace(blink::Visitor* visitor) {
- // This makes the parent link strong, which is different from the
- // pre-oilpan world, where the parent link is mysteriously zeroed under
- // some circumstances.
- if (parent_is_rule_)
- visitor->Trace(parent_rule_);
- else
- visitor->Trace(parent_style_sheet_);
+void CSSRule::Trace(Visitor* visitor) {
+ visitor->Trace(parent_);
ScriptWrappable::Trace(visitor);
}
+bool CSSRule::VerifyParentIsCSSRule() const {
+ return !parent_ || parent_->GetWrapperTypeInfo()->IsSubclass(
+ CSSRule::GetStaticWrapperTypeInfo());
+}
+bool CSSRule::VerifyParentIsCSSStyleSheet() const {
+ return !parent_ || parent_->GetWrapperTypeInfo()->IsSubclass(
+ CSSStyleSheet::GetStaticWrapperTypeInfo());
+}
+
} // namespace blink
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 32b28627ece..c7e81d9efde 100644
--- a/chromium/third_party/blink/renderer/core/css/css_rule.h
+++ b/chromium/third_party/blink/renderer/core/css/css_rule.h
@@ -71,26 +71,23 @@ class CORE_EXPORT CSSRule : public ScriptWrappable {
void SetParentRule(CSSRule*);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
CSSStyleSheet* parentStyleSheet() const {
if (parent_is_rule_)
- return parent_rule_ ? parent_rule_->parentStyleSheet() : nullptr;
- return parent_style_sheet_;
+ return parent_ ? ParentAsCSSRule()->parentStyleSheet() : nullptr;
+ return ParentAsCSSStyleSheet();
}
CSSRule* parentRule() const {
- return parent_is_rule_ ? parent_rule_ : nullptr;
+ return parent_is_rule_ ? ParentAsCSSRule() : nullptr;
}
// The CSSOM spec states that "setting the cssText attribute must do nothing."
void setCSSText(const String&) {}
protected:
- CSSRule(CSSStyleSheet* parent)
- : has_cached_selector_text_(false),
- parent_is_rule_(false),
- parent_style_sheet_(parent) {}
+ CSSRule(CSSStyleSheet* parent);
bool HasCachedSelectorText() const { return has_cached_selector_text_; }
void SetHasCachedSelectorText(bool has_cached_selector_text) const {
@@ -100,14 +97,27 @@ class CORE_EXPORT CSSRule : public ScriptWrappable {
const CSSParserContext* ParserContext(SecureContextMode) const;
private:
+ bool VerifyParentIsCSSRule() const;
+ bool VerifyParentIsCSSStyleSheet() const;
+
+ CSSRule* ParentAsCSSRule() const {
+ DCHECK(parent_is_rule_);
+ DCHECK(VerifyParentIsCSSRule());
+ return reinterpret_cast<CSSRule*>(parent_.Get());
+ }
+ CSSStyleSheet* ParentAsCSSStyleSheet() const {
+ DCHECK(!parent_is_rule_);
+ DCHECK(VerifyParentIsCSSStyleSheet());
+ return reinterpret_cast<CSSStyleSheet*>(parent_.Get());
+ }
+
mutable unsigned char has_cached_selector_text_ : 1;
unsigned char parent_is_rule_ : 1;
- // These should be Members, but no Members in unions.
- union {
- CSSRule* parent_rule_;
- CSSStyleSheet* parent_style_sheet_;
- };
+ // parent_ should reference either CSSRule or CSSStyleSheet (both are
+ // descendants of ScriptWrappable). This field should only be accessed
+ // via the getters above (ParentAsCSSRule and ParentAsCSSStyleSheet).
+ Member<ScriptWrappable> parent_;
};
} // namespace blink
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 f677ac956e9..52fce745177 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(rule_);
CSSRuleList::Trace(visitor);
}
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 3a67864fc52..d5294ee7a9e 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
@@ -33,11 +33,22 @@
#include "third_party/blink/renderer/platform/fonts/segmented_font_data.h"
#include "third_party/blink/renderer/platform/fonts/simple_font_data.h"
+// See comment below in CSSSegmentedFontFace::GetFontData - the cache from
+// CSSSegmentedFontFace (which represents a group of @font-face declarations
+// with identical FontSelectionCapabilities but differing by unicode-range) to
+// FontData/SegmentedFontData, (i.e. the actual font blobs that can be used for
+// shaping and painting retrieved from a CSSFontFaceSource) is usually small
+// (less than a dozen, up to tens) for non-animation-cases, but grows fast to
+// thousands when animating variable font parameters. Set a limit until we start
+// dropping cache entries in animation scenarios.
+static constexpr size_t kFontDataTableMaxSize = 250;
+
namespace blink {
CSSSegmentedFontFace::CSSSegmentedFontFace(
FontSelectionCapabilities font_selection_capabilities)
: font_selection_capabilities_(font_selection_capabilities),
+ font_data_table_(kFontDataTableMaxSize),
first_non_css_connected_face_(font_faces_.end()),
approximate_character_count_(0) {}
@@ -45,10 +56,10 @@ CSSSegmentedFontFace::~CSSSegmentedFontFace() = default;
void CSSSegmentedFontFace::PruneTable() {
// Make sure the glyph page tree prunes out all uses of this custom font.
- if (font_data_table_.IsEmpty())
+ if (!font_data_table_.size())
return;
- font_data_table_.clear();
+ font_data_table_.Clear();
}
bool CSSSegmentedFontFace::IsValid() const {
@@ -71,10 +82,11 @@ void CSSSegmentedFontFace::AddFontFace(FontFace* font_face,
if (css_connected) {
font_faces_.InsertBefore(first_non_css_connected_face_, font_face);
} else {
- // This is the only place in Blink that is using addReturnIterator.
- FontFaceList::iterator iterator = font_faces_.AddReturnIterator(font_face);
- if (first_non_css_connected_face_ == font_faces_.end())
- first_non_css_connected_face_ = iterator;
+ FontFaceList::AddResult result = font_faces_.insert(font_face);
+ if (first_non_css_connected_face_ == font_faces_.end()) {
+ --first_non_css_connected_face_;
+ DCHECK_EQ(result.stored_value, &*first_non_css_connected_face_);
+ }
}
}
@@ -102,16 +114,26 @@ scoped_refptr<FontData> CSSSegmentedFontFace::GetFontData(
FontCacheKey key = font_description.CacheKey(
FontFaceCreationParams(), is_unique_match, font_selection_request);
- scoped_refptr<SegmentedFontData>& font_data =
- font_data_table_.insert(key, nullptr).stored_value->value;
- if (font_data && font_data->NumFaces()) {
- // No release, we have a reference to an object in the cache which should
- // retain the ref count it has.
- return font_data;
- }
-
- if (!font_data)
- font_data = SegmentedFontData::Create();
+ // font_data_table_ caches FontData and SegmentedFontData instances, which
+ // provide SimpleFontData objects containing FontPlatformData objects. In the
+ // case of variable font animations, the variable instance SkTypeface is
+ // contained in these FontPlatformData objects. In other words, this cache
+ // stores the recently used variable font instances during a variable font
+ // animation. The cache reflects in how many different sizes, synthetic styles
+ // (bold / italic synthetic versions), or for variable fonts, in how many
+ // variable instances (stretch/style/weightand font-variation-setings
+ // variations) the font is instantiated. In non animation scenarios, there is
+ // usually only a small number of FontData/SegmentedFontData instances created
+ // per CSSSegmentedFontFace. Whereas in variable font animations, this number
+ // grows rapidly.
+ scoped_refptr<SegmentedFontData>* cached_font_data =
+ font_data_table_.Get(key);
+ if (cached_font_data && (*cached_font_data) &&
+ (*cached_font_data)->NumFaces())
+ return *cached_font_data;
+
+ scoped_refptr<SegmentedFontData> created_font_data;
+ created_font_data = SegmentedFontData::Create();
FontDescription requested_font_description(font_description);
if (!font_selection_capabilities_.HasRange()) {
@@ -131,18 +153,21 @@ scoped_refptr<FontData> CSSSegmentedFontFace::GetFontData(
(*it)->CssFontFace()->GetFontData(requested_font_description)) {
DCHECK(!face_font_data->IsSegmented());
if (face_font_data->IsCustomFont()) {
- font_data->AppendFace(base::AdoptRef(new FontDataForRangeSet(
+ created_font_data->AppendFace(base::AdoptRef(new FontDataForRangeSet(
std::move(face_font_data), (*it)->CssFontFace()->Ranges())));
} else {
- font_data->AppendFace(base::AdoptRef(new FontDataForRangeSetFromCache(
- std::move(face_font_data), (*it)->CssFontFace()->Ranges())));
+ created_font_data->AppendFace(
+ base::AdoptRef(new FontDataForRangeSetFromCache(
+ std::move(face_font_data), (*it)->CssFontFace()->Ranges())));
}
}
}
- if (font_data->NumFaces()) {
+ if (created_font_data->NumFaces()) {
+ scoped_refptr<SegmentedFontData> put_to_cache(created_font_data);
+ font_data_table_.Put(std::move(key), std::move(put_to_cache));
// No release, we have a reference to an object in the cache which should
// retain the ref count it has.
- return font_data;
+ return created_font_data;
}
return nullptr;
@@ -192,7 +217,7 @@ void CSSSegmentedFontFace::Match(const String& text,
}
}
-void CSSSegmentedFontFace::Trace(blink::Visitor* visitor) {
+void CSSSegmentedFontFace::Trace(Visitor* visitor) {
visitor->Trace(first_non_css_connected_face_);
visitor->Trace(font_faces_);
}
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 fad468a96b4..75933f47f7c 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
@@ -31,7 +31,7 @@
#include "third_party/blink/renderer/platform/fonts/segmented_font_data.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#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/lru_cache.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -70,7 +70,7 @@ class CSSSegmentedFontFace final
return approximate_character_count_;
}
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
void PruneTable();
@@ -79,11 +79,10 @@ class CSSSegmentedFontFace final
using FontFaceList = HeapListHashSet<Member<FontFace>>;
FontSelectionCapabilities font_selection_capabilities_;
- HashMap<FontCacheKey,
- scoped_refptr<SegmentedFontData>,
- FontCacheKeyHash,
- FontCacheKeyTraits>
+
+ WTF::LruCache<FontCacheKey, scoped_refptr<SegmentedFontData>>
font_data_table_;
+
// All non-CSS-connected FontFaces are stored after the CSS-connected ones.
FontFaceList font_faces_;
FontFaceList::iterator first_non_css_connected_face_;
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 df7bb9aa9fe..fdda0d6e98b 100644
--- a/chromium/third_party/blink/renderer/core/css/css_selector.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_selector.cc
@@ -297,7 +297,7 @@ PseudoId CSSSelector::GetPseudoId(PseudoType type) {
case kPseudoSlotted:
case kPseudoVideoPersistent:
case kPseudoVideoPersistentAncestor:
- case kPseudoXrImmersiveDomOverlay:
+ case kPseudoXrOverlay:
return kPseudoIdNone;
}
@@ -331,8 +331,6 @@ const static NameToPseudoStruct kPseudoTypeWithoutArgumentsMap[] = {
{"-internal-video-persistent", CSSSelector::kPseudoVideoPersistent},
{"-internal-video-persistent-ancestor",
CSSSelector::kPseudoVideoPersistentAncestor},
- {"-internal-xr-immersive-dom-overlay",
- CSSSelector::kPseudoXrImmersiveDomOverlay},
{"-webkit-any-link", CSSSelector::kPseudoWebkitAnyLink},
{"-webkit-autofill", CSSSelector::kPseudoAutofill},
{"-webkit-drag", CSSSelector::kPseudoDrag},
@@ -410,6 +408,7 @@ const static NameToPseudoStruct kPseudoTypeWithoutArgumentsMap[] = {
{"vertical", CSSSelector::kPseudoVertical},
{"visited", CSSSelector::kPseudoVisited},
{"window-inactive", CSSSelector::kPseudoWindowInactive},
+ {"xr-overlay", CSSSelector::kPseudoXrOverlay},
};
const static NameToPseudoStruct kPseudoTypeWithArgumentsMap[] = {
@@ -597,7 +596,6 @@ void CSSSelector::UpdatePseudoType(const AtomicString& value,
case kPseudoSpatialNavigationInterest:
case kPseudoVideoPersistent:
case kPseudoVideoPersistentAncestor:
- case kPseudoXrImmersiveDomOverlay:
if (mode != kUASheetMode) {
pseudo_type_ = kPseudoUnknown;
break;
@@ -673,6 +671,7 @@ void CSSSelector::UpdatePseudoType(const AtomicString& value,
case kPseudoVisited:
case kPseudoWebkitAnyLink:
case kPseudoWindowInactive:
+ case kPseudoXrOverlay:
if (match_ != kPseudoClass)
pseudo_type_ = kPseudoUnknown;
break;
@@ -787,7 +786,7 @@ const CSSSelector* CSSSelector::SerializeCompound(
case kPseudoLang:
case kPseudoState:
builder.Append('(');
- builder.Append(simple_selector->Argument());
+ SerializeIdentifier(simple_selector->Argument(), builder);
builder.Append(')');
break;
case kPseudoNot:
@@ -804,13 +803,19 @@ const CSSSelector* CSSSelector::SerializeCompound(
}
} else if (simple_selector->match_ == kPseudoElement) {
builder.Append("::");
- builder.Append(simple_selector->SerializingValue());
+ SerializeIdentifier(simple_selector->SerializingValue(), builder);
switch (simple_selector->GetPseudoType()) {
- case kPseudoPart:
- builder.Append('(');
- builder.Append(simple_selector->Argument());
+ case kPseudoPart: {
+ char separator = '(';
+ for (AtomicString part : *simple_selector->PartNames()) {
+ builder.Append(separator);
+ if (separator == '(')
+ separator = ' ';
+ SerializeIdentifier(part, builder);
+ }
builder.Append(')');
break;
+ }
default:
break;
}
@@ -1211,4 +1216,10 @@ bool CSSSelector::RareData::MatchNth(unsigned unsigned_count) {
return (NthBValue() - count) % (-NthAValue()) == 0;
}
+void CSSSelector::SetPartNames(
+ std::unique_ptr<Vector<AtomicString>> part_names) {
+ CreateRareData();
+ data_.rare_data_->part_names_ = std::move(part_names);
+}
+
} // namespace blink
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 3e30168b202..4e63bd24291 100644
--- a/chromium/third_party/blink/renderer/core/css/css_selector.h
+++ b/chromium/third_party/blink/renderer/core/css/css_selector.h
@@ -231,9 +231,10 @@ class CORE_EXPORT CSSSelector {
kPseudoPictureInPicture,
kPseudoInRange,
kPseudoOutOfRange,
+ kPseudoXrOverlay,
// Pseudo elements in UA ShadowRoots. Available in any stylesheets.
kPseudoWebKitCustomElement,
- // Pseudo elements in UA ShadowRoots. Availble only in UA stylesheets.
+ // Pseudo elements in UA ShadowRoots. Available only in UA stylesheets.
kPseudoBlinkInternalElement,
kPseudoCue,
kPseudoFutureCue,
@@ -253,7 +254,6 @@ class CORE_EXPORT CSSSelector {
kPseudoSlotted,
kPseudoVideoPersistent,
kPseudoVideoPersistentAncestor,
- kPseudoXrImmersiveDomOverlay,
};
enum AttributeMatchType {
@@ -303,6 +303,9 @@ class CORE_EXPORT CSSSelector {
const CSSSelectorList* SelectorList() const {
return has_rare_data_ ? data_.rare_data_->selector_list_.get() : nullptr;
}
+ const Vector<AtomicString>* PartNames() const {
+ return has_rare_data_ ? data_.rare_data_->part_names_.get() : nullptr;
+ }
#ifndef NDEBUG
void Show() const;
@@ -314,6 +317,7 @@ class CORE_EXPORT CSSSelector {
void SetAttribute(const QualifiedName&, AttributeMatchType);
void SetArgument(const AtomicString&);
void SetSelectorList(std::unique_ptr<CSSSelectorList>);
+ void SetPartNames(std::unique_ptr<Vector<AtomicString>>);
void SetNth(int a, int b);
bool MatchNth(unsigned count) const;
@@ -448,6 +452,8 @@ class CORE_EXPORT CSSSelector {
AtomicString argument_; // Used for :contains, :lang, :nth-*
std::unique_ptr<CSSSelectorList>
selector_list_; // Used for :-webkit-any and :not
+ std::unique_ptr<Vector<AtomicString>>
+ part_names_; // Used for ::part() selectors.
private:
RareData(const AtomicString& value);
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 6e143c94af0..44e63a470b9 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(blink::Visitor* visitor) {
+void CSSSelectorWatch::Trace(Visitor* visitor) {
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 16df789b574..059fd4c0138 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void CallbackSelectorChangeTimerFired(TimerBase*);
diff --git a/chromium/third_party/blink/renderer/core/css/css_selector_watch_test.cc b/chromium/third_party/blink/renderer/core/css/css_selector_watch_test.cc
index 55351d77d3e..46e58f5f810 100644
--- a/chromium/third_party/blink/renderer/core/css/css_selector_watch_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_selector_watch_test.cc
@@ -33,7 +33,7 @@ void CSSSelectorWatchTest::ClearAddedRemoved(CSSSelectorWatch& watch) {
}
TEST_F(CSSSelectorWatchTest, RecalcOnDocumentChange) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<div>
<span id='x' class='a'></span>
<span id='y' class='b'><span></span></span>
diff --git a/chromium/third_party/blink/renderer/core/css/css_shadow_value.cc b/chromium/third_party/blink/renderer/core/css/css_shadow_value.cc
index 49972caaba0..5ac6c6b49a3 100644
--- a/chromium/third_party/blink/renderer/core/css/css_shadow_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_shadow_value.cc
@@ -77,7 +77,7 @@ bool CSSShadowValue::Equals(const CSSShadowValue& other) const {
DataEquivalent(style, other.style);
}
-void CSSShadowValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSShadowValue::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(x);
visitor->Trace(y);
visitor->Trace(blur);
diff --git a/chromium/third_party/blink/renderer/core/css/css_shadow_value.h b/chromium/third_party/blink/renderer/core/css/css_shadow_value.h
index 34223f84e0c..9cd0d954129 100644
--- a/chromium/third_party/blink/renderer/core/css/css_shadow_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_shadow_value.h
@@ -52,7 +52,7 @@ class CORE_EXPORT CSSShadowValue : public CSSValue {
Member<CSSIdentifierValue> style;
Member<CSSValue> color;
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
};
template <>
diff --git a/chromium/third_party/blink/renderer/core/css/css_string_value.cc b/chromium/third_party/blink/renderer/core/css/css_string_value.cc
index b98811386e8..3795a102590 100644
--- a/chromium/third_party/blink/renderer/core/css/css_string_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_string_value.cc
@@ -16,7 +16,7 @@ String CSSStringValue::CustomCSSText() const {
return SerializeString(string_);
}
-void CSSStringValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSStringValue::TraceAfterDispatch(blink::Visitor* visitor) const {
CSSValue::TraceAfterDispatch(visitor);
}
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 b2b71ee05f3..2641f37aa26 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
@@ -23,7 +23,7 @@ class CSSStringValue : public CSSValue {
return string_ == other.string_;
}
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
String 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 697a1b6eb9c..5ab57f1fb4e 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
@@ -78,7 +78,8 @@ bool HasCSSPropertyNamePrefix(const AtomicString& property_name,
return false;
}
-CSSPropertyID ParseCSSPropertyID(const AtomicString& property_name) {
+CSSPropertyID ParseCSSPropertyID(const ExecutionContext* execution_context,
+ const AtomicString& property_name) {
unsigned length = property_name.length();
if (!length)
return CSSPropertyID::kInvalid;
@@ -117,7 +118,7 @@ CSSPropertyID ParseCSSPropertyID(const AtomicString& property_name) {
return CSSPropertyID::kInvalid;
String prop_name = builder.ToString();
- return unresolvedCSSPropertyID(prop_name);
+ return unresolvedCSSPropertyID(execution_context, prop_name);
}
// When getting properties on CSSStyleDeclarations, the name used from
@@ -129,28 +130,36 @@ CSSPropertyID ParseCSSPropertyID(const AtomicString& property_name) {
// Example: 'backgroundPositionY' -> 'background-position-y'
//
// Also, certain prefixes such as 'css-' are stripped.
-CSSPropertyID CssPropertyInfo(const AtomicString& name) {
+CSSPropertyID CssPropertyInfo(const ExecutionContext* execution_context,
+ const AtomicString& name) {
typedef HashMap<String, CSSPropertyID> CSSPropertyIDMap;
DEFINE_STATIC_LOCAL(CSSPropertyIDMap, map, ());
CSSPropertyIDMap::iterator iter = map.find(name);
if (iter != map.end())
return iter->value;
- CSSPropertyID unresolved_property = ParseCSSPropertyID(name);
+ CSSPropertyID unresolved_property =
+ ParseCSSPropertyID(execution_context, name);
if (unresolved_property == CSSPropertyID::kVariable)
unresolved_property = CSSPropertyID::kInvalid;
map.insert(name, unresolved_property);
DCHECK(!isValidCSSPropertyID(unresolved_property) ||
CSSProperty::Get(resolveCSSPropertyID(unresolved_property))
- .IsWebExposed());
+ .IsWebExposed(execution_context));
return unresolved_property;
}
} // namespace
+void CSSStyleDeclaration::Trace(Visitor* visitor) {
+ ExecutionContextClient::Trace(visitor);
+ ScriptWrappable::Trace(visitor);
+}
+
String CSSStyleDeclaration::AnonymousNamedGetter(const AtomicString& name) {
// Search the style declaration.
- CSSPropertyID unresolved_property = CssPropertyInfo(name);
+ CSSPropertyID unresolved_property =
+ CssPropertyInfo(GetExecutionContext(), name);
// Do not handle non-property names.
if (!isValidCSSPropertyID(unresolved_property))
@@ -159,16 +168,17 @@ String CSSStyleDeclaration::AnonymousNamedGetter(const AtomicString& name) {
return GetPropertyValueInternal(resolveCSSPropertyID(unresolved_property));
}
-bool CSSStyleDeclaration::AnonymousNamedSetter(ScriptState* script_state,
- const AtomicString& name,
- const String& value) {
+NamedPropertySetterResult CSSStyleDeclaration::AnonymousNamedSetter(
+ ScriptState* script_state,
+ const AtomicString& name,
+ const String& value) {
const ExecutionContext* execution_context =
ExecutionContext::From(script_state);
if (!execution_context)
- return false;
- CSSPropertyID unresolved_property = CssPropertyInfo(name);
+ return NamedPropertySetterResult::kDidNotIntercept;
+ CSSPropertyID unresolved_property = CssPropertyInfo(execution_context, name);
if (!isValidCSSPropertyID(unresolved_property))
- return false;
+ return NamedPropertySetterResult::kDidNotIntercept;
// We create the ExceptionState manually due to performance issues: adding
// [RaisesException] to the IDL causes the bindings layer to expensively
// create a std::string to set the ExceptionState's |property_name| argument,
@@ -182,8 +192,8 @@ bool CSSStyleDeclaration::AnonymousNamedSetter(ScriptState* script_state,
execution_context->GetSecureContextMode(),
exception_state);
if (exception_state.HadException())
- return false;
- return true;
+ return NamedPropertySetterResult::kIntercepted;
+ return NamedPropertySetterResult::kIntercepted;
}
void CSSStyleDeclaration::NamedPropertyEnumerator(Vector<String>& names,
@@ -191,17 +201,19 @@ void CSSStyleDeclaration::NamedPropertyEnumerator(Vector<String>& names,
typedef Vector<String, numCSSProperties - 1> PreAllocatedPropertyVector;
DEFINE_STATIC_LOCAL(PreAllocatedPropertyVector, property_names, ());
+ const ExecutionContext* execution_context = GetExecutionContext();
+
if (property_names.IsEmpty()) {
for (CSSPropertyID property_id : CSSPropertyIDList()) {
const CSSProperty& property_class =
CSSProperty::Get(resolveCSSPropertyID(property_id));
- if (property_class.IsWebExposed())
+ if (property_class.IsWebExposed(execution_context))
property_names.push_back(property_class.GetJSPropertyName());
}
for (CSSPropertyID property_id : kCSSPropertyAliasList) {
const CSSUnresolvedProperty* property_class =
CSSUnresolvedProperty::GetAliasProperty(property_id);
- if (property_class->IsWebExposed())
+ if (property_class->IsWebExposed(execution_context))
property_names.push_back(property_class->GetJSPropertyName());
}
std::sort(property_names.begin(), property_names.end(),
@@ -212,7 +224,7 @@ void CSSStyleDeclaration::NamedPropertyEnumerator(Vector<String>& names,
bool CSSStyleDeclaration::NamedPropertyQuery(const AtomicString& name,
ExceptionState&) {
- return isValidCSSPropertyID(CssPropertyInfo(name));
+ return isValidCSSPropertyID(CssPropertyInfo(GetExecutionContext(), name));
}
} // namespace blink
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 8292a45eda3..ad53e5b954a 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
@@ -25,7 +25,9 @@
#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/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -37,12 +39,16 @@ class CSSValue;
class ExceptionState;
enum class SecureContextMode;
-class CORE_EXPORT CSSStyleDeclaration : public ScriptWrappable {
+class CORE_EXPORT CSSStyleDeclaration : public ScriptWrappable,
+ public ExecutionContextClient {
DEFINE_WRAPPERTYPEINFO();
+ USING_GARBAGE_COLLECTED_MIXIN(CSSStyleDeclaration);
public:
~CSSStyleDeclaration() override = default;
+ void Trace(Visitor* visitor) override;
+
virtual CSSRule* parentRule() const = 0;
String cssFloat() { return GetPropertyValueInternal(CSSPropertyID::kFloat); }
void setCSSFloat(const ExecutionContext* execution_context,
@@ -93,14 +99,15 @@ class CORE_EXPORT CSSStyleDeclaration : public ScriptWrappable {
// Note: AnonymousNamedSetter() can end up throwing an exception via
// SetPropertyInternal() even though it does not take an |ExceptionState| as
// an argument (see bug 829408).
- bool AnonymousNamedSetter(ScriptState*,
- const AtomicString& name,
- const String& value);
+ NamedPropertySetterResult AnonymousNamedSetter(ScriptState*,
+ const AtomicString& name,
+ const String& value);
void NamedPropertyEnumerator(Vector<String>& names, ExceptionState&);
bool NamedPropertyQuery(const AtomicString&, ExceptionState&);
protected:
- CSSStyleDeclaration() = default;
+ CSSStyleDeclaration(ExecutionContext* context)
+ : ExecutionContextClient(context) {}
private:
DISALLOW_COPY_AND_ASSIGN(CSSStyleDeclaration);
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 b612a98bd0e..0cfed7f3602 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(blink::Visitor* visitor) {
+void CSSStyleRule::Trace(Visitor* visitor) {
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 1ede742db9d..a4e648bb88a 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,7 +54,7 @@ class CORE_EXPORT CSSStyleRule final : public CSSRule {
// FIXME: Not CSSOM. Remove.
StyleRule* GetStyleRule() const { return style_rule_.Get(); }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
CSSRule::Type type() const override { return 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 0a7e0f3a169..096dc2743b7 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
@@ -24,9 +24,9 @@
#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_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_css_style_sheet_init.h"
#include "third_party/blink/renderer/core/css/css_import_rule.h"
#include "third_party/blink/renderer/core/css/css_rule_list.h"
-#include "third_party/blink/renderer/core/css/css_style_sheet_init.h"
#include "third_party/blink/renderer/core/css/media_list.h"
#include "third_party/blink/renderer/core/css/parser/css_parser.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_context.h"
@@ -55,7 +55,7 @@ class StyleSheetCSSRuleList final : public CSSRuleList {
public:
StyleSheetCSSRuleList(CSSStyleSheet* sheet) : style_sheet_(sheet) {}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(style_sheet_);
CSSRuleList::Trace(visitor);
}
@@ -106,10 +106,12 @@ CSSStyleSheet* CSSStyleSheet::Create(Document& document,
sheet->ClearOwnerRule();
contents->RegisterClient(sheet);
scoped_refptr<MediaQuerySet> media_query_set;
- if (options->media().IsString())
- media_query_set = MediaQuerySet::Create(options->media().GetAsString());
- else
+ if (options->media().IsString()) {
+ media_query_set = MediaQuerySet::Create(options->media().GetAsString(),
+ document.GetExecutionContext());
+ } else {
media_query_set = options->media().GetAsMediaList()->Queries()->Copy();
+ }
auto* media_list = MakeGarbageCollected<MediaList>(
media_query_set, const_cast<CSSStyleSheet*>(sheet));
sheet->SetMedia(media_list);
@@ -450,17 +452,21 @@ int CSSStyleSheet::addRule(const String& selector,
}
ScriptPromise CSSStyleSheet::replace(ScriptState* script_state,
- const String& text,
- ExceptionState& exception_state) {
+ const String& text) {
if (!is_constructed_) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kNotAllowedError,
- "Can't call replace on non-constructed CSSStyleSheets.");
+ return ScriptPromise::RejectWithDOMException(
+ script_state,
+ MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kNotAllowedError,
+ "Can't call replace on non-constructed CSSStyleSheets."));
}
// Parses the text synchronously, loads import rules asynchronously.
- SetText(text, true /* allow_import_rules */, exception_state);
+ SetText(text, true /* allow_import_rules */, nullptr);
if (!IsLoading())
return ScriptPromise::Cast(script_state, ToV8(this, script_state));
+ // We're loading a stylesheet that contains @import rules. This is deprecated.
+ Deprecation::CountDeprecation(OwnerDocument(),
+ WebFeature::kCssStyleSheetReplaceWithImport);
resolver_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
return resolver_->Promise();
}
@@ -468,11 +474,11 @@ ScriptPromise CSSStyleSheet::replace(ScriptState* script_state,
void CSSStyleSheet::replaceSync(const String& text,
ExceptionState& exception_state) {
if (!is_constructed_) {
- exception_state.ThrowDOMException(
+ return exception_state.ThrowDOMException(
DOMExceptionCode::kNotAllowedError,
"Can't call replaceSync on non-constructed CSSStyleSheets.");
}
- SetText(text, false /* allow_import_rules */, exception_state);
+ SetText(text, false /* allow_import_rules */, &exception_state);
}
void CSSStyleSheet::ResolveReplacePromiseIfNeeded(bool load_error_occured) {
@@ -565,16 +571,17 @@ void CSSStyleSheet::SetLoadCompleted(bool completed) {
void CSSStyleSheet::SetText(const String& text,
bool allow_import_rules,
- ExceptionState& exception_state) {
+ ExceptionState* exception_state) {
child_rule_cssom_wrappers_.clear();
CSSStyleSheet::RuleMutationScope mutation_scope(this);
contents_->ClearRules();
if (contents_->ParseString(text, allow_import_rules) ==
ParseSheetResult::kHasUnallowedImportRule) {
- exception_state.ThrowDOMException(DOMExceptionCode::kNotAllowedError,
- "@import rules are not allowed when "
- "creating stylesheet synchronously.");
+ DCHECK(exception_state);
+ exception_state->ThrowDOMException(DOMExceptionCode::kNotAllowedError,
+ "@import rules are not allowed when "
+ "creating stylesheet synchronously.");
}
}
@@ -621,7 +628,7 @@ bool CSSStyleSheet::CanBeActivated(
return true;
}
-void CSSStyleSheet::Trace(blink::Visitor* visitor) {
+void CSSStyleSheet::Trace(Visitor* visitor) {
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 e6dbe47fb96..84d53558a22 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
@@ -100,9 +100,7 @@ class CORE_EXPORT CSSStyleSheet final : public StyleSheet {
deleteRule(index, exception_state);
}
- ScriptPromise replace(ScriptState* script_state,
- const String& text,
- ExceptionState&);
+ ScriptPromise replace(ScriptState* script_state, const String& text);
void replaceSync(const String& text, ExceptionState&);
void ResolveReplacePromiseIfNeeded(bool load_error_occured);
@@ -160,7 +158,7 @@ class CORE_EXPORT CSSStyleSheet final : public StyleSheet {
~RuleMutationScope();
private:
- Member<CSSStyleSheet> style_sheet_;
+ CSSStyleSheet* style_sheet_;
DISALLOW_COPY_AND_ASSIGN(RuleMutationScope);
};
@@ -176,7 +174,7 @@ class CORE_EXPORT CSSStyleSheet final : public StyleSheet {
~InspectorMutationScope();
private:
- Member<CSSStyleSheet> style_sheet_;
+ CSSStyleSheet* style_sheet_;
DISALLOW_COPY_AND_ASSIGN(InspectorMutationScope);
};
@@ -191,7 +189,9 @@ class CORE_EXPORT CSSStyleSheet final : public StyleSheet {
bool SheetLoaded();
bool LoadCompleted() const { return load_completed_; }
void StartLoadingDynamicSheet();
- void SetText(const String&, bool allow_import_rules, ExceptionState&);
+ // If `allow_import_rules` is false, an ExceptionState pointer must be
+ // provided, otherwise it can be null.
+ void SetText(const String&, bool allow_import_rules, ExceptionState*);
void SetMedia(MediaList*);
void SetAlternateFromConstructor(bool);
bool CanBeActivated(const String& current_preferrable_name) const;
@@ -202,7 +202,7 @@ class CORE_EXPORT CSSStyleSheet final : public StyleSheet {
bool IsConstructed() { return is_constructed_; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
bool IsAlternate() const;
diff --git a/chromium/third_party/blink/renderer/core/css/css_style_sheet.idl b/chromium/third_party/blink/renderer/core/css/css_style_sheet.idl
index 94b6f421d26..7f075cfe7fb 100644
--- a/chromium/third_party/blink/renderer/core/css/css_style_sheet.idl
+++ b/chromium/third_party/blink/renderer/core/css/css_style_sheet.idl
@@ -21,21 +21,19 @@
// https://drafts.csswg.org/cssom/#the-cssstylesheet-interface
[
- ConstructorCallWith=Document,
- RaisesException=Constructor,
- Constructor(optional CSSStyleSheetInit options),
Exposed=Window
] interface CSSStyleSheet : StyleSheet {
+ [CallWith=Document, RaisesException] constructor(optional CSSStyleSheetInit options = {});
readonly attribute CSSRule? ownerRule;
[SameObject, RaisesException] readonly attribute CSSRuleList cssRules;
[RaisesException] unsigned long insertRule(DOMString rule, optional unsigned long index = 0);
[RaisesException] void deleteRule(unsigned long index);
- [MeasureAs=CSSStyleSheetReplace, CallWith=ScriptState, RaisesException] Promise<CSSStyleSheet> replace(DOMString text);
+ [MeasureAs=CSSStyleSheetReplace, CallWith=ScriptState] Promise<CSSStyleSheet> replace(DOMString text);
[MeasureAs=CSSStyleSheetReplaceSync, RaisesException] void replaceSync(DOMString text);
// Non-standard APIs
[MeasureAs=CSSStyleSheetRules, RaisesException] readonly attribute CSSRuleList rules;
- [MeasureAs=CSSStyleSheetAddRule, RaisesException] long addRule([DefaultValue=Undefined] optional DOMString selector, [DefaultValue=Undefined] optional DOMString style, optional unsigned long index);
- [MeasureAs=CSSStyleSheetRemoveRule, RaisesException] void removeRule([DefaultValue=Undefined] optional unsigned long index);
+ [MeasureAs=CSSStyleSheetAddRule, RaisesException] long addRule(optional DOMString selector = "undefined", optional DOMString style = "undefined", optional unsigned long index);
+ [MeasureAs=CSSStyleSheetRemoveRule, RaisesException] void removeRule(optional unsigned long index = 0);
};
diff --git a/chromium/third_party/blink/renderer/core/css/css_style_sheet_test.cc b/chromium/third_party/blink/renderer/core/css/css_style_sheet_test.cc
index d008ae92ffe..2ecb48e21a4 100644
--- a/chromium/third_party/blink/renderer/core/css/css_style_sheet_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_style_sheet_test.cc
@@ -11,10 +11,14 @@
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_css_style_sheet.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_css_style_sheet_init.h"
+#include "third_party/blink/renderer/core/css/css_rule.h"
#include "third_party/blink/renderer/core/css/css_rule_list.h"
-#include "third_party/blink/renderer/core/css/css_style_sheet_init.h"
#include "third_party/blink/renderer/core/css/media_list.h"
+#include "third_party/blink/renderer/core/css/style_sheet_contents.h"
+#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
+#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
namespace blink {
@@ -64,7 +68,7 @@ TEST_F(CSSStyleSheetTest,
EXPECT_EQ(sheet->ownerNode(), nullptr);
EXPECT_EQ(sheet->ownerRule(), nullptr);
EXPECT_EQ(sheet->media()->length(), 2U);
- EXPECT_EQ(sheet->media()->mediaText(), init->media().GetAsString());
+ EXPECT_EQ(sheet->media()->mediaText(nullptr), init->media().GetAsString());
EXPECT_EQ(sheet->title(), init->title());
EXPECT_TRUE(sheet->AlternateFromConstructor());
EXPECT_TRUE(sheet->disabled());
@@ -99,4 +103,74 @@ TEST_F(CSSStyleSheetTest,
EXPECT_EQ(shadow_b.AdoptedStyleSheets().size(), 1u);
}
+TEST_F(CSSStyleSheetTest, AdoptedStyleSheetMediaQueryEvalChange) {
+ SetBodyInnerHTML("<div id=green></div><div id=blue></div>");
+
+ Element* green = GetDocument().getElementById("green");
+ Element* blue = GetDocument().getElementById("blue");
+
+ CSSStyleSheetInit* init = CSSStyleSheetInit::Create();
+ CSSStyleSheet* sheet =
+ CSSStyleSheet::Create(GetDocument(), init, ASSERT_NO_EXCEPTION);
+ sheet->replaceSync(
+ "@media (max-width: 300px) {#green{color:green}} @media "
+ "(prefers-reduced-motion: reduce) {#blue{color:blue}}",
+ ASSERT_NO_EXCEPTION);
+
+ HeapVector<Member<CSSStyleSheet>> empty_adopted_sheets;
+ HeapVector<Member<CSSStyleSheet>> adopted_sheets;
+ adopted_sheets.push_back(sheet);
+
+ GetDocument().SetAdoptedStyleSheets(adopted_sheets);
+ UpdateAllLifecyclePhasesForTest();
+
+ ASSERT_TRUE(sheet->Contents());
+ ASSERT_TRUE(sheet->Contents()->HasRuleSet());
+ RuleSet* rule_set = &sheet->Contents()->GetRuleSet();
+
+ EXPECT_EQ(Color::kBlack, green->GetComputedStyle()->VisitedDependentColor(
+ GetCSSPropertyColor()));
+
+ GetDocument().SetAdoptedStyleSheets(empty_adopted_sheets);
+ UpdateAllLifecyclePhasesForTest();
+
+ ASSERT_TRUE(sheet->Contents()->HasRuleSet());
+ EXPECT_EQ(rule_set, &sheet->Contents()->GetRuleSet());
+ EXPECT_EQ(Color::kBlack, green->GetComputedStyle()->VisitedDependentColor(
+ GetCSSPropertyColor()));
+
+ GetDocument().View()->SetLayoutSizeFixedToFrameSize(false);
+ GetDocument().View()->SetLayoutSize(IntSize(200, 500));
+ UpdateAllLifecyclePhasesForTest();
+
+ GetDocument().SetAdoptedStyleSheets(adopted_sheets);
+ UpdateAllLifecyclePhasesForTest();
+
+ ASSERT_TRUE(sheet->Contents()->HasRuleSet());
+ EXPECT_NE(rule_set, &sheet->Contents()->GetRuleSet());
+ EXPECT_EQ(
+ MakeRGB(0, 128, 0),
+ green->GetComputedStyle()->VisitedDependentColor(GetCSSPropertyColor()));
+ EXPECT_EQ(Color::kBlack, blue->GetComputedStyle()->VisitedDependentColor(
+ GetCSSPropertyColor()));
+
+ GetDocument().SetAdoptedStyleSheets(empty_adopted_sheets);
+ GetDocument().GetSettings()->SetPrefersReducedMotion(true);
+ UpdateAllLifecyclePhasesForTest();
+
+ EXPECT_EQ(Color::kBlack, green->GetComputedStyle()->VisitedDependentColor(
+ GetCSSPropertyColor()));
+ EXPECT_EQ(Color::kBlack, blue->GetComputedStyle()->VisitedDependentColor(
+ GetCSSPropertyColor()));
+
+ GetDocument().SetAdoptedStyleSheets(adopted_sheets);
+ UpdateAllLifecyclePhasesForTest();
+
+ EXPECT_EQ(
+ MakeRGB(0, 128, 0),
+ green->GetComputedStyle()->VisitedDependentColor(GetCSSPropertyColor()));
+ EXPECT_EQ(MakeRGB(0, 0, 255), blue->GetComputedStyle()->VisitedDependentColor(
+ GetCSSPropertyColor()));
+}
+
} // namespace blink
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 70fd25fc121..1a3977717f2 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
@@ -42,7 +42,7 @@ bool CouldConsumeReservedKeyword(CSSParserTokenRange range) {
const CSSValue* ConsumeSingleType(const CSSSyntaxComponent& syntax,
CSSParserTokenRange& range,
- const CSSParserContext* context) {
+ const CSSParserContext& context) {
switch (syntax.GetType()) {
case CSSSyntaxType::kIdent:
if (range.Peek().GetType() == kIdentToken &&
@@ -52,46 +52,54 @@ const CSSValue* ConsumeSingleType(const CSSSyntaxComponent& syntax,
AtomicString(syntax.GetString()));
}
return nullptr;
- case CSSSyntaxType::kLength:
+ case CSSSyntaxType::kLength: {
+ CSSParserContext::ParserModeOverridingScope scope(context,
+ kHTMLStandardMode);
return css_property_parser_helpers::ConsumeLength(
- range, kHTMLStandardMode, ValueRange::kValueRangeAll);
+ range, context, ValueRange::kValueRangeAll);
+ }
case CSSSyntaxType::kNumber:
return css_property_parser_helpers::ConsumeNumber(
- range, ValueRange::kValueRangeAll);
+ range, context, ValueRange::kValueRangeAll);
case CSSSyntaxType::kPercentage:
return css_property_parser_helpers::ConsumePercent(
- range, ValueRange::kValueRangeAll);
- case CSSSyntaxType::kLengthPercentage:
+ range, context, ValueRange::kValueRangeAll);
+ case CSSSyntaxType::kLengthPercentage: {
+ CSSParserContext::ParserModeOverridingScope scope(context,
+ kHTMLStandardMode);
return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, kHTMLStandardMode, ValueRange::kValueRangeAll);
- case CSSSyntaxType::kColor:
- return css_property_parser_helpers::ConsumeColor(range,
- kHTMLStandardMode);
+ range, context, ValueRange::kValueRangeAll);
+ }
+ case CSSSyntaxType::kColor: {
+ CSSParserContext::ParserModeOverridingScope scope(context,
+ kHTMLStandardMode);
+ return css_property_parser_helpers::ConsumeColor(range, context);
+ }
case CSSSyntaxType::kImage:
return css_property_parser_helpers::ConsumeImage(range, context);
case CSSSyntaxType::kUrl:
return css_property_parser_helpers::ConsumeUrl(range, context);
case CSSSyntaxType::kInteger:
- return css_property_parser_helpers::ConsumeIntegerOrNumberCalc(range);
+ return css_property_parser_helpers::ConsumeIntegerOrNumberCalc(range,
+ context);
case CSSSyntaxType::kAngle:
return css_property_parser_helpers::ConsumeAngle(
range, context, base::Optional<WebFeature>());
case CSSSyntaxType::kTime:
return css_property_parser_helpers::ConsumeTime(
- range, ValueRange::kValueRangeAll);
+ range, context, ValueRange::kValueRangeAll);
case CSSSyntaxType::kResolution:
return css_property_parser_helpers::ConsumeResolution(range);
case CSSSyntaxType::kTransformFunction:
- return css_property_parser_helpers::ConsumeTransformValue(range,
- *context);
+ return css_property_parser_helpers::ConsumeTransformValue(range, context);
case CSSSyntaxType::kTransformList:
- return css_property_parser_helpers::ConsumeTransformList(range, *context);
+ return css_property_parser_helpers::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_property_parser_helpers::ConsumeCustomIdent(range, context);
default:
NOTREACHED();
return nullptr;
@@ -100,7 +108,7 @@ const CSSValue* ConsumeSingleType(const CSSSyntaxComponent& syntax,
const CSSValue* ConsumeSyntaxComponent(const CSSSyntaxComponent& syntax,
CSSParserTokenRange range,
- const CSSParserContext* context) {
+ const CSSParserContext& context) {
// CSS-wide keywords are already handled by the CSSPropertyParser
if (syntax.GetRepeat() == CSSSyntaxRepeat::kSpaceSeparated) {
CSSValueList* list = CSSValueList::CreateSpaceSeparated();
@@ -132,7 +140,7 @@ const CSSValue* ConsumeSyntaxComponent(const CSSSyntaxComponent& syntax,
} // namespace
const CSSValue* CSSSyntaxDefinition::Parse(CSSParserTokenRange range,
- const CSSParserContext* context,
+ const CSSParserContext& context,
bool is_animation_tainted) const {
if (IsTokenStream()) {
// TODO(crbug.com/579788): Implement 'revert'.
@@ -140,7 +148,7 @@ const CSSValue* CSSSyntaxDefinition::Parse(CSSParserTokenRange range,
if (CouldConsumeReservedKeyword(range))
return nullptr;
return CSSVariableParser::ParseRegisteredPropertyValue(
- range, *context, false, is_animation_tainted);
+ range, context, false, is_animation_tainted);
}
range.ConsumeWhitespace();
for (const CSSSyntaxComponent& component : syntax_components_) {
@@ -148,7 +156,7 @@ const CSSValue* CSSSyntaxDefinition::Parse(CSSParserTokenRange range,
ConsumeSyntaxComponent(component, range, context))
return result;
}
- return CSSVariableParser::ParseRegisteredPropertyValue(range, *context, true,
+ return CSSVariableParser::ParseRegisteredPropertyValue(range, context, true,
is_animation_tainted);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_syntax_definition.h b/chromium/third_party/blink/renderer/core/css/css_syntax_definition.h
index 98f778510b1..60a2308039d 100644
--- a/chromium/third_party/blink/renderer/core/css/css_syntax_definition.h
+++ b/chromium/third_party/blink/renderer/core/css/css_syntax_definition.h
@@ -17,7 +17,7 @@ class CSSValue;
class CORE_EXPORT CSSSyntaxDefinition {
public:
const CSSValue* Parse(CSSParserTokenRange,
- const CSSParserContext*,
+ const CSSParserContext&,
bool is_animation_tainted) const;
bool IsTokenStream() const {
return syntax_components_.size() == 1 &&
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 fabc8ce438b..874c1d50e6d 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
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/css/css_test_helpers.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_property_definition.h"
#include "third_party/blink/renderer/core/css/css_custom_ident_value.h"
#include "third_party/blink/renderer/core/css/css_rule_list.h"
#include "third_party/blink/renderer/core/css/css_style_sheet.h"
@@ -15,7 +16,6 @@
#include "third_party/blink/renderer/core/css/parser/css_tokenizer.h"
#include "third_party/blink/renderer/core/css/properties/css_property_ref.h"
#include "third_party/blink/renderer/core/css/properties/longhand.h"
-#include "third_party/blink/renderer/core/css/property_definition.h"
#include "third_party/blink/renderer/core/css/property_registration.h"
#include "third_party/blink/renderer/core/css/property_registry.h"
#include "third_party/blink/renderer/core/css/rule_set.h"
@@ -73,8 +73,8 @@ void RegisterProperty(Document& document,
property_definition->setSyntax(syntax);
property_definition->setInitialValue(initial_value);
property_definition->setInherits(is_inherited);
- PropertyRegistration::registerProperty(&document, property_definition,
- exception_state);
+ PropertyRegistration::registerProperty(document.GetExecutionContext(),
+ property_definition, exception_state);
ASSERT_FALSE(exception_state.HadException());
}
@@ -107,5 +107,13 @@ const CSSValue* ParseLonghand(Document& document,
return longhand->ParseSingleValue(range, *context, local_context);
}
+const CSSPropertyValueSet* ParseDeclarationBlock(const String& block_text,
+ CSSParserMode mode) {
+ auto* set = MakeGarbageCollected<MutableCSSPropertyValueSet>(mode);
+ set->ParseDeclarationList(block_text, SecureContextMode::kSecureContext,
+ nullptr);
+ return set;
+}
+
} // namespace css_test_helpers
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/css_test_helpers.h b/chromium/third_party/blink/renderer/core/css/css_test_helpers.h
index 3a9c1efc4dd..9b220f7659c 100644
--- a/chromium/third_party/blink/renderer/core/css/css_test_helpers.h
+++ b/chromium/third_party/blink/renderer/core/css/css_test_helpers.h
@@ -54,6 +54,9 @@ const CSSValue* CreateCustomIdent(AtomicString);
const CSSValue* ParseLonghand(Document& document,
const CSSProperty&,
const String& value);
+const CSSPropertyValueSet* ParseDeclarationBlock(
+ const String& block_text,
+ CSSParserMode mode = kHTMLStandardMode);
} // namespace css_test_helpers
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/css_timing_function_value.h b/chromium/third_party/blink/renderer/core/css/css_timing_function_value.h
index 5cab5ad10fe..26e09608ef6 100644
--- a/chromium/third_party/blink/renderer/core/css/css_timing_function_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_timing_function_value.h
@@ -53,7 +53,7 @@ class CSSCubicBezierTimingFunctionValue : public CSSValue {
bool Equals(const CSSCubicBezierTimingFunctionValue&) const;
- void TraceAfterDispatch(blink::Visitor* visitor) {
+ void TraceAfterDispatch(blink::Visitor* visitor) const {
CSSValue::TraceAfterDispatch(visitor);
}
@@ -66,13 +66,6 @@ class CSSCubicBezierTimingFunctionValue : public CSSValue {
class CSSStepsTimingFunctionValue : public CSSValue {
public:
- static CSSStepsTimingFunctionValue* Create(
- int steps,
- StepsTimingFunction::StepPosition step_position) {
- return MakeGarbageCollected<CSSStepsTimingFunctionValue>(steps,
- step_position);
- }
-
CSSStepsTimingFunctionValue(int steps,
StepsTimingFunction::StepPosition step_position)
: CSSValue(kStepsTimingFunctionClass),
@@ -88,7 +81,7 @@ class CSSStepsTimingFunctionValue : public CSSValue {
bool Equals(const CSSStepsTimingFunctionValue&) const;
- 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_to_length_conversion_data.cc b/chromium/third_party/blink/renderer/core/css/css_to_length_conversion_data.cc
index 13008d87853..f7c4f68e909 100644
--- a/chromium/third_party/blink/renderer/core/css/css_to_length_conversion_data.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_to_length_conversion_data.cc
@@ -121,6 +121,12 @@ double CSSToLengthConversionData::ViewportMaxPercent() const {
return std::max(viewport_size_.Width(), viewport_size_.Height()) / 100;
}
+float CSSToLengthConversionData::EmFontSize() const {
+ if (style_)
+ const_cast<ComputedStyle*>(style_)->SetHasEmUnits();
+ return font_sizes_.Em();
+}
+
float CSSToLengthConversionData::RemFontSize() const {
if (style_)
const_cast<ComputedStyle*>(style_)->SetHasRemUnits();
diff --git a/chromium/third_party/blink/renderer/core/css/css_to_length_conversion_data.h b/chromium/third_party/blink/renderer/core/css/css_to_length_conversion_data.h
index 9af029c517e..cad9d5eaad8 100644
--- a/chromium/third_party/blink/renderer/core/css/css_to_length_conversion_data.h
+++ b/chromium/third_party/blink/renderer/core/css/css_to_length_conversion_data.h
@@ -46,7 +46,7 @@ class LayoutView;
class Font;
class CORE_EXPORT CSSToLengthConversionData {
- DISALLOW_NEW();
+ STACK_ALLOCATED();
public:
class CORE_EXPORT FontSizes {
@@ -97,7 +97,7 @@ class CORE_EXPORT CSSToLengthConversionData {
float Zoom() const { return zoom_; }
- float EmFontSize() const { return font_sizes_.Em(); }
+ float EmFontSize() const;
float RemFontSize() const;
float ExFontSize() const;
float ChFontSize() const;
diff --git a/chromium/third_party/blink/renderer/core/css/css_unicode_range_value.h b/chromium/third_party/blink/renderer/core/css/css_unicode_range_value.h
index 506c0806947..4db1508cd36 100644
--- a/chromium/third_party/blink/renderer/core/css/css_unicode_range_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_unicode_range_value.h
@@ -45,7 +45,7 @@ class CSSUnicodeRangeValue : public CSSValue {
bool Equals(const CSSUnicodeRangeValue&) const;
- 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_unset_value.h b/chromium/third_party/blink/renderer/core/css/css_unset_value.h
index 91f23e06e35..dfbf7a8fd84 100644
--- a/chromium/third_party/blink/renderer/core/css/css_unset_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_unset_value.h
@@ -26,7 +26,7 @@ class CORE_EXPORT CSSUnsetValue : public CSSValue {
bool Equals(const CSSUnsetValue&) 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_uri_value.cc b/chromium/third_party/blink/renderer/core/css/css_uri_value.cc
index b1078fefcde..18e3b74e0f2 100644
--- a/chromium/third_party/blink/renderer/core/css/css_uri_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_uri_value.cc
@@ -19,6 +19,9 @@ CSSURIValue::CSSURIValue(const AtomicString& relative_url,
is_local_(relative_url.StartsWith('#')),
absolute_url_(absolute_url) {}
+CSSURIValue::CSSURIValue(const AtomicString& absolute_url)
+ : CSSURIValue(absolute_url, absolute_url) {}
+
CSSURIValue::CSSURIValue(const AtomicString& relative_url, const KURL& url)
: CSSURIValue(relative_url, AtomicString(url.GetString())) {}
@@ -31,8 +34,6 @@ SVGResource* CSSURIValue::EnsureResourceReference() const {
}
void CSSURIValue::ReResolveUrl(const Document& document) const {
- if (is_local_)
- return;
KURL url = document.CompleteURL(relative_url_);
AtomicString url_string(url.GetString());
if (url_string == absolute_url_)
@@ -46,8 +47,8 @@ String CSSURIValue::CustomCSSText() const {
}
AtomicString CSSURIValue::FragmentIdentifier() const {
- if (is_local_)
- return AtomicString(relative_url_.GetString().Substring(1));
+ // Always use KURL's FragmentIdentifier to ensure that we're handling the
+ // fragment in a consistent manner.
return AtomicString(AbsoluteUrl().FragmentIdentifier());
}
@@ -72,13 +73,15 @@ bool CSSURIValue::Equals(const CSSURIValue& other) const {
CSSURIValue* CSSURIValue::ValueWithURLMadeAbsolute(
const KURL& base_url,
const WTF::TextEncoding& charset) const {
- if (!charset.IsValid())
- return Create(AtomicString(KURL(base_url, relative_url_).GetString()));
- return Create(
+ if (!charset.IsValid()) {
+ return MakeGarbageCollected<CSSURIValue>(
+ AtomicString(KURL(base_url, relative_url_).GetString()));
+ }
+ return MakeGarbageCollected<CSSURIValue>(
AtomicString(KURL(base_url, relative_url_, charset).GetString()));
}
-void CSSURIValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSURIValue::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(resource_);
CSSValue::TraceAfterDispatch(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_uri_value.h b/chromium/third_party/blink/renderer/core/css/css_uri_value.h
index e49901fdbe9..909779e4796 100644
--- a/chromium/third_party/blink/renderer/core/css/css_uri_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_uri_value.h
@@ -20,16 +20,10 @@ namespace cssvalue {
class CORE_EXPORT CSSURIValue : public CSSValue {
public:
- static CSSURIValue* Create(const String& relative_url, const KURL& url) {
- return MakeGarbageCollected<CSSURIValue>(AtomicString(relative_url), url);
- }
- static CSSURIValue* Create(const AtomicString& absolute_url) {
- return MakeGarbageCollected<CSSURIValue>(absolute_url, absolute_url);
- }
-
CSSURIValue(const AtomicString&, const KURL&);
CSSURIValue(const AtomicString& relative_url,
const AtomicString& absolute_url);
+ CSSURIValue(const AtomicString& absolute_url);
~CSSURIValue();
SVGResource* EnsureResourceReference() const;
@@ -49,7 +43,7 @@ class CORE_EXPORT CSSURIValue : public CSSValue {
CSSURIValue* ValueWithURLMadeAbsolute(const KURL& base_url,
const WTF::TextEncoding&) const;
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
KURL AbsoluteUrl() const;
diff --git a/chromium/third_party/blink/renderer/core/css/css_uri_value_test.cc b/chromium/third_party/blink/renderer/core/css/css_uri_value_test.cc
index 3b04a119ff7..05d7251525e 100644
--- a/chromium/third_party/blink/renderer/core/css/css_uri_value_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_uri_value_test.cc
@@ -12,15 +12,15 @@ namespace blink {
namespace {
TEST(CSSURIValueTest, ValueWithURLMadeAbsolute) {
- cssvalue::CSSURIValue* rel =
- cssvalue::CSSURIValue::Create("a", KURL("http://foo.com/a"));
+ cssvalue::CSSURIValue* rel = MakeGarbageCollected<cssvalue::CSSURIValue>(
+ "a", KURL("http://foo.com/a"));
cssvalue::CSSURIValue* abs = rel->ValueWithURLMadeAbsolute(
KURL("http://bar.com"), WTF::TextEncoding());
EXPECT_EQ("url(\"http://bar.com/a\")", abs->CssText());
}
TEST(CSSURIValueTest, AlreadyAbsoluteURLMadeAbsolute) {
- cssvalue::CSSURIValue* rel = cssvalue::CSSURIValue::Create(
+ cssvalue::CSSURIValue* rel = MakeGarbageCollected<cssvalue::CSSURIValue>(
"http://baz.com/a", KURL("http://baz.com/a"));
cssvalue::CSSURIValue* abs = rel->ValueWithURLMadeAbsolute(
KURL("http://bar.com"), WTF::TextEncoding());
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 17c495769db..d849ce2795d 100644
--- a/chromium/third_party/blink/renderer/core/css/css_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_value.cc
@@ -60,7 +60,6 @@
#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_pending_interpolation_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_quad_value.h"
@@ -81,7 +80,7 @@
namespace blink {
struct SameSizeAsCSSValue final : public GarbageCollected<SameSizeAsCSSValue> {
- uint32_t bitfields;
+ char bitfields[sizeof(uint16_t) + sizeof(uint8_t)];
};
ASSERT_SIZE(CSSValue, SameSizeAsCSSValue);
@@ -100,7 +99,7 @@ CSSValue* CSSValue::Create(const Length& value, float zoom) {
return CSSPrimitiveValue::CreateFromLength(value, zoom);
case Length::kDeviceWidth:
case Length::kDeviceHeight:
- case Length::kMaxSizeNone:
+ case Length::kNone:
NOTREACHED();
break;
}
@@ -262,9 +261,6 @@ bool CSSValue::operator==(const CSSValue& other) const {
case kCSSContentDistributionClass:
return CompareCSSValues<cssvalue::CSSContentDistributionValue>(*this,
other);
- case kPendingInterpolationClass:
- return CompareCSSValues<cssvalue::CSSPendingInterpolationValue>(*this,
- other);
case kCustomPropertyDeclarationClass:
return CompareCSSValues<CSSCustomPropertyDeclaration>(*this, other);
case kVariableReferenceClass:
@@ -382,8 +378,6 @@ String CSSValue::CssText() const {
return To<CSSImageSetValue>(this)->CustomCSSText();
case kCSSContentDistributionClass:
return To<cssvalue::CSSContentDistributionValue>(this)->CustomCSSText();
- case kPendingInterpolationClass:
- return To<cssvalue::CSSPendingInterpolationValue>(this)->CustomCSSText();
case kVariableReferenceClass:
return To<CSSVariableReferenceValue>(this)->CustomCSSText();
case kCustomPropertyDeclarationClass:
@@ -552,10 +546,6 @@ void CSSValue::FinalizeGarbageCollectedObject() {
To<cssvalue::CSSContentDistributionValue>(this)
->~CSSContentDistributionValue();
return;
- case kPendingInterpolationClass:
- To<cssvalue::CSSPendingInterpolationValue>(this)
- ->~CSSPendingInterpolationValue();
- return;
case kVariableReferenceClass:
To<CSSVariableReferenceValue>(this)->~CSSVariableReferenceValue();
return;
@@ -576,7 +566,7 @@ void CSSValue::FinalizeGarbageCollectedObject() {
NOTREACHED();
}
-void CSSValue::Trace(blink::Visitor* visitor) {
+void CSSValue::Trace(Visitor* visitor) {
switch (GetClassType()) {
case kAxisClass:
To<cssvalue::CSSAxisValue>(this)->TraceAfterDispatch(visitor);
@@ -729,10 +719,6 @@ void CSSValue::Trace(blink::Visitor* visitor) {
To<cssvalue::CSSContentDistributionValue>(this)->TraceAfterDispatch(
visitor);
return;
- case kPendingInterpolationClass:
- To<cssvalue::CSSPendingInterpolationValue>(this)->TraceAfterDispatch(
- visitor);
- return;
case kVariableReferenceClass:
To<CSSVariableReferenceValue>(this)->TraceAfterDispatch(visitor);
return;
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 94a011c3dbc..db205280304 100644
--- a/chromium/third_party/blink/renderer/core/css/css_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_value.h
@@ -143,9 +143,6 @@ class CORE_EXPORT CSSValue : public GarbageCollected<CSSValue> {
bool IsContentDistributionValue() const {
return class_type_ == kCSSContentDistributionClass;
}
- bool IsPendingInterpolationValue() const {
- return class_type_ == kPendingInterpolationClass;
- }
bool IsUnicodeRangeValue() const { return class_type_ == kUnicodeRangeClass; }
bool IsGridLineNamesValue() const {
return class_type_ == kGridLineNamesClass;
@@ -183,8 +180,8 @@ class CORE_EXPORT CSSValue : public GarbageCollected<CSSValue> {
bool operator==(const CSSValue&) const;
void FinalizeGarbageCollectedObject();
- void TraceAfterDispatch(blink::Visitor* visitor) {}
- void Trace(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor* visitor) const {}
+ void Trace(Visitor*);
// ~CSSValue should be public, because non-public ~CSSValue causes C2248
// error: 'blink::CSSValue::~CSSValue' : cannot access protected member
@@ -193,7 +190,6 @@ class CORE_EXPORT CSSValue : public GarbageCollected<CSSValue> {
~CSSValue() = default;
protected:
- static const size_t kClassTypeBits = 6;
enum ClassType {
kNumericLiteralClass,
kMathFunctionClass,
@@ -255,7 +251,6 @@ class CORE_EXPORT CSSValue : public GarbageCollected<CSSValue> {
kCSSContentDistributionClass,
- kPendingInterpolationClass,
kKeyframeShorthandClass,
// List class types must appear after ValueListClass.
@@ -276,8 +271,8 @@ class CORE_EXPORT CSSValue : public GarbageCollected<CSSValue> {
explicit CSSValue(ClassType class_type)
: numeric_literal_unit_type_(0),
- value_list_separator_(kSpaceSeparator),
is_non_negative_math_function_(false),
+ value_list_separator_(kSpaceSeparator),
allows_negative_percentage_reference_(false),
class_type_(class_type) {}
@@ -287,18 +282,30 @@ class CORE_EXPORT CSSValue : public GarbageCollected<CSSValue> {
protected:
// The bits in this section are only used by specific subclasses but kept here
// to maximize struct packing.
+ // The bits are ordered and split into groups to such that from the
+ // perspective of each subclass, each field is a separate memory location.
+ // Using NOLINT here allows to use uint8_t as bitfield type which reduces
+ // size of CSSValue from 4 bytes to 3 bytes.
// CSSNumericLiteralValue bits:
- unsigned numeric_literal_unit_type_ : 7; // CSSPrimitiveValue::UnitType
+ // This field hold CSSPrimitiveValue::UnitType.
+ uint8_t numeric_literal_unit_type_ : 7; // NOLINT
- unsigned value_list_separator_ : kValueListSeparatorBits;
+ // CSSMathFunctionValue:
+ uint8_t is_non_negative_math_function_ : 1; // NOLINT
+
+ // Force a new memory location. This will make TSAN treat the 2 fields above
+ // this line as a separate memory location than the 2 fields below it.
+ char : 0;
+
+ // CSSNumericLiteralValue bits:
+ uint8_t value_list_separator_ : kValueListSeparatorBits; // NOLINT
- // CSSMathFunctionValue
- unsigned is_non_negative_math_function_ : 1;
- unsigned allows_negative_percentage_reference_ : 1;
+ // CSSMathFunctionValue:
+ uint8_t allows_negative_percentage_reference_ : 1; // NOLINT
private:
- unsigned class_type_ : kClassTypeBits; // ClassType
+ const uint8_t class_type_; // ClassType
};
template <typename CSSValueType, wtf_size_t inlineCapacity>
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 eefc9a0ace0..3b7a8b92b34 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
@@ -145,7 +145,6 @@
"fantasy",
"monospace",
"-webkit-body",
- "-webkit-pictograph",
//
// font-display
@@ -228,9 +227,6 @@
// Value used to implement the behavior in:
// https://quirks.spec.whatwg.org/#the-tables-inherit-color-from-body-quirk
"-internal-quirk-inherit",
- // The default color value for the root element. Using a keyword to account
- // for different values for different color schemes like dark mode.
- "-internal-root-color",
//
// background-repeat
//
@@ -480,6 +476,8 @@
"-webkit-isolate",
"-webkit-isolate-override",
"-webkit-plaintext",
+ "jis-b5",
+ "jis-b4",
"landscape",
"ledger",
"legal",
@@ -507,6 +505,12 @@
"wavy",
"-webkit-nowrap",
+ //
+ // math-style
+ //
+ // inline
+ "display",
+
// CSS3 Values
// box-align
"stretch",
@@ -619,12 +623,12 @@
// auto
// none
- //
- // -webkit-margin-collapse
- //
- // collapse
- // separate
- "discard",
+ // text-underline-position
+ // auto
+ "from-font",
+ // under
+ // left
+ // right
//
// word-break
@@ -1217,9 +1221,15 @@
// none
"back-button",
- // render-subtree
- "invisible",
- "skip-activation",
- "skip-viewport-activation",
+ // subtree-visibility
+ "hidden-matchable",
+
+ // -internal-empty-line-height
+ // none
+ "fabricated",
+
+ // @supports selector(...)
+ // https://drafts.csswg.org/css-conditional-4/#typedef-supports-selector-fn
+ "selector",
],
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_value_list.cc b/chromium/third_party/blink/renderer/core/css/css_value_list.cc
index 1e02ae2d2bc..fb8bf14737f 100644
--- a/chromium/third_party/blink/renderer/core/css/css_value_list.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_value_list.cc
@@ -138,7 +138,7 @@ void CSSValueList::ReResolveUrl(const Document& document) const {
value->ReResolveUrl(document);
}
-void CSSValueList::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSValueList::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(values_);
CSSValue::TraceAfterDispatch(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_value_list.h b/chromium/third_party/blink/renderer/core/css/css_value_list.h
index 6883efc8223..eb63aff480e 100644
--- a/chromium/third_party/blink/renderer/core/css/css_value_list.h
+++ b/chromium/third_party/blink/renderer/core/css/css_value_list.h
@@ -75,7 +75,7 @@ class CORE_EXPORT CSSValueList : public CSSValue {
bool MayContainUrl() const;
void ReResolveUrl(const Document&) const;
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
HeapVector<Member<const CSSValue>, 4> values_;
diff --git a/chromium/third_party/blink/renderer/core/css/css_value_pair.cc b/chromium/third_party/blink/renderer/core/css/css_value_pair.cc
index 3ca5de6b848..820b646b483 100644
--- a/chromium/third_party/blink/renderer/core/css/css_value_pair.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_value_pair.cc
@@ -6,7 +6,7 @@
namespace blink {
-void CSSValuePair::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSValuePair::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(first_);
visitor->Trace(second_);
CSSValue::TraceAfterDispatch(visitor);
diff --git a/chromium/third_party/blink/renderer/core/css/css_value_pair.h b/chromium/third_party/blink/renderer/core/css/css_value_pair.h
index 2cd6b476e46..db0081bff0e 100644
--- a/chromium/third_party/blink/renderer/core/css/css_value_pair.h
+++ b/chromium/third_party/blink/renderer/core/css/css_value_pair.h
@@ -64,7 +64,7 @@ class CORE_EXPORT CSSValuePair : public CSSValue {
DataEquivalent(second_, other.second_);
}
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
protected:
CSSValuePair(ClassType class_type,
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 16c7f3e6303..1d62b641b68 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
@@ -52,32 +52,17 @@ CSSValuePool::CSSValuePool()
MakeGarbageCollected<cssvalue::CSSColorValue>(Color::kWhite)),
color_black_(
MakeGarbageCollected<cssvalue::CSSColorValue>(Color::kBlack)) {
- {
- using Value = cssvalue::CSSPendingInterpolationValue;
- using Type = cssvalue::CSSPendingInterpolationValue::Type;
- pending_interpolation_values_[0] =
- MakeGarbageCollected<Value>(Type::kCSSProperty);
- pending_interpolation_values_[1] =
- MakeGarbageCollected<Value>(Type::kPresentationAttribute);
- static_assert(static_cast<size_t>(Type::kCSSProperty) == 0u,
- "kCSSProperty must be 0");
- static_assert(static_cast<size_t>(Type::kPresentationAttribute) == 1u,
- "kPresentationAttribute must be 1");
- }
-
identifier_value_cache_.resize(numCSSValueKeywords);
pixel_value_cache_.resize(kMaximumCacheableIntegerValue + 1);
percent_value_cache_.resize(kMaximumCacheableIntegerValue + 1);
number_value_cache_.resize(kMaximumCacheableIntegerValue + 1);
}
-void CSSValuePool::Trace(blink::Visitor* visitor) {
+void CSSValuePool::Trace(Visitor* visitor) {
visitor->Trace(inherited_value_);
visitor->Trace(initial_value_);
visitor->Trace(unset_value_);
visitor->Trace(invalid_variable_value_);
- visitor->Trace(pending_interpolation_values_[0]);
- visitor->Trace(pending_interpolation_values_[1]);
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 10d55b77ac1..c2fb257666c 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
@@ -38,7 +38,6 @@
#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"
-#include "third_party/blink/renderer/core/css/css_pending_interpolation_value.h"
#include "third_party/blink/renderer/core/css/css_property_names.h"
#include "third_party/blink/renderer/core/css/css_unset_value.h"
#include "third_party/blink/renderer/core/css/css_value_list.h"
@@ -56,7 +55,6 @@ class CORE_EXPORT CSSValuePool final : public GarbageCollected<CSSValuePool> {
static const int kMaximumCacheableIntegerValue = 255;
using CSSColorValue = cssvalue::CSSColorValue;
using CSSUnsetValue = cssvalue::CSSUnsetValue;
- using CSSPendingInterpolationValue = cssvalue::CSSPendingInterpolationValue;
using ColorValueCache = HeapHashMap<unsigned, Member<CSSColorValue>>;
static const unsigned kMaximumColorCacheSize = 512;
using FontFaceValueCache =
@@ -76,12 +74,6 @@ class CORE_EXPORT CSSValuePool final : public GarbageCollected<CSSValuePool> {
CSSInvalidVariableValue* InvalidVariableValue() {
return invalid_variable_value_;
}
- CSSPendingInterpolationValue* PendingInterpolationValue(
- CSSPendingInterpolationValue::Type type) {
- DCHECK_GE(static_cast<size_t>(type), 0u);
- DCHECK_LE(static_cast<size_t>(type), 1u);
- return pending_interpolation_values_[static_cast<size_t>(type)];
- }
// Vector caches.
CSSIdentifierValue* IdentifierCacheValue(CSSValueID ident) {
@@ -135,7 +127,7 @@ class CORE_EXPORT CSSValuePool final : public GarbageCollected<CSSValuePool> {
return font_face_value_cache_.insert(string, nullptr);
}
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
// Cached individual values.
@@ -143,7 +135,6 @@ class CORE_EXPORT CSSValuePool final : public GarbageCollected<CSSValuePool> {
Member<CSSInitialValue> initial_value_;
Member<CSSUnsetValue> unset_value_;
Member<CSSInvalidVariableValue> invalid_variable_value_;
- Member<CSSPendingInterpolationValue> pending_interpolation_values_[2];
Member<CSSColorValue> color_transparent_;
Member<CSSColorValue> color_white_;
Member<CSSColorValue> color_black_;
diff --git a/chromium/third_party/blink/renderer/core/css/css_variable_data.cc b/chromium/third_party/blink/renderer/core/css/css_variable_data.cc
index 68f6a166b11..303a387cf38 100644
--- a/chromium/third_party/blink/renderer/core/css/css_variable_data.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_variable_data.cc
@@ -96,7 +96,8 @@ const CSSValue* CSSVariableData::ParseForSyntax(
DCHECK(!NeedsVariableResolution());
// TODO(timloh): This probably needs a proper parser context for
// relative URL resolution.
- return syntax.Parse(TokenRange(), StrictCSSParserContext(secure_context_mode),
+ return syntax.Parse(TokenRange(),
+ *StrictCSSParserContext(secure_context_mode),
is_animation_tainted_);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_variable_reference_value.cc b/chromium/third_party/blink/renderer/core/css/css_variable_reference_value.cc
index 859749f4de8..699091f049d 100644
--- a/chromium/third_party/blink/renderer/core/css/css_variable_reference_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_variable_reference_value.cc
@@ -6,7 +6,8 @@
namespace blink {
-void CSSVariableReferenceValue::TraceAfterDispatch(blink::Visitor* visitor) {
+void CSSVariableReferenceValue::TraceAfterDispatch(
+ blink::Visitor* visitor) const {
CSSValue::TraceAfterDispatch(visitor);
visitor->Trace(parser_context_);
}
diff --git a/chromium/third_party/blink/renderer/core/css/css_variable_reference_value.h b/chromium/third_party/blink/renderer/core/css/css_variable_reference_value.h
index 7ec8b2dcb26..d3dcf20d374 100644
--- a/chromium/third_party/blink/renderer/core/css/css_variable_reference_value.h
+++ b/chromium/third_party/blink/renderer/core/css/css_variable_reference_value.h
@@ -38,7 +38,7 @@ class CSSVariableReferenceValue : public CSSValue {
}
String CustomCSSText() const;
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
scoped_refptr<CSSVariableData> data_;
diff --git a/chromium/third_party/blink/renderer/core/css/css_viewport_rule.cc b/chromium/third_party/blink/renderer/core/css/css_viewport_rule.cc
index 1449477e2c4..90a2ce21992 100644
--- a/chromium/third_party/blink/renderer/core/css/css_viewport_rule.cc
+++ b/chromium/third_party/blink/renderer/core/css/css_viewport_rule.cc
@@ -75,7 +75,7 @@ void CSSViewportRule::Reattach(StyleRuleBase* rule) {
properties_cssom_wrapper_->Reattach(viewport_rule_->MutableProperties());
}
-void CSSViewportRule::Trace(blink::Visitor* visitor) {
+void CSSViewportRule::Trace(Visitor* visitor) {
visitor->Trace(viewport_rule_);
visitor->Trace(properties_cssom_wrapper_);
CSSRule::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/css/css_viewport_rule.h b/chromium/third_party/blink/renderer/core/css/css_viewport_rule.h
index 96c503884ba..1806a6739f6 100644
--- a/chromium/third_party/blink/renderer/core/css/css_viewport_rule.h
+++ b/chromium/third_party/blink/renderer/core/css/css_viewport_rule.h
@@ -53,7 +53,7 @@ class CSSViewportRule final : public CSSRule {
CSSStyleDeclaration* style() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
CSSRule::Type type() const override { return kViewportRule; }
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/computed_style_property_map.cc b/chromium/third_party/blink/renderer/core/css/cssom/computed_style_property_map.cc
index 8ae6921ecdf..aacccd53811 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/computed_style_property_map.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/computed_style_property_map.cc
@@ -10,161 +10,24 @@
#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_variable_data.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/dom/document.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/transforms/matrix_3d_transform_operation.h"
-#include "third_party/blink/renderer/platform/transforms/matrix_transform_operation.h"
-#include "third_party/blink/renderer/platform/transforms/perspective_transform_operation.h"
-#include "third_party/blink/renderer/platform/transforms/skew_transform_operation.h"
namespace blink {
namespace {
-// We collapse functions like translateX into translate, since we will reify
-// them as a translate anyway.
-const CSSValue* ComputedTransformComponent(const TransformOperation& operation,
- float zoom) {
- switch (operation.GetType()) {
- case TransformOperation::kScaleX:
- case TransformOperation::kScaleY:
- case TransformOperation::kScaleZ:
- case TransformOperation::kScale:
- case TransformOperation::kScale3D: {
- const auto& scale = ToScaleTransformOperation(operation);
- CSSFunctionValue* result = MakeGarbageCollected<CSSFunctionValue>(
- operation.Is3DOperation() ? CSSValueID::kScale3d
- : CSSValueID::kScale);
- result->Append(*CSSNumericLiteralValue::Create(
- scale.X(), CSSPrimitiveValue::UnitType::kNumber));
- result->Append(*CSSNumericLiteralValue::Create(
- scale.Y(), CSSPrimitiveValue::UnitType::kNumber));
- if (operation.Is3DOperation()) {
- result->Append(*CSSNumericLiteralValue::Create(
- scale.Z(), CSSPrimitiveValue::UnitType::kNumber));
- }
- return result;
- }
- case TransformOperation::kTranslateX:
- case TransformOperation::kTranslateY:
- case TransformOperation::kTranslateZ:
- case TransformOperation::kTranslate:
- case TransformOperation::kTranslate3D: {
- const auto& translate = ToTranslateTransformOperation(operation);
- CSSFunctionValue* result = MakeGarbageCollected<CSSFunctionValue>(
- operation.Is3DOperation() ? CSSValueID::kTranslate3d
- : CSSValueID::kTranslate);
- result->Append(*CSSPrimitiveValue::CreateFromLength(translate.X(), zoom));
- result->Append(*CSSPrimitiveValue::CreateFromLength(translate.Y(), zoom));
- if (operation.Is3DOperation()) {
- result->Append(*CSSNumericLiteralValue::Create(
- translate.Z(), CSSPrimitiveValue::UnitType::kPixels));
- }
- return result;
- }
- case TransformOperation::kRotateX:
- case TransformOperation::kRotateY:
- case TransformOperation::kRotate3D: {
- const auto& rotate = ToRotateTransformOperation(operation);
- CSSFunctionValue* result =
- MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kRotate3d);
- result->Append(*CSSNumericLiteralValue::Create(
- rotate.X(), CSSPrimitiveValue::UnitType::kNumber));
- result->Append(*CSSNumericLiteralValue::Create(
- rotate.Y(), CSSPrimitiveValue::UnitType::kNumber));
- result->Append(*CSSNumericLiteralValue::Create(
- rotate.Z(), CSSPrimitiveValue::UnitType::kNumber));
- result->Append(*CSSNumericLiteralValue::Create(
- rotate.Angle(), CSSPrimitiveValue::UnitType::kDegrees));
- return result;
- }
- case TransformOperation::kRotate: {
- const auto& rotate = ToRotateTransformOperation(operation);
- auto* result =
- MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kRotate);
- result->Append(*CSSNumericLiteralValue::Create(
- rotate.Angle(), CSSPrimitiveValue::UnitType::kDegrees));
- return result;
- }
- case TransformOperation::kSkewX: {
- const auto& skew = ToSkewTransformOperation(operation);
- auto* result = MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kSkewX);
- result->Append(*CSSNumericLiteralValue::Create(
- skew.AngleX(), CSSPrimitiveValue::UnitType::kDegrees));
- return result;
- }
- case TransformOperation::kSkewY: {
- const auto& skew = ToSkewTransformOperation(operation);
- auto* result = MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kSkewY);
- result->Append(*CSSNumericLiteralValue::Create(
- skew.AngleY(), CSSPrimitiveValue::UnitType::kDegrees));
- return result;
- }
- case TransformOperation::kSkew: {
- const auto& skew = ToSkewTransformOperation(operation);
- auto* result = MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kSkew);
- result->Append(*CSSNumericLiteralValue::Create(
- skew.AngleX(), CSSPrimitiveValue::UnitType::kDegrees));
- result->Append(*CSSNumericLiteralValue::Create(
- skew.AngleY(), CSSPrimitiveValue::UnitType::kDegrees));
- return result;
- }
- case TransformOperation::kPerspective: {
- const auto& perspective = ToPerspectiveTransformOperation(operation);
- auto* result =
- MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kPerspective);
- result->Append(*CSSNumericLiteralValue::Create(
- perspective.Perspective(), CSSPrimitiveValue::UnitType::kPixels));
- return result;
- }
- case TransformOperation::kMatrix: {
- const auto& matrix = ToMatrixTransformOperation(operation).Matrix();
- auto* result =
- MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kMatrix);
- double values[6] = {matrix.A(), matrix.B(), matrix.C(),
- matrix.D(), matrix.E(), matrix.F()};
- for (double value : values) {
- result->Append(*CSSNumericLiteralValue::Create(
- value, CSSPrimitiveValue::UnitType::kNumber));
- }
- return result;
- }
- case TransformOperation::kMatrix3D: {
- const auto& matrix = ToMatrix3DTransformOperation(operation).Matrix();
- CSSFunctionValue* result =
- MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kMatrix3d);
- double values[16] = {
- matrix.M11(), matrix.M12(), matrix.M13(), matrix.M14(),
- matrix.M21(), matrix.M22(), matrix.M23(), matrix.M24(),
- matrix.M31(), matrix.M32(), matrix.M33(), matrix.M34(),
- matrix.M41(), matrix.M42(), matrix.M43(), matrix.M44()};
- for (double value : values) {
- result->Append(*CSSNumericLiteralValue::Create(
- value, CSSPrimitiveValue::UnitType::kNumber));
- }
- return result;
- }
- case TransformOperation::kInterpolated:
- // TODO(816803): The computed value in this case is not fully spec'd
- // See https://github.com/w3c/css-houdini-drafts/issues/425
- return CSSIdentifierValue::Create(CSSValueID::kNone);
- default:
- // The remaining operations are unsupported.
- NOTREACHED();
- return CSSIdentifierValue::Create(CSSValueID::kNone);
- }
-}
-
const CSSValue* ComputedTransform(const ComputedStyle& style) {
if (style.Transform().Operations().size() == 0)
return CSSIdentifierValue::Create(CSSValueID::kNone);
CSSValueList* components = CSSValueList::CreateSpaceSeparated();
for (const auto& operation : style.Transform().Operations()) {
- components->Append(
- *ComputedTransformComponent(*operation, style.EffectiveZoom()));
+ components->Append(*ComputedStyleUtils::ValueForTransformOperation(
+ *operation, style.EffectiveZoom()));
}
return components;
}
@@ -177,9 +40,12 @@ unsigned int ComputedStylePropertyMap::size() const {
return 0;
DCHECK(StyledNode());
- return CSSComputedStyleDeclaration::ComputableProperties().size() +
+ const Document& document = StyledNode()->GetDocument();
+ return CSSComputedStyleDeclaration::ComputableProperties(
+ StyledNode()->GetExecutionContext())
+ .size() +
ComputedStyleCSSValueMapping::GetVariables(
- *style, StyledNode()->GetDocument().GetPropertyRegistry())
+ *style, document.GetPropertyRegistry())
.size();
}
@@ -242,6 +108,8 @@ const CSSValue* ComputedStylePropertyMap::GetProperty(
switch (property_id) {
case CSSPropertyID::kTransform:
return ComputedTransform(*style);
+ case CSSPropertyID::kLineHeight:
+ return ComputedStyleUtils::ComputedValueForLineHeight(*style);
default:
return CSSProperty::Get(property_id)
.CSSValueFromComputedStyle(*style, nullptr /* layout_object */,
@@ -265,11 +133,14 @@ void ComputedStylePropertyMap::ForEachProperty(
if (!style)
return;
+ DCHECK(StyledNode());
+ const Document& document = StyledNode()->GetDocument();
// Have to sort by all properties by code point, so we have to store
// them in a buffer first.
HeapVector<std::pair<CSSPropertyName, Member<const CSSValue>>> values;
for (const CSSProperty* property :
- CSSComputedStyleDeclaration::ComputableProperties()) {
+ CSSComputedStyleDeclaration::ComputableProperties(
+ StyledNode()->GetExecutionContext())) {
DCHECK(property);
DCHECK(!property->IDEquals(CSSPropertyID::kVariable));
const CSSValue* value = property->CSSValueFromComputedStyle(
@@ -278,8 +149,7 @@ void ComputedStylePropertyMap::ForEachProperty(
values.emplace_back(CSSPropertyName(property->PropertyID()), value);
}
- PropertyRegistry* registry =
- StyledNode()->GetDocument().GetPropertyRegistry();
+ const PropertyRegistry* registry = document.GetPropertyRegistry();
for (const auto& name_value :
ComputedStyleCSSValueMapping::GetVariables(*style, registry)) {
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 bf4b583ec76..53733de72fa 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
@@ -25,16 +25,12 @@ namespace blink {
class CORE_EXPORT ComputedStylePropertyMap
: public StylePropertyMapReadOnlyMainThread {
public:
- static ComputedStylePropertyMap* Create(Node* node) {
- return MakeGarbageCollected<ComputedStylePropertyMap>(node);
- }
-
ComputedStylePropertyMap(Node* node, const String& pseudo_element = String())
: StylePropertyMapReadOnlyMainThread(),
pseudo_id_(CSSSelector::ParsePseudoId(pseudo_element)),
node_(node) {}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(node_);
StylePropertyMapReadOnlyMainThread::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/computed_style_property_map_test.cc b/chromium/third_party/blink/renderer/core/css/cssom/computed_style_property_map_test.cc
new file mode 100644
index 00000000000..946ad25258d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/cssom/computed_style_property_map_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/css/cssom/computed_style_property_map.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/html/html_element.h"
+#include "third_party/blink/renderer/core/testing/page_test_base.h"
+
+namespace blink {
+
+class ComputedStylePropertyMapTest : public PageTestBase {
+ public:
+ ComputedStylePropertyMapTest() = default;
+
+ protected:
+ ComputedStylePropertyMap* SetBodyStyle(const AtomicString& style) {
+ GetDocument().body()->setAttribute(html_names::kStyleAttr, style);
+ UpdateAllLifecyclePhasesForTest();
+ return MakeGarbageCollected<ComputedStylePropertyMap>(GetDocument().body());
+ }
+};
+
+TEST_F(ComputedStylePropertyMapTest, TransformMatrixZoom) {
+ ComputedStylePropertyMap* map =
+ SetBodyStyle("transform:matrix(1, 0, 0, 1, 100, 100);zoom:2");
+ CSSStyleValue* style_value = map->get(GetDocument().GetExecutionContext(),
+ "transform", ASSERT_NO_EXCEPTION);
+ ASSERT_TRUE(style_value);
+ EXPECT_EQ("matrix(1, 0, 0, 1, 100, 100)", style_value->toString());
+}
+
+TEST_F(ComputedStylePropertyMapTest, TransformMatrix3DZoom) {
+ ComputedStylePropertyMap* map = SetBodyStyle(
+ "transform:matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 100, 100, 100, "
+ "1);zoom:2");
+ CSSStyleValue* style_value = map->get(GetDocument().GetExecutionContext(),
+ "transform", ASSERT_NO_EXCEPTION);
+ ASSERT_TRUE(style_value);
+ EXPECT_EQ("matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 100, 100, 100, 1)",
+ style_value->toString());
+}
+
+TEST_F(ComputedStylePropertyMapTest, TransformPerspectiveZoom) {
+ ComputedStylePropertyMap* map =
+ SetBodyStyle("transform:perspective(100px);zoom:2");
+ CSSStyleValue* style_value = map->get(GetDocument().GetExecutionContext(),
+ "transform", ASSERT_NO_EXCEPTION);
+ ASSERT_TRUE(style_value);
+ EXPECT_EQ("perspective(100px)", style_value->toString());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/cross_thread_color_value.cc b/chromium/third_party/blink/renderer/core/css/cssom/cross_thread_color_value.cc
index 99270832ef3..8e0c4853759 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/cross_thread_color_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/cross_thread_color_value.cc
@@ -9,7 +9,7 @@
namespace blink {
CSSStyleValue* CrossThreadColorValue::ToCSSStyleValue() {
- return CSSUnsupportedColorValue::Create(value_);
+ return MakeGarbageCollected<CSSUnsupportedColorValue>(value_);
}
bool CrossThreadColorValue::operator==(
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/cross_thread_unsupported_value.cc b/chromium/third_party/blink/renderer/core/css/cssom/cross_thread_unsupported_value.cc
index 657fc347847..756e2ab2740 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/cross_thread_unsupported_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/cross_thread_unsupported_value.cc
@@ -9,7 +9,7 @@
namespace blink {
CSSStyleValue* CrossThreadUnsupportedValue::ToCSSStyleValue() {
- return CSSUnsupportedStyleValue::Create(std::move(value_.IsolatedCopy()));
+ return MakeGarbageCollected<CSSUnsupportedStyleValue>(value_.IsolatedCopy());
}
bool CrossThreadUnsupportedValue::operator==(
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_keyword_value.idl b/chromium/third_party/blink/renderer/core/css/cssom/css_keyword_value.idl
index 31f6b51730d..0185871c3f6 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_keyword_value.idl
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_keyword_value.idl
@@ -6,9 +6,8 @@
// example "initial".
// https://drafts.css-houdini.org/css-typed-om/#keywordvalue-objects
[
- Constructor(CSSOMString keyword),
- Exposed=(Window,LayoutWorklet,PaintWorklet),
- RaisesException=Constructor
+ Exposed=(Window,LayoutWorklet,PaintWorklet)
] interface CSSKeywordValue : CSSStyleValue {
+ [RaisesException] constructor(CSSOMString keyword);
[RaisesException=Setter] attribute CSSOMString value;
};
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_math_invert.idl b/chromium/third_party/blink/renderer/core/css/cssom/css_math_invert.idl
index c165677b6c5..5217cd9db71 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_math_invert.idl
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_math_invert.idl
@@ -5,8 +5,8 @@
// Represents the inverse a CSSNumericValue.
// https://drafts.css-houdini.org/css-typed-om/#cssmathinvert
[
- Constructor(CSSNumberish arg),
Exposed=(Window,LayoutWorklet,PaintWorklet)
] interface CSSMathInvert : CSSMathValue {
+ constructor(CSSNumberish arg);
readonly attribute CSSNumberish value;
};
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_math_max.cc b/chromium/third_party/blink/renderer/core/css/cssom/css_math_max.cc
index 80f6e206f99..328225ead56 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_math_max.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_math_max.cc
@@ -71,9 +71,6 @@ void CSSMathMax::BuildCSSText(Nested, ParenLess, StringBuilder& result) const {
}
CSSMathExpressionNode* CSSMathMax::ToCalcExpressionNode() const {
- if (!RuntimeEnabledFeatures::CSSComparisonFunctionsEnabled())
- return nullptr;
-
CSSMathExpressionVariadicOperation::Operands operands;
operands.ReserveCapacity(NumericValues().size());
for (const auto& value : NumericValues()) {
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_math_max.idl b/chromium/third_party/blink/renderer/core/css/cssom/css_math_max.idl
index 4a29b526ffd..d8f8a89d886 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_math_max.idl
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_math_max.idl
@@ -5,9 +5,8 @@
// Represents the maximum of one or more CSSNumericValues.
// https://drafts.css-houdini.org/css-typed-om/#cssmathsum
[
- Constructor(CSSNumberish... args),
- Exposed=(Window,LayoutWorklet,PaintWorklet),
- RaisesException=Constructor
+ Exposed=(Window,LayoutWorklet,PaintWorklet)
] interface CSSMathMax : CSSMathValue {
+ [RaisesException] constructor(CSSNumberish... args);
readonly attribute CSSNumericArray values;
};
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_math_min.cc b/chromium/third_party/blink/renderer/core/css/cssom/css_math_min.cc
index 7b8d0f8666f..cff5f907f7b 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_math_min.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_math_min.cc
@@ -70,9 +70,6 @@ void CSSMathMin::BuildCSSText(Nested, ParenLess, StringBuilder& result) const {
}
CSSMathExpressionNode* CSSMathMin::ToCalcExpressionNode() const {
- if (!RuntimeEnabledFeatures::CSSComparisonFunctionsEnabled())
- return nullptr;
-
CSSMathExpressionVariadicOperation::Operands operands;
operands.ReserveCapacity(NumericValues().size());
for (const auto& value : NumericValues()) {
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_math_min.idl b/chromium/third_party/blink/renderer/core/css/cssom/css_math_min.idl
index fd8fbb1d2f8..075499cdcd5 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_math_min.idl
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_math_min.idl
@@ -5,9 +5,8 @@
// Represents the minimum of one or more CSSNumericValues.
// https://drafts.css-houdini.org/css-typed-om/#cssmathsum
[
- Constructor(CSSNumberish... args),
- Exposed=(Window,LayoutWorklet,PaintWorklet),
- RaisesException=Constructor
+ Exposed=(Window,LayoutWorklet,PaintWorklet)
] interface CSSMathMin : CSSMathValue {
+ [RaisesException] constructor(CSSNumberish... args);
readonly attribute CSSNumericArray values;
};
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_math_negate.idl b/chromium/third_party/blink/renderer/core/css/cssom/css_math_negate.idl
index 69095537e37..aa2ef47788b 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_math_negate.idl
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_math_negate.idl
@@ -5,8 +5,8 @@
// Represents the negation of a CSSNumericValue.
// https://drafts.css-houdini.org/css-typed-om/#cssmathnegate
[
- Constructor(CSSNumberish arg),
Exposed=(Window,LayoutWorklet,PaintWorklet)
] interface CSSMathNegate : CSSMathValue {
+ constructor(CSSNumberish arg);
readonly attribute CSSNumberish value;
};
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_math_product.idl b/chromium/third_party/blink/renderer/core/css/cssom/css_math_product.idl
index f4c4471331d..abd367d66c5 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_math_product.idl
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_math_product.idl
@@ -5,9 +5,8 @@
// Represents the product of one or more CSSNumericValues.
// https://drafts.css-houdini.org/css-typed-om/#cssmathsub
[
- Constructor(CSSNumberish... args),
- Exposed=(Window,LayoutWorklet,PaintWorklet),
- RaisesException=Constructor
+ Exposed=(Window,LayoutWorklet,PaintWorklet)
] interface CSSMathProduct : CSSMathValue {
+ [RaisesException] constructor(CSSNumberish... args);
readonly attribute CSSNumericArray values;
};
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_math_sum.idl b/chromium/third_party/blink/renderer/core/css/cssom/css_math_sum.idl
index 72b8cb82e9f..dcc74e288be 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_math_sum.idl
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_math_sum.idl
@@ -5,9 +5,8 @@
// Represents the sum of one or more CSSNumericValues.
// https://drafts.css-houdini.org/css-typed-om/#cssmathsum
[
- Constructor(CSSNumberish... args),
- Exposed=(Window,LayoutWorklet,PaintWorklet),
- RaisesException=Constructor
+ Exposed=(Window,LayoutWorklet,PaintWorklet)
] interface CSSMathSum : CSSMathValue {
+ [RaisesException] constructor(CSSNumberish... args);
readonly attribute CSSNumericArray values;
};
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_matrix_component.cc b/chromium/third_party/blink/renderer/core/css/cssom/css_matrix_component.cc
index d6545b6621c..a9e15538810 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_matrix_component.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_matrix_component.cc
@@ -4,9 +4,9 @@
#include "third_party/blink/renderer/core/css/cssom/css_matrix_component.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_css_matrix_component_options.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/cssom/css_matrix_component_options.h"
#include "third_party/blink/renderer/core/geometry/dom_matrix.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
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 e60ebefee2c..4f6287a7f17 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(matrix_);
CSSTransformComponent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_matrix_component.idl b/chromium/third_party/blink/renderer/core/css/cssom/css_matrix_component.idl
index 530e42f1402..6c304bffd84 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_matrix_component.idl
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_matrix_component.idl
@@ -6,9 +6,9 @@
// "transform".
// Spec: https://drafts.css-houdini.org/css-typed-om/#cssmatrixcomponent
[
- Constructor(DOMMatrixReadOnly matrix,
- optional CSSMatrixComponentOptions options),
Exposed=(Window,LayoutWorklet,PaintWorklet)
] interface CSSMatrixComponent : CSSTransformComponent {
+ constructor(DOMMatrixReadOnly matrix,
+ optional CSSMatrixComponentOptions options = {});
attribute DOMMatrix matrix;
};
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 529f6a463ba..181c3882d76 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
@@ -15,10 +15,6 @@ class CORE_EXPORT CSSNumericArray final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- // blink internal
- static CSSNumericArray* Create(CSSNumericValueVector values) {
- return MakeGarbageCollected<CSSNumericArray>(std::move(values));
- }
static CSSNumericArray* FromNumberishes(
const HeapVector<CSSNumberish>& values) {
return MakeGarbageCollected<CSSNumericArray>(
@@ -28,7 +24,7 @@ class CORE_EXPORT CSSNumericArray final : public ScriptWrappable {
explicit CSSNumericArray(CSSNumericValueVector values)
: values_(std::move(values)) {}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(values_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_numeric_array.idl b/chromium/third_party/blink/renderer/core/css/cssom/css_numeric_array.idl
index 402d98c6720..ae6e651369d 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_numeric_array.idl
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_numeric_array.idl
@@ -5,8 +5,7 @@
// Represents the sum of one or more CSSNumericValues.
// https://drafts.css-houdini.org/css-typed-om/#cssmathsum
[
- Exposed=(Window,LayoutWorklet,PaintWorklet),
- RaisesException=Constructor
+ Exposed=(Window,LayoutWorklet,PaintWorklet)
] interface CSSNumericArray {
iterable<CSSNumericValue>;
readonly attribute unsigned long length;
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_numeric_type.idl b/chromium/third_party/blink/renderer/core/css/cssom/css_numeric_type.idl
index e539ea80e9a..24abf9ddd70 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_numeric_type.idl
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_numeric_type.idl
@@ -2,9 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-[
- Exposed=(Window,LayoutWorklet,PaintWorklet)
-] enum CSSNumericBaseType {
+// https://drafts.css-houdini.org/css-typed-om/#enumdef-cssnumericbasetype
+enum CSSNumericBaseType {
"length",
"angle",
"time",
@@ -14,10 +13,8 @@
"percent",
};
-// https://drafts.css-houdini.org/css-typed-om/#cssnumerictype
-[
- Exposed=(Window,LayoutWorklet,PaintWorklet)
-] dictionary CSSNumericType {
+// https://drafts.css-houdini.org/css-typed-om/#dictdef-cssnumerictype
+dictionary CSSNumericType {
long length;
long angle;
long time;
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_numeric_value.cc b/chromium/third_party/blink/renderer/core/css/cssom/css_numeric_value.cc
index 2b0c4e3f499..56a1526b9e0 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_numeric_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_numeric_value.cc
@@ -6,6 +6,7 @@
#include <numeric>
+#include "third_party/blink/renderer/bindings/core/v8/v8_css_numeric_type.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_primitive_value.h"
@@ -251,10 +252,9 @@ CSSNumericValue* CSSNumericValue::parse(const String& css_text,
case kFunctionToken:
if (range.Peek().FunctionId() == CSSValueID::kCalc ||
range.Peek().FunctionId() == CSSValueID::kWebkitCalc ||
- (RuntimeEnabledFeatures::CSSComparisonFunctionsEnabled() &&
- (range.Peek().FunctionId() == CSSValueID::kMin ||
- range.Peek().FunctionId() == CSSValueID::kMax ||
- range.Peek().FunctionId() == CSSValueID::kClamp))) {
+ range.Peek().FunctionId() == CSSValueID::kMin ||
+ range.Peek().FunctionId() == CSSValueID::kMax ||
+ range.Peek().FunctionId() == CSSValueID::kClamp) {
CSSMathExpressionNode* expression =
CSSMathExpressionNode::ParseCalc(range);
if (expression)
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_numeric_value.h b/chromium/third_party/blink/renderer/core/css/cssom/css_numeric_value.h
index 066261868cd..15d9723b565 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_numeric_value.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_numeric_value.h
@@ -10,7 +10,6 @@
#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/core/css/cssom/css_numeric_sum_value.h"
-#include "third_party/blink/renderer/core/css/cssom/css_numeric_type.h"
#include "third_party/blink/renderer/core/css/cssom/css_numeric_value_type.h"
#include "third_party/blink/renderer/core/css/cssom/css_style_value.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -18,12 +17,13 @@
namespace blink {
+class CSSMathExpressionNode;
+class CSSMathSum;
+class CSSNumericType;
+class CSSNumericValue;
class CSSUnitValue;
class ExceptionState;
-class CSSMathExpressionNode;
-class CSSNumericValue;
-class CSSMathSum;
using CSSNumberish = DoubleOrCSSNumericValue;
using CSSNumericValueVector = HeapVector<Member<CSSNumericValue>>;
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 ff15be0e46a..fed2a88ed39 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(length_);
CSSTransformComponent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_perspective.idl b/chromium/third_party/blink/renderer/core/css/cssom/css_perspective.idl
index 9cba1d1f123..0e763fc3e37 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_perspective.idl
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_perspective.idl
@@ -6,9 +6,8 @@
// like "transform".
// Spec: https://drafts.css-houdini.org/css-typed-om/#cssperspective
[
- Constructor(CSSNumericValue length),
- Exposed=(Window,LayoutWorklet,PaintWorklet),
- RaisesException=Constructor
+ Exposed=(Window,LayoutWorklet,PaintWorklet)
] interface CSSPerspective : CSSTransformComponent {
+ [RaisesException] constructor(CSSNumericValue length);
[RaisesException=Setter] attribute CSSNumericValue length;
};
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 4d9d1ac5d93..464e1e37700 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(x_);
visitor->Trace(y_);
CSSStyleValue::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_position_value.idl b/chromium/third_party/blink/renderer/core/css/cssom/css_position_value.idl
index 3954abba2d5..6d12b1dd02d 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_position_value.idl
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_position_value.idl
@@ -6,10 +6,9 @@
// background-position.
// Spec: https://drafts.css-houdini.org/css-typed-om/#positionvalue-objects
[
- Constructor(CSSNumericValue x, CSSNumericValue y),
- Exposed=(Window,LayoutWorklet,PaintWorklet),
- RaisesException=Constructor
+ Exposed=(Window,LayoutWorklet,PaintWorklet)
] interface CSSPositionValue : CSSStyleValue {
+ [RaisesException] constructor(CSSNumericValue x, CSSNumericValue y);
[RaisesException=Setter] attribute CSSNumericValue x;
[RaisesException=Setter] attribute CSSNumericValue y;
};
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 b08ae0a20d6..e7e3f46401e 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,9 +32,7 @@ class CORE_EXPORT CSSResourceValue : public CSSStyleValue {
}
}
- void Trace(blink::Visitor* visitor) override {
- CSSStyleValue::Trace(visitor);
- }
+ void Trace(Visitor* visitor) 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 f0a5f04a575..cf22fa2e433 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(angle_);
visitor->Trace(x_);
visitor->Trace(y_);
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_rotate.idl b/chromium/third_party/blink/renderer/core/css/cssom/css_rotate.idl
index 1b19a86e0e0..2340f4604bb 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_rotate.idl
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_rotate.idl
@@ -6,11 +6,10 @@
// "transform".
// Spec: https://drafts.css-houdini.org/css-typed-om/#cssrotate
[
- Constructor(CSSNumericValue angleValue),
- Constructor(CSSNumberish x, CSSNumberish y, CSSNumberish z, CSSNumericValue angle),
- Exposed=(Window,LayoutWorklet,PaintWorklet),
- RaisesException=Constructor
+ Exposed=(Window,LayoutWorklet,PaintWorklet)
] interface CSSRotate : CSSTransformComponent {
+ [RaisesException] constructor(CSSNumericValue angleValue);
+ [RaisesException] constructor(CSSNumberish x, CSSNumberish y, CSSNumberish z, CSSNumericValue angle);
[RaisesException=Setter] attribute CSSNumericValue angle;
[RaisesException=Setter] attribute CSSNumberish x;
[RaisesException=Setter] attribute CSSNumberish 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 e564e330d76..43c1adf6c5d 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(x_);
visitor->Trace(y_);
visitor->Trace(z_);
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_scale.idl b/chromium/third_party/blink/renderer/core/css/cssom/css_scale.idl
index 2644e70bb61..7294deea0e5 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_scale.idl
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_scale.idl
@@ -6,10 +6,9 @@
// "transform".
// Spec: https://drafts.css-houdini.org/css-typed-om/#cssscale
[
- Constructor(CSSNumberish x, CSSNumberish y, optional CSSNumberish z),
- Exposed=(Window,LayoutWorklet,PaintWorklet),
- RaisesException=Constructor
+ Exposed=(Window,LayoutWorklet,PaintWorklet)
] interface CSSScale : CSSTransformComponent {
+ [RaisesException] constructor(CSSNumberish x, CSSNumberish y, optional CSSNumberish z);
[RaisesException=Setter] attribute CSSNumberish x;
[RaisesException=Setter] attribute CSSNumberish y;
[RaisesException=Setter] attribute CSSNumberish 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 9fddbe91471..2b0bf78633f 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(ax_);
visitor->Trace(ay_);
CSSTransformComponent::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_skew.idl b/chromium/third_party/blink/renderer/core/css/cssom/css_skew.idl
index 8aed33f0326..15e91f5d5f5 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_skew.idl
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_skew.idl
@@ -6,10 +6,9 @@
// "transform".
// Spec: https://drafts.css-houdini.org/css-typed-om/#cssskew
[
- Constructor(CSSNumericValue ax, CSSNumericValue ay),
- Exposed=(Window,LayoutWorklet,PaintWorklet),
- RaisesException=Constructor
+ Exposed=(Window,LayoutWorklet,PaintWorklet)
] interface CSSSkew : CSSTransformComponent {
+ [RaisesException] constructor(CSSNumericValue ax, CSSNumericValue ay);
[RaisesException=Setter] attribute CSSNumericValue ax;
[RaisesException=Setter] attribute CSSNumericValue ay;
};
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 7e16aac2c3e..73b55695173 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(ax_);
CSSTransformComponent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_skew_x.idl b/chromium/third_party/blink/renderer/core/css/cssom/css_skew_x.idl
index fc08ea50bf3..a342b898baf 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_skew_x.idl
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_skew_x.idl
@@ -6,9 +6,8 @@
// "transform".
// Spec: https://drafts.css-houdini.org/css-typed-om/#cssskewx
[
- Constructor(CSSNumericValue ax),
- Exposed=(Window, Worker, PaintWorklet, LayoutWorklet),
- RaisesException=Constructor]
-interface CSSSkewX : CSSTransformComponent {
+ Exposed=(Window, Worker, PaintWorklet, LayoutWorklet)
+] interface CSSSkewX : CSSTransformComponent {
+ [RaisesException] constructor(CSSNumericValue ax);
[RaisesException=Setter] attribute CSSNumericValue ax;
};
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 10378a73b9a..1d7bc3257d3 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(ay_);
CSSTransformComponent::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_skew_y.idl b/chromium/third_party/blink/renderer/core/css/cssom/css_skew_y.idl
index eea0517cc41..5c3130ca7ac 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_skew_y.idl
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_skew_y.idl
@@ -6,9 +6,8 @@
// "transform".
// Spec: https://drafts.css-houdini.org/css-typed-om/#cssskewy
[
- Constructor(CSSNumericValue ay),
- Exposed=(Window, Worker, PaintWorklet, LayoutWorklet),
- RaisesException=Constructor]
-interface CSSSkewY : CSSTransformComponent {
+ Exposed=(Window, Worker, PaintWorklet, LayoutWorklet)
+] interface CSSSkewY : CSSTransformComponent {
+ [RaisesException] constructor(CSSNumericValue ay);
[RaisesException=Setter] attribute CSSNumericValue ay;
};
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_style_image_value.cc b/chromium/third_party/blink/renderer/core/css/cssom/css_style_image_value.cc
index cf9e080f1ad..2348a398c4e 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_style_image_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_style_image_value.cc
@@ -34,7 +34,8 @@ double CSSStyleImageValue::intrinsicRatio(bool& is_null) const {
}
FloatSize CSSStyleImageValue::ElementSize(
- const FloatSize& default_object_size) const {
+ const FloatSize& default_object_size,
+ const RespectImageOrientationEnum) const {
bool not_used;
return FloatSize(intrinsicWidth(not_used), intrinsicHeight(not_used));
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_style_image_value.h b/chromium/third_party/blink/renderer/core/css/cssom/css_style_image_value.h
index 77e9d0e5275..1731aa9ee8c 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_style_image_value.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_style_image_value.h
@@ -30,7 +30,8 @@ class CORE_EXPORT CSSStyleImageValue : public CSSResourceValue,
// CanvasImageSource
bool IsCSSImageValue() const final { return true; }
bool WouldTaintOrigin() const final { return true; }
- FloatSize ElementSize(const FloatSize& default_object_size) const final;
+ FloatSize ElementSize(const FloatSize& default_object_size,
+ const RespectImageOrientationEnum) const final;
protected:
CSSStyleImageValue() = default;
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_style_value.cc b/chromium/third_party/blink/renderer/core/css/cssom/css_style_value.cc
index 53dd6b1c279..5e26e4e55f9 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_style_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_style_value.cc
@@ -24,7 +24,8 @@ CSSStyleValueVector ParseCSSStyleValue(
const String& property_name,
const String& value,
ExceptionState& exception_state) {
- const CSSPropertyID property_id = cssPropertyID(property_name);
+ const CSSPropertyID property_id =
+ cssPropertyID(execution_context, property_name);
if (property_id == CSSPropertyID::kInvalid) {
exception_state.ThrowTypeError("Invalid property name");
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 2173b0cef9a..74b8914e3c0 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(fallback_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_transform_value.cc b/chromium/third_party/blink/renderer/core/css/cssom/css_transform_value.cc
index 4876fa3337d..53b81acb115 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_transform_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_transform_value.cc
@@ -77,25 +77,25 @@ const CSSValue* CSSTransformValue::ToCSSValue() const {
return transform_css_value;
}
-bool CSSTransformValue::AnonymousIndexedSetter(
+IndexedPropertySetterResult CSSTransformValue::AnonymousIndexedSetter(
unsigned index,
const Member<CSSTransformComponent> component,
ExceptionState& exception_state) {
if (index < transform_components_.size()) {
transform_components_[index] = component;
- return true;
+ return IndexedPropertySetterResult::kIntercepted;
}
if (index == transform_components_.size()) {
transform_components_.push_back(component);
- return true;
+ return IndexedPropertySetterResult::kIntercepted;
}
exception_state.ThrowRangeError(
ExceptionMessages::IndexOutsideRange<unsigned>(
"index", index, 0, ExceptionMessages::kInclusiveBound,
transform_components_.size(), ExceptionMessages::kInclusiveBound));
- return false;
+ return IndexedPropertySetterResult::kIntercepted;
}
} // namespace blink
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 c7bcc5a4103..7cfb9f5e02b 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
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/core/css/cssom/css_style_value.h"
#include "third_party/blink/renderer/core/css/cssom/css_transform_component.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
namespace blink {
@@ -45,13 +46,14 @@ class CORE_EXPORT CSSTransformValue final : public CSSStyleValue {
CSSTransformComponent* AnonymousIndexedGetter(wtf_size_t index) {
return transform_components_.at(index);
}
- bool AnonymousIndexedSetter(unsigned,
- const Member<CSSTransformComponent>,
- ExceptionState&);
+ IndexedPropertySetterResult AnonymousIndexedSetter(
+ unsigned,
+ const Member<CSSTransformComponent>,
+ ExceptionState&);
wtf_size_t length() const { return transform_components_.size(); }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(transform_components_);
CSSStyleValue::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_transform_value.idl b/chromium/third_party/blink/renderer/core/css/cssom/css_transform_value.idl
index 7c654d1180a..96b6f2a8736 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_transform_value.idl
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_transform_value.idl
@@ -3,10 +3,9 @@
// found in the LICENSE file.
[
- Constructor(sequence<CSSTransformComponent> transforms),
- RaisesException=Constructor,
Exposed=(Window,LayoutWorklet,PaintWorklet)
] interface CSSTransformValue : CSSStyleValue {
+ [RaisesException] constructor(sequence<CSSTransformComponent> transforms);
iterable<CSSTransformComponent>;
readonly attribute unsigned long length;
getter CSSTransformComponent (unsigned long index);
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 e28fa08ee1c..24bc55a7ff1 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(x_);
visitor->Trace(y_);
visitor->Trace(z_);
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_translate.idl b/chromium/third_party/blink/renderer/core/css/cssom/css_translate.idl
index 51f2ce9e6de..33c7adb9df9 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_translate.idl
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_translate.idl
@@ -6,11 +6,10 @@
// like "transform".
// Spec: https://drafts.css-houdini.org/css-typed-om/#csstranslate
[
- Constructor(CSSNumericValue x, CSSNumericValue y,
- optional CSSNumericValue z),
- Exposed=(Window,LayoutWorklet,PaintWorklet),
- RaisesException=Constructor
+ Exposed=(Window,LayoutWorklet,PaintWorklet)
] interface CSSTranslate : CSSTransformComponent {
+ [RaisesException] constructor(CSSNumericValue x, CSSNumericValue y,
+ optional CSSNumericValue z);
[RaisesException=Setter] attribute CSSNumericValue x;
[RaisesException=Setter] attribute CSSNumericValue y;
[RaisesException=Setter] attribute CSSNumericValue z;
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_unit_value.idl b/chromium/third_party/blink/renderer/core/css/cssom/css_unit_value.idl
index b0be5d7bdfd..92aa8035ae6 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_unit_value.idl
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_unit_value.idl
@@ -6,10 +6,9 @@
// unit (or a naked number or percentage).
// https://drafts.css-houdini.org/css-typed-om/#cssunitvalue
[
- Constructor(double value, CSSOMString unit),
- RaisesException=Constructor,
Exposed=(Window,LayoutWorklet,PaintWorklet)
] interface CSSUnitValue : CSSNumericValue {
+ [RaisesException] constructor(double value, CSSOMString unit);
attribute double value;
readonly attribute CSSOMString unit;
};
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_unparsed_value.cc b/chromium/third_party/blink/renderer/core/css/cssom/css_unparsed_value.cc
index 8d7badb9cac..48193970239 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_unparsed_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_unparsed_value.cc
@@ -94,24 +94,25 @@ CSSUnparsedSegment CSSUnparsedValue::AnonymousIndexedGetter(
return {};
}
-bool CSSUnparsedValue::AnonymousIndexedSetter(unsigned index,
- const CSSUnparsedSegment& segment,
- ExceptionState& exception_state) {
+IndexedPropertySetterResult CSSUnparsedValue::AnonymousIndexedSetter(
+ unsigned index,
+ const CSSUnparsedSegment& segment,
+ ExceptionState& exception_state) {
if (index < tokens_.size()) {
tokens_[index] = segment;
- return true;
+ return IndexedPropertySetterResult::kIntercepted;
}
if (index == tokens_.size()) {
tokens_.push_back(segment);
- return true;
+ return IndexedPropertySetterResult::kIntercepted;
}
exception_state.ThrowRangeError(
ExceptionMessages::IndexOutsideRange<unsigned>(
"index", index, 0, ExceptionMessages::kInclusiveBound, tokens_.size(),
ExceptionMessages::kInclusiveBound));
- return false;
+ return IndexedPropertySetterResult::kIntercepted;
}
const CSSValue* CSSUnparsedValue::ToCSSValue() const {
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 7c87b475f86..f567216c372 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
@@ -47,10 +47,19 @@ class CORE_EXPORT CSSUnparsedValue final : public CSSStyleValue {
StyleValueType GetType() const override { return kUnparsedType; }
+ void AnonymousIndexedGetter(uint32_t index,
+ CSSUnparsedSegment& return_value,
+ ExceptionState& exception_state) const {
+ return_value = AnonymousIndexedGetter(index, exception_state);
+ }
+ // TODO(crbug.com/1050474): Remove the following 2-arguments version once the
+ // migration to the new bindings generator is done. The current policy is
+ // that return value of IDL union type is returned by argument. This policy
+ // may change when we implement IDL union types with GarbageCollected classes.
CSSUnparsedSegment AnonymousIndexedGetter(unsigned, ExceptionState&) const;
- bool AnonymousIndexedSetter(unsigned,
- const CSSUnparsedSegment&,
- ExceptionState&);
+ IndexedPropertySetterResult AnonymousIndexedSetter(unsigned,
+ const CSSUnparsedSegment&,
+ ExceptionState&);
wtf_size_t length() const { return tokens_.size(); }
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_unparsed_value.idl b/chromium/third_party/blink/renderer/core/css/cssom/css_unparsed_value.idl
index 685c20f086c..40696ca7940 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_unparsed_value.idl
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_unparsed_value.idl
@@ -6,9 +6,9 @@
// They represent a list of string fragments and variable references.
// Spec: https://drafts.css-houdini.org/css-typed-om/#unparsedvalue-objects
[
- Constructor(sequence<CSSUnparsedSegment> members),
Exposed=(Window,LayoutWorklet,PaintWorklet)
] interface CSSUnparsedValue : CSSStyleValue {
+ constructor(sequence<CSSUnparsedSegment> members);
iterable<CSSUnparsedSegment>;
readonly attribute unsigned long length;
[RaisesException] getter CSSUnparsedSegment (unsigned long index);
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_unsupported_color_value.cc b/chromium/third_party/blink/renderer/core/css/cssom/css_unsupported_color_value.cc
index 1a10dbe3d52..f94b593c1c3 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_unsupported_color_value.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_unsupported_color_value.cc
@@ -17,21 +17,6 @@
namespace blink {
-CSSUnsupportedColorValue* CSSUnsupportedColorValue::Create(Color color) {
- return MakeGarbageCollected<CSSUnsupportedColorValue>(color);
-}
-
-CSSUnsupportedColorValue* CSSUnsupportedColorValue::Create(
- const CSSPropertyName& name,
- Color color) {
- return MakeGarbageCollected<CSSUnsupportedColorValue>(name, color);
-}
-
-CSSUnsupportedColorValue* CSSUnsupportedColorValue::FromCSSValue(
- const cssvalue::CSSColorValue& color_value) {
- return MakeGarbageCollected<CSSUnsupportedColorValue>(color_value.Value());
-}
-
Color CSSUnsupportedColorValue::Value() const {
return color_value_;
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_unsupported_color_value.h b/chromium/third_party/blink/renderer/core/css/cssom/css_unsupported_color_value.h
index afe63a5ad49..4e23e45b943 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_unsupported_color_value.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_unsupported_color_value.h
@@ -21,11 +21,6 @@ namespace blink {
class CORE_EXPORT CSSUnsupportedColorValue final
: public CSSUnsupportedStyleValue {
public:
- static CSSUnsupportedColorValue* Create(Color color);
- static CSSUnsupportedColorValue* Create(const CSSPropertyName& name,
- Color color);
- static CSSUnsupportedColorValue* FromCSSValue(const cssvalue::CSSColorValue&);
-
explicit CSSUnsupportedColorValue(Color color)
: CSSUnsupportedStyleValue(
cssvalue::CSSColorValue::SerializeAsCSSComponentValue(color)),
@@ -35,6 +30,8 @@ class CORE_EXPORT CSSUnsupportedColorValue final
name,
cssvalue::CSSColorValue::SerializeAsCSSComponentValue(color)),
color_value_(color) {}
+ explicit CSSUnsupportedColorValue(const cssvalue::CSSColorValue& color_value)
+ : CSSUnsupportedColorValue(color_value.Value()) {}
StyleValueType GetType() const override { return kUnsupportedColorType; }
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_unsupported_color_value_test.cc b/chromium/third_party/blink/renderer/core/css/cssom/css_unsupported_color_value_test.cc
index b501a3b2e29..b83e40cbf50 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_unsupported_color_value_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_unsupported_color_value_test.cc
@@ -10,7 +10,7 @@ namespace blink {
TEST(CSSUnsupportedColorValueTest, CreateColorStyleValue) {
CSSStyleValue* style_value =
- CSSUnsupportedColorValue::Create(Color(0, 255, 0));
+ MakeGarbageCollected<CSSUnsupportedColorValue>(Color(0, 255, 0));
EXPECT_EQ(style_value->GetType(),
CSSStyleValue::StyleValueType::kUnsupportedColorType);
@@ -26,7 +26,7 @@ TEST(CSSUnsupportedColorValueTest, CreateColorStyleValue) {
TEST(CSSUnsupportedColorValueTest, ColorStyleValueToString) {
CSSUnsupportedColorValue* style_value =
- CSSUnsupportedColorValue::Create(Color(0, 255, 0));
+ MakeGarbageCollected<CSSUnsupportedColorValue>(Color(0, 255, 0));
EXPECT_TRUE(style_value);
EXPECT_EQ(
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_unsupported_style_value.h b/chromium/third_party/blink/renderer/core/css/cssom/css_unsupported_style_value.h
index c43d1303a6c..751ddda529c 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_unsupported_style_value.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_unsupported_style_value.h
@@ -26,27 +26,15 @@ namespace blink {
class CORE_EXPORT CSSUnsupportedStyleValue : public CSSStyleValue {
public:
- static CSSUnsupportedStyleValue* Create(const CSSValue& value) {
- return MakeGarbageCollected<CSSUnsupportedStyleValue>(value.CssText());
- }
- static CSSUnsupportedStyleValue* Create(const String& css_text) {
- return MakeGarbageCollected<CSSUnsupportedStyleValue>(css_text);
- }
- static CSSUnsupportedStyleValue* Create(const CSSPropertyName& name,
- const String& css_text) {
- return MakeGarbageCollected<CSSUnsupportedStyleValue>(name, css_text);
- }
- static CSSUnsupportedStyleValue* Create(const CSSPropertyName& name,
- const CSSValue& value) {
- return MakeGarbageCollected<CSSUnsupportedStyleValue>(name,
- value.CssText());
- }
-
CSSUnsupportedStyleValue(const String& css_text) { SetCSSText(css_text); }
CSSUnsupportedStyleValue(const CSSPropertyName& name, const String& css_text)
: name_(name) {
SetCSSText(css_text);
}
+ CSSUnsupportedStyleValue(const CSSPropertyName& name, const CSSValue& value)
+ : name_(name) {
+ SetCSSText(value.CssText());
+ }
StyleValueType GetType() const override {
return StyleValueType::kUnknownType;
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 922cd34ec61..4130f1cca56 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
@@ -20,8 +20,9 @@ base::Optional<IntSize> CSSURLImageValue::IntrinsicSize() const {
DCHECK(!value_->IsCachePending());
ImageResourceContent* resource_content = value_->CachedImage()->CachedImage();
+
return resource_content
- ? resource_content->IntrinsicSize(kDoNotRespectImageOrientation)
+ ? resource_content->IntrinsicSize(kRespectImageOrientation)
: IntSize(0, 0);
}
@@ -58,7 +59,7 @@ const CSSValue* CSSURLImageValue::ToCSSValue() const {
return value_;
}
-void CSSURLImageValue::Trace(blink::Visitor* visitor) {
+void CSSURLImageValue::Trace(Visitor* visitor) {
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 f8ca0aa20d8..a941d43fb33 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
@@ -32,7 +32,7 @@ class CORE_EXPORT CSSURLImageValue final : public CSSStyleImageValue {
StyleValueType GetType() const final { return kURLImageType; }
const CSSValue* ToCSSValue() const final;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
scoped_refptr<Image> GetImage() const;
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/css_variable_reference_value.idl b/chromium/third_party/blink/renderer/core/css/cssom/css_variable_reference_value.idl
index ca4677386dd..1fc1325d779 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/css_variable_reference_value.idl
+++ b/chromium/third_party/blink/renderer/core/css/cssom/css_variable_reference_value.idl
@@ -5,11 +5,10 @@
// Represents a CSS var() reference in a CSS value.
// Spec: https://drafts.css-houdini.org/css-typed-om/#cssvariablereferencevalue
[
- Constructor(CSSOMString variable, optional CSSUnparsedValue? fallback = null),
Exposed=(Window,LayoutWorklet,PaintWorklet),
- RaisesException=Constructor,
ImplementedAs=CSSStyleVariableReferenceValue
] interface CSSVariableReferenceValue {
+ [RaisesException] constructor(CSSOMString variable, optional CSSUnparsedValue? fallback = null);
[RaisesException=Setter] attribute CSSOMString variable;
readonly attribute CSSUnparsedValue? fallback;
};
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 f0757b7453f..4bb264af0b5 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 40969db6e14..1c02dd570c5 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 87412c21f99..6ee90aaba8d 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
@@ -29,7 +29,7 @@ TEST(InlineStylePropertyMapTest, PendingSubstitutionValueCrash) {
div->SetInlineStyleProperty(property_id, "var(--dummy)");
const StylePropertyShorthand& longhands = shorthandForProperty(property_id);
for (unsigned i = 0; i < longhands.length(); i++) {
- map.get(document,
+ map.get(document->GetExecutionContext(),
longhands.properties()[i]->GetCSSPropertyName().ToAtomicString(),
ASSERT_NO_EXCEPTION);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_deferred_image.cc b/chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_deferred_image.cc
index f37d073af4f..35a58b2dcd2 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_deferred_image.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_deferred_image.cc
@@ -37,7 +37,8 @@ void PaintWorkletDeferredImage::Draw(cc::PaintCanvas* canvas,
}
void PaintWorkletDeferredImage::DrawTile(GraphicsContext& context,
- const FloatRect& src_rect) {
+ const FloatRect& src_rect,
+ RespectImageOrientationEnum) {
DrawInternal(context.Canvas(), FloatRect(), src_rect, context.FillFlags(),
kClampImageToSourceRect, image_);
}
@@ -45,7 +46,8 @@ void PaintWorkletDeferredImage::DrawTile(GraphicsContext& context,
sk_sp<PaintShader> PaintWorkletDeferredImage::CreateShader(
const FloatRect& tile_rect,
const SkMatrix* pattern_matrix,
- const FloatRect& src_rect) {
+ const FloatRect& src_rect,
+ RespectImageOrientationEnum) {
SkRect tile = SkRect::MakeXYWH(tile_rect.X(), tile_rect.Y(),
tile_rect.Width(), tile_rect.Height());
sk_sp<PaintShader> shader = PaintShader::MakeImage(
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_deferred_image.h b/chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_deferred_image.h
index 11429a243ba..d82c56208fe 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_deferred_image.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_deferred_image.h
@@ -38,10 +38,13 @@ class CORE_EXPORT PaintWorkletDeferredImage : public GeneratedImage {
RespectImageOrientationEnum,
ImageClampingMode,
ImageDecodingMode) override;
- void DrawTile(GraphicsContext&, const FloatRect&) override;
+ void DrawTile(GraphicsContext&,
+ const FloatRect&,
+ RespectImageOrientationEnum) override;
sk_sp<cc::PaintShader> CreateShader(const FloatRect& tile_rect,
const SkMatrix* pattern_matrix,
- const FloatRect& src_rect) final;
+ const FloatRect& src_rect,
+ RespectImageOrientationEnum) final;
private:
PaintWorkletDeferredImage(scoped_refptr<PaintWorkletInput> input,
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 c50b855c43b..d9259c4f9fd 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(values_);
PairIterable<String, CSSStyleValueVector>::IterationSource::Trace(visitor);
}
@@ -172,7 +172,7 @@ CSSStyleValueVector PaintWorkletStylePropertyMap::getAll(
const ExecutionContext* execution_context,
const String& property_name,
ExceptionState& exception_state) const {
- CSSPropertyID property_id = cssPropertyID(property_name);
+ CSSPropertyID property_id = cssPropertyID(execution_context, property_name);
if (property_id == CSSPropertyID::kInvalid) {
exception_state.ThrowTypeError("Invalid propertyName: " + property_name);
return CSSStyleValueVector();
@@ -209,7 +209,7 @@ PaintWorkletStylePropertyMap::StartIteration(ScriptState* script_state,
result);
}
-void PaintWorkletStylePropertyMap::Trace(blink::Visitor* visitor) {
+void PaintWorkletStylePropertyMap::Trace(Visitor* visitor) {
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 67349970ad4..f76a0658c50 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
const CrossThreadData& StyleMapDataForTest() const { return data_; }
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map_test.cc b/chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map_test.cc
index 5c84570058a..d8e1fdad55f 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map_test.cc
@@ -115,7 +115,7 @@ TEST_F(PaintWorkletStylePropertyMapTest, UnregisteredCustomProperty) {
Vector<CSSPropertyID> native_properties;
Vector<AtomicString> custom_properties({"--x"});
- GetDocument().documentElement()->SetInnerHTMLFromString(
+ GetDocument().documentElement()->setInnerHTML(
"<div id='target' style='--x:50'></div>");
UpdateAllLifecyclePhasesForTest();
@@ -162,7 +162,7 @@ TEST_F(PaintWorkletStylePropertyMapTest, SupportedCrossThreadData) {
css_test_helpers::RegisterProperty(GetDocument(), "--gar", "<color>",
"rgb(0, 255, 0)", false);
- GetDocument().documentElement()->SetInnerHTMLFromString(
+ GetDocument().documentElement()->setInnerHTML(
"<div id='target' style='--foo:10px; --bar:15; --gar:rgb(255, 0, "
"0)'></div>");
UpdateAllLifecyclePhasesForTest();
@@ -208,7 +208,7 @@ TEST_F(PaintWorkletStylePropertyMapTest, UnsupportedCrossThreadData) {
css_test_helpers::RegisterProperty(GetDocument(), "--loo", "test", "test",
false);
- GetDocument().documentElement()->SetInnerHTMLFromString(
+ GetDocument().documentElement()->setInnerHTML(
"<div id='target' style='--foo:url(https://crbug.com/); "
"--bar:15;'></div>");
UpdateAllLifecyclePhasesForTest();
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 0351536b7e4..f8699198e9a 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(blink::Visitor* visitor) {
+void PrepopulatedComputedStylePropertyMap::Trace(Visitor* visitor) {
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 88b52b13f2e..6da8bd700df 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
const CSSValue* GetProperty(CSSPropertyID) const override;
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map_test.cc b/chromium/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map_test.cc
index 72cb0bf289f..d69a8b53e21 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map_test.cc
@@ -19,8 +19,8 @@ class PrepopulatedComputedStylePropertyMapTest : public PageTestBase {
PrepopulatedComputedStylePropertyMapTest() = default;
void SetElementWithStyle(const String& value) {
- GetDocument().body()->SetInnerHTMLFromString("<div id='target' style='" +
- value + "'></div>");
+ GetDocument().body()->setInnerHTML("<div id='target' style='" + value +
+ "'></div>");
UpdateAllLifecyclePhasesForTest();
}
@@ -63,24 +63,27 @@ TEST_F(PrepopulatedComputedStylePropertyMapTest, NativePropertyAccessors) {
DummyExceptionStateForTesting exception_state;
- map->get(&GetDocument(), "color", exception_state);
+ map->get(GetDocument().GetExecutionContext(), "color", exception_state);
EXPECT_FALSE(exception_state.HadException());
- map->has(&GetDocument(), "color", exception_state);
+ map->has(GetDocument().GetExecutionContext(), "color", exception_state);
EXPECT_FALSE(exception_state.HadException());
- map->getAll(&GetDocument(), "color", exception_state);
+ map->getAll(GetDocument().GetExecutionContext(), "color", exception_state);
EXPECT_FALSE(exception_state.HadException());
- map->get(&GetDocument(), "align-contents", exception_state);
+ map->get(GetDocument().GetExecutionContext(), "align-contents",
+ exception_state);
EXPECT_TRUE(exception_state.HadException());
exception_state.ClearException();
- map->has(&GetDocument(), "align-contents", exception_state);
+ map->has(GetDocument().GetExecutionContext(), "align-contents",
+ exception_state);
EXPECT_TRUE(exception_state.HadException());
exception_state.ClearException();
- map->getAll(&GetDocument(), "align-contents", exception_state);
+ map->getAll(GetDocument().GetExecutionContext(), "align-contents",
+ exception_state);
EXPECT_TRUE(exception_state.HadException());
exception_state.ClearException();
}
@@ -99,29 +102,34 @@ TEST_F(PrepopulatedComputedStylePropertyMapTest, CustomPropertyAccessors) {
DummyExceptionStateForTesting exception_state;
- const CSSStyleValue* foo = map->get(&GetDocument(), "--foo", exception_state);
+ const CSSStyleValue* foo =
+ map->get(GetDocument().GetExecutionContext(), "--foo", exception_state);
ASSERT_NE(nullptr, foo);
ASSERT_EQ(CSSStyleValue::kUnparsedType, foo->GetType());
EXPECT_FALSE(exception_state.HadException());
- EXPECT_EQ(true, map->has(&GetDocument(), "--foo", exception_state));
+ EXPECT_EQ(true, map->has(GetDocument().GetExecutionContext(), "--foo",
+ exception_state));
EXPECT_FALSE(exception_state.HadException());
- CSSStyleValueVector fooAll =
- map->getAll(&GetDocument(), "--foo", exception_state);
+ CSSStyleValueVector fooAll = map->getAll(GetDocument().GetExecutionContext(),
+ "--foo", exception_state);
EXPECT_EQ(1U, fooAll.size());
ASSERT_NE(nullptr, fooAll[0]);
ASSERT_EQ(CSSStyleValue::kUnparsedType, fooAll[0]->GetType());
EXPECT_FALSE(exception_state.HadException());
- EXPECT_EQ(nullptr, map->get(&GetDocument(), "--quix", exception_state));
+ EXPECT_EQ(nullptr, map->get(GetDocument().GetExecutionContext(), "--quix",
+ exception_state));
EXPECT_FALSE(exception_state.HadException());
- EXPECT_EQ(false, map->has(&GetDocument(), "--quix", exception_state));
+ EXPECT_EQ(false, map->has(GetDocument().GetExecutionContext(), "--quix",
+ exception_state));
EXPECT_FALSE(exception_state.HadException());
EXPECT_EQ(CSSStyleValueVector(),
- map->getAll(&GetDocument(), "--quix", exception_state));
+ map->getAll(GetDocument().GetExecutionContext(), "--quix",
+ exception_state));
EXPECT_FALSE(exception_state.HadException());
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/style_property_map.cc b/chromium/third_party/blink/renderer/core/css/cssom/style_property_map.cc
index 8c174cab389..6f20d0983f4 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/style_property_map.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/style_property_map.cc
@@ -254,7 +254,8 @@ void StylePropertyMap::set(const ExecutionContext* execution_context,
const String& property_name,
const HeapVector<CSSStyleValueOrString>& values,
ExceptionState& exception_state) {
- const CSSPropertyID property_id = cssPropertyID(property_name);
+ const CSSPropertyID property_id =
+ cssPropertyID(execution_context, property_name);
if (property_id == CSSPropertyID::kInvalid) {
exception_state.ThrowTypeError("Invalid propertyName: " + property_name);
return;
@@ -318,7 +319,8 @@ void StylePropertyMap::append(const ExecutionContext* execution_context,
if (values.IsEmpty())
return;
- const CSSPropertyID property_id = cssPropertyID(property_name);
+ const CSSPropertyID property_id =
+ cssPropertyID(execution_context, property_name);
if (property_id == CSSPropertyID::kInvalid) {
exception_state.ThrowTypeError("Invalid propertyName: " + property_name);
@@ -360,9 +362,10 @@ void StylePropertyMap::append(const ExecutionContext* execution_context,
SetProperty(property_id, *current_value);
}
-void StylePropertyMap::remove(const String& property_name,
+void StylePropertyMap::remove(const ExecutionContext* execution_context,
+ const String& property_name,
ExceptionState& exception_state) {
- CSSPropertyID property_id = cssPropertyID(property_name);
+ CSSPropertyID property_id = cssPropertyID(execution_context, property_name);
if (property_id == CSSPropertyID::kInvalid) {
exception_state.ThrowTypeError("Invalid property name: " + property_name);
return;
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/style_property_map.h b/chromium/third_party/blink/renderer/core/css/cssom/style_property_map.h
index 6bbc19bb0f2..6b9e16cb42f 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/style_property_map.h
+++ b/chromium/third_party/blink/renderer/core/css/cssom/style_property_map.h
@@ -27,7 +27,9 @@ class CORE_EXPORT StylePropertyMap : public StylePropertyMapReadOnlyMainThread {
const String& property_name,
const HeapVector<CSSStyleValueOrString>& values,
ExceptionState&);
- void remove(const String& property_name, ExceptionState&);
+ void remove(const ExecutionContext*,
+ const String& property_name,
+ ExceptionState&);
void clear();
protected:
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/style_property_map.idl b/chromium/third_party/blink/renderer/core/css/cssom/style_property_map.idl
index 775ab0b0cb0..f4d358419dc 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/style_property_map.idl
+++ b/chromium/third_party/blink/renderer/core/css/cssom/style_property_map.idl
@@ -10,6 +10,6 @@
// TODO(https://crbug.com/838890): DOMString should be CSSOMString
[RaisesException, CallWith=ExecutionContext] void set(CSSOMString property, (CSSStyleValue or DOMString)... values);
[RaisesException, CallWith=ExecutionContext] void append(CSSOMString property, (CSSStyleValue or DOMString)... values);
- [RaisesException, ImplementedAs=remove] void delete(CSSOMString property);
+ [RaisesException, CallWith=ExecutionContext, ImplementedAs=remove] void delete(CSSOMString property);
void clear();
};
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 3499347c498..c5471a9b66b 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(values_);
PairIterable<String, CSSStyleValueVector>::IterationSource::Trace(visitor);
}
@@ -62,7 +62,8 @@ CSSStyleValue* StylePropertyMapReadOnlyMainThread::get(
const ExecutionContext* execution_context,
const String& property_name,
ExceptionState& exception_state) const {
- base::Optional<CSSPropertyName> name = CSSPropertyName::From(property_name);
+ base::Optional<CSSPropertyName> name =
+ CSSPropertyName::From(execution_context, property_name);
if (!name) {
exception_state.ThrowTypeError("Invalid propertyName: " + property_name);
@@ -94,7 +95,8 @@ CSSStyleValueVector StylePropertyMapReadOnlyMainThread::getAll(
const ExecutionContext* execution_context,
const String& property_name,
ExceptionState& exception_state) const {
- base::Optional<CSSPropertyName> name = CSSPropertyName::From(property_name);
+ base::Optional<CSSPropertyName> name =
+ CSSPropertyName::From(execution_context, property_name);
if (!name) {
exception_state.ThrowTypeError("Invalid propertyName: " + property_name);
@@ -145,7 +147,7 @@ CSSStyleValue* StylePropertyMapReadOnlyMainThread::GetShorthandProperty(
const auto serialization = SerializationForShorthand(property);
if (serialization.IsEmpty())
return nullptr;
- return CSSUnsupportedStyleValue::Create(
+ return MakeGarbageCollected<CSSUnsupportedStyleValue>(
CSSPropertyName(property.PropertyID()), serialization);
}
diff --git a/chromium/third_party/blink/renderer/core/css/cssom/style_value_factory.cc b/chromium/third_party/blink/renderer/core/css/cssom/style_value_factory.cc
index f9c43847b3b..ed6ac6fd33d 100644
--- a/chromium/third_party/blink/renderer/core/css/cssom/style_value_factory.cc
+++ b/chromium/third_party/blink/renderer/core/css/cssom/style_value_factory.cc
@@ -56,7 +56,7 @@ CSSStyleValue* CreateStyleValue(const CSSValue& value) {
if (auto* primitive_value = DynamicTo<CSSPrimitiveValue>(value))
return CSSNumericValue::FromCSSValue(*primitive_value);
if (auto* color_value = DynamicTo<cssvalue::CSSColorValue>(value))
- return CSSUnsupportedColorValue::FromCSSValue(*color_value);
+ return MakeGarbageCollected<CSSUnsupportedColorValue>(*color_value);
if (auto* image_value = DynamicTo<CSSImageValue>(value))
return MakeGarbageCollected<CSSURLImageValue>(*image_value->Clone());
return nullptr;
@@ -106,8 +106,8 @@ CSSStyleValue* CreateStyleValueWithPropertyInternal(CSSPropertyID property_id,
if (identifier_value &&
identifier_value->GetValueID() == CSSValueID::kCurrentcolor)
return CSSKeywordValue::Create("currentcolor");
- return CSSUnsupportedStyleValue::Create(CSSPropertyName(property_id),
- value);
+ return MakeGarbageCollected<CSSUnsupportedStyleValue>(
+ CSSPropertyName(property_id), value);
}
case CSSPropertyID::kContain: {
if (value.IsIdentifierValue())
@@ -228,8 +228,8 @@ CSSStyleValue* CreateStyleValueWithProperty(CSSPropertyID property_id,
if (!CSSOMTypes::IsPropertySupported(property_id)) {
DCHECK_NE(property_id, CSSPropertyID::kVariable);
- return CSSUnsupportedStyleValue::Create(CSSPropertyName(property_id),
- value);
+ return MakeGarbageCollected<CSSUnsupportedStyleValue>(
+ CSSPropertyName(property_id), value);
}
CSSStyleValue* style_value =
@@ -242,7 +242,8 @@ CSSStyleValue* CreateStyleValueWithProperty(CSSPropertyID property_id,
CSSStyleValueVector UnsupportedCSSValue(const CSSPropertyName& name,
const CSSValue& value) {
CSSStyleValueVector style_value_vector;
- style_value_vector.push_back(CSSUnsupportedStyleValue::Create(name, value));
+ style_value_vector.push_back(
+ MakeGarbageCollected<CSSUnsupportedStyleValue>(name, value));
return style_value_vector;
}
@@ -278,7 +279,7 @@ CSSStyleValueVector StyleValueFactory::FromString(
// Shorthands are not yet supported.
CSSStyleValueVector result;
- result.push_back(CSSUnsupportedStyleValue::Create(
+ result.push_back(MakeGarbageCollected<CSSUnsupportedStyleValue>(
CSSPropertyName(property_id), css_text));
return result;
}
@@ -304,7 +305,7 @@ CSSStyleValue* StyleValueFactory::CssValueToStyleValue(
CSSStyleValue* style_value =
CreateStyleValueWithProperty(name.Id(), css_value);
if (!style_value)
- return CSSUnsupportedStyleValue::Create(name, css_value);
+ return MakeGarbageCollected<CSSUnsupportedStyleValue>(name, css_value);
return style_value;
}
@@ -385,10 +386,12 @@ CSSStyleValueVector StyleValueFactory::CssValueToStyleValueVector(
const CSSValue& css_value) {
CSSStyleValueVector style_value_vector;
- if (CSSStyleValue* value = CreateStyleValueWithoutProperty(css_value))
+ if (CSSStyleValue* value = CreateStyleValueWithoutProperty(css_value)) {
style_value_vector.push_back(value);
- else
- style_value_vector.push_back(CSSUnsupportedStyleValue::Create(css_value));
+ } else {
+ style_value_vector.push_back(
+ MakeGarbageCollected<CSSUnsupportedStyleValue>(css_value.CssText()));
+ }
return style_value_vector;
}
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 c2c0c993cf7..881dfbb9c49 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
@@ -50,7 +50,7 @@ class DocumentStyleSheetCollection final
DocumentStyleSheetCollector&);
void CollectViewportRules(ViewportStyleResolver&);
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
TreeScopeStyleSheetCollection::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/document_style_sheet_collector.cc b/chromium/third_party/blink/renderer/core/css/document_style_sheet_collector.cc
index 089bc33e2ef..3028abd3348 100644
--- a/chromium/third_party/blink/renderer/core/css/document_style_sheet_collector.cc
+++ b/chromium/third_party/blink/renderer/core/css/document_style_sheet_collector.cc
@@ -43,8 +43,6 @@ DocumentStyleSheetCollector::DocumentStyleSheetCollector(
style_sheets_for_style_sheet_list_(sheets_for_list),
visited_documents_(visited_documents) {}
-DocumentStyleSheetCollector::~DocumentStyleSheetCollector() = default;
-
void DocumentStyleSheetCollector::AppendActiveStyleSheet(
const ActiveStyleSheet& sheet) {
DCHECK(collection_);
diff --git a/chromium/third_party/blink/renderer/core/css/document_style_sheet_collector.h b/chromium/third_party/blink/renderer/core/css/document_style_sheet_collector.h
index 7bd33f73c98..bb6f4a928f4 100644
--- a/chromium/third_party/blink/renderer/core/css/document_style_sheet_collector.h
+++ b/chromium/third_party/blink/renderer/core/css/document_style_sheet_collector.h
@@ -50,7 +50,6 @@ class DocumentStyleSheetCollector {
DocumentStyleSheetCollector(StyleSheetCollection*,
HeapVector<Member<StyleSheet>>*,
HeapHashSet<Member<Document>>*);
- ~DocumentStyleSheetCollector();
void AppendActiveStyleSheet(const ActiveStyleSheet&);
void AppendSheetForList(StyleSheet*);
@@ -61,7 +60,7 @@ class DocumentStyleSheetCollector {
void WillVisit(Document* document) { visited_documents_->insert(document); }
private:
- Member<StyleSheetCollection> collection_;
+ StyleSheetCollection* collection_;
HeapVector<Member<StyleSheet>>* style_sheets_for_style_sheet_list_;
HeapHashSet<Member<Document>>* visited_documents_;
};
diff --git a/chromium/third_party/blink/renderer/core/css/dom_window_css.cc b/chromium/third_party/blink/renderer/core/css/dom_window_css.cc
index 1f83329c0b4..d3133caa4b7 100644
--- a/chromium/third_party/blink/renderer/core/css/dom_window_css.cc
+++ b/chromium/third_party/blink/renderer/core/css/dom_window_css.cc
@@ -43,7 +43,8 @@ namespace blink {
bool DOMWindowCSS::supports(const ExecutionContext* execution_context,
const String& property,
const String& value) {
- CSSPropertyID unresolved_property = unresolvedCSSPropertyID(property);
+ CSSPropertyID unresolved_property =
+ unresolvedCSSPropertyID(execution_context, property);
if (unresolved_property == CSSPropertyID::kInvalid)
return false;
if (unresolved_property == CSSPropertyID::kVariable) {
@@ -59,7 +60,7 @@ bool DOMWindowCSS::supports(const ExecutionContext* execution_context,
#if DCHECK_IS_ON()
DCHECK(CSSProperty::Get(resolveCSSPropertyID(unresolved_property))
- .IsWebExposed());
+ .IsWebExposed(execution_context));
#endif
// This will return false when !important is present
diff --git a/chromium/third_party/blink/renderer/core/css/dom_window_css.h b/chromium/third_party/blink/renderer/core/css/dom_window_css.h
index dd39a14ce5e..5e97263b191 100644
--- a/chromium/third_party/blink/renderer/core/css/dom_window_css.h
+++ b/chromium/third_party/blink/renderer/core/css/dom_window_css.h
@@ -30,6 +30,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_DOM_WINDOW_CSS_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_DOM_WINDOW_CSS_H_
+#include "third_party/blink/renderer/core/core_export.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/wtf/forward.h"
@@ -38,7 +39,7 @@ namespace blink {
class ExecutionContext;
-class DOMWindowCSS : public ScriptWrappable {
+class CORE_EXPORT DOMWindowCSS : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
diff --git a/chromium/third_party/blink/renderer/core/css/drag_update_test.cc b/chromium/third_party/blink/renderer/core/css/drag_update_test.cc
index 5f884f83607..99bee956462 100644
--- a/chromium/third_party/blink/renderer/core/css/drag_update_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/drag_update_test.cc
@@ -18,7 +18,7 @@ TEST(DragUpdateTest, AffectedByDragUpdate) {
auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
Document& document = dummy_page_holder->GetDocument();
- document.documentElement()->SetInnerHTMLFromString(R"HTML(
+ document.documentElement()->setInnerHTML(R"HTML(
<style>div {width:100px;height:100px} div:-webkit-drag {
background-color: green }</style>
<div id='div'>
@@ -29,13 +29,11 @@ TEST(DragUpdateTest, AffectedByDragUpdate) {
</div>
)HTML");
- document.View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ document.View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
unsigned start_count = document.GetStyleEngine().StyleForElementCount();
document.getElementById("div")->SetDragged(true);
- document.View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ document.View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
unsigned element_count =
document.GetStyleEngine().StyleForElementCount() - start_count;
@@ -49,7 +47,7 @@ TEST(DragUpdateTest, ChildAffectedByDragUpdate) {
auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
Document& document = dummy_page_holder->GetDocument();
- document.documentElement()->SetInnerHTMLFromString(R"HTML(
+ document.documentElement()->setInnerHTML(R"HTML(
<style>div {width:100px;height:100px} div:-webkit-drag .drag {
background-color: green }</style>
<div id='div'>
@@ -60,11 +58,11 @@ TEST(DragUpdateTest, ChildAffectedByDragUpdate) {
</div>
)HTML");
- document.UpdateStyleAndLayout();
+ document.UpdateStyleAndLayout(DocumentUpdateReason::kTest);
unsigned start_count = document.GetStyleEngine().StyleForElementCount();
document.getElementById("div")->SetDragged(true);
- document.UpdateStyleAndLayout();
+ document.UpdateStyleAndLayout(DocumentUpdateReason::kTest);
unsigned element_count =
document.GetStyleEngine().StyleForElementCount() - start_count;
@@ -78,7 +76,7 @@ TEST(DragUpdateTest, SiblingAffectedByDragUpdate) {
auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
Document& document = dummy_page_holder->GetDocument();
- document.documentElement()->SetInnerHTMLFromString(R"HTML(
+ document.documentElement()->setInnerHTML(R"HTML(
<style>div {width:100px;height:100px} div:-webkit-drag + .drag {
background-color: green }</style>
<div id='div'>
@@ -90,11 +88,11 @@ TEST(DragUpdateTest, SiblingAffectedByDragUpdate) {
<span class='drag'></span>
)HTML");
- document.UpdateStyleAndLayout();
+ document.UpdateStyleAndLayout(DocumentUpdateReason::kTest);
unsigned start_count = document.GetStyleEngine().StyleForElementCount();
document.getElementById("div")->SetDragged(true);
- document.UpdateStyleAndLayout();
+ document.UpdateStyleAndLayout(DocumentUpdateReason::kTest);
unsigned element_count =
document.GetStyleEngine().StyleForElementCount() - start_count;
diff --git a/chromium/third_party/blink/renderer/core/css/element_rule_collector.cc b/chromium/third_party/blink/renderer/core/css/element_rule_collector.cc
index e76a9e60d33..84e0377e7d4 100644
--- a/chromium/third_party/blink/renderer/core/css/element_rule_collector.cc
+++ b/chromium/third_party/blink/renderer/core/css/element_rule_collector.cc
@@ -48,9 +48,22 @@
namespace blink {
+namespace {
+
+unsigned AdjustLinkMatchType(EInsideLink inside_link,
+ unsigned link_match_type) {
+ if (inside_link == EInsideLink::kNotInsideLink)
+ return CSSSelector::kMatchLink;
+ return link_match_type;
+}
+
+} // namespace
+
ElementRuleCollector::ElementRuleCollector(const ElementResolveContext& context,
const SelectorFilter& filter,
- ComputedStyle* style)
+ MatchResult& result,
+ ComputedStyle* style,
+ EInsideLink inside_link)
: context_(context),
selector_filter_(filter),
style_(style),
@@ -60,7 +73,9 @@ ElementRuleCollector::ElementRuleCollector(const ElementResolveContext& context,
selector_filter_.ParentStackIsConsistent(context.ParentNode())),
same_origin_only_(false),
matching_ua_rules_(false),
- include_empty_rules_(false) {}
+ include_empty_rules_(false),
+ inside_link_(inside_link),
+ result_(result) {}
ElementRuleCollector::~ElementRuleCollector() = default;
@@ -99,7 +114,9 @@ void ElementRuleCollector::AddElementStyleProperties(
bool is_cacheable) {
if (!property_set)
return;
- result_.AddMatchedProperties(property_set);
+ auto link_match_type = static_cast<unsigned>(CSSSelector::kMatchAll);
+ result_.AddMatchedProperties(
+ property_set, AdjustLinkMatchType(inside_link_, link_match_type));
if (!is_cacheable)
result_.SetIsCacheable(false);
}
@@ -326,7 +343,8 @@ void ElementRuleCollector::SortAndTransferMatchedRules() {
for (unsigned i = 0; i < matched_rules_.size(); i++) {
const RuleData* rule_data = matched_rules_[i].GetRuleData();
result_.AddMatchedProperties(
- &rule_data->Rule()->Properties(), rule_data->LinkMatchType(),
+ &rule_data->Rule()->Properties(),
+ AdjustLinkMatchType(inside_link_, rule_data->LinkMatchType()),
rule_data->GetValidPropertyFilter(matching_ua_rules_));
}
}
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 31444ad2754..a98fc111be3 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
@@ -31,6 +31,7 @@
#include "third_party/blink/renderer/core/css/resolver/match_request.h"
#include "third_party/blink/renderer/core/css/resolver/match_result.h"
#include "third_party/blink/renderer/core/css/selector_checker.h"
+#include "third_party/blink/renderer/core/style/computed_style_base_constants.h"
#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -75,7 +76,7 @@ class MatchedRule {
return GetRuleData()->Specificity() + specificity_;
}
const CSSStyleSheet* ParentStyleSheet() const { return parent_style_sheet_; }
- void Trace(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
visitor->Trace(parent_style_sheet_);
visitor->Trace(rule_data_);
}
@@ -109,7 +110,9 @@ class ElementRuleCollector {
public:
ElementRuleCollector(const ElementResolveContext&,
const SelectorFilter&,
- ComputedStyle* = nullptr);
+ MatchResult&,
+ ComputedStyle*,
+ EInsideLink);
~ElementRuleCollector();
void SetMode(SelectorChecker::Mode mode) { mode_ = mode; }
@@ -188,13 +191,14 @@ class ElementRuleCollector {
bool same_origin_only_;
bool matching_ua_rules_;
bool include_empty_rules_;
+ EInsideLink inside_link_;
HeapVector<MatchedRule, 32> matched_rules_;
// Output.
Member<RuleIndexList> css_rule_list_;
Member<StyleRuleList> style_rule_list_;
- MatchResult result_;
+ MatchResult& result_;
DISALLOW_COPY_AND_ASSIGN(ElementRuleCollector);
};
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 978de58faad..1a11168bd2f 100644
--- a/chromium/third_party/blink/renderer/core/css/font_face.cc
+++ b/chromium/third_party/blink/renderer/core/css/font_face.cc
@@ -32,6 +32,7 @@
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_array_buffer_or_array_buffer_view.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_font_face_descriptors.h"
#include "third_party/blink/renderer/core/css/binary_data_font_face_source.h"
#include "third_party/blink/renderer/core/css/css_font_face.h"
#include "third_party/blink/renderer/core/css/css_font_face_src_value.h"
@@ -42,7 +43,6 @@
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
#include "third_party/blink/renderer/core/css/css_unicode_range_value.h"
#include "third_party/blink/renderer/core/css/css_value_list.h"
-#include "third_party/blink/renderer/core/css/font_face_descriptors.h"
#include "third_party/blink/renderer/core/css/local_font_face_source.h"
#include "third_party/blink/renderer/core/css/offscreen_font_selector.h"
#include "third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.h"
@@ -54,6 +54,7 @@
#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/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/typed_arrays/dom_array_buffer.h"
@@ -76,9 +77,9 @@ const CSSValue* ParseCSSValue(const ExecutionContext* context,
const String& value,
AtRuleDescriptorID descriptor_id) {
CSSParserContext* parser_context =
- IsA<Document>(context)
- ? MakeGarbageCollected<CSSParserContext>(*To<Document>(context))
- : MakeGarbageCollected<CSSParserContext>(*context);
+ context->IsDocument() ? MakeGarbageCollected<CSSParserContext>(
+ *To<LocalDOMWindow>(context)->document())
+ : MakeGarbageCollected<CSSParserContext>(*context);
return AtRuleDescriptorParser::ParseFontFaceDescriptor(descriptor_id, value,
*parser_context);
}
@@ -171,7 +172,8 @@ FontFace* FontFace::Create(Document* document,
if (!src || !src->IsValueList())
return nullptr;
- FontFace* font_face = MakeGarbageCollected<FontFace>(document);
+ FontFace* font_face =
+ MakeGarbageCollected<FontFace>(document->GetExecutionContext());
if (font_face->SetFamilyValue(*family) &&
font_face->SetPropertyFromStyle(properties,
@@ -190,19 +192,19 @@ FontFace* FontFace::Create(Document* document,
AtRuleDescriptorID::FontDisplay) &&
font_face->GetFontSelectionCapabilities().IsValid() &&
!font_face->family().IsEmpty()) {
- font_face->InitCSSFontFace(document, *src);
+ font_face->InitCSSFontFace(document->GetExecutionContext(), *src);
return font_face;
}
return nullptr;
}
FontFace::FontFace(ExecutionContext* context)
- : ContextClient(context), status_(kUnloaded) {}
+ : ExecutionContextClient(context), status_(kUnloaded) {}
FontFace::FontFace(ExecutionContext* context,
const AtomicString& family,
const FontFaceDescriptors* descriptors)
- : ContextClient(context), family_(family), status_(kUnloaded) {
+ : ExecutionContextClient(context), family_(family), status_(kUnloaded) {
SetPropertyFromString(context, descriptors->style(),
AtRuleDescriptorID::FontStyle);
SetPropertyFromString(context, descriptors->weight(),
@@ -380,9 +382,6 @@ bool FontFace::SetFamilyValue(const CSSValue& value) {
case CSSValueID::kMonospace:
family = font_family_names::kWebkitMonospace;
break;
- case CSSValueID::kWebkitPictograph:
- family = font_family_names::kWebkitPictograph;
- break;
default:
return false;
}
@@ -463,7 +462,7 @@ void FontFace::SetError(DOMException* error) {
ScriptPromise FontFace::FontStatusPromise(ScriptState* script_state) {
if (!loaded_property_) {
loaded_property_ = MakeGarbageCollected<LoadedProperty>(
- ExecutionContext::From(script_state), this, LoadedProperty::kLoaded);
+ ExecutionContext::From(script_state));
if (status_ == kLoaded)
loaded_property_->Resolve(this);
else if (status_ == kError)
@@ -475,6 +474,7 @@ ScriptPromise FontFace::FontStatusPromise(ScriptState* script_state) {
ScriptPromise FontFace::load(ScriptState* script_state) {
if (status_ == kUnloaded)
css_font_face_->Load();
+ DidBeginImperativeLoad();
return FontStatusPromise(script_state);
}
@@ -556,8 +556,17 @@ FontSelectionCapabilities FontFace::GetFontSelectionCapabilities() const {
return normal_capabilities;
if (!stretch_from->IsPercentage() || !stretch_to->IsPercentage())
return normal_capabilities;
- capabilities.width = {FontSelectionValue(stretch_from->GetFloatValue()),
- FontSelectionValue(stretch_to->GetFloatValue())};
+ // https://drafts.csswg.org/css-fonts/#font-prop-desc
+ // "User agents must swap the computed value of the startpoint and
+ // endpoint of the range in order to forbid decreasing ranges."
+ if (stretch_from->GetFloatValue() < stretch_to->GetFloatValue()) {
+ capabilities.width = {FontSelectionValue(stretch_from->GetFloatValue()),
+ FontSelectionValue(stretch_to->GetFloatValue())};
+ } else {
+ capabilities.width = {
+ FontSelectionValue(stretch_to->GetFloatValue()),
+ FontSelectionValue(stretch_from->GetFloatValue())};
+ }
} else if (auto* stretch_primitive_value =
DynamicTo<CSSPrimitiveValue>(stretch_.Get())) {
float stretch_value = stretch_primitive_value->GetFloatValue();
@@ -610,9 +619,18 @@ FontSelectionCapabilities FontFace::GetFontSelectionCapabilities() const {
To<CSSPrimitiveValue>(range_value->GetObliqueValues()->Item(0));
const auto& range_end =
To<CSSPrimitiveValue>(range_value->GetObliqueValues()->Item(1));
- capabilities.slope = {
- FontSelectionValue(range_start.GetFloatValue()),
- FontSelectionValue(range_end.GetFloatValue())};
+ // https://drafts.csswg.org/css-fonts/#font-prop-desc
+ // "User agents must swap the computed value of the startpoint and
+ // endpoint of the range in order to forbid decreasing ranges."
+ if (range_start.GetFloatValue() < range_end.GetFloatValue()) {
+ capabilities.slope = {
+ FontSelectionValue(range_start.GetFloatValue()),
+ FontSelectionValue(range_end.GetFloatValue())};
+ } else {
+ capabilities.slope = {
+ FontSelectionValue(range_end.GetFloatValue()),
+ FontSelectionValue(range_start.GetFloatValue())};
+ }
}
}
}
@@ -655,8 +673,17 @@ FontSelectionCapabilities FontFace::GetFontSelectionCapabilities() const {
if (!weight_from->IsNumber() || !weight_to->IsNumber() ||
weight_from->GetFloatValue() < 1 || weight_to->GetFloatValue() > 1000)
return normal_capabilities;
- capabilities.weight = {FontSelectionValue(weight_from->GetFloatValue()),
- FontSelectionValue(weight_to->GetFloatValue())};
+ // https://drafts.csswg.org/css-fonts/#font-prop-desc
+ // "User agents must swap the computed value of the startpoint and
+ // endpoint of the range in order to forbid decreasing ranges."
+ if (weight_from->GetFloatValue() < weight_to->GetFloatValue()) {
+ capabilities.weight = {FontSelectionValue(weight_from->GetFloatValue()),
+ FontSelectionValue(weight_to->GetFloatValue())};
+ } else {
+ capabilities.weight = {
+ FontSelectionValue(weight_to->GetFloatValue()),
+ FontSelectionValue(weight_from->GetFloatValue())};
+ }
} else if (auto* weight_primitive_value =
DynamicTo<CSSPrimitiveValue>(weight_.Get())) {
float weight_value = weight_primitive_value->GetFloatValue();
@@ -683,8 +710,9 @@ bool ContextAllowsDownload(ExecutionContext* context) {
if (!context) {
return false;
}
- if (const Document* document = DynamicTo<Document>(context)) {
- const Settings* settings = document->GetSettings();
+ if (const auto* window = DynamicTo<LocalDOMWindow>(context)) {
+ const Settings* settings =
+ window->GetFrame() ? window->GetFrame()->GetSettings() : nullptr;
return settings && settings->GetDownloadableBinaryFontsEnabled();
}
// TODO(fserb): ideally, we would like to have the settings value available
@@ -708,8 +736,8 @@ void FontFace::InitCSSFontFace(ExecutionContext* context, const CSSValue& src) {
const CSSFontFaceSrcValue& item = To<CSSFontFaceSrcValue>(src_list.Item(i));
FontSelector* font_selector = nullptr;
- if (auto* document = DynamicTo<Document>(context)) {
- font_selector = document->GetStyleEngine().GetFontSelector();
+ if (auto* window = DynamicTo<LocalDOMWindow>(context)) {
+ font_selector = window->document()->GetStyleEngine().GetFontSelector();
} else if (auto* scope = DynamicTo<WorkerGlobalScope>(context)) {
font_selector = scope->GetFontSelector();
} else {
@@ -756,7 +784,7 @@ void FontFace::InitCSSFontFace(const unsigned char* data, size_t size) {
css_font_face_->AddSource(source);
}
-void FontFace::Trace(blink::Visitor* visitor) {
+void FontFace::Trace(Visitor* visitor) {
visitor->Trace(style_);
visitor->Trace(weight_);
visitor->Trace(stretch_);
@@ -769,7 +797,7 @@ void FontFace::Trace(blink::Visitor* visitor) {
visitor->Trace(css_font_face_);
visitor->Trace(callbacks_);
ScriptWrappable::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
bool FontFace::HadBlankText() const {
@@ -784,4 +812,9 @@ FontDisplay FontFace::GetFontDisplay() const {
return CSSValueToFontDisplay(display_.Get());
}
+void FontFace::DidBeginImperativeLoad() {
+ if (GetDocument())
+ GetDocument()->GetFontPreloadManager().ImperativeFontLoadingStarted(this);
+}
+
} // namespace blink
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 b6ac8235889..b7eb9d0725e 100644
--- a/chromium/third_party/blink/renderer/core/css/font_face.h
+++ b/chromium/third_party/blink/renderer/core/css/font_face.h
@@ -39,7 +39,7 @@
#include "third_party/blink/renderer/core/css/font_display.h"
#include "third_party/blink/renderer/core/css/parser/at_rule_descriptors.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/fonts/font_selection_types.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -59,7 +59,7 @@ class StyleRuleFontFace;
class CORE_EXPORT FontFace : public ScriptWrappable,
public ActiveScriptWrappable<FontFace>,
- public ContextClient {
+ public ExecutionContextClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(FontFace);
@@ -115,7 +115,7 @@ class CORE_EXPORT FontFace : public ScriptWrappable,
size_t ApproximateBlankCharacterCount() const;
FontDisplay GetFontDisplay() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
bool HadBlankText() const;
@@ -124,11 +124,13 @@ class CORE_EXPORT FontFace : public ScriptWrappable,
virtual ~LoadFontCallback() = default;
virtual void NotifyLoaded(FontFace*) = 0;
virtual void NotifyError(FontFace*) = 0;
- void Trace(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) override {}
};
void LoadWithCallback(LoadFontCallback*);
void AddCallback(LoadFontCallback*);
+ void DidBeginImperativeLoad();
+
// ScriptWrappable:
bool HasPendingActivity() const final;
@@ -159,7 +161,6 @@ class CORE_EXPORT FontFace : public ScriptWrappable,
void RunCallbacks();
using LoadedProperty = ScriptPromiseProperty<Member<FontFace>,
- Member<FontFace>,
Member<DOMException>>;
AtomicString family_;
diff --git a/chromium/third_party/blink/renderer/core/css/font_face.idl b/chromium/third_party/blink/renderer/core/css/font_face.idl
index 3487e4d2386..90baf8a8b66 100644
--- a/chromium/third_party/blink/renderer/core/css/font_face.idl
+++ b/chromium/third_party/blink/renderer/core/css/font_face.idl
@@ -39,12 +39,10 @@ enum FontFaceLoadStatus {
[
ActiveScriptWrappable,
- Exposed=(Window,Worker),
- // FIXME: This should be (DOMString or BinaryData), where BinaryData is typedef of (ArrayBuffer or ArrayBufferView)
- Constructor(DOMString family, (DOMString or ArrayBuffer or ArrayBufferView) source, optional FontFaceDescriptors descriptors),
- ConstructorCallWith=ExecutionContext,
- MeasureAs=FontFaceConstructor
+ Exposed=(Window,Worker)
] interface FontFace {
+ // FIXME: This should be (DOMString or BinaryData), where BinaryData is typedef of (ArrayBuffer or ArrayBufferView)
+ [CallWith=ExecutionContext, MeasureAs=FontFaceConstructor] constructor(DOMString family, (DOMString or ArrayBuffer or ArrayBufferView) source, optional FontFaceDescriptors descriptors = {});
[RaisesException=Setter, SetterCallWith=ExecutionContext] attribute DOMString family;
[RaisesException=Setter, SetterCallWith=ExecutionContext] attribute DOMString style;
[RaisesException=Setter, SetterCallWith=ExecutionContext] attribute DOMString weight;
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 7d1e21737d3..2f978936161 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(blink::Visitor* visitor) {
+void FontFaceCache::Trace(Visitor* visitor) {
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 cfec05eee93..3253979d209 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(blink::Visitor*);
+ void Trace(Visitor*);
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 8937f200d5a..1c05906fd6a 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(blink::Visitor*);
+ void Trace(Visitor*);
protected:
const AtomicString kFontNameForTesting{"Arial"};
@@ -64,7 +64,7 @@ void FontFaceCacheTest::AppendTestFaceForCapabilities(const CSSValue& stretch,
CSSFontFamilyValue* family_name =
CSSFontFamilyValue::Create(kFontNameForTesting);
CSSFontFaceSrcValue* src = CSSFontFaceSrcValue::CreateLocal(
- kFontNameForTesting, kDoNotCheckContentSecurityPolicy,
+ kFontNameForTesting, network::mojom::CSPDisposition::DO_NOT_CHECK,
OriginClean::kTrue);
CSSValueList* src_value_list = CSSValueList::CreateCommaSeparated();
src_value_list->Append(*src);
@@ -494,7 +494,7 @@ TEST_F(FontFaceCacheTest, ObliqueRangeMatching) {
FontSelectionRange({FontSelectionValue(30), FontSelectionValue(35)}));
}
-void FontFaceCacheTest::Trace(blink::Visitor* visitor) {
+void FontFaceCacheTest::Trace(Visitor* visitor) {
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 7c1d4d832ed..c137ca35c91 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
@@ -106,13 +106,13 @@ bool FontFaceSet::hasForBinding(ScriptState*,
IsCSSConnectedFontFace(font_face);
}
-void FontFaceSet::Trace(blink::Visitor* visitor) {
+void FontFaceSet::Trace(Visitor* visitor) {
visitor->Trace(non_css_connected_faces_);
visitor->Trace(loading_fonts_);
visitor->Trace(loaded_fonts_);
visitor->Trace(failed_fonts_);
visitor->Trace(ready_);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
EventTargetWithInlineData::Trace(visitor);
FontFace::LoadFontCallback::Trace(visitor);
}
@@ -152,8 +152,10 @@ void FontFaceSet::LoadFontPromiseResolver::LoadFonts() {
return;
}
- for (wtf_size_t i = 0; i < font_faces_.size(); i++)
+ for (wtf_size_t i = 0; i < font_faces_.size(); i++) {
font_faces_[i]->LoadWithCallback(this);
+ font_faces_[i]->DidBeginImperativeLoad();
+ }
}
ScriptPromise FontFaceSet::load(ScriptState* script_state,
@@ -273,7 +275,7 @@ void FontFaceSet::LoadFontPromiseResolver::NotifyError(FontFace* font_face) {
}
}
-void FontFaceSet::LoadFontPromiseResolver::Trace(blink::Visitor* visitor) {
+void FontFaceSet::LoadFontPromiseResolver::Trace(Visitor* visitor) {
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 f71d240add9..17a41e25578 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
@@ -14,7 +14,7 @@
#include "third_party/blink/renderer/core/css/font_face.h"
#include "third_party/blink/renderer/core/dom/events/event_listener.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/fonts/font_selector.h"
@@ -31,17 +31,15 @@ class FontFaceCache;
using FontFaceSetIterable = SetlikeIterable<Member<FontFace>>;
class CORE_EXPORT FontFaceSet : public EventTargetWithInlineData,
- public ContextClient,
+ public ExecutionContextClient,
public FontFaceSetIterable,
public FontFace::LoadFontCallback {
DEFINE_WRAPPERTYPEINFO();
public:
FontFaceSet(ExecutionContext& context)
- : ContextClient(&context),
- ready_(MakeGarbageCollected<ReadyProperty>(GetExecutionContext(),
- this,
- ReadyProperty::kReady)) {}
+ : ExecutionContextClient(&context),
+ ready_(MakeGarbageCollected<ReadyProperty>(GetExecutionContext())) {}
~FontFaceSet() override = default;
DEFINE_ATTRIBUTE_EVENT_LISTENER(loading, kLoading)
@@ -53,7 +51,7 @@ class CORE_EXPORT FontFaceSet : public EventTargetWithInlineData,
virtual ScriptPromise ready(ScriptState*) = 0;
ExecutionContext* GetExecutionContext() const override {
- return ContextClient::GetExecutionContext();
+ return ExecutionContextClient::GetExecutionContext();
}
const AtomicString& InterfaceName() const override {
@@ -70,7 +68,7 @@ class CORE_EXPORT FontFaceSet : public EventTargetWithInlineData,
wtf_size_t size() const;
virtual AtomicString status() const = 0;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
static const int kDefaultFontSize;
@@ -94,7 +92,6 @@ class CORE_EXPORT FontFaceSet : public EventTargetWithInlineData,
void FireDoneEvent();
using ReadyProperty = ScriptPromiseProperty<Member<FontFaceSet>,
- Member<FontFaceSet>,
Member<DOMException>>;
bool is_loading_ = false;
@@ -115,7 +112,7 @@ class CORE_EXPORT FontFaceSet : public EventTargetWithInlineData,
Member<FontFace>&,
ExceptionState&) override;
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(font_faces_);
FontFaceSetIterable::IterationSource::Trace(visitor);
}
@@ -131,11 +128,6 @@ class CORE_EXPORT FontFaceSet : public EventTargetWithInlineData,
USING_GARBAGE_COLLECTED_MIXIN(LoadFontPromiseResolver);
public:
- static LoadFontPromiseResolver* Create(FontFaceArray faces,
- ScriptState* script_state) {
- return MakeGarbageCollected<LoadFontPromiseResolver>(faces, script_state);
- }
-
LoadFontPromiseResolver(FontFaceArray faces, ScriptState* script_state)
: num_loading_(faces.size()),
error_occured_(false),
@@ -149,7 +141,7 @@ class CORE_EXPORT FontFaceSet : public EventTargetWithInlineData,
void NotifyLoaded(FontFace*) override;
void NotifyError(FontFace*) override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 4abf570d9b1..21d0ebce61f 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
@@ -25,6 +25,7 @@
#include "third_party/blink/renderer/core/css/font_face_set_document.h"
+#include "base/metrics/histogram_functions.h"
#include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
#include "third_party/blink/renderer/core/css/css_font_selector.h"
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
@@ -36,12 +37,12 @@
#include "third_party/blink/renderer/core/css/resolver/style_resolver.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/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/style/computed_style.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/instrumentation/histogram.h"
namespace blink {
@@ -49,14 +50,14 @@ namespace blink {
const char FontFaceSetDocument::kSupplementName[] = "FontFaceSetDocument";
FontFaceSetDocument::FontFaceSetDocument(Document& document)
- : FontFaceSet(document), Supplement<Document>(document) {
-}
+ : FontFaceSet(*document.GetExecutionContext()),
+ Supplement<Document>(document) {}
FontFaceSetDocument::~FontFaceSetDocument() = default;
bool FontFaceSetDocument::InActiveContext() const {
ExecutionContext* context = GetExecutionContext();
- return context && To<Document>(context)->IsActive();
+ return context && To<LocalDOMWindow>(context)->document()->IsActive();
}
@@ -103,7 +104,7 @@ ScriptPromise FontFaceSetDocument::ready(ScriptState* script_state) {
// changes and/or layout operations that may cause another font loads.
// So synchronously update style and layout here.
// This may trigger font loads, and replace |ready_| with a new Promise.
- GetDocument()->UpdateStyleAndLayout();
+ GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
}
return ready_->Promise(script_state->World());
}
@@ -156,8 +157,7 @@ bool FontFaceSetDocument::ResolveFontStyle(const String& font_string,
auto* font_selector = GetDocument()->GetStyleEngine().GetFontSelector();
FontDescription description =
FontStyleResolver::ComputeFont(*parsed_style, font_selector);
- font = Font(description);
- font.Update(font_selector);
+ font = Font(description, font_selector);
return true;
}
@@ -173,14 +173,16 @@ bool FontFaceSetDocument::ResolveFontStyle(const String& font_string,
style->SetFontDescription(default_font_description);
- style->GetFont().Update(style->GetFont().GetFontSelector());
-
GetDocument()->UpdateActiveStyle();
GetDocument()->EnsureStyleResolver().ComputeFont(
*GetDocument()->documentElement(), style.get(), *parsed_style);
font = style->GetFont();
- font.Update(GetFontSelector());
+
+ // StyleResolver::ComputeFont() should have set the document's FontSelector
+ // to |style|.
+ DCHECK_EQ(font.GetFontSelector(), GetFontSelector());
+
return true;
}
@@ -208,7 +210,7 @@ size_t FontFaceSetDocument::ApproximateBlankCharacterCount(Document& document) {
return 0;
}
-void FontFaceSetDocument::Trace(blink::Visitor* visitor) {
+void FontFaceSetDocument::Trace(Visitor* visitor) {
Supplement<Document>::Trace(visitor);
FontFaceSet::Trace(visitor);
}
@@ -224,9 +226,7 @@ void FontFaceSetDocument::FontLoadHistogram::UpdateStatus(FontFace* font_face) {
void FontFaceSetDocument::FontLoadHistogram::Record() {
if (status_ == kHadBlankText || status_ == kDidNotHaveBlankText) {
- DEFINE_STATIC_LOCAL(EnumerationHistogram, had_blank_text_histogram,
- ("WebFont.HadBlankText", 2));
- had_blank_text_histogram.Count(status_ == kHadBlankText ? 1 : 0);
+ base::UmaHistogramBoolean("WebFont.HadBlankText", status_ == kHadBlankText);
status_ = kReported;
}
}
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 3def99aa7ea..5ee0f4d01da 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
@@ -70,7 +70,7 @@ class CORE_EXPORT FontFaceSetDocument final : public FontFaceSet,
static void DidLayout(Document&);
static size_t ApproximateBlankCharacterCount(Document&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 7ecec065917..f1b44491aa5 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
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/core/css/font_face_set_load_event.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_font_face_set_load_event_init.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
namespace blink {
@@ -49,7 +50,7 @@ const AtomicString& FontFaceSetLoadEvent::InterfaceName() const {
return event_interface_names::kFontFaceSetLoadEvent;
}
-void FontFaceSetLoadEvent::Trace(blink::Visitor* visitor) {
+void FontFaceSetLoadEvent::Trace(Visitor* visitor) {
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 ca012ca0c24..4f332c15eb3 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
@@ -33,11 +33,12 @@
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/core/css/font_face.h"
-#include "third_party/blink/renderer/core/css/font_face_set_load_event_init.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
namespace blink {
+class FontFaceSetLoadEventInit;
+
class FontFaceSetLoadEvent final : public Event {
DEFINE_WRAPPERTYPEINFO();
@@ -62,7 +63,7 @@ class FontFaceSetLoadEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
FontFaceArray fontfaces_;
diff --git a/chromium/third_party/blink/renderer/core/css/font_face_set_load_event.idl b/chromium/third_party/blink/renderer/core/css/font_face_set_load_event.idl
index 59da6a5c39b..a85f1cbeec4 100644
--- a/chromium/third_party/blink/renderer/core/css/font_face_set_load_event.idl
+++ b/chromium/third_party/blink/renderer/core/css/font_face_set_load_event.idl
@@ -31,9 +31,9 @@
// https://drafts.csswg.org/css-font-loading/#fontfacesetloadevent
[
- Constructor(DOMString type, optional FontFaceSetLoadEventInit eventInitDict),
// TODO(loonybear): Exposed=(Window,Worker)
Exposed=Window
] interface FontFaceSetLoadEvent : Event {
+ constructor(DOMString type, optional FontFaceSetLoadEventInit eventInitDict = {});
[SameObject] readonly attribute FrozenArray<FontFace> 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 6135290fc34..00350f89d2a 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
@@ -97,8 +97,7 @@ bool FontFaceSetWorker::ResolveFontStyle(const String& font_string,
FontDescription description = FontStyleResolver::ComputeFont(
*parsed_style, GetWorker()->GetFontSelector());
- font = Font(description);
- font.Update(GetWorker()->GetFontSelector());
+ font = Font(description, GetWorker()->GetFontSelector());
return true;
}
diff --git a/chromium/third_party/blink/renderer/core/css/font_face_source.h b/chromium/third_party/blink/renderer/core/css/font_face_source.h
index 02a8d197b00..ac53642711a 100644
--- a/chromium/third_party/blink/renderer/core/css/font_face_source.h
+++ b/chromium/third_party/blink/renderer/core/css/font_face_source.h
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_FONT_FACE_SOURCE_H_
#include "base/memory/scoped_refptr.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"
@@ -15,7 +16,7 @@ class Document;
class FontFaceSet;
class WorkerGlobalScope;
-class FontFaceSource {
+class CORE_EXPORT FontFaceSource {
STATIC_ONLY(FontFaceSource);
public:
diff --git a/chromium/third_party/blink/renderer/core/css/fullscreen.css b/chromium/third_party/blink/renderer/core/css/fullscreen.css
index 7ed4f7704cc..a0982cad72b 100644
--- a/chromium/third_party/blink/renderer/core/css/fullscreen.css
+++ b/chromium/third_party/blink/renderer/core/css/fullscreen.css
@@ -65,10 +65,3 @@ iframe:fullscreen {
background-color: black !important;
z-index: 2147483647 !important;
}
-
-/* WebXR DOM Overlay for handheld AR needs a transparent background for both the
- fullscreened element and its backdrop. */
-:-internal-xr-immersive-dom-overlay :fullscreen,
-:-internal-xr-immersive-dom-overlay :fullscreen::backdrop {
- background-color: rgba(0,0,0,0) !important;
-}
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 77cf6154914..08c14c61351 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
@@ -41,9 +41,6 @@ void InlineCSSStyleDeclaration::DidMutate(MutationType type) {
return;
parent_element_->ClearMutableInlineStyleIfEmpty();
- parent_element_->SetNeedsStyleRecalc(
- kLocalStyleChange, StyleChangeReasonForTracing::Create(
- style_change_reason::kInlineCSSStyleMutated));
parent_element_->InvalidateStyleAttribute();
StyleAttributeMutationScope(this).DidInvalidateStyleAttr();
}
@@ -53,7 +50,7 @@ CSSStyleSheet* InlineCSSStyleDeclaration::ParentStyleSheet() const {
: nullptr;
}
-void InlineCSSStyleDeclaration::Trace(blink::Visitor* visitor) {
+void InlineCSSStyleDeclaration::Trace(Visitor* visitor) {
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 127c9d8944d..85f004cfdfa 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
@@ -27,18 +27,20 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_INLINE_CSS_STYLE_DECLARATION_H_
#include "third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/dom/element.h"
namespace blink {
-class Element;
-
class InlineCSSStyleDeclaration final
: public AbstractPropertySetCSSStyleDeclaration {
public:
explicit InlineCSSStyleDeclaration(Element* parent_element)
- : parent_element_(parent_element) {}
+ : AbstractPropertySetCSSStyleDeclaration(
+ parent_element ? parent_element->GetExecutionContext() : nullptr),
+ parent_element_(parent_element) {}
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
MutableCSSPropertyValueSet& PropertySet() const override;
diff --git a/chromium/third_party/blink/renderer/core/css/invalidation/invalidation_set.cc b/chromium/third_party/blink/renderer/core/css/invalidation/invalidation_set.cc
index e73fe97dc50..108a3417d3d 100644
--- a/chromium/third_party/blink/renderer/core/css/invalidation/invalidation_set.cc
+++ b/chromium/third_party/blink/renderer/core/css/invalidation/invalidation_set.cc
@@ -366,11 +366,11 @@ void InvalidationSet::ToTracedValue(TracedValue* value) const {
#ifndef NDEBUG
void InvalidationSet::Show() const {
- auto value = std::make_unique<TracedValue>();
- value->BeginArray("InvalidationSet");
- ToTracedValue(value.get());
- value->EndArray();
- fprintf(stderr, "%s\n", value->ToString().Ascii().c_str());
+ TracedValueJSON value;
+ value.BeginArray("InvalidationSet");
+ ToTracedValue(&value);
+ value.EndArray();
+ LOG(ERROR) << value.ToJSON().Ascii();
}
#endif // NDEBUG
diff --git a/chromium/third_party/blink/renderer/core/css/invalidation/invalidation_set_test.cc b/chromium/third_party/blink/renderer/core/css/invalidation/invalidation_set_test.cc
index de9261c178b..b17fc85138c 100644
--- a/chromium/third_party/blink/renderer/core/css/invalidation/invalidation_set_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/invalidation/invalidation_set_test.cc
@@ -264,9 +264,8 @@ TEST(InvalidationSetTest, Backing_GetHashSet) {
TEST(InvalidationSetTest, ClassInvalidatesElement) {
auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
auto& document = dummy_page_holder->GetDocument();
- document.body()->SetInnerHTMLFromString("<div id=test class='a b'>");
- document.View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ document.body()->setInnerHTML("<div id=test class='a b'>");
+ document.View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
Element* element = document.getElementById("test");
ASSERT_TRUE(element);
@@ -290,9 +289,8 @@ TEST(InvalidationSetTest, ClassInvalidatesElement) {
TEST(InvalidationSetTest, AttributeInvalidatesElement) {
auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
auto& document = dummy_page_holder->GetDocument();
- document.body()->SetInnerHTMLFromString("<div id=test a b>");
- document.View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ document.body()->setInnerHTML("<div id=test a b>");
+ document.View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
Element* element = document.getElementById("test");
ASSERT_TRUE(element);
diff --git a/chromium/third_party/blink/renderer/core/css/invalidation/pending_invalidations.cc b/chromium/third_party/blink/renderer/core/css/invalidation/pending_invalidations.cc
index 678a929e4a3..9453376b596 100644
--- a/chromium/third_party/blink/renderer/core/css/invalidation/pending_invalidations.cc
+++ b/chromium/third_party/blink/renderer/core/css/invalidation/pending_invalidations.cc
@@ -26,6 +26,7 @@ void PendingInvalidations::ScheduleInvalidationSetsForNode(
const InvalidationLists& invalidation_lists,
ContainerNode& node) {
DCHECK(node.InActiveDocument());
+ DCHECK(!node.GetDocument().InStyleRecalc());
bool requires_descendant_invalidation = false;
if (node.GetStyleChangeType() < kSubtreeStyleChange) {
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 6090c79df0c..798d166581a 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,9 +81,7 @@ class CORE_EXPORT PendingInvalidations {
PendingInvalidationMap& GetPendingInvalidationMap() {
return pending_invalidation_map_;
}
- void Trace(blink::Visitor* visitor) {
- visitor->Trace(pending_invalidation_map_);
- }
+ void Trace(Visitor* visitor) { visitor->Trace(pending_invalidation_map_); }
private:
NodeInvalidationSets& EnsurePendingInvalidations(ContainerNode&);
diff --git a/chromium/third_party/blink/renderer/core/css/invalidation/pending_invalidations_test.cc b/chromium/third_party/blink/renderer/core/css/invalidation/pending_invalidations_test.cc
index fe8dbcfccfb..6529bfdd074 100644
--- a/chromium/third_party/blink/renderer/core/css/invalidation/pending_invalidations_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/invalidation/pending_invalidations_test.cc
@@ -31,10 +31,9 @@ void PendingInvalidationsTest::SetUp() {
}
TEST_F(PendingInvalidationsTest, ScheduleOnDocumentNode) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<div id='d'></div><i id='i'></i><span></span>");
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
unsigned before_count = GetStyleEngine().StyleForElementCount();
@@ -58,14 +57,13 @@ TEST_F(PendingInvalidationsTest, ScheduleOnDocumentNode) {
EXPECT_FALSE(GetDocument().NeedsStyleRecalc());
EXPECT_TRUE(GetStyleEngine().NeedsStyleRecalc());
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
unsigned after_count = GetStyleEngine().StyleForElementCount();
EXPECT_EQ(2u, after_count - before_count);
}
TEST_F(PendingInvalidationsTest, DescendantInvalidationOnDisplayNone) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
#a { display: none }
.a .b { color: green }
@@ -76,8 +74,7 @@ TEST_F(PendingInvalidationsTest, DescendantInvalidationOnDisplayNone) {
</div>
)HTML");
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
// We skip scheduling descendant invalidations on display:none elements.
GetDocument().getElementById("a")->setAttribute(html_names::kClassAttr, "a");
diff --git a/chromium/third_party/blink/renderer/core/css/invalidation/style_invalidator_test.cc b/chromium/third_party/blink/renderer/core/css/invalidation/style_invalidator_test.cc
index ed8c8d7df20..e1daed984c0 100644
--- a/chromium/third_party/blink/renderer/core/css/invalidation/style_invalidator_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/invalidation/style_invalidator_test.cc
@@ -25,7 +25,7 @@ class StyleInvalidatorTest : public testing::Test {
};
TEST_F(StyleInvalidatorTest, SkipDisplayNone) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<div id="root">
<div style="display:none">
<div class="a"></div>
@@ -34,8 +34,7 @@ TEST_F(StyleInvalidatorTest, SkipDisplayNone) {
</div>
)HTML");
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
PendingInvalidations pending;
{
@@ -54,7 +53,7 @@ TEST_F(StyleInvalidatorTest, SkipDisplayNone) {
}
TEST_F(StyleInvalidatorTest, SkipDisplayNoneClearPendingNth) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<div id="none" style="display:none">
<div class="a"></div>
<div class="a"></div>
@@ -64,8 +63,7 @@ TEST_F(StyleInvalidatorTest, SkipDisplayNoneClearPendingNth) {
</div>
)HTML");
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
PendingInvalidations pending;
{
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 d3dfe3edc73..38d08f4d909 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
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/css/local_font_face_source.h"
+#include "base/metrics/histogram_functions.h"
#include "build/build_config.h"
#include "third_party/blink/renderer/core/css/css_custom_font_data.h"
#include "third_party/blink/renderer/core/css/css_font_face.h"
@@ -14,7 +15,6 @@
#include "third_party/blink/renderer/platform/fonts/font_unique_name_lookup.h"
#include "third_party/blink/renderer/platform/fonts/simple_font_data.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
@@ -38,8 +38,16 @@ bool LocalFontFaceSource::IsLocalNonBlocking() const {
bool LocalFontFaceSource::IsLocalFontAvailable(
const FontDescription& font_description) const {
- return FontCache::GetFontCache()->IsPlatformFontUniqueNameMatchAvailable(
- font_description, font_name_);
+ // TODO(crbug.com/1027158): Remove metrics code after metrics collected.
+ // TODO(crbug.com/1025945): Properly handle Windows prior to 10 and Android.
+ bool font_available =
+ FontCache::GetFontCache()->IsPlatformFontUniqueNameMatchAvailable(
+ font_description, font_name_);
+ if (font_available)
+ font_selector_->ReportSuccessfulLocalFontMatch(font_name_);
+ else
+ font_selector_->ReportFailedLocalFontMatch(font_name_);
+ return font_available;
}
scoped_refptr<SimpleFontData>
@@ -130,12 +138,10 @@ void LocalFontFaceSource::LocalFontHistograms::Record(bool load_success) {
if (reported_)
return;
reported_ = true;
- DEFINE_STATIC_LOCAL(EnumerationHistogram, local_font_used_histogram,
- ("WebFont.LocalFontUsed", 2));
- local_font_used_histogram.Count(load_success ? 1 : 0);
+ base::UmaHistogramBoolean("WebFont.LocalFontUsed", load_success);
}
-void LocalFontFaceSource::Trace(blink::Visitor* visitor) {
+void LocalFontFaceSource::Trace(Visitor* visitor) {
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 8dc55e00610..2e2dbe30b35 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(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
void NotifyFontUniqueNameLookupReady();
diff --git a/chromium/third_party/blink/renderer/core/css/mathml.css b/chromium/third_party/blink/renderer/core/css/mathml.css
index 514a4621f75..5adc7b167ce 100644
--- a/chromium/third_party/blink/renderer/core/css/mathml.css
+++ b/chromium/third_party/blink/renderer/core/css/mathml.css
@@ -29,11 +29,11 @@
/* By default, we only display the MathML formulas without any formatting other than the one specified by the display attribute. */
math {
- display: inline;
+ display: inline-math;
}
math[display="block"] {
- display: block;
+ display: math;
text-align: center;
}
@@ -46,13 +46,25 @@ math[display="block"] {
outline: auto 1px -webkit-focus-ring-color;
}
-/* We hide the PresentationExpression constructions that are children of a <semantics> element.
- http://www.w3.org/TR/MathML/appendixa.html#parsing_PresentationExpression */
-semantics > mi, semantics > mn, semantics > mo, semantics > mtext, semantics > mspace, semantics > ms, semantics > maligngroup, semantics > malignmark, semantics > mrow, semantics > mfrac, semantics > msqrt, semantics > mroot, semantics > mstyle, semantics > merror, semantics > mpadded, semantics > mphantom, semantics > mfenced, semantics > menclose, semantics > msub, semantics > msup, semantics > msubsup, semantics > munder, semantics > mover, semantics > munderover, semantics > mmultiscripts, semantics > mtable, semantics > mstack, semantics > mlongdiv, semantics > maction {
- display: none;
+maction, merror, mfrac, mphantom, mrow, mspace, mstyle
+{
+ display: math;
}
-/* However, we display all the annotations. */
-annotation, annotation-xml {
- display: inline-block;
+mphantom {
+ visibility: hidden;
+}
+
+merror {
+ color: red;
+ background-color: lightYellow;
+}
+
+mspace {
+ overflow: hidden !important;
+}
+
+mfrac {
+ padding-inline-start: 1px;
+ padding-inline-end: 1px;
}
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 b78aa49241e..cd214bc0f89 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
@@ -49,6 +49,8 @@
"min-width",
"min-resolution",
"navigation-controls",
+ // This feature only exists to test out origin-trial infrastructure.
+ "origin-trial-test",
"pointer",
"prefers-color-scheme",
"prefers-reduced-motion",
diff --git a/chromium/third_party/blink/renderer/core/css/media_feature_overrides.cc b/chromium/third_party/blink/renderer/core/css/media_feature_overrides.cc
index c6a0850d57b..fb953f83f6b 100644
--- a/chromium/third_party/blink/renderer/core/css/media_feature_overrides.cc
+++ b/chromium/third_party/blink/renderer/core/css/media_feature_overrides.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/css/media_feature_overrides.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_tokenizer.h"
@@ -14,7 +15,23 @@ void MediaFeatureOverrides::SetOverride(const AtomicString& feature,
CSSTokenizer tokenizer(value_string);
const auto tokens = tokenizer.TokenizeToEOF();
CSSParserTokenRange range(tokens);
- auto value = MediaQueryExp::Create(feature, range).ExpValue();
+
+ // TODO(xiaochengh): This is a fake CSSParserContext that only passes
+ // down the CSSParserMode. Plumb the real CSSParserContext through, so that
+ // web features can be counted correctly.
+ const CSSParserContext* fake_context = MakeGarbageCollected<CSSParserContext>(
+ kHTMLStandardMode, SecureContextMode::kInsecureContext);
+
+ // MediaFeatureOverrides are used to emulate various media feature values.
+ // These don't need to pass an ExecutionContext, since the parsing of
+ // the actual CSS will determine whether or not the emulated values will come
+ // into play (i.e. if you can parse an origin trial enabled feature, you
+ // will never ask for the emulated override value).
+ // Note that once a real CSSParserContext is plumbed through we can use its
+ // Document to get the ExecutionContext so the extra parameter should be
+ // removed.
+ auto value =
+ MediaQueryExp::Create(feature, range, *fake_context, nullptr).ExpValue();
if (value.IsValid())
overrides_.Set(feature, value);
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 b2b2456075e..2e25f0fde73 100644
--- a/chromium/third_party/blink/renderer/core/css/media_list.cc
+++ b/chromium/third_party/blink/renderer/core/css/media_list.cc
@@ -57,15 +57,18 @@ MediaQuerySet::MediaQuerySet(const MediaQuerySet& o)
queries_[i] = o.queries_[i]->Copy();
}
-scoped_refptr<MediaQuerySet> MediaQuerySet::Create(const String& media_string) {
+scoped_refptr<MediaQuerySet> MediaQuerySet::Create(
+ const String& media_string,
+ const ExecutionContext* execution_context) {
if (media_string.IsEmpty())
return MediaQuerySet::Create();
- return MediaQueryParser::ParseMediaQuerySet(media_string);
+ return MediaQueryParser::ParseMediaQuerySet(media_string, execution_context);
}
-bool MediaQuerySet::Set(const String& media_string) {
- scoped_refptr<MediaQuerySet> result = Create(media_string);
+bool MediaQuerySet::Set(const String& media_string,
+ const ExecutionContext* execution_context) {
+ scoped_refptr<MediaQuerySet> result = Create(media_string, execution_context);
// TODO(keishi) Changed DCHECK to CHECK for crbug.com/699269 diagnosis
for (const auto& query : result->queries_) {
CHECK(query);
@@ -74,11 +77,12 @@ bool MediaQuerySet::Set(const String& media_string) {
return true;
}
-bool MediaQuerySet::Add(const String& query_string) {
+bool MediaQuerySet::Add(const String& query_string,
+ const ExecutionContext* execution_context) {
// To "parse a media query" for a given string means to follow "the parse
// a media query list" steps and return "null" if more than one media query
// is returned, or else the returned media query.
- scoped_refptr<MediaQuerySet> result = Create(query_string);
+ scoped_refptr<MediaQuerySet> result = Create(query_string, execution_context);
// Only continue if exactly one media query is found, as described above.
if (result->queries_.size() != 1)
@@ -100,11 +104,13 @@ bool MediaQuerySet::Add(const String& query_string) {
return true;
}
-bool MediaQuerySet::Remove(const String& query_string_to_remove) {
+bool MediaQuerySet::Remove(const String& query_string_to_remove,
+ const ExecutionContext* execution_context) {
// To "parse a media query" for a given string means to follow "the parse
// a media query list" steps and return "null" if more than one media query
// is returned, or else the returned media query.
- scoped_refptr<MediaQuerySet> result = Create(query_string_to_remove);
+ scoped_refptr<MediaQuerySet> result =
+ Create(query_string_to_remove, execution_context);
// Only continue if exactly one media query is found, as described above.
if (result->queries_.size() != 1)
@@ -161,10 +167,11 @@ MediaList::MediaList(scoped_refptr<MediaQuerySet> media_queries,
parent_style_sheet_(nullptr),
parent_rule_(parent_rule) {}
-void MediaList::setMediaText(const String& value) {
+void MediaList::setMediaText(const ExecutionContext* execution_context,
+ const String& value) {
CSSStyleSheet::RuleMutationScope mutation_scope(parent_rule_);
- media_queries_->Set(value);
+ media_queries_->Set(value, execution_context);
if (parent_style_sheet_)
parent_style_sheet_->DidMutate();
@@ -178,11 +185,12 @@ String MediaList::item(unsigned index) const {
return String();
}
-void MediaList::deleteMedium(const String& medium,
+void MediaList::deleteMedium(const ExecutionContext* execution_context,
+ const String& medium,
ExceptionState& exception_state) {
CSSStyleSheet::RuleMutationScope mutation_scope(parent_rule_);
- bool success = media_queries_->Remove(medium);
+ bool success = media_queries_->Remove(medium, execution_context);
if (!success) {
exception_state.ThrowDOMException(DOMExceptionCode::kNotFoundError,
"Failed to delete '" + medium + "'.");
@@ -192,10 +200,11 @@ void MediaList::deleteMedium(const String& medium,
parent_style_sheet_->DidMutate();
}
-void MediaList::appendMedium(const String& medium) {
+void MediaList::appendMedium(const ExecutionContext* execution_context,
+ const String& medium) {
CSSStyleSheet::RuleMutationScope mutation_scope(parent_rule_);
- bool added = media_queries_->Add(medium);
+ bool added = media_queries_->Add(medium, execution_context);
if (!added)
return;
@@ -212,7 +221,7 @@ void MediaList::Reattach(scoped_refptr<MediaQuerySet> media_queries) {
media_queries_ = media_queries;
}
-void MediaList::Trace(blink::Visitor* visitor) {
+void MediaList::Trace(Visitor* visitor) {
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 e9f697b132b..61781552ee5 100644
--- a/chromium/third_party/blink/renderer/core/css/media_list.h
+++ b/chromium/third_party/blink/renderer/core/css/media_list.h
@@ -35,6 +35,7 @@ namespace blink {
class CSSRule;
class CSSStyleSheet;
class ExceptionState;
+class ExecutionContext;
class MediaList;
class MediaQuery;
@@ -43,11 +44,12 @@ class CORE_EXPORT MediaQuerySet : public RefCounted<MediaQuerySet> {
static scoped_refptr<MediaQuerySet> Create() {
return base::AdoptRef(new MediaQuerySet());
}
- static scoped_refptr<MediaQuerySet> Create(const String& media_string);
+ static scoped_refptr<MediaQuerySet> Create(const String& media_string,
+ const ExecutionContext*);
- bool Set(const String&);
- bool Add(const String&);
- bool Remove(const String&);
+ bool Set(const String&, const ExecutionContext*);
+ bool Add(const String&, const ExecutionContext*);
+ bool Remove(const String&, const ExecutionContext*);
void AddMediaQuery(std::unique_ptr<MediaQuery>);
@@ -77,11 +79,18 @@ class MediaList final : public ScriptWrappable {
unsigned length() const { return media_queries_->QueryVector().size(); }
String item(unsigned index) const;
- void deleteMedium(const String& old_medium, ExceptionState&);
- void appendMedium(const String& new_medium);
-
- String mediaText() const { return media_queries_->MediaText(); }
- void setMediaText(const String&);
+ void deleteMedium(const ExecutionContext*,
+ const String& old_medium,
+ ExceptionState&);
+ void appendMedium(const ExecutionContext*, const String& new_medium);
+
+ // Note that this getter doesn't require the ExecutionContext, but the
+ // attribute is marked as [CallWith=ExecutionContext] so that the setter can
+ // have access to the ExecutionContext.
+ String mediaText(const ExecutionContext*) const {
+ return media_queries_->MediaText();
+ }
+ void setMediaText(const ExecutionContext*, const String&);
// Not part of CSSOM.
CSSRule* ParentRule() const { return parent_rule_; }
@@ -91,7 +100,7 @@ class MediaList final : public ScriptWrappable {
void Reattach(scoped_refptr<MediaQuerySet>);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
scoped_refptr<MediaQuerySet> media_queries_;
diff --git a/chromium/third_party/blink/renderer/core/css/media_list.idl b/chromium/third_party/blink/renderer/core/css/media_list.idl
index 6b33f759b76..dc9484d94d0 100644
--- a/chromium/third_party/blink/renderer/core/css/media_list.idl
+++ b/chromium/third_party/blink/renderer/core/css/media_list.idl
@@ -28,9 +28,9 @@
[
Exposed=Window
] interface MediaList {
- stringifier attribute [TreatNullAs=EmptyString] DOMString mediaText;
+ [CallWith=ExecutionContext] stringifier attribute [TreatNullAs=EmptyString] DOMString mediaText;
readonly attribute unsigned long length;
[Measure] getter DOMString? item(unsigned long index);
- void appendMedium(DOMString medium);
- [RaisesException] void deleteMedium(DOMString medium);
+ [CallWith=ExecutionContext] void appendMedium(DOMString medium);
+ [CallWith=ExecutionContext, RaisesException] void deleteMedium(DOMString medium);
};
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 ae21ebd3dcf..1a091ab8789 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
@@ -84,7 +84,7 @@ MediaQueryEvaluator::MediaQueryEvaluator(
MediaQueryEvaluator::~MediaQueryEvaluator() = default;
-void MediaQueryEvaluator::Trace(blink::Visitor* visitor) {
+void MediaQueryEvaluator::Trace(Visitor* visitor) {
visitor->Trace(media_values_);
}
@@ -101,9 +101,8 @@ const String MediaQueryEvaluator::MediaType() const {
bool MediaQueryEvaluator::MediaTypeMatch(
const String& media_type_to_match) const {
return media_type_to_match.IsEmpty() ||
- DeprecatedEqualIgnoringCase(media_type_to_match,
- media_type_names::kAll) ||
- DeprecatedEqualIgnoringCase(media_type_to_match, MediaType());
+ EqualIgnoringASCIICase(media_type_to_match, media_type_names::kAll) ||
+ EqualIgnoringASCIICase(media_type_to_match, MediaType());
}
static bool ApplyRestrictor(MediaQuery::RestrictorType r, bool value) {
@@ -158,6 +157,15 @@ bool MediaQueryEvaluator::Eval(
return result;
}
+bool MediaQueryEvaluator::DidResultsChange(
+ const MediaQueryResultList& results) const {
+ for (auto& result : results) {
+ if (Eval(result.Expression()) != result.Result())
+ return true;
+ }
+ return false;
+}
+
template <typename T>
bool CompareValue(T a, T b, MediaFeaturePrefix op) {
switch (op) {
@@ -323,11 +331,11 @@ static bool EvalResolution(const MediaQueryExpValue& value,
// this method only got called if this media type matches the one defined
// in the query. Thus, if if the document's media type is "print", the
// media type of the query will either be "print" or "all".
- if (DeprecatedEqualIgnoringCase(media_values.MediaType(),
- media_type_names::kScreen)) {
+ if (EqualIgnoringASCIICase(media_values.MediaType(),
+ media_type_names::kScreen)) {
actual_resolution = clampTo<float>(media_values.DevicePixelRatio());
- } else if (DeprecatedEqualIgnoringCase(media_values.MediaType(),
- media_type_names::kPrint)) {
+ } else if (EqualIgnoringASCIICase(media_values.MediaType(),
+ media_type_names::kPrint)) {
// The resolution of images while printing should not depend on the DPI
// of the screen. Until we support proper ways of querying this info
// we use 300px which is considered minimum for current printers.
@@ -687,6 +695,15 @@ static bool AnyHoverMediaFeatureEval(const MediaQueryExpValue& value,
}
}
+static bool OriginTrialTestMediaFeatureEval(const MediaQueryExpValue& value,
+ MediaFeaturePrefix,
+ const MediaValues& media_values) {
+ // The test feature only supports a 'no-value' parsing. So if we've gotten
+ // to this point it will always match.
+ DCHECK(!value.IsValid());
+ return true;
+}
+
static bool PointerMediaFeatureEval(const MediaQueryExpValue& value,
MediaFeaturePrefix,
const MediaValues& media_values) {
@@ -769,8 +786,7 @@ static bool ScanMediaFeatureEval(const MediaQueryExpValue& value,
MediaFeaturePrefix,
const MediaValues& media_values) {
// Scan only applies to 'tv' media.
- if (!DeprecatedEqualIgnoringCase(media_values.MediaType(),
- media_type_names::kTv))
+ if (!EqualIgnoringASCIICase(media_values.MediaType(), media_type_names::kTv))
return false;
if (!value.IsValid())
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 570e0ff096b..2d9e016d8fe 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
@@ -94,7 +94,11 @@ class CORE_EXPORT MediaQueryEvaluator final
// Evaluates media query subexpression, ie "and (media-feature: value)" part.
bool Eval(const MediaQueryExp&) const;
- void Trace(blink::Visitor*);
+ // Returns true if any of the expressions in the results lists changed its
+ // evaluation.
+ bool DidResultsChange(const MediaQueryResultList& results) const;
+
+ void Trace(Visitor*);
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 e7bfdefb089..998370f4203 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
@@ -210,7 +210,7 @@ void TestMQEvaluator(MediaQueryEvaluatorTestCase* test_cases,
query_set = MediaQueryParser::ParseMediaQuerySetInMode(
CSSParserTokenRange(
CSSTokenizer(test_cases[i].input).TokenizeToEOF()),
- mode);
+ mode, nullptr);
}
EXPECT_EQ(test_cases[i].output, media_query_evaluator.Eval(*query_set))
<< "Query: " << test_cases[i].input;
@@ -300,7 +300,8 @@ TEST(MediaQueryEvaluatorTest, DynamicNoView) {
page_holder.reset();
ASSERT_EQ(nullptr, frame->View());
MediaQueryEvaluator media_query_evaluator(frame);
- scoped_refptr<MediaQuerySet> query_set = MediaQuerySet::Create("foobar");
+ scoped_refptr<MediaQuerySet> query_set =
+ MediaQuerySet::Create("foobar", nullptr);
EXPECT_FALSE(media_query_evaluator.Eval(*query_set));
}
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 3600f2f55b0..37d0f166736 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
@@ -32,6 +32,7 @@
#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/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/html/parser/html_parser_idioms.h"
@@ -80,11 +81,9 @@ static inline bool FeatureWithValidIdent(const String& media_feature,
ident == CSSValueID::kRec2020;
}
- if (RuntimeEnabledFeatures::MediaQueryPrefersColorSchemeEnabled()) {
- 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::kNoPreference || ident == CSSValueID::kDark ||
+ ident == CSSValueID::kLight;
}
if (media_feature == media_feature_names::kPrefersReducedMotionMediaFeature)
@@ -186,7 +185,9 @@ static inline bool FeatureWithAspectRatio(const String& media_feature) {
media_feature == kMaxDeviceAspectRatioMediaFeature;
}
-static inline bool FeatureWithoutValue(const String& media_feature) {
+static inline bool FeatureWithoutValue(
+ const String& media_feature,
+ const ExecutionContext* execution_context) {
// Media features that are prefixed by min/max cannot be used without a value.
return media_feature == media_feature_names::kMonochromeMediaFeature ||
media_feature == media_feature_names::kColorMediaFeature ||
@@ -208,15 +209,22 @@ static inline bool FeatureWithoutValue(const String& media_feature) {
media_feature == media_feature_names::kResolutionMediaFeature ||
media_feature == media_feature_names::kDisplayModeMediaFeature ||
media_feature == media_feature_names::kScanMediaFeature ||
- media_feature == media_feature_names::kShapeMediaFeature ||
+ (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::kForcedColorsMediaFeature ||
- media_feature == media_feature_names::kNavigationControlsMediaFeature;
+ (media_feature == media_feature_names::kForcedColorsMediaFeature &&
+ RuntimeEnabledFeatures::ForcedColorsEnabled()) ||
+ (media_feature ==
+ media_feature_names::kNavigationControlsMediaFeature &&
+ RuntimeEnabledFeatures::MediaQueryNavigationControlsEnabled()) ||
+ (media_feature == media_feature_names::kOriginTrialTestMediaFeature &&
+ RuntimeEnabledFeatures::OriginTrialsSampleAPIEnabled(
+ execution_context));
}
bool MediaQueryExp::IsViewportDependent() const {
@@ -259,22 +267,26 @@ MediaQueryExp::MediaQueryExp(const String& media_feature,
: media_feature_(media_feature), exp_value_(exp_value) {}
MediaQueryExp MediaQueryExp::Create(const String& media_feature,
- CSSParserTokenRange& range) {
+ CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ const ExecutionContext* execution_context) {
DCHECK(!media_feature.IsNull());
MediaQueryExpValue exp_value;
String lower_media_feature =
AttemptStaticStringCreation(media_feature.LowerASCII());
+ CSSParserContext::ParserModeOverridingScope scope(context, kHTMLStandardMode);
+
CSSPrimitiveValue* value =
- css_property_parser_helpers::ConsumeInteger(range, 0);
+ css_property_parser_helpers::ConsumeInteger(range, context, 0);
if (!value && !FeatureExpectingPositiveInteger(lower_media_feature) &&
!FeatureWithAspectRatio(lower_media_feature)) {
- value = css_property_parser_helpers::ConsumeNumber(range,
+ value = css_property_parser_helpers::ConsumeNumber(range, context,
kValueRangeNonNegative);
}
if (!value) {
- value = css_property_parser_helpers::ConsumeLength(range, kHTMLStandardMode,
+ value = css_property_parser_helpers::ConsumeLength(range, context,
kValueRangeNonNegative);
}
if (!value)
@@ -290,7 +302,7 @@ MediaQueryExp MediaQueryExp::Create(const String& media_feature,
exp_value.is_id = true;
return MediaQueryExp(lower_media_feature, exp_value);
}
- if (FeatureWithoutValue(lower_media_feature)) {
+ if (FeatureWithoutValue(lower_media_feature, execution_context)) {
// Valid, creates a MediaQueryExp with an 'invalid' MediaQueryExpValue
return MediaQueryExp(lower_media_feature, exp_value);
}
@@ -305,7 +317,7 @@ MediaQueryExp MediaQueryExp::Create(const String& media_feature,
if (!css_property_parser_helpers::ConsumeSlashIncludingWhitespace(range))
return Invalid();
CSSPrimitiveValue* denominator =
- css_property_parser_helpers::ConsumePositiveInteger(range);
+ css_property_parser_helpers::ConsumePositiveInteger(range, context);
if (!denominator)
return Invalid();
diff --git a/chromium/third_party/blink/renderer/core/css/media_query_exp.h b/chromium/third_party/blink/renderer/core/css/media_query_exp.h
index 7650002aefa..f579b0204e7 100644
--- a/chromium/third_party/blink/renderer/core/css/media_query_exp.h
+++ b/chromium/third_party/blink/renderer/core/css/media_query_exp.h
@@ -38,7 +38,9 @@
namespace blink {
+class CSSParserContext;
class CSSParserTokenRange;
+class ExecutionContext;
struct MediaQueryExpValue {
DISALLOW_NEW();
@@ -82,7 +84,9 @@ class CORE_EXPORT MediaQueryExp {
public:
// Returns an invalid MediaQueryExp if the arguments are invalid.
static MediaQueryExp Create(const String& media_feature,
- CSSParserTokenRange&);
+ CSSParserTokenRange&,
+ const CSSParserContext&,
+ const ExecutionContext*);
static MediaQueryExp Invalid() {
return MediaQueryExp(String(), MediaQueryExpValue());
}
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 cfce0042be6..8bd1ff1f1ab 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
@@ -30,7 +30,7 @@ namespace blink {
MediaQueryList::MediaQueryList(ExecutionContext* context,
MediaQueryMatcher* matcher,
scoped_refptr<MediaQuerySet> media)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
matcher_(matcher),
media_(media),
matches_dirty_(true),
@@ -72,7 +72,7 @@ bool MediaQueryList::HasPendingActivity() const {
(listeners_.size() || HasEventListeners(event_type_names::kChange));
}
-void MediaQueryList::ContextDestroyed(ExecutionContext*) {
+void MediaQueryList::ContextDestroyed() {
listeners_.clear();
RemoveAllEventListeners();
}
@@ -102,11 +102,11 @@ bool MediaQueryList::matches() {
return matches_;
}
-void MediaQueryList::Trace(blink::Visitor* visitor) {
+void MediaQueryList::Trace(Visitor* visitor) {
visitor->Trace(matcher_);
visitor->Trace(listeners_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
const AtomicString& MediaQueryList::InterfaceName() const {
@@ -114,7 +114,7 @@ const AtomicString& MediaQueryList::InterfaceName() const {
}
ExecutionContext* MediaQueryList::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
} // namespace blink
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 1d5b593a070..c09f4fcc05b 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
@@ -24,7 +24,7 @@
#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/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/wtf/forward.h"
@@ -45,7 +45,7 @@ class MediaQuerySet;
class CORE_EXPORT MediaQueryList final
: public EventTargetWithInlineData,
public ActiveScriptWrappable<MediaQueryList>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(MediaQueryList);
@@ -74,13 +74,13 @@ class CORE_EXPORT MediaQueryList final
bool MediaFeaturesChanged(
HeapVector<Member<MediaQueryListListener>>* listeners_to_notify);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// From ScriptWrappable
bool HasPendingActivity() const final;
- // From ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // From ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
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 f09b3f7053f..f9c0643b0b2 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
@@ -5,8 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_MEDIA_QUERY_LIST_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_MEDIA_QUERY_LIST_EVENT_H_
+#include "third_party/blink/renderer/bindings/core/v8/v8_media_query_list_event_init.h"
#include "third_party/blink/renderer/core/css/media_query_list.h"
-#include "third_party/blink/renderer/core/css/media_query_list_event_init.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
@@ -65,7 +65,7 @@ class MediaQueryListEvent final : public Event {
return true;
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
Event::Trace(visitor);
visitor->Trace(media_query_list_);
}
diff --git a/chromium/third_party/blink/renderer/core/css/media_query_list_event.idl b/chromium/third_party/blink/renderer/core/css/media_query_list_event.idl
index fdc30d5f4fb..2a2ae62692e 100644
--- a/chromium/third_party/blink/renderer/core/css/media_query_list_event.idl
+++ b/chromium/third_party/blink/renderer/core/css/media_query_list_event.idl
@@ -5,9 +5,9 @@
// https://drafts.csswg.org/cssom-view/#mediaquerylistevent
[
- Exposed=Window,
- Constructor(DOMString type, optional MediaQueryListEventInit eventInitDict)
+ Exposed=Window
] interface MediaQueryListEvent : Event {
+ constructor(DOMString type, optional MediaQueryListEventInit eventInitDict = {});
readonly attribute DOMString media;
readonly attribute boolean matches;
};
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 b589a88ea73..d448990a9ce 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(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
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 68cdeaa9580..85d8002d66b 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
@@ -25,10 +25,11 @@ class TestListener : public MediaQueryListListener {
TEST(MediaQueryListTest, CrashInStop) {
auto* document = MakeGarbageCollected<Document>();
auto* list = MakeGarbageCollected<MediaQueryList>(
- document, MakeGarbageCollected<MediaQueryMatcher>(*document),
+ document->GetExecutionContext(),
+ MakeGarbageCollected<MediaQueryMatcher>(*document),
MediaQuerySet::Create());
list->AddListener(MakeGarbageCollected<TestListener>());
- list->ContextDestroyed(document);
+ list->ContextDestroyed();
// This test passes if it's not crashed.
}
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 e532d32634f..d3685e88d86 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
@@ -71,8 +71,10 @@ MediaQueryList* MediaQueryMatcher::MatchMedia(const String& query) {
if (!document_)
return nullptr;
- scoped_refptr<MediaQuerySet> media = MediaQuerySet::Create(query);
- return MakeGarbageCollected<MediaQueryList>(document_, this, media);
+ scoped_refptr<MediaQuerySet> media =
+ MediaQuerySet::Create(query, document_->GetExecutionContext());
+ return MakeGarbageCollected<MediaQueryList>(document_->GetExecutionContext(),
+ this, media);
}
void MediaQueryMatcher::AddMediaQueryList(MediaQueryList* query) {
@@ -126,7 +128,7 @@ void MediaQueryMatcher::ViewportChanged() {
document_->EnqueueMediaQueryChangeListeners(listeners_to_notify);
}
-void MediaQueryMatcher::Trace(blink::Visitor* visitor) {
+void MediaQueryMatcher::Trace(Visitor* visitor) {
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 818119762de..63412b1895d 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
@@ -42,8 +42,6 @@ class MediaQuerySet;
class CORE_EXPORT MediaQueryMatcher final
: public GarbageCollected<MediaQueryMatcher> {
public:
- static MediaQueryMatcher* Create(Document&);
-
explicit MediaQueryMatcher(Document&);
~MediaQueryMatcher();
@@ -61,7 +59,7 @@ class CORE_EXPORT MediaQueryMatcher final
void ViewportChanged();
bool Evaluate(const MediaQuerySet*);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
MediaQueryEvaluator* CreateEvaluator() const;
diff --git a/chromium/third_party/blink/renderer/core/css/media_query_matcher_test.cc b/chromium/third_party/blink/renderer/core/css/media_query_matcher_test.cc
index 76cba48fc9b..4d3cef4436c 100644
--- a/chromium/third_party/blink/renderer/core/css/media_query_matcher_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/media_query_matcher_test.cc
@@ -17,7 +17,7 @@ TEST(MediaQueryMatcherTest, LostFrame) {
auto* matcher =
MakeGarbageCollected<MediaQueryMatcher>(page_holder->GetDocument());
scoped_refptr<MediaQuerySet> query_set =
- MediaQuerySet::Create(media_type_names::kAll);
+ MediaQuerySet::Create(media_type_names::kAll, nullptr);
ASSERT_TRUE(matcher->Evaluate(query_set.get()));
matcher->DocumentDetached();
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 603ae1dec74..fc00218599b 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
@@ -6,6 +6,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/css/media_list.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"
namespace blink {
@@ -184,7 +185,31 @@ TEST(MediaQuerySetTest, Basic) {
for (unsigned i = 0; test_cases[i].input; ++i) {
scoped_refptr<MediaQuerySet> query_set =
- MediaQuerySet::Create(test_cases[i].input);
+ MediaQuerySet::Create(test_cases[i].input, nullptr);
+ TestMediaQuery(test_cases[i], *query_set);
+ }
+}
+
+TEST(MediaQuerySetTest, BehindRuntimeFlag) {
+ ScopedMediaQueryShapeForTest shape_flag(false);
+ ScopedForcedColorsForTest forced_colors_flag(false);
+ ScopedMediaQueryNavigationControlsForTest navigation_controls_flag(false);
+
+ // 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"},
+ {"(shape: rect)", "not all"},
+ {"(forced-colors: none)", "not all"},
+ {"(navigation-controls: none)", "not all"},
+ {nullptr, nullptr} // Do not remove the terminator line.
+ };
+
+ for (unsigned i = 0; test_cases[i].input; ++i) {
+ scoped_refptr<MediaQuerySet> query_set =
+ MediaQuerySet::Create(test_cases[i].input, nullptr);
TestMediaQuery(test_cases[i], *query_set);
}
}
diff --git a/chromium/third_party/blink/renderer/core/css/media_value_change.h b/chromium/third_party/blink/renderer/core/css/media_value_change.h
new file mode 100644
index 00000000000..4f161cc725f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/media_value_change.h
@@ -0,0 +1,19 @@
+// 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_MEDIA_VALUE_CHANGE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_MEDIA_VALUE_CHANGE_H_
+
+namespace blink {
+
+enum class MediaValueChange {
+ // Viewport or device size changed. width/height/device-width/device-height.
+ kSize,
+ // Any other value which affect media query evaluations changed.
+ kOther,
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_MEDIA_VALUE_CHANGE_H_
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 f7c0484a11e..3ff366de0a8 100644
--- a/chromium/third_party/blink/renderer/core/css/media_values.cc
+++ b/chromium/third_party/blink/renderer/core/css/media_values.cc
@@ -20,7 +20,6 @@
#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/compositing/paint_layer_compositor.h"
#include "third_party/blink/renderer/platform/graphics/color_space_gamut.h"
namespace blink {
@@ -139,13 +138,7 @@ blink::mojom::DisplayMode MediaValues::CalculateDisplayMode(LocalFrame* frame) {
}
bool MediaValues::CalculateThreeDEnabled(LocalFrame* frame) {
- DCHECK(frame);
- DCHECK(frame->ContentLayoutObject());
- DCHECK(frame->ContentLayoutObject()->Compositor());
- bool three_d_enabled = false;
- if (LayoutView* view = frame->ContentLayoutObject())
- three_d_enabled = view->Compositor()->HasAcceleratedCompositing();
- return three_d_enabled;
+ return frame->GetPage()->GetSettings().GetAcceleratedCompositingEnabled();
}
bool MediaValues::CalculateInImmersiveMode(LocalFrame* frame) {
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 22d46d54110..9a774e643a6 100644
--- a/chromium/third_party/blink/renderer/core/css/media_values.h
+++ b/chromium/third_party/blink/renderer/core/css/media_values.h
@@ -28,7 +28,7 @@ PreferredColorScheme CSSValueIDToPreferredColorScheme(CSSValueID id);
class CORE_EXPORT MediaValues : public GarbageCollected<MediaValues> {
public:
virtual ~MediaValues() = default;
- virtual void Trace(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
static MediaValues* CreateDynamicIfFrameExists(LocalFrame*);
virtual MediaValues* Copy() const = 0;
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 6a1035ea3a5..0b80c39984c 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
@@ -168,7 +168,7 @@ bool MediaValuesDynamic::HasValues() const {
return frame_;
}
-void MediaValuesDynamic::Trace(blink::Visitor* visitor) {
+void MediaValuesDynamic::Trace(Visitor* visitor) {
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 8b73c573a91..779a9fb4b8d 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
@@ -56,7 +56,7 @@ class CORE_EXPORT MediaValuesDynamic : public MediaValues {
bool HasValues() const override;
void OverrideViewportDimensions(double width, double height) override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 892abac0870..2042a1618e6 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
@@ -93,6 +93,12 @@ void OffscreenFontSelector::ReportSuccessfulFontFamilyMatch(
void OffscreenFontSelector::ReportFailedFontFamilyMatch(
const AtomicString& font_family_name) {}
+void OffscreenFontSelector::ReportSuccessfulLocalFontMatch(
+ const AtomicString& font_name) {}
+
+void OffscreenFontSelector::ReportFailedLocalFontMatch(
+ const AtomicString& font_name) {}
+
void OffscreenFontSelector::FontCacheInvalidated() {
font_face_cache_.IncrementVersion();
}
@@ -101,7 +107,7 @@ void OffscreenFontSelector::FontFaceInvalidated() {
FontCacheInvalidated();
}
-void OffscreenFontSelector::Trace(blink::Visitor* visitor) {
+void OffscreenFontSelector::Trace(Visitor* visitor) {
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 e28be16abcb..0a32bc74468 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
@@ -34,6 +34,10 @@ class CORE_EXPORT OffscreenFontSelector : public FontSelector {
void ReportFailedFontFamilyMatch(
const AtomicString& font_family_name) override;
+ void ReportSuccessfulLocalFontMatch(const AtomicString& font_name) override;
+
+ void ReportFailedLocalFontMatch(const AtomicString& font_name) override;
+
scoped_refptr<FontData> GetFontData(const FontDescription&,
const AtomicString&) override;
void WillUseFontData(const FontDescription&,
@@ -65,7 +69,7 @@ class CORE_EXPORT OffscreenFontSelector : public FontSelector {
return execution_context_;
}
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 ff844b883dd..0b20fc696dc 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
@@ -64,10 +64,12 @@ String PageRuleCollector::PageName(int /* pageIndex */) const {
}
PageRuleCollector::PageRuleCollector(const ComputedStyle* root_element_style,
- int page_index)
+ int page_index,
+ 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_(PageName(page_index)),
+ result_(match_result) {}
void PageRuleCollector::MatchPageRules(RuleSet* rules) {
if (!rules)
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 065618bdcc1..f8fe90eb998 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
@@ -34,7 +34,9 @@ class PageRuleCollector {
STACK_ALLOCATED();
public:
- PageRuleCollector(const ComputedStyle* root_element_style, int page_index);
+ PageRuleCollector(const ComputedStyle* root_element_style,
+ int page_index,
+ MatchResult&);
void MatchPageRules(RuleSet* rules);
const MatchResult& MatchedResult() { return result_; }
@@ -59,7 +61,7 @@ class PageRuleCollector {
const bool is_first_page_;
const String page_name_;
- MatchResult result_;
+ MatchResult& result_;
};
} // namespace blink
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 ac9e91b9b56..78f9ce32541 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
@@ -73,7 +73,7 @@ CSSValueList* ConsumeFontFaceUnicodeRange(CSSParserTokenRange& range) {
CSSValue* ConsumeFontFaceSrcURI(CSSParserTokenRange& range,
const CSSParserContext& context) {
String url =
- css_property_parser_helpers::ConsumeUrlAsStringView(range, &context)
+ css_property_parser_helpers::ConsumeUrlAsStringView(range, context)
.ToString();
if (url.IsNull())
return nullptr;
@@ -101,7 +101,7 @@ CSSValue* ConsumeFontFaceSrcLocal(CSSParserTokenRange& range,
const CSSParserContext& context) {
CSSParserTokenRange args =
css_property_parser_helpers::ConsumeFunction(range);
- ContentSecurityPolicyDisposition should_check_content_security_policy =
+ network::mojom::CSPDisposition should_check_content_security_policy =
context.ShouldCheckContentSecurityPolicy();
if (args.Peek().GetType() == kStringToken) {
const CSSParserToken& arg = args.ConsumeIncludingWhitespace();
@@ -165,23 +165,30 @@ CSSValue* AtRuleDescriptorParser::ParseFontFaceDescriptor(
case AtRuleDescriptorID::FontDisplay:
parsed_value = ConsumeFontDisplay(range);
break;
- case AtRuleDescriptorID::FontStretch:
- parsed_value =
- css_parsing_utils::ConsumeFontStretch(range, kCSSFontFaceRuleMode);
+ case AtRuleDescriptorID::FontStretch: {
+ CSSParserContext::ParserModeOverridingScope scope(context,
+ kCSSFontFaceRuleMode);
+ parsed_value = css_parsing_utils::ConsumeFontStretch(range, context);
break;
- case AtRuleDescriptorID::FontStyle:
- parsed_value =
- css_parsing_utils::ConsumeFontStyle(range, kCSSFontFaceRuleMode);
+ }
+ case AtRuleDescriptorID::FontStyle: {
+ CSSParserContext::ParserModeOverridingScope scope(context,
+ kCSSFontFaceRuleMode);
+ parsed_value = css_parsing_utils::ConsumeFontStyle(range, context);
break;
+ }
case AtRuleDescriptorID::FontVariant:
parsed_value = ConsumeFontVariantList(range);
break;
- case AtRuleDescriptorID::FontWeight:
- parsed_value =
- css_parsing_utils::ConsumeFontWeight(range, kCSSFontFaceRuleMode);
+ case AtRuleDescriptorID::FontWeight: {
+ CSSParserContext::ParserModeOverridingScope scope(context,
+ kCSSFontFaceRuleMode);
+ parsed_value = css_parsing_utils::ConsumeFontWeight(range, context);
break;
+ }
case AtRuleDescriptorID::FontFeatureSettings:
- parsed_value = css_parsing_utils::ConsumeFontFeatureSettings(range);
+ parsed_value =
+ css_parsing_utils::ConsumeFontFeatureSettings(range, context);
break;
default:
break;
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 8f3dcbf5979..973f7c865ad 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css.proto
+++ b/chromium/third_party/blink/renderer/core/css/parser/css.proto
@@ -952,501 +952,496 @@ message Property {
_WEBKIT_MASK_POSITION_X = 65;
_WEBKIT_MASK_POSITION_Y = 66;
OUTLINE_STYLE = 67;
- _WEBKIT_MARGIN_BOTTOM_COLLAPSE = 68;
- COLOR_INTERPOLATION_FILTERS = 69;
- FONT_VARIANT = 70;
- _WEBKIT_ANIMATION_FILL_MODE = 71;
- BORDER_RIGHT = 72;
- VISIBILITY = 73;
- TRANSFORM_BOX = 74;
- FONT_VARIANT_CAPS = 75;
- _EPUB_TEXT_EMPHASIS_COLOR = 76;
- _WEBKIT_BORDER_BEFORE_STYLE = 77;
- RESIZE = 78;
- _WEBKIT_RTL_ORDERING = 79;
- _WEBKIT_BOX_ORDINAL_GROUP = 80;
- PAINT_ORDER = 81;
- STROKE_LINECAP = 82;
- ANIMATION_DIRECTION = 83;
- _WEBKIT_FONT_FEATURE_SETTINGS = 84;
- BORDER_TOP_LEFT_RADIUS = 85;
- _WEBKIT_COLUMN_WIDTH = 86;
- _WEBKIT_BOX_ALIGN = 87;
- _WEBKIT_PADDING_AFTER = 88;
- COLUMN_WIDTH = 89;
- LIST_STYLE = 90;
- _WEBKIT_MASK_REPEAT_Y = 91;
- _WEBKIT_MARGIN_BEFORE_COLLAPSE = 92;
- STROKE = 93;
- TEXT_DECORATION_LINE = 94;
- _WEBKIT_BACKGROUND_SIZE = 95;
- _WEBKIT_MASK_REPEAT_X = 96;
- PADDING_BOTTOM = 97;
- FONT_STYLE = 98;
- _WEBKIT_TRANSITION_DELAY = 99;
- BACKGROUND_REPEAT = 100;
- FLEX_BASIS = 101;
- BORDER_IMAGE_SLICE = 102;
- _WEBKIT_TRANSFORM_ORIGIN = 103;
- SCROLL_BOUNDARY_BEHAVIOR_X = 104;
- SCROLL_BOUNDARY_BEHAVIOR_Y = 105;
- VECTOR_EFFECT = 106;
- _WEBKIT_ANIMATION_TIMING_FUNCTION = 107;
- _WEBKIT_BORDER_AFTER_STYLE = 108;
- _WEBKIT_PERSPECTIVE_ORIGIN_X = 109;
- _WEBKIT_PERSPECTIVE_ORIGIN_Y = 110;
- INLINE_SIZE = 111;
- OUTLINE = 112;
- FONT_DISPLAY = 113;
- _WEBKIT_BORDER_BEFORE = 114;
- BORDER_IMAGE_SOURCE = 115;
- TRANSITION_DURATION = 116;
- SCROLL_PADDING_TOP = 117;
- ORDER = 118;
- _WEBKIT_BOX_ORIENT = 119;
- COUNTER_RESET = 120;
- COLOR_RENDERING = 121;
- FLEX_DIRECTION = 122;
- _WEBKIT_TEXT_STROKE_WIDTH = 123;
- FONT_VARIANT_NUMERIC = 124;
- SCROLL_MARGIN_BLOCK_END = 125;
- MIN_HEIGHT = 126;
- SCROLL_PADDING_INLINE_START = 127;
- _WEBKIT_MASK_BOX_IMAGE = 128;
- LEFT = 129;
- _WEBKIT_MASK = 130;
- _WEBKIT_BORDER_AFTER_WIDTH = 131;
- STROKE_WIDTH = 132;
- _WEBKIT_BOX_DECORATION_BREAK = 133;
- _WEBKIT_MASK_POSITION = 134;
- BACKGROUND_ORIGIN = 135;
- _WEBKIT_BORDER_START_COLOR = 136;
- FONT_STRETCH = 137;
- _WEBKIT_BACKGROUND_CLIP = 138;
- SCROLL_MARGIN_TOP = 139;
- _WEBKIT_BORDER_HORIZONTAL_SPACING = 140;
- BORDER_RADIUS = 141;
- FLEX = 142;
- TEXT_INDENT = 143;
- HYPHENS = 144;
- COLUMN_RULE_WIDTH = 145;
- _WEBKIT_MARGIN_AFTER = 146;
- _EPUB_CAPTION_SIDE = 147;
- BREAK_AFTER = 148;
- TEXT_TRANSFORM = 149;
- TOUCH_ACTION = 150;
- FONT_SIZE = 151;
- _WEBKIT_ANIMATION_NAME = 152;
- SCROLL_PADDING_INLINE = 153;
- OFFSET_PATH = 154;
- SCROLL_MARGIN = 155;
- PADDING_TOP = 156;
- SCROLL_SNAP_ALIGN = 157;
- _WEBKIT_TEXT_COMBINE = 158;
- _WEBKIT_FLEX_SHRINK = 159;
- RX = 160;
- RY = 161;
- CONTENT = 162;
- PADDING_RIGHT = 163;
- _WEBKIT_TRANSFORM = 164;
- MARKER_MID = 165;
- _WEBKIT_MIN_LOGICAL_WIDTH = 166;
- CLIP_RULE = 167;
- FONT_FAMILY = 168;
- SCROLL_SNAP_TYPE = 169;
- TEXT_DECORATION_SKIP_INK = 170;
- TRANSITION = 171;
- FILTER = 172;
- BORDER_RIGHT_WIDTH = 173;
- _WEBKIT_FLEX_DIRECTION = 174;
- _WEBKIT_MASK_COMPOSITE = 175;
- MIX_BLEND_MODE = 176;
- COLOR_INTERPOLATION = 177;
- BORDER_TOP_STYLE = 178;
- FILL_OPACITY = 179;
- MARKER_START = 180;
- BORDER_BOTTOM_WIDTH = 181;
- _WEBKIT_TEXT_EMPHASIS = 182;
- GRID_AREA = 183;
- SIZE = 184;
- BACKGROUND_CLIP = 185;
- _WEBKIT_TEXT_FILL_COLOR = 186;
- TOP = 187;
- _WEBKIT_BOX_REFLECT = 188;
- BORDER_WIDTH = 189;
- OFFSET_ANCHOR = 190;
- MAX_INLINE_SIZE = 191;
- _WEBKIT_COLUMN_RULE_STYLE = 192;
- _WEBKIT_COLUMN_COUNT = 193;
- ANIMATION_PLAY_STATE = 194;
- PADDING = 195;
- DOMINANT_BASELINE = 196;
- BACKGROUND_ATTACHMENT = 197;
- _WEBKIT_BOX_SIZING = 198;
- _WEBKIT_BOX_FLEX = 199;
- TEXT_ORIENTATION = 200;
- BACKGROUND_POSITION = 201;
- _WEBKIT_BORDER_START_WIDTH = 202;
- _EPUB_TEXT_EMPHASIS_STYLE = 203;
- ISOLATION = 204;
- _EPUB_TEXT_ORIENTATION = 205;
- _WEBKIT_BORDER_BOTTOM_RIGHT_RADIUS = 206;
- R = 207;
- BORDER_LEFT_WIDTH = 208;
- GRID_COLUMN_END = 209;
- BACKGROUND_BLEND_MODE = 210;
- VERTICAL_ALIGN = 211;
- CLIP = 212;
- GRID_AUTO_ROWS = 213;
- OFFSET_ROTATE = 214;
- MARGIN_LEFT = 215;
- ANIMATION_NAME = 216;
- TEXT_DECORATION = 217;
- BORDER = 218;
- _WEBKIT_TRANSITION_TIMING_FUNCTION = 219;
- MARGIN_BOTTOM = 220;
- UNICODE_RANGE = 221;
- ANIMATION = 222;
- _WEBKIT_SHAPE_MARGIN = 223;
- FONT_WEIGHT = 224;
- SHAPE_MARGIN = 225;
- MASK_TYPE = 226;
- SCROLL_PADDING = 227;
- MIN_INLINE_SIZE = 228;
- OBJECT_POSITION = 229;
- PAGE_BREAK_AFTER = 230;
- _WEBKIT_MASK_CLIP = 231;
- WHITE_SPACE = 232;
- _WEBKIT_BORDER_AFTER_COLOR = 233;
- _WEBKIT_MAX_LOGICAL_WIDTH = 234;
- _WEBKIT_BORDER_BEFORE_COLOR = 235;
- FONT_KERNING = 236;
- _EPUB_WORD_BREAK = 237;
- CLEAR = 238;
- ANIMATION_TIMING_FUNCTION = 239;
- _WEBKIT_BORDER_RADIUS = 240;
- SCROLL_PADDING_RIGHT = 241;
- _WEBKIT_TEXT_DECORATIONS_IN_EFFECT = 242;
- _WEBKIT_ANIMATION_DIRECTION = 243;
- JUSTIFY_SELF = 244;
- TRANSITION_TIMING_FUNCTION = 245;
- SCROLL_SNAP_STOP = 246;
- COUNTER_INCREMENT = 247;
- _WEBKIT_TRANSFORM_STYLE = 248;
- GRID_AUTO_COLUMNS = 249;
- _WEBKIT_ALIGN_CONTENT = 250;
- FONT = 251;
- FLEX_WRAP = 252;
- GRID_ROW_START = 253;
- LIST_STYLE_IMAGE = 254;
- _WEBKIT_TAP_HIGHLIGHT_COLOR = 255;
- _WEBKIT_TEXT_EMPHASIS_COLOR = 256;
- BORDER_LEFT = 257;
- _WEBKIT_BORDER_END_COLOR = 258;
- COLUMNS = 259;
- BOX_SHADOW = 260;
- _WEBKIT_FLEX_WRAP = 261;
- ALIGN_SELF = 262;
- BORDER_BOTTOM = 263;
- BORDER_SPACING = 264;
- _WEBKIT_COLUMN_SPAN = 265;
- GRID_ROW_END = 266;
- _WEBKIT_BORDER_END = 267;
- PERSPECTIVE_ORIGIN = 268;
- PAGE_BREAK_INSIDE = 269;
- ORPHANS = 270;
- _WEBKIT_BORDER_START_STYLE = 271;
- SCROLL_BEHAVIOR = 272;
- COLUMN_SPAN = 273;
- _WEBKIT_HYPHENATE_CHARACTER = 274;
- COLUMN_FILL = 275;
- TAB_SIZE = 276;
- CONTAIN = 277;
- X = 278;
- GRID_ROW = 279;
- BORDER_BOTTOM_RIGHT_RADIUS = 280;
- LINE_HEIGHT = 281;
- STROKE_LINEJOIN = 282;
- TEXT_ALIGN_LAST = 283;
- OFFSET_POSITION = 284;
- WORD_SPACING = 285;
- TRANSFORM_STYLE = 286;
- _WEBKIT_APP_REGION = 287;
- _WEBKIT_BORDER_END_STYLE = 288;
- _WEBKIT_TRANSFORM_ORIGIN_Z = 289;
- _WEBKIT_TRANSFORM_ORIGIN_X = 290;
- _WEBKIT_TRANSFORM_ORIGIN_Y = 291;
- BACKGROUND_REPEAT_X = 292;
- BACKGROUND_REPEAT_Y = 293;
- BORDER_BOTTOM_COLOR = 294;
- _WEBKIT_RUBY_POSITION = 295;
- _WEBKIT_LOGICAL_WIDTH = 296;
- TEXT_JUSTIFY = 297;
- SCROLL_MARGIN_INLINE_START = 298;
- CAPTION_SIDE = 299;
- MASK_SOURCE_TYPE = 300;
- _WEBKIT_MASK_BOX_IMAGE_SLICE = 301;
- _WEBKIT_BORDER_IMAGE = 302;
- TEXT_SIZE_ADJUST = 303;
- _WEBKIT_TEXT_SECURITY = 304;
- _EPUB_WRITING_MODE = 305;
- GRID_TEMPLATE = 306;
- _WEBKIT_MASK_BOX_IMAGE_REPEAT = 307;
- _WEBKIT_MASK_REPEAT = 308;
- _WEBKIT_JUSTIFY_CONTENT = 309;
- BASELINE_SHIFT = 310;
- BORDER_IMAGE = 311;
- TEXT_DECORATION_COLOR = 312;
- COLOR = 313;
- SHAPE_IMAGE_THRESHOLD = 314;
- SHAPE_RENDERING = 315;
- CY = 316;
- CX = 317;
- _WEBKIT_USER_MODIFY = 318;
- OFFSET_DISTANCE = 319;
- _WEBKIT_BORDER_BOTTOM_LEFT_RADIUS = 320;
- SPEAK = 321;
- BORDER_BOTTOM_LEFT_RADIUS = 322;
- _WEBKIT_COLUMN_BREAK_AFTER = 323;
- _WEBKIT_FONT_SMOOTHING = 324;
- _WEBKIT_MAX_LOGICAL_HEIGHT = 325;
- _WEBKIT_LINE_BREAK = 326;
- FILL_RULE = 327;
- _WEBKIT_MARGIN_START = 328;
- MIN_WIDTH = 329;
- _EPUB_TEXT_COMBINE = 330;
- BREAK_BEFORE = 331;
- CARET_COLOR = 332;
- EMPTY_CELLS = 333;
- DIRECTION = 334;
- CLIP_PATH = 335;
- JUSTIFY_CONTENT = 336;
- SCROLL_PADDING_BLOCK_END = 337;
- Z_INDEX = 338;
- BACKGROUND_POSITION_Y = 339;
- TEXT_DECORATION_STYLE = 340;
- GRID_TEMPLATE_AREAS = 341;
- _WEBKIT_MIN_LOGICAL_HEIGHT = 342;
- FONT_SIZE_ADJUST = 343;
- SCROLL_PADDING_BLOCK = 344;
- OVERFLOW_ANCHOR = 345;
- CURSOR = 346;
- SCROLL_MARGIN_BLOCK_START = 347;
- _WEBKIT_MASK_BOX_IMAGE_SOURCE = 348;
- MARGIN = 349;
- _WEBKIT_ANIMATION = 350;
- LETTER_SPACING = 351;
- ORIENTATION = 352;
- WILL_CHANGE = 353;
- _WEBKIT_HIGHLIGHT = 354;
- TRANSFORM_ORIGIN = 355;
- FONT_VARIANT_LIGATURES = 356;
- _WEBKIT_ANIMATION_DURATION = 357;
- _WEBKIT_MASK_ORIGIN = 358;
- _WEBKIT_CLIP_PATH = 359;
- WORD_BREAK = 360;
- TABLE_LAYOUT = 361;
- TEXT_OVERFLOW = 362;
- _WEBKIT_LOCALE = 363;
- _WEBKIT_FLEX = 364;
- GRID_AUTO_FLOW = 365;
- BORDER_TOP_RIGHT_RADIUS = 366;
- BORDER_IMAGE_OUTSET = 367;
- PLACE_ITEMS = 368;
- BORDER_LEFT_COLOR = 369;
- FONT_VARIATION_SETTINGS = 370;
- BORDER_RIGHT_COLOR = 371;
- MIN_ZOOM = 372;
- SCROLL_MARGIN_INLINE = 373;
- _WEBKIT_BORDER_BEFORE_WIDTH = 374;
- BACKFACE_VISIBILITY = 375;
- BACKGROUND_IMAGE = 376;
- _WEBKIT_TRANSITION_PROPERTY = 377;
- WRITING_MODE = 378;
- STROKE_OPACITY = 379;
- _WEBKIT_MARGIN_COLLAPSE = 380;
- BOX_SIZING = 381;
- MARGIN_TOP = 382;
- COLUMN_RULE_COLOR = 383;
- Y = 384;
- POSITION = 385;
- SCROLL_MARGIN_BOTTOM = 386;
- LIST_STYLE_POSITION = 387;
- _WEBKIT_BOX_PACK = 388;
- SCROLL_PADDING_INLINE_END = 389;
- QUOTES = 390;
- BORDER_TOP = 391;
- SCROLL_PADDING_LEFT = 392;
- _WEBKIT_TRANSITION = 393;
- _WEBKIT_COLUMN_BREAK_BEFORE = 394;
- LIGHTING_COLOR = 395;
- BACKGROUND_SIZE = 396;
- _WEBKIT_PADDING_BEFORE = 397;
- _WEBKIT_BORDER_TOP_LEFT_RADIUS = 398;
- FLOOD_OPACITY = 399;
- LINE_HEIGHT_STEP = 400;
- _WEBKIT_MASK_SIZE = 401;
- TEXT_ALIGN = 402;
- _WEBKIT_FILTER = 403;
- WORD_WRAP = 404;
- MAX_ZOOM = 405;
- GRID = 406;
- BACKGROUND = 407;
- HEIGHT = 408;
- GRID_COLUMN_START = 409;
- ANIMATION_FILL_MODE = 410;
- ROTATE = 411;
- MARKER_END = 412;
- D = 413;
- JUSTIFY_ITEMS = 414;
- ZOOM = 415;
- SCROLL_PADDING_BLOCK_START = 416;
- _WEBKIT_MARGIN_TOP_COLLAPSE = 417;
- PAGE = 418;
- RIGHT = 419;
- USER_SELECT = 420;
- MARGIN_RIGHT = 421;
- MARKER = 422;
- LINE_BREAK = 423;
- _WEBKIT_MARGIN_END = 424;
- _WEBKIT_TRANSITION_DURATION = 425;
- _WEBKIT_WRITING_MODE = 426;
- BORDER_TOP_WIDTH = 427;
- BOTTOM = 428;
- PLACE_CONTENT = 429;
- _WEBKIT_SHAPE_IMAGE_THRESHOLD = 430;
- _WEBKIT_USER_DRAG = 431;
- _WEBKIT_BORDER_VERTICAL_SPACING = 432;
- _WEBKIT_COLUMN_GAP = 433;
- _WEBKIT_OPACITY = 434;
- BACKGROUND_COLOR = 435;
- COLUMN_GAP = 436;
- SHAPE_OUTSIDE = 437;
- _WEBKIT_PADDING_END = 438;
- _WEBKIT_BORDER_START = 439;
- ANIMATION_DELAY = 440;
- UNICODE_BIDI = 441;
- TEXT_SHADOW = 442;
- _WEBKIT_BOX_DIRECTION = 443;
- IMAGE_RENDERING = 444;
- SRC = 445;
- GAP = 446;
- GRID_GAP = 447;
- POINTER_EVENTS = 448;
- BORDER_IMAGE_WIDTH = 449;
- MIN_BLOCK_SIZE = 450;
- TRANSITION_PROPERTY = 451;
- _WEBKIT_MASK_IMAGE = 452;
- FLOAT = 453;
- MAX_HEIGHT = 454;
- OUTLINE_OFFSET = 455;
- _WEBKIT_BOX_SHADOW = 456;
- OVERFLOW_WRAP = 457;
- BLOCK_SIZE = 458;
- TRANSFORM = 459;
- PLACE_SELF = 460;
- WIDTH = 461;
- STROKE_MITERLIMIT = 462;
- STOP_OPACITY = 463;
- BORDER_TOP_COLOR = 464;
- TRANSLATE = 465;
- OBJECT_FIT = 466;
- _WEBKIT_MASK_BOX_IMAGE_WIDTH = 467;
- _WEBKIT_BACKGROUND_ORIGIN = 468;
- _WEBKIT_ALIGN_ITEMS = 469;
- TRANSITION_DELAY = 470;
- SCROLL_MARGIN_LEFT = 471;
- BORDER_STYLE = 472;
- ANIMATION_ITERATION_COUNT = 473;
- _WEBKIT_MARGIN_AFTER_COLLAPSE = 474;
+ COLOR_INTERPOLATION_FILTERS = 68;
+ FONT_VARIANT = 69;
+ _WEBKIT_ANIMATION_FILL_MODE = 70;
+ BORDER_RIGHT = 71;
+ VISIBILITY = 72;
+ TRANSFORM_BOX = 73;
+ FONT_VARIANT_CAPS = 74;
+ _EPUB_TEXT_EMPHASIS_COLOR = 75;
+ _WEBKIT_BORDER_BEFORE_STYLE = 76;
+ RESIZE = 77;
+ _WEBKIT_RTL_ORDERING = 78;
+ _WEBKIT_BOX_ORDINAL_GROUP = 79;
+ PAINT_ORDER = 80;
+ STROKE_LINECAP = 81;
+ ANIMATION_DIRECTION = 82;
+ _WEBKIT_FONT_FEATURE_SETTINGS = 83;
+ BORDER_TOP_LEFT_RADIUS = 84;
+ _WEBKIT_COLUMN_WIDTH = 85;
+ _WEBKIT_BOX_ALIGN = 86;
+ _WEBKIT_PADDING_AFTER = 87;
+ COLUMN_WIDTH = 88;
+ LIST_STYLE = 89;
+ _WEBKIT_MASK_REPEAT_Y = 90;
+ STROKE = 91;
+ TEXT_DECORATION_LINE = 92;
+ _WEBKIT_BACKGROUND_SIZE = 93;
+ _WEBKIT_MASK_REPEAT_X = 94;
+ PADDING_BOTTOM = 95;
+ FONT_STYLE = 96;
+ _WEBKIT_TRANSITION_DELAY = 97;
+ BACKGROUND_REPEAT = 98;
+ FLEX_BASIS = 99;
+ BORDER_IMAGE_SLICE = 100;
+ _WEBKIT_TRANSFORM_ORIGIN = 101;
+ SCROLL_BOUNDARY_BEHAVIOR_X = 102;
+ SCROLL_BOUNDARY_BEHAVIOR_Y = 103;
+ VECTOR_EFFECT = 104;
+ _WEBKIT_ANIMATION_TIMING_FUNCTION = 105;
+ _WEBKIT_BORDER_AFTER_STYLE = 106;
+ _WEBKIT_PERSPECTIVE_ORIGIN_X = 107;
+ _WEBKIT_PERSPECTIVE_ORIGIN_Y = 108;
+ INLINE_SIZE = 109;
+ OUTLINE = 110;
+ FONT_DISPLAY = 111;
+ _WEBKIT_BORDER_BEFORE = 112;
+ BORDER_IMAGE_SOURCE = 113;
+ TRANSITION_DURATION = 114;
+ SCROLL_PADDING_TOP = 115;
+ ORDER = 116;
+ _WEBKIT_BOX_ORIENT = 117;
+ COUNTER_RESET = 118;
+ COLOR_RENDERING = 119;
+ FLEX_DIRECTION = 120;
+ _WEBKIT_TEXT_STROKE_WIDTH = 121;
+ FONT_VARIANT_NUMERIC = 122;
+ SCROLL_MARGIN_BLOCK_END = 123;
+ MIN_HEIGHT = 124;
+ SCROLL_PADDING_INLINE_START = 125;
+ _WEBKIT_MASK_BOX_IMAGE = 126;
+ LEFT = 127;
+ _WEBKIT_MASK = 128;
+ _WEBKIT_BORDER_AFTER_WIDTH = 129;
+ STROKE_WIDTH = 130;
+ _WEBKIT_BOX_DECORATION_BREAK = 131;
+ _WEBKIT_MASK_POSITION = 132;
+ BACKGROUND_ORIGIN = 133;
+ _WEBKIT_BORDER_START_COLOR = 134;
+ FONT_STRETCH = 135;
+ _WEBKIT_BACKGROUND_CLIP = 136;
+ SCROLL_MARGIN_TOP = 137;
+ _WEBKIT_BORDER_HORIZONTAL_SPACING = 138;
+ BORDER_RADIUS = 139;
+ FLEX = 140;
+ TEXT_INDENT = 141;
+ HYPHENS = 142;
+ COLUMN_RULE_WIDTH = 143;
+ _WEBKIT_MARGIN_AFTER = 144;
+ _EPUB_CAPTION_SIDE = 145;
+ BREAK_AFTER = 146;
+ TEXT_TRANSFORM = 147;
+ TOUCH_ACTION = 148;
+ FONT_SIZE = 149;
+ _WEBKIT_ANIMATION_NAME = 150;
+ SCROLL_PADDING_INLINE = 151;
+ OFFSET_PATH = 152;
+ SCROLL_MARGIN = 153;
+ PADDING_TOP = 154;
+ SCROLL_SNAP_ALIGN = 155;
+ _WEBKIT_TEXT_COMBINE = 156;
+ _WEBKIT_FLEX_SHRINK = 157;
+ RX = 158;
+ RY = 159;
+ CONTENT = 160;
+ PADDING_RIGHT = 161;
+ _WEBKIT_TRANSFORM = 162;
+ MARKER_MID = 163;
+ _WEBKIT_MIN_LOGICAL_WIDTH = 164;
+ CLIP_RULE = 165;
+ FONT_FAMILY = 166;
+ SCROLL_SNAP_TYPE = 167;
+ TEXT_DECORATION_SKIP_INK = 168;
+ TRANSITION = 169;
+ FILTER = 170;
+ BORDER_RIGHT_WIDTH = 171;
+ _WEBKIT_FLEX_DIRECTION = 172;
+ _WEBKIT_MASK_COMPOSITE = 173;
+ MIX_BLEND_MODE = 174;
+ COLOR_INTERPOLATION = 175;
+ BORDER_TOP_STYLE = 176;
+ FILL_OPACITY = 177;
+ MARKER_START = 178;
+ BORDER_BOTTOM_WIDTH = 179;
+ _WEBKIT_TEXT_EMPHASIS = 180;
+ GRID_AREA = 181;
+ SIZE = 182;
+ BACKGROUND_CLIP = 183;
+ _WEBKIT_TEXT_FILL_COLOR = 184;
+ TOP = 185;
+ _WEBKIT_BOX_REFLECT = 186;
+ BORDER_WIDTH = 187;
+ OFFSET_ANCHOR = 188;
+ MAX_INLINE_SIZE = 189;
+ _WEBKIT_COLUMN_RULE_STYLE = 190;
+ _WEBKIT_COLUMN_COUNT = 191;
+ ANIMATION_PLAY_STATE = 192;
+ PADDING = 193;
+ DOMINANT_BASELINE = 194;
+ BACKGROUND_ATTACHMENT = 195;
+ _WEBKIT_BOX_SIZING = 196;
+ _WEBKIT_BOX_FLEX = 197;
+ TEXT_ORIENTATION = 198;
+ BACKGROUND_POSITION = 199;
+ _WEBKIT_BORDER_START_WIDTH = 200;
+ _EPUB_TEXT_EMPHASIS_STYLE = 201;
+ ISOLATION = 202;
+ _EPUB_TEXT_ORIENTATION = 203;
+ _WEBKIT_BORDER_BOTTOM_RIGHT_RADIUS = 204;
+ R = 205;
+ BORDER_LEFT_WIDTH = 206;
+ GRID_COLUMN_END = 207;
+ BACKGROUND_BLEND_MODE = 208;
+ VERTICAL_ALIGN = 209;
+ CLIP = 210;
+ GRID_AUTO_ROWS = 211;
+ OFFSET_ROTATE = 212;
+ MARGIN_LEFT = 213;
+ ANIMATION_NAME = 214;
+ TEXT_DECORATION = 215;
+ BORDER = 216;
+ _WEBKIT_TRANSITION_TIMING_FUNCTION = 217;
+ MARGIN_BOTTOM = 218;
+ UNICODE_RANGE = 219;
+ ANIMATION = 220;
+ _WEBKIT_SHAPE_MARGIN = 221;
+ FONT_WEIGHT = 222;
+ SHAPE_MARGIN = 223;
+ MASK_TYPE = 224;
+ SCROLL_PADDING = 225;
+ MIN_INLINE_SIZE = 226;
+ OBJECT_POSITION = 227;
+ PAGE_BREAK_AFTER = 228;
+ _WEBKIT_MASK_CLIP = 229;
+ WHITE_SPACE = 230;
+ _WEBKIT_BORDER_AFTER_COLOR = 231;
+ _WEBKIT_MAX_LOGICAL_WIDTH = 232;
+ _WEBKIT_BORDER_BEFORE_COLOR = 233;
+ FONT_KERNING = 234;
+ _EPUB_WORD_BREAK = 235;
+ CLEAR = 236;
+ ANIMATION_TIMING_FUNCTION = 237;
+ _WEBKIT_BORDER_RADIUS = 238;
+ SCROLL_PADDING_RIGHT = 239;
+ _WEBKIT_TEXT_DECORATIONS_IN_EFFECT = 240;
+ _WEBKIT_ANIMATION_DIRECTION = 241;
+ JUSTIFY_SELF = 242;
+ TRANSITION_TIMING_FUNCTION = 243;
+ SCROLL_SNAP_STOP = 244;
+ COUNTER_INCREMENT = 245;
+ _WEBKIT_TRANSFORM_STYLE = 246;
+ GRID_AUTO_COLUMNS = 247;
+ _WEBKIT_ALIGN_CONTENT = 248;
+ FONT = 249;
+ FLEX_WRAP = 250;
+ GRID_ROW_START = 251;
+ LIST_STYLE_IMAGE = 252;
+ _WEBKIT_TAP_HIGHLIGHT_COLOR = 253;
+ _WEBKIT_TEXT_EMPHASIS_COLOR = 254;
+ BORDER_LEFT = 255;
+ _WEBKIT_BORDER_END_COLOR = 256;
+ COLUMNS = 257;
+ BOX_SHADOW = 258;
+ _WEBKIT_FLEX_WRAP = 259;
+ ALIGN_SELF = 260;
+ BORDER_BOTTOM = 261;
+ BORDER_SPACING = 262;
+ _WEBKIT_COLUMN_SPAN = 263;
+ GRID_ROW_END = 264;
+ _WEBKIT_BORDER_END = 265;
+ PERSPECTIVE_ORIGIN = 266;
+ PAGE_BREAK_INSIDE = 267;
+ ORPHANS = 268;
+ _WEBKIT_BORDER_START_STYLE = 269;
+ SCROLL_BEHAVIOR = 270;
+ COLUMN_SPAN = 271;
+ _WEBKIT_HYPHENATE_CHARACTER = 272;
+ COLUMN_FILL = 273;
+ TAB_SIZE = 274;
+ CONTAIN = 275;
+ X = 276;
+ GRID_ROW = 277;
+ BORDER_BOTTOM_RIGHT_RADIUS = 278;
+ LINE_HEIGHT = 279;
+ STROKE_LINEJOIN = 280;
+ TEXT_ALIGN_LAST = 281;
+ OFFSET_POSITION = 282;
+ WORD_SPACING = 283;
+ TRANSFORM_STYLE = 284;
+ _WEBKIT_APP_REGION = 285;
+ _WEBKIT_BORDER_END_STYLE = 286;
+ _WEBKIT_TRANSFORM_ORIGIN_Z = 287;
+ _WEBKIT_TRANSFORM_ORIGIN_X = 288;
+ _WEBKIT_TRANSFORM_ORIGIN_Y = 289;
+ BACKGROUND_REPEAT_X = 290;
+ BACKGROUND_REPEAT_Y = 291;
+ BORDER_BOTTOM_COLOR = 292;
+ _WEBKIT_RUBY_POSITION = 293;
+ _WEBKIT_LOGICAL_WIDTH = 294;
+ TEXT_JUSTIFY = 295;
+ SCROLL_MARGIN_INLINE_START = 296;
+ CAPTION_SIDE = 297;
+ MASK_SOURCE_TYPE = 298;
+ _WEBKIT_MASK_BOX_IMAGE_SLICE = 299;
+ _WEBKIT_BORDER_IMAGE = 300;
+ TEXT_SIZE_ADJUST = 301;
+ _WEBKIT_TEXT_SECURITY = 302;
+ _EPUB_WRITING_MODE = 303;
+ GRID_TEMPLATE = 304;
+ _WEBKIT_MASK_BOX_IMAGE_REPEAT = 305;
+ _WEBKIT_MASK_REPEAT = 306;
+ _WEBKIT_JUSTIFY_CONTENT = 307;
+ BASELINE_SHIFT = 308;
+ BORDER_IMAGE = 309;
+ TEXT_DECORATION_COLOR = 310;
+ COLOR = 311;
+ SHAPE_IMAGE_THRESHOLD = 312;
+ SHAPE_RENDERING = 313;
+ CY = 314;
+ CX = 315;
+ _WEBKIT_USER_MODIFY = 316;
+ OFFSET_DISTANCE = 317;
+ _WEBKIT_BORDER_BOTTOM_LEFT_RADIUS = 318;
+ SPEAK = 319;
+ BORDER_BOTTOM_LEFT_RADIUS = 320;
+ _WEBKIT_COLUMN_BREAK_AFTER = 321;
+ _WEBKIT_FONT_SMOOTHING = 322;
+ _WEBKIT_MAX_LOGICAL_HEIGHT = 323;
+ _WEBKIT_LINE_BREAK = 324;
+ FILL_RULE = 325;
+ _WEBKIT_MARGIN_START = 326;
+ MIN_WIDTH = 327;
+ _EPUB_TEXT_COMBINE = 328;
+ BREAK_BEFORE = 329;
+ CARET_COLOR = 330;
+ EMPTY_CELLS = 331;
+ DIRECTION = 332;
+ CLIP_PATH = 333;
+ JUSTIFY_CONTENT = 334;
+ SCROLL_PADDING_BLOCK_END = 335;
+ Z_INDEX = 336;
+ BACKGROUND_POSITION_Y = 337;
+ TEXT_DECORATION_STYLE = 338;
+ GRID_TEMPLATE_AREAS = 339;
+ _WEBKIT_MIN_LOGICAL_HEIGHT = 340;
+ FONT_SIZE_ADJUST = 341;
+ SCROLL_PADDING_BLOCK = 342;
+ OVERFLOW_ANCHOR = 343;
+ CURSOR = 344;
+ SCROLL_MARGIN_BLOCK_START = 345;
+ _WEBKIT_MASK_BOX_IMAGE_SOURCE = 346;
+ MARGIN = 347;
+ _WEBKIT_ANIMATION = 348;
+ LETTER_SPACING = 349;
+ ORIENTATION = 350;
+ WILL_CHANGE = 351;
+ _WEBKIT_HIGHLIGHT = 352;
+ TRANSFORM_ORIGIN = 353;
+ FONT_VARIANT_LIGATURES = 354;
+ _WEBKIT_ANIMATION_DURATION = 355;
+ _WEBKIT_MASK_ORIGIN = 356;
+ _WEBKIT_CLIP_PATH = 357;
+ WORD_BREAK = 358;
+ TABLE_LAYOUT = 359;
+ TEXT_OVERFLOW = 360;
+ _WEBKIT_LOCALE = 361;
+ _WEBKIT_FLEX = 362;
+ GRID_AUTO_FLOW = 363;
+ BORDER_TOP_RIGHT_RADIUS = 364;
+ BORDER_IMAGE_OUTSET = 365;
+ PLACE_ITEMS = 366;
+ BORDER_LEFT_COLOR = 367;
+ FONT_VARIATION_SETTINGS = 368;
+ BORDER_RIGHT_COLOR = 369;
+ MIN_ZOOM = 370;
+ SCROLL_MARGIN_INLINE = 371;
+ _WEBKIT_BORDER_BEFORE_WIDTH = 372;
+ BACKFACE_VISIBILITY = 373;
+ BACKGROUND_IMAGE = 374;
+ _WEBKIT_TRANSITION_PROPERTY = 375;
+ WRITING_MODE = 376;
+ STROKE_OPACITY = 377;
+ BOX_SIZING = 378;
+ MARGIN_TOP = 379;
+ COLUMN_RULE_COLOR = 380;
+ Y = 381;
+ POSITION = 382;
+ SCROLL_MARGIN_BOTTOM = 383;
+ LIST_STYLE_POSITION = 384;
+ _WEBKIT_BOX_PACK = 385;
+ SCROLL_PADDING_INLINE_END = 386;
+ QUOTES = 387;
+ BORDER_TOP = 388;
+ SCROLL_PADDING_LEFT = 389;
+ _WEBKIT_TRANSITION = 390;
+ _WEBKIT_COLUMN_BREAK_BEFORE = 391;
+ LIGHTING_COLOR = 392;
+ BACKGROUND_SIZE = 393;
+ _WEBKIT_PADDING_BEFORE = 394;
+ _WEBKIT_BORDER_TOP_LEFT_RADIUS = 395;
+ FLOOD_OPACITY = 396;
+ LINE_HEIGHT_STEP = 397;
+ _WEBKIT_MASK_SIZE = 398;
+ TEXT_ALIGN = 399;
+ _WEBKIT_FILTER = 400;
+ WORD_WRAP = 401;
+ MAX_ZOOM = 402;
+ GRID = 403;
+ BACKGROUND = 404;
+ HEIGHT = 405;
+ GRID_COLUMN_START = 406;
+ ANIMATION_FILL_MODE = 407;
+ ROTATE = 408;
+ MARKER_END = 409;
+ D = 410;
+ JUSTIFY_ITEMS = 411;
+ ZOOM = 412;
+ SCROLL_PADDING_BLOCK_START = 413;
+ PAGE = 414;
+ RIGHT = 415;
+ USER_SELECT = 416;
+ MARGIN_RIGHT = 417;
+ MARKER = 418;
+ LINE_BREAK = 419;
+ _WEBKIT_MARGIN_END = 420;
+ _WEBKIT_TRANSITION_DURATION = 421;
+ _WEBKIT_WRITING_MODE = 422;
+ BORDER_TOP_WIDTH = 423;
+ BOTTOM = 424;
+ PLACE_CONTENT = 425;
+ _WEBKIT_SHAPE_IMAGE_THRESHOLD = 426;
+ _WEBKIT_USER_DRAG = 427;
+ _WEBKIT_BORDER_VERTICAL_SPACING = 428;
+ _WEBKIT_COLUMN_GAP = 429;
+ _WEBKIT_OPACITY = 430;
+ BACKGROUND_COLOR = 431;
+ COLUMN_GAP = 432;
+ SHAPE_OUTSIDE = 433;
+ _WEBKIT_PADDING_END = 434;
+ _WEBKIT_BORDER_START = 435;
+ ANIMATION_DELAY = 436;
+ UNICODE_BIDI = 437;
+ TEXT_SHADOW = 438;
+ _WEBKIT_BOX_DIRECTION = 439;
+ IMAGE_RENDERING = 440;
+ SRC = 441;
+ GAP = 442;
+ GRID_GAP = 443;
+ POINTER_EVENTS = 444;
+ BORDER_IMAGE_WIDTH = 445;
+ MIN_BLOCK_SIZE = 446;
+ TRANSITION_PROPERTY = 447;
+ _WEBKIT_MASK_IMAGE = 448;
+ FLOAT = 449;
+ MAX_HEIGHT = 450;
+ OUTLINE_OFFSET = 451;
+ _WEBKIT_BOX_SHADOW = 452;
+ OVERFLOW_WRAP = 453;
+ BLOCK_SIZE = 454;
+ TRANSFORM = 455;
+ PLACE_SELF = 456;
+ WIDTH = 457;
+ STROKE_MITERLIMIT = 458;
+ STOP_OPACITY = 459;
+ BORDER_TOP_COLOR = 460;
+ TRANSLATE = 461;
+ OBJECT_FIT = 462;
+ _WEBKIT_MASK_BOX_IMAGE_WIDTH = 463;
+ _WEBKIT_BACKGROUND_ORIGIN = 464;
+ _WEBKIT_ALIGN_ITEMS = 465;
+ TRANSITION_DELAY = 466;
+ SCROLL_MARGIN_LEFT = 467;
+ BORDER_STYLE = 468;
+ ANIMATION_ITERATION_COUNT = 469;
// Should be named OVERFLOW but can't because a macro uses this. Needs two
// underscores for Windows.
- __OVERFLOW = 475;
- USER_ZOOM = 476;
- _WEBKIT_BORDER_TOP_RIGHT_RADIUS = 477;
- GRID_TEMPLATE_COLUMNS = 478;
- _WEBKIT_ALIGN_SELF = 479;
- _WEBKIT_PERSPECTIVE_ORIGIN = 480;
- COLUMN_RULE_STYLE = 481;
- DISPLAY = 482;
- _WEBKIT_COLUMN_RULE_WIDTH = 483;
- BORDER_COLOR = 484;
- _WEBKIT_FLEX_BASIS = 485;
- STROKE_DASHOFFSET = 486;
- _WEBKIT_TEXT_SIZE_ADJUST = 487;
- SCROLL_BOUNDARY_BEHAVIOR = 488;
- _WEBKIT_TEXT_STROKE = 489;
- WIDOWS = 490;
- FILL = 491;
- OVERFLOW_Y = 492;
- OVERFLOW_X = 493;
- OPACITY = 494;
- _WEBKIT_PERSPECTIVE = 495;
- _WEBKIT_TEXT_STROKE_COLOR = 496;
- SCROLL_MARGIN_INLINE_END = 497;
- SCALE = 498;
- _WEBKIT_TEXT_ORIENTATION = 499;
- _WEBKIT_MASK_BOX_IMAGE_OUTSET = 500;
- ALIGN_CONTENT = 501;
- _WEBKIT_BORDER_END_WIDTH = 502;
- BORDER_BOTTOM_STYLE = 503;
- MASK = 504;
- BACKGROUND_POSITION_X = 505;
- _EPUB_TEXT_TRANSFORM = 506;
- STOP_COLOR = 507;
- STROKE_DASHARRAY = 508;
- _WEBKIT_LINE_CLAMP = 509;
- MARGIN_BLOCK_START = 510;
- MARGIN_BLOCK_END = 511;
- MARGIN_INLINE_START = 512;
- MARGIN_INLINE_END = 513;
- PADDING_BLOCK_START = 514;
- PADDING_BLOCK_END = 515;
- PADDING_INLINE_START = 516;
- PADDING_INLINE_END = 517;
- BORDER_BLOCK_START_WIDTH = 518;
- BORDER_BLOCK_START_STYLE = 519;
- BORDER_BLOCK_START_COLOR = 520;
- BORDER_BLOCK_END_WIDTH = 521;
- BORDER_BLOCK_END_STYLE = 522;
- BORDER_BLOCK_END_COLOR = 523;
- BORDER_INLINE_START_WIDTH = 524;
- BORDER_INLINE_START_STYLE = 525;
- BORDER_INLINE_START_COLOR = 526;
- BORDER_INLINE_END_WIDTH = 527;
- BORDER_INLINE_END_STYLE = 528;
- BORDER_INLINE_END_COLOR = 529;
- BORDER_BLOCK_START = 530;
- BORDER_BLOCK_END = 531;
- BORDER_INLINE_START = 532;
- BORDER_INLINE_END = 533;
- MARGIN_BLOCK = 534;
- MARGIN_INLINE = 535;
- PADDING_BLOCK = 536;
- PADDING_INLINE = 537;
- BORDER_BLOCK_WIDTH = 538;
- BORDER_BLOCK_STYLE = 539;
- BORDER_BLOCK_COLOR = 540;
- BORDER_INLINE_WIDTH = 541;
- BORDER_INLINE_STYLE = 542;
- BORDER_INLINE_COLOR = 543;
- BORDER_BLOCK = 544;
- BORDER_INLINE = 545;
- INSET_BLOCK_START = 546;
- INSET_BLOCK_END = 547;
- INSET_BLOCK = 548;
- INSET_INLINE_START = 549;
- INSET_INLINE_END = 550;
- INSET_INLINE = 551;
- INSET = 552;
- OVERFLOW_BLOCK = 553;
- OVERFLOW_INLINE = 554;
- FORCED_COLOR_ADJUST = 555;
- OVERSCROLL_BEHAVIOR_INLINE = 556;
- OVERSCROLL_BEHAVIOR_BLOCK = 557;
- OVERSCROLL_BEHAVIOR_X = 558;
- OVERSCROLL_BEHAVIOR_Y = 559;
- INVALID_PROPERTY = 560;
+ __OVERFLOW = 470;
+ USER_ZOOM = 471;
+ _WEBKIT_BORDER_TOP_RIGHT_RADIUS = 472;
+ GRID_TEMPLATE_COLUMNS = 473;
+ _WEBKIT_ALIGN_SELF = 474;
+ _WEBKIT_PERSPECTIVE_ORIGIN = 475;
+ COLUMN_RULE_STYLE = 476;
+ DISPLAY = 477;
+ _WEBKIT_COLUMN_RULE_WIDTH = 478;
+ BORDER_COLOR = 479;
+ _WEBKIT_FLEX_BASIS = 480;
+ STROKE_DASHOFFSET = 481;
+ _WEBKIT_TEXT_SIZE_ADJUST = 482;
+ SCROLL_BOUNDARY_BEHAVIOR = 483;
+ _WEBKIT_TEXT_STROKE = 484;
+ WIDOWS = 485;
+ FILL = 486;
+ OVERFLOW_Y = 487;
+ OVERFLOW_X = 488;
+ OPACITY = 489;
+ _WEBKIT_PERSPECTIVE = 490;
+ _WEBKIT_TEXT_STROKE_COLOR = 491;
+ SCROLL_MARGIN_INLINE_END = 492;
+ SCALE = 493;
+ _WEBKIT_TEXT_ORIENTATION = 494;
+ _WEBKIT_MASK_BOX_IMAGE_OUTSET = 495;
+ ALIGN_CONTENT = 496;
+ _WEBKIT_BORDER_END_WIDTH = 497;
+ BORDER_BOTTOM_STYLE = 498;
+ MASK = 499;
+ BACKGROUND_POSITION_X = 500;
+ _EPUB_TEXT_TRANSFORM = 501;
+ STOP_COLOR = 502;
+ STROKE_DASHARRAY = 503;
+ _WEBKIT_LINE_CLAMP = 504;
+ MARGIN_BLOCK_START = 505;
+ MARGIN_BLOCK_END = 506;
+ MARGIN_INLINE_START = 507;
+ MARGIN_INLINE_END = 508;
+ PADDING_BLOCK_START = 509;
+ PADDING_BLOCK_END = 510;
+ PADDING_INLINE_START = 511;
+ PADDING_INLINE_END = 512;
+ BORDER_BLOCK_START_WIDTH = 513;
+ BORDER_BLOCK_START_STYLE = 514;
+ BORDER_BLOCK_START_COLOR = 515;
+ BORDER_BLOCK_END_WIDTH = 516;
+ BORDER_BLOCK_END_STYLE = 517;
+ BORDER_BLOCK_END_COLOR = 518;
+ BORDER_INLINE_START_WIDTH = 519;
+ BORDER_INLINE_START_STYLE = 520;
+ BORDER_INLINE_START_COLOR = 521;
+ BORDER_INLINE_END_WIDTH = 522;
+ BORDER_INLINE_END_STYLE = 523;
+ BORDER_INLINE_END_COLOR = 524;
+ BORDER_BLOCK_START = 525;
+ BORDER_BLOCK_END = 526;
+ BORDER_INLINE_START = 527;
+ BORDER_INLINE_END = 528;
+ MARGIN_BLOCK = 529;
+ MARGIN_INLINE = 530;
+ PADDING_BLOCK = 531;
+ PADDING_INLINE = 532;
+ BORDER_BLOCK_WIDTH = 533;
+ BORDER_BLOCK_STYLE = 534;
+ BORDER_BLOCK_COLOR = 535;
+ BORDER_INLINE_WIDTH = 536;
+ BORDER_INLINE_STYLE = 537;
+ BORDER_INLINE_COLOR = 538;
+ BORDER_BLOCK = 539;
+ BORDER_INLINE = 540;
+ INSET_BLOCK_START = 541;
+ INSET_BLOCK_END = 542;
+ INSET_BLOCK = 543;
+ INSET_INLINE_START = 544;
+ INSET_INLINE_END = 545;
+ INSET_INLINE = 546;
+ INSET = 547;
+ OVERFLOW_BLOCK = 548;
+ OVERFLOW_INLINE = 549;
+ FORCED_COLOR_ADJUST = 550;
+ OVERSCROLL_BEHAVIOR_INLINE = 551;
+ OVERSCROLL_BEHAVIOR_BLOCK = 552;
+ OVERSCROLL_BEHAVIOR_X = 553;
+ OVERSCROLL_BEHAVIOR_Y = 554;
+ INVALID_PROPERTY = 555;
}
required NameId name_id = 1;
}
@@ -2383,7 +2378,9 @@ message PropertyAndValue {
SMOOTH = 757;
JUMP_START = 758;
NO_DRAG = 759;
- INVALID_VALUE = 760;
+ JIS_B5 = 760;
+ JIS_B4 = 761;
+ INVALID_VALUE = 762;
};
optional ValueId value_id = 4;
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 2d4ad53c69c..d4c77529916 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(blink::Visitor* visitor) {
+void CSSLazyParsingState::Trace(Visitor* visitor) {
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 19f486bb983..f892be65c7b 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(blink::Visitor*);
+ void Trace(Visitor*);
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 2d9670e3b0a..afbf2a9c6bc 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 22e5721e50b..37d310b53ff 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,6 +11,7 @@
#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"
@@ -216,7 +217,8 @@ bool CSSParser::ParseSupportsCondition(const String& condition,
CSSParserImpl parser(StrictCSSParserContext(secure_context_mode));
return CSSSupportsParser::SupportsCondition(
CSSParserTokenRange(tokens), parser,
- CSSSupportsParser::kForWindowCSS) == CSSSupportsParser::kSupported;
+ CSSSupportsParser::Mode::kForWindowCSS) ==
+ CSSSupportsParser::Result::kSupported;
}
bool CSSParser::ParseColor(Color& color, const String& string, bool strict) {
@@ -258,14 +260,6 @@ bool CSSParser::ParseSystemColor(Color& color,
if (!StyleColor::IsSystemColor(id))
return false;
- if (!RuntimeEnabledFeatures::LinkSystemColorsEnabled() &&
- (id == CSSValueID::kLinktext || id == CSSValueID::kVisitedtext)) {
- return false;
- } else if (!RuntimeEnabledFeatures::NewSystemColorsEnabled() &&
- (id == CSSValueID::kActivetext || id == CSSValueID::kField ||
- id == CSSValueID::kFieldtext)) {
- return false;
- }
color = LayoutTheme::GetTheme().SystemColor(id, color_scheme);
return true;
}
@@ -282,4 +276,16 @@ const CSSValue* CSSParser::ParseFontFaceDescriptor(
return value;
}
+CSSPrimitiveValue* CSSParser::ParseLengthPercentage(
+ const String& string,
+ const CSSParserContext* context) {
+ if (string.IsEmpty() || !context)
+ return nullptr;
+ CSSTokenizer tokenizer(string);
+ const auto tokens = tokenizer.TokenizeToEOF();
+ CSSParserTokenRange range(tokens);
+ return css_property_parser_helpers::ConsumeLengthOrPercent(range, *context,
+ kValueRangeAll);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_parser.h b/chromium/third_party/blink/renderer/core/css/parser/css_parser.h
index 6de5b9be336..df51b7f0142 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_parser.h
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_parser.h
@@ -23,6 +23,7 @@ class StyleRuleBase;
class StyleRuleKeyframe;
class StyleSheetContents;
class CSSValue;
+class CSSPrimitiveValue;
enum class ParseSheetResult;
enum class SecureContextMode;
@@ -112,6 +113,9 @@ class CORE_EXPORT CSSParser {
const String&,
CSSParserObserver&);
+ static CSSPrimitiveValue* ParseLengthPercentage(const String&,
+ const CSSParserContext*);
+
private:
static MutableCSSPropertyValueSet::SetResult ParseValue(
MutableCSSPropertyValueSet*,
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 8f0f74637ad..3976f68094f 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
@@ -13,7 +13,9 @@
#include "third_party/blink/renderer/core/feature_policy/layout_animations_policy.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.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/settings.h"
+#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html/imports/html_imports_controller.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/page/page.h"
@@ -85,7 +87,7 @@ CSSParserContext::CSSParserContext(CSSParserMode mode,
false,
false,
secure_context_mode,
- kDoNotCheckContentSecurityPolicy,
+ network::mojom::CSPDisposition::DO_NOT_CHECK,
use_counter_document,
ResourceFetchRestriction::kNone) {}
@@ -118,15 +120,16 @@ CSSParserContext::CSSParserContext(
profile,
Referrer(base_url_override.StrippedForUseAsReferrer(),
referrer_policy_override),
- document.IsHTMLDocument(),
+ IsA<HTMLDocument>(document),
document.GetSettings()
? document.GetSettings()
->GetUseLegacyBackgroundSizeShorthandBehavior()
: false,
document.GetSecureContextMode(),
- ContentSecurityPolicy::ShouldBypassMainWorld(&document)
- ? kDoNotCheckContentSecurityPolicy
- : kCheckContentSecurityPolicy,
+ ContentSecurityPolicy::ShouldBypassMainWorld(
+ document.GetExecutionContext())
+ ? network::mojom::CSPDisposition::DO_NOT_CHECK
+ : network::mojom::CSPDisposition::CHECK,
&document,
resource_fetch_restriction) {}
@@ -143,9 +146,11 @@ CSSParserContext::CSSParserContext(const ExecutionContext& context)
false,
context.GetSecureContextMode(),
ContentSecurityPolicy::ShouldBypassMainWorld(&context)
- ? kDoNotCheckContentSecurityPolicy
- : kCheckContentSecurityPolicy,
- DynamicTo<Document>(context),
+ ? network::mojom::CSPDisposition::DO_NOT_CHECK
+ : network::mojom::CSPDisposition::CHECK,
+ IsA<LocalDOMWindow>(&context)
+ ? To<LocalDOMWindow>(context).document()
+ : nullptr,
ResourceFetchRestriction::kNone) {}
CSSParserContext::CSSParserContext(
@@ -159,7 +164,7 @@ CSSParserContext::CSSParserContext(
bool is_html_document,
bool use_legacy_background_size_shorthand_behavior,
SecureContextMode secure_context_mode,
- ContentSecurityPolicyDisposition policy_disposition,
+ network::mojom::CSPDisposition policy_disposition,
const Document* use_counter_document,
enum ResourceFetchRestriction resource_fetch_restriction)
: base_url_(base_url),
@@ -188,6 +193,8 @@ bool CSSParserContext::operator==(const CSSParserContext& other) const {
resource_fetch_restriction_ == other.resource_fetch_restriction_;
}
+// TODO(xiaochengh): This function never returns null. Change it to return a
+// const reference to avoid confusion.
const CSSParserContext* StrictCSSParserContext(
SecureContextMode secure_context_mode) {
DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<Persistent<CSSParserContext>>,
@@ -244,6 +251,16 @@ bool CSSParserContext::IsDocumentHandleEqual(const Document* other) const {
return document_.Get() == other;
}
+const Document* CSSParserContext::GetDocument() const {
+ return document_.Get();
+}
+
+// Fuzzers may execution CSS parsing code without a Document being available,
+// thus this method can return null.
+const ExecutionContext* CSSParserContext::GetExecutionContext() const {
+ return (document_.Get()) ? document_.Get()->GetExecutionContext() : nullptr;
+}
+
void CSSParserContext::ReportLayoutAnimationsViolationIfNeeded(
const StyleRuleKeyframe& rule) const {
if (!document_)
@@ -252,7 +269,8 @@ void CSSParserContext::ReportLayoutAnimationsViolationIfNeeded(
const CSSProperty& property = rule.Properties().PropertyAt(i).Property();
if (!LayoutAnimationsPolicy::AffectedCSSProperties().Contains(&property))
continue;
- LayoutAnimationsPolicy::ReportViolation(property, *document_);
+ LayoutAnimationsPolicy::ReportViolation(property,
+ *document_->GetExecutionContext());
}
}
@@ -267,7 +285,7 @@ bool CSSParserContext::IsForMarkupSanitization() const {
return document_ && document_->IsForMarkupSanitization();
}
-void CSSParserContext::Trace(blink::Visitor* visitor) {
+void CSSParserContext::Trace(Visitor* visitor) {
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 28a2da4cfc2..b9d230e1ed3 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
@@ -37,8 +37,8 @@ class CORE_EXPORT CSSParserContext final
// FIXME: This constructor shouldn't exist if we properly piped the UseCounter
// through the CSS subsystem. Currently the UseCounter life time is too crazy
// and we need a way to override it.
- CSSParserContext(const CSSParserContext* other,
- const Document* use_counter_document = nullptr);
+ explicit CSSParserContext(const CSSParserContext* other,
+ const Document* use_counter_document = nullptr);
CSSParserContext(const CSSParserContext* other,
const KURL& base_url_override,
@@ -73,7 +73,7 @@ class CORE_EXPORT CSSParserContext final
bool is_html_document,
bool use_legacy_background_size_shorthand_behavior,
SecureContextMode,
- ContentSecurityPolicyDisposition,
+ network::mojom::CSPDisposition,
const Document* use_counter_document,
ResourceFetchRestriction resource_fetch_restriction);
@@ -119,8 +119,10 @@ class CORE_EXPORT CSSParserContext final
void CountDeprecation(WebFeature) const;
bool IsUseCounterRecordingEnabled() const { return document_; }
bool IsDocumentHandleEqual(const Document* other) const;
+ const Document* GetDocument() const;
+ const ExecutionContext* GetExecutionContext() const;
- ContentSecurityPolicyDisposition ShouldCheckContentSecurityPolicy() const {
+ network::mojom::CSPDisposition ShouldCheckContentSecurityPolicy() const {
return should_check_content_security_policy_;
}
@@ -135,12 +137,30 @@ class CORE_EXPORT CSSParserContext final
bool IsForMarkupSanitization() const;
- void Trace(blink::Visitor*);
+ // Overrides |mode_| of a CSSParserContext within the scope, allowing us to
+ // switching parsing mode while parsing different parts of a style sheet.
+ // TODO(xiaochengh): This isn't the right approach, as it breaks the
+ // immutability of CSSParserContext. We should introduce some local context.
+ class ParserModeOverridingScope {
+ STACK_ALLOCATED();
+
+ public:
+ ParserModeOverridingScope(const CSSParserContext& context,
+ CSSParserMode mode)
+ : mode_reset_(const_cast<CSSParserMode*>(&context.mode_), mode) {}
+
+ private:
+ base::AutoReset<CSSParserMode> mode_reset_;
+ };
+
+ void Trace(Visitor*);
private:
+ friend class ParserModeOverridingScope;
+
KURL base_url_;
- ContentSecurityPolicyDisposition should_check_content_security_policy_;
+ network::mojom::CSPDisposition should_check_content_security_policy_;
// If true, allows reading and modifying of the CSS rules.
// https://drafts.csswg.org/cssom/#concept-css-style-sheet-origin-clean-flag
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 8a2621d5f9a..faf3e61ee94 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
@@ -643,6 +643,10 @@ bool CSSParserFastPaths::IsValidKeywordPropertyAndValue(
case CSSPropertyID::kMaskType:
return value_id == CSSValueID::kLuminance ||
value_id == CSSValueID::kAlpha;
+ case CSSPropertyID::kMathStyle:
+ DCHECK(RuntimeEnabledFeatures::CSSMathStyleEnabled());
+ return value_id == CSSValueID::kInline ||
+ value_id == CSSValueID::kDisplay;
case CSSPropertyID::kObjectFit:
return value_id == CSSValueID::kFill ||
value_id == CSSValueID::kContain ||
@@ -792,7 +796,7 @@ bool CSSParserFastPaths::IsValidKeywordPropertyAndValue(
case CSSPropertyID::kWebkitAppearance:
return (value_id >= CSSValueID::kCheckbox &&
value_id <= CSSValueID::kTextarea) ||
- value_id == CSSValueID::kNone;
+ value_id == CSSValueID::kNone || value_id == CSSValueID::kAuto;
case CSSPropertyID::kBackfaceVisibility:
return value_id == CSSValueID::kVisible ||
value_id == CSSValueID::kHidden;
@@ -905,13 +909,6 @@ bool CSSParserFastPaths::IsValidKeywordPropertyAndValue(
value_id == CSSValueID::kNormal ||
value_id == CSSValueID::kStrict ||
value_id == CSSValueID::kAfterWhiteSpace;
- case CSSPropertyID::kWebkitMarginAfterCollapse:
- case CSSPropertyID::kWebkitMarginBeforeCollapse:
- case CSSPropertyID::kWebkitMarginBottomCollapse:
- case CSSPropertyID::kWebkitMarginTopCollapse:
- return value_id == CSSValueID::kCollapse ||
- value_id == CSSValueID::kSeparate ||
- value_id == CSSValueID::kDiscard;
case CSSPropertyID::kWebkitPrintColorAdjust:
return value_id == CSSValueID::kExact || value_id == CSSValueID::kEconomy;
case CSSPropertyID::kWebkitRtlOrdering:
@@ -970,6 +967,8 @@ bool CSSParserFastPaths::IsValidKeywordPropertyAndValue(
case CSSPropertyID::kOverscrollBehaviorY:
return value_id == CSSValueID::kAuto ||
value_id == CSSValueID::kContain || value_id == CSSValueID::kNone;
+ case CSSPropertyID::kOriginTrialTestProperty:
+ return value_id == CSSValueID::kNormal || value_id == CSSValueID::kNone;
default:
NOTREACHED();
return false;
@@ -1009,6 +1008,7 @@ bool CSSParserFastPaths::IsKeywordPropertyID(CSSPropertyID property_id) {
case CSSPropertyID::kListStylePosition:
case CSSPropertyID::kListStyleType:
case CSSPropertyID::kMaskType:
+ case CSSPropertyID::kMathStyle:
case CSSPropertyID::kObjectFit:
case CSSPropertyID::kOutlineStyle:
case CSSPropertyID::kOverflowAnchor:
@@ -1069,10 +1069,6 @@ bool CSSParserFastPaths::IsKeywordPropertyID(CSSPropertyID property_id) {
case CSSPropertyID::kWebkitFontSmoothing:
case CSSPropertyID::kLineBreak:
case CSSPropertyID::kWebkitLineBreak:
- case CSSPropertyID::kWebkitMarginAfterCollapse:
- case CSSPropertyID::kWebkitMarginBeforeCollapse:
- case CSSPropertyID::kWebkitMarginBottomCollapse:
- case CSSPropertyID::kWebkitMarginTopCollapse:
case CSSPropertyID::kWebkitPrintColorAdjust:
case CSSPropertyID::kWebkitRtlOrdering:
case CSSPropertyID::kWebkitRubyPosition:
@@ -1088,6 +1084,7 @@ bool CSSParserFastPaths::IsKeywordPropertyID(CSSPropertyID property_id) {
case CSSPropertyID::kWordBreak:
case CSSPropertyID::kWritingMode:
case CSSPropertyID::kScrollSnapStop:
+ case CSSPropertyID::kOriginTrialTestProperty:
return true;
default:
return false;
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 69c969f6211..bf766c0312a 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
@@ -65,7 +65,10 @@ AtomicString ConsumeStringOrURI(CSSParserTokenStream& stream) {
CSSParserImpl::CSSParserImpl(const CSSParserContext* context,
StyleSheetContents* style_sheet)
- : context_(context), style_sheet_(style_sheet), observer_(nullptr) {}
+ : context_(context),
+ style_sheet_(style_sheet),
+ observer_(nullptr),
+ lazy_state_(nullptr) {}
MutableCSSPropertyValueSet::SetResult CSSParserImpl::ParseValue(
MutableCSSPropertyValueSet* declaration,
@@ -635,7 +638,9 @@ StyleRuleImport* CSSParserImpl::ConsumeImportRule(
}
return MakeGarbageCollected<StyleRuleImport>(
- uri, MediaQueryParser::ParseMediaQuerySet(prelude),
+ uri,
+ MediaQueryParser::ParseMediaQuerySet(prelude,
+ context_->GetExecutionContext()),
context_->IsOriginClean() ? OriginClean::kTrue : OriginClean::kFalse);
}
@@ -668,7 +673,8 @@ StyleRuleMedia* CSSParserImpl::ConsumeMediaRule(
if (style_sheet_)
style_sheet_->SetHasMediaQueries();
- const auto media = MediaQueryParser::ParseMediaQuerySet(prelude);
+ const auto media = MediaQueryParser::ParseMediaQuerySet(
+ prelude, context_->GetExecutionContext());
ConsumeRuleList(block, kRegularRuleList,
[&rules](StyleRuleBase* rule) { rules.push_back(rule); });
@@ -683,10 +689,9 @@ StyleRuleSupports* CSSParserImpl::ConsumeSupportsRule(
const CSSParserTokenRange prelude,
const RangeOffset& prelude_offset,
CSSParserTokenStream& block) {
- CSSSupportsParser::SupportsResult supported =
- CSSSupportsParser::SupportsCondition(prelude, *this,
- CSSSupportsParser::kForAtRule);
- if (supported == CSSSupportsParser::kInvalid)
+ CSSSupportsParser::Result supported = CSSSupportsParser::SupportsCondition(
+ prelude, *this, CSSSupportsParser::Mode::kForAtRule);
+ if (supported == CSSSupportsParser::Result::kParseFailure)
return nullptr; // Parse error, invalid @supports condition
if (observer_) {
@@ -704,8 +709,9 @@ StyleRuleSupports* CSSParserImpl::ConsumeSupportsRule(
if (observer_)
observer_->EndRuleBody(block.Offset());
- return MakeGarbageCollected<StyleRuleSupports>(prelude_serialized, supported,
- rules);
+ return MakeGarbageCollected<StyleRuleSupports>(
+ prelude_serialized, supported == CSSSupportsParser::Result::kSupported,
+ rules);
}
StyleRuleViewport* CSSParserImpl::ConsumeViewportRule(
@@ -836,7 +842,7 @@ StyleRuleProperty* CSSParserImpl::ConsumePropertyRule(
}
ConsumeDeclarationList(block, StyleRule::kProperty);
- return StyleRuleProperty::Create(
+ return MakeGarbageCollected<StyleRuleProperty>(
name, CreateCSSPropertyValueSet(parsed_properties_, context_->Mode()));
}
@@ -1003,7 +1009,8 @@ void CSSParserImpl::ConsumeDeclaration(CSSParserTokenRange range,
AtRuleDescriptorParser::ParseAtRule(atrule_id, range, *context_,
parsed_properties_);
} else {
- unresolved_property = lhs.ParseAsUnresolvedCSSPropertyID(context_->Mode());
+ unresolved_property = lhs.ParseAsUnresolvedCSSPropertyID(
+ context_->GetExecutionContext(), context_->Mode());
}
// @rules other than FontFace still handled with legacy code.
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 6f1fa33bb69..055faedfc23 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
@@ -8,6 +8,7 @@
#include <memory>
#include "base/macros.h"
+#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/css/css_property_source_data.h"
#include "third_party/blink/renderer/core/css/css_property_value.h"
@@ -44,7 +45,7 @@ enum class ParseSheetResult {
kHasUnallowedImportRule,
};
-class CSSParserImpl {
+class CORE_EXPORT CSSParserImpl {
STACK_ALLOCATED();
public:
@@ -115,6 +116,7 @@ class CSSParserImpl {
static std::unique_ptr<Vector<double>> ParseKeyframeKeyList(const String&);
bool SupportsDeclaration(CSSParserTokenRange&);
+ const CSSParserContext* GetContext() const { return context_; }
static void ParseDeclarationListForInspector(const String&,
const CSSParserContext*,
@@ -198,13 +200,13 @@ class CSSParserImpl {
// FIXME: Investigate using a smaller inline buffer
HeapVector<CSSPropertyValue, 256> parsed_properties_;
- Member<const CSSParserContext> context_;
- Member<StyleSheetContents> style_sheet_;
+ const CSSParserContext* context_;
+ StyleSheetContents* style_sheet_;
// For the inspector
CSSParserObserver* observer_;
- Member<CSSLazyParsingState> lazy_state_;
+ CSSLazyParsingState* lazy_state_;
DISALLOW_COPY_AND_ASSIGN(CSSParserImpl);
};
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_parser_selector.h b/chromium/third_party/blink/renderer/core/css/parser/css_parser_selector.h
index 341013ccb9e..9ea94a4761a 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_parser_selector.h
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_parser_selector.h
@@ -54,6 +54,9 @@ class CORE_EXPORT CSSParserSelector {
selector_->SetAttribute(value, match_type);
}
void SetArgument(const AtomicString& value) { selector_->SetArgument(value); }
+ void SetPartNames(std::unique_ptr<Vector<AtomicString>> part_names) {
+ selector_->SetPartNames(std::move(part_names));
+ }
void SetNth(int a, int b) { selector_->SetNth(a, b); }
void SetMatch(CSSSelector::MatchType value) { selector_->SetMatch(value); }
void SetRelation(CSSSelector::RelationType value) {
@@ -80,6 +83,7 @@ class CORE_EXPORT CSSParserSelector {
void AdoptSelectorVector(
Vector<std::unique_ptr<CSSParserSelector>>& selector_vector);
void SetSelectorList(std::unique_ptr<CSSSelectorList>);
+ void SetAtomics(std::unique_ptr<CSSSelectorList>);
bool IsHostPseudoSelector() const;
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_parser_token.cc b/chromium/third_party/blink/renderer/core/css/parser/css_parser_token.cc
index 39a17b852c2..6f85bf2fca0 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_parser_token.cc
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_parser_token.cc
@@ -87,9 +87,10 @@ double CSSParserToken::NumericValue() const {
}
CSSPropertyID CSSParserToken::ParseAsUnresolvedCSSPropertyID(
+ const ExecutionContext* execution_context,
CSSParserMode mode) const {
DCHECK_EQ(type_, static_cast<unsigned>(kIdentToken));
- return UnresolvedCSSPropertyID(Value(), mode);
+ return UnresolvedCSSPropertyID(execution_context, Value(), mode);
}
AtRuleDescriptorID CSSParserToken::ParseAsAtRuleDescriptorID() const {
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_parser_token.h b/chromium/third_party/blink/renderer/core/css/parser/css_parser_token.h
index a626f9030af..c094ae05276 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_parser_token.h
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_parser_token.h
@@ -14,6 +14,7 @@
namespace blink {
+class ExecutionContext;
enum class CSSValueID;
enum CSSParserTokenType {
@@ -149,6 +150,7 @@ class CORE_EXPORT CSSParserToken {
bool HasStringBacking() const;
CSSPropertyID ParseAsUnresolvedCSSPropertyID(
+ const ExecutionContext* execution_context,
CSSParserMode mode = kHTMLStandardMode) const;
AtRuleDescriptorID ParseAsAtRuleDescriptorID() const;
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 1f6e911c2f1..1365fb4c828 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
@@ -157,7 +157,8 @@ bool CSSPropertyParser::ParseValueStart(CSSPropertyID unresolved_property,
if (is_shorthand) {
const cssvalue::CSSPendingSubstitutionValue& pending_value =
- *cssvalue::CSSPendingSubstitutionValue::Create(property_id, variable);
+ *MakeGarbageCollected<cssvalue::CSSPendingSubstitutionValue>(
+ property_id, variable);
css_property_parser_helpers::AddExpandedPropertyForValue(
property_id, pending_value, important, *parsed_properties_);
} else {
@@ -170,16 +171,19 @@ bool CSSPropertyParser::ParseValueStart(CSSPropertyID unresolved_property,
return false;
}
-static inline bool IsExposedInMode(const CSSProperty& property,
+static inline bool IsExposedInMode(const ExecutionContext* execution_context,
+ const CSSProperty& property,
CSSParserMode mode) {
- return mode == kUASheetMode ? property.IsUAExposed()
- : property.IsWebExposed();
+ return mode == kUASheetMode ? property.IsUAExposed(execution_context)
+ : property.IsWebExposed(execution_context);
}
template <typename CharacterType>
-static CSSPropertyID UnresolvedCSSPropertyID(const CharacterType* property_name,
- unsigned length,
- CSSParserMode mode) {
+static CSSPropertyID UnresolvedCSSPropertyID(
+ const ExecutionContext* execution_context,
+ const CharacterType* property_name,
+ unsigned length,
+ CSSParserMode mode) {
if (length == 0)
return CSSPropertyID::kInvalid;
if (length >= 2 && property_name[0] == '-' && property_name[1] == '-')
@@ -204,23 +208,30 @@ static CSSPropertyID UnresolvedCSSPropertyID(const CharacterType* property_name,
CSSPropertyID property_id = static_cast<CSSPropertyID>(hash_table_entry->id);
const CSSProperty& property =
CSSProperty::Get(resolveCSSPropertyID(property_id));
- bool exposed = IsExposedInMode(property, mode);
+ bool exposed = IsExposedInMode(execution_context, property, mode);
return exposed ? property_id : CSSPropertyID::kInvalid;
}
-CSSPropertyID unresolvedCSSPropertyID(const String& string) {
+CSSPropertyID unresolvedCSSPropertyID(const ExecutionContext* execution_context,
+ const String& string) {
unsigned length = string.length();
CSSParserMode mode = kHTMLStandardMode;
return string.Is8Bit()
- ? UnresolvedCSSPropertyID(string.Characters8(), length, mode)
- : UnresolvedCSSPropertyID(string.Characters16(), length, mode);
+ ? UnresolvedCSSPropertyID(execution_context, string.Characters8(),
+ length, mode)
+ : UnresolvedCSSPropertyID(execution_context, string.Characters16(),
+ length, mode);
}
-CSSPropertyID UnresolvedCSSPropertyID(StringView string, CSSParserMode mode) {
+CSSPropertyID UnresolvedCSSPropertyID(const ExecutionContext* execution_context,
+ StringView string,
+ CSSParserMode mode) {
unsigned length = string.length();
return string.Is8Bit()
- ? UnresolvedCSSPropertyID(string.Characters8(), length, mode)
- : UnresolvedCSSPropertyID(string.Characters16(), length, mode);
+ ? UnresolvedCSSPropertyID(execution_context, string.Characters8(),
+ length, mode)
+ : UnresolvedCSSPropertyID(execution_context, string.Characters16(),
+ length, mode);
}
template <typename CharacterType>
@@ -278,7 +289,7 @@ bool CSSPropertyParser::ConsumeCSSWideKeyword(CSSPropertyID unresolved_property,
static CSSValue* ConsumeSingleViewportDescriptor(
CSSParserTokenRange& range,
CSSPropertyID prop_id,
- CSSParserMode css_parser_mode) {
+ const CSSParserContext& context) {
CSSValueID id = range.Peek().Id();
switch (prop_id) {
case CSSPropertyID::kMinWidth:
@@ -288,18 +299,18 @@ static CSSValue* ConsumeSingleViewportDescriptor(
if (id == CSSValueID::kAuto || id == CSSValueID::kInternalExtendToZoom)
return ConsumeIdent(range);
return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, css_parser_mode, kValueRangeNonNegative);
+ 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(
- range, kValueRangeNonNegative);
+ range, context, kValueRangeNonNegative);
if (parsed_value)
return parsed_value;
return css_property_parser_helpers::ConsumePercent(
- range, kValueRangeNonNegative);
+ range, context, kValueRangeNonNegative);
}
case CSSPropertyID::kUserZoom:
return ConsumeIdent<CSSValueID::kZoom, CSSValueID::kFixed>(range);
@@ -326,13 +337,13 @@ bool CSSPropertyParser::ParseViewportDescriptor(CSSPropertyID prop_id,
switch (prop_id) {
case CSSPropertyID::kWidth: {
CSSValue* min_width = ConsumeSingleViewportDescriptor(
- range_, CSSPropertyID::kMinWidth, context_->Mode());
+ range_, CSSPropertyID::kMinWidth, *context_);
if (!min_width)
return false;
CSSValue* max_width = min_width;
if (!range_.AtEnd()) {
max_width = ConsumeSingleViewportDescriptor(
- range_, CSSPropertyID::kMaxWidth, context_->Mode());
+ range_, CSSPropertyID::kMaxWidth, *context_);
}
if (!max_width || !range_.AtEnd())
return false;
@@ -346,13 +357,13 @@ bool CSSPropertyParser::ParseViewportDescriptor(CSSPropertyID prop_id,
}
case CSSPropertyID::kHeight: {
CSSValue* min_height = ConsumeSingleViewportDescriptor(
- range_, CSSPropertyID::kMinHeight, context_->Mode());
+ range_, CSSPropertyID::kMinHeight, *context_);
if (!min_height)
return false;
CSSValue* max_height = min_height;
if (!range_.AtEnd()) {
max_height = ConsumeSingleViewportDescriptor(
- range_, CSSPropertyID::kMaxHeight, context_->Mode());
+ range_, CSSPropertyID::kMaxHeight, *context_);
}
if (!max_height || !range_.AtEnd())
return false;
@@ -375,7 +386,7 @@ bool CSSPropertyParser::ParseViewportDescriptor(CSSPropertyID prop_id,
case CSSPropertyID::kUserZoom:
case CSSPropertyID::kOrientation: {
CSSValue* parsed_value =
- ConsumeSingleViewportDescriptor(range_, prop_id, context_->Mode());
+ ConsumeSingleViewportDescriptor(range_, prop_id, *context_);
if (!parsed_value || !range_.AtEnd())
return false;
AddProperty(prop_id, CSSPropertyID::kInvalid, *parsed_value, important,
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_property_parser.h b/chromium/third_party/blink/renderer/core/css/parser/css_property_parser.h
index d4989ede007..2090b9ec5a8 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_property_parser.h
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_property_parser.h
@@ -36,6 +36,7 @@ namespace blink {
class CSSPropertyValue;
class CSSValue;
+class ExecutionContext;
// Inputs: PropertyID, isImportant bool, CSSParserTokenRange.
// Outputs: Vector of CSSProperties
@@ -71,13 +72,14 @@ class CORE_EXPORT CSSPropertyParser {
private:
// Inputs:
CSSParserTokenRange range_;
- Member<const CSSParserContext> context_;
+ const CSSParserContext* context_;
// Outputs:
HeapVector<CSSPropertyValue, 256>* parsed_properties_;
DISALLOW_COPY_AND_ASSIGN(CSSPropertyParser);
};
-CSSPropertyID UnresolvedCSSPropertyID(StringView,
+CSSPropertyID UnresolvedCSSPropertyID(const ExecutionContext*,
+ StringView,
CSSParserMode mode = kHTMLStandardMode);
CSSValueID CssValueKeywordID(StringView);
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
index c091695c955..c2034ea64b7 100644
--- 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
@@ -31,6 +31,7 @@
#include "third_party/blink/renderer/core/css/style_color.h"
#include "third_party/blink/renderer/core/frame/web_feature.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"
@@ -44,12 +45,12 @@ namespace {
bool AddCSSPaintArgument(
const Vector<CSSParserToken>& tokens,
Vector<scoped_refptr<CSSVariableData>>* const variable_data,
- const CSSParserContext* context) {
+ 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());
+ 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;
@@ -97,7 +98,7 @@ CSSFunctionValue* ConsumeFilterFunction(CSSParserTokenRange& range,
if (filter_type == CSSValueID::kDropShadow) {
parsed_value = css_parsing_utils::ParseSingleShadow(
- args, context.Mode(), css_parsing_utils::AllowInsetAndSpread::kForbid);
+ args, context, css_parsing_utils::AllowInsetAndSpread::kForbid);
} else {
if (args.AtEnd()) {
context.Count(WebFeature::kCSSFilterFunctionNoArguments);
@@ -105,25 +106,27 @@ CSSFunctionValue* ConsumeFilterFunction(CSSParserTokenRange& range,
}
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, kValueRangeAll);
+ parsed_value = css_property_parser_helpers::ConsumePercent(
+ args, context, kValueRangeAll);
if (!parsed_value) {
parsed_value = css_property_parser_helpers::ConsumeNumber(
- args, kValueRangeNonNegative);
+ args, context, kValueRangeNonNegative);
}
} else if (filter_type == CSSValueID::kHueRotate) {
parsed_value = css_property_parser_helpers::ConsumeAngle(
- args, &context, WebFeature::kUnitlessZeroAngleFilter);
+ args, context, WebFeature::kUnitlessZeroAngleFilter);
} else if (filter_type == CSSValueID::kBlur) {
+ CSSParserContext::ParserModeOverridingScope scope(context,
+ kHTMLStandardMode);
parsed_value = css_property_parser_helpers::ConsumeLength(
- args, kHTMLStandardMode, kValueRangeNonNegative);
+ args, context, kValueRangeNonNegative);
} else {
// FIXME (crbug.com/397061): Support calc expressions like calc(10% + 0.5)
parsed_value = css_property_parser_helpers::ConsumePercent(
- args, kValueRangeNonNegative);
+ args, context, kValueRangeNonNegative);
if (!parsed_value) {
parsed_value = css_property_parser_helpers::ConsumeNumber(
- args, kValueRangeNonNegative);
+ args, context, kValueRangeNonNegative);
}
if (parsed_value && filter_type != CSSValueID::kSaturate &&
filter_type != CSSValueID::kContrast) {
@@ -189,47 +192,52 @@ class MathFunctionParser {
STACK_ALLOCATED();
public:
- explicit MathFunctionParser(CSSParserTokenRange& range,
- ValueRange value_range = kValueRangeAll)
+ MathFunctionParser(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ ValueRange value_range)
: source_range_(range), range_(range) {
const CSSParserToken& token = range.Peek();
- if (token.FunctionId() == CSSValueID::kCalc ||
- token.FunctionId() == CSSValueID::kWebkitCalc) {
- calc_value_ = CSSMathFunctionValue::Create(
- CSSMathExpressionNode::ParseCalc(ConsumeFunction(range_)),
- value_range);
- return;
- }
-
- if (RuntimeEnabledFeatures::CSSComparisonFunctionsEnabled()) {
- switch (token.FunctionId()) {
- case CSSValueID::kMin:
- calc_value_ = CSSMathFunctionValue::Create(
- CSSMathExpressionNode::ParseMin(ConsumeFunction(range_)),
- value_range);
- return;
- case CSSValueID::kMax:
- calc_value_ = CSSMathFunctionValue::Create(
- CSSMathExpressionNode::ParseMax(ConsumeFunction(range_)),
- value_range);
- return;
- case CSSValueID::kClamp:
- calc_value_ = CSSMathFunctionValue::Create(
- CSSMathExpressionNode::ParseClamp(ConsumeFunction(range_)),
- value_range);
- return;
- default:
- break;
- }
+ 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_;
- return calc_value_.Release();
+ CSSMathFunctionValue* result = calc_value_;
+ calc_value_ = nullptr;
+ return result;
}
CSSPrimitiveValue* ConsumeRoundedInt() {
@@ -264,10 +272,11 @@ class MathFunctionParser {
private:
CSSParserTokenRange& source_range_;
CSSParserTokenRange range_;
- Member<CSSMathFunctionValue> calc_value_;
+ CSSMathFunctionValue* calc_value_ = nullptr;
};
CSSPrimitiveValue* ConsumeInteger(CSSParserTokenRange& range,
+ const CSSParserContext& context,
double minimum_value) {
const CSSParserToken& token = range.Peek();
if (token.GetType() == kNumberToken) {
@@ -278,7 +287,7 @@ CSSPrimitiveValue* ConsumeInteger(CSSParserTokenRange& range,
range.ConsumeIncludingWhitespace().NumericValue(),
CSSPrimitiveValue::UnitType::kInteger);
}
- MathFunctionParser math_parser(range);
+ MathFunctionParser math_parser(range, context);
if (const CSSMathFunctionValue* math_value = math_parser.Value()) {
if (!RuntimeEnabledFeatures::CSSCalcAsIntEnabled() && !math_value->IsInt())
return nullptr;
@@ -305,13 +314,14 @@ CSSPrimitiveValue* ConsumeInteger(CSSParserTokenRange& range,
// 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) {
+CSSPrimitiveValue* ConsumeIntegerOrNumberCalc(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
CSSParserTokenRange int_range(range);
- if (CSSPrimitiveValue* value = ConsumeInteger(int_range)) {
+ if (CSSPrimitiveValue* value = ConsumeInteger(int_range, context)) {
range = int_range;
return value;
}
- MathFunctionParser math_parser(range);
+ MathFunctionParser math_parser(range, context);
if (const CSSMathFunctionValue* calculation = math_parser.Value()) {
if (calculation->Category() != kCalcNumber)
return nullptr;
@@ -320,21 +330,25 @@ CSSPrimitiveValue* ConsumeIntegerOrNumberCalc(CSSParserTokenRange& range) {
return nullptr;
}
-CSSPrimitiveValue* ConsumePositiveInteger(CSSParserTokenRange& range) {
- return ConsumeInteger(range, 1);
+CSSPrimitiveValue* ConsumePositiveInteger(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
+ return ConsumeInteger(range, context, 1);
}
-bool ConsumeNumberRaw(CSSParserTokenRange& range, double& result) {
+bool ConsumeNumberRaw(CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ double& result) {
if (range.Peek().GetType() == kNumberToken) {
result = range.ConsumeIncludingWhitespace().NumericValue();
return true;
}
- MathFunctionParser math_parser(range, kValueRangeAll);
+ 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) {
@@ -343,7 +357,7 @@ CSSPrimitiveValue* ConsumeNumber(CSSParserTokenRange& range,
return CSSNumericLiteralValue::Create(
range.ConsumeIncludingWhitespace().NumericValue(), token.GetUnitType());
}
- MathFunctionParser math_parser(range, kValueRangeAll);
+ 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
@@ -364,14 +378,14 @@ inline bool ShouldAcceptUnitlessLength(double value,
}
CSSPrimitiveValue* ConsumeLength(CSSParserTokenRange& range,
- CSSParserMode css_parser_mode,
+ 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 (css_parser_mode != kUASheetMode)
+ if (context.Mode() != kUASheetMode)
return nullptr;
FALLTHROUGH;
case CSSPrimitiveValue::UnitType::kEms:
@@ -400,26 +414,27 @@ CSSPrimitiveValue* ConsumeLength(CSSParserTokenRange& range,
range.ConsumeIncludingWhitespace().NumericValue(), token.GetUnitType());
}
if (token.GetType() == kNumberToken) {
- if (!ShouldAcceptUnitlessLength(token.NumericValue(), css_parser_mode,
+ if (!ShouldAcceptUnitlessLength(token.NumericValue(), context.Mode(),
unitless) ||
(value_range == kValueRangeNonNegative && token.NumericValue() < 0))
return nullptr;
CSSPrimitiveValue::UnitType unit_type =
CSSPrimitiveValue::UnitType::kPixels;
- if (css_parser_mode == kSVGAttributeMode)
+ if (context.Mode() == kSVGAttributeMode)
unit_type = CSSPrimitiveValue::UnitType::kUserUnits;
return CSSNumericLiteralValue::Create(
range.ConsumeIncludingWhitespace().NumericValue(), unit_type);
}
- if (css_parser_mode == kSVGAttributeMode)
+ if (context.Mode() == kSVGAttributeMode)
return nullptr;
- MathFunctionParser math_parser(range, value_range);
+ 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) {
@@ -429,7 +444,7 @@ CSSPrimitiveValue* ConsumePercent(CSSParserTokenRange& range,
range.ConsumeIncludingWhitespace().NumericValue(),
CSSPrimitiveValue::UnitType::kPercentage);
}
- MathFunctionParser math_parser(range, value_range);
+ MathFunctionParser math_parser(range, context, value_range);
if (const CSSMathFunctionValue* calculation = math_parser.Value()) {
if (calculation->Category() == kCalcPercent)
return math_parser.ConsumeValue();
@@ -437,11 +452,14 @@ CSSPrimitiveValue* ConsumePercent(CSSParserTokenRange& range,
return nullptr;
}
-CSSPrimitiveValue* ConsumeAlphaValue(CSSParserTokenRange& range) {
- if (CSSPrimitiveValue* value = ConsumeNumber(range, kValueRangeAll)) {
+CSSPrimitiveValue* ConsumeAlphaValue(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
+ if (CSSPrimitiveValue* value =
+ ConsumeNumber(range, context, kValueRangeAll)) {
return value;
}
- if (CSSPrimitiveValue* value = ConsumePercent(range, kValueRangeAll)) {
+ if (CSSPrimitiveValue* value =
+ ConsumePercent(range, context, kValueRangeAll)) {
return CSSNumericLiteralValue::Create(value->GetDoubleValue() / 100.0,
CSSPrimitiveValue::UnitType::kNumber);
}
@@ -465,17 +483,17 @@ bool CanConsumeCalcValue(CalculationCategory category,
}
CSSPrimitiveValue* ConsumeLengthOrPercent(CSSParserTokenRange& range,
- CSSParserMode css_parser_mode,
+ const CSSParserContext& context,
ValueRange value_range,
UnitlessQuirk unitless) {
const CSSParserToken& token = range.Peek();
if (token.GetType() == kDimensionToken || token.GetType() == kNumberToken)
- return ConsumeLength(range, css_parser_mode, value_range, unitless);
+ return ConsumeLength(range, context, value_range, unitless);
if (token.GetType() == kPercentageToken)
- return ConsumePercent(range, value_range);
- MathFunctionParser math_parser(range, value_range);
+ return ConsumePercent(range, context, value_range);
+ MathFunctionParser math_parser(range, context, value_range);
if (const CSSMathFunctionValue* calculation = math_parser.Value()) {
- if (CanConsumeCalcValue(calculation->Category(), css_parser_mode))
+ if (CanConsumeCalcValue(calculation->Category(), context.Mode()))
return math_parser.ConsumeValue();
}
return nullptr;
@@ -510,8 +528,9 @@ CSSPrimitiveValue* ConsumeSVGGeometryPropertyLength(
CSSParserTokenRange& range,
const CSSParserContext& context,
ValueRange value_range) {
- CSSPrimitiveValue* value = ConsumeLengthOrPercent(
- range, kSVGAttributeMode, value_range, UnitlessQuirk::kForbid);
+ CSSParserContext::ParserModeOverridingScope scope(context, kSVGAttributeMode);
+ CSSPrimitiveValue* value = ConsumeLengthOrPercent(range, context, value_range,
+ UnitlessQuirk::kForbid);
if (IsNonZeroUserUnitsValue(value))
context.Count(WebFeature::kSVGGeometryPropertyHasNonZeroUnitlessValue);
return value;
@@ -522,18 +541,15 @@ CSSPrimitiveValue* ConsumeGradientLengthOrPercent(
const CSSParserContext& context,
ValueRange value_range,
UnitlessQuirk unitless) {
- return ConsumeLengthOrPercent(range, context.Mode(), value_range, unitless);
+ return ConsumeLengthOrPercent(range, context, value_range, unitless);
}
CSSPrimitiveValue* ConsumeAngle(
CSSParserTokenRange& range,
- const CSSParserContext* context,
+ const CSSParserContext& context,
base::Optional<WebFeature> unitless_zero_feature,
double minimum_value,
double maximum_value) {
- // Ensure that we have a context for counting the
- // unitless_zero_feature if it is requested.
- DCHECK(context || !unitless_zero_feature);
const CSSParserToken& token = range.Peek();
if (token.GetType() == kDimensionToken) {
switch (token.GetUnitType()) {
@@ -551,11 +567,11 @@ CSSPrimitiveValue* ConsumeAngle(
if (token.GetType() == kNumberToken && token.NumericValue() == 0 &&
unitless_zero_feature) {
range.ConsumeIncludingWhitespace();
- context->Count(*unitless_zero_feature);
+ context.Count(*unitless_zero_feature);
return CSSNumericLiteralValue::Create(
0, CSSPrimitiveValue::UnitType::kDegrees);
}
- MathFunctionParser math_parser(range, kValueRangeAll);
+ MathFunctionParser math_parser(range, context, kValueRangeAll);
if (const CSSMathFunctionValue* calculation = math_parser.Value()) {
if (calculation->Category() != kCalcAngle)
return nullptr;
@@ -576,7 +592,7 @@ CSSPrimitiveValue* ConsumeAngle(
CSSPrimitiveValue* ConsumeAngle(
CSSParserTokenRange& range,
- const CSSParserContext* context,
+ const CSSParserContext& context,
base::Optional<WebFeature> unitless_zero_feature) {
return ConsumeAngle(range, context, std::move(unitless_zero_feature),
std::numeric_limits<double>::lowest(),
@@ -584,6 +600,7 @@ CSSPrimitiveValue* ConsumeAngle(
}
CSSPrimitiveValue* ConsumeTime(CSSParserTokenRange& range,
+ const CSSParserContext& context,
ValueRange value_range) {
const CSSParserToken& token = range.Peek();
if (token.GetType() == kDimensionToken) {
@@ -597,7 +614,7 @@ CSSPrimitiveValue* ConsumeTime(CSSParserTokenRange& range,
token.GetUnitType());
return nullptr;
}
- MathFunctionParser math_parser(range, value_range);
+ MathFunctionParser math_parser(range, context, value_range);
if (const CSSMathFunctionValue* calculation = math_parser.Value()) {
if (calculation->Category() == kCalcTime)
return math_parser.ConsumeValue();
@@ -667,7 +684,7 @@ CSSStringValue* ConsumeString(CSSParserTokenRange& range) {
}
StringView ConsumeUrlAsStringView(CSSParserTokenRange& range,
- const CSSParserContext* context) {
+ const CSSParserContext& context) {
StringView url;
const CSSParserToken& token = range.Peek();
if (token.GetType() == kUrlToken) {
@@ -688,7 +705,7 @@ StringView ConsumeUrlAsStringView(CSSParserTokenRange& range,
// Invalidate the URL if only data URLs are allowed and the protocol is not
// data.
if (!url.IsNull() &&
- context->ResourceFetchRestriction() ==
+ context.ResourceFetchRestriction() ==
ResourceFetchRestriction::kOnlyDataUrls &&
!ProtocolIs(url.ToString(), "data")) {
// The StringView must be instantiated with an empty string otherwise the
@@ -701,13 +718,13 @@ StringView ConsumeUrlAsStringView(CSSParserTokenRange& range,
}
cssvalue::CSSURIValue* ConsumeUrl(CSSParserTokenRange& range,
- const CSSParserContext* context) {
+ const CSSParserContext& context) {
StringView url = ConsumeUrlAsStringView(range, context);
if (url.IsNull())
return nullptr;
- String url_string = url.ToString();
- return cssvalue::CSSURIValue::Create(url_string,
- context->CompleteURL(url_string));
+ AtomicString url_string(url.ToString());
+ return MakeGarbageCollected<cssvalue::CSSURIValue>(
+ url_string, context.CompleteURL(url_string));
}
static int ClampRGBComponent(const CSSPrimitiveValue& value) {
@@ -719,13 +736,16 @@ static int ClampRGBComponent(const CSSPrimitiveValue& value) {
return clampTo<int>(round(result), 0, 255);
}
-static bool ParseRGBParameters(CSSParserTokenRange& range, RGBA32& result) {
+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, kValueRangeAll);
+ CSSPrimitiveValue* color_parameter =
+ ConsumeNumber(args, context, kValueRangeAll);
if (!color_parameter)
- color_parameter = ConsumePercent(args, kValueRangeAll);
+ color_parameter = ConsumePercent(args, context, kValueRangeAll);
if (!color_parameter)
return false;
const bool is_percent = color_parameter->IsPercentage();
@@ -740,8 +760,8 @@ static bool ParseRGBParameters(CSSParserTokenRange& range, RGBA32& result) {
} else if (requires_commas || args.AtEnd()) {
return false;
}
- color_parameter = is_percent ? ConsumePercent(args, kValueRangeAll)
- : ConsumeNumber(args, kValueRangeAll);
+ color_parameter = is_percent ? ConsumePercent(args, context, kValueRangeAll)
+ : ConsumeNumber(args, context, kValueRangeAll);
if (!color_parameter)
return false;
color_array[i] = ClampRGBComponent(*color_parameter);
@@ -754,8 +774,9 @@ static bool ParseRGBParameters(CSSParserTokenRange& range, RGBA32& result) {
return false;
if (comma_consumed || slash_consumed) {
double alpha;
- if (!ConsumeNumberRaw(args, alpha)) {
- CSSPrimitiveValue* alpha_percent = ConsumePercent(args, kValueRangeAll);
+ if (!ConsumeNumberRaw(args, context, alpha)) {
+ CSSPrimitiveValue* alpha_percent =
+ ConsumePercent(args, context, kValueRangeAll);
if (!alpha_percent)
return false;
else
@@ -772,14 +793,16 @@ static bool ParseRGBParameters(CSSParserTokenRange& range, RGBA32& result) {
return args.AtEnd();
}
-static bool ParseHSLParameters(CSSParserTokenRange& range, RGBA32& result) {
+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, nullptr, base::nullopt);
+ CSSPrimitiveValue* hsl_value = ConsumeAngle(args, context, base::nullopt);
double angle_value;
if (!hsl_value) {
- hsl_value = ConsumeNumber(args, kValueRangeAll);
+ hsl_value = ConsumeNumber(args, context, kValueRangeAll);
if (!hsl_value)
return false;
angle_value = hsl_value->GetDoubleValue();
@@ -797,7 +820,7 @@ static bool ParseHSLParameters(CSSParserTokenRange& range, RGBA32& result) {
} else if (requires_commas || args.AtEnd()) {
return false;
}
- hsl_value = ConsumePercent(args, kValueRangeAll);
+ hsl_value = ConsumePercent(args, context, kValueRangeAll);
if (!hsl_value)
return false;
double double_value = hsl_value->GetDoubleValue();
@@ -812,8 +835,9 @@ static bool ParseHSLParameters(CSSParserTokenRange& range, RGBA32& result) {
(slash_consumed && requires_commas))
return false;
if (comma_consumed || slash_consumed) {
- if (!ConsumeNumberRaw(args, alpha)) {
- CSSPrimitiveValue* alpha_percent = ConsumePercent(args, kValueRangeAll);
+ if (!ConsumeNumberRaw(args, context, alpha)) {
+ CSSPrimitiveValue* alpha_percent =
+ ConsumePercent(args, context, kValueRangeAll);
if (!alpha_percent)
return false;
else
@@ -861,82 +885,76 @@ static bool ParseHexColor(CSSParserTokenRange& range,
return true;
}
-static bool ParseColorFunction(CSSParserTokenRange& range, RGBA32& result) {
+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, result)) ||
+ !ParseRGBParameters(color_range, context, result)) ||
(function_id >= CSSValueID::kHsl &&
- !ParseHSLParameters(color_range, result)))
+ !ParseHSLParameters(color_range, context, result)))
return false;
range = color_range;
return true;
}
-static CSSLightDarkColorPair* ParseLightDarkColor(CSSParserTokenRange& range,
- CSSParserMode mode) {
+static CSSLightDarkColorPair* ParseLightDarkColor(
+ CSSParserTokenRange& range,
+ const CSSParserContext& context) {
if (range.Peek().FunctionId() != CSSValueID::kInternalLightDarkColor)
return nullptr;
- if (!isValueAllowedInMode(CSSValueID::kInternalLightDarkColor, mode))
+ if (!isValueAllowedInMode(CSSValueID::kInternalLightDarkColor,
+ context.Mode()))
return nullptr;
+ CSSParserContext::ParserModeOverridingScope scope(context, kUASheetMode);
CSSParserTokenRange args = ConsumeFunction(range);
- CSSValue* light_color = ConsumeColor(args, kUASheetMode);
+ CSSValue* light_color = ConsumeColor(args, context);
if (!light_color || !ConsumeCommaIncludingWhitespace(args))
return nullptr;
- CSSValue* dark_color = ConsumeColor(args, kUASheetMode);
+ CSSValue* dark_color = ConsumeColor(args, context);
if (!dark_color || !args.AtEnd())
return nullptr;
return MakeGarbageCollected<CSSLightDarkColorPair>(light_color, dark_color);
}
CSSValue* ConsumeColor(CSSParserTokenRange& range,
- CSSParserMode css_parser_mode,
+ const CSSParserContext& context,
bool accept_quirky_colors) {
CSSValueID id = range.Peek().Id();
if (StyleColor::IsColorKeyword(id)) {
- if (!isValueAllowedInMode(id, css_parser_mode))
+ if (!isValueAllowedInMode(id, context.Mode()))
return nullptr;
CSSIdentifierValue* color = ConsumeIdent(range);
- if (!RuntimeEnabledFeatures::LinkSystemColorsEnabled() &&
- (color->GetValueID() == CSSValueID::kLinktext ||
- color->GetValueID() == CSSValueID::kVisitedtext)) {
- return nullptr;
- } else if (!RuntimeEnabledFeatures::NewSystemColorsEnabled() &&
- (id == CSSValueID::kActivetext || id == CSSValueID::kField ||
- id == CSSValueID::kFieldtext)) {
- return nullptr;
- }
return color;
}
RGBA32 color = Color::kTransparent;
if (!ParseHexColor(range, color, accept_quirky_colors) &&
- !ParseColorFunction(range, color)) {
- return ParseLightDarkColor(range, css_parser_mode);
+ !ParseColorFunction(range, context, color)) {
+ return ParseLightDarkColor(range, context);
}
return cssvalue::CSSColorValue::Create(color);
}
CSSValue* ConsumeLineWidth(CSSParserTokenRange& range,
- CSSParserMode css_parser_mode,
+ 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, css_parser_mode, kValueRangeNonNegative,
- unitless);
+ return ConsumeLength(range, context, kValueRangeNonNegative, unitless);
}
static CSSValue* ConsumePositionComponent(CSSParserTokenRange& range,
- CSSParserMode css_parser_mode,
+ const CSSParserContext& context,
UnitlessQuirk unitless,
bool& horizontal_edge,
bool& vertical_edge) {
if (range.Peek().GetType() != kIdentToken)
- return ConsumeLengthOrPercent(range, css_parser_mode, kValueRangeAll,
- unitless);
+ return ConsumeLengthOrPercent(range, context, kValueRangeAll, unitless);
CSSValueID id = range.Peek().Id();
if (id == CSSValueID::kLeft || id == CSSValueID::kRight) {
@@ -1047,7 +1065,7 @@ bool ConsumePosition(CSSParserTokenRange& range,
CSSValue*& result_y) {
bool horizontal_edge = false;
bool vertical_edge = false;
- CSSValue* value1 = ConsumePositionComponent(range, context.Mode(), unitless,
+ CSSValue* value1 = ConsumePositionComponent(range, context, unitless,
horizontal_edge, vertical_edge);
if (!value1)
return false;
@@ -1055,7 +1073,7 @@ bool ConsumePosition(CSSParserTokenRange& range,
horizontal_edge = true;
CSSParserTokenRange range_after_first_consume = range;
- CSSValue* value2 = ConsumePositionComponent(range, context.Mode(), unitless,
+ CSSValue* value2 = ConsumePositionComponent(range, context, unitless,
horizontal_edge, vertical_edge);
if (!value2) {
PositionFromOneValue(value1, result_x, result_y);
@@ -1072,9 +1090,10 @@ bool ConsumePosition(CSSParserTokenRange& range,
!!identifier_value2 != (range.Peek().GetType() == kIdentToken) &&
(identifier_value2
? identifier_value2->GetValueID()
- : identifier_value1->GetValueID()) != CSSValueID::kCenter)
- value3 = ConsumePositionComponent(range, context.Mode(), unitless,
- horizontal_edge, vertical_edge);
+ : 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;
@@ -1089,9 +1108,10 @@ bool ConsumePosition(CSSParserTokenRange& range,
auto* identifier_value3 = DynamicTo<CSSIdentifierValue>(value3);
if (identifier_value3 &&
identifier_value3->GetValueID() != CSSValueID::kCenter &&
- range.Peek().GetType() != kIdentToken)
- value4 = ConsumePositionComponent(range, context.Mode(), unitless,
- horizontal_edge, vertical_edge);
+ range.Peek().GetType() != kIdentToken) {
+ value4 = ConsumePositionComponent(range, context, unitless, horizontal_edge,
+ vertical_edge);
+ }
if (!value4) {
if (!three_value_position) {
@@ -1135,25 +1155,25 @@ CSSValuePair* ConsumePosition(CSSParserTokenRange& range,
}
bool ConsumeOneOrTwoValuedPosition(CSSParserTokenRange& range,
- CSSParserMode css_parser_mode,
+ const CSSParserContext& context,
UnitlessQuirk unitless,
CSSValue*& result_x,
CSSValue*& result_y) {
bool horizontal_edge = false;
bool vertical_edge = false;
- CSSValue* value1 = ConsumePositionComponent(range, css_parser_mode, unitless,
+ 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, css_parser_mode,
- kValueRangeAll, unitless)) {
+ if (vertical_edge &&
+ ConsumeLengthOrPercent(range, context, kValueRangeAll, unitless)) {
// <length-percentage> is not permitted after top | bottom.
return false;
}
- CSSValue* value2 = ConsumePositionComponent(range, css_parser_mode, unitless,
+ CSSValue* value2 = ConsumePositionComponent(range, context, unitless,
horizontal_edge, vertical_edge);
if (!value2) {
PositionFromOneValue(value1, result_x, result_y);
@@ -1171,8 +1191,7 @@ bool ConsumeBorderShorthand(CSSParserTokenRange& range,
while (!result_width || !result_style || !result_color) {
if (!result_width) {
result_width = css_property_parser_helpers::ConsumeLineWidth(
- range, context.Mode(),
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
if (result_width)
continue;
}
@@ -1184,8 +1203,7 @@ bool ConsumeBorderShorthand(CSSParserTokenRange& range,
continue;
}
if (!result_color) {
- result_color =
- css_property_parser_helpers::ConsumeColor(range, context.Mode());
+ result_color = css_property_parser_helpers::ConsumeColor(range, context);
if (result_color)
continue;
}
@@ -1207,6 +1225,7 @@ bool ConsumeBorderShorthand(CSSParserTokenRange& range,
// 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)) ||
@@ -1222,25 +1241,25 @@ static CSSPrimitiveValue* ConsumeDeprecatedGradientPoint(
50., CSSPrimitiveValue::UnitType::kPercentage);
return nullptr;
}
- CSSPrimitiveValue* result = ConsumePercent(args, kValueRangeAll);
+ CSSPrimitiveValue* result = ConsumePercent(args, context, kValueRangeAll);
if (!result)
- result = ConsumeNumber(args, kValueRangeAll);
+ result = ConsumeNumber(args, context, kValueRangeAll);
return result;
}
// Used to parse colors for -webkit-gradient(...).
static CSSValue* ConsumeDeprecatedGradientStopColor(
CSSParserTokenRange& args,
- CSSParserMode css_parser_mode) {
+ const CSSParserContext& context) {
if (args.Peek().Id() == CSSValueID::kCurrentcolor)
return nullptr;
- return ConsumeColor(args, css_parser_mode);
+ return ConsumeColor(args, context);
}
static bool ConsumeDeprecatedGradientColorStop(
CSSParserTokenRange& range,
cssvalue::CSSGradientColorStop& stop,
- CSSParserMode css_parser_mode) {
+ const CSSParserContext& context) {
CSSValueID id = range.Peek().FunctionId();
if (id != CSSValueID::kFrom && id != CSSValueID::kTo &&
id != CSSValueID::kColorStop)
@@ -1252,9 +1271,10 @@ static bool ConsumeDeprecatedGradientColorStop(
position = (id == CSSValueID::kFrom) ? 0 : 1;
} else {
DCHECK(id == CSSValueID::kColorStop);
- if (CSSPrimitiveValue* percent_value = ConsumePercent(args, kValueRangeAll))
+ if (CSSPrimitiveValue* percent_value =
+ ConsumePercent(args, context, kValueRangeAll))
position = percent_value->GetDoubleValue() / 100.0;
- else if (!ConsumeNumberRaw(args, position))
+ else if (!ConsumeNumberRaw(args, context, position))
return false;
if (!ConsumeCommaIncludingWhitespace(args))
@@ -1263,12 +1283,12 @@ static bool ConsumeDeprecatedGradientColorStop(
stop.offset_ = CSSNumericLiteralValue::Create(
position, CSSPrimitiveValue::UnitType::kNumber);
- stop.color_ = ConsumeDeprecatedGradientStopColor(args, css_parser_mode);
+ stop.color_ = ConsumeDeprecatedGradientStopColor(args, context);
return stop.color_ && args.AtEnd();
}
static CSSValue* ConsumeDeprecatedGradient(CSSParserTokenRange& args,
- CSSParserMode css_parser_mode) {
+ const CSSParserContext& context) {
CSSValueID id = args.ConsumeIncludingWhitespace().Id();
if (id != CSSValueID::kRadial && id != CSSValueID::kLinear)
return nullptr;
@@ -1276,11 +1296,12 @@ static CSSValue* ConsumeDeprecatedGradient(CSSParserTokenRange& args,
if (!ConsumeCommaIncludingWhitespace(args))
return nullptr;
- const CSSPrimitiveValue* first_x = ConsumeDeprecatedGradientPoint(args, true);
+ const CSSPrimitiveValue* first_x =
+ ConsumeDeprecatedGradientPoint(args, context, true);
if (!first_x)
return nullptr;
const CSSPrimitiveValue* first_y =
- ConsumeDeprecatedGradientPoint(args, false);
+ ConsumeDeprecatedGradientPoint(args, context, false);
if (!first_y)
return nullptr;
if (!ConsumeCommaIncludingWhitespace(args))
@@ -1289,17 +1310,17 @@ static CSSValue* ConsumeDeprecatedGradient(CSSParserTokenRange& args,
// For radial gradients only, we now expect a numeric radius.
const CSSPrimitiveValue* first_radius = nullptr;
if (id == CSSValueID::kRadial) {
- first_radius = ConsumeNumber(args, kValueRangeNonNegative);
+ first_radius = ConsumeNumber(args, context, kValueRangeNonNegative);
if (!first_radius || !ConsumeCommaIncludingWhitespace(args))
return nullptr;
}
const CSSPrimitiveValue* second_x =
- ConsumeDeprecatedGradientPoint(args, true);
+ ConsumeDeprecatedGradientPoint(args, context, true);
if (!second_x)
return nullptr;
const CSSPrimitiveValue* second_y =
- ConsumeDeprecatedGradientPoint(args, false);
+ ConsumeDeprecatedGradientPoint(args, context, false);
if (!second_y)
return nullptr;
@@ -1308,24 +1329,24 @@ static CSSValue* ConsumeDeprecatedGradient(CSSParserTokenRange& args,
if (id == CSSValueID::kRadial) {
if (!ConsumeCommaIncludingWhitespace(args))
return nullptr;
- second_radius = ConsumeNumber(args, kValueRangeNonNegative);
+ second_radius = ConsumeNumber(args, context, kValueRangeNonNegative);
if (!second_radius)
return nullptr;
}
- cssvalue::CSSGradientValue* result =
- (id == CSSValueID::kRadial)
- ? cssvalue::CSSRadialGradientValue::Create(
- first_x, first_y, first_radius, second_x, second_y,
- second_radius, cssvalue::kNonRepeating,
- cssvalue::kCSSDeprecatedRadialGradient)
- : MakeGarbageCollected<cssvalue::CSSLinearGradientValue>(
- first_x, first_y, second_x, second_y, nullptr,
- cssvalue::kNonRepeating,
- cssvalue::kCSSDeprecatedLinearGradient);
+ 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, css_parser_mode))
+ if (!ConsumeDeprecatedGradientColorStop(args, stop, context))
return nullptr;
result->AddStop(stop);
}
@@ -1340,12 +1361,11 @@ static CSSPrimitiveValue* ConsumeGradientAngleOrPercent(
UnitlessQuirk) {
const CSSParserToken& token = range.Peek();
if (token.GetType() == kDimensionToken || token.GetType() == kNumberToken) {
- return ConsumeAngle(range, &context,
- WebFeature::kUnitlessZeroAngleGradient);
+ return ConsumeAngle(range, context, WebFeature::kUnitlessZeroAngleGradient);
}
if (token.GetType() == kPercentageToken)
- return ConsumePercent(range, value_range);
- MathFunctionParser math_parser(range, value_range);
+ 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?
@@ -1373,7 +1393,7 @@ static bool ConsumeGradientColorStops(CSSParserTokenRange& range,
bool previous_stop_was_color_hint = true;
do {
cssvalue::CSSGradientColorStop stop;
- stop.color_ = ConsumeColor(range, context.Mode());
+ 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;
@@ -1408,8 +1428,8 @@ static CSSValue* ConsumeDeprecatedRadialGradient(
cssvalue::CSSGradientRepeat repeating) {
CSSValue* center_x = nullptr;
CSSValue* center_y = nullptr;
- ConsumeOneOrTwoValuedPosition(args, context.Mode(), UnitlessQuirk::kForbid,
- center_x, center_y);
+ ConsumeOneOrTwoValuedPosition(args, context, UnitlessQuirk::kForbid, center_x,
+ center_y);
if ((center_x || center_y) && !ConsumeCommaIncludingWhitespace(args))
return nullptr;
@@ -1427,10 +1447,10 @@ static CSSValue* ConsumeDeprecatedRadialGradient(
const CSSPrimitiveValue* vertical_size = nullptr;
if (!shape && !size_keyword) {
horizontal_size =
- ConsumeLengthOrPercent(args, context.Mode(), kValueRangeNonNegative);
+ ConsumeLengthOrPercent(args, context, kValueRangeNonNegative);
if (horizontal_size) {
vertical_size =
- ConsumeLengthOrPercent(args, context.Mode(), kValueRangeNonNegative);
+ ConsumeLengthOrPercent(args, context, kValueRangeNonNegative);
if (!vertical_size)
return nullptr;
ConsumeCommaIncludingWhitespace(args);
@@ -1439,9 +1459,10 @@ static CSSValue* ConsumeDeprecatedRadialGradient(
ConsumeCommaIncludingWhitespace(args);
}
- cssvalue::CSSGradientValue* result = cssvalue::CSSRadialGradientValue::Create(
- center_x, center_y, shape, size_keyword, horizontal_size, vertical_size,
- repeating, cssvalue::kCSSPrefixedRadialGradient);
+ 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
@@ -1479,14 +1500,13 @@ static CSSValue* ConsumeRadialGradient(CSSParserTokenRange& args,
}
} else {
CSSPrimitiveValue* center =
- ConsumeLengthOrPercent(args, context.Mode(), kValueRangeNonNegative);
+ ConsumeLengthOrPercent(args, context, kValueRangeNonNegative);
if (!center)
break;
if (horizontal_size)
return nullptr;
horizontal_size = center;
- center =
- ConsumeLengthOrPercent(args, context.Mode(), kValueRangeNonNegative);
+ center = ConsumeLengthOrPercent(args, context, kValueRangeNonNegative);
if (center) {
vertical_size = center;
++i;
@@ -1530,9 +1550,10 @@ static CSSValue* ConsumeRadialGradient(CSSParserTokenRange& args,
return nullptr;
}
- cssvalue::CSSGradientValue* result = cssvalue::CSSRadialGradientValue::Create(
- center_x, center_y, shape, size_keyword, horizontal_size, vertical_size,
- repeating, cssvalue::kCSSRadialGradient);
+ 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
@@ -1546,7 +1567,7 @@ static CSSValue* ConsumeLinearGradient(
cssvalue::CSSGradientType gradient_type) {
bool expect_comma = true;
const CSSPrimitiveValue* angle =
- ConsumeAngle(args, &context, WebFeature::kUnitlessZeroAngleGradient);
+ ConsumeAngle(args, context, WebFeature::kUnitlessZeroAngleGradient);
const CSSIdentifierValue* end_x = nullptr;
const CSSIdentifierValue* end_y = nullptr;
if (!angle) {
@@ -1584,7 +1605,7 @@ static CSSValue* ConsumeConicGradient(CSSParserTokenRange& args,
cssvalue::CSSGradientRepeat repeating) {
const CSSPrimitiveValue* from_angle = nullptr;
if (ConsumeIdent<CSSValueID::kFrom>(args)) {
- if (!(from_angle = ConsumeAngle(args, &context,
+ if (!(from_angle = ConsumeAngle(args, context,
WebFeature::kUnitlessZeroAngleGradient)))
return nullptr;
}
@@ -1603,7 +1624,7 @@ static CSSValue* ConsumeConicGradient(CSSParserTokenRange& args,
return nullptr;
}
- cssvalue::CSSGradientValue* result = cssvalue::CSSConicGradientValue::Create(
+ auto* result = MakeGarbageCollected<cssvalue::CSSConicGradientValue>(
center_x, center_y, from_angle, repeating);
return ConsumeGradientColorStops(args, context, result,
ConsumeGradientAngleOrPercent)
@@ -1612,13 +1633,14 @@ static CSSValue* ConsumeConicGradient(CSSParserTokenRange& args,
}
CSSValue* ConsumeImageOrNone(CSSParserTokenRange& range,
- const CSSParserContext* context) {
+ const CSSParserContext& context) {
if (range.Peek().Id() == CSSValueID::kNone)
return ConsumeIdent(range);
return ConsumeImage(range, context);
}
-CSSValue* ConsumeAxis(CSSParserTokenRange& range) {
+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) {
@@ -1626,12 +1648,12 @@ CSSValue* ConsumeAxis(CSSParserTokenRange& range) {
return MakeGarbageCollected<cssvalue::CSSAxisValue>(axis_id);
}
- CSSValue* x_dimension =
- css_property_parser_helpers::ConsumeNumber(range, kValueRangeAll);
- CSSValue* y_dimension =
- css_property_parser_helpers::ConsumeNumber(range, kValueRangeAll);
- CSSValue* z_dimension =
- css_property_parser_helpers::ConsumeNumber(range, kValueRangeAll);
+ 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();
@@ -1641,7 +1663,7 @@ CSSValue* ConsumeAxis(CSSParserTokenRange& range) {
}
static CSSValue* ConsumeCrossFade(CSSParserTokenRange& args,
- const CSSParserContext* context) {
+ const CSSParserContext& context) {
CSSValue* from_image_value = ConsumeImageOrNone(args, context);
if (!from_image_value || !ConsumeCommaIncludingWhitespace(args))
return nullptr;
@@ -1650,12 +1672,13 @@ static CSSValue* ConsumeCrossFade(CSSParserTokenRange& args,
return nullptr;
CSSPrimitiveValue* percentage = nullptr;
- if (CSSPrimitiveValue* percent_value = ConsumePercent(args, kValueRangeAll))
+ 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, kValueRangeAll))
+ ConsumeNumber(args, context, kValueRangeAll))
percentage = CSSNumericLiteralValue::Create(
clampTo<double>(number_value->GetDoubleValue(), 0, 1),
CSSPrimitiveValue::UnitType::kNumber);
@@ -1667,9 +1690,9 @@ static CSSValue* ConsumeCrossFade(CSSParserTokenRange& args,
}
static CSSValue* ConsumePaint(CSSParserTokenRange& args,
- const CSSParserContext* context) {
+ const CSSParserContext& context) {
const CSSParserToken& name_token = args.ConsumeIncludingWhitespace();
- CSSCustomIdentValue* name = ConsumeCustomIdentWithToken(name_token, *context);
+ CSSCustomIdentValue* name = ConsumeCustomIdentWithToken(name_token, context);
if (!name)
return nullptr;
@@ -1708,48 +1731,48 @@ static CSSValue* ConsumePaint(CSSParserTokenRange& args,
}
static CSSValue* ConsumeGeneratedImage(CSSParserTokenRange& range,
- const CSSParserContext* context) {
+ 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);
+ result = ConsumeRadialGradient(args, context, cssvalue::kNonRepeating);
} else if (id == CSSValueID::kRepeatingRadialGradient) {
- result = ConsumeRadialGradient(args, *context, cssvalue::kRepeating);
+ result = ConsumeRadialGradient(args, context, cssvalue::kRepeating);
} else if (id == CSSValueID::kWebkitLinearGradient) {
- context->Count(WebFeature::kDeprecatedWebKitLinearGradient);
- result = ConsumeLinearGradient(args, *context, cssvalue::kNonRepeating,
+ 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,
+ context.Count(WebFeature::kDeprecatedWebKitRepeatingLinearGradient);
+ result = ConsumeLinearGradient(args, context, cssvalue::kRepeating,
cssvalue::kCSSPrefixedLinearGradient);
} else if (id == CSSValueID::kRepeatingLinearGradient) {
- result = ConsumeLinearGradient(args, *context, cssvalue::kRepeating,
+ result = ConsumeLinearGradient(args, context, cssvalue::kRepeating,
cssvalue::kCSSLinearGradient);
} else if (id == CSSValueID::kLinearGradient) {
- result = ConsumeLinearGradient(args, *context, cssvalue::kNonRepeating,
+ result = ConsumeLinearGradient(args, context, cssvalue::kNonRepeating,
cssvalue::kCSSLinearGradient);
} else if (id == CSSValueID::kWebkitGradient) {
- context->Count(WebFeature::kDeprecatedWebKitGradient);
- result = ConsumeDeprecatedGradient(args, context->Mode());
+ context.Count(WebFeature::kDeprecatedWebKitGradient);
+ result = ConsumeDeprecatedGradient(args, context);
} else if (id == CSSValueID::kWebkitRadialGradient) {
- context->Count(WebFeature::kDeprecatedWebKitRadialGradient);
- result = ConsumeDeprecatedRadialGradient(args, *context,
- cssvalue::kNonRepeating);
+ context.Count(WebFeature::kDeprecatedWebKitRadialGradient);
+ result =
+ ConsumeDeprecatedRadialGradient(args, context, cssvalue::kNonRepeating);
} else if (id == CSSValueID::kWebkitRepeatingRadialGradient) {
- context->Count(WebFeature::kDeprecatedWebKitRepeatingRadialGradient);
+ context.Count(WebFeature::kDeprecatedWebKitRepeatingRadialGradient);
result =
- ConsumeDeprecatedRadialGradient(args, *context, cssvalue::kRepeating);
+ ConsumeDeprecatedRadialGradient(args, context, cssvalue::kRepeating);
} else if (id == CSSValueID::kConicGradient) {
- result = ConsumeConicGradient(args, *context, cssvalue::kNonRepeating);
+ result = ConsumeConicGradient(args, context, cssvalue::kNonRepeating);
} else if (id == CSSValueID::kRepeatingConicGradient) {
- result = ConsumeConicGradient(args, *context, cssvalue::kRepeating);
+ 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;
+ result = context.IsSecureContext() ? ConsumePaint(args, context) : nullptr;
}
if (!result || !args.AtEnd())
return nullptr;
@@ -1761,7 +1784,7 @@ static CSSValue* ConsumeGeneratedImage(CSSParserTokenRange& range,
feature = WebFeature::kCSSPaintFunction;
else
feature = WebFeature::kCSSGradient;
- context->Count(feature);
+ context.Count(feature);
range = range_copy;
return result;
@@ -1769,18 +1792,18 @@ static CSSValue* ConsumeGeneratedImage(CSSParserTokenRange& range,
static CSSValue* CreateCSSImageValueWithReferrer(
const AtomicString& raw_value,
- const CSSParserContext* context) {
- CSSValue* image_value = CSSImageValue::Create(
- raw_value, context->CompleteURL(raw_value), context->GetReferrer(),
- context->IsOriginClean() ? OriginClean::kTrue : OriginClean::kFalse);
+ const CSSParserContext& context) {
+ CSSValue* image_value = MakeGarbageCollected<CSSImageValue>(
+ raw_value, context.CompleteURL(raw_value), context.GetReferrer(),
+ context.IsOriginClean() ? OriginClean::kTrue : OriginClean::kFalse);
return image_value;
}
static CSSValue* ConsumeImageSet(CSSParserTokenRange& range,
- const CSSParserContext* context) {
+ const CSSParserContext& context) {
CSSParserTokenRange range_copy = range;
CSSParserTokenRange args = ConsumeFunction(range_copy);
- auto* image_set = MakeGarbageCollected<CSSImageSetValue>(context->Mode());
+ auto* image_set = MakeGarbageCollected<CSSImageSetValue>(context.Mode());
do {
AtomicString url_value =
ConsumeUrlAsStringView(args, context).ToAtomicString();
@@ -1824,7 +1847,7 @@ static bool IsGeneratedImage(CSSValueID id) {
}
CSSValue* ConsumeImage(CSSParserTokenRange& range,
- const CSSParserContext* context,
+ const CSSParserContext& context,
ConsumeGeneratedImagePolicy generated_image) {
AtomicString uri = ConsumeUrlAsStringView(range, context).ToAtomicString();
if (!uri.IsNull())
@@ -1912,7 +1935,7 @@ CSSValue* ConsumeFilterFunctionList(CSSParserTokenRange& range,
CSSValueList* list = CSSValueList::CreateSpaceSeparated();
do {
- CSSValue* filter_value = ConsumeUrl(range, &context);
+ CSSValue* filter_value = ConsumeUrl(range, context);
if (!filter_value) {
filter_value = ConsumeFilterFunction(range, context);
if (!filter_value)
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
index 90e4e387eb4..45c628c090a 100644
--- 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
@@ -49,20 +49,30 @@ enum class UnitlessQuirk { kAllow, kForbid };
CSSPrimitiveValue* ConsumeInteger(
CSSParserTokenRange&,
+ const CSSParserContext&,
double minimum_value = -std::numeric_limits<double>::max());
-CSSPrimitiveValue* ConsumeIntegerOrNumberCalc(CSSParserTokenRange&);
-CSSPrimitiveValue* ConsumePositiveInteger(CSSParserTokenRange&);
-bool ConsumeNumberRaw(CSSParserTokenRange&, double& result);
-CSSPrimitiveValue* ConsumeNumber(CSSParserTokenRange&, ValueRange);
+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&,
- CSSParserMode,
+ const CSSParserContext&,
ValueRange,
UnitlessQuirk = UnitlessQuirk::kForbid);
-CSSPrimitiveValue* ConsumePercent(CSSParserTokenRange&, ValueRange);
-CSSPrimitiveValue* ConsumeAlphaValue(CSSParserTokenRange&);
+CSSPrimitiveValue* ConsumePercent(CSSParserTokenRange&,
+ const CSSParserContext&,
+ ValueRange);
+CSSPrimitiveValue* ConsumeAlphaValue(CSSParserTokenRange&,
+ const CSSParserContext&);
CSSPrimitiveValue* ConsumeLengthOrPercent(
CSSParserTokenRange&,
- CSSParserMode,
+ const CSSParserContext&,
ValueRange,
UnitlessQuirk = UnitlessQuirk::kForbid);
CSSPrimitiveValue* ConsumeSVGGeometryPropertyLength(CSSParserTokenRange&,
@@ -71,15 +81,17 @@ CSSPrimitiveValue* ConsumeSVGGeometryPropertyLength(CSSParserTokenRange&,
CSSPrimitiveValue* ConsumeAngle(
CSSParserTokenRange&,
- const CSSParserContext*,
+ const CSSParserContext&,
base::Optional<WebFeature> unitless_zero_feature);
CSSPrimitiveValue* ConsumeAngle(
CSSParserTokenRange&,
- const CSSParserContext*,
+ const CSSParserContext&,
base::Optional<WebFeature> unitless_zero_feature,
double minimum_value,
double maximum_value);
-CSSPrimitiveValue* ConsumeTime(CSSParserTokenRange&, ValueRange);
+CSSPrimitiveValue* ConsumeTime(CSSParserTokenRange&,
+ const CSSParserContext&,
+ ValueRange);
CSSPrimitiveValue* ConsumeResolution(CSSParserTokenRange&);
CSSIdentifierValue* ConsumeIdent(CSSParserTokenRange&);
@@ -95,15 +107,17 @@ CSSCustomIdentValue* ConsumeCustomIdent(CSSParserTokenRange&,
const CSSParserContext&);
CSSStringValue* ConsumeString(CSSParserTokenRange&);
StringView ConsumeUrlAsStringView(CSSParserTokenRange&,
- const CSSParserContext*);
+ const CSSParserContext&);
cssvalue::CSSURIValue* ConsumeUrl(CSSParserTokenRange&,
- const CSSParserContext*);
+ const CSSParserContext&);
CSSValue* ConsumeColor(CSSParserTokenRange&,
- CSSParserMode,
+ const CSSParserContext&,
bool accept_quirky_colors = false);
-CSSValue* ConsumeLineWidth(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk);
+CSSValue* ConsumeLineWidth(CSSParserTokenRange&,
+ const CSSParserContext&,
+ UnitlessQuirk);
CSSValuePair* ConsumePosition(CSSParserTokenRange&,
const CSSParserContext&,
@@ -116,7 +130,7 @@ bool ConsumePosition(CSSParserTokenRange&,
CSSValue*& result_x,
CSSValue*& result_y);
bool ConsumeOneOrTwoValuedPosition(CSSParserTokenRange&,
- CSSParserMode,
+ const CSSParserContext&,
UnitlessQuirk,
CSSValue*& result_x,
CSSValue*& result_y);
@@ -130,11 +144,11 @@ enum class ConsumeGeneratedImagePolicy { kAllow, kForbid };
CSSValue* ConsumeImage(
CSSParserTokenRange&,
- const CSSParserContext*,
+ const CSSParserContext&,
ConsumeGeneratedImagePolicy = ConsumeGeneratedImagePolicy::kAllow);
-CSSValue* ConsumeImageOrNone(CSSParserTokenRange&, const CSSParserContext*);
+CSSValue* ConsumeImageOrNone(CSSParserTokenRange&, const CSSParserContext&);
-CSSValue* ConsumeAxis(CSSParserTokenRange&);
+CSSValue* ConsumeAxis(CSSParserTokenRange&, const CSSParserContext& context);
bool IsCSSWideKeyword(StringView);
bool IsRevertKeyword(StringView);
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_property_parser_test.cc b/chromium/third_party/blink/renderer/core/css/parser/css_property_parser_test.cc
index 83e602857dd..edd37e2658e 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_property_parser_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_property_parser_test.cc
@@ -378,7 +378,7 @@ TEST(CSSPropertyParserTest, GradientUseCount) {
Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
WebFeature feature = WebFeature::kCSSGradient;
EXPECT_FALSE(document.IsUseCounted(feature));
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<style>* { background-image: linear-gradient(red, blue); }</style>");
EXPECT_TRUE(document.IsUseCounted(feature));
}
@@ -387,10 +387,10 @@ TEST(CSSPropertyParserTest, PaintUseCount) {
auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
Document& document = dummy_page_holder->GetDocument();
Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
- document.SetSecureContextStateForTesting(SecureContextState::kSecure);
+ document.SetSecureContextModeForTesting(SecureContextMode::kSecureContext);
WebFeature feature = WebFeature::kCSSPaintFunction;
EXPECT_FALSE(document.IsUseCounted(feature));
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<style>span { background-image: paint(geometry); }</style>");
EXPECT_TRUE(document.IsUseCounted(feature));
}
@@ -401,7 +401,7 @@ TEST(CSSPropertyParserTest, CrossFadeUseCount) {
Page::InsertOrdinaryPageForTesting(&dummy_page_holder->GetPage());
WebFeature feature = WebFeature::kWebkitCrossFade;
EXPECT_FALSE(document.IsUseCounted(feature));
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<style>div { background-image: -webkit-cross-fade(url('from.png'), "
"url('to.png'), 0.2); }</style>");
EXPECT_TRUE(document.IsUseCounted(feature));
@@ -415,7 +415,7 @@ TEST(CSSPropertyParserTest, TwoValueOverflowOverlayCount) {
WebFeature feature2 = WebFeature::kTwoValuedOverflow;
EXPECT_FALSE(document.IsUseCounted(feature));
EXPECT_FALSE(document.IsUseCounted(feature2));
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<div style=\"height: 10px; width: 10px; overflow: overlay overlay;\">"
"<div style=\"height: 50px; width: 50px;\"></div></div>");
EXPECT_TRUE(document.IsUseCounted(feature));
@@ -430,7 +430,7 @@ TEST(CSSPropertyParserTest, OneValueOverflowOverlayCount) {
WebFeature feature2 = WebFeature::kTwoValuedOverflow;
EXPECT_FALSE(document.IsUseCounted(feature));
EXPECT_FALSE(document.IsUseCounted(feature2));
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<div style=\"height: 10px; width: 10px; overflow: overlay;\">"
"<div style=\"height: 50px; width: 50px;\"></div></div>");
EXPECT_TRUE(document.IsUseCounted(feature));
@@ -445,7 +445,7 @@ TEST(CSSPropertyParserTest, OverflowXOverlayCount) {
WebFeature feature2 = WebFeature::kTwoValuedOverflow;
EXPECT_FALSE(document.IsUseCounted(feature));
EXPECT_FALSE(document.IsUseCounted(feature2));
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<div style=\"height: 10px; width: 10px; overflow-x: overlay;\">"
"<div style=\"height: 50px; width: 50px;\"></div></div>");
EXPECT_TRUE(document.IsUseCounted(feature));
@@ -460,7 +460,7 @@ TEST(CSSPropertyParserTest, OverflowYOverlayCount) {
WebFeature feature2 = WebFeature::kTwoValuedOverflow;
EXPECT_FALSE(document.IsUseCounted(feature));
EXPECT_FALSE(document.IsUseCounted(feature2));
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<div style=\"height: 10px; width: 10px; overflow-y: overlay;\">"
"<div style=\"height: 50px; width: 50px;\"></div></div>");
EXPECT_TRUE(document.IsUseCounted(feature));
@@ -475,7 +475,7 @@ TEST(CSSPropertyParserTest, OverflowFirstValueOverlayCount) {
WebFeature feature2 = WebFeature::kTwoValuedOverflow;
EXPECT_FALSE(document.IsUseCounted(feature));
EXPECT_FALSE(document.IsUseCounted(feature2));
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<div style=\"height: 10px; width: 10px; overflow: overlay scroll;\">"
"<div style=\"height: 50px; width: 50px;\"></div></div>");
EXPECT_TRUE(document.IsUseCounted(feature));
@@ -490,7 +490,7 @@ TEST(CSSPropertyParserTest, OverflowSecondValueOverlayCount) {
WebFeature feature2 = WebFeature::kTwoValuedOverflow;
EXPECT_FALSE(document.IsUseCounted(feature));
EXPECT_FALSE(document.IsUseCounted(feature2));
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<div style=\"height: 10px; width: 10px; overflow: scroll overlay;\">"
"<div style=\"height: 50px; width: 50px;\"></div></div>");
EXPECT_TRUE(document.IsUseCounted(feature));
@@ -615,7 +615,7 @@ TEST_F(CSSPropertyUseCounterTest, CSSPropertyCyUnitlessUseCount) {
TEST_F(CSSPropertyUseCounterTest, UnitlessPresentationAttributesNotCounted) {
WebFeature feature = WebFeature::kSVGGeometryPropertyHasNonZeroUnitlessValue;
EXPECT_FALSE(IsCounted(feature));
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<svg>
<rect x="42" y="42" rx="42" ry="42"/>
<circle cx="42" cy="42" r="42"/>
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 6a7eb90c89c..50fa91463a0 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
@@ -38,7 +38,6 @@ const std::string Converter::kPseudoLookupTable[] = {
"-internal-spatial-navigation-focus",
"-internal-video-persistent",
"-internal-video-persistent-ancestor",
- "-internal-xr-immersive-dom-overlay",
"-webkit-any-link",
"-webkit-autofill",
"-webkit-drag",
@@ -121,6 +120,7 @@ const std::string Converter::kPseudoLookupTable[] = {
"nth-last-of-type",
"nth-of-type",
"slotted",
+ "xr-overlay",
"INVALID_PSEUDO_VALUE"};
const std::string Converter::kMediaTypeLookupTable[] = {
@@ -956,6 +956,8 @@ const std::string Converter::kValueLookupTable[] = {
"smooth",
"jump-start",
"no-drag",
+ "jis-b5",
+ "jis-b4",
"INVALID_VALUE",
};
@@ -1028,7 +1030,6 @@ const std::string Converter::kPropertyLookupTable[] = {
"-webkit-mask-position-x",
"-webkit-mask-position-y",
"outline-style",
- "-webkit-margin-bottom-collapse",
"color-interpolation-filters",
"font-variant",
"-webkit-animation-fill-mode",
@@ -1052,7 +1053,6 @@ const std::string Converter::kPropertyLookupTable[] = {
"column-width",
"list-style",
"-webkit-mask-repeat-y",
- "-webkit-margin-before-collapse",
"stroke",
"text-decoration-line",
"-webkit-background-size",
@@ -1340,7 +1340,6 @@ const std::string Converter::kPropertyLookupTable[] = {
"-webkit-transition-property",
"writing-mode",
"stroke-opacity",
- "-webkit-margin-collapse",
"box-sizing",
"margin-top",
"column-rule-color",
@@ -1377,7 +1376,6 @@ const std::string Converter::kPropertyLookupTable[] = {
"justify-items",
"zoom",
"scroll-padding-block-start",
- "-webkit-margin-top-collapse",
"page",
"right",
"user-select",
@@ -1434,7 +1432,6 @@ const std::string Converter::kPropertyLookupTable[] = {
"scroll-margin-left",
"border-style",
"animation-iteration-count",
- "-webkit-margin-after-collapse",
"overflow",
"user-zoom",
"-webkit-border-top-right-radius",
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 ca9550f30d8..4831273c13a 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
@@ -52,6 +52,22 @@ CSSSelectorList CSSSelectorParser::ConsumeSelector(
return result;
}
+// static
+bool CSSSelectorParser::SupportsComplexSelector(
+ CSSParserTokenRange range,
+ const CSSParserContext* context) {
+ range.ConsumeWhitespace();
+ CSSSelectorParser parser(context, nullptr);
+ auto parser_selector = parser.ConsumeComplexSelector(range);
+ if (parser.failed_parsing_ || !range.AtEnd() || !parser_selector)
+ return false;
+ auto complex_selector = parser_selector->ReleaseSelector();
+ DCHECK(complex_selector);
+ if (ContainsUnknownWebkitPseudoElements(*complex_selector.get()))
+ return false;
+ return true;
+}
+
CSSSelectorParser::CSSSelectorParser(const CSSParserContext* context,
StyleSheetContents* style_sheet)
: context_(context), style_sheet_(style_sheet) {}
@@ -148,10 +164,10 @@ unsigned ExtractCompoundFlags(const CSSParserSelector& simple_selector,
return kHasContentPseudoElement;
if (simple_selector.GetPseudoType() == CSSSelector::kPseudoShadow)
return 0;
- // TODO(futhark@chromium.org): crbug.com/578131
- // The UASheetMode check is a work-around to allow this selector in
- // mediaControls(New).css:
- // input[type="range" i]::-webkit-media-slider-container > div {
+ // We don't restrict what follows custom ::-webkit-* pseudo elements in UA
+ // sheets. We currently use selectors in mediaControls.css like this:
+ //
+ // video::-webkit-media-text-track-region-container.scrolling
if (parser_mode == kUASheetMode &&
simple_selector.GetPseudoType() ==
CSSSelector::kPseudoWebKitCustomElement)
@@ -405,15 +421,16 @@ bool CSSSelectorParser::ConsumeName(CSSParserTokenRange& range,
if (range.Peek().GetType() != kDelimiterToken ||
range.Peek().Delimiter() != '|')
return true;
- range.Consume();
namespace_prefix =
name == CSSSelector::UniversalSelectorAtom() ? g_star_atom : name;
- const CSSParserToken& name_token = range.Consume();
- if (name_token.GetType() == kIdentToken) {
- name = name_token.Value().ToAtomicString();
- } else if (name_token.GetType() == kDelimiterToken &&
- name_token.Delimiter() == '*') {
+ if (range.Peek(1).GetType() == kIdentToken) {
+ range.Consume();
+ name = range.Consume().Value().ToAtomicString();
+ } else if (range.Peek(1).GetType() == kDelimiterToken &&
+ range.Peek(1).Delimiter() == '*') {
+ range.Consume();
+ range.Consume();
name = CSSSelector::UniversalSelectorAtom();
} else {
name = g_null_atom;
@@ -615,14 +632,24 @@ std::unique_ptr<CSSParserSelector> CSSSelectorParser::ConsumePseudo(
selector->AdoptSelectorVector(selector_vector);
return selector;
}
- case CSSSelector::kPseudoState:
- case CSSSelector::kPseudoPart: {
+ case CSSSelector::kPseudoState: {
const CSSParserToken& ident = block.ConsumeIncludingWhitespace();
if (ident.GetType() != kIdentToken || !block.AtEnd())
return nullptr;
selector->SetArgument(ident.Value().ToAtomicString());
return selector;
}
+ case CSSSelector::kPseudoPart: {
+ Vector<AtomicString> parts;
+ do {
+ const CSSParserToken& ident = block.ConsumeIncludingWhitespace();
+ if (ident.GetType() != kIdentToken)
+ return nullptr;
+ parts.push_back(ident.Value().ToAtomicString());
+ } while (!block.AtEnd());
+ selector->SetPartNames(std::make_unique<Vector<AtomicString>>(parts));
+ return selector;
+ }
case CSSSelector::kPseudoSlotted: {
DisallowPseudoElementsScope scope(this);
@@ -1187,4 +1214,17 @@ void CSSSelectorParser::RecordUsageAndDeprecations(
}
}
+bool CSSSelectorParser::ContainsUnknownWebkitPseudoElements(
+ const CSSSelector& complex_selector) {
+ for (const CSSSelector* current = &complex_selector; current;
+ current = current->TagHistory()) {
+ if (current->GetPseudoType() != CSSSelector::kPseudoWebKitCustomElement)
+ continue;
+ WebFeature feature = FeatureForWebKitCustomPseudoElement(current->Value());
+ if (feature == WebFeature::kCSSSelectorWebkitUnknownPseudo)
+ return true;
+ }
+ return false;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_selector_parser.h b/chromium/third_party/blink/renderer/core/css/parser/css_selector_parser.h
index b1a8442a5ab..efddcb43400 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_selector_parser.h
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_selector_parser.h
@@ -35,6 +35,9 @@ class CORE_EXPORT CSSSelectorParser {
static bool ConsumeANPlusB(CSSParserTokenRange&, std::pair<int, int>&);
+ static bool SupportsComplexSelector(CSSParserTokenRange,
+ const CSSParserContext*);
+
private:
CSSSelectorParser(const CSSParserContext*, StyleSheetContents*);
@@ -80,9 +83,11 @@ class CORE_EXPORT CSSSelectorParser {
SplitCompoundAtImplicitShadowCrossingCombinator(
std::unique_ptr<CSSParserSelector> compound_selector);
void RecordUsageAndDeprecations(const CSSSelectorList&);
+ static bool ContainsUnknownWebkitPseudoElements(
+ const CSSSelector& complex_selector);
- Member<const CSSParserContext> context_;
- Member<const StyleSheetContents> style_sheet_;
+ const CSSParserContext* context_;
+ const StyleSheetContents* style_sheet_;
bool failed_parsing_ = false;
bool disallow_pseudo_elements_ = false;
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_selector_parser_test.cc b/chromium/third_party/blink/renderer/core/css/parser/css_selector_parser_test.cc
index 19c40798228..ae5410b08a0 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_selector_parser_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_selector_parser_test.cc
@@ -287,6 +287,23 @@ TEST(CSSSelectorParserTest, UnresolvedNamespacePrefix) {
}
}
+TEST(CSSSelectorParserTest, UnexpectedPipe) {
+ const char* test_cases[] = {"div | .c", "| div", " | div"};
+
+ auto* context = MakeGarbageCollected<CSSParserContext>(
+ kHTMLStandardMode, SecureContextMode::kInsecureContext);
+ auto* sheet = MakeGarbageCollected<StyleSheetContents>(context);
+
+ for (auto* test_case : test_cases) {
+ CSSTokenizer tokenizer(test_case);
+ const auto tokens = tokenizer.TokenizeToEOF();
+ CSSParserTokenRange range(tokens);
+ CSSSelectorList list =
+ CSSSelectorParser::ParseSelector(range, context, sheet);
+ EXPECT_FALSE(list.IsValid());
+ }
+}
+
TEST(CSSSelectorParserTest, SerializedUniversal) {
const char* test_cases[][2] = {
{"*::-webkit-volume-slider", "::-webkit-volume-slider"},
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_supports_parser.cc b/chromium/third_party/blink/renderer/core/css/parser/css_supports_parser.cc
index 43f19506156..7b2a4478c64 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_supports_parser.cc
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_supports_parser.cc
@@ -5,105 +5,209 @@
#include "third_party/blink/renderer/core/css/parser/css_supports_parser.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_impl.h"
+#include "third_party/blink/renderer/core/css/parser/css_selector_parser.h"
+#include "third_party/blink/renderer/core/css_value_keywords.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
-CSSSupportsParser::SupportsResult CSSSupportsParser::SupportsCondition(
+namespace {
+
+// The result kUnknown must be converted to 'false' if passed to a context
+// which requires a boolean value.
+// TODO(crbug.com/1052274): This is supposed to happen at the top-level,
+// but currently happens on ConsumeGeneralEnclosed's result.
+CSSSupportsParser::Result EvalUnknown(CSSSupportsParser::Result result) {
+ return result == CSSSupportsParser::Result::kUnknown
+ ? CSSSupportsParser::Result::kUnsupported
+ : result;
+}
+
+// https://drafts.csswg.org/css-syntax/#typedef-any-value
+bool IsNextTokenAllowedForAnyValue(CSSParserTokenRange& range) {
+ switch (range.Peek().GetType()) {
+ case kBadStringToken:
+ case kEOFToken:
+ case kBadUrlToken:
+ return false;
+ case kRightParenthesisToken:
+ case kRightBracketToken:
+ case kRightBraceToken:
+ return range.Peek().GetBlockType() == CSSParserToken::kBlockEnd;
+ default:
+ return true;
+ }
+}
+
+// https://drafts.csswg.org/css-syntax/#typedef-any-value
+bool ConsumeAnyValue(CSSParserTokenRange& range) {
+ DCHECK(!range.AtEnd());
+ while (IsNextTokenAllowedForAnyValue(range))
+ range.Consume();
+ return range.AtEnd();
+}
+
+} // namespace
+
+CSSSupportsParser::Result CSSSupportsParser::SupportsCondition(
CSSParserTokenRange range,
CSSParserImpl& parser,
- SupportsParsingMode parsing_mode) {
+ Mode mode) {
range.ConsumeWhitespace();
+ CSSParserTokenRange stored_range = range;
CSSSupportsParser supports_parser(parser);
- SupportsResult result = supports_parser.ConsumeCondition(range);
- if (parsing_mode != kForWindowCSS || result != kInvalid)
+ Result result = supports_parser.ConsumeSupportsCondition(range);
+ if (mode != Mode::kForWindowCSS || result != Result::kParseFailure)
return result;
+
// window.CSS.supports requires to parse as-if it was wrapped in parenthesis.
- // The only wrapped production that wouldn't have parsed above is the
- // declaration condition production.
- return supports_parser.ConsumeDeclarationCondition(range);
+ // The only wrapped production that wouldn't have parsed above is
+ // <declaration>.
+ if (stored_range.Peek().GetType() != kIdentToken)
+ return Result::kParseFailure;
+ if (parser.SupportsDeclaration(stored_range))
+ return Result::kSupported;
+ return Result::kUnsupported;
+}
+
+bool CSSSupportsParser::AtIdent(CSSParserTokenRange& range, const char* ident) {
+ return range.Peek().GetType() == kIdentToken &&
+ EqualIgnoringASCIICase(range.Peek().Value(), ident);
+}
+
+bool CSSSupportsParser::ConsumeIfIdent(CSSParserTokenRange& range,
+ const char* ident) {
+ if (!AtIdent(range, ident))
+ return false;
+ range.ConsumeIncludingWhitespace();
+ return true;
+}
+
+// <supports-condition> = not <supports-in-parens>
+// | <supports-in-parens> [ and <supports-in-parens> ]*
+// | <supports-in-parens> [ or <supports-in-parens> ]*
+CSSSupportsParser::Result CSSSupportsParser::ConsumeSupportsCondition(
+ CSSParserTokenRange& range) {
+ // not <supports-in-parens>
+ if (ConsumeIfIdent(range, "not")) {
+ Result result = !ConsumeSupportsInParens(range);
+ return range.AtEnd() ? result : Result::kParseFailure;
+ }
+
+ // <supports-in-parens> [ and <supports-in-parens> ]*
+ // | <supports-in-parens> [ or <supports-in-parens> ]*
+ Result result = ConsumeSupportsInParens(range);
+
+ if (AtIdent(range, "and")) {
+ while (ConsumeIfIdent(range, "and"))
+ result = result & ConsumeSupportsInParens(range);
+ } else if (AtIdent(range, "or")) {
+ while (ConsumeIfIdent(range, "or"))
+ result = result | ConsumeSupportsInParens(range);
+ }
+
+ return range.AtEnd() ? result : Result::kParseFailure;
}
-enum ClauseType { kUnresolved, kConjunction, kDisjunction };
-
-CSSSupportsParser::SupportsResult CSSSupportsParser::ConsumeCondition(
- CSSParserTokenRange range) {
- if (range.Peek().GetType() == kIdentToken)
- return ConsumeNegation(range);
-
- bool result;
- ClauseType clause_type = kUnresolved;
-
- while (true) {
- SupportsResult next_result = ConsumeConditionInParenthesis(range);
- if (next_result == kInvalid)
- return kInvalid;
- bool next_supported = next_result;
- if (clause_type == kUnresolved)
- result = next_supported;
- else if (clause_type == kConjunction)
- result &= next_supported;
- else
- result |= next_supported;
-
- if (range.AtEnd())
- break;
- if (range.ConsumeIncludingWhitespace().GetType() != kWhitespaceToken)
- return kInvalid;
- if (range.AtEnd())
- break;
-
- const CSSParserToken& token = range.Consume();
- if (token.GetType() != kIdentToken)
- return kInvalid;
- if (clause_type == kUnresolved)
- clause_type = token.Value().length() == 3 ? kConjunction : kDisjunction;
- if ((clause_type == kConjunction &&
- !EqualIgnoringASCIICase(token.Value(), "and")) ||
- (clause_type == kDisjunction &&
- !EqualIgnoringASCIICase(token.Value(), "or")))
- return kInvalid;
-
- if (range.ConsumeIncludingWhitespace().GetType() != kWhitespaceToken)
- return kInvalid;
+// <supports-in-parens> = ( <supports-condition> )
+// | <supports-feature>
+// | <general-enclosed>
+CSSSupportsParser::Result CSSSupportsParser::ConsumeSupportsInParens(
+ CSSParserTokenRange& range) {
+ const CSSParserTokenRange stored_range = range;
+
+ // ( <supports-condition> )
+ if (range.Peek().GetType() == kLeftParenthesisToken) {
+ auto block = range.ConsumeBlock();
+ block.ConsumeWhitespace();
+ range.ConsumeWhitespace();
+ Result result = ConsumeSupportsCondition(block);
+ if (result != Result::kParseFailure)
+ return result;
+ // Parsing failed, so try parsing again as <supports-feature>.
+ range = stored_range;
}
- return result ? kSupported : kUnsupported;
+
+ // <supports-feature>
+ Result result = ConsumeSupportsFeature(range);
+ if (result != Result::kParseFailure)
+ return result;
+ // Parsing failed, try again as <general-enclosed>
+ range = stored_range;
+
+ // <general-enclosed>
+ //
+ // TODO(crbug.com/1052274): Support kUnknown beyond this point.
+ //
+ // The result kUnknown is supposed to be evaluated at the top level, but
+ // we have already shipped the behavior of evaluating it here, and Firefox
+ // does the same thing.
+ return EvalUnknown(ConsumeGeneralEnclosed(range));
}
-CSSSupportsParser::SupportsResult CSSSupportsParser::ConsumeNegation(
- CSSParserTokenRange range) {
- DCHECK_EQ(range.Peek().GetType(), kIdentToken);
- if (!EqualIgnoringASCIICase(range.Consume().Value(), "not"))
- return kInvalid;
- if (range.ConsumeIncludingWhitespace().GetType() != kWhitespaceToken)
- return kInvalid;
- SupportsResult result = ConsumeConditionInParenthesis(range);
+// <supports-feature> = <supports-selector-fn> | <supports-decl>
+CSSSupportsParser::Result CSSSupportsParser::ConsumeSupportsFeature(
+ CSSParserTokenRange& range) {
+ const CSSParserTokenRange stored_range = range;
+
+ // <supports-selector-fn>
+ Result result = ConsumeSupportsSelectorFn(range);
+ if (result != Result::kParseFailure)
+ return result;
+ range = stored_range;
+
+ // <supports-decl>
+ return ConsumeSupportsDecl(range);
+}
+
+// <supports-selector-fn> = selector( <complex-selector> )
+CSSSupportsParser::Result CSSSupportsParser::ConsumeSupportsSelectorFn(
+ CSSParserTokenRange& range) {
+ if (!RuntimeEnabledFeatures::CSSSupportsSelectorEnabled())
+ return Result::kParseFailure;
+ if (range.Peek().GetType() != kFunctionToken)
+ return Result::kParseFailure;
+ if (range.Peek().FunctionId() != CSSValueID::kSelector)
+ return Result::kParseFailure;
+ auto block = range.ConsumeBlock();
+ block.ConsumeWhitespace();
range.ConsumeWhitespace();
- if (!range.AtEnd() || result == kInvalid)
- return kInvalid;
- return result ? kUnsupported : kSupported;
+ if (CSSSelectorParser::SupportsComplexSelector(block, parser_.GetContext()))
+ return Result::kSupported;
+ return Result::kUnsupported;
}
-CSSSupportsParser::SupportsResult
-CSSSupportsParser::ConsumeConditionInParenthesis(CSSParserTokenRange& range) {
- if (range.Peek().GetType() == kFunctionToken) {
- range.ConsumeComponentValue();
- return kUnsupported;
- }
+// <supports-decl> = ( <declaration> )
+CSSSupportsParser::Result CSSSupportsParser::ConsumeSupportsDecl(
+ CSSParserTokenRange& range) {
if (range.Peek().GetType() != kLeftParenthesisToken)
- return kInvalid;
- CSSParserTokenRange inner_range = range.ConsumeBlock();
- inner_range.ConsumeWhitespace();
- SupportsResult result = ConsumeCondition(inner_range);
- if (result != kInvalid)
- return result;
- return ConsumeDeclarationCondition(inner_range);
+ return Result::kParseFailure;
+ auto block = range.ConsumeBlock();
+ block.ConsumeWhitespace();
+ range.ConsumeWhitespace();
+ if (block.Peek().GetType() != kIdentToken)
+ return Result::kParseFailure;
+ if (parser_.SupportsDeclaration(block))
+ return Result::kSupported;
+ return Result::kUnsupported;
}
-CSSSupportsParser::SupportsResult
-CSSSupportsParser::ConsumeDeclarationCondition(CSSParserTokenRange& range) {
- if (range.Peek().GetType() != kIdentToken)
- return kUnsupported;
- return parser_.SupportsDeclaration(range) ? kSupported : kUnsupported;
+// <general-enclosed> = [ <function-token> <any-value> ) ]
+// | ( <ident> <any-value> )
+CSSSupportsParser::Result CSSSupportsParser::ConsumeGeneralEnclosed(
+ CSSParserTokenRange& range) {
+ if (range.Peek().GetType() == kFunctionToken ||
+ range.Peek().GetType() == kLeftParenthesisToken) {
+ auto block = range.ConsumeBlock();
+ // Note that <any-value> matches a sequence of one or more tokens, hence the
+ // block-range can't be empty.
+ // https://drafts.csswg.org/css-syntax-3/#typedef-any-value
+ if (block.AtEnd() || !ConsumeAnyValue(block))
+ return Result::kParseFailure;
+ range.ConsumeWhitespace();
+ return Result::kUnknown;
+ }
+ return Result::kParseFailure;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_supports_parser.h b/chromium/third_party/blink/renderer/core/css/parser/css_supports_parser.h
index 698c8c558ac..9f447f5a8f5 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/css_supports_parser.h
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_supports_parser.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PARSER_CSS_SUPPORTS_PARSER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PARSER_CSS_SUPPORTS_PARSER_H_
+#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
@@ -12,29 +13,116 @@ namespace blink {
class CSSParserImpl;
class CSSParserTokenRange;
-class CSSSupportsParser {
+class CORE_EXPORT CSSSupportsParser {
STACK_ALLOCATED();
public:
- enum SupportsResult { kUnsupported = false, kSupported = true, kInvalid };
- enum SupportsParsingMode { kForAtRule, kForWindowCSS };
+ enum class Mode { kForAtRule, kForWindowCSS };
- static SupportsResult SupportsCondition(CSSParserTokenRange,
- CSSParserImpl&,
- SupportsParsingMode);
+ enum class Result {
+ // kUnsupported/kSupported means that we parsed the @supports
+ // successfully, and conclusively determined that we either support or
+ // don't support the feature.
+ kUnsupported,
+ kSupported,
+ // kUnknown is a special value used for productions that only match
+ // <general-enclosed> [1]. See note regarding Kleene 3-valued logic [2]
+ // for explanation of how this is different from kUnsupported.
+ //
+ // [1] https://drafts.csswg.org/css-conditional-3/#at-supports
+ // [2] https://drafts.csswg.org/mediaqueries-4/#evaluating
+ kUnknown,
+ // This is used to signal parse failure in the @supports syntax itself.
+ // This means that for a production like:
+ //
+ // <supports-in-parens> = ( <supports-condition> )
+ // | <supports-feature>
+ // | <general-enclosed>
+ //
+ // If ConsumeSupportsCondition returns a kParseFailure, we'll proceed to
+ // trying the ConsumeGeneralEnclosed branch. Had however
+ // ConsumeSupportsCondition returned kUnsupported, we would consider this a
+ // conclusive answer, and would have returned kUnsupported without trying
+ // any further parsing branches.
+ kParseFailure
+ };
+
+ static Result SupportsCondition(CSSParserTokenRange, CSSParserImpl&, Mode);
private:
+ friend class CSSSupportsParserTest;
+
CSSSupportsParser(CSSParserImpl& parser) : parser_(parser) {}
- SupportsResult ConsumeCondition(CSSParserTokenRange);
- SupportsResult ConsumeNegation(CSSParserTokenRange);
- SupportsResult ConsumeDeclarationCondition(CSSParserTokenRange&);
+ // True if the current token is a kIdentToken with the specified value
+ // (case-insensitive).
+ bool AtIdent(CSSParserTokenRange&, const char*);
+
+ // If the current token is a kIdentToken with the specified value (case
+ // insensitive), consumes the token and returns true.
+ bool ConsumeIfIdent(CSSParserTokenRange&, const char*);
+
+ // Parsing functions follow, as defined by:
+ // https://drafts.csswg.org/css-conditional-3/#typedef-supports-condition
+
+ // <supports-condition> = not <supports-in-parens>
+ // | <supports-in-parens> [ and <supports-in-parens> ]*
+ // | <supports-in-parens> [ or <supports-in-parens> ]*
+ Result ConsumeSupportsCondition(CSSParserTokenRange&);
+
+ // <supports-in-parens> = ( <supports-condition> )
+ // | <supports-feature>
+ // | <general-enclosed>
+ Result ConsumeSupportsInParens(CSSParserTokenRange&);
- SupportsResult ConsumeConditionInParenthesis(CSSParserTokenRange&);
+ // <supports-feature> = <supports-selector-fn> | <supports-decl>
+ Result ConsumeSupportsFeature(CSSParserTokenRange&);
+
+ // <supports-selector-fn> = selector( <complex-selector> )
+ Result ConsumeSupportsSelectorFn(CSSParserTokenRange&);
+
+ // <supports-decl> = ( <declaration> )
+ Result ConsumeSupportsDecl(CSSParserTokenRange&);
+
+ // <general-enclosed>
+ Result ConsumeGeneralEnclosed(CSSParserTokenRange&);
CSSParserImpl& parser_;
};
+inline CSSSupportsParser::Result operator!(CSSSupportsParser::Result result) {
+ using Result = CSSSupportsParser::Result;
+ if (result == Result::kUnsupported)
+ return Result::kSupported;
+ if (result == Result::kSupported)
+ return Result::kUnsupported;
+ return result;
+}
+
+inline CSSSupportsParser::Result operator&(CSSSupportsParser::Result a,
+ CSSSupportsParser::Result b) {
+ using Result = CSSSupportsParser::Result;
+ if (a == Result::kParseFailure || b == Result::kParseFailure)
+ return Result::kParseFailure;
+ if (a == Result::kUnknown && b == Result::kUnknown)
+ return Result::kUnknown;
+ if (a != Result::kSupported || b != Result::kSupported)
+ return Result::kUnsupported;
+ return Result::kSupported;
+}
+
+inline CSSSupportsParser::Result operator|(CSSSupportsParser::Result a,
+ CSSSupportsParser::Result b) {
+ using Result = CSSSupportsParser::Result;
+ if (a == Result::kParseFailure || b == Result::kParseFailure)
+ return Result::kParseFailure;
+ if (a == Result::kSupported || b == Result::kSupported)
+ return Result::kSupported;
+ if (a == Result::kUnknown || b == Result::kUnknown)
+ return Result::kUnknown;
+ return Result::kUnsupported;
+}
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PARSER_CSS_SUPPORTS_PARSER_H_
diff --git a/chromium/third_party/blink/renderer/core/css/parser/css_supports_parser_test.cc b/chromium/third_party/blink/renderer/core/css/parser/css_supports_parser_test.cc
new file mode 100644
index 00000000000..04f7b706b78
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/parser/css_supports_parser_test.cc
@@ -0,0 +1,390 @@
+// 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_supports_parser.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/css/parser/css_parser_context.h"
+#include "third_party/blink/renderer/core/css/parser/css_parser_impl.h"
+#include "third_party/blink/renderer/core/css/parser/css_tokenizer.h"
+#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
+
+namespace blink {
+
+using Result = CSSSupportsParser::Result;
+
+class CSSSupportsParserTest : public testing::Test {
+ public:
+ CSSParserContext* MakeContext() {
+ return MakeGarbageCollected<CSSParserContext>(
+ kHTMLStandardMode, SecureContextMode::kInsecureContext);
+ }
+
+ Vector<CSSParserToken, 32> Tokenize(const String& string) {
+ return CSSTokenizer(string).TokenizeToEOF();
+ }
+
+ Result SupportsCondition(String string, CSSSupportsParser::Mode mode) {
+ CSSParserImpl impl(MakeContext());
+ auto tokens = Tokenize(string);
+ return CSSSupportsParser::SupportsCondition(tokens, impl, mode);
+ }
+
+ Result AtSupports(String string) {
+ return SupportsCondition(string, CSSSupportsParser::Mode::kForAtRule);
+ }
+
+ Result WindowCSSSupports(String string) {
+ return SupportsCondition(string, CSSSupportsParser::Mode::kForWindowCSS);
+ }
+
+ Result ConsumeSupportsCondition(String string) {
+ CSSParserImpl impl(MakeContext());
+ CSSSupportsParser parser(impl);
+ auto tokens = Tokenize(string);
+ CSSParserTokenRange range = tokens;
+ return parser.ConsumeSupportsCondition(range);
+ }
+
+ Result ConsumeSupportsInParens(String string) {
+ CSSParserImpl impl(MakeContext());
+ CSSSupportsParser parser(impl);
+ auto tokens = Tokenize(string);
+ CSSParserTokenRange range = tokens;
+ return parser.ConsumeSupportsInParens(range);
+ }
+
+ Result ConsumeSupportsFeature(String string) {
+ CSSParserImpl impl(MakeContext());
+ CSSSupportsParser parser(impl);
+ auto tokens = Tokenize(string);
+ CSSParserTokenRange range = tokens;
+ return parser.ConsumeSupportsFeature(range);
+ }
+
+ Result ConsumeSupportsSelectorFn(String string) {
+ CSSParserImpl impl(MakeContext());
+ CSSSupportsParser parser(impl);
+ auto tokens = Tokenize(string);
+ CSSParserTokenRange range = tokens;
+ return parser.ConsumeSupportsSelectorFn(range);
+ }
+
+ Result ConsumeSupportsDecl(String string) {
+ CSSParserImpl impl(MakeContext());
+ CSSSupportsParser parser(impl);
+ auto tokens = Tokenize(string);
+ CSSParserTokenRange range = tokens;
+ return parser.ConsumeSupportsDecl(range);
+ }
+
+ Result ConsumeGeneralEnclosed(String string) {
+ CSSParserImpl impl(MakeContext());
+ CSSSupportsParser parser(impl);
+ auto tokens = Tokenize(string);
+ CSSParserTokenRange range = tokens;
+ return parser.ConsumeGeneralEnclosed(range);
+ }
+};
+
+TEST_F(CSSSupportsParserTest, ResultNot) {
+ EXPECT_EQ(Result::kSupported, !Result::kUnsupported);
+ EXPECT_EQ(Result::kUnsupported, !Result::kSupported);
+ EXPECT_EQ(Result::kParseFailure, !Result::kParseFailure);
+ EXPECT_EQ(Result::kUnknown, !Result::kUnknown);
+}
+
+TEST_F(CSSSupportsParserTest, ResultAnd) {
+ EXPECT_EQ(Result::kSupported, Result::kSupported & Result::kSupported);
+ EXPECT_EQ(Result::kUnsupported, Result::kUnsupported & Result::kSupported);
+ EXPECT_EQ(Result::kUnsupported, Result::kSupported & Result::kUnsupported);
+ EXPECT_EQ(Result::kUnsupported, Result::kUnsupported & Result::kUnsupported);
+
+ EXPECT_EQ(Result::kParseFailure, Result::kSupported & Result::kParseFailure);
+ EXPECT_EQ(Result::kParseFailure, Result::kParseFailure & Result::kSupported);
+
+ EXPECT_EQ(Result::kUnknown, Result::kUnknown & Result::kUnknown);
+ EXPECT_EQ(Result::kUnsupported, Result::kSupported & Result::kUnknown);
+ EXPECT_EQ(Result::kUnsupported, Result::kUnknown & Result::kSupported);
+}
+
+TEST_F(CSSSupportsParserTest, ResultOr) {
+ EXPECT_EQ(Result::kSupported, Result::kSupported | Result::kSupported);
+ EXPECT_EQ(Result::kSupported, Result::kUnsupported | Result::kSupported);
+ EXPECT_EQ(Result::kSupported, Result::kSupported | Result::kUnsupported);
+ EXPECT_EQ(Result::kUnsupported, Result::kUnsupported | Result::kUnsupported);
+
+ EXPECT_EQ(Result::kParseFailure, Result::kSupported | Result::kParseFailure);
+ EXPECT_EQ(Result::kParseFailure, Result::kParseFailure | Result::kSupported);
+
+ EXPECT_EQ(Result::kUnknown, Result::kUnknown | Result::kUnknown);
+ EXPECT_EQ(Result::kSupported, Result::kSupported | Result::kUnknown);
+ EXPECT_EQ(Result::kSupported, Result::kUnknown | Result::kSupported);
+}
+
+TEST_F(CSSSupportsParserTest, ConsumeSupportsCondition) {
+ // not <supports-in-parens>
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsCondition("not (asdf:red)"));
+ EXPECT_EQ(Result::kUnsupported,
+ ConsumeSupportsCondition("(not (color:red))"));
+ EXPECT_EQ(Result::kParseFailure, ConsumeSupportsCondition("nay (color:red)"));
+
+ // <supports-in-parens> [ and <supports-in-parens> ]*
+ EXPECT_EQ(Result::kSupported,
+ ConsumeSupportsCondition("(color:red) and (color:green)"));
+ EXPECT_EQ(Result::kUnsupported,
+ ConsumeSupportsCondition("(color:red) and (asdf:green)"));
+ EXPECT_EQ(Result::kUnsupported,
+ ConsumeSupportsCondition("(asdf:red) and (asdf:green)"));
+ EXPECT_EQ(Result::kUnsupported,
+ ConsumeSupportsCondition(
+ "(color:red) and (color:green) and (asdf:color)"));
+ EXPECT_EQ(Result::kSupported,
+ ConsumeSupportsCondition(
+ "(color:red) and (color:green) and (not (asdf:color))"));
+
+ // <supports-in-parens> [ or <supports-in-parens> ]*
+ EXPECT_EQ(Result::kSupported,
+ ConsumeSupportsCondition("(color:red) or (color:asdf)"));
+ EXPECT_EQ(Result::kSupported,
+ ConsumeSupportsCondition("(color:asdf) or (color:green)"));
+ EXPECT_EQ(Result::kUnsupported,
+ ConsumeSupportsCondition("(asdf:red) or (asdf:green)"));
+ EXPECT_EQ(
+ Result::kSupported,
+ ConsumeSupportsCondition("(color:red) or (color:green) or (asdf:color)"));
+ EXPECT_EQ(Result::kUnsupported,
+ ConsumeSupportsCondition(
+ "(color:asdf1) or (color:asdf2) or (asdf:asdf2)"));
+ EXPECT_EQ(Result::kSupported,
+ ConsumeSupportsCondition(
+ "(color:asdf) or (color:ghjk) or (not (asdf:color))"));
+
+ // <supports-feature>
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsCondition("(color:red)"));
+ EXPECT_EQ(Result::kUnsupported, ConsumeSupportsCondition("(color:asdf)"));
+
+ // <general-enclosed>
+ EXPECT_EQ(Result::kUnsupported, ConsumeSupportsCondition("asdf(1)"));
+}
+
+TEST_F(CSSSupportsParserTest, ConsumeSupportsInParens) {
+ // ( <supports-condition> )
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsInParens("(not (asdf:red))"));
+ EXPECT_EQ(Result::kUnsupported, ConsumeSupportsInParens("(not (color:red))"));
+
+ // <supports-feature>
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsInParens("(color:red)"));
+ EXPECT_EQ(Result::kUnsupported, ConsumeSupportsInParens("(color:asdf)"));
+
+ // <general-enclosed>
+ EXPECT_EQ(Result::kUnsupported, ConsumeSupportsInParens("asdf(1)"));
+
+ EXPECT_EQ(Result::kSupported,
+ ConsumeSupportsInParens("(color:red)and (color:green)"));
+ EXPECT_EQ(Result::kSupported,
+ ConsumeSupportsInParens("(color:red)or (color:green)"));
+ {
+ ScopedCSSSupportsSelectorForTest css_supports_selector(true);
+ EXPECT_EQ(Result::kSupported,
+ ConsumeSupportsInParens("selector(div)or (color:green)"));
+ EXPECT_EQ(Result::kSupported,
+ ConsumeSupportsInParens("selector(div)and (color:green)"));
+ }
+}
+
+TEST_F(CSSSupportsParserTest, ConsumeSupportsSelectorFn) {
+ ScopedCSSSupportsSelectorForTest css_supports_selector(true);
+
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsSelectorFn("selector(*)"));
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsSelectorFn("selector(*:hover)"));
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsSelectorFn("selector(:hover)"));
+ EXPECT_EQ(Result::kSupported,
+ ConsumeSupportsSelectorFn("selector(::before)"));
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsSelectorFn("selector(div)"));
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsSelectorFn("selector(div"));
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsSelectorFn("selector(.a)"));
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsSelectorFn("selector(#a)"));
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsSelectorFn("selector(div.a)"));
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsSelectorFn("selector(div a)"));
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsSelectorFn("selector(a > div)"));
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsSelectorFn("selector(a ~ div)"));
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsSelectorFn("selector(a + div)"));
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsSelectorFn("selector(*|a)"));
+ EXPECT_EQ(Result::kSupported,
+ ConsumeSupportsSelectorFn("selector(a + div#test)"));
+ EXPECT_EQ(Result::kSupported,
+ ConsumeSupportsSelectorFn("selector(a + div#test::before)"));
+ EXPECT_EQ(Result::kSupported,
+ ConsumeSupportsSelectorFn("selector(a.cls:hover)"));
+ EXPECT_EQ(Result::kSupported,
+ ConsumeSupportsSelectorFn("selector(a.cls::before)"));
+ EXPECT_EQ(Result::kSupported,
+ ConsumeSupportsSelectorFn("selector(div::-webkit-clear-button)"));
+
+ EXPECT_EQ(Result::kUnsupported,
+ ConsumeSupportsSelectorFn("selector(div::-webkit-asdf)"));
+ EXPECT_EQ(Result::kUnsupported,
+ ConsumeSupportsSelectorFn("selector(a + div::-webkit-asdf)"));
+ EXPECT_EQ(Result::kUnsupported,
+ ConsumeSupportsSelectorFn("selector(div.cls::-webkit-asdf)"));
+
+ EXPECT_EQ(Result::kUnsupported,
+ ConsumeSupportsSelectorFn("selector(div.~cls)"));
+ EXPECT_EQ(Result::kUnsupported,
+ ConsumeSupportsSelectorFn("selector(div. ~cls)"));
+ EXPECT_EQ(Result::kUnsupported,
+ ConsumeSupportsSelectorFn("selector(div .~ cls)"));
+ EXPECT_EQ(Result::kUnsupported,
+ ConsumeSupportsSelectorFn("selector(div$ cls)"));
+ EXPECT_EQ(Result::kUnsupported,
+ ConsumeSupportsSelectorFn("selector(div $cls)"));
+ EXPECT_EQ(Result::kUnsupported,
+ ConsumeSupportsSelectorFn("selector(div $ cls)"));
+ EXPECT_EQ(Result::kUnsupported,
+ ConsumeSupportsSelectorFn("selector(unknown|a)"));
+ EXPECT_EQ(Result::kUnsupported,
+ ConsumeSupportsSelectorFn("selector(a::asdf)"));
+ EXPECT_EQ(Result::kUnsupported,
+ ConsumeSupportsSelectorFn("selector(a:asdf)"));
+ EXPECT_EQ(Result::kUnsupported,
+ ConsumeSupportsSelectorFn("selector(a, body)"));
+ EXPECT_EQ(Result::kUnsupported,
+ ConsumeSupportsSelectorFn("selector(*:asdf)"));
+ EXPECT_EQ(Result::kUnsupported,
+ ConsumeSupportsSelectorFn("selector(*::asdf)"));
+ EXPECT_EQ(Result::kUnsupported, ConsumeSupportsSelectorFn("selector(:asdf)"));
+ EXPECT_EQ(Result::kUnsupported,
+ ConsumeSupportsSelectorFn("selector(::asdf)"));
+
+ EXPECT_EQ(Result::kParseFailure, ConsumeSupportsSelectorFn("#test"));
+ EXPECT_EQ(Result::kParseFailure, ConsumeSupportsSelectorFn("test"));
+ EXPECT_EQ(Result::kParseFailure, ConsumeSupportsSelectorFn("test(1)"));
+}
+
+TEST_F(CSSSupportsParserTest, ConsumeSupportsSelectorFnWithFeatureDisabled) {
+ ScopedCSSSupportsSelectorForTest css_supports_selector(false);
+
+ EXPECT_EQ(Result::kParseFailure, ConsumeSupportsSelectorFn("selector(*)"));
+ EXPECT_EQ(Result::kParseFailure, ConsumeSupportsSelectorFn("selector(div)"));
+ EXPECT_EQ(Result::kParseFailure, ConsumeSupportsSelectorFn("selector(.a)"));
+}
+
+TEST_F(CSSSupportsParserTest, ConsumeSupportsDecl) {
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsDecl("(color:red)"));
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsDecl("(color: red)"));
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsDecl("(color : red)"));
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsDecl("(color :red)"));
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsDecl("( color:red )"));
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsDecl("(--x:red)"));
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsDecl("(--x:\tred) "));
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsDecl("(--x:\tred) \t "));
+ EXPECT_EQ(Result::kSupported,
+ ConsumeSupportsDecl("(color:green !important)"));
+ // For some reason EOF is allowed in place of ')' (everywhere in Blink).
+ // Seems to be the case in Firefox too.
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsDecl("(color:red"));
+
+ EXPECT_EQ(Result::kUnsupported, ConsumeSupportsDecl("(color:asdf)"));
+ EXPECT_EQ(Result::kUnsupported, ConsumeSupportsDecl("(asdf)"));
+ EXPECT_EQ(Result::kUnsupported, ConsumeSupportsDecl("(color)"));
+ EXPECT_EQ(Result::kUnsupported, ConsumeSupportsDecl("(color:)"));
+
+ EXPECT_EQ(Result::kParseFailure, ConsumeSupportsDecl(""));
+ EXPECT_EQ(Result::kParseFailure, ConsumeSupportsDecl("("));
+ EXPECT_EQ(Result::kParseFailure, ConsumeSupportsDecl(")"));
+ EXPECT_EQ(Result::kParseFailure, ConsumeSupportsDecl("()"));
+ EXPECT_EQ(Result::kParseFailure, ConsumeSupportsDecl("color:red)"));
+ EXPECT_EQ(Result::kParseFailure, ConsumeSupportsDecl("color:red"));
+}
+
+TEST_F(CSSSupportsParserTest, ConsumeSupportsFeature) {
+ EXPECT_EQ(Result::kSupported, ConsumeSupportsFeature("(color:red)"));
+
+ {
+ ScopedCSSSupportsSelectorForTest css_supports_selector(true);
+ EXPECT_EQ(Result::kParseFailure, ConsumeSupportsFeature("asdf(1)"));
+ }
+}
+
+TEST_F(CSSSupportsParserTest, ConsumeGeneralEnclosed) {
+ EXPECT_EQ(Result::kUnknown, ConsumeGeneralEnclosed("(asdf)"));
+ EXPECT_EQ(Result::kUnknown, ConsumeGeneralEnclosed("( asdf )"));
+ EXPECT_EQ(Result::kUnknown, ConsumeGeneralEnclosed("(3)"));
+ EXPECT_EQ(Result::kUnknown, ConsumeGeneralEnclosed("max(1, 2)"));
+ EXPECT_EQ(Result::kUnknown, ConsumeGeneralEnclosed("asdf(1, 2)"));
+ EXPECT_EQ(Result::kUnknown, ConsumeGeneralEnclosed("asdf(1, 2)\t"));
+
+ EXPECT_EQ(Result::kParseFailure, ConsumeGeneralEnclosed(""));
+ EXPECT_EQ(Result::kParseFailure, ConsumeGeneralEnclosed("("));
+ EXPECT_EQ(Result::kParseFailure, ConsumeGeneralEnclosed(")"));
+ EXPECT_EQ(Result::kParseFailure, ConsumeGeneralEnclosed("()"));
+ EXPECT_EQ(Result::kParseFailure, ConsumeGeneralEnclosed("color:red"));
+ EXPECT_EQ(Result::kParseFailure, ConsumeGeneralEnclosed("asdf"));
+
+ EXPECT_EQ(Result::kUnknown, ConsumeGeneralEnclosed("(asdf)"));
+ EXPECT_EQ(Result::kUnknown, ConsumeGeneralEnclosed("( asdf )"));
+ EXPECT_EQ(Result::kUnknown, ConsumeGeneralEnclosed("(3)"));
+ EXPECT_EQ(Result::kUnknown, ConsumeGeneralEnclosed("max(1, 2)"));
+ EXPECT_EQ(Result::kUnknown, ConsumeGeneralEnclosed("asdf(1, 2)"));
+ EXPECT_EQ(Result::kUnknown, ConsumeGeneralEnclosed("asdf(1, 2)\t"));
+
+ EXPECT_EQ(Result::kParseFailure, ConsumeGeneralEnclosed(""));
+ EXPECT_EQ(Result::kParseFailure, ConsumeGeneralEnclosed("("));
+ EXPECT_EQ(Result::kParseFailure, ConsumeGeneralEnclosed(")"));
+ EXPECT_EQ(Result::kParseFailure, ConsumeGeneralEnclosed("()"));
+ EXPECT_EQ(Result::kParseFailure, ConsumeGeneralEnclosed("color:red"));
+ EXPECT_EQ(Result::kParseFailure, ConsumeGeneralEnclosed("asdf"));
+
+ // Invalid <any-value>:
+ EXPECT_EQ(Result::kParseFailure, ConsumeGeneralEnclosed("(asdf})"));
+ EXPECT_EQ(Result::kParseFailure, ConsumeGeneralEnclosed("(asd]f)"));
+ EXPECT_EQ(Result::kParseFailure, ConsumeGeneralEnclosed("(\"as\ndf\")"));
+ EXPECT_EQ(Result::kParseFailure, ConsumeGeneralEnclosed("(url(as'df))"));
+
+ // Valid <any-value>
+ EXPECT_EQ(Result::kUnknown, ConsumeGeneralEnclosed("(as;df)"));
+ EXPECT_EQ(Result::kUnknown, ConsumeGeneralEnclosed("(as ! df)"));
+}
+
+TEST_F(CSSSupportsParserTest, AtSupportsCondition) {
+ EXPECT_EQ(Result::kSupported, AtSupports("(--x:red)"));
+ EXPECT_EQ(Result::kSupported, AtSupports("(--x:red) and (color:green)"));
+ EXPECT_EQ(Result::kSupported, AtSupports("(--x:red) or (color:asdf)"));
+ EXPECT_EQ(Result::kSupported,
+ AtSupports("not ((color:gjhk) or (color:asdf))"));
+ EXPECT_EQ(Result::kSupported,
+ AtSupports("(display: none) and ( (display: none) )"));
+
+ EXPECT_EQ(Result::kUnsupported, AtSupports("(color:ghjk) or (color:asdf)"));
+ EXPECT_EQ(Result::kUnsupported, AtSupports("(color:ghjk) or asdf(1)"));
+ EXPECT_EQ(Result::kParseFailure, AtSupports("color:red"));
+ EXPECT_EQ(
+ Result::kParseFailure,
+ AtSupports("(display: none) and (display: block) or (display: inline)"));
+ EXPECT_EQ(Result::kParseFailure,
+ AtSupports("not (display: deadbeef) and (display: block)"));
+ EXPECT_EQ(Result::kParseFailure,
+ AtSupports("(margin: 0) and (display: inline) or (width:1em)"));
+
+ // "and("/"or(" are function tokens, hence not allowed here.
+ EXPECT_EQ(Result::kParseFailure, AtSupports("(left:0) and(top:0)"));
+ EXPECT_EQ(Result::kParseFailure, AtSupports("(left:0) or(top:0)"));
+}
+
+TEST_F(CSSSupportsParserTest, WindowCSSSupportsCondition) {
+ EXPECT_EQ(Result::kSupported, WindowCSSSupports("(--x:red)"));
+ EXPECT_EQ(Result::kSupported, WindowCSSSupports("( --x:red )"));
+ EXPECT_EQ(Result::kSupported,
+ WindowCSSSupports("(--x:red) and (color:green)"));
+ EXPECT_EQ(Result::kSupported, WindowCSSSupports("(--x:red) or (color:asdf)"));
+ EXPECT_EQ(Result::kSupported,
+ WindowCSSSupports("not ((color:gjhk) or (color:asdf))"));
+
+ EXPECT_EQ(Result::kUnsupported,
+ WindowCSSSupports("(color:ghjk) or (color:asdf)"));
+ EXPECT_EQ(Result::kUnsupported, WindowCSSSupports("(color:ghjk) or asdf(1)"));
+ EXPECT_EQ(Result::kSupported, WindowCSSSupports("color:red"));
+}
+
+} // namespace blink
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 cd30505863e..d8f4be1589d 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
@@ -55,12 +55,18 @@ class FontVariantEastAsianParser {
CSSValue* FinalizeValue() {
CSSValueList* result = CSSValueList::CreateSpaceSeparated();
- if (east_asian_form_value_)
- result->Append(*east_asian_form_value_.Release());
- if (east_asian_width_value_)
- result->Append(*east_asian_width_value_.Release());
- if (ruby_value_)
- result->Append(*ruby_value_.Release());
+ if (east_asian_form_value_) {
+ result->Append(*east_asian_form_value_);
+ east_asian_form_value_ = nullptr;
+ }
+ if (east_asian_width_value_) {
+ result->Append(*east_asian_width_value_);
+ east_asian_width_value_ = nullptr;
+ }
+ if (ruby_value_) {
+ result->Append(*ruby_value_);
+ ruby_value_ = nullptr;
+ }
if (!result->length())
return CSSIdentifierValue::Create(CSSValueID::kNormal);
@@ -68,9 +74,9 @@ class FontVariantEastAsianParser {
}
private:
- Member<CSSIdentifierValue> east_asian_form_value_;
- Member<CSSIdentifierValue> east_asian_width_value_;
- Member<CSSIdentifierValue> ruby_value_;
+ CSSIdentifierValue* east_asian_form_value_;
+ CSSIdentifierValue* east_asian_width_value_;
+ CSSIdentifierValue* ruby_value_;
};
} // namespace blink
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 5a823068751..9da89771349 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
@@ -62,7 +62,9 @@ class FontVariantLigaturesParser {
CSSValue* FinalizeValue() {
if (!result_->length())
return CSSIdentifierValue::Create(CSSValueID::kNormal);
- return result_.Release();
+ CSSValue* result = result_;
+ result_ = nullptr;
+ return result;
}
private:
@@ -70,7 +72,7 @@ class FontVariantLigaturesParser {
bool saw_discretionary_ligatures_value_;
bool saw_historical_ligatures_value_;
bool saw_contextual_ligatures_value_;
- Member<CSSValueList> result_;
+ CSSValueList* result_;
};
} // namespace blink
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 519c321695c..f34b7ae000f 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
@@ -73,11 +73,11 @@ class FontVariantNumericParser {
}
private:
- Member<CSSIdentifierValue> numeric_figure_;
- Member<CSSIdentifierValue> numeric_spacing_;
- Member<CSSIdentifierValue> numeric_fraction_;
- Member<CSSIdentifierValue> ordinal_;
- Member<CSSIdentifierValue> slashed_zero_;
+ CSSIdentifierValue* numeric_figure_ = nullptr;
+ CSSIdentifierValue* numeric_spacing_ = nullptr;
+ CSSIdentifierValue* numeric_fraction_ = nullptr;
+ CSSIdentifierValue* ordinal_ = nullptr;
+ CSSIdentifierValue* slashed_zero_ = nullptr;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/parser/media_condition_test.cc b/chromium/third_party/blink/renderer/core/css/parser/media_condition_test.cc
index cc8668d3c4b..f76c97e21f1 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/media_condition_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/parser/media_condition_test.cc
@@ -40,7 +40,8 @@ TEST(MediaConditionParserTest, Basic) {
CSSTokenizer tokenizer(test_cases[i].input);
const auto tokens = tokenizer.TokenizeToEOF();
scoped_refptr<MediaQuerySet> media_condition_query_set =
- MediaQueryParser::ParseMediaCondition(CSSParserTokenRange(tokens));
+ MediaQueryParser::ParseMediaCondition(CSSParserTokenRange(tokens),
+ nullptr);
ASSERT_EQ(media_condition_query_set->QueryVector().size(), (unsigned)1);
String query_text = media_condition_query_set->QueryVector()[0]->CssText();
ASSERT_EQ(test_cases[i].output, query_text);
diff --git a/chromium/third_party/blink/renderer/core/css/parser/media_query_parser.cc b/chromium/third_party/blink/renderer/core/css/parser/media_query_parser.cc
index fef2f9cd162..c64ea658fd4 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/media_query_parser.cc
+++ b/chromium/third_party/blink/renderer/core/css/parser/media_query_parser.cc
@@ -4,32 +4,41 @@
#include "third_party/blink/renderer/core/css/parser/media_query_parser.h"
+#include "third_party/blink/renderer/core/css/parser/css_parser_context.h"
#include "third_party/blink/renderer/core/css/parser/css_tokenizer.h"
#include "third_party/blink/renderer/core/media_type_names.h"
namespace blink {
scoped_refptr<MediaQuerySet> MediaQueryParser::ParseMediaQuerySet(
- const String& query_string) {
+ const String& query_string,
+ const ExecutionContext* execution_context) {
return ParseMediaQuerySet(
- CSSParserTokenRange(CSSTokenizer(query_string).TokenizeToEOF()));
+ CSSParserTokenRange(CSSTokenizer(query_string).TokenizeToEOF()),
+ execution_context);
}
scoped_refptr<MediaQuerySet> MediaQueryParser::ParseMediaQuerySet(
- CSSParserTokenRange range) {
- return MediaQueryParser(kMediaQuerySetParser, kHTMLStandardMode)
+ CSSParserTokenRange range,
+ const ExecutionContext* execution_context) {
+ return MediaQueryParser(kMediaQuerySetParser, kHTMLStandardMode,
+ execution_context)
.ParseImpl(range);
}
scoped_refptr<MediaQuerySet> MediaQueryParser::ParseMediaQuerySetInMode(
CSSParserTokenRange range,
- CSSParserMode mode) {
- return MediaQueryParser(kMediaQuerySetParser, mode).ParseImpl(range);
+ CSSParserMode mode,
+ const ExecutionContext* execution_context) {
+ return MediaQueryParser(kMediaQuerySetParser, mode, execution_context)
+ .ParseImpl(range);
}
scoped_refptr<MediaQuerySet> MediaQueryParser::ParseMediaCondition(
- CSSParserTokenRange range) {
- return MediaQueryParser(kMediaConditionParser, kHTMLStandardMode)
+ CSSParserTokenRange range,
+ const ExecutionContext* execution_context) {
+ return MediaQueryParser(kMediaConditionParser, kHTMLStandardMode,
+ execution_context)
.ParseImpl(range);
}
@@ -57,10 +66,13 @@ const MediaQueryParser::State MediaQueryParser::kSkipUntilBlockEnd =
&MediaQueryParser::SkipUntilBlockEnd;
const MediaQueryParser::State MediaQueryParser::kDone = &MediaQueryParser::Done;
-MediaQueryParser::MediaQueryParser(ParserType parser_type, CSSParserMode mode)
+MediaQueryParser::MediaQueryParser(ParserType parser_type,
+ CSSParserMode mode,
+ const ExecutionContext* execution_context)
: parser_type_(parser_type),
query_set_(MediaQuerySet::Create()),
- mode_(mode) {
+ mode_(mode),
+ execution_context_(execution_context) {
if (parser_type == kMediaQuerySetParser)
state_ = &MediaQueryParser::ReadRestrictor;
else // MediaConditionParser
@@ -183,7 +195,7 @@ void MediaQueryParser::ReadFeatureColon(CSSParserTokenType type,
else
state_ = kReadFeatureValue;
} else if (type == kRightParenthesisToken || type == kEOFToken) {
- media_query_data_.AddExpression(range);
+ media_query_data_.AddExpression(range, execution_context_);
ReadFeatureEnd(type, token, range);
} else {
state_ = kSkipUntilBlockEnd;
@@ -198,7 +210,7 @@ void MediaQueryParser::ReadFeatureValue(CSSParserTokenType type,
range.Consume();
state_ = kSkipUntilComma;
} else {
- media_query_data_.AddExpression(range);
+ media_query_data_.AddExpression(range, execution_context_);
state_ = kReadFeatureEnd;
}
}
@@ -289,7 +301,10 @@ bool MediaQueryParser::IsMediaFeatureAllowedInMode(
MediaQueryData::MediaQueryData()
: restrictor_(MediaQuery::kNone),
media_type_(media_type_names::kAll),
- media_type_set_(false) {}
+ media_type_set_(false),
+ fake_context_(*MakeGarbageCollected<CSSParserContext>(
+ kHTMLStandardMode,
+ SecureContextMode::kInsecureContext)) {}
void MediaQueryData::Clear() {
restrictor_ = MediaQuery::kNone;
@@ -306,8 +321,10 @@ std::unique_ptr<MediaQuery> MediaQueryData::TakeMediaQuery() {
return media_query;
}
-void MediaQueryData::AddExpression(CSSParserTokenRange& range) {
- expressions_.push_back(MediaQueryExp::Create(media_feature_, range));
+void MediaQueryData::AddExpression(CSSParserTokenRange& range,
+ const ExecutionContext* execution_context) {
+ expressions_.push_back(MediaQueryExp::Create(
+ media_feature_, range, fake_context_, execution_context));
}
bool MediaQueryData::LastExpressionValid() {
diff --git a/chromium/third_party/blink/renderer/core/css/parser/media_query_parser.h b/chromium/third_party/blink/renderer/core/css/parser/media_query_parser.h
index 0da7b89eb18..a956c975641 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/media_query_parser.h
+++ b/chromium/third_party/blink/renderer/core/css/parser/media_query_parser.h
@@ -19,6 +19,7 @@
namespace blink {
class MediaQuerySet;
+class CSSParserContext;
class MediaQueryData {
STACK_ALLOCATED();
@@ -30,10 +31,14 @@ class MediaQueryData {
String media_feature_;
bool media_type_set_;
+ // A fake CSSParserContext for use counter only.
+ // TODO(xiaochengh): Plumb the real CSSParserContext from the document.
+ const CSSParserContext& fake_context_;
+
public:
MediaQueryData();
void Clear();
- void AddExpression(CSSParserTokenRange&);
+ void AddExpression(CSSParserTokenRange&, const ExecutionContext*);
bool LastExpressionValid();
void RemoveLastExpression();
void SetMediaType(const String&);
@@ -57,12 +62,19 @@ class CORE_EXPORT MediaQueryParser {
STACK_ALLOCATED();
public:
- static scoped_refptr<MediaQuerySet> ParseMediaQuerySet(const String&);
- static scoped_refptr<MediaQuerySet> ParseMediaQuerySet(CSSParserTokenRange);
- static scoped_refptr<MediaQuerySet> ParseMediaCondition(CSSParserTokenRange);
+ static scoped_refptr<MediaQuerySet> ParseMediaQuerySet(
+ const String&,
+ const ExecutionContext*);
+ static scoped_refptr<MediaQuerySet> ParseMediaQuerySet(
+ CSSParserTokenRange,
+ const ExecutionContext*);
+ static scoped_refptr<MediaQuerySet> ParseMediaCondition(
+ CSSParserTokenRange,
+ const ExecutionContext*);
static scoped_refptr<MediaQuerySet> ParseMediaQuerySetInMode(
CSSParserTokenRange,
- CSSParserMode);
+ CSSParserMode,
+ const ExecutionContext*);
private:
enum ParserType {
@@ -70,7 +82,7 @@ class CORE_EXPORT MediaQueryParser {
kMediaConditionParser,
};
- MediaQueryParser(ParserType, CSSParserMode);
+ MediaQueryParser(ParserType, CSSParserMode, const ExecutionContext*);
virtual ~MediaQueryParser();
scoped_refptr<MediaQuerySet> ParseImpl(CSSParserTokenRange);
@@ -125,6 +137,7 @@ class CORE_EXPORT MediaQueryParser {
scoped_refptr<MediaQuerySet> query_set_;
MediaQueryBlockWatcher block_watcher_;
CSSParserMode mode_;
+ const ExecutionContext* execution_context_;
const static State kReadRestrictor;
const static State kReadMediaNot;
diff --git a/chromium/third_party/blink/renderer/core/css/parser/sizes_attribute_parser.cc b/chromium/third_party/blink/renderer/core/css/parser/sizes_attribute_parser.cc
index 7a59eb34018..11ad76dae45 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/sizes_attribute_parser.cc
+++ b/chromium/third_party/blink/renderer/core/css/parser/sizes_attribute_parser.cc
@@ -11,10 +11,15 @@
namespace blink {
-SizesAttributeParser::SizesAttributeParser(MediaValues* media_values,
- const String& attribute)
- : media_values_(media_values), length_(0), length_was_set_(false) {
- DCHECK(media_values_.Get());
+SizesAttributeParser::SizesAttributeParser(
+ MediaValues* media_values,
+ const String& attribute,
+ const ExecutionContext* execution_context)
+ : media_values_(media_values),
+ execution_context_(execution_context),
+ length_(0),
+ length_was_set_(false) {
+ DCHECK(media_values_);
is_valid_ =
Parse(CSSParserTokenRange(CSSTokenizer(attribute).TokenizeToEOF()));
}
@@ -83,7 +88,8 @@ bool SizesAttributeParser::Parse(CSSParserTokenRange range) {
continue;
scoped_refptr<MediaQuerySet> media_condition =
MediaQueryParser::ParseMediaCondition(
- range.MakeSubRange(media_condition_start, length_token_start));
+ range.MakeSubRange(media_condition_start, length_token_start),
+ execution_context_);
if (!media_condition || !MediaConditionMatches(*media_condition))
continue;
length_ = length;
diff --git a/chromium/third_party/blink/renderer/core/css/parser/sizes_attribute_parser.h b/chromium/third_party/blink/renderer/core/css/parser/sizes_attribute_parser.h
index 3549b57c29a..f0dfbd4569e 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/sizes_attribute_parser.h
+++ b/chromium/third_party/blink/renderer/core/css/parser/sizes_attribute_parser.h
@@ -14,11 +14,13 @@
namespace blink {
+class ExecutionContext;
+
class CORE_EXPORT SizesAttributeParser {
STACK_ALLOCATED();
public:
- SizesAttributeParser(MediaValues*, const String&);
+ SizesAttributeParser(MediaValues*, const String&, const ExecutionContext*);
float length();
@@ -30,7 +32,8 @@ class CORE_EXPORT SizesAttributeParser {
float EffectiveSizeDefaultValue();
scoped_refptr<MediaQuerySet> media_condition_;
- Member<MediaValues> media_values_;
+ MediaValues* media_values_;
+ const ExecutionContext* execution_context_;
float length_;
bool length_was_set_;
bool is_valid_;
diff --git a/chromium/third_party/blink/renderer/core/css/parser/sizes_attribute_parser_test.cc b/chromium/third_party/blink/renderer/core/css/parser/sizes_attribute_parser_test.cc
index bcb5bcd9e49..e6f80eada0f 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/sizes_attribute_parser_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/parser/sizes_attribute_parser_test.cc
@@ -91,7 +91,7 @@ TEST(SizesAttributeParserTest, Basic) {
auto* media_values = MakeGarbageCollected<MediaValuesCached>(data);
for (unsigned i = 0; test_cases[i].input; ++i) {
- SizesAttributeParser parser(media_values, test_cases[i].input);
+ SizesAttributeParser parser(media_values, test_cases[i].input, nullptr);
ASSERT_EQ(test_cases[i].effective_size, parser.length());
}
}
@@ -172,7 +172,7 @@ TEST(SizesAttributeParserTest, FloatViewportWidth) {
auto* media_values = MakeGarbageCollected<MediaValuesCached>(data);
for (unsigned i = 0; test_cases[i].input; ++i) {
- SizesAttributeParser parser(media_values, test_cases[i].input);
+ SizesAttributeParser parser(media_values, test_cases[i].input, nullptr);
ASSERT_EQ(test_cases[i].effective_size, parser.length());
}
}
diff --git a/chromium/third_party/blink/renderer/core/css/parser/sizes_math_function_parser.cc b/chromium/third_party/blink/renderer/core/css/parser/sizes_math_function_parser.cc
index 6daa4598c3c..7dd70a11bf0 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/sizes_math_function_parser.cc
+++ b/chromium/third_party/blink/renderer/core/css/parser/sizes_math_function_parser.cc
@@ -117,8 +117,6 @@ bool SizesMathFunctionParser::HandleRightParenthesis(
bool SizesMathFunctionParser::HandleComma(Vector<CSSParserToken>& stack,
const CSSParserToken& token) {
- if (!RuntimeEnabledFeatures::CSSComparisonFunctionsEnabled())
- return false;
// Treat comma as a binary right-associative operation for now, so that
// when reaching the right parenthesis of the function, we can get the
// number of parameters by counting the number of commas.
@@ -180,13 +178,11 @@ bool SizesMathFunctionParser::CalcToReversePolishNotation(
return false;
break;
case kFunctionToken:
- if (RuntimeEnabledFeatures::CSSComparisonFunctionsEnabled()) {
- if (token.FunctionId() == CSSValueID::kMin ||
- token.FunctionId() == CSSValueID::kMax ||
- token.FunctionId() == CSSValueID::kClamp) {
- stack.push_back(token);
- break;
- }
+ if (token.FunctionId() == CSSValueID::kMin ||
+ token.FunctionId() == CSSValueID::kMax ||
+ token.FunctionId() == CSSValueID::kClamp) {
+ stack.push_back(token);
+ break;
}
if (token.FunctionId() != CSSValueID::kCalc)
return false;
diff --git a/chromium/third_party/blink/renderer/core/css/parser/sizes_math_function_parser.h b/chromium/third_party/blink/renderer/core/css/parser/sizes_math_function_parser.h
index de8b146de0c..7c88ea53a82 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/sizes_math_function_parser.h
+++ b/chromium/third_party/blink/renderer/core/css/parser/sizes_math_function_parser.h
@@ -48,7 +48,7 @@ class CORE_EXPORT SizesMathFunctionParser {
void AppendOperator(const CSSParserToken&);
Vector<SizesMathValue> value_list_;
- Member<MediaValues> media_values_;
+ MediaValues* media_values_;
bool is_valid_;
float result_;
};
diff --git a/chromium/third_party/blink/renderer/core/css/parser/sizes_math_function_parser_test.cc b/chromium/third_party/blink/renderer/core/css/parser/sizes_math_function_parser_test.cc
index f6b07c22960..7710f1917e5 100644
--- a/chromium/third_party/blink/renderer/core/css/parser/sizes_math_function_parser_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/parser/sizes_math_function_parser_test.cc
@@ -12,7 +12,6 @@
#include "third_party/blink/renderer/core/css/parser/css_tokenizer.h"
#include "third_party/blink/renderer/core/media_type_names.h"
#include "third_party/blink/renderer/platform/fonts/font.h"
-#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
namespace blink {
@@ -63,8 +62,6 @@ static void VerifyCSSCalc(String text,
}
TEST(SizesMathFunctionParserTest, Basic) {
- ScopedCSSComparisonFunctionsForTest scope(true);
-
SizesCalcTestCase test_cases[] = {
{"calc(500px + 10em)", 660, true, false},
{"calc(500px / 8)", 62.5, true, false},
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 b4ee2719ad6..b876e57eebd 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
@@ -45,6 +45,10 @@
#include "third_party/blink/renderer/core/style/style_svg_resource.h"
#include "third_party/blink/renderer/core/style_property_shorthand.h"
#include "third_party/blink/renderer/core/svg_element_type_helpers.h"
+#include "third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.h"
+#include "third_party/blink/renderer/platform/transforms/matrix_transform_operation.h"
+#include "third_party/blink/renderer/platform/transforms/perspective_transform_operation.h"
+#include "third_party/blink/renderer/platform/transforms/skew_transform_operation.h"
namespace blink {
@@ -162,11 +166,10 @@ const CSSValue* ComputedStyleUtils::ValueForFillSize(
return ZoomAdjustedPixelValueForLength(fill_size.size.Width(), style);
}
- CSSValueList* list = CSSValueList::CreateSpaceSeparated();
- list->Append(*ZoomAdjustedPixelValueForLength(fill_size.size.Width(), style));
- list->Append(
- *ZoomAdjustedPixelValueForLength(fill_size.size.Height(), style));
- return list;
+ return MakeGarbageCollected<CSSValuePair>(
+ ZoomAdjustedPixelValueForLength(fill_size.size.Width(), style),
+ ZoomAdjustedPixelValueForLength(fill_size.size.Height(), style),
+ CSSValuePair::kKeepIdenticalValues);
}
const CSSValue* ComputedStyleUtils::BackgroundImageOrWebkitMaskSize(
@@ -286,8 +289,15 @@ const CSSValue* ComputedStyleUtils::BackgroundPositionXOrWebkitMaskPositionX(
const FillLayer* curr_layer) {
CSSValueList* list = CSSValueList::CreateCommaSeparated();
for (; curr_layer; curr_layer = curr_layer->Next()) {
- list->Append(
- *ZoomAdjustedPixelValueForLength(curr_layer->PositionX(), style));
+ const Length& from_edge = curr_layer->PositionX();
+ if (curr_layer->BackgroundXOrigin() == BackgroundEdgeOrigin::kRight) {
+ // TODO(crbug.com/610627): This should use two-value syntax once the
+ // parser accepts it.
+ list->Append(*ZoomAdjustedPixelValueForLength(
+ from_edge.SubtractFromOneHundredPercent(), style));
+ } else {
+ list->Append(*ZoomAdjustedPixelValueForLength(from_edge, style));
+ }
}
return list;
}
@@ -297,8 +307,15 @@ const CSSValue* ComputedStyleUtils::BackgroundPositionYOrWebkitMaskPositionY(
const FillLayer* curr_layer) {
CSSValueList* list = CSSValueList::CreateCommaSeparated();
for (; curr_layer; curr_layer = curr_layer->Next()) {
- list->Append(
- *ZoomAdjustedPixelValueForLength(curr_layer->PositionY(), style));
+ const Length& from_edge = curr_layer->PositionY();
+ if (curr_layer->BackgroundYOrigin() == BackgroundEdgeOrigin::kBottom) {
+ // TODO(crbug.com/610627): This should use two-value syntax once the
+ // parser accepts it.
+ list->Append(*ZoomAdjustedPixelValueForLength(
+ from_edge.SubtractFromOneHundredPercent(), style));
+ } else {
+ list->Append(*ZoomAdjustedPixelValueForLength(from_edge, style));
+ }
}
return list;
}
@@ -738,6 +755,22 @@ CSSValue* ComputedStyleUtils::ValueForLineHeight(const ComputedStyle& style) {
style);
}
+CSSValue* ComputedStyleUtils::ComputedValueForLineHeight(
+ const ComputedStyle& style) {
+ const Length& length = style.LineHeight();
+ if (length.IsNegative())
+ return CSSIdentifierValue::Create(CSSValueID::kNormal);
+
+ if (length.IsPercent()) {
+ return CSSNumericLiteralValue::Create(length.GetFloatValue() / 100.0,
+ CSSPrimitiveValue::UnitType::kNumber);
+ } else {
+ return ZoomAdjustedPixelValue(
+ FloatValueForLength(length, style.GetFontDescription().ComputedSize()),
+ style);
+ }
+}
+
CSSValueID IdentifierForFamily(const AtomicString& family) {
if (family == font_family_names::kWebkitCursive)
return CSSValueID::kCursive;
@@ -745,8 +778,6 @@ CSSValueID IdentifierForFamily(const AtomicString& family) {
return CSSValueID::kFantasy;
if (family == font_family_names::kWebkitMonospace)
return CSSValueID::kMonospace;
- if (family == font_family_names::kWebkitPictograph)
- return CSSValueID::kWebkitPictograph;
if (family == font_family_names::kWebkitSansSerif)
return CSSValueID::kSansSerif;
if (family == font_family_names::kWebkitSerif)
@@ -1485,30 +1516,27 @@ CSSValue* ComputedStyleUtils::ValueForTextDecorationSkipInk(
CSSValue* ComputedStyleUtils::TouchActionFlagsToCSSValue(
TouchAction touch_action) {
CSSValueList* list = CSSValueList::CreateSpaceSeparated();
- if (touch_action == TouchAction::kTouchActionAuto) {
+ if (touch_action == TouchAction::kAuto) {
list->Append(*CSSIdentifierValue::Create(CSSValueID::kAuto));
- } else if (touch_action == TouchAction::kTouchActionNone) {
+ } else if (touch_action == TouchAction::kNone) {
list->Append(*CSSIdentifierValue::Create(CSSValueID::kNone));
- } else if (touch_action == TouchAction::kTouchActionManipulation) {
+ } else if (touch_action == TouchAction::kManipulation) {
list->Append(*CSSIdentifierValue::Create(CSSValueID::kManipulation));
} else {
- if ((touch_action & TouchAction::kTouchActionPanX) ==
- TouchAction::kTouchActionPanX)
+ if ((touch_action & TouchAction::kPanX) == TouchAction::kPanX)
list->Append(*CSSIdentifierValue::Create(CSSValueID::kPanX));
- else if (touch_action & TouchAction::kTouchActionPanLeft)
+ else if ((touch_action & TouchAction::kPanLeft) != TouchAction::kNone)
list->Append(*CSSIdentifierValue::Create(CSSValueID::kPanLeft));
- else if (touch_action & TouchAction::kTouchActionPanRight)
+ else if ((touch_action & TouchAction::kPanRight) != TouchAction::kNone)
list->Append(*CSSIdentifierValue::Create(CSSValueID::kPanRight));
- if ((touch_action & TouchAction::kTouchActionPanY) ==
- TouchAction::kTouchActionPanY)
+ if ((touch_action & TouchAction::kPanY) == TouchAction::kPanY)
list->Append(*CSSIdentifierValue::Create(CSSValueID::kPanY));
- else if (touch_action & TouchAction::kTouchActionPanUp)
+ else if ((touch_action & TouchAction::kPanUp) != TouchAction::kNone)
list->Append(*CSSIdentifierValue::Create(CSSValueID::kPanUp));
- else if (touch_action & TouchAction::kTouchActionPanDown)
+ else if ((touch_action & TouchAction::kPanDown) != TouchAction::kNone)
list->Append(*CSSIdentifierValue::Create(CSSValueID::kPanDown));
- if ((touch_action & TouchAction::kTouchActionPinchZoom) ==
- TouchAction::kTouchActionPinchZoom)
+ if ((touch_action & TouchAction::kPinchZoom) == TouchAction::kPinchZoom)
list->Append(*CSSIdentifierValue::Create(CSSValueID::kPinchZoom));
}
@@ -1620,8 +1648,8 @@ CSSValue* ComputedStyleUtils::CreateTimingFunctionValue(
const TimingFunction* timing_function) {
switch (timing_function->GetType()) {
case TimingFunction::Type::CUBIC_BEZIER: {
- const CubicBezierTimingFunction* bezier_timing_function =
- ToCubicBezierTimingFunction(timing_function);
+ const auto* bezier_timing_function =
+ To<CubicBezierTimingFunction>(timing_function);
if (bezier_timing_function->GetEaseType() !=
CubicBezierTimingFunction::EaseType::CUSTOM) {
CSSValueID value_id = CSSValueID::kInvalid;
@@ -1650,15 +1678,16 @@ CSSValue* ComputedStyleUtils::CreateTimingFunctionValue(
}
case TimingFunction::Type::STEPS: {
- const StepsTimingFunction* steps_timing_function =
- ToStepsTimingFunction(timing_function);
+ const auto* steps_timing_function =
+ To<StepsTimingFunction>(timing_function);
StepsTimingFunction::StepPosition position =
steps_timing_function->GetStepPosition();
int steps = steps_timing_function->NumberOfSteps();
// Canonical form of step timing function is step(n, type) or step(n) even
// if initially parsed as step-start or step-end.
- return cssvalue::CSSStepsTimingFunctionValue::Create(steps, position);
+ return MakeGarbageCollected<cssvalue::CSSStepsTimingFunctionValue>(
+ steps, position);
}
default:
@@ -1700,16 +1729,16 @@ CSSValueList* ComputedStyleUtils::ValuesForBorderRadiusCorner(
return list;
}
-const CSSValue& ComputedStyleUtils::ValueForBorderRadiusCorner(
+CSSValue* ComputedStyleUtils::ValueForBorderRadiusCorner(
const LengthSize& radius,
const ComputedStyle& style) {
- CSSValueList& list = *ValuesForBorderRadiusCorner(radius, style);
- if (list.Item(0) == list.Item(1))
- return list.Item(0);
- return list;
+ return MakeGarbageCollected<CSSValuePair>(
+ ZoomAdjustedPixelValueForLength(radius.Width(), style),
+ ZoomAdjustedPixelValueForLength(radius.Height(), style),
+ CSSValuePair::kDropIdenticalValues);
}
-CSSFunctionValue* ValueForMatrixTransform(
+CSSValue* ComputedStyleUtils::ValueForMatrixTransform(
const TransformationMatrix& transform_param,
const ComputedStyle& style) {
// Take TransformationMatrix by reference and then copy it because VC++
@@ -1777,6 +1806,153 @@ CSSFunctionValue* ValueForMatrixTransform(
return transform_value;
}
+// We collapse functions like translateX into translate, since we will reify
+// them as a translate anyway.
+CSSValue* ComputedStyleUtils::ValueForTransformOperation(
+ const TransformOperation& operation,
+ float zoom) {
+ switch (operation.GetType()) {
+ case TransformOperation::kScaleX:
+ case TransformOperation::kScaleY:
+ case TransformOperation::kScaleZ:
+ case TransformOperation::kScale:
+ case TransformOperation::kScale3D: {
+ const auto& scale = To<ScaleTransformOperation>(operation);
+ CSSFunctionValue* result = MakeGarbageCollected<CSSFunctionValue>(
+ operation.Is3DOperation() ? CSSValueID::kScale3d
+ : CSSValueID::kScale);
+ result->Append(*CSSNumericLiteralValue::Create(
+ scale.X(), CSSPrimitiveValue::UnitType::kNumber));
+ result->Append(*CSSNumericLiteralValue::Create(
+ scale.Y(), CSSPrimitiveValue::UnitType::kNumber));
+ if (operation.Is3DOperation()) {
+ result->Append(*CSSNumericLiteralValue::Create(
+ scale.Z(), CSSPrimitiveValue::UnitType::kNumber));
+ }
+ return result;
+ }
+ case TransformOperation::kTranslateX:
+ case TransformOperation::kTranslateY:
+ case TransformOperation::kTranslateZ:
+ case TransformOperation::kTranslate:
+ case TransformOperation::kTranslate3D: {
+ const auto& translate = To<TranslateTransformOperation>(operation);
+ CSSFunctionValue* result = MakeGarbageCollected<CSSFunctionValue>(
+ operation.Is3DOperation() ? CSSValueID::kTranslate3d
+ : CSSValueID::kTranslate);
+ result->Append(*CSSPrimitiveValue::CreateFromLength(translate.X(), zoom));
+ result->Append(*CSSPrimitiveValue::CreateFromLength(translate.Y(), zoom));
+ if (operation.Is3DOperation()) {
+ // Since this is pixel length, we must unzoom (CreateFromLength above
+ // does the division internally).
+ result->Append(*CSSNumericLiteralValue::Create(
+ translate.Z() / zoom, CSSPrimitiveValue::UnitType::kPixels));
+ }
+ return result;
+ }
+ case TransformOperation::kRotateX:
+ case TransformOperation::kRotateY:
+ case TransformOperation::kRotate3D: {
+ const auto& rotate = To<RotateTransformOperation>(operation);
+ CSSFunctionValue* result =
+ MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kRotate3d);
+ result->Append(*CSSNumericLiteralValue::Create(
+ rotate.X(), CSSPrimitiveValue::UnitType::kNumber));
+ result->Append(*CSSNumericLiteralValue::Create(
+ rotate.Y(), CSSPrimitiveValue::UnitType::kNumber));
+ result->Append(*CSSNumericLiteralValue::Create(
+ rotate.Z(), CSSPrimitiveValue::UnitType::kNumber));
+ result->Append(*CSSNumericLiteralValue::Create(
+ rotate.Angle(), CSSPrimitiveValue::UnitType::kDegrees));
+ return result;
+ }
+ case TransformOperation::kRotate: {
+ const auto& rotate = To<RotateTransformOperation>(operation);
+ auto* result =
+ MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kRotate);
+ result->Append(*CSSNumericLiteralValue::Create(
+ rotate.Angle(), CSSPrimitiveValue::UnitType::kDegrees));
+ return result;
+ }
+ case TransformOperation::kSkewX: {
+ const auto& skew = To<SkewTransformOperation>(operation);
+ auto* result = MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kSkewX);
+ result->Append(*CSSNumericLiteralValue::Create(
+ skew.AngleX(), CSSPrimitiveValue::UnitType::kDegrees));
+ return result;
+ }
+ case TransformOperation::kSkewY: {
+ const auto& skew = To<SkewTransformOperation>(operation);
+ auto* result = MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kSkewY);
+ result->Append(*CSSNumericLiteralValue::Create(
+ skew.AngleY(), CSSPrimitiveValue::UnitType::kDegrees));
+ return result;
+ }
+ case TransformOperation::kSkew: {
+ const auto& skew = To<SkewTransformOperation>(operation);
+ auto* result = MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kSkew);
+ result->Append(*CSSNumericLiteralValue::Create(
+ skew.AngleX(), CSSPrimitiveValue::UnitType::kDegrees));
+ result->Append(*CSSNumericLiteralValue::Create(
+ skew.AngleY(), CSSPrimitiveValue::UnitType::kDegrees));
+ return result;
+ }
+ case TransformOperation::kPerspective: {
+ const auto& perspective = To<PerspectiveTransformOperation>(operation);
+ auto* result =
+ MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kPerspective);
+ result->Append(*CSSNumericLiteralValue::Create(
+ perspective.Perspective() / zoom,
+ CSSPrimitiveValue::UnitType::kPixels));
+ return result;
+ }
+ case TransformOperation::kMatrix: {
+ const auto& matrix = To<MatrixTransformOperation>(operation).Matrix();
+ auto* result =
+ MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kMatrix);
+ // CSS matrix values are returned in column-major order.
+ double values[6] = {matrix.A(), matrix.B(), //
+ matrix.C(), matrix.D(), //
+ // E and F are pixel lengths so unzoom
+ matrix.E() / zoom, matrix.F() / zoom};
+ for (double value : values) {
+ result->Append(*CSSNumericLiteralValue::Create(
+ value, CSSPrimitiveValue::UnitType::kNumber));
+ }
+ return result;
+ }
+ case TransformOperation::kMatrix3D: {
+ const auto& matrix = To<Matrix3DTransformOperation>(operation).Matrix();
+ CSSFunctionValue* result =
+ MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kMatrix3d);
+ // CSS matrix values are returned in column-major order.
+ double values[16] = {
+ // Note that the transformation matrix operates on (Length^3 * R).
+ // Each column contains 3 scalars followed by a reciprocal length
+ // (with a value in 1/px) which must be unzoomed accordingly.
+ matrix.M11(), matrix.M12(), matrix.M13(), matrix.M14() * zoom,
+ matrix.M21(), matrix.M22(), matrix.M23(), matrix.M24() * zoom,
+ matrix.M31(), matrix.M32(), matrix.M33(), matrix.M34() * zoom,
+ // Last column has 3 pixel lengths and a scalar
+ matrix.M41() / zoom, matrix.M42() / zoom, matrix.M43() / zoom,
+ matrix.M44()};
+ for (double value : values) {
+ result->Append(*CSSNumericLiteralValue::Create(
+ value, CSSPrimitiveValue::UnitType::kNumber));
+ }
+ return result;
+ }
+ case TransformOperation::kInterpolated:
+ // TODO(816803): The computed value in this case is not fully spec'd
+ // See https://github.com/w3c/css-houdini-drafts/issues/425
+ return CSSIdentifierValue::Create(CSSValueID::kNone);
+ default:
+ // The remaining operations are unsupported.
+ NOTREACHED();
+ return CSSIdentifierValue::Create(CSSValueID::kNone);
+ }
+}
+
FloatRect ComputedStyleUtils::ReferenceBoxForTransform(
const LayoutObject& layout_object,
UsePixelSnappedBox pixel_snap_box) {
@@ -1857,6 +2033,11 @@ CSSValueID ValueForQuoteType(const QuoteType quote_type) {
CSSValue* ComputedStyleUtils::ValueForContentData(const ComputedStyle& style,
bool allow_visited_style) {
+ if (style.ContentPreventsBoxGeneration())
+ return CSSIdentifierValue::Create(CSSValueID::kNone);
+ if (style.ContentBehavesAsNormal())
+ return CSSIdentifierValue::Create(CSSValueID::kNormal);
+
CSSValueList* outer_list = CSSValueList::CreateSlashSeparated();
CSSValueList* list = CSSValueList::CreateSpaceSeparated();
@@ -1901,12 +2082,7 @@ CSSValue* ComputedStyleUtils::ValueForContentData(const ComputedStyle& style,
NOTREACHED();
}
}
- if (!list->length()) {
- PseudoId pseudoId = style.StyleType();
- if (pseudoId == kPseudoIdBefore || pseudoId == kPseudoIdAfter)
- return CSSIdentifierValue::Create(CSSValueID::kNone);
- return CSSIdentifierValue::Create(CSSValueID::kNormal);
- }
+ DCHECK(list->length());
outer_list->Append(*list);
if (alt_text)
@@ -2041,7 +2217,8 @@ CSSValue* ComputedStyleUtils::AdjustSVGPaintForCurrentColor(
const Color& current_color) {
if (paint.type >= SVG_PAINTTYPE_URI_NONE) {
CSSValueList* values = CSSValueList::CreateSpaceSeparated();
- values->Append(*cssvalue::CSSURIValue::Create(paint.GetUrl()));
+ values->Append(
+ *MakeGarbageCollected<cssvalue::CSSURIValue>(paint.GetUrl()));
if (paint.type == SVG_PAINTTYPE_URI_NONE)
values->Append(*CSSIdentifierValue::Create(CSSValueID::kNone));
else if (paint.type == SVG_PAINTTYPE_URI_CURRENTCOLOR)
@@ -2061,7 +2238,7 @@ CSSValue* ComputedStyleUtils::AdjustSVGPaintForCurrentColor(
CSSValue* ComputedStyleUtils::ValueForSVGResource(
const StyleSVGResource* resource) {
if (resource)
- return cssvalue::CSSURIValue::Create(resource->Url());
+ return MakeGarbageCollected<cssvalue::CSSURIValue>(resource->Url());
return CSSIdentifierValue::Create(CSSValueID::kNone);
}
@@ -2576,24 +2753,4 @@ ComputedStyleUtils::CrossThreadStyleValueFromCSSStyleValue(
}
}
-CSSValuePair* ComputedStyleUtils::ValuesForIntrinsicSizeShorthand(
- const StylePropertyShorthand& shorthand,
- const ComputedStyle& style,
- const LayoutObject* layout_object,
- bool allow_visited_style) {
- const CSSValue* start_value =
- shorthand.properties()[0]->CSSValueFromComputedStyle(style, layout_object,
- allow_visited_style);
- if (!start_value)
- return nullptr;
-
- const CSSValue* end_value =
- shorthand.properties()[1]->CSSValueFromComputedStyle(style, layout_object,
- allow_visited_style);
- if (!end_value)
- end_value = start_value;
- return MakeGarbageCollected<CSSValuePair>(start_value, end_value,
- CSSValuePair::kDropIdenticalValues);
-}
-
} // namespace blink
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 cd53fe3de2b..51fcb47c59f 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
@@ -99,6 +99,7 @@ class ComputedStyleUtils {
ValueForContentPositionAndDistributionWithOverflowAlignment(
const StyleContentAlignmentData&);
static CSSValue* ValueForLineHeight(const ComputedStyle&);
+ static CSSValue* ComputedValueForLineHeight(const ComputedStyle&);
static CSSValueList* ValueForFontFamily(const ComputedStyle&);
static CSSPrimitiveValue* ValueForFontSize(const ComputedStyle&);
static CSSPrimitiveValue* ValueForFontStretch(const ComputedStyle&);
@@ -135,8 +136,8 @@ class ComputedStyleUtils {
static CSSValue* ValueForAnimationTimingFunction(const CSSTimingData*);
static CSSValueList* ValuesForBorderRadiusCorner(const LengthSize&,
const ComputedStyle&);
- static const CSSValue& ValueForBorderRadiusCorner(const LengthSize&,
- const ComputedStyle&);
+ static CSSValue* ValueForBorderRadiusCorner(const LengthSize&,
+ const ComputedStyle&);
// TODO(fs): For some properties ('transform') we use the pixel snapped
// border-box as the reference box. In other cases ('transform-origin') we use
// the "unsnapped" border-box. Maybe use the same (the "unsnapped") in both
@@ -145,6 +146,10 @@ class ComputedStyleUtils {
kDontUsePixelSnappedBox,
kUsePixelSnappedBox,
};
+ static CSSValue* ValueForMatrixTransform(const TransformationMatrix&,
+ const ComputedStyle&);
+ static CSSValue* ValueForTransformOperation(const TransformOperation&,
+ float zoom);
static FloatRect ReferenceBoxForTransform(
const LayoutObject&,
UsePixelSnappedBox = kUsePixelSnappedBox);
@@ -214,12 +219,6 @@ class ComputedStyleUtils {
static CSSValue* ValueForGapLength(const GapLength&, const ComputedStyle&);
static std::unique_ptr<CrossThreadStyleValue>
CrossThreadStyleValueFromCSSStyleValue(CSSStyleValue* style_value);
-
- static CSSValuePair* ValuesForIntrinsicSizeShorthand(
- const StylePropertyShorthand&,
- const ComputedStyle&,
- const LayoutObject*,
- bool allow_visited_style);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/properties/css_direction_aware_resolver.cc b/chromium/third_party/blink/renderer/core/css/properties/css_direction_aware_resolver.cc
index d34df6ddfdc..451c66bec37 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/css_direction_aware_resolver.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/css_direction_aware_resolver.cc
@@ -60,10 +60,6 @@ PhysicalGroup<4> CSSDirectionAwareResolver::InsetGroup() {
return PhysicalGroup<4>(insetShorthand());
}
-PhysicalGroup<2> CSSDirectionAwareResolver::IntrinsicSizeGroup() {
- return PhysicalGroup<2>(intrinsicSizeShorthand());
-}
-
PhysicalGroup<4> CSSDirectionAwareResolver::MarginGroup() {
return PhysicalGroup<4>(marginShorthand());
}
diff --git a/chromium/third_party/blink/renderer/core/css/properties/css_direction_aware_resolver.h b/chromium/third_party/blink/renderer/core/css/properties/css_direction_aware_resolver.h
index cbf4f7a4e22..4340a49a9c1 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/css_direction_aware_resolver.h
+++ b/chromium/third_party/blink/renderer/core/css/properties/css_direction_aware_resolver.h
@@ -36,7 +36,6 @@ class CSSDirectionAwareResolver {
static PhysicalGroup<4> BorderStyleGroup();
static PhysicalGroup<4> BorderWidthGroup();
static PhysicalGroup<4> InsetGroup();
- static PhysicalGroup<2> IntrinsicSizeGroup();
static PhysicalGroup<4> MarginGroup();
static PhysicalGroup<2> MaxSizeGroup();
static PhysicalGroup<2> MinSizeGroup();
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 f71c5c321c8..4ede24db6b5 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
@@ -42,6 +42,7 @@
#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_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/style_property_shorthand.h"
#include "third_party/blink/renderer/core/svg/svg_parsing_error.h"
@@ -122,14 +123,15 @@ CSSValue* ConsumeBaselineKeyword(CSSParserTokenRange& range) {
return baseline;
}
-CSSValue* ConsumeSteps(CSSParserTokenRange& range) {
+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);
CSSPrimitiveValue* steps =
- css_property_parser_helpers::ConsumePositiveInteger(args);
+ css_property_parser_helpers::ConsumePositiveInteger(args, context);
if (!steps)
return nullptr;
@@ -176,26 +178,28 @@ CSSValue* ConsumeSteps(CSSParserTokenRange& range) {
}
range = range_copy;
- return cssvalue::CSSStepsTimingFunctionValue::Create(steps->GetIntValue(),
- position);
+ return MakeGarbageCollected<cssvalue::CSSStepsTimingFunctionValue>(
+ steps->GetIntValue(), position);
}
-CSSValue* ConsumeCubicBezier(CSSParserTokenRange& range) {
+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);
double x1, y1, x2, y2;
- if (css_property_parser_helpers::ConsumeNumberRaw(args, x1) && x1 >= 0 &&
- x1 <= 1 &&
+ 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, y1) &&
+ css_property_parser_helpers::ConsumeNumberRaw(args, context, y1) &&
css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args) &&
- css_property_parser_helpers::ConsumeNumberRaw(args, x2) && x2 >= 0 &&
- x2 <= 1 &&
+ css_property_parser_helpers::ConsumeNumberRaw(args, context, x2) &&
+ x2 >= 0 && x2 <= 1 &&
css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args) &&
- css_property_parser_helpers::ConsumeNumberRaw(args, y2) && args.AtEnd()) {
+ css_property_parser_helpers::ConsumeNumberRaw(args, context, y2) &&
+ args.AtEnd()) {
range = range_copy;
return MakeGarbageCollected<cssvalue::CSSCubicBezierTimingFunctionValue>(
x1, y1, x2, y2);
@@ -221,13 +225,13 @@ bool ConsumeCSSValueId(CSSParserTokenRange& range, CSSValueID& value) {
}
CSSValue* ConsumeShapeRadius(CSSParserTokenRange& args,
- CSSParserMode css_parser_mode) {
+ const CSSParserContext& context) {
if (css_property_parser_helpers::IdentMatches<CSSValueID::kClosestSide,
CSSValueID::kFarthestSide>(
args.Peek().Id()))
return css_property_parser_helpers::ConsumeIdent(args);
return css_property_parser_helpers::ConsumeLengthOrPercent(
- args, css_parser_mode, kValueRangeNonNegative);
+ args, context, kValueRangeNonNegative);
}
cssvalue::CSSBasicShapeCircleValue* ConsumeBasicShapeCircle(
@@ -236,7 +240,7 @@ cssvalue::CSSBasicShapeCircleValue* ConsumeBasicShapeCircle(
// spec: https://drafts.csswg.org/css-shapes/#supported-basic-shapes
// circle( [<shape-radius>]? [at <position>]? )
auto* shape = MakeGarbageCollected<cssvalue::CSSBasicShapeCircleValue>();
- if (CSSValue* radius = ConsumeShapeRadius(args, context.Mode()))
+ if (CSSValue* radius = ConsumeShapeRadius(args, context))
shape->SetRadius(radius);
if (css_property_parser_helpers::ConsumeIdent<CSSValueID::kAt>(args)) {
CSSValue* center_x = nullptr;
@@ -258,8 +262,8 @@ cssvalue::CSSBasicShapeEllipseValue* ConsumeBasicShapeEllipse(
// ellipse( [<shape-radius>{2}]? [at <position>]? )
auto* shape = MakeGarbageCollected<cssvalue::CSSBasicShapeEllipseValue>();
WebFeature feature = WebFeature::kBasicShapeEllipseNoRadius;
- if (CSSValue* radius_x = ConsumeShapeRadius(args, context.Mode())) {
- CSSValue* radius_y = ConsumeShapeRadius(args, context.Mode());
+ if (CSSValue* radius_x = ConsumeShapeRadius(args, context)) {
+ CSSValue* radius_y = ConsumeShapeRadius(args, context);
if (!radius_y) {
return nullptr;
}
@@ -298,13 +302,13 @@ cssvalue::CSSBasicShapePolygonValue* ConsumeBasicShapePolygon(
do {
CSSPrimitiveValue* x_length =
- css_property_parser_helpers::ConsumeLengthOrPercent(
- args, context.Mode(), kValueRangeAll);
+ css_property_parser_helpers::ConsumeLengthOrPercent(args, context,
+ kValueRangeAll);
if (!x_length)
return nullptr;
CSSPrimitiveValue* y_length =
- css_property_parser_helpers::ConsumeLengthOrPercent(
- args, context.Mode(), kValueRangeAll);
+ css_property_parser_helpers::ConsumeLengthOrPercent(args, context,
+ kValueRangeAll);
if (!y_length)
return nullptr;
shape->AppendPoint(x_length, y_length);
@@ -317,20 +321,20 @@ cssvalue::CSSBasicShapeInsetValue* ConsumeBasicShapeInset(
const CSSParserContext& context) {
auto* shape = MakeGarbageCollected<cssvalue::CSSBasicShapeInsetValue>();
CSSPrimitiveValue* top = css_property_parser_helpers::ConsumeLengthOrPercent(
- args, context.Mode(), kValueRangeAll);
+ args, context, kValueRangeAll);
if (!top)
return nullptr;
CSSPrimitiveValue* right =
- css_property_parser_helpers::ConsumeLengthOrPercent(args, context.Mode(),
+ css_property_parser_helpers::ConsumeLengthOrPercent(args, context,
kValueRangeAll);
CSSPrimitiveValue* bottom = nullptr;
CSSPrimitiveValue* left = nullptr;
if (right) {
bottom = css_property_parser_helpers::ConsumeLengthOrPercent(
- args, context.Mode(), kValueRangeAll);
+ args, context, kValueRangeAll);
if (bottom) {
left = css_property_parser_helpers::ConsumeLengthOrPercent(
- args, context.Mode(), kValueRangeAll);
+ args, context, kValueRangeAll);
}
}
if (left)
@@ -345,8 +349,7 @@ cssvalue::CSSBasicShapeInsetValue* ConsumeBasicShapeInset(
if (css_property_parser_helpers::ConsumeIdent<CSSValueID::kRound>(args)) {
CSSValue* horizontal_radii[4] = {nullptr};
CSSValue* vertical_radii[4] = {nullptr};
- if (!ConsumeRadii(horizontal_radii, vertical_radii, args, context.Mode(),
- false))
+ if (!ConsumeRadii(horizontal_radii, vertical_radii, args, context, false))
return nullptr;
shape->SetTopLeftRadius(MakeGarbageCollected<CSSValuePair>(
horizontal_radii[0], vertical_radii[0],
@@ -365,11 +368,12 @@ cssvalue::CSSBasicShapeInsetValue* ConsumeBasicShapeInset(
}
bool ConsumeNumbers(CSSParserTokenRange& args,
+ const CSSParserContext& context,
CSSFunctionValue*& transform_value,
unsigned number_of_arguments) {
do {
- CSSValue* parsed_value =
- css_property_parser_helpers::ConsumeNumber(args, kValueRangeAll);
+ CSSValue* parsed_value = css_property_parser_helpers::ConsumeNumber(
+ args, context, kValueRangeAll);
if (!parsed_value)
return false;
transform_value->Append(*parsed_value);
@@ -386,10 +390,11 @@ bool ConsumePerspective(CSSParserTokenRange& args,
CSSFunctionValue*& transform_value,
bool use_legacy_parsing) {
CSSPrimitiveValue* parsed_value = css_property_parser_helpers::ConsumeLength(
- args, context.Mode(), kValueRangeNonNegative);
+ args, context, kValueRangeNonNegative);
if (!parsed_value && use_legacy_parsing) {
double perspective;
- if (!css_property_parser_helpers::ConsumeNumberRaw(args, perspective) ||
+ if (!css_property_parser_helpers::ConsumeNumberRaw(args, context,
+ perspective) ||
perspective < 0) {
return false;
}
@@ -404,21 +409,21 @@ bool ConsumePerspective(CSSParserTokenRange& args,
}
bool ConsumeTranslate3d(CSSParserTokenRange& args,
- CSSParserMode css_parser_mode,
+ const CSSParserContext& context,
CSSFunctionValue*& transform_value) {
unsigned number_of_arguments = 2;
CSSValue* parsed_value = nullptr;
do {
parsed_value = css_property_parser_helpers::ConsumeLengthOrPercent(
- args, css_parser_mode, kValueRangeAll);
+ args, context, kValueRangeAll);
if (!parsed_value)
return false;
transform_value->Append(*parsed_value);
if (!css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args))
return false;
} while (--number_of_arguments);
- parsed_value = css_property_parser_helpers::ConsumeLength(
- args, css_parser_mode, kValueRangeAll);
+ parsed_value =
+ css_property_parser_helpers::ConsumeLength(args, context, kValueRangeAll);
if (!parsed_value)
return false;
transform_value->Append(*parsed_value);
@@ -453,13 +458,15 @@ bool IsContentPositionOrLeftOrRightKeyword(CSSValueID id) {
return IsContentPositionKeyword(id) || IsLeftOrRightKeyword(id);
}
-CSSValue* ConsumeScrollOffset(CSSParserTokenRange& range) {
+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);
+ CSSParserContext::ParserModeOverridingScope scope(context, kHTMLStandardMode);
CSSValue* value = css_property_parser_helpers::ConsumeLengthOrPercent(
- range, kHTMLStandardMode, kValueRangeNonNegative);
+ range, context, kValueRangeNonNegative);
if (!range.AtEnd())
return nullptr;
return value;
@@ -526,10 +533,11 @@ CSSValue* ConsumeContentDistributionOverflowPosition(
return nullptr;
}
-CSSValue* ConsumeAnimationIterationCount(CSSParserTokenRange& range) {
+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,
+ return css_property_parser_helpers::ConsumeNumber(range, context,
kValueRangeNonNegative);
}
@@ -553,7 +561,8 @@ CSSValue* ConsumeAnimationName(CSSParserTokenRange& range,
return css_property_parser_helpers::ConsumeCustomIdent(range, context);
}
-CSSValue* ConsumeAnimationTimingFunction(CSSParserTokenRange& range) {
+CSSValue* ConsumeAnimationTimingFunction(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
CSSValueID id = range.Peek().Id();
if (id == CSSValueID::kEase || id == CSSValueID::kLinear ||
id == CSSValueID::kEaseIn || id == CSSValueID::kEaseOut ||
@@ -563,9 +572,9 @@ CSSValue* ConsumeAnimationTimingFunction(CSSParserTokenRange& range) {
CSSValueID function = range.Peek().FunctionId();
if (function == CSSValueID::kSteps)
- return ConsumeSteps(range);
+ return ConsumeSteps(range, context);
if (function == CSSValueID::kCubicBezier)
- return ConsumeCubicBezier(range);
+ return ConsumeCubicBezier(range, context);
return nullptr;
}
@@ -666,7 +675,7 @@ CSSPrimitiveValue* ConsumeLengthOrPercentCountNegative(
const CSSParserContext& context,
base::Optional<WebFeature> negative_size) {
CSSPrimitiveValue* result = ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeNonNegative,
+ range, context, kValueRangeNonNegative,
css_property_parser_helpers::UnitlessQuirk::kForbid);
if (!result && negative_size)
context.Count(*negative_size);
@@ -790,15 +799,15 @@ CSSValue* ConsumeBackgroundComponent(CSSPropertyID resolved_property,
return ConsumeBackgroundBox(range);
case CSSPropertyID::kBackgroundImage:
case CSSPropertyID::kWebkitMaskImage:
- return css_property_parser_helpers::ConsumeImageOrNone(range, &context);
+ return css_property_parser_helpers::ConsumeImageOrNone(range, context);
case CSSPropertyID::kBackgroundPositionX:
case CSSPropertyID::kWebkitMaskPositionX:
return ConsumePositionLonghand<CSSValueID::kLeft, CSSValueID::kRight>(
- range, context.Mode());
+ range, context);
case CSSPropertyID::kBackgroundPositionY:
case CSSPropertyID::kWebkitMaskPositionY:
return ConsumePositionLonghand<CSSValueID::kTop, CSSValueID::kBottom>(
- range, context.Mode());
+ range, context);
case CSSPropertyID::kBackgroundSize:
return ConsumeBackgroundSize(range, context,
WebFeature::kNegativeBackgroundSize,
@@ -808,7 +817,7 @@ CSSValue* ConsumeBackgroundComponent(CSSPropertyID resolved_property,
WebFeature::kNegativeMaskSize,
ParsingStyle::kNotLegacy);
case CSSPropertyID::kBackgroundColor:
- return css_property_parser_helpers::ConsumeColor(range, context.Mode());
+ return css_property_parser_helpers::ConsumeColor(range, context);
case CSSPropertyID::kWebkitMaskClip:
return ConsumePrefixedBackgroundBox(range, AllowTextValue::kAllow);
case CSSPropertyID::kWebkitMaskOrigin:
@@ -1019,7 +1028,7 @@ bool ConsumeBorderImageComponents(CSSParserTokenRange& range,
DefaultFill default_fill) {
do {
if (!source) {
- source = css_property_parser_helpers::ConsumeImageOrNone(range, &context);
+ source = css_property_parser_helpers::ConsumeImageOrNone(range, context);
if (source)
continue;
}
@@ -1029,16 +1038,16 @@ bool ConsumeBorderImageComponents(CSSParserTokenRange& range,
continue;
}
if (!slice) {
- slice = ConsumeBorderImageSlice(range, default_fill);
+ slice = ConsumeBorderImageSlice(range, context, default_fill);
if (slice) {
DCHECK(!width);
DCHECK(!outset);
if (css_property_parser_helpers::ConsumeSlashIncludingWhitespace(
range)) {
- width = ConsumeBorderImageWidth(range);
+ width = ConsumeBorderImageWidth(range, context);
if (css_property_parser_helpers::ConsumeSlashIncludingWhitespace(
range)) {
- outset = ConsumeBorderImageOutset(range);
+ outset = ConsumeBorderImageOutset(range, context);
if (!outset)
return false;
} else if (!width) {
@@ -1067,6 +1076,7 @@ CSSValue* ConsumeBorderImageRepeat(CSSParserTokenRange& range) {
}
CSSValue* ConsumeBorderImageSlice(CSSParserTokenRange& range,
+ const CSSParserContext& context,
DefaultFill default_fill) {
bool fill =
css_property_parser_helpers::ConsumeIdent<CSSValueID::kFill>(range);
@@ -1074,10 +1084,10 @@ CSSValue* ConsumeBorderImageSlice(CSSParserTokenRange& range,
for (size_t index = 0; index < 4; ++index) {
CSSPrimitiveValue* value = css_property_parser_helpers::ConsumePercent(
- range, kValueRangeNonNegative);
+ range, context, kValueRangeNonNegative);
if (!value) {
value = css_property_parser_helpers::ConsumeNumber(
- range, kValueRangeNonNegative);
+ range, context, kValueRangeNonNegative);
}
if (!value)
break;
@@ -1100,16 +1110,19 @@ CSSValue* ConsumeBorderImageSlice(CSSParserTokenRange& range,
fill);
}
-CSSValue* ConsumeBorderImageWidth(CSSParserTokenRange& range) {
+CSSValue* ConsumeBorderImageWidth(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
CSSValue* widths[4] = {nullptr};
CSSValue* value = nullptr;
for (size_t index = 0; index < 4; ++index) {
- value = css_property_parser_helpers::ConsumeNumber(range,
+ value = css_property_parser_helpers::ConsumeNumber(range, context,
kValueRangeNonNegative);
if (!value) {
+ CSSParserContext::ParserModeOverridingScope scope(context,
+ kHTMLStandardMode);
value = css_property_parser_helpers::ConsumeLengthOrPercent(
- range, kHTMLStandardMode, kValueRangeNonNegative,
+ range, context, kValueRangeNonNegative,
css_property_parser_helpers::UnitlessQuirk::kForbid);
}
if (!value) {
@@ -1128,16 +1141,19 @@ CSSValue* ConsumeBorderImageWidth(CSSParserTokenRange& range) {
CSSQuadValue::kSerializeAsQuad);
}
-CSSValue* ConsumeBorderImageOutset(CSSParserTokenRange& range) {
+CSSValue* ConsumeBorderImageOutset(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
CSSValue* outsets[4] = {nullptr};
CSSValue* value = nullptr;
for (size_t index = 0; index < 4; ++index) {
- value = css_property_parser_helpers::ConsumeNumber(range,
+ value = css_property_parser_helpers::ConsumeNumber(range, context,
kValueRangeNonNegative);
if (!value) {
+ CSSParserContext::ParserModeOverridingScope scope(context,
+ kHTMLStandardMode);
value = css_property_parser_helpers::ConsumeLength(
- range, kHTMLStandardMode, kValueRangeNonNegative);
+ range, context, kValueRangeNonNegative);
}
if (!value)
break;
@@ -1154,11 +1170,11 @@ CSSValue* ConsumeBorderImageOutset(CSSParserTokenRange& range) {
CSSValue* ParseBorderRadiusCorner(CSSParserTokenRange& range,
const CSSParserContext& context) {
CSSValue* parsed_value1 = css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeNonNegative);
+ range, context, kValueRangeNonNegative);
if (!parsed_value1)
return nullptr;
CSSValue* parsed_value2 = css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeNonNegative);
+ range, context, kValueRangeNonNegative);
if (!parsed_value2)
parsed_value2 = parsed_value1;
return MakeGarbageCollected<CSSValuePair>(parsed_value1, parsed_value2,
@@ -1176,20 +1192,20 @@ CSSValue* ParseBorderWidthSide(CSSParserTokenRange& range,
allow_quirky_lengths
? css_property_parser_helpers::UnitlessQuirk::kAllow
: css_property_parser_helpers::UnitlessQuirk::kForbid;
- return ConsumeBorderWidth(range, context.Mode(), unitless);
+ return ConsumeBorderWidth(range, context, unitless);
}
CSSValue* ConsumeShadow(CSSParserTokenRange& range,
- CSSParserMode css_parser_mode,
+ 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, css_parser_mode, inset_and_spread);
+ ParseSingleShadow, range, context, inset_and_spread);
}
CSSShadowValue* ParseSingleShadow(CSSParserTokenRange& range,
- CSSParserMode css_parser_mode,
+ const CSSParserContext& context,
AllowInsetAndSpread inset_and_spread) {
CSSIdentifierValue* style = nullptr;
CSSValue* color = nullptr;
@@ -1197,47 +1213,46 @@ CSSShadowValue* ParseSingleShadow(CSSParserTokenRange& range,
if (range.AtEnd())
return nullptr;
- color = css_property_parser_helpers::ConsumeColor(range, css_parser_mode);
+ color = css_property_parser_helpers::ConsumeColor(range, context);
if (range.Peek().Id() == CSSValueID::kInset) {
if (inset_and_spread != AllowInsetAndSpread::kAllow)
return nullptr;
style = css_property_parser_helpers::ConsumeIdent(range);
if (!color)
- color = css_property_parser_helpers::ConsumeColor(range, css_parser_mode);
+ color = css_property_parser_helpers::ConsumeColor(range, context);
}
CSSPrimitiveValue* horizontal_offset =
- css_property_parser_helpers::ConsumeLength(range, css_parser_mode,
+ css_property_parser_helpers::ConsumeLength(range, context,
kValueRangeAll);
if (!horizontal_offset)
return nullptr;
CSSPrimitiveValue* vertical_offset =
- css_property_parser_helpers::ConsumeLength(range, css_parser_mode,
+ css_property_parser_helpers::ConsumeLength(range, context,
kValueRangeAll);
if (!vertical_offset)
return nullptr;
CSSPrimitiveValue* blur_radius = css_property_parser_helpers::ConsumeLength(
- range, css_parser_mode, kValueRangeNonNegative);
+ range, context, kValueRangeNonNegative);
CSSPrimitiveValue* spread_distance = nullptr;
if (blur_radius) {
if (inset_and_spread == AllowInsetAndSpread::kAllow) {
spread_distance = css_property_parser_helpers::ConsumeLength(
- range, css_parser_mode, kValueRangeAll);
+ range, context, kValueRangeAll);
}
}
if (!range.AtEnd()) {
if (!color)
- color = css_property_parser_helpers::ConsumeColor(range, css_parser_mode);
+ color = css_property_parser_helpers::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);
if (!color) {
- color =
- css_property_parser_helpers::ConsumeColor(range, css_parser_mode);
+ color = css_property_parser_helpers::ConsumeColor(range, context);
}
}
}
@@ -1246,25 +1261,29 @@ CSSShadowValue* ParseSingleShadow(CSSParserTokenRange& range,
spread_distance, style, color);
}
-CSSValue* ConsumeColumnCount(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);
+ return css_property_parser_helpers::ConsumePositiveInteger(range, context);
}
-CSSValue* ConsumeColumnWidth(CSSParserTokenRange& range) {
+CSSValue* ConsumeColumnWidth(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
if (range.Peek().Id() == CSSValueID::kAuto)
return css_property_parser_helpers::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, kHTMLStandardMode, kValueRangeNonNegative);
+ range, context, kValueRangeNonNegative);
if (!column_width)
return nullptr;
return column_width;
}
bool ConsumeColumnWidthOrCount(CSSParserTokenRange& range,
+ const CSSParserContext& context,
CSSValue*& column_width,
CSSValue*& column_count) {
if (range.Peek().Id() == CSSValueID::kAuto) {
@@ -1272,12 +1291,12 @@ bool ConsumeColumnWidthOrCount(CSSParserTokenRange& range,
return true;
}
if (!column_width) {
- column_width = ConsumeColumnWidth(range);
+ column_width = ConsumeColumnWidth(range, context);
if (column_width)
return true;
}
if (!column_count)
- column_count = ConsumeColumnCount(range);
+ column_count = ConsumeColumnCount(range, context);
return column_count;
}
@@ -1286,7 +1305,7 @@ CSSValue* ConsumeGapLength(CSSParserTokenRange& range,
if (range.Peek().Id() == CSSValueID::kNormal)
return css_property_parser_helpers::ConsumeIdent(range);
return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeNonNegative);
+ range, context, kValueRangeNonNegative);
}
CSSValue* ConsumeCounter(CSSParserTokenRange& range,
@@ -1303,7 +1322,7 @@ CSSValue* ConsumeCounter(CSSParserTokenRange& range,
return nullptr;
int value = default_value;
if (CSSPrimitiveValue* counter_value =
- css_property_parser_helpers::ConsumeInteger(range))
+ css_property_parser_helpers::ConsumeInteger(range, context))
value = clampTo<int>(counter_value->GetDoubleValue());
list->Append(*MakeGarbageCollected<CSSValuePair>(
counter_name,
@@ -1323,20 +1342,20 @@ CSSValue* ConsumeFontSize(CSSParserTokenRange& range,
range.Peek().Id() <= CSSValueID::kWebkitXxxLarge)
return css_property_parser_helpers::ConsumeIdent(range);
return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeNonNegative, unitless);
+ range, context, kValueRangeNonNegative, unitless);
}
CSSValue* ConsumeLineHeight(CSSParserTokenRange& range,
- CSSParserMode css_parser_mode) {
+ const CSSParserContext& context) {
if (range.Peek().Id() == CSSValueID::kNormal)
return css_property_parser_helpers::ConsumeIdent(range);
- CSSPrimitiveValue* line_height =
- css_property_parser_helpers::ConsumeNumber(range, kValueRangeNonNegative);
+ CSSPrimitiveValue* line_height = css_property_parser_helpers::ConsumeNumber(
+ range, context, kValueRangeNonNegative);
if (line_height)
return line_height;
return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, css_parser_mode, kValueRangeNonNegative);
+ range, context, kValueRangeNonNegative);
}
CSSValueList* ConsumeFontFamily(CSSParserTokenRange& range) {
@@ -1394,12 +1413,13 @@ String ConcatenateFamilyName(CSSParserTokenRange& range) {
return builder.ToString();
}
-CSSValueList* CombineToRangeListOrNull(const CSSPrimitiveValue* range_start,
- const CSSPrimitiveValue* range_end) {
+CSSValueList* CombineToRangeList(const CSSPrimitiveValue* range_start,
+ const CSSPrimitiveValue* range_end) {
DCHECK(range_start);
DCHECK(range_end);
- if (range_end->GetFloatValue() < range_start->GetFloatValue())
- return nullptr;
+ // Reversed ranges are valid, let them pass through here and swap them in
+ // FontFace to keep serialisation of the value as specified.
+ // https://drafts.csswg.org/css-fonts/#font-prop-desc
CSSValueList* value_list = CSSValueList::CreateSpaceSeparated();
value_list->Append(*range_start);
value_list->Append(*range_end);
@@ -1413,7 +1433,7 @@ bool IsAngleWithinLimits(CSSPrimitiveValue* angle) {
}
CSSValue* ConsumeFontStyle(CSSParserTokenRange& range,
- const CSSParserMode& parser_mode) {
+ const CSSParserContext& context) {
if (range.Peek().Id() == CSSValueID::kNormal ||
range.Peek().Id() == CSSValueID::kItalic)
return css_property_parser_helpers::ConsumeIdent(range);
@@ -1425,13 +1445,13 @@ CSSValue* ConsumeFontStyle(CSSParserTokenRange& range,
css_property_parser_helpers::ConsumeIdent<CSSValueID::kOblique>(range);
CSSPrimitiveValue* start_angle = css_property_parser_helpers::ConsumeAngle(
- range, nullptr, base::nullopt, MinObliqueValue(), MaxObliqueValue());
+ range, context, base::nullopt, MinObliqueValue(), MaxObliqueValue());
if (!start_angle)
return oblique_identifier;
if (!IsAngleWithinLimits(start_angle))
return nullptr;
- if (parser_mode != kCSSFontFaceRuleMode || range.AtEnd()) {
+ if (context.Mode() != kCSSFontFaceRuleMode || range.AtEnd()) {
CSSValueList* value_list = CSSValueList::CreateSpaceSeparated();
value_list->Append(*start_angle);
return MakeGarbageCollected<cssvalue::CSSFontStyleRangeValue>(
@@ -1439,11 +1459,11 @@ CSSValue* ConsumeFontStyle(CSSParserTokenRange& range,
}
CSSPrimitiveValue* end_angle = css_property_parser_helpers::ConsumeAngle(
- range, nullptr, base::nullopt, MinObliqueValue(), MaxObliqueValue());
+ range, context, base::nullopt, MinObliqueValue(), MaxObliqueValue());
if (!end_angle || !IsAngleWithinLimits(end_angle))
return nullptr;
- CSSValueList* range_list = CombineToRangeListOrNull(start_angle, end_angle);
+ CSSValueList* range_list = CombineToRangeList(start_angle, end_angle);
if (!range_list)
return nullptr;
return MakeGarbageCollected<cssvalue::CSSFontStyleRangeValue>(
@@ -1460,31 +1480,31 @@ CSSIdentifierValue* ConsumeFontStretchKeywordOnly(CSSParserTokenRange& range) {
}
CSSValue* ConsumeFontStretch(CSSParserTokenRange& range,
- const CSSParserMode& parser_mode) {
+ const CSSParserContext& context) {
CSSIdentifierValue* parsed_keyword = ConsumeFontStretchKeywordOnly(range);
if (parsed_keyword)
return parsed_keyword;
CSSPrimitiveValue* start_percent =
- css_property_parser_helpers::ConsumePercent(range,
+ css_property_parser_helpers::ConsumePercent(range, context,
kValueRangeNonNegative);
if (!start_percent)
return nullptr;
// In a non-font-face context, more than one percentage is not allowed.
- if (parser_mode != kCSSFontFaceRuleMode || range.AtEnd())
+ if (context.Mode() != kCSSFontFaceRuleMode || range.AtEnd())
return start_percent;
CSSPrimitiveValue* end_percent = css_property_parser_helpers::ConsumePercent(
- range, kValueRangeNonNegative);
+ range, context, kValueRangeNonNegative);
if (!end_percent)
return nullptr;
- return CombineToRangeListOrNull(start_percent, end_percent);
+ return CombineToRangeList(start_percent, end_percent);
}
CSSValue* ConsumeFontWeight(CSSParserTokenRange& range,
- const CSSParserMode& parser_mode) {
+ const CSSParserContext& context) {
const CSSParserToken& token = range.Peek();
if (token.Id() >= CSSValueID::kNormal && token.Id() <= CSSValueID::kLighter)
return css_property_parser_helpers::ConsumeIdent(range);
@@ -1500,8 +1520,8 @@ CSSValue* ConsumeFontWeight(CSSParserTokenRange& range,
(token.NumericValue() < 1 || token.NumericValue() > 1000))
return nullptr;
- CSSPrimitiveValue* start_weight =
- css_property_parser_helpers::ConsumeNumber(range, kValueRangeNonNegative);
+ CSSPrimitiveValue* start_weight = css_property_parser_helpers::ConsumeNumber(
+ range, context, kValueRangeNonNegative);
if (!start_weight || start_weight->GetFloatValue() < 1 ||
start_weight->GetFloatValue() > 1000)
return nullptr;
@@ -1509,24 +1529,26 @@ CSSValue* ConsumeFontWeight(CSSParserTokenRange& range,
// In a non-font-face context, more than one number is not allowed. Return
// what we have. If there is trailing garbage, the AtEnd() check in
// CSSPropertyParser::ParseValueStart will catch that.
- if (parser_mode != kCSSFontFaceRuleMode || range.AtEnd())
+ if (context.Mode() != kCSSFontFaceRuleMode || range.AtEnd())
return start_weight;
- CSSPrimitiveValue* end_weight =
- css_property_parser_helpers::ConsumeNumber(range, kValueRangeNonNegative);
+ CSSPrimitiveValue* end_weight = css_property_parser_helpers::ConsumeNumber(
+ range, context, kValueRangeNonNegative);
if (!end_weight || end_weight->GetFloatValue() < 1 ||
end_weight->GetFloatValue() > 1000)
return nullptr;
- return CombineToRangeListOrNull(start_weight, end_weight);
+ return CombineToRangeList(start_weight, end_weight);
}
-CSSValue* ConsumeFontFeatureSettings(CSSParserTokenRange& range) {
+CSSValue* ConsumeFontFeatureSettings(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
if (range.Peek().Id() == CSSValueID::kNormal)
return css_property_parser_helpers::ConsumeIdent(range);
CSSValueList* settings = CSSValueList::CreateCommaSeparated();
do {
- CSSFontFeatureValue* font_feature_value = ConsumeFontFeatureTag(range);
+ CSSFontFeatureValue* font_feature_value =
+ ConsumeFontFeatureTag(range, context);
if (!font_feature_value)
return nullptr;
settings->Append(*font_feature_value);
@@ -1534,7 +1556,8 @@ CSSValue* ConsumeFontFeatureSettings(CSSParserTokenRange& range) {
return settings;
}
-CSSFontFeatureValue* ConsumeFontFeatureTag(CSSParserTokenRange& range) {
+CSSFontFeatureValue* ConsumeFontFeatureTag(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
// Feature tag name consists of 4-letter characters.
const unsigned kTagNameLength = 4;
@@ -1556,7 +1579,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, 0)) {
+ css_property_parser_helpers::ConsumeInteger(range, context, 0)) {
tag_value = clampTo<int>(value->GetDoubleValue());
} else if (range.Peek().Id() == CSSValueID::kOn ||
range.Peek().Id() == CSSValueID::kOff) {
@@ -1613,7 +1636,7 @@ Vector<String> ParseGridTemplateAreasColumnNames(const String& grid_row_names) {
}
CSSValue* ConsumeGridBreadth(CSSParserTokenRange& range,
- CSSParserMode css_parser_mode) {
+ const CSSParserContext& context) {
const CSSParserToken& token = range.Peek();
if (css_property_parser_helpers::IdentMatches<
CSSValueID::kMinContent, CSSValueID::kMaxContent, CSSValueID::kAuto>(
@@ -1628,18 +1651,18 @@ CSSValue* ConsumeGridBreadth(CSSParserTokenRange& range,
CSSPrimitiveValue::UnitType::kFraction);
}
return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, css_parser_mode, kValueRangeNonNegative,
+ range, context, kValueRangeNonNegative,
css_property_parser_helpers::UnitlessQuirk::kForbid);
}
CSSValue* ConsumeFitContent(CSSParserTokenRange& range,
- CSSParserMode css_parser_mode) {
+ const CSSParserContext& context) {
CSSParserTokenRange range_copy = range;
CSSParserTokenRange args =
css_property_parser_helpers::ConsumeFunction(range_copy);
CSSPrimitiveValue* length =
css_property_parser_helpers::ConsumeLengthOrPercent(
- args, css_parser_mode, kValueRangeNonNegative,
+ args, context, kValueRangeNonNegative,
css_property_parser_helpers::UnitlessQuirk::kAllow);
if (!length || !args.AtEnd())
return nullptr;
@@ -1680,7 +1703,7 @@ bool IsGridTrackFixedSized(const CSSValue& value) {
}
CSSValue* ConsumeGridTrackSize(CSSParserTokenRange& range,
- CSSParserMode css_parser_mode) {
+ 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);
@@ -1689,7 +1712,7 @@ CSSValue* ConsumeGridTrackSize(CSSParserTokenRange& range,
CSSParserTokenRange range_copy = range;
CSSParserTokenRange args =
css_property_parser_helpers::ConsumeFunction(range_copy);
- CSSValue* min_track_breadth = ConsumeGridBreadth(args, css_parser_mode);
+ CSSValue* min_track_breadth = ConsumeGridBreadth(args, context);
auto* min_track_breadth_primitive_value =
DynamicTo<CSSPrimitiveValue>(min_track_breadth);
if (!min_track_breadth ||
@@ -1697,7 +1720,7 @@ CSSValue* ConsumeGridTrackSize(CSSParserTokenRange& range,
min_track_breadth_primitive_value->IsFlex()) ||
!css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args))
return nullptr;
- CSSValue* max_track_breadth = ConsumeGridBreadth(args, css_parser_mode);
+ CSSValue* max_track_breadth = ConsumeGridBreadth(args, context);
if (!max_track_breadth || !args.AtEnd())
return nullptr;
range = range_copy;
@@ -1708,9 +1731,9 @@ CSSValue* ConsumeGridTrackSize(CSSParserTokenRange& range,
}
if (token.FunctionId() == CSSValueID::kFitContent)
- return ConsumeFitContent(range, css_parser_mode);
+ return ConsumeFitContent(range, context);
- return ConsumeGridBreadth(range, css_parser_mode);
+ return ConsumeGridBreadth(range, context);
}
CSSCustomIdentValue* ConsumeCustomIdentForGridLine(
@@ -1747,7 +1770,6 @@ CSSGridLineNamesValue* ConsumeGridLineNames(
bool ConsumeGridTrackRepeatFunction(CSSParserTokenRange& range,
const CSSParserContext& context,
- CSSParserMode css_parser_mode,
CSSValueList& list,
bool& is_auto_repeat,
bool& all_tracks_are_fixed_sized) {
@@ -1765,7 +1787,7 @@ bool ConsumeGridTrackRepeatFunction(CSSParserTokenRange& range,
} else {
// TODO(rob.buis): a consumeIntegerRaw would be more efficient here.
CSSPrimitiveValue* repetition =
- css_property_parser_helpers::ConsumePositiveInteger(args);
+ css_property_parser_helpers::ConsumePositiveInteger(args, context);
if (!repetition)
return false;
repetitions =
@@ -1780,7 +1802,7 @@ bool ConsumeGridTrackRepeatFunction(CSSParserTokenRange& range,
size_t number_of_tracks = 0;
while (!args.AtEnd()) {
- CSSValue* track_size = ConsumeGridTrackSize(args, css_parser_mode);
+ CSSValue* track_size = ConsumeGridTrackSize(args, context);
if (!track_size)
return false;
if (all_tracks_are_fixed_sized)
@@ -1847,7 +1869,7 @@ bool ConsumeGridTemplateRowsAndAreasAndColumns(bool important,
++row_count;
// Handle template-rows's track-size.
- CSSValue* value = ConsumeGridTrackSize(range, context.Mode());
+ CSSValue* value = ConsumeGridTrackSize(range, context);
if (!value)
value = CSSIdentifierValue::Create(CSSValueID::kAuto);
template_rows_value_list->Append(*value);
@@ -1863,7 +1885,7 @@ bool ConsumeGridTemplateRowsAndAreasAndColumns(bool important,
if (!css_property_parser_helpers::ConsumeSlashIncludingWhitespace(range))
return false;
template_columns = ConsumeGridTrackList(
- range, context, context.Mode(), TrackListType::kGridTemplateNoRepeat);
+ range, context, TrackListType::kGridTemplateNoRepeat);
if (!template_columns || !range.AtEnd())
return false;
} else {
@@ -1884,7 +1906,7 @@ CSSValue* ConsumeGridLine(CSSParserTokenRange& range,
CSSIdentifierValue* span_value = nullptr;
CSSCustomIdentValue* grid_line_name = nullptr;
CSSPrimitiveValue* numeric_value =
- css_property_parser_helpers::ConsumeInteger(range);
+ css_property_parser_helpers::ConsumeInteger(range, context);
if (numeric_value) {
grid_line_name = ConsumeCustomIdentForGridLine(range, context);
span_value =
@@ -1893,14 +1915,18 @@ CSSValue* ConsumeGridLine(CSSParserTokenRange& range,
span_value =
css_property_parser_helpers::ConsumeIdent<CSSValueID::kSpan>(range);
if (span_value) {
- numeric_value = css_property_parser_helpers::ConsumeInteger(range);
+ numeric_value =
+ css_property_parser_helpers::ConsumeInteger(range, context);
grid_line_name = ConsumeCustomIdentForGridLine(range, context);
- if (!numeric_value)
- numeric_value = css_property_parser_helpers::ConsumeInteger(range);
+ if (!numeric_value) {
+ numeric_value =
+ css_property_parser_helpers::ConsumeInteger(range, context);
+ }
} else {
grid_line_name = ConsumeCustomIdentForGridLine(range, context);
if (grid_line_name) {
- numeric_value = css_property_parser_helpers::ConsumeInteger(range);
+ numeric_value =
+ css_property_parser_helpers::ConsumeInteger(range, context);
span_value =
css_property_parser_helpers::ConsumeIdent<CSSValueID::kSpan>(range);
if (!span_value && !numeric_value)
@@ -1938,7 +1964,6 @@ CSSValue* ConsumeGridLine(CSSParserTokenRange& range,
CSSValue* ConsumeGridTrackList(CSSParserTokenRange& range,
const CSSParserContext& context,
- CSSParserMode css_parser_mode,
TrackListType track_list_type) {
bool allow_grid_line_names = track_list_type != TrackListType::kGridAuto;
CSSValueList* values = CSSValueList::CreateSpaceSeparated();
@@ -1956,14 +1981,14 @@ CSSValue* ConsumeGridTrackList(CSSParserTokenRange& range,
if (range.Peek().FunctionId() == CSSValueID::kRepeat) {
if (!allow_repeat)
return nullptr;
- if (!ConsumeGridTrackRepeatFunction(range, context, css_parser_mode,
- *values, is_auto_repeat,
+ if (!ConsumeGridTrackRepeatFunction(range, context, *values,
+ is_auto_repeat,
all_tracks_are_fixed_sized))
return nullptr;
if (is_auto_repeat && seen_auto_repeat)
return nullptr;
seen_auto_repeat = seen_auto_repeat || is_auto_repeat;
- } else if (CSSValue* value = ConsumeGridTrackSize(range, css_parser_mode)) {
+ } else if (CSSValue* value = ConsumeGridTrackSize(range, context)) {
if (all_tracks_are_fixed_sized)
all_tracks_are_fixed_sized = IsGridTrackFixedSized(*value);
values->Append(*value);
@@ -2050,12 +2075,10 @@ bool ParseGridTemplateAreasRow(const String& grid_row_names,
}
CSSValue* ConsumeGridTemplatesRowsOrColumns(CSSParserTokenRange& range,
- const CSSParserContext& context,
- CSSParserMode css_parser_mode) {
+ const CSSParserContext& context) {
if (range.Peek().Id() == CSSValueID::kNone)
return css_property_parser_helpers::ConsumeIdent(range);
- return ConsumeGridTrackList(range, context, css_parser_mode,
- TrackListType::kGridTemplate);
+ return ConsumeGridTrackList(range, context, TrackListType::kGridTemplate);
}
bool ConsumeGridItemPositionShorthand(bool important,
@@ -2110,15 +2133,14 @@ bool ConsumeGridTemplateShorthand(bool important,
// 2- <grid-template-rows> / <grid-template-columns>
if (!template_rows) {
- template_rows = ConsumeGridTrackList(range, context, context.Mode(),
- TrackListType::kGridTemplate);
+ template_rows =
+ ConsumeGridTrackList(range, context, TrackListType::kGridTemplate);
}
if (template_rows) {
if (!css_property_parser_helpers::ConsumeSlashIncludingWhitespace(range))
return false;
- template_columns =
- ConsumeGridTemplatesRowsOrColumns(range, context, context.Mode());
+ template_columns = ConsumeGridTemplatesRowsOrColumns(range, context);
if (!template_columns || !range.AtEnd())
return false;
@@ -2235,7 +2257,7 @@ CSSValue* ConsumeRay(CSSParserTokenRange& range,
while (!function_args.AtEnd()) {
if (!angle) {
angle = css_property_parser_helpers::ConsumeAngle(
- function_args, &context, base::Optional<WebFeature>());
+ function_args, context, base::Optional<WebFeature>());
if (angle)
continue;
}
@@ -2269,7 +2291,7 @@ CSSValue* ConsumeMaxWidthOrHeight(
ValidWidthOrHeightKeyword(range.Peek().Id(), context))
return css_property_parser_helpers::ConsumeIdent(range);
return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeNonNegative, unitless);
+ range, context, kValueRangeNonNegative, unitless);
}
CSSValue* ConsumeWidthOrHeight(
@@ -2280,24 +2302,26 @@ CSSValue* ConsumeWidthOrHeight(
ValidWidthOrHeightKeyword(range.Peek().Id(), context))
return css_property_parser_helpers::ConsumeIdent(range);
return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeNonNegative, unitless);
+ range, context, kValueRangeNonNegative, unitless);
}
CSSValue* ConsumeMarginOrOffset(
CSSParserTokenRange& range,
- CSSParserMode css_parser_mode,
+ const CSSParserContext& context,
css_property_parser_helpers::UnitlessQuirk unitless) {
if (range.Peek().Id() == CSSValueID::kAuto)
return css_property_parser_helpers::ConsumeIdent(range);
return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, css_parser_mode, kValueRangeAll, unitless);
+ range, context, kValueRangeAll, unitless);
}
-CSSValue* ConsumeScrollPadding(CSSParserTokenRange& range) {
+CSSValue* ConsumeScrollPadding(CSSParserTokenRange& range,
+ const CSSParserContext& context) {
if (range.Peek().Id() == CSSValueID::kAuto)
return css_property_parser_helpers::ConsumeIdent(range);
+ CSSParserContext::ParserModeOverridingScope scope(context, kHTMLStandardMode);
return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, kHTMLStandardMode, kValueRangeNonNegative,
+ range, context, kValueRangeNonNegative,
css_property_parser_helpers::UnitlessQuirk::kForbid);
}
@@ -2327,7 +2351,7 @@ CSSValue* ConsumePathOrNone(CSSParserTokenRange& range) {
CSSValue* ConsumeOffsetRotate(CSSParserTokenRange& range,
const CSSParserContext& context) {
CSSValue* angle = css_property_parser_helpers::ConsumeAngle(
- range, &context, base::Optional<WebFeature>());
+ range, context, base::Optional<WebFeature>());
CSSValue* keyword =
css_property_parser_helpers::ConsumeIdent<CSSValueID::kAuto,
CSSValueID::kReverse>(range);
@@ -2336,7 +2360,7 @@ CSSValue* ConsumeOffsetRotate(CSSParserTokenRange& range,
if (!angle) {
angle = css_property_parser_helpers::ConsumeAngle(
- range, &context, base::Optional<WebFeature>());
+ range, context, base::Optional<WebFeature>());
}
CSSValueList* list = CSSValueList::CreateSpaceSeparated();
@@ -2350,7 +2374,7 @@ CSSValue* ConsumeOffsetRotate(CSSParserTokenRange& range,
bool ConsumeRadii(CSSValue* horizontal_radii[4],
CSSValue* vertical_radii[4],
CSSParserTokenRange& range,
- CSSParserMode css_parser_mode,
+ const CSSParserContext& context,
bool use_legacy_parsing) {
unsigned horizontal_value_count = 0;
for (; horizontal_value_count < 4 && !range.AtEnd() &&
@@ -2358,7 +2382,7 @@ bool ConsumeRadii(CSSValue* horizontal_radii[4],
++horizontal_value_count) {
horizontal_radii[horizontal_value_count] =
css_property_parser_helpers::ConsumeLengthOrPercent(
- range, css_parser_mode, kValueRangeNonNegative);
+ range, context, kValueRangeNonNegative);
if (!horizontal_radii[horizontal_value_count])
return false;
}
@@ -2381,7 +2405,7 @@ bool ConsumeRadii(CSSValue* horizontal_radii[4],
return false;
for (unsigned i = 0; i < 4 && !range.AtEnd(); ++i) {
vertical_radii[i] = css_property_parser_helpers::ConsumeLengthOrPercent(
- range, css_parser_mode, kValueRangeNonNegative);
+ range, context, kValueRangeNonNegative);
if (!vertical_radii[i])
return false;
}
@@ -2479,14 +2503,14 @@ CSSValue* ConsumeTransformValue(CSSParserTokenRange& range,
case CSSValueID::kSkewY:
case CSSValueID::kSkew:
parsed_value = css_property_parser_helpers::ConsumeAngle(
- args, &context, WebFeature::kUnitlessZeroAngleTransform);
+ args, context, WebFeature::kUnitlessZeroAngleTransform);
if (!parsed_value)
return nullptr;
if (function_id == CSSValueID::kSkew &&
css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args)) {
transform_value->Append(*parsed_value);
parsed_value = css_property_parser_helpers::ConsumeAngle(
- args, &context, WebFeature::kUnitlessZeroAngleTransform);
+ args, context, WebFeature::kUnitlessZeroAngleTransform);
if (!parsed_value)
return nullptr;
}
@@ -2495,15 +2519,15 @@ CSSValue* ConsumeTransformValue(CSSParserTokenRange& range,
case CSSValueID::kScaleY:
case CSSValueID::kScaleZ:
case CSSValueID::kScale:
- parsed_value =
- css_property_parser_helpers::ConsumeNumber(args, kValueRangeAll);
+ parsed_value = css_property_parser_helpers::ConsumeNumber(args, context,
+ kValueRangeAll);
if (!parsed_value)
return nullptr;
if (function_id == CSSValueID::kScale &&
css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args)) {
transform_value->Append(*parsed_value);
- parsed_value =
- css_property_parser_helpers::ConsumeNumber(args, kValueRangeAll);
+ parsed_value = css_property_parser_helpers::ConsumeNumber(
+ args, context, kValueRangeAll);
if (!parsed_value)
return nullptr;
}
@@ -2518,45 +2542,45 @@ CSSValue* ConsumeTransformValue(CSSParserTokenRange& range,
case CSSValueID::kTranslateY:
case CSSValueID::kTranslate:
parsed_value = css_property_parser_helpers::ConsumeLengthOrPercent(
- args, context.Mode(), kValueRangeAll);
+ args, context, kValueRangeAll);
if (!parsed_value)
return nullptr;
if (function_id == CSSValueID::kTranslate &&
css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args)) {
transform_value->Append(*parsed_value);
parsed_value = css_property_parser_helpers::ConsumeLengthOrPercent(
- args, context.Mode(), kValueRangeAll);
+ args, context, kValueRangeAll);
if (!parsed_value)
return nullptr;
}
break;
case CSSValueID::kTranslateZ:
- parsed_value = css_property_parser_helpers::ConsumeLength(
- args, context.Mode(), kValueRangeAll);
+ parsed_value = css_property_parser_helpers::ConsumeLength(args, context,
+ kValueRangeAll);
break;
case CSSValueID::kMatrix:
case CSSValueID::kMatrix3d:
- if (!ConsumeNumbers(args, transform_value,
+ if (!ConsumeNumbers(args, context, transform_value,
(function_id == CSSValueID::kMatrix3d) ? 16 : 6)) {
return nullptr;
}
break;
case CSSValueID::kScale3d:
- if (!ConsumeNumbers(args, transform_value, 3))
+ if (!ConsumeNumbers(args, context, transform_value, 3))
return nullptr;
break;
case CSSValueID::kRotate3d:
- if (!ConsumeNumbers(args, transform_value, 3) ||
+ if (!ConsumeNumbers(args, context, transform_value, 3) ||
!css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args)) {
return nullptr;
}
parsed_value = css_property_parser_helpers::ConsumeAngle(
- args, &context, WebFeature::kUnitlessZeroAngleTransform);
+ args, context, WebFeature::kUnitlessZeroAngleTransform);
if (!parsed_value)
return nullptr;
break;
case CSSValueID::kTranslate3d:
- if (!ConsumeTranslate3d(args, context.Mode(), transform_value))
+ if (!ConsumeTranslate3d(args, context, transform_value))
return nullptr;
break;
default:
@@ -2594,12 +2618,14 @@ CSSValue* ConsumeTransitionProperty(CSSParserTokenRange& range,
return nullptr;
if (token.Id() == CSSValueID::kNone)
return css_property_parser_helpers::ConsumeIdent(range);
- CSSPropertyID unresolved_property = token.ParseAsUnresolvedCSSPropertyID();
+ const auto* execution_context = context.GetExecutionContext();
+ CSSPropertyID unresolved_property =
+ token.ParseAsUnresolvedCSSPropertyID(execution_context);
if (unresolved_property != CSSPropertyID::kInvalid &&
unresolved_property != CSSPropertyID::kVariable) {
#if DCHECK_IS_ON()
DCHECK(CSSProperty::Get(resolveCSSPropertyID(unresolved_property))
- .IsWebExposed());
+ .IsWebExposed(execution_context));
#endif
range.ConsumeIncludingWhitespace();
return MakeGarbageCollected<CSSCustomIdentValue>(unresolved_property);
@@ -2625,15 +2651,15 @@ 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.Mode(),
+ return css_property_parser_helpers::ConsumeColor(range, context,
allow_quirky_colors);
}
CSSValue* ConsumeBorderWidth(
CSSParserTokenRange& range,
- CSSParserMode css_parser_mode,
+ const CSSParserContext& context,
css_property_parser_helpers::UnitlessQuirk unitless) {
- return css_property_parser_helpers::ConsumeLineWidth(range, css_parser_mode,
+ return css_property_parser_helpers::ConsumeLineWidth(range, context,
unitless);
}
@@ -2643,7 +2669,7 @@ CSSValue* ParseSpacing(CSSParserTokenRange& range,
return css_property_parser_helpers::ConsumeIdent(range);
// TODO(timloh): allow <percentage>s in word-spacing.
return css_property_parser_helpers::ConsumeLength(
- range, context.Mode(), kValueRangeAll,
+ range, context, kValueRangeAll,
css_property_parser_helpers::UnitlessQuirk::kAllow);
}
@@ -2652,14 +2678,13 @@ CSSValue* ParsePaintStroke(CSSParserTokenRange& range,
if (range.Peek().Id() == CSSValueID::kNone)
return css_property_parser_helpers::ConsumeIdent(range);
cssvalue::CSSURIValue* url =
- css_property_parser_helpers::ConsumeUrl(range, &context);
+ css_property_parser_helpers::ConsumeUrl(range, context);
if (url) {
CSSValue* parsed_value = nullptr;
if (range.Peek().Id() == CSSValueID::kNone) {
parsed_value = css_property_parser_helpers::ConsumeIdent(range);
} else {
- parsed_value =
- css_property_parser_helpers::ConsumeColor(range, context.Mode());
+ parsed_value = css_property_parser_helpers::ConsumeColor(range, context);
}
if (parsed_value) {
CSSValueList* values = CSSValueList::CreateSpaceSeparated();
@@ -2669,7 +2694,7 @@ CSSValue* ParsePaintStroke(CSSParserTokenRange& range,
}
return url;
}
- return css_property_parser_helpers::ConsumeColor(range, context.Mode());
+ return css_property_parser_helpers::ConsumeColor(range, context);
}
css_property_parser_helpers::UnitlessQuirk UnitlessUnlessShorthand(
@@ -2679,16 +2704,5 @@ css_property_parser_helpers::UnitlessQuirk UnitlessUnlessShorthand(
: css_property_parser_helpers::UnitlessQuirk::kForbid;
}
-CSSValue* ConsumeIntrinsicLength(CSSParserTokenRange& range,
- const CSSParserContext& context) {
- if (css_property_parser_helpers::IdentMatches<CSSValueID::kLegacy,
- CSSValueID::kAuto>(
- range.Peek().Id())) {
- return css_property_parser_helpers::ConsumeIdent(range);
- }
- return css_property_parser_helpers::ConsumeLength(range, context.Mode(),
- kValueRangeNonNegative);
-}
-
} // namespace css_parsing_utils
} // namespace blink
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 f95d8e87a3c..1ffeb8471f0 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
@@ -47,7 +47,7 @@ bool IsSelfPositionOrLeftOrRightKeyword(CSSValueID);
bool IsContentPositionKeyword(CSSValueID);
bool IsContentPositionOrLeftOrRightKeyword(CSSValueID);
-CSSValue* ConsumeScrollOffset(CSSParserTokenRange&);
+CSSValue* ConsumeScrollOffset(CSSParserTokenRange&, const CSSParserContext&);
CSSValue* ConsumeSelfPositionOverflowPosition(CSSParserTokenRange&,
IsPositionKeyword);
CSSValue* ConsumeSimplifiedDefaultPosition(CSSParserTokenRange&,
@@ -59,11 +59,13 @@ CSSValue* ConsumeContentDistributionOverflowPosition(CSSParserTokenRange&,
CSSValue* ConsumeSimplifiedContentPosition(CSSParserTokenRange&,
IsPositionKeyword);
-CSSValue* ConsumeAnimationIterationCount(CSSParserTokenRange&);
+CSSValue* ConsumeAnimationIterationCount(CSSParserTokenRange&,
+ const CSSParserContext&);
CSSValue* ConsumeAnimationName(CSSParserTokenRange&,
const CSSParserContext&,
bool allow_quoted_name);
-CSSValue* ConsumeAnimationTimingFunction(CSSParserTokenRange&);
+CSSValue* ConsumeAnimationTimingFunction(CSSParserTokenRange&,
+ const CSSParserContext&);
bool ConsumeAnimationShorthand(
const StylePropertyShorthand&,
HeapVector<Member<CSSValueList>, kMaxNumAnimationLonghands>&,
@@ -117,9 +119,13 @@ bool ConsumeBorderImageComponents(CSSParserTokenRange&,
CSSValue*& repeat,
DefaultFill);
CSSValue* ConsumeBorderImageRepeat(CSSParserTokenRange&);
-CSSValue* ConsumeBorderImageSlice(CSSParserTokenRange&, DefaultFill);
-CSSValue* ConsumeBorderImageWidth(CSSParserTokenRange&);
-CSSValue* ConsumeBorderImageOutset(CSSParserTokenRange&);
+CSSValue* ConsumeBorderImageSlice(CSSParserTokenRange&,
+ const CSSParserContext&,
+ DefaultFill);
+CSSValue* ConsumeBorderImageWidth(CSSParserTokenRange&,
+ const CSSParserContext&);
+CSSValue* ConsumeBorderImageOutset(CSSParserTokenRange&,
+ const CSSParserContext&);
CSSValue* ParseBorderRadiusCorner(CSSParserTokenRange&,
const CSSParserContext&);
@@ -128,15 +134,18 @@ CSSValue* ParseBorderWidthSide(CSSParserTokenRange&,
const CSSParserLocalContext&);
CSSValue* ConsumeShadow(CSSParserTokenRange&,
- CSSParserMode,
+ const CSSParserContext&,
AllowInsetAndSpread);
CSSShadowValue* ParseSingleShadow(CSSParserTokenRange&,
- CSSParserMode,
+ const CSSParserContext&,
AllowInsetAndSpread);
-CSSValue* ConsumeColumnCount(CSSParserTokenRange&);
-CSSValue* ConsumeColumnWidth(CSSParserTokenRange&);
-bool ConsumeColumnWidthOrCount(CSSParserTokenRange&, CSSValue*&, CSSValue*&);
+CSSValue* ConsumeColumnCount(CSSParserTokenRange&, const CSSParserContext&);
+CSSValue* ConsumeColumnWidth(CSSParserTokenRange&, const CSSParserContext&);
+bool ConsumeColumnWidthOrCount(CSSParserTokenRange&,
+ const CSSParserContext&,
+ CSSValue*&,
+ CSSValue*&);
CSSValue* ConsumeGapLength(CSSParserTokenRange&, const CSSParserContext&);
CSSValue* ConsumeCounter(CSSParserTokenRange&, const CSSParserContext&, int);
@@ -147,32 +156,32 @@ CSSValue* ConsumeFontSize(
css_property_parser_helpers::UnitlessQuirk =
css_property_parser_helpers::UnitlessQuirk::kForbid);
-CSSValue* ConsumeLineHeight(CSSParserTokenRange&, CSSParserMode);
+CSSValue* ConsumeLineHeight(CSSParserTokenRange&, const CSSParserContext&);
CSSValueList* ConsumeFontFamily(CSSParserTokenRange&);
CSSValue* ConsumeGenericFamily(CSSParserTokenRange&);
CSSValue* ConsumeFamilyName(CSSParserTokenRange&);
String ConcatenateFamilyName(CSSParserTokenRange&);
CSSIdentifierValue* ConsumeFontStretchKeywordOnly(CSSParserTokenRange&);
-CSSValue* ConsumeFontStretch(CSSParserTokenRange&, const CSSParserMode&);
-CSSValue* ConsumeFontStyle(CSSParserTokenRange&, const CSSParserMode&);
-CSSValue* ConsumeFontWeight(CSSParserTokenRange&, const CSSParserMode&);
-CSSValue* ConsumeFontFeatureSettings(CSSParserTokenRange&);
-cssvalue::CSSFontFeatureValue* ConsumeFontFeatureTag(CSSParserTokenRange&);
+CSSValue* ConsumeFontStretch(CSSParserTokenRange&, const CSSParserContext&);
+CSSValue* ConsumeFontStyle(CSSParserTokenRange&, const CSSParserContext&);
+CSSValue* ConsumeFontWeight(CSSParserTokenRange&, const CSSParserContext&);
+CSSValue* ConsumeFontFeatureSettings(CSSParserTokenRange&,
+ const CSSParserContext&);
+cssvalue::CSSFontFeatureValue* ConsumeFontFeatureTag(CSSParserTokenRange&,
+ const CSSParserContext&);
CSSIdentifierValue* ConsumeFontVariantCSS21(CSSParserTokenRange&);
CSSValue* ConsumeGridLine(CSSParserTokenRange&, const CSSParserContext&);
CSSValue* ConsumeGridTrackList(CSSParserTokenRange&,
const CSSParserContext&,
- CSSParserMode,
TrackListType);
bool ParseGridTemplateAreasRow(const WTF::String& grid_row_names,
NamedGridAreaMap&,
const size_t row_count,
size_t& column_count);
CSSValue* ConsumeGridTemplatesRowsOrColumns(CSSParserTokenRange&,
- const CSSParserContext&,
- CSSParserMode);
+ const CSSParserContext&);
bool ConsumeGridItemPositionShorthand(bool important,
CSSParserTokenRange&,
const CSSParserContext&,
@@ -205,9 +214,9 @@ CSSValue* ConsumeWidthOrHeight(
css_property_parser_helpers::UnitlessQuirk::kForbid);
CSSValue* ConsumeMarginOrOffset(CSSParserTokenRange&,
- CSSParserMode,
+ const CSSParserContext&,
css_property_parser_helpers::UnitlessQuirk);
-CSSValue* ConsumeScrollPadding(CSSParserTokenRange&);
+CSSValue* ConsumeScrollPadding(CSSParserTokenRange&, const CSSParserContext&);
CSSValue* ConsumeOffsetPath(CSSParserTokenRange&, const CSSParserContext&);
CSSValue* ConsumePathOrNone(CSSParserTokenRange&);
CSSValue* ConsumeOffsetRotate(CSSParserTokenRange&, const CSSParserContext&);
@@ -216,7 +225,7 @@ CSSValue* ConsumeBasicShape(CSSParserTokenRange&, const CSSParserContext&);
bool ConsumeRadii(CSSValue* horizontal_radii[4],
CSSValue* vertical_radii[4],
CSSParserTokenRange&,
- CSSParserMode,
+ const CSSParserContext&,
bool use_legacy_parsing);
CSSValue* ConsumeTextDecorationLine(CSSParserTokenRange&);
@@ -235,7 +244,7 @@ CSSValue* ConsumeBorderColorSide(CSSParserTokenRange&,
const CSSParserContext&,
const CSSParserLocalContext&);
CSSValue* ConsumeBorderWidth(CSSParserTokenRange&,
- CSSParserMode,
+ const CSSParserContext&,
css_property_parser_helpers::UnitlessQuirk);
CSSValue* ParsePaintStroke(CSSParserTokenRange&, const CSSParserContext&);
CSSValue* ParseSpacing(CSSParserTokenRange&, const CSSParserContext&);
@@ -245,7 +254,7 @@ css_property_parser_helpers::UnitlessQuirk UnitlessUnlessShorthand(
template <CSSValueID start, CSSValueID end>
CSSValue* ConsumePositionLonghand(CSSParserTokenRange& range,
- CSSParserMode css_parser_mode) {
+ const CSSParserContext& context) {
if (range.Peek().GetType() == kIdentToken) {
CSSValueID id = range.Peek().Id();
int percent;
@@ -261,12 +270,10 @@ CSSValue* ConsumePositionLonghand(CSSParserTokenRange& range,
return CSSNumericLiteralValue::Create(
percent, CSSPrimitiveValue::UnitType::kPercentage);
}
- return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, css_parser_mode, kValueRangeAll);
+ return css_property_parser_helpers::ConsumeLengthOrPercent(range, context,
+ kValueRangeAll);
}
-CSSValue* ConsumeIntrinsicLength(CSSParserTokenRange&, const CSSParserContext&);
-
} // namespace css_parsing_utils
} // namespace blink
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 7b9aad46a4a..8ac05ca0a7d 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
@@ -16,7 +16,7 @@ TEST(CSSParsingUtilsTest, BasicShapeUseCount) {
Document& document = dummy_page_holder->GetDocument();
WebFeature feature = WebFeature::kCSSBasicShape;
EXPECT_FALSE(document.IsUseCounted(feature));
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<style>span { shape-outside: circle(); }</style>");
EXPECT_TRUE(document.IsUseCounted(feature));
}
diff --git a/chromium/third_party/blink/renderer/core/css/properties/css_property.cc b/chromium/third_party/blink/renderer/core/css/properties/css_property.cc
index 0c0540f2c19..af17d6cc31b 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/css_property.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/css_property.cc
@@ -53,12 +53,13 @@ const CSSValue* CSSProperty::CSSValueFromComputedStyle(
}
void CSSProperty::FilterWebExposedCSSPropertiesIntoVector(
+ const ExecutionContext* execution_context,
const CSSPropertyID* properties,
size_t propertyCount,
Vector<const CSSProperty*>& outVector) {
for (unsigned i = 0; i < propertyCount; i++) {
const CSSProperty& property = Get(properties[i]);
- if (property.IsWebExposed())
+ if (property.IsWebExposed(execution_context))
outVector.push_back(&property);
}
}
diff --git a/chromium/third_party/blink/renderer/core/css/properties/css_property.h b/chromium/third_party/blink/renderer/core/css/properties/css_property.h
index a3d418cab44..0ecc8b561ea 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/css_property.h
+++ b/chromium/third_party/blink/renderer/core/css/properties/css_property.h
@@ -19,11 +19,14 @@ namespace blink {
class ComputedStyle;
class CrossThreadStyleValue;
+class ExecutionContext;
class LayoutObject;
class SVGComputedStyle;
class CORE_EXPORT CSSProperty : public CSSUnresolvedProperty {
public:
+ using Flags = uint16_t;
+
static const CSSProperty& Get(CSSPropertyID);
// For backwards compatibility when passing around CSSUnresolvedProperty
@@ -37,6 +40,7 @@ class CORE_EXPORT CSSProperty : public CSSUnresolvedProperty {
bool IDEquals(CSSPropertyID id) const { return PropertyID() == id; }
bool IsResolvedProperty() const override { return true; }
+ Flags GetFlags() const { return flags_; }
bool IsInterpolable() const { return flags_ & kInterpolable; }
bool IsCompositableProperty() const { return flags_ & kCompositableProperty; }
bool IsDescriptor() const { return flags_ & kDescriptor; }
@@ -49,6 +53,11 @@ class CORE_EXPORT CSSProperty : public CSSUnresolvedProperty {
bool IsAffectedByForcedColors() const {
return flags_ & kIsAffectedByForcedColors;
}
+ bool IsValidForFirstLetter() const { return flags_ & kValidForFirstLetter; }
+ bool IsValidForCue() const { return flags_ & kValidForCue; }
+ bool IsValidForMarker() const { return flags_ & kValidForMarker; }
+ bool IsSurrogate() const { return flags_ & kSurrogate; }
+ bool AffectsFont() const { return flags_ & kAffectsFont; }
bool IsRepeated() const { return repetition_separator_ != '\0'; }
char RepetitionSeparator() const { return repetition_separator_; }
@@ -82,13 +91,18 @@ class CORE_EXPORT CSSProperty : public CSSUnresolvedProperty {
}
virtual const CSSProperty* GetVisitedProperty() const { return nullptr; }
virtual const CSSProperty* GetUnvisitedProperty() const { return nullptr; }
+
+ virtual const CSSProperty* SurrogateFor(TextDirection, WritingMode) const {
+ return nullptr;
+ }
+
static void FilterWebExposedCSSPropertiesIntoVector(
+ const ExecutionContext*,
const CSSPropertyID*,
size_t length,
Vector<const CSSProperty*>&);
- protected:
- enum Flag : uint16_t {
+ enum Flag : Flags {
kInterpolable = 1 << 0,
kCompositableProperty = 1 << 1,
kDescriptor = 1 << 2,
@@ -102,11 +116,25 @@ class CORE_EXPORT CSSProperty : public CSSUnresolvedProperty {
// seen by CSSOM, which is represented by the unvisited property).
kVisited = 1 << 7,
kInternal = 1 << 8,
- kIsAffectedByForcedColors = 1 << 9
+ kIsAffectedByForcedColors = 1 << 9,
+ // Animation properties have this flag set. (I.e. longhands of the
+ // 'animation' and 'transition' shorthands).
+ kAnimation = 1 << 10,
+ // https://drafts.csswg.org/css-pseudo-4/#first-letter-styling
+ kValidForFirstLetter = 1 << 11,
+ // https://w3c.github.io/webvtt/#the-cue-pseudo-element
+ kValidForCue = 1 << 12,
+ // https://drafts.csswg.org/css-pseudo-4/#marker-pseudo
+ kValidForMarker = 1 << 13,
+ // A surrogate is a (non-alias) property which acts like another property,
+ // for example -webkit-writing-mode is a surrogate for writing-mode, and
+ // inline-size is a surrogate for either width or height.
+ kSurrogate = 1 << 14,
+ kAffectsFont = 1 << 15,
};
constexpr CSSProperty(CSSPropertyID property_id,
- uint16_t flags,
+ Flags flags,
char repetition_separator)
: CSSUnresolvedProperty(),
property_id_(property_id),
@@ -115,7 +143,7 @@ class CORE_EXPORT CSSProperty : public CSSUnresolvedProperty {
private:
CSSPropertyID property_id_;
- uint16_t flags_;
+ Flags flags_;
char repetition_separator_;
};
diff --git a/chromium/third_party/blink/renderer/core/css/properties/css_property_ref.cc b/chromium/third_party/blink/renderer/core/css/properties/css_property_ref.cc
index bd83e45f25a..0cd1fdcae0a 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/css_property_ref.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/css_property_ref.cc
@@ -9,7 +9,8 @@
namespace blink {
CSSPropertyRef::CSSPropertyRef(const String& name, const Document& document)
- : property_id_(unresolvedCSSPropertyID(name)) {
+ : property_id_(
+ unresolvedCSSPropertyID(document.GetExecutionContext(), name)) {
if (property_id_ == CSSPropertyID::kVariable)
custom_property_ = CustomProperty(AtomicString(name), document);
}
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 0aead62b8b1..f3e986218fb 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(blink::Visitor* visitor) { visitor->Trace(custom_property_); }
+ void Trace(Visitor* visitor) { 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 a281633b8b1..0ea0edf0642 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
@@ -18,7 +18,8 @@ class CSSPropertyTest : public PageTestBase {};
TEST_F(CSSPropertyTest, VisitedPropertiesAreNotWebExposed) {
for (CSSPropertyID property_id : CSSPropertyIDList()) {
const CSSProperty& property = CSSProperty::Get(property_id);
- EXPECT_TRUE(!property.IsVisited() || !property.IsWebExposed());
+ EXPECT_TRUE(!property.IsVisited() ||
+ !property.IsWebExposed(GetDocument().GetExecutionContext()));
}
}
@@ -40,7 +41,7 @@ TEST_F(CSSPropertyTest, GetUnvisitedPropertyFromVisited) {
TEST_F(CSSPropertyTest, InternalEffectiveZoomNotWebExposed) {
const CSSProperty& property = GetCSSPropertyInternalEffectiveZoom();
- EXPECT_FALSE(property.IsWebExposed());
+ EXPECT_FALSE(property.IsWebExposed(GetDocument().GetExecutionContext()));
}
TEST_F(CSSPropertyTest, InternalEffectiveZoomCanBeParsed) {
@@ -87,4 +88,18 @@ TEST_F(CSSPropertyTest, VisitedPropertiesCanParseValues) {
EXPECT_GT(num_visited, 0u);
}
+TEST_F(CSSPropertyTest, Surrogates) {
+ EXPECT_EQ(&GetCSSPropertyWidth(),
+ GetCSSPropertyInlineSize().SurrogateFor(
+ TextDirection::kLtr, WritingMode::kHorizontalTb));
+ EXPECT_EQ(&GetCSSPropertyHeight(),
+ GetCSSPropertyInlineSize().SurrogateFor(TextDirection::kLtr,
+ WritingMode::kVerticalRl));
+ EXPECT_EQ(&GetCSSPropertyWritingMode(),
+ GetCSSPropertyWebkitWritingMode().SurrogateFor(
+ TextDirection::kLtr, WritingMode::kHorizontalTb));
+ EXPECT_FALSE(GetCSSPropertyWidth().SurrogateFor(TextDirection::kLtr,
+ WritingMode::kHorizontalTb));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/properties/css_unresolved_property.h b/chromium/third_party/blink/renderer/core/css/properties/css_unresolved_property.h
index 9abed9fed82..afeae4ae8c6 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/css_unresolved_property.h
+++ b/chromium/third_party/blink/renderer/core/css/properties/css_unresolved_property.h
@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/core/css/properties/css_exposure.h"
#include "third_party/blink/renderer/core/css/properties/css_property_instances.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -22,6 +23,18 @@ class CORE_EXPORT CSSUnresolvedProperty {
bool IsWebExposed() const { return blink::IsWebExposed(Exposure()); }
bool IsUAExposed() const { return blink::IsUAExposed(Exposure()); }
virtual CSSExposure Exposure() const { return CSSExposure::kWeb; }
+ // Takes origin trial into account
+ bool IsWebExposed(const ExecutionContext* context) const {
+ return blink::IsWebExposed(Exposure(context));
+ }
+ bool IsUAExposed(const ExecutionContext* context) const {
+ return blink::IsUAExposed(Exposure(context));
+ }
+ virtual CSSExposure Exposure(const ExecutionContext* context) const {
+ // css properties that does not override this function should return
+ // the same value as Exposure()
+ return Exposure();
+ }
virtual bool IsResolvedProperty() const { return false; }
virtual const char* GetPropertyName() const {
NOTREACHED();
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhand.h b/chromium/third_party/blink/renderer/core/css/properties/longhand.h
index 6bdebb7b389..161366cbd83 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhand.h
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhand.h
@@ -43,9 +43,7 @@ class Longhand : public CSSProperty {
}
protected:
- constexpr Longhand(CSSPropertyID id,
- uint16_t flags,
- char repetition_separator)
+ constexpr Longhand(CSSPropertyID id, Flags flags, char repetition_separator)
: CSSProperty(id, flags | kLonghand, repetition_separator) {}
};
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/custom_property.cc b/chromium/third_party/blink/renderer/core/css/properties/longhands/custom_property.cc
index 28138d97ff7..8cb1be641d8 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/custom_property.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/custom_property.cc
@@ -17,7 +17,9 @@ namespace blink {
CustomProperty::CustomProperty(const AtomicString& name,
const Document& document)
- : CustomProperty(name, PropertyRegistration::From(&document, name)) {}
+ : CustomProperty(
+ name,
+ PropertyRegistration::From(document.GetExecutionContext(), name)) {}
CustomProperty::CustomProperty(const AtomicString& name,
const PropertyRegistry* registry)
@@ -186,7 +188,7 @@ const CSSValue* CustomProperty::ParseTyped(
const CSSParserLocalContext& local_context) const {
if (!registration_)
return ParseUntyped(range, context, local_context);
- return registration_->Syntax().Parse(range, &context,
+ return registration_->Syntax().Parse(range, context,
local_context.IsAnimationTainted());
}
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 87b813e3260..1e498cd35bc 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
@@ -49,7 +49,7 @@ class CORE_EXPORT CustomProperty : public Variable {
bool IsRegistered() const { return registration_; }
- void Trace(blink::Visitor* visitor) { visitor->Trace(registration_); }
+ void Trace(Visitor* visitor) { visitor->Trace(registration_); }
private:
CustomProperty(const AtomicString& name,
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/custom_property_test.cc b/chromium/third_party/blink/renderer/core/css/properties/longhands/custom_property_test.cc
index c8f3a61da57..9819322441e 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/custom_property_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/custom_property_test.cc
@@ -24,8 +24,8 @@ namespace {
class CustomPropertyTest : public PageTestBase {
public:
void SetElementWithStyle(const String& value) {
- GetDocument().body()->SetInnerHTMLFromString("<div id='target' style='" +
- value + "'></div>");
+ GetDocument().body()->setInnerHTML("<div id='target' style='" + value +
+ "'></div>");
UpdateAllLifecyclePhasesForTest();
}
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 f2bb58fe73a..2273c259d3a 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
@@ -126,10 +126,10 @@ const CSSValue* AlignmentBaseline::CSSValueFromComputedStyleInternal(
const CSSValue* AnimationDelay::ParseSingleValue(
CSSParserTokenRange& range,
- const CSSParserContext&,
+ const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_property_parser_helpers::ConsumeCommaSeparatedList(
- css_property_parser_helpers::ConsumeTime, range, kValueRangeAll);
+ css_property_parser_helpers::ConsumeTime, range, context, kValueRangeAll);
}
const CSSValue* AnimationDelay::CSSValueFromComputedStyleInternal(
@@ -185,10 +185,11 @@ const CSSValue* AnimationDirection::InitialValue() const {
const CSSValue* AnimationDuration::ParseSingleValue(
CSSParserTokenRange& range,
- const CSSParserContext&,
+ const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_property_parser_helpers::ConsumeCommaSeparatedList(
- css_property_parser_helpers::ConsumeTime, range, kValueRangeNonNegative);
+ css_property_parser_helpers::ConsumeTime, range, context,
+ kValueRangeNonNegative);
}
const CSSValue* AnimationDuration::CSSValueFromComputedStyleInternal(
@@ -244,10 +245,10 @@ const CSSValue* AnimationFillMode::InitialValue() const {
const CSSValue* AnimationIterationCount::ParseSingleValue(
CSSParserTokenRange& range,
- const CSSParserContext&,
+ const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_property_parser_helpers::ConsumeCommaSeparatedList(
- css_parsing_utils::ConsumeAnimationIterationCount, range);
+ css_parsing_utils::ConsumeAnimationIterationCount, range, context);
}
const CSSValue* AnimationIterationCount::CSSValueFromComputedStyleInternal(
@@ -347,10 +348,10 @@ const CSSValue* AnimationPlayState::InitialValue() const {
const CSSValue* AnimationTimingFunction::ParseSingleValue(
CSSParserTokenRange& range,
- const CSSParserContext&,
+ const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_property_parser_helpers::ConsumeCommaSeparatedList(
- css_parsing_utils::ConsumeAnimationTimingFunction, range);
+ css_parsing_utils::ConsumeAnimationTimingFunction, range, context);
}
const CSSValue* AnimationTimingFunction::CSSValueFromComputedStyleInternal(
@@ -368,6 +369,45 @@ const CSSValue* AnimationTimingFunction::InitialValue() const {
return value;
}
+const CSSValue* AspectRatio::ParseSingleValue(
+ CSSParserTokenRange& range,
+ 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);
+ if (!width)
+ return nullptr;
+ if (!css_property_parser_helpers::ConsumeSlashIncludingWhitespace(range))
+ return nullptr;
+ CSSValue* height =
+ css_property_parser_helpers::ConsumePositiveInteger(range, context);
+ if (!height)
+ return nullptr;
+ CSSValueList* list = CSSValueList::CreateSlashSeparated();
+ list->Append(*width);
+ list->Append(*height);
+ return list;
+}
+
+const CSSValue* AspectRatio::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject* layout_object,
+ bool allow_visited_style) const {
+ auto& ratio = style.AspectRatio();
+ if (!ratio.has_value())
+ return CSSIdentifierValue::Create(CSSValueID::kAuto);
+
+ CSSValueList* list = CSSValueList::CreateSlashSeparated();
+ list->Append(*CSSNumericLiteralValue::Create(
+ ratio->Width(), CSSPrimitiveValue::UnitType::kInteger));
+ list->Append(*CSSNumericLiteralValue::Create(
+ ratio->Height(), CSSPrimitiveValue::UnitType::kInteger));
+ return list;
+}
+
const CSSValue* BackdropFilter::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
@@ -460,7 +500,7 @@ const CSSValue* BackgroundColor::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_property_parser_helpers::ConsumeColor(
- range, context.Mode(), IsQuirksModeBehavior(context.Mode()));
+ range, context, IsQuirksModeBehavior(context.Mode()));
}
const blink::Color BackgroundColor::ColorIncludingFallback(
@@ -489,7 +529,7 @@ const CSSValue* BackgroundImage::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_property_parser_helpers::ConsumeCommaSeparatedList(
- css_property_parser_helpers::ConsumeImageOrNone, range, &context);
+ css_property_parser_helpers::ConsumeImageOrNone, range, context);
}
const CSSValue* BackgroundImage::CSSValueFromComputedStyleInternal(
@@ -531,7 +571,7 @@ const CSSValue* BackgroundPositionX::ParseSingleValue(
return css_property_parser_helpers::ConsumeCommaSeparatedList(
css_parsing_utils::ConsumePositionLonghand<CSSValueID::kLeft,
CSSValueID::kRight>,
- range, context.Mode());
+ range, context);
}
const CSSValue* BackgroundPositionX::CSSValueFromComputedStyleInternal(
@@ -551,7 +591,7 @@ const CSSValue* BackgroundPositionY::ParseSingleValue(
return css_property_parser_helpers::ConsumeCommaSeparatedList(
css_parsing_utils::ConsumePositionLonghand<CSSValueID::kTop,
CSSValueID::kBottom>,
- range, context.Mode());
+ range, context);
}
const CSSValue* BackgroundPositionY::CSSValueFromComputedStyleInternal(
@@ -589,8 +629,9 @@ const CSSValue* BaselineShift::ParseSingleValue(
if (id == CSSValueID::kBaseline || id == CSSValueID::kSub ||
id == CSSValueID::kSuper)
return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, kSVGAttributeMode, kValueRangeAll);
+ CSSParserContext::ParserModeOverridingScope scope(context, kSVGAttributeMode);
+ return css_property_parser_helpers::ConsumeLengthOrPercent(range, context,
+ kValueRangeAll);
}
const CSSValue* BaselineShift::CSSValueFromComputedStyleInternal(
@@ -662,7 +703,7 @@ const CSSValue* BorderBlockEndColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context.Mode());
+ return css_property_parser_helpers::ConsumeColor(range, context);
}
const CSSValue* BorderBlockEndWidth::ParseSingleValue(
@@ -670,15 +711,14 @@ const CSSValue* BorderBlockEndWidth::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeBorderWidth(
- range, context.Mode(),
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
}
const CSSValue* BorderBlockStartColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context.Mode());
+ return css_property_parser_helpers::ConsumeColor(range, context);
}
const CSSValue* BorderBlockStartWidth::ParseSingleValue(
@@ -686,8 +726,7 @@ const CSSValue* BorderBlockStartWidth::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeBorderWidth(
- range, context.Mode(),
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
}
const CSSValue* BorderBottomColor::ParseSingleValue(
@@ -730,7 +769,7 @@ const CSSValue* BorderBottomLeftRadius::CSSValueFromComputedStyleInternal(
const SVGComputedStyle&,
const LayoutObject*,
bool allow_visited_style) const {
- return &ComputedStyleUtils::ValueForBorderRadiusCorner(
+ return ComputedStyleUtils::ValueForBorderRadiusCorner(
style.BorderBottomLeftRadius(), style);
}
@@ -746,7 +785,7 @@ const CSSValue* BorderBottomRightRadius::CSSValueFromComputedStyleInternal(
const SVGComputedStyle&,
const LayoutObject*,
bool allow_visited_style) const {
- return &ComputedStyleUtils::ValueForBorderRadiusCorner(
+ return ComputedStyleUtils::ValueForBorderRadiusCorner(
style.BorderBottomRightRadius(), style);
}
const CSSValue* BorderBottomStyle::CSSValueFromComputedStyleInternal(
@@ -784,9 +823,9 @@ const CSSValue* BorderCollapse::CSSValueFromComputedStyleInternal(
const CSSValue* BorderImageOutset::ParseSingleValue(
CSSParserTokenRange& range,
- const CSSParserContext&,
+ const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeBorderImageOutset(range);
+ return css_parsing_utils::ConsumeBorderImageOutset(range, context);
}
const CSSValue* BorderImageOutset::CSSValueFromComputedStyleInternal(
@@ -799,11 +838,11 @@ const CSSValue* BorderImageOutset::CSSValueFromComputedStyleInternal(
}
const CSSValue* BorderImageOutset::InitialValue() const {
- DEFINE_STATIC_LOCAL(
- const Persistent<CSSQuadValue>, value,
- (CSSQuadValue::Create(CSSNumericLiteralValue::Create(
- 0, CSSPrimitiveValue::UnitType::kInteger),
- CSSQuadValue::kSerializeAsQuad)));
+ DEFINE_STATIC_LOCAL(const Persistent<CSSQuadValue>, value,
+ (MakeGarbageCollected<CSSQuadValue>(
+ CSSNumericLiteralValue::Create(
+ 0, CSSPrimitiveValue::UnitType::kInteger),
+ CSSQuadValue::kSerializeAsQuad)));
return value;
}
@@ -830,10 +869,10 @@ const CSSValue* BorderImageRepeat::InitialValue() const {
const CSSValue* BorderImageSlice::ParseSingleValue(
CSSParserTokenRange& range,
- const CSSParserContext&,
+ const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeBorderImageSlice(
- range, css_parsing_utils::DefaultFill::kNoFill);
+ range, context, css_parsing_utils::DefaultFill::kNoFill);
}
const CSSValue* BorderImageSlice::CSSValueFromComputedStyleInternal(
@@ -848,7 +887,7 @@ const CSSValue* BorderImageSlice::InitialValue() const {
DEFINE_STATIC_LOCAL(
const Persistent<cssvalue::CSSBorderImageSliceValue>, value,
(MakeGarbageCollected<cssvalue::CSSBorderImageSliceValue>(
- CSSQuadValue::Create(
+ MakeGarbageCollected<CSSQuadValue>(
CSSNumericLiteralValue::Create(
100, CSSPrimitiveValue::UnitType::kPercentage),
CSSQuadValue::kSerializeAsQuad),
@@ -860,7 +899,7 @@ const CSSValue* BorderImageSource::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeImageOrNone(range, &context);
+ return css_property_parser_helpers::ConsumeImageOrNone(range, context);
}
const CSSValue* BorderImageSource::CSSValueFromComputedStyleInternal(
@@ -889,9 +928,9 @@ void BorderImageSource::ApplyValue(StyleResolverState& state,
const CSSValue* BorderImageWidth::ParseSingleValue(
CSSParserTokenRange& range,
- const CSSParserContext&,
+ const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeBorderImageWidth(range);
+ return css_parsing_utils::ConsumeBorderImageWidth(range, context);
}
const CSSValue* BorderImageWidth::CSSValueFromComputedStyleInternal(
@@ -904,11 +943,11 @@ const CSSValue* BorderImageWidth::CSSValueFromComputedStyleInternal(
}
const CSSValue* BorderImageWidth::InitialValue() const {
- DEFINE_STATIC_LOCAL(
- const Persistent<CSSQuadValue>, value,
- (CSSQuadValue::Create(CSSNumericLiteralValue::Create(
- 1, CSSPrimitiveValue::UnitType::kInteger),
- CSSQuadValue::kSerializeAsQuad)));
+ DEFINE_STATIC_LOCAL(const Persistent<CSSQuadValue>, value,
+ (MakeGarbageCollected<CSSQuadValue>(
+ CSSNumericLiteralValue::Create(
+ 1, CSSPrimitiveValue::UnitType::kInteger),
+ CSSQuadValue::kSerializeAsQuad)));
return value;
}
@@ -916,7 +955,7 @@ const CSSValue* BorderInlineEndColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context.Mode());
+ return css_property_parser_helpers::ConsumeColor(range, context);
}
const CSSValue* BorderInlineEndWidth::ParseSingleValue(
@@ -924,15 +963,14 @@ const CSSValue* BorderInlineEndWidth::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeBorderWidth(
- range, context.Mode(),
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
}
const CSSValue* BorderInlineStartColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context.Mode());
+ return css_property_parser_helpers::ConsumeColor(range, context);
}
const CSSValue* BorderInlineStartWidth::ParseSingleValue(
@@ -940,8 +978,7 @@ const CSSValue* BorderInlineStartWidth::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeBorderWidth(
- range, context.Mode(),
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
}
const CSSValue* BorderLeftColor::ParseSingleValue(
@@ -1084,7 +1121,7 @@ const CSSValue* BorderTopLeftRadius::CSSValueFromComputedStyleInternal(
const SVGComputedStyle&,
const LayoutObject*,
bool allow_visited_style) const {
- return &ComputedStyleUtils::ValueForBorderRadiusCorner(
+ return ComputedStyleUtils::ValueForBorderRadiusCorner(
style.BorderTopLeftRadius(), style);
}
@@ -1100,7 +1137,7 @@ const CSSValue* BorderTopRightRadius::CSSValueFromComputedStyleInternal(
const SVGComputedStyle&,
const LayoutObject*,
bool allow_visited_style) const {
- return &ComputedStyleUtils::ValueForBorderRadiusCorner(
+ return ComputedStyleUtils::ValueForBorderRadiusCorner(
style.BorderTopRightRadius(), style);
}
@@ -1132,7 +1169,7 @@ const CSSValue* Bottom::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext& local_context) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context.Mode(),
+ range, context,
css_parsing_utils::UnitlessUnlessShorthand(local_context));
}
@@ -1155,7 +1192,7 @@ const CSSValue* BoxShadow::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeShadow(
- range, context.Mode(), css_parsing_utils::AllowInsetAndSpread::kAllow);
+ range, context, css_parsing_utils::AllowInsetAndSpread::kAllow);
}
const CSSValue* BoxShadow::CSSValueFromComputedStyleInternal(
@@ -1222,7 +1259,7 @@ const CSSValue* CaretColor::ParseSingleValue(
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kAuto)
return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeColor(range, context.Mode());
+ return css_property_parser_helpers::ConsumeColor(range, context);
}
const blink::Color CaretColor::ColorIncludingFallback(
@@ -1277,11 +1314,11 @@ const CSSValue* Clear::CSSValueFromComputedStyleInternal(
namespace {
CSSValue* ConsumeClipComponent(CSSParserTokenRange& range,
- CSSParserMode css_parser_mode) {
+ const CSSParserContext& context) {
if (range.Peek().Id() == CSSValueID::kAuto)
return css_property_parser_helpers::ConsumeIdent(range);
return css_property_parser_helpers::ConsumeLength(
- range, css_parser_mode, kValueRangeAll,
+ range, context, kValueRangeAll,
css_property_parser_helpers::UnitlessQuirk::kAllow);
}
@@ -1299,22 +1336,22 @@ const CSSValue* Clip::ParseSingleValue(CSSParserTokenRange& range,
CSSParserTokenRange args =
css_property_parser_helpers::ConsumeFunction(range);
// rect(t, r, b, l) || rect(t r b l)
- CSSValue* top = ConsumeClipComponent(args, context.Mode());
+ CSSValue* top = ConsumeClipComponent(args, context);
if (!top)
return nullptr;
bool needs_comma =
css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args);
- CSSValue* right = ConsumeClipComponent(args, context.Mode());
+ CSSValue* right = ConsumeClipComponent(args, context);
if (!right ||
(needs_comma &&
!css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args)))
return nullptr;
- CSSValue* bottom = ConsumeClipComponent(args, context.Mode());
+ CSSValue* bottom = ConsumeClipComponent(args, context);
if (!bottom ||
(needs_comma &&
!css_property_parser_helpers::ConsumeCommaIncludingWhitespace(args)))
return nullptr;
- CSSValue* left = ConsumeClipComponent(args, context.Mode());
+ CSSValue* left = ConsumeClipComponent(args, context);
if (!left || !args.AtEnd())
return nullptr;
return MakeGarbageCollected<CSSQuadValue>(top, right, bottom, left,
@@ -1346,7 +1383,7 @@ const CSSValue* ClipPath::ParseSingleValue(CSSParserTokenRange& range,
if (range.Peek().Id() == CSSValueID::kNone)
return css_property_parser_helpers::ConsumeIdent(range);
if (cssvalue::CSSURIValue* url =
- css_property_parser_helpers::ConsumeUrl(range, &context))
+ css_property_parser_helpers::ConsumeUrl(range, context))
return url;
return css_parsing_utils::ConsumeBasicShape(range, context);
}
@@ -1362,8 +1399,8 @@ const CSSValue* ClipPath::CSSValueFromComputedStyleInternal(
style, To<ShapeClipPathOperation>(operation)->GetBasicShape());
}
if (operation->GetType() == ClipPathOperation::REFERENCE) {
- return cssvalue::CSSURIValue::Create(
- To<ReferenceClipPathOperation>(operation)->Url());
+ AtomicString url = To<ReferenceClipPathOperation>(operation)->Url();
+ return MakeGarbageCollected<cssvalue::CSSURIValue>(url);
}
}
return CSSIdentifierValue::Create(CSSValueID::kNone);
@@ -1381,7 +1418,7 @@ const CSSValue* Color::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_property_parser_helpers::ConsumeColor(
- range, context.Mode(), IsQuirksModeBehavior(context.Mode()));
+ range, context, IsQuirksModeBehavior(context.Mode()));
}
const blink::Color Color::ColorIncludingFallback(
@@ -1407,8 +1444,7 @@ void Color::ApplyInitial(StyleResolverState& state) const {
CSSIdentifierValue::Create(CSSValueID::kInitial));
return;
}
- blink::Color color = ComputedStyleInitialValues::InitialColor();
- state.Style()->SetColor(color);
+ state.Style()->SetColor(state.Style()->InitialColorForColorScheme());
}
void Color::ApplyInherit(StyleResolverState& state) const {
@@ -1417,11 +1453,7 @@ void Color::ApplyInherit(StyleResolverState& state) const {
CSSIdentifierValue::Create(CSSValueID::kInherit));
return;
}
- blink::Color color = state.ParentStyle()->GetColor();
- if (state.ParentStyle()->IsColorInternalText())
- state.Style()->SetIsColorInternalText(true);
- else
- state.Style()->SetColor(color);
+ state.Style()->SetColor(state.ParentStyle()->GetColor());
}
void Color::ApplyValue(StyleResolverState& state, const CSSValue& value) const {
@@ -1436,13 +1468,7 @@ void Color::ApplyValue(StyleResolverState& state, const CSSValue& value) const {
ApplyInherit(state);
return;
}
-
- if (identifier_value &&
- identifier_value->GetValueID() == CSSValueID::kInternalRootColor) {
- state.Style()->SetIsColorInternalText(true);
- } else {
- state.Style()->SetColor(StyleBuilderConverter::ConvertColor(state, value));
- }
+ state.Style()->SetColor(StyleBuilderConverter::ConvertColor(state, value));
}
const CSSValue* ColorInterpolation::CSSValueFromComputedStyleInternal(
@@ -1488,11 +1514,11 @@ const CSSValue* ColorScheme::ParseSingleValue(
CSSValueList* values = CSSValueList::CreateSpaceSeparated();
do {
CSSValueID id = range.Peek().Id();
- // 'normal' is handled above, and 'none' is reserved for future use.
+ // 'normal' is handled above, and 'default' is reserved for future use.
// 'revert' is not yet implemented as a keyword, but still skip it for
// compat and interop.
- if (id == CSSValueID::kNormal || id == CSSValueID::kNone ||
- id == CSSValueID::kRevert || id == CSSValueID::kDefault) {
+ if (id == CSSValueID::kNormal || id == CSSValueID::kRevert ||
+ id == CSSValueID::kDefault) {
return nullptr;
}
if (id == CSSValueID::kOnly) {
@@ -1579,7 +1605,7 @@ const CSSValue* ColumnCount::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeColumnCount(range);
+ return css_parsing_utils::ConsumeColumnCount(range, context);
}
const CSSValue* ColumnCount::CSSValueFromComputedStyleInternal(
@@ -1620,7 +1646,7 @@ const CSSValue* ColumnRuleColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context.Mode());
+ return css_property_parser_helpers::ConsumeColor(range, context);
}
const blink::Color ColumnRuleColor::ColorIncludingFallback(
@@ -1654,8 +1680,7 @@ const CSSValue* ColumnRuleWidth::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_property_parser_helpers::ConsumeLineWidth(
- range, context.Mode(),
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
}
const CSSValue* ColumnRuleWidth::CSSValueFromComputedStyleInternal(
@@ -1688,7 +1713,7 @@ const CSSValue* ColumnWidth::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeColumnWidth(range);
+ return css_parsing_utils::ConsumeColumnWidth(range, context);
}
const CSSValue* ColumnWidth::CSSValueFromComputedStyleInternal(
@@ -1772,60 +1797,40 @@ const CSSValue* Contain::CSSValueFromComputedStyleInternal(
return list;
}
-const CSSValue* IntrinsicBlockSize::ParseSingleValue(
- CSSParserTokenRange& range,
- const CSSParserContext& context,
- const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeIntrinsicLength(range, context);
-}
-
-const CSSValue* IntrinsicInlineSize::ParseSingleValue(
- CSSParserTokenRange& range,
- const CSSParserContext& context,
- const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeIntrinsicLength(range, context);
-}
-
-const CSSValue* IntrinsicWidth::ParseSingleValue(
+const CSSValue* ContainIntrinsicSize::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeIntrinsicLength(range, context);
-}
-
-const CSSValue* IntrinsicWidth::CSSValueFromComputedStyleInternal(
- const ComputedStyle& style,
- const SVGComputedStyle&,
- const LayoutObject* layout_object,
- bool allow_visited_style) const {
- auto& width = style.IntrinsicWidth();
- if (width.IsLegacy())
- return CSSIdentifierValue::Create(CSSValueID::kLegacy);
- if (width.IsAuto())
- return CSSIdentifierValue::Create(CSSValueID::kAuto);
- return ComputedStyleUtils::ZoomAdjustedPixelValueForLength(width.GetLength(),
- style);
-}
-
-const CSSValue* IntrinsicHeight::ParseSingleValue(
- CSSParserTokenRange& range,
- const CSSParserContext& context,
- const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeIntrinsicLength(range, context);
+ if (range.Peek().Id() == CSSValueID::kAuto)
+ return css_property_parser_helpers::ConsumeIdent(range);
+ CSSValue* width = css_property_parser_helpers::ConsumeLength(
+ range, context, kValueRangeNonNegative);
+ if (!width)
+ return nullptr;
+ CSSValue* height = css_property_parser_helpers::ConsumeLength(
+ range, context, kValueRangeNonNegative);
+ if (!height)
+ height = width;
+ return MakeGarbageCollected<CSSValuePair>(width, height,
+ CSSValuePair::kDropIdenticalValues);
}
-const CSSValue* IntrinsicHeight::CSSValueFromComputedStyleInternal(
+const CSSValue* ContainIntrinsicSize::CSSValueFromComputedStyleInternal(
const ComputedStyle& style,
const SVGComputedStyle&,
const LayoutObject* layout_object,
bool allow_visited_style) const {
- auto& height = style.IntrinsicHeight();
- if (height.IsLegacy())
- return CSSIdentifierValue::Create(CSSValueID::kLegacy);
- if (height.IsAuto())
+ auto& size = style.ContainIntrinsicSize();
+ if (size.Width().IsAuto()) {
+ DCHECK(size.Height().IsAuto());
return CSSIdentifierValue::Create(CSSValueID::kAuto);
- return ComputedStyleUtils::ZoomAdjustedPixelValueForLength(height.GetLength(),
- style);
+ }
+ return MakeGarbageCollected<CSSValuePair>(
+ ComputedStyleUtils::ZoomAdjustedPixelValueForLength(
+ style.ContainIntrinsicSize().Width(), style),
+ ComputedStyleUtils::ZoomAdjustedPixelValueForLength(
+ style.ContainIntrinsicSize().Height(), style),
+ CSSValuePair::kDropIdenticalValues);
}
namespace {
@@ -1900,7 +1905,7 @@ const CSSValue* Content::ParseSingleValue(CSSParserTokenRange& range,
bool alt_text_present = false;
do {
CSSValue* parsed_value =
- css_property_parser_helpers::ConsumeImage(range, &context);
+ css_property_parser_helpers::ConsumeImage(range, context);
if (!parsed_value) {
parsed_value = css_property_parser_helpers::ConsumeIdent<
CSSValueID::kOpenQuote, CSSValueID::kCloseQuote,
@@ -1968,7 +1973,10 @@ void Content::ApplyValue(StyleResolverState& state,
if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) {
DCHECK(identifier_value->GetValueID() == CSSValueID::kNormal ||
identifier_value->GetValueID() == CSSValueID::kNone);
- state.Style()->SetContent(nullptr);
+ if (identifier_value->GetValueID() == CSSValueID::kNone)
+ state.Style()->SetContent(MakeGarbageCollected<NoneContentData>());
+ else
+ state.Style()->SetContent(nullptr);
return;
}
const CSSValueList& outer_list = To<CSSValueList>(value);
@@ -2096,14 +2104,14 @@ const CSSValue* Cursor::ParseSingleValue(CSSParserTokenRange& range,
CSSValueList* list = nullptr;
while (
CSSValue* image = css_property_parser_helpers::ConsumeImage(
- range, &context,
+ range, context,
css_property_parser_helpers::ConsumeGeneratedImagePolicy::kForbid)) {
double num;
IntPoint hot_spot(-1, -1);
bool hot_spot_specified = false;
- if (css_property_parser_helpers::ConsumeNumberRaw(range, num)) {
+ if (css_property_parser_helpers::ConsumeNumberRaw(range, context, num)) {
hot_spot.SetX(clampTo<int>(num));
- if (!css_property_parser_helpers::ConsumeNumberRaw(range, num))
+ if (!css_property_parser_helpers::ConsumeNumberRaw(range, context, num))
return nullptr;
hot_spot.SetY(clampTo<int>(num));
hot_spot_specified = true;
@@ -2380,7 +2388,7 @@ const CSSValue* FillOpacity::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeAlphaValue(range);
+ return css_property_parser_helpers::ConsumeAlphaValue(range, context);
}
const CSSValue* FillOpacity::CSSValueFromComputedStyleInternal(
@@ -2422,7 +2430,7 @@ const CSSValue* FlexBasis::ParseSingleValue(
if (range.Peek().Id() == CSSValueID::kAuto)
return css_property_parser_helpers::ConsumeIdent(range);
return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeNonNegative);
+ range, context, kValueRangeNonNegative);
}
const CSSValue* FlexBasis::CSSValueFromComputedStyleInternal(
@@ -2443,9 +2451,9 @@ const CSSValue* FlexDirection::CSSValueFromComputedStyleInternal(
}
const CSSValue* FlexGrow::ParseSingleValue(CSSParserTokenRange& range,
- const CSSParserContext&,
+ const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeNumber(range,
+ return css_property_parser_helpers::ConsumeNumber(range, context,
kValueRangeNonNegative);
}
@@ -2460,9 +2468,9 @@ const CSSValue* FlexGrow::CSSValueFromComputedStyleInternal(
const CSSValue* FlexShrink::ParseSingleValue(
CSSParserTokenRange& range,
- const CSSParserContext&,
+ const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeNumber(range,
+ return css_property_parser_helpers::ConsumeNumber(range, context,
kValueRangeNonNegative);
}
@@ -2497,7 +2505,7 @@ const CSSValue* FloodColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context.Mode());
+ return css_property_parser_helpers::ConsumeColor(range, context);
}
const blink::Color FloodColor::ColorIncludingFallback(
@@ -2522,7 +2530,7 @@ const CSSValue* FloodOpacity::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeAlphaValue(range);
+ return css_property_parser_helpers::ConsumeAlphaValue(range, context);
}
const CSSValue* FloodOpacity::CSSValueFromComputedStyleInternal(
@@ -2551,9 +2559,9 @@ const CSSValue* FontFamily::CSSValueFromComputedStyleInternal(
const CSSValue* FontFeatureSettings::ParseSingleValue(
CSSParserTokenRange& range,
- const CSSParserContext&,
+ const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeFontFeatureSettings(range);
+ return css_parsing_utils::ConsumeFontFeatureSettings(range, context);
}
const CSSValue* FontFeatureSettings::CSSValueFromComputedStyleInternal(
@@ -2599,7 +2607,7 @@ const CSSValue* FontSizeAdjust::ParseSingleValue(
DCHECK(RuntimeEnabledFeatures::CSSFontSizeAdjustEnabled());
if (range.Peek().Id() == CSSValueID::kNone)
return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeNumber(range,
+ return css_property_parser_helpers::ConsumeNumber(range, context,
kValueRangeNonNegative);
}
@@ -2634,7 +2642,7 @@ const CSSValue* FontStretch::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeFontStretch(range, context.Mode());
+ return css_parsing_utils::ConsumeFontStretch(range, context);
}
const CSSValue* FontStretch::CSSValueFromComputedStyleInternal(
@@ -2649,7 +2657,7 @@ const CSSValue* FontStyle::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeFontStyle(range, context.Mode());
+ return css_parsing_utils::ConsumeFontStyle(range, context);
}
const CSSValue* FontStyle::CSSValueFromComputedStyleInternal(
@@ -2757,7 +2765,8 @@ const CSSValue* FontVariantNumeric::CSSValueFromComputedStyleInternal(
namespace {
cssvalue::CSSFontVariationValue* ConsumeFontVariationTag(
- CSSParserTokenRange& range) {
+ CSSParserTokenRange& range,
+ const CSSParserContext& context) {
// Feature tag name consists of 4-letter characters.
static const wtf_size_t kTagNameLength = 4;
@@ -2777,7 +2786,7 @@ cssvalue::CSSFontVariationValue* ConsumeFontVariationTag(
}
double tag_value = 0;
- if (!css_property_parser_helpers::ConsumeNumberRaw(range, tag_value))
+ if (!css_property_parser_helpers::ConsumeNumberRaw(range, context, tag_value))
return nullptr;
return MakeGarbageCollected<cssvalue::CSSFontVariationValue>(
tag, clampTo<float>(tag_value));
@@ -2794,7 +2803,7 @@ const CSSValue* FontVariationSettings::ParseSingleValue(
CSSValueList* variation_settings = CSSValueList::CreateCommaSeparated();
do {
cssvalue::CSSFontVariationValue* font_variation_value =
- ConsumeFontVariationTag(range);
+ ConsumeFontVariationTag(range, context);
if (!font_variation_value)
return nullptr;
variation_settings->Append(*font_variation_value);
@@ -2826,7 +2835,7 @@ const CSSValue* FontWeight::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeFontWeight(range, context.Mode());
+ return css_parsing_utils::ConsumeFontWeight(range, context);
}
const CSSValue* FontWeight::CSSValueFromComputedStyleInternal(
@@ -2864,7 +2873,8 @@ const CSSValue* InternalEffectiveZoom::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext& local_context) const {
ValueRange value_range = kValueRangeNonNegative;
- return css_property_parser_helpers::ConsumeNumber(range, value_range);
+ return css_property_parser_helpers::ConsumeNumber(range, context,
+ value_range);
}
void InternalVisitedColor::ApplyInitial(StyleResolverState& state) const {
@@ -2873,8 +2883,8 @@ void InternalVisitedColor::ApplyInitial(StyleResolverState& state) const {
CSSIdentifierValue::Create(CSSValueID::kInitial));
return;
}
- auto color = ComputedStyleInitialValues::InitialColor();
- state.Style()->SetInternalVisitedColor(color);
+ state.Style()->SetInternalVisitedColor(
+ state.Style()->InitialColorForColorScheme());
}
void InternalVisitedColor::ApplyInherit(StyleResolverState& state) const {
@@ -2915,7 +2925,7 @@ const CSSValue* InternalVisitedColor::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext& local_context) const {
return css_property_parser_helpers::ConsumeColor(
- range, context.Mode(), IsQuirksModeBehavior(context.Mode()));
+ range, context, IsQuirksModeBehavior(context.Mode()));
}
const CSSValue* GridAutoColumns::ParseSingleValue(
@@ -2923,8 +2933,7 @@ const CSSValue* GridAutoColumns::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeGridTrackList(
- range, context, context.Mode(),
- css_parsing_utils::TrackListType::kGridAuto);
+ range, context, css_parsing_utils::TrackListType::kGridAuto);
}
// Specs mention that getComputedStyle() should return the used value of the
@@ -3003,8 +3012,7 @@ const CSSValue* GridAutoRows::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeGridTrackList(
- range, context, context.Mode(),
- css_parsing_utils::TrackListType::kGridAuto);
+ range, context, css_parsing_utils::TrackListType::kGridAuto);
}
const CSSValue* GridAutoRows::CSSValueFromComputedStyleInternal(
@@ -3146,18 +3154,15 @@ void GridTemplateAreas::ApplyValue(StyleResolverState& state,
const NamedGridAreaMap& new_named_grid_areas =
grid_template_areas_value.GridAreaMap();
- NamedGridLinesMap named_grid_column_lines;
- NamedGridLinesMap named_grid_row_lines;
- StyleBuilderConverter::ConvertOrderedNamedGridLinesMapToNamedGridLinesMap(
- state.Style()->OrderedNamedGridColumnLines(), named_grid_column_lines);
- StyleBuilderConverter::ConvertOrderedNamedGridLinesMapToNamedGridLinesMap(
- state.Style()->OrderedNamedGridRowLines(), named_grid_row_lines);
+ NamedGridLinesMap implicit_named_grid_column_lines;
+ NamedGridLinesMap implicit_named_grid_row_lines;
StyleBuilderConverter::CreateImplicitNamedGridLinesFromGridArea(
- new_named_grid_areas, named_grid_column_lines, kForColumns);
+ new_named_grid_areas, implicit_named_grid_column_lines, kForColumns);
StyleBuilderConverter::CreateImplicitNamedGridLinesFromGridArea(
- new_named_grid_areas, named_grid_row_lines, kForRows);
- state.Style()->SetNamedGridColumnLines(named_grid_column_lines);
- state.Style()->SetNamedGridRowLines(named_grid_row_lines);
+ new_named_grid_areas, implicit_named_grid_row_lines, kForRows);
+ state.Style()->SetImplicitNamedGridColumnLines(
+ implicit_named_grid_column_lines);
+ state.Style()->SetImplicitNamedGridRowLines(implicit_named_grid_row_lines);
state.Style()->SetNamedGridArea(new_named_grid_areas);
state.Style()->SetNamedGridAreaRowCount(grid_template_areas_value.RowCount());
@@ -3169,8 +3174,7 @@ const CSSValue* GridTemplateColumns::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeGridTemplatesRowsOrColumns(range, context,
- context.Mode());
+ return css_parsing_utils::ConsumeGridTemplatesRowsOrColumns(range, context);
}
bool GridTemplateColumns::IsLayoutDependent(const ComputedStyle* style,
@@ -3191,8 +3195,7 @@ const CSSValue* GridTemplateRows::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeGridTemplatesRowsOrColumns(range, context,
- context.Mode());
+ return css_parsing_utils::ConsumeGridTemplatesRowsOrColumns(range, context);
}
bool GridTemplateRows::IsLayoutDependent(const ComputedStyle* style,
@@ -3249,11 +3252,8 @@ const CSSValue* ImageOrientation::ParseSingleValue(
DCHECK(RuntimeEnabledFeatures::ImageOrientationEnabled());
if (range.Peek().Id() == CSSValueID::kFromImage)
return css_property_parser_helpers::ConsumeIdent(range);
- if (range.Peek().GetType() != kNumberToken) {
- CSSPrimitiveValue* angle = css_property_parser_helpers::ConsumeAngle(
- range, &context, base::Optional<WebFeature>());
- if (angle && angle->GetDoubleValue() == 0)
- return angle;
+ if (range.Peek().Id() == CSSValueID::kNone) {
+ return css_property_parser_helpers::ConsumeIdent(range);
}
return nullptr;
}
@@ -3265,8 +3265,7 @@ const CSSValue* ImageOrientation::CSSValueFromComputedStyleInternal(
bool allow_visited_style) const {
if (style.RespectImageOrientation() == kRespectImageOrientation)
return CSSIdentifierValue::Create(CSSValueID::kFromImage);
- return CSSNumericLiteralValue::Create(0,
- CSSPrimitiveValue::UnitType::kDegrees);
+ return CSSIdentifierValue::Create(CSSValueID::kNone);
}
const CSSValue* ImageRendering::CSSValueFromComputedStyleInternal(
@@ -3294,8 +3293,7 @@ const CSSValue* InsetBlockEnd::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context.Mode(),
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
}
const CSSValue* InsetBlockStart::ParseSingleValue(
@@ -3303,8 +3301,7 @@ const CSSValue* InsetBlockStart::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context.Mode(),
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
}
const CSSValue* InsetInlineEnd::ParseSingleValue(
@@ -3312,8 +3309,7 @@ const CSSValue* InsetInlineEnd::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context.Mode(),
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
}
const CSSValue* InsetInlineStart::ParseSingleValue(
@@ -3321,8 +3317,7 @@ const CSSValue* InsetInlineStart::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context.Mode(),
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
}
const blink::Color InternalVisitedBackgroundColor::ColorIncludingFallback(
@@ -3351,7 +3346,7 @@ const CSSValue* InternalVisitedBackgroundColor::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext& local_context) const {
return css_property_parser_helpers::ConsumeColor(
- range, context.Mode(), IsQuirksModeBehavior(context.Mode()));
+ range, context, IsQuirksModeBehavior(context.Mode()));
}
const blink::Color InternalVisitedBorderLeftColor::ColorIncludingFallback(
@@ -3487,7 +3482,7 @@ const CSSValue* InternalVisitedColumnRuleColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext& local_context) const {
- return css_property_parser_helpers::ConsumeColor(range, context.Mode());
+ return css_property_parser_helpers::ConsumeColor(range, context);
}
const blink::Color InternalVisitedOutlineColor::ColorIncludingFallback(
@@ -3525,7 +3520,7 @@ const CSSValue* InternalVisitedTextDecorationColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext& local_context) const {
- return css_property_parser_helpers::ConsumeColor(range, context.Mode());
+ return css_property_parser_helpers::ConsumeColor(range, context);
}
const blink::Color InternalVisitedTextEmphasisColor::ColorIncludingFallback(
@@ -3540,7 +3535,7 @@ const CSSValue* InternalVisitedTextEmphasisColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext& local_context) const {
- return css_property_parser_helpers::ConsumeColor(range, context.Mode());
+ return css_property_parser_helpers::ConsumeColor(range, context);
}
const blink::Color InternalVisitedTextFillColor::ColorIncludingFallback(
@@ -3555,7 +3550,7 @@ const CSSValue* InternalVisitedTextFillColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext& local_context) const {
- return css_property_parser_helpers::ConsumeColor(range, context.Mode());
+ return css_property_parser_helpers::ConsumeColor(range, context);
}
const blink::Color InternalVisitedTextStrokeColor::ColorIncludingFallback(
@@ -3570,7 +3565,7 @@ const CSSValue* InternalVisitedTextStrokeColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext& local_context) const {
- return css_property_parser_helpers::ConsumeColor(range, context.Mode());
+ return css_property_parser_helpers::ConsumeColor(range, context);
}
const CSSValue* Isolation::CSSValueFromComputedStyleInternal(
@@ -3671,7 +3666,7 @@ const CSSValue* Left::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext& local_context) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context.Mode(),
+ range, context,
css_parsing_utils::UnitlessUnlessShorthand(local_context));
}
@@ -3710,7 +3705,7 @@ const CSSValue* LightingColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context.Mode());
+ return css_property_parser_helpers::ConsumeColor(range, context);
}
const blink::Color LightingColor::ColorIncludingFallback(
@@ -3743,7 +3738,7 @@ const CSSValue* LineHeight::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeLineHeight(range, context.Mode());
+ return css_parsing_utils::ConsumeLineHeight(range, context);
}
const CSSValue* LineHeight::CSSValueFromComputedStyleInternal(
@@ -3758,7 +3753,7 @@ const CSSValue* LineHeightStep::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeLength(range, context.Mode(),
+ return css_property_parser_helpers::ConsumeLength(range, context,
kValueRangeNonNegative);
}
@@ -3774,7 +3769,7 @@ const CSSValue* ListStyleImage::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeImageOrNone(range, &context);
+ return css_property_parser_helpers::ConsumeImageOrNone(range, context);
}
const CSSValue* ListStyleImage::CSSValueFromComputedStyleInternal(
@@ -3858,8 +3853,7 @@ const CSSValue* MarginBlockEnd::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context.Mode(),
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
}
bool MarginBlockStart::IsLayoutDependent(const ComputedStyle* style,
@@ -3872,8 +3866,7 @@ const CSSValue* MarginBlockStart::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context.Mode(),
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
}
const CSSValue* MarginBottom::ParseSingleValue(
@@ -3881,8 +3874,7 @@ const CSSValue* MarginBottom::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context.Mode(),
- css_property_parser_helpers::UnitlessQuirk::kAllow);
+ range, context, css_property_parser_helpers::UnitlessQuirk::kAllow);
}
bool MarginBottom::IsLayoutDependent(const ComputedStyle* style,
@@ -3915,8 +3907,7 @@ const CSSValue* MarginInlineEnd::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context.Mode(),
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
}
bool MarginInlineStart::IsLayoutDependent(const ComputedStyle* style,
@@ -3929,8 +3920,7 @@ const CSSValue* MarginInlineStart::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context.Mode(),
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
}
const CSSValue* MarginLeft::ParseSingleValue(
@@ -3938,8 +3928,7 @@ const CSSValue* MarginLeft::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context.Mode(),
- css_property_parser_helpers::UnitlessQuirk::kAllow);
+ range, context, css_property_parser_helpers::UnitlessQuirk::kAllow);
}
bool MarginLeft::IsLayoutDependent(const ComputedStyle* style,
@@ -3967,8 +3956,7 @@ const CSSValue* MarginRight::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context.Mode(),
- css_property_parser_helpers::UnitlessQuirk::kAllow);
+ range, context, css_property_parser_helpers::UnitlessQuirk::kAllow);
}
bool MarginRight::IsLayoutDependent(const ComputedStyle* style,
@@ -4010,8 +3998,7 @@ const CSSValue* MarginTop::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context.Mode(),
- css_property_parser_helpers::UnitlessQuirk::kAllow);
+ range, context, css_property_parser_helpers::UnitlessQuirk::kAllow);
}
bool MarginTop::IsLayoutDependent(const ComputedStyle* style,
@@ -4039,7 +4026,7 @@ const CSSValue* MarkerEnd::ParseSingleValue(
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_property_parser_helpers::ConsumeUrl(range, context);
}
const CSSValue* MarkerEnd::CSSValueFromComputedStyleInternal(
@@ -4056,7 +4043,7 @@ const CSSValue* MarkerMid::ParseSingleValue(
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_property_parser_helpers::ConsumeUrl(range, context);
}
const CSSValue* MarkerMid::CSSValueFromComputedStyleInternal(
@@ -4073,7 +4060,7 @@ const CSSValue* MarkerStart::ParseSingleValue(
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_property_parser_helpers::ConsumeUrl(range, context);
}
const CSSValue* MarkerStart::CSSValueFromComputedStyleInternal(
@@ -4090,7 +4077,7 @@ const CSSValue* Mask::ParseSingleValue(CSSParserTokenRange& range,
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_property_parser_helpers::ConsumeUrl(range, context);
}
const CSSValue* Mask::CSSValueFromComputedStyleInternal(
@@ -4140,6 +4127,14 @@ const CSSValue* MaskType::CSSValueFromComputedStyleInternal(
return CSSIdentifierValue::Create(svg_style.MaskType());
}
+const CSSValue* MathStyle::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject*,
+ bool allow_visited_style) const {
+ return CSSIdentifierValue::Create(style.MathStyle());
+}
+
const CSSValue* MaxBlockSize::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
@@ -4161,7 +4156,7 @@ const CSSValue* MaxHeight::CSSValueFromComputedStyleInternal(
const LayoutObject*,
bool allow_visited_style) const {
const Length& max_height = style.MaxHeight();
- if (max_height.IsMaxSizeNone())
+ if (max_height.IsNone())
return CSSIdentifierValue::Create(CSSValueID::kNone);
return ComputedStyleUtils::ZoomAdjustedPixelValueForLength(max_height, style);
}
@@ -4186,7 +4181,7 @@ const CSSValue* MaxWidth::CSSValueFromComputedStyleInternal(
const LayoutObject*,
bool allow_visited_style) const {
const Length& max_width = style.MaxWidth();
- if (max_width.IsMaxSizeNone())
+ if (max_width.IsNone())
return CSSIdentifierValue::Create(CSSValueID::kNone);
return ComputedStyleUtils::ZoomAdjustedPixelValueForLength(max_width, style);
}
@@ -4304,8 +4299,8 @@ const CSSValue* OffsetDistance::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeAll);
+ return css_property_parser_helpers::ConsumeLengthOrPercent(range, context,
+ kValueRangeAll);
}
const CSSValue* OffsetDistance::CSSValueFromComputedStyleInternal(
@@ -4381,7 +4376,7 @@ const CSSValue* OffsetRotate::CSSValueFromComputedStyleInternal(
const CSSValue* Opacity::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeAlphaValue(range);
+ return css_property_parser_helpers::ConsumeAlphaValue(range, context);
}
const CSSValue* Opacity::CSSValueFromComputedStyleInternal(
@@ -4396,7 +4391,7 @@ const CSSValue* Opacity::CSSValueFromComputedStyleInternal(
const CSSValue* Order::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeInteger(range);
+ return css_property_parser_helpers::ConsumeInteger(range, context);
}
const CSSValue* Order::CSSValueFromComputedStyleInternal(
@@ -4408,10 +4403,19 @@ const CSSValue* Order::CSSValueFromComputedStyleInternal(
CSSPrimitiveValue::UnitType::kNumber);
}
+const CSSValue* OriginTrialTestProperty::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject*,
+ bool allow_visited_style) const {
+ return CSSIdentifierValue::Create(style.OriginTrialTestProperty());
+ ;
+}
+
const CSSValue* Orphans::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumePositiveInteger(range);
+ return css_property_parser_helpers::ConsumePositiveInteger(range, context);
}
const CSSValue* Orphans::CSSValueFromComputedStyleInternal(
@@ -4430,7 +4434,7 @@ const CSSValue* OutlineColor::ParseSingleValue(
// 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.Mode());
+ return css_property_parser_helpers::ConsumeColor(range, context);
}
const blink::Color OutlineColor::ColorIncludingFallback(
@@ -4455,7 +4459,7 @@ const CSSValue* OutlineOffset::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeLength(range, context.Mode(),
+ return css_property_parser_helpers::ConsumeLength(range, context,
kValueRangeAll);
}
@@ -4502,8 +4506,7 @@ const CSSValue* OutlineWidth::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_property_parser_helpers::ConsumeLineWidth(
- range, context.Mode(),
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
}
const CSSValue* OutlineWidth::CSSValueFromComputedStyleInternal(
@@ -4572,7 +4575,7 @@ const CSSValue* PaddingBlockEnd::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeNonNegative,
+ range, context, kValueRangeNonNegative,
css_property_parser_helpers::UnitlessQuirk::kForbid);
}
@@ -4586,7 +4589,7 @@ const CSSValue* PaddingBlockStart::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeNonNegative,
+ range, context, kValueRangeNonNegative,
css_property_parser_helpers::UnitlessQuirk::kForbid);
}
@@ -4595,7 +4598,7 @@ const CSSValue* PaddingBottom::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeNonNegative,
+ range, context, kValueRangeNonNegative,
css_property_parser_helpers::UnitlessQuirk::kAllow);
}
@@ -4629,7 +4632,7 @@ const CSSValue* PaddingInlineEnd::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeNonNegative,
+ range, context, kValueRangeNonNegative,
css_property_parser_helpers::UnitlessQuirk::kForbid);
}
@@ -4643,7 +4646,7 @@ const CSSValue* PaddingInlineStart::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeNonNegative,
+ range, context, kValueRangeNonNegative,
css_property_parser_helpers::UnitlessQuirk::kForbid);
}
@@ -4652,7 +4655,7 @@ const CSSValue* PaddingLeft::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeNonNegative,
+ range, context, kValueRangeNonNegative,
css_property_parser_helpers::UnitlessQuirk::kAllow);
}
@@ -4681,7 +4684,7 @@ const CSSValue* PaddingRight::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeNonNegative,
+ range, context, kValueRangeNonNegative,
css_property_parser_helpers::UnitlessQuirk::kAllow);
}
@@ -4710,7 +4713,7 @@ const CSSValue* PaddingTop::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeNonNegative,
+ range, context, kValueRangeNonNegative,
css_property_parser_helpers::UnitlessQuirk::kAllow);
}
@@ -4742,6 +4745,16 @@ const CSSValue* Page::ParseSingleValue(CSSParserTokenRange& range,
return css_property_parser_helpers::ConsumeCustomIdent(range, context);
}
+const CSSValue* Page::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject*,
+ bool allow_visited_style) const {
+ if (style.Page().IsNull())
+ return CSSIdentifierValue::Create(CSSValueID::kAuto);
+ return MakeGarbageCollected<CSSCustomIdentValue>(style.Page());
+}
+
const CSSValue* PaintOrder::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
@@ -4839,11 +4852,12 @@ const CSSValue* Perspective::ParseSingleValue(
if (range.Peek().Id() == CSSValueID::kNone)
return css_property_parser_helpers::ConsumeIdent(range);
CSSPrimitiveValue* parsed_value = css_property_parser_helpers::ConsumeLength(
- range, context.Mode(), kValueRangeAll);
+ range, context, kValueRangeAll);
bool use_legacy_parsing = localContext.UseAliasParsing();
if (!parsed_value && use_legacy_parsing) {
double perspective;
- if (!css_property_parser_helpers::ConsumeNumberRaw(range, perspective))
+ if (!css_property_parser_helpers::ConsumeNumberRaw(range, context,
+ perspective))
return nullptr;
context.Count(WebFeature::kUnitlessPerspectiveInPerspectiveProperty);
parsed_value = CSSNumericLiteralValue::Create(
@@ -4985,60 +4999,6 @@ const CSSValue* R::CSSValueFromComputedStyleInternal(
style);
}
-const CSSValue* RenderSubtree::ParseSingleValue(
- CSSParserTokenRange& range,
- const CSSParserContext& context,
- const CSSParserLocalContext&) const {
- CSSValueID id = range.Peek().Id();
- if (id == CSSValueID::kNone)
- return css_property_parser_helpers::ConsumeIdent(range);
-
- CSSValueList* list = CSSValueList::CreateSpaceSeparated();
- bool has_invisible = false;
- bool has_skip_activation = false;
- bool has_skip_viewport_activation = false;
- while (true) {
- id = range.Peek().Id();
- if (id == CSSValueID::kInvisible && !has_invisible) {
- list->Append(*css_property_parser_helpers::ConsumeIdent(range));
- has_invisible = true;
- } else if (id == CSSValueID::kSkipActivation && !has_skip_activation) {
- list->Append(*css_property_parser_helpers::ConsumeIdent(range));
- has_skip_activation = true;
- } else if (id == CSSValueID::kSkipViewportActivation &&
- !has_skip_viewport_activation) {
- list->Append(*css_property_parser_helpers::ConsumeIdent(range));
- has_skip_viewport_activation = true;
- } else {
- break;
- }
- }
- if (!list->length())
- return nullptr;
- return list;
-}
-
-const CSSValue* RenderSubtree::CSSValueFromComputedStyleInternal(
- const ComputedStyle& style,
- const SVGComputedStyle&,
- const LayoutObject*,
- bool allow_visited_style) const {
- if (style.RenderSubtree() == RenderSubtreeFlags::kNone)
- return CSSIdentifierValue::Create(CSSValueID::kNone);
-
- CSSValueList* list = CSSValueList::CreateSpaceSeparated();
- if (style.RenderSubtreeInvisible())
- list->Append(*CSSIdentifierValue::Create(CSSValueID::kInvisible));
- if (style.RenderSubtreeSkipActivation())
- list->Append(*CSSIdentifierValue::Create(CSSValueID::kSkipActivation));
- if (style.RenderSubtreeSkipViewportActivation()) {
- list->Append(
- *CSSIdentifierValue::Create(CSSValueID::kSkipViewportActivation));
- }
- DCHECK(list->length());
- return list;
-}
-
const CSSValue* Resize::CSSValueFromComputedStyleInternal(
const ComputedStyle& style,
const SVGComputedStyle&,
@@ -5069,7 +5029,7 @@ const CSSValue* Right::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext& local_context) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context.Mode(),
+ range, context,
css_parsing_utils::UnitlessUnlessShorthand(local_context));
}
@@ -5099,9 +5059,9 @@ const CSSValue* Rotate::ParseSingleValue(CSSParserTokenRange& range,
CSSValueList* list = CSSValueList::CreateSpaceSeparated();
CSSValue* rotation = css_property_parser_helpers::ConsumeAngle(
- range, &context, base::Optional<WebFeature>());
+ range, context, base::Optional<WebFeature>());
- CSSValue* axis = css_property_parser_helpers::ConsumeAxis(range);
+ CSSValue* axis = css_property_parser_helpers::ConsumeAxis(range, context);
if (axis)
list->Append(*axis);
else if (!rotation)
@@ -5109,7 +5069,7 @@ const CSSValue* Rotate::ParseSingleValue(CSSParserTokenRange& range,
if (!rotation) {
rotation = css_property_parser_helpers::ConsumeAngle(
- range, &context, base::Optional<WebFeature>());
+ range, context, base::Optional<WebFeature>());
if (!rotation)
return nullptr;
}
@@ -5198,19 +5158,19 @@ const CSSValue* Scale::ParseSingleValue(CSSParserTokenRange& range,
if (id == CSSValueID::kNone)
return css_property_parser_helpers::ConsumeIdent(range);
- CSSValue* x_scale =
- css_property_parser_helpers::ConsumeNumber(range, kValueRangeAll);
+ CSSValue* x_scale = css_property_parser_helpers::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, kValueRangeAll);
+ CSSValue* y_scale = css_property_parser_helpers::ConsumeNumber(
+ range, context, kValueRangeAll);
if (y_scale) {
- CSSValue* z_scale =
- css_property_parser_helpers::ConsumeNumber(range, kValueRangeAll);
+ CSSValue* z_scale = css_property_parser_helpers::ConsumeNumber(
+ range, context, kValueRangeAll);
if (z_scale) {
list->Append(*y_scale);
list->Append(*z_scale);
@@ -5318,7 +5278,7 @@ const CSSValue* ScrollMarginBlockEnd::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return ConsumeLength(range, context.Mode(), kValueRangeAll,
+ return ConsumeLength(range, context, kValueRangeAll,
css_property_parser_helpers::UnitlessQuirk::kForbid);
}
@@ -5326,7 +5286,7 @@ const CSSValue* ScrollMarginBlockStart::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return ConsumeLength(range, context.Mode(), kValueRangeAll,
+ return ConsumeLength(range, context, kValueRangeAll,
css_property_parser_helpers::UnitlessQuirk::kForbid);
}
@@ -5334,7 +5294,7 @@ const CSSValue* ScrollMarginBottom::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return ConsumeLength(range, context.Mode(), kValueRangeAll,
+ return ConsumeLength(range, context, kValueRangeAll,
css_property_parser_helpers::UnitlessQuirk::kForbid);
}
@@ -5350,7 +5310,7 @@ const CSSValue* ScrollMarginInlineEnd::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return ConsumeLength(range, context.Mode(), kValueRangeAll,
+ return ConsumeLength(range, context, kValueRangeAll,
css_property_parser_helpers::UnitlessQuirk::kForbid);
}
@@ -5358,7 +5318,7 @@ const CSSValue* ScrollMarginInlineStart::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return ConsumeLength(range, context.Mode(), kValueRangeAll,
+ return ConsumeLength(range, context, kValueRangeAll,
css_property_parser_helpers::UnitlessQuirk::kForbid);
}
@@ -5366,7 +5326,7 @@ const CSSValue* ScrollMarginLeft::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return ConsumeLength(range, context.Mode(), kValueRangeAll,
+ return ConsumeLength(range, context, kValueRangeAll,
css_property_parser_helpers::UnitlessQuirk::kForbid);
}
@@ -5382,7 +5342,7 @@ const CSSValue* ScrollMarginRight::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return ConsumeLength(range, context.Mode(), kValueRangeAll,
+ return ConsumeLength(range, context, kValueRangeAll,
css_property_parser_helpers::UnitlessQuirk::kForbid);
}
@@ -5398,7 +5358,7 @@ const CSSValue* ScrollMarginTop::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return ConsumeLength(range, context.Mode(), kValueRangeAll,
+ return ConsumeLength(range, context, kValueRangeAll,
css_property_parser_helpers::UnitlessQuirk::kForbid);
}
@@ -5414,21 +5374,21 @@ const CSSValue* ScrollPaddingBlockEnd::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeScrollPadding(range);
+ return css_parsing_utils::ConsumeScrollPadding(range, context);
}
const CSSValue* ScrollPaddingBlockStart::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeScrollPadding(range);
+ return css_parsing_utils::ConsumeScrollPadding(range, context);
}
const CSSValue* ScrollPaddingBottom::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeScrollPadding(range);
+ return css_parsing_utils::ConsumeScrollPadding(range, context);
}
const CSSValue* ScrollPaddingBottom::CSSValueFromComputedStyleInternal(
@@ -5444,21 +5404,21 @@ const CSSValue* ScrollPaddingInlineEnd::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeScrollPadding(range);
+ return css_parsing_utils::ConsumeScrollPadding(range, context);
}
const CSSValue* ScrollPaddingInlineStart::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeScrollPadding(range);
+ return css_parsing_utils::ConsumeScrollPadding(range, context);
}
const CSSValue* ScrollPaddingLeft::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeScrollPadding(range);
+ return css_parsing_utils::ConsumeScrollPadding(range, context);
}
const CSSValue* ScrollPaddingLeft::CSSValueFromComputedStyleInternal(
@@ -5474,7 +5434,7 @@ const CSSValue* ScrollPaddingRight::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeScrollPadding(range);
+ return css_parsing_utils::ConsumeScrollPadding(range, context);
}
const CSSValue* ScrollPaddingRight::CSSValueFromComputedStyleInternal(
@@ -5490,7 +5450,7 @@ const CSSValue* ScrollPaddingTop::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeScrollPadding(range);
+ return css_parsing_utils::ConsumeScrollPadding(range, context);
}
const CSSValue* ScrollPaddingTop::CSSValueFromComputedStyleInternal(
@@ -5579,7 +5539,7 @@ const CSSValue* ShapeImageThreshold::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeAlphaValue(range);
+ return css_property_parser_helpers::ConsumeAlphaValue(range, context);
}
const CSSValue* ShapeImageThreshold::CSSValueFromComputedStyleInternal(
@@ -5596,7 +5556,7 @@ const CSSValue* ShapeMargin::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeNonNegative);
+ range, context, kValueRangeNonNegative);
}
const CSSValue* ShapeMargin::CSSValueFromComputedStyleInternal(
@@ -5612,7 +5572,7 @@ const CSSValue* ShapeOutside::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
if (CSSValue* image_value =
- css_property_parser_helpers::ConsumeImageOrNone(range, &context))
+ css_property_parser_helpers::ConsumeImageOrNone(range, context))
return image_value;
CSSValueList* list = CSSValueList::CreateSpaceSeparated();
CSSValue* box_value = css_property_parser_helpers::ConsumeShapeBox(range);
@@ -5650,8 +5610,8 @@ const CSSValue* ShapeRendering::CSSValueFromComputedStyleInternal(
static CSSValue* ConsumePageSize(CSSParserTokenRange& range) {
return css_property_parser_helpers::ConsumeIdent<
CSSValueID::kA3, CSSValueID::kA4, CSSValueID::kA5, CSSValueID::kB4,
- CSSValueID::kB5, CSSValueID::kLedger, CSSValueID::kLegal,
- CSSValueID::kLetter>(range);
+ CSSValueID::kB5, CSSValueID::kJisB5, CSSValueID::kJisB4,
+ CSSValueID::kLedger, CSSValueID::kLegal, CSSValueID::kLetter>(range);
}
static float MmToPx(float mm) {
@@ -5672,6 +5632,10 @@ static FloatSize GetPageSizeFromName(const CSSIdentifierValue& page_size_name) {
return FloatSize(MmToPx(176), MmToPx(250));
case CSSValueID::kB4:
return FloatSize(MmToPx(250), MmToPx(353));
+ case CSSValueID::kJisB5:
+ return FloatSize(MmToPx(182), MmToPx(257));
+ case CSSValueID::kJisB4:
+ return FloatSize(MmToPx(257), MmToPx(364));
case CSSValueID::kLetter:
return FloatSize(InchToPx(8.5), InchToPx(11));
case CSSValueID::kLegal:
@@ -5695,9 +5659,9 @@ const CSSValue* Size::ParseSingleValue(CSSParserTokenRange& range,
}
if (CSSValue* width = css_property_parser_helpers::ConsumeLength(
- range, context.Mode(), kValueRangeNonNegative)) {
+ range, context, kValueRangeNonNegative)) {
CSSValue* height = css_property_parser_helpers::ConsumeLength(
- range, context.Mode(), kValueRangeNonNegative);
+ range, context, kValueRangeNonNegative);
result->Append(*width);
if (height)
result->Append(*height);
@@ -5727,7 +5691,7 @@ void Size::ApplyInherit(StyleResolverState& state) const {}
void Size::ApplyValue(StyleResolverState& state, const CSSValue& value) const {
state.Style()->ResetPageSizeType();
FloatSize size;
- EPageSizeType page_size_type = EPageSizeType::kAuto;
+ PageSizeType page_size_type = PageSizeType::kAuto;
const auto& list = To<CSSValueList>(value);
if (list.length() == 2) {
// <length>{2} | <page-size> <orientation>
@@ -5752,7 +5716,7 @@ void Size::ApplyValue(StyleResolverState& state, const CSSValue& value) const {
if (To<CSSIdentifierValue>(second).GetValueID() == CSSValueID::kLandscape)
size = size.TransposedSize();
}
- page_size_type = EPageSizeType::kResolved;
+ page_size_type = PageSizeType::kFixed;
} else {
DCHECK_EQ(list.length(), 1U);
// <length> | auto | <page-size> | [ portrait | landscape]
@@ -5760,7 +5724,7 @@ void Size::ApplyValue(StyleResolverState& state, const CSSValue& value) const {
auto* first_primitive_value = DynamicTo<CSSPrimitiveValue>(first);
if (first_primitive_value && first_primitive_value->IsLength()) {
// <length>
- page_size_type = EPageSizeType::kResolved;
+ page_size_type = PageSizeType::kFixed;
float width = first_primitive_value->ComputeLength<float>(
state.CssToLengthConversionData().CopyWithAdjustedZoom(1.0));
size = FloatSize(width, width);
@@ -5768,17 +5732,17 @@ void Size::ApplyValue(StyleResolverState& state, const CSSValue& value) const {
const auto& ident = To<CSSIdentifierValue>(first);
switch (ident.GetValueID()) {
case CSSValueID::kAuto:
- page_size_type = EPageSizeType::kAuto;
+ page_size_type = PageSizeType::kAuto;
break;
case CSSValueID::kPortrait:
- page_size_type = EPageSizeType::kPortrait;
+ page_size_type = PageSizeType::kPortrait;
break;
case CSSValueID::kLandscape:
- page_size_type = EPageSizeType::kLandscape;
+ page_size_type = PageSizeType::kLandscape;
break;
default:
// <page-size>
- page_size_type = EPageSizeType::kResolved;
+ page_size_type = PageSizeType::kFixed;
size = GetPageSizeFromName(ident);
}
}
@@ -5799,7 +5763,7 @@ const CSSValue* StopColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context.Mode());
+ return css_property_parser_helpers::ConsumeColor(range, context);
}
const blink::Color StopColor::ColorIncludingFallback(
@@ -5823,7 +5787,7 @@ const CSSValue* StopOpacity::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeAlphaValue(range);
+ return css_property_parser_helpers::ConsumeAlphaValue(range, context);
}
const CSSValue* StopOpacity::CSSValueFromComputedStyleInternal(
@@ -5858,11 +5822,12 @@ const CSSValue* StrokeDasharray::ParseSingleValue(
if (id == CSSValueID::kNone)
return css_property_parser_helpers::ConsumeIdent(range);
+ CSSParserContext::ParserModeOverridingScope scope(context, kSVGAttributeMode);
CSSValueList* dashes = CSSValueList::CreateCommaSeparated();
do {
CSSPrimitiveValue* dash =
css_property_parser_helpers::ConsumeLengthOrPercent(
- range, kSVGAttributeMode, kValueRangeNonNegative);
+ range, context, kValueRangeNonNegative);
if (!dash ||
(css_property_parser_helpers::ConsumeCommaIncludingWhitespace(range) &&
range.AtEnd()))
@@ -5883,10 +5848,11 @@ const CSSValue* StrokeDasharray::CSSValueFromComputedStyleInternal(
const CSSValue* StrokeDashoffset::ParseSingleValue(
CSSParserTokenRange& range,
- const CSSParserContext&,
+ const CSSParserContext& context,
const CSSParserLocalContext&) const {
+ CSSParserContext::ParserModeOverridingScope scope(context, kSVGAttributeMode);
return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, kSVGAttributeMode, kValueRangeAll,
+ range, context, kValueRangeAll,
css_property_parser_helpers::UnitlessQuirk::kForbid);
}
@@ -5919,7 +5885,7 @@ const CSSValue* StrokeMiterlimit::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeNumber(range,
+ return css_property_parser_helpers::ConsumeNumber(range, context,
kValueRangeNonNegative);
}
@@ -5936,7 +5902,7 @@ const CSSValue* StrokeOpacity::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeAlphaValue(range);
+ return css_property_parser_helpers::ConsumeAlphaValue(range, context);
}
const CSSValue* StrokeOpacity::CSSValueFromComputedStyleInternal(
@@ -5950,10 +5916,11 @@ const CSSValue* StrokeOpacity::CSSValueFromComputedStyleInternal(
const CSSValue* StrokeWidth::ParseSingleValue(
CSSParserTokenRange& range,
- const CSSParserContext&,
+ const CSSParserContext& context,
const CSSParserLocalContext&) const {
+ CSSParserContext::ParserModeOverridingScope scope(context, kSVGAttributeMode);
return css_property_parser_helpers::ConsumeLengthOrPercent(
- range, kSVGAttributeMode, kValueRangeNonNegative,
+ range, context, kValueRangeNonNegative,
css_property_parser_helpers::UnitlessQuirk::kForbid);
}
@@ -5962,22 +5929,44 @@ const CSSValue* StrokeWidth::CSSValueFromComputedStyleInternal(
const SVGComputedStyle& svg_style,
const LayoutObject*,
bool allow_visited_style) const {
- const Length& length = svg_style.StrokeWidth().length();
- if (length.IsFixed()) {
- return CSSNumericLiteralValue::Create(length.Value(),
- CSSPrimitiveValue::UnitType::kPixels);
+ // We store the unzoomed stroke-width value using ConvertUnzoomedLength().
+ // Don't apply zoom here either.
+ return CSSValue::Create(svg_style.StrokeWidth().length(), 1);
+}
+
+const CSSValue* SubtreeVisibility::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const SVGComputedStyle&,
+ const LayoutObject*,
+ bool allow_visited_style) const {
+ return CSSIdentifierValue::Create(style.SubtreeVisibility());
+}
+
+const CSSValue* SubtreeVisibility::ParseSingleValue(
+ CSSParserTokenRange& range,
+ const CSSParserContext& context,
+ const CSSParserLocalContext&) const {
+ auto id = range.Peek().Id();
+ if (id == CSSValueID::kHiddenMatchable &&
+ !RuntimeEnabledFeatures::CSSSubtreeVisibilityHiddenMatchableEnabled()) {
+ return nullptr;
+ }
+ if (!css_property_parser_helpers::IdentMatches<
+ CSSValueID::kVisible, CSSValueID::kAuto, CSSValueID::kHidden,
+ CSSValueID::kHiddenMatchable>(id)) {
+ return nullptr;
}
- return CSSValue::Create(length, style.EffectiveZoom());
+ return css_property_parser_helpers::ConsumeIdent(range);
}
const CSSValue* TabSize::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- CSSPrimitiveValue* parsed_value =
- css_property_parser_helpers::ConsumeNumber(range, kValueRangeNonNegative);
+ CSSPrimitiveValue* parsed_value = css_property_parser_helpers::ConsumeNumber(
+ range, context, kValueRangeNonNegative);
if (parsed_value)
return parsed_value;
- return css_property_parser_helpers::ConsumeLength(range, context.Mode(),
+ return css_property_parser_helpers::ConsumeLength(range, context,
kValueRangeNonNegative);
}
@@ -6063,7 +6052,7 @@ const CSSValue* TextDecorationColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context.Mode());
+ return css_property_parser_helpers::ConsumeColor(range, context);
}
const blink::Color TextDecorationColor::ColorIncludingFallback(
@@ -6129,7 +6118,7 @@ const CSSValue* TextIndent::ParseSingleValue(
do {
if (!length_percentage) {
length_percentage = css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeAll,
+ range, context, kValueRangeAll,
css_property_parser_helpers::UnitlessQuirk::kAllow);
if (length_percentage) {
continue;
@@ -6269,7 +6258,7 @@ const CSSValue* TextShadow::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeShadow(
- range, context.Mode(), css_parsing_utils::AllowInsetAndSpread::kForbid);
+ range, context, css_parsing_utils::AllowInsetAndSpread::kForbid);
}
const CSSValue* TextShadow::CSSValueFromComputedStyleInternal(
@@ -6289,7 +6278,7 @@ const CSSValue* TextSizeAdjust::ParseSingleValue(
return css_property_parser_helpers::ConsumeIdent(range);
if (range.Peek().Id() == CSSValueID::kNone)
return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumePercent(range,
+ return css_property_parser_helpers::ConsumePercent(range, context,
kValueRangeNonNegative);
}
@@ -6313,7 +6302,8 @@ const CSSValue* TextTransform::CSSValueFromComputedStyleInternal(
return CSSIdentifierValue::Create(style.TextTransform());
}
-// auto | [ under || [ left | right ] ]
+// https://drafts.csswg.org/css-text-decor-4/#text-underline-position-property
+// auto | [ from-font | under ] || [ left | right ] - default: auto
const CSSValue* TextUnderlinePosition::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
@@ -6321,21 +6311,29 @@ const CSSValue* TextUnderlinePosition::ParseSingleValue(
if (range.Peek().Id() == CSSValueID::kAuto)
return css_property_parser_helpers::ConsumeIdent(range);
- CSSIdentifierValue* under_value =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kUnder>(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);
CSSIdentifierValue* left_or_right_value =
css_property_parser_helpers::ConsumeIdent<CSSValueID::kLeft,
CSSValueID::kRight>(range);
- if (left_or_right_value && !under_value) {
- under_value =
- css_property_parser_helpers::ConsumeIdent<CSSValueID::kUnder>(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);
}
- if (!under_value && !left_or_right_value) {
+ if (!from_font_or_under_value && !left_or_right_value)
return nullptr;
- }
CSSValueList* list = CSSValueList::CreateSpaceSeparated();
- if (under_value)
- list->Append(*under_value);
+ if (from_font_or_under_value)
+ list->Append(*from_font_or_under_value);
if (left_or_right_value)
list->Append(*left_or_right_value);
return list;
@@ -6349,6 +6347,8 @@ const CSSValue* TextUnderlinePosition::CSSValueFromComputedStyleInternal(
auto text_underline_position = style.TextUnderlinePosition();
if (text_underline_position == kTextUnderlinePositionAuto)
return CSSIdentifierValue::Create(CSSValueID::kAuto);
+ if (text_underline_position == kTextUnderlinePositionFromFont)
+ return CSSIdentifierValue::Create(CSSValueID::kFromFont);
if (text_underline_position == kTextUnderlinePositionUnder)
return CSSIdentifierValue::Create(CSSValueID::kUnder);
if (text_underline_position == kTextUnderlinePositionLeft)
@@ -6357,8 +6357,12 @@ const CSSValue* TextUnderlinePosition::CSSValueFromComputedStyleInternal(
return CSSIdentifierValue::Create(CSSValueID::kRight);
CSSValueList* list = CSSValueList::CreateSpaceSeparated();
- DCHECK(text_underline_position & kTextUnderlinePositionUnder);
- list->Append(*CSSIdentifierValue::Create(CSSValueID::kUnder));
+ if (text_underline_position & kTextUnderlinePositionFromFont) {
+ list->Append(*CSSIdentifierValue::Create(CSSValueID::kFromFont));
+ } else {
+ DCHECK(text_underline_position & kTextUnderlinePositionUnder);
+ list->Append(*CSSIdentifierValue::Create(CSSValueID::kUnder));
+ }
if (text_underline_position & kTextUnderlinePositionLeft)
list->Append(*CSSIdentifierValue::Create(CSSValueID::kLeft));
if (text_underline_position & kTextUnderlinePositionRight)
@@ -6372,7 +6376,7 @@ const CSSValue* Top::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext& local_context) const {
return css_parsing_utils::ConsumeMarginOrOffset(
- range, context.Mode(),
+ range, context,
css_parsing_utils::UnitlessUnlessShorthand(local_context));
}
@@ -6490,14 +6494,13 @@ const CSSValue* TransformOrigin::ParseSingleValue(
CSSValue* result_x = nullptr;
CSSValue* result_y = nullptr;
if (css_property_parser_helpers::ConsumeOneOrTwoValuedPosition(
- range, context.Mode(),
- css_property_parser_helpers::UnitlessQuirk::kForbid, result_x,
- result_y)) {
+ range, context, css_property_parser_helpers::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.Mode(), kValueRangeAll);
+ range, context, kValueRangeAll);
if (result_z)
list->Append(*result_z);
return list;
@@ -6549,10 +6552,10 @@ const CSSValue* TransformStyle::CSSValueFromComputedStyleInternal(
const CSSValue* TransitionDelay::ParseSingleValue(
CSSParserTokenRange& range,
- const CSSParserContext&,
+ const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_property_parser_helpers::ConsumeCommaSeparatedList(
- css_property_parser_helpers::ConsumeTime, range, kValueRangeAll);
+ css_property_parser_helpers::ConsumeTime, range, context, kValueRangeAll);
}
const CSSValue* TransitionDelay::CSSValueFromComputedStyleInternal(
@@ -6573,10 +6576,11 @@ const CSSValue* TransitionDelay::InitialValue() const {
const CSSValue* TransitionDuration::ParseSingleValue(
CSSParserTokenRange& range,
- const CSSParserContext&,
+ const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_property_parser_helpers::ConsumeCommaSeparatedList(
- css_property_parser_helpers::ConsumeTime, range, kValueRangeNonNegative);
+ css_property_parser_helpers::ConsumeTime, range, context,
+ kValueRangeNonNegative);
}
const CSSValue* TransitionDuration::CSSValueFromComputedStyleInternal(
@@ -6622,10 +6626,10 @@ const CSSValue* TransitionProperty::InitialValue() const {
const CSSValue* TransitionTimingFunction::ParseSingleValue(
CSSParserTokenRange& range,
- const CSSParserContext&,
+ const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_property_parser_helpers::ConsumeCommaSeparatedList(
- css_parsing_utils::ConsumeAnimationTimingFunction, range);
+ css_parsing_utils::ConsumeAnimationTimingFunction, range, context);
}
const CSSValue* TransitionTimingFunction::CSSValueFromComputedStyleInternal(
@@ -6653,17 +6657,17 @@ const CSSValue* Translate::ParseSingleValue(
return css_property_parser_helpers::ConsumeIdent(range);
CSSValue* translate_x = css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeAll);
+ 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.Mode(),
+ css_property_parser_helpers::ConsumeLengthOrPercent(range, context,
kValueRangeAll);
if (translate_y) {
CSSValue* translate_z = css_property_parser_helpers::ConsumeLength(
- range, context.Mode(), kValueRangeAll);
+ range, context, kValueRangeAll);
if (translate_y->IsZero() && !translate_z)
return list;
@@ -6736,7 +6740,7 @@ const CSSValue* VerticalAlign::ParseSingleValue(
range, CSSValueID::kBaseline, CSSValueID::kWebkitBaselineMiddle);
if (!parsed_value) {
parsed_value = css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeAll,
+ range, context, kValueRangeAll,
css_property_parser_helpers::UnitlessQuirk::kAllow);
}
return parsed_value;
@@ -6842,7 +6846,7 @@ const CSSValue* WebkitBorderHorizontalSpacing::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeLength(range, context.Mode(),
+ return css_property_parser_helpers::ConsumeLength(range, context,
kValueRangeNonNegative);
}
@@ -6883,7 +6887,7 @@ const CSSValue* WebkitBorderVerticalSpacing::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeLength(range, context.Mode(),
+ return css_property_parser_helpers::ConsumeLength(range, context,
kValueRangeNonNegative);
}
@@ -6923,9 +6927,10 @@ const CSSValue* WebkitBoxDirection::CSSValueFromComputedStyleInternal(
const CSSValue* WebkitBoxFlex::ParseSingleValue(
CSSParserTokenRange& range,
- const CSSParserContext&,
+ const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeNumber(range, kValueRangeAll);
+ return css_property_parser_helpers::ConsumeNumber(range, context,
+ kValueRangeAll);
}
const CSSValue* WebkitBoxFlex::CSSValueFromComputedStyleInternal(
@@ -6941,7 +6946,7 @@ const CSSValue* WebkitBoxOrdinalGroup::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumePositiveInteger(range);
+ return css_property_parser_helpers::ConsumePositiveInteger(range, context);
}
const CSSValue* WebkitBoxOrdinalGroup::CSSValueFromComputedStyleInternal(
@@ -6985,7 +6990,7 @@ CSSValue* ConsumeReflect(CSSParserTokenRange& range,
CSSNumericLiteralValue::Create(0, CSSPrimitiveValue::UnitType::kPixels);
} else {
offset = ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeAll,
+ range, context, kValueRangeAll,
css_property_parser_helpers::UnitlessQuirk::kForbid);
if (!offset)
return nullptr;
@@ -7024,7 +7029,7 @@ const CSSValue* WebkitFontSizeDelta::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_property_parser_helpers::ConsumeLength(
- range, context.Mode(), kValueRangeAll,
+ range, context, kValueRangeAll,
css_property_parser_helpers::UnitlessQuirk::kAllow);
}
@@ -7087,7 +7092,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);
+ return css_property_parser_helpers::ConsumePositiveInteger(range, context);
}
const CSSValue* WebkitLineClamp::CSSValueFromComputedStyleInternal(
@@ -7131,43 +7136,11 @@ void WebkitLocale::ApplyValue(StyleResolverState& state,
}
}
-const CSSValue* WebkitMarginAfterCollapse::CSSValueFromComputedStyleInternal(
- const ComputedStyle& style,
- const SVGComputedStyle&,
- const LayoutObject*,
- bool allow_visited_style) const {
- return CSSIdentifierValue::Create(style.MarginAfterCollapse());
-}
-
-const CSSValue* WebkitMarginBeforeCollapse::CSSValueFromComputedStyleInternal(
- const ComputedStyle& style,
- const SVGComputedStyle&,
- const LayoutObject*,
- bool allow_visited_style) const {
- return CSSIdentifierValue::Create(style.MarginBeforeCollapse());
-}
-
-const CSSValue* WebkitMarginBottomCollapse::CSSValueFromComputedStyleInternal(
- const ComputedStyle& style,
- const SVGComputedStyle&,
- const LayoutObject*,
- bool allow_visited_style) const {
- return CSSIdentifierValue::Create(style.MarginAfterCollapse());
-}
-
-const CSSValue* WebkitMarginTopCollapse::CSSValueFromComputedStyleInternal(
- const ComputedStyle& style,
- const SVGComputedStyle&,
- const LayoutObject*,
- bool allow_visited_style) const {
- return CSSIdentifierValue::Create(style.MarginBeforeCollapse());
-}
-
const CSSValue* WebkitMaskBoxImageOutset::ParseSingleValue(
CSSParserTokenRange& range,
- const CSSParserContext&,
+ const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeBorderImageOutset(range);
+ return css_parsing_utils::ConsumeBorderImageOutset(range, context);
}
const CSSValue* WebkitMaskBoxImageOutset::CSSValueFromComputedStyleInternal(
@@ -7196,10 +7169,10 @@ const CSSValue* WebkitMaskBoxImageRepeat::CSSValueFromComputedStyleInternal(
const CSSValue* WebkitMaskBoxImageSlice::ParseSingleValue(
CSSParserTokenRange& range,
- const CSSParserContext&,
+ const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumeBorderImageSlice(
- range, css_parsing_utils::DefaultFill::kNoFill);
+ range, context, css_parsing_utils::DefaultFill::kNoFill);
}
const CSSValue* WebkitMaskBoxImageSlice::CSSValueFromComputedStyleInternal(
@@ -7214,7 +7187,7 @@ const CSSValue* WebkitMaskBoxImageSource::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeImageOrNone(range, &context);
+ return css_property_parser_helpers::ConsumeImageOrNone(range, context);
}
const CSSValue* WebkitMaskBoxImageSource::CSSValueFromComputedStyleInternal(
@@ -7237,9 +7210,9 @@ void WebkitMaskBoxImageSource::ApplyValue(StyleResolverState& state,
const CSSValue* WebkitMaskBoxImageWidth::ParseSingleValue(
CSSParserTokenRange& range,
- const CSSParserContext&,
+ const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_parsing_utils::ConsumeBorderImageWidth(range);
+ return css_parsing_utils::ConsumeBorderImageWidth(range, context);
}
const CSSValue* WebkitMaskBoxImageWidth::CSSValueFromComputedStyleInternal(
@@ -7299,7 +7272,7 @@ const CSSValue* WebkitMaskImage::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_property_parser_helpers::ConsumeCommaSeparatedList(
- css_property_parser_helpers::ConsumeImageOrNone, range, &context);
+ css_property_parser_helpers::ConsumeImageOrNone, range, context);
}
const CSSValue* WebkitMaskImage::CSSValueFromComputedStyleInternal(
@@ -7342,7 +7315,7 @@ const CSSValue* WebkitMaskPositionX::ParseSingleValue(
return css_property_parser_helpers::ConsumeCommaSeparatedList(
css_parsing_utils::ConsumePositionLonghand<CSSValueID::kLeft,
CSSValueID::kRight>,
- range, context.Mode());
+ range, context);
}
const CSSValue* WebkitMaskPositionX::CSSValueFromComputedStyleInternal(
@@ -7362,7 +7335,7 @@ const CSSValue* WebkitMaskPositionY::ParseSingleValue(
return css_property_parser_helpers::ConsumeCommaSeparatedList(
css_parsing_utils::ConsumePositionLonghand<CSSValueID::kTop,
CSSValueID::kBottom>,
- range, context.Mode());
+ range, context);
}
const CSSValue* WebkitMaskPositionY::CSSValueFromComputedStyleInternal(
@@ -7398,7 +7371,7 @@ const CSSValue* WebkitPerspectiveOriginX::ParseSingleValue(
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumePositionLonghand<CSSValueID::kLeft,
CSSValueID::kRight>(
- range, context.Mode());
+ range, context);
}
const CSSValue* WebkitPerspectiveOriginY::ParseSingleValue(
@@ -7407,7 +7380,7 @@ const CSSValue* WebkitPerspectiveOriginY::ParseSingleValue(
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumePositionLonghand<CSSValueID::kTop,
CSSValueID::kBottom>(
- range, context.Mode());
+ range, context);
}
const CSSValue* WebkitPrintColorAdjust::CSSValueFromComputedStyleInternal(
@@ -7440,7 +7413,7 @@ const CSSValue* WebkitTapHighlightColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context.Mode());
+ return css_property_parser_helpers::ConsumeColor(range, context);
}
const blink::Color WebkitTapHighlightColor::ColorIncludingFallback(
@@ -7492,7 +7465,7 @@ const CSSValue* WebkitTextEmphasisColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context.Mode());
+ return css_property_parser_helpers::ConsumeColor(range, context);
}
const blink::Color WebkitTextEmphasisColor::ColorIncludingFallback(
@@ -7717,7 +7690,7 @@ const CSSValue* WebkitTextFillColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context.Mode());
+ return css_property_parser_helpers::ConsumeColor(range, context);
}
const blink::Color WebkitTextFillColor::ColorIncludingFallback(
@@ -7764,7 +7737,7 @@ const CSSValue* WebkitTextStrokeColor::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeColor(range, context.Mode());
+ return css_property_parser_helpers::ConsumeColor(range, context);
}
const blink::Color WebkitTextStrokeColor::ColorIncludingFallback(
@@ -7788,8 +7761,7 @@ const CSSValue* WebkitTextStrokeWidth::ParseSingleValue(
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_property_parser_helpers::ConsumeLineWidth(
- range, context.Mode(),
- css_property_parser_helpers::UnitlessQuirk::kForbid);
+ range, context, css_property_parser_helpers::UnitlessQuirk::kForbid);
}
const CSSValue* WebkitTextStrokeWidth::CSSValueFromComputedStyleInternal(
@@ -7806,7 +7778,7 @@ const CSSValue* WebkitTransformOriginX::ParseSingleValue(
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumePositionLonghand<CSSValueID::kLeft,
CSSValueID::kRight>(
- range, context.Mode());
+ range, context);
}
const CSSValue* WebkitTransformOriginY::ParseSingleValue(
@@ -7815,14 +7787,14 @@ const CSSValue* WebkitTransformOriginY::ParseSingleValue(
const CSSParserLocalContext&) const {
return css_parsing_utils::ConsumePositionLonghand<CSSValueID::kTop,
CSSValueID::kBottom>(
- range, context.Mode());
+ range, context);
}
const CSSValue* WebkitTransformOriginZ::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumeLength(range, context.Mode(),
+ return css_property_parser_helpers::ConsumeLength(range, context,
kValueRangeAll);
}
@@ -7867,7 +7839,7 @@ const CSSValue* WhiteSpace::CSSValueFromComputedStyleInternal(
const CSSValue* Widows::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
- return css_property_parser_helpers::ConsumePositiveInteger(range);
+ return css_property_parser_helpers::ConsumePositiveInteger(range, context);
}
const CSSValue* Widows::CSSValueFromComputedStyleInternal(
@@ -7917,13 +7889,13 @@ const CSSValue* WillChange::ParseSingleValue(
while (true) {
if (range.Peek().GetType() != kIdentToken)
return nullptr;
- CSSPropertyID unresolved_property =
- UnresolvedCSSPropertyID(range.Peek().Value());
+ CSSPropertyID unresolved_property = UnresolvedCSSPropertyID(
+ context.GetExecutionContext(), range.Peek().Value());
if (unresolved_property != CSSPropertyID::kInvalid &&
unresolved_property != CSSPropertyID::kVariable) {
#if DCHECK_IS_ON()
DCHECK(CSSProperty::Get(resolveCSSPropertyID(unresolved_property))
- .IsWebExposed());
+ .IsWebExposed(context.GetExecutionContext()));
#endif
// Now "all" is used by both CSSValue and CSSPropertyValue.
// Need to return nullptr when currentValue is CSSPropertyID::kAll.
@@ -8095,7 +8067,7 @@ const CSSValue* ZIndex::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserLocalContext&) const {
if (range.Peek().Id() == CSSValueID::kAuto)
return css_property_parser_helpers::ConsumeIdent(range);
- return css_property_parser_helpers::ConsumeInteger(range);
+ return css_property_parser_helpers::ConsumeInteger(range, context);
}
const CSSValue* ZIndex::CSSValueFromComputedStyleInternal(
@@ -8118,10 +8090,10 @@ const CSSValue* Zoom::ParseSingleValue(CSSParserTokenRange& range,
zoom =
css_property_parser_helpers::ConsumeIdent<CSSValueID::kNormal>(range);
} else {
- zoom = css_property_parser_helpers::ConsumePercent(range,
+ zoom = css_property_parser_helpers::ConsumePercent(range, context,
kValueRangeNonNegative);
if (!zoom) {
- zoom = css_property_parser_helpers::ConsumeNumber(range,
+ zoom = css_property_parser_helpers::ConsumeNumber(range, context,
kValueRangeNonNegative);
}
}
@@ -8157,5 +8129,13 @@ void Zoom::ApplyValue(StyleResolverState& state, const CSSValue& value) const {
state.SetZoom(StyleBuilderConverter::ConvertZoom(state, value));
}
+const CSSValue* InternalEmptyLineHeight::ParseSingleValue(
+ CSSParserTokenRange& range,
+ const CSSParserContext&,
+ const CSSParserLocalContext&) const {
+ return css_property_parser_helpers::ConsumeIdent<CSSValueID::kFabricated,
+ CSSValueID::kNone>(range);
+}
+
} // namespace css_longhand
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/properties/longhands/variable.h b/chromium/third_party/blink/renderer/core/css/properties/longhands/variable.h
index fd5cd2ec39b..db5c776088c 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/longhands/variable.h
+++ b/chromium/third_party/blink/renderer/core/css/properties/longhands/variable.h
@@ -35,7 +35,8 @@ class CORE_EXPORT Variable : public Longhand {
protected:
constexpr Variable(bool inherited)
: Longhand(CSSPropertyID::kVariable,
- kProperty | (inherited ? kInherited : 0),
+ kProperty | (inherited ? kInherited : 0) |
+ kValidForFirstLetter | kValidForMarker,
'\0') {}
};
diff --git a/chromium/third_party/blink/renderer/core/css/properties/shorthand.h b/chromium/third_party/blink/renderer/core/css/properties/shorthand.h
index a4743b279ae..6970ad40902 100644
--- a/chromium/third_party/blink/renderer/core/css/properties/shorthand.h
+++ b/chromium/third_party/blink/renderer/core/css/properties/shorthand.h
@@ -31,9 +31,7 @@ class Shorthand : public CSSProperty {
}
protected:
- constexpr Shorthand(CSSPropertyID id,
- uint16_t flags,
- char repetition_separator)
+ constexpr Shorthand(CSSPropertyID id, Flags flags, char repetition_separator)
: CSSProperty(id, flags | kShorthand, repetition_separator) {}
};
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 914931a252d..657fd78d604 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
@@ -43,20 +43,21 @@ CSSValue* ConsumeAnimationValue(CSSPropertyID property,
bool use_legacy_parsing) {
switch (property) {
case CSSPropertyID::kAnimationDelay:
- return css_property_parser_helpers::ConsumeTime(range, kValueRangeAll);
+ return css_property_parser_helpers::ConsumeTime(range, context,
+ kValueRangeAll);
case CSSPropertyID::kAnimationDirection:
return css_property_parser_helpers::ConsumeIdent<
CSSValueID::kNormal, CSSValueID::kAlternate, CSSValueID::kReverse,
CSSValueID::kAlternateReverse>(range);
case CSSPropertyID::kAnimationDuration:
- return css_property_parser_helpers::ConsumeTime(range,
+ return css_property_parser_helpers::ConsumeTime(range, context,
kValueRangeNonNegative);
case CSSPropertyID::kAnimationFillMode:
return css_property_parser_helpers::ConsumeIdent<
CSSValueID::kNone, CSSValueID::kForwards, CSSValueID::kBackwards,
CSSValueID::kBoth>(range);
case CSSPropertyID::kAnimationIterationCount:
- return css_parsing_utils::ConsumeAnimationIterationCount(range);
+ return css_parsing_utils::ConsumeAnimationIterationCount(range, context);
case CSSPropertyID::kAnimationName:
return css_parsing_utils::ConsumeAnimationName(range, context,
use_legacy_parsing);
@@ -65,7 +66,7 @@ CSSValue* ConsumeAnimationValue(CSSPropertyID property,
CSSValueID::kPaused>(
range);
case CSSPropertyID::kAnimationTimingFunction:
- return css_parsing_utils::ConsumeAnimationTimingFunction(range);
+ return css_parsing_utils::ConsumeAnimationTimingFunction(range, context);
default:
NOTREACHED();
return nullptr;
@@ -670,7 +671,7 @@ bool BorderRadius::ParseShorthand(
CSSValue* vertical_radii[4] = {nullptr};
if (!css_parsing_utils::ConsumeRadii(horizontal_radii, vertical_radii, range,
- context.Mode(),
+ context,
local_context.UseAliasParsing()))
return false;
@@ -739,14 +740,14 @@ bool BorderSpacing::ParseShorthand(
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
CSSValue* horizontal_spacing =
- ConsumeLength(range, context.Mode(), kValueRangeNonNegative,
+ ConsumeLength(range, context, kValueRangeNonNegative,
css_property_parser_helpers::UnitlessQuirk::kAllow);
if (!horizontal_spacing)
return false;
CSSValue* vertical_spacing = horizontal_spacing;
if (!range.AtEnd()) {
vertical_spacing =
- ConsumeLength(range, context.Mode(), kValueRangeNonNegative,
+ ConsumeLength(range, context, kValueRangeNonNegative,
css_property_parser_helpers::UnitlessQuirk::kAllow);
}
if (!vertical_spacing || !range.AtEnd())
@@ -854,15 +855,15 @@ const CSSValue* ColumnRule::CSSValueFromComputedStyleInternal(
bool Columns::ParseShorthand(
bool important,
CSSParserTokenRange& range,
- const CSSParserContext&,
+ const CSSParserContext& context,
const CSSParserLocalContext&,
HeapVector<CSSPropertyValue, 256>& properties) const {
CSSValue* column_width = nullptr;
CSSValue* column_count = nullptr;
- if (!css_parsing_utils::ConsumeColumnWidthOrCount(range, column_width,
- column_count))
+ if (!css_parsing_utils::ConsumeColumnWidthOrCount(range, context,
+ column_width, column_count))
return false;
- css_parsing_utils::ConsumeColumnWidthOrCount(range, column_width,
+ css_parsing_utils::ConsumeColumnWidthOrCount(range, context, column_width,
column_count);
if (!range.AtEnd())
return false;
@@ -909,7 +910,7 @@ bool Flex::ParseShorthand(bool important,
unsigned index = 0;
while (!range.AtEnd() && index++ < 3) {
double num;
- if (css_property_parser_helpers::ConsumeNumberRaw(range, num)) {
+ if (css_property_parser_helpers::ConsumeNumberRaw(range, context, num)) {
if (num < 0)
return false;
if (flex_grow == kUnsetValue) {
@@ -930,7 +931,7 @@ bool Flex::ParseShorthand(bool important,
flex_basis = css_property_parser_helpers::ConsumeIdent(range);
if (!flex_basis) {
flex_basis = css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeNonNegative);
+ range, context, kValueRangeNonNegative);
}
if (index == 2 && !range.AtEnd())
return false;
@@ -1095,7 +1096,7 @@ bool ConsumeFont(bool important,
}
if (!font_style &&
(id == CSSValueID::kItalic || id == CSSValueID::kOblique)) {
- font_style = css_parsing_utils::ConsumeFontStyle(range, context.Mode());
+ font_style = css_parsing_utils::ConsumeFontStyle(range, context);
if (!font_style)
return false;
continue;
@@ -1109,7 +1110,7 @@ bool ConsumeFont(bool important,
continue;
}
if (!font_weight) {
- font_weight = css_parsing_utils::ConsumeFontWeight(range, context.Mode());
+ font_weight = css_parsing_utils::ConsumeFontWeight(range, context);
if (font_weight)
continue;
}
@@ -1182,7 +1183,7 @@ bool ConsumeFont(bool important,
if (css_property_parser_helpers::ConsumeSlashIncludingWhitespace(range)) {
CSSValue* line_height =
- css_parsing_utils::ConsumeLineHeight(range, context.Mode());
+ css_parsing_utils::ConsumeLineHeight(range, context);
if (!line_height)
return false;
css_property_parser_helpers::AddProperty(
@@ -1628,23 +1629,22 @@ bool Grid::ParseShorthand(bool important,
auto_rows_value = CSSInitialValue::Create();
} else {
auto_rows_value = css_parsing_utils::ConsumeGridTrackList(
- range, context, context.Mode(),
- css_parsing_utils::TrackListType::kGridAuto);
+ range, context, css_parsing_utils::TrackListType::kGridAuto);
if (!auto_rows_value)
return false;
if (!css_property_parser_helpers::ConsumeSlashIncludingWhitespace(range))
return false;
}
if (!(template_columns =
- css_parsing_utils::ConsumeGridTemplatesRowsOrColumns(
- range, context, context.Mode())))
+ css_parsing_utils::ConsumeGridTemplatesRowsOrColumns(range,
+ context)))
return false;
template_rows = CSSInitialValue::Create();
auto_columns_value = CSSInitialValue::Create();
} else {
// 3- <grid-template-rows> / [ auto-flow && dense? ] <grid-auto-columns>?
- template_rows = css_parsing_utils::ConsumeGridTemplatesRowsOrColumns(
- range, context, context.Mode());
+ template_rows =
+ css_parsing_utils::ConsumeGridTemplatesRowsOrColumns(range, context);
if (!template_rows)
return false;
if (!css_property_parser_helpers::ConsumeSlashIncludingWhitespace(range))
@@ -1657,8 +1657,7 @@ bool Grid::ParseShorthand(bool important,
auto_columns_value = CSSInitialValue::Create();
} else {
auto_columns_value = css_parsing_utils::ConsumeGridTrackList(
- range, context, context.Mode(),
- css_parsing_utils::TrackListType::kGridAuto);
+ range, context, css_parsing_utils::TrackListType::kGridAuto);
if (!auto_columns_value)
return false;
}
@@ -1923,25 +1922,6 @@ const CSSValue* InsetInline::CSSValueFromComputedStyleInternal(
insetInlineShorthand(), style, layout_object, allow_visited_style);
}
-bool IntrinsicSize::ParseShorthand(
- bool important,
- CSSParserTokenRange& range,
- const CSSParserContext& context,
- const CSSParserLocalContext&,
- HeapVector<CSSPropertyValue, 256>& properties) const {
- return css_property_parser_helpers::ConsumeShorthandVia2Longhands(
- intrinsicSizeShorthand(), important, context, range, properties);
-}
-
-const CSSValue* IntrinsicSize::CSSValueFromComputedStyleInternal(
- const ComputedStyle& style,
- const SVGComputedStyle&,
- const LayoutObject* layout_object,
- bool allow_visited_style) const {
- return ComputedStyleUtils::ValuesForIntrinsicSizeShorthand(
- intrinsicSizeShorthand(), style, layout_object, allow_visited_style);
-}
-
bool ListStyle::ParseShorthand(
bool important,
CSSParserTokenRange& range,
@@ -2165,11 +2145,11 @@ bool Offset::ParseShorthand(
const CSSValue* offset_rotate = nullptr;
if (offset_path) {
offset_distance = css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeAll);
+ range, context, kValueRangeAll);
offset_rotate = css_parsing_utils::ConsumeOffsetRotate(range, context);
if (offset_rotate && !offset_distance) {
offset_distance = css_property_parser_helpers::ConsumeLengthOrPercent(
- range, context.Mode(), kValueRangeAll);
+ range, context, kValueRangeAll);
}
}
const CSSValue* offset_anchor = nullptr;
@@ -2784,14 +2764,15 @@ CSSValue* ConsumeTransitionValue(CSSPropertyID property,
bool use_legacy_parsing) {
switch (property) {
case CSSPropertyID::kTransitionDelay:
- return css_property_parser_helpers::ConsumeTime(range, kValueRangeAll);
+ return css_property_parser_helpers::ConsumeTime(range, context,
+ kValueRangeAll);
case CSSPropertyID::kTransitionDuration:
- return css_property_parser_helpers::ConsumeTime(range,
+ return css_property_parser_helpers::ConsumeTime(range, context,
kValueRangeNonNegative);
case CSSPropertyID::kTransitionProperty:
return css_parsing_utils::ConsumeTransitionProperty(range, context);
case CSSPropertyID::kTransitionTimingFunction:
- return css_parsing_utils::ConsumeAnimationTimingFunction(range);
+ return css_parsing_utils::ConsumeAnimationTimingFunction(range, context);
default:
NOTREACHED();
return nullptr;
@@ -2959,45 +2940,6 @@ const CSSValue* WebkitColumnBreakInside::CSSValueFromComputedStyleInternal(
style.BreakInside());
}
-bool WebkitMarginCollapse::ParseShorthand(
- bool important,
- CSSParserTokenRange& range,
- const CSSParserContext& context,
- const CSSParserLocalContext&,
- HeapVector<CSSPropertyValue, 256>& properties) const {
- CSSValueID id = range.ConsumeIncludingWhitespace().Id();
- if (!CSSParserFastPaths::IsValidKeywordPropertyAndValue(
- CSSPropertyID::kWebkitMarginBeforeCollapse, id, context.Mode()))
- return false;
-
- CSSValue* before_collapse = CSSIdentifierValue::Create(id);
- css_property_parser_helpers::AddProperty(
- CSSPropertyID::kWebkitMarginBeforeCollapse,
- CSSPropertyID::kWebkitMarginCollapse, *before_collapse, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
-
- if (range.AtEnd()) {
- css_property_parser_helpers::AddProperty(
- CSSPropertyID::kWebkitMarginAfterCollapse,
- CSSPropertyID::kWebkitMarginCollapse, *before_collapse, important,
- css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- return true;
- }
-
- id = range.ConsumeIncludingWhitespace().Id();
- if (!CSSParserFastPaths::IsValidKeywordPropertyAndValue(
- CSSPropertyID::kWebkitMarginAfterCollapse, id, context.Mode()))
- return false;
- css_property_parser_helpers::AddProperty(
- CSSPropertyID::kWebkitMarginAfterCollapse,
- CSSPropertyID::kWebkitMarginCollapse, *CSSIdentifierValue::Create(id),
- important, css_property_parser_helpers::IsImplicitProperty::kNotImplicit,
- properties);
- return true;
-}
-
bool WebkitMaskBoxImage::ParseShorthand(
bool important,
CSSParserTokenRange& range,
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 fe76bb0476c..4ac80062d6c 100644
--- a/chromium/third_party/blink/renderer/core/css/property_registration.cc
+++ b/chromium/third_party/blink/renderer/core/css/property_registration.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/css/property_registration.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_property_definition.h"
#include "third_party/blink/renderer/core/animation/css_interpolation_types_map.h"
#include "third_party/blink/renderer/core/css/css_custom_property_declaration.h"
#include "third_party/blink/renderer/core/css/css_identifier_value.h"
@@ -16,7 +17,6 @@
#include "third_party/blink/renderer/core/css/parser/css_parser_context.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/property_definition.h"
#include "third_party/blink/renderer/core/css/property_registry.h"
#include "third_party/blink/renderer/core/css/resolver/style_builder_converter.h"
#include "third_party/blink/renderer/core/css/style_change_reason.h"
@@ -24,16 +24,17 @@
#include "third_party/blink/renderer/core/css/style_rule.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/frame/local_dom_window.h"
namespace blink {
const PropertyRegistration* PropertyRegistration::From(
const ExecutionContext* execution_context,
const AtomicString& property_name) {
- const auto* document = DynamicTo<Document>(execution_context);
- if (!document)
+ const auto* window = DynamicTo<LocalDOMWindow>(execution_context);
+ if (!window)
return nullptr;
- const PropertyRegistry* registry = document->GetPropertyRegistry();
+ const PropertyRegistry* registry = window->document()->GetPropertyRegistry();
return registry ? registry->Registration(property_name) : nullptr;
}
@@ -133,8 +134,8 @@ PropertyRegistration* PropertyRegistration::MaybeCreate(
const CSSParserContext* parser_context =
document.ElementSheet().Contents()->ParserContext();
const bool is_animation_tainted = false;
- initial = syntax->Parse(initial_variable_data->TokenRange(), parser_context,
- is_animation_tainted);
+ initial = syntax->Parse(initial_variable_data->TokenRange(),
+ *parser_context, is_animation_tainted);
if (!initial)
return nullptr;
if (!ComputationallyIndependent(*initial))
@@ -167,7 +168,7 @@ void PropertyRegistration::registerProperty(
return;
}
AtomicString atomic_name(name);
- Document* document = To<Document>(execution_context);
+ Document* document = To<LocalDOMWindow>(execution_context)->document();
PropertyRegistry& registry = *document->GetPropertyRegistry();
if (registry.Registration(atomic_name)) {
exception_state.ThrowDOMException(
@@ -195,7 +196,7 @@ void PropertyRegistration::registerProperty(
const auto tokens = tokenizer.TokenizeToEOF();
bool is_animation_tainted = false;
initial = syntax_definition->Parse(CSSParserTokenRange(tokens),
- parser_context, is_animation_tainted);
+ *parser_context, is_animation_tainted);
if (!initial) {
exception_state.ThrowDOMException(
DOMExceptionCode::kSyntaxError,
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 4562c64397b..7bcdc866b22 100644
--- a/chromium/third_party/blink/renderer/core/css/property_registration.h
+++ b/chromium/third_party/blink/renderer/core/css/property_registration.h
@@ -53,7 +53,7 @@ class CORE_EXPORT PropertyRegistration final
return interpolation_types_;
}
- void Trace(blink::Visitor* visitor) { visitor->Trace(initial_); }
+ void Trace(Visitor* visitor) { visitor->Trace(initial_); }
private:
friend class ::blink::PropertyRegistry;
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 53bea429eec..ad7769a293f 100644
--- a/chromium/third_party/blink/renderer/core/css/property_registry.h
+++ b/chromium/third_party/blink/renderer/core/css/property_registry.h
@@ -23,7 +23,7 @@ class CORE_EXPORT PropertyRegistry : public GarbageCollected<PropertyRegistry> {
RegistrationMap::const_iterator begin() const;
RegistrationMap::const_iterator end() const;
- void Trace(blink::Visitor* visitor) { visitor->Trace(registrations_); }
+ void Trace(Visitor* visitor) { visitor->Trace(registrations_); }
void MarkReferenced(const AtomicString&) const;
bool WasReferenced(const AtomicString&) const;
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 f9c6752cb02..33ab62e21d1 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(blink::Visitor* visitor) {
+void PropertySetCSSStyleDeclaration::Trace(Visitor* visitor) {
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 0c1e52f2ceb..2d7ec1b1076 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
@@ -36,10 +36,12 @@ class MutableCSSPropertyValueSet;
class PropertySetCSSStyleDeclaration
: public AbstractPropertySetCSSStyleDeclaration {
public:
- PropertySetCSSStyleDeclaration(MutableCSSPropertyValueSet& property_set)
- : property_set_(&property_set) {}
+ PropertySetCSSStyleDeclaration(ExecutionContext* execution_context,
+ MutableCSSPropertyValueSet& property_set)
+ : AbstractPropertySetCSSStyleDeclaration(execution_context),
+ property_set_(&property_set) {}
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 29c77e87961..857accbd03e 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(blink::Visitor* visitor) { visitor->Trace(scrollbar); }
+ void Trace(Visitor* visitor) { 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 475ea4d21bc..e00c1c19a0c 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
@@ -4,12 +4,15 @@
#include "third_party/blink/renderer/core/css/remote_font_face_source.h"
+#include "base/metrics/histogram_functions.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_effective_connection_type.h"
#include "third_party/blink/renderer/core/css/css_custom_font_data.h"
#include "third_party/blink/renderer/core/css/css_font_face.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_client.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
@@ -19,65 +22,78 @@
#include "third_party/blink/renderer/platform/fonts/font_description.h"
#include "third_party/blink/renderer/platform/fonts/font_selector.h"
#include "third_party/blink/renderer/platform/fonts/simple_font_data.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.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/loader/fetch/resource_load_priority.h"
#include "third_party/blink/renderer/platform/network/network_state_notifier.h"
namespace blink {
-namespace {
-
-RemoteFontFaceSource::DisplayPeriod ComputePeriod(
- FontDisplay displayValue,
- RemoteFontFaceSource::Phase phase,
- bool is_intervention_triggered) {
- switch (displayValue) {
+RemoteFontFaceSource::DisplayPeriod RemoteFontFaceSource::ComputePeriod()
+ const {
+ switch (display_) {
case kFontDisplayAuto:
- if (is_intervention_triggered)
- return RemoteFontFaceSource::kSwapPeriod;
+ if (is_intervention_triggered_)
+ return kSwapPeriod;
FALLTHROUGH;
case kFontDisplayBlock:
- switch (phase) {
- case RemoteFontFaceSource::kNoLimitExceeded:
- case RemoteFontFaceSource::kShortLimitExceeded:
- return RemoteFontFaceSource::kBlockPeriod;
- case RemoteFontFaceSource::kLongLimitExceeded:
- return RemoteFontFaceSource::kSwapPeriod;
+ switch (phase_) {
+ case kNoLimitExceeded:
+ case kShortLimitExceeded:
+ return kBlockPeriod;
+ case kLongLimitExceeded:
+ return kSwapPeriod;
}
case kFontDisplaySwap:
- return RemoteFontFaceSource::kSwapPeriod;
+ return kSwapPeriod;
case kFontDisplayFallback:
- switch (phase) {
- case RemoteFontFaceSource::kNoLimitExceeded:
- return RemoteFontFaceSource::kBlockPeriod;
- case RemoteFontFaceSource::kShortLimitExceeded:
- return RemoteFontFaceSource::kSwapPeriod;
- case RemoteFontFaceSource::kLongLimitExceeded:
- return RemoteFontFaceSource::kFailurePeriod;
+ switch (phase_) {
+ case kNoLimitExceeded:
+ return kBlockPeriod;
+ case kShortLimitExceeded:
+ return kSwapPeriod;
+ case kLongLimitExceeded:
+ return kFailurePeriod;
+ }
+
+ case kFontDisplayOptional: {
+ const bool use_phase_value =
+ !base::FeatureList::IsEnabled(
+ features::kFontPreloadingDelaysRendering) ||
+ !GetDocument();
+
+ if (use_phase_value) {
+ switch (phase_) {
+ case kNoLimitExceeded:
+ return kBlockPeriod;
+ case kShortLimitExceeded:
+ case kLongLimitExceeded:
+ return kFailurePeriod;
+ }
}
- case kFontDisplayOptional:
- switch (phase) {
- case RemoteFontFaceSource::kNoLimitExceeded:
- return RemoteFontFaceSource::kBlockPeriod;
- case RemoteFontFaceSource::kShortLimitExceeded:
- case RemoteFontFaceSource::kLongLimitExceeded:
- return RemoteFontFaceSource::kFailurePeriod;
+ // We simply skip the block period, as we should never render invisible
+ // fallback for 'font-display: optional'.
+
+ if (GetDocument()->GetFontPreloadManager().RenderingHasBegun()) {
+ if (FinishedFromMemoryCache() ||
+ finished_before_document_rendering_begin_)
+ return kSwapPeriod;
+ return kFailurePeriod;
}
+ return kSwapPeriod;
+ }
case kFontDisplayEnumMax:
NOTREACHED();
break;
}
NOTREACHED();
- return RemoteFontFaceSource::kSwapPeriod;
+ return kSwapPeriod;
}
-} // namespace
-
RemoteFontFaceSource::RemoteFontFaceSource(CSSFontFace* css_font_face,
FontSelector* font_selector,
FontDisplay display)
@@ -89,13 +105,20 @@ RemoteFontFaceSource::RemoteFontFaceSource(CSSFontFace* css_font_face,
font_selector,
ReportOptions::kDoNotReport)),
phase_(kNoLimitExceeded),
- is_intervention_triggered_(ShouldTriggerWebFontsIntervention()) {
+ is_intervention_triggered_(ShouldTriggerWebFontsIntervention()),
+ finished_before_document_rendering_begin_(false) {
DCHECK(face_);
- period_ = ComputePeriod(display_, phase_, is_intervention_triggered_);
+ period_ = ComputePeriod();
}
RemoteFontFaceSource::~RemoteFontFaceSource() = default;
+Document* RemoteFontFaceSource::GetDocument() const {
+ auto* window =
+ DynamicTo<LocalDOMWindow>(font_selector_->GetExecutionContext());
+ return window ? window->document() : nullptr;
+}
+
void RemoteFontFaceSource::Dispose() {
ClearResource();
PruneTable();
@@ -120,8 +143,9 @@ void RemoteFontFaceSource::NotifyFinished(Resource* resource) {
// Prevent promise rejection while shutting down the document.
// See crbug.com/960290
if (execution_context->IsDocument() &&
- To<Document>(execution_context)->IsDetached())
+ To<LocalDOMWindow>(execution_context)->document()->IsDetached()) {
return;
+ }
FontResource* font = ToFontResource(resource);
histograms_.RecordRemoteFont(font);
@@ -131,12 +155,12 @@ void RemoteFontFaceSource::NotifyFinished(Resource* resource) {
// FIXME: Provide more useful message such as OTS rejection reason.
// See crbug.com/97467
if (font->GetStatus() == ResourceStatus::kDecodeError) {
- execution_context->AddConsoleMessage(ConsoleMessage::Create(
+ execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kWarning,
"Failed to decode downloaded font: " + font->Url().ElidedString()));
if (font->OtsParsingMessage().length() > 1) {
- execution_context->AddConsoleMessage(ConsoleMessage::Create(
+ execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kWarning,
"OTS parsing error: " + font->OtsParsingMessage()));
@@ -146,6 +170,17 @@ void RemoteFontFaceSource::NotifyFinished(Resource* resource) {
ClearResource();
PruneTable();
+
+ if (GetDocument() &&
+ !GetDocument()->GetFontPreloadManager().RenderingHasBegun()) {
+ finished_before_document_rendering_begin_ = true;
+ }
+
+ if (FinishedFromMemoryCache())
+ period_ = kNotApplicablePeriod;
+ else
+ UpdatePeriod();
+
if (face_->FontLoaded(this)) {
font_selector_->FontFaceInvalidated();
@@ -186,8 +221,7 @@ void RemoteFontFaceSource::SetDisplay(FontDisplay display) {
}
void RemoteFontFaceSource::UpdatePeriod() {
- DisplayPeriod new_period =
- ComputePeriod(display_, phase_, is_intervention_triggered_);
+ DisplayPeriod new_period = ComputePeriod();
// Fallback font is invisible iff the font is loading and in the block period.
// Invalidate the font if its fallback visibility has changed.
@@ -204,21 +238,19 @@ void RemoteFontFaceSource::UpdatePeriod() {
FontDisplay RemoteFontFaceSource::GetFontDisplayWithFeaturePolicyCheck(
FontDisplay display,
const FontSelector* font_selector,
- ReportOptions report) const {
+ ReportOptions report_option) const {
ExecutionContext* context = font_selector->GetExecutionContext();
if (display != kFontDisplayFallback && display != kFontDisplayOptional &&
context && context->IsDocument() &&
- !To<Document>(context)->IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kFontDisplay, report)) {
+ !context->IsFeatureEnabled(
+ mojom::blink::DocumentPolicyFeature::kFontDisplay, report_option)) {
return kFontDisplayOptional;
}
return display;
}
bool RemoteFontFaceSource::ShouldTriggerWebFontsIntervention() {
- const auto* document =
- DynamicTo<Document>(font_selector_->GetExecutionContext());
- if (!document)
+ if (!IsA<LocalDOMWindow>(font_selector_->GetExecutionContext()))
return false;
WebEffectiveConnectionType connection_type =
@@ -286,7 +318,7 @@ void RemoteFontFaceSource::BeginLoadIfNeeded() {
if (font->StillNeedsLoad()) {
if (font->IsLowPriorityLoadingAllowedForRemoteFont()) {
font_selector_->GetExecutionContext()->AddConsoleMessage(
- ConsoleMessage::Create(
+ MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kIntervention,
mojom::ConsoleMessageLevel::kInfo,
"Slow network is detected. See "
@@ -313,7 +345,7 @@ void RemoteFontFaceSource::BeginLoadIfNeeded() {
face_->DidBeginLoad();
}
-void RemoteFontFaceSource::Trace(blink::Visitor* visitor) {
+void RemoteFontFaceSource::Trace(Visitor* visitor) {
visitor->Trace(face_);
visitor->Trace(font_selector_);
CSSFontFaceSource::Trace(visitor);
@@ -341,13 +373,10 @@ void RemoteFontFaceSource::FontLoadHistograms::LongLimitExceeded() {
void RemoteFontFaceSource::FontLoadHistograms::RecordFallbackTime() {
if (blank_paint_time_.is_null() || blank_paint_time_recorded_)
return;
+ // TODO(https://crbug.com/1049257): This time should be recorded using a more
+ // appropriate UMA helper, since >1% of samples are in the overflow bucket.
base::TimeDelta duration = base::TimeTicks::Now() - blank_paint_time_;
- DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram,
- blank_text_shown_time_histogram,
- ("WebFont.BlankTextShownTime", 0, 10000, 50));
- blank_text_shown_time_histogram.Count(
- base::saturated_cast<base::HistogramBase::Sample>(
- duration.InMilliseconds()));
+ base::UmaHistogramTimes("WebFont.BlankTextShownTime", duration);
blank_paint_time_recorded_ = true;
}
@@ -355,9 +384,7 @@ void RemoteFontFaceSource::FontLoadHistograms::RecordRemoteFont(
const FontResource* font) {
MaySetDataSource(DataSourceForLoadFinish(font));
- DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, cache_hit_histogram,
- ("WebFont.CacheHit", kCacheHitEnumMax));
- cache_hit_histogram.Count(DataSourceMetricsValue());
+ base::UmaHistogramEnumeration("WebFont.CacheHit", DataSourceMetricsValue());
if (data_source_ == kFromDiskCache || data_source_ == kFromNetwork) {
DCHECK(!load_start_time_.is_null());
@@ -383,98 +410,74 @@ void RemoteFontFaceSource::FontLoadHistograms::RecordLoadTimeHistogram(
base::TimeDelta delta) {
CHECK_NE(kFromUnknown, data_source_);
- int duration =
- base::saturated_cast<base::HistogramBase::Sample>(delta.InMilliseconds());
+ // TODO(https://crbug.com/1049257): These times should be recorded using a
+ // more appropriate UMA helper, since >1% of samples are in the overflow
+ // bucket.
if (font->ErrorOccurred()) {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, load_error_histogram,
- ("WebFont.DownloadTime.LoadError", 0, 10000, 50));
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, missed_cache_load_error_histogram,
- ("WebFont.MissedCache.DownloadTime.LoadError", 0, 10000, 50));
- load_error_histogram.Count(duration);
- if (data_source_ == kFromNetwork)
- missed_cache_load_error_histogram.Count(duration);
+ base::UmaHistogramTimes("WebFont.DownloadTime.LoadError", delta);
+ if (data_source_ == kFromNetwork) {
+ base::UmaHistogramTimes("WebFont.MissedCache.DownloadTime.LoadError",
+ delta);
+ }
return;
}
size_t size = font->EncodedSize();
if (size < 10 * 1024) {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, under10k_histogram,
- ("WebFont.DownloadTime.0.Under10KB", 0, 10000, 50));
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, missed_cache_under10k_histogram,
- ("WebFont.MissedCache.DownloadTime.0.Under10KB", 0, 10000, 50));
- under10k_histogram.Count(duration);
- if (data_source_ == kFromNetwork)
- missed_cache_under10k_histogram.Count(duration);
+ base::UmaHistogramTimes("WebFont.DownloadTime.0.Under10KB", delta);
+ if (data_source_ == kFromNetwork) {
+ base::UmaHistogramTimes("WebFont.MissedCache.DownloadTime.0.Under10KB",
+ delta);
+ }
return;
}
if (size < 50 * 1024) {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, under50k_histogram,
- ("WebFont.DownloadTime.1.10KBTo50KB", 0, 10000, 50));
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, missed_cache_under50k_histogram,
- ("WebFont.MissedCache.DownloadTime.1.10KBTo50KB", 0, 10000, 50));
- under50k_histogram.Count(duration);
- if (data_source_ == kFromNetwork)
- missed_cache_under50k_histogram.Count(duration);
+ base::UmaHistogramTimes("WebFont.DownloadTime.1.10KBTo50KB", delta);
+ if (data_source_ == kFromNetwork) {
+ base::UmaHistogramTimes("WebFont.MissedCache.DownloadTime.1.10KBTo50KB",
+ delta);
+ }
return;
}
if (size < 100 * 1024) {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, under100k_histogram,
- ("WebFont.DownloadTime.2.50KBTo100KB", 0, 10000, 50));
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, missed_cache_under100k_histogram,
- ("WebFont.MissedCache.DownloadTime.2.50KBTo100KB", 0, 10000, 50));
- under100k_histogram.Count(duration);
- if (data_source_ == kFromNetwork)
- missed_cache_under100k_histogram.Count(duration);
+ base::UmaHistogramTimes("WebFont.DownloadTime.2.50KBTo100KB", delta);
+ if (data_source_ == kFromNetwork) {
+ base::UmaHistogramTimes("WebFont.MissedCache.DownloadTime.2.50KBTo100KB",
+ delta);
+ }
return;
}
if (size < 1024 * 1024) {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, under1mb_histogram,
- ("WebFont.DownloadTime.3.100KBTo1MB", 0, 10000, 50));
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, missed_cache_under1mb_histogram,
- ("WebFont.MissedCache.DownloadTime.3.100KBTo1MB", 0, 10000, 50));
- under1mb_histogram.Count(duration);
- if (data_source_ == kFromNetwork)
- missed_cache_under1mb_histogram.Count(duration);
+ base::UmaHistogramTimes("WebFont.DownloadTime.3.100KBTo1MB", delta);
+ if (data_source_ == kFromNetwork) {
+ base::UmaHistogramTimes("WebFont.MissedCache.DownloadTime.3.100KBTo1MB",
+ delta);
+ }
return;
}
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, over1mb_histogram,
- ("WebFont.DownloadTime.4.Over1MB", 0, 10000, 50));
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, missed_cache_over1mb_histogram,
- ("WebFont.MissedCache.DownloadTime.4.Over1MB", 0, 10000, 50));
- over1mb_histogram.Count(duration);
- if (data_source_ == kFromNetwork)
- missed_cache_over1mb_histogram.Count(duration);
+ base::UmaHistogramTimes("WebFont.DownloadTime.4.Over1MB", delta);
+ if (data_source_ == kFromNetwork) {
+ base::UmaHistogramTimes("WebFont.MissedCache.DownloadTime.4.Over1MB",
+ delta);
+ }
}
RemoteFontFaceSource::FontLoadHistograms::CacheHitMetrics
RemoteFontFaceSource::FontLoadHistograms::DataSourceMetricsValue() {
switch (data_source_) {
case kFromDataURL:
- return kDataUrl;
+ return CacheHitMetrics::kDataUrl;
case kFromMemoryCache:
- return kMemoryHit;
+ return CacheHitMetrics::kMemoryHit;
case kFromDiskCache:
- return kDiskHit;
+ return CacheHitMetrics::kDiskHit;
case kFromNetwork:
- return kMiss;
+ return CacheHitMetrics::kMiss;
case kFromUnknown:
- // Fall through.
- default:
- NOTREACHED();
+ return CacheHitMetrics::kMiss;
}
- return kMiss;
+ NOTREACHED();
+ return CacheHitMetrics::kMiss;
}
} // namespace blink
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 fa6a90489e8..5476391da88 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
@@ -13,6 +13,7 @@
namespace blink {
class CSSFontFace;
+class Document;
class FontSelector;
class FontCustomPlatformData;
@@ -23,9 +24,6 @@ class RemoteFontFaceSource final : public CSSFontFaceSource,
public:
enum Phase { kNoLimitExceeded, kShortLimitExceeded, kLongLimitExceeded };
- // Periods of the Font Display Timeline.
- // https://drafts.csswg.org/css-fonts-4/#font-display-timeline
- enum DisplayPeriod { kBlockPeriod, kSwapPeriod, kFailurePeriod };
RemoteFontFaceSource(CSSFontFace*, FontSelector*, FontDisplay);
~RemoteFontFaceSource() override;
@@ -50,7 +48,7 @@ class RemoteFontFaceSource final : public CSSFontFaceSource,
bool HadBlankText() override { return histograms_.HadBlankText(); }
void PaintRequested() override { histograms_.FallbackFontPainted(period_); }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
scoped_refptr<SimpleFontData> CreateFontData(
@@ -60,18 +58,31 @@ class RemoteFontFaceSource final : public CSSFontFaceSource,
const FontDescription&);
private:
+ // Periods of the Font Display Timeline.
+ // https://drafts.csswg.org/css-fonts-4/#font-display-timeline
+ // Note that kNotApplicablePeriod is an implementation detail indicating that
+ // the font is loaded from memory cache synchronously, and hence, made
+ // immediately available. As we never need to use a fallback for it, using
+ // other DisplayPeriod values seem artificial. So we use a special value.
+ enum DisplayPeriod {
+ kBlockPeriod,
+ kSwapPeriod,
+ kFailurePeriod,
+ kNotApplicablePeriod
+ };
+
class FontLoadHistograms {
DISALLOW_NEW();
public:
// Should not change following order in CacheHitMetrics to be used for
// metrics values.
- enum CacheHitMetrics {
+ enum class CacheHitMetrics {
kMiss,
kDiskHit,
kDataUrl,
kMemoryHit,
- kCacheHitEnumMax
+ kMaxValue = kMemoryHit,
};
enum DataSource {
kFromUnknown,
@@ -113,6 +124,9 @@ class RemoteFontFaceSource final : public CSSFontFaceSource,
DataSource data_source_;
};
+ Document* GetDocument() const;
+
+ DisplayPeriod ComputePeriod() const;
void UpdatePeriod();
bool ShouldTriggerWebFontsIntervention();
bool IsLowPriorityLoadingAllowedForRemoteFont() const override;
@@ -132,6 +146,7 @@ class RemoteFontFaceSource final : public CSSFontFaceSource,
DisplayPeriod period_;
FontLoadHistograms histograms_;
bool is_intervention_triggered_;
+ bool finished_before_document_rendering_begin_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/cascade_expansion.cc b/chromium/third_party/blink/renderer/core/css/resolver/cascade_expansion.cc
new file mode 100644
index 00000000000..fca902cce4d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/resolver/cascade_expansion.cc
@@ -0,0 +1,189 @@
+// 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/cascade_expansion.h"
+
+#include "third_party/blink/renderer/core/css/resolver/match_result.h"
+#include "third_party/blink/renderer/core/css/rule_set.h"
+
+namespace blink {
+
+namespace {
+
+CascadeFilter AddValidPropertiesFilter(
+ CascadeFilter filter,
+ const MatchedProperties& matched_properties) {
+ switch (static_cast<ValidPropertyFilter>(
+ matched_properties.types_.valid_property_filter)) {
+ case ValidPropertyFilter::kNoFilter:
+ return filter;
+ case ValidPropertyFilter::kCue:
+ return filter.Add(CSSProperty::kValidForCue, false);
+ case ValidPropertyFilter::kFirstLetter:
+ return filter.Add(CSSProperty::kValidForFirstLetter, false);
+ case ValidPropertyFilter::kMarker:
+ return filter.Add(CSSProperty::kValidForMarker, false);
+ }
+}
+
+CascadeFilter AddLinkFilter(CascadeFilter filter,
+ const MatchedProperties& matched_properties) {
+ switch (matched_properties.types_.link_match_type) {
+ case CSSSelector::kMatchVisited:
+ return filter.Add(CSSProperty::kVisited, false);
+ case CSSSelector::kMatchLink:
+ return filter.Add(CSSProperty::kVisited, true);
+ case CSSSelector::kMatchAll:
+ return filter;
+ default:
+ return filter.Add(CSSProperty::kProperty, true);
+ }
+}
+
+CascadeFilter AmendFilter(CascadeFilter filter,
+ const MatchedProperties& matched_properties) {
+ return AddLinkFilter(AddValidPropertiesFilter(filter, matched_properties),
+ matched_properties);
+}
+
+} // anonymous namespace
+
+CascadeExpansion::CascadeExpansion(const MatchedProperties& matched_properties,
+ const Document& document,
+ CascadeFilter filter,
+ size_t matched_properties_index)
+ : document_(document),
+ matched_properties_(matched_properties),
+ size_(matched_properties.properties->PropertyCount()),
+ filter_(AmendFilter(filter, matched_properties)),
+ matched_properties_index_(matched_properties_index) {
+ // We can't handle a MatchResult with more than 0xFFFF MatchedProperties,
+ // or a MatchedProperties object with more than 0xFFFF declarations. If this
+ // happens, we skip right to the end, and emit nothing.
+ if (size_ > kMaxDeclarationIndex + 1 ||
+ matched_properties_index_ > kMaxMatchedPropertiesIndex) {
+ index_ = size_;
+ } else {
+ Next();
+ }
+}
+
+CascadeExpansion::CascadeExpansion(const CascadeExpansion& o)
+ : document_(o.document_),
+ state_(o.state_),
+ matched_properties_(o.matched_properties_),
+ priority_(o.priority_),
+ index_(o.index_),
+ size_(o.size_),
+ filter_(o.filter_),
+ matched_properties_index_(o.matched_properties_index_),
+ id_(o.id_),
+ property_(id_ == CSSPropertyID::kVariable ? &custom_ : o.property_),
+ custom_(o.custom_) {}
+
+void CascadeExpansion::Next() {
+ do {
+ switch (state_) {
+ case State::kInit:
+ AdvanceNormal();
+ break;
+ case State::kNormal:
+ if (ShouldEmitVisited() && AdvanceVisited())
+ break;
+ AdvanceNormal();
+ break;
+ case State::kVisited:
+ AdvanceNormal();
+ break;
+ case State::kAll:
+ AdvanceAll();
+ break;
+ }
+ } while (!AtEnd() && filter_.Rejects(*property_));
+}
+
+bool CascadeExpansion::IsAffectedByAll(CSSPropertyID id) {
+ const CSSProperty& property = CSSProperty::Get(id);
+ return !property.IsShorthand() && property.IsAffectedByAll();
+}
+
+bool CascadeExpansion::ShouldEmitVisited() const {
+ // This check is slightly redundant, as the emitted property would anyway
+ // be skipped by the do-while in Next(). However, it's probably good to avoid
+ // entering State::kVisited at all, if we can avoid it.
+ return !filter_.Rejects(CSSProperty::kVisited, true);
+}
+
+void CascadeExpansion::AdvanceNormal() {
+ state_ = State::kNormal;
+ ++index_;
+ if (AtEnd())
+ return;
+ auto reference = PropertyAt(index_);
+ const auto& metadata = reference.PropertyMetadata();
+ id_ = metadata.property_->PropertyID();
+ priority_ = CascadePriority(
+ matched_properties_.types_.origin, metadata.important_,
+ matched_properties_.types_.tree_order,
+ EncodeMatchResultPosition(matched_properties_index_, index_));
+
+ switch (id_) {
+ case CSSPropertyID::kVariable:
+ custom_ = CustomProperty(reference.Name().ToAtomicString(), document_);
+ property_ = &custom_;
+ break;
+ case CSSPropertyID::kAll:
+ state_ = State::kAll;
+ id_ = firstCSSProperty;
+ property_ = &CSSProperty::Get(id_);
+ // If this DCHECK is triggered, it means firstCSSProperty is not affected
+ // by 'all', and we need a function for figuring out the first property
+ // that _is_ affected by 'all'.
+ DCHECK(IsAffectedByAll(id_));
+ break;
+ default:
+ property_ = metadata.property_;
+ break;
+ }
+
+ DCHECK(property_);
+}
+
+bool CascadeExpansion::AdvanceVisited() {
+ DCHECK(ShouldEmitVisited());
+ DCHECK(property_);
+ const CSSProperty* visited = property_->GetVisitedProperty();
+ if (!visited)
+ return false;
+ property_ = visited;
+ id_ = visited->PropertyID();
+ state_ = State::kVisited;
+ return true;
+}
+
+void CascadeExpansion::AdvanceAll() {
+ state_ = State::kAll;
+
+ int i = static_cast<int>(id_) + 1;
+ int end = kIntLastCSSProperty + 1;
+
+ for (; i < end; ++i) {
+ id_ = convertToCSSPropertyID(i);
+ if (IsAffectedByAll(id_))
+ break;
+ }
+
+ if (i >= end)
+ AdvanceNormal();
+ else
+ property_ = &CSSProperty::Get(id_);
+}
+
+CSSPropertyValueSet::PropertyReference CascadeExpansion::PropertyAt(
+ size_t index) const {
+ DCHECK(!AtEnd());
+ return matched_properties_.properties->PropertyAt(index_);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/cascade_expansion.h b/chromium/third_party/blink/renderer/core/css/resolver/cascade_expansion.h
new file mode 100644
index 00000000000..af6d8d2ca56
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/resolver/cascade_expansion.h
@@ -0,0 +1,143 @@
+// 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_RESOLVER_CASCADE_EXPANSION_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CASCADE_EXPANSION_H_
+
+#include <limits>
+#include "third_party/blink/renderer/core/css/properties/longhands/custom_property.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_filter.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_origin.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_priority.h"
+#include "third_party/blink/renderer/core/style/computed_style_base_constants.h"
+
+namespace blink {
+
+struct MatchedProperties;
+
+inline uint32_t EncodeMatchResultPosition(uint16_t block,
+ uint16_t declaration) {
+ return (static_cast<uint32_t>(block) << 16) | declaration;
+}
+
+inline size_t DecodeMatchedPropertiesIndex(uint32_t position) {
+ return (position >> 16) & 0xFFFF;
+}
+
+inline size_t DecodeDeclarationIndex(uint32_t position) {
+ return position & 0xFFFF;
+}
+
+// CascadeExpansion takes a declaration block (MatchedProperties) and
+// expands the declarations found into the final list of declarations observed
+// by StyleCascade. It exists to prevent callers to deal with the complexity
+// of the 'all' property, '-internal-visited-' properties, '-internal-ua-'
+// properties, and filtering of both regular declarations and "generated"
+// declarations.
+//
+// For example, for the declaration block:
+//
+// top:1px;
+// all:unset;
+// top:2px;
+//
+// CascadeExpansion would emit:
+//
+// top:1px;
+// animation-delay:unset;
+// animation-direction:unset;
+// /* ... <all longhands affected by 'all'> ... */
+// -webkit-text-emphasis:unset;
+// -webkit-text-stroke:unset;
+// top:2px;
+//
+// In other words, 'all' is expanded into the actual longhands it represents.
+// A similar expansion happens for properties which have companion
+// -internal-visited-* properties (depending on inside-link status).
+//
+// Usage:
+//
+// CascadeExpansion e = ...;
+// for (; !e.AtEnd(); a.Next())
+// DoStuff(e);
+//
+class CORE_EXPORT CascadeExpansion {
+ STACK_ALLOCATED();
+
+ enum class State { kInit, kNormal, kVisited, kAll };
+
+ public:
+ // CascadeExpansion objects which exceed these limits will emit nothing.
+ static constexpr size_t kMaxDeclarationIndex =
+ std::numeric_limits<uint16_t>::max();
+ static constexpr size_t kMaxMatchedPropertiesIndex =
+ std::numeric_limits<uint16_t>::max();
+
+ CascadeExpansion(const MatchedProperties&,
+ const Document&,
+ CascadeFilter,
+ size_t matched_properties_index);
+ // We need an explicit copy constructor, since CascadeExpansion has self-
+ // pointers.
+ CascadeExpansion(const CascadeExpansion& o);
+ void Next();
+ inline bool AtEnd() const { return index_ >= size_; }
+ inline CSSPropertyID Id() const { return id_; }
+ inline CSSPropertyName Name() const {
+ if (id_ != CSSPropertyID::kVariable)
+ return CSSPropertyName(id_);
+ return Property().GetCSSPropertyName();
+ }
+ inline const CSSProperty& Property() const {
+ DCHECK(!AtEnd());
+ return *property_;
+ }
+ inline const CSSValue& Value() const {
+ DCHECK(!AtEnd());
+ return PropertyAt(index_).Value();
+ }
+ inline CascadePriority Priority() const { return priority_; }
+
+ private:
+ static bool IsAffectedByAll(CSSPropertyID);
+
+ bool ShouldEmitVisited() const;
+
+ void AdvanceNormal();
+ bool AdvanceVisited();
+ void AdvanceAll();
+
+ CSSPropertyValueSet::PropertyReference PropertyAt(size_t) const;
+
+ const Document& document_;
+ State state_ = State::kInit;
+ const MatchedProperties& matched_properties_;
+
+ // The priority of the current declaration pointed to by index_. This does
+ // not change for generated declarations.
+ CascadePriority priority_;
+
+ // Index and size of the regular declarations. In other words, index_ will
+ // only move during State::kNormal, and not while expanding 'all', etc. It
+ // will always point to a valid index in matched_properties_ (unless we're
+ // AtEnd()).
+ //
+ // Note that this is initialized to ~0 such that the first call to Next()
+ // (done by the constructor) will produce ~0+1 = 0.
+ size_t index_ = std::numeric_limits<size_t>::max();
+ size_t size_;
+
+ CascadeFilter filter_;
+ const size_t matched_properties_index_;
+
+ // The id/property of the current "virtual" declaration. In other words,
+ // the id/property will be updated when expanding 'all', etc.
+ CSSPropertyID id_ = CSSPropertyID::kInvalid;
+ const CSSProperty* property_ = nullptr;
+ CustomProperty custom_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CASCADE_EXPANSION_H_
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/cascade_expansion_test.cc b/chromium/third_party/blink/renderer/core/css/resolver/cascade_expansion_test.cc
new file mode 100644
index 00000000000..dec485885e1
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/resolver/cascade_expansion_test.cc
@@ -0,0 +1,636 @@
+// 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/cascade_expansion.h"
+
+#include "third_party/blink/renderer/core/css/css_property_value_set.h"
+#include "third_party/blink/renderer/core/css/css_selector.h"
+#include "third_party/blink/renderer/core/css/css_test_helpers.h"
+#include "third_party/blink/renderer/core/css/css_unset_value.h"
+#include "third_party/blink/renderer/core/css/resolver/match_result.h"
+#include "third_party/blink/renderer/core/css/rule_set.h"
+#include "third_party/blink/renderer/core/testing/page_test_base.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
+
+namespace blink {
+
+using css_test_helpers::ParseDeclarationBlock;
+
+class CascadeExpansionTest : public PageTestBase {
+ public:
+ CascadeExpansion ExpansionAt(const MatchResult& result,
+ size_t i,
+ CascadeFilter filter = CascadeFilter()) {
+ return CascadeExpansion(result.GetMatchedProperties()[i], GetDocument(),
+ filter, i);
+ }
+
+ Vector<CSSPropertyID> AllProperties(CascadeFilter filter = CascadeFilter()) {
+ Vector<CSSPropertyID> all;
+ for (CSSPropertyID id : CSSPropertyIDList()) {
+ const CSSProperty& property = CSSProperty::Get(id);
+ if (property.IsShorthand())
+ continue;
+ if (!property.IsAffectedByAll())
+ continue;
+ if (filter.Rejects(property))
+ continue;
+ all.push_back(id);
+ }
+ return all;
+ }
+};
+
+TEST_F(CascadeExpansionTest, UARules) {
+ MatchResult result;
+ result.AddMatchedProperties(ParseDeclarationBlock("cursor:help;top:1px"));
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ ASSERT_EQ(1u, result.GetMatchedProperties().size());
+
+ auto e = ExpansionAt(result, 0);
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kCursor, e.Id());
+ EXPECT_EQ(CascadeOrigin::kUserAgent, e.Priority().GetOrigin());
+ e.Next();
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kTop, e.Id());
+ EXPECT_EQ(CascadeOrigin::kUserAgent, e.Priority().GetOrigin());
+ e.Next();
+ EXPECT_TRUE(e.AtEnd());
+}
+
+TEST_F(CascadeExpansionTest, UserRules) {
+ MatchResult result;
+ result.FinishAddingUARules();
+ result.AddMatchedProperties(ParseDeclarationBlock("cursor:help"));
+ result.AddMatchedProperties(ParseDeclarationBlock("float:left"));
+ result.FinishAddingUserRules();
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ ASSERT_EQ(2u, result.GetMatchedProperties().size());
+
+ {
+ auto e = ExpansionAt(result, 0);
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kCursor, e.Id());
+ EXPECT_EQ(CascadeOrigin::kUser, e.Priority().GetOrigin());
+ e.Next();
+ EXPECT_TRUE(e.AtEnd());
+ }
+
+ {
+ auto e = ExpansionAt(result, 1);
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kFloat, e.Id());
+ EXPECT_EQ(CascadeOrigin::kUser, e.Priority().GetOrigin());
+ e.Next();
+ EXPECT_TRUE(e.AtEnd());
+ }
+}
+
+TEST_F(CascadeExpansionTest, AuthorRules) {
+ MatchResult result;
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(ParseDeclarationBlock("cursor:help;top:1px"));
+ result.AddMatchedProperties(ParseDeclarationBlock("float:left"));
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ ASSERT_EQ(2u, result.GetMatchedProperties().size());
+
+ {
+ auto e = ExpansionAt(result, 0);
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kCursor, e.Id());
+ EXPECT_EQ(CascadeOrigin::kAuthor, e.Priority().GetOrigin());
+ e.Next();
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kTop, e.Id());
+ EXPECT_EQ(CascadeOrigin::kAuthor, e.Priority().GetOrigin());
+ e.Next();
+ EXPECT_TRUE(e.AtEnd());
+ }
+
+ {
+ auto e = ExpansionAt(result, 1);
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kFloat, e.Id());
+ EXPECT_EQ(CascadeOrigin::kAuthor, e.Priority().GetOrigin());
+ e.Next();
+ EXPECT_TRUE(e.AtEnd());
+ }
+}
+
+TEST_F(CascadeExpansionTest, AllOriginRules) {
+ MatchResult result;
+ result.AddMatchedProperties(ParseDeclarationBlock("font-size:2px"));
+ result.FinishAddingUARules();
+ result.AddMatchedProperties(ParseDeclarationBlock("cursor:help;top:1px"));
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(ParseDeclarationBlock("left:1px"));
+ result.AddMatchedProperties(ParseDeclarationBlock("float:left"));
+ result.FinishAddingAuthorRulesForTreeScope();
+ result.AddMatchedProperties(ParseDeclarationBlock("bottom:2px"));
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ ASSERT_EQ(5u, result.GetMatchedProperties().size());
+
+ {
+ auto e = ExpansionAt(result, 0);
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kFontSize, e.Id());
+ EXPECT_EQ(CascadeOrigin::kUserAgent, e.Priority().GetOrigin());
+ e.Next();
+ EXPECT_TRUE(e.AtEnd());
+ }
+
+ {
+ auto e = ExpansionAt(result, 1);
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kCursor, e.Id());
+ EXPECT_EQ(CascadeOrigin::kUser, e.Priority().GetOrigin());
+ e.Next();
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kTop, e.Id());
+ EXPECT_EQ(CascadeOrigin::kUser, e.Priority().GetOrigin());
+ e.Next();
+ EXPECT_TRUE(e.AtEnd());
+ }
+
+ {
+ auto e = ExpansionAt(result, 2);
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kLeft, e.Id());
+ EXPECT_EQ(CascadeOrigin::kAuthor, e.Priority().GetOrigin());
+ e.Next();
+ EXPECT_TRUE(e.AtEnd());
+ }
+
+ {
+ auto e = ExpansionAt(result, 3);
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kFloat, e.Id());
+ EXPECT_EQ(CascadeOrigin::kAuthor, e.Priority().GetOrigin());
+ e.Next();
+ EXPECT_TRUE(e.AtEnd());
+ }
+
+ {
+ auto e = ExpansionAt(result, 4);
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kBottom, e.Id());
+ EXPECT_EQ(CascadeOrigin::kAuthor, e.Priority().GetOrigin());
+ e.Next();
+ EXPECT_TRUE(e.AtEnd());
+ }
+}
+
+TEST_F(CascadeExpansionTest, Name) {
+ MatchResult result;
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(ParseDeclarationBlock("--x:1px;--y:2px"));
+ result.AddMatchedProperties(ParseDeclarationBlock("float:left"));
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ ASSERT_EQ(2u, result.GetMatchedProperties().size());
+
+ {
+ auto e = ExpansionAt(result, 0);
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyName("--x"), e.Name());
+ EXPECT_EQ(CSSPropertyID::kVariable, e.Id());
+ e.Next();
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyName("--y"), e.Name());
+ EXPECT_EQ(CSSPropertyID::kVariable, e.Id());
+ e.Next();
+ EXPECT_TRUE(e.AtEnd());
+ }
+
+ {
+ auto e = ExpansionAt(result, 1);
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyName(CSSPropertyID::kFloat), e.Name());
+ EXPECT_EQ(CSSPropertyID::kFloat, e.Id());
+ e.Next();
+ EXPECT_TRUE(e.AtEnd());
+ }
+}
+
+TEST_F(CascadeExpansionTest, Value) {
+ MatchResult result;
+ result.AddMatchedProperties(ParseDeclarationBlock("background-color:red"));
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ ASSERT_EQ(1u, result.GetMatchedProperties().size());
+
+ auto e = ExpansionAt(result, 0);
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kBackgroundColor, e.Id());
+ EXPECT_EQ("red", e.Value().CssText());
+ e.Next();
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kInternalVisitedBackgroundColor, e.Id());
+ EXPECT_EQ("red", e.Value().CssText());
+ e.Next();
+ EXPECT_TRUE(e.AtEnd());
+}
+
+TEST_F(CascadeExpansionTest, LinkOmitted) {
+ MatchResult result;
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(ParseDeclarationBlock("color:red"),
+ CSSSelector::kMatchVisited);
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ ASSERT_EQ(1u, result.GetMatchedProperties().size());
+
+ auto e = ExpansionAt(result, 0);
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kInternalVisitedColor, e.Id());
+ e.Next();
+ EXPECT_TRUE(e.AtEnd());
+}
+
+TEST_F(CascadeExpansionTest, InternalVisited) {
+ MatchResult result;
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(ParseDeclarationBlock("color:red"));
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ ASSERT_EQ(1u, result.GetMatchedProperties().size());
+
+ auto e = ExpansionAt(result, 0);
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kColor, e.Id());
+ e.Next();
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kInternalVisitedColor, e.Id());
+ e.Next();
+ EXPECT_TRUE(e.AtEnd());
+}
+
+TEST_F(CascadeExpansionTest, InternalVisitedOmitted) {
+ MatchResult result;
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(ParseDeclarationBlock("color:red"),
+ CSSSelector::kMatchLink);
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ ASSERT_EQ(1u, result.GetMatchedProperties().size());
+
+ auto e = ExpansionAt(result, 0);
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kColor, e.Id());
+ e.Next();
+ EXPECT_TRUE(e.AtEnd());
+}
+
+TEST_F(CascadeExpansionTest, InternalVisitedWithTrailer) {
+ MatchResult result;
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(ParseDeclarationBlock("color:red;left:1px"));
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ ASSERT_EQ(1u, result.GetMatchedProperties().size());
+
+ auto e = ExpansionAt(result, 0);
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kColor, e.Id());
+ e.Next();
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kInternalVisitedColor, e.Id());
+ e.Next();
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kLeft, e.Id());
+ e.Next();
+ EXPECT_TRUE(e.AtEnd());
+}
+
+TEST_F(CascadeExpansionTest, All) {
+ MatchResult result;
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(ParseDeclarationBlock("all:unset"));
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ ASSERT_EQ(1u, result.GetMatchedProperties().size());
+
+ auto e = ExpansionAt(result, 0);
+
+ for (CSSPropertyID expected : AllProperties()) {
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(expected, e.Id());
+ e.Next();
+ }
+
+ EXPECT_TRUE(e.AtEnd());
+}
+
+TEST_F(CascadeExpansionTest, InlineAll) {
+ MatchResult result;
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(
+ ParseDeclarationBlock("left:1px;all:unset;right:1px"));
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ ASSERT_EQ(1u, result.GetMatchedProperties().size());
+
+ auto e = ExpansionAt(result, 0);
+
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kLeft, e.Id());
+ e.Next();
+
+ for (CSSPropertyID expected : AllProperties()) {
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(expected, e.Id());
+ e.Next();
+ }
+
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kRight, e.Id());
+ e.Next();
+
+ EXPECT_TRUE(e.AtEnd());
+}
+
+TEST_F(CascadeExpansionTest, FilterNormalNonInherited) {
+ MatchResult result;
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(ParseDeclarationBlock("font-size:1px;left:1px"));
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ ASSERT_EQ(1u, result.GetMatchedProperties().size());
+
+ CascadeFilter filter(CSSProperty::kInherited, false);
+
+ auto e = ExpansionAt(result, 0, filter);
+
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kFontSize, e.Id());
+ e.Next();
+
+ EXPECT_TRUE(e.AtEnd());
+}
+
+TEST_F(CascadeExpansionTest, FilterInternalVisited) {
+ MatchResult result;
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(ParseDeclarationBlock("color:red"));
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ CascadeFilter filter(CSSProperty::kVisited, true);
+
+ ASSERT_EQ(1u, result.GetMatchedProperties().size());
+
+ auto e = ExpansionAt(result, 0, filter);
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kColor, e.Id());
+ e.Next();
+ EXPECT_TRUE(e.AtEnd());
+}
+
+TEST_F(CascadeExpansionTest, FilterFirstLetter) {
+ MatchResult result;
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(
+ ParseDeclarationBlock("object-fit:unset;font-size:1px"),
+ CSSSelector::kMatchAll, ValidPropertyFilter::kFirstLetter);
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ auto e = ExpansionAt(result, 0);
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kFontSize, e.Id());
+ e.Next();
+ EXPECT_TRUE(e.AtEnd());
+}
+
+TEST_F(CascadeExpansionTest, FilterCue) {
+ MatchResult result;
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(
+ ParseDeclarationBlock("object-fit:unset;font-size:1px"),
+ CSSSelector::kMatchAll, ValidPropertyFilter::kCue);
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ auto e = ExpansionAt(result, 0);
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kFontSize, e.Id());
+ e.Next();
+ EXPECT_TRUE(e.AtEnd());
+}
+
+TEST_F(CascadeExpansionTest, FilterMarker) {
+ MatchResult result;
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(
+ ParseDeclarationBlock("object-fit:unset;font-size:1px"),
+ CSSSelector::kMatchAll, ValidPropertyFilter::kMarker);
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ auto e = ExpansionAt(result, 0);
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kFontSize, e.Id());
+ e.Next();
+ EXPECT_TRUE(e.AtEnd());
+}
+
+TEST_F(CascadeExpansionTest, FilterAllNonInherited) {
+ MatchResult result;
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(ParseDeclarationBlock("all:unset"));
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ ASSERT_EQ(1u, result.GetMatchedProperties().size());
+
+ CascadeFilter filter(CSSProperty::kInherited, false);
+
+ auto e = ExpansionAt(result, 0, filter);
+
+ for (CSSPropertyID expected : AllProperties(filter)) {
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(expected, e.Id());
+ e.Next();
+ }
+
+ EXPECT_TRUE(e.AtEnd());
+}
+
+TEST_F(CascadeExpansionTest, Importance) {
+ MatchResult result;
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(
+ ParseDeclarationBlock("cursor:help;display:block !important"));
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ ASSERT_EQ(1u, result.GetMatchedProperties().size());
+
+ auto e = ExpansionAt(result, 0);
+
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kCursor, e.Id());
+ EXPECT_FALSE(e.Priority().IsImportant());
+ e.Next();
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kDisplay, e.Id());
+ EXPECT_TRUE(e.Priority().IsImportant());
+ e.Next();
+
+ EXPECT_TRUE(e.AtEnd());
+}
+
+TEST_F(CascadeExpansionTest, AllImportance) {
+ MatchResult result;
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(ParseDeclarationBlock("all:unset !important"));
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ ASSERT_EQ(1u, result.GetMatchedProperties().size());
+
+ auto e = ExpansionAt(result, 0);
+
+ for (CSSPropertyID expected : AllProperties()) {
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(expected, e.Id());
+ EXPECT_TRUE(e.Priority().IsImportant());
+ e.Next();
+ }
+
+ EXPECT_TRUE(e.AtEnd());
+}
+
+TEST_F(CascadeExpansionTest, AllNonImportance) {
+ MatchResult result;
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(ParseDeclarationBlock("all:unset"));
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ ASSERT_EQ(1u, result.GetMatchedProperties().size());
+
+ auto e = ExpansionAt(result, 0);
+
+ for (CSSPropertyID expected : AllProperties()) {
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(expected, e.Id());
+ EXPECT_FALSE(e.Priority().IsImportant());
+ e.Next();
+ }
+
+ EXPECT_TRUE(e.AtEnd());
+}
+
+TEST_F(CascadeExpansionTest, Position) {
+ MatchResult result;
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(ParseDeclarationBlock("left:1px;top:1px"));
+ result.AddMatchedProperties(ParseDeclarationBlock("bottom:1px;right:1px"));
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ ASSERT_EQ(2u, result.GetMatchedProperties().size());
+
+ {
+ auto e = ExpansionAt(result, 0);
+
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kLeft, e.Id());
+ EXPECT_EQ(0u, DecodeMatchedPropertiesIndex(e.Priority().GetPosition()));
+ EXPECT_EQ(0u, DecodeDeclarationIndex(e.Priority().GetPosition()));
+ e.Next();
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kTop, e.Id());
+ EXPECT_EQ(0u, DecodeMatchedPropertiesIndex(e.Priority().GetPosition()));
+ EXPECT_EQ(1u, DecodeDeclarationIndex(e.Priority().GetPosition()));
+ e.Next();
+
+ EXPECT_TRUE(e.AtEnd());
+ }
+
+ {
+ auto e = ExpansionAt(result, 1);
+
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kBottom, e.Id());
+ EXPECT_EQ(1u, DecodeMatchedPropertiesIndex(e.Priority().GetPosition()));
+ EXPECT_EQ(0u, DecodeDeclarationIndex(e.Priority().GetPosition()));
+ e.Next();
+ ASSERT_FALSE(e.AtEnd());
+ EXPECT_EQ(CSSPropertyID::kRight, e.Id());
+ EXPECT_EQ(1u, DecodeMatchedPropertiesIndex(e.Priority().GetPosition()));
+ EXPECT_EQ(1u, DecodeDeclarationIndex(e.Priority().GetPosition()));
+ e.Next();
+
+ EXPECT_TRUE(e.AtEnd());
+ }
+}
+
+TEST_F(CascadeExpansionTest, MatchedPropertiesLimit) {
+ constexpr size_t max = std::numeric_limits<uint16_t>::max();
+
+ static_assert(CascadeExpansion::kMaxMatchedPropertiesIndex == max,
+ "Unexpected max. If the limit increased, evaluate whether it "
+ "still makes sense to run this test");
+
+ auto* set = ParseDeclarationBlock("left:1px");
+
+ MatchResult result;
+ for (size_t i = 0; i < max + 3; ++i)
+ result.AddMatchedProperties(set);
+
+ ASSERT_EQ(max + 3u, result.GetMatchedProperties().size());
+
+ for (size_t i = 0; i < max + 1; ++i)
+ EXPECT_FALSE(ExpansionAt(result, i).AtEnd());
+
+ // The indices beyond the max should not yield anything.
+ EXPECT_TRUE(ExpansionAt(result, max + 1).AtEnd());
+ EXPECT_TRUE(ExpansionAt(result, max + 2).AtEnd());
+}
+
+TEST_F(CascadeExpansionTest, MatchedDeclarationsLimit) {
+ constexpr size_t max = std::numeric_limits<uint16_t>::max();
+
+ static_assert(CascadeExpansion::kMaxDeclarationIndex == max,
+ "Unexpected max. If the limit increased, evaluate whether it "
+ "still makes sense to run this test");
+
+ HeapVector<CSSPropertyValue> declarations(max + 2);
+
+ // Actually give the first index a value, such that the initial call to
+ // Next() does not crash.
+ declarations[0] = CSSPropertyValue(GetCSSPropertyColor(),
+ *cssvalue::CSSUnsetValue::Create());
+
+ MatchResult result;
+ result.AddMatchedProperties(ImmutableCSSPropertyValueSet::Create(
+ declarations.data(), max + 1, kHTMLStandardMode));
+ result.AddMatchedProperties(ImmutableCSSPropertyValueSet::Create(
+ declarations.data(), max + 2, kHTMLStandardMode));
+
+ EXPECT_FALSE(ExpansionAt(result, 0).AtEnd());
+ EXPECT_TRUE(ExpansionAt(result, 1).AtEnd());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/cascade_filter.h b/chromium/third_party/blink/renderer/core/css/resolver/cascade_filter.h
new file mode 100644
index 00000000000..bef63b8bf39
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/resolver/cascade_filter.h
@@ -0,0 +1,101 @@
+// 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_RESOLVER_CASCADE_FILTER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CASCADE_FILTER_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/css/properties/css_property.h"
+
+namespace blink {
+
+// Reject properties with the given flags set or unset.
+//
+// For example, the following applies only inherited properties that don't apply
+// to ::first-letter:
+//
+// CascadeFilter filter;
+// filter = filter.Add(CSSProperty::kInherited, false);
+// filter = filter.Add(CSSProperty::kValidForFirstLetter, true);
+// filter.Reject(GetCSSPropertyColor()); // -> false
+// filter.Reject(GetCSSPropertyDirection()); // -> true
+// filter.Reject(GetCSSPropertyTop()); // -> true
+//
+class CORE_EXPORT CascadeFilter {
+ public:
+ // Empty filter. Rejects nothing.
+ CascadeFilter() = default;
+
+ // Creates a filter with a single rule.
+ //
+ // This is equivalent to:
+ //
+ // CascadeFilter filter;
+ // filter.Add(flag, v);
+ //
+ CascadeFilter(CSSProperty::Flag flag, bool v)
+ : mask_(flag), flags_(v ? flag : 0) {}
+
+ bool operator==(const CascadeFilter& o) const {
+ return mask_ == o.mask_ && flags_ == o.flags_;
+ }
+ bool operator!=(const CascadeFilter& o) const {
+ return mask_ != o.mask_ || flags_ != o.flags_;
+ }
+
+ // Add a given rule to the filter.
+ //
+ // A flag can be rejected when it's either set or unset. For example
+ //
+ // CascadeFilter f1(CSSProperty::kInherited, true); // Rejects inherited
+ // CascadeFilter f2(CSSProperty::kInherited, false); // Rejects non-inherited
+ //
+ // Note that it's not possible to reject both set and unset flags in the same
+ // filter. However, if you wish to reject all properties, you can do so by
+ // using the CSSProperty::kProperty flag.
+ //
+ // Add() will have no effect if there already is a rule for the given flag:
+ //
+ // CascadeFilter filter;
+ // CascadeFilter f1 = filter.Add(CSSProperty::kInherited, true);
+ // CascadeFilter f2 = f1.Add(CSSProperty::kInherited, false);
+ // bool equal = f1 == f2; // true. Second call to Add had to effect.
+ //
+ // If you want to overwrite a previous rule, use Set().
+ CascadeFilter Add(CSSProperty::Flag flag, bool v) const {
+ const CSSProperty::Flags mask = mask_ | flag;
+ const CSSProperty::Flags flags =
+ v ? (flags_ | (flag & ~mask_)) : (flags_ & ~(flag & ~mask_));
+ return CascadeFilter(mask, flags);
+ }
+
+ // Like Add, except overwrites a previous rule for the same flag.
+ CascadeFilter Set(CSSProperty::Flag flag, bool v) const {
+ const CSSProperty::Flags mask = mask_ | flag;
+ const CSSProperty::Flags flags = v ? (flags_ | flag) : (flags_ & ~flag);
+ return CascadeFilter(mask, flags);
+ }
+
+ bool Rejects(const CSSProperty& property) const {
+ return ~(property.GetFlags() ^ flags_) & mask_;
+ }
+
+ bool Rejects(CSSProperty::Flag flag, bool v) const {
+ return ~((v ? flag : 0) ^ flags_) & (mask_ & flag);
+ }
+
+ private:
+ CascadeFilter(CSSProperty::Flags mask, CSSProperty::Flags flags)
+ : mask_(mask), flags_(flags) {}
+ // Specifies which bits are significant in flags_. In other words, mask_
+ // contains a '1' at the corresponding position for each flag seen by
+ // Add().
+ CSSProperty::Flags mask_ = 0;
+ // Contains the flags to exclude. Only bits set in mask_ matter.
+ CSSProperty::Flags flags_ = 0;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CASCADE_FILTER_H_
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/cascade_filter_test.cc b/chromium/third_party/blink/renderer/core/css/resolver/cascade_filter_test.cc
new file mode 100644
index 00000000000..2ef0adaa4f6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/resolver/cascade_filter_test.cc
@@ -0,0 +1,121 @@
+// 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/cascade_filter.h"
+#include <gtest/gtest.h>
+
+namespace blink {
+
+TEST(CascadeFilterTest, FilterNothing) {
+ CascadeFilter filter;
+ EXPECT_FALSE(filter.Rejects(GetCSSPropertyBackgroundColor()));
+ EXPECT_FALSE(filter.Rejects(GetCSSPropertyColor()));
+ EXPECT_FALSE(filter.Rejects(GetCSSPropertyDisplay()));
+ EXPECT_FALSE(filter.Rejects(GetCSSPropertyFloat()));
+ EXPECT_FALSE(filter.Rejects(GetCSSPropertyInternalVisitedColor()));
+}
+
+TEST(CascadeFilterTest, ConstructorBehavesLikeSingleAdd) {
+ EXPECT_EQ(CascadeFilter().Add(CSSProperty::kInherited, true),
+ CascadeFilter(CSSProperty::kInherited, true));
+ EXPECT_EQ(CascadeFilter().Add(CSSProperty::kInherited, false),
+ CascadeFilter(CSSProperty::kInherited, false));
+}
+
+TEST(CascadeFilterTest, Equals) {
+ EXPECT_EQ(CascadeFilter(CSSProperty::kInherited, true),
+ CascadeFilter(CSSProperty::kInherited, true));
+ EXPECT_EQ(CascadeFilter(CSSProperty::kInherited, false),
+ CascadeFilter(CSSProperty::kInherited, false));
+}
+
+TEST(CascadeFilterTest, NotEqualsMask) {
+ EXPECT_NE(CascadeFilter(CSSProperty::kInherited, true),
+ CascadeFilter(CSSProperty::kInherited, false));
+ EXPECT_NE(CascadeFilter(CSSProperty::kInherited, false),
+ CascadeFilter(CSSProperty::kVisited, false));
+ EXPECT_NE(CascadeFilter(CSSProperty::kInherited, false),
+ CascadeFilter(CSSProperty::kInherited, false)
+ .Add(CSSProperty::kVisited, false));
+ EXPECT_NE(CascadeFilter(CSSProperty::kInherited, false), CascadeFilter());
+}
+
+TEST(CascadeFilterTest, FilterInherited) {
+ CascadeFilter filter(CSSProperty::kInherited, true);
+ EXPECT_FALSE(filter.Rejects(GetCSSPropertyBackgroundColor()));
+ EXPECT_TRUE(filter.Rejects(GetCSSPropertyColor()));
+ EXPECT_TRUE(filter.Rejects(GetCSSPropertyFontSize()));
+ EXPECT_FALSE(filter.Rejects(GetCSSPropertyDisplay()));
+ EXPECT_FALSE(filter.Rejects(GetCSSPropertyFloat()));
+ EXPECT_TRUE(filter.Rejects(GetCSSPropertyInternalVisitedColor()));
+}
+
+TEST(CascadeFilterTest, FilterNonInherited) {
+ CascadeFilter filter(CSSProperty::kInherited, false);
+ EXPECT_TRUE(filter.Rejects(GetCSSPropertyBackgroundColor()));
+ EXPECT_FALSE(filter.Rejects(GetCSSPropertyColor()));
+ EXPECT_TRUE(filter.Rejects(GetCSSPropertyDisplay()));
+ EXPECT_TRUE(filter.Rejects(GetCSSPropertyFloat()));
+ EXPECT_FALSE(filter.Rejects(GetCSSPropertyInternalVisitedColor()));
+}
+
+TEST(CascadeFilterTest, FilterVisitedAndInherited) {
+ auto filter = CascadeFilter()
+ .Add(CSSProperty::kVisited, true)
+ .Add(CSSProperty::kInherited, true);
+ EXPECT_FALSE(filter.Rejects(GetCSSPropertyBackgroundColor()));
+ EXPECT_TRUE(filter.Rejects(GetCSSPropertyColor()));
+ EXPECT_FALSE(filter.Rejects(GetCSSPropertyDisplay()));
+ EXPECT_FALSE(filter.Rejects(GetCSSPropertyFloat()));
+ EXPECT_TRUE(filter.Rejects(GetCSSPropertyInternalVisitedBackgroundColor()));
+}
+
+TEST(CascadeFilterTest, FilterVisitedAndNonInherited) {
+ auto filter = CascadeFilter()
+ .Add(CSSProperty::kVisited, true)
+ .Add(CSSProperty::kInherited, false);
+ EXPECT_TRUE(filter.Rejects(GetCSSPropertyBackgroundColor()));
+ EXPECT_FALSE(filter.Rejects(GetCSSPropertyColor()));
+ EXPECT_TRUE(filter.Rejects(GetCSSPropertyDisplay()));
+ EXPECT_TRUE(filter.Rejects(GetCSSPropertyFloat()));
+ EXPECT_TRUE(filter.Rejects(GetCSSPropertyInternalVisitedColor()));
+}
+
+TEST(CascadeFilterTest, RejectFlag) {
+ auto filter = CascadeFilter()
+ .Add(CSSProperty::kVisited, true)
+ .Add(CSSProperty::kInherited, false);
+ EXPECT_TRUE(filter.Rejects(CSSProperty::kVisited, true));
+ EXPECT_TRUE(filter.Rejects(CSSProperty::kInherited, false));
+ EXPECT_FALSE(filter.Rejects(CSSProperty::kVisited, false));
+ EXPECT_FALSE(filter.Rejects(CSSProperty::kInherited, true));
+}
+
+TEST(CascadeFilterTest, AddDoesNotOverwrite) {
+ auto filter = CascadeFilter()
+ .Add(CSSProperty::kVisited, true)
+ .Add(CSSProperty::kInherited, false);
+ EXPECT_TRUE(filter.Rejects(CSSProperty::kVisited, true));
+ EXPECT_TRUE(filter.Rejects(CSSProperty::kInherited, false));
+ filter = filter.Add(CSSProperty::kVisited, false);
+ filter = filter.Add(CSSProperty::kInherited, true);
+ // Add has no effect if flags are already set:
+ EXPECT_TRUE(filter.Rejects(CSSProperty::kVisited, true));
+ EXPECT_TRUE(filter.Rejects(CSSProperty::kInherited, false));
+}
+
+TEST(CascadeFilterTest, SetDoesOverwrite) {
+ auto filter = CascadeFilter()
+ .Add(CSSProperty::kVisited, true)
+ .Add(CSSProperty::kInherited, false);
+ EXPECT_TRUE(filter.Rejects(CSSProperty::kVisited, true));
+ EXPECT_TRUE(filter.Rejects(CSSProperty::kInherited, false));
+ filter = filter.Set(CSSProperty::kVisited, false);
+ filter = filter.Set(CSSProperty::kInherited, true);
+ // Add has no effect if flags are already set:
+ EXPECT_TRUE(filter.Rejects(CSSProperty::kVisited, false));
+ EXPECT_TRUE(filter.Rejects(CSSProperty::kInherited, true));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/cascade_interpolations.h b/chromium/third_party/blink/renderer/core/css/resolver/cascade_interpolations.h
new file mode 100644
index 00000000000..a2a9fb2c43d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/resolver/cascade_interpolations.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_CSS_RESOLVER_CASCADE_INTERPOLATIONS_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CASCADE_INTERPOLATIONS_H_
+
+#include "third_party/blink/renderer/core/animation/interpolation.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_origin.h"
+#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
+
+namespace blink {
+
+class CORE_EXPORT CascadeInterpolations {
+ STACK_ALLOCATED();
+
+ public:
+ static constexpr size_t kMaxEntryIndex = std::numeric_limits<uint16_t>::max();
+
+ struct Entry {
+ DISALLOW_NEW();
+
+ public:
+ const ActiveInterpolationsMap* map = nullptr;
+ CascadeOrigin origin = CascadeOrigin::kNone;
+ };
+
+ void Add(const ActiveInterpolationsMap* map, CascadeOrigin origin) {
+ DCHECK(map);
+ entries_.push_back(Entry{map, origin});
+ }
+
+ bool IsEmpty() const { return GetEntries().IsEmpty(); }
+
+ const Vector<Entry, 4>& GetEntries() const {
+ using EntryVector = Vector<Entry, 4>;
+ DEFINE_STATIC_LOCAL(EntryVector, empty, ());
+ if (entries_.size() > kMaxEntryIndex + 1)
+ return empty;
+ return entries_;
+ }
+
+ void Reset() { entries_.clear(); }
+
+ private:
+ // We need to add at most four entries (see CSSAnimationUpdate):
+ //
+ // 1. Standard property transitions
+ // 2. Standard property animations
+ // 3. Custom property transitions
+ // 4. Custom property animations
+ //
+ // TODO(andruud): Once regular declarations and interpolations are applied
+ // using the same StyleCascade object, we can store standard and custom
+ // property interpolations together, and use Vector<Entry,2> instead.
+ Vector<Entry, 4> entries_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CASCADE_INTERPOLATIONS_H_
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/cascade_interpolations_test.cc b/chromium/third_party/blink/renderer/core/css/resolver/cascade_interpolations_test.cc
new file mode 100644
index 00000000000..005809de63e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/resolver/cascade_interpolations_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/css/resolver/cascade_interpolations.h"
+
+#include <gtest/gtest.h>
+
+namespace blink {
+
+TEST(CascadeInterpolationsTest, Limit) {
+ constexpr size_t max = std::numeric_limits<uint16_t>::max();
+
+ static_assert(CascadeInterpolations::kMaxEntryIndex == max,
+ "Unexpected max. If the limit increased, evaluate whether it "
+ "still makes sense to run this test");
+
+ ActiveInterpolationsMap map;
+
+ CascadeInterpolations interpolations;
+ for (size_t i = 0; i <= max; ++i)
+ interpolations.Add(&map, CascadeOrigin::kAuthor);
+
+ // At maximum
+ EXPECT_FALSE(interpolations.IsEmpty());
+
+ interpolations.Add(&map, CascadeOrigin::kAuthor);
+
+ // Maximum + 1
+ EXPECT_TRUE(interpolations.IsEmpty());
+}
+
+TEST(CascadeInterpolationsTest, Reset) {
+ ActiveInterpolationsMap map;
+
+ CascadeInterpolations interpolations;
+ EXPECT_TRUE(interpolations.IsEmpty());
+
+ interpolations.Add(&map, CascadeOrigin::kAuthor);
+ EXPECT_FALSE(interpolations.IsEmpty());
+
+ interpolations.Reset();
+ EXPECT_TRUE(interpolations.IsEmpty());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/cascade_map.cc b/chromium/third_party/blink/renderer/core/css/resolver/cascade_map.cc
new file mode 100644
index 00000000000..bfe2770df21
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/resolver/cascade_map.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/core/css/resolver/cascade_map.h"
+#include "third_party/blink/renderer/core/css/resolver/css_property_priority.h"
+
+namespace blink {
+
+CascadePriority CascadeMap::At(const CSSPropertyName& name) const {
+ if (name.IsCustomProperty())
+ return custom_properties_.at(name);
+ size_t index = static_cast<size_t>(name.Id());
+ DCHECK_LT(index, static_cast<size_t>(numCSSProperties));
+ return native_property_bits_.test(index)
+ ? reinterpret_cast<const CascadePriority*>(
+ native_properties_)[index]
+ : CascadePriority();
+}
+
+CascadePriority* CascadeMap::Find(const CSSPropertyName& name) {
+ if (name.IsCustomProperty()) {
+ auto iter = custom_properties_.find(name);
+ if (iter != custom_properties_.end())
+ return &iter->value;
+ return nullptr;
+ }
+ size_t index = static_cast<size_t>(name.Id());
+ DCHECK_LT(index, static_cast<size_t>(numCSSProperties));
+ if (!native_property_bits_.test(index))
+ return nullptr;
+ return reinterpret_cast<CascadePriority*>(native_properties_) + index;
+}
+
+void CascadeMap::Add(const CSSPropertyName& name, CascadePriority priority) {
+ if (name.IsCustomProperty()) {
+ DCHECK_NE(CascadeOrigin::kUserAgent, priority.GetOrigin());
+ auto result = custom_properties_.insert(name, priority);
+ if (result.is_new_entry || result.stored_value->value < priority)
+ result.stored_value->value = priority;
+ return;
+ }
+ CSSPropertyID id = name.Id();
+ size_t index = static_cast<size_t>(id);
+ DCHECK_LT(index, static_cast<size_t>(numCSSProperties));
+
+ // Set bit in high_priority_, if appropriate.
+ using HighPriority = CSSPropertyPriorityData<kHighPropertyPriority>;
+ static_assert(static_cast<int>(HighPriority::Last()) < 64,
+ "CascadeMap supports at most 63 high-priority properties");
+ if (HighPriority::PropertyHasPriority(id))
+ high_priority_ |= (1ull << index);
+ CascadePriority* p =
+ reinterpret_cast<CascadePriority*>(native_properties_) + index;
+ if (!native_property_bits_.test(index) || *p < priority) {
+ native_property_bits_.set(index);
+ static_assert(
+ std::is_trivially_destructible<CascadePriority>::value,
+ "~CascadePriority is never called on these CascadePriority objects");
+ new (p) CascadePriority(priority);
+ }
+}
+
+void CascadeMap::Reset() {
+ high_priority_ = 0;
+ native_property_bits_.reset();
+ custom_properties_.clear();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/cascade_map.h b/chromium/third_party/blink/renderer/core/css/resolver/cascade_map.h
new file mode 100644
index 00000000000..249ebcbc6cf
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/resolver/cascade_map.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CASCADE_MAP_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CASCADE_MAP_H_
+
+#include <bitset>
+#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/resolver/cascade_priority.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+
+namespace blink {
+
+// Optimized map from CSSPropertyNames to CascadePriority.
+//
+// Because using a HashMap for everything is quite expensive in terms of
+// performance, this class stores standard (non-custom) properties in a fixed-
+// size array, and only custom properties are stored in a HashMap.
+class CORE_EXPORT CascadeMap {
+ STACK_ALLOCATED();
+
+ public:
+ // Get the CascadePriority for the given CSSPropertyName. If there is no
+ // entry for the given name, CascadePriority() is returned.
+ CascadePriority At(const CSSPropertyName&) const;
+ // Find the CascadePriority location for a given name, if present. If there
+ // is no entry for the given name, nullptr is returned.
+ //
+ // Note that the returned pointer may accessed to change the stored value.
+ //
+ // Note also that calling Add() invalidates the pointer.
+ CascadePriority* Find(const CSSPropertyName&);
+ // Adds an an entry to the map if the incoming priority is greater than or
+ // equal to the current priority for the same name.
+ void Add(const CSSPropertyName&, CascadePriority);
+ // Added properties with CSSPropertyPriority::kHighPropertyPriority cause the
+ // corresponding high_priority_-bit to be set. This provides a fast way to
+ // check which high-priority properties have been added (if any).
+ uint64_t HighPriorityBits() const { return high_priority_; }
+ // Remove all properties (both native and custom) from the CascadeMap.
+ void Reset();
+
+ private:
+ uint64_t high_priority_ = 0;
+ // For performance reasons, a char-array is used to prevent construction of
+ // CascadePriority objects. A companion std::bitset keeps track of which
+ // properties are initialized.
+ std::bitset<numCSSProperties> native_property_bits_;
+ alignas(CascadePriority) char native_properties_[numCSSProperties *
+ sizeof(CascadePriority)];
+ HashMap<CSSPropertyName, CascadePriority> custom_properties_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CASCADE_MAP_H_
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/cascade_map_test.cc b/chromium/third_party/blink/renderer/core/css/resolver/cascade_map_test.cc
new file mode 100644
index 00000000000..0266bf95007
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/resolver/cascade_map_test.cc
@@ -0,0 +1,230 @@
+// 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/cascade_map.h"
+#include <gtest/gtest.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/resolver/cascade_priority.h"
+#include "third_party/blink/renderer/core/css/resolver/css_property_priority.h"
+
+namespace blink {
+
+namespace {
+
+bool AddTo(CascadeMap& map,
+ const CSSPropertyName& name,
+ CascadePriority priority) {
+ CascadePriority before = map.At(name);
+ map.Add(name, priority);
+ CascadePriority after = map.At(name);
+ return before != after;
+}
+
+} // namespace
+
+TEST(CascadeMapTest, Empty) {
+ CascadeMap map;
+ EXPECT_FALSE(map.Find(CSSPropertyName(AtomicString("--x"))));
+ EXPECT_FALSE(map.Find(CSSPropertyName(AtomicString("--y"))));
+ EXPECT_FALSE(map.Find(CSSPropertyName(CSSPropertyID::kColor)));
+ EXPECT_FALSE(map.Find(CSSPropertyName(CSSPropertyID::kDisplay)));
+}
+
+TEST(CascadeMapTest, AddCustom) {
+ CascadeMap map;
+ CascadePriority user(CascadeOrigin::kUser);
+ CascadePriority author(CascadeOrigin::kAuthor);
+ CSSPropertyName x(AtomicString("--x"));
+ CSSPropertyName y(AtomicString("--y"));
+
+ EXPECT_TRUE(AddTo(map, x, user));
+ EXPECT_TRUE(AddTo(map, x, author));
+ EXPECT_FALSE(AddTo(map, x, author));
+ ASSERT_TRUE(map.Find(x));
+ EXPECT_EQ(author, *map.Find(x));
+
+ EXPECT_FALSE(map.Find(y));
+ EXPECT_TRUE(AddTo(map, y, user));
+
+ // --x should be unchanged.
+ ASSERT_TRUE(map.Find(x));
+ EXPECT_EQ(author, *map.Find(x));
+
+ // --y should exist too.
+ ASSERT_TRUE(map.Find(y));
+ EXPECT_EQ(user, *map.Find(y));
+}
+
+TEST(CascadeMapTest, AddNative) {
+ CascadeMap map;
+ CascadePriority user(CascadeOrigin::kUser);
+ CascadePriority author(CascadeOrigin::kAuthor);
+ CSSPropertyName color(CSSPropertyID::kColor);
+ CSSPropertyName display(CSSPropertyID::kDisplay);
+
+ EXPECT_TRUE(AddTo(map, color, user));
+ EXPECT_TRUE(AddTo(map, color, author));
+ EXPECT_FALSE(AddTo(map, color, author));
+ ASSERT_TRUE(map.Find(color));
+ EXPECT_EQ(author, *map.Find(color));
+
+ EXPECT_FALSE(map.Find(display));
+ EXPECT_TRUE(AddTo(map, display, user));
+
+ // color should be unchanged.
+ ASSERT_TRUE(map.Find(color));
+ EXPECT_EQ(author, *map.Find(color));
+
+ // display should exist too.
+ ASSERT_TRUE(map.Find(display));
+ EXPECT_EQ(user, *map.Find(display));
+}
+
+TEST(CascadeMapTest, FindAndMutateCustom) {
+ CascadeMap map;
+ CascadePriority user(CascadeOrigin::kUser);
+ CascadePriority author(CascadeOrigin::kAuthor);
+ CSSPropertyName x(AtomicString("--x"));
+
+ EXPECT_TRUE(AddTo(map, x, user));
+
+ CascadePriority* p = map.Find(x);
+ ASSERT_TRUE(p);
+ EXPECT_EQ(user, *p);
+
+ *p = author;
+
+ EXPECT_FALSE(AddTo(map, x, author));
+ ASSERT_TRUE(map.Find(x));
+ EXPECT_EQ(author, *map.Find(x));
+}
+
+TEST(CascadeMapTest, FindAndMutateNative) {
+ CascadeMap map;
+ CascadePriority user(CascadeOrigin::kUser);
+ CascadePriority author(CascadeOrigin::kAuthor);
+ CSSPropertyName color(CSSPropertyID::kColor);
+
+ EXPECT_TRUE(AddTo(map, color, user));
+
+ CascadePriority* p = map.Find(color);
+ ASSERT_TRUE(p);
+ EXPECT_EQ(user, *p);
+
+ *p = author;
+
+ EXPECT_FALSE(AddTo(map, color, author));
+ ASSERT_TRUE(map.Find(color));
+ EXPECT_EQ(author, *map.Find(color));
+}
+
+TEST(CascadeMapTest, AtCustom) {
+ CascadeMap map;
+ CascadePriority user(CascadeOrigin::kUser);
+ CascadePriority author(CascadeOrigin::kAuthor);
+ CSSPropertyName x(AtomicString("--x"));
+
+ EXPECT_EQ(CascadePriority(), map.At(x));
+
+ EXPECT_TRUE(AddTo(map, x, user));
+ EXPECT_EQ(user, map.At(x));
+
+ EXPECT_TRUE(AddTo(map, x, author));
+ EXPECT_EQ(author, map.At(x));
+}
+
+TEST(CascadeMapTest, AtNative) {
+ CascadeMap map;
+ CascadePriority user(CascadeOrigin::kUser);
+ CascadePriority author(CascadeOrigin::kAuthor);
+ CSSPropertyName color(CSSPropertyID::kColor);
+
+ EXPECT_EQ(CascadePriority(), map.At(color));
+
+ EXPECT_TRUE(AddTo(map, color, user));
+ EXPECT_EQ(user, map.At(color));
+
+ EXPECT_TRUE(AddTo(map, color, author));
+ EXPECT_EQ(author, map.At(color));
+}
+
+TEST(CascadeMapTest, HighPriorityBits) {
+ CascadeMap map;
+
+ EXPECT_FALSE(map.HighPriorityBits());
+
+ map.Add(CSSPropertyName(CSSPropertyID::kFontSize), CascadeOrigin::kAuthor);
+ EXPECT_EQ(map.HighPriorityBits(),
+ 1ull << static_cast<uint64_t>(CSSPropertyID::kFontSize));
+
+ map.Add(CSSPropertyName(CSSPropertyID::kColor), CascadeOrigin::kAuthor);
+ map.Add(CSSPropertyName(CSSPropertyID::kFontSize), CascadeOrigin::kAuthor);
+ EXPECT_EQ(map.HighPriorityBits(),
+ (1ull << static_cast<uint64_t>(CSSPropertyID::kFontSize)) |
+ (1ull << static_cast<uint64_t>(CSSPropertyID::kColor)));
+}
+
+TEST(CascadeMapTest, AllHighPriorityBits) {
+ CascadeMap map;
+
+ EXPECT_FALSE(map.HighPriorityBits());
+
+ uint64_t expected = 0;
+ for (CSSPropertyID id : CSSPropertyIDList()) {
+ if (CSSPropertyPriorityData<kHighPropertyPriority>::PropertyHasPriority(
+ id)) {
+ map.Add(CSSPropertyName(id), CascadeOrigin::kAuthor);
+ expected |= (1ull << static_cast<uint64_t>(id));
+ }
+ }
+
+ EXPECT_EQ(expected, map.HighPriorityBits());
+}
+
+TEST(CascadeMapTest, LastHighPrio) {
+ CascadeMap map;
+
+ EXPECT_FALSE(map.HighPriorityBits());
+
+ CSSPropertyID last = CSSPropertyPriorityData<kHighPropertyPriority>::Last();
+
+ map.Add(CSSPropertyName(last), CascadeOrigin::kAuthor);
+ EXPECT_EQ(map.HighPriorityBits(), 1ull << static_cast<uint64_t>(last));
+}
+
+TEST(CascadeMapTest, Reset) {
+ CascadeMap map;
+
+ CascadePriority author(CascadeOrigin::kAuthor);
+
+ CSSPropertyName color(CSSPropertyID::kColor);
+ CSSPropertyName x(AtomicString("--x"));
+
+ EXPECT_FALSE(map.Find(color));
+ EXPECT_FALSE(map.Find(x));
+
+ map.Add(color, author);
+ map.Add(x, author);
+
+ EXPECT_EQ(author, map.At(color));
+ EXPECT_EQ(author, map.At(x));
+
+ map.Reset();
+
+ EXPECT_FALSE(map.Find(color));
+ EXPECT_FALSE(map.Find(x));
+}
+
+TEST(CascadeMapTest, ResetHighPrio) {
+ CascadeMap map;
+ EXPECT_FALSE(map.HighPriorityBits());
+ map.Add(CSSPropertyName(CSSPropertyID::kFontSize),
+ CascadePriority(CascadeOrigin::kAuthor));
+ EXPECT_TRUE(map.HighPriorityBits());
+ map.Reset();
+ EXPECT_FALSE(map.HighPriorityBits());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/cascade_origin.h b/chromium/third_party/blink/renderer/core/css/resolver/cascade_origin.h
new file mode 100644
index 00000000000..565d5843fe4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/resolver/cascade_origin.h
@@ -0,0 +1,38 @@
+// 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_RESOLVER_CASCADE_ORIGIN_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CASCADE_ORIGIN_H_
+
+#include <cstdint>
+
+namespace blink {
+
+// Represents the origin criteria described by css-cascade [1].
+//
+// [1] https://www.w3.org/TR/css-cascade-3/#cascade-origin
+enum class CascadeOrigin : uint8_t {
+ kNone = 0,
+ kUserAgent = 0b0001,
+ kUser = 0b0010,
+ kAuthor = 0b0011,
+ kAnimation = 0b0100,
+ // The lower four bits of kAuthor, kUser and kUserAgent can be inverted to
+ // efficiently produce a "cascade correct" value when compared with the values
+ // specified in this enum:
+ //
+ // kAuthor important: ~0b0011 == 0b1100 (> kAnimation)
+ // kUser important: ~0b0010 == 0b1101 (> kAuthor important)
+ // kUserAgent important: ~0b0001 == 0b1110 (> kUser important)
+ //
+ // Because kTransition has a higher priority than anything else, it's set to
+ // 0b10000, which is greater than kUserAgent important. Although 0b1111 is
+ // available, we avoid using that such that the fourth bit can be used as
+ // as quick is-important check.
+ kTransition = 0b10000,
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CASCADE_ORIGIN_H_
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
new file mode 100644
index 00000000000..9a49e2c72d2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/resolver/cascade_priority.h
@@ -0,0 +1,107 @@
+// 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_RESOLVER_CASCADE_PRIORITY_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CASCADE_PRIORITY_H_
+
+#include "base/logging.h"
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_origin.h"
+
+namespace blink {
+
+// The origin and importance criteria are evaluated together [1], hence we
+// encode both into a single integer which will do the right thing when compared
+// to another such encoded integer. See CascadeOrigin for more information on
+// how that works.
+//
+// [1] https://www.w3.org/TR/css-cascade-3/#cascade-origin
+inline uint64_t EncodeOriginImportance(CascadeOrigin origin, bool important) {
+ uint8_t important_xor = (static_cast<uint8_t>(!important) - 1) & 0xF;
+ return static_cast<uint64_t>(origin) ^ important_xor;
+}
+
+// Tree order bits are flipped for important declarations to reverse the
+// priority [1].
+//
+// [1] https://drafts.csswg.org/css-scoping/#shadow-cascading
+inline uint64_t EncodeTreeOrder(uint16_t tree_order, bool important) {
+ uint16_t important_xor = static_cast<uint16_t>(!important) - 1;
+ return static_cast<uint64_t>(tree_order) ^ important_xor;
+}
+
+// The CascadePriority class encapsulates a subset of the cascading criteria
+// described by css-cascade [1], and provides a way to compare priorities
+// quickly by encoding all the information in a single integer.
+//
+// It encompasses, from most significant to least significant:
+// Origin/importance; tree order, which is a number representing the
+// shadow-including tree order [2]; position, which contains the index (or
+// indices) required to lookup a declaration in the underlying structure (e.g. a
+// MatchResult); and finally generation, which is a monotonically increasing
+// number generated by StyleCascade for each call to StyleCascade::Apply.
+//
+// [1] https://drafts.csswg.org/css-cascade/#cascading
+// [2] https://drafts.csswg.org/css-scoping/#shadow-cascading
+class CORE_EXPORT CascadePriority {
+ public:
+ // The declaration is important if this bit is set on the encoded priority.
+ static constexpr uint64_t kImportantBit = 55;
+ static constexpr uint64_t kOriginImportanceOffset = 52;
+ static constexpr uint64_t kTreeOrderOffset = 36;
+
+ CascadePriority() : bits_(0) {}
+ CascadePriority(CascadeOrigin origin)
+ : CascadePriority(origin, false, 0, 0) {}
+ CascadePriority(CascadeOrigin origin, bool important)
+ : CascadePriority(origin, important, 0, 0) {}
+ CascadePriority(CascadeOrigin origin, bool important, uint16_t tree_order)
+ : CascadePriority(origin, important, tree_order, 0) {}
+ // For an explanation of 'tree_order', see css-scoping:
+ // https://drafts.csswg.org/css-scoping/#shadow-cascading
+ CascadePriority(CascadeOrigin origin,
+ bool important,
+ uint16_t tree_order,
+ uint32_t position)
+ : bits_(static_cast<uint64_t>(position) << 4 |
+ EncodeTreeOrder(tree_order, important) << kTreeOrderOffset |
+ EncodeOriginImportance(origin, important)
+ << kOriginImportanceOffset) {}
+ // See StyleCascade.generation_.
+ CascadePriority(CascadePriority o, uint8_t generation)
+ : bits_((o.bits_ & ~static_cast<uint8_t>(0xF)) | generation) {
+ DCHECK_LE(generation, 0xF);
+ }
+
+ bool IsImportant() const { return (bits_ >> kImportantBit) & 1; }
+ CascadeOrigin GetOrigin() const {
+ uint64_t important_xor = (((~bits_ >> kImportantBit) & 1) - 1) & 0xF;
+ return static_cast<CascadeOrigin>((bits_ >> kOriginImportanceOffset) ^
+ important_xor);
+ }
+ bool HasOrigin() const { return GetOrigin() != CascadeOrigin::kNone; }
+ uint32_t GetPosition() const { return (bits_ >> 4) & 0xFFFFFFFF; }
+ uint8_t GetGeneration() const { return bits_ & 0xF; }
+
+ bool operator>=(const CascadePriority& o) const { return bits_ >= o.bits_; }
+ bool operator<(const CascadePriority& o) const { return bits_ < o.bits_; }
+ bool operator==(const CascadePriority& o) const { return bits_ == o.bits_; }
+ bool operator!=(const CascadePriority& o) const { return bits_ != o.bits_; }
+
+ private:
+ friend class StyleCascade;
+ friend class StyleCascadeTest;
+
+ CascadePriority(uint64_t bits) : bits_(bits) {}
+
+ // Bit 0-3 : generation
+ // Bit 4-35: position
+ // Bit 36-51: tree_order (encoded)
+ // Bit 52-59: origin/importance (encoded)
+ uint64_t bits_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CASCADE_PRIORITY_H_
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/cascade_priority_test.cc b/chromium/third_party/blink/renderer/core/css/resolver/cascade_priority_test.cc
new file mode 100644
index 00000000000..ddf587267ee
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/resolver/cascade_priority_test.cc
@@ -0,0 +1,249 @@
+// 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/cascade_priority.h"
+#include <gtest/gtest.h>
+
+namespace blink {
+
+namespace {
+
+CascadePriority AuthorPriority(uint16_t tree_order, uint32_t position) {
+ return CascadePriority(CascadeOrigin::kAuthor, false, tree_order, position);
+}
+
+CascadePriority ImportantAuthorPriority(uint16_t tree_order,
+ uint32_t position) {
+ return CascadePriority(CascadeOrigin::kAuthor, true, tree_order, position);
+}
+
+} // namespace
+
+TEST(CascadePriorityTest, EncodeOriginImportance) {
+ using Origin = CascadeOrigin;
+ EXPECT_EQ(0b00001ull, EncodeOriginImportance(Origin::kUserAgent, false));
+ EXPECT_EQ(0b00010ull, EncodeOriginImportance(Origin::kUser, false));
+ EXPECT_EQ(0b00011ull, EncodeOriginImportance(Origin::kAuthor, false));
+ EXPECT_EQ(0b00100ull, EncodeOriginImportance(Origin::kAnimation, false));
+ EXPECT_EQ(0b01100ull, EncodeOriginImportance(Origin::kAuthor, true));
+ EXPECT_EQ(0b01101ull, EncodeOriginImportance(Origin::kUser, true));
+ EXPECT_EQ(0b01110ull, EncodeOriginImportance(Origin::kUserAgent, true));
+ EXPECT_EQ(0b10000ull, EncodeOriginImportance(Origin::kTransition, false));
+}
+
+TEST(CascadePriorityTest, OriginOperators) {
+ std::vector<CascadePriority> priority = {
+ CascadePriority(CascadeOrigin::kTransition, false, 0, 0),
+ CascadePriority(CascadeOrigin::kAnimation, false, 0, 0),
+ CascadePriority(CascadeOrigin::kAuthor, false, 0, 0),
+ CascadePriority(CascadeOrigin::kUser, false, 0, 0),
+ CascadePriority(CascadeOrigin::kUserAgent, false, 0, 0),
+ CascadePriority(CascadeOrigin::kNone, false, 0, 0)};
+
+ for (size_t i = 0; i < priority.size(); ++i) {
+ for (size_t j = i; j < priority.size(); ++j) {
+ EXPECT_GE(priority[i], priority[j]);
+ EXPECT_FALSE(priority[i] < priority[j]);
+ }
+ }
+
+ for (size_t i = 0; i < priority.size(); ++i) {
+ for (size_t j = i + 1; j < priority.size(); ++j) {
+ EXPECT_LT(priority[j], priority[i]);
+ EXPECT_FALSE(priority[j] >= priority[i]);
+ }
+ }
+
+ for (CascadePriority priority : priority)
+ EXPECT_EQ(priority, priority);
+
+ for (size_t i = 0; i < priority.size(); ++i) {
+ for (size_t j = 0; j < priority.size(); ++j) {
+ if (i == j)
+ continue;
+ EXPECT_NE(priority[i], priority[j]);
+ }
+ }
+}
+
+TEST(CascadePriorityTest, OriginImportance) {
+ std::vector<CascadePriority> priority = {
+ CascadePriority(CascadeOrigin::kTransition, false, 0, 0),
+ CascadePriority(CascadeOrigin::kUserAgent, true, 0, 0),
+ CascadePriority(CascadeOrigin::kUser, true, 0, 0),
+ CascadePriority(CascadeOrigin::kAuthor, true, 0, 0),
+ CascadePriority(CascadeOrigin::kAnimation, false, 0, 0),
+ CascadePriority(CascadeOrigin::kAuthor, false, 0, 0),
+ CascadePriority(CascadeOrigin::kUser, false, 0, 0),
+ CascadePriority(CascadeOrigin::kUserAgent, false, 0, 0),
+ CascadePriority(CascadeOrigin::kNone, false, 0, 0)};
+
+ for (size_t i = 0; i < priority.size(); ++i) {
+ for (size_t j = i; j < priority.size(); ++j)
+ EXPECT_GE(priority[i], priority[j]);
+ }
+}
+
+TEST(CascadePriorityTest, IsImportant) {
+ using Priority = CascadePriority;
+ using Origin = CascadeOrigin;
+
+ EXPECT_FALSE(Priority(Origin::kUserAgent, false, 0, 0).IsImportant());
+ EXPECT_FALSE(Priority(Origin::kUser, false, 0, 0).IsImportant());
+ EXPECT_FALSE(Priority(Origin::kAuthor, false, 0, 0).IsImportant());
+ EXPECT_FALSE(Priority(Origin::kAnimation, false, 0, 0).IsImportant());
+ EXPECT_FALSE(Priority(Origin::kTransition, false, 0, 0).IsImportant());
+ EXPECT_FALSE(Priority(Origin::kAuthor, false, 1024, 2048).IsImportant());
+
+ EXPECT_TRUE(Priority(Origin::kUserAgent, true, 0, 0).IsImportant());
+ EXPECT_TRUE(Priority(Origin::kUser, true, 0, 0).IsImportant());
+ EXPECT_TRUE(Priority(Origin::kAuthor, true, 0, 0).IsImportant());
+ EXPECT_TRUE(Priority(Origin::kAnimation, true, 0, 0).IsImportant());
+ EXPECT_TRUE(Priority(Origin::kTransition, true, 0, 0).IsImportant());
+ EXPECT_TRUE(Priority(Origin::kAuthor, true, 1024, 2048).IsImportant());
+}
+
+static std::vector<CascadeOrigin> all_origins = {
+ CascadeOrigin::kUserAgent, CascadeOrigin::kUser, CascadeOrigin::kAuthor,
+ CascadeOrigin::kTransition, CascadeOrigin::kAnimation};
+
+TEST(CascadePriorityTest, GetOrigin) {
+ for (CascadeOrigin origin : all_origins)
+ EXPECT_EQ(CascadePriority(origin, false, 0, 0).GetOrigin(), origin);
+
+ for (CascadeOrigin origin : all_origins) {
+ if (origin == CascadeOrigin::kAnimation)
+ continue;
+ if (origin == CascadeOrigin::kTransition)
+ continue;
+ EXPECT_EQ(CascadePriority(origin, true, 0, 0).GetOrigin(), origin);
+ }
+}
+
+TEST(CascadePriorityTest, HasOrigin) {
+ for (CascadeOrigin origin : all_origins) {
+ if (origin != CascadeOrigin::kNone)
+ EXPECT_TRUE(CascadePriority(origin).HasOrigin());
+ else
+ EXPECT_FALSE(CascadePriority(origin).HasOrigin());
+ }
+ EXPECT_FALSE(CascadePriority().HasOrigin());
+}
+
+TEST(CascadePriorityTest, EncodeTreeOrder) {
+ EXPECT_EQ(0ull, EncodeTreeOrder(0, false));
+ EXPECT_EQ(1ull, EncodeTreeOrder(1, false));
+ EXPECT_EQ(2ull, EncodeTreeOrder(2, false));
+ EXPECT_EQ(100ull, EncodeTreeOrder(100, false));
+ EXPECT_EQ(0xFFFFull, EncodeTreeOrder(0xFFFF, false));
+
+ EXPECT_EQ(0ull ^ 0xFFFF, EncodeTreeOrder(0, true));
+ EXPECT_EQ(1ull ^ 0xFFFF, EncodeTreeOrder(1, true));
+ EXPECT_EQ(2ull ^ 0xFFFF, EncodeTreeOrder(2, true));
+ EXPECT_EQ(100ull ^ 0xFFFF, EncodeTreeOrder(100, true));
+ EXPECT_EQ(0xFFFFull ^ 0xFFFF, EncodeTreeOrder(0xFFFF, true));
+}
+
+TEST(CascadePriorityTest, TreeOrder) {
+ using Priority = CascadePriority;
+ CascadeOrigin origin = CascadeOrigin::kAuthor;
+ EXPECT_GE(Priority(origin, false, 1), Priority(origin, false, 0));
+ EXPECT_GE(Priority(origin, false, 7), Priority(origin, false, 6));
+ EXPECT_GE(Priority(origin, false, 42), Priority(origin, false, 42));
+ EXPECT_FALSE(Priority(origin, false, 1) >= Priority(origin, false, 8));
+}
+
+TEST(CascadePriorityTest, TreeOrderImportant) {
+ using Priority = CascadePriority;
+ CascadeOrigin origin = CascadeOrigin::kAuthor;
+ EXPECT_GE(Priority(origin, true, 0), Priority(origin, true, 1));
+ EXPECT_GE(Priority(origin, true, 6), Priority(origin, true, 7));
+ EXPECT_GE(Priority(origin, true, 42), Priority(origin, true, 42));
+ EXPECT_FALSE(Priority(origin, true, 8) >= Priority(origin, true, 1));
+}
+
+TEST(CascadePriorityTest, TreeOrderDifferentOrigin) {
+ using Priority = CascadePriority;
+ // Tree order does not matter if the origin is different.
+ CascadeOrigin author = CascadeOrigin::kAuthor;
+ CascadeOrigin transition = CascadeOrigin::kTransition;
+ EXPECT_GE(Priority(transition, 1), Priority(author, 42));
+ EXPECT_GE(Priority(transition, 1), Priority(author, 1));
+}
+
+TEST(CascadePriorityTest, Position) {
+ // AuthorPriority(tree_order, position)
+ EXPECT_GE(AuthorPriority(0, 0), AuthorPriority(0, 0));
+ EXPECT_GE(AuthorPriority(0, 1), AuthorPriority(0, 1));
+ EXPECT_GE(AuthorPriority(0, 1), AuthorPriority(0, 0));
+ EXPECT_GE(AuthorPriority(0, 2), AuthorPriority(0, 1));
+ EXPECT_GE(AuthorPriority(0, 0xFFFFFFFF), AuthorPriority(0, 0xFFFFFFFE));
+ EXPECT_FALSE(AuthorPriority(0, 2) >= AuthorPriority(0, 3));
+}
+
+TEST(CascadePriorityTest, PositionAndTreeOrder) {
+ // AuthorPriority(tree_order, position)
+ EXPECT_GE(AuthorPriority(1, 0), AuthorPriority(0, 0));
+ EXPECT_GE(AuthorPriority(1, 1), AuthorPriority(0, 1));
+ EXPECT_GE(AuthorPriority(1, 1), AuthorPriority(0, 3));
+ EXPECT_GE(AuthorPriority(1, 2), AuthorPriority(0, 0xFFFFFFFF));
+}
+
+TEST(CascadePriorityTest, PositionAndOrigin) {
+ // [Important]AuthorPriority(tree_order, position)
+ EXPECT_GE(ImportantAuthorPriority(0, 0), AuthorPriority(0, 0));
+ EXPECT_GE(ImportantAuthorPriority(0, 1), AuthorPriority(0, 1));
+ EXPECT_GE(ImportantAuthorPriority(0, 1), AuthorPriority(0, 3));
+ EXPECT_GE(ImportantAuthorPriority(0, 2), AuthorPriority(0, 0xFFFFFFFF));
+}
+
+TEST(CascadePriorityTest, Generation) {
+ CascadePriority ua(CascadeOrigin::kUserAgent);
+ CascadePriority author(CascadeOrigin::kAuthor);
+
+ EXPECT_EQ(author, author);
+ EXPECT_GE(CascadePriority(author, 1), author);
+ EXPECT_GE(CascadePriority(author, 2), CascadePriority(author, 1));
+ EXPECT_EQ(CascadePriority(author, 2), CascadePriority(author, 2));
+
+ EXPECT_LT(ua, author);
+ EXPECT_LT(CascadePriority(ua, 1), author);
+ EXPECT_LT(CascadePriority(ua, 2), CascadePriority(author, 1));
+ EXPECT_LT(CascadePriority(ua, 2), CascadePriority(author, 2));
+ EXPECT_LT(CascadePriority(ua, 2), CascadePriority(author, 3));
+}
+
+TEST(CascadePriorityTest, GenerationOverwrite) {
+ CascadePriority ua(CascadeOrigin::kUserAgent);
+
+ for (int8_t g = 0; g < 16; ++g) {
+ ua = CascadePriority(ua, g);
+ EXPECT_EQ(g, ua.GetGeneration());
+ }
+
+ for (int8_t g = 15; g >= 0; --g) {
+ ua = CascadePriority(ua, g);
+ EXPECT_EQ(g, ua.GetGeneration());
+ }
+}
+
+TEST(CascadePriorityTest, PositionEncoding) {
+ // Test 0b0, 0b1, 0b11, 0b111, etc.
+ uint32_t pos = 0;
+ do {
+ // AuthorPriority(tree_order, position)
+ ASSERT_EQ(pos, AuthorPriority(0, pos).GetPosition());
+ pos = (pos << 1) | 1;
+ } while (pos != ~static_cast<uint32_t>(0));
+
+ // Test 0b1, 0b10, 0b100, etc
+ pos = 1;
+ do {
+ // AuthorPriority(tree_order, position)
+ ASSERT_EQ(pos, AuthorPriority(0, pos).GetPosition());
+ pos <<= 1;
+ } while (pos != ~static_cast<uint32_t>(1) << 31);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..55865460fa8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/resolver/cascade_resolver.cc
@@ -0,0 +1,72 @@
+// 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/cascade_resolver.h"
+
+#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/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);
+}
+
+bool CascadeResolver::AllowSubstitution(CSSVariableData* data) const {
+ if (data && data->IsAnimationTainted() && stack_.size()) {
+ const CSSPropertyName& name = stack_.back();
+ if (name.IsCustomProperty())
+ return true;
+ const CSSProperty& property = CSSProperty::Get(name.Id());
+ return !CSSAnimations::IsAnimationAffectingProperty(property);
+ }
+ return true;
+}
+
+void CascadeResolver::MarkUnapplied(CascadePriority* priority) const {
+ DCHECK(priority);
+ *priority = CascadePriority(*priority, 0);
+}
+
+void CascadeResolver::MarkApplied(CascadePriority* priority) const {
+ DCHECK(priority);
+ *priority = CascadePriority(*priority, generation_);
+}
+
+bool CascadeResolver::DetectCycle(const CSSProperty& property) {
+ wtf_size_t index = stack_.Find(property.GetCSSPropertyName());
+ if (index == kNotFound)
+ return false;
+ cycle_depth_ = std::min(cycle_depth_, index);
+ return true;
+}
+
+bool CascadeResolver::InCycle() const {
+ return cycle_depth_ != kNotFound;
+}
+
+CascadeResolver::AutoLock::AutoLock(const CSSProperty& property,
+ CascadeResolver& resolver)
+ : AutoLock(property.GetCSSPropertyName(), resolver) {}
+
+CascadeResolver::AutoLock::AutoLock(const CSSPropertyName& name,
+ CascadeResolver& resolver)
+ : resolver_(resolver) {
+ DCHECK(!resolver.IsLocked(name));
+ resolver_.stack_.push_back(name);
+}
+
+CascadeResolver::AutoLock::~AutoLock() {
+ resolver_.stack_.pop_back();
+ if (resolver_.stack_.size() <= resolver_.cycle_depth_)
+ resolver_.cycle_depth_ = kNotFound;
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..165f6334ab3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/resolver/cascade_resolver.h
@@ -0,0 +1,115 @@
+// 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_RESOLVER_CASCADE_RESOLVER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CASCADE_RESOLVER_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/css/css_property_name.h"
+#include "third_party/blink/renderer/core/css/properties/css_property.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_filter.h"
+#include "third_party/blink/renderer/core/css/rule_set.h"
+
+namespace blink {
+
+class CascadePriority;
+class CSSProperty;
+class CSSVariableData;
+
+namespace cssvalue {
+
+class CSSPendingSubstitutionValue;
+
+} // namespace cssvalue
+
+// CascadeResolver is an object passed on the stack during Apply. Its most
+// important job is to detect cycles during Apply (in general, keep track of
+// which properties we're currently applying).
+class CORE_EXPORT CascadeResolver {
+ STACK_ALLOCATED();
+
+ public:
+ // TODO(crbug.com/985047): Probably use a HashMap for this.
+ using NameStack = Vector<CSSPropertyName, 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;
+
+ // We do not allow substitution of animation-tainted values into
+ // an animation-affecting property.
+ //
+ // https://drafts.csswg.org/css-variables/#animation-tainted
+ bool AllowSubstitution(CSSVariableData*) const;
+
+ // Sets the generation of the priority to zero, which has the effect of
+ // marking it as unapplied. (I.e. this can be used to force re-application of
+ // a declaration).
+ void MarkUnapplied(CascadePriority*) const;
+
+ // Sets the generation of the priority to the current generation,
+ // which has the effect of marking it as already applied. (I.e. this can be
+ // used to skip application of a declaration).
+ void MarkApplied(CascadePriority*) const;
+
+ // Automatically locks and unlocks the given property. (See
+ // CascadeResolver::IsLocked).
+ class CORE_EXPORT AutoLock {
+ STACK_ALLOCATED();
+
+ public:
+ AutoLock(const CSSProperty&, CascadeResolver&);
+ AutoLock(const CSSPropertyName&, CascadeResolver&);
+ ~AutoLock();
+
+ private:
+ CascadeResolver& resolver_;
+ };
+
+ private:
+ friend class AutoLock;
+ friend class StyleCascade;
+ friend class TestCascadeResolver;
+
+ CascadeResolver(CascadeFilter filter, uint8_t generation)
+ : filter_(filter), generation_(generation) {}
+
+ // If the given property is already being applied, returns true.
+ // The return value is the same value you would get from InCycle(), and
+ // is just returned for convenience.
+ //
+ // When a cycle has been detected, the CascadeResolver will *persist the cycle
+ // state* (i.e. InCycle() will continue to return true) until we reach
+ // the start of the cycle.
+ //
+ // The cycle state is cleared by ~AutoLock, once we have moved far enough
+ // up the stack.
+ bool DetectCycle(const CSSProperty&);
+ // Returns true whenever the CascadeResolver is in a cycle state.
+ // This DOES NOT detect cycles; the caller must call DetectCycle first.
+ bool InCycle() const;
+
+ NameStack stack_;
+ wtf_size_t cycle_depth_ = kNotFound;
+ CascadeFilter filter_;
+ const uint8_t generation_ = 0;
+
+ // A very simple cache for CSSPendingSubstitutionValues. We cache only the
+ // most recently parsed CSSPendingSubstitutionValue, such that consecutive
+ // calls to ResolvePendingSubstitution with the same value don't need to
+ // do the same parsing job all over again.
+ struct {
+ STACK_ALLOCATED();
+
+ public:
+ const cssvalue::CSSPendingSubstitutionValue* value = nullptr;
+ HeapVector<CSSPropertyValue, 256> parsed_properties;
+ } shorthand_cache_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CASCADE_RESOLVER_H_
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 a77173acd07..6e5676a5756 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
@@ -29,15 +29,15 @@ class CSSPropertyPriorityData {
STATIC_ONLY(CSSPropertyPriorityData);
public:
- static inline CSSPropertyID First();
- static inline CSSPropertyID Last();
- static inline bool PropertyHasPriority(CSSPropertyID prop) {
+ static constexpr CSSPropertyID First();
+ static constexpr CSSPropertyID Last();
+ static constexpr bool PropertyHasPriority(CSSPropertyID prop) {
return First() <= prop && prop <= Last();
}
};
template <>
-inline CSSPropertyID CSSPropertyPriorityData<kResolveVariables>::First() {
+constexpr CSSPropertyID CSSPropertyPriorityData<kResolveVariables>::First() {
static_assert(
static_cast<int>(CSSPropertyID::kVariable) == kIntFirstCSSProperty - 1,
"CSSPropertyID::kVariable should be directly before the first CSS "
@@ -46,12 +46,12 @@ inline CSSPropertyID CSSPropertyPriorityData<kResolveVariables>::First() {
}
template <>
-inline CSSPropertyID CSSPropertyPriorityData<kResolveVariables>::Last() {
+constexpr CSSPropertyID CSSPropertyPriorityData<kResolveVariables>::Last() {
return CSSPropertyID::kVariable;
}
template <>
-inline CSSPropertyID
+constexpr CSSPropertyID
CSSPropertyPriorityData<kAnimationPropertyPriority>::First() {
static_assert(CSSPropertyID::kAnimationDelay == firstCSSProperty,
"CSSPropertyID::kAnimationDelay should be the first animation "
@@ -60,7 +60,7 @@ CSSPropertyPriorityData<kAnimationPropertyPriority>::First() {
}
template <>
-inline CSSPropertyID
+constexpr CSSPropertyID
CSSPropertyPriorityData<kAnimationPropertyPriority>::Last() {
static_assert(
static_cast<int>(CSSPropertyID::kTransitionTimingFunction) ==
@@ -76,7 +76,8 @@ CSSPropertyPriorityData<kAnimationPropertyPriority>::Last() {
}
template <>
-inline CSSPropertyID CSSPropertyPriorityData<kHighPropertyPriority>::First() {
+constexpr CSSPropertyID
+CSSPropertyPriorityData<kHighPropertyPriority>::First() {
static_assert(
static_cast<int>(CSSPropertyID::kColor) ==
static_cast<int>(CSSPropertyID::kTransitionTimingFunction) + 1,
@@ -85,7 +86,7 @@ inline CSSPropertyID CSSPropertyPriorityData<kHighPropertyPriority>::First() {
}
template <>
-inline CSSPropertyID CSSPropertyPriorityData<kHighPropertyPriority>::Last() {
+constexpr CSSPropertyID CSSPropertyPriorityData<kHighPropertyPriority>::Last() {
static_assert(static_cast<int>(CSSPropertyID::kZoom) ==
static_cast<int>(CSSPropertyID::kColor) + 27,
"CSSPropertyID::kZoom should be the end of the high priority "
@@ -98,7 +99,7 @@ inline CSSPropertyID CSSPropertyPriorityData<kHighPropertyPriority>::Last() {
}
template <>
-inline CSSPropertyID CSSPropertyPriorityData<kLowPropertyPriority>::First() {
+constexpr CSSPropertyID CSSPropertyPriorityData<kLowPropertyPriority>::First() {
static_assert(
static_cast<int>(CSSPropertyID::kAlignContent) ==
static_cast<int>(CSSPropertyID::kZoom) + 1,
@@ -107,11 +108,11 @@ inline CSSPropertyID CSSPropertyPriorityData<kLowPropertyPriority>::First() {
}
template <>
-inline CSSPropertyID CSSPropertyPriorityData<kLowPropertyPriority>::Last() {
+constexpr CSSPropertyID CSSPropertyPriorityData<kLowPropertyPriority>::Last() {
return static_cast<CSSPropertyID>(lastCSSProperty);
}
-inline CSSPropertyPriority PriorityForProperty(CSSPropertyID property) {
+constexpr CSSPropertyPriority PriorityForProperty(CSSPropertyID property) {
if (CSSPropertyPriorityData<kLowPropertyPriority>::PropertyHasPriority(
property)) {
return kLowPropertyPriority;
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/css_variable_animator.cc b/chromium/third_party/blink/renderer/core/css/resolver/css_variable_animator.cc
index 1edd47f7c1e..f137cab9032 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/css_variable_animator.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/css_variable_animator.cc
@@ -70,13 +70,13 @@ void CSSVariableAnimator::Apply(const PropertyHandle& property) {
const ActiveInterpolations& interpolations =
ActiveInterpolationsForCustomProperty(update_, property);
const Interpolation& interpolation = *interpolations.front();
- if (interpolation.IsInvalidatableInterpolation()) {
+ if (IsA<InvalidatableInterpolation>(interpolation)) {
CSSInterpolationTypesMap map(state_.GetDocument().GetPropertyRegistry(),
state_.GetDocument());
CSSInterpolationEnvironment environment(map, state_, this);
InvalidatableInterpolation::ApplyStack(interpolations, environment);
} else {
- ToTransitionInterpolation(interpolation).Apply(state_);
+ To<TransitionInterpolation>(interpolation).Apply(state_);
}
pending_properties_.erase(property);
}
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/css_variable_resolver.cc b/chromium/third_party/blink/renderer/core/css/resolver/css_variable_resolver.cc
index 210bc41cd1b..1ebf7711cdf 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/css_variable_resolver.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/css_variable_resolver.cc
@@ -52,7 +52,7 @@ CSSVariableResolver::Fallback CSSVariableResolver::ResolveFallback(
const CSSParserContext* context =
StrictCSSParserContext(state_.GetDocument().GetSecureContextMode());
const bool is_animation_tainted = false;
- if (!registration->Syntax().Parse(resolved_range, context,
+ if (!registration->Syntax().Parse(resolved_range, *context,
is_animation_tainted))
return Fallback::kFail;
}
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/css_variable_resolver.h b/chromium/third_party/blink/renderer/core/css/resolver/css_variable_resolver.h
index 1df731c3b04..eaa6f3204f9 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/css_variable_resolver.h
+++ b/chromium/third_party/blink/renderer/core/css/resolver/css_variable_resolver.h
@@ -222,7 +222,7 @@ class CORE_EXPORT CSSVariableResolver {
const StyleResolverState& state_;
StyleInheritedVariables* inherited_variables_;
StyleNonInheritedVariables* non_inherited_variables_;
- Member<const PropertyRegistry> registry_;
+ const PropertyRegistry* registry_;
HashSet<AtomicString> variables_seen_;
// Resolution doesn't finish when a cycle is detected. Fallbacks still
// need to be tracked for additional cycles, and invalidation only
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/css_variable_resolver_test.cc b/chromium/third_party/blink/renderer/core/css/resolver/css_variable_resolver_test.cc
index 0b4876c69d2..a5095306bea 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/css_variable_resolver_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/css_variable_resolver_test.cc
@@ -52,7 +52,7 @@ class CSSVariableResolverTest : public PageTestBase {
}
void SetTestHTML(const String& value) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<style>"
" #target {"
" --main-bg-color: black;"
@@ -129,7 +129,7 @@ class CSSVariableResolverTest : public PageTestBase {
builder.Append("</style>\n");
builder.Append("<div id=target></div>\n");
- GetDocument().body()->SetInnerHTMLFromString(builder.ToString());
+ GetDocument().body()->setInnerHTML(builder.ToString());
UpdateAllLifecyclePhasesForTest();
}
};
@@ -301,7 +301,7 @@ TEST_F(CSSVariableResolverTest, NeedsResolutionClearedByResolver) {
const auto tokens = CSSTokenizer(initial_value_str).TokenizeToEOF();
const auto* context = MakeGarbageCollected<CSSParserContext>(GetDocument());
const CSSValue* initial_value =
- token_syntax->Parse(CSSParserTokenRange(tokens), context, false);
+ token_syntax->Parse(CSSParserTokenRange(tokens), *context, false);
ASSERT_TRUE(initial_value);
ASSERT_TRUE(initial_value->IsVariableReferenceValue());
PropertyRegistration* registration =
@@ -426,7 +426,7 @@ TEST_F(CSSVariableResolverTest, BillionLaughs) {
builder.Append("</style>\n");
builder.Append("<div id=target></div>\n");
- GetDocument().body()->SetInnerHTMLFromString(builder.ToString());
+ GetDocument().body()->setInnerHTML(builder.ToString());
UpdateAllLifecyclePhasesForTest();
Element* target = GetDocument().getElementById("target");
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/element_resolve_context.cc b/chromium/third_party/blink/renderer/core/css/resolver/element_resolve_context.cc
index 3e755ed6cd8..d6b8ea6ef44 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/element_resolve_context.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/element_resolve_context.cc
@@ -32,6 +32,8 @@ namespace blink {
ElementResolveContext::ElementResolveContext(Element& element)
: element_(&element),
+ parent_node_(nullptr),
+ layout_parent_(nullptr),
element_link_state_(
element.GetDocument().GetVisitedLinkState().DetermineLinkState(
element)),
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/element_resolve_context.h b/chromium/third_party/blink/renderer/core/css/resolver/element_resolve_context.h
index d1984700d80..3af63d30b8e 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/element_resolve_context.h
+++ b/chromium/third_party/blink/renderer/core/css/resolver/element_resolve_context.h
@@ -60,9 +60,9 @@ class CORE_EXPORT ElementResolveContext {
}
private:
- Member<Element> element_;
- Member<ContainerNode> parent_node_;
- Member<ContainerNode> layout_parent_;
+ Element* element_;
+ ContainerNode* parent_node_;
+ ContainerNode* layout_parent_;
scoped_refptr<const ComputedStyle> root_element_style_;
EInsideLink element_link_state_;
bool distributed_to_insertion_point_;
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/element_style_resources.cc b/chromium/third_party/blink/renderer/core/css/resolver/element_style_resources.cc
index 2c89c02b6cc..97c4441eea0 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/element_style_resources.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/element_style_resources.cc
@@ -220,8 +220,8 @@ void ElementStyleResources::LoadPendingImages(ComputedStyle* style) {
LoadPendingImage(style, To<StylePendingImage>(background_image),
image_request_optimization);
if (new_image && new_image->IsLazyloadPossiblyDeferred()) {
- LazyImageHelper::StartMonitoring(
- pseudo_element_ ? pseudo_element_ : element_.Get());
+ LazyImageHelper::StartMonitoring(pseudo_element_ ? pseudo_element_
+ : element_);
}
background_layer->SetImage(new_image);
}
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/element_style_resources.h b/chromium/third_party/blink/renderer/core/css/resolver/element_style_resources.h
index a61766b3006..d04897105c5 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/element_style_resources.h
+++ b/chromium/third_party/blink/renderer/core/css/resolver/element_style_resources.h
@@ -88,10 +88,10 @@ class ElementStyleResources {
FetchParameters::ImageRequestOptimization,
CrossOriginAttributeValue = kCrossOriginAttributeNotSet);
- Member<Element> element_;
+ Element* element_;
HashSet<CSSPropertyID> pending_image_properties_;
float device_scale_factor_;
- Member<PseudoElement> pseudo_element_;
+ PseudoElement* pseudo_element_;
DISALLOW_COPY_AND_ASSIGN(ElementStyleResources);
};
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/font_builder.cc b/chromium/third_party/blink/renderer/core/css/resolver/font_builder.cc
index f71b93bbf59..08667ae3f4a 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/font_builder.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/font_builder.cc
@@ -24,6 +24,8 @@
#include "third_party/blink/renderer/core/css/resolver/font_builder.h"
+#include "third_party/blink/renderer/core/css/css_font_selector.h"
+#include "third_party/blink/renderer/core/css/style_engine.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/local_frame.h"
@@ -35,8 +37,7 @@
namespace blink {
-FontBuilder::FontBuilder(const Document* document)
- : document_(document), flags_(0) {
+FontBuilder::FontBuilder(Document* document) : document_(document), flags_(0) {
DCHECK(!document || document->GetFrame());
}
@@ -95,8 +96,6 @@ AtomicString FontBuilder::GenericFontFamilyName(
return font_family_names::kWebkitCursive;
case FontDescription::kFantasyFamily:
return font_family_names::kWebkitFantasy;
- case FontDescription::kPictographFamily:
- return font_family_names::kWebkitPictograph;
}
}
@@ -255,18 +254,18 @@ float FontBuilder::GetComputedSizeFromSpecifiedSize(
}
void FontBuilder::CheckForGenericFamilyChange(
- const FontDescription& old_description,
+ const FontDescription& parent_description,
FontDescription& new_description) {
DCHECK(document_);
if (new_description.IsAbsoluteSize())
return;
- if (new_description.IsMonospace() == old_description.IsMonospace())
+ if (new_description.IsMonospace() == parent_description.IsMonospace())
return;
// For now, lump all families but monospace together.
if (new_description.GenericFamily() != FontDescription::kMonospaceFamily &&
- old_description.GenericFamily() != FontDescription::kMonospaceFamily)
+ parent_description.GenericFamily() != FontDescription::kMonospaceFamily)
return;
// We know the parent is monospace or the child is monospace, and that font
@@ -285,7 +284,7 @@ void FontBuilder::CheckForGenericFamilyChange(
? static_cast<float>(settings->GetDefaultFixedFontSize()) /
settings->GetDefaultFontSize()
: 1;
- size = old_description.IsMonospace()
+ size = parent_description.IsMonospace()
? new_description.SpecifiedSize() / fixed_scale_factor
: new_description.SpecifiedSize() * fixed_scale_factor;
}
@@ -294,7 +293,8 @@ void FontBuilder::CheckForGenericFamilyChange(
}
void FontBuilder::UpdateSpecifiedSize(FontDescription& font_description,
- const ComputedStyle& style) {
+ const ComputedStyle& style,
+ const ComputedStyle* parent_style) {
float specified_size = font_description.SpecifiedSize();
if (!specified_size && font_description.KeywordSize())
@@ -303,7 +303,12 @@ void FontBuilder::UpdateSpecifiedSize(FontDescription& font_description,
font_description.SetSpecifiedSize(specified_size);
- CheckForGenericFamilyChange(style.GetFontDescription(), font_description);
+ // TODO(crbug.com/1086680): Avoid nullptr parent style.
+ const FontDescription& parent_description =
+ parent_style ? parent_style->GetFontDescription()
+ : style.GetFontDescription();
+
+ CheckForGenericFamilyChange(parent_description, font_description);
}
void FontBuilder::UpdateAdjustedSize(FontDescription& font_description,
@@ -319,8 +324,7 @@ void FontBuilder::UpdateAdjustedSize(FontDescription& font_description,
// FontDescription::EffectiveFontSize.
font_description.SetAdjustedSize(font_description.ComputedSize());
- Font font(font_description);
- font.Update(font_selector);
+ Font font(font_description, font_selector);
const SimpleFontData* font_data = font.PrimaryFont();
@@ -406,8 +410,8 @@ void FontBuilder::UpdateFontDescription(FontDescription& description,
description.SetAdjustedSize(size);
}
-void FontBuilder::CreateFont(FontSelector* font_selector,
- ComputedStyle& style) {
+void FontBuilder::CreateFont(ComputedStyle& style,
+ const ComputedStyle* parent_style) {
DCHECK(document_);
if (!flags_)
@@ -416,18 +420,17 @@ void FontBuilder::CreateFont(FontSelector* font_selector,
FontDescription description = style.GetFontDescription();
UpdateFontDescription(description, style.ComputeFontOrientation());
-
- UpdateSpecifiedSize(description, style);
+ UpdateSpecifiedSize(description, style, parent_style);
UpdateComputedSize(description, style);
+
+ FontSelector* font_selector = document_->GetStyleEngine().GetFontSelector();
UpdateAdjustedSize(description, style, font_selector);
- style.SetFontDescription(description);
- style.GetFont().Update(font_selector);
+ style.SetFontInternal(Font(description, font_selector));
flags_ = 0;
}
-void FontBuilder::CreateFontForDocument(FontSelector* font_selector,
- ComputedStyle& document_style) {
+void FontBuilder::CreateFontForDocument(ComputedStyle& document_style) {
DCHECK(document_);
FontDescription font_description = FontDescription();
font_description.SetLocale(document_style.GetFontDescription().Locale());
@@ -437,12 +440,13 @@ void FontBuilder::CreateFontForDocument(FontSelector* font_selector,
SetSize(font_description,
FontDescription::Size(FontSizeFunctions::InitialKeywordSize(), 0.0f,
false));
- UpdateSpecifiedSize(font_description, document_style);
+ UpdateSpecifiedSize(font_description, document_style, &document_style);
UpdateComputedSize(font_description, document_style);
font_description.SetOrientation(document_style.ComputeFontOrientation());
- document_style.SetFontDescription(font_description);
- document_style.GetFont().Update(font_selector);
+
+ FontSelector* font_selector = document_->GetStyleEngine().GetFontSelector();
+ document_style.SetFontInternal(Font(font_description, font_selector));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/font_builder.h b/chromium/third_party/blink/renderer/core/css/resolver/font_builder.h
index 2021eb1672f..b661f992d9b 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/font_builder.h
+++ b/chromium/third_party/blink/renderer/core/css/resolver/font_builder.h
@@ -42,7 +42,7 @@ class CORE_EXPORT FontBuilder {
STACK_ALLOCATED();
public:
- FontBuilder(const Document*);
+ explicit FontBuilder(Document*);
void SetInitial(float effective_zoom);
@@ -79,9 +79,8 @@ class CORE_EXPORT FontBuilder {
// FIXME: These need to just vend a Font object eventually.
void UpdateFontDescription(FontDescription&,
FontOrientation = FontOrientation::kHorizontal);
- void CreateFont(FontSelector*, ComputedStyle&);
-
- void CreateFontForDocument(FontSelector*, ComputedStyle&);
+ void CreateFont(ComputedStyle&, const ComputedStyle* parent_style);
+ void CreateFontForDocument(ComputedStyle&);
bool FontDirty() const { return flags_; }
@@ -129,7 +128,9 @@ class CORE_EXPORT FontBuilder {
// This function fixes up the default font size if it detects that the current
// generic font family has changed. -dwh
void CheckForGenericFamilyChange(const FontDescription&, FontDescription&);
- void UpdateSpecifiedSize(FontDescription&, const ComputedStyle&);
+ void UpdateSpecifiedSize(FontDescription&,
+ const ComputedStyle&,
+ const ComputedStyle* parent_style);
void UpdateComputedSize(FontDescription&, const ComputedStyle&);
void UpdateAdjustedSize(FontDescription&,
const ComputedStyle&,
@@ -139,7 +140,7 @@ class CORE_EXPORT FontBuilder {
float effective_zoom,
float specified_size);
- Member<const Document> document_;
+ Document* document_;
FontDescription font_description_;
enum class PropertySetFlag {
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/font_builder_test.cc b/chromium/third_party/blink/renderer/core/css/resolver/font_builder_test.cc
index 076628b2578..9aff72b7dd1 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/font_builder_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/font_builder_test.cc
@@ -49,8 +49,7 @@ TEST_F(FontBuilderInitTest, InitialFontSizeNotScaled) {
FontBuilder builder(&GetDocument());
builder.SetInitial(1.0f); // FIXME: Remove unused param.
- builder.CreateFont(GetDocument().GetStyleEngine().GetFontSelector(),
- *initial);
+ builder.CreateFont(*initial, initial.get());
EXPECT_EQ(16.0f, initial->GetFontDescription().ComputedSize());
}
@@ -69,13 +68,15 @@ TEST_P(FontBuilderAdditiveTest, OnlySetValueIsModified) {
FontDescription parent_description;
funcs.set_base_value(parent_description);
+ scoped_refptr<ComputedStyle> parent_style = ComputedStyle::Create();
+ parent_style->SetFontDescription(parent_description);
+
scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
- style->SetFontDescription(parent_description);
+ style->InheritFrom(*parent_style);
FontBuilder font_builder(&GetDocument());
funcs.set_value(font_builder);
- font_builder.CreateFont(GetDocument().GetStyleEngine().GetFontSelector(),
- *style);
+ font_builder.CreateFont(*style, parent_style.get());
FontDescription output_description = style->GetFontDescription();
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/font_style_resolver.cc b/chromium/third_party/blink/renderer/core/css/resolver/font_style_resolver.cc
index e899b8e9cf4..cbac112bb23 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/font_style_resolver.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/font_style_resolver.cc
@@ -18,8 +18,7 @@ FontDescription FontStyleResolver::ComputeFont(
FontBuilder builder(nullptr);
FontDescription fontDescription;
- Font font(fontDescription);
- font.Update(font_selector);
+ Font font(fontDescription, font_selector);
CSSToLengthConversionData::FontSizes fontSizes(10, 10, &font, 1);
CSSToLengthConversionData::ViewportSize viewportSize(0, 0);
CSSToLengthConversionData conversionData(nullptr, fontSizes, viewportSize, 1);
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/match_request.h b/chromium/third_party/blink/renderer/core/css/resolver/match_request.h
index 1a500f48853..e7911422dfc 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/match_request.h
+++ b/chromium/third_party/blink/renderer/core/css/resolver/match_request.h
@@ -53,9 +53,9 @@ class MatchRequest {
rule_set->CompactRulesIfNeeded();
}
- Member<const RuleSet> rule_set;
- Member<const ContainerNode> scope;
- Member<const CSSStyleSheet> style_sheet;
+ const RuleSet* rule_set;
+ const ContainerNode* scope;
+ const CSSStyleSheet* style_sheet;
const unsigned style_sheet_index;
bool is_from_vtt;
};
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 4391044d6b1..ae05e3e6776 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,9 +43,7 @@ MatchedProperties::MatchedProperties() {
memset(&types_, 0, sizeof(types_));
}
-MatchedProperties::~MatchedProperties() = default;
-
-void MatchedProperties::Trace(blink::Visitor* visitor) {
+void MatchedProperties::Trace(Visitor* visitor) {
visitor->Trace(properties);
}
@@ -60,17 +58,17 @@ void MatchResult::AddMatchedProperties(
new_properties.types_.valid_property_filter =
static_cast<std::underlying_type_t<ValidPropertyFilter>>(
valid_property_filter);
- // TODO(andruud): MatchedProperties are stored here in reverse order.
- // Reevaluate this when cascade has shipped.
- new_properties.types_.tree_order =
- std::numeric_limits<uint16_t>::max() - current_tree_order_;
+ new_properties.types_.origin = current_origin_;
+ new_properties.types_.tree_order = current_tree_order_;
}
void MatchResult::FinishAddingUARules() {
+ current_origin_ = CascadeOrigin::kUser;
ua_range_end_ = matched_properties_.size();
}
void MatchResult::FinishAddingUserRules() {
+ current_origin_ = CascadeOrigin::kAuthor;
// Don't add empty ranges.
if (user_range_ends_.IsEmpty() &&
ua_range_end_ == matched_properties_.size())
@@ -97,4 +95,23 @@ void MatchResult::FinishAddingAuthorRulesForTreeScope() {
current_tree_order_ = clampTo<uint16_t>(author_range_ends_.size());
}
+MatchedExpansionsRange MatchResult::Expansions(const Document& document,
+ CascadeFilter filter) const {
+ return MatchedExpansionsRange(
+ MatchedExpansionsIterator(matched_properties_.begin(), document, filter,
+ 0),
+ MatchedExpansionsIterator(matched_properties_.end(), document, filter,
+ matched_properties_.size()));
+}
+
+void MatchResult::Reset() {
+ matched_properties_.clear();
+ user_range_ends_.clear();
+ author_range_ends_.clear();
+ ua_range_end_ = 0;
+ is_cacheable_ = true;
+ current_origin_ = CascadeOrigin::kUserAgent;
+ current_tree_order_ = 0;
+}
+
} // namespace blink
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 2a6f8ad74ed..476088ef23e 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
@@ -26,6 +26,10 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_expansion.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_filter.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_origin.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_priority.h"
#include "third_party/blink/renderer/core/css/rule_set.h"
#include "third_party/blink/renderer/core/css/selector_checker.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -40,15 +44,15 @@ struct CORE_EXPORT MatchedProperties {
public:
MatchedProperties();
- ~MatchedProperties();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
Member<CSSPropertyValueSet> properties;
struct Data {
unsigned link_match_type : 2;
unsigned valid_property_filter : 2;
+ CascadeOrigin origin;
// This is approximately equivalent to the 'shadow-including tree order'.
// It can be used to evaluate the 'Shadow Tree' criteria. Note that the
// number stored here is 'local' to each origin (user, author), and is
@@ -95,6 +99,58 @@ class MatchedPropertiesRange {
MatchedPropertiesVector::const_iterator end_;
};
+class MatchedExpansionsIterator {
+ STACK_ALLOCATED();
+ using Iterator = MatchedPropertiesVector::const_iterator;
+
+ public:
+ MatchedExpansionsIterator(Iterator iterator,
+ const Document& document,
+ CascadeFilter filter,
+ size_t index)
+ : iterator_(iterator),
+ document_(document),
+ filter_(filter),
+ index_(index) {}
+
+ void operator++() {
+ iterator_++;
+ index_++;
+ }
+ bool operator==(const MatchedExpansionsIterator& o) const {
+ return iterator_ == o.iterator_;
+ }
+ bool operator!=(const MatchedExpansionsIterator& o) const {
+ return iterator_ != o.iterator_;
+ }
+
+ CascadeExpansion operator*() const {
+ return CascadeExpansion(*iterator_, document_, filter_, index_);
+ }
+
+ private:
+ Iterator iterator_;
+ const Document& document_;
+ CascadeFilter filter_;
+ size_t index_;
+};
+
+class MatchedExpansionsRange {
+ STACK_ALLOCATED();
+
+ public:
+ MatchedExpansionsRange(MatchedExpansionsIterator begin,
+ MatchedExpansionsIterator end)
+ : begin_(begin), end_(end) {}
+
+ MatchedExpansionsIterator begin() const { return begin_; }
+ MatchedExpansionsIterator end() const { return end_; }
+
+ private:
+ MatchedExpansionsIterator begin_;
+ MatchedExpansionsIterator end_;
+};
+
class CORE_EXPORT MatchResult {
STACK_ALLOCATED();
@@ -114,6 +170,8 @@ class CORE_EXPORT MatchResult {
void SetIsCacheable(bool cacheable) { is_cacheable_ = cacheable; }
bool IsCacheable() const { return is_cacheable_; }
+ MatchedExpansionsRange Expansions(const Document&, CascadeFilter) const;
+
MatchedPropertiesRange AllRules() const {
return MatchedPropertiesRange(matched_properties_.begin(),
matched_properties_.end());
@@ -146,6 +204,10 @@ class CORE_EXPORT MatchResult {
return matched_properties_;
}
+ // Reset the MatchResult to its initial state, as if no MatchedProperties
+ // objects were added.
+ void Reset();
+
private:
friend class ImportantUserRanges;
friend class ImportantUserRangeIterator;
@@ -157,6 +219,7 @@ class CORE_EXPORT MatchResult {
Vector<unsigned, 16> author_range_ends_;
unsigned ua_range_end_ = 0;
bool is_cacheable_ = true;
+ CascadeOrigin current_origin_ = CascadeOrigin::kUserAgent;
uint16_t current_tree_order_ = 0;
DISALLOW_COPY_AND_ASSIGN(MatchResult);
};
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/match_result_test.cc b/chromium/third_party/blink/renderer/core/css/resolver/match_result_test.cc
index 8ee20ac3ee8..02a87f62bef 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/match_result_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/match_result_test.cc
@@ -4,13 +4,16 @@
#include "third_party/blink/renderer/core/css/resolver/match_result.h"
-#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
+#include "third_party/blink/renderer/core/css/css_test_helpers.h"
+#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
-class MatchResultTest : public testing::Test {
+using css_test_helpers::ParseDeclarationBlock;
+
+class MatchResultTest : public PageTestBase {
protected:
void SetUp() override;
@@ -23,6 +26,7 @@ class MatchResultTest : public testing::Test {
};
void MatchResultTest::SetUp() {
+ PageTestBase::SetUp();
property_sets =
MakeGarbageCollected<HeapVector<Member<MutableCSSPropertyValueSet>, 8>>();
for (unsigned i = 0; i < 8; i++) {
@@ -39,6 +43,14 @@ void TestMatchedPropertiesRange(const MatchedPropertiesRange& range,
EXPECT_EQ(*expected_sets++, matched_properties.properties);
}
+void TestOriginInRange(const MatchedPropertiesRange& range,
+ int expected_length,
+ CascadeOrigin expected_origin) {
+ EXPECT_EQ(expected_length, range.end() - range.begin());
+ for (const auto& matched_properties : range)
+ EXPECT_EQ(matched_properties.types_.origin, expected_origin);
+}
+
TEST_F(MatchResultTest, UARules) {
const CSSPropertyValueSet* ua_sets[] = {PropertySet(0), PropertySet(1)};
@@ -225,4 +237,224 @@ TEST_F(MatchResultTest, AllRulesMultipleScopes) {
EXPECT_EQ(importantUser.end(), ++importantUser.begin());
}
+TEST_F(MatchResultTest, CascadeOriginUserAgent) {
+ MatchResult result;
+ result.AddMatchedProperties(PropertySet(0));
+ result.AddMatchedProperties(PropertySet(1));
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ TestOriginInRange(result.UaRules(), 2, CascadeOrigin::kUserAgent);
+ TestOriginInRange(result.AllRules(), 2, CascadeOrigin::kUserAgent);
+}
+
+TEST_F(MatchResultTest, CascadeOriginUser) {
+ MatchResult result;
+ result.FinishAddingUARules();
+ result.AddMatchedProperties(PropertySet(0));
+ result.AddMatchedProperties(PropertySet(1));
+ result.FinishAddingUserRules();
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ TestOriginInRange(result.UserRules(), 2, CascadeOrigin::kUser);
+ TestOriginInRange(result.AllRules(), 2, CascadeOrigin::kUser);
+}
+
+TEST_F(MatchResultTest, CascadeOriginAuthor) {
+ MatchResult result;
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(PropertySet(0));
+ result.AddMatchedProperties(PropertySet(1));
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ TestOriginInRange(result.AuthorRules(), 2, CascadeOrigin::kAuthor);
+ TestOriginInRange(result.AllRules(), 2, CascadeOrigin::kAuthor);
+}
+
+TEST_F(MatchResultTest, CascadeOriginAll) {
+ MatchResult result;
+ result.AddMatchedProperties(PropertySet(0));
+ result.FinishAddingUARules();
+ result.AddMatchedProperties(PropertySet(1));
+ result.AddMatchedProperties(PropertySet(2));
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(PropertySet(3));
+ result.AddMatchedProperties(PropertySet(4));
+ result.AddMatchedProperties(PropertySet(5));
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ TestOriginInRange(result.UaRules(), 1, CascadeOrigin::kUserAgent);
+ TestOriginInRange(result.UserRules(), 2, CascadeOrigin::kUser);
+ TestOriginInRange(result.AuthorRules(), 3, CascadeOrigin::kAuthor);
+}
+
+TEST_F(MatchResultTest, CascadeOriginAllExceptUserAgent) {
+ MatchResult result;
+ result.FinishAddingUARules();
+ result.AddMatchedProperties(PropertySet(1));
+ result.AddMatchedProperties(PropertySet(2));
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(PropertySet(3));
+ result.AddMatchedProperties(PropertySet(4));
+ result.AddMatchedProperties(PropertySet(5));
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ TestOriginInRange(result.UaRules(), 0, CascadeOrigin::kUserAgent);
+ TestOriginInRange(result.UserRules(), 2, CascadeOrigin::kUser);
+ TestOriginInRange(result.AuthorRules(), 3, CascadeOrigin::kAuthor);
+}
+
+TEST_F(MatchResultTest, CascadeOriginAllExceptUser) {
+ MatchResult result;
+ result.AddMatchedProperties(PropertySet(0));
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(PropertySet(3));
+ result.AddMatchedProperties(PropertySet(4));
+ result.AddMatchedProperties(PropertySet(5));
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ TestOriginInRange(result.UaRules(), 1, CascadeOrigin::kUserAgent);
+ TestOriginInRange(result.UserRules(), 0, CascadeOrigin::kUser);
+ TestOriginInRange(result.AuthorRules(), 3, CascadeOrigin::kAuthor);
+}
+
+TEST_F(MatchResultTest, CascadeOriginAllExceptAuthor) {
+ MatchResult result;
+ result.AddMatchedProperties(PropertySet(0));
+ result.FinishAddingUARules();
+ result.AddMatchedProperties(PropertySet(1));
+ result.AddMatchedProperties(PropertySet(2));
+ result.FinishAddingUserRules();
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ TestOriginInRange(result.UaRules(), 1, CascadeOrigin::kUserAgent);
+ TestOriginInRange(result.UserRules(), 2, CascadeOrigin::kUser);
+ TestOriginInRange(result.AuthorRules(), 0, CascadeOrigin::kAuthor);
+}
+
+TEST_F(MatchResultTest, CascadeOriginTreeScopes) {
+ MatchResult result;
+ result.AddMatchedProperties(PropertySet(0));
+ result.FinishAddingUARules();
+ result.AddMatchedProperties(PropertySet(1));
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(PropertySet(2));
+ result.FinishAddingAuthorRulesForTreeScope();
+ result.AddMatchedProperties(PropertySet(3));
+ result.AddMatchedProperties(PropertySet(4));
+ result.FinishAddingAuthorRulesForTreeScope();
+ result.AddMatchedProperties(PropertySet(5));
+ result.AddMatchedProperties(PropertySet(6));
+ result.AddMatchedProperties(PropertySet(7));
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ TestOriginInRange(result.UaRules(), 1, CascadeOrigin::kUserAgent);
+ TestOriginInRange(result.UserRules(), 1, CascadeOrigin::kUser);
+ TestOriginInRange(result.AuthorRules(), 6, CascadeOrigin::kAuthor);
+}
+
+TEST_F(MatchResultTest, ExpansionsRange) {
+ MatchResult result;
+ result.AddMatchedProperties(ParseDeclarationBlock("left:1px;all:unset"));
+ result.AddMatchedProperties(ParseDeclarationBlock("color:red"));
+ result.FinishAddingUARules();
+ result.AddMatchedProperties(ParseDeclarationBlock("display:block"));
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(ParseDeclarationBlock("left:unset"));
+ result.AddMatchedProperties(ParseDeclarationBlock("top:unset"));
+ result.AddMatchedProperties(
+ ParseDeclarationBlock("right:unset;bottom:unset"));
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ CascadeFilter filter;
+
+ size_t i = 0;
+ size_t size = result.GetMatchedProperties().size();
+ for (auto actual : result.Expansions(GetDocument(), filter)) {
+ ASSERT_LT(i, size);
+ CascadeExpansion expected(result.GetMatchedProperties()[i], GetDocument(),
+ filter, i);
+ EXPECT_EQ(expected.Id(), actual.Id());
+ EXPECT_EQ(expected.Priority(), actual.Priority());
+ EXPECT_EQ(expected.Value(), actual.Value());
+ ++i;
+ }
+
+ EXPECT_EQ(6u, i);
+}
+
+TEST_F(MatchResultTest, EmptyExpansionsRange) {
+ MatchResult result;
+ result.FinishAddingUARules();
+ result.FinishAddingUserRules();
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ CascadeFilter filter;
+ auto range = result.Expansions(GetDocument(), filter);
+ EXPECT_EQ(range.end(), range.begin());
+}
+
+TEST_F(MatchResultTest, Reset) {
+ MatchResult result;
+ result.AddMatchedProperties(PropertySet(0));
+ result.FinishAddingUARules();
+ result.AddMatchedProperties(PropertySet(1));
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(PropertySet(2));
+ result.FinishAddingAuthorRulesForTreeScope();
+ result.AddMatchedProperties(PropertySet(3));
+ result.FinishAddingAuthorRulesForTreeScope();
+ result.AddMatchedProperties(PropertySet(4));
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ TestOriginInRange(result.UaRules(), 1, CascadeOrigin::kUserAgent);
+ TestOriginInRange(result.UserRules(), 1, CascadeOrigin::kUser);
+ TestOriginInRange(result.AuthorRules(), 3, CascadeOrigin::kAuthor);
+
+ // Check tree_order of last entry.
+ EXPECT_TRUE(result.HasMatchedProperties());
+ ASSERT_EQ(5u, result.GetMatchedProperties().size());
+ EXPECT_EQ(2u, result.GetMatchedProperties()[4].types_.tree_order);
+
+ EXPECT_TRUE(result.IsCacheable());
+ result.SetIsCacheable(false);
+ EXPECT_FALSE(result.IsCacheable());
+
+ result.Reset();
+
+ EXPECT_TRUE(result.UaRules().IsEmpty());
+ EXPECT_TRUE(result.UserRules().IsEmpty());
+ EXPECT_TRUE(result.AuthorRules().IsEmpty());
+ EXPECT_TRUE(result.AllRules().IsEmpty());
+ EXPECT_TRUE(result.IsCacheable());
+ EXPECT_FALSE(result.GetMatchedProperties().size());
+ EXPECT_FALSE(result.HasMatchedProperties());
+
+ // Add same declarations again.
+ result.AddMatchedProperties(PropertySet(0));
+ result.FinishAddingUARules();
+ result.AddMatchedProperties(PropertySet(1));
+ result.FinishAddingUserRules();
+ result.AddMatchedProperties(PropertySet(2));
+ result.FinishAddingAuthorRulesForTreeScope();
+ result.AddMatchedProperties(PropertySet(3));
+ result.FinishAddingAuthorRulesForTreeScope();
+ result.AddMatchedProperties(PropertySet(4));
+ result.FinishAddingAuthorRulesForTreeScope();
+
+ TestOriginInRange(result.UaRules(), 1, CascadeOrigin::kUserAgent);
+ TestOriginInRange(result.UserRules(), 1, CascadeOrigin::kUser);
+ TestOriginInRange(result.AuthorRules(), 3, CascadeOrigin::kAuthor);
+
+ // Check tree_order of last entry.
+ EXPECT_TRUE(result.HasMatchedProperties());
+ ASSERT_EQ(5u, result.GetMatchedProperties().size());
+ EXPECT_EQ(2u, result.GetMatchedProperties()[4].types_.tree_order);
+
+ EXPECT_TRUE(result.IsCacheable());
+}
+
} // namespace blink
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 e47045b6284..08a34b7e55a 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
@@ -178,7 +178,7 @@ bool MatchedPropertiesCache::IsCacheable(const StyleResolverState& state) {
return true;
}
-void MatchedPropertiesCache::Trace(blink::Visitor* visitor) {
+void MatchedPropertiesCache::Trace(Visitor* visitor) {
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 261a4501e61..fd88d23411b 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
@@ -52,7 +52,7 @@ class CachedMatchedProperties final
const MatchedPropertiesVector&);
void Clear();
- void Trace(blink::Visitor*) {}
+ void Trace(Visitor*) {}
bool operator==(const MatchedPropertiesVector& properties);
bool operator!=(const MatchedPropertiesVector& properties);
@@ -79,7 +79,7 @@ class CORE_EXPORT MatchedPropertiesCache {
static bool IsCacheable(const StyleResolverState&);
static bool IsStyleCacheable(const ComputedStyle&);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
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/media_query_result.h b/chromium/third_party/blink/renderer/core/css/resolver/media_query_result.h
index 6ff6d379648..6ec50445e86 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/media_query_result.h
+++ b/chromium/third_party/blink/renderer/core/css/resolver/media_query_result.h
@@ -44,6 +44,22 @@ class MediaQueryResult {
bool result_;
};
+class MediaQuerySetResult {
+ DISALLOW_NEW();
+
+ public:
+ MediaQuerySetResult(const MediaQuerySet& media_queries, bool result)
+ : media_queries_(&media_queries), result_(result) {}
+
+ const MediaQuerySet& MediaQueries() const { return *media_queries_; }
+
+ bool Result() const { return result_; }
+
+ private:
+ scoped_refptr<const MediaQuerySet> media_queries_;
+ bool result_;
+};
+
} // namespace blink
#endif
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 f27c2171e2c..0b75dc38e7c 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(blink::Visitor* visitor) {
+void ScopedStyleResolver::Trace(Visitor* visitor) {
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(blink::Visitor* visitor) {
+void ScopedStyleResolver::RuleSubSet::Trace(Visitor* visitor) {
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 51ed87c6892..ae51e9644af 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(blink::Visitor*);
+ void Trace(Visitor*);
private:
void AddTreeBoundaryCrossingRules(const RuleSet&,
@@ -118,7 +118,7 @@ class CORE_EXPORT ScopedStyleResolver final
unsigned parent_index_;
Member<RuleSet> rule_set_;
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
};
using CSSStyleSheetRuleSubSet = HeapVector<Member<RuleSubSet>>;
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/selector_filter_parent_scope.h b/chromium/third_party/blink/renderer/core/css/resolver/selector_filter_parent_scope.h
index 9d98c9d3fc1..598d5c8a684 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/selector_filter_parent_scope.h
+++ b/chromium/third_party/blink/renderer/core/css/resolver/selector_filter_parent_scope.h
@@ -40,11 +40,11 @@ class CORE_EXPORT SelectorFilterParentScope {
void PushAncestors(Element&);
void PopAncestors(Element&);
- Member<Element> parent_;
+ Element* parent_;
bool pushed_ = false;
ScopeType scope_type_;
SelectorFilterParentScope* previous_;
- Member<StyleResolver> resolver_;
+ StyleResolver* resolver_;
static SelectorFilterParentScope* current_scope_;
};
@@ -70,7 +70,10 @@ class CORE_EXPORT SelectorFilterRootScope final
inline SelectorFilterParentScope::SelectorFilterParentScope(
Element* parent,
ScopeType scope_type)
- : parent_(parent), scope_type_(scope_type), previous_(current_scope_) {
+ : parent_(parent),
+ scope_type_(scope_type),
+ previous_(current_scope_),
+ resolver_(nullptr) {
DCHECK(scope_type != ScopeType::kRoot || !parent || !previous_ ||
!previous_->parent_ ||
&parent_->GetDocument() != &previous_->parent_->GetDocument());
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/selector_filter_parent_scope_test.cc b/chromium/third_party/blink/renderer/core/css/resolver/selector_filter_parent_scope_test.cc
index e1c19e8d946..550f016357f 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/selector_filter_parent_scope_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/selector_filter_parent_scope_test.cc
@@ -56,7 +56,7 @@ TEST_F(SelectorFilterParentScopeTest, ParentScope) {
}
TEST_F(SelectorFilterParentScopeTest, RootScope) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<div class=x>
<span id=y></span>
</div>
@@ -84,7 +84,7 @@ TEST_F(SelectorFilterParentScopeTest, RootScope) {
}
TEST_F(SelectorFilterParentScopeTest, ReentrantSVGImageLoading) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
div::before {
content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"></svg>');
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 46e74fd190c..49f61afb7c4 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,9 +50,12 @@
#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/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"
#include "third_party/blink/renderer/core/style/computed_style_constants.h"
#include "third_party/blink/renderer/core/svg/svg_svg_element.h"
@@ -74,7 +77,7 @@ TouchAction AdjustTouchActionForElement(TouchAction touch_action,
element && element == element->GetDocument().documentElement() &&
element->GetDocument().LocalOwner();
if (style.ScrollsOverflow() || is_child_document)
- return touch_action | TouchAction::kTouchActionPan;
+ return touch_action | TouchAction::kPan;
return touch_action;
}
@@ -130,24 +133,28 @@ static bool IsOutermostSVGElement(const Element* element) {
return svg_element && svg_element->IsOutermostSVGSVGElement();
}
-static bool IsAtUAShadowBoundary(const Element* element) {
+static bool IsAtMediaUAShadowBoundary(const Element* element) {
if (!element)
return false;
- if (ContainerNode* parent = element->parentNode())
- return parent->IsShadowRoot() && To<ShadowRoot>(parent)->IsUserAgent();
+ if (ContainerNode* parent = element->parentNode()) {
+ if (auto* shadow_root = DynamicTo<ShadowRoot>(parent))
+ return shadow_root->host().IsMediaElement();
+ }
return false;
}
-// CSS requires text-decoration to be reset at each DOM element for
-// inline blocks, inline tables, UA shadow DOM crossings, floating elements,
-// and absolute or relatively positioned elements. Outermost <svg> roots are
-// considered to be atomic inline-level.
+// CSS requires text-decoration to be reset at each DOM element for inline
+// blocks, inline tables, floating elements, and absolute or relatively
+// positioned elements. Outermost <svg> roots are considered to be atomic
+// inline-level. Media elements have a special rendering where the media
+// controls do not use a proper containing block model which means we need
+// to manually stop text-decorations to apply to text inside media controls.
static bool StopPropagateTextDecorations(const ComputedStyle& style,
const Element* element) {
return style.Display() == EDisplay::kInlineTable ||
style.Display() == EDisplay::kInlineBlock ||
style.Display() == EDisplay::kWebkitInlineBox ||
- IsAtUAShadowBoundary(element) || style.IsFloating() ||
+ IsAtMediaUAShadowBoundary(element) || style.IsFloating() ||
style.HasOutOfFlowPosition() || IsOutermostSVGElement(element) ||
IsA<HTMLRTElement>(element);
}
@@ -197,6 +204,37 @@ static void AdjustStyleForFirstLetter(ComputedStyle& style) {
style.SetPosition(EPosition::kStatic);
}
+static void AdjustStyleForMarker(ComputedStyle& style,
+ const ComputedStyle& parent_style,
+ const Element& parent_element) {
+ if (style.StyleType() != kPseudoIdMarker)
+ return;
+
+ bool is_inside =
+ parent_style.ListStylePosition() == EListStylePosition::kInside ||
+ (IsA<HTMLLIElement>(parent_element) &&
+ !parent_style.IsInsideListElement());
+
+ if (is_inside) {
+ auto margins = LayoutListMarker::InlineMarginsForInside(
+ style, parent_style.GeneratesMarkerImage());
+ style.SetMarginStart(Length::Fixed(margins.first));
+ style.SetMarginEnd(Length::Fixed(margins.second));
+ } else {
+ // Outside list markers should generate a block container.
+ style.SetDisplay(EDisplay::kInlineBlock);
+
+ // Do not break inside the marker, and honor the trailing spaces.
+ style.SetWhiteSpace(EWhiteSpace::kPre);
+
+ // Compute margins for 'outside' during layout, because it requires the
+ // layout size of the marker.
+ // TODO(kojii): absolute position looks more reasonable, and maybe required
+ // in some cases, but this is currently blocked by crbug.com/734554
+ // style.SetPosition(EPosition::kAbsolute);
+ }
+}
+
static void AdjustStyleForHTMLElement(ComputedStyle& style,
HTMLElement& element) {
// <div> and <span> are the most common elements on the web, we skip all the
@@ -204,7 +242,7 @@ static void AdjustStyleForHTMLElement(ComputedStyle& style,
if (IsA<HTMLDivElement>(element) || IsA<HTMLSpanElement>(element))
return;
- if (IsHTMLTableCellElement(element)) {
+ if (IsA<HTMLTableCellElement>(element)) {
if (style.WhiteSpace() == EWhiteSpace::kWebkitNowrap) {
// Figure out if we are really nowrapping or if we should just
// use normal instead. If the width of the cell is fixed, then
@@ -243,7 +281,7 @@ static void AdjustStyleForHTMLElement(ComputedStyle& style,
return;
}
- if (IsHTMLFrameElementBase(element)) {
+ if (IsA<HTMLFrameElementBase>(element)) {
if (style.Display() == EDisplay::kContents) {
style.SetDisplay(EDisplay::kNone);
return;
@@ -296,20 +334,36 @@ static void AdjustStyleForHTMLElement(ComputedStyle& style,
return;
}
- if (IsHTMLPlugInElement(element)) {
+ if (auto* html_plugin_element = DynamicTo<HTMLPlugInElement>(element)) {
style.SetRequiresAcceleratedCompositingForExternalReasons(
- ToHTMLPlugInElement(element).ShouldAccelerate());
+ html_plugin_element->ShouldAccelerate());
if (style.Display() == EDisplay::kContents)
style.SetDisplay(EDisplay::kNone);
return;
}
+ if (IsA<HTMLUListElement>(element) || IsA<HTMLOListElement>(element)) {
+ style.SetIsInsideListElement();
+ return;
+ }
+
+ if (IsA<HTMLSummaryElement>(element)) {
+ // <summary> should be a list item by default, but currently it's a block
+ // and the disclosure symbol is not a ::marker (bug 590014). If an author
+ // specifies 'display: list-item', the <summary> would seem to have two
+ // markers (the real one and the disclosure symbol). To avoid this, compute
+ // to 'display: block'. This adjustment should go away with bug 590014.
+ if (style.Display() == EDisplay::kListItem)
+ style.SetDisplay(EDisplay::kBlock);
+ return;
+ }
+
if (style.Display() == EDisplay::kContents) {
// See https://drafts.csswg.org/css-display/#unbox-html
// Some of these elements are handled with other adjustments above.
if (IsA<HTMLBRElement>(element) || IsA<HTMLWBRElement>(element) ||
IsA<HTMLMeterElement>(element) || IsA<HTMLProgressElement>(element) ||
- IsA<HTMLCanvasElement>(element) || IsHTMLMediaElement(element) ||
+ IsA<HTMLCanvasElement>(element) || IsA<HTMLMediaElement>(element) ||
IsA<HTMLInputElement>(element) || IsA<HTMLTextAreaElement>(element) ||
IsA<HTMLSelectElement>(element)) {
style.SetDisplay(EDisplay::kNone);
@@ -347,12 +401,6 @@ void StyleAdjuster::AdjustOverflow(ComputedStyle& style) {
style.OverflowX() != EOverflow::kVisible) {
style.SetOverflowY(EOverflow::kAuto);
}
-
- // Menulists should have visible overflow
- if (style.Appearance() == kMenulistPart) {
- style.SetOverflowX(EOverflow::kVisible);
- style.SetOverflowY(EOverflow::kVisible);
- }
}
static void AdjustStyleForDisplay(ComputedStyle& style,
@@ -467,7 +515,7 @@ static void AdjustEffectiveTouchAction(ComputedStyle& style,
bool is_layout_object_needed =
element && element->LayoutObjectIsNeeded(style);
- TouchAction element_touch_action = TouchAction::kTouchActionAuto;
+ TouchAction element_touch_action = TouchAction::kAuto;
// Touch actions are only supported by elements that support both the CSS
// width and height properties.
// See https://www.w3.org/TR/pointerevents/#the-touch-action-css-property.
@@ -486,7 +534,7 @@ static void AdjustEffectiveTouchAction(ComputedStyle& style,
// Apply touch action inherited from parent frame.
if (is_child_document && element->GetDocument().GetFrame()) {
inherited_action &=
- TouchAction::kTouchActionPan |
+ TouchAction::kPan |
element->GetDocument().GetFrame()->InheritedEffectiveTouchAction();
}
@@ -500,9 +548,9 @@ static void AdjustEffectiveTouchAction(ComputedStyle& style,
inherited_action =
AdjustTouchActionForElement(inherited_action, style, element);
- TouchAction enforced_by_policy = TouchAction::kTouchActionNone;
+ TouchAction enforced_by_policy = TouchAction::kNone;
if (element->GetDocument().IsVerticalScrollEnforced())
- enforced_by_policy = TouchAction::kTouchActionPanY;
+ enforced_by_policy = TouchAction::kPanY;
// Apply the adjusted parent effective touch actions.
style.SetEffectiveTouchAction((element_touch_action & inherited_action) |
@@ -518,57 +566,22 @@ static void AdjustEffectiveTouchAction(ComputedStyle& style,
}
}
-static void AdjustStateForRenderSubtree(ComputedStyle& style,
- Element* element) {
+static void AdjustStateForSubtreeVisibility(ComputedStyle& style,
+ Element* element) {
if (!element)
return;
-
- bool should_be_invisible = style.RenderSubtreeInvisible();
auto* context = element->GetDisplayLockContext();
-
- // Return early if there's no context and no render-subtree invisible token.
- if (!should_be_invisible && !context)
- return;
-
- // If we're using an attribute version of display locking, then also abort.
- if (context && DisplayLockContext::IsAttributeVersion(context))
+ // The common case for most elements is that we don't have a context and have
+ // the default (visible) subtree-visibility value.
+ if (LIKELY(!context &&
+ style.SubtreeVisibility() == ESubtreeVisibility::kVisible)) {
return;
-
- // Create a context if we need to be invisible.
- if (should_be_invisible && !context) {
- context = &element->EnsureDisplayLockContext(
- DisplayLockContextCreateMethod::kCSS);
- }
- DCHECK(context);
-
- uint16_t activation_mask =
- static_cast<uint16_t>(DisplayLockActivationReason::kAny);
- if (style.RenderSubtreeSkipActivation()) {
- activation_mask = 0;
- } else if (style.RenderSubtreeSkipViewportActivation()) {
- activation_mask &=
- ~static_cast<uint16_t>(DisplayLockActivationReason::kViewport);
}
- // Propagate activatable style to context.
- context->SetActivatable(activation_mask);
-
- if (should_be_invisible) {
- // Add containment to style if we're invisible.
- auto contain =
- style.Contain() | kContainsStyle | kContainsLayout | kContainsSize;
- style.SetContain(contain);
-
- // If we're unlocked and unactivated, then we should lock the context. Note
- // that we do this here, since locking the element means we can skip styling
- // the subtree.
- if (!context->IsLocked() && !context->IsActivated())
- context->StartAcquire();
- } else {
- context->ClearActivated();
- if (context->IsLocked())
- context->StartCommit();
- }
+ if (!context)
+ context = &element->EnsureDisplayLockContext();
+ context->SetRequestedState(style.SubtreeVisibility());
+ context->AdjustElementStyle(&style);
}
void StyleAdjuster::AdjustComputedStyle(StyleResolverState& state,
@@ -608,6 +621,7 @@ void StyleAdjuster::AdjustComputedStyle(StyleResolverState& state,
// We don't adjust the first letter style earlier because we may change the
// display setting in adjustStyeForTagName() above.
AdjustStyleForFirstLetter(style);
+ AdjustStyleForMarker(style, parent_style, state.GetElement());
AdjustStyleForDisplay(style, layout_parent_style,
element ? &element->GetDocument() : nullptr);
@@ -618,35 +632,18 @@ void StyleAdjuster::AdjustComputedStyle(StyleResolverState& state,
style.SetDisplayLayoutCustomParentName(
layout_parent_style.DisplayLayoutCustomName());
}
+
+ bool is_in_main_frame = element && element->GetDocument().IsInMainFrame();
+ // The root element of the main frame has no backdrop, so don't allow
+ // it to have a backdrop filter either.
+ if (is_document_element && is_in_main_frame && style.HasBackdropFilter())
+ style.MutableBackdropFilter().clear();
} else {
AdjustStyleForFirstLetter(style);
}
- if (element &&
- RuntimeEnabledFeatures::DisplayLockingEnabled(
- element->GetExecutionContext()) &&
- element->FastHasAttribute(html_names::kRendersubtreeAttr)) {
- // The element has the rendersubtree attr, so we should add style and
- // layout containment. If the attribute contains "invisible" we should
- // also add size containment.
- Containment contain = kContainsStyle | kContainsLayout;
- SpaceSplitString tokens(
- element->FastGetAttribute(html_names::kRendersubtreeAttr).LowerASCII());
- if (style.ContainsSize() || tokens.Contains("invisible")) {
- contain |= kContainsSize;
- }
- if (style.ContainsPaint())
- contain |= kContainsPaint;
- style.SetContain(contain);
- }
-
- if (RuntimeEnabledFeatures::CSSRenderSubtreeEnabled())
- AdjustStateForRenderSubtree(style, element);
-
- if (style.IsColorInternalText()) {
- style.ResolveInternalTextColor(
- LayoutTheme::GetTheme().RootElementColor(style.UsedColorScheme()));
- }
+ if (RuntimeEnabledFeatures::CSSSubtreeVisibilityEnabled())
+ AdjustStateForSubtreeVisibility(style, element);
// Make sure our z-index value is only applied if the object is positioned.
if (style.GetPosition() == EPosition::kStatic &&
@@ -719,6 +716,18 @@ void StyleAdjuster::AdjustComputedStyle(StyleResolverState& state,
// https://drafts.csswg.org/css-display/#unbox-mathml
style.SetDisplay(EDisplay::kNone);
}
+ if (auto* space = DynamicTo<MathMLSpaceElement>(*element)) {
+ space->AddMathBaselineIfNeeded(style, state.CssToLengthConversionData());
+ } else if (auto* fraction = DynamicTo<MathMLFractionElement>(*element)) {
+ fraction->AddMathFractionBarThicknessIfNeeded(
+ style, state.CssToLengthConversionData());
+ }
+ if (style.GetWritingMode() != WritingMode::kHorizontalTb) {
+ // TODO(rbuis): this will not work with logical CSS properties.
+ // Disable vertical writing-mode for now.
+ style.SetWritingMode(WritingMode::kHorizontalTb);
+ style.UpdateFontOrientation();
+ }
}
// If this node is sticky it marks the creation of a sticky subtree, which we
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/style_adjuster_test.cc b/chromium/third_party/blink/renderer/core/css/resolver/style_adjuster_test.cc
index f2ed5f9c2df..070db9a01a6 100644
--- a/chromium/third_party/blink/renderer/core/css/resolver/style_adjuster_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/resolver/style_adjuster_test.cc
@@ -31,13 +31,13 @@ TEST_F(StyleAdjusterTest, TouchActionPropagatedAcrossIframes) {
UpdateAllLifecyclePhasesForTest();
Element* target = ChildDocument().getElementById("target");
- EXPECT_EQ(TouchAction::kTouchActionNone,
+ EXPECT_EQ(TouchAction::kNone,
target->GetComputedStyle()->GetEffectiveTouchAction());
Element* owner = GetDocument().getElementById("owner");
owner->setAttribute(html_names::kStyleAttr, "touch-action: auto");
UpdateAllLifecyclePhasesForTest();
- EXPECT_EQ(TouchAction::kTouchActionPinchZoom,
+ EXPECT_EQ(TouchAction::kPinchZoom,
target->GetComputedStyle()->GetEffectiveTouchAction());
}
@@ -53,7 +53,7 @@ TEST_F(StyleAdjusterTest, TouchActionPanningReEnabledByScrollers) {
UpdateAllLifecyclePhasesForTest();
Element* target = GetDocument().getElementById("target");
- EXPECT_EQ(TouchAction::kTouchActionManipulation,
+ EXPECT_EQ(TouchAction::kManipulation,
target->GetComputedStyle()->GetEffectiveTouchAction());
}
@@ -69,20 +69,20 @@ TEST_F(StyleAdjusterTest, TouchActionPropagatedWhenAncestorStyleChanges) {
UpdateAllLifecyclePhasesForTest();
Element* target = GetDocument().getElementById("target");
- EXPECT_EQ(TouchAction::kTouchActionPanX,
+ EXPECT_EQ(TouchAction::kPanX,
target->GetComputedStyle()->GetEffectiveTouchAction());
Element* ancestor = GetDocument().getElementById("ancestor");
ancestor->setAttribute(html_names::kStyleAttr, "touch-action: pan-y");
UpdateAllLifecyclePhasesForTest();
- EXPECT_EQ(TouchAction::kTouchActionPanY,
+ EXPECT_EQ(TouchAction::kPanY,
target->GetComputedStyle()->GetEffectiveTouchAction());
Element* potential_scroller =
GetDocument().getElementById("potential-scroller");
potential_scroller->setAttribute(html_names::kStyleAttr, "overflow: scroll");
UpdateAllLifecyclePhasesForTest();
- EXPECT_EQ(TouchAction::kTouchActionPan,
+ EXPECT_EQ(TouchAction::kPan,
target->GetComputedStyle()->GetEffectiveTouchAction());
}
@@ -97,13 +97,13 @@ TEST_F(StyleAdjusterTest, TouchActionRestrictedByLowerAncestor) {
UpdateAllLifecyclePhasesForTest();
Element* target = GetDocument().getElementById("target");
- EXPECT_EQ(TouchAction::kTouchActionPanRight,
+ EXPECT_EQ(TouchAction::kPanRight,
target->GetComputedStyle()->GetEffectiveTouchAction());
Element* parent = GetDocument().getElementById("parent");
parent->setAttribute(html_names::kStyleAttr, "touch-action: auto");
UpdateAllLifecyclePhasesForTest();
- EXPECT_EQ(TouchAction::kTouchActionPanX,
+ EXPECT_EQ(TouchAction::kPanX,
target->GetComputedStyle()->GetEffectiveTouchAction());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/style_animator.cc b/chromium/third_party/blink/renderer/core/css/resolver/style_animator.cc
deleted file mode 100644
index c9ebb4db1c5..00000000000
--- a/chromium/third_party/blink/renderer/core/css/resolver/style_animator.cc
+++ /dev/null
@@ -1,78 +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/css/resolver/style_animator.h"
-
-#include "third_party/blink/renderer/core/animation/css_interpolation_environment.h"
-#include "third_party/blink/renderer/core/animation/css_interpolation_types_map.h"
-#include "third_party/blink/renderer/core/animation/invalidatable_interpolation.h"
-#include "third_party/blink/renderer/core/animation/transition_interpolation.h"
-#include "third_party/blink/renderer/core/css/css_pending_interpolation_value.h"
-#include "third_party/blink/renderer/core/css/properties/longhands/custom_property.h"
-
-namespace blink {
-
-namespace {
-
-PropertyHandle ToPropertyHandle(
- const CSSProperty& property,
- const cssvalue::CSSPendingInterpolationValue& value) {
- if (IsA<CustomProperty>(property))
- return PropertyHandle(property.GetPropertyNameAtomicString());
- return PropertyHandle(property, value.IsPresentationAttribute());
-}
-
-const ActiveInterpolations& GetActiveInterpolations(
- const ActiveInterpolationsMap& animations_map,
- const ActiveInterpolationsMap& transitions_map,
- const PropertyHandle& property) {
- // Interpolations will never be found in both animations_map and
- // transitions_map. This condition is ensured by
- // CSSAnimations::CalculateTransitionUpdateForProperty().
- const auto& animation = animations_map.find(property);
- if (animation != animations_map.end()) {
- DCHECK_EQ(transitions_map.find(property), transitions_map.end());
- return animation->value;
- }
- const auto& transition = transitions_map.find(property);
- DCHECK_NE(transition, transitions_map.end());
- return transition->value;
-}
-
-const ActiveInterpolations& GetActiveInterpolations(
- const CSSAnimationUpdate& update,
- const PropertyHandle& property) {
- if (property.IsCSSCustomProperty()) {
- return GetActiveInterpolations(
- update.ActiveInterpolationsForCustomAnimations(),
- update.ActiveInterpolationsForCustomTransitions(), property);
- }
- return GetActiveInterpolations(
- update.ActiveInterpolationsForStandardAnimations(),
- update.ActiveInterpolationsForStandardTransitions(), property);
-}
-
-} // namespace
-
-StyleAnimator::StyleAnimator(StyleResolverState& state, StyleCascade& cascade)
- : state_(state), cascade_(cascade) {}
-
-void StyleAnimator::Apply(const CSSProperty& property,
- const cssvalue::CSSPendingInterpolationValue& value,
- StyleCascade::Resolver& resolver) {
- PropertyHandle property_handle = ToPropertyHandle(property, value);
- const ActiveInterpolations& interpolations =
- GetActiveInterpolations(state_.AnimationUpdate(), property_handle);
- const Interpolation& interpolation = *interpolations.front();
- if (interpolation.IsInvalidatableInterpolation()) {
- CSSInterpolationTypesMap map(state_.GetDocument().GetPropertyRegistry(),
- state_.GetDocument());
- CSSInterpolationEnvironment environment(map, state_, &cascade_, &resolver);
- InvalidatableInterpolation::ApplyStack(interpolations, environment);
- } else {
- ToTransitionInterpolation(interpolation).Apply(state_);
- }
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/style_animator.h b/chromium/third_party/blink/renderer/core/css/resolver/style_animator.h
deleted file mode 100644
index 5bcbc7f2c41..00000000000
--- a/chromium/third_party/blink/renderer/core/css/resolver/style_animator.h
+++ /dev/null
@@ -1,53 +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_CSS_RESOLVER_STYLE_ANIMATOR_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_STYLE_ANIMATOR_H_
-
-#include "third_party/blink/renderer/core/animation/interpolation.h"
-#include "third_party/blink/renderer/core/animation/property_handle.h"
-#include "third_party/blink/renderer/core/css/resolver/style_cascade.h"
-
-namespace blink {
-
-class StyleResolverState;
-class StyleCascade;
-
-namespace cssvalue {
-
-class CSSPendingInterpolationValue;
-
-} // namespace cssvalue
-
-// StyleAnimator is a class which knows how to apply active interpolations
-// for given a CSSProperty.
-//
-// When the set of currently animating properties has been determined,
-// a CSSPendingInterpolationValues is added to the cascade for each animating
-// property (see StyleResolver::CascadeInterpolations). Later, when the
-// cascade is applied, an Animator may be provided. That Animator is then
-// responsible for applying the actual interpolated values represented by
-// any CSSPendingInterpolationValues that may (or may not) remain in the
-// cascade. See StyleCascade::Animator for more information.
-//
-// TODO(crbug.com/985051) Evaluate if there's a performance issue here, and
-// if so possibly store active interpolations directly in the cascade.
-class CORE_EXPORT StyleAnimator : public StyleCascade::Animator {
- STACK_ALLOCATED();
-
- public:
- explicit StyleAnimator(StyleResolverState&, StyleCascade&);
-
- void Apply(const CSSProperty&,
- const cssvalue::CSSPendingInterpolationValue&,
- StyleCascade::Resolver&) override;
-
- private:
- StyleResolverState& state_;
- StyleCascade& cascade_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_STYLE_ANIMATOR_H_
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 fe1a6a2de31..b336c49b015 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
@@ -52,13 +52,10 @@
#include "third_party/blink/renderer/core/css/css_uri_value.h"
#include "third_party/blink/renderer/core/css/parser/css_tokenizer.h"
#include "third_party/blink/renderer/core/css/resolver/filter_operation_resolver.h"
-#include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h"
#include "third_party/blink/renderer/core/css/resolver/transform_builder.h"
#include "third_party/blink/renderer/core/css/style_engine.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/style/computed_style.h"
-#include "third_party/blink/renderer/core/style/intrinsic_length.h"
#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"
@@ -130,7 +127,7 @@ scoped_refptr<StyleSVGResource> StyleBuilderConverter::ConvertElementReference(
return nullptr;
SVGResource* resource =
state.GetElementStyleResources().GetSVGResourceFromValue(
- state.GetTreeScope(), *url_value);
+ state.GetElement().OriginatingTreeScope(), *url_value);
return StyleSVGResource::Create(resource, url_value->ValueForSerialization());
}
@@ -152,7 +149,7 @@ scoped_refptr<ClipPathOperation> StyleBuilderConverter::ConvertClipPath(
if (const auto* url_value = DynamicTo<cssvalue::CSSURIValue>(value)) {
SVGResource* resource =
state.GetElementStyleResources().GetSVGResourceFromValue(
- state.GetTreeScope(), *url_value);
+ state.GetElement().OriginatingTreeScope(), *url_value);
// TODO(fs): Doesn't work with external SVG references (crbug.com/109212.)
return ReferenceClipPathOperation::Create(
url_value->ValueForSerialization(), resource);
@@ -190,8 +187,6 @@ static FontDescription::GenericFamilyType ConvertGenericFamily(
return FontDescription::kFantasyFamily;
case CSSValueID::kMonospace:
return FontDescription::kMonospaceFamily;
- case CSSValueID::kWebkitPictograph:
- return FontDescription::kPictographFamily;
default:
return FontDescription::kNoFamily;
}
@@ -940,28 +935,6 @@ void StyleBuilderConverter::ConvertGridTrackList(
DCHECK(!track_sizes.IsEmpty() || !auto_repeat_track_sizes.IsEmpty());
}
-void StyleBuilderConverter::ConvertOrderedNamedGridLinesMapToNamedGridLinesMap(
- const OrderedNamedGridLines& ordered_named_grid_lines,
- NamedGridLinesMap& named_grid_lines) {
- DCHECK_EQ(named_grid_lines.size(), 0u);
-
- if (ordered_named_grid_lines.size() == 0)
- return;
-
- for (auto& ordered_named_grid_line : ordered_named_grid_lines) {
- for (auto& line_name : ordered_named_grid_line.value) {
- NamedGridLinesMap::AddResult start_result =
- named_grid_lines.insert(line_name, Vector<size_t>());
- start_result.stored_value->value.push_back(ordered_named_grid_line.key);
- }
- }
-
- for (auto& named_grid_line : named_grid_lines) {
- Vector<size_t>& grid_line_indexes = named_grid_line.value;
- std::sort(grid_line_indexes.begin(), grid_line_indexes.end());
- }
-}
-
void StyleBuilderConverter::CreateImplicitNamedGridLinesFromGridArea(
const NamedGridAreaMap& named_grid_areas,
NamedGridLinesMap& named_grid_lines,
@@ -1001,8 +974,13 @@ float StyleBuilderConverter::ConvertBorderWidth(StyleResolverState& state,
return 0;
}
const auto& primitive_value = To<CSSPrimitiveValue>(value);
- return primitive_value.ComputeLength<float>(
- state.CssToLengthConversionData());
+ double result =
+ primitive_value.ComputeLength<float>(state.CssToLengthConversionData());
+ double zoomed_result = state.StyleRef().EffectiveZoom() * result;
+ if (zoomed_result > 0.0 && zoomed_result < 1.0)
+ return 1.0;
+ return clampTo<float>(result, defaultMinimumForClamp<float>(),
+ defaultMaximumForClamp<float>());
}
GapLength StyleBuilderConverter::ConvertGapLength(StyleResolverState& state,
@@ -1089,7 +1067,7 @@ Length StyleBuilderConverter::ConvertLengthMaxSizing(StyleResolverState& state,
const CSSValue& value) {
auto* identifier_value = DynamicTo<CSSIdentifierValue>(value);
if (identifier_value && identifier_value->GetValueID() == CSSValueID::kNone)
- return Length::MaxSizeNone();
+ return Length::None();
return ConvertLengthSizing(state, value);
}
@@ -1683,11 +1661,11 @@ scoped_refptr<ScaleTransformOperation> StyleBuilderConverter::ConvertScale(
RespectImageOrientationEnum StyleBuilderConverter::ConvertImageOrientation(
StyleResolverState& state,
const CSSValue& value) {
+ // The default is kFromImage, so branch on the only other valid value, kNone
auto* identifier_value = DynamicTo<CSSIdentifierValue>(value);
- return identifier_value &&
- identifier_value->GetValueID() == CSSValueID::kFromImage
- ? kRespectImageOrientation
- : kDoNotRespectImageOrientation;
+ return identifier_value && identifier_value->GetValueID() == CSSValueID::kNone
+ ? kDoNotRespectImageOrientation
+ : kRespectImageOrientation;
}
scoped_refptr<StylePath> StyleBuilderConverter::ConvertPathOrNone(
@@ -1861,17 +1839,47 @@ StyleBuilderConverter::CssToLengthConversionData(StyleResolverState& state) {
return state.CssToLengthConversionData();
}
-IntrinsicLength StyleBuilderConverter::ConvertIntrinsicLength(
+LengthSize StyleBuilderConverter::ConvertIntrinsicSize(
StyleResolverState& state,
const CSSValue& value) {
auto* identifier_value = DynamicTo<CSSIdentifierValue>(value);
- if (identifier_value) {
- if (identifier_value->GetValueID() == CSSValueID::kLegacy)
- return IntrinsicLength::MakeLegacy();
- if (identifier_value->GetValueID() == CSSValueID::kAuto)
- return IntrinsicLength::MakeAuto();
- }
- return IntrinsicLength::Make(ConvertLength(state, value));
+ if (identifier_value && identifier_value->GetValueID() == CSSValueID::kAuto)
+ return LengthSize(Length::Auto(), Length::Auto());
+ const CSSValuePair& pair = To<CSSValuePair>(value);
+ Length width = ConvertLength(state, pair.First());
+ Length height = ConvertLength(state, pair.Second());
+ return LengthSize(width, height);
+}
+
+base::Optional<IntSize> StyleBuilderConverter::ConvertAspectRatio(
+ StyleResolverState& state,
+ const CSSValue& value) {
+ auto* identifier_value = DynamicTo<CSSIdentifierValue>(value);
+ if (identifier_value && identifier_value->GetValueID() == CSSValueID::kAuto)
+ return base::nullopt;
+ const CSSValueList& list = To<CSSValueList>(value);
+ DCHECK_EQ(list.length(), 2u);
+ int width = To<CSSPrimitiveValue>(list.Item(0)).GetIntValue();
+ int height = To<CSSPrimitiveValue>(list.Item(1)).GetIntValue();
+ return IntSize(width, height);
+}
+
+bool StyleBuilderConverter::ConvertInternalEmptyLineHeight(
+ StyleResolverState&,
+ const CSSValue& value) {
+ auto* identifier_value = DynamicTo<CSSIdentifierValue>(value);
+ return identifier_value &&
+ identifier_value->GetValueID() == CSSValueID::kFabricated;
+}
+
+AtomicString StyleBuilderConverter::ConvertPage(StyleResolverState& state,
+ const CSSValue& value) {
+ if (auto* custom_ident_value = DynamicTo<CSSCustomIdentValue>(value))
+ return AtomicString(custom_ident_value->Value());
+ DCHECK(DynamicTo<CSSIdentifierValue>(value));
+ DCHECK_EQ(DynamicTo<CSSIdentifierValue>(value)->GetValueID(),
+ CSSValueID::kAuto);
+ return AtomicString();
}
} // 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 f83616b2085..d81b23435e1 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
@@ -36,6 +36,8 @@
#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/resolver/style_resolver_state.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style/grid_area.h"
#include "third_party/blink/renderer/core/style/grid_positions_resolver.h"
#include "third_party/blink/renderer/core/style/named_grid_lines_map.h"
@@ -231,9 +233,6 @@ class StyleBuilderConverter {
const NamedGridAreaMap&,
NamedGridLinesMap&,
GridTrackSizingDirection);
- static void ConvertOrderedNamedGridLinesMapToNamedGridLinesMap(
- const OrderedNamedGridLines&,
- NamedGridLinesMap&);
static cc::ScrollSnapType ConvertSnapType(StyleResolverState&,
const CSSValue&);
@@ -272,8 +271,15 @@ class StyleBuilderConverter {
const CSSValue&,
bool is_animation_tainted);
- static IntrinsicLength ConvertIntrinsicLength(StyleResolverState&,
- const CSSValue&);
+ static LengthSize ConvertIntrinsicSize(StyleResolverState&, const CSSValue&);
+
+ static base::Optional<IntSize> ConvertAspectRatio(StyleResolverState&,
+ const CSSValue&);
+
+ static bool ConvertInternalEmptyLineHeight(StyleResolverState& state,
+ const CSSValue& value);
+
+ static AtomicString ConvertPage(StyleResolverState&, const CSSValue&);
private:
static const CSSToLengthConversionData& CssToLengthConversionData(
@@ -322,7 +328,8 @@ T StyleBuilderConverter::ConvertLineWidth(StyleResolverState& state,
// Reference crbug.com/485650 and crbug.com/382483
double result =
primitive_value.ComputeLength<double>(CssToLengthConversionData(state));
- if (result > 0.0 && result < 1.0)
+ double zoomed_result = state.StyleRef().EffectiveZoom() * result;
+ if (zoomed_result > 0.0 && zoomed_result < 1.0)
return 1.0;
return clampTo<T>(RoundForImpreciseConversion<T>(result),
defaultMinimumForClamp<T>(), defaultMaximumForClamp<T>());
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 3b0f06df960..1fc9ecbb274 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
@@ -13,7 +13,6 @@
#include "third_party/blink/renderer/core/css/css_custom_property_declaration.h"
#include "third_party/blink/renderer/core/css/css_font_selector.h"
#include "third_party/blink/renderer/core/css/css_invalid_variable_value.h"
-#include "third_party/blink/renderer/core/css/css_pending_interpolation_value.h"
#include "third_party/blink/renderer/core/css/css_pending_substitution_value.h"
#include "third_party/blink/renderer/core/css/css_unset_value.h"
#include "third_party/blink/renderer/core/css/css_variable_data.h"
@@ -24,26 +23,23 @@
#include "third_party/blink/renderer/core/css/properties/css_property.h"
#include "third_party/blink/renderer/core/css/properties/css_property_ref.h"
#include "third_party/blink/renderer/core/css/property_registry.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_expansion.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_interpolations.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_resolver.h"
#include "third_party/blink/renderer/core/css/resolver/css_property_priority.h"
#include "third_party/blink/renderer/core/css/resolver/style_builder.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h"
#include "third_party/blink/renderer/core/css/style_engine.h"
#include "third_party/blink/renderer/core/dom/shadow_root.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/platform/wtf/math_extras.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
namespace blink {
namespace {
-class NullAnimator : public StyleCascade::Animator {
- STACK_ALLOCATED();
-
- public:
- void Apply(const CSSProperty&,
- const cssvalue::CSSPendingInterpolationValue&,
- StyleCascade::Resolver&) override {}
-};
-
AtomicString ConsumeVariableName(CSSParserTokenRange& range) {
range.ConsumeWhitespace();
CSSParserToken ident_token = range.ConsumeIncludingWhitespace();
@@ -66,85 +62,91 @@ const CSSValue* Parse(const CSSProperty& property,
context);
}
-constexpr bool IsImportant(StyleCascade::Origin origin) {
- return static_cast<uint8_t>(origin) & StyleCascade::kImportantBit;
+uint32_t EncodeInterpolationPosition(size_t index,
+ bool is_presentation_attribute) {
+ // Our tests currently expect css properties to win over presentation
+ // attributes. Hence, we borrow a bit in the position-uint32_t for this
+ // purpose.
+ return (static_cast<uint32_t>(!is_presentation_attribute) << 16) |
+ static_cast<uint16_t>(index);
}
-static_assert(!IsImportant(StyleCascade::Origin::kNone),
- "Origin::kNone is not important");
-static_assert(!IsImportant(StyleCascade::Origin::kUserAgent),
- "Origin::kUserAgent is not important");
-static_assert(!IsImportant(StyleCascade::Origin::kUser),
- "Origin::kUser is not important");
-static_assert(!IsImportant(StyleCascade::Origin::kAnimation),
- "Origin::kAnimation is not important");
-static_assert(IsImportant(StyleCascade::Origin::kImportantAuthor),
- "Origin::kImportantAuthor is important");
-static_assert(IsImportant(StyleCascade::Origin::kImportantUser),
- "Origin::kImportantUser is important");
-static_assert(IsImportant(StyleCascade::Origin::kImportantUserAgent),
- "Origin::kImportantUserAgent is important");
-static_assert(!IsImportant(StyleCascade::Origin::kTransition),
- "Origin::kTransition is not important");
-
-} // namespace
+size_t DecodeInterpolationIndex(uint32_t position) {
+ return position & 0xFFFF;
+}
-StyleCascade::Priority::Priority(Origin origin, uint16_t tree_order)
- : priority_((static_cast<uint64_t>(origin) << 32) |
- (static_cast<uint64_t>(tree_order) << 16) |
- StyleCascade::kMaxCascadeOrder) {}
+bool DecodeIsPresentationAttribute(uint32_t position) {
+ return (~position >> 16) & 1;
+}
-StyleCascade::Origin StyleCascade::Priority::GetOrigin() const {
- return static_cast<StyleCascade::Origin>((priority_ >> 32) & 0xFF);
+const CSSValue* ValueAt(const MatchResult& result, uint32_t position) {
+ size_t matched_properties_index = DecodeMatchedPropertiesIndex(position);
+ size_t declaration_index = DecodeDeclarationIndex(position);
+ const MatchedPropertiesVector& vector = result.GetMatchedProperties();
+ const CSSPropertyValueSet* set = vector[matched_properties_index].properties;
+ return &set->PropertyAt(declaration_index).Value();
}
-bool StyleCascade::Priority::operator>=(const Priority& other) const {
- uint64_t important_xor = IsImportant(GetOrigin()) ? 0 : (0xFF << 16);
- return (priority_ ^ important_xor) >= (other.priority_ ^ important_xor);
+PropertyHandle ToPropertyHandle(const CSSProperty& property,
+ CascadePriority priority) {
+ if (IsA<CustomProperty>(property))
+ return PropertyHandle(property.GetPropertyNameAtomicString());
+ uint32_t position = priority.GetPosition();
+ return PropertyHandle(property, DecodeIsPresentationAttribute(position));
}
-void StyleCascade::Add(const CSSPropertyName& name,
- const CSSValue* value,
- Priority priority) {
- auto result = cascade_.insert(name, Value());
- if (priority >= result.stored_value->value.GetPriority()) {
- result.stored_value->value =
- Value(value, priority.WithCascadeOrder(++order_));
- }
+} // namespace
+
+MatchResult& StyleCascade::MutableMatchResult() {
+ needs_match_result_analyze_ = true;
+ return match_result_;
}
-void StyleCascade::Apply() {
- NullAnimator animator;
- Apply(animator);
+void StyleCascade::AddInterpolations(const ActiveInterpolationsMap* map,
+ CascadeOrigin origin) {
+ DCHECK(map);
+ needs_interpolations_analyze_ = true;
+ interpolations_.Add(map, origin);
}
-void StyleCascade::Apply(Animator& animator) {
- Resolver resolver(animator);
+void StyleCascade::Apply(CascadeFilter filter) {
+ AnalyzeIfNeeded();
+
+ CascadeResolver resolver(filter, ++generation_);
+
+ // Affects the computed value of 'color', hence needs to happen before
+ // high-priority properties.
+ LookupAndApply(GetCSSPropertyColorScheme(), resolver);
+
+ ApplyWebkitBorderImage(resolver);
+
+ // -webkit-mask-image needs to be applied before -webkit-mask-composite,
+ // otherwise -webkit-mask-composite has no effect.
+ LookupAndApply(GetCSSPropertyWebkitMaskImage(), resolver);
- // TODO(crbug.com/985031): Set bits ::Add-time to know if we need to do this.
ApplyHighPriority(resolver);
- // TODO(crbug.com/985010): Improve with non-destructive Apply.
- while (!cascade_.IsEmpty()) {
- auto iter = cascade_.begin();
- const CSSPropertyName& name = iter->key;
- Apply(name, resolver);
+ ApplyMatchResult(resolver);
+ ApplyInterpolations(resolver);
+
+ if (map_.Find(CSSPropertyName(CSSPropertyID::kWebkitAppearance)) &&
+ !resolver.filter_.Rejects(GetCSSPropertyWebkitAppearance()) &&
+ state_.Style()->HasAppearance()) {
+ state_.Style()->SetHasAuthorBackground(HasAuthorBackground());
+ state_.Style()->SetHasAuthorBorder(HasAuthorBorder());
}
}
-void StyleCascade::RemoveAnimationPriority() {
- using AnimPrio = CSSPropertyPriorityData<kAnimationPropertyPriority>;
- int first = static_cast<int>(AnimPrio::First());
- int last = static_cast<int>(AnimPrio::Last());
- for (int i = first; i <= last; ++i) {
- CSSPropertyName name(convertToCSSPropertyID(i));
- cascade_.erase(name);
- }
+void StyleCascade::Reset() {
+ map_.Reset();
+ match_result_.Reset();
+ interpolations_.Reset();
+ generation_ = 0;
}
const CSSValue* StyleCascade::Resolve(const CSSPropertyName& name,
const CSSValue& value,
- Resolver& resolver) {
+ CascadeResolver& resolver) {
CSSPropertyRef ref(name, state_.GetDocument());
const CSSValue* resolved = Resolve(ref.GetProperty(), value, resolver);
@@ -157,78 +159,295 @@ const CSSValue* StyleCascade::Resolve(const CSSPropertyName& name,
return resolved;
}
-void StyleCascade::ApplyHighPriority(Resolver& resolver) {
- using HighPriority = CSSPropertyPriorityData<kHighPropertyPriority>;
- int first = static_cast<int>(HighPriority::First());
- int last = static_cast<int>(HighPriority::Last());
- for (int i = first; i <= last; ++i)
- Apply(CSSProperty::Get(convertToCSSPropertyID(i)), resolver);
+void StyleCascade::AnalyzeIfNeeded() {
+ if (needs_match_result_analyze_) {
+ AnalyzeMatchResult();
+ needs_match_result_analyze_ = false;
+ }
+ if (needs_interpolations_analyze_) {
+ AnalyzeInterpolations();
+ needs_interpolations_analyze_ = true;
+ }
+}
+
+void StyleCascade::AnalyzeMatchResult() {
+ for (auto e : match_result_.Expansions(GetDocument(), CascadeFilter())) {
+ for (; !e.AtEnd(); e.Next())
+ map_.Add(e.Name(), e.Priority());
+ }
+}
+
+void StyleCascade::AnalyzeInterpolations() {
+ const auto& entries = interpolations_.GetEntries();
+ for (size_t i = 0; i < entries.size(); ++i) {
+ for (const auto& active_interpolation : *entries[i].map) {
+ uint32_t position = EncodeInterpolationPosition(
+ i, active_interpolation.key.IsPresentationAttribute());
+ CascadePriority priority(entries[i].origin, false, 0, position);
+
+ auto name = active_interpolation.key.GetCSSPropertyName();
+ CSSPropertyRef ref(name, GetDocument());
+ DCHECK(ref.IsValid());
+ const CSSProperty& property = ref.GetProperty();
+
+ map_.Add(name, priority);
+
+ // Since an interpolation for an unvisited property also causes an
+ // interpolation of the visited property, add the visited property to
+ // the map as well.
+ // TODO(crbug.com/1062217): Interpolate visited colors separately
+ if (const CSSProperty* visited = property.GetVisitedProperty())
+ map_.Add(visited->GetCSSPropertyName(), priority);
+ }
+ }
+}
+
+void StyleCascade::ApplyHighPriority(CascadeResolver& resolver) {
+ uint64_t bits = map_.HighPriorityBits();
- state_.GetFontBuilder().CreateFont(
- state_.GetDocument().GetStyleEngine().GetFontSelector(),
- state_.StyleRef());
+ if (bits) {
+ using HighPriority = CSSPropertyPriorityData<kHighPropertyPriority>;
+ int first = static_cast<int>(HighPriority::First());
+ int last = static_cast<int>(HighPriority::Last());
+ for (int i = first; i <= last; ++i) {
+ if (bits & (static_cast<uint64_t>(1) << i))
+ LookupAndApply(CSSProperty::Get(convertToCSSPropertyID(i)), resolver);
+ }
+ }
+
+ state_.GetFontBuilder().CreateFont(state_.StyleRef(), state_.ParentStyle());
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::Apply(const CSSPropertyName& name) {
- NullAnimator animator;
- Resolver resolver(animator);
- Apply(name, resolver);
+void StyleCascade::ApplyWebkitBorderImage(CascadeResolver& resolver) {
+ const CascadePriority* priority =
+ map_.Find(CSSPropertyName(CSSPropertyID::kWebkitBorderImage));
+ if (!priority)
+ return;
+
+ // -webkit-border-image is a surrogate for the border-image (shorthand).
+ // By applying -webkit-border-image first, we avoid having to "partially"
+ // apply -webkit-border-image depending on the border-image-* longhands that
+ // have already been applied.
+ // See also crbug.com/1056600
+ LookupAndApply(GetCSSPropertyWebkitBorderImage(), resolver);
+
+ const auto& shorthand = borderImageShorthand();
+ const CSSProperty** longhands = shorthand.properties();
+ for (unsigned i = 0; i < shorthand.length(); ++i) {
+ const CSSProperty& longhand = *longhands[i];
+ if (CascadePriority* p = map_.Find(longhand.GetCSSPropertyName())) {
+ // If -webkit-border-image has higher priority than a border-image
+ // longhand, we skip applying that longhand.
+ if (*p < *priority)
+ *p = CascadePriority(*p, resolver.generation_);
+ }
+ }
}
-void StyleCascade::Apply(const CSSPropertyName& name, Resolver& resolver) {
- CSSPropertyRef ref(name, state_.GetDocument());
- DCHECK(ref.IsValid());
- Apply(ref.GetProperty(), resolver);
+void StyleCascade::ApplyMatchResult(CascadeResolver& resolver) {
+ for (auto e : match_result_.Expansions(GetDocument(), resolver.filter_)) {
+ for (; !e.AtEnd(); e.Next()) {
+ auto priority = CascadePriority(e.Priority(), resolver.generation_);
+ CascadePriority* p = map_.Find(e.Name());
+ if (!p || *p >= priority)
+ continue;
+ *p = priority;
+ const CSSProperty& property = e.Property();
+ if (property.IsSurrogate()) {
+ ApplySurrogate(property, priority, resolver);
+ continue;
+ }
+ const CSSValue* value = Resolve(property, e.Value(), resolver);
+ StyleBuilder::ApplyProperty(property, state_, *value);
+ }
+ }
}
-void StyleCascade::Apply(const CSSProperty& property, Resolver& resolver) {
- CSSPropertyName name = property.GetCSSPropertyName();
+void StyleCascade::ApplyInterpolations(CascadeResolver& resolver) {
+ const auto& entries = interpolations_.GetEntries();
+ for (size_t i = 0; i < entries.size(); ++i) {
+ const auto& entry = entries[i];
+ ApplyInterpolationMap(*entry.map, entry.origin, i, resolver);
+ }
+}
- DCHECK(!resolver.IsLocked(name));
+void StyleCascade::ApplyInterpolationMap(const ActiveInterpolationsMap& map,
+ CascadeOrigin origin,
+ size_t index,
+ CascadeResolver& resolver) {
+ for (const auto& entry : map) {
+ auto name = entry.key.GetCSSPropertyName();
+ uint32_t position =
+ EncodeInterpolationPosition(index, entry.key.IsPresentationAttribute());
+ CascadePriority priority(origin, false, 0, position);
+ priority = CascadePriority(priority, resolver.generation_);
+
+ CSSPropertyRef ref(name, GetDocument());
+ const CSSProperty& property = ref.GetProperty();
+ if (resolver.filter_.Rejects(property))
+ continue;
+
+ CascadePriority* p = map_.Find(name);
+ if (!p || *p >= priority) {
+ if (p->IsImportant())
+ state_.SetHasImportantOverrides();
+ continue;
+ }
+ *p = priority;
- Value cascaded = cascade_.Take(property.GetCSSPropertyName());
- if (cascaded.IsEmpty())
- return;
+ if (property.IsSurrogate()) {
+ ApplySurrogate(property, priority, resolver);
+ continue;
+ }
- const CSSValue* value = cascaded.GetValue();
+ ApplyInterpolation(property, priority, entry.value, resolver);
+ }
+}
- if (const auto* v =
- DynamicTo<cssvalue::CSSPendingInterpolationValue>(value)) {
- resolver.animator_.Apply(property, *v, resolver);
- return;
+void StyleCascade::ApplyInterpolation(
+ const CSSProperty& property,
+ CascadePriority priority,
+ const ActiveInterpolations& interpolations,
+ CascadeResolver& resolver) {
+ const Interpolation& interpolation = *interpolations.front();
+ if (IsA<InvalidatableInterpolation>(interpolation)) {
+ CSSInterpolationTypesMap map(state_.GetDocument().GetPropertyRegistry(),
+ state_.GetDocument());
+ CSSInterpolationEnvironment environment(map, state_, this, &resolver);
+ InvalidatableInterpolation::ApplyStack(interpolations, environment);
+ } else {
+ To<TransitionInterpolation>(interpolation).Apply(state_);
}
- value = Resolve(property, *value, resolver);
+ if (property.AffectsFont())
+ state_.SetHasFontAffectingAnimation();
- DCHECK(!value->IsVariableReferenceValue());
- DCHECK(!value->IsPendingSubstitutionValue());
- DCHECK(!value->IsPendingInterpolationValue());
+ // Applying a color property interpolation will also unconditionally apply
+ // the -internal-visited- counterpart (see CSSColorInterpolationType::
+ // ApplyStandardPropertyValue). To make sure !important rules in :visited
+ // selectors win over animations, we re-apply the -internal-visited property
+ // if its priority is higher.
+ //
+ // TODO(crbug.com/1062217): Interpolate visited colors separately
+ if (const CSSProperty* visited = property.GetVisitedProperty()) {
+ CascadePriority* visited_priority =
+ 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);
+ LookupAndApply(*visited, resolver);
+ }
+ }
+}
+
+void StyleCascade::ApplySurrogate(const CSSProperty& surrogate,
+ CascadePriority surrogate_priority,
+ CascadeResolver& resolver) {
+ DCHECK(surrogate.IsSurrogate());
+
+ const CSSProperty& original = SurrogateFor(surrogate);
+ CascadePriority* original_priority = map_.Find(original.GetCSSPropertyName());
+
+ if (original_priority) {
+ if (surrogate_priority < *original_priority) {
+ // The original has a higher priority, so skip the surrogate property.
+ return;
+ }
- if (!resolver.filter_.Add(property, cascaded))
+ // The surrogate has a higher priority, so skip the original property.
+ // The original might have been applied already, but that doesn't matter,
+ // as we're about to overwrite it.
+ resolver.MarkApplied(original_priority);
+ }
+
+ LookupAndApplyValue(surrogate, surrogate_priority, resolver);
+}
+
+void StyleCascade::LookupAndApply(const CSSPropertyName& name,
+ CascadeResolver& resolver) {
+ CSSPropertyRef ref(name, state_.GetDocument());
+ DCHECK(ref.IsValid());
+ LookupAndApply(ref.GetProperty(), resolver);
+}
+
+void StyleCascade::LookupAndApply(const CSSProperty& property,
+ CascadeResolver& resolver) {
+ CSSPropertyName name = property.GetCSSPropertyName();
+ DCHECK(!resolver.IsLocked(name));
+
+ CascadePriority* p = map_.Find(name);
+ if (!p)
return;
+ CascadePriority priority(*p, resolver.generation_);
+ if (*p >= priority)
+ return;
+ *p = priority;
- StyleBuilder::ApplyProperty(property, state_, *value);
+ if (resolver.filter_.Rejects(property))
+ return;
+ if (property.IsSurrogate()) {
+ ApplySurrogate(property, priority, resolver);
+ return;
+ }
+
+ LookupAndApplyValue(property, priority, resolver);
}
-bool StyleCascade::HasValue(const CSSPropertyName& name,
- const CSSValue* value) const {
- auto iter = cascade_.find(name);
- return (iter != cascade_.end()) && (iter->value.GetValue() == value);
+void StyleCascade::LookupAndApplyValue(const CSSProperty& property,
+ CascadePriority priority,
+ CascadeResolver& resolver) {
+ if (priority.GetOrigin() < CascadeOrigin::kAnimation)
+ LookupAndApplyDeclaration(property, priority, resolver);
+ else if (priority.GetOrigin() >= CascadeOrigin::kAnimation)
+ LookupAndApplyInterpolation(property, priority, resolver);
}
-const CSSValue* StyleCascade::GetValue(const CSSPropertyName& name) const {
- auto iter = cascade_.find(name);
- return (iter != cascade_.end()) ? iter->value.GetValue() : nullptr;
+void StyleCascade::LookupAndApplyDeclaration(const CSSProperty& property,
+ CascadePriority priority,
+ CascadeResolver& resolver) {
+ DCHECK(priority.GetOrigin() < CascadeOrigin::kAnimation);
+ const CSSValue* value = ValueAt(match_result_, priority.GetPosition());
+ DCHECK(value);
+ value = Resolve(property, *value, resolver);
+ DCHECK(!value->IsVariableReferenceValue());
+ DCHECK(!value->IsPendingSubstitutionValue());
+ StyleBuilder::ApplyProperty(property, state_, *value);
}
-void StyleCascade::ReplaceValue(const CSSPropertyName& name,
- const CSSValue* value) {
- auto iter = cascade_.find(name);
- if (iter != cascade_.end())
- iter->value = Value(value, iter->value.GetPriority());
+void StyleCascade::LookupAndApplyInterpolation(const CSSProperty& property,
+ CascadePriority priority,
+ CascadeResolver& resolver) {
+ // Interpolations for -internal-visited properties are applied via the
+ // interpolation for the main (unvisited) property, so we don't need to
+ // apply it twice.
+ // TODO(crbug.com/1062217): Interpolate visited colors separately
+ if (property.IsVisited())
+ return;
+ DCHECK(priority.GetOrigin() >= CascadeOrigin::kAnimation);
+ size_t index = DecodeInterpolationIndex(priority.GetPosition());
+ DCHECK_LE(index, interpolations_.GetEntries().size());
+ const ActiveInterpolationsMap& map = *interpolations_.GetEntries()[index].map;
+ PropertyHandle handle = ToPropertyHandle(property, priority);
+ const auto& entry = map.find(handle);
+ DCHECK_NE(entry, map.end());
+ ApplyInterpolation(property, priority, entry->value, resolver);
}
bool StyleCascade::IsRootElement() const {
@@ -274,7 +493,7 @@ StyleCascade::TokenSequence::BuildVariableData() {
const CSSValue* StyleCascade::Resolve(const CSSProperty& property,
const CSSValue& value,
- Resolver& resolver) {
+ CascadeResolver& resolver) {
if (const auto* v = DynamicTo<CSSCustomPropertyDeclaration>(value))
return ResolveCustomProperty(property, *v, resolver);
if (const auto* v = DynamicTo<CSSVariableReferenceValue>(value))
@@ -287,9 +506,9 @@ const CSSValue* StyleCascade::Resolve(const CSSProperty& property,
const CSSValue* StyleCascade::ResolveCustomProperty(
const CSSProperty& property,
const CSSCustomPropertyDeclaration& decl,
- Resolver& resolver) {
+ CascadeResolver& resolver) {
DCHECK(!resolver.IsLocked(property));
- AutoLock lock(property, resolver);
+ CascadeResolver::AutoLock lock(property, resolver);
// TODO(andruud): Don't transport css-wide keywords in this value.
if (!decl.Value())
@@ -306,15 +525,8 @@ const CSSValue* StyleCascade::ResolveCustomProperty(
if (resolver.InCycle())
return CSSInvalidVariableValue::Create();
- if (!data) {
- // TODO(crbug.com/980930): Treat custom properties as unset here,
- // not invalid. This behavior is enforced by WPT, but violates the spec.
- if (const auto* custom_property = DynamicTo<CustomProperty>(property)) {
- if (!custom_property->IsRegistered())
- return CSSInvalidVariableValue::Create();
- }
+ if (!data)
return cssvalue::CSSUnsetValue::Create();
- }
if (data == decl.Value())
return &decl;
@@ -326,13 +538,15 @@ const CSSValue* StyleCascade::ResolveCustomProperty(
const CSSValue* StyleCascade::ResolveVariableReference(
const CSSProperty& property,
const CSSVariableReferenceValue& value,
- Resolver& resolver) {
+ CascadeResolver& resolver) {
DCHECK(!resolver.IsLocked(property));
- AutoLock lock(property, resolver);
+ CascadeResolver::AutoLock lock(property, resolver);
const CSSVariableData* data = value.VariableDataValue();
const CSSParserContext* context = GetParserContext(value);
+ MarkHasVariableReference(property);
+
DCHECK(data);
DCHECK(context);
@@ -349,31 +563,46 @@ const CSSValue* StyleCascade::ResolveVariableReference(
const CSSValue* StyleCascade::ResolvePendingSubstitution(
const CSSProperty& property,
const cssvalue::CSSPendingSubstitutionValue& value,
- Resolver& resolver) {
+ CascadeResolver& resolver) {
DCHECK(!resolver.IsLocked(property));
- AutoLock lock(property, resolver);
+ CascadeResolver::AutoLock lock(property, resolver);
+ CascadePriority priority = map_.At(property.GetCSSPropertyName());
DCHECK_NE(property.PropertyID(), CSSPropertyID::kVariable);
+ DCHECK_NE(priority.GetOrigin(), CascadeOrigin::kNone);
- CSSVariableReferenceValue* shorthand_value = value.ShorthandValue();
- const auto* shorthand_data = shorthand_value->VariableDataValue();
- CSSPropertyID shorthand_property_id = value.ShorthandPropertyId();
+ MarkHasVariableReference(property);
- TokenSequence sequence;
+ // If the previous call to ResolvePendingSubstitution parsed 'value', then
+ // we don't need to do it again.
+ bool is_cached = resolver.shorthand_cache_.value == &value;
- if (!ResolveTokensInto(shorthand_data->Tokens(), resolver, sequence))
- return cssvalue::CSSUnsetValue::Create();
+ if (!is_cached) {
+ CSSVariableReferenceValue* shorthand_value = value.ShorthandValue();
+ const auto* shorthand_data = shorthand_value->VariableDataValue();
+ CSSPropertyID shorthand_property_id = value.ShorthandPropertyId();
- HeapVector<CSSPropertyValue, 256> parsed_properties;
- const bool important = false;
+ TokenSequence sequence;
- if (!CSSPropertyParser::ParseValue(
- shorthand_property_id, important, sequence.TokenRange(),
- shorthand_value->ParserContext(), parsed_properties,
- StyleRule::RuleType::kStyle)) {
- return cssvalue::CSSUnsetValue::Create();
+ if (!ResolveTokensInto(shorthand_data->Tokens(), resolver, sequence))
+ return cssvalue::CSSUnsetValue::Create();
+
+ HeapVector<CSSPropertyValue, 256> parsed_properties;
+ const bool important = false;
+
+ if (!CSSPropertyParser::ParseValue(
+ shorthand_property_id, important, sequence.TokenRange(),
+ shorthand_value->ParserContext(), parsed_properties,
+ StyleRule::RuleType::kStyle)) {
+ return cssvalue::CSSUnsetValue::Create();
+ }
+
+ resolver.shorthand_cache_.value = &value;
+ resolver.shorthand_cache_.parsed_properties = std::move(parsed_properties);
}
+ const auto& parsed_properties = resolver.shorthand_cache_.parsed_properties;
+
// For -internal-visited-properties with CSSPendingSubstitutionValues,
// the inner 'shorthand_property_id' will expand to a set of longhands
// containing the unvisited equivalent. Hence, when parsing the
@@ -382,27 +611,22 @@ const CSSValue* StyleCascade::ResolvePendingSubstitution(
const CSSProperty* unvisited_property =
property.IsVisited() ? property.GetUnvisitedProperty() : &property;
- const CSSValue* result = nullptr;
-
unsigned parsed_properties_count = parsed_properties.size();
for (unsigned i = 0; i < parsed_properties_count; ++i) {
const CSSProperty& longhand = CSSProperty::Get(parsed_properties[i].Id());
- const CSSPropertyName& name = longhand.GetCSSPropertyName();
const CSSValue* parsed = parsed_properties[i].Value();
if (unvisited_property == &longhand)
- result = parsed;
- else if (HasValue(name, &value))
- ReplaceValue(name, parsed);
+ return parsed;
}
- DCHECK(result);
- return result;
+ NOTREACHED();
+ return cssvalue::CSSUnsetValue::Create();
}
scoped_refptr<CSSVariableData> StyleCascade::ResolveVariableData(
CSSVariableData* data,
- Resolver& resolver) {
+ CascadeResolver& resolver) {
DCHECK(data && data->NeedsVariableResolution());
TokenSequence sequence(data);
@@ -414,7 +638,7 @@ scoped_refptr<CSSVariableData> StyleCascade::ResolveVariableData(
}
bool StyleCascade::ResolveTokensInto(CSSParserTokenRange range,
- Resolver& resolver,
+ CascadeResolver& resolver,
TokenSequence& out) {
bool success = true;
while (!range.AtEnd()) {
@@ -430,7 +654,7 @@ bool StyleCascade::ResolveTokensInto(CSSParserTokenRange range,
}
bool StyleCascade::ResolveVarInto(CSSParserTokenRange range,
- Resolver& resolver,
+ CascadeResolver& resolver,
TokenSequence& out) {
AtomicString variable_name = ConsumeVariableName(range);
DCHECK(range.AtEnd() || (range.Peek().GetType() == kCommaToken));
@@ -440,7 +664,7 @@ 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.
- MarkReferenced(property);
+ MarkIsReferenced(property);
if (!resolver.DetectCycle(property)) {
// We are about to substitute var(property). In order to do that, we must
@@ -449,7 +673,7 @@ bool StyleCascade::ResolveVarInto(CSSParserTokenRange range,
// We can however not do this if we're in a cycle. If a cycle is detected
// here, it means we are already resolving 'property', and have discovered
// a reference to 'property' during that resolution.
- Apply(property, resolver);
+ LookupAndApply(property, resolver);
}
// Note that even if we are in a cycle, we must proceed in order to discover
@@ -492,7 +716,7 @@ bool StyleCascade::ResolveVarInto(CSSParserTokenRange range,
}
bool StyleCascade::ResolveEnvInto(CSSParserTokenRange range,
- Resolver& resolver,
+ CascadeResolver& resolver,
TokenSequence& out) {
AtomicString variable_name = ConsumeVariableName(range);
DCHECK(range.AtEnd() || (range.Peek().GetType() == kCommaToken));
@@ -561,87 +785,70 @@ bool StyleCascade::ValidateFallback(const CustomProperty& property,
return property.ParseSingleValue(range, *context, local_context);
}
-void StyleCascade::MarkReferenced(const CustomProperty& property) {
- if (!property.IsInherited())
- state_.Style()->SetHasVariableReferenceFromNonInheritedProperty();
+void StyleCascade::MarkIsReferenced(const CustomProperty& property) {
if (!property.IsRegistered())
return;
const AtomicString& name = property.GetPropertyNameAtomicString();
state_.GetDocument().GetPropertyRegistry()->MarkReferenced(name);
}
-bool StyleCascade::Filter::Add(const CSSProperty& property,
- const Value& value) {
- Priority& slot = GetSlot(property);
- if (value.GetPriority() >= slot) {
- slot = value.GetPriority();
- return true;
- }
- return false;
-}
-
-StyleCascade::Priority& StyleCascade::Filter::GetSlot(
- const CSSProperty& property) {
- // TODO(crbug.com/985043): Ribbonize?
- switch (property.PropertyID()) {
- case CSSPropertyID::kWritingMode:
- case CSSPropertyID::kWebkitWritingMode:
- return writing_mode_;
- case CSSPropertyID::kZoom:
- case CSSPropertyID::kInternalEffectiveZoom:
- return zoom_;
- default:
- none_ = Priority();
- return none_;
- }
-}
-
-bool StyleCascade::Resolver::IsLocked(const CSSProperty& property) const {
- return IsLocked(property.GetCSSPropertyName());
-}
-
-bool StyleCascade::Resolver::IsLocked(const CSSPropertyName& name) const {
- return stack_.Contains(name);
-}
-
-bool StyleCascade::Resolver::AllowSubstitution(CSSVariableData* data) const {
- if (data && data->IsAnimationTainted() && stack_.size()) {
- const CSSPropertyName& name = stack_.back();
- if (name.IsCustomProperty())
- return true;
- const CSSProperty& property = CSSProperty::Get(name.Id());
- return !CSSAnimations::IsAnimationAffectingProperty(property);
- }
- return true;
-}
-
-bool StyleCascade::Resolver::DetectCycle(const CSSProperty& property) {
- wtf_size_t index = stack_.Find(property.GetCSSPropertyName());
- if (index == kNotFound)
- return false;
- cycle_depth_ = std::min(cycle_depth_, index);
- return true;
-}
-
-bool StyleCascade::Resolver::InCycle() const {
- return cycle_depth_ != kNotFound;
-}
-
-StyleCascade::AutoLock::AutoLock(const CSSProperty& property,
- Resolver& resolver)
- : AutoLock(property.GetCSSPropertyName(), resolver) {}
-
-StyleCascade::AutoLock::AutoLock(const CSSPropertyName& name,
- Resolver& resolver)
- : resolver_(resolver) {
- DCHECK(!resolver.IsLocked(name));
- resolver_.stack_.push_back(name);
+void StyleCascade::MarkHasVariableReference(const CSSProperty& property) {
+ if (!property.IsInherited())
+ state_.Style()->SetHasVariableReferenceFromNonInheritedProperty();
}
-StyleCascade::AutoLock::~AutoLock() {
- resolver_.stack_.pop_back();
- if (resolver_.stack_.size() <= resolver_.cycle_depth_)
- resolver_.cycle_depth_ = kNotFound;
+const Document& StyleCascade::GetDocument() const {
+ return state_.GetDocument();
+}
+
+const CSSProperty& StyleCascade::SurrogateFor(
+ const CSSProperty& surrogate) const {
+ DCHECK(surrogate.IsSurrogate());
+ const CSSProperty* original = surrogate.SurrogateFor(
+ state_.Style()->Direction(), state_.Style()->GetWritingMode());
+ DCHECK(original);
+ return *original;
+}
+
+bool StyleCascade::HasAuthorDeclaration(const CSSProperty& property) const {
+ return map_.At(property.GetCSSPropertyName()).GetOrigin() ==
+ CascadeOrigin::kAuthor;
+}
+
+bool StyleCascade::HasAuthorBorder() const {
+ return HasAuthorDeclaration(GetCSSPropertyBorderBottomColor()) ||
+ HasAuthorDeclaration(GetCSSPropertyBorderBottomLeftRadius()) ||
+ HasAuthorDeclaration(GetCSSPropertyBorderBottomRightRadius()) ||
+ HasAuthorDeclaration(GetCSSPropertyBorderBottomStyle()) ||
+ HasAuthorDeclaration(GetCSSPropertyBorderBottomWidth()) ||
+ HasAuthorDeclaration(GetCSSPropertyBorderImageOutset()) ||
+ HasAuthorDeclaration(GetCSSPropertyBorderImageRepeat()) ||
+ HasAuthorDeclaration(GetCSSPropertyBorderImageSlice()) ||
+ HasAuthorDeclaration(GetCSSPropertyBorderImageSource()) ||
+ HasAuthorDeclaration(GetCSSPropertyBorderImageWidth()) ||
+ HasAuthorDeclaration(GetCSSPropertyBorderLeftColor()) ||
+ HasAuthorDeclaration(GetCSSPropertyBorderLeftStyle()) ||
+ HasAuthorDeclaration(GetCSSPropertyBorderLeftWidth()) ||
+ HasAuthorDeclaration(GetCSSPropertyBorderRightColor()) ||
+ HasAuthorDeclaration(GetCSSPropertyBorderRightStyle()) ||
+ HasAuthorDeclaration(GetCSSPropertyBorderRightWidth()) ||
+ HasAuthorDeclaration(GetCSSPropertyBorderTopColor()) ||
+ HasAuthorDeclaration(GetCSSPropertyBorderTopLeftRadius()) ||
+ HasAuthorDeclaration(GetCSSPropertyBorderTopRightRadius()) ||
+ HasAuthorDeclaration(GetCSSPropertyBorderTopStyle()) ||
+ HasAuthorDeclaration(GetCSSPropertyBorderTopWidth());
+}
+
+bool StyleCascade::HasAuthorBackground() const {
+ return HasAuthorDeclaration(GetCSSPropertyBackgroundAttachment()) ||
+ HasAuthorDeclaration(GetCSSPropertyBackgroundBlendMode()) ||
+ HasAuthorDeclaration(GetCSSPropertyBackgroundClip()) ||
+ HasAuthorDeclaration(GetCSSPropertyBackgroundColor()) ||
+ HasAuthorDeclaration(GetCSSPropertyBackgroundImage()) ||
+ HasAuthorDeclaration(GetCSSPropertyBackgroundOrigin()) ||
+ HasAuthorDeclaration(GetCSSPropertyBackgroundPositionX()) ||
+ HasAuthorDeclaration(GetCSSPropertyBackgroundPositionY()) ||
+ HasAuthorDeclaration(GetCSSPropertyBackgroundSize());
}
} // namespace blink
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 d6cbce28d14..5b4fe46d901 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
@@ -5,15 +5,27 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_STYLE_CASCADE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_STYLE_CASCADE_H_
+#include "third_party/blink/renderer/core/animation/interpolation.h"
+#include "third_party/blink/renderer/core/css/css_property_id_templates.h"
#include "third_party/blink/renderer/core/css/css_property_name.h"
+#include "third_party/blink/renderer/core/css/css_property_value.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/properties/css_property.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_filter.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_interpolations.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_map.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_origin.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_priority.h"
+#include "third_party/blink/renderer/core/css/resolver/match_result.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/text/text_encoding.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
+class CascadeInterpolations;
+class CascadeResolver;
class CSSCustomPropertyDeclaration;
class CSSParserContext;
class CSSProperty;
@@ -21,335 +33,76 @@ class CSSValue;
class CSSVariableData;
class CSSVariableReferenceValue;
class CustomProperty;
+class MatchResult;
class StyleResolverState;
namespace cssvalue {
class CSSPendingSubstitutionValue;
-class CSSPendingInterpolationValue;
} // namespace cssvalue
-// The StyleCascade is responsible for managing cascaded values [1], resolving
-// dependencies between them, and applying the values to the ComputedStyle.
+// StyleCascade analyzes declarations provided by CSS rules and animations,
+// and figures out which declarations should be skipped, and which should be
+// applied (and in which order).
//
-// Its usage pattern is:
-//
-// const CSSPropertyName& name = ...;
-// const CSSValue* value1 = ...;
-// const CSSValue* value2 = ...;
+// Usage:
//
// StyleCascade cascade(state);
-// cascade.Add(name, value1, Priority(Origin::kAuthor));
-// cascade.Add(name, value2, Priority(Origin::kUA));
-// cascade.Apply(); // value1 is applied, value2 is ignored.
+// cascade.MutableMatchResult().AddMatchedProperties(...matched rule...);
+// cascade.MutableMatchResult().AddMatchedProperties(...another rule...);
+// cascade.AddInterpolation(...); // Optional
+// cascade.Apply();
//
// [1] https://drafts.csswg.org/css-cascade/#cascade
class CORE_EXPORT StyleCascade {
STACK_ALLOCATED();
using CSSPendingSubstitutionValue = cssvalue::CSSPendingSubstitutionValue;
- using CSSPendingInterpolationValue = cssvalue::CSSPendingInterpolationValue;
public:
- class Animator;
- class Resolver;
- class AutoLock;
-
StyleCascade(StyleResolverState& state) : state_(state) {}
- static constexpr uint16_t kMaxCascadeOrder = ~static_cast<uint16_t>(0);
-
- // Represents the origin and importance criteria described by css-cascade [1].
- //
- // Higher values are more significant than lower values. The values are
- // chosen such that an important origin can be produced by inverting the bits
- // of the corresponding non-important origin.
- //
- // [1] https://www.w3.org/TR/css-cascade-3/#cascade-origin
- enum class Origin : uint8_t {
- kNone = 0,
- kUserAgent = 0b0001,
- kUser = 0b0010,
- kAuthor = 0b0011,
- kAnimation = 0b0100,
- kImportantAuthor = 0b1100,
- kImportantUser = 0b1101,
- kImportantUserAgent = 0b1110,
- kTransition = 0b10000,
- };
-
- // All important Origins (and only those) must have this bit set. This
- // provides a fast way to check if an Origin is important.
- static constexpr uint8_t kImportantBit = 0b1000;
+ const MatchResult& GetMatchResult() { return match_result_; }
- // The Priority class encapsulates a subset of the cascading criteria
- // described by css-cascade [1], and provides a way to compare priorities.
- //
- // It encompasses, from most significant to least significant: Origin (which
- // includes importance); tree order, which is a number representing the
- // shadow-including tree order [2]; and finally cascade order, which is
- // a monotonically increasing number increased by one every time something
- // is added to the cascade.
+ // Access the MatchResult in order to add declarations to it.
+ // The modifications made will be taken into account during the next call to
+ // Apply.
//
- // The cascade order is initially kMaxCascadeOrder for an instance of
- // Priority; an actual value will be assigned by StyleCascade::Add.
- //
- // [1] https://drafts.csswg.org/css-cascade/#cascading
- // [2] https://drafts.csswg.org/css-scoping/#shadow-cascading
- class CORE_EXPORT Priority {
- DISALLOW_NEW();
-
- public:
- Priority() : Priority(Origin::kNone) {}
- // Deliberately implicit.
- Priority(Origin origin) : Priority(origin, 0) {}
- // For an explanation of 'tree_order', see css-scoping [1].
- // [1] https://drafts.csswg.org/css-scoping/#shadow-cascading
- Priority(Origin, uint16_t tree_order);
-
- Origin GetOrigin() const;
- bool HasOrigin() const { return GetOrigin() != Origin::kNone; }
-
- // This function is used to determine if an incoming Value should win
- // over the Value which already exists in the cascade.
- bool operator>=(const Priority&) const;
-
- // Returns a copy of this Priority, except that the non-important origin
- // has been converted to its important counterpart.
- //
- // Must be used with kUserAgent, kAuthor, and kAuthor only, as importance
- // does not apply to the other origins.
- //
- // https://drafts.csswg.org/css-cascade/#important
- inline Priority AddImportance() const {
- DCHECK_GE(GetOrigin(), Origin::kUserAgent);
- DCHECK_LE(GetOrigin(), Origin::kAuthor);
- // Flip Origin bits, converting non-important to important. We only
- // xor four bits here, because only those bits are in use by
- // k[Important,][User,UserAgent,Author].
- return Priority(priority_ ^ (static_cast<uint64_t>(0b1111) << 32));
- }
-
- private:
- friend class StyleCascade;
- friend class StyleCascadeTest;
-
- Priority(uint64_t priority) : priority_(priority) {}
-
- // Returns a copy of this Priority, with the cascade order set to the
- // specified value.
- //
- // For the purposes of StyleCascade::Add alone, we don't need to store the
- // cascade order at all, since the cascade order is implicit in the order
- // of the calls to ::Add. However, some properties unfortunately require
- // that we store the cascade order and act upon it Apply-time. This is
- // because we have multiple properties that mutate the same field on
- // ComputedStyle, hence the relative ordering must be preserved between
- // them to know which should be applied. (See class Filter).
- inline Priority WithCascadeOrder(uint16_t cascade_order) const {
- return Priority((priority_ & ~0xFFFF) | cascade_order);
- }
-
- // To make Priority comparisons fast, the origin, tree_order and
- // cascade_order are stored in a single uint64_t, as follows:
- //
- // Bit 0-15: cascade_order
- // Bit 16-31: tree_order
- // Bit 32-39: Origin
- //
- // This way, the numeric value of priority_ can be compared directly
- // for all criteria simultaneously.
- uint64_t priority_;
- };
-
- // The Value class simply represents the data we store for each property
- // in the cascade. See StyleCascade::cascade_ field.
- class CORE_EXPORT Value {
- DISALLOW_NEW();
-
- public:
- // The empty Value is needed because we store it in a HashMap.
- Value() = default;
- Value(const CSSValue* value, Priority priority)
- : value_(value), priority_(priority) {}
- bool IsEmpty() const { return !priority_.HasOrigin(); }
- const CSSValue* GetValue() const { return value_; }
- const Priority& GetPriority() const { return priority_; }
- void Trace(blink::Visitor* visitor) { visitor->Trace(value_); }
+ // TODO(andruud): ElementRuleCollector could emit MatchedProperties
+ // directly to the cascade.
+ MatchResult& MutableMatchResult();
- private:
- Member<const CSSValue> value_;
- Priority priority_;
- };
-
- // Add a Value to the cascade. The Value will either become the cascaded
- // value, or be discarded, depending on the Priority of the incoming value
- // vs. the Priority of the existing value.
- void Add(const CSSPropertyName&, const CSSValue*, Priority);
-
- // Applies all values currently in the cascade to the ComputedStyle.
- // Any CSSPendingInterpolationValues present in the cascade will be ignored.
- void Apply();
- // Applies all values currently in the cascade to the ComputedStyle,
- // dispatching any CSSPendingInterpolationValues to the given Animator.
- void Apply(Animator&);
-
- // Removes all kAnimationPropertyPriority properties from the cascade,
- // without applying the properties. This is used when pre-emptively copying
- // the cascade in case there are animations.
+ // Add ActiveInterpolationsMap to the cascade. The interpolations present
+ // in the map will be taken into account during the next call to Apply.
//
- // TODO(crbug.com/985010): Improve with non-destructive Apply.
- void RemoveAnimationPriority();
+ // Note that it's assumed that the incoming ActiveInterpolationsMap outlives
+ // the StyleCascade object.
+ void AddInterpolations(const ActiveInterpolationsMap*, CascadeOrigin);
- // The Filter class is responsible for resolving situations where
- // we have multiple (non-alias) properties in the cascade that mutates the
- // same fields on ComputedStyle.
+ // Applies the current CSS declarations and animations to the
+ // StyleResolverState.
//
- // An example of this is writing-mode and -webkit-writing-mode, which
- // both result in ComputedStyle::SetWritingMode calls.
- //
- // When applying the cascade (applying each property/value pair to the
- // ComputedStyle), the order of the application is in the general case
- // not defined. (It is determined by the iteration order of the HashMap).
- // This means that if both writing-mode and -webkit-writing-mode exist in
- // the cascade, we would get non-deterministic behavior: the application order
- // would not be defined. To fix this, all Values pass through this Filter
- // before being applied.
-
- // The Filter stores the Priority of the Value that was previously applied
- // for a certain 'group' of properties (writing_mode_ is one such group).
- // When we're about to apply a Value, we only actually do so if the call to
- // Filter::Add succeeds. If the call to Filter::Add does not succeed, it means
- // that we have previously added a Value with higher Priority, and that the
- // current Value must be ignored.
-
- // A key difference between discarding Values in the Filter, vs. discarding
- // them cascade-time (StyleCascade::Add), is that we are taking the cascade
- // order into account. This means that, if everything else is equal (origin,
- // tree order), the Value that entered the cascade last wins. This is crucial
- // to resolve situations like writing-mode and -webkit-writing-mode.
-
- // The Filter is also expected to resolve similar difficulties with
- // direction-aware properties in the future, although this is not yet
- // implemented.
- class CORE_EXPORT Filter {
- STACK_ALLOCATED();
-
- public:
- // Attempts to add a given property/value to the Filter. If this returns
- // true, the Value may be applied to the ComputedStyle. If not, it means
- // that we have previously applied a Value with higher Priority, and the
- // current Value must be discarded.
- bool Add(const CSSProperty& property, const Value&);
-
- private:
- Priority& GetSlot(const CSSProperty&);
-
- Priority none_;
- Priority writing_mode_;
- Priority zoom_;
- };
-
- // Resolver is an object passed on a stack during Apply. Its most important
- // job is to detect cycles during Apply (in general, keep track of which
- // properties we're currently applying).
- class CORE_EXPORT Resolver {
- STACK_ALLOCATED();
-
- public:
- // TODO(crbug.com/985047): Probably use a HashMap for this.
- using NameStack = Vector<CSSPropertyName, 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;
-
- // We do not allow substitution of animation-tainted values into
- // an animation-affecting property.
- //
- // https://drafts.csswg.org/css-variables/#animation-tainted
- bool AllowSubstitution(CSSVariableData*) const;
-
- private:
- friend class AutoLock;
- friend class StyleCascade;
- friend class TestCascadeResolver;
-
- Resolver(Animator& animator) : animator_(animator) {}
- // If the given property is already being applied, returns true.
- // The return value is the same value you would get from InCycle(), and
- // is just returned for convenience.
- //
- // When a cycle has been detected, the Resolver will *persist the cycle
- // state* (i.e. InCycle() will continue to return true) until we reach
- // the start of the cycle.
- //
- // The cycle state is cleared by ~AutoLock, once we have moved far enough
- // up the stack.
- bool DetectCycle(const CSSProperty&);
- // Returns true whenever the Resolver is in a cycle state.
- // This DOES NOT detect cycles; the caller must call DetectCycle first.
- bool InCycle() const;
-
- NameStack stack_;
- Animator& animator_;
- wtf_size_t cycle_depth_ = kNotFound;
- Filter filter_;
- };
+ // It is valid to call Apply multiple times (up to 15), and each call may
+ // provide a different filter.
+ void Apply(CascadeFilter = CascadeFilter());
- // Automatically locks and unlocks the given property. (See
- // Resolver::IsLocked).
- class CORE_EXPORT AutoLock {
- STACK_ALLOCATED();
-
- public:
- AutoLock(const CSSProperty&, Resolver&);
- AutoLock(const CSSPropertyName&, Resolver&);
- ~AutoLock();
-
- private:
- Resolver& resolver_;
- };
-
- // Animator & CSSPendingInterpolationValue
- //
- // Blink's way of applying animations poses some difficulty for StyleCascade,
- // as much of the code that applies the animation effects completely bypasses
- // StyleBuilder; it sets the values on ComputedStyle directly. This prevents
- // those values from participating properly in the cascade.
- //
- // At the same time, we don't want to actually create CSSValues for the
- // animation effects, as this is (yet another?) unnecessary conversion, and
- // it produces unwanted GC pressure. To solve this problem, the cascading
- // and application aspects of interpolations are handled *separately*.
- //
- // CSSPendingInterpolationValue represents the cascading aspect of an
- // interpolation: this means that, once we know that an interpolation is
- // active for a given property, we add a CSSPendingInterpolationValue to the
- // cascade (with the appropriate Priority). Apply-time, we then ask the
- // Animator (see StyleAnimator) to actually apply the interpolated value
- // using the interpolation infrastructure.
- class CORE_EXPORT Animator {
- public:
- virtual void Apply(const CSSProperty&,
- const CSSPendingInterpolationValue&,
- Resolver&) = 0;
- };
+ // Resets the cascade to its initial state. Note that this does not undo
+ // any changes already applied to the StyleResolverState/ComputedStyle.
+ void Reset();
- // Applying a CSSPendingInterpolationValue may involve resolving values,
- // since we may be applying a keyframe from e.g. "color: var(--x)" to
- // "color: var(--y)". Hence that code needs an entry point to the resolving
- // process.
+ // Applying interpolations may involve resolving values, since we may be
+ // applying a keyframe from e.g. "color: var(--x)" to "color: var(--y)".
+ // Hence that code needs an entry point to the resolving process.
//
// TODO(crbug.com/985023): This function has an associated const
// violation, which isn't great. (This vilation was not introduced with
// StyleCascade, however).
//
// See documentation the other Resolve* functions for what resolve means.
- const CSSValue* Resolve(const CSSPropertyName&, const CSSValue&, Resolver&);
+ const CSSValue* Resolve(const CSSPropertyName&,
+ const CSSValue&,
+ CascadeResolver&);
private:
friend class TestCascade;
@@ -360,30 +113,67 @@ class CORE_EXPORT StyleCascade {
// https://drafts.csswg.org/css-variables/#long-variables
static const size_t kMaxSubstitutionTokens = 16384;
+ // Before we can Apply the cascade, the MatchResult and CascadeInterpolations
+ // must be Analyzed. This means going through all the declarations, and
+ // adding them to the CascadeMap, which gives us a complete picture of which
+ // declarations won the cascade.
+ //
+ // We analyze only if needed (i.e. if MatchResult or CascadeInterpolations)
+ // has been mutated since the last call to AnalyzeIfNeeded.
+ void AnalyzeIfNeeded();
+ void AnalyzeMatchResult();
+ void AnalyzeInterpolations();
+
// Applies kHighPropertyPriority properties.
//
// In theory, it would be possible for each property/value that contains
// em/ch/etc to dynamically apply font-size (and related properties), but
// in practice, it is very inconvenient to detect these dependencies. Hence,
// we apply font-affecting properties (among others) before all the others.
- void ApplyHighPriority(Resolver&);
+ void ApplyHighPriority(CascadeResolver&);
- // Apply a single property (including any dependencies).
- void Apply(const CSSPropertyName&);
- void Apply(const CSSPropertyName&, Resolver&);
- void Apply(const CSSProperty&, Resolver&);
+ // Applies -webkit-appearance, and excludes -internal-ua-* properties if
+ // we don't have an appearance.
+ void ApplyAppearance(CascadeResolver&);
- // True if the cascade currently holds the provided value for a given
- // property. Note that the value is compared by address.
- bool HasValue(const CSSPropertyName&, const CSSValue*) const;
-
- // Get current cascaded value for the specified property.
- const CSSValue* GetValue(const CSSPropertyName&) const;
-
- // If there is a cascaded value for the specified property, replace it
- // with the incoming value, maintaining the current cascade origin.
- // Has no effect if there is no cascaded value for the property.
- void ReplaceValue(const CSSPropertyName&, const CSSValue*);
+ // Applies -webkit-border-image (if present), and skips any border-image
+ // longhands found with lower priority than -webkit-border-image.
+ //
+ // The -webkit-border-image property is unique (in a bad way), since it's
+ // a surrogate of a shorthand. Therefore it needs special treatment to
+ // behave correctly.
+ void ApplyWebkitBorderImage(CascadeResolver&);
+
+ void ApplyMatchResult(CascadeResolver&);
+ void ApplyInterpolations(CascadeResolver&);
+ void ApplyInterpolationMap(const ActiveInterpolationsMap&,
+ CascadeOrigin,
+ size_t index,
+ CascadeResolver&);
+ void ApplyInterpolation(const CSSProperty&,
+ CascadePriority,
+ const ActiveInterpolations&,
+ CascadeResolver&);
+ // Surrogates (such as css-logical properties) require special handling, since
+ // both the surrogate and the original property exist in the cascade at the
+ // same time. For example, 'inline-size' and 'width' may both exist in the
+ // CascadeMap, and the winner must be determined Apply-time, since we don't
+ // know which physical property 'inline-size' corresponds to before
+ // 'writing-mode' and 'direction' have been applied.
+ void ApplySurrogate(const CSSProperty&, CascadePriority, CascadeResolver&);
+
+ // Looks up a value with random access, and applies it.
+ void LookupAndApply(const CSSPropertyName&, CascadeResolver&);
+ void LookupAndApply(const CSSProperty&, CascadeResolver&);
+ void LookupAndApplyValue(const CSSProperty&,
+ CascadePriority,
+ CascadeResolver&);
+ void LookupAndApplyDeclaration(const CSSProperty&,
+ CascadePriority,
+ CascadeResolver&);
+ void LookupAndApplyInterpolation(const CSSProperty&,
+ CascadePriority,
+ CascadeResolver&);
// Whether or not we are calculating the style for the root element.
// We need to know this to detect cycles with 'rem' units.
@@ -453,19 +243,21 @@ class CORE_EXPORT StyleCascade {
// other words, we must first Apply '--y'. Hence, resolving 'width' will
// Apply '--y' as a side-effect. (This process would then continue to '--x').
- const CSSValue* Resolve(const CSSProperty&, const CSSValue&, Resolver&);
+ const CSSValue* Resolve(const CSSProperty&,
+ const CSSValue&,
+ CascadeResolver&);
const CSSValue* ResolveCustomProperty(const CSSProperty&,
const CSSCustomPropertyDeclaration&,
- Resolver&);
+ CascadeResolver&);
const CSSValue* ResolveVariableReference(const CSSProperty&,
const CSSVariableReferenceValue&,
- Resolver&);
+ CascadeResolver&);
const CSSValue* ResolvePendingSubstitution(const CSSProperty&,
const CSSPendingSubstitutionValue&,
- Resolver&);
+ CascadeResolver&);
scoped_refptr<CSSVariableData> ResolveVariableData(CSSVariableData*,
- Resolver&);
+ CascadeResolver&);
// The Resolve*Into functions either resolve dependencies, append to the
// TokenSequence accordingly, and return true; or it returns false when
@@ -475,9 +267,9 @@ class CORE_EXPORT StyleCascade {
//
// [1] https://drafts.csswg.org/css-variables/#invalid-at-computed-value-time
- bool ResolveTokensInto(CSSParserTokenRange, Resolver&, TokenSequence&);
- bool ResolveVarInto(CSSParserTokenRange, Resolver&, TokenSequence&);
- bool ResolveEnvInto(CSSParserTokenRange, Resolver&, TokenSequence&);
+ bool ResolveTokensInto(CSSParserTokenRange, CascadeResolver&, TokenSequence&);
+ bool ResolveVarInto(CSSParserTokenRange, CascadeResolver&, TokenSequence&);
+ bool ResolveEnvInto(CSSParserTokenRange, CascadeResolver&, TokenSequence&);
CSSVariableData* GetVariableData(const CustomProperty&) const;
CSSVariableData* GetEnvironmentVariable(const AtomicString&) const;
@@ -494,13 +286,66 @@ class CORE_EXPORT StyleCascade {
// https://drafts.css-houdini.org/css-properties-values-api-1/#fallbacks-in-var-references
bool ValidateFallback(const CustomProperty&, CSSParserTokenRange) const;
// Marks the CustomProperty as referenced by something. Needed to avoid
- // animating these custom properties on the compositor, and to disable the
- // matched properties cache in some cases.
- void MarkReferenced(const CustomProperty&);
+ // animating these custom properties on the compositor.
+ void MarkIsReferenced(const CustomProperty&);
+ // 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&);
+
+ const Document& GetDocument() const;
+ const CSSProperty& SurrogateFor(const CSSProperty& surrogate) const;
+
+ bool HasAuthorDeclaration(const CSSProperty&) const;
+ bool HasAuthorBorder() const;
+ bool HasAuthorBackground() const;
StyleResolverState& state_;
- HeapHashMap<CSSPropertyName, Value> cascade_;
- uint16_t order_ = 0;
+ MatchResult match_result_;
+ CascadeInterpolations interpolations_;
+ CascadeMap map_;
+ // Generational Apply
+ //
+ // Generation is a number that's incremented by one for each call to Apply
+ // (the first call to Apply has generation 1). When a declaration is applied
+ // to ComputedStyle, the current Apply-generation is stored in the CascadeMap.
+ // In other words, the CascadeMap knows which declarations have already been
+ // applied to ComputedStyle, which makes it possible to avoid applying the
+ // same declaration twice during a single call to Apply:
+ //
+ // For example:
+ //
+ // --x: red;
+ // background-color: var(--x);
+ //
+ // During Apply (generation=1), we linearly traverse the declarations above,
+ // and first apply '--x' to the ComputedStyle. Then, we proceed to
+ // 'background-color', which must first have its dependencies resolved before
+ // we can apply it. This is where we check the current generation stored for
+ // '--x'. If it's equal to the generation associated with the Apply call, we
+ // know that we already applied it. Either something else referenced it before
+ // we did, or it appeared before us in the MatchResult. Either way, we don't
+ // have to apply '--x' again.
+ //
+ // Had the order been reversed, such that the '--x' declaration appeared after
+ // the 'background-color' declaration, we would discover (during resolution of
+ // var(--x), that the current generation of '--x' is _less_ than the
+ // generation associated with the Apply call, hence we need to LookupAndApply
+ // '--x' before applying 'background-color'.
+ //
+ // A secondary benefit to the generational apply mechanic, is that it's
+ // possible to efficiently apply the StyleCascade more than once (perhaps with
+ // a different CascadeFilter for each call), without rebuilding it. By
+ // incrementing generation_, the existing record of what has been applied is
+ // immediately invalidated, and everything will be applied again.
+ //
+ // Note: The maximum generation number is currently 15. This is more than
+ // enough for our needs.
+ uint8_t generation_ = 0;
+
+ bool needs_match_result_analyze_ = false;
+ bool needs_interpolations_analyze_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(StyleCascade);
};
} // namespace blink
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 d72f04ff789..87269c3ba0d 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
@@ -6,13 +6,12 @@
#include <vector>
+#include "third_party/blink/renderer/bindings/core/v8/v8_css_style_sheet_init.h"
#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_pending_interpolation_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_style_sheet_init.h"
#include "third_party/blink/renderer/core/css/css_test_helpers.h"
#include "third_party/blink/renderer/core/css/css_variable_reference_value.h"
#include "third_party/blink/renderer/core/css/document_style_environment_variables.h"
@@ -27,8 +26,12 @@
#include "third_party/blink/renderer/core/css/properties/css_property_ref.h"
#include "third_party/blink/renderer/core/css/properties/longhands/custom_property.h"
#include "third_party/blink/renderer/core/css/property_registry.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_filter.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_interpolations.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_map.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_priority.h"
+#include "third_party/blink/renderer/core/css/resolver/cascade_resolver.h"
#include "third_party/blink/renderer/core/css/resolver/scoped_style_resolver.h"
-#include "third_party/blink/renderer/core/css/resolver/style_animator.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
#include "third_party/blink/renderer/core/css/style_engine.h"
#include "third_party/blink/renderer/core/css/style_sheet_contents.h"
@@ -41,14 +44,12 @@
namespace blink {
+using css_test_helpers::ParseDeclarationBlock;
using css_test_helpers::RegisterProperty;
-using cssvalue::CSSPendingInterpolationValue;
-using Origin = StyleCascade::Origin;
-using Priority = StyleCascade::Priority;
+using Origin = CascadeOrigin;
+using Priority = CascadePriority;
using UnitType = CSSPrimitiveValue::UnitType;
-enum class AnimationTainted { kYes, kNo };
-
class TestCascade {
STACK_ALLOCATED();
@@ -67,72 +68,33 @@ class TestCascade {
state_.StyleRef().InheritFrom(*parent);
}
- void Add(String name,
- String value,
- Priority priority = Origin::kAuthor,
- AnimationTainted animation_tainted = AnimationTainted::kNo) {
- return Add(*CSSPropertyName::From(name), value, priority,
- animation_tainted);
- }
-
- void Add(const CSSPropertyName& name,
- String value,
- Priority priority = Origin::kAuthor,
- AnimationTainted animation_tainted = AnimationTainted::kNo) {
- HeapVector<CSSPropertyValue, 256> values =
- ParseValues(name, value, animation_tainted);
+ // Note that because of how MatchResult works, declarations must be added
+ // in "origin order", i.e. UserAgent first, then User, then Author.
- for (const CSSPropertyValue& v : values)
- Add(v.Name(), v.Value(), priority);
+ void Add(String block,
+ CascadeOrigin origin = CascadeOrigin::kAuthor,
+ unsigned link_match_type = CSSSelector::kMatchAll) {
+ CSSParserMode mode =
+ origin == CascadeOrigin::kUserAgent ? kUASheetMode : kHTMLStandardMode;
+ Add(ParseDeclarationBlock(block, mode), origin, link_match_type);
}
- void Add(String name,
- const CSSValue* value,
- Priority priority = Origin::kAuthor) {
- Add(*CSSPropertyName::From(name), value, priority);
+ void Add(String name, String value, CascadeOrigin origin = Origin::kAuthor) {
+ Add(name + ":" + value, origin);
}
- void Add(const CSSPropertyName& name,
- const CSSValue* value,
- Priority priority = Origin::kAuthor) {
- DCHECK(CSSPropertyRef(name, GetDocument()).GetProperty().IsLonghand());
- cascade_.Add(name, value, priority);
+ void Add(const CSSPropertyValueSet* set,
+ CascadeOrigin origin = CascadeOrigin::kAuthor,
+ unsigned link_match_type = CSSSelector::kMatchAll) {
+ DCHECK_LE(origin, CascadeOrigin::kAuthor) << "Animations not supported";
+ DCHECK_LE(current_origin_, origin) << "Please add declarations in order";
+ EnsureAtLeast(origin);
+ cascade_.MutableMatchResult().AddMatchedProperties(set, link_match_type);
}
- void Apply(const CSSPropertyName& name) { cascade_.Apply(name); }
- void Apply(String name) { Apply(*CSSPropertyName::From(name)); }
- void Apply() { cascade_.Apply(); }
- void Apply(StyleCascade::Animator& animator) { cascade_.Apply(animator); }
-
- HeapVector<CSSPropertyValue, 256> ParseValues(
- const CSSPropertyName& name,
- String value,
- AnimationTainted animation_tainted) {
- CSSTokenizer tokenizer(value);
- auto tokens = tokenizer.TokenizeToEOF();
- auto* context = MakeGarbageCollected<CSSParserContext>(GetDocument());
- context->SetMode(kUASheetMode); // Allows -internal variables.
-
- HeapVector<CSSPropertyValue, 256> parsed_properties;
-
- bool is_animation_tainted = animation_tainted == AnimationTainted::kYes;
- if (name.Id() == CSSPropertyID::kVariable) {
- // TODO(andruud): Make CSSPropertyParser::ParseValue handle custom props.
- const CSSValue* decl = CSSVariableParser::ParseDeclarationValue(
- name.ToAtomicString(), tokens, is_animation_tainted, *context);
- DCHECK(decl);
- parsed_properties.emplace_back(GetCSSPropertyVariable(), *decl);
- return parsed_properties;
- }
-
- const bool important = false;
-
- bool ok = CSSPropertyParser::ParseValue(name.Id(), important, tokens,
- context, parsed_properties,
- StyleRule::RuleType::kStyle);
- DCHECK(ok);
-
- return parsed_properties;
+ void Apply(CascadeFilter filter = CascadeFilter()) {
+ EnsureAtLeast(CascadeOrigin::kAuthor);
+ cascade_.Apply(filter);
}
String ComputedValue(String name) const {
@@ -145,77 +107,37 @@ class TestCascade {
return value ? value->CssText() : g_null_atom;
}
- bool HasValue(String name, const CSSValue* value) {
- return cascade_.HasValue(*CSSPropertyName::From(name), value);
+ CascadePriority GetPriority(String name) {
+ return GetPriority(
+ *CSSPropertyName::From(GetDocument().GetExecutionContext(), name));
}
- const CSSValue* GetCSSValue(String name) {
- return cascade_.GetValue(*CSSPropertyName::From(name));
+ CascadePriority GetPriority(CSSPropertyName name) {
+ CascadePriority* c = cascade_.map_.Find(name);
+ return c ? *c : CascadePriority();
}
- const String GetValue(String name) {
- const CSSValue* value = GetCSSValue(name);
- // Per spec, CSSPendingSubstitutionValue serializes as an empty string,
- // but for testing purposes it's nice to see the actual value.
- if (const auto* v = DynamicTo<cssvalue::CSSPendingSubstitutionValue>(value))
- return v->ShorthandValue()->CssText();
- if (DynamicTo<CSSPendingInterpolationValue>(value))
- return "<interpolation>";
- return value ? value->CssText() : g_null_atom;
- }
+ CascadeOrigin GetOrigin(String name) { return GetPriority(name).GetOrigin(); }
- CSSAnimationUpdate& CalculateTransitionUpdate() {
+ void CalculateTransitionUpdate() {
CSSAnimations::CalculateTransitionUpdate(
state_.AnimationUpdate(), CSSAnimations::PropertyPass::kCustom,
&state_.GetElement(), *state_.Style());
CSSAnimations::CalculateTransitionUpdate(
state_.AnimationUpdate(), CSSAnimations::PropertyPass::kStandard,
&state_.GetElement(), *state_.Style());
- return state_.AnimationUpdate();
+ AddTransitions();
}
- CSSAnimationUpdate& CalculateAnimationUpdate() {
+ void CalculateAnimationUpdate() {
CSSAnimations::CalculateAnimationUpdate(
state_.AnimationUpdate(), &state_.GetElement(), state_.GetElement(),
*state_.Style(), state_.ParentStyle(),
&GetDocument().EnsureStyleResolver());
- return state_.AnimationUpdate();
- }
-
- void AddAnimations() {
- auto& update = CalculateAnimationUpdate();
- using Type = CSSPendingInterpolationValue::Type;
-
- for (const auto& entry : update.ActiveInterpolationsForCustomAnimations()) {
- auto name = entry.key.GetCSSPropertyName();
- auto* v = CSSPendingInterpolationValue::Create(Type::kCSSProperty);
- Add(name.ToAtomicString(), v);
- }
- for (const auto& entry :
- update.ActiveInterpolationsForStandardAnimations()) {
- auto name = entry.key.GetCSSPropertyName();
- auto* v = CSSPendingInterpolationValue::Create(Type::kCSSProperty);
- Add(name.ToAtomicString(), v);
- }
+ AddAnimations();
}
- void AddTransitions() {
- auto& update = CalculateTransitionUpdate();
- using Type = CSSPendingInterpolationValue::Type;
-
- for (const auto& entry :
- update.ActiveInterpolationsForCustomTransitions()) {
- auto name = entry.key.GetCSSPropertyName();
- auto* v = CSSPendingInterpolationValue::Create(Type::kCSSProperty);
- Add(name.ToAtomicString(), v);
- }
- for (const auto& entry :
- update.ActiveInterpolationsForStandardTransitions()) {
- auto name = entry.key.GetCSSPropertyName();
- auto* v = CSSPendingInterpolationValue::Create(Type::kCSSProperty);
- Add(name.ToAtomicString(), v);
- }
- }
+ void Reset() { cascade_.Reset(); }
private:
Document& GetDocument() const { return state_.GetDocument(); }
@@ -231,6 +153,53 @@ class TestCascade {
return StyleResolver::InitialStyleForElement(document);
}
+ void FinishOrigin() {
+ switch (current_origin_) {
+ case CascadeOrigin::kUserAgent:
+ cascade_.MutableMatchResult().FinishAddingUARules();
+ current_origin_ = CascadeOrigin::kUser;
+ break;
+ case CascadeOrigin::kUser:
+ cascade_.MutableMatchResult().FinishAddingUserRules();
+ current_origin_ = CascadeOrigin::kAuthor;
+ break;
+ case CascadeOrigin::kAuthor:
+ default:
+ NOTREACHED();
+ break;
+ }
+ }
+
+ void EnsureAtLeast(CascadeOrigin origin) {
+ while (current_origin_ < origin)
+ FinishOrigin();
+ }
+
+ void AddAnimations() {
+ const auto& update = state_.AnimationUpdate();
+ if (update.IsEmpty())
+ return;
+ cascade_.AddInterpolations(
+ &update.ActiveInterpolationsForCustomAnimations(),
+ CascadeOrigin::kAnimation);
+ cascade_.AddInterpolations(
+ &update.ActiveInterpolationsForStandardAnimations(),
+ CascadeOrigin::kAnimation);
+ }
+
+ void AddTransitions() {
+ const auto& update = state_.AnimationUpdate();
+ if (update.IsEmpty())
+ return;
+ cascade_.AddInterpolations(
+ &update.ActiveInterpolationsForCustomTransitions(),
+ CascadeOrigin::kTransition);
+ cascade_.AddInterpolations(
+ &update.ActiveInterpolationsForStandardTransitions(),
+ CascadeOrigin::kTransition);
+ }
+
+ CascadeOrigin current_origin_ = CascadeOrigin::kUserAgent;
StyleResolverState state_;
StyleCascade cascade_;
};
@@ -239,22 +208,29 @@ class TestCascadeResolver {
STACK_ALLOCATED();
public:
- TestCascadeResolver(Document& document, StyleAnimator& animator)
- : document_(&document), resolver_(animator) {}
+ explicit TestCascadeResolver(Document& document, uint8_t generation = 0)
+ : document_(document), resolver_(CascadeFilter(), generation) {}
bool InCycle() const { return resolver_.InCycle(); }
bool DetectCycle(String name) {
- CSSPropertyRef ref(name, *document_);
+ CSSPropertyRef ref(name, document_);
DCHECK(ref.IsValid());
const CSSProperty& property = ref.GetProperty();
return resolver_.DetectCycle(property);
}
wtf_size_t CycleDepth() const { return resolver_.cycle_depth_; }
+ void MarkApplied(CascadePriority* priority) {
+ resolver_.MarkApplied(priority);
+ }
+ void MarkUnapplied(CascadePriority* priority) {
+ resolver_.MarkUnapplied(priority);
+ }
+ uint8_t GetGeneration() { return resolver_.generation_; }
private:
friend class TestCascadeAutoLock;
- Member<Document> document_;
- StyleCascade::Resolver resolver_;
+ Document& document_;
+ CascadeResolver resolver_;
};
class TestCascadeAutoLock {
@@ -266,7 +242,7 @@ class TestCascadeAutoLock {
: lock_(name, resolver.resolver_) {}
private:
- StyleCascade::AutoLock lock_;
+ CascadeResolver::AutoLock lock_;
};
class StyleCascadeTest : public PageTestBase, private ScopedCSSCascadeForTest {
@@ -306,15 +282,15 @@ class StyleCascadeTest : public PageTestBase, private ScopedCSSCascadeForTest {
UpdateAllLifecyclePhasesForTest();
}
- Priority AuthorPriority(uint16_t tree_order, uint16_t cascade_order) {
- return Priority(Origin::kAuthor, tree_order)
- .WithCascadeOrder(cascade_order);
- }
-
- Priority ImportantAuthorPriority(uint16_t tree_order,
- uint16_t cascade_order) {
- return Priority(Origin::kImportantAuthor, tree_order)
- .WithCascadeOrder(cascade_order);
+ const MutableCSSPropertyValueSet* AnimationTaintedSet(AtomicString name,
+ String value) {
+ CSSParserMode mode = kHTMLStandardMode;
+ auto* set = MakeGarbageCollected<MutableCSSPropertyValueSet>(mode);
+ set->SetProperty(name, value, /* important */ false,
+ SecureContextMode::kSecureContext,
+ /* context_style_sheet */ nullptr,
+ /* is_animation_tainted */ true);
+ return set;
}
// Temporarily create a CSS Environment Variable.
@@ -334,130 +310,87 @@ class StyleCascadeTest : public PageTestBase, private ScopedCSSCascadeForTest {
return document_->GetStyleEngine().EnsureEnvironmentVariables();
}
- Member<Document> document_;
+ Document* document_;
AtomicString name_;
};
};
-TEST_F(StyleCascadeTest, OriginImportance) {
- EXPECT_EQ(Origin::kImportantUserAgent,
- Priority(Origin::kUserAgent).AddImportance().GetOrigin());
- EXPECT_EQ(Origin::kImportantUser,
- Priority(Origin::kUser).AddImportance().GetOrigin());
- EXPECT_EQ(Origin::kImportantAuthor,
- Priority(Origin::kAuthor).AddImportance().GetOrigin());
-}
-
-TEST_F(StyleCascadeTest, PriorityOrigin) {
- std::vector<Priority> priorities = {
- Origin::kTransition, Origin::kImportantUserAgent,
- Origin::kImportantUser, Origin::kImportantAuthor,
- Origin::kAnimation, Origin::kAuthor,
- Origin::kUser, Origin::kUserAgent,
- Origin::kNone};
-
- for (size_t i = 0; i < priorities.size(); ++i) {
- for (size_t j = i; j < priorities.size(); ++j)
- EXPECT_GE(priorities[i], priorities[j]);
- }
-
- EXPECT_FALSE(Priority(Origin::kUser) >= Priority(Origin::kAuthor));
-}
+TEST_F(StyleCascadeTest, ApplySingle) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("width", "1px", CascadeOrigin::kUserAgent);
+ cascade.Add("width", "2px", CascadeOrigin::kAuthor);
+ cascade.Apply();
-TEST_F(StyleCascadeTest, PriorityHasOrigin) {
- EXPECT_TRUE(Priority(Origin::kTransition).HasOrigin());
- EXPECT_TRUE(Priority(Origin::kAuthor).HasOrigin());
- EXPECT_FALSE(Priority(Origin::kNone).HasOrigin());
+ EXPECT_EQ("2px", cascade.ComputedValue("width"));
}
-TEST_F(StyleCascadeTest, PriorityTreeOrder) {
- Origin origin = Origin::kAuthor;
- EXPECT_GE(Priority(origin, 0), Priority(origin, 1));
- EXPECT_GE(Priority(origin, 6), Priority(origin, 7));
- EXPECT_GE(Priority(origin, 42), Priority(origin, 42));
- EXPECT_FALSE(Priority(origin, 8) >= Priority(origin, 1));
-}
+TEST_F(StyleCascadeTest, ApplyImportance) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("width:1px !important", CascadeOrigin::kUserAgent);
+ cascade.Add("width:2px", CascadeOrigin::kAuthor);
+ cascade.Apply();
-TEST_F(StyleCascadeTest, PriorityTreeOrderImportant) {
- Origin origin = Origin::kImportantAuthor;
- EXPECT_GE(Priority(origin, 1), Priority(origin, 0));
- EXPECT_GE(Priority(origin, 7), Priority(origin, 6));
- EXPECT_GE(Priority(origin, 42), Priority(origin, 42));
- EXPECT_FALSE(Priority(origin, 1) >= Priority(origin, 8));
+ EXPECT_EQ("1px", cascade.ComputedValue("width"));
}
-TEST_F(StyleCascadeTest, PriorityTreeOrderDifferentOrigin) {
- // Tree order does not matter if the origin is different.
- Origin author = Origin::kAuthor;
- Origin transition = Origin::kTransition;
- EXPECT_GE(Priority(transition, 42), Priority(author, 1));
- EXPECT_GE(Priority(transition, 1), Priority(author, 1));
-}
+TEST_F(StyleCascadeTest, ApplyAll) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("width:1px", CascadeOrigin::kUserAgent);
+ cascade.Add("height:1px", CascadeOrigin::kUserAgent);
+ cascade.Add("all:initial", CascadeOrigin::kAuthor);
+ cascade.Apply();
-TEST_F(StyleCascadeTest, PriorityCascadeOrder) {
- // AuthorPriority(tree_order, cascade_order)
- EXPECT_GE(AuthorPriority(0, 0), AuthorPriority(0, 0));
- EXPECT_GE(AuthorPriority(0, 1), AuthorPriority(0, 1));
- EXPECT_GE(AuthorPriority(0, 1), AuthorPriority(0, 0));
- EXPECT_GE(AuthorPriority(0, 2), AuthorPriority(0, 1));
- EXPECT_GE(AuthorPriority(0, 0xFFFF), AuthorPriority(0, 0xFFFE));
- EXPECT_FALSE(AuthorPriority(0, 2) >= AuthorPriority(0, 3));
+ EXPECT_EQ("auto", cascade.ComputedValue("width"));
+ EXPECT_EQ("auto", cascade.ComputedValue("height"));
}
-TEST_F(StyleCascadeTest, PriorityCascadeOrderAndTreeOrder) {
- // AuthorPriority(tree_order, cascade_order)
- EXPECT_GE(AuthorPriority(0, 0), AuthorPriority(1, 0));
- EXPECT_GE(AuthorPriority(0, 1), AuthorPriority(1, 1));
- EXPECT_GE(AuthorPriority(0, 1), AuthorPriority(1, 3));
- EXPECT_GE(AuthorPriority(0, 2), AuthorPriority(1, 0xFFFE));
-}
+TEST_F(StyleCascadeTest, ApplyAllImportance) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("opacity:0.5", CascadeOrigin::kUserAgent);
+ cascade.Add("display:block !important", CascadeOrigin::kUserAgent);
+ cascade.Add("all:initial", CascadeOrigin::kAuthor);
+ cascade.Apply();
-TEST_F(StyleCascadeTest, PriorityCascadeOrderAndOrigin) {
- // [Important]AuthorPriority(tree_order, cascade_order)
- EXPECT_GE(ImportantAuthorPriority(0, 0), AuthorPriority(0, 0));
- EXPECT_GE(ImportantAuthorPriority(0, 1), AuthorPriority(0, 1));
- EXPECT_GE(ImportantAuthorPriority(0, 1), AuthorPriority(0, 3));
- EXPECT_GE(ImportantAuthorPriority(0, 2), AuthorPriority(0, 0xFFFE));
+ EXPECT_EQ("1", cascade.ComputedValue("opacity"));
+ EXPECT_EQ("block", cascade.ComputedValue("display"));
}
-TEST_F(StyleCascadeTest, ApplySingle) {
+TEST_F(StyleCascadeTest, ApplyAllWithPhysicalLonghands) {
TestCascade cascade(GetDocument());
- cascade.Add("width", "2px", Origin::kAuthor);
- cascade.Add("width", "1px", Origin::kUser);
- cascade.Apply("width");
-
- EXPECT_EQ("2px", cascade.ComputedValue("width"));
+ cascade.Add("width:1px", CascadeOrigin::kUserAgent);
+ cascade.Add("height:1px !important", CascadeOrigin::kUserAgent);
+ cascade.Add("all:initial", CascadeOrigin::kAuthor);
+ cascade.Apply();
+ EXPECT_EQ("auto", cascade.ComputedValue("width"));
+ EXPECT_EQ("1px", cascade.ComputedValue("height"));
}
TEST_F(StyleCascadeTest, ApplyCustomProperty) {
TestCascade cascade(GetDocument());
cascade.Add("--x", " 10px ");
cascade.Add("--y", "nope");
- cascade.Apply("--x");
- cascade.Apply("--y");
+ cascade.Apply();
EXPECT_EQ(" 10px ", cascade.ComputedValue("--x"));
EXPECT_EQ("nope", cascade.ComputedValue("--y"));
}
-TEST_F(StyleCascadeTest, Copy) {
- StyleResolverState state(GetDocument(), *GetDocument().body());
-
+TEST_F(StyleCascadeTest, ApplyGenerations) {
TestCascade cascade(GetDocument());
- cascade.Add("--x", "10px");
- cascade.Add("width", "20px");
-
- // Take snapshot of the cascade, pointing to the same StyleResolverState.
- StyleCascade snapshot(cascade.InnerCascade());
- cascade.Add("--x", "0px");
- cascade.Add("width", "1px");
+ cascade.Add("--x:10px");
+ cascade.Add("width:20px");
cascade.Apply();
+ EXPECT_EQ("10px", cascade.ComputedValue("--x"));
+ EXPECT_EQ("20px", cascade.ComputedValue("width"));
- EXPECT_EQ("0px", cascade.ComputedValue("--x"));
- EXPECT_EQ("1px", cascade.ComputedValue("width"));
+ cascade.State().StyleRef().SetWidth(Length::Auto());
+ cascade.State().StyleRef().SetVariableData("--x", nullptr, true);
+ EXPECT_EQ(g_null_atom, cascade.ComputedValue("--x"));
+ EXPECT_EQ("auto", cascade.ComputedValue("width"));
- snapshot.Apply();
+ // Apply again
+ cascade.Apply();
EXPECT_EQ("10px", cascade.ComputedValue("--x"));
EXPECT_EQ("20px", cascade.ComputedValue("width"));
}
@@ -468,8 +401,7 @@ TEST_F(StyleCascadeTest, ApplyCustomPropertyVar) {
TestCascade cascade(GetDocument());
cascade.Add("--x", "yes and var(--y)");
cascade.Add("--y", "no");
- cascade.Apply("--x");
- cascade.Apply("--y");
+ cascade.Apply();
EXPECT_EQ("yes and no", cascade.ComputedValue("--x"));
EXPECT_EQ("no", cascade.ComputedValue("--y"));
@@ -478,10 +410,9 @@ TEST_F(StyleCascadeTest, ApplyCustomPropertyVar) {
// Apply --y first.
{
TestCascade cascade(GetDocument());
- cascade.Add("--x", "yes and var(--y)");
cascade.Add("--y", "no");
- cascade.Apply("--y");
- cascade.Apply("--x");
+ cascade.Add("--x", "yes and var(--y)");
+ cascade.Apply();
EXPECT_EQ("yes and no", cascade.ComputedValue("--x"));
EXPECT_EQ("no", cascade.ComputedValue("--y"));
@@ -491,7 +422,7 @@ TEST_F(StyleCascadeTest, ApplyCustomPropertyVar) {
TEST_F(StyleCascadeTest, InvalidVarReferenceCauseInvalidVariable) {
TestCascade cascade(GetDocument());
cascade.Add("--x", "nope var(--y)");
- cascade.Apply("--x");
+ cascade.Apply();
EXPECT_EQ(g_null_atom, cascade.ComputedValue("--x"));
}
@@ -499,7 +430,7 @@ TEST_F(StyleCascadeTest, InvalidVarReferenceCauseInvalidVariable) {
TEST_F(StyleCascadeTest, ApplyCustomPropertyFallback) {
TestCascade cascade(GetDocument());
cascade.Add("--x", "yes and var(--y,no)");
- cascade.Apply("--x");
+ cascade.Apply();
EXPECT_EQ("yes and no", cascade.ComputedValue("--x"));
}
@@ -530,7 +461,7 @@ TEST_F(StyleCascadeTest, VarInFallback) {
TestCascade cascade(GetDocument());
cascade.Add("--x", "one var(--z,two var(--y))");
cascade.Add("--y", "three");
- cascade.Apply("--x");
+ cascade.Apply();
EXPECT_EQ("one two three", cascade.ComputedValue("--x"));
}
@@ -539,7 +470,7 @@ TEST_F(StyleCascadeTest, VarReferenceInNormalProperty) {
TestCascade cascade(GetDocument());
cascade.Add("--x", "10px");
cascade.Add("width", "var(--x)");
- cascade.Apply("width");
+ cascade.Apply();
EXPECT_EQ("10px", cascade.ComputedValue("width"));
}
@@ -548,7 +479,7 @@ TEST_F(StyleCascadeTest, MultipleVarRefs) {
TestCascade cascade(GetDocument());
cascade.Add("--x", "var(--y) bar var(--y)");
cascade.Add("--y", "foo");
- cascade.Apply("--x");
+ cascade.Apply();
EXPECT_EQ("foo bar foo", cascade.ComputedValue("--x"));
}
@@ -558,7 +489,7 @@ TEST_F(StyleCascadeTest, RegisteredPropertyComputedValue) {
TestCascade cascade(GetDocument());
cascade.Add("--x", "1in");
- cascade.Apply("--x");
+ cascade.Apply();
EXPECT_EQ("96px", cascade.ComputedValue("--x"));
}
@@ -569,8 +500,7 @@ TEST_F(StyleCascadeTest, RegisteredPropertySyntaxErrorCausesInitial) {
TestCascade cascade(GetDocument());
cascade.Add("--x", "#fefefe");
cascade.Add("--y", "var(--x)");
- cascade.Apply("--x");
- cascade.Apply("--y");
+ cascade.Apply();
EXPECT_EQ("10px", cascade.ComputedValue("--x"));
EXPECT_EQ("10px", cascade.ComputedValue("--y"));
@@ -582,7 +512,7 @@ TEST_F(StyleCascadeTest, RegisteredPropertySubstitution) {
TestCascade cascade(GetDocument());
cascade.Add("--x", "1in");
cascade.Add("--y", "var(--x)");
- cascade.Apply("--y");
+ cascade.Apply();
EXPECT_EQ("96px", cascade.ComputedValue("--y"));
}
@@ -630,10 +560,6 @@ TEST_F(StyleCascadeTest, ApplyingPendingSubstitutionFirst) {
cascade.Add("margin", "1px var(--x) 3px 4px");
cascade.Add("--x", "2px");
cascade.Add("margin-right", "5px");
-
- // Apply one of the pending substitution values first. This should not
- // overwrite margin-right's 5px.
- cascade.Apply("margin-left");
cascade.Apply();
EXPECT_EQ("1px", cascade.ComputedValue("margin-top"));
@@ -644,48 +570,20 @@ TEST_F(StyleCascadeTest, ApplyingPendingSubstitutionFirst) {
TEST_F(StyleCascadeTest, ApplyingPendingSubstitutionLast) {
TestCascade cascade(GetDocument());
+ cascade.Add("margin-right", "5px");
cascade.Add("margin", "1px var(--x) 3px 4px");
cascade.Add("--x", "2px");
- cascade.Add("margin-right", "5px");
-
- // Apply margin-right before the others. Applying the pending substitution
- // afterwards should not overwrite margin-right's 5px.
- cascade.Apply("margin-right");
cascade.Apply();
EXPECT_EQ("1px", cascade.ComputedValue("margin-top"));
- EXPECT_EQ("5px", cascade.ComputedValue("margin-right"));
+ EXPECT_EQ("2px", cascade.ComputedValue("margin-right"));
EXPECT_EQ("3px", cascade.ComputedValue("margin-bottom"));
EXPECT_EQ("4px", cascade.ComputedValue("margin-left"));
}
-TEST_F(StyleCascadeTest, ApplyingPendingSubstitutionModifiesCascade) {
- TestCascade cascade(GetDocument());
- cascade.Add("margin", "1px var(--x) 3px 4px");
- cascade.Add("--x", "2px");
- cascade.Add("margin-right", "5px");
-
- // We expect the pending substitution value for all the shorthands,
- // except margin-right.
- EXPECT_EQ("1px var(--x) 3px 4px", cascade.GetValue("margin-top"));
- EXPECT_EQ("5px", cascade.GetValue("margin-right"));
- EXPECT_EQ("1px var(--x) 3px 4px", cascade.GetValue("margin-bottom"));
- EXPECT_EQ("1px var(--x) 3px 4px", cascade.GetValue("margin-left"));
-
- // Apply a pending substitution value should modify the cascade for other
- // longhands with the same pending substitution value.
- cascade.Apply("margin-left");
-
- EXPECT_EQ("1px", cascade.GetValue("margin-top"));
- EXPECT_EQ("5px", cascade.GetValue("margin-right"));
- EXPECT_EQ("3px", cascade.GetValue("margin-bottom"));
- EXPECT_FALSE(cascade.GetValue("margin-left"));
-}
-
TEST_F(StyleCascadeTest, ResolverDetectCycle) {
TestCascade cascade(GetDocument());
- StyleAnimator animator(cascade.State(), cascade.InnerCascade());
- TestCascadeResolver resolver(GetDocument(), animator);
+ TestCascadeResolver resolver(GetDocument());
{
TestCascadeAutoLock lock(CSSPropertyName("--a"), resolver);
@@ -709,8 +607,7 @@ TEST_F(StyleCascadeTest, ResolverDetectCycle) {
TEST_F(StyleCascadeTest, ResolverDetectNoCycle) {
TestCascade cascade(GetDocument());
- StyleAnimator animator(cascade.State(), cascade.InnerCascade());
- TestCascadeResolver resolver(GetDocument(), animator);
+ TestCascadeResolver resolver(GetDocument());
{
TestCascadeAutoLock lock(CSSPropertyName("--a"), resolver);
@@ -734,8 +631,7 @@ TEST_F(StyleCascadeTest, ResolverDetectNoCycle) {
TEST_F(StyleCascadeTest, ResolverDetectCycleSelf) {
TestCascade cascade(GetDocument());
- StyleAnimator animator(cascade.State(), cascade.InnerCascade());
- TestCascadeResolver resolver(GetDocument(), animator);
+ TestCascadeResolver resolver(GetDocument());
{
TestCascadeAutoLock lock(CSSPropertyName("--a"), resolver);
@@ -751,8 +647,7 @@ TEST_F(StyleCascadeTest, ResolverDetectMultiCycle) {
using AutoLock = TestCascadeAutoLock;
TestCascade cascade(GetDocument());
- StyleAnimator animator(cascade.State(), cascade.InnerCascade());
- TestCascadeResolver resolver(GetDocument(), animator);
+ TestCascadeResolver resolver(GetDocument());
{
AutoLock lock(CSSPropertyName("--a"), resolver);
@@ -789,8 +684,7 @@ TEST_F(StyleCascadeTest, ResolverDetectMultiCycleReverse) {
using AutoLock = TestCascadeAutoLock;
TestCascade cascade(GetDocument());
- StyleAnimator animator(cascade.State(), cascade.InnerCascade());
- TestCascadeResolver resolver(GetDocument(), animator);
+ TestCascadeResolver resolver(GetDocument());
{
AutoLock lock(CSSPropertyName("--a"), resolver);
@@ -823,6 +717,37 @@ TEST_F(StyleCascadeTest, ResolverDetectMultiCycleReverse) {
EXPECT_FALSE(resolver.InCycle());
}
+TEST_F(StyleCascadeTest, ResolverMarkApplied) {
+ TestCascadeResolver resolver(GetDocument(), 2);
+
+ CascadePriority priority(CascadeOrigin::kAuthor);
+ EXPECT_EQ(0, priority.GetGeneration());
+
+ resolver.MarkApplied(&priority);
+ EXPECT_EQ(2, priority.GetGeneration());
+
+ // Mark a second time to verify observation of the same generation.
+ resolver.MarkApplied(&priority);
+ EXPECT_EQ(2, priority.GetGeneration());
+}
+
+TEST_F(StyleCascadeTest, ResolverMarkUnapplied) {
+ TestCascadeResolver resolver(GetDocument(), 7);
+
+ CascadePriority priority(CascadeOrigin::kAuthor);
+ EXPECT_EQ(0, priority.GetGeneration());
+
+ resolver.MarkApplied(&priority);
+ EXPECT_EQ(7, priority.GetGeneration());
+
+ resolver.MarkUnapplied(&priority);
+ EXPECT_EQ(0, priority.GetGeneration());
+
+ // Mark a second time to verify observation of the same generation.
+ resolver.MarkUnapplied(&priority);
+ EXPECT_EQ(0, priority.GetGeneration());
+}
+
TEST_F(StyleCascadeTest, BasicCycle) {
TestCascade cascade(GetDocument());
cascade.Add("--a", "foo");
@@ -1066,7 +991,7 @@ TEST_F(StyleCascadeTest, CycleReferencedFromStandardProperty) {
TestCascade cascade(GetDocument());
cascade.Add("--a", "var(--b)");
cascade.Add("--b", "var(--a)");
- cascade.Add("color", "var(--a,green)");
+ cascade.Add("color:var(--a,green)");
cascade.Apply();
EXPECT_FALSE(cascade.ComputedValue("--a"));
@@ -1383,7 +1308,7 @@ TEST_F(StyleCascadeTest, RegisteredExplicitUnset) {
TEST_F(StyleCascadeTest, SubstituteAnimationTaintedInCustomProperty) {
TestCascade cascade(GetDocument());
- cascade.Add("--x", "15px", Origin::kAuthor, AnimationTainted::kYes);
+ cascade.Add(AnimationTaintedSet("--x", "15px"));
cascade.Add("--y", "var(--x)");
cascade.Apply();
EXPECT_EQ("15px", cascade.ComputedValue("--x"));
@@ -1392,7 +1317,7 @@ TEST_F(StyleCascadeTest, SubstituteAnimationTaintedInCustomProperty) {
TEST_F(StyleCascadeTest, SubstituteAnimationTaintedInStandardProperty) {
TestCascade cascade(GetDocument());
- cascade.Add("--x", "15px", Origin::kAuthor, AnimationTainted::kYes);
+ cascade.Add(AnimationTaintedSet("--x", "15px"));
cascade.Add("width", "var(--x)");
cascade.Apply();
EXPECT_EQ("15px", cascade.ComputedValue("--x"));
@@ -1408,7 +1333,7 @@ TEST_F(StyleCascadeTest, SubstituteAnimationTaintedInAnimationProperty) {
EXPECT_EQ("20s", cascade.ComputedValue("--x"));
EXPECT_EQ("20s", cascade.ComputedValue("animation-duration"));
- cascade.Add("--y", "20s", Origin::kAuthor, AnimationTainted::kYes);
+ cascade.Add(AnimationTaintedSet("--y", "20s"));
cascade.Add("animation-duration", "var(--y)");
cascade.Apply();
@@ -1418,7 +1343,7 @@ TEST_F(StyleCascadeTest, SubstituteAnimationTaintedInAnimationProperty) {
TEST_F(StyleCascadeTest, IndirectlyAnimationTainted) {
TestCascade cascade(GetDocument());
- cascade.Add("--x", "20s", Origin::kAuthor, AnimationTainted::kYes);
+ cascade.Add(AnimationTaintedSet("--x", "20s"));
cascade.Add("--y", "var(--x)");
cascade.Add("animation-duration", "var(--y)");
cascade.Apply();
@@ -1430,7 +1355,7 @@ TEST_F(StyleCascadeTest, IndirectlyAnimationTainted) {
TEST_F(StyleCascadeTest, AnimationTaintedFallback) {
TestCascade cascade(GetDocument());
- cascade.Add("--x", "20s", Origin::kAuthor, AnimationTainted::kYes);
+ cascade.Add(AnimationTaintedSet("--x", "20s"));
cascade.Add("animation-duration", "var(--x,1s)");
cascade.Apply();
@@ -1506,33 +1431,50 @@ TEST_F(StyleCascadeTest, ValidEnvInUsedFallback) {
EXPECT_EQ("rgb(255, 0, 0)", cascade.ComputedValue("background-color"));
}
-// An Animator that just records the name of all the properties
-// applied.
-class RecordingAnimator : public StyleCascade::Animator {
- public:
- void Apply(const CSSProperty& property,
- const CSSPendingInterpolationValue&,
- StyleCascade::Resolver& resolver) override {
- record.push_back(property.GetCSSPropertyName());
- }
+TEST_F(StyleCascadeTest, AnimationApplyFilter) {
+ AppendSheet(R"HTML(
+ @keyframes test {
+ from { color: white; background-color: white; }
+ to { color: gray; background-color: gray; }
+ }
+ )HTML");
- Vector<CSSPropertyName> record;
-};
+ TestCascade cascade(GetDocument());
-TEST_F(StyleCascadeTest, AnimatorCalledByPendingInterpolationValue) {
- RegisterProperty(GetDocument(), "--x", "<length>", "0px", false);
+ cascade.Add("animation: test linear 10s -5s");
+ cascade.Add("color:green");
+ cascade.Apply();
- RecordingAnimator animator;
+ cascade.CalculateAnimationUpdate();
+ cascade.Apply(CascadeFilter(CSSProperty::kInherited, true));
- using Type = CSSPendingInterpolationValue::Type;
- TestCascade cascade(GetDocument());
- cascade.Add("--x", CSSPendingInterpolationValue::Create(Type::kCSSProperty));
- cascade.Add("--y", CSSPendingInterpolationValue::Create(Type::kCSSProperty));
+ EXPECT_EQ("rgb(0, 128, 0)", cascade.ComputedValue("color"));
+ EXPECT_EQ("rgb(192, 192, 192)", cascade.ComputedValue("background-color"));
+}
+
+TEST_F(StyleCascadeTest, TransitionApplyFilter) {
+ TestCascade cascade1(GetDocument());
+ cascade1.Add("background-color: white");
+ cascade1.Add("color: white");
+ cascade1.Add("transition: all steps(2, start) 100s");
+ cascade1.Apply();
+
+ // Set the old style on the element, so that the transition
+ // update detects it.
+ GetDocument().body()->SetComputedStyle(cascade1.TakeStyle());
+
+ // Now simulate a new style, with new color values.
+ TestCascade cascade2(GetDocument());
+ cascade2.Add("background-color: gray");
+ cascade2.Add("color: gray");
+ cascade2.Add("transition: all steps(2, start) 100s");
+ cascade2.Apply();
- cascade.Apply(animator);
+ cascade2.CalculateTransitionUpdate();
+ cascade2.Apply(CascadeFilter(CSSProperty::kInherited, true));
- EXPECT_TRUE(animator.record.Contains(*CSSPropertyName::From("--x")));
- EXPECT_TRUE(animator.record.Contains(*CSSPropertyName::From("--y")));
+ EXPECT_EQ("rgb(128, 128, 128)", cascade2.ComputedValue("color"));
+ EXPECT_EQ("rgb(192, 192, 192)", cascade2.ComputedValue("background-color"));
}
TEST_F(StyleCascadeTest, PendingKeyframeAnimation) {
@@ -1551,9 +1493,10 @@ TEST_F(StyleCascadeTest, PendingKeyframeAnimation) {
cascade.Add("animation-duration", "1s");
cascade.Apply();
- cascade.AddAnimations();
+ cascade.CalculateAnimationUpdate();
+ cascade.Apply();
- EXPECT_EQ("<interpolation>", cascade.GetValue("--x"));
+ EXPECT_EQ(CascadeOrigin::kAnimation, cascade.GetPriority("--x").GetOrigin());
}
TEST_F(StyleCascadeTest, PendingKeyframeAnimationApply) {
@@ -1574,11 +1517,10 @@ TEST_F(StyleCascadeTest, PendingKeyframeAnimationApply) {
cascade.Add("animation-delay", "-5s");
cascade.Apply();
- cascade.AddAnimations();
+ cascade.CalculateAnimationUpdate();
+ cascade.Apply();
- EXPECT_EQ("<interpolation>", cascade.GetValue("--x"));
- StyleAnimator animator(cascade.State(), cascade.InnerCascade());
- cascade.Apply(animator);
+ EXPECT_EQ(CascadeOrigin::kAnimation, cascade.GetPriority("--x").GetOrigin());
EXPECT_EQ("15px", cascade.ComputedValue("--x"));
}
@@ -1601,11 +1543,11 @@ TEST_F(StyleCascadeTest, TransitionCausesInterpolationValue) {
cascade2.Add("transition", "--x 1s");
cascade2.Apply();
- // Detects transitions, and adds CSSPendingInterpolationValues
- // to the cascade, as appropriate.
- cascade2.AddTransitions();
+ cascade2.CalculateTransitionUpdate();
+ cascade2.Apply();
- EXPECT_EQ("<interpolation>", cascade2.GetValue("--x"));
+ EXPECT_EQ(CascadeOrigin::kTransition,
+ cascade2.GetPriority("--x").GetOrigin());
}
TEST_F(StyleCascadeTest, TransitionDetectedForChangedFontSize) {
@@ -1629,10 +1571,11 @@ TEST_F(StyleCascadeTest, TransitionDetectedForChangedFontSize) {
cascade2.Add("transition", "--x 1s, width 1s");
cascade2.Apply();
- cascade2.AddTransitions();
+ cascade2.CalculateTransitionUpdate();
+ cascade2.Apply();
- EXPECT_EQ("<interpolation>", cascade2.GetValue("--x"));
- EXPECT_EQ("<interpolation>", cascade2.GetValue("width"));
+ EXPECT_EQ(CascadeOrigin::kTransition, cascade2.GetOrigin("--x"));
+ EXPECT_EQ(CascadeOrigin::kTransition, cascade2.GetOrigin("width"));
EXPECT_EQ("10px", cascade2.ComputedValue("height"));
}
@@ -1654,13 +1597,11 @@ TEST_F(StyleCascadeTest, AnimatingVarReferences) {
cascade.Add("animation-delay", "-5s");
cascade.Apply();
- StyleAnimator animator(cascade.State(), cascade.InnerCascade());
-
- cascade.AddAnimations();
+ cascade.CalculateAnimationUpdate();
cascade.Add("--from", "10px");
cascade.Add("--to", "20px");
cascade.Add("--y", "var(--x)");
- cascade.Apply(animator);
+ cascade.Apply();
EXPECT_EQ("15px", cascade.ComputedValue("--x"));
EXPECT_EQ("15px", cascade.ComputedValue("--y"));
@@ -1682,13 +1623,67 @@ TEST_F(StyleCascadeTest, AnimateStandardProperty) {
cascade.Add("animation-delay", "-5s");
cascade.Apply();
- StyleAnimator animator(cascade.State(), cascade.InnerCascade());
+ cascade.CalculateAnimationUpdate();
+ cascade.Apply();
+
+ EXPECT_EQ(CascadeOrigin::kAnimation, cascade.GetOrigin("width"));
+ EXPECT_EQ("15px", cascade.ComputedValue("width"));
+}
+
+TEST_F(StyleCascadeTest, AuthorImportantWinOverAnimations) {
+ AppendSheet(R"HTML(
+ @keyframes test {
+ from { width: 10px; height: 10px; }
+ to { width: 20px; height: 20px; }
+ }
+ )HTML");
- cascade.AddAnimations();
- EXPECT_EQ("<interpolation>", cascade.GetValue("width"));
+ TestCascade cascade(GetDocument());
+
+ cascade.Add("animation-name", "test");
+ cascade.Add("animation-duration", "10s");
+ cascade.Add("animation-timing-function", "linear");
+ cascade.Add("animation-delay", "-5s");
+ cascade.Add("width:40px");
+ cascade.Add("height:40px !important");
+ cascade.Apply();
+
+ cascade.CalculateAnimationUpdate();
+ cascade.Apply();
+
+ EXPECT_EQ(CascadeOrigin::kAnimation, cascade.GetOrigin("width"));
+ EXPECT_EQ(CascadeOrigin::kAuthor, cascade.GetOrigin("height"));
- cascade.Apply(animator);
EXPECT_EQ("15px", cascade.ComputedValue("width"));
+ EXPECT_EQ("40px", cascade.ComputedValue("height"));
+}
+
+TEST_F(StyleCascadeTest, TransitionsWinOverAuthorImportant) {
+ // First, simulate an "old style".
+ TestCascade cascade1(GetDocument());
+ cascade1.Add("width:10px !important");
+ cascade1.Add("height:10px !important");
+ cascade1.Add("transition:all 1s");
+ cascade1.Apply();
+
+ // Set the old style on the element, so that the animation
+ // update detects it.
+ GetDocument().body()->SetComputedStyle(cascade1.TakeStyle());
+
+ // Now simulate a new style, with a new value for width/height.
+ TestCascade cascade2(GetDocument());
+ cascade2.Add("width:20px !important");
+ cascade2.Add("height:20px !important");
+ cascade2.Add("transition:all 1s");
+ cascade2.Apply();
+
+ cascade2.CalculateTransitionUpdate();
+ cascade2.Apply();
+
+ EXPECT_EQ(CascadeOrigin::kTransition,
+ cascade2.GetPriority("width").GetOrigin());
+ EXPECT_EQ(CascadeOrigin::kTransition,
+ cascade2.GetPriority("height").GetOrigin());
}
TEST_F(StyleCascadeTest, EmRespondsToAnimatedFontSize) {
@@ -1709,13 +1704,11 @@ TEST_F(StyleCascadeTest, EmRespondsToAnimatedFontSize) {
cascade.Add("animation-delay", "-5s");
cascade.Apply();
- StyleAnimator animator(cascade.State(), cascade.InnerCascade());
-
- cascade.AddAnimations();
+ cascade.CalculateAnimationUpdate();
cascade.Add("--x", "2em");
cascade.Add("width", "10em");
- cascade.Apply(animator);
+ cascade.Apply();
EXPECT_EQ("30px", cascade.ComputedValue("--x"));
EXPECT_EQ("150px", cascade.ComputedValue("width"));
}
@@ -1738,13 +1731,11 @@ TEST_F(StyleCascadeTest, AnimateStandardPropertyWithVar) {
cascade.Add("animation-delay", "-5s");
cascade.Apply();
- StyleAnimator animator(cascade.State(), cascade.InnerCascade());
-
- cascade.AddAnimations();
+ cascade.CalculateAnimationUpdate();
cascade.Add("--from", "10px");
cascade.Add("--to", "20px");
- cascade.Apply(animator);
+ cascade.Apply();
EXPECT_EQ("15px", cascade.ComputedValue("width"));
}
@@ -1766,21 +1757,162 @@ TEST_F(StyleCascadeTest, AnimateStandardShorthand) {
cascade.Add("animation-delay", "-5s");
cascade.Apply();
- StyleAnimator animator(cascade.State(), cascade.InnerCascade());
+ cascade.CalculateAnimationUpdate();
+ cascade.Apply();
- cascade.AddAnimations();
- EXPECT_EQ("<interpolation>", cascade.GetValue("margin-top"));
- EXPECT_EQ("<interpolation>", cascade.GetValue("margin-right"));
- EXPECT_EQ("<interpolation>", cascade.GetValue("margin-bottom"));
- EXPECT_EQ("<interpolation>", cascade.GetValue("margin-left"));
+ EXPECT_EQ(CascadeOrigin::kAnimation, cascade.GetOrigin("margin-top"));
+ EXPECT_EQ(CascadeOrigin::kAnimation, cascade.GetOrigin("margin-right"));
+ EXPECT_EQ(CascadeOrigin::kAnimation, cascade.GetOrigin("margin-bottom"));
+ EXPECT_EQ(CascadeOrigin::kAnimation, cascade.GetOrigin("margin-left"));
- cascade.Apply(animator);
EXPECT_EQ("15px", cascade.ComputedValue("margin-top"));
EXPECT_EQ("15px", cascade.ComputedValue("margin-right"));
EXPECT_EQ("15px", cascade.ComputedValue("margin-bottom"));
EXPECT_EQ("15px", cascade.ComputedValue("margin-left"));
}
+TEST_F(StyleCascadeTest, AnimatedVisitedImportantOverride) {
+ AppendSheet(R"HTML(
+ @keyframes test {
+ from { background-color: rgb(100, 100, 100); }
+ to { background-color: rgb(200, 200, 200); }
+ }
+ )HTML");
+
+ TestCascade cascade(GetDocument());
+ cascade.State().Style()->SetInsideLink(EInsideLink::kInsideVisitedLink);
+
+ cascade.Add(ParseDeclarationBlock("background-color:red !important"),
+ CascadeOrigin::kAuthor, CSSSelector::kMatchVisited);
+ cascade.Add("animation-name:test");
+ cascade.Add("animation-duration:10s");
+ cascade.Add("animation-timing-function:linear");
+ cascade.Add("animation-delay:-5s");
+ cascade.Apply();
+
+ cascade.CalculateAnimationUpdate();
+ cascade.Apply();
+ EXPECT_EQ("rgb(150, 150, 150)", cascade.ComputedValue("background-color"));
+
+ auto style = cascade.TakeStyle();
+
+ style->SetInsideLink(EInsideLink::kInsideVisitedLink);
+ EXPECT_EQ(Color(255, 0, 0),
+ style->VisitedDependentColor(GetCSSPropertyBackgroundColor()));
+
+ style->SetInsideLink(EInsideLink::kNotInsideLink);
+ EXPECT_EQ(Color(150, 150, 150),
+ style->VisitedDependentColor(GetCSSPropertyBackgroundColor()));
+}
+
+TEST_F(StyleCascadeTest, AnimatedVisitedHighPrio) {
+ AppendSheet(R"HTML(
+ @keyframes test {
+ from { color: rgb(100, 100, 100); }
+ to { color: rgb(200, 200, 200); }
+ }
+ )HTML");
+
+ TestCascade cascade(GetDocument());
+ cascade.Add("color:red");
+ cascade.Add("animation:test 10s -5s linear");
+ cascade.Apply();
+
+ cascade.CalculateAnimationUpdate();
+ cascade.Apply();
+ EXPECT_EQ("rgb(150, 150, 150)", cascade.ComputedValue("color"));
+
+ auto style = cascade.TakeStyle();
+
+ style->SetInsideLink(EInsideLink::kInsideVisitedLink);
+ EXPECT_EQ(Color(150, 150, 150),
+ style->VisitedDependentColor(GetCSSPropertyColor()));
+
+ style->SetInsideLink(EInsideLink::kNotInsideLink);
+ EXPECT_EQ(Color(150, 150, 150),
+ style->VisitedDependentColor(GetCSSPropertyColor()));
+}
+
+TEST_F(StyleCascadeTest, AnimatedImportantOverrideFlag) {
+ AppendSheet(R"HTML(
+ @keyframes test {
+ from { background-color: white; }
+ to { background-color: gray; }
+ }
+ )HTML");
+
+ TestCascade cascade(GetDocument());
+ cascade.Add("animation:test 10s -5s linear");
+ cascade.Add("background-color: green !important");
+ cascade.Apply();
+ EXPECT_FALSE(cascade.State().HasImportantOverrides());
+
+ cascade.CalculateAnimationUpdate();
+ cascade.Apply();
+ EXPECT_TRUE(cascade.State().HasImportantOverrides());
+}
+
+TEST_F(StyleCascadeTest, AnimatedImportantOverrideNoFlag) {
+ AppendSheet(R"HTML(
+ @keyframes test {
+ from { background-color: white; }
+ to { background-color: gray; }
+ }
+ )HTML");
+
+ TestCascade cascade(GetDocument());
+ cascade.Add("animation:test 10s -5s linear");
+ cascade.Add("color:green !important");
+ cascade.Apply();
+ EXPECT_FALSE(cascade.State().HasImportantOverrides());
+
+ cascade.CalculateAnimationUpdate();
+ cascade.Apply();
+ EXPECT_FALSE(cascade.State().HasImportantOverrides());
+}
+
+TEST_F(StyleCascadeTest, AnimatedImportantOverrideFlagHighPriority) {
+ AppendSheet(R"HTML(
+ @keyframes test {
+ from { color: white; }
+ to { color: gray; }
+ }
+ )HTML");
+
+ // 'color' is a high priority property, and therefore applied by lookup.
+ TestCascade cascade(GetDocument());
+ cascade.Add("animation:test 10s -5s linear");
+ cascade.Add("color:green !important");
+ cascade.Apply();
+ EXPECT_FALSE(cascade.State().HasImportantOverrides());
+
+ cascade.CalculateAnimationUpdate();
+ cascade.Apply();
+ EXPECT_TRUE(cascade.State().HasImportantOverrides());
+}
+
+TEST_F(StyleCascadeTest, AnimatedImportantOverrideFlagVisited) {
+ AppendSheet(R"HTML(
+ @keyframes test {
+ from { background-color: white; }
+ to { background-color: gray; }
+ }
+ )HTML");
+
+ TestCascade cascade(GetDocument());
+ cascade.State().Style()->SetInsideLink(EInsideLink::kInsideVisitedLink);
+
+ cascade.Add(ParseDeclarationBlock("background-color:red !important"),
+ CascadeOrigin::kAuthor, CSSSelector::kMatchVisited);
+ cascade.Add("animation:test 10s -5s linear");
+ cascade.Apply();
+ EXPECT_FALSE(cascade.State().HasImportantOverrides());
+
+ cascade.CalculateAnimationUpdate();
+ cascade.Apply();
+ EXPECT_TRUE(cascade.State().HasImportantOverrides());
+}
+
TEST_F(StyleCascadeTest, AnimatePendingSubstitutionValue) {
RegisterProperty(GetDocument(), "--x", "<length>", "0px", false);
@@ -1799,17 +1931,16 @@ TEST_F(StyleCascadeTest, AnimatePendingSubstitutionValue) {
cascade.Add("animation-delay", "-5s");
cascade.Apply();
- StyleAnimator animator(cascade.State(), cascade.InnerCascade());
-
- cascade.AddAnimations();
+ cascade.CalculateAnimationUpdate();
cascade.Add("--from", "10px");
cascade.Add("--to", "20px");
- EXPECT_EQ("<interpolation>", cascade.GetValue("margin-top"));
- EXPECT_EQ("<interpolation>", cascade.GetValue("margin-right"));
- EXPECT_EQ("<interpolation>", cascade.GetValue("margin-bottom"));
- EXPECT_EQ("<interpolation>", cascade.GetValue("margin-left"));
+ cascade.Apply();
+
+ EXPECT_EQ(CascadeOrigin::kAnimation, cascade.GetOrigin("margin-top"));
+ EXPECT_EQ(CascadeOrigin::kAnimation, cascade.GetOrigin("margin-right"));
+ EXPECT_EQ(CascadeOrigin::kAnimation, cascade.GetOrigin("margin-bottom"));
+ EXPECT_EQ(CascadeOrigin::kAnimation, cascade.GetOrigin("margin-left"));
- cascade.Apply(animator);
EXPECT_EQ("15px", cascade.ComputedValue("margin-top"));
EXPECT_EQ("15px", cascade.ComputedValue("margin-right"));
EXPECT_EQ("15px", cascade.ComputedValue("margin-bottom"));
@@ -1817,7 +1948,7 @@ TEST_F(StyleCascadeTest, AnimatePendingSubstitutionValue) {
}
TEST_F(StyleCascadeTest, ForeignObjectZoomVsEffectiveZoom) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<svg>
<foreignObject id='foreign'></foreignObject>
</svg>
@@ -1828,44 +1959,54 @@ TEST_F(StyleCascadeTest, ForeignObjectZoomVsEffectiveZoom) {
ASSERT_TRUE(foreign_object);
TestCascade cascade(GetDocument(), foreign_object);
-
- cascade.Add("zoom", "200%");
- // TODO(andruud): Can't use CSSPropertyName to get -internal properties
- // yet.
- cascade.Add(CSSPropertyName(CSSPropertyID::kInternalEffectiveZoom),
- "initial");
+ cascade.Add("-internal-effective-zoom:initial !important",
+ CascadeOrigin::kUserAgent);
+ cascade.Add("zoom:200%");
cascade.Apply();
- // If both zoom and -internal-zoom exists in the cascade,
- // -internal-effective-zoom should win.
EXPECT_EQ(1.0f, cascade.TakeStyle()->EffectiveZoom());
}
TEST_F(StyleCascadeTest, ZoomCascadeOrder) {
- CSSPropertyName effective_zoom(CSSPropertyID::kInternalEffectiveZoom);
TestCascade cascade(GetDocument());
- cascade.Add("zoom", "200%");
- cascade.Add(effective_zoom, "initial");
+ cascade.Add("zoom:200%", CascadeOrigin::kUserAgent);
+ cascade.Add("-internal-effective-zoom:initial", CascadeOrigin::kUserAgent);
+ cascade.Apply();
+
+ EXPECT_EQ(1.0f, cascade.TakeStyle()->EffectiveZoom());
+}
+
+TEST_F(StyleCascadeTest, ZoomVsAll) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("zoom:200%", CascadeOrigin::kUserAgent);
+ cascade.Add("all:initial");
+ cascade.Apply();
+
+ EXPECT_EQ(1.0f, cascade.TakeStyle()->EffectiveZoom());
+}
+
+TEST_F(StyleCascadeTest, InternalEffectiveZoomVsAll) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("-internal-effective-zoom:200%", CascadeOrigin::kUserAgent);
+ cascade.Add("all:initial");
cascade.Apply();
EXPECT_EQ(1.0f, cascade.TakeStyle()->EffectiveZoom());
}
TEST_F(StyleCascadeTest, ZoomReversedCascadeOrder) {
- CSSPropertyName effective_zoom(CSSPropertyID::kInternalEffectiveZoom);
TestCascade cascade(GetDocument());
- cascade.Add(effective_zoom, "initial");
- cascade.Add("zoom", "200%");
+ cascade.Add("-internal-effective-zoom:initial", CascadeOrigin::kUserAgent);
+ cascade.Add("zoom:200%", CascadeOrigin::kUserAgent);
cascade.Apply();
EXPECT_EQ(2.0f, cascade.TakeStyle()->EffectiveZoom());
}
-TEST_F(StyleCascadeTest, ZoomPriority) {
- CSSPropertyName effective_zoom(CSSPropertyID::kInternalEffectiveZoom);
+TEST_F(StyleCascadeTest, ZoomImportant) {
TestCascade cascade(GetDocument());
- cascade.Add("zoom", "200%", Origin::kImportantAuthor);
- cascade.Add(effective_zoom, "initial");
+ cascade.Add("zoom:200% !important", CascadeOrigin::kUserAgent);
+ cascade.Add("-internal-effective-zoom:initial", CascadeOrigin::kAuthor);
cascade.Apply();
EXPECT_EQ(2.0f, cascade.TakeStyle()->EffectiveZoom());
@@ -1893,14 +2034,77 @@ TEST_F(StyleCascadeTest, WritingModeReversedCascadeOrder) {
TEST_F(StyleCascadeTest, WritingModePriority) {
TestCascade cascade(GetDocument());
- cascade.Add("writing-mode", "vertical-lr", Origin::kImportantAuthor);
- cascade.Add("-webkit-writing-mode", "vertical-rl", Origin::kAuthor);
+ cascade.Add("writing-mode:vertical-lr !important", Origin::kAuthor);
+ cascade.Add("-webkit-writing-mode:vertical-rl", Origin::kAuthor);
cascade.Apply();
EXPECT_EQ("vertical-lr", cascade.ComputedValue("writing-mode"));
EXPECT_EQ("vertical-lr", cascade.ComputedValue("-webkit-writing-mode"));
}
+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))");
+
+ TestCascade cascade(GetDocument());
+ cascade.Add("-webkit-border-image", gradient1 + " round 40 / 10px / 20px",
+ Origin::kAuthor);
+ cascade.Add("border-image-source", gradient2, Origin::kAuthor);
+ cascade.Add("border-image-slice", "20", Origin::kAuthor);
+ cascade.Add("border-image-width", "6px", Origin::kAuthor);
+ cascade.Add("border-image-outset", "4px", Origin::kAuthor);
+ cascade.Add("border-image-repeat", "space", Origin::kAuthor);
+ cascade.Apply();
+
+ EXPECT_EQ(gradient2, cascade.ComputedValue("border-image-source"));
+ EXPECT_EQ("20", cascade.ComputedValue("border-image-slice"));
+ EXPECT_EQ("6px", cascade.ComputedValue("border-image-width"));
+ EXPECT_EQ("4px", cascade.ComputedValue("border-image-outset"));
+ EXPECT_EQ("space", cascade.ComputedValue("border-image-repeat"));
+}
+
+TEST_F(StyleCascadeTest, WebkitBorderImageReverseCascadeOrder) {
+ String gradient1("linear-gradient(rgb(0, 0, 0), rgb(0, 128, 0))");
+ String gradient2("linear-gradient(rgb(0, 0, 0), rgb(0, 200, 0))");
+
+ TestCascade cascade(GetDocument());
+ cascade.Add("border-image-source", gradient2, Origin::kAuthor);
+ cascade.Add("border-image-slice", "20", Origin::kAuthor);
+ cascade.Add("border-image-width", "6px", Origin::kAuthor);
+ cascade.Add("border-image-outset", "4px", Origin::kAuthor);
+ cascade.Add("border-image-repeat", "space", Origin::kAuthor);
+ cascade.Add("-webkit-border-image", gradient1 + " round 40 / 10px / 20px",
+ Origin::kAuthor);
+ cascade.Apply();
+
+ EXPECT_EQ(gradient1, cascade.ComputedValue("border-image-source"));
+ EXPECT_EQ("40 fill", cascade.ComputedValue("border-image-slice"));
+ EXPECT_EQ("10px", cascade.ComputedValue("border-image-width"));
+ EXPECT_EQ("20px", cascade.ComputedValue("border-image-outset"));
+ EXPECT_EQ("round", cascade.ComputedValue("border-image-repeat"));
+}
+
+TEST_F(StyleCascadeTest, WebkitBorderImageMixedOrder) {
+ String gradient1("linear-gradient(rgb(0, 0, 0), rgb(0, 128, 0))");
+ String gradient2("linear-gradient(rgb(0, 0, 0), rgb(0, 200, 0))");
+
+ TestCascade cascade(GetDocument());
+ cascade.Add("border-image-source", gradient2, Origin::kAuthor);
+ cascade.Add("border-image-width", "6px", Origin::kAuthor);
+ cascade.Add("-webkit-border-image", gradient1 + " round 40 / 10px / 20px",
+ Origin::kAuthor);
+ cascade.Add("border-image-slice", "20", Origin::kAuthor);
+ cascade.Add("border-image-outset", "4px", Origin::kAuthor);
+ cascade.Add("border-image-repeat", "space", Origin::kAuthor);
+ cascade.Apply();
+
+ EXPECT_EQ(gradient1, cascade.ComputedValue("border-image-source"));
+ EXPECT_EQ("20", cascade.ComputedValue("border-image-slice"));
+ EXPECT_EQ("10px", cascade.ComputedValue("border-image-width"));
+ EXPECT_EQ("4px", cascade.ComputedValue("border-image-outset"));
+ EXPECT_EQ("space", cascade.ComputedValue("border-image-repeat"));
+}
+
TEST_F(StyleCascadeTest, MarkReferenced) {
RegisterProperty(GetDocument(), "--x", "<length>", "0px", false);
RegisterProperty(GetDocument(), "--y", "<length>", "0px", false);
@@ -1916,15 +2120,63 @@ TEST_F(StyleCascadeTest, MarkReferenced) {
EXPECT_FALSE(registry->WasReferenced("--y"));
}
-TEST_F(StyleCascadeTest, InternalVisitedColorLonghand) {
- CSSPropertyName visited_color(CSSPropertyID::kInternalVisitedColor);
+TEST_F(StyleCascadeTest, MarkHasVariableReferenceLonghand) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("--x", "1px");
+ cascade.Add("width", "var(--x)");
+ cascade.Apply();
+ auto style = cascade.TakeStyle();
+ EXPECT_TRUE(style->HasVariableReferenceFromNonInheritedProperty());
+}
+
+TEST_F(StyleCascadeTest, MarkHasVariableReferenceShorthand) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("--x", "1px");
+ cascade.Add("margin", "var(--x)");
+ cascade.Apply();
+ auto style = cascade.TakeStyle();
+ EXPECT_TRUE(style->HasVariableReferenceFromNonInheritedProperty());
+}
+
+TEST_F(StyleCascadeTest, MarkHasVariableReferenceLonghandMissingVar) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("width", "var(--x)");
+ cascade.Apply();
+ auto style = cascade.TakeStyle();
+ EXPECT_TRUE(style->HasVariableReferenceFromNonInheritedProperty());
+}
+
+TEST_F(StyleCascadeTest, MarkHasVariableReferenceShorthandMissingVar) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("margin", "var(--x)");
+ cascade.Apply();
+ auto style = cascade.TakeStyle();
+ EXPECT_TRUE(style->HasVariableReferenceFromNonInheritedProperty());
+}
+TEST_F(StyleCascadeTest, NoMarkHasVariableReferenceInherited) {
TestCascade cascade(GetDocument());
- cascade.Add(visited_color, "red");
- cascade.Add("color", "green");
+ cascade.Add("color", "var(--x)");
cascade.Apply();
+ auto style = cascade.TakeStyle();
+ EXPECT_FALSE(style->HasVariableReferenceFromNonInheritedProperty());
+}
+
+TEST_F(StyleCascadeTest, NoMarkHasVariableReferenceWithoutVar) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("width", "1px");
+ cascade.Apply();
+ auto style = cascade.TakeStyle();
+ EXPECT_FALSE(style->HasVariableReferenceFromNonInheritedProperty());
+}
+
+TEST_F(StyleCascadeTest, InternalVisitedColorLonghand) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("color:green", CascadeOrigin::kAuthor);
+ cascade.Add("color:red", CascadeOrigin::kAuthor, CSSSelector::kMatchVisited);
cascade.State().Style()->SetInsideLink(EInsideLink::kInsideVisitedLink);
+ cascade.Apply();
EXPECT_EQ("rgb(0, 128, 0)", cascade.ComputedValue("color"));
@@ -1933,37 +2185,210 @@ TEST_F(StyleCascadeTest, InternalVisitedColorLonghand) {
EXPECT_EQ(red, cascade.TakeStyle()->VisitedDependentColor(color));
}
-TEST_F(StyleCascadeTest, VarInInternalVisitedShorthand) {
- CSSPropertyName visited_outline_color(
- CSSPropertyID::kInternalVisitedOutlineColor);
+TEST_F(StyleCascadeTest, VarInInternalVisitedColorShorthand) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("--x:red", CascadeOrigin::kAuthor);
+ cascade.Add("outline:medium solid var(--x)", CascadeOrigin::kAuthor,
+ CSSSelector::kMatchVisited);
+ cascade.Add("outline-color:green", CascadeOrigin::kAuthor,
+ CSSSelector::kMatchLink);
+
+ cascade.State().Style()->SetInsideLink(EInsideLink::kInsideVisitedLink);
+ cascade.Apply();
+
+ EXPECT_EQ("rgb(0, 128, 0)", cascade.ComputedValue("outline-color"));
+
+ Color red(255, 0, 0);
+ const CSSProperty& outline_color = GetCSSPropertyOutlineColor();
+ EXPECT_EQ(red, cascade.TakeStyle()->VisitedDependentColor(outline_color));
+}
+TEST_F(StyleCascadeTest, ApplyWithFilter) {
TestCascade cascade(GetDocument());
- cascade.Add("--x", "green");
- cascade.Add("outline", "medium solid var(--x)");
+ cascade.Add("color", "blue", Origin::kAuthor);
+ cascade.Add("background-color", "green", Origin::kAuthor);
+ cascade.Add("display", "inline", Origin::kAuthor);
+ cascade.Apply();
+ cascade.Add("color", "green", Origin::kAuthor);
+ cascade.Add("background-color", "red", Origin::kAuthor);
+ cascade.Add("display", "block", Origin::kAuthor);
+ cascade.Apply(CascadeFilter(CSSProperty::kInherited, false));
+ EXPECT_EQ("rgb(0, 128, 0)", cascade.ComputedValue("color"));
+ EXPECT_EQ("rgb(0, 128, 0)", cascade.ComputedValue("background-color"));
+ EXPECT_EQ("inline", cascade.ComputedValue("display"));
+}
+
+TEST_F(StyleCascadeTest, HasAuthorBackground) {
+ Vector<String> properties = {"background-attachment"/*, "background-blend-mode",
+ "background-clip", "background-image",
+ "background-origin", "background-position-x",
+ "background-position-y", "background-size"*/};
- // Copy pending substitution value from outline-color to
- // -internal-visited-outline-color, approximating StyleResolver's behavior
- // for :visited declarations.
- const CSSValue* pending_substitution = cascade.GetCSSValue("outline-color");
- ASSERT_TRUE(pending_substitution);
- cascade.Add(visited_outline_color, pending_substitution);
- cascade.Add("outline-color", "red");
+ for (String property : properties) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("-webkit-appearance", "button", Origin::kUserAgent);
+ cascade.Add(property, "unset", Origin::kAuthor);
+ cascade.Apply();
+ EXPECT_TRUE(cascade.TakeStyle()->HasAuthorBackground());
+ }
+}
- // Apply "outline-color" manually first, to ensure that
- // -internal-visited-outline-color is applied afterwards.
- cascade.Apply("outline-color");
+TEST_F(StyleCascadeTest, HasAuthorBorder) {
+ Vector<String> properties = {
+ "border-top-color", "border-right-color",
+ "border-bottom-color", "border-left-color",
+ "border-top-style", "border-right-style",
+ "border-bottom-style", "border-left-style",
+ "border-top-width", "border-right-width",
+ "border-bottom-width", "border-left-width",
+ "border-top-left-radius", "border-top-right-radius",
+ "border-bottom-left-radius", "border-bottom-right-radius",
+ "border-image-source", "border-image-slice",
+ "border-image-width", "border-image-outset",
+ "border-image-repeat"};
+
+ for (String property : properties) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("-webkit-appearance", "button", Origin::kUserAgent);
+ cascade.Add(property, "unset", Origin::kAuthor);
+ cascade.Apply();
+ EXPECT_TRUE(cascade.TakeStyle()->HasAuthorBorder());
+ }
+}
- // When applying -internal-visited-outline-color, it should not modify
- // outline-color.
+TEST_F(StyleCascadeTest, NoAuthorBackgroundOrBorder) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("-webkit-appearance", "button", Origin::kUserAgent);
+ cascade.Add("background-color", "red", Origin::kUserAgent);
+ cascade.Add("border-left-color", "green", Origin::kUserAgent);
+ cascade.Add("background-clip", "padding-box", Origin::kUser);
+ cascade.Add("border-right-color", "green", Origin::kUser);
cascade.Apply();
+ auto style = cascade.TakeStyle();
+ EXPECT_FALSE(style->HasAuthorBackground());
+ EXPECT_FALSE(style->HasAuthorBorder());
+}
- cascade.State().Style()->SetInsideLink(EInsideLink::kInsideVisitedLink);
+TEST_F(StyleCascadeTest, AnalyzeMatchResult) {
+ auto ua = CascadeOrigin::kUserAgent;
+ auto author = CascadeOrigin::kAuthor;
- EXPECT_EQ("rgb(255, 0, 0)", cascade.ComputedValue("outline-color"));
+ TestCascade cascade(GetDocument());
+ cascade.Add("display:none;left:5px", ua);
+ cascade.Add("font-size:1px !important", ua);
+ cascade.Add("display:block;color:red", author);
+ cascade.Add("font-size:3px", author);
+ cascade.Apply();
- Color green(0, 128, 0);
- const CSSProperty& outline_color = GetCSSPropertyOutlineColor();
- EXPECT_EQ(green, cascade.TakeStyle()->VisitedDependentColor(outline_color));
+ EXPECT_EQ(cascade.GetPriority("display").GetOrigin(), author);
+ EXPECT_EQ(cascade.GetPriority("left").GetOrigin(), ua);
+ EXPECT_EQ(cascade.GetPriority("color").GetOrigin(), author);
+ EXPECT_EQ(cascade.GetPriority("font-size").GetOrigin(), ua);
+}
+
+TEST_F(StyleCascadeTest, AnalyzeMatchResultAll) {
+ auto ua = CascadeOrigin::kUserAgent;
+ auto author = CascadeOrigin::kAuthor;
+
+ TestCascade cascade(GetDocument());
+ cascade.Add("display:block", ua);
+ cascade.Add("font-size:1px !important", ua);
+ cascade.Add("all:unset", author);
+ cascade.Apply();
+
+ EXPECT_EQ(cascade.GetPriority("display").GetOrigin(), author);
+ EXPECT_EQ(cascade.GetPriority("font-size").GetOrigin(), ua);
+
+ // Random sample from another property affected by 'all'.
+ EXPECT_EQ(cascade.GetPriority("color").GetOrigin(), author);
+ EXPECT_EQ(cascade.GetPriority("color"), cascade.GetPriority("display"));
+}
+
+TEST_F(StyleCascadeTest, ApplyMatchResultFilter) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("display:block");
+ cascade.Add("color:green");
+ cascade.Add("font-size:3px");
+ cascade.Apply();
+
+ cascade.Add("display:inline");
+ cascade.Add("color:red");
+ cascade.Apply(CascadeFilter(CSSProperty::kInherited, true));
+
+ EXPECT_EQ("inline", cascade.ComputedValue("display"));
+ EXPECT_EQ("rgb(0, 128, 0)", cascade.ComputedValue("color"));
+ EXPECT_EQ("3px", cascade.ComputedValue("font-size"));
+}
+
+TEST_F(StyleCascadeTest, ApplyMatchResultAllFilter) {
+ TestCascade cascade(GetDocument());
+ cascade.Add("color:green");
+ cascade.Add("display:block");
+ cascade.Apply();
+
+ cascade.Add("all:unset");
+ cascade.Apply(CascadeFilter(CSSProperty::kInherited, true));
+
+ EXPECT_EQ("rgb(0, 128, 0)", cascade.ComputedValue("color"));
+ EXPECT_EQ("inline", cascade.ComputedValue("display"));
+}
+
+TEST_F(StyleCascadeTest, MarkHasReferenceLonghand) {
+ TestCascade cascade(GetDocument());
+
+ cascade.Add("--x:red");
+ cascade.Add("background-color:var(--x)");
+ cascade.Apply();
+
+ EXPECT_TRUE(cascade.State()
+ .StyleRef()
+ .HasVariableReferenceFromNonInheritedProperty());
+}
+
+TEST_F(StyleCascadeTest, MarkHasReferenceShorthand) {
+ TestCascade cascade(GetDocument());
+
+ cascade.Add("--x:red");
+ cascade.Add("background:var(--x)");
+ cascade.Apply();
+
+ EXPECT_TRUE(cascade.State()
+ .StyleRef()
+ .HasVariableReferenceFromNonInheritedProperty());
+}
+
+TEST_F(StyleCascadeTest, NoMarkHasReferenceForInherited) {
+ TestCascade cascade(GetDocument());
+
+ cascade.Add("--x:red");
+ cascade.Add("--y:caption");
+ cascade.Add("color:var(--x)");
+ cascade.Add("font:var(--y)");
+ cascade.Apply();
+
+ EXPECT_FALSE(cascade.State()
+ .StyleRef()
+ .HasVariableReferenceFromNonInheritedProperty());
+}
+
+TEST_F(StyleCascadeTest, Reset) {
+ TestCascade cascade(GetDocument());
+
+ EXPECT_EQ(CascadePriority(), cascade.GetPriority("color"));
+ EXPECT_EQ(CascadePriority(), cascade.GetPriority("--x"));
+
+ cascade.Add("color:red");
+ cascade.Add("--x:red");
+ cascade.Apply(); // generation=1
+ cascade.Apply(); // generation=2
+
+ EXPECT_EQ(2u, cascade.GetPriority("color").GetGeneration());
+ EXPECT_EQ(2u, cascade.GetPriority("--x").GetGeneration());
+
+ cascade.Reset();
+
+ EXPECT_EQ(CascadePriority(), cascade.GetPriority("color"));
+ EXPECT_EQ(CascadePriority(), cascade.GetPriority("--x"));
}
} // 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 f5601fe254d..4b487f15cc4 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
@@ -45,7 +45,6 @@
#include "third_party/blink/renderer/core/css/css_identifier_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_pending_interpolation_value.h"
#include "third_party/blink/renderer/core/css/css_property_names.h"
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
#include "third_party/blink/renderer/core/css/css_reflect_value.h"
@@ -68,7 +67,6 @@
#include "third_party/blink/renderer/core/css/resolver/scoped_style_resolver.h"
#include "third_party/blink/renderer/core/css/resolver/selector_filter_parent_scope.h"
#include "third_party/blink/renderer/core/css/resolver/style_adjuster.h"
-#include "third_party/blink/renderer/core/css/resolver/style_animator.h"
#include "third_party/blink/renderer/core/css/resolver/style_builder_converter.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver_stats.h"
@@ -114,9 +112,15 @@ void SetAnimationUpdateIfNeeded(StyleResolverState& state, Element& element) {
// If any changes to CSS Animations were detected, stash the update away for
// application after the layout object is updated if we're in the appropriate
// scope.
- if (!state.AnimationUpdate().IsEmpty())
- element.EnsureElementAnimations().CssAnimations().SetPendingUpdate(
+ if (!state.AnimationUpdate().IsEmpty()) {
+ auto& element_animations = element.EnsureElementAnimations();
+ element_animations.CssAnimations().SetPendingUpdate(
state.AnimationUpdate());
+ if (state.HasImportantOverrides())
+ element_animations.SetHasImportantOverrides();
+ if (state.HasFontAffectingAnimation())
+ element_animations.SetHasFontAffectingAnimation();
+ }
}
bool HasAnimationsOrTransitions(const StyleResolverState& state) {
@@ -125,6 +129,61 @@ bool HasAnimationsOrTransitions(const StyleResolverState& state) {
state.GetAnimatingElement()->HasAnimations());
}
+bool ShouldComputeBaseComputedStyle(const ComputedStyle* base_computed_style) {
+#if DCHECK_IS_ON()
+ // The invariant in the base computed style optimization is that as long as
+ // |IsAnimationStyleChange| is true, the computed style that would be
+ // generated by the style resolver is equivalent to the one we hold
+ // internally. To ensure this, we always compute a new style here disregarding
+ // the fact that we have a base computed style when DCHECKs are enabled, and
+ // call ValidateBaseComputedStyle() to check that the optimization was sound.
+ return true;
+#else
+ return !base_computed_style;
+#endif // !DCHECK_IS_ON()
+}
+
+// Compare the base computed style with the one we compute to validate that the
+// optimization is sound.
+bool ValidateBaseComputedStyle(const ComputedStyle* base_computed_style,
+ const ComputedStyle& computed_style) {
+#if DCHECK_IS_ON()
+ if (!base_computed_style)
+ return true;
+ // Under certain conditions ComputedStyle::operator==() may return false for
+ // differences that are permitted during an animation.
+ // The FontFaceCache version number may be increased without forcing a style
+ // recalc (see crbug.com/471079).
+ if (!base_computed_style->GetFont().IsFallbackValid())
+ return true;
+ // Images use instance equality rather than value equality (see
+ // crbug.com/781461).
+ for (CSSPropertyID id :
+ {CSSPropertyID::kBackgroundImage, CSSPropertyID::kWebkitMaskImage}) {
+ if (!CSSPropertyEquality::PropertiesEqual(
+ PropertyHandle(CSSProperty::Get(id)), *base_computed_style,
+ computed_style)) {
+ return true;
+ }
+ }
+ return *base_computed_style == computed_style;
+#else
+ return true;
+#endif // DCHECK_IS_ON()
+}
+
+// When force-computing the base computed style for validation purposes,
+// we need to reset the StyleCascade when the base computed style optimization
+// is used. This is because we don't want the computation of the base to
+// populate the cascade, as they are supposed to be empty when the optimization
+// is in use. This is to match the behavior of non-DCHECK builds.
+void MaybeResetCascade(StyleCascade* cascade) {
+#if DCHECK_IS_ON()
+ if (cascade)
+ cascade->Reset();
+#endif // DCHECK_IS_ON()
+}
+
} // namespace
static CSSPropertyValueSet* LeftToRightDeclaration() {
@@ -696,6 +755,8 @@ scoped_refptr<ComputedStyle> StyleResolver::StyleForViewport(
viewport_style->SetOverflowX(EOverflow::kAuto);
viewport_style->SetOverflowY(EOverflow::kAuto);
+ document.GetStyleEngine().ApplyVisionDeficiencyStyle(viewport_style);
+
return viewport_style;
}
@@ -763,79 +824,114 @@ scoped_refptr<ComputedStyle> StyleResolver::StyleForElement(
bool can_cache_animation_base_computed_style =
!default_parent && !default_layout_parent &&
matching_behavior == kMatchAllRules;
- const ComputedStyle* animation_base_computed_style =
- can_cache_animation_base_computed_style
- ? CachedAnimationBaseComputedStyle(state)
- : nullptr;
- if (animation_base_computed_style) {
- state.SetStyle(ComputedStyle::Clone(*animation_base_computed_style));
- if (!state.ParentStyle()) {
- state.SetParentStyle(InitialStyleForElement(GetDocument()));
- state.SetLayoutParentStyle(state.ParentStyle());
- }
- } else {
- if (state.ParentStyle()) {
- scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
- style->InheritFrom(*state.ParentStyle(),
- IsAtShadowBoundary(element)
- ? ComputedStyle::kAtShadowBoundary
- : ComputedStyle::kNotAtShadowBoundary);
- state.SetStyle(std::move(style));
- } else {
- state.SetStyle(InitialStyleForElement(GetDocument()));
- state.SetParentStyle(ComputedStyle::Clone(*state.Style()));
- state.SetLayoutParentStyle(state.ParentStyle());
- if (element != GetDocument().documentElement()) {
- // Strictly, we should only allow the root element to inherit from
- // initial styles, but we allow getComputedStyle() for connected
- // elements outside the flat tree rooted at an unassigned shadow host
- // child, or Shadow DOM V0 insertion points.
- DCHECK(element->IsV0InsertionPoint() ||
- (IsShadowHost(element->parentNode()) &&
- !LayoutTreeBuilderTraversal::ParentElement(*element)));
- state.Style()->SetIsEnsuredOutsideFlatTree();
- }
- }
+ STACK_UNINITIALIZED StyleCascade cascade(state);
+ StyleCascade* cascade_ptr =
+ RuntimeEnabledFeatures::CSSCascadeEnabled() ? &cascade : nullptr;
+
+ ApplyBaseComputedStyle(element, state, cascade_ptr,
+ cascade.MutableMatchResult(), matching_behavior,
+ can_cache_animation_base_computed_style);
+
+ if (ApplyAnimatedStandardProperties(state, cascade_ptr)) {
+ INCREMENT_STYLE_STATS_COUNTER(GetDocument().GetStyleEngine(),
+ styles_animated, 1);
+ StyleAdjuster::AdjustComputedStyle(state, element);
}
- // contenteditable attribute (implemented by -webkit-user-modify) should
- // be propagated from shadow host to distributed node.
- if (state.DistributedToV0InsertionPoint() || element->AssignedSlot()) {
- if (Element* parent = element->parentElement()) {
- if (const ComputedStyle* style_of_shadow_host =
- parent->GetComputedStyle()) {
- state.Style()->SetUserModify(style_of_shadow_host->UserModify());
+ if (IsA<HTMLBodyElement>(*element))
+ GetDocument().GetTextLinkColors().SetTextColor(state.Style()->GetColor());
+
+ SetAnimationUpdateIfNeeded(state, *element);
+
+ if (state.Style()->HasViewportUnits())
+ GetDocument().SetHasViewportUnits();
+
+ if (state.Style()->HasRemUnits())
+ GetDocument().GetStyleEngine().SetUsesRemUnit(true);
+
+ if (state.Style()->HasGlyphRelativeUnits())
+ UseCounter::Count(GetDocument(), WebFeature::kHasGlyphRelativeUnits);
+
+ // Now return the style.
+ return state.TakeStyle();
+}
+
+void StyleResolver::InitStyleAndApplyInheritance(Element& element,
+ StyleResolverState& state) {
+ if (state.ParentStyle()) {
+ scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
+ style->InheritFrom(*state.ParentStyle(),
+ IsAtShadowBoundary(&element)
+ ? ComputedStyle::kAtShadowBoundary
+ : ComputedStyle::kNotAtShadowBoundary);
+ state.SetStyle(std::move(style));
+
+ // contenteditable attribute (implemented by -webkit-user-modify) should
+ // be propagated from shadow host to distributed node.
+ if (state.DistributedToV0InsertionPoint() || element.AssignedSlot()) {
+ if (Element* parent = element.parentElement()) {
+ if (const ComputedStyle* shadow_host_style = parent->GetComputedStyle())
+ state.Style()->SetUserModify(shadow_host_style->UserModify());
}
}
+ } else {
+ state.SetStyle(InitialStyleForElement(GetDocument()));
+ state.SetParentStyle(ComputedStyle::Clone(*state.Style()));
+ state.SetLayoutParentStyle(state.ParentStyle());
+ if (element != GetDocument().documentElement()) {
+ // Strictly, we should only allow the root element to inherit from
+ // initial styles, but we allow getComputedStyle() for connected
+ // elements outside the flat tree rooted at an unassigned shadow host
+ // child, or Shadow DOM V0 insertion points.
+ DCHECK(element.IsV0InsertionPoint() ||
+ (IsShadowHost(element.parentNode()) &&
+ !LayoutTreeBuilderTraversal::ParentElement(element)));
+ state.Style()->SetIsEnsuredOutsideFlatTree();
+ }
}
- if (element->IsLink()) {
+ if (element.IsLink()) {
state.Style()->SetIsLink();
EInsideLink link_state = state.ElementLinkState();
if (link_state != EInsideLink::kNotInsideLink) {
bool force_visited = false;
- probe::ForcePseudoState(element, CSSSelector::kPseudoVisited,
+ probe::ForcePseudoState(&element, CSSSelector::kPseudoVisited,
&force_visited);
if (force_visited)
link_state = EInsideLink::kInsideVisitedLink;
}
state.Style()->SetInsideLink(link_state);
}
+}
+
+void StyleResolver::ApplyBaseComputedStyle(
+ Element* element,
+ StyleResolverState& state,
+ StyleCascade* cascade,
+ MatchResult& match_result,
+ RuleMatchingBehavior matching_behavior,
+ bool can_cache_animation_base_computed_style) {
+ const ComputedStyle* animation_base_computed_style =
+ can_cache_animation_base_computed_style
+ ? CachedAnimationBaseComputedStyle(state)
+ : nullptr;
+
+ if (ShouldComputeBaseComputedStyle(animation_base_computed_style)) {
+ InitStyleAndApplyInheritance(*element, state);
- if (!animation_base_computed_style) {
GetDocument().GetStyleEngine().EnsureUAStyleForElement(*element);
ElementRuleCollector collector(state.ElementContext(), selector_filter_,
- state.Style());
+ match_result, state.Style(),
+ state.Style()->InsideLink());
MatchAllRules(state, collector,
matching_behavior != kMatchAllRulesExcludingSMIL);
// TODO(dominicc): Remove this counter when Issue 590014 is fixed.
if (element->HasTagName(html_names::kSummaryTag)) {
- MatchedPropertiesRange matched_range =
- collector.MatchedResult().AuthorRules();
+ MatchedPropertiesRange matched_range = match_result.AuthorRules();
for (const auto& matched : matched_range) {
const CSSValue* value =
matched.properties->GetPropertyCSSValue(CSSPropertyID::kDisplay);
@@ -866,7 +962,13 @@ scoped_refptr<ComputedStyle> StyleResolver::StyleForElement(
if (state.HasDirAutoAttribute())
state.Style()->SetSelfOrAncestorHasDirAutoAttribute(true);
- ApplyMatchedProperties(state, collector.MatchedResult());
+ if (RuntimeEnabledFeatures::CSSCascadeEnabled()) {
+ DCHECK(cascade);
+ CascadeAndApplyMatchedProperties(state, *cascade);
+ } else {
+ ApplyMatchedProperties(state, match_result);
+ }
+
ApplyCallbackSelectors(state);
// Cache our original display.
@@ -874,39 +976,24 @@ scoped_refptr<ComputedStyle> StyleResolver::StyleForElement(
StyleAdjuster::AdjustComputedStyle(state, element);
- if (can_cache_animation_base_computed_style)
- UpdateAnimationBaseComputedStyle(state);
- } else {
- INCREMENT_STYLE_STATS_COUNTER(GetDocument().GetStyleEngine(),
- base_styles_used, 1);
+ if (can_cache_animation_base_computed_style) {
+ DCHECK(ValidateBaseComputedStyle(animation_base_computed_style,
+ *state.Style()));
+ if (!animation_base_computed_style)
+ UpdateAnimationBaseComputedStyle(state);
+ }
}
- // FIXME: The CSSWG wants to specify that the effects of animations are
- // applied before important rules, but this currently happens here as we
- // require adjustment to have happened before deciding which properties to
- // transition.
- if (ApplyAnimatedStandardProperties(state)) {
+ if (animation_base_computed_style) {
+ state.SetStyle(ComputedStyle::Clone(*animation_base_computed_style));
+ if (!state.ParentStyle()) {
+ state.SetParentStyle(InitialStyleForElement(GetDocument()));
+ state.SetLayoutParentStyle(state.ParentStyle());
+ }
+ MaybeResetCascade(cascade);
INCREMENT_STYLE_STATS_COUNTER(GetDocument().GetStyleEngine(),
- styles_animated, 1);
- StyleAdjuster::AdjustComputedStyle(state, element);
+ base_styles_used, 1);
}
-
- if (IsA<HTMLBodyElement>(*element))
- GetDocument().GetTextLinkColors().SetTextColor(state.Style()->GetColor());
-
- SetAnimationUpdateIfNeeded(state, *element);
-
- if (state.Style()->HasViewportUnits())
- GetDocument().SetHasViewportUnits();
-
- if (state.Style()->HasRemUnits())
- GetDocument().GetStyleEngine().SetUsesRemUnit(true);
-
- if (state.Style()->HasGlyphRelativeUnits())
- UseCounter::Count(GetDocument(), WebFeature::kHasGlyphRelativeUnits);
-
- // Now return the style.
- return state.TakeStyle();
}
CompositorKeyframeValue* StyleResolver::CreateCompositorKeyframeValueSnapshot(
@@ -922,15 +1009,17 @@ CompositorKeyframeValue* StyleResolver::CreateCompositorKeyframeValueSnapshot(
state.SetStyle(ComputedStyle::Clone(base_style));
if (value) {
if (RuntimeEnabledFeatures::CSSCascadeEnabled()) {
- StyleCascade cascade(state);
- auto name = property.GetCSSPropertyName();
- cascade.Add(name, value, StyleCascade::Origin::kAuthor);
+ STACK_UNINITIALIZED StyleCascade cascade(state);
+ auto* set = MakeGarbageCollected<MutableCSSPropertyValueSet>(
+ state.GetParserMode());
+ set->SetProperty(property.GetCSSProperty().PropertyID(), *value);
+ cascade.MutableMatchResult().FinishAddingUARules();
+ cascade.MutableMatchResult().FinishAddingUserRules();
+ cascade.MutableMatchResult().AddMatchedProperties(set);
cascade.Apply();
} else {
StyleBuilder::ApplyProperty(property.GetCSSPropertyName(), state, *value);
- state.GetFontBuilder().CreateFont(
- state.GetDocument().GetStyleEngine().GetFontSelector(),
- state.StyleRef());
+ state.GetFontBuilder().CreateFont(state.StyleRef(), parent_style);
CSSVariableResolver(state).ResolveVariableDefinitions();
}
}
@@ -951,39 +1040,52 @@ bool StyleResolver::PseudoStyleForElementInternal(
const ComputedStyle* animation_base_computed_style =
CachedAnimationBaseComputedStyle(state);
- if (animation_base_computed_style) {
- state.SetStyle(ComputedStyle::Clone(*animation_base_computed_style));
- } else if (pseudo_style_request.AllowsInheritance(state.ParentStyle())) {
- scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
- style->InheritFrom(*state.ParentStyle());
- state.SetStyle(std::move(style));
- } else {
- // ::backdrop inherits from initial styles. All other pseudo elements
- // inherit from their originating element (::before/::after), or originating
- // element descendants (::first-line/::first-letter).
- DCHECK(pseudo_style_request.pseudo_id == kPseudoIdBackdrop);
- state.SetStyle(InitialStyleForElement(GetDocument()));
- state.SetParentStyle(ComputedStyle::Clone(*state.Style()));
- }
-
- state.Style()->SetStyleType(pseudo_style_request.pseudo_id);
-
// Since we don't use pseudo-elements in any of our quirk/print
// user agent rules, don't waste time walking those rules.
- if (!animation_base_computed_style) {
+ STACK_UNINITIALIZED StyleCascade cascade(state);
+ StyleCascade* cascade_ptr =
+ RuntimeEnabledFeatures::CSSCascadeEnabled() ? &cascade : nullptr;
+
+ if (ShouldComputeBaseComputedStyle(animation_base_computed_style)) {
+ if (pseudo_style_request.AllowsInheritance(state.ParentStyle())) {
+ scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
+ style->InheritFrom(*state.ParentStyle());
+ state.SetStyle(std::move(style));
+ } else {
+ // ::backdrop inherits from initial styles. All other pseudo elements
+ // inherit from their originating element (::before/::after), or
+ // originating element descendants (::first-line/::first-letter).
+ DCHECK(pseudo_style_request.pseudo_id == kPseudoIdBackdrop);
+ state.SetStyle(InitialStyleForElement(GetDocument()));
+ state.SetParentStyle(ComputedStyle::Clone(*state.Style()));
+ }
+ state.Style()->SetStyleType(pseudo_style_request.pseudo_id);
+
// Check UA, user and author rules.
ElementRuleCollector collector(state.ElementContext(), selector_filter_,
- state.Style());
+ cascade.MutableMatchResult(), state.Style(),
+ 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) {
+ // Set 'unicode-bidi: isolate'
state.Style()->SetUnicodeBidi(UnicodeBidi::kIsolate);
- state.Style()->SetFontVariantNumericSpacing(
- FontVariantNumeric::kTabularNums);
+
+ // Set 'font-variant-numeric: tabular-nums'
+ FontVariantNumeric variant_numeric;
+ variant_numeric.SetNumericSpacing(FontVariantNumeric::kTabularNums);
+ state.GetFontBuilder().SetVariantNumeric(variant_numeric);
+ UpdateFont(state);
+
+ // Don't bother matching rules if there is no style for ::marker
+ if (!state.ParentStyle()->HasPseudoElementStyle(kPseudoIdMarker)) {
+ StyleAdjuster::AdjustComputedStyle(state, nullptr);
+ return true;
+ }
}
MatchUARules(collector);
@@ -994,10 +1096,16 @@ bool StyleResolver::PseudoStyleForElementInternal(
if (tracker_)
AddMatchedRulesToTracker(collector);
- if (!collector.MatchedResult().HasMatchedProperties())
+ if (!collector.MatchedResult().HasMatchedProperties()) {
+ StyleAdjuster::AdjustComputedStyle(state, nullptr);
return false;
+ }
+
+ if (RuntimeEnabledFeatures::CSSCascadeEnabled())
+ CascadeAndApplyMatchedProperties(state, cascade);
+ else
+ ApplyMatchedProperties(state, cascade.GetMatchResult());
- ApplyMatchedProperties(state, collector.MatchedResult());
ApplyCallbackSelectors(state);
// Cache our original display.
@@ -1007,14 +1115,20 @@ bool StyleResolver::PseudoStyleForElementInternal(
// in the StyleAdjuster::AdjustComputedStyle code.
StyleAdjuster::AdjustComputedStyle(state, nullptr);
- UpdateAnimationBaseComputedStyle(state);
+ DCHECK(ValidateBaseComputedStyle(animation_base_computed_style,
+ *state.Style()));
+
+ if (!animation_base_computed_style)
+ UpdateAnimationBaseComputedStyle(state);
}
- // FIXME: The CSSWG wants to specify that the effects of animations are
- // applied before important rules, but this currently happens here as we
- // require adjustment to have happened before deciding which properties to
- // transition.
- if (ApplyAnimatedStandardProperties(state))
+ if (animation_base_computed_style) {
+ state.SetStyle(ComputedStyle::Clone(*animation_base_computed_style));
+ state.Style()->SetStyleType(pseudo_style_request.pseudo_id);
+ MaybeResetCascade(cascade_ptr);
+ }
+
+ if (ApplyAnimatedStandardProperties(state, cascade_ptr))
StyleAdjuster::AdjustComputedStyle(state, nullptr);
GetDocument().GetStyleEngine().IncStyleForElementCount();
@@ -1073,7 +1187,10 @@ scoped_refptr<const ComputedStyle> StyleResolver::StyleForPage(int page_index) {
style->InheritFrom(*root_element_style);
state.SetStyle(std::move(style));
- PageRuleCollector collector(root_element_style, page_index);
+ STACK_UNINITIALIZED StyleCascade cascade(state);
+
+ PageRuleCollector collector(root_element_style, page_index,
+ cascade.MutableMatchResult());
collector.MatchPageRules(
CSSDefaultStyleSheets::Instance().DefaultPrintStyle());
@@ -1086,16 +1203,21 @@ scoped_refptr<const ComputedStyle> StyleResolver::StyleForPage(int page_index) {
NeedsApplyPass needs_apply_pass;
const MatchResult& result = collector.MatchedResult();
- ApplyMatchedProperties<kAnimationPropertyPriority, kUpdateNeedsApplyPass>(
- state, result.AllRules(), false, inherited_only, needs_apply_pass);
- ApplyMatchedProperties<kHighPropertyPriority, kCheckNeedsApplyPass>(
- state, result.AllRules(), false, inherited_only, needs_apply_pass);
- // If our font got dirtied, go ahead and update it now.
- UpdateFont(state);
+ if (RuntimeEnabledFeatures::CSSCascadeEnabled()) {
+ cascade.Apply();
+ } else {
+ ApplyMatchedProperties<kAnimationPropertyPriority, kUpdateNeedsApplyPass>(
+ state, result.AllRules(), false, inherited_only, needs_apply_pass);
+ ApplyMatchedProperties<kHighPropertyPriority, kCheckNeedsApplyPass>(
+ state, result.AllRules(), false, inherited_only, needs_apply_pass);
- ApplyMatchedProperties<kLowPropertyPriority, kCheckNeedsApplyPass>(
- state, result.AllRules(), false, inherited_only, needs_apply_pass);
+ // If our font got dirtied, go ahead and update it now.
+ UpdateFont(state);
+
+ ApplyMatchedProperties<kLowPropertyPriority, kCheckNeedsApplyPass>(
+ state, result.AllRules(), false, inherited_only, needs_apply_pass);
+ }
LoadPendingResources(state);
@@ -1146,8 +1268,7 @@ scoped_refptr<const ComputedStyle> StyleResolver::StyleForText(
}
void StyleResolver::UpdateFont(StyleResolverState& state) {
- state.GetFontBuilder().CreateFont(
- GetDocument().GetStyleEngine().GetFontSelector(), state.StyleRef());
+ state.GetFontBuilder().CreateFont(state.StyleRef(), state.ParentStyle());
state.SetConversionFontSizes(CSSToLengthConversionData::FontSizes(
state.Style(), state.RootElementStyle()));
state.SetConversionZoom(state.Style()->EffectiveZoom());
@@ -1162,8 +1283,10 @@ StyleRuleList* StyleResolver::StyleRulesForElement(Element* element,
unsigned rules_to_include) {
DCHECK(element);
StyleResolverState state(GetDocument(), *element);
+ MatchResult match_result;
ElementRuleCollector collector(state.ElementContext(), selector_filter_,
- state.Style());
+ match_result, state.Style(),
+ EInsideLink::kNotInsideLink);
collector.SetMode(SelectorChecker::kCollectingStyleRules);
CollectPseudoRulesForElement(*element, collector, kPseudoIdNone,
rules_to_include);
@@ -1176,8 +1299,10 @@ RuleIndexList* StyleResolver::PseudoCSSRulesForElement(
unsigned rules_to_include) {
DCHECK(element);
StyleResolverState state(GetDocument(), *element);
+ MatchResult match_result;
ElementRuleCollector collector(state.ElementContext(), selector_filter_,
- state.Style());
+ match_result, state.Style(),
+ EInsideLink::kNotInsideLink);
collector.SetMode(SelectorChecker::kCollectingCSSRules);
CollectPseudoRulesForElement(*element, collector, pseudo_id,
rules_to_include);
@@ -1211,7 +1336,9 @@ void StyleResolver::CollectPseudoRulesForElement(
}
}
-bool StyleResolver::ApplyAnimatedStandardProperties(StyleResolverState& state) {
+bool StyleResolver::ApplyAnimatedStandardProperties(
+ StyleResolverState& state,
+ StyleCascade* cascade) {
Element& element = state.GetElement();
// The animating element may be this element, the pseudo element we are
@@ -1222,12 +1349,12 @@ bool StyleResolver::ApplyAnimatedStandardProperties(StyleResolverState& state) {
DCHECK(animating_element == &element || !animating_element ||
animating_element->ParentOrShadowHostElement() == element);
- if (state.Style()->Animations() ||
- (animating_element && animating_element->HasAnimations())) {
- if (!state.IsAnimationInterpolationMapReady())
- CalculateAnimationUpdate(state);
- } else if (!state.Style()->Transitions()) {
+ if (!HasAnimationsOrTransitions(state))
return false;
+
+ if (!state.IsAnimationInterpolationMapReady() ||
+ RuntimeEnabledFeatures::CSSCascadeEnabled()) {
+ CalculateAnimationUpdate(state);
}
CSSAnimations::CalculateCompositorAnimationUpdate(
@@ -1243,36 +1370,43 @@ bool StyleResolver::ApplyAnimatedStandardProperties(StyleResolverState& state) {
if (state.AnimationUpdate().IsEmpty())
return false;
- const ActiveInterpolationsMap& animations_map =
+ const ActiveInterpolationsMap& standard_animations =
state.AnimationUpdate().ActiveInterpolationsForStandardAnimations();
- const ActiveInterpolationsMap& transitions_map =
+ const ActiveInterpolationsMap& standard_transitions =
state.AnimationUpdate().ActiveInterpolationsForStandardTransitions();
+ const ActiveInterpolationsMap& custom_animations =
+ state.AnimationUpdate().ActiveInterpolationsForCustomAnimations();
+ const ActiveInterpolationsMap& custom_transitions =
+ state.AnimationUpdate().ActiveInterpolationsForCustomTransitions();
if (RuntimeEnabledFeatures::CSSCascadeEnabled()) {
- // TODO(crbug.com/985049): Use main cascade.
- //
- // For now, we use a dedicated cascade for animation of standard properties.
- // A StyleCascade is required, because otherwise we can't resolve any var()
- // references that may appear in keyframes. Ultimately, we should use ONE
- // cascade for everything, but this is not yet possible.
- using Origin = StyleCascade::Origin;
- StyleCascade cascade(state);
- StyleAnimator animator(state, cascade);
- CascadeInterpolations(cascade, animations_map, Origin::kAnimation);
- CascadeInterpolations(cascade, transitions_map, Origin::kTransition);
- cascade.Apply(animator);
+ DCHECK(cascade);
+ cascade->AddInterpolations(&standard_animations, CascadeOrigin::kAnimation);
+ cascade->AddInterpolations(&standard_transitions,
+ CascadeOrigin::kTransition);
+ cascade->AddInterpolations(&custom_animations, CascadeOrigin::kAnimation);
+ cascade->AddInterpolations(&custom_transitions, CascadeOrigin::kTransition);
+
+ CascadeFilter filter;
+ if (IsForcedColorsModeEnabled(state))
+ filter = filter.Add(CSSProperty::kIsAffectedByForcedColors, true);
+ if (state.Style()->StyleType() == kPseudoIdMarker)
+ filter = filter.Add(CSSProperty::kValidForMarker, false);
+ filter = filter.Add(CSSProperty::kAnimation, true);
+
+ cascade->Apply(filter);
} else {
ApplyAnimatedStandardProperties<kHighPropertyPriority>(state,
- animations_map);
- ApplyAnimatedStandardProperties<kHighPropertyPriority>(state,
- transitions_map);
+ standard_animations);
+ ApplyAnimatedStandardProperties<kHighPropertyPriority>(
+ state, standard_transitions);
UpdateFont(state);
ApplyAnimatedStandardProperties<kLowPropertyPriority>(state,
- animations_map);
+ standard_animations);
ApplyAnimatedStandardProperties<kLowPropertyPriority>(state,
- transitions_map);
+ standard_transitions);
}
// Start loading resources used by animations.
@@ -1308,6 +1442,23 @@ StyleRuleKeyframes* StyleResolver::FindKeyframesRule(
return nullptr;
}
+static bool PassesPropertyFilter(ValidPropertyFilter valid_property_filter,
+ CSSPropertyID property,
+ const Document& document) {
+ switch (valid_property_filter) {
+ case ValidPropertyFilter::kNoFilter:
+ return true;
+ case ValidPropertyFilter::kFirstLetter:
+ return CSSProperty::Get(property).IsValidForFirstLetter();
+ case ValidPropertyFilter::kCue:
+ return CSSProperty::Get(property).IsValidForCue();
+ case ValidPropertyFilter::kMarker:
+ return CSSProperty::Get(property).IsValidForMarker();
+ }
+ NOTREACHED();
+ return true;
+}
+
template <CSSPropertyPriority priority>
void StyleResolver::ApplyAnimatedStandardProperties(
StyleResolverState& state,
@@ -1328,243 +1479,22 @@ void StyleResolver::ApplyAnimatedStandardProperties(
entry.key.GetCSSProperty().IsAffectedByForcedColors() &&
state.Style()->ForcedColorAdjust() != EForcedColorAdjust::kNone)
continue;
+ if (state.Style()->StyleType() == kPseudoIdMarker &&
+ !PassesPropertyFilter(ValidPropertyFilter::kMarker, property,
+ state.GetDocument()))
+ continue;
const Interpolation& interpolation = *entry.value.front();
- if (interpolation.IsInvalidatableInterpolation()) {
+ if (IsA<InvalidatableInterpolation>(interpolation)) {
CSSInterpolationTypesMap map(state.GetDocument().GetPropertyRegistry(),
state.GetDocument());
CSSInterpolationEnvironment environment(map, state, nullptr);
InvalidatableInterpolation::ApplyStack(entry.value, environment);
} else {
- ToTransitionInterpolation(interpolation).Apply(state);
+ To<TransitionInterpolation>(interpolation).Apply(state);
}
}
}
-static inline bool IsValidCueStyleProperty(CSSPropertyID id) {
- switch (id) {
- case CSSPropertyID::kBackground:
- case CSSPropertyID::kBackgroundAttachment:
- case CSSPropertyID::kBackgroundClip:
- case CSSPropertyID::kBackgroundColor:
- case CSSPropertyID::kBackgroundImage:
- case CSSPropertyID::kBackgroundOrigin:
- case CSSPropertyID::kBackgroundPosition:
- case CSSPropertyID::kBackgroundPositionX:
- case CSSPropertyID::kBackgroundPositionY:
- case CSSPropertyID::kBackgroundRepeat:
- case CSSPropertyID::kBackgroundRepeatX:
- case CSSPropertyID::kBackgroundRepeatY:
- case CSSPropertyID::kBackgroundSize:
- case CSSPropertyID::kColor:
- case CSSPropertyID::kFont:
- case CSSPropertyID::kFontFamily:
- case CSSPropertyID::kFontSize:
- case CSSPropertyID::kFontStretch:
- case CSSPropertyID::kFontStyle:
- case CSSPropertyID::kFontVariant:
- case CSSPropertyID::kFontWeight:
- case CSSPropertyID::kLineHeight:
- case CSSPropertyID::kOpacity:
- case CSSPropertyID::kOutline:
- case CSSPropertyID::kOutlineColor:
- case CSSPropertyID::kOutlineOffset:
- case CSSPropertyID::kOutlineStyle:
- case CSSPropertyID::kOutlineWidth:
- case CSSPropertyID::kVisibility:
- case CSSPropertyID::kWhiteSpace:
- // FIXME: 'text-decoration' shorthand to be handled when available.
- // See https://chromiumcodereview.appspot.com/19516002 for details.
- case CSSPropertyID::kTextDecoration:
- case CSSPropertyID::kTextShadow:
- case CSSPropertyID::kBorderStyle:
- return true;
- case CSSPropertyID::kTextDecorationLine:
- case CSSPropertyID::kTextDecorationStyle:
- case CSSPropertyID::kTextDecorationColor:
- case CSSPropertyID::kTextDecorationSkipInk:
- return true;
- case CSSPropertyID::kFontVariationSettings:
- return true;
- default:
- break;
- }
- return false;
-}
-
-static inline bool IsValidFirstLetterStyleProperty(CSSPropertyID id) {
- switch (id) {
- // Valid ::first-letter properties listed in spec:
- // https://drafts.csswg.org/css-pseudo-4/#first-letter-styling
- case CSSPropertyID::kBackgroundAttachment:
- case CSSPropertyID::kBackgroundBlendMode:
- case CSSPropertyID::kBackgroundClip:
- case CSSPropertyID::kBackgroundColor:
- case CSSPropertyID::kBackgroundImage:
- case CSSPropertyID::kBackgroundOrigin:
- case CSSPropertyID::kBackgroundPosition:
- case CSSPropertyID::kBackgroundPositionX:
- case CSSPropertyID::kBackgroundPositionY:
- case CSSPropertyID::kBackgroundRepeat:
- case CSSPropertyID::kBackgroundRepeatX:
- case CSSPropertyID::kBackgroundRepeatY:
- case CSSPropertyID::kBackgroundSize:
- case CSSPropertyID::kBorderBlockEnd:
- case CSSPropertyID::kBorderBlockEndColor:
- case CSSPropertyID::kBorderBlockEndStyle:
- case CSSPropertyID::kBorderBlockEndWidth:
- case CSSPropertyID::kBorderBlockStart:
- case CSSPropertyID::kBorderBlockStartColor:
- case CSSPropertyID::kBorderBlockStartStyle:
- case CSSPropertyID::kBorderBlockStartWidth:
- case CSSPropertyID::kBorderBottomColor:
- case CSSPropertyID::kBorderBottomLeftRadius:
- case CSSPropertyID::kBorderBottomRightRadius:
- case CSSPropertyID::kBorderBottomStyle:
- case CSSPropertyID::kBorderBottomWidth:
- case CSSPropertyID::kBorderImageOutset:
- case CSSPropertyID::kBorderImageRepeat:
- case CSSPropertyID::kBorderImageSlice:
- case CSSPropertyID::kBorderImageSource:
- case CSSPropertyID::kBorderImageWidth:
- case CSSPropertyID::kBorderInlineEnd:
- case CSSPropertyID::kBorderInlineEndColor:
- case CSSPropertyID::kBorderInlineEndStyle:
- case CSSPropertyID::kBorderInlineEndWidth:
- case CSSPropertyID::kBorderInlineStart:
- case CSSPropertyID::kBorderInlineStartColor:
- case CSSPropertyID::kBorderInlineStartStyle:
- case CSSPropertyID::kBorderInlineStartWidth:
- case CSSPropertyID::kBorderLeftColor:
- case CSSPropertyID::kBorderLeftStyle:
- case CSSPropertyID::kBorderLeftWidth:
- case CSSPropertyID::kBorderRightColor:
- case CSSPropertyID::kBorderRightStyle:
- case CSSPropertyID::kBorderRightWidth:
- case CSSPropertyID::kBorderTopColor:
- case CSSPropertyID::kBorderTopLeftRadius:
- case CSSPropertyID::kBorderTopRightRadius:
- case CSSPropertyID::kBorderTopStyle:
- case CSSPropertyID::kBorderTopWidth:
- case CSSPropertyID::kBoxShadow:
- case CSSPropertyID::kColor:
- case CSSPropertyID::kFloat:
- case CSSPropertyID::kFontFamily:
- case CSSPropertyID::kFontFeatureSettings:
- case CSSPropertyID::kFontKerning:
- case CSSPropertyID::kFontOpticalSizing:
- case CSSPropertyID::kFontSize:
- case CSSPropertyID::kFontSizeAdjust:
- case CSSPropertyID::kFontStretch:
- case CSSPropertyID::kFontStyle:
- case CSSPropertyID::kFontVariant:
- case CSSPropertyID::kFontVariantCaps:
- case CSSPropertyID::kFontVariantLigatures:
- case CSSPropertyID::kFontVariantNumeric:
- case CSSPropertyID::kFontVariantEastAsian:
- case CSSPropertyID::kFontVariationSettings:
- case CSSPropertyID::kFontWeight:
- case CSSPropertyID::kLetterSpacing:
- case CSSPropertyID::kLineHeight:
- case CSSPropertyID::kMarginBlockEnd:
- case CSSPropertyID::kMarginBlockStart:
- case CSSPropertyID::kMarginBottom:
- case CSSPropertyID::kMarginInlineEnd:
- case CSSPropertyID::kMarginInlineStart:
- case CSSPropertyID::kMarginLeft:
- case CSSPropertyID::kMarginRight:
- case CSSPropertyID::kMarginTop:
- case CSSPropertyID::kOpacity:
- case CSSPropertyID::kPaddingBottom:
- case CSSPropertyID::kPaddingLeft:
- case CSSPropertyID::kPaddingRight:
- case CSSPropertyID::kPaddingTop:
- case CSSPropertyID::kTextDecorationColor:
- case CSSPropertyID::kTextDecorationLine:
- case CSSPropertyID::kTextDecorationStyle:
- case CSSPropertyID::kTextDecorationSkipInk:
- case CSSPropertyID::kTextJustify:
- case CSSPropertyID::kTextShadow:
- case CSSPropertyID::kTextTransform:
- case CSSPropertyID::kTextUnderlinePosition:
- case CSSPropertyID::kVerticalAlign:
- case CSSPropertyID::kWebkitBorderHorizontalSpacing:
- case CSSPropertyID::kWebkitBorderImage:
- case CSSPropertyID::kWebkitBorderVerticalSpacing:
- case CSSPropertyID::kWebkitFontSmoothing:
- case CSSPropertyID::kWebkitMarginAfterCollapse:
- case CSSPropertyID::kWebkitMarginBeforeCollapse:
- case CSSPropertyID::kWebkitMarginBottomCollapse:
- case CSSPropertyID::kWebkitMarginCollapse:
- case CSSPropertyID::kWebkitMarginTopCollapse:
- case CSSPropertyID::kWordSpacing:
- return true;
-
- // Not directly specified in spec, but variables should be supported nearly
- // anywhere.
- case CSSPropertyID::kVariable:
- // Properties that we currently support outside of spec.
- case CSSPropertyID::kVisibility:
- return true;
-
- default:
- return false;
- }
-}
-
-static inline bool IsValidMarkerStyleProperty(CSSPropertyID id) {
- switch (id) {
- // Valid ::marker properties listed in spec:
- // https://drafts.csswg.org/css-pseudo-4/#marker-pseudo
- case CSSPropertyID::kColor:
- case CSSPropertyID::kContent:
- case CSSPropertyID::kDirection:
- case CSSPropertyID::kFont:
- case CSSPropertyID::kFontFamily:
- case CSSPropertyID::kFontFeatureSettings:
- case CSSPropertyID::kFontKerning:
- case CSSPropertyID::kFontOpticalSizing:
- case CSSPropertyID::kFontSize:
- case CSSPropertyID::kFontSizeAdjust:
- case CSSPropertyID::kFontStretch:
- case CSSPropertyID::kFontStyle:
- case CSSPropertyID::kFontVariant:
- case CSSPropertyID::kFontVariantCaps:
- case CSSPropertyID::kFontVariantEastAsian:
- case CSSPropertyID::kFontVariantLigatures:
- case CSSPropertyID::kFontVariantNumeric:
- case CSSPropertyID::kFontVariationSettings:
- case CSSPropertyID::kFontWeight:
- case CSSPropertyID::kTextCombineUpright:
- case CSSPropertyID::kUnicodeBidi:
- return true;
-
- // Not directly specified in spec, but variables should be supported nearly
- // anywhere.
- case CSSPropertyID::kVariable:
- return true;
-
- default:
- return false;
- }
-}
-
-static bool PassesPropertyFilter(ValidPropertyFilter valid_property_filter,
- CSSPropertyID property,
- const Document& document) {
- switch (valid_property_filter) {
- case ValidPropertyFilter::kNoFilter:
- return true;
- case ValidPropertyFilter::kFirstLetter:
- return IsValidFirstLetterStyleProperty(property);
- case ValidPropertyFilter::kCue:
- return IsValidCueStyleProperty(property);
- case ValidPropertyFilter::kMarker:
- return IsValidMarkerStyleProperty(property);
- }
- NOTREACHED();
- return true;
-}
-
static inline void ApplyProperty(const CSSProperty& property,
StyleResolverState& state,
const CSSValue& value,
@@ -1710,20 +1640,6 @@ void StyleResolver::ApplyProperties(StyleResolverState& state,
}
}
-static inline unsigned ComputeApplyMask(
- StyleResolverState& state,
- const MatchedProperties& matched_properties) {
- if (state.Style()->InsideLink() == EInsideLink::kNotInsideLink)
- return kApplyMaskRegular;
- static_assert(static_cast<int>(kApplyMaskRegular) ==
- static_cast<int>(CSSSelector::kMatchLink),
- "kApplyMaskRegular and kMatchLink must match");
- static_assert(static_cast<int>(kApplyMaskVisited) ==
- static_cast<int>(CSSSelector::kMatchVisited),
- "kApplyMaskVisited and kMatchVisited must match");
- return matched_properties.types_.link_match_type;
-}
-
template <CSSPropertyPriority priority,
StyleResolver::ShouldUpdateNeedsApplyPass shouldUpdateNeedsApplyPass>
void StyleResolver::ApplyMatchedProperties(StyleResolverState& state,
@@ -1732,6 +1648,8 @@ void StyleResolver::ApplyMatchedProperties(StyleResolverState& state,
bool inherited_only,
NeedsApplyPass& needs_apply_pass,
ForcedColorFilter forced_colors) {
+ DCHECK(!RuntimeEnabledFeatures::CSSCascadeEnabled());
+
if (range.IsEmpty())
return;
@@ -1740,7 +1658,13 @@ void StyleResolver::ApplyMatchedProperties(StyleResolverState& state,
return;
for (const auto& matched_properties : range) {
- const unsigned apply_mask = ComputeApplyMask(state, matched_properties);
+ static_assert(static_cast<int>(kApplyMaskRegular) ==
+ static_cast<int>(CSSSelector::kMatchLink),
+ "kApplyMaskRegular and kMatchLink must match");
+ static_assert(static_cast<int>(kApplyMaskVisited) ==
+ static_cast<int>(CSSSelector::kMatchVisited),
+ "kApplyMaskVisited and kMatchVisited must match");
+ const unsigned apply_mask = matched_properties.types_.link_match_type;
ApplyProperties<priority, shouldUpdateNeedsApplyPass>(
state, matched_properties.properties.Get(), is_important,
inherited_only, needs_apply_pass,
@@ -1809,12 +1733,12 @@ void StyleResolver::ApplyForcedColors(StyleResolverState& state,
ApplyProperty(GetCSSPropertyWebkitTextEmphasisColor(), state, *unset,
apply_mask);
- // Background colors compute to the Window system color for all values
+ // Background colors compute to the Canvas system color for all values
// except for the alpha channel.
RGBA32 prev_bg_color = state.Style()->BackgroundColor().GetColor().Rgb();
RGBA32 sys_bg_color =
LayoutTheme::GetTheme()
- .SystemColor(CSSValueID::kWindow, WebColorScheme::kLight)
+ .SystemColor(CSSValueID::kCanvas, WebColorScheme::kLight)
.Rgb();
ApplyProperty(GetCSSPropertyBackgroundColor(), state,
*cssvalue::CSSColorValue::Create(sys_bg_color), apply_mask);
@@ -1845,6 +1769,27 @@ void StyleResolver::ApplyUaForcedColors(StyleResolverState& state,
needs_apply_pass, force_colors);
}
+bool StyleResolver::CacheSuccess::EffectiveZoomChanged(
+ const ComputedStyle& style) const {
+ if (!cached_matched_properties)
+ return false;
+ return cached_matched_properties->computed_style->EffectiveZoom() !=
+ style.EffectiveZoom();
+}
+
+bool StyleResolver::CacheSuccess::FontChanged(
+ const ComputedStyle& style) const {
+ if (!cached_matched_properties)
+ return false;
+ return cached_matched_properties->computed_style->GetFontDescription() !=
+ style.GetFontDescription();
+}
+
+bool StyleResolver::CacheSuccess::EffectiveZoomOrFontChanged(
+ const ComputedStyle& style) const {
+ return EffectiveZoomChanged(style) || FontChanged(style);
+}
+
StyleResolver::CacheSuccess StyleResolver::ApplyMatchedCache(
StyleResolverState& state,
const MatchResult& match_result) {
@@ -1902,6 +1847,21 @@ StyleResolver::CacheSuccess StyleResolver::ApplyMatchedCache(
cache_hash, cached_matched_properties);
}
+void StyleResolver::MaybeAddToMatchedPropertiesCache(
+ StyleResolverState& state,
+ const CacheSuccess& cache_success,
+ const MatchResult& match_result) {
+ if (!state.IsAnimatingCustomProperties() &&
+ !cache_success.cached_matched_properties && cache_success.cache_hash &&
+ MatchedPropertiesCache::IsCacheable(state)) {
+ INCREMENT_STYLE_STATS_COUNTER(GetDocument().GetStyleEngine(),
+ matched_property_cache_added, 1);
+ matched_properties_cache_.Add(*state.Style(), *state.ParentStyle(),
+ cache_success.cache_hash,
+ match_result.GetMatchedProperties());
+ }
+}
+
void StyleResolver::ApplyCustomProperties(StyleResolverState& state,
const MatchResult& match_result,
const CacheSuccess& cache_success,
@@ -2053,15 +2013,6 @@ void StyleResolver::ApplyMatchedLowPriorityProperties(
ApplyMatchedProperties<kLowPropertyPriority, kCheckNeedsApplyPass>(
state, range, true, apply_inherited_only, needs_apply_pass);
}
- ApplyMatchedProperties<kLowPropertyPriority, kCheckNeedsApplyPass>(
- state, match_result.UaRules(), true, apply_inherited_only,
- needs_apply_pass);
-
- if (IsForcedColorsModeEnabled() &&
- state.Style()->ForcedColorAdjust() != EForcedColorAdjust::kNone) {
- ApplyForcedColors<kLowPropertyPriority>(
- state, match_result, apply_inherited_only, needs_apply_pass);
- }
if (state.Style()->HasAppearance() && !apply_inherited_only) {
// Check whether the final border and background differs from the cached UA
@@ -2073,31 +2024,29 @@ void StyleResolver::ApplyMatchedLowPriorityProperties(
state.Style()->SetHasAuthorBorder(HasAuthorBorder(state));
}
- LoadPendingResources(state);
+ ApplyMatchedProperties<kLowPropertyPriority, kCheckNeedsApplyPass>(
+ state, match_result.UaRules(), true, apply_inherited_only,
+ needs_apply_pass);
- if (!state.IsAnimatingCustomProperties() &&
- !cache_success.cached_matched_properties && cache_success.cache_hash &&
- MatchedPropertiesCache::IsCacheable(state)) {
- INCREMENT_STYLE_STATS_COUNTER(GetDocument().GetStyleEngine(),
- matched_property_cache_added, 1);
- matched_properties_cache_.Add(*state.Style(), *state.ParentStyle(),
- cache_success.cache_hash,
- match_result.GetMatchedProperties());
+ if (IsForcedColorsModeEnabled() &&
+ state.Style()->ForcedColorAdjust() != EForcedColorAdjust::kNone) {
+ ApplyForcedColors<kLowPropertyPriority>(
+ state, match_result, apply_inherited_only, needs_apply_pass);
}
+ LoadPendingResources(state);
+ MaybeAddToMatchedPropertiesCache(state, cache_success, match_result);
+
DCHECK(!state.GetFontBuilder().FontDirty());
}
void StyleResolver::ApplyMatchedProperties(StyleResolverState& state,
const MatchResult& match_result) {
+ DCHECK(!RuntimeEnabledFeatures::CSSCascadeEnabled());
+
INCREMENT_STYLE_STATS_COUNTER(GetDocument().GetStyleEngine(),
matched_property_apply, 1);
- if (RuntimeEnabledFeatures::CSSCascadeEnabled()) {
- CascadeAndApplyMatchedProperties(state, match_result);
- return;
- }
-
CacheSuccess cache_success = ApplyMatchedCache(state, match_result);
bool apply_inherited_only = cache_success.ShouldApplyInheritedOnly();
NeedsApplyPass needs_apply_pass;
@@ -2143,184 +2092,104 @@ void StyleResolver::ApplyMatchedProperties(StyleResolverState& state,
apply_inherited_only, needs_apply_pass);
}
-void StyleResolver::CascadeAndApplyMatchedProperties(
- StyleResolverState& state,
- const MatchResult& match_result) {
- DCHECK(RuntimeEnabledFeatures::CSSCascadeEnabled());
-
- CacheSuccess cache_success = ApplyMatchedCache(state, match_result);
-
- StyleCascade cascade(state);
- CascadeMatchResult(state, cascade, match_result);
-
- // We need to copy the entire cascade before applying, in case there are
- // animations.
- //
- // TODO(crbug.com/985010): Avoid this copy with non-destructive Apply.
- StyleCascade cascade_copy(cascade);
- cascade_copy.RemoveAnimationPriority();
+scoped_refptr<ComputedStyle> StyleResolver::StyleForInterpolations(
+ Element& element,
+ ActiveInterpolationsMap& interpolations) {
+ StyleResolverState state(GetDocument(), element);
+ STACK_UNINITIALIZED StyleCascade cascade(state);
- if (!cache_success.IsFullCacheHit())
+ if (RuntimeEnabledFeatures::CSSCascadeEnabled()) {
+ ApplyBaseComputedStyle(&element, state, &cascade,
+ cascade.MutableMatchResult(), kMatchAllRules, true);
+ cascade.AddInterpolations(&interpolations, CascadeOrigin::kAnimation);
cascade.Apply();
-
- if (HasAnimationsOrTransitions(state)) {
- CalculateAnimationUpdate(state);
-
- // Add animation effects for custom properties to the cascade.
- if (state.IsAnimatingCustomProperties()) {
- cache_success.SetFailed();
- CascadeAnimations(state, cascade_copy);
- CascadeTransitions(state, cascade_copy);
- StyleAnimator animator(state, cascade_copy);
- cascade_copy.Apply(animator);
- }
+ } else {
+ ApplyBaseComputedStyle(&element, state, nullptr /* cascade */,
+ cascade.MutableMatchResult(), kMatchAllRules, true);
+ ApplyAnimatedStandardProperties<kHighPropertyPriority>(state,
+ interpolations);
+ UpdateFont(state);
+ ApplyAnimatedStandardProperties<kLowPropertyPriority>(state,
+ interpolations);
}
- if (cache_success.IsFullCacheHit())
- return;
-
- // TODO(crbug.com/985025): We only support full cache hits for now.
- bool apply_inherited_only = false;
-
- // TODO(crbug.com/985027): Cascade kLowPropertyPriority.
- //
- // Ultimately NeedsApplyPass will be removed, so we don't bother fixing
- // that for this codepath. For now, just always go through the low-priority
- // properties.
- const bool important = true;
- NeedsApplyPass needs_apply_pass;
- needs_apply_pass.Set(kLowPropertyPriority, important);
- needs_apply_pass.Set(kLowPropertyPriority, !important);
- ApplyMatchedLowPriorityProperties(state, match_result, cache_success,
- apply_inherited_only, needs_apply_pass);
+ return state.TakeStyle();
}
-static void CascadeDeclaration(StyleCascade& cascade,
- const CSSPropertyName& name,
- const CSSValue& value,
- StyleCascade::Priority priority,
- unsigned apply_mask) {
- if (apply_mask & kApplyMaskRegular)
- cascade.Add(name, &value, priority);
- if (apply_mask & kApplyMaskVisited) {
- const CSSProperty* visited =
- CSSProperty::Get(name.Id()).GetVisitedProperty();
- if (visited)
- cascade.Add(visited->GetCSSPropertyName(), &value, priority);
- }
-}
-
-// https://drafts.csswg.org/css-cascade/#all-shorthand
-static void CascadeAll(StyleResolverState& state,
- StyleCascade& cascade,
- StyleCascade::Priority priority,
- unsigned apply_mask,
- ValidPropertyFilter filter,
- const CSSValue& value) {
- for (CSSPropertyID property_id : CSSPropertyIDList()) {
- using LowPrioData = CSSPropertyPriorityData<kLowPropertyPriority>;
- if (LowPrioData::PropertyHasPriority(property_id))
- continue;
+void StyleResolver::CascadeAndApplyMatchedProperties(StyleResolverState& state,
+ StyleCascade& cascade) {
+ DCHECK(RuntimeEnabledFeatures::CSSCascadeEnabled());
+ const MatchResult& result = cascade.GetMatchResult();
- const CSSProperty& property = CSSProperty::Get(property_id);
+ CacheSuccess cache_success = ApplyMatchedCache(state, result);
- if (property.IsShorthand())
- continue;
- if (!property.IsAffectedByAll())
- continue;
- if (!PassesPropertyFilter(filter, property_id, state.GetDocument()))
- continue;
+ if (cache_success.IsFullCacheHit())
+ return;
- CascadeDeclaration(cascade, CSSPropertyName(property_id), value, priority,
- apply_mask);
+ if (cache_success.ShouldApplyInheritedOnly()) {
+ cascade.Apply(CascadeFilter(CSSProperty::kInherited, false));
+ if (cache_success.EffectiveZoomOrFontChanged(state.StyleRef()))
+ cascade.Apply(CascadeFilter(CSSProperty::kInherited, true));
+ } else {
+ cascade.Apply();
}
-}
-void StyleResolver::CascadeMatchResult(StyleResolverState& state,
- StyleCascade& cascade,
- const MatchResult& result) {
- DCHECK(RuntimeEnabledFeatures::CSSCascadeEnabled());
+ CascadeAndApplyForcedColors(state, result);
- using Origin = StyleCascade::Origin;
- CascadeRange(state, cascade, result.UaRules(), Origin::kUserAgent);
- CascadeRange(state, cascade, result.AuthorRules(), Origin::kAuthor);
- CascadeRange(state, cascade, result.UserRules(), Origin::kUser);
-}
+ LoadPendingResources(state);
+ MaybeAddToMatchedPropertiesCache(state, cache_success, result);
-void StyleResolver::CascadeRange(StyleResolverState& state,
- StyleCascade& cascade,
- const MatchedPropertiesRange& range,
- StyleCascade::Origin origin) {
- DCHECK(RuntimeEnabledFeatures::CSSCascadeEnabled());
+ DCHECK(!state.GetFontBuilder().FontDirty());
+}
- if (range.IsEmpty())
+void StyleResolver::CascadeAndApplyForcedColors(StyleResolverState& state,
+ const MatchResult& result) {
+ if (!IsForcedColorsModeEnabled())
+ return;
+ if (state.Style()->ForcedColorAdjust() == EForcedColorAdjust::kNone)
return;
- for (const auto& matched_properties : range) {
- auto filter = static_cast<ValidPropertyFilter>(
- matched_properties.types_.valid_property_filter);
- uint16_t tree_order = matched_properties.types_.tree_order;
- unsigned apply_mask = ComputeApplyMask(state, matched_properties);
- const CSSPropertyValueSet* properties = matched_properties.properties.Get();
- unsigned property_count = properties->PropertyCount();
-
- for (unsigned i = 0; i < property_count; ++i) {
- CSSPropertyValueSet::PropertyReference current =
- properties->PropertyAt(i);
- CSSPropertyID property_id = current.Id();
-
- StyleCascade::Priority priority(origin, tree_order);
-
- if (current.IsImportant())
- priority = priority.AddImportance();
-
- if (property_id == CSSPropertyID::kAll) {
- CascadeAll(state, cascade, priority, apply_mask, filter,
- current.Value());
- continue;
- }
-
- using LowPrioData = CSSPropertyPriorityData<kLowPropertyPriority>;
- if (LowPrioData::PropertyHasPriority(property_id))
- continue;
+ Color prev_bg_color = state.Style()->BackgroundColor().GetColor();
- if (!PassesPropertyFilter(filter, property_id, state.GetDocument()))
- continue;
+ STACK_UNINITIALIZED StyleCascade cascade(state);
- CascadeDeclaration(cascade, current.Name(), current.Value(), priority,
- apply_mask);
- }
+ 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));
}
-}
-
-void StyleResolver::CascadeTransitions(StyleResolverState& state,
- StyleCascade& cascade) {
- const auto& update = state.AnimationUpdate();
- const auto& map = update.ActiveInterpolationsForCustomTransitions();
- const auto origin = StyleCascade::Origin::kTransition;
- CascadeInterpolations(cascade, map, origin);
-}
-void StyleResolver::CascadeAnimations(StyleResolverState& state,
- StyleCascade& cascade) {
- const auto& update = state.AnimationUpdate();
- const auto& map = update.ActiveInterpolationsForCustomAnimations();
- const auto origin = StyleCascade::Origin::kAnimation;
- CascadeInterpolations(cascade, map, origin);
-}
+ CascadeFilter filter(CSSProperty::kIsAffectedByForcedColors, false);
+ cascade.Apply(filter);
-void StyleResolver::CascadeInterpolations(StyleCascade& cascade,
- const ActiveInterpolationsMap& map,
- StyleCascade::Origin origin) {
- using Type = cssvalue::CSSPendingInterpolationValue::Type;
- for (const auto& entry : map) {
- auto name = entry.key.GetCSSPropertyName();
- Type type = entry.key.IsPresentationAttribute()
- ? Type::kPresentationAttribute
- : Type::kCSSProperty;
- auto* v = cssvalue::CSSPendingInterpolationValue::Create(type);
- cascade.Add(name, v, origin);
- }
+ 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) {
@@ -2356,8 +2225,10 @@ void StyleResolver::ApplyCallbackSelectors(StyleResolverState& state) {
if (!watched_selectors_rule_set)
return;
+ MatchResult match_result;
ElementRuleCollector collector(state.ElementContext(), selector_filter_,
- state.Style());
+ match_result, state.Style(),
+ state.Style()->InsideLink());
collector.SetMode(SelectorChecker::kCollectingStyleRules);
collector.SetIncludeEmptyRules(true);
@@ -2404,14 +2275,14 @@ void StyleResolver::ComputeFont(Element& element,
void StyleResolver::UpdateMediaType() {
if (LocalFrameView* view = GetDocument().View()) {
bool was_print = print_media_type_;
- print_media_type_ = DeprecatedEqualIgnoringCase(view->MediaType(),
- media_type_names::kPrint);
+ print_media_type_ =
+ EqualIgnoringASCIICase(view->MediaType(), media_type_names::kPrint);
if (was_print != print_media_type_)
matched_properties_cache_.ClearViewportDependent();
}
}
-void StyleResolver::Trace(blink::Visitor* visitor) {
+void StyleResolver::Trace(Visitor* visitor) {
visitor->Trace(matched_properties_cache_);
visitor->Trace(selector_filter_);
visitor->Trace(document_);
@@ -2422,6 +2293,12 @@ bool StyleResolver::IsForcedColorsModeEnabled() const {
return GetDocument().InForcedColorsMode();
}
+bool StyleResolver::IsForcedColorsModeEnabled(
+ const StyleResolverState& state) const {
+ return IsForcedColorsModeEnabled() &&
+ state.Style()->ForcedColorAdjust() != EForcedColorAdjust::kNone;
+}
+
void StyleResolver::ApplyCascadedColorValue(StyleResolverState& state) {
if (RuntimeEnabledFeatures::CSSCascadeEnabled())
return;
@@ -2435,16 +2312,10 @@ void StyleResolver::ApplyCascadedColorValue(StyleResolverState& state) {
// As per the spec, 'color: currentColor' is treated as 'color:
// inherit'
case CSSValueID::kInherit:
- if (state.ParentStyle()->IsColorInternalText())
- state.Style()->SetIsColorInternalText(true);
- else
- state.Style()->SetColor(state.ParentStyle()->GetColor());
+ state.Style()->SetColor(state.ParentStyle()->GetColor());
break;
case CSSValueID::kInitial:
- state.Style()->SetColor(ComputedStyleInitialValues::InitialColor());
- break;
- case CSSValueID::kInternalRootColor:
- state.Style()->SetIsColorInternalText(true);
+ state.Style()->SetColor(state.Style()->InitialColorForColorScheme());
break;
default:
identifier_value = nullptr;
@@ -2455,6 +2326,8 @@ void StyleResolver::ApplyCascadedColorValue(StyleResolverState& state) {
state.Style()->SetColor(
StyleBuilderConverter::ConvertColor(state, *color_value));
}
+ } else if (state.GetElement() == GetDocument().documentElement()) {
+ state.Style()->SetColor(state.Style()->InitialColorForColorScheme());
}
if (const CSSValue* visited_color_value =
@@ -2473,7 +2346,7 @@ void StyleResolver::ApplyCascadedColorValue(StyleResolverState& state) {
break;
case CSSValueID::kInitial:
state.Style()->SetInternalVisitedColor(
- ComputedStyleInitialValues::InitialColor());
+ state.Style()->InitialColorForColorScheme());
break;
default:
identifier_value = nullptr;
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 452b8a7568b..7f64e22e336 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
@@ -132,9 +132,22 @@ class CORE_EXPORT StyleResolver final : public GarbageCollected<StyleResolver> {
static bool HasAuthorBackground(const StyleResolverState&);
- void Trace(blink::Visitor*);
+ scoped_refptr<ComputedStyle> StyleForInterpolations(
+ Element& target,
+ ActiveInterpolationsMap& animations);
+
+ void Trace(Visitor*);
private:
+ void InitStyleAndApplyInheritance(Element& element,
+ StyleResolverState& state);
+ void ApplyBaseComputedStyle(Element* element,
+ StyleResolverState& state,
+ StyleCascade* cascade,
+ MatchResult& match_result,
+ RuleMatchingBehavior matching_behavior,
+ bool can_cache_animation_base_computed_style);
+
// FIXME: This should probably go away, folded into FontBuilder.
void UpdateFont(StyleResolverState&);
@@ -171,7 +184,7 @@ class CORE_EXPORT StyleResolver final : public GarbageCollected<StyleResolver> {
bool is_inherited_cache_hit;
bool is_non_inherited_cache_hit;
unsigned cache_hash;
- Member<const CachedMatchedProperties> cached_matched_properties;
+ const CachedMatchedProperties* cached_matched_properties;
CacheSuccess(bool is_inherited_cache_hit,
bool is_non_inherited_cache_hit,
@@ -192,6 +205,9 @@ class CORE_EXPORT StyleResolver final : public GarbageCollected<StyleResolver> {
is_inherited_cache_hit = false;
is_non_inherited_cache_hit = false;
}
+ bool EffectiveZoomChanged(const ComputedStyle&) const;
+ bool FontChanged(const ComputedStyle&) const;
+ bool EffectiveZoomOrFontChanged(const ComputedStyle&) const;
};
// These flags indicate whether an apply pass for a given CSSPropertyPriority
@@ -221,6 +237,10 @@ class CORE_EXPORT StyleResolver final : public GarbageCollected<StyleResolver> {
};
CacheSuccess ApplyMatchedCache(StyleResolverState&, const MatchResult&);
+ void MaybeAddToMatchedPropertiesCache(StyleResolverState&,
+ const CacheSuccess&,
+ const MatchResult&);
+
void ApplyCustomProperties(StyleResolverState&,
const MatchResult&,
const CacheSuccess&,
@@ -250,25 +270,15 @@ 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&,
- const MatchResult&);
- void CascadeMatchResult(StyleResolverState&,
- StyleCascade&,
- const MatchResult&);
- void CascadeRange(StyleResolverState&,
- StyleCascade&,
- const MatchedPropertiesRange&,
- StyleCascade::Origin);
- void CascadeTransitions(StyleResolverState&, StyleCascade&);
- void CascadeAnimations(StyleResolverState&, StyleCascade&);
- void CascadeInterpolations(StyleCascade&,
- const ActiveInterpolationsMap&,
- StyleCascade::Origin);
+ StyleCascade& cascade);
void CalculateAnimationUpdate(StyleResolverState&);
- bool ApplyAnimatedStandardProperties(StyleResolverState&);
+ bool ApplyAnimatedStandardProperties(StyleResolverState&,
+ StyleCascade* cascade = nullptr);
void ApplyCallbackSelectors(StyleResolverState&);
@@ -311,6 +321,7 @@ class CORE_EXPORT StyleResolver final : public GarbageCollected<StyleResolver> {
bool WasViewportResized() const { return was_viewport_resized_; }
bool IsForcedColorsModeEnabled() const;
+ bool IsForcedColorsModeEnabled(const StyleResolverState&) const;
MatchedPropertiesCache matched_properties_cache_;
Member<Document> document_;
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 9bdbdd1639f..b2cd50a4809 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
@@ -39,13 +39,15 @@ StyleResolverState::StyleResolverState(
const ComputedStyle* parent_style,
const ComputedStyle* layout_parent_style)
: element_context_(element),
- document_(document),
+ 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),
font_builder_(&document),
element_style_resources_(GetElement(),
document.DevicePixelRatio(),
@@ -204,6 +206,10 @@ StyleResolverState::ParsedPropertiesForPendingSubstitutionCache(
return *map;
}
+CSSParserMode StyleResolverState::GetParserMode() const {
+ return GetDocument().InQuirksMode() ? kHTMLQuirksMode : kHTMLStandardMode;
+}
+
const Element* StyleResolverState::GetAnimatingElement() const {
if (animating_element_type_ == AnimatingElementType::kElement)
return &GetElement();
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 b452c08434b..24b06a2a7c5 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
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/core/css/css_pending_substitution_value.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/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"
@@ -128,6 +129,27 @@ class CORE_EXPORT StyleResolverState {
is_animating_custom_properties_ = 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 StyleCascade skipped
+ // application of some interpolation, it means something else in the cascade
+ // had a higher priority (i.e. it was !important). In this case, we can't
+ // use the base-computed-style optimization, since that code path is unable
+ // to skip any animation effects at all.
+ //
+ // [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;
void SetParentStyle(scoped_refptr<const ComputedStyle>);
@@ -192,6 +214,8 @@ class CORE_EXPORT StyleResolverState {
ParsedPropertiesForPendingSubstitutionCache(
const cssvalue::CSSPendingSubstitutionValue&) const;
+ CSSParserMode GetParserMode() const;
+
private:
enum class AnimatingElementType { kElement, kPseudoElement };
@@ -206,7 +230,7 @@ class CORE_EXPORT StyleResolverState {
const ComputedStyle* font_style) const;
ElementResolveContext element_context_;
- Member<Document> document_;
+ Document* document_;
// style_ is the primary output for each element's style resolve.
scoped_refptr<ComputedStyle> style_;
@@ -224,18 +248,20 @@ class CORE_EXPORT StyleResolverState {
CSSAnimationUpdate animation_update_;
bool is_animation_interpolation_map_ready_;
bool is_animating_custom_properties_;
+ bool has_important_overrides_ = false;
+ bool has_font_affecting_animation_ = false;
bool has_dir_auto_attribute_;
- Member<const CSSValue> cascaded_color_value_;
- Member<const CSSValue> cascaded_visited_color_value_;
+ const CSSValue* cascaded_color_value_;
+ const CSSValue* cascaded_visited_color_value_;
FontBuilder font_builder_;
std::unique_ptr<CachedUAStyle> cached_ua_style_;
ElementStyleResources element_style_resources_;
- Member<Element> pseudo_element_;
+ Element* pseudo_element_;
AnimatingElementType animating_element_type_;
mutable HeapHashMap<
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 927e1f143ca..7f9577045f0 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
@@ -9,17 +9,29 @@
#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/dom/node_computed_style.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/testing/page_test_base.h"
+#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
namespace blink {
class StyleResolverTest : public PageTestBase {
+ public:
+ scoped_refptr<ComputedStyle> StyleForId(AtomicString id) {
+ Element* element = GetDocument().getElementById(id);
+ StyleResolver* resolver = GetStyleEngine().Resolver();
+ DCHECK(resolver);
+ auto style = resolver->StyleForElement(element);
+ DCHECK(style);
+ return style;
+ }
+
protected:
};
TEST_F(StyleResolverTest, StyleForTextInDisplayNone) {
- GetDocument().documentElement()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().documentElement()->setInnerHTML(R"HTML(
<body style="display:none">Text</body>
)HTML");
@@ -35,7 +47,7 @@ TEST_F(StyleResolverTest, StyleForTextInDisplayNone) {
}
TEST_F(StyleResolverTest, AnimationBaseComputedStyle) {
- GetDocument().documentElement()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().documentElement()->setInnerHTML(R"HTML(
<style>
html { font-size: 10px; }
body { font-size: 20px; }
@@ -52,12 +64,8 @@ TEST_F(StyleResolverTest, AnimationBaseComputedStyle) {
ASSERT_TRUE(resolver->StyleForElement(div));
EXPECT_EQ(20, resolver->StyleForElement(div)->FontSize());
-#if DCHECK_IS_ON()
- EXPECT_FALSE(animations.BaseComputedStyle());
-#else
ASSERT_TRUE(animations.BaseComputedStyle());
EXPECT_EQ(20, animations.BaseComputedStyle()->FontSize());
-#endif
// Getting style with customized parent style should not affect cached
// animation base computed style.
@@ -66,13 +74,111 @@ TEST_F(StyleResolverTest, AnimationBaseComputedStyle) {
EXPECT_EQ(
10,
resolver->StyleForElement(div, parent_style, parent_style)->FontSize());
-#if DCHECK_IS_ON()
- EXPECT_FALSE(animations.BaseComputedStyle());
-#else
ASSERT_TRUE(animations.BaseComputedStyle());
EXPECT_EQ(20, animations.BaseComputedStyle()->FontSize());
-#endif
EXPECT_EQ(20, resolver->StyleForElement(div)->FontSize());
}
+TEST_F(StyleResolverTest, ShadowDOMV0Crash) {
+ GetDocument().documentElement()->setInnerHTML(R"HTML(
+ <style>
+ span { display: contents; }
+ </style>
+ <summary><span id="outer"><span id="inner"></b></b></summary>
+ )HTML");
+
+ Element* outer = GetDocument().getElementById("outer");
+ Element* inner = GetDocument().getElementById("inner");
+ ShadowRoot& outer_root = outer->CreateV0ShadowRootForTesting();
+ ShadowRoot& inner_root = inner->CreateV0ShadowRootForTesting();
+ outer_root.setInnerHTML("<content>");
+ inner_root.setInnerHTML("<span>");
+
+ // Test passes if it doesn't crash.
+ UpdateAllLifecyclePhasesForTest();
+}
+
+TEST_F(StyleResolverTest, HasEmUnits) {
+ GetDocument().documentElement()->setInnerHTML("<div id=div>Test</div>");
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_FALSE(StyleForId("div")->HasEmUnits());
+
+ GetDocument().documentElement()->setInnerHTML(
+ "<div id=div style='width:1em'>Test</div>");
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_TRUE(StyleForId("div")->HasEmUnits());
+}
+
+TEST_F(StyleResolverTest, BasePresentIfFontRelativeUnitsAbsent) {
+ GetDocument().documentElement()->setInnerHTML("<div id=div>Test</div>");
+ UpdateAllLifecyclePhasesForTest();
+
+ Element* div = GetDocument().getElementById("div");
+ StyleResolver* resolver = GetStyleEngine().Resolver();
+ ASSERT_TRUE(resolver);
+ ElementAnimations& animations = div->EnsureElementAnimations();
+ animations.SetAnimationStyleChange(true);
+ // We're animating a font affecting property, but we should still be able to
+ // use the base computed style optimization, since no font-relative units
+ // exist in the base.
+ animations.SetHasFontAffectingAnimation();
+
+ EXPECT_TRUE(resolver->StyleForElement(div));
+ EXPECT_TRUE(animations.BaseComputedStyle());
+}
+
+TEST_F(StyleResolverTest, NoCrashWhenAnimatingWithoutCascade) {
+ ScopedCSSCascadeForTest scoped_cascade(false);
+
+ GetDocument().documentElement()->setInnerHTML(R"HTML(
+ <style>
+ @keyframes test {
+ from { width: 10px; }
+ to { width: 20px; }
+ }
+ div {
+ animation: test 1s;
+ }
+ </style>
+ <div id="div">Test</div>
+ )HTML");
+ UpdateAllLifecyclePhasesForTest();
+}
+
+class StyleResolverFontRelativeUnitTest
+ : public testing::WithParamInterface<const char*>,
+ public StyleResolverTest {};
+
+TEST_P(StyleResolverFontRelativeUnitTest, NoBaseIfFontRelativeUnitPresent) {
+ GetDocument().documentElement()->setInnerHTML(
+ String::Format("<div id=div style='width:1%s'>Test</div>", GetParam()));
+ UpdateAllLifecyclePhasesForTest();
+
+ Element* div = GetDocument().getElementById("div");
+ ElementAnimations& animations = div->EnsureElementAnimations();
+ animations.SetAnimationStyleChange(true);
+ animations.SetHasFontAffectingAnimation();
+
+ EXPECT_TRUE(StyleForId("div")->HasFontRelativeUnits());
+ EXPECT_FALSE(animations.BaseComputedStyle());
+}
+
+TEST_P(StyleResolverFontRelativeUnitTest,
+ BasePresentIfNoFontAffectingAnimation) {
+ GetDocument().documentElement()->setInnerHTML(
+ String::Format("<div id=div style='width:1%s'>Test</div>", GetParam()));
+ UpdateAllLifecyclePhasesForTest();
+
+ Element* div = GetDocument().getElementById("div");
+ ElementAnimations& animations = div->EnsureElementAnimations();
+ animations.SetAnimationStyleChange(true);
+
+ EXPECT_TRUE(StyleForId("div")->HasFontRelativeUnits());
+ EXPECT_TRUE(animations.BaseComputedStyle());
+}
+
+INSTANTIATE_TEST_SUITE_P(All,
+ StyleResolverFontRelativeUnitTest,
+ testing::Values("em", "rem", "ex", "ch"));
+
} // 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 a6fd1ff564a..acdb913c628 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
@@ -15,11 +15,22 @@ StyleRuleUsageTracker::RuleListByStyleSheet StyleRuleUsageTracker::TakeDelta() {
return result;
}
+bool StyleRuleUsageTracker::InsertToUsedRulesMap(
+ const CSSStyleSheet* parent_sheet,
+ const StyleRule* rule) {
+ HeapHashSet<Member<const StyleRule>>* set =
+ used_rules_
+ .insert(parent_sheet,
+ MakeGarbageCollected<HeapHashSet<Member<const StyleRule>>>())
+ .stored_value->value;
+ return set->insert(rule).is_new_entry;
+}
+
void StyleRuleUsageTracker::Track(const CSSStyleSheet* parent_sheet,
const StyleRule* rule) {
if (!parent_sheet)
return;
- if (!used_rules_.insert(std::make_pair(parent_sheet, rule)).is_new_entry)
+ if (!InsertToUsedRulesMap(parent_sheet, rule))
return;
auto it = used_rules_delta_.find(parent_sheet);
if (it != used_rules_delta_.end()) {
@@ -31,7 +42,7 @@ void StyleRuleUsageTracker::Track(const CSSStyleSheet* parent_sheet,
}
}
-void StyleRuleUsageTracker::Trace(blink::Visitor* visitor) {
+void StyleRuleUsageTracker::Trace(Visitor* visitor) {
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 ad0d2b93b5e..d28f7d43763 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,10 +19,13 @@ class StyleRuleUsageTracker : public GarbageCollected<StyleRuleUsageTracker> {
void Track(const CSSStyleSheet*, const StyleRule*);
RuleListByStyleSheet TakeDelta();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
- HeapHashSet<std::pair<Member<const CSSStyleSheet>, Member<const StyleRule>>>
+ bool InsertToUsedRulesMap(const CSSStyleSheet*, const StyleRule*);
+
+ HeapHashMap<Member<const CSSStyleSheet>,
+ Member<HeapHashSet<Member<const StyleRule>>>>
used_rules_;
RuleListByStyleSheet used_rules_delta_;
};
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 a79ba7df190..e7a0ddea13f 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
@@ -358,13 +358,9 @@ void ViewportStyleResolver::InitialViewportChanged() {
if (has_viewport_units_)
needs_update_ = kResolve;
- auto& results = viewport_dependent_media_query_results_;
- for (unsigned i = 0; i < results.size(); i++) {
- if (initial_viewport_medium_->Eval(results[i].Expression()) !=
- results[i].Result()) {
- needs_update_ = kCollectRules;
- break;
- }
+ if (initial_viewport_medium_->DidResultsChange(
+ viewport_dependent_media_query_results_)) {
+ needs_update_ = kCollectRules;
}
if (needs_update_ == kNoUpdate)
return;
@@ -396,7 +392,7 @@ void ViewportStyleResolver::UpdateViewport(
needs_update_ = kNoUpdate;
}
-void ViewportStyleResolver::Trace(blink::Visitor* visitor) {
+void ViewportStyleResolver::Trace(Visitor* visitor) {
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 f4c771b1058..aec4e463abc 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(blink::Visitor*);
+ void Trace(Visitor*);
private:
void Reset();
diff --git a/chromium/third_party/blink/renderer/core/css/rule_feature_set.cc b/chromium/third_party/blink/renderer/core/css/rule_feature_set.cc
index 3153b71af7d..fd7c8f3eb08 100644
--- a/chromium/third_party/blink/renderer/core/css/rule_feature_set.cc
+++ b/chromium/third_party/blink/renderer/core/css/rule_feature_set.cc
@@ -171,7 +171,7 @@ bool SupportsInvalidation(CSSSelector::PseudoType type) {
case CSSSelector::kPseudoSlotted:
case CSSSelector::kPseudoVideoPersistent:
case CSSSelector::kPseudoVideoPersistentAncestor:
- case CSSSelector::kPseudoXrImmersiveDomOverlay:
+ case CSSSelector::kPseudoXrOverlay:
return true;
case CSSSelector::kPseudoIs:
case CSSSelector::kPseudoWhere:
@@ -553,7 +553,7 @@ InvalidationSet* RuleFeatureSet::InvalidationSetForSimpleSelector(
case CSSSelector::kPseudoDefined:
case CSSSelector::kPseudoVideoPersistent:
case CSSSelector::kPseudoVideoPersistentAncestor:
- case CSSSelector::kPseudoXrImmersiveDomOverlay:
+ case CSSSelector::kPseudoXrOverlay:
case CSSSelector::kPseudoSpatialNavigationInterest:
case CSSSelector::kPseudoMultiSelectFocus:
return &EnsurePseudoInvalidationSet(selector.GetPseudoType(), type,
diff --git a/chromium/third_party/blink/renderer/core/css/rule_feature_set.h b/chromium/third_party/blink/renderer/core/css/rule_feature_set.h
index c4130255891..84d407eee41 100644
--- a/chromium/third_party/blink/renderer/core/css/rule_feature_set.h
+++ b/chromium/third_party/blink/renderer/core/css/rule_feature_set.h
@@ -99,6 +99,10 @@ class CORE_EXPORT RuleFeatureSet {
MediaQueryResultList& DeviceDependentMediaQueryResults() {
return device_dependent_media_query_results_;
}
+ bool HasMediaQueryResults() const {
+ return !viewport_dependent_media_query_results_.IsEmpty() ||
+ !device_dependent_media_query_results_.IsEmpty();
+ }
// Collect descendant and sibling invalidation sets.
void CollectInvalidationSetsForClass(InvalidationLists&,
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 903c783e01d..02ce7c9fdbe 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
@@ -31,7 +31,7 @@ class RuleFeatureSetTest : public testing::Test {
html->AppendChild(MakeGarbageCollected<HTMLBodyElement>(*document_));
document_->AppendChild(html);
- document_->body()->SetInnerHTMLFromString("<b><i></i></b>");
+ document_->body()->setInnerHTML("<b><i></i></b>");
}
RuleFeatureSet::SelectorPreMatch CollectFeatures(
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 6d5d9352aec..b5b09b832f1 100644
--- a/chromium/third_party/blink/renderer/core/css/rule_set.cc
+++ b/chromium/third_party/blink/renderer/core/css/rule_set.cc
@@ -112,6 +112,7 @@ static void ExtractSelectorValues(const CSSSelector* selector,
AtomicString& class_name,
AtomicString& custom_pseudo_element_name,
AtomicString& tag_name,
+ AtomicString& part_name,
CSSSelector::PseudoType& pseudo_type) {
switch (selector->Match()) {
case CSSSelector::kId:
@@ -137,7 +138,6 @@ static void ExtractSelectorValues(const CSSSelector* selector,
case CSSSelector::kPseudoAnyLink:
case CSSSelector::kPseudoFocus:
case CSSSelector::kPseudoPlaceholder:
- case CSSSelector::kPseudoPart:
case CSSSelector::kPseudoHost:
case CSSSelector::kPseudoHostContext:
case CSSSelector::kPseudoSpatialNavigationInterest:
@@ -147,6 +147,9 @@ static void ExtractSelectorValues(const CSSSelector* selector,
case CSSSelector::kPseudoBlinkInternalElement:
custom_pseudo_element_name = selector->Value();
break;
+ case CSSSelector::kPseudoPart:
+ part_name = selector->Value();
+ break;
default:
break;
}
@@ -162,6 +165,7 @@ bool RuleSet::FindBestRuleSetAndAdd(const CSSSelector& component,
AtomicString class_name;
AtomicString custom_pseudo_element_name;
AtomicString tag_name;
+ AtomicString part_name;
CSSSelector::PseudoType pseudo_type = CSSSelector::kPseudoUnknown;
#ifndef NDEBUG
@@ -172,11 +176,11 @@ bool RuleSet::FindBestRuleSetAndAdd(const CSSSelector& component,
for (; it && it->Relation() == CSSSelector::kSubSelector;
it = it->TagHistory()) {
ExtractSelectorValues(it, id, class_name, custom_pseudo_element_name,
- tag_name, pseudo_type);
+ tag_name, part_name, pseudo_type);
}
if (it) {
ExtractSelectorValues(it, id, class_name, custom_pseudo_element_name,
- tag_name, pseudo_type);
+ tag_name, part_name, pseudo_type);
}
// Prefer rule sets in order of most likely to apply infrequently.
@@ -202,6 +206,11 @@ bool RuleSet::FindBestRuleSetAndAdd(const CSSSelector& component,
return true;
}
+ if (!part_name.IsEmpty()) {
+ part_pseudo_rules_.push_back(rule_data);
+ return true;
+ }
+
switch (pseudo_type) {
case CSSSelector::kPseudoCue:
cue_pseudo_rules_.push_back(rule_data);
@@ -231,9 +240,6 @@ bool RuleSet::FindBestRuleSetAndAdd(const CSSSelector& component,
case CSSSelector::kPseudoHostContext:
shadow_host_rules_.push_back(rule_data);
return true;
- case CSSSelector::kPseudoPart:
- part_pseudo_rules_.push_back(rule_data);
- return true;
default:
break;
}
@@ -314,10 +320,7 @@ void RuleSet::AddChildRules(const HeapVector<Member<StyleRuleBase>>& rules,
} else if (auto* page_rule = DynamicTo<StyleRulePage>(rule)) {
AddPageRule(page_rule);
} else if (auto* media_rule = DynamicTo<StyleRuleMedia>(rule)) {
- if (!media_rule->MediaQueries() ||
- medium.Eval(*media_rule->MediaQueries(),
- &features_.ViewportDependentMediaQueryResults(),
- &features_.DeviceDependentMediaQueryResults()))
+ if (MatchMediaForAddRules(medium, media_rule->MediaQueries()))
AddChildRules(media_rule->ChildRules(), medium, add_rule_flags);
} else if (auto* font_face_rule = DynamicTo<StyleRuleFontFace>(rule)) {
AddFontFaceRule(font_face_rule);
@@ -332,6 +335,18 @@ void RuleSet::AddChildRules(const HeapVector<Member<StyleRuleBase>>& rules,
}
}
+bool RuleSet::MatchMediaForAddRules(const MediaQueryEvaluator& evaluator,
+ const MediaQuerySet* media_queries) {
+ if (!media_queries)
+ return true;
+ bool match_media = evaluator.Eval(
+ *media_queries, &features_.ViewportDependentMediaQueryResults(),
+ &features_.DeviceDependentMediaQueryResults());
+ media_query_set_results_.push_back(
+ MediaQuerySetResult(*media_queries, match_media));
+ return match_media;
+}
+
void RuleSet::AddRulesFromSheet(StyleSheetContents* sheet,
const MediaQueryEvaluator& medium,
AddRuleFlags add_rule_flags) {
@@ -344,11 +359,9 @@ void RuleSet::AddRulesFromSheet(StyleSheetContents* sheet,
for (unsigned i = 0; i < import_rules.size(); ++i) {
StyleRuleImport* import_rule = import_rules[i].Get();
if (import_rule->GetStyleSheet() &&
- (!import_rule->MediaQueries() ||
- medium.Eval(*import_rule->MediaQueries(),
- &features_.ViewportDependentMediaQueryResults(),
- &features_.DeviceDependentMediaQueryResults())))
+ MatchMediaForAddRules(medium, import_rule->MediaQueries())) {
AddRulesFromSheet(import_rule->GetStyleSheet(), medium, add_rule_flags);
+ }
}
AddChildRules(sheet->ChildRules(), medium, add_rule_flags);
@@ -407,22 +420,31 @@ void RuleSet::CompactRules() {
slotted_pseudo_element_rules_.ShrinkToFit();
}
-void MinimalRuleData::Trace(blink::Visitor* visitor) {
+bool RuleSet::DidMediaQueryResultsChange(
+ const MediaQueryEvaluator& evaluator) const {
+ for (const auto& result : media_query_set_results_) {
+ if (result.Result() != evaluator.Eval(result.MediaQueries()))
+ return true;
+ }
+ return false;
+}
+
+void MinimalRuleData::Trace(Visitor* visitor) {
visitor->Trace(rule_);
}
-void RuleData::Trace(blink::Visitor* visitor) {
+void RuleData::Trace(Visitor* visitor) {
visitor->Trace(rule_);
}
-void RuleSet::PendingRuleMaps::Trace(blink::Visitor* visitor) {
+void RuleSet::PendingRuleMaps::Trace(Visitor* visitor) {
visitor->Trace(id_rules);
visitor->Trace(class_rules);
visitor->Trace(tag_rules);
visitor->Trace(shadow_pseudo_element_rules);
}
-void RuleSet::Trace(blink::Visitor* visitor) {
+void RuleSet::Trace(Visitor* visitor) {
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 b3672077c83..26a1b5f107d 100644
--- a/chromium/third_party/blink/renderer/core/css/rule_set.h
+++ b/chromium/third_party/blink/renderer/core/css/rule_set.h
@@ -30,7 +30,7 @@
#include "third_party/blink/renderer/core/css/resolver/media_query_result.h"
#include "third_party/blink/renderer/core/css/rule_feature_set.h"
#include "third_party/blink/renderer/core/css/style_rule.h"
-#include "third_party/blink/renderer/platform/heap/heap_linked_stack.h"
+#include "third_party/blink/renderer/platform/heap/collection_support/heap_linked_stack.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.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(blink::Visitor*);
+ void Trace(Visitor*);
Member<StyleRule> rule_;
unsigned selector_index_;
@@ -127,7 +127,7 @@ class CORE_EXPORT RuleData : public GarbageCollected<RuleData> {
return descendant_selector_identifier_hashes_;
}
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
// This number is picked fairly arbitrary. If lowered, be aware that there
// might be sites and extensions using style rules with selector lists
@@ -284,11 +284,13 @@ class CORE_EXPORT RuleSet final : public GarbageCollected<RuleSet> {
HasV0BoundaryCrossingRules();
}
+ bool DidMediaQueryResultsChange(const MediaQueryEvaluator& evaluator) const;
+
#ifndef NDEBUG
void Show() const;
#endif
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
using PendingRuleMap =
@@ -304,6 +306,8 @@ class CORE_EXPORT RuleSet final : public GarbageCollected<RuleSet> {
void AddKeyframesRule(StyleRuleKeyframes*);
void AddPropertyRule(StyleRuleProperty*);
+ bool MatchMediaForAddRules(const MediaQueryEvaluator& evaluator,
+ const MediaQuerySet* media_queries);
void AddChildRules(const HeapVector<Member<StyleRuleBase>>&,
const MediaQueryEvaluator& medium,
AddRuleFlags);
@@ -321,7 +325,7 @@ class CORE_EXPORT RuleSet final : public GarbageCollected<RuleSet> {
PendingRuleMap tag_rules;
PendingRuleMap shadow_pseudo_element_rules;
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
};
PendingRuleMaps* EnsurePendingRules() {
@@ -349,6 +353,7 @@ class CORE_EXPORT RuleSet final : public GarbageCollected<RuleSet> {
HeapVector<MinimalRuleData> deep_combinator_or_shadow_pseudo_rules_;
HeapVector<MinimalRuleData> content_pseudo_element_rules_;
HeapVector<MinimalRuleData> slotted_pseudo_element_rules_;
+ Vector<MediaQuerySetResult> media_query_set_results_;
unsigned rule_count_;
Member<PendingRuleMaps> pending_rules_;
diff --git a/chromium/third_party/blink/renderer/core/css/rule_set_test.cc b/chromium/third_party/blink/renderer/core/css/rule_set_test.cc
index 3e93a91f61e..359b6e9d527 100644
--- a/chromium/third_party/blink/renderer/core/css/rule_set_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/rule_set_test.cc
@@ -307,6 +307,15 @@ TEST(RuleSetTest, findBestRuleSetAndAdd_PseudoWhere) {
}
}
+TEST(RuleSetTest, findBestRuleSetAndAdd_PartPseudoElements) {
+ css_test_helpers::TestStyleSheet sheet;
+
+ sheet.AddCSSRules("::part(dummy):focus, #id::part(dummy) { }");
+ RuleSet& rule_set = sheet.GetRuleSet();
+ const HeapVector<Member<const RuleData>>* rules = rule_set.PartPseudoRules();
+ ASSERT_EQ(2u, rules->size());
+}
+
TEST(RuleSetTest, findBestRuleSetAndAdd_PseudoIsTooLarge) {
// RuleData cannot support selectors at index 8192 or beyond so the expansion
// is limited to this size
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 8227d4192f6..5067dc81ebf 100644
--- a/chromium/third_party/blink/renderer/core/css/selector_checker.cc
+++ b/chromium/third_party/blink/renderer/core/css/selector_checker.cc
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/core/css/selector_checker.h"
#include "base/auto_reset.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/renderer/core/css/css_selector_list.h"
#include "third_party/blink/renderer/core/css/part_names.h"
#include "third_party/blink/renderer/core/css/style_engine.h"
@@ -101,7 +102,7 @@ static bool MatchesTagName(const Element& element,
const AtomicString& local_name = tag_q_name.LocalName();
if (local_name != CSSSelector::UniversalSelectorAtom() &&
local_name != element.localName()) {
- if (element.IsHTMLElement() || !element.GetDocument().IsHTMLDocument())
+ if (element.IsHTMLElement() || !IsA<HTMLDocument>(element.GetDocument()))
return false;
// Non-html elements in html documents are normalized to their camel-cased
// version during parsing if applicable. Yet, type selectors are lower-cased
@@ -132,7 +133,7 @@ static bool MatchesTagNameForVTT(
if (local_name != CSSSelector::UniversalSelectorAtom() &&
local_name != element.localName()) {
- if (element.IsHTMLElement() || !element.GetDocument().IsHTMLDocument())
+ if (element.IsHTMLElement() || !IsA<HTMLDocument>(element.GetDocument()))
return false;
// Non-html elements in html documents are normalized to their camel-cased
@@ -773,7 +774,7 @@ static bool AnyAttributeMatches(Element& element,
AttributeCollection attributes = element.AttributesWithoutUpdate();
for (const auto& attribute_item : attributes) {
if (!attribute_item.Matches(selector_attr)) {
- if (element.IsHTMLElement() || !element.GetDocument().IsHTMLDocument())
+ if (element.IsHTMLElement() || !IsA<HTMLDocument>(element.GetDocument()))
continue;
// Non-html attributes in html documents are normalized to their camel-
// cased version during parsing if applicable. Yet, attribute selectors
@@ -798,7 +799,7 @@ static bool AnyAttributeMatches(Element& element,
// a case-insensitive manner regardless of whether the case insensitive
// flag is set or not.
bool legacy_case_insensitive =
- element.GetDocument().IsHTMLDocument() &&
+ IsA<HTMLDocument>(element.GetDocument()) &&
!HTMLDocument::IsCaseSensitiveAttribute(selector_attr);
// If case-insensitive, re-check, and count if result differs.
@@ -1249,11 +1250,12 @@ bool SelectorChecker::CheckPseudoClass(const SelectorCheckingContext& context,
case CSSSelector::kPseudoVideoPersistentAncestor:
DCHECK(is_ua_rule_);
return element.ContainsPersistentVideo();
- case CSSSelector::kPseudoXrImmersiveDomOverlay:
- DCHECK(is_ua_rule_);
- // In immersive AR overlay mode, apply a pseudostyle to the root element.
- return element.GetDocument().IsImmersiveArOverlay() &&
- element == element.GetDocument().documentElement();
+ case CSSSelector::kPseudoXrOverlay:
+ // In immersive AR overlay mode, apply a pseudostyle to the DOM Overlay
+ // element. This is the same as the fullscreen element in the current
+ // implementation, but could be different for AR headsets.
+ return element.GetDocument().IsXrOverlay() &&
+ Fullscreen::IsFullscreenElement(element);
case CSSSelector::kPseudoInRange:
return element.IsInRange();
case CSSSelector::kPseudoOutOfRange:
@@ -1271,7 +1273,7 @@ bool SelectorChecker::CheckPseudoClass(const SelectorCheckingContext& context,
return false;
if (context.scope == &element.GetDocument())
return element == element.GetDocument().documentElement();
- if (auto* shadow_root = DynamicTo<ShadowRoot>(context.scope.Get()))
+ if (auto* shadow_root = DynamicTo<ShadowRoot>(context.scope))
return element == shadow_root->host();
return context.scope == &element;
case CSSSelector::kPseudoUnresolved:
@@ -1295,7 +1297,7 @@ bool SelectorChecker::CheckPseudoClass(const SelectorCheckingContext& context,
return MatchesSpatialNavigationInterestPseudoClass(element);
case CSSSelector::kPseudoIsHtml:
DCHECK(is_ua_rule_);
- return element.GetDocument().IsHTMLDocument();
+ return IsA<HTMLDocument>(element.GetDocument());
case CSSSelector::kPseudoListBox:
DCHECK(is_ua_rule_);
return MatchesListBoxPseudoClass(element);
@@ -1394,7 +1396,11 @@ bool SelectorChecker::CheckPseudoElement(const SelectorCheckingContext& context,
}
case CSSSelector::kPseudoPart:
DCHECK(part_names_);
- return part_names_->Contains(selector.Argument());
+ for (const auto& part_name : *selector.PartNames()) {
+ if (!part_names_->Contains(part_name))
+ return false;
+ }
+ return true;
case CSSSelector::kPseudoPlaceholder:
if (ShadowRoot* root = element.ContainingShadowRoot()) {
return root->IsUserAgent() &&
@@ -1611,42 +1617,21 @@ bool SelectorChecker::CheckScrollbarPseudoClass(
return scrollbar_part_ == kBackButtonEndPart ||
scrollbar_part_ == kForwardButtonEndPart ||
scrollbar_part_ == kForwardTrackPart;
- case CSSSelector::kPseudoDoubleButton: {
- WebScrollbarButtonsPlacement buttons_placement =
- scrollbar_->GetTheme().ButtonsPlacement();
- if (scrollbar_part_ == kBackButtonStartPart ||
- scrollbar_part_ == kForwardButtonStartPart ||
- scrollbar_part_ == kBackTrackPart)
- return buttons_placement == kWebScrollbarButtonsPlacementDoubleStart ||
- buttons_placement == kWebScrollbarButtonsPlacementDoubleBoth;
- if (scrollbar_part_ == kBackButtonEndPart ||
- scrollbar_part_ == kForwardButtonEndPart ||
- scrollbar_part_ == kForwardTrackPart)
- return buttons_placement == kWebScrollbarButtonsPlacementDoubleEnd ||
- buttons_placement == kWebScrollbarButtonsPlacementDoubleBoth;
- return false;
- }
- case CSSSelector::kPseudoSingleButton: {
- WebScrollbarButtonsPlacement buttons_placement =
- scrollbar_->GetTheme().ButtonsPlacement();
- if (scrollbar_part_ == kBackButtonStartPart ||
- scrollbar_part_ == kForwardButtonEndPart ||
- scrollbar_part_ == kBackTrackPart ||
- scrollbar_part_ == kForwardTrackPart)
- return buttons_placement == kWebScrollbarButtonsPlacementSingle;
- return false;
- }
- case CSSSelector::kPseudoNoButton: {
- WebScrollbarButtonsPlacement buttons_placement =
- scrollbar_->GetTheme().ButtonsPlacement();
- if (scrollbar_part_ == kBackTrackPart)
- return buttons_placement == kWebScrollbarButtonsPlacementNone ||
- buttons_placement == kWebScrollbarButtonsPlacementDoubleEnd;
- if (scrollbar_part_ == kForwardTrackPart)
- return buttons_placement == kWebScrollbarButtonsPlacementNone ||
- buttons_placement == kWebScrollbarButtonsPlacementDoubleStart;
+ case CSSSelector::kPseudoDoubleButton:
+ // :double-button matches nothing on all platforms.
return false;
- }
+ case CSSSelector::kPseudoSingleButton:
+ if (!scrollbar_->GetTheme().NativeThemeHasButtons())
+ return false;
+ return scrollbar_part_ == kBackButtonStartPart ||
+ scrollbar_part_ == kForwardButtonEndPart ||
+ scrollbar_part_ == kBackTrackPart ||
+ scrollbar_part_ == kForwardTrackPart;
+ case CSSSelector::kPseudoNoButton:
+ if (scrollbar_->GetTheme().NativeThemeHasButtons())
+ return false;
+ return scrollbar_part_ == kBackTrackPart ||
+ scrollbar_part_ == kForwardTrackPart;
case CSSSelector::kPseudoCornerPresent:
return scrollbar_->GetScrollableArea() &&
scrollbar_->GetScrollableArea()->IsScrollCornerVisible();
@@ -1680,7 +1665,7 @@ bool SelectorChecker::MatchesFocusVisiblePseudoClass(const Element& element) {
bool last_focus_from_mouse =
document.GetFrame() &&
document.GetFrame()->Selection().FrameIsFocusedAndActive() &&
- document.LastFocusType() == kWebFocusTypeMouse;
+ document.LastFocusType() == mojom::blink::FocusType::kMouse;
bool had_keyboard_event = document.HadKeyboardEvent();
return (!last_focus_from_mouse || had_keyboard_event ||
diff --git a/chromium/third_party/blink/renderer/core/css/selector_checker.h b/chromium/third_party/blink/renderer/core/css/selector_checker.h
index e4748e49172..e385e97d39a 100644
--- a/chromium/third_party/blink/renderer/core/css/selector_checker.h
+++ b/chromium/third_party/blink/renderer/core/css/selector_checker.h
@@ -48,7 +48,10 @@ class SelectorChecker {
STACK_ALLOCATED();
public:
- enum VisitedMatchType { kVisitedMatchDisabled, kVisitedMatchEnabled };
+ enum VisitedMatchType : uint8_t {
+ kVisitedMatchDisabled,
+ kVisitedMatchEnabled
+ };
enum Mode {
// Used when matching selectors inside style recalc. This mode will set
@@ -83,18 +86,21 @@ class SelectorChecker {
Mode mode = kResolvingStyle;
bool is_ua_rule = false;
ComputedStyle* element_style = nullptr;
- Member<CustomScrollbar> scrollbar = nullptr;
+ CustomScrollbar* scrollbar = nullptr;
ScrollbarPart scrollbar_part = kNoPart;
PartNames* part_names = nullptr;
};
explicit SelectorChecker(const Init& init)
- : mode_(init.mode),
- is_ua_rule_(init.is_ua_rule),
- element_style_(init.element_style),
+ : element_style_(init.element_style),
scrollbar_(init.scrollbar),
+ part_names_(init.part_names),
scrollbar_part_(init.scrollbar_part),
- part_names_(init.part_names) {}
+ mode_(init.mode) {
+#if DCHECK_IS_ON()
+ is_ua_rule_ = init.is_ua_rule;
+#endif
+ }
// Wraps the current element and a CSSSelector and stores some other state of
// the selector matching process.
@@ -105,31 +111,20 @@ class SelectorChecker {
// Initial selector constructor
SelectorCheckingContext(Element* element,
VisitedMatchType visited_match_type)
- : selector(nullptr),
- element(element),
- previous_element(nullptr),
- scope(nullptr),
- visited_match_type(visited_match_type),
- pseudo_id(kPseudoIdNone),
- is_sub_selector(false),
- in_rightmost_compound(true),
- has_scrollbar_pseudo(false),
- has_selection_pseudo(false),
- treat_shadow_host_as_normal_scope(false),
- is_from_vtt(false) {}
-
- const CSSSelector* selector;
- Member<Element> element;
- Member<Element> previous_element;
- Member<const ContainerNode> scope;
+ : element(element), visited_match_type(visited_match_type) {}
+
+ const CSSSelector* selector = nullptr;
+ Element* element = nullptr;
+ Element* previous_element = nullptr;
+ const ContainerNode* scope = nullptr;
VisitedMatchType visited_match_type;
- PseudoId pseudo_id;
- bool is_sub_selector;
- bool in_rightmost_compound;
- bool has_scrollbar_pseudo;
- bool has_selection_pseudo;
- bool treat_shadow_host_as_normal_scope;
- bool is_from_vtt;
+ PseudoId pseudo_id = kPseudoIdNone;
+ bool is_sub_selector = false;
+ bool in_rightmost_compound = true;
+ bool has_scrollbar_pseudo = false;
+ bool has_selection_pseudo = false;
+ bool treat_shadow_host_as_normal_scope = false;
+ bool is_from_vtt = false;
};
struct MatchResult {
@@ -215,12 +210,16 @@ class SelectorChecker {
bool CheckPseudoNot(const SelectorCheckingContext&, MatchResult&) const;
bool CheckPseudoNotForVTT(const SelectorCheckingContext&, MatchResult&) const;
- Mode mode_;
- bool is_ua_rule_;
ComputedStyle* element_style_;
- Member<CustomScrollbar> scrollbar_;
- ScrollbarPart scrollbar_part_;
+ CustomScrollbar* scrollbar_;
PartNames* part_names_;
+ ScrollbarPart scrollbar_part_;
+ Mode mode_;
+#if DCHECK_IS_ON()
+ bool is_ua_rule_;
+#else
+ static constexpr bool is_ua_rule_ = true;
+#endif
DISALLOW_COPY_AND_ASSIGN(SelectorChecker);
};
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 9fb0fb79bf7..64d86ed4bb5 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(blink::Visitor* visitor) {
+void SelectorFilter::ParentStackFrame::Trace(Visitor* visitor) {
visitor->Trace(element);
}
-void SelectorFilter::Trace(blink::Visitor* visitor) {
+void SelectorFilter::Trace(Visitor* visitor) {
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 69d9b975e6d..d911116c19d 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(blink::Visitor*);
+ void Trace(Visitor*);
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(blink::Visitor*);
+ void Trace(Visitor*);
private:
void PushParentStackFrame(Element& parent);
diff --git a/chromium/third_party/blink/renderer/core/css/selector_query.cc b/chromium/third_party/blink/renderer/core/css/selector_query.cc
index 39140ed8dce..722b751f192 100644
--- a/chromium/third_party/blink/renderer/core/css/selector_query.cc
+++ b/chromium/third_party/blink/renderer/core/css/selector_query.cc
@@ -38,6 +38,7 @@
#include "third_party/blink/renderer/core/dom/nth_index_cache.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/dom/static_node_list.h"
+#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
@@ -172,7 +173,7 @@ inline bool MatchesTagName(const QualifiedName& tag_name,
// version during parsing if applicable. Yet, type selectors are lower-cased
// for selectors in html documents. Compare the upper case converted names
// instead to allow matching SVG elements like foreignObject.
- if (!element.IsHTMLElement() && element.GetDocument().IsHTMLDocument())
+ if (!element.IsHTMLElement() && IsA<HTMLDocument>(element.GetDocument()))
return element.TagQName().LocalNameUpper() == tag_name.LocalNameUpper();
return false;
}
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 c5cf6131fcc..84cffc1e660 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
@@ -67,7 +67,7 @@ TEST(SelectorQueryTest, NotMatchingPseudoElement) {
auto* document = MakeGarbageCollected<Document>();
auto* html = MakeGarbageCollected<HTMLHtmlElement>(*document);
document->AppendChild(html);
- document->documentElement()->SetInnerHTMLFromString(
+ document->documentElement()->setInnerHTML(
"<body><style>span::before { content: 'X' }</style><span></span></body>");
CSSSelectorList selector_list = CSSParser::ParseSelector(
@@ -96,7 +96,7 @@ TEST(SelectorQueryTest, LastOfTypeNotFinishedParsing) {
auto* document = MakeGarbageCollected<HTMLDocument>();
auto* html = MakeGarbageCollected<HTMLHtmlElement>(*document);
document->AppendChild(html);
- document->documentElement()->SetInnerHTMLFromString(
+ document->documentElement()->setInnerHTML(
"<body><p></p><p id=last></p></body>", ASSERT_NO_EXCEPTION);
document->body()->BeginParsingChildren();
@@ -331,7 +331,7 @@ TEST(SelectorQueryTest, QuirksModeSlowPath) {
TEST(SelectorQueryTest, DisconnectedSubtree) {
auto* document = MakeGarbageCollected<HTMLDocument>();
Element* scope = document->CreateRawElement(html_names::kDivTag);
- scope->SetInnerHTMLFromString(R"HTML(
+ scope->setInnerHTML(R"HTML(
<section>
<span id=first>
<span id=A class=A></span>
@@ -360,7 +360,7 @@ TEST(SelectorQueryTest, DisconnectedTreeScope) {
Element* host = document->CreateRawElement(html_names::kDivTag);
ShadowRoot& shadowRoot =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadowRoot.SetInnerHTMLFromString(R"HTML(
+ shadowRoot.setInnerHTML(R"HTML(
<section>
<span id=first>
<span id=A class=A></span>
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 138bf722465..5a9cd376b13 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
@@ -47,7 +47,7 @@ class ShadowTreeStyleSheetCollection final
void UpdateActiveStyleSheets(StyleEngine& master_engine);
bool IsShadowTreeStyleSheetCollection() const final { return true; }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
TreeScopeStyleSheetCollection::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/style_attribute_mutation_scope.h b/chromium/third_party/blink/renderer/core/css/style_attribute_mutation_scope.h
index 34fd5076832..7a5f8cded52 100644
--- a/chromium/third_party/blink/renderer/core/css/style_attribute_mutation_scope.h
+++ b/chromium/third_party/blink/renderer/core/css/style_attribute_mutation_scope.h
@@ -51,8 +51,8 @@ class StyleAttributeMutationScope {
static bool should_notify_inspector_;
static bool should_deliver_;
- Member<MutationObserverInterestGroup> mutation_recipients_;
- Member<MutationRecord> mutation_;
+ MutationObserverInterestGroup* mutation_recipients_ = nullptr;
+ MutationRecord* mutation_ = nullptr;
AtomicString old_value_;
DISALLOW_COPY_AND_ASSIGN(StyleAttributeMutationScope);
};
diff --git a/chromium/third_party/blink/renderer/core/css/style_change_reason.cc b/chromium/third_party/blink/renderer/core/css/style_change_reason.cc
index c3eeeb35293..9a660dd1f6e 100644
--- a/chromium/third_party/blink/renderer/core/css/style_change_reason.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_change_reason.cc
@@ -27,7 +27,6 @@ const char kFrame[] = "Frame";
const char kFullscreen[] = "Fullscreen";
const char kInheritedStyleChangeFromParentFrame[] =
"InheritedStyleChangeFromParentFrame";
-const char kInline[] = "Inline";
const char kInlineCSSStyleMutated[] =
"Inline CSS style declaration was mutated";
const char kInspector[] = "Inspector";
diff --git a/chromium/third_party/blink/renderer/core/css/style_change_reason.h b/chromium/third_party/blink/renderer/core/css/style_change_reason.h
index dadf17e01d2..bece22e6514 100644
--- a/chromium/third_party/blink/renderer/core/css/style_change_reason.h
+++ b/chromium/third_party/blink/renderer/core/css/style_change_reason.h
@@ -29,7 +29,6 @@ extern const char kFonts[];
extern const char kFullscreen[];
extern const char kFindInvisible[];
extern const char kInheritedStyleChangeFromParentFrame[];
-extern const char kInline[];
extern const char kInlineCSSStyleMutated[];
extern const char kInspector[];
extern const char kInvisibleChange[];
diff --git a/chromium/third_party/blink/renderer/core/css/style_color.cc b/chromium/third_party/blink/renderer/core/css/style_color.cc
index 4f12e871d29..669adf45133 100644
--- a/chromium/third_party/blink/renderer/core/css/style_color.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_color.cc
@@ -40,9 +40,8 @@ bool StyleColor::IsColorKeyword(CSSValueID id) {
// '-internal-inactive-list-box-selection-text'
// '-webkit-focus-ring-color'
// '-internal-quirk-inherit'
- // '-internal-root-color'
//
- return (id >= CSSValueID::kAqua && id <= CSSValueID::kInternalRootColor) ||
+ return (id >= CSSValueID::kAqua && id <= CSSValueID::kInternalQuirkInherit) ||
(id >= CSSValueID::kAliceblue && id <= CSSValueID::kYellowgreen) ||
id == CSSValueID::kMenu;
}
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 03ac95e4895..52c653e7cff 100644
--- a/chromium/third_party/blink/renderer/core/css/style_element.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_element.cc
@@ -40,9 +40,9 @@
namespace blink {
static bool IsCSS(const Element& element, const AtomicString& type) {
- return type.IsEmpty() || (element.IsHTMLElement()
- ? DeprecatedEqualIgnoringCase(type, "text/css")
- : (type == "text/css"));
+ return type.IsEmpty() ||
+ (element.IsHTMLElement() ? EqualIgnoringASCIICase(type, "text/css")
+ : (type == "text/css"));
}
StyleElement::StyleElement(Document* document, bool created_by_parser)
@@ -150,8 +150,10 @@ StyleElement::ProcessingResult StyleElement::CreateSheet(Element& element,
if (IsCSS(element, type) && passes_content_security_policy_checks) {
scoped_refptr<MediaQuerySet> media_queries;
const AtomicString& media_string = media();
- if (!media_string.IsEmpty())
- media_queries = MediaQuerySet::Create(media_string);
+ if (!media_string.IsEmpty()) {
+ media_queries =
+ MediaQuerySet::Create(media_string, element.GetExecutionContext());
+ }
loading_ = true;
TextPosition start_position =
start_position_ == TextPosition::BelowRangePosition()
@@ -193,7 +195,7 @@ void StyleElement::StartLoadingDynamicSheet(Document& document) {
document.GetStyleEngine().AddPendingSheet(style_engine_context_);
}
-void StyleElement::Trace(blink::Visitor* visitor) {
+void StyleElement::Trace(Visitor* visitor) {
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 957a6e23d2c..bb39739da6b 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
enum ProcessingResult { kProcessingSuccessful, kProcessingFatalError };
diff --git a/chromium/third_party/blink/renderer/core/css/style_element_test.cc b/chromium/third_party/blink/renderer/core/css/style_element_test.cc
index 13a2d7e9610..5b37ef79e65 100644
--- a/chromium/third_party/blink/renderer/core/css/style_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_element_test.cc
@@ -17,7 +17,7 @@ TEST(StyleElementTest, CreateSheetUsesCache) {
auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
Document& document = dummy_page_holder->GetDocument();
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<style id=style>a { top: 0; }</style>");
auto& style_element = To<HTMLStyleElement>(*document.getElementById("style"));
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 e7d64e18e37..4d430870ed3 100644
--- a/chromium/third_party/blink/renderer/core/css/style_engine.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_engine.cc
@@ -36,6 +36,7 @@
#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_style_sheet.h"
+#include "third_party/blink/renderer/core/css/css_uri_value.h"
#include "third_party/blink/renderer/core/css/css_value_list.h"
#include "third_party/blink/renderer/core/css/document_style_environment_variables.h"
#include "third_party/blink/renderer/core/css/document_style_sheet_collector.h"
@@ -53,6 +54,7 @@
#include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/css/style_environment_variables.h"
#include "third_party/blink/renderer/core/css/style_sheet_contents.h"
+#include "third_party/blink/renderer/core/css/vision_deficiency.h"
#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
#include "third_party/blink/renderer/core/dom/document_lifecycle.h"
#include "third_party/blink/renderer/core/dom/element.h"
@@ -75,10 +77,13 @@
#include "third_party/blink/renderer/core/layout/layout_object.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"
#include "third_party/blink/renderer/core/paint/paint_layer.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/filter_operations.h"
#include "third_party/blink/renderer/core/style/style_initial_data.h"
+#include "third_party/blink/renderer/core/svg/svg_resource.h"
#include "third_party/blink/renderer/core/svg/svg_style_element.h"
#include "third_party/blink/renderer/platform/fonts/font_cache.h"
#include "third_party/blink/renderer/platform/fonts/font_selector.h"
@@ -89,6 +94,18 @@
namespace blink {
+namespace {
+
+CSSFontSelector* CreateCSSFontSelectorFor(Document& document) {
+ DCHECK(document.GetFrame());
+ if (UNLIKELY(document.GetFrame()->PagePopupOwner())) {
+ return PagePopupController::CreateCSSFontSelector(document);
+ }
+ return MakeGarbageCollected<CSSFontSelector>(&document);
+}
+
+} // namespace
+
StyleEngine::StyleEngine(Document& document)
: document_(&document),
is_master_(!document.IsHTMLImport()),
@@ -97,18 +114,19 @@ StyleEngine::StyleEngine(Document& document)
if (document.GetFrame()) {
// We don't need to create CSSFontSelector for imported document or
// HTMLTemplateElement's document, because those documents have no frame.
- font_selector_ = MakeGarbageCollected<CSSFontSelector>(&document);
+ font_selector_ = CreateCSSFontSelectorFor(document);
font_selector_->RegisterForInvalidationCallbacks(this);
}
if (document.IsInMainFrame())
viewport_resolver_ = MakeGarbageCollected<ViewportStyleResolver>(document);
if (IsMaster())
global_rule_set_ = MakeGarbageCollected<CSSGlobalRuleSet>();
- if (Platform::Current() && Platform::Current()->ThemeEngine()) {
- preferred_color_scheme_ =
- Platform::Current()->ThemeEngine()->PreferredColorScheme();
- forced_colors_ = Platform::Current()->ThemeEngine()->GetForcedColors();
+ if (auto* settings = GetDocument().GetSettings()) {
+ if (!settings->GetForceDarkModeEnabled())
+ preferred_color_scheme_ = settings->GetPreferredColorScheme();
}
+ if (Platform::Current() && Platform::Current()->ThemeEngine())
+ forced_colors_ = Platform::Current()->ThemeEngine()->GetForcedColors();
}
StyleEngine::~StyleEngine() = default;
@@ -363,6 +381,58 @@ void StyleEngine::AddedCustomElementDefaultStyles(
global_rule_set_->MarkDirty();
}
+namespace {
+
+bool HasMediaQueries(const ActiveStyleSheetVector& active_style_sheets) {
+ for (const auto& active_sheet : active_style_sheets) {
+ if (const MediaQuerySet* media_queries =
+ active_sheet.first->MediaQueries()) {
+ if (!media_queries->QueryVector().IsEmpty())
+ return true;
+ }
+ StyleSheetContents* contents = active_sheet.first->Contents();
+ if (contents->HasMediaQueries())
+ return true;
+ }
+ return false;
+}
+
+bool HasSizeDependentMediaQueries(
+ const ActiveStyleSheetVector& active_style_sheets) {
+ for (const auto& active_sheet : active_style_sheets) {
+ if (active_sheet.first->HasMediaQueryResults())
+ return true;
+ StyleSheetContents* contents = active_sheet.first->Contents();
+ if (!contents->HasRuleSet())
+ continue;
+ if (contents->GetRuleSet().Features().HasMediaQueryResults())
+ return true;
+ }
+ return false;
+}
+
+} // namespace
+
+bool StyleEngine::MediaQueryAffectingValueChanged(
+ const ActiveStyleSheetVector& active_sheets,
+ MediaValueChange change) {
+ if (change == MediaValueChange::kSize)
+ return HasSizeDependentMediaQueries(active_sheets);
+
+ DCHECK(change == MediaValueChange::kOther);
+ return HasMediaQueries(active_sheets);
+}
+
+void StyleEngine::MediaQueryAffectingValueChanged(TreeScope& tree_scope,
+ MediaValueChange change) {
+ auto* collection = StyleSheetCollectionFor(tree_scope);
+ DCHECK(collection);
+ if (MediaQueryAffectingValueChanged(collection->ActiveAuthorStyleSheets(),
+ change)) {
+ SetNeedsActiveStyleUpdate(tree_scope);
+ }
+}
+
void StyleEngine::MediaQueriesChangedInScope(TreeScope& tree_scope) {
if (ScopedStyleResolver* resolver = tree_scope.GetScopedStyleResolver())
resolver->SetNeedsAppendAllSheets();
@@ -387,14 +457,11 @@ bool StyleEngine::ShouldUpdateShadowTreeStyleSheetCollection() const {
}
void StyleEngine::MediaQueryAffectingValueChanged(
- UnorderedTreeScopeSet& tree_scopes) {
+ UnorderedTreeScopeSet& tree_scopes,
+ MediaValueChange change) {
for (TreeScope* tree_scope : tree_scopes) {
DCHECK(tree_scope != document_);
- auto* collection = To<ShadowTreeStyleSheetCollection>(
- StyleSheetCollectionFor(*tree_scope));
- DCHECK(collection);
- if (collection->MediaQueryAffectingValueChanged())
- SetNeedsActiveStyleUpdate(*tree_scope);
+ MediaQueryAffectingValueChanged(*tree_scope, change);
}
}
@@ -407,7 +474,8 @@ void StyleEngine::RemoveTextTrack(TextTrack* text_track) {
}
void StyleEngine::MediaQueryAffectingValueChanged(
- HeapHashSet<Member<TextTrack>>& text_tracks) {
+ HeapHashSet<Member<TextTrack>>& text_tracks,
+ MediaValueChange change) {
if (text_tracks.IsEmpty())
return;
@@ -433,13 +501,12 @@ void StyleEngine::MediaQueryAffectingValueChanged(
}
}
-void StyleEngine::MediaQueryAffectingValueChanged() {
- if (ClearMediaQueryDependentRuleSets(active_user_style_sheets_))
+void StyleEngine::MediaQueryAffectingValueChanged(MediaValueChange change) {
+ if (MediaQueryAffectingValueChanged(active_user_style_sheets_, change))
MarkUserStyleDirty();
- if (GetDocumentStyleSheetCollection().MediaQueryAffectingValueChanged())
- SetNeedsActiveStyleUpdate(GetDocument());
- MediaQueryAffectingValueChanged(active_tree_scopes_);
- MediaQueryAffectingValueChanged(text_tracks_);
+ MediaQueryAffectingValueChanged(GetDocument(), change);
+ MediaQueryAffectingValueChanged(active_tree_scopes_, change);
+ MediaQueryAffectingValueChanged(text_tracks_, change);
if (resolver_)
resolver_->UpdateMediaType();
}
@@ -671,17 +738,24 @@ void StyleEngine::DidDetach() {
environment_variables_ = nullptr;
}
-void StyleEngine::ClearFontCacheAndAddUserFonts() {
+bool StyleEngine::ClearFontCacheAndAddUserFonts() {
+ bool fonts_changed = false;
+
if (font_selector_ &&
- font_selector_->GetFontFaceCache()->ClearCSSConnected() && resolver_) {
- resolver_->InvalidateMatchedPropertiesCache();
+ font_selector_->GetFontFaceCache()->ClearCSSConnected()) {
+ fonts_changed = true;
+ if (resolver_)
+ resolver_->InvalidateMatchedPropertiesCache();
}
// Rebuild the font cache with @font-face rules from user style sheets.
for (unsigned i = 0; i < active_user_style_sheets_.size(); ++i) {
DCHECK(active_user_style_sheets_[i].second);
- AddUserFontFaceRules(*active_user_style_sheets_[i].second);
+ if (AddUserFontFaceRules(*active_user_style_sheets_[i].second))
+ fonts_changed = true;
}
+
+ return fonts_changed;
}
void StyleEngine::UpdateGenericFontFamilySettings() {
@@ -822,6 +896,34 @@ void StyleEngine::CollectScopedStyleFeaturesTo(RuleFeatureSet& features) const {
}
}
+void StyleEngine::InvalidateStyleAndLayoutForFontUpdates() {
+ if (!fonts_need_update_)
+ return;
+
+ DCHECK(RuntimeEnabledFeatures::CSSReducedFontLoadingInvalidationsEnabled());
+ TRACE_EVENT0("blink", "StyleEngine::InvalidateStyleAndLayoutForFontUpdates");
+
+ fonts_need_update_ = false;
+ Element* root = GetDocument().documentElement();
+ if (!root)
+ return;
+
+ {
+ TRACE_EVENT0("blink", "Node::MarkSubtreeNeedsStyleRecalcForFontUpdates");
+ root->MarkSubtreeNeedsStyleRecalcForFontUpdates();
+ }
+
+ if (LayoutObject* root_object = root->GetLayoutObject()) {
+ TRACE_EVENT0("blink", "LayoutObject::InvalidateSubtreeForFontUpdates");
+ root_object->InvalidateSubtreeLayoutForFontUpdates();
+ }
+}
+
+void StyleEngine::MarkFontsNeedUpdate() {
+ fonts_need_update_ = true;
+ GetDocument().ScheduleLayoutTreeUpdateIfNeeded();
+}
+
void StyleEngine::FontsNeedUpdate(FontSelector*) {
if (!GetDocument().IsActive())
return;
@@ -829,17 +931,16 @@ void StyleEngine::FontsNeedUpdate(FontSelector*) {
if (resolver_)
resolver_->InvalidateMatchedPropertiesCache();
MarkViewportStyleDirty();
- MarkAllElementsForStyleRecalc(
- StyleChangeReasonForTracing::Create(style_change_reason::kFonts));
- probe::FontsUpdated(document_, nullptr, String(), nullptr);
-}
-void StyleEngine::SetFontSelector(CSSFontSelector* font_selector) {
- if (font_selector_)
- font_selector_->UnregisterForInvalidationCallbacks(this);
- font_selector_ = font_selector;
- if (font_selector_)
- font_selector_->RegisterForInvalidationCallbacks(this);
+ if (RuntimeEnabledFeatures::CSSReducedFontLoadingInvalidationsEnabled()) {
+ MarkFontsNeedUpdate();
+ } else {
+ MarkAllElementsForStyleRecalc(
+ StyleChangeReasonForTracing::Create(style_change_reason::kFonts));
+ }
+
+ probe::FontsUpdated(document_->GetExecutionContext(), nullptr, String(),
+ nullptr);
}
void StyleEngine::PlatformColorsChanged() {
@@ -852,6 +953,26 @@ void StyleEngine::PlatformColorsChanged() {
bool StyleEngine::ShouldSkipInvalidationFor(const Element& element) const {
if (!element.InActiveDocument())
return true;
+ if (GetDocument().InStyleRecalc()) {
+#if DCHECK_IS_ON()
+ // TODO(futhark): The InStyleRecalc() if-guard above should have been a
+ // DCHECK(!InStyleRecalc()), but there are a couple of cases where we try to
+ // invalidate style from style recalc:
+ //
+ // 1. We may animate the class attribute of an SVG element and change it
+ // during style recalc when applying the animation effect.
+ // 2. We may call SetInlineStyle on elements in a UA shadow tree as part of
+ // style recalc. For instance from HTMLImageFallbackHelper.
+ //
+ // If there are more cases, we need to adjust the DCHECKs below, but ideally
+ // The origin of these invalidations should be fixed.
+ if (!element.IsSVGElement()) {
+ DCHECK(element.ContainingShadowRoot());
+ DCHECK(element.ContainingShadowRoot()->IsUserAgent());
+ }
+#endif // DCHECK_IS_ON()
+ return true;
+ }
if (GetDocument().GetStyleChangeType() == kSubtreeStyleChange)
return true;
Element* root = GetDocument().documentElement();
@@ -1278,6 +1399,15 @@ void StyleEngine::SetHttpDefaultStyle(const String& content) {
SetPreferredStylesheetSetNameIfNotSet(content);
}
+void StyleEngine::EnsureUAStyleForXrOverlay() {
+ DCHECK(IsMaster());
+ DCHECK(global_rule_set_);
+ if (CSSDefaultStyleSheets::Instance().EnsureDefaultStyleSheetForXrOverlay()) {
+ global_rule_set_->MarkDirty();
+ UpdateActiveStyle();
+ }
+}
+
void StyleEngine::EnsureUAStyleForFullscreen() {
DCHECK(IsMaster());
DCHECK(global_rule_set_);
@@ -1310,7 +1440,7 @@ void StyleEngine::InitialStyleChanged() {
// Media queries may rely on the initial font size relative lengths which may
// have changed.
- MediaQueryAffectingValueChanged();
+ MediaQueryAffectingValueChanged(MediaValueChange::kOther);
MarkViewportStyleDirty();
MarkAllElementsForStyleRecalc(
StyleChangeReasonForTracing::Create(style_change_reason::kSettings));
@@ -1385,18 +1515,29 @@ unsigned GetRuleSetFlags(const HeapHashSet<Member<RuleSet>> rule_sets) {
return flags;
}
+bool NeedsFullRecalcForRuleSetChanges(TreeScope& tree_scope,
+ unsigned changed_rule_flags,
+ bool has_rebuilt_font_cache) {
+ if (changed_rule_flags & kFullRecalcRules)
+ return true;
+ if (!tree_scope.RootNode().IsDocumentNode())
+ return false;
+ return (changed_rule_flags & kFontFaceRules) || has_rebuilt_font_cache;
+}
+
} // namespace
void StyleEngine::InvalidateForRuleSetChanges(
TreeScope& tree_scope,
const HeapHashSet<Member<RuleSet>>& changed_rule_sets,
unsigned changed_rule_flags,
- InvalidationScope invalidation_scope) {
+ InvalidationScope invalidation_scope,
+ bool has_rebuilt_font_cache) {
if (tree_scope.GetDocument().HasPendingForcedStyleRecalc())
return;
if (!tree_scope.GetDocument().documentElement())
return;
- if (changed_rule_sets.IsEmpty())
+ if (changed_rule_sets.IsEmpty() && !has_rebuilt_font_cache)
return;
Element& invalidation_root =
@@ -1404,9 +1545,8 @@ void StyleEngine::InvalidateForRuleSetChanges(
if (invalidation_root.GetStyleChangeType() == kSubtreeStyleChange)
return;
- if (changed_rule_flags & kFullRecalcRules ||
- ((changed_rule_flags & kFontFaceRules) &&
- tree_scope.RootNode().IsDocumentNode())) {
+ if (NeedsFullRecalcForRuleSetChanges(tree_scope, changed_rule_flags,
+ has_rebuilt_font_cache)) {
invalidation_root.SetNeedsStyleRecalc(
kSubtreeStyleChange,
StyleChangeReasonForTracing::Create(
@@ -1414,6 +1554,8 @@ void StyleEngine::InvalidateForRuleSetChanges(
return;
}
+ if (changed_rule_sets.IsEmpty())
+ return;
ScheduleInvalidationsForRuleSets(tree_scope, changed_rule_sets,
invalidation_scope);
}
@@ -1439,6 +1581,7 @@ void StyleEngine::ApplyUserRuleSetChanges(
global_rule_set_->MarkDirty();
unsigned changed_rule_flags = GetRuleSetFlags(changed_rule_sets);
+ bool has_rebuilt_font_cache = false;
if (changed_rule_flags & kFontFaceRules) {
if (ScopedStyleResolver* scoped_resolver =
GetDocument().GetScopedStyleResolver()) {
@@ -1449,7 +1592,7 @@ void StyleEngine::ApplyUserRuleSetChanges(
scoped_resolver->SetNeedsAppendAllSheets();
MarkDocumentDirty();
} else {
- ClearFontCacheAndAddUserFonts();
+ has_rebuilt_font_cache = ClearFontCacheAndAddUserFonts();
}
}
@@ -1466,7 +1609,8 @@ void StyleEngine::ApplyUserRuleSetChanges(
}
InvalidateForRuleSetChanges(GetDocument(), changed_rule_sets,
- changed_rule_flags, kInvalidateAllScopes);
+ changed_rule_flags, kInvalidateAllScopes,
+ has_rebuilt_font_cache);
}
void StyleEngine::ApplyRuleSetChanges(
@@ -1514,8 +1658,9 @@ void StyleEngine::ApplyRuleSetChanges(
}
}
+ bool has_rebuilt_font_cache = false;
if (rebuild_font_cache)
- ClearFontCacheAndAddUserFonts();
+ has_rebuilt_font_cache = ClearFontCacheAndAddUserFonts();
unsigned append_start_index = 0;
if (scoped_resolver) {
@@ -1538,7 +1683,43 @@ void StyleEngine::ApplyRuleSetChanges(
}
InvalidateForRuleSetChanges(tree_scope, changed_rule_sets, changed_rule_flags,
- kInvalidateCurrentScope);
+ kInvalidateCurrentScope, has_rebuilt_font_cache);
+}
+
+void StyleEngine::LoadVisionDeficiencyFilter() {
+ VisionDeficiency old_vision_deficiency = vision_deficiency_;
+ vision_deficiency_ = GetDocument().GetPage()->GetVisionDeficiency();
+ if (vision_deficiency_ == old_vision_deficiency)
+ return;
+
+ if (vision_deficiency_ == VisionDeficiency::kNoVisionDeficiency) {
+ vision_deficiency_filter_ = nullptr;
+ } else {
+ AtomicString url = CreateVisionDeficiencyFilterUrl(vision_deficiency_);
+ cssvalue::CSSURIValue css_uri_value(url);
+ SVGResource* svg_resource = css_uri_value.EnsureResourceReference();
+ // Note: The fact that we're using data: URLs here is an
+ // implementation detail. Emulating vision deficiencies should still
+ // work even if the Document's Content-Security-Policy disallows
+ // data: URLs.
+ svg_resource->LoadWithoutCSP(GetDocument());
+ vision_deficiency_filter_ =
+ MakeGarbageCollected<ReferenceFilterOperation>(url, svg_resource);
+ }
+}
+
+void StyleEngine::VisionDeficiencyChanged() {
+ MarkViewportStyleDirty();
+}
+
+void StyleEngine::ApplyVisionDeficiencyStyle(
+ scoped_refptr<ComputedStyle> layout_view_style) {
+ LoadVisionDeficiencyFilter();
+ if (vision_deficiency_filter_) {
+ FilterOperations ops;
+ ops.Operations().push_back(vision_deficiency_filter_);
+ layout_view_style->SetFilter(ops);
+ }
}
const MediaQueryEvaluator& StyleEngine::EnsureMediaQueryEvaluator() {
@@ -1556,35 +1737,24 @@ const MediaQueryEvaluator& StyleEngine::EnsureMediaQueryEvaluator() {
bool StyleEngine::MediaQueryAffectedByViewportChange() {
DCHECK(IsMaster());
DCHECK(global_rule_set_);
- const MediaQueryEvaluator& evaluator = EnsureMediaQueryEvaluator();
- const auto& results = global_rule_set_->GetRuleFeatureSet()
- .ViewportDependentMediaQueryResults();
- for (unsigned i = 0; i < results.size(); ++i) {
- if (evaluator.Eval(results[i].Expression()) != results[i].Result())
- return true;
- }
- return false;
+ return EnsureMediaQueryEvaluator().DidResultsChange(
+ global_rule_set_->GetRuleFeatureSet()
+ .ViewportDependentMediaQueryResults());
}
bool StyleEngine::MediaQueryAffectedByDeviceChange() {
DCHECK(IsMaster());
DCHECK(global_rule_set_);
- const MediaQueryEvaluator& evaluator = EnsureMediaQueryEvaluator();
- const auto& results =
- global_rule_set_->GetRuleFeatureSet().DeviceDependentMediaQueryResults();
- for (unsigned i = 0; i < results.size(); ++i) {
- if (evaluator.Eval(results[i].Expression()) != results[i].Result())
- return true;
- }
- return false;
+ return EnsureMediaQueryEvaluator().DidResultsChange(
+ global_rule_set_->GetRuleFeatureSet().DeviceDependentMediaQueryResults());
}
bool StyleEngine::UpdateRemUnits(const ComputedStyle* old_root_style,
const ComputedStyle* new_root_style) {
if (!new_root_style || !UsesRemUnits())
return false;
- if (!old_root_style ||
- old_root_style->FontSize() != new_root_style->FontSize()) {
+ if (!old_root_style || old_root_style->SpecifiedFontSize() !=
+ new_root_style->SpecifiedFontSize()) {
DCHECK(Resolver());
// Resolved rem units are stored in the matched properties cache so we need
// to make sure to invalidate the cache if the documentElement font size
@@ -1645,7 +1815,7 @@ void StyleEngine::NodeWillBeRemoved(Node& node) {
if (!layout_object)
return;
// Floating or out-of-flow elements do not affect whitespace siblings.
- if (layout_object->IsFloatingOrOutOfFlowPositioned())
+ if (!layout_object->AffectsWhitespaceSiblings())
return;
layout_object = layout_object->Parent();
while (layout_object->IsAnonymous())
@@ -1688,9 +1858,9 @@ void StyleEngine::CollectMatchingUserRules(
}
}
-void StyleEngine::AddUserFontFaceRules(const RuleSet& rule_set) {
+bool StyleEngine::AddUserFontFaceRules(const RuleSet& rule_set) {
if (!font_selector_)
- return;
+ return false;
const HeapVector<Member<StyleRuleFontFace>> font_face_rules =
rule_set.FontFaceRules();
@@ -1700,6 +1870,7 @@ void StyleEngine::AddUserFontFaceRules(const RuleSet& rule_set) {
}
if (resolver_ && font_face_rules.size())
resolver_->InvalidateMatchedPropertiesCache();
+ return font_face_rules.size();
}
void StyleEngine::AddUserKeyframeRules(const RuleSet& rule_set) {
@@ -1950,7 +2121,7 @@ void StyleEngine::UpdateColorScheme() {
forced_colors_ = web_theme_engine->GetForcedColors();
PreferredColorScheme old_preferred_color_scheme = preferred_color_scheme_;
- preferred_color_scheme_ = web_theme_engine->PreferredColorScheme();
+ preferred_color_scheme_ = settings->GetPreferredColorScheme();
if (const auto* overrides =
GetDocument().GetPage()->GetMediaFeatureOverrides()) {
MediaQueryExpValue value = overrides->GetOverride("prefers-color-scheme");
@@ -1960,7 +2131,7 @@ void StyleEngine::UpdateColorScheme() {
bool use_dark_scheme =
preferred_color_scheme_ == PreferredColorScheme::kDark &&
SupportsDarkColorScheme();
- if (!use_dark_scheme && settings->ForceDarkModeEnabled()) {
+ if (!use_dark_scheme && settings->GetForceDarkModeEnabled()) {
// Make sure we don't match (prefers-color-scheme: dark) when forced
// darkening is enabled.
preferred_color_scheme_ = PreferredColorScheme::kNoPreference;
@@ -1998,7 +2169,7 @@ void StyleEngine::UpdateColorSchemeBackground() {
if (auto* root_element = GetDocument().documentElement())
style = root_element->GetComputedStyle();
if (style) {
- if (style->UsedColorScheme() == WebColorScheme::kDark)
+ if (style->UsedColorSchemeForInitialColors() == WebColorScheme::kDark)
use_dark_background = true;
} else if (SupportsDarkColorScheme()) {
use_dark_background = true;
@@ -2046,7 +2217,7 @@ void StyleEngine::PropagateWritingModeAndDirectionToHTMLRoot() {
root_element->PropagateWritingModeAndDirectionFromBody();
}
-void StyleEngine::Trace(blink::Visitor* visitor) {
+void StyleEngine::Trace(Visitor* visitor) {
visitor->Trace(document_);
visitor->Trace(injected_user_style_sheets_);
visitor->Trace(injected_author_style_sheets_);
@@ -2060,6 +2231,7 @@ void StyleEngine::Trace(blink::Visitor* visitor) {
visitor->Trace(active_tree_scopes_);
visitor->Trace(tree_boundary_crossing_scopes_);
visitor->Trace(resolver_);
+ visitor->Trace(vision_deficiency_filter_);
visitor->Trace(viewport_resolver_);
visitor->Trace(media_query_evaluator_);
visitor->Trace(global_rule_set_);
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 44e3046e90c..e33a320f61a 100644
--- a/chromium/third_party/blink/renderer/core/css/style_engine.h
+++ b/chromium/third_party/blink/renderer/core/css/style_engine.h
@@ -48,9 +48,11 @@
#include "third_party/blink/renderer/core/css/style_engine_context.h"
#include "third_party/blink/renderer/core/css/style_invalidation_root.h"
#include "third_party/blink/renderer/core/css/style_recalc_root.h"
+#include "third_party/blink/renderer/core/css/vision_deficiency.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/tree_ordered_list.h"
#include "third_party/blink/renderer/core/html/track/text_track.h"
+#include "third_party/blink/renderer/core/style/filter_operations.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/fonts/font_selector_client.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -80,7 +82,7 @@ using StyleSheetKey = AtomicString;
// The StyleEngine class manages style-related state for the document. There is
// a 1-1 relationship of Document to StyleEngine. The document calls the
-// StyleEngine when the the document is updated in a way that impacts styles.
+// StyleEngine when the document is updated in a way that impacts styles.
class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
public FontSelectorClient,
public NameClient {
@@ -154,7 +156,7 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
}
RuleSet* RuleSetForSheet(CSSStyleSheet&);
- void MediaQueryAffectingValueChanged();
+ void MediaQueryAffectingValueChanged(MediaValueChange change);
void UpdateActiveStyleSheetsInImport(
StyleEngine& master_engine,
DocumentStyleSheetCollector& parent_collector);
@@ -243,7 +245,6 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
void UpdateLayoutTreeRebuildRoot(ContainerNode* ancestor, Node* dirty_node);
CSSFontSelector* GetFontSelector() { return font_selector_; }
- void SetFontSelector(CSSFontSelector*);
void RemoveFontFaceRules(const HeapVector<Member<const StyleRuleFontFace>>&);
// updateGenericFontFamilySettings is used from WebSettingsImpl.
@@ -268,6 +269,7 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
}
void EnsureUAStyleForFullscreen();
+ void EnsureUAStyleForXrOverlay();
void EnsureUAStyleForElement(const Element&);
void PlatformColorsChanged();
@@ -323,6 +325,10 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
void ApplyUserRuleSetChanges(const ActiveStyleSheetVector& old_style_sheets,
const ActiveStyleSheetVector& new_style_sheets);
+ void VisionDeficiencyChanged();
+ void ApplyVisionDeficiencyStyle(
+ scoped_refptr<ComputedStyle> layout_view_style);
+
void CollectMatchingUserRules(ElementRuleCollector&) const;
void CustomPropertyRegistered();
@@ -344,6 +350,9 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
void MarkViewportStyleDirty();
bool IsViewportStyleDirty() const { return viewport_style_dirty_; }
+ void MarkFontsNeedUpdate();
+ void InvalidateStyleAndLayoutForFontUpdates();
+
StyleRuleKeyframes* KeyframeStylesForAnimation(
const AtomicString& animation_name);
@@ -375,13 +384,15 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
ForcedColors GetForcedColors() const { return forced_colors_; }
void UpdateColorSchemeBackground();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
const char* NameInHeapSnapshot() const override { return "StyleEngine"; }
private:
// FontSelectorClient implementation.
void FontsNeedUpdate(FontSelector*) override;
+ void LoadVisionDeficiencyFilter();
+
private:
bool NeedsActiveStyleSheetUpdate() const {
return all_tree_scopes_dirty_ || tree_scopes_removed_ ||
@@ -404,8 +415,14 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
typedef HeapHashSet<Member<TreeScope>> UnorderedTreeScopeSet;
- void MediaQueryAffectingValueChanged(UnorderedTreeScopeSet&);
- void MediaQueryAffectingValueChanged(HeapHashSet<Member<TextTrack>>&);
+ bool MediaQueryAffectingValueChanged(const ActiveStyleSheetVector&,
+ MediaValueChange);
+ void MediaQueryAffectingValueChanged(TreeScope&, MediaValueChange);
+ void MediaQueryAffectingValueChanged(UnorderedTreeScopeSet&,
+ MediaValueChange);
+ void MediaQueryAffectingValueChanged(HeapHashSet<Member<TextTrack>>&,
+ MediaValueChange);
+
const RuleFeatureSet& GetRuleFeatureSet() const {
DCHECK(IsMaster());
DCHECK(global_rule_set_);
@@ -447,7 +464,8 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
TreeScope& tree_scope,
const HeapHashSet<Member<RuleSet>>& changed_rule_sets,
unsigned changed_rule_flags,
- InvalidationScope invalidation_scope);
+ InvalidationScope invalidation_scope,
+ bool rebuild_font_cache);
void InvalidateInitialData();
void UpdateViewport();
@@ -461,11 +479,14 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
const MediaQueryEvaluator& EnsureMediaQueryEvaluator();
void UpdateStyleSheetList(TreeScope&);
- void ClearFontCacheAndAddUserFonts();
+ // Returns true if any @font-face rules are added or removed.
+ bool ClearFontCacheAndAddUserFonts();
+
void ClearKeyframeRules() { keyframes_rule_map_.clear(); }
void ClearPropertyRules();
- void AddUserFontFaceRules(const RuleSet&);
+ // Returns true if any @font-face rules are added.
+ bool AddUserFontFaceRules(const RuleSet&);
void AddUserKeyframeRules(const RuleSet&);
void AddUserKeyframeStyle(StyleRuleKeyframes*);
void AddPropertyRules(const RuleSet&);
@@ -528,6 +549,10 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
bool in_layout_tree_rebuild_ = false;
bool in_dom_removal_ = false;
bool viewport_style_dirty_ = false;
+ bool fonts_need_update_ = false;
+
+ VisionDeficiency vision_deficiency_ = VisionDeficiency::kNoVisionDeficiency;
+ Member<ReferenceFilterOperation> vision_deficiency_filter_;
Member<StyleResolver> resolver_;
Member<ViewportStyleResolver> viewport_resolver_;
@@ -577,9 +602,9 @@ class CORE_EXPORT StyleEngine final : public GarbageCollected<StyleEngine>,
// scheme is used to opt-out of forced darkening.
Member<const CSSValue> meta_color_scheme_;
- // The preferred color scheme is set in WebThemeEngine, 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.
+ // 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;
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 ea225bc6809..0bab3c371e1 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
@@ -13,6 +13,7 @@
#include "third_party/blink/public/platform/web_float_rect.h"
#include "third_party/blink/public/platform/web_theme_engine.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_shadow_root_init.h"
#include "third_party/blink/renderer/core/animation/element_animations.h"
#include "third_party/blink/renderer/core/css/css_font_selector.h"
#include "third_party/blink/renderer/core/css/css_rule_list.h"
@@ -25,7 +26,6 @@
#include "third_party/blink/renderer/core/dom/first_letter_pseudo_element.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
-#include "third_party/blink/renderer/core/dom/shadow_root_init.h"
#include "third_party/blink/renderer/core/dom/slot_assignment_engine.h"
#include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
@@ -65,8 +65,7 @@ class StyleEngineTest : public testing::Test {
// A wrapper to add a reason for UpdateAllLifecyclePhases
void UpdateAllLifecyclePhases() {
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
}
Node* GetStyleRecalcRoot() {
@@ -110,7 +109,7 @@ TEST_F(StyleEngineTest, DocumentDirtyAfterInject) {
}
TEST_F(StyleEngineTest, AnalyzedInject) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
@font-face {
font-family: 'Cool Font';
@@ -297,7 +296,7 @@ TEST_F(StyleEngineTest, AnalyzedInject) {
auto* style_element = MakeGarbageCollected<HTMLStyleElement>(
GetDocument(), CreateElementFlags());
- style_element->SetInnerHTMLFromString(
+ style_element->setInnerHTML(
"@font-face {"
" font-family: 'Cool Font';"
" src: url(dummy);"
@@ -366,8 +365,7 @@ TEST_F(StyleEngineTest, AnalyzedInject) {
style_element = MakeGarbageCollected<HTMLStyleElement>(GetDocument(),
CreateElementFlags());
- style_element->SetInnerHTMLFromString(
- "@keyframes dummy-animation { from {} to {} }");
+ style_element->setInnerHTML("@keyframes dummy-animation { from {} to {} }");
GetDocument().body()->AppendChild(style_element);
UpdateAllLifecyclePhases();
@@ -621,7 +619,7 @@ TEST_F(StyleEngineTest, AnalyzedInject) {
}
TEST_F(StyleEngineTest, InjectedFontFace) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
@font-face {
font-family: 'Author';
@@ -654,7 +652,7 @@ TEST_F(StyleEngineTest, InjectedFontFace) {
}
TEST_F(StyleEngineTest, IgnoreInvalidPropertyValue) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<section><div id='t1'>Red</div></section>"
"<style id='s1'>div { color: red; } section div#t1 { color:rgb(0");
UpdateAllLifecyclePhases();
@@ -706,7 +704,7 @@ TEST_F(StyleEngineTest, TextToSheetCache) {
}
TEST_F(StyleEngineTest, RuleSetInvalidationTypeSelectors) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<div>
<span></span>
<div></div>
@@ -752,7 +750,7 @@ TEST_F(StyleEngineTest, RuleSetInvalidationTypeSelectors) {
}
TEST_F(StyleEngineTest, RuleSetInvalidationCustomPseudo) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>progress { -webkit-appearance:none }</style>
<progress></progress>
<div></div><div></div><div></div><div></div><div></div><div></div>
@@ -770,7 +768,7 @@ TEST_F(StyleEngineTest, RuleSetInvalidationCustomPseudo) {
}
TEST_F(StyleEngineTest, RuleSetInvalidationHost) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<div id=nohost></div><div id=host></div>");
Element* host = GetDocument().getElementById("host");
ASSERT_TRUE(host);
@@ -778,7 +776,7 @@ TEST_F(StyleEngineTest, RuleSetInvalidationHost) {
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString("<div></div><div></div><div></div>");
+ shadow_root.setInnerHTML("<div></div><div></div><div></div>");
UpdateAllLifecyclePhases();
unsigned before_count = GetStyleEngine().StyleForElementCount();
@@ -809,7 +807,7 @@ TEST_F(StyleEngineTest, RuleSetInvalidationHost) {
}
TEST_F(StyleEngineTest, RuleSetInvalidationSlotted) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<div id=host>
<span slot=other class=s1></span>
<span class=s2></span>
@@ -824,7 +822,7 @@ TEST_F(StyleEngineTest, RuleSetInvalidationSlotted) {
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString("<slot name=other></slot><slot></slot>");
+ shadow_root.setInnerHTML("<slot name=other></slot><slot></slot>");
UpdateAllLifecyclePhases();
unsigned before_count = GetStyleEngine().StyleForElementCount();
@@ -845,15 +843,14 @@ TEST_F(StyleEngineTest, RuleSetInvalidationSlotted) {
}
TEST_F(StyleEngineTest, RuleSetInvalidationHostContext) {
- GetDocument().body()->SetInnerHTMLFromString("<div id=host></div>");
+ GetDocument().body()->setInnerHTML("<div id=host></div>");
Element* host = GetDocument().getElementById("host");
ASSERT_TRUE(host);
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString(
- "<div></div><div class=a></div><div></div>");
+ shadow_root.setInnerHTML("<div></div><div class=a></div><div></div>");
UpdateAllLifecyclePhases();
unsigned before_count = GetStyleEngine().StyleForElementCount();
@@ -873,15 +870,14 @@ TEST_F(StyleEngineTest, RuleSetInvalidationHostContext) {
}
TEST_F(StyleEngineTest, RuleSetInvalidationV0BoundaryCrossing) {
- GetDocument().body()->SetInnerHTMLFromString("<div id=host></div>");
+ GetDocument().body()->setInnerHTML("<div id=host></div>");
Element* host = GetDocument().getElementById("host");
ASSERT_TRUE(host);
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString(
- "<div></div><div class=a></div><div></div>");
+ shadow_root.setInnerHTML("<div></div><div class=a></div><div></div>");
UpdateAllLifecyclePhases();
EXPECT_EQ(ScheduleInvalidationsForRules(
@@ -890,7 +886,7 @@ TEST_F(StyleEngineTest, RuleSetInvalidationV0BoundaryCrossing) {
}
TEST_F(StyleEngineTest, HasViewportDependentMediaQueries) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>div {}</style>
<style id='sheet' media='(min-width: 200px)'>
div {}
@@ -915,7 +911,7 @@ TEST_F(StyleEngineTest, HasViewportDependentMediaQueries) {
}
TEST_F(StyleEngineTest, StyleMediaAttributeStyleChange) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<style id='s1' media='(max-width: 1px)'>#t1 { color: green }</style>"
"<div id='t1'>Green</div><div></div>");
UpdateAllLifecyclePhases();
@@ -941,7 +937,7 @@ TEST_F(StyleEngineTest, StyleMediaAttributeStyleChange) {
}
TEST_F(StyleEngineTest, StyleMediaAttributeNoStyleChange) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<style id='s1' media='(max-width: 1000px)'>#t1 { color: green }</style>"
"<div id='t1'>Green</div><div></div>");
UpdateAllLifecyclePhases();
@@ -972,7 +968,7 @@ TEST_F(StyleEngineTest, ModifyStyleRuleMatchedPropertiesCache) {
// CSSPropertyValueSet pointers. When a mutable CSSPropertyValueSet is
// modified, the pointer doesn't change, yet the declarations do.
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<style id='s1'>#t1 { color: blue }</style>"
"<div id='t1'>Green</div>");
UpdateAllLifecyclePhases();
@@ -996,16 +992,16 @@ TEST_F(StyleEngineTest, ModifyStyleRuleMatchedPropertiesCache) {
// Modify the CSSPropertyValueSet once to make it a mutable set. Subsequent
// modifications will not change the CSSPropertyValueSet pointer and cache
// hash value will be the same.
- style_rule->style()->setProperty(&GetDocument(), "color", "red", "",
- ASSERT_NO_EXCEPTION);
+ style_rule->style()->setProperty(GetDocument().GetExecutionContext(), "color",
+ "red", "", ASSERT_NO_EXCEPTION);
UpdateAllLifecyclePhases();
ASSERT_TRUE(t1->GetComputedStyle());
EXPECT_EQ(MakeRGB(255, 0, 0), t1->GetComputedStyle()->VisitedDependentColor(
GetCSSPropertyColor()));
- style_rule->style()->setProperty(&GetDocument(), "color", "green", "",
- ASSERT_NO_EXCEPTION);
+ style_rule->style()->setProperty(GetDocument().GetExecutionContext(), "color",
+ "green", "", ASSERT_NO_EXCEPTION);
UpdateAllLifecyclePhases();
ASSERT_TRUE(t1->GetComputedStyle());
@@ -1014,7 +1010,7 @@ TEST_F(StyleEngineTest, ModifyStyleRuleMatchedPropertiesCache) {
}
TEST_F(StyleEngineTest, VisitedExplicitInheritanceMatchedPropertiesCache) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
:visited { overflow: inherit }
</style>
@@ -1036,7 +1032,7 @@ TEST_F(StyleEngineTest, VisitedExplicitInheritanceMatchedPropertiesCache) {
}
TEST_F(StyleEngineTest, ScheduleInvalidationAfterSubtreeRecalc) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style id='s1'>
.t1 span { color: green }
.t2 span { color: green }
@@ -1108,8 +1104,8 @@ TEST_F(StyleEngineTest, ScheduleInvalidationAfterSubtreeRecalc) {
EXPECT_FALSE(t2->NeedsStyleInvalidation());
}
-TEST_F(StyleEngineTest, NoScheduledRuleSetInvalidationsOnNewShadow) {
- GetDocument().body()->SetInnerHTMLFromString("<div id='host'></div>");
+TEST_F(StyleEngineTest, ScheduleRuleSetInvalidationsOnNewShadow) {
+ GetDocument().body()->setInnerHTML("<div id='host'></div>");
Element* host = GetDocument().getElementById("host");
ASSERT_TRUE(host);
@@ -1117,7 +1113,7 @@ TEST_F(StyleEngineTest, NoScheduledRuleSetInvalidationsOnNewShadow) {
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString(R"HTML(
+ shadow_root.setInnerHTML(R"HTML(
<style>
span { color: green }
t1 { color: green }
@@ -1127,12 +1123,13 @@ TEST_F(StyleEngineTest, NoScheduledRuleSetInvalidationsOnNewShadow) {
)HTML");
GetStyleEngine().UpdateActiveStyle();
- EXPECT_FALSE(GetDocument().ChildNeedsStyleInvalidation());
+ EXPECT_TRUE(GetDocument().ChildNeedsStyleInvalidation());
EXPECT_FALSE(GetDocument().NeedsStyleInvalidation());
+ EXPECT_TRUE(shadow_root.NeedsStyleInvalidation());
}
TEST_F(StyleEngineTest, EmptyHttpEquivDefaultStyle) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<style>div { color:pink }</style><div id=container></div>");
UpdateAllLifecyclePhases();
@@ -1140,18 +1137,16 @@ TEST_F(StyleEngineTest, EmptyHttpEquivDefaultStyle) {
Element* container = GetDocument().getElementById("container");
ASSERT_TRUE(container);
- container->SetInnerHTMLFromString(
- "<meta http-equiv='default-style' content=''>");
+ container->setInnerHTML("<meta http-equiv='default-style' content=''>");
EXPECT_FALSE(GetStyleEngine().NeedsActiveStyleUpdate());
- container->SetInnerHTMLFromString(
+ container->setInnerHTML(
"<meta http-equiv='default-style' content='preferred'>");
EXPECT_TRUE(GetStyleEngine().NeedsActiveStyleUpdate());
}
TEST_F(StyleEngineTest, StyleSheetsForStyleSheetList_Document) {
- GetDocument().body()->SetInnerHTMLFromString(
- "<style>span { color: green }</style>");
+ GetDocument().body()->setInnerHTML("<style>span { color: green }</style>");
EXPECT_TRUE(GetStyleEngine().NeedsActiveStyleUpdate());
const auto& sheet_list =
@@ -1159,7 +1154,7 @@ TEST_F(StyleEngineTest, StyleSheetsForStyleSheetList_Document) {
EXPECT_EQ(1u, sheet_list.size());
EXPECT_TRUE(GetStyleEngine().NeedsActiveStyleUpdate());
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<style>span { color: green }</style><style>div { color: pink }</style>");
EXPECT_TRUE(GetStyleEngine().NeedsActiveStyleUpdate());
@@ -1174,7 +1169,7 @@ TEST_F(StyleEngineTest, StyleSheetsForStyleSheetList_Document) {
}
TEST_F(StyleEngineTest, StyleSheetsForStyleSheetList_ShadowRoot) {
- GetDocument().body()->SetInnerHTMLFromString("<div id='host'></div>");
+ GetDocument().body()->setInnerHTML("<div id='host'></div>");
Element* host = GetDocument().getElementById("host");
ASSERT_TRUE(host);
@@ -1182,7 +1177,7 @@ TEST_F(StyleEngineTest, StyleSheetsForStyleSheetList_ShadowRoot) {
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString("<style>span { color: green }</style>");
+ shadow_root.setInnerHTML("<style>span { color: green }</style>");
EXPECT_TRUE(GetStyleEngine().NeedsActiveStyleUpdate());
const auto& sheet_list =
@@ -1190,7 +1185,7 @@ TEST_F(StyleEngineTest, StyleSheetsForStyleSheetList_ShadowRoot) {
EXPECT_EQ(1u, sheet_list.size());
EXPECT_TRUE(GetStyleEngine().NeedsActiveStyleUpdate());
- shadow_root.SetInnerHTMLFromString(
+ shadow_root.setInnerHTML(
"<style>span { color: green }</style><style>div { color: pink }</style>");
EXPECT_TRUE(GetStyleEngine().NeedsActiveStyleUpdate());
@@ -1230,7 +1225,7 @@ TEST_F(StyleEngineTest, ViewportDescriptionForZoomDSF) {
WebViewImpl* web_view_impl =
web_view_helper.Initialize(nullptr, nullptr, &client);
web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
Document* document =
To<LocalFrame>(web_view_impl->GetPage()->MainFrame())->GetDocument();
@@ -1244,7 +1239,7 @@ TEST_F(StyleEngineTest, ViewportDescriptionForZoomDSF) {
const float device_scale = 3.5f;
client.set_device_scale_factor(device_scale);
web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
desc = document->GetViewportData().GetViewportDescription();
EXPECT_FLOAT_EQ(device_scale * min_width, desc.min_width.GetFloatValue());
@@ -1254,28 +1249,25 @@ TEST_F(StyleEngineTest, ViewportDescriptionForZoomDSF) {
}
TEST_F(StyleEngineTest, MediaQueryAffectingValueChanged_StyleElementNoMedia) {
- GetDocument().body()->SetInnerHTMLFromString(
- "<style>div{color:pink}</style>");
+ GetDocument().body()->setInnerHTML("<style>div{color:pink}</style>");
UpdateAllLifecyclePhases();
- GetStyleEngine().MediaQueryAffectingValueChanged();
+ GetStyleEngine().MediaQueryAffectingValueChanged(MediaValueChange::kOther);
EXPECT_FALSE(GetStyleEngine().NeedsActiveStyleUpdate());
}
TEST_F(StyleEngineTest,
MediaQueryAffectingValueChanged_StyleElementMediaNoValue) {
- GetDocument().body()->SetInnerHTMLFromString(
- "<style media>div{color:pink}</style>");
+ GetDocument().body()->setInnerHTML("<style media>div{color:pink}</style>");
UpdateAllLifecyclePhases();
- GetStyleEngine().MediaQueryAffectingValueChanged();
+ GetStyleEngine().MediaQueryAffectingValueChanged(MediaValueChange::kOther);
EXPECT_FALSE(GetStyleEngine().NeedsActiveStyleUpdate());
}
TEST_F(StyleEngineTest,
MediaQueryAffectingValueChanged_StyleElementMediaEmpty) {
- GetDocument().body()->SetInnerHTMLFromString(
- "<style media=''>div{color:pink}</style>");
+ GetDocument().body()->setInnerHTML("<style media=''>div{color:pink}</style>");
UpdateAllLifecyclePhases();
- GetStyleEngine().MediaQueryAffectingValueChanged();
+ GetStyleEngine().MediaQueryAffectingValueChanged(MediaValueChange::kOther);
EXPECT_FALSE(GetStyleEngine().NeedsActiveStyleUpdate());
}
@@ -1285,40 +1277,40 @@ TEST_F(StyleEngineTest,
TEST_F(StyleEngineTest,
MediaQueryAffectingValueChanged_StyleElementMediaNoValid) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<style media=',,'>div{color:pink}</style>");
UpdateAllLifecyclePhases();
- GetStyleEngine().MediaQueryAffectingValueChanged();
+ GetStyleEngine().MediaQueryAffectingValueChanged(MediaValueChange::kOther);
EXPECT_TRUE(GetStyleEngine().NeedsActiveStyleUpdate());
}
TEST_F(StyleEngineTest, MediaQueryAffectingValueChanged_StyleElementMediaAll) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<style media='all'>div{color:pink}</style>");
UpdateAllLifecyclePhases();
- GetStyleEngine().MediaQueryAffectingValueChanged();
+ GetStyleEngine().MediaQueryAffectingValueChanged(MediaValueChange::kOther);
EXPECT_TRUE(GetStyleEngine().NeedsActiveStyleUpdate());
}
TEST_F(StyleEngineTest,
MediaQueryAffectingValueChanged_StyleElementMediaNotAll) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<style media='not all'>div{color:pink}</style>");
UpdateAllLifecyclePhases();
- GetStyleEngine().MediaQueryAffectingValueChanged();
+ GetStyleEngine().MediaQueryAffectingValueChanged(MediaValueChange::kOther);
EXPECT_TRUE(GetStyleEngine().NeedsActiveStyleUpdate());
}
TEST_F(StyleEngineTest, MediaQueryAffectingValueChanged_StyleElementMediaType) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<style media='print'>div{color:pink}</style>");
UpdateAllLifecyclePhases();
- GetStyleEngine().MediaQueryAffectingValueChanged();
+ GetStyleEngine().MediaQueryAffectingValueChanged(MediaValueChange::kOther);
EXPECT_TRUE(GetStyleEngine().NeedsActiveStyleUpdate());
}
TEST_F(StyleEngineTest, EmptyPseudo_RemoveLast) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
.empty:empty + span { color: purple }
</style>
@@ -1340,7 +1332,7 @@ TEST_F(StyleEngineTest, EmptyPseudo_RemoveLast) {
}
TEST_F(StyleEngineTest, EmptyPseudo_RemoveNotLast) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
.empty:empty + span { color: purple }
</style>
@@ -1362,7 +1354,7 @@ TEST_F(StyleEngineTest, EmptyPseudo_RemoveNotLast) {
}
TEST_F(StyleEngineTest, EmptyPseudo_InsertFirst) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
.empty:empty + span { color: purple }
</style>
@@ -1384,7 +1376,7 @@ TEST_F(StyleEngineTest, EmptyPseudo_InsertFirst) {
}
TEST_F(StyleEngineTest, EmptyPseudo_InsertNotFirst) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
.empty:empty + span { color: purple }
</style>
@@ -1406,7 +1398,7 @@ TEST_F(StyleEngineTest, EmptyPseudo_InsertNotFirst) {
}
TEST_F(StyleEngineTest, EmptyPseudo_ModifyTextData_SingleNode) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
.empty:empty + span { color: purple }
</style>
@@ -1439,7 +1431,7 @@ TEST_F(StyleEngineTest, EmptyPseudo_ModifyTextData_SingleNode) {
}
TEST_F(StyleEngineTest, EmptyPseudo_ModifyTextData_HasSiblings) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
.empty:empty + span { color: purple }
</style>
@@ -1470,7 +1462,7 @@ TEST_F(StyleEngineTest, EmptyPseudo_ModifyTextData_HasSiblings) {
}
TEST_F(StyleEngineTest, MediaQueriesChangeDefaultFontSize) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
body { color: red }
@media (max-width: 40em) {
@@ -1493,9 +1485,10 @@ TEST_F(StyleEngineTest, MediaQueriesChangeDefaultFontSize) {
}
TEST_F(StyleEngineTest, MediaQueriesChangeColorScheme) {
- ScopedMediaQueryPrefersColorSchemeForTest feature_scope(true);
+ ColorSchemeHelper color_scheme_helper(GetDocument());
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kLight);
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
body { color: red }
@media (prefers-color-scheme: dark) {
@@ -1510,9 +1503,7 @@ TEST_F(StyleEngineTest, MediaQueriesChangeColorScheme) {
GetDocument().body()->GetComputedStyle()->VisitedDependentColor(
GetCSSPropertyColor()));
- ColorSchemeHelper color_scheme_helper;
- color_scheme_helper.SetPreferredColorScheme(GetDocument(),
- PreferredColorScheme::kDark);
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kDark);
UpdateAllLifecyclePhases();
EXPECT_EQ(MakeRGB(0, 128, 0),
GetDocument().body()->GetComputedStyle()->VisitedDependentColor(
@@ -1520,14 +1511,11 @@ TEST_F(StyleEngineTest, MediaQueriesChangeColorScheme) {
}
TEST_F(StyleEngineTest, MediaQueriesChangeColorSchemeForcedDarkMode) {
- ScopedMediaQueryPrefersColorSchemeForTest feature_scope(true);
-
GetDocument().GetSettings()->SetForceDarkModeEnabled(true);
- ColorSchemeHelper color_scheme_helper;
- color_scheme_helper.SetPreferredColorScheme(GetDocument(),
- PreferredColorScheme::kDark);
+ ColorSchemeHelper color_scheme_helper(GetDocument());
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kDark);
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
@media (prefers-color-scheme: no-preference) {
body { color: green }
@@ -1546,7 +1534,7 @@ TEST_F(StyleEngineTest, MediaQueriesChangeColorSchemeForcedDarkMode) {
}
TEST_F(StyleEngineTest, MediaQueriesChangePrefersReducedMotion) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
body { color: red }
@media (prefers-reduced-motion: reduce) {
@@ -1570,7 +1558,7 @@ TEST_F(StyleEngineTest, MediaQueriesChangePrefersReducedMotion) {
TEST_F(StyleEngineTest, MediaQueriesChangeForcedColors) {
ScopedForcedColorsForTest scoped_feature(true);
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
body {
forced-color-adjust: none;
@@ -1590,7 +1578,7 @@ TEST_F(StyleEngineTest, MediaQueriesChangeForcedColors) {
GetDocument().body()->GetComputedStyle()->VisitedDependentColor(
GetCSSPropertyColor()));
- ColorSchemeHelper color_scheme_helper;
+ ColorSchemeHelper color_scheme_helper(GetDocument());
color_scheme_helper.SetForcedColors(GetDocument(), ForcedColors::kActive);
UpdateAllLifecyclePhases();
EXPECT_EQ(MakeRGB(0, 128, 0),
@@ -1600,7 +1588,7 @@ TEST_F(StyleEngineTest, MediaQueriesChangeForcedColors) {
TEST_F(StyleEngineTest, MediaQueriesChangeForcedColorsAndPreferredColorScheme) {
ScopedForcedColorsForTest scoped_feature(true);
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
body {
forced-color-adjust: none;
@@ -1625,18 +1613,16 @@ TEST_F(StyleEngineTest, MediaQueriesChangeForcedColorsAndPreferredColorScheme) {
)HTML");
// ForcedColors = kNone, PreferredColorScheme = kLight
- ColorSchemeHelper color_scheme_helper;
+ ColorSchemeHelper color_scheme_helper(GetDocument());
color_scheme_helper.SetForcedColors(GetDocument(), ForcedColors::kNone);
- color_scheme_helper.SetPreferredColorScheme(GetDocument(),
- PreferredColorScheme::kLight);
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kLight);
UpdateAllLifecyclePhases();
EXPECT_EQ(MakeRGB(255, 0, 0),
GetDocument().body()->GetComputedStyle()->VisitedDependentColor(
GetCSSPropertyColor()));
// ForcedColors = kNone, PreferredColorScheme = kDark
- color_scheme_helper.SetPreferredColorScheme(GetDocument(),
- PreferredColorScheme::kDark);
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kDark);
UpdateAllLifecyclePhases();
EXPECT_EQ(MakeRGB(0, 128, 0),
GetDocument().body()->GetComputedStyle()->VisitedDependentColor(
@@ -1651,15 +1637,14 @@ TEST_F(StyleEngineTest, MediaQueriesChangeForcedColorsAndPreferredColorScheme) {
// ForcedColors = kActive, PreferredColorScheme = kNoPreference
color_scheme_helper.SetPreferredColorScheme(
- GetDocument(), PreferredColorScheme::kNoPreference);
+ PreferredColorScheme::kNoPreference);
UpdateAllLifecyclePhases();
EXPECT_EQ(MakeRGB(255, 255, 0),
GetDocument().body()->GetComputedStyle()->VisitedDependentColor(
GetCSSPropertyColor()));
// ForcedColors = kActive, PreferredColorScheme = kLight
- color_scheme_helper.SetPreferredColorScheme(GetDocument(),
- PreferredColorScheme::kLight);
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kLight);
UpdateAllLifecyclePhases();
EXPECT_EQ(MakeRGB(0, 0, 255),
GetDocument().body()->GetComputedStyle()->VisitedDependentColor(
@@ -1667,12 +1652,12 @@ TEST_F(StyleEngineTest, MediaQueriesChangeForcedColorsAndPreferredColorScheme) {
}
TEST_F(StyleEngineTest, MediaQueriesColorSchemeOverride) {
- ScopedMediaQueryPrefersColorSchemeForTest feature_scope(true);
-
+ ColorSchemeHelper color_scheme_helper(GetDocument());
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kLight);
EXPECT_EQ(PreferredColorScheme::kLight,
- Platform::Current()->ThemeEngine()->PreferredColorScheme());
+ GetDocument().GetSettings()->GetPreferredColorScheme());
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
body { color: red }
@media (prefers-color-scheme: dark) {
@@ -1704,7 +1689,7 @@ TEST_F(StyleEngineTest, MediaQueriesColorSchemeOverride) {
TEST_F(StyleEngineTest, MediaQueriesReducedMotionOverride) {
EXPECT_FALSE(GetDocument().GetSettings()->GetPrefersReducedMotion());
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
body { color: red }
@media (prefers-reduced-motion: reduce) {
@@ -1735,7 +1720,7 @@ TEST_F(StyleEngineTest, MediaQueriesReducedMotionOverride) {
TEST_F(StyleEngineTest, MediaQueriesChangeNavigationControls) {
ScopedMediaQueryNavigationControlsForTest scoped_feature(true);
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
@media (navigation-controls: none) {
body { color: red }
@@ -1761,14 +1746,14 @@ TEST_F(StyleEngineTest, MediaQueriesChangeNavigationControls) {
}
TEST_F(StyleEngineTest, ShadowRootStyleRecalcCrash) {
- GetDocument().body()->SetInnerHTMLFromString("<div id=host></div>");
+ GetDocument().body()->setInnerHTML("<div id=host></div>");
auto* host = To<HTMLElement>(GetDocument().getElementById("host"));
ASSERT_TRUE(host);
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString(R"HTML(
+ shadow_root.setInnerHTML(R"HTML(
<span id=span></span>
<style>
:nth-child(odd) { color: green }
@@ -1783,7 +1768,7 @@ TEST_F(StyleEngineTest, ShadowRootStyleRecalcCrash) {
}
TEST_F(StyleEngineTest, GetComputedStyleOutsideFlatTreeCrash) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
body, div { display: contents }
div::before { display: contents; content: "" }
@@ -1800,7 +1785,7 @@ TEST_F(StyleEngineTest, GetComputedStyleOutsideFlatTreeCrash) {
}
TEST_F(StyleEngineTest, RejectSelectorForPseudoElement) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
div::before { content: "" }
.not-in-filter div::before { color: red }
@@ -1810,10 +1795,13 @@ TEST_F(StyleEngineTest, RejectSelectorForPseudoElement) {
UpdateAllLifecyclePhases();
StyleEngine& engine = GetStyleEngine();
+ // If the Stats() were already enabled, we would not start with 0 counts.
+ EXPECT_FALSE(engine.Stats());
engine.SetStatsEnabled(true);
StyleResolverStats* stats = engine.Stats();
ASSERT_TRUE(stats);
+ EXPECT_EQ(0u, stats->rules_fast_rejected);
Element* div = GetDocument().QuerySelector("div");
ASSERT_TRUE(div);
@@ -1828,7 +1816,7 @@ TEST_F(StyleEngineTest, RejectSelectorForPseudoElement) {
}
TEST_F(StyleEngineTest, MarkForWhitespaceReattachment) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<div id=d1><span></span></div>
<div id=d2><span></span><span></span></div>
<div id=d3><span></span><span></span></div>
@@ -1874,7 +1862,7 @@ TEST_F(StyleEngineTest, MarkForWhitespaceReattachment) {
}
TEST_F(StyleEngineTest, FirstLetterRemoved) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>.fl::first-letter { color: pink }</style>
<div class=fl id=d1><div><span id=f1>A</span></div></div>
<div class=fl id=d2><div><span id=f2>BB</span></div></div>
@@ -1952,8 +1940,7 @@ TEST_F(StyleEngineTest, InitialDataCreation) {
EXPECT_TRUE(data1);
// After a full recalc, we should have the same initial data.
- GetDocument().body()->SetInnerHTMLFromString(
- "<style>* { font-size: 1px; } </style>");
+ GetDocument().body()->setInnerHTML("<style>* { font-size: 1px; } </style>");
EXPECT_TRUE(GetDocument().documentElement()->NeedsStyleRecalc());
EXPECT_TRUE(GetDocument().documentElement()->ChildNeedsStyleRecalc());
UpdateAllLifecyclePhases();
@@ -1969,7 +1956,7 @@ TEST_F(StyleEngineTest, InitialDataCreation) {
}
TEST_F(StyleEngineTest, CSSSelectorEmptyWhitespaceOnlyFail) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>.match:empty { background-color: red }</style>
<div></div>
<div> <span></span></div>
@@ -1977,8 +1964,7 @@ TEST_F(StyleEngineTest, CSSSelectorEmptyWhitespaceOnlyFail) {
<div></div>
<div> <!-- --></div>
)HTML");
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
EXPECT_FALSE(GetDocument().IsUseCounted(
WebFeature::kCSSSelectorEmptyWhitespaceOnlyFail));
@@ -1990,7 +1976,7 @@ TEST_F(StyleEngineTest, CSSSelectorEmptyWhitespaceOnlyFail) {
auto is_counted = [](Element* element) {
element->setAttribute(blink::html_names::kClassAttr, "match");
element->GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
return element->GetDocument().IsUseCounted(
WebFeature::kCSSSelectorEmptyWhitespaceOnlyFail);
};
@@ -2003,7 +1989,7 @@ TEST_F(StyleEngineTest, CSSSelectorEmptyWhitespaceOnlyFail) {
}
TEST_F(StyleEngineTest, EnsuredComputedStyleRecalc) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<div style="display:none">
<div>
<div id="computed">
@@ -2054,8 +2040,8 @@ TEST_F(StyleEngineTest, EnsuredComputedStyleRecalc) {
}
TEST_F(StyleEngineTest, EnsureCustomComputedStyle) {
- GetDocument().body()->SetInnerHTMLFromString("");
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML("");
+ GetDocument().body()->setInnerHTML(R"HTML(
<div id=div>
<progress id=progress>
</div>
@@ -2098,7 +2084,7 @@ TEST_F(StyleEngineTest, EnsureCustomComputedStyle) {
// InvalidateDefaultButtonStyle while the subtree disconnection
// is taking place.
TEST_F(StyleEngineTest, NoCrashWhenMarkingPartiallyRemovedSubtree) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
#foo:default {} /* Needed to enter Element::PseudoStateChanged */
</style>
@@ -2120,7 +2106,7 @@ TEST_F(StyleEngineTest, NoCrashWhenMarkingPartiallyRemovedSubtree) {
// Add some more buttons, to give InvalidateDefaultButtonStyle
// something to do when the original <button> is removed.
- inner->SetInnerHTMLFromString("<button><button>");
+ inner->setInnerHTML("<button><button>");
UpdateAllLifecyclePhases();
form->removeChild(outer);
@@ -2128,9 +2114,8 @@ TEST_F(StyleEngineTest, NoCrashWhenMarkingPartiallyRemovedSubtree) {
TEST_F(StyleEngineTest, ColorSchemeBaseBackgroundChange) {
ScopedCSSColorSchemeForTest enable_color_scheme(true);
- ColorSchemeHelper color_scheme_helper;
- color_scheme_helper.SetPreferredColorScheme(GetDocument(),
- PreferredColorScheme::kDark);
+ ColorSchemeHelper color_scheme_helper(GetDocument());
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kDark);
UpdateAllLifecyclePhases();
EXPECT_EQ(Color::kWhite, GetDocument().View()->BaseBackgroundColor());
@@ -2144,6 +2129,10 @@ TEST_F(StyleEngineTest, ColorSchemeBaseBackgroundChange) {
TEST_F(StyleEngineTest, ColorSchemeOverride) {
ScopedCSSColorSchemeForTest enable_color_scheme(true);
+ ScopedCSSColorSchemeUARenderingForTest enable_color_scheme_ua(true);
+
+ ColorSchemeHelper color_scheme_helper(GetDocument());
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kLight);
GetDocument().documentElement()->SetInlineStyleProperty(
CSSPropertyID::kColorScheme, "light dark");
@@ -2162,54 +2151,8 @@ TEST_F(StyleEngineTest, ColorSchemeOverride) {
GetDocument().documentElement()->GetComputedStyle()->UsedColorScheme());
}
-TEST_F(StyleEngineTest, InternalRootColor) {
- ScopedCSSColorSchemeForTest enable_color_scheme(true);
- ColorSchemeHelper color_scheme_helper;
- color_scheme_helper.SetPreferredColorScheme(GetDocument(),
- PreferredColorScheme::kDark);
-
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
- <style>
- #container { color-scheme: dark }
- #light { color-scheme: light }
- </style>
- <div id="container">
- <span id="dark">Text</span>
- <span id="light">Text</span>
- </div>
- )HTML");
-
- UpdateAllLifecyclePhases();
-
- auto* container = GetDocument().getElementById("container");
- auto* light = GetDocument().getElementById("light");
- auto* dark = GetDocument().getElementById("dark");
-
- // Initial value of color-scheme is 'light'.
- EXPECT_EQ(
- WebColorScheme::kLight,
- GetDocument().documentElement()->GetComputedStyle()->UsedColorScheme());
- EXPECT_EQ(WebColorScheme::kDark,
- container->GetComputedStyle()->UsedColorScheme());
- // color-scheme:dark inherited from #container.
- EXPECT_EQ(WebColorScheme::kDark, dark->GetComputedStyle()->UsedColorScheme());
- EXPECT_EQ(WebColorScheme::kLight,
- light->GetComputedStyle()->UsedColorScheme());
-
- EXPECT_EQ(Color::kBlack, GetDocument()
- .documentElement()
- ->GetComputedStyle()
- ->VisitedDependentColor(GetCSSPropertyColor()));
- EXPECT_EQ(Color::kWhite, container->GetComputedStyle()->VisitedDependentColor(
- GetCSSPropertyColor()));
- EXPECT_EQ(Color::kWhite, dark->GetComputedStyle()->VisitedDependentColor(
- GetCSSPropertyColor()));
- EXPECT_EQ(Color::kBlack, light->GetComputedStyle()->VisitedDependentColor(
- GetCSSPropertyColor()));
-}
-
TEST_F(StyleEngineTest, PseudoElementBaseComputedStyle) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
@keyframes anim {
from { background-color: white }
@@ -2267,7 +2210,7 @@ TEST_F(StyleEngineTest, NeedsLayoutTreeRebuild) {
}
TEST_F(StyleEngineTest, ForceReattachLayoutTreeStyleRecalcRoot) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<div id="outer">
<div id="inner"></div>
</div>
@@ -2306,7 +2249,7 @@ TEST_F(StyleEngineTest, RecalcPropagatedWritingMode) {
TEST_F(StyleEngineTest, GetComputedStyleOutsideFlatTree) {
ScopedFlatTreeStyleRecalcForTest feature_scope(true);
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
R"HTML(<div id="host"><div id="outer"><div id="inner"><div id="innermost"></div></div></div></div>)HTML");
auto* host = GetDocument().getElementById("host");
@@ -2373,7 +2316,7 @@ TEST_F(StyleEngineTest, GetComputedStyleOutsideFlatTree) {
TEST_F(StyleEngineTest, MoveSlottedOutsideFlatTree) {
ScopedFlatTreeStyleRecalcForTest feature_scope(true);
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<div id="host1"><span></span></div>
<div id="host2"></div>
)HTML");
@@ -2384,7 +2327,7 @@ TEST_F(StyleEngineTest, MoveSlottedOutsideFlatTree) {
ShadowRoot& shadow_root =
host1->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString("<slot></slot>");
+ shadow_root.setInnerHTML("<slot></slot>");
host2->AttachShadowRootInternal(ShadowRootType::kOpen);
UpdateAllLifecyclePhases();
@@ -2399,13 +2342,13 @@ TEST_F(StyleEngineTest, MoveSlottedOutsideFlatTree) {
TEST_F(StyleEngineTest, StyleRecalcRootInShadowTree) {
ScopedFlatTreeStyleRecalcForTest feature_scope(true);
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<div id="host"></div>
)HTML");
Element* host = GetDocument().getElementById("host");
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString("<div><span></span></div>");
+ shadow_root.setInnerHTML("<div><span></span></div>");
UpdateAllLifecyclePhases();
Element* span = To<Element>(shadow_root.firstChild()->firstChild());
@@ -2418,7 +2361,7 @@ TEST_F(StyleEngineTest, StyleRecalcRootInShadowTree) {
TEST_F(StyleEngineTest, StyleRecalcRootOutsideFlatTree) {
ScopedFlatTreeStyleRecalcForTest feature_scope(true);
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<div id="host"><div id="ensured"><span></span></div></div>
<div id="dirty"></div>
)HTML");
@@ -2451,7 +2394,7 @@ TEST_F(StyleEngineTest, StyleRecalcRootOutsideFlatTree) {
TEST_F(StyleEngineTest, RemoveStyleRecalcRootFromFlatTree) {
ScopedFlatTreeStyleRecalcForTest scope(true);
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<div id=host><span></span></div>
)HTML");
@@ -2460,7 +2403,7 @@ TEST_F(StyleEngineTest, RemoveStyleRecalcRootFromFlatTree) {
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString("<div><slot></slot></div>");
+ shadow_root.setInnerHTML("<div><slot></slot></div>");
UpdateAllLifecyclePhases();
@@ -2484,4 +2427,272 @@ TEST_F(StyleEngineTest, RemoveStyleRecalcRootFromFlatTree) {
EXPECT_FALSE(GetStyleRecalcRoot());
}
+TEST_F(StyleEngineTest, SlottedWithEnsuredStyleOutsideFlatTree) {
+ ScopedFlatTreeStyleRecalcForTest scope(true);
+
+ GetDocument().body()->setInnerHTML(R"HTML(
+ <div id="host"><span></span></div>
+ )HTML");
+
+ auto* host = GetDocument().getElementById("host");
+ auto* span = To<Element>(host->firstChild());
+
+ ShadowRoot& shadow_root =
+ host->AttachShadowRootInternal(ShadowRootType::kOpen);
+ shadow_root.setInnerHTML(R"HTML(
+ <div><slot name="default"></slot></div>
+ )HTML");
+
+ UpdateAllLifecyclePhases();
+
+ // Ensure style outside the flat tree.
+ const ComputedStyle* style = span->EnsureComputedStyle();
+ ASSERT_TRUE(style);
+ EXPECT_TRUE(style->IsEnsuredOutsideFlatTree());
+
+ span->setAttribute("slot", "default");
+ GetDocument().GetSlotAssignmentEngine().RecalcSlotAssignments();
+ EXPECT_EQ(span, GetStyleRecalcRoot());
+ EXPECT_FALSE(span->GetComputedStyle());
+}
+
+TEST_F(StyleEngineTest, RecalcEnsuredStyleOutsideFlatTreeV0) {
+ ScopedFlatTreeStyleRecalcForTest scope(true);
+
+ GetDocument().body()->setInnerHTML(R"HTML(
+ <div id="host"><span></span></div>
+ )HTML");
+
+ auto* host = GetDocument().getElementById("host");
+ auto* span = To<Element>(host->firstChild());
+
+ host->CreateV0ShadowRootForTesting();
+ UpdateAllLifecyclePhases();
+
+ EXPECT_FALSE(span->FlatTreeParentForChildDirty());
+
+ // Ensure style outside the flat tree.
+ const ComputedStyle* style = span->EnsureComputedStyle();
+ ASSERT_TRUE(style);
+ EXPECT_TRUE(style->IsEnsuredOutsideFlatTree());
+ EXPECT_EQ(EDisplay::kInline, style->Display());
+
+ span->SetInlineStyleProperty(CSSPropertyID::kDisplay, "block");
+ EXPECT_FALSE(GetStyleRecalcRoot());
+ EXPECT_FALSE(GetDocument().body()->ChildNeedsStyleRecalc());
+}
+
+TEST_F(StyleEngineTest, ForceReattachRecalcRootAttachShadow) {
+ ScopedFlatTreeStyleRecalcForTest scope(true);
+
+ GetDocument().body()->setInnerHTML(R"HTML(
+ <div id="reattach"></div><div id="host"><span></span></div>
+ )HTML");
+
+ auto* reattach = GetDocument().getElementById("reattach");
+ auto* host = GetDocument().getElementById("host");
+
+ UpdateAllLifecyclePhases();
+
+ reattach->SetForceReattachLayoutTree();
+ EXPECT_FALSE(reattach->NeedsStyleRecalc());
+ EXPECT_EQ(reattach, GetStyleRecalcRoot());
+
+ // Attaching the shadow root will call RemovedFromFlatTree() on the span child
+ // of the host. The style recalc root should still be #reattach.
+ host->AttachShadowRootInternal(ShadowRootType::kOpen);
+ EXPECT_EQ(reattach, GetStyleRecalcRoot());
+}
+
+TEST_F(StyleEngineTest, InitialColorChange) {
+ // Set color scheme to light.
+ ColorSchemeHelper color_scheme_helper(GetDocument());
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kLight);
+
+ GetDocument().body()->setInnerHTML(R"HTML(
+ <style>
+ :root { color-scheme: light dark }
+ #initial { color: initial }
+ </style>
+ <div id="initial"></div>
+ )HTML");
+ UpdateAllLifecyclePhases();
+
+ Element* initial = GetDocument().getElementById("initial");
+ ASSERT_TRUE(initial);
+ ASSERT_TRUE(GetDocument().documentElement());
+ const ComputedStyle* document_element_style =
+ GetDocument().documentElement()->GetComputedStyle();
+ ASSERT_TRUE(document_element_style);
+ EXPECT_EQ(Color::kBlack, document_element_style->VisitedDependentColor(
+ GetCSSPropertyColor()));
+
+ const ComputedStyle* initial_style = initial->GetComputedStyle();
+ ASSERT_TRUE(initial_style);
+ EXPECT_EQ(Color::kBlack,
+ initial_style->VisitedDependentColor(GetCSSPropertyColor()));
+
+ // Change color scheme to dark.
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kDark);
+ UpdateAllLifecyclePhases();
+
+ document_element_style = GetDocument().documentElement()->GetComputedStyle();
+ ASSERT_TRUE(document_element_style);
+ EXPECT_EQ(Color::kWhite, document_element_style->VisitedDependentColor(
+ GetCSSPropertyColor()));
+
+ initial_style = initial->GetComputedStyle();
+ ASSERT_TRUE(initial_style);
+ EXPECT_EQ(Color::kWhite,
+ initial_style->VisitedDependentColor(GetCSSPropertyColor()));
+}
+
+TEST_F(StyleEngineTest,
+ MediaQueryAffectingValueChanged_InvalidateForChangedSizeQueries) {
+ GetDocument().body()->setInnerHTML(R"HTML(
+ <style>
+ @media (min-width: 1000px) {
+ div { color: green }
+ }
+ </style>
+ <style>
+ @media (min-width: 1200px) {
+ * { color: red }
+ }
+ </style>
+ <style>
+ @media print {
+ * { color: blue }
+ }
+ </style>
+ <div id="green"></div>
+ <span></span>
+ )HTML");
+ UpdateAllLifecyclePhases();
+
+ Element* div = GetDocument().getElementById("green");
+ EXPECT_EQ(Color::kBlack, div->GetComputedStyle()->VisitedDependentColor(
+ GetCSSPropertyColor()));
+
+ unsigned initial_count = GetStyleEngine().StyleForElementCount();
+
+ GetDocument().View()->SetLayoutSizeFixedToFrameSize(false);
+ GetDocument().View()->SetLayoutSize(IntSize(1100, 800));
+ UpdateAllLifecyclePhases();
+
+ // Only the single div element should have its style recomputed.
+ EXPECT_EQ(1u, GetStyleEngine().StyleForElementCount() - initial_count);
+ EXPECT_EQ(MakeRGB(0, 128, 0), div->GetComputedStyle()->VisitedDependentColor(
+ GetCSSPropertyColor()));
+}
+
+TEST_F(StyleEngineTest,
+ MediaQueryAffectingValueChanged_InvalidateForChangedTypeQuery) {
+ GetDocument().body()->setInnerHTML(R"HTML(
+ <style>
+ @media speech {
+ div { color: green }
+ }
+ </style>
+ <style>
+ @media (max-width: 100px) {
+ * { color: red }
+ }
+ </style>
+ <style>
+ @media print {
+ * { color: blue }
+ }
+ </style>
+ <div id="green"></div>
+ <span></span>
+ )HTML");
+ UpdateAllLifecyclePhases();
+
+ Element* div = GetDocument().getElementById("green");
+ EXPECT_EQ(Color::kBlack, div->GetComputedStyle()->VisitedDependentColor(
+ GetCSSPropertyColor()));
+
+ unsigned initial_count = GetStyleEngine().StyleForElementCount();
+
+ GetDocument().GetSettings()->SetMediaTypeOverride("speech");
+ UpdateAllLifecyclePhases();
+
+ // Only the single div element should have its style recomputed.
+ EXPECT_EQ(1u, GetStyleEngine().StyleForElementCount() - initial_count);
+ EXPECT_EQ(MakeRGB(0, 128, 0), div->GetComputedStyle()->VisitedDependentColor(
+ GetCSSPropertyColor()));
+}
+
+TEST_F(StyleEngineTest,
+ MediaQueryAffectingValueChanged_InvalidateForChangedReducedMotionQuery) {
+ GetDocument().body()->setInnerHTML(R"HTML(
+ <style>
+ @media (prefers-reduced-motion: reduce) {
+ div { color: green }
+ }
+ </style>
+ <style>
+ @media (max-width: 100px) {
+ * { color: red }
+ }
+ </style>
+ <style>
+ @media print {
+ * { color: blue }
+ }
+ </style>
+ <div id="green"></div>
+ <span></span>
+ )HTML");
+ UpdateAllLifecyclePhases();
+
+ Element* div = GetDocument().getElementById("green");
+ EXPECT_EQ(Color::kBlack, div->GetComputedStyle()->VisitedDependentColor(
+ GetCSSPropertyColor()));
+
+ unsigned initial_count = GetStyleEngine().StyleForElementCount();
+
+ GetDocument().GetSettings()->SetPrefersReducedMotion(true);
+ UpdateAllLifecyclePhases();
+
+ // Only the single div element should have its style recomputed.
+ EXPECT_EQ(1u, GetStyleEngine().StyleForElementCount() - initial_count);
+ EXPECT_EQ(MakeRGB(0, 128, 0), div->GetComputedStyle()->VisitedDependentColor(
+ GetCSSPropertyColor()));
+}
+
+class ParameterizedStyleEngineTest
+ : public testing::WithParamInterface<bool>,
+ private ScopedCSSReducedFontLoadingInvalidationsForTest,
+ public StyleEngineTest {
+ public:
+ ParameterizedStyleEngineTest()
+ : ScopedCSSReducedFontLoadingInvalidationsForTest(GetParam()) {}
+};
+
+INSTANTIATE_TEST_SUITE_P(All, ParameterizedStyleEngineTest, testing::Bool());
+
+// https://crbug.com/1050564
+TEST_P(ParameterizedStyleEngineTest,
+ MediaAttributeChangeUpdatesFontCacheVersion) {
+ GetDocument().body()->setInnerHTML(R"HTML(
+ <style>
+ @font-face { font-family: custom-font; src: url(fake-font.woff); }
+ </style>
+ <style id=target>
+ .display-none { display: none; }
+ </style>
+ <div style="font-family: custom-font">foo</div>
+ <div class="display-none">bar</div>
+ )HTML");
+ UpdateAllLifecyclePhases();
+
+ Element* target = GetDocument().getElementById("target");
+ target->setAttribute(html_names::kMediaAttr, "print");
+
+ // Shouldn't crash.
+ UpdateAllLifecyclePhases();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/style_environment_variables_test.cc b/chromium/third_party/blink/renderer/core/css/style_environment_variables_test.cc
index 21d16088658..bc8fa6776f3 100644
--- a/chromium/third_party/blink/renderer/core/css/style_environment_variables_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_environment_variables_test.cc
@@ -48,9 +48,9 @@ class StyleEnvironmentVariablesTest : public PageTestBase {
void InitializeWithHTML(LocalFrame& frame, const String& html_content) {
// Sets the inner html and runs the document lifecycle.
- frame.GetDocument()->body()->SetInnerHTMLFromString(html_content);
+ frame.GetDocument()->body()->setInnerHTML(html_content);
frame.GetDocument()->View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
}
void InitializeTestPageWithVariableNamed(LocalFrame& frame,
@@ -231,7 +231,7 @@ TEST_F(StyleEnvironmentVariablesTest, MultiDocumentInvalidation_FromRoot) {
// Create an empty page that does not use the variable.
auto empty_page = std::make_unique<DummyPageHolder>(IntSize(800, 600));
empty_page->GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
StyleEnvironmentVariables::GetRootInstance().SetVariable(kVariableName,
kVariableTestColor);
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 55f908545ea..6725fe11f60 100644
--- a/chromium/third_party/blink/renderer/core/css/style_media.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_media.cc
@@ -28,12 +28,13 @@
#include "third_party/blink/renderer/core/css/media_list.h"
#include "third_party/blink/renderer/core/css/media_query_evaluator.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"
namespace blink {
-StyleMedia::StyleMedia(LocalFrame* frame) : ContextClient(frame) {}
+StyleMedia::StyleMedia(LocalFrame* frame) : ExecutionContextClient(frame) {}
AtomicString StyleMedia::type() const {
LocalFrameView* view = GetFrame() ? GetFrame()->View() : nullptr;
@@ -54,16 +55,16 @@ bool StyleMedia::matchMedium(const String& query) const {
return false;
scoped_refptr<MediaQuerySet> media = MediaQuerySet::Create();
- if (!media->Set(query))
+ if (!media->Set(query, GetFrame()->DomWindow()))
return false;
MediaQueryEvaluator screen_eval(GetFrame());
return screen_eval.Eval(*media);
}
-void StyleMedia::Trace(blink::Visitor* visitor) {
+void StyleMedia::Trace(Visitor* visitor) {
ScriptWrappable::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 e18e562f523..7a16067f560 100644
--- a/chromium/third_party/blink/renderer/core/css/style_media.h
+++ b/chromium/third_party/blink/renderer/core/css/style_media.h
@@ -27,7 +27,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_STYLE_MEDIA_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_STYLE_MEDIA_H_
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/wtf/text/wtf_string.h"
@@ -36,7 +36,7 @@ namespace blink {
class LocalFrame;
-class StyleMedia final : public ScriptWrappable, public ContextClient {
+class StyleMedia final : public ScriptWrappable, public ExecutionContextClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(StyleMedia);
@@ -46,7 +46,7 @@ class StyleMedia final : public ScriptWrappable, public ContextClient {
AtomicString type() const;
bool matchMedium(const String&) const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/style_media.idl b/chromium/third_party/blink/renderer/core/css/style_media.idl
index f87108f5ab1..36b427af621 100644
--- a/chromium/third_party/blink/renderer/core/css/style_media.idl
+++ b/chromium/third_party/blink/renderer/core/css/style_media.idl
@@ -35,5 +35,5 @@
NoInterfaceObject
] interface StyleMedia {
[MeasureAs=StyleMediaType] readonly attribute DOMString type;
- [MeasureAs=StyleMediaMatchMedium] boolean matchMedium([DefaultValue=Undefined] optional DOMString mediaquery);
+ [MeasureAs=StyleMediaMatchMedium] boolean matchMedium(optional DOMString mediaquery = "undefined");
};
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 1de5c5fad3b..a54cefc8d04 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
@@ -339,7 +339,6 @@ static bool AllowInitialInShorthand(CSSPropertyID property_id) {
case CSSPropertyID::kListStyle:
case CSSPropertyID::kOffset:
case CSSPropertyID::kTextDecoration:
- case CSSPropertyID::kWebkitMarginCollapse:
case CSSPropertyID::kWebkitMask:
case CSSPropertyID::kWebkitTextEmphasis:
case CSSPropertyID::kWebkitTextStroke:
@@ -522,8 +521,6 @@ String StylePropertySerializer::SerializeShorthand(
return Get2Values(marginInlineShorthand());
case CSSPropertyID::kOffset:
return OffsetValue();
- case CSSPropertyID::kWebkitMarginCollapse:
- return GetShorthandValue(webkitMarginCollapseShorthand());
case CSSPropertyID::kOverflow:
return Get2Values(overflowShorthand());
case CSSPropertyID::kOverscrollBehavior:
@@ -582,8 +579,6 @@ String StylePropertySerializer::SerializeShorthand(
return PageBreakPropertyValue(pageBreakBeforeShorthand());
case CSSPropertyID::kPageBreakInside:
return PageBreakPropertyValue(pageBreakInsideShorthand());
- case CSSPropertyID::kIntrinsicSize:
- return Get2Values(intrinsicSizeShorthand());
default:
return String();
}
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 4205dabebbd..4d214d695a5 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
@@ -86,7 +86,7 @@ class StylePropertySerializer {
public:
explicit PropertyValueForSerializer(
CSSPropertyValueSet::PropertyReference property)
- : value_(property.Value()),
+ : value_(&property.Value()),
property_(property.Property()),
is_important_(property.IsImportant()),
is_inherited_(property.IsInherited()) {}
@@ -107,7 +107,7 @@ class StylePropertySerializer {
bool IsValid() const { return value_; }
private:
- Member<const CSSValue> value_;
+ const CSSValue* value_;
const CSSProperty& property_;
bool is_important_;
bool is_inherited_;
@@ -129,7 +129,7 @@ class StylePropertySerializer {
const CSSValue* GetPropertyCSSValue(const CSSProperty&) const;
bool IsDescriptorContext() const;
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
bool HasExpandedAllProperty() const {
diff --git a/chromium/third_party/blink/renderer/core/css/style_recalc_root.cc b/chromium/third_party/blink/renderer/core/css/style_recalc_root.cc
index dcc8ed70037..fe2e85a0bba 100644
--- a/chromium/third_party/blink/renderer/core/css/style_recalc_root.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_recalc_root.cc
@@ -6,6 +6,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/dom/shadow_root.h"
+#include "third_party/blink/renderer/core/dom/shadow_root_v0.h"
#include "third_party/blink/renderer/core/dom/slot_assignment.h"
#include "third_party/blink/renderer/core/html/html_slot_element.h"
@@ -62,8 +63,15 @@ base::Optional<Member<Element>> FirstFlatTreeAncestorForChildDirty(
if (!root)
return To<Element>(&parent);
if (root->IsV0()) {
- // Fall back to use the parent as the new style recalc root for Shadow DOM
- // V0. It is too complicated to try to find the closest flat tree parent.
+ // The child has already been removed, so we cannot look up its insertion
+ // point directly. Find the insertion point which was part of the ancestor
+ // chain before the removal by checking the child-dirty bits. Since the
+ // recalc root was removed, there is at most one such child-dirty insertion
+ // point.
+ for (const auto& insertion_point : root->V0().DescendantInsertionPoints()) {
+ if (insertion_point->ChildNeedsStyleRecalc())
+ return insertion_point;
+ }
return base::nullopt;
}
if (!root->HasSlotAssignment())
@@ -72,7 +80,7 @@ base::Optional<Member<Element>> FirstFlatTreeAncestorForChildDirty(
// assignment directly. Find the slot which was part of the ancestor chain
// before the removal by checking the child-dirty bits. Since the recalc root
// was removed, there is at most one such child-dirty slot.
- for (const auto slot : root->GetSlotAssignment().Slots()) {
+ for (const auto& slot : root->GetSlotAssignment().Slots()) {
if (slot->ChildNeedsStyleRecalc())
return slot;
}
@@ -123,6 +131,7 @@ void StyleRecalcRoot::RemovedFromFlatTree(const Node& node) {
// make sure we don't have a recalc root outside the flat tree, which is not
// allowed with FlatTreeStyleRecalc enabled.
if (GetRootNode()->NeedsStyleRecalc() ||
+ GetRootNode()->GetForceReattachLayoutTree() ||
GetRootNode()->ChildNeedsStyleRecalc()) {
return;
}
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 4a99e20558e..1220ed8fd1c 100644
--- a/chromium/third_party/blink/renderer/core/css/style_rule.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_rule.cc
@@ -55,7 +55,7 @@ CSSRule* StyleRuleBase::CreateCSSOMWrapper(CSSRule* parent_rule) const {
return CreateCSSOMWrapper(nullptr, parent_rule);
}
-void StyleRuleBase::Trace(blink::Visitor* visitor) {
+void StyleRuleBase::Trace(Visitor* visitor) {
switch (GetType()) {
case kCharset:
To<StyleRuleCharset>(this)->TraceAfterDispatch(visitor);
@@ -287,7 +287,7 @@ bool StyleRule::HasParsedProperties() const {
return !lazy_property_parser_;
}
-void StyleRule::TraceAfterDispatch(blink::Visitor* visitor) {
+void StyleRule::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(properties_);
visitor->Trace(lazy_property_parser_);
StyleRuleBase::TraceAfterDispatch(visitor);
@@ -312,7 +312,7 @@ MutableCSSPropertyValueSet& StyleRulePage::MutableProperties() {
return *To<MutableCSSPropertyValueSet>(properties_.Get());
}
-void StyleRulePage::TraceAfterDispatch(blink::Visitor* visitor) {
+void StyleRulePage::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(properties_);
StyleRuleBase::TraceAfterDispatch(visitor);
}
@@ -333,7 +333,7 @@ MutableCSSPropertyValueSet& StyleRuleProperty::MutableProperties() {
return *To<MutableCSSPropertyValueSet>(properties_.Get());
}
-void StyleRuleProperty::TraceAfterDispatch(blink::Visitor* visitor) {
+void StyleRuleProperty::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(properties_);
StyleRuleBase::TraceAfterDispatch(visitor);
}
@@ -345,15 +345,13 @@ StyleRuleFontFace::StyleRuleFontFace(const StyleRuleFontFace& font_face_rule)
: StyleRuleBase(font_face_rule),
properties_(font_face_rule.properties_->MutableCopy()) {}
-StyleRuleFontFace::~StyleRuleFontFace() = default;
-
MutableCSSPropertyValueSet& StyleRuleFontFace::MutableProperties() {
if (!properties_->IsMutable())
properties_ = properties_->MutableCopy();
return *To<MutableCSSPropertyValueSet>(properties_.Get());
}
-void StyleRuleFontFace::TraceAfterDispatch(blink::Visitor* visitor) {
+void StyleRuleFontFace::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(properties_);
StyleRuleBase::TraceAfterDispatch(visitor);
}
@@ -378,7 +376,7 @@ void StyleRuleGroup::WrapperRemoveRule(unsigned index) {
child_rules_.EraseAt(index);
}
-void StyleRuleGroup::TraceAfterDispatch(blink::Visitor* visitor) {
+void StyleRuleGroup::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(child_rules_);
StyleRuleBase::TraceAfterDispatch(visitor);
}
@@ -414,7 +412,7 @@ StyleRuleSupports::StyleRuleSupports(
: StyleRuleCondition(kSupports, condition_text, adopt_rules),
condition_is_supported_(condition_is_supported) {}
-void StyleRuleMedia::TraceAfterDispatch(blink::Visitor* visitor) {
+void StyleRuleMedia::TraceAfterDispatch(blink::Visitor* visitor) const {
StyleRuleCondition::TraceAfterDispatch(visitor);
}
@@ -429,15 +427,13 @@ StyleRuleViewport::StyleRuleViewport(const StyleRuleViewport& viewport_rule)
: StyleRuleBase(viewport_rule),
properties_(viewport_rule.properties_->MutableCopy()) {}
-StyleRuleViewport::~StyleRuleViewport() = default;
-
MutableCSSPropertyValueSet& StyleRuleViewport::MutableProperties() {
if (!properties_->IsMutable())
properties_ = properties_->MutableCopy();
return *To<MutableCSSPropertyValueSet>(properties_.Get());
}
-void StyleRuleViewport::TraceAfterDispatch(blink::Visitor* visitor) {
+void StyleRuleViewport::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(properties_);
StyleRuleBase::TraceAfterDispatch(visitor);
}
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 feaac3a2c00..a4a11462a2e 100644
--- a/chromium/third_party/blink/renderer/core/css/style_rule.h
+++ b/chromium/third_party/blink/renderer/core/css/style_rule.h
@@ -73,8 +73,8 @@ class CORE_EXPORT StyleRuleBase : public GarbageCollected<StyleRuleBase> {
CSSRule* CreateCSSOMWrapper(CSSStyleSheet* parent_sheet = nullptr) const;
CSSRule* CreateCSSOMWrapper(CSSRule* parent_rule) const;
- void Trace(blink::Visitor*);
- void TraceAfterDispatch(blink::Visitor* visitor) {}
+ void Trace(Visitor*);
+ void TraceAfterDispatch(blink::Visitor* visitor) const {}
void FinalizeGarbageCollectedObject();
// ~StyleRuleBase should be public, because non-public ~StyleRuleBase
@@ -91,7 +91,7 @@ class CORE_EXPORT StyleRuleBase : public GarbageCollected<StyleRuleBase> {
CSSRule* CreateCSSOMWrapper(CSSStyleSheet* parent_sheet,
CSSRule* parent_rule) const;
- unsigned type_ : 5;
+ const uint8_t type_;
};
// A single rule from a stylesheet. Contains a selector list (one or more
@@ -121,7 +121,7 @@ class CORE_EXPORT StyleRule : public StyleRuleBase {
bool PropertiesHaveFailedOrCanceledSubresources() const;
bool ShouldConsiderForMatchingRules(bool include_empty_rules) const;
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
friend class CSSLazyParsingTest;
@@ -147,7 +147,6 @@ class CORE_EXPORT StyleRuleFontFace : public StyleRuleBase {
public:
StyleRuleFontFace(CSSPropertyValueSet*);
StyleRuleFontFace(const StyleRuleFontFace&);
- ~StyleRuleFontFace();
const CSSPropertyValueSet& Properties() const { return *properties_; }
MutableCSSPropertyValueSet& MutableProperties();
@@ -156,7 +155,7 @@ class CORE_EXPORT StyleRuleFontFace : public StyleRuleBase {
return MakeGarbageCollected<StyleRuleFontFace>(*this);
}
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
Member<CSSPropertyValueSet> properties_; // Cannot be null.
@@ -180,7 +179,7 @@ class StyleRulePage : public StyleRuleBase {
return MakeGarbageCollected<StyleRulePage>(*this);
}
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
Member<CSSPropertyValueSet> properties_; // Cannot be null.
@@ -189,11 +188,6 @@ class StyleRulePage : public StyleRuleBase {
class StyleRuleProperty : public StyleRuleBase {
public:
- static StyleRuleProperty* Create(const String& name,
- CSSPropertyValueSet* properties) {
- return MakeGarbageCollected<StyleRuleProperty>(name, properties);
- }
-
StyleRuleProperty(const String& name, CSSPropertyValueSet*);
StyleRuleProperty(const StyleRuleProperty&);
~StyleRuleProperty();
@@ -206,7 +200,7 @@ class StyleRuleProperty : public StyleRuleBase {
return MakeGarbageCollected<StyleRuleProperty>(*this);
}
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
String name_;
@@ -222,7 +216,7 @@ class CORE_EXPORT StyleRuleGroup : public StyleRuleBase {
void WrapperInsertRule(unsigned, StyleRuleBase*);
void WrapperRemoveRule(unsigned);
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
protected:
StyleRuleGroup(RuleType, HeapVector<Member<StyleRuleBase>>& adopt_rule);
@@ -236,7 +230,7 @@ class CORE_EXPORT StyleRuleCondition : public StyleRuleGroup {
public:
String ConditionText() const { return condition_text_; }
- void TraceAfterDispatch(blink::Visitor* visitor) {
+ void TraceAfterDispatch(blink::Visitor* visitor) const {
StyleRuleGroup::TraceAfterDispatch(visitor);
}
@@ -261,7 +255,7 @@ class CORE_EXPORT StyleRuleMedia : public StyleRuleCondition {
return MakeGarbageCollected<StyleRuleMedia>(*this);
}
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
scoped_refptr<MediaQuerySet> media_queries_;
@@ -279,7 +273,7 @@ class StyleRuleSupports : public StyleRuleCondition {
return MakeGarbageCollected<StyleRuleSupports>(*this);
}
- void TraceAfterDispatch(blink::Visitor* visitor) {
+ void TraceAfterDispatch(blink::Visitor* visitor) const {
StyleRuleCondition::TraceAfterDispatch(visitor);
}
@@ -292,7 +286,6 @@ class StyleRuleViewport : public StyleRuleBase {
public:
explicit StyleRuleViewport(CSSPropertyValueSet*);
explicit StyleRuleViewport(const StyleRuleViewport&);
- ~StyleRuleViewport();
const CSSPropertyValueSet& Properties() const { return *properties_; }
MutableCSSPropertyValueSet& MutableProperties();
@@ -301,7 +294,7 @@ class StyleRuleViewport : public StyleRuleBase {
return MakeGarbageCollected<StyleRuleViewport>(*this);
}
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
Member<CSSPropertyValueSet> properties_; // Cannot be null
@@ -311,7 +304,7 @@ class StyleRuleViewport : public StyleRuleBase {
class StyleRuleCharset : public StyleRuleBase {
public:
StyleRuleCharset() : StyleRuleBase(kCharset) {}
- void TraceAfterDispatch(blink::Visitor* visitor) {
+ void TraceAfterDispatch(blink::Visitor* visitor) const {
StyleRuleBase::TraceAfterDispatch(visitor);
}
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 4b45ec7238c..95e62d4c6ad 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
@@ -31,7 +31,14 @@ namespace blink {
StyleRuleCSSStyleDeclaration::StyleRuleCSSStyleDeclaration(
MutableCSSPropertyValueSet& property_set_arg,
CSSRule* parent_rule)
- : PropertySetCSSStyleDeclaration(property_set_arg),
+ : PropertySetCSSStyleDeclaration(
+ const_cast<Document*>(CSSStyleSheet::SingleOwnerDocument(
+ parent_rule->parentStyleSheet()))
+ ? const_cast<Document*>(CSSStyleSheet::SingleOwnerDocument(
+ parent_rule->parentStyleSheet()))
+ ->GetExecutionContext()
+ : nullptr,
+ property_set_arg),
parent_rule_(parent_rule) {}
StyleRuleCSSStyleDeclaration::~StyleRuleCSSStyleDeclaration() = default;
@@ -57,7 +64,7 @@ void StyleRuleCSSStyleDeclaration::Reattach(
property_set_ = &property_set;
}
-void StyleRuleCSSStyleDeclaration::Trace(blink::Visitor* visitor) {
+void StyleRuleCSSStyleDeclaration::Trace(Visitor* visitor) {
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 e3bc6fb5ddf..cbf19455579 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 8493e493442..55a0036c700 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
@@ -22,7 +22,6 @@
#include "third_party/blink/renderer/core/css/style_rule_import.h"
-#include "third_party/blink/public/common/features.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/loader/resource/css_style_sheet_resource.h"
@@ -45,7 +44,7 @@ StyleRuleImport::StyleRuleImport(const String& href,
loading_(false),
origin_clean_(origin_clean) {
if (!media_queries_)
- media_queries_ = MediaQuerySet::Create(String());
+ media_queries_ = MediaQuerySet::Create(String(), nullptr);
}
StyleRuleImport::~StyleRuleImport() = default;
@@ -54,7 +53,7 @@ void StyleRuleImport::Dispose() {
style_sheet_client_->Dispose();
}
-void StyleRuleImport::TraceAfterDispatch(blink::Visitor* visitor) {
+void StyleRuleImport::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(style_sheet_client_);
visitor->Trace(parent_style_sheet_);
visitor->Trace(style_sheet_);
@@ -109,9 +108,7 @@ void StyleRuleImport::RequestStyleSheet() {
return;
Document* document_for_origin = document;
- if (base::FeatureList::IsEnabled(
- features::kHtmlImportsRequestInitiatorLock) &&
- document->ImportsController()) {
+ if (document->ImportsController()) {
// For @imports from HTML imported Documents, we use the
// context document for getting origin and ResourceFetcher to use the main
// Document's origin, while using the element document for CompleteURL() to
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 3d9d022e23c..db062f0825a 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
@@ -57,7 +57,7 @@ class StyleRuleImport : public StyleRuleBase {
void RequestStyleSheet();
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
// FIXME: inherit from ResourceClient directly to eliminate back
@@ -80,7 +80,7 @@ class StyleRuleImport : public StyleRuleBase {
String DebugName() const override { return "ImportedStyleSheetClient"; }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(owner_rule_);
ResourceClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/style_rule_keyframe.cc b/chromium/third_party/blink/renderer/core/css/style_rule_keyframe.cc
index f9aa723aacc..d6881937202 100644
--- a/chromium/third_party/blink/renderer/core/css/style_rule_keyframe.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_rule_keyframe.cc
@@ -63,7 +63,7 @@ String StyleRuleKeyframe::CssText() const {
return result.ToString();
}
-void StyleRuleKeyframe::TraceAfterDispatch(blink::Visitor* visitor) {
+void StyleRuleKeyframe::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(properties_);
StyleRuleBase::TraceAfterDispatch(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/style_rule_keyframe.h b/chromium/third_party/blink/renderer/core/css/style_rule_keyframe.h
index cb8cac2e614..37493bc9f84 100644
--- a/chromium/third_party/blink/renderer/core/css/style_rule_keyframe.h
+++ b/chromium/third_party/blink/renderer/core/css/style_rule_keyframe.h
@@ -30,7 +30,7 @@ class StyleRuleKeyframe final : public StyleRuleBase {
String CssText() const;
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
Member<CSSPropertyValueSet> properties_;
diff --git a/chromium/third_party/blink/renderer/core/css/style_rule_namespace.h b/chromium/third_party/blink/renderer/core/css/style_rule_namespace.h
index 6ae26b469be..b1875ca9fa9 100644
--- a/chromium/third_party/blink/renderer/core/css/style_rule_namespace.h
+++ b/chromium/third_party/blink/renderer/core/css/style_rule_namespace.h
@@ -14,10 +14,6 @@ namespace blink {
// the parser to pass to a stylesheet
class StyleRuleNamespace final : public StyleRuleBase {
public:
- static StyleRuleNamespace* Create(AtomicString prefix, AtomicString uri) {
- return MakeGarbageCollected<StyleRuleNamespace>(prefix, uri);
- }
-
StyleRuleNamespace(AtomicString prefix, AtomicString uri)
: StyleRuleBase(kNamespace), prefix_(prefix), uri_(uri) {}
@@ -28,7 +24,7 @@ class StyleRuleNamespace final : public StyleRuleBase {
AtomicString Prefix() const { return prefix_; }
AtomicString Uri() const { return uri_; }
- void TraceAfterDispatch(blink::Visitor* visitor) {
+ void TraceAfterDispatch(blink::Visitor* visitor) const {
StyleRuleBase::TraceAfterDispatch(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/css/style_sheet_candidate.cc b/chromium/third_party/blink/renderer/core/css/style_sheet_candidate.cc
index 644416a3651..6336519676b 100644
--- a/chromium/third_party/blink/renderer/core/css/style_sheet_candidate.cc
+++ b/chromium/third_party/blink/renderer/core/css/style_sheet_candidate.cc
@@ -29,6 +29,7 @@
#include "third_party/blink/renderer/core/css/style_engine.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/processing_instruction.h"
+#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html/html_link_element.h"
#include "third_party/blink/renderer/core/html/html_style_element.h"
#include "third_party/blink/renderer/core/html/imports/html_import.h"
@@ -44,7 +45,7 @@ AtomicString StyleSheetCandidate::Title() const {
}
bool StyleSheetCandidate::IsXSL() const {
- return !GetNode().GetDocument().IsHTMLDocument() && type_ == kPi &&
+ return !IsA<HTMLDocument>(GetNode().GetDocument()) && type_ == kPi &&
To<ProcessingInstruction>(GetNode()).IsXSL();
}
diff --git a/chromium/third_party/blink/renderer/core/css/style_sheet_candidate.h b/chromium/third_party/blink/renderer/core/css/style_sheet_candidate.h
index 3f7f645bb4b..e6208bf6439 100644
--- a/chromium/third_party/blink/renderer/core/css/style_sheet_candidate.h
+++ b/chromium/third_party/blink/renderer/core/css/style_sheet_candidate.h
@@ -43,7 +43,7 @@ class StyleSheetCandidate {
public:
enum Type { kHTMLLink, kHTMLStyle, kSVGStyle, kPi, kInvalid };
- StyleSheetCandidate(Node& node) : node_(node), type_(TypeOf(node)) {}
+ StyleSheetCandidate(Node& node) : node_(&node), type_(TypeOf(node)) {}
bool IsXSL() const;
bool IsImport() const;
@@ -64,7 +64,7 @@ class StyleSheetCandidate {
static Type TypeOf(Node&);
- Member<Node> node_;
+ Node* node_;
Type type_;
};
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 0b304623e35..92c1fec1051 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(blink::Visitor* visitor) {
+void StyleSheetCollection::Trace(Visitor* visitor) {
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 57951be3103..a1f8d3d677d 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(blink::Visitor*);
+ virtual void Trace(Visitor*);
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 000e05e1de7..85d3a8e9d08 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
@@ -601,6 +601,8 @@ void StyleSheetContents::ClearReferencedFromResource() {
RuleSet& StyleSheetContents::EnsureRuleSet(const MediaQueryEvaluator& medium,
AddRuleFlags add_rule_flags) {
+ if (rule_set_ && rule_set_->DidMediaQueryResultsChange(medium))
+ rule_set_ = nullptr;
if (!rule_set_) {
rule_set_ = MakeGarbageCollected<RuleSet>();
rule_set_->AddRulesFromSheet(this, medium, add_rule_flags);
@@ -674,7 +676,7 @@ void StyleSheetContents::FindFontFaceRules(
FindFontFaceRulesFromRules(ChildRules(), font_face_rules);
}
-void StyleSheetContents::Trace(blink::Visitor* visitor) {
+void StyleSheetContents::Trace(Visitor* visitor) {
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 c92b55bd7b4..746d80b89b7 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
@@ -59,6 +59,8 @@ class CORE_EXPORT StyleSheetContents final
StyleSheetContents() = delete;
~StyleSheetContents();
+ // TODO(xiaochengh): |parser_context_| should never be null. Make it return a
+ // const reference here to avoid confusion.
const CSSParserContext* ParserContext() const { return parser_context_; }
const AtomicString& DefaultNamespace() const { return default_namespace_; }
@@ -189,7 +191,7 @@ class CORE_EXPORT StyleSheetContents final
String SourceMapURL() const { return source_map_url_; }
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
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 5df9b07a218..eb9e126c479 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(blink::Visitor* visitor) {
+void StyleSheetList::Trace(Visitor* visitor) {
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 dd80ae6122e..88905c866de 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 78440f040f5..83d3a95dbf0 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(blink::Visitor* visitor) { visitor->Trace(root_node_); }
+ void Trace(Visitor* visitor) { visitor->Trace(root_node_); }
protected:
virtual ~StyleTraversalRoot() = default;
diff --git a/chromium/third_party/blink/renderer/core/css/svg.css b/chromium/third_party/blink/renderer/core/css/svg.css
index 7c8ccbab6c3..f031de7f650 100644
--- a/chromium/third_party/blink/renderer/core/css/svg.css
+++ b/chromium/third_party/blink/renderer/core/css/svg.css
@@ -95,12 +95,15 @@ foreignObject {
https://drafts.csswg.org/css-color-adjust-1/#forced-colors-properties
*/
@media forced-colors {
+ svg:root {
+ color: CanvasText;
+ }
+
svg {
forced-color-adjust: none;
}
- text, foreignObject {
- fill: WindowText;
+ foreignObject {
forced-color-adjust: auto;
}
}
diff --git a/chromium/third_party/blink/renderer/core/css/threaded/font_object_threaded_test.cc b/chromium/third_party/blink/renderer/core/css/threaded/font_object_threaded_test.cc
index e7adb8d968a..98f767dee50 100644
--- a/chromium/third_party/blink/renderer/core/css/threaded/font_object_threaded_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/threaded/font_object_threaded_test.cc
@@ -52,8 +52,7 @@ TSAN_TEST(FontObjectThreadedTest, GetDefaultFontData) {
for (FontDescription::GenericFamilyType family_type :
{FontDescription::kStandardFamily, FontDescription::kSerifFamily,
FontDescription::kSansSerifFamily, FontDescription::kMonospaceFamily,
- FontDescription::kCursiveFamily, FontDescription::kFantasyFamily,
- FontDescription::kPictographFamily}) {
+ FontDescription::kCursiveFamily, FontDescription::kFantasyFamily}) {
FontDescription font_description;
font_description.SetComputedSize(12.0);
font_description.SetLocale(LayoutLocale::Get("en"));
@@ -61,8 +60,6 @@ TSAN_TEST(FontObjectThreadedTest, GetDefaultFontData) {
font_description.SetGenericFamily(family_type);
Font font = Font(font_description);
- font.Update(nullptr);
-
ASSERT_TRUE(font.PrimaryFont());
}
});
@@ -121,7 +118,6 @@ TSAN_TEST(FontObjectThreadedTest, WordShaperTest) {
font_description.SetGenericFamily(FontDescription::kStandardFamily);
Font font = Font(font_description);
- font.Update(nullptr);
ASSERT_TRUE(font.CanShapeWordByWord());
ShapeCache cache;
diff --git a/chromium/third_party/blink/renderer/core/css/threaded/text_renderer_threaded_test.cc b/chromium/third_party/blink/renderer/core/css/threaded/text_renderer_threaded_test.cc
index a5dc9527686..460006ee9d1 100644
--- a/chromium/third_party/blink/renderer/core/css/threaded/text_renderer_threaded_test.cc
+++ b/chromium/third_party/blink/renderer/core/css/threaded/text_renderer_threaded_test.cc
@@ -37,7 +37,6 @@ TSAN_TEST(TextRendererThreadedTest, MeasureText) {
font_description.SetGenericFamily(FontDescription::kStandardFamily);
Font font = Font(font_description);
- font.Update(nullptr);
const SimpleFontData* font_data = font.PrimaryFont();
ASSERT_TRUE(font_data);
@@ -77,7 +76,6 @@ TSAN_TEST(TextRendererThreadedTest, DrawText) {
font_description.SetGenericFamily(FontDescription::kStandardFamily);
Font font = Font(font_description);
- font.Update(nullptr);
FloatPoint location(0, 0);
TextRun text_run(text, 0, 0, TextRun::kAllowTrailingExpansion,
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 fed66b88285..738ab2f9d56 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
@@ -50,10 +50,6 @@ void TreeScopeStyleSheetCollection::AddStyleSheetCandidateNode(Node& node) {
style_sheet_candidate_nodes_.Add(&node);
}
-bool TreeScopeStyleSheetCollection::MediaQueryAffectingValueChanged() {
- return ClearMediaQueryDependentRuleSets(active_author_style_sheets_);
-}
-
void TreeScopeStyleSheetCollection::ApplyActiveStyleSheetChanges(
StyleSheetCollection& new_collection) {
GetDocument().GetStyleEngine().ApplyRuleSetChanges(
@@ -89,7 +85,7 @@ void TreeScopeStyleSheetCollection::UpdateStyleSheetList() {
SwapSheetsForSheetList(new_list);
}
-void TreeScopeStyleSheetCollection::Trace(blink::Visitor* visitor) {
+void TreeScopeStyleSheetCollection::Trace(Visitor* visitor) {
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 2236374d8be..e7e28c21fe0 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
@@ -51,12 +51,10 @@ class CORE_EXPORT TreeScopeStyleSheetCollection : public StyleSheetCollection {
}
bool HasStyleSheets() const;
- bool MediaQueryAffectingValueChanged();
-
virtual bool IsShadowTreeStyleSheetCollection() const { return false; }
void UpdateStyleSheetList();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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
new file mode 100644
index 00000000000..6ab3903071e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/vision_deficiency.cc
@@ -0,0 +1,73 @@
+// 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/vision_deficiency.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+AtomicString CreateFilterDataUrl(AtomicString piece) {
+ // clang-format off
+ AtomicString url =
+ "data:image/svg+xml,"
+ "<svg xmlns=\"http://www.w3.org/2000/svg\">"
+ "<filter id=\"f\">" +
+ piece +
+ "</filter>"
+ "</svg>"
+ "#f";
+ // clang-format on
+ return url;
+}
+
+AtomicString CreateVisionDeficiencyFilterUrl(
+ VisionDeficiency vision_deficiency) {
+ // The filter color matrices are based on the following research paper:
+ // Gustavo M. Machado, Manuel M. Oliveira, and Leandro A. F. Fernandes
+ // "A Physiologically-based Model for Simulation of Color Vision Deficiency".
+ // IEEE Transactions on Visualization and Computer Graphics. Volume 15 (2009),
+ // Number 6, November/December 2009. pp. 1291-1298.
+ // https://www.inf.ufrgs.br/~oliveira/pubs_files/CVD_Simulation/CVD_Simulation.html
+ switch (vision_deficiency) {
+ case VisionDeficiency::kAchromatopsia:
+ return CreateFilterDataUrl(
+ "<feColorMatrix values=\""
+ "0.299 0.587 0.114 0.000 0.000 "
+ "0.299 0.587 0.114 0.000 0.000 "
+ "0.299 0.587 0.114 0.000 0.000 "
+ "0.000 0.000 0.000 1.000 0.000 "
+ "\"/>");
+ case VisionDeficiency::kBlurredVision:
+ return CreateFilterDataUrl("<feGaussianBlur stdDeviation=\"2\"/>");
+ case VisionDeficiency::kDeuteranopia:
+ return CreateFilterDataUrl(
+ "<feColorMatrix values=\""
+ " 0.367 0.861 -0.228 0.000 0.000 "
+ " 0.280 0.673 0.047 0.000 0.000 "
+ "-0.012 0.043 0.969 0.000 0.000 "
+ " 0.000 0.000 0.000 1.000 0.000 "
+ "\"/>");
+ case VisionDeficiency::kProtanopia:
+ return CreateFilterDataUrl(
+ "<feColorMatrix values=\""
+ " 0.152 1.053 -0.205 0.000 0.000 "
+ " 0.115 0.786 0.099 0.000 0.000 "
+ "-0.004 -0.048 1.052 0.000 0.000 "
+ " 0.000 0.000 0.000 1.000 0.000 "
+ "\"/>");
+ case VisionDeficiency::kTritanopia:
+ return CreateFilterDataUrl(
+ "<feColorMatrix values=\""
+ " 1.256 -0.077 -0.179 0.000 0.000 "
+ "-0.078 0.931 0.148 0.000 0.000 "
+ " 0.005 0.691 0.304 0.000 0.000 "
+ " 0.000 0.000 0.000 1.000 0.000 "
+ "\"/>");
+ case VisionDeficiency::kNoVisionDeficiency:
+ NOTREACHED();
+ return "";
+ }
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/css/vision_deficiency.h b/chromium/third_party/blink/renderer/core/css/vision_deficiency.h
new file mode 100644
index 00000000000..84d70757200
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/vision_deficiency.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_VISION_DEFICIENCY_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_VISION_DEFICIENCY_H_
+
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+enum class VisionDeficiency {
+ kNoVisionDeficiency,
+ kAchromatopsia,
+ kBlurredVision,
+ kDeuteranopia,
+ kProtanopia,
+ kTritanopia,
+};
+
+AtomicString CreateVisionDeficiencyFilterUrl(
+ VisionDeficiency vision_deficiency);
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_VISION_DEFICIENCY_H_
diff --git a/chromium/third_party/blink/renderer/core/css/webxr_overlay.css b/chromium/third_party/blink/renderer/core/css/webxr_overlay.css
new file mode 100644
index 00000000000..d4f65fb76e1
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/css/webxr_overlay.css
@@ -0,0 +1,26 @@
+:xr-overlay {
+ /* force a transparent background */
+ background: rgba(0,0,0,0) !important;
+
+ /* act as containing block for descendants */
+ contain: paint !important;
+
+ /* the following styling is identical to :fullscreen */
+ position: fixed !important;
+ top: 0 !important;
+ right: 0 !important;
+ bottom: 0 !important;
+ left: 0 !important;
+ margin: 0 !important;
+ box-sizing: border-box !important;
+ min-width: 0 !important;
+ max-width: none !important;
+ min-height: 0 !important;
+ max-height: none !important;
+ width: 100% !important;
+ height: 100% !important;
+ transform: none !important;
+
+ /* intentionally not !important */
+ object-fit: contain;
+}
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 9587445ac7d..b331bb226e7 100644
--- a/chromium/third_party/blink/renderer/core/display_lock/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/display_lock/BUILD.gn
@@ -2,40 +2,19 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import("//testing/libfuzzer/fuzzer_test.gni")
import("//third_party/blink/renderer/core/core.gni")
blink_core_sources("display_lock") {
sources = [
- "display_lock_budget.cc",
- "display_lock_budget.h",
"display_lock_context.cc",
"display_lock_context.h",
"display_lock_utilities.cc",
"display_lock_utilities.h",
"render_subtree_activation_event.cc",
"render_subtree_activation_event.h",
- "strict_yielding_display_lock_budget.cc",
- "strict_yielding_display_lock_budget.h",
- "unyielding_display_lock_budget.cc",
- "unyielding_display_lock_budget.h",
- "yielding_display_lock_budget.cc",
- "yielding_display_lock_budget.h",
]
public_deps = [
"//third_party/blink/renderer/bindings/core/v8:bindings_core_v8_generated",
]
}
-
-fuzzer_test("display_lock_fuzzer") {
- sources = [
- "display_lock_fuzzer.cc",
- ]
- deps = [
- "//content/test/fuzzer:fuzzer_support",
- ]
-
- seed_corpus = "//third_party/blink/web_tests/wpt_internal/display-lock"
- dict = "display_lock.dict"
-}
diff --git a/chromium/third_party/blink/renderer/core/display_lock/DEPS b/chromium/third_party/blink/renderer/core/display_lock/DEPS
deleted file mode 100644
index df774afac1e..00000000000
--- a/chromium/third_party/blink/renderer/core/display_lock/DEPS
+++ /dev/null
@@ -1,3 +0,0 @@
-specific_include_rules = {
- "display_lock_fuzzer.cc" : [ "+content/test/fuzzer/fuzzer_support.h" ],
-}
diff --git a/chromium/third_party/blink/renderer/core/display_lock/display_lock.dict b/chromium/third_party/blink/renderer/core/display_lock/display_lock.dict
deleted file mode 100644
index 02c0f17d8f2..00000000000
--- a/chromium/third_party/blink/renderer/core/display_lock/display_lock.dict
+++ /dev/null
@@ -1,5 +0,0 @@
-"rendersubtree=''"
-"rendersubtree='invisible'"
-"rendersubtree='invisible activatable'"
-"updateRendering()"
-"content-size"
diff --git a/chromium/third_party/blink/renderer/core/display_lock/display_lock_budget.cc b/chromium/third_party/blink/renderer/core/display_lock/display_lock_budget.cc
deleted file mode 100644
index 35a62be4289..00000000000
--- a/chromium/third_party/blink/renderer/core/display_lock/display_lock_budget.cc
+++ /dev/null
@@ -1,50 +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/core/display_lock/display_lock_budget.h"
-
-#include "base/time/default_tick_clock.h"
-#include "third_party/blink/renderer/core/display_lock/display_lock_context.h"
-
-namespace blink {
-
-DisplayLockBudget::DisplayLockBudget(DisplayLockContext* context)
- : clock_(base::DefaultTickClock::GetInstance()), context_(context) {}
-
-bool DisplayLockBudget::MarkDirtyForPhaseIfNeeded(Phase phase) {
- switch (phase) {
- case Phase::kStyle:
- return context_->MarkForStyleRecalcIfNeeded();
- case Phase::kLayout:
- return context_->MarkForLayoutIfNeeded();
- case Phase::kPrePaint:
- return context_->MarkAncestorsForPrePaintIfNeeded();
- }
- NOTREACHED();
- return false;
-}
-
-bool DisplayLockBudget::IsElementDirtyForPhase(Phase phase) const {
- switch (phase) {
- case Phase::kStyle:
- return context_->IsElementDirtyForStyleRecalc();
- case Phase::kLayout:
- return context_->IsElementDirtyForLayout();
- case Phase::kPrePaint:
- return context_->IsElementDirtyForPrePaint();
- }
- NOTREACHED();
- return false;
-}
-
-void DisplayLockBudget::MarkPhaseAsDirty(Phase marking_phase) {
- // Mark the next phase we're scheduled to run.
- for (auto phase = static_cast<unsigned>(marking_phase);
- phase <= static_cast<unsigned>(Phase::kLast); ++phase) {
- if (MarkDirtyForPhaseIfNeeded(static_cast<Phase>(phase)))
- break;
- }
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/display_lock/display_lock_budget.h b/chromium/third_party/blink/renderer/core/display_lock/display_lock_budget.h
deleted file mode 100644
index aeea5fa3dbe..00000000000
--- a/chromium/third_party/blink/renderer/core/display_lock/display_lock_budget.h
+++ /dev/null
@@ -1,73 +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_DISPLAY_LOCK_DISPLAY_LOCK_BUDGET_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_DISPLAY_LOCK_DISPLAY_LOCK_BUDGET_H_
-
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/platform/heap/member.h"
-
-namespace base {
-class TickClock;
-}
-
-namespace blink {
-
-class DisplayLockContext;
-struct LifecycleData;
-
-class CORE_EXPORT DisplayLockBudget {
- public:
- enum class Phase : unsigned {
- kStyle,
- kLayout,
- kPrePaint,
- kFirst = kStyle,
- kLast = kPrePaint
- };
-
- DisplayLockBudget(DisplayLockContext*);
- virtual ~DisplayLockBudget() = default;
-
- // Returns true if the given phase is allowed to proceed under the current
- // budget.
- virtual bool ShouldPerformPhase(Phase, const LifecycleData&) = 0;
-
- // Called just before any calls to ShouldPerformPhase for a new lifecycle.
- virtual void OnLifecycleChange(const LifecycleData&) = 0;
-
- // Notifies the budget that the given phase was completed.
- virtual void DidPerformPhase(Phase) = 0;
-
- // Returns true if according to this budget, we still need a lifecycle update.
- // For example, if a budget blocked a needed phase, then it this will return
- // true indicating that another frame is needed.
- virtual bool NeedsLifecycleUpdates() const = 0;
-
- // The caller is the owner of the |clock|. The |clock| must outlive the
- // DisplayLockBudget.
- void SetTickClockForTesting(const base::TickClock* clock) { clock_ = clock; }
-
- protected:
- // Returns true if there is likely to be work for the given phase.
- bool IsElementDirtyForPhase(Phase) const;
-
- void MarkPhaseAsDirty(Phase marking_phase);
-
- // Marks the element and ancestor chain dirty for the given phase if it's
- // needed. Returns true if the ancestors were marked dirty and false
- // otherwise.
- bool MarkDirtyForPhaseIfNeeded(Phase);
-
- const base::TickClock* clock_;
-
- private:
- // This is a backpointer to the context, which should always outlive this
- // budget, so it's untraced.
- UntracedMember<DisplayLockContext> context_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DISPLAY_LOCK_DISPLAY_LOCK_BUDGET_H_
diff --git a/chromium/third_party/blink/renderer/core/display_lock/display_lock_budget_test.cc b/chromium/third_party/blink/renderer/core/display_lock/display_lock_budget_test.cc
deleted file mode 100644
index 513da9c01ad..00000000000
--- a/chromium/third_party/blink/renderer/core/display_lock/display_lock_budget_test.cc
+++ /dev/null
@@ -1,608 +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/core/display_lock/display_lock_budget.h"
-
-#include "base/test/test_mock_time_task_runner.h"
-#include "third_party/blink/renderer/bindings/core/v8/script_function.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
-#include "third_party/blink/renderer/core/display_lock/display_lock_context.h"
-#include "third_party/blink/renderer/core/display_lock/strict_yielding_display_lock_budget.h"
-#include "third_party/blink/renderer/core/display_lock/unyielding_display_lock_budget.h"
-#include "third_party/blink/renderer/core/display_lock/yielding_display_lock_budget.h"
-#include "third_party/blink/renderer/core/html_names.h"
-#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
-#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
-#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
-
-namespace blink {
-
-class DisplayLockBudgetTest : public RenderingTest,
- private ScopedDisplayLockingForTest {
- public:
- DisplayLockBudgetTest() : ScopedDisplayLockingForTest(true) {}
- void SetUp() override {
- RenderingTest::SetUp();
- test_task_runner_ = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
- }
-
- base::TimeDelta GetBudget(const YieldingDisplayLockBudget& budget,
- const LifecycleData& lifecycle_data) const {
- return budget.GetCurrentBudget(lifecycle_data);
- }
-
- void ResetDeadlineForTesting(YieldingDisplayLockBudget& budget,
- const LifecycleData& lifecycle_data) {
- budget.deadline_ =
- base::TimeTicks::Now() + budget.GetCurrentBudget(lifecycle_data);
- }
-
- void ResetBudget(std::unique_ptr<DisplayLockBudget> budget,
- DisplayLockContext* context) {
- ASSERT_TRUE(context->update_budget_);
- context->update_budget_ = std::move(budget);
- }
-
- void LockElement(Element& element, bool update_lifecycle = true) {
- element.setAttribute(html_names::kRendersubtreeAttr, "invisible");
- if (update_lifecycle)
- UpdateAllLifecyclePhasesForTest();
- }
-
- void CommitElement(Element& element, bool update_lifecycle = true) {
- element.setAttribute(html_names::kRendersubtreeAttr, "");
- if (update_lifecycle)
- UpdateAllLifecyclePhasesForTest();
- }
-
- protected:
- scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner_;
-
- private:
- base::Optional<RuntimeEnabledFeatures::Backup> features_backup_;
-};
-
-TEST_F(DisplayLockBudgetTest, UnyieldingBudget) {
- // Note that we're not testing the display lock here, just the budget so we
- // can do minimal work to ensure we have a context, ignoring containment and
- // other requirements.
- SetHtmlInnerHTML(R"HTML(
- <style>
- div {
- contain: style layout;
- }
- </style>
- <div id="container"></div>
- )HTML");
-
- auto* element = GetDocument().getElementById("container");
- LockElement(*element, false);
-
- ASSERT_TRUE(element->GetDisplayLockContext());
- UnyieldingDisplayLockBudget budget(element->GetDisplayLockContext());
-
- // When acquiring, we need to update the layout with the locked size, so we
- // need an update.
- EXPECT_TRUE(budget.NeedsLifecycleUpdates());
-
- LifecycleData lifecycle_data;
-
- // Check everything twice since it shouldn't matter how many times we ask the
- // unyielding budget, the results should always be the same.
- for (int i = 0; i < 2; ++i) {
- // Note that although we only dirtied layout, all phases "should" complete,
- // since the budget should never be responsible for blocking phases for any
- // reason other than we're out of budget.
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
- budget.DidPerformPhase(DisplayLockBudget::Phase::kStyle);
- budget.DidPerformPhase(DisplayLockBudget::Phase::kLayout);
- budget.DidPerformPhase(DisplayLockBudget::Phase::kPrePaint);
- }
-}
-
-TEST_F(DisplayLockBudgetTest, StrictYieldingBudget) {
- // Note that we're not testing the display lock here, just the budget so we
- // can do minimal work to ensure we have a context, ignoring containment and
- // other requirements.
- SetBodyInnerHTML(R"HTML(
- <style>
- div {
- contain: style layout;
- }
- </style>
- <div id="container"></div>
- )HTML");
-
- auto* element = GetDocument().getElementById("container");
- LockElement(*element, false);
-
- ASSERT_TRUE(element->GetDisplayLockContext());
- StrictYieldingDisplayLockBudget budget(element->GetDisplayLockContext());
-
- // When acquiring, we need to update the layout with the locked size, so we
- // need an update.
- EXPECT_TRUE(budget.NeedsLifecycleUpdates());
-
- LifecycleData lifecycle_data;
-
- {
- // Initially all of the phase checks should return true, since we don't know
- // which phase the system wants to process next.
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
-
- // Not doing anything should ensure that we schedule another animation by
- // returning true here.
- EXPECT_TRUE(budget.NeedsLifecycleUpdates());
- }
- {
- lifecycle_data.count++;
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
-
- // Once we perform a phase, its check should remain true, but the rest
- // will be false for this cycle.
- budget.DidPerformPhase(DisplayLockBudget::Phase::kStyle);
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- lifecycle_data));
- EXPECT_FALSE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
- EXPECT_FALSE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
- if (true)
- return;
-
- // We would need at least one more run to finish everything.
- EXPECT_TRUE(budget.NeedsLifecycleUpdates());
- }
- {
- lifecycle_data.count++;
- // Run the previous block again, now everything will always return true
- // since the phase we complete here (style) has already been completed
- // before, and we are open to complete a new phase.
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
-
- // Since we already befored style before, no new phase has been processed
- // and all phases are allowed to finish.
- budget.DidPerformPhase(DisplayLockBudget::Phase::kStyle);
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
-
- // We would need at least one more run to finish everything.
- EXPECT_TRUE(budget.NeedsLifecycleUpdates());
- }
- {
- lifecycle_data.count++;
- // On the next run, the checks for phases completed before should always
- // return true, and as before since we haven't completed a new phase, the
- // remainder of the phases should return true for now.
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
-
- // This check is the same as in the previous block, but is here to verify
- // that going through NeedsLifecycleUpdates() and then
- // WillStartLifecycleUpdate() again doesn't change the fact that we should
- // still perform all of the phases at this point.
- budget.DidPerformPhase(DisplayLockBudget::Phase::kStyle);
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
-
- // Let's say layout was clean and we jumped and did prepaint instead, now
- // every phase before and including prepaint should be true, the rest are
- // locked from completing.
- budget.DidPerformPhase(DisplayLockBudget::Phase::kPrePaint);
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
-
- // Note that since we processed everything, we no longer need lifecycle
- // updates.
- EXPECT_FALSE(budget.NeedsLifecycleUpdates());
- }
- {
- // Do one more run to ensure everything is still returning true.
- lifecycle_data.count++;
- // On the last run, we'll complete all phases. Since there is only one
- // remaining phase we haven't done, all of the checks should always return
- // true (it's either an old phase or a first uncompleted phase).
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
-
- budget.DidPerformPhase(DisplayLockBudget::Phase::kStyle);
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
-
- budget.DidPerformPhase(DisplayLockBudget::Phase::kLayout);
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
-
- budget.DidPerformPhase(DisplayLockBudget::Phase::kPrePaint);
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
-
- // Since we completed everything, we should now be returning false here (no
- // more updates needed).
- EXPECT_FALSE(budget.NeedsLifecycleUpdates());
- }
-}
-
-TEST_F(DisplayLockBudgetTest,
- StrictYieldingBudgetOnlyNeedsUpdatesForDirtyPhases) {
- // Note that we're not testing the display lock here, just the budget so we
- // can do minimal work to ensure we have a context, ignoring containment and
- // other requirements.
- SetHtmlInnerHTML(R"HTML(
- <style>
- div {
- contain: style layout;
- }
- </style>
- <div id="container"></div>
- )HTML");
-
- auto* element = GetDocument().getElementById("container");
- LockElement(*element, false);
-
- ASSERT_TRUE(element->GetDisplayLockContext());
- StrictYieldingDisplayLockBudget budget(element->GetDisplayLockContext());
-
- // When acquiring, we need to update the layout with the locked size, so we
- // need an update.
- EXPECT_TRUE(budget.NeedsLifecycleUpdates());
-
- LifecycleData lifecycle_data;
- budget.OnLifecycleChange(lifecycle_data);
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
- budget.DidPerformPhase(DisplayLockBudget::Phase::kLayout);
- EXPECT_TRUE(budget.NeedsLifecycleUpdates());
-
- lifecycle_data.count++;
- budget.OnLifecycleChange(lifecycle_data);
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
- budget.DidPerformPhase(DisplayLockBudget::Phase::kPrePaint);
-
- // Note that since the layout was indicated as done (from the budget
- // perspective), it will no longer need updates even though the true layout is
- // dirty. This is because it will no longer block layout from synchronously
- // completing whenever necessary.
- EXPECT_FALSE(budget.NeedsLifecycleUpdates());
-}
-
-TEST_F(DisplayLockBudgetTest, YieldingBudget) {
- // Note that we're not testing the display lock here, just the budget so we
- // can do minimal work to ensure we have a context, ignoring containment and
- // other requirements.
- SetBodyInnerHTML(R"HTML(
- <style>
- div {
- contain: style layout;
- }
- </style>
- <div id="container"></div>
- )HTML");
-
- auto* element = GetDocument().getElementById("container");
- LockElement(*element, false);
-
- ASSERT_TRUE(element->GetDisplayLockContext());
- YieldingDisplayLockBudget budget(element->GetDisplayLockContext());
- budget.SetTickClockForTesting(test_task_runner_->GetMockTickClock());
-
- // When acquiring, we need to update the layout with the locked size, so we
- // need an update.
- EXPECT_TRUE(budget.NeedsLifecycleUpdates());
- LifecycleData lifecycle_data;
- budget.OnLifecycleChange(lifecycle_data);
-
- // Initially all of the phase checks should return true, since we don't know
- // which phase the system wants to process next.
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
-
- // Not doing anything should ensure that we schedule another animation by
- // returning true here.
- EXPECT_TRUE(budget.NeedsLifecycleUpdates());
-
- // Advancing the clock a bit will make us still want to the phases.
- test_task_runner_->FastForwardBy(GetBudget(budget, lifecycle_data) / 2);
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
-
- // However, once we're out of budget, we will only do the next phase.
- test_task_runner_->FastForwardBy(GetBudget(budget, lifecycle_data));
-
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- lifecycle_data));
- EXPECT_FALSE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
- EXPECT_FALSE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
-
- // Starting a new lifecycle will reset the budget.
- lifecycle_data.count++;
- lifecycle_data.start_time = test_task_runner_->NowTicks();
- budget.OnLifecycleChange(lifecycle_data);
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
-
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
-
- // Performing a phase still keeps the rest of the phases available for work
- // since we haven't advanced the clock.
- budget.DidPerformPhase(DisplayLockBudget::Phase::kStyle);
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
-
- // Now that we're out of budget, phases performed previously should remain
- // true.
- test_task_runner_->FastForwardBy(GetBudget(budget, lifecycle_data) * 2);
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- lifecycle_data));
- EXPECT_FALSE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
- EXPECT_FALSE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
-
- // Sanity check here: the element still needs layout.
- EXPECT_TRUE(budget.NeedsLifecycleUpdates());
-
- // Resetting the budget, and advancing again should yield the same results as
- // before, except that we will process at least one more phase.
- lifecycle_data.count++;
- lifecycle_data.start_time = test_task_runner_->NowTicks();
- budget.OnLifecycleChange(lifecycle_data);
-
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
- test_task_runner_->FastForwardBy(GetBudget(budget, lifecycle_data) * 2);
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
- EXPECT_FALSE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
-
- // Eventually the budget becomes essentially infinite.
- lifecycle_data.count += 60;
- budget.OnLifecycleChange(lifecycle_data);
-
- EXPECT_GT(GetBudget(budget, lifecycle_data),
- base::TimeDelta::FromMilliseconds(1e6));
- for (int i = 0; i < 60; ++i) {
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
- EXPECT_TRUE(budget.ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
- test_task_runner_->FastForwardBy(base::TimeDelta::FromMillisecondsD(10000));
- }
-}
-
-TEST_F(DisplayLockBudgetTest, YieldingBudgetMarksNextPhase) {
- // Note that we're not testing the display lock here, just the budget so we
- // can do minimal work to ensure we have a context, ignoring containment and
- // other requirements.
- SetHtmlInnerHTML(R"HTML(
- <style>
- #container {
- contain: style layout;
- }
- </style>
- <div id="parent"><div id="container"><div id="child"></div></div></div>
- )HTML");
-
- auto* element = GetDocument().getElementById("container");
- LockElement(*element);
-
- ASSERT_TRUE(element->GetDisplayLockContext());
- ASSERT_TRUE(element->GetDisplayLockContext()->IsLocked());
-
- auto budget_owned = base::WrapUnique(
- new YieldingDisplayLockBudget(element->GetDisplayLockContext()));
- auto* budget = budget_owned.get();
- budget->SetTickClockForTesting(test_task_runner_->GetMockTickClock());
- {
- auto* script_state = ToScriptStateForMainWorld(GetDocument().GetFrame());
- ScriptState::Scope scope(script_state);
- element->GetDisplayLockContext()->UpdateRendering(script_state);
- ResetBudget(std::move(budget_owned), element->GetDisplayLockContext());
- }
-
- // When acquiring, we need to update the layout with the locked size, so we
- // need an update.
- EXPECT_TRUE(budget->NeedsLifecycleUpdates());
-
- // Dirtying the element will cause us to do updates.
- GetDocument().getElementById("child")->SetInnerHTMLFromString("a");
-
- auto* parent = GetDocument().getElementById("parent");
- EXPECT_TRUE(budget->NeedsLifecycleUpdates());
-
- LifecycleData lifecycle_data;
- budget->OnLifecycleChange(lifecycle_data);
-
- GetDocument().View()->SetInLifecycleUpdateForTest(true);
- GetDocument().View()->SetLifecycleDataForTesting(lifecycle_data);
-
- // Initially all of the phase checks should return true, since we don't know
- // which phase the system wants to process next.
- EXPECT_TRUE(
- budget->ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- GetDocument().View()->CurrentLifecycleData()));
- EXPECT_TRUE(
- budget->ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- GetDocument().View()->CurrentLifecycleData()));
- EXPECT_TRUE(
- budget->ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- GetDocument().View()->CurrentLifecycleData()));
-
- EXPECT_TRUE(parent->NeedsStyleRecalc() || parent->ChildNeedsStyleRecalc());
- EXPECT_TRUE(element->NeedsStyleRecalc() || element->ChildNeedsStyleRecalc());
-
- test_task_runner_->FastForwardBy(
- GetBudget(*budget, GetDocument().View()->CurrentLifecycleData()) * 2);
- EXPECT_TRUE(
- budget->ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- GetDocument().View()->CurrentLifecycleData()));
- EXPECT_FALSE(
- budget->ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- GetDocument().View()->CurrentLifecycleData()));
-
- GetDocument().UpdateStyleAndLayoutTree();
- EXPECT_FALSE(
- budget->ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- GetDocument().View()->CurrentLifecycleData()));
-
- EXPECT_FALSE(parent->NeedsStyleRecalc() || parent->ChildNeedsStyleRecalc());
- EXPECT_FALSE(element->NeedsStyleRecalc() || element->ChildNeedsStyleRecalc());
-
- EXPECT_TRUE(parent->GetLayoutObject()->NeedsLayout());
- EXPECT_TRUE(element->GetLayoutObject()->NeedsLayout());
-
- ResetDeadlineForTesting(*budget,
- GetDocument().View()->CurrentLifecycleData());
- EXPECT_TRUE(
- budget->ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- GetDocument().View()->CurrentLifecycleData()));
-
- GetDocument().View()->SetInLifecycleUpdateForTest(false);
-}
-
-TEST_F(DisplayLockBudgetTest, UpdateHappensInLifecycleOnly) {
- // Note that we're not testing the display lock here, just the budget so we
- // can do minimal work to ensure we have a context, ignoring containment and
- // other requirements.
- SetHtmlInnerHTML(R"HTML(
- <style>
- #container {
- contain: style layout;
- }
- </style>
- <div id="parent"><div id="container"><div id="child"></div></div></div>
- )HTML");
-
- auto* element = GetDocument().getElementById("container");
- LockElement(*element);
-
- ASSERT_TRUE(element->GetDisplayLockContext());
- ASSERT_TRUE(element->GetDisplayLockContext()->IsLocked());
-
- auto budget_owned = base::WrapUnique(
- new UnyieldingDisplayLockBudget(element->GetDisplayLockContext()));
- auto* budget = budget_owned.get();
- {
- auto* script_state = ToScriptStateForMainWorld(GetDocument().GetFrame());
- ScriptState::Scope scope(script_state);
- element->GetDisplayLockContext()->UpdateRendering(script_state);
- ResetBudget(std::move(budget_owned), element->GetDisplayLockContext());
- }
-
- // When acquiring, we need to update the layout with the locked size, so we
- // need an update.
- EXPECT_TRUE(budget->NeedsLifecycleUpdates());
-
- LifecycleData lifecycle_data;
- budget->OnLifecycleChange(lifecycle_data);
-
- auto* context = element->GetDisplayLockContext();
- EXPECT_TRUE(budget->ShouldPerformPhase(DisplayLockBudget::Phase::kStyle,
- lifecycle_data));
- EXPECT_TRUE(budget->ShouldPerformPhase(DisplayLockBudget::Phase::kLayout,
- lifecycle_data));
- EXPECT_TRUE(budget->ShouldPerformPhase(DisplayLockBudget::Phase::kPrePaint,
- lifecycle_data));
-
- // Since we're not in a lifecycle, the budget itself should not want to do any
- // phases, even though the budget allows it.
- EXPECT_FALSE(context->ShouldStyle(DisplayLockLifecycleTarget::kChildren));
- EXPECT_FALSE(context->ShouldLayout(DisplayLockLifecycleTarget::kChildren));
- EXPECT_FALSE(context->ShouldPrePaint(DisplayLockLifecycleTarget::kChildren));
-
- GetDocument().GetFrame()->View()->SetInLifecycleUpdateForTest(true);
-
- EXPECT_TRUE(context->ShouldStyle(DisplayLockLifecycleTarget::kChildren));
- EXPECT_TRUE(context->ShouldLayout(DisplayLockLifecycleTarget::kChildren));
- EXPECT_TRUE(context->ShouldPrePaint(DisplayLockLifecycleTarget::kChildren));
-
- GetDocument().GetFrame()->View()->SetInLifecycleUpdateForTest(false);
-
- EXPECT_FALSE(context->ShouldStyle(DisplayLockLifecycleTarget::kChildren));
- EXPECT_FALSE(context->ShouldLayout(DisplayLockLifecycleTarget::kChildren));
- EXPECT_FALSE(context->ShouldPrePaint(DisplayLockLifecycleTarget::kChildren));
-
- // Ensure to flush any tasks scheduled by context calls.
- test::RunPendingTasks();
-}
-} // namespace blink
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 cc63c0fd03d..a758b00fa8a 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
@@ -7,18 +7,18 @@
#include <string>
#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_macros.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
#include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/css/style_recalc.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/display_lock/strict_yielding_display_lock_budget.h"
-#include "third_party/blink/renderer/core/display_lock/unyielding_display_lock_budget.h"
-#include "third_party/blink/renderer/core/display_lock/yielding_display_lock_budget.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"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
+#include "third_party/blink/renderer/core/editing/frame_selection.h"
+#include "third_party/blink/renderer/core/editing/selection_template.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/html_element_type_helpers.h"
#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
@@ -34,139 +34,234 @@ namespace blink {
namespace {
namespace rejection_names {
-const char* kExecutionContextDestroyed = "Execution context destroyed.";
const char* kContainmentNotSatisfied =
"Containment requirement is not satisfied.";
const char* kUnsupportedDisplay =
"Element has unsupported display type (display: contents).";
-const char* kElementIsDisconnected = "Element is disconnected.";
-const char* kElementIsNested = "Element is nested under a locked element.";
} // namespace rejection_names
-// Helper function to convert a display locking state to a string. Used in
-// traces.
-std::string StateToString(DisplayLockContext::State state) {
- switch (state) {
- case DisplayLockContext::kLocked:
- return "kLocked";
- case DisplayLockContext::kUpdating:
- return "kUpdating";
- case DisplayLockContext::kCommitting:
- return "kCommitting";
- case DisplayLockContext::kUnlocked:
- return "kUnlocked";
+void RecordActivationReason(Document* document,
+ DisplayLockActivationReason reason) {
+ int ordered_reason = -1;
+
+ // IMPORTANT: This number needs to be bumped up when adding
+ // new reasons.
+ static const int number_of_reasons = 9;
+
+ switch (reason) {
+ case DisplayLockActivationReason::kAccessibility:
+ ordered_reason = 0;
+ break;
+ case DisplayLockActivationReason::kFindInPage:
+ ordered_reason = 1;
+ break;
+ case DisplayLockActivationReason::kFragmentNavigation:
+ ordered_reason = 2;
+ break;
+ case DisplayLockActivationReason::kScriptFocus:
+ ordered_reason = 3;
+ break;
+ case DisplayLockActivationReason::kScrollIntoView:
+ ordered_reason = 4;
+ break;
+ case DisplayLockActivationReason::kSelection:
+ ordered_reason = 5;
+ break;
+ case DisplayLockActivationReason::kSimulatedClick:
+ ordered_reason = 6;
+ break;
+ case DisplayLockActivationReason::kUserFocus:
+ ordered_reason = 7;
+ break;
+ case DisplayLockActivationReason::kViewportIntersection:
+ ordered_reason = 8;
+ break;
+ case DisplayLockActivationReason::kViewport:
+ case DisplayLockActivationReason::kAny:
+ NOTREACHED();
+ break;
}
- return "";
-}
+ UMA_HISTOGRAM_ENUMERATION("Blink.Render.DisplayLockActivationReason",
+ ordered_reason, number_of_reasons);
-// Helper function that returns an immediately rejected promise.
-ScriptPromise GetRejectedPromise(ScriptState* script_state,
- const char* rejection_reason) {
- auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
- auto promise = resolver->Promise();
- resolver->Reject(MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotAllowedError, rejection_reason));
- return promise;
+ if (document && reason == DisplayLockActivationReason::kFindInPage)
+ document->MarkHasFindInPageSubtreeVisibilityActiveMatch();
}
+} // namespace
-// Helper function that returns an immediately resolved promise.
-ScriptPromise GetResolvedPromise(ScriptState* script_state) {
- auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
- auto promise = resolver->Promise();
- resolver->Resolve();
- return promise;
+DisplayLockContext::DisplayLockContext(Element* element)
+ : element_(element), document_(&element_->GetDocument()) {
+ document_->AddDisplayLockContext(this);
+ DetermineIfSubtreeHasFocus();
+ DetermineIfSubtreeHasSelection();
}
-} // namespace
+void DisplayLockContext::SetRequestedState(ESubtreeVisibility state) {
+ if (state_ == state)
+ return;
+ state_ = state;
+ switch (state_) {
+ case ESubtreeVisibility::kVisible:
+ RequestUnlock();
+ break;
+ case ESubtreeVisibility::kAuto:
+ RequestLock(static_cast<uint16_t>(DisplayLockActivationReason::kAny));
+ break;
+ case ESubtreeVisibility::kHidden:
+ RequestLock(0u);
+ break;
+ case ESubtreeVisibility::kHiddenMatchable:
+ RequestLock(
+ static_cast<uint16_t>(DisplayLockActivationReason::kAny) &
+ ~static_cast<uint16_t>(DisplayLockActivationReason::kViewport));
+ break;
+ }
+ // In a new state, we might need to either start or stop observing viewport
+ // intersections.
+ UpdateActivationObservationIfNeeded();
-DisplayLockContext::DisplayLockContext(Element* element,
- ExecutionContext* context)
- : ContextLifecycleObserver(context),
- element_(element),
- document_(&element_->GetDocument()),
- state_(this) {}
+ // If we needed a deferred not intersecting signal from 'auto' mode, we can
+ // set that to false, since the mode has switched to something else. If we're
+ // switching _to_ 'auto' mode, this should already be false and will be a
+ // no-op.
+ DCHECK(state_ != ESubtreeVisibility::kAuto ||
+ !needs_deferred_not_intersecting_signal_);
+ needs_deferred_not_intersecting_signal_ = false;
+ UpdateLifecycleNotificationRegistration();
-DisplayLockContext::~DisplayLockContext() {
- DCHECK_EQ(state_, kUnlocked);
+ // Note that we call this here since the |state_| change is a render affecting
+ // state, but is tracked independently.
+ NotifyRenderAffectingStateChanged();
}
-void DisplayLockContext::Trace(blink::Visitor* visitor) {
- visitor->Trace(update_resolver_);
- visitor->Trace(element_);
- visitor->Trace(document_);
- visitor->Trace(whitespace_reattach_set_);
- ContextLifecycleObserver::Trace(visitor);
+void DisplayLockContext::AdjustElementStyle(ComputedStyle* style) const {
+ if (state_ == ESubtreeVisibility::kVisible)
+ return;
+ // If not visible, element gains style and layout containment. If skipped, it
+ // also gains size containment.
+ // https://wicg.github.io/display-locking/#subtree-visibility
+ auto contain = style->Contain() | kContainsStyle | kContainsLayout;
+ if (IsLocked())
+ contain |= kContainsSize;
+ style->SetContain(contain);
+}
+
+void DisplayLockContext::RequestLock(uint16_t activation_mask) {
+ UpdateActivationMask(activation_mask);
+ SetRenderAffectingState(RenderAffectingState::kLockRequested, true);
+}
+
+void DisplayLockContext::RequestUnlock() {
+ SetRenderAffectingState(RenderAffectingState::kLockRequested, false);
}
-void DisplayLockContext::Dispose() {
- // Note that if we have any resolvers at dispose time, then it's too late to
- // reject the promise, since we are not allowed to create new strong
- // references to objects already set for destruction (and rejecting would do
- // this since the rejection has to be deferred). We need to detach instead.
- // TODO(vmpstr): See if there is another earlier time we can detect that we're
- // going to be disposed.
- FinishUpdateResolver(kDetach);
- state_ = kUnlocked;
+void DisplayLockContext::UpdateActivationMask(uint16_t activatable_mask) {
+ if (activatable_mask == activatable_mask_)
+ return;
+
+ bool all_activation_was_blocked = !activatable_mask_;
+ bool all_activation_is_blocked = !activatable_mask;
+ UpdateDocumentBookkeeping(IsLocked(), all_activation_was_blocked, IsLocked(),
+ all_activation_is_blocked);
+
+ activatable_mask_ = activatable_mask;
}
-void DisplayLockContext::ContextDestroyed(ExecutionContext*) {
- FinishUpdateResolver(kReject, rejection_names::kExecutionContextDestroyed);
- state_ = kUnlocked;
+void DisplayLockContext::UpdateDocumentBookkeeping(
+ bool was_locked,
+ bool all_activation_was_blocked,
+ bool is_locked,
+ bool all_activation_is_blocked) {
+ if (!document_)
+ return;
+
+ if (was_locked != is_locked) {
+ if (is_locked)
+ document_->AddLockedDisplayLock();
+ else
+ document_->RemoveLockedDisplayLock();
+ }
+
+ bool was_locked_and_blocking = was_locked && all_activation_was_blocked;
+ bool is_locked_and_blocking = is_locked && all_activation_is_blocked;
+ if (was_locked_and_blocking != is_locked_and_blocking) {
+ if (is_locked_and_blocking)
+ document_->IncrementDisplayLockBlockingAllActivation();
+ else
+ document_->DecrementDisplayLockBlockingAllActivation();
+ }
}
void DisplayLockContext::UpdateActivationObservationIfNeeded() {
+ // If we don't have a document, then we don't have an observer so just make
+ // sure we're marked as not observing anything and early out.
if (!document_) {
is_observed_ = false;
return;
}
+ // We require observation if we are in 'auto' mode and we're connected to a
+ // view.
bool should_observe =
- IsLocked() &&
- IsActivatable(DisplayLockActivationReason::kViewportIntersection) &&
- ConnectedToView();
- if (should_observe && !is_observed_) {
+ state_ == ESubtreeVisibility::kAuto && ConnectedToView();
+ if (is_observed_ == should_observe)
+ return;
+ is_observed_ = should_observe;
+
+ if (should_observe) {
document_->RegisterDisplayLockActivationObservation(element_);
- } else if (!should_observe && is_observed_) {
+ } else {
document_->UnregisterDisplayLockActivationObservation(element_);
+ // If we're not listening to viewport intersections, then we can assume
+ // we're not intersecting:
+ // 1. We might not be connected, in which case we're not intersecting.
+ // 2. We might not be in 'auto' mode. which means that this doesn't affect
+ // anything consequential but acts as a reset should we switch back to
+ // the 'auto' mode.
+ SetRenderAffectingState(RenderAffectingState::kIntersectsViewport, false);
}
- is_observed_ = should_observe;
}
-void DisplayLockContext::SetActivatable(uint16_t activatable_mask) {
- if (IsLocked()) {
- // If we're locked, the activatable mask might change the activation
- // blocking lock count. If we're not locked, the activation blocking lock
- // count will be updated when we changed the state.
- // Note that we record this only if we're blocking all activation. That is,
- // the lock is considered activatable if any bit is set.
- state_.UpdateActivationBlockingCount(activatable_mask_, activatable_mask);
+bool DisplayLockContext::NeedsLifecycleNotifications() const {
+ return needs_deferred_not_intersecting_signal_;
+}
+
+void DisplayLockContext::UpdateLifecycleNotificationRegistration() {
+ if (!document_ || !document_->View()) {
+ is_registered_for_lifecycle_notifications_ = false;
+ return;
+ }
+
+ bool needs_notifications = NeedsLifecycleNotifications();
+ if (needs_notifications == is_registered_for_lifecycle_notifications_)
+ return;
+
+ is_registered_for_lifecycle_notifications_ = needs_notifications;
+ if (needs_notifications) {
+ document_->View()->RegisterForLifecycleNotifications(this);
+ } else {
+ document_->View()->UnregisterFromLifecycleNotifications(this);
}
- activatable_mask_ = activatable_mask;
- UpdateActivationObservationIfNeeded();
}
-void DisplayLockContext::StartAcquire() {
+void DisplayLockContext::Lock() {
DCHECK(!IsLocked());
- update_budget_.reset();
- state_ = kLocked;
-
- // We're no longer activated, so if the signal didn't run yet, we should
- // cancel it.
- weak_factory_.InvalidateWeakPtrs();
+ is_locked_ = true;
+ UpdateDocumentBookkeeping(false, !activatable_mask_, true,
+ !activatable_mask_);
- // If we're already connected then we need to ensure that we update our style
- // to check for containment later, layout size based on the options, and
- // also clear the painted output.
+ // If we're not connected, then we don't have to do anything else. Otherwise,
+ // we need to ensure that we update our style to check for containment later,
+ // layout size based on the options, and also clear the painted output.
if (!ConnectedToView())
return;
- // There are several ways we can call StartAcquire. Most of them require us to
- // dirty style so that we can add proper containment onto the element.
- // However, if we're doing a StartAcquire from within style recalc, then we
- // don't need to do anything as we should have already added containment.
- // Moreover, dirtying self style from within style recalc is not allowed,
- // since either it has no effect and is cleaned before any work is done, or it
- // causes DHCECKs in AssertLayoutTreeUpdated().
+ // There are two ways we can get locked:
+ // 1. A new subtree-visibility property needs us to be locked.
+ // 2. We're in 'auto' mode and we are not intersecting the viewport.
+ // In the first case, we are already in style processing, so we don't need to
+ // invalidate style. However, in the second case we invalidate style so that
+ // `AdjustElementStyle()` can be called.
if (!document_->InStyleRecalc()) {
element_->SetNeedsStyleRecalc(
kLocalStyleChange,
@@ -177,21 +272,14 @@ void DisplayLockContext::StartAcquire() {
// lifecycle update, this will be a no-op.
ScheduleAnimation();
- // We need to notify the AX cache (if it exists) to update the childrens
- // of |element_| in the AX cache.
+ // We need to notify the AX cache (if it exists) to update |element_|'s
+ // children in the AX cache.
if (AXObjectCache* cache = element_->GetDocument().ExistingAXObjectCache())
cache->ChildrenChanged(element_);
- auto* layout_object = element_->GetLayoutObject();
- if (!layout_object) {
- is_horizontal_writing_mode_ = true;
+ if (!element_->GetLayoutObject())
return;
- }
- layout_object->SetNeedsLayoutAndPrefWidthsRecalc(
- layout_invalidation_reason::kDisplayLock);
-
- is_horizontal_writing_mode_ = layout_object->IsHorizontalWritingMode();
// GraphicsLayer collection would normally skip layers if paint is blocked
// by display-locking (see: CollectDrawableLayersForLayerListRecursively
// in LocalFrameView). However, if we don't trigger this collection, then
@@ -203,179 +291,54 @@ void DisplayLockContext::StartAcquire() {
MarkPaintLayerNeedsRepaint();
}
-ScriptPromise DisplayLockContext::UpdateRendering(ScriptState* script_state) {
- TRACE_EVENT0("blink", "DisplayLockContext::UpdateRendering");
- // Immediately resolve if we're unlocked or disconnected.
- if (state_ == kUnlocked || !ConnectedToView())
- return GetResolvedPromise(script_state);
-
- // If we have a resolver, then we're at least updating already, just return
- // the same promise.
- if (update_resolver_) {
- DCHECK(state_ == kUpdating || state_ == kCommitting) << state_;
- return update_resolver_->Promise();
- }
-
- if (DisplayLockUtilities::NearestLockedExclusiveAncestor(*element_)) {
- return GetRejectedPromise(script_state, rejection_names::kElementIsNested);
- }
-
- MakeResolver(script_state, &update_resolver_);
- StartUpdateIfNeeded();
- return update_resolver_->Promise();
-}
-
-bool DisplayLockContext::CleanupAndRejectCommitIfNotConnected() {
- // If we're not connected, then the process of committing is the same as just
- // unlocking the element. Early out if this conditions *doesn't* hold.
- if (ConnectedToView())
- return false;
-
- state_ = kUnlocked;
- update_budget_.reset();
- // Note that we reject the update, but resolve the commit.
- FinishUpdateResolver(kReject, rejection_names::kElementIsDisconnected);
- return true;
-}
-
-void DisplayLockContext::MakeResolver(ScriptState* script_state,
- Member<ScriptPromiseResolver>* resolver) {
- DCHECK(ConnectedToView());
- document_->View()->RegisterForLifecycleNotifications(this);
- *resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
-}
-
-bool DisplayLockContext::HasResolver() {
- return update_resolver_;
-}
-
-void DisplayLockContext::FinishUpdateResolver(ResolverState state,
- const char* rejection_reason) {
- FinishResolver(&update_resolver_, state, rejection_reason);
-}
-
-void DisplayLockContext::FinishResolver(Member<ScriptPromiseResolver>* resolver,
- ResolverState state,
- const char* rejection_reason) {
- if (!*resolver)
- return;
- switch (state) {
- case kResolve:
- // In order to avoid script doing work as a part of the lifecycle update,
- // we delay the resolution to be in a task.
- GetExecutionContext()
- ->GetTaskRunner(TaskType::kMiscPlatformAPI)
- ->PostTask(FROM_HERE, WTF::Bind(
- +[](ScriptPromiseResolver* resolver) {
- resolver->Resolve();
- },
- WrapPersistent(resolver->Get())));
- break;
- case kReject:
- DCHECK(rejection_reason);
- (*resolver)->Reject(MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotAllowedError, rejection_reason));
- break;
- case kDetach:
- (*resolver)->Detach();
- break;
- }
- *resolver = nullptr;
- if (!HasResolver() && ConnectedToView())
- document_->View()->UnregisterFromLifecycleNotifications(this);
-}
-
-bool DisplayLockContext::ShouldPerformUpdatePhase(
- DisplayLockBudget::Phase phase) const {
- DCHECK(document_);
- if (state_ != kUpdating)
- return false;
- auto* view = document_->View();
- return view && view->InLifecycleUpdate() &&
- update_budget_->ShouldPerformPhase(phase,
- view->CurrentLifecycleData());
-}
-
+// Should* and Did* function for the lifecycle phases. These functions control
+// whether or not to process the lifecycle for self or for children.
+// =============================================================================
bool DisplayLockContext::ShouldStyle(DisplayLockLifecycleTarget target) const {
- return target == DisplayLockLifecycleTarget::kSelf || update_forced_ ||
- state_ > kUpdating ||
- ShouldPerformUpdatePhase(DisplayLockBudget::Phase::kStyle);
+ return !is_locked_ || target == DisplayLockLifecycleTarget::kSelf ||
+ update_forced_ ||
+ (document_->ActivatableDisplayLocksForced() &&
+ IsActivatable(DisplayLockActivationReason::kAny));
}
void DisplayLockContext::DidStyle(DisplayLockLifecycleTarget target) {
- if (state_ == kUnlocked) {
- // If we're committing without finishing the acquire() first, it's possible
- // for the state to be kUnlocked instead of kCommitting. We should still
- // mark child reattachment & whitespace reattachment in that case.
- MarkElementsForWhitespaceReattachment();
- if (element_->ChildNeedsReattachLayoutTree())
- element_->MarkAncestorsWithChildNeedsReattachLayoutTree();
- return;
- }
-
if (target == DisplayLockLifecycleTarget::kSelf) {
+ // TODO(vmpstr): This needs to be in the spec.
if (ForceUnlockIfNeeded())
return;
if (blocked_style_traversal_type_ == kStyleUpdateSelf)
blocked_style_traversal_type_ = kStyleUpdateNotRequired;
- auto* layout_object = element_->GetLayoutObject();
- is_horizontal_writing_mode_ =
- !layout_object || layout_object->IsHorizontalWritingMode();
- return;
+ } else {
+ if (element_->ChildNeedsReattachLayoutTree())
+ element_->MarkAncestorsWithChildNeedsReattachLayoutTree();
+ blocked_style_traversal_type_ = kStyleUpdateNotRequired;
+ MarkElementsForWhitespaceReattachment();
}
-
- if (state_ != kCommitting && state_ != kUpdating && !update_forced_)
- return;
-
- if (element_->ChildNeedsReattachLayoutTree())
- element_->MarkAncestorsWithChildNeedsReattachLayoutTree();
-
- blocked_style_traversal_type_ = kStyleUpdateNotRequired;
-
- MarkElementsForWhitespaceReattachment();
-
- if (state_ == kUpdating)
- update_budget_->DidPerformPhase(DisplayLockBudget::Phase::kStyle);
}
bool DisplayLockContext::ShouldLayout(DisplayLockLifecycleTarget target) const {
- return target == DisplayLockLifecycleTarget::kSelf || update_forced_ ||
- state_ > kUpdating ||
- ShouldPerformUpdatePhase(DisplayLockBudget::Phase::kLayout);
+ return !is_locked_ || target == DisplayLockLifecycleTarget::kSelf ||
+ update_forced_ ||
+ (document_->ActivatableDisplayLocksForced() &&
+ IsActivatable(DisplayLockActivationReason::kAny));
}
void DisplayLockContext::DidLayout(DisplayLockLifecycleTarget target) {
if (target == DisplayLockLifecycleTarget::kSelf)
return;
-
// Since we did layout on children already, we'll clear this.
child_layout_was_blocked_ = false;
- if (state_ == kUpdating)
- update_budget_->DidPerformPhase(DisplayLockBudget::Phase::kLayout);
}
bool DisplayLockContext::ShouldPrePaint(
DisplayLockLifecycleTarget target) const {
- return target == DisplayLockLifecycleTarget::kSelf || update_forced_ ||
- state_ > kUpdating ||
- ShouldPerformUpdatePhase(DisplayLockBudget::Phase::kPrePaint);
+ return !is_locked_ || target == DisplayLockLifecycleTarget::kSelf ||
+ update_forced_;
}
void DisplayLockContext::DidPrePaint(DisplayLockLifecycleTarget target) {
- if (target == DisplayLockLifecycleTarget::kSelf)
- return;
-
- if (state_ == kUpdating)
- update_budget_->DidPerformPhase(DisplayLockBudget::Phase::kPrePaint);
-
-#if DCHECK_IS_ON()
- if (state_ == kUpdating || state_ == kCommitting) {
- // Since we should be under containment, we should have a layer. If we
- // don't, then paint might not happen and we'll never resolve.
- DCHECK(element_->GetLayoutObject()->HasLayer());
- }
-#endif
+ // This is here for symmetry, but could be removed if necessary.
}
bool DisplayLockContext::ShouldPaint(DisplayLockLifecycleTarget target) const {
@@ -383,51 +346,91 @@ bool DisplayLockContext::ShouldPaint(DisplayLockLifecycleTarget target) const {
// check |update_forced_| here. In other words, although |update_forced_|
// could be true here, we still should not paint. This also holds for
// kUpdating state, since updates should not paint.
- return target == DisplayLockLifecycleTarget::kSelf || state_ == kCommitting ||
- state_ == kUnlocked;
+ return !is_locked_ || target == DisplayLockLifecycleTarget::kSelf;
}
void DisplayLockContext::DidPaint(DisplayLockLifecycleTarget) {
// This is here for symmetry, but could be removed if necessary.
}
+// End Should* and Did* functions ==============================================
bool DisplayLockContext::IsActivatable(
DisplayLockActivationReason reason) const {
- return !IsLocked() || (activatable_mask_ & static_cast<uint16_t>(reason));
+ return activatable_mask_ & static_cast<uint16_t>(reason);
}
void DisplayLockContext::FireActivationEvent(Element* activated_element) {
+ DCHECK(RuntimeEnabledFeatures::CSSSubtreeVisibilityActivationEventEnabled());
element_->DispatchEvent(
*MakeGarbageCollected<RenderSubtreeActivationEvent>(*activated_element));
}
void DisplayLockContext::CommitForActivationWithSignal(
- Element* activated_element) {
+ Element* activated_element,
+ DisplayLockActivationReason reason) {
DCHECK(activated_element);
DCHECK(element_);
DCHECK(ConnectedToView());
DCHECK(IsLocked());
DCHECK(ShouldCommitForActivation(DisplayLockActivationReason::kAny));
- document_->EnqueueDisplayLockActivationTask(
- WTF::Bind(&DisplayLockContext::FireActivationEvent,
- weak_factory_.GetWeakPtr(), WrapPersistent(activated_element)));
-
- StartCommit();
- is_activated_ = true;
+ // TODO(vmpstr): Remove this when we have a beforematch event.
+ if (RuntimeEnabledFeatures::CSSSubtreeVisibilityActivationEventEnabled()) {
+ document_->EnqueueDisplayLockActivationTask(
+ WTF::Bind(&DisplayLockContext::FireActivationEvent,
+ weak_factory_.GetWeakPtr(), WrapPersistent(activated_element)));
+ }
- // Since setting the attribute might trigger a commit if we are still locked,
- // we set it after we start the commit.
- if (element_->FastHasAttribute(html_names::kRendersubtreeAttr))
- element_->setAttribute(html_names::kRendersubtreeAttr, "");
+ RecordActivationReason(document_, reason);
}
-bool DisplayLockContext::IsActivated() const {
- return is_activated_;
+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.
+ needs_deferred_not_intersecting_signal_ = false;
+ UpdateLifecycleNotificationRegistration();
+ // If we're not connected, then there is no need to change any state.
+ // This could be the case if we were disconnected while a viewport
+ // intersection notification was pending.
+ if (ConnectedToView())
+ SetRenderAffectingState(RenderAffectingState::kIntersectsViewport, true);
}
-void DisplayLockContext::ClearActivated() {
- is_activated_ = false;
+void DisplayLockContext::NotifyIsNotIntersectingViewport() {
+ if (IsLocked()) {
+ DCHECK(!needs_deferred_not_intersecting_signal_);
+ return;
+ }
+
+ // We might have been disconnected while the intersection observation
+ // notification was pending. Ensure to unregister from lifecycle
+ // notifications if we're doing that, and early out.
+ if (!ConnectedToView()) {
+ needs_deferred_not_intersecting_signal_ = false;
+ UpdateLifecycleNotificationRegistration();
+ return;
+ }
+
+ // There are two situations we need to consider here:
+ // 1. We are off-screen but not nested in any other lock. This means we should
+ // re-lock (also verify that the reason we're in this state is that we're
+ // activated).
+ // 2. We are in a nested locked context. This means we don't actually know
+ // whether we should lock or not. In order to avoid needless dirty of the
+ // layout and style trees up to the nested context, we remain unlocked.
+ // However, we also need to ensure that we relock if we become unnested.
+ // So, we simply delay this check to the next frame (via LocalFrameView),
+ // which will call this function again and so we can perform the check
+ // again.
+ auto* locked_ancestor =
+ DisplayLockUtilities::NearestLockedExclusiveAncestor(*element_);
+ if (locked_ancestor) {
+ needs_deferred_not_intersecting_signal_ = true;
+ } else {
+ needs_deferred_not_intersecting_signal_ = false;
+ SetRenderAffectingState(RenderAffectingState::kIntersectsViewport, false);
+ }
+ UpdateLifecycleNotificationRegistration();
}
bool DisplayLockContext::ShouldCommitForActivation(
@@ -435,21 +438,16 @@ bool DisplayLockContext::ShouldCommitForActivation(
return IsActivatable(reason) && IsLocked();
}
-void DisplayLockContext::DidAttachLayoutTree() {
- if (state_ >= kUnlocked)
- return;
-
- if (auto* layout_object = element_->GetLayoutObject())
- is_horizontal_writing_mode_ = layout_object->IsHorizontalWritingMode();
-}
-
DisplayLockContext::ScopedForcedUpdate
DisplayLockContext::GetScopedForcedUpdate() {
- if (state_ >= kCommitting)
+ if (!is_locked_)
return ScopedForcedUpdate(nullptr);
DCHECK(!update_forced_);
update_forced_ = true;
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(
+ TRACE_DISABLED_BY_DEFAULT("blink.debug.display_lock"), "LockForced",
+ TRACE_ID_LOCAL(this));
// Now that the update is forced, we should ensure that style layout, and
// prepaint code can reach it via dirty bits. Note that paint isn't a part of
@@ -464,27 +462,42 @@ DisplayLockContext::GetScopedForcedUpdate() {
void DisplayLockContext::NotifyForcedUpdateScopeEnded() {
DCHECK(update_forced_);
update_forced_ = false;
+ TRACE_EVENT_NESTABLE_ASYNC_END0(
+ TRACE_DISABLED_BY_DEFAULT("blink.debug.display_lock"), "LockForced",
+ TRACE_ID_LOCAL(this));
}
-void DisplayLockContext::StartCommit() {
+void DisplayLockContext::Unlock() {
DCHECK(IsLocked());
- if (CleanupAndRejectCommitIfNotConnected())
- return;
+ is_locked_ = false;
+ UpdateDocumentBookkeeping(true, !activatable_mask_, false,
+ !activatable_mask_);
- if (state_ != kUpdating)
- ScheduleAnimation();
-
- // We might already be unlocked due to above, but we should still mark
- // ancestor chains for updates below.
- if (state_ < kCommitting)
- state_ = kCommitting;
+ if (!ConnectedToView())
+ return;
- update_budget_.reset();
+ ScheduleAnimation();
- // We skip updating the style dirtiness if we're within style recalc. This is
- // instead handled by a call to AdjustStyleRecalcChangeForChildren().
+ // There are a few ways we can get unlocked:
+ // 1. A new subtree-visibility property needs us to be ulocked.
+ // 2. We're in 'auto' mode and we are intersecting the viewport.
+ // 3. We're activating in hidden-matchable or auto mode
+ // In the first case, we are already in style processing, so we don't need to
+ // invalidate style. However, in the second and third cases we invalidate
+ // style so that `AdjustElementStyle()` can be called.
+ // TODO(vmpstr): Case 3 needs to be reworked, since the spec no longer has a
+ // notion of activation.
if (!document_->InStyleRecalc()) {
- // We're committing without a budget, so ensure we can reach style.
+ // Since size containment depends on the activatability state, we should
+ // invalidate the style for this element, so that the style adjuster can
+ // properly remove the containment.
+ element_->SetNeedsStyleRecalc(
+ kLocalStyleChange,
+ StyleChangeReasonForTracing::Create(style_change_reason::kDisplayLock));
+
+ // Also propagate any dirty bits that we have previously blocked.
+ // If we're in style recalc, this will be handled by
+ // `AdjustStyleRecalcChangeForChildren()`.
MarkForStyleRecalcIfNeeded();
}
@@ -503,41 +516,6 @@ void DisplayLockContext::StartCommit() {
MarkForLayoutIfNeeded();
MarkAncestorsForPrePaintIfNeeded();
MarkPaintLayerNeedsRepaint();
-
- layout_object->SetNeedsLayoutAndPrefWidthsRecalc(
- layout_invalidation_reason::kDisplayLock);
-
- if (auto* view = layout_object->GetFrameView())
- view->SetNeedsForcedResizeObservations();
-}
-
-void DisplayLockContext::StartUpdateIfNeeded() {
- // We should not be calling this if we're unlocked.
- DCHECK_NE(state_, kUnlocked);
- // Any state other than kLocked means that we are already in the process of
- // updating/committing, so we can piggy back on that process without kicking
- // off any new updates.
- if (state_ != kLocked)
- return;
-
- // We don't need to mark anything dirty since the budget will take care of
- // that for us.
- update_budget_ = CreateNewBudget();
- state_ = kUpdating;
- ScheduleAnimation();
-}
-
-std::unique_ptr<DisplayLockBudget> DisplayLockContext::CreateNewBudget() {
- switch (BudgetType::kDefault) {
- case BudgetType::kDoNotYield:
- return base::WrapUnique(new UnyieldingDisplayLockBudget(this));
- case BudgetType::kStrictYieldBetweenLifecyclePhases:
- return base::WrapUnique(new StrictYieldingDisplayLockBudget(this));
- case BudgetType::kYieldBetweenLifecyclePhases:
- return base::WrapUnique(new YieldingDisplayLockBudget(this));
- }
- NOTREACHED();
- return nullptr;
}
void DisplayLockContext::AddToWhitespaceReattachSet(Element& element) {
@@ -563,7 +541,6 @@ StyleRecalcChange DisplayLockContext::AdjustStyleRecalcChangeForChildren(
// Note that since we're already in self style recalc, this code is shorter
// since it doesn't have to deal with dirtying self-style.
DCHECK(document_->InStyleRecalc());
- DCHECK(!IsAttributeVersion(this));
if (reattach_layout_tree_was_blocked_) {
change = change.ForceReattachLayoutTree();
@@ -743,6 +720,9 @@ void DisplayLockContext::DidMoveToNewDocument(Document& old_document) {
DCHECK(element_);
document_ = &element_->GetDocument();
+ old_document.RemoveDisplayLockContext(this);
+ document_->AddDisplayLockContext(this);
+
if (is_observed_) {
old_document.UnregisterDisplayLockActivationObservation(element_);
document_->RegisterDisplayLockActivationObservation(element_);
@@ -750,65 +730,43 @@ void DisplayLockContext::DidMoveToNewDocument(Document& old_document) {
// Since we're observing the lifecycle updates, ensure that we listen to the
// right document's view.
- if (HasResolver()) {
+ if (is_registered_for_lifecycle_notifications_) {
if (old_document.View())
old_document.View()->UnregisterFromLifecycleNotifications(this);
+
if (document_->View())
document_->View()->RegisterForLifecycleNotifications(this);
+ else
+ is_registered_for_lifecycle_notifications_ = false;
}
- if (!IsActivatable(DisplayLockActivationReason::kAny)) {
- old_document.RemoveActivationBlockingDisplayLock();
- document_->AddActivationBlockingDisplayLock();
- }
if (IsLocked()) {
old_document.RemoveLockedDisplayLock();
document_->AddLockedDisplayLock();
- }
-}
-
-void DisplayLockContext::WillStartLifecycleUpdate(const LocalFrameView& view) {
- if (update_budget_)
- update_budget_->OnLifecycleChange(view.CurrentLifecycleData());
-}
-
-void DisplayLockContext::DidFinishLifecycleUpdate(const LocalFrameView& view) {
- if (state_ == kCommitting) {
- FinishUpdateResolver(kResolve);
- state_ = kUnlocked;
- return;
- }
-
- if (state_ != kUpdating)
- return;
-
- // If we became disconnected for any reason, then we should reject the
- // update promise and go back to the locked state.
- if (!ConnectedToView()) {
- FinishUpdateResolver(kReject, rejection_names::kElementIsDisconnected);
- update_budget_.reset();
-
- if (state_ == kCommitting) {
- state_ = kUnlocked;
- } else {
- state_ = kLocked;
+ if (!IsActivatable(DisplayLockActivationReason::kAny)) {
+ old_document.DecrementDisplayLockBlockingAllActivation();
+ document_->IncrementDisplayLockBlockingAllActivation();
}
- return;
}
- if (update_budget_->NeedsLifecycleUpdates()) {
- // Note that we post a task to schedule an animation, since rAF requests can
- // be ignored if they happen from within a lifecycle update.
- GetExecutionContext()
- ->GetTaskRunner(TaskType::kMiscPlatformAPI)
- ->PostTask(FROM_HERE, WTF::Bind(&DisplayLockContext::ScheduleAnimation,
- WrapWeakPersistent(this)));
- return;
- }
+ DetermineIfSubtreeHasFocus();
+ DetermineIfSubtreeHasSelection();
+}
- FinishUpdateResolver(kResolve);
- update_budget_.reset();
- state_ = kLocked;
+void DisplayLockContext::WillStartLifecycleUpdate(const LocalFrameView& view) {
+ DCHECK(NeedsLifecycleNotifications());
+ // We might have delayed processing intersection observation update (signal
+ // that we were not intersecting) because this context was nested in another
+ // locked context. At the start of the lifecycle, we should check whether
+ // that is still true. In other words, this call will check if we're still
+ // nested. If we are, we won't do anything. If we're not, then we will lock
+ // this context.
+ //
+ // Note that when we are no longer nested and and we have not received any
+ // notifications from the intersection observer, it means that we are not
+ // visible.
+ if (needs_deferred_not_intersecting_signal_)
+ NotifyIsNotIntersectingViewport();
}
void DisplayLockContext::NotifyWillDisconnect() {
@@ -829,20 +787,14 @@ void DisplayLockContext::ElementDisconnected() {
void DisplayLockContext::ElementConnected() {
UpdateActivationObservationIfNeeded();
+ DetermineIfSubtreeHasFocus();
+ DetermineIfSubtreeHasSelection();
}
void DisplayLockContext::ScheduleAnimation() {
DCHECK(element_);
- // We could have posted a task to run ScheduleAnimation if we're updating.
- // However, before that task runs, we could have disconnected the element
- // already. If that's the case and we don't need to finalize update, then we
- // can skip scheduling animation. If we do need to finalize update (ie reset
- // update_budget_), then we should still schedule an animation just in case
- // one was not scheduled.
- if ((!ConnectedToView() && !update_budget_) || !document_ ||
- !document_->GetPage()) {
+ if (!ConnectedToView() || !document_ || !document_->GetPage())
return;
- }
// Schedule an animation to perform the lifecycle phases.
document_->GetPage()->Animator().ScheduleVisualUpdate(document_->GetFrame());
@@ -911,8 +863,7 @@ bool DisplayLockContext::ForceUnlockIfNeeded() {
// commit() isn't in progress, the web author won't know that the element
// got unlocked. Figure out how to notify the author.
if (auto* reason = ShouldForceUnlock()) {
- FinishUpdateResolver(kReject, reason);
- state_ = kUnlocked;
+ is_locked_ = false;
return true;
}
return false;
@@ -922,87 +873,125 @@ bool DisplayLockContext::ConnectedToView() const {
return element_ && document_ && element_->isConnected() && document_->View();
}
-// Scoped objects implementation
-// -----------------------------------------------
+void DisplayLockContext::NotifySubtreeLostFocus() {
+ SetRenderAffectingState(RenderAffectingState::kSubtreeHasFocus, false);
+}
-DisplayLockContext::ScopedForcedUpdate::ScopedForcedUpdate(
- DisplayLockContext* context)
- : context_(context) {}
+void DisplayLockContext::NotifySubtreeGainedFocus() {
+ SetRenderAffectingState(RenderAffectingState::kSubtreeHasFocus, true);
+}
-DisplayLockContext::ScopedForcedUpdate::ScopedForcedUpdate(
- ScopedForcedUpdate&& other)
- : context_(other.context_) {
- other.context_ = nullptr;
+void DisplayLockContext::DetermineIfSubtreeHasFocus() {
+ if (!ConnectedToView()) {
+ SetRenderAffectingState(RenderAffectingState::kSubtreeHasFocus, false);
+ return;
+ }
+
+ bool subtree_has_focus = false;
+ // Iterate up the ancestor chain from the currently focused element. If at any
+ // time we find our element, then our subtree is focused.
+ for (auto* focused = document_->FocusedElement(); focused;
+ focused = FlatTreeTraversal::ParentElement(*focused)) {
+ if (focused == element_.Get()) {
+ subtree_has_focus = true;
+ break;
+ }
+ }
+ SetRenderAffectingState(RenderAffectingState::kSubtreeHasFocus,
+ subtree_has_focus);
}
-DisplayLockContext::ScopedForcedUpdate::~ScopedForcedUpdate() {
- if (context_)
- context_->NotifyForcedUpdateScopeEnded();
+void DisplayLockContext::NotifySubtreeGainedSelection() {
+ SetRenderAffectingState(RenderAffectingState::kSubtreeHasSelection, true);
}
-// StateChangeHelper implementation
-// -----------------------------------------------
-DisplayLockContext::StateChangeHelper::StateChangeHelper(
- DisplayLockContext* context)
- : context_(context) {}
+void DisplayLockContext::NotifySubtreeLostSelection() {
+ SetRenderAffectingState(RenderAffectingState::kSubtreeHasSelection, false);
+}
-DisplayLockContext::StateChangeHelper& DisplayLockContext::StateChangeHelper::
-operator=(State new_state) {
- if (new_state == state_)
- return *this;
+void DisplayLockContext::DetermineIfSubtreeHasSelection() {
+ if (!ConnectedToView() || !document_->GetFrame()) {
+ SetRenderAffectingState(RenderAffectingState::kSubtreeHasSelection, false);
+ return;
+ }
- if (state_ == kUnlocked) {
- TRACE_EVENT_ASYNC_BEGIN0(
- TRACE_DISABLED_BY_DEFAULT("blink.debug.display_lock"),
- "LockedDisplayLock", this);
- } else if (new_state == kUnlocked) {
- TRACE_EVENT_ASYNC_END0(
- TRACE_DISABLED_BY_DEFAULT("blink.debug.display_lock"),
- "LockedDisplayLock", this);
+ auto range = ToEphemeralRangeInFlatTree(document_->GetFrame()
+ ->Selection()
+ .GetSelectionInDOMTree()
+ .ComputeRange());
+ bool subtree_has_selection = false;
+ for (auto& node : range.Nodes()) {
+ for (auto& ancestor : FlatTreeTraversal::InclusiveAncestorsOf(node)) {
+ if (&ancestor == element_.Get()) {
+ subtree_has_selection = true;
+ break;
+ }
+ }
+ if (subtree_has_selection)
+ break;
}
+ SetRenderAffectingState(RenderAffectingState::kSubtreeHasSelection,
+ subtree_has_selection);
+}
- bool was_activatable =
- context_->IsActivatable(DisplayLockActivationReason::kAny);
- bool was_locked = context_->IsLocked();
+void DisplayLockContext::SetRenderAffectingState(RenderAffectingState state,
+ bool new_flag) {
+ render_affecting_state_[static_cast<int>(state)] = new_flag;
+ NotifyRenderAffectingStateChanged();
+}
- state_ = new_state;
- if (state_ != kUnlocked) {
- TRACE_EVENT_ASYNC_STEP_INTO0(
- TRACE_DISABLED_BY_DEFAULT("blink.debug.display_lock"),
- "LockedDisplayLock", this, StateToString(state_));
- }
+void DisplayLockContext::NotifyRenderAffectingStateChanged() {
+ auto state = [this](RenderAffectingState state) {
+ return render_affecting_state_[static_cast<int>(state)];
+ };
- if (!context_->document_)
- return *this;
+ // Check that we're visible if and only if lock has not been requested.
+ DCHECK(state_ == ESubtreeVisibility::kVisible ||
+ state(RenderAffectingState::kLockRequested));
+ DCHECK(state_ != ESubtreeVisibility::kVisible ||
+ !state(RenderAffectingState::kLockRequested));
- UpdateActivationBlockingCount(
- was_activatable,
- context_->IsActivatable(DisplayLockActivationReason::kAny));
+ // We should be locked if the lock has been requested (the above DCHECKs
+ // verify that this means that we are not 'visible'), and any of the
+ // following is true:
+ // - We are not in 'auto' mode (meaning 'hidden') or
+ // - We are in 'auto' mode and nothing blocks locking: viewport is
+ // not intersecting, subtree doesn't have focus, and subtree doesn't have
+ // selection.
+ bool should_be_locked =
+ state(RenderAffectingState::kLockRequested) &&
+ (state_ != ESubtreeVisibility::kAuto ||
+ (!state(RenderAffectingState::kIntersectsViewport) &&
+ !state(RenderAffectingState::kSubtreeHasFocus) &&
+ !state(RenderAffectingState::kSubtreeHasSelection)));
- // Adjust the total number of locked display locks.
- auto& document = *context_->document_;
- if (context_->IsLocked() != was_locked) {
- if (was_locked)
- document.RemoveLockedDisplayLock();
- else
- document.AddLockedDisplayLock();
- }
+ if (should_be_locked && !IsLocked())
+ Lock();
+ else if (!should_be_locked && IsLocked())
+ Unlock();
+}
- context_->UpdateActivationObservationIfNeeded();
- return *this;
+void DisplayLockContext::Trace(Visitor* visitor) {
+ visitor->Trace(element_);
+ visitor->Trace(document_);
+ visitor->Trace(whitespace_reattach_set_);
}
-void DisplayLockContext::StateChangeHelper::UpdateActivationBlockingCount(
- bool old_activatable,
- bool new_activatable) {
- auto& document = *context_->document_;
- // Adjust activation blocking lock counts.
- if (old_activatable != new_activatable) {
- if (old_activatable)
- document.AddActivationBlockingDisplayLock();
- else
- document.RemoveActivationBlockingDisplayLock();
- }
+// Scoped objects implementation
+// -----------------------------------------------
+DisplayLockContext::ScopedForcedUpdate::ScopedForcedUpdate(
+ DisplayLockContext* context)
+ : context_(context) {}
+
+DisplayLockContext::ScopedForcedUpdate::ScopedForcedUpdate(
+ ScopedForcedUpdate&& other)
+ : context_(other.context_) {
+ other.context_ = nullptr;
+}
+
+DisplayLockContext::ScopedForcedUpdate::~ScopedForcedUpdate() {
+ if (context_)
+ context_->NotifyForcedUpdateScopeEnded();
}
} // 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 bd85935bae8..870b662ed60 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
@@ -5,18 +5,13 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DISPLAY_LOCK_DISPLAY_LOCK_CONTEXT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_DISPLAY_LOCK_DISPLAY_LOCK_CONTEXT_H_
-#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
-#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/display_lock/display_lock_budget.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
-#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
namespace blink {
-class DisplayLockSuspendedHandle;
class Element;
class DisplayLockScopedLogger;
class StyleRecalcChange;
@@ -45,7 +40,8 @@ enum class DisplayLockActivationReason {
// Shorthands
kViewport = static_cast<uint16_t>(kSelection) |
static_cast<uint16_t>(kUserFocus) |
- static_cast<uint16_t>(kViewportIntersection),
+ static_cast<uint16_t>(kViewportIntersection) |
+ static_cast<uint16_t>(kAccessibility),
kAny = static_cast<uint16_t>(kAccessibility) |
static_cast<uint16_t>(kFindInPage) |
static_cast<uint16_t>(kFragmentNavigation) |
@@ -64,47 +60,12 @@ static_assert(static_cast<uint32_t>(DisplayLockActivationReason::kAny) <
std::numeric_limits<uint16_t>::max(),
"DisplayLockActivationReason is too large");
-// Since we currently, and temporarily, support both CSS and attribute version,
-// we need to distinguish the two so that lack of CSS, for example, doesn't
-// unlock the attribute version and vice versa.
-enum class DisplayLockContextCreateMethod { kUnknown, kCSS, kAttribute };
-
class CORE_EXPORT DisplayLockContext final
: public GarbageCollected<DisplayLockContext>,
- public ContextLifecycleObserver,
public LocalFrameView::LifecycleNotificationObserver {
USING_GARBAGE_COLLECTED_MIXIN(DisplayLockContext);
- USING_PRE_FINALIZER(DisplayLockContext, Dispose);
public:
- // Determines what type of budget to use. This can be overridden via
- // DisplayLockContext::SetBudgetType().
- // - kDoNotYield:
- // This will effectively do all of the lifecycle phases when we're
- // committing. That is, this is the "no budget" option.
- // - kStrictYieldBetweenLifecyclePhases:
- // This type always yields between each lifecycle phase, even if that
- // phase was quick (note that it still skips phases that don't need any
- // updates).
- // - kYieldBetweenLifecyclePhases:
- // This type will only yield between lifecycle phases (not in the middle
- // of one). However, if there is sufficient time left (TODO(vmpstr):
- // define this), then it will continue on to the next lifecycle phase.
- enum class BudgetType {
- kDoNotYield,
- kStrictYieldBetweenLifecyclePhases,
- kYieldBetweenLifecyclePhases,
- kDefault = kYieldBetweenLifecyclePhases
- };
-
- // The current state of the lock. Note that the order of these matters.
- enum State {
- kLocked,
- kUpdating,
- kCommitting,
- kUnlocked,
- };
-
// The type of style that was blocked by this display lock.
enum StyleType {
kStyleUpdateNotRequired,
@@ -130,31 +91,18 @@ class CORE_EXPORT DisplayLockContext final
UntracedMember<DisplayLockContext> context_ = nullptr;
};
- DisplayLockContext(Element*, ExecutionContext*);
- ~DisplayLockContext();
+ explicit DisplayLockContext(Element*);
+ ~DisplayLockContext() = default;
- // GC functions.
- void Trace(blink::Visitor*) override;
- void Dispose();
-
- // ContextLifecycleObserver overrides.
- void ContextDestroyed(ExecutionContext*) override;
-
- // Set which reasons activate, as a mask of DisplayLockActivationReason enums.
- void SetActivatable(uint16_t activatable_mask);
-
- // Returns true if this lock has been activated and the activation has not yet
- // been cleared.
- bool IsActivated() const;
- // Clear the activated flag.
- void ClearActivated();
+ // Called by style to update the current state of subtree-visibility.
+ void SetRequestedState(ESubtreeVisibility state);
+ // Called by style to adjust the element's style based on the current state.
+ void AdjustElementStyle(ComputedStyle* style) const;
- // Acquire the lock, should only be called when unlocked.
- void StartAcquire();
- // Initiate a commit.
- void StartCommit();
- // Update rendering of the subtree.
- ScriptPromise UpdateRendering(ScriptState*);
+ // Is called by the intersection observer callback to inform us of the
+ // intersection state.
+ void NotifyIsIntersectingViewport();
+ void NotifyIsNotIntersectingViewport();
// Lifecycle observation / state functions.
bool ShouldStyle(DisplayLockLifecycleTarget) const;
@@ -182,17 +130,14 @@ class CORE_EXPORT DisplayLockContext final
// find-in-page, scrolling, etc.
// This issues a before activate signal with the given element as the
// activated element.
- void CommitForActivationWithSignal(Element* activated_element);
+ // The reason is specified for metrics.
+ void CommitForActivationWithSignal(Element* activated_element,
+ DisplayLockActivationReason reason);
bool ShouldCommitForActivation(DisplayLockActivationReason reason) const;
- // Returns true if this lock is locked. Note from the outside perspective, the
- // lock is locked any time the state is not kUnlocked or kCommitting.
- bool IsLocked() const { return state_ != kUnlocked && state_ != kCommitting; }
-
- // Called when the layout tree is attached. This is used to verify
- // containment.
- void DidAttachLayoutTree();
+ // Returns true if this context is locked.
+ bool IsLocked() const { return is_locked_; }
// Returns a ScopedForcedUpdate object which for the duration of its lifetime
// will allow updates to happen on this element's subtree. For the element
@@ -212,7 +157,6 @@ class CORE_EXPORT DisplayLockContext final
// LifecycleNotificationObserver overrides.
void WillStartLifecycleUpdate(const LocalFrameView&) override;
- void DidFinishLifecycleUpdate(const LocalFrameView&) override;
// Inform the display lock that it prevented a style change. This is used to
// invalidate style when we need to update it in the future.
@@ -244,6 +188,12 @@ class CORE_EXPORT DisplayLockContext final
void ElementDisconnected();
void ElementConnected();
+ void NotifySubtreeLostFocus();
+ void NotifySubtreeGainedFocus();
+
+ void NotifySubtreeLostSelection();
+ void NotifySubtreeGainedSelection();
+
void SetNeedsPrePaintSubtreeWalk(
bool needs_effective_allowed_touch_action_update) {
needs_effective_allowed_touch_action_update_ =
@@ -251,50 +201,47 @@ class CORE_EXPORT DisplayLockContext final
needs_prepaint_subtree_walk_ = true;
}
- void SetMethod(DisplayLockContextCreateMethod method) { method_ = method; }
- DisplayLockContextCreateMethod GetMethod() const {
- DCHECK(method_ != DisplayLockContextCreateMethod::kUnknown);
- return method_;
- }
-
- // Note that this returns true if there is no context at all, so in order to
- // check whether this is strictly an attribute version, as opposed to a null
- // context, one needs to compare context with nullptr first.
- static bool IsAttributeVersion(DisplayLockContext* context) {
- return !context ||
- context->GetMethod() == DisplayLockContextCreateMethod::kAttribute;
- }
-
// This is called by the style recalc code in lieu of
// MarkForStyleRecalcIfNeeded() in order to adjust the child change if we need
// to recalc children nodes here.
StyleRecalcChange AdjustStyleRecalcChangeForChildren(
StyleRecalcChange change);
- private:
- friend class DisplayLockContextTest;
- friend class DisplayLockBudgetTest;
- friend class DisplayLockSuspendedHandle;
- friend class DisplayLockBudget;
+ void DidForceActivatableDisplayLocks() {
+ if (IsLocked() && IsActivatable(DisplayLockActivationReason::kAny)) {
+ MarkForStyleRecalcIfNeeded();
+ MarkForLayoutIfNeeded();
+ }
+ }
- class StateChangeHelper {
- DISALLOW_NEW();
+ // GC functions.
+ void Trace(Visitor*) override;
- public:
- explicit StateChangeHelper(DisplayLockContext*);
+ private:
+ // Test friends.
+ friend class DisplayLockContextRenderingTest;
+ friend class DisplayLockContextTest;
- operator State() const { return state_; }
- StateChangeHelper& operator=(State);
- void UpdateActivationBlockingCount(bool old_activatable,
- bool new_activatable);
+ // Request that this context be locked. Called when style determines that the
+ // subtree rooted at this element should be skipped, unless things like
+ // viewport intersection prevent it from doing so.
+ void RequestLock(uint16_t activation_mask);
+ // Request that this context be unlocked. Called when style determines that
+ // the subtree rooted at this element should be rendered.
+ void RequestUnlock();
+
+ // Records the locked context counts on the document as well as context that
+ // block all activation.
+ void UpdateDocumentBookkeeping(bool was_locked,
+ bool all_activation_was_blocked,
+ bool is_locked,
+ bool all_activation_is_blocked);
- private:
- State state_ = kUnlocked;
- UntracedMember<DisplayLockContext> context_;
- };
+ // Set which reasons activate, as a mask of DisplayLockActivationReason enums.
+ void UpdateActivationMask(uint16_t activatable_mask);
- // Initiate an update.
- void StartUpdateIfNeeded();
+ // Clear the activated flag.
+ void ResetActivation();
// Marks ancestors of elements in |whitespace_reattach_set_| with
// ChildNeedsReattachLayoutTree and clears the set.
@@ -318,26 +265,10 @@ class CORE_EXPORT DisplayLockContext final
// GetScopedForcedUpdate() for more information.
void NotifyForcedUpdateScopeEnded();
- // Creates a new update budget based on the BudgetType::kDefault enum. In
- // other words, it will create a budget of that type.
- // TODO(vmpstr): In tests, we will probably switch the value to test other
- // budgets. As well, this makes it easier to change the budget right in the
- // enum definitions.
- std::unique_ptr<DisplayLockBudget> CreateNewBudget();
-
// Helper to schedule an animation to delay lifecycle updates for the next
// frame.
void ScheduleAnimation();
- // Helper functions to resolve the update/commit promises.
- enum ResolverState { kResolve, kReject, kDetach };
- void MakeResolver(ScriptState*, Member<ScriptPromiseResolver>*);
- bool HasResolver();
- void FinishUpdateResolver(ResolverState, const char* reject_reason = nullptr);
- void FinishResolver(Member<ScriptPromiseResolver>*,
- ResolverState,
- const char* reject_reason);
-
// Checks whether we should force unlock the lock (due to not meeting
// containment/display requirements), returns a string from rejection_names
// if we should, nullptr if not. Note that this can only be called if the
@@ -355,12 +286,6 @@ class CORE_EXPORT DisplayLockContext final
// when acquiring this lock should immediately resolve the acquire promise.
bool ConnectedToView() const;
- bool ShouldPerformUpdatePhase(DisplayLockBudget::Phase phase) const;
-
- // During an attempt to commit, clean up state and reject pending resolver
- // promises if the lock is not connected to the tree.
- bool CleanupAndRejectCommitIfNotConnected();
-
// Registers or unregisters the element for intersection observations in the
// document. This is used to activate on visibily changes. This can be safely
// called even if changes are not required, since it will only act if a
@@ -371,11 +296,28 @@ class CORE_EXPORT DisplayLockContext final
// Scheduled by CommitForActivationWithSignal.
void FireActivationEvent(Element* activated_element);
- std::unique_ptr<DisplayLockBudget> update_budget_;
+ // Determines whether or not we need lifecycle notifications.
+ bool NeedsLifecycleNotifications() const;
+ // Updates the lifecycle notification registration based on whether we need
+ // the notifications.
+ void UpdateLifecycleNotificationRegistration();
+
+ // Locks the context.
+ void Lock();
+ // Unlocks the context.
+ void Unlock();
+
+ // Determines if the subtree has focus. This is a linear walk from the focused
+ // element to its root element.
+ void DetermineIfSubtreeHasFocus();
+
+ // Determines if the subtree has selection. This will walk from each of the
+ // selected notes up to its root looking for `element_`.
+ void DetermineIfSubtreeHasSelection();
- Member<ScriptPromiseResolver> update_resolver_;
WeakMember<Element> element_;
WeakMember<Document> document_;
+ ESubtreeVisibility state_ = ESubtreeVisibility::kVisible;
// See StyleEngine's |whitespace_reattach_set_|.
// Set of elements that had at least one rendered children removed
@@ -386,8 +328,6 @@ class CORE_EXPORT DisplayLockContext final
// style recalc on them.
HeapHashSet<Member<Element>> whitespace_reattach_set_;
- StateChangeHelper state_;
-
bool update_forced_ = false;
StyleType blocked_style_traversal_type_ = kStyleUpdateNotRequired;
@@ -398,7 +338,6 @@ class CORE_EXPORT DisplayLockContext final
bool needs_effective_allowed_touch_action_update_ = false;
bool needs_prepaint_subtree_walk_ = false;
- bool is_horizontal_writing_mode_ = true;
bool needs_graphics_layer_collection_ = false;
bool needs_compositing_requirements_update_ = false;
@@ -415,11 +354,33 @@ class CORE_EXPORT DisplayLockContext final
uint16_t activatable_mask_ =
static_cast<uint16_t>(DisplayLockActivationReason::kAny);
- bool is_activated_ = false;
+ // Is set to true if we are registered for lifecycle notifications.
+ bool is_registered_for_lifecycle_notifications_ = false;
+
+ // This is set to true when we have delayed locking ourselves due to viewport
+ // intersection (or lack thereof) because we were nested in a locked subtree.
+ // In that case, we register for lifecycle notifications and check every time
+ // if we are still nested.
+ bool needs_deferred_not_intersecting_signal_ = false;
+
+ // Lock has been requested.
+ bool is_locked_ = false;
+
+ enum class RenderAffectingState : int {
+ kLockRequested,
+ kIntersectsViewport,
+ kSubtreeHasFocus,
+ kSubtreeHasSelection,
+ kNumRenderAffectingStates
+ };
+ void SetRenderAffectingState(RenderAffectingState state, bool flag);
+ void NotifyRenderAffectingStateChanged();
- DisplayLockContextCreateMethod method_ =
- DisplayLockContextCreateMethod::kUnknown;
+ bool render_affecting_state_[static_cast<int>(
+ RenderAffectingState::kNumRenderAffectingStates)] = {false};
+ // TODO(vmpstr): This is only needed while we're still sending activation
+ // events.
base::WeakPtrFactory<DisplayLockContext> weak_factory_{this};
};
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 95b1854f265..bb877c91f75 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
@@ -7,16 +7,17 @@
#include <memory>
#include <utility>
+#include "base/memory/ptr_util.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/core/css/style_change_reason.h"
-#include "third_party/blink/renderer/core/display_lock/strict_yielding_display_lock_budget.h"
#include "third_party/blink/renderer/core/dom/dom_token_list.h"
#include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/editing/ephemeral_range.h"
#include "third_party/blink/renderer/core/editing/finder/text_finder.h"
+#include "third_party/blink/renderer/core/editing/markers/document_marker_controller.h"
#include "third_party/blink/renderer/core/editing/visible_units.h"
#include "third_party/blink/renderer/core/frame/find_in_page.h"
#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
@@ -50,10 +51,10 @@ class DisplayLockTestFindInPageClient : public mojom::blink::FindInPageClient {
}
void SetActiveMatch(int request_id,
- const WebRect& active_match_rect,
+ const gfx::Rect& active_match_rect,
int active_match_ordinal,
mojom::blink::FindMatchUpdateType final_update) final {
- active_match_rect_ = active_match_rect;
+ active_match_rect_ = IntRect(active_match_rect);
active_index_ = active_match_ordinal;
find_results_are_ready_ =
(final_update == mojom::blink::FindMatchUpdateType::kFinalUpdate);
@@ -87,9 +88,9 @@ class DisplayLockEmptyEventListener final : public NativeEventListener {
} // namespace
class DisplayLockContextTest : public testing::Test,
- private ScopedDisplayLockingForTest {
+ private ScopedCSSSubtreeVisibilityHiddenMatchableForTest {
public:
- DisplayLockContextTest() : ScopedDisplayLockingForTest(true) {}
+ DisplayLockContextTest() : ScopedCSSSubtreeVisibilityHiddenMatchableForTest(true) {}
void SetUp() override {
web_view_helper_.Initialize();
@@ -111,13 +112,11 @@ class DisplayLockContextTest : public testing::Test,
}
void UpdateAllLifecyclePhasesForTest() {
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
}
void SetHtmlInnerHTML(const char* content) {
- GetDocument().documentElement()->SetInnerHTMLFromString(
- String::FromUTF8(content));
+ GetDocument().documentElement()->setInnerHTML(String::FromUTF8(content));
UpdateAllLifecyclePhasesForTest();
}
@@ -127,25 +126,25 @@ class DisplayLockContextTest : public testing::Test,
test::RunPendingTasks();
}
- void LockElement(Element& element,
- bool activatable,
- bool update_lifecycle = true) {
+ void LockElement(Element& element, bool activatable) {
StringBuilder value;
- value.Append("invisible");
- if (!activatable)
- value.Append(" skip-activation");
- element.setAttribute(html_names::kRendersubtreeAttr,
- value.ToAtomicString());
- if (update_lifecycle)
- UpdateAllLifecyclePhasesForTest();
+ value.Append("subtree-visibility: hidden");
+ if (activatable)
+ value.Append("-matchable");
+ element.setAttribute(html_names::kStyleAttr, value.ToAtomicString());
+ UpdateAllLifecyclePhasesForTest();
}
void CommitElement(Element& element, bool update_lifecycle = true) {
- element.setAttribute(html_names::kRendersubtreeAttr, "");
+ element.setAttribute(html_names::kStyleAttr, "");
if (update_lifecycle)
UpdateAllLifecyclePhasesForTest();
}
+ void UnlockImmediate(DisplayLockContext* context) {
+ context->SetRequestedState(ESubtreeVisibility::kVisible);
+ }
+
bool GraphicsLayerNeedsCollection(DisplayLockContext* context) const {
return context->needs_graphics_layer_collection_;
}
@@ -166,12 +165,6 @@ class DisplayLockContextTest : public testing::Test,
test::RunPendingTasks();
}
- void ResetBudget(std::unique_ptr<DisplayLockBudget> budget,
- DisplayLockContext* context) {
- ASSERT_TRUE(context->update_budget_);
- context->update_budget_ = std::move(budget);
- }
-
bool ReattachWasBlocked(DisplayLockContext* context) {
return context->reattach_layout_tree_was_blocked_;
}
@@ -195,7 +188,7 @@ TEST_F(DisplayLockContextTest, LockAfterAppendStyleDirtyBits) {
)HTML");
auto* element = GetDocument().getElementById("container");
- LockElement(*element, false, false);
+ LockElement(*element, false);
// Finished acquiring the lock.
// Note that because the element is locked after append, the "self" phase for
@@ -211,7 +204,9 @@ TEST_F(DisplayLockContextTest, LockAfterAppendStyleDirtyBits) {
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 1);
// If the element is dirty, style recalc would handle it in the next recalc.
- element->setAttribute("style", "color: red;");
+ element->setAttribute(
+ html_names::kStyleAttr,
+ "subtree-visibility: hidden; color: red;");
EXPECT_TRUE(GetDocument().body()->ChildNeedsStyleRecalc());
EXPECT_TRUE(element->NeedsStyleRecalc());
EXPECT_FALSE(element->ChildNeedsStyleRecalc());
@@ -223,7 +218,11 @@ TEST_F(DisplayLockContextTest, LockAfterAppendStyleDirtyBits) {
EXPECT_EQ(
element->GetComputedStyle()->VisitedDependentColor(GetCSSPropertyColor()),
MakeRGB(255, 0, 0));
- CommitElement(*element, false);
+ // Manually commit the lock so that we can verify which dirty bits get
+ // propagated.
+ UnlockImmediate(element->GetDisplayLockContext());
+ element->setAttribute(html_names::kStyleAttr, "color: red;");
+
auto* child = GetDocument().getElementById("child");
EXPECT_TRUE(GetDocument().body()->ChildNeedsStyleRecalc());
EXPECT_TRUE(element->NeedsStyleRecalc());
@@ -236,32 +235,25 @@ TEST_F(DisplayLockContextTest, LockAfterAppendStyleDirtyBits) {
EXPECT_FALSE(element->ChildNeedsStyleRecalc());
EXPECT_FALSE(child->NeedsStyleRecalc());
- // Re-acquire.
- LockElement(*element, false);
-
- // If a child is dirty, it will still be dirty.
- child->setAttribute("style", "color: blue;");
- EXPECT_FALSE(GetDocument().body()->ChildNeedsStyleRecalc());
- EXPECT_FALSE(element->NeedsStyleRecalc());
- EXPECT_TRUE(element->ChildNeedsStyleRecalc());
- EXPECT_TRUE(child->NeedsStyleRecalc());
- EXPECT_FALSE(child->ChildNeedsStyleRecalc());
-
+ // Lock the child.
+ child->setAttribute(
+ html_names::kStyleAttr,
+ "subtree-visibility: hidden; color: blue;");
UpdateAllLifecyclePhasesForTest();
+
EXPECT_FALSE(GetDocument().body()->ChildNeedsStyleRecalc());
EXPECT_FALSE(element->NeedsStyleRecalc());
- EXPECT_TRUE(element->ChildNeedsStyleRecalc());
- EXPECT_TRUE(child->NeedsStyleRecalc());
+ EXPECT_FALSE(element->ChildNeedsStyleRecalc());
+ EXPECT_FALSE(child->NeedsStyleRecalc());
ASSERT_TRUE(child->GetComputedStyle());
- EXPECT_NE(
+ EXPECT_EQ(
child->GetComputedStyle()->VisitedDependentColor(GetCSSPropertyColor()),
MakeRGB(0, 0, 255));
- CommitElement(*element, false);
+ UnlockImmediate(child->GetDisplayLockContext());
+ child->setAttribute(html_names::kStyleAttr, "color: blue;");
EXPECT_TRUE(GetDocument().body()->ChildNeedsStyleRecalc());
- // Since the rendersubtree attribute changes, it will force self style to put
- // in proper containment in place.
- EXPECT_TRUE(element->NeedsStyleRecalc());
+ EXPECT_FALSE(element->NeedsStyleRecalc());
EXPECT_TRUE(element->ChildNeedsStyleRecalc());
EXPECT_TRUE(child->NeedsStyleRecalc());
UpdateAllLifecyclePhasesForTest();
@@ -309,13 +301,16 @@ TEST_F(DisplayLockContextTest,
ResizeAndFocus();
SetHtmlInnerHTML(R"HTML(
<style>
+ .spacer {
+ height: 10000px;
+ }
#container {
width: 100px;
height: 100px;
contain: style layout paint;
}
</style>
- <body><div id="container">testing</div></body>
+ <body><div class=spacer></div><div id="container">testing</div></body>
)HTML");
const String search_text = "testing";
@@ -336,7 +331,120 @@ TEST_F(DisplayLockContextTest,
// Check if we can still get the same result with the same query.
Find(search_text, client);
EXPECT_EQ(1, client.Count());
- EXPECT_FALSE(container->GetDisplayLockContext()->IsLocked());
+ EXPECT_TRUE(container->GetDisplayLockContext()->IsLocked());
+ EXPECT_GT(GetDocument().scrollingElement()->scrollTop(), 1000);
+}
+
+TEST_F(DisplayLockContextTest,
+ ActivatableLockedElementTickmarksAreAtLockedRoots) {
+ ResizeAndFocus();
+ SetHtmlInnerHTML(R"HTML(
+ <style>
+ body {
+ margin: 0;
+ padding: 0;
+ }
+ .small {
+ width: 100px;
+ height: 100px;
+ }
+ .medium {
+ width: 150px;
+ height: 150px;
+ }
+ .large {
+ width: 200px;
+ height: 200px;
+ }
+ </style>
+ <body>
+ testing
+ <div id="container1" class=small>testing</div>
+ <div id="container2" class=medium>testing</div>
+ <div id="container3" class=large>
+ <div id="container4" class=medium>testing</div>
+ </div>
+ <div id="container5" class=small>testing</div>
+ </body>
+ )HTML");
+
+ const String search_text = "testing";
+ DisplayLockTestFindInPageClient client;
+ client.SetFrame(LocalMainFrame());
+
+ auto* container1 = GetDocument().getElementById("container1");
+ auto* container2 = GetDocument().getElementById("container2");
+ auto* container3 = GetDocument().getElementById("container3");
+ auto* container4 = GetDocument().getElementById("container4");
+ auto* container5 = GetDocument().getElementById("container5");
+ LockElement(*container5, false /* activatable */);
+ LockElement(*container4, true /* activatable */);
+ LockElement(*container3, true /* activatable */);
+ LockElement(*container2, true /* activatable */);
+ LockElement(*container1, true /* activatable */);
+
+ EXPECT_TRUE(container1->GetDisplayLockContext()->IsLocked());
+ EXPECT_TRUE(container2->GetDisplayLockContext()->IsLocked());
+ EXPECT_TRUE(container3->GetDisplayLockContext()->IsLocked());
+ EXPECT_TRUE(container4->GetDisplayLockContext()->IsLocked());
+ EXPECT_TRUE(container5->GetDisplayLockContext()->IsLocked());
+
+ // Do a find-in-page.
+ Find(search_text, client);
+ // "testing" outside of the container divs, and 3 inside activatable divs.
+ EXPECT_EQ(4, client.Count());
+
+ auto tick_rects = GetDocument().Markers().LayoutRectsForTextMatchMarkers();
+ ASSERT_EQ(4u, tick_rects.size());
+
+ // Sort the layout rects by y coordinate for deterministic checks below.
+ std::sort(tick_rects.begin(), tick_rects.end(),
+ [](const IntRect& a, const IntRect& b) { return a.Y() < b.Y(); });
+
+ int y_offset = tick_rects[0].Height();
+
+ // The first tick rect will be based on the text itself, so we don't need to
+ // check that. The next three should be the small, medium and large rects,
+ // since those are the locked roots.
+ EXPECT_EQ(IntRect(0, y_offset, 100, 100), tick_rects[1]);
+ y_offset += tick_rects[1].Height();
+ EXPECT_EQ(IntRect(0, y_offset, 150, 150), tick_rects[2]);
+ y_offset += tick_rects[2].Height();
+ EXPECT_EQ(IntRect(0, y_offset, 200, 200), tick_rects[3]);
+}
+
+TEST_F(DisplayLockContextTest,
+ FindInPageWhileLockedContentChangesDoesNotCrash) {
+ ResizeAndFocus();
+ SetHtmlInnerHTML(R"HTML(
+ <style>
+ #container {
+ width: 100px;
+ height: 100px;
+ contain: style layout paint;
+ }
+ </style>
+ <body>testing<div id="container">testing</div></body>
+ )HTML");
+
+ const String search_text = "testing";
+ DisplayLockTestFindInPageClient client;
+ client.SetFrame(LocalMainFrame());
+
+ // Lock the container.
+ auto* container = GetDocument().getElementById("container");
+ LockElement(*container, true /* activatable */);
+ EXPECT_TRUE(container->GetDisplayLockContext()->IsLocked());
+
+ // Find the first "testing", container still locked since the match is outside
+ // the container.
+ Find(search_text, client);
+ EXPECT_EQ(2, client.Count());
+ EXPECT_TRUE(container->GetDisplayLockContext()->IsLocked());
+
+ // Change the inner text, this should not DCHECK.
+ container->setInnerHTML("please don't DCHECK");
+ UpdateAllLifecyclePhasesForTest();
}
TEST_F(DisplayLockContextTest, FindInPageWithChangedContent) {
@@ -358,7 +466,7 @@ TEST_F(DisplayLockContextTest, FindInPageWithChangedContent) {
auto* container = GetDocument().getElementById("container");
LockElement(*container, true /* activatable */);
EXPECT_TRUE(container->GetDisplayLockContext()->IsLocked());
- container->SetInnerHTMLFromString(
+ container->setInnerHTML(
"testing"
"<div>testing</div>"
"tes<div style='display:none;'>x</div>ting");
@@ -367,7 +475,7 @@ TEST_F(DisplayLockContextTest, FindInPageWithChangedContent) {
client.SetFrame(LocalMainFrame());
Find("testing", client);
EXPECT_EQ(3, client.Count());
- EXPECT_FALSE(container->GetDisplayLockContext()->IsLocked());
+ EXPECT_TRUE(container->GetDisplayLockContext()->IsLocked());
}
TEST_F(DisplayLockContextTest, FindInPageWithNoMatchesWontUnlock) {
@@ -444,18 +552,14 @@ TEST_F(DisplayLockContextTest,
EXPECT_EQ(2, client.Count());
EXPECT_EQ(1, client.ActiveIndex());
- // #container should be unlocked, since the match is inside that
- // element ("testing1" inside the div).
- EXPECT_FALSE(container->GetDisplayLockContext()->IsLocked());
- // Since the active match isn't located within other locked elements
- // they need to stay locked.
+ EXPECT_TRUE(container->GetDisplayLockContext()->IsLocked());
EXPECT_TRUE(activatable->GetDisplayLockContext()->IsLocked());
EXPECT_TRUE(non_activatable->GetDisplayLockContext()->IsLocked());
EXPECT_TRUE(nested_non_activatable->GetDisplayLockContext()->IsLocked());
}
TEST_F(DisplayLockContextTest,
- NestedActivatableLockedElementIsUnlockedByFindInPage) {
+ NestedActivatableLockedElementIsNotUnlockedByFindInPage) {
ResizeAndFocus();
SetHtmlInnerHTML(R"HTML(
<body>
@@ -484,8 +588,8 @@ TEST_F(DisplayLockContextTest,
EXPECT_EQ(1, client.Count());
EXPECT_EQ(1, client.ActiveIndex());
- EXPECT_FALSE(container->GetDisplayLockContext()->IsLocked());
- EXPECT_FALSE(child->GetDisplayLockContext()->IsLocked());
+ EXPECT_TRUE(container->GetDisplayLockContext()->IsLocked());
+ EXPECT_TRUE(child->GetDisplayLockContext()->IsLocked());
}
TEST_F(DisplayLockContextTest,
@@ -512,8 +616,8 @@ TEST_F(DisplayLockContextTest,
auto* div_two = GetDocument().getElementById("two");
auto* div_three = GetDocument().getElementById("three");
// Lock three divs, make #div_two non-activatable.
- LockElement(*div_one, true /* activatable */, false /* update_lifecycle */);
- LockElement(*div_two, false /* activatable */, false /* update_lifecycle */);
+ LockElement(*div_one, true /* activatable */);
+ LockElement(*div_two, false /* activatable */);
LockElement(*div_three, true /* activatable */);
DisplayLockTestFindInPageClient client;
@@ -529,12 +633,16 @@ TEST_F(DisplayLockContextTest,
EXPECT_EQ(2, client.Count());
EXPECT_EQ(1, client.ActiveIndex());
EXPECT_EQ(text_rect(div_one), client.ActiveMatchRect());
+ // Pretend that the event unlocked the element.
+ CommitElement(*div_one);
// Going forward from #one would go to #three.
Find(search_text, client, true /* find_next */);
EXPECT_EQ(2, client.Count());
EXPECT_EQ(2, client.ActiveIndex());
EXPECT_EQ(text_rect(div_three), client.ActiveMatchRect());
+ // Pretend that the event unlocked the element.
+ CommitElement(*div_three);
// Going backwards from #three would go to #one.
client.Reset();
@@ -563,6 +671,7 @@ TEST_F(DisplayLockContextTest, CallUpdateStyleAndLayoutAfterChange) {
LockElement(*element, false);
// Sanity checks to ensure the element is locked.
+ EXPECT_TRUE(element->GetDisplayLockContext()->IsLocked());
EXPECT_FALSE(element->GetDisplayLockContext()->ShouldStyle(
DisplayLockLifecycleTarget::kChildren));
EXPECT_FALSE(element->GetDisplayLockContext()->ShouldLayout(
@@ -570,7 +679,7 @@ TEST_F(DisplayLockContextTest, CallUpdateStyleAndLayoutAfterChange) {
EXPECT_FALSE(element->GetDisplayLockContext()->ShouldPaint(
DisplayLockLifecycleTarget::kChildren));
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 1);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 1);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 1);
EXPECT_FALSE(element->NeedsStyleRecalc());
EXPECT_FALSE(element->ChildNeedsStyleRecalc());
@@ -585,7 +694,7 @@ TEST_F(DisplayLockContextTest, CallUpdateStyleAndLayoutAfterChange) {
EXPECT_FALSE(element->NeedsReattachLayoutTree());
EXPECT_FALSE(element->ChildNeedsReattachLayoutTree());
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_FALSE(element->NeedsStyleRecalc());
EXPECT_FALSE(element->ChildNeedsStyleRecalc());
@@ -593,23 +702,23 @@ TEST_F(DisplayLockContextTest, CallUpdateStyleAndLayoutAfterChange) {
EXPECT_FALSE(element->ChildNeedsReattachLayoutTree());
// Testing whitespace reattachment + dirty style.
- element->SetInnerHTMLFromString("<div>something</div>");
+ element->setInnerHTML("<div>something</div>");
EXPECT_FALSE(element->NeedsStyleRecalc());
EXPECT_TRUE(element->ChildNeedsStyleRecalc());
EXPECT_FALSE(element->NeedsReattachLayoutTree());
EXPECT_FALSE(element->ChildNeedsReattachLayoutTree());
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_FALSE(element->NeedsStyleRecalc());
EXPECT_TRUE(element->ChildNeedsStyleRecalc());
EXPECT_FALSE(element->NeedsReattachLayoutTree());
EXPECT_FALSE(element->ChildNeedsReattachLayoutTree());
- CommitElement(*element, false);
- // Since containment may change, we need self style recalc.
- EXPECT_TRUE(element->NeedsStyleRecalc());
+ // Manually start commit, so that we can verify which dirty bits get
+ // propagated.
+ UnlockImmediate(element->GetDisplayLockContext());
EXPECT_TRUE(element->ChildNeedsStyleRecalc());
EXPECT_FALSE(element->NeedsReattachLayoutTree());
EXPECT_FALSE(element->ChildNeedsReattachLayoutTree());
@@ -620,8 +729,6 @@ TEST_F(DisplayLockContextTest, CallUpdateStyleAndLayoutAfterChange) {
element->GetDisplayLockContext()->DidStyle(
DisplayLockLifecycleTarget::kChildren);
- // Self style still needs updating.
- EXPECT_TRUE(element->NeedsStyleRecalc());
EXPECT_FALSE(element->ChildNeedsStyleRecalc());
EXPECT_FALSE(element->NeedsReattachLayoutTree());
EXPECT_TRUE(element->ChildNeedsReattachLayoutTree());
@@ -640,7 +747,7 @@ TEST_F(DisplayLockContextTest, CallUpdateStyleAndLayoutAfterChangeCSS) {
background: blue;
}
.locked {
- render-subtree: invisible skip-activation;
+ subtree-visibility: hidden;
}
</style>
<body><div class=locked id="container"><b>t</b>esting<div id=inner></div></div></body>
@@ -656,7 +763,7 @@ TEST_F(DisplayLockContextTest, CallUpdateStyleAndLayoutAfterChangeCSS) {
EXPECT_FALSE(element->GetDisplayLockContext()->ShouldPaint(
DisplayLockLifecycleTarget::kChildren));
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 1);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 1);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 1);
EXPECT_TRUE(ReattachWasBlocked(element->GetDisplayLockContext()));
// Note that we didn't create a layout object for inner, since the layout tree
@@ -708,7 +815,7 @@ TEST_F(DisplayLockContextTest, LockedElementAndDescendantsAreNotFocusable) {
ASSERT_TRUE(GetDocument().getElementById("textfield")->IsMouseFocusable());
ASSERT_TRUE(GetDocument().getElementById("textfield")->IsFocusable());
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 0);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 0);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 0);
auto* element = GetDocument().getElementById("container");
LockElement(*element, false);
@@ -721,7 +828,7 @@ TEST_F(DisplayLockContextTest, LockedElementAndDescendantsAreNotFocusable) {
EXPECT_FALSE(element->GetDisplayLockContext()->ShouldPaint(
DisplayLockLifecycleTarget::kChildren));
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 1);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 1);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 1);
// The input should not be focusable now.
EXPECT_FALSE(
@@ -734,7 +841,7 @@ TEST_F(DisplayLockContextTest, LockedElementAndDescendantsAreNotFocusable) {
EXPECT_FALSE(GetDocument().FocusedElement());
// Now commit the lock and ensure we can focus the input
- CommitElement(*element, false);
+ CommitElement(*element);
EXPECT_TRUE(element->GetDisplayLockContext()->ShouldStyle(
DisplayLockLifecycleTarget::kChildren));
@@ -746,7 +853,7 @@ TEST_F(DisplayLockContextTest, LockedElementAndDescendantsAreNotFocusable) {
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 0);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 0);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 0);
EXPECT_TRUE(GetDocument().getElementById("textfield")->IsKeyboardFocusable());
EXPECT_TRUE(GetDocument().getElementById("textfield")->IsMouseFocusable());
EXPECT_TRUE(GetDocument().getElementById("textfield")->IsFocusable());
@@ -777,7 +884,7 @@ TEST_F(DisplayLockContextTest, DisplayLockPreventsActivation) {
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString(
+ shadow_root.setInnerHTML(
"<div id='container' style='contain:style layout "
"paint;'><slot></slot></div>");
UpdateAllLifecyclePhasesForTest();
@@ -790,10 +897,10 @@ TEST_F(DisplayLockContextTest, DisplayLockPreventsActivation) {
EXPECT_FALSE(slotted->DisplayLockPreventsActivation(
DisplayLockActivationReason::kAny));
- LockElement(*container, false, false);
+ LockElement(*container, false);
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 1);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 1);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 1);
EXPECT_FALSE(
host->DisplayLockPreventsActivation(DisplayLockActivationReason::kAny));
EXPECT_TRUE(container->DisplayLockPreventsActivation(
@@ -805,10 +912,10 @@ TEST_F(DisplayLockContextTest, DisplayLockPreventsActivation) {
// step.
UpdateAllLifecyclePhasesForTest();
- CommitElement(*container, false);
+ CommitElement(*container);
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 0);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 0);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 0);
EXPECT_FALSE(
host->DisplayLockPreventsActivation(DisplayLockActivationReason::kAny));
EXPECT_FALSE(container->DisplayLockPreventsActivation(
@@ -819,13 +926,31 @@ TEST_F(DisplayLockContextTest, DisplayLockPreventsActivation) {
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 0);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 0);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 0);
EXPECT_FALSE(
host->DisplayLockPreventsActivation(DisplayLockActivationReason::kAny));
EXPECT_FALSE(container->DisplayLockPreventsActivation(
DisplayLockActivationReason::kAny));
EXPECT_FALSE(slotted->DisplayLockPreventsActivation(
DisplayLockActivationReason::kAny));
+
+ SetHtmlInnerHTML(R"HTML(
+ <body>
+ <div id="nonviewport" style="subtree-visibility: hidden-matchable">
+ </div>
+ </body>
+ )HTML");
+ auto* non_viewport = GetDocument().getElementById("nonviewport");
+
+ EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 1);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 0);
+
+ EXPECT_FALSE(non_viewport->DisplayLockPreventsActivation(
+ DisplayLockActivationReason::kAny));
+ EXPECT_FALSE(non_viewport->DisplayLockPreventsActivation(
+ DisplayLockActivationReason::kFindInPage));
+ EXPECT_TRUE(non_viewport->DisplayLockPreventsActivation(
+ DisplayLockActivationReason::kUserFocus));
}
TEST_F(DisplayLockContextTest,
@@ -843,7 +968,7 @@ TEST_F(DisplayLockContextTest,
auto* text_field = GetDocument().getElementById("textfield");
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString(
+ shadow_root.setInnerHTML(
"<div id='container' style='contain:style layout "
"paint;'><slot></slot></div>");
@@ -863,7 +988,7 @@ TEST_F(DisplayLockContextTest,
EXPECT_FALSE(element->GetDisplayLockContext()->ShouldPaint(
DisplayLockLifecycleTarget::kChildren));
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 1);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 1);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 1);
// The input should not be focusable now.
EXPECT_FALSE(text_field->IsKeyboardFocusable());
@@ -894,7 +1019,7 @@ TEST_F(DisplayLockContextTest, LockedCountsWithMultipleLocks) {
)HTML");
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 0);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 0);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 0);
auto* one = GetDocument().getElementById("one");
auto* two = GetDocument().getElementById("two");
@@ -903,37 +1028,41 @@ TEST_F(DisplayLockContextTest, LockedCountsWithMultipleLocks) {
LockElement(*one, false);
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 1);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 1);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 1);
LockElement(*two, false);
- EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 2);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 2);
+ // Because |two| is nested, the lock counts aren't updated since the lock
+ // doesn't actually take effect until style can determine that we should lock.
+ EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 1);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 1);
LockElement(*three, false);
- EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 3);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 3);
+ EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 2);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 2);
- // Now commit the inner lock.
- CommitElement(*two);
+ // Now commit the outer lock.
+ CommitElement(*one);
+ // The counts remain the same since now the inner lock is determined to be
+ // locked.
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 2);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 2);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 2);
- // Commit the outer lock.
- CommitElement(*one);
+ // Commit the inner lock.
+ CommitElement(*two);
// Both inner and outer locks should have committed.
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 1);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 1);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 1);
// Commit the sibling lock.
CommitElement(*three);
// Both inner and outer locks should have committed.
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 0);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 0);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 0);
}
TEST_F(DisplayLockContextTest, ActivatableNotCountedAsBlocking) {
@@ -953,48 +1082,41 @@ TEST_F(DisplayLockContextTest, ActivatableNotCountedAsBlocking) {
)HTML");
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 0);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 0);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 0);
auto* activatable = GetDocument().getElementById("activatable");
auto* non_activatable = GetDocument().getElementById("nonActivatable");
+ // Initial display lock context should be activatable, since nothing skipped
+ // activation for it.
+ EXPECT_TRUE(activatable->EnsureDisplayLockContext().IsActivatable(
+ DisplayLockActivationReason::kAny));
+
LockElement(*activatable, true);
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 1);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 0);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 0);
EXPECT_TRUE(activatable->GetDisplayLockContext()->IsActivatable(
DisplayLockActivationReason::kAny));
LockElement(*non_activatable, false);
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 2);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 1);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 1);
EXPECT_FALSE(non_activatable->GetDisplayLockContext()->IsActivatable(
DisplayLockActivationReason::kAny));
- // Now commit the lock for |non_ctivatable|.
+ // Now commit the lock for |non_activatable|.
CommitElement(*non_activatable);
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 1);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 0);
- EXPECT_TRUE(activatable->GetDisplayLockContext()->IsActivatable(
- DisplayLockActivationReason::kAny));
- EXPECT_TRUE(activatable->GetDisplayLockContext()->IsActivatable(
- DisplayLockActivationReason::kAny));
-
- // Re-acquire the lock for |activatable|, but without the activatable flag.
- LockElement(*activatable, false);
-
- EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 1);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 1);
- EXPECT_FALSE(activatable->GetDisplayLockContext()->IsActivatable(
- DisplayLockActivationReason::kAny));
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 0);
// Re-acquire the lock for |activatable| again with the activatable flag.
LockElement(*activatable, true);
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 1);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 0);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 0);
EXPECT_TRUE(activatable->GetDisplayLockContext()->IsActivatable(
DisplayLockActivationReason::kAny));
}
@@ -1022,7 +1144,7 @@ TEST_F(DisplayLockContextTest, ElementInTemplate) {
)HTML");
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 0);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 0);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 0);
auto* template_el =
To<HTMLTemplateElement>(GetDocument().getElementById("template"));
@@ -1033,12 +1155,12 @@ TEST_F(DisplayLockContextTest, ElementInTemplate) {
LockElement(*child, false);
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 0);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 0);
- EXPECT_TRUE(child->GetDisplayLockContext()->IsLocked());
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 0);
+ EXPECT_FALSE(child->GetDisplayLockContext());
- // commit() will unlock the element.
+ // Commit also works, but does nothing.
CommitElement(*child);
- EXPECT_FALSE(child->GetDisplayLockContext()->IsLocked());
+ EXPECT_FALSE(child->GetDisplayLockContext());
// Try to lock an element that was moved from a template to a document.
auto* document_child =
@@ -1048,25 +1170,35 @@ TEST_F(DisplayLockContextTest, ElementInTemplate) {
LockElement(*document_child, false);
+ // These should be 0, since container is display: none, so locking its child
+ // is not visible to style.
+ EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 0);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 0);
+ ASSERT_FALSE(document_child->GetDisplayLockContext());
+
+ container->setAttribute(html_names::kStyleAttr, "display: block;");
+ EXPECT_TRUE(container->NeedsStyleRecalc());
+ UpdateAllLifecyclePhasesForTest();
+
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 1);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 1);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 1);
+ ASSERT_TRUE(document_child->GetDisplayLockContext());
EXPECT_TRUE(document_child->GetDisplayLockContext()->IsLocked());
- container->setAttribute("style", "display: block;");
- document_child->setAttribute("style", "color: red;");
+ document_child->setAttribute(
+ html_names::kStyleAttr,
+ "subtree-visibility: hidden; color: red;");
+ UpdateAllLifecyclePhasesForTest();
- EXPECT_TRUE(container->NeedsStyleRecalc());
EXPECT_FALSE(document_child->NeedsStyleRecalc());
+ // Commit will unlock the element and update the style.
+ document_child->setAttribute(html_names::kStyleAttr, "color: red;");
UpdateAllLifecyclePhasesForTest();
- EXPECT_FALSE(document_child->NeedsStyleRecalc());
-
- // commit() will unlock the element and update the style.
- CommitElement(*document_child);
EXPECT_FALSE(document_child->GetDisplayLockContext()->IsLocked());
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 0);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 0);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 0);
EXPECT_FALSE(document_child->NeedsStyleRecalc());
EXPECT_FALSE(document_child->ChildNeedsStyleRecalc());
@@ -1177,7 +1309,10 @@ TEST_F(DisplayLockContextTest, AncestorAllowedTouchAction) {
EXPECT_TRUE(locked_object->InsideBlockingTouchEventHandler());
EXPECT_FALSE(lockedchild_object->InsideBlockingTouchEventHandler());
+ // Manually commit the lock so that we can verify which dirty bits get
+ // propagated.
CommitElement(*locked_element, false);
+ UnlockImmediate(locked_element->GetDisplayLockContext());
EXPECT_FALSE(ancestor_object->EffectiveAllowedTouchActionChanged());
EXPECT_FALSE(handler_object->EffectiveAllowedTouchActionChanged());
@@ -1318,7 +1453,10 @@ TEST_F(DisplayLockContextTest, DescendantAllowedTouchAction) {
EXPECT_FALSE(locked_object->InsideBlockingTouchEventHandler());
EXPECT_FALSE(handler_object->InsideBlockingTouchEventHandler());
+ // Manually commit the lock so that we can verify which dirty bits get
+ // propagated.
CommitElement(*locked_element, false);
+ UnlockImmediate(locked_element->GetDisplayLockContext());
EXPECT_FALSE(ancestor_object->EffectiveAllowedTouchActionChanged());
EXPECT_FALSE(descendant_object->EffectiveAllowedTouchActionChanged());
@@ -1365,6 +1503,7 @@ TEST_F(DisplayLockContextTest,
width: 100px;
height: 100px;
contain: style layout;
+ will-change: transform;
}
#composited {
will-change: transform;
@@ -1468,7 +1607,10 @@ TEST_F(DisplayLockContextTest, DescendantNeedsPaintPropertyUpdateBlocked) {
EXPECT_TRUE(locked_object->DescendantNeedsPaintPropertyUpdate());
EXPECT_FALSE(handler_object->DescendantNeedsPaintPropertyUpdate());
+ // Manually commit the lock so that we can verify which dirty bits get
+ // propagated.
CommitElement(*locked_element, false);
+ UnlockImmediate(locked_element->GetDisplayLockContext());
EXPECT_FALSE(ancestor_object->NeedsPaintPropertyUpdate());
EXPECT_FALSE(descendant_object->NeedsPaintPropertyUpdate());
@@ -1493,68 +1635,25 @@ TEST_F(DisplayLockContextTest, DescendantNeedsPaintPropertyUpdateBlocked) {
EXPECT_FALSE(handler_object->DescendantNeedsPaintPropertyUpdate());
}
-TEST_F(DisplayLockContextTest, DisconnectedWhileUpdating) {
- SetHtmlInnerHTML(R"HTML(
- <style>
- #container {
- contain: style layout;
- }
- </style>
- <div id="container"></div>
- )HTML");
-
- auto* container = GetDocument().getElementById("container");
- LockElement(*container, false);
-
- EXPECT_TRUE(container->GetDisplayLockContext()->IsLocked());
- EXPECT_FALSE(container->GetDisplayLockContext()->ShouldStyle(
- DisplayLockLifecycleTarget::kChildren));
- EXPECT_FALSE(container->GetDisplayLockContext()->ShouldLayout(
- DisplayLockLifecycleTarget::kChildren));
- EXPECT_FALSE(container->GetDisplayLockContext()->ShouldPrePaint(
- DisplayLockLifecycleTarget::kChildren));
-
- auto* script_state = ToScriptStateForMainWorld(GetDocument().GetFrame());
- {
- ScriptState::Scope scope(script_state);
- container->GetDisplayLockContext()->UpdateRendering(script_state);
- }
- auto budget = base::WrapUnique(
- new StrictYieldingDisplayLockBudget(container->GetDisplayLockContext()));
- ResetBudget(std::move(budget), container->GetDisplayLockContext());
-
- // This should style and allow layout, but not actually do layout (thus
- // pre-paint would be blocked). Furthermore, this should schedule a task to
- // run DisplayLockLifecycleTarget::ScheduleAnimation (since we can't directly
- // schedule it from within a lifecycle).
- UpdateAllLifecyclePhasesForTest();
-
- ASSERT_FALSE(GetDocument().View()->InLifecycleUpdate());
- GetDocument().View()->SetInLifecycleUpdateForTest(true);
- EXPECT_TRUE(container->GetDisplayLockContext()->IsLocked());
- EXPECT_TRUE(container->GetDisplayLockContext()->ShouldStyle(
- DisplayLockLifecycleTarget::kChildren));
- EXPECT_TRUE(container->GetDisplayLockContext()->ShouldLayout(
- DisplayLockLifecycleTarget::kChildren));
- EXPECT_FALSE(container->GetDisplayLockContext()->ShouldPrePaint(
- DisplayLockLifecycleTarget::kChildren));
- GetDocument().View()->SetInLifecycleUpdateForTest(false);
-
- // Now disconnect the element.
- container->remove();
-
- // Flushing the pending tasks would call ScheduleAnimation, but since we're no
- // longer connected and can't schedule from within the element, we should
- // gracefully exit (and not crash).
- test::RunPendingTasks();
-}
-
class DisplayLockContextRenderingTest : public RenderingTest,
- private ScopedDisplayLockingForTest {
+ private ScopedCSSSubtreeVisibilityHiddenMatchableForTest {
public:
DisplayLockContextRenderingTest()
: RenderingTest(MakeGarbageCollected<SingleChildLocalFrameClient>()),
- ScopedDisplayLockingForTest(true) {}
+ ScopedCSSSubtreeVisibilityHiddenMatchableForTest(true) {}
+
+ bool IsObservingLifecycle(DisplayLockContext* context) const {
+ return context->is_registered_for_lifecycle_notifications_;
+ }
+ void LockImmediate(DisplayLockContext* context) {
+ context->SetRequestedState(ESubtreeVisibility::kHidden);
+ }
+ void RunStartOfLifecycleTasks() {
+ auto start_of_lifecycle_tasks =
+ GetDocument().View()->TakeStartOfLifecycleTasksForTest();
+ for (auto& task : start_of_lifecycle_tasks)
+ std::move(task).Run();
+ }
};
TEST_F(DisplayLockContextRenderingTest, FrameDocumentRemovedWhileAcquire) {
@@ -1573,8 +1672,7 @@ TEST_F(DisplayLockContextRenderingTest, FrameDocumentRemovedWhileAcquire) {
auto* target = ChildDocument().getElementById("target");
GetDocument().getElementById("frame")->remove();
- target->EnsureDisplayLockContext(DisplayLockContextCreateMethod::kAttribute)
- .StartAcquire();
+ LockImmediate(&target->EnsureDisplayLockContext());
}
TEST_F(DisplayLockContextRenderingTest,
@@ -1645,8 +1743,8 @@ TEST_F(DisplayLockContextRenderingTest, ObjectsNeedingLayoutConsidersLocks) {
EXPECT_EQ(dirty_count, 10u);
EXPECT_EQ(total_count, 10u);
- GetDocument().getElementById("e")->setAttribute(
- html_names::kRendersubtreeAttr, "invisible");
+ GetDocument().getElementById("e")->setAttribute(html_names::kStyleAttr,
+ "subtree-visibility: auto");
UpdateAllLifecyclePhasesForTest();
// Note that the dirty_all call propagate the dirty bit from the unlocked
@@ -1661,8 +1759,8 @@ TEST_F(DisplayLockContextRenderingTest, ObjectsNeedingLayoutConsidersLocks) {
// We still see the locked element, so the total is 8.
EXPECT_EQ(total_count, 8u);
- GetDocument().getElementById("a")->setAttribute(
- html_names::kRendersubtreeAttr, "invisible");
+ GetDocument().getElementById("a")->setAttribute(html_names::kStyleAttr,
+ "subtree-visibility: auto");
UpdateAllLifecyclePhasesForTest();
// Note that this dirty_all call is now not propagating the dirty bits at all,
@@ -1677,4 +1775,291 @@ TEST_F(DisplayLockContextRenderingTest, ObjectsNeedingLayoutConsidersLocks) {
EXPECT_EQ(total_count, 4u);
}
+TEST_F(DisplayLockContextRenderingTest,
+ NestedLockDoesNotInvalidateOnHideOrShow) {
+ SetHtmlInnerHTML(R"HTML(
+ <style>
+ .auto { subtree-visibility: auto; }
+ .hidden { subtree-visibility: hidden; }
+ .item { height: 10px; }
+ /* this is important to not invalidate layout when we hide the element! */
+ #outer { contain: style layout; }
+ </style>
+ <div id=outer>
+ <div id=unrelated>
+ <div id=inner class=auto>Content</div>
+ </div>
+ </div>
+ )HTML");
+
+ auto* inner_element = GetDocument().getElementById("inner");
+ 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());
+
+ RunStartOfLifecycleTasks();
+
+ // Now that the intersection observer notifications switch the visibility of
+ // the context, we expect to see dirty layout bits to be propagated.
+ EXPECT_TRUE(outer_element->GetLayoutObject()->NeedsLayout());
+ EXPECT_FALSE(outer_element->GetLayoutObject()->SelfNeedsLayout());
+ EXPECT_TRUE(unrelated_element->GetLayoutObject()->NeedsLayout());
+ EXPECT_FALSE(unrelated_element->GetLayoutObject()->SelfNeedsLayout());
+ EXPECT_TRUE(inner_element->GetLayoutObject()->NeedsLayout());
+ EXPECT_FALSE(inner_element->GetLayoutObject()->SelfNeedsLayout());
+
+ // Clear the layout.
+ UpdateAllLifecyclePhasesForTest();
+ 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());
+
+ // Verify lock state.
+ auto* inner_context = inner_element->GetDisplayLockContext();
+ ASSERT_TRUE(inner_context);
+ EXPECT_FALSE(inner_context->IsLocked());
+
+ // Lock outer.
+ outer_element->setAttribute(html_names::kClassAttr, "hidden");
+ // Ensure the lock processes (but don't run intersection observation tasks
+ // yet).
+ UpdateAllLifecyclePhasesForTest();
+
+ // Verify the lock exists.
+ auto* outer_context = outer_element->GetDisplayLockContext();
+ ASSERT_TRUE(outer_context);
+ EXPECT_TRUE(outer_context->IsLocked());
+
+ // Everything should be layout clean.
+ 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());
+
+ // Inner context should not be observing the lifecycle.
+ EXPECT_FALSE(IsObservingLifecycle(inner_context));
+
+ // Process any visibility changes.
+ RunStartOfLifecycleTasks();
+
+ // Run the following checks a few times since we should be observing
+ // lifecycle.
+ for (int i = 0; i < 3; ++i) {
+ // It shouldn't change the fact that we're layout clean.
+ 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());
+
+ // Because we skipped hiding the element, inner_context should be observing
+ // lifecycle.
+ EXPECT_TRUE(IsObservingLifecycle(inner_context));
+
+ UpdateAllLifecyclePhasesForTest();
+ }
+
+ // Unlock outer.
+ outer_element->setAttribute(html_names::kClassAttr, "");
+ // Ensure the lock processes (but don't run intersection observation tasks
+ // yet).
+ UpdateAllLifecyclePhasesForTest();
+
+ // Note that although we're not nested, we're still observing the lifecycle
+ // because we don't yet know whether we should or should not hide and we only
+ // make this decision _before_ the lifecycle actually unlocked outer.
+ EXPECT_TRUE(IsObservingLifecycle(inner_context));
+
+ // Verify the lock is gone.
+ EXPECT_FALSE(outer_context->IsLocked());
+
+ // Everything should be layout clean.
+ 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());
+
+ // Process visibility changes.
+ RunStartOfLifecycleTasks();
+
+ // We now should know we're visible and so we're not observing the lifecycle.
+ EXPECT_FALSE(IsObservingLifecycle(inner_context));
+
+ // Also we should still be activated and unlocked.
+ EXPECT_FALSE(inner_context->IsLocked());
+
+ // Everything should be layout clean.
+ 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());
+}
+
+TEST_F(DisplayLockContextRenderingTest, NestedLockDoesHideWhenItIsOffscreen) {
+ SetHtmlInnerHTML(R"HTML(
+ <style>
+ .auto { subtree-visibility: auto; }
+ .hidden { subtree-visibility: hidden; }
+ .item { height: 10px; }
+ /* this is important to not invalidate layout when we hide the element! */
+ #outer { contain: style layout; }
+ .spacer { height: 10000px; }
+ </style>
+ <div id=future_spacer></div>
+ <div id=outer>
+ <div id=unrelated>
+ <div id=inner class=auto>Content</div>
+ </div>
+ </div>
+ )HTML");
+
+ auto* inner_element = GetDocument().getElementById("inner");
+ 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());
+
+ RunStartOfLifecycleTasks();
+
+ // Now that the intersection observer notifications switch the visibility of
+ // the context, we expect to see dirty layout bits to be propagated.
+ EXPECT_TRUE(outer_element->GetLayoutObject()->NeedsLayout());
+ EXPECT_FALSE(outer_element->GetLayoutObject()->SelfNeedsLayout());
+ EXPECT_TRUE(unrelated_element->GetLayoutObject()->NeedsLayout());
+ EXPECT_FALSE(unrelated_element->GetLayoutObject()->SelfNeedsLayout());
+ EXPECT_TRUE(inner_element->GetLayoutObject()->NeedsLayout());
+ EXPECT_FALSE(inner_element->GetLayoutObject()->SelfNeedsLayout());
+
+ // Clear the layout.
+ UpdateAllLifecyclePhasesForTest();
+ 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());
+
+ // Verify lock state.
+ auto* inner_context = inner_element->GetDisplayLockContext();
+ ASSERT_TRUE(inner_context);
+ EXPECT_FALSE(inner_context->IsLocked());
+
+ // Lock outer.
+ outer_element->setAttribute(html_names::kClassAttr, "hidden");
+ // Ensure the lock processes (but don't run intersection observation tasks
+ // yet).
+ UpdateAllLifecyclePhasesForTest();
+
+ // Verify the lock exists.
+ auto* outer_context = outer_element->GetDisplayLockContext();
+ ASSERT_TRUE(outer_context);
+ EXPECT_TRUE(outer_context->IsLocked());
+
+ // Everything should be layout clean.
+ 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());
+
+ // Inner context should not be observing the lifecycle.
+ EXPECT_FALSE(IsObservingLifecycle(inner_context));
+
+ // Process any visibility changes.
+ RunStartOfLifecycleTasks();
+
+ // It shouldn't change the fact that we're layout clean.
+ 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());
+
+ // Let future spacer become a real spacer!
+ GetDocument()
+ .getElementById("future_spacer")
+ ->setAttribute(html_names::kClassAttr, "spacer");
+
+ UpdateAllLifecyclePhasesForTest();
+
+ // Because we skipped hiding the element, inner_context should be observing
+ // lifecycle.
+ EXPECT_TRUE(IsObservingLifecycle(inner_context));
+
+ // Unlock outer.
+ outer_element->setAttribute(html_names::kClassAttr, "");
+ // Ensure the lock processes (but don't run intersection observation tasks
+ // yet).
+ UpdateAllLifecyclePhasesForTest();
+
+ // Note that although we're not nested, we're still observing the lifecycle
+ // because we don't yet know whether we should or should not hide and we only
+ // make this decision _before_ the lifecycle actually unlocked outer.
+ EXPECT_TRUE(IsObservingLifecycle(inner_context));
+
+ // Verify the lock is gone.
+ EXPECT_FALSE(outer_context->IsLocked());
+
+ // Everything should be layout clean.
+ 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());
+
+ // Process any visibility changes.
+ RunStartOfLifecycleTasks();
+
+ // We're still invisible, and we don't know that we're not nested so we're
+ // still observing the lifecycle.
+ EXPECT_TRUE(IsObservingLifecycle(inner_context));
+
+ // We're unlocked for now.
+ EXPECT_FALSE(inner_context->IsLocked());
+
+ // Everything should be layout clean.
+ 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());
+
+ UpdateAllLifecyclePhasesForTest();
+
+ // We figured out that we're actually invisible so no need to observe the
+ // lifecycle.
+ EXPECT_FALSE(IsObservingLifecycle(inner_context));
+
+ // We're locked.
+ EXPECT_TRUE(inner_context->IsLocked());
+}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/display_lock/display_lock_fuzzer.cc b/chromium/third_party/blink/renderer/core/display_lock/display_lock_fuzzer.cc
deleted file mode 100644
index 03ab9065171..00000000000
--- a/chromium/third_party/blink/renderer/core/display_lock/display_lock_fuzzer.cc
+++ /dev/null
@@ -1,50 +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 "content/test/fuzzer/fuzzer_support.h"
-#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
-#include "third_party/blink/public/platform/web_runtime_features.h"
-#include "third_party/blink/public/web/web_local_frame.h"
-#include "third_party/blink/public/web/web_view.h"
-#include "third_party/blink/public/web/web_widget.h"
-
-static content::Env* env;
-
-bool Initialize() {
- blink::WebRuntimeFeatures::EnableDisplayLocking(true);
- env = new content::Env();
- return true;
-}
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- static bool initialized = Initialize();
- // Suppress unused variable warning.
- (void)initialized;
-
- // Only handle reasonable size inputs.
- if (size < 1 || size > 10000)
- return 0;
-
- std::string data_as_string(reinterpret_cast<const char*>(data), size);
- int num_rafs = std::hash<std::string>()(data_as_string) % 10;
- env->adapter->LoadHTML(data_as_string, "");
-
- // Delay each frame 17ms which is roughly the length of a frame when running
- // at 60fps.
- auto frame_delay = base::TimeDelta::FromMillisecondsD(17);
-
- for (int i = 0; i < num_rafs; ++i) {
- base::RunLoop run_loop;
- blink::scheduler::GetSingleThreadTaskRunnerForTesting()->PostDelayedTask(
- FROM_HERE, run_loop.QuitClosure(), frame_delay);
- run_loop.Run();
-
- env->adapter->GetMainFrame()
- ->View()
- ->MainFrameWidget()
- ->UpdateAllLifecyclePhases(
- blink::WebWidget::LifecycleUpdateReason::kTest);
- }
- return 0;
-}
diff --git a/chromium/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc b/chromium/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc
index 81ff80d17e2..183b36b0f3c 100644
--- a/chromium/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc
+++ b/chromium/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc
@@ -12,9 +12,12 @@
#include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/editing/editing_boundary.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
+#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
+#include <set>
+
namespace blink {
namespace {
@@ -32,9 +35,9 @@ bool UpdateStyleAndLayoutForRangeIfNeeded(const EphemeralRangeInFlatTree& range,
DisplayLockActivationReason reason) {
if (range.IsNull() || range.IsCollapsed())
return false;
- if (!RuntimeEnabledFeatures::DisplayLockingEnabled(&range.GetDocument()) ||
+ if (!RuntimeEnabledFeatures::CSSSubtreeVisibilityEnabled() ||
range.GetDocument().LockedDisplayLockCount() ==
- range.GetDocument().ActivationBlockingDisplayLockCount())
+ range.GetDocument().DisplayLockBlockingAllActivationCount())
return false;
Vector<DisplayLockContext::ScopedForcedUpdate> scoped_forced_update_list_;
for (Node& node : range.Nodes()) {
@@ -50,21 +53,35 @@ bool UpdateStyleAndLayoutForRangeIfNeeded(const EphemeralRangeInFlatTree& range,
->GetScopedForcedUpdate());
}
}
- if (!scoped_forced_update_list_.IsEmpty())
- range.GetDocument().UpdateStyleAndLayout();
+ if (!scoped_forced_update_list_.IsEmpty()) {
+ range.GetDocument().UpdateStyleAndLayout(
+ DocumentUpdateReason::kDisplayLock);
+ }
return !scoped_forced_update_list_.IsEmpty();
}
+void PopulateAncestorContexts(Node* node,
+ std::set<DisplayLockContext*>* contexts) {
+ DCHECK(node);
+ for (Node& ancestor : FlatTreeTraversal::InclusiveAncestorsOf(*node)) {
+ auto* ancestor_element = DynamicTo<Element>(ancestor);
+ if (!ancestor_element)
+ continue;
+ if (auto* context = ancestor_element->GetDisplayLockContext())
+ contexts->insert(context);
+ }
+}
+
} // namespace
bool DisplayLockUtilities::ActivateFindInPageMatchRangeIfNeeded(
const EphemeralRangeInFlatTree& range) {
- if (!RuntimeEnabledFeatures::DisplayLockingEnabled(&range.GetDocument()))
+ if (!RuntimeEnabledFeatures::CSSSubtreeVisibilityEnabled())
return false;
DCHECK(!range.IsNull());
DCHECK(!range.IsCollapsed());
if (range.GetDocument().LockedDisplayLockCount() ==
- range.GetDocument().ActivationBlockingDisplayLockCount())
+ range.GetDocument().DisplayLockBlockingAllActivationCount())
return false;
// Find-in-page matches can't span multiple block-level elements (because the
// text will be broken by newlines between blocks), so first we find the
@@ -73,9 +90,13 @@ bool DisplayLockUtilities::ActivateFindInPageMatchRangeIfNeeded(
// case we are traversing from the start position of the range.
Element* enclosing_block =
EnclosingBlock(range.StartPosition(), kCannotCrossEditingBoundary);
+ // Note that we don't check the `range.EndPosition()` since we just activate
+ // the beginning of the range. In find-in-page cases, the end position is the
+ // same since the matches cannot cross block boundaries. However, in
+ // scroll-to-text, the range might be different, but we still just activate
+ // the beginning of the range. See
+ // https://github.com/WICG/display-locking/issues/125 for more details.
DCHECK(enclosing_block);
- DCHECK_EQ(enclosing_block,
- EnclosingBlock(range.EndPosition(), kCannotCrossEditingBoundary));
return enclosing_block->ActivateDisplayLockIfNeeded(
DisplayLockActivationReason::kFindInPage);
}
@@ -84,9 +105,9 @@ bool DisplayLockUtilities::ActivateSelectionRangeIfNeeded(
const EphemeralRangeInFlatTree& range) {
if (range.IsNull() || range.IsCollapsed())
return false;
- if (!RuntimeEnabledFeatures::DisplayLockingEnabled(&range.GetDocument()) ||
+ if (!RuntimeEnabledFeatures::CSSSubtreeVisibilityEnabled() ||
range.GetDocument().LockedDisplayLockCount() ==
- range.GetDocument().ActivationBlockingDisplayLockCount())
+ range.GetDocument().DisplayLockBlockingAllActivationCount())
return false;
UpdateStyleAndLayoutForRangeIfNeeded(range,
DisplayLockActivationReason::kSelection);
@@ -112,10 +133,9 @@ DisplayLockUtilities::ActivatableLockedInclusiveAncestors(
DisplayLockActivationReason reason) {
HeapVector<Member<Element>> elements_to_activate;
const_cast<Node*>(&node)->UpdateDistributionForFlatTreeTraversal();
- if (!RuntimeEnabledFeatures::DisplayLockingEnabled(
- node.GetExecutionContext()) ||
+ if (!RuntimeEnabledFeatures::CSSSubtreeVisibilityEnabled() ||
node.GetDocument().LockedDisplayLockCount() ==
- node.GetDocument().ActivationBlockingDisplayLockCount())
+ node.GetDocument().DisplayLockBlockingAllActivationCount())
return elements_to_activate;
for (Node& ancestor : FlatTreeTraversal::InclusiveAncestorsOf(node)) {
@@ -140,8 +160,7 @@ DisplayLockUtilities::ActivatableLockedInclusiveAncestors(
DisplayLockUtilities::ScopedChainForcedUpdate::ScopedChainForcedUpdate(
const Node* node,
bool include_self) {
- if (!RuntimeEnabledFeatures::DisplayLockingEnabled(
- node->GetExecutionContext()))
+ if (!RuntimeEnabledFeatures::CSSSubtreeVisibilityEnabled())
return;
CreateParentFrameScopeIfNeeded(node);
@@ -197,8 +216,7 @@ const Element* DisplayLockUtilities::NearestLockedInclusiveAncestor(
auto* element = DynamicTo<Element>(node);
if (!element)
return NearestLockedExclusiveAncestor(node);
- if (!RuntimeEnabledFeatures::DisplayLockingEnabled(
- node.GetExecutionContext()) ||
+ if (!RuntimeEnabledFeatures::CSSSubtreeVisibilityEnabled() ||
!node.isConnected() || node.GetDocument().LockedDisplayLockCount() == 0 ||
!node.CanParticipateInFlatTree()) {
return nullptr;
@@ -217,8 +235,7 @@ Element* DisplayLockUtilities::NearestLockedInclusiveAncestor(Node& node) {
Element* DisplayLockUtilities::NearestLockedExclusiveAncestor(
const Node& node) {
- if (!RuntimeEnabledFeatures::DisplayLockingEnabled(
- node.GetExecutionContext()) ||
+ if (!RuntimeEnabledFeatures::CSSSubtreeVisibilityEnabled() ||
!node.isConnected() || node.GetDocument().LockedDisplayLockCount() == 0 ||
!node.CanParticipateInFlatTree()) {
return nullptr;
@@ -240,8 +257,7 @@ Element* DisplayLockUtilities::NearestLockedExclusiveAncestor(
Element* DisplayLockUtilities::HighestLockedInclusiveAncestor(
const Node& node) {
- if (!RuntimeEnabledFeatures::DisplayLockingEnabled(
- node.GetExecutionContext()) ||
+ if (!RuntimeEnabledFeatures::CSSSubtreeVisibilityEnabled() ||
node.GetDocument().LockedDisplayLockCount() == 0 ||
!node.CanParticipateInFlatTree()) {
return nullptr;
@@ -262,8 +278,7 @@ Element* DisplayLockUtilities::HighestLockedInclusiveAncestor(
Element* DisplayLockUtilities::HighestLockedExclusiveAncestor(
const Node& node) {
- if (!RuntimeEnabledFeatures::DisplayLockingEnabled(
- node.GetExecutionContext()) ||
+ if (!RuntimeEnabledFeatures::CSSSubtreeVisibilityEnabled() ||
node.GetDocument().LockedDisplayLockCount() == 0 ||
!node.CanParticipateInFlatTree()) {
return nullptr;
@@ -296,29 +311,29 @@ Element* DisplayLockUtilities::NearestLockedExclusiveAncestor(
return nullptr;
}
-bool DisplayLockUtilities::IsInNonActivatableLockedSubtree(const Node& node) {
- if (!RuntimeEnabledFeatures::DisplayLockingEnabled(
+bool DisplayLockUtilities::IsInUnlockedOrActivatableSubtree(
+ const Node& node,
+ DisplayLockActivationReason activation_reason) {
+ if (!RuntimeEnabledFeatures::CSSSubtreeVisibilityEnabled(
node.GetExecutionContext()) ||
node.GetDocument().LockedDisplayLockCount() == 0 ||
- node.GetDocument().ActivationBlockingDisplayLockCount() == 0 ||
+ node.GetDocument().DisplayLockBlockingAllActivationCount() == 0 ||
!node.CanParticipateInFlatTree()) {
- return false;
+ return true;
}
for (auto* element = NearestLockedExclusiveAncestor(node); element;
element = NearestLockedExclusiveAncestor(*element)) {
- if (!element->GetDisplayLockContext()->IsActivatable(
- DisplayLockActivationReason::kAny)) {
- return true;
+ if (!element->GetDisplayLockContext()->IsActivatable(activation_reason)) {
+ return false;
}
}
- return false;
+ return true;
}
bool DisplayLockUtilities::IsInLockedSubtreeCrossingFrames(
const Node& source_node) {
- if (!RuntimeEnabledFeatures::DisplayLockingEnabled(
- source_node.GetExecutionContext()))
+ if (!RuntimeEnabledFeatures::CSSSubtreeVisibilityEnabled())
return false;
const Node* node = &source_node;
@@ -347,4 +362,99 @@ bool DisplayLockUtilities::IsInLockedSubtreeCrossingFrames(
return false;
}
+void DisplayLockUtilities::ElementLostFocus(Element* element) {
+ if (!RuntimeEnabledFeatures::CSSSubtreeVisibilityEnabled() ||
+ (element && element->GetDocument().DisplayLockCount() == 0))
+ return;
+ for (; element; element = FlatTreeTraversal::ParentElement(*element)) {
+ auto* context = element->GetDisplayLockContext();
+ if (context)
+ context->NotifySubtreeLostFocus();
+ }
+}
+void DisplayLockUtilities::ElementGainedFocus(Element* element) {
+ if (!RuntimeEnabledFeatures::CSSSubtreeVisibilityEnabled() ||
+ (element && element->GetDocument().DisplayLockCount() == 0))
+ return;
+
+ for (; element; element = FlatTreeTraversal::ParentElement(*element)) {
+ auto* context = element->GetDisplayLockContext();
+ if (context)
+ context->NotifySubtreeGainedFocus();
+ }
+}
+
+void DisplayLockUtilities::SelectionChanged(
+ const EphemeralRangeInFlatTree& old_selection,
+ const EphemeralRangeInFlatTree& new_selection) {
+ if (!RuntimeEnabledFeatures::CSSSubtreeVisibilityEnabled() ||
+ (!old_selection.IsNull() &&
+ old_selection.GetDocument().DisplayLockCount() == 0) ||
+ (!new_selection.IsNull() &&
+ new_selection.GetDocument().DisplayLockCount() == 0))
+ return;
+
+ TRACE_EVENT0("blink", "DisplayLockUtilities::SelectionChanged");
+ std::set<Node*> old_nodes;
+ for (Node& node : old_selection.Nodes())
+ old_nodes.insert(&node);
+
+ std::set<Node*> new_nodes;
+ for (Node& node : new_selection.Nodes())
+ new_nodes.insert(&node);
+
+ std::set<DisplayLockContext*> lost_selection_contexts;
+ std::set<DisplayLockContext*> gained_selection_contexts;
+
+ // Skip common nodes and extract contexts from nodes that lost selection and
+ // contexts from nodes that gained selection.
+ // This is similar to std::set_symmetric_difference except that we need to
+ // know which set the resulting item came from. In this version, we simply do
+ // the relevant operation on each of the items instead of storing the
+ // difference.
+ std::set<Node*>::iterator old_it = old_nodes.begin();
+ std::set<Node*>::iterator new_it = new_nodes.begin();
+ while (old_it != old_nodes.end() && new_it != new_nodes.end()) {
+ // Compare the addresses since that's how the nodes are ordered in the set.
+ if (*old_it < *new_it) {
+ PopulateAncestorContexts(*old_it++, &lost_selection_contexts);
+ } else if (*old_it > *new_it) {
+ PopulateAncestorContexts(*new_it++, &gained_selection_contexts);
+ } else {
+ ++old_it;
+ ++new_it;
+ }
+ }
+ while (old_it != old_nodes.end())
+ PopulateAncestorContexts(*old_it++, &lost_selection_contexts);
+ while (new_it != new_nodes.end())
+ PopulateAncestorContexts(*new_it++, &gained_selection_contexts);
+
+ // Now do a similar thing with contexts: skip common ones, and mark the ones
+ // that lost selection or gained selection as such.
+ std::set<DisplayLockContext*>::iterator lost_it =
+ lost_selection_contexts.begin();
+ std::set<DisplayLockContext*>::iterator gained_it =
+ gained_selection_contexts.begin();
+ while (lost_it != lost_selection_contexts.end() &&
+ gained_it != gained_selection_contexts.end()) {
+ if (*lost_it < *gained_it) {
+ (*lost_it++)->NotifySubtreeLostSelection();
+ } else if (*lost_it > *gained_it) {
+ (*gained_it++)->NotifySubtreeGainedSelection();
+ } else {
+ ++lost_it;
+ ++gained_it;
+ }
+ }
+ while (lost_it != lost_selection_contexts.end())
+ (*lost_it++)->NotifySubtreeLostSelection();
+ while (gained_it != gained_selection_contexts.end())
+ (*gained_it++)->NotifySubtreeGainedSelection();
+}
+
+void DisplayLockUtilities::SelectionRemovedFromDocument(Document& document) {
+ document.NotifySelectionRemovedFromDisplayLocks();
+}
+
} // namespace blink
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 b9b4bf33c23..8a875f84521 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
@@ -19,7 +19,7 @@ class CORE_EXPORT DisplayLockUtilities {
public:
// This class forces updates on display locks from the given node up the
// ancestor chain until the local frame root.
- class ScopedChainForcedUpdate {
+ class CORE_EXPORT ScopedChainForcedUpdate {
DISALLOW_COPY_AND_ASSIGN(ScopedChainForcedUpdate);
public:
@@ -70,12 +70,35 @@ class CORE_EXPORT DisplayLockUtilities {
static Element* NearestLockedInclusiveAncestor(const LayoutObject& object);
static Element* NearestLockedExclusiveAncestor(const LayoutObject& object);
- // Whether this node has non-activatable locked exclusive ancestors or not.
- static bool IsInNonActivatableLockedSubtree(const Node& node);
+ // Returns true if |node| is not in a locked subtree, or if it's possible to
+ // activate all of the locked ancestors for |activation_reason|.
+ static bool IsInUnlockedOrActivatableSubtree(
+ const Node& node,
+ DisplayLockActivationReason activation_reason =
+ DisplayLockActivationReason::kAny);
+
+ // Returns true if |node| is in a locked subtree, and at least one of its
+ // locked ancestors can't be activated with |activation_reason|. In other
+ // words, this node should be treated as if it's not in the tree for
+ // |activation_reason|.
+ static bool ShouldIgnoreNodeDueToDisplayLock(
+ const Node& node,
+ DisplayLockActivationReason activation_reason) {
+ return !IsInUnlockedOrActivatableSubtree(node, activation_reason);
+ }
// Returns true if the element is in a locked subtree (or is self-locked with
// no self-updates). This crosses frames while navigating the ancestor chain.
static bool IsInLockedSubtreeCrossingFrames(const Node& node);
+
+ // Called when the focused element changes. These functions update locks to
+ // ensure that focused element ancestors remain unlocked for 'auto' state.
+ static void ElementLostFocus(Element*);
+ static void ElementGainedFocus(Element*);
+
+ static void SelectionChanged(const EphemeralRangeInFlatTree& old_selection,
+ const EphemeralRangeInFlatTree& new_selection);
+ static void SelectionRemovedFromDocument(Document& document);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/display_lock/display_lock_utilities_test.cc b/chromium/third_party/blink/renderer/core/display_lock/display_lock_utilities_test.cc
index 154a07eb585..f055499b51b 100644
--- a/chromium/third_party/blink/renderer/core/display_lock/display_lock_utilities_test.cc
+++ b/chromium/third_party/blink/renderer/core/display_lock/display_lock_utilities_test.cc
@@ -14,37 +14,28 @@
namespace blink {
class DisplayLockUtilitiesTest : public RenderingTest,
- private ScopedDisplayLockingForTest {
+ private ScopedCSSSubtreeVisibilityHiddenMatchableForTest {
public:
DisplayLockUtilitiesTest()
: RenderingTest(MakeGarbageCollected<SingleChildLocalFrameClient>()),
- ScopedDisplayLockingForTest(true) {}
+ ScopedCSSSubtreeVisibilityHiddenMatchableForTest(true) {}
- void LockElement(Element& element,
- bool activatable,
- bool update_lifecycle = true) {
+ void LockElement(Element& element, bool activatable) {
StringBuilder value;
- value.Append("invisible");
- if (!activatable)
- value.Append(" skip-activation");
- element.setAttribute(html_names::kRendersubtreeAttr,
- value.ToAtomicString());
- if (update_lifecycle)
- UpdateAllLifecyclePhasesForTest();
+ value.Append("subtree-visibility: hidden");
+ if (activatable)
+ value.Append("-matchable");
+ element.setAttribute(html_names::kStyleAttr, value.ToAtomicString());
+ UpdateAllLifecyclePhasesForTest();
}
- void CommitElement(Element& element, bool update_lifecycle = true) {
- element.setAttribute(html_names::kRendersubtreeAttr, "");
- if (update_lifecycle)
- UpdateAllLifecyclePhasesForTest();
+ void CommitElement(Element& element) {
+ element.setAttribute(html_names::kStyleAttr, "");
+ UpdateAllLifecyclePhasesForTest();
}
};
-TEST_F(DisplayLockUtilitiesTest, ActivatableLockedInclusiveAncestors) {
- // TODO(vmpstr): Implement for layout ng.
- if (RuntimeEnabledFeatures::LayoutNGEnabled())
- return;
-
+TEST_F(DisplayLockUtilitiesTest, DISABLED_ActivatableLockedInclusiveAncestors) {
SetBodyInnerHTML(R"HTML(
<style>
div {
@@ -65,12 +56,12 @@ TEST_F(DisplayLockUtilitiesTest, ActivatableLockedInclusiveAncestors) {
Element& innermost = *GetDocument().getElementById("innermost");
ShadowRoot& shadow_root =
inner_b.AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString("<div id='shadowDiv'>shadow!</div>");
+ shadow_root.setInnerHTML("<div id='shadowDiv'>shadow!</div>");
Element& shadow_div = *shadow_root.getElementById("shadowDiv");
LockElement(outer, true);
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 1);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 0);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 0);
// Querying from every element gives |outer|.
HeapVector<Member<Element>> result_for_outer =
DisplayLockUtilities::ActivatableLockedInclusiveAncestors(
@@ -105,7 +96,7 @@ TEST_F(DisplayLockUtilitiesTest, ActivatableLockedInclusiveAncestors) {
// Lock innermost with activatable flag.
LockElement(innermost, true);
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 2);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 0);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 0);
result_for_outer = DisplayLockUtilities::ActivatableLockedInclusiveAncestors(
outer, DisplayLockActivationReason::kAny);
@@ -138,10 +129,10 @@ TEST_F(DisplayLockUtilitiesTest, ActivatableLockedInclusiveAncestors) {
EXPECT_EQ(result_for_shadow_div.at(0), outer);
// Unlock everything.
- CommitElement(innermost, false);
+ CommitElement(innermost);
CommitElement(outer);
EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 0);
- EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 0);
+ EXPECT_EQ(GetDocument().DisplayLockBlockingAllActivationCount(), 0);
EXPECT_EQ(DisplayLockUtilities::ActivatableLockedInclusiveAncestors(
outer, DisplayLockActivationReason::kAny)
@@ -233,5 +224,4 @@ TEST_F(DisplayLockUtilitiesTest, LockedSubtreeCrossingFrames) {
EXPECT_FALSE(DisplayLockUtilities::IsInLockedSubtreeCrossingFrames(*parent));
EXPECT_FALSE(DisplayLockUtilities::IsInLockedSubtreeCrossingFrames(*child));
}
-
} // namespace blink
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
index 3578ce7e9dc..104b4d1bb09 100644
--- 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
@@ -3,7 +3,7 @@
// found in the LICENSE file.
[
- RuntimeEnabled=DisplayLocking
+ RuntimeEnabled=CSSSubtreeVisibilityActivationEvent
] interface RenderSubtreeActivationEvent : Event {
readonly attribute Element activatedElement;
};
diff --git a/chromium/third_party/blink/renderer/core/display_lock/strict_yielding_display_lock_budget.cc b/chromium/third_party/blink/renderer/core/display_lock/strict_yielding_display_lock_budget.cc
deleted file mode 100644
index 3f319b97ae1..00000000000
--- a/chromium/third_party/blink/renderer/core/display_lock/strict_yielding_display_lock_budget.cc
+++ /dev/null
@@ -1,76 +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/core/display_lock/strict_yielding_display_lock_budget.h"
-
-#include <algorithm>
-#include "third_party/blink/renderer/core/frame/local_frame_view.h"
-
-namespace blink {
-
-StrictYieldingDisplayLockBudget::StrictYieldingDisplayLockBudget(
- DisplayLockContext* context)
- : DisplayLockBudget(context) {}
-
-bool StrictYieldingDisplayLockBudget::ShouldPerformPhase(
- Phase phase,
- const LifecycleData& lifecycle_data) {
- // We should perform any phase earlier than the one we already completed.
- // Also, we should complete a new phase once per cycle.
- return (last_completed_phase_ && phase <= *last_completed_phase_) ||
- !completed_new_phase_this_cycle_;
-}
-
-void StrictYieldingDisplayLockBudget::DidPerformPhase(Phase phase) {
- if (!completed_new_phase_this_cycle_ &&
- (!last_completed_phase_ || phase > *last_completed_phase_)) {
- last_completed_phase_ = phase;
- completed_new_phase_this_cycle_ = true;
- }
-
-#if DCHECK_IS_ON()
- // If we completed a new phase this cycle, then we should not complete any
- // later phases in the same cycle.
- if (completed_new_phase_this_cycle_) {
- DCHECK(last_completed_phase_);
- DCHECK(phase <= *last_completed_phase_);
- }
-#endif
-}
-
-void StrictYieldingDisplayLockBudget::OnLifecycleChange(
- const LifecycleData& lifecycle_data) {
- // Figure out the next phase we would run. If we had completed a phase before,
- // then we should try to complete the next one, otherwise we'll start with the
- // first phase.
- Phase next_phase =
- last_completed_phase_
- ? static_cast<Phase>(
- std::min(static_cast<unsigned>(*last_completed_phase_) + 1,
- static_cast<unsigned>(Phase::kLast)))
- : Phase::kFirst;
-
- // Mark the next phase we're scheduled to run.
- MarkPhaseAsDirty(next_phase);
- completed_new_phase_this_cycle_ = false;
-}
-
-bool StrictYieldingDisplayLockBudget::NeedsLifecycleUpdates() const {
- if (last_completed_phase_ && *last_completed_phase_ == Phase::kLast)
- return false;
-
- auto next_phase = last_completed_phase_
- ? static_cast<Phase>(
- static_cast<unsigned>(*last_completed_phase_) + 1)
- : Phase::kFirst;
- // Check if any future phase needs updates.
- for (auto phase = static_cast<unsigned>(next_phase);
- phase <= static_cast<unsigned>(Phase::kLast); ++phase) {
- if (IsElementDirtyForPhase(static_cast<Phase>(phase)))
- return true;
- }
- return false;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/display_lock/strict_yielding_display_lock_budget.h b/chromium/third_party/blink/renderer/core/display_lock/strict_yielding_display_lock_budget.h
deleted file mode 100644
index c0b9cbac611..00000000000
--- a/chromium/third_party/blink/renderer/core/display_lock/strict_yielding_display_lock_budget.h
+++ /dev/null
@@ -1,42 +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_DISPLAY_LOCK_STRICT_YIELDING_DISPLAY_LOCK_BUDGET_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_DISPLAY_LOCK_STRICT_YIELDING_DISPLAY_LOCK_BUDGET_H_
-
-#include "base/optional.h"
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/display_lock/display_lock_budget.h"
-
-namespace blink {
-
-// This budget yields between lifecycle phases even if that phase is quick. In
-// other words, it will only do one new lifecycle phase at a time, and block the
-// future ones. Any lifecycle phases that have already been allowed by this
-// budget in the past are not blocked.
-class CORE_EXPORT StrictYieldingDisplayLockBudget final
- : public DisplayLockBudget {
- public:
- StrictYieldingDisplayLockBudget(DisplayLockContext*);
- ~StrictYieldingDisplayLockBudget() override = default;
-
- bool ShouldPerformPhase(Phase, const LifecycleData&) override;
- void DidPerformPhase(Phase) override;
- void OnLifecycleChange(const LifecycleData&) override;
- // Returns true if any of the lifecycles that have been previously blocked by
- // this budget need updates. Note that this does not check lifecycle phases
- // that have already completed by this budget even if they are now dirty
- // again. This is done to prevent starvation (ie, it is possible for the
- // budget to always schedule more work if something in rAF keeps dirtying
- // layout, for example).
- bool NeedsLifecycleUpdates() const override;
-
- protected:
- base::Optional<Phase> last_completed_phase_;
- bool completed_new_phase_this_cycle_ = false;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DISPLAY_LOCK_STRICT_YIELDING_DISPLAY_LOCK_BUDGET_H_
diff --git a/chromium/third_party/blink/renderer/core/display_lock/unyielding_display_lock_budget.cc b/chromium/third_party/blink/renderer/core/display_lock/unyielding_display_lock_budget.cc
deleted file mode 100644
index 8ed458bdc75..00000000000
--- a/chromium/third_party/blink/renderer/core/display_lock/unyielding_display_lock_budget.cc
+++ /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.
-
-#include "third_party/blink/renderer/core/display_lock/unyielding_display_lock_budget.h"
-
-#include "third_party/blink/renderer/core/frame/local_frame_view.h"
-
-namespace blink {
-
-UnyieldingDisplayLockBudget::UnyieldingDisplayLockBudget(
- DisplayLockContext* context)
- : DisplayLockBudget(context) {}
-
-bool UnyieldingDisplayLockBudget::ShouldPerformPhase(
- Phase,
- const LifecycleData& lifecycle_data) {
- return true;
-}
-
-void UnyieldingDisplayLockBudget::DidPerformPhase(Phase) {}
-
-void UnyieldingDisplayLockBudget::OnLifecycleChange(
- const LifecycleData& lifecycle_data) {
- // Mark all the phases dirty since we have no intention of yielding.
- for (auto phase = static_cast<unsigned>(Phase::kFirst);
- phase <= static_cast<unsigned>(Phase::kLast); ++phase) {
- MarkDirtyForPhaseIfNeeded(static_cast<Phase>(phase));
- }
-}
-
-bool UnyieldingDisplayLockBudget::NeedsLifecycleUpdates() const {
- for (auto phase = static_cast<unsigned>(Phase::kFirst);
- phase <= static_cast<unsigned>(Phase::kLast); ++phase) {
- if (IsElementDirtyForPhase(static_cast<Phase>(phase)))
- return true;
- }
- return false;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/display_lock/unyielding_display_lock_budget.h b/chromium/third_party/blink/renderer/core/display_lock/unyielding_display_lock_budget.h
deleted file mode 100644
index 7b3351aaae2..00000000000
--- a/chromium/third_party/blink/renderer/core/display_lock/unyielding_display_lock_budget.h
+++ /dev/null
@@ -1,29 +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_DISPLAY_LOCK_UNYIELDING_DISPLAY_LOCK_BUDGET_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_DISPLAY_LOCK_UNYIELDING_DISPLAY_LOCK_BUDGET_H_
-
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/display_lock/display_lock_budget.h"
-
-namespace blink {
-
-// This budget never yields. That is, this is essentially infinite budget that
-// will finish all of the lifecycle phases for the locked subtree if given the
-// chance.
-class CORE_EXPORT UnyieldingDisplayLockBudget final : public DisplayLockBudget {
- public:
- UnyieldingDisplayLockBudget(DisplayLockContext*);
- ~UnyieldingDisplayLockBudget() override = default;
-
- bool ShouldPerformPhase(Phase, const LifecycleData&) override;
- void DidPerformPhase(Phase) override;
- void OnLifecycleChange(const LifecycleData&) override;
- bool NeedsLifecycleUpdates() const override;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DISPLAY_LOCK_UNYIELDING_DISPLAY_LOCK_BUDGET_H_
diff --git a/chromium/third_party/blink/renderer/core/display_lock/yielding_display_lock_budget.cc b/chromium/third_party/blink/renderer/core/display_lock/yielding_display_lock_budget.cc
deleted file mode 100644
index 431f2fcf267..00000000000
--- a/chromium/third_party/blink/renderer/core/display_lock/yielding_display_lock_budget.cc
+++ /dev/null
@@ -1,97 +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/core/display_lock/yielding_display_lock_budget.h"
-
-#include "base/time/tick_clock.h"
-#include "third_party/blink/renderer/core/frame/local_frame_view.h"
-
-#include <algorithm>
-
-namespace blink {
-
-YieldingDisplayLockBudget::YieldingDisplayLockBudget(
- DisplayLockContext* context)
- : DisplayLockBudget(context) {}
-
-bool YieldingDisplayLockBudget::ShouldPerformPhase(
- Phase phase,
- const LifecycleData& lifecycle_data) {
- // Always perform at least one more phase.
- if (phase <= next_phase_from_start_of_lifecycle_)
- return true;
-
- // We should perform any phase earlier than the one we already completed.
- if (last_completed_phase_ && phase <= *last_completed_phase_)
- return true;
-
- // Otherwise, we can still do work while we're not past the deadline.
- return clock_->NowTicks() < deadline_;
-}
-
-void YieldingDisplayLockBudget::DidPerformPhase(Phase phase) {
- if (!last_completed_phase_ || phase > *last_completed_phase_)
- last_completed_phase_ = phase;
-
- // Mark the next phase as dirty so that we can reach it if we need to.
- MarkPhaseAsDirty(
- static_cast<Phase>(static_cast<unsigned>(*last_completed_phase_) + 1));
-}
-
-void YieldingDisplayLockBudget::OnLifecycleChange(
- const LifecycleData& lifecycle_data) {
- if (first_lifecycle_count_ == 0)
- first_lifecycle_count_ = lifecycle_data.count;
- deadline_ = lifecycle_data.start_time + GetCurrentBudget(lifecycle_data);
-
- // Figure out the next phase we would run. If we had completed a phase before,
- // then we should try to complete the next one, otherwise we'll start with the
- // first phase.
- next_phase_from_start_of_lifecycle_ =
- last_completed_phase_
- ? static_cast<Phase>(
- std::min(static_cast<unsigned>(*last_completed_phase_) + 1,
- static_cast<unsigned>(Phase::kLast)))
- : Phase::kFirst;
- MarkPhaseAsDirty(next_phase_from_start_of_lifecycle_);
-}
-
-bool YieldingDisplayLockBudget::NeedsLifecycleUpdates() const {
- if (last_completed_phase_ && *last_completed_phase_ == Phase::kLast)
- return false;
-
- auto next_phase = last_completed_phase_
- ? static_cast<Phase>(
- static_cast<unsigned>(*last_completed_phase_) + 1)
- : Phase::kFirst;
- // Check if any future phase needs updates.
- for (auto phase = static_cast<unsigned>(next_phase);
- phase <= static_cast<unsigned>(Phase::kLast); ++phase) {
- if (IsElementDirtyForPhase(static_cast<Phase>(phase)))
- return true;
- }
- return false;
-}
-
-base::TimeDelta YieldingDisplayLockBudget::GetCurrentBudget(
- const LifecycleData& lifecycle_data) const {
- int lifecycle_count = lifecycle_data.count - first_lifecycle_count_ + 1;
- if (base::TimeTicks::IsHighResolution()) {
- if (lifecycle_count < 3)
- return base::TimeDelta::FromMilliseconds(4);
- if (lifecycle_count < 10)
- return base::TimeDelta::FromMilliseconds(8);
- if (lifecycle_count < 60)
- return base::TimeDelta::FromMilliseconds(16);
- } else {
- // Without a high resolution clock, the resolution can be as bad as 15ms, so
- // increase the budgets accordingly to ensure we don't abort before doing
- // any phases.
- if (lifecycle_count < 60)
- return base::TimeDelta::FromMilliseconds(16);
- }
- return base::TimeDelta::FromMilliseconds(1e9);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/display_lock/yielding_display_lock_budget.h b/chromium/third_party/blink/renderer/core/display_lock/yielding_display_lock_budget.h
deleted file mode 100644
index 5b1893fe988..00000000000
--- a/chromium/third_party/blink/renderer/core/display_lock/yielding_display_lock_budget.h
+++ /dev/null
@@ -1,48 +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_DISPLAY_LOCK_YIELDING_DISPLAY_LOCK_BUDGET_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_DISPLAY_LOCK_YIELDING_DISPLAY_LOCK_BUDGET_H_
-
-#include "base/optional.h"
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/display_lock/display_lock_budget.h"
-
-namespace blink {
-
-// This budget yields between lifecycle phases even if that phase is quick. In
-// other words, it will only do one new lifecycle phase at a time, and block the
-// future ones. Any lifecycle phases that have already been allowed by this
-// budget in the past are not blocked.
-class CORE_EXPORT YieldingDisplayLockBudget final : public DisplayLockBudget {
- public:
- YieldingDisplayLockBudget(DisplayLockContext*);
- ~YieldingDisplayLockBudget() override = default;
-
- bool ShouldPerformPhase(Phase, const LifecycleData& lifecycle_data) override;
- void DidPerformPhase(Phase) override;
- void OnLifecycleChange(const LifecycleData& lifecycle_data) override;
- // Returns true if any of the lifecycles that have been previously blocked by
- // this budget need updates. Note that this does not check lifecycle phases
- // that have already completed by this budget even if they are now dirty
- // again. This is done to prevent starvation (ie, it is possible for the
- // budget to always schedule more work if something in rAF keeps dirtying
- // layout, for example).
- bool NeedsLifecycleUpdates() const override;
-
- protected:
- friend class DisplayLockBudgetTest;
-
- base::TimeDelta GetCurrentBudget(const LifecycleData& lifecycle_data) const;
-
- private:
- unsigned first_lifecycle_count_ = 0;
- base::TimeTicks deadline_;
- base::Optional<Phase> last_completed_phase_;
- Phase next_phase_from_start_of_lifecycle_ = Phase::kFirst;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DISPLAY_LOCK_YIELDING_DISPLAY_LOCK_BUDGET_H_
diff --git a/chromium/third_party/blink/renderer/core/dom/BUILD.gn b/chromium/third_party/blink/renderer/core/dom/BUILD.gn
index a53843730ce..9d751fa8499 100644
--- a/chromium/third_party/blink/renderer/core/dom/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/dom/BUILD.gn
@@ -62,10 +62,6 @@ blink_core_sources("dom") {
"document_parser_client.h",
"document_parser_timing.cc",
"document_parser_timing.h",
- "document_shutdown_notifier.cc",
- "document_shutdown_notifier.h",
- "document_shutdown_observer.cc",
- "document_shutdown_observer.h",
"document_statistics_collector.cc",
"document_statistics_collector.h",
"document_timing.cc",
@@ -238,8 +234,6 @@ blink_core_sources("dom") {
"static_node_list.h",
"static_range.cc",
"static_range.h",
- "synchronous_mutation_notifier.cc",
- "synchronous_mutation_notifier.h",
"synchronous_mutation_observer.cc",
"synchronous_mutation_observer.h",
"tag_collection.cc",
diff --git a/chromium/third_party/blink/renderer/core/dom/abort_controller.idl b/chromium/third_party/blink/renderer/core/dom/abort_controller.idl
index 84afef572ad..f3f881c922d 100644
--- a/chromium/third_party/blink/renderer/core/dom/abort_controller.idl
+++ b/chromium/third_party/blink/renderer/core/dom/abort_controller.idl
@@ -5,11 +5,9 @@
// https://dom.spec.whatwg.org/#interface-abortcontroller
[
- Constructor,
- ConstructorCallWith=ExecutionContext,
- Exposed=(Window,Worker),
- Measure
+ Exposed=(Window,Worker)
] interface AbortController {
+ [CallWith=ExecutionContext, Measure] constructor();
[SameObject] readonly attribute AbortSignal signal;
void abort();
diff --git a/chromium/third_party/blink/renderer/core/dom/aria_attributes.idl b/chromium/third_party/blink/renderer/core/dom/aria_attributes.idl
index 393f49022da..31bee8c6dc3 100644
--- a/chromium/third_party/blink/renderer/core/dom/aria_attributes.idl
+++ b/chromium/third_party/blink/renderer/core/dom/aria_attributes.idl
@@ -16,6 +16,7 @@
[CEReactions, Reflect=aria_colindex] attribute DOMString? ariaColIndex;
[CEReactions, Reflect=aria_colspan] attribute DOMString? ariaColSpan;
[CEReactions, Reflect=aria_current] attribute DOMString? ariaCurrent;
+ [RuntimeEnabled=AccessibilityExposeARIAAnnotations, CEReactions, Reflect=aria_description] attribute DOMString? ariaDescription;
[CEReactions, Reflect=aria_disabled] attribute DOMString? ariaDisabled;
[CEReactions, Reflect=aria_expanded] attribute DOMString? ariaExpanded;
[CEReactions, Reflect=aria_haspopup] attribute DOMString? ariaHasPopup;
diff --git a/chromium/third_party/blink/renderer/core/dom/aria_relationship_attributes.idl b/chromium/third_party/blink/renderer/core/dom/aria_relationship_attributes.idl
index 7a2a504040e..2229d59ed6a 100644
--- a/chromium/third_party/blink/renderer/core/dom/aria_relationship_attributes.idl
+++ b/chromium/third_party/blink/renderer/core/dom/aria_relationship_attributes.idl
@@ -10,7 +10,7 @@
[CEReactions, Reflect=aria_activedescendant] attribute Element? ariaActiveDescendantElement;
[CEReactions, Reflect=aria_controls] attribute FrozenArray<Element>? ariaControlsElements;
[CEReactions, Reflect=aria_describedby] attribute FrozenArray<Element>? ariaDescribedByElements;
- [CEReactions, Reflect=aria_details] attribute Element? ariaDetailsElement;
+ [CEReactions, Reflect=aria_details] attribute FrozenArray<Element>? ariaDetailsElements;
[CEReactions, Reflect=aria_errormessage] attribute Element? ariaErrorMessageElement;
[CEReactions, Reflect=aria_flowto] attribute FrozenArray<Element>? ariaFlowToElements;
[CEReactions, Reflect=aria_labelledby] attribute FrozenArray<Element>? ariaLabelledByElements;
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 bc289cf7748..a66ac3a2b91 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
@@ -18,7 +18,7 @@ void BeforeUnloadEventListener::Invoke(ExecutionContext* execution_context,
Event* event) {
DCHECK_EQ(event->type(), event_type_names::kBeforeunload);
if (show_dialog_)
- ToBeforeUnloadEvent(event)->setReturnValue(g_empty_string);
+ To<BeforeUnloadEvent>(event)->setReturnValue(g_empty_string);
}
void BeforeUnloadEventListener::Trace(Visitor* visitor) {
diff --git a/chromium/third_party/blink/renderer/core/dom/character_data.cc b/chromium/third_party/blink/renderer/core/dom/character_data.cc
index 146bd34ff72..55a99d7eb1c 100644
--- a/chromium/third_party/blink/renderer/core/dom/character_data.cc
+++ b/chromium/third_party/blink/renderer/core/dom/character_data.cc
@@ -38,19 +38,13 @@
namespace blink {
-void CharacterData::MakeParkableOrAtomize() {
+void CharacterData::MakeParkable() {
if (is_parkable_)
return;
- // ParkableStrings have some overhead, don't pay it if we're not going to
- // park a string at all.
- if (ParkableStringManager::ShouldPark(*data_.Impl())) {
- parkable_data_ = ParkableString(data_.ReleaseImpl());
- data_ = String();
- is_parkable_ = true;
- } else {
- data_ = AtomicString(data_);
- }
+ parkable_data_ = ParkableString(data_.ReleaseImpl());
+ data_ = String();
+ is_parkable_ = true;
}
void CharacterData::setData(const String& data) {
@@ -233,8 +227,14 @@ void CharacterData::DidModifyData(const String& old_data, UpdateSource source) {
if (parentNode()) {
ContainerNode::ChildrenChange change = {
- ContainerNode::kTextChanged, this, previousSibling(), nextSibling(),
- ContainerNode::kChildrenChangeSourceAPI};
+ ContainerNode::ChildrenChangeType::kTextChanged,
+ source == kUpdateFromParser
+ ? ContainerNode::ChildrenChangeSource::kParser
+ : ContainerNode::ChildrenChangeSource::kAPI,
+ this,
+ previousSibling(),
+ nextSibling(),
+ nullptr};
parentNode()->ChildrenChanged(change);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/character_data.h b/chromium/third_party/blink/renderer/core/dom/character_data.h
index b3acf286820..cfd038dce61 100644
--- a/chromium/third_party/blink/renderer/core/dom/character_data.h
+++ b/chromium/third_party/blink/renderer/core/dom/character_data.h
@@ -38,9 +38,8 @@ class CORE_EXPORT CharacterData : public Node {
DEFINE_WRAPPERTYPEINFO();
public:
- // Makes the data either Parkable or Atomic. This enables de-duplication in
- // both cases, the first one allowing compression as well.
- void MakeParkableOrAtomize();
+ // Makes the data Parkable. This enables de-duplication and compression.
+ void MakeParkable();
const String& data() const {
return is_parkable_ ? parkable_data_.ToString() : data_;
}
diff --git a/chromium/third_party/blink/renderer/core/dom/child_frame_disconnector.h b/chromium/third_party/blink/renderer/core/dom/child_frame_disconnector.h
index 5d17d81682b..02155cd2151 100644
--- a/chromium/third_party/blink/renderer/core/dom/child_frame_disconnector.h
+++ b/chromium/third_party/blink/renderer/core/dom/child_frame_disconnector.h
@@ -18,7 +18,7 @@ class ChildFrameDisconnector {
public:
enum DisconnectPolicy { kRootAndDescendants, kDescendantsOnly };
- explicit ChildFrameDisconnector(Node& root) : root_(root) {}
+ explicit ChildFrameDisconnector(Node& root) : root_(&root) {}
void Disconnect(DisconnectPolicy = kRootAndDescendants);
@@ -28,7 +28,7 @@ class ChildFrameDisconnector {
Node& Root() const { return *root_; }
HeapVector<Member<HTMLFrameOwnerElement>, 10> frame_owners_;
- Member<Node> root_;
+ Node* root_;
};
} // namespace blink
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 718d39de507..e8290df1d71 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
@@ -119,7 +119,7 @@ class ChildListMutationScope final {
}
private:
- Member<ChildListMutationAccumulator> accumulator_;
+ ChildListMutationAccumulator* accumulator_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(ChildListMutationScope);
};
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 457df191759..fbd31f32306 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
@@ -23,7 +23,6 @@
#include "third_party/blink/renderer/core/dom/child_node_list.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/dom/node_rare_data.h"
@@ -38,10 +37,7 @@ Node* ChildNodeList::VirtualOwnerNode() const {
ChildNodeList::~ChildNodeList() = default;
Node* ChildNodeList::item(unsigned index) const {
- Node* node = collection_index_cache_.NodeAt(*this, index);
- if (node && node->GetDocument().InDOMNodeRemovedHandler())
- node->GetDocument().CountDetachingNodeAccessInDOMNodeRemovedHandler();
- return node;
+ return collection_index_cache_.NodeAt(*this, index);
}
void ChildNodeList::ChildrenChanged(
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 b52dc467877..80d86082530 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
@@ -70,11 +70,12 @@ class ChildNodeList final : public NodeList {
mutable CollectionIndexCache<ChildNodeList, Node> collection_index_cache_;
};
-DEFINE_TYPE_CASTS(ChildNodeList,
- NodeList,
- nodeList,
- nodeList->IsChildNodeList(),
- nodeList.IsChildNodeList());
+template <>
+struct DowncastTraits<ChildNodeList> {
+ static bool AllowFrom(const NodeList& nodeList) {
+ return nodeList.IsChildNodeList();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/dom/class_collection.h b/chromium/third_party/blink/renderer/core/dom/class_collection.h
index d4f30f19010..24f67d9420a 100644
--- a/chromium/third_party/blink/renderer/core/dom/class_collection.h
+++ b/chromium/third_party/blink/renderer/core/dom/class_collection.h
@@ -50,11 +50,12 @@ class ClassCollection final : public HTMLCollection {
SpaceSplitString class_names_;
};
-DEFINE_TYPE_CASTS(ClassCollection,
- LiveNodeListBase,
- collection,
- collection->GetType() == kClassCollectionType,
- collection.GetType() == kClassCollectionType);
+template <>
+struct DowncastTraits<ClassCollection> {
+ static bool AllowFrom(const LiveNodeListBase& collection) {
+ return collection.GetType() == kClassCollectionType;
+ }
+};
inline bool ClassCollection::ElementMatches(const Element& test_element) const {
if (!test_element.HasClass())
diff --git a/chromium/third_party/blink/renderer/core/dom/comment.idl b/chromium/third_party/blink/renderer/core/dom/comment.idl
index 06e5126c605..428d0366b40 100644
--- a/chromium/third_party/blink/renderer/core/dom/comment.idl
+++ b/chromium/third_party/blink/renderer/core/dom/comment.idl
@@ -20,8 +20,7 @@
// https://dom.spec.whatwg.org/#interface-comment
[
- Constructor(optional DOMString data = ""),
- ConstructorCallWith=Document,
Exposed=Window
] interface Comment : CharacterData {
+ [CallWith=Document] constructor(optional DOMString data = "");
};
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 bb3119ce25a..b946eea979a 100644
--- a/chromium/third_party/blink/renderer/core/dom/container_node.cc
+++ b/chromium/third_party/blink/renderer/core/dom/container_node.cc
@@ -47,6 +47,7 @@
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/html/forms/radio_node_list.h"
#include "third_party/blink/renderer/core/html/html_collection.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_tag_collection.h"
#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
@@ -84,9 +85,9 @@ class DOMTreeMutationDetector {
public:
DOMTreeMutationDetector(const Node& node, const Node& parent)
: node_(&node),
- node_document_(node.GetDocument()),
- parent_document_(parent.GetDocument()),
- parent_(parent),
+ node_document_(&node.GetDocument()),
+ parent_document_(&parent.GetDocument()),
+ parent_(&parent),
original_node_document_version_(node_document_->DomTreeVersion()),
original_parent_document_version_(parent_document_->DomTreeVersion()) {}
@@ -105,10 +106,10 @@ class DOMTreeMutationDetector {
}
private:
- const Member<const Node> node_;
- const Member<Document> node_document_;
- const Member<Document> parent_document_;
- const Member<const Node> parent_;
+ const Node* const node_;
+ Document* const node_document_;
+ Document* const parent_document_;
+ const Node* const parent_;
const uint64_t original_node_document_version_;
const uint64_t original_parent_document_version_;
};
@@ -341,7 +342,7 @@ void ContainerNode::DidInsertNodeVector(
targets.size() > 0 ? targets[0]->previousSibling() : nullptr;
for (const auto& target_node : targets) {
ChildrenChanged(ChildrenChange::ForInsertion(
- *target_node, unchanged_previous, next, kChildrenChangeSourceAPI));
+ *target_node, unchanged_previous, next, ChildrenChangeSource::kAPI));
}
for (const auto& descendant : post_insertion_notification_targets) {
if (descendant->isConnected())
@@ -516,7 +517,7 @@ void ContainerNode::ParserInsertBefore(Node* new_child, Node& next_child) {
ChildListMutationScope(*this).ChildAdded(*new_child);
}
- NotifyNodeInserted(*new_child, kChildrenChangeSourceParser);
+ NotifyNodeInserted(*new_child, ChildrenChangeSource::kParser);
}
Node* ContainerNode::ReplaceChild(Node* new_child,
@@ -720,7 +721,7 @@ Node* ContainerNode::RemoveChild(Node* old_child,
NotifyNodeRemoved(*child);
}
ChildrenChanged(ChildrenChange::ForRemoval(*child, prev, next,
- kChildrenChangeSourceAPI));
+ ChildrenChangeSource::kAPI));
}
DispatchSubtreeModifiedEvent();
return child;
@@ -781,7 +782,7 @@ void ContainerNode::ParserRemoveChild(Node& old_child) {
NotifyNodeRemoved(old_child);
}
ChildrenChanged(ChildrenChange::ForRemoval(old_child, prev, next,
- kChildrenChangeSourceParser));
+ ChildrenChangeSource::kParser));
}
// This differs from other remove functions because it forcibly removes all the
@@ -809,6 +810,11 @@ void ContainerNode::RemoveChildren(SubtreeModificationAction action) {
GetDocument().NodeChildrenWillBeRemoved(*this);
}
+ HeapVector<Member<Node>>* removed_nodes = nullptr;
+ if (ChildrenChangedAllChildrenRemovedNeedsList()) {
+ removed_nodes =
+ MakeGarbageCollected<HeapVector<Member<Node>>>(CountChildren());
+ }
{
HTMLFrameOwnerElement::PluginDisposeSuspendScope suspend_plugin_dispose;
TreeOrderedMap::RemoveScope tree_remove_scope;
@@ -821,11 +827,17 @@ void ContainerNode::RemoveChildren(SubtreeModificationAction action) {
while (Node* child = first_child_) {
RemoveBetween(nullptr, child->nextSibling(), *child);
NotifyNodeRemoved(*child);
+ if (removed_nodes)
+ removed_nodes->push_back(child);
}
}
- ChildrenChange change = {kAllChildrenRemoved, nullptr, nullptr, nullptr,
- kChildrenChangeSourceAPI};
+ ChildrenChange change = {ChildrenChangeType::kAllChildrenRemoved,
+ ChildrenChangeSource::kAPI,
+ nullptr,
+ nullptr,
+ nullptr,
+ removed_nodes};
ChildrenChanged(change);
}
@@ -896,7 +908,7 @@ void ContainerNode::ParserAppendChild(Node* new_child) {
ChildListMutationScope(*this).ChildAdded(*new_child);
}
- NotifyNodeInserted(*new_child, kChildrenChangeSourceParser);
+ NotifyNodeInserted(*new_child, ChildrenChangeSource::kParser);
}
DISABLE_CFI_PERF
@@ -1007,13 +1019,16 @@ void ContainerNode::ChildrenChanged(const ChildrenChange& change) {
GetDocument().IncDOMTreeVersion();
GetDocument().NotifyChangeChildren(*this);
InvalidateNodeListCachesInAncestors(nullptr, nullptr, &change);
-
- if (change.IsChildRemoval() || change.type == kAllChildrenRemoved) {
+ if (change.IsChildRemoval() ||
+ change.type == ChildrenChangeType::kAllChildrenRemoved) {
GetDocument().GetStyleEngine().ChildrenRemoved(*this);
return;
}
if (!change.IsChildInsertion())
return;
+ Node* inserted_node = change.sibling_changed;
+ if (inserted_node->IsContainerNode() || inserted_node->IsTextNode())
+ inserted_node->ClearFlatTreeNodeDataIfHostChanged(*this);
if (!InActiveDocument())
return;
if (IsElementNode() && !GetComputedStyle()) {
@@ -1024,11 +1039,12 @@ void ContainerNode::ChildrenChanged(const ChildrenChange& change) {
// the ComputedStyle goes from null to non-null.
return;
}
- Node* inserted_node = change.sibling_changed;
- if (inserted_node->IsContainerNode() || inserted_node->IsTextNode()) {
- inserted_node->ClearFlatTreeNodeDataIfHostChanged(*this);
+ if (inserted_node->IsContainerNode() || inserted_node->IsTextNode())
inserted_node->SetStyleChangeOnInsertion();
- }
+}
+
+bool ContainerNode::ChildrenChangedAllChildrenRemovedNeedsList() const {
+ return false;
}
void ContainerNode::CloneChildNodesFrom(const ContainerNode& node) {
@@ -1101,7 +1117,8 @@ void ContainerNode::FocusWithinStateChanged() {
this_element->PseudoStateChanged(CSSSelector::kPseudoFocusWithin);
}
-void ContainerNode::SetFocused(bool received, WebFocusType focus_type) {
+void ContainerNode::SetFocused(bool received,
+ mojom::blink::FocusType focus_type) {
// Recurse up author shadow trees to mark shadow hosts if it matches :focus.
// TODO(kochi): Handle UA shadows which marks multiple nodes as focused such
// as <input type="date"> the same way as author shadow.
@@ -1227,12 +1244,7 @@ Element* ContainerNode::QuerySelector(const AtomicString& selectors,
selectors, GetDocument(), exception_state);
if (!selector_query)
return nullptr;
- Element* element = selector_query->QueryFirst(*this);
- if (element && element->GetDocument().InDOMNodeRemovedHandler()) {
- if (NodeChildRemovalTracker::IsBeingRemoved(*element))
- GetDocument().CountDetachingNodeAccessInDOMNodeRemovedHandler();
- }
- return element;
+ return selector_query->QueryFirst(*this);
}
Element* ContainerNode::QuerySelector(const AtomicString& selectors) {
@@ -1300,43 +1312,20 @@ static void DispatchChildRemovalEvents(Node& child) {
// Dispatch pre-removal mutation events.
if (c->parentNode() &&
document.HasListenerType(Document::kDOMNodeRemovedListener)) {
- bool original_node_flag = c->InDOMNodeRemovedHandler();
- auto original_document_state = document.GetInDOMNodeRemovedHandlerState();
- if (ScopedEventQueue::Instance()->ShouldQueueEvents()) {
- UseCounter::Count(document, WebFeature::kDOMNodeRemovedEventDelayed);
- } else {
- c->SetInDOMNodeRemovedHandler(true);
- document.SetInDOMNodeRemovedHandlerState(
- Document::InDOMNodeRemovedHandlerState::kDOMNodeRemoved);
- }
NodeChildRemovalTracker scope(child);
c->DispatchScopedEvent(
*MutationEvent::Create(event_type_names::kDOMNodeRemoved,
Event::Bubbles::kYes, c->parentNode()));
- document.SetInDOMNodeRemovedHandlerState(original_document_state);
- c->SetInDOMNodeRemovedHandler(original_node_flag);
}
// Dispatch the DOMNodeRemovedFromDocument event to all descendants.
if (c->isConnected() &&
document.HasListenerType(Document::kDOMNodeRemovedFromDocumentListener)) {
- bool original_node_flag = c->InDOMNodeRemovedHandler();
- auto original_document_state = document.GetInDOMNodeRemovedHandlerState();
- if (ScopedEventQueue::Instance()->ShouldQueueEvents()) {
- UseCounter::Count(document,
- WebFeature::kDOMNodeRemovedFromDocumentEventDelayed);
- } else {
- c->SetInDOMNodeRemovedHandler(true);
- document.SetInDOMNodeRemovedHandlerState(
- Document::InDOMNodeRemovedHandlerState::kDOMNodeRemovedFromDocument);
- }
NodeChildRemovalTracker scope(child);
for (; c; c = NodeTraversal::Next(*c, &child)) {
c->DispatchScopedEvent(*MutationEvent::Create(
event_type_names::kDOMNodeRemovedFromDocument, Event::Bubbles::kNo));
}
- document.SetInDOMNodeRemovedHandlerState(original_document_state);
- child.SetInDOMNodeRemovedHandler(original_node_flag);
}
}
@@ -1486,7 +1475,7 @@ void ContainerNode::InvalidateNodeListCachesInAncestors(
const ChildrenChange* change) {
// This is a performance optimization, NodeList cache invalidation is
// not necessary for a text change.
- if (change && change->type == kTextChanged)
+ if (change && change->type == ChildrenChangeType::kTextChanged)
return;
if (HasRareData() && (!attr_name || IsAttributeNode())) {
@@ -1521,7 +1510,7 @@ HTMLCollection* ContainerNode::getElementsByTagName(
const AtomicString& qualified_name) {
DCHECK(!qualified_name.IsNull());
- if (GetDocument().IsHTMLDocument()) {
+ if (IsA<HTMLDocument>(GetDocument())) {
return EnsureCachedCollection<HTMLTagCollection>(kHTMLTagCollectionType,
qualified_name);
}
@@ -1540,15 +1529,14 @@ HTMLCollection* ContainerNode::getElementsByTagNameNS(
// Takes an AtomicString in argument because it is common for elements to share
// the same name attribute. Therefore, the NameNodeList factory function
// expects an AtomicString type.
-NameNodeList* ContainerNode::getElementsByName(
- const AtomicString& element_name) {
+NodeList* ContainerNode::getElementsByName(const AtomicString& element_name) {
return EnsureCachedCollection<NameNodeList>(kNameNodeListType, element_name);
}
// Takes an AtomicString in argument because it is common for elements to share
// the same set of class names. Therefore, the ClassNodeList factory function
// expects an AtomicString type.
-ClassCollection* ContainerNode::getElementsByClassName(
+HTMLCollection* ContainerNode::getElementsByClassName(
const AtomicString& class_names) {
return EnsureCachedCollection<ClassCollection>(kClassCollectionType,
class_names);
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 8649528aac9..c3582de6bfc 100644
--- a/chromium/third_party/blink/renderer/core/dom/container_node.h
+++ b/chromium/third_party/blink/renderer/core/dom/container_node.h
@@ -25,27 +25,25 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_CONTAINER_NODE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_CONTAINER_NODE_H_
-#include "third_party/blink/public/platform/web_focus_type.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/css/style_recalc.h"
#include "third_party/blink/renderer/core/dom/node.h"
+#include "third_party/blink/renderer/core/dom/static_node_list.h"
#include "third_party/blink/renderer/core/html/collection_type.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
-class ClassCollection;
-class ExceptionState;
class Element;
+class ExceptionState;
class HTMLCollection;
-class NameNodeList;
-template <typename NodeType>
-class StaticNodeTypeList;
-using StaticElementList = StaticNodeTypeList<Element>;
class RadioNodeList;
class WhitespaceAttacher;
+using StaticElementList = StaticNodeTypeList<Element>;
+
enum class DynamicRestyleFlags {
kChildrenOrSiblingsAffectedByFocus = 1 << 0,
kChildrenOrSiblingsAffectedByHover = 1 << 1,
@@ -131,8 +129,8 @@ class CORE_EXPORT ContainerNode : public Node {
HTMLCollection* getElementsByTagName(const AtomicString&);
HTMLCollection* getElementsByTagNameNS(const AtomicString& namespace_uri,
const AtomicString& local_name);
- NameNodeList* getElementsByName(const AtomicString& element_name);
- ClassCollection* getElementsByClassName(const AtomicString& class_names);
+ NodeList* getElementsByName(const AtomicString& element_name);
+ HTMLCollection* getElementsByClassName(const AtomicString& class_names);
RadioNodeList* GetRadioNodeList(const AtomicString&,
bool only_match_img_elements = false);
@@ -151,7 +149,7 @@ class CORE_EXPORT ContainerNode : public Node {
void AttachLayoutTree(AttachContext&) override;
void DetachLayoutTree(bool performing_reattach = false) override;
PhysicalRect BoundingBox() const final;
- void SetFocused(bool, WebFocusType) override;
+ void SetFocused(bool, mojom::blink::FocusType) override;
void SetHasFocusWithinUpToAncestor(bool, Node* ancestor);
void FocusStateChanged();
void FocusVisibleStateChanged();
@@ -296,7 +294,7 @@ class CORE_EXPORT ContainerNode : public Node {
// Notification of document structure changes (see core/dom/node.h for more
// notification methods)
- enum ChildrenChangeType {
+ enum class ChildrenChangeType : uint8_t {
kElementInserted,
kNonElementInserted,
kElementRemoved,
@@ -304,10 +302,7 @@ class CORE_EXPORT ContainerNode : public Node {
kAllChildrenRemoved,
kTextChanged
};
- enum ChildrenChangeSource {
- kChildrenChangeSourceAPI,
- kChildrenChangeSourceParser
- };
+ enum class ChildrenChangeSource : uint8_t { kAPI, kParser };
struct ChildrenChange {
STACK_ALLOCATED();
@@ -316,9 +311,14 @@ class CORE_EXPORT ContainerNode : public Node {
Node* unchanged_previous,
Node* unchanged_next,
ChildrenChangeSource by_parser) {
- ChildrenChange change = {
- node.IsElementNode() ? kElementInserted : kNonElementInserted, &node,
- unchanged_previous, unchanged_next, by_parser};
+ ChildrenChange change = {node.IsElementNode()
+ ? ChildrenChangeType::kElementInserted
+ : ChildrenChangeType::kNonElementInserted,
+ by_parser,
+ &node,
+ unchanged_previous,
+ unchanged_next,
+ nullptr};
return change;
}
@@ -326,43 +326,63 @@ class CORE_EXPORT ContainerNode : public Node {
Node* previous_sibling,
Node* next_sibling,
ChildrenChangeSource by_parser) {
- ChildrenChange change = {
- node.IsElementNode() ? kElementRemoved : kNonElementRemoved, &node,
- previous_sibling, next_sibling, by_parser};
+ ChildrenChange change = {node.IsElementNode()
+ ? ChildrenChangeType::kElementRemoved
+ : ChildrenChangeType::kNonElementRemoved,
+ by_parser,
+ &node,
+ previous_sibling,
+ next_sibling,
+ nullptr};
return change;
}
bool IsChildInsertion() const {
- return type == kElementInserted || type == kNonElementInserted;
+ return type == ChildrenChangeType::kElementInserted ||
+ type == ChildrenChangeType::kNonElementInserted;
}
bool IsChildRemoval() const {
- return type == kElementRemoved || type == kNonElementRemoved;
+ return type == ChildrenChangeType::kElementRemoved ||
+ type == ChildrenChangeType::kNonElementRemoved;
}
bool IsChildElementChange() const {
- return type == kElementInserted || type == kElementRemoved;
+ return type == ChildrenChangeType::kElementInserted ||
+ type == ChildrenChangeType::kElementRemoved;
}
+ bool ByParser() const { return by_parser == ChildrenChangeSource::kParser; }
+
ChildrenChangeType type;
- Member<Node> sibling_changed;
+ ChildrenChangeSource by_parser;
+ Node* sibling_changed = nullptr;
// |siblingBeforeChange| is
// - siblingChanged.previousSibling before node removal
// - siblingChanged.previousSibling after single node insertion
// - previousSibling of the first inserted node after multiple node
// insertion
- Member<Node> sibling_before_change;
+ Node* sibling_before_change = nullptr;
// |siblingAfterChange| is
// - siblingChanged.nextSibling before node removal
// - siblingChanged.nextSibling after single node insertion
// - nextSibling of the last inserted node after multiple node insertion.
- Member<Node> sibling_after_change;
- ChildrenChangeSource by_parser;
+ Node* sibling_after_change = nullptr;
+ // List of removed nodes for ChildrenChangeType::kAllChildrenRemoved.
+ // This is available only if ChildrenChangedAllChildrenRemovedNeedsList()
+ // returns true.
+ HeapVector<Member<Node>>* removed_nodes;
};
// Notifies the node that it's list of children have changed (either by adding
// or removing child nodes), or a child node that is of the type
- // CDATA_SECTION_NODE, TEXT_NODE or COMMENT_NODE has changed its value.
+ // kCdataSectionNode, kTextNode or kCommentNode has changed its value.
+ //
+ // ChildrenChanged() implementations may modify the DOM tree, and may dispatch
+ // synchronous events.
virtual void ChildrenChanged(const ChildrenChange&);
+ // Provides ChildrenChange::removed_nodes for kAllChildrenRemoved.
+ virtual bool ChildrenChangedAllChildrenRemovedNeedsList() const;
+
virtual bool ChildrenCanHaveStyle() const { return true; }
void Trace(Visitor*) override;
@@ -429,7 +449,7 @@ class CORE_EXPORT ContainerNode : public Node {
void AddChildNodesToDeletionQueue(Node*&, Node*&, ContainerNode&);
void NotifyNodeInserted(Node&,
- ChildrenChangeSource = kChildrenChangeSourceAPI);
+ ChildrenChangeSource = ChildrenChangeSource::kAPI);
void NotifyNodeInsertedInternal(
Node&,
NodeVector& post_insertion_notification_targets);
diff --git a/chromium/third_party/blink/renderer/core/dom/document.cc b/chromium/third_party/blink/renderer/core/dom/document.cc
index 2247f71c3c9..f55c90df996 100644
--- a/chromium/third_party/blink/renderer/core/dom/document.cc
+++ b/chromium/third_party/blink/renderer/core/dom/document.cc
@@ -41,6 +41,8 @@
#include "components/performance_manager/public/mojom/coordination_unit.mojom-blink.h"
#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 "net/base/registry_controlled_domains/registry_controlled_domain.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"
@@ -48,16 +50,16 @@
#include "services/network/public/mojom/ip_address_space.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/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"
-#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
+#include "third_party/blink/public/mojom/feature_policy/policy_disposition.mojom-blink.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/public/mojom/insecure_input/insecure_input_service.mojom-blink.h"
#include "third_party/blink/public/mojom/ukm/ukm.mojom-blink.h"
-#include "third_party/blink/public/platform/interface_provider.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_content_settings_client.h"
-#include "third_party/blink/public/platform/web_prerendering_support.h"
#include "third_party/blink/public/platform/web_theme_engine.h"
#include "third_party/blink/renderer/bindings/core/v8/html_script_element_or_svg_script_element.h"
#include "third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h"
@@ -68,6 +70,7 @@
#include "third_party/blink/renderer/bindings/core/v8/string_or_element_creation_options.h"
#include "third_party/blink/renderer/bindings/core/v8/v0_custom_element_constructor_builder.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_element_creation_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_element_registration_options.h"
#include "third_party/blink/renderer/bindings/core/v8/window_proxy.h"
#include "third_party/blink/renderer/core/accessibility/ax_context.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
@@ -95,6 +98,7 @@
#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/css/style_sheet_list.h"
+#include "third_party/blink/renderer/core/display_lock/display_lock_context.h"
#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
#include "third_party/blink/renderer/core/dom/attr.h"
#include "third_party/blink/renderer/core/dom/beforeunload_event_listener.h"
@@ -107,9 +111,7 @@
#include "third_party/blink/renderer/core/dom/document_type.h"
#include "third_party/blink/renderer/core/dom/dom_implementation.h"
#include "third_party/blink/renderer/core/dom/element.h"
-#include "third_party/blink/renderer/core/dom/element_creation_options.h"
#include "third_party/blink/renderer/core/dom/element_data_cache.h"
-#include "third_party/blink/renderer/core/dom/element_registration_options.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
@@ -151,12 +153,14 @@
#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"
#include "third_party/blink/renderer/core/frame/csp/navigation_initiator_impl.h"
+#include "third_party/blink/renderer/core/frame/document_policy_violation_report_body.h"
#include "third_party/blink/renderer/core/frame/dom_timer.h"
#include "third_party/blink/renderer/core/frame/dom_visual_viewport.h"
#include "third_party/blink/renderer/core/frame/event_handler_registry.h"
@@ -187,6 +191,7 @@
#include "third_party/blink/renderer/core/html/document_all_name_collection.h"
#include "third_party/blink/renderer/core/html/document_name_collection.h"
#include "third_party/blink/renderer/core/html/forms/form_controller.h"
+#include "third_party/blink/renderer/core/html/forms/html_form_element.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_anchor_element.h"
@@ -222,9 +227,12 @@
#include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/input/touch_list.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
+#include "third_party/blink/renderer/core/inspector/inspector_issue.h"
+#include "third_party/blink/renderer/core/inspector/inspector_issue_storage.h"
#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
-#include "third_party/blink/renderer/core/inspector/main_thread_debugger.h"
+#include "third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.h"
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.h"
+#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.h"
#include "third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h"
#include "third_party/blink/renderer/core/layout/hit_test_canvas_result.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
@@ -243,6 +251,7 @@
#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"
#include "third_party/blink/renderer/core/mathml_names.h"
#include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h"
@@ -261,8 +270,10 @@
#include "third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.h"
#include "third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.h"
#include "third_party/blink/renderer/core/page/spatial_navigation_controller.h"
+#include "third_party/blink/renderer/core/page/validation_message_client.h"
#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.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/resize_observer/resize_observer_controller.h"
@@ -275,11 +286,10 @@
#include "third_party/blink/renderer/core/svg/svg_use_element.h"
#include "third_party/blink/renderer/core/svg_element_factory.h"
#include "third_party/blink/renderer/core/svg_names.h"
-#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
-#include "third_party/blink/renderer/core/timing/window_performance.h"
#include "third_party/blink/renderer/core/trustedtypes/trusted_html.h"
#include "third_party/blink/renderer/core/xml/parser/xml_document_parser.h"
#include "third_party/blink/renderer/core/xml_names.h"
+#include "third_party/blink/renderer/core/xmlhttprequest/main_thread_disallow_synchronous_xhr_scope.h"
#include "third_party/blink/renderer/core/xmlns_names.h"
#include "third_party/blink/renderer/platform/bindings/dom_data_store.h"
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
@@ -303,7 +313,6 @@
#include "third_party/blink/renderer/platform/network/http_parsers.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/dummy_schedulers.h"
#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"
@@ -573,12 +582,12 @@ static bool g_threaded_parsing_enabled_for_testing = true;
class Document::NetworkStateObserver final
: public GarbageCollected<Document::NetworkStateObserver>,
public NetworkStateNotifier::NetworkStateObserver,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(Document::NetworkStateObserver);
public:
- explicit NetworkStateObserver(Document& document)
- : ContextLifecycleObserver(&document) {
+ explicit NetworkStateObserver(ExecutionContext* context)
+ : ExecutionContextLifecycleObserver(context) {
online_observer_handle_ = GetNetworkStateNotifier().AddOnLineObserver(
this, GetExecutionContext()->GetTaskRunner(TaskType::kNetworking));
}
@@ -586,15 +595,13 @@ class Document::NetworkStateObserver final
void OnLineStateChange(bool on_line) override {
AtomicString event_name =
on_line ? event_type_names::kOnline : event_type_names::kOffline;
- Document* document = To<Document>(GetExecutionContext());
- if (!document->domWindow())
- return;
- document->domWindow()->DispatchEvent(*Event::Create(event_name));
- probe::NetworkStateChanged(document->GetFrame(), on_line);
+ auto* window = To<LocalDOMWindow>(GetExecutionContext());
+ window->DispatchEvent(*Event::Create(event_name));
+ probe::NetworkStateChanged(window->GetFrame(), on_line);
}
- void ContextDestroyed(ExecutionContext* context) override {
- UnregisterAsObserver(context);
+ void ContextDestroyed() override {
+ UnregisterAsObserver(GetExecutionContext());
}
void UnregisterAsObserver(ExecutionContext* context) {
@@ -603,7 +610,7 @@ class Document::NetworkStateObserver final
}
void Trace(Visitor* visitor) override {
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
private:
@@ -611,460 +618,6 @@ class Document::NetworkStateObserver final
online_observer_handle_;
};
-// A helper class that allows the security context be initialized in the
-// process of constructing the document.
-class Document::SecurityContextInit : public FeaturePolicyParserDelegate {
- STACK_ALLOCATED();
-
- public:
- SecurityContextInit(const DocumentInit& initializer,
- DocumentClassFlags document_classes) {
- // 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, document_classes);
-
- // Sandbox flags can come from initializer, loader or CSP.
- InitializeSandboxFlags(initializer);
-
- // The origin can be opaque based on sandbox flags.
- InitializeOrigin(initializer);
-
- // The secure context state is based on the origin.
- InitializeSecureContextState(initializer);
-
- // Initialize origin trials, requires the post sandbox flags
- // security origin and secure context state.
- InitializeOriginTrials(initializer);
-
- // Initialize feature policy, depends on origin trials.
- InitializeFeaturePolicy(initializer, document_classes);
-
- // Initialize the agent. Depends on security origin.
- InitializeAgent(initializer);
- }
-
- const scoped_refptr<SecurityOrigin>& GetSecurityOrigin() const {
- return security_origin_;
- }
-
- WebSandboxFlags GetSandboxFlags() { return sandbox_flags_; }
-
- ContentSecurityPolicy* GetCSP() const { return csp_; }
-
- std::unique_ptr<FeaturePolicy> TakeFeaturePolicy() {
- DCHECK(feature_policy_);
- return std::move(feature_policy_);
- }
-
- const Vector<String>& FeaturePolicyParseMessages() const {
- return feature_policy_parse_messages_;
- }
- const ParsedFeaturePolicy& ParsedHeader() const { return parsed_header_; }
-
- OriginTrialContext* GetOriginTrialContext() { return origin_trials_; }
-
- WindowAgentFactory* GetWindowAgentFactory() { return window_agent_factory_; }
- Agent* GetAgent() { return agent_; }
- SecureContextState GetSecureContextState() {
- return secure_context_state_.value();
- }
-
- void CountFeaturePolicyUsage(mojom::WebFeature feature) override {
- feature_count_.insert(feature);
- }
-
- bool FeaturePolicyFeatureObserved(
- mojom::FeaturePolicyFeature feature) override {
- if (parsed_feature_policies_.Contains(feature))
- return true;
- parsed_feature_policies_.insert(feature);
- return false;
- }
-
- bool FeatureEnabled(OriginTrialFeature feature) const override {
- return origin_trials_->IsFeatureEnabled(feature);
- }
-
- void ApplyPendingDataToDocument(Document& document) {
- for (auto feature : feature_count_)
- UseCounter::Count(document, feature);
- for (auto feature : parsed_feature_policies_)
- document.FeaturePolicyFeatureObserved(feature);
- }
-
- bool BindCSPImmediately() const { return bind_csp_immediately_; }
-
- private:
- void InitializeContentSecurityPolicy(const DocumentInit& initializer,
- DocumentClassFlags document_classes) {
- auto* frame = initializer.GetFrame();
- ContentSecurityPolicy* last_origin_document_csp =
- frame ? frame->Loader().GetLastOriginDocumentCSP() : nullptr;
-
- KURL url;
- if (initializer.ShouldSetURL())
- url = initializer.Url().IsEmpty() ? BlankURL() : initializer.Url();
-
- // Alias certain security properties from |owner_document|. Used for the
- // case of about:blank pages inheriting the security properties of their
- // requestor context.
- //
- // Note that this is currently somewhat broken; Blink always inherits from
- // the parent or opener, even though it should actually be inherited from
- // the request initiator.
- if (url.IsEmpty() && initializer.HasSecurityContext() &&
- !initializer.OriginToCommit() && initializer.OwnerDocument()) {
- last_origin_document_csp =
- initializer.OwnerDocument()->GetContentSecurityPolicy();
- }
-
- csp_ = initializer.GetContentSecurityPolicy();
-
- if (!csp_) {
- if (initializer.ImportsController()) {
- // If this document is an HTML import, grab a reference to its master
- // document's Content Security Policy. We don't bind the CSP's delegate
- // in 'InitSecurityPolicy' in this case, as we can't rebind the master
- // document's policy object: The Content Security Policy's delegate
- // needs to remain set to the master document.
- csp_ = initializer.ImportsController()
- ->Master()
- ->GetContentSecurityPolicy();
- return;
- }
-
- csp_ = MakeGarbageCollected<ContentSecurityPolicy>();
- bind_csp_immediately_ = true;
- }
-
- // We should inherit the navigation initiator CSP if the document is loaded
- // using a local-scheme url.
- //
- // Note: about:srcdoc inherits CSP from its parent, not from its initiator.
- // In this case, the initializer.GetContentSecurityPolicy() is used.
- if (last_origin_document_csp && !url.IsAboutSrcdocURL() &&
- (url.IsEmpty() || url.ProtocolIsAbout() || url.ProtocolIsData() ||
- url.ProtocolIs("blob") || url.ProtocolIs("filesystem"))) {
- csp_->CopyStateFrom(last_origin_document_csp);
- }
-
- if (document_classes & kPluginDocumentClass) {
- if (last_origin_document_csp) {
- csp_->CopyPluginTypesFrom(last_origin_document_csp);
- return;
- }
-
- // TODO(andypaicu): This should inherit the origin document's plugin types
- // but because this could be a OOPIF document it might not have access. In
- // this situation we fallback on using the parent/opener:
- if (frame) {
- Frame* inherit_from = frame->Tree().Parent()
- ? frame->Tree().Parent()
- : frame->Client()->Opener();
- if (inherit_from && frame != inherit_from) {
- csp_->CopyPluginTypesFrom(
- inherit_from->GetSecurityContext()->GetContentSecurityPolicy());
- }
- }
- }
- }
-
- void 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_ |=
- (WebSandboxFlags::kAll &
- ~(WebSandboxFlags::kPopups |
- WebSandboxFlags::kPropagatesToAuxiliaryBrowsingContexts));
- }
- }
-
- void InitializeOrigin(const DocumentInit& initializer) {
- scoped_refptr<SecurityOrigin> document_origin =
- initializer.GetDocumentOrigin();
- if ((sandbox_flags_ & WebSandboxFlags::kOrigin) != 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 (IsPagePopupRunningInWebTest(frame)) {
- 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 InitializeFeaturePolicy(const DocumentInit& initializer,
- DocumentClassFlags document_classes) {
- auto* frame = initializer.GetFrame();
- // For a main frame, get inherited feature policy from the opener if any.
- const FeaturePolicy::FeatureState* opener_feature_state = nullptr;
- if (frame && frame->IsMainFrame() && !frame->OpenerFeatureState().empty()) {
- opener_feature_state = &frame->OpenerFeatureState();
- }
-
- parsed_header_ = FeaturePolicyParser::ParseHeader(
- initializer.FeaturePolicyHeader(), security_origin_,
- &feature_policy_parse_messages_, this);
-
- if (sandbox_flags_ != WebSandboxFlags::kNone &&
- RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) {
- // The sandbox flags might have come from CSP header or the browser; in
- // such cases the sandbox is not part of the container policy. They are
- // added to the header policy (which specifically makes sense in the case
- // of CSP sandbox).
- ApplySandboxFlagsToParsedFeaturePolicy(sandbox_flags_, parsed_header_);
- }
-
- ParsedFeaturePolicy container_policy;
-
- if (frame && frame->Owner()) {
- // TODO(chenleihu): Due to the data replication mechanism in
- // multi-process site-per-process environment, the container_policy
- // value in remote frame owner gets lazily updated only when the next
- // navigation is initiated on the remote frame. We need a more robust way
- // to enforce the validity of container_policy value.
- // https://crbug.com/972089
- if (frame->Owner()->IsRemote()) {
- container_policy = frame->Owner()->GetFramePolicy().container_policy;
- } else {
- container_policy = initializer.GetFramePolicy()
- .value_or(FramePolicy())
- .container_policy;
- }
- }
-
- // TODO(icelland): This is problematic querying sandbox flags before
- // feature policy is initialized.
- if (RuntimeEnabledFeatures::BlockingFocusWithoutUserActivationEnabled() &&
- frame && frame->Tree().Parent() &&
- (sandbox_flags_ & WebSandboxFlags::kNavigation) !=
- WebSandboxFlags::kNone) {
- // Enforcing the policy for sandbox frames (for context see
- // https://crbug.com/954349).
- DisallowFeatureIfNotPresent(
- mojom::FeaturePolicyFeature::kFocusWithoutUserActivation,
- container_policy);
- }
-
- const FeaturePolicy* parent_feature_policy = nullptr;
- if (frame && !frame->IsMainFrame()) {
- parent_feature_policy =
- frame->Tree().Parent()->GetSecurityContext()->GetFeaturePolicy();
- }
-
- // If we are a HTMLViewSourceDocument we use container, header or
- // inherited policies. https://crbug.com/898688
- if (document_classes & kViewSourceDocumentClass) {
- feature_policy_ = FeaturePolicy::CreateFromParentPolicy(
- nullptr, {}, security_origin_->ToUrlOrigin());
- return;
- }
-
- // Feature policy should either come from a parent in the case of an
- // embedded child frame, or from an opener if any when a new window is
- // created by an opener. A main frame without an opener would not have a
- // parent policy nor an opener feature state.
- DCHECK(!parent_feature_policy || !opener_feature_state);
- if (!opener_feature_state ||
- !RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) {
- feature_policy_ = FeaturePolicy::CreateFromParentPolicy(
- parent_feature_policy, container_policy,
- security_origin_->ToUrlOrigin());
- } else {
- DCHECK(!parent_feature_policy);
- feature_policy_ = FeaturePolicy::CreateWithOpenerPolicy(
- *opener_feature_state, security_origin_->ToUrlOrigin());
- }
- feature_policy_->SetHeaderPolicy(parsed_header_);
- }
-
- void InitializeSecureContextState(const DocumentInit& initializer) {
- auto* frame = initializer.GetFrame();
- if (!security_origin_->IsPotentiallyTrustworthy()) {
- secure_context_state_ = SecureContextState::kNonSecure;
- } else if (SchemeRegistry::SchemeShouldBypassSecureContextCheck(
- security_origin_->Protocol())) {
- secure_context_state_ = SecureContextState::kSecure;
- } else if (frame) {
- Frame* parent = frame->Tree().Parent();
- while (parent) {
- if (!parent->GetSecurityContext()
- ->GetSecurityOrigin()
- ->IsPotentiallyTrustworthy()) {
- secure_context_state_ = SecureContextState::kNonSecure;
- break;
- }
- parent = parent->Tree().Parent();
- }
- if (!secure_context_state_.has_value())
- secure_context_state_ = SecureContextState::kSecure;
- } else {
- secure_context_state_ = SecureContextState::kNonSecure;
- }
- bool is_secure = secure_context_state_ == SecureContextState::kSecure;
- if (GetSandboxFlags() != WebSandboxFlags::kNone) {
- feature_count_.insert(
- is_secure ? WebFeature::kSecureContextCheckForSandboxedOriginPassed
- : WebFeature::kSecureContextCheckForSandboxedOriginFailed);
- }
- feature_count_.insert(is_secure ? WebFeature::kSecureContextCheckPassed
- : WebFeature::kSecureContextCheckFailed);
- }
-
- void InitializeOriginTrials(const DocumentInit& initializer) {
- DCHECK(secure_context_state_.has_value());
- origin_trials_ = MakeGarbageCollected<OriginTrialContext>();
-
- const String& header_value = initializer.OriginTrialsHeader();
-
- if (header_value.IsEmpty())
- return;
- std::unique_ptr<Vector<String>> tokens(
- OriginTrialContext::ParseHeaderValue(header_value));
- if (!tokens)
- return;
- origin_trials_->AddTokens(
- security_origin_.get(),
- secure_context_state_ == SecureContextState::kSecure /*is_secure*/,
- *tokens);
- }
-
- void InitializeAgent(const DocumentInit& initializer) {
- auto* frame = initializer.GetFrame();
-
- // 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.
- if (IsPagePopupRunningInWebTest(frame)) {
- frame = frame->PagePopupOwner()->GetDocument().GetFrame();
- } else if (!frame) {
- if (Document* context_document = initializer.ContextDocument()) {
- frame = context_document->GetFrame();
- window_agent_factory_ = context_document->window_agent_factory_;
- } else if (const Document* owner_document = initializer.OwnerDocument()) {
- frame = owner_document->GetFrame();
- window_agent_factory_ = owner_document->window_agent_factory_;
- }
- }
-
- if (!window_agent_factory_ && frame)
- window_agent_factory_ = &frame->window_agent_factory();
-
- // 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 (window_agent_factory_) {
- bool has_potential_universal_access_privilege = false;
- if (frame) {
- if (Settings* settings = frame->GetSettings()) {
- // 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());
- }
-
- bool IsPagePopupRunningInWebTest(LocalFrame* frame) {
- return frame && frame->GetPage()->GetChromeClient().IsPopup() &&
- WebTestSupport::IsRunningWebTest();
- }
-
- scoped_refptr<SecurityOrigin> security_origin_;
- WebSandboxFlags sandbox_flags_ = WebSandboxFlags::kNone;
- std::unique_ptr<FeaturePolicy> feature_policy_;
- Vector<String> feature_policy_parse_messages_;
- ParsedFeaturePolicy parsed_header_;
- Member<ContentSecurityPolicy> csp_;
- Member<OriginTrialContext> origin_trials_;
- Member<Agent> agent_;
- Member<WindowAgentFactory> window_agent_factory_;
- HashSet<mojom::FeaturePolicyFeature> parsed_feature_policies_;
- HashSet<mojom::WebFeature> feature_count_;
- bool bind_csp_immediately_ = false;
- base::Optional<SecureContextState> secure_context_state_;
-};
-
ExplicitlySetAttrElementsMap* Document::GetExplicitlySetAttrElementsMap(
Element* element) {
DCHECK(element);
@@ -1093,28 +646,24 @@ Document::Document() : Document(DocumentInit::Create()) {}
Document::Document(const DocumentInit& initializer,
DocumentClassFlags document_classes)
: Document(initializer,
- SecurityContextInit(initializer, document_classes),
+ SecurityContextInit(initializer),
document_classes) {}
Document::Document(const DocumentInit& initializer,
- SecurityContextInit security_initializer,
+ const SecurityContextInit& security_initializer,
DocumentClassFlags document_classes)
: ContainerNode(nullptr, kCreateDocument),
TreeScope(*this),
- SecurityContext(security_initializer.GetSecurityOrigin(),
- security_initializer.GetSandboxFlags(),
- security_initializer.TakeFeaturePolicy()),
- ExecutionContext(V8PerIsolateData::MainThreadIsolate(),
- security_initializer.GetAgent(),
- security_initializer.GetOriginTrialContext()),
evaluate_media_queries_on_style_recalc_(false),
pending_sheet_layout_(kNoLayoutWithPendingSheets),
- window_agent_factory_(security_initializer.GetWindowAgentFactory()),
+ 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),
imports_controller_(initializer.ImportsController()),
+ security_context_(security_initializer, SecurityContext::kLocal),
+ use_counter_during_construction_(initializer.GetUseCounter()),
context_document_(initializer.ContextDocument()),
context_features_(ContextFeatures::DefaultSwitch()),
http_refresh_scheduler_(MakeGarbageCollected<HttpRefreshScheduler>(this)),
@@ -1123,7 +672,7 @@ Document::Document(const DocumentInit& initializer,
is_painting_preview_(false),
compatibility_mode_(kNoQuirksMode),
compatibility_mode_locked_(false),
- last_focus_type_(kWebFocusTypeNone),
+ last_focus_type_(mojom::blink::FocusType::kNone),
had_keyboard_event_(false),
clear_focused_element_timer_(
GetTaskRunner(TaskType::kInternalUserInteraction),
@@ -1135,7 +684,17 @@ Document::Document(const DocumentInit& initializer,
mutation_observer_types_(0),
visited_link_state_(MakeGarbageCollected<VisitedLinkState>(*this)),
visually_ordered_(false),
- ready_state_(kComplete),
+ // https://html.spec.whatwg.org/multipage/dom.html#current-document-readiness
+ // says the ready state starts as 'loading' if there's an associated
+ // parser and 'complete' otherwise. We don't know whether there's an
+ // 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),
parsing_state_(kFinishedParsing),
contains_plugins_(false),
ignore_destructive_write_count_(0),
@@ -1175,12 +734,15 @@ Document::Document(const DocumentInit& initializer,
document_timing_(*this),
write_recursion_is_too_deep_(false),
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),
this,
&Document::ElementDataCacheClearTimerFired),
+ document_animations_(MakeGarbageCollected<DocumentAnimations>(this)),
timeline_(MakeGarbageCollected<DocumentTimeline>(this)),
pending_animations_(MakeGarbageCollected<PendingAnimations>(*this)),
worklet_animation_controller_(
@@ -1194,14 +756,23 @@ Document::Document(const DocumentInit& initializer,
parser_sync_policy_(kAllowAsynchronousParsing),
node_count_(0),
logged_field_edit_(false),
- secure_context_state_(security_initializer.GetSecureContextState()),
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>>>()) {
+ HeapHashMap<int, Member<ContentSecurityPolicy>>>()),
+ permission_service_(GetExecutionContext()),
+ font_preload_manager_(*this) {
security_initializer.ApplyPendingDataToDocument(*this);
+ GetOriginTrialContext()->BindExecutionContext(GetExecutionContext());
+
+ if (frame_) {
+ pending_fp_headers_ = security_initializer.FeaturePolicyHeader();
+ pending_dp_headers_ = initializer.GetDocumentPolicy().feature_state;
+ }
+
if (frame_) {
DCHECK(frame_->GetPage());
ProvideContextFeaturesToDocumentFrom(*this, *frame_->GetPage());
@@ -1213,11 +784,7 @@ Document::Document(const DocumentInit& initializer,
: nullptr;
if (registry && registration_context_)
registry->Entangle(registration_context_);
- cookie_jar_ = std::make_unique<CookieJar>(this);
- } else if (imports_controller_ &&
- !base::FeatureList::IsEnabled(
- features::kHtmlImportsRequestInitiatorLock)) {
- fetcher_ = FrameFetchContext::CreateFetcherForImportedDocument(this);
+ cookie_jar_ = MakeGarbageCollected<CookieJar>(this);
} else {
// We disable fetches for frame-less Documents, including HTML-imported
// Documents (if kHtmlImportsRequestInitiatorLock is enabled). Subresources
@@ -1253,15 +820,21 @@ Document::Document(const DocumentInit& initializer,
UpdateBaseURL();
}
- InitSecurityContext(initializer, security_initializer);
- FeaturePolicyInitialized(initializer, security_initializer);
+ if (initializer.GetWebBundleClaimedUrl().IsValid()) {
+ web_bundle_claimed_url_ = initializer.GetWebBundleClaimedUrl();
+ SetBaseURLOverride(initializer.GetWebBundleClaimedUrl());
+ }
+ InitSecurityContext(initializer);
+ PoliciesInitialized(initializer);
InitDNSPrefetch();
InstanceCounters::IncrementCounter(InstanceCounters::kDocumentCounter);
lifecycle_.AdvanceTo(DocumentLifecycle::kInactive);
+ UpdateForcedColors();
+
// Since CSSFontSelector requires Document::fetcher_ and StyleEngine owns
// CSSFontSelector, need to initialize |style_engine_| after initializing
// |fetcher_|.
@@ -1279,6 +852,9 @@ Document::Document(const DocumentInit& initializer,
if (frame_ && frame_->GetPage()->GetAgentMetricsCollector())
frame_->GetPage()->GetAgentMetricsCollector()->DidAttachDocument(*this);
+
+ // We will use Loader() as UseCounter after initialization.
+ use_counter_during_construction_ = nullptr;
}
Document::~Document() {
@@ -1319,8 +895,8 @@ MediaQueryMatcher& Document::GetMediaQueryMatcher() {
return *media_query_matcher_;
}
-void Document::MediaQueryAffectingValueChanged() {
- GetStyleEngine().MediaQueryAffectingValueChanged();
+void Document::MediaQueryAffectingValueChanged(MediaValueChange change) {
+ GetStyleEngine().MediaQueryAffectingValueChanged(change);
if (NeedsLayoutTreeUpdate())
evaluate_media_queries_on_style_recalc_ = true;
else
@@ -1372,12 +948,10 @@ Location* Document::location() const {
return domWindow()->location();
}
-bool Document::ShouldInstallV8Extensions() const {
- return frame_->Client()->AllowScriptExtensions();
-}
-
ContentSecurityPolicy* Document::GetContentSecurityPolicyForWorld() {
v8::Isolate* isolate = GetIsolate();
+ if (!isolate)
+ return GetContentSecurityPolicy();
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> v8_context = isolate->GetCurrentContext();
@@ -1404,6 +978,161 @@ ContentSecurityPolicy* Document::GetContentSecurityPolicyForWorld() {
return policy;
}
+// static
+Document& Document::From(ExecutionContext& context) {
+ SECURITY_DCHECK(context.IsDocument());
+ return *static_cast<LocalDOMWindow&>(context).document();
+}
+
+// static
+const Document& Document::From(const ExecutionContext& context) {
+ SECURITY_DCHECK(context.IsDocument());
+ return *static_cast<const LocalDOMWindow&>(context).document();
+}
+
+ExecutionContext* Document::ToExecutionContext() {
+ return GetExecutionContext();
+}
+
+const ExecutionContext* Document::ToExecutionContext() const {
+ return GetExecutionContext();
+}
+
+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;
+}
+
+const SecurityOrigin* Document::GetSecurityOrigin() const {
+ return GetSecurityContext().GetSecurityOrigin();
+}
+
+SecurityOrigin* Document::GetMutableSecurityOrigin() {
+ return GetSecurityContext().GetMutableSecurityOrigin();
+}
+
+ContentSecurityPolicy* Document::GetContentSecurityPolicy() const {
+ return GetSecurityContext().GetContentSecurityPolicy();
+}
+
+mojom::blink::WebSandboxFlags Document::GetSandboxFlags() const {
+ return GetSecurityContext().GetSandboxFlags();
+}
+
+bool Document::IsSandboxed(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();
+}
+
+void Document::SetSecureContextModeForTesting(SecureContextMode mode) {
+ GetSecurityContext().SetSecureContextModeForTesting(mode);
+}
+
+bool Document::IsFeatureEnabled(mojom::blink::FeaturePolicyFeature feature,
+ ReportOptions report_on_failure,
+ const String& message,
+ const String& source_file) const {
+ return GetExecutionContext() &&
+ GetExecutionContext()->IsFeatureEnabled(feature, report_on_failure,
+ message, source_file);
+}
+
+bool Document::IsFeatureEnabled(mojom::blink::FeaturePolicyFeature feature,
+ PolicyValue threshold_value,
+ ReportOptions report_on_failure,
+ const String& message,
+ const String& source_file) const {
+ return GetExecutionContext() &&
+ GetExecutionContext()->IsFeatureEnabled(
+ feature, threshold_value, report_on_failure, message, source_file);
+}
+
+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();
+}
+
void Document::ChildrenChanged(const ChildrenChange& change) {
ContainerNode::ChildrenChanged(change);
document_element_ = ElementTraversal::FirstWithin(*this);
@@ -1413,7 +1142,7 @@ void Document::ChildrenChanged(const ChildrenChange& change) {
// documents there may never be a <body> (since the parser won't always
// insert one), so we resume here too. That does mean XHTML documents make
// frames when there's only a <head>, but such documents are pretty rare.
- if (document_element_ && !IsHTMLDocument())
+ if (document_element_ && !IsA<HTMLDocument>(this))
BeginLifecycleUpdatesIfRenderingReady();
}
@@ -1430,7 +1159,7 @@ bool Document::IsInMainFrame() const {
}
AtomicString Document::ConvertLocalName(const AtomicString& name) {
- return IsHTMLDocument() ? name.LowerASCII() : name;
+ return IsA<HTMLDocument>(this) ? name.LowerASCII() : name;
}
// Just creates an element with specified qualified name without any
@@ -1463,10 +1192,11 @@ Element* Document::CreateRawElement(const QualifiedName& qname,
} else if (RuntimeEnabledFeatures::MathMLCoreEnabled() &&
qname.NamespaceURI() == mathml_names::kNamespaceURI) {
element = MathMLElementFactory::Create(qname.LocalName(), *this, flags);
+ // An unknown MathML element is treated like an <mrow> element.
// TODO(crbug.com/1021837): Determine if we need to introduce a
- // MathMLUnknownClass.
+ // MathMLUnknownElement IDL.
if (!element)
- element = MakeGarbageCollected<MathMLElement>(qname, *this);
+ element = MakeGarbageCollected<MathMLRowElement>(qname, *this);
saw_elements_in_known_namespaces_ = true;
} else {
element = MakeGarbageCollected<Element>(qname, this);
@@ -1489,7 +1219,7 @@ Element* Document::CreateElementForBinding(const AtomicString& name,
return nullptr;
}
- if (IsXHTMLDocument() || IsHTMLDocument()) {
+ if (IsXHTMLDocument() || IsA<HTMLDocument>(this)) {
// 2. If the context object is an HTML document, let localName be
// converted to ASCII lowercase.
AtomicString local_name = ConvertLocalName(name);
@@ -1554,7 +1284,7 @@ Element* Document::CreateElementForBinding(
// 2. localName converted to ASCII lowercase
const AtomicString& converted_local_name = ConvertLocalName(local_name);
QualifiedName q_name(g_null_atom, converted_local_name,
- IsXHTMLDocument() || IsHTMLDocument()
+ IsXHTMLDocument() || IsA<HTMLDocument>(this)
? html_names::xhtmlNamespaceURI
: g_null_atom);
@@ -1798,7 +1528,7 @@ Comment* Document::createComment(const String& data) {
CDATASection* Document::createCDATASection(const String& data,
ExceptionState& exception_state) {
- if (IsHTMLDocument()) {
+ if (IsA<HTMLDocument>(this)) {
exception_state.ThrowDOMException(
DOMExceptionCode::kNotSupportedError,
"This operation is not supported for HTML documents.");
@@ -1830,7 +1560,7 @@ ProcessingInstruction* Document::createProcessingInstruction(
"The data provided ('" + data + "') contains '?>'.");
return nullptr;
}
- if (IsHTMLDocument()) {
+ if (IsA<HTMLDocument>(this)) {
UseCounter::Count(*this,
WebFeature::kHTMLDocumentCreateProcessingInstruction);
}
@@ -1910,7 +1640,7 @@ Node* Document::adoptNode(Node* source, ExceptionState& exception_state) {
return nullptr;
// The above removeChild() can execute arbitrary JavaScript code.
if (source->parentNode()) {
- AddConsoleMessage(ConsoleMessage::Create(
+ AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning,
ExceptionMessages::FailedToExecute("adoptNode", "Document",
@@ -2049,7 +1779,7 @@ void Document::SetContent(const String& content) {
}
String Document::SuggestedMIMEType() const {
- if (IsXMLDocument()) {
+ if (IsA<XMLDocument>(this)) {
if (IsXHTMLDocument())
return "application/xhtml+xml";
if (IsSVGDocument())
@@ -2058,7 +1788,7 @@ String Document::SuggestedMIMEType() const {
}
if (xmlStandalone())
return "text/xml";
- if (IsHTMLDocument())
+ if (IsA<HTMLDocument>(this))
return "text/html";
if (DocumentLoader* document_loader = Loader())
@@ -2197,6 +1927,11 @@ void Document::UpdateTitle(const String& title) {
}
void Document::DispatchDidReceiveTitle() {
+ if (GetFrame() && !GetFrame()->Tree().Parent()) {
+ String shortened_title = title_.Substring(0, mojom::blink::kMaxTitleChars);
+ GetFrame()->GetLocalFrameHostRemote().UpdateTitle(
+ shortened_title, mojo_base::mojom::blink::TextDirection::LEFT_TO_RIGHT);
+ }
frame_->Client()->DispatchDidReceiveTitle(title_);
}
@@ -2256,7 +1991,7 @@ void Document::RemoveTitle(Element* title_element) {
title_element_ = nullptr;
// Update title based on first title element in the document, if one exists.
- if (IsHTMLDocument() || IsXHTMLDocument()) {
+ if (IsA<HTMLDocument>(this) || IsXHTMLDocument()) {
if (HTMLTitleElement* title =
Traversal<HTMLTitleElement>::FirstWithin(*this))
SetTitleElement(title);
@@ -2450,7 +2185,7 @@ bool Document::NeedsFullLayoutTreeUpdate() const {
return true;
if (IsSlotAssignmentOrLegacyDistributionDirty())
return true;
- if (DocumentAnimations::NeedsAnimationTimingUpdate(*this))
+ if (document_animations_->NeedsAnimationTimingUpdate())
return true;
return false;
}
@@ -2476,6 +2211,11 @@ void Document::ScheduleLayoutTreeUpdate() {
if (!View()->CanThrottleRendering())
GetPage()->Animator().ScheduleVisualUpdate(GetFrame());
+
+ // FrameSelection caches visual selection information, which must be
+ // invalidated on dirty layout tree.
+ GetFrame()->Selection().MarkCacheDirty();
+
lifecycle_.EnsureStateAtMost(DocumentLifecycle::kVisualUpdatePending);
TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
@@ -2503,8 +2243,7 @@ void Document::UpdateStyleInvalidationIfNeeded() {
void Document::SetupFontBuilder(ComputedStyle& document_style) {
FontBuilder font_builder(this);
- CSSFontSelector* selector = GetStyleEngine().GetFontSelector();
- font_builder.CreateFontForDocument(selector, document_style);
+ font_builder.CreateFontForDocument(document_style);
}
#define PROPAGATE_FROM(source, getter, setter, initial) \
@@ -2714,9 +2453,9 @@ void Document::PropagateStyleToViewport() {
// Misc
{
PROPAGATE_FROM(document_element_style, GetEffectiveTouchAction,
- SetEffectiveTouchAction, TouchAction::kTouchActionAuto);
+ SetEffectiveTouchAction, TouchAction::kAuto);
PROPAGATE_FROM(document_element_style, GetScrollBehavior, SetScrollBehavior,
- kScrollBehaviorAuto);
+ mojom::blink::ScrollBehavior::kAuto);
PROPAGATE_FROM(document_element_style, DarkColorScheme, SetDarkColorScheme,
false);
}
@@ -2746,27 +2485,43 @@ void Document::PropagateStyleToViewport() {
#undef PROPAGATE_FROM
#if DCHECK_IS_ON()
+static void AssertNodeClean(const Node& node) {
+ DCHECK(!node.NeedsStyleRecalc());
+ DCHECK(!node.ChildNeedsStyleRecalc());
+ DCHECK(!node.NeedsReattachLayoutTree());
+ DCHECK(!node.ChildNeedsReattachLayoutTree());
+ DCHECK(!node.ChildNeedsDistributionRecalc());
+ DCHECK(!node.NeedsStyleInvalidation());
+ DCHECK(!node.ChildNeedsStyleInvalidation());
+ DCHECK(!node.GetForceReattachLayoutTree());
+}
+
+static void AssertLayoutTreeUpdatedForPseudoElements(const Element& element) {
+ WTF::Vector<PseudoId> pseudo_ids = {kPseudoIdFirstLetter, kPseudoIdBefore,
+ kPseudoIdAfter, kPseudoIdMarker,
+ kPseudoIdBackdrop};
+ for (auto pseudo_id : pseudo_ids) {
+ if (auto* pseudo_element = element.GetPseudoElement(pseudo_id))
+ AssertNodeClean(*pseudo_element);
+ }
+}
+
static void AssertLayoutTreeUpdated(Node& root) {
Node* node = &root;
while (node) {
- auto* element = DynamicTo<Element>(node);
- if (element &&
- RuntimeEnabledFeatures::DisplayLockingEnabled(
- root.GetExecutionContext()) &&
- element->StyleRecalcBlockedByDisplayLock(
- DisplayLockLifecycleTarget::kChildren)) {
- node = FlatTreeTraversal::NextSkippingChildren(*node);
- continue;
+ if (auto* element = DynamicTo<Element>(node)) {
+ if (RuntimeEnabledFeatures::CSSSubtreeVisibilityEnabled() &&
+ element->StyleRecalcBlockedByDisplayLock(
+ DisplayLockLifecycleTarget::kChildren)) {
+ node = FlatTreeTraversal::NextSkippingChildren(*node);
+ continue;
+ }
+ // Check pseudo elements.
+ AssertLayoutTreeUpdatedForPseudoElements(*element);
}
- DCHECK(!node->NeedsStyleRecalc());
- DCHECK(!node->ChildNeedsStyleRecalc());
- DCHECK(!node->NeedsReattachLayoutTree());
- DCHECK(!node->ChildNeedsReattachLayoutTree());
- DCHECK(!node->ChildNeedsDistributionRecalc());
- DCHECK(!node->NeedsStyleInvalidation());
- DCHECK(!node->ChildNeedsStyleInvalidation());
- DCHECK(!node->GetForceReattachLayoutTree());
+ AssertNodeClean(*node);
+
// Make sure there is no node which has a LayoutObject, but doesn't have a
// parent in a flat tree. If there is such a node, we forgot to detach the
// node. DocumentNode is only an exception.
@@ -2845,13 +2600,14 @@ void Document::UpdateStyleAndLayoutTree() {
probe::RecalculateStyle recalculate_style_scope(this);
- DocumentAnimations::UpdateAnimationTimingIfNeeded(*this);
+ document_animations_->UpdateAnimationTimingIfNeeded();
EvaluateMediaQueryListIfNeeded();
UpdateUseShadowTreesIfNeeded();
UpdateDistributionForLegacyDistributedNodes();
UpdateActiveStyle();
+ InvalidateStyleAndLayoutForFontUpdates();
UpdateStyleInvalidationIfNeeded();
UpdateStyle();
@@ -2861,7 +2617,7 @@ void Document::UpdateStyleAndLayoutTree() {
ClearFocusedElementSoon();
GetLayoutView()->ClearHitTestCache();
- DCHECK(!DocumentAnimations::NeedsAnimationTimingUpdate(*this));
+ DCHECK(!document_animations_->NeedsAnimationTimingUpdate());
unsigned element_count =
GetStyleEngine().StyleForElementCount() - start_element_count;
@@ -2881,6 +2637,12 @@ void Document::UpdateActiveStyle() {
GetStyleEngine().UpdateActiveStyle();
}
+void Document::InvalidateStyleAndLayoutForFontUpdates() {
+ DCHECK(IsActive());
+ DCHECK(IsMainThread());
+ GetStyleEngine().InvalidateStyleAndLayoutForFontUpdates();
+}
+
void Document::UpdateStyle() {
DCHECK(!View()->ShouldThrottleRendering());
TRACE_EVENT_BEGIN0("blink,blink_style", "Document::updateStyle");
@@ -3024,20 +2786,127 @@ void Document::UpdateStyleAndLayoutTreeForSubtree(const Node* node) {
}
}
-void Document::UpdateStyleAndLayoutForNode(const Node* node) {
+void Document::UpdateStyleAndLayoutForNode(const Node* node,
+ DocumentUpdateReason reason) {
DCHECK(node);
if (!node->InActiveDocument())
return;
DisplayLockUtilities::ScopedChainForcedUpdate scoped_update_forced(node);
- UpdateStyleAndLayout();
+ UpdateStyleAndLayout(reason);
}
-void Document::UpdateStyleAndLayout(ForcedLayoutStatus status) {
+void Document::ApplyScrollRestorationLogic() {
+ // This function in not re-entrant. However, the places that invoke this are
+ // re-entrant. Specifically, UpdateStyleAndLayout() calls this, which in turn
+ // can do a find-in-page for the scroll-to-text feature, which can cause
+ // UpdateStyleAndLayout to happen with subtree-visibility, which gets back here
+ // and recurses indefinitely. As a result, we ensure to early out from this
+ // function if are currently in process of restoring scroll.
+ if (applying_scroll_restoration_logic_)
+ return;
+ base::AutoReset<bool> applying_scroll_restoration_logic_scope(
+ &applying_scroll_restoration_logic_, true);
+
+ // If we're restoring a scroll position from history, that takes precedence
+ // over scrolling to the anchor in the URL.
+ View()->InvokeFragmentAnchor();
+
+ auto& frame_loader = GetFrame()->Loader();
+ auto* document_loader = frame_loader.GetDocumentLoader();
+ if (!document_loader)
+ return;
+ if (frame_->IsLoading() &&
+ !FrameLoader::NeedsHistoryItemRestore(document_loader->LoadType()))
+ return;
+
+ auto* history_item = document_loader->GetHistoryItem();
+
+ if (!history_item || !history_item->GetViewState())
+ return;
+
+ if (!View()->GetScrollableArea()->HasPendingHistoryRestoreScrollOffset())
+ return;
+
+ bool should_restore_scroll =
+ history_item->ScrollRestorationType() != kScrollRestorationManual;
+ auto& scroll_offset = history_item->GetViewState()->scroll_offset_;
+
+ // This tries to balance:
+ // 1. restoring as soon as possible.
+ // 2. not overriding user scroll (TODO(majidvp): also respect user scale).
+ // 3. detecting clamping to avoid repeatedly popping the scroll position
+ // down
+ // as the page height increases.
+ // 4. ignoring clamp detection if scroll state is not being restored, if
+ // load
+ // is complete, or if the navigation is same-document (as the new page
+ // may be smaller than the previous page).
+ bool can_restore_without_clamping =
+ View()->LayoutViewport()->ClampScrollOffset(scroll_offset) ==
+ scroll_offset;
+
+ bool can_restore_without_annoying_user =
+ !document_loader->GetInitialScrollState().was_scrolled_by_user &&
+ (can_restore_without_clamping || !frame_->IsLoading() ||
+ !should_restore_scroll);
+ if (!can_restore_without_annoying_user)
+ return;
+
+ // Apply scroll restoration to the LayoutView's scroller. Note that we do
+ // *not* apply it to the RootFrameViewport's LayoutViewport, because that
+ // may be for child frame's implicit root scroller, which is not the right
+ // one to apply to because scroll restoration does not affect implicit root
+ // scrollers.
+ auto* layout_scroller = View()->LayoutViewport();
+ layout_scroller->ApplyPendingHistoryRestoreScrollOffset();
+
+ // Also apply restoration to the visual viewport of the root frame, if needed.
+ auto* root_frame_scroller = View()->GetScrollableArea();
+ if (root_frame_scroller != layout_scroller)
+ root_frame_scroller->ApplyPendingHistoryRestoreScrollOffset();
+
+ document_loader->GetInitialScrollState().did_restore_from_history = true;
+}
+
+void Document::MarkHasFindInPageRequest() {
+ // Note that although find-in-page requests happen in non-main frames, we only
+ // record the main frame results (per UKM policy). Additionally, we only
+ // record the event once.
+ if (had_find_in_page_request_ || !IsInMainFrame())
+ return;
+
+ auto* recorder = UkmRecorder();
+ DCHECK(recorder);
+ DCHECK(UkmSourceID() != ukm::kInvalidSourceId);
+ ukm::builders::Blink_FindInPage(UkmSourceID())
+ .SetDidSearch(true)
+ .Record(recorder);
+ had_find_in_page_request_ = true;
+}
+
+void Document::MarkHasFindInPageSubtreeVisibilityActiveMatch() {
+ // Note that although find-in-page in subtree-visibility requests happen in
+ // non-main frames, we only record the main frame results (per UKM policy).
+ // Additionally, we only record the event once.
+ if (had_find_in_page_render_subtree_active_match_ || !IsInMainFrame())
+ return;
+
+ auto* recorder = UkmRecorder();
+ DCHECK(recorder);
+ DCHECK(UkmSourceID() != ukm::kInvalidSourceId);
+ // TODO(vmpstr): Rename UKM values if possible.
+ ukm::builders::Blink_FindInPage(UkmSourceID())
+ .SetDidHaveRenderSubtreeMatch(true)
+ .Record(recorder);
+ had_find_in_page_render_subtree_active_match_ = true;
+}
+
+void Document::UpdateStyleAndLayout(DocumentUpdateReason reason) {
DCHECK(IsMainThread());
LocalFrameView* frame_view = View();
- if (status == IsForcedLayout && frame_view)
+ if (reason != DocumentUpdateReason::kBeginMainFrame && frame_view)
frame_view->WillStartForcedLayout();
HTMLFrameOwnerElement::PluginDisposeSuspendScope suspend_plugin_dispose;
@@ -3047,12 +2916,15 @@ void Document::UpdateStyleAndLayout(ForcedLayoutStatus status) {
<< "View layout should not be re-entrant";
if (HTMLFrameOwnerElement* owner = LocalOwner())
- owner->GetDocument().UpdateStyleAndLayout();
+ owner->GetDocument().UpdateStyleAndLayout(reason);
UpdateStyleAndLayoutTree();
- if (!IsActive())
+ if (!IsActive()) {
+ if (reason != DocumentUpdateReason::kBeginMainFrame && frame_view)
+ frame_view->DidFinishForcedLayout(reason);
return;
+ }
if (frame_view && frame_view->NeedsLayout())
frame_view->UpdateLayout();
@@ -3060,11 +2932,14 @@ void Document::UpdateStyleAndLayout(ForcedLayoutStatus status) {
if (Lifecycle().GetState() < DocumentLifecycle::kLayoutClean)
Lifecycle().AdvanceTo(DocumentLifecycle::kLayoutClean);
+ ApplyScrollRestorationLogic();
+
if (LocalFrameView* frame_view_anchored = View())
frame_view_anchored->PerformScrollAnchoringAdjustments();
+ PerformScrollSnappingTasks();
- if (status == IsForcedLayout && frame_view)
- frame_view->DidFinishForcedLayout();
+ if (reason != DocumentUpdateReason::kBeginMainFrame && frame_view)
+ frame_view->DidFinishForcedLayout(reason);
if (update_focus_appearance_after_layout_)
UpdateFocusAppearance();
@@ -3074,11 +2949,6 @@ void Document::LayoutUpdated() {
DCHECK(GetFrame());
DCHECK(View());
- // If we're restoring a scroll position from history, that takes precedence
- // over scrolling to the anchor in the URL.
- View()->InvokeFragmentAnchor();
- GetFrame()->Loader().RestoreScrollPositionAndViewState();
-
// Plugins can run script inside layout which can detach the page.
// TODO(dcheng): Does it make sense to do any of this work if detached?
if (GetFrame()) {
@@ -3089,23 +2959,40 @@ void Document::LayoutUpdated() {
// don't have a good place that has access to its local root's FrameWidget.
// TODO(dcheng): If we create FrameWidget before Frame then we could move
// this to Document::Initialize().
- if (Platform::Current()->IsThreadedAnimationEnabled() &&
- GetSettings()->GetAcceleratedCompositingEnabled()) {
- GetPage()->GetChromeClient().AttachCompositorAnimationTimeline(
- Timeline().CompositorTimeline(), GetFrame());
- }
+ AttachCompositorTimeline(Timeline().CompositorTimeline());
}
Markers().InvalidateRectsForAllTextMatchMarkers();
+}
- // TODO(esprehn): This doesn't really make sense, why not track the first
- // beginFrame? This will catch the first layout in a page that does lots
- // of layout thrashing even though that layout might not be followed by
- // a paint for many seconds.
- if (HaveRenderBlockingResourcesLoaded()) {
- if (document_timing_.FirstLayout().is_null())
- document_timing_.MarkFirstLayout();
- }
+void Document::AttachCompositorTimeline(
+ CompositorAnimationTimeline* timeline) const {
+ if (!Platform::Current()->IsThreadedAnimationEnabled() ||
+ !GetSettings()->GetAcceleratedCompositingEnabled())
+ return;
+
+ if (timeline->GetAnimationTimeline()->IsScrollTimeline() &&
+ timeline->GetAnimationTimeline()->animation_host())
+ return;
+
+ GetPage()->GetChromeClient().AttachCompositorAnimationTimeline(timeline,
+ GetFrame());
+}
+
+void Document::DetachCompositorTimeline(
+ CompositorAnimationTimeline* timeline) const {
+ if (!Platform::Current()->IsThreadedAnimationEnabled() ||
+ !GetSettings()->GetAcceleratedCompositingEnabled())
+ return;
+
+ // This requires detaching all animations from timeline first before detaching
+ // timeline.
+ if (timeline->GetAnimationTimeline()->IsScrollTimeline() &&
+ timeline->GetAnimationTimeline()->HasAnimation())
+ return;
+
+ GetPage()->GetChromeClient().DetachCompositorAnimationTimeline(timeline,
+ GetFrame());
}
void Document::ClearFocusedElementSoon() {
@@ -3125,7 +3012,9 @@ scoped_refptr<const ComputedStyle> Document::StyleForPage(int page_index) {
return EnsureStyleResolver().StyleForPage(page_index);
}
-void Document::EnsurePaintLocationDataValidForNode(const Node* node) {
+void Document::EnsurePaintLocationDataValidForNode(
+ const Node* node,
+ DocumentUpdateReason reason) {
DCHECK(node);
if (!node->InActiveDocument())
return;
@@ -3134,7 +3023,7 @@ void Document::EnsurePaintLocationDataValidForNode(const Node* node) {
// For all nodes we must have up-to-date style and have performed layout to do
// any location-based calculation.
- UpdateStyleAndLayout();
+ UpdateStyleAndLayout(reason);
// The location of elements that are position: sticky is not known until
// compositing inputs are cleaned. Therefore, for any elements that are either
@@ -3145,9 +3034,9 @@ void Document::EnsurePaintLocationDataValidForNode(const Node* node) {
bool success = false;
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
// In CAP, compositing inputs are cleaned as part of PrePaint.
- success = View()->UpdateAllLifecyclePhasesExceptPaint();
+ success = View()->UpdateAllLifecyclePhasesExceptPaint(reason);
} else {
- success = View()->UpdateLifecycleToCompositingInputsClean();
+ success = View()->UpdateLifecycleToCompositingInputsClean(reason);
}
// The lifecycle update should always succeed, because forced lifecycles
// from script are never throttled.
@@ -3170,18 +3059,18 @@ void Document::PageSizeAndMarginsInPixels(int page_index,
double width = page_size.Width();
double height = page_size.Height();
- switch (style->PageSizeType()) {
- case EPageSizeType::kAuto:
+ switch (style->GetPageSizeType()) {
+ case PageSizeType::kAuto:
break;
- case EPageSizeType::kLandscape:
+ case PageSizeType::kLandscape:
if (width < height)
std::swap(width, height);
break;
- case EPageSizeType::kPortrait:
+ case PageSizeType::kPortrait:
if (width > height)
std::swap(width, height);
break;
- case EPageSizeType::kResolved: {
+ case PageSizeType::kFixed: {
FloatSize size = style->PageSize();
width = size.Width();
height = size.Height();
@@ -3215,27 +3104,43 @@ void Document::SetIsViewSource(bool is_view_source) {
return;
}
-void Document::SetIsImmersiveArOverlay(bool val) {
+void Document::SetIsXrOverlay(bool val, Element* overlay_element) {
if (!documentElement())
return;
- if (val != is_immersive_ar_overlay_) {
- DCHECK(RuntimeEnabledFeatures::WebXRARDOMOverlayEnabled(this));
- is_immersive_ar_overlay_ = val;
+ if (val == is_xr_overlay_)
+ return;
- // If the property has changed, apply the pseudo-style change to the root
- // element. This will cascade further UA stylesheet changes such as setting
- // the fullscreened element and its backdrop transparent.
- documentElement()->PseudoStateChanged(
- CSSSelector::kPseudoXrImmersiveDomOverlay);
+ is_xr_overlay_ = val;
- // Ensure that the graphics layer tree gets fully rebuilt on changes,
- // similar to HTMLVideoElement::DidEnterFullscreen(). This may not be
- // strictly necessary if the compositing changes are based on visibility
- // settings, but helps ensure consistency in case it's changed to
- // detaching layers or re-rooting the graphics layer tree.
- GetLayoutView()->Compositor()->SetNeedsCompositingUpdate(
- kCompositingUpdateRebuildTree);
+ // On navigation, the layout view may be invalid, skip style changes.
+ if (!GetLayoutView())
+ return;
+
+ if (val) {
+ // The UA style sheet for the :xr-overlay pseudoclass uses lazy loading.
+ // If we get here, we need to ensure that it's present.
+ GetStyleEngine().EnsureUAStyleForXrOverlay();
+ }
+
+ if (overlay_element) {
+ // Now that the custom style sheet is loaded, update the pseudostyle for
+ // the overlay element.
+ overlay_element->PseudoStateChanged(CSSSelector::kPseudoXrOverlay);
+ }
+
+ // The DOM overlay may change the effective root element. Need to update
+ // compositing inputs to avoid a mismatch in CompositingRequirementsUpdater.
+ GetLayoutView()->Layer()->SetNeedsCompositingInputsUpdate();
+
+ // Ensure that the graphics layer tree gets fully rebuilt on changes,
+ // similar to HTMLVideoElement::DidEnterFullscreen(). This may not be
+ // strictly necessary if the compositing changes are based on visibility
+ // settings, but helps ensure consistency in case it's changed to
+ // detaching layers or re-rooting the graphics layer tree.
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ auto* compositor = GetLayoutView()->Compositor();
+ compositor->SetNeedsCompositingUpdate(kCompositingUpdateRebuildTree);
}
}
@@ -3249,17 +3154,15 @@ void Document::UnscheduleUseShadowTreeUpdate(SVGUseElement& element) {
}
void Document::UpdateUseShadowTreesIfNeeded() {
- if (use_elements_needing_update_.IsEmpty())
- return;
-
ScriptForbiddenScope forbid_script;
- HeapHashSet<Member<SVGUseElement>> elements;
- use_elements_needing_update_.swap(elements);
- for (SVGUseElement* element : elements)
- element->BuildPendingResource();
-
- DCHECK(use_elements_needing_update_.IsEmpty());
+ // Breadth-first search since nested use elements add to the queue.
+ while (!use_elements_needing_update_.IsEmpty()) {
+ HeapHashSet<Member<SVGUseElement>> elements;
+ use_elements_needing_update_.swap(elements);
+ for (SVGUseElement* element : elements)
+ element->BuildPendingResource();
+ }
}
StyleResolver* Document::GetStyleResolver() const {
@@ -3294,14 +3197,14 @@ void Document::Initialize() {
View()->DidAttachDocument();
// Observer(s) should not be initialized until the document is initialized /
- // attached to a frame. Otherwise ContextLifecycleObserver::contextDestroyed
- // wouldn't be fired.
- network_state_observer_ = MakeGarbageCollected<NetworkStateObserver>(*this);
+ // attached to a frame. Otherwise
+ // ExecutionContextLifecycleObserver::contextDestroyed wouldn't be fired.
+ network_state_observer_ =
+ MakeGarbageCollected<NetworkStateObserver>(GetExecutionContext());
- // Check for frame_ so we only attach execution contexts with its own
- // scheduler.
+ // Check for frame_ so we only attach documents with its own scheduler.
if (frame_)
- GetAgent()->AttachExecutionContext(this);
+ GetAgent()->AttachDocument(this);
}
void Document::Shutdown() {
@@ -3368,11 +3271,6 @@ void Document::Shutdown() {
probe::DocumentDetached(this);
- // FIXME: consider using ContextLifecycleStateObserver.
- if (scripted_animation_controller_)
- scripted_animation_controller_->ClearDocumentPointer();
- scripted_animation_controller_.Clear();
-
scripted_idle_task_controller_.Clear();
if (SvgExtensions())
@@ -3380,16 +3278,14 @@ void Document::Shutdown() {
CancelPendingJavaScriptUrls();
http_refresh_scheduler_->Cancel();
+ GetFrame()->CancelFormSubmission();
- if (Platform::Current()->IsThreadedAnimationEnabled() &&
- GetSettings()->GetAcceleratedCompositingEnabled()) {
- GetPage()->GetChromeClient().DetachCompositorAnimationTimeline(
- Timeline().CompositorTimeline(), GetFrame());
- }
+ DetachCompositorTimeline(Timeline().CompositorTimeline());
if (frame_->IsLocalRoot())
GetPage()->GetChromeClient().AttachRootLayer(nullptr, frame_.Get());
- layout_view_->CleanUpCompositor();
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ layout_view_->CleanUpCompositor();
if (RegistrationContext())
RegistrationContext()->DocumentWasDetached();
@@ -3435,8 +3331,12 @@ void Document::Shutdown() {
frame_->GetEventHandlerRegistry().DocumentDetached(*this);
// Signal destruction to mutation observers.
- DocumentShutdownNotifier::NotifyContextDestroyed();
- SynchronousMutationNotifier::NotifyContextDestroyed();
+ synchronous_mutation_observer_list_.ForEachObserver(
+ [](SynchronousMutationObserver* observer) {
+ observer->ContextDestroyed();
+ observer->ObserverListWillBeCleared();
+ });
+ synchronous_mutation_observer_list_.Clear();
cookie_jar_ = nullptr; // Not accessible after navigated away.
fetcher_->ClearContext();
@@ -3455,22 +3355,12 @@ void Document::Shutdown() {
// TODO(crbug.com/729196): Trace why LocalFrameView::DetachFromLayout crashes.
CHECK(!View()->IsAttached());
- // Check for frame_ so we only detach execution contexts with its own
- // scheduler.
+ // 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()->DetachExecutionContext(this);
-
- // TODO(haraken): Call contextDestroyed() before we start any disruptive
- // operations.
- // TODO(haraken): Currently we call notifyContextDestroyed() only in
- // Document::detachLayoutTree(), which means that we don't call
- // notifyContextDestroyed() for a document that doesn't get detached.
- // If such a document has any observer, the observer won't get
- // a contextDestroyed() notification. This can happen for a document
- // created by DOMImplementation::createDocument().
- ExecutionContext::NotifyContextDestroyed();
+ GetAgent()->DetachDocument(this);
+
// TODO(crbug.com/729196): Trace why LocalFrameView::DetachFromLayout crashes.
CHECK(!View()->IsAttached());
@@ -3585,8 +3475,8 @@ CanvasFontCache* Document::GetCanvasFontCache() {
}
DocumentParser* Document::CreateParser() {
- if (IsHTMLDocument()) {
- return MakeGarbageCollected<HTMLDocumentParser>(ToHTMLDocument(*this),
+ if (auto* html_document = DynamicTo<HTMLDocument>(this)) {
+ return MakeGarbageCollected<HTMLDocumentParser>(*html_document,
parser_sync_policy_);
}
// FIXME: this should probably pass the frame instead
@@ -3594,7 +3484,7 @@ DocumentParser* Document::CreateParser() {
}
bool Document::IsFrameSet() const {
- if (!IsHTMLDocument())
+ if (!IsA<HTMLDocument>(this))
return false;
return IsA<HTMLFrameSetElement>(body());
}
@@ -3647,7 +3537,7 @@ void Document::open(Document* entered_document,
// If |document| is an XML document, then throw an "InvalidStateError"
// DOMException exception.
- if (!IsHTMLDocument()) {
+ if (!IsA<HTMLDocument>(this)) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
"Only HTML documents support open().");
return;
@@ -3687,6 +3577,7 @@ void Document::open(Document* entered_document,
if (ignore_opens_during_unload_count_)
return;
+ // If |document|'s active parser was aborted is true, then return |document|.
if (ignore_opens_and_writes_for_abort_)
return;
@@ -3697,7 +3588,7 @@ void Document::open(Document* entered_document,
csp->CopyStateFrom(entered_document->GetContentSecurityPolicy());
// We inherit the sandbox flags of the entered document, so mask on
// the ones contained in the CSP.
- sandbox_flags_ |= csp->GetSandboxMask();
+ GetSecurityContext().ApplySandboxFlags(csp->GetSandboxMask());
InitContentSecurityPolicy(csp);
// Clear the hash fragment from the inherited URL to prevent a
// scroll-into-view for any document.open()'d frame.
@@ -3707,7 +3598,8 @@ void Document::open(Document* entered_document,
if (Loader())
Loader()->UpdateUrlForDocumentOpen(new_url);
- SetSecurityOrigin(entered_document->GetMutableSecurityOrigin());
+ GetSecurityContext().SetSecurityOrigin(
+ entered_document->GetMutableSecurityOrigin());
SetReferrerPolicy(entered_document->GetReferrerPolicy());
SetCookieURL(entered_document->CookieURL());
}
@@ -3745,6 +3637,12 @@ void Document::open() {
}
CancelPendingJavaScriptUrls();
+ // TODO(crbug.com/1085514): Consider making HasProvisionalNavigation() return
+ // true when form submission task is active, in which case we can delete this
+ // redundant attempt to cancel it.
+ if (GetFrame())
+ GetFrame()->CancelFormSubmission();
+
// For each shadow-including inclusive descendant |node| of |document|, erase
// all event listeners and handlers given |node|.
//
@@ -3978,7 +3876,7 @@ void Document::close(ExceptionState& exception_state) {
// If the Document object is an XML document, then throw an
// "InvalidStateError" DOMException.
- if (!IsHTMLDocument()) {
+ if (!IsA<HTMLDocument>(this)) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
"Only HTML documents support close().");
return;
@@ -4039,6 +3937,9 @@ void Document::ImplicitClose() {
if (domWindow())
domWindow()->DocumentWasClosed();
+ if (GetFrame() && GetFrame()->IsMainFrame())
+ GetFrame()->GetLocalFrameHostRemote().DocumentOnLoadCompleted();
+
if (GetFrame()) {
GetFrame()->Client()->DispatchDidHandleOnloadEvents();
Loader()->GetApplicationCacheHost()->StopDeferringEvents();
@@ -4141,19 +4042,6 @@ bool Document::CheckCompletedInternal() {
return false;
}
- // !ukm_binding_ is checked to avoid repeating work.
- if (frame_ && frame_->Client()->GetRemoteNavigationAssociatedInterfaces() &&
- !ukm_binding_) {
- ukm_binding_ = std::make_unique<
- mojo::AssociatedRemote<mojom::blink::UkmSourceIdFrameHost>>();
- frame_->Client()->GetRemoteNavigationAssociatedInterfaces()->GetInterface(
- ukm_binding_.get());
- DCHECK(ukm_binding_->is_bound());
- auto callback =
- WTF::Bind(&Document::SetNavigationSourceId, WrapPersistent(this));
- (*ukm_binding_.get())->GetNavigationSourceId(std::move(callback));
- }
-
// OK, completed. Fire load completion events as needed.
SetReadyState(kComplete);
if (LoadEventStillNeeded())
@@ -4175,13 +4063,17 @@ bool Document::CheckCompletedInternal() {
GetViewportData().GetViewportDescription().ReportMobilePageStats(frame_);
Loader()->SetSentDidFinishLoad();
frame_->Client()->DispatchDidFinishLoad();
+ frame_->GetLocalFrameHostRemote().DidFinishLoad(Loader()->Url());
if (!frame_)
return false;
// Send the source ID of the document to the browser.
if (frame_->Client()->GetRemoteNavigationAssociatedInterfaces()) {
- DCHECK(ukm_binding_->is_bound());
- (*ukm_binding_.get())->SetDocumentSourceId(ukm_source_id_);
+ mojo::AssociatedRemote<mojom::blink::UkmSourceIdFrameHost> ukm_binding;
+ frame_->Client()->GetRemoteNavigationAssociatedInterfaces()->GetInterface(
+ &ukm_binding);
+ DCHECK(ukm_binding.is_bound());
+ ukm_binding->SetDocumentSourceId(ukm_source_id_);
}
frame_->GetFrameScheduler()->RegisterStickyFeature(
@@ -4200,6 +4092,16 @@ bool Document::CheckCompletedInternal() {
}
}
+ if (auto* view = View()) {
+ if (view->GetFragmentAnchor()) {
+ // Schedule an animation frame to process fragment anchors. The frame
+ // can't be scheduled when the fragment anchor is set because, per spec,
+ // we must wait for the document to be loaded before invoking fragment
+ // anchors.
+ View()->ScheduleAnimation();
+ }
+ }
+
return true;
}
@@ -4215,6 +4117,7 @@ bool Document::DispatchBeforeUnloadEvent(ChromeClient* chrome_client,
if (ProcessingBeforeUnload())
return false;
+ MainThreadDisallowSynchronousXHRScope disallow_synchronous_xhr;
auto& before_unload_event = *MakeGarbageCollected<BeforeUnloadEvent>();
before_unload_event.initEvent(event_type_names::kBeforeunload, false, true);
load_event_progress_ = kBeforeUnloadEventInProgress;
@@ -4246,7 +4149,7 @@ bool Document::DispatchBeforeUnloadEvent(ChromeClient* chrome_client,
if (!GetFrame() || before_unload_event.returnValue().IsNull())
return true;
- if (!GetFrame()->HasBeenActivated()) {
+ if (!GetFrame()->HasStickyUserActivation()) {
beforeunload_dialog_histogram.Count(kNoDialogNoUserGesture);
String message =
"Blocked attempt to show a 'beforeunload' confirmation panel for a "
@@ -4298,6 +4201,7 @@ void Document::DispatchUnloadEvents(
SecurityOrigin* committing_origin,
base::Optional<Document::UnloadEventTiming>* unload_timing) {
PluginScriptForbiddenScope forbid_plugin_destructor_scripting;
+ MainThreadDisallowSynchronousXHRScope disallow_synchronous_xhr;
if (parser_)
parser_->StopParsing();
@@ -4455,7 +4359,7 @@ void Document::write(const String& text,
return;
}
- if (!IsHTMLDocument()) {
+ if (!IsA<HTMLDocument>(this)) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
"Only HTML documents support write().");
return;
@@ -4493,7 +4397,7 @@ void Document::write(const String& text,
if (!has_insertion_point) {
if (ignore_destructive_write_count_) {
- AddConsoleMessage(ConsoleMessage::Create(
+ AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning,
ExceptionMessages::FailedToExecute(
@@ -4511,12 +4415,12 @@ void Document::write(const String& text,
DCHECK(parser_);
PerformanceMonitor::ReportGenericViolation(
- this, PerformanceMonitor::kDiscouragedAPIUse,
+ domWindow(), PerformanceMonitor::kDiscouragedAPIUse,
"Avoid using document.write(). "
"https://developers.google.com/web/updates/2016/08/"
"removing-document-write",
base::TimeDelta(), nullptr);
- probe::BreakableLocation(this, "Document.write");
+ probe::BreakableLocation(domWindow(), "Document.write");
parser_->insert(text);
}
@@ -4539,7 +4443,7 @@ void Document::write(v8::Isolate* isolate,
for (const String& string : text)
builder.Append(string);
String string =
- GetStringFromTrustedHTML(builder.ToString(), this, exception_state);
+ TrustedTypesCheckForHTML(builder.ToString(), this, exception_state);
if (exception_state.HadException())
return;
@@ -4556,7 +4460,7 @@ void Document::writeln(v8::Isolate* isolate,
for (const String& string : text)
builder.Append(string);
String string =
- GetStringFromTrustedHTML(builder.ToString(), this, exception_state);
+ TrustedTypesCheckForHTML(builder.ToString(), this, exception_state);
if (exception_state.HadException())
return;
@@ -4564,7 +4468,7 @@ void Document::writeln(v8::Isolate* isolate,
}
bool Document::IsTrustedTypesEnabledForDoc() const {
- return ExecutionContext::RequireTrustedTypes();
+ return GetExecutionContext()->RequireTrustedTypes();
}
void Document::write(v8::Isolate* isolate,
@@ -4583,15 +4487,10 @@ void Document::writeln(v8::Isolate* isolate,
exception_state);
}
-EventTarget* Document::ErrorEventTarget() {
- return domWindow();
-}
-
-void Document::ExceptionThrown(ErrorEvent* event) {
- MainThreadDebugger::Instance()->ExceptionThrown(this, event);
-}
-
KURL Document::urlForBinding() const {
+ if (WebBundleClaimedUrl().IsValid()) {
+ return WebBundleClaimedUrl();
+ }
if (!Url().IsNull()) {
return Url();
}
@@ -4761,7 +4660,7 @@ void Document::ProcessBaseElement() {
if (base_element_url.ProtocolIsData() ||
base_element_url.ProtocolIsJavaScript()) {
UseCounter::Count(*this, WebFeature::kBaseWithDataHref);
- AddConsoleMessage(ConsoleMessage::Create(
+ AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kSecurity,
mojom::ConsoleMessageLevel::kError,
"'" + base_element_url.Protocol() +
@@ -4794,13 +4693,6 @@ String Document::UserAgent() const {
return GetFrame() ? GetFrame()->Loader().UserAgent() : String();
}
-void Document::DisableEval(const String& error_message) {
- if (!GetFrame())
- return;
-
- GetFrame()->GetScriptController().DisableEval(error_message);
-}
-
void Document::DidLoadAllImports() {
if (!HaveScriptBlockingStylesheetsLoaded())
return;
@@ -4834,11 +4726,11 @@ void Document::DidLoadAllScriptBlockingResources() {
WTF::Bind(&Document::ExecuteScriptsWaitingForResources,
WrapWeakPersistent(this)));
- if (IsHTMLDocument() && body()) {
+ if (IsA<HTMLDocument>(this) && body()) {
// For HTML if we have no more stylesheets to load and we're past the body
// tag, we should have something to paint so resume.
BeginLifecycleUpdatesIfRenderingReady();
- } else if (!IsHTMLDocument() && documentElement()) {
+ } else if (!IsA<HTMLDocument>(this) && documentElement()) {
// For non-HTML there is no body so resume as soon as the sheets are loaded.
BeginLifecycleUpdatesIfRenderingReady();
}
@@ -4876,21 +4768,21 @@ void Document::MaybeHandleHttpRefresh(const String& content,
if (refresh_url.ProtocolIsJavaScript()) {
String message =
"Refused to refresh " + url_.ElidedString() + " to a javascript: URL";
- AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kError, message));
+ AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kSecurity,
+ mojom::ConsoleMessageLevel::kError, message));
return;
}
if (http_refresh_type == kHttpRefreshFromMetaTag &&
- IsSandboxed(WebSandboxFlags::kAutomaticFeatures)) {
+ IsSandboxed(mojom::blink::WebSandboxFlags::kAutomaticFeatures)) {
String message =
"Refused to execute the redirect specified via '<meta "
"http-equiv='refresh' content='...'>'. The document is sandboxed, and "
"the 'allow-scripts' keyword is not set.";
- AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kError, message));
+ AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kSecurity,
+ mojom::ConsoleMessageLevel::kError, message));
return;
}
if (http_refresh_type == kHttpRefreshFromHeader) {
@@ -4933,24 +4825,15 @@ String Document::OutgoingReferrer() const {
}
network::mojom::ReferrerPolicy Document::GetReferrerPolicy() const {
- network::mojom::ReferrerPolicy policy = ExecutionContext::GetReferrerPolicy();
- // For srcdoc documents without their own policy, walk up the frame
- // tree to find the document that is either not a srcdoc or doesn't
- // have its own policy. This algorithm is defined in
- // https://html.spec.whatwg.org/C/#set-up-a-window-environment-settings-object.
- if (!frame_ || policy != network::mojom::ReferrerPolicy::kDefault ||
- !IsSrcdocDocument()) {
- return policy;
- }
- LocalFrame* frame = To<LocalFrame>(frame_->Tree().Parent());
- return frame->GetDocument()->GetReferrerPolicy();
+ return GetExecutionContext() ? GetExecutionContext()->GetReferrerPolicy()
+ : network::mojom::ReferrerPolicy::kDefault;
}
MouseEventWithHitTestResults Document::PerformMouseEventHitTest(
const HitTestRequest& request,
const PhysicalOffset& document_point,
const WebMouseEvent& event) {
- DCHECK(!GetLayoutView() || GetLayoutView()->IsLayoutView());
+ DCHECK(!GetLayoutView() || IsA<LayoutView>(GetLayoutView()));
// LayoutView::hitTest causes a layout, and we don't want to hit that until
// the first layout because until then, there is nothing shown on the screen -
@@ -5172,7 +5055,7 @@ Document* Document::CloneDocumentWithoutChildren() const {
.WithContextDocument(ContextDocument())
.WithOwnerDocument(const_cast<Document*>(this))
.WithURL(Url());
- if (IsXMLDocument()) {
+ if (IsA<XMLDocument>(this)) {
if (IsXHTMLDocument())
return XMLDocument::CreateXHTML(
init.WithRegistrationContext(RegistrationContext()));
@@ -5303,7 +5186,7 @@ void Document::SetAnnotatedRegions(
SetAnnotatedRegionsDirty(false);
}
-void Document::SetLastFocusType(WebFocusType last_focus_type) {
+void Document::SetLastFocusType(mojom::blink::FocusType last_focus_type) {
last_focus_type_ = last_focus_type;
}
@@ -5341,6 +5224,8 @@ bool Document::SetFocusedElement(Element* new_focused_element,
old_focused_element->SetFocused(false, params.type);
old_focused_element->SetHasFocusWithinUpToAncestor(false, ancestor);
+ DisplayLockUtilities::ElementLostFocus(old_focused_element);
+
// Dispatch the blur event and let the node do any other blur related
// activities (important for text fields)
// If page lost focus, blur event will have already been dispatched
@@ -5389,11 +5274,12 @@ bool Document::SetFocusedElement(Element* new_focused_element,
SetSequentialFocusNavigationStartingPoint(focused_element_.Get());
// Keep track of last focus from user interaction, ignoring focus from code.
- if (params.type != kWebFocusTypeNone)
+ if (params.type != mojom::blink::FocusType::kNone)
last_focus_type_ = params.type;
focused_element_->SetFocused(true, params.type);
focused_element_->SetHasFocusWithinUpToAncestor(true, ancestor);
+ DisplayLockUtilities::ElementGainedFocus(focused_element_.Get());
// Element::setFocused for frames can dispatch events.
if (focused_element_ != new_focused_element) {
@@ -5403,7 +5289,8 @@ bool Document::SetFocusedElement(Element* new_focused_element,
return false;
}
CancelFocusAppearanceUpdate();
- EnsurePaintLocationDataValidForNode(focused_element_);
+ EnsurePaintLocationDataValidForNode(focused_element_,
+ DocumentUpdateReason::kFocus);
focused_element_->UpdateFocusAppearanceWithOptions(
params.selection_behavior, params.options);
@@ -5462,20 +5349,47 @@ bool Document::SetFocusedElement(Element* new_focused_element,
}
void Document::ClearFocusedElement() {
- SetFocusedElement(nullptr, FocusParams(SelectionBehaviorOnFocus::kNone,
- kWebFocusTypeNone, nullptr));
+ SetFocusedElement(nullptr,
+ FocusParams(SelectionBehaviorOnFocus::kNone,
+ mojom::blink::FocusType::kNone, nullptr));
}
void Document::NotifyFocusedElementChanged(Element* old_focused_element,
Element* new_focused_element) {
+ // |old_focused_element| may not belong to this document by invoking
+ // adoptNode in event handlers during moving the focus to the new element.
+ DCHECK(!new_focused_element || new_focused_element->GetDocument() == this);
+
if (AXObjectCache* cache = ExistingAXObjectCache()) {
cache->HandleFocusedUIElementChanged(old_focused_element,
new_focused_element);
}
if (GetPage()) {
- GetPage()->GetChromeClient().FocusedElementChanged(old_focused_element,
- new_focused_element);
+ GetPage()->GetValidationMessageClient().DidChangeFocusTo(
+ new_focused_element);
+
+ bool is_editable = false;
+ gfx::Rect element_bounds;
+ if (new_focused_element) {
+ IntRect rect = new_focused_element->BoundsInViewport();
+ View()->FrameToScreen(rect);
+ is_editable = IsEditableElement(*new_focused_element);
+ element_bounds = gfx::Rect(rect);
+ }
+
+ GetFrame()->GetLocalFrameHostRemote().FocusedElementChanged(is_editable,
+ element_bounds);
+
+ Document* old_document =
+ old_focused_element ? &old_focused_element->GetDocument() : nullptr;
+ if (old_document && old_document != this && old_document->GetFrame())
+ old_document->GetFrame()->Client()->FocusedElementChanged(nullptr);
+
+ GetFrame()->Client()->FocusedElementChanged(new_focused_element);
+
+ GetPage()->GetChromeClient().SetKeyboardFocusURL(new_focused_element);
+
if (GetSettings()->GetSpatialNavigationEnabled())
GetPage()->GetSpatialNavigationController().FocusedNodeChanged(this);
}
@@ -5496,7 +5410,7 @@ void Document::SetSequentialFocusNavigationStartingPoint(Node* node) {
}
Element* Document::SequentialFocusNavigationStartingPoint(
- WebFocusType type) const {
+ mojom::blink::FocusType type) const {
if (focused_element_)
return focused_element_.Get();
if (!sequential_focus_navigation_starting_point_)
@@ -5508,7 +5422,7 @@ Element* Document::SequentialFocusNavigationStartingPoint(
sequential_focus_navigation_starting_point_->endContainer());
if (auto* element = DynamicTo<Element>(node))
return element;
- if (Element* neighbor_element = type == kWebFocusTypeForward
+ if (Element* neighbor_element = type == mojom::blink::FocusType::kForward
? ElementTraversal::Previous(*node)
: ElementTraversal::Next(*node))
return neighbor_element;
@@ -5532,7 +5446,7 @@ Element* Document::SequentialFocusNavigationStartingPoint(
// TODO(tkent): Using FlatTreeTraversal is inconsistent with
// FocusController. Ideally we should find backward/forward focusable
// elements before the starting point is disconnected. crbug.com/606582
- if (type == kWebFocusTypeForward) {
+ if (type == mojom::blink::FocusType::kForward) {
Node* previous = FlatTreeTraversal::Previous(*next_node);
for (; previous; previous = FlatTreeTraversal::Previous(*previous)) {
if (auto* element = DynamicTo<Element>(previous))
@@ -5605,7 +5519,10 @@ void Document::DidMoveTreeToNewDocument(const Node& root) {
for (Range* range : ranges)
range->UpdateOwnerDocumentIfNeeded();
}
- NotifyMoveTreeToNewDocument(root);
+ synchronous_mutation_observer_list_.ForEachObserver(
+ [&](SynchronousMutationObserver* observer) {
+ observer->DidMoveTreeToNewDocument(root);
+ });
}
void Document::NodeChildrenWillBeRemoved(ContainerNode& container) {
@@ -5621,7 +5538,10 @@ void Document::NodeChildrenWillBeRemoved(ContainerNode& container) {
ni->NodeWillBeRemoved(n);
}
- NotifyNodeChildrenWillBeRemoved(container);
+ synchronous_mutation_observer_list_.ForEachObserver(
+ [&](SynchronousMutationObserver* observer) {
+ observer->NodeChildrenWillBeRemoved(container);
+ });
if (ContainsV1ShadowTree()) {
for (Node& n : NodeTraversal::ChildrenOf(container))
@@ -5639,7 +5559,10 @@ void Document::NodeWillBeRemoved(Node& n) {
range->FixupRemovedNodeAcrossShadowBoundary(n);
}
- NotifyNodeWillBeRemoved(n);
+ synchronous_mutation_observer_list_.ForEachObserver(
+ [&](SynchronousMutationObserver* observer) {
+ observer->NodeWillBeRemoved(n);
+ });
if (ContainsV1ShadowTree())
n.CheckSlotChangeBeforeRemoved();
@@ -5648,6 +5571,24 @@ void Document::NodeWillBeRemoved(Node& n) {
GetStyleEngine().NodeWillBeRemoved(n);
}
+void Document::NotifyUpdateCharacterData(CharacterData* character_data,
+ unsigned offset,
+ unsigned old_length,
+ unsigned new_length) {
+ synchronous_mutation_observer_list_.ForEachObserver(
+ [&](SynchronousMutationObserver* observer) {
+ observer->DidUpdateCharacterData(character_data, offset, old_length,
+ new_length);
+ });
+}
+
+void Document::NotifyChangeChildren(const ContainerNode& container) {
+ synchronous_mutation_observer_list_.ForEachObserver(
+ [&](SynchronousMutationObserver* observer) {
+ observer->DidChangeChildren(container);
+ });
+}
+
void Document::DidInsertText(const CharacterData& text,
unsigned offset,
unsigned length) {
@@ -5672,7 +5613,11 @@ void Document::DidMergeTextNodes(const Text& merged_node,
range->DidMergeTextNodes(node_to_be_removed_with_index, old_length);
}
- NotifyMergeTextNodes(merged_node, node_to_be_removed_with_index, old_length);
+ synchronous_mutation_observer_list_.ForEachObserver(
+ [&](SynchronousMutationObserver* observer) {
+ observer->DidMergeTextNodes(merged_node, node_to_be_removed_with_index,
+ old_length);
+ });
// FIXME: This should update markers for spelling and grammar checking.
}
@@ -5681,7 +5626,10 @@ void Document::DidSplitTextNode(const Text& old_node) {
for (Range* range : ranges_)
range->DidSplitTextNode(old_node);
- NotifySplitTextNode(old_node);
+ synchronous_mutation_observer_list_.ForEachObserver(
+ [&](SynchronousMutationObserver* observer) {
+ observer->DidSplitTextNode(old_node);
+ });
// FIXME: This should update markers for spelling and grammar checking.
}
@@ -5703,79 +5651,83 @@ EventListener* Document::GetWindowAttributeEventListener(
}
void Document::EnqueueDisplayLockActivationTask(base::OnceClosure task) {
- EnsureScriptedAnimationController().EnqueueTask(std::move(task));
+ scripted_animation_controller_->EnqueueTask(std::move(task));
}
void Document::EnqueueAnimationFrameTask(base::OnceClosure task) {
- EnsureScriptedAnimationController().EnqueueTask(std::move(task));
+ scripted_animation_controller_->EnqueueTask(std::move(task));
}
void Document::EnqueueAnimationFrameEvent(Event* event) {
- EnsureScriptedAnimationController().EnqueueEvent(event);
+ scripted_animation_controller_->EnqueueEvent(event);
}
void Document::EnqueueUniqueAnimationFrameEvent(Event* event) {
- EnsureScriptedAnimationController().EnqueuePerFrameEvent(event);
+ scripted_animation_controller_->EnqueuePerFrameEvent(event);
}
void Document::EnqueueScrollEventForNode(Node* target) {
// Per the W3C CSSOM View Module only scroll events fired at the document
// should bubble.
+ overscroll_accumulated_delta_x_ = overscroll_accumulated_delta_y_ = 0;
Event* scroll_event = target->IsDocumentNode()
? Event::CreateBubble(event_type_names::kScroll)
: Event::Create(event_type_names::kScroll);
scroll_event->SetTarget(target);
- EnsureScriptedAnimationController().EnqueuePerFrameEvent(scroll_event);
+ scripted_animation_controller_->EnqueuePerFrameEvent(scroll_event);
}
void Document::EnqueueScrollEndEventForNode(Node* target) {
// Mimic bubbling behavior of scroll event for consistency.
+ overscroll_accumulated_delta_x_ = overscroll_accumulated_delta_y_ = 0;
Event* scroll_end_event =
target->IsDocumentNode()
? Event::CreateBubble(event_type_names::kScrollend)
: Event::Create(event_type_names::kScrollend);
scroll_end_event->SetTarget(target);
- EnsureScriptedAnimationController().EnqueuePerFrameEvent(scroll_end_event);
+ scripted_animation_controller_->EnqueuePerFrameEvent(scroll_end_event);
}
void Document::EnqueueOverscrollEventForNode(Node* target,
double delta_x,
double delta_y) {
// Mimic bubbling behavior of scroll event for consistency.
+ overscroll_accumulated_delta_x_ += delta_x;
+ overscroll_accumulated_delta_y_ += delta_y;
bool bubbles = target->IsDocumentNode();
Event* overscroll_event = OverscrollEvent::Create(
- event_type_names::kOverscroll, bubbles, delta_x, delta_y);
+ event_type_names::kOverscroll, bubbles, overscroll_accumulated_delta_x_,
+ overscroll_accumulated_delta_y_);
overscroll_event->SetTarget(target);
- EnsureScriptedAnimationController().EnqueuePerFrameEvent(overscroll_event);
+ scripted_animation_controller_->EnqueuePerFrameEvent(overscroll_event);
}
void Document::EnqueueResizeEvent() {
Event* event = Event::Create(event_type_names::kResize);
event->SetTarget(domWindow());
- EnsureScriptedAnimationController().EnqueuePerFrameEvent(event);
+ scripted_animation_controller_->EnqueuePerFrameEvent(event);
}
void Document::EnqueueMediaQueryChangeListeners(
HeapVector<Member<MediaQueryListListener>>& listeners) {
- EnsureScriptedAnimationController().EnqueueMediaQueryChangeListeners(
- listeners);
+ scripted_animation_controller_->EnqueueMediaQueryChangeListeners(listeners);
}
void Document::EnqueueVisualViewportScrollEvent() {
- VisualViewportScrollEvent* event = VisualViewportScrollEvent::Create();
+ VisualViewportScrollEvent* event =
+ MakeGarbageCollected<VisualViewportScrollEvent>();
event->SetTarget(domWindow()->visualViewport());
- EnsureScriptedAnimationController().EnqueuePerFrameEvent(event);
+ scripted_animation_controller_->EnqueuePerFrameEvent(event);
}
void Document::EnqueueVisualViewportResizeEvent() {
- VisualViewportResizeEvent* event = VisualViewportResizeEvent::Create();
+ VisualViewportResizeEvent* event =
+ MakeGarbageCollected<VisualViewportResizeEvent>();
event->SetTarget(domWindow()->visualViewport());
- EnsureScriptedAnimationController().EnqueuePerFrameEvent(event);
+ scripted_animation_controller_->EnqueuePerFrameEvent(event);
}
void Document::DispatchEventsForPrinting() {
- if (!scripted_animation_controller_)
- return;
scripted_animation_controller_->DispatchEventsAndCallbacksForPrinting();
}
@@ -5819,7 +5771,7 @@ Event* Document::createEvent(ScriptState* script_state,
if (event) {
// createEvent for TouchEvent should throw DOM exception if touch event
// feature detection is not enabled. See crbug.com/392584#c22
- if (DeprecatedEqualIgnoringCase(event_type, "TouchEvent") &&
+ if (EqualIgnoringASCIICase(event_type, "TouchEvent") &&
!RuntimeEnabledFeatures::TouchEventFeatureDetectionEnabled(
execution_context))
break;
@@ -5871,6 +5823,8 @@ void Document::AddListenerTypeIfNeeded(const AtomicString& event_type,
// Need to re-evaluate time-to-effect-change for any running animations.
View()->ScheduleAnimation();
}
+ } else if (event_type == event_type_names::kAnimationcancel) {
+ AddListenerType(kAnimationCancelListener);
} else if (event_type == event_type_names::kTransitioncancel) {
AddListenerType(kTransitionCancelListener);
} else if (event_type == event_type_names::kTransitionrun) {
@@ -5902,10 +5856,11 @@ HTMLFrameOwnerElement* Document::LocalOwner() const {
return GetFrame()->DeprecatedLocalOwner();
}
-void Document::WillChangeFrameOwnerProperties(int margin_width,
- int margin_height,
- ScrollbarMode scrolling_mode,
- bool is_display_none) {
+void Document::WillChangeFrameOwnerProperties(
+ int margin_width,
+ int margin_height,
+ mojom::blink::ScrollbarMode scrollbar_mode,
+ bool is_display_none) {
DCHECK(GetFrame() && GetFrame()->Owner());
FrameOwner* owner = GetFrame()->Owner();
@@ -5926,8 +5881,9 @@ void Document::WillChangeFrameOwnerProperties(int margin_width,
margin_height);
}
}
- if (scrolling_mode != owner->ScrollingMode() && View()) {
- View()->SetCanHaveScrollbars(scrolling_mode != ScrollbarMode::kAlwaysOff);
+ if (scrollbar_mode != owner->ScrollbarMode() && View()) {
+ View()->SetCanHaveScrollbars(scrollbar_mode !=
+ mojom::blink::ScrollbarMode::kAlwaysOff);
View()->SetNeedsLayout();
}
}
@@ -5939,10 +5895,10 @@ String Document::cookie(ExceptionState& exception_state) const {
CountUse(WebFeature::kCookieGet);
if (!GetSecurityOrigin()->CanAccessCookies()) {
- if (IsSandboxed(WebSandboxFlags::kOrigin))
+ if (IsSandboxed(mojom::blink::WebSandboxFlags::kOrigin))
exception_state.ThrowSecurityError(
"The document is sandboxed and lacks the 'allow-same-origin' flag.");
- else if (Url().ProtocolIs("data"))
+ else if (Url().ProtocolIsData())
exception_state.ThrowSecurityError(
"Cookies are disabled inside 'data:' URLs.");
else
@@ -5965,10 +5921,10 @@ void Document::setCookie(const String& value, ExceptionState& exception_state) {
UseCounter::Count(*this, WebFeature::kCookieSet);
if (!GetSecurityOrigin()->CanAccessCookies()) {
- if (IsSandboxed(WebSandboxFlags::kOrigin))
+ if (IsSandboxed(mojom::blink::WebSandboxFlags::kOrigin))
exception_state.ThrowSecurityError(
"The document is sandboxed and lacks the 'allow-same-origin' flag.");
- else if (Url().ProtocolIs("data"))
+ else if (Url().ProtocolIsData())
exception_state.ThrowSecurityError(
"Cookies are disabled inside 'data:' URLs.");
else
@@ -6011,7 +5967,7 @@ void Document::setDomain(const String& raw_domain,
const String feature_policy_error =
"Setting `document.domain` is disabled by Feature Policy.";
- if (!IsFeatureEnabled(mojom::FeaturePolicyFeature::kDocumentDomain,
+ if (!IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kDocumentDomain,
ReportOptions::kReportOnFailure,
feature_policy_error)) {
exception_state.ThrowSecurityError(feature_policy_error);
@@ -6024,7 +5980,7 @@ void Document::setDomain(const String& raw_domain,
return;
}
- if (IsSandboxed(WebSandboxFlags::kDocumentDomain)) {
+ if (IsSandboxed(mojom::blink::WebSandboxFlags::kDocumentDomain)) {
exception_state.ThrowSecurityError(
"Assignment is forbidden for sandboxed iframes.");
return;
@@ -6077,13 +6033,44 @@ void Document::setDomain(const String& raw_domain,
GetSecurityOrigin()->Port() == 0
? WebFeature::kDocumentDomainSetWithDefaultPort
: WebFeature::kDocumentDomainSetWithNonDefaultPort);
- bool was_cross_domain = frame_->IsCrossOriginSubframe();
+ bool was_cross_origin_to_main_frame = frame_->IsCrossOriginToMainFrame();
+ bool was_cross_origin_to_parent_frame =
+ frame_->IsCrossOriginToParentFrame();
GetMutableSecurityOrigin()->SetDomainFromDOM(new_domain);
- bool is_cross_domain = frame_->IsCrossOriginSubframe();
+ bool is_cross_origin_to_main_frame = frame_->IsCrossOriginToMainFrame();
if (FrameScheduler* frame_scheduler = frame_->GetFrameScheduler())
- frame_scheduler->SetCrossOrigin(is_cross_domain);
- if (View() && (was_cross_domain != is_cross_domain))
- View()->CrossOriginStatusChanged();
+ 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()) {
+ // 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_)) {
+ auto* child_local_frame = DynamicTo<LocalFrame>(child);
+ if (child_local_frame && child_local_frame->View())
+ child_local_frame->View()->CrossOriginToMainFrameChanged();
+ }
+ }
+
+ if (View() && was_cross_origin_to_parent_frame !=
+ frame_->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;
+ 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());
}
@@ -6131,7 +6118,7 @@ scoped_refptr<const SecurityOrigin> Document::TopFrameOrigin() const {
return GetFrame()->Tree().Top().GetSecurityContext()->GetSecurityOrigin();
}
-const KURL Document::SiteForCookies() 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:
@@ -6139,44 +6126,50 @@ const KURL Document::SiteForCookies() const {
return ImportsController()->Master()->SiteForCookies();
if (!GetFrame())
- return NullURL();
+ return net::SiteForCookies();
Frame& top = GetFrame()->Tree().Top();
const SecurityOrigin* origin = top.GetSecurityContext()->GetSecurityOrigin();
// TODO(yhirano): Ideally |origin| should not be null here.
if (!origin)
- return NullURL();
+ return net::SiteForCookies();
+
+ net::SiteForCookies candidate =
+ net::SiteForCookies::FromOrigin(origin->ToUrlOrigin());
if (SchemeRegistry::ShouldTreatURLSchemeAsFirstPartyWhenTopLevel(
origin->Protocol())) {
- return origin->IsOpaque() ? NullURL() : KURL(origin->ToRawString());
+ return candidate;
}
- OriginAccessEntry access_entry(
- *origin, network::mojom::CorsDomainMatchMode::kAllowRegistrableDomains);
-
const Frame* current_frame = GetFrame();
while (current_frame) {
const SecurityOrigin* cur_security_origin =
current_frame->GetSecurityContext()->GetSecurityOrigin();
- // We use 'matchesDomain' here, as it turns out that some folks embed HTTPS
- // login forms into HTTP pages; we should allow this kind of upgrade.
- //
- // The second clause bypasses strange permissiveness of OriginAccessEntry on
- // empty domain names. See the beginning of OriginAccessEntry::MatchesDomain
- // in services/network/public/cpp/cors/origin_access_entry.cc
- if (access_entry.MatchesDomain(*cur_security_origin) ==
- network::cors::OriginAccessEntry::kDoesNotMatchOrigin ||
- (origin->Domain().IsEmpty() != cur_security_origin->Host().IsEmpty())) {
- return NullURL();
+ if (!candidate.IsEquivalent(net::SiteForCookies::FromOrigin(
+ cur_security_origin->ToUrlOrigin()))) {
+ return net::SiteForCookies();
}
-
current_frame = current_frame->Tree().Parent();
}
- // Note: don't want origin->ToString() here since that may mess up file:///,
- // depending on AllowFileAccessFromFileURLs setting.
- return origin->IsOpaque() ? NullURL() : KURL(origin->ToRawString());
+ return candidate;
+}
+
+mojom::blink::PermissionService* Document::GetPermissionService(
+ ExecutionContext* execution_context) {
+ if (!permission_service_.is_bound()) {
+ execution_context->GetBrowserInterfaceBroker().GetInterface(
+ permission_service_.BindNewPipeAndPassReceiver(
+ execution_context->GetTaskRunner(TaskType::kPermission)));
+ permission_service_.set_disconnect_handler(WTF::Bind(
+ &Document::PermissionServiceConnectionError, WrapWeakPersistent(this)));
+ }
+ return permission_service_.get();
+}
+
+void Document::PermissionServiceConnectionError() {
+ permission_service_.reset();
}
ScriptPromise Document::hasStorageAccess(ScriptState* script_state) const {
@@ -6193,14 +6186,39 @@ ScriptPromise Document::hasStorageAccess(ScriptState* script_state) const {
return promise;
}
-ScriptPromise Document::requestStorageAccess(ScriptState* script_state) const {
+ScriptPromise Document::requestStorageAccess(ScriptState* script_state) {
+ DCHECK(frame_);
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();
- resolver->Reject();
+
+ 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.
+ resolver->Reject();
+ }
return promise;
}
@@ -6471,9 +6489,8 @@ KURL Document::OpenSearchDescriptionURL() {
Traversal<HTMLLinkElement>::FirstChild(*head());
link_element;
link_element = Traversal<HTMLLinkElement>::NextSibling(*link_element)) {
- if (!DeprecatedEqualIgnoringCase(link_element->GetType(),
- kOpenSearchMIMEType) ||
- !DeprecatedEqualIgnoringCase(link_element->Rel(), kOpenSearchRelation))
+ if (!EqualIgnoringASCIICase(link_element->GetType(), kOpenSearchMIMEType) ||
+ !EqualIgnoringASCIICase(link_element->Rel(), kOpenSearchRelation))
continue;
if (link_element->Href().IsEmpty())
continue;
@@ -6528,10 +6545,10 @@ String Document::designMode() const {
void Document::setDesignMode(const String& value) {
bool new_value = design_mode_;
- if (DeprecatedEqualIgnoringCase(value, "on")) {
+ if (EqualIgnoringASCIICase(value, "on")) {
new_value = true;
UseCounter::Count(*this, WebFeature::kDocumentDesignModeEnabeld);
- } else if (DeprecatedEqualIgnoringCase(value, "off")) {
+ } else if (EqualIgnoringASCIICase(value, "off")) {
new_value = false;
}
if (new_value == design_mode_)
@@ -6564,11 +6581,8 @@ Document& Document::TopDocument() const {
}
Document* Document::ContextDocument() const {
- if (context_document_)
- return context_document_;
- if (frame_)
- return const_cast<Document*>(this);
- return nullptr;
+ return context_document_ ? context_document_.Get()
+ : const_cast<Document*>(this);
}
Attr* Document::createAttribute(const AtomicString& name,
@@ -6665,7 +6679,7 @@ HTMLCollection* Document::DocumentAllNamedItems(const AtomicString& name) {
kDocumentAllNamedItems, name);
}
-LocalDOMWindow* Document::defaultView() const {
+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.
@@ -6755,7 +6769,7 @@ void Document::FinishedParsing() {
// Forward origin trial freeze policy to the corresponding frame object in
// the resource coordinator.
if (auto* document_resource_coordinator = GetResourceCoordinator())
- SetOriginTrialFreezePolicy(document_resource_coordinator, this);
+ SetOriginTrialFreezePolicy(document_resource_coordinator, domWindow());
}
// Schedule dropping of the ElementDataCache. We keep it alive for a while
@@ -6769,9 +6783,6 @@ void Document::FinishedParsing() {
// Parser should have picked up all preloads by now
fetcher_->ClearPreloads(ResourceFetcher::kClearSpeculativeMarkupPreloads);
-
- if (IsPrefetchOnly())
- WebPrerenderingSupport::Current()->PrefetchFinished();
}
void Document::ElementDataCacheClearTimerFired(TimerBase*) {
@@ -6783,6 +6794,7 @@ void Document::BeginLifecycleUpdatesIfRenderingReady() {
return;
if (!HaveRenderBlockingResourcesLoaded())
return;
+ font_preload_manager_.WillBeginRendering();
View()->BeginLifecycleUpdates();
}
@@ -6808,23 +6820,30 @@ Vector<IconURL> Document::IconURLs(int icon_types_mask) {
// required by the spec.
for (HTMLLinkElement* link_element = first_element; link_element;
link_element = find_next_candidate(*link_element)) {
- if (!(link_element->GetIconType() & icon_types_mask))
+ if (!((1 << static_cast<int>(link_element->GetIconType())) &
+ icon_types_mask)) {
continue;
+ }
if (link_element->Href().IsEmpty())
continue;
IconURL new_url(link_element->Href(), link_element->IconSizes(),
link_element->GetType(), link_element->GetIconType());
- if (link_element->GetIconType() == kFavicon) {
- if (first_favicon.icon_type_ != kInvalidIcon)
+ if (link_element->GetIconType() ==
+ mojom::blink::FaviconIconType::kFavicon) {
+ if (first_favicon.icon_type_ != mojom::blink::FaviconIconType::kInvalid)
secondary_icons.push_back(first_favicon);
first_favicon = new_url;
- } else if (link_element->GetIconType() == kTouchIcon) {
- if (first_touch_icon.icon_type_ != kInvalidIcon)
+ } else if (link_element->GetIconType() ==
+ mojom::blink::FaviconIconType::kTouchIcon) {
+ if (first_touch_icon.icon_type_ !=
+ mojom::blink::FaviconIconType::kInvalid)
secondary_icons.push_back(first_touch_icon);
first_touch_icon = new_url;
- } else if (link_element->GetIconType() == kTouchPrecomposedIcon) {
- if (first_touch_precomposed_icon.icon_type_ != kInvalidIcon)
+ } else if (link_element->GetIconType() ==
+ mojom::blink::FaviconIconType::kTouchPrecomposedIcon) {
+ if (first_touch_precomposed_icon.icon_type_ !=
+ mojom::blink::FaviconIconType::kInvalid)
secondary_icons.push_back(first_touch_precomposed_icon);
first_touch_precomposed_icon = new_url;
} else {
@@ -6833,14 +6852,18 @@ Vector<IconURL> Document::IconURLs(int icon_types_mask) {
}
Vector<IconURL> icon_urls;
- if (first_favicon.icon_type_ != kInvalidIcon)
+ if (first_favicon.icon_type_ != mojom::blink::FaviconIconType::kInvalid) {
icon_urls.push_back(first_favicon);
- else if (url_.ProtocolIsInHTTPFamily() && icon_types_mask & kFavicon)
+ } else if (url_.ProtocolIsInHTTPFamily() &&
+ icon_types_mask & 1 << static_cast<int>(
+ mojom::blink::FaviconIconType::kFavicon)) {
icon_urls.push_back(IconURL::DefaultFavicon(url_));
+ }
- if (first_touch_icon.icon_type_ != kInvalidIcon)
+ if (first_touch_icon.icon_type_ != mojom::blink::FaviconIconType::kInvalid)
icon_urls.push_back(first_touch_icon);
- if (first_touch_precomposed_icon.icon_type_ != kInvalidIcon)
+ if (first_touch_precomposed_icon.icon_type_ !=
+ mojom::blink::FaviconIconType::kInvalid)
icon_urls.push_back(first_touch_precomposed_icon);
for (int i = secondary_icons.size() - 1; i >= 0; --i)
icon_urls.push_back(secondary_icons[i]);
@@ -6854,7 +6877,7 @@ base::Optional<Color> Document::ThemeColor() const {
for (HTMLMetaElement& meta_element :
Traversal<HTMLMetaElement>::DescendantsOf(*root_element)) {
Color color;
- if (DeprecatedEqualIgnoringCase(meta_element.GetName(), "theme-color") &&
+ if (EqualIgnoringASCIICase(meta_element.GetName(), "theme-color") &&
CSSParser::ParseColor(
color, meta_element.Content().GetString().StripWhiteSpace(), true))
return color;
@@ -6866,19 +6889,17 @@ void Document::ColorSchemeMetaChanged() {
if (!RuntimeEnabledFeatures::MetaColorSchemeEnabled())
return;
- auto* root_element = documentElement();
- if (!root_element)
- return;
-
const CSSValue* color_scheme = nullptr;
- for (HTMLMetaElement& meta_element :
- Traversal<HTMLMetaElement>::DescendantsOf(*root_element)) {
- if (EqualIgnoringASCIICase(meta_element.GetName(), "color-scheme")) {
- if ((color_scheme = CSSParser::ParseSingleValue(
- CSSPropertyID::kColorScheme,
- meta_element.Content().GetString().StripWhiteSpace(),
- ElementSheet().Contents()->ParserContext()))) {
- break;
+ if (auto* head_element = head()) {
+ for (HTMLMetaElement& meta_element :
+ Traversal<HTMLMetaElement>::DescendantsOf(*head_element)) {
+ if (EqualIgnoringASCIICase(meta_element.GetName(), "color-scheme")) {
+ if ((color_scheme = CSSParser::ParseSingleValue(
+ CSSPropertyID::kColorScheme,
+ meta_element.Content().GetString().StripWhiteSpace(),
+ ElementSheet().Contents()->ParserContext()))) {
+ break;
+ }
}
}
}
@@ -6912,23 +6933,11 @@ HTMLLinkElement* Document::LinkCanonical() const {
});
}
-void Document::FeaturePolicyInitialized(
- const DocumentInit& document_initializer,
- const SecurityContextInit& security_initializer) {
+void Document::PoliciesInitialized(const DocumentInit& document_initializer) {
// Processing of the feature policy header is done before the SecurityContext
// is initialized. This method just records the usage.
if (!document_initializer.FeaturePolicyHeader().IsEmpty())
UseCounter::Count(*this, WebFeature::kFeaturePolicyHeader);
- for (const auto& message :
- security_initializer.FeaturePolicyParseMessages()) {
- AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kError,
- "Error with Feature-Policy header: " + message));
- }
- if (frame_) {
- pending_parsed_headers_ = security_initializer.ParsedHeader();
- }
// At this point, the document will not have been installed in the frame's
// LocalDOMWindow, so we cannot call frame_->IsFeatureEnabled. This calls
@@ -6937,8 +6946,8 @@ void Document::FeaturePolicyInitialized(
is_vertical_scroll_enforced_ =
frame_ && !frame_->IsMainFrame() &&
RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled() &&
- !GetFeaturePolicy()->IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kVerticalScroll);
+ !GetSecurityContext().GetFeaturePolicy()->IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kVerticalScroll);
}
const ParsedFeaturePolicy Document::GetOwnerContainerPolicy() const {
@@ -6957,46 +6966,13 @@ const FeaturePolicy* Document::GetParentFeaturePolicy() const {
return nullptr;
}
-void Document::ApplyPendingFeaturePolicyHeaders() {
+void Document::ApplyPendingFramePolicyHeaders() {
if (frame_) {
- frame_->Client()->DidSetFramePolicyHeaders(GetSandboxFlags(),
- pending_parsed_headers_);
+ frame_->Client()->DidSetFramePolicyHeaders(
+ GetSandboxFlags(), pending_fp_headers_, pending_dp_headers_);
}
- pending_parsed_headers_.clear();
-}
-
-void Document::ApplyReportOnlyFeaturePolicyFromHeader(
- const String& feature_policy_report_only_header) {
- if (feature_policy_report_only_header.IsEmpty())
- return;
- // TODO(iclelland): Remove this message when reporting is no longer part of an
- // origin trial.
- // Note that we do not return here. Instead, the header is parsed and the
- // report-only policy is stored, in case a valid Origin Trial token is added
- // later. In that case, any subsequent violations will be correctly reported.
- if (!RuntimeEnabledFeatures::FeaturePolicyReportingEnabled(this)) {
- AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kWarning,
- "Feature-Policy-Report-Only header will have no effect unless Feature "
- "Policy reporting is enabled with an Origin Trial. Sign up at "
- "https://developers.chrome.com/origintrials/"));
- }
-
- UseCounter::Count(*this, WebFeature::kFeaturePolicyReportOnlyHeader);
- Vector<String> messages;
- const ParsedFeaturePolicy& report_only_policy =
- FeaturePolicyParser::ParseHeader(feature_policy_report_only_header,
- GetSecurityOrigin(), &messages, this);
- for (auto& message : messages) {
- AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kError,
- "Error with Feature-Policy-Report-Only header: " + message));
- }
-
- AddReportOnlyFeaturePolicy(report_only_policy, GetOwnerContainerPolicy(),
- GetParentFeaturePolicy());
+ pending_fp_headers_.clear();
+ pending_dp_headers_.clear();
}
bool Document::AllowedToUseDynamicMarkUpInsertion(
@@ -7005,8 +6981,9 @@ bool Document::AllowedToUseDynamicMarkUpInsertion(
if (!RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled()) {
return true;
}
- if (!frame_ || IsFeatureEnabled(mojom::FeaturePolicyFeature::kDocumentWrite,
- ReportOptions::kReportOnFailure)) {
+ if (!frame_ ||
+ IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kDocumentWrite,
+ ReportOptions::kReportOnFailure)) {
return true;
}
@@ -7053,16 +7030,13 @@ FontMatchingMetrics* Document::GetFontMatchingMetrics() {
}
void Document::InitContentSecurityPolicy(ContentSecurityPolicy* csp) {
- SetContentSecurityPolicy(csp);
+ GetSecurityContext().SetContentSecurityPolicy(csp);
GetContentSecurityPolicy()->BindToDelegate(
GetContentSecurityPolicyDelegate());
}
-void Document::InitSecurityContext(
- const DocumentInit& initializer,
- const SecurityContextInit& security_initializer) {
+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
@@ -7070,21 +7044,17 @@ void Document::InitSecurityContext(
// callbacks from binding the CSP delegate immediately would not get called
// if it was bound immediately. eg. Callbacks back to browser or console
// logging.
- if (security_initializer.BindCSPImmediately()) {
- InitContentSecurityPolicy(security_initializer.GetCSP());
- } else {
- SetContentSecurityPolicy(security_initializer.GetCSP());
- }
if (!initializer.HasSecurityContext()) {
// No source for a security context.
// This can occur via document.implementation.createDocument().
cookie_url_ = KURL(g_empty_string);
return;
}
- SetInsecureRequestPolicy(initializer.GetInsecureRequestPolicy());
+ GetSecurityContext().SetInsecureRequestPolicy(
+ initializer.GetInsecureRequestPolicy());
if (initializer.InsecureNavigationsToUpgrade()) {
for (auto to_upgrade : *initializer.InsecureNavigationsToUpgrade())
- AddInsecureNavigationUpgrade(to_upgrade);
+ GetSecurityContext().AddInsecureNavigationUpgrade(to_upgrade);
}
bool inherit_cookie_url_from_owner = initializer.IsSrcdocDocument() ||
@@ -7095,15 +7065,7 @@ void Document::InitSecurityContext(
? initializer.OwnerDocument()->CookieURL()
: url_;
- SetAddressSpace(initializer.GetIPAddressSpace());
-}
-
-void Document::SetSecurityOrigin(scoped_refptr<SecurityOrigin> origin) {
- // Enforce that we don't change access, we might change the reference (via
- // IsolatedCopy but we can't change the security policy).
- CHECK(origin);
- CHECK(GetSecurityOrigin()->CanAccess(origin.get()));
- SecurityContext::SetSecurityOrigin(origin);
+ GetSecurityContext().SetAddressSpace(initializer.GetIPAddressSpace());
}
void Document::BindContentSecurityPolicy() {
@@ -7120,12 +7082,12 @@ bool Document::CanExecuteScripts(ReasonForCallingCanExecuteScripts reason) {
// 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(WebSandboxFlags::kScripts) &&
- !ContentSecurityPolicy::ShouldBypassMainWorld(this)) {
+ if (IsSandboxed(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(ConsoleMessage::Create(
+ AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kSecurity,
mojom::ConsoleMessageLevel::kError,
"Blocked script execution in '" + Url().ElidedString() +
@@ -7186,10 +7148,6 @@ bool Document::AllowInlineEventHandler(Node* node,
return true;
}
-bool Document::IsContextThread() const {
- return IsMainThread();
-}
-
void Document::UpdateFocusAppearanceAfterLayout() {
update_focus_appearance_after_layout_ = true;
}
@@ -7238,7 +7196,7 @@ void Document::InitDNSPrefetch() {
void Document::ParseDNSPrefetchControlHeader(
const String& dns_prefetch_control) {
- if (DeprecatedEqualIgnoringCase(dns_prefetch_control, "on") &&
+ if (EqualIgnoringASCIICase(dns_prefetch_control, "on") &&
!have_explicitly_disabled_dns_prefetch_) {
is_dns_prefetch_enabled_ = true;
return;
@@ -7256,11 +7214,26 @@ IntersectionObserverController&
Document::EnsureIntersectionObserverController() {
if (!intersection_observer_controller_) {
intersection_observer_controller_ =
- MakeGarbageCollected<IntersectionObserverController>(this);
+ MakeGarbageCollected<IntersectionObserverController>(
+ GetExecutionContext());
}
return *intersection_observer_controller_;
}
+ElementIntersectionObserverData*
+Document::DocumentExplicitRootIntersectionObserverData() const {
+ return document_explicit_root_intersection_observer_data_.Get();
+}
+
+ElementIntersectionObserverData&
+Document::EnsureDocumentExplicitRootIntersectionObserverData() {
+ if (!document_explicit_root_intersection_observer_data_) {
+ document_explicit_root_intersection_observer_data_ =
+ MakeGarbageCollected<ElementIntersectionObserverData>();
+ }
+ return *document_explicit_root_intersection_observer_data_;
+}
+
ResizeObserverController& Document::EnsureResizeObserverController() {
if (!resize_observer_controller_) {
resize_observer_controller_ =
@@ -7269,76 +7242,22 @@ ResizeObserverController& Document::EnsureResizeObserverController() {
return *resize_observer_controller_;
}
-static void RunAddConsoleMessageTask(mojom::ConsoleMessageSource source,
- mojom::ConsoleMessageLevel level,
- const String& message,
- ExecutionContext* context,
- bool discard_duplicates) {
- ConsoleMessage* console_message =
- ConsoleMessage::Create(source, level, message);
- context->AddConsoleMessage(console_message, discard_duplicates);
+void Document::AddConsoleMessage(ConsoleMessage* message,
+ bool discard_duplicates) {
+ // Don't let non-attached Documents spam the console.
+ if (domWindow())
+ domWindow()->AddConsoleMessage(message, discard_duplicates);
}
-void Document::AddConsoleMessageImpl(ConsoleMessage* console_message,
- bool discard_duplicates) {
- if (!IsContextThread()) {
- PostCrossThreadTask(
- *GetTaskRunner(TaskType::kInternalInspector), FROM_HERE,
- CrossThreadBindOnce(
- &RunAddConsoleMessageTask, console_message->Source(),
- console_message->Level(), console_message->Message(),
- WrapCrossThreadPersistent(this), discard_duplicates));
- return;
- }
+void Document::AddInspectorIssue(InspectorIssue* issue) {
+ Page* page = GetPage();
- if (!frame_) {
- if (imports_controller_) {
- imports_controller_->Master()->GetFrame()->Console().AddMessage(
- console_message);
- }
+ if (!page) {
return;
}
- if (console_message->Location()->IsUnknown()) {
- // TODO(dgozman): capture correct location at call places instead.
- unsigned line_number = 0;
- if (!IsInDocumentWrite() && GetScriptableDocumentParser()) {
- ScriptableDocumentParser* parser = GetScriptableDocumentParser();
- if (parser->IsParsingAtLineNumber())
- line_number = parser->LineNumber().OneBasedInt();
- }
- Vector<DOMNodeId> nodes(console_message->Nodes());
- console_message = ConsoleMessage::Create(
- console_message->Source(), console_message->Level(),
- console_message->Message(),
- std::make_unique<SourceLocation>(Url().GetString(), line_number, 0,
- nullptr));
- console_message->SetNodes(frame_, std::move(nodes));
- }
-
- frame_->Console().AddMessage(console_message, discard_duplicates);
-}
-
-void Document::TasksWerePaused() {
- GetScriptRunner()->Suspend();
-
- if (scripted_animation_controller_)
- scripted_animation_controller_->Pause();
-}
-
-void Document::TasksWereUnpaused() {
- GetScriptRunner()->Resume();
-
- if (scripted_animation_controller_)
- scripted_animation_controller_->Unpause();
-
- if (dom_window_)
- DOMWindowPerformance::performance(*dom_window_)->ResumeSuspendedObservers();
-}
-
-bool Document::TasksNeedPause() {
- Page* page = GetPage();
- return page && page->Paused();
+ page->GetInspectorIssueStorage().AddInspectorIssue(GetExecutionContext(),
+ issue);
}
void Document::AddToTopLayer(Element* element, const Element* before) {
@@ -7441,36 +7360,24 @@ void Document::LoadPluginsSoon() {
}
void Document::PluginLoadingTimerFired(TimerBase*) {
- UpdateStyleAndLayout();
+ UpdateStyleAndLayout(DocumentUpdateReason::kPlugin);
}
-ScriptedAnimationController& Document::EnsureScriptedAnimationController() {
- if (!scripted_animation_controller_) {
- scripted_animation_controller_ =
- MakeGarbageCollected<ScriptedAnimationController>(this);
- // We need to make sure that we don't start up the animation controller on a
- // background tab, for example.
- if (!GetPage())
- scripted_animation_controller_->Pause();
- }
+ScriptedAnimationController& Document::GetScriptedAnimationController() {
return *scripted_animation_controller_;
}
int Document::RequestAnimationFrame(
FrameRequestCallbackCollection::FrameCallback* callback) {
- return EnsureScriptedAnimationController().RegisterFrameCallback(callback);
+ return scripted_animation_controller_->RegisterFrameCallback(callback);
}
void Document::CancelAnimationFrame(int id) {
- if (!scripted_animation_controller_)
- return;
scripted_animation_controller_->CancelFrameCallback(id);
}
void Document::ServiceScriptedAnimations(
base::TimeTicks monotonic_animation_start_time) {
- if (!scripted_animation_controller_)
- return;
auto start_time = base::TimeTicks::Now();
scripted_animation_controller_->ServiceScriptedAnimations(
monotonic_animation_start_time);
@@ -7482,29 +7389,27 @@ void Document::ServiceScriptedAnimations(
int Document::RequestPostAnimationFrame(
FrameRequestCallbackCollection::FrameCallback* cb) {
- return EnsureScriptedAnimationController().RegisterPostFrameCallback(cb);
+ return scripted_animation_controller_->RegisterPostFrameCallback(cb);
}
void Document::CancelPostAnimationFrame(int id) {
- if (scripted_animation_controller_)
- scripted_animation_controller_->CancelPostFrameCallback(id);
+ scripted_animation_controller_->CancelPostFrameCallback(id);
}
void Document::RunPostAnimationFrameCallbacks() {
bool was_throttled = current_frame_is_throttled_;
current_frame_is_throttled_ = false;
- if (was_throttled || !scripted_animation_controller_)
+ if (was_throttled)
return;
scripted_animation_controller_->RunPostFrameCallbacks();
}
ScriptedIdleTaskController& Document::EnsureScriptedIdleTaskController() {
if (!scripted_idle_task_controller_) {
- scripted_idle_task_controller_ = ScriptedIdleTaskController::Create(this);
- // We need to make sure that we don't start up the idle controller if we
- // don't have an attached frame and if execution context is destroyed.
- if (!frame_ || !frame_->IsAttached() ||
- ExecutionContext::IsContextDestroyed()) {
+ scripted_idle_task_controller_ =
+ ScriptedIdleTaskController::Create(domWindow());
+ // We need to make sure that we don't start up if we're detached.
+ if (!domWindow() || domWindow()->IsContextDestroyed()) {
scripted_idle_task_controller_->ContextLifecycleStateChanged(
mojom::FrameLifecycleState::kFrozen);
}
@@ -7541,11 +7446,11 @@ Node* EventTargetNodeForDocument(Document* doc) {
if (!doc)
return nullptr;
Node* node = doc->FocusedElement();
- if (!node && doc->IsPluginDocument()) {
- PluginDocument* plugin_document = ToPluginDocument(doc);
+ auto* plugin_document = DynamicTo<PluginDocument>(doc);
+ if (plugin_document && !node) {
node = plugin_document->PluginNode();
}
- if (!node && doc->IsHTMLDocument())
+ if (!node && IsA<HTMLDocument>(doc))
node = doc->body();
if (!node)
node = doc->documentElement();
@@ -7587,6 +7492,15 @@ SnapCoordinator& Document::GetSnapCoordinator() {
return *snap_coordinator_;
}
+void Document::PerformScrollSnappingTasks() {
+ SnapCoordinator& snap_coordinator = GetSnapCoordinator();
+ if (!snap_coordinator.AnySnapContainerDataNeedsUpdate())
+ return;
+ snap_coordinator.UpdateAllSnapContainerDataIfNeeded();
+ if (RuntimeEnabledFeatures::ScrollSnapAfterLayoutEnabled())
+ snap_coordinator.ResnapAllContainersIfNeeded();
+}
+
void Document::SetContextFeatures(ContextFeatures& features) {
context_features_ = &features;
}
@@ -7725,7 +7639,8 @@ bool Document::HaveScriptBlockingStylesheetsLoaded() const {
bool Document::HaveRenderBlockingResourcesLoaded() const {
return HaveImportsLoaded() &&
- style_engine_->HaveRenderBlockingStylesheetsLoaded();
+ style_engine_->HaveRenderBlockingStylesheetsLoaded() &&
+ !font_preload_manager_.HasPendingRenderBlockingFonts();
}
Locale& Document::GetCachedLocale(const AtomicString& locale) {
@@ -7757,7 +7672,7 @@ Document& Document::EnsureTemplateDocument() {
if (template_document_)
return *template_document_;
- if (IsHTMLDocument()) {
+ if (IsA<HTMLDocument>(this)) {
template_document_ = MakeGarbageCollected<HTMLDocument>(
DocumentInit::Create()
.WithContextDocument(ContextDocument())
@@ -7765,7 +7680,9 @@ Document& Document::EnsureTemplateDocument() {
.WithNewRegistrationContext());
} else {
template_document_ = MakeGarbageCollected<Document>(
- DocumentInit::Create().WithURL(BlankURL()));
+ DocumentInit::Create()
+ .WithContextDocument(ContextDocument())
+ .WithURL(BlankURL()));
}
template_document_->template_document_host_ = this; // balanced in dtor.
@@ -7837,8 +7754,6 @@ void Document::EnqueueAutofocusCandidate(Element& element) {
if (index != WTF::kNotFound)
autofocus_candidates_.EraseAt(index);
autofocus_candidates_.push_back(element);
- // ScriptedAnimationController invokes FlushAutofocusCandidates().
- EnsureScriptedAnimationController();
}
bool Document::HasAutofocusCandidates() const {
@@ -7863,22 +7778,22 @@ void Document::FlushAutofocusCandidates() {
if (AdjustedFocusedElement()) {
autofocus_candidates_.clear();
autofocus_processed_flag_ = true;
- AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kRendering,
- mojom::ConsoleMessageLevel::kInfo,
- "Autofocus processing was blocked because a "
- "document already has a focused element."));
+ AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kRendering,
+ mojom::ConsoleMessageLevel::kInfo,
+ "Autofocus processing was blocked because a "
+ "document already has a focused element."));
return;
}
if (HasNonEmptyFragment()) {
autofocus_candidates_.clear();
autofocus_processed_flag_ = true;
- AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kRendering,
- mojom::ConsoleMessageLevel::kInfo,
- "Autofocus processing was blocked because a "
- "document's URL has a fragment '#" +
- Url().FragmentIdentifier() + "'."));
+ AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kRendering,
+ mojom::ConsoleMessageLevel::kInfo,
+ "Autofocus processing was blocked because a "
+ "document's URL has a fragment '#" +
+ Url().FragmentIdentifier() + "'."));
return;
}
@@ -7933,12 +7848,12 @@ void Document::FlushAutofocusCandidates() {
doc = &frameOwner->GetDocument();
}
if (doc->HasNonEmptyFragment()) {
- AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kRendering,
- mojom::ConsoleMessageLevel::kInfo,
- "Autofocus processing was blocked because a "
- "document's URL has a fragment '#" +
- doc->Url().FragmentIdentifier() + "'."));
+ AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kRendering,
+ mojom::ConsoleMessageLevel::kInfo,
+ "Autofocus processing was blocked because a "
+ "document's URL has a fragment '#" +
+ doc->Url().FragmentIdentifier() + "'."));
continue;
}
DCHECK_EQ(doc, this);
@@ -8093,23 +8008,11 @@ void Document::PlatformColorsChanged() {
GetStyleEngine().PlatformColorsChanged();
}
-bool Document::IsSecureContext(String& error_message) const {
- if (!IsSecureContext()) {
- error_message = SecurityOrigin::IsPotentiallyTrustworthyErrorMessage();
- return false;
- }
- return true;
-}
-
-bool Document::IsSecureContext() const {
- return secure_context_state_ == SecureContextState::kSecure;
-}
-
void Document::DidEnforceInsecureRequestPolicy() {
if (!GetFrame())
return;
GetFrame()->GetLocalFrameHostRemote().EnforceInsecureRequestPolicy(
- GetInsecureRequestPolicy());
+ GetSecurityContext().GetInsecureRequestPolicy());
}
void Document::DidEnforceInsecureNavigationsSet() {
@@ -8117,18 +8020,7 @@ void Document::DidEnforceInsecureNavigationsSet() {
return;
GetFrame()->GetLocalFrameHostRemote().EnforceInsecureNavigationsSet(
SecurityContext::SerializeInsecureNavigationSet(
- InsecureNavigationsToUpgrade()));
-}
-
-void Document::CountDetachingNodeAccessInDOMNodeRemovedHandler() {
- auto state = GetInDOMNodeRemovedHandlerState();
- DCHECK_NE(state, InDOMNodeRemovedHandlerState::kNone);
- UseCounter::Count(
- *this,
- state == InDOMNodeRemovedHandlerState::kDOMNodeRemoved
- ? WebFeature::kDOMNodeRemovedEventHandlerAccessDetachingNode
- : WebFeature::
- kDOMNodeRemovedFromDocumentEventHandlerAccessDetachingNode);
+ GetSecurityContext().InsecureNavigationsToUpgrade()));
}
void Document::SetShadowCascadeOrder(ShadowCascadeOrder order) {
@@ -8194,13 +8086,6 @@ CoreProbeSink* Document::GetProbeSink() {
return probe::ToCoreProbeSink(frame);
}
-service_manager::InterfaceProvider* Document::GetInterfaceProvider() {
- if (!GetFrame())
- return nullptr;
-
- return &GetFrame()->GetInterfaceProvider();
-}
-
BrowserInterfaceBrokerProxy& Document::GetBrowserInterfaceBroker() {
if (!GetFrame())
return GetEmptyBrowserInterfaceBroker();
@@ -8218,17 +8103,7 @@ DocumentResourceCoordinator* Document::GetResourceCoordinator() {
FrameOrWorkerScheduler* Document::GetScheduler() {
DCHECK(IsMainThread());
-
- if (ContextDocument() && ContextDocument()->GetFrame())
- return ContextDocument()->GetFrame()->GetFrameScheduler();
- // In most cases, ContextDocument() will get us to a relevant Frame. In some
- // cases, though, there isn't a good candidate (most commonly when either the
- // passed-in document or ContextDocument() used to be attached to a Frame but
- // has since been detached).
- if (!detached_scheduler_) {
- detached_scheduler_ = scheduler::CreateDummyFrameScheduler();
- }
- return detached_scheduler_.get();
+ return GetExecutionContext()->GetScheduler();
}
scoped_refptr<base::SingleThreadTaskRunner> Document::GetTaskRunner(
@@ -8278,7 +8153,9 @@ StylePropertyMapReadOnly* Document::RemoveComputedStyleMapItem(
}
void Document::Trace(Visitor* visitor) {
+ visitor->Trace(security_context_);
visitor->Trace(imports_controller_);
+ visitor->Trace(use_counter_during_construction_);
visitor->Trace(doc_type_);
visitor->Trace(implementation_);
visitor->Trace(autofocus_candidates_);
@@ -8300,6 +8177,7 @@ void Document::Trace(Visitor* visitor) {
visitor->Trace(elem_sheet_);
visitor->Trace(node_iterators_);
visitor->Trace(ranges_);
+ visitor->Trace(document_explicit_root_intersection_observer_data_);
visitor->Trace(style_engine_);
visitor->Trace(form_controller_);
visitor->Trace(visited_link_state_);
@@ -8325,6 +8203,7 @@ void Document::Trace(Visitor* visitor) {
visitor->Trace(template_document_host_);
visitor->Trace(user_action_elements_);
visitor->Trace(svg_extensions_);
+ visitor->Trace(document_animations_);
visitor->Trace(timeline_);
visitor->Trace(pending_animations_);
visitor->Trace(worklet_animation_controller_);
@@ -8338,21 +8217,22 @@ void Document::Trace(Visitor* visitor) {
visitor->Trace(policy_);
visitor->Trace(slot_assignment_engine_);
visitor->Trace(viewport_data_);
+ visitor->Trace(display_lock_contexts_);
visitor->Trace(navigation_initiator_);
visitor->Trace(lazy_load_image_observer_);
visitor->Trace(isolated_world_csp_map_);
visitor->Trace(find_in_page_root_);
visitor->Trace(computed_node_mapping_);
visitor->Trace(mime_handler_view_before_unload_event_listener_);
+ visitor->Trace(cookie_jar_);
+ visitor->Trace(synchronous_mutation_observer_list_);
visitor->Trace(element_explicitly_set_attr_elements_map_);
visitor->Trace(display_lock_activation_observer_);
+ visitor->Trace(permission_service_);
+ visitor->Trace(font_preload_manager_);
Supplementable<Document>::Trace(visitor);
TreeScope::Trace(visitor);
ContainerNode::Trace(visitor);
- ExecutionContext::Trace(visitor);
- SecurityContext::Trace(visitor);
- DocumentShutdownNotifier::Trace(visitor);
- SynchronousMutationNotifier::Trace(visitor);
}
void Document::RecordUkmOutliveTimeAfterShutdown(int outlive_time_count) {
@@ -8368,13 +8248,11 @@ void Document::RecordUkmOutliveTimeAfterShutdown(int outlive_time_count) {
}
bool Document::CurrentFrameHadRAF() const {
- return scripted_animation_controller_ &&
- scripted_animation_controller_->CurrentFrameHadRAF();
+ return scripted_animation_controller_->CurrentFrameHadRAF();
}
bool Document::NextFrameHasPendingRAF() const {
- return scripted_animation_controller_ &&
- scripted_animation_controller_->NextFrameHasPendingRAF();
+ return scripted_animation_controller_->NextFrameHasPendingRAF();
}
void Document::NavigateLocalAdsFrames() {
@@ -8384,9 +8262,8 @@ void Document::NavigateLocalAdsFrames() {
child = child->Tree().TraverseNext(frame_)) {
if (auto* child_local_frame = DynamicTo<LocalFrame>(child)) {
if (child_local_frame->IsAdSubframe()) {
- child_local_frame->Navigate(
- FrameLoadRequest(this, ResourceRequest(BlankURL())),
- WebFrameLoadType::kStandard);
+ FrameLoadRequest request(this, ResourceRequest(BlankURL()));
+ child_local_frame->Navigate(request, WebFrameLoadType::kStandard);
}
}
// TODO(yuzus): Once AdsTracker for remote frames is implemented and OOPIF
@@ -8412,11 +8289,14 @@ bool Document::IsSlotAssignmentOrLegacyDistributionDirty() const {
bool Document::IsLazyLoadPolicyEnforced() const {
return RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled() &&
- !GetFeaturePolicy()->IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kLazyLoad);
+ !GetSecurityContext().GetFeaturePolicy()->IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kLazyLoad);
}
bool Document::IsFocusAllowed() const {
+ if (frame_ && frame_->GetPage()->InsidePortal())
+ return false;
+
if (!frame_ || frame_->IsMainFrame() ||
LocalFrame::HasTransientUserActivation(frame_)) {
// 'autofocus' runs Element::focus asynchronously at which point the
@@ -8425,7 +8305,7 @@ bool Document::IsFocusAllowed() const {
}
WebFeature uma_type;
- bool sandboxed = IsSandboxed(WebSandboxFlags::kNavigation);
+ bool sandboxed = IsSandboxed(mojom::blink::WebSandboxFlags::kNavigation);
bool ad = frame_->IsAdSubframe();
if (sandboxed) {
uma_type = ad ? WebFeature::kFocusWithoutUserActivationSandboxedAdFrame
@@ -8439,7 +8319,7 @@ bool Document::IsFocusAllowed() const {
if (!RuntimeEnabledFeatures::BlockingFocusWithoutUserActivationEnabled())
return true;
return IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kFocusWithoutUserActivation);
+ mojom::blink::FeaturePolicyFeature::kFocusWithoutUserActivation);
}
NavigationInitiatorImpl& Document::NavigationInitiator() {
@@ -8463,11 +8343,12 @@ WindowAgent& Document::GetWindowAgent() {
}
void Document::CountPotentialFeaturePolicyViolation(
- mojom::FeaturePolicyFeature feature) const {
+ mojom::blink::FeaturePolicyFeature feature) const {
wtf_size_t index = static_cast<wtf_size_t>(feature);
if (potentially_violated_features_.size() == 0) {
potentially_violated_features_.resize(
- static_cast<wtf_size_t>(mojom::FeaturePolicyFeature::kMaxValue) + 1);
+ static_cast<wtf_size_t>(mojom::blink::FeaturePolicyFeature::kMaxValue) +
+ 1);
} else if (potentially_violated_features_[index]) {
return;
}
@@ -8476,8 +8357,8 @@ void Document::CountPotentialFeaturePolicyViolation(
feature);
}
void Document::ReportFeaturePolicyViolation(
- mojom::FeaturePolicyFeature feature,
- mojom::FeaturePolicyDisposition disposition,
+ mojom::blink::FeaturePolicyFeature feature,
+ mojom::blink::PolicyDisposition disposition,
const String& message,
const String& source_file) const {
if (!RuntimeEnabledFeatures::FeaturePolicyReportingEnabled(this))
@@ -8489,7 +8370,7 @@ void Document::ReportFeaturePolicyViolation(
// Construct the feature policy violation report.
const String& feature_name = GetNameForFeature(feature);
const String& disp_str =
- (disposition == mojom::FeaturePolicyDisposition::kReport ? "report"
+ (disposition == mojom::blink::PolicyDisposition::kReport ? "report"
: "enforce");
FeaturePolicyViolationReportBody* body =
@@ -8504,12 +8385,12 @@ void Document::ReportFeaturePolicyViolation(
ReportType::kFeaturePolicyViolation, Url().GetString(), body);
// Send the feature policy violation report to any ReportingObservers.
- auto* reporting_context = ReportingContext::From(this);
+ auto* reporting_context = ReportingContext::From(domWindow());
reporting_context->QueueReport(report);
// TODO(iclelland): Report something different in report-only mode
- if (disposition == mojom::FeaturePolicyDisposition::kEnforce) {
- frame->Console().AddMessage(ConsoleMessage::Create(
+ if (disposition == mojom::blink::PolicyDisposition::kEnforce) {
+ frame->Console().AddMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kViolation,
mojom::ConsoleMessageLevel::kError,
(message.IsEmpty() ? ("Feature policy violation: " + feature_name +
@@ -8518,36 +8399,144 @@ void Document::ReportFeaturePolicyViolation(
}
}
+void Document::ReportDocumentPolicyViolation(
+ mojom::blink::DocumentPolicyFeature feature,
+ mojom::blink::PolicyDisposition disposition,
+ const String& message,
+ const String& source_file) const {
+ LocalFrame* frame = GetFrame();
+ if (!frame)
+ return;
+
+ // Construct the document policy violation report.
+ const String& feature_name =
+ GetDocumentPolicyFeatureInfoMap().at(feature).feature_name.c_str();
+ bool is_report_only = disposition == mojom::blink::PolicyDisposition::kReport;
+ const String& disp_str = is_report_only ? "report" : "enforce";
+ const DocumentPolicy* relevant_document_policy =
+ is_report_only ? GetSecurityContext().GetReportOnlyDocumentPolicy()
+ : GetSecurityContext().GetDocumentPolicy();
+
+ DocumentPolicyViolationReportBody* body =
+ source_file.IsEmpty()
+ ? MakeGarbageCollected<DocumentPolicyViolationReportBody>(
+ feature_name, "Document policy violation", disp_str)
+ : MakeGarbageCollected<DocumentPolicyViolationReportBody>(
+ feature_name, "Document policy violation", disp_str,
+ source_file);
+
+ Report* report = MakeGarbageCollected<Report>(
+ ReportType::kDocumentPolicyViolation, Url().GetString(), body);
+
+ // Send the document policy violation report to any ReportingObservers.
+ auto* reporting_context = ReportingContext::From(domWindow());
+ const base::Optional<std::string> endpoint =
+ relevant_document_policy->GetFeatureEndpoint(feature);
+
+ reporting_context->QueueReport(
+ report, endpoint ? Vector<String>{endpoint->c_str()} : Vector<String>{});
+
+ // TODO(iclelland): Report something different in report-only mode
+ if (!is_report_only) {
+ frame->Console().AddMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kViolation,
+ mojom::blink::ConsoleMessageLevel::kError,
+ (message.IsEmpty() ? ("Document policy violation: " + feature_name +
+ " is not allowed in this document.")
+ : message)));
+ }
+}
+
void Document::IncrementNumberOfCanvases() {
num_canvases_++;
}
-void Document::AddActivationBlockingDisplayLock() {
- ++activation_blocking_display_lock_count_;
+void Document::IncrementDisplayLockBlockingAllActivation() {
+ ++display_lock_blocking_all_activation_count_;
}
-void Document::RemoveActivationBlockingDisplayLock() {
- DCHECK_GT(activation_blocking_display_lock_count_, 0);
- --activation_blocking_display_lock_count_;
+void Document::DecrementDisplayLockBlockingAllActivation() {
+ DCHECK_GT(display_lock_blocking_all_activation_count_, 0);
+ --display_lock_blocking_all_activation_count_;
}
-int Document::ActivationBlockingDisplayLockCount() const {
- return activation_blocking_display_lock_count_;
+int Document::DisplayLockBlockingAllActivationCount() const {
+ return display_lock_blocking_all_activation_count_;
}
void Document::AddLockedDisplayLock() {
++locked_display_lock_count_;
+ TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("blink.debug.display_lock"),
+ "LockedDisplayLockCount", TRACE_ID_LOCAL(this),
+ locked_display_lock_count_);
}
void Document::RemoveLockedDisplayLock() {
DCHECK_GT(locked_display_lock_count_, 0);
--locked_display_lock_count_;
+ TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("blink.debug.display_lock"),
+ "LockedDisplayLockCount", TRACE_ID_LOCAL(this),
+ locked_display_lock_count_);
}
int Document::LockedDisplayLockCount() const {
return locked_display_lock_count_;
}
+void Document::AddDisplayLockContext(DisplayLockContext* context) {
+ display_lock_contexts_.insert(context);
+}
+
+void Document::RemoveDisplayLockContext(DisplayLockContext* context) {
+ display_lock_contexts_.erase(context);
+}
+
+int Document::DisplayLockCount() const {
+ return display_lock_contexts_.size();
+}
+
+void Document::NotifySelectionRemovedFromDisplayLocks() {
+ for (auto context : display_lock_contexts_)
+ context->NotifySubtreeLostSelection();
+}
+
+Document::ScopedForceActivatableDisplayLocks
+Document::GetScopedForceActivatableLocks() {
+ return ScopedForceActivatableDisplayLocks(this);
+}
+
+Document::ScopedForceActivatableDisplayLocks::
+ ScopedForceActivatableDisplayLocks(Document* document)
+ : document_(document) {
+ if (++document_->activatable_display_locks_forced_ == 1) {
+ for (auto context : document_->display_lock_contexts_)
+ context->DidForceActivatableDisplayLocks();
+ }
+}
+
+Document::ScopedForceActivatableDisplayLocks::
+ ScopedForceActivatableDisplayLocks(
+ ScopedForceActivatableDisplayLocks&& other)
+ : document_(other.document_) {
+ other.document_ = nullptr;
+}
+
+Document::ScopedForceActivatableDisplayLocks&
+Document::ScopedForceActivatableDisplayLocks::operator=(
+ ScopedForceActivatableDisplayLocks&& other) {
+ document_ = other.document_;
+ other.document_ = nullptr;
+ return *this;
+}
+
+Document::ScopedForceActivatableDisplayLocks::
+ ~ScopedForceActivatableDisplayLocks() {
+ if (!document_)
+ return;
+ DCHECK(document_->activatable_display_locks_forced_);
+ --document_->activatable_display_locks_forced_;
+}
+
void Document::RegisterDisplayLockActivationObservation(Element* element) {
EnsureDisplayLockActivationObserver().observe(element);
}
@@ -8566,22 +8555,28 @@ IntersectionObserver& Document::EnsureDisplayLockActivationObserver() {
{Length::Percent(50.f)}, {std::numeric_limits<float>::min()}, this,
WTF::BindRepeating(&Document::ProcessDisplayLockActivationObservation,
WrapWeakPersistent(this)),
- IntersectionObserver::kPostTaskToDeliver);
+ IntersectionObserver::kDeliverDuringPostLifecycleSteps);
}
return *display_lock_activation_observer_;
}
void Document::ProcessDisplayLockActivationObservation(
const HeapVector<Member<IntersectionObserverEntry>>& entries) {
+ DCHECK(View());
for (auto& entry : entries) {
+ auto* context = entry->target()->GetDisplayLockContext();
+ DCHECK(context);
if (entry->isIntersecting()) {
- auto* context = entry->target()->GetDisplayLockContext();
- DCHECK(context);
- DCHECK(context->ShouldCommitForActivation(
- DisplayLockActivationReason::kViewportIntersection));
- context->CommitForActivationWithSignal(entry->target());
+ View()->EnqueueStartOfLifecycleTask(
+ WTF::Bind(&DisplayLockContext::NotifyIsIntersectingViewport,
+ WrapWeakPersistent(context)));
+ } else {
+ View()->EnqueueStartOfLifecycleTask(
+ WTF::Bind(&DisplayLockContext::NotifyIsNotIntersectingViewport,
+ WrapWeakPersistent(context)));
}
}
+ View()->ScheduleAnimation();
}
void Document::ExecuteJavaScriptUrls() {
@@ -8600,7 +8595,7 @@ void Document::ExecuteJavaScriptUrls() {
void Document::ProcessJavaScriptUrl(
const KURL& url,
- ContentSecurityPolicyDisposition disposition) {
+ network::mojom::CSPDisposition disposition) {
DCHECK(url.ProtocolIsJavaScript());
if (frame_->Loader().StateMachine()->IsDisplayingInitialEmptyDocument())
load_event_progress_ = kLoadEventNotRun;
@@ -8667,146 +8662,55 @@ void Document::SetShowBeforeUnloadDialog(bool show_dialog) {
show_dialog);
}
-const Document* DocumentForTrustedTypes(const Document* doc) {
- // The Trusted Type factory & friends are stored on the window. For
- // programmatically created docs (like createHTMLDocument) let's use the one
- // from the context document.
- DCHECK(doc);
- while (doc->ContextDocument() && !doc->ExecutingWindow())
- doc = doc->ContextDocument();
- return doc;
+void Document::ColorSchemeChanged() {
+ UpdateForcedColors();
+ GetStyleEngine().ColorSchemeChanged();
+ MediaQueryAffectingValueChanged(MediaValueChange::kOther);
}
-TrustedTypePolicyFactory* Document::GetTrustedTypes() const {
- const Document* doc = DocumentForTrustedTypes(this);
- return doc->ExecutingWindow() ? doc->ExecutingWindow()->trustedTypes()
- : nullptr;
+void Document::VisionDeficiencyChanged() {
+ GetStyleEngine().VisionDeficiencyChanged();
}
-bool Document::RequireTrustedTypes() const {
- return DocumentForTrustedTypes(this)->ExecutionContext::RequireTrustedTypes();
+void Document::UpdateForcedColors() {
+ auto* web_theme_engine =
+ RuntimeEnabledFeatures::ForcedColorsEnabled() && Platform::Current()
+ ? Platform::Current()->ThemeEngine()
+ : nullptr;
+ ForcedColors forced_colors = web_theme_engine
+ ? web_theme_engine->GetForcedColors()
+ : ForcedColors::kNone;
+ in_forced_colors_mode_ = forced_colors != ForcedColors::kNone;
}
-void Document::ColorSchemeChanged() {
- GetStyleEngine().ColorSchemeChanged();
- MediaQueryAffectingValueChanged();
+bool Document::InForcedColorsMode() const {
+ return in_forced_colors_mode_ && !Printing();
}
-bool Document::InForcedColorsMode() const {
- return RuntimeEnabledFeatures::ForcedColorsEnabled() && Platform::Current() &&
- Platform::Current()->ThemeEngine() &&
- Platform::Current()->ThemeEngine()->GetForcedColors() !=
- ForcedColors::kNone;
+bool Document::IsCrossSiteSubframe() const {
+ // It'd be nice to avoid the url::Origin temporaries, but that would require
+ // exposing the net internal helper.
+ // TODO: If the helper gets exposed, we could do this without any new
+ // allocations using StringUTF8Adaptor.
+ return TopFrameOrigin() &&
+ !net::registry_controlled_domains::SameDomainOrHost(
+ TopFrameOrigin()->ToUrlOrigin(),
+ GetSecurityOrigin()->ToUrlOrigin(),
+ net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
}
void Document::CountUse(mojom::WebFeature feature) const {
- if (DocumentLoader* loader = Loader()) {
+ if (use_counter_during_construction_)
+ use_counter_during_construction_->CountUse(feature);
+ else if (DocumentLoader* loader = Loader())
loader->CountUse(feature);
- }
}
void Document::CountUse(mojom::WebFeature feature) {
- if (DocumentLoader* loader = Loader()) {
+ if (use_counter_during_construction_)
+ use_counter_during_construction_->CountUse(feature);
+ else if (DocumentLoader* loader = Loader())
loader->CountUse(feature);
- }
-}
-
-void Document::RecordCallInDetachedWindow(
- v8::Isolate::UseCounterFeature reason) {
- // Emit each reason only once (max twice, in the case explained below).
- // We're mainly interested if this kind of call occurred in a page or not.
- // It would be nice to count how many times, but that would flood the UKM
- // infrastructure with too many events.
- if (calls_in_detached_window_emitted_.Contains(reason))
- return;
-
- if (navigation_source_id_ == ukm::kInvalidSourceId) {
- // It's possible that navigation_source_id_ isn't set yet. Emit the event
- // with invalid ID (at most once) so that we could potentially make use of
- // it in combination with DocumentCreated event, using document's source ID.
- // However, save it to give it a chance to be emitted again with valid
- // navigation_source_id_.
- if (calls_in_detached_window_orphaned_.Contains(reason))
- return;
- calls_in_detached_window_orphaned_.insert(reason);
- }
-
- HashSet<v8::Isolate::UseCounterFeature> reasons;
- reasons.insert(reason);
- EmitDetachedWindowsUkmEvent(reasons);
-}
-
-void Document::SetNavigationSourceId(int64_t source_id) {
- navigation_source_id_ = source_id;
- if (navigation_source_id_ != ukm::kInvalidSourceId) {
- // Now that a valid navigation_source_id_ is set, re-emit the DetacheWindows
- // event for cases that were emitted with invalid ID.
- EmitDetachedWindowsUkmEvent(calls_in_detached_window_orphaned_);
- calls_in_detached_window_orphaned_.clear();
- }
-}
-
-void Document::EmitDetachedWindowsUkmEvent(
- const HashSet<v8::Isolate::UseCounterFeature>& reasons) {
- if (reasons.IsEmpty())
- return;
-
- DCHECK_NE(ukm_source_id_, ukm::kInvalidSourceId);
- ukm::builders::DetachedWindows_Experimental builder(ukm_source_id_);
- // Invalid ID should be 0 to take advantage of the protobuf default.
- DCHECK_EQ(ukm::kInvalidSourceId, 0);
- if (navigation_source_id_ != ukm::kInvalidSourceId)
- builder.SetNavigationSourceId(navigation_source_id_);
- for (auto reason : reasons) {
- if (navigation_source_id_ != ukm::kInvalidSourceId)
- calls_in_detached_window_emitted_.insert(reason);
-
- switch (reason) {
- case v8::Isolate::kCallInDetachedWindowByNavigation:
- builder.SetNumberOfCallsInDetachedWindowByNavigation(1);
- break;
- case v8::Isolate::kCallInDetachedWindowByNavigationAfter10s:
- builder
- .SetNumberOfCallsInDetachedWindowByNavigation_After10sSinceDetaching(
- 1);
- break;
- case v8::Isolate::kCallInDetachedWindowByNavigationAfter1min:
- builder
- .SetNumberOfCallsInDetachedWindowByNavigation_After1minSinceDetaching(
- 1);
- break;
- case v8::Isolate::kCallInDetachedWindowByClosing:
- builder.SetNumberOfCallsInDetachedWindowByClosing(1);
- break;
- case v8::Isolate::kCallInDetachedWindowByClosingAfter10s:
- builder
- .SetNumberOfCallsInDetachedWindowByClosing_After10sSinceDetaching(
- 1);
- break;
- case v8::Isolate::kCallInDetachedWindowByClosingAfter1min:
- builder
- .SetNumberOfCallsInDetachedWindowByClosing_After1minSinceDetaching(
- 1);
- break;
- case v8::Isolate::kCallInDetachedWindowByOtherReason:
- builder.SetNumberOfCallsInDetachedWindowByOtherReason(1);
- break;
- case v8::Isolate::kCallInDetachedWindowByOtherReasonAfter10s:
- builder
- .SetNumberOfCallsInDetachedWindowByOtherReason_After10sSinceDetaching(
- 1);
- break;
- case v8::Isolate::kCallInDetachedWindowByOtherReasonAfter1min:
- builder
- .SetNumberOfCallsInDetachedWindowByOtherReason_After1minSinceDetaching(
- 1);
- break;
- default:
- LOG(DFATAL) << "Use counter not related to detached windows: "
- << reason;
- }
- }
- builder.Record(UkmRecorder());
}
void Document::CountDeprecation(mojom::WebFeature feature) {
@@ -8828,7 +8732,17 @@ void Document::CountDeprecation(mojom::WebFeature feature) {
CountUse(WebFeature::kDocumentRegisterElementOnReverseOriginTrials);
}
}
- Deprecation::CountDeprecation(Loader(), feature);
+
+ // 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);
+ }
}
void Document::CountProperty(CSSPropertyID property) const {
@@ -8848,7 +8762,7 @@ void Document::CountAnimatedProperty(CSSPropertyID property) const {
void Document::CountUseOnlyInCrossOriginIframe(
mojom::WebFeature feature) const {
LocalFrame* frame = GetFrame();
- if (frame && frame->IsCrossOriginSubframe())
+ if (frame && frame->IsCrossOriginToMainFrame())
CountUse(feature);
}
@@ -8880,6 +8794,19 @@ void Document::ClearUseCounterForTesting(mojom::WebFeature feature) {
loader->GetUseCounterHelper().ClearMeasurementForTesting(feature);
}
+void Document::FontPreloadingFinishedOrTimedOut() {
+ DCHECK(!font_preload_manager_.HasPendingRenderBlockingFonts());
+ if (IsA<HTMLDocument>(this) && body()) {
+ // For HTML, we resume only when we're past the body tag, so that we should
+ // have something to paint now.
+ BeginLifecycleUpdatesIfRenderingReady();
+ } else if (!IsA<HTMLDocument>(this) && documentElement()) {
+ // For non-HTML there is no body so resume as soon as font preloading is
+ // done or has timed out.
+ BeginLifecycleUpdatesIfRenderingReady();
+ }
+}
+
template class CORE_TEMPLATE_EXPORT Supplement<Document>;
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/dom/document.h b/chromium/third_party/blink/renderer/core/dom/document.h
index 3d25b6321cb..6733851f425 100644
--- a/chromium/third_party/blink/renderer/core/dom/document.h
+++ b/chromium/third_party/blink/renderer/core/dom/document.h
@@ -36,25 +36,24 @@
#include "base/memory/scoped_refptr.h"
#include "base/timer/elapsed_timer.h"
+#include "net/cookies/site_for_cookies.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
-#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
-#include "third_party/blink/public/mojom/ukm/ukm.mojom-blink.h"
-#include "third_party/blink/public/platform/web_focus_type.h"
-#include "third_party/blink/public/platform/web_insecure_request_policy.h"
+#include "third_party/blink/public/common/metrics/document_update_reason.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
+#include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h"
+#include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink.h"
#include "third_party/blink/renderer/core/accessibility/axid.h"
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/css/media_value_change.h"
#include "third_party/blink/renderer/core/dom/container_node.h"
#include "third_party/blink/renderer/core/dom/create_element_flags.h"
#include "third_party/blink/renderer/core/dom/document_encoding_data.h"
#include "third_party/blink/renderer/core/dom/document_lifecycle.h"
-#include "third_party/blink/renderer/core/dom/document_shutdown_notifier.h"
-#include "third_party/blink/renderer/core/dom/document_shutdown_observer.h"
#include "third_party/blink/renderer/core/dom/document_timing.h"
#include "third_party/blink/renderer/core/dom/frame_request_callback_collection.h"
#include "third_party/blink/renderer/core/dom/live_node_list_registry.h"
#include "third_party/blink/renderer/core/dom/qualified_name.h"
#include "third_party/blink/renderer/core/dom/scripted_idle_task_controller.h"
-#include "third_party/blink/renderer/core/dom/synchronous_mutation_notifier.h"
#include "third_party/blink/renderer/core/dom/synchronous_mutation_observer.h"
#include "third_party/blink/renderer/core/dom/text_link_colors.h"
#include "third_party/blink/renderer/core/dom/tree_scope.h"
@@ -62,10 +61,12 @@
#include "third_party/blink/renderer/core/editing/forward.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/execution_context/security_context.h"
-#include "third_party/blink/renderer/core/frame/hosts_using_features.h"
#include "third_party/blink/renderer/core/html/custom/v0_custom_element.h"
#include "third_party/blink/renderer/core/html/parser/parser_synchronization_policy.h"
+#include "third_party/blink/renderer/core/loader/font_preload_manager.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/heap_observer_list.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -80,6 +81,12 @@ namespace ukm {
class UkmRecorder;
} // namespace ukm
+namespace network {
+namespace mojom {
+enum class CSPDisposition : int32_t;
+} // namespace mojom
+} // namespace network
+
namespace blink {
class AnimationClock;
@@ -92,11 +99,15 @@ class CSSStyleSheet;
class CanvasFontCache;
class ChromeClient;
class Comment;
+class CompositorAnimationTimeline;
class ComputedAccessibleNode;
+class DisplayLockContext;
+class ElementIntersectionObserverData;
class WindowAgent;
class WindowAgentFactory;
class ComputedStyle;
class ConsoleMessage;
+class InspectorIssue;
class ContextFeatures;
class CookieJar;
class V0CustomElementMicrotaskRunQueue;
@@ -112,6 +123,7 @@ class DocumentOutliveTimeReporter;
class DocumentParser;
class DocumentResourceCoordinator;
class DocumentState;
+class DocumentAnimations;
class DocumentTimeline;
class DocumentType;
class DOMFeaturePolicy;
@@ -130,6 +142,7 @@ class FontMatchingMetrics;
class FormController;
class HTMLAllCollection;
class HTMLBodyElement;
+class FrameScheduler;
class HTMLCollection;
class HTMLDialogElement;
class HTMLElement;
@@ -178,6 +191,7 @@ class ScriptPromise;
class ScriptRunner;
class ScriptableDocumentParser;
class ScriptedAnimationController;
+class SecurityContextInit;
class SecurityOrigin;
class SelectorQueryCache;
class SerializedScriptValue;
@@ -198,9 +212,7 @@ class VisitedLinkState;
class WebComputedAXTree;
class WebMouseEvent;
class WorkletAnimationController;
-enum ContentSecurityPolicyDisposition : uint8_t;
enum class CSSPropertyID;
-enum class ScrollbarMode;
struct AnnotatedRegionValue;
struct FocusParams;
struct IconURL;
@@ -238,8 +250,6 @@ enum ShadowCascadeOrder {
kShadowCascadeV1
};
-enum class SecureContextState { kNonSecure, kSecure };
-
using DocumentClassFlags = unsigned char;
// A map of IDL attribute name to Element value, for one particular element.
@@ -262,10 +272,8 @@ using ExplicitlySetAttrElementsMap =
// the user in a frame and an execution context for JavaScript code.
class CORE_EXPORT Document : public ContainerNode,
public TreeScope,
- public SecurityContext,
- public ExecutionContext,
- public DocumentShutdownNotifier,
- public SynchronousMutationNotifier,
+ public UseCounter,
+ public FeaturePolicyParserDelegate,
public Supplementable<Document> {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(Document);
@@ -292,17 +300,129 @@ class CORE_EXPORT Document : public ContainerNode,
MediaQueryMatcher& GetMediaQueryMatcher();
- void MediaQueryAffectingValueChanged();
+ void MediaQueryAffectingValueChanged(MediaValueChange change);
- using SecurityContext::GetContentSecurityPolicy;
- using SecurityContext::GetMutableSecurityOrigin;
- using SecurityContext::GetSecurityOrigin;
using TreeScope::getElementById;
- // ExecutionContext overrides:
- bool IsDocument() const final { return true; }
- bool ShouldInstallV8Extensions() const final;
- ContentSecurityPolicy* GetContentSecurityPolicyForWorld() override;
+ // TODO(crbug.com/1029822) Former ExecutionContext overrides. Most of these
+ // should move to LocalDOMWindow.
+ ContentSecurityPolicy* GetContentSecurityPolicyForWorld();
+ LocalDOMWindow* ExecutingWindow() const;
+ String UserAgent() const;
+ // TODO(https://crbug.com/880986): Implement Document's HTTPS state in more
+ // spec-conformant way.
+ HttpsState GetHttpsState() const {
+ return CalculateHttpsState(GetSecurityOrigin());
+ }
+ bool CanExecuteScripts(ReasonForCallingCanExecuteScripts);
+ String OutgoingReferrer() const;
+ network::mojom::ReferrerPolicy GetReferrerPolicy() const;
+ CoreProbeSink* GetProbeSink();
+ BrowserInterfaceBrokerProxy& GetBrowserInterfaceBroker();
+ FrameOrWorkerScheduler* GetScheduler();
+ void CountPotentialFeaturePolicyViolation(
+ mojom::blink::FeaturePolicyFeature) const;
+ void ReportFeaturePolicyViolation(
+ mojom::blink::FeaturePolicyFeature,
+ mojom::blink::PolicyDisposition,
+ const String& message = g_empty_string,
+ // If source_file is set to empty string,
+ // current JS file would be used as source_file instead.
+ const String& source_file = g_empty_string) const;
+ void ReportDocumentPolicyViolation(
+ mojom::blink::DocumentPolicyFeature,
+ mojom::blink::PolicyDisposition disposition,
+ const String& message = g_empty_string,
+ // If source_file is set to empty string,
+ // current JS file would be used as source_file instead.
+ const String& source_file = g_empty_string) const;
+
+ // 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;
+
+ SecurityContext& GetSecurityContext() { return security_context_; }
+ const SecurityContext& GetSecurityContext() const {
+ return security_context_;
+ }
+
+ // TODO(crbug.com/1029822): Temporary cast helpers while ExecutionContext is
+ // migrating to LocalDOMWindow. Callsite that permanently need to convert a
+ // Document to an ExecutionContext should use either GetExecutionContext() as
+ // inherited from Node, or domWindow().
+ // Downcasts will cast to a LocalDOMWindow, then use
+ // LocalDOMWindow::document() if the Document is what is actually needed.
+ ExecutionContext* ToExecutionContext();
+ const ExecutionContext* ToExecutionContext() const;
+ static Document* From(ExecutionContext* context) {
+ return context ? &From(*context) : nullptr;
+ }
+ static Document& From(ExecutionContext& context);
+ static const Document* From(const ExecutionContext* context) {
+ return context ? &From(*context) : nullptr;
+ }
+ static const Document& From(const ExecutionContext& context);
+ static Document* DynamicFrom(ExecutionContext* context) {
+ return context && context->IsDocument() ? From(context) : nullptr;
+ }
+ static Document* DynamicFrom(ExecutionContext& context) {
+ return context.IsDocument() ? &From(context) : nullptr;
+ }
+ static const Document* DynamicFrom(const ExecutionContext* context) {
+ return context && context->IsDocument() ? From(context) : nullptr;
+ }
+ static const Document* DynamicFrom(const ExecutionContext& context) {
+ return context.IsDocument() ? &From(context) : nullptr;
+ }
+
+ // TODO(crbug.com/1029822): Temporary helpers to access ExecutionContext
+ // methods. These will need to be audited. Some might be useful permanent
+ // helpers.
+ const SecurityOrigin* GetSecurityOrigin() const;
+ SecurityOrigin* GetMutableSecurityOrigin();
+ ContentSecurityPolicy* GetContentSecurityPolicy() const;
+ mojom::blink::WebSandboxFlags GetSandboxFlags() const;
+ bool IsSandboxed(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 String& source_file = g_empty_string) const;
+ bool IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature,
+ PolicyValue threshold_value,
+ ReportOptions report_on_failure = ReportOptions::kDoNotReport,
+ const String& message = g_empty_string,
+ const String& source_file = 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;
bool CanContainRangeEndPoint() const override { return true; }
@@ -329,9 +449,6 @@ class CORE_EXPORT Document : public ContainerNode,
ViewportData& GetViewportData() const { return *viewport_data_; }
- String OutgoingReferrer() const override;
- network::mojom::ReferrerPolicy GetReferrerPolicy() const override;
-
void SetDoctype(DocumentType*);
DocumentType* doctype() const { return doc_type_.Get(); }
@@ -445,7 +562,7 @@ class CORE_EXPORT Document : public ContainerNode,
HTMLCollection* DocumentAllNamedItems(const AtomicString& name);
// "defaultView" attribute defined in HTML spec.
- LocalDOMWindow* defaultView() const;
+ DOMWindow* defaultView() const;
bool IsHTMLDocument() const { return document_classes_ & kHTMLDocumentClass; }
bool IsXHTMLDocument() const {
@@ -476,23 +593,25 @@ class CORE_EXPORT Document : public ContainerNode,
bool IsViewSource() const { return is_view_source_; }
void SetIsViewSource(bool);
- bool IsImmersiveArOverlay() const { return is_immersive_ar_overlay_; }
- void SetIsImmersiveArOverlay(bool);
+ // WebXR DOM Overlay support, cf https://immersive-web.github.io/dom-overlays/
+ // True if there's an ongoing "immersive-ar" WebXR session with a DOM Overlay
+ // element active. This is needed for applying the :xr-overlay pseudoclass
+ // and compositing/paint integration for this mode.
+ bool IsXrOverlay() const { return is_xr_overlay_; }
+ // Called from modules/xr's XRSystem when DOM Overlay mode starts and ends.
+ // This lazy-loads the UA stylesheet and updates the overlay element's
+ // pseudoclass.
+ void SetIsXrOverlay(bool enabled, Element* overlay_element);
bool SawElementsInKnownNamespaces() const {
return saw_elements_in_known_namespaces_;
}
- bool CanExecuteScripts(ReasonForCallingCanExecuteScripts) override;
bool IsScriptExecutionReady() const {
return HaveImportsLoaded() && HaveScriptBlockingStylesheetsLoaded();
}
bool IsForExternalHandler() const { return is_for_external_handler_; }
- void SetIsForExternalHandler() {
- DCHECK(!is_for_external_handler_);
- is_for_external_handler_ = true;
- }
// This is a DOM function.
StyleSheetList& StyleSheets();
@@ -553,14 +672,13 @@ class CORE_EXPORT Document : public ContainerNode,
void UpdateStyleAndLayoutTreeForNode(const Node*);
void UpdateStyleAndLayoutTreeForSubtree(const Node*);
- enum ForcedLayoutStatus { IsForcedLayout, IsNotForcedLayout };
- void UpdateStyleAndLayout(ForcedLayoutStatus = IsForcedLayout);
+ void UpdateStyleAndLayout(DocumentUpdateReason);
void LayoutUpdated();
enum RunPostLayoutTasks {
kRunPostLayoutTasksAsynchronously,
kRunPostLayoutTasksSynchronously,
};
- void UpdateStyleAndLayoutForNode(const Node*);
+ void UpdateStyleAndLayoutForNode(const Node*, DocumentUpdateReason);
scoped_refptr<const ComputedStyle> StyleForPage(int page_index);
// Ensures that location-based data will be valid for a given node.
@@ -571,7 +689,8 @@ class CORE_EXPORT Document : public ContainerNode,
//
// Due to this you should only call this if you definitely need valid location
// data, otherwise use one of the |UpdateStyleAndLayout...| methods above.
- void EnsurePaintLocationDataValidForNode(const Node*);
+ void EnsurePaintLocationDataValidForNode(const Node*,
+ DocumentUpdateReason reason);
// Returns true if page box (margin boxes and page borders) is visible.
bool IsPageBoxVisible(int page_index);
@@ -587,9 +706,7 @@ class CORE_EXPORT Document : public ContainerNode,
int& margin_bottom,
int& margin_left);
- ResourceFetcher* Fetcher() const override { return fetcher_.Get(); }
-
- using ExecutionContext::NotifyContextDestroyed;
+ ResourceFetcher* Fetcher() const { return fetcher_.Get(); }
void Initialize();
virtual void Shutdown();
@@ -711,7 +828,7 @@ class CORE_EXPORT Document : public ContainerNode,
// Return the document URL, or an empty URL if it's unavailable.
// This is not an implementation of web-exposed Document.prototype.URL.
- const KURL& Url() const final { return url_; }
+ const KURL& Url() const { return url_; }
void SetURL(const KURL&);
// Bind the url to document.url, if unavailable bind to about:blank.
@@ -722,7 +839,7 @@ class CORE_EXPORT Document : public ContainerNode,
// Document base URL.
// https://html.spec.whatwg.org/C/#document-base-url
- const KURL& BaseURL() const final;
+ const KURL& BaseURL() const;
void SetBaseURLOverride(const KURL&);
const KURL& BaseURLOverride() const { return base_url_override_; }
KURL ValidBaseElementURL() const;
@@ -736,24 +853,17 @@ class CORE_EXPORT Document : public ContainerNode,
// Creates URL based on passed relative url and this documents base URL.
// Depending on base URL value it is possible that parent document
// base URL will be used instead. Uses CompleteURLWithOverride internally.
- KURL CompleteURL(const String&) const final;
+ KURL CompleteURL(const String&) const;
// Creates URL based on passed relative url and passed base URL override.
KURL CompleteURLWithOverride(const String&,
const KURL& base_url_override) const;
+ const KURL& WebBundleClaimedUrl() const { return web_bundle_claimed_url_; }
+
// Determines whether a new document should take on the same origin as that of
// the document which created it.
static bool ShouldInheritSecurityOriginFromOwner(const KURL&);
- String UserAgent() const final;
- void DisableEval(const String& error_message) final;
-
- // TODO(https://crbug.com/880986): Implement Document's HTTPS state in more
- // spec-conformant way.
- HttpsState GetHttpsState() const final {
- return CalculateHttpsState(GetSecurityOrigin());
- }
-
CSSStyleSheet& ElementSheet();
virtual DocumentParser* CreateParser();
@@ -800,6 +910,7 @@ class CORE_EXPORT Document : public ContainerNode,
// https://html.spec.whatwg.org/C/#documentreadystate
enum DocumentReadyState { kLoading, kInteractive, kComplete };
+ DocumentReadyState GetReadyState() const { return ready_state_; }
void SetReadyState(DocumentReadyState);
bool IsLoadCompleted() const;
@@ -824,8 +935,8 @@ class CORE_EXPORT Document : public ContainerNode,
had_keyboard_event_ = had_keyboard_event;
}
bool HadKeyboardEvent() const { return had_keyboard_event_; }
- void SetLastFocusType(WebFocusType last_focus_type);
- WebFocusType LastFocusType() const { return last_focus_type_; }
+ void SetLastFocusType(mojom::blink::FocusType last_focus_type);
+ mojom::blink::FocusType LastFocusType() const { return last_focus_type_; }
bool SetFocusedElement(Element*, const FocusParams&);
void ClearFocusedElement();
Element* FocusedElement() const { return focused_element_.Get(); }
@@ -845,7 +956,8 @@ class CORE_EXPORT Document : public ContainerNode,
void FlushAutofocusCandidates();
void FinalizeAutofocus();
void SetSequentialFocusNavigationStartingPoint(Node*);
- Element* SequentialFocusNavigationStartingPoint(WebFocusType) const;
+ Element* SequentialFocusNavigationStartingPoint(
+ mojom::blink::FocusType) const;
void SetActiveElement(Element*);
Element* GetActiveElement() const { return active_element_.Get(); }
@@ -933,13 +1045,14 @@ class CORE_EXPORT Document : public ContainerNode,
kAnimationEndListener = 1 << 6,
kAnimationStartListener = 1 << 7,
kAnimationIterationListener = 1 << 8,
- kTransitionRunListener = 1 << 9,
- kTransitionStartListener = 1 << 10,
- kTransitionEndListener = 1 << 11,
- kTransitionCancelListener = 1 << 12,
- kScrollListener = 1 << 13,
- kLoadListenerAtCapturePhaseOrAtStyleElement = 1 << 14
- // 1 bit remaining
+ kAnimationCancelListener = 1 << 9,
+ kTransitionRunListener = 1 << 10,
+ kTransitionStartListener = 1 << 11,
+ kTransitionEndListener = 1 << 12,
+ kTransitionCancelListener = 1 << 13,
+ kScrollListener = 1 << 14,
+ kLoadListenerAtCapturePhaseOrAtStyleElement = 1 << 15,
+ // 0 bits remaining
};
bool HasListenerType(ListenerType listener_type) const {
@@ -958,6 +1071,14 @@ class CORE_EXPORT Document : public ContainerNode,
IntersectionObserverController* GetIntersectionObserverController();
IntersectionObserverController& EnsureIntersectionObserverController();
+ // This is used to track IntersectionObservers for which this document is the
+ // explicit root. The IntersectionObserverController tracks *all* observers
+ // associated with this document; usually that's what you want.
+ ElementIntersectionObserverData*
+ DocumentExplicitRootIntersectionObserverData() const;
+ ElementIntersectionObserverData&
+ EnsureDocumentExplicitRootIntersectionObserverData();
+
ResizeObserverController* GetResizeObserverController() const {
return resize_observer_controller_;
}
@@ -969,7 +1090,7 @@ class CORE_EXPORT Document : public ContainerNode,
void WillChangeFrameOwnerProperties(int margin_width,
int margin_height,
- ScrollbarMode,
+ mojom::blink::ScrollbarMode,
bool is_display_none);
String title() const { return title_; }
@@ -1015,12 +1136,18 @@ class CORE_EXPORT Document : public ContainerNode,
scoped_refptr<const SecurityOrigin> TopFrameOrigin() const;
- const KURL SiteForCookies() const;
+ net::SiteForCookies SiteForCookies() const;
+
+ // Permissions service helper methods to facilitate requesting and checking
+ // storage access permissions.
+ mojom::blink::PermissionService* GetPermissionService(
+ ExecutionContext* execution_context);
+ void PermissionServiceConnectionError();
// Storage Access API methods to check for or request access to storage that
// may otherwise be blocked.
ScriptPromise hasStorageAccess(ScriptState* script_state) const;
- ScriptPromise requestStorageAccess(ScriptState* script_state) const;
+ ScriptPromise requestStorageAccess(ScriptState* script_state);
// The following implements the rule from HTML 4 for what valid names are.
// To get this right for all the XML cases, we probably have to improve this
@@ -1130,10 +1257,6 @@ class CORE_EXPORT Document : public ContainerNode,
bool IsDNSPrefetchEnabled() const { return is_dns_prefetch_enabled_; }
void ParseDNSPrefetchControlHeader(const String&);
- void TasksWerePaused() final;
- void TasksWereUnpaused() final;
- bool TasksNeedPause() final;
-
void FinishedParsing();
void SetEncodingData(const DocumentEncodingData& new_data);
@@ -1192,9 +1315,6 @@ class CORE_EXPORT Document : public ContainerNode,
void SetContainsPlugins() { contains_plugins_ = true; }
bool ContainsPlugins() const { return contains_plugins_; }
- bool IsContextThread() const final;
- bool IsJSExecutionForbidden() const final { return false; }
-
void EnqueueResizeEvent();
void EnqueueScrollEventForNode(Node*);
void EnqueueScrollEndEventForNode(Node*);
@@ -1248,8 +1368,7 @@ class CORE_EXPORT Document : public ContainerNode,
const IdleRequestOptions*);
void CancelIdleCallback(int id);
- EventTarget* ErrorEventTarget() final;
- void ExceptionThrown(ErrorEvent*) final;
+ ScriptedAnimationController& GetScriptedAnimationController();
void InitDNSPrefetch();
@@ -1301,12 +1420,18 @@ class CORE_EXPORT Document : public ContainerNode,
AnimationClock& GetAnimationClock();
const AnimationClock& GetAnimationClock() const;
+ DocumentAnimations& GetDocumentAnimations() const {
+ return *document_animations_;
+ }
DocumentTimeline& Timeline() const { return *timeline_; }
PendingAnimations& GetPendingAnimations() { return *pending_animations_; }
WorkletAnimationController& GetWorkletAnimationController() {
return *worklet_animation_controller_;
}
+ void AttachCompositorTimeline(CompositorAnimationTimeline*) const;
+ void DetachCompositorTimeline(CompositorAnimationTimeline*) const;
+
void AddToTopLayer(Element*, const Element* before = nullptr);
void RemoveFromTopLayer(Element*);
const HeapVector<Member<Element>>& TopLayerElements() const {
@@ -1324,9 +1449,10 @@ class CORE_EXPORT Document : public ContainerNode,
// for controls outside of forms as well.
void DidAssociateFormControl(Element*);
- void AddConsoleMessageImpl(ConsoleMessage*, bool discard_duplicates) final;
+ void AddConsoleMessage(ConsoleMessage* message,
+ bool discard_duplicates = false);
+ void AddInspectorIssue(InspectorIssue*);
- LocalDOMWindow* ExecutingWindow() const final;
LocalFrame* ExecutingFrame();
DocumentLifecycle& Lifecycle() { return lifecycle_; }
@@ -1349,6 +1475,7 @@ class CORE_EXPORT Document : public ContainerNode,
void ClearResizedForViewportUnits();
void UpdateActiveStyle();
+ void InvalidateStyleAndLayoutForFontUpdates();
void Trace(Visitor*) override;
@@ -1356,18 +1483,8 @@ class CORE_EXPORT Document : public ContainerNode,
void PlatformColorsChanged();
- HostsUsingFeatures::Value& HostsUsingFeaturesValue() {
- return hosts_using_features_value_;
- }
-
NthIndexCache* GetNthIndexCache() const { return nth_index_cache_; }
- bool IsSecureContext(String& error_message) const override;
- bool IsSecureContext() const override;
- void SetSecureContextStateForTesting(SecureContextState state) {
- secure_context_state_ = state;
- }
-
CanvasFontCache* GetCanvasFontCache();
// Used by unit tests so that all parsing will be main thread for
@@ -1383,28 +1500,11 @@ class CORE_EXPORT Document : public ContainerNode,
int NodeCount() const { return node_count_; }
SnapCoordinator& GetSnapCoordinator();
+ void PerformScrollSnappingTasks();
void DidEnforceInsecureRequestPolicy();
void DidEnforceInsecureNavigationsSet();
- // Temporary flag for some UseCounter items. crbug.com/859391.
- enum class InDOMNodeRemovedHandlerState {
- kNone,
- kDOMNodeRemoved,
- kDOMNodeRemovedFromDocument
- };
- void SetInDOMNodeRemovedHandlerState(InDOMNodeRemovedHandlerState state) {
- in_dom_node_removed_handler_state_ = state;
- }
- InDOMNodeRemovedHandlerState GetInDOMNodeRemovedHandlerState() const {
- return in_dom_node_removed_handler_state_;
- }
- bool InDOMNodeRemovedHandler() const {
- return in_dom_node_removed_handler_state_ !=
- InDOMNodeRemovedHandlerState::kNone;
- }
- void CountDetachingNodeAccessInDOMNodeRemovedHandler();
-
bool MayContainV0Shadow() const { return may_contain_v0_shadow_; }
ShadowCascadeOrder GetShadowCascadeOrder() const {
@@ -1432,21 +1532,11 @@ class CORE_EXPORT Document : public ContainerNode,
// text field in a non-secure context.
void MaybeQueueSendDidEditFieldInInsecureContext();
- CoreProbeSink* GetProbeSink() final;
- service_manager::InterfaceProvider* GetInterfaceProvider() final;
-
- BrowserInterfaceBrokerProxy& GetBrowserInterfaceBroker() final;
-
// May return nullptr when PerformanceManager instrumentation is disabled.
DocumentResourceCoordinator* GetResourceCoordinator();
- // Apply pending feature policy headers.
- void ApplyPendingFeaturePolicyHeaders();
-
- // Set the report-only feature policy on this document in response to an HTTP
- // Feature-Policy-Report-Only header.
- void ApplyReportOnlyFeaturePolicyFromHeader(
- const String& feature_policy_report_only_header);
+ // Apply pending feature policy headers and document policy headers.
+ void ApplyPendingFramePolicyHeaders();
const AtomicString& bgColor() const;
void setBgColor(const AtomicString&);
@@ -1471,10 +1561,7 @@ class CORE_EXPORT Document : public ContainerNode,
// attempts (both successful and not successful) by the page.
FontMatchingMetrics* GetFontMatchingMetrics();
- // May return nullptr.
- FrameOrWorkerScheduler* GetScheduler() override;
-
- scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(TaskType) override;
+ scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(TaskType);
void RecordUkmOutliveTimeAfterShutdown(int outlive_time_count);
@@ -1529,35 +1616,54 @@ class CORE_EXPORT Document : public ContainerNode,
LazyLoadImageObserver& EnsureLazyLoadImageObserver();
WindowAgent& GetWindowAgent();
- WindowAgentFactory* GetWindowAgentFactory() { return window_agent_factory_; }
-
- void CountPotentialFeaturePolicyViolation(
- mojom::FeaturePolicyFeature) const override;
- void ReportFeaturePolicyViolation(
- mojom::FeaturePolicyFeature,
- mojom::FeaturePolicyDisposition,
- const String& message = g_empty_string,
- // If source_file is set to empty string,
- // current JS file would be used as source_file instead.
- const String& source_file = g_empty_string) const override;
+ WindowAgentFactory* GetWindowAgentFactory() const {
+ return window_agent_factory_;
+ }
void IncrementNumberOfCanvases();
- void ProcessJavaScriptUrl(const KURL&, ContentSecurityPolicyDisposition);
+ void ProcessJavaScriptUrl(const KURL&, network::mojom::CSPDisposition);
// Functions to keep count of display locks in this document.
- void AddActivationBlockingDisplayLock();
- void RemoveActivationBlockingDisplayLock();
- int ActivationBlockingDisplayLockCount() const;
+ void IncrementDisplayLockBlockingAllActivation();
+ void DecrementDisplayLockBlockingAllActivation();
+ int DisplayLockBlockingAllActivationCount() const;
void AddLockedDisplayLock();
void RemoveLockedDisplayLock();
int LockedDisplayLockCount() const;
+ void AddDisplayLockContext(DisplayLockContext*);
+ void RemoveDisplayLockContext(DisplayLockContext*);
+ int DisplayLockCount() const;
+ void NotifySelectionRemovedFromDisplayLocks();
+
// Manage the element's observation for display lock activation.
void RegisterDisplayLockActivationObservation(Element*);
void UnregisterDisplayLockActivationObservation(Element*);
+ class ScopedForceActivatableDisplayLocks {
+ STACK_ALLOCATED();
+
+ public:
+ ScopedForceActivatableDisplayLocks(ScopedForceActivatableDisplayLocks&&);
+ ~ScopedForceActivatableDisplayLocks();
+
+ ScopedForceActivatableDisplayLocks& operator=(
+ ScopedForceActivatableDisplayLocks&&);
+
+ private:
+ friend Document;
+ ScopedForceActivatableDisplayLocks(Document*);
+
+ Document* document_;
+ };
+
+ ScopedForceActivatableDisplayLocks GetScopedForceActivatableLocks();
+ bool ActivatableDisplayLocksForced() const {
+ return activatable_display_locks_forced_ > 0;
+ }
+
// Deferred compositor commits are disallowed by default, and are only allowed
// for same-origin navigations to an html document fetched with http.
bool DeferredCompositorCommitIsAllowed() {
@@ -1583,11 +1689,11 @@ class CORE_EXPORT Document : public ContainerNode,
// inside a cross-process frame (MimeHandlerView).
void SetShowBeforeUnloadDialog(bool show_dialog);
- TrustedTypePolicyFactory* GetTrustedTypes() const override;
- bool RequireTrustedTypes() const override;
-
void ColorSchemeChanged();
+ // 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.
@@ -1614,17 +1720,20 @@ class CORE_EXPORT Document : public ContainerNode,
// NOTE: only for use in testing.
bool IsAnimatedPropertyCounted(CSSPropertyID property) const;
void ClearUseCounterForTesting(mojom::WebFeature);
- void SetSecurityOrigin(scoped_refptr<SecurityOrigin>) final;
-
- void RecordCallInDetachedWindow(v8::Isolate::UseCounterFeature reason);
// Bind Content Security Policy to this document. This will cause the
// CSP to resolve the 'self' attribute and all policies will then be
// applied to this document.
void BindContentSecurityPolicy();
+ void UpdateForcedColors();
bool InForcedColorsMode() const;
+ // Returns true if the subframe document is cross-site to the main frame. If
+ // we can't tell whether the document was ever cross-site or not (e.g. it is
+ // not the active Document in a browsing context), return false.
+ bool IsCrossSiteSubframe() const;
+
// Capture the toggle event during parsing either by HTML parser or XML
// parser.
void SetToggleDuringParsing(bool toggle_during_parsing) {
@@ -1657,6 +1766,27 @@ class CORE_EXPORT Document : public ContainerNode,
}
#endif
+ void ApplyScrollRestorationLogic();
+
+ void MarkHasFindInPageRequest();
+ void MarkHasFindInPageSubtreeVisibilityActiveMatch();
+
+ void CancelPendingJavaScriptUrls();
+
+ HeapObserverList<SynchronousMutationObserver>&
+ SynchronousMutationObserverList() {
+ return synchronous_mutation_observer_list_;
+ }
+
+ void NotifyUpdateCharacterData(CharacterData* character_data,
+ unsigned offset,
+ unsigned old_length,
+ unsigned new_length);
+ void NotifyChangeChildren(const ContainerNode& container);
+
+ FontPreloadManager& GetFontPreloadManager() { return font_preload_manager_; }
+ void FontPreloadingFinishedOrTimedOut();
+
protected:
void ClearXMLVersion() { xml_version_ = String(); }
@@ -1674,17 +1804,16 @@ class CORE_EXPORT Document : public ContainerNode,
friend class NthIndexCache;
FRIEND_TEST_ALL_PREFIXES(FrameFetchContextSubresourceFilterTest,
DuringOnFreeze);
+ FRIEND_TEST_ALL_PREFIXES(DocumentTest, FindInPageUkm);
class NetworkStateObserver;
- class SecurityContextInit;
Document(const DocumentInit& initization,
- SecurityContextInit init_helper,
+ const SecurityContextInit& init_helper,
DocumentClassFlags document_classes);
- // Post initialization of the object handling of the feature policy.
- void FeaturePolicyInitialized(
- const DocumentInit& document_initializer,
- const SecurityContextInit& security_initializer);
+ // Post initialization of the object handling of both feature policy and
+ // document policy.
+ void PoliciesInitialized(const DocumentInit& document_initializer);
friend class AXContext;
void AddAXContext(AXContext*);
@@ -1697,13 +1826,8 @@ class CORE_EXPORT Document : public ContainerNode,
bool IsElementNode() const =
delete; // This will catch anyone doing an unnecessary check.
- ScriptedAnimationController& EnsureScriptedAnimationController();
ScriptedIdleTaskController& EnsureScriptedIdleTaskController();
- void InitSecurityContext(const DocumentInit&,
- const SecurityContextInit& security_initializer);
- void InitSecureContextState();
- SecurityContext& GetSecurityContext() final { return *this; }
- const SecurityContext& GetSecurityContext() const final { return *this; }
+ void InitSecurityContext(const DocumentInit&);
bool HasPendingVisualUpdate() const {
return lifecycle_.GetState() == DocumentLifecycle::kVisualUpdatePending;
@@ -1754,7 +1878,6 @@ class CORE_EXPORT Document : public ContainerNode,
void ExecuteScriptsWaitingForResources();
void ExecuteJavaScriptUrls();
- void CancelPendingJavaScriptUrls();
void LoadEventDelayTimerFired(TimerBase*);
void PluginLoadingTimerFired(TimerBase*);
@@ -1815,12 +1938,6 @@ class CORE_EXPORT Document : public ContainerNode,
void ProcessDisplayLockActivationObservation(
const HeapVector<Member<IntersectionObserverEntry>>&);
- void SetNavigationSourceId(int64_t source_id);
-
- // TODO(bartekn): Remove after investigation is completed.
- void EmitDetachedWindowsUkmEvent(
- const HashSet<v8::Isolate::UseCounterFeature>& reasons);
-
DocumentLifecycle lifecycle_;
bool evaluate_media_queries_on_style_recalc_;
@@ -1835,6 +1952,14 @@ class CORE_EXPORT Document : public ContainerNode,
Member<LocalDOMWindow> dom_window_;
Member<HTMLImportsController> imports_controller_;
+ SecurityContext security_context_;
+
+ // Document::CountUse() attributes the feature counts to the DocumentLoader
+ // which is returned by Loader(). During construction Loader() returns null,
+ // so we use this UseCounter instead.
+ // 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_;
@@ -1860,6 +1985,8 @@ class CORE_EXPORT Document : public ContainerNode,
KURL cookie_url_; // The URL to use for cookie access.
std::unique_ptr<OriginAccessEntry> access_entry_from_url_;
+ KURL web_bundle_claimed_url_;
+
AtomicString base_target_;
// Mime-type of the document in case it was cloned or created by XHR.
@@ -1882,16 +2009,16 @@ class CORE_EXPORT Document : public ContainerNode,
struct PendingJavascriptUrl {
public:
PendingJavascriptUrl(const KURL& input_url,
- ContentSecurityPolicyDisposition input_disposition)
+ network::mojom::CSPDisposition input_disposition)
: url(input_url), disposition(input_disposition) {}
KURL url;
- ContentSecurityPolicyDisposition disposition;
+ network::mojom::CSPDisposition disposition;
};
Vector<PendingJavascriptUrl> pending_javascript_urls_;
// https://html.spec.whatwg.org/C/#autofocus-processed-flag
bool autofocus_processed_flag_ = false;
- WebFocusType last_focus_type_;
+ mojom::blink::FocusType last_focus_type_;
bool had_keyboard_event_;
TaskRunnerTimer<Document> clear_focused_element_timer_;
// https://html.spec.whatwg.org/C/#autofocus-candidates
@@ -1905,6 +2032,9 @@ class CORE_EXPORT Document : public ContainerNode,
UserActionElementSet user_action_elements_;
Member<RootScrollerController> root_scroller_controller_;
+ double overscroll_accumulated_delta_x_ = 0;
+ double overscroll_accumulated_delta_y_ = 0;
+
uint64_t dom_tree_version_;
static uint64_t global_tree_version_;
@@ -1918,6 +2048,9 @@ class CORE_EXPORT Document : public ContainerNode,
MutationObserverOptions mutation_observer_types_;
+ Member<ElementIntersectionObserverData>
+ document_explicit_root_intersection_observer_data_;
+
Member<StyleEngine> style_engine_;
Member<StyleSheetList> style_sheet_list_;
@@ -2009,7 +2142,7 @@ class CORE_EXPORT Document : public ContainerNode,
DocumentClassFlags document_classes_;
bool is_view_source_;
- bool is_immersive_ar_overlay_;
+ bool is_xr_overlay_;
bool saw_elements_in_known_namespaces_;
bool is_srcdoc_document_;
bool is_mobile_document_;
@@ -2049,6 +2182,7 @@ class CORE_EXPORT Document : public ContainerNode,
HashMap<AtomicString, std::unique_ptr<Locale>>;
LocaleIdentifierToLocaleMap locale_cache_;
+ Member<DocumentAnimations> document_animations_;
Member<DocumentTimeline> timeline_;
Member<PendingAnimations> pending_animations_;
Member<WorkletAnimationController> worklet_animation_controller_;
@@ -2064,8 +2198,6 @@ class CORE_EXPORT Document : public ContainerNode,
ParserSynchronizationPolicy parser_sync_policy_;
- HostsUsingFeatures::Value hosts_using_features_value_;
-
Member<CanvasFontCache> canvas_font_cache_;
Member<IntersectionObserverController> intersection_observer_controller_;
@@ -2073,9 +2205,6 @@ class CORE_EXPORT Document : public ContainerNode,
int node_count_;
- // Temporary flag for some UseCounter items. crbug.com/859391.
- InDOMNodeRemovedHandlerState in_dom_node_removed_handler_state_ =
- InDOMNodeRemovedHandlerState::kNone;
bool may_contain_v0_shadow_ = false;
Member<SnapCoordinator> snap_coordinator_;
@@ -2086,8 +2215,6 @@ class CORE_EXPORT Document : public ContainerNode,
TaskHandle sensitive_input_edited_task_;
- SecureContextState secure_context_state_;
-
Member<NetworkStateObserver> network_state_observer_;
std::unique_ptr<DocumentOutliveTimeReporter> document_outlive_time_reporter_;
@@ -2098,10 +2225,6 @@ class CORE_EXPORT Document : public ContainerNode,
int64_t ukm_source_id_;
bool needs_to_record_ukm_outlive_time_;
- std::unique_ptr<mojo::AssociatedRemote<mojom::blink::UkmSourceIdFrameHost>>
- ukm_binding_;
- uint64_t navigation_source_id_ = ukm::kInvalidSourceId;
-
// Tracks and reports UKM metrics of the number of attempted font family match
// attempts (both successful and not successful) by the page.
std::unique_ptr<FontMatchingMetrics> font_matching_metrics_;
@@ -2125,10 +2248,14 @@ class CORE_EXPORT Document : public ContainerNode,
// The number of canvas elements on the document
int num_canvases_ = 0;
- // Number of activation blocking display locks currently in this document.
- int activation_blocking_display_lock_count_ = 0;
+ // Number of display locks in this document that block all activation.
+ int display_lock_blocking_all_activation_count_ = 0;
// Number of locked display locks in the document.
int locked_display_lock_count_ = 0;
+ // All of this document's display lock contexts.
+ HeapHashSet<WeakMember<DisplayLockContext>> display_lock_contexts_;
+ // If non-zero, then the activatable locks have been globally forced.
+ int activatable_display_locks_forced_ = 0;
bool deferred_compositor_commit_is_allowed_ = false;
@@ -2136,7 +2263,7 @@ class CORE_EXPORT Document : public ContainerNode,
// types that are handled externally. The document in this case is the
// counterpart to a PluginDocument except that it contains a FrameView as
// opposed to a PluginView.
- bool is_for_external_handler_ = false;
+ bool is_for_external_handler_;
#if DCHECK_IS_ON()
// Allow traversal of Shadow DOM V0 traversal with dirty distribution.
@@ -2152,9 +2279,21 @@ class CORE_EXPORT Document : public ContainerNode,
// We don't use std::bitset to avoid to include feature_policy.mojom-blink.h.
mutable Vector<bool> potentially_violated_features_;
- // Pending parsed headers to send to browser after DidCommitNavigation
+ // Pending feature policy headers to send to browser after DidCommitNavigation
// IPC.
- ParsedFeaturePolicy pending_parsed_headers_;
+ ParsedFeaturePolicy pending_fp_headers_;
+
+ // Pending document policy headers to send to browser after
+ // DidCommitNavigation IPC. Note: pending_dp_headers is the document policy
+ // state used to initialize |document_policy_| in SecurityContext. Verifying
+ // its integrity against required_document_policy has already been done in
+ // DocumentLoader.
+ DocumentPolicy::FeatureState pending_dp_headers_;
+
+ // Tracks which feature policies have already been parsed, so as not to count
+ // them multiple times.
+ // The size of this vector is 0 until FeaturePolicyFeatureObserved is called.
+ Vector<bool> parsed_feature_policies_;
AtomicString override_last_modified_;
@@ -2177,16 +2316,7 @@ class CORE_EXPORT Document : public ContainerNode,
std::unique_ptr<DocumentResourceCoordinator> resource_coordinator_;
// Used for document.cookie. May be null.
- std::unique_ptr<CookieJar> cookie_jar_;
-
- // A dummy scheduler to return when the document is detached.
- // All operations on it result in no-op, but due to this it's safe to
- // use the returned value of GetScheduler() without additional checks.
- // A task posted to a task runner obtained from one of its task runners
- // will be forwarded to the default task runner.
- // TODO(altimin): We should be able to remove it after we complete
- // frame:document lifetime refactoring.
- std::unique_ptr<FrameOrWorkerScheduler> detached_scheduler_;
+ Member<CookieJar> cookie_jar_;
bool toggle_during_parsing_ = false;
@@ -2199,10 +2329,24 @@ class CORE_EXPORT Document : public ContainerNode,
HeapHashMap<WeakMember<Element>, Member<ExplicitlySetAttrElementsMap>>
element_explicitly_set_attr_elements_map_;
+ HeapObserverList<SynchronousMutationObserver>
+ synchronous_mutation_observer_list_;
+
Member<IntersectionObserver> display_lock_activation_observer_;
- HashSet<v8::Isolate::UseCounterFeature> calls_in_detached_window_orphaned_;
- HashSet<v8::Isolate::UseCounterFeature> calls_in_detached_window_emitted_;
+ bool in_forced_colors_mode_;
+
+ bool applying_scroll_restoration_logic_ = false;
+
+ // Records find-in-page metrics, which are sent to UKM on shutdown.
+ bool had_find_in_page_request_ = false;
+ bool had_find_in_page_render_subtree_active_match_ = false;
+
+ // Mojo remote used to determine if the document has permission to access
+ // storage or not.
+ HeapMojoRemote<mojom::blink::PermissionService> permission_service_;
+
+ FontPreloadManager font_preload_manager_;
};
extern template class CORE_EXTERN_TEMPLATE_EXPORT Supplement<Document>;
@@ -2234,9 +2378,6 @@ Node* EventTargetNodeForDocument(Document*);
template <>
struct DowncastTraits<Document> {
- static bool AllowFrom(const ExecutionContext& context) {
- return context.IsDocument();
- }
static bool AllowFrom(const Node& node) { return node.IsDocumentNode(); }
};
diff --git a/chromium/third_party/blink/renderer/core/dom/document.idl b/chromium/third_party/blink/renderer/core/dom/document.idl
index ec4b33c91e2..a8025f5cf65 100644
--- a/chromium/third_party/blink/renderer/core/dom/document.idl
+++ b/chromium/third_party/blink/renderer/core/dom/document.idl
@@ -34,10 +34,9 @@ typedef (HTMLScriptElement or SVGScriptElement) HTMLOrSVGScriptElement;
// https://html.spec.whatwg.org/C/#documents
[
- Exposed=Window,
- Constructor(),
- ConstructorCallWith=Document
+ Exposed=Window
] interface Document : Node {
+ [CallWith=Document] constructor();
[SameObject] readonly attribute DOMImplementation implementation;
[ImplementedAs=urlForBinding] readonly attribute USVString URL;
// FIXME: documentURI should not be nullable.
@@ -170,7 +169,7 @@ typedef (HTMLScriptElement or SVGScriptElement) HTMLOrSVGScriptElement;
// Custom Elements
// https://w3c.github.io/webcomponents/spec/custom/#extensions-to-document-interface-to-register
// FIXME: The registerElement return type should be Function.
- [RuntimeEnabled=CustomElementsV0, CallWith=ScriptState, CustomElementCallbacks, RaisesException, DeprecateAs=DocumentRegisterElement] any registerElement(DOMString type, optional ElementRegistrationOptions options);
+ [RuntimeEnabled=CustomElementsV0, CallWith=ScriptState, CustomElementCallbacks, RaisesException, DeprecateAs=DocumentRegisterElement] any registerElement(DOMString type, optional ElementRegistrationOptions options = {});
// https://w3c.github.io/webcomponents/spec/custom/#extensions-to-document-interface-to-instantiate
[CustomElementCallbacks, PerWorldBindings, RaisesException, ImplementedAs=CreateElementForBinding] Element createElement(DOMString localName, (DOMString or ElementCreationOptions) options);
[CustomElementCallbacks, RaisesException] Element createElementNS(DOMString? namespaceURI, DOMString qualifiedName, (DOMString or ElementCreationOptions) options);
@@ -186,7 +185,7 @@ typedef (HTMLScriptElement or SVGScriptElement) HTMLOrSVGScriptElement;
[RuntimeEnabled=AddressSpace, ImplementedAs=addressSpaceForBindings] readonly attribute AddressSpace addressSpace;
// Non-standard APIs
- [MeasureAs=DocumentCaretRangeFromPoint] Range caretRangeFromPoint([DefaultValue=Undefined] optional long x, [DefaultValue=Undefined] optional long y);
+ [MeasureAs=DocumentCaretRangeFromPoint] Range caretRangeFromPoint(optional long x = 0, optional long y = 0);
// Storage Access API
[CallWith=ScriptState, NewObject, RuntimeEnabled=StorageAccessAPI] Promise<boolean> hasStorageAccess();
diff --git a/chromium/third_party/blink/renderer/core/dom/document_fragment.idl b/chromium/third_party/blink/renderer/core/dom/document_fragment.idl
index e69c55f80cd..ddb78da3185 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_fragment.idl
+++ b/chromium/third_party/blink/renderer/core/dom/document_fragment.idl
@@ -20,10 +20,9 @@
// https://dom.spec.whatwg.org/#interface-documentfragment
[
- Constructor,
- ConstructorCallWith=Document,
Exposed=Window
] interface DocumentFragment : Node {
+ [CallWith=Document] constructor();
};
DocumentFragment includes ParentNode;
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 a06ea5d6947..c9c761dd34e 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_init.cc
+++ b/chromium/third_party/blink/renderer/core/dom/document_init.cc
@@ -29,13 +29,24 @@
#include "third_party/blink/renderer/core/dom/document_init.h"
+#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/frame/csp/content_security_policy.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_frame_owner_element.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/loader/document_loader.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/page/plugin_data.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/network/network_utils.h"
+#include "third_party/blink/renderer/platform/web_test_support.h"
namespace blink {
@@ -94,8 +105,8 @@ DocumentLoader* DocumentInit::MasterDocumentLoader() const {
return nullptr;
}
-WebSandboxFlags DocumentInit::GetSandboxFlags() const {
- WebSandboxFlags flags = sandbox_flags_;
+mojom::blink::WebSandboxFlags DocumentInit::GetSandboxFlags() const {
+ mojom::blink::WebSandboxFlags flags = sandbox_flags_;
if (DocumentLoader* loader = MasterDocumentLoader())
flags |= loader->GetFrame()->Loader().EffectiveSandboxFlags();
// If the load was blocked by CSP, force the Document's origin to be unique,
@@ -103,15 +114,16 @@ WebSandboxFlags DocumentInit::GetSandboxFlags() const {
// document's load per CSP spec:
// https://www.w3.org/TR/CSP3/#directive-frame-ancestors.
if (blocked_by_csp_)
- flags |= WebSandboxFlags::kOrigin;
+ flags |= mojom::blink::WebSandboxFlags::kOrigin;
return flags;
}
-WebInsecureRequestPolicy DocumentInit::GetInsecureRequestPolicy() const {
+mojom::blink::InsecureRequestPolicy DocumentInit::GetInsecureRequestPolicy()
+ const {
DCHECK(MasterDocumentLoader());
Frame* parent_frame = MasterDocumentLoader()->GetFrame()->Tree().Parent();
if (!parent_frame)
- return kLeaveInsecureRequestsAlone;
+ return mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone;
return parent_frame->GetSecurityContext()->GetInsecureRequestPolicy();
}
@@ -146,6 +158,87 @@ LocalFrame* DocumentInit::GetFrame() const {
return document_loader_ ? document_loader_->GetFrame() : nullptr;
}
+UseCounter* DocumentInit::GetUseCounter() const {
+ return document_loader_;
+}
+
+DocumentInit& DocumentInit::WithTypeFrom(const String& type) {
+ mime_type_ = type;
+
+ if (GetFrame() && GetFrame()->InViewSourceMode()) {
+ type_ = Type::kViewSource;
+ return *this;
+ }
+
+ // Plugins cannot take HTML and XHTML from us, and we don't even need to
+ // initialize the plugin database for those.
+ if (type == "text/html") {
+ type_ = Type::kHTML;
+ return *this;
+ }
+ if (type == "application/xhtml+xml") {
+ type_ = Type::kXHTML;
+ return *this;
+ }
+ // multipart/x-mixed-replace is only supported for images.
+ if (MIMETypeRegistry::IsSupportedImageResourceMIMEType(type) ||
+ type == "multipart/x-mixed-replace") {
+ type_ = Type::kImage;
+ return *this;
+ }
+ if (HTMLMediaElement::GetSupportsType(ContentType(type))) {
+ type_ = Type::kMedia;
+ return *this;
+ }
+
+ PluginData* plugin_data = nullptr;
+ if (GetFrame() && GetFrame()->GetPage() &&
+ GetFrame()->Loader().AllowPlugins(kNotAboutToInstantiatePlugin)) {
+ // If the document is being created for the main frame,
+ // frame()->tree().top()->securityContext() returns nullptr.
+ // For that reason, the origin must be retrieved directly from url().
+ if (GetFrame()->IsMainFrame()) {
+ scoped_refptr<const SecurityOrigin> origin =
+ SecurityOrigin::Create(Url());
+ plugin_data = GetFrame()->GetPage()->GetPluginData(origin.get());
+ } else {
+ auto* top_security_origin =
+ GetFrame()->Tree().Top().GetSecurityContext()->GetSecurityOrigin();
+ plugin_data = GetFrame()->GetPage()->GetPluginData(top_security_origin);
+ }
+ }
+
+ // Everything else except text/plain can be overridden by plugins.
+ // Disallowing plugins to use text/plain prevents plugins from hijacking a
+ // fundamental type that the browser is expected to handle, and also serves as
+ // an optimization to prevent loading the plugin database in the common case.
+ if (type != "text/plain" && plugin_data &&
+ plugin_data->SupportsMimeType(type)) {
+ // Plugins handled by MimeHandlerView do not create a PluginDocument. They
+ // are rendered inside cross-process frames and the notion of a PluginView
+ // (which is associated with PluginDocument) is irrelevant here.
+ if (plugin_data->IsExternalPluginMimeType(type)) {
+ type_ = Type::kHTML;
+ is_for_external_handler_ = true;
+ } else {
+ type_ = Type::kPlugin;
+ plugin_background_color_ =
+ plugin_data->PluginBackgroundColorForMimeType(type);
+ }
+ return *this;
+ }
+
+ if (DOMImplementation::IsTextMIMEType(type))
+ type_ = Type::kText;
+ else if (type == "image/svg+xml")
+ type_ = Type::kSVG;
+ else if (DOMImplementation::IsXMLMIMEType(type))
+ type_ = Type::kXML;
+ else
+ type_ = Type::kHTML;
+ return *this;
+}
+
DocumentInit& DocumentInit::WithContextDocument(Document* context_document) {
DCHECK(!context_document_);
context_document_ = context_document;
@@ -239,13 +332,13 @@ DocumentInit& DocumentInit::WithNewRegistrationContext() {
V0CustomElementRegistrationContext* DocumentInit::RegistrationContext(
Document* document) const {
- if (!document->IsHTMLDocument() && !document->IsXHTMLDocument())
+ if (!IsA<HTMLDocument>(document) && !document->IsXHTMLDocument())
return nullptr;
if (create_new_registration_context_)
return MakeGarbageCollected<V0CustomElementRegistrationContext>();
- return registration_context_.Get();
+ return registration_context_;
}
Document* DocumentInit::ContextDocument() const {
@@ -258,13 +351,21 @@ DocumentInit& DocumentInit::WithFeaturePolicyHeader(const String& header) {
return *this;
}
+DocumentInit& DocumentInit::WithReportOnlyFeaturePolicyHeader(
+ const String& header) {
+ DCHECK(report_only_feature_policy_header_.IsEmpty());
+ report_only_feature_policy_header_ = header;
+ return *this;
+}
+
DocumentInit& DocumentInit::WithOriginTrialsHeader(const String& header) {
DCHECK(origin_trials_header_.IsEmpty());
origin_trials_header_ = header;
return *this;
}
-DocumentInit& DocumentInit::WithSandboxFlags(WebSandboxFlags flags) {
+DocumentInit& DocumentInit::WithSandboxFlags(
+ mojom::blink::WebSandboxFlags flags) {
// Only allow adding more sandbox flags.
sandbox_flags_ |= flags;
return *this;
@@ -284,15 +385,82 @@ DocumentInit& DocumentInit::WithContentSecurityPolicyFromContextDoc() {
ContentSecurityPolicy* DocumentInit::GetContentSecurityPolicy() const {
DCHECK(
!(content_security_policy_ && content_security_policy_from_context_doc_));
- if (context_document_ && content_security_policy_from_context_doc_)
- return context_document_->GetContentSecurityPolicy();
+ 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;
+ }
return content_security_policy_;
}
DocumentInit& DocumentInit::WithFramePolicy(
const base::Optional<FramePolicy>& frame_policy) {
frame_policy_ = frame_policy;
+ if (frame_policy_.has_value()) {
+ DCHECK(document_loader_);
+ // Make the snapshot value of sandbox flags from the beginning of navigation
+ // available in frame loader, so that the value could be further used to
+ // initialize sandbox flags in security context. crbug.com/1026627
+ document_loader_->GetFrame()->Loader().SetFrameOwnerSandboxFlags(
+ frame_policy_.value().sandbox_flags);
+ }
+ return *this;
+}
+
+DocumentInit& DocumentInit::WithDocumentPolicy(
+ const DocumentPolicy::ParsedDocumentPolicy& document_policy) {
+ document_policy_ = document_policy;
return *this;
}
+DocumentInit& DocumentInit::WithReportOnlyDocumentPolicyHeader(
+ const String& header) {
+ DCHECK(report_only_document_policy_header_.IsEmpty());
+ report_only_document_policy_header_ = header;
+ return *this;
+}
+
+DocumentInit& DocumentInit::WithWebBundleClaimedUrl(
+ const KURL& web_bundle_claimed_url) {
+ web_bundle_claimed_url_ = web_bundle_claimed_url;
+ 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.
+ if (IsPagePopupRunningInWebTest(GetFrame())) {
+ auto* frame = GetFrame()->PagePopupOwner()->GetDocument().GetFrame();
+ return &frame->window_agent_factory();
+ }
+ if (GetFrame())
+ return &GetFrame()->window_agent_factory();
+ if (Document* context_document = ContextDocument())
+ return context_document->GetWindowAgentFactory();
+ if (const Document* owner_document = OwnerDocument())
+ return owner_document->GetWindowAgentFactory();
+ return 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();
+ else if (const Document* owner_document = OwnerDocument())
+ frame = owner_document->GetFrame();
+ return frame ? frame->GetSettings() : 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 2a26b3a173a..7a7da46660d 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_init.h
+++ b/chromium/third_party/blink/renderer/core/dom/document_init.h
@@ -32,11 +32,13 @@
#include "services/network/public/mojom/ip_address_space.mojom-shared.h"
#include "third_party/blink/public/common/frame/frame_policy.h"
-#include "third_party/blink/public/platform/web_insecure_request_policy.h"
+#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/execution_context/security_context.h"
#include "third_party/blink/renderer/core/frame/sandbox_flags.h"
#include "third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h"
+#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -48,6 +50,8 @@ class DocumentLoader;
class LocalFrame;
class HTMLImportsController;
class Settings;
+class UseCounter;
+class WindowAgentFactory;
class CORE_EXPORT DocumentInit final {
STACK_ALLOCATED();
@@ -70,6 +74,19 @@ class CORE_EXPORT DocumentInit final {
DocumentInit(const DocumentInit&);
~DocumentInit();
+ enum class Type {
+ kHTML,
+ kXHTML,
+ kImage,
+ kPlugin,
+ kMedia,
+ kSVG,
+ kXML,
+ kViewSource,
+ kText,
+ kUnspecified
+ };
+
HTMLImportsController* ImportsController() const {
return imports_controller_;
}
@@ -77,8 +94,8 @@ class CORE_EXPORT DocumentInit final {
bool HasSecurityContext() const { return MasterDocumentLoader(); }
bool IsSrcdocDocument() const;
bool ShouldSetURL() const;
- WebSandboxFlags GetSandboxFlags() const;
- WebInsecureRequestPolicy GetInsecureRequestPolicy() const;
+ mojom::blink::WebSandboxFlags GetSandboxFlags() const;
+ mojom::blink::InsecureRequestPolicy GetInsecureRequestPolicy() const;
const SecurityContext::InsecureNavigationsSet* InsecureNavigationsToUpgrade()
const;
bool GrantLoadLocalResources() const { return grant_load_local_resources_; }
@@ -87,6 +104,13 @@ class CORE_EXPORT DocumentInit final {
DocumentInit& WithDocumentLoader(DocumentLoader*);
LocalFrame* GetFrame() const;
+ UseCounter* GetUseCounter() const;
+
+ DocumentInit& WithTypeFrom(const String& type);
+ Type GetType() const { return type_; }
+ const String& GetMimeType() const { return mime_type_; }
+ 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
@@ -101,7 +125,7 @@ class CORE_EXPORT DocumentInit final {
// Specifies the Document to inherit security configurations from.
DocumentInit& WithOwnerDocument(Document*);
- Document* OwnerDocument() const { return owner_document_.Get(); }
+ Document* OwnerDocument() const { return owner_document_; }
// Specifies the SecurityOrigin in which the URL was requested. This is
// relevant for determining properties of the resulting document's origin
@@ -130,10 +154,15 @@ class CORE_EXPORT DocumentInit final {
DocumentInit& WithFeaturePolicyHeader(const String& header);
const String& FeaturePolicyHeader() const { return feature_policy_header_; }
+ DocumentInit& WithReportOnlyFeaturePolicyHeader(const String& header);
+ const String& ReportOnlyFeaturePolicyHeader() const {
+ return report_only_feature_policy_header_;
+ }
+
DocumentInit& WithOriginTrialsHeader(const String& header);
const String& OriginTrialsHeader() const { return origin_trials_header_; }
- DocumentInit& WithSandboxFlags(WebSandboxFlags flags);
+ DocumentInit& WithSandboxFlags(mojom::blink::WebSandboxFlags flags);
DocumentInit& WithContentSecurityPolicy(ContentSecurityPolicy* policy);
DocumentInit& WithContentSecurityPolicyFromContextDoc();
@@ -145,6 +174,23 @@ class CORE_EXPORT DocumentInit final {
return frame_policy_;
}
+ DocumentInit& WithDocumentPolicy(
+ const DocumentPolicy::ParsedDocumentPolicy& document_policy);
+ const DocumentPolicy::ParsedDocumentPolicy& GetDocumentPolicy() const {
+ return document_policy_;
+ }
+
+ DocumentInit& WithReportOnlyDocumentPolicyHeader(const String& header);
+ const String& ReportOnlyDocumentPolicyHeader() const {
+ return report_only_document_policy_header_;
+ }
+
+ DocumentInit& WithWebBundleClaimedUrl(const KURL& web_bundle_claimed_url);
+ const KURL& GetWebBundleClaimedUrl() const { return web_bundle_claimed_url_; }
+
+ WindowAgentFactory* GetWindowAgentFactory() const;
+ Settings* GetSettingsForWindowAgentFactory() const;
+
private:
DocumentInit(HTMLImportsController*);
@@ -154,14 +200,17 @@ class CORE_EXPORT DocumentInit final {
// of its owning Document.
DocumentLoader* MasterDocumentLoader() const;
- Member<DocumentLoader> document_loader_;
- Member<Document> parent_document_;
+ Type type_ = Type::kUnspecified;
+ String mime_type_;
+
+ DocumentLoader* document_loader_ = nullptr;
+ Document* parent_document_ = nullptr;
- Member<HTMLImportsController> imports_controller_;
+ HTMLImportsController* imports_controller_ = nullptr;
- Member<Document> context_document_;
+ Document* context_document_ = nullptr;
KURL url_;
- Member<Document> owner_document_;
+ Document* owner_document_ = nullptr;
// Initiator origin is used for calculating the document origin when the
// navigation is started in a different process. In such cases, the document
@@ -194,20 +243,22 @@ class CORE_EXPORT DocumentInit final {
// Whether the document should be able to access local file:// resources.
bool grant_load_local_resources_ = false;
- Member<V0CustomElementRegistrationContext> registration_context_;
+ V0CustomElementRegistrationContext* registration_context_ = nullptr;
bool create_new_registration_context_;
// The feature policy set via response header.
String feature_policy_header_;
+ String report_only_feature_policy_header_;
// The origin trial set via response header.
String origin_trials_header_;
// Additional sandbox flags
- WebSandboxFlags sandbox_flags_ = WebSandboxFlags::kNone;
+ mojom::blink::WebSandboxFlags sandbox_flags_ =
+ mojom::blink::WebSandboxFlags::kNone;
// Loader's CSP
- Member<ContentSecurityPolicy> content_security_policy_;
+ ContentSecurityPolicy* content_security_policy_ = nullptr;
bool content_security_policy_from_context_doc_;
network::mojom::IPAddressSpace ip_address_space_ =
@@ -215,6 +266,18 @@ class CORE_EXPORT DocumentInit final {
// The frame policy snapshot from the beginning of navigation.
base::Optional<FramePolicy> frame_policy_ = base::nullopt;
+
+ // The document policy set via response header.
+ DocumentPolicy::ParsedDocumentPolicy document_policy_;
+ String report_only_document_policy_header_;
+
+ // The claimed URL inside Web Bundle file from which the document is loaded.
+ // This URL is used for window.location and document.URL and relative path
+ // computation in the document.
+ KURL web_bundle_claimed_url_;
+
+ bool is_for_external_handler_ = false;
+ Color plugin_background_color_;
};
} // 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 2a1c3b4d032..3b9b819c42b 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_lifecycle.cc
+++ b/chromium/third_party/blink/renderer/core/dom/document_lifecycle.cc
@@ -91,8 +91,6 @@ DocumentLifecycle::DocumentLifecycle()
disallow_transition_count_(0),
check_no_transition_(false) {}
-DocumentLifecycle::~DocumentLifecycle() = default;
-
#if DCHECK_IS_ON()
bool DocumentLifecycle::CanAdvanceTo(LifecycleState next_state) const {
@@ -200,6 +198,21 @@ bool DocumentLifecycle::CanAdvanceTo(LifecycleState next_state) const {
return true;
if (next_state == kStyleClean)
return true;
+ // InAccessibility only runs if there is an ExistingAXObjectCache.
+ if (next_state == kInAccessibility)
+ return true;
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
+ next_state == kInCompositingUpdate)
+ return true;
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
+ next_state == kInPrePaint)
+ return true;
+ break;
+ case kInAccessibility:
+ if (next_state == kAccessibilityClean)
+ return true;
+ break;
+ case kAccessibilityClean:
if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
next_state == kInCompositingUpdate)
return true;
@@ -222,6 +235,8 @@ bool DocumentLifecycle::CanAdvanceTo(LifecycleState next_state) const {
return true;
if (next_state == kInCompositingUpdate)
return true;
+ if (next_state == kInAccessibility)
+ return true;
// Otherwise, we can continue onwards.
if (next_state == kCompositingClean)
return true;
@@ -236,6 +251,8 @@ bool DocumentLifecycle::CanAdvanceTo(LifecycleState next_state) const {
return true;
if (next_state == kInPrePaint)
return true;
+ if (next_state == kInAccessibility)
+ return true;
break;
case kInPrePaint:
if (next_state == kPrePaintClean)
@@ -253,6 +270,8 @@ bool DocumentLifecycle::CanAdvanceTo(LifecycleState next_state) const {
return true;
if (next_state == kInPrePaint)
return true;
+ if (next_state == kInAccessibility)
+ return true;
break;
case kInPaint:
if (next_state == kPaintClean)
@@ -270,6 +289,8 @@ bool DocumentLifecycle::CanAdvanceTo(LifecycleState next_state) const {
return true;
if (next_state == kInPaint)
return true;
+ if (next_state == kInAccessibility)
+ return true;
break;
case kStopping:
return next_state == kStopped;
@@ -290,8 +311,9 @@ bool DocumentLifecycle::CanRewindTo(LifecycleState next_state) const {
return true;
return state_ == kStyleClean || state_ == kLayoutSubtreeChangeClean ||
state_ == kAfterPerformLayout || state_ == kLayoutClean ||
- state_ == kCompositingInputsClean || state_ == kCompositingClean ||
- state_ == kPrePaintClean || state_ == kPaintClean;
+ state_ == kAccessibilityClean || state_ == kCompositingInputsClean ||
+ state_ == kCompositingClean || state_ == kPrePaintClean ||
+ state_ == kPaintClean;
}
#define DEBUG_STRING_CASE(StateName) \
@@ -312,6 +334,8 @@ static WTF::String StateAsDebugString(
DEBUG_STRING_CASE(kInPerformLayout);
DEBUG_STRING_CASE(kAfterPerformLayout);
DEBUG_STRING_CASE(kLayoutClean);
+ DEBUG_STRING_CASE(kInAccessibility);
+ DEBUG_STRING_CASE(kAccessibilityClean);
DEBUG_STRING_CASE(kInCompositingUpdate);
DEBUG_STRING_CASE(kCompositingInputsClean);
DEBUG_STRING_CASE(kCompositingClean);
diff --git a/chromium/third_party/blink/renderer/core/dom/document_lifecycle.h b/chromium/third_party/blink/renderer/core/dom/document_lifecycle.h
index 5327f5ce96c..62ce22ed6e2 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_lifecycle.h
+++ b/chromium/third_party/blink/renderer/core/dom/document_lifecycle.h
@@ -66,6 +66,11 @@ class CORE_EXPORT DocumentLifecycle {
kAfterPerformLayout,
kLayoutClean,
+ // In InAccessibility step, fire deferred accessibility events which
+ // require layout to be in a clean state.
+ kInAccessibility,
+ kAccessibilityClean,
+
kInCompositingUpdate,
kCompositingInputsClean,
kCompositingClean,
@@ -87,9 +92,6 @@ class CORE_EXPORT DocumentLifecycle {
kStopped,
};
- // This must be kept coordinated with WebWidget::LifecycleUpdateReason
- enum LifecycleUpdateReason { kBeginMainFrame, kTest, kOther };
-
class Scope {
STACK_ALLOCATED();
@@ -213,7 +215,6 @@ class CORE_EXPORT DocumentLifecycle {
};
DocumentLifecycle();
- ~DocumentLifecycle();
bool IsActive() const { return state_ > kInactive && state_ < kStopping; }
LifecycleState GetState() const { return state_; }
diff --git a/chromium/third_party/blink/renderer/core/dom/document_or_shadow_root.h b/chromium/third_party/blink/renderer/core/dom/document_or_shadow_root.h
index 6e0427e3566..cfed2ae42a7 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_or_shadow_root.h
+++ b/chromium/third_party/blink/renderer/core/dom/document_or_shadow_root.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_DOCUMENT_OR_SHADOW_ROOT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_DOCUMENT_OR_SHADOW_ROOT_H_
+#include "third_party/blink/renderer/core/animation/document_animation.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
@@ -50,6 +51,15 @@ class DocumentOrShadowRoot {
return tree_scope.GetSelection();
}
+ static HeapVector<Member<Animation>> getAnimations(Document& document) {
+ return document.GetDocumentAnimations().getAnimations(document);
+ }
+
+ static HeapVector<Member<Animation>> getAnimations(ShadowRoot& shadow_root) {
+ return shadow_root.GetDocument().GetDocumentAnimations().getAnimations(
+ shadow_root);
+ }
+
static Element* elementFromPoint(TreeScope& tree_scope, double x, double y) {
return tree_scope.ElementFromPoint(x, y);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/document_or_shadow_root.idl b/chromium/third_party/blink/renderer/core/dom/document_or_shadow_root.idl
index f637e1a98b5..212bde8455e 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_or_shadow_root.idl
+++ b/chromium/third_party/blink/renderer/core/dom/document_or_shadow_root.idl
@@ -10,6 +10,9 @@
// Selection API
// https://w3c.github.io/selection-api/#extensions-to-document-interface
[Affects=Nothing] Selection? getSelection();
+ // Web-Animation-API
+ //https://drafts.csswg.org/web-animations/#extensions-to-the-documentorshadowroot-interface-mixin
+ [RuntimeEnabled=WebAnimationsAPI, Measure] sequence<Animation> getAnimations();
// CSSOM View Module
// https://drafts.csswg.org/cssom-view/#extensions-to-the-document-interface
Element? elementFromPoint(double x, double y);
diff --git a/chromium/third_party/blink/renderer/core/dom/document_shutdown_notifier.cc b/chromium/third_party/blink/renderer/core/dom/document_shutdown_notifier.cc
deleted file mode 100644
index 575a859ab7f..00000000000
--- a/chromium/third_party/blink/renderer/core/dom/document_shutdown_notifier.cc
+++ /dev/null
@@ -1,14 +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/dom/document_shutdown_notifier.h"
-
-#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/dom/document_shutdown_observer.h"
-
-namespace blink {
-
-DocumentShutdownNotifier::DocumentShutdownNotifier() = default;
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/dom/document_shutdown_notifier.h b/chromium/third_party/blink/renderer/core/dom/document_shutdown_notifier.h
deleted file mode 100644
index a7c241b01fd..00000000000
--- a/chromium/third_party/blink/renderer/core/dom/document_shutdown_notifier.h
+++ /dev/null
@@ -1,29 +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_DOM_DOCUMENT_SHUTDOWN_NOTIFIER_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_DOCUMENT_SHUTDOWN_NOTIFIER_H_
-
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/platform/lifecycle_notifier.h"
-
-namespace blink {
-
-class Document;
-class DocumentShutdownObserver;
-
-// Sibling class of DocumentShutdownObserver; implemented by Document to notify
-// subclasses of DocumentShutdownObserver of Document shutdown.
-class CORE_EXPORT DocumentShutdownNotifier
- : public LifecycleNotifier<Document, DocumentShutdownObserver> {
- protected:
- DocumentShutdownNotifier();
-
- private:
- DISALLOW_COPY_AND_ASSIGN(DocumentShutdownNotifier);
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_DOCUMENT_SHUTDOWN_NOTIFIER_H_
diff --git a/chromium/third_party/blink/renderer/core/dom/document_shutdown_observer.cc b/chromium/third_party/blink/renderer/core/dom/document_shutdown_observer.cc
deleted file mode 100644
index 76f3327775e..00000000000
--- a/chromium/third_party/blink/renderer/core/dom/document_shutdown_observer.cc
+++ /dev/null
@@ -1,17 +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/dom/document_shutdown_observer.h"
-
-#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/dom/document_shutdown_notifier.h"
-
-namespace blink {
-
-void DocumentShutdownObserver::ContextDestroyed(Document*) {}
-
-DocumentShutdownObserver::DocumentShutdownObserver()
- : LifecycleObserver(nullptr) {}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/dom/document_shutdown_observer.h b/chromium/third_party/blink/renderer/core/dom/document_shutdown_observer.h
deleted file mode 100644
index e7321eca284..00000000000
--- a/chromium/third_party/blink/renderer/core/dom/document_shutdown_observer.h
+++ /dev/null
@@ -1,35 +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_DOM_DOCUMENT_SHUTDOWN_OBSERVER_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_DOCUMENT_SHUTDOWN_OBSERVER_H_
-
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/platform/lifecycle_observer.h"
-
-namespace blink {
-
-class Document;
-
-// This class is a base class for classes which observe Document shutdown
-// synchronously.
-// Note: this functionality is also provided by SynchronousMutationObserver,
-// but if you don't need to respond to the other events handled by that class,
-// using this class is more efficient.
-class CORE_EXPORT DocumentShutdownObserver
- : public LifecycleObserver<Document, DocumentShutdownObserver> {
- public:
- // Called when detaching document.
- virtual void ContextDestroyed(Document*);
-
- protected:
- DocumentShutdownObserver();
-
- private:
- DISALLOW_COPY_AND_ASSIGN(DocumentShutdownObserver);
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_DOCUMENT_SHUTDOWN_OBSERVER_H_
diff --git a/chromium/third_party/blink/renderer/core/dom/document_statistics_collector.cc b/chromium/third_party/blink/renderer/core/dom/document_statistics_collector.cc
index dfbc4d3b1c6..b575ca1e27f 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_statistics_collector.cc
+++ b/chromium/third_party/blink/renderer/core/dom/document_statistics_collector.cc
@@ -169,7 +169,7 @@ bool HasOpenGraphArticle(const Element& head) {
if (meta->GetName() == og_type ||
meta->getAttribute(property_attr) == og_type) {
- if (DeprecatedEqualIgnoringCase(meta->Content(), "article")) {
+ if (EqualIgnoringASCIICase(meta->Content(), "article")) {
return true;
}
}
diff --git a/chromium/third_party/blink/renderer/core/dom/document_statistics_collector_test.cc b/chromium/third_party/blink/renderer/core/dom/document_statistics_collector_test.cc
index 1e4245e7d6f..cd881386004 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_statistics_collector_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/document_statistics_collector_test.cc
@@ -35,7 +35,7 @@ class DocumentStatisticsCollectorTest : public PageTestBase {
void DocumentStatisticsCollectorTest::SetHtmlInnerHTML(
const String& html_content) {
- GetDocument().documentElement()->SetInnerHTMLFromString((html_content));
+ GetDocument().documentElement()->setInnerHTML((html_content));
}
// This test checks open graph articles can be recognized.
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 e1cfa453dd4..5d3721c6624 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/document_test.cc
@@ -34,9 +34,12 @@
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
+#include "components/ukm/test_ukm_recorder.h"
#include "services/network/public/mojom/referrer_policy.mojom-blink.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/feature_policy/document_policy_features.h"
+#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
@@ -71,9 +74,13 @@
#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/wtf/text/string_builder.h"
+#include "url/url_util.h"
namespace blink {
+using network::mojom::ContentSecurityPolicySource;
+using network::mojom::ContentSecurityPolicyType;
+
class DocumentTest : public PageTestBase {
protected:
void TearDown() override {
@@ -85,8 +92,7 @@ class DocumentTest : public PageTestBase {
};
void DocumentTest::SetHtmlInnerHTML(const char* html_content) {
- GetDocument().documentElement()->SetInnerHTMLFromString(
- String::FromUTF8(html_content));
+ GetDocument().documentElement()->setInnerHTML(String::FromUTF8(html_content));
UpdateAllLifecyclePhasesForTest();
}
@@ -135,11 +141,11 @@ class TestSynchronousMutationObserver
void Trace(Visitor* visitor) { visitor->Trace(node_); }
};
- TestSynchronousMutationObserver(Document&);
+ explicit TestSynchronousMutationObserver(Document&);
virtual ~TestSynchronousMutationObserver() = default;
int CountContextDestroyedCalled() const {
- return context_destroyed_called_counter_;
+ return on_document_shutdown_called_counter_;
}
const HeapVector<Member<const ContainerNode>>& ChildrenChangedNodes() const {
@@ -176,7 +182,7 @@ class TestSynchronousMutationObserver
private:
// Implement |SynchronousMutationObserver| member functions.
- void ContextDestroyed(Document*) final;
+ void ContextDestroyed() final;
void DidChangeChildren(const ContainerNode&) final;
void DidMergeTextNodes(const Text&, const NodeWithIndex&, unsigned) final;
void DidMoveTreeToNewDocument(const Node& root) final;
@@ -188,7 +194,7 @@ class TestSynchronousMutationObserver
void NodeChildrenWillBeRemoved(ContainerNode&) final;
void NodeWillBeRemoved(Node&) final;
- int context_destroyed_called_counter_ = 0;
+ int on_document_shutdown_called_counter_ = 0;
HeapVector<Member<const ContainerNode>> children_changed_nodes_;
HeapVector<Member<MergeTextNodesRecord>> merge_text_nodes_records_;
HeapVector<Member<const Node>> move_tree_to_new_document_nodes_;
@@ -202,11 +208,11 @@ class TestSynchronousMutationObserver
TestSynchronousMutationObserver::TestSynchronousMutationObserver(
Document& document) {
- SetContext(&document);
+ SetDocument(&document);
}
-void TestSynchronousMutationObserver::ContextDestroyed(Document*) {
- ++context_destroyed_called_counter_;
+void TestSynchronousMutationObserver::ContextDestroyed() {
+ ++on_document_shutdown_called_counter_;
}
void TestSynchronousMutationObserver::DidChangeChildren(
@@ -262,42 +268,6 @@ void TestSynchronousMutationObserver::Trace(Visitor* visitor) {
SynchronousMutationObserver::Trace(visitor);
}
-class TestDocumentShutdownObserver
- : public GarbageCollected<TestDocumentShutdownObserver>,
- public DocumentShutdownObserver {
- USING_GARBAGE_COLLECTED_MIXIN(TestDocumentShutdownObserver);
-
- public:
- TestDocumentShutdownObserver(Document&);
- virtual ~TestDocumentShutdownObserver() = default;
-
- int CountContextDestroyedCalled() const {
- return context_destroyed_called_counter_;
- }
-
- void Trace(Visitor*) override;
-
- private:
- // Implement |DocumentShutdownObserver| member functions.
- void ContextDestroyed(Document*) final;
-
- int context_destroyed_called_counter_ = 0;
-
- DISALLOW_COPY_AND_ASSIGN(TestDocumentShutdownObserver);
-};
-
-TestDocumentShutdownObserver::TestDocumentShutdownObserver(Document& document) {
- SetContext(&document);
-}
-
-void TestDocumentShutdownObserver::ContextDestroyed(Document*) {
- ++context_destroyed_called_counter_;
-}
-
-void TestDocumentShutdownObserver::Trace(Visitor* visitor) {
- DocumentShutdownObserver::Trace(visitor);
-}
-
class MockDocumentValidationMessageClient
: public GarbageCollected<MockDocumentValidationMessageClient>,
public ValidationMessageClient {
@@ -362,8 +332,7 @@ class PrefersColorSchemeTestListener final : public MediaQueryListListener {
} // anonymous namespace
TEST_F(DocumentTest, CreateRangeAdjustedToTreeScopeWithPositionInShadowTree) {
- GetDocument().body()->SetInnerHTMLFromString(
- "<div><select><option>012</option></div>");
+ GetDocument().body()->setInnerHTML("<div><select><option>012</option></div>");
Element* const select_element = GetDocument().QuerySelector("select");
const Position& position =
Position(*select_element->UserAgentShadowRoot(),
@@ -550,9 +519,7 @@ TEST_F(DocumentTest, referrerPolicyParsing) {
{"same-origin", network::mojom::ReferrerPolicy::kSameOrigin, false},
{"strict-origin", network::mojom::ReferrerPolicy::kStrictOrigin, false},
{"strict-origin-when-cross-origin",
- network::mojom::ReferrerPolicy::
- kNoReferrerWhenDowngradeOriginWhenCrossOrigin,
- false},
+ network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin, false},
{"unsafe-url", network::mojom::ReferrerPolicy::kAlways},
};
@@ -561,12 +528,15 @@ TEST_F(DocumentTest, referrerPolicyParsing) {
if (test.is_legacy) {
// Legacy keyword support must be explicitly enabled for the policy to
// parse successfully.
- GetDocument().ParseAndSetReferrerPolicy(test.policy);
+ GetDocument().GetExecutionContext()->ParseAndSetReferrerPolicy(
+ test.policy);
EXPECT_EQ(network::mojom::ReferrerPolicy::kDefault,
GetDocument().GetReferrerPolicy());
- GetDocument().ParseAndSetReferrerPolicy(test.policy, true);
+ GetDocument().GetExecutionContext()->ParseAndSetReferrerPolicy(
+ test.policy, true);
} else {
- GetDocument().ParseAndSetReferrerPolicy(test.policy);
+ GetDocument().GetExecutionContext()->ParseAndSetReferrerPolicy(
+ test.policy);
}
EXPECT_EQ(test.expected, GetDocument().GetReferrerPolicy()) << test.policy;
}
@@ -578,8 +548,8 @@ TEST_F(DocumentTest, OutgoingReferrer) {
}
TEST_F(DocumentTest, OutgoingReferrerWithUniqueOrigin) {
- NavigateTo(KURL("https://www.example.com/hoge#fuga?piyo"), "",
- "sandbox allow-scripts");
+ 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());
}
@@ -614,30 +584,35 @@ TEST_F(DocumentTest, StyleVersion) {
}
TEST_F(DocumentTest, EnforceSandboxFlags) {
- NavigateTo(KURL("http://example.test/"), "", "sandbox allow-same-origin");
+ NavigateTo(KURL("http://example.test/"), {{http_names::kContentSecurityPolicy,
+ "sandbox allow-same-origin"}});
EXPECT_FALSE(GetDocument().GetSecurityOrigin()->IsOpaque());
EXPECT_FALSE(GetDocument().GetSecurityOrigin()->IsPotentiallyTrustworthy());
- NavigateTo(KURL("http://example.test/"), "", "sandbox");
+ NavigateTo(KURL("http://example.test/"),
+ {{http_names::kContentSecurityPolicy, "sandbox"}});
EXPECT_TRUE(GetDocument().GetSecurityOrigin()->IsOpaque());
EXPECT_FALSE(GetDocument().GetSecurityOrigin()->IsPotentiallyTrustworthy());
// A unique origin does not bypass secure context checks unless it
// is also potentially trustworthy.
- url::AddStandardScheme("very-special-scheme",
- url::SchemeType::SCHEME_WITH_HOST);
+ url::ScopedSchemeRegistryForTests scoped_registry;
+ url::AddStandardScheme("very-special-scheme", url::SCHEME_WITH_HOST);
SchemeRegistry::RegisterURLSchemeBypassingSecureContextCheck(
"very-special-scheme");
- NavigateTo(KURL("very-special-scheme://example.test"), "", "sandbox");
+ NavigateTo(KURL("very-special-scheme://example.test"),
+ {{http_names::kContentSecurityPolicy, "sandbox"}});
EXPECT_TRUE(GetDocument().GetSecurityOrigin()->IsOpaque());
EXPECT_FALSE(GetDocument().GetSecurityOrigin()->IsPotentiallyTrustworthy());
SchemeRegistry::RegisterURLSchemeAsSecure("very-special-scheme");
- NavigateTo(KURL("very-special-scheme://example.test"), "", "sandbox");
+ NavigateTo(KURL("very-special-scheme://example.test"),
+ {{http_names::kContentSecurityPolicy, "sandbox"}});
EXPECT_TRUE(GetDocument().GetSecurityOrigin()->IsOpaque());
EXPECT_TRUE(GetDocument().GetSecurityOrigin()->IsPotentiallyTrustworthy());
- NavigateTo(KURL("https://example.test"), "", "sandbox");
+ NavigateTo(KURL("https://example.test"),
+ {{http_names::kContentSecurityPolicy, "sandbox"}});
EXPECT_TRUE(GetDocument().GetSecurityOrigin()->IsOpaque());
EXPECT_TRUE(GetDocument().GetSecurityOrigin()->IsPotentiallyTrustworthy());
}
@@ -646,7 +621,7 @@ TEST_F(DocumentTest, SynchronousMutationNotifier) {
auto& observer =
*MakeGarbageCollected<TestSynchronousMutationObserver>(GetDocument());
- EXPECT_EQ(GetDocument(), observer.LifecycleContext());
+ EXPECT_EQ(GetDocument(), observer.GetDocument());
EXPECT_EQ(0, observer.CountContextDestroyedCalled());
Element* div_node = GetDocument().CreateRawElement(html_names::kDivTag);
@@ -673,7 +648,7 @@ TEST_F(DocumentTest, SynchronousMutationNotifier) {
EXPECT_EQ(div_node, observer.RemovedChildrenNodes()[0]);
GetDocument().Shutdown();
- EXPECT_EQ(nullptr, observer.LifecycleContext());
+ EXPECT_EQ(nullptr, observer.GetDocument());
EXPECT_EQ(1, observer.CountContextDestroyedCalled());
}
@@ -817,18 +792,6 @@ TEST_F(DocumentTest, SynchronousMutationNotifierUpdateCharacterData) {
EXPECT_EQ(3u, observer.UpdatedCharacterDataRecords()[3]->new_length_);
}
-TEST_F(DocumentTest, DocumentShutdownNotifier) {
- auto& observer =
- *MakeGarbageCollected<TestDocumentShutdownObserver>(GetDocument());
-
- EXPECT_EQ(GetDocument(), observer.LifecycleContext());
- EXPECT_EQ(0, observer.CountContextDestroyedCalled());
-
- GetDocument().Shutdown();
- EXPECT_EQ(nullptr, observer.LifecycleContext());
- EXPECT_EQ(1, observer.CountContextDestroyedCalled());
-}
-
TEST_F(DocumentTest, AttachExecutionContext) {
EXPECT_TRUE(
GetDocument().GetAgent()->event_loop()->IsSchedulerAttachedForTest(
@@ -880,7 +843,7 @@ TEST_F(DocumentTest, ValidationMessageCleanup) {
"document.querySelector('input').reportValidity(); };");
GetDocument().body()->AppendChild(script);
auto* input = To<HTMLInputElement>(GetDocument().body()->firstChild());
- DVLOG(0) << GetDocument().body()->OuterHTMLAsString();
+ DVLOG(0) << GetDocument().body()->outerHTML();
// Sanity check.
input->reportValidity();
@@ -897,7 +860,8 @@ TEST_F(DocumentTest, ValidationMessageCleanup) {
}
TEST_F(DocumentTest, SandboxDisablesAppCache) {
- NavigateTo(KURL("https://test.com/foobar/document"), "", "sandbox");
+ NavigateTo(KURL("https://test.com/foobar/document"),
+ {{http_names::kContentSecurityPolicy, "sandbox"}});
GetDocument().Loader()->SetApplicationCacheHostForTesting(
MakeGarbageCollected<MockApplicationCacheHost>(GetDocument().Loader()));
@@ -914,7 +878,7 @@ TEST_F(DocumentTest, SandboxDisablesAppCache) {
// as it is more expensive than just doing layout.
TEST_F(DocumentTest,
EnsurePaintLocationDataValidForNodeCompositingInputsOnlyWhenNecessary) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<div id='ancestor'>
<div id='sticky' style='position:sticky;'>
<div id='stickyChild'></div>
@@ -929,19 +893,19 @@ TEST_F(DocumentTest,
// Asking for any element that is not affected by a sticky element should only
// advance the lifecycle to layout clean.
GetDocument().EnsurePaintLocationDataValidForNode(
- GetDocument().getElementById("ancestor"));
+ GetDocument().getElementById("ancestor"), DocumentUpdateReason::kTest);
EXPECT_EQ(DocumentLifecycle::kLayoutClean,
GetDocument().Lifecycle().GetState());
GetDocument().EnsurePaintLocationDataValidForNode(
- GetDocument().getElementById("nonSticky"));
+ GetDocument().getElementById("nonSticky"), DocumentUpdateReason::kTest);
EXPECT_EQ(DocumentLifecycle::kLayoutClean,
GetDocument().Lifecycle().GetState());
// However, asking for either the sticky element or it's descendents should
// clean compositing inputs as well.
GetDocument().EnsurePaintLocationDataValidForNode(
- GetDocument().getElementById("sticky"));
+ GetDocument().getElementById("sticky"), DocumentUpdateReason::kTest);
EXPECT_EQ(DocumentLifecycle::kCompositingInputsClean,
GetDocument().Lifecycle().GetState());
@@ -951,7 +915,7 @@ TEST_F(DocumentTest,
GetDocument().Lifecycle().GetState());
GetDocument().EnsurePaintLocationDataValidForNode(
- GetDocument().getElementById("stickyChild"));
+ GetDocument().getElementById("stickyChild"), DocumentUpdateReason::kTest);
EXPECT_EQ(DocumentLifecycle::kCompositingInputsClean,
GetDocument().Lifecycle().GetState());
}
@@ -996,8 +960,8 @@ TEST_P(IsolatedWorldCSPTest, CSPForWorld) {
// Set a CSP for the main world.
const char* kMainWorldCSP = "connect-src https://google.com;";
GetDocument().GetContentSecurityPolicy()->DidReceiveHeader(
- kMainWorldCSP, kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ kMainWorldCSP, ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
LocalFrame* frame = GetDocument().GetFrame();
ScriptState* main_world_script_state = ToScriptStateForMainWorld(frame);
@@ -1031,7 +995,7 @@ TEST_P(IsolatedWorldCSPTest, CSPForWorld) {
ScriptState::Scope scope(main_world_script_state);
EXPECT_THAT(get_csp_headers(),
ElementsAre(CSPHeaderAndType(
- {kMainWorldCSP, kContentSecurityPolicyHeaderTypeEnforce})));
+ {kMainWorldCSP, ContentSecurityPolicyType::kEnforce})));
}
{
@@ -1042,7 +1006,7 @@ TEST_P(IsolatedWorldCSPTest, CSPForWorld) {
// CSP.
EXPECT_THAT(get_csp_headers(),
ElementsAre(CSPHeaderAndType(
- {kMainWorldCSP, kContentSecurityPolicyHeaderTypeEnforce})));
+ {kMainWorldCSP, ContentSecurityPolicyType::kEnforce})));
}
{
@@ -1062,7 +1026,7 @@ TEST_P(IsolatedWorldCSPTest, CSPForWorld) {
EXPECT_THAT(
get_csp_headers(),
ElementsAre(CSPHeaderAndType(
- {kIsolatedWorldCSP, kContentSecurityPolicyHeaderTypeEnforce})));
+ {kIsolatedWorldCSP, ContentSecurityPolicyType::kEnforce})));
}
}
}
@@ -1072,7 +1036,8 @@ INSTANTIATE_TEST_SUITE_P(All,
testing::Values(true, false));
TEST_F(DocumentTest, CanExecuteScriptsWithSandboxAndIsolatedWorld) {
- NavigateTo(KURL("https://www.example.com/"), "", "sandbox");
+ NavigateTo(KURL("https://www.example.com/"),
+ {{http_names::kContentSecurityPolicy, "sandbox"}});
LocalFrame* frame = GetDocument().GetFrame();
frame->GetSettings()->SetScriptEnabled(true);
@@ -1178,6 +1143,8 @@ TEST_F(DocumentTest, ElementFromPointWithPageZoom) {
}
TEST_F(DocumentTest, PrefersColorSchemeChanged) {
+ ColorSchemeHelper color_scheme_helper(GetDocument());
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kLight);
UpdateAllLifecyclePhasesForTest();
auto* list = GetDocument().GetMediaQueryMatcher().MatchMedia(
@@ -1187,9 +1154,7 @@ TEST_F(DocumentTest, PrefersColorSchemeChanged) {
EXPECT_FALSE(listener->IsNotified());
- ColorSchemeHelper color_scheme_helper;
- color_scheme_helper.SetPreferredColorScheme(GetDocument(),
- PreferredColorScheme::kDark);
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kDark);
UpdateAllLifecyclePhasesForTest();
GetDocument().ServiceScriptedAnimations(base::TimeTicks());
@@ -1197,43 +1162,61 @@ TEST_F(DocumentTest, PrefersColorSchemeChanged) {
EXPECT_TRUE(listener->IsNotified());
}
-TEST_F(DocumentTest, DocumentPolicyFeaturePolicyCoexist) {
- blink::ScopedDocumentPolicyForTest sdp(true);
- const auto test_feature = blink::mojom::FeaturePolicyFeature::kFontDisplay;
- const auto report_option = blink::ReportOptions::kReportOnFailure;
-
- // When document_policy is not initialized, feature_policy should
- // be sufficient to determine the result.
- NavigateTo(KURL("https://www.example.com/"), "font-display-late-swap 'none'",
- "");
- EXPECT_FALSE(GetDocument().IsFeatureEnabled(test_feature, report_option));
-
- NavigateTo(KURL("https://www.example.com/"), "font-display-late-swap *", "");
- EXPECT_TRUE(GetDocument().IsFeatureEnabled(test_feature, report_option));
-
- // When document_policy is specified, both feature_policy and
- // document_policy need to return true for the feature to be
- // enabled.
- NavigateTo(KURL("https://www.example.com/"), "font-display-late-swap *", "");
- GetDocument().SetDocumentPolicyForTesting(
- DocumentPolicy::CreateWithRequiredPolicy(
- {{test_feature, blink::PolicyValue(true)}}));
- EXPECT_TRUE(GetDocument().IsFeatureEnabled(test_feature, report_option));
- GetDocument().SetDocumentPolicyForTesting(
- DocumentPolicy::CreateWithRequiredPolicy(
- {{test_feature, blink::PolicyValue(false)}}));
- EXPECT_FALSE(GetDocument().IsFeatureEnabled(test_feature, report_option));
-
- NavigateTo(KURL("https://www.example.com/"), "font-display-late-swap 'none'",
- "");
- GetDocument().SetDocumentPolicyForTesting(
- DocumentPolicy::CreateWithRequiredPolicy(
- {{test_feature, blink::PolicyValue(true)}}));
- EXPECT_FALSE(GetDocument().IsFeatureEnabled(test_feature, report_option));
- GetDocument().SetDocumentPolicyForTesting(
- DocumentPolicy::CreateWithRequiredPolicy(
- {{test_feature, blink::PolicyValue(false)}}));
- EXPECT_FALSE(GetDocument().IsFeatureEnabled(test_feature, report_option));
+TEST_F(DocumentTest, FindInPageUkm) {
+ GetDocument().ukm_recorder_ = std::make_unique<ukm::TestUkmRecorder>();
+ auto* recorder =
+ static_cast<ukm::TestUkmRecorder*>(GetDocument().UkmRecorder());
+
+ EXPECT_EQ(recorder->entries_count(), 0u);
+ GetDocument().MarkHasFindInPageRequest();
+ EXPECT_EQ(recorder->entries_count(), 1u);
+ GetDocument().MarkHasFindInPageRequest();
+ EXPECT_EQ(recorder->entries_count(), 1u);
+
+ auto entries = recorder->GetEntriesByName("Blink.FindInPage");
+ EXPECT_EQ(entries.size(), 1u);
+ EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entries[0], "DidSearch"));
+ EXPECT_EQ(*ukm::TestUkmRecorder::GetEntryMetric(entries[0], "DidSearch"), 1);
+ EXPECT_FALSE(ukm::TestUkmRecorder::EntryHasMetric(
+ entries[0], "DidHaveRenderSubtreeMatch"));
+
+ GetDocument().MarkHasFindInPageSubtreeVisibilityActiveMatch();
+ EXPECT_EQ(recorder->entries_count(), 2u);
+ GetDocument().MarkHasFindInPageSubtreeVisibilityActiveMatch();
+ EXPECT_EQ(recorder->entries_count(), 2u);
+ entries = recorder->GetEntriesByName("Blink.FindInPage");
+ EXPECT_EQ(entries.size(), 2u);
+
+ EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entries[0], "DidSearch"));
+ EXPECT_EQ(*ukm::TestUkmRecorder::GetEntryMetric(entries[0], "DidSearch"), 1);
+ EXPECT_FALSE(ukm::TestUkmRecorder::EntryHasMetric(
+ entries[0], "DidHaveRenderSubtreeMatch"));
+
+ EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(
+ entries[1], "DidHaveRenderSubtreeMatch"));
+ EXPECT_EQ(*ukm::TestUkmRecorder::GetEntryMetric(entries[1],
+ "DidHaveRenderSubtreeMatch"),
+ 1);
+ EXPECT_FALSE(ukm::TestUkmRecorder::EntryHasMetric(entries[1], "DidSearch"));
+}
+
+TEST_F(DocumentTest, AtPageMarginWithDeviceScaleFactor) {
+ GetDocument().GetFrame()->SetPageZoomFactor(2);
+ SetBodyInnerHTML("<style>@page { margin: 50px; size: 400px 10in; }</style>");
+
+ constexpr FloatSize initial_page_size(800, 600);
+
+ GetDocument().GetFrame()->StartPrinting(initial_page_size, initial_page_size);
+ GetDocument().View()->UpdateLifecyclePhasesForPrinting();
+
+ DoubleSize page_size;
+ int margin[4];
+ GetDocument().PageSizeAndMarginsInPixels(0, page_size, margin[0], margin[1],
+ margin[2], margin[3]);
+
+ for (int side_margin : margin)
+ EXPECT_EQ(50, side_margin);
+ EXPECT_EQ(DoubleSize(400, 960), page_size);
}
/**
@@ -1321,7 +1304,7 @@ class ParameterizedViewportFitDocumentTest
html.Append("'>");
}
- GetDocument().documentElement()->SetInnerHTMLFromString(html.ToString());
+ GetDocument().documentElement()->setInnerHTML(html.ToString());
UpdateAllLifecyclePhasesForTest();
}
};
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 beb3f9deb31..cb5d4b364e4 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_timing.cc
+++ b/chromium/third_party/blink/renderer/core/dom/document_timing.cc
@@ -12,7 +12,10 @@
namespace blink {
-DocumentTiming::DocumentTiming(Document& document) : document_(document) {}
+DocumentTiming::DocumentTiming(Document& document) : document_(document) {
+ if (document_->GetReadyState() == Document::kLoading)
+ MarkDomLoading();
+}
void DocumentTiming::Trace(Visitor* visitor) {
visitor->Trace(document_);
@@ -72,12 +75,4 @@ void DocumentTiming::MarkDomComplete() {
NotifyDocumentTimingChanged();
}
-void DocumentTiming::MarkFirstLayout() {
- first_layout_ = base::TimeTicks::Now();
- TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing,rail", "firstLayout",
- first_layout_, "frame",
- ToTraceValue(GetFrame()));
- NotifyDocumentTimingChanged();
-}
-
} // namespace blink
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 5dd735d169d..b3401679130 100644
--- a/chromium/third_party/blink/renderer/core/dom/document_timing.h
+++ b/chromium/third_party/blink/renderer/core/dom/document_timing.h
@@ -44,7 +44,6 @@ class DocumentTiming final {
void MarkDomContentLoadedEventStart();
void MarkDomContentLoadedEventEnd();
void MarkDomComplete();
- void MarkFirstLayout();
// These return monotonically-increasing time.
base::TimeTicks DomLoading() const { return dom_loading_; }
@@ -56,7 +55,6 @@ class DocumentTiming final {
return dom_content_loaded_event_end_;
}
base::TimeTicks DomComplete() const { return dom_complete_; }
- base::TimeTicks FirstLayout() const { return first_layout_; }
void Trace(Visitor*);
@@ -69,7 +67,6 @@ class DocumentTiming final {
base::TimeTicks dom_content_loaded_event_start_;
base::TimeTicks dom_content_loaded_event_end_;
base::TimeTicks dom_complete_;
- base::TimeTicks first_layout_;
Member<Document> document_;
};
diff --git a/chromium/third_party/blink/renderer/core/dom/dom_exception.idl b/chromium/third_party/blink/renderer/core/dom/dom_exception.idl
index 2e3e9adac67..fee491b6b8a 100644
--- a/chromium/third_party/blink/renderer/core/dom/dom_exception.idl
+++ b/chromium/third_party/blink/renderer/core/dom/dom_exception.idl
@@ -32,10 +32,10 @@
[
Exposed=(Window,Worker),
- Constructor(optional DOMString message = "", optional DOMString name = "Error"),
Serializable,
DoNotCheckConstants
] interface DOMException {
+ constructor(optional DOMString message = "", optional DOMString name = "Error");
readonly attribute unsigned short code;
readonly attribute DOMString name;
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 55f1adf5e98..7c1a0d0f2cf 100644
--- a/chromium/third_party/blink/renderer/core/dom/dom_implementation.cc
+++ b/chromium/third_party/blink/renderer/core/dom/dom_implementation.cc
@@ -32,6 +32,7 @@
#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"
@@ -41,14 +42,11 @@
#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/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/html_names.h"
#include "third_party/blink/renderer/core/loader/frame_loader.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/svg_names.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
@@ -206,84 +204,42 @@ Document* DOMImplementation::createHTMLDocument(const String& title) {
return d;
}
-Document* DOMImplementation::createDocument(const String& type,
- const DocumentInit& init,
- bool in_view_source_mode) {
- if (in_view_source_mode)
- return MakeGarbageCollected<HTMLViewSourceDocument>(init, type);
-
- // Plugins cannot take HTML and XHTML from us, and we don't even need to
- // initialize the plugin database for those.
- if (type == "text/html")
- return MakeGarbageCollected<HTMLDocument>(init);
- if (type == "application/xhtml+xml")
- return XMLDocument::CreateXHTML(init);
-
- PluginData* plugin_data = nullptr;
- if (init.GetFrame() && init.GetFrame()->GetPage() &&
- init.GetFrame()->Loader().AllowPlugins(kNotAboutToInstantiatePlugin)) {
- // If the document is being created for the main frame,
- // init.frame()->tree().top()->securityContext() returns nullptr.
- // For that reason, the origin must be retrieved directly from init.url().
- if (init.GetFrame()->IsMainFrame()) {
- scoped_refptr<const SecurityOrigin> origin =
- SecurityOrigin::Create(init.Url());
- plugin_data = init.GetFrame()->GetPage()->GetPluginData(origin.get());
- } else {
- plugin_data =
- init.GetFrame()->GetPage()->GetPluginData(init.GetFrame()
- ->Tree()
- .Top()
- .GetSecurityContext()
- ->GetSecurityOrigin());
+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(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;
}
-
- if (plugin_data && plugin_data->IsExternalPluginMimeType(type)) {
- // Plugins handled by MimeHandlerView do not create a PluginDocument. They
- // are rendered inside cross-process frames and the notion of a PluginView
- // (which is associated with PluginDocument) is irrelevant here.
- auto* html_document = MakeGarbageCollected<HTMLDocument>(init);
- html_document->SetIsForExternalHandler();
- return html_document;
- }
-
- // PDF is one image type for which a plugin can override built-in support.
- // We do not want QuickTime to take over all image types, obviously.
- if ((type == "application/pdf" || type == "text/pdf") && plugin_data &&
- plugin_data->SupportsMimeType(type)) {
- return MakeGarbageCollected<PluginDocument>(
- init, plugin_data->PluginBackgroundColorForMimeType(type));
- }
- // multipart/x-mixed-replace is only supported for images.
- if (MIMETypeRegistry::IsSupportedImageResourceMIMEType(type) ||
- type == "multipart/x-mixed-replace") {
- return MakeGarbageCollected<ImageDocument>(init);
- }
-
- // Check to see if the type can be played by our media player, if so create a
- // MediaDocument
- if (HTMLMediaElement::GetSupportsType(ContentType(type)))
- return MakeGarbageCollected<MediaDocument>(init);
-
- // Everything else except text/plain can be overridden by plugins. In
- // particular, Adobe SVG Viewer should be used for SVG, if installed.
- // Disallowing plugins to use text/plain prevents plugins from hijacking a
- // fundamental type that the browser is expected to handle, and also serves as
- // an optimization to prevent loading the plugin database in the common case.
- if (type != "text/plain" && plugin_data &&
- plugin_data->SupportsMimeType(type)) {
- return MakeGarbageCollected<PluginDocument>(
- init, plugin_data->PluginBackgroundColorForMimeType(type));
- }
- if (IsTextMIMEType(type))
- return MakeGarbageCollected<TextDocument>(init);
- if (type == "image/svg+xml")
- return XMLDocument::CreateSVG(init);
- if (IsXMLMIMEType(type))
- return MakeGarbageCollected<XMLDocument>(init);
-
- return MakeGarbageCollected<HTMLDocument>(init);
+ NOTREACHED();
+ return nullptr;
}
void DOMImplementation::Trace(Visitor* 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 25e6d63e950..72599ffa7ed 100644
--- a/chromium/third_party/blink/renderer/core/dom/dom_implementation.h
+++ b/chromium/third_party/blink/renderer/core/dom/dom_implementation.h
@@ -56,9 +56,7 @@ class CORE_EXPORT DOMImplementation final : public ScriptWrappable {
Document* createHTMLDocument(const String& title = String());
// Other methods (not part of DOM)
- static Document* createDocument(const String& mime_type,
- const DocumentInit&,
- bool in_view_source_mode);
+ static Document* createDocument(const DocumentInit&);
static bool IsXMLMIMEType(const String&);
static bool IsTextMIMEType(const String&);
diff --git a/chromium/third_party/blink/renderer/core/dom/dom_string_map.h b/chromium/third_party/blink/renderer/core/dom/dom_string_map.h
index 04d281dfa45..5ae98a1a827 100644
--- a/chromium/third_party/blink/renderer/core/dom/dom_string_map.h
+++ b/chromium/third_party/blink/renderer/core/dom/dom_string_map.h
@@ -47,15 +47,16 @@ class DOMStringMap : public ScriptWrappable {
const String& value,
ExceptionState&) = 0;
virtual bool DeleteItem(const String& name) = 0;
- bool AnonymousNamedSetter(const String& name,
- const String& value,
- ExceptionState& exception_state) {
+ NamedPropertySetterResult AnonymousNamedSetter(
+ const String& name,
+ const String& value,
+ ExceptionState& exception_state) {
SetItem(name, value, exception_state);
- return true;
+ return NamedPropertySetterResult::kIntercepted;
}
- DeleteResult AnonymousNamedDeleter(const AtomicString& name) {
- bool known_property = DeleteItem(name);
- return known_property ? kDeleteSuccess : kDeleteUnknownProperty;
+ NamedPropertyDeleterResult AnonymousNamedDeleter(const AtomicString& name) {
+ return DeleteItem(name) ? NamedPropertyDeleterResult::kDeleted
+ : NamedPropertyDeleterResult::kDidNotIntercept;
}
void NamedPropertyEnumerator(Vector<String>& names, ExceptionState&) {
GetNames(names);
diff --git a/chromium/third_party/blink/renderer/core/dom/element.cc b/chromium/third_party/blink/renderer/core/dom/element.cc
index a31d920c809..9801e9a3cf8 100644
--- a/chromium/third_party/blink/renderer/core/dom/element.cc
+++ b/chromium/third_party/blink/renderer/core/dom/element.cc
@@ -26,18 +26,22 @@
#include "third_party/blink/renderer/core/dom/element.h"
+#include <algorithm>
#include <bitset>
+#include <limits>
#include <memory>
+#include <utility>
#include "cc/input/snap_selection_strategy.h"
-#include "third_party/blink/public/platform/web_scroll_into_view_params.h"
+#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/scroll_into_view_options_or_boolean.h"
-#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_html.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_html_or_trusted_script_or_trusted_script_url.h"
-#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script.h"
-#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script_url.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_pointer_lock_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_scroll_into_view_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_scroll_to_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_shadow_root_init.h"
#include "third_party/blink/renderer/core/accessibility/ax_context.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
#include "third_party/blink/renderer/core/animation/css/css_animations.h"
@@ -76,12 +80,10 @@
#include "third_party/blink/renderer/core/dom/mutation_record.h"
#include "third_party/blink/renderer/core/dom/named_node_map.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
-#include "third_party/blink/renderer/core/dom/pointer_lock_options.h"
#include "third_party/blink/renderer/core/dom/presentation_attribute_style.h"
#include "third_party/blink/renderer/core/dom/pseudo_element.h"
#include "third_party/blink/renderer/core/dom/scriptable_document_parser.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
-#include "third_party/blink/renderer/core/dom/shadow_root_init.h"
#include "third_party/blink/renderer/core/dom/shadow_root_v0.h"
#include "third_party/blink/renderer/core/dom/slot_assignment.h"
#include "third_party/blink/renderer/core/dom/space_split_string.h"
@@ -100,8 +102,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/frame/local_frame_view.h"
-#include "third_party/blink/renderer/core/frame/scroll_into_view_options.h"
-#include "third_party/blink/renderer/core/frame/scroll_to_options.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/fullscreen/fullscreen.h"
@@ -174,7 +174,7 @@ namespace {
class DisplayLockStyleScope {
public:
- DisplayLockStyleScope(Element* element) : element_(element) {
+ explicit DisplayLockStyleScope(Element* element) : element_(element) {
// Note that we don't store context as a member of this scope, since it may
// get created as part of element self style recalc.
auto* context = element->GetDisplayLockContext();
@@ -232,7 +232,7 @@ bool IsRootEditableElementWithCounting(const Element& element) {
auto user_modify = style->UserModify();
const AtomicString& ce_value =
element.FastGetAttribute(html_names::kContenteditableAttr);
- if (ce_value.IsNull() || DeprecatedEqualIgnoringCase(ce_value, "false")) {
+ if (ce_value.IsNull() || EqualIgnoringASCIICase(ce_value, "false")) {
if (user_modify == EUserModify::kReadWritePlaintextOnly) {
UseCounter::Count(doc, WebFeature::kPlainTextEditingEffective);
UseCounter::Count(doc, WebFeature::kWebKitUserModifyPlainTextEffective);
@@ -241,8 +241,7 @@ bool IsRootEditableElementWithCounting(const Element& element) {
UseCounter::Count(doc, WebFeature::kWebKitUserModifyReadWriteEffective);
UseCounter::Count(doc, WebFeature::kWebKitUserModifyEffective);
}
- } else if (ce_value.IsEmpty() ||
- DeprecatedEqualIgnoringCase(ce_value, "true")) {
+ } else if (ce_value.IsEmpty() || EqualIgnoringASCIICase(ce_value, "true")) {
if (user_modify == EUserModify::kReadWritePlaintextOnly) {
UseCounter::Count(doc, WebFeature::kPlainTextEditingEffective);
UseCounter::Count(doc, WebFeature::kWebKitUserModifyPlainTextEffective);
@@ -251,7 +250,7 @@ bool IsRootEditableElementWithCounting(const Element& element) {
UseCounter::Count(doc, WebFeature::kWebKitUserModifyReadOnlyEffective);
UseCounter::Count(doc, WebFeature::kWebKitUserModifyEffective);
}
- } else if (DeprecatedEqualIgnoringCase(ce_value, "plaintext-only")) {
+ } else if (EqualIgnoringASCIICase(ce_value, "plaintext-only")) {
UseCounter::Count(doc, WebFeature::kPlainTextEditingEffective);
if (user_modify == EUserModify::kReadWrite) {
UseCounter::Count(doc, WebFeature::kWebKitUserModifyReadWriteEffective);
@@ -330,28 +329,33 @@ bool CalculateStyleShouldForceLegacyLayout(const Element& element,
return true;
}
- if (style.IsDeprecatedWebkitBox())
+ if (style.IsDeprecatedWebkitBox() &&
+ (!style.IsDeprecatedWebkitBoxWithVerticalLineClamp() ||
+ !RuntimeEnabledFeatures::BlockFlowHandlesWebkitLineClampEnabled())) {
return true;
+ }
if (!RuntimeEnabledFeatures::LayoutNGBlockFragmentationEnabled()) {
- // Disable NG for the entire subtree if we're establishing a block
- // fragmentation context.
+ // Disable NG for the entire subtree if we're establishing a multicol
+ // container.
if (style.SpecifiesColumns())
return true;
- if (document.Printing() && element == document.documentElement())
- return true;
-
- // Fall back to legacy layout for frameset documents. The frameset itself
- // (and the frames) can only create legacy layout objects anyway (no NG
- // counterpart for them yet). However, the layout object for the HTML root
- // element would be an NG one. If we'd then print the document, we'd fall
- // back to legacy layout (because of the above check), which would re-attach
- // all layout objects, which would cause the frameset to lose state of some
- // sort, leaving everything blank when printed.
- if (document.IsFrameSet())
- return true;
}
+ // No printing support in LayoutNG yet.
+ if (document.Printing() && element == document.documentElement())
+ return true;
+
+ // Fall back to legacy layout for frameset documents. The frameset itself (and
+ // the frames) can only create legacy layout objects anyway (no NG counterpart
+ // for them yet). However, the layout object for the HTML root element would
+ // be an NG one. If we'd then print the document, we'd fall back to legacy
+ // layout (because of the above check), which would re-attach all layout
+ // objects, which would cause the frameset to lose state of some sort, leaving
+ // everything blank when printed.
+ if (document.IsFrameSet())
+ return true;
+
// 'text-combine-upright' property is not supported yet.
if (style.HasTextCombine() && !style.IsHorizontalWritingMode())
return true;
@@ -411,6 +415,8 @@ bool IsElementReflectionAttribute(const QualifiedName& name) {
return true;
if (name == html_names::kAriaFlowtoAttr)
return true;
+ if (name == html_names::kAriaLabeledbyAttr)
+ return true;
if (name == html_names::kAriaLabelledbyAttr)
return true;
if (name == html_names::kAriaOwnsAttr)
@@ -420,7 +426,7 @@ bool IsElementReflectionAttribute(const QualifiedName& name) {
HeapVector<Member<Element>>* GetExplicitlySetElementsForAttr(
Element* element,
- QualifiedName name) {
+ const QualifiedName& name) {
ExplicitlySetAttrElementsMap* element_attribute_map =
element->GetDocument().GetExplicitlySetAttrElementsMap(element);
return element_attribute_map->at(name);
@@ -473,8 +479,8 @@ void EnqueueAutofocus(Element& element) {
// 4. If target's active sandboxing flag set has the sandboxed automatic
// features browsing context flag, then return.
- if (doc.IsSandboxed(WebSandboxFlags::kAutomaticFeatures)) {
- doc.AddConsoleMessage(ConsoleMessage::Create(
+ if (doc.IsSandboxed(mojom::blink::WebSandboxFlags::kAutomaticFeatures)) {
+ doc.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kSecurity,
mojom::ConsoleMessageLevel::kError,
"Blocked autofocusing on a form control because the form's frame is "
@@ -488,7 +494,7 @@ void EnqueueAutofocus(Element& element) {
// then return.
if (!doc.IsInMainFrame() &&
!doc.TopFrameOrigin()->CanAccess(doc.GetSecurityOrigin())) {
- doc.AddConsoleMessage(ConsoleMessage::Create(
+ doc.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kSecurity,
mojom::ConsoleMessageLevel::kError,
"Blocked autofocusing on a form control in a cross-origin subframe."));
@@ -576,8 +582,10 @@ bool Element::IsFocusableStyle() const {
// Update style if we're in a display-locked subtree, because it isn't
// included in the normal style updates. We also need to update the layout
// here because some callers expect the layout stays clean.
- if (DisplayLockUtilities::NearestLockedExclusiveAncestor(*this))
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ if (DisplayLockUtilities::NearestLockedExclusiveAncestor(*this)) {
+ GetDocument().UpdateStyleAndLayoutForNode(
+ this, DocumentUpdateReason::kDisplayLock);
+ }
if (IsInsideInvisibleSubtree()) {
const ComputedStyle* style =
@@ -669,6 +677,11 @@ void Element::SetBooleanAttribute(const QualifiedName& name, bool value) {
removeAttribute(name);
}
+bool Element::HasExplicitlySetAttrAssociatedElements(
+ const QualifiedName& name) {
+ return GetExplicitlySetElementsForAttr(this, name);
+}
+
void Element::SynchronizeContentAttributeAndElementReference(
const QualifiedName& name) {
ExplicitlySetAttrElementsMap* element_attribute_map =
@@ -716,6 +729,11 @@ void Element::SetElementAttribute(const QualifiedName& name, Element* element) {
result.stored_value->value->clear();
}
result.stored_value->value->push_back(element);
+
+ if (isConnected()) {
+ if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache())
+ cache->HandleAttributeChanged(name, this);
+ }
}
Element* Element::GetElementAttribute(const QualifiedName& name) {
@@ -740,12 +758,11 @@ Element* Element::GetElementAttribute(const QualifiedName& name) {
void Element::SetElementArrayAttribute(
const QualifiedName& name,
- HeapVector<Member<Element>> given_elements,
- bool is_null) {
+ const base::Optional<HeapVector<Member<Element>>>& given_elements) {
ExplicitlySetAttrElementsMap* element_attribute_map =
GetDocument().GetExplicitlySetAttrElementsMap(this);
- if (is_null) {
+ if (!given_elements) {
element_attribute_map->erase(name);
removeAttribute(name);
return;
@@ -762,7 +779,7 @@ void Element::SetElementArrayAttribute(
elements->clear();
SpaceSplitString value;
- for (auto element : given_elements) {
+ for (auto element : given_elements.value()) {
// Elements that are not descendants of this element's shadow including
// ancestors are dropped.
if (!ElementIsDescendantOfShadowIncludingAncestor(*this, *element))
@@ -796,20 +813,43 @@ void Element::SetElementArrayAttribute(
}
setAttribute(name, value.SerializeToString());
+ if (isConnected()) {
+ if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache())
+ cache->HandleAttributeChanged(name, this);
+ }
element_attribute_map->Set(name, elements);
}
-HeapVector<Member<Element>> Element::GetElementArrayAttribute(
+void Element::SetElementArrayAttribute(
const QualifiedName& name,
- bool& is_null) {
+ HeapVector<Member<Element>> given_elements,
+ bool is_null) {
+ if (is_null)
+ SetElementArrayAttribute(name, base::nullopt);
+ else
+ SetElementArrayAttribute(name, std::move(given_elements));
+}
+
+base::Optional<HeapVector<Member<Element>>> Element::GetElementArrayAttribute(
+ const QualifiedName& name) {
HeapVector<Member<Element>>* explicitly_set_elements =
GetExplicitlySetElementsForAttr(this, name);
- is_null = false;
+
if (explicitly_set_elements) {
return *explicitly_set_elements;
}
- String attribute_value = getAttribute(name).GetString();
+ QualifiedName attr = name;
+
+ // Account for labelled vs labeled spelling
+ if (attr == html_names::kAriaLabelledbyAttr) {
+ attr = hasAttribute(html_names::kAriaLabeledbyAttr) &&
+ !hasAttribute(html_names::kAriaLabelledbyAttr)
+ ? html_names::kAriaLabeledbyAttr
+ : html_names::kAriaLabelledbyAttr;
+ }
+
+ String attribute_value = getAttribute(attr).GetString();
HeapVector<Member<Element>> content_elements;
Vector<String> tokens;
@@ -822,10 +862,18 @@ HeapVector<Member<Element>> Element::GetElementArrayAttribute(
content_elements.push_back(candidate);
}
if (content_elements.IsEmpty())
- is_null = true;
+ return base::nullopt;
return content_elements;
}
+HeapVector<Member<Element>> Element::GetElementArrayAttribute(
+ const QualifiedName& name,
+ bool& is_null) {
+ const auto& result = GetElementArrayAttribute(name);
+ is_null = !result.has_value();
+ return result.value_or(HeapVector<Member<Element>>());
+}
+
NamedNodeMap* Element::attributesForBindings() const {
ElementRareData& rare_data =
const_cast<Element*>(this)->EnsureElementRareData();
@@ -898,11 +946,11 @@ void Element::SynchronizeAllAttributes() const {
// NOTE: AnyAttributeMatches in selector_checker.cc currently assumes that all
// lazy attributes have a null namespace. If that ever changes we'll need to
// fix that code.
- if (GetElementData()->style_attribute_is_dirty_) {
+ if (GetElementData()->style_attribute_is_dirty()) {
DCHECK(IsStyledElement());
SynchronizeStyleAttributeInternal();
}
- if (GetElementData()->animated_svg_attributes_are_dirty_)
+ if (GetElementData()->animated_svg_attributes_are_dirty())
To<SVGElement>(this)->SynchronizeAnimatedSVGAttribute(AnyQName());
}
@@ -910,12 +958,12 @@ inline void Element::SynchronizeAttribute(const QualifiedName& name) const {
if (!GetElementData())
return;
if (UNLIKELY(name == html_names::kStyleAttr &&
- GetElementData()->style_attribute_is_dirty_)) {
+ GetElementData()->style_attribute_is_dirty())) {
DCHECK(IsStyledElement());
SynchronizeStyleAttributeInternal();
return;
}
- if (UNLIKELY(GetElementData()->animated_svg_attributes_are_dirty_)) {
+ if (UNLIKELY(GetElementData()->animated_svg_attributes_are_dirty())) {
// See comment in the AtomicString version of SynchronizeAttribute()
// also.
To<SVGElement>(this)->SynchronizeAnimatedSVGAttribute(name);
@@ -927,13 +975,13 @@ void Element::SynchronizeAttribute(const AtomicString& local_name) const {
// you don't have a full QualifiedName, e.g when called from DOM API.
if (!GetElementData())
return;
- if (GetElementData()->style_attribute_is_dirty_ &&
+ if (GetElementData()->style_attribute_is_dirty() &&
LowercaseIfNecessary(local_name) == html_names::kStyleAttr.LocalName()) {
DCHECK(IsStyledElement());
SynchronizeStyleAttributeInternal();
return;
}
- if (GetElementData()->animated_svg_attributes_are_dirty_) {
+ if (GetElementData()->animated_svg_attributes_are_dirty()) {
// We're not passing a namespace argument on purpose. SVGNames::*Attr are
// defined w/o namespaces as well.
@@ -961,8 +1009,8 @@ const AtomicString& Element::getAttribute(const QualifiedName& name) const {
}
AtomicString Element::LowercaseIfNecessary(const AtomicString& name) const {
- return IsHTMLElement() && GetDocument().IsHTMLDocument() ? name.LowerASCII()
- : name;
+ return IsHTMLElement() && IsA<HTMLDocument>(GetDocument()) ? name.LowerASCII()
+ : name;
}
const AtomicString& Element::nonce() const {
@@ -993,10 +1041,11 @@ void Element::scrollIntoView(bool align_to_top) {
scrollIntoView(arg);
}
-static ScrollAlignment ToPhysicalAlignment(const ScrollIntoViewOptions* options,
- ScrollOrientation axis,
- WritingMode writing_mode,
- bool is_ltr) {
+static mojom::blink::ScrollAlignment ToPhysicalAlignment(
+ const ScrollIntoViewOptions* options,
+ ScrollOrientation axis,
+ WritingMode writing_mode,
+ bool is_ltr) {
bool is_horizontal_writing_mode = IsHorizontalWritingMode(writing_mode);
String alignment =
((axis == kHorizontalScroll && is_horizontal_writing_mode) ||
@@ -1005,40 +1054,40 @@ static ScrollAlignment ToPhysicalAlignment(const ScrollIntoViewOptions* options,
: options->block();
if (alignment == "center")
- return ScrollAlignment::kAlignCenterAlways;
+ return ScrollAlignment::CenterAlways();
if (alignment == "nearest")
- return ScrollAlignment::kAlignToEdgeIfNeeded;
+ return ScrollAlignment::ToEdgeIfNeeded();
if (alignment == "start") {
if (axis == kHorizontalScroll) {
switch (writing_mode) {
case WritingMode::kHorizontalTb:
- return is_ltr ? ScrollAlignment::kAlignLeftAlways
- : ScrollAlignment::kAlignRightAlways;
+ return is_ltr ? ScrollAlignment::LeftAlways()
+ : ScrollAlignment::RightAlways();
case WritingMode::kVerticalRl:
case WritingMode::kSidewaysRl:
- return ScrollAlignment::kAlignRightAlways;
+ return ScrollAlignment::RightAlways();
case WritingMode::kVerticalLr:
case WritingMode::kSidewaysLr:
- return ScrollAlignment::kAlignLeftAlways;
+ return ScrollAlignment::LeftAlways();
default:
NOTREACHED();
- return ScrollAlignment::kAlignLeftAlways;
+ return ScrollAlignment::LeftAlways();
}
} else {
switch (writing_mode) {
case WritingMode::kHorizontalTb:
- return ScrollAlignment::kAlignTopAlways;
+ return ScrollAlignment::TopAlways();
case WritingMode::kVerticalRl:
case WritingMode::kSidewaysRl:
case WritingMode::kVerticalLr:
- return is_ltr ? ScrollAlignment::kAlignTopAlways
- : ScrollAlignment::kAlignBottomAlways;
+ return is_ltr ? ScrollAlignment::TopAlways()
+ : ScrollAlignment::BottomAlways();
case WritingMode::kSidewaysLr:
- return is_ltr ? ScrollAlignment::kAlignBottomAlways
- : ScrollAlignment::kAlignTopAlways;
+ return is_ltr ? ScrollAlignment::BottomAlways()
+ : ScrollAlignment::TopAlways();
default:
NOTREACHED();
- return ScrollAlignment::kAlignTopAlways;
+ return ScrollAlignment::TopAlways();
}
}
}
@@ -1046,49 +1095,50 @@ static ScrollAlignment ToPhysicalAlignment(const ScrollIntoViewOptions* options,
if (axis == kHorizontalScroll) {
switch (writing_mode) {
case WritingMode::kHorizontalTb:
- return is_ltr ? ScrollAlignment::kAlignRightAlways
- : ScrollAlignment::kAlignLeftAlways;
+ return is_ltr ? ScrollAlignment::RightAlways()
+ : ScrollAlignment::LeftAlways();
case WritingMode::kVerticalRl:
case WritingMode::kSidewaysRl:
- return ScrollAlignment::kAlignLeftAlways;
+ return ScrollAlignment::LeftAlways();
case WritingMode::kVerticalLr:
case WritingMode::kSidewaysLr:
- return ScrollAlignment::kAlignRightAlways;
+ return ScrollAlignment::RightAlways();
default:
NOTREACHED();
- return ScrollAlignment::kAlignRightAlways;
+ return ScrollAlignment::RightAlways();
}
} else {
switch (writing_mode) {
case WritingMode::kHorizontalTb:
- return ScrollAlignment::kAlignBottomAlways;
+ return ScrollAlignment::BottomAlways();
case WritingMode::kVerticalRl:
case WritingMode::kSidewaysRl:
case WritingMode::kVerticalLr:
- return is_ltr ? ScrollAlignment::kAlignBottomAlways
- : ScrollAlignment::kAlignTopAlways;
+ return is_ltr ? ScrollAlignment::BottomAlways()
+ : ScrollAlignment::TopAlways();
case WritingMode::kSidewaysLr:
- return is_ltr ? ScrollAlignment::kAlignTopAlways
- : ScrollAlignment::kAlignBottomAlways;
+ return is_ltr ? ScrollAlignment::TopAlways()
+ : ScrollAlignment::BottomAlways();
default:
NOTREACHED();
- return ScrollAlignment::kAlignBottomAlways;
+ return ScrollAlignment::BottomAlways();
}
}
}
// Default values
if (is_horizontal_writing_mode) {
- return (axis == kHorizontalScroll) ? ScrollAlignment::kAlignToEdgeIfNeeded
- : ScrollAlignment::kAlignTopAlways;
+ return (axis == kHorizontalScroll) ? ScrollAlignment::ToEdgeIfNeeded()
+ : ScrollAlignment::TopAlways();
}
- return (axis == kHorizontalScroll) ? ScrollAlignment::kAlignLeftAlways
- : ScrollAlignment::kAlignToEdgeIfNeeded;
+ return (axis == kHorizontalScroll) ? ScrollAlignment::LeftAlways()
+ : ScrollAlignment::ToEdgeIfNeeded();
}
void Element::scrollIntoViewWithOptions(const ScrollIntoViewOptions* options) {
ActivateDisplayLockIfNeeded(DisplayLockActivationReason::kScrollIntoView);
- GetDocument().EnsurePaintLocationDataValidForNode(this);
+ GetDocument().EnsurePaintLocationDataValidForNode(
+ this, DocumentUpdateReason::kJavaScript);
ScrollIntoViewNoVisualUpdate(options);
}
@@ -1097,31 +1147,29 @@ void Element::ScrollIntoViewNoVisualUpdate(
if (!GetLayoutObject() || !GetDocument().GetPage())
return;
- if (DisplayLockPreventsActivation(
- DisplayLockActivationReason::kScrollIntoView))
- return;
-
- ScrollBehavior behavior = (options->behavior() == "smooth")
- ? kScrollBehaviorSmooth
- : kScrollBehaviorAuto;
+ mojom::blink::ScrollBehavior behavior =
+ (options->behavior() == "smooth") ? mojom::blink::ScrollBehavior::kSmooth
+ : mojom::blink::ScrollBehavior::kAuto;
WritingMode writing_mode = GetComputedStyle()->GetWritingMode();
bool is_ltr = GetComputedStyle()->IsLeftToRightDirection();
- ScrollAlignment align_x =
+ auto align_x =
ToPhysicalAlignment(options, kHorizontalScroll, writing_mode, is_ltr);
- ScrollAlignment align_y =
+ auto align_y =
ToPhysicalAlignment(options, kVerticalScroll, writing_mode, is_ltr);
PhysicalRect bounds = BoundingBoxForScrollIntoView();
GetLayoutObject()->ScrollRectToVisible(
- bounds, {align_x, align_y, kProgrammaticScroll,
- /*make_visible_in_visual_viewport=*/true, behavior});
+ bounds, ScrollAlignment::CreateScrollIntoViewParams(
+ align_x, align_y, mojom::blink::ScrollType::kProgrammatic,
+ /*make_visible_in_visual_viewport=*/true, behavior));
GetDocument().SetSequentialFocusNavigationStartingPoint(this);
}
void Element::scrollIntoViewIfNeeded(bool center_if_needed) {
- GetDocument().EnsurePaintLocationDataValidForNode(this);
+ GetDocument().EnsurePaintLocationDataValidForNode(
+ this, DocumentUpdateReason::kJavaScript);
if (!GetLayoutObject())
return;
@@ -1129,17 +1177,20 @@ void Element::scrollIntoViewIfNeeded(bool center_if_needed) {
PhysicalRect bounds = BoundingBoxForScrollIntoView();
if (center_if_needed) {
GetLayoutObject()->ScrollRectToVisible(
- bounds, {ScrollAlignment::kAlignCenterIfNeeded,
- ScrollAlignment::kAlignCenterIfNeeded});
+ bounds, ScrollAlignment::CreateScrollIntoViewParams(
+ ScrollAlignment::CenterIfNeeded(),
+ ScrollAlignment::CenterIfNeeded()));
} else {
GetLayoutObject()->ScrollRectToVisible(
- bounds, {ScrollAlignment::kAlignToEdgeIfNeeded,
- ScrollAlignment::kAlignToEdgeIfNeeded});
+ bounds, ScrollAlignment::CreateScrollIntoViewParams(
+ ScrollAlignment::ToEdgeIfNeeded(),
+ ScrollAlignment::ToEdgeIfNeeded()));
}
}
int Element::OffsetLeft() {
- GetDocument().EnsurePaintLocationDataValidForNode(this);
+ GetDocument().EnsurePaintLocationDataValidForNode(
+ this, DocumentUpdateReason::kJavaScript);
if (LayoutBoxModelObject* layout_object = GetLayoutBoxModelObject())
return AdjustForAbsoluteZoom::AdjustLayoutUnit(
LayoutUnit(
@@ -1150,7 +1201,8 @@ int Element::OffsetLeft() {
}
int Element::OffsetTop() {
- GetDocument().EnsurePaintLocationDataValidForNode(this);
+ GetDocument().EnsurePaintLocationDataValidForNode(
+ this, DocumentUpdateReason::kJavaScript);
if (LayoutBoxModelObject* layout_object = GetLayoutBoxModelObject())
return AdjustForAbsoluteZoom::AdjustLayoutUnit(
LayoutUnit(layout_object->PixelSnappedOffsetTop(OffsetParent())),
@@ -1160,7 +1212,8 @@ int Element::OffsetTop() {
}
int Element::OffsetWidth() {
- GetDocument().EnsurePaintLocationDataValidForNode(this);
+ GetDocument().EnsurePaintLocationDataValidForNode(
+ this, DocumentUpdateReason::kJavaScript);
if (LayoutBoxModelObject* layout_object = GetLayoutBoxModelObject())
return AdjustForAbsoluteZoom::AdjustLayoutUnit(
LayoutUnit(
@@ -1171,7 +1224,8 @@ int Element::OffsetWidth() {
}
int Element::OffsetHeight() {
- GetDocument().EnsurePaintLocationDataValidForNode(this);
+ GetDocument().EnsurePaintLocationDataValidForNode(
+ this, DocumentUpdateReason::kJavaScript);
if (LayoutBoxModelObject* layout_object = GetLayoutBoxModelObject())
return AdjustForAbsoluteZoom::AdjustLayoutUnit(
LayoutUnit(
@@ -1182,14 +1236,16 @@ int Element::OffsetHeight() {
}
Element* Element::OffsetParent() {
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
LayoutObject* layout_object = GetLayoutObject();
return layout_object ? layout_object->OffsetParent() : nullptr;
}
int Element::clientLeft() {
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
if (LayoutBox* layout_object = GetLayoutBox())
return AdjustForAbsoluteZoom::AdjustLayoutUnit(layout_object->ClientLeft(),
@@ -1199,7 +1255,8 @@ int Element::clientLeft() {
}
int Element::clientTop() {
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
if (LayoutBox* layout_object = GetLayoutBox())
return AdjustForAbsoluteZoom::AdjustLayoutUnit(layout_object->ClientTop(),
@@ -1220,8 +1277,10 @@ int Element::clientWidth() {
if (layout_view) {
// TODO(crbug.com/740879): Use per-page overlay scrollbar settings.
if (!ScrollbarThemeSettings::OverlayScrollbarsEnabled() ||
- !GetDocument().GetFrame()->IsLocalRoot())
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ !GetDocument().GetFrame()->IsLocalRoot()) {
+ GetDocument().UpdateStyleAndLayoutForNode(
+ this, DocumentUpdateReason::kJavaScript);
+ }
if (GetDocument().GetPage()->GetSettings().GetForceZeroLayoutHeight())
return AdjustForAbsoluteZoom::AdjustLayoutUnit(
layout_view->OverflowClipRect(PhysicalOffset()).Width(),
@@ -1234,7 +1293,8 @@ int Element::clientWidth() {
}
}
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
if (LayoutBox* layout_object = GetLayoutBox())
return AdjustForAbsoluteZoom::AdjustLayoutUnit(
@@ -1259,8 +1319,10 @@ int Element::clientHeight() {
if (layout_view) {
// TODO(crbug.com/740879): Use per-page overlay scrollbar settings.
if (!ScrollbarThemeSettings::OverlayScrollbarsEnabled() ||
- !GetDocument().GetFrame()->IsLocalRoot())
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ !GetDocument().GetFrame()->IsLocalRoot()) {
+ GetDocument().UpdateStyleAndLayoutForNode(
+ this, DocumentUpdateReason::kJavaScript);
+ }
if (GetDocument().GetPage()->GetSettings().GetForceZeroLayoutHeight())
return AdjustForAbsoluteZoom::AdjustLayoutUnit(
layout_view->OverflowClipRect(PhysicalOffset()).Height(),
@@ -1273,7 +1335,8 @@ int Element::clientHeight() {
}
}
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
if (LayoutBox* layout_object = GetLayoutBox())
return AdjustForAbsoluteZoom::AdjustLayoutUnit(
@@ -1296,7 +1359,8 @@ double Element::scrollLeft() {
if (!InActiveDocument())
return 0;
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
if (GetDocument().ScrollingElementNoLayout() == this) {
if (GetDocument().domWindow())
@@ -1333,7 +1397,8 @@ double Element::scrollTop() {
if (!InActiveDocument())
return 0;
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
if (GetDocument().ScrollingElementNoLayout() == this) {
if (GetDocument().domWindow())
@@ -1370,7 +1435,8 @@ void Element::setScrollLeft(double new_left) {
if (!InActiveDocument())
return;
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
new_left = ScrollableArea::NormalizeNonFiniteScroll(new_left);
@@ -1411,8 +1477,9 @@ void Element::setScrollLeft(double new_left) {
end_offset =
scrollable_area->ScrollPositionToOffset(snap_point.value());
}
- scrollable_area->SetScrollOffset(end_offset, kProgrammaticScroll,
- kScrollBehaviorAuto);
+ scrollable_area->SetScrollOffset(end_offset,
+ mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kAuto);
} else {
FloatPoint end_point(new_left * box->Style()->EffectiveZoom(),
scrollable_area->ScrollPosition().Y());
@@ -1425,8 +1492,8 @@ void Element::setScrollLeft(double new_left) {
FloatPoint new_position(end_point.X(),
scrollable_area->ScrollPosition().Y());
- scrollable_area->ScrollToAbsolutePosition(new_position,
- kScrollBehaviorAuto);
+ scrollable_area->ScrollToAbsolutePosition(
+ new_position, mojom::blink::ScrollBehavior::kAuto);
}
}
}
@@ -1435,7 +1502,8 @@ void Element::setScrollTop(double new_top) {
if (!InActiveDocument())
return;
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
new_top = ScrollableArea::NormalizeNonFiniteScroll(new_top);
@@ -1477,8 +1545,9 @@ void Element::setScrollTop(double new_top) {
scrollable_area->ScrollPositionToOffset(snap_point.value());
}
- scrollable_area->SetScrollOffset(end_offset, kProgrammaticScroll,
- kScrollBehaviorAuto);
+ scrollable_area->SetScrollOffset(end_offset,
+ mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kAuto);
} else {
FloatPoint end_point(scrollable_area->ScrollPosition().X(),
new_top * box->Style()->EffectiveZoom());
@@ -1490,8 +1559,8 @@ void Element::setScrollTop(double new_top) {
end_point);
FloatPoint new_position(scrollable_area->ScrollPosition().X(),
end_point.Y());
- scrollable_area->ScrollToAbsolutePosition(new_position,
- kScrollBehaviorAuto);
+ scrollable_area->ScrollToAbsolutePosition(
+ new_position, mojom::blink::ScrollBehavior::kAuto);
}
}
}
@@ -1500,7 +1569,8 @@ int Element::scrollWidth() {
if (!InActiveDocument())
return 0;
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
if (GetDocument().ScrollingElementNoLayout() == this) {
if (GetDocument().View()) {
@@ -1522,7 +1592,8 @@ int Element::scrollHeight() {
if (!InActiveDocument())
return 0;
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
if (GetDocument().ScrollingElementNoLayout() == this) {
if (GetDocument().View()) {
@@ -1553,7 +1624,8 @@ void Element::scrollBy(const ScrollToOptions* scroll_to_options) {
// FIXME: This should be removed once scroll updates are processed only after
// the compositing update. See http://crbug.com/420741.
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
if (GetDocument().ScrollingElementNoLayout() == this) {
ScrollFrameBy(scroll_to_options);
@@ -1575,7 +1647,8 @@ void Element::scrollTo(const ScrollToOptions* scroll_to_options) {
// FIXME: This should be removed once scroll updates are processed only after
// the compositing update. See http://crbug.com/420741.
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
if (GetDocument().ScrollingElementNoLayout() == this) {
ScrollFrameTo(scroll_to_options);
@@ -1595,7 +1668,8 @@ void Element::ScrollLayoutBoxBy(const ScrollToOptions* scroll_to_options) {
ScrollableArea::NormalizeNonFiniteScroll(scroll_to_options->top()));
}
- ScrollBehavior scroll_behavior = kScrollBehaviorAuto;
+ mojom::blink::ScrollBehavior scroll_behavior =
+ mojom::blink::ScrollBehavior::kAuto;
ScrollableArea::ScrollBehaviorFromString(scroll_to_options->behavior(),
scroll_behavior);
if (PaintLayerScrollableArea* scrollable_area = GetScrollableArea()) {
@@ -1608,8 +1682,9 @@ void Element::ScrollLayoutBoxBy(const ScrollToOptions* scroll_to_options) {
FloatPoint new_position(new_offset.x(), new_offset.y());
std::unique_ptr<cc::SnapSelectionStrategy> strategy =
- cc::SnapSelectionStrategy::CreateForEndAndDirection(current_position,
- displacement);
+ cc::SnapSelectionStrategy::CreateForEndAndDirection(
+ current_position, displacement,
+ RuntimeEnabledFeatures::FractionalScrollOffsetsEnabled());
new_position =
scrollable_area->GetSnapPositionAndSetTarget(*strategy).value_or(
new_position);
@@ -1618,7 +1693,8 @@ void Element::ScrollLayoutBoxBy(const ScrollToOptions* scroll_to_options) {
}
void Element::ScrollLayoutBoxTo(const ScrollToOptions* scroll_to_options) {
- ScrollBehavior scroll_behavior = kScrollBehaviorAuto;
+ mojom::blink::ScrollBehavior scroll_behavior =
+ mojom::blink::ScrollBehavior::kAuto;
ScrollableArea::ScrollBehaviorFromString(scroll_to_options->behavior(),
scroll_behavior);
@@ -1679,8 +1755,8 @@ void Element::ScrollLayoutBoxTo(const ScrollToOptions* scroll_to_options) {
scrollable_area->ScrollPositionToOffset(snap_point.value());
}
- scrollable_area->SetScrollOffset(new_offset, kProgrammaticScroll,
- scroll_behavior);
+ scrollable_area->SetScrollOffset(
+ new_offset, mojom::blink::ScrollType::kProgrammatic, scroll_behavior);
} else {
FloatPoint new_position(scrollable_area->ScrollPosition().X(),
scrollable_area->ScrollPosition().Y());
@@ -1718,7 +1794,8 @@ void Element::ScrollFrameBy(const ScrollToOptions* scroll_to_options) {
ScrollableArea::NormalizeNonFiniteScroll(scroll_to_options->top()));
}
- ScrollBehavior scroll_behavior = kScrollBehaviorAuto;
+ mojom::blink::ScrollBehavior scroll_behavior =
+ mojom::blink::ScrollBehavior::kAuto;
ScrollableArea::ScrollBehaviorFromString(scroll_to_options->behavior(),
scroll_behavior);
LocalFrame* frame = GetDocument().GetFrame();
@@ -1735,16 +1812,19 @@ void Element::ScrollFrameBy(const ScrollToOptions* scroll_to_options) {
gfx::ScrollOffset current_position(viewport->ScrollPosition());
std::unique_ptr<cc::SnapSelectionStrategy> strategy =
- cc::SnapSelectionStrategy::CreateForEndAndDirection(current_position,
- displacement);
+ cc::SnapSelectionStrategy::CreateForEndAndDirection(
+ current_position, displacement,
+ RuntimeEnabledFeatures::FractionalScrollOffsetsEnabled());
new_position =
viewport->GetSnapPositionAndSetTarget(*strategy).value_or(new_position);
viewport->SetScrollOffset(viewport->ScrollPositionToOffset(new_position),
- kProgrammaticScroll, scroll_behavior);
+ mojom::blink::ScrollType::kProgrammatic,
+ scroll_behavior);
}
void Element::ScrollFrameTo(const ScrollToOptions* scroll_to_options) {
- ScrollBehavior scroll_behavior = kScrollBehaviorAuto;
+ mojom::blink::ScrollBehavior scroll_behavior =
+ mojom::blink::ScrollBehavior::kAuto;
ScrollableArea::ScrollBehaviorFromString(scroll_to_options->behavior(),
scroll_behavior);
LocalFrame* frame = GetDocument().GetFrame();
@@ -1775,11 +1855,13 @@ void Element::ScrollFrameTo(const ScrollToOptions* scroll_to_options) {
new_position =
viewport->GetSnapPositionAndSetTarget(*strategy).value_or(new_position);
new_offset = viewport->ScrollPositionToOffset(new_position);
- viewport->SetScrollOffset(new_offset, kProgrammaticScroll, scroll_behavior);
+ viewport->SetScrollOffset(new_offset, mojom::blink::ScrollType::kProgrammatic,
+ scroll_behavior);
}
IntRect Element::BoundsInViewport() const {
- GetDocument().EnsurePaintLocationDataValidForNode(this);
+ GetDocument().EnsurePaintLocationDataValidForNode(
+ this, DocumentUpdateReason::kUnknown);
LocalFrameView* view = GetDocument().View();
if (!view)
@@ -1798,7 +1880,7 @@ IntRect Element::BoundsInViewport() const {
!GetLayoutObject()->IsSVGForeignObject()) {
// Get the bounding rectangle from the SVG model.
// TODO(pdr): This should include stroke.
- if (svg_element->IsSVGGraphicsElement()) {
+ if (IsA<SVGGraphicsElement>(svg_element)) {
quads.push_back(GetLayoutObject()->LocalToAbsoluteQuad(
GetLayoutObject()->ObjectBoundingBox()));
}
@@ -1843,8 +1925,8 @@ IntRect Element::VisibleBoundsInVisualViewport() const {
// expect the result to be in the coordinate system of the local root frame.
// Either the method should be renamed to something which communicates that,
// or callers should be updated to expect actual top-level frame coordinates.
- rect.Move(-PhysicalOffset(
- GetDocument().GetFrame()->LocalFrameRoot().RemoteViewportOffset()));
+ rect.Move(-PhysicalOffset(IntPoint(
+ GetDocument().GetFrame()->LocalFrameRoot().RemoteViewportOffset())));
IntRect visible_rect = PixelSnappedIntRect(rect);
// If the rect is in the coordinates of the main frame, then it should
@@ -1862,7 +1944,8 @@ IntRect Element::VisibleBoundsInVisualViewport() const {
}
void Element::ClientQuads(Vector<FloatQuad>& quads) {
- GetDocument().EnsurePaintLocationDataValidForNode(this);
+ GetDocument().EnsurePaintLocationDataValidForNode(
+ this, DocumentUpdateReason::kJavaScript);
LayoutObject* element_layout_object = GetLayoutObject();
if (!element_layout_object)
@@ -1879,7 +1962,7 @@ void Element::ClientQuads(Vector<FloatQuad>& quads) {
// TODO(pdr): ObjectBoundingBox does not include stroke and the spec is not
// clear (see: https://github.com/w3c/svgwg/issues/339, crbug.com/529734).
// If stroke is desired, we can update this to use AbsoluteQuads, below.
- if (svg_element->IsSVGGraphicsElement()) {
+ if (IsA<SVGGraphicsElement>(svg_element)) {
quads.push_back(element_layout_object->LocalToAbsoluteQuad(
element_layout_object->ObjectBoundingBox()));
}
@@ -1896,13 +1979,13 @@ DOMRectList* Element::getClientRects() {
Vector<FloatQuad> quads;
ClientQuads(quads);
if (quads.IsEmpty())
- return DOMRectList::Create();
+ return MakeGarbageCollected<DOMRectList>();
LayoutObject* element_layout_object = GetLayoutObject();
DCHECK(element_layout_object);
GetDocument().AdjustFloatQuadsForScrollAndAbsoluteZoom(
quads, *element_layout_object);
- return DOMRectList::Create(quads);
+ return MakeGarbageCollected<DOMRectList>(quads);
}
DOMRect* Element::getBoundingClientRect() {
@@ -1926,7 +2009,7 @@ const AtomicString& Element::computedRole() {
Document& document = GetDocument();
if (!document.IsActive())
return g_null_atom;
- document.UpdateStyleAndLayoutForNode(this);
+ document.UpdateStyleAndLayoutForNode(this, DocumentUpdateReason::kJavaScript);
UpdateDistributionForFlatTreeTraversal();
AXContext ax_context(document);
return ax_context.GetAXObjectCache().ComputedRoleForNode(this);
@@ -1936,7 +2019,7 @@ String Element::computedName() {
Document& document = GetDocument();
if (!document.IsActive())
return String();
- document.UpdateStyleAndLayoutForNode(this);
+ document.UpdateStyleAndLayoutForNode(this, DocumentUpdateReason::kJavaScript);
UpdateDistributionForFlatTreeTraversal();
AXContext ax_context(document);
return ax_context.GetAXObjectCache().ComputedNameForNode(this);
@@ -2175,9 +2258,9 @@ void Element::setAttribute(const AtomicString& local_name,
QualifiedName q_name = QualifiedName::Null();
std::tie(index, q_name) = LookupAttributeQNameInternal(local_name);
- String trusted_value = GetStringFromSpecificTrustedType(
- value, ExpectedTrustedTypeForAttribute(q_name), &GetDocument(),
- exception_state);
+ String trusted_value =
+ TrustedTypesCheckFor(ExpectedTrustedTypeForAttribute(q_name), value,
+ GetExecutionContext(), exception_state);
if (exception_state.HadException())
return;
@@ -2185,11 +2268,6 @@ void Element::setAttribute(const AtomicString& local_name,
kNotInSynchronizationOfLazyAttribute);
}
-void Element::setAttribute(const AtomicString& name,
- const AtomicString& value) {
- setAttribute(name, value, ASSERT_NO_EXCEPTION);
-}
-
void Element::setAttribute(const QualifiedName& name,
const AtomicString& value) {
SynchronizeAttribute(name);
@@ -2208,9 +2286,9 @@ void Element::setAttribute(const QualifiedName& name,
? GetElementData()->Attributes().FindIndex(name)
: kNotFound;
- String trusted_value = GetStringFromSpecificTrustedType(
- value, ExpectedTrustedTypeForAttribute(name), &GetDocument(),
- exception_state);
+ String trusted_value =
+ TrustedTypesCheckFor(ExpectedTrustedTypeForAttribute(name), value,
+ GetExecutionContext(), exception_state);
if (exception_state.HadException())
return;
@@ -2228,7 +2306,8 @@ void Element::SetSynchronizedLazyAttribute(const QualifiedName& name,
void Element::setAttribute(
const AtomicString& local_name,
- const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL& string_or_TT,
+ const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&
+ string_or_trusted,
ExceptionState& exception_state) {
if (!Document::IsValidName(local_name)) {
exception_state.ThrowDOMException(
@@ -2241,9 +2320,9 @@ void Element::setAttribute(
wtf_size_t index;
QualifiedName q_name = QualifiedName::Null();
std::tie(index, q_name) = LookupAttributeQNameInternal(local_name);
- String value = GetStringFromSpecificTrustedType(
- string_or_TT, ExpectedTrustedTypeForAttribute(q_name), &GetDocument(),
- exception_state);
+ String value = TrustedTypesCheckFor(ExpectedTrustedTypeForAttribute(q_name),
+ string_or_trusted, GetExecutionContext(),
+ exception_state);
if (exception_state.HadException())
return;
SetAttributeInternal(index, q_name, AtomicString(value),
@@ -2278,40 +2357,17 @@ SpecificTrustedType Element::ExpectedTrustedTypeForAttribute(
// starting with "on", including e.g. "one". We use this pattern elsewhere
// (e.g. in IsEventHandlerAttribute) but it's not ideal. Consider using
// the event attribute of the resulting AttributeTriggers.
- return SpecificTrustedType::kTrustedScript;
+ return SpecificTrustedType::kScript;
}
return SpecificTrustedType::kNone;
}
void Element::setAttribute(const QualifiedName& name,
- const StringOrTrustedHTML& stringOrHTML,
- ExceptionState& exception_state) {
- String valueString =
- GetStringFromTrustedHTML(stringOrHTML, &GetDocument(), exception_state);
- if (!exception_state.HadException()) {
- setAttribute(name, AtomicString(valueString));
- }
-}
-
-void Element::setAttribute(const QualifiedName& name,
- const StringOrTrustedScript& stringOrScript,
- ExceptionState& exception_state) {
- String valueString = GetStringFromTrustedScript(
- stringOrScript, &GetDocument(), exception_state);
- if (!exception_state.HadException()) {
- setAttribute(name, AtomicString(valueString));
- }
-}
-
-void Element::setAttribute(const QualifiedName& name,
- const StringOrTrustedScriptURL& stringOrURL,
+ const String& string,
ExceptionState& exception_state) {
- String valueString = GetStringFromTrustedScriptURL(
- stringOrURL, &GetDocument(), exception_state);
- if (!exception_state.HadException()) {
- setAttribute(name, AtomicString(valueString));
- }
+ // TODO(lyf): Removes |exception_state| because this function never throws.
+ setAttribute(name, AtomicString(string));
}
ALWAYS_INLINE void Element::SetAttributeInternal(
@@ -2399,44 +2455,9 @@ void Element::AttributeChanged(const AttributeModificationParams& params) {
if (name == html_names::kStyleAttr) {
StyleAttributeChanged(params.new_value, params.reason);
} else if (IsPresentationAttribute(name)) {
- GetElementData()->presentation_attribute_style_is_dirty_ = true;
+ GetElementData()->SetPresentationAttributeStyleIsDirty(true);
SetNeedsStyleRecalc(kLocalStyleChange,
StyleChangeReasonForTracing::FromAttribute(name));
- } else if (RuntimeEnabledFeatures::DisplayLockingEnabled(
- GetExecutionContext()) &&
- name == html_names::kRendersubtreeAttr &&
- params.old_value != params.new_value &&
- DisplayLockContext::IsAttributeVersion(
- GetDisplayLockContext())) {
- UseCounter::Count(GetDocument(), WebFeature::kRenderSubtreeAttribute);
-
- // This is needed to ensure that proper containment is put in place.
- SetNeedsStyleRecalc(kLocalStyleChange,
- StyleChangeReasonForTracing::FromAttribute(name));
- SpaceSplitString tokens(params.new_value.LowerASCII());
- uint16_t activation_mask =
- static_cast<uint16_t>(DisplayLockActivationReason::kAny);
-
- // Figure out the activation mask.
- if (tokens.Contains("skip-activation"))
- activation_mask = 0;
- if (tokens.Contains("skip-viewport-activation")) {
- activation_mask &=
- ~static_cast<uint16_t>(DisplayLockActivationReason::kViewport);
- }
-
- EnsureDisplayLockContext(DisplayLockContextCreateMethod::kAttribute)
- .SetActivatable(activation_mask);
- const bool should_be_invisible = tokens.Contains("invisible");
- if (should_be_invisible) {
- if (!GetDisplayLockContext()->IsLocked())
- GetDisplayLockContext()->StartAcquire();
- } else {
- // Getting unlocked.
- if (GetDisplayLockContext()->IsLocked())
- GetDisplayLockContext()->StartCommit();
- }
-
} else if (RuntimeEnabledFeatures::InvisibleDOMEnabled() &&
name == html_names::kInvisibleAttr &&
params.old_value != params.new_value) {
@@ -2653,7 +2674,7 @@ String Element::nodeName() const {
}
AtomicString Element::LocalNameForSelectorMatching() const {
- if (IsHTMLElement() || !GetDocument().IsHTMLDocument())
+ if (IsHTMLElement() || !IsA<HTMLDocument>(GetDocument()))
return localName();
return localName().LowerASCII();
}
@@ -2700,16 +2721,14 @@ Node::InsertionNotificationRequest Element::InsertedInto(
if (!insertion_point.IsInTreeScope())
return kInsertionDone;
- if (HasRareData()) {
+ if (isConnected() && HasRareData()) {
ElementRareData* rare_data = GetElementRareData();
if (ElementIntersectionObserverData* observer_data =
rare_data->IntersectionObserverData()) {
- if (observer_data->IsTargetOfImplicitRootObserver() ||
- observer_data->IsRoot()) {
- GetDocument().EnsureIntersectionObserverController().AddTrackedElement(
- *this, observer_data->NeedsOcclusionTracking());
- }
- if (observer_data->IsTarget() || observer_data->IsRoot()) {
+ observer_data->InvalidateCachedRects();
+ observer_data->TrackWithController(
+ GetDocument().EnsureIntersectionObserverController());
+ if (!observer_data->IsEmpty()) {
if (LocalFrameView* frame_view = GetDocument().View()) {
frame_view->SetIntersectionObservationState(
LocalFrameView::kRequired);
@@ -2717,10 +2736,8 @@ Node::InsertionNotificationRequest Element::InsertedInto(
}
}
- if (isConnected()) {
- if (auto* context = rare_data->GetDisplayLockContext())
- context->ElementConnected();
- }
+ if (auto* context = rare_data->GetDisplayLockContext())
+ context->ElementConnected();
}
if (isConnected()) {
@@ -2815,8 +2832,8 @@ void Element::RemovedFrom(ContainerNode& insertion_point) {
IntersectionObservation::kExplicitRootObserversNeedUpdate |
IntersectionObservation::kImplicitRootObserversNeedUpdate |
IntersectionObservation::kIgnoreDelay);
- GetDocument().EnsureIntersectionObserverController().RemoveTrackedElement(
- *this);
+ data->IntersectionObserverData()->StopTrackingWithController(
+ GetDocument().EnsureIntersectionObserverController());
}
if (auto* context = data->GetDisplayLockContext())
@@ -2896,14 +2913,11 @@ void Element::AttachLayoutTree(AttachContext& context) {
AttachPseudoElement(kPseudoIdFirstLetter, children_context);
if (layout_object) {
- if (!layout_object->IsFloatingOrOutOfFlowPositioned())
+ if (layout_object->AffectsWhitespaceSiblings())
context.previous_in_flow = layout_object;
} else {
context.previous_in_flow = children_context.previous_in_flow;
}
-
- if (auto* display_lock_context = GetDisplayLockContext())
- display_lock_context->DidAttachLayoutTree();
}
void Element::DetachLayoutTree(bool performing_reattach) {
@@ -2915,11 +2929,6 @@ void Element::DetachLayoutTree(bool performing_reattach) {
if (ElementAnimations* element_animations = data->GetElementAnimations()) {
if (performing_reattach) {
- // FIXME: We call detach from within style recalc, so compositingState
- // is not up to date.
- // https://code.google.com/p/chromium/issues/detail?id=339847
- DisableCompositingQueryAsserts disabler;
-
// FIXME: restart compositor animations rather than pull back to the
// main thread
element_animations->RestartAnimationOnCompositor();
@@ -2971,7 +2980,6 @@ void Element::DetachLayoutTree(bool performing_reattach) {
GetDocument().UserActionElements().DidDetach(*this);
}
- SetNeedsResizeObserverUpdate();
GetDocument().GetStyleEngine().ClearNeedsWhitespaceReattachmentFor(this);
}
@@ -3269,11 +3277,9 @@ StyleRecalcChange Element::RecalcOwnStyle(const StyleRecalcChange change) {
// change for children, since this could be the first time we unlocked the
// context and as a result need to process more of the subtree than we would
// normally. Note that if this is not the first time, then
- // AdjustTyleRecalcChangeForChildren() won't do any adjustments.
- if (!DisplayLockContext::IsAttributeVersion(context) &&
- !context->IsLocked()) {
+ // AdjustStyleRecalcChangeForChildren() won't do any adjustments.
+ if (!context->IsLocked())
child_change = context->AdjustStyleRecalcChangeForChildren(child_change);
- }
}
if (new_style) {
@@ -3358,7 +3364,7 @@ void Element::RebuildLayoutTree(WhitespaceAttacher& whitespace_attacher) {
else
RebuildChildrenLayoutTrees(*child_attacher);
RebuildPseudoElementLayoutTree(kPseudoIdBefore, *child_attacher);
- RebuildPseudoElementLayoutTree(kPseudoIdMarker, *child_attacher);
+ RebuildMarkerLayoutTree(*child_attacher);
RebuildPseudoElementLayoutTree(kPseudoIdBackdrop, *child_attacher);
RebuildFirstLetterLayoutTree();
ClearChildNeedsReattachLayoutTree();
@@ -3412,6 +3418,31 @@ void Element::RebuildFirstLetterLayoutTree() {
}
}
+void Element::RebuildMarkerLayoutTree(WhitespaceAttacher& whitespace_attacher) {
+ if (PseudoElement* marker = GetPseudoElement(kPseudoIdMarker)) {
+ // In legacy layout, we need to reattach a marker in this case:
+ //
+ // <ol><li id="outer"><div id="inner">0</div></li></ol>
+ // <script>outer.offsetTop; inner.style.display = "inline";</script>
+ //
+ // An outside marker must be aligned with the 1st line box in the
+ // list item, so legacy layout will insert it inside #inner.
+ // But when #inner becomes inline, the LayoutBlockFlow is destroyed,
+ // so we need to reinsert it.
+ //
+ // TODO: SetNeedsReattachLayoutTree() should not be called at this point.
+ // The layout tree rebuilding for markers should be done similarly to how
+ // it is done for ::first-letter.
+ if (LayoutObject* layout_object = GetLayoutObject()) {
+ if (layout_object->IsListItem() && !marker->GetLayoutObject())
+ marker->SetNeedsReattachLayoutTree();
+ }
+
+ if (marker->NeedsRebuildLayoutTree(whitespace_attacher))
+ marker->RebuildLayoutTree(whitespace_attacher);
+ }
+}
+
void Element::UpdateCallbackSelectors(const ComputedStyle* old_style,
const ComputedStyle* new_style) {
Vector<String> empty_vector;
@@ -3452,21 +3483,33 @@ ShadowRoot& Element::CreateAndAttachShadowRoot(ShadowRootType type) {
EnsureElementRareData().SetShadowRoot(*shadow_root);
shadow_root->SetParentOrShadowHostNode(this);
shadow_root->SetParentTreeScope(GetTreeScope());
- if (type == ShadowRootType::V0) {
+ if (type == ShadowRootType::V0)
shadow_root->SetNeedsDistributionRecalc();
- }
-
shadow_root->InsertedInto(*this);
- if (InActiveDocument() && GetComputedStyle())
- SetChildNeedsStyleRecalc();
- SetNeedsStyleRecalc(kSubtreeStyleChange, StyleChangeReasonForTracing::Create(
- style_change_reason::kShadow));
probe::DidPushShadowRoot(this, shadow_root);
return *shadow_root;
}
+void Element::AttachDeclarativeShadowRoot(HTMLTemplateElement* template_element,
+ ShadowRootType type,
+ FocusDelegation focus_delegation,
+ SlotAssignmentMode slot_assignment) {
+ DCHECK(template_element);
+ DCHECK(type == ShadowRootType::kOpen || type == ShadowRootType::kClosed);
+ if (!CanAttachShadowRoot()) {
+ // TODO(masonfreed): Eventually, this should be a DOMException.
+ LOG(ERROR) << "Invalid shadow root host element";
+ return;
+ }
+ ShadowRoot* shadow_root = &AttachShadowRootInternal(
+ type, focus_delegation == FocusDelegation::kDelegateFocus,
+ slot_assignment == SlotAssignmentMode::kManual);
+ shadow_root->appendChild(template_element->content());
+ template_element->remove();
+}
+
ShadowRoot* Element::GetShadowRoot() const {
return HasRareData() ? GetElementRareData()->GetShadowRoot() : nullptr;
}
@@ -3512,9 +3555,16 @@ void Element::SetNeedsCompositingUpdate() {
if (!layout_object->HasLayer())
return;
layout_object->Layer()->SetNeedsCompositingInputsUpdate();
- // Changes in the return value of requiresAcceleratedCompositing change if
- // the PaintLayer is self-painting.
- layout_object->Layer()->UpdateSelfPaintingLayer();
+
+ // Changes to RequiresAcceleratedCompositing change if the PaintLayer is
+ // self-painting (see: LayoutEmbeddedContent::LayerTypeRequired).
+ if (layout_object->IsLayoutEmbeddedContent())
+ layout_object->Layer()->UpdateSelfPaintingLayer();
+
+ // Changes to AdditionalCompositingReasons can change direct compositing
+ // reasons which affect paint properties.
+ if (layout_object->CanHaveAdditionalCompositingReasons())
+ layout_object->SetNeedsPaintPropertyUpdate();
}
void Element::V0SetCustomElementDefinition(
@@ -3666,7 +3716,7 @@ ShadowRoot* Element::attachShadow(const ShadowRootInit* shadow_root_init_dict,
DCHECK(!shadow_root_init_dict->hasMode() || !GetShadowRoot());
bool delegates_focus = shadow_root_init_dict->hasDelegatesFocus() &&
shadow_root_init_dict->delegatesFocus();
- bool manual_slotting = shadow_root_init_dict->slotting() == "manual";
+ bool manual_slotting = shadow_root_init_dict->slotAssignment() == "manual";
return &AttachShadowRootInternal(type, delegates_focus, manual_slotting);
}
@@ -3696,8 +3746,9 @@ ShadowRoot& Element::AttachShadowRootInternal(ShadowRootType type,
GetDocument().SetShadowCascadeOrder(ShadowCascadeOrder::kShadowCascadeV1);
ShadowRoot& shadow_root = CreateAndAttachShadowRoot(type);
shadow_root.SetDelegatesFocus(delegates_focus);
- shadow_root.SetSlotting(manual_slotting ? ShadowRootSlotting::kManual
- : ShadowRootSlotting::kAuto);
+ shadow_root.SetSlotAssignmentMode(manual_slotting
+ ? SlotAssignmentMode::kManual
+ : SlotAssignmentMode::kAuto);
return shadow_root;
}
@@ -3792,11 +3843,12 @@ void Element::ChildrenChanged(const ChildrenChange& change) {
CheckForEmptyStyleChange(change.sibling_before_change,
change.sibling_after_change);
- if (!change.by_parser && change.IsChildElementChange())
+ if (!change.ByParser() && change.IsChildElementChange())
CheckForSiblingStyleChanges(
- change.type == kElementRemoved ? kSiblingElementRemoved
- : kSiblingElementInserted,
- To<Element>(change.sibling_changed.Get()), change.sibling_before_change,
+ change.type == ChildrenChangeType::kElementRemoved
+ ? kSiblingElementRemoved
+ : kSiblingElementInserted,
+ To<Element>(change.sibling_changed), change.sibling_before_change,
change.sibling_after_change);
if (ShadowRoot* shadow_root = GetShadowRoot())
@@ -3837,7 +3889,7 @@ Attr* Element::setAttributeNode(Attr* attr_node,
return nullptr;
}
- if (!IsHTMLElement() && attr_node->GetDocument().IsHTMLDocument() &&
+ if (!IsHTMLElement() && IsA<HTMLDocument>(attr_node->GetDocument()) &&
attr_node->name() != attr_node->name().LowerASCII())
UseCounter::Count(
GetDocument(),
@@ -3847,10 +3899,9 @@ Attr* Element::setAttributeNode(Attr* attr_node,
SynchronizeAllAttributes();
const UniqueElementData& element_data = EnsureUniqueElementData();
- String value = GetStringFromSpecificTrustedType(
- attr_node->value(),
+ String value = TrustedTypesCheckFor(
ExpectedTrustedTypeForAttribute(attr_node->GetQualifiedName()),
- &GetDocument(), exception_state);
+ attr_node->value(), GetExecutionContext(), exception_state);
if (exception_state.HadException())
return nullptr;
@@ -3961,16 +4012,17 @@ bool Element::ParseAttributeName(QualifiedName& out,
void Element::setAttributeNS(
const AtomicString& namespace_uri,
const AtomicString& qualified_name,
- const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL& string_or_TT,
+ const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&
+ string_or_trusted,
ExceptionState& exception_state) {
QualifiedName parsed_name = g_any_name;
if (!ParseAttributeName(parsed_name, namespace_uri, qualified_name,
exception_state))
return;
- String value = GetStringFromSpecificTrustedType(
- string_or_TT, ExpectedTrustedTypeForAttribute(parsed_name),
- &GetDocument(), exception_state);
+ String value = TrustedTypesCheckFor(
+ ExpectedTrustedTypeForAttribute(parsed_name), string_or_trusted,
+ GetExecutionContext(), exception_state);
if (exception_state.HadException())
return;
@@ -4025,7 +4077,7 @@ void Element::removeAttribute(const AtomicString& name) {
wtf_size_t index = GetElementData()->Attributes().FindIndex(local_name);
if (index == kNotFound) {
if (UNLIKELY(local_name == html_names::kStyleAttr) &&
- GetElementData()->style_attribute_is_dirty_ && IsStyledElement())
+ GetElementData()->style_attribute_is_dirty() && IsStyledElement())
RemoveAllInlineStyleProperties();
return;
}
@@ -4098,19 +4150,12 @@ Element* Element::GetFocusableArea() const {
return focused_element;
// Slide the focus to its inner node.
- // TODO(crbug.com/1014094): We should pick the first focusable element in
- // the flat tree.
- Element* found =
- doc.GetPage()->GetFocusController().FindFocusableElementInShadowHost(
- *this);
- if (found && IsShadowIncludingInclusiveAncestorOf(*found))
- return found;
- return nullptr;
+ return FocusController::FindFocusableElementInShadowHost(*this);
}
void Element::focus(const FocusOptions* options) {
- focus(FocusParams(SelectionBehaviorOnFocus::kRestore, kWebFocusTypeNone,
- nullptr, options));
+ focus(FocusParams(SelectionBehaviorOnFocus::kRestore,
+ mojom::blink::FocusType::kNone, nullptr, options));
}
void Element::focus(const FocusParams& params) {
@@ -4142,8 +4187,8 @@ void Element::focus(const FocusParams& params) {
// Unlike the specification, we re-run focus() for new_focus_target
// because we can't change |this| in a member function.
new_focus_target->focus(FocusParams(SelectionBehaviorOnFocus::kReset,
- kWebFocusTypeForward, nullptr,
- params.options));
+ mojom::blink::FocusType::kForward,
+ nullptr, params.options));
}
// 2. If new focus target is null, then:
// 2.1. If no fallback target was specified, then return.
@@ -4152,7 +4197,7 @@ void Element::focus(const FocusParams& params) {
// If script called focus(), then the type would be none. This means we are
// activating because of a script action (kScriptFocus). Otherwise, this is a
// user activation (kUserFocus).
- ActivateDisplayLockIfNeeded(params.type == kWebFocusTypeNone
+ ActivateDisplayLockIfNeeded(params.type == mojom::blink::FocusType::kNone
? DisplayLockActivationReason::kScriptFocus
: DisplayLockActivationReason::kUserFocus);
DispatchActivateInvisibleEventIfNeeded();
@@ -4173,7 +4218,7 @@ void Element::focus(const FocusParams& params) {
return;
if (GetDocument().FocusedElement() == this &&
- GetDocument().GetFrame()->HasBeenActivated()) {
+ GetDocument().GetFrame()->HasStickyUserActivation()) {
// Bring up the keyboard in the context of anything triggered by a user
// gesture. Since tracking that across arbitrary boundaries (eg.
// animations) is difficult, for now we match IE's heuristic and bring
@@ -4225,8 +4270,21 @@ void Element::UpdateFocusAppearanceWithOptions(
} else if (GetLayoutObject() &&
!GetLayoutObject()->IsLayoutEmbeddedContent()) {
if (!options->preventScroll()) {
+ auto params = ScrollAlignment::CreateScrollIntoViewParams();
+
+ // It's common to have menus and list controls that have items slightly
+ // overflowing horizontally but the control isn't horizontally
+ // scrollable. Navigating through such a list should make sure items are
+ // vertically fully visible but avoid horizontal changes. This mostly
+ // matches behavior in WebKit and Gecko (though, the latter has the
+ // same behavior vertically) and there's some UA-defined wiggle room in
+ // the spec for the scrollIntoViewOptions from focus:
+ // https://html.spec.whatwg.org/#dom-focus.
+ params->align_x->rect_partial =
+ mojom::blink::ScrollAlignment::Behavior::kNoScroll;
+
GetLayoutObject()->ScrollRectToVisible(BoundingBoxForScrollIntoView(),
- WebScrollIntoViewParams());
+ std::move(params));
}
}
}
@@ -4333,9 +4391,9 @@ bool Element::IsAutofocusable() const {
}
bool Element::ActivateDisplayLockIfNeeded(DisplayLockActivationReason reason) {
- if (!RuntimeEnabledFeatures::DisplayLockingEnabled(GetExecutionContext()) ||
+ if (!RuntimeEnabledFeatures::CSSSubtreeVisibilityEnabled() ||
GetDocument().LockedDisplayLockCount() ==
- GetDocument().ActivationBlockingDisplayLockCount())
+ GetDocument().DisplayLockBlockingAllActivationCount())
return false;
const_cast<Element*>(this)->UpdateDistributionForFlatTreeTraversal();
@@ -4347,7 +4405,7 @@ bool Element::ActivateDisplayLockIfNeeded(DisplayLockActivationReason reason) {
if (auto* context = ancestor_element->GetDisplayLockContext()) {
// If any of the ancestors is not activatable for the given reason, we
// can't activate.
- if (!context->IsActivatable(reason))
+ if (context->IsLocked() && !context->IsActivatable(reason))
return false;
activatable_targets.push_back(std::make_pair(
ancestor_element, &ancestor.GetTreeScope().Retarget(*this)));
@@ -4361,7 +4419,7 @@ bool Element::ActivateDisplayLockIfNeeded(DisplayLockActivationReason reason) {
if (auto* context = target.first->GetDisplayLockContext()) {
if (context->ShouldCommitForActivation(reason)) {
activated = true;
- context->CommitForActivationWithSignal(target.second);
+ context->CommitForActivationWithSignal(target.second, reason);
}
}
}
@@ -4370,10 +4428,10 @@ bool Element::ActivateDisplayLockIfNeeded(DisplayLockActivationReason reason) {
bool Element::DisplayLockPreventsActivation(
DisplayLockActivationReason reason) const {
- if (!RuntimeEnabledFeatures::DisplayLockingEnabled(GetExecutionContext()))
+ if (!RuntimeEnabledFeatures::CSSSubtreeVisibilityEnabled())
return false;
- if (GetDocument().ActivationBlockingDisplayLockCount() == 0)
+ if (GetDocument().LockedDisplayLockCount() == 0)
return false;
const_cast<Element*>(this)->UpdateDistributionForFlatTreeTraversal();
@@ -4388,7 +4446,7 @@ bool Element::DisplayLockPreventsActivation(
if (!current_element)
continue;
if (auto* context = current_element->GetDisplayLockContext()) {
- if (!context->IsActivatable(reason))
+ if (context->IsLocked() && !context->IsActivatable(reason))
return true;
}
}
@@ -4531,7 +4589,7 @@ Element* Element::AdjustedFocusedElementInTreeScope() const {
}
void Element::DispatchFocusEvent(Element* old_focused_element,
- WebFocusType type,
+ mojom::blink::FocusType type,
InputDeviceCapabilities* source_capabilities) {
DispatchEvent(*FocusEvent::Create(
event_type_names::kFocus, Event::Bubbles::kNo, GetDocument().domWindow(),
@@ -4539,7 +4597,7 @@ void Element::DispatchFocusEvent(Element* old_focused_element,
}
void Element::DispatchBlurEvent(Element* new_focused_element,
- WebFocusType type,
+ mojom::blink::FocusType type,
InputDeviceCapabilities* source_capabilities) {
DispatchEvent(*FocusEvent::Create(
event_type_names::kBlur, Event::Bubbles::kNo, GetDocument().domWindow(),
@@ -4549,7 +4607,7 @@ void Element::DispatchBlurEvent(Element* new_focused_element,
void Element::DispatchFocusInEvent(
const AtomicString& event_type,
Element* old_focused_element,
- WebFocusType,
+ mojom::blink::FocusType,
InputDeviceCapabilities* source_capabilities) {
#if DCHECK_IS_ON()
DCHECK(!EventDispatchForbiddenScope::IsEventDispatchForbidden());
@@ -4575,25 +4633,17 @@ void Element::DispatchFocusOutEvent(
new_focused_element, source_capabilities));
}
-String Element::InnerHTMLAsString() const {
+String Element::innerHTML() const {
return CreateMarkup(this, kChildrenOnly);
}
-String Element::OuterHTMLAsString() const {
+String Element::outerHTML() const {
return CreateMarkup(this);
}
-void Element::innerHTML(StringOrTrustedHTML& result) const {
- result.SetString(InnerHTMLAsString());
-}
-
-void Element::outerHTML(StringOrTrustedHTML& result) const {
- result.SetString(OuterHTMLAsString());
-}
-
-void Element::SetInnerHTMLFromString(const String& html,
- ExceptionState& exception_state) {
- probe::BreakableLocation(&GetDocument(), "Element.setInnerHTML");
+void Element::setInnerHTML(const String& html,
+ ExceptionState& exception_state) {
+ probe::BreakableLocation(GetExecutionContext(), "Element.setInnerHTML");
if (html.IsEmpty() && !HasNonInBodyInsertionMode()) {
setTextContent(html);
} else {
@@ -4607,25 +4657,14 @@ void Element::SetInnerHTMLFromString(const String& html,
}
}
-void Element::SetInnerHTMLFromString(const String& html) {
- SetInnerHTMLFromString(html, ASSERT_NO_EXCEPTION);
+String Element::getInnerHTML(bool include_shadow_roots) const {
+ return CreateMarkup(
+ this, kChildrenOnly, kDoNotResolveURLs,
+ include_shadow_roots ? kIncludeShadowRoots : kNoShadowRoots);
}
-void Element::setInnerHTML(const StringOrTrustedHTML& string_or_html,
+void Element::setOuterHTML(const String& html,
ExceptionState& exception_state) {
- String html =
- GetStringFromTrustedHTML(string_or_html, &GetDocument(), exception_state);
- if (!exception_state.HadException()) {
- SetInnerHTMLFromString(html, exception_state);
- }
-}
-
-void Element::setInnerHTML(const StringOrTrustedHTML& string_or_html) {
- setInnerHTML(string_or_html, ASSERT_NO_EXCEPTION);
-}
-
-void Element::SetOuterHTMLFromString(const String& html,
- ExceptionState& exception_state) {
Node* p = parentNode();
if (!p) {
exception_state.ThrowDOMException(
@@ -4669,41 +4708,32 @@ void Element::SetOuterHTMLFromString(const String& html,
}
}
-void Element::setOuterHTML(const StringOrTrustedHTML& string_or_html,
- ExceptionState& exception_state) {
- String html =
- GetStringFromTrustedHTML(string_or_html, &GetDocument(), exception_state);
- if (!exception_state.HadException()) {
- SetOuterHTMLFromString(html, exception_state);
- }
-}
-
// Step 4 of http://domparsing.spec.whatwg.org/#insertadjacenthtml()
Node* Element::InsertAdjacent(const String& where,
Node* new_child,
ExceptionState& exception_state) {
- if (DeprecatedEqualIgnoringCase(where, "beforeBegin")) {
+ if (EqualIgnoringASCIICase(where, "beforeBegin")) {
if (ContainerNode* parent = parentNode()) {
- parent->insertBefore(new_child, this, exception_state);
+ parent->InsertBefore(new_child, this, exception_state);
if (!exception_state.HadException())
return new_child;
}
return nullptr;
}
- if (DeprecatedEqualIgnoringCase(where, "afterBegin")) {
- insertBefore(new_child, firstChild(), exception_state);
+ if (EqualIgnoringASCIICase(where, "afterBegin")) {
+ InsertBefore(new_child, firstChild(), exception_state);
return exception_state.HadException() ? nullptr : new_child;
}
- if (DeprecatedEqualIgnoringCase(where, "beforeEnd")) {
- appendChild(new_child, exception_state);
+ if (EqualIgnoringASCIICase(where, "beforeEnd")) {
+ AppendChild(new_child, exception_state);
return exception_state.HadException() ? nullptr : new_child;
}
- if (DeprecatedEqualIgnoringCase(where, "afterEnd")) {
+ if (EqualIgnoringASCIICase(where, "afterEnd")) {
if (ContainerNode* parent = parentNode()) {
- parent->insertBefore(new_child, nextSibling(), exception_state);
+ parent->InsertBefore(new_child, nextSibling(), exception_state);
if (!exception_state.HadException())
return new_child;
}
@@ -4718,6 +4748,16 @@ Node* Element::InsertAdjacent(const String& where,
return nullptr;
}
+void Element::HideNonce() {
+ const AtomicString& nonce_value = FastGetAttribute(html_names::kNonceAttr);
+ if (nonce_value.IsEmpty())
+ return;
+ if (!InActiveDocument())
+ return;
+ if (GetDocument().GetContentSecurityPolicy()->HasHeaderDeliveredPolicy())
+ setAttribute(html_names::kNonceAttr, g_empty_atom);
+}
+
ElementIntersectionObserverData* Element::IntersectionObserverData() const {
if (HasRareData())
return GetElementRareData()->IntersectionObserverData();
@@ -4728,18 +4768,6 @@ ElementIntersectionObserverData& Element::EnsureIntersectionObserverData() {
return EnsureElementRareData().EnsureIntersectionObserverData();
}
-bool Element::ComputeIntersectionsForLifecycleUpdate(unsigned flags) {
- if (ElementIntersectionObserverData* data = IntersectionObserverData())
- return data->ComputeIntersectionsForLifecycleUpdate(flags);
- return false;
-}
-
-bool Element::NeedsOcclusionTracking() const {
- if (ElementIntersectionObserverData* data = IntersectionObserverData())
- return data->NeedsOcclusionTracking();
- return false;
-}
-
HeapHashMap<Member<ResizeObserver>, Member<ResizeObservation>>*
Element::ResizeObserverData() const {
if (HasRareData())
@@ -4752,56 +4780,23 @@ Element::EnsureResizeObserverData() {
return EnsureElementRareData().EnsureResizeObserverData();
}
-void Element::SetNeedsResizeObserverUpdate() {
- if (auto* data = ResizeObserverData()) {
- for (auto& observation : data->Values())
- observation->ElementSizeChanged();
- }
-}
-
DisplayLockContext* Element::GetDisplayLockContext() const {
- if (!RuntimeEnabledFeatures::DisplayLockingEnabled(GetExecutionContext()))
+ if (!RuntimeEnabledFeatures::CSSSubtreeVisibilityEnabled())
return nullptr;
return HasRareData() ? GetElementRareData()->GetDisplayLockContext()
: nullptr;
}
-DisplayLockContext& Element::EnsureDisplayLockContext(
- DisplayLockContextCreateMethod method) {
- auto& result = *EnsureElementRareData().EnsureDisplayLockContext(
- this, GetExecutionContext());
- result.SetMethod(method);
- return result;
-}
-
-ScriptPromise Element::updateRendering(ScriptState* script_state) {
- auto* context = GetDisplayLockContext();
- if (context)
- return context->UpdateRendering(script_state);
- auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
- auto promise = resolver->Promise();
- resolver->Resolve();
- return promise;
-}
-
-void Element::resetSubtreeRendered() {
- if (auto* context = GetDisplayLockContext()) {
- context->ClearActivated();
- // Note that we need to schedule a style invalidation since we may need to
- // adjust the lock state, which happens during style recalc for
- // CSS-render-subtree.
- SetNeedsStyleRecalc(
- kLocalStyleChange,
- StyleChangeReasonForTracing::Create(style_change_reason::kDisplayLock));
- }
+DisplayLockContext& Element::EnsureDisplayLockContext() {
+ return *EnsureElementRareData().EnsureDisplayLockContext(this);
}
// Step 1 of http://domparsing.spec.whatwg.org/#insertadjacenthtml()
static Node* ContextNodeForInsertion(const String& where,
Element* element,
ExceptionState& exception_state) {
- if (DeprecatedEqualIgnoringCase(where, "beforeBegin") ||
- DeprecatedEqualIgnoringCase(where, "afterEnd")) {
+ if (EqualIgnoringASCIICase(where, "beforeBegin") ||
+ EqualIgnoringASCIICase(where, "afterEnd")) {
Node* parent = element->parentNode();
if (!parent || IsA<Document>(parent)) {
exception_state.ThrowDOMException(
@@ -4811,8 +4806,8 @@ static Node* ContextNodeForInsertion(const String& where,
}
return parent;
}
- if (DeprecatedEqualIgnoringCase(where, "afterBegin") ||
- DeprecatedEqualIgnoringCase(where, "beforeEnd"))
+ if (EqualIgnoringASCIICase(where, "afterBegin") ||
+ EqualIgnoringASCIICase(where, "beforeEnd"))
return element;
exception_state.ThrowDOMException(
DOMExceptionCode::kSyntaxError,
@@ -4845,7 +4840,7 @@ void Element::insertAdjacentHTML(const String& where,
// Step 2 of http://domparsing.spec.whatwg.org/#insertadjacenthtml()
Element* context_element;
if (!IsA<Element>(context_node) ||
- (context_node->GetDocument().IsHTMLDocument() &&
+ (IsA<HTMLDocument>(context_node->GetDocument()) &&
IsA<HTMLHtmlElement>(context_node))) {
context_element =
MakeGarbageCollected<HTMLBodyElement>(context_node->GetDocument());
@@ -4862,16 +4857,6 @@ void Element::insertAdjacentHTML(const String& where,
InsertAdjacent(where, fragment, exception_state);
}
-void Element::insertAdjacentHTML(const String& where,
- const StringOrTrustedHTML& string_or_html,
- ExceptionState& exception_state) {
- String markup =
- GetStringFromTrustedHTML(string_or_html, &GetDocument(), exception_state);
- if (!exception_state.HadException()) {
- insertAdjacentHTML(where, markup, exception_state);
- }
-}
-
void Element::setPointerCapture(PointerId pointer_id,
ExceptionState& exception_state) {
if (GetDocument().GetFrame()) {
@@ -4947,7 +4932,7 @@ String Element::TextFromChildren() {
return g_empty_string;
if (first_text_node && !found_multiple_text_nodes) {
- first_text_node->MakeParkableOrAtomize();
+ first_text_node->MakeParkable();
return first_text_node->data();
}
@@ -5212,10 +5197,11 @@ void Element::UpdateFirstLetterPseudoElement(StyleUpdatePhase phase) {
DCHECK(!To<FirstLetterPseudoElement>(element)->RemainingTextLayoutObject());
DCHECK(text_node_changed);
scoped_refptr<ComputedStyle> pseudo_style = element->StyleForLayoutObject();
- if (PseudoElementLayoutObjectIsNeeded(pseudo_style.get()))
+ if (PseudoElementLayoutObjectIsNeeded(pseudo_style.get(), this))
element->SetComputedStyle(std::move(pseudo_style));
else
GetElementRareData()->SetPseudoElement(kPseudoIdFirstLetter, nullptr);
+ element->ClearNeedsStyleRecalc();
return;
}
@@ -5228,7 +5214,7 @@ void Element::UpdateFirstLetterPseudoElement(StyleUpdatePhase phase) {
element->RecalcStyle(change);
if (element->NeedsReattachLayoutTree() &&
- !PseudoElementLayoutObjectIsNeeded(element->GetComputedStyle())) {
+ !PseudoElementLayoutObjectIsNeeded(element->GetComputedStyle(), this)) {
GetElementRareData()->SetPseudoElement(kPseudoIdFirstLetter, nullptr);
GetDocument().GetStyleEngine().PseudoElementRemoved(*this);
}
@@ -5238,8 +5224,11 @@ void Element::UpdatePseudoElement(PseudoId pseudo_id,
const StyleRecalcChange change) {
PseudoElement* element = GetPseudoElement(pseudo_id);
if (!element) {
- if ((element = CreatePseudoElementIfNeeded(pseudo_id)))
+ if ((element = CreatePseudoElementIfNeeded(pseudo_id))) {
+ // ::before and ::after can have a nested ::marker
+ element->CreatePseudoElementIfNeeded(kPseudoIdMarker);
element->SetNeedsReattachLayoutTree();
+ }
return;
}
@@ -5248,7 +5237,7 @@ void Element::UpdatePseudoElement(PseudoId pseudo_id,
element->RecalcStyle(change.ForPseudoElement());
if (!element->NeedsReattachLayoutTree())
return;
- if (PseudoElementLayoutObjectIsNeeded(element->GetComputedStyle()))
+ if (PseudoElementLayoutObjectIsNeeded(element->GetComputedStyle(), this))
return;
}
GetElementRareData()->SetPseudoElement(pseudo_id, nullptr);
@@ -5257,8 +5246,6 @@ void Element::UpdatePseudoElement(PseudoId pseudo_id,
}
PseudoElement* Element::CreatePseudoElementIfNeeded(PseudoId pseudo_id) {
- if (IsPseudoElement())
- return nullptr;
if (!CanGeneratePseudoElement(pseudo_id))
return nullptr;
if (pseudo_id == kPseudoIdFirstLetter) {
@@ -5272,7 +5259,7 @@ PseudoElement* Element::CreatePseudoElementIfNeeded(PseudoId pseudo_id) {
scoped_refptr<ComputedStyle> pseudo_style =
pseudo_element->StyleForLayoutObject();
- if (!PseudoElementLayoutObjectIsNeeded(pseudo_style.get())) {
+ if (!PseudoElementLayoutObjectIsNeeded(pseudo_style.get(), this)) {
GetElementRareData()->SetPseudoElement(pseudo_id, nullptr);
return nullptr;
}
@@ -5316,6 +5303,34 @@ LayoutObject* Element::PseudoElementLayoutObject(PseudoId pseudo_id) const {
return nullptr;
}
+bool Element::PseudoElementStylesDependOnFontMetrics() const {
+ const ComputedStyle* style = GetComputedStyle();
+ if (!style)
+ return false;
+ if (style->CachedPseudoElementStylesDependOnFontMetrics())
+ return true;
+
+ // Note that |HasAnyPseudoElementStyles()| counts public pseudo elements only.
+ // ::-webkit-scrollbar-* are internal, and hence are not counted. So we must
+ // perform this check after checking the cached pseudo element styles to avoid
+ // false negatives.
+ if (!style->HasAnyPseudoElementStyles())
+ return false;
+
+ // If we don't generate a PseudoElement, its style must have been cached on
+ // the originating element's ComputedStyle. Hence, it remains to check styles
+ // on the generated PseudoElements.
+ if (!HasRareData())
+ return false;
+ for (PseudoElement* pseudo_element :
+ GetElementRareData()->GetPseudoElements()) {
+ if (pseudo_element->GetComputedStyle()->DependsOnFontMetrics())
+ return true;
+ }
+
+ return false;
+}
+
const ComputedStyle* Element::CachedStyleForPseudoElement(
const PseudoElementStyleRequest& request) {
const ComputedStyle* style = GetComputedStyle();
@@ -5457,18 +5472,6 @@ KURL Element::GetURLAttribute(const QualifiedName& name) const {
StripLeadingAndTrailingHTMLSpaces(getAttribute(name)));
}
-void Element::GetURLAttribute(const QualifiedName& name,
- StringOrTrustedScriptURL& result) const {
- KURL url = GetURLAttribute(name);
- result.SetString(url.GetString());
-}
-
-void Element::FastGetAttribute(const QualifiedName& name,
- StringOrTrustedHTML& result) const {
- String html = FastGetAttribute(name);
- result.SetString(html);
-}
-
KURL Element::GetNonEmptyURLAttribute(const QualifiedName& name) const {
#if DCHECK_IS_ON()
if (GetElementData()) {
@@ -5493,6 +5496,12 @@ int Element::GetIntegralAttribute(const QualifiedName& attribute_name,
return integral_value;
}
+unsigned int Element::GetUnsignedIntegralAttribute(
+ const QualifiedName& attribute_name) const {
+ return static_cast<unsigned int>(
+ std::max(0, GetIntegralAttribute(attribute_name)));
+}
+
void Element::SetIntegralAttribute(const QualifiedName& attribute_name,
int value) {
setAttribute(attribute_name, AtomicString::Number(value));
@@ -5590,21 +5599,50 @@ void Element::SetIsInTopLayer(bool in_top_layer) {
SetForceReattachLayoutTree();
}
-void Element::requestPointerLock(const PointerLockOptions* options) {
+ScriptValue Element::requestPointerLock(ScriptState* script_state,
+ const PointerLockOptions* options,
+ ExceptionState& exception_state) {
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ ScriptPromise promise;
if (GetDocument().GetPage()) {
- GetDocument().GetPage()->GetPointerLockController().RequestPointerLock(
- this, options);
+ promise =
+ GetDocument().GetPage()->GetPointerLockController().RequestPointerLock(
+ resolver, this, exception_state, options);
+ } else {
+ promise = resolver->Promise();
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kWrongDocumentError,
+ "PointerLock cannot be request when there "
+ "is no frame or that frame has no page.");
+ }
+
+ if (RuntimeEnabledFeatures::PointerLockOptionsEnabled(
+ GetExecutionContext())) {
+ if (exception_state.HadException())
+ resolver->Reject(exception_state);
+ return promise.GetScriptValue();
}
+
+ // The current spec for PointerLock does not have any language about throwing
+ // exceptions. Therefore to be spec compliant we must clear all exceptions.
+ // When behind our experimental flag however, we will throw exceptions which
+ // should be caught as a promise rejection.
+ exception_state.ClearException();
+
+ // Detach the resolver, since we are not using it, to prepare it for garbage
+ // collection.
+ resolver->Detach();
+ return ScriptValue();
}
SpellcheckAttributeState Element::GetSpellcheckAttributeState() const {
const AtomicString& value = FastGetAttribute(html_names::kSpellcheckAttr);
if (value == g_null_atom)
return kSpellcheckAttributeDefault;
- if (DeprecatedEqualIgnoringCase(value, "true") ||
- DeprecatedEqualIgnoringCase(value, ""))
+ if (EqualIgnoringASCIICase(value, "true") ||
+ EqualIgnoringASCIICase(value, ""))
return kSpellcheckAttributeTrue;
- if (DeprecatedEqualIgnoringCase(value, "false"))
+ if (EqualIgnoringASCIICase(value, "false"))
return kSpellcheckAttributeFalse;
return kSpellcheckAttributeDefault;
@@ -5805,23 +5843,23 @@ void Element::DidMoveToNewDocument(Document& old_document) {
void Element::UpdateNamedItemRegistration(NamedItemType type,
const AtomicString& old_name,
const AtomicString& new_name) {
- if (!GetDocument().IsHTMLDocument())
+ auto* doc = DynamicTo<HTMLDocument>(GetDocument());
+ if (!doc)
return;
- HTMLDocument& doc = ToHTMLDocument(GetDocument());
if (!old_name.IsEmpty())
- doc.RemoveNamedItem(old_name);
+ doc->RemoveNamedItem(old_name);
if (!new_name.IsEmpty())
- doc.AddNamedItem(new_name);
+ doc->AddNamedItem(new_name);
if (type == NamedItemType::kNameOrIdWithName) {
const AtomicString id = GetIdAttribute();
if (!id.IsEmpty()) {
if (!old_name.IsEmpty() && new_name.IsEmpty())
- doc.RemoveNamedItem(id);
+ doc->RemoveNamedItem(id);
else if (old_name.IsEmpty() && !new_name.IsEmpty())
- doc.AddNamedItem(id);
+ doc->AddNamedItem(id);
}
}
}
@@ -5829,17 +5867,18 @@ void Element::UpdateNamedItemRegistration(NamedItemType type,
void Element::UpdateIdNamedItemRegistration(NamedItemType type,
const AtomicString& old_id,
const AtomicString& new_id) {
- if (!GetDocument().IsHTMLDocument())
+ auto* doc = DynamicTo<HTMLDocument>(GetDocument());
+ if (!doc)
return;
if (type == NamedItemType::kNameOrIdWithName && GetNameAttribute().IsEmpty())
return;
if (!old_id.IsEmpty())
- ToHTMLDocument(GetDocument()).RemoveNamedItem(old_id);
+ doc->RemoveNamedItem(old_id);
if (!new_id.IsEmpty())
- ToHTMLDocument(GetDocument()).AddNamedItem(new_id);
+ doc->AddNamedItem(new_id);
}
ScrollOffset Element::SavedLayerScrollOffset() const {
@@ -6025,8 +6064,8 @@ void Element::CreateUniqueElementData() {
void Element::SynchronizeStyleAttributeInternal() const {
DCHECK(IsStyledElement());
DCHECK(GetElementData());
- DCHECK(GetElementData()->style_attribute_is_dirty_);
- GetElementData()->style_attribute_is_dirty_ = false;
+ DCHECK(GetElementData()->style_attribute_is_dirty());
+ GetElementData()->SetStyleAttributeIsDirty(false);
const CSSPropertyValueSet* inline_style = InlineStyle();
const_cast<Element*>(this)->SetSynchronizedLazyAttribute(
html_names::kStyleAttr,
@@ -6119,7 +6158,7 @@ void Element::StyleAttributeChanged(
SetInlineStyleFromString(new_style_string);
}
- GetElementData()->style_attribute_is_dirty_ = false;
+ GetElementData()->SetStyleAttributeIsDirty(false);
SetNeedsStyleRecalc(kLocalStyleChange,
StyleChangeReasonForTracing::Create(
@@ -6129,10 +6168,7 @@ void Element::StyleAttributeChanged(
void Element::InlineStyleChanged() {
DCHECK(IsStyledElement());
- SetNeedsStyleRecalc(kLocalStyleChange, StyleChangeReasonForTracing::Create(
- style_change_reason::kInline));
- DCHECK(GetElementData());
- GetElementData()->style_attribute_is_dirty_ = true;
+ InvalidateStyleAttribute();
probe::DidInvalidateStyleAttr(this);
if (MutationObserverInterestGroup* recipients =
@@ -6222,7 +6258,7 @@ void Element::UpdatePresentationAttributeStyle() {
// ShareableElementData doesn't store presentation attribute style, so make
// sure we have a UniqueElementData.
UniqueElementData& element_data = EnsureUniqueElementData();
- element_data.presentation_attribute_style_is_dirty_ = false;
+ element_data.SetPresentationAttributeStyleIsDirty(false);
element_data.presentation_attribute_style_ =
ComputePresentationAttributeStyle(*this);
}
@@ -6331,8 +6367,6 @@ void Element::LogUpdateAttributeIfIsolatedWorldAndInDocument(
}
void Element::Trace(Visitor* visitor) {
- if (HasRareData())
- visitor->Trace(GetElementRareData());
visitor->Trace(element_data_);
ContainerNode::Trace(visitor);
}
@@ -6432,4 +6466,14 @@ void Element::SetActive(bool active) {
GetLayoutObject()->InvalidateIfControlStateChanged(kPressedControlState);
}
+void Element::InvalidateStyleAttribute() {
+ DCHECK(GetElementData());
+ GetElementData()->SetStyleAttributeIsDirty(true);
+ SetNeedsStyleRecalc(kLocalStyleChange,
+ StyleChangeReasonForTracing::Create(
+ style_change_reason::kInlineCSSStyleMutated));
+ GetDocument().GetStyleEngine().AttributeChangedForElement(
+ html_names::kStyleAttr, *this);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/dom/element.h b/chromium/third_party/blink/renderer/core/dom/element.h
index cc135847c83..541b0321bd1 100644
--- a/chromium/third_party/blink/renderer/core/dom/element.h
+++ b/chromium/third_party/blink/renderer/core/dom/element.h
@@ -25,8 +25,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_ELEMENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_ELEMENT_H_
-#include "third_party/blink/public/platform/pointer_id.h"
-#include "third_party/blink/public/platform/web_focus_type.h"
+#include "third_party/blink/public/common/input/pointer_id.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_focus_options.h"
#include "third_party/blink/renderer/core/animation/animatable.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/css/css_primitive_value.h"
@@ -37,7 +38,6 @@
#include "third_party/blink/renderer/core/dom/element_data.h"
#include "third_party/blink/renderer/core/dom/names_map.h"
#include "third_party/blink/renderer/core/dom/whitespace_attacher.h"
-#include "third_party/blink/renderer/core/html/focus_options.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/trustedtypes/trusted_types_util.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -65,7 +65,7 @@ class ElementRareData;
class ExceptionState;
class FloatQuad;
class FloatSize;
-class FocusOptions;
+class HTMLTemplateElement;
class Image;
class InputDeviceCapabilities;
class Locale;
@@ -77,17 +77,13 @@ class PseudoElement;
class PseudoElementStyleRequest;
class ResizeObservation;
class ResizeObserver;
-class ScriptPromise;
class ScrollIntoViewOptions;
class ScrollIntoViewOptionsOrBoolean;
class ScrollToOptions;
class ShadowRoot;
class ShadowRootInit;
class SpaceSplitString;
-class StringOrTrustedHTML;
class StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL;
-class StringOrTrustedScript;
-class StringOrTrustedScriptURL;
class StylePropertyMap;
class StylePropertyMapReadOnly;
class V0CustomElementDefinition;
@@ -96,7 +92,6 @@ enum class CSSPropertyID;
enum class CSSValueID;
enum class DisplayLockActivationReason;
enum class DisplayLockLifecycleTarget;
-enum class DisplayLockContextCreateMethod;
using ScrollOffset = FloatSize;
@@ -118,6 +113,8 @@ enum class ElementFlags {
};
enum class ShadowRootType;
+enum class FocusDelegation;
+enum class SlotAssignmentMode;
enum class SelectionBehaviorOnFocus {
kReset,
@@ -145,7 +142,7 @@ struct FocusParams {
public:
FocusParams() : options(FocusOptions::Create()) {}
FocusParams(SelectionBehaviorOnFocus selection,
- WebFocusType focus_type,
+ mojom::blink::FocusType focus_type,
InputDeviceCapabilities* capabilities,
const FocusOptions* focus_options = FocusOptions::Create())
: selection_behavior(selection),
@@ -155,9 +152,9 @@ struct FocusParams {
SelectionBehaviorOnFocus selection_behavior =
SelectionBehaviorOnFocus::kRestore;
- WebFocusType type = kWebFocusTypeNone;
- Member<InputDeviceCapabilities> source_capabilities = nullptr;
- Member<const FocusOptions> options;
+ mojom::blink::FocusType type = mojom::blink::FocusType::kNone;
+ InputDeviceCapabilities* source_capabilities = nullptr;
+ const FocusOptions* options = nullptr;
};
typedef HeapVector<Member<Attr>> AttrNodeList;
@@ -198,6 +195,8 @@ class CORE_EXPORT Element : public ContainerNode, public Animatable {
int GetIntegralAttribute(const QualifiedName& attribute_name) const;
int GetIntegralAttribute(const QualifiedName& attribute_name,
int default_value) const;
+ unsigned int GetUnsignedIntegralAttribute(
+ const QualifiedName& attribute_name) const;
void SetIntegralAttribute(const QualifiedName& attribute_name, int value);
void SetUnsignedIntegralAttribute(const QualifiedName& attribute_name,
unsigned value,
@@ -208,12 +207,27 @@ class CORE_EXPORT Element : public ContainerNode, public Animatable {
void SetFloatingPointAttribute(const QualifiedName& attribute_name,
double value);
+ // Returns true if |this| element has attr-associated elements that were set
+ // via the IDL, rather than computed from the content attribute.
+ // See
+ // https://whatpr.org/html/3917/common-dom-interfaces.html#reflecting-content-attributes-in-idl-attributes:element
+ // for more information.
+ // This is only exposed as an implementation detail to AXRelationCache, which
+ // computes aria-owns differently for element reflection.
+ bool HasExplicitlySetAttrAssociatedElements(const QualifiedName& name);
Element* GetElementAttribute(const QualifiedName& name);
void SetElementAttribute(const QualifiedName&, Element*);
- HeapVector<Member<Element>> GetElementArrayAttribute(
+ base::Optional<HeapVector<Member<Element>>> GetElementArrayAttribute(
+ const QualifiedName& name);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ HeapVector<Member<Element>> GetElementArrayAttribute( // DEPRECATED
const QualifiedName& name,
bool& is_null);
- void SetElementArrayAttribute(const QualifiedName&,
+ void SetElementArrayAttribute(
+ const QualifiedName&,
+ const base::Optional<HeapVector<Member<Element>>>&);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ void SetElementArrayAttribute(const QualifiedName&, // DEPRECATED
HeapVector<Member<Element>>,
bool is_null);
@@ -243,8 +257,7 @@ class CORE_EXPORT Element : public ContainerNode, public Animatable {
void setAttribute(const AtomicString& name,
const AtomicString& value,
- ExceptionState&);
- void setAttribute(const AtomicString& name, const AtomicString& value);
+ ExceptionState& = ASSERT_NO_EXCEPTION);
// Trusted Types variant for explicit setAttribute() use.
void setAttribute(const AtomicString&,
@@ -254,20 +267,7 @@ class CORE_EXPORT Element : public ContainerNode, public Animatable {
// Returns attributes that should be checked against Trusted Types
virtual const AttrNameToTrustedType& GetCheckedAttributeTypes() const;
- // Trusted Type HTML variant
- void setAttribute(const QualifiedName&,
- const StringOrTrustedHTML&,
- ExceptionState&);
-
- // Trusted Type Script variant
- void setAttribute(const QualifiedName&,
- const StringOrTrustedScript&,
- ExceptionState&);
-
- // Trusted Type ScriptURL variant
- void setAttribute(const QualifiedName&,
- const StringOrTrustedScriptURL&,
- ExceptionState&);
+ void setAttribute(const QualifiedName&, const String&, ExceptionState&);
static bool ParseAttributeName(QualifiedName&,
const AtomicString& namespace_uri,
@@ -541,6 +541,8 @@ class CORE_EXPORT Element : public ContainerNode, public Animatable {
void RecalcStyleForTraversalRootAncestor();
void RebuildLayoutTreeForTraversalRootAncestor() {
RebuildFirstLetterLayoutTree();
+ WhitespaceAttacher whitespace_attacher;
+ RebuildMarkerLayoutTree(whitespace_attacher);
}
bool NeedsRebuildLayoutTree(
const WhitespaceAttacher& whitespace_attacher) const {
@@ -565,6 +567,11 @@ class CORE_EXPORT Element : public ContainerNode, public Animatable {
ShadowRoot* createShadowRoot(ExceptionState&);
ShadowRoot* attachShadow(const ShadowRootInit*, ExceptionState&);
+ void AttachDeclarativeShadowRoot(HTMLTemplateElement*,
+ ShadowRootType,
+ FocusDelegation,
+ SlotAssignmentMode);
+
ShadowRoot& CreateV0ShadowRootForTesting() {
return CreateShadowRootInternal();
}
@@ -613,8 +620,11 @@ class CORE_EXPORT Element : public ContainerNode, public Animatable {
}
bool IsDefined() const {
- return !(static_cast<int>(GetCustomElementState()) &
- static_cast<int>(CustomElementState::kNotDefinedFlag));
+ // An element whose custom element state is "uncustomized" or "custom"
+ // is said to be defined.
+ // https://dom.spec.whatwg.org/#concept-element-defined
+ return GetCustomElementState() == CustomElementState::kUncustomized ||
+ GetCustomElementState() == CustomElementState::kCustom;
}
bool IsUpgradedV0CustomElement() {
return GetV0CustomElementState() == kV0Upgraded;
@@ -641,8 +651,6 @@ class CORE_EXPORT Element : public ContainerNode, public Animatable {
KURL HrefURL() const;
KURL GetURLAttribute(const QualifiedName&) const;
- void GetURLAttribute(const QualifiedName&, StringOrTrustedScriptURL&) const;
- void FastGetAttribute(const QualifiedName&, StringOrTrustedHTML&) const;
KURL GetNonEmptyURLAttribute(const QualifiedName&) const;
@@ -679,16 +687,16 @@ class CORE_EXPORT Element : public ContainerNode, public Animatable {
virtual void DispatchFocusEvent(
Element* old_focused_element,
- WebFocusType,
+ mojom::blink::FocusType,
InputDeviceCapabilities* source_capabilities = nullptr);
virtual void DispatchBlurEvent(
Element* new_focused_element,
- WebFocusType,
+ mojom::blink::FocusType,
InputDeviceCapabilities* source_capabilities = nullptr);
virtual void DispatchFocusInEvent(
const AtomicString& event_type,
Element* old_focused_element,
- WebFocusType,
+ mojom::blink::FocusType,
InputDeviceCapabilities* source_capabilities = nullptr);
void DispatchFocusOutEvent(
const AtomicString& event_type,
@@ -698,11 +706,6 @@ class CORE_EXPORT Element : public ContainerNode, public Animatable {
// The implementation of |innerText()| is found in "element_inner_text.cc".
String innerText();
String outerText();
- String InnerHTMLAsString() const;
- String OuterHTMLAsString() const;
- void SetInnerHTMLFromString(const String& html, ExceptionState&);
- void SetInnerHTMLFromString(const String& html);
- void SetOuterHTMLFromString(const String& html, ExceptionState&);
Element* insertAdjacentElement(const String& where,
Element* new_child,
@@ -714,16 +717,11 @@ class CORE_EXPORT Element : public ContainerNode, public Animatable {
const String& html,
ExceptionState&);
- // TrustedTypes variants of the above.
- // TODO(mkwst): Write a spec for these bits. https://crbug.com/739170
- void innerHTML(StringOrTrustedHTML&) const;
- void outerHTML(StringOrTrustedHTML&) const;
- void setInnerHTML(const StringOrTrustedHTML&, ExceptionState&);
- void setInnerHTML(const StringOrTrustedHTML&);
- void setOuterHTML(const StringOrTrustedHTML&, ExceptionState&);
- void insertAdjacentHTML(const String& where,
- const StringOrTrustedHTML&,
- ExceptionState&);
+ String innerHTML() const;
+ String outerHTML() const;
+ void setInnerHTML(const String&, ExceptionState& = ASSERT_NO_EXCEPTION);
+ String getInnerHTML(bool include_shadow_roots) const;
+ void setOuterHTML(const String&, ExceptionState& = ASSERT_NO_EXCEPTION);
void setPointerCapture(PointerId poinetr_id, ExceptionState&);
void releasePointerCapture(PointerId pointer_id, ExceptionState&);
@@ -758,12 +756,13 @@ class CORE_EXPORT Element : public ContainerNode, public Animatable {
PseudoElement* GetPseudoElement(PseudoId) const;
LayoutObject* PseudoElementLayoutObject(PseudoId) const;
+ bool PseudoElementStylesDependOnFontMetrics() const;
const ComputedStyle* CachedStyleForPseudoElement(
const PseudoElementStyleRequest&);
scoped_refptr<ComputedStyle> StyleForPseudoElement(
const PseudoElementStyleRequest&,
const ComputedStyle* parent_style = nullptr);
- bool CanGeneratePseudoElement(PseudoId) const;
+ virtual bool CanGeneratePseudoElement(PseudoId) const;
virtual bool MatchesDefaultPseudoClass() const { return false; }
virtual bool MatchesEnabledPseudoClass() const { return false; }
@@ -860,7 +859,9 @@ class CORE_EXPORT Element : public ContainerNode, public Animatable {
}
void SetIsInTopLayer(bool);
- void requestPointerLock(const PointerLockOptions*);
+ ScriptValue requestPointerLock(ScriptState* script_state,
+ const PointerLockOptions* options,
+ ExceptionState& exception_state);
bool IsSpellCheckingEnabled() const;
@@ -920,23 +921,14 @@ class CORE_EXPORT Element : public ContainerNode, public Animatable {
ElementIntersectionObserverData* IntersectionObserverData() const;
ElementIntersectionObserverData& EnsureIntersectionObserverData();
- bool ComputeIntersectionsForLifecycleUpdate(unsigned flags);
- // Returns true if the Element is being observed by an IntersectionObserver
- // for which trackVisibility() is true.
- bool NeedsOcclusionTracking() const;
HeapHashMap<Member<ResizeObserver>, Member<ResizeObservation>>*
ResizeObserverData() const;
HeapHashMap<Member<ResizeObserver>, Member<ResizeObservation>>&
EnsureResizeObserverData();
- void SetNeedsResizeObserverUpdate();
DisplayLockContext* GetDisplayLockContext() const;
- DisplayLockContext& EnsureDisplayLockContext(DisplayLockContextCreateMethod);
-
- // Display locking IDL implementation
- ScriptPromise updateRendering(ScriptState*);
- void resetSubtreeRendered();
+ DisplayLockContext& EnsureDisplayLockContext();
bool StyleRecalcBlockedByDisplayLock(DisplayLockLifecycleTarget) const;
@@ -948,6 +940,10 @@ class CORE_EXPORT Element : public ContainerNode, public Animatable {
virtual void SetActive(bool active);
virtual void SetHovered(bool hovered);
+ // Classes overriding this method can return true when an element has
+ // been determined to be from an ad. Returns false by default.
+ virtual bool IsAdRelated() const { return false; }
+
protected:
const ElementData* GetElementData() const { return element_data_.Get(); }
UniqueElementData& EnsureUniqueElementData();
@@ -1004,6 +1000,17 @@ class CORE_EXPORT Element : public ContainerNode, public Animatable {
virtual void ParserDidSetAttributes() {}
+ // The "nonce" attribute is hidden when:
+ // 1) The Content-Security-Policy is delivered from the HTTP headers.
+ // 2) The Element is part of the active document.
+ // See https://github.com/whatwg/html/pull/2373
+ //
+ // This applies to the element of the HTML and SVG namespaces.
+ //
+ // This function clears the "nonce" attribute whenever conditions (1) and (2)
+ // are met.
+ void HideNonce();
+
private:
void ScrollLayoutBoxBy(const ScrollToOptions*);
void ScrollLayoutBoxTo(const ScrollToOptions*);
@@ -1050,6 +1057,7 @@ class CORE_EXPORT Element : public ContainerNode, public Animatable {
void RebuildPseudoElementLayoutTree(PseudoId, WhitespaceAttacher&);
void RebuildFirstLetterLayoutTree();
+ void RebuildMarkerLayoutTree(WhitespaceAttacher&);
void RebuildShadowRootLayoutTree(WhitespaceAttacher&);
inline void CheckForEmptyStyleChange(const Node* node_before_change,
const Node* node_after_change);
@@ -1216,7 +1224,6 @@ class CORE_EXPORT Element : public ContainerNode, public Animatable {
Member<ElementData> element_data_;
};
-DEFINE_NODE_TYPE_CASTS(Element, IsElementNode());
template <typename T>
bool IsElementOfType(const Node&);
template <>
@@ -1237,27 +1244,6 @@ struct DowncastTraits<Element> {
static bool AllowFrom(const Node& node) { return node.IsElementNode(); }
};
-// Type casting.
-template <typename T>
-inline T& ToElement(Node& node) {
- SECURITY_DCHECK(IsElementOfType<const T>(node));
- return static_cast<T&>(node);
-}
-template <typename T>
-inline T* ToElement(Node* node) {
- SECURITY_DCHECK(!node || IsElementOfType<const T>(*node));
- return static_cast<T*>(node);
-}
-template <typename T>
-inline const T& ToElement(const Node& node) {
- SECURITY_DCHECK(IsElementOfType<const T>(node));
- return static_cast<const T&>(node);
-}
-template <typename T>
-inline const T* ToElement(const Node* node) {
- SECURITY_DCHECK(!node || IsElementOfType<const T>(*node));
- return static_cast<const T*>(node);
-}
inline bool IsDisabledFormControl(const Node* node) {
auto* element = DynamicTo<Element>(node);
@@ -1356,15 +1342,10 @@ inline UniqueElementData& Element::EnsureUniqueElementData() {
return To<UniqueElementData>(*element_data_);
}
-inline void Element::InvalidateStyleAttribute() {
- DCHECK(GetElementData());
- GetElementData()->style_attribute_is_dirty_ = true;
-}
-
inline const CSSPropertyValueSet* Element::PresentationAttributeStyle() {
if (!GetElementData())
return nullptr;
- if (GetElementData()->presentation_attribute_style_is_dirty_)
+ if (GetElementData()->presentation_attribute_style_is_dirty())
UpdatePresentationAttributeStyle();
// Need to call elementData() again since updatePresentationAttributeStyle()
// might swap it with a UniqueElementData.
@@ -1402,23 +1383,6 @@ inline bool IsAtShadowBoundary(const Element* element) {
return parent_node && parent_node->IsShadowRoot();
}
-// These macros do the same as their NODE equivalents but additionally provide a
-// template specialization for isElementOfType<>() so that the Traversal<> API
-// works for these Element types.
-#define DEFINE_ELEMENT_TYPE_CASTS(thisType, predicate) \
- template <> \
- inline bool IsElementOfType<const thisType>(const Node& node) { \
- return node.predicate; \
- } \
- DEFINE_NODE_TYPE_CASTS(thisType, predicate)
-
-#define DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(thisType) \
- template <> \
- inline bool IsElementOfType<const thisType>(const Node& node) { \
- return Is##thisType(node); \
- } \
- DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(thisType)
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_ELEMENT_H_
diff --git a/chromium/third_party/blink/renderer/core/dom/element.idl b/chromium/third_party/blink/renderer/core/dom/element.idl
index 2f0674c6038..5ed1c0311d6 100644
--- a/chromium/third_party/blink/renderer/core/dom/element.idl
+++ b/chromium/third_party/blink/renderer/core/dom/element.idl
@@ -90,13 +90,19 @@ callback ScrollStateCallback = void (ScrollState scrollState);
// https://w3c.github.io/DOM-Parsing/#extensions-to-the-element-interface
//
// TODO(mkwst): Write a spec for the `TrustedHTML` variants.
- [Affects=Nothing, CEReactions, CustomElementCallbacks, Custom=Setter, RuntimeCallStatsCounter=ElementInnerHTML] attribute HTMLString innerHTML;
- [Affects=Nothing, CEReactions, CustomElementCallbacks, Custom=Setter] attribute HTMLString outerHTML;
+ // TODO(lyf): Change the type to `[TreatNullAs=xxx] HTMLString` after
+ // https://crbug.com/1058762 has been fixed.
+ [Affects=Nothing, CEReactions, CustomElementCallbacks, RuntimeCallStatsCounter=ElementInnerHTML, RaisesException=Setter] attribute [TreatNullAs=EmptyString, StringContext=TrustedHTML] DOMString innerHTML;
+ [Affects=Nothing, CEReactions, CustomElementCallbacks, RaisesException=Setter] attribute [TreatNullAs=EmptyString, StringContext=TrustedHTML] DOMString outerHTML;
[CEReactions, CustomElementCallbacks, RaisesException] void insertAdjacentHTML(DOMString position, HTMLString text);
+ // Declarative Shadow DOM getInnerHTML() function.
+ [RuntimeEnabled=DeclarativeShadowDOM, RuntimeCallStatsCounter=ElementGetInnerHTML] HTMLString getInnerHTML(boolean includeShadowRoots);
+
// Pointer Lock
// https://w3c.github.io/pointerlock/#extensions-to-the-element-interface
- [MeasureAs=ElementRequestPointerLock] void requestPointerLock(optional PointerLockOptions options);
+ // This function returns void unless the Runtime Enabled Feature |PointerLockOptions| is enabled then it returns Promise<void>.
+ [MeasureAs=ElementRequestPointerLock, CallWith=ScriptState, RaisesException] any requestPointerLock(optional PointerLockOptions options = {});
// CSSOM View Module
// https://drafts.csswg.org/cssom-view/#extension-to-the-element-interface
@@ -105,12 +111,12 @@ callback ScrollStateCallback = void (ScrollState scrollState);
// TODO(sunyunjia): Add default value for scrollIntoView() once
// crbug.com/734599 is fixed.
- void scrollIntoView(optional (ScrollIntoViewOptions or boolean) arg);
- [ImplementedAs=scrollTo] void scroll(optional ScrollToOptions options);
+ void scrollIntoView(optional (ScrollIntoViewOptions or boolean) arg = {});
+ [ImplementedAs=scrollTo] void scroll(optional ScrollToOptions options = {});
[ImplementedAs=scrollTo] void scroll(unrestricted double x, unrestricted double y);
- void scrollTo(optional ScrollToOptions options);
+ void scrollTo(optional ScrollToOptions options = {});
void scrollTo(unrestricted double x, unrestricted double y);
- void scrollBy(optional ScrollToOptions options);
+ void scrollBy(optional ScrollToOptions options = {});
void scrollBy(unrestricted double x, unrestricted double y);
[Affects=Nothing] attribute unrestricted double scrollTop;
[Affects=Nothing] attribute unrestricted double scrollLeft;
@@ -145,13 +151,6 @@ callback ScrollStateCallback = void (ScrollState scrollState);
attribute EventHandler onbeforepaste;
attribute EventHandler onsearch;
- // Declarative display locking.
- [RuntimeEnabled=DisplayLocking, CEReactions, CustomElementCallbacks, Reflect] attribute DOMString renderSubtree;
- [RuntimeEnabled=DisplayLocking, CallWith=ScriptState] Promise<any> updateRendering();
-
- // CSS version of display locking.
- [RuntimeEnabled=CSSRenderSubtree] void resetSubtreeRendered();
-
// Element Timing
[Affects=Nothing, CEReactions, Reflect=elementtiming] attribute DOMString elementTiming;
};
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 890989ea8f6..cb990d551b0 100644
--- a/chromium/third_party/blink/renderer/core/dom/element_data.cc
+++ b/chromium/third_party/blink/renderer/core/dom/element_data.cc
@@ -52,27 +52,27 @@ static AdditionalBytes AdditionalBytesForShareableElementDataWithAttributeCount(
}
ElementData::ElementData()
- : is_unique_(true),
- array_size_(0),
- presentation_attribute_style_is_dirty_(false),
- style_attribute_is_dirty_(false),
- animated_svg_attributes_are_dirty_(false) {}
+ : bit_field_(IsUniqueFlag::encode(true) | ArraySize::encode(0) |
+ PresentationAttributeStyleIsDirty::encode(false) |
+ StyleAttributeIsDirty::encode(false) |
+ AnimatedSvgAttributesAreDirty::encode(false)) {}
ElementData::ElementData(unsigned array_size)
- : is_unique_(false),
- array_size_(array_size),
- presentation_attribute_style_is_dirty_(false),
- style_attribute_is_dirty_(false),
- animated_svg_attributes_are_dirty_(false) {}
+ : bit_field_(IsUniqueFlag::encode(false) | ArraySize::encode(array_size) |
+ PresentationAttributeStyleIsDirty::encode(false) |
+ StyleAttributeIsDirty::encode(false) |
+ AnimatedSvgAttributesAreDirty::encode(false)) {}
ElementData::ElementData(const ElementData& other, bool is_unique)
- : is_unique_(is_unique),
- array_size_(is_unique ? 0 : other.Attributes().size()),
- presentation_attribute_style_is_dirty_(
- other.presentation_attribute_style_is_dirty_),
- style_attribute_is_dirty_(other.style_attribute_is_dirty_),
- animated_svg_attributes_are_dirty_(
- other.animated_svg_attributes_are_dirty_),
+ : bit_field_(
+ IsUniqueFlag::encode(is_unique) |
+ ArraySize::encode(is_unique ? 0 : other.Attributes().size()) |
+ PresentationAttributeStyleIsDirty::encode(
+ other.bit_field_.get<PresentationAttributeStyleIsDirty>()) |
+ StyleAttributeIsDirty::encode(
+ other.bit_field_.get<StyleAttributeIsDirty>()) |
+ AnimatedSvgAttributesAreDirty::encode(
+ other.bit_field_.get<AnimatedSvgAttributesAreDirty>())),
class_names_(other.class_names_),
id_for_style_resolution_(other.id_for_style_resolution_) {
// NOTE: The inline style is copied by the subclass copy constructor since we
@@ -111,24 +111,25 @@ bool ElementData::IsEquivalent(const ElementData* other) const {
}
void ElementData::Trace(Visitor* visitor) {
- if (auto* unique_element_data = DynamicTo<UniqueElementData>(this))
- unique_element_data->TraceAfterDispatch(visitor);
- else
- To<ShareableElementData>(this)->TraceAfterDispatch(visitor);
+ if (bit_field_.get_concurrently<IsUniqueFlag>()) {
+ static_cast<UniqueElementData*>(this)->TraceAfterDispatch(visitor);
+ } else {
+ static_cast<ShareableElementData*>(this)->TraceAfterDispatch(visitor);
+ }
}
-void ElementData::TraceAfterDispatch(blink::Visitor* visitor) {
+void ElementData::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(inline_style_);
}
ShareableElementData::ShareableElementData(const Vector<Attribute>& attributes)
: ElementData(attributes.size()) {
- for (unsigned i = 0; i < array_size_; ++i)
+ for (unsigned i = 0; i < bit_field_.get<ArraySize>(); ++i)
new (&attribute_array_[i]) Attribute(attributes[i]);
}
ShareableElementData::~ShareableElementData() {
- for (unsigned i = 0; i < array_size_; ++i)
+ for (unsigned i = 0; i < bit_field_.get<ArraySize>(); ++i)
attribute_array_[i].~Attribute();
}
@@ -140,7 +141,7 @@ ShareableElementData::ShareableElementData(const UniqueElementData& other)
inline_style_ = other.inline_style_->ImmutableCopyIfNeeded();
}
- for (unsigned i = 0; i < array_size_; ++i)
+ for (unsigned i = 0; i < bit_field_.get<ArraySize>(); ++i)
new (&attribute_array_[i]) Attribute(other.attribute_vector_.at(i));
}
@@ -182,7 +183,7 @@ ShareableElementData* UniqueElementData::MakeShareableCopy() const {
*this);
}
-void UniqueElementData::TraceAfterDispatch(blink::Visitor* visitor) {
+void UniqueElementData::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(presentation_attribute_style_);
ElementData::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 a3b87797d0b..bda30301170 100644
--- a/chromium/third_party/blink/renderer/core/dom/element_data.h
+++ b/chromium/third_party/blink/renderer/core/dom/element_data.h
@@ -37,6 +37,7 @@
#include "third_party/blink/renderer/core/dom/attribute_collection.h"
#include "third_party/blink/renderer/core/dom/space_split_string.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/wtf/bit_field.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
@@ -78,23 +79,55 @@ class ElementData : public GarbageCollected<ElementData> {
bool IsEquivalent(const ElementData* other) const;
- bool IsUnique() const { return is_unique_; }
+ bool IsUnique() const { return bit_field_.get<IsUniqueFlag>(); }
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
void Trace(Visitor*);
protected:
+ using BitField = WTF::ConcurrentlyReadBitField<uint32_t>;
+ using IsUniqueFlag =
+ BitField::DefineFirstValue<bool, 1, WTF::BitFieldValueConstness::kConst>;
+ using ArraySize = IsUniqueFlag::
+ DefineNextValue<uint32_t, 28, WTF::BitFieldValueConstness::kConst>;
+ using PresentationAttributeStyleIsDirty = ArraySize::DefineNextValue<bool, 1>;
+ using StyleAttributeIsDirty =
+ PresentationAttributeStyleIsDirty::DefineNextValue<bool, 1>;
+ using AnimatedSvgAttributesAreDirty =
+ StyleAttributeIsDirty::DefineNextValue<bool, 1>;
+
ElementData();
explicit ElementData(unsigned array_size);
ElementData(const ElementData&, bool is_unique);
- // Keep the type in a bitfield instead of using virtual destructors to avoid
- // adding a vtable.
- unsigned is_unique_ : 1;
- unsigned array_size_ : 28;
- mutable unsigned presentation_attribute_style_is_dirty_ : 1;
- mutable unsigned style_attribute_is_dirty_ : 1;
- mutable unsigned animated_svg_attributes_are_dirty_ : 1;
+ bool presentation_attribute_style_is_dirty() const {
+ return bit_field_.get<PresentationAttributeStyleIsDirty>();
+ }
+ bool style_attribute_is_dirty() const {
+ return bit_field_.get<StyleAttributeIsDirty>();
+ }
+ bool animated_svg_attributes_are_dirty() const {
+ return bit_field_.get<AnimatedSvgAttributesAreDirty>();
+ }
+
+ // Following 3 fields are meant to be mutable and can change even when const.
+ void SetPresentationAttributeStyleIsDirty(
+ bool presentation_attribute_style_is_dirty) const {
+ const_cast<BitField*>(&bit_field_)
+ ->set<PresentationAttributeStyleIsDirty>(
+ presentation_attribute_style_is_dirty);
+ }
+ void SetStyleAttributeIsDirty(bool style_attribute_is_dirty) const {
+ const_cast<BitField*>(&bit_field_)
+ ->set<StyleAttributeIsDirty>(style_attribute_is_dirty);
+ }
+ void SetAnimatedSvgAttributesAreDirty(
+ bool animated_svg_attributes_are_dirty) const {
+ const_cast<BitField*>(&bit_field_)
+ ->set<AnimatedSvgAttributesAreDirty>(animated_svg_attributes_are_dirty);
+ }
+
+ BitField bit_field_;
mutable Member<CSSPropertyValueSet> inline_style_;
mutable SpaceSplitString class_names_;
@@ -105,6 +138,8 @@ class ElementData : public GarbageCollected<ElementData> {
friend class ShareableElementData;
friend class UniqueElementData;
friend class SVGElement;
+ friend struct DowncastTraits<UniqueElementData>;
+ friend struct DowncastTraits<ShareableElementData>;
UniqueElementData* MakeUniqueCopy() const;
};
@@ -127,7 +162,7 @@ class ShareableElementData final : public ElementData {
explicit ShareableElementData(const UniqueElementData&);
~ShareableElementData();
- void TraceAfterDispatch(blink::Visitor* visitor) {
+ void TraceAfterDispatch(blink::Visitor* visitor) const {
ElementData::TraceAfterDispatch(visitor);
}
@@ -138,7 +173,9 @@ class ShareableElementData final : public ElementData {
template <>
struct DowncastTraits<ShareableElementData> {
- static bool AllowFrom(const ElementData& data) { return !data.IsUnique(); }
+ static bool AllowFrom(const ElementData& data) {
+ return !data.bit_field_.get<ElementData::IsUniqueFlag>();
+ }
};
#if defined(COMPILER_MSVC)
@@ -162,7 +199,7 @@ class UniqueElementData final : public ElementData {
explicit UniqueElementData(const ShareableElementData&);
explicit UniqueElementData(const UniqueElementData&);
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
// FIXME: We might want to support sharing element data for elements with
// presentation attribute style. Lots of table cells likely have the same
@@ -174,12 +211,14 @@ class UniqueElementData final : public ElementData {
template <>
struct DowncastTraits<UniqueElementData> {
- static bool AllowFrom(const ElementData& data) { return data.IsUnique(); }
+ static bool AllowFrom(const ElementData& data) {
+ return data.bit_field_.get<ElementData::IsUniqueFlag>();
+ }
};
inline const CSSPropertyValueSet* ElementData::PresentationAttributeStyle()
const {
- if (!is_unique_)
+ if (!bit_field_.get<IsUniqueFlag>())
return nullptr;
return To<UniqueElementData>(this)->presentation_attribute_style_.Get();
}
@@ -191,7 +230,7 @@ inline AttributeCollection ElementData::Attributes() const {
}
inline AttributeCollection ShareableElementData::Attributes() const {
- return AttributeCollection(attribute_array_, array_size_);
+ return AttributeCollection(attribute_array_, bit_field_.get<ArraySize>());
}
inline AttributeCollection UniqueElementData::Attributes() const {
diff --git a/chromium/third_party/blink/renderer/core/dom/element_rare_data.cc b/chromium/third_party/blink/renderer/core/dom/element_rare_data.cc
index ca9b48e74f8..0f6056b71e0 100644
--- a/chromium/third_party/blink/renderer/core/dom/element_rare_data.cc
+++ b/chromium/third_party/blink/renderer/core/dom/element_rare_data.cc
@@ -47,9 +47,7 @@ struct SameSizeAsElementRareData : NodeRareData {
};
ElementRareData::ElementRareData(NodeRenderingData* node_layout_data)
- : NodeRareData(node_layout_data), class_list_(nullptr) {
- is_element_rare_data_ = true;
-}
+ : NodeRareData(node_layout_data, true), class_list_(nullptr) {}
ElementRareData::~ElementRareData() {
DCHECK(!pseudo_element_data_);
@@ -95,7 +93,7 @@ ElementInternals& ElementRareData::EnsureElementInternals(HTMLElement& target) {
return *element_internals_;
}
-void ElementRareData::TraceAfterDispatch(blink::Visitor* visitor) {
+void ElementRareData::TraceAfterDispatch(blink::Visitor* visitor) const {
visitor->Trace(dataset_);
visitor->Trace(class_list_);
visitor->Trace(part_);
diff --git a/chromium/third_party/blink/renderer/core/dom/element_rare_data.h b/chromium/third_party/blink/renderer/core/dom/element_rare_data.h
index c105ed22f15..21c5a80acac 100644
--- a/chromium/third_party/blink/renderer/core/dom/element_rare_data.h
+++ b/chromium/third_party/blink/renderer/core/dom/element_rare_data.h
@@ -58,6 +58,7 @@ class ElementRareData : public NodeRareData {
void SetPseudoElement(PseudoId, PseudoElement*);
PseudoElement* GetPseudoElement(PseudoId) const;
+ PseudoElementData::PseudoElementVector GetPseudoElements() const;
void SetTabIndexExplicitly() {
SetElementFlag(ElementFlags::kTabIndexWasSetExplicitly, true);
@@ -191,11 +192,9 @@ class ElementRareData : public NodeRareData {
}
ResizeObserverDataMap& EnsureResizeObserverData();
- DisplayLockContext* EnsureDisplayLockContext(Element* element,
- ExecutionContext* context) {
+ DisplayLockContext* EnsureDisplayLockContext(Element* element) {
if (!display_lock_context_) {
- display_lock_context_ =
- MakeGarbageCollected<DisplayLockContext>(element, context);
+ display_lock_context_ = MakeGarbageCollected<DisplayLockContext>(element);
}
return display_lock_context_.Get();
}
@@ -206,7 +205,7 @@ class ElementRareData : public NodeRareData {
const AtomicString& GetNonce() const { return nonce_; }
void SetNonce(const AtomicString& nonce) { nonce_ = nonce; }
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
private:
ScrollOffset saved_layer_scroll_offset_;
@@ -274,6 +273,13 @@ inline PseudoElement* ElementRareData::GetPseudoElement(
return pseudo_element_data_->GetPseudoElement(pseudo_id);
}
+inline PseudoElementData::PseudoElementVector
+ElementRareData::GetPseudoElements() const {
+ if (!pseudo_element_data_)
+ return {};
+ return pseudo_element_data_->GetPseudoElements();
+}
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_ELEMENT_RARE_DATA_H_
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 8ab66b130d1..83346d25b0b 100644
--- a/chromium/third_party/blink/renderer/core/dom/element_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/element_test.cc
@@ -30,8 +30,7 @@ TEST_F(ElementTest, SupportsFocus) {
Document& document = GetDocument();
DCHECK(IsA<HTMLHtmlElement>(document.documentElement()));
document.setDesignMode("on");
- document.View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ document.View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
EXPECT_TRUE(document.documentElement()->SupportsFocus())
<< "<html> with designMode=on should be focusable.";
}
@@ -66,8 +65,7 @@ TEST_F(ElementTest,
// Insert a new <div> above the sticky. This will dirty layout and invalidate
// the sticky constraints.
- writer->SetInnerHTMLFromString(
- "<div style='height: 100px; width: 700px;'></div>");
+ writer->setInnerHTML("<div style='height: 100px; width: 700px;'></div>");
EXPECT_EQ(DocumentLifecycle::kVisualUpdatePending,
document.Lifecycle().GetState());
@@ -111,8 +109,7 @@ TEST_F(ElementTest, OffsetTopAndLeftCorrectForStickyElementsAfterInsertion) {
// Insert a new <div> above the sticky. This will dirty layout and invalidate
// the sticky constraints.
- writer->SetInnerHTMLFromString(
- "<div style='height: 100px; width: 700px;'></div>");
+ writer->setInnerHTML("<div style='height: 100px; width: 700px;'></div>");
EXPECT_EQ(DocumentLifecycle::kVisualUpdatePending,
document.Lifecycle().GetState());
@@ -126,8 +123,7 @@ TEST_F(ElementTest, OffsetTopAndLeftCorrectForStickyElementsAfterInsertion) {
->NeedsCompositingInputsUpdate());
// Dirty layout again, since |OffsetTop| will have cleaned it.
- writer->SetInnerHTMLFromString(
- "<div style='height: 100px; width: 700px;'></div>");
+ writer->setInnerHTML("<div style='height: 100px; width: 700px;'></div>");
EXPECT_EQ(DocumentLifecycle::kVisualUpdatePending,
document.Lifecycle().GetState());
@@ -169,8 +165,7 @@ TEST_F(ElementTest, BoundsInViewportCorrectForStickyElementsAfterInsertion) {
// Insert a new <div> above the sticky. This will dirty layout and invalidate
// the sticky constraints.
- writer->SetInnerHTMLFromString(
- "<div style='height: 100px; width: 700px;'></div>");
+ writer->setInnerHTML("<div style='height: 100px; width: 700px;'></div>");
EXPECT_EQ(DocumentLifecycle::kVisualUpdatePending,
document.Lifecycle().GetState());
@@ -224,8 +219,7 @@ TEST_F(ElementTest, StickySubtreesAreTrackedCorrectly) {
// ensure that the sticky subtree update behavior survives forking.
document.getElementById("child")->SetInlineStyleProperty(
CSSPropertyID::kWebkitRubyPosition, CSSValueID::kAfter);
- document.View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ document.View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
EXPECT_EQ(DocumentLifecycle::kPaintClean, document.Lifecycle().GetState());
EXPECT_EQ(RubyPosition::kBefore, outer_sticky->StyleRef().GetRubyPosition());
@@ -247,8 +241,7 @@ TEST_F(ElementTest, StickySubtreesAreTrackedCorrectly) {
// fork it's StyleRareInheritedData to maintain the sticky subtree bit.
document.getElementById("outerSticky")
->SetInlineStyleProperty(CSSPropertyID::kPosition, CSSValueID::kStatic);
- document.View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ document.View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
EXPECT_EQ(DocumentLifecycle::kPaintClean, document.Lifecycle().GetState());
EXPECT_FALSE(outer_sticky->StyleRef().SubtreeIsSticky());
@@ -469,11 +462,6 @@ TEST_F(ElementTest, OptionElementDisplayNoneComputedStyle) {
EXPECT_FALSE(document.getElementById("inner-option")->GetComputedStyle());
}
-template <>
-struct DowncastTraits<HTMLPlugInElement> {
- static bool AllowFrom(const Node& n) { return IsHTMLPlugInElement(n); }
-};
-
// A fake plugin which will assert that script is allowed in Destroy.
class ScriptOnDestroyPlugin : public GarbageCollected<ScriptOnDestroyPlugin>,
public WebPlugin {
@@ -488,16 +476,16 @@ class ScriptOnDestroyPlugin : public GarbageCollected<ScriptOnDestroyPlugin>,
}
WebPluginContainer* Container() const override { return container_; }
- void UpdateAllLifecyclePhases(WebWidget::LifecycleUpdateReason) override {}
+ void UpdateAllLifecyclePhases(DocumentUpdateReason) override {}
void Paint(cc::PaintCanvas*, const WebRect&) override {}
void UpdateGeometry(const WebRect&,
const WebRect&,
const WebRect&,
bool) override {}
- void UpdateFocus(bool, WebFocusType) override {}
+ void UpdateFocus(bool, mojom::blink::FocusType) override {}
void UpdateVisibility(bool) override {}
WebInputEventResult HandleInputEvent(const WebCoalescedInputEvent&,
- WebCursorInfo&) override {
+ ui::Cursor*) override {
return {};
}
void DidReceiveResponse(const WebURLResponse&) override {}
@@ -505,7 +493,7 @@ class ScriptOnDestroyPlugin : public GarbageCollected<ScriptOnDestroyPlugin>,
void DidFinishLoading() override {}
void DidFailLoading(const WebURLError&) override {}
- void Trace(blink::Visitor*) {}
+ void Trace(Visitor*) {}
bool DestroyCalled() const { return destroy_called_; }
diff --git a/chromium/third_party/blink/renderer/core/dom/element_traversal.h b/chromium/third_party/blink/renderer/core/dom/element_traversal.h
index 9c203350a96..1754eba2cb2 100644
--- a/chromium/third_party/blink/renderer/core/dom/element_traversal.h
+++ b/chromium/third_party/blink/renderer/core/dom/element_traversal.h
@@ -131,6 +131,13 @@ class Traversal {
}
template <typename MatchFunc>
static ElementType* FirstWithin(const ContainerNode&, MatchFunc);
+
+ static ElementType* InclusiveFirstWithin(Node& current) {
+ if (IsElementOfType<const ElementType>(current))
+ return To<ElementType>(&current);
+ return FirstWithin(current);
+ }
+
static ElementType* LastWithin(const ContainerNode& current) {
return LastWithinTemplate(current);
}
@@ -288,7 +295,7 @@ inline ElementType* Traversal<ElementType>::FirstChildTemplate(
Node* node = current.firstChild();
while (node && !IsElementOfType<const ElementType>(*node))
node = node->nextSibling();
- return ToElement<ElementType>(node);
+ return To<ElementType>(node);
}
template <class ElementType>
@@ -307,7 +314,7 @@ inline ElementType* Traversal<ElementType>::FirstAncestor(const Node& current) {
ContainerNode* ancestor = current.parentNode();
while (ancestor && !IsElementOfType<const ElementType>(*ancestor))
ancestor = ancestor->parentNode();
- return ToElement<ElementType>(ancestor);
+ return To<ElementType>(ancestor);
}
template <class ElementType>
@@ -315,7 +322,7 @@ template <class NodeType>
inline ElementType* Traversal<ElementType>::FirstAncestorOrSelfTemplate(
NodeType& current) {
if (IsElementOfType<const ElementType>(current))
- return &ToElement<ElementType>(current);
+ return &To<ElementType>(current);
return FirstAncestor(current);
}
@@ -326,7 +333,7 @@ inline ElementType* Traversal<ElementType>::LastChildTemplate(
Node* node = current.lastChild();
while (node && !IsElementOfType<const ElementType>(*node))
node = node->previousSibling();
- return ToElement<ElementType>(node);
+ return To<ElementType>(node);
}
template <class ElementType>
@@ -347,7 +354,7 @@ inline ElementType* Traversal<ElementType>::FirstWithinTemplate(
Node* node = current.firstChild();
while (node && !IsElementOfType<const ElementType>(*node))
node = NodeTraversal::Next(*node, &current);
- return ToElement<ElementType>(node);
+ return To<ElementType>(node);
}
template <class ElementType>
@@ -368,7 +375,7 @@ inline ElementType* Traversal<ElementType>::LastWithinTemplate(
Node* node = NodeTraversal::LastWithin(current);
while (node && !IsElementOfType<const ElementType>(*node))
node = NodeTraversal::Previous(*node, &current);
- return ToElement<ElementType>(node);
+ return To<ElementType>(node);
}
template <class ElementType>
@@ -396,7 +403,7 @@ inline ElementType* Traversal<ElementType>::NextTemplate(NodeType& current) {
Node* node = NodeTraversal::Next(current);
while (node && !IsElementOfType<const ElementType>(*node))
node = NodeTraversal::Next(*node);
- return ToElement<ElementType>(node);
+ return To<ElementType>(node);
}
template <class ElementType>
@@ -407,7 +414,7 @@ inline ElementType* Traversal<ElementType>::NextTemplate(
Node* node = NodeTraversal::Next(current, stay_within);
while (node && !IsElementOfType<const ElementType>(*node))
node = NodeTraversal::Next(*node, stay_within);
- return ToElement<ElementType>(node);
+ return To<ElementType>(node);
}
template <class ElementType>
@@ -426,7 +433,7 @@ inline ElementType* Traversal<ElementType>::Previous(const Node& current) {
Node* node = NodeTraversal::Previous(current);
while (node && !IsElementOfType<const ElementType>(*node))
node = NodeTraversal::Previous(*node);
- return ToElement<ElementType>(node);
+ return To<ElementType>(node);
}
template <class ElementType>
@@ -435,7 +442,7 @@ inline ElementType* Traversal<ElementType>::Previous(const Node& current,
Node* node = NodeTraversal::Previous(current, stay_within);
while (node && !IsElementOfType<const ElementType>(*node))
node = NodeTraversal::Previous(*node, stay_within);
- return ToElement<ElementType>(node);
+ return To<ElementType>(node);
}
template <class ElementType>
@@ -456,7 +463,7 @@ inline ElementType* Traversal<ElementType>::NextSkippingChildren(
Node* node = NodeTraversal::NextSkippingChildren(current);
while (node && !IsElementOfType<const ElementType>(*node))
node = NodeTraversal::NextSkippingChildren(*node);
- return ToElement<ElementType>(node);
+ return To<ElementType>(node);
}
template <class ElementType>
@@ -466,7 +473,7 @@ inline ElementType* Traversal<ElementType>::NextSkippingChildren(
Node* node = NodeTraversal::NextSkippingChildren(current, stay_within);
while (node && !IsElementOfType<const ElementType>(*node))
node = NodeTraversal::NextSkippingChildren(*node, stay_within);
- return ToElement<ElementType>(node);
+ return To<ElementType>(node);
}
template <class ElementType>
@@ -476,7 +483,7 @@ inline ElementType* Traversal<ElementType>::PreviousIncludingPseudo(
Node* node = NodeTraversal::PreviousIncludingPseudo(current, stay_within);
while (node && !IsElementOfType<const ElementType>(*node))
node = NodeTraversal::PreviousIncludingPseudo(*node, stay_within);
- return ToElement<ElementType>(node);
+ return To<ElementType>(node);
}
template <class ElementType>
@@ -486,7 +493,7 @@ inline ElementType* Traversal<ElementType>::NextIncludingPseudo(
Node* node = NodeTraversal::NextIncludingPseudo(current, stay_within);
while (node && !IsElementOfType<const ElementType>(*node))
node = NodeTraversal::NextIncludingPseudo(*node, stay_within);
- return ToElement<ElementType>(node);
+ return To<ElementType>(node);
}
template <class ElementType>
@@ -498,7 +505,7 @@ inline ElementType* Traversal<ElementType>::NextIncludingPseudoSkippingChildren(
while (node && !IsElementOfType<const ElementType>(*node))
node =
NodeTraversal::NextIncludingPseudoSkippingChildren(*node, stay_within);
- return ToElement<ElementType>(node);
+ return To<ElementType>(node);
}
template <class ElementType>
@@ -507,7 +514,7 @@ inline ElementType* Traversal<ElementType>::PseudoAwarePreviousSibling(
Node* node = current.PseudoAwarePreviousSibling();
while (node && !IsElementOfType<const ElementType>(*node))
node = node->PseudoAwarePreviousSibling();
- return ToElement<ElementType>(node);
+ return To<ElementType>(node);
}
template <class ElementType>
@@ -516,7 +523,7 @@ inline ElementType* Traversal<ElementType>::PreviousSibling(
Node* node = current.previousSibling();
while (node && !IsElementOfType<const ElementType>(*node))
node = node->previousSibling();
- return ToElement<ElementType>(node);
+ return To<ElementType>(node);
}
template <class ElementType>
@@ -535,7 +542,7 @@ inline ElementType* Traversal<ElementType>::NextSibling(const Node& current) {
Node* node = current.nextSibling();
while (node && !IsElementOfType<const ElementType>(*node))
node = node->nextSibling();
- return ToElement<ElementType>(node);
+ return To<ElementType>(node);
}
template <class ElementType>
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 321db436341..1eb95afb2c8 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
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_ADD_EVENT_LISTENER_OPTIONS_RESOLVED_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_ADD_EVENT_LISTENER_OPTIONS_RESOLVED_H_
-#include "third_party/blink/renderer/core/dom/events/add_event_listener_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_add_event_listener_options.h"
namespace blink {
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 447a53e79f4..95b79fbcd94 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
@@ -25,6 +25,7 @@
#include "third_party/blink/renderer/core/dom/events/custom_event.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_custom_event_init.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
namespace blink {
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 3cce5f21cd8..f456e3d543f 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
@@ -28,11 +28,12 @@
#include "third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/dom/events/custom_event_init.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
namespace blink {
+class CustomEventInit;
+
class CORE_EXPORT CustomEvent final : public Event {
DEFINE_WRAPPERTYPEINFO();
diff --git a/chromium/third_party/blink/renderer/core/dom/events/custom_event.idl b/chromium/third_party/blink/renderer/core/dom/events/custom_event.idl
index 2ae3973b317..0bb00fd08d1 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/custom_event.idl
+++ b/chromium/third_party/blink/renderer/core/dom/events/custom_event.idl
@@ -26,10 +26,9 @@
// https://dom.spec.whatwg.org/#interface-customevent
[
- Constructor(DOMString type, optional CustomEventInit eventInitDict),
- ConstructorCallWith=ScriptState,
Exposed=(Window,Worker)
] interface CustomEvent : Event {
+ [CallWith=ScriptState] constructor(DOMString type, optional CustomEventInit eventInitDict = {});
[CallWith=ScriptState] readonly attribute any detail;
[Measure, CallWith=ScriptState] void initCustomEvent(DOMString type, optional boolean bubbles = false, optional boolean cancelable = false, optional any detail = null);
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 47ee4071da3..1e5f4e14e3c 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event.cc
+++ b/chromium/third_party/blink/renderer/core/dom/events/event.cc
@@ -32,7 +32,6 @@
#include "third_party/blink/renderer/core/events/mouse_event.h"
#include "third_party/blink/renderer/core/events/pointer_event.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
-#include "third_party/blink/renderer/core/frame/hosts_using_features.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/svg/svg_element.h"
@@ -273,20 +272,20 @@ void Event::SetTarget(EventTarget* target) {
}
void Event::SetRelatedTargetIfExists(EventTarget* related_target) {
- if (IsMouseEvent()) {
- ToMouseEvent(this)->SetRelatedTarget(related_target);
- } else if (IsPointerEvent()) {
- ToPointerEvent(this)->SetRelatedTarget(related_target);
- } else if (IsFocusEvent()) {
- ToFocusEvent(this)->SetRelatedTarget(related_target);
+ if (auto* mouse_event = DynamicTo<MouseEvent>(this)) {
+ mouse_event->SetRelatedTarget(related_target);
+ } else if (auto* pointer_event = DynamicTo<PointerEvent>(this)) {
+ pointer_event->SetRelatedTarget(related_target);
+ } else if (auto* focus_event = DynamicTo<FocusEvent>(this)) {
+ focus_event->SetRelatedTarget(related_target);
}
}
void Event::ReceivedTarget() {}
-void Event::SetUnderlyingEvent(Event* ue) {
+void Event::SetUnderlyingEvent(const Event* ue) {
// Prohibit creation of a cycle -- just do nothing in that case.
- for (Event* e = ue; e; e = e->UnderlyingEvent())
+ for (const Event* e = ue; e; e = e->UnderlyingEvent())
if (e == this)
return;
underlying_event_ = ue;
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 650e935ca96..d261a7f2252 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event.h
+++ b/chromium/third_party/blink/renderer/core/dom/events/event.h
@@ -249,11 +249,11 @@ class CORE_EXPORT Event : public ScriptWrappable {
}
void setCancelBubble(ScriptState*, bool);
- Event* UnderlyingEvent() const { return underlying_event_.Get(); }
- void SetUnderlyingEvent(Event*);
+ const Event* UnderlyingEvent() const { return underlying_event_.Get(); }
+ void SetUnderlyingEvent(const Event*);
bool HasEventPath() { return event_path_; }
- EventPath& GetEventPath() {
+ EventPath& GetEventPath() const {
DCHECK(event_path_);
return *event_path_;
}
@@ -355,7 +355,7 @@ class CORE_EXPORT Event : public ScriptWrappable {
Member<EventTarget> current_target_;
Member<EventTarget> target_;
- Member<Event> underlying_event_;
+ Member<const Event> underlying_event_;
Member<EventPath> event_path_;
// The monotonic platform time in seconds, for input events it is the
// event timestamp provided by the host OS and reported in the original
@@ -363,10 +363,6 @@ class CORE_EXPORT Event : public ScriptWrappable {
base::TimeTicks platform_time_stamp_;
};
-#define DEFINE_EVENT_TYPE_CASTS(typeName) \
- DEFINE_TYPE_CASTS(typeName, Event, event, event->Is##typeName(), \
- event.Is##typeName())
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_EVENT_H_
diff --git a/chromium/third_party/blink/renderer/core/dom/events/event.idl b/chromium/third_party/blink/renderer/core/dom/events/event.idl
index 85e3cab97e0..88b05a48924 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event.idl
+++ b/chromium/third_party/blink/renderer/core/dom/events/event.idl
@@ -21,9 +21,9 @@
// https://dom.spec.whatwg.org/#interface-event
[
- Constructor(DOMString type, optional EventInit eventInitDict),
Exposed=(Window,Worker,AudioWorklet)
] interface Event {
+ constructor(DOMString type, optional EventInit eventInitDict = {});
readonly attribute DOMString type;
readonly attribute EventTarget? target;
readonly attribute EventTarget? currentTarget;
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 67441a59665..dc55e6a462a 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
@@ -64,7 +64,7 @@ DispatchEventResult EventDispatcher::DispatchEvent(Node& node, Event& event) {
}
EventDispatcher::EventDispatcher(Node& node, Event& event)
- : node_(node), event_(event) {
+ : node_(&node), event_(&event) {
view_ = node.GetDocument().View();
event_->InitEventPath(*node_);
}
@@ -78,7 +78,7 @@ void EventDispatcher::DispatchScopedEvent(Node& node, Event& event) {
void EventDispatcher::DispatchSimulatedClick(
Node& node,
- Event* underlying_event,
+ const Event* underlying_event,
SimulatedClickMouseEventOptions mouse_event_options,
SimulatedClickCreationScope creation_scope) {
// This persistent vector doesn't cause leaks, because added Nodes are removed
@@ -140,8 +140,8 @@ DispatchEventResult EventDispatcher::Dispatch() {
event_dispatched_ = true;
#endif
if (GetEvent().GetEventPath().IsEmpty()) {
- // eventPath() can be empty if event path is shrinked by relataedTarget
- // retargeting.
+ // eventPath() can be empty if relatedTarget retargeting has shrunk the
+ // path.
return DispatchEventResult::kNotCanceled;
}
std::unique_ptr<EventTiming> eventTiming;
@@ -159,7 +159,8 @@ DispatchEventResult EventDispatcher::Dispatch() {
// A genuine mouse click cannot be triggered by script so we don't expect
// there are any script in the stack.
DCHECK(!frame->GetAdTracker() ||
- !frame->GetAdTracker()->IsAdScriptInStack());
+ !frame->GetAdTracker()->IsAdScriptInStack(
+ AdTracker::StackType::kBottomAndTop));
if (frame->IsAdSubframe()) {
UseCounter::Count(document, WebFeature::kAdClick);
}
@@ -202,9 +203,6 @@ DispatchEventResult EventDispatcher::Dispatch() {
pre_dispatch_event_handler_result) ==
kContinueDispatching) {
if (DispatchEventAtCapturing() == kContinueDispatching) {
- // TODO(crbug/882574): Remove these.
- CHECK(event_->HasEventPath());
- CHECK(!event_->GetEventPath().IsEmpty());
if (DispatchEventAtTarget() == kContinueDispatching)
DispatchEventAtBubbling();
}
@@ -309,8 +307,9 @@ inline void EventDispatcher::DispatchEventPostProcess(
// 17. Set event’s currentTarget attribute to null.
event_->SetCurrentTarget(nullptr);
- bool is_click = event_->IsMouseEvent() &&
- ToMouseEvent(*event_).type() == event_type_names::kClick;
+ auto* mouse_event = DynamicTo<MouseEvent>(event_);
+ bool is_click =
+ mouse_event && mouse_event->type() == event_type_names::kClick;
if (is_click) {
// Fire an accessibility event indicating a node was clicked on. This is
// safe if event_->target()->ToNode() returns null.
@@ -347,10 +346,8 @@ inline void EventDispatcher::DispatchEventPostProcess(
// Call default event handlers. While the DOM does have a concept of
// preventing default handling, the detail of which handlers are called is an
// internal implementation detail and not part of the DOM.
- if (event_->defaultPrevented()) {
- if (activation_target)
- activation_target->DidPreventDefault(*event_);
- } else if (!event_->DefaultHandled() && is_trusted_or_click) {
+ if (!event_->defaultPrevented() && !event_->DefaultHandled() &&
+ is_trusted_or_click) {
// Non-bubbling events call only one default event handler, the one for the
// target.
node_->DefaultEventHandler(*event_);
@@ -368,10 +365,11 @@ inline void EventDispatcher::DispatchEventPostProcess(
}
}
+ auto* keyboard_event = DynamicTo<KeyboardEvent>(event_);
if (Page* page = node_->GetDocument().GetPage()) {
if (page->GetSettings().GetSpatialNavigationEnabled() &&
- is_trusted_or_click && event_->IsKeyboardEvent() &&
- ToKeyboardEvent(*event_).key() == "Enter" &&
+ is_trusted_or_click && keyboard_event &&
+ keyboard_event->key() == "Enter" &&
event_->type() == event_type_names::kKeyup) {
page->GetSpatialNavigationController().ResetEnterKeyState();
}
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 59eba27ca46..048327a6a80 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
@@ -56,7 +56,7 @@ class EventDispatcher {
static void DispatchScopedEvent(Node&, Event&);
static void DispatchSimulatedClick(Node&,
- Event* underlying_event,
+ const Event* underlying_event,
SimulatedClickMouseEventOptions,
SimulatedClickCreationScope);
@@ -76,9 +76,9 @@ class EventDispatcher {
void DispatchEventPostProcess(Node* activation_target,
EventDispatchHandlingState*);
- Member<Node> node_;
- Member<Event> event_;
- Member<LocalFrameView> view_;
+ Node* node_;
+ Event* event_;
+ LocalFrameView* view_;
#if DCHECK_IS_ON()
bool event_dispatched_ = false;
#endif
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 b3137fcb85e..1d59550227a 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
@@ -32,6 +32,8 @@
#include "third_party/blink/renderer/core/dom/events/event_listener_map.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_event_listener_options.h"
+#include "third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.h"
#include "third_party/blink/renderer/core/dom/events/event_listener.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
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 7121c9f06af..ae83fe10ce2 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
@@ -35,13 +35,12 @@
#include "base/macros.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.h"
-#include "third_party/blink/renderer/core/dom/events/event_listener_options.h"
#include "third_party/blink/renderer/core/dom/events/registered_event_listener.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string_hash.h"
namespace blink {
+class EventListenerOptions;
class EventTarget;
using EventListenerVector = HeapVector<RegisteredEventListener, 1>;
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 a0a24e1025f..419938ad5e9 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
@@ -36,7 +36,7 @@
namespace blink {
EventQueue::EventQueue(ExecutionContext* context, TaskType task_type)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
task_type_(task_type),
is_closed_(false) {
if (!GetExecutionContext() || GetExecutionContext()->IsContextDestroyed())
@@ -47,7 +47,7 @@ EventQueue::~EventQueue() = default;
void EventQueue::Trace(Visitor* visitor) {
visitor->Trace(queued_events_);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
bool EventQueue::EnqueueEvent(const base::Location& from_here, Event& event) {
@@ -105,8 +105,8 @@ void EventQueue::DispatchEvent(Event* event) {
target->DispatchEvent(*event);
}
-void EventQueue::ContextDestroyed(ExecutionContext* context) {
- Close(context);
+void EventQueue::ContextDestroyed() {
+ Close(GetExecutionContext());
}
void EventQueue::Close(ExecutionContext* context) {
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 c0d12674570..4c0f2995b2d 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
@@ -28,7 +28,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_EVENT_QUEUE_H_
#include "third_party/blink/public/platform/task_type.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/wtf/linked_hash_set.h"
namespace blink {
@@ -37,7 +37,7 @@ class Event;
class ExecutionContext;
class CORE_EXPORT EventQueue final : public GarbageCollected<EventQueue>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(EventQueue);
public:
@@ -53,7 +53,7 @@ class CORE_EXPORT EventQueue final : public GarbageCollected<EventQueue>,
bool RemoveEvent(Event&);
void DispatchEvent(Event*);
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
void Close(ExecutionContext*);
void DoCancelAllEvents(ExecutionContext*);
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 5d6f05dc435..2c506ac3266 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
@@ -40,6 +40,7 @@
#include "third_party/blink/renderer/bindings/core/v8/js_based_event_listener.h"
#include "third_party/blink/renderer/bindings/core/v8/js_event_listener.h"
#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
+#include "third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
#include "third_party/blink/renderer/core/dom/events/event_target_impl.h"
@@ -179,7 +180,7 @@ void CountFiringEventListeners(const Event& event,
}
if (CheckTypeThenUseCount(event, event_type_names::kPointerdown,
WebFeature::kPointerDownFired, document)) {
- if (event.IsPointerEvent() &&
+ if (IsA<PointerEvent>(event) &&
static_cast<const PointerEvent&>(event).pointerType() == "touch") {
UseCounter::Count(document, WebFeature::kPointerDownFiredForTouch);
}
@@ -212,24 +213,11 @@ void CountFiringEventListeners(const Event& event,
counted_event.feature, document))
return;
}
-
- if (event.eventPhase() == Event::kCapturingPhase ||
- event.eventPhase() == Event::kBubblingPhase) {
- if (CheckTypeThenUseCount(
- event, event_type_names::kDOMNodeRemoved,
- WebFeature::kDOMNodeRemovedEventListenedAtNonTarget, document))
- return;
- if (CheckTypeThenUseCount(
- event, event_type_names::kDOMNodeRemovedFromDocument,
- WebFeature::kDOMNodeRemovedFromDocumentEventListenedAtNonTarget,
- document))
- return;
- }
}
void RegisterWithScheduler(ExecutionContext* execution_context,
const AtomicString& event_type) {
- if (!execution_context)
+ if (!execution_context || !execution_context->GetScheduler())
return;
// TODO(altimin): Ideally we would also support tracking unregistration of
// event listeners, but we don't do this for performance reasons.
@@ -410,7 +398,7 @@ void EventTarget::SetDefaultAddEventListenerOptions(
WebFeature::kSmoothScrollJSInterventionActivated);
executing_window->GetFrame()->Console().AddMessage(
- ConsoleMessage::Create(
+ MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kIntervention,
mojom::ConsoleMessageLevel::kWarning,
"Registering mousewheel event as passive due to "
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 9c3f2d35018..0963aaaab0a 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
@@ -37,7 +37,6 @@
#include "base/macros.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/core/core_export.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_result.h"
#include "third_party/blink/renderer/core/dom/events/event_listener_map.h"
#include "third_party/blink/renderer/core/event_target_names.h"
@@ -50,6 +49,7 @@
namespace blink {
class AddEventListenerOptionsOrBoolean;
+class AddEventListenerOptionsResolved;
class DOMWindow;
class Event;
class EventListenerOptionsOrBoolean;
@@ -58,10 +58,10 @@ class ExecutionContext;
class LocalDOMWindow;
class MessagePort;
class Node;
+class PortalHost;
class ScriptState;
class ServiceWorker;
class V8EventListener;
-class PortalHost;
struct FiringEventIterator {
DISALLOW_NEW();
@@ -109,8 +109,8 @@ class CORE_EXPORT EventTargetData final
// file.
// - Override EventTarget::interfaceName() and getExecutionContext(). The former
// will typically return EventTargetNames::YourClassName. The latter will
-// return ContextLifecycleObserver::executionContext (if you are an
-// ContextLifecycleObserver)
+// return ExecutionContextLifecycleObserver::executionContext (if you are an
+// ExecutionContextLifecycleObserver)
// or the document you're in.
// - Your trace() method will need to call EventTargetWithInlineData::trace
// depending on the base class of your class.
diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_target.idl b/chromium/third_party/blink/renderer/core/dom/events/event_target.idl
index 9446764ac88..f80e0071488 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event_target.idl
+++ b/chromium/third_party/blink/renderer/core/dom/events/event_target.idl
@@ -22,12 +22,11 @@
[
CheckSecurity=Receiver,
- Constructor(),
- ConstructorCallWith=ScriptState,
Exposed=(Window,Worker,AudioWorklet),
ImmutablePrototype
] interface EventTarget {
- [Custom=CallPrologue] void addEventListener(DOMString type, EventListener? listener, optional (AddEventListenerOptions or boolean) options);
- [Custom=CallPrologue] void removeEventListener(DOMString type, EventListener? listener, optional (EventListenerOptions or boolean) options);
+ [CallWith=ScriptState] constructor();
+ void addEventListener(DOMString type, EventListener? listener, optional (AddEventListenerOptions or boolean) options);
+ void removeEventListener(DOMString type, EventListener? listener, optional (EventListenerOptions or boolean) options);
[ImplementedAs=dispatchEventForBindings, RaisesException, RuntimeCallStatsCounter=EventTargetDispatchEvent] boolean dispatchEvent(Event event);
};
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 005b8cd2a46..83a530add58 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
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/core/dom/events/event_target_impl.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+
namespace blink {
const AtomicString& EventTargetImpl::InterfaceName() const {
@@ -11,15 +13,15 @@ const AtomicString& EventTargetImpl::InterfaceName() const {
}
ExecutionContext* EventTargetImpl::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextClient::GetExecutionContext();
}
void EventTargetImpl::Trace(Visitor* visitor) {
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
EventTargetImpl::EventTargetImpl(ScriptState* script_state)
- : ContextLifecycleObserver(ExecutionContext::From(script_state)) {}
+ : ExecutionContextClient(ExecutionContext::From(script_state)) {}
} // namespace blink
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 d817811a70a..df9434937be 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
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_EVENT_TARGET_IMPL_H_
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
class ScriptState;
@@ -21,7 +21,7 @@ namespace blink {
// that are mostly unnecessary for them, resulting in a performance
// decrease.
class CORE_EXPORT EventTargetImpl final : public EventTargetWithInlineData,
- public ContextLifecycleObserver {
+ public ExecutionContextClient {
USING_GARBAGE_COLLECTED_MIXIN(EventTargetImpl);
public:
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 28fbb1ae8e2..8d0dd9bf75e 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
@@ -32,6 +32,7 @@
#include "third_party/blink/renderer/core/dom/static_node_list.h"
#include "third_party/blink/renderer/core/events/touch_event_context.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
@@ -82,7 +83,7 @@ HeapVector<Member<EventTarget>>& TreeScopeEventContext::EnsureEventPath(
TouchEventContext& TreeScopeEventContext::EnsureTouchEventContext() {
if (!touch_event_context_)
- touch_event_context_ = TouchEventContext::Create();
+ touch_event_context_ = MakeGarbageCollected<TouchEventContext>();
return *touch_event_context_;
}
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 d2571c6ee9a..219f5212afe 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
@@ -143,7 +143,7 @@ LayoutText* FirstLetterPseudoElement::FirstLetterTextLayoutObject(
first_letter_text_layout_object =
first_letter_text_layout_object->NextSibling();
} else if (first_letter_text_layout_object
- ->IsListMarkerIncludingNGInside()) {
+ ->IsListMarkerIncludingNGOutsideAndInside()) {
// 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.
@@ -166,7 +166,7 @@ LayoutText* FirstLetterPseudoElement::FirstLetterTextLayoutObject(
first_letter_text_layout_object->NextSibling();
} else if (first_letter_text_layout_object->IsAtomicInlineLevel() ||
first_letter_text_layout_object->IsLayoutButton() ||
- first_letter_text_layout_object->IsMenuList()) {
+ IsMenuList(first_letter_text_layout_object)) {
return nullptr;
} else if (first_letter_text_layout_object
->IsFlexibleBoxIncludingDeprecatedAndNG() ||
@@ -232,7 +232,7 @@ void FirstLetterPseudoElement::UpdateTextFragments() {
// Make sure the first-letter layoutObject is set to require a layout as it
// needs to re-create the line boxes. The remaining text layoutObject
// will be marked by the LayoutText::setText.
- child_fragment->SetNeedsLayoutAndPrefWidthsRecalc(
+ child_fragment->SetNeedsLayoutAndIntrinsicWidthsRecalc(
layout_invalidation_reason::kTextChanged);
break;
}
diff --git a/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal_test.cc b/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal_test.cc
index 718f61219e3..e880c282988 100644
--- a/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/flat_tree_traversal_test.cc
@@ -48,22 +48,22 @@ void FlatTreeTraversalTest::SetupSampleHTML(const char* main_html,
const char* shadow_html,
unsigned index) {
Element* body = GetDocument().body();
- body->SetInnerHTMLFromString(String::FromUTF8(main_html));
+ body->setInnerHTML(String::FromUTF8(main_html));
auto* shadow_host = To<Element>(NodeTraversal::ChildAt(*body, index));
ShadowRoot& shadow_root = shadow_host->CreateV0ShadowRootForTesting();
- shadow_root.SetInnerHTMLFromString(String::FromUTF8(shadow_html));
+ shadow_root.setInnerHTML(String::FromUTF8(shadow_html));
body->UpdateDistributionForFlatTreeTraversal();
}
void FlatTreeTraversalTest::SetupDocumentTree(const char* main_html) {
Element* body = GetDocument().body();
- body->SetInnerHTMLFromString(String::FromUTF8(main_html));
+ body->setInnerHTML(String::FromUTF8(main_html));
}
void FlatTreeTraversalTest::AttachV0ShadowRoot(Element& shadow_host,
const char* shadow_inner_html) {
ShadowRoot& shadow_root = shadow_host.CreateV0ShadowRootForTesting();
- shadow_root.SetInnerHTMLFromString(String::FromUTF8(shadow_inner_html));
+ shadow_root.setInnerHTML(String::FromUTF8(shadow_inner_html));
GetDocument().body()->UpdateDistributionForFlatTreeTraversal();
}
@@ -72,7 +72,7 @@ void FlatTreeTraversalTest::AttachOpenShadowRoot(
const char* shadow_inner_html) {
ShadowRoot& shadow_root =
shadow_host.AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString(String::FromUTF8(shadow_inner_html));
+ shadow_root.setInnerHTML(String::FromUTF8(shadow_inner_html));
GetDocument().body()->UpdateDistributionForFlatTreeTraversal();
}
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 e18c39445b1..c92b4ed1cd6 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
@@ -127,6 +127,14 @@ class GlobalEventHandlers {
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(touchstart, kTouchstart)
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(volumechange, kVolumechange)
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(waiting, kWaiting)
+ DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(webkitanimationend,
+ kWebkitAnimationEnd)
+ DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(webkitanimationiteration,
+ kWebkitAnimationIteration)
+ DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(webkitanimationstart,
+ kWebkitAnimationStart)
+ DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(webkittransitionend,
+ kWebkitTransitionEnd)
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(wheel, kWheel)
};
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 d4480cf6d8f..e5ea3133cd1 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
@@ -82,7 +82,7 @@
attribute EventHandler onplaying;
attribute EventHandler onprogress;
attribute EventHandler onratechange;
- [RuntimeEnabled=DisplayLocking] attribute EventHandler onrendersubtreeactivation;
+ [RuntimeEnabled=CSSSubtreeVisibilityActivationEvent] attribute EventHandler onrendersubtreeactivation;
attribute EventHandler onreset;
attribute EventHandler onresize;
attribute EventHandler onscroll;
@@ -98,6 +98,10 @@
attribute EventHandler ontoggle;
attribute EventHandler onvolumechange;
attribute EventHandler onwaiting;
+ attribute EventHandler onwebkitanimationend;
+ attribute EventHandler onwebkitanimationiteration;
+ attribute EventHandler onwebkitanimationstart;
+ attribute EventHandler onwebkittransitionend;
attribute EventHandler onwheel;
// auxclick
diff --git a/chromium/third_party/blink/renderer/core/dom/icon_url.cc b/chromium/third_party/blink/renderer/core/dom/icon_url.cc
index 38b41d01827..4b1476afcef 100644
--- a/chromium/third_party/blink/renderer/core/dom/icon_url.cc
+++ b/chromium/third_party/blink/renderer/core/dom/icon_url.cc
@@ -28,7 +28,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "third_party/blink/public/web/web_icon_url.h"
#include "third_party/blink/renderer/core/dom/icon_url.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
@@ -44,7 +43,8 @@ IconURL IconURL::DefaultFavicon(const KURL& document_url) {
url.SetPort(document_url.Port());
url.SetPath("/favicon.ico");
- IconURL result(url, Vector<IntSize>(), g_empty_string, kFavicon);
+ IconURL result(url, {}, g_empty_string,
+ mojom::blink::FaviconIconType::kFavicon);
result.is_default_icon_ = true;
return result;
}
@@ -56,9 +56,4 @@ bool operator==(const IconURL& lhs, const IconURL& rhs) {
lhs.mime_type_ == rhs.mime_type_;
}
-STATIC_ASSERT_ENUM(WebIconURL::kTypeInvalid, kInvalidIcon);
-STATIC_ASSERT_ENUM(WebIconURL::kTypeFavicon, kFavicon);
-STATIC_ASSERT_ENUM(WebIconURL::kTypeTouch, kTouchIcon);
-STATIC_ASSERT_ENUM(WebIconURL::kTypeTouchPrecomposed, kTouchPrecomposedIcon);
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/dom/icon_url.h b/chromium/third_party/blink/renderer/core/dom/icon_url.h
index 04f45144db5..9aa68b47662 100644
--- a/chromium/third_party/blink/renderer/core/dom/icon_url.h
+++ b/chromium/third_party/blink/renderer/core/dom/icon_url.h
@@ -31,33 +31,29 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_ICON_URL_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_ICON_URL_H_
-#include "third_party/blink/renderer/platform/geometry/int_size.h"
+#include "third_party/blink/public/mojom/favicon/favicon_url.mojom-blink.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "ui/gfx/geometry/size.h"
namespace blink {
-enum IconType {
- kInvalidIcon = 0,
- kFavicon = 1,
- kTouchIcon = 1 << 1,
- kTouchPrecomposedIcon = 1 << 2,
-};
-
struct IconURL {
DISALLOW_NEW();
- IconType icon_type_;
- Vector<IntSize> sizes_;
+ mojom::blink::FaviconIconType icon_type_;
+ Vector<gfx::Size> sizes_;
String mime_type_;
KURL icon_url_;
bool is_default_icon_;
- IconURL() : icon_type_(kInvalidIcon), is_default_icon_(false) {}
+ IconURL()
+ : icon_type_(mojom::blink::FaviconIconType::kInvalid),
+ is_default_icon_(false) {}
IconURL(const KURL& url,
- const Vector<IntSize>& sizes,
+ const Vector<gfx::Size>& sizes,
const String& mime_type,
- IconType type)
+ mojom::blink::FaviconIconType type)
: icon_type_(type),
sizes_(sizes),
mime_type_(mime_type),
diff --git a/chromium/third_party/blink/renderer/core/dom/idle_deadline_test.cc b/chromium/third_party/blink/renderer/core/dom/idle_deadline_test.cc
index 8116102c65a..71dc4d7e458 100644
--- a/chromium/third_party/blink/renderer/core/dom/idle_deadline_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/idle_deadline_test.cc
@@ -42,6 +42,9 @@ class MockIdleDeadlineScheduler final : public ThreadScheduler {
scoped_refptr<base::SingleThreadTaskRunner> IPCTaskRunner() override {
return nullptr;
}
+ scoped_refptr<base::SingleThreadTaskRunner> NonWakingTaskRunner() override {
+ return nullptr;
+ }
scoped_refptr<base::SingleThreadTaskRunner> DeprecatedDefaultTaskRunner()
override {
return nullptr;
diff --git a/chromium/third_party/blink/renderer/core/dom/layout_tree_builder.h b/chromium/third_party/blink/renderer/core/dom/layout_tree_builder.h
index 97047f10db2..ecbfb41c6dd 100644
--- a/chromium/third_party/blink/renderer/core/dom/layout_tree_builder.h
+++ b/chromium/third_party/blink/renderer/core/dom/layout_tree_builder.h
@@ -61,7 +61,7 @@ class LayoutTreeBuilder {
LayoutTreeBuilder(NodeType& node,
Node::AttachContext& context,
const ComputedStyle* style)
- : node_(node), context_(context), style_(style) {
+ : node_(&node), context_(context), style_(style) {
DCHECK(!node.GetLayoutObject());
DCHECK(node.GetDocument().InStyleRecalc());
DCHECK(node.InActiveDocument());
@@ -87,7 +87,7 @@ class LayoutTreeBuilder {
return next;
}
- Member<NodeType> node_;
+ NodeType* node_;
Node::AttachContext& context_;
const ComputedStyle* style_;
};
diff --git a/chromium/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.cc b/chromium/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.cc
index 031c54abae3..c023f6557b3 100644
--- a/chromium/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.cc
+++ b/chromium/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.cc
@@ -30,6 +30,7 @@
#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/layout/layout_object.h"
+#include "third_party/blink/renderer/core/layout/layout_view.h"
namespace blink {
@@ -344,7 +345,7 @@ LayoutObject* LayoutTreeBuilderTraversal::NextInTopLayer(
// If top_layer_elements[i] is not a LayoutView child, its LayoutObject is
// not re-attached and not in the top layer yet, thus we can not use it as a
// sibling LayoutObject.
- if (layout_object && layout_object->Parent()->IsLayoutView())
+ if (layout_object && IsA<LayoutView>(layout_object->Parent()))
return layout_object;
}
return nullptr;
diff --git a/chromium/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h b/chromium/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h
index 300be78ef8e..106020b85a9 100644
--- a/chromium/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h
+++ b/chromium/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h
@@ -59,7 +59,7 @@ class CORE_EXPORT LayoutTreeBuilderTraversal {
}
private:
- Member<const V0InsertionPoint> insertion_point_;
+ const V0InsertionPoint* insertion_point_;
};
static ContainerNode* Parent(const Node&, ParentDetails* = nullptr);
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 291c4d10e5a..13c0cdb2861 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
@@ -22,8 +22,6 @@
#include "third_party/blink/renderer/core/dom/live_node_list.h"
-#include "third_party/blink/renderer/core/dom/node_child_removal_tracker.h"
-
namespace blink {
namespace {
@@ -39,7 +37,7 @@ class IsMatch {
}
private:
- Member<const LiveNodeList> list_;
+ const LiveNodeList* list_;
};
} // namespace
@@ -57,12 +55,7 @@ unsigned LiveNodeList::length() const {
}
Element* LiveNodeList::item(unsigned offset) const {
- Element* element = collection_items_cache_.NodeAt(*this, offset);
- if (element && element->GetDocument().InDOMNodeRemovedHandler()) {
- if (NodeChildRemovalTracker::IsBeingRemoved(*element))
- GetDocument().CountDetachingNodeAccessInDOMNodeRemovedHandler();
- }
- return element;
+ return collection_items_cache_.NodeAt(*this, offset);
}
Element* LiveNodeList::TraverseToFirst() const {
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 37f27fe048d..af5bcea9f72 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
@@ -79,11 +79,12 @@ class CORE_EXPORT LiveNodeList : public NodeList, public LiveNodeListBase {
mutable CollectionItemsCache<LiveNodeList, Element> collection_items_cache_;
};
-DEFINE_TYPE_CASTS(LiveNodeList,
- LiveNodeListBase,
- list,
- IsLiveNodeListType(list->GetType()),
- IsLiveNodeListType(list.GetType()));
+template <>
+struct DowncastTraits<LiveNodeList> {
+ static bool AllowFrom(const LiveNodeListBase& list) {
+ return IsLiveNodeListType(list.GetType());
+ }
+};
inline void LiveNodeList::InvalidateCacheForAttribute(
const QualifiedName* attr_name) const {
diff --git a/chromium/third_party/blink/renderer/core/dom/live_node_list_base.cc b/chromium/third_party/blink/renderer/core/dom/live_node_list_base.cc
index 36c48183ddd..d60ec265eaf 100644
--- a/chromium/third_party/blink/renderer/core/dom/live_node_list_base.cc
+++ b/chromium/third_party/blink/renderer/core/dom/live_node_list_base.cc
@@ -31,9 +31,9 @@ namespace blink {
void LiveNodeListBase::InvalidateCacheForAttribute(
const QualifiedName* attr_name) const {
if (IsLiveNodeListType(GetType()))
- ToLiveNodeList(this)->InvalidateCacheForAttribute(attr_name);
+ To<LiveNodeList>(this)->InvalidateCacheForAttribute(attr_name);
else
- ToHTMLCollection(this)->InvalidateCacheForAttribute(attr_name);
+ To<HTMLCollection>(this)->InvalidateCacheForAttribute(attr_name);
}
ContainerNode& LiveNodeListBase::RootNode() const {
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 bc2775726de..24a4c117fe8 100644
--- a/chromium/third_party/blink/renderer/core/dom/mutation_observer.cc
+++ b/chromium/third_party/blink/renderer/core/dom/mutation_observer.cc
@@ -34,8 +34,8 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_mutation_callback.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mutation_observer_init.h"
#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/dom/mutation_observer_init.h"
#include "third_party/blink/renderer/core/dom/mutation_observer_registration.h"
#include "third_party/blink/renderer/core/dom/mutation_record.h"
#include "third_party/blink/renderer/core/dom/node.h"
@@ -50,7 +50,7 @@ namespace blink {
class MutationObserver::V8DelegateImpl final
: public MutationObserver::Delegate,
- public ContextClient {
+ public ExecutionContextClient {
USING_GARBAGE_COLLECTED_MIXIN(V8DelegateImpl);
public:
@@ -61,10 +61,10 @@ class MutationObserver::V8DelegateImpl final
V8DelegateImpl(V8MutationCallback* callback,
ExecutionContext* execution_context)
- : ContextClient(execution_context), callback_(callback) {}
+ : ExecutionContextClient(execution_context), callback_(callback) {}
ExecutionContext* GetExecutionContext() const override {
- return ContextClient::GetExecutionContext();
+ return ExecutionContextClient::GetExecutionContext();
}
void Deliver(const MutationRecordVector& records,
@@ -77,7 +77,7 @@ class MutationObserver::V8DelegateImpl final
void Trace(Visitor* visitor) override {
visitor->Trace(callback_);
MutationObserver::Delegate::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
private:
@@ -108,7 +108,8 @@ MutationObserver* MutationObserver::Create(ScriptState* script_state,
MutationObserver::MutationObserver(ExecutionContext* execution_context,
Delegate* delegate)
- : ContextLifecycleStateObserver(execution_context), delegate_(delegate) {
+ : ExecutionContextLifecycleStateObserver(execution_context),
+ delegate_(delegate) {
priority_ = g_observer_priority++;
UpdateStateIfNeeded();
}
@@ -346,7 +347,7 @@ void MutationObserver::Trace(Visitor* visitor) {
visitor->Trace(records_);
visitor->Trace(registrations_);
ScriptWrappable::Trace(visitor);
- ContextLifecycleStateObserver::Trace(visitor);
+ ExecutionContextLifecycleStateObserver::Trace(visitor);
}
} // namespace blink
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 2b77b0b7b6c..060b575349a 100644
--- a/chromium/third_party/blink/renderer/core/dom/mutation_observer.h
+++ b/chromium/third_party/blink/renderer/core/dom/mutation_observer.h
@@ -35,8 +35,8 @@
#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/mutation_observer_options.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -65,7 +65,7 @@ using MutationRecordVector = HeapVector<Member<MutationRecord>>;
class CORE_EXPORT MutationObserver final
: public ScriptWrappable,
public ActiveScriptWrappable<MutationObserver>,
- public ContextLifecycleStateObserver {
+ public ExecutionContextLifecycleStateObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(MutationObserver);
// Using CancelInspectorAsyncTasks as pre-finalizer to cancel async tasks.
@@ -116,6 +116,7 @@ class CORE_EXPORT MutationObserver final
bool HasPendingActivity() const override { return !records_.IsEmpty(); }
void ContextLifecycleStateChanged(mojom::FrameLifecycleState) final;
+ void ContextDestroyed() final {}
void Trace(Visitor*) override;
diff --git a/chromium/third_party/blink/renderer/core/dom/mutation_observer.idl b/chromium/third_party/blink/renderer/core/dom/mutation_observer.idl
index 370a5a07868..b0402dc46ff 100644
--- a/chromium/third_party/blink/renderer/core/dom/mutation_observer.idl
+++ b/chromium/third_party/blink/renderer/core/dom/mutation_observer.idl
@@ -34,12 +34,13 @@ callback MutationCallback = void (sequence<MutationRecord> mutations,
MutationObserver observer);
[
- ConstructorCallWith=ScriptState,
- Constructor(MutationCallback callback),
ActiveScriptWrappable,
- Exposed=Window
+ Exposed=Window,
+ LegacyWindowAlias=WebKitMutationObserver,
+ LegacyWindowAlias_Measure=PrefixedMutationObserverConstructor
] interface MutationObserver {
- [RaisesException] void observe(Node target, optional MutationObserverInit options);
+ [CallWith=ScriptState] constructor(MutationCallback callback);
+ [RaisesException] void observe(Node target, optional MutationObserverInit options = {});
void disconnect();
sequence<MutationRecord> takeRecords();
};
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 42c73cfa883..a9773f16e62 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
@@ -72,10 +72,6 @@ void MutationObserverInterestGroup::EnqueueMutationRecord(
MutationRecord* mutation) {
MutationRecord* mutation_with_null_old_value = nullptr;
- // For investigation of crbug.com/1003733.
- // If the crashes stop it means there is a GC related issue.
- ThreadState::GCForbiddenScope gc_forbidden(ThreadState::Current());
-
for (auto& iter : observers_) {
MutationObserver* observer = iter.key.Get();
if (HasOldValue(iter.value)) {
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 6268b17c7a4..9ee4b3d8ea6 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
@@ -5,7 +5,7 @@
#include "third_party/blink/renderer/core/dom/mutation_observer.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/core/dom/mutation_observer_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mutation_observer_init.h"
#include "third_party/blink/renderer/core/dom/mutation_observer_registration.h"
#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html/html_element.h"
@@ -19,7 +19,9 @@ class EmptyMutationCallback : public MutationObserver::Delegate {
public:
explicit EmptyMutationCallback(Document& document) : document_(document) {}
- ExecutionContext* GetExecutionContext() const override { return document_; }
+ ExecutionContext* GetExecutionContext() const override {
+ return document_->GetExecutionContext();
+ }
void Deliver(const MutationRecordVector&, MutationObserver&) override {}
@@ -39,7 +41,7 @@ TEST(MutationObserverTest, DisconnectCrash) {
auto* root =
To<HTMLElement>(document->CreateRawElement(html_names::kHTMLTag));
document->AppendChild(root);
- root->SetInnerHTMLFromString("<head><title>\n</title></head><body></body>");
+ root->setInnerHTML("<head><title>\n</title></head><body></body>");
Node* head = root->firstChild()->firstChild();
DCHECK(head);
Persistent<MutationObserver> observer = MutationObserver::Create(
diff --git a/chromium/third_party/blink/renderer/core/dom/mutation_record.h b/chromium/third_party/blink/renderer/core/dom/mutation_record.h
index c8e5cce7dac..246e76b098d 100644
--- a/chromium/third_party/blink/renderer/core/dom/mutation_record.h
+++ b/chromium/third_party/blink/renderer/core/dom/mutation_record.h
@@ -32,6 +32,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_MUTATION_RECORD_H_
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/dom/static_node_list.h"
#include "third_party/blink/renderer/core/probe/async_task_id.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -41,8 +42,7 @@ namespace blink {
class Node;
class QualifiedName;
-template <typename NodeType>
-class StaticNodeTypeList;
+
using StaticNodeList = StaticNodeTypeList<Node>;
class CORE_EXPORT MutationRecord : public ScriptWrappable {
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 af97e374a74..e1120392bec 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
@@ -28,6 +28,7 @@
#include "third_party/blink/renderer/core/dom/attr.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/html/html_document.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -105,7 +106,7 @@ void NamedNodeMap::NamedPropertyEnumerator(Vector<String>& names,
// 3. Return names.
const AttributeCollection attributes = element_->Attributes();
names.ReserveInitialCapacity(attributes.size());
- if (element_->IsHTMLElement() && element_->GetDocument().IsHTMLDocument()) {
+ if (element_->IsHTMLElement() && IsA<HTMLDocument>(element_->GetDocument())) {
for (const Attribute& attribute : attributes) {
if ((attribute.Prefix() == attribute.Prefix().LowerASCII()) &&
(attribute.LocalName() == attribute.LocalName().LowerASCII())) {
diff --git a/chromium/third_party/blink/renderer/core/dom/node.cc b/chromium/third_party/blink/renderer/core/dom/node.cc
index 1442bac4064..371f39cbed5 100644
--- a/chromium/third_party/blink/renderer/core/dom/node.cc
+++ b/chromium/third_party/blink/renderer/core/dom/node.cc
@@ -28,8 +28,10 @@
#include <algorithm>
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/node_or_string_or_trusted_script.h"
#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/css/css_selector.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
@@ -47,6 +49,7 @@
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/element_rare_data.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
+#include "third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
#include "third_party/blink/renderer/core/dom/events/event_dispatcher.h"
@@ -54,7 +57,6 @@
#include "third_party/blink/renderer/core/dom/events/event_path.h"
#include "third_party/blink/renderer/core/dom/flat_tree_node_data.h"
#include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
-#include "third_party/blink/renderer/core/dom/get_root_node_options.h"
#include "third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h"
#include "third_party/blink/renderer/core/dom/mutation_observer_registration.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
@@ -102,6 +104,7 @@
#include "third_party/blink/renderer/core/input/input_device_capabilities.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
+#include "third_party/blink/renderer/core/layout/layout_shift_tracker.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/mathml_names.h"
#include "third_party/blink/renderer/core/page/context_menu_controller.h"
@@ -165,32 +168,18 @@ void AppendUnsafe(StringBuilder& builder, const String& off_thread_string) {
} // namespace
+using ReattachHook = LayoutShiftTracker::ReattachHook;
+
struct SameSizeAsNode : EventTarget {
uint32_t node_flags_;
Member<void*> willbe_member_[4];
- void* pointer_;
+ Member<NodeData> member_;
+#if !DCHECK_IS_ON()
+ static_assert(sizeof(Member<NodeData>) == sizeof(void*),
+ "Increasing size of Member increases size of Node");
+#endif // !DCHECK_IS_ON()
};
-NodeRenderingData::NodeRenderingData(
- LayoutObject* layout_object,
- scoped_refptr<const ComputedStyle> computed_style)
- : layout_object_(layout_object), computed_style_(computed_style) {}
-
-NodeRenderingData::~NodeRenderingData() {
- CHECK(!layout_object_);
-}
-
-void NodeRenderingData::SetComputedStyle(
- scoped_refptr<const ComputedStyle> computed_style) {
- DCHECK_NE(&SharedEmptyData(), this);
- computed_style_ = computed_style;
-}
-
-NodeRenderingData& NodeRenderingData::SharedEmptyData() {
- DEFINE_STATIC_LOCAL(NodeRenderingData, shared_empty_data, (nullptr, nullptr));
- return shared_empty_data;
-}
-
static_assert(sizeof(Node) <= sizeof(SameSizeAsNode), "Node should stay small");
#if DUMP_NODE_STATISTICS
@@ -341,7 +330,8 @@ Node::Node(TreeScope* tree_scope, ConstructionType type)
parent_or_shadow_host_node_(nullptr),
tree_scope_(tree_scope),
previous_(nullptr),
- next_(nullptr) {
+ next_(nullptr),
+ data_(&NodeRenderingData::SharedEmptyData()) {
DCHECK(tree_scope_ || type == kCreateDocument || type == kCreateShadowRoot);
#if !defined(NDEBUG) || (defined(DUMP_NODE_STATISTICS) && DUMP_NODE_STATISTICS)
TrackForDebugging();
@@ -353,23 +343,18 @@ Node::Node(TreeScope* tree_scope, ConstructionType type)
}
Node::~Node() {
- if (!HasRareData() && !data_.node_layout_data_->IsSharedEmptyData())
- delete data_.node_layout_data_;
InstanceCounters::DecrementCounter(InstanceCounters::kNodeCounter);
}
NodeRareData& Node::CreateRareData() {
if (IsElementNode()) {
- data_.rare_data_ =
- MakeGarbageCollected<ElementRareData>(data_.node_layout_data_);
+ data_ = MakeGarbageCollected<ElementRareData>(DataAsNodeRenderingData());
} else {
- data_.rare_data_ =
- MakeGarbageCollected<NodeRareData>(data_.node_layout_data_);
+ data_ = MakeGarbageCollected<NodeRareData>(DataAsNodeRenderingData());
}
- DCHECK(data_.rare_data_);
+ DCHECK(data_);
SetFlag(kHasRareDataFlag);
- MarkingVisitor::WriteBarrier(RareData());
return *RareData();
}
@@ -389,14 +374,7 @@ ContainerNode* Node::parentNode() const {
return IsShadowRoot() ? nullptr : ParentOrShadowHostNode();
}
-ContainerNode* Node::ParentNodeWithCounting() const {
- if (GetFlag(kInDOMNodeRemovedHandler))
- GetDocument().CountDetachingNodeAccessInDOMNodeRemovedHandler();
- return IsShadowRoot() ? nullptr : ParentOrShadowHostNode();
-}
-
NodeList* Node::childNodes() {
- ThreadState::MainThreadGCForbiddenScope gc_forbidden;
auto* this_node = DynamicTo<ContainerNode>(this);
if (this_node)
return EnsureRareData().EnsureNodeLists().EnsureChildNodeList(*this_node);
@@ -404,36 +382,64 @@ NodeList* Node::childNodes() {
}
Node* Node::PseudoAwarePreviousSibling() const {
- if (parentElement() && !previousSibling()) {
- Element* parent = parentElement();
- if (IsAfterPseudoElement() && parent->lastChild())
- return parent->lastChild();
- if (!IsBeforePseudoElement())
- return parent->GetPseudoElement(kPseudoIdBefore);
+ Element* parent = parentElement();
+ if (!parent || previousSibling())
+ return previousSibling();
+ switch (GetPseudoId()) {
+ case kPseudoIdAfter:
+ if (Node* previous = parent->lastChild())
+ return previous;
+ FALLTHROUGH;
+ case kPseudoIdNone:
+ if (Node* previous = parent->GetPseudoElement(kPseudoIdBefore))
+ return previous;
+ FALLTHROUGH;
+ case kPseudoIdBefore:
+ if (Node* previous = parent->GetPseudoElement(kPseudoIdMarker))
+ return previous;
+ FALLTHROUGH;
+ case kPseudoIdMarker:
+ break;
+ default:
+ NOTREACHED();
}
- return previousSibling();
+ return nullptr;
}
Node* Node::PseudoAwareNextSibling() const {
- if (parentElement() && !nextSibling()) {
- Element* parent = parentElement();
- if (IsBeforePseudoElement() && parent->HasChildren())
- return parent->firstChild();
- if (!IsAfterPseudoElement())
- return parent->GetPseudoElement(kPseudoIdAfter);
+ Element* parent = parentElement();
+ if (!parent || nextSibling())
+ return nextSibling();
+ switch (GetPseudoId()) {
+ case kPseudoIdMarker:
+ if (Node* next = parent->GetPseudoElement(kPseudoIdBefore))
+ return next;
+ FALLTHROUGH;
+ case kPseudoIdBefore:
+ if (parent->HasChildren())
+ return parent->firstChild();
+ FALLTHROUGH;
+ case kPseudoIdNone:
+ if (Node* next = parent->GetPseudoElement(kPseudoIdAfter))
+ return next;
+ FALLTHROUGH;
+ case kPseudoIdAfter:
+ break;
+ default:
+ NOTREACHED();
}
- return nextSibling();
+ return nullptr;
}
Node* Node::PseudoAwareFirstChild() const {
if (const auto* current_element = DynamicTo<Element>(this)) {
- Node* first = current_element->GetPseudoElement(kPseudoIdBefore);
- if (first)
+ if (Node* first = current_element->GetPseudoElement(kPseudoIdMarker))
+ return first;
+ if (Node* first = current_element->GetPseudoElement(kPseudoIdBefore))
+ return first;
+ if (Node* first = current_element->firstChild())
return first;
- first = current_element->firstChild();
- if (!first)
- first = current_element->GetPseudoElement(kPseudoIdAfter);
- return first;
+ return current_element->GetPseudoElement(kPseudoIdAfter);
}
return firstChild();
@@ -441,13 +447,13 @@ Node* Node::PseudoAwareFirstChild() const {
Node* Node::PseudoAwareLastChild() const {
if (const auto* current_element = DynamicTo<Element>(this)) {
- Node* last = current_element->GetPseudoElement(kPseudoIdAfter);
- if (last)
+ if (Node* last = current_element->GetPseudoElement(kPseudoIdAfter))
+ return last;
+ if (Node* last = current_element->lastChild())
+ return last;
+ if (Node* last = current_element->GetPseudoElement(kPseudoIdBefore))
return last;
- last = current_element->lastChild();
- if (!last)
- last = current_element->GetPseudoElement(kPseudoIdBefore);
- return last;
+ return current_element->GetPseudoElement(kPseudoIdMarker);
}
return lastChild();
@@ -536,9 +542,8 @@ void Node::NativeApplyScroll(ScrollState& scroll_state) {
if (delta.IsZero())
return;
- // TODO(esprehn): This should use
- // updateStyleAndLayoutForNode.
- GetDocument().UpdateStyleAndLayout();
+ // TODO: This should use updateStyleAndLayoutForNode.
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kScroll);
LayoutBox* box_to_scroll = ToLayoutBox(GetLayoutObject());
@@ -556,7 +561,7 @@ void Node::NativeApplyScroll(ScrollState& scroll_state) {
// behavior in CC.
bool also_scroll_visual_viewport = GetDocument().GetFrame() &&
GetDocument().GetFrame()->IsMainFrame() &&
- box_to_scroll->IsLayoutView();
+ IsA<LayoutView>(box_to_scroll);
DCHECK(!also_scroll_visual_viewport ||
!box_to_scroll->IsGlobalRootScroller());
@@ -566,16 +571,16 @@ void Node::NativeApplyScroll(ScrollState& scroll_state) {
return;
}
- ScrollResult result = scrollable_area->UserScroll(
- ScrollGranularity(static_cast<int>(scroll_state.deltaGranularity())),
- delta, ScrollableArea::ScrollCallback());
+ ScrollResult result =
+ scrollable_area->UserScroll(scroll_state.delta_granularity(), delta,
+ ScrollableArea::ScrollCallback());
// Also try scrolling the visual viewport if we're at the end of the scroll
// chain.
if (!result.DidScroll() && also_scroll_visual_viewport) {
result = GetDocument().GetPage()->GetVisualViewport().UserScroll(
- ScrollGranularity(static_cast<int>(scroll_state.deltaGranularity())),
- delta, ScrollableArea::ScrollCallback());
+ scroll_state.delta_granularity(), delta,
+ ScrollableArea::ScrollCallback());
}
if (!result.DidScroll())
@@ -697,10 +702,6 @@ void Node::DidEndCustomizedScrollPhase() {
Node* Node::insertBefore(Node* new_child,
Node* ref_child,
ExceptionState& exception_state) {
- new_child = TrustedTypesCheckForScriptNode(new_child, exception_state);
- if (!new_child)
- return nullptr;
-
auto* this_node = DynamicTo<ContainerNode>(this);
if (this_node)
return this_node->InsertBefore(new_child, ref_child, exception_state);
@@ -718,10 +719,6 @@ Node* Node::insertBefore(Node* new_child, Node* ref_child) {
Node* Node::replaceChild(Node* new_child,
Node* old_child,
ExceptionState& exception_state) {
- new_child = TrustedTypesCheckForScriptNode(new_child, exception_state);
- if (!new_child)
- return nullptr;
-
auto* this_node = DynamicTo<ContainerNode>(this);
if (this_node)
return this_node->ReplaceChild(new_child, old_child, exception_state);
@@ -752,10 +749,6 @@ Node* Node::removeChild(Node* old_child) {
}
Node* Node::appendChild(Node* new_child, ExceptionState& exception_state) {
- new_child = TrustedTypesCheckForScriptNode(new_child, exception_state);
- if (!new_child)
- return nullptr;
-
auto* this_node = DynamicTo<ContainerNode>(this);
if (this_node)
return this_node->AppendChild(new_child, exception_state);
@@ -833,8 +826,8 @@ static Node* NodeOrStringToNode(
? node_or_string.GetAsString()
: node_or_string.GetAsNode()->textContent();
- string_value =
- GetStringFromTrustedScript(string_value, &document, exception_state);
+ string_value = TrustedTypesCheckForScript(
+ string_value, document.GetExecutionContext(), exception_state);
if (exception_state.HadException())
return nullptr;
return Text::Create(document, string_value);
@@ -1019,8 +1012,8 @@ LayoutBox* Node::GetLayoutBox() const {
void Node::SetLayoutObject(LayoutObject* layout_object) {
NodeRenderingData* node_layout_data =
- HasRareData() ? data_.rare_data_->GetNodeRenderingData()
- : data_.node_layout_data_;
+ HasRareData() ? DataAsNodeRareData()->GetNodeRenderingData()
+ : DataAsNodeRenderingData();
// Already pointing to a non empty NodeRenderingData so just set the pointer
// to the new LayoutObject.
@@ -1035,11 +1028,13 @@ void Node::SetLayoutObject(LayoutObject* layout_object) {
// Swap the NodeRenderingData to point to a new NodeRenderingData instead of
// the static SharedEmptyData instance.
DCHECK(!node_layout_data->GetComputedStyle());
- node_layout_data = new NodeRenderingData(layout_object, nullptr);
- if (HasRareData())
- data_.rare_data_->SetNodeRenderingData(node_layout_data);
- else
- data_.node_layout_data_ = node_layout_data;
+ node_layout_data =
+ MakeGarbageCollected<NodeRenderingData>(layout_object, nullptr);
+ if (HasRareData()) {
+ DataAsNodeRareData()->SetNodeRenderingData(node_layout_data);
+ } else {
+ data_ = node_layout_data;
+ }
}
void Node::SetComputedStyle(scoped_refptr<const ComputedStyle> computed_style) {
@@ -1047,8 +1042,8 @@ void Node::SetComputedStyle(scoped_refptr<const ComputedStyle> computed_style) {
DCHECK(IsElementNode());
NodeRenderingData* node_layout_data =
- HasRareData() ? data_.rare_data_->GetNodeRenderingData()
- : data_.node_layout_data_;
+ HasRareData() ? DataAsNodeRareData()->GetNodeRenderingData()
+ : DataAsNodeRenderingData();
// Already pointing to a non empty NodeRenderingData so just set the pointer
// to the new LayoutObject.
@@ -1068,11 +1063,13 @@ void Node::SetComputedStyle(scoped_refptr<const ComputedStyle> computed_style) {
// Swap the NodeRenderingData to point to a new NodeRenderingData instead of
// the static SharedEmptyData instance.
DCHECK(!node_layout_data->GetLayoutObject());
- node_layout_data = new NodeRenderingData(nullptr, computed_style);
- if (HasRareData())
- data_.rare_data_->SetNodeRenderingData(node_layout_data);
- else
- data_.node_layout_data_ = node_layout_data;
+ node_layout_data =
+ MakeGarbageCollected<NodeRenderingData>(nullptr, computed_style);
+ if (HasRareData()) {
+ DataAsNodeRareData()->SetNodeRenderingData(node_layout_data);
+ } else {
+ data_ = node_layout_data;
+ }
}
LayoutBoxModelObject* Node::GetLayoutBoxModelObject() const {
@@ -1229,6 +1226,35 @@ void Node::MarkAncestorsWithChildNeedsDistributionRecalc() {
GetDocument().ScheduleLayoutTreeUpdateIfNeeded();
}
+void Node::MarkSubtreeNeedsStyleRecalcForFontUpdates() {
+ if (GetStyleChangeType() == kSubtreeStyleChange)
+ return;
+
+ if (IsElementNode()) {
+ const ComputedStyle* style = GetComputedStyle();
+ if (!style)
+ return;
+
+ // We require font-specific metrics to resolve length units 'ex' and 'ch',
+ // and to compute the adjusted font size when 'font-size-adjust' is set. All
+ // other style computations are unaffected by font loading.
+ if (!NeedsStyleRecalc()) {
+ if (style->DependsOnFontMetrics() ||
+ To<Element>(this)->PseudoElementStylesDependOnFontMetrics()) {
+ SetNeedsStyleRecalc(
+ kLocalStyleChange,
+ StyleChangeReasonForTracing::Create(style_change_reason::kFonts));
+ }
+ }
+
+ if (Node* shadow_root = GetShadowRoot())
+ shadow_root->MarkSubtreeNeedsStyleRecalcForFontUpdates();
+ }
+
+ for (Node* child = firstChild(); child; child = child->nextSibling())
+ child->MarkSubtreeNeedsStyleRecalcForFontUpdates();
+}
+
#if DCHECK_IS_ON()
namespace {
class AllowDirtyShadowV0TraversalScope {
@@ -1245,7 +1271,7 @@ class AllowDirtyShadowV0TraversalScope {
}
private:
- Member<Document> document_;
+ Document* document_;
bool old_value_;
};
} // namespace
@@ -1292,7 +1318,7 @@ void Node::MarkAncestorsWithChildNeedsStyleRecalc() {
break;
// If we reach a locked ancestor, we should abort since the ancestor marking
// will be done when the lock is committed.
- if (RuntimeEnabledFeatures::DisplayLockingEnabled(GetExecutionContext())) {
+ if (RuntimeEnabledFeatures::CSSSubtreeVisibilityEnabled()) {
auto* ancestor_element = DynamicTo<Element>(ancestor);
if (ancestor_element && ancestor_element->StyleRecalcBlockedByDisplayLock(
DisplayLockLifecycleTarget::kChildren)) {
@@ -1328,7 +1354,7 @@ void Node::MarkAncestorsWithChildNeedsStyleRecalc() {
// roots. These would be updated when we commit the lock. If we have locked
// display locks somewhere in the document, we iterate up the ancestor chain
// to check if we're in one such subtree.
- if (RuntimeEnabledFeatures::DisplayLockingEnabled(GetExecutionContext()) &&
+ if (RuntimeEnabledFeatures::CSSSubtreeVisibilityEnabled() &&
GetDocument().LockedDisplayLockCount() > 0) {
for (auto* ancestor_copy = ancestor; ancestor_copy;
ancestor_copy = ancestor_copy->GetStyleRecalcParent()) {
@@ -1359,6 +1385,7 @@ Element* Node::FlatTreeParentForChildDirty() const {
const_cast<V0InsertionPoint*>(ResolveReprojection(this))) {
return insertion_point;
}
+ return nullptr;
}
}
return ParentOrShadowHostElement();
@@ -1416,7 +1443,8 @@ void Node::SetNeedsStyleRecalc(StyleChangeType change_type,
TRACE_EVENT_INSTANT1(
TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"),
"StyleRecalcInvalidationTracking", TRACE_EVENT_SCOPE_THREAD, "data",
- inspector_style_recalc_invalidation_tracking_event::Data(this, reason));
+ inspector_style_recalc_invalidation_tracking_event::Data(
+ this, change_type, reason));
StyleChangeType existing_change_type = GetStyleChangeType();
if (change_type > existing_change_type)
@@ -1528,6 +1556,8 @@ void Node::ClearFlatTreeNodeDataIfHostChanged(const ContainerNode& parent) {
}
bool Node::IsDescendantOf(const Node* other) const {
+ DCHECK(this); // Necessary for clusterfuzz tooling to get a useful backtrace
+
// Return true if other is an ancestor of this, otherwise false
if (!other || isConnected() != other->isConnected())
return false;
@@ -1631,6 +1661,7 @@ Node* Node::CommonAncestor(const Node& other,
void Node::ReattachLayoutTree(AttachContext& context) {
context.performing_reattach = true;
+ ReattachHook::Scope reattach_scope(*this);
DetachLayoutTree(context.performing_reattach);
AttachLayoutTree(context);
@@ -1646,12 +1677,15 @@ void Node::AttachLayoutTree(AttachContext& context) {
LayoutObject* layout_object = GetLayoutObject();
DCHECK(!layout_object ||
(layout_object->Style() &&
- (layout_object->Parent() || layout_object->IsLayoutView())));
+ (layout_object->Parent() || IsA<LayoutView>(layout_object))));
ClearNeedsReattachLayoutTree();
if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache())
cache->UpdateCacheAfterNodeIsAttached(this);
+
+ if (context.performing_reattach)
+ ReattachHook::NotifyAttach(*this);
}
void Node::DetachLayoutTree(bool performing_reattach) {
@@ -1659,6 +1693,10 @@ void Node::DetachLayoutTree(bool performing_reattach) {
DCHECK(!performing_reattach ||
GetDocument().GetStyleEngine().InRebuildLayoutTree());
DocumentLifecycle::DetachScope will_detach(GetDocument().Lifecycle());
+
+ if (performing_reattach)
+ ReattachHook::NotifyDetach(*this);
+
if (GetLayoutObject())
GetLayoutObject()->DestroyAndCleanupAnonymousWrappers();
SetLayoutObject(nullptr);
@@ -1844,6 +1882,16 @@ ContainerNode* Node::ParentOrShadowHostOrTemplateHostNode() const {
return ParentOrShadowHostNode();
}
+TreeScope& Node::OriginatingTreeScope() const {
+ if (const SVGElement* svg_element = DynamicTo<SVGElement>(this)) {
+ if (const SVGElement* corr_element = svg_element->CorrespondingElement()) {
+ DCHECK(!corr_element->CorrespondingElement());
+ return corr_element->GetTreeScope();
+ }
+ }
+ return GetTreeScope();
+}
+
Document* Node::ownerDocument() const {
Document* doc = &GetDocument();
return doc == this ? nullptr : doc;
@@ -2418,6 +2466,10 @@ static void AppendMarkedTree(const String& base_indent,
indent.Append('\t');
if (const auto* element = DynamicTo<Element>(node)) {
+ if (Element* pseudo = element->GetPseudoElement(kPseudoIdMarker)) {
+ AppendMarkedTree(indent.ToString(), pseudo, marked_node1, marked_label1,
+ marked_node2, marked_label2, builder);
+ }
if (Element* pseudo = element->GetPseudoElement(kPseudoIdBefore))
AppendMarkedTree(indent.ToString(), pseudo, marked_node1, marked_label1,
marked_node2, marked_label2, builder);
@@ -2560,7 +2612,9 @@ const AtomicString& Node::InterfaceName() const {
}
ExecutionContext* Node::GetExecutionContext() const {
- return GetDocument().ContextDocument();
+ if (auto* document = GetDocument().ContextDocument())
+ return document->domWindow();
+ return nullptr;
}
void Node::WillMoveToNewDocument(Document& old_document,
@@ -2823,7 +2877,7 @@ void Node::HandleLocalEvents(Event& event) {
if (!HasEventTargetData())
return;
- if (IsDisabledFormControl(this) && event.IsMouseEvent() &&
+ if (IsDisabledFormControl(this) && IsA<MouseEvent>(event) &&
!RuntimeEnabledFeatures::SendMouseEventsDisabledFormControlsEnabled()) {
if (HasEventListeners(event.type())) {
UseCounter::Count(GetDocument(),
@@ -2884,10 +2938,10 @@ DispatchEventResult Node::DispatchDOMActivateEvent(int detail,
return EventTarget::GetDispatchEventResult(event);
}
-void Node::DispatchSimulatedClick(Event* underlying_event,
+void Node::DispatchSimulatedClick(const Event* underlying_event,
SimulatedClickMouseEventOptions event_options,
SimulatedClickCreationScope scope) {
- if (auto* element = IsElementNode() ? ToElement(this) : parentElement()) {
+ if (auto* element = IsElementNode() ? To<Element>(this) : parentElement()) {
element->ActivateDisplayLockIfNeeded(
DisplayLockActivationReason::kSimulatedClick);
}
@@ -2895,13 +2949,6 @@ void Node::DispatchSimulatedClick(Event* underlying_event,
event_options, scope);
}
-void Node::DispatchInputEvent() {
- // Legacy 'input' event for forms set value and checked.
- Event* event = Event::CreateBubble(event_type_names::kInput);
- event->SetComposed(true);
- DispatchScopedEvent(*event);
-}
-
void Node::DefaultEventHandler(Event& event) {
if (event.target() != this)
return;
@@ -2909,22 +2956,22 @@ void Node::DefaultEventHandler(Event& event) {
if (event_type == event_type_names::kKeydown ||
event_type == event_type_names::kKeypress ||
event_type == event_type_names::kKeyup) {
- if (event.IsKeyboardEvent()) {
+ if (auto* keyboard_event = DynamicTo<KeyboardEvent>(&event)) {
if (LocalFrame* frame = GetDocument().GetFrame()) {
- frame->GetEventHandler().DefaultKeyboardEventHandler(
- ToKeyboardEvent(&event));
+ frame->GetEventHandler().DefaultKeyboardEventHandler(keyboard_event);
}
}
} else if (event_type == event_type_names::kClick) {
- int detail = event.IsUIEvent() ? ToUIEvent(event).detail() : 0;
+ auto* ui_event = DynamicTo<UIEvent>(event);
+ int detail = ui_event ? ui_event->detail() : 0;
if (DispatchDOMActivateEvent(detail, event) !=
DispatchEventResult::kNotCanceled)
event.SetDefaultHandled();
} else if (event_type == event_type_names::kContextmenu &&
- event.IsMouseEvent()) {
+ IsA<MouseEvent>(event)) {
if (Page* page = GetDocument().GetPage()) {
page->GetContextMenuController().HandleContextMenuEvent(
- ToMouseEvent(&event));
+ To<MouseEvent>(&event));
}
} else if (event_type == event_type_names::kTextInput) {
if (event.HasInterface(event_interface_names::kTextEvent)) {
@@ -2935,8 +2982,8 @@ void Node::DefaultEventHandler(Event& event) {
}
} else if (RuntimeEnabledFeatures::MiddleClickAutoscrollEnabled() &&
event_type == event_type_names::kMousedown &&
- event.IsMouseEvent()) {
- auto& mouse_event = ToMouseEvent(event);
+ IsA<MouseEvent>(event)) {
+ auto& mouse_event = To<MouseEvent>(event);
if (mouse_event.button() ==
static_cast<int16_t>(WebPointerProperties::Button::kMiddle)) {
if (EnclosingLinkEventParentOrSelf())
@@ -2947,7 +2994,7 @@ void Node::DefaultEventHandler(Event& event) {
// FIXME: We should avoid synchronous layout if possible. We can
// remove this synchronous layout if we avoid synchronous layout in
// LayoutTextControlSingleLine::scrollHeight
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kInput);
LayoutObject* layout_object = GetLayoutObject();
while (
layout_object &&
@@ -3082,8 +3129,8 @@ HTMLSlotElement* Node::assignedSlotForBinding() {
return nullptr;
}
-void Node::SetFocused(bool flag, WebFocusType focus_type) {
- if (focus_type == kWebFocusTypeMouse)
+void Node::SetFocused(bool flag, mojom::blink::FocusType focus_type) {
+ if (focus_type == mojom::blink::FocusType::kMouse)
GetDocument().SetHadKeyboardEvent(false);
GetDocument().UserActionElements().SetFocused(this, flag);
}
@@ -3139,7 +3186,8 @@ void Node::SetCustomElementState(CustomElementState new_state) {
break;
case CustomElementState::kCustom:
- DCHECK_EQ(CustomElementState::kUndefined, old_state);
+ DCHECK(old_state == CustomElementState::kUndefined ||
+ old_state == CustomElementState::kFailed);
break;
case CustomElementState::kFailed:
@@ -3235,6 +3283,12 @@ bool Node::IsEffectiveRootScroller() const {
: false;
}
+LayoutBox* Node::AutoscrollBox() {
+ return nullptr;
+}
+
+void Node::StopAutoscroll() {}
+
WebPluginContainerImpl* Node::GetWebPluginContainer() const {
if (!IsA<HTMLObjectElement>(this) && !IsA<HTMLEmbedElement>(this)) {
return nullptr;
@@ -3273,6 +3327,14 @@ void Node::FlatTreeParentChanged() {
DCHECK(GetDocument().MayContainV0Shadow());
return;
}
+ if (const ComputedStyle* style = GetComputedStyle()) {
+ // We are moving a node with ensured computed style into the flat tree.
+ // Clear ensured styles so that we can use IsEnsuredOutsideFlatTree() to
+ // determine that we are outside the flat tree before updating the style
+ // recalc root in MarkAncestorsWithChildNeedsStyleRecalc().
+ if (style->IsEnsuredOutsideFlatTree())
+ DetachLayoutTree();
+ }
// The node changed the flat tree position by being slotted to a new slot or
// slotted for the first time. We need to recalc style since the inheritance
// parent may have changed.
@@ -3300,29 +3362,11 @@ void Node::RemovedFromFlatTree() {
GetDocument().GetStyleEngine().RemovedFromFlatTree(*this);
}
-Node* Node::TrustedTypesCheckForScriptNode(
- Node* child,
- ExceptionState& exception_state) const {
- DCHECK(child);
- bool needs_check = IsA<HTMLScriptElement>(this) && child->IsTextNode() &&
- GetDocument().IsTrustedTypesEnabledForDoc();
- if (!needs_check)
- return child;
-
- child = TrustedTypesCheckForHTMLScriptElement(child, &GetDocument(),
- exception_state);
- DCHECK_EQ(!child, exception_state.HadException());
- return child;
-}
-
void Node::Trace(Visitor* visitor) {
visitor->Trace(parent_or_shadow_host_node_);
visitor->Trace(previous_);
visitor->Trace(next_);
- // rareData() and data_.node_layout_data_ share their storage. We have to
- // trace only one of them.
- if (HasRareData())
- visitor->Trace(RareData());
+ visitor->Trace(data_);
visitor->Trace(tree_scope_);
EventTarget::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/node.h b/chromium/third_party/blink/renderer/core/dom/node.h
index e2a2045833d..767e551efc4 100644
--- a/chromium/third_party/blink/renderer/core/dom/node.h
+++ b/chromium/third_party/blink/renderer/core/dom/node.h
@@ -27,7 +27,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_NODE_H_
#include "base/macros.h"
-#include "third_party/blink/public/platform/web_focus_type.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.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/dom/events/simulated_click_options.h"
@@ -80,12 +80,14 @@ class V8ScrollStateCallback;
class WebPluginContainerImpl;
struct PhysicalRect;
-const int kNodeStyleChangeShift = 19;
-const int kNodeCustomElementShift = 21;
+const int kDOMNodeTypeShift = 2;
+const int kElementNamespaceTypeShift = 4;
+const int kNodeStyleChangeShift = 17;
+const int kNodeCustomElementShift = 19;
// Values for kChildNeedsStyleRecalcFlag, controlling whether a node gets its
// style recalculated.
-enum StyleChangeType {
+enum StyleChangeType : uint32_t {
// This node does not need style recalculation.
kNoStyleChange = 0,
// This node needs style recalculation.
@@ -94,14 +96,12 @@ enum StyleChangeType {
kSubtreeStyleChange = 2 << kNodeStyleChangeShift,
};
-enum class CustomElementState {
+enum class CustomElementState : uint32_t {
// https://dom.spec.whatwg.org/#concept-element-custom-element-state
kUncustomized = 0,
kCustom = 1 << kNodeCustomElementShift,
kUndefined = 2 << kNodeCustomElementShift,
kFailed = 3 << kNodeCustomElementShift,
-
- kNotDefinedFlag = 2 << kNodeCustomElementShift,
};
enum class SlotChangeType {
@@ -260,7 +260,7 @@ class CORE_EXPORT Node : public EventTarget {
const AtomicString& lookupNamespaceURI(const String& prefix) const;
String textContent(bool convert_brs_to_newlines = false) const;
- void setTextContent(const String&);
+ virtual void setTextContent(const String&);
void textContent(StringOrTrustedScript& result);
virtual void setTextContent(const StringOrTrustedScript&, ExceptionState&);
@@ -269,13 +269,28 @@ class CORE_EXPORT Node : public EventTarget {
void SetComputedStyle(scoped_refptr<const ComputedStyle> computed_style);
// Other methods (not part of DOM)
+ ALWAYS_INLINE bool IsTextNode() const {
+ return GetDOMNodeType() == DOMNodeType::kText;
+ }
+ ALWAYS_INLINE bool IsContainerNode() const {
+ return GetFlag(kIsContainerFlag);
+ }
+ ALWAYS_INLINE bool IsElementNode() const {
+ return GetDOMNodeType() == DOMNodeType::kElement;
+ }
+ ALWAYS_INLINE bool IsDocumentFragment() const {
+ return GetDOMNodeType() == DOMNodeType::kDocumentFragment;
+ }
- bool IsElementNode() const { return GetFlag(kIsElementFlag); }
- bool IsContainerNode() const { return GetFlag(kIsContainerFlag); }
- bool IsTextNode() const { return GetFlag(kIsTextFlag); }
- bool IsHTMLElement() const { return GetFlag(kIsHTMLFlag); }
- bool IsMathMLElement() const { return GetFlag(kIsMathMLFlag); }
- bool IsSVGElement() const { return GetFlag(kIsSVGFlag); }
+ ALWAYS_INLINE bool IsHTMLElement() const {
+ return GetElementNamespaceType() == ElementNamespaceType::kHTML;
+ }
+ ALWAYS_INLINE bool IsMathMLElement() const {
+ return GetElementNamespaceType() == ElementNamespaceType::kMathML;
+ }
+ ALWAYS_INLINE bool IsSVGElement() const {
+ return GetElementNamespaceType() == ElementNamespaceType::kSVG;
+ }
DISABLE_CFI_PERF bool IsPseudoElement() const {
return GetPseudoId() != kPseudoIdNone;
@@ -335,7 +350,6 @@ class CORE_EXPORT Node : public EventTarget {
bool IsDocumentNode() const;
bool IsTreeScope() const;
- bool IsDocumentFragment() const { return GetFlag(kIsDocumentFragmentFlag); }
bool IsShadowRoot() const { return IsDocumentFragment() && IsTreeScope(); }
bool IsV0InsertionPoint() const { return GetFlag(kIsV0InsertionPointFlag); }
@@ -463,6 +477,10 @@ class CORE_EXPORT Node : public EventTarget {
// Propagates a dirty bit breadcrumb for this element up the ancestor chain.
void MarkAncestorsWithChildNeedsStyleRecalc();
+ // Traverses subtree (include pseudo elements and shadow trees) and
+ // invalidates nodes whose styles depend on font metrics (e.g., 'ex' unit).
+ void MarkSubtreeNeedsStyleRecalcForFontUpdates();
+
// Nodes which are not connected are style clean. Mark them for style recalc
// when inserting them into a document. This method was added as a light-
// weight alternative to SetNeedsStyleRecalc because using that method caused
@@ -574,7 +592,7 @@ class CORE_EXPORT Node : public EventTarget {
SetFlag(flag, kHasEventTargetDataFlag);
}
- virtual void SetFocused(bool flag, WebFocusType);
+ virtual void SetFocused(bool flag, mojom::blink::FocusType);
void SetHasFocusWithin(bool flag);
virtual void SetDragged(bool flag);
@@ -617,6 +635,11 @@ class CORE_EXPORT Node : public EventTarget {
return *tree_scope_;
}
+ // Returns the tree scope where this element originated.
+ // Use this when resolving element references for (CSS url(...)s and #id).
+ // This differs from GetTreeScope for shadow clones inside <svg:use/>.
+ TreeScope& OriginatingTreeScope() const;
+
bool InActiveDocument() const;
// Returns true if this node is connected to a document, false otherwise.
@@ -666,8 +689,8 @@ class CORE_EXPORT Node : public EventTarget {
// have one as well.
LayoutObject* GetLayoutObject() const {
return HasRareData()
- ? data_.rare_data_->GetNodeRenderingData()->GetLayoutObject()
- : data_.node_layout_data_->GetLayoutObject();
+ ? DataAsNodeRareData()->GetNodeRenderingData()->GetLayoutObject()
+ : DataAsNodeRenderingData()->GetLayoutObject();
}
void SetLayoutObject(LayoutObject*);
// Use these two methods with caution.
@@ -744,16 +767,20 @@ class CORE_EXPORT Node : public EventTarget {
//
// Blink notifies this callback regardless if the subtree of the node is a
// document tree or a floating subtree. Implementation can determine the type
- // of subtree by seeing insertionPoint->isConnected(). For a performance
+ // of subtree by seeing insertion_point->isConnected(). For a performance
// reason, notifications are delivered only to ContainerNode subclasses if the
- // insertionPoint is out of document.
+ // insertion_point is out of document.
//
- // There are another callback named didNotifySubtreeInsertionsToDocument(),
+ // There are another callback named DidNotifySubtreeInsertionsToDocument(),
// which is called after all the descendant is notified, if this node was
// inserted into the document tree. Only a few subclasses actually need
// this. To utilize this, the node should return
- // InsertionShouldCallDidNotifySubtreeInsertions from insertedInto().
+ // kInsertionShouldCallDidNotifySubtreeInsertions from InsertedInto().
//
+ // InsertedInto() implementations must not modify the DOM tree, and must not
+ // dispatch synchronous events. On the other hand,
+ // DidNotifySubtreeInsertionsToDocument() may modify the DOM tree, and may
+ // dispatch synchronous events.
enum InsertionNotificationRequest {
kInsertionDone,
kInsertionShouldCallDidNotifySubtreeInsertions
@@ -765,10 +792,12 @@ class CORE_EXPORT Node : public EventTarget {
// Notifies the node that it is no longer part of the tree.
//
- // This is a dual of insertedInto(), and is similar to the
+ // This is a dual of InsertedInto(), and is similar to the
// DOMNodeRemovedFromDocument DOM event, but does not require the overhead of
// event dispatching, and is called _after_ the node is removed from the tree.
//
+ // RemovedFrom() implementations must not modify the DOM tree, and must not
+ // dispatch synchronous events.
virtual void RemovedFrom(ContainerNode& insertion_point);
// FIXME(dominicc): This method is not debug-only--it is used by
@@ -826,10 +855,6 @@ class CORE_EXPORT Node : public EventTarget {
}
virtual void PostDispatchEventHandler(Event&, EventDispatchHandlingState*) {}
- // TODO(crbug.com/1013385): Remove DidPreventDefault. It is here as a
- // temporary fix for form double-submit.
- virtual void DidPreventDefault(const Event&) {}
-
void DispatchScopedEvent(Event&);
virtual void HandleLocalEvents(Event&);
@@ -838,13 +863,11 @@ class CORE_EXPORT Node : public EventTarget {
DispatchEventResult DispatchDOMActivateEvent(int detail,
Event& underlying_event);
- void DispatchSimulatedClick(Event* underlying_event,
+ void DispatchSimulatedClick(const Event* underlying_event,
SimulatedClickMouseEventOptions = kSendNoEvents,
SimulatedClickCreationScope =
SimulatedClickCreationScope::kFromUserAgent);
- void DispatchInputEvent();
-
// Perform the default action for an event.
virtual void DefaultEventHandler(Event&);
void UpdateHadKeyboardEvent(const Event&);
@@ -895,100 +918,128 @@ class CORE_EXPORT Node : public EventTarget {
return GetFlag(kHasDuplicateAttributes);
}
- void SetInDOMNodeRemovedHandler(bool flag) {
- SetFlag(flag, kInDOMNodeRemovedHandler);
- }
- bool InDOMNodeRemovedHandler() const {
- return GetFlag(kInDOMNodeRemovedHandler);
- }
-
bool IsEffectiveRootScroller() const;
+ virtual LayoutBox* AutoscrollBox();
+ virtual void StopAutoscroll();
+
// If the node is a plugin, then this returns its WebPluginContainer.
WebPluginContainerImpl* GetWebPluginContainer() const;
void Trace(Visitor*) override;
private:
- enum NodeFlags {
+ enum NodeFlags : uint32_t {
kHasRareDataFlag = 1,
// Node type flags. These never change once created.
- kIsTextFlag = 1 << 1,
- kIsContainerFlag = 1 << 2,
- kIsElementFlag = 1 << 3,
- kIsHTMLFlag = 1 << 4,
- kIsMathMLFlag = 1 << 5,
- kIsSVGFlag = 1 << 6,
- kIsDocumentFragmentFlag = 1 << 7,
- kIsV0InsertionPointFlag = 1 << 8,
+ kIsContainerFlag = 1 << 1,
+ kDOMNodeTypeMask = 0x3 << kDOMNodeTypeShift,
+ kElementNamespaceTypeMask = 0x3 << kElementNamespaceTypeShift,
+ kIsV0InsertionPointFlag = 1 << 6,
// Changes based on if the element should be treated like a link,
// ex. When setting the href attribute on an <a>.
- kIsLinkFlag = 1 << 9,
+ kIsLinkFlag = 1 << 7,
// Changes based on :hover, :active and :focus state.
- kIsUserActionElementFlag = 1 << 10,
+ kIsUserActionElementFlag = 1 << 8,
// Tree state flags. These change when the element is added/removed
// from a DOM tree.
- kIsConnectedFlag = 1 << 11,
- kIsInShadowTreeFlag = 1 << 12,
+ kIsConnectedFlag = 1 << 9,
+ kIsInShadowTreeFlag = 1 << 10,
// Set by the parser when the children are done parsing.
- kIsFinishedParsingChildrenFlag = 1 << 13,
+ kIsFinishedParsingChildrenFlag = 1 << 11,
// Flags related to recalcStyle.
- kHasCustomStyleCallbacksFlag = 1 << 14,
- kChildNeedsStyleInvalidationFlag = 1 << 15,
- kNeedsStyleInvalidationFlag = 1 << 16,
- kChildNeedsDistributionRecalcFlag = 1 << 17,
- kChildNeedsStyleRecalcFlag = 1 << 18,
- kStyleChangeMask =
- 1 << kNodeStyleChangeShift | 1 << (kNodeStyleChangeShift + 1),
+ kHasCustomStyleCallbacksFlag = 1 << 12,
+ kChildNeedsStyleInvalidationFlag = 1 << 13,
+ kNeedsStyleInvalidationFlag = 1 << 14,
+ kChildNeedsDistributionRecalcFlag = 1 << 15,
+ kChildNeedsStyleRecalcFlag = 1 << 16,
+ kStyleChangeMask = 0x3 << kNodeStyleChangeShift,
kCustomElementStateMask = 0x3 << kNodeCustomElementShift,
- kHasNameOrIsEditingTextFlag = 1 << 23,
- kHasEventTargetDataFlag = 1 << 24,
-
- kV0CustomElementFlag = 1 << 25,
- kV0CustomElementUpgradedFlag = 1 << 26,
+ kHasNameOrIsEditingTextFlag = 1 << 21,
+ kHasEventTargetDataFlag = 1 << 22,
- kNeedsReattachLayoutTree = 1 << 27,
- kChildNeedsReattachLayoutTree = 1 << 28,
+ kV0CustomElementFlag = 1 << 23,
+ kV0CustomElementUpgradedFlag = 1 << 24,
- kHasDuplicateAttributes = 1 << 29,
+ kNeedsReattachLayoutTree = 1 << 25,
+ kChildNeedsReattachLayoutTree = 1 << 26,
- // Temporary flag for some UseCounter items. crbug.com/859391.
- kInDOMNodeRemovedHandler = 1 << 30,
+ kHasDuplicateAttributes = 1 << 27,
- kForceReattachLayoutTree = 1 << 31,
+ kForceReattachLayoutTree = 1 << 28,
kDefaultNodeFlags = kIsFinishedParsingChildrenFlag,
- };
- // 0 bits remaining.
+ // 4 bits remaining.
+ };
- bool GetFlag(NodeFlags mask) const { return node_flags_ & mask; }
+ ALWAYS_INLINE bool GetFlag(NodeFlags mask) const {
+ return node_flags_ & mask;
+ }
void SetFlag(bool f, NodeFlags mask) {
node_flags_ = (node_flags_ & ~mask) | (-(int32_t)f & mask);
}
void SetFlag(NodeFlags mask) { node_flags_ |= mask; }
void ClearFlag(NodeFlags mask) { node_flags_ &= ~mask; }
+ enum class DOMNodeType : uint32_t {
+ kElement = 0,
+ kText = 1 << kDOMNodeTypeShift,
+ kDocumentFragment = 2 << kDOMNodeTypeShift,
+ kOther = 3 << kDOMNodeTypeShift,
+ };
+ ALWAYS_INLINE DOMNodeType GetDOMNodeType() const {
+ return static_cast<DOMNodeType>(node_flags_ & kDOMNodeTypeMask);
+ }
+
+ enum class ElementNamespaceType : uint32_t {
+ kHTML = 0,
+ kMathML = 1 << kElementNamespaceTypeShift,
+ kSVG = 2 << kElementNamespaceTypeShift,
+ kOther = 3 << kElementNamespaceTypeShift,
+ };
+ ALWAYS_INLINE ElementNamespaceType GetElementNamespaceType() const {
+ return static_cast<ElementNamespaceType>(node_flags_ &
+ kElementNamespaceTypeMask);
+ }
+
protected:
enum ConstructionType {
- kCreateOther = kIsFinishedParsingChildrenFlag,
- kCreateText = kDefaultNodeFlags | kIsTextFlag,
- kCreateContainer = kDefaultNodeFlags | kIsContainerFlag,
- kCreateElement = kCreateContainer | kIsElementFlag,
- kCreateShadowRoot =
- kCreateContainer | kIsDocumentFragmentFlag | kIsInShadowTreeFlag,
- kCreateDocumentFragment = kCreateContainer | kIsDocumentFragmentFlag,
- kCreateHTMLElement = kCreateElement | kIsHTMLFlag,
- kCreateMathMLElement = kCreateElement | kIsMathMLFlag,
- kCreateSVGElement = kCreateElement | kIsSVGFlag,
+ kCreateOther = kDefaultNodeFlags |
+ static_cast<NodeFlags>(DOMNodeType::kOther) |
+ static_cast<NodeFlags>(ElementNamespaceType::kOther),
+ kCreateText = kDefaultNodeFlags |
+ static_cast<NodeFlags>(DOMNodeType::kText) |
+ static_cast<NodeFlags>(ElementNamespaceType::kOther),
+ kCreateContainer = kDefaultNodeFlags | kIsContainerFlag |
+ static_cast<NodeFlags>(DOMNodeType::kOther) |
+ static_cast<NodeFlags>(ElementNamespaceType::kOther),
+ kCreateElement = kDefaultNodeFlags | kIsContainerFlag |
+ static_cast<NodeFlags>(DOMNodeType::kElement) |
+ static_cast<NodeFlags>(ElementNamespaceType::kOther),
+ kCreateDocumentFragment =
+ kDefaultNodeFlags | kIsContainerFlag |
+ static_cast<NodeFlags>(DOMNodeType::kDocumentFragment) |
+ static_cast<NodeFlags>(ElementNamespaceType::kOther),
+ kCreateShadowRoot = kCreateDocumentFragment | kIsInShadowTreeFlag,
+ kCreateHTMLElement = kDefaultNodeFlags | kIsContainerFlag |
+ static_cast<NodeFlags>(DOMNodeType::kElement) |
+ static_cast<NodeFlags>(ElementNamespaceType::kHTML),
+ kCreateMathMLElement =
+ kDefaultNodeFlags | kIsContainerFlag |
+ static_cast<NodeFlags>(DOMNodeType::kElement) |
+ static_cast<NodeFlags>(ElementNamespaceType::kMathML),
+ kCreateSVGElement = kDefaultNodeFlags | kIsContainerFlag |
+ static_cast<NodeFlags>(DOMNodeType::kElement) |
+ static_cast<NodeFlags>(ElementNamespaceType::kSVG),
kCreateDocument = kCreateContainer | kIsConnectedFlag,
kCreateV0InsertionPoint = kCreateHTMLElement | kIsV0InsertionPointFlag,
kCreateEditingText = kCreateText | kHasNameOrIsEditingTextFlag,
@@ -1009,7 +1060,7 @@ class CORE_EXPORT Node : public EventTarget {
NodeRareData* RareData() const {
SECURITY_DCHECK(HasRareData());
- return static_cast<NodeRareData*>(data_.rare_data_);
+ return DataAsNodeRareData();
}
NodeRareData& EnsureRareData() {
if (HasRareData())
@@ -1063,8 +1114,14 @@ class CORE_EXPORT Node : public EventTarget {
const HeapHashSet<Member<MutationObserverRegistration>>*
TransientMutationObserverRegistry();
- inline Node* TrustedTypesCheckForScriptNode(Node* child,
- ExceptionState&) const;
+ NodeRareData* DataAsNodeRareData() const {
+ DCHECK(HasRareData());
+ return reinterpret_cast<NodeRareData*>(data_.Get());
+ }
+ NodeRenderingData* DataAsNodeRenderingData() const {
+ DCHECK(!HasRareData());
+ return reinterpret_cast<NodeRenderingData*>(data_.Get());
+ }
uint32_t node_flags_;
Member<Node> parent_or_shadow_host_node_;
@@ -1072,13 +1129,7 @@ class CORE_EXPORT Node : public EventTarget {
Member<Node> previous_;
Member<Node> next_;
// When a node has rare data we move the layoutObject into the rare data.
- union DataUnion {
- DataUnion() : node_layout_data_(&NodeRenderingData::SharedEmptyData()) {}
- // LayoutObjects are fully owned by their DOM node. See LayoutObject's
- // LIFETIME documentation section.
- NodeRenderingData* node_layout_data_;
- NodeRareDataBase* rare_data_;
- } data_;
+ Member<NodeData> data_;
};
inline void Node::SetParentOrShadowHostNode(ContainerNode* parent) {
@@ -1094,14 +1145,6 @@ inline ContainerNode* Node::ParentOrShadowHostNode() const {
// Allow equality comparisons of Nodes by reference or pointer, interchangeably.
DEFINE_COMPARISON_OPERATORS_WITH_REFERENCES(Node)
-#define DEFINE_NODE_TYPE_CASTS(thisType, predicate) \
- DEFINE_TYPE_CASTS(thisType, Node, node, node->predicate, node.predicate)
-
-// This requires isClassName(const Node&).
-#define DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(thisType) \
- DEFINE_TYPE_CASTS(thisType, Node, node, Is##thisType(*node), \
- Is##thisType(node))
-
CORE_EXPORT std::ostream& operator<<(std::ostream&, const Node&);
CORE_EXPORT std::ostream& operator<<(std::ostream&, const Node*);
diff --git a/chromium/third_party/blink/renderer/core/dom/node.idl b/chromium/third_party/blink/renderer/core/dom/node.idl
index 758feb3d188..f3e793fdb01 100644
--- a/chromium/third_party/blink/renderer/core/dom/node.idl
+++ b/chromium/third_party/blink/renderer/core/dom/node.idl
@@ -46,7 +46,7 @@
[Affects=Nothing, Measure] readonly attribute boolean isConnected;
[Affects=Nothing, PerWorldBindings] readonly attribute Document? ownerDocument;
- [Affects=Nothing, PerWorldBindings, ImplementedAs=ParentNodeWithCounting] readonly attribute Node? parentNode;
+ [Affects=Nothing, PerWorldBindings] readonly attribute Node? parentNode;
[Affects=Nothing, PerWorldBindings] readonly attribute Element? parentElement;
[Affects=Nothing, ImplementedAs=hasChildren] boolean hasChildNodes();
[Affects=Nothing, SameObject, PerWorldBindings] readonly attribute NodeList childNodes;
@@ -54,11 +54,11 @@
[Affects=Nothing, PerWorldBindings] readonly attribute Node? lastChild;
[Affects=Nothing, PerWorldBindings] readonly attribute Node? previousSibling;
[Affects=Nothing, PerWorldBindings] readonly attribute Node? nextSibling;
- [MeasureAs=NodeGetRootNode] Node getRootNode(optional GetRootNodeOptions options);
+ [MeasureAs=NodeGetRootNode] Node getRootNode(optional GetRootNodeOptions options = {});
[Affects=Nothing, CEReactions, CustomElementCallbacks] attribute DOMString? nodeValue;
- [Affects=Nothing, CEReactions, CustomElementCallbacks, RaisesException=Setter] attribute ScriptString? textContent;
+ [Affects=Nothing, CEReactions, CustomElementCallbacks, RaisesException=Setter] attribute (DOMString or TrustedScript)? textContent;
[CEReactions, CustomElementCallbacks] void normalize();
[NewObject, DoNotTestNewObject, CEReactions, CustomElementCallbacks, RaisesException] Node cloneNode(optional boolean deep = false);
diff --git a/chromium/third_party/blink/renderer/core/dom/node_child_removal_tracker.h b/chromium/third_party/blink/renderer/core/dom/node_child_removal_tracker.h
index afb769a183d..8e8df211f22 100644
--- a/chromium/third_party/blink/renderer/core/dom/node_child_removal_tracker.h
+++ b/chromium/third_party/blink/renderer/core/dom/node_child_removal_tracker.h
@@ -27,7 +27,6 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_NODE_CHILD_REMOVAL_TRACKER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_NODE_CHILD_REMOVAL_TRACKER_H_
-#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -46,15 +45,15 @@ class NodeChildRemovalTracker {
const Node& GetNode() const { return *node_; }
NodeChildRemovalTracker* Previous() { return previous_; }
- Member<const Node> node_;
+ const Node* node_;
// Using raw pointers are safe because these NodeChildRemovalTrackers are
// guaranteed to be on a stack.
NodeChildRemovalTracker* previous_;
- CORE_EXPORT static NodeChildRemovalTracker* last_;
+ static NodeChildRemovalTracker* last_;
};
inline NodeChildRemovalTracker::NodeChildRemovalTracker(const Node& node)
- : node_(node), previous_(last_) {
+ : node_(&node), previous_(last_) {
last_ = this;
}
diff --git a/chromium/third_party/blink/renderer/core/dom/node_computed_style.h b/chromium/third_party/blink/renderer/core/dom/node_computed_style.h
index a870a3d2610..3d28403ddc9 100644
--- a/chromium/third_party/blink/renderer/core/dom/node_computed_style.h
+++ b/chromium/third_party/blink/renderer/core/dom/node_computed_style.h
@@ -39,9 +39,10 @@ inline ComputedStyle* Node::MutableComputedStyleForEditingDeprecated() const {
inline const ComputedStyle* Node::GetComputedStyle() const {
if (IsElementNode()) {
- return HasRareData()
- ? data_.rare_data_->GetNodeRenderingData()->GetComputedStyle()
- : data_.node_layout_data_->GetComputedStyle();
+ return HasRareData() ? DataAsNodeRareData()
+ ->GetNodeRenderingData()
+ ->GetComputedStyle()
+ : DataAsNodeRenderingData()->GetComputedStyle();
}
// Text nodes and Document.
if (LayoutObject* layout_object = GetLayoutObject())
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 09cb934340b..375ba7f6d5c 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
@@ -39,20 +39,18 @@ class NodeListsNodeData final : public GarbageCollected<NodeListsNodeData> {
public:
ChildNodeList* GetChildNodeList(ContainerNode& node) {
DCHECK(!child_node_list_ || node == child_node_list_->VirtualOwnerNode());
- return ToChildNodeList(child_node_list_);
+ return To<ChildNodeList>(child_node_list_.Get());
}
ChildNodeList* EnsureChildNodeList(ContainerNode& node) {
- DCHECK(ThreadState::Current()->IsGCForbidden());
if (child_node_list_)
- return ToChildNodeList(child_node_list_);
+ return To<ChildNodeList>(child_node_list_.Get());
auto* list = MakeGarbageCollected<ChildNodeList>(node);
child_node_list_ = list;
return list;
}
EmptyNodeList* EnsureEmptyChildNodeList(Node& node) {
- DCHECK(ThreadState::Current()->IsGCForbidden());
if (child_node_list_)
return To<EmptyNodeList>(child_node_list_.Get());
auto* list = MakeGarbageCollected<EmptyNodeList>(node);
@@ -88,7 +86,6 @@ class NodeListsNodeData final : public GarbageCollected<NodeListsNodeData> {
T* AddCache(ContainerNode& node,
CollectionType collection_type,
const AtomicString& name) {
- DCHECK(ThreadState::Current()->IsGCForbidden());
NodeListAtomicNameCacheMap::AddResult result = atomic_name_caches_.insert(
std::make_pair(collection_type, name), nullptr);
if (!result.is_new_entry) {
@@ -102,7 +99,6 @@ class NodeListsNodeData final : public GarbageCollected<NodeListsNodeData> {
template <typename T>
T* AddCache(ContainerNode& node, CollectionType collection_type) {
- DCHECK(ThreadState::Current()->IsGCForbidden());
NodeListAtomicNameCacheMap::AddResult result = atomic_name_caches_.insert(
NamedNodeListKey(collection_type, CSSSelector::UniversalSelectorAtom()),
nullptr);
@@ -124,15 +120,14 @@ class NodeListsNodeData final : public GarbageCollected<NodeListsNodeData> {
TagCollectionNS* AddCache(ContainerNode& node,
const AtomicString& namespace_uri,
const AtomicString& local_name) {
- DCHECK(ThreadState::Current()->IsGCForbidden());
QualifiedName name(g_null_atom, local_name, namespace_uri);
TagCollectionNSCache::AddResult result =
tag_collection_ns_caches_.insert(name, nullptr);
if (!result.is_new_entry)
return result.stored_value->value;
- TagCollectionNS* list =
- TagCollectionNS::Create(node, namespace_uri, local_name);
+ auto* list = MakeGarbageCollected<TagCollectionNS>(
+ node, kTagCollectionNSType, namespace_uri, local_name);
result.stored_value->value = list;
return list;
}
@@ -183,7 +178,6 @@ class NodeListsNodeData final : public GarbageCollected<NodeListsNodeData> {
template <typename Collection>
inline Collection* ContainerNode::EnsureCachedCollection(CollectionType type) {
- ThreadState::MainThreadGCForbiddenScope gc_forbidden;
return EnsureNodeLists().AddCache<Collection>(*this, type);
}
@@ -191,7 +185,6 @@ template <typename Collection>
inline Collection* ContainerNode::EnsureCachedCollection(
CollectionType type,
const AtomicString& name) {
- ThreadState::MainThreadGCForbiddenScope gc_forbidden;
return EnsureNodeLists().AddCache<Collection>(*this, type, name);
}
@@ -201,7 +194,6 @@ inline Collection* ContainerNode::EnsureCachedCollection(
const AtomicString& namespace_uri,
const AtomicString& local_name) {
DCHECK_EQ(type, kTagCollectionNSType);
- ThreadState::MainThreadGCForbiddenScope gc_forbidden;
return EnsureNodeLists().AddCache(*this, namespace_uri, local_name);
}
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 8b4d8a63bd0..50a72f9dee0 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
@@ -37,13 +37,13 @@
#include "third_party/blink/renderer/core/dom/mutation_observer_registration.h"
#include "third_party/blink/renderer/core/dom/node_lists_node_data.h"
#include "third_party/blink/renderer/core/page/page.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
struct SameSizeAsNodeRareData {
- void* pointer_;
- Member<void*> willbe_member_[3];
+ Member<void*> willbe_member_[4];
unsigned bitfields_;
};
@@ -77,25 +77,47 @@ void NodeMutationObserverData::RemoveRegistration(
registry_.EraseAt(registry_.Find(registration));
}
-void NodeRareData::TraceAfterDispatch(blink::Visitor* visitor) {
- visitor->Trace(mutation_observer_data_);
- visitor->Trace(flat_tree_node_data_);
- // Do not keep empty NodeListsNodeData objects around.
- if (node_lists_ && node_lists_->IsEmpty())
- node_lists_.Clear();
- else
- visitor->Trace(node_lists_);
+void NodeData::Trace(Visitor* visitor) {
+ if (bit_field_.get_concurrently<IsRareData>()) {
+ if (bit_field_.get_concurrently<IsElementRareData>())
+ static_cast<ElementRareData*>(this)->TraceAfterDispatch(visitor);
+ else
+ static_cast<NodeRareData*>(this)->TraceAfterDispatch(visitor);
+ } else {
+ static_cast<NodeRenderingData*>(this)->TraceAfterDispatch(visitor);
+ }
}
-void NodeRareData::Trace(Visitor* visitor) {
- if (is_element_rare_data_)
- static_cast<ElementRareData*>(this)->TraceAfterDispatch(visitor);
- else
- TraceAfterDispatch(visitor);
+NodeRenderingData::NodeRenderingData(
+ LayoutObject* layout_object,
+ scoped_refptr<const ComputedStyle> computed_style)
+ : NodeData(false, false),
+ layout_object_(layout_object),
+ computed_style_(computed_style) {}
+
+void NodeRenderingData::SetComputedStyle(
+ scoped_refptr<const ComputedStyle> computed_style) {
+ DCHECK_NE(&SharedEmptyData(), this);
+ computed_style_ = computed_style;
+}
+
+NodeRenderingData& NodeRenderingData::SharedEmptyData() {
+ DEFINE_STATIC_LOCAL(
+ Persistent<NodeRenderingData>, shared_empty_data,
+ (MakeGarbageCollected<NodeRenderingData>(nullptr, nullptr)));
+ return *shared_empty_data;
+}
+
+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_);
+ NodeData::TraceAfterDispatch(visitor);
}
void NodeRareData::FinalizeGarbageCollectedObject() {
- if (is_element_rare_data_)
+ if (bit_field_.get<IsElementRareData>())
static_cast<ElementRareData*>(this)->~ElementRareData();
else
this->~NodeRareData();
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 6daa78adc8b..f38a3374e33 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
@@ -25,6 +25,7 @@
#include "base/macros.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/bit_field.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
namespace blink {
@@ -63,13 +64,48 @@ class NodeMutationObserverData final
DISALLOW_COPY_AND_ASSIGN(NodeMutationObserverData);
};
-class NodeRenderingData {
- USING_FAST_MALLOC(NodeRenderingData);
+class GC_PLUGIN_IGNORE(
+ "GC plugin reports that TraceAfterDispatch is not called but it is called "
+ "by both NodeRareDate::TraceAfterDispatch and "
+ "NodeRenderingData::TraceAfterDispatch.") NodeData
+ : public GarbageCollected<NodeData> {
+ public:
+ NodeData(bool is_rare_data, bool is_element_rare_data)
+ : connected_frame_count_(0),
+ element_flags_(0),
+ bit_field_(RestyleFlags::encode(0) |
+ IsElementRareData::encode(is_element_rare_data) |
+ IsRareData::encode(is_rare_data)) {
+ DCHECK(!is_element_rare_data || is_rare_data);
+ }
+ void Trace(Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const {}
+
+ enum {
+ kConnectedFrameCountBits = 10, // Must fit Page::maxNumberOfFrames.
+ kNumberOfElementFlags = 6,
+ kNumberOfDynamicRestyleFlags = 14
+ };
+
+ protected:
+ using BitField = WTF::ConcurrentlyReadBitField<uint16_t>;
+ using RestyleFlags =
+ BitField::DefineFirstValue<uint16_t, kNumberOfDynamicRestyleFlags>;
+ using IsElementRareData = RestyleFlags::
+ DefineNextValue<bool, 1, WTF::BitFieldValueConstness::kConst>;
+ using IsRareData = IsElementRareData::
+ DefineNextValue<bool, 1, WTF::BitFieldValueConstness::kConst>;
+
+ uint16_t connected_frame_count_ : kConnectedFrameCountBits;
+ uint16_t element_flags_ : kNumberOfElementFlags;
+ BitField bit_field_;
+};
+class GC_PLUGIN_IGNORE("Manual dispatch implemented in NodeData.")
+ NodeRenderingData final : public NodeData {
public:
NodeRenderingData(LayoutObject*,
scoped_refptr<const ComputedStyle> computed_style);
- ~NodeRenderingData();
LayoutObject* GetLayoutObject() const { return layout_object_; }
void SetLayoutObject(LayoutObject* layout_object) {
@@ -85,51 +121,34 @@ class NodeRenderingData {
static NodeRenderingData& SharedEmptyData();
bool IsSharedEmptyData() { return this == &SharedEmptyData(); }
+ void TraceAfterDispatch(Visitor* visitor) const {
+ NodeData::TraceAfterDispatch(visitor);
+ }
+
private:
LayoutObject* layout_object_;
scoped_refptr<const ComputedStyle> computed_style_;
DISALLOW_COPY_AND_ASSIGN(NodeRenderingData);
};
-class NodeRareDataBase {
+class GC_PLUGIN_IGNORE("Manual dispatch implemented in NodeData.") NodeRareData
+ : public NodeData {
public:
+ explicit NodeRareData(NodeRenderingData* node_layout_data)
+ : NodeRareData(node_layout_data, false) {}
+
NodeRenderingData* GetNodeRenderingData() const { return node_layout_data_; }
void SetNodeRenderingData(NodeRenderingData* node_layout_data) {
DCHECK(node_layout_data);
node_layout_data_ = node_layout_data;
}
- protected:
- explicit NodeRareDataBase(NodeRenderingData* node_layout_data)
- : node_layout_data_(node_layout_data) {}
- ~NodeRareDataBase() {
- if (node_layout_data_ && !node_layout_data_->IsSharedEmptyData())
- delete node_layout_data_;
- }
-
- protected:
- NodeRenderingData* node_layout_data_;
-};
-
-class NodeRareData : public GarbageCollected<NodeRareData>,
- public NodeRareDataBase {
- public:
- explicit NodeRareData(NodeRenderingData* node_layout_data)
- : NodeRareDataBase(node_layout_data),
- connected_frame_count_(0),
- element_flags_(0),
- restyle_flags_(0),
- is_element_rare_data_(false) {
- CHECK_NE(node_layout_data, nullptr);
- }
-
void ClearNodeLists() { node_lists_.Clear(); }
NodeListsNodeData* NodeLists() const { return node_lists_.Get(); }
// EnsureNodeLists() and a following NodeListsNodeData functions must be
// wrapped with a ThreadState::GCForbiddenScope in order to avoid an
// initialized node_lists_ is cleared by NodeRareData::TraceAfterDispatch().
NodeListsNodeData& EnsureNodeLists() {
- DCHECK(ThreadState::Current()->IsGCForbidden());
if (!node_lists_)
return CreateNodeLists();
return *node_lists_;
@@ -149,7 +168,7 @@ class NodeRareData : public GarbageCollected<NodeRareData>,
return *mutation_observer_data_;
}
- unsigned ConnectedSubframeCount() const { return connected_frame_count_; }
+ uint16_t ConnectedSubframeCount() const { return connected_frame_count_; }
void IncrementConnectedSubframeCount();
void DecrementConnectedSubframeCount() {
DCHECK(connected_frame_count_);
@@ -157,36 +176,41 @@ class NodeRareData : public GarbageCollected<NodeRareData>,
}
bool HasElementFlag(ElementFlags mask) const {
- return element_flags_ & static_cast<unsigned>(mask);
+ return element_flags_ & static_cast<uint16_t>(mask);
}
void SetElementFlag(ElementFlags mask, bool value) {
- element_flags_ = (element_flags_ & ~static_cast<unsigned>(mask)) |
- (-(int32_t)value & static_cast<unsigned>(mask));
+ element_flags_ =
+ (element_flags_ & ~static_cast<uint16_t>(mask)) |
+ (-static_cast<uint16_t>(value) & static_cast<uint16_t>(mask));
}
void ClearElementFlag(ElementFlags mask) {
- element_flags_ &= ~static_cast<unsigned>(mask);
+ element_flags_ &= ~static_cast<uint16_t>(mask);
}
bool HasRestyleFlag(DynamicRestyleFlags mask) const {
- return restyle_flags_ & static_cast<unsigned>(mask);
+ return bit_field_.get<RestyleFlags>() & static_cast<uint16_t>(mask);
}
void SetRestyleFlag(DynamicRestyleFlags mask) {
- restyle_flags_ |= static_cast<unsigned>(mask);
- CHECK(restyle_flags_);
+ bit_field_.set<RestyleFlags>(bit_field_.get<RestyleFlags>() |
+ static_cast<uint16_t>(mask));
+ CHECK(bit_field_.get<RestyleFlags>());
}
- bool HasRestyleFlags() const { return restyle_flags_; }
- void ClearRestyleFlags() { restyle_flags_ = 0; }
+ bool HasRestyleFlags() const { return bit_field_.get<RestyleFlags>(); }
+ void ClearRestyleFlags() { bit_field_.set<RestyleFlags>(0); }
- enum {
- kConnectedFrameCountBits = 10, // Must fit Page::maxNumberOfFrames.
- kNumberOfElementFlags = 6,
- kNumberOfDynamicRestyleFlags = 14
- };
-
- void Trace(Visitor*);
- void TraceAfterDispatch(blink::Visitor*);
+ void TraceAfterDispatch(blink::Visitor*) const;
void FinalizeGarbageCollectedObject();
+ protected:
+ explicit NodeRareData(NodeRenderingData* node_layout_data,
+ bool is_element_rare_data)
+ : NodeData(true, is_element_rare_data),
+ node_layout_data_(node_layout_data) {
+ CHECK_NE(node_layout_data, nullptr);
+ }
+
+ Member<NodeRenderingData> node_layout_data_;
+
private:
NodeListsNodeData& CreateNodeLists();
@@ -194,12 +218,6 @@ class NodeRareData : public GarbageCollected<NodeRareData>,
Member<NodeMutationObserverData> mutation_observer_data_;
Member<FlatTreeNodeData> flat_tree_node_data_;
- unsigned connected_frame_count_ : kConnectedFrameCountBits;
- unsigned element_flags_ : kNumberOfElementFlags;
- unsigned restyle_flags_ : kNumberOfDynamicRestyleFlags;
-
- protected:
- unsigned is_element_rare_data_ : 1;
DISALLOW_COPY_AND_ASSIGN(NodeRareData);
};
diff --git a/chromium/third_party/blink/renderer/core/dom/node_test.cc b/chromium/third_party/blink/renderer/core/dom/node_test.cc
index 4156ce2f7d8..96d805be445 100644
--- a/chromium/third_party/blink/renderer/core/dom/node_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/node_test.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_shadow_root_init.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
#include "third_party/blink/renderer/core/css/style_engine.h"
#include "third_party/blink/renderer/core/dom/comment.h"
@@ -14,7 +15,6 @@
#include "third_party/blink/renderer/core/dom/processing_instruction.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/shadow_root_init.h"
#include "third_party/blink/renderer/core/dom/slot_assignment_engine.h"
#include "third_party/blink/renderer/core/editing/testing/editing_test_base.h"
#include "third_party/blink/renderer/core/html/html_div_element.h"
@@ -269,7 +269,7 @@ TEST_F(NodeTest, AttachContext_PreviousInFlow_Slotted) {
ShadowRoot& shadow_root =
GetDocument().getElementById("host")->AttachShadowRootInternal(
ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString(
+ shadow_root.setInnerHTML(
"<div id=root style='display:contents'><span></span><slot></slot></div>");
UpdateAllLifecyclePhasesForTest();
@@ -352,8 +352,7 @@ TEST_F(NodeTest, SkipStyleDirtyHostChild) {
Element* host = GetDocument().getElementById("host");
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString(
- "<div style='display:none'><slot></slot></div>");
+ shadow_root.setInnerHTML("<div style='display:none'><slot></slot></div>");
UpdateAllLifecyclePhasesForTest();
EXPECT_FALSE(GetDocument().NeedsLayoutTreeUpdate());
@@ -392,7 +391,7 @@ TEST_F(NodeTest, SkipForceReattachDisplayNone) {
Element* host = GetDocument().getElementById("host");
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString("<slot name='target'></slot>");
+ shadow_root.setInnerHTML("<slot name='target'></slot>");
UpdateAllLifecyclePhasesForTest();
Element* span = To<Element>(host->firstChild());
@@ -413,7 +412,7 @@ TEST_F(NodeTest, UpdateChildDirtyAncestorsOnSlotAssignment) {
Element* host = GetDocument().getElementById("host");
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString(
+ shadow_root.setInnerHTML(
"<div><slot></slot></div><div id='child-dirty'><slot "
"name='target'></slot></div>");
UpdateAllLifecyclePhasesForTest();
@@ -439,7 +438,7 @@ TEST_F(NodeTest, UpdateChildDirtySlotAfterRemoval) {
Element* host = GetDocument().getElementById("host");
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString("<slot></slot>");
+ shadow_root.setInnerHTML("<slot></slot>");
UpdateAllLifecyclePhasesForTest();
auto* span = To<Element>(host->firstChild());
@@ -471,7 +470,7 @@ TEST_F(NodeTest, UpdateChildDirtyAfterSlotRemoval) {
Element* host = GetDocument().getElementById("host");
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString("<div><slot></slot></div>");
+ shadow_root.setInnerHTML("<div><slot></slot></div>");
UpdateAllLifecyclePhasesForTest();
auto* span = To<Element>(host->firstChild());
@@ -513,7 +512,7 @@ TEST_F(NodeTest, UpdateChildDirtyAfterSlottingDirtyNode) {
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString("<div><slot name=x></slot></div>");
+ shadow_root.setInnerHTML("<div><slot name=x></slot></div>");
UpdateAllLifecyclePhasesForTest();
// Make sure the span is style dirty.
diff --git a/chromium/third_party/blink/renderer/core/dom/node_with_index.h b/chromium/third_party/blink/renderer/core/dom/node_with_index.h
index fbbb90d5157..ac401632f6a 100644
--- a/chromium/third_party/blink/renderer/core/dom/node_with_index.h
+++ b/chromium/third_party/blink/renderer/core/dom/node_with_index.h
@@ -37,7 +37,7 @@ class NodeWithIndex {
STACK_ALLOCATED();
public:
- explicit NodeWithIndex(Node& node) : node_(node), index_(-1) {}
+ explicit NodeWithIndex(Node& node) : node_(&node), index_(-1) {}
Node& GetNode() const { return *node_; }
@@ -53,7 +53,7 @@ class NodeWithIndex {
private:
bool HasIndex() const { return index_ >= 0; }
- Member<Node> node_;
+ Node* node_;
mutable int index_;
};
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 b2aa37a7b9b..002e8c3f808 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
@@ -55,9 +55,9 @@ class CORE_EXPORT NthIndexCache final {
IndexByType& EnsureTypeIndexMap(ContainerNode&);
NthIndexData* NthTypeIndexDataForParent(Element&) const;
- Member<Document> document_;
- Member<ParentMap> parent_map_;
- Member<ParentMapForType> parent_map_for_type_;
+ Document* document_ = nullptr;
+ ParentMap* parent_map_ = nullptr;
+ ParentMapForType* parent_map_for_type_ = nullptr;
#if DCHECK_IS_ON()
uint64_t dom_tree_version_;
diff --git a/chromium/third_party/blink/renderer/core/dom/nth_index_cache_test.cc b/chromium/third_party/blink/renderer/core/dom/nth_index_cache_test.cc
index 128459bb123..942d9b4f3d5 100644
--- a/chromium/third_party/blink/renderer/core/dom/nth_index_cache_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/nth_index_cache_test.cc
@@ -15,7 +15,7 @@ namespace blink {
class NthIndexCacheTest : public PageTestBase {};
TEST_F(NthIndexCacheTest, NthIndex) {
- GetDocument().documentElement()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().documentElement()->setInnerHTML(R"HTML(
<body>
<span
id=first></span><span></span><span></span><span></span><span></span>
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 c7e29ddcf5c..be5780126f8 100644
--- a/chromium/third_party/blink/renderer/core/dom/processing_instruction.cc
+++ b/chromium/third_party/blink/renderer/core/dom/processing_instruction.cc
@@ -138,7 +138,8 @@ void ProcessingInstruction::Process(const String& href, const String& charset) {
// can hang off some parent sheet.
if (is_xsl_ && RuntimeEnabledFeatures::XSLTEnabled()) {
KURL final_url(local_href_);
- sheet_ = XSLStyleSheet::CreateEmbedded(this, final_url);
+ sheet_ = MakeGarbageCollected<XSLStyleSheet>(this, final_url.GetString(),
+ final_url, true);
loading_ = false;
}
return;
@@ -195,9 +196,9 @@ void ProcessingInstruction::NotifyFinished(Resource* resource) {
is_xsl_ ? std::make_unique<IncrementLoadEventDelayCount>(GetDocument())
: nullptr;
if (is_xsl_) {
- sheet_ = XSLStyleSheet::Create(this, resource->Url(),
- resource->GetResponse().ResponseUrl());
- ToXSLStyleSheet(sheet_.Get())
+ sheet_ = MakeGarbageCollected<XSLStyleSheet>(
+ this, resource->Url(), resource->GetResponse().ResponseUrl(), false);
+ To<XSLStyleSheet>(sheet_.Get())
->ParseString(ToXSLStyleSheetResource(resource)->Sheet());
} else {
DCHECK(is_css_);
@@ -217,7 +218,8 @@ void ProcessingInstruction::NotifyFinished(Resource* resource) {
GetDocument().GetStyleEngine().SetPreferredStylesheetSetNameIfNotSet(
title_);
}
- css_sheet->SetMediaQueries(MediaQuerySet::Create(media_));
+ css_sheet->SetMediaQueries(
+ MediaQuerySet::Create(media_, GetExecutionContext()));
sheet_ = css_sheet;
// We don't need the cross-origin security check here because we are
// getting the sheet text in "strict" mode. This enforces a valid CSS MIME
@@ -232,7 +234,7 @@ void ProcessingInstruction::NotifyFinished(Resource* resource) {
if (is_css_)
To<CSSStyleSheet>(sheet_.Get())->Contents()->CheckLoaded();
else if (is_xsl_)
- ToXSLStyleSheet(sheet_.Get())->CheckLoaded();
+ To<XSLStyleSheet>(sheet_.Get())->CheckLoaded();
}
Node::InsertionNotificationRequest ProcessingInstruction::InsertedInto(
@@ -282,6 +284,8 @@ void ProcessingInstruction::ClearSheet() {
}
void ProcessingInstruction::RemovePendingSheet() {
+ if (is_xsl_)
+ return;
GetDocument().GetStyleEngine().RemovePendingSheet(*this,
style_engine_context_);
}
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 146cefae08d..2f7c2899e92 100644
--- a/chromium/third_party/blink/renderer/core/dom/pseudo_element.cc
+++ b/chromium/third_party/blink/renderer/core/dom/pseudo_element.cc
@@ -35,6 +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/probe/core_probes.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style/content_data.h"
@@ -160,6 +161,17 @@ PseudoElement::AttachLayoutTreeScope::~AttachLayoutTreeScope() {
void PseudoElement::AttachLayoutTree(AttachContext& context) {
DCHECK(!GetLayoutObject());
+
+ // Some elements may have 'display: list-item' but not be list items.
+ // Do not create a layout object for the ::marker in that case.
+ if (pseudo_id_ == kPseudoIdMarker) {
+ LayoutObject* originating_layout = parentNode()->GetLayoutObject();
+ if (!originating_layout || !originating_layout->IsListItemIncludingNG()) {
+ Node::AttachLayoutTree(context);
+ return;
+ }
+ }
+
{
AttachLayoutTreeScope scope(this);
Element::AttachLayoutTree(context);
@@ -176,12 +188,28 @@ void PseudoElement::AttachLayoutTree(AttachContext& context) {
DCHECK(CanHaveGeneratedChildren(*layout_object->Parent()));
const ComputedStyle& style = layout_object->StyleRef();
- if (style.StyleType() != kPseudoIdBefore &&
- style.StyleType() != kPseudoIdAfter &&
- style.StyleType() != kPseudoIdMarker)
- return;
- DCHECK(style.GetContentData());
+ switch (pseudo_id_) {
+ case kPseudoIdMarker: {
+ if (ListMarker* marker = ListMarker::Get(layout_object)) {
+ marker->UpdateMarkerContentIfNeeded(*layout_object);
+ } else {
+ DCHECK(layout_object->IsListMarker());
+ // TODO(obrufau): support non-normal content in legacy markers.
+ return;
+ }
+ if (style.ContentBehavesAsNormal())
+ return;
+ break;
+ }
+ case kPseudoIdBefore:
+ case kPseudoIdAfter:
+ break;
+ default:
+ return;
+ }
+ DCHECK(!style.ContentBehavesAsNormal());
+ DCHECK(!style.ContentPreventsBoxGeneration());
for (const ContentData* content = style.GetContentData(); content;
content = content->Next()) {
LegacyLayout legacy = context.force_legacy_layout ? LegacyLayout::kForce
@@ -200,22 +228,55 @@ void PseudoElement::AttachLayoutTree(AttachContext& context) {
}
bool PseudoElement::LayoutObjectIsNeeded(const ComputedStyle& style) const {
- return PseudoElementLayoutObjectIsNeeded(&style);
+ return PseudoElementLayoutObjectIsNeeded(&style, this->parentElement());
+}
+
+bool PseudoElement::CanGeneratePseudoElement(PseudoId pseudo_id) const {
+ switch (pseudo_id_) {
+ case kPseudoIdBefore:
+ case kPseudoIdAfter:
+ if (pseudo_id != kPseudoIdMarker)
+ return false;
+ break;
+ default:
+ return false;
+ }
+ return Element::CanGeneratePseudoElement(pseudo_id);
}
Node* PseudoElement::InnerNodeForHitTesting() const {
- return ParentOrShadowHostNode();
+ Node* parent = ParentOrShadowHostNode();
+ if (parent && parent->IsPseudoElement())
+ return To<PseudoElement>(parent)->InnerNodeForHitTesting();
+ return parent;
}
-bool PseudoElementLayoutObjectIsNeeded(const ComputedStyle* style) {
- if (!style)
+bool PseudoElementLayoutObjectIsNeeded(const ComputedStyle* pseudo_style,
+ const Element* originating_element) {
+ if (!pseudo_style)
return false;
- if (style->Display() == EDisplay::kNone)
+ if (pseudo_style->Display() == EDisplay::kNone)
return false;
- if (style->StyleType() == kPseudoIdFirstLetter ||
- style->StyleType() == kPseudoIdBackdrop)
- return true;
- return style->GetContentData();
+ switch (pseudo_style->StyleType()) {
+ case kPseudoIdFirstLetter:
+ case kPseudoIdBackdrop:
+ return true;
+ case kPseudoIdBefore:
+ case kPseudoIdAfter:
+ return !pseudo_style->ContentPreventsBoxGeneration();
+ case kPseudoIdMarker: {
+ if (!pseudo_style->ContentBehavesAsNormal())
+ return !pseudo_style->ContentPreventsBoxGeneration();
+ const ComputedStyle* parent_style =
+ originating_element->GetComputedStyle();
+ return parent_style &&
+ (parent_style->ListStyleType() != EListStyleType::kNone ||
+ parent_style->GeneratesMarkerImage());
+ }
+ default:
+ NOTREACHED();
+ return false;
+ }
}
} // namespace blink
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 951fc21bc7a..2f38fb6a975 100644
--- a/chromium/third_party/blink/renderer/core/dom/pseudo_element.h
+++ b/chromium/third_party/blink/renderer/core/dom/pseudo_element.h
@@ -44,6 +44,7 @@ class CORE_EXPORT PseudoElement : public Element {
scoped_refptr<ComputedStyle> CustomStyleForLayoutObject() override;
void AttachLayoutTree(AttachContext&) override;
bool LayoutObjectIsNeeded(const ComputedStyle&) const override;
+ bool CanGeneratePseudoElement(PseudoId) const override;
bool CanStartSelection() const override { return false; }
bool CanContainRangeEndPoint() const override { return false; }
@@ -68,7 +69,7 @@ class CORE_EXPORT PseudoElement : public Element {
~AttachLayoutTreeScope();
private:
- Member<PseudoElement> element_;
+ PseudoElement* element_;
scoped_refptr<const ComputedStyle> original_style_;
};
@@ -77,7 +78,8 @@ class CORE_EXPORT PseudoElement : public Element {
const QualifiedName& PseudoElementTagName(PseudoId);
-bool PseudoElementLayoutObjectIsNeeded(const ComputedStyle*);
+bool PseudoElementLayoutObjectIsNeeded(const ComputedStyle* pseudo_style,
+ const Element* originating_element);
template <>
struct DowncastTraits<PseudoElement> {
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 a94702a0564..23af73fd418 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
@@ -17,6 +17,10 @@ class PseudoElementData final : public GarbageCollected<PseudoElementData> {
void SetPseudoElement(PseudoId, PseudoElement*);
PseudoElement* GetPseudoElement(PseudoId) const;
+
+ using PseudoElementVector = HeapVector<Member<PseudoElement>, 2>;
+ PseudoElementVector GetPseudoElements() const;
+
bool HasPseudoElements() const;
void ClearPseudoElements();
void Trace(Visitor* visitor) {
@@ -102,6 +106,22 @@ inline PseudoElement* PseudoElementData::GetPseudoElement(
return nullptr;
}
+inline PseudoElementData::PseudoElementVector
+PseudoElementData::GetPseudoElements() const {
+ PseudoElementData::PseudoElementVector result;
+ if (generated_before_)
+ result.push_back(generated_before_);
+ if (generated_after_)
+ result.push_back(generated_after_);
+ if (generated_marker_)
+ result.push_back(generated_marker_);
+ if (generated_first_letter_)
+ result.push_back(generated_first_letter_);
+ if (backdrop_)
+ result.push_back(backdrop_);
+ return result;
+}
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_PSEUDO_ELEMENT_DATA_H_
diff --git a/chromium/third_party/blink/renderer/core/dom/range.cc b/chromium/third_party/blink/renderer/core/dom/range.cc
index 44c86ad3893..71bad3d8be8 100644
--- a/chromium/third_party/blink/renderer/core/dom/range.cc
+++ b/chromium/third_party/blink/renderer/core/dom/range.cc
@@ -25,7 +25,6 @@
#include "third_party/blink/renderer/core/dom/range.h"
-#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_html.h"
#include "third_party/blink/renderer/core/dom/character_data.h"
#include "third_party/blink/renderer/core/dom/container_node.h"
#include "third_party/blink/renderer/core/dom/document_fragment.h"
@@ -72,7 +71,7 @@ class RangeUpdateScope {
DCHECK(range);
if (++scope_count_ == 1) {
range_ = range;
- old_document_ = range->OwnerDocument();
+ old_document_ = &range->OwnerDocument();
#if DCHECK_IS_ON()
current_range_ = range;
} else {
@@ -107,8 +106,8 @@ class RangeUpdateScope {
// - RangeUpdateScope is used only in Range member functions.
static Range* current_range_;
#endif
- Member<Range> range_;
- Member<Document> old_document_;
+ Range* range_ = nullptr;
+ Document* old_document_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(RangeUpdateScope);
};
@@ -963,29 +962,13 @@ String Range::GetText() const {
}
DocumentFragment* Range::createContextualFragment(
- const StringOrTrustedHTML& string_or_html,
- ExceptionState& exception_state) {
- // Algorithm:
- // http://domparsing.spec.whatwg.org/#extensions-to-the-range-interface
-
- DCHECK(!string_or_html.IsNull());
-
- Document& document = start_.Container().GetDocument();
-
- String markup =
- GetStringFromTrustedHTML(string_or_html, &document, exception_state);
- if (!exception_state.HadException()) {
- return createContextualFragmentFromString(markup, exception_state);
- }
- return nullptr;
-}
-
-DocumentFragment* Range::createContextualFragmentFromString(
const String& markup,
ExceptionState& exception_state) {
// Algorithm:
// http://domparsing.spec.whatwg.org/#extensions-to-the-range-interface
+ DCHECK(!markup.IsNull());
+
Node* node = &start_.Container();
// Step 1.
@@ -1599,7 +1582,7 @@ void Range::DidSplitTextNode(const Text& old_node) {
void Range::expand(const String& unit, ExceptionState& exception_state) {
if (!StartPosition().IsConnected() || !EndPosition().IsConnected())
return;
- owner_document_->UpdateStyleAndLayout();
+ owner_document_->UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
VisiblePosition start = CreateVisiblePosition(StartPosition());
VisiblePosition end = CreateVisiblePosition(EndPosition());
if (unit == "word") {
@@ -1626,12 +1609,12 @@ void Range::expand(const String& unit, ExceptionState& exception_state) {
}
DOMRectList* Range::getClientRects() const {
- owner_document_->UpdateStyleAndLayout();
+ owner_document_->UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
Vector<FloatQuad> quads;
GetBorderAndTextQuads(quads);
- return DOMRectList::Create(quads);
+ return MakeGarbageCollected<DOMRectList>(quads);
}
DOMRect* Range::getBoundingClientRect() const {
@@ -1747,7 +1730,7 @@ void Range::GetBorderAndTextQuads(Vector<FloatQuad>& quads) const {
}
FloatRect Range::BoundingRect() const {
- owner_document_->UpdateStyleAndLayout();
+ owner_document_->UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
Vector<FloatQuad> quads;
GetBorderAndTextQuads(quads);
diff --git a/chromium/third_party/blink/renderer/core/dom/range.h b/chromium/third_party/blink/renderer/core/dom/range.h
index 98d708375ac..e3d643b525d 100644
--- a/chromium/third_party/blink/renderer/core/dom/range.h
+++ b/chromium/third_party/blink/renderer/core/dom/range.h
@@ -46,7 +46,6 @@ class ExceptionState;
class FloatQuad;
class Node;
class NodeWithIndex;
-class StringOrTrustedHTML;
class Text;
class CORE_EXPORT Range final : public ScriptWrappable {
@@ -117,7 +116,7 @@ class CORE_EXPORT Range final : public ScriptWrappable {
String GetText() const;
- DocumentFragment* createContextualFragment(const StringOrTrustedHTML& html,
+ DocumentFragment* createContextualFragment(const String& html,
ExceptionState&);
void detach();
@@ -206,9 +205,6 @@ class CORE_EXPORT Range final : public ScriptWrappable {
void UpdateSelectionIfAddedToSelection();
void RemoveFromSelectionIfInDifferentRoot(Document& old_document);
- DocumentFragment* createContextualFragmentFromString(const String& html,
- ExceptionState&);
-
Member<Document> owner_document_; // Cannot be null.
RangeBoundaryPoint start_;
RangeBoundaryPoint end_;
diff --git a/chromium/third_party/blink/renderer/core/dom/range.idl b/chromium/third_party/blink/renderer/core/dom/range.idl
index c2ee325331f..499e5b55452 100644
--- a/chromium/third_party/blink/renderer/core/dom/range.idl
+++ b/chromium/third_party/blink/renderer/core/dom/range.idl
@@ -20,10 +20,9 @@
// https://dom.spec.whatwg.org/#interface-range
[
- Constructor,
- ConstructorCallWith=Document,
Exposed=Window
] interface Range {
+ [CallWith=Document] constructor();
readonly attribute Node startContainer;
readonly attribute unsigned long startOffset;
readonly attribute Node endContainer;
@@ -73,5 +72,5 @@
[NewObject, RaisesException, CEReactions, CustomElementCallbacks] DocumentFragment createContextualFragment(HTMLString fragment);
// Non-standard API
- [RaisesException, DeprecateAs=RangeExpand] void expand([DefaultValue=Undefined] optional DOMString unit);
+ [RaisesException, DeprecateAs=RangeExpand] void expand(optional DOMString unit = "");
};
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 b9a5b8be767..173d2e2e524 100644
--- a/chromium/third_party/blink/renderer/core/dom/range_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/range_test.cc
@@ -8,7 +8,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_array_buffer_or_array_buffer_view.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
-#include "third_party/blink/renderer/core/css/font_face_descriptors.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_font_face_descriptors.h"
#include "third_party/blink/renderer/core/css/font_face_set_document.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/node_list.h"
@@ -37,7 +37,7 @@ namespace blink {
class RangeTest : public EditingTestBase {};
TEST_F(RangeTest, extractContentsWithDOMMutationEvent) {
- GetDocument().body()->SetInnerHTMLFromString("<span><b>abc</b>def</span>");
+ GetDocument().body()->setInnerHTML("<span><b>abc</b>def</span>");
GetDocument().GetSettings()->SetScriptEnabled(true);
Element* const script_element =
GetDocument().CreateRawElement(html_names::kScriptTag);
@@ -57,9 +57,9 @@ TEST_F(RangeTest, extractContentsWithDOMMutationEvent) {
Element* const result = GetDocument().CreateRawElement(html_names::kDivTag);
result->AppendChild(range->extractContents(ASSERT_NO_EXCEPTION));
- EXPECT_EQ("<b>abc</b>", result->InnerHTMLAsString())
+ EXPECT_EQ("<b>abc</b>", result->innerHTML())
<< "DOM mutation event handler should not affect result.";
- EXPECT_EQ("<span>DEF</span>", span_element->OuterHTMLAsString())
+ EXPECT_EQ("<span>DEF</span>", span_element->outerHTML())
<< "DOM mutation event handler should be executed.";
}
@@ -102,7 +102,7 @@ TEST_F(RangeTest, IntersectsNode) {
TEST_F(RangeTest, SplitTextNodeRangeWithinText) {
V8TestingScope scope;
- GetDocument().body()->SetInnerHTMLFromString("1234");
+ GetDocument().body()->setInnerHTML("1234");
auto* old_text = To<Text>(GetDocument().body()->firstChild());
auto* range04 =
@@ -147,7 +147,7 @@ TEST_F(RangeTest, SplitTextNodeRangeWithinText) {
TEST_F(RangeTest, SplitTextNodeRangeOutsideText) {
V8TestingScope scope;
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<span id=\"outer\">0<span id=\"inner-left\">1</span>SPLITME<span "
"id=\"inner-right\">2</span>3</span>");
@@ -233,7 +233,7 @@ TEST_F(RangeTest, updateOwnerDocumentIfNeeded) {
// Regression test for crbug.com/639184
TEST_F(RangeTest, NotMarkedValidByIrrelevantTextInsert) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<div><span id=span1>foo</span>bar<span id=span2>baz</span></div>");
Element* div = GetDocument().QuerySelector("div");
@@ -255,7 +255,7 @@ TEST_F(RangeTest, NotMarkedValidByIrrelevantTextInsert) {
// Regression test for crbug.com/639184
TEST_F(RangeTest, NotMarkedValidByIrrelevantTextRemove) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<div><span id=span1>foofoo</span>bar<span id=span2>baz</span></div>");
Element* div = GetDocument().QuerySelector("div");
@@ -294,7 +294,7 @@ TEST_F(RangeTest, ToPosition) {
TEST_F(RangeTest, BoundingRectMustIndependentFromSelection) {
LoadAhem();
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<div style='font: Ahem; width: 2em;letter-spacing: 5px;'>xx xx </div>");
Node* const div = GetDocument().QuerySelector("div");
// "x^x
@@ -316,9 +316,8 @@ TEST_F(RangeTest, BoundingRectMustIndependentFromSelection) {
// Regression test for crbug.com/681536
TEST_F(RangeTest, BorderAndTextQuadsWithInputInBetween) {
- GetDocument().body()->SetInnerHTMLFromString(
- "<div>foo <u><input> bar</u></div>");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().body()->setInnerHTML("<div>foo <u><input> bar</u></div>");
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Node* foo = GetDocument().QuerySelector("div")->firstChild();
Node* bar = GetDocument().QuerySelector("u")->lastChild();
@@ -349,7 +348,7 @@ static Vector<IntSize> ComputeSizesOfQuads(const Vector<FloatQuad>& quads) {
}
TEST_F(RangeTest, GetBorderAndTextQuadsWithFirstLetterOne) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
body { font-size: 20px; }
#sample::first-letter { font-size: 500%; }
@@ -357,7 +356,7 @@ TEST_F(RangeTest, GetBorderAndTextQuadsWithFirstLetterOne) {
<p id=sample>abc</p>
<p id=expected><span style='font-size: 500%'>a</span>bc</p>
)HTML");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Element* const expected = GetDocument().getElementById("expected");
Element* const sample = GetDocument().getElementById("sample");
@@ -394,7 +393,7 @@ TEST_F(RangeTest, GetBorderAndTextQuadsWithFirstLetterOne) {
}
TEST_F(RangeTest, GetBorderAndTextQuadsWithFirstLetterThree) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
body { font-size: 20px; }
#sample::first-letter { font-size: 500%; }
@@ -402,7 +401,7 @@ TEST_F(RangeTest, GetBorderAndTextQuadsWithFirstLetterThree) {
<p id=sample>(a)bc</p>
<p id=expected><span style='font-size: 500%'>(a)</span>bc</p>
)HTML");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Element* const expected = GetDocument().getElementById("expected");
Element* const sample = GetDocument().getElementById("sample");
@@ -455,7 +454,7 @@ TEST_F(RangeTest, GetBorderAndTextQuadsWithFirstLetterThree) {
}
TEST_F(RangeTest, CollapsedRangeGetBorderAndTextQuadsWithFirstLetter) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
body { font-size: 20px; }
#sample::first-letter { font-size: 500%; }
@@ -463,7 +462,7 @@ TEST_F(RangeTest, CollapsedRangeGetBorderAndTextQuadsWithFirstLetter) {
<p id=sample>abc</p>
<p id=expected><span style='font-size: 500%'>a</span>bc</p>
)HTML");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Element* const expected = GetDocument().getElementById("expected");
Element* const sample = GetDocument().getElementById("sample");
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 61ac0c87702..64afdc19a08 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
@@ -43,13 +43,11 @@ class CORE_EXPORT ScriptableDocumentParser : public DecodedDataDocumentParser {
// JavaScript document.open() call right now, or it should be ignored.
virtual bool IsExecutingScript() const { return false; }
- // FIXME: Only the HTMLDocumentParser ever blocks script execution on
- // stylesheet load, which is likely a bug in the XMLDocumentParser.
- virtual void ExecuteScriptsWaitingForResources() {}
+ virtual void ExecuteScriptsWaitingForResources() = 0;
virtual bool IsWaitingForScripts() const = 0;
- virtual void DidAddPendingParserBlockingStylesheet() {}
- virtual void DidLoadAllPendingParserBlockingStylesheets() {}
+ virtual void DidAddPendingParserBlockingStylesheet() = 0;
+ virtual void DidLoadAllPendingParserBlockingStylesheets() = 0;
// These are used to expose the current line/column to the scripting system.
virtual bool IsParsingAtLineNumber() const;
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 934615945bf..7e54b479fe7 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
@@ -38,32 +38,44 @@
namespace blink {
-std::pair<EventTarget*, StringImpl*> EventTargetKey(const Event* event) {
- return std::make_pair(event->target(), event->type().Impl());
+bool ScriptedAnimationController::InsertToPerFrameEventsMap(
+ const Event* event) {
+ HashSet<const StringImpl*>& set =
+ per_frame_events_.insert(event->target(), HashSet<const StringImpl*>())
+ .stored_value->value;
+ return set.insert(event->type().Impl()).is_new_entry;
}
-ScriptedAnimationController::ScriptedAnimationController(Document* document)
- : document_(document), callback_collection_(document), suspend_count_(0) {}
+void ScriptedAnimationController::EraseFromPerFrameEventsMap(
+ const Event* event) {
+ EventTarget* target = event->target();
+ PerFrameEventsMap::iterator it = per_frame_events_.find(target);
+ if (it != per_frame_events_.end()) {
+ HashSet<const StringImpl*>& set = it->value;
+ set.erase(event->type().Impl());
+ if (set.IsEmpty())
+ per_frame_events_.erase(target);
+ }
+}
+
+ScriptedAnimationController::ScriptedAnimationController(LocalDOMWindow* window)
+ : ExecutionContextLifecycleStateObserver(window),
+ callback_collection_(window) {
+ UpdateStateIfNeeded();
+}
void ScriptedAnimationController::Trace(Visitor* visitor) {
- visitor->Trace(document_);
+ ExecutionContextLifecycleStateObserver::Trace(visitor);
visitor->Trace(callback_collection_);
visitor->Trace(event_queue_);
visitor->Trace(media_query_list_listeners_);
visitor->Trace(per_frame_events_);
}
-void ScriptedAnimationController::Pause() {
- ++suspend_count_;
-}
-
-void ScriptedAnimationController::Unpause() {
- // It would be nice to put an DCHECK_GT(suspend_count_, 0) here, but in WK1
- // resume() can be called even when suspend hasn't (if a tab was created in
- // the background).
- if (suspend_count_ > 0)
- --suspend_count_;
- ScheduleAnimationIfNeeded();
+void ScriptedAnimationController::ContextLifecycleStateChanged(
+ mojom::FrameLifecycleState state) {
+ if (state == mojom::FrameLifecycleState::kRunning)
+ ScheduleAnimationIfNeeded();
}
void ScriptedAnimationController::DispatchEventsAndCallbacksForPrinting() {
@@ -71,6 +83,13 @@ void ScriptedAnimationController::DispatchEventsAndCallbacksForPrinting() {
CallMediaQueryListListeners();
}
+void ScriptedAnimationController::ScheduleVideoFrameCallbacksExecution(
+ ExecuteVfcCallback execute_vfc_callback) {
+ DCHECK(RuntimeEnabledFeatures::RequestVideoFrameCallbackEnabled());
+ vfc_execution_queue_.push_back(std::move(execute_vfc_callback));
+ ScheduleAnimationIfNeeded();
+}
+
ScriptedAnimationController::CallbackId
ScriptedAnimationController::RegisterFrameCallback(
FrameRequestCallbackCollection::FrameCallback* callback) {
@@ -84,7 +103,8 @@ void ScriptedAnimationController::CancelFrameCallback(CallbackId id) {
}
bool ScriptedAnimationController::HasFrameCallback() const {
- return callback_collection_.HasFrameCallback();
+ return callback_collection_.HasFrameCallback() ||
+ !vfc_execution_queue_.IsEmpty();
}
ScriptedAnimationController::CallbackId
@@ -116,7 +136,7 @@ void ScriptedAnimationController::DispatchEvents(
HeapVector<Member<Event>> remaining;
for (auto& event : event_queue_) {
if (event && event->InterfaceName() == event_interface_filter) {
- per_frame_events_.erase(EventTargetKey(event.Get()));
+ EraseFromPerFrameEventsMap(event.Get());
events.push_back(event.Release());
} else {
remaining.push_back(event.Release());
@@ -140,9 +160,20 @@ void ScriptedAnimationController::DispatchEvents(
}
}
+void ScriptedAnimationController::ExecuteVideoFrameCallbacks() {
+ // dispatchEvents() runs script which can cause the context to be destroyed.
+ if (!GetExecutionContext())
+ return;
+
+ Vector<ExecuteVfcCallback> execute_vfc_callbacks;
+ vfc_execution_queue_.swap(execute_vfc_callbacks);
+ for (auto& callback : execute_vfc_callbacks)
+ std::move(callback).Run(current_frame_time_ms_);
+}
+
void ScriptedAnimationController::ExecuteFrameCallbacks() {
- // dispatchEvents() runs script which can cause the document to be destroyed.
- if (!document_)
+ // dispatchEvents() runs script which can cause the context to be destroyed.
+ if (!GetExecutionContext())
return;
callback_collection_.ExecuteFrameCallbacks(current_frame_time_ms_,
@@ -159,28 +190,28 @@ void ScriptedAnimationController::CallMediaQueryListListeners() {
}
bool ScriptedAnimationController::HasScheduledFrameTasks() const {
- if (suspend_count_)
- return false;
-
return callback_collection_.HasFrameCallback() || !task_queue_.IsEmpty() ||
!event_queue_.IsEmpty() || !media_query_list_listeners_.IsEmpty() ||
- (document_ && document_->HasAutofocusCandidates());
+ GetWindow()->document()->HasAutofocusCandidates() ||
+ !vfc_execution_queue_.IsEmpty();
}
void ScriptedAnimationController::ServiceScriptedAnimations(
base::TimeTicks monotonic_time_now) {
- if (document_ && document_->Loader()) {
- current_frame_time_ms_ =
- document_->Loader()
- ->GetTiming()
- .MonotonicTimeToZeroBasedDocumentTime(monotonic_time_now)
- .InMillisecondsF();
- current_frame_legacy_time_ms_ =
- document_->Loader()
- ->GetTiming()
- .MonotonicTimeToPseudoWallTime(monotonic_time_now)
- .InMillisecondsF();
- }
+ if (!GetExecutionContext() || GetExecutionContext()->IsContextPaused())
+ return;
+ auto* loader = GetWindow()->document()->Loader();
+ if (!loader)
+ return;
+
+ current_frame_time_ms_ =
+ loader->GetTiming()
+ .MonotonicTimeToZeroBasedDocumentTime(monotonic_time_now)
+ .InMillisecondsF();
+ current_frame_legacy_time_ms_ =
+ loader->GetTiming()
+ .MonotonicTimeToPseudoWallTime(monotonic_time_now)
+ .InMillisecondsF();
current_frame_had_raf_ = HasFrameCallback();
if (!HasScheduledFrameTasks())
@@ -191,8 +222,7 @@ void ScriptedAnimationController::ServiceScriptedAnimations(
// 10.5. For each fully active Document in docs, flush autofocus
// candidates for that Document if its browsing context is a top-level
// browsing context.
- if (document_)
- document_->FlushAutofocusCandidates();
+ GetWindow()->document()->FlushAutofocusCandidates();
// 10.8. For each fully active Document in docs, evaluate media
// queries and report changes for that Document, passing in now as the
@@ -213,6 +243,12 @@ void ScriptedAnimationController::ServiceScriptedAnimations(
// steps for that Document, passing in now as the timestamp.
RunTasks();
+ if (RuntimeEnabledFeatures::RequestVideoFrameCallbackEnabled()) {
+ // Run the fulfilled HTMLVideoELement.requestVideoFrameCallback() callbacks.
+ // See https://wicg.github.io/video-raf/.
+ ExecuteVideoFrameCallbacks();
+ }
+
// 10.11. For each fully active Document in docs, run the animation
// frame callbacks for that Document, passing in now as the timestamp.
ExecuteFrameCallbacks();
@@ -245,7 +281,7 @@ void ScriptedAnimationController::EnqueueEvent(Event* event) {
}
void ScriptedAnimationController::EnqueuePerFrameEvent(Event* event) {
- if (!per_frame_events_.insert(EventTargetKey(event)).is_new_entry)
+ if (!InsertToPerFrameEventsMap(event))
return;
EnqueueEvent(event);
}
@@ -259,16 +295,17 @@ void ScriptedAnimationController::EnqueueMediaQueryChangeListeners(
}
void ScriptedAnimationController::ScheduleAnimationIfNeeded() {
- if (suspend_count_ || !document_)
+ if (!GetExecutionContext() || GetExecutionContext()->IsContextPaused())
return;
- LocalFrameView* frame_view = document_->View();
- if (!frame_view)
+
+ auto* frame = GetWindow()->GetFrame();
+ if (!frame)
return;
// If there is any pre-frame work to do, schedule an animation
// unconditionally.
if (HasScheduledFrameTasks()) {
- frame_view->ScheduleAnimation();
+ frame->View()->ScheduleAnimation();
return;
}
@@ -276,12 +313,14 @@ void ScriptedAnimationController::ScheduleAnimationIfNeeded() {
// 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())
- return;
- if (Page* page = document_->GetPage()) {
- if (!page->Animator().IsServicingAnimations())
- frame_view->ScheduleAnimation();
+ if (callback_collection_.HasPostFrameCallback() &&
+ !frame->GetPage()->Animator().IsServicingAnimations()) {
+ frame->View()->ScheduleAnimation();
}
}
+LocalDOMWindow* ScriptedAnimationController::GetWindow() const {
+ return To<LocalDOMWindow>(GetExecutionContext());
+}
+
} // namespace blink
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 430fe011dac..d3ac68f2b31 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
@@ -28,31 +28,42 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/frame_request_callback_collection.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
#include "third_party/blink/renderer/platform/wtf/text/string_impl.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
-class Document;
class Event;
class EventTarget;
+class LocalDOMWindow;
class MediaQueryListListener;
class CORE_EXPORT ScriptedAnimationController
: public GarbageCollected<ScriptedAnimationController>,
+ public ExecutionContextLifecycleStateObserver,
public NameClient {
+ USING_GARBAGE_COLLECTED_MIXIN(ScriptedAnimationController);
+
public:
- explicit ScriptedAnimationController(Document*);
- virtual ~ScriptedAnimationController() = default;
+ explicit ScriptedAnimationController(LocalDOMWindow*);
+ ~ScriptedAnimationController() override = default;
- void Trace(Visitor*);
+ void Trace(Visitor*) override;
const char* NameInHeapSnapshot() const override {
return "ScriptedAnimationController";
}
- void ClearDocumentPointer() { document_ = nullptr; }
+
+ // Runs all the video.requestVideoFrameCallback() callbacks associated with
+ // one HTMLVideoElement. |double| is the current frame time in milliseconds
+ // (e.g. |current_frame_time_ms_|), to be passed as the "now" parameter
+ // when running the callbacks.
+ using ExecuteVfcCallback = base::OnceCallback<void(double)>;
// Animation frame callbacks are used for requestAnimationFrame().
typedef int CallbackId;
@@ -66,6 +77,10 @@ class CORE_EXPORT ScriptedAnimationController
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);
+
// Animation frame events are used for resize events, scroll events, etc.
void EnqueueEvent(Event*);
void EnqueuePerFrameEvent(Event*);
@@ -82,8 +97,8 @@ class CORE_EXPORT ScriptedAnimationController
void ServiceScriptedAnimations(base::TimeTicks monotonic_time_now);
void RunPostFrameCallbacks();
- void Pause();
- void Unpause();
+ void ContextLifecycleStateChanged(mojom::FrameLifecycleState) final;
+ void ContextDestroyed() final {}
void DispatchEventsAndCallbacksForPrinting();
@@ -97,17 +112,23 @@ class CORE_EXPORT ScriptedAnimationController
void DispatchEvents(
const AtomicString& event_interface_filter = AtomicString());
void ExecuteFrameCallbacks();
+ void ExecuteVideoFrameCallbacks();
void CallMediaQueryListListeners();
bool HasScheduledFrameTasks() const;
- Member<Document> document_;
+ LocalDOMWindow* GetWindow() const;
+
+ ALWAYS_INLINE bool InsertToPerFrameEventsMap(const Event* event);
+ ALWAYS_INLINE void EraseFromPerFrameEventsMap(const Event* event);
+
FrameRequestCallbackCollection callback_collection_;
- int suspend_count_;
Vector<base::OnceClosure> task_queue_;
+ Vector<ExecuteVfcCallback> vfc_execution_queue_;
HeapVector<Member<Event>> event_queue_;
- HeapListHashSet<std::pair<Member<const EventTarget>, const StringImpl*>>
- per_frame_events_;
+ using PerFrameEventsMap =
+ HeapHashMap<Member<const EventTarget>, HashSet<const StringImpl*>>;
+ PerFrameEventsMap per_frame_events_;
using MediaQueryListListeners =
HeapListHashSet<Member<MediaQueryListListener>>;
MediaQueryListListeners media_query_list_listeners_;
diff --git a/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller_test.cc b/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller_test.cc
index 72057a2e44f..e757b3d8ea2 100644
--- a/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/scripted_animation_controller_test.cc
@@ -36,10 +36,10 @@ void ScriptedAnimationControllerTest::SetUp() {
dummy_page_holder_ = std::make_unique<DummyPageHolder>(IntSize(800, 600));
// Note: The document doesn't know about this ScriptedAnimationController
- // instance, and will create another if
- // Document::ensureScriptedAnimationController is called.
- controller_ = WrapPersistent(
- MakeGarbageCollected<ScriptedAnimationController>(&GetDocument()));
+ // instance.
+ controller_ =
+ WrapPersistent(MakeGarbageCollected<ScriptedAnimationController>(
+ dummy_page_holder_->GetFrame().DomWindow()));
}
namespace {
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 cb844a1fdbc..760c696f452 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
@@ -7,7 +7,7 @@
#include "base/location.h"
#include "base/metrics/histogram_macros.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/renderer/core/dom/idle_request_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_idle_request_options.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
@@ -90,7 +90,7 @@ void ScriptedIdleTaskController::V8IdleTask::invoke(IdleDeadline* deadline) {
ScriptedIdleTaskController::ScriptedIdleTaskController(
ExecutionContext* context)
- : ContextLifecycleStateObserver(context),
+ : ExecutionContextLifecycleStateObserver(context),
scheduler_(ThreadScheduler::Current()),
next_callback_id_(0),
paused_(false) {}
@@ -99,7 +99,7 @@ ScriptedIdleTaskController::~ScriptedIdleTaskController() = default;
void ScriptedIdleTaskController::Trace(Visitor* visitor) {
visitor->Trace(idle_tasks_);
- ContextLifecycleStateObserver::Trace(visitor);
+ ExecutionContextLifecycleStateObserver::Trace(visitor);
}
int ScriptedIdleTaskController::NextCallbackId() {
@@ -228,7 +228,7 @@ void ScriptedIdleTaskController::RunCallback(
idle_tasks_.erase(id);
}
-void ScriptedIdleTaskController::ContextDestroyed(ExecutionContext*) {
+void ScriptedIdleTaskController::ContextDestroyed() {
idle_tasks_.clear();
}
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 6bcc6b19bbc..c13fe650ed9 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
@@ -7,7 +7,7 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_idle_request_callback.h"
#include "third_party/blink/renderer/core/dom/idle_deadline.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h"
#include "third_party/blink/renderer/core/probe/async_task_id.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -25,7 +25,7 @@ class ThreadScheduler;
class CORE_EXPORT ScriptedIdleTaskController
: public GarbageCollected<ScriptedIdleTaskController>,
- public ContextLifecycleStateObserver,
+ public ExecutionContextLifecycleStateObserver,
public NameClient {
USING_GARBAGE_COLLECTED_MIXIN(ScriptedIdleTaskController);
@@ -82,8 +82,8 @@ class CORE_EXPORT ScriptedIdleTaskController
int RegisterCallback(IdleTask*, const IdleRequestOptions*);
void CancelCallback(CallbackId);
- // ContextLifecycleStateObserver interface.
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleStateObserver interface.
+ void ContextDestroyed() override;
void ContextLifecycleStateChanged(mojom::FrameLifecycleState) override;
void CallbackFired(CallbackId,
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 55f08d66335..911c7e2cf0d 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
@@ -7,7 +7,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_idle_request_callback.h"
-#include "third_party/blink/renderer/core/dom/idle_request_options.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/testing/scoped_scheduler_overrider.h"
@@ -33,6 +33,9 @@ class MockScriptedIdleTaskControllerScheduler final : public ThreadScheduler {
scoped_refptr<base::SingleThreadTaskRunner> V8TaskRunner() override {
return nullptr;
}
+ scoped_refptr<base::SingleThreadTaskRunner> NonWakingTaskRunner() override {
+ return nullptr;
+ }
scoped_refptr<base::SingleThreadTaskRunner> DeprecatedDefaultTaskRunner()
override {
return nullptr;
diff --git a/chromium/third_party/blink/renderer/core/dom/shadow_dom_v0_test.cc b/chromium/third_party/blink/renderer/core/dom/shadow_dom_v0_test.cc
index df99e4679f3..c20d7e70dd2 100644
--- a/chromium/third_party/blink/renderer/core/dom/shadow_dom_v0_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/shadow_dom_v0_test.cc
@@ -111,7 +111,7 @@ TEST_F(ShadowDOMV0Test, FeatureSetMultipleSelectors) {
TEST_F(ShadowDOMV0Test, FeatureSetSubtree) {
LoadURL("about:blank");
auto* host = GetDocument().CreateRawElement(html_names::kDivTag);
- host->CreateV0ShadowRootForTesting().SetInnerHTMLFromString(R"HTML(
+ host->CreateV0ShadowRootForTesting().setInnerHTML(R"HTML(
<div>
<div></div>
<content select='*'></content>
@@ -130,7 +130,7 @@ TEST_F(ShadowDOMV0Test, FeatureSetMultipleShadowRoots) {
LoadURL("about:blank");
auto* host = GetDocument().CreateRawElement(html_names::kDivTag);
auto& host_shadow = host->CreateV0ShadowRootForTesting();
- host_shadow.SetInnerHTMLFromString("<content select='#foo'></content>");
+ host_shadow.setInnerHTML("<content select='#foo'></content>");
auto* child = GetDocument().CreateRawElement(html_names::kDivTag);
auto& child_root = child->CreateV0ShadowRootForTesting();
auto* child_content = GetDocument().CreateRawElement(html_names::kContentTag);
@@ -157,8 +157,7 @@ TEST_F(ShadowDOMV0Test, ReattachNonDistributedElements) {
host->appendChild(inner_host);
inner_host->appendChild(span);
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
host->CreateV0ShadowRootForTesting();
inner_host->CreateV0ShadowRootForTesting();
@@ -166,8 +165,7 @@ TEST_F(ShadowDOMV0Test, ReattachNonDistributedElements) {
CSSValueID::kInlineBlock);
span->SetInlineStyleProperty(CSSPropertyID::kDisplay, CSSValueID::kBlock);
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
EXPECT_FALSE(span->NeedsReattachLayoutTree());
}
@@ -180,8 +178,7 @@ TEST_F(ShadowDOMV0Test, DetachLayoutTreeOnShadowRootCreation) {
auto* span = GetDocument().CreateRawElement(html_names::kSpanTag);
host->appendChild(span);
GetDocument().body()->appendChild(host);
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
EXPECT_TRUE(span->GetLayoutObject());
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 155f4e28ad9..215a8af0e76 100644
--- a/chromium/third_party/blink/renderer/core/dom/shadow_root.cc
+++ b/chromium/third_party/blink/renderer/core/dom/shadow_root.cc
@@ -27,7 +27,6 @@
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_html.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
#include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/css/style_engine.h"
@@ -71,7 +70,7 @@ ShadowRoot::ShadowRoot(Document& document, ShadowRootType type)
type_(static_cast<unsigned>(type)),
registered_with_parent_shadow_root_(false),
delegates_focus_(false),
- slotting_(static_cast<unsigned>(ShadowRootSlotting::kAuto)),
+ slot_assignment_mode_(static_cast<unsigned>(SlotAssignmentMode::kAuto)),
needs_distribution_recalc_(false),
unused_(0) {
if (IsV0())
@@ -109,35 +108,22 @@ Node* ShadowRoot::Clone(Document&, CloneChildrenFlag) const {
return nullptr;
}
-void ShadowRoot::SetSlotting(ShadowRootSlotting slotting) {
- slotting_ = static_cast<unsigned>(slotting);
+void ShadowRoot::SetSlotAssignmentMode(SlotAssignmentMode assignment_mode) {
+ slot_assignment_mode_ = static_cast<unsigned>(assignment_mode);
}
-String ShadowRoot::InnerHTMLAsString() const {
+String ShadowRoot::innerHTML() const {
return CreateMarkup(this, kChildrenOnly);
}
-void ShadowRoot::innerHTML(StringOrTrustedHTML& result) const {
- result.SetString(InnerHTMLAsString());
-}
-
-void ShadowRoot::SetInnerHTMLFromString(const String& markup,
- ExceptionState& exception_state) {
+void ShadowRoot::setInnerHTML(const String& markup,
+ ExceptionState& exception_state) {
if (DocumentFragment* fragment = CreateFragmentForInnerOuterHTML(
markup, &host(), kAllowScriptingContent, "innerHTML",
exception_state))
ReplaceChildrenWithFragment(this, fragment, exception_state);
}
-void ShadowRoot::setInnerHTML(const StringOrTrustedHTML& stringOrHtml,
- ExceptionState& exception_state) {
- String html =
- GetStringFromTrustedHTML(stringOrHtml, &GetDocument(), exception_state);
- if (!exception_state.HadException()) {
- SetInnerHTMLFromString(html, exception_state);
- }
-}
-
void ShadowRoot::RecalcStyle(const StyleRecalcChange change) {
// ShadowRoot doesn't support custom callbacks.
DCHECK(!HasCustomStyleCallbacks());
@@ -222,9 +208,10 @@ void ShadowRoot::ChildrenChanged(const ChildrenChange& change) {
if (change.IsChildElementChange()) {
CheckForSiblingStyleChanges(
- change.type == kElementRemoved ? kSiblingElementRemoved
- : kSiblingElementInserted,
- To<Element>(change.sibling_changed.Get()), change.sibling_before_change,
+ change.type == ChildrenChangeType::kElementRemoved
+ ? kSiblingElementRemoved
+ : kSiblingElementInserted,
+ To<Element>(change.sibling_changed), change.sibling_before_change,
change.sibling_after_change);
}
}
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 5cce67184ee..7a0290d0790 100644
--- a/chromium/third_party/blink/renderer/core/dom/shadow_root.h
+++ b/chromium/third_party/blink/renderer/core/dom/shadow_root.h
@@ -42,12 +42,13 @@ class Document;
class ExceptionState;
class ShadowRootV0;
class SlotAssignment;
-class StringOrTrustedHTML;
class WhitespaceAttacher;
enum class ShadowRootType { V0, kOpen, kClosed, kUserAgent };
-enum class ShadowRootSlotting { kManual, kAuto };
+enum class SlotAssignmentMode { kManual, kAuto };
+
+enum class FocusDelegation { kNone, kDelegateFocus };
class CORE_EXPORT ShadowRoot final : public DocumentFragment, public TreeScope {
DEFINE_WRAPPERTYPEINFO();
@@ -139,23 +140,24 @@ class CORE_EXPORT ShadowRoot final : public DocumentFragment, public TreeScope {
Element* ActiveElement() const;
- String InnerHTMLAsString() const;
- void SetInnerHTMLFromString(const String&,
- ExceptionState& = ASSERT_NO_EXCEPTION);
-
- // TrustedTypes variants of the above.
- // TODO(mkwst): Write a spec for these bits. https://crbug.com/739170
- void innerHTML(StringOrTrustedHTML&) const;
- void setInnerHTML(const StringOrTrustedHTML&, ExceptionState&);
+ String innerHTML() const;
+ void setInnerHTML(const String&, ExceptionState& = ASSERT_NO_EXCEPTION);
Node* Clone(Document&, CloneChildrenFlag) const override;
void SetDelegatesFocus(bool flag) { delegates_focus_ = flag; }
bool delegatesFocus() const { return delegates_focus_; }
- void SetSlotting(ShadowRootSlotting slotting);
- bool IsManualSlotting() {
- return slotting_ == static_cast<unsigned>(ShadowRootSlotting::kManual);
+ void SetSlotAssignmentMode(SlotAssignmentMode assignment);
+ bool IsManualSlotting() const {
+ return slot_assignment_mode_ ==
+ static_cast<unsigned>(SlotAssignmentMode::kManual);
+ }
+ SlotAssignmentMode GetSlotAssignmentMode() const {
+ return static_cast<SlotAssignmentMode>(slot_assignment_mode_);
+ }
+ String slotAssignment() const {
+ return IsManualSlotting() ? "manual" : "auto";
}
bool ContainsShadowRoots() const { return child_shadow_root_count_; }
@@ -188,7 +190,7 @@ class CORE_EXPORT ShadowRoot final : public DocumentFragment, public TreeScope {
unsigned type_ : 2;
unsigned registered_with_parent_shadow_root_ : 1;
unsigned delegates_focus_ : 1;
- unsigned slotting_ : 1;
+ unsigned slot_assignment_mode_ : 1;
unsigned needs_distribution_recalc_ : 1;
unsigned unused_ : 10;
diff --git a/chromium/third_party/blink/renderer/core/dom/shadow_root.idl b/chromium/third_party/blink/renderer/core/dom/shadow_root.idl
index ec004dfb701..0080770117d 100644
--- a/chromium/third_party/blink/renderer/core/dom/shadow_root.idl
+++ b/chromium/third_party/blink/renderer/core/dom/shadow_root.idl
@@ -30,8 +30,11 @@
interface ShadowRoot : DocumentFragment {
readonly attribute ShadowRootMode mode;
readonly attribute Element host;
- [CEReactions, CustomElementCallbacks, Custom=Setter] attribute HTMLString innerHTML;
+ // TODO(lyf): Change the type to `[TreatNullAs=xxx] HTMLString` after
+ // https://crbug.com/1058762 has been fixed.
+ [CEReactions, CustomElementCallbacks, RaisesException=Setter] attribute [TreatNullAs=EmptyString, StringContext=TrustedHTML] DOMString innerHTML;
readonly attribute boolean delegatesFocus;
+ [RuntimeEnabled=ManualSlotting] readonly attribute SlotAssignmentMode slotAssignment;
};
ShadowRoot includes DocumentOrShadowRoot;
diff --git a/chromium/third_party/blink/renderer/core/dom/shadow_root_init.idl b/chromium/third_party/blink/renderer/core/dom/shadow_root_init.idl
index 0857f2ae500..ed464209c97 100644
--- a/chromium/third_party/blink/renderer/core/dom/shadow_root_init.idl
+++ b/chromium/third_party/blink/renderer/core/dom/shadow_root_init.idl
@@ -5,10 +5,10 @@
// Spec: https://w3c.github.io/webcomponents/spec/shadow/#shadowrootinit-dictionary
enum ShadowRootMode { "open", "closed" };
-enum ShadowRootSlottingMode { "manual", "auto" };
+enum SlotAssignmentMode { "manual", "auto" };
dictionary ShadowRootInit {
required ShadowRootMode mode;
boolean delegatesFocus;
- [RuntimeEnabled=ManualSlotting] ShadowRootSlottingMode slotting;
+ [RuntimeEnabled=ManualSlotting] SlotAssignmentMode slotAssignment;
};
diff --git a/chromium/third_party/blink/renderer/core/dom/slot_assignment_test.cc b/chromium/third_party/blink/renderer/core/dom/slot_assignment_test.cc
index db21a594ec7..ec0505a065c 100644
--- a/chromium/third_party/blink/renderer/core/dom/slot_assignment_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/slot_assignment_test.cc
@@ -103,7 +103,7 @@ void SlotAssignmentTest::SetUp() {
void SlotAssignmentTest::SetBody(const char* html) {
Element* body = GetDocument().body();
- body->SetInnerHTMLFromString(String::FromUTF8(html));
+ body->setInnerHTML(String::FromUTF8(html));
ConvertDeclarativeShadowDOMToShadowRoot(*body);
RemoveWhiteSpaceOnlyTextNode(*body);
}
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 c40af665aff..ec11d4c1c20 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
@@ -29,8 +29,6 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_STATIC_NODE_LIST_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_STATIC_NODE_LIST_H_
-#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/dom/node_child_removal_tracker.h"
#include "third_party/blink/renderer/core/dom/node_list.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -75,13 +73,8 @@ unsigned StaticNodeTypeList<NodeType>::length() const {
template <typename NodeType>
NodeType* StaticNodeTypeList<NodeType>::item(unsigned index) const {
- if (index < nodes_.size()) {
- auto* node = nodes_[index].Get();
- if (node->GetDocument().InDOMNodeRemovedHandler() &&
- NodeChildRemovalTracker::IsBeingRemoved(*node))
- node->GetDocument().CountDetachingNodeAccessInDOMNodeRemovedHandler();
- return node;
- }
+ if (index < nodes_.size())
+ return nodes_[index].Get();
return nullptr;
}
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 bbab5fd4e89..c46da517509 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
@@ -45,7 +45,7 @@ HTMLDocument& StaticRangeTest::GetDocument() const {
TEST_F(StaticRangeTest, SplitTextNodeRangeWithinText) {
V8TestingScope scope;
- GetDocument().body()->SetInnerHTMLFromString("1234");
+ GetDocument().body()->setInnerHTML("1234");
auto* old_text = To<Text>(GetDocument().body()->firstChild());
auto* static_range04 = MakeGarbageCollected<StaticRange>(
@@ -116,7 +116,7 @@ TEST_F(StaticRangeTest, SplitTextNodeRangeWithinText) {
TEST_F(StaticRangeTest, SplitTextNodeRangeOutsideText) {
V8TestingScope scope;
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<span id=\"outer\">0<span id=\"inner-left\">1</span>SPLITME<span "
"id=\"inner-right\">2</span>3</span>");
@@ -231,7 +231,7 @@ TEST_F(StaticRangeTest, SplitTextNodeRangeOutsideText) {
TEST_F(StaticRangeTest, InvalidToRange) {
V8TestingScope scope;
- GetDocument().body()->SetInnerHTMLFromString("1234");
+ GetDocument().body()->setInnerHTML("1234");
auto* old_text = To<Text>(GetDocument().body()->firstChild());
auto* static_range04 = MakeGarbageCollected<StaticRange>(
diff --git a/chromium/third_party/blink/renderer/core/dom/synchronous_mutation_notifier.cc b/chromium/third_party/blink/renderer/core/dom/synchronous_mutation_notifier.cc
deleted file mode 100644
index c2c719883ce..00000000000
--- a/chromium/third_party/blink/renderer/core/dom/synchronous_mutation_notifier.cc
+++ /dev/null
@@ -1,68 +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/dom/synchronous_mutation_notifier.h"
-
-#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/dom/synchronous_mutation_observer.h"
-
-namespace blink {
-
-SynchronousMutationNotifier::SynchronousMutationNotifier() = default;
-
-void SynchronousMutationNotifier::NotifyChangeChildren(
- const ContainerNode& container) {
- ForEachObserver([&](SynchronousMutationObserver* observer) {
- observer->DidChangeChildren(container);
- });
-}
-
-void SynchronousMutationNotifier::NotifyMergeTextNodes(
- const Text& node,
- const NodeWithIndex& node_to_be_removed_with_index,
- unsigned old_length) {
- ForEachObserver([&](SynchronousMutationObserver* observer) {
- observer->DidMergeTextNodes(node, node_to_be_removed_with_index,
- old_length);
- });
-}
-
-void SynchronousMutationNotifier::NotifyMoveTreeToNewDocument(
- const Node& root) {
- ForEachObserver([&](SynchronousMutationObserver* observer) {
- observer->DidMoveTreeToNewDocument(root);
- });
-}
-
-void SynchronousMutationNotifier::NotifySplitTextNode(const Text& node) {
- ForEachObserver([&](SynchronousMutationObserver* observer) {
- observer->DidSplitTextNode(node);
- });
-}
-
-void SynchronousMutationNotifier::NotifyUpdateCharacterData(
- CharacterData* character_data,
- unsigned offset,
- unsigned old_length,
- unsigned new_length) {
- ForEachObserver([&](SynchronousMutationObserver* observer) {
- observer->DidUpdateCharacterData(character_data, offset, old_length,
- new_length);
- });
-}
-
-void SynchronousMutationNotifier::NotifyNodeChildrenWillBeRemoved(
- ContainerNode& container) {
- ForEachObserver([&](SynchronousMutationObserver* observer) {
- observer->NodeChildrenWillBeRemoved(container);
- });
-}
-
-void SynchronousMutationNotifier::NotifyNodeWillBeRemoved(Node& node) {
- ForEachObserver([&](SynchronousMutationObserver* observer) {
- observer->NodeWillBeRemoved(node);
- });
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/dom/synchronous_mutation_notifier.h b/chromium/third_party/blink/renderer/core/dom/synchronous_mutation_notifier.h
deleted file mode 100644
index dd2a04a94e8..00000000000
--- a/chromium/third_party/blink/renderer/core/dom/synchronous_mutation_notifier.h
+++ /dev/null
@@ -1,49 +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_DOM_SYNCHRONOUS_MUTATION_NOTIFIER_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_SYNCHRONOUS_MUTATION_NOTIFIER_H_
-
-#include "base/macros.h"
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/platform/lifecycle_notifier.h"
-
-namespace blink {
-
-class CharacterData;
-class ContainerNode;
-class Document;
-class Node;
-class NodeWithIndex;
-class SynchronousMutationObserver;
-class Text;
-
-class CORE_EXPORT SynchronousMutationNotifier
- : public LifecycleNotifier<Document, SynchronousMutationObserver> {
- public:
- // TODO(yosin): We will have |notifyXXX()| functions defined in
- // |SynchronousMutationObserver|.
- void NotifyChangeChildren(const ContainerNode&);
- void NotifyMergeTextNodes(const Text& merged_node,
- const NodeWithIndex& node_to_be_removed_with_index,
- unsigned old_length);
- void NotifyMoveTreeToNewDocument(const Node&);
- void NotifySplitTextNode(const Text&);
- void NotifyUpdateCharacterData(CharacterData*,
- unsigned offset,
- unsigned old_length,
- unsigned new_length);
- void NotifyNodeChildrenWillBeRemoved(ContainerNode&);
- void NotifyNodeWillBeRemoved(Node&);
-
- protected:
- SynchronousMutationNotifier();
-
- private:
- DISALLOW_COPY_AND_ASSIGN(SynchronousMutationNotifier);
-};
-
-} // namespace dom
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_SYNCHRONOUS_MUTATION_NOTIFIER_H_
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 f3eac687ac3..ce72d1f7c2c 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
@@ -5,24 +5,28 @@
#include "third_party/blink/renderer/core/dom/synchronous_mutation_observer.h"
#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/dom/synchronous_mutation_notifier.h"
namespace blink {
-SynchronousMutationObserver::SynchronousMutationObserver()
- : LifecycleObserver(nullptr) {}
-
-void SynchronousMutationObserver::DidChangeChildren(const ContainerNode&) {}
-void SynchronousMutationObserver::DidMergeTextNodes(const Text&,
- const NodeWithIndex&,
- unsigned) {}
-void SynchronousMutationObserver::DidMoveTreeToNewDocument(const Node&) {}
-void SynchronousMutationObserver::DidSplitTextNode(const Text&) {}
-void SynchronousMutationObserver::DidUpdateCharacterData(CharacterData*,
- unsigned,
- unsigned,
- unsigned) {}
-void SynchronousMutationObserver::NodeChildrenWillBeRemoved(ContainerNode&) {}
-void SynchronousMutationObserver::NodeWillBeRemoved(Node&) {}
+void SynchronousMutationObserver::ObserverListWillBeCleared() {
+ document_ = nullptr;
+}
+
+void SynchronousMutationObserver::SetDocument(Document* document) {
+ if (document == document_)
+ return;
+
+ if (document_)
+ document_->SynchronousMutationObserverList().RemoveObserver(this);
+
+ document_ = document;
+
+ if (document_)
+ document_->SynchronousMutationObserverList().AddObserver(this);
+}
+
+void SynchronousMutationObserver::Trace(Visitor* visitor) {
+ visitor->Trace(document_);
+}
} // namespace blink
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 1ef62cea242..6999e725ad8 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
@@ -5,9 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_SYNCHRONOUS_MUTATION_OBSERVER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_SYNCHRONOUS_MUTATION_OBSERVER_H_
-#include "base/macros.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/platform/lifecycle_observer.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
@@ -21,8 +20,8 @@ class Text;
// synchronously. If you want to observe DOM tree mutation asynchronously see
// MutationObserver Web API.
// Note: if you only need to observe Document shutdown,
-// DocumentShutdownObserver provides this same functionality more efficiently
-// (since it doesn't observe the other events).
+// ExecutionContextLifecycleObserver::ContextDestroyed provides this same
+// functionality more efficiently (since it doesn't observe the other events).
//
// TODO(yosin): Following classes should be derived from this class to
// simplify Document class.
@@ -34,8 +33,7 @@ class Text;
// - SelectionController
// - Range set
// - NodeIterator set
-class CORE_EXPORT SynchronousMutationObserver
- : public LifecycleObserver<Document, SynchronousMutationObserver> {
+class CORE_EXPORT SynchronousMutationObserver : public GarbageCollectedMixin {
public:
// TODO(yosin): We will have following member functions:
// - dataWillBeChanged(const CharacterData&);
@@ -44,21 +42,21 @@ class CORE_EXPORT SynchronousMutationObserver
// - didRemoveText(Node*, unsigned offset, unsigned length);
// Called after child nodes changed.
- virtual void DidChangeChildren(const ContainerNode&);
+ virtual void DidChangeChildren(const ContainerNode&) {}
// Called after characters in |nodeToBeRemoved| is appended into |mergedNode|.
// |oldLength| holds length of |mergedNode| before merge.
virtual void DidMergeTextNodes(
const Text& merged_node,
const NodeWithIndex& node_to_be_removed_with_index,
- unsigned old_length);
+ unsigned old_length) {}
// Called just after node tree |root| is moved to new document.
- virtual void DidMoveTreeToNewDocument(const Node& root);
+ virtual void DidMoveTreeToNewDocument(const Node& root) {}
// Called when |Text| node is split, next sibling |oldNode| contains
// characters after split point.
- virtual void DidSplitTextNode(const Text& old_node);
+ virtual void DidSplitTextNode(const Text& old_node) {}
// Called when |CharacterData| is updated at |offset|, |oldLength| is a
// number of deleted character and |newLength| is a number of added
@@ -66,22 +64,30 @@ class CORE_EXPORT SynchronousMutationObserver
virtual void DidUpdateCharacterData(CharacterData*,
unsigned offset,
unsigned old_length,
- unsigned new_length);
+ unsigned new_length) {}
// Called before removing container node.
- virtual void NodeChildrenWillBeRemoved(ContainerNode&);
+ virtual void NodeChildrenWillBeRemoved(ContainerNode&) {}
// Called before removing node.
- virtual void NodeWillBeRemoved(Node&);
+ virtual void NodeWillBeRemoved(Node&) {}
// Called when detaching document.
- virtual void ContextDestroyed(Document*) {}
+ virtual void ContextDestroyed() {}
+
+ // Call before clearing an observer list.
+ void ObserverListWillBeCleared();
+
+ Document* GetDocument() const { return document_; }
+ void SetDocument(Document*);
+
+ void Trace(Visitor*) override;
protected:
- SynchronousMutationObserver();
+ SynchronousMutationObserver() = default;
private:
- DISALLOW_COPY_AND_ASSIGN(SynchronousMutationObserver);
+ WeakMember<Document> document_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/dom/tag_collection.h b/chromium/third_party/blink/renderer/core/dom/tag_collection.h
index d9842209221..40cbb9c1019 100644
--- a/chromium/third_party/blink/renderer/core/dom/tag_collection.h
+++ b/chromium/third_party/blink/renderer/core/dom/tag_collection.h
@@ -32,14 +32,6 @@ namespace blink {
// Collection that limits to a particular tag.
class TagCollection : public HTMLCollection {
public:
- static TagCollection* Create(ContainerNode& root_node,
- CollectionType type,
- const AtomicString& qualified_name) {
- DCHECK_EQ(type, kTagCollectionType);
- return MakeGarbageCollected<TagCollection>(root_node, kTagCollectionType,
- qualified_name);
- }
-
TagCollection(ContainerNode& root_node,
CollectionType,
const AtomicString& qualified_name);
@@ -53,13 +45,6 @@ class TagCollection : public HTMLCollection {
class TagCollectionNS : public HTMLCollection {
public:
- static TagCollectionNS* Create(ContainerNode& root_node,
- const AtomicString& namespace_uri,
- const AtomicString& local_name) {
- return MakeGarbageCollected<TagCollectionNS>(
- root_node, kTagCollectionNSType, namespace_uri, local_name);
- }
-
TagCollectionNS(ContainerNode& root_node,
CollectionType,
const AtomicString& namespace_uri,
@@ -73,17 +58,19 @@ class TagCollectionNS : public HTMLCollection {
AtomicString local_name_;
};
-DEFINE_TYPE_CASTS(TagCollection,
- LiveNodeListBase,
- collection,
- collection->GetType() == kTagCollectionType,
- collection.GetType() == kTagCollectionType);
+template <>
+struct DowncastTraits<TagCollection> {
+ static bool AllowFrom(const LiveNodeListBase& collection) {
+ return collection.GetType() == kTagCollectionType;
+ }
+};
-DEFINE_TYPE_CASTS(TagCollectionNS,
- LiveNodeListBase,
- collection,
- collection->GetType() == kTagCollectionNSType,
- collection.GetType() == kTagCollectionNSType);
+template <>
+struct DowncastTraits<TagCollectionNS> {
+ static bool AllowFrom(const LiveNodeListBase& collection) {
+ return collection.GetType() == kTagCollectionNSType;
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/dom/text.idl b/chromium/third_party/blink/renderer/core/dom/text.idl
index d199fd7adf7..7a10043d266 100644
--- a/chromium/third_party/blink/renderer/core/dom/text.idl
+++ b/chromium/third_party/blink/renderer/core/dom/text.idl
@@ -20,10 +20,9 @@
// https://dom.spec.whatwg.org/#interface-text
[
- Constructor(optional DOMString data = ""),
- ConstructorCallWith=Document,
Exposed=Window
] interface Text : CharacterData {
+ [CallWith=Document] constructor(optional DOMString data = "");
[NewObject, DoNotTestNewObject, RaisesException] Text splitText(unsigned long offset);
[MeasureAs=TextWholeText] readonly attribute DOMString wholeText;
diff --git a/chromium/third_party/blink/renderer/core/dom/text_link_colors.cc b/chromium/third_party/blink/renderer/core/dom/text_link_colors.cc
index 6c38ddaa4db..df6d9db255c 100644
--- a/chromium/third_party/blink/renderer/core/dom/text_link_colors.cc
+++ b/chromium/third_party/blink/renderer/core/dom/text_link_colors.cc
@@ -85,8 +85,6 @@ Color TextLinkColors::ColorFromCSSValue(const CSSValue& value,
return LayoutTheme::GetTheme().FocusRingColor();
case CSSValueID::kCurrentcolor:
return current_color;
- case CSSValueID::kInternalRootColor:
- return LayoutTheme::GetTheme().RootElementColor(color_scheme);
default:
return StyleColor::ColorFromKeyword(value_id, color_scheme);
}
diff --git a/chromium/third_party/blink/renderer/core/dom/traversal_range.h b/chromium/third_party/blink/renderer/core/dom/traversal_range.h
index 38939a61e34..cd8d349e2a9 100644
--- a/chromium/third_party/blink/renderer/core/dom/traversal_range.h
+++ b/chromium/third_party/blink/renderer/core/dom/traversal_range.h
@@ -22,7 +22,7 @@ class TraversalRange {
Iterator end() { return Iterator::End(); }
private:
- Member<const StartNodeType> start_;
+ const StartNodeType* start_;
};
template <class Traversal>
@@ -39,7 +39,7 @@ class TraversalIteratorBase {
protected:
explicit TraversalIteratorBase(NodeType* current) : current_(current) {}
- Member<NodeType> current_;
+ NodeType* current_;
};
template <class Traversal>
@@ -81,7 +81,7 @@ class TraversalDescendantIterator : public TraversalIteratorBase<Traversal> {
private:
TraversalDescendantIterator() : TraversalIteratorBase<Traversal>(nullptr) {}
- Member<const StartNodeType> root_;
+ const StartNodeType* root_ = nullptr;
};
template <class Traversal>
@@ -102,7 +102,7 @@ class TraversalInclusiveDescendantIterator
}
private:
- Member<const StartNodeType> root_;
+ const StartNodeType* root_;
};
template <class Traversal>
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 6a30fd0ce23..f1aef848635 100644
--- a/chromium/third_party/blink/renderer/core/dom/tree_scope.cc
+++ b/chromium/third_party/blink/renderer/core/dom/tree_scope.cc
@@ -34,7 +34,6 @@
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/dom/events/event_path.h"
#include "third_party/blink/renderer/core/dom/id_target_observer_registry.h"
-#include "third_party/blink/renderer/core/dom/node_child_removal_tracker.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/dom/tree_scope_adopter.h"
@@ -115,13 +114,7 @@ Element* TreeScope::getElementById(const AtomicString& element_id) const {
return nullptr;
if (!elements_by_id_)
return nullptr;
- Element* element = elements_by_id_->GetElementById(element_id, *this);
- if (element && &RootNode() == &GetDocument() &&
- GetDocument().InDOMNodeRemovedHandler()) {
- if (NodeChildRemovalTracker::IsBeingRemoved(*element))
- GetDocument().CountDetachingNodeAccessInDOMNodeRemovedHandler();
- }
- return element;
+ return elements_by_id_->GetElementById(element_id, *this);
}
const HeapVector<Member<Element>>& TreeScope::GetAllElementsById(
@@ -207,7 +200,7 @@ static bool PointInFrameContentIfVisible(Document& document,
return false;
// The VisibleContentRect check below requires that scrollbars are up-to-date.
- document.UpdateStyleAndLayout();
+ document.UpdateStyleAndLayout(DocumentUpdateReason::kHitTest);
auto* scrollable_area = frame_view->LayoutViewport();
IntRect visible_frame_rect(IntPoint(),
@@ -289,7 +282,7 @@ HeapVector<Member<Element>> TreeScope::ElementsFromHitTestResult(
HitTestResult& result) const {
HeapVector<Member<Element>> elements;
Node* last_node = nullptr;
- for (const auto rect_based_node : result.ListBasedTestResult()) {
+ for (const auto& rect_based_node : result.ListBasedTestResult()) {
Node* node = rect_based_node.Get();
if (!node->IsElementNode() && !ShouldAcceptNonElementNode(*node))
continue;
diff --git a/chromium/third_party/blink/renderer/core/dom/tree_scope_adopter.h b/chromium/third_party/blink/renderer/core/dom/tree_scope_adopter.h
index db59f06c363..0644c27164f 100644
--- a/chromium/third_party/blink/renderer/core/dom/tree_scope_adopter.h
+++ b/chromium/third_party/blink/renderer/core/dom/tree_scope_adopter.h
@@ -63,15 +63,15 @@ class CORE_EXPORT TreeScopeAdopter {
TreeScope& OldScope() const { return *old_scope_; }
TreeScope& NewScope() const { return *new_scope_; }
- Member<Node> to_adopt_;
- Member<TreeScope> new_scope_;
- Member<TreeScope> old_scope_;
+ Node* to_adopt_;
+ TreeScope* new_scope_;
+ TreeScope* old_scope_;
};
inline TreeScopeAdopter::TreeScopeAdopter(Node& to_adopt, TreeScope& new_scope)
- : to_adopt_(to_adopt),
- new_scope_(new_scope),
- old_scope_(to_adopt.GetTreeScope()) {}
+ : to_adopt_(&to_adopt),
+ new_scope_(&new_scope),
+ old_scope_(&to_adopt.GetTreeScope()) {}
} // namespace blink
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 b2985558174..1f19a82a2ef 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
@@ -33,8 +33,6 @@ namespace blink {
UserActionElementSet::UserActionElementSet() = default;
-UserActionElementSet::~UserActionElementSet() = default;
-
void UserActionElementSet::DidDetach(Element& element) {
DCHECK(element.IsUserActionElement());
ClearFlags(&element, kIsActiveFlag | kInActiveChainFlag | kIsHoveredFlag |
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 408825e8507..23181dacb0f 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
@@ -69,7 +69,6 @@ class UserActionElementSet final {
}
UserActionElementSet();
- ~UserActionElementSet();
void DidDetach(Element&);
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 0aff714f64b..b0a904af877 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
@@ -72,8 +72,8 @@ void V0InsertionPoint::SetDistributedNodes(
for (; i < distributed_nodes_.size() && j < distributed_nodes.size();
++i, ++j) {
if (distributed_nodes_.size() < distributed_nodes.size()) {
- // If the new distribution is larger than the old one, reattach all nodes
- // in the new distribution that were inserted.
+ // If the new distribution is larger than the old one, notify all nodes in
+ // the new distribution that were inserted.
for (; j < distributed_nodes.size() &&
distributed_nodes_.at(i) != distributed_nodes.at(j);
++j)
@@ -81,26 +81,21 @@ void V0InsertionPoint::SetDistributedNodes(
if (j == distributed_nodes.size())
break;
} else if (distributed_nodes_.size() > distributed_nodes.size()) {
- // If the old distribution is larger than the new one, reattach all nodes
- // in the old distribution that were removed.
- for (; i < distributed_nodes_.size() &&
- distributed_nodes_.at(i) != distributed_nodes.at(j);
- ++i)
- distributed_nodes_.at(i)->FlatTreeParentChanged();
+ // If the old distribution is larger than the new one, skip all nodes in
+ // the old distribution that were removed.
+ while (i < distributed_nodes_.size() &&
+ distributed_nodes_.at(i) != distributed_nodes.at(j))
+ ++i;
if (i == distributed_nodes_.size())
break;
} else if (distributed_nodes_.at(i) != distributed_nodes.at(j)) {
- // If both distributions are the same length reattach both old and new.
- distributed_nodes_.at(i)->FlatTreeParentChanged();
+ // If both distributions are the same length notify the new.
distributed_nodes.at(j)->FlatTreeParentChanged();
}
}
- // If we hit the end of either list above we need to reattach all remaining
- // nodes.
-
- for (; i < distributed_nodes_.size(); ++i)
- distributed_nodes_.at(i)->FlatTreeParentChanged();
+ // If we hit the end of either list above we need to notify all remaining
+ // nodes in the new distribution.
for (; j < distributed_nodes.size(); ++j)
distributed_nodes.at(j)->FlatTreeParentChanged();
diff --git a/chromium/third_party/blink/renderer/core/dom/whitespace_attacher.cc b/chromium/third_party/blink/renderer/core/dom/whitespace_attacher.cc
index a4dbdb24af0..b03567ba2fa 100644
--- a/chromium/third_party/blink/renderer/core/dom/whitespace_attacher.cc
+++ b/chromium/third_party/blink/renderer/core/dom/whitespace_attacher.cc
@@ -34,7 +34,7 @@ void WhitespaceAttacher::DidReattach(Node* node, LayoutObject* prev_in_flow) {
layout_object = prev_in_flow;
// Only in-flow boxes affect subsequent whitespace.
- if (layout_object && !layout_object->IsFloatingOrOutOfFlowPositioned())
+ if (layout_object && layout_object->AffectsWhitespaceSiblings())
ReattachWhitespaceSiblings(layout_object);
}
@@ -102,7 +102,7 @@ void WhitespaceAttacher::DidVisitElement(Element* element) {
SetLastTextNode(nullptr);
return;
}
- if (layout_object->IsFloatingOrOutOfFlowPositioned())
+ if (!layout_object->AffectsWhitespaceSiblings())
return;
ReattachWhitespaceSiblings(layout_object);
}
@@ -136,7 +136,7 @@ void WhitespaceAttacher::ReattachWhitespaceSiblings(
if (sibling_layout_object)
context.previous_in_flow = sibling_layout_object;
} else if (sibling_layout_object &&
- !sibling_layout_object->IsFloatingOrOutOfFlowPositioned()) {
+ sibling_layout_object->AffectsWhitespaceSiblings()) {
break;
}
context.next_sibling_valid = false;
@@ -160,7 +160,8 @@ void WhitespaceAttacher::ForceLastTextNodeNeedsReattach() {
void WhitespaceAttacher::UpdateLastTextNodeFromDisplayContents() {
DCHECK(last_display_contents_);
DCHECK(last_display_contents_->HasDisplayContentsStyle());
- Element* contents_element = last_display_contents_.Release();
+ Element* contents_element = last_display_contents_;
+ last_display_contents_ = nullptr;
Node* sibling =
LayoutTreeBuilderTraversal::FirstLayoutChild(*contents_element);
@@ -183,7 +184,7 @@ void WhitespaceAttacher::UpdateLastTextNodeFromDisplayContents() {
last_text_node_ = text;
return;
}
- if (layout_object && !layout_object->IsFloatingOrOutOfFlowPositioned()) {
+ if (layout_object && layout_object->AffectsWhitespaceSiblings()) {
last_text_node_ = nullptr;
break;
}
diff --git a/chromium/third_party/blink/renderer/core/dom/whitespace_attacher.h b/chromium/third_party/blink/renderer/core/dom/whitespace_attacher.h
index 2c2b427c1b8..15563dee305 100644
--- a/chromium/third_party/blink/renderer/core/dom/whitespace_attacher.h
+++ b/chromium/third_party/blink/renderer/core/dom/whitespace_attacher.h
@@ -77,10 +77,10 @@ class CORE_EXPORT WhitespaceAttacher {
// Invariants:
// DCHECK(!last_display_contents_ || !last_text_node_needs_reattach_)
// DCHECK(last_text_node_ || !last_text_node_needs_reattach_)
- Member<Element> last_display_contents_ = nullptr;
+ Element* last_display_contents_ = nullptr;
// The last text node we've visited during rebuild for this attacher.
- Member<Text> last_text_node_ = nullptr;
+ Text* last_text_node_ = nullptr;
// Set to true if we need to re-attach last_text_node_ when:
// 1. We visiting a previous in-flow sibling, or
diff --git a/chromium/third_party/blink/renderer/core/dom/whitespace_attacher_test.cc b/chromium/third_party/blink/renderer/core/dom/whitespace_attacher_test.cc
index da281640af4..f4ffb1b13a5 100644
--- a/chromium/third_party/blink/renderer/core/dom/whitespace_attacher_test.cc
+++ b/chromium/third_party/blink/renderer/core/dom/whitespace_attacher_test.cc
@@ -6,10 +6,10 @@
#include <gtest/gtest.h>
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_shadow_root_init.h"
#include "third_party/blink/renderer/core/css/style_engine.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
-#include "third_party/blink/renderer/core/dom/shadow_root_init.h"
#include "third_party/blink/renderer/core/layout/layout_text.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
@@ -24,7 +24,7 @@ class WhitespaceAttacherTest : public PageTestBase {
};
TEST_F(WhitespaceAttacherTest, WhitespaceAfterReattachedBlock) {
- GetDocument().body()->SetInnerHTMLFromString("<div id=block></div> ");
+ GetDocument().body()->setInnerHTML("<div id=block></div> ");
UpdateAllLifecyclePhasesForTest();
Element* div = GetDocument().getElementById("block");
@@ -44,7 +44,7 @@ TEST_F(WhitespaceAttacherTest, WhitespaceAfterReattachedBlock) {
}
TEST_F(WhitespaceAttacherTest, WhitespaceAfterReattachedInline) {
- GetDocument().body()->SetInnerHTMLFromString("<span id=inline></span> ");
+ GetDocument().body()->setInnerHTML("<span id=inline></span> ");
UpdateAllLifecyclePhasesForTest();
Element* span = GetDocument().getElementById("inline");
@@ -63,8 +63,7 @@ TEST_F(WhitespaceAttacherTest, WhitespaceAfterReattachedInline) {
}
TEST_F(WhitespaceAttacherTest, WhitespaceAfterReattachedWhitespace) {
- GetDocument().body()->SetInnerHTMLFromString(
- "<span id=inline></span> <!-- --> ");
+ GetDocument().body()->setInnerHTML("<span id=inline></span> <!-- --> ");
UpdateAllLifecyclePhasesForTest();
Element* span = GetDocument().getElementById("inline");
@@ -90,7 +89,7 @@ TEST_F(WhitespaceAttacherTest, WhitespaceAfterReattachedWhitespace) {
}
TEST_F(WhitespaceAttacherTest, VisitBlockAfterReattachedWhitespace) {
- GetDocument().body()->SetInnerHTMLFromString("<div id=block></div> ");
+ GetDocument().body()->setInnerHTML("<div id=block></div> ");
UpdateAllLifecyclePhasesForTest();
Element* div = GetDocument().getElementById("block");
@@ -108,7 +107,7 @@ TEST_F(WhitespaceAttacherTest, VisitBlockAfterReattachedWhitespace) {
}
TEST_F(WhitespaceAttacherTest, VisitInlineAfterReattachedWhitespace) {
- GetDocument().body()->SetInnerHTMLFromString("<span id=inline></span> ");
+ GetDocument().body()->setInnerHTML("<span id=inline></span> ");
UpdateAllLifecyclePhasesForTest();
Element* span = GetDocument().getElementById("inline");
@@ -129,7 +128,7 @@ TEST_F(WhitespaceAttacherTest, VisitInlineAfterReattachedWhitespace) {
}
TEST_F(WhitespaceAttacherTest, VisitTextAfterReattachedWhitespace) {
- GetDocument().body()->SetInnerHTMLFromString("Text<!-- --> ");
+ GetDocument().body()->setInnerHTML("Text<!-- --> ");
UpdateAllLifecyclePhasesForTest();
auto* text = To<Text>(GetDocument().body()->firstChild());
@@ -152,7 +151,7 @@ TEST_F(WhitespaceAttacherTest, VisitTextAfterReattachedWhitespace) {
}
TEST_F(WhitespaceAttacherTest, ReattachWhitespaceInsideBlockExitingScope) {
- GetDocument().body()->SetInnerHTMLFromString("<div id=block> </div>");
+ GetDocument().body()->setInnerHTML("<div id=block> </div>");
UpdateAllLifecyclePhasesForTest();
Element* div = GetDocument().getElementById("block");
@@ -174,7 +173,7 @@ TEST_F(WhitespaceAttacherTest, ReattachWhitespaceInsideBlockExitingScope) {
}
TEST_F(WhitespaceAttacherTest, ReattachWhitespaceInsideInlineExitingScope) {
- GetDocument().body()->SetInnerHTMLFromString("<span id=inline> </span>");
+ GetDocument().body()->setInnerHTML("<span id=inline> </span>");
UpdateAllLifecyclePhasesForTest();
Element* span = GetDocument().getElementById("inline");
@@ -195,13 +194,13 @@ TEST_F(WhitespaceAttacherTest, ReattachWhitespaceInsideInlineExitingScope) {
}
TEST_F(WhitespaceAttacherTest, SlottedWhitespaceAfterReattachedBlock) {
- GetDocument().body()->SetInnerHTMLFromString("<div id=host> </div>");
+ GetDocument().body()->setInnerHTML("<div id=host> </div>");
Element* host = GetDocument().getElementById("host");
ASSERT_TRUE(host);
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString("<div id=block></div><slot></slot>");
+ shadow_root.setInnerHTML("<div id=block></div><slot></slot>");
UpdateAllLifecyclePhasesForTest();
Element* div = shadow_root.getElementById("block");
@@ -223,13 +222,13 @@ TEST_F(WhitespaceAttacherTest, SlottedWhitespaceAfterReattachedBlock) {
}
TEST_F(WhitespaceAttacherTest, SlottedWhitespaceAfterReattachedInline) {
- GetDocument().body()->SetInnerHTMLFromString("<div id=host> </div>");
+ GetDocument().body()->setInnerHTML("<div id=host> </div>");
Element* host = GetDocument().getElementById("host");
ASSERT_TRUE(host);
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString("<span id=inline></span><slot></slot>");
+ shadow_root.setInnerHTML("<span id=inline></span><slot></slot>");
UpdateAllLifecyclePhasesForTest();
Element* span = shadow_root.getElementById("inline");
@@ -251,7 +250,7 @@ TEST_F(WhitespaceAttacherTest, SlottedWhitespaceAfterReattachedInline) {
TEST_F(WhitespaceAttacherTest,
WhitespaceInDisplayContentsAfterReattachedBlock) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<div id=block></div><span style='display:contents'> </span>");
UpdateAllLifecyclePhasesForTest();
@@ -277,7 +276,7 @@ TEST_F(WhitespaceAttacherTest,
TEST_F(WhitespaceAttacherTest,
WhitespaceInDisplayContentsAfterReattachedInline) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<span id=inline></span><span style='display:contents'> </span>");
UpdateAllLifecyclePhasesForTest();
@@ -302,7 +301,7 @@ TEST_F(WhitespaceAttacherTest,
TEST_F(WhitespaceAttacherTest,
WhitespaceAfterEmptyDisplayContentsAfterReattachedBlock) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<div id=block></div><span style='display:contents'></span> ");
UpdateAllLifecyclePhasesForTest();
@@ -329,7 +328,7 @@ TEST_F(WhitespaceAttacherTest,
TEST_F(WhitespaceAttacherTest,
WhitespaceAfterDisplayContentsWithDisplayNoneChildAfterReattachedBlock) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<div id=block></div><span style='display:contents'>"
"<span style='display:none'></span></span> ");
UpdateAllLifecyclePhasesForTest();
@@ -356,7 +355,7 @@ TEST_F(WhitespaceAttacherTest,
}
TEST_F(WhitespaceAttacherTest, WhitespaceDeepInsideDisplayContents) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<span id=inline></span><span style='display:contents'>"
"<span style='display:none'></span>"
"<span id=inner style='display:contents'> </span></span>");
@@ -381,7 +380,7 @@ TEST_F(WhitespaceAttacherTest, WhitespaceDeepInsideDisplayContents) {
}
TEST_F(WhitespaceAttacherTest, MultipleDisplayContents) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<span id=inline></span>"
"<span style='display:contents'></span>"
"<span style='display:contents'></span>"
@@ -411,13 +410,13 @@ TEST_F(WhitespaceAttacherTest, MultipleDisplayContents) {
}
TEST_F(WhitespaceAttacherTest, SlottedWhitespaceInsideDisplayContents) {
- GetDocument().body()->SetInnerHTMLFromString("<div id=host> </div>");
+ GetDocument().body()->setInnerHTML("<div id=host> </div>");
Element* host = GetDocument().getElementById("host");
ASSERT_TRUE(host);
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString(
+ shadow_root.setInnerHTML(
"<span id=inline></span>"
"<div style='display:contents'><slot></slot></div>");
UpdateAllLifecyclePhasesForTest();
@@ -441,7 +440,7 @@ TEST_F(WhitespaceAttacherTest, SlottedWhitespaceInsideDisplayContents) {
}
TEST_F(WhitespaceAttacherTest, RemoveInlineBeforeSpace) {
- GetDocument().body()->SetInnerHTMLFromString("<span id=inline></span> ");
+ GetDocument().body()->setInnerHTML("<span id=inline></span> ");
UpdateAllLifecyclePhasesForTest();
Element* span = GetDocument().getElementById("inline");
@@ -463,7 +462,7 @@ TEST_F(WhitespaceAttacherTest, RemoveInlineBeforeSpace) {
}
TEST_F(WhitespaceAttacherTest, RemoveInlineBeforeOutOfFlowBeforeSpace) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<span id=inline></span><div id=float style='float:right'></div> ");
UpdateAllLifecyclePhasesForTest();
@@ -489,7 +488,7 @@ TEST_F(WhitespaceAttacherTest, RemoveInlineBeforeOutOfFlowBeforeSpace) {
}
TEST_F(WhitespaceAttacherTest, RemoveSpaceBeforeSpace) {
- GetDocument().body()->SetInnerHTMLFromString("<span> <!-- --> </span>");
+ GetDocument().body()->setInnerHTML("<span> <!-- --> </span>");
UpdateAllLifecyclePhasesForTest();
Node* span = GetDocument().body()->firstChild();
@@ -512,7 +511,7 @@ TEST_F(WhitespaceAttacherTest, RemoveSpaceBeforeSpace) {
}
TEST_F(WhitespaceAttacherTest, RemoveInlineBeforeDisplayContentsWithSpace) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<style>div { display: contents }</style>"
"<div><span id=inline></span></div>"
"<div><div><div id=innerdiv> </div></div></div>text");
@@ -533,8 +532,7 @@ TEST_F(WhitespaceAttacherTest, RemoveInlineBeforeDisplayContentsWithSpace) {
}
TEST_F(WhitespaceAttacherTest, RemoveBlockBeforeSpace) {
- GetDocument().body()->SetInnerHTMLFromString(
- "A<div id=block></div> <span>B</span>");
+ GetDocument().body()->setInnerHTML("A<div id=block></div> <span>B</span>");
UpdateAllLifecyclePhasesForTest();
Node* div = GetDocument().getElementById("block");
diff --git a/chromium/third_party/blink/renderer/core/dom/xml_document.h b/chromium/third_party/blink/renderer/core/dom/xml_document.h
index 95828e80e86..858e7f68c79 100644
--- a/chromium/third_party/blink/renderer/core/dom/xml_document.h
+++ b/chromium/third_party/blink/renderer/core/dom/xml_document.h
@@ -50,7 +50,12 @@ class XMLDocument final : public Document {
DocumentClassFlags document_classes = kXMLDocumentClass);
};
-DEFINE_DOCUMENT_TYPE_CASTS(XMLDocument);
+template <>
+struct DowncastTraits<XMLDocument> {
+ static bool AllowFrom(const Document& document) {
+ return document.IsXMLDocument();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/editing/caret_display_item_client_test.cc b/chromium/third_party/blink/renderer/core/editing/caret_display_item_client_test.cc
index cbafb7631ff..a89d234d80d 100644
--- a/chromium/third_party/blink/renderer/core/editing/caret_display_item_client_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/caret_display_item_client_test.cc
@@ -64,10 +64,12 @@ class CaretDisplayItemClientTest : public PaintAndRasterInvalidationTest {
void UpdateAllLifecyclePhasesForCaretTest() {
// Partial lifecycle updates should not affect caret paint invalidation.
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
UpdateAllLifecyclePhasesForTest();
// Partial lifecycle updates should not affect caret paint invalidation.
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
}
};
@@ -86,7 +88,8 @@ TEST_P(CaretDisplayItemClientTest, CaretPaintInvalidation) {
GetDocument().View()->SetTracksRasterInvalidations(true);
GetDocument().body()->focus();
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_FALSE(GetCaretDisplayItemClient().IsValid());
UpdateAllLifecyclePhasesForCaretTest();
@@ -110,7 +113,8 @@ TEST_P(CaretDisplayItemClientTest, CaretPaintInvalidation) {
SelectionInDOMTree::Builder().Collapse(Position(text, 5)).Build());
EXPECT_TRUE(GetCaretDisplayItemClient().IsValid());
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_FALSE(GetCaretDisplayItemClient().IsValid());
UpdateAllLifecyclePhasesForCaretTest();
@@ -138,7 +142,8 @@ TEST_P(CaretDisplayItemClientTest, CaretPaintInvalidation) {
Selection().SetSelectionAndEndTyping(SelectionInDOMTree());
EXPECT_TRUE(GetCaretDisplayItemClient().IsValid());
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_FALSE(GetCaretDisplayItemClient().IsValid());
UpdateAllLifecyclePhasesForCaretTest();
@@ -167,7 +172,8 @@ TEST_P(CaretDisplayItemClientTest, CaretMovesBetweenBlocks) {
// Focus the body.
GetDocument().body()->focus();
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_FALSE(GetCaretDisplayItemClient().IsValid());
UpdateAllLifecyclePhasesForCaretTest();
@@ -188,7 +194,8 @@ TEST_P(CaretDisplayItemClientTest, CaretMovesBetweenBlocks) {
.Build());
EXPECT_TRUE(GetCaretDisplayItemClient().IsValid());
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_FALSE(GetCaretDisplayItemClient().IsValid());
UpdateAllLifecyclePhasesForCaretTest();
@@ -219,7 +226,8 @@ TEST_P(CaretDisplayItemClientTest, CaretMovesBetweenBlocks) {
.Build());
EXPECT_TRUE(GetCaretDisplayItemClient().IsValid());
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_FALSE(GetCaretDisplayItemClient().IsValid());
UpdateAllLifecyclePhasesForCaretTest();
@@ -256,7 +264,8 @@ TEST_P(CaretDisplayItemClientTest, UpdatePreviousLayoutBlock) {
SelectionInDOMTree::Builder()
.Collapse(Position(block_element2, 0))
.Build());
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(block2->ShouldPaintCursorCaret());
EXPECT_EQ(block2, CaretLayoutBlock());
EXPECT_FALSE(block1->ShouldPaintCursorCaret());
@@ -267,7 +276,8 @@ TEST_P(CaretDisplayItemClientTest, UpdatePreviousLayoutBlock) {
SelectionInDOMTree::Builder()
.Collapse(Position(block_element1, 0))
.Build());
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(block1->ShouldPaintCursorCaret());
EXPECT_EQ(block1, CaretLayoutBlock());
EXPECT_FALSE(block2->ShouldPaintCursorCaret());
@@ -279,7 +289,8 @@ TEST_P(CaretDisplayItemClientTest, UpdatePreviousLayoutBlock) {
SelectionInDOMTree::Builder()
.Collapse(Position(block_element2, 0))
.Build());
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(block2->ShouldPaintCursorCaret());
EXPECT_EQ(block2, CaretLayoutBlock());
EXPECT_FALSE(block1->ShouldPaintCursorCaret());
@@ -298,7 +309,8 @@ TEST_P(CaretDisplayItemClientTest, UpdatePreviousLayoutBlock) {
UpdateAllLifecyclePhasesForCaretTest();
// Remove selection.
Selection().SetSelectionAndEndTyping(SelectionInDOMTree());
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
EXPECT_EQ(block1, PreviousCaretLayoutBlock());
}
@@ -326,7 +338,8 @@ TEST_P(CaretDisplayItemClientTest, CaretHideMoveAndShow) {
Selection().SetCaretVisible(true);
EXPECT_TRUE(GetCaretDisplayItemClient().IsValid());
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_FALSE(GetCaretDisplayItemClient().IsValid());
UpdateAllLifecyclePhasesForCaretTest();
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/apply_block_element_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/apply_block_element_command.cc
index 9f4a15e0eda..81a99ce7a41 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/apply_block_element_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/apply_block_element_command.cc
@@ -107,7 +107,7 @@ void ApplyBlockElementCommand::DoApply(EditingState* editing_state) {
if (editing_state->IsAborted())
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
DCHECK_EQ(start_scope, end_scope);
DCHECK_GE(start_index, 0);
@@ -211,7 +211,7 @@ void ApplyBlockElementCommand::FormatSelection(
!end_of_next_paragraph.IsConnected())
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
end_of_current_paragraph = CreateVisiblePosition(end_of_next_paragraph);
}
}
@@ -372,7 +372,7 @@ ApplyBlockElementCommand::EndOfNextParagrahSplittingTextNodesIfNeeded(
// pointing at this same text node, endOfNextParagraph will be shifted by one
// paragraph. Avoid this by splitting "\n"
SplitTextNode(end_of_next_paragraph_text, 1);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
Text* const previous_text =
DynamicTo<Text>(end_of_next_paragraph_text->previousSibling());
if (end_of_next_paragraph_text == start.ComputeContainerNode() &&
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/apply_block_element_command_test.cc b/chromium/third_party/blink/renderer/core/editing/commands/apply_block_element_command_test.cc
index 0630b0654e5..0e5736dcc45 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/apply_block_element_command_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/apply_block_element_command_test.cc
@@ -36,7 +36,7 @@ TEST_F(ApplyBlockElementCommandTest, selectionCrossingOverBody) {
GetDocument().body()->setContentEditable("false", ASSERT_NO_EXCEPTION);
GetDocument().setDesignMode("on");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Selection().SetSelection(
SelectionInDOMTree::Builder()
.SetBaseAndExtent(
@@ -52,7 +52,7 @@ TEST_F(ApplyBlockElementCommandTest, selectionCrossingOverBody) {
EXPECT_EQ(
"<body contenteditable=\"false\">\n"
"<pre><var id=\"va\" class=\"CLASS13\">\nC\n</var></pre><input></body>",
- GetDocument().documentElement()->InnerHTMLAsString());
+ GetDocument().documentElement()->innerHTML());
}
// This is a regression test for https://crbug.com/660801
@@ -77,7 +77,7 @@ TEST_F(ApplyBlockElementCommandTest, visibilityChangeDuringCommand) {
EXPECT_EQ(
"<head><style>li:first-child { visibility:visible; }</style></head>"
"<body><ul style=\"visibility:hidden\"><ul></ul><li>xyz</li></ul></body>",
- GetDocument().documentElement()->InnerHTMLAsString());
+ GetDocument().documentElement()->innerHTML());
}
// This is a regression test for https://crbug.com/712510
@@ -109,7 +109,7 @@ TEST_F(ApplyBlockElementCommandTest, IndentHeadingIntoBlockquote) {
"<h6><button></button></h6><br>"
"<object></object>"
"</div>",
- GetDocument().body()->InnerHTMLAsString());
+ GetDocument().body()->innerHTML());
}
// This is a regression test for https://crbug.com/806525
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 8367b7803a7..cd6d78a27bc 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
@@ -180,7 +180,7 @@ void ApplyStyleCommand::UpdateStartEnd(const EphemeralRange& range) {
if (!use_ending_selection_ &&
(range.StartPosition() != start_ || range.EndPosition() != end_))
use_ending_selection_ = true;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
const bool was_base_first =
StartingSelection().IsBaseFirst() || !SelectionIsDirectional();
SelectionInDOMTree::Builder builder;
@@ -216,7 +216,8 @@ void ApplyStyleCommand::DoApply(EditingState* editing_state) {
switch (property_level_) {
case kPropertyDefault: {
// Apply the block-centric properties of the style.
- EditingStyle* block_style = style_->ExtractAndRemoveBlockProperties();
+ EditingStyle* block_style = style_->ExtractAndRemoveBlockProperties(
+ GetDocument().ToExecutionContext());
if (!block_style->IsEmpty()) {
ApplyBlockStyle(block_style, editing_state);
if (editing_state->IsAborted())
@@ -250,7 +251,7 @@ void ApplyStyleCommand::ApplyBlockStyle(EditingStyle* style,
// update document layout once before removing styles
// so that we avoid the expense of updating before each and every call
// to check a computed style
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// get positions we want to use for applying style
Position start = StartPosition();
@@ -312,7 +313,7 @@ void ApplyStyleCommand::ApplyBlockStyle(EditingStyle* style,
if (new_block) {
block = new_block;
if (paragraph_start.IsOrphan()) {
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
paragraph_start = CreateVisiblePosition(
Position::FirstPositionInNode(*new_block));
}
@@ -330,7 +331,7 @@ void ApplyStyleCommand::ApplyBlockStyle(EditingStyle* style,
}
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// Make the VisiblePositions valid again after style changes.
// TODO(editing-dev): We shouldn't store VisiblePositions and inspect
@@ -355,7 +356,7 @@ void ApplyStyleCommand::ApplyBlockStyle(EditingStyle* style,
// Update style and layout again, since added or removed styles could have
// affected the layout. We need clean layout in order to compute
// plain-text ranges below.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
EphemeralRange start_ephemeral_range =
PlainTextRange(start_index)
@@ -698,7 +699,7 @@ void ApplyStyleCommand::ApplyInlineStyle(EditingStyle* style,
// update document layout once before removing styles
// so that we avoid the expense of updating before each and every call
// to check a computed style
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// adjust to the positions we want to use for applying style
Position start = StartPosition();
@@ -830,7 +831,7 @@ void ApplyStyleCommand::ApplyInlineStyle(EditingStyle* style,
// update document layout once before running the rest of the function
// so that we avoid the expense of updating before each and every call
// to check a computed style
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
EditingStyle* style_to_apply = style;
if (has_text_direction) {
@@ -868,7 +869,7 @@ void ApplyStyleCommand::ApplyInlineStyle(EditingStyle* style,
}
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
FixRangeAndApplyInlineStyle(style_to_apply, start, end, editing_state);
if (editing_state->IsAborted())
return;
@@ -985,7 +986,7 @@ void ApplyStyleCommand::ApplyInlineStyleToNodeRange(
if (remove_only_)
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
HeapVector<InlineRunToApplyStyle> runs;
Node* node = start_node;
@@ -1060,7 +1061,7 @@ void ApplyStyleCommand::ApplyInlineStyleToNodeRange(
}
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
for (auto& run : runs) {
if (run.position_for_style_computation.IsNotNull())
@@ -1442,7 +1443,7 @@ void ApplyStyleCommand::RemoveInlineStyle(EditingStyle* style,
// TODO(editing-dev): Use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
Position push_down_start = MostForwardCaretPosition(start);
// If the pushDownStart is at the end of a text node, then this node is not
@@ -1460,7 +1461,7 @@ void ApplyStyleCommand::RemoveInlineStyle(EditingStyle* style,
// TODO(editing-dev): Use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
Position push_down_end = MostBackwardCaretPosition(end);
// If pushDownEnd is at the start of a text node, then this node is not fully
@@ -1563,7 +1564,7 @@ bool ApplyStyleCommand::ElementFullySelected(const HTMLElement& element,
const Position& end) const {
// The tree may have changed and Position::upstream() relies on an up-to-date
// layout.
- element.GetDocument().UpdateStyleAndLayout();
+ element.GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
return ComparePositions(FirstPositionInOrBeforeNode(element), start) >= 0 &&
ComparePositions(
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/apply_style_command_test.cc b/chromium/third_party/blink/renderer/core/editing/commands/apply_style_command_test.cc
index 8cc843910dd..7732a825793 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/apply_style_command_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/apply_style_command_test.cc
@@ -67,9 +67,9 @@ TEST_F(ApplyStyleCommandTest, JustifyRightDetachesDestination) {
"<button></button>"
"</ruby");
Element* body = GetDocument().body();
- // The bug does't reproduce with a contenteditable <div> as container.
+ // The bug doesn't reproduce with a contenteditable <div> as container.
body->setAttribute(html_names::kContenteditableAttr, "true");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Selection().SelectAll();
auto* style =
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 849508fd7b0..1675649b6d8 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
@@ -151,7 +151,7 @@ void BreakBlockquoteCommand::DoApply(EditingState* editing_state) {
if (editing_state->IsAborted())
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// If we're inserting the break at the end of the quoted content, we don't
// need to break the quote.
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc b/chromium/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
index c5e7c916b89..e697b04265a 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
@@ -82,7 +82,7 @@ bool ClipboardCommands::CanWriteClipboard(LocalFrame& frame,
bool ClipboardCommands::CanSmartReplaceInClipboard(LocalFrame& frame) {
return frame.GetEditor().SmartInsertDeleteEnabled() &&
- SystemClipboard::GetInstance().CanSmartReplace();
+ frame.GetSystemClipboard()->CanSmartReplace();
}
Element* ClipboardCommands::FindEventTargetForClipboardEvent(
@@ -110,19 +110,19 @@ bool ClipboardCommands::DispatchClipboardEvent(LocalFrame& frame,
if (!target)
return true;
- DataTransfer* const data_transfer =
- DataTransfer::Create(DataTransfer::kCopyAndPaste, policy,
- policy == DataTransferAccessPolicy::kWritable
- ? DataObject::Create()
- : DataObject::CreateFromClipboard(paste_mode));
+ SystemClipboard* system_clipboard = frame.GetSystemClipboard();
+ DataTransfer* const data_transfer = DataTransfer::Create(
+ DataTransfer::kCopyAndPaste, policy,
+ policy == DataTransferAccessPolicy::kWritable
+ ? DataObject::Create()
+ : DataObject::CreateFromClipboard(system_clipboard, paste_mode));
Event* const evt = ClipboardEvent::Create(event_type, data_transfer);
target->DispatchEvent(*evt);
const bool no_default_processing = evt->defaultPrevented();
if (no_default_processing && policy == DataTransferAccessPolicy::kWritable) {
- SystemClipboard::GetInstance().WriteDataObject(
- data_transfer->GetDataObject());
- SystemClipboard::GetInstance().CommitWrite();
+ frame.GetSystemClipboard()->WriteDataObject(data_transfer->GetDataObject());
+ frame.GetSystemClipboard()->CommitWrite();
}
// Invalidate clipboard here for security.
@@ -135,7 +135,7 @@ bool ClipboardCommands::DispatchCopyOrCutEvent(LocalFrame& frame,
const AtomicString& event_type) {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (IsInPasswordField(
frame.Selection().ComputeVisibleSelectionInDOMTree().Start()))
return true;
@@ -204,9 +204,9 @@ void ClipboardCommands::WriteSelectionToClipboard(LocalFrame& frame) {
const KURL& url = frame.GetDocument()->Url();
const String html = frame.Selection().SelectedHTMLForClipboard();
const String plain_text = frame.SelectedTextForClipboard();
- SystemClipboard::GetInstance().WriteHTML(html, url, plain_text,
- GetSmartReplaceOption(frame));
- SystemClipboard::GetInstance().CommitWrite();
+ frame.GetSystemClipboard()->WriteHTML(html, url, plain_text,
+ GetSmartReplaceOption(frame));
+ frame.GetSystemClipboard()->CommitWrite();
}
bool ClipboardCommands::PasteSupported(LocalFrame* frame) {
@@ -235,12 +235,20 @@ bool ClipboardCommands::ExecuteCopy(LocalFrame& frame,
// needs to be audited. See http://crbug.com/590369 for more details.
// A 'copy' event handler might have dirtied the layout so we need to update
// before we obtain the selection.
- document->UpdateStyleAndLayout();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (HTMLImageElement* image_element =
ImageElementFromImageDocument(document)) {
- WriteImageNodeToClipboard(*image_element, document->title());
- return true;
+ // In an image document, normally there isn't anything to select, and we
+ // only want to copy the image itself.
+ if (frame.Selection().ComputeVisibleSelectionInDOMTree().IsNone()) {
+ WriteImageNodeToClipboard(*frame.GetSystemClipboard(), *image_element,
+ document->title());
+ return true;
+ }
+
+ // Scripts may insert other contents into an image document. Falls through
+ // when they are selected.
}
// Since copy is a read-only operation it succeeds anytime a selection
@@ -252,9 +260,9 @@ bool ClipboardCommands::ExecuteCopy(LocalFrame& frame,
if (EnclosingTextControl(
frame.Selection().ComputeVisibleSelectionInDOMTree().Start())) {
- SystemClipboard::GetInstance().WritePlainText(
- frame.SelectedTextForClipboard(), GetSmartReplaceOption(frame));
- SystemClipboard::GetInstance().CommitWrite();
+ frame.GetSystemClipboard()->WritePlainText(frame.SelectedTextForClipboard(),
+ GetSmartReplaceOption(frame));
+ frame.GetSystemClipboard()->CommitWrite();
return true;
}
WriteSelectionToClipboard(frame);
@@ -292,7 +300,7 @@ bool ClipboardCommands::ExecuteCut(LocalFrame& frame,
// needs to be audited. See http://crbug.com/590369 for more details.
// A 'cut' event handler might have dirtied the layout so we need to update
// before we obtain the selection.
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (source == EditorCommandSource::kMenuOrKeyBinding &&
!frame.Selection().SelectionHasFocus())
@@ -303,9 +311,9 @@ bool ClipboardCommands::ExecuteCut(LocalFrame& frame,
if (EnclosingTextControl(
frame.Selection().ComputeVisibleSelectionInDOMTree().Start())) {
const String plain_text = frame.SelectedTextForClipboard();
- SystemClipboard::GetInstance().WritePlainText(plain_text,
- GetSmartReplaceOption(frame));
- SystemClipboard::GetInstance().CommitWrite();
+ frame.GetSystemClipboard()->WritePlainText(plain_text,
+ GetSmartReplaceOption(frame));
+ frame.GetSystemClipboard()->CommitWrite();
} else {
WriteSelectionToClipboard(frame);
}
@@ -346,26 +354,35 @@ void ClipboardCommands::PasteAsPlainTextFromClipboard(
if (!target)
return;
target->DispatchEvent(*TextEvent::CreateForPlainTextPaste(
- frame.DomWindow(), SystemClipboard::GetInstance().ReadPlainText(),
+ frame.DomWindow(), frame.GetSystemClipboard()->ReadPlainText(),
CanSmartReplaceInClipboard(frame)));
}
ClipboardCommands::FragmentAndPlainText
ClipboardCommands::GetFragmentFromClipboard(LocalFrame& frame) {
DocumentFragment* fragment = nullptr;
- if (SystemClipboard::GetInstance().IsHTMLAvailable()) {
+ if (frame.GetSystemClipboard()->IsHTMLAvailable()) {
unsigned fragment_start = 0;
unsigned fragment_end = 0;
KURL url;
- const String markup = SystemClipboard::GetInstance().ReadHTML(
- url, fragment_start, fragment_end);
+ const String markup =
+ frame.GetSystemClipboard()->ReadHTML(url, fragment_start, fragment_end);
fragment = CreateSanitizedFragmentFromMarkupWithContext(
*frame.GetDocument(), markup, fragment_start, fragment_end, url);
}
if (fragment)
return std::make_pair(fragment, false);
- const String text = SystemClipboard::GetInstance().ReadPlainText();
+ if (const String markup = frame.GetSystemClipboard()->ReadImageAsImageMarkup(
+ mojom::blink::ClipboardBuffer::kStandard)) {
+ fragment = CreateFragmentFromMarkup(*frame.GetDocument(), markup,
+ /* base_url */ "",
+ kDisallowScriptingAndPluginContent);
+ DCHECK(fragment);
+ return std::make_pair(fragment, false);
+ }
+
+ const String text = frame.GetSystemClipboard()->ReadPlainText();
if (text.IsEmpty())
return std::make_pair(fragment, false);
@@ -373,7 +390,7 @@ ClipboardCommands::GetFragmentFromClipboard(LocalFrame& frame) {
// needs to be audited. See http://crbug.com/590369 for more details.
// |SelectedRange| requires clean layout for visible selection
// normalization.
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
fragment = CreateFragmentFromText(frame.GetEditor().SelectedRange(), text);
return std::make_pair(fragment, true);
}
@@ -402,7 +419,7 @@ void ClipboardCommands::Paste(LocalFrame& frame, EditorCommandSource source) {
// needs to be audited. See http://crbug.com/590369 for more details.
// A 'paste' event handler might have dirtied the layout so we need to update
// before we obtain the selection.
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (source == EditorCommandSource::kMenuOrKeyBinding &&
!frame.Selection().SelectionHasFocus())
@@ -418,7 +435,8 @@ void ClipboardCommands::Paste(LocalFrame& frame, EditorCommandSource source) {
if (source == EditorCommandSource::kMenuOrKeyBinding) {
DataTransfer* data_transfer = DataTransfer::Create(
DataTransfer::kCopyAndPaste, DataTransferAccessPolicy::kReadable,
- DataObject::CreateFromClipboard(paste_mode));
+ DataObject::CreateFromClipboard(frame.GetSystemClipboard(),
+ paste_mode));
if (DispatchBeforeInputDataTransfer(
FindEventTargetForClipboardEvent(frame, source),
@@ -453,11 +471,10 @@ bool ClipboardCommands::ExecutePasteGlobalSelection(LocalFrame& frame,
return false;
DCHECK_EQ(source, EditorCommandSource::kMenuOrKeyBinding);
- const bool old_selection_mode =
- SystemClipboard::GetInstance().IsSelectionMode();
- SystemClipboard::GetInstance().SetSelectionMode(true);
+ const bool old_selection_mode = frame.GetSystemClipboard()->IsSelectionMode();
+ frame.GetSystemClipboard()->SetSelectionMode(true);
Paste(frame, source);
- SystemClipboard::GetInstance().SetSelectionMode(old_selection_mode);
+ frame.GetSystemClipboard()->SetSelectionMode(old_selection_mode);
return true;
}
@@ -474,7 +491,7 @@ bool ClipboardCommands::ExecutePasteAndMatchStyle(LocalFrame& frame,
// needs to be audited. See http://crbug.com/590369 for more details.
// A 'paste' event handler might have dirtied the layout so we need to update
// before we obtain the selection.
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (source == EditorCommandSource::kMenuOrKeyBinding &&
!frame.Selection().SelectionHasFocus())
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 a826be457eb..a665fe43804 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
@@ -104,7 +104,7 @@ VisibleSelection CompositeEditCommand::EndingVisibleSelection() const {
// TODO(editing-dev): The use of
// |Document::UpdateStyleAndLayout()|
// needs to be audited. See http://crbug.com/590369 for more details.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
return CreateVisibleSelection(ending_selection_);
}
@@ -144,7 +144,7 @@ bool CompositeEditCommand::Apply() {
// operations, like RemoveNodeCommand, don't require a layout because the high
// level operations that use them perform one if one is necessary (like for
// the creation of VisiblePositions).
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
LocalFrame* frame = GetDocument().GetFrame();
DCHECK(frame);
@@ -289,7 +289,7 @@ void CompositeEditCommand::InsertNodeBefore(
ABORT_EDITING_COMMAND_IF(!ref_child->parentNode());
// TODO(editing-dev): Use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
ABORT_EDITING_COMMAND_IF(!HasEditableStyle(*ref_child->parentNode()) &&
ref_child->parentNode()->InActiveDocument());
ApplyCommandToComposite(
@@ -319,7 +319,7 @@ void CompositeEditCommand::InsertNodeAfter(Node* insert_child,
void CompositeEditCommand::InsertNodeAt(Node* insert_child,
const Position& editing_position,
EditingState* editing_state) {
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
ABORT_EDITING_COMMAND_IF(!IsEditablePosition(editing_position));
// For editing positions like [table, 0], insert before the table,
// likewise for replaced elements, brs, etc.
@@ -615,7 +615,7 @@ Position CompositeEditCommand::PositionOutsideTabSpan(const Position& pos) {
// TODO(editing-dev): Hoist this UpdateStyleAndLayout
// to the callers. See crbug.com/590369 for details.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (pos.OffsetInContainerNode() <= CaretMinOffset(pos.ComputeContainerNode()))
return Position::InParentBeforeNode(*tab_span);
@@ -681,7 +681,7 @@ void CompositeEditCommand::SetNodeAttribute(Element* element,
bool CompositeEditCommand::CanRebalance(const Position& position) const {
// TODO(editing-dev): Use of UpdateStyleAndLayout()
// needs to be audited. See http://crbug.com/590369 for more details.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
auto* text_node = DynamicTo<Text>(position.ComputeContainerNode());
if (!position.IsOffsetInAnchor() || !text_node ||
@@ -740,7 +740,7 @@ void CompositeEditCommand::RebalanceWhitespaceOnTextSubstring(Text* text_node,
if (!length)
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
VisiblePosition visible_upstream_pos =
CreateVisiblePosition(Position(text_node, upstream));
VisiblePosition visible_downstream_pos =
@@ -788,14 +788,14 @@ void CompositeEditCommand::PrepareWhitespaceAtPositionForSplit(
Position upstream_pos = MostBackwardCaretPosition(position);
DeleteInsignificantText(upstream_pos, MostForwardCaretPosition(position));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
position = MostForwardCaretPosition(upstream_pos);
VisiblePosition visible_pos = CreateVisiblePosition(position);
VisiblePosition previous_visible_pos = PreviousPositionOf(visible_pos);
ReplaceCollapsibleWhitespaceWithNonBreakingSpaceIfNeeded(
previous_visible_pos);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
ReplaceCollapsibleWhitespaceWithNonBreakingSpaceIfNeeded(
CreateVisiblePosition(position));
}
@@ -829,7 +829,7 @@ void CompositeEditCommand::DeleteInsignificantText(Text* text_node,
if (!text_node || start >= end)
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
LayoutText* text_layout_object = text_node->GetLayoutObject();
if (!text_layout_object)
@@ -951,7 +951,7 @@ HTMLBRElement* CompositeEditCommand::AppendBlockPlaceholder(
if (!container)
return nullptr;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// Should assert isLayoutBlockFlow || isInlineFlow when deletion improves. See
// 4244964.
@@ -987,7 +987,7 @@ HTMLBRElement* CompositeEditCommand::AddBlockPlaceholderIfNeeded(
if (!container)
return nullptr;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
auto* block = DynamicTo<LayoutBlockFlow>(container->GetLayoutObject());
if (!block)
@@ -1102,7 +1102,7 @@ HTMLElement* CompositeEditCommand::MoveParagraphContentsToNewBlockIfNecessary(
// Inserting default paragraph element can change visible position. We
// should update visible positions before use them.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
const VisiblePosition& destination =
VisiblePosition::FirstPositionInNode(*new_block);
if (destination.IsNull()) {
@@ -1258,7 +1258,7 @@ void CompositeEditCommand::CleanupAfterDeletion(EditingState* editing_state) {
void CompositeEditCommand::CleanupAfterDeletion(EditingState* editing_state,
VisiblePosition destination) {
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
VisiblePosition caret_after_delete = EndingVisibleSelection().VisibleStart();
Node* destination_node = destination.DeepEquivalent().AnchorNode();
@@ -1360,7 +1360,7 @@ void CompositeEditCommand::MoveParagraphWithClones(
if (editing_state->IsAborted())
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// Add a br if pruning an empty block level element caused a collapse. For
// example:
@@ -1518,7 +1518,8 @@ void CompositeEditCommand::MoveParagraphs(
start_of_paragraph_to_move.DeepEquivalent());
style_in_empty_paragraph->MergeTypingStyle(&GetDocument());
// The moved paragraph should assume the block style of the destination.
- style_in_empty_paragraph->RemoveBlockProperties();
+ style_in_empty_paragraph->RemoveBlockProperties(
+ GetDocument().ToExecutionContext());
}
// FIXME (5098931): We should add a new insert action
@@ -1541,7 +1542,7 @@ void CompositeEditCommand::MoveParagraphs(
return;
DCHECK(destination.DeepEquivalent().IsConnected()) << destination;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// Add a br if pruning an empty block level element caused a collapse. For
// example:
@@ -1569,7 +1570,7 @@ void CompositeEditCommand::MoveParagraphs(
}
// TextIterator::rangeLength requires clean layout.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
destination_index = TextIterator::RangeLength(
Position::FirstPositionInNode(*GetDocument().documentElement()),
@@ -1599,7 +1600,7 @@ void CompositeEditCommand::MoveParagraphs(
return;
ABORT_EDITING_COMMAND_IF(!EndingSelection().IsValidFor(GetDocument()));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// If the selection is in an empty paragraph, restore styles from the old
// empty paragraph to the new empty paragraph.
@@ -1620,7 +1621,7 @@ void CompositeEditCommand::MoveParagraphs(
return;
// We need clean layout in order to compute plain-text ranges below.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// Fragment creation (using createMarkup) incorrectly uses regular spaces
// instead of nbsps for some spaces that were rendered (11475), which causes
@@ -1770,7 +1771,7 @@ bool CompositeEditCommand::BreakOutOfEmptyMailBlockquotedParagraph(
if (!EndingSelection().IsCaret())
return false;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
VisiblePosition caret = EndingVisibleSelection().VisibleStart();
auto* highest_blockquote = To<HTMLQuoteElement>(HighestEnclosingNodeOfType(
@@ -1796,7 +1797,7 @@ bool CompositeEditCommand::BreakOutOfEmptyMailBlockquotedParagraph(
if (editing_state->IsAborted())
return false;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
VisiblePosition at_br = VisiblePosition::BeforeNode(*br);
// If the br we inserted collapsed, for example:
@@ -1807,7 +1808,7 @@ bool CompositeEditCommand::BreakOutOfEmptyMailBlockquotedParagraph(
editing_state);
if (editing_state->IsAborted())
return false;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
}
SetEndingSelection(SelectionForUndoStep::From(
SelectionInDOMTree::Builder()
@@ -1855,7 +1856,7 @@ Position CompositeEditCommand::PositionAvoidingSpecialElementBoundary(
if (original.IsNull())
return original;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
VisiblePosition visible_pos = CreateVisiblePosition(original);
Element* enclosing_anchor = EnclosingAnchorElement(original);
Position result = original;
@@ -1885,7 +1886,7 @@ Position CompositeEditCommand::PositionAvoidingSpecialElementBoundary(
return original;
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// Don't insert outside an anchor if doing so would skip over a line
// break. It would probably be safe to move the line break so that we
@@ -1947,7 +1948,7 @@ Node* CompositeEditCommand::SplitTreeToNode(Node* start,
if (!parent_element)
break;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// Do not split a node when doing so introduces an empty node.
VisiblePosition position_in_parent =
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/composite_edit_command_test.cc b/chromium/third_party/blink/renderer/core/editing/commands/composite_edit_command_test.cc
index 3cf0ee68df3..760a475e3ae 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/composite_edit_command_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/composite_edit_command_test.cc
@@ -77,7 +77,7 @@ TEST_F(CompositeEditCommandTest, insertNodeBefore) {
EditingState editing_state;
sample.InsertNodeBefore(insert_child, ref_child, &editing_state);
EXPECT_FALSE(editing_state.IsAborted());
- EXPECT_EQ("foo<b></b>", div->InnerHTMLAsString());
+ EXPECT_EQ("foo<b></b>", div->innerHTML());
}
TEST_F(CompositeEditCommandTest, insertNodeBeforeInUneditable) {
@@ -102,7 +102,7 @@ TEST_F(CompositeEditCommandTest, insertNodeBeforeDisconnectedNode) {
EditingState editing_state;
sample.InsertNodeBefore(insert_child, ref_child, &editing_state);
EXPECT_FALSE(editing_state.IsAborted());
- EXPECT_EQ("<b></b>", div->InnerHTMLAsString())
+ EXPECT_EQ("<b></b>", div->innerHTML())
<< "InsertNodeBeforeCommand does nothing for disconnected node";
}
@@ -117,7 +117,7 @@ TEST_F(CompositeEditCommandTest, insertNodeBeforeWithDirtyLayoutTree) {
EditingState editing_state;
sample.InsertNodeBefore(insert_child, ref_child, &editing_state);
EXPECT_FALSE(editing_state.IsAborted());
- EXPECT_EQ("foo<b></b>", div->InnerHTMLAsString());
+ EXPECT_EQ("foo<b></b>", div->innerHTML());
}
TEST_F(CompositeEditCommandTest,
@@ -129,7 +129,7 @@ TEST_F(CompositeEditCommandTest,
Element* body = GetDocument().body();
Node* text = body->lastChild();
body->setAttribute(html_names::kContenteditableAttr, "true");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EditingState editing_state;
sample.MoveParagraphContentsToNewBlockIfNecessary(Position(text, 0),
@@ -139,7 +139,7 @@ TEST_F(CompositeEditCommandTest,
"<div><br></div>"
"<style>div{-webkit-user-modify:read-only;user-select:none;}</style>"
"foo",
- body->InnerHTMLAsString());
+ body->innerHTML());
}
TEST_F(CompositeEditCommandTest, InsertNodeOnDisconnectedParent) {
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 9425c9c546e..44c3eff34e5 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
@@ -25,6 +25,7 @@
#include "third_party/blink/renderer/core/editing/commands/delete_selection_command.h"
+#include "build/build_config.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/dom/node_traversal.h"
@@ -61,7 +62,7 @@ static bool IsTableRowEmpty(Node* row) {
if (!IsA<HTMLTableRowElement>(row))
return false;
- row->GetDocument().UpdateStyleAndLayout();
+ row->GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
for (Node* child = row->firstChild(); child; child = child->nextSibling()) {
if (IsTableCell(child) && !IsTableCellEmpty(child))
return false;
@@ -89,10 +90,10 @@ DeleteSelectionCommand::DeleteSelectionCommand(
reference_move_position_(reference_move_position) {}
DeleteSelectionCommand::DeleteSelectionCommand(
- const VisibleSelection& selection,
+ const SelectionForUndoStep& selection,
const DeleteSelectionOptions& options,
InputEvent::InputType input_type)
- : CompositeEditCommand(*selection.Start().GetDocument()),
+ : CompositeEditCommand(*selection.Base().GetDocument()),
options_(options),
has_selection_to_delete_(true),
merge_blocks_after_delete_(options.IsMergeBlocksAfterDelete()),
@@ -137,9 +138,10 @@ void DeleteSelectionCommand::InitializeStartEnd(Position& start,
break;
if (CreateVisiblePosition(start).DeepEquivalent() !=
- selection_to_delete_.VisibleStart().DeepEquivalent() ||
+ CreateVisiblePosition(selection_to_delete_.Start())
+ .DeepEquivalent() ||
CreateVisiblePosition(end).DeepEquivalent() !=
- selection_to_delete_.VisibleEnd().DeepEquivalent())
+ CreateVisiblePosition(selection_to_delete_.End()).DeepEquivalent())
break;
// If we're going to expand to include the startSpecialContainer, it must be
@@ -224,6 +226,15 @@ static Position TrailingWhitespacePosition(const Position& position,
return Position();
}
+// Workaround: GCC fails to resolve overloaded template functions, passed as
+// parameters of EnclosingNodeType. But it works wrapping that in a utility
+// function.
+#if defined(COMPILER_GCC)
+static bool IsHTMLTableRowElement(const blink::Node* node) {
+ return IsA<HTMLTableRowElement>(node);
+}
+#endif
+
void DeleteSelectionCommand::InitializePositionData(
EditingState* editing_state) {
DCHECK(!GetDocument().NeedsLayoutTreeUpdate());
@@ -252,10 +263,18 @@ void DeleteSelectionCommand::InitializePositionData(
start_root_ = RootEditableElementOf(start);
end_root_ = RootEditableElementOf(end);
+#if defined(COMPILER_GCC)
+ // Workaround. See declaration of IsHTMLTableRowElement
+ start_table_row_ = To<HTMLTableRowElement>(
+ EnclosingNodeOfType(start, &IsHTMLTableRowElement));
+ end_table_row_ =
+ To<HTMLTableRowElement>(EnclosingNodeOfType(end, &IsHTMLTableRowElement));
+#else
start_table_row_ = To<HTMLTableRowElement>(
EnclosingNodeOfType(start, &IsA<HTMLTableRowElement>));
end_table_row_ = To<HTMLTableRowElement>(
EnclosingNodeOfType(end, &IsA<HTMLTableRowElement>));
+#endif
// Don't move content out of a table cell.
// If the cell is non-editable, enclosingNodeOfType won't return it by
@@ -442,7 +461,7 @@ bool DeleteSelectionCommand::HandleSpecialCaseBRDelete(
// We detect the case where the start is an empty line consisting of BR not
// wrapped in a block element.
if (upstream_start_is_br && downstream_start_is_br) {
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (!(IsStartOfBlock(
VisiblePosition::BeforeNode(*node_after_upstream_start)) &&
IsEndOfBlock(
@@ -497,7 +516,7 @@ void DeleteSelectionCommand::RemoveNode(
return;
// Make sure empty cell has some height, if a placeholder can be inserted.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
LayoutObject* r = node->GetLayoutObject();
if (r && r->IsTableCell() && ToLayoutBox(r)->ContentHeight() <= 0) {
Position first_editable_position = FirstEditablePositionInNode(node);
@@ -507,7 +526,7 @@ void DeleteSelectionCommand::RemoveNode(
return;
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (node == start_block_) {
VisiblePosition previous = PreviousPositionOf(
VisiblePosition::FirstPositionInNode(*start_block_.Get()));
@@ -561,7 +580,8 @@ void DeleteSelectionCommand::DeleteTextFromNode(Text* node,
void DeleteSelectionCommand::
MakeStylingElementsDirectChildrenOfEditableRootToPreventStyleLoss(
EditingState* editing_state) {
- Range* range = CreateRange(selection_to_delete_.ToNormalizedEphemeralRange());
+ Range* range = CreateRange(CreateVisibleSelection(selection_to_delete_)
+ .ToNormalizedEphemeralRange());
Node* node = range->FirstNode();
while (node && node != range->PastLastNode()) {
Node* next_node = NodeTraversal::Next(*node);
@@ -605,12 +625,13 @@ void DeleteSelectionCommand::HandleGeneralDelete(EditingState* editing_state) {
return;
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
auto* text = DynamicTo<Text>(start_node);
if (start_offset >= CaretMaxOffset(start_node) && text) {
- if (text->length() > (unsigned)CaretMaxOffset(start_node))
+ if (text->length() > static_cast<unsigned>(CaretMaxOffset(start_node))) {
DeleteTextFromNode(text, CaretMaxOffset(start_node),
text->length() - CaretMaxOffset(start_node));
+ }
}
if (start_offset >= EditingStrategy::LastOffsetForEditing(start_node)) {
@@ -638,7 +659,7 @@ void DeleteSelectionCommand::HandleGeneralDelete(EditingState* editing_state) {
ending_position_ = upstream_start_;
}
// We should update layout to associate |start_node| to layout object.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
}
// The selection to delete is all in one node.
@@ -686,7 +707,7 @@ void DeleteSelectionCommand::HandleGeneralDelete(EditingState* editing_state) {
return;
node = next_node;
} else {
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
Node& n = NodeTraversal::LastWithinOrSelf(*node);
if (downstream_end_.AnchorNode() == n &&
downstream_end_.ComputeEditingOffset() >= CaretMaxOffset(&n)) {
@@ -702,7 +723,7 @@ void DeleteSelectionCommand::HandleGeneralDelete(EditingState* editing_state) {
// TODO(editing-dev): Hoist UpdateStyleAndLayout
// to caller. See http://crbug.com/590369 for more details.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (downstream_end_.AnchorNode() != start_node &&
!upstream_start_.AnchorNode()->IsDescendantOf(
@@ -752,7 +773,7 @@ void DeleteSelectionCommand::HandleGeneralDelete(EditingState* editing_state) {
}
void DeleteSelectionCommand::FixupWhitespace() {
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (leading_whitespace_.IsNotNull() &&
!IsRenderedCharacter(leading_whitespace_)) {
if (auto* text_node = DynamicTo<Text>(leading_whitespace_.AnchorNode())) {
@@ -812,7 +833,7 @@ void DeleteSelectionCommand::MergeParagraphs(EditingState* editing_state) {
if (upstream_start_ == downstream_end_)
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
VisiblePosition start_of_paragraph_to_move =
CreateVisiblePosition(downstream_end_);
@@ -846,7 +867,7 @@ void DeleteSelectionCommand::MergeParagraphs(EditingState* editing_state) {
upstream_start_, editing_state);
if (editing_state->IsAborted())
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
merge_destination = CreateVisiblePosition(upstream_start_);
start_of_paragraph_to_move =
CreateVisiblePosition(relocatable_start.GetPosition());
@@ -973,7 +994,8 @@ void DeleteSelectionCommand::RemovePreviouslySelectedEmptyTableRows(
if (IsTableRowEmpty(end_table_row_.Get())) {
// Don't remove end_table_row_ if it's where we're putting the ending
// selection.
- if (!ending_position_.AnchorNode()->IsDescendantOf(
+ if (ending_position_.IsNull() ||
+ !ending_position_.AnchorNode()->IsDescendantOf(
end_table_row_.Get())) {
// FIXME: We probably shouldn't remove end_table_row_ unless it's
// fully selected, even if it is empty. We'll need to start
@@ -1020,7 +1042,7 @@ void DeleteSelectionCommand::CalculateTypingStyleAfterDelete() {
}
void DeleteSelectionCommand::ClearTransientState() {
- selection_to_delete_ = VisibleSelection();
+ selection_to_delete_ = SelectionForUndoStep();
upstream_start_ = Position();
downstream_start_ = Position();
upstream_end_ = Position();
@@ -1059,12 +1081,14 @@ void DeleteSelectionCommand::RemoveRedundantBlocks(
void DeleteSelectionCommand::DoApply(EditingState* editing_state) {
// If selection has not been set to a custom selection when the command was
// created, use the current ending selection.
- if (!has_selection_to_delete_)
- selection_to_delete_ = EndingVisibleSelection();
+ if (!has_selection_to_delete_) {
+ selection_to_delete_ =
+ SelectionForUndoStep::From(EndingVisibleSelection().AsSelection());
+ }
if (!selection_to_delete_.IsValidFor(GetDocument()) ||
!selection_to_delete_.IsRange() ||
- !selection_to_delete_.IsContentEditable()) {
+ !IsEditablePosition(selection_to_delete_.Base())) {
// editing/execCommand/delete-non-editable-range-crash.html reaches here.
return;
}
@@ -1074,7 +1098,7 @@ void DeleteSelectionCommand::DoApply(EditingState* editing_state) {
// save this to later make the selection with
TextAffinity affinity = selection_to_delete_.Affinity();
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
Position downstream_end =
MostForwardCaretPosition(selection_to_delete_.End());
@@ -1084,20 +1108,26 @@ void DeleteSelectionCommand::DoApply(EditingState* editing_state) {
(downstream_end.ComputeContainerNode()->IsTextNode() &&
downstream_end.ComputeContainerNode()->parentNode() ==
RootEditableElement(*downstream_end.ComputeContainerNode()));
+ VisiblePosition visible_start = CreateVisiblePosition(
+ selection_to_delete_.Start(),
+ selection_to_delete_.IsRange() ? TextAffinity::kDownstream : affinity);
+ VisiblePosition visible_end = CreateVisiblePosition(
+ selection_to_delete_.End(),
+ selection_to_delete_.IsRange() ? TextAffinity::kUpstream : affinity);
+
bool line_break_at_end_of_selection_to_delete =
- LineBreakExistsAtVisiblePosition(selection_to_delete_.VisibleEnd());
- need_placeholder_ = !root_will_stay_open_without_placeholder &&
- IsStartOfParagraph(selection_to_delete_.VisibleStart(),
- kCanCrossEditingBoundary) &&
- IsEndOfParagraph(selection_to_delete_.VisibleEnd(),
- kCanCrossEditingBoundary) &&
- !line_break_at_end_of_selection_to_delete;
+ LineBreakExistsAtVisiblePosition(visible_end);
+
+ need_placeholder_ =
+ !root_will_stay_open_without_placeholder &&
+ IsStartOfParagraph(visible_start, kCanCrossEditingBoundary) &&
+ IsEndOfParagraph(visible_end, kCanCrossEditingBoundary) &&
+ !line_break_at_end_of_selection_to_delete;
if (need_placeholder_) {
// Don't need a placeholder when deleting a selection that starts just
// before a table and ends inside it (we do need placeholders to hold
// open empty cells, but that's handled elsewhere).
- if (Element* table =
- TableElementJustAfter(selection_to_delete_.VisibleStart())) {
+ if (Element* table = TableElementJustAfter(visible_start)) {
if (selection_to_delete_.End().AnchorNode()->IsDescendantOf(table))
need_placeholder_ = false;
}
@@ -1124,7 +1154,7 @@ void DeleteSelectionCommand::DoApply(EditingState* editing_state) {
return;
if (br_result) {
CalculateTypingStyleAfterDelete();
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
SelectionInDOMTree::Builder builder;
builder.SetAffinity(affinity);
if (ending_position_.IsNotNull())
@@ -1138,7 +1168,7 @@ void DeleteSelectionCommand::DoApply(EditingState* editing_state) {
return;
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
HandleGeneralDelete(editing_state);
if (editing_state->IsAborted())
@@ -1155,7 +1185,7 @@ void DeleteSelectionCommand::DoApply(EditingState* editing_state) {
return;
if (!need_placeholder_ && root_will_stay_open_without_placeholder) {
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
VisiblePosition visual_ending = CreateVisiblePosition(ending_position_);
bool has_placeholder =
LineBreakExistsAtVisiblePosition(visual_ending) &&
@@ -1187,7 +1217,7 @@ void DeleteSelectionCommand::DoApply(EditingState* editing_state) {
CalculateTypingStyleAfterDelete();
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
SelectionInDOMTree::Builder builder;
builder.SetAffinity(affinity);
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 f9f3d3da710..66e8a82259d 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
@@ -43,7 +43,7 @@ class CORE_EXPORT DeleteSelectionCommand final : public CompositeEditCommand {
InputEvent::InputType input_type = InputEvent::InputType::kNone,
const Position& reference_move_position = Position());
DeleteSelectionCommand(
- const VisibleSelection&,
+ const SelectionForUndoStep&,
const DeleteSelectionOptions&,
InputEvent::InputType input_type = InputEvent::InputType::kNone);
@@ -85,7 +85,7 @@ class CORE_EXPORT DeleteSelectionCommand final : public CompositeEditCommand {
// This data is transient and should be cleared at the end of the doApply
// function.
- VisibleSelection selection_to_delete_;
+ SelectionForUndoStep selection_to_delete_;
Position upstream_start_;
Position downstream_start_;
Position upstream_end_;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/delete_selection_command_test.cc b/chromium/third_party/blink/renderer/core/editing/commands/delete_selection_command_test.cc
index 2ee3a40be4f..d5ad9c4c4d1 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/delete_selection_command_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/delete_selection_command_test.cc
@@ -56,7 +56,7 @@ TEST_F(DeleteSelectionCommandTest, deleteListFromTable) {
EXPECT_TRUE(command->Apply()) << "the delete command should have succeeded";
EXPECT_EQ("<div contenteditable=\"true\"><br></div>",
- GetDocument().body()->InnerHTMLAsString());
+ GetDocument().body()->innerHTML());
EXPECT_TRUE(frame->Selection().GetSelectionInDOMTree().IsCaret());
EXPECT_EQ(Position(div, 0), frame->Selection()
.ComputeVisibleSelectionInDOMTree()
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/document_exec_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/document_exec_command.cc
index bce2db4038c..0a859b99353 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/document_exec_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/document_exec_command.cc
@@ -39,6 +39,7 @@
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/html/forms/text_control_element.h"
#include "third_party/blink/renderer/core/inspector/console_message.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/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
@@ -81,9 +82,9 @@ bool Document::execCommand(const String& command_name,
String message =
"We don't execute document.execCommand() this time, because it is "
"called recursively.";
- AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning, message));
+ AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning, message));
return false;
}
base::AutoReset<bool> execute_scope(&is_running_exec_command_, true);
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/editing_command_test.cc b/chromium/third_party/blink/renderer/core/editing/commands/editing_command_test.cc
index 2016f475780..c2c2f90021c 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/editing_command_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/editing_command_test.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "base/stl_util.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/renderer/core/editing/commands/editing_command_type.h"
#include "third_party/blink/renderer/core/editing/commands/editor_command.h"
#include "third_party/blink/renderer/core/editing/commands/editor_command_names.h"
@@ -61,7 +62,7 @@ TEST_F(EditingCommandTest, CreateCommandFromStringCaseFolding) {
Editor& dummy_editor = GetDocument().GetFrame()->GetEditor();
for (const auto& entry : kCommandNameEntries) {
const EditorCommand lower_name_command =
- dummy_editor.CreateCommand(String(entry.name).DeprecatedLower());
+ dummy_editor.CreateCommand(String(entry.name).LowerASCII());
EXPECT_EQ(static_cast<int>(entry.type), lower_name_command.IdForHistogram())
<< entry.name;
const EditorCommand upper_name_command =
@@ -91,8 +92,8 @@ TEST_F(EditingCommandTest, EnabledVisibleSelection) {
SetSelectionOptions());
Element* div = GetDocument().QuerySelector("div");
GetDocument().SetFocusedElement(
- div,
- FocusParams(SelectionBehaviorOnFocus::kNone, kWebFocusTypeNone, nullptr));
+ div, FocusParams(SelectionBehaviorOnFocus::kNone,
+ mojom::blink::FocusType::kNone, nullptr));
EXPECT_TRUE(command.IsEnabled());
div->removeAttribute("contenteditable");
EXPECT_FALSE(command.IsEnabled());
@@ -108,8 +109,8 @@ TEST_F(EditingCommandTest, EnabledVisibleSelectionAndMark) {
SetSelectionOptions());
Element* div = GetDocument().QuerySelector("div");
GetDocument().SetFocusedElement(
- div,
- FocusParams(SelectionBehaviorOnFocus::kNone, kWebFocusTypeNone, nullptr));
+ div, FocusParams(SelectionBehaviorOnFocus::kNone,
+ mojom::blink::FocusType::kNone, nullptr));
EXPECT_FALSE(command.IsEnabled());
editor.SetMark();
EXPECT_TRUE(command.IsEnabled());
@@ -135,8 +136,8 @@ TEST_F(EditingCommandTest, EnabledInEditableTextOrCaretBrowsing) {
SetSelectionOptions());
Element* div = GetDocument().QuerySelector("div");
GetDocument().SetFocusedElement(
- div,
- FocusParams(SelectionBehaviorOnFocus::kNone, kWebFocusTypeNone, nullptr));
+ div, FocusParams(SelectionBehaviorOnFocus::kNone,
+ mojom::blink::FocusType::kNone, nullptr));
EXPECT_TRUE(command.IsEnabled());
div->removeAttribute("contenteditable");
EXPECT_FALSE(command.IsEnabled());
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 db361a8fa3d..e73728712a4 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
@@ -534,7 +534,7 @@ void TidyUpHTMLStructure(Document& document) {
// documentElement as rootEditableElement is problematic. So we move
// non-<html> root elements under <body>, and the <body> works as
// rootEditableElement.
- document.AddConsoleMessage(ConsoleMessage::Create(
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning,
"document.execCommand() doesn't work with an invalid HTML structure. It "
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/editing_state.cc b/chromium/third_party/blink/renderer/core/editing/commands/editing_state.cc
index 8c20b9f5a12..3b3d854c2af 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/editing_state.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/editing_state.cc
@@ -8,8 +8,6 @@ namespace blink {
EditingState::EditingState() = default;
-EditingState::~EditingState() = default;
-
void EditingState::Abort() {
DCHECK(!is_aborted_);
is_aborted_ = true;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/editing_state.h b/chromium/third_party/blink/renderer/core/editing/commands/editing_state.h
index f5b63acbfe8..2ae504fc33d 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/editing_state.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/editing_state.h
@@ -27,7 +27,6 @@ class CORE_EXPORT EditingState final {
public:
EditingState();
- ~EditingState();
void Abort();
bool IsAborted() const { return is_aborted_; }
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/editor_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/editor_command.cc
index 27d77a2af4b..96645898d7f 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/editor_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/editor_command.cc
@@ -195,7 +195,7 @@ StaticRangeVector* RangesFromCurrentSelectionOrExtendCaret(
const LocalFrame& frame,
SelectionModifyDirection direction,
TextGranularity granularity) {
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
SelectionModifier selection_modifier(
frame, frame.Selection().GetSelectionInDOMTree());
selection_modifier.SetSelectionIsDirectional(
@@ -361,12 +361,12 @@ static bool ExecuteDefaultParagraphSeparator(LocalFrame& frame,
Event*,
EditorCommandSource,
const String& value) {
- if (DeprecatedEqualIgnoringCase(value, "div")) {
+ if (EqualIgnoringASCIICase(value, "div")) {
frame.GetEditor().SetDefaultParagraphSeparator(
EditorParagraphSeparator::kIsDiv);
return true;
}
- if (DeprecatedEqualIgnoringCase(value, "p")) {
+ if (EqualIgnoringASCIICase(value, "p")) {
frame.GetEditor().SetDefaultParagraphSeparator(
EditorParagraphSeparator::kIsP);
}
@@ -380,7 +380,7 @@ static void PerformDelete(LocalFrame& frame) {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
// |SelectedRange| requires clean layout for visible selection normalization.
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
frame.GetEditor().AddToKillRing(frame.GetEditor().SelectedRange());
// TODO(editing-dev): |Editor::performDelete()| has no direction.
@@ -571,7 +571,7 @@ static bool ExecuteDeleteToMark(LocalFrame& frame,
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
frame.GetEditor().SetMark();
return true;
}
@@ -754,7 +754,8 @@ static bool ExecuteScrollPageBackward(LocalFrame& frame,
EditorCommandSource,
const String&) {
return frame.GetEventHandler().BubblingScroll(
- kScrollBlockDirectionBackward, ScrollGranularity::kScrollByPage);
+ mojom::blink::ScrollDirection::kScrollBlockDirectionBackward,
+ ScrollGranularity::kScrollByPage);
}
static bool ExecuteScrollPageForward(LocalFrame& frame,
@@ -762,7 +763,8 @@ static bool ExecuteScrollPageForward(LocalFrame& frame,
EditorCommandSource,
const String&) {
return frame.GetEventHandler().BubblingScroll(
- kScrollBlockDirectionForward, ScrollGranularity::kScrollByPage);
+ mojom::blink::ScrollDirection::kScrollBlockDirectionForward,
+ ScrollGranularity::kScrollByPage);
}
static bool ExecuteScrollLineUp(LocalFrame& frame,
@@ -770,7 +772,8 @@ static bool ExecuteScrollLineUp(LocalFrame& frame,
EditorCommandSource,
const String&) {
return frame.GetEventHandler().BubblingScroll(
- kScrollUpIgnoringWritingMode, ScrollGranularity::kScrollByLine);
+ mojom::blink::ScrollDirection::kScrollUpIgnoringWritingMode,
+ ScrollGranularity::kScrollByLine);
}
static bool ExecuteScrollLineDown(LocalFrame& frame,
@@ -778,7 +781,8 @@ static bool ExecuteScrollLineDown(LocalFrame& frame,
EditorCommandSource,
const String&) {
return frame.GetEventHandler().BubblingScroll(
- kScrollDownIgnoringWritingMode, ScrollGranularity::kScrollByLine);
+ mojom::blink::ScrollDirection::kScrollDownIgnoringWritingMode,
+ ScrollGranularity::kScrollByLine);
}
static bool ExecuteScrollToBeginningOfDocument(LocalFrame& frame,
@@ -786,7 +790,8 @@ static bool ExecuteScrollToBeginningOfDocument(LocalFrame& frame,
EditorCommandSource,
const String&) {
return frame.GetEventHandler().BubblingScroll(
- kScrollBlockDirectionBackward, ScrollGranularity::kScrollByDocument);
+ mojom::blink::ScrollDirection::kScrollBlockDirectionBackward,
+ ScrollGranularity::kScrollByDocument);
}
static bool ExecuteScrollToEndOfDocument(LocalFrame& frame,
@@ -794,7 +799,8 @@ static bool ExecuteScrollToEndOfDocument(LocalFrame& frame,
EditorCommandSource,
const String&) {
return frame.GetEventHandler().BubblingScroll(
- kScrollBlockDirectionForward, ScrollGranularity::kScrollByDocument);
+ mojom::blink::ScrollDirection::kScrollBlockDirectionForward,
+ ScrollGranularity::kScrollByDocument);
}
static bool ExecuteSelectAll(LocalFrame& frame,
@@ -893,7 +899,7 @@ static bool ExecuteTranspose(LocalFrame& frame,
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- document->UpdateStyleAndLayout();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
const EphemeralRange& range = ComputeRangeForTranspose(frame);
if (range.IsNull())
@@ -919,7 +925,7 @@ static bool ExecuteTranspose(LocalFrame& frame,
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- document->UpdateStyleAndLayout();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// 'beforeinput' event handler may change selection, we need to re-calculate
// range.
@@ -987,7 +993,7 @@ static bool ExecuteYank(LocalFrame& frame,
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
frame.GetEditor().InsertTextWithoutSendingTextEvent(
yank_string, false, nullptr, InputEvent::InputType::kInsertFromYank);
@@ -1012,7 +1018,7 @@ static bool ExecuteYankAndSelect(LocalFrame& frame,
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
frame.GetEditor().InsertTextWithoutSendingTextEvent(
frame.GetEditor().GetKillRing().Yank(), true, nullptr,
@@ -1040,7 +1046,7 @@ static bool Enabled(LocalFrame&, Event*, EditorCommandSource) {
static bool EnabledVisibleSelection(LocalFrame& frame,
Event* event,
EditorCommandSource source) {
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (source == EditorCommandSource::kMenuOrKeyBinding &&
!frame.Selection().SelectionHasFocus())
@@ -1058,7 +1064,7 @@ static bool EnabledVisibleSelection(LocalFrame& frame,
static bool EnabledVisibleSelectionAndMark(LocalFrame& frame,
Event* event,
EditorCommandSource source) {
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (source == EditorCommandSource::kMenuOrKeyBinding &&
!frame.Selection().SelectionHasFocus())
@@ -1075,7 +1081,7 @@ static bool EnabledVisibleSelectionAndMark(LocalFrame& frame,
static bool EnableCaretInEditableText(LocalFrame& frame,
Event* event,
EditorCommandSource source) {
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (source == EditorCommandSource::kMenuOrKeyBinding &&
!frame.Selection().SelectionHasFocus())
@@ -1088,7 +1094,7 @@ static bool EnableCaretInEditableText(LocalFrame& frame,
static bool EnabledInEditableText(LocalFrame& frame,
Event* event,
EditorCommandSource source) {
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (source == EditorCommandSource::kMenuOrKeyBinding &&
!frame.Selection().SelectionHasFocus())
return false;
@@ -1124,7 +1130,7 @@ static bool EnabledDelete(LocalFrame& frame,
static bool EnabledInRichlyEditableText(LocalFrame& frame,
Event*,
EditorCommandSource source) {
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (source == EditorCommandSource::kMenuOrKeyBinding &&
!frame.Selection().SelectionHasFocus())
return false;
@@ -1137,7 +1143,7 @@ static bool EnabledInRichlyEditableText(LocalFrame& frame,
static bool EnabledRangeInEditableText(LocalFrame& frame,
Event*,
EditorCommandSource source) {
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (source == EditorCommandSource::kMenuOrKeyBinding &&
!frame.Selection().SelectionHasFocus())
return false;
@@ -1152,7 +1158,7 @@ static bool EnabledRangeInEditableText(LocalFrame& frame,
static bool EnabledRangeInRichlyEditableText(LocalFrame& frame,
Event*,
EditorCommandSource source) {
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (source == EditorCommandSource::kMenuOrKeyBinding &&
!frame.Selection().SelectionHasFocus())
return false;
@@ -1172,7 +1178,7 @@ static bool EnabledUndo(LocalFrame& frame, Event*, EditorCommandSource) {
static bool EnabledUnselect(LocalFrame& frame,
Event* event,
EditorCommandSource) {
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// The term "visible" here includes a caret in editable text or a range in any
// text.
@@ -1187,7 +1193,7 @@ static bool EnabledSelectAll(LocalFrame& frame,
EditorCommandSource source) {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
const VisibleSelection& selection =
frame.Selection().ComputeVisibleSelectionInDOMTree();
if (selection.IsNone())
@@ -1853,7 +1859,8 @@ bool Editor::ExecuteCommand(const String& command_name) {
if (command_name == "AdvanceToNextMisspelling") {
// TODO(editing-dev): Use of UpdateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- GetFrame().GetDocument()->UpdateStyleAndLayout();
+ GetFrame().GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kEditing);
// We need to pass false here or else the currently selected word will never
// be skipped.
@@ -1864,7 +1871,8 @@ bool Editor::ExecuteCommand(const String& command_name) {
// TODO(editing-dev): Use of UpdateStyleAndLayout
// needs to be audited.
// see http://crbug.com/590369 for more details.
- GetFrame().GetDocument()->UpdateStyleAndLayout();
+ GetFrame().GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kEditing);
GetSpellChecker().ShowSpellingGuessPanel();
return true;
@@ -1878,18 +1886,21 @@ bool Editor::ExecuteCommand(const String& command_name, const String& value) {
DCHECK(GetFrame().GetDocument()->IsActive());
if (!CanEdit() && command_name == "moveToBeginningOfDocument") {
return GetFrame().GetEventHandler().BubblingScroll(
- kScrollUpIgnoringWritingMode, ScrollGranularity::kScrollByDocument);
+ mojom::blink::ScrollDirection::kScrollUpIgnoringWritingMode,
+ ScrollGranularity::kScrollByDocument);
}
if (!CanEdit() && command_name == "moveToEndOfDocument") {
return GetFrame().GetEventHandler().BubblingScroll(
- kScrollDownIgnoringWritingMode, ScrollGranularity::kScrollByDocument);
+ mojom::blink::ScrollDirection::kScrollDownIgnoringWritingMode,
+ ScrollGranularity::kScrollByDocument);
}
if (command_name == "ToggleSpellPanel") {
// TODO(editing-dev): Use of UpdateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- GetFrame().GetDocument()->UpdateStyleAndLayout();
+ GetFrame().GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kEditing);
GetSpellChecker().ShowSpellingGuessPanel();
return true;
@@ -1903,7 +1914,9 @@ bool Editor::IsCommandEnabled(const String& command_name) const {
}
EditorCommand::EditorCommand()
- : command_(nullptr), source_(EditorCommandSource::kMenuOrKeyBinding) {}
+ : command_(nullptr),
+ source_(EditorCommandSource::kMenuOrKeyBinding),
+ frame_(nullptr) {}
EditorCommand::EditorCommand(const EditorInternalCommand* command,
EditorCommandSource source,
@@ -1940,7 +1953,8 @@ bool EditorCommand::Execute(const String& parameter,
}
}
- GetFrame().GetDocument()->UpdateStyleAndLayout();
+ GetFrame().GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kEditing);
DEFINE_STATIC_LOCAL(SparseHistogram, command_histogram,
("WebCore.Editing.Commands"));
command_histogram.Sample(static_cast<int>(command_->command_type));
@@ -1964,7 +1978,7 @@ bool EditorCommand::IsSupported() const {
case EditorCommandSource::kMenuOrKeyBinding:
return true;
case EditorCommandSource::kDOM:
- return command_->is_supported_from_dom(frame_.Get());
+ return command_->is_supported_from_dom(frame_);
}
NOTREACHED();
return false;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/editor_command.h b/chromium/third_party/blink/renderer/core/editing/commands/editor_command.h
index 0cee2e65931..41e3e935b73 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/editor_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/editor_command.h
@@ -76,7 +76,7 @@ class CORE_EXPORT EditorCommand {
const EditorInternalCommand* command_;
const EditorCommandSource source_;
- const Member<LocalFrame> frame_;
+ LocalFrame* const frame_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/format_block_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/format_block_command.cc
index fe177074549..5cecaf62ad7 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/format_block_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/format_block_command.cc
@@ -89,7 +89,7 @@ void FormatBlockCommand::FormatRange(const Position& start,
Node* node_after_insertion_position = outer_block;
const EphemeralRange range(start, end_of_selection);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (IsElementForFormatBlock(ref_element->TagQName()) &&
CreateVisiblePosition(start).DeepEquivalent() ==
StartOfBlock(CreateVisiblePosition(start)).DeepEquivalent() &&
@@ -112,7 +112,7 @@ void FormatBlockCommand::FormatRange(const Position& start,
editing_state);
if (editing_state->IsAborted())
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
}
Position last_paragraph_in_block_node =
@@ -146,7 +146,7 @@ void FormatBlockCommand::FormatRange(const Position& start,
->getAttribute(html_names::kStyleAttr));
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (was_end_of_paragraph &&
!IsEndOfParagraph(CreateVisiblePosition(last_paragraph_in_block_node)) &&
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/indent_outdent_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/indent_outdent_command.cc
index d251d94704d..177107431ac 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/indent_outdent_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/indent_outdent_command.cc
@@ -98,7 +98,7 @@ bool IndentOutdentCommand::TryIndentingAsListItem(const Position& start,
if (editing_state->IsAborted())
return false;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// We should clone all the children of the list item for indenting purposes.
// However, in case the current selection does not encompass all its children,
@@ -134,7 +134,7 @@ bool IndentOutdentCommand::TryIndentingAsListItem(const Position& start,
return false;
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
DCHECK(new_list);
if (previous_list && CanMergeLists(*previous_list, *new_list)) {
MergeIdenticalElements(previous_list, new_list, editing_state);
@@ -142,7 +142,7 @@ bool IndentOutdentCommand::TryIndentingAsListItem(const Position& start,
return false;
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (next_list && CanMergeLists(*new_list, *next_list)) {
MergeIdenticalElements(new_list, next_list, editing_state);
if (editing_state->IsAborted())
@@ -173,7 +173,7 @@ void IndentOutdentCommand::IndentIntoBlockquote(const Position& start,
? start.ComputeContainerNode()
: SplitTreeToNode(start.ComputeContainerNode(), element_to_split_to);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
VisiblePosition start_of_contents = CreateVisiblePosition(start);
if (!target_blockquote) {
// Create a new blockquote and insert it as a child of the root editable
@@ -191,7 +191,7 @@ void IndentOutdentCommand::IndentIntoBlockquote(const Position& start,
InsertNodeBefore(target_blockquote, outer_block, editing_state);
if (editing_state->IsAborted())
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
start_of_contents = VisiblePosition::InParentAfterNode(*target_blockquote);
}
@@ -268,7 +268,7 @@ void IndentOutdentCommand::OutdentParagraph(EditingState* editing_state) {
}
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
visible_start_of_paragraph =
CreateVisiblePosition(visible_start_of_paragraph.DeepEquivalent());
if (visible_start_of_paragraph.IsNotNull() &&
@@ -279,7 +279,7 @@ void IndentOutdentCommand::OutdentParagraph(EditingState* editing_state) {
return;
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
visible_end_of_paragraph =
CreateVisiblePosition(visible_end_of_paragraph.DeepEquivalent());
if (visible_end_of_paragraph.IsNotNull() &&
@@ -324,7 +324,7 @@ void IndentOutdentCommand::OutdentParagraph(EditingState* editing_state) {
: visible_start_of_paragraph.DeepEquivalent().AnchorNode());
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// Re-canonicalize visible{Start,End}OfParagraph, make them valid again
// after DOM change.
@@ -351,7 +351,7 @@ void IndentOutdentCommand::OutdentParagraph(EditingState* editing_state) {
if (editing_state->IsAborted())
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
start_of_paragraph_to_move = CreateVisiblePosition(
start_of_paragraph_to_move.ToPositionWithAffinity());
end_of_paragraph_to_move =
@@ -407,7 +407,7 @@ void IndentOutdentCommand::OutdentRegion(
if (end_after_selection.IsNotNull() && !end_after_selection.IsConnected())
break;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (end_of_next_paragraph.IsNotNull() &&
!end_of_next_paragraph.IsConnected()) {
end_of_current_paragraph =
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/insert_incremental_text_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/insert_incremental_text_command.cc
index 9df720b50ed..be0e603a835 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/insert_incremental_text_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/insert_incremental_text_command.cc
@@ -118,14 +118,6 @@ SelectionInDOMTree ComputeSelectionForInsertion(
} // anonymous namespace
-InsertIncrementalTextCommand* InsertIncrementalTextCommand::Create(
- Document& document,
- const String& text,
- RebalanceType rebalance_type) {
- return MakeGarbageCollected<InsertIncrementalTextCommand>(document, text,
- rebalance_type);
-}
-
InsertIncrementalTextCommand::InsertIncrementalTextCommand(
Document& document,
const String& text,
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/insert_incremental_text_command.h b/chromium/third_party/blink/renderer/core/editing/commands/insert_incremental_text_command.h
index 165a04a8be1..324767a1a4d 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/insert_incremental_text_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/insert_incremental_text_command.h
@@ -12,15 +12,11 @@ namespace blink {
class CORE_EXPORT InsertIncrementalTextCommand final
: public InsertTextCommand {
public:
- static InsertIncrementalTextCommand* Create(
+ InsertIncrementalTextCommand(
Document&,
- const String&,
+ const String& text,
RebalanceType = kRebalanceLeadingAndTrailingWhitespaces);
- InsertIncrementalTextCommand(Document&,
- const String& text,
- RebalanceType);
-
private:
void DoApply(EditingState*) override;
};
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/insert_incremental_text_command_test.cc b/chromium/third_party/blink/renderer/core/editing/commands/insert_incremental_text_command_test.cc
index b36ae21d721..881c52bec7f 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/insert_incremental_text_command_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/insert_incremental_text_command_test.cc
@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/editing/selection_template.h"
#include "third_party/blink/renderer/core/editing/testing/editing_test_base.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
@@ -23,7 +24,8 @@ TEST_F(InsertIncrementalTextCommandTest, SurrogatePairsReplace) {
.Build(),
SetSelectionOptions());
CompositeEditCommand* const command =
- InsertIncrementalTextCommand::Create(GetDocument(), new_text);
+ MakeGarbageCollected<InsertIncrementalTextCommand>(GetDocument(),
+ new_text);
command->Apply();
EXPECT_EQ(String(Vector<UChar>{'b', 0xD83D, 0xDE38}),
@@ -41,7 +43,8 @@ TEST_F(InsertIncrementalTextCommandTest, SurrogatePairsNoReplace) {
.Build(),
SetSelectionOptions());
CompositeEditCommand* const command =
- InsertIncrementalTextCommand::Create(GetDocument(), new_text);
+ MakeGarbageCollected<InsertIncrementalTextCommand>(GetDocument(),
+ new_text);
command->Apply();
EXPECT_EQ(String(Vector<UChar>{'b', 0xD83D, 0xDE3A}),
@@ -61,7 +64,8 @@ TEST_F(InsertIncrementalTextCommandTest, SurrogatePairsTwo) {
.Build(),
SetSelectionOptions());
CompositeEditCommand* const command =
- InsertIncrementalTextCommand::Create(GetDocument(), new_text);
+ MakeGarbageCollected<InsertIncrementalTextCommand>(GetDocument(),
+ new_text);
command->Apply();
EXPECT_EQ(String(Vector<UChar>{'b', 0xD83D, 0xDE38}),
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 4969f958e52..89293666dba 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
@@ -50,8 +50,9 @@ void InsertIntoTextNodeCommand::DoApply(EditingState*) {
bool password_echo_enabled =
GetDocument().GetSettings() &&
GetDocument().GetSettings()->GetPasswordEchoEnabled();
- if (password_echo_enabled)
- GetDocument().UpdateStyleAndLayout();
+ if (password_echo_enabled) {
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
+ }
if (!HasEditableStyle(*node_))
return;
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/insert_line_break_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/insert_line_break_command.cc
index 40f823a5cf1..fe3f95f7da5 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/insert_line_break_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/insert_line_break_command.cc
@@ -68,7 +68,7 @@ void InsertLineBreakCommand::DoApply(EditingState* editing_state) {
if (!DeleteSelection(editing_state, DeleteSelectionOptions::NormalDelete()))
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
VisibleSelection selection = EndingVisibleSelection();
if (selection.IsNone() || selection.Start().IsOrphan() ||
@@ -98,7 +98,7 @@ void InsertLineBreakCommand::DoApply(EditingState* editing_state) {
else
node_to_insert = GetDocument().createTextNode("\n");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// FIXME: Need to merge text nodes when inserting just after or before text.
@@ -137,7 +137,7 @@ void InsertLineBreakCommand::DoApply(EditingState* editing_state) {
InsertNodeAt(node_to_insert, pos, editing_state);
if (editing_state->IsAborted())
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// Insert an extra br or '\n' if the just inserted one collapsed.
if (!IsStartOfParagraph(VisiblePosition::BeforeNode(*node_to_insert))) {
@@ -172,7 +172,7 @@ void InsertLineBreakCommand::DoApply(EditingState* editing_state) {
Position ending_position = Position::FirstPositionInNode(*text_node);
// Handle whitespace that occurs after the split
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (!IsRenderedCharacter(ending_position)) {
Position position_before_text_node(
Position::InParentBeforeNode(*text_node));
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 45eabd837e1..e569395f451 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
@@ -75,7 +75,7 @@ HTMLElement* InsertListCommand::MergeWithNeighboringLists(
DCHECK(passed_list);
HTMLElement* list = passed_list;
Element* previous_list = ElementTraversal::PreviousSibling(*list);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (previous_list && CanMergeLists(*previous_list, *list)) {
MergeIdenticalElements(previous_list, list, editing_state);
if (editing_state->IsAborted())
@@ -90,7 +90,7 @@ HTMLElement* InsertListCommand::MergeWithNeighboringLists(
if (!next_list)
return list;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (CanMergeLists(*list, *next_list)) {
MergeIdenticalElements(list, next_list, editing_state);
if (editing_state->IsAborted())
@@ -244,7 +244,7 @@ void InsertListCommand::DoApply(EditingState* editing_state) {
if (!single_paragraph_result)
break;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// Make |visibleEndOfSelection| valid again.
if (!end_of_selection.IsConnected() ||
@@ -280,7 +280,7 @@ void InsertListCommand::DoApply(EditingState* editing_state) {
if (editing_state->IsAborted())
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// Fetch the end of the selection, for the reason mentioned above.
if (!end_of_selection.IsConnected()) {
@@ -358,7 +358,7 @@ bool InsertListCommand::DoApplyForSingleParagraph(
list_element = MergeWithNeighboringLists(list_element, editing_state);
if (editing_state->IsAborted())
return false;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
}
DCHECK(HasEditableStyle(*list_element));
DCHECK(HasEditableStyle(*list_element->parentNode()));
@@ -393,7 +393,7 @@ bool InsertListCommand::DoApplyForSingleParagraph(
if (editing_state->IsAborted())
return false;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
Node* first_child_in_list =
EnclosingListChild(VisiblePosition::FirstPositionInNode(*list_element)
.DeepEquivalent()
@@ -449,7 +449,7 @@ bool InsertListCommand::DoApplyForSingleParagraph(
list_child_node, editing_state);
if (editing_state->IsAborted())
return false;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
}
if (!list_child_node || switch_list_type || force_create_list) {
@@ -538,7 +538,7 @@ void InsertListCommand::UnlistifyParagraph(
if (editing_state->IsAborted())
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// Make |start| and |end| valid again.
start = CreateVisiblePosition(start_position);
@@ -604,7 +604,7 @@ void InsertListCommand::ListifyParagraph(const VisiblePosition& original_start,
if (editing_state->IsAborted())
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (previous_list && next_list && CanMergeLists(*previous_list, *next_list))
MergeIdenticalElements(previous_list, next_list, editing_state);
@@ -626,7 +626,7 @@ void InsertListCommand::ListifyParagraph(const VisiblePosition& original_start,
start_pos = Position::BeforeNode(*placeholder);
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// Insert the list at a position visually equivalent to start of the
// paragraph that is being moved into the list.
@@ -669,7 +669,7 @@ void InsertListCommand::ListifyParagraph(const VisiblePosition& original_start,
MoveParagraphOverPositionIntoEmptyListItem(
original_start, list_item_element, editing_state);
} else {
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
MoveParagraphOverPositionIntoEmptyListItem(
CreateVisiblePosition(start_pos), list_item_element, editing_state);
}
@@ -692,7 +692,7 @@ void InsertListCommand::MoveParagraphOverPositionIntoEmptyListItem(
return;
// Inserting list element and list item list may change start of pargraph
// to move. We calculate start of paragraph again.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
const VisiblePosition& valid_pos =
CreateVisiblePosition(pos.ToPositionWithAffinity());
const VisiblePosition& start =
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/insert_list_command_test.cc b/chromium/third_party/blink/renderer/core/editing/commands/insert_list_command_test.cc
index 727520dfd17..97a9ca423b2 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/insert_list_command_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/insert_list_command_test.cc
@@ -48,8 +48,7 @@ TEST_F(InsertListCommandTest, ShouldCleanlyRemoveSpuriousTextNode) {
// This should not DCHECK.
EXPECT_TRUE(command->Apply())
<< "The insert ordered list command should have succeeded";
- EXPECT_EQ("<ol><li>\nd\n</li></ol>",
- GetDocument().body()->InnerHTMLAsString());
+ EXPECT_EQ("<ol><li>\nd\n</li></ol>", GetDocument().body()->innerHTML());
}
// Refer https://crbug.com/794356
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 d6b3421d0d2..8e5acdce6ee 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
@@ -193,7 +193,7 @@ void InsertParagraphSeparatorCommand::DoApply(EditingState* editing_state) {
// Delete the current selection.
if (EndingSelection().IsRange()) {
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
CalculateStyleBeforeInsertion(insertion_position);
if (!DeleteSelection(editing_state, DeleteSelectionOptions::NormalDelete()))
return;
@@ -203,7 +203,7 @@ void InsertParagraphSeparatorCommand::DoApply(EditingState* editing_state) {
affinity = visble_selection_after_delete.Affinity();
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// FIXME: The parentAnchoredEquivalent conversion needs to be moved into
// enclosingBlock.
@@ -252,7 +252,7 @@ void InsertParagraphSeparatorCommand::DoApply(EditingState* editing_state) {
To<HTMLElement>(EnclosingAnchorElement(original_insertion_position));
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
CalculateStyleBeforeInsertion(insertion_position);
//---------------------------------------------------------------------
@@ -387,7 +387,7 @@ void InsertParagraphSeparatorCommand::DoApply(EditingState* editing_state) {
ref_node = insertion_position.AnchorNode();
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// find ending selection position easily before inserting the paragraph
insertion_position = MostForwardCaretPosition(insertion_position);
@@ -436,7 +436,7 @@ void InsertParagraphSeparatorCommand::DoApply(EditingState* editing_state) {
InsertNodeAt(br, insertion_position, editing_state);
if (editing_state->IsAborted())
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
insertion_position = Position::InParentAfterNode(*br);
visible_pos = CreateVisiblePosition(insertion_position);
@@ -493,7 +493,7 @@ void InsertParagraphSeparatorCommand::DoApply(EditingState* editing_state) {
ReplaceTextInNode(text_node,
leading_whitespace.ComputeOffsetInContainerNode(), 1,
NonBreakingSpaceString());
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
}
}
@@ -506,7 +506,7 @@ void InsertParagraphSeparatorCommand::DoApply(EditingState* editing_state) {
bool at_end = static_cast<unsigned>(text_offset) >= text_node->length();
if (text_offset > 0 && !at_end) {
SplitTextNode(text_node, text_offset);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
position_after_split = Position::FirstPositionInNode(*text_node);
insertion_position =
@@ -534,7 +534,7 @@ void InsertParagraphSeparatorCommand::DoApply(EditingState* editing_state) {
if (editing_state->IsAborted())
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
visible_pos = CreateVisiblePosition(insertion_position);
// If the paragraph separator was inserted at the end of a paragraph, an empty
@@ -547,7 +547,7 @@ void InsertParagraphSeparatorCommand::DoApply(EditingState* editing_state) {
block_to_insert, editing_state);
if (editing_state->IsAborted())
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
}
// Move the start node and the siblings of the start node.
@@ -565,7 +565,7 @@ void InsertParagraphSeparatorCommand::DoApply(EditingState* editing_state) {
if (split_to)
SplitTreeToNode(split_to, start_block);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
for (n = start_block->firstChild(); n; n = n->nextSibling()) {
VisiblePosition before_node_position = VisiblePosition::BeforeNode(*n);
@@ -584,7 +584,7 @@ void InsertParagraphSeparatorCommand::DoApply(EditingState* editing_state) {
// Handle whitespace that occurs after the split
if (position_after_split.IsNotNull()) {
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (!IsRenderedCharacter(position_after_split)) {
// Clear out all whitespace and insert one non-breaking space
DCHECK(!position_after_split.ComputeContainerNode()->GetLayoutObject() ||
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command_test.cc b/chromium/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command_test.cc
index f93883a02cd..c4f9bc8e5c7 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command_test.cc
@@ -69,7 +69,7 @@ TEST_F(InsertParagraphSeparatorCommandTest, CrashWithCaptionBeforeBody) {
// Insert <caption> between head and body
Element* caption = GetDocument().CreateElementForBinding("caption");
- caption->SetInnerHTMLFromString("AxBxC");
+ caption->setInnerHTML("AxBxC");
GetDocument().documentElement()->insertBefore(caption, GetDocument().body());
Selection().SetSelection(
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/insert_text_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/insert_text_command.cc
index b7bd0eaa042..d59c6167bf5 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/insert_text_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/insert_text_command.cc
@@ -157,7 +157,7 @@ void InsertTextCommand::DoApply(EditingState* editing_state) {
if (EndingSelection().IsRange()) {
if (PerformTrivialReplace(text_))
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
bool end_of_selection_was_at_start_of_block =
IsStartOfBlock(EndingVisibleSelection().VisibleEnd());
if (!DeleteSelection(editing_state, DeleteSelectionOptions::Builder()
@@ -174,14 +174,14 @@ void InsertTextCommand::DoApply(EditingState* editing_state) {
if (end_of_selection_was_at_start_of_block) {
if (EditingStyle* typing_style =
GetDocument().GetFrame()->GetEditor().TypingStyle())
- typing_style->RemoveBlockProperties();
+ typing_style->RemoveBlockProperties(GetDocument().ToExecutionContext());
}
} else if (GetDocument().GetFrame()->GetEditor().IsOverwriteModeEnabled()) {
if (PerformOverwrite(text_))
return;
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// Reached by InsertTextCommandTest.NoVisibleSelectionAfterDeletingSelection
ABORT_EDITING_COMMAND_IF(EndingVisibleSelection().IsNone());
@@ -222,7 +222,7 @@ void InsertTextCommand::DoApply(EditingState* editing_state) {
// TODO(editing-dev): Use of UpdateStyleAndLayout()
// needs to be audited. See http://crbug.com/590369 for more details.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (!start_position.IsConnected())
start_position = position_before_start_node;
@@ -302,7 +302,7 @@ void InsertTextCommand::DoApply(EditingState* editing_state) {
Position InsertTextCommand::InsertTab(const Position& pos,
EditingState* editing_state) {
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
Position insert_pos = CreateVisiblePosition(pos).DeepEquivalent();
if (insert_pos.IsNull())
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/insert_text_command_test.cc b/chromium/third_party/blink/renderer/core/editing/commands/insert_text_command_test.cc
index 72d7153b370..14d4cfff12e 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/insert_text_command_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/insert_text_command_test.cc
@@ -29,7 +29,7 @@ TEST_F(InsertTextCommandTest, WithTypingStyle) {
EXPECT_EQ(
"<div contenteditable=\"true\"><option id=\"sample\">x</option></div>",
- GetDocument().body()->InnerHTMLAsString())
+ GetDocument().body()->innerHTML())
<< "Content of OPTION is distributed into shadow node as text"
"without applying typing style.";
}
@@ -282,7 +282,7 @@ TEST_F(InsertTextCommandTest, AnchorElementWithBlockCrash) {
Element* iElement = GetDocument().CreateRawElement(html_names::kITag);
nested_anchor->setAttribute("href", "www");
- iElement->SetInnerHTMLFromString("home");
+ iElement->setInnerHTML("home");
anchor->AppendChild(nested_anchor);
nested_anchor->AppendChild(iElement);
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/move_commands.cc b/chromium/third_party/blink/renderer/core/editing/commands/move_commands.cc
index f11ec20005c..83f4c4ef317 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/move_commands.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/move_commands.cc
@@ -31,6 +31,7 @@
#include "third_party/blink/renderer/core/editing/commands/move_commands.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/editing/editing_behavior.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
@@ -143,8 +144,8 @@ void MoveCommands::UpdateFocusForCaretBrowsing(LocalFrame& frame) {
Element* new_focused_element = nullptr;
while (node) {
- if (node->IsElementNode() && ToElement(node)->IsFocusable()) {
- new_focused_element = ToElement(node);
+ if (node->IsElementNode() && To<Element>(node)->IsFocusable()) {
+ new_focused_element = To<Element>(node);
break;
}
node = node->ParentOrShadowHostNode();
@@ -155,7 +156,8 @@ void MoveCommands::UpdateFocusForCaretBrowsing(LocalFrame& frame) {
frame.GetDocument()->SetFocusedElement(
new_focused_element,
- FocusParams(SelectionBehaviorOnFocus::kNone, kWebFocusTypeNone, nullptr));
+ FocusParams(SelectionBehaviorOnFocus::kNone,
+ mojom::blink::FocusType::kNone, nullptr));
}
void MoveCommands::UpdateSelectionForCaretBrowsing(LocalFrame& frame) {
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/move_commands_test.cc b/chromium/third_party/blink/renderer/core/editing/commands/move_commands_test.cc
index 7de107b8210..f3e7cffdbd2 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/move_commands_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/move_commands_test.cc
@@ -5,6 +5,7 @@
#include <string>
#include "build/build_config.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/editing/commands/move_commands.h"
#include "third_party/blink/renderer/core/editing/editor.h"
@@ -27,8 +28,8 @@ class MoveCommandsTest : public EditingTestBase {
SetSelectionOptions());
GetDocument().SetFocusedElement(
GetDocument().QuerySelector(initial_focus_element),
- FocusParams(SelectionBehaviorOnFocus::kNone, kWebFocusTypeNone,
- nullptr));
+ FocusParams(SelectionBehaviorOnFocus::kNone,
+ mojom::blink::FocusType::kNone, nullptr));
GetDocument().GetFrame()->GetSettings()->SetCaretBrowsingEnabled(true);
execute(*GetDocument().GetFrame(), nullptr,
EditorCommandSource::kMenuOrKeyBinding, String());
@@ -316,7 +317,8 @@ TEST_F(MoveCommandsTest, CaretBrowsingSelectionUpdate) {
SetSelectionOptions());
GetDocument().SetFocusedElement(
GetDocument().QuerySelector("a"),
- FocusParams(SelectionBehaviorOnFocus::kNone, kWebFocusTypeNone, nullptr));
+ FocusParams(SelectionBehaviorOnFocus::kNone,
+ mojom::blink::FocusType::kNone, nullptr));
GetDocument().GetFrame()->GetSettings()->SetCaretBrowsingEnabled(true);
MoveCommands::ExecuteMoveRight(*GetDocument().GetFrame(), nullptr,
EditorCommandSource::kMenuOrKeyBinding,
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 708ee997b89..f2ad9e8cd10 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
@@ -105,8 +105,8 @@ class ReplacementFragment final {
void InsertNodeBefore(Node*, Node* ref_node);
- Member<Document> document_;
- Member<DocumentFragment> fragment_;
+ Document* document_;
+ DocumentFragment* fragment_;
bool has_interchange_newline_at_start_;
bool has_interchange_newline_at_end_;
@@ -175,7 +175,7 @@ ReplacementFragment::ReplacementFragment(Document* document,
if (!editable_root)
return;
- document_->UpdateStyleAndLayout();
+ document_->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
Element* shadow_ancestor_element;
if (editable_root->IsInShadowTree())
@@ -191,7 +191,7 @@ ReplacementFragment::ReplacementFragment(Document* document,
!(shadow_ancestor_element && shadow_ancestor_element->GetLayoutObject() &&
shadow_ancestor_element->GetLayoutObject()->IsTextControl()) &&
HasRichlyEditableStyle(*editable_root)) {
- RemoveInterchangeNodes(fragment_.Get());
+ RemoveInterchangeNodes(fragment_);
return;
}
@@ -208,7 +208,7 @@ ReplacementFragment::ReplacementFragment(Document* document,
// We don't need TestRendering for plain-text editing + plain-text
// insertion.
if (is_plain_text) {
- RemoveInterchangeNodes(fragment_.Get());
+ RemoveInterchangeNodes(fragment_);
String original_text = fragment_->textContent();
auto* event =
MakeGarbageCollected<BeforeTextInsertedEvent>(original_text);
@@ -216,7 +216,7 @@ ReplacementFragment::ReplacementFragment(Document* document,
if (original_text != event->GetText()) {
fragment_ = CreateFragmentFromText(
selection.ToNormalizedEphemeralRange(), event->GetText());
- RemoveInterchangeNodes(fragment_.Get());
+ RemoveInterchangeNodes(fragment_);
}
return;
}
@@ -224,7 +224,7 @@ ReplacementFragment::ReplacementFragment(Document* document,
HTMLElement* holder = InsertFragmentForTestRendering(editable_root);
if (!holder) {
- RemoveInterchangeNodes(fragment_.Get());
+ RemoveInterchangeNodes(fragment_);
return;
}
@@ -250,7 +250,7 @@ ReplacementFragment::ReplacementFragment(Document* document,
// TODO(editing-dev): Use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- document->UpdateStyleAndLayout();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
fragment_ = CreateFragmentFromText(selection.ToNormalizedEphemeralRange(),
evt->GetText());
@@ -314,13 +314,13 @@ HTMLElement* ReplacementFragment::InsertFragmentForTestRendering(
Element* root_editable_element) {
TRACE_EVENT0("blink", "ReplacementFragment::insertFragmentForTestRendering");
DCHECK(document_);
- HTMLElement* holder = CreateDefaultParagraphElement(*document_.Get());
+ HTMLElement* holder = CreateDefaultParagraphElement(*document_);
holder->AppendChild(fragment_);
root_editable_element->AppendChild(holder);
// TODO(editing-dev): Hoist this call to the call sites.
- document_->UpdateStyleAndLayout();
+ document_->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
return holder;
}
@@ -391,24 +391,24 @@ inline void ReplaceSelectionCommand::InsertedNodes::RespondToNodeInsertion(
inline void
ReplaceSelectionCommand::InsertedNodes::WillRemoveNodePreservingChildren(
Node& node) {
- if (first_node_inserted_.Get() == node)
+ if (first_node_inserted_ == node)
first_node_inserted_ = NodeTraversal::Next(node);
- if (last_node_inserted_.Get() == node)
+ if (last_node_inserted_ == node)
last_node_inserted_ = node.lastChild()
? node.lastChild()
: NodeTraversal::NextSkippingChildren(node);
- if (ref_node_.Get() == node)
+ if (ref_node_ == node)
ref_node_ = NodeTraversal::Next(node);
}
inline void ReplaceSelectionCommand::InsertedNodes::WillRemoveNode(Node& node) {
- if (first_node_inserted_.Get() == node && last_node_inserted_.Get() == node) {
+ if (first_node_inserted_ == node && last_node_inserted_ == node) {
first_node_inserted_ = nullptr;
last_node_inserted_ = nullptr;
- } else if (first_node_inserted_.Get() == node) {
+ } else if (first_node_inserted_ == node) {
first_node_inserted_ =
NodeTraversal::NextSkippingChildren(*first_node_inserted_);
- } else if (last_node_inserted_.Get() == node) {
+ } else if (last_node_inserted_ == node) {
last_node_inserted_ =
NodeTraversal::PreviousSkippingChildren(*last_node_inserted_);
}
@@ -419,11 +419,11 @@ inline void ReplaceSelectionCommand::InsertedNodes::WillRemoveNode(Node& node) {
inline void ReplaceSelectionCommand::InsertedNodes::DidReplaceNode(
Node& node,
Node& new_node) {
- if (first_node_inserted_.Get() == node)
+ if (first_node_inserted_ == node)
first_node_inserted_ = &new_node;
- if (last_node_inserted_.Get() == node)
+ if (last_node_inserted_ == node)
last_node_inserted_ = &new_node;
- if (ref_node_.Get() == node)
+ if (ref_node_ == node)
ref_node_ = &new_node;
}
@@ -610,7 +610,7 @@ void ReplaceSelectionCommand::RemoveRedundantStylesAndKeepStyleSpanInline(
// TODO(editing-dev): There is currently no way to update style without
// updating layout. We might want to have updateLifcycleToStyleClean()
// similar to FrameView::updateLifecylceToLayoutClean() in Document.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (blockquote_element)
new_inline_style->RemoveStyleFromRulesAndContext(
@@ -635,7 +635,7 @@ void ReplaceSelectionCommand::RemoveRedundantStylesAndKeepStyleSpanInline(
AtomicString(new_inline_style->Style()->AsText()));
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// FIXME: Tolerate differences in id, class, and style attributes.
if (element->parentNode() && IsNonTableCellHTMLBlockElement(element) &&
@@ -765,7 +765,7 @@ void ReplaceSelectionCommand::MoveElementOutOfAncestor(
if (!HasEditableStyle(*ancestor->parentNode()))
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
VisiblePosition position_at_end_of_node =
CreateVisiblePosition(LastPositionInOrAfterNode(*element));
VisiblePosition last_position_in_paragraph =
@@ -801,7 +801,7 @@ static inline bool NodeHasVisibleLayoutText(Text& text) {
void ReplaceSelectionCommand::RemoveUnrenderedTextNodesAtEnds(
InsertedNodes& inserted_nodes) {
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
auto* last_leaf_inserted = DynamicTo<Text>(inserted_nodes.LastLeafInserted());
if (last_leaf_inserted && !NodeHasVisibleLayoutText(*last_leaf_inserted) &&
@@ -829,7 +829,7 @@ void ReplaceSelectionCommand::RemoveUnrenderedTextNodesAtEnds(
VisiblePosition ReplaceSelectionCommand::PositionAtEndOfInsertedContent()
const {
// TODO(editing-dev): Hoist the call and change it into a DCHECK.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// TODO(yosin): We should set |end_of_inserted_content_| not in SELECT
// element, since contents of SELECT elements, e.g. OPTION, OPTGROUP, are
// not editable, or SELECT element is an atomic on editing.
@@ -846,7 +846,7 @@ VisiblePosition ReplaceSelectionCommand::PositionAtEndOfInsertedContent()
VisiblePosition ReplaceSelectionCommand::PositionAtStartOfInsertedContent()
const {
// TODO(editing-dev): Hoist the call and change it into a DCHECK.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (start_of_inserted_content_.IsOrphan())
return VisiblePosition();
return CreateVisiblePosition(start_of_inserted_content_);
@@ -981,7 +981,7 @@ void ReplaceSelectionCommand::MergeEndIfNeeded(EditingState* editing_state) {
// TODO(editing-dev): Use of UpdateStyleAndLayout()
// needs to be audited. See http://crbug.com/590369 for more details.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
destination = VisiblePosition::BeforeNode(*placeholder);
start_of_paragraph_to_move = CreateVisiblePosition(
@@ -994,7 +994,7 @@ void ReplaceSelectionCommand::MergeEndIfNeeded(EditingState* editing_state) {
if (editing_state->IsAborted())
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// Merging forward will remove end_of_inserted_content from the document.
if (merge_forward) {
@@ -1118,7 +1118,7 @@ void ReplaceSelectionCommand::InsertParagraphSeparatorIfNeeds(
.Build()))
return;
if (fragment.HasInterchangeNewlineAtStart()) {
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
VisiblePosition start_after_delete =
EndingVisibleSelection().VisibleStart();
if (IsEndOfParagraph(start_after_delete) &&
@@ -1149,7 +1149,7 @@ void ReplaceSelectionCommand::InsertParagraphSeparatorIfNeeds(
InsertParagraphSeparator(editing_state);
if (editing_state->IsAborted())
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
}
}
// We split the current paragraph in two to avoid nesting the blocks from
@@ -1174,7 +1174,7 @@ void ReplaceSelectionCommand::InsertParagraphSeparatorIfNeeds(
InsertParagraphSeparator(editing_state);
if (editing_state->IsAborted())
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
SetEndingSelection(SelectionForUndoStep::From(
SelectionInDOMTree::Builder()
.Collapse(
@@ -1205,7 +1205,7 @@ void ReplaceSelectionCommand::DoApply(EditingState* editing_state) {
if (trivial_replace_result)
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
SetUpStyle(selection);
Element* const current_root = selection.RootEditableElement();
@@ -1250,7 +1250,7 @@ void ReplaceSelectionCommand::DoApply(EditingState* editing_state) {
// <div>foo</div> into hello^ world.
PrepareWhitespaceAtPositionForSplit(insertion_pos);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// If the downstream node has been removed there's no point in continuing.
if (!MostForwardCaretPosition(insertion_pos).AnchorNode())
@@ -1305,7 +1305,7 @@ void ReplaceSelectionCommand::DoApply(EditingState* editing_state) {
RemoveHeadContents(fragment);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// We don't want the destination to end up inside nodes that weren't selected.
// To avoid that, we move the position forward without changing the visible
@@ -1421,7 +1421,7 @@ void ReplaceSelectionCommand::DoApply(EditingState* editing_state) {
ABORT_EDITING_COMMAND_IF(!inserted_nodes.RefNode());
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// Mutation events (bug 20161) may have already removed the inserted content
if (!inserted_nodes.FirstNodeInserted() ||
@@ -1454,7 +1454,7 @@ void ReplaceSelectionCommand::DoApply(EditingState* editing_state) {
return;
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (end_br &&
(plain_text_fragment ||
(ShouldRemoveEndBR(end_br, original_vis_pos_before_end_br) &&
@@ -1570,7 +1570,7 @@ void ReplaceSelectionCommand::DoApply(EditingState* editing_state) {
return;
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// Making the two VisiblePositions valid again.
start_of_paragraph_to_move =
@@ -1586,7 +1586,7 @@ void ReplaceSelectionCommand::DoApply(EditingState* editing_state) {
if (editing_state->IsAborted())
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
const VisibleSelection& visible_selection_of_insterted_content =
EndingVisibleSelection();
start_of_inserted_content_ = MostForwardCaretPosition(
@@ -1654,7 +1654,7 @@ void ReplaceSelectionCommand::DoApply(EditingState* editing_state) {
return;
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// Select up to the paragraph separator that was added.
last_position_to_select =
@@ -1772,7 +1772,7 @@ void ReplaceSelectionCommand::AddSpacesForSmartReplace(
}
}
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
VisiblePosition start_of_inserted_content =
PositionAtStartOfInsertedContent();
@@ -1983,7 +1983,7 @@ Node* ReplaceSelectionCommand::InsertAsListItems(HTMLElement* list_element,
IsHTMLListElement(list_element->firstChild()))
list_element = To<HTMLElement>(list_element->firstChild());
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
bool is_start = IsStartOfParagraph(CreateVisiblePosition(insert_pos));
bool is_end = IsEndOfParagraph(CreateVisiblePosition(insert_pos));
bool is_middle = !is_start && !is_end;
@@ -2060,7 +2060,7 @@ bool ReplaceSelectionCommand::PerformTrivialReplace(
// TODO(editing-dev): Use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
Node* node_after_insertion_pos =
MostForwardCaretPosition(EndingSelection().End()).AnchorNode();
@@ -2073,7 +2073,7 @@ bool ReplaceSelectionCommand::PerformTrivialReplace(
if (end.IsNull())
return false;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (node_after_insertion_pos && node_after_insertion_pos->parentNode() &&
IsA<HTMLBRElement>(*node_after_insertion_pos) &&
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 a0b3bd914e9..3913dccb1ce 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
@@ -71,7 +71,7 @@ class CORE_EXPORT ReplaceSelectionCommand final : public CompositeEditCommand {
void WillRemoveNode(Node&);
void DidReplaceNode(Node&, Node& new_node);
- Node* FirstNodeInserted() const { return first_node_inserted_.Get(); }
+ Node* FirstNodeInserted() const { return first_node_inserted_; }
Node* LastLeafInserted() const {
return last_node_inserted_
? &NodeTraversal::LastWithinOrSelf(*last_node_inserted_)
@@ -83,13 +83,13 @@ class CORE_EXPORT ReplaceSelectionCommand final : public CompositeEditCommand {
NodeTraversal::LastWithinOrSelf(*last_node_inserted_))
: nullptr;
}
- Node* RefNode() const { return ref_node_.Get(); }
+ Node* RefNode() const { return ref_node_; }
void SetRefNode(Node* node) { ref_node_ = node; }
private:
- Member<Node> first_node_inserted_;
- Member<Node> last_node_inserted_;
- Member<Node> ref_node_;
+ Node* first_node_inserted_ = nullptr;
+ Node* last_node_inserted_ = nullptr;
+ Node* ref_node_ = nullptr;
};
Node* InsertAsListItems(HTMLElement* list_element,
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/replace_selection_command_test.cc b/chromium/third_party/blink/renderer/core/editing/commands/replace_selection_command_test.cc
index 0f6244a43e3..aaf00dd0f92 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/replace_selection_command_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/replace_selection_command_test.cc
@@ -53,8 +53,7 @@ TEST_F(ReplaceSelectionCommandTest, pastingEmptySpan) {
GetDocument(), fragment, options);
EXPECT_TRUE(command->Apply()) << "the replace command should have succeeded";
- EXPECT_EQ("foo", GetDocument().body()->InnerHTMLAsString())
- << "no DOM tree mutation";
+ EXPECT_EQ("foo", GetDocument().body()->innerHTML()) << "no DOM tree mutation";
}
// This is a regression test for https://crbug.com/668808
@@ -79,7 +78,7 @@ TEST_F(ReplaceSelectionCommandTest, pasteSpanInText) {
GetDocument(), fragment, options);
EXPECT_TRUE(command->Apply()) << "the replace command should have succeeded";
- EXPECT_EQ("<b>t</b>bar<b>ext</b>", GetDocument().body()->InnerHTMLAsString())
+ EXPECT_EQ("<b>t</b>bar<b>ext</b>", GetDocument().body()->innerHTML())
<< "'bar' should have been inserted";
}
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 2a5c7e1ee35..2d8c4ccc459 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
@@ -72,7 +72,7 @@ void SplitTextNodeCommand::DoUnapply() {
String prefix_text = text1_->data();
text2_->insertData(0, prefix_text, ASSERT_NO_EXCEPTION);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
GetDocument().Markers().MoveMarkers(*text1_, prefix_text.length(), *text2_);
text1_->remove(ASSERT_NO_EXCEPTION);
@@ -98,7 +98,7 @@ void SplitTextNodeCommand::InsertText1AndTrimText2() {
if (exception_state.HadException())
return;
text2_->deleteData(0, offset_, exception_state);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
}
void SplitTextNodeCommand::Trace(Visitor* visitor) {
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/style_commands.cc b/chromium/third_party/blink/renderer/core/editing/commands/style_commands.cc
index 00eef3d1f00..7d1900ad7a3 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/style_commands.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/style_commands.cc
@@ -216,8 +216,9 @@ bool StyleCommands::SelectionStartHasStyle(LocalFrame& frame,
frame.Selection().ComputeVisibleSelectionInDOMTreeDeprecated(),
property_id == CSSPropertyID::kBackgroundColor,
style_to_check->Style());
- return style_to_check->TriStateOfStyle(style_at_start, secure_context_mode) !=
- EditingTriState::kFalse;
+ return style_to_check->TriStateOfStyle(
+ frame.GetDocument()->ToExecutionContext(), style_at_start,
+ secure_context_mode) != EditingTriState::kFalse;
}
bool StyleCommands::ExecuteToggleStyle(LocalFrame& frame,
@@ -351,7 +352,7 @@ bool StyleCommands::ExecuteStyleWithCSS(LocalFrame& frame,
EditorCommandSource,
const String& value) {
frame.GetEditor().SetShouldStyleWithCSS(
- !DeprecatedEqualIgnoringCase(value, "false"));
+ !EqualIgnoringASCIICase(value, "false"));
return true;
}
@@ -360,7 +361,7 @@ bool StyleCommands::ExecuteUseCSS(LocalFrame& frame,
EditorCommandSource,
const String& value) {
frame.GetEditor().SetShouldStyleWithCSS(
- DeprecatedEqualIgnoringCase(value, "false"));
+ EqualIgnoringASCIICase(value, "false"));
return true;
}
@@ -368,7 +369,7 @@ bool StyleCommands::ExecuteUseCSS(LocalFrame& frame,
EditingTriState StyleCommands::StateStyle(LocalFrame& frame,
CSSPropertyID property_id,
const char* desired_value) {
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (frame.GetEditor().Behavior().ShouldToggleStyleBasedOnStartOfSelection()) {
return SelectionStartHasStyle(frame, property_id, desired_value)
? EditingTriState::kTrue
@@ -528,7 +529,7 @@ WritingDirection StyleCommands::TextDirectionForSelection(
EditingTriState StyleCommands::StateTextWritingDirection(
LocalFrame& frame,
WritingDirection direction) {
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
bool has_nested_or_multiple_embeddings;
WritingDirection selection_direction = TextDirectionForSelection(
@@ -582,7 +583,7 @@ String StyleCommands::SelectionStartCSSPropertyValue(
}
String StyleCommands::ValueStyle(LocalFrame& frame, CSSPropertyID property_id) {
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// TODO(editing-dev): Rather than retrieving the style at the start of the
// current selection, we should retrieve the style present throughout the
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/typing_command.cc b/chromium/third_party/blink/renderer/core/editing/commands/typing_command.cc
index 99626cccad0..f32727d51fd 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/typing_command.cc
+++ b/chromium/third_party/blink/renderer/core/editing/commands/typing_command.cc
@@ -205,8 +205,9 @@ void TypingCommand::DeleteSelection(Document& document, Options options) {
->Apply();
}
-void TypingCommand::DeleteSelectionIfRange(const VisibleSelection& selection,
- EditingState* editing_state) {
+void TypingCommand::DeleteSelectionIfRange(
+ const SelectionForUndoStep& selection,
+ EditingState* editing_state) {
if (!selection.IsRange())
return;
// Although the 'selection' to delete is indeed a Range, it may have been
@@ -316,7 +317,7 @@ void TypingCommand::AdjustSelectionAfterIncrementalInsertion(
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- frame->GetDocument()->UpdateStyleAndLayout();
+ frame->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
Element* element = frame->Selection()
.ComputeVisibleSelectionInDOMTreeDeprecated()
@@ -383,7 +384,7 @@ void TypingCommand::InsertText(
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- document.UpdateStyleAndLayout();
+ document.UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
const PlainTextRange selection_offsets =
GetSelectionOffsets(selection_for_insertion.AsSelection());
@@ -663,7 +664,7 @@ void TypingCommand::InsertTextRunWithoutNewlines(const String& text,
EditingState* editing_state) {
CompositeEditCommand* command;
if (IsIncrementalInsertion()) {
- command = InsertIncrementalTextCommand::Create(
+ command = MakeGarbageCollected<InsertIncrementalTextCommand>(
GetDocument(), text,
composition_type_ == kTextCompositionNone
? InsertIncrementalTextCommand::
@@ -785,8 +786,8 @@ void TypingCommand::DeleteKeyPressed(TextGranularity granularity,
return;
if (EndingSelection().IsRange()) {
- DeleteKeyPressedInternal(EndingVisibleSelection(), EndingSelection(),
- kill_ring, editing_state);
+ DeleteKeyPressedInternal(EndingSelection(), EndingSelection(), kill_ring,
+ editing_state);
return;
}
@@ -806,7 +807,7 @@ void TypingCommand::DeleteKeyPressed(TextGranularity granularity,
TypingAddedToOpenCommand(kDeleteKey);
smart_delete_ = false;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
SelectionModifier selection_modifier(*frame, EndingSelection().AsSelection());
selection_modifier.SetSelectionIsDirectional(SelectionIsDirectional());
@@ -894,7 +895,7 @@ void TypingCommand::DeleteKeyPressed(TextGranularity granularity,
if (!StartingSelection().IsRange() ||
selection_to_delete.Base() != StartingSelection().Start()) {
DeleteKeyPressedInternal(
- selection_to_delete,
+ SelectionForUndoStep::From(selection_to_delete.AsSelection()),
SelectionForUndoStep::From(selection_to_delete.AsSelection()),
kill_ring, editing_state);
return;
@@ -908,12 +909,13 @@ void TypingCommand::DeleteKeyPressed(TextGranularity granularity,
CreateVisiblePosition(selection_to_delete.Extent())
.DeepEquivalent())
.Build();
- DeleteKeyPressedInternal(selection_to_delete, selection_after_undo, kill_ring,
- editing_state);
+ DeleteKeyPressedInternal(
+ SelectionForUndoStep::From(selection_to_delete.AsSelection()),
+ selection_after_undo, kill_ring, editing_state);
}
void TypingCommand::DeleteKeyPressedInternal(
- const VisibleSelection& selection_to_delete,
+ const SelectionForUndoStep& selection_to_delete,
const SelectionForUndoStep& selection_after_undo,
bool kill_ring,
EditingState* editing_state) {
@@ -927,9 +929,10 @@ void TypingCommand::DeleteKeyPressedInternal(
LocalFrame* frame = GetDocument().GetFrame();
DCHECK(frame);
- if (kill_ring)
- frame->GetEditor().AddToKillRing(
- selection_to_delete.ToNormalizedEphemeralRange());
+ if (kill_ring) {
+ frame->GetEditor().AddToKillRing(CreateVisibleSelection(selection_to_delete)
+ .ToNormalizedEphemeralRange());
+ }
// On Mac, make undo select everything that has been deleted, unless an undo
// will undo more than just this deletion.
// FIXME: This behaves like TextEdit except for the case where you open with
@@ -969,7 +972,7 @@ void TypingCommand::ForwardDeleteKeyPressed(TextGranularity granularity,
return;
if (EndingSelection().IsRange()) {
- ForwardDeleteKeyPressedInternal(EndingVisibleSelection(), EndingSelection(),
+ ForwardDeleteKeyPressedInternal(EndingSelection(), EndingSelection(),
kill_ring, editing_state);
return;
}
@@ -980,7 +983,7 @@ void TypingCommand::ForwardDeleteKeyPressed(TextGranularity granularity,
}
smart_delete_ = false;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// Handle delete at beginning-of-block case.
// Do nothing in the case that the caret is at the start of a
@@ -1041,7 +1044,7 @@ void TypingCommand::ForwardDeleteKeyPressed(TextGranularity granularity,
MostBackwardCaretPosition(selection_to_delete.Base()) !=
StartingSelection().Start()) {
ForwardDeleteKeyPressedInternal(
- selection_to_delete,
+ SelectionForUndoStep::From(selection_to_delete.AsSelection()),
SelectionForUndoStep::From(selection_to_delete.AsSelection()),
kill_ring, editing_state);
return;
@@ -1054,12 +1057,13 @@ void TypingCommand::ForwardDeleteKeyPressed(TextGranularity granularity,
ComputeExtentForForwardDeleteUndo(selection_to_delete,
StartingSelection().End()))
.Build();
- ForwardDeleteKeyPressedInternal(selection_to_delete, selection_after_undo,
- kill_ring, editing_state);
+ ForwardDeleteKeyPressedInternal(
+ SelectionForUndoStep::From(selection_to_delete.AsSelection()),
+ selection_after_undo, kill_ring, editing_state);
}
void TypingCommand::ForwardDeleteKeyPressedInternal(
- const VisibleSelection& selection_to_delete,
+ const SelectionForUndoStep& selection_to_delete,
const SelectionForUndoStep& selection_after_undo,
bool kill_ring,
EditingState* editing_state) {
@@ -1073,9 +1077,10 @@ void TypingCommand::ForwardDeleteKeyPressedInternal(
LocalFrame* frame = GetDocument().GetFrame();
DCHECK(frame);
- if (kill_ring)
- frame->GetEditor().AddToKillRing(
- selection_to_delete.ToNormalizedEphemeralRange());
+ if (kill_ring) {
+ frame->GetEditor().AddToKillRing(CreateVisibleSelection(selection_to_delete)
+ .ToNormalizedEphemeralRange());
+ }
// Make undo select what was deleted on Mac alone
if (frame->GetEditor().Behavior().ShouldUndoOfDeleteSelectText())
SetStartingSelection(selection_after_undo);
diff --git a/chromium/third_party/blink/renderer/core/editing/commands/typing_command.h b/chromium/third_party/blink/renderer/core/editing/commands/typing_command.h
index 28a13a44582..cfec38f07c5 100644
--- a/chromium/third_party/blink/renderer/core/editing/commands/typing_command.h
+++ b/chromium/third_party/blink/renderer/core/editing/commands/typing_command.h
@@ -145,15 +145,15 @@ class CORE_EXPORT TypingCommand final : public CompositeEditCommand {
bool IsIncrementalInsertion() const { return is_incremental_insertion_; }
void DeleteKeyPressedInternal(
- const VisibleSelection& selection_to_delete,
+ const SelectionForUndoStep& selection_to_delete,
const SelectionForUndoStep& selection_after_undo,
bool kill_ring,
EditingState*);
- void DeleteSelectionIfRange(const VisibleSelection&, EditingState*);
+ void DeleteSelectionIfRange(const SelectionForUndoStep&, EditingState*);
void ForwardDeleteKeyPressedInternal(
- const VisibleSelection& selection_to_delete,
+ const SelectionForUndoStep& selection_to_delete,
const SelectionForUndoStep& selection_after_undo,
bool kill_ring,
EditingState*);
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 8d11cf65807..e1a71e04ee7 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
@@ -44,7 +44,7 @@ void UndoStep::Unapply() {
// operations, like RemoveNodeCommand, don't require a layout because the high
// level operations that use them perform one if one is necessary (like for
// the creation of VisiblePositions).
- document_->UpdateStyleAndLayout();
+ document_->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
{
wtf_size_t size = commands_.size();
@@ -86,7 +86,7 @@ void UndoStep::Reapply() {
// operations, like RemoveNodeCommand, don't require a layout because the high
// level operations that use them perform one if one is necessary (like for
// the creation of VisiblePositions).
- document_->UpdateStyleAndLayout();
+ document_->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
{
for (const auto& command : commands_)
diff --git a/chromium/third_party/blink/renderer/core/editing/compute_layer_selection.cc b/chromium/third_party/blink/renderer/core/editing/compute_layer_selection.cc
index 17a681396fd..2526b31ad76 100644
--- a/chromium/third_party/blink/renderer/core/editing/compute_layer_selection.cc
+++ b/chromium/third_party/blink/renderer/core/editing/compute_layer_selection.cc
@@ -245,6 +245,11 @@ EndPositionInGraphicsLayerBacking(const SelectionInDOMTree& selection) {
cc::LayerSelection ComputeLayerSelection(
const FrameSelection& frame_selection) {
+ // TODO(https://crbug.com/1065049) - Implement layer selection for
+ // CompositeAfterPaint
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ return {};
+
if (!frame_selection.IsHandleVisible() || frame_selection.IsHidden())
return {};
diff --git a/chromium/third_party/blink/renderer/core/editing/compute_layer_selection_test.cc b/chromium/third_party/blink/renderer/core/editing/compute_layer_selection_test.cc
index f0062e79597..30ff7dd81d1 100644
--- a/chromium/third_party/blink/renderer/core/editing/compute_layer_selection_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/compute_layer_selection_test.cc
@@ -121,7 +121,8 @@ TEST_F(ComputeLayerSelectionTest, PositionInScrollableRoot) {
To<HTMLInputElement>(GetDocument().getElementById("target")));
ScrollableArea* root_scroller = GetDocument().View()->GetScrollableArea();
- root_scroller->SetScrollOffset(ScrollOffset(800, 500), kProgrammaticScroll);
+ root_scroller->SetScrollOffset(ScrollOffset(800, 500),
+ mojom::blink::ScrollType::kProgrammatic);
ASSERT_EQ(ScrollOffset(800, 500), root_scroller->GetScrollOffset());
UpdateAllLifecyclePhasesForTest();
@@ -185,7 +186,8 @@ TEST_F(ComputeLayerSelectionTest, PositionInScroller) {
Element* e = GetDocument().getElementById("scroller");
PaintLayerScrollableArea* scroller =
ToLayoutBox(e->GetLayoutObject())->GetScrollableArea();
- scroller->SetScrollOffset(ScrollOffset(900, 800), kProgrammaticScroll);
+ scroller->SetScrollOffset(ScrollOffset(900, 800),
+ mojom::blink::ScrollType::kProgrammatic);
ASSERT_EQ(ScrollOffset(900, 800), scroller->GetScrollOffset());
UpdateAllLifecyclePhasesForTest();
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 862ff5be65b..5c6960cbb03 100644
--- a/chromium/third_party/blink/renderer/core/editing/dom_selection.cc
+++ b/chromium/third_party/blink/renderer/core/editing/dom_selection.cc
@@ -46,6 +46,7 @@
#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/platform/bindings/exception_state.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/wtf_string.h"
@@ -66,7 +67,7 @@ static Node* SelectionShadowAncestor(LocalFrame* frame) {
}
DOMSelection::DOMSelection(const TreeScope* tree_scope)
- : ContextClient(tree_scope->RootNode().GetDocument().GetFrame()),
+ : ExecutionContextClient(tree_scope->RootNode().GetDocument().GetFrame()),
tree_scope_(tree_scope) {}
void DOMSelection::ClearTreeScope() {
@@ -411,50 +412,51 @@ void DOMSelection::modify(const String& alter_string,
return;
SelectionModifyAlteration alter;
- if (DeprecatedEqualIgnoringCase(alter_string, "extend"))
+ if (EqualIgnoringASCIICase(alter_string, "extend"))
alter = SelectionModifyAlteration::kExtend;
- else if (DeprecatedEqualIgnoringCase(alter_string, "move"))
+ else if (EqualIgnoringASCIICase(alter_string, "move"))
alter = SelectionModifyAlteration::kMove;
else
return;
SelectionModifyDirection direction;
- if (DeprecatedEqualIgnoringCase(direction_string, "forward"))
+ if (EqualIgnoringASCIICase(direction_string, "forward"))
direction = SelectionModifyDirection::kForward;
- else if (DeprecatedEqualIgnoringCase(direction_string, "backward"))
+ else if (EqualIgnoringASCIICase(direction_string, "backward"))
direction = SelectionModifyDirection::kBackward;
- else if (DeprecatedEqualIgnoringCase(direction_string, "left"))
+ else if (EqualIgnoringASCIICase(direction_string, "left"))
direction = SelectionModifyDirection::kLeft;
- else if (DeprecatedEqualIgnoringCase(direction_string, "right"))
+ else if (EqualIgnoringASCIICase(direction_string, "right"))
direction = SelectionModifyDirection::kRight;
else
return;
TextGranularity granularity;
- if (DeprecatedEqualIgnoringCase(granularity_string, "character"))
+ if (EqualIgnoringASCIICase(granularity_string, "character"))
granularity = TextGranularity::kCharacter;
- else if (DeprecatedEqualIgnoringCase(granularity_string, "word"))
+ else if (EqualIgnoringASCIICase(granularity_string, "word"))
granularity = TextGranularity::kWord;
- else if (DeprecatedEqualIgnoringCase(granularity_string, "sentence"))
+ else if (EqualIgnoringASCIICase(granularity_string, "sentence"))
granularity = TextGranularity::kSentence;
- else if (DeprecatedEqualIgnoringCase(granularity_string, "line"))
+ else if (EqualIgnoringASCIICase(granularity_string, "line"))
granularity = TextGranularity::kLine;
- else if (DeprecatedEqualIgnoringCase(granularity_string, "paragraph"))
+ else if (EqualIgnoringASCIICase(granularity_string, "paragraph"))
granularity = TextGranularity::kParagraph;
- else if (DeprecatedEqualIgnoringCase(granularity_string, "lineboundary"))
+ else if (EqualIgnoringASCIICase(granularity_string, "lineboundary"))
granularity = TextGranularity::kLineBoundary;
- else if (DeprecatedEqualIgnoringCase(granularity_string, "sentenceboundary"))
+ else if (EqualIgnoringASCIICase(granularity_string, "sentenceboundary"))
granularity = TextGranularity::kSentenceBoundary;
- else if (DeprecatedEqualIgnoringCase(granularity_string, "paragraphboundary"))
+ else if (EqualIgnoringASCIICase(granularity_string, "paragraphboundary"))
granularity = TextGranularity::kParagraphBoundary;
- else if (DeprecatedEqualIgnoringCase(granularity_string, "documentboundary"))
+ else if (EqualIgnoringASCIICase(granularity_string, "documentboundary"))
granularity = TextGranularity::kDocumentBoundary;
else
return;
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kSelection);
Element* focused_element = GetFrame()->GetDocument()->FocusedElement();
GetFrame()->Selection().Modify(alter, direction, granularity,
@@ -688,7 +690,8 @@ void DOMSelection::deleteFromDocument() {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kSelection);
// The following code is necessary for
// editing/selection/deleteFromDocument-crash.html, which assumes
@@ -724,7 +727,8 @@ bool DOMSelection::containsNode(const Node* n, bool allow_partial) const {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
// |VisibleSelection::toNormalizedEphemeralRange| requires clean layout.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kSelection);
FrameSelection& selection = GetFrame()->Selection();
const EphemeralRange selected_range =
@@ -784,7 +788,8 @@ String DOMSelection::toString() {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kSelection);
DocumentLifecycle::DisallowTransitionScope disallow_transition(
GetFrame()->GetDocument()->Lifecycle());
@@ -842,15 +847,16 @@ bool DOMSelection::IsValidForPosition(Node* node) const {
void DOMSelection::AddConsoleWarning(const String& message) {
if (tree_scope_) {
tree_scope_->GetDocument().AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning, message));
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning, message));
}
}
void DOMSelection::Trace(Visitor* visitor) {
visitor->Trace(tree_scope_);
ScriptWrappable::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 4d7dd9b8d34..f3a9e52c76e 100644
--- a/chromium/third_party/blink/renderer/core/editing/dom_selection.h
+++ b/chromium/third_party/blink/renderer/core/editing/dom_selection.h
@@ -31,7 +31,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_DOM_SELECTION_H_
#include "third_party/blink/renderer/core/editing/forward.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/heap/handle.h"
@@ -46,7 +46,7 @@ class SetSelectionOptions;
class TreeScope;
class CORE_EXPORT DOMSelection final : public ScriptWrappable,
- public ContextClient {
+ public ExecutionContextClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(DOMSelection);
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 c368dd36eb2..d29c09c69fb 100644
--- a/chromium/third_party/blink/renderer/core/editing/drag_caret.cc
+++ b/chromium/third_party/blink/renderer/core/editing/drag_caret.cc
@@ -66,7 +66,7 @@ void DragCaret::SetCaretPosition(const PositionWithAffinity& position) {
Document* document = nullptr;
if (Node* node = position_.AnchorNode()) {
document = &node->GetDocument();
- SetContext(document);
+ SetDocument(document);
}
}
diff --git a/chromium/third_party/blink/renderer/core/editing/editing_behavior.cc b/chromium/third_party/blink/renderer/core/editing/editing_behavior.cc
index e47785874e6..b10407a84d6 100644
--- a/chromium/third_party/blink/renderer/core/editing/editing_behavior.cc
+++ b/chromium/third_party/blink/renderer/core/editing/editing_behavior.cc
@@ -27,7 +27,7 @@
#include "third_party/blink/renderer/core/editing/editing_behavior.h"
#include "build/build_config.h"
-#include "third_party/blink/public/platform/web_input_event.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/public/web/web_settings.h"
#include "third_party/blink/renderer/core/events/keyboard_event.h"
#include "third_party/blink/renderer/platform/keyboard_codes.h"
@@ -177,6 +177,10 @@ const KeyboardCodeKeyDownEntry kKeyboardCodeKeyDownEntries[] = {
{'Z', kCtrlKey | kShiftKey, "Redo"},
{'Y', kCtrlKey, "Redo"},
#endif
+#if defined(OS_WIN)
+ {VKEY_BACK, kAltKey, "Undo"},
+ {VKEY_BACK, kAltKey | kShiftKey, "Redo"},
+#endif
{VKEY_INSERT, 0, "OverWrite"},
};
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 645205a7471..2a3acb5cf40 100644
--- a/chromium/third_party/blink/renderer/core/editing/editing_style.cc
+++ b/chromium/third_party/blink/renderer/core/editing/editing_style.cc
@@ -96,12 +96,13 @@ enum EditingPropertiesType {
kAllEditingProperties
};
-static const Vector<const CSSProperty*>& AllEditingProperties() {
+static const Vector<const CSSProperty*>& AllEditingProperties(
+ const ExecutionContext* execution_context) {
DEFINE_STATIC_LOCAL(Vector<const CSSProperty*>, properties, ());
if (properties.IsEmpty()) {
CSSProperty::FilterWebExposedCSSPropertiesIntoVector(
- kStaticEditingProperties, base::size(kStaticEditingProperties),
- properties);
+ execution_context, kStaticEditingProperties,
+ base::size(kStaticEditingProperties), properties);
for (wtf_size_t index = 0; index < properties.size(); index++) {
if (properties[index]->IDEquals(CSSPropertyID::kTextDecoration)) {
properties.EraseAt(index);
@@ -112,12 +113,13 @@ static const Vector<const CSSProperty*>& AllEditingProperties() {
return properties;
}
-static const Vector<const CSSProperty*>& InheritableEditingProperties() {
+static const Vector<const CSSProperty*>& InheritableEditingProperties(
+ const ExecutionContext* execution_context) {
DEFINE_STATIC_LOCAL(Vector<const CSSProperty*>, properties, ());
if (properties.IsEmpty()) {
CSSProperty::FilterWebExposedCSSPropertiesIntoVector(
- kStaticEditingProperties, base::size(kStaticEditingProperties),
- properties);
+ execution_context, kStaticEditingProperties,
+ base::size(kStaticEditingProperties), properties);
for (wtf_size_t index = 0; index < properties.size();) {
if (!properties[index]->IsInherited()) {
properties.EraseAt(index);
@@ -131,15 +133,19 @@ static const Vector<const CSSProperty*>& InheritableEditingProperties() {
template <class StyleDeclarationType>
static MutableCSSPropertyValueSet* CopyEditingProperties(
+ const ExecutionContext* execution_context,
StyleDeclarationType* style,
EditingPropertiesType type = kOnlyInheritableEditingProperties) {
if (type == kAllEditingProperties)
- return style->CopyPropertiesInSet(AllEditingProperties());
- return style->CopyPropertiesInSet(InheritableEditingProperties());
+ return style->CopyPropertiesInSet(AllEditingProperties(execution_context));
+ return style->CopyPropertiesInSet(
+ InheritableEditingProperties(execution_context));
}
-static inline bool IsEditingProperty(CSSPropertyID id) {
- static const Vector<const CSSProperty*>& properties = AllEditingProperties();
+static inline bool IsEditingProperty(ExecutionContext* execution_context,
+ CSSPropertyID id) {
+ static const Vector<const CSSProperty*>& properties =
+ AllEditingProperties(execution_context);
for (wtf_size_t index = 0; index < properties.size(); index++) {
if (properties[index]->IDEquals(id))
return true;
@@ -504,7 +510,9 @@ void EditingStyle::Init(Node* node, PropertiesToInclude properties_to_include) {
mutable_style_ =
properties_to_include == kAllProperties && computed_style_at_position
? computed_style_at_position->CopyProperties()
- : CopyEditingProperties(computed_style_at_position);
+ : CopyEditingProperties(
+ node ? node->GetDocument().ToExecutionContext() : nullptr,
+ computed_style_at_position);
if (properties_to_include == kEditingPropertiesInEffect) {
if (const CSSValue* value =
@@ -700,23 +708,26 @@ static const CSSPropertyID kStaticBlockProperties[] = {
CSSPropertyID::kTextAlignLast, CSSPropertyID::kTextIndent,
CSSPropertyID::kTextJustify, CSSPropertyID::kWidows};
-static const Vector<const CSSProperty*>& BlockPropertiesVector() {
+static const Vector<const CSSProperty*>& BlockPropertiesVector(
+ const ExecutionContext* execution_context) {
DEFINE_STATIC_LOCAL(Vector<const CSSProperty*>, properties, ());
if (properties.IsEmpty()) {
CSSProperty::FilterWebExposedCSSPropertiesIntoVector(
- kStaticBlockProperties, base::size(kStaticBlockProperties), properties);
+ execution_context, kStaticBlockProperties,
+ base::size(kStaticBlockProperties), properties);
}
return properties;
}
-EditingStyle* EditingStyle::ExtractAndRemoveBlockProperties() {
+EditingStyle* EditingStyle::ExtractAndRemoveBlockProperties(
+ const ExecutionContext* execution_context) {
EditingStyle* block_properties = MakeGarbageCollected<EditingStyle>();
if (!mutable_style_)
return block_properties;
- block_properties->mutable_style_ =
- mutable_style_->CopyPropertiesInSet(BlockPropertiesVector());
- RemoveBlockProperties();
+ block_properties->mutable_style_ = mutable_style_->CopyPropertiesInSet(
+ BlockPropertiesVector(execution_context));
+ RemoveBlockProperties(execution_context);
return block_properties;
}
@@ -742,21 +753,25 @@ EditingStyle* EditingStyle::ExtractAndRemoveTextDirection(
return text_direction;
}
-void EditingStyle::RemoveBlockProperties() {
+void EditingStyle::RemoveBlockProperties(
+ const ExecutionContext* execution_context) {
if (!mutable_style_)
return;
- mutable_style_->RemovePropertiesInSet(BlockPropertiesVector().data(),
- BlockPropertiesVector().size());
+ mutable_style_->RemovePropertiesInSet(
+ BlockPropertiesVector(execution_context).data(),
+ BlockPropertiesVector(execution_context).size());
}
void EditingStyle::RemoveStyleAddedByElement(Element* element) {
if (!element || !element->parentNode())
return;
MutableCSSPropertyValueSet* parent_style = CopyEditingProperties(
+ element->parentNode()->GetDocument().ToExecutionContext(),
MakeGarbageCollected<CSSComputedStyleDeclaration>(element->parentNode()),
kAllEditingProperties);
MutableCSSPropertyValueSet* node_style = CopyEditingProperties(
+ element->GetDocument().ToExecutionContext(),
MakeGarbageCollected<CSSComputedStyleDeclaration>(element),
kAllEditingProperties);
node_style->RemoveEquivalentProperties(parent_style);
@@ -768,9 +783,11 @@ void EditingStyle::RemoveStyleConflictingWithStyleOfElement(Element* element) {
return;
MutableCSSPropertyValueSet* parent_style = CopyEditingProperties(
+ element->parentNode()->GetDocument().ToExecutionContext(),
MakeGarbageCollected<CSSComputedStyleDeclaration>(element->parentNode()),
kAllEditingProperties);
MutableCSSPropertyValueSet* node_style = CopyEditingProperties(
+ element->GetDocument().ToExecutionContext(),
MakeGarbageCollected<CSSComputedStyleDeclaration>(element),
kAllEditingProperties);
node_style->RemoveEquivalentProperties(parent_style);
@@ -804,12 +821,14 @@ void EditingStyle::CollapseTextDecorationProperties(
}
EditingTriState EditingStyle::TriStateOfStyle(
+ ExecutionContext* execution_context,
EditingStyle* style,
SecureContextMode secure_context_mode) const {
if (!style || !style->mutable_style_)
return EditingTriState::kFalse;
- return TriStateOfStyle(style->mutable_style_->EnsureCSSStyleDeclaration(),
- kDoNotIgnoreTextOnlyProperties, secure_context_mode);
+ return TriStateOfStyle(
+ style->mutable_style_->EnsureCSSStyleDeclaration(execution_context),
+ kDoNotIgnoreTextOnlyProperties, secure_context_mode);
}
EditingTriState EditingStyle::TriStateOfStyle(
@@ -852,6 +871,7 @@ EditingTriState EditingStyle::TriStateOfStyle(
if (selection.IsCaret()) {
return TriStateOfStyle(
+ selection.Start().GetDocument()->ToExecutionContext(),
EditingStyleUtilities::CreateStyleAtSelectionStart(selection),
secure_context_mode);
}
@@ -1179,7 +1199,8 @@ bool EditingStyle::ElementIsStyledSpanOrHTMLEquivalent(
if (const CSSPropertyValueSet* style = element->InlineStyle()) {
unsigned property_count = style->PropertyCount();
for (unsigned i = 0; i < property_count; ++i) {
- if (!IsEditingProperty(style->PropertyAt(i).Id()))
+ if (!IsEditingProperty(element->GetDocument().ToExecutionContext(),
+ style->PropertyAt(i).Id()))
return false;
}
}
@@ -1265,13 +1286,15 @@ void EditingStyle::MergeInlineStyleOfElement(
MergeStyle(element->InlineStyle(), mode);
return;
case kOnlyEditingInheritableProperties:
- MergeStyle(CopyEditingProperties(element->InlineStyle(),
- kOnlyInheritableEditingProperties),
+ MergeStyle(CopyEditingProperties(
+ element->GetDocument().ToExecutionContext(),
+ element->InlineStyle(), kOnlyInheritableEditingProperties),
mode);
return;
case kEditingPropertiesInEffect:
MergeStyle(
- CopyEditingProperties(element->InlineStyle(), kAllEditingProperties),
+ CopyEditingProperties(element->GetDocument().ToExecutionContext(),
+ element->InlineStyle(), kAllEditingProperties),
mode);
return;
}
@@ -1290,6 +1313,7 @@ static inline bool ElementMatchesAndPropertyIsNotInInlineStyleDecl(
}
static MutableCSSPropertyValueSet* ExtractEditingProperties(
+ const ExecutionContext* execution_context,
const CSSPropertyValueSet* style,
EditingStyle::PropertiesToInclude properties_to_include) {
if (!style)
@@ -1298,9 +1322,11 @@ static MutableCSSPropertyValueSet* ExtractEditingProperties(
switch (properties_to_include) {
case EditingStyle::kAllProperties:
case EditingStyle::kEditingPropertiesInEffect:
- return CopyEditingProperties(style, kAllEditingProperties);
+ return CopyEditingProperties(execution_context, style,
+ kAllEditingProperties);
case EditingStyle::kOnlyEditingInheritableProperties:
- return CopyEditingProperties(style, kOnlyInheritableEditingProperties);
+ return CopyEditingProperties(execution_context, style,
+ kOnlyInheritableEditingProperties);
}
NOTREACHED();
@@ -1319,6 +1345,7 @@ void EditingStyle::MergeInlineAndImplicitStyleOfElement(
element->InlineStyle());
style_from_rules->mutable_style_ = ExtractEditingProperties(
+ element->GetDocument().ToExecutionContext(),
style_from_rules->mutable_style_.Get(), properties_to_include);
MergeStyle(style_from_rules->mutable_style_.Get(), mode);
@@ -1493,10 +1520,11 @@ void EditingStyle::RemoveStyleFromRulesAndContext(Element* element,
StyleFromMatchedRulesForElement(element,
StyleResolver::kAllButEmptyCSSRules);
if (style_from_matched_rules && !style_from_matched_rules->IsEmpty()) {
- mutable_style_ = GetPropertiesNotIn(
- mutable_style_.Get(),
- style_from_matched_rules->EnsureCSSStyleDeclaration(),
- secure_context_mode);
+ mutable_style_ =
+ GetPropertiesNotIn(mutable_style_.Get(),
+ style_from_matched_rules->EnsureCSSStyleDeclaration(
+ element->GetDocument().ToExecutionContext()),
+ secure_context_mode);
}
// 2. Remove style present in context and not overriden by matched rules.
@@ -1513,7 +1541,8 @@ void EditingStyle::RemoveStyleFromRulesAndContext(Element* element,
style_from_matched_rules);
mutable_style_ = GetPropertiesNotIn(
mutable_style_.Get(),
- computed_style->mutable_style_->EnsureCSSStyleDeclaration(),
+ computed_style->mutable_style_->EnsureCSSStyleDeclaration(
+ element->GetDocument().ToExecutionContext()),
secure_context_mode);
}
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 9700794ebce..23815f2e154 100644
--- a/chromium/third_party/blink/renderer/core/editing/editing_style.h
+++ b/chromium/third_party/blink/renderer/core/editing/editing_style.h
@@ -48,6 +48,7 @@ class CSSComputedStyleDeclaration;
class ContainerNode;
class Document;
class Element;
+class ExecutionContext;
class HTMLElement;
class LocalFrame;
class MutableCSSPropertyValueSet;
@@ -90,9 +91,9 @@ class CORE_EXPORT EditingStyle final : public GarbageCollected<EditingStyle> {
void OverrideWithStyle(const CSSPropertyValueSet*);
void Clear();
EditingStyle* Copy() const;
- EditingStyle* ExtractAndRemoveBlockProperties();
+ EditingStyle* ExtractAndRemoveBlockProperties(const ExecutionContext*);
EditingStyle* ExtractAndRemoveTextDirection(SecureContextMode);
- void RemoveBlockProperties();
+ void RemoveBlockProperties(const ExecutionContext*);
void RemoveStyleAddedByElement(Element*);
void RemoveStyleConflictingWithStyleOfElement(Element*);
void CollapseTextDecorationProperties(SecureContextMode);
@@ -100,7 +101,9 @@ class CORE_EXPORT EditingStyle final : public GarbageCollected<EditingStyle> {
kIgnoreTextOnlyProperties,
kDoNotIgnoreTextOnlyProperties
};
- EditingTriState TriStateOfStyle(EditingStyle*, SecureContextMode) const;
+ EditingTriState TriStateOfStyle(ExecutionContext*,
+ EditingStyle*,
+ SecureContextMode) const;
EditingTriState TriStateOfStyle(const VisibleSelection&,
SecureContextMode) const;
bool ConflictsWithInlineStyleOfElement(HTMLElement* element) const {
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 6def00469d7..d198257b409 100644
--- a/chromium/third_party/blink/renderer/core/editing/editing_utilities.cc
+++ b/chromium/third_party/blink/renderer/core/editing/editing_utilities.cc
@@ -64,6 +64,7 @@
#include "third_party/blink/renderer/core/html/html_span_element.h"
#include "third_party/blink/renderer/core/html/html_table_cell_element.h"
#include "third_party/blink/renderer/core/html/html_ulist_element.h"
+#include "third_party/blink/renderer/core/html/image_document.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/core/html_element_factory.h"
#include "third_party/blink/renderer/core/html_names.h"
@@ -1246,7 +1247,7 @@ bool IsDisplayInsideTable(const Node* node) {
bool IsTableCell(const Node* node) {
DCHECK(node);
LayoutObject* r = node->GetLayoutObject();
- return r ? r->IsTableCell() : IsHTMLTableCellElement(*node);
+ return r ? r->IsTableCell() : IsA<HTMLTableCellElement>(*node);
}
HTMLElement* CreateDefaultParagraphElement(Document& document) {
@@ -1580,7 +1581,7 @@ FloatQuad LocalToAbsoluteQuadOf(const LocalCaretRect& caret_rect) {
const StaticRangeVector* TargetRangesForInputEvent(const Node& node) {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- node.GetDocument().UpdateStyleAndLayout();
+ node.GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (!HasRichlyEditableStyle(node))
return nullptr;
const EphemeralRange& range =
@@ -1725,15 +1726,16 @@ AtomicString GetUrlStringFromNode(const Node& node) {
return AtomicString();
}
-void WriteImageNodeToClipboard(const Node& node, const String& title) {
+void WriteImageNodeToClipboard(SystemClipboard& system_clipboard,
+ const Node& node,
+ const String& title) {
const scoped_refptr<Image> image = ImageFromNode(node);
if (!image.get())
return;
const KURL url_string = node.GetDocument().CompleteURL(
StripLeadingAndTrailingHTMLSpaces(GetUrlStringFromNode(node)));
- SystemClipboard::GetInstance().WriteImageWithTag(image.get(), url_string,
- title);
- SystemClipboard::GetInstance().CommitWrite();
+ system_clipboard.WriteImageWithTag(image.get(), url_string, title);
+ system_clipboard.CommitWrite();
}
Element* FindEventTargetFrom(LocalFrame& frame,
@@ -1749,7 +1751,7 @@ Element* FindEventTargetFrom(LocalFrame& frame,
HTMLImageElement* ImageElementFromImageDocument(const Document* document) {
if (!document)
return nullptr;
- if (!document->IsImageDocument())
+ if (!IsA<ImageDocument>(document))
return nullptr;
const HTMLElement* const body = document->body();
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 e2e9992852f..5597e7282e2 100644
--- a/chromium/third_party/blink/renderer/core/editing/editing_utilities.h
+++ b/chromium/third_party/blink/renderer/core/editing/editing_utilities.h
@@ -56,6 +56,7 @@ class HTMLElement;
class HTMLSpanElement;
struct LocalCaretRect;
class Node;
+class SystemClipboard;
// This file contains a set of helper functions used by the editing commands
@@ -136,7 +137,7 @@ inline ContainerNode* ParentCrossingShadowBoundaries<EditingInFlatTreeStrategy>(
return FlatTreeTraversal::Parent(node);
}
-void WriteImageNodeToClipboard(const Node&, const String&);
+void WriteImageNodeToClipboard(SystemClipboard&, const Node&, const String&);
// boolean functions on Node
diff --git a/chromium/third_party/blink/renderer/core/editing/editing_utilities_test.cc b/chromium/third_party/blink/renderer/core/editing/editing_utilities_test.cc
index de55c5bf706..3c3a5ea8955 100644
--- a/chromium/third_party/blink/renderer/core/editing/editing_utilities_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/editing_utilities_test.cc
@@ -127,7 +127,7 @@ TEST_F(EditingUtilitiesTest, isEditablePositionWithTable) {
// element. So, we build DOM tree manually.
// Note: This is unusual HTML taken from http://crbug.com/574230
Element* table = GetDocument().CreateRawElement(html_names::kTableTag);
- table->SetInnerHTMLFromString("<caption>foo</caption>");
+ table->setInnerHTML("<caption>foo</caption>");
while (GetDocument().firstChild())
GetDocument().firstChild()->remove();
GetDocument().AppendChild(table);
diff --git a/chromium/third_party/blink/renderer/core/editing/editor.cc b/chromium/third_party/blink/renderer/core/editing/editor.cc
index 5d656f31189..b27d63b98a8 100644
--- a/chromium/third_party/blink/renderer/core/editing/editor.cc
+++ b/chromium/third_party/blink/renderer/core/editing/editor.cc
@@ -26,7 +26,6 @@
#include "third_party/blink/renderer/core/editing/editor.h"
-#include "third_party/blink/public/platform/web_scroll_into_view_params.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
#include "third_party/blink/renderer/core/clipboard/data_object.h"
#include "third_party/blink/renderer/core/clipboard/data_transfer.h"
@@ -175,7 +174,7 @@ bool Editor::HandleTextEvent(TextEvent* event) {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- frame_->GetDocument()->UpdateStyleAndLayout();
+ frame_->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (event->IsPaste()) {
if (event->PastingFragment()) {
@@ -236,7 +235,7 @@ bool Editor::CanCopy() const {
FrameSelection& selection = GetFrameSelection();
if (!selection.IsAvailable())
return false;
- frame_->GetDocument()->UpdateStyleAndLayout();
+ frame_->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
const VisibleSelectionInFlatTree& visible_selection =
selection.ComputeVisibleSelectionInFlatTree();
return visible_selection.IsRange() &&
@@ -502,7 +501,7 @@ bool Editor::InsertTextWithoutSendingTextEvent(
LocalFrame* focused_or_main_frame =
To<LocalFrame>(page->GetFocusController().FocusedOrMainFrame());
focused_or_main_frame->Selection().RevealSelection(
- ScrollAlignment::kAlignToEdgeIfNeeded);
+ ScrollAlignment::ToEdgeIfNeeded());
}
}
@@ -518,7 +517,7 @@ bool Editor::InsertLineBreak() {
DCHECK(GetFrame().GetDocument());
if (!TypingCommand::InsertLineBreak(*GetFrame().GetDocument()))
return false;
- RevealSelectionAfterEditingOperation(ScrollAlignment::kAlignToEdgeIfNeeded);
+ RevealSelectionAfterEditingOperation(ScrollAlignment::ToEdgeIfNeeded());
return true;
}
@@ -536,7 +535,7 @@ bool Editor::InsertParagraphSeparator() {
EditingState editing_state;
if (!TypingCommand::InsertParagraphSeparator(*GetFrame().GetDocument()))
return false;
- RevealSelectionAfterEditingOperation(ScrollAlignment::kAlignToEdgeIfNeeded);
+ RevealSelectionAfterEditingOperation(ScrollAlignment::ToEdgeIfNeeded());
return true;
}
@@ -612,7 +611,8 @@ void Editor::CountEvent(ExecutionContext* execution_context,
}
void Editor::CopyImage(const HitTestResult& result) {
- WriteImageNodeToClipboard(*result.InnerNodeOrImageMapImage(),
+ WriteImageNodeToClipboard(*frame_->GetSystemClipboard(),
+ *result.InnerNodeOrImageMapImage(),
result.AltDisplayString());
}
@@ -634,13 +634,13 @@ void Editor::Redo() {
void Editor::SetBaseWritingDirection(WritingDirection direction) {
Element* focused_element = GetFrame().GetDocument()->FocusedElement();
- if (IsTextControl(focused_element)) {
+ if (auto* text_control = ToTextControlOrNull(focused_element)) {
if (direction == WritingDirection::kNatural)
return;
- focused_element->setAttribute(
+ text_control->setAttribute(
html_names::kDirAttr,
direction == WritingDirection::kLeftToRight ? "ltr" : "rtl");
- focused_element->DispatchInputEvent();
+ text_control->DispatchInputEvent();
return;
}
@@ -657,7 +657,7 @@ void Editor::SetBaseWritingDirection(WritingDirection direction) {
}
void Editor::RevealSelectionAfterEditingOperation(
- const ScrollAlignment& alignment) {
+ const mojom::blink::ScrollAlignment& alignment) {
if (prevent_reveal_selection_)
return;
if (!GetFrameSelection().IsAvailable())
@@ -725,7 +725,8 @@ void Editor::ComputeAndSetTypingStyle(CSSPropertyValueSet* style,
EditingStyle::kPreserveWritingDirection);
// Handle block styles, substracting these from the typing style.
- EditingStyle* block_style = typing_style_->ExtractAndRemoveBlockProperties();
+ EditingStyle* block_style = typing_style_->ExtractAndRemoveBlockProperties(
+ GetFrame().GetDocument()->ToExecutionContext());
if (!block_style->IsEmpty()) {
DCHECK(GetFrame().GetDocument());
MakeGarbageCollected<ApplyStyleCommand>(*GetFrame().GetDocument(),
diff --git a/chromium/third_party/blink/renderer/core/editing/editor.h b/chromium/third_party/blink/renderer/core/editing/editor.h
index eebbd98c3b6..e6bcb5dd76a 100644
--- a/chromium/third_party/blink/renderer/core/editing/editor.h
+++ b/chromium/third_party/blink/renderer/core/editing/editor.h
@@ -224,7 +224,7 @@ class CORE_EXPORT Editor final : public GarbageCollected<Editor> {
void Trace(Visitor*);
void RevealSelectionAfterEditingOperation(
- const ScrollAlignment& = ScrollAlignment::kAlignToEdgeIfNeeded);
+ const mojom::blink::ScrollAlignment& = ScrollAlignment::ToEdgeIfNeeded());
private:
Member<LocalFrame> frame_;
diff --git a/chromium/third_party/blink/renderer/core/editing/editor_key_bindings.cc b/chromium/third_party/blink/renderer/core/editing/editor_key_bindings.cc
index 4e9cca888e2..8b3aac0c93b 100644
--- a/chromium/third_party/blink/renderer/core/editing/editor_key_bindings.cc
+++ b/chromium/third_party/blink/renderer/core/editing/editor_key_bindings.cc
@@ -26,7 +26,7 @@
#include "third_party/blink/renderer/core/editing/editor.h"
-#include "third_party/blink/public/platform/web_input_event.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/renderer/core/editing/commands/editor_command.h"
#include "third_party/blink/renderer/core/editing/editing_behavior.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
@@ -39,8 +39,7 @@ namespace blink {
bool Editor::HandleEditingKeyboardEvent(KeyboardEvent* evt) {
const WebKeyboardEvent* key_event = evt->KeyEvent();
- // do not treat this as text input if it's a system key event
- if (!key_event || key_event->is_system_key)
+ if (!key_event)
return false;
String command_name = Behavior().InterpretKeyEvent(*evt);
diff --git a/chromium/third_party/blink/renderer/core/editing/editor_test.cc b/chromium/third_party/blink/renderer/core/editing/editor_test.cc
index 02cece851f0..8e77b8d4f62 100644
--- a/chromium/third_party/blink/renderer/core/editing/editor_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/editor_test.cc
@@ -18,8 +18,8 @@ namespace blink {
class EditorTest : public EditingTestBase {
public:
void TearDown() override {
- SystemClipboard::GetInstance().WritePlainText(String(""));
- SystemClipboard::GetInstance().CommitWrite();
+ GetDocument().GetFrame()->GetSystemClipboard()->WritePlainText(String(""));
+ GetDocument().GetFrame()->GetSystemClipboard()->CommitWrite();
EditingTestBase::TearDown();
}
@@ -69,7 +69,8 @@ TEST_F(EditorTest, CopyVisibleSelection) {
ExecuteCopy();
- const String copied = SystemClipboard::GetInstance().ReadPlainText();
+ const String copied =
+ GetDocument().GetFrame()->GetSystemClipboard()->ReadPlainText();
EXPECT_EQ("HEY", copied);
}
@@ -89,7 +90,8 @@ TEST_F(EditorTest, DontCopyHiddenSelections) {
ExecuteCopy();
- const String copied = SystemClipboard::GetInstance().ReadPlainText();
+ const String copied =
+ GetDocument().GetFrame()->GetSystemClipboard()->ReadPlainText();
EXPECT_TRUE(copied.IsEmpty()) << copied << " was copied.";
}
diff --git a/chromium/third_party/blink/renderer/core/editing/element_inner_text.cc b/chromium/third_party/blink/renderer/core/editing/element_inner_text.cc
index 2fe5c49d329..3f9ec9020d8 100644
--- a/chromium/third_party/blink/renderer/core/editing/element_inner_text.cc
+++ b/chromium/third_party/blink/renderer/core/editing/element_inner_text.cc
@@ -72,7 +72,6 @@ class ElementInnerTextCollector final {
static bool IsBeingRendered(const Node& node);
// Returns true if used value of "display" is block-level.
static bool IsDisplayBlockLevel(const Node&);
- static LayoutObject* PreviousLeafOf(const LayoutObject& layout_object);
static bool ShouldEmitNewlineForTableRow(
const LayoutNGTableRowInterface& table_row);
@@ -81,7 +80,6 @@ class ElementInnerTextCollector final {
void ProcessChildrenWithRequiredLineBreaks(const Node& node,
int required_line_break_count);
void ProcessLayoutText(const LayoutText& layout_text, const Text& text_node);
- void ProcessLayoutTextEmpty(const LayoutText& layout_text);
void ProcessNode(const Node& node);
void ProcessOptionElement(const HTMLOptionElement& element);
void ProcessSelectElement(const HTMLSelectElement& element);
@@ -181,19 +179,6 @@ bool ElementInnerTextCollector::IsDisplayBlockLevel(const Node& node) {
}
// static
-LayoutObject* ElementInnerTextCollector::PreviousLeafOf(
- const LayoutObject& layout_object) {
- LayoutObject* parent = layout_object.Parent();
- for (LayoutObject* runner = layout_object.PreviousInPreOrder(); runner;
- runner = runner->PreviousInPreOrder()) {
- if (runner != parent)
- return runner;
- parent = runner->Parent();
- }
- return nullptr;
-}
-
-// static
bool ElementInnerTextCollector::ShouldEmitNewlineForTableRow(
const LayoutNGTableRowInterface& table_row) {
const LayoutNGTableInterface* const table = table_row.TableInterface();
@@ -477,7 +462,8 @@ void ElementInnerTextCollector::Result::FlushRequiredLineBreak() {
String Element::innerText() {
// We need to update layout, since |ElementInnerTextCollector()| uses line
// boxes in the layout tree.
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
return ElementInnerTextCollector().RunOn(*this);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/element_inner_text_test.cc b/chromium/third_party/blink/renderer/core/editing/element_inner_text_test.cc
index efc058cf6d4..b211b9f529c 100644
--- a/chromium/third_party/blink/renderer/core/editing/element_inner_text_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/element_inner_text_test.cc
@@ -15,7 +15,9 @@ class ElementInnerTest : public testing::WithParamInterface<bool>,
protected:
ElementInnerTest() : ScopedLayoutNGForTest(GetParam()) {}
- bool LayoutNGEnabled() const { return GetParam(); }
+ bool LayoutNGEnabled() const {
+ return RuntimeEnabledFeatures::LayoutNGEnabled();
+ }
};
INSTANTIATE_TEST_SUITE_P(All, ElementInnerTest, testing::Bool());
diff --git a/chromium/third_party/blink/renderer/core/editing/ephemeral_range.cc b/chromium/third_party/blink/renderer/core/editing/ephemeral_range.cc
index 8b9e78a9a92..1d193eb467a 100644
--- a/chromium/third_party/blink/renderer/core/editing/ephemeral_range.cc
+++ b/chromium/third_party/blink/renderer/core/editing/ephemeral_range.cc
@@ -212,13 +212,21 @@ std::ostream& operator<<(std::ostream& ostream,
EphemeralRangeInFlatTree ToEphemeralRangeInFlatTree(
const EphemeralRange& range) {
+ // We need to update the distribution before getting the position in the flat
+ // tree, since that operation requires us to navigate the flat tree.
+ if (range.StartPosition().AnchorNode()) {
+ range.StartPosition()
+ .AnchorNode()
+ ->UpdateDistributionForFlatTreeTraversal();
+ }
+ if (range.EndPosition().AnchorNode()) {
+ range.EndPosition().AnchorNode()->UpdateDistributionForFlatTreeTraversal();
+ }
PositionInFlatTree start = ToPositionInFlatTree(range.StartPosition());
PositionInFlatTree end = ToPositionInFlatTree(range.EndPosition());
if (start.IsNull() || end.IsNull() ||
start.GetDocument() != end.GetDocument())
return EphemeralRangeInFlatTree();
- start.AnchorNode()->UpdateDistributionForFlatTreeTraversal();
- end.AnchorNode()->UpdateDistributionForFlatTreeTraversal();
if (!start.IsValidFor(*start.GetDocument()) ||
!end.IsValidFor(*end.GetDocument()))
return EphemeralRangeInFlatTree();
diff --git a/chromium/third_party/blink/renderer/core/editing/ephemeral_range.h b/chromium/third_party/blink/renderer/core/editing/ephemeral_range.h
index 3e15fb20746..907747a3c3d 100644
--- a/chromium/third_party/blink/renderer/core/editing/ephemeral_range.h
+++ b/chromium/third_party/blink/renderer/core/editing/ephemeral_range.h
@@ -29,7 +29,7 @@ class TraversalRangeNodes : private TraversalRange<Iterator> {
Iterator end() { return Iterator(past_end_node_); }
private:
- const Member<const StartNodeType> past_end_node_;
+ const StartNodeType* const past_end_node_;
};
// This class acts like |TraversalNextIterator| but in addition
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 ed537308ac2..1367abe1212 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
@@ -24,108 +24,10 @@
#include "third_party/blink/renderer/platform/wtf/text/unicode.h"
namespace blink {
+namespace {
-FindBuffer::FindBuffer(const EphemeralRangeInFlatTree& range) {
- DCHECK(range.IsNotNull() && !range.IsCollapsed()) << range;
- CollectTextUntilBlockBoundary(range);
-}
-
-FindBuffer::Results::Results() {
- empty_result_ = true;
-}
-
-FindBuffer::Results::Results(const FindBuffer& find_buffer,
- TextSearcherICU* text_searcher,
- const Vector<UChar>& buffer,
- const String& search_text,
- const blink::FindOptions options) {
- // We need to own the |search_text| because |text_searcher_| only has a
- // StringView (doesn't own the search text).
- search_text_ = search_text;
- find_buffer_ = &find_buffer;
- text_searcher_ = text_searcher;
- text_searcher_->SetPattern(search_text_, options);
- text_searcher_->SetText(buffer.data(), buffer.size());
- text_searcher_->SetOffset(0);
-}
-
-FindBuffer::Results::Iterator::Iterator(const FindBuffer& find_buffer,
- TextSearcherICU* text_searcher,
- const String& search_text)
- : find_buffer_(&find_buffer),
- text_searcher_(text_searcher),
- has_match_(true) {
- operator++();
-}
-
-const FindBuffer::BufferMatchResult FindBuffer::Results::Iterator::operator*()
- const {
- DCHECK(has_match_);
- return FindBuffer::BufferMatchResult({match_.start, match_.length});
-}
-
-void FindBuffer::Results::Iterator::operator++() {
- DCHECK(has_match_);
- has_match_ = text_searcher_->NextMatchResult(match_);
- if (has_match_ && find_buffer_ && find_buffer_->IsInvalidMatch(match_))
- operator++();
-}
-
-bool FindBuffer::IsInvalidMatch(MatchResultICU match) const {
- // Invalid matches are a result of accidentally matching elements that are
- // replaced with the max code point, and may lead to crashes. To avoid
- // crashing, we should skip the matches that are invalid - they would have
- // either an empty position or a non-offset-in-anchor position.
- const unsigned start_index = match.start;
- PositionInFlatTree start_position =
- PositionAtStartOfCharacterAtIndex(start_index);
- if (start_position.IsNull() || !start_position.IsOffsetInAnchor())
- return true;
-
- const unsigned end_index = match.start + match.length;
- DCHECK_LE(start_index, end_index);
- PositionInFlatTree end_position =
- PositionAtEndOfCharacterAtIndex(end_index - 1);
- if (end_position.IsNull() || !end_position.IsOffsetInAnchor())
- return true;
- return false;
-}
-
-FindBuffer::Results::Iterator FindBuffer::Results::begin() const {
- if (empty_result_)
- return end();
- text_searcher_->SetOffset(0);
- return Iterator(*find_buffer_, text_searcher_, search_text_);
-}
-
-FindBuffer::Results::Iterator FindBuffer::Results::end() const {
- return Iterator();
-}
-
-bool FindBuffer::Results::IsEmpty() const {
- return begin() == end();
-}
-
-FindBuffer::BufferMatchResult FindBuffer::Results::front() const {
- return *begin();
-}
-
-FindBuffer::BufferMatchResult FindBuffer::Results::back() const {
- Iterator last_result;
- for (Iterator it = begin(); it != end(); ++it) {
- last_result = it;
- }
- return *last_result;
-}
-
-unsigned FindBuffer::Results::CountForTesting() const {
- unsigned result = 0;
- for (Iterator it = begin(); it != end(); ++it) {
- ++result;
- }
- return result;
-}
-
+// 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) {
const auto* element = DynamicTo<HTMLElement>(node);
if (!element)
@@ -140,10 +42,14 @@ bool ShouldIgnoreContents(const Node& node) {
IsA<HTMLStyleElement>(*element) || IsA<HTMLScriptElement>(*element) ||
IsA<HTMLVideoElement>(*element) || IsA<HTMLAudioElement>(*element) ||
(element->GetDisplayLockContext() &&
+ element->GetDisplayLockContext()->IsLocked() &&
!element->GetDisplayLockContext()->IsActivatable(
DisplayLockActivationReason::kFindInPage));
}
+// Returns the first ancestor that isn't searchable. In other words, either
+// ShouldIgnoreContents() returns true for it or it has a display: none style.
+// Returns nullptr if no such ancestor exists.
Node* GetNonSearchableAncestor(const Node& node) {
for (Node& ancestor : FlatTreeTraversal::InclusiveAncestorsOf(node)) {
const ComputedStyle* style = ancestor.EnsureComputedStyle();
@@ -156,12 +62,15 @@ Node* GetNonSearchableAncestor(const Node& node) {
return nullptr;
}
+// Returns true if the given |display| is considered a 'block'
bool IsBlock(EDisplay display) {
return display == EDisplay::kBlock || display == EDisplay::kTable ||
display == EDisplay::kFlowRoot || display == EDisplay::kGrid ||
display == EDisplay::kFlex || display == EDisplay::kListItem;
}
+// Returns the next node after |start_node| (including start node) that is a
+// text node and is searchable and visible.
Node* GetVisibleTextNode(Node& start_node) {
Node* node = &start_node;
// Move to outside display none subtree if we're inside one.
@@ -192,6 +101,8 @@ Node* GetVisibleTextNode(Node& start_node) {
return nullptr;
}
+// Returns the closest ancestor of |start_node| (including the node itself) that
+// is a block.
Node& GetLowestDisplayBlockInclusiveAncestor(const Node& start_node) {
// Gets lowest inclusive ancestor that has block display value.
// <div id=outer>a<div id=inner>b</div>c</div>
@@ -204,6 +115,33 @@ Node& GetLowestDisplayBlockInclusiveAncestor(const Node& start_node) {
}
return *start_node.GetDocument().documentElement();
}
+} // namespace
+
+// FindBuffer implementation.
+FindBuffer::FindBuffer(const EphemeralRangeInFlatTree& range) {
+ DCHECK(range.IsNotNull() && !range.IsCollapsed()) << range;
+ CollectTextUntilBlockBoundary(range);
+}
+
+bool FindBuffer::IsInvalidMatch(MatchResultICU match) const {
+ // Invalid matches are a result of accidentally matching elements that are
+ // replaced with the max code point, and may lead to crashes. To avoid
+ // crashing, we should skip the matches that are invalid - they would have
+ // either an empty position or a non-offset-in-anchor position.
+ const unsigned start_index = match.start;
+ PositionInFlatTree start_position =
+ PositionAtStartOfCharacterAtIndex(start_index);
+ if (start_position.IsNull() || !start_position.IsOffsetInAnchor())
+ return true;
+
+ const unsigned end_index = match.start + match.length;
+ DCHECK_LE(start_index, end_index);
+ PositionInFlatTree end_position =
+ PositionAtEndOfCharacterAtIndex(end_index - 1);
+ if (end_position.IsNull() || !end_position.IsOffsetInAnchor())
+ return true;
+ return false;
+}
EphemeralRangeInFlatTree FindBuffer::FindMatchInRange(
const EphemeralRangeInFlatTree& range,
@@ -265,52 +203,12 @@ FindBuffer::Results FindBuffer::FindMatches(const WebString& search_text,
return Results(*this, &text_searcher_, buffer_, search_text_16_bit, options);
}
-bool FindBuffer::PushScopedForcedUpdateIfNeeded(const Element& element) {
- if (auto* context = element.GetDisplayLockContext()) {
- DCHECK(context->IsActivatable(DisplayLockActivationReason::kFindInPage));
- scoped_forced_update_list_.push_back(context->GetScopedForcedUpdate());
- return true;
- }
- return false;
-}
-
-void FindBuffer::CollectScopedForcedUpdates(Node& start_node,
- const Node* search_range_end_node,
- const Node* node_after_block) {
- if (!RuntimeEnabledFeatures::DisplayLockingEnabled(
- start_node.GetExecutionContext()))
- return;
- if (start_node.GetDocument().LockedDisplayLockCount() ==
- start_node.GetDocument().ActivationBlockingDisplayLockCount())
- return;
-
- Node* node = &start_node;
- // We assume |start_node| is always visible/activatable if locked, so we don't
- // need to check activatability of ancestors here.
- for (Node& ancestor : FlatTreeTraversal::InclusiveAncestorsOf(*node)) {
- auto* ancestor_element = DynamicTo<Element>(ancestor);
- if (!ancestor_element)
- continue;
- PushScopedForcedUpdateIfNeeded(*ancestor_element);
- }
-
- while (node && node != node_after_block && node != search_range_end_node) {
- if (ShouldIgnoreContents(*node)) {
- // Will skip display:none/non-activatable locked subtrees/etc.
- node = FlatTreeTraversal::NextSkippingChildren(*node);
- continue;
- }
- if (auto* element = DynamicTo<Element>(node))
- PushScopedForcedUpdateIfNeeded(*element);
- node = FlatTreeTraversal::Next(*node);
- }
-}
-
-// Collects text until block boundary located at or after |start_node|
-// to |buffer_|. Saves the next starting node after the block to
-// |node_after_block_|.
void FindBuffer::CollectTextUntilBlockBoundary(
const EphemeralRangeInFlatTree& range) {
+ // Collects text until block boundary located at or after |start_node|
+ // to |buffer_|. Saves the next starting node after the block to
+ // |node_after_block_|.
+
DCHECK(range.IsNotNull() && !range.IsCollapsed()) << range;
node_after_block_ = nullptr;
@@ -337,12 +235,6 @@ void FindBuffer::CollectTextUntilBlockBoundary(
// We will also stop if we encountered/passed |end_node|.
Node* end_node = range.EndPosition().NodeAsRangeLastNode();
- if (node) {
- CollectScopedForcedUpdates(*node, end_node, just_after_block);
- if (!scoped_forced_update_list_.IsEmpty())
- node->GetDocument().UpdateStyleAndLayout();
- }
-
while (node && node != just_after_block) {
if (ShouldIgnoreContents(*node)) {
if (end_node && (end_node == node ||
@@ -499,4 +391,82 @@ void FindBuffer::AddTextToBuffer(const Text& text_node,
}
}
+// FindBuffer::Results implementation.
+FindBuffer::Results::Results() {
+ empty_result_ = true;
+}
+
+FindBuffer::Results::Results(const FindBuffer& find_buffer,
+ TextSearcherICU* text_searcher,
+ const Vector<UChar>& buffer,
+ const String& search_text,
+ const blink::FindOptions options) {
+ // We need to own the |search_text| because |text_searcher_| only has a
+ // StringView (doesn't own the search text).
+ search_text_ = search_text;
+ find_buffer_ = &find_buffer;
+ text_searcher_ = text_searcher;
+ text_searcher_->SetPattern(search_text_, options);
+ text_searcher_->SetText(buffer.data(), buffer.size());
+ text_searcher_->SetOffset(0);
+}
+
+FindBuffer::Results::Iterator FindBuffer::Results::begin() const {
+ if (empty_result_)
+ return end();
+ text_searcher_->SetOffset(0);
+ return Iterator(*find_buffer_, text_searcher_, search_text_);
+}
+
+FindBuffer::Results::Iterator FindBuffer::Results::end() const {
+ return Iterator();
+}
+
+bool FindBuffer::Results::IsEmpty() const {
+ return begin() == end();
+}
+
+FindBuffer::BufferMatchResult FindBuffer::Results::front() const {
+ return *begin();
+}
+
+FindBuffer::BufferMatchResult FindBuffer::Results::back() const {
+ Iterator last_result;
+ for (Iterator it = begin(); it != end(); ++it) {
+ last_result = it;
+ }
+ return *last_result;
+}
+
+unsigned FindBuffer::Results::CountForTesting() const {
+ unsigned result = 0;
+ for (Iterator it = begin(); it != end(); ++it) {
+ ++result;
+ }
+ return result;
+}
+
+// Findbuffer::Results::Iterator implementation.
+FindBuffer::Results::Iterator::Iterator(const FindBuffer& find_buffer,
+ TextSearcherICU* text_searcher,
+ const String& search_text)
+ : find_buffer_(&find_buffer),
+ text_searcher_(text_searcher),
+ has_match_(true) {
+ operator++();
+}
+
+const FindBuffer::BufferMatchResult FindBuffer::Results::Iterator::operator*()
+ const {
+ DCHECK(has_match_);
+ return FindBuffer::BufferMatchResult({match_.start, match_.length});
+}
+
+void FindBuffer::Results::Iterator::operator++() {
+ DCHECK(has_match_);
+ has_match_ = text_searcher_->NextMatchResult(match_);
+ if (has_match_ && find_buffer_ && find_buffer_->IsInvalidMatch(match_))
+ operator++();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/editing/finder/find_buffer.h b/chromium/third_party/blink/renderer/core/editing/finder/find_buffer.h
index bcb387c9097..97cb1ce114e 100644
--- a/chromium/third_party/blink/renderer/core/editing/finder/find_buffer.h
+++ b/chromium/third_party/blink/renderer/core/editing/finder/find_buffer.h
@@ -133,19 +133,6 @@ class CORE_EXPORT FindBuffer {
// another LayoutBlockFlow or after |end_position|) to |node_after_block_|.
void CollectTextUntilBlockBoundary(const EphemeralRangeInFlatTree& range);
- // Adds the ScopedForcedUpdate of |element|'s DisplayLockContext (if it's
- // there) to |scoped_forced_update_list_|. Returns true if we added a
- // ScopedForceUpdate.
- bool PushScopedForcedUpdateIfNeeded(const Element& element);
-
- // Collects all ScopedForceUpdates of any activatable-locked element
- // within the range of [start_node, search_range_end_node] or
- // [start_node, node_after_block) whichever is smaller, to
- // |scoped_forced_update_list_|.
- void CollectScopedForcedUpdates(Node& start_node,
- const Node* search_range_end_node,
- const Node* node_after_block);
-
// Mapping for position in buffer -> actual node where the text came from,
// along with the offset in the NGOffsetMapping of this find_buffer.
// This is needed because when we find a match in the buffer, we want to know
@@ -187,10 +174,9 @@ class CORE_EXPORT FindBuffer {
LayoutBlockFlow& block_flow,
const EphemeralRangeInFlatTree& range);
- Member<Node> node_after_block_;
+ Node* node_after_block_ = nullptr;
Vector<UChar> buffer_;
Vector<BufferNodeMapping> buffer_node_mappings_;
- Vector<DisplayLockContext::ScopedForcedUpdate> scoped_forced_update_list_;
TextSearcherICU text_searcher_;
const NGOffsetMapping* offset_mapping_ = nullptr;
diff --git a/chromium/third_party/blink/renderer/core/editing/finder/find_in_page_coordinates.cc b/chromium/third_party/blink/renderer/core/editing/finder/find_in_page_coordinates.cc
index 46f2f6b312d..f0127d5567c 100644
--- a/chromium/third_party/blink/renderer/core/editing/finder/find_in_page_coordinates.cc
+++ b/chromium/third_party/blink/renderer/core/editing/finder/find_in_page_coordinates.cc
@@ -49,12 +49,12 @@ namespace blink {
static const LayoutBlock* EnclosingScrollableAncestor(
const LayoutObject* layout_object) {
- DCHECK(!layout_object->IsLayoutView());
+ DCHECK(!IsA<LayoutView>(layout_object));
// Trace up the containingBlocks until we reach either the layoutObject view
// or a scrollable object.
const LayoutBlock* container = layout_object->ContainingBlock();
- while (!container->HasOverflowClip() && !container->IsLayoutView())
+ while (!container->HasOverflowClip() && !IsA<LayoutView>(container))
container = container->ContainingBlock();
return container;
}
@@ -64,7 +64,7 @@ static FloatRect ToNormalizedRect(const FloatRect& absolute_rect,
const LayoutBlock* container) {
DCHECK(layout_object);
- DCHECK(container || layout_object->IsLayoutView());
+ DCHECK(container || IsA<LayoutView>(layout_object));
if (!container)
return FloatRect();
@@ -111,7 +111,7 @@ FloatRect FindInPageRectFromAbsoluteRect(
for (const LayoutBox* layout_object = base_container; layout_object;) {
// Go up the layout tree until we reach the root of the current frame (the
// LayoutView).
- while (!layout_object->IsLayoutView()) {
+ while (!IsA<LayoutView>(layout_object)) {
const LayoutBlock* container = EnclosingScrollableAncestor(layout_object);
// Compose the normalized rects.
@@ -125,7 +125,7 @@ FloatRect FindInPageRectFromAbsoluteRect(
layout_object = container;
}
- DCHECK(layout_object->IsLayoutView());
+ DCHECK(IsA<LayoutView>(layout_object));
// Jump to the layoutObject owning the frame, if any.
layout_object = layout_object->GetFrame()
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 d4617e7a720..594e3ff6895 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
@@ -5,8 +5,8 @@
#include "third_party/blink/renderer/core/editing/finder/find_task_controller.h"
#include "third_party/blink/public/mojom/frame/find_in_page.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_idle_request_options.h"
#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/dom/idle_request_options.h"
#include "third_party/blink/renderer/core/dom/range.h"
#include "third_party/blink/renderer/core/dom/scripted_idle_task_controller.h"
#include "third_party/blink/renderer/core/editing/ephemeral_range.h"
@@ -68,21 +68,33 @@ class FindTaskController::IdleFindTask
private:
void invoke(IdleDeadline* deadline) override {
+ const base::TimeTicks task_start_time = base::TimeTicks::Now();
+ if (!controller_)
+ return;
if (!controller_->ShouldFindMatches(search_text_, *options_)) {
controller_->DidFinishTask(identifier_, search_text_, *options_,
true /* finished_whole_request */,
- PositionInFlatTree(), 0 /* match_count */);
+ PositionInFlatTree(), 0 /* match_count */,
+ true /* aborted */, task_start_time);
+ return;
}
-
- Document& document = *controller_->GetLocalFrame()->GetDocument();
+ SCOPED_UMA_HISTOGRAM_TIMER("WebCore.FindInPage.TaskDuration");
+
+ Document* document = controller_->GetLocalFrame()->GetDocument();
+ if (!document || document_ != document)
+ return;
+ Document::ScopedForceActivatableDisplayLocks
+ forced_activatable_display_locks(
+ document->GetScopedForceActivatableLocks());
PositionInFlatTree search_start =
- PositionInFlatTree::FirstPositionInNode(document);
+ PositionInFlatTree::FirstPositionInNode(*document);
PositionInFlatTree search_end;
- if (document.documentElement() && document.documentElement()->lastChild()) {
+ if (document->documentElement() &&
+ document->documentElement()->lastChild()) {
search_end = PositionInFlatTree::AfterNode(
- *document.documentElement()->lastChild());
+ *document->documentElement()->lastChild());
} else {
- search_end = PositionInFlatTree::LastPositionInNode(document);
+ search_end = PositionInFlatTree::LastPositionInNode(*document);
}
DCHECK_EQ(search_start.GetDocument(), search_end.GetDocument());
@@ -96,9 +108,8 @@ class FindTaskController::IdleFindTask
return;
}
- // TODO(editing-dev): Use of UpdateStyleAndLayout
- // needs to be audited. see http://crbug.com/590369 for more details.
- search_start.GetDocument()->UpdateStyleAndLayout();
+ // This is required if we forced any of the display-locks.
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kFindInPage);
int match_count = 0;
bool full_range_searched = false;
@@ -143,10 +154,10 @@ class FindTaskController::IdleFindTask
if (deadline->timeRemaining() <= 0)
break;
}
-
controller_->DidFinishTask(identifier_, search_text_, *options_,
full_range_searched, next_task_start_position,
- match_count);
+ match_count, false /* aborted */,
+ task_start_time);
}
Member<Document> document_;
@@ -167,6 +178,10 @@ void FindTaskController::StartRequest(
int identifier,
const WebString& search_text,
const mojom::blink::FindOptions& options) {
+ current_request_start_time_ = base::TimeTicks::Now();
+ total_task_duration_for_current_request_ = base::TimeDelta();
+ task_count_for_current_request_ = 0;
+ DCHECK(!finding_in_progress_);
// This is a brand new search, so we need to reset everything.
finding_in_progress_ = true;
current_match_count_ = 0;
@@ -174,12 +189,14 @@ void FindTaskController::StartRequest(
}
void FindTaskController::CancelPendingRequest() {
- if (idle_find_task_) {
- idle_find_task_->Dispose();
- idle_find_task_.Clear();
+ if (find_task_) {
+ find_task_->Dispose();
+ find_task_.Clear();
}
- if (finding_in_progress_)
+ if (finding_in_progress_) {
+ RecordRequestMetrics(RequestEndState::ABORTED);
last_find_request_completed_with_no_matches_ = false;
+ }
finding_in_progress_ = false;
resume_finding_from_range_ = nullptr;
}
@@ -188,14 +205,14 @@ void FindTaskController::RequestIdleFindTask(
int identifier,
const WebString& search_text,
const mojom::blink::FindOptions& options) {
- DCHECK_EQ(idle_find_task_, nullptr);
- idle_find_task_ = MakeGarbageCollected<IdleFindTask>(
+ DCHECK_EQ(find_task_, nullptr);
+ find_task_ = MakeGarbageCollected<IdleFindTask>(
this, GetLocalFrame()->GetDocument(), identifier, search_text, options);
// If it's for testing, run the task immediately.
// TODO(rakina): Change to use general solution when it's available.
// https://crbug.com/875203
if (options.run_synchronously_for_testing)
- idle_find_task_->ForceInvocationForTesting();
+ find_task_->ForceInvocationForTesting();
}
void FindTaskController::DidFinishTask(
@@ -204,11 +221,17 @@ void FindTaskController::DidFinishTask(
const mojom::blink::FindOptions& options,
bool finished_whole_request,
PositionInFlatTree next_starting_position,
- int match_count) {
- if (idle_find_task_) {
- idle_find_task_->Dispose();
- idle_find_task_.Clear();
+ int match_count,
+ bool aborted,
+ base::TimeTicks task_start_time) {
+ if (find_task_) {
+ find_task_->Dispose();
+ find_task_.Clear();
}
+ total_task_duration_for_current_request_ +=
+ base::TimeTicks::Now() - task_start_time;
+ if (find_task_)
+ find_task_.Clear();
// Remember what we search for last time, so we can skip searching if more
// letters are added to the search string (and last outcome was 0).
last_search_string_ = search_text;
@@ -226,17 +249,42 @@ void FindTaskController::DidFinishTask(
}
if (!finished_whole_request) {
- // Idle task ran out of time, request for another one.
+ // Task ran out of time, request for another one.
RequestIdleFindTask(identifier, search_text, options);
return; // Done for now, resume work later.
}
text_finder_->FinishCurrentScopingEffort(identifier);
+ RecordRequestMetrics(RequestEndState::ABORTED);
last_find_request_completed_with_no_matches_ = !current_match_count_;
finding_in_progress_ = false;
}
+void FindTaskController::RecordRequestMetrics(
+ RequestEndState request_end_state) {
+ bool aborted = (request_end_state == RequestEndState::ABORTED);
+ if (aborted) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WebCore.FindInPage.TotalTaskDuration.Aborted",
+ total_task_duration_for_current_request_);
+ UMA_HISTOGRAM_MEDIUM_TIMES(
+ "WebCore.FindInPage.RequestDuration.Aborted",
+ base::TimeTicks::Now() - current_request_start_time_);
+ UMA_HISTOGRAM_COUNTS_1000(
+ "WebCore.FindInPage.NumberOfTasksPerRequest.Aborted",
+ task_count_for_current_request_);
+ } else {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WebCore.FindInPage.TotalTaskDuration.Finished",
+ total_task_duration_for_current_request_);
+ UMA_HISTOGRAM_MEDIUM_TIMES(
+ "WebCore.FindInPage.RequestDuration.Finished",
+ base::TimeTicks::Now() - current_request_start_time_);
+ UMA_HISTOGRAM_COUNTS_1000(
+ "WebCore.FindInPage.NumberOfTasksPerRequest.Finished",
+ task_count_for_current_request_);
+ }
+}
+
LocalFrame* FindTaskController::GetLocalFrame() const {
return OwnerFrame().GetFrame();
}
@@ -244,10 +292,10 @@ LocalFrame* FindTaskController::GetLocalFrame() const {
bool FindTaskController::ShouldFindMatches(
const String& search_text,
const mojom::blink::FindOptions& options) {
- // Don't scope if we can't find a frame or a view.
+ // Don't scope if we can't find a frame, a document, or a view.
// The user may have closed the tab/application, so abort.
LocalFrame* frame = GetLocalFrame();
- if (!frame || !frame->View() || !frame->GetPage())
+ if (!frame || !frame->View() || !frame->GetPage() || !frame->GetDocument())
return false;
DCHECK(frame->GetDocument());
@@ -283,7 +331,7 @@ void FindTaskController::DidFindMatch(int identifier, Range* result_range) {
void FindTaskController::Trace(Visitor* visitor) {
visitor->Trace(owner_frame_);
visitor->Trace(text_finder_);
- visitor->Trace(idle_find_task_);
+ visitor->Trace(find_task_);
visitor->Trace(resume_finding_from_range_);
}
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 58e6c8394b4..ff28a2d2849 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
@@ -48,7 +48,7 @@ class CORE_EXPORT FindTaskController final
bool ShouldFindMatches(const String& search_text,
const mojom::blink::FindOptions& options);
- // During a run of |idle_find_task|, we found a match.
+ // During a run of |find_task|, we found a match.
// Updates |current_match_count_| and notifies |text_finder_|.
void DidFindMatch(int identifier, Range* result_range);
@@ -59,12 +59,14 @@ class CORE_EXPORT FindTaskController final
const mojom::blink::FindOptions& options,
bool finished_whole_request,
PositionInFlatTree next_starting_position,
- int match_count);
+ int match_count,
+ bool aborted,
+ base::TimeTicks task_start_time);
Range* ResumeFindingFromRange() const { return resume_finding_from_range_; }
int CurrentMatchCount() const { return current_match_count_; }
- // Idle task, when invoked will search for a given text and notify us
+ // When invoked this will search for a given text and notify us
// whenever a match is found or when it finishes, through FoundMatch and
// DidFinishTask.
class IdleFindTask;
@@ -78,11 +80,22 @@ class CORE_EXPORT FindTaskController final
const WebString& search_text,
const mojom::blink::FindOptions& options);
+ enum class RequestEndState {
+ // The find-in-page request got aborted before going through every text in
+ // the document.
+ ABORTED,
+ // The find-in-page request finished going through every text in the
+ // document.
+ FINISHED,
+ };
+
+ void RecordRequestMetrics(RequestEndState request_end_state);
+
Member<WebLocalFrameImpl> owner_frame_;
Member<TextFinder> text_finder_;
- Member<IdleFindTask> idle_find_task_;
+ Member<IdleFindTask> find_task_;
// Keeps track if there is any ongoing find effort or not.
bool finding_in_progress_;
@@ -102,6 +115,13 @@ class CORE_EXPORT FindTaskController final
// without finding any matches in this frame.
bool last_find_request_completed_with_no_matches_;
+ // The start time of the current find-in-page request.
+ base::TimeTicks current_request_start_time_;
+ // The combined duration of all the tasks done for the current request.
+ base::TimeDelta total_task_duration_for_current_request_;
+ // The number of find-in-page tasks the current request has made.
+ int task_count_for_current_request_;
+
// Keeps track of the last string this frame searched for. This is used for
// short-circuiting searches in the following scenarios: When a frame has
// been searched and returned 0 results, we don't need to search that frame
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 ad3e029794a..4e83f654829 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
@@ -30,8 +30,9 @@
#include "third_party/blink/renderer/core/editing/finder/text_finder.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
+#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink.h"
#include "third_party/blink/public/platform/web_float_rect.h"
-#include "third_party/blink/public/platform/web_scroll_into_view_params.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/public/web/web_frame_widget.h"
#include "third_party/blink/public/web/web_local_frame_client.h"
@@ -75,23 +76,25 @@ void TextFinder::FindMatch::Trace(Visitor* visitor) {
static void ScrollToVisible(Range* match) {
const Node& first_node = *match->FirstNode();
if (RuntimeEnabledFeatures::InvisibleDOMEnabled() ||
- RuntimeEnabledFeatures::DisplayLockingEnabled(
- first_node.GetExecutionContext())) {
+ RuntimeEnabledFeatures::CSSSubtreeVisibilityEnabled()) {
const EphemeralRangeInFlatTree range(match);
if (InvisibleDOM::ActivateRangeIfNeeded(range) ||
- DisplayLockUtilities::ActivateFindInPageMatchRangeIfNeeded(range))
- first_node.GetDocument().UpdateStyleAndLayout();
+ DisplayLockUtilities::ActivateFindInPageMatchRangeIfNeeded(range)) {
+ first_node.GetDocument().UpdateStyleAndLayout(
+ DocumentUpdateReason::kFindInPage);
+ }
}
Settings* settings = first_node.GetDocument().GetSettings();
bool smooth_find_enabled =
settings ? settings->GetSmoothScrollForFindEnabled() : false;
- ScrollBehavior scroll_behavior =
- smooth_find_enabled ? kScrollBehaviorSmooth : kScrollBehaviorAuto;
+ mojom::blink::ScrollBehavior scroll_behavior =
+ smooth_find_enabled ? mojom::blink::ScrollBehavior::kSmooth
+ : mojom::blink::ScrollBehavior::kAuto;
first_node.GetLayoutObject()->ScrollRectToVisible(
PhysicalRect(match->BoundingBox()),
- WebScrollIntoViewParams(
- ScrollAlignment::kAlignCenterIfNeeded,
- ScrollAlignment::kAlignCenterIfNeeded, kUserScroll,
+ ScrollAlignment::CreateScrollIntoViewParams(
+ ScrollAlignment::CenterIfNeeded(), ScrollAlignment::CenterIfNeeded(),
+ mojom::blink::ScrollType::kUser,
true /* make_visible_in_visual_viewport */, scroll_behavior,
true /* is_for_scroll_sequence */));
first_node.GetDocument().SetSequentialFocusNavigationStartingPoint(
@@ -205,7 +208,7 @@ bool TextFinder::Find(int identifier,
else if (active_match_index_ < 0)
active_match_index_ = find_task_controller_->CurrentMatchCount() - 1;
}
- WebRect selection_rect = OwnerFrame().GetFrameView()->ConvertToRootFrame(
+ gfx::Rect selection_rect = OwnerFrame().GetFrameView()->ConvertToRootFrame(
active_match_->BoundingBox());
ReportFindInPageSelection(selection_rect, active_match_index_ + 1,
identifier);
@@ -242,7 +245,8 @@ void TextFinder::SetFindEndstateFocusAndSelection() {
// Need to clean out style and layout state before querying
// Element::isFocusable().
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kFindInPage);
// Try to find the first focusable node up the chain, which will, for
// example, focus links if we have found text within the link.
@@ -268,7 +272,7 @@ void TextFinder::SetFindEndstateFocusAndSelection() {
.Build());
GetFrame()->GetDocument()->SetFocusedElement(
element, FocusParams(SelectionBehaviorOnFocus::kNone,
- kWebFocusTypeNone, nullptr));
+ mojom::blink::FocusType::kNone, nullptr));
return;
}
}
@@ -284,7 +288,7 @@ void TextFinder::SetFindEndstateFocusAndSelection() {
if (element->IsFocusable()) {
GetFrame()->GetDocument()->SetFocusedElement(
element, FocusParams(SelectionBehaviorOnFocus::kNone,
- kWebFocusTypeNone, nullptr));
+ mojom::blink::FocusType::kNone, nullptr));
return;
}
}
@@ -327,9 +331,9 @@ void TextFinder::StopFindingAndClearSelection() {
}
void TextFinder::ReportFindInPageTerminationToAccessibility() {
- if (OwnerFrame().Client()) {
- OwnerFrame().Client()->HandleAccessibilityFindInPageTermination();
- }
+ GetFrame()
+ ->GetLocalFrameHostRemote()
+ .HandleAccessibilityFindInPageTermination();
}
void TextFinder::ReportFindInPageResultToAccessibility(int identifier) {
@@ -345,12 +349,14 @@ void TextFinder::ReportFindInPageResultToAccessibility(int identifier) {
Node* end_node = active_match_->endContainer();
ax_object_cache->HandleTextMarkerDataAdded(start_node, end_node);
- if (OwnerFrame().Client()) {
- OwnerFrame().Client()->HandleAccessibilityFindInPageResult(
- identifier, active_match_index_ + 1, blink::WebNode(start_node),
- active_match_->startOffset(), blink::WebNode(end_node),
- active_match_->endOffset());
- }
+ int32_t start_id = ax_object_cache->GetAXID(start_node);
+ int32_t end_id = ax_object_cache->GetAXID(end_node);
+
+ auto params = mojom::blink::FindInPageResultAXParams::New(
+ identifier, active_match_index_ + 1, start_id,
+ active_match_->startOffset(), end_id, active_match_->endOffset());
+ GetFrame()->GetLocalFrameHostRemote().HandleAccessibilityFindInPageResult(
+ std::move(params));
}
void TextFinder::StartScopingStringMatches(
@@ -450,11 +456,14 @@ void TextFinder::UpdateMatches(int identifier,
}
void TextFinder::FinishCurrentScopingEffort(int identifier) {
+ scoping_in_progress_ = false;
+ if (!OwnerFrame().GetFrame())
+ return;
+
if (!total_match_count_)
OwnerFrame().GetFrame()->Selection().Clear();
FlushCurrentScopingEffort(identifier);
- scoping_in_progress_ = false;
// This frame is done, so show any scrollbar tickmarks we haven't drawn yet.
InvalidatePaintForTickmarks();
}
@@ -476,7 +485,7 @@ void TextFinder::IncreaseMatchCount(int identifier, int count) {
identifier, total_match_count_, !frame_scoping_);
}
-void TextFinder::ReportFindInPageSelection(const WebRect& selection_rect,
+void TextFinder::ReportFindInPageSelection(const gfx::Rect& selection_rect,
int active_match_ordinal,
int identifier) {
// Update the UI with the latest selection rect.
@@ -539,17 +548,17 @@ void TextFinder::UpdateFindMatchRects() {
find_match_rects_are_valid_ = true;
}
-WebFloatRect TextFinder::ActiveFindMatchRect() {
+gfx::RectF TextFinder::ActiveFindMatchRect() {
if (!current_active_match_frame_ || !active_match_)
- return WebFloatRect();
+ return gfx::RectF();
- return WebFloatRect(FindInPageRectFromRange(EphemeralRange(ActiveMatch())));
+ return gfx::RectF(FindInPageRectFromRange(EphemeralRange(ActiveMatch())));
}
-Vector<WebFloatRect> TextFinder::FindMatchRects() {
+Vector<gfx::RectF> TextFinder::FindMatchRects() {
UpdateFindMatchRects();
- Vector<WebFloatRect> match_rects;
+ Vector<gfx::RectF> match_rects;
match_rects.ReserveCapacity(match_rects.size() + find_matches_cache_.size());
for (const FindMatch& match : find_matches_cache_) {
DCHECK(!match.rect_.IsEmpty());
@@ -559,9 +568,9 @@ Vector<WebFloatRect> TextFinder::FindMatchRects() {
return match_rects;
}
-int TextFinder::SelectNearestFindMatch(const WebFloatPoint& point,
- WebRect* selection_rect) {
- int index = NearestFindMatch(point, nullptr);
+int TextFinder::SelectNearestFindMatch(const gfx::PointF& point,
+ gfx::Rect* selection_rect) {
+ int index = NearestFindMatch(FloatPoint(point), nullptr);
if (index != -1)
return SelectFindMatch(static_cast<unsigned>(index), selection_rect);
@@ -592,7 +601,7 @@ int TextFinder::NearestFindMatch(const FloatPoint& point,
return nearest;
}
-int TextFinder::SelectFindMatch(unsigned index, WebRect* selection_rect) {
+int TextFinder::SelectFindMatch(unsigned index, gfx::Rect* selection_rect) {
SECURITY_DCHECK(index < find_matches_cache_.size());
Range* range = find_matches_cache_[index].range_;
@@ -630,9 +639,10 @@ int TextFinder::SelectFindMatch(unsigned index, WebRect* selection_rect) {
active_match_->FirstNode()->GetLayoutObject()) {
active_match_->FirstNode()->GetLayoutObject()->ScrollRectToVisible(
PhysicalRect(active_match_bounding_box),
- WebScrollIntoViewParams(ScrollAlignment::kAlignCenterIfNeeded,
- ScrollAlignment::kAlignCenterIfNeeded,
- kUserScroll));
+ ScrollAlignment::CreateScrollIntoViewParams(
+ ScrollAlignment::CenterIfNeeded(),
+ ScrollAlignment::CenterIfNeeded(),
+ mojom::blink::ScrollType::kUser));
// Absolute coordinates are scroll-variant so the bounding box will change
// if the page is scrolled by ScrollRectToVisible above. Recompute the
@@ -674,8 +684,6 @@ TextFinder::TextFinder(WebLocalFrameImpl& owner_frame)
scoping_in_progress_(false),
find_match_rects_are_valid_(false) {}
-TextFinder::~TextFinder() = default;
-
bool TextFinder::SetMarkerActive(Range* range, bool active) {
if (!range || range->collapsed())
return false;
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 c025a326699..ebffeb7cfaf 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
@@ -33,7 +33,6 @@
#include "base/macros.h"
#include "third_party/blink/public/mojom/frame/find_in_page.mojom-blink-forward.h"
-#include "third_party/blink/public/platform/web_float_point.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -47,9 +46,6 @@ class LocalFrame;
class Range;
class WebLocalFrameImpl;
class WebString;
-struct WebFloatPoint;
-struct WebFloatRect;
-struct WebRect;
class CORE_EXPORT TextFinder final : public GarbageCollected<TextFinder> {
public:
@@ -63,12 +59,12 @@ class CORE_EXPORT TextFinder final : public GarbageCollected<TextFinder> {
void StopFindingAndClearSelection();
void IncreaseMatchCount(int identifier, int count);
int FindMatchMarkersVersion() const { return find_match_markers_version_; }
- WebFloatRect ActiveFindMatchRect();
- Vector<WebFloatRect> FindMatchRects();
- int SelectNearestFindMatch(const WebFloatPoint&, WebRect* selection_rect);
+ gfx::RectF ActiveFindMatchRect();
+ Vector<gfx::RectF> FindMatchRects();
+ int SelectNearestFindMatch(const gfx::PointF&, gfx::Rect* selection_rect);
// Starts brand new scoping request: resets the scoping state and
- // asyncronously calls scopeStringMatches().
+ // asynchronously calls scopeStringMatches().
void StartScopingStringMatches(int identifier,
const WebString& search_text,
const mojom::blink::FindOptions& options);
@@ -119,7 +115,6 @@ class CORE_EXPORT TextFinder final : public GarbageCollected<TextFinder> {
bool finished_whole_request);
explicit TextFinder(WebLocalFrameImpl& owner_frame);
- ~TextFinder();
class FindMatch {
DISALLOW_NEW();
@@ -143,7 +138,7 @@ class CORE_EXPORT TextFinder final : public GarbageCollected<TextFinder> {
private:
// Notifies the delegate about a new selection rect.
- void ReportFindInPageSelection(const WebRect& selection_rect,
+ void ReportFindInPageSelection(const gfx::Rect& selection_rect,
int active_match_ordinal,
int identifier);
@@ -158,7 +153,7 @@ class CORE_EXPORT TextFinder final : public GarbageCollected<TextFinder> {
// match index returned by nearestFindMatch. Returns the ordinal of the new
// selected match or -1 in case of error. Also provides the bounding box of
// the marker in window coordinates if selectionRect is not null.
- int SelectFindMatch(unsigned index, WebRect* selection_rect);
+ int SelectFindMatch(unsigned index, gfx::Rect* selection_rect);
// Compute and cache the rects for FindMatches if required.
// Rects are automatically invalidated in case of content size changes.
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 f45477f6d9b..2e0035d3f9c 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
@@ -37,7 +37,7 @@ class TextFinderTest : public testing::Test {
WebLocalFrameImpl& frame_impl = *web_view_helper_.LocalMainFrame();
frame_impl.ViewImpl()->MainFrameWidget()->Resize(WebSize(640, 480));
frame_impl.ViewImpl()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
document_ = static_cast<Document*>(frame_impl.GetDocument());
text_finder_ = &frame_impl.EnsureTextFinder();
}
@@ -45,10 +45,10 @@ class TextFinderTest : public testing::Test {
Document& GetDocument() const;
TextFinder& GetTextFinder() const;
- static WebFloatRect FindInPageRect(Node* start_container,
- int start_offset,
- Node* end_container,
- int end_offset);
+ static gfx::RectF FindInPageRect(Node* start_container,
+ int start_offset,
+ Node* end_container,
+ int end_offset);
private:
frame_test_helpers::WebViewHelper web_view_helper_;
@@ -64,19 +64,19 @@ TextFinder& TextFinderTest::GetTextFinder() const {
return *text_finder_;
}
-WebFloatRect TextFinderTest::FindInPageRect(Node* start_container,
- int start_offset,
- Node* end_container,
- int end_offset) {
+gfx::RectF TextFinderTest::FindInPageRect(Node* start_container,
+ int start_offset,
+ Node* end_container,
+ int end_offset) {
const Position start_position(start_container, start_offset);
const Position end_position(end_container, end_offset);
const EphemeralRange range(start_position, end_position);
- return WebFloatRect(FindInPageRectFromRange(range));
+ return gfx::RectF(FindInPageRectFromRange(range));
}
TEST_F(TextFinderTest, FindTextSimple) {
- GetDocument().body()->SetInnerHTMLFromString("XXXXFindMeYYYYfindmeZZZZ");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().body()->setInnerHTML("XXXXFindMeYYYYfindmeZZZZ");
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Node* text_node = GetDocument().body()->firstChild();
int identifier = 0;
@@ -150,8 +150,8 @@ TEST_F(TextFinderTest, FindTextSimple) {
}
TEST_F(TextFinderTest, FindTextAutosizing) {
- GetDocument().body()->SetInnerHTMLFromString("XXXXFindMeYYYYfindmeZZZZ");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().body()->setInnerHTML("XXXXFindMeYYYYfindmeZZZZ");
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
int identifier = 0;
WebString search_text(String("FindMe"));
@@ -170,7 +170,7 @@ TEST_F(TextFinderTest, FindTextAutosizing) {
GetDocument().GetSettings()->SetTextAutosizingWindowSizeOverride(
IntSize(20, 20));
GetDocument().GetTextAutosizer()->UpdatePageInfo();
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
// In case of autosizing, scale _should_ change
ASSERT_TRUE(GetTextFinder().Find(identifier, search_text, *find_options,
@@ -182,7 +182,7 @@ TEST_F(TextFinderTest, FindTextAutosizing) {
visual_viewport.SetScale(20);
GetDocument().GetSettings()->SetTextAutosizingEnabled(false);
GetDocument().GetTextAutosizer()->UpdatePageInfo();
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
ASSERT_TRUE(GetTextFinder().Find(identifier, search_text, *find_options,
wrap_within_frame));
@@ -191,8 +191,8 @@ TEST_F(TextFinderTest, FindTextAutosizing) {
}
TEST_F(TextFinderTest, FindTextNotFound) {
- GetDocument().body()->SetInnerHTMLFromString("XXXXFindMeYYYYfindmeZZZZ");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().body()->setInnerHTML("XXXXFindMeYYYYfindmeZZZZ");
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
int identifier = 0;
WebString search_text(String("Boo"));
@@ -206,15 +206,15 @@ TEST_F(TextFinderTest, FindTextNotFound) {
}
TEST_F(TextFinderTest, FindTextInShadowDOM) {
- GetDocument().body()->SetInnerHTMLFromString("<b>FOO</b><i>foo</i>");
+ GetDocument().body()->setInnerHTML("<b>FOO</b><i>foo</i>");
ShadowRoot& shadow_root =
GetDocument().body()->CreateV0ShadowRootForTesting();
- shadow_root.SetInnerHTMLFromString(
+ shadow_root.setInnerHTML(
"<content select=\"i\"></content><u>Foo</u><content></content>");
Node* text_in_b_element = GetDocument().body()->firstChild()->firstChild();
Node* text_in_i_element = GetDocument().body()->lastChild()->firstChild();
Node* text_in_u_element = shadow_root.childNodes()->item(1)->firstChild();
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
int identifier = 0;
WebString search_text(String("foo"));
@@ -308,8 +308,8 @@ TEST_F(TextFinderTest, FindTextInShadowDOM) {
}
TEST_F(TextFinderTest, ScopeTextMatchesSimple) {
- GetDocument().body()->SetInnerHTMLFromString("XXXXFindMeYYYYfindmeZZZZ");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().body()->setInnerHTML("XXXXFindMeYYYYfindmeZZZZ");
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Node* text_node = GetDocument().body()->firstChild();
@@ -324,7 +324,7 @@ TEST_F(TextFinderTest, ScopeTextMatchesSimple) {
*find_options);
EXPECT_EQ(2, GetTextFinder().TotalMatchCount());
- WebVector<WebFloatRect> match_rects = GetTextFinder().FindMatchRects();
+ WebVector<gfx::RectF> match_rects = GetTextFinder().FindMatchRects();
ASSERT_EQ(2u, match_rects.size());
EXPECT_EQ(FindInPageRect(text_node, 4, text_node, 10), match_rects[0]);
EXPECT_EQ(FindInPageRect(text_node, 14, text_node, 20), match_rects[1]);
@@ -332,7 +332,7 @@ TEST_F(TextFinderTest, ScopeTextMatchesSimple) {
// Modify the document size and ensure the cached match rects are recomputed
// to reflect the updated layout.
GetDocument().body()->setAttribute(html_names::kStyleAttr, "margin: 2000px");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
match_rects = GetTextFinder().FindMatchRects();
ASSERT_EQ(2u, match_rects.size());
@@ -341,8 +341,8 @@ TEST_F(TextFinderTest, ScopeTextMatchesSimple) {
}
TEST_F(TextFinderTest, ScopeTextMatchesRepeated) {
- GetDocument().body()->SetInnerHTMLFromString("XXXXFindMeYYYYfindmeZZZZ");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().body()->setInnerHTML("XXXXFindMeYYYYfindmeZZZZ");
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Node* text_node = GetDocument().body()->firstChild();
@@ -361,22 +361,22 @@ TEST_F(TextFinderTest, ScopeTextMatchesRepeated) {
// Only searchText2 should be highlighted.
EXPECT_EQ(2, GetTextFinder().TotalMatchCount());
- WebVector<WebFloatRect> match_rects = GetTextFinder().FindMatchRects();
+ WebVector<gfx::RectF> match_rects = GetTextFinder().FindMatchRects();
ASSERT_EQ(2u, match_rects.size());
EXPECT_EQ(FindInPageRect(text_node, 4, text_node, 10), match_rects[0]);
EXPECT_EQ(FindInPageRect(text_node, 14, text_node, 20), match_rects[1]);
}
TEST_F(TextFinderTest, ScopeTextMatchesWithShadowDOM) {
- GetDocument().body()->SetInnerHTMLFromString("<b>FOO</b><i>foo</i>");
+ GetDocument().body()->setInnerHTML("<b>FOO</b><i>foo</i>");
ShadowRoot& shadow_root =
GetDocument().body()->CreateV0ShadowRootForTesting();
- shadow_root.SetInnerHTMLFromString(
+ shadow_root.setInnerHTML(
"<content select=\"i\"></content><u>Foo</u><content></content>");
Node* text_in_b_element = GetDocument().body()->firstChild()->firstChild();
Node* text_in_i_element = GetDocument().body()->lastChild()->firstChild();
Node* text_in_u_element = shadow_root.childNodes()->item(1)->firstChild();
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
int identifier = 0;
WebString search_text(String("fOO"));
@@ -392,7 +392,7 @@ TEST_F(TextFinderTest, ScopeTextMatchesWithShadowDOM) {
// so in this case the matches will be returned in the order of
// <i> -> <u> -> <b>.
EXPECT_EQ(3, GetTextFinder().TotalMatchCount());
- WebVector<WebFloatRect> match_rects = GetTextFinder().FindMatchRects();
+ WebVector<gfx::RectF> match_rects = GetTextFinder().FindMatchRects();
ASSERT_EQ(3u, match_rects.size());
EXPECT_EQ(FindInPageRect(text_in_i_element, 0, text_in_i_element, 3),
match_rects[0]);
@@ -403,8 +403,8 @@ TEST_F(TextFinderTest, ScopeTextMatchesWithShadowDOM) {
}
TEST_F(TextFinderTest, ScopeRepeatPatternTextMatches) {
- GetDocument().body()->SetInnerHTMLFromString("ab ab ab ab ab");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().body()->setInnerHTML("ab ab ab ab ab");
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Node* text_node = GetDocument().body()->firstChild();
@@ -419,15 +419,15 @@ TEST_F(TextFinderTest, ScopeRepeatPatternTextMatches) {
*find_options);
EXPECT_EQ(2, GetTextFinder().TotalMatchCount());
- WebVector<WebFloatRect> match_rects = GetTextFinder().FindMatchRects();
+ WebVector<gfx::RectF> match_rects = GetTextFinder().FindMatchRects();
ASSERT_EQ(2u, match_rects.size());
EXPECT_EQ(FindInPageRect(text_node, 0, text_node, 5), match_rects[0]);
EXPECT_EQ(FindInPageRect(text_node, 6, text_node, 11), match_rects[1]);
}
TEST_F(TextFinderTest, OverlappingMatches) {
- GetDocument().body()->SetInnerHTMLFromString("aababaa");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().body()->setInnerHTML("aababaa");
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Node* text_node = GetDocument().body()->firstChild();
@@ -443,14 +443,14 @@ TEST_F(TextFinderTest, OverlappingMatches) {
// We shouldn't find overlapped matches.
EXPECT_EQ(1, GetTextFinder().TotalMatchCount());
- WebVector<WebFloatRect> match_rects = GetTextFinder().FindMatchRects();
+ WebVector<gfx::RectF> match_rects = GetTextFinder().FindMatchRects();
ASSERT_EQ(1u, match_rects.size());
EXPECT_EQ(FindInPageRect(text_node, 1, text_node, 4), match_rects[0]);
}
TEST_F(TextFinderTest, SequentialMatches) {
- GetDocument().body()->SetInnerHTMLFromString("ababab");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().body()->setInnerHTML("ababab");
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Node* text_node = GetDocument().body()->firstChild();
@@ -465,7 +465,7 @@ TEST_F(TextFinderTest, SequentialMatches) {
*find_options);
EXPECT_EQ(3, GetTextFinder().TotalMatchCount());
- WebVector<WebFloatRect> match_rects = GetTextFinder().FindMatchRects();
+ WebVector<gfx::RectF> match_rects = GetTextFinder().FindMatchRects();
ASSERT_EQ(3u, match_rects.size());
EXPECT_EQ(FindInPageRect(text_node, 0, text_node, 2), match_rects[0]);
EXPECT_EQ(FindInPageRect(text_node, 2, text_node, 4), match_rects[1]);
@@ -473,8 +473,8 @@ TEST_F(TextFinderTest, SequentialMatches) {
}
TEST_F(TextFinderTest, FindTextJavaScriptUpdatesDOM) {
- GetDocument().body()->SetInnerHTMLFromString("<b>XXXXFindMeYYYY</b><i></i>");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().body()->setInnerHTML("<b>XXXXFindMeYYYY</b><i></i>");
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
int identifier = 0;
WebString search_text(String("FindMe"));
@@ -499,8 +499,8 @@ TEST_F(TextFinderTest, FindTextJavaScriptUpdatesDOM) {
// Add new text to DOM and try FindNext.
auto* i_element = To<Element>(GetDocument().body()->lastChild());
ASSERT_TRUE(i_element);
- i_element->SetInnerHTMLFromString("ZZFindMe");
- GetDocument().UpdateStyleAndLayout();
+ i_element->setInnerHTML("ZZFindMe");
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
ASSERT_TRUE(GetTextFinder().Find(identifier, search_text, *find_options,
wrap_within_frame, &active_now));
@@ -519,7 +519,7 @@ TEST_F(TextFinderTest, FindTextJavaScriptUpdatesDOM) {
EXPECT_EQ(2, GetTextFinder().TotalMatchCount());
- WebVector<WebFloatRect> match_rects = GetTextFinder().FindMatchRects();
+ WebVector<gfx::RectF> match_rects = GetTextFinder().FindMatchRects();
ASSERT_EQ(2u, match_rects.size());
Node* text_in_b_element = GetDocument().body()->firstChild()->firstChild();
Node* text_in_i_element = GetDocument().body()->lastChild()->firstChild();
@@ -530,8 +530,8 @@ TEST_F(TextFinderTest, FindTextJavaScriptUpdatesDOM) {
}
TEST_F(TextFinderTest, FindTextJavaScriptUpdatesDOMAfterNoMatches) {
- GetDocument().body()->SetInnerHTMLFromString("<b>XXXXYYYY</b><i></i>");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().body()->setInnerHTML("<b>XXXXYYYY</b><i></i>");
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
int identifier = 0;
WebString search_text(String("FindMe"));
@@ -553,8 +553,8 @@ TEST_F(TextFinderTest, FindTextJavaScriptUpdatesDOMAfterNoMatches) {
// Add new text to DOM and try FindNext.
auto* i_element = To<Element>(GetDocument().body()->lastChild());
ASSERT_TRUE(i_element);
- i_element->SetInnerHTMLFromString("ZZFindMe");
- GetDocument().UpdateStyleAndLayout();
+ i_element->setInnerHTML("ZZFindMe");
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
ASSERT_TRUE(GetTextFinder().Find(identifier, search_text, *find_options,
wrap_within_frame, &active_now));
@@ -573,7 +573,7 @@ TEST_F(TextFinderTest, FindTextJavaScriptUpdatesDOMAfterNoMatches) {
EXPECT_EQ(1, GetTextFinder().TotalMatchCount());
- WebVector<WebFloatRect> match_rects = GetTextFinder().FindMatchRects();
+ WebVector<gfx::RectF> match_rects = GetTextFinder().FindMatchRects();
ASSERT_EQ(1u, match_rects.size());
Node* text_in_i_element = GetDocument().body()->lastChild()->firstChild();
EXPECT_EQ(FindInPageRect(text_in_i_element, 2, text_in_i_element, 8),
@@ -593,8 +593,8 @@ TEST_F(TextFinderTest, ScopeWithTimeouts) {
}
}
- GetDocument().body()->SetInnerHTMLFromString(text.ToString());
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().body()->setInnerHTML(text.ToString());
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
int identifier = 0;
auto find_options =
diff --git a/chromium/third_party/blink/renderer/core/editing/frame_caret_test.cc b/chromium/third_party/blink/renderer/core/editing/frame_caret_test.cc
index 1081d4ccd5d..7f72172730b 100644
--- a/chromium/third_party/blink/renderer/core/editing/frame_caret_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/frame_caret_test.cc
@@ -47,7 +47,7 @@ TEST_F(FrameCaretTest, BlinkAfterTyping) {
base::TimeDelta::FromSecondsD(kInterval));
GetDocument().GetPage()->GetFocusController().SetActive(true);
GetDocument().GetPage()->GetFocusController().SetFocused(true);
- GetDocument().body()->SetInnerHTMLFromString("<textarea>");
+ GetDocument().body()->setInnerHTML("<textarea>");
auto* editor = To<Element>(GetDocument().body()->firstChild());
editor->focus();
UpdateAllLifecyclePhasesForTest();
@@ -81,7 +81,7 @@ TEST_F(FrameCaretTest, ShouldNotBlinkWhenSelectionLooseFocus) {
FrameCaret& caret = Selection().FrameCaretForTesting();
GetDocument().GetPage()->GetFocusController().SetActive(true);
GetDocument().GetPage()->GetFocusController().SetFocused(true);
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<div id='outer' tabindex='-1'>"
"<div id='input' contenteditable>foo</div>"
"</div>");
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 9a5917e9008..b068e2fc56c 100644
--- a/chromium/third_party/blink/renderer/core/editing/frame_selection.cc
+++ b/chromium/third_party/blink/renderer/core/editing/frame_selection.cc
@@ -26,7 +26,6 @@
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include <stdio.h>
-#include "third_party/blink/public/platform/web_scroll_into_view_params.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
@@ -113,9 +112,13 @@ const DisplayItemClient& FrameSelection::CaretDisplayItemClientForTesting()
return frame_caret_->GetDisplayItemClient();
}
+bool FrameSelection::IsAvailable() const {
+ return SynchronousMutationObserver::GetDocument();
+}
+
Document& FrameSelection::GetDocument() const {
- DCHECK(LifecycleContext());
- return *LifecycleContext();
+ DCHECK(IsAvailable());
+ return *SynchronousMutationObserver::GetDocument();
}
VisibleSelection FrameSelection::ComputeVisibleSelectionInDOMTree() const {
@@ -150,7 +153,7 @@ VisibleSelection FrameSelection::ComputeVisibleSelectionInDOMTreeDeprecated()
const {
// TODO(editing-dev): Hoist UpdateStyleAndLayout
// to caller. See http://crbug.com/590369 for more details.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kSelection);
return ComputeVisibleSelectionInDOMTree();
}
@@ -238,8 +241,19 @@ bool FrameSelection::SetSelectionDeprecated(
if (is_changed) {
AssertUserSelection(new_selection, options);
selection_editor_->SetSelectionAndEndTyping(new_selection);
- DisplayLockUtilities::ActivateSelectionRangeIfNeeded(
- ToEphemeralRangeInFlatTree(new_selection.ComputeRange()));
+
+ // The old selection might not be valid, and thus not iteratable. If that's
+ // the case, notify that all selection was removed and use an empty range as
+ // the old selection.
+ EphemeralRangeInFlatTree old_range;
+ if (old_selection_in_dom_tree.IsValidFor(GetDocument())) {
+ old_range =
+ ToEphemeralRangeInFlatTree(old_selection_in_dom_tree.ComputeRange());
+ } else {
+ DisplayLockUtilities::SelectionRemovedFromDocument(GetDocument());
+ }
+ DisplayLockUtilities::SelectionChanged(
+ old_range, ToEphemeralRangeInFlatTree(new_selection.ComputeRange()));
}
is_directional_ = options.IsDirectional();
should_shrink_next_tap_ = options.ShouldShrinkNextTap();
@@ -288,18 +302,19 @@ void FrameSelection::DidSetSelectionDeprecated(
NotifyTextControlOfSelectionChange(set_selection_by);
if (set_selection_by == SetSelectionBy::kUser) {
const CursorAlignOnScroll align = options.GetCursorAlignOnScroll();
- ScrollAlignment alignment;
+ mojom::blink::ScrollAlignment alignment;
if (frame_->GetEditor()
.Behavior()
- .ShouldCenterAlignWhenSelectionIsRevealed())
+ .ShouldCenterAlignWhenSelectionIsRevealed()) {
alignment = (align == CursorAlignOnScroll::kAlways)
- ? ScrollAlignment::kAlignCenterAlways
- : ScrollAlignment::kAlignCenterIfNeeded;
- else
+ ? ScrollAlignment::CenterAlways()
+ : ScrollAlignment::CenterIfNeeded();
+ } else {
alignment = (align == CursorAlignOnScroll::kAlways)
- ? ScrollAlignment::kAlignTopAlways
- : ScrollAlignment::kAlignToEdgeIfNeeded;
+ ? ScrollAlignment::TopAlways()
+ : ScrollAlignment::ToEdgeIfNeeded();
+ }
RevealSelection(alignment, kRevealExtent);
}
@@ -422,7 +437,7 @@ void FrameSelection::Clear() {
bool FrameSelection::SelectionHasFocus() const {
// TODO(editing-dev): Hoist UpdateStyleAndLayout
// to caller. See http://crbug.com/590369 for more details.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kSelection);
if (ComputeVisibleSelectionInFlatTree().IsNone())
return false;
const Node* current =
@@ -486,13 +501,13 @@ bool FrameSelection::IsHidden() const {
void FrameSelection::DidAttachDocument(Document* document) {
DCHECK(document);
selection_editor_->DidAttachDocument(document);
- SetContext(document);
+ SetDocument(document);
}
-void FrameSelection::ContextDestroyed(Document* document) {
+void FrameSelection::ContextDestroyed() {
granularity_ = TextGranularity::kCharacter;
- layout_selection_->OnDocumentShutdown();
+ layout_selection_->ContextDestroyed();
frame_->GetEditor().ClearTypingStyle();
}
@@ -537,7 +552,7 @@ bool FrameSelection::ComputeAbsoluteBounds(IntRect& anchor,
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- frame_->GetDocument()->UpdateStyleAndLayout();
+ frame_->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kSelection);
if (ComputeVisibleSelectionInDOMTree().IsNone()) {
// plugins/mouse-capture-inside-shadow.html reaches here.
return false;
@@ -618,7 +633,7 @@ void FrameSelection::SelectFrameElementInParentIfFullySelected() {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kSelection);
if (!IsStartOfDocument(ComputeVisibleSelectionInDOMTree().VisibleStart()))
return;
@@ -642,7 +657,8 @@ void FrameSelection::SelectFrameElementInParentIfFullySelected() {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- owner_element_parent->GetDocument().UpdateStyleAndLayout();
+ owner_element_parent->GetDocument().UpdateStyleAndLayout(
+ DocumentUpdateReason::kSelection);
// This method's purpose is it to make it easier to select iframes (in order
// to delete them). Don't do anything if the iframe isn't deletable.
@@ -969,7 +985,7 @@ PhysicalRect FrameSelection::AbsoluteUnclippedBounds() const {
if (!view || !layout_view)
return PhysicalRect();
- view->UpdateLifecycleToLayoutClean();
+ view->UpdateLifecycleToLayoutClean(DocumentUpdateReason::kSelection);
return PhysicalRect(layout_selection_->AbsoluteSelectionBounds());
}
@@ -988,14 +1004,15 @@ IntRect FrameSelection::ComputeRectToScroll(
}
// TODO(editing-dev): This should be done in FlatTree world.
-void FrameSelection::RevealSelection(const ScrollAlignment& alignment,
- RevealExtentOption reveal_extent_option) {
+void FrameSelection::RevealSelection(
+ const mojom::blink::ScrollAlignment& alignment,
+ RevealExtentOption reveal_extent_option) {
DCHECK(IsAvailable());
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
// Calculation of absolute caret bounds requires clean layout.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kSelection);
const VisibleSelection& selection = ComputeVisibleSelectionInDOMTree();
if (selection.IsNone())
@@ -1010,14 +1027,16 @@ void FrameSelection::RevealSelection(const ScrollAlignment& alignment,
DCHECK(start.AnchorNode()->GetLayoutObject());
// This function is needed to make sure that ComputeRectToScroll below has the
// sticky offset info available before the computation.
- GetDocument().EnsurePaintLocationDataValidForNode(start.AnchorNode());
+ GetDocument().EnsurePaintLocationDataValidForNode(
+ start.AnchorNode(), DocumentUpdateReason::kSelection);
PhysicalRect selection_rect(ComputeRectToScroll(reveal_extent_option));
if (selection_rect == PhysicalRect() ||
!start.AnchorNode()->GetLayoutObject()->EnclosingBox())
return;
start.AnchorNode()->GetLayoutObject()->ScrollRectToVisible(
- selection_rect, WebScrollIntoViewParams(alignment, alignment));
+ selection_rect,
+ ScrollAlignment::CreateScrollIntoViewParams(alignment, alignment));
UpdateAppearance();
}
@@ -1244,6 +1263,10 @@ bool FrameSelection::IsDirectional() const {
return is_directional_;
}
+void FrameSelection::MarkCacheDirty() {
+ selection_editor_->MarkCacheDirty();
+}
+
} // namespace blink
#if DCHECK_IS_ON()
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 af6de9f2d22..263f259996a 100644
--- a/chromium/third_party/blink/renderer/core/editing/frame_selection.h
+++ b/chromium/third_party/blink/renderer/core/editing/frame_selection.h
@@ -87,6 +87,9 @@ struct LayoutSelectionStatus {
: start(passed_start), end(passed_end), line_break(passed_line_break) {
DCHECK_LE(start, end);
}
+
+ bool HasValidRange() const { return start < end; }
+
bool operator==(const LayoutSelectionStatus& other) const {
return start == other.start && end == other.end &&
line_break == other.line_break;
@@ -129,7 +132,7 @@ class CORE_EXPORT FrameSelection final
explicit FrameSelection(LocalFrame&);
~FrameSelection();
- bool IsAvailable() const { return LifecycleContext(); }
+ bool IsAvailable() const;
// You should not call |document()| when |!isAvailable()|.
Document& GetDocument() const;
LocalFrame* GetFrame() const { return frame_; }
@@ -260,7 +263,7 @@ class CORE_EXPORT FrameSelection final
// TODO(tkent): This function has a bug that scrolling doesn't work well in
// a case of RangeSelection. crbug.com/443061
void RevealSelection(
- const ScrollAlignment& = ScrollAlignment::kAlignCenterIfNeeded,
+ const mojom::blink::ScrollAlignment& = ScrollAlignment::CenterIfNeeded(),
RevealExtentOption = kDoNotRevealExtent);
void SetSelectionFromNone();
@@ -272,6 +275,10 @@ class CORE_EXPORT FrameSelection final
Range* DocumentCachedRange() const;
void ClearDocumentCachedRange();
+ // Invalidates the cached visual selection information, like
+ // |VisibleSelection| and selection bounds.
+ void MarkCacheDirty();
+
FrameCaret& FrameCaretForTesting() const { return *frame_caret_; }
LayoutTextSelectionStatus ComputeLayoutSelectionStatus(
@@ -304,7 +311,7 @@ class CORE_EXPORT FrameSelection final
void MoveRangeSelectionInternal(const SelectionInDOMTree&, TextGranularity);
// Implementation of |SynchronousMutationObserver| member functions.
- void ContextDestroyed(Document*) final;
+ void ContextDestroyed() final;
void NodeChildrenWillBeRemoved(ContainerNode&) final;
void NodeWillBeRemoved(Node&) final;
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 3ba2c413a9c..f1409f46337 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
@@ -147,7 +147,7 @@ TEST_F(FrameSelectionTest, PaintCaretShouldNotLayout) {
{
GraphicsContext context(*paint_controller);
paint_controller->UpdateCurrentPaintChunkProperties(
- root_paint_chunk_id_, PropertyTreeState::Root());
+ &root_paint_chunk_id_, PropertyTreeState::Root());
Selection().PaintCaret(context, PhysicalOffset());
}
paint_controller->CommitNewDisplayItems();
@@ -272,7 +272,7 @@ TEST_F(FrameSelectionTest, MoveRangeSelectionNoLiveness) {
EXPECT_EQ("xyz", Selection().SelectedText());
sample->insertBefore(Text::Create(GetDocument(), "abc"),
sample->firstChild());
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
const VisibleSelection& selection =
Selection().ComputeVisibleSelectionInDOMTree();
// Inserting "abc" before "xyz" should not affect to selection.
@@ -307,7 +307,7 @@ TEST_F(FrameSelectionTest, SelectAllWithInputElement) {
TEST_F(FrameSelectionTest, SelectAllWithUnselectableRoot) {
Element* select = GetDocument().CreateRawElement(html_names::kSelectTag);
GetDocument().ReplaceChild(select, GetDocument().documentElement());
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Selection().SelectAll();
EXPECT_TRUE(Selection().ComputeVisibleSelectionInDOMTree().IsNone())
<< "Nothing should be selected if the "
@@ -1063,8 +1063,8 @@ TEST_F(FrameSelectionTest, SelectionBounds) {
// bottom is visible. The unclipped selection bounds should not be clipped.
const int scroll_offset = 500;
LocalFrameView* frame_view = GetDocument().View();
- frame_view->LayoutViewport()->SetScrollOffset(ScrollOffset(0, scroll_offset),
- kProgrammaticScroll);
+ frame_view->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, scroll_offset), mojom::blink::ScrollType::kProgrammatic);
EXPECT_EQ(PhysicalRect(0, node_margin_top, node_width, node_height),
frame_view->FrameToDocument(Selection().AbsoluteUnclippedBounds()));
diff --git a/chromium/third_party/blink/renderer/core/editing/granularity_strategy_test.cc b/chromium/third_party/blink/renderer/core/editing/granularity_strategy_test.cc
index 61cd633411e..659e29b7886 100644
--- a/chromium/third_party/blink/renderer/core/editing/granularity_strategy_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/granularity_strategy_test.cc
@@ -91,8 +91,7 @@ Text* GranularityStrategyTest::AppendTextNode(const String& data) {
}
void GranularityStrategyTest::SetInnerHTML(const char* html_content) {
- GetDocument().documentElement()->SetInnerHTMLFromString(
- String::FromUTF8(html_content));
+ GetDocument().documentElement()->setInnerHTML(String::FromUTF8(html_content));
UpdateAllLifecyclePhasesForTest();
}
@@ -477,7 +476,7 @@ TEST_F(GranularityStrategyTest, Character) {
GetDummyPageHolder().GetFrame().GetSettings()->SetDefaultFontSize(12);
// "Foo Bar Baz,"
Text* text = AppendTextNode("Foo Bar Baz,");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
// "Foo B^a|>r Baz," (^ means base, | means extent, , < means start, and >
// means end).
@@ -638,7 +637,7 @@ TEST_F(GranularityStrategyTest, DirectionSwitchSideWordGranularityThenShrink) {
String str = "ab cd efghijkl mnopqr iiin, abc";
Text* text = GetDocument().createTextNode(str);
GetDocument().body()->AppendChild(text);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
GetDummyPageHolder().GetFrame().GetSettings()->SetSelectionStrategy(
SelectionStrategy::kDirection);
@@ -677,7 +676,7 @@ TEST_F(GranularityStrategyTest, DirectionSwitchStartOnBoundary) {
String str = "ab cd efghijkl mnopqr iiin, abc";
Text* text = GetDocument().createTextNode(str);
GetDocument().body()->AppendChild(text);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
GetDummyPageHolder().GetFrame().GetSettings()->SetSelectionStrategy(
SelectionStrategy::kDirection);
@@ -699,15 +698,15 @@ TEST_F(GranularityStrategyTest, DirectionSwitchStartOnBoundary) {
TEST_F(GranularityStrategyTest, UpdateExtentWithNullPositionForCharacter) {
GetDummyPageHolder().GetFrame().GetSettings()->SetSelectionStrategy(
SelectionStrategy::kCharacter);
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<div id=host></div><div id=sample>ab</div>");
// Simulate VIDEO element which has a RANGE as slider of video time.
Element* const host = GetDocument().getElementById("host");
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString("<input type=range>");
+ shadow_root.setInnerHTML("<input type=range>");
Element* const sample = GetDocument().getElementById("sample");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
const SelectionInDOMTree& selection_in_dom_tree =
SelectionInDOMTree::Builder()
.Collapse(Position(sample->firstChild(), 2))
@@ -737,15 +736,15 @@ TEST_F(GranularityStrategyTest, UpdateExtentWithNullPositionForCharacter) {
// For http://crbug.com/704529
TEST_F(GranularityStrategyTest, UpdateExtentWithNullPositionForDirectional) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<div id=host></div><div id=sample>ab</div>");
// Simulate VIDEO element which has a RANGE as slider of video time.
Element* const host = GetDocument().getElementById("host");
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString("<input type=range>");
+ shadow_root.setInnerHTML("<input type=range>");
Element* const sample = GetDocument().getElementById("sample");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
const SelectionInDOMTree& selection_in_dom_tree =
SelectionInDOMTree::Builder()
.Collapse(Position(sample->firstChild(), 2))
diff --git a/chromium/third_party/blink/renderer/core/editing/hit_testing_bidi_test.cc b/chromium/third_party/blink/renderer/core/editing/hit_testing_bidi_test.cc
index 73e3e9ad888..8db2725fe17 100644
--- a/chromium/third_party/blink/renderer/core/editing/hit_testing_bidi_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/hit_testing_bidi_test.cc
@@ -23,7 +23,9 @@ class ParameterizedHitTestingBidiTest
ParameterizedHitTestingBidiTest() : ScopedLayoutNGForTest(GetParam()) {}
protected:
- bool LayoutNGEnabled() const { return GetParam(); }
+ bool LayoutNGEnabled() const {
+ return RuntimeEnabledFeatures::LayoutNGEnabled();
+ }
};
INSTANTIATE_TEST_SUITE_P(All, ParameterizedHitTestingBidiTest, testing::Bool());
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 6f19a2a3093..598f585111a 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
@@ -8,9 +8,9 @@
#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"
#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/editing/ime/edit_context_init.h"
#include "third_party/blink/renderer/core/editing/ime/input_method_controller.h"
#include "third_party/blink/renderer/core/editing/ime/text_format_update_event.h"
#include "third_party/blink/renderer/core/editing/ime/text_update_event.h"
@@ -24,7 +24,7 @@
namespace blink {
EditContext::EditContext(ScriptState* script_state, const EditContextInit* dict)
- : ContextLifecycleObserver(ExecutionContext::From(script_state)) {
+ : ExecutionContextClient(ExecutionContext::From(script_state)) {
DCHECK(IsMainThread());
if (dict->hasText())
@@ -58,7 +58,7 @@ const AtomicString& EditContext::InterfaceName() const {
}
ExecutionContext* EditContext::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextClient::GetExecutionContext();
}
bool EditContext::HasPendingActivity() const {
@@ -66,22 +66,32 @@ bool EditContext::HasPendingActivity() const {
}
InputMethodController& EditContext::GetInputMethodController() const {
- return ContextLifecycleObserver::GetFrame()->GetInputMethodController();
+ return ExecutionContextClient::GetFrame()->GetInputMethodController();
+}
+
+bool EditContext::IsEditContextActive() const {
+ return true;
+}
+
+bool EditContext::IsInputPanelPolicyManual() const {
+ return GetInputMethodController()
+ .GetActiveEditContext()
+ ->inputPanelPolicy() == "manual";
}
void EditContext::DispatchCompositionEndEvent(const String& text) {
auto* event = MakeGarbageCollected<CompositionEvent>(
event_type_names::kCompositionend,
- ContextLifecycleObserver::GetFrame()->DomWindow(), text);
+ ExecutionContextClient::GetFrame()->DomWindow(), text);
DispatchEvent(*event);
}
bool EditContext::DispatchCompositionStartEvent(const String& text) {
auto* event = MakeGarbageCollected<CompositionEvent>(
event_type_names::kCompositionstart,
- ContextLifecycleObserver::GetFrame()->DomWindow(), text);
+ ExecutionContextClient::GetFrame()->DomWindow(), text);
DispatchEvent(*event);
- if (!ContextLifecycleObserver::GetFrame())
+ if (!ExecutionContextClient::GetFrame())
return false;
return true;
}
@@ -153,7 +163,7 @@ void EditContext::focus() {
void EditContext::blur() {
if (GetInputMethodController().GetActiveEditContext() != this)
return;
- // Clean up the state of the |this| EditContext
+ // Clean up the state of the |this| EditContext.
FinishComposingText(ConfirmCompositionBehavior::kKeepSelection);
GetInputMethodController().SetActiveEditContext(this);
}
@@ -179,7 +189,7 @@ void EditContext::updateSelection(uint32_t start,
return;
// There is an active composition so need to set the range of the
- // composition too so that we can commit the string properly
+ // composition too so that we can commit the string properly.
if (composition_range_start_ == 0 && composition_range_end_ == 0) {
composition_range_start_ = selection_start_;
composition_range_end_ = selection_end_;
@@ -261,7 +271,7 @@ void EditContext::setInputPanelPolicy(const String& input_policy) {
}
void EditContext::setInputMode(const String& input_mode) {
- // inputMode password is not supported by browsers yet
+ // inputMode password is not supported by browsers yet:
// https://github.com/whatwg/html/issues/4875
if (input_mode == "text")
@@ -299,7 +309,7 @@ String EditContext::inputMode() const {
case WebTextInputMode::kWebTextInputModeUrl:
return "url";
default:
- return "none"; // defaulting to none
+ return "none"; // Defaulting to none.
}
}
@@ -339,15 +349,15 @@ String EditContext::enterKeyHint() const {
case ui::TextInputAction::kSend:
return "send";
default:
- // defaulting to enter
+ // Defaulting to enter.
return "enter";
}
}
-void EditContext::GetLayoutBounds(WebRect& web_control_bounds,
- WebRect& web_selection_bounds) {
- web_control_bounds = control_bounds_;
- web_selection_bounds = selection_bounds_;
+void EditContext::GetLayoutBounds(WebRect* web_control_bounds,
+ WebRect* web_selection_bounds) {
+ *web_control_bounds = control_bounds_;
+ *web_selection_bounds = selection_bounds_;
}
bool EditContext::SetComposition(
@@ -368,24 +378,17 @@ bool EditContext::SetComposition(
composition_range_start_ = selection_start_;
composition_range_end_ = selection_end_;
}
- // Update the selection and buffer if the composition range has changed
+ // Update the selection and buffer if the composition range has changed.
String update_text(text);
- if (composition_range_start_ != selection_start_ &&
- composition_range_end_ != selection_end_) {
- selection_start_ = composition_range_end_;
- selection_end_ = composition_range_end_;
- }
- text_ = text_.Substring(0, selection_start_) + update_text +
- text_.Substring(selection_end_);
+ text_ = text_.Substring(0, composition_range_start_) + update_text +
+ text_.Substring(composition_range_end_);
- // Fire textupdate and textformatupdate events to JS
+ // Fire textupdate and textformatupdate events to JS.
const uint32_t update_range_start = composition_range_start_;
const uint32_t update_range_end = composition_range_end_;
- if (has_composition_) {
- // Replace the existing composition with empty string
- composition_range_start_ = selection_start_;
- composition_range_end_ = selection_end_;
- }
+ // Update the new selection.
+ selection_start_ = composition_range_start_ + selection_end;
+ selection_end_ = composition_range_start_ + selection_end;
DispatchTextUpdateEvent(update_text, update_range_start, update_range_end,
selection_start_, selection_end_);
composition_range_end_ = composition_range_start_ + selection_end;
@@ -422,7 +425,7 @@ bool EditContext::SetCompositionFromExistingText(
composition_range_end_, composition_start,
composition_start);
DispatchTextFormatEvent(ime_text_spans);
- // Update the selection range
+ // Update the selection range.
selection_start_ = composition_start;
selection_end_ = composition_start;
return true;
@@ -432,10 +435,10 @@ bool EditContext::CommitText(const WebString& text,
const WebVector<WebImeTextSpan>& ime_text_spans,
const WebRange& replacement_range,
int relative_caret_position) {
- // Fire textupdate and textformatupdate events to JS
+ // Fire textupdate and textformatupdate events to JS.
// ime_text_spans can have multiple format updates so loop through and fire
- // events accordingly
- // Update the cached selection too
+ // events accordingly.
+ // Update the cached selection too.
String update_text(text);
uint32_t update_range_start;
uint32_t update_range_end;
@@ -462,7 +465,7 @@ bool EditContext::CommitText(const WebString& text,
composition_range_end_ = 0;
DispatchTextUpdateEvent(update_text, update_range_start, update_range_end,
new_selection_start, new_selection_end);
- // Fire composition end event
+ // Fire composition end event.
if (!text.IsEmpty() && has_composition_)
DispatchCompositionEndEvent(text);
@@ -475,7 +478,7 @@ bool EditContext::FinishComposingText(
WebString text;
if (has_composition_) {
text = text_.Substring(composition_range_start_, composition_range_end_);
- // Fire composition end event
+ // Fire composition end event.
DispatchCompositionEndEvent(text);
} else {
text = text_.Substring(selection_start_, selection_end_);
@@ -536,7 +539,7 @@ WebTextInputMode EditContext::GetInputModeOfEditContext() const {
WebTextInputInfo EditContext::TextInputInfo() {
WebTextInputInfo info;
- // Fetch all the text input info from edit context
+ // Fetch all the text input info from edit context.
info.action = GetEditContextEnterKeyHint();
info.input_mode = GetInputModeOfEditContext();
info.type = TextInputType();
@@ -551,12 +554,12 @@ WebTextInputInfo EditContext::TextInputInfo() {
int EditContext::TextInputFlags() const {
int flags = 0;
- // Disable spellcheck & autocorrect for EditContext
+ // Disable spellcheck & autocorrect for EditContext.
flags |= kWebTextInputFlagAutocorrectOff;
flags |= kWebTextInputFlagSpellcheckOff;
// TODO:(snianu) Enable this once the password type
- // is supported by inputMode attribute
+ // is supported by inputMode attribute.
// if (input_mode_ == WebTextInputMode::kPassword)
// flags |= kWebTextInputFlagHasBeenPasswordField;
@@ -578,7 +581,7 @@ WebRange EditContext::GetSelectionOffsets() const {
void EditContext::Trace(Visitor* visitor) {
ActiveScriptWrappable::Trace(visitor);
- ContextLifecycleObserver::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 38cdc12c43e..74e27ec35a2 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
@@ -14,7 +14,7 @@
#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/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
namespace blink {
@@ -29,11 +29,11 @@ class InputMethodController;
// The goal of the EditContext is to expose the lower-level APIs provided by
// modern operating systems to facilitate various input modalities to unlock
// advanced editing scenarios. For more information please refer
-// https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/master/EditContext/explainer.md
+// https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/master/EditContext/explainer.md.
class CORE_EXPORT EditContext final : public EventTargetWithInlineData,
public ActiveScriptWrappable<EditContext>,
- public ContextLifecycleObserver,
+ public ExecutionContextClient,
public WebInputMethodController {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(EditContext);
@@ -44,13 +44,13 @@ class CORE_EXPORT EditContext final : public EventTargetWithInlineData,
const EditContextInit* dict);
~EditContext() override;
- // Event listeners for an EditContext
+ // Event listeners for an EditContext.
DEFINE_ATTRIBUTE_EVENT_LISTENER(textupdate, kTextupdate)
DEFINE_ATTRIBUTE_EVENT_LISTENER(textformatupdate, kTextformatupdate)
DEFINE_ATTRIBUTE_EVENT_LISTENER(compositionstart, kCompositionstart)
DEFINE_ATTRIBUTE_EVENT_LISTENER(compositionend, kCompositionend)
- // Public APIs for an EditContext (called from JS)
+ // Public APIs for an EditContext (called from JS).
// When focus is called on an EditContext, it sets the active EditContext in
// the document so it can use the text input state to send info about the
@@ -87,51 +87,51 @@ class CORE_EXPORT EditContext final : public EventTargetWithInlineData,
// updated. However, in general this should be avoided during the firing of
// textupdate as it will result in a canceled composition.
// Also, after calling this API, update the selection by calling
- // updateSelection
+ // updateSelection.
void updateText(uint32_t start,
uint32_t end,
const String& new_text,
ExceptionState& exception_state);
- // Returns the text of the EditContext
+ // Returns the text of the EditContext.
String text() const;
- // Returns the current selectionStart of the EditContext
+ // Returns the current selectionStart of the EditContext.
uint32_t selectionStart() const;
- // Returns the current selectionEnd of the EditContext
+ // Returns the current selectionEnd of the EditContext.
uint32_t selectionEnd() const;
- // Returns the InputMode of the EditContext
+ // Returns the InputMode of the EditContext.
String inputMode() const;
- // Returns the EnterKeyHint of the EditContext
+ // Returns the EnterKeyHint of the EditContext.
String enterKeyHint() const;
- // Returns the InputPanelPolicy of the EditContext
+ // Returns the InputPanelPolicy of the EditContext.
String inputPanelPolicy() const;
- // Sets the text of the EditContext which is used to display suggestions
+ // Sets the text of the EditContext which is used to display suggestions.
void setText(const String& text);
- // Sets the selectionStart of the EditContext
+ // Sets the selectionStart of the EditContext.
void setSelectionStart(uint32_t selection_start,
ExceptionState& exception_state);
- // Sets the selectionEnd of the EditContext
+ // Sets the selectionEnd of the EditContext.
void setSelectionEnd(uint32_t selection_end, ExceptionState& exception_state);
// Sets an input mode defined in EditContextInputMode.
- // This relates to the inputMode attribute defined for input element
- // https://html.spec.whatwg.org/multipage/interaction.html#input-modalities:-the-inputmode-attribute
+ // This relates to the inputMode attribute defined for input element:
+ // https://html.spec.whatwg.org/multipage/interaction.html#input-modalities:-the-inputmode-attribute.
void setInputMode(const String& input_mode);
// Sets a specific action related to Enter key defined in
- // https://html.spec.whatwg.org/multipage/interaction.html#input-modalities:-the-enterkeyhint-attribute
+ // https://html.spec.whatwg.org/multipage/interaction.html#input-modalities:-the-enterkeyhint-attribute.
void setEnterKeyHint(const String& enter_key_hint);
- // Sets a policy that determines whether the VK should be raised or dismissed
- // Auto raises the VK automatically, Manual suppresses it
+ // Sets a policy that determines whether the VK should be raised or dismissed.
+ // Auto raises the VK automatically, Manual suppresses it.
void setInputPanelPolicy(const String& input_policy);
// EventTarget overrides
@@ -163,9 +163,10 @@ class CORE_EXPORT EditContext final : public EventTargetWithInlineData,
bool GetCompositionCharacterBounds(WebVector<WebRect>& bounds) override;
WebRange GetSelectionOffsets() const override;
- // Returns the control and selection bounds for an EditContext
- void GetLayoutBounds(WebRect& web_control_bounds,
- WebRect& web_selection_bounds) override;
+ // Populate |control_bounds| and |selection_bounds| with the bounds fetched
+ // from the active EditContext.
+ void GetLayoutBounds(WebRect* web_control_bounds,
+ WebRect* web_selection_bounds) override;
// Sets the composition range from the already existing text
// This is used for reconversion scenarios in JPN IME.
@@ -174,28 +175,29 @@ class CORE_EXPORT EditContext final : public EventTargetWithInlineData,
int composition_end,
const WebVector<WebImeTextSpan>& ime_text_spans);
- bool IsEditContextActive() const override { return true; }
+ bool IsInputPanelPolicyManual() const override;
+ bool IsEditContextActive() const override;
// Called from WebLocalFrame for English compositions
// such as shape-writing, handwriting panels etc.
// Extends the current selection range and removes the
- // characters from the buffer
+ // characters from the buffer.
void ExtendSelectionAndDelete(int before, int after);
private:
- // Returns the enter key action attribute set in the EditContext
+ // Returns the enter key action attribute set in the EditContext.
ui::TextInputAction GetEditContextEnterKeyHint() const;
- // Returns the inputMode of the EditContext from enterKeyHint property
+ // Returns the inputMode of the EditContext from enterKeyHint property.
WebTextInputMode GetInputModeOfEditContext() const;
InputMethodController& GetInputMethodController() const;
- // Events fired to JS
- // Fires compositionstart event to JS whenever user starts a composition
+ // Events fired to JS.
+ // Fires compositionstart event to JS whenever user starts a composition.
bool DispatchCompositionStartEvent(const String& text);
// Fires compositionend event to JS whenever composition is terminated by the
- // user
+ // user.
void DispatchCompositionEndEvent(const String& text);
// The textformatupdate event is fired when the input method desires a
@@ -203,7 +205,7 @@ class CORE_EXPORT EditContext final : public EventTargetWithInlineData,
// properties that correspond with the properties that are exposed on
// 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
+ // the user with visual feedback as prescribed by the software keyboard.
void DispatchTextFormatEvent(const WebVector<WebImeTextSpan>& ime_text_spans);
// The textupdate event will be fired on the EditContext when user input has
@@ -227,7 +229,7 @@ class CORE_EXPORT EditContext final : public EventTargetWithInlineData,
uint32_t new_selection_start,
uint32_t new_selection_end);
- // EditContext member variables
+ // EditContext member variables.
String text_;
uint32_t selection_start_ = 0;
uint32_t selection_end_ = 0;
diff --git a/chromium/third_party/blink/renderer/core/editing/ime/edit_context.idl b/chromium/third_party/blink/renderer/core/editing/ime/edit_context.idl
index 18bc5d02740..b085b020237 100644
--- a/chromium/third_party/blink/renderer/core/editing/ime/edit_context.idl
+++ b/chromium/third_party/blink/renderer/core/editing/ime/edit_context.idl
@@ -7,12 +7,11 @@
// advanced editing scenarios. For more information please refer
// https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/master/EditContext/explainer.md
[
- Constructor(optional EditContextInit options),
- ConstructorCallWith=ScriptState,
Exposed=Window,
ActiveScriptWrappable,
RuntimeEnabled=EditContext
] interface EditContext : EventTarget {
+ [CallWith=ScriptState] constructor(optional EditContextInit options = {});
void focus();
void blur();
[RaisesException] void updateSelection(unsigned long start, unsigned long end);
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 6a40e77088b..359a07258ff 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
@@ -14,6 +14,8 @@ ImeTextSpan::ImeTextSpan(Type type,
unsigned end_offset,
const Color& underline_color,
ui::mojom::ImeTextSpanThickness thickness,
+ ui::mojom::ImeTextSpanUnderlineStyle underline_style,
+ const Color& text_color,
const Color& background_color,
const Color& suggestion_highlight_color,
bool remove_on_finish_composing,
@@ -21,6 +23,8 @@ ImeTextSpan::ImeTextSpan(Type type,
: type_(type),
underline_color_(underline_color),
thickness_(thickness),
+ underline_style_(underline_style),
+ text_color_(text_color),
background_color_(background_color),
suggestion_highlight_color_(suggestion_highlight_color),
remove_on_finish_composing_(remove_on_finish_composing),
@@ -67,6 +71,8 @@ ImeTextSpan::ImeTextSpan(const WebImeTextSpan& ime_text_span)
ime_text_span.end_offset,
Color(ime_text_span.underline_color),
ime_text_span.thickness,
+ 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,
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 40fcf98a41a..5e8f42e51bf 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
@@ -48,6 +48,8 @@ class CORE_EXPORT ImeTextSpan {
unsigned end_offset,
const Color& underline_color,
ui::mojom::ImeTextSpanThickness,
+ ui::mojom::ImeTextSpanUnderlineStyle,
+ const Color& text_color,
const Color& background_color,
const Color& suggestion_highlight_color = Color::kTransparent,
bool remove_on_finish_composing = false,
@@ -60,6 +62,10 @@ class CORE_EXPORT ImeTextSpan {
unsigned EndOffset() const { return end_offset_; }
const Color& UnderlineColor() const { return underline_color_; }
ui::mojom::ImeTextSpanThickness Thickness() const { return thickness_; }
+ ui::mojom::ImeTextSpanUnderlineStyle UnderlineStyle() const {
+ return underline_style_;
+ }
+ const Color& TextColor() const { return text_color_; }
const Color& BackgroundColor() const { return background_color_; }
const Color& SuggestionHighlightColor() const {
return suggestion_highlight_color_;
@@ -75,6 +81,8 @@ class CORE_EXPORT ImeTextSpan {
unsigned end_offset_;
Color underline_color_;
ui::mojom::ImeTextSpanThickness thickness_;
+ ui::mojom::ImeTextSpanUnderlineStyle underline_style_;
+ Color text_color_;
Color background_color_;
Color suggestion_highlight_color_;
bool remove_on_finish_composing_;
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 23131ca7f06..8095b83030d 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
@@ -14,7 +14,18 @@ ImeTextSpan CreateImeTextSpan(unsigned start_offset, unsigned end_offset) {
return ImeTextSpan(ImeTextSpan::Type::kComposition, start_offset, end_offset,
Color::kTransparent,
ui::mojom::ImeTextSpanThickness::kNone,
- Color::kTransparent);
+ ui::mojom::ImeTextSpanUnderlineStyle::kNone,
+ Color::kTransparent, Color::kTransparent);
+}
+
+ImeTextSpan CreateImeTextSpan(
+ unsigned start_offset,
+ unsigned end_offset,
+ ui::mojom::ImeTextSpanUnderlineStyle underline_style) {
+ return ImeTextSpan(ImeTextSpan::Type::kComposition, start_offset, end_offset,
+ Color::kTransparent,
+ ui::mojom::ImeTextSpanThickness::kNone, underline_style,
+ Color::kTransparent, Color::kTransparent);
}
TEST(ImeTextSpanTest, OneChar) {
@@ -73,5 +84,24 @@ TEST(ImeTextSpanTest, LastCharEndBeforeStartZeroEnd) {
EXPECT_EQ(std::numeric_limits<unsigned>::max(), ime_text_span.EndOffset());
}
+TEST(ImeTextSpanTest, UnderlineStyles) {
+ ImeTextSpan ime_text_span =
+ CreateImeTextSpan(0, 5, ui::mojom::ImeTextSpanUnderlineStyle::kSolid);
+ EXPECT_EQ(ui::mojom::ImeTextSpanUnderlineStyle::kSolid,
+ ime_text_span.UnderlineStyle());
+ ime_text_span =
+ CreateImeTextSpan(0, 5, ui::mojom::ImeTextSpanUnderlineStyle::kDot);
+ EXPECT_EQ(ui::mojom::ImeTextSpanUnderlineStyle::kDot,
+ ime_text_span.UnderlineStyle());
+ ime_text_span =
+ CreateImeTextSpan(0, 5, ui::mojom::ImeTextSpanUnderlineStyle::kDash);
+ EXPECT_EQ(ui::mojom::ImeTextSpanUnderlineStyle::kDash,
+ ime_text_span.UnderlineStyle());
+ ime_text_span =
+ CreateImeTextSpan(0, 5, ui::mojom::ImeTextSpanUnderlineStyle::kSquiggle);
+ EXPECT_EQ(ui::mojom::ImeTextSpanUnderlineStyle::kSquiggle,
+ ime_text_span.UnderlineStyle());
+}
+
} // namespace
} // 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 6de4f3a2aae..64be8237804 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
@@ -26,12 +26,14 @@
#include "third_party/blink/renderer/core/editing/ime/input_method_controller.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.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/dom/events/event_dispatcher.h"
#include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h"
#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"
@@ -50,6 +52,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/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"
#include "third_party/blink/renderer/core/input/event_handler.h"
@@ -77,7 +80,7 @@ void DispatchCompositionUpdateEvent(LocalFrame& frame, const String& text) {
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 necesary).
+ // selection update, if necessary).
DCHECK(ScopedEventQueue::Instance()->ShouldQueueEvents());
Element* target = frame.GetDocument()->FocusedElement();
@@ -131,7 +134,7 @@ void InsertTextDuringCompositionWithEvents(
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 necesary).
+ // selection update, if necessary).
DCHECK(ScopedEventQueue::Instance()->ShouldQueueEvents());
DCHECK(composition_type ==
TypingCommand::TextCompositionType::kTextCompositionUpdate ||
@@ -163,7 +166,7 @@ void InsertTextDuringCompositionWithEvents(
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kInput);
const bool is_incremental_insertion = NeedsIncrementalInsertion(frame, text);
@@ -175,7 +178,7 @@ void InsertTextDuringCompositionWithEvents(
// https://crbug.com/693481
if (text.IsEmpty())
TypingCommand::DeleteSelection(*frame.GetDocument(), 0);
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
TypingCommand::InsertText(*frame.GetDocument(), text, options,
composition_type, is_incremental_insertion);
break;
@@ -320,7 +323,8 @@ Element* RootEditableElementOfSelection(const FrameSelection& frameSelection) {
// TODO(editing-dev): Use of UpdateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- frameSelection.GetDocument().UpdateStyleAndLayout();
+ frameSelection.GetDocument().UpdateStyleAndLayout(
+ DocumentUpdateReason::kEditing);
const VisibleSelection& visibleSeleciton =
frameSelection.ComputeVisibleSelectionInDOMTree();
return RootEditableElementOf(visibleSeleciton.Start());
@@ -393,12 +397,12 @@ InputMethodController::InputMethodController(LocalFrame& frame)
InputMethodController::~InputMethodController() = default;
bool InputMethodController::IsAvailable() const {
- return LifecycleContext();
+ return GetExecutionContext();
}
Document& InputMethodController::GetDocument() const {
DCHECK(IsAvailable());
- return *LifecycleContext();
+ return *Document::From(GetExecutionContext());
}
bool InputMethodController::HasComposition() const {
@@ -422,7 +426,7 @@ void InputMethodController::Clear() {
DocumentMarker::MarkerTypes::Composition());
}
-void InputMethodController::ContextDestroyed(Document*) {
+void InputMethodController::ContextDestroyed() {
Clear();
composition_range_ = nullptr;
active_edit_context_ = nullptr;
@@ -430,7 +434,7 @@ void InputMethodController::ContextDestroyed(Document*) {
void InputMethodController::DidAttachDocument(Document* document) {
DCHECK(document);
- SetContext(document);
+ SetExecutionContext(document->ToExecutionContext());
}
void InputMethodController::SelectComposition() const {
@@ -470,9 +474,9 @@ bool InputMethodController::FinishComposingText(
// clamp the text by replacing the composition with the same value.
const bool is_too_long = IsTextTooLongAt(composition_range_->StartPosition());
- // TODO(editing-dev): Use of UpdateStyleAndLayoutIgnorePendingStylesheets
+ // TODO(editing-dev): Use of UpdateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
const String& composing = ComposingText();
// Suppress input event (if we hit the is_too_long case) and compositionend
@@ -495,9 +499,9 @@ bool InputMethodController::FinishComposingText(
DispatchCompositionEndEvent(GetFrame(), composing);
}
- // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets
+ // TODO(editing-dev): Use of updateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
const EphemeralRange& old_selection_range =
EphemeralRangeForOffsets(old_offsets);
@@ -568,7 +572,7 @@ bool InputMethodController::ReplaceText(const String& text,
bool InputMethodController::ReplaceComposition(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 necesary).
+ // selection update, if necessary).
DCHECK(ScopedEventQueue::Instance()->ShouldQueueEvents());
if (!HasComposition())
@@ -630,7 +634,8 @@ void InputMethodController::AddImeTextSpans(
case ImeTextSpan::Type::kComposition:
GetDocument().Markers().AddCompositionMarker(
ephemeral_line_range, ime_text_span.UnderlineColor(),
- ime_text_span.Thickness(), ime_text_span.BackgroundColor());
+ ime_text_span.Thickness(), ime_text_span.UnderlineStyle(),
+ ime_text_span.TextColor(), ime_text_span.BackgroundColor());
break;
case ImeTextSpan::Type::kSuggestion:
case ImeTextSpan::Type::kMisspellingSuggestion:
@@ -656,6 +661,8 @@ void InputMethodController::AddImeTextSpans(
.SetHighlightColor(ime_text_span.SuggestionHighlightColor())
.SetUnderlineColor(ime_text_span.UnderlineColor())
.SetThickness(ime_text_span.Thickness())
+ .SetUnderlineStyle(ime_text_span.UnderlineStyle())
+ .SetTextColor(ime_text_span.TextColor())
.SetBackgroundColor(ime_text_span.BackgroundColor())
.SetRemoveOnFinishComposing(
ime_text_span.NeedsRemovalOnFinishComposing())
@@ -691,7 +698,7 @@ bool InputMethodController::ReplaceCompositionAndMoveCaret(
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
AddImeTextSpans(ime_text_spans, root_editable_element, text_start);
@@ -807,7 +814,7 @@ void InputMethodController::SetComposition(
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
PlainTextRange selected_range = CreateSelectionRangeForSetComposition(
selection_start, selection_end, text.length());
@@ -847,7 +854,7 @@ void InputMethodController::SetComposition(
// TODO(editing-dev): Use of UpdateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
SetEditableSelectionOffsets(selected_range);
return;
@@ -876,7 +883,7 @@ void InputMethodController::SetComposition(
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// The undo stack could become empty if a JavaScript event handler calls
// execCommand('undo') to pop elements off the stack. Or, the top element of
@@ -915,7 +922,7 @@ void InputMethodController::SetComposition(
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// We shouldn't close typing in the middle of setComposition.
SetEditableSelectionOffsets(selected_range, TypingContinuation::kContinue);
@@ -948,6 +955,7 @@ void InputMethodController::SetComposition(
GetDocument().Markers().AddCompositionMarker(
CompositionEphemeralRange(), Color::kTransparent,
ui::mojom::ImeTextSpanThickness::kThin,
+ ui::mojom::ImeTextSpanUnderlineStyle::kSolid, Color::kTransparent,
LayoutTheme::GetTheme().PlatformDefaultCompositionBackgroundColor());
return;
}
@@ -1158,8 +1166,50 @@ bool InputMethodController::DeleteSelection() {
return IsAvailable();
}
+bool InputMethodController::DeleteSelectionWithoutAdjustment() {
+ const SelectionInDOMTree& selection_in_dom_tree =
+ GetFrame().Selection().GetSelectionInDOMTree();
+ if (selection_in_dom_tree.IsCaret())
+ return true;
+
+ const SelectionForUndoStep& selection =
+ SelectionForUndoStep::From(selection_in_dom_tree);
+
+ Node* target = GetFrame().GetDocument()->FocusedElement();
+ if (target) {
+ DispatchBeforeInputEditorCommand(
+ target, InputEvent::InputType::kDeleteContentBackward,
+ TargetRangesForInputEvent(*target));
+ // Frame could have been destroyed by the beforeinput event.
+ if (!IsAvailable())
+ return false;
+ }
+
+ if (TypingCommand* last_typing_command =
+ TypingCommand::LastTypingCommandIfStillOpenForTyping(&GetFrame())) {
+ TypingCommand::UpdateSelectionIfDifferentFromCurrentSelection(
+ last_typing_command, &GetFrame());
+
+ last_typing_command->DeleteSelection(TypingCommand::kSmartDelete,
+ ASSERT_NO_EDITING_ABORT);
+ return true;
+ }
+
+ MakeGarbageCollected<DeleteSelectionCommand>(
+ selection,
+ DeleteSelectionOptions::Builder()
+ .SetMergeBlocksAfterDelete(true)
+ .SetSanitizeMarkup(true)
+ .Build(),
+ InputEvent::InputType::kDeleteContentBackward)
+ ->Apply();
+
+ // Frame could have been destroyed by the input event.
+ return IsAvailable();
+}
+
bool InputMethodController::MoveCaret(int new_caret_position) {
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
PlainTextRange selected_range =
CreateRangeForSelection(new_caret_position, new_caret_position, 0);
if (selected_range.IsNull())
@@ -1206,7 +1256,9 @@ void InputMethodController::ExtendSelectionAndDelete(int before, int after) {
ignore_result(DeleteSelection());
}
-// TODO(yabinh): We should reduce the number of selectionchange events.
+// TODO(ctzsm): We should reduce the number of selectionchange events.
+// Ideally, we want to do the deletion without selection, however, there is no
+// such editing command exists currently.
void InputMethodController::DeleteSurroundingText(int before, int after) {
if (!GetEditor().CanEdit())
return;
@@ -1227,25 +1279,17 @@ void InputMethodController::DeleteSurroundingText(int before, int after) {
if (before > 0 && selection_start > 0) {
// In case of exceeding the left boundary.
const int start = std::max(selection_start - before, 0);
-
const EphemeralRange& range =
PlainTextRange(0, start).CreateRange(*root_editable_element);
if (range.IsNull())
return;
- const Position& position = range.EndPosition();
-
- // Adjust the start of selection for multi-code text(a grapheme cluster
- // contains more than one code point). TODO(yabinh): Adjustment should be
- // based on code point instead of grapheme cluster.
- const size_t diff = ComputeDistanceToLeftGraphemeBoundary(position);
- const int adjusted_start = start - static_cast<int>(diff);
- if (!SetSelectionOffsets(PlainTextRange(adjusted_start, selection_start)))
+ if (!SetSelectionOffsets(PlainTextRange(start, selection_start)))
return;
- if (!DeleteSelection())
+ if (!DeleteSelectionWithoutAdjustment())
return;
- selection_end = selection_end - (selection_start - adjusted_start);
- selection_start = adjusted_start;
+ selection_end = selection_end - (selection_start - start);
+ selection_start = start;
}
// Select the text to be deleted after SelectionState::kEnd.
@@ -1260,15 +1304,10 @@ void InputMethodController::DeleteSurroundingText(int before, int after) {
return;
const int end =
PlainTextRange::Create(*root_editable_element, valid_range).End();
- const Position& position = valid_range.EndPosition();
- // Adjust the end of selection for multi-code text. TODO(yabinh): Adjustment
- // should be based on code point instead of grapheme cluster.
- const size_t diff = ComputeDistanceToRightGraphemeBoundary(position);
- const int adjusted_end = end + static_cast<int>(diff);
- if (!SetSelectionOffsets(PlainTextRange(selection_end, adjusted_end)))
+ if (!SetSelectionOffsets(PlainTextRange(selection_end, end)))
return;
- if (!DeleteSelection())
+ if (!DeleteSelectionWithoutAdjustment())
return;
}
@@ -1316,6 +1355,31 @@ void InputMethodController::DeleteSurroundingTextInCodePoints(int before,
return DeleteSurroundingText(before_length, after_length);
}
+void InputMethodController::GetLayoutBounds(WebRect* control_bounds,
+ WebRect* selection_bounds) {
+ if (!IsAvailable())
+ return;
+
+ if (GetActiveEditContext()) {
+ return GetActiveEditContext()->GetLayoutBounds(control_bounds,
+ selection_bounds);
+ }
+ if (!GetFrame().Selection().IsAvailable())
+ return;
+ Element* element = RootEditableElementOfSelection(GetFrame().Selection());
+ if (!element)
+ return;
+ // Fetch the control bounds of the active editable element.
+ // Selection bounds are currently populated only for EditContext.
+ // For editable elements we use GetCompositionCharacterBounds to fetch the
+ // selection bounds.
+ DOMRect* editable_rect = element->getBoundingClientRect();
+ control_bounds->x = editable_rect->x();
+ control_bounds->y = editable_rect->y();
+ control_bounds->width = editable_rect->width();
+ control_bounds->height = editable_rect->height();
+}
+
WebTextInputInfo InputMethodController::TextInputInfo() const {
WebTextInputInfo info;
if (!IsAvailable())
@@ -1341,7 +1405,7 @@ WebTextInputInfo InputMethodController::TextInputInfo() const {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
DocumentLifecycle::DisallowTransitionScope disallow_transition(
GetDocument().Lifecycle());
@@ -1428,11 +1492,11 @@ int InputMethodController::ComputeWebTextInputNextPreviousFlags() const {
int flags = kWebTextInputFlagNone;
if (page->GetFocusController().NextFocusableElementInForm(
- element, kWebFocusTypeForward))
+ element, mojom::blink::FocusType::kForward))
flags |= kWebTextInputFlagHaveNextFocusableElement;
if (page->GetFocusController().NextFocusableElementInForm(
- element, kWebFocusTypeBackward))
+ element, mojom::blink::FocusType::kBackward))
flags |= kWebTextInputFlagHavePreviousFocusableElement;
return flags;
@@ -1557,7 +1621,7 @@ void InputMethodController::Trace(Visitor* visitor) {
visitor->Trace(frame_);
visitor->Trace(composition_range_);
visitor->Trace(active_edit_context_);
- DocumentShutdownObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 4db0f92ecb3..3ad7cd7c416 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
@@ -28,11 +28,11 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
+#include "third_party/blink/public/platform/web_rect.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/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/dom/document_shutdown_observer.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"
@@ -49,7 +49,7 @@ enum class TypingContinuation;
class CORE_EXPORT InputMethodController final
: public GarbageCollected<InputMethodController>,
- public DocumentShutdownObserver {
+ ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(InputMethodController);
public:
@@ -120,6 +120,10 @@ class CORE_EXPORT InputMethodController final
active_edit_context_ = edit_context;
}
+ // Returns either the focused editable element's control bounds or the
+ // EditContext's control and selection bounds if available.
+ void GetLayoutBounds(WebRect* control_bounds, WebRect* selection_bounds);
+
private:
friend class InputMethodControllerTest;
@@ -167,6 +171,12 @@ class CORE_EXPORT InputMethodController final
// Returns false if the frame was destroyed, true otherwise.
bool DeleteSelection() WARN_UNUSED_RESULT;
+ // Returns false if the frame was destroyed, true otherwise.
+ // The difference between this function and DeleteSelection() is that
+ // DeleteSelection() code path may modify the selection to visible units,
+ // which we don't want when deleting code point.
+ bool DeleteSelectionWithoutAdjustment() WARN_UNUSED_RESULT;
+
// Returns true if moved caret successfully.
bool MoveCaret(int new_caret_position);
@@ -181,8 +191,8 @@ class CORE_EXPORT InputMethodController final
ui::TextInputAction InputActionOfFocusedElement() const;
WebTextInputMode InputModeOfFocusedElement() const;
- // Implements |DocumentShutdownObserver|.
- void ContextDestroyed(Document*) final;
+ // Implements |ExecutionContextLifecycleObserver|.
+ void ContextDestroyed() final;
enum class TypingContinuation;
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 c79051a4946..d7f61e65188 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
@@ -24,6 +24,7 @@
#include "third_party/blink/renderer/core/html/forms/html_text_area_element.h"
using ui::mojom::ImeTextSpanThickness;
+using ui::mojom::ImeTextSpanUnderlineStyle;
namespace blink {
@@ -46,7 +47,7 @@ class InputMethodControllerTest : public EditingTestBase {
Element* InputMethodControllerTest::InsertHTMLElement(const char* element_code,
const char* element_id) {
GetDocument().write(element_code);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Element* element = GetElementById(element_id);
element->focus();
return element;
@@ -57,7 +58,7 @@ void InputMethodControllerTest::CreateHTMLWithCompositionInputEventListeners() {
Element* editable =
InsertHTMLElement("<div id='sample' contenteditable></div>", "sample");
Element* script = GetDocument().CreateRawElement(html_names::kScriptTag);
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
"document.getElementById('sample').addEventListener('beforeinput', "
" event => document.title = `beforeinput.data:${event.data};`);"
"document.getElementById('sample').addEventListener('input', "
@@ -78,14 +79,14 @@ void InputMethodControllerTest::CreateHTMLWithCompositionEndEventListener(
switch (type) {
case kNoSelection:
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
// If the caret position is set before firing 'compositonend' event
// (and it should), the final caret position will be reset to null.
"document.getElementById('sample').addEventListener('compositionend',"
" event => getSelection().removeAllRanges());");
break;
case kCaretSelection:
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
// If the caret position is set before firing 'compositonend' event
// (and it should), the final caret position will be reset to [3,3].
"document.getElementById('sample').addEventListener('compositionend',"
@@ -95,7 +96,7 @@ void InputMethodControllerTest::CreateHTMLWithCompositionEndEventListener(
"});");
break;
case kRangeSelection:
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
// If the caret position is set before firing 'compositonend' event
// (and it should), the final caret position will be reset to [2,4].
"document.getElementById('sample').addEventListener('compositionend',"
@@ -119,14 +120,14 @@ TEST_F(InputMethodControllerTest, BackspaceFromEndOfInput) {
To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample"));
input->setValue("fooX");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(4, 4));
EXPECT_EQ("fooX", input->value());
Controller().ExtendSelectionAndDelete(0, 0);
EXPECT_EQ("fooX", input->value());
input->setValue("fooX");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(4, 4));
EXPECT_EQ("fooX", input->value());
Controller().ExtendSelectionAndDelete(1, 0);
@@ -134,7 +135,7 @@ TEST_F(InputMethodControllerTest, BackspaceFromEndOfInput) {
input->setValue(
String::FromUTF8("foo\xE2\x98\x85")); // U+2605 == "black star"
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(4, 4));
EXPECT_EQ("foo\xE2\x98\x85", input->value().Utf8());
Controller().ExtendSelectionAndDelete(1, 0);
@@ -142,7 +143,7 @@ TEST_F(InputMethodControllerTest, BackspaceFromEndOfInput) {
input->setValue(
String::FromUTF8("foo\xF0\x9F\x8F\x86")); // U+1F3C6 == "trophy"
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(4, 4));
EXPECT_EQ("foo\xF0\x9F\x8F\x86", input->value().Utf8());
Controller().ExtendSelectionAndDelete(1, 0);
@@ -150,14 +151,14 @@ TEST_F(InputMethodControllerTest, BackspaceFromEndOfInput) {
// composed U+0E01 "ka kai" + U+0E49 "mai tho"
input->setValue(String::FromUTF8("foo\xE0\xB8\x81\xE0\xB9\x89"));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(4, 4));
EXPECT_EQ("foo\xE0\xB8\x81\xE0\xB9\x89", input->value().Utf8());
Controller().ExtendSelectionAndDelete(1, 0);
EXPECT_EQ("foo", input->value());
input->setValue("fooX");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(4, 4));
EXPECT_EQ("fooX", input->value());
Controller().ExtendSelectionAndDelete(0, 1);
@@ -169,9 +170,9 @@ TEST_F(InputMethodControllerTest, SetCompositionFromExistingText) {
"<div id='sample' contenteditable>hello world</div>", "sample");
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().SetCompositionFromExistingText(ime_text_spans, 0, 5);
Range* range = GetCompositionRange();
@@ -189,11 +190,11 @@ TEST_F(InputMethodControllerTest, SetCompositionAfterEmoji) {
"<div id='sample' contenteditable>&#x1f3c6</div>", "sample");
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 2,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 2, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(2, 2));
EXPECT_EQ(2, GetFrame()
.Selection()
@@ -217,10 +218,10 @@ TEST_F(InputMethodControllerTest, SetCompositionWithGraphemeCluster) {
InsertHTMLElement("<div id='sample' contenteditable></div>", "sample");
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 6, 6,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
- GetDocument().UpdateStyleAndLayout();
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 6, 6, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
// UTF16 = 0x0939 0x0947 0x0932 0x0932. Note that 0x0932 0x0932 is a grapheme
// cluster.
@@ -245,10 +246,10 @@ TEST_F(InputMethodControllerTest,
InsertHTMLElement("<div id='sample' contenteditable></div>", "sample");
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 12, 12,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
- GetDocument().UpdateStyleAndLayout();
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 12, 12, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
// UTF16 = 0x0939 0x0947 0x0932 0x094D 0x0932 0x094B. 0x0939 0x0947 0x0932 is
// a grapheme cluster, so is the remainding 0x0932 0x094B.
@@ -281,29 +282,26 @@ TEST_F(InputMethodControllerTest, SetCompositionKeepingStyle) {
"sample");
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 3, 12,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 3, 12, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().SetCompositionFromExistingText(ime_text_spans, 3, 12);
// Subtract a character.
Controller().SetComposition(String("12345789"), ime_text_spans, 8, 8);
- EXPECT_EQ("abc1<b>2</b>3457<b>8</b>9d<b>e</b>f",
- div->InnerHTMLAsString().Utf8());
+ EXPECT_EQ("abc1<b>2</b>3457<b>8</b>9d<b>e</b>f", div->innerHTML().Utf8());
EXPECT_EQ(11u, Controller().GetSelectionOffsets().Start());
EXPECT_EQ(11u, Controller().GetSelectionOffsets().End());
// Append a character.
Controller().SetComposition(String("123456789"), ime_text_spans, 9, 9);
- EXPECT_EQ("abc1<b>2</b>34567<b>8</b>9d<b>e</b>f",
- div->InnerHTMLAsString().Utf8());
+ EXPECT_EQ("abc1<b>2</b>34567<b>8</b>9d<b>e</b>f", div->innerHTML().Utf8());
EXPECT_EQ(12u, Controller().GetSelectionOffsets().Start());
EXPECT_EQ(12u, Controller().GetSelectionOffsets().End());
// Subtract and append characters.
Controller().SetComposition(String("123hello789"), ime_text_spans, 11, 11);
- EXPECT_EQ("abc1<b>2</b>3hello7<b>8</b>9d<b>e</b>f",
- div->InnerHTMLAsString().Utf8());
+ EXPECT_EQ("abc1<b>2</b>3hello7<b>8</b>9d<b>e</b>f", div->innerHTML().Utf8());
}
TEST_F(InputMethodControllerTest, SetCompositionWithEmojiKeepingStyle) {
@@ -312,9 +310,9 @@ TEST_F(InputMethodControllerTest, SetCompositionWithEmojiKeepingStyle) {
"<div id='sample' contenteditable><b>&#x1f3e0</b></div>", "sample");
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 2,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 2, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().SetCompositionFromExistingText(ime_text_spans, 0, 2);
@@ -322,11 +320,11 @@ TEST_F(InputMethodControllerTest, SetCompositionWithEmojiKeepingStyle) {
// surrogate pair to the previous one.
Controller().SetComposition(String::FromUTF8("\xF0\x9F\x8F\xAB"),
ime_text_spans, 2, 2);
- EXPECT_EQ("<b>\xF0\x9F\x8F\xAB</b>", div->InnerHTMLAsString().Utf8());
+ EXPECT_EQ("<b>\xF0\x9F\x8F\xAB</b>", div->innerHTML().Utf8());
Controller().SetComposition(String::FromUTF8("\xF0\x9F\x8F\xA0"),
ime_text_spans, 2, 2);
- EXPECT_EQ("<b>\xF0\x9F\x8F\xA0</b>", div->InnerHTMLAsString().Utf8());
+ EXPECT_EQ("<b>\xF0\x9F\x8F\xA0</b>", div->innerHTML().Utf8());
}
TEST_F(InputMethodControllerTest,
@@ -338,20 +336,20 @@ TEST_F(InputMethodControllerTest,
"<div id='sample' contenteditable><b>&#xc03</b></div>", "sample");
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 2,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 2, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().SetCompositionFromExistingText(ime_text_spans, 0, 1);
// 0xE0 0xB0 0x83 0xE0 0xB0 0x83, a telugu character with 2 code points in
// 1 grapheme cluster.
Controller().SetComposition(String::FromUTF8("\xE0\xB0\x83\xE0\xB0\x83"),
ime_text_spans, 2, 2);
- EXPECT_EQ("<b>\xE0\xB0\x83\xE0\xB0\x83</b>", div->InnerHTMLAsString().Utf8());
+ EXPECT_EQ("<b>\xE0\xB0\x83\xE0\xB0\x83</b>", div->innerHTML().Utf8());
Controller().SetComposition(String::FromUTF8("\xE0\xB0\x83"), ime_text_spans,
1, 1);
- EXPECT_EQ("<b>\xE0\xB0\x83</b>", div->InnerHTMLAsString().Utf8());
+ EXPECT_EQ("<b>\xE0\xB0\x83</b>", div->innerHTML().Utf8());
}
TEST_F(InputMethodControllerTest, FinishComposingTextKeepingStyle) {
@@ -361,16 +359,16 @@ TEST_F(InputMethodControllerTest, FinishComposingTextKeepingStyle) {
"sample");
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 3, 12,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 3, 12, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().SetCompositionFromExistingText(ime_text_spans, 3, 12);
Controller().SetComposition(String("123hello789"), ime_text_spans, 11, 11);
- EXPECT_EQ("abc1<b>2</b>3hello7<b>8</b>9", div->InnerHTMLAsString());
+ EXPECT_EQ("abc1<b>2</b>3hello7<b>8</b>9", div->innerHTML());
Controller().FinishComposingText(InputMethodController::kKeepSelection);
- EXPECT_EQ("abc1<b>2</b>3hello7<b>8</b>9", div->InnerHTMLAsString());
+ EXPECT_EQ("abc1<b>2</b>3hello7<b>8</b>9", div->innerHTML());
}
TEST_F(InputMethodControllerTest, CommitTextKeepingStyle) {
@@ -380,25 +378,25 @@ TEST_F(InputMethodControllerTest, CommitTextKeepingStyle) {
"sample");
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 3, 12,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 3, 12, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().SetCompositionFromExistingText(ime_text_spans, 3, 12);
Controller().CommitText(String("123789"), ime_text_spans, 0);
- EXPECT_EQ("abc1<b>2</b>37<b>8</b>9", div->InnerHTMLAsString());
+ EXPECT_EQ("abc1<b>2</b>37<b>8</b>9", div->innerHTML());
}
TEST_F(InputMethodControllerTest, InsertTextWithNewLine) {
Element* div =
InsertHTMLElement("<div id='sample' contenteditable></div>", "sample");
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 11,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 11, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().CommitText(String("hello\nworld"), ime_text_spans, 0);
- EXPECT_EQ("hello<div>world</div>", div->InnerHTMLAsString());
+ EXPECT_EQ("hello<div>world</div>", div->innerHTML());
}
TEST_F(InputMethodControllerTest, InsertTextWithNewLineIncrementally) {
@@ -408,10 +406,10 @@ TEST_F(InputMethodControllerTest, InsertTextWithNewLineIncrementally) {
Vector<ImeTextSpan> ime_text_spans;
Controller().CommitText("a", ime_text_spans, 0);
Controller().SetComposition("bcd", ime_text_spans, 0, 2);
- EXPECT_EQ("abcd", div->InnerHTMLAsString());
+ EXPECT_EQ("abcd", div->innerHTML());
Controller().CommitText(String("bcd\nefgh\nijkl"), ime_text_spans, 0);
- EXPECT_EQ("abcd<div>efgh</div><div>ijkl</div>", div->InnerHTMLAsString());
+ EXPECT_EQ("abcd<div>efgh</div><div>ijkl</div>", div->innerHTML());
}
TEST_F(InputMethodControllerTest, SelectionOnConfirmExistingText) {
@@ -419,9 +417,9 @@ TEST_F(InputMethodControllerTest, SelectionOnConfirmExistingText) {
"sample");
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().SetCompositionFromExistingText(ime_text_spans, 0, 5);
Controller().FinishComposingText(InputMethodController::kKeepSelection);
@@ -442,23 +440,23 @@ TEST_F(InputMethodControllerTest, DeleteBySettingEmptyComposition) {
To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample"));
input->setValue("foo ");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(4, 4));
EXPECT_EQ("foo ", input->value());
Controller().ExtendSelectionAndDelete(0, 0);
EXPECT_EQ("foo ", input->value());
input->setValue("foo ");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(4, 4));
EXPECT_EQ("foo ", input->value());
Controller().ExtendSelectionAndDelete(1, 0);
EXPECT_EQ("foo", input->value());
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 3,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 3, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().SetCompositionFromExistingText(ime_text_spans, 0, 3);
Controller().SetComposition(String(""), ime_text_spans, 0, 3);
@@ -474,9 +472,9 @@ TEST_F(InputMethodControllerTest,
"<div id='sample' contenteditable>\nhello world</div>", "sample");
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().SetCompositionFromExistingText(ime_text_spans, 0, 5);
Range* range = GetCompositionRange();
@@ -493,9 +491,9 @@ TEST_F(InputMethodControllerTest,
InsertHTMLElement("<div id='sample' contenteditable>test</div>", "sample");
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 7, 8,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 7, 8, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().SetCompositionFromExistingText(ime_text_spans, 7, 8);
EXPECT_FALSE(GetCompositionRange());
@@ -506,9 +504,9 @@ TEST_F(InputMethodControllerTest, ConfirmPasswordComposition) {
"<input id='sample' type='password' size='24'>", "sample"));
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().SetComposition("foo", ime_text_spans, 0, 3);
Controller().FinishComposingText(InputMethodController::kKeepSelection);
@@ -520,25 +518,25 @@ TEST_F(InputMethodControllerTest, DeleteSurroundingTextWithEmptyText) {
To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample"));
input->setValue("");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_EQ("", input->value());
Controller().DeleteSurroundingText(0, 0);
EXPECT_EQ("", input->value());
input->setValue("");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_EQ("", input->value());
Controller().DeleteSurroundingText(1, 0);
EXPECT_EQ("", input->value());
input->setValue("");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_EQ("", input->value());
Controller().DeleteSurroundingText(0, 1);
EXPECT_EQ("", input->value());
input->setValue("");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_EQ("", input->value());
Controller().DeleteSurroundingText(1, 1);
EXPECT_EQ("", input->value());
@@ -549,35 +547,35 @@ TEST_F(InputMethodControllerTest, DeleteSurroundingTextWithRangeSelection) {
To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample"));
input->setValue("hello");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_EQ("hello", input->value());
Controller().SetEditableSelectionOffsets(PlainTextRange(1, 4));
Controller().DeleteSurroundingText(0, 0);
EXPECT_EQ("hello", input->value());
input->setValue("hello");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_EQ("hello", input->value());
Controller().SetEditableSelectionOffsets(PlainTextRange(1, 4));
Controller().DeleteSurroundingText(1, 1);
EXPECT_EQ("ell", input->value());
input->setValue("hello");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_EQ("hello", input->value());
Controller().SetEditableSelectionOffsets(PlainTextRange(1, 4));
Controller().DeleteSurroundingText(100, 0);
EXPECT_EQ("ello", input->value());
input->setValue("hello");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_EQ("hello", input->value());
Controller().SetEditableSelectionOffsets(PlainTextRange(1, 4));
Controller().DeleteSurroundingText(0, 100);
EXPECT_EQ("hell", input->value());
input->setValue("hello");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_EQ("hello", input->value());
Controller().SetEditableSelectionOffsets(PlainTextRange(1, 4));
Controller().DeleteSurroundingText(100, 100);
@@ -589,63 +587,63 @@ TEST_F(InputMethodControllerTest, DeleteSurroundingTextWithCursorSelection) {
To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample"));
input->setValue("hello");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_EQ("hello", input->value());
Controller().SetEditableSelectionOffsets(PlainTextRange(2, 2));
Controller().DeleteSurroundingText(1, 0);
EXPECT_EQ("hllo", input->value());
input->setValue("hello");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_EQ("hello", input->value());
Controller().SetEditableSelectionOffsets(PlainTextRange(2, 2));
Controller().DeleteSurroundingText(0, 1);
EXPECT_EQ("helo", input->value());
input->setValue("hello");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_EQ("hello", input->value());
Controller().SetEditableSelectionOffsets(PlainTextRange(2, 2));
Controller().DeleteSurroundingText(0, 0);
EXPECT_EQ("hello", input->value());
input->setValue("hello");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_EQ("hello", input->value());
Controller().SetEditableSelectionOffsets(PlainTextRange(2, 2));
Controller().DeleteSurroundingText(1, 1);
EXPECT_EQ("hlo", input->value());
input->setValue("hello");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_EQ("hello", input->value());
Controller().SetEditableSelectionOffsets(PlainTextRange(2, 2));
Controller().DeleteSurroundingText(100, 0);
EXPECT_EQ("llo", input->value());
input->setValue("hello");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_EQ("hello", input->value());
Controller().SetEditableSelectionOffsets(PlainTextRange(2, 2));
Controller().DeleteSurroundingText(0, 100);
EXPECT_EQ("he", input->value());
input->setValue("hello");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_EQ("hello", input->value());
Controller().SetEditableSelectionOffsets(PlainTextRange(2, 2));
Controller().DeleteSurroundingText(100, 100);
EXPECT_EQ("", input->value());
input->setValue("h");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_EQ("h", input->value());
Controller().SetEditableSelectionOffsets(PlainTextRange(1, 1));
Controller().DeleteSurroundingText(1, 0);
EXPECT_EQ("", input->value());
input->setValue("h");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_EQ("h", input->value());
Controller().SetEditableSelectionOffsets(PlainTextRange(0, 0));
Controller().DeleteSurroundingText(0, 1);
@@ -659,7 +657,7 @@ TEST_F(InputMethodControllerTest,
// U+2605 == "black star". It takes up 1 space.
input->setValue(String::FromUTF8("foo\xE2\x98\x85"));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(4, 4));
EXPECT_EQ("foo\xE2\x98\x85", input->value().Utf8());
Controller().DeleteSurroundingText(1, 0);
@@ -667,23 +665,23 @@ TEST_F(InputMethodControllerTest,
// U+1F3C6 == "trophy". It takes up 2 space.
input->setValue(String::FromUTF8("foo\xF0\x9F\x8F\x86"));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(5, 5));
EXPECT_EQ("foo\xF0\x9F\x8F\x86", input->value().Utf8());
Controller().DeleteSurroundingText(1, 0);
- EXPECT_EQ("foo", input->value());
+ EXPECT_EQ("foo\xED\xA0\xBC", input->value().Utf8());
// composed U+0E01 "ka kai" + U+0E49 "mai tho". It takes up 2 space.
input->setValue(String::FromUTF8("foo\xE0\xB8\x81\xE0\xB9\x89"));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(5, 5));
EXPECT_EQ("foo\xE0\xB8\x81\xE0\xB9\x89", input->value().Utf8());
Controller().DeleteSurroundingText(1, 0);
- EXPECT_EQ("foo", input->value());
+ EXPECT_EQ("foo\xE0\xB8\x81", input->value().Utf8());
// "trophy" + "trophy".
input->setValue(String::FromUTF8("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86"));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(7, 7));
EXPECT_EQ("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86", input->value().Utf8());
Controller().DeleteSurroundingText(2, 0);
@@ -691,15 +689,15 @@ TEST_F(InputMethodControllerTest,
// "trophy" + "trophy".
input->setValue(String::FromUTF8("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86"));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(7, 7));
EXPECT_EQ("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86", input->value().Utf8());
Controller().DeleteSurroundingText(3, 0);
- EXPECT_EQ("foo", input->value());
+ EXPECT_EQ("foo\xED\xA0\xBC", input->value().Utf8());
// "trophy" + "trophy".
input->setValue(String::FromUTF8("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86"));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(7, 7));
EXPECT_EQ("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86", input->value().Utf8());
Controller().DeleteSurroundingText(4, 0);
@@ -707,7 +705,7 @@ TEST_F(InputMethodControllerTest,
// "trophy" + "trophy".
input->setValue(String::FromUTF8("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86"));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(7, 7));
EXPECT_EQ("foo\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86", input->value().Utf8());
Controller().DeleteSurroundingText(5, 0);
@@ -721,7 +719,7 @@ TEST_F(InputMethodControllerTest,
// U+2605 == "black star". It takes up 1 space.
input->setValue(String::FromUTF8("\xE2\x98\x85 foo"));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(0, 0));
EXPECT_EQ("\xE2\x98\x85 foo", input->value().Utf8());
Controller().DeleteSurroundingText(0, 1);
@@ -729,23 +727,23 @@ TEST_F(InputMethodControllerTest,
// U+1F3C6 == "trophy". It takes up 2 space.
input->setValue(String::FromUTF8("\xF0\x9F\x8F\x86 foo"));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(0, 0));
EXPECT_EQ("\xF0\x9F\x8F\x86 foo", input->value().Utf8());
Controller().DeleteSurroundingText(0, 1);
- EXPECT_EQ(" foo", input->value());
+ EXPECT_EQ("\xED\xBF\x86 foo", input->value().Utf8());
// composed U+0E01 "ka kai" + U+0E49 "mai tho". It takes up 2 space.
input->setValue(String::FromUTF8("\xE0\xB8\x81\xE0\xB9\x89 foo"));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(0, 0));
EXPECT_EQ("\xE0\xB8\x81\xE0\xB9\x89 foo", input->value().Utf8());
Controller().DeleteSurroundingText(0, 1);
- EXPECT_EQ(" foo", input->value());
+ EXPECT_EQ("\xE0\xB9\x89 foo", input->value().Utf8());
// "trophy" + "trophy".
input->setValue(String::FromUTF8("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo"));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(0, 0));
EXPECT_EQ("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo", input->value().Utf8());
Controller().DeleteSurroundingText(0, 2);
@@ -753,15 +751,15 @@ TEST_F(InputMethodControllerTest,
// "trophy" + "trophy".
input->setValue(String::FromUTF8("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo"));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(0, 0));
EXPECT_EQ("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo", input->value().Utf8());
Controller().DeleteSurroundingText(0, 3);
- EXPECT_EQ(" foo", input->value());
+ EXPECT_EQ("\xED\xBF\x86 foo", input->value().Utf8());
// "trophy" + "trophy".
input->setValue(String::FromUTF8("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo"));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(0, 0));
EXPECT_EQ("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo", input->value().Utf8());
Controller().DeleteSurroundingText(0, 4);
@@ -769,7 +767,7 @@ TEST_F(InputMethodControllerTest,
// "trophy" + "trophy".
input->setValue(String::FromUTF8("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo"));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(0, 0));
EXPECT_EQ("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86 foo", input->value().Utf8());
Controller().DeleteSurroundingText(0, 5);
@@ -783,11 +781,29 @@ TEST_F(InputMethodControllerTest,
// "trophy" + "trophy".
input->setValue(String::FromUTF8("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86"));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(2, 2));
EXPECT_EQ("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86", input->value().Utf8());
Controller().DeleteSurroundingText(1, 1);
- EXPECT_EQ("", input->value());
+ // Deleted second half of the first trophy and the first half of the second
+ // trophy, so we ended up with a complete trophy.
+ EXPECT_EQ("\xF0\x9F\x8F\x86", input->value().Utf8());
+}
+
+// This test comes from http://crbug.com/1024738. It is basically the same to
+// composed text (U+0E01 "ka kai" + U+0E49 "mai tho"), but easier to understand.
+TEST_F(InputMethodControllerTest, DeleteSurroundingTextForComposedCharacter) {
+ auto* input =
+ To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample"));
+ // p̂p̂ (U+0070 U+0302 U+0070 U+0302)
+ input->setValue(String::FromUTF8("\x70\xCC\x82\x70\xCC\x82"));
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
+ Controller().SetEditableSelectionOffsets(PlainTextRange(4, 4));
+ EXPECT_EQ("\x70\xCC\x82\x70\xCC\x82", input->value().Utf8());
+ Controller().DeleteSurroundingText(1, 0);
+ EXPECT_EQ("\x70\xCC\x82\x70", input->value().Utf8());
+ Controller().DeleteSurroundingText(1, 0);
+ EXPECT_EQ("\x70\xCC\x82", input->value().Utf8());
}
TEST_F(InputMethodControllerTest, DeleteSurroundingTextForMultipleNodes) {
@@ -833,7 +849,7 @@ TEST_F(InputMethodControllerTest,
// [1,2,2].
input->setValue(String::FromUTF8(
"a\xE2\x98\x85 \xF0\x9F\x8F\x86 \xE0\xB8\x81\xE0\xB9\x89"));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
// The cursor is at the end of the text.
Controller().SetEditableSelectionOffsets(PlainTextRange(8, 8));
@@ -845,15 +861,14 @@ TEST_F(InputMethodControllerTest,
// 'a' + "black star" + SPACE + "trophy" + SPACE + composed text
input->setValue(String::FromUTF8(
"a\xE2\x98\x85 \xF0\x9F\x8F\x86 \xE0\xB8\x81\xE0\xB9\x89"));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
// The cursor is at the end of the text.
Controller().SetEditableSelectionOffsets(PlainTextRange(8, 8));
- // TODO(yabinh): We should only delete 1 code point instead of the entire
- // grapheme cluster (2 code points). The root cause is that we adjust the
- // selection by grapheme cluster in deleteSurroundingText().
+ // We should only delete 1 code point.
Controller().DeleteSurroundingTextInCodePoints(1, 0);
- EXPECT_EQ("a\xE2\x98\x85 \xF0\x9F\x8F\x86 ", input->value().Utf8());
+ EXPECT_EQ("a\xE2\x98\x85 \xF0\x9F\x8F\x86 \xE0\xB8\x81",
+ input->value().Utf8());
}
TEST_F(InputMethodControllerTest,
@@ -864,15 +879,15 @@ TEST_F(InputMethodControllerTest,
// 'a' + "black star" + SPACE + "trophy" + SPACE + composed text
input->setValue(String::FromUTF8(
"a\xE2\x98\x85 \xF0\x9F\x8F\x86 \xE0\xB8\x81\xE0\xB9\x89"));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(0, 0));
Controller().DeleteSurroundingTextInCodePoints(0, 5);
EXPECT_EQ("\xE0\xB8\x81\xE0\xB9\x89", input->value().Utf8());
Controller().DeleteSurroundingTextInCodePoints(0, 1);
- // TODO(yabinh): Same here. We should only delete 1 code point.
- EXPECT_EQ("", input->value());
+ // We should only delete 1 code point.
+ EXPECT_EQ("\xE0\xB9\x89", input->value().Utf8());
}
TEST_F(InputMethodControllerTest,
@@ -883,7 +898,7 @@ TEST_F(InputMethodControllerTest,
// 'a' + "black star" + SPACE + "trophy" + SPACE + composed text
input->setValue(String::FromUTF8(
"a\xE2\x98\x85 \xF0\x9F\x8F\x86 \xE0\xB8\x81\xE0\xB9\x89"));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(3, 3));
Controller().DeleteSurroundingTextInCodePoints(2, 2);
EXPECT_EQ("a\xE0\xB8\x81\xE0\xB9\x89", input->value().Utf8());
@@ -913,7 +928,7 @@ TEST_F(InputMethodControllerTest,
const String& text = String(kUText);
input->setValue(text);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
// The invalid high surrogate is encoded as '\xED\xA0\xBC', and invalid low
// surrogate is encoded as '\xED\xBF\x86'.
EXPECT_EQ("a\xED\xA0\xBC\xE2\x98\x85\xED\xBF\x86 ", input->value().Utf8());
@@ -940,16 +955,16 @@ TEST_F(InputMethodControllerTest, SetCompositionForInputWithNewCaretPositions) {
To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample"));
input->setValue("hello");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(2, 2));
EXPECT_EQ("hello", input->value());
EXPECT_EQ(2u, Controller().GetSelectionOffsets().Start());
EXPECT_EQ(2u, Controller().GetSelectionOffsets().End());
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 2,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 2, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
// The caret exceeds left boundary.
// "*heABllo", where * stands for caret.
@@ -1013,9 +1028,9 @@ TEST_F(InputMethodControllerTest,
EXPECT_EQ(17u, Controller().GetSelectionOffsets().End());
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 2,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 2, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
// The caret exceeds left boundary.
// "*hello\nworld\n\n01234AB56789", where * stands for caret.
@@ -1105,13 +1120,13 @@ TEST_F(InputMethodControllerTest, SetCompositionWithEmptyText) {
EXPECT_EQ(2u, Controller().GetSelectionOffsets().End());
Vector<ImeTextSpan> ime_text_spans0;
- ime_text_spans0.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 0,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans0.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 0, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Vector<ImeTextSpan> ime_text_spans2;
- ime_text_spans2.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 2,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans2.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 2, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().SetComposition("AB", ime_text_spans2, 2, 2);
// With previous composition.
@@ -1132,9 +1147,9 @@ TEST_F(InputMethodControllerTest, InsertLineBreakWhileComposingText) {
InsertHTMLElement("<div id='sample' contenteditable></div>", "sample");
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().SetComposition("hello", ime_text_spans, 5, 5);
EXPECT_EQ("hello", div->innerText());
EXPECT_EQ(5u, Controller().GetSelectionOffsets().Start());
@@ -1151,9 +1166,9 @@ TEST_F(InputMethodControllerTest, InsertLineBreakAfterConfirmingText) {
InsertHTMLElement("<div id='sample' contenteditable></div>", "sample");
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 2,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 2, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().CommitText("hello", ime_text_spans, 0);
EXPECT_EQ("hello", div->innerText());
@@ -1172,7 +1187,7 @@ TEST_F(InputMethodControllerTest, CompositionInputEventIsComposing) {
Element* editable =
InsertHTMLElement("<div id='sample' contenteditable></div>", "sample");
Element* script = GetDocument().CreateRawElement(html_names::kScriptTag);
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
"document.getElementById('sample').addEventListener('beforeinput', "
" event => document.title = "
" `beforeinput.isComposing:${event.isComposing};`);"
@@ -1184,9 +1199,9 @@ TEST_F(InputMethodControllerTest, CompositionInputEventIsComposing) {
// Simulate composition in the |contentEditable|.
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
editable->focus();
GetDocument().setTitle(g_empty_string);
@@ -1206,9 +1221,9 @@ TEST_F(InputMethodControllerTest, CompositionInputEventForReplace) {
// Simulate composition in the |contentEditable|.
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
GetDocument().setTitle(g_empty_string);
Controller().SetComposition("hell", ime_text_spans, 4, 4);
@@ -1225,9 +1240,9 @@ TEST_F(InputMethodControllerTest, CompositionInputEventForConfirm) {
// Simulate composition in the |contentEditable|.
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
GetDocument().setTitle(g_empty_string);
Controller().SetComposition("hello", ime_text_spans, 5, 5);
@@ -1244,9 +1259,9 @@ TEST_F(InputMethodControllerTest, CompositionInputEventForDelete) {
// Simulate composition in the |contentEditable|.
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
GetDocument().setTitle(g_empty_string);
Controller().SetComposition("hello", ime_text_spans, 5, 5);
@@ -1264,13 +1279,13 @@ TEST_F(InputMethodControllerTest, CompositionInputEventForInsert) {
// Simulate composition in the |contentEditable|.
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
// Insert new text without previous composition.
GetDocument().setTitle(g_empty_string);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().CommitText("hello", ime_text_spans, 0);
EXPECT_EQ("beforeinput.data:hello;input.data:hello;", GetDocument().title());
@@ -1280,7 +1295,7 @@ TEST_F(InputMethodControllerTest, CompositionInputEventForInsert) {
// Insert new text with previous composition.
GetDocument().setTitle(g_empty_string);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().CommitText("hello", ime_text_spans, 1);
EXPECT_EQ(
"beforeinput.data:hello;input.data:hello;compositionend.data:hello;",
@@ -1292,13 +1307,13 @@ TEST_F(InputMethodControllerTest, CompositionInputEventForInsertEmptyText) {
// Simulate composition in the |contentEditable|.
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
// Insert empty text without previous composition.
GetDocument().setTitle(g_empty_string);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().CommitText("", ime_text_spans, 0);
EXPECT_EQ("", GetDocument().title().Utf8());
@@ -1308,7 +1323,7 @@ TEST_F(InputMethodControllerTest, CompositionInputEventForInsertEmptyText) {
// Insert empty text with previous composition.
GetDocument().setTitle(g_empty_string);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().CommitText("", ime_text_spans, 1);
EXPECT_EQ("beforeinput.data:;input.data:null;compositionend.data:;",
GetDocument().title());
@@ -1319,19 +1334,19 @@ TEST_F(InputMethodControllerTest, CompositionEndEventWithNoSelection) {
// Simulate composition in the |contentEditable|.
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().SetComposition("hello", ime_text_spans, 1, 1);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_EQ(1u, Controller().GetSelectionOffsets().Start());
EXPECT_EQ(1u, Controller().GetSelectionOffsets().End());
// Confirm the ongoing composition. Note that it moves the caret to the end of
// text [5,5] before firing 'compositonend' event.
Controller().FinishComposingText(InputMethodController::kDoNotKeepSelection);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_TRUE(Controller().GetSelectionOffsets().IsNull());
}
@@ -1346,7 +1361,7 @@ TEST_F(InputMethodControllerTest, FinishCompositionRemovedRange) {
EXPECT_EQ(kWebTextInputTypeText, Controller().TextInputType());
// Remove element 'a'.
- input_a->SetOuterHTMLFromString("", ASSERT_NO_EXCEPTION);
+ input_a->setOuterHTML("", ASSERT_NO_EXCEPTION);
EXPECT_EQ(kWebTextInputTypeNone, Controller().TextInputType());
GetDocument().getElementById("b")->focus();
@@ -1374,9 +1389,9 @@ TEST_F(InputMethodControllerTest, SetCompositionPlainTextWithIme_Text_Span) {
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, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 1, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().SetComposition(" ", ime_text_spans, 1, 1);
@@ -1394,9 +1409,9 @@ TEST_F(InputMethodControllerTest, CommitPlainTextWithIme_Text_SpanInsert) {
Controller().SetEditableSelectionOffsets(PlainTextRange(8, 8));
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 1, 11,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 1, 11, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().CommitText(String("ime_text_spand"), ime_text_spans, 0);
@@ -1414,9 +1429,9 @@ TEST_F(InputMethodControllerTest, CommitPlainTextWithIme_Text_SpanReplace) {
Controller().SetCompositionFromExistingText(ime_text_spans, 8, 12);
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 1, 11,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 1, 11, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().CommitText(String("string"), ime_text_spans, 0);
@@ -1437,9 +1452,9 @@ TEST_F(InputMethodControllerTest, ImeTextSpanAppearsCorrectlyAfterNewline) {
Controller().SetCompositionFromExistingText(ime_text_spans, 8, 8);
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().SetComposition(String("world"), ime_text_spans, 0, 0);
ASSERT_EQ(1u, GetDocument().Markers().Markers().size());
@@ -1473,9 +1488,9 @@ TEST_F(InputMethodControllerTest, SelectionWhenFocusChangeFinishesComposition) {
// Simulate composition in the |contentEditable|.
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 5,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 5, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().SetComposition("foo", ime_text_spans, 3, 3);
EXPECT_TRUE(Controller().HasComposition());
@@ -1516,13 +1531,13 @@ TEST_F(InputMethodControllerTest, SetEmptyCompositionShouldNotMoveCaret) {
To<HTMLTextAreaElement>(InsertHTMLElement("<textarea id='txt'>", "txt"));
textarea->setValue("abc\n");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Controller().SetEditableSelectionOffsets(PlainTextRange(4, 4));
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 3,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 3, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().SetComposition(String("def"), ime_text_spans, 0, 3);
Controller().SetComposition(String(""), ime_text_spans, 0, 3);
Controller().CommitText(String("def"), ime_text_spans, 0);
@@ -1541,14 +1556,14 @@ TEST_F(InputMethodControllerTest, WhitespaceFixup) {
// The space at the beginning of the string should have been converted to an
// nbsp
- EXPECT_EQ("&nbsp;text blah", div->InnerHTMLAsString());
+ EXPECT_EQ("&nbsp;text blah", div->innerHTML());
// Delete "blah"
Controller().SetCompositionFromExistingText(empty_ime_text_spans, 6, 10);
Controller().CommitText(String(""), empty_ime_text_spans, 0);
// The space at the end of the string should have been converted to an nbsp
- EXPECT_EQ("&nbsp;text&nbsp;", div->InnerHTMLAsString());
+ EXPECT_EQ("&nbsp;text&nbsp;", div->innerHTML());
}
TEST_F(InputMethodControllerTest, CommitEmptyTextDeletesSelection) {
@@ -1556,7 +1571,7 @@ TEST_F(InputMethodControllerTest, CommitEmptyTextDeletesSelection) {
To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample"));
input->setValue("Abc Def Ghi");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Vector<ImeTextSpan> empty_ime_text_spans;
Controller().SetEditableSelectionOffsets(PlainTextRange(4, 8));
Controller().CommitText(String(""), empty_ime_text_spans, 0);
@@ -1585,7 +1600,8 @@ TEST_F(InputMethodControllerTest,
// persist across editing operations)
EphemeralRange marker_range = PlainTextRange(8, 12).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
// Delete "Initial"
Vector<ImeTextSpan> empty_ime_text_spans;
Controller().SetCompositionFromExistingText(empty_ime_text_spans, 0, 7);
@@ -1613,7 +1629,8 @@ TEST_F(InputMethodControllerTest,
// persist across editing operations)
EphemeralRange marker_range = PlainTextRange(7, 12).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
// Delete "Initial"
Vector<ImeTextSpan> empty_ime_text_spans;
Controller().SetCompositionFromExistingText(empty_ime_text_spans, 0, 7);
@@ -1640,7 +1657,8 @@ TEST_F(InputMethodControllerTest,
// persist across editing operations)
EphemeralRange marker_range = PlainTextRange(8, 13).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
// Delete "Initial"
Vector<ImeTextSpan> empty_ime_text_spans;
Controller().SetCompositionFromExistingText(empty_ime_text_spans, 0, 7);
@@ -1668,7 +1686,8 @@ TEST_F(
// persist across editing operations)
EphemeralRange marker_range = PlainTextRange(7, 13).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
// Delete "Initial"
Vector<ImeTextSpan> empty_ime_text_spans;
@@ -1713,7 +1732,8 @@ TEST_F(InputMethodControllerTest,
// Add marker under "Initial text"
EphemeralRange marker_range = PlainTextRange(0, 12).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
// Replace "Initial" with "Original"
Vector<ImeTextSpan> empty_ime_text_spans;
@@ -1756,7 +1776,8 @@ TEST_F(InputMethodControllerTest,
// Add marker under "initial text"
EphemeralRange marker_range = PlainTextRange(13, 25).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
// Replace "some initial" with "boring"
Vector<ImeTextSpan> empty_ime_text_spans;
@@ -1794,7 +1815,8 @@ TEST_F(InputMethodControllerTest, ContentIndependentMarker_ReplaceEndOfMarker) {
// Add marker under "Initial text"
EphemeralRange marker_range = PlainTextRange(0, 12).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
// Replace "text" with "string"
Vector<ImeTextSpan> empty_ime_text_spans;
@@ -1824,7 +1846,7 @@ TEST_F(InputMethodControllerTest,
Controller().SetCompositionFromExistingText(empty_ime_text_spans, 13, 25);
Controller().CommitText(String("content"), empty_ime_text_spans, 0);
- EXPECT_EQ("This is some content", div->InnerHTMLAsString());
+ EXPECT_EQ("This is some content", div->innerHTML());
// Verify marker was removed
EXPECT_EQ(0u, GetDocument().Markers().Markers().size());
@@ -1839,14 +1861,15 @@ TEST_F(InputMethodControllerTest,
// Add marker under "some initial"
EphemeralRange marker_range = PlainTextRange(8, 20).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
// Replace "initial text" with "content"
Vector<ImeTextSpan> empty_ime_text_spans;
Controller().SetCompositionFromExistingText(empty_ime_text_spans, 13, 25);
Controller().CommitText(String("content"), empty_ime_text_spans, 0);
- EXPECT_EQ("This is some content", div->InnerHTMLAsString());
+ EXPECT_EQ("This is some content", div->innerHTML());
// Verify marker is under "some "
EXPECT_EQ(1u, GetDocument().Markers().Markers().size());
@@ -1880,7 +1903,8 @@ TEST_F(InputMethodControllerTest,
// Add marker under "text"
EphemeralRange marker_range = PlainTextRange(8, 12).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
// Replace "text" with "string"
Vector<ImeTextSpan> empty_ime_text_spans;
@@ -1923,7 +1947,8 @@ TEST_F(InputMethodControllerTest,
// Add marker under "Initial"
EphemeralRange marker_range = PlainTextRange(0, 7).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
EXPECT_EQ(1u, GetDocument().Markers().Markers().size());
@@ -1965,7 +1990,8 @@ TEST_F(InputMethodControllerTest,
// Add marker under "text"
EphemeralRange marker_range = PlainTextRange(8, 12).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
EXPECT_EQ(1u, GetDocument().Markers().Markers().size());
@@ -2027,23 +2053,28 @@ TEST_F(InputMethodControllerTest, ContentIndependentMarker_Deletions) {
EphemeralRange marker_range = PlainTextRange(0, 5).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
marker_range = PlainTextRange(5, 10).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
marker_range = PlainTextRange(10, 15).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
marker_range = PlainTextRange(15, 20).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
marker_range = PlainTextRange(20, 25).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
EXPECT_EQ(5u, GetDocument().Markers().Markers().size());
@@ -2095,7 +2126,8 @@ TEST_F(InputMethodControllerTest,
EphemeralRange marker_range = PlainTextRange(5, 10).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, 0, Color::kBlack);
EXPECT_EQ(1u, GetDocument().Markers().Markers().size());
@@ -2132,7 +2164,8 @@ TEST_F(InputMethodControllerTest,
EphemeralRange marker_range = PlainTextRange(5, 10).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, 0, Color::kBlack);
// Delete middle of marker
Vector<ImeTextSpan> empty_ime_text_spans;
@@ -2187,15 +2220,18 @@ TEST_F(InputMethodControllerTest,
EphemeralRange marker_range = PlainTextRange(0, 5).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, 0, Color::kBlack);
marker_range = PlainTextRange(5, 10).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, 0, Color::kBlack);
marker_range = PlainTextRange(10, 15).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, 0, Color::kBlack);
EXPECT_EQ(3u, GetDocument().Markers().Markers().size());
@@ -2259,15 +2295,18 @@ TEST_F(InputMethodControllerTest,
EphemeralRange marker_range = PlainTextRange(0, 5).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, 0, Color::kBlack);
marker_range = PlainTextRange(5, 15).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, 0, Color::kBlack);
marker_range = PlainTextRange(15, 20).CreateRange(*div);
GetDocument().Markers().AddActiveSuggestionMarker(
- marker_range, Color::kBlack, ImeTextSpanThickness::kThin, Color::kBlack);
+ marker_range, Color::kBlack, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, 0, Color::kBlack);
EXPECT_EQ(3u, GetDocument().Markers().Markers().size());
@@ -2297,7 +2336,8 @@ TEST_F(InputMethodControllerTest,
// Try to commit a non-misspelling suggestion marker.
ime_text_spans.push_back(
ImeTextSpan(ImeTextSpan::Type::kSuggestion, 0, 5, Color::kTransparent,
- ImeTextSpanThickness::kNone, Color::kTransparent));
+ ImeTextSpanThickness::kNone, ImeTextSpanUnderlineStyle::kNone,
+ Color::kTransparent, Color::kTransparent));
Controller().CommitText("hello", ime_text_spans, 1);
// The marker should have been added.
@@ -2314,7 +2354,8 @@ TEST_F(InputMethodControllerTest,
// Try to commit a non-misspelling suggestion marker.
ime_text_spans.push_back(ImeTextSpan(
ImeTextSpan::Type::kMisspellingSuggestion, 0, 5, Color::kTransparent,
- ImeTextSpanThickness::kNone, Color::kTransparent));
+ ImeTextSpanThickness::kNone, ImeTextSpanUnderlineStyle::kNone,
+ Color::kTransparent, Color::kTransparent));
Controller().CommitText("hello", ime_text_spans, 1);
// The marker should not have been added since the div has spell checking
@@ -2330,7 +2371,8 @@ TEST_F(InputMethodControllerTest, RemoveSuggestionMarkerInRangeOnFinish) {
Vector<ImeTextSpan> ime_text_spans;
ime_text_spans.push_back(ImeTextSpan(
ImeTextSpan::Type::kMisspellingSuggestion, 0, 5, Color::kTransparent,
- ImeTextSpanThickness::kNone, Color::kTransparent, Color ::kTransparent,
+ ImeTextSpanThickness::kNone, ImeTextSpanUnderlineStyle::kNone,
+ Color::kTransparent, Color::kTransparent, Color ::kTransparent,
/* remove_on_finish_composing */ true));
// Case 1: SetComposition() -> FinishComposingText() removes the suggestion
@@ -2402,9 +2444,9 @@ TEST_F(InputMethodControllerTest, CompositionUnderlineSpansMultipleNodes) {
Element* div = InsertHTMLElement(
"<div id='sample' contenteditable><b>t</b>est</div>", "sample");
Vector<ImeTextSpan> ime_text_spans;
- ime_text_spans.push_back(ImeTextSpan(ImeTextSpan::Type::kComposition, 0, 4,
- Color(255, 0, 0),
- ImeTextSpanThickness::kThin, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 4, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().SetCompositionFromExistingText(Vector<ImeTextSpan>(), 0, 4);
Controller().SetComposition("test", ime_text_spans, 0, 4);
@@ -2483,9 +2525,9 @@ TEST_F(InputMethodControllerTest,
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, 0));
+ ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, 1, Color(255, 0, 0),
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid, 0, 0));
Controller().CommitText(" ", ime_text_spans, 0);
// Add character U+094D: 'DEVANAGARI SIGN VIRAMA'
Controller().SetComposition(String::FromUTF8("\xE0\xA5\x8D"), ime_text_spans,
@@ -2545,7 +2587,7 @@ TEST_F(InputMethodControllerTest,
GetDocument().GetSettings()->SetScriptEnabled(true);
Element* script = GetDocument().CreateRawElement(html_names::kScriptTag);
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
"document.getElementById('sample').addEventListener('input', "
" event => {"
" const node = event.currentTarget;"
@@ -2580,7 +2622,7 @@ TEST_F(InputMethodControllerTest,
GetDocument().GetSettings()->SetScriptEnabled(true);
Element* script = GetDocument().CreateRawElement(html_names::kScriptTag);
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
"document.getElementById('sample').addEventListener('input', "
" event => {"
" const node = event.currentTarget;"
@@ -2618,7 +2660,7 @@ TEST_F(
GetDocument().GetSettings()->SetScriptEnabled(true);
Element* script = GetDocument().CreateRawElement(html_names::kScriptTag);
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
"document.getElementById('sample').addEventListener('input', "
" event => {"
" const node = event.currentTarget;"
@@ -2651,7 +2693,7 @@ TEST_F(InputMethodControllerTest,
GetDocument().GetSettings()->SetScriptEnabled(true);
Element* script = GetDocument().CreateRawElement(html_names::kScriptTag);
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
"document.getElementById('sample').addEventListener('input', "
" event => {"
" const node = event.currentTarget;"
@@ -2685,7 +2727,7 @@ TEST_F(InputMethodControllerTest,
GetDocument().GetSettings()->SetScriptEnabled(true);
Element* script = GetDocument().CreateRawElement(html_names::kScriptTag);
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
"document.getElementById('sample').addEventListener('input', "
" event => {"
" const node = event.currentTarget;"
@@ -2719,7 +2761,7 @@ TEST_F(InputMethodControllerTest,
GetDocument().GetSettings()->SetScriptEnabled(true);
Element* script = GetDocument().CreateRawElement(html_names::kScriptTag);
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
"document.getElementById('sample').addEventListener('input', "
" event => {"
" const node = event.currentTarget;"
@@ -2752,7 +2794,7 @@ TEST_F(InputMethodControllerTest,
GetDocument().GetSettings()->SetScriptEnabled(true);
Element* script = GetDocument().CreateRawElement(html_names::kScriptTag);
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
"document.getElementById('sample').addEventListener('input', "
" event => {"
" const node = event.currentTarget;"
@@ -2789,7 +2831,7 @@ TEST_F(InputMethodControllerTest,
GetDocument().GetSettings()->SetScriptEnabled(true);
Element* script = GetDocument().CreateRawElement(html_names::kScriptTag);
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
"document.getElementById('sample').addEventListener('compositionend', "
" event => {"
" const node = event.currentTarget;"
@@ -2825,7 +2867,7 @@ TEST_F(
GetDocument().GetSettings()->SetScriptEnabled(true);
Element* script = GetDocument().CreateRawElement(html_names::kScriptTag);
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
"document.getElementById('sample').addEventListener('compositionend', "
" event => {"
" const node = event.currentTarget;"
@@ -2859,7 +2901,7 @@ TEST_F(
GetDocument().GetSettings()->SetScriptEnabled(true);
Element* script = GetDocument().CreateRawElement(html_names::kScriptTag);
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
"document.getElementById('sample').addEventListener('compositionend', "
" event => {"
" const node = event.currentTarget;"
@@ -2892,7 +2934,7 @@ TEST_F(InputMethodControllerTest,
GetDocument().GetSettings()->SetScriptEnabled(true);
Element* script = GetDocument().CreateRawElement(html_names::kScriptTag);
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
"document.getElementById('sample').addEventListener('compositionend', "
" event => {"
" const node = event.currentTarget;"
@@ -2924,7 +2966,7 @@ TEST_F(InputMethodControllerTest,
GetDocument().GetSettings()->SetScriptEnabled(true);
Element* script = GetDocument().CreateRawElement(html_names::kScriptTag);
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
"document.getElementById('sample').addEventListener('compositionend', "
" event => {"
" const node = event.currentTarget;"
@@ -2956,7 +2998,7 @@ TEST_F(InputMethodControllerTest,
GetDocument().GetSettings()->SetScriptEnabled(true);
Element* script = GetDocument().CreateRawElement(html_names::kScriptTag);
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
"document.getElementById('sample').addEventListener('input', "
" event => {"
" const node = event.currentTarget;"
@@ -2986,7 +3028,7 @@ TEST_F(InputMethodControllerTest,
GetDocument().GetSettings()->SetScriptEnabled(true);
Element* script = GetDocument().CreateRawElement(html_names::kScriptTag);
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
"document.getElementById('sample').addEventListener('input', "
" event => {"
" const node = event.currentTarget;"
@@ -3016,7 +3058,7 @@ TEST_F(InputMethodControllerTest,
GetDocument().GetSettings()->SetScriptEnabled(true);
Element* script = GetDocument().CreateRawElement(html_names::kScriptTag);
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
"document.getElementById('sample').addEventListener('compositionend', "
" event => {"
" const node = event.currentTarget;"
@@ -3048,7 +3090,7 @@ TEST_F(
GetDocument().GetSettings()->SetScriptEnabled(true);
Element* script = GetDocument().CreateRawElement(html_names::kScriptTag);
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
"document.getElementById('sample').addEventListener('compositionend', "
" event => {"
" const node = event.currentTarget;"
@@ -3163,7 +3205,7 @@ TEST_F(InputMethodControllerTest, AutocapitalizeTextInputFlags) {
const int expected_flags = element_and_expected_flags_pair.second;
GetDocument().write(element);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
To<Element>(GetDocument().body()->lastChild())->focus();
EXPECT_EQ(expected_flags,
@@ -3186,7 +3228,7 @@ TEST_F(InputMethodControllerTest, ExecCommandDuringComposition) {
Vector<ImeTextSpan>(), 10, 10);
// "world" should be bold.
- EXPECT_EQ("hello<b>world</b>", div->InnerHTMLAsString());
+ EXPECT_EQ("hello<b>world</b>", div->innerHTML());
}
TEST_F(InputMethodControllerTest, SetCompositionAfterNonEditableElement) {
@@ -3235,4 +3277,32 @@ TEST_F(InputMethodControllerTest, SetCompositionInTableCell) {
EXPECT_EQ(1u, range->endOffset());
}
+TEST_F(InputMethodControllerTest, SetCompositionInMyanmar) {
+ Element* div =
+ InsertHTMLElement("<div id='sample' contenteditable></div>", "sample");
+
+ // Add character U+200C: 'kZeroWidthNonJoinerCharacter' and Myanmar vowel
+ Controller().SetComposition(String::FromUTF8("\xE2\x80\x8C\xE1\x80\xB1"),
+ Vector<ImeTextSpan>(), 0, 0);
+
+ EXPECT_EQ(1u, div->CountChildren());
+ EXPECT_EQ(String::FromUTF8("\xE2\x80\x8C\xE1\x80\xB1"), div->innerHTML());
+
+ Range* range = GetCompositionRange();
+ EXPECT_EQ(0u, range->startOffset());
+ EXPECT_EQ(2u, range->endOffset());
+ Controller().CommitText(String::FromUTF8("\xE2\x80\x8C\xE1\x80\xB1"),
+ Vector<ImeTextSpan>(), 1);
+ EXPECT_EQ(String::FromUTF8("\xE2\x80\x8C\xE1\x80\xB1"), div->innerHTML());
+
+ // Add character U+200C: 'kZeroWidthNonJoinerCharacter' and Myanmar vowel
+ Controller().SetComposition(String::FromUTF8("\xE2\x80\x8C\xE1\x80\xB1"),
+ Vector<ImeTextSpan>(), 2, 2);
+ Controller().CommitText(String::FromUTF8("\xE2\x80\x8C\xE1\x80\xB1"),
+ Vector<ImeTextSpan>(), 1);
+ EXPECT_EQ(
+ String::FromUTF8("\xE2\x80\x8C\xE1\x80\xB1\xE2\x80\x8C\xE1\x80\xB1"),
+ div->innerHTML());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/editing/ime/text_format_update_event.cc b/chromium/third_party/blink/renderer/core/editing/ime/text_format_update_event.cc
index 8152313f19e..2a5696c3096 100644
--- a/chromium/third_party/blink/renderer/core/editing/ime/text_format_update_event.cc
+++ b/chromium/third_party/blink/renderer/core/editing/ime/text_format_update_event.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/core/editing/ime/text_format_update_event.h"
-#include "third_party/blink/renderer/core/editing/ime/text_format_update_event_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_text_format_update_event_init.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
#include "third_party/blink/renderer/core/event_type_names.h"
diff --git a/chromium/third_party/blink/renderer/core/editing/ime/text_format_update_event.idl b/chromium/third_party/blink/renderer/core/editing/ime/text_format_update_event.idl
index eb6046133b9..cbf87a6faae 100644
--- a/chromium/third_party/blink/renderer/core/editing/ime/text_format_update_event.idl
+++ b/chromium/third_party/blink/renderer/core/editing/ime/text_format_update_event.idl
@@ -8,10 +8,10 @@
// (e.g. backgroundColor, textDecoration, etc.).
// Explainer: https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/master/EditContext/explainer.md
[
- Constructor(optional TextFormatUpdateEventInit options),
Exposed=Window,
RuntimeEnabled=EditContext
] interface TextFormatUpdateEvent : Event {
+ constructor(optional TextFormatUpdateEventInit options = {});
readonly attribute unsigned long formatRangeStart;
readonly attribute unsigned long formatRangeEnd;
readonly attribute DOMString underlineColor;
diff --git a/chromium/third_party/blink/renderer/core/editing/ime/text_update_event.cc b/chromium/third_party/blink/renderer/core/editing/ime/text_update_event.cc
index bbf5d8bc1ea..4448dee70da 100644
--- a/chromium/third_party/blink/renderer/core/editing/ime/text_update_event.cc
+++ b/chromium/third_party/blink/renderer/core/editing/ime/text_update_event.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/core/editing/ime/text_update_event.h"
-#include "third_party/blink/renderer/core/editing/ime/text_update_event_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_text_update_event_init.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
#include "third_party/blink/renderer/core/event_type_names.h"
diff --git a/chromium/third_party/blink/renderer/core/editing/ime/text_update_event.idl b/chromium/third_party/blink/renderer/core/editing/ime/text_update_event.idl
index 5c1122fb292..f622e1862d1 100644
--- a/chromium/third_party/blink/renderer/core/editing/ime/text_update_event.idl
+++ b/chromium/third_party/blink/renderer/core/editing/ime/text_update_event.idl
@@ -9,10 +9,10 @@
// fired).
// Explainer: https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/master/EditContext/explainer.md
[
- Constructor(optional TextUpdateEventInit options),
Exposed=Window,
RuntimeEnabled=EditContext
] interface TextUpdateEvent : Event {
+ constructor(optional TextUpdateEventInit options = {});
readonly attribute unsigned long updateRangeStart;
readonly attribute unsigned long updateRangeEnd;
readonly attribute DOMString updateText;
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 44d1ff78963..9aa084812dd 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
@@ -25,6 +25,8 @@ std::ostream& operator<<(std::ostream& ostream,
class InlineBoxPositionTest : public EditingTestBase {};
TEST_F(InlineBoxPositionTest, ComputeInlineBoxPositionBidiIsolate) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
// InlineBoxPosition is a legacy-only data structure.
ScopedLayoutNGForTest scoped_layout_ng(false);
@@ -43,6 +45,8 @@ 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);
@@ -62,6 +66,8 @@ 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);
@@ -79,6 +85,8 @@ TEST_F(InlineBoxPositionTest, InFlatTreeAfterInputWithPlaceholderDoesntCrash) {
}
TEST_F(InlineBoxPositionTest, DownstreamBeforeLineBreakLTR) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
// InlineBoxPosition is a legacy-only data structure.
ScopedLayoutNGForTest scoped_layout_ng(false);
@@ -101,6 +109,8 @@ TEST_F(InlineBoxPositionTest, DownstreamBeforeLineBreakLTR) {
}
TEST_F(InlineBoxPositionTest, DownstreamBeforeLineBreakRTL) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
// InlineBoxPosition is a legacy-only data structure.
ScopedLayoutNGForTest scoped_layout_ng(false);
diff --git a/chromium/third_party/blink/renderer/core/editing/inline_box_traversal.cc b/chromium/third_party/blink/renderer/core/editing/inline_box_traversal.cc
index e6f9b75cc84..b3748d258a8 100644
--- a/chromium/third_party/blink/renderer/core/editing/inline_box_traversal.cc
+++ b/chromium/third_party/blink/renderer/core/editing/inline_box_traversal.cc
@@ -74,13 +74,13 @@ class AbstractInlineBox {
UBiDiLevel BidiLevel() const {
DCHECK(IsNotNull());
return IsOldLayout() ? GetInlineBox().BidiLevel()
- : line_cursor_.CurrentBidiLevel();
+ : line_cursor_.Current().BidiLevel();
}
TextDirection Direction() const {
DCHECK(IsNotNull());
return IsOldLayout() ? GetInlineBox().Direction()
- : line_cursor_.CurrentResolvedDirection();
+ : line_cursor_.Current().ResolvedDirection();
}
AbstractInlineBox PrevLeafChild() const {
@@ -131,7 +131,7 @@ class AbstractInlineBox {
DCHECK(IsNotNull());
if (IsOldLayout())
return ParagraphDirectionOf(GetInlineBox());
- return GetLineBox(line_cursor_).CurrentBaseDirection();
+ return GetLineBox(line_cursor_).Current().BaseDirection();
}
private:
@@ -189,7 +189,7 @@ bool IsAtFragmentStart(const NGCaretPosition& caret_position) {
case NGCaretPositionType::kAtTextOffset:
DCHECK(caret_position.text_offset.has_value());
return *caret_position.text_offset ==
- caret_position.cursor.CurrentTextStartOffset();
+ caret_position.cursor.Current().TextStartOffset();
}
NOTREACHED();
return false;
@@ -205,7 +205,7 @@ bool IsAtFragmentEnd(const NGCaretPosition& caret_position) {
case NGCaretPositionType::kAtTextOffset:
DCHECK(caret_position.text_offset.has_value());
return *caret_position.text_offset ==
- caret_position.cursor.CurrentTextEndOffset();
+ caret_position.cursor.Current().TextEndOffset();
}
NOTREACHED();
return false;
@@ -217,7 +217,7 @@ SideAffinity GetSideAffinity(const NGCaretPosition& caret_position) {
DCHECK(IsAtFragmentStart(caret_position) || IsAtFragmentEnd(caret_position));
const bool is_at_start = IsAtFragmentStart(caret_position);
const bool is_at_left_side =
- is_at_start == IsLtr(caret_position.cursor.CurrentResolvedDirection());
+ is_at_start == IsLtr(caret_position.cursor.Current().ResolvedDirection());
return is_at_left_side ? SideAffinity::kLeft : SideAffinity::kRight;
}
@@ -260,7 +260,7 @@ class AbstractInlineBoxAndSideAffinity {
const bool is_at_start = IsLtr(box_.Direction()) == AtLeftSide();
NGInlineCursor cursor(box_.GetCursor());
- if (!cursor.IsText()) {
+ if (!cursor.Current().IsText()) {
return {cursor,
is_at_start ? NGCaretPositionType::kBeforeBox
: NGCaretPositionType::kAfterBox,
@@ -268,8 +268,8 @@ class AbstractInlineBoxAndSideAffinity {
}
return {cursor, NGCaretPositionType::kAtTextOffset,
- is_at_start ? cursor.CurrentTextStartOffset()
- : cursor.CurrentTextEndOffset()};
+ is_at_start ? cursor.Current().TextStartOffset()
+ : cursor.Current().TextEndOffset()};
}
PositionInFlatTree GetPosition() const {
diff --git a/chromium/third_party/blink/renderer/core/editing/iterators/character_iterator_test.cc b/chromium/third_party/blink/renderer/core/editing/iterators/character_iterator_test.cc
index b6450e7cb53..845cf94c0d7 100644
--- a/chromium/third_party/blink/renderer/core/editing/iterators/character_iterator_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/iterators/character_iterator_test.cc
@@ -48,7 +48,9 @@ class ParameterizedCharacterIteratorTest
ParameterizedCharacterIteratorTest() : ScopedLayoutNGForTest(GetParam()) {}
protected:
- bool LayoutNGEnabled() const { return GetParam(); }
+ bool LayoutNGEnabled() const {
+ return RuntimeEnabledFeatures::LayoutNGEnabled();
+ }
};
INSTANTIATE_TEST_SUITE_P(All,
diff --git a/chromium/third_party/blink/renderer/core/editing/iterators/fully_clipped_state_stack.cc b/chromium/third_party/blink/renderer/core/editing/iterators/fully_clipped_state_stack.cc
index d19897a1f1f..0709db472e5 100644
--- a/chromium/third_party/blink/renderer/core/editing/iterators/fully_clipped_state_stack.cc
+++ b/chromium/third_party/blink/renderer/core/editing/iterators/fully_clipped_state_stack.cc
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/editing/editing_utilities.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/layout/layout_view.h"
namespace blink {
@@ -17,7 +18,7 @@ namespace {
inline bool FullyClipsContents(const Node* node) {
LayoutObject* layout_object = node->GetLayoutObject();
if (!layout_object || !layout_object->IsBox() ||
- !layout_object->HasOverflowClip() || layout_object->IsLayoutView())
+ !layout_object->HasOverflowClip() || IsA<LayoutView>(layout_object))
return false;
return ToLayoutBox(layout_object)->Size().IsEmpty();
}
diff --git a/chromium/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.cc b/chromium/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.cc
index 9128e858a11..6ba981cca82 100644
--- a/chromium/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.cc
+++ b/chromium/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.cc
@@ -224,7 +224,7 @@ bool SimplifiedBackwardsTextIteratorAlgorithm<Strategy>::HandleTextNode() {
return true;
String text = layout_object->GetText();
- if (!layout_object->HasTextBoxes() && text.length() > 0)
+ if (!layout_object->HasInlineFragments() && text.length() > 0)
return true;
const int position_end_offset = offset_;
diff --git a/chromium/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.h b/chromium/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.h
index 4d41206bf82..128bc4849df 100644
--- a/chromium/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.h
+++ b/chromium/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.h
@@ -104,17 +104,17 @@ class SimplifiedBackwardsTextIteratorAlgorithm {
// Current position, not necessarily of the text being returned, but position
// as we walk through the DOM tree.
- Member<const Node> node_;
+ const Node* node_;
int offset_;
bool handled_node_;
bool handled_children_;
FullyClippedStateStackAlgorithm<Strategy> fully_clipped_stack_;
// End of the range.
- Member<const Node> start_node_;
+ const Node* start_node_;
int start_offset_;
// Start of the range.
- Member<const Node> end_node_;
+ const Node* end_node_;
int end_offset_;
// Whether |node_| has advanced beyond the iteration range (i.e. start_node_).
diff --git a/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator.cc b/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator.cc
index 3e8c64b5c2c..31a98194236 100644
--- a/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator.cc
+++ b/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator.cc
@@ -176,9 +176,12 @@ bool ShouldHandleChildren(const Node& node,
if (!behavior.EntersTextControls() && IsTextControl(node))
return false;
- if (auto* element = DynamicTo<Element>(node)) {
- if (auto* context = element->GetDisplayLockContext()) {
- return context->IsActivatable(DisplayLockActivationReason::kSelection);
+ if (!behavior.IgnoresDisplayLock()) {
+ if (auto* element = DynamicTo<Element>(node)) {
+ if (auto* context = element->GetDisplayLockContext()) {
+ return !context->IsLocked() ||
+ context->IsActivatable(DisplayLockActivationReason::kSelection);
+ }
}
}
return true;
@@ -267,7 +270,7 @@ bool TextIteratorAlgorithm<Strategy>::HandleRememberedProgress() {
// FIXME: It would be cleaner if we emitted two newlines during the last
// iteration, instead of using needs_another_newline_.
Node* last_child = Strategy::LastChild(*node_);
- const Node* base_node = last_child ? last_child : node_.Get();
+ const Node* base_node = last_child ? last_child : node_;
EmitChar16AfterNode('\n', *base_node);
needs_another_newline_ = false;
return true;
@@ -310,26 +313,32 @@ void TextIteratorAlgorithm<Strategy>::Advance() {
node_ = nullptr;
return;
}
+
+ // If an element is locked, we shouldn't recurse down into its children
+ // since they might not have up-to-date layout. In particular, they might
+ // not have the NG offset mapping which is required. The display lock can
+ // still be bypassed by marking the iterator behavior to ignore display
+ // lock.
const bool locked =
+ !behavior_.IgnoresDisplayLock() &&
DisplayLockUtilities::NearestLockedInclusiveAncestor(*node_);
LayoutObject* layout_object = node_->GetLayoutObject();
if (!layout_object || locked) {
- if (!locked &&
- (IsA<ShadowRoot>(node_.Get()) || HasDisplayContents(*node_))) {
+ if (!locked && (IsA<ShadowRoot>(node_) || HasDisplayContents(*node_))) {
// Shadow roots or display: contents elements don't have LayoutObjects,
// but we want to visit children anyway.
iteration_progress_ = iteration_progress_ < kHandledNode
? kHandledNode
: iteration_progress_;
- handle_shadow_root_ = IsA<ShadowRoot>(node_.Get());
+ handle_shadow_root_ = IsA<ShadowRoot>(node_);
} else {
iteration_progress_ = kHandledChildren;
}
} else {
// Enter author shadow roots, from youngest, if any and if necessary.
if (iteration_progress_ < kHandledOpenShadowRoots) {
- auto* element = DynamicTo<Element>(node_.Get());
+ auto* element = DynamicTo<Element>(node_);
if (std::is_same<Strategy, EditingStrategy>::value &&
EntersOpenShadowRoots() && element && element->OpenShadowRoot()) {
ShadowRoot* youngest_shadow_root = element->OpenShadowRoot();
@@ -350,7 +359,7 @@ void TextIteratorAlgorithm<Strategy>::Advance() {
if (std::is_same<Strategy, EditingStrategy>::value &&
EntersTextControls() && layout_object->IsTextControl()) {
ShadowRoot* user_agent_shadow_root =
- To<Element>(node_.Get())->UserAgentShadowRoot();
+ To<Element>(node_)->UserAgentShadowRoot();
DCHECK(user_agent_shadow_root->IsUserAgent());
node_ = user_agent_shadow_root;
iteration_progress_ = kHandledNone;
@@ -374,7 +383,7 @@ void TextIteratorAlgorithm<Strategy>::Advance() {
(layout_object->IsImage() ||
layout_object->IsLayoutEmbeddedContent() ||
(html_element &&
- (IsHTMLFormControlElement(html_element) ||
+ (IsA<HTMLFormControlElement>(html_element) ||
IsA<HTMLLegendElement>(html_element) ||
IsA<HTMLImageElement>(html_element) ||
IsA<HTMLMeterElement>(html_element) ||
@@ -427,7 +436,7 @@ void TextIteratorAlgorithm<Strategy>::Advance() {
// 4. Reached the top of a shadow root. If it's created by author,
// then try to visit the next
// sibling shadow root, if any.
- const auto* shadow_root = DynamicTo<ShadowRoot>(node_.Get());
+ const auto* shadow_root = DynamicTo<ShadowRoot>(node_);
if (!shadow_root) {
NOTREACHED();
should_stop_ = true;
@@ -483,7 +492,7 @@ void TextIteratorAlgorithm<Strategy>::HandleTextNode() {
DCHECK_NE(last_text_node_, node_)
<< "We should never call HandleTextNode on the same node twice";
- const auto* text = To<Text>(node_.Get());
+ const auto* text = To<Text>(node_);
last_text_node_ = text;
// TODO(editing-dev): Introduce a |DOMOffsetRange| class so that we can pass
@@ -810,7 +819,7 @@ void TextIteratorAlgorithm<Strategy>::ExitNode() {
// case it is a block, because the run should start where the
// emitted character is positioned visually.
Node* last_child = Strategy::LastChild(*node_);
- const Node* base_node = last_child ? last_child : node_.Get();
+ const Node* base_node = last_child ? last_child : node_;
// FIXME: This shouldn't require the last_text_node to be true, but we can't
// change that without making the logic in _web_attributedStringFromRange
// match. We'll get that for free when we switch to use TextIterator in
diff --git a/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator.h b/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator.h
index 1f6e69d5285..c7cba216a98 100644
--- a/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator.h
+++ b/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator.h
@@ -198,18 +198,18 @@ class TextIteratorAlgorithm {
void EnsurePositionContainer() const;
// The range.
- const Member<const Node> start_container_;
+ const Node* const start_container_;
const unsigned start_offset_;
- const Member<const Node> end_container_;
+ const Node* const end_container_;
const unsigned end_offset_;
// |end_node_| stores |Strategy::ChildAt(*end_container_, end_offfset_ - 1)|,
// if it exists, or |nullptr| otherwise.
- const Member<const Node> end_node_;
- const Member<const Node> past_end_node_;
+ const Node* const end_node_;
+ const Node* const past_end_node_;
// Current position, not necessarily of the text being returned, but position
// as we walk through the DOM tree.
- Member<const Node> node_;
+ const Node* node_;
IterationProgress iteration_progress_;
FullyClippedStateStackAlgorithm<Strategy> fully_clipped_stack_;
unsigned shadow_depth_;
@@ -219,7 +219,7 @@ class TextIteratorAlgorithm {
bool needs_another_newline_ = false;
bool needs_handle_replaced_element_ = false;
- Member<const Text> last_text_node_;
+ const Text* last_text_node_ = nullptr;
const TextIteratorBehavior behavior_;
diff --git a/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.cc b/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.cc
index d8291acea5a..98cabe8caca 100644
--- a/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.cc
+++ b/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.cc
@@ -130,6 +130,12 @@ TextIteratorBehavior::Builder::SetSuppressesExtraNewlineEmission(bool value) {
behavior_.values_.bits.suppresses_newline_emission = value;
return *this;
}
+
+TextIteratorBehavior::Builder&
+TextIteratorBehavior::Builder::SetIgnoresDisplayLock(bool value) {
+ behavior_.values_.bits.ignores_display_lock = value;
+ return *this;
+}
// -
TextIteratorBehavior::TextIteratorBehavior(const TextIteratorBehavior& other) =
default;
@@ -138,8 +144,6 @@ TextIteratorBehavior::TextIteratorBehavior() {
values_.all = 0;
}
-TextIteratorBehavior::~TextIteratorBehavior() = default;
-
bool TextIteratorBehavior::operator==(const TextIteratorBehavior& other) const {
return values_.all == other.values_.all;
}
diff --git a/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.h b/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.h
index 232842e603a..f198a7a4457 100644
--- a/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.h
+++ b/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.h
@@ -19,7 +19,6 @@ class CORE_EXPORT TextIteratorBehavior final {
TextIteratorBehavior(const TextIteratorBehavior& other);
TextIteratorBehavior();
- ~TextIteratorBehavior();
bool operator==(const TextIteratorBehavior& other) const;
bool operator!=(const TextIteratorBehavior& other) const;
@@ -72,6 +71,8 @@ class CORE_EXPORT TextIteratorBehavior final {
bool SuppressesExtraNewlineEmission() const {
return values_.bits.suppresses_newline_emission;
}
+
+ bool IgnoresDisplayLock() const { return values_.bits.ignores_display_lock; }
static TextIteratorBehavior EmitsObjectReplacementCharacterBehavior();
static TextIteratorBehavior IgnoresStyleVisibilityBehavior();
static TextIteratorBehavior DefaultRangeLengthBehavior();
@@ -101,6 +102,7 @@ class CORE_EXPORT TextIteratorBehavior final {
bool does_not_emit_space_beyond_range_end : 1;
bool skips_unselectable_content : 1;
bool suppresses_newline_emission : 1;
+ bool ignores_display_lock : 1;
} bits;
} values_;
};
@@ -134,6 +136,7 @@ class CORE_EXPORT TextIteratorBehavior::Builder final {
Builder& SetDoesNotEmitSpaceBeyondRangeEnd(bool);
Builder& SetSkipsUnselectableContent(bool);
Builder& SetSuppressesExtraNewlineEmission(bool);
+ Builder& SetIgnoresDisplayLock(bool);
private:
TextIteratorBehavior behavior_;
diff --git a/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_test.cc b/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_test.cc
index 1bfddc2cf6f..7f7f2a2fd7d 100644
--- a/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_test.cc
@@ -97,7 +97,9 @@ class TextIteratorTest : public testing::WithParamInterface<bool>,
protected:
TextIteratorTest() : ScopedLayoutNGForTest(GetParam()) {}
- bool LayoutNGEnabled() const { return GetParam(); }
+ bool LayoutNGEnabled() const {
+ return RuntimeEnabledFeatures::LayoutNGEnabled();
+ }
template <typename Tree>
std::string Iterate(const TextIteratorBehavior& = TextIteratorBehavior());
@@ -945,7 +947,7 @@ TEST_P(TextIteratorTest, BasicIterationInputiWithBr) {
const ShadowRoot* shadow_root = input_element->UserAgentShadowRoot();
const Position start = Position::FirstPositionInNode(*shadow_root);
const Position end = Position::LastPositionInNode(*shadow_root);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_EQ("[b]", IteratePartial<DOMTree>(start, end));
}
@@ -978,8 +980,8 @@ TEST_P(TextIteratorTest, PositionInShadowTree) {
Element& host = *GetDocument().getElementById("host");
ShadowRoot& shadow_root =
host.AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString("A<slot name=c></slot>");
- GetDocument().UpdateStyleAndLayout();
+ shadow_root.setInnerHTML("A<slot name=c></slot>");
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Element& body = *GetDocument().body();
Node& text_a = *shadow_root.firstChild();
Node& slot = *shadow_root.lastChild();
@@ -1034,8 +1036,8 @@ TEST_P(TextIteratorTest, EmitsSpaceForNbsp) {
TEST_P(TextIteratorTest, IterateWithLockedSubtree) {
SetBodyContent("<div id='parent'>foo<div id='locked'>text</div>bar</div>");
auto* locked = GetDocument().getElementById("locked");
- locked->setAttribute("rendersubtree", "invisible activatable");
- GetDocument().UpdateStyleAndLayout();
+ locked->setAttribute(html_names::kStyleAttr, "subtree-visibility: auto");
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
auto* parent = GetDocument().getElementById("parent");
const Position start_position = Position::FirstPositionInNode(*parent);
const Position end_position = Position::LastPositionInNode(*parent);
diff --git a/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.h b/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.h
index 72ab43606bb..e1ffb8fc480 100644
--- a/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.h
+++ b/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.h
@@ -76,7 +76,7 @@ class TextIteratorTextNodeHandler {
unsigned text_end_offset);
// The current text node and offset range, from which text should be emitted.
- Member<const Text> text_node_;
+ const Text* text_node_ = nullptr;
unsigned offset_ = 0;
unsigned end_offset_ = 0;
diff --git a/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.cc b/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.cc
index 156f67c69d4..4ee6e5ad040 100644
--- a/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.cc
+++ b/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.cc
@@ -108,7 +108,7 @@ void TextIteratorTextState::ResetPositionContainerNode(
DCHECK_NE(node_type, PositionNodeType::kNone);
position_node_type_ = node_type;
position_container_node_ = nullptr;
- position_node_ = node;
+ position_node_ = &node;
position_start_offset_ = base::nullopt;
position_end_offset_ = base::nullopt;
}
diff --git a/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.h b/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.h
index dce6a069d87..b508e5ad516 100644
--- a/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.h
+++ b/chromium/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.h
@@ -145,9 +145,9 @@ class CORE_EXPORT TextIteratorTextState {
unsigned text_start_offset_ = 0;
// Position of the current text, in the form to be returned from the iterator.
- Member<const Node> position_node_;
+ const Node* position_node_ = nullptr;
// |Text| node when |position_node_type_ == kInText| or |ContainerNode|.
- mutable Member<const Node> position_container_node_;
+ mutable const Node* position_container_node_ = nullptr;
mutable base::Optional<unsigned> position_start_offset_;
mutable base::Optional<unsigned> position_end_offset_;
PositionNodeType position_node_type_ = PositionNodeType::kNone;
diff --git a/chromium/third_party/blink/renderer/core/editing/keyboard_test.cc b/chromium/third_party/blink/renderer/core/editing/keyboard_test.cc
index 356c4353370..f208b02608e 100644
--- a/chromium/third_party/blink/renderer/core/editing/keyboard_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/keyboard_test.cc
@@ -34,8 +34,8 @@
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_input_event.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/editing/editor.h"
#include "third_party/blink/renderer/core/events/keyboard_event.h"
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 dcbd563e350..a1e219fd9d2 100644
--- a/chromium/third_party/blink/renderer/core/editing/layout_selection.cc
+++ b/chromium/third_party/blink/renderer/core/editing/layout_selection.cc
@@ -191,7 +191,7 @@ struct OldSelectedNodes {
selected_map = std::move(other.selected_map);
}
- Member<SelectionPaintRange> paint_range;
+ SelectionPaintRange* paint_range;
HeapHashMap<Member<const Node>, SelectionState> selected_map;
private:
@@ -230,7 +230,7 @@ struct NewPaintRangeAndSelectedNodes {
#endif
}
- Member<SelectionPaintRange> paint_range;
+ SelectionPaintRange* paint_range;
HeapHashSet<Member<const Node>> selected_objects;
private:
@@ -584,9 +584,10 @@ static SelectionState GetSelectionStateFor(const LayoutText& layout_text) {
}
static SelectionState GetSelectionStateFor(const NGInlineCursor& cursor) {
- DCHECK(cursor.CurrentLayoutObject() &&
- cursor.CurrentLayoutObject()->IsText());
- return GetSelectionStateFor(ToLayoutText(*cursor.CurrentLayoutObject()));
+ DCHECK(cursor.Current().GetLayoutObject() &&
+ cursor.Current().GetLayoutObject()->IsText());
+ return GetSelectionStateFor(
+ ToLayoutText(*cursor.Current().GetLayoutObject()));
}
bool LayoutSelection::IsSelected(const LayoutObject& layout_object) {
@@ -661,10 +662,11 @@ LayoutTextSelectionStatus FrameSelection::ComputeLayoutSelectionStatus(
LayoutSelectionStatus LayoutSelection::ComputeSelectionStatus(
const NGInlineCursor& cursor) const {
// We don't paint selection on ellipsis.
- if (cursor.IsEllipsis())
+ if (cursor.Current().IsEllipsis())
return {0, 0, SelectSoftLineBreak::kNotSelected};
- const unsigned start_offset = cursor.CurrentTextStartOffset();
- const unsigned end_offset = cursor.CurrentTextEndOffset();
+ const NGTextOffset offset = cursor.Current().TextOffset();
+ const unsigned start_offset = offset.start;
+ const unsigned end_offset = offset.end;
switch (GetSelectionStateFor(cursor)) {
case SelectionState::kStart: {
const unsigned start_in_block = paint_range_->start_offset.value();
@@ -802,7 +804,7 @@ void LayoutSelection::Commit() {
paint_range_ = new_range.paint_range;
}
-void LayoutSelection::OnDocumentShutdown() {
+void LayoutSelection::ContextDestroyed() {
has_pending_selection_ = false;
paint_range_->start_node = nullptr;
paint_range_->start_offset = base::nullopt;
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 c7c218ca402..5939c51400a 100644
--- a/chromium/third_party/blink/renderer/core/editing/layout_selection.h
+++ b/chromium/third_party/blink/renderer/core/editing/layout_selection.h
@@ -52,7 +52,7 @@ class LayoutSelection final : public GarbageCollected<LayoutSelection> {
LayoutSelectionStatus ComputeSelectionStatus(const NGInlineCursor&) const;
static bool IsSelected(const LayoutObject&);
- void OnDocumentShutdown();
+ void ContextDestroyed();
void Trace(Visitor*);
diff --git a/chromium/third_party/blink/renderer/core/editing/layout_selection_test.cc b/chromium/third_party/blink/renderer/core/editing/layout_selection_test.cc
index 5e84a2c9931..8d14afd7cf4 100644
--- a/chromium/third_party/blink/renderer/core/editing/layout_selection_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/layout_selection_test.cc
@@ -5,7 +5,7 @@
#include "third_party/blink/renderer/core/editing/layout_selection.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
-#include "third_party/blink/renderer/core/dom/shadow_root_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_shadow_root_init.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/editing/selection_template.h"
#include "third_party/blink/renderer/core/editing/testing/editing_test_base.h"
@@ -43,7 +43,7 @@ class LayoutSelectionTestBase : public EditingTestBase {
cursor.MoveTo(layout_text);
if (!cursor)
return;
- const unsigned text_start = cursor.CurrentTextStartOffset();
+ const unsigned text_start = cursor.Current().TextStartOffset();
for (; cursor; cursor.MoveToNextForSameLayoutObject()) {
const LayoutSelectionStatus status =
selection.ComputeLayoutSelectionStatus(cursor);
@@ -148,7 +148,9 @@ class LayoutSelectionTest : public ::testing::WithParamInterface<bool>,
protected:
LayoutSelectionTest() : ScopedLayoutNGForTest(GetParam()) {}
- bool LayoutNGEnabled() const { return GetParam(); }
+ bool LayoutNGEnabled() const {
+ return RuntimeEnabledFeatures::LayoutNGEnabled();
+ }
};
INSTANTIATE_TEST_SUITE_P(All, LayoutSelectionTest, ::testing::Bool());
@@ -776,7 +778,7 @@ TEST_P(LayoutSelectionTest, ClearByRemoveNode) {
Node* baz = GetDocument().body()->lastChild();
baz->remove();
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Selection().CommitAppearanceIfNeeded();
EXPECT_EQ(
"BODY, Contain, NotInvalidate \n"
@@ -809,7 +811,7 @@ TEST_P(LayoutSelectionTest, ClearByRemoveLayoutObject) {
auto* span_baz = To<Element>(GetDocument().body()->lastChild());
span_baz->SetInlineStyleProperty(CSSPropertyID::kDisplay, CSSValueID::kNone);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Selection().CommitAppearanceIfNeeded();
EXPECT_EQ(
"BODY, Contain, NotInvalidate \n"
@@ -853,7 +855,7 @@ TEST_P(LayoutSelectionTest, ClearBySlotChange) {
GetDocument().body()->firstChild()->GetShadowRoot()->QuerySelector(
"slot");
slot->setAttribute("name", "s2");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Selection().CommitAppearanceIfNeeded();
EXPECT_EQ(
"BODY, Contain, NotInvalidate \n"
diff --git a/chromium/third_party/blink/renderer/core/editing/link_selection_test.cc b/chromium/third_party/blink/renderer/core/editing/link_selection_test.cc
index 5f0e04ca791..69e1e4c06f6 100644
--- a/chromium/third_party/blink/renderer/core/editing/link_selection_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/link_selection_test.cc
@@ -16,9 +16,10 @@
#include "third_party/blink/renderer/core/page/context_menu_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/platform/cursor.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/cursor/cursor.h"
+#include "ui/base/mojom/cursor_type.mojom-blink.h"
using testing::_;
@@ -194,7 +195,7 @@ TEST_F(LinkSelectionTest, HandCursorDuringLinkDrag) {
test::RunDelayedTasks(base::TimeDelta::FromMilliseconds(50));
const auto& cursor =
main_frame_->GetFrame()->GetChromeClient().LastSetCursorForTesting();
- EXPECT_EQ(ui::CursorType::kHand, cursor.GetType());
+ EXPECT_EQ(ui::mojom::blink::CursorType::kHand, cursor.type());
}
TEST_F(LinkSelectionTest, DragOnNothingShowsPointer) {
@@ -206,7 +207,7 @@ TEST_F(LinkSelectionTest, DragOnNothingShowsPointer) {
test::RunDelayedTasks(base::TimeDelta::FromMilliseconds(50));
const auto& cursor =
main_frame_->GetFrame()->GetChromeClient().LastSetCursorForTesting();
- EXPECT_EQ(ui::CursorType::kPointer, cursor.GetType());
+ EXPECT_EQ(ui::mojom::blink::CursorType::kPointer, cursor.type());
}
TEST_F(LinkSelectionTest, CaretCursorOverLinkDuringSelection) {
@@ -219,7 +220,7 @@ TEST_F(LinkSelectionTest, CaretCursorOverLinkDuringSelection) {
test::RunDelayedTasks(base::TimeDelta::FromMilliseconds(50));
const auto& cursor =
main_frame_->GetFrame()->GetChromeClient().LastSetCursorForTesting();
- EXPECT_EQ(ui::CursorType::kIBeam, cursor.GetType());
+ EXPECT_EQ(ui::mojom::blink::CursorType::kIBeam, cursor.type());
}
TEST_F(LinkSelectionTest, HandCursorOverLinkAfterContextMenu) {
@@ -238,7 +239,7 @@ TEST_F(LinkSelectionTest, HandCursorOverLinkAfterContextMenu) {
test::RunDelayedTasks(base::TimeDelta::FromMilliseconds(50));
const auto& cursor =
main_frame_->GetFrame()->GetChromeClient().LastSetCursorForTesting();
- EXPECT_EQ(ui::CursorType::kHand, cursor.GetType());
+ EXPECT_EQ(ui::mojom::blink::CursorType::kHand, cursor.type());
}
TEST_F(LinkSelectionTest, SingleClickWithAltStartsDownload) {
diff --git a/chromium/third_party/blink/renderer/core/editing/local_caret_rect_bidi_test.cc b/chromium/third_party/blink/renderer/core/editing/local_caret_rect_bidi_test.cc
index 3bb8e08951d..b4439331f43 100644
--- a/chromium/third_party/blink/renderer/core/editing/local_caret_rect_bidi_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/local_caret_rect_bidi_test.cc
@@ -23,7 +23,9 @@ class ParameterizedLocalCaretRectBidiTest
ParameterizedLocalCaretRectBidiTest() : ScopedLayoutNGForTest(GetParam()) {}
protected:
- bool LayoutNGEnabled() const { return GetParam(); }
+ bool LayoutNGEnabled() const {
+ return RuntimeEnabledFeatures::LayoutNGEnabled();
+ }
};
INSTANTIATE_TEST_SUITE_P(All,
diff --git a/chromium/third_party/blink/renderer/core/editing/local_caret_rect_test.cc b/chromium/third_party/blink/renderer/core/editing/local_caret_rect_test.cc
index 71cda0c29fd..941499d8f2c 100644
--- a/chromium/third_party/blink/renderer/core/editing/local_caret_rect_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/local_caret_rect_test.cc
@@ -36,7 +36,9 @@ class ParameterizedLocalCaretRectTest
ParameterizedLocalCaretRectTest() : ScopedLayoutNGForTest(GetParam()) {}
protected:
- bool LayoutNGEnabled() const { return GetParam(); }
+ bool LayoutNGEnabled() const {
+ return RuntimeEnabledFeatures::LayoutNGEnabled();
+ }
};
INSTANTIATE_TEST_SUITE_P(All, ParameterizedLocalCaretRectTest, testing::Bool());
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.cc b/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.cc
index 926d2c85509..21fef20291c 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.cc
+++ b/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.cc
@@ -11,11 +11,15 @@ ActiveSuggestionMarker::ActiveSuggestionMarker(
unsigned end_offset,
Color underline_color,
ui::mojom::ImeTextSpanThickness thickness,
+ ui::mojom::ImeTextSpanUnderlineStyle underline_style,
+ Color text_color,
Color background_color)
: StyleableMarker(start_offset,
end_offset,
underline_color,
thickness,
+ underline_style,
+ text_color,
background_color) {}
DocumentMarker::MarkerType ActiveSuggestionMarker::GetType() const {
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.h b/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.h
index 62a99d9bb89..645e49e17bd 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.h
+++ b/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker.h
@@ -18,6 +18,8 @@ class CORE_EXPORT ActiveSuggestionMarker final : public StyleableMarker {
unsigned end_offset,
Color underline_color,
ui::mojom::ImeTextSpanThickness,
+ ui::mojom::ImeTextSpanUnderlineStyle underline_style,
+ Color text_color,
Color background_color);
// DocumentMarker implementations
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_list_impl_test.cc b/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_list_impl_test.cc
index 3278806ce74..8ccff83e0d5 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_list_impl_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_list_impl_test.cc
@@ -17,7 +17,9 @@ class ActiveSuggestionMarkerListImplTest : public EditingTestBase {
DocumentMarker* CreateMarker(unsigned start_offset, unsigned end_offset) {
return MakeGarbageCollected<ActiveSuggestionMarker>(
start_offset, end_offset, Color::kTransparent,
- ui::mojom::ImeTextSpanThickness::kThin, Color::kBlack);
+ ui::mojom::ImeTextSpanThickness::kThin,
+ ui::mojom::ImeTextSpanUnderlineStyle::kSolid, Color::kBlack,
+ Color::kBlack);
}
Persistent<ActiveSuggestionMarkerListImpl> marker_list_;
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_test.cc b/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_test.cc
index 1e3872be954..2c478280954 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/markers/active_suggestion_marker_test.cc
@@ -7,6 +7,7 @@
#include "testing/gtest/include/gtest/gtest.h"
using ui::mojom::ImeTextSpanThickness;
+using ui::mojom::ImeTextSpanUnderlineStyle;
namespace blink {
@@ -15,6 +16,7 @@ class ActiveSuggestionMarkerTest : public testing::Test {};
TEST_F(ActiveSuggestionMarkerTest, MarkerType) {
DocumentMarker* marker = MakeGarbageCollected<ActiveSuggestionMarker>(
0, 1, Color::kTransparent, ImeTextSpanThickness::kNone,
+ ImeTextSpanUnderlineStyle::kNone, Color::kTransparent,
Color::kTransparent);
EXPECT_EQ(DocumentMarker::kActiveSuggestion, marker->GetType());
}
@@ -22,21 +24,28 @@ TEST_F(ActiveSuggestionMarkerTest, MarkerType) {
TEST_F(ActiveSuggestionMarkerTest, IsStyleableMarker) {
DocumentMarker* marker = MakeGarbageCollected<ActiveSuggestionMarker>(
0, 1, Color::kTransparent, ImeTextSpanThickness::kNone,
+ ImeTextSpanUnderlineStyle::kNone, Color::kTransparent,
Color::kTransparent);
EXPECT_TRUE(IsStyleableMarker(*marker));
}
TEST_F(ActiveSuggestionMarkerTest, ConstructorAndGetters) {
ActiveSuggestionMarker* marker = MakeGarbageCollected<ActiveSuggestionMarker>(
- 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThin, Color::kGray);
+ 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kTransparent, Color::kGray);
EXPECT_EQ(Color::kDarkGray, marker->UnderlineColor());
EXPECT_FALSE(marker->HasThicknessThick());
+ EXPECT_EQ(ImeTextSpanUnderlineStyle::kSolid, marker->UnderlineStyle());
+ EXPECT_EQ(Color::kTransparent, marker->TextColor());
EXPECT_EQ(Color::kGray, marker->BackgroundColor());
ActiveSuggestionMarker* thick_marker =
MakeGarbageCollected<ActiveSuggestionMarker>(
- 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThick, Color::kGray);
+ 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThick,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kTransparent, Color::kGray);
EXPECT_EQ(true, thick_marker->HasThicknessThick());
+ EXPECT_EQ(ImeTextSpanUnderlineStyle::kSolid, marker->UnderlineStyle());
+ EXPECT_EQ(Color::kTransparent, marker->TextColor());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/composition_marker.cc b/chromium/third_party/blink/renderer/core/editing/markers/composition_marker.cc
index 954fa2ae1e1..d35e03485f0 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/composition_marker.cc
+++ b/chromium/third_party/blink/renderer/core/editing/markers/composition_marker.cc
@@ -6,15 +6,20 @@
namespace blink {
-CompositionMarker::CompositionMarker(unsigned start_offset,
- unsigned end_offset,
- Color underline_color,
- ui::mojom::ImeTextSpanThickness thickness,
- Color background_color)
+CompositionMarker::CompositionMarker(
+ unsigned start_offset,
+ unsigned end_offset,
+ Color underline_color,
+ ui::mojom::ImeTextSpanThickness thickness,
+ ui::mojom::ImeTextSpanUnderlineStyle underline_style,
+ Color text_color,
+ Color background_color)
: StyleableMarker(start_offset,
end_offset,
underline_color,
thickness,
+ underline_style,
+ text_color,
background_color) {}
DocumentMarker::MarkerType CompositionMarker::GetType() const {
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/composition_marker.h b/chromium/third_party/blink/renderer/core/editing/markers/composition_marker.h
index 81f853f86b5..994bb4fcbe5 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/composition_marker.h
+++ b/chromium/third_party/blink/renderer/core/editing/markers/composition_marker.h
@@ -20,6 +20,8 @@ class CORE_EXPORT CompositionMarker final : public StyleableMarker {
unsigned end_offset,
Color underline_color,
ui::mojom::ImeTextSpanThickness,
+ ui::mojom::ImeTextSpanUnderlineStyle,
+ Color text_color,
Color background_color);
// DocumentMarker implementations
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl_test.cc b/chromium/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl_test.cc
index d1d3b4049c2..5760908bde2 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl_test.cc
@@ -18,7 +18,9 @@ class CompositionMarkerListImplTest : public EditingTestBase {
DocumentMarker* CreateMarker(unsigned start_offset, unsigned end_offset) {
return MakeGarbageCollected<CompositionMarker>(
start_offset, end_offset, Color::kTransparent,
- ui::mojom::ImeTextSpanThickness::kThin, Color::kBlack);
+ ui::mojom::ImeTextSpanThickness::kThin,
+ ui::mojom::ImeTextSpanUnderlineStyle::kSolid, Color::kBlack,
+ Color::kBlack);
}
Persistent<CompositionMarkerListImpl> marker_list_;
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/composition_marker_test.cc b/chromium/third_party/blink/renderer/core/editing/markers/composition_marker_test.cc
index 5bf0d806048..d0c8083a91d 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/composition_marker_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/markers/composition_marker_test.cc
@@ -7,6 +7,7 @@
#include "testing/gtest/include/gtest/gtest.h"
using ui::mojom::ImeTextSpanThickness;
+using ui::mojom::ImeTextSpanUnderlineStyle;
namespace blink {
@@ -15,6 +16,7 @@ class CompositionMarkerTest : public testing::Test {};
TEST_F(CompositionMarkerTest, MarkerType) {
DocumentMarker* marker = MakeGarbageCollected<CompositionMarker>(
0, 1, Color::kTransparent, ImeTextSpanThickness::kNone,
+ ImeTextSpanUnderlineStyle::kNone, Color::kTransparent,
Color::kTransparent);
EXPECT_EQ(DocumentMarker::kComposition, marker->GetType());
}
@@ -22,20 +24,81 @@ TEST_F(CompositionMarkerTest, MarkerType) {
TEST_F(CompositionMarkerTest, IsStyleableMarker) {
DocumentMarker* marker = MakeGarbageCollected<CompositionMarker>(
0, 1, Color::kTransparent, ImeTextSpanThickness::kNone,
+ ImeTextSpanUnderlineStyle::kNone, Color::kTransparent,
Color::kTransparent);
EXPECT_TRUE(IsStyleableMarker(*marker));
}
TEST_F(CompositionMarkerTest, ConstructorAndGetters) {
CompositionMarker* marker = MakeGarbageCollected<CompositionMarker>(
- 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThin, Color::kGray);
+ 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kTransparent, Color::kGray);
EXPECT_EQ(Color::kDarkGray, marker->UnderlineColor());
EXPECT_TRUE(marker->HasThicknessThin());
+ EXPECT_EQ(ImeTextSpanUnderlineStyle::kSolid, marker->UnderlineStyle());
+ EXPECT_EQ(Color::kTransparent, marker->TextColor());
EXPECT_EQ(Color::kGray, marker->BackgroundColor());
CompositionMarker* thick_marker = MakeGarbageCollected<CompositionMarker>(
- 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThick, Color::kGray);
+ 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThick,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kTransparent, Color::kGray);
EXPECT_TRUE(thick_marker->HasThicknessThick());
+ EXPECT_EQ(ImeTextSpanUnderlineStyle::kSolid, marker->UnderlineStyle());
+ EXPECT_EQ(Color::kTransparent, marker->TextColor());
+}
+
+TEST_F(CompositionMarkerTest, UnderlineStyleDottedAndGrayText) {
+ CompositionMarker* marker = MakeGarbageCollected<CompositionMarker>(
+ 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kDot, Color::kGray, Color::kGray);
+ EXPECT_EQ(Color::kDarkGray, marker->UnderlineColor());
+ EXPECT_TRUE(marker->HasThicknessThin());
+ EXPECT_EQ(ImeTextSpanUnderlineStyle::kDot, marker->UnderlineStyle());
+ EXPECT_EQ(Color::kGray, marker->TextColor());
+ EXPECT_EQ(Color::kGray, marker->BackgroundColor());
+
+ CompositionMarker* thick_marker = MakeGarbageCollected<CompositionMarker>(
+ 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThick,
+ ImeTextSpanUnderlineStyle::kDot, Color::kGray, Color::kGray);
+ EXPECT_TRUE(thick_marker->HasThicknessThick());
+ EXPECT_EQ(ImeTextSpanUnderlineStyle::kDot, marker->UnderlineStyle());
+ EXPECT_EQ(Color::kGray, marker->TextColor());
+}
+
+TEST_F(CompositionMarkerTest, UnderlineStyleDashed) {
+ CompositionMarker* marker = MakeGarbageCollected<CompositionMarker>(
+ 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kDash, Color::kTransparent, Color::kGray);
+ EXPECT_EQ(Color::kDarkGray, marker->UnderlineColor());
+ EXPECT_TRUE(marker->HasThicknessThin());
+ EXPECT_EQ(ImeTextSpanUnderlineStyle::kDash, marker->UnderlineStyle());
+ EXPECT_EQ(Color::kTransparent, marker->TextColor());
+ EXPECT_EQ(Color::kGray, marker->BackgroundColor());
+
+ CompositionMarker* thick_marker = MakeGarbageCollected<CompositionMarker>(
+ 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThick,
+ ImeTextSpanUnderlineStyle::kDash, Color::kTransparent, Color::kGray);
+ EXPECT_TRUE(thick_marker->HasThicknessThick());
+ EXPECT_EQ(ImeTextSpanUnderlineStyle::kDash, marker->UnderlineStyle());
+ EXPECT_EQ(Color::kTransparent, marker->TextColor());
+}
+
+TEST_F(CompositionMarkerTest, UnderlineStyleSquiggled) {
+ CompositionMarker* marker = MakeGarbageCollected<CompositionMarker>(
+ 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSquiggle, Color::kTransparent, Color::kGray);
+ EXPECT_EQ(Color::kDarkGray, marker->UnderlineColor());
+ EXPECT_TRUE(marker->HasThicknessThin());
+ EXPECT_EQ(ImeTextSpanUnderlineStyle::kSquiggle, marker->UnderlineStyle());
+ EXPECT_EQ(Color::kTransparent, marker->TextColor());
+ EXPECT_EQ(Color::kGray, marker->BackgroundColor());
+
+ CompositionMarker* thick_marker = MakeGarbageCollected<CompositionMarker>(
+ 0, 1, Color::kDarkGray, ImeTextSpanThickness::kThick,
+ ImeTextSpanUnderlineStyle::kSquiggle, Color::kTransparent, Color::kGray);
+ EXPECT_TRUE(thick_marker->HasThicknessThick());
+ EXPECT_EQ(ImeTextSpanUnderlineStyle::kSquiggle, marker->UnderlineStyle());
+ EXPECT_EQ(Color::kTransparent, marker->TextColor());
}
} // namespace blink
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 5df64a5db9b..e9c3deffee1 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
@@ -150,7 +150,7 @@ DocumentMarkerController::DocumentMarkerController(Document& document)
void DocumentMarkerController::Clear() {
markers_.clear();
possibly_existing_marker_types_ = DocumentMarker::MarkerTypes();
- SetContext(nullptr);
+ SetDocument(nullptr);
}
void DocumentMarkerController::AddSpellingMarker(const EphemeralRange& range,
@@ -173,10 +173,16 @@ void DocumentMarkerController::AddTextMatchMarker(
const EphemeralRange& range,
TextMatchMarker::MatchStatus match_status) {
DCHECK(!document_->NeedsLayoutTreeUpdate());
- AddMarkerInternal(range, [match_status](int start_offset, int end_offset) {
- return MakeGarbageCollected<TextMatchMarker>(start_offset, end_offset,
- match_status);
- });
+ AddMarkerInternal(
+ range,
+ [match_status](int start_offset, int end_offset) {
+ return MakeGarbageCollected<TextMatchMarker>(start_offset, end_offset,
+ match_status);
+ },
+ // Since we've already determined to have a match in the given range (via
+ // FindBuffer), we can ignore the display lock for the purposes of finding
+ // where to put the marker.
+ TextIteratorBehavior::Builder().SetIgnoresDisplayLock(true).Build());
// Don't invalidate tickmarks here. TextFinder invalidates tickmarks using a
// throttling algorithm. crbug.com/6819.
}
@@ -185,26 +191,34 @@ void DocumentMarkerController::AddCompositionMarker(
const EphemeralRange& range,
Color underline_color,
ui::mojom::ImeTextSpanThickness thickness,
+ ui::mojom::ImeTextSpanUnderlineStyle underline_style,
+ Color text_color,
Color background_color) {
DCHECK(!document_->NeedsLayoutTreeUpdate());
- AddMarkerInternal(range, [underline_color, thickness, background_color](
- int start_offset, int end_offset) {
- return MakeGarbageCollected<CompositionMarker>(
- start_offset, end_offset, underline_color, thickness, background_color);
- });
+ AddMarkerInternal(range,
+ [underline_color, thickness, underline_style, text_color,
+ background_color](int start_offset, int end_offset) {
+ return MakeGarbageCollected<CompositionMarker>(
+ start_offset, end_offset, underline_color, thickness,
+ underline_style, text_color, background_color);
+ });
}
void DocumentMarkerController::AddActiveSuggestionMarker(
const EphemeralRange& range,
Color underline_color,
ui::mojom::ImeTextSpanThickness thickness,
+ ui::mojom::ImeTextSpanUnderlineStyle underline_style,
+ Color text_color,
Color background_color) {
DCHECK(!document_->NeedsLayoutTreeUpdate());
- AddMarkerInternal(range, [underline_color, thickness, background_color](
- int start_offset, int end_offset) {
- return MakeGarbageCollected<ActiveSuggestionMarker>(
- start_offset, end_offset, underline_color, thickness, background_color);
- });
+ AddMarkerInternal(range,
+ [underline_color, thickness, underline_style, text_color,
+ background_color](int start_offset, int end_offset) {
+ return MakeGarbageCollected<ActiveSuggestionMarker>(
+ start_offset, end_offset, underline_color, thickness,
+ underline_style, text_color, background_color);
+ });
}
void DocumentMarkerController::AddSuggestionMarker(
@@ -258,8 +272,10 @@ void DocumentMarkerController::RemoveMarkersInRange(
void DocumentMarkerController::AddMarkerInternal(
const EphemeralRange& range,
- std::function<DocumentMarker*(int, int)> create_marker_from_offsets) {
- for (TextIterator marked_text(range.StartPosition(), range.EndPosition());
+ std::function<DocumentMarker*(int, int)> create_marker_from_offsets,
+ const TextIteratorBehavior& iterator_behavior) {
+ for (TextIterator marked_text(range.StartPosition(), range.EndPosition(),
+ iterator_behavior);
!marked_text.AtEnd(); marked_text.Advance()) {
const int start_offset_in_current_container =
marked_text.StartOffsetInCurrentContainer();
@@ -292,7 +308,7 @@ void DocumentMarkerController::AddMarkerToNode(const Text& text,
DCHECK_GE(text.length(), new_marker->EndOffset());
possibly_existing_marker_types_ = possibly_existing_marker_types_.Add(
DocumentMarker::MarkerTypes(new_marker->GetType()));
- SetContext(document_);
+ SetDocument(document_);
Member<MarkerLists>& markers =
markers_.insert(&text, nullptr).stored_value->value;
@@ -395,7 +411,7 @@ void DocumentMarkerController::RemoveMarkersInternal(
markers_.erase(&text);
if (markers_.IsEmpty()) {
possibly_existing_marker_types_ = DocumentMarker::MarkerTypes();
- SetContext(nullptr);
+ SetDocument(nullptr);
}
}
@@ -851,7 +867,7 @@ void DocumentMarkerController::RemoveMarkersOfTypes(
if (PossiblyHasMarkers(DocumentMarker::MarkerTypes::AllBut(marker_types)))
return;
- SetContext(nullptr);
+ SetDocument(nullptr);
}
void DocumentMarkerController::RemoveMarkersFromList(
@@ -897,7 +913,7 @@ void DocumentMarkerController::RemoveMarkersFromList(
markers_.erase(iterator);
if (markers_.IsEmpty()) {
possibly_existing_marker_types_ = DocumentMarker::MarkerTypes();
- SetContext(nullptr);
+ SetDocument(nullptr);
}
}
}
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 64274cd6eed..a5d7b850598 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
@@ -67,10 +67,14 @@ class CORE_EXPORT DocumentMarkerController final
void AddCompositionMarker(const EphemeralRange&,
Color underline_color,
ui::mojom::ImeTextSpanThickness,
+ ui::mojom::ImeTextSpanUnderlineStyle,
+ Color text_color,
Color background_color);
void AddActiveSuggestionMarker(const EphemeralRange&,
Color underline_color,
ui::mojom::ImeTextSpanThickness,
+ ui::mojom::ImeTextSpanUnderlineStyle,
+ Color text_color,
Color background_color);
void AddSuggestionMarker(const EphemeralRange&,
const SuggestionMarkerProperties&);
@@ -166,7 +170,8 @@ class CORE_EXPORT DocumentMarkerController final
private:
void AddMarkerInternal(
const EphemeralRange&,
- std::function<DocumentMarker*(int, int)> create_marker_from_offsets);
+ std::function<DocumentMarker*(int, int)> create_marker_from_offsets,
+ const TextIteratorBehavior& iterator_behavior = {});
void AddMarkerToNode(const Text&, DocumentMarker*);
using MarkerLists = HeapVector<Member<DocumentMarkerList>,
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 5453ea97203..b2685cff5aa 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
@@ -65,7 +65,7 @@ Text* DocumentMarkerControllerTest::CreateTextNode(const char* text_contents) {
void DocumentMarkerControllerTest::MarkNodeContents(Node* node) {
// Force layoutObjects to be created; TextIterator, which is used in
// DocumentMarkerControllerTest::addMarker(), needs them.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
auto range = EphemeralRange::RangeOfContents(*node);
MarkerController().AddSpellingMarker(range);
}
@@ -73,7 +73,7 @@ void DocumentMarkerControllerTest::MarkNodeContents(Node* node) {
void DocumentMarkerControllerTest::MarkNodeContentsTextMatch(Node* node) {
// Force layoutObjects to be created; TextIterator, which is used in
// DocumentMarkerControllerTest::addMarker(), needs them.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
auto range = EphemeralRange::RangeOfContents(*node);
MarkerController().AddTextMatchMarker(range,
TextMatchMarker::MatchStatus::kActive);
@@ -228,7 +228,7 @@ TEST_F(DocumentMarkerControllerTest, UpdateRenderedRects) {
EXPECT_EQ(1u, rendered_rects.size());
div->setAttribute(html_names::kStyleAttr, "margin: 200px");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Vector<IntRect> new_rendered_rects =
MarkerController().LayoutRectsForTextMatchMarkers();
EXPECT_EQ(1u, new_rendered_rects.size());
@@ -240,10 +240,14 @@ TEST_F(DocumentMarkerControllerTest, CompositionMarkersNotMerged) {
Node* text = GetDocument().body()->firstChild()->firstChild();
MarkerController().AddCompositionMarker(
EphemeralRange(Position(text, 0), Position(text, 1)), Color::kTransparent,
- ui::mojom::ImeTextSpanThickness::kThin, Color::kBlack);
+ ui::mojom::ImeTextSpanThickness::kThin,
+ ui::mojom::ImeTextSpanUnderlineStyle::kSolid, Color::kBlack,
+ Color::kBlack);
MarkerController().AddCompositionMarker(
EphemeralRange(Position(text, 1), Position(text, 3)), Color::kTransparent,
- ui::mojom::ImeTextSpanThickness::kThick, Color::kBlack);
+ ui::mojom::ImeTextSpanThickness::kThick,
+ ui::mojom::ImeTextSpanUnderlineStyle::kSolid, Color::kBlack,
+ Color::kBlack);
EXPECT_EQ(2u, MarkerController().Markers().size());
}
@@ -420,7 +424,7 @@ TEST_F(DocumentMarkerControllerTest, RemoveSuggestionMarkerInRangeOnFinish) {
TEST_F(DocumentMarkerControllerTest, FirstMarkerIntersectingOffsetRange) {
SetBodyContent("<div contenteditable>123456789</div>");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Element* div = GetDocument().QuerySelector("div");
auto* text = To<Text>(div->firstChild());
@@ -441,7 +445,7 @@ TEST_F(DocumentMarkerControllerTest, FirstMarkerIntersectingOffsetRange) {
TEST_F(DocumentMarkerControllerTest,
FirstMarkerIntersectingOffsetRange_collapsed) {
SetBodyContent("<div contenteditable>123456789</div>");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Element* div = GetDocument().QuerySelector("div");
auto* text = To<Text>(div->firstChild());
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/styleable_marker.cc b/chromium/third_party/blink/renderer/core/editing/markers/styleable_marker.cc
index 51691b29762..e4bb6533c34 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/styleable_marker.cc
+++ b/chromium/third_party/blink/renderer/core/editing/markers/styleable_marker.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/editing/markers/styleable_marker.h"
using ui::mojom::ImeTextSpanThickness;
+using ui::mojom::ImeTextSpanUnderlineStyle;
namespace blink {
@@ -12,11 +13,15 @@ StyleableMarker::StyleableMarker(unsigned start_offset,
unsigned end_offset,
Color underline_color,
ImeTextSpanThickness thickness,
+ ImeTextSpanUnderlineStyle underline_style,
+ Color text_color,
Color background_color)
: DocumentMarker(start_offset, end_offset),
underline_color_(underline_color),
background_color_(background_color),
- thickness_(thickness) {}
+ thickness_(thickness),
+ underline_style_(underline_style),
+ text_color_(text_color) {}
Color StyleableMarker::UnderlineColor() const {
return underline_color_;
@@ -34,6 +39,14 @@ bool StyleableMarker::HasThicknessThick() const {
return thickness_ == ImeTextSpanThickness::kThick;
}
+ui::mojom::ImeTextSpanUnderlineStyle StyleableMarker::UnderlineStyle() const {
+ return underline_style_;
+}
+
+Color StyleableMarker::TextColor() const {
+ return text_color_;
+}
+
bool StyleableMarker::UseTextColor() const {
return thickness_ != ImeTextSpanThickness::kNone &&
underline_color_ == Color::kTransparent;
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/styleable_marker.h b/chromium/third_party/blink/renderer/core/editing/markers/styleable_marker.h
index 801afb125a1..13994f2e74e 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/styleable_marker.h
+++ b/chromium/third_party/blink/renderer/core/editing/markers/styleable_marker.h
@@ -19,6 +19,8 @@ class CORE_EXPORT StyleableMarker : public DocumentMarker {
unsigned end_offset,
Color underline_color,
ui::mojom::ImeTextSpanThickness,
+ ui::mojom::ImeTextSpanUnderlineStyle,
+ Color text_color,
Color background_color);
// StyleableMarker-specific
@@ -26,13 +28,17 @@ class CORE_EXPORT StyleableMarker : public DocumentMarker {
bool HasThicknessNone() const;
bool HasThicknessThin() const;
bool HasThicknessThick() const;
+ ui::mojom::ImeTextSpanUnderlineStyle UnderlineStyle() const;
bool UseTextColor() const;
Color BackgroundColor() const;
+ Color TextColor() const;
private:
const Color underline_color_;
const Color background_color_;
const ui::mojom::ImeTextSpanThickness thickness_;
+ const ui::mojom::ImeTextSpanUnderlineStyle underline_style_;
+ const Color text_color_;
DISALLOW_COPY_AND_ASSIGN(StyleableMarker);
};
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 57b25336eec..8d4ce2822ae 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
@@ -17,6 +17,8 @@ SuggestionMarker::SuggestionMarker(unsigned start_offset,
end_offset,
properties.UnderlineColor(),
properties.Thickness(),
+ properties.UnderlineStyle(),
+ properties.TextColor(),
properties.BackgroundColor()),
tag_(NextTag()),
suggestions_(properties.Suggestions()),
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.cc b/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.cc
index 4e446603ee3..95e2fff765b 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.cc
+++ b/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.cc
@@ -70,4 +70,17 @@ SuggestionMarkerProperties::Builder::SetThickness(
return *this;
}
+SuggestionMarkerProperties::Builder&
+SuggestionMarkerProperties::Builder::SetUnderlineStyle(
+ ui::mojom::ImeTextSpanUnderlineStyle underline_style) {
+ data_.underline_style_ = underline_style;
+ return *this;
+}
+
+SuggestionMarkerProperties::Builder&
+SuggestionMarkerProperties::Builder::SetTextColor(Color text_color) {
+ data_.text_color_ = text_color;
+ return *this;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.h b/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.h
index a69b47a1cff..e6d9d229be0 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.h
+++ b/chromium/third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.h
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/core/editing/markers/suggestion_marker.h"
using ui::mojom::ImeTextSpanThickness;
+using ui::mojom::ImeTextSpanUnderlineStyle;
namespace blink {
@@ -33,6 +34,8 @@ class CORE_EXPORT SuggestionMarkerProperties final {
Color UnderlineColor() const { return underline_color_; }
Color BackgroundColor() const { return background_color_; }
ImeTextSpanThickness Thickness() const { return thickness_; }
+ ImeTextSpanUnderlineStyle UnderlineStyle() const { return underline_style_; }
+ Color TextColor() const { return text_color_; }
private:
SuggestionMarker::SuggestionType type_ =
@@ -44,6 +47,9 @@ class CORE_EXPORT SuggestionMarkerProperties final {
Color underline_color_ = Color::kTransparent;
Color background_color_ = Color::kTransparent;
ImeTextSpanThickness thickness_ = ImeTextSpanThickness::kThin;
+ ImeTextSpanUnderlineStyle underline_style_ =
+ ImeTextSpanUnderlineStyle::kSolid;
+ Color text_color_ = Color::kTransparent;
};
// This class is used for building SuggestionMarkerProperties objects.
@@ -63,6 +69,8 @@ class CORE_EXPORT SuggestionMarkerProperties::Builder final {
Builder& SetUnderlineColor(Color);
Builder& SetBackgroundColor(Color);
Builder& SetThickness(ImeTextSpanThickness);
+ Builder& SetUnderlineStyle(ImeTextSpanUnderlineStyle);
+ Builder& SetTextColor(Color);
private:
SuggestionMarkerProperties data_;
diff --git a/chromium/third_party/blink/renderer/core/editing/markers/text_match_marker_list_impl.cc b/chromium/third_party/blink/renderer/core/editing/markers/text_match_marker_list_impl.cc
index 767ba9fe1a9..f9c8599dd5f 100644
--- a/chromium/third_party/blink/renderer/core/editing/markers/text_match_marker_list_impl.cc
+++ b/chromium/third_party/blink/renderer/core/editing/markers/text_match_marker_list_impl.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/editing/markers/text_match_marker_list_impl.h"
+#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/dom/range.h"
#include "third_party/blink/renderer/core/editing/ephemeral_range.h"
@@ -11,6 +12,7 @@
#include "third_party/blink/renderer/core/editing/visible_units.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/layout/layout_object.h"
namespace blink {
@@ -19,14 +21,32 @@ DocumentMarker::MarkerType TextMatchMarkerListImpl::MarkerType() const {
}
static void UpdateMarkerLayoutRect(const Node& node, TextMatchMarker& marker) {
- const Position start_position(node, marker.StartOffset());
- const Position end_position(node, marker.EndOffset());
- EphemeralRange range(start_position, end_position);
-
DCHECK(node.GetDocument().GetFrame());
LocalFrameView* frame_view = node.GetDocument().GetFrame()->View();
DCHECK(frame_view);
+
+ // If we have a locked ancestor, then the only reliable place to have a marker
+ // is at the locked root rect, since the elements under a locked root might
+ // not have up-to-date layout information.
+ if (auto* locked_root =
+ DisplayLockUtilities::HighestLockedInclusiveAncestor(node)) {
+ if (auto* locked_root_layout_object = locked_root->GetLayoutObject()) {
+ marker.SetRect(frame_view->FrameToDocument(
+ PhysicalRect(locked_root_layout_object->AbsoluteBoundingBoxRect())));
+ } else {
+ // If the locked root doesn't have a layout object, then we don't have the
+ // information needed to place the tickmark. Set the marker rect to an
+ // empty rect.
+ marker.SetRect(PhysicalRect());
+ }
+ return;
+ }
+
+ const Position start_position(node, marker.StartOffset());
+ const Position end_position(node, marker.EndOffset());
+ EphemeralRange range(start_position, end_position);
+
marker.SetRect(
frame_view->FrameToDocument(PhysicalRect(ComputeTextRect(range))));
}
diff --git a/chromium/third_party/blink/renderer/core/editing/position.h b/chromium/third_party/blink/renderer/core/editing/position.h
index 7584f3e90d3..c9cde1a6d58 100644
--- a/chromium/third_party/blink/renderer/core/editing/position.h
+++ b/chromium/third_party/blink/renderer/core/editing/position.h
@@ -184,7 +184,7 @@ class PositionTemplate {
// Note: Comparison of positions require both parameters are non-null. You
// should check null-position before comparing them.
// TODO(yosin): We should use |Position::operator<()| instead of
- // |Position::comapreTo()| to utilize |DHCECK_XX()|.
+ // |Position::compareTo()| to utilize |DCHECK_XX()|.
int16_t CompareTo(const PositionTemplate<Strategy>&) const;
bool operator<(const PositionTemplate<Strategy>&) const;
bool operator<=(const PositionTemplate<Strategy>&) const;
diff --git a/chromium/third_party/blink/renderer/core/editing/position_iterator.cc b/chromium/third_party/blink/renderer/core/editing/position_iterator.cc
index d5a5c9e2011..eae88822ceb 100644
--- a/chromium/third_party/blink/renderer/core/editing/position_iterator.cc
+++ b/chromium/third_party/blink/renderer/core/editing/position_iterator.cc
@@ -39,6 +39,11 @@ bool ShouldTraverseChildren(const Node& node) {
return Strategy::HasChildren(node) && !IsUserSelectContain(node);
}
+template <typename Strategy>
+int LastOffsetForPositionIterator(const Node* node) {
+ return IsUserSelectContain(*node) ? 1 : Strategy::LastOffsetForEditing(node);
+}
+
// TODO(editing-dev): We should replace usages of |parent()| in
// |PositionIterator| to |selectableParentOf()|.
template <typename Strategy>
@@ -187,7 +192,8 @@ void PositionIteratorAlgorithm<Strategy>::Increment() {
if (anchor_node_->GetLayoutObject() &&
!ShouldTraverseChildren<Strategy>(*anchor_node_) &&
- offset_in_anchor_ < Strategy::LastOffsetForEditing(anchor_node_)) {
+ offset_in_anchor_ <
+ LastOffsetForPositionIterator<Strategy>(anchor_node_)) {
// Case #2. This is the next of Case #1 or #2 itself.
// Position is (|anchor|, |offset_in_anchor_|).
// In this case |anchor| is a leaf(E,F,C,G or H) and
@@ -249,9 +255,10 @@ void PositionIteratorAlgorithm<Strategy>::Decrement() {
// Let |anchor| is B and |child| is F,
// next |anchor| is E and |child| is null.
node_after_position_in_anchor_ = nullptr;
- offset_in_anchor_ = ShouldTraverseChildren<Strategy>(*anchor_node_)
- ? 0
- : Strategy::LastOffsetForEditing(anchor_node_);
+ offset_in_anchor_ =
+ ShouldTraverseChildren<Strategy>(*anchor_node_)
+ ? 0
+ : LastOffsetForPositionIterator<Strategy>(anchor_node_);
// Decrement offset of |child| or initialize if it have never been
// used.
if (offsets_in_anchor_node_[depth_to_anchor_node_] == kInvalidOffset)
@@ -293,9 +300,10 @@ void PositionIteratorAlgorithm<Strategy>::Decrement() {
// Case #2. This is a reverse of increment()::Case3-b.
// Let |anchor| is B, next |anchor| is F.
anchor_node_ = Strategy::LastChild(*anchor_node_);
- offset_in_anchor_ = ShouldTraverseChildren<Strategy>(*anchor_node_)
- ? 0
- : Strategy::LastOffsetForEditing(anchor_node_);
+ offset_in_anchor_ =
+ ShouldTraverseChildren<Strategy>(*anchor_node_)
+ ? 0
+ : LastOffsetForPositionIterator<Strategy>(anchor_node_);
// Decrement depth initializing with -1 because
// |node_after_position_in_anchor_| is null so still unneeded.
if (depth_to_anchor_node_ >= offsets_in_anchor_node_.size())
diff --git a/chromium/third_party/blink/renderer/core/editing/position_iterator.h b/chromium/third_party/blink/renderer/core/editing/position_iterator.h
index 7a43559b737..582f22f247e 100644
--- a/chromium/third_party/blink/renderer/core/editing/position_iterator.h
+++ b/chromium/third_party/blink/renderer/core/editing/position_iterator.h
@@ -77,10 +77,10 @@ class PositionIteratorAlgorithm {
dom_tree_version_ == anchor_node_->GetDocument().DomTreeVersion();
}
- Member<Node> anchor_node_;
+ Node* anchor_node_ = nullptr;
// If this is non-null, Strategy::Parent(*node_after_position_in_anchor_) ==
// anchor_node_;
- Member<Node> node_after_position_in_anchor_;
+ Node* node_after_position_in_anchor_ = nullptr;
int offset_in_anchor_;
wtf_size_t depth_to_anchor_node_;
// If |node_after_position_in_anchor_| is not null,
diff --git a/chromium/third_party/blink/renderer/core/editing/position_iterator_test.cc b/chromium/third_party/blink/renderer/core/editing/position_iterator_test.cc
index 5fa5a32f9a0..08525dd7136 100644
--- a/chromium/third_party/blink/renderer/core/editing/position_iterator_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/position_iterator_test.cc
@@ -10,238 +10,110 @@
namespace blink {
-class PositionIteratorTest : public EditingTestBase {};
-
-// For http://crbug.com/695317
-TEST_F(PositionIteratorTest, decrementWithInputElement) {
- SetBodyContent("123<input value='abc'>");
- Element* const input = GetDocument().QuerySelector("input");
- Node* const text = input->previousSibling();
-
- // Decrement until start of "123" from INPUT on DOM tree
- PositionIterator dom_iterator(
- Position::LastPositionInNode(*GetDocument().body()));
- EXPECT_EQ(Position::LastPositionInNode(*GetDocument().body()),
+class PositionIteratorTest : public EditingTestBase {
+ protected:
+ void TestDecrement(const char* markup);
+ void TestIncrement(const char* markup);
+};
+
+void PositionIteratorTest::TestDecrement(const char* markup) {
+ SetBodyContent(markup);
+ const Element& element = *GetDocument().QuerySelector("#target");
+ const Node* const text = element.previousSibling();
+ const Element* const body = element.GetDocument().body();
+
+ // Decrement until start of Text "123" from |element| on DOM tree.
+ PositionIterator dom_iterator(Position::LastPositionInNode(*body));
+ EXPECT_EQ(Position::LastPositionInNode(*body),
dom_iterator.ComputePosition());
dom_iterator.Decrement();
- EXPECT_EQ(Position::AfterNode(*input), dom_iterator.ComputePosition());
+ EXPECT_EQ(Position::AfterNode(element), dom_iterator.ComputePosition());
dom_iterator.Decrement();
- EXPECT_EQ(Position::BeforeNode(*input), dom_iterator.ComputePosition());
+ EXPECT_EQ(Position::BeforeNode(element), dom_iterator.ComputePosition());
dom_iterator.Decrement();
- EXPECT_EQ(Position(GetDocument().body(), 1), dom_iterator.ComputePosition());
+ EXPECT_EQ(Position(body, 1), dom_iterator.ComputePosition());
dom_iterator.Decrement();
EXPECT_EQ(Position(text, 3), dom_iterator.ComputePosition());
- // Decrement until start of "123" from INPUT on flat tree
+ // Decrement until start of Text "123" from |element| on flat tree.
PositionIteratorInFlatTree flat_iterator(
- PositionInFlatTree::LastPositionInNode(*GetDocument().body()));
- EXPECT_EQ(PositionInFlatTree::LastPositionInNode(*GetDocument().body()),
+ PositionInFlatTree::LastPositionInNode(*body));
+ EXPECT_EQ(PositionInFlatTree::LastPositionInNode(*body),
flat_iterator.ComputePosition());
flat_iterator.Decrement();
- EXPECT_EQ(PositionInFlatTree::AfterNode(*input),
+ EXPECT_EQ(PositionInFlatTree::AfterNode(element),
flat_iterator.ComputePosition());
flat_iterator.Decrement();
- EXPECT_EQ(PositionInFlatTree::BeforeNode(*input),
+ EXPECT_EQ(PositionInFlatTree::BeforeNode(element),
flat_iterator.ComputePosition());
flat_iterator.Decrement();
- EXPECT_EQ(PositionInFlatTree(GetDocument().body(), 1),
- flat_iterator.ComputePosition());
+ EXPECT_EQ(PositionInFlatTree(body, 1), flat_iterator.ComputePosition());
flat_iterator.Decrement();
EXPECT_EQ(PositionInFlatTree(text, 3), flat_iterator.ComputePosition());
}
-TEST_F(PositionIteratorTest, decrementWithSelectElement) {
- SetBodyContent("123<select><option>1</option><option>2</option></select>");
- Element* const select = GetDocument().QuerySelector("select");
- Node* text = select->previousSibling();
-
- // Decrement until start of "123" from SELECT on DOM tree
- PositionIterator dom_iterator(
- Position::LastPositionInNode(*GetDocument().body()));
- EXPECT_EQ(Position::LastPositionInNode(*GetDocument().body()),
- dom_iterator.ComputePosition());
- dom_iterator.Decrement();
- EXPECT_EQ(Position::AfterNode(*select), dom_iterator.ComputePosition());
- dom_iterator.Decrement();
- EXPECT_EQ(Position::AfterNode(*select), dom_iterator.ComputePosition())
- << "This is redundant result, we should not have. see "
- "http://crbug.com/697283";
- dom_iterator.Decrement();
- EXPECT_EQ(Position::BeforeNode(*select), dom_iterator.ComputePosition());
- dom_iterator.Decrement();
- EXPECT_EQ(Position(GetDocument().body(), 1), dom_iterator.ComputePosition());
- dom_iterator.Decrement();
- EXPECT_EQ(Position(text, 3), dom_iterator.ComputePosition());
+void PositionIteratorTest::TestIncrement(const char* markup) {
+ SetBodyContent(markup);
+ const Element& element = *GetDocument().QuerySelector("#target");
+ Node* const text = element.nextSibling();
+ const Element* body = element.GetDocument().body();
- // Decrement until start of "123" from SELECT on flat tree
- PositionIteratorInFlatTree flat_iterator(
- PositionInFlatTree::LastPositionInNode(*GetDocument().body()));
- EXPECT_EQ(PositionInFlatTree::LastPositionInNode(*GetDocument().body()),
- flat_iterator.ComputePosition());
- flat_iterator.Decrement();
- EXPECT_EQ(PositionInFlatTree::AfterNode(*select),
- flat_iterator.ComputePosition());
- flat_iterator.Decrement();
- EXPECT_EQ(PositionInFlatTree::BeforeNode(*select),
- flat_iterator.ComputePosition());
- flat_iterator.Decrement();
- EXPECT_EQ(PositionInFlatTree(GetDocument().body(), 1),
- flat_iterator.ComputePosition());
- flat_iterator.Decrement();
- EXPECT_EQ(PositionInFlatTree(text, 3), flat_iterator.ComputePosition());
-}
-
-// For http://crbug.com/695317
-TEST_F(PositionIteratorTest, decrementWithTextAreaElement) {
- SetBodyContent("123<textarea>456</textarea>");
- Element* const textarea = GetDocument().QuerySelector("textarea");
- Node* const text = textarea->previousSibling();
-
- // Decrement until end of "123" from after TEXTAREA on DOM tree
- PositionIterator dom_iterator(
- Position::LastPositionInNode(*GetDocument().body()));
- EXPECT_EQ(Position::LastPositionInNode(*GetDocument().body()),
- dom_iterator.ComputePosition());
- dom_iterator.Decrement();
- EXPECT_EQ(Position::AfterNode(*textarea), dom_iterator.ComputePosition());
- dom_iterator.Decrement();
- EXPECT_EQ(Position::BeforeNode(*textarea), dom_iterator.ComputePosition());
- dom_iterator.Decrement();
- EXPECT_EQ(Position(GetDocument().body(), 1), dom_iterator.ComputePosition());
- dom_iterator.Decrement();
- EXPECT_EQ(Position(text, 3), dom_iterator.ComputePosition());
-
- // Decrement until end of "123" from after TEXTAREA on flat tree
- PositionIteratorInFlatTree flat_iterator(
- PositionInFlatTree::LastPositionInNode(*GetDocument().body()));
- EXPECT_EQ(PositionInFlatTree::LastPositionInNode(*GetDocument().body()),
- flat_iterator.ComputePosition());
- flat_iterator.Decrement();
- EXPECT_EQ(PositionInFlatTree::AfterNode(*textarea),
- flat_iterator.ComputePosition());
- flat_iterator.Decrement();
- EXPECT_EQ(PositionInFlatTree::BeforeNode(*textarea),
- flat_iterator.ComputePosition());
- flat_iterator.Decrement();
- EXPECT_EQ(PositionInFlatTree(GetDocument().body(), 1),
- flat_iterator.ComputePosition());
- flat_iterator.Decrement();
- EXPECT_EQ(PositionInFlatTree(text, 3), flat_iterator.ComputePosition());
-}
-
-// For http://crbug.com/695317
-TEST_F(PositionIteratorTest, incrementWithInputElement) {
- SetBodyContent("<input value='abc'>123");
- Element* const input = GetDocument().QuerySelector("input");
- Node* const text = input->nextSibling();
-
- // Increment until start of "123" from INPUT on DOM tree
- PositionIterator dom_iterator(
- Position::FirstPositionInNode(*GetDocument().body()));
- EXPECT_EQ(Position(GetDocument().body(), 0), dom_iterator.ComputePosition());
+ // Increment until start of Text "123" from |element| on DOM tree.
+ PositionIterator dom_iterator(Position::FirstPositionInNode(*body));
+ EXPECT_EQ(Position(body, 0), dom_iterator.ComputePosition());
dom_iterator.Increment();
- EXPECT_EQ(Position::BeforeNode(*input), dom_iterator.ComputePosition());
+ EXPECT_EQ(Position::BeforeNode(element), dom_iterator.ComputePosition());
dom_iterator.Increment();
- EXPECT_EQ(Position::AfterNode(*input), dom_iterator.ComputePosition());
+ EXPECT_EQ(Position::AfterNode(element), dom_iterator.ComputePosition());
dom_iterator.Increment();
- EXPECT_EQ(Position(GetDocument().body(), 1), dom_iterator.ComputePosition());
+ EXPECT_EQ(Position(body, 1), dom_iterator.ComputePosition());
dom_iterator.Increment();
EXPECT_EQ(Position(text, 0), dom_iterator.ComputePosition());
- // Increment until start of "123" from INPUT on flat tree
+ // Increment until start of Text "123" from |element| on flat tree.
PositionIteratorInFlatTree flat_iterator(
- PositionInFlatTree::FirstPositionInNode(*GetDocument().body()));
- EXPECT_EQ(PositionInFlatTree(GetDocument().body(), 0),
- flat_iterator.ComputePosition());
+ PositionInFlatTree::FirstPositionInNode(*body));
+ EXPECT_EQ(PositionInFlatTree(body, 0), flat_iterator.ComputePosition());
flat_iterator.Increment();
- EXPECT_EQ(PositionInFlatTree::BeforeNode(*input),
+ EXPECT_EQ(PositionInFlatTree::BeforeNode(element),
flat_iterator.ComputePosition());
flat_iterator.Increment();
- EXPECT_EQ(PositionInFlatTree::AfterNode(*input),
+ EXPECT_EQ(PositionInFlatTree::AfterNode(element),
flat_iterator.ComputePosition());
flat_iterator.Increment();
- EXPECT_EQ(PositionInFlatTree(GetDocument().body(), 1),
- flat_iterator.ComputePosition());
+ EXPECT_EQ(PositionInFlatTree(body, 1), flat_iterator.ComputePosition());
flat_iterator.Increment();
EXPECT_EQ(PositionInFlatTree(text, 0), flat_iterator.ComputePosition());
}
-TEST_F(PositionIteratorTest, incrementWithSelectElement) {
- SetBodyContent("<select><option>1</option><option>2</option></select>123");
- Element* const select = GetDocument().QuerySelector("select");
- Node* const text = select->nextSibling();
-
- // Increment until start of "123" from SELECT on DOM tree
- PositionIterator dom_iterator(
- Position::FirstPositionInNode(*GetDocument().body()));
- EXPECT_EQ(Position(GetDocument().body(), 0), dom_iterator.ComputePosition());
- dom_iterator.Increment();
- EXPECT_EQ(Position::BeforeNode(*select), dom_iterator.ComputePosition());
- dom_iterator.Increment();
- EXPECT_EQ(Position::AfterNode(*select), dom_iterator.ComputePosition());
- dom_iterator.Increment();
- EXPECT_EQ(Position::AfterNode(*select), dom_iterator.ComputePosition())
- << "This is redundant result, we should not have. see "
- "http://crbug.com/697283";
- dom_iterator.Increment();
- EXPECT_EQ(Position(GetDocument().body(), 1), dom_iterator.ComputePosition());
- dom_iterator.Increment();
- EXPECT_EQ(Position(text, 0), dom_iterator.ComputePosition());
+// For http://crbug.com/695317
+TEST_F(PositionIteratorTest, decrementWithInputElement) {
+ TestDecrement("123<input id=target value='abc'>");
+}
- // Increment until start of "123" from SELECT on flat tree
- PositionIteratorInFlatTree flat_iterator(
- PositionInFlatTree::FirstPositionInNode(*GetDocument().body()));
- EXPECT_EQ(PositionInFlatTree(GetDocument().body(), 0),
- flat_iterator.ComputePosition());
- flat_iterator.Increment();
- EXPECT_EQ(PositionInFlatTree::BeforeNode(*select),
- flat_iterator.ComputePosition());
- flat_iterator.Increment();
- EXPECT_EQ(PositionInFlatTree::AfterNode(*select),
- flat_iterator.ComputePosition());
- flat_iterator.Increment();
- EXPECT_EQ(PositionInFlatTree(GetDocument().body(), 1),
- flat_iterator.ComputePosition());
- flat_iterator.Increment();
- EXPECT_EQ(PositionInFlatTree(text, 0), flat_iterator.ComputePosition());
+TEST_F(PositionIteratorTest, decrementWithSelectElement) {
+ TestDecrement(
+ "123<select id=target><option>1</option><option>2</option></select>");
}
// For http://crbug.com/695317
-TEST_F(PositionIteratorTest, incrementWithTextAreaElement) {
- SetBodyContent("<textarea>123</textarea>456");
- Element* const textarea = GetDocument().QuerySelector("textarea");
- Node* const text = textarea->nextSibling();
-
- // Increment until start of "123" from TEXTAREA on DOM tree
- PositionIterator dom_iterator(
- Position::FirstPositionInNode(*GetDocument().body()));
- EXPECT_EQ(Position(GetDocument().body(), 0), dom_iterator.ComputePosition());
- dom_iterator.Increment();
- EXPECT_EQ(Position::BeforeNode(*textarea), dom_iterator.ComputePosition());
- dom_iterator.Increment();
- EXPECT_EQ(Position::AfterNode(*textarea), dom_iterator.ComputePosition());
- dom_iterator.Increment();
- EXPECT_EQ(Position(GetDocument().body(), 1), dom_iterator.ComputePosition());
- dom_iterator.Increment();
- EXPECT_EQ(Position(text, 0), dom_iterator.ComputePosition());
+TEST_F(PositionIteratorTest, decrementWithTextAreaElement) {
+ TestDecrement("123<textarea id=target>456</textarea>");
+}
- // Increment until start of "123" from TEXTAREA on flat tree
- PositionIteratorInFlatTree flat_iterator(
- PositionInFlatTree::FirstPositionInNode(*GetDocument().body()));
- EXPECT_EQ(PositionInFlatTree(GetDocument().body(), 0),
- flat_iterator.ComputePosition());
- // TODO(yosin): We should not traverse inside TEXTAREA
- flat_iterator.Increment();
- EXPECT_EQ(PositionInFlatTree::BeforeNode(*textarea),
- flat_iterator.ComputePosition());
- flat_iterator.Increment();
- EXPECT_EQ(PositionInFlatTree::AfterNode(*textarea),
- flat_iterator.ComputePosition());
- flat_iterator.Increment();
- EXPECT_EQ(PositionInFlatTree(GetDocument().body(), 1),
- flat_iterator.ComputePosition());
- flat_iterator.Increment();
- EXPECT_EQ(PositionInFlatTree(text, 0), flat_iterator.ComputePosition());
+// For http://crbug.com/695317
+TEST_F(PositionIteratorTest, incrementWithInputElement) {
+ TestIncrement("<input id=target value='abc'>123");
+}
+
+TEST_F(PositionIteratorTest, incrementWithSelectElement) {
+ TestIncrement(
+ "<select id=target><option>1</option><option>2</option></select>123");
+}
+
+// For http://crbug.com/695317
+TEST_F(PositionIteratorTest, incrementWithTextAreaElement) {
+ TestIncrement("<textarea id=target>123</textarea>456");
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/editing/relocatable_position.h b/chromium/third_party/blink/renderer/core/editing/relocatable_position.h
index 796c64745db..99fa3ba0eb7 100644
--- a/chromium/third_party/blink/renderer/core/editing/relocatable_position.h
+++ b/chromium/third_party/blink/renderer/core/editing/relocatable_position.h
@@ -25,7 +25,7 @@ class CORE_EXPORT RelocatablePosition final {
Position GetPosition() const;
private:
- const Member<Range> range_;
+ Range* const range_;
DISALLOW_COPY_AND_ASSIGN(RelocatablePosition);
};
diff --git a/chromium/third_party/blink/renderer/core/editing/relocatable_position_test.cc b/chromium/third_party/blink/renderer/core/editing/relocatable_position_test.cc
index f72c2016c6a..b65dccd840d 100644
--- a/chromium/third_party/blink/renderer/core/editing/relocatable_position_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/relocatable_position_test.cc
@@ -19,7 +19,7 @@ TEST_F(RelocatablePositionTest, position) {
RelocatablePosition relocatable_position(
Position(textarea, PositionAnchorType::kBeforeAnchor));
textarea->remove();
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
// RelocatablePosition should track the given Position even if its original
// anchor node is moved away from the document.
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 f21b51312cc..18e7a3bf8cf 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
@@ -47,7 +47,7 @@ RevealSelectionScope::~RevealSelectionScope() {
return;
if (!frame_->Selection().IsAvailable())
return;
- frame_->Selection().RevealSelection(ScrollAlignment::kAlignToEdgeIfNeeded,
+ frame_->Selection().RevealSelection(ScrollAlignment::ToEdgeIfNeeded(),
kRevealExtent);
}
diff --git a/chromium/third_party/blink/renderer/core/editing/selection.idl b/chromium/third_party/blink/renderer/core/editing/selection.idl
index c789c376c11..465a945ceab 100644
--- a/chromium/third_party/blink/renderer/core/editing/selection.idl
+++ b/chromium/third_party/blink/renderer/core/editing/selection.idl
@@ -67,7 +67,7 @@
[MeasureAs=SelectionExtentOffset] readonly attribute unsigned long extentOffset;
// https://github.com/w3c/selection-api/issues/37
- [MeasureAs=SelectionModify] void modify([DefaultValue=Undefined] optional DOMString alter,
- [DefaultValue=Undefined] optional DOMString direction,
- [DefaultValue=Undefined] optional DOMString granularity);
+ [MeasureAs=SelectionModify] void modify(optional DOMString alter = "",
+ optional DOMString direction = "",
+ optional DOMString granularity = "");
};
diff --git a/chromium/third_party/blink/renderer/core/editing/selection_adjuster_test.cc b/chromium/third_party/blink/renderer/core/editing/selection_adjuster_test.cc
index 34765590077..447cc6a84a1 100644
--- a/chromium/third_party/blink/renderer/core/editing/selection_adjuster_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/selection_adjuster_test.cc
@@ -246,7 +246,7 @@ TEST_F(SelectionAdjusterTest, ShadowDistributedNodesWithoutEditingBoundary) {
Element* host = GetDocument().getElementById("host");
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString(shadow_content);
+ shadow_root.setInnerHTML(shadow_content);
Element* foo = GetDocument().getElementById("foo");
Element* s1 = shadow_root.QuerySelector("#s1");
@@ -312,7 +312,7 @@ TEST_F(SelectionAdjusterTest, ShadowDistributedNodesWithEditingBoundary) {
Element* host = GetDocument().getElementById("host");
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString(shadow_content);
+ shadow_root.setInnerHTML(shadow_content);
Element* foo = GetDocument().getElementById("foo");
Element* bar = GetDocument().getElementById("bar");
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 8a9ee855603..8ed3c295c8a 100644
--- a/chromium/third_party/blink/renderer/core/editing/selection_controller.cc
+++ b/chromium/third_party/blink/renderer/core/editing/selection_controller.cc
@@ -30,7 +30,7 @@
#include "third_party/blink/renderer/core/editing/selection_controller.h"
#include "base/auto_reset.h"
-#include "third_party/blink/public/platform/web_menu_source_type.h"
+#include "third_party/blink/public/common/input/web_menu_source_type.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
@@ -62,7 +62,8 @@
namespace blink {
SelectionController::SelectionController(LocalFrame& frame)
- : frame_(&frame),
+ : ExecutionContextLifecycleObserver(frame.GetDocument()),
+ frame_(&frame),
mouse_down_may_start_select_(false),
mouse_down_was_single_click_in_selection_(false),
mouse_down_allows_multi_click_(false),
@@ -71,7 +72,7 @@ SelectionController::SelectionController(LocalFrame& frame)
void SelectionController::Trace(Visitor* visitor) {
visitor->Trace(frame_);
visitor->Trace(original_base_in_flat_tree_);
- DocumentShutdownObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
namespace {
@@ -123,8 +124,9 @@ bool CanMouseDownStartSelect(Node* node) {
PositionInFlatTreeWithAffinity PositionWithAffinityOfHitTestResult(
const HitTestResult& hit_test_result) {
return FromPositionInDOMTree<EditingInFlatTreeStrategy>(
- hit_test_result.InnerNode()->GetLayoutObject()->PositionForPoint(
- hit_test_result.LocalPoint()));
+ hit_test_result.InnerPossiblyPseudoNode()
+ ->GetLayoutObject()
+ ->PositionForPoint(hit_test_result.LocalPoint()));
}
DocumentMarker* SpellCheckMarkerAtPosition(
@@ -167,7 +169,7 @@ Document& SelectionController::GetDocument() const {
return *frame_->GetDocument();
}
-void SelectionController::ContextDestroyed(Document*) {
+void SelectionController::ContextDestroyed() {
original_base_in_flat_tree_ = PositionInFlatTreeWithAffinity();
}
@@ -311,8 +313,9 @@ bool SelectionController::HandleSingleClick(
DCHECK(!frame_->GetDocument()->NeedsLayoutTreeUpdate());
Node* 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;
// Extend the selection if the Shift key is down, unless the click is in a
@@ -477,13 +480,13 @@ void SelectionController::UpdateSelectionForMouseDrag(
if (!mouse_down_may_start_select_)
return;
- Node* target = hit_test_result.InnerNode();
+ Node* target = hit_test_result.InnerPossiblyPseudoNode();
if (!target)
return;
// TODO(editing-dev): Use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- frame_->GetDocument()->UpdateStyleAndLayout();
+ frame_->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kSelection);
const PositionWithAffinity& raw_target_position =
Selection().SelectionHasFocus()
@@ -581,7 +584,7 @@ bool SelectionController::UpdateSelectionForMouseDownDispatchingSelectStart(
// TODO(editing-dev): Use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kSelection);
const SelectionInFlatTree visible_selection =
CreateVisibleSelection(selection).AsSelection();
@@ -602,7 +605,7 @@ bool SelectionController::SelectClosestWordFromHitTestResult(
const HitTestResult& result,
AppendTrailingWhitespace append_trailing_whitespace,
SelectInputEventType select_input_event_type) {
- Node* const inner_node = result.InnerNode();
+ Node* const inner_node = result.InnerPossiblyPseudoNode();
if (!inner_node || !inner_node->GetLayoutObject() ||
!inner_node->GetLayoutObject()->IsSelectable())
@@ -615,8 +618,8 @@ bool SelectionController::SelectClosestWordFromHitTestResult(
HitTestResult adjusted_hit_test_result = result;
if (select_input_event_type == SelectInputEventType::kTouch &&
result.GetImage()) {
- adjusted_hit_test_result.SetNodeAndPosition(result.InnerNode(),
- PhysicalOffset());
+ adjusted_hit_test_result.SetNodeAndPosition(
+ result.InnerPossiblyPseudoNode(), PhysicalOffset());
}
const PositionInFlatTreeWithAffinity pos =
@@ -681,7 +684,7 @@ bool SelectionController::SelectClosestWordFromHitTestResult(
void SelectionController::SelectClosestMisspellingFromHitTestResult(
const HitTestResult& result,
AppendTrailingWhitespace append_trailing_whitespace) {
- Node* inner_node = result.InnerNode();
+ Node* inner_node = result.InnerPossiblyPseudoNode();
if (!inner_node || !inner_node->GetLayoutObject())
return;
@@ -830,7 +833,7 @@ void SelectionController::SetNonDirectionalSelectionIfNeeded(
if (adjusted_selection.Base() != base.GetPosition() ||
adjusted_selection.Extent() != extent.GetPosition()) {
original_base_in_flat_tree_ = base;
- SetContext(&GetDocument());
+ SetExecutionContext(GetDocument().ToExecutionContext());
builder.SetBaseAndExtent(adjusted_selection.Base(),
adjusted_selection.Extent());
} else if (original_base.IsNotNull()) {
@@ -871,7 +874,7 @@ void SelectionController::SetNonDirectionalSelectionIfNeeded(
void SelectionController::SetCaretAtHitTestResult(
const HitTestResult& hit_test_result) {
- Node* inner_node = hit_test_result.InnerNode();
+ Node* inner_node = hit_test_result.InnerPossiblyPseudoNode();
DCHECK(inner_node);
const PositionInFlatTreeWithAffinity visible_hit_pos =
CreateVisiblePosition(
@@ -1078,7 +1081,8 @@ bool SelectionController::HandleMouseReleaseEvent(
event.Event().button != WebPointerProperties::Button::kRight) {
// TODO(editing-dev): Use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- frame_->GetDocument()->UpdateStyleAndLayout();
+ frame_->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kSelection);
SelectionInFlatTree::Builder builder;
Node* node = event.InnerNode();
@@ -1156,7 +1160,7 @@ bool SelectionController::HandleGestureLongPress(
if (hit_test_result.IsLiveLink())
return false;
- Node* inner_node = hit_test_result.InnerNode();
+ Node* inner_node = hit_test_result.InnerPossiblyPseudoNode();
inner_node->GetDocument().UpdateStyleAndLayoutTree();
bool inner_node_is_selectable = HasEditableStyle(*inner_node) ||
inner_node->IsTextNode() ||
@@ -1182,15 +1186,8 @@ void SelectionController::HandleGestureTwoFingerTap(
SetCaretAtHitTestResult(targeted_event.GetHitTestResult());
}
-void SelectionController::HandleGestureLongTap(
- const GestureEventWithHitTestResults& targeted_event) {
- TRACE_EVENT0("blink", "SelectionController::handleGestureLongTap");
-
- SetCaretAtHitTestResult(targeted_event.GetHitTestResult());
-}
-
static bool HitTestResultIsMisspelled(const HitTestResult& result) {
- Node* inner_node = result.InnerNode();
+ Node* inner_node = result.InnerPossiblyPseudoNode();
if (!inner_node || !inner_node->GetLayoutObject())
return false;
PositionWithAffinity pos_with_affinity =
@@ -1206,7 +1203,7 @@ static bool HitTestResultIsMisspelled(const HitTestResult& result) {
ToPositionInFlatTree(marker_position));
}
-void SelectionController::SendContextMenuEvent(
+void SelectionController::UpdateSelectionForContextMenuEvent(
const MouseEventWithHitTestResults& mev,
const PhysicalOffset& position) {
if (!Selection().IsAvailable())
@@ -1241,7 +1238,7 @@ void SelectionController::PassMousePressEventToSubframe(
const MouseEventWithHitTestResults& mev) {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- frame_->GetDocument()->UpdateStyleAndLayout();
+ frame_->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kInput);
// If we're clicking into a frame that is selected, the frame will appear
// greyed out even though we're clicking on the selection. This looks
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 20fb1033163..3b7ac5e7ed6 100644
--- a/chromium/third_party/blink/renderer/core/editing/selection_controller.h
+++ b/chromium/third_party/blink/renderer/core/editing/selection_controller.h
@@ -30,7 +30,6 @@
#include "base/macros.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/document_shutdown_observer.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/editing/position_with_affinity.h"
#include "third_party/blink/renderer/core/editing/text_granularity.h"
@@ -44,7 +43,7 @@ class LocalFrame;
class CORE_EXPORT SelectionController final
: public GarbageCollected<SelectionController>,
- public DocumentShutdownObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(SelectionController);
public:
@@ -62,15 +61,14 @@ class CORE_EXPORT SelectionController final
bool HandlePasteGlobalSelection(const WebMouseEvent&);
bool HandleGestureLongPress(const HitTestResult&);
void HandleGestureTwoFingerTap(const GestureEventWithHitTestResults&);
- void HandleGestureLongTap(const GestureEventWithHitTestResults&);
void UpdateSelectionForMouseDrag(const PhysicalOffset&,
const PhysicalOffset&);
void UpdateSelectionForMouseDrag(const HitTestResult&,
const PhysicalOffset&,
const PhysicalOffset&);
- void SendContextMenuEvent(const MouseEventWithHitTestResults&,
- const PhysicalOffset&);
+ void UpdateSelectionForContextMenuEvent(const MouseEventWithHitTestResults&,
+ const PhysicalOffset&);
void PassMousePressEventToSubframe(const MouseEventWithHitTestResults&);
void InitializeSelectionState();
@@ -117,10 +115,10 @@ class CORE_EXPORT SelectionController final
FrameSelection& Selection() const;
- // Implements |DocumentShutdownObserver|.
+ // Implements |ExecutionContextLifecycleObserver|.
// TODO(yosin): We should relocate |original_base_in_flat_tree_| when DOM tree
// changed.
- void ContextDestroyed(Document*) final;
+ void ContextDestroyed() final;
bool HandleSingleClick(const MouseEventWithHitTestResults&);
bool HandleDoubleClick(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 8ad90dc4410..39db548a9d0 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
@@ -161,7 +161,7 @@ TEST_F(SelectionControllerTest, setCaretAtHitTestResult) {
SetBodyContent(body_content);
GetDocument().GetSettings()->SetScriptEnabled(true);
Element* script = GetDocument().CreateRawElement(html_names::kScriptTag);
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
"var sample = document.getElementById('sample');"
"sample.addEventListener('onselectstart', "
" event => elem.parentNode.removeChild(elem));");
@@ -195,7 +195,7 @@ TEST_F(SelectionControllerTest,
SetCaretAtHitTestResultWithDisconnectedPosition) {
GetDocument().GetSettings()->SetScriptEnabled(true);
Element* script = GetDocument().CreateRawElement(html_names::kScriptTag);
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
"document.designMode = 'on';"
"const selection = window.getSelection();"
"const html = document.getElementsByTagName('html')[0];"
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 506e7b7d146..3b89e99469c 100644
--- a/chromium/third_party/blink/renderer/core/editing/selection_editor.cc
+++ b/chromium/third_party/blink/renderer/core/editing/selection_editor.cc
@@ -59,8 +59,8 @@ void SelectionEditor::ClearVisibleSelection() {
selection_ = SelectionInDOMTree();
cached_visible_selection_in_dom_tree_ = VisibleSelection();
cached_visible_selection_in_flat_tree_ = VisibleSelectionInFlatTree();
- cached_visible_selection_in_dom_tree_is_dirty_ = false;
- cached_visible_selection_in_flat_tree_is_dirty_ = false;
+ cached_visible_selection_in_dom_tree_is_dirty_ = true;
+ cached_visible_selection_in_flat_tree_is_dirty_ = true;
}
void SelectionEditor::Dispose() {
@@ -69,8 +69,8 @@ void SelectionEditor::Dispose() {
}
Document& SelectionEditor::GetDocument() const {
- DCHECK(LifecycleContext());
- return *LifecycleContext();
+ DCHECK(SynchronousMutationObserver::GetDocument());
+ return *SynchronousMutationObserver::GetDocument();
}
VisibleSelection SelectionEditor::ComputeVisibleSelectionInDOMTree() const {
@@ -164,24 +164,29 @@ void SelectionEditor::DidFinishDOMMutation() {
void SelectionEditor::DidAttachDocument(Document* document) {
DCHECK(document);
- DCHECK(!LifecycleContext()) << LifecycleContext();
+ DCHECK(!SynchronousMutationObserver::GetDocument())
+ << SynchronousMutationObserver::GetDocument();
+#if DCHECK_IS_ON()
style_version_for_dom_tree_ = static_cast<uint64_t>(-1);
style_version_for_flat_tree_ = static_cast<uint64_t>(-1);
+#endif
ClearVisibleSelection();
- SetContext(document);
+ SetDocument(document);
}
-void SelectionEditor::ContextDestroyed(Document*) {
+void SelectionEditor::ContextDestroyed() {
Dispose();
+#if DCHECK_IS_ON()
style_version_for_dom_tree_ = static_cast<uint64_t>(-1);
style_version_for_flat_tree_ = static_cast<uint64_t>(-1);
style_version_for_absolute_bounds_ = static_cast<uint64_t>(-1);
+#endif
selection_ = SelectionInDOMTree();
cached_visible_selection_in_dom_tree_ = VisibleSelection();
cached_visible_selection_in_flat_tree_ = VisibleSelectionInFlatTree();
- cached_visible_selection_in_dom_tree_is_dirty_ = false;
- cached_visible_selection_in_flat_tree_is_dirty_ = false;
- cached_absolute_bounds_are_dirty_ = false;
+ cached_visible_selection_in_dom_tree_is_dirty_ = true;
+ cached_visible_selection_in_flat_tree_is_dirty_ = true;
+ cached_absolute_bounds_are_dirty_ = true;
has_selection_bounds_ = false;
cached_anchor_bounds_ = IntRect();
cached_focus_bounds_ = IntRect();
@@ -395,8 +400,12 @@ bool SelectionEditor::ShouldAlwaysUseDirectionalSelection() const {
}
bool SelectionEditor::NeedsUpdateVisibleSelection() const {
- return cached_visible_selection_in_dom_tree_is_dirty_ ||
- style_version_for_dom_tree_ != GetDocument().StyleVersion();
+#if DCHECK_IS_ON()
+ // Verify that cache has been marked dirty on style changes
+ DCHECK(cached_visible_selection_in_dom_tree_is_dirty_ ||
+ style_version_for_dom_tree_ == GetDocument().StyleVersion());
+#endif
+ return cached_visible_selection_in_dom_tree_is_dirty_;
}
void SelectionEditor::UpdateCachedVisibleSelectionIfNeeded() const {
@@ -408,19 +417,27 @@ void SelectionEditor::UpdateCachedVisibleSelectionIfNeeded() const {
AssertSelectionValid();
if (!NeedsUpdateVisibleSelection())
return;
+#if DCHECK_IS_ON()
style_version_for_dom_tree_ = GetDocument().StyleVersion();
+#endif
cached_visible_selection_in_dom_tree_is_dirty_ = false;
cached_visible_selection_in_dom_tree_ = CreateVisibleSelection(selection_);
if (!cached_visible_selection_in_dom_tree_.IsNone())
return;
+#if DCHECK_IS_ON()
style_version_for_flat_tree_ = GetDocument().StyleVersion();
+#endif
cached_visible_selection_in_flat_tree_is_dirty_ = false;
cached_visible_selection_in_flat_tree_ = VisibleSelectionInFlatTree();
}
bool SelectionEditor::NeedsUpdateVisibleSelectionInFlatTree() const {
- return cached_visible_selection_in_flat_tree_is_dirty_ ||
- style_version_for_flat_tree_ != GetDocument().StyleVersion();
+#if DCHECK_IS_ON()
+ // Verify that cache has been marked dirty on style changes
+ DCHECK(cached_visible_selection_in_flat_tree_is_dirty_ ||
+ style_version_for_flat_tree_ == GetDocument().StyleVersion());
+#endif
+ return cached_visible_selection_in_flat_tree_is_dirty_;
}
void SelectionEditor::UpdateCachedVisibleSelectionInFlatTreeIfNeeded() const {
@@ -432,7 +449,9 @@ void SelectionEditor::UpdateCachedVisibleSelectionInFlatTreeIfNeeded() const {
AssertSelectionValid();
if (!NeedsUpdateVisibleSelectionInFlatTree())
return;
+#if DCHECK_IS_ON()
style_version_for_flat_tree_ = GetDocument().StyleVersion();
+#endif
cached_visible_selection_in_flat_tree_is_dirty_ = false;
SelectionInFlatTree::Builder builder;
const PositionInFlatTree& base = ToPositionInFlatTree(selection_.Base());
@@ -448,14 +467,20 @@ void SelectionEditor::UpdateCachedVisibleSelectionInFlatTreeIfNeeded() const {
CreateVisibleSelection(builder.Build());
if (!cached_visible_selection_in_flat_tree_.IsNone())
return;
+#if DCHECK_IS_ON()
style_version_for_dom_tree_ = GetDocument().StyleVersion();
+#endif
cached_visible_selection_in_dom_tree_is_dirty_ = false;
cached_visible_selection_in_dom_tree_ = VisibleSelection();
}
bool SelectionEditor::NeedsUpdateAbsoluteBounds() const {
- return cached_absolute_bounds_are_dirty_ ||
- style_version_for_absolute_bounds_ != GetDocument().StyleVersion();
+#if DCHECK_IS_ON()
+ // Verify that cache has been marked dirty on style changes
+ DCHECK(cached_absolute_bounds_are_dirty_ ||
+ style_version_for_absolute_bounds_ == GetDocument().StyleVersion());
+#endif
+ return cached_absolute_bounds_are_dirty_;
}
void SelectionEditor::UpdateCachedAbsoluteBoundsIfNeeded() const {
@@ -471,7 +496,9 @@ void SelectionEditor::UpdateCachedAbsoluteBoundsIfNeeded() const {
DocumentLifecycle::DisallowTransitionScope disallow_transition(
frame_->GetDocument()->Lifecycle());
+#if DCHECK_IS_ON()
style_version_for_absolute_bounds_ = GetDocument().StyleVersion();
+#endif
cached_absolute_bounds_are_dirty_ = false;
const VisibleSelection selection = ComputeVisibleSelectionInDOMTree();
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 51cf56c352a..fb05474d37f 100644
--- a/chromium/third_party/blink/renderer/core/editing/selection_editor.h
+++ b/chromium/third_party/blink/renderer/core/editing/selection_editor.h
@@ -62,6 +62,8 @@ class SelectionEditor final : public GarbageCollected<SelectionEditor>,
Range* DocumentCachedRange() const;
void ClearDocumentCachedRange();
+ void MarkCacheDirty();
+
void Trace(Visitor*) override;
private:
@@ -70,7 +72,6 @@ class SelectionEditor final : public GarbageCollected<SelectionEditor>,
void AssertSelectionValid() const;
void ClearVisibleSelection();
- void MarkCacheDirty();
bool ShouldAlwaysUseDirectionalSelection() const;
// VisibleSelection cache related
@@ -87,7 +88,7 @@ class SelectionEditor final : public GarbageCollected<SelectionEditor>,
void DidFinishDOMMutation();
// Implementation of |SynchronousMutationObsderver| member functions.
- void ContextDestroyed(Document*) final;
+ void ContextDestroyed() final;
void DidChangeChildren(const ContainerNode&) final;
void DidMergeTextNodes(const Text& merged_node,
const NodeWithIndex& node_to_be_removed_with_index,
@@ -110,17 +111,22 @@ class SelectionEditor final : public GarbageCollected<SelectionEditor>,
mutable VisibleSelection cached_visible_selection_in_dom_tree_;
mutable VisibleSelectionInFlatTree cached_visible_selection_in_flat_tree_;
- mutable uint64_t style_version_for_dom_tree_ = static_cast<uint64_t>(-1);
- mutable uint64_t style_version_for_flat_tree_ = static_cast<uint64_t>(-1);
- mutable bool cached_visible_selection_in_dom_tree_is_dirty_ = false;
- mutable bool cached_visible_selection_in_flat_tree_is_dirty_ = false;
+ mutable bool cached_visible_selection_in_dom_tree_is_dirty_ = true;
+ mutable bool cached_visible_selection_in_flat_tree_is_dirty_ = true;
mutable IntRect cached_anchor_bounds_;
mutable IntRect cached_focus_bounds_;
+ mutable bool cached_absolute_bounds_are_dirty_ = true;
+ mutable bool has_selection_bounds_ = false;
+
+#if DCHECK_IS_ON()
+ // TODO(xiaochengh): We should move these style versions into VisibleSelection
+ // and a new structure for absolute bounds, instead of maintaining them here.
+ mutable uint64_t style_version_for_dom_tree_ = static_cast<uint64_t>(-1);
+ mutable uint64_t style_version_for_flat_tree_ = static_cast<uint64_t>(-1);
mutable uint64_t style_version_for_absolute_bounds_ =
static_cast<uint64_t>(-1);
- mutable bool cached_absolute_bounds_are_dirty_ = false;
- mutable bool has_selection_bounds_ = false;
+#endif
DISALLOW_COPY_AND_ASSIGN(SelectionEditor);
};
diff --git a/chromium/third_party/blink/renderer/core/editing/selection_modifier.cc b/chromium/third_party/blink/renderer/core/editing/selection_modifier.cc
index 8ba37d66319..5b4c215906a 100644
--- a/chromium/third_party/blink/renderer/core/editing/selection_modifier.cc
+++ b/chromium/third_party/blink/renderer/core/editing/selection_modifier.cc
@@ -161,7 +161,7 @@ base::Optional<TextDirection> DirectionAt(const VisiblePosition& position) {
if (NGInlineFormattingContextOf(adjusted.GetPosition())) {
const NGInlineCursor& cursor = ComputeNGCaretPosition(adjusted).cursor;
if (cursor)
- return cursor.CurrentResolvedDirection();
+ return cursor.Current().ResolvedDirection();
return base::nullopt;
}
@@ -185,7 +185,7 @@ base::Optional<TextDirection> LineDirectionAt(const VisiblePosition& position) {
if (!line)
return base::nullopt;
line.MoveToContainingLine();
- return line.CurrentBaseDirection();
+ return line.Current().BaseDirection();
}
if (const InlineBox* box =
diff --git a/chromium/third_party/blink/renderer/core/editing/selection_modifier.h b/chromium/third_party/blink/renderer/core/editing/selection_modifier.h
index 1620aea5126..3aebd05b90e 100644
--- a/chromium/third_party/blink/renderer/core/editing/selection_modifier.h
+++ b/chromium/third_party/blink/renderer/core/editing/selection_modifier.h
@@ -111,7 +111,7 @@ class CORE_EXPORT SelectionModifier {
static VisiblePosition NextParagraphPosition(const VisiblePosition&,
LayoutUnit line_direction_point);
- Member<const LocalFrame> frame_;
+ const LocalFrame* frame_;
// TODO(editing-dev): We should get rid of |selection_| once we change
// all member functions not to use |selection_|.
// |selection_| is used as implicit parameter or a cache instead of pass it.
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 da5eabd4d9b..fffc06a48b4 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
@@ -63,11 +63,11 @@ class AbstractLineBox {
return GetRootInlineBox().LogicalHeight() &&
GetRootInlineBox().FirstLeafChild();
}
- if (cursor_.IsEmptyLineBox())
+ if (cursor_.Current().IsEmptyLineBox())
return false;
- const PhysicalSize physical_size = cursor_.CurrentSize();
- const LogicalSize logical_size =
- physical_size.ConvertToLogical(cursor_.CurrentStyle().GetWritingMode());
+ const PhysicalSize physical_size = cursor_.Current().Size();
+ const LogicalSize logical_size = physical_size.ConvertToLogical(
+ cursor_.Current().Style().GetWritingMode());
if (!logical_size.block_size)
return false;
// Use |ClosestLeafChildForPoint| to check if there's any leaf child.
@@ -127,7 +127,8 @@ class AbstractLineBox {
return GetRootInlineBox().ClosestLeafChildForPoint(
GetBlock().FlipForWritingMode(point), only_editable_leaves);
}
- const PhysicalOffset local_physical_point = point - cursor_.CurrentOffset();
+ const PhysicalOffset local_physical_point =
+ point - cursor_.Current().OffsetInContainerBlock();
return ClosestLeafChildForPoint(cursor_, local_physical_point,
only_editable_leaves);
}
@@ -138,7 +139,7 @@ class AbstractLineBox {
explicit AbstractLineBox(const NGInlineCursor& cursor)
: cursor_(cursor), type_(Type::kLayoutNG) {
- DCHECK(cursor_.IsLineBox());
+ DCHECK(cursor_.Current().IsLineBox());
}
const LayoutBlockFlow& GetBlock() const {
@@ -156,8 +157,9 @@ class AbstractLineBox {
return GetBlock().FlipForWritingMode(
GetRootInlineBox().BlockDirectionPointInLine());
}
- const PhysicalOffset physical_offset = cursor_.CurrentOffset();
- return cursor_.CurrentStyle().IsHorizontalWritingMode()
+ const PhysicalOffset physical_offset =
+ cursor_.Current().OffsetInContainerBlock();
+ return cursor_.Current().Style().IsHorizontalWritingMode()
? physical_offset.top
: physical_offset.left;
}
@@ -172,7 +174,8 @@ class AbstractLineBox {
}
static bool IsEditable(const NGInlineCursor& cursor) {
- const LayoutObject* const layout_object = cursor.CurrentLayoutObject();
+ const LayoutObject* const layout_object =
+ cursor.Current().GetLayoutObject();
return layout_object && layout_object->GetNode() &&
HasEditableStyle(*layout_object->GetNode());
}
@@ -183,14 +186,14 @@ class AbstractLineBox {
bool only_editable_leaves) {
const PhysicalSize unit_square(LayoutUnit(1), LayoutUnit(1));
const LogicalOffset logical_point = point.ConvertToLogical(
- line.CurrentStyle().GetWritingMode(), line.CurrentBaseDirection(),
- line.CurrentSize(), unit_square);
+ 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;
LayoutUnit closest_leaf_distance;
NGInlineCursor cursor(line);
for (cursor.MoveToNext(); cursor; cursor.MoveToNext()) {
- if (!cursor.CurrentLayoutObject())
+ if (!cursor.Current().GetLayoutObject())
continue;
if (!cursor.IsInlineLeaf())
continue;
@@ -198,21 +201,22 @@ class AbstractLineBox {
continue;
const LogicalRect fragment_logical_rect =
- cursor.CurrentRect().ConvertToLogical(
- line.CurrentStyle().GetWritingMode(), line.CurrentBaseDirection(),
- line.CurrentSize(), cursor.CurrentSize());
+ cursor.Current().RectInContainerBlock().ConvertToLogical(
+ line.Current().Style().GetWritingMode(),
+ line.Current().BaseDirection(), line.Current().Size(),
+ cursor.Current().Size());
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.CurrentLayoutObject();
+ return cursor.Current().GetLayoutObject();
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.CurrentLayoutObject();
+ closest_leaf_child = cursor.Current().GetLayoutObject();
closest_leaf_distance = distance;
}
}
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 80b9ff306c5..8e302f604d6 100644
--- a/chromium/third_party/blink/renderer/core/editing/selection_template.h
+++ b/chromium/third_party/blink/renderer/core/editing/selection_template.h
@@ -130,6 +130,7 @@ class SelectionTemplate final {
private:
friend class SelectionEditor;
+ friend class FrameSelection;
enum class Direction {
kNotComputed,
diff --git a/chromium/third_party/blink/renderer/core/editing/serializers/create_markup_options.h b/chromium/third_party/blink/renderer/core/editing/serializers/create_markup_options.h
index 109fb8a3b91..1f1a14aae6c 100644
--- a/chromium/third_party/blink/renderer/core/editing/serializers/create_markup_options.h
+++ b/chromium/third_party/blink/renderer/core/editing/serializers/create_markup_options.h
@@ -34,7 +34,7 @@ class CORE_EXPORT CreateMarkupOptions final {
bool IsForMarkupSanitization() const { return is_for_markup_sanitization_; }
private:
- Member<const Node> constraining_ancestor_;
+ const Node* constraining_ancestor_ = nullptr;
AbsoluteURLs should_resolve_urls_ = kDoNotResolveURLs;
bool should_annotate_for_interchange_ = false;
bool should_convert_blocks_to_inlines_ = false;
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 94e5aeef795..508c0337557 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
@@ -45,6 +45,10 @@
namespace blink {
+namespace {
+const char kShadowRootAttributeName[] = "shadowroot";
+}
+
class MarkupAccumulator::NamespaceContext final {
USING_FAST_MALLOC(MarkupAccumulator::NamespaceContext);
@@ -136,8 +140,10 @@ class MarkupAccumulator::ElementSerializationData final {
};
MarkupAccumulator::MarkupAccumulator(AbsoluteURLs resolve_urls_method,
- SerializationType serialization_type)
- : formatter_(resolve_urls_method, serialization_type) {}
+ SerializationType serialization_type,
+ IncludeShadowRoots include_shadow_roots)
+ : formatter_(resolve_urls_method, serialization_type),
+ include_shadow_roots_(include_shadow_roots) {}
MarkupAccumulator::~MarkupAccumulator() = default;
@@ -538,7 +544,31 @@ bool MarkupAccumulator::SerializeAsHTML() const {
std::pair<Node*, Element*> MarkupAccumulator::GetAuxiliaryDOMTree(
const Element& element) const {
- return std::pair<Node*, Element*>();
+ ShadowRoot* shadow_root = element.GetShadowRoot();
+ if (!shadow_root || include_shadow_roots_ != kIncludeShadowRoots)
+ return std::pair<Node*, Element*>();
+ DCHECK(RuntimeEnabledFeatures::DeclarativeShadowDOMEnabled());
+ AtomicString shadowroot_type;
+ switch (shadow_root->GetType()) {
+ case ShadowRootType::V0:
+ case ShadowRootType::kUserAgent:
+ // Don't serialize user agent shadow roots, only explicit shadow roots.
+ return std::pair<Node*, Element*>();
+ case ShadowRootType::kOpen:
+ shadowroot_type = "open";
+ break;
+ case ShadowRootType::kClosed:
+ shadowroot_type = "closed";
+ break;
+ }
+ // Wrap the shadowroot into a declarative Shadow DOM <template shadowroot>
+ // element.
+ auto* template_element = MakeGarbageCollected<Element>(
+ html_names::kTemplateTag, &(element.GetDocument()));
+ template_element->setAttribute(
+ QualifiedName(g_null_atom, kShadowRootAttributeName, g_null_atom),
+ shadowroot_type);
+ return std::pair<Node*, Element*>(shadow_root, template_element);
}
template <typename Strategy>
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 0b936ae89aa..454bb5d4eff 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,7 @@ class MarkupAccumulator {
STACK_ALLOCATED();
public:
- MarkupAccumulator(AbsoluteURLs, SerializationType);
+ MarkupAccumulator(AbsoluteURLs, SerializationType, IncludeShadowRoots);
virtual ~MarkupAccumulator();
template <typename Strategy>
@@ -59,6 +59,7 @@ class MarkupAccumulator {
MarkupFormatter formatter_;
StringBuilder markup_;
+ IncludeShadowRoots include_shadow_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 12badfab696..7993c70f88d 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
@@ -126,8 +126,6 @@ MarkupFormatter::MarkupFormatter(AbsoluteURLs resolve_urls_method,
: resolve_urls_method_(resolve_urls_method),
serialization_type_(serialization_type) {}
-MarkupFormatter::~MarkupFormatter() = default;
-
String MarkupFormatter::ResolveURLIfNeeded(const Element& element,
const Attribute& attribute) const {
String value = attribute.Value();
diff --git a/chromium/third_party/blink/renderer/core/editing/serializers/markup_formatter.h b/chromium/third_party/blink/renderer/core/editing/serializers/markup_formatter.h
index 48112fc4181..984cefbaa02 100644
--- a/chromium/third_party/blink/renderer/core/editing/serializers/markup_formatter.h
+++ b/chromium/third_party/blink/renderer/core/editing/serializers/markup_formatter.h
@@ -95,7 +95,6 @@ class MarkupFormatter final {
static void AppendXMLDeclaration(StringBuilder&, const Document&);
MarkupFormatter(AbsoluteURLs, SerializationType);
- ~MarkupFormatter();
void AppendStartMarkup(StringBuilder&, const Node&);
void AppendEndMarkup(StringBuilder&, const Element&);
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 f6a318053fd..21b74b91f87 100644
--- a/chromium/third_party/blink/renderer/core/editing/serializers/serialization.cc
+++ b/chromium/third_party/blink/renderer/core/editing/serializers/serialization.cc
@@ -56,6 +56,7 @@
#include "third_party/blink/renderer/core/html/html_body_element.h"
#include "third_party/blink/renderer/core/html/html_br_element.h"
#include "third_party/blink/renderer/core/html/html_div_element.h"
+#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/html/html_quote_element.h"
#include "third_party/blink/renderer/core/html/html_span_element.h"
@@ -66,6 +67,7 @@
#include "third_party/blink/renderer/core/loader/empty_clients.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/svg/svg_style_element.h"
+#include "third_party/blink/renderer/core/svg/svg_use_element.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
@@ -125,7 +127,8 @@ static void CompleteURLs(DocumentFragment& fragment, const String& base_url) {
static bool IsHTMLBlockElement(const Node* node) {
DCHECK(node);
- return IsHTMLTableCellElement(*node) || IsNonTableCellHTMLBlockElement(node);
+ return IsA<HTMLTableCellElement>(*node) ||
+ IsNonTableCellHTMLBlockElement(node);
}
static HTMLElement* AncestorToRetainStructureAndAppearanceForBlock(
@@ -446,14 +449,16 @@ DocumentFragment* CreateFragmentFromMarkupWithContext(
String CreateMarkup(const Node* node,
ChildrenOnly children_only,
- AbsoluteURLs should_resolve_urls) {
+ AbsoluteURLs should_resolve_urls,
+ IncludeShadowRoots include_shadow_roots) {
if (!node)
return "";
MarkupAccumulator accumulator(should_resolve_urls,
- node->GetDocument().IsHTMLDocument()
+ IsA<HTMLDocument>(node->GetDocument())
? SerializationType::kHTML
- : SerializationType::kXML);
+ : SerializationType::kXML,
+ include_shadow_roots);
return accumulator.SerializeNodes<EditingStrategy>(*node, children_only);
}
@@ -609,7 +614,7 @@ DocumentFragment* CreateFragmentForInnerOuterHTML(
: context_element->GetDocument();
DocumentFragment* fragment = DocumentFragment::Create(document);
- if (document.IsHTMLDocument()) {
+ if (IsA<HTMLDocument>(document)) {
fragment->ParseHTML(markup, context_element, parser_content_policy);
return fragment;
}
@@ -768,6 +773,8 @@ static Document* CreateStagingDocumentForMarkupSanitization() {
page->GetSettings().SetScriptEnabled(false);
page->GetSettings().SetPluginsEnabled(false);
page->GetSettings().SetAcceleratedCompositingEnabled(false);
+ page->GetSettings().SetParserScriptingFlagPolicy(
+ ParserScriptingFlagPolicy::kEnabled);
LocalFrame* frame = MakeGarbageCollected<LocalFrame>(
MakeGarbageCollected<EmptyLocalFrameClient>(), *page,
@@ -783,7 +790,7 @@ static Document* CreateStagingDocumentForMarkupSanitization() {
Document* document = frame->GetDocument();
DCHECK(document);
- DCHECK(document->IsHTMLDocument());
+ DCHECK(IsA<HTMLDocument>(document));
DCHECK(document->body());
document->SetIsForMarkupSanitization(true);
@@ -799,6 +806,25 @@ static bool ContainsStyleElements(const DocumentFragment& fragment) {
return false;
}
+// Returns true if any svg <use> element is removed.
+static bool StripSVGUseDataURLs(Node& node) {
+ if (IsA<SVGUseElement>(node)) {
+ SVGUseElement& use = To<SVGUseElement>(node);
+ SVGURLReferenceResolver resolver(use.HrefString(), use.GetDocument());
+ if (resolver.AbsoluteUrl().ProtocolIsData())
+ node.remove();
+ return true;
+ }
+ bool stripped = false;
+ for (Node* child = node.firstChild(); child;) {
+ Node* next = child->nextSibling();
+ if (StripSVGUseDataURLs(*child))
+ stripped = true;
+ child = next;
+ }
+ return stripped;
+}
+
DocumentFragment* CreateSanitizedFragmentFromMarkupWithContext(
Document& document,
const String& raw_markup,
@@ -819,7 +845,13 @@ DocumentFragment* CreateSanitizedFragmentFromMarkupWithContext(
return nullptr;
}
- if (!ContainsStyleElements(*fragment)) {
+ bool needs_sanitization = false;
+ if (ContainsStyleElements(*fragment))
+ needs_sanitization = true;
+ if (StripSVGUseDataURLs(*fragment))
+ needs_sanitization = true;
+
+ if (!needs_sanitization) {
staging_document->GetPage()->WillBeDestroyed();
return CreateFragmentFromMarkupWithContext(
document, raw_markup, fragment_start, fragment_end, base_url,
@@ -827,7 +859,7 @@ DocumentFragment* CreateSanitizedFragmentFromMarkupWithContext(
}
body->appendChild(fragment);
- staging_document->UpdateStyleAndLayout();
+ staging_document->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
// This sanitizes stylesheets in the markup into element inline styles
String markup = CreateMarkup(Position::FirstPositionInNode(*body),
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 004d323b4a8..e5d456a8d0f 100644
--- a/chromium/third_party/blink/renderer/core/editing/serializers/serialization.h
+++ b/chromium/third_party/blink/renderer/core/editing/serializers/serialization.h
@@ -46,6 +46,7 @@ class Node;
class CSSPropertyValueSet;
enum ChildrenOnly { kIncludeNode, kChildrenOnly };
+enum IncludeShadowRoots { kNoShadowRoots, kIncludeShadowRoots };
DocumentFragment* CreateFragmentFromText(const EphemeralRange& context,
const String& text);
@@ -85,7 +86,8 @@ void ReplaceChildrenWithText(ContainerNode*, const String&, ExceptionState&);
CORE_EXPORT String CreateMarkup(const Node*,
ChildrenOnly = kIncludeNode,
- AbsoluteURLs = kDoNotResolveURLs);
+ AbsoluteURLs = kDoNotResolveURLs,
+ IncludeShadowRoots = kNoShadowRoots);
CORE_EXPORT String
CreateMarkup(const Position& start,
diff --git a/chromium/third_party/blink/renderer/core/editing/serializers/styled_markup_accumulator.cc b/chromium/third_party/blink/renderer/core/editing/serializers/styled_markup_accumulator.cc
index 7563aaaf2a2..b1b21ef1fe3 100644
--- a/chromium/third_party/blink/renderer/core/editing/serializers/styled_markup_accumulator.cc
+++ b/chromium/third_party/blink/renderer/core/editing/serializers/styled_markup_accumulator.cc
@@ -34,6 +34,7 @@
#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/iterators/text_iterator.h"
+#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
namespace blink {
@@ -55,8 +56,8 @@ StyledMarkupAccumulator::StyledMarkupAccumulator(
Document* document,
const CreateMarkupOptions& options)
: formatter_(options.ShouldResolveURLs(),
- document->IsHTMLDocument() ? SerializationType::kHTML
- : SerializationType::kXML),
+ IsA<HTMLDocument>(document) ? SerializationType::kHTML
+ : SerializationType::kXML),
start_(start),
end_(end),
document_(document),
@@ -107,7 +108,7 @@ void StyledMarkupAccumulator::AppendTextWithInlineStyle(
result_.Append("<span style=\"");
MarkupFormatter::AppendAttributeValue(
- result_, inline_style->Style()->AsText(), document_->IsHTMLDocument());
+ result_, inline_style->Style()->AsText(), IsA<HTMLDocument>(document_));
result_.Append("\">");
}
if (!ShouldAnnotate()) {
@@ -141,7 +142,7 @@ void StyledMarkupAccumulator::AppendElementWithInlineStyle(
StringBuilder& out,
const Element& element,
EditingStyle* style) {
- const bool document_is_html = element.GetDocument().IsHTMLDocument();
+ const bool document_is_html = IsA<HTMLDocument>(element.GetDocument());
formatter_.AppendStartTagOpen(out, element);
AttributeCollection attributes = element.Attributes();
for (const auto& attribute : attributes) {
@@ -194,7 +195,7 @@ void StyledMarkupAccumulator::WrapWithStyleNode(CSSPropertyValueSet* style) {
StringBuilder open_tag;
open_tag.Append("<div style=\"");
MarkupFormatter::AppendAttributeValue(open_tag, style->AsText(),
- document_->IsHTMLDocument());
+ IsA<HTMLDocument>(document_));
open_tag.Append("\">");
reversed_preceding_markup_.push_back(open_tag.ToString());
diff --git a/chromium/third_party/blink/renderer/core/editing/serializers/styled_markup_accumulator.h b/chromium/third_party/blink/renderer/core/editing/serializers/styled_markup_accumulator.h
index 32cda2c3669..bb1f1d8ccb6 100644
--- a/chromium/third_party/blink/renderer/core/editing/serializers/styled_markup_accumulator.h
+++ b/chromium/third_party/blink/renderer/core/editing/serializers/styled_markup_accumulator.h
@@ -92,7 +92,7 @@ class StyledMarkupAccumulator final {
MarkupFormatter formatter_;
const TextOffset start_;
const TextOffset end_;
- const Member<Document> document_;
+ Document* const document_;
const CreateMarkupOptions options_;
StringBuilder result_;
Vector<String> reversed_preceding_markup_;
diff --git a/chromium/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc b/chromium/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc
index d941a65dff8..d150e8ca331 100644
--- a/chromium/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc
+++ b/chromium/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc
@@ -105,8 +105,8 @@ class StyledMarkupTraverser {
bool ShouldSerializeUnrenderedElement(const Node&) const;
StyledMarkupAccumulator* accumulator_;
- Member<Node> last_closed_;
- Member<EditingStyle> wrapping_style_;
+ Node* last_closed_;
+ EditingStyle* wrapping_style_;
DISALLOW_COPY_AND_ASSIGN(StyledMarkupTraverser);
};
@@ -135,7 +135,8 @@ StyledMarkupSerializer<Strategy>::StyledMarkupSerializer(
end_(end),
highest_node_to_be_serialized_(highest_node_to_be_serialized),
options_(options),
- last_closed_(highest_node_to_be_serialized) {}
+ last_closed_(highest_node_to_be_serialized),
+ wrapping_style_(nullptr) {}
template <typename Strategy>
static bool NeedInterchangeNewlineAfter(
@@ -358,9 +359,9 @@ Node* StyledMarkupTraverser<Strategy>::Traverse(Node* start_node,
// If |n| is a selection boundary such as <input>, traverse the child
// nodes in the DOM tree instead of the flat tree.
if (HandleSelectionBoundary<Strategy>(*n)) {
- last_closed = StyledMarkupTraverser<EditingStrategy>(accumulator_,
- last_closed_.Get())
- .Traverse(n, EditingStrategy::NextSkippingChildren(*n));
+ last_closed =
+ StyledMarkupTraverser<EditingStrategy>(accumulator_, last_closed_)
+ .Traverse(n, EditingStrategy::NextSkippingChildren(*n));
next = EditingInFlatTreeStrategy::NextSkippingChildren(*n);
} else {
next = Strategy::Next(*n);
diff --git a/chromium/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.h b/chromium/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.h
index afb9bd72cec..115207de85d 100644
--- a/chromium/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.h
+++ b/chromium/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.h
@@ -59,10 +59,10 @@ class StyledMarkupSerializer final {
const PositionTemplate<Strategy> start_;
const PositionTemplate<Strategy> end_;
- const Member<Node> highest_node_to_be_serialized_;
+ Node* const highest_node_to_be_serialized_;
const CreateMarkupOptions options_;
- Member<Node> last_closed_;
- Member<EditingStyle> wrapping_style_;
+ Node* last_closed_;
+ EditingStyle* wrapping_style_;
};
extern template class StyledMarkupSerializer<EditingStrategy>;
diff --git a/chromium/third_party/blink/renderer/core/editing/serializers/text_offset.h b/chromium/third_party/blink/renderer/core/editing/serializers/text_offset.h
index f5367f7190a..27c96b8cb1e 100644
--- a/chromium/third_party/blink/renderer/core/editing/serializers/text_offset.h
+++ b/chromium/third_party/blink/renderer/core/editing/serializers/text_offset.h
@@ -20,14 +20,14 @@ class TextOffset {
TextOffset(Text*, int);
TextOffset(const TextOffset&);
- Text* GetText() const { return text_.Get(); }
+ Text* GetText() const { return text_; }
int Offset() const { return offset_; }
bool IsNull() const;
bool IsNotNull() const;
private:
- Member<Text> text_;
+ Text* text_ = nullptr;
int offset_;
};
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 a01a37b8201..1821a5e93fc 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
@@ -78,7 +78,8 @@ void ColdModeSpellCheckRequester::Invoke(IdleDeadline* deadline) {
TRACE_EVENT0("blink", "ColdModeSpellCheckRequester::invoke");
// TODO(xiaochengh): Figure out if this has any performance impact.
- GetFrame().GetDocument()->UpdateStyleAndLayout();
+ GetFrame().GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kSpellCheck);
const Element* current_focused = CurrentFocusedEditable();
if (!current_focused) {
diff --git a/chromium/third_party/blink/renderer/core/editing/spellcheck/hot_mode_spell_check_requester.cc b/chromium/third_party/blink/renderer/core/editing/spellcheck/hot_mode_spell_check_requester.cc
index 6a97ae4a32e..28b2d10dfa7 100644
--- a/chromium/third_party/blink/renderer/core/editing/spellcheck/hot_mode_spell_check_requester.cc
+++ b/chromium/third_party/blink/renderer/core/editing/spellcheck/hot_mode_spell_check_requester.cc
@@ -96,7 +96,7 @@ EphemeralRange CalculateHotModeCheckingRange(const Element& editable,
HotModeSpellCheckRequester::HotModeSpellCheckRequester(
SpellCheckRequester& requester)
- : requester_(requester) {}
+ : requester_(&requester) {}
void HotModeSpellCheckRequester::CheckSpellingAt(const Position& position) {
const Element* root_editable = RootEditableElementOf(position);
diff --git a/chromium/third_party/blink/renderer/core/editing/spellcheck/hot_mode_spell_check_requester.h b/chromium/third_party/blink/renderer/core/editing/spellcheck/hot_mode_spell_check_requester.h
index 2d9971fb821..c1c667f342c 100644
--- a/chromium/third_party/blink/renderer/core/editing/spellcheck/hot_mode_spell_check_requester.h
+++ b/chromium/third_party/blink/renderer/core/editing/spellcheck/hot_mode_spell_check_requester.h
@@ -25,7 +25,7 @@ class HotModeSpellCheckRequester {
private:
HeapVector<Member<const Element>> processed_root_editables_;
- Member<SpellCheckRequester> requester_;
+ SpellCheckRequester* requester_;
DISALLOW_COPY_AND_ASSIGN(HotModeSpellCheckRequester);
};
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 66d209feb0b..c3bda605135 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
@@ -5,7 +5,7 @@
#include "third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller.h"
#include "third_party/blink/public/platform/task_type.h"
-#include "third_party/blink/renderer/core/dom/idle_request_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_idle_request_options.h"
#include "third_party/blink/renderer/core/editing/commands/undo_stack.h"
#include "third_party/blink/renderer/core/editing/commands/undo_step.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
@@ -63,7 +63,7 @@ IdleSpellCheckController::~IdleSpellCheckController() = default;
void IdleSpellCheckController::Trace(Visitor* visitor) {
visitor->Trace(frame_);
visitor->Trace(cold_mode_requester_);
- DocumentShutdownObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
IdleSpellCheckController::IdleSpellCheckController(LocalFrame& frame)
@@ -161,7 +161,7 @@ void IdleSpellCheckController::HotModeInvocation(IdleDeadline* deadline) {
TRACE_EVENT0("blink", "IdleSpellCheckController::hotModeInvocation");
// TODO(xiaochengh): Figure out if this has any performance impact.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
HotModeSpellCheckRequester requester(GetSpellCheckRequester());
@@ -212,10 +212,10 @@ void IdleSpellCheckController::Invoke(IdleDeadline* deadline) {
}
void IdleSpellCheckController::DidAttachDocument(Document* document) {
- SetContext(document);
+ SetExecutionContext(document->ToExecutionContext());
}
-void IdleSpellCheckController::ContextDestroyed(Document*) {
+void IdleSpellCheckController::ContextDestroyed() {
Deactivate();
}
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 c380d5fecdf..171a8adc367 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
@@ -6,9 +6,9 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_SPELLCHECK_IDLE_SPELL_CHECK_CONTROLLER_H_
#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/dom/document_shutdown_observer.h"
#include "third_party/blink/renderer/core/dom/scripted_idle_task_controller.h"
#include "third_party/blink/renderer/core/editing/forward.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/timer.h"
namespace blink {
@@ -29,7 +29,7 @@ class SpellCheckRequester;
// See design doc for details: https://goo.gl/zONC3v
class CORE_EXPORT IdleSpellCheckController final
: public GarbageCollected<IdleSpellCheckController>,
- public DocumentShutdownObserver {
+ public ExecutionContextLifecycleObserver {
DISALLOW_COPY_AND_ASSIGN(IdleSpellCheckController);
USING_GARBAGE_COLLECTED_MIXIN(IdleSpellCheckController);
@@ -70,12 +70,12 @@ class CORE_EXPORT IdleSpellCheckController final
LocalFrame& GetFrame() const { return *frame_; }
// Returns whether there is an active document to work on.
- bool IsAvailable() const { return LifecycleContext(); }
+ bool IsAvailable() const { return GetExecutionContext(); }
// Return the document to work on. Callable only when IsAvailable() is true.
Document& GetDocument() const {
DCHECK(IsAvailable());
- return *LifecycleContext();
+ return *Document::From(GetExecutionContext());
}
// Returns whether spell checking is globally enabled.
@@ -95,8 +95,8 @@ class CORE_EXPORT IdleSpellCheckController final
void ColdModeTimerFired(TimerBase*);
void ColdModeInvocation(IdleDeadline*);
- // Implements |DocumentShutdownObserver|.
- void ContextDestroyed(Document*) final;
+ // Implements |ExecutionContextLifecycleObserver|.
+ void ContextDestroyed() final;
void DisposeIdleCallback();
diff --git a/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller_test.cc b/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller_test.cc
index e0f8e8dee28..fb13b4cac86 100644
--- a/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/spellcheck/idle_spell_check_controller_test.cc
@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/editing/spellcheck/spell_check_test_base.h"
#include "third_party/blink/renderer/core/editing/spellcheck/spell_checker.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_object_element.h"
@@ -115,25 +116,25 @@ TEST_F(IdleSpellCheckControllerTest, ColdModeToInactive) {
TEST_F(IdleSpellCheckControllerTest, DetachWhenInactive) {
TransitTo(State::kInactive);
- GetDocument().Shutdown();
+ GetFrame().DomWindow()->FrameDestroyed();
EXPECT_EQ(State::kInactive, IdleChecker().GetState());
}
TEST_F(IdleSpellCheckControllerTest, DetachWhenHotModeRequested) {
TransitTo(State::kHotModeRequested);
- GetDocument().Shutdown();
+ GetFrame().DomWindow()->FrameDestroyed();
EXPECT_EQ(State::kInactive, IdleChecker().GetState());
}
TEST_F(IdleSpellCheckControllerTest, DetachWhenColdModeTimerStarted) {
TransitTo(State::kColdModeTimerStarted);
- GetDocument().Shutdown();
+ GetFrame().DomWindow()->FrameDestroyed();
EXPECT_EQ(State::kInactive, IdleChecker().GetState());
}
TEST_F(IdleSpellCheckControllerTest, DetachWhenColdModeRequested) {
TransitTo(State::kColdModeRequested);
- GetDocument().Shutdown();
+ GetFrame().DomWindow()->FrameDestroyed();
EXPECT_EQ(State::kInactive, IdleChecker().GetState());
}
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 e110e675994..d5b3c0c0f19 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
@@ -221,7 +221,9 @@ void SpellChecker::AdvanceToNextMisspelling(bool start_before_selection) {
FindFirstMisspelling(spelling_search_start, spelling_search_end);
}
- if (!misspelled_word.IsEmpty()) {
+ if (misspelled_word.IsEmpty()) {
+ SpellCheckPanelHostClient().UpdateSpellingUIWithMisspelledWord({});
+ } else {
// We found a misspelling. Select the misspelling, update the spelling
// panel, and store a marker so we draw the red squiggle later.
@@ -303,10 +305,8 @@ void SpellChecker::MarkAndReplaceFor(
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetFrame().GetDocument()->UpdateStyleAndLayout();
-
- DocumentLifecycle::DisallowTransitionScope disallow_transition(
- GetFrame().GetDocument()->Lifecycle());
+ GetFrame().GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kSpellCheck);
EphemeralRange checking_range(request->CheckingRange());
@@ -490,7 +490,7 @@ void SpellChecker::ReplaceMisspelledRange(const String& text) {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- current_document.UpdateStyleAndLayout();
+ current_document.UpdateStyleAndLayout(DocumentUpdateReason::kSpellCheck);
// Dispatch 'beforeinput'.
Element* const target = FindEventTargetFrom(
@@ -510,7 +510,8 @@ void SpellChecker::ReplaceMisspelledRange(const String& text) {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetFrame().GetDocument()->UpdateStyleAndLayout();
+ GetFrame().GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kSpellCheck);
if (cancel)
return;
@@ -545,9 +546,9 @@ static Node* FindFirstMarkable(Node* node) {
return nullptr;
if (node->GetLayoutObject()->IsText())
return node;
- if (node->GetLayoutObject()->IsTextControl())
- node = ToLayoutTextControl(node->GetLayoutObject())
- ->GetTextControlElement()
+ if (auto* text_control =
+ DynamicTo<LayoutTextControl>(node->GetLayoutObject()))
+ node = text_control->GetTextControlElement()
->VisiblePositionForIndex(1)
.DeepEquivalent()
.AnchorNode();
diff --git a/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_checker_test.cc b/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_checker_test.cc
index de50eee1b3c..cc7882e46be 100644
--- a/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_checker_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/spellcheck/spell_checker_test.cc
@@ -35,7 +35,7 @@ void SpellCheckerTest::ForceLayout() {
frame_rect.SetWidth(frame_rect.Width() + 1);
frame_rect.SetHeight(frame_rect.Height() + 1);
Page().GetFrameView().SetFrameRect(frame_rect);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
}
TEST_F(SpellCheckerTest, AdvanceToNextMisspellingWithEmptyInputNoCrash) {
@@ -83,7 +83,7 @@ TEST_F(SpellCheckerTest, SpellCheckDoesNotCauseUpdateLayout) {
auto* input = To<HTMLInputElement>(GetDocument().QuerySelector("input"));
input->focus();
input->setValue("Hello, input field");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Position new_position(input->InnerEditorElement()->firstChild(), 3);
GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
diff --git a/chromium/third_party/blink/renderer/core/editing/state_machines/state_machine_util.cc b/chromium/third_party/blink/renderer/core/editing/state_machines/state_machine_util.cc
index 9f3c4eb386f..13d35c58583 100644
--- a/chromium/third_party/blink/renderer/core/editing/state_machines/state_machine_util.cc
+++ b/chromium/third_party/blink/renderer/core/editing/state_machines/state_machine_util.cc
@@ -38,7 +38,7 @@ bool IsIndicSyllabicCategoryVirama(uint32_t code_point) {
bool IsGraphemeBreak(UChar32 prev_code_point, UChar32 next_code_point) {
// The following breaking rules come from Unicode Standard Annex #29 on
- // Unicode Text Segmaentation. See http://www.unicode.org/reports/tr29/
+ // Unicode Text Segmentation. See http://www.unicode.org/reports/tr29/
int prev_prop =
u_getIntPropertyValue(prev_code_point, UCHAR_GRAPHEME_CLUSTER_BREAK);
int next_prop =
@@ -85,6 +85,13 @@ bool IsGraphemeBreak(UChar32 prev_code_point, UChar32 next_code_point) {
Character::IsRegionalIndicator(next_code_point))
NOTREACHED() << "Do not use this function for regional indicators.";
+ // This is an exception for Myanmar IMEs that uses zwnj character as base
+ // character during a composition to avoid merging the actively composed text
+ // into the previous character. We intentionally diverge from UAX#29.
+ // Please see crbug.com/1027695 for more details.
+ if (next_code_point == kZeroWidthNonJoinerCharacter)
+ return true;
+
// Rule GB9, x (Extend | ZWJ)
// Rule GB9a, x SpacingMark
if (next_prop == U_GCB_EXTEND ||
diff --git a/chromium/third_party/blink/renderer/core/editing/state_machines/state_machine_util_test.cc b/chromium/third_party/blink/renderer/core/editing/state_machines/state_machine_util_test.cc
index 3a1c58751d3..f473c1f8b7e 100644
--- a/chromium/third_party/blink/renderer/core/editing/state_machines/state_machine_util_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/state_machines/state_machine_util_test.cc
@@ -168,4 +168,10 @@ TEST(StateMachineUtilTest, IsGraphmeBreak_IndicSyllabicCategoryVirama) {
EXPECT_TRUE(IsGraphemeBreak(kTamilVirama, kDevangariKa));
}
+TEST(StateMachineUtilTest, IsGraphmeBreak_ZWNJSequecne) {
+ // U+200C (kZeroWidthNonJoinerCharacter)
+ EXPECT_TRUE(IsGraphemeBreak('a', WTF::unicode::kZeroWidthNonJoinerCharacter));
+ EXPECT_TRUE(IsGraphemeBreak(WTF::unicode::kZeroWidthNonJoinerCharacter, 'a'));
+}
+
} // 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 75b21990cd5..748094ca5cf 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
@@ -152,8 +152,8 @@ SuggestionInfosWithNodeAndHighlightColor ComputeSuggestionInfos(
Vector<TextSuggestionInfo>& suggestion_infos =
suggestion_infos_with_node_and_highlight_color.suggestion_infos;
- for (const std::pair<const Text*, DocumentMarker*>& node_marker_pair :
- node_suggestion_marker_pairs_sorted_by_length) {
+ for (const std::pair<Member<const Text>, Member<DocumentMarker>>&
+ node_marker_pair : node_suggestion_marker_pairs_sorted_by_length) {
if (node_marker_pair.first !=
suggestion_infos_with_node_and_highlight_color.text_node)
continue;
@@ -161,7 +161,7 @@ SuggestionInfosWithNodeAndHighlightColor ComputeSuggestionInfos(
if (suggestion_infos.size() == max_number_of_suggestions)
break;
- const auto* marker = To<SuggestionMarker>(node_marker_pair.second);
+ const auto* marker = To<SuggestionMarker>(node_marker_pair.second.Get());
const Vector<String>& marker_suggestions = marker->Suggestions();
for (wtf_size_t suggestion_index = 0;
suggestion_index < marker_suggestions.size(); ++suggestion_index) {
@@ -197,7 +197,7 @@ TextSuggestionController::TextSuggestionController(LocalFrame& frame)
void TextSuggestionController::DidAttachDocument(Document* document) {
DCHECK(document);
- SetContext(document);
+ SetExecutionContext(document->ToExecutionContext());
}
bool TextSuggestionController::IsMenuOpen() const {
@@ -206,8 +206,18 @@ bool TextSuggestionController::IsMenuOpen() const {
void TextSuggestionController::HandlePotentialSuggestionTap(
const PositionInFlatTree& caret_position) {
+ if (!IsAvailable()) {
+ // TODO(crbug.com/1054955): We should fix caller not to make this happens.
+ NOTREACHED();
+ return;
+ }
+ if (GetFrame() != GetDocument().GetFrame()) {
+ // TODO(crbug.com/1054955): We should fix caller not to make this happens.
+ NOTREACHED();
+ return;
+ }
// TODO(crbug.com/779126): add support for suggestions in immersive mode.
- if (GetDocument().GetSettings()->GetImmersiveModeEnabled())
+ if (GetFrame().GetSettings()->GetImmersiveModeEnabled())
return;
// It's theoretically possible, but extremely unlikely, that the user has
@@ -243,7 +253,7 @@ void TextSuggestionController::HandlePotentialSuggestionTap(
void TextSuggestionController::Trace(Visitor* visitor) {
visitor->Trace(frame_);
- DocumentShutdownObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
void TextSuggestionController::ReplaceActiveSuggestionRange(
@@ -420,6 +430,7 @@ void TextSuggestionController::ShowSpellCheckMenu(
GetDocument().Markers().AddActiveSuggestionMarker(
active_suggestion_range, SK_ColorTRANSPARENT,
ui::mojom::ImeTextSpanThickness::kNone,
+ ui::mojom::ImeTextSpanUnderlineStyle::kSolid, SK_ColorTRANSPARENT,
LayoutTheme::GetTheme().PlatformActiveSpellingMarkerHighlightColor());
Vector<String> suggestions;
@@ -485,6 +496,7 @@ void TextSuggestionController::ShowSuggestionMenu(
GetDocument().Markers().AddActiveSuggestionMarker(
marker_range, SK_ColorTRANSPARENT, ui::mojom::ImeTextSpanThickness::kThin,
+ ui::mojom::ImeTextSpanUnderlineStyle::kSolid, SK_ColorTRANSPARENT,
suggestion_infos_with_node_and_highlight_color.highlight_color);
is_suggestion_menu_open_ = true;
@@ -523,11 +535,11 @@ void TextSuggestionController::CallMojoShowTextSuggestionMenu(
Document& TextSuggestionController::GetDocument() const {
DCHECK(IsAvailable());
- return *LifecycleContext();
+ return *Document::From(GetExecutionContext());
}
bool TextSuggestionController::IsAvailable() const {
- return LifecycleContext();
+ return GetExecutionContext();
}
LocalFrame& TextSuggestionController::GetFrame() const {
@@ -612,7 +624,8 @@ void TextSuggestionController::ReplaceRangeWithText(const EphemeralRange& range,
// available or not.
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetFrame().GetDocument()->UpdateStyleAndLayout();
+ GetFrame().GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kSpellCheck);
// Dispatch 'beforeinput'.
Element* const target = FindEventTargetFrom(
@@ -634,7 +647,8 @@ void TextSuggestionController::ReplaceRangeWithText(const EphemeralRange& range,
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetFrame().GetDocument()->UpdateStyleAndLayout();
+ GetFrame().GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kSpellCheck);
if (is_canceled)
return;
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 61702afe3e0..29b70a243ef 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
@@ -10,9 +10,9 @@
#include "third_party/blink/public/mojom/input/input_host.mojom-blink.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/document_shutdown_observer.h"
#include "third_party/blink/renderer/core/editing/forward.h"
#include "third_party/blink/renderer/core/editing/markers/document_marker.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
@@ -27,7 +27,7 @@ struct TextSuggestionInfo;
// suggestions. Android is currently the only platform that has such a menu.
class CORE_EXPORT TextSuggestionController final
: public GarbageCollected<TextSuggestionController>,
- public DocumentShutdownObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(TextSuggestionController);
public:
@@ -46,6 +46,9 @@ class CORE_EXPORT TextSuggestionController final
void OnSuggestionMenuClosed();
void SuggestionMenuTimeoutCallback(size_t max_number_of_suggestions);
+ // ExecutionContextLifecycleObserver methods:
+ void ContextDestroyed() override {}
+
void Trace(Visitor*) override;
private:
diff --git a/chromium/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller_test.cc b/chromium/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller_test.cc
index 65ca6e7f00d..d2a6e5a1f8a 100644
--- a/chromium/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller_test.cc
@@ -12,8 +12,10 @@
#include "third_party/blink/renderer/core/editing/spellcheck/spell_checker.h"
#include "third_party/blink/renderer/core/editing/testing/editing_test_base.h"
#include "third_party/blink/renderer/core/editing/visible_selection.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
using ui::mojom::ImeTextSpanThickness;
+using ui::mojom::ImeTextSpanUnderlineStyle;
namespace blink {
@@ -56,7 +58,8 @@ TEST_F(TextSuggestionControllerTest, ApplySpellCheckSuggestion) {
GetDocument().Markers().AddActiveSuggestionMarker(
EphemeralRange(Position(text, 0), Position(text, 8)), Color::kBlack,
- ImeTextSpanThickness::kThin, Color::kBlack);
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid,
+ Color::kBlack, Color::kBlack);
// Select immediately before misspelling
GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
SelectionInDOMTree::Builder()
@@ -237,7 +240,8 @@ TEST_F(TextSuggestionControllerTest, DeleteActiveSuggestionRange_DeleteAtEnd) {
// Mark "word2" as the active suggestion range
GetDocument().Markers().AddActiveSuggestionMarker(
EphemeralRange(Position(text, 6), Position(text, 11)),
- Color::kTransparent, ImeTextSpanThickness::kThin, Color::kBlack);
+ Color::kTransparent, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
// Select immediately before word2
GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
SelectionInDOMTree::Builder()
@@ -263,7 +267,8 @@ TEST_F(TextSuggestionControllerTest,
// Mark "word2" as the active suggestion range
GetDocument().Markers().AddActiveSuggestionMarker(
EphemeralRange(Position(text, 6), Position(text, 11)),
- Color::kTransparent, ImeTextSpanThickness::kThin, Color::kBlack);
+ Color::kTransparent, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
// Select immediately before word2
GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
SelectionInDOMTree::Builder()
@@ -290,7 +295,8 @@ TEST_F(TextSuggestionControllerTest,
// Mark "word1" as the active suggestion range
GetDocument().Markers().AddActiveSuggestionMarker(
EphemeralRange(Position(text, 0), Position(text, 5)), Color::kTransparent,
- ImeTextSpanThickness::kThin, Color::kBlack);
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid,
+ Color::kBlack, Color::kBlack);
// Select immediately before word1
GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
SelectionInDOMTree::Builder()
@@ -318,7 +324,8 @@ TEST_F(TextSuggestionControllerTest,
// Mark "word1" as the active suggestion range
GetDocument().Markers().AddActiveSuggestionMarker(
EphemeralRange(Position(text, 0), Position(text, 5)), Color::kTransparent,
- ImeTextSpanThickness::kThin, Color::kBlack);
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid,
+ Color::kBlack, Color::kBlack);
// Select immediately before word1
GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
SelectionInDOMTree::Builder()
@@ -349,7 +356,8 @@ TEST_F(TextSuggestionControllerTest,
// Mark "word2" as the active suggestion range
GetDocument().Markers().AddActiveSuggestionMarker(
EphemeralRange(Position(text, 5), Position(text, 10)),
- Color::kTransparent, ImeTextSpanThickness::kThin, Color::kBlack);
+ Color::kTransparent, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
// Select immediately before word2
GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
SelectionInDOMTree::Builder()
@@ -375,7 +383,8 @@ TEST_F(TextSuggestionControllerTest,
// Mark "word2" as the active suggestion range
GetDocument().Markers().AddActiveSuggestionMarker(
EphemeralRange(Position(text, 6), Position(text, 11)),
- Color::kTransparent, ImeTextSpanThickness::kThin, Color::kBlack);
+ Color::kTransparent, ImeTextSpanThickness::kThin,
+ ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
// Select immediately before word2
GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
SelectionInDOMTree::Builder()
@@ -401,7 +410,8 @@ TEST_F(TextSuggestionControllerTest,
// Mark "word1" as the active suggestion range
GetDocument().Markers().AddActiveSuggestionMarker(
EphemeralRange(Position(text, 0), Position(text, 5)), Color::kTransparent,
- ImeTextSpanThickness::kThin, Color::kBlack);
+ ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid,
+ Color::kBlack, Color::kBlack);
// Select immediately before word1
GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
SelectionInDOMTree::Builder()
@@ -460,7 +470,7 @@ TEST_F(TextSuggestionControllerTest,
TEST_F(TextSuggestionControllerTest, CallbackHappensAfterDocumentDestroyed) {
LocalFrame& frame = *GetDocument().GetFrame();
- GetDocument().Shutdown();
+ frame.DomWindow()->FrameDestroyed();
// Shouldn't crash
frame.GetTextSuggestionController().SuggestionMenuTimeoutCallback(0);
diff --git a/chromium/third_party/blink/renderer/core/editing/surrounding_text.cc b/chromium/third_party/blink/renderer/core/editing/surrounding_text.cc
index cb9d29a8b4f..c2dab2267de 100644
--- a/chromium/third_party/blink/renderer/core/editing/surrounding_text.cc
+++ b/chromium/third_party/blink/renderer/core/editing/surrounding_text.cc
@@ -42,7 +42,7 @@ namespace {
EphemeralRange ComputeRangeFromFrameSelection(LocalFrame* frame) {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- frame->GetDocument()->UpdateStyleAndLayout();
+ frame->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
return frame->Selection()
.ComputeVisibleSelectionInDOMTree()
diff --git a/chromium/third_party/blink/renderer/core/editing/surrounding_text_test.cc b/chromium/third_party/blink/renderer/core/editing/surrounding_text_test.cc
index 4809afae953..56d0ad75763 100644
--- a/chromium/third_party/blink/renderer/core/editing/surrounding_text_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/surrounding_text_test.cc
@@ -36,8 +36,8 @@ void SurroundingTextTest::SetUp() {
}
void SurroundingTextTest::SetHTML(const String& content) {
- GetDocument().body()->SetInnerHTMLFromString(content);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().body()->setInnerHTML(content);
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
}
EphemeralRange SurroundingTextTest::Select(int start, int end) {
@@ -307,7 +307,7 @@ TEST_F(SurroundingTextTest, EmptyInputElementWithChild) {
TextControlElement* input_element = reinterpret_cast<TextControlElement*>(
GetDocument().getElementById("input_name"));
input_element->SetInnerEditorValue("John Smith");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
// BODY
// INPUT
diff --git a/chromium/third_party/blink/renderer/core/editing/testing/editing_test_base.cc b/chromium/third_party/blink/renderer/core/editing/testing/editing_test_base.cc
index b66976cf71d..945ddbace93 100644
--- a/chromium/third_party/blink/renderer/core/editing/testing/editing_test_base.cc
+++ b/chromium/third_party/blink/renderer/core/editing/testing/editing_test_base.cc
@@ -73,10 +73,10 @@ ShadowRoot* EditingTestBase::CreateShadowRootForElementWithIDAndSetInnerHTML(
ShadowRoot& shadow_root =
scope.getElementById(AtomicString::FromUTF8(host_element_id))
->CreateV0ShadowRootForTesting();
- shadow_root.SetInnerHTMLFromString(String::FromUTF8(shadow_root_content),
- ASSERT_NO_EXCEPTION);
+ shadow_root.setInnerHTML(String::FromUTF8(shadow_root_content),
+ ASSERT_NO_EXCEPTION);
scope.GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
return &shadow_root;
}
diff --git a/chromium/third_party/blink/renderer/core/editing/testing/selection_sample.cc b/chromium/third_party/blink/renderer/core/editing/testing/selection_sample.cc
index 9ae865ebf77..4d9fbc36087 100644
--- a/chromium/third_party/blink/renderer/core/editing/testing/selection_sample.cc
+++ b/chromium/third_party/blink/renderer/core/editing/testing/selection_sample.cc
@@ -6,12 +6,12 @@
#include <algorithm>
+#include "third_party/blink/renderer/bindings/core/v8/v8_shadow_root_init.h"
#include "third_party/blink/renderer/core/dom/attribute.h"
#include "third_party/blink/renderer/core/dom/character_data.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/dom/processing_instruction.h"
-#include "third_party/blink/renderer/core/dom/shadow_root_init.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
#include "third_party/blink/renderer/core/editing/selection_template.h"
#include "third_party/blink/renderer/core/html/html_collection.h"
@@ -60,7 +60,7 @@ class Parser final {
// |SelectionInDOMTree| marked up within |selection_text|.
SelectionInDOMTree SetSelectionText(HTMLElement* element,
const std::string& selection_text) {
- element->SetInnerHTMLFromString(String::FromUTF8(selection_text.c_str()));
+ element->setInnerHTML(String::FromUTF8(selection_text.c_str()));
ConvertTemplatesToShadowRoots(*element);
Traverse(element);
if (anchor_node_ && focus_node_) {
@@ -162,8 +162,8 @@ class Parser final {
NOTREACHED() << node;
}
- Member<Node> anchor_node_;
- Member<Node> focus_node_;
+ Node* anchor_node_ = nullptr;
+ Node* focus_node_ = nullptr;
int anchor_offset_ = 0;
int focus_offset_ = 0;
};
diff --git a/chromium/third_party/blink/renderer/core/editing/testing/selection_sample_test.cc b/chromium/third_party/blink/renderer/core/editing/testing/selection_sample_test.cc
index f266eb74594..85a0d2de848 100644
--- a/chromium/third_party/blink/renderer/core/editing/testing/selection_sample_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/testing/selection_sample_test.cc
@@ -42,7 +42,7 @@ TEST_F(SelectionSampleTest, GetSelectionTextFlatTree) {
TEST_F(SelectionSampleTest, SetCommentInBody) {
const SelectionInDOMTree& selection = SelectionSample::SetSelectionText(
GetDocument().body(), "<!--^-->foo<!--|-->");
- EXPECT_EQ("foo", GetDocument().body()->InnerHTMLAsString());
+ EXPECT_EQ("foo", GetDocument().body()->innerHTML());
EXPECT_EQ(SelectionInDOMTree::Builder()
.Collapse(Position(GetDocument().body(), 0))
.Extend(Position(GetDocument().body(), 1))
@@ -55,7 +55,7 @@ TEST_F(SelectionSampleTest, SetCommentInElement) {
GetDocument().body(), "<span id=sample><!--^-->foo<!--|--></span>");
const Element* const sample = GetDocument().body()->getElementById("sample");
EXPECT_EQ("<span id=\"sample\">foo</span>",
- GetDocument().body()->InnerHTMLAsString());
+ GetDocument().body()->innerHTML());
EXPECT_EQ(SelectionInDOMTree::Builder()
.Collapse(Position(sample, 0))
.Extend(Position(sample, 1))
@@ -66,7 +66,7 @@ TEST_F(SelectionSampleTest, SetCommentInElement) {
TEST_F(SelectionSampleTest, SetEmpty1) {
const SelectionInDOMTree& selection =
SelectionSample::SetSelectionText(GetDocument().body(), "|");
- EXPECT_EQ("", GetDocument().body()->InnerHTMLAsString());
+ EXPECT_EQ("", GetDocument().body()->innerHTML());
EXPECT_EQ(0u, GetDocument().body()->CountChildren());
EXPECT_EQ(SelectionInDOMTree::Builder()
.Collapse(Position(GetDocument().body(), 0))
@@ -77,7 +77,7 @@ TEST_F(SelectionSampleTest, SetEmpty1) {
TEST_F(SelectionSampleTest, SetEmpty2) {
const SelectionInDOMTree& selection =
SelectionSample::SetSelectionText(GetDocument().body(), "^|");
- EXPECT_EQ("", GetDocument().body()->InnerHTMLAsString());
+ EXPECT_EQ("", GetDocument().body()->innerHTML());
EXPECT_EQ(0u, GetDocument().body()->CountChildren());
EXPECT_EQ(SelectionInDOMTree::Builder()
.Collapse(Position(GetDocument().body(), 0))
@@ -102,7 +102,7 @@ TEST_F(SelectionSampleTest, SetText) {
{
const auto& selection =
SelectionSample::SetSelectionText(GetDocument().body(), "^ab|c");
- EXPECT_EQ("abc", GetDocument().body()->InnerHTMLAsString());
+ EXPECT_EQ("abc", GetDocument().body()->innerHTML());
EXPECT_EQ(SelectionInDOMTree::Builder()
.Collapse(Position(GetDocument().body()->firstChild(), 0))
.Extend(Position(GetDocument().body()->firstChild(), 2))
@@ -112,7 +112,7 @@ TEST_F(SelectionSampleTest, SetText) {
{
const auto& selection =
SelectionSample::SetSelectionText(GetDocument().body(), "a^b|c");
- EXPECT_EQ("abc", GetDocument().body()->InnerHTMLAsString());
+ EXPECT_EQ("abc", GetDocument().body()->innerHTML());
EXPECT_EQ(SelectionInDOMTree::Builder()
.Collapse(Position(GetDocument().body()->firstChild(), 1))
.Extend(Position(GetDocument().body()->firstChild(), 2))
@@ -122,7 +122,7 @@ TEST_F(SelectionSampleTest, SetText) {
{
const auto& selection =
SelectionSample::SetSelectionText(GetDocument().body(), "ab^|c");
- EXPECT_EQ("abc", GetDocument().body()->InnerHTMLAsString());
+ EXPECT_EQ("abc", GetDocument().body()->innerHTML());
EXPECT_EQ(SelectionInDOMTree::Builder()
.Collapse(Position(GetDocument().body()->firstChild(), 2))
.Build(),
@@ -131,7 +131,7 @@ TEST_F(SelectionSampleTest, SetText) {
{
const auto& selection =
SelectionSample::SetSelectionText(GetDocument().body(), "ab|c^");
- EXPECT_EQ("abc", GetDocument().body()->InnerHTMLAsString());
+ EXPECT_EQ("abc", GetDocument().body()->innerHTML());
EXPECT_EQ(SelectionInDOMTree::Builder()
.Collapse(Position(GetDocument().body()->firstChild(), 3))
.Extend(Position(GetDocument().body()->firstChild(), 2))
@@ -267,7 +267,7 @@ TEST_F(SelectionSampleTest, ConvertTemplatesToShadowRoots) {
ShadowRoot* shadow_root = host->ShadowRootIfV1();
ASSERT_TRUE(shadow_root->IsShadowRoot());
EXPECT_EQ("<div>shadow_first</div><div>shadow_second</div>",
- shadow_root->InnerHTMLAsString());
+ shadow_root->innerHTML());
}
TEST_F(SelectionSampleTest, ConvertTemplatesToShadowRootsNoTemplates) {
@@ -281,7 +281,7 @@ TEST_F(SelectionSampleTest, ConvertTemplatesToShadowRootsNoTemplates) {
SelectionSample::ConvertTemplatesToShadowRootsForTesring(
*(To<HTMLElement>(host)));
EXPECT_FALSE(host->ShadowRootIfV1());
- EXPECT_EQ("<div>first</div><div>second</div>", host->InnerHTMLAsString());
+ EXPECT_EQ("<div>first</div><div>second</div>", host->innerHTML());
}
TEST_F(SelectionSampleTest, ConvertTemplatesToShadowRootsMultipleTemplates) {
@@ -308,10 +308,10 @@ TEST_F(SelectionSampleTest, ConvertTemplatesToShadowRootsMultipleTemplates) {
EXPECT_TRUE(shadow_root_1->IsShadowRoot());
EXPECT_EQ("<div>shadow_first</div><div>shadow_second</div>",
- shadow_root_1->InnerHTMLAsString());
+ shadow_root_1->innerHTML());
EXPECT_TRUE(shadow_root_2->IsShadowRoot());
EXPECT_EQ("<div>shadow_third</div><div>shadow_forth</div>",
- shadow_root_2->InnerHTMLAsString());
+ shadow_root_2->innerHTML());
}
TEST_F(SelectionSampleTest, TraverseShadowContent) {
@@ -324,7 +324,7 @@ TEST_F(SelectionSampleTest, TraverseShadowContent) {
"</div>";
const SelectionInDOMTree& selection =
SelectionSample::SetSelectionText(body, content);
- EXPECT_EQ("<div id=\"host\"></div>", body->InnerHTMLAsString());
+ EXPECT_EQ("<div id=\"host\"></div>", body->innerHTML());
Element* host = body->getElementById("host");
ShadowRoot* shadow_root = host->ShadowRootIfV1();
@@ -332,7 +332,7 @@ TEST_F(SelectionSampleTest, TraverseShadowContent) {
EXPECT_EQ(
"<div id=\"shadow1\">shadow_first</div>"
"<div id=\"shadow2\">shadow_second</div>",
- shadow_root->InnerHTMLAsString());
+ shadow_root->innerHTML());
EXPECT_EQ(Position(shadow_root->getElementById("shadow1")->firstChild(), 0),
selection.Base());
@@ -353,7 +353,7 @@ TEST_F(SelectionSampleTest, TraverseShadowContentWithSlot) {
const SelectionInDOMTree& selection =
SelectionSample::SetSelectionText(body, content);
EXPECT_EQ("<div id=\"host\">foo<span slot=\"slot1\">bar</span></div>",
- body->InnerHTMLAsString());
+ body->innerHTML());
Element* host = body->getElementById("host");
ShadowRoot* shadow_root = host->ShadowRootIfV1();
@@ -362,7 +362,7 @@ TEST_F(SelectionSampleTest, TraverseShadowContentWithSlot) {
"<div id=\"shadow1\">shadow_first</div>"
"<slot name=\"slot1\">slot</slot>"
"<div id=\"shadow2\">shadow_second</div>",
- shadow_root->InnerHTMLAsString());
+ shadow_root->innerHTML());
EXPECT_EQ(Position(GetDocument().getElementById("host")->firstChild(), 0),
selection.Base());
@@ -388,7 +388,7 @@ TEST_F(SelectionSampleTest, TraverseMultipleShadowContents) {
const SelectionInDOMTree& selection =
SelectionSample::SetSelectionText(body, content);
EXPECT_EQ("<div id=\"host1\"></div><div id=\"host2\"></div>",
- body->InnerHTMLAsString());
+ body->innerHTML());
Element* host1 = body->getElementById("host1");
ShadowRoot* shadow_root1 = host1->ShadowRootIfV1();
@@ -399,11 +399,11 @@ TEST_F(SelectionSampleTest, TraverseMultipleShadowContents) {
EXPECT_EQ(
"<div id=\"shadow1\">shadow_first</div>"
"<div id=\"shadow2\">shadow_second</div>",
- shadow_root1->InnerHTMLAsString());
+ shadow_root1->innerHTML());
EXPECT_EQ(
"<div id=\"shadow3\">shadow_third</div>"
"<div id=\"shadow4\">shadow_forth</div>",
- shadow_root2->InnerHTMLAsString());
+ shadow_root2->innerHTML());
EXPECT_EQ(Position(shadow_root1->getElementById("shadow1")->firstChild(), 0),
selection.Base());
diff --git a/chromium/third_party/blink/renderer/core/editing/text_offset_mapping.cc b/chromium/third_party/blink/renderer/core/editing/text_offset_mapping.cc
index a49900ca1a4..fd564038fa9 100644
--- a/chromium/third_party/blink/renderer/core/editing/text_offset_mapping.cc
+++ b/chromium/third_party/blink/renderer/core/editing/text_offset_mapping.cc
@@ -52,6 +52,17 @@ bool CanBeInlineContentsContainer(const LayoutObject& layout_object) {
return HasNonPsuedoNode(*block_flow);
}
+Node* PreviousNodeSkippingAncestors(const Node& node) {
+ ContainerNode* parent = FlatTreeTraversal::Parent(node);
+ for (Node* runner = FlatTreeTraversal::Previous(node); runner;
+ runner = FlatTreeTraversal::Previous(*runner)) {
+ if (runner != parent)
+ return runner;
+ parent = FlatTreeTraversal::Parent(*runner);
+ }
+ return nullptr;
+}
+
// Returns outer most nested inline formatting context.
const LayoutBlockFlow& RootInlineContentsContainerOf(
const LayoutBlockFlow& block_flow) {
@@ -60,8 +71,9 @@ const LayoutBlockFlow& RootInlineContentsContainerOf(
for (const LayoutBlock* runner = block_flow.ContainingBlock(); runner;
runner = runner->ContainingBlock()) {
auto* containing_block_flow = DynamicTo<LayoutBlockFlow>(runner);
- if (containing_block_flow && runner->ChildrenInline())
- root_block_flow = containing_block_flow;
+ if (!containing_block_flow || !runner->ChildrenInline())
+ break;
+ root_block_flow = containing_block_flow;
}
DCHECK(!root_block_flow->IsAtomicInlineLevel())
<< block_flow << ' ' << root_block_flow;
@@ -118,6 +130,7 @@ const LayoutBlockFlow* ComputeInlineContentsAsBlockFlow(
TextOffsetMapping::InlineContents CreateInlineContentsFromBlockFlow(
const LayoutBlockFlow& block_flow) {
+ DCHECK(block_flow.ChildrenInline()) << block_flow;
const LayoutObject* first = nullptr;
for (const LayoutObject* runner = block_flow.FirstChild(); runner;
runner = runner->NextInPreOrder(&block_flow)) {
@@ -270,7 +283,7 @@ TextOffsetMapping::InlineContents TextOffsetMapping::FindBackwardInlineContents(
auto previous_skipping_text_control = [](const Node& node) -> const Node* {
DCHECK(!EnclosingTextControl(&node));
- const Node* previous = FlatTreeTraversal::Previous(node);
+ const Node* previous = PreviousNodeSkippingAncestors(node);
const TextControlElement* previous_text_control =
EnclosingTextControl(previous);
if (!previous_text_control)
diff --git a/chromium/third_party/blink/renderer/core/editing/text_offset_mapping_test.cc b/chromium/third_party/blink/renderer/core/editing/text_offset_mapping_test.cc
index e6db282def1..9c6412805bb 100644
--- a/chromium/third_party/blink/renderer/core/editing/text_offset_mapping_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/text_offset_mapping_test.cc
@@ -391,6 +391,7 @@ TEST_P(ParameterizedTextOffsetMappingTest, RangeWithNestedPosition) {
TEST_P(ParameterizedTextOffsetMappingTest, RangeWithSelect) {
EXPECT_EQ(
"^<select>"
+ "<div aria-hidden=\"true\"></div>"
"<slot name=\"user-agent-custom-assign-slot\"></slot>"
"</select>foo|",
GetRange("<select>|</select>foo"));
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 cabb3c35026..9a5adde5b36 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
@@ -89,15 +89,15 @@ TEST_F(VisiblePositionTest, NonNullInvalidatedAfterStyleChange) {
Position position(paragraph->firstChild(), 1);
VisiblePosition visible_position1 = CreateVisiblePosition(position);
- div->style()->setProperty(&GetDocument(), "color", "red", "important",
- ASSERT_NO_EXCEPTION);
+ div->style()->setProperty(GetDocument().ToExecutionContext(), "color", "red",
+ "important", ASSERT_NO_EXCEPTION);
EXPECT_FALSE(visible_position1.IsValid());
UpdateAllLifecyclePhasesForTest();
VisiblePosition visible_position2 = CreateVisiblePosition(position);
- div->style()->setProperty(&GetDocument(), "display", "none", "important",
- ASSERT_NO_EXCEPTION);
+ div->style()->setProperty(GetDocument().ToExecutionContext(), "display",
+ "none", "important", ASSERT_NO_EXCEPTION);
EXPECT_FALSE(visible_position2.IsValid());
UpdateAllLifecyclePhasesForTest();
diff --git a/chromium/third_party/blink/renderer/core/editing/visible_selection_test.cc b/chromium/third_party/blink/renderer/core/editing/visible_selection_test.cc
index 77e481324ce..0fed925d2de 100644
--- a/chromium/third_party/blink/renderer/core/editing/visible_selection_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/visible_selection_test.cc
@@ -687,7 +687,7 @@ TEST_F(VisibleSelectionTest, updateIfNeededWithShadowHost) {
// Simulates modifying DOM tree to invalidate distribution.
Element* host = GetDocument().getElementById("host");
host->AppendChild(sample);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
// Simulates to restore selection from undo stack.
selection = CreateVisibleSelection(selection.AsSelection());
@@ -699,7 +699,7 @@ TEST_F(VisibleSelectionTest, BackwardSelectionWithMultipleEmptyBodies) {
Element* body = GetDocument().body();
Element* new_body = GetDocument().CreateRawElement(html_names::kBodyTag);
body->appendChild(new_body);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
const SelectionInDOMTree selection =
SelectionInDOMTree::Builder()
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 014e69a138d..46334945df3 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
@@ -69,10 +69,10 @@ PositionWithAffinityTemplate<Strategy> StartPositionForLine(
}
NGInlineCursor line_box = caret_position.cursor;
line_box.MoveToContainingLine();
- DCHECK(line_box.IsLineBox()) << line_box;
+ DCHECK(line_box.Current().IsLineBox()) << line_box;
const PhysicalOffset start_point = line_box.LineStartPoint();
return FromPositionInDOMTree<Strategy>(
- line_box.CursorForDescendants().PositionForPoint(start_point));
+ line_box.PositionForPointInInlineBox(start_point));
}
const InlineBox* inline_box =
@@ -254,7 +254,7 @@ static PositionWithAffinityTemplate<Strategy> EndPositionForLine(
line_box.MoveToContainingLine();
const PhysicalOffset end_point = line_box.LineEndPoint();
return FromPositionInDOMTree<Strategy>(
- line_box.CursorForDescendants().PositionForPoint(end_point));
+ line_box.PositionForPointInInlineBox(end_point));
}
const InlineBox* inline_box =
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 f2cc911f76c..1e6bf188ee5 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
@@ -60,7 +60,9 @@ class ParameterizedVisibleUnitsLineTest
protected:
ParameterizedVisibleUnitsLineTest() : ScopedLayoutNGForTest(GetParam()) {}
- bool LayoutNGEnabled() const { return GetParam(); }
+ bool LayoutNGEnabled() const {
+ return RuntimeEnabledFeatures::LayoutNGEnabled();
+ }
};
INSTANTIATE_TEST_SUITE_P(All,
diff --git a/chromium/third_party/blink/renderer/core/editing/visible_units_sentence_test.cc b/chromium/third_party/blink/renderer/core/editing/visible_units_sentence_test.cc
index 2f172c12ee0..c71d3ad0a16 100644
--- a/chromium/third_party/blink/renderer/core/editing/visible_units_sentence_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/visible_units_sentence_test.cc
@@ -56,7 +56,9 @@ class ParameterizedVisibleUnitsSentenceTest
protected:
ParameterizedVisibleUnitsSentenceTest() : ScopedLayoutNGForTest(GetParam()) {}
- bool LayoutNGEnabled() const { return GetParam(); }
+ bool LayoutNGEnabled() const {
+ return RuntimeEnabledFeatures::LayoutNGEnabled();
+ }
};
INSTANTIATE_TEST_SUITE_P(All,
diff --git a/chromium/third_party/blink/renderer/core/editing/visible_units_test.cc b/chromium/third_party/blink/renderer/core/editing/visible_units_test.cc
index 6e002c7c73a..69ef2db0725 100644
--- a/chromium/third_party/blink/renderer/core/editing/visible_units_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/visible_units_test.cc
@@ -331,7 +331,7 @@ TEST_F(VisibleUnitsTest, isVisuallyEquivalentCandidateWithHTMLBodyElement) {
body->AppendChild(three);
body->AppendChild(four);
one->appendChild(body);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_FALSE(IsVisuallyEquivalentCandidate(
Position(GetDocument().documentElement(), 0)));
diff --git a/chromium/third_party/blink/renderer/core/editing/visible_units_word_test.cc b/chromium/third_party/blink/renderer/core/editing/visible_units_word_test.cc
index e6481fb213a..d3e11728af2 100644
--- a/chromium/third_party/blink/renderer/core/editing/visible_units_word_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/visible_units_word_test.cc
@@ -82,7 +82,9 @@ class ParameterizedVisibleUnitsWordTest
protected:
ParameterizedVisibleUnitsWordTest() : ScopedLayoutNGForTest(GetParam()) {}
- bool LayoutNGEnabled() const { return GetParam(); }
+ bool LayoutNGEnabled() const {
+ return RuntimeEnabledFeatures::LayoutNGEnabled();
+ }
};
INSTANTIATE_TEST_SUITE_P(All,
@@ -652,6 +654,108 @@ TEST_P(ParameterizedVisibleUnitsWordTest, PreviousWordCrossingPlaceholderBR) {
EXPECT_EQ("<p>|<br></p><p>abc</p>", DoPreviousWord("<p><br></p><p>|abc</p>"));
}
+TEST_P(ParameterizedVisibleUnitsWordTest, PreviousWordInFloat) {
+ InsertStyleElement(
+ "c { display: block; float: right; }"
+ "e { display: block; }");
+
+ // To "|abc"
+ EXPECT_EQ("<c><e>|abc def ghi</e></c>",
+ DoPreviousWord("<c><e>|abc def ghi</e></c>"));
+ EXPECT_EQ("<c><e>|abc def ghi</e></c>",
+ DoPreviousWord("<c><e>a|bc def ghi</e></c>"));
+ EXPECT_EQ("<c><e>|abc def ghi</e></c>",
+ DoPreviousWord("<c><e>ab|c def ghi</e></c>"));
+ EXPECT_EQ("<c><e>|abc def ghi</e></c>",
+ DoPreviousWord("<c><e>abc| def ghi</e></c>"));
+ EXPECT_EQ("<c><e>|abc def ghi</e></c>",
+ DoPreviousWord("<c><e>abc |def ghi</e></c>"));
+ // To "|def"
+ EXPECT_EQ("<c><e>abc |def ghi</e></c>",
+ DoPreviousWord("<c><e>abc d|ef ghi</e></c>"));
+ EXPECT_EQ("<c><e>abc |def ghi</e></c>",
+ DoPreviousWord("<c><e>abc de|f ghi</e></c>"));
+ EXPECT_EQ("<c><e>abc |def ghi</e></c>",
+ DoPreviousWord("<c><e>abc def| ghi</e></c>"));
+ EXPECT_EQ("<c><e>abc |def ghi</e></c>",
+ DoPreviousWord("<c><e>abc def |ghi</e></c>"));
+ // To "|ghi"
+ EXPECT_EQ("<c><e>abc def |ghi</e></c>",
+ DoPreviousWord("<c><e>abc def g|hi</e></c>"));
+ EXPECT_EQ("<c><e>abc def |ghi</e></c>",
+ DoPreviousWord("<c><e>abc def gh|i</e></c>"));
+ EXPECT_EQ("<c><e>abc def |ghi</e></c>",
+ DoPreviousWord("<c><e>abc def ghi|</e></c>"));
+}
+
+TEST_P(ParameterizedVisibleUnitsWordTest, PreviousWordInInlineBlock) {
+ InsertStyleElement(
+ "c { display: inline-block; }"
+ "e { display: block; }");
+
+ // To "|abc"
+ EXPECT_EQ("<c><e>|abc def ghi</e></c>",
+ DoPreviousWord("<c><e>|abc def ghi</e></c>"));
+ EXPECT_EQ("<c><e>|abc def ghi</e></c>",
+ DoPreviousWord("<c><e>a|bc def ghi</e></c>"));
+ EXPECT_EQ("<c><e>|abc def ghi</e></c>",
+ DoPreviousWord("<c><e>ab|c def ghi</e></c>"));
+ EXPECT_EQ("<c><e>|abc def ghi</e></c>",
+ DoPreviousWord("<c><e>abc| def ghi</e></c>"));
+ EXPECT_EQ("<c><e>|abc def ghi</e></c>",
+ DoPreviousWord("<c><e>abc |def ghi</e></c>"));
+ // To "|def"
+ EXPECT_EQ("<c><e>abc |def ghi</e></c>",
+ DoPreviousWord("<c><e>abc d|ef ghi</e></c>"));
+ EXPECT_EQ("<c><e>abc |def ghi</e></c>",
+ DoPreviousWord("<c><e>abc de|f ghi</e></c>"));
+ EXPECT_EQ("<c><e>abc |def ghi</e></c>",
+ DoPreviousWord("<c><e>abc def| ghi</e></c>"));
+ EXPECT_EQ("<c><e>abc |def ghi</e></c>",
+ DoPreviousWord("<c><e>abc def |ghi</e></c>"));
+ // To "|ghi"
+ EXPECT_EQ("<c><e>abc def |ghi</e></c>",
+ DoPreviousWord("<c><e>abc def g|hi</e></c>"));
+ EXPECT_EQ("<c><e>abc def |ghi</e></c>",
+ DoPreviousWord("<c><e>abc def gh|i</e></c>"));
+ EXPECT_EQ("<c><e>abc def |ghi</e></c>",
+ DoPreviousWord("<c><e>abc def ghi|</e></c>"));
+}
+
+TEST_P(ParameterizedVisibleUnitsWordTest, PreviousWordInPositionAbsolute) {
+ InsertStyleElement(
+ "c { display: block; position: absolute; }"
+ "e { display: block; }");
+
+ // To "|abc"
+ EXPECT_EQ("<c><e>|abc def ghi</e></c>",
+ DoPreviousWord("<c><e>|abc def ghi</e></c>"));
+ EXPECT_EQ("<c><e>|abc def ghi</e></c>",
+ DoPreviousWord("<c><e>a|bc def ghi</e></c>"));
+ EXPECT_EQ("<c><e>|abc def ghi</e></c>",
+ DoPreviousWord("<c><e>ab|c def ghi</e></c>"));
+ EXPECT_EQ("<c><e>|abc def ghi</e></c>",
+ DoPreviousWord("<c><e>abc| def ghi</e></c>"));
+ EXPECT_EQ("<c><e>|abc def ghi</e></c>",
+ DoPreviousWord("<c><e>abc |def ghi</e></c>"));
+ // To "|def"
+ EXPECT_EQ("<c><e>abc |def ghi</e></c>",
+ DoPreviousWord("<c><e>abc d|ef ghi</e></c>"));
+ EXPECT_EQ("<c><e>abc |def ghi</e></c>",
+ DoPreviousWord("<c><e>abc de|f ghi</e></c>"));
+ EXPECT_EQ("<c><e>abc |def ghi</e></c>",
+ DoPreviousWord("<c><e>abc def| ghi</e></c>"));
+ EXPECT_EQ("<c><e>abc |def ghi</e></c>",
+ DoPreviousWord("<c><e>abc def |ghi</e></c>"));
+ // To "|ghi"
+ EXPECT_EQ("<c><e>abc def |ghi</e></c>",
+ DoPreviousWord("<c><e>abc def g|hi</e></c>"));
+ EXPECT_EQ("<c><e>abc def |ghi</e></c>",
+ DoPreviousWord("<c><e>abc def gh|i</e></c>"));
+ EXPECT_EQ("<c><e>abc def |ghi</e></c>",
+ DoPreviousWord("<c><e>abc def ghi|</e></c>"));
+}
+
TEST_P(ParameterizedVisibleUnitsWordTest, PreviousWordSkipTextControl) {
EXPECT_EQ("|foo<input value=\"bla\">bar",
DoPreviousWord("|foo<input value=\"bla\">bar"));
diff --git a/chromium/third_party/blink/renderer/core/editing/web_substring_util.mm b/chromium/third_party/blink/renderer/core/editing/web_substring_util.mm
index 327b82aa565..a966c7852ed 100644
--- a/chromium/third_party/blink/renderer/core/editing/web_substring_util.mm
+++ b/chromium/third_party/blink/renderer/core/editing/web_substring_util.mm
@@ -77,7 +77,8 @@ NSAttributedString* AttributedSubstringFromRange(const EphemeralRange& range,
// TODO(editing-dev): The use of updateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- range.StartPosition().GetDocument()->UpdateStyleAndLayout();
+ range.StartPosition().GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kEditing);
for (TextIterator it(range.StartPosition(), range.EndPosition());
!it.AtEnd() && [string length] < length; it.Advance()) {
@@ -138,9 +139,9 @@ NSAttributedString* AttributedSubstringFromRange(const EphemeralRange& range,
return [string autorelease];
}
-WebPoint GetBaselinePoint(LocalFrameView* frame_view,
- const EphemeralRange& range,
- NSAttributedString* string) {
+gfx::Point GetBaselinePoint(LocalFrameView* frame_view,
+ const EphemeralRange& range,
+ NSAttributedString* string) {
IntRect string_rect = frame_view->FrameToViewport(FirstRectForRange(range));
IntPoint string_point = string_rect.MinXMaxYCorner();
@@ -157,8 +158,8 @@ WebPoint GetBaselinePoint(LocalFrameView* frame_view,
NSAttributedString* WebSubstringUtil::AttributedWordAtPoint(
WebFrameWidget* frame_widget,
- WebPoint point,
- WebPoint& baseline_point) {
+ gfx::Point point,
+ gfx::Point& baseline_point) {
HitTestResult result = static_cast<WebFrameWidgetBase*>(frame_widget)
->CoreHitTestResultAt(IntPoint(point));
@@ -195,7 +196,7 @@ NSAttributedString* WebSubstringUtil::AttributedSubstringInRange(
WebLocalFrame* web_frame,
size_t location,
size_t length,
- WebPoint* baseline_point) {
+ gfx::Point* baseline_point) {
LocalFrame* frame = To<WebLocalFrameImpl>(web_frame)->GetFrame();
if (frame->View()->NeedsLayout())
frame->View()->UpdateLayout();
diff --git a/chromium/third_party/blink/renderer/core/events/after_print_event.h b/chromium/third_party/blink/renderer/core/events/after_print_event.h
index 5fad32c6555..48748f383ea 100644
--- a/chromium/third_party/blink/renderer/core/events/after_print_event.h
+++ b/chromium/third_party/blink/renderer/core/events/after_print_event.h
@@ -12,10 +12,6 @@ namespace blink {
class AfterPrintEvent final : public Event {
public:
- static AfterPrintEvent* Create() {
- return MakeGarbageCollected<AfterPrintEvent>();
- }
-
AfterPrintEvent()
: Event(event_type_names::kAfterprint, Bubbles::kNo, Cancelable::kNo) {}
~AfterPrintEvent() override = default;
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 2f7f9ad71cb..69a5caa4862 100644
--- a/chromium/third_party/blink/renderer/core/events/animation_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/animation_event.cc
@@ -25,6 +25,7 @@
#include "third_party/blink/renderer/core/events/animation_event.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_animation_event_init.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
namespace blink {
@@ -66,7 +67,7 @@ const AtomicString& AnimationEvent::InterfaceName() const {
return event_interface_names::kAnimationEvent;
}
-void AnimationEvent::Trace(blink::Visitor* visitor) {
+void AnimationEvent::Trace(Visitor* visitor) {
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 69d57ccc6b1..9189ed645cb 100644
--- a/chromium/third_party/blink/renderer/core/events/animation_event.h
+++ b/chromium/third_party/blink/renderer/core/events/animation_event.h
@@ -28,10 +28,11 @@
#include "third_party/blink/renderer/core/animation/animation_time_delta.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
-#include "third_party/blink/renderer/core/events/animation_event_init.h"
namespace blink {
+class AnimationEventInit;
+
class AnimationEvent final : public Event {
DEFINE_WRAPPERTYPEINFO();
@@ -65,7 +66,7 @@ class AnimationEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
String animation_name_;
diff --git a/chromium/third_party/blink/renderer/core/events/animation_event.idl b/chromium/third_party/blink/renderer/core/events/animation_event.idl
index b8e9c218515..e32d8e6e338 100644
--- a/chromium/third_party/blink/renderer/core/events/animation_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/animation_event.idl
@@ -26,9 +26,9 @@
// https://drafts.csswg.org/css-animations/#interface-animationevent
[
- Constructor(DOMString type, optional AnimationEventInit eventInitDict),
Exposed=Window
] interface AnimationEvent : Event {
+ constructor(DOMString type, optional AnimationEventInit eventInitDict = {});
readonly attribute DOMString animationName;
readonly attribute double elapsedTime;
readonly attribute DOMString pseudoElement;
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 56048609344..a1f113c9a25 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
@@ -4,28 +4,34 @@
#include "third_party/blink/renderer/core/events/animation_playback_event.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_animation_playback_event_init.h"
+#include "third_party/blink/renderer/core/animation/timing.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
namespace blink {
-AnimationPlaybackEvent::AnimationPlaybackEvent(const AtomicString& type,
- double current_time,
- double timeline_time)
- : Event(type, Bubbles::kNo, Cancelable::kNo) {
- if (!std::isnan(current_time))
- current_time_ = current_time;
- if (!std::isnan(timeline_time))
- timeline_time_ = timeline_time;
+AnimationPlaybackEvent::AnimationPlaybackEvent(
+ const AtomicString& type,
+ base::Optional<double> current_time,
+ base::Optional<double> timeline_time)
+ : Event(type, Bubbles::kNo, Cancelable::kNo),
+ current_time_(current_time),
+ timeline_time_(timeline_time) {
+ DCHECK(!current_time_ || !std::isnan(current_time_.value()));
+ DCHECK(!timeline_time_ || !std::isnan(timeline_time_.value()));
}
AnimationPlaybackEvent::AnimationPlaybackEvent(
const AtomicString& type,
const AnimationPlaybackEventInit* initializer)
: Event(type, initializer) {
- if (initializer->hasCurrentTime())
+ if (initializer->hasCurrentTime() && !std::isnan(initializer->currentTime()))
current_time_ = initializer->currentTime();
- if (initializer->hasTimelineTime())
+ if (initializer->hasTimelineTime() &&
+ !std::isnan(initializer->timelineTime()))
timeline_time_ = initializer->timelineTime();
+ DCHECK(!current_time_ || !std::isnan(current_time_.value()));
+ DCHECK(!timeline_time_ || !std::isnan(timeline_time_.value()));
}
AnimationPlaybackEvent::~AnimationPlaybackEvent() = default;
@@ -44,7 +50,7 @@ const AtomicString& AnimationPlaybackEvent::InterfaceName() const {
return event_interface_names::kAnimationPlaybackEvent;
}
-void AnimationPlaybackEvent::Trace(blink::Visitor* visitor) {
+void AnimationPlaybackEvent::Trace(Visitor* visitor) {
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 285c88c835f..de5a081d84b 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
@@ -7,10 +7,11 @@
#include "base/optional.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
-#include "third_party/blink/renderer/core/events/animation_playback_event_init.h"
namespace blink {
+class AnimationPlaybackEventInit;
+
class AnimationPlaybackEvent final : public Event {
DEFINE_WRAPPERTYPEINFO();
@@ -22,18 +23,21 @@ class AnimationPlaybackEvent final : public Event {
}
AnimationPlaybackEvent(const AtomicString& type,
- double current_time,
- double timeline_time);
+ base::Optional<double> current_time,
+ base::Optional<double> timeline_time);
AnimationPlaybackEvent(const AtomicString&,
const AnimationPlaybackEventInit*);
~AnimationPlaybackEvent() override;
- double currentTime(bool& is_null) const;
- double timelineTime(bool& is_null) const;
+ base::Optional<double> currentTime() const { return current_time_; }
+ base::Optional<double> timelineTime() const { return timeline_time_; }
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ double currentTime(bool& is_null) const; // DEPRECATED
+ double timelineTime(bool& is_null) const; // DEPRECATED
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
base::Optional<double> current_time_;
diff --git a/chromium/third_party/blink/renderer/core/events/animation_playback_event.idl b/chromium/third_party/blink/renderer/core/events/animation_playback_event.idl
index 7579153ec93..00e5e9168eb 100644
--- a/chromium/third_party/blink/renderer/core/events/animation_playback_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/animation_playback_event.idl
@@ -5,10 +5,10 @@
// https://drafts.csswg.org/web-animations/#the-animationplaybackevent-interface
[
- Constructor(DOMString type, optional AnimationPlaybackEventInit eventInitDict),
RuntimeEnabled=WebAnimationsAPI,
Exposed=Window
] interface AnimationPlaybackEvent : Event {
+ constructor(DOMString type, optional AnimationPlaybackEventInit eventInitDict = {});
readonly attribute double? currentTime;
readonly attribute double? timelineTime;
};
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 1bc90bf3d76..2bf16a6928a 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
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/events/application_cache_error_event.h"
#include "third_party/blink/public/mojom/appcache/appcache.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_application_cache_error_event_init.h"
#include "third_party/blink/renderer/core/event_type_names.h"
namespace blink {
@@ -56,9 +57,10 @@ ApplicationCacheErrorEvent::ApplicationCacheErrorEvent(
const AtomicString& event_type,
const ApplicationCacheErrorEventInit* initializer)
: Event(event_type, initializer), status_(0) {
+ DCHECK(RuntimeEnabledFeatures::AppCacheEnabled());
if (initializer->hasReason())
reason_ = initializer->reason();
- if (initializer->hasURL())
+ if (initializer->hasUrl())
url_ = initializer->url();
if (initializer->hasStatus())
status_ = initializer->status();
@@ -68,7 +70,7 @@ ApplicationCacheErrorEvent::ApplicationCacheErrorEvent(
ApplicationCacheErrorEvent::~ApplicationCacheErrorEvent() = default;
-void ApplicationCacheErrorEvent::Trace(blink::Visitor* visitor) {
+void ApplicationCacheErrorEvent::Trace(Visitor* visitor) {
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 1be99be242a..5ef73cb7675 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
@@ -8,11 +8,12 @@
#include "third_party/blink/public/mojom/appcache/appcache.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
-#include "third_party/blink/renderer/core/events/application_cache_error_event_init.h"
#include "third_party/blink/renderer/core/loader/appcache/application_cache_host.h"
namespace blink {
+class ApplicationCacheErrorEventInit;
+
class ApplicationCacheErrorEvent final : public Event {
DEFINE_WRAPPERTYPEINFO();
@@ -41,7 +42,7 @@ class ApplicationCacheErrorEvent final : public Event {
return event_interface_names::kApplicationCacheErrorEvent;
}
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
String reason_;
diff --git a/chromium/third_party/blink/renderer/core/events/application_cache_error_event.idl b/chromium/third_party/blink/renderer/core/events/application_cache_error_event.idl
index dfd0eb51752..c5c59b49a95 100644
--- a/chromium/third_party/blink/renderer/core/events/application_cache_error_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/application_cache_error_event.idl
@@ -9,9 +9,10 @@
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=22702
[
- Constructor(DOMString type, optional ApplicationCacheErrorEventInit eventInitDict),
+ RuntimeEnabled=AppCache,
SecureContext=RestrictAppCacheToSecureContexts
] interface ApplicationCacheErrorEvent : Event {
+ constructor(DOMString type, optional ApplicationCacheErrorEventInit eventInitDict = {});
readonly attribute DOMString reason;
readonly attribute DOMString url;
readonly attribute unsigned short status;
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 8d7166a48ad..7478354ccaf 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(blink::Visitor* visitor) {
+void BeforeTextInsertedEvent::Trace(Visitor* visitor) {
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 478b0436ac3..9adbb14e036 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 125146b4bb6..2c6feb6f2f5 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(blink::Visitor* visitor) {
+void BeforeUnloadEvent::Trace(Visitor* visitor) {
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 4d5c98ffcb3..9042923492e 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
@@ -27,6 +27,7 @@
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -59,13 +60,18 @@ class BeforeUnloadEvent final : public Event {
return true;
}
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
String return_value_;
};
-DEFINE_EVENT_TYPE_CASTS(BeforeUnloadEvent);
+template <>
+struct DowncastTraits<BeforeUnloadEvent> {
+ static bool AllowFrom(const Event& event) {
+ return event.IsBeforeUnloadEvent();
+ }
+};
} // namespace blink
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 8bd5975a084..5a78499ebd6 100644
--- a/chromium/third_party/blink/renderer/core/events/clipboard_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/clipboard_event.cc
@@ -22,6 +22,7 @@
#include "third_party/blink/renderer/core/events/clipboard_event.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_clipboard_event_init.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
namespace blink {
@@ -45,7 +46,7 @@ bool ClipboardEvent::IsClipboardEvent() const {
return true;
}
-void ClipboardEvent::Trace(blink::Visitor* visitor) {
+void ClipboardEvent::Trace(Visitor* visitor) {
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 a0f55a6099c..f213d187404 100644
--- a/chromium/third_party/blink/renderer/core/events/clipboard_event.h
+++ b/chromium/third_party/blink/renderer/core/events/clipboard_event.h
@@ -27,10 +27,11 @@
#include "third_party/blink/renderer/core/clipboard/data_transfer.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
-#include "third_party/blink/renderer/core/events/clipboard_event_init.h"
namespace blink {
+class ClipboardEventInit;
+
class ClipboardEvent final : public Event {
DEFINE_WRAPPERTYPEINFO();
@@ -51,7 +52,7 @@ class ClipboardEvent final : public Event {
DataTransfer* clipboardData() const { return clipboard_data_.Get(); }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
const AtomicString& InterfaceName() const override;
diff --git a/chromium/third_party/blink/renderer/core/events/clipboard_event.idl b/chromium/third_party/blink/renderer/core/events/clipboard_event.idl
index 34834d532cc..ec305c639f6 100644
--- a/chromium/third_party/blink/renderer/core/events/clipboard_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/clipboard_event.idl
@@ -5,8 +5,8 @@
// https://w3c.github.io/clipboard-apis/#clipboard-event-interfaces
[
- Constructor(DOMString type, optional ClipboardEventInit eventInitDict),
Exposed=Window
] interface ClipboardEvent : Event {
+ constructor(DOMString type, optional ClipboardEventInit eventInitDict = {});
readonly attribute DataTransfer? clipboardData;
};
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 69814ff5fb1..7ab4246ba5f 100644
--- a/chromium/third_party/blink/renderer/core/events/composition_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/composition_event.cc
@@ -26,6 +26,7 @@
#include "third_party/blink/renderer/core/events/composition_event.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_composition_event_init.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
#include "third_party/blink/renderer/core/input/input_device_capabilities.h"
@@ -77,7 +78,7 @@ bool CompositionEvent::IsCompositionEvent() const {
return true;
}
-void CompositionEvent::Trace(blink::Visitor* visitor) {
+void CompositionEvent::Trace(Visitor* visitor) {
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 011463af4d3..0ec3e0b93ed 100644
--- a/chromium/third_party/blink/renderer/core/events/composition_event.h
+++ b/chromium/third_party/blink/renderer/core/events/composition_event.h
@@ -27,11 +27,12 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_COMPOSITION_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_COMPOSITION_EVENT_H_
-#include "third_party/blink/renderer/core/events/composition_event_init.h"
#include "third_party/blink/renderer/core/events/ui_event.h"
namespace blink {
+class CompositionEventInit;
+
class CompositionEvent final : public UIEvent {
DEFINE_WRAPPERTYPEINFO();
@@ -62,7 +63,7 @@ class CompositionEvent final : public UIEvent {
bool IsCompositionEvent() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
String data_;
diff --git a/chromium/third_party/blink/renderer/core/events/composition_event.idl b/chromium/third_party/blink/renderer/core/events/composition_event.idl
index fd8a17947b0..3665dc1076f 100644
--- a/chromium/third_party/blink/renderer/core/events/composition_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/composition_event.idl
@@ -26,17 +26,15 @@
// https://w3c.github.io/uievents/#interface-CompositionEvent
[
- Constructor(DOMString type, optional CompositionEventInit eventInitDict),
Exposed=Window
] interface CompositionEvent : UIEvent {
+ constructor(DOMString type, optional CompositionEventInit eventInitDict = {});
readonly attribute DOMString data;
// https://w3c.github.io/uievents/#idl-interface-CompositionEvent-initializers
- // TODO(foolip): None of the initCompositionEvent() arguments should be
- // optional, and the spec has a locale argument after data.
- [Measure] void initCompositionEvent([DefaultValue=Undefined] optional DOMString type,
- [DefaultValue=Undefined] optional boolean bubbles,
- [DefaultValue=Undefined] optional boolean cancelable,
- [DefaultValue=Undefined] optional Window? view,
- [DefaultValue=Undefined] optional DOMString data);
+ [Measure] void initCompositionEvent(DOMString type,
+ optional boolean bubbles = false,
+ optional boolean cancelable = false,
+ optional Window? view = null,
+ optional DOMString data = "undefined");
};
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 fcfbeddcf3a..c3fa0a5a18e 100644
--- a/chromium/third_party/blink/renderer/core/events/drag_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/drag_event.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/events/drag_event.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_drag_event_init.h"
#include "third_party/blink/renderer/core/clipboard/data_transfer.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/events/event_dispatcher.h"
@@ -28,7 +29,7 @@ bool DragEvent::IsMouseEvent() const {
return false;
}
-void DragEvent::Trace(blink::Visitor* visitor) {
+void DragEvent::Trace(Visitor* visitor) {
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 25041f8cf89..cd002a4b3d3 100644
--- a/chromium/third_party/blink/renderer/core/events/drag_event.h
+++ b/chromium/third_party/blink/renderer/core/events/drag_event.h
@@ -6,12 +6,13 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_DRAG_EVENT_H_
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/events/drag_event_init.h"
#include "third_party/blink/renderer/core/events/mouse_event.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
class DataTransfer;
+class DragEventInit;
class CORE_EXPORT DragEvent final : public MouseEvent {
DEFINE_WRAPPERTYPEINFO();
@@ -48,13 +49,16 @@ class CORE_EXPORT DragEvent final : public MouseEvent {
DispatchEventResult DispatchEvent(EventDispatcher&) override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<DataTransfer> data_transfer_;
};
-DEFINE_EVENT_TYPE_CASTS(DragEvent);
+template <>
+struct DowncastTraits<DragEvent> {
+ static bool AllowFrom(const Event& event) { return event.IsDragEvent(); }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/events/drag_event.idl b/chromium/third_party/blink/renderer/core/events/drag_event.idl
index ba9e5838b56..e586af63220 100644
--- a/chromium/third_party/blink/renderer/core/events/drag_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/drag_event.idl
@@ -5,8 +5,8 @@
// https://html.spec.whatwg.org/C/#dragevent
[
- Exposed=Window,
- Constructor(DOMString type, optional DragEventInit eventInitDict)
+ Exposed=Window
] interface DragEvent : MouseEvent {
+ constructor(DOMString type, optional DragEventInit eventInitDict = {});
[ImplementedAs=getDataTransfer] readonly attribute DataTransfer? dataTransfer;
};
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 a1f165358b4..57d3110b656 100644
--- a/chromium/third_party/blink/renderer/core/events/error_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/error_event.cc
@@ -31,6 +31,7 @@
#include "third_party/blink/renderer/core/events/error_event.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_error_event_init.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
#include "v8/include/v8.h"
@@ -113,7 +114,7 @@ ScriptValue ErrorEvent::error(ScriptState* script_state) const {
return ScriptValue(script_state->GetIsolate(), error_.Get(script_state));
}
-void ErrorEvent::Trace(blink::Visitor* visitor) {
+void ErrorEvent::Trace(Visitor* visitor) {
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 9f0b4c01d59..7a2163ecadd 100644
--- a/chromium/third_party/blink/renderer/core/events/error_event.h
+++ b/chromium/third_party/blink/renderer/core/events/error_event.h
@@ -34,16 +34,20 @@
#include <memory>
#include "base/memory/scoped_refptr.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/world_safe_v8_reference.h"
+#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
-#include "third_party/blink/renderer/core/events/error_event_init.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
-class ErrorEvent final : public Event {
+class ErrorEventInit;
+
+class CORE_EXPORT ErrorEvent final : public Event {
DEFINE_WRAPPERTYPEINFO();
public:
@@ -102,7 +106,7 @@ class ErrorEvent final : public Event {
void SetUnsanitizedMessage(const String&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
String unsanitized_message_;
@@ -112,7 +116,10 @@ class ErrorEvent final : public Event {
scoped_refptr<DOMWrapperWorld> world_;
};
-DEFINE_EVENT_TYPE_CASTS(ErrorEvent);
+template <>
+struct DowncastTraits<ErrorEvent> {
+ static bool AllowFrom(const Event& event) { return event.IsErrorEvent(); }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/events/error_event.idl b/chromium/third_party/blink/renderer/core/events/error_event.idl
index 4ceb73c1bc8..d3e436253c4 100644
--- a/chromium/third_party/blink/renderer/core/events/error_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/error_event.idl
@@ -31,10 +31,9 @@
// https://html.spec.whatwg.org/C/#the-errorevent-interface
[
- Constructor(DOMString type, optional ErrorEventInit eventInitDict),
- ConstructorCallWith=ScriptState,
Exposed=(Window,Worker)
] interface ErrorEvent : Event {
+ [CallWith=ScriptState] constructor(DOMString type, optional ErrorEventInit eventInitDict = {});
readonly attribute DOMString message;
readonly attribute DOMString filename;
readonly attribute unsigned long lineno;
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 2b61d1c4fe1..90d76aae98d 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
@@ -31,6 +31,7 @@
"addtrack",
"advertisementreceived",
"afterprint",
+ "animationcancel",
"animationend",
"animationiteration",
"animationstart",
@@ -51,6 +52,7 @@
"beforepaste",
"beforeprint",
"beforeunload",
+ "beforexrselect",
"beginEvent",
"blocked",
"blur",
@@ -68,6 +70,7 @@
"checking",
"click",
"close",
+ "closing",
"complete",
"compositionend",
"compositionstart",
@@ -219,6 +222,7 @@
"pointerup",
"popstate",
"portalactivate",
+ "prioritychange",
"progress",
"processorerror",
"push",
@@ -229,6 +233,7 @@
"readystatechange",
"rejectionhandled",
"release",
+ "remove",
"removesourcebuffer",
"removestream",
"removetrack",
@@ -248,9 +253,9 @@
"seeking",
"select",
"selectedcandidatepairchange",
+ "selectend",
"selectionchange",
"selectstart",
- "selectend",
"shippingaddresschange",
"shippingoptionchange",
"show",
@@ -263,6 +268,9 @@
"sourceopen",
"speechend",
"speechstart",
+ "squeeze",
+ "squeezeend",
+ "squeezestart",
"stalled",
"start",
"stop",
@@ -278,6 +286,7 @@
"textformatupdate",
"timeout",
"timeupdate",
+ "timezonechange",
"toggle",
"tonechange",
"touchcancel",
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 da2ebd38125..e0c0d634786 100644
--- a/chromium/third_party/blink/renderer/core/events/focus_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/focus_event.cc
@@ -25,6 +25,7 @@
#include "third_party/blink/renderer/core/events/focus_event.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_focus_event_init.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/events/event_dispatcher.h"
#include "third_party/blink/renderer/core/dom/events/event_path.h"
@@ -65,7 +66,7 @@ FocusEvent::FocusEvent(const AtomicString& type,
related_target_ = initializer->relatedTarget();
}
-void FocusEvent::Trace(blink::Visitor* visitor) {
+void FocusEvent::Trace(Visitor* visitor) {
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 aa7c5102438..10d5e52355d 100644
--- a/chromium/third_party/blink/renderer/core/events/focus_event.h
+++ b/chromium/third_party/blink/renderer/core/events/focus_event.h
@@ -27,11 +27,13 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_FOCUS_EVENT_H_
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/events/focus_event_init.h"
#include "third_party/blink/renderer/core/events/ui_event.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
+class FocusEventInit;
+
class FocusEvent final : public UIEvent {
DEFINE_WRAPPERTYPEINFO();
@@ -72,13 +74,16 @@ class FocusEvent final : public UIEvent {
DispatchEventResult DispatchEvent(EventDispatcher&) override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<EventTarget> related_target_;
};
-DEFINE_EVENT_TYPE_CASTS(FocusEvent);
+template <>
+struct DowncastTraits<FocusEvent> {
+ static bool AllowFrom(const Event& event) { return event.IsFocusEvent(); }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/events/focus_event.idl b/chromium/third_party/blink/renderer/core/events/focus_event.idl
index 15b682cdd80..1f6c23376ad 100644
--- a/chromium/third_party/blink/renderer/core/events/focus_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/focus_event.idl
@@ -26,8 +26,8 @@
// https://w3c.github.io/uievents/#interface-FocusEvent
[
- Constructor(DOMString type, optional FocusEventInit eventInitDict),
Exposed=Window
] interface FocusEvent : UIEvent {
+ constructor(DOMString type, optional FocusEventInit eventInitDict = {});
readonly attribute EventTarget? relatedTarget;
};
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 7ee15a9418d..68516d8992d 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(blink::Visitor* visitor) {
+void GestureEvent::Trace(Visitor* visitor) {
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 0cd4fe36786..357a626e978 100644
--- a/chromium/third_party/blink/renderer/core/events/gesture_event.h
+++ b/chromium/third_party/blink/renderer/core/events/gesture_event.h
@@ -26,10 +26,11 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_GESTURE_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_GESTURE_EVENT_H_
-#include "third_party/blink/public/platform/web_gesture_event.h"
+#include "third_party/blink/public/common/input/web_gesture_event.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/events/ui_event_with_key_state.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -46,13 +47,16 @@ class CORE_EXPORT GestureEvent final : public UIEventWithKeyState {
const WebGestureEvent& NativeEvent() const { return native_event_; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
WebGestureEvent native_event_;
};
-DEFINE_EVENT_TYPE_CASTS(GestureEvent);
+template <>
+struct DowncastTraits<GestureEvent> {
+ static bool AllowFrom(const Event& event) { return event.IsGestureEvent(); }
+};
} // namespace blink
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 e6bc7d7cce9..5d31f5b93b9 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
@@ -21,9 +21,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_HASH_CHANGE_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_HASH_CHANGE_EVENT_H_
+#include "third_party/blink/renderer/bindings/core/v8/v8_hash_change_event_init.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
-#include "third_party/blink/renderer/core/events/hash_change_event_init.h"
namespace blink {
@@ -65,7 +65,7 @@ class HashChangeEvent final : public Event {
return event_interface_names::kHashChangeEvent;
}
- void Trace(blink::Visitor* visitor) override { Event::Trace(visitor); }
+ void Trace(Visitor* visitor) override { Event::Trace(visitor); }
private:
String old_url_;
diff --git a/chromium/third_party/blink/renderer/core/events/hash_change_event.idl b/chromium/third_party/blink/renderer/core/events/hash_change_event.idl
index 8e38fdb76f7..bbfd5490ade 100644
--- a/chromium/third_party/blink/renderer/core/events/hash_change_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/hash_change_event.idl
@@ -20,10 +20,10 @@
// https://html.spec.whatwg.org/C/#the-hashchangeevent-interface
[
- Constructor(DOMString type, optional HashChangeEventInit eventInitDict),
// TODO(foolip): Exposed=(Window,Worker)
Exposed=Window
] interface HashChangeEvent : Event {
+ constructor(DOMString type, optional HashChangeEventInit eventInitDict = {});
readonly attribute DOMString oldURL;
readonly attribute DOMString newURL;
};
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 40e3077d34d..484326cfd43 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(blink::Visitor* visitor) {
+void InputEvent::Trace(Visitor* visitor) {
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 e432d634354..003708a81a7 100644
--- a/chromium/third_party/blink/renderer/core/events/input_event.h
+++ b/chromium/third_party/blink/renderer/core/events/input_event.h
@@ -5,10 +5,10 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_INPUT_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_INPUT_EVENT_H_
+#include "third_party/blink/renderer/bindings/core/v8/v8_input_event_init.h"
#include "third_party/blink/renderer/core/clipboard/data_transfer.h"
#include "third_party/blink/renderer/core/dom/range.h"
#include "third_party/blink/renderer/core/dom/static_range.h"
-#include "third_party/blink/renderer/core/events/input_event_init.h"
#include "third_party/blink/renderer/core/events/ui_event.h"
namespace blink {
@@ -111,7 +111,7 @@ class InputEvent final : public UIEvent {
DispatchEventResult DispatchEvent(EventDispatcher&) override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
InputType input_type_;
diff --git a/chromium/third_party/blink/renderer/core/events/input_event.idl b/chromium/third_party/blink/renderer/core/events/input_event.idl
index 0ba6e095c12..dc356b2ca7a 100644
--- a/chromium/third_party/blink/renderer/core/events/input_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/input_event.idl
@@ -6,9 +6,9 @@
// https://w3c.github.io/uievents/#idl-inputevent
[
- Constructor(DOMString type, optional InputEventInit eventInitDict),
Exposed=Window
] interface InputEvent : UIEvent {
+ constructor(DOMString type, optional InputEventInit eventInitDict = {});
readonly attribute DOMString? data;
readonly attribute boolean isComposing;
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 d6ff51365a4..2b905985c1b 100644
--- a/chromium/third_party/blink/renderer/core/events/keyboard_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/keyboard_event.cc
@@ -23,8 +23,9 @@
#include "third_party/blink/renderer/core/events/keyboard_event.h"
#include "build/build_config.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_input_event.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_keyboard_event_init.h"
#include "third_party/blink/renderer/core/editing/ime/input_method_controller.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
@@ -218,7 +219,7 @@ void KeyboardEvent::InitLocationModifiers(unsigned location) {
}
}
-void KeyboardEvent::Trace(blink::Visitor* visitor) {
+void KeyboardEvent::Trace(Visitor* visitor) {
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 a9f2dcf8a29..402486842d2 100644
--- a/chromium/third_party/blink/renderer/core/events/keyboard_event.h
+++ b/chromium/third_party/blink/renderer/core/events/keyboard_event.h
@@ -26,13 +26,15 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_KEYBOARD_EVENT_H_
#include <memory>
-#include "third_party/blink/public/platform/web_keyboard_event.h"
+#include "third_party/blink/public/common/input/web_keyboard_event.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/events/keyboard_event_init.h"
#include "third_party/blink/renderer/core/events/ui_event_with_key_state.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
+class KeyboardEventInit;
+
class CORE_EXPORT KeyboardEvent final : public UIEventWithKeyState {
DEFINE_WRAPPERTYPEINFO();
@@ -95,7 +97,7 @@ class CORE_EXPORT KeyboardEvent final : public UIEventWithKeyState {
unsigned which() const override;
bool isComposing() const { return is_composing_; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void InitLocationModifiers(unsigned location);
@@ -109,7 +111,10 @@ class CORE_EXPORT KeyboardEvent final : public UIEventWithKeyState {
unsigned key_code_ = 0;
};
-DEFINE_EVENT_TYPE_CASTS(KeyboardEvent);
+template <>
+struct DowncastTraits<KeyboardEvent> {
+ static bool AllowFrom(const Event& event) { return event.IsKeyboardEvent(); }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/events/keyboard_event.idl b/chromium/third_party/blink/renderer/core/events/keyboard_event.idl
index a808fcb9933..6ef9b987b8b 100644
--- a/chromium/third_party/blink/renderer/core/events/keyboard_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/keyboard_event.idl
@@ -18,13 +18,12 @@
* Boston, MA 02110-1301, USA.
*/
-// https://w3c.github.io/uievents/#interface-KeyboardEvent
+// https://w3c.github.io/uievents/#interface-keyboardevent
[
- Constructor(DOMString type, optional KeyboardEventInit eventInitDict),
- ConstructorCallWith=ScriptState,
Exposed=Window
] interface KeyboardEvent : UIEvent {
+ [CallWith=ScriptState] constructor(DOMString type, optional KeyboardEventInit eventInitDict = {});
// KeyLocationCode
const unsigned long DOM_KEY_LOCATION_STANDARD = 0x00;
const unsigned long DOM_KEY_LOCATION_LEFT = 0x01;
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 9f8511d9065..9ea925f9dab 100644
--- a/chromium/third_party/blink/renderer/core/events/message_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/message_event.cc
@@ -30,6 +30,7 @@
#include <memory>
#include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_message_event_init.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
#include "third_party/blink/renderer/core/frame/user_activation.h"
#include "third_party/blink/renderer/core/html/portal/html_portal_element.h"
@@ -46,25 +47,46 @@ static inline bool IsValidSource(EventTarget* source) {
IsA<HTMLPortalElement>(source->ToNode());
}
-MessageEvent::V8GCAwareString::V8GCAwareString(const String& value)
- : string_(value) {
- const int64_t size = string_.length();
- v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(size);
+size_t MessageEvent::SizeOfExternalMemoryInBytes() {
+ switch (data_type_) {
+ case kDataTypeNull:
+ return 0;
+ case kDataTypeScriptValue:
+ // This is not external memory.
+ return 0;
+ case kDataTypeSerializedScriptValue: {
+ size_t result = 0;
+ for (auto const& array_buffer :
+ data_as_serialized_script_value_->ArrayBuffers()) {
+ result += array_buffer->ByteLengthAsSizeT();
+ }
+
+ return result;
+ }
+ case kDataTypeString:
+ return data_as_string_.length();
+ case kDataTypeBlob:
+ return static_cast<size_t>(data_as_blob_->size());
+ case kDataTypeArrayBuffer:
+ return data_as_array_buffer_->ByteLengthAsSizeT();
+ }
}
-MessageEvent::V8GCAwareString::~V8GCAwareString() {
- const int64_t size = string_.length();
- v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-size);
+void MessageEvent::RegisterAmountOfExternallyAllocatedMemory() {
+ CHECK_EQ(amount_of_external_memory_, 0u);
+ size_t size = SizeOfExternalMemoryInBytes();
+
+ v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
+ static_cast<int64_t>(size));
+ amount_of_external_memory_ = size;
}
-MessageEvent::V8GCAwareString& MessageEvent::V8GCAwareString::operator=(
- const String& other) {
- const int64_t old_size = string_.length();
- const int64_t new_size = other.length();
- string_ = other;
- v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(new_size -
- old_size);
- return *this;
+void MessageEvent::UnregisterAmountOfExternallyAllocatedMemory() {
+ if (amount_of_external_memory_ > 0) {
+ v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
+ -static_cast<int64_t>(amount_of_external_memory_));
+ amount_of_external_memory_ = 0;
+ }
}
MessageEvent::MessageEvent() : data_type_(kDataTypeScriptValue) {}
@@ -120,6 +142,7 @@ MessageEvent::MessageEvent(scoped_refptr<SerializedScriptValue> data,
ports_(ports),
user_activation_(user_activation) {
DCHECK(IsValidSource(source_.Get()));
+ RegisterAmountOfExternallyAllocatedMemory();
}
MessageEvent::MessageEvent(scoped_refptr<SerializedScriptValue> data,
@@ -142,6 +165,7 @@ MessageEvent::MessageEvent(scoped_refptr<SerializedScriptValue> data,
transfer_user_activation_(transfer_user_activation),
allow_autoplay_(allow_autoplay) {
DCHECK(IsValidSource(source_.Get()));
+ RegisterAmountOfExternallyAllocatedMemory();
}
MessageEvent::MessageEvent(const String& origin, EventTarget* source)
@@ -156,21 +180,29 @@ MessageEvent::MessageEvent(const String& data, const String& origin)
: Event(event_type_names::kMessage, Bubbles::kNo, Cancelable::kNo),
data_type_(kDataTypeString),
data_as_string_(data),
- origin_(origin) {}
+ origin_(origin) {
+ RegisterAmountOfExternallyAllocatedMemory();
+}
MessageEvent::MessageEvent(Blob* data, const String& origin)
: Event(event_type_names::kMessage, Bubbles::kNo, Cancelable::kNo),
data_type_(kDataTypeBlob),
data_as_blob_(data),
- origin_(origin) {}
+ origin_(origin) {
+ RegisterAmountOfExternallyAllocatedMemory();
+}
MessageEvent::MessageEvent(DOMArrayBuffer* data, const String& origin)
: Event(event_type_names::kMessage, Bubbles::kNo, Cancelable::kNo),
data_type_(kDataTypeArrayBuffer),
data_as_array_buffer_(data),
- origin_(origin) {}
+ origin_(origin) {
+ RegisterAmountOfExternallyAllocatedMemory();
+}
-MessageEvent::~MessageEvent() = default;
+MessageEvent::~MessageEvent() {
+ UnregisterAmountOfExternallyAllocatedMemory();
+}
MessageEvent* MessageEvent::Create(const AtomicString& type,
const MessageEventInit* initializer,
@@ -239,6 +271,7 @@ void MessageEvent::initMessageEvent(const AtomicString& type,
user_activation_ = user_activation;
transfer_user_activation_ = transfer_user_activation;
allow_autoplay_ = allow_autoplay;
+ RegisterAmountOfExternallyAllocatedMemory();
}
void MessageEvent::initMessageEvent(const AtomicString& type,
@@ -262,6 +295,7 @@ void MessageEvent::initMessageEvent(const AtomicString& type,
source_ = source;
ports_ = ports;
is_ports_dirty_ = true;
+ RegisterAmountOfExternallyAllocatedMemory();
}
ScriptValue MessageEvent::data(ScriptState* script_state) {
@@ -283,6 +317,10 @@ ScriptValue MessageEvent::data(ScriptState* script_state) {
case MessageEvent::kDataTypeSerializedScriptValue:
if (data_as_serialized_script_value_) {
+ // The data is put on the V8 GC heap here, and therefore the V8 GC does
+ // the accounting from here on. We unregister the registered memory to
+ // avoid double accounting.
+ UnregisterAmountOfExternallyAllocatedMemory();
MessagePortArray message_ports = ports();
SerializedScriptValue::DeserializeOptions options;
options.message_ports = &message_ports;
@@ -293,7 +331,7 @@ ScriptValue MessageEvent::data(ScriptState* script_state) {
break;
case MessageEvent::kDataTypeString:
- value = V8String(isolate, data_as_string_.data());
+ value = V8String(isolate, data_as_string_);
break;
case MessageEvent::kDataTypeBlob:
@@ -329,6 +367,8 @@ bool MessageEvent::IsOriginCheckRequiredToAccessData() const {
}
bool MessageEvent::IsLockedToAgentCluster() const {
+ if (locked_to_agent_cluster_)
+ return true;
if (data_type_ != kDataTypeSerializedScriptValue) {
return false;
}
@@ -340,7 +380,7 @@ void MessageEvent::EntangleMessagePorts(ExecutionContext* context) {
is_ports_dirty_ = true;
}
-void MessageEvent::Trace(blink::Visitor* visitor) {
+void MessageEvent::Trace(Visitor* visitor) {
visitor->Trace(data_as_v8_value_);
visitor->Trace(data_as_serialized_script_value_);
visitor->Trace(data_as_blob_);
@@ -351,6 +391,10 @@ void MessageEvent::Trace(blink::Visitor* visitor) {
Event::Trace(visitor);
}
+void MessageEvent::LockToAgentCluster() {
+ locked_to_agent_cluster_ = true;
+}
+
v8::Local<v8::Object> MessageEvent::AssociateWithWrapper(
v8::Isolate* isolate,
const WrapperTypeInfo* wrapper_type,
@@ -369,7 +413,7 @@ v8::Local<v8::Object> MessageEvent::AssociateWithWrapper(
case kDataTypeString:
V8PrivateProperty::GetSymbol(isolate,
kPrivatePropertyMessageEventCachedData)
- .Set(wrapper, V8String(isolate, data_as_string_.data()));
+ .Set(wrapper, V8String(isolate, data_as_string_));
break;
case kDataTypeBlob:
break;
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 609e382c152..f8310326df6 100644
--- a/chromium/third_party/blink/renderer/core/events/message_event.h
+++ b/chromium/third_party/blink/renderer/core/events/message_event.h
@@ -37,7 +37,6 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/events/message_event_init.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
#include "third_party/blink/renderer/core/messaging/message_port.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
@@ -46,6 +45,7 @@
namespace blink {
+class MessageEventInit;
class UserActivation;
class CORE_EXPORT MessageEvent final : public Event {
@@ -193,7 +193,9 @@ class CORE_EXPORT MessageEvent final : public Event {
void EntangleMessagePorts(ExecutionContext*);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
+
+ void LockToAgentCluster();
WARN_UNUSED_RESULT v8::Local<v8::Object> AssociateWithWrapper(
v8::Isolate*,
@@ -210,27 +212,16 @@ class CORE_EXPORT MessageEvent final : public Event {
kDataTypeArrayBuffer
};
- class V8GCAwareString final {
- DISALLOW_NEW();
-
- public:
- V8GCAwareString() = default;
- V8GCAwareString(const String&);
-
- ~V8GCAwareString();
+ size_t SizeOfExternalMemoryInBytes();
- V8GCAwareString& operator=(const String&);
+ void RegisterAmountOfExternallyAllocatedMemory();
- const String& data() const { return string_; }
-
- private:
- String string_;
- };
+ void UnregisterAmountOfExternallyAllocatedMemory();
DataType data_type_;
WorldSafeV8Reference<v8::Value> data_as_v8_value_;
Member<UnpackedSerializedScriptValue> data_as_serialized_script_value_;
- V8GCAwareString data_as_string_;
+ String data_as_string_;
Member<Blob> data_as_blob_;
Member<DOMArrayBuffer> data_as_array_buffer_;
bool is_data_dirty_ = true;
@@ -246,11 +237,13 @@ class CORE_EXPORT MessageEvent final : public Event {
Member<UserActivation> user_activation_;
bool transfer_user_activation_ = false;
bool allow_autoplay_ = false;
+ size_t amount_of_external_memory_ = 0;
+ // For serialized messages across process this attribute contains the
+ // information of whether the actual original SerializedScriptValue was locked
+ // to the agent cluster.
+ bool locked_to_agent_cluster_ = false;
};
-extern CORE_EXPORT const V8PrivateProperty::SymbolKey
- kPrivatePropertyMessageEventCachedData;
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_MESSAGE_EVENT_H_
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 5252a7099d8..c325dfb22ee 100644
--- a/chromium/third_party/blink/renderer/core/events/message_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/message_event.idl
@@ -28,10 +28,9 @@
// https://html.spec.whatwg.org/C/#the-messageevent-interface
[
- Constructor(DOMString type, optional MessageEventInit eventInitDict),
- Exposed=(Window,Worker,AudioWorklet),
- RaisesException=Constructor
+ Exposed=(Window,Worker,AudioWorklet)
] interface MessageEvent : Event {
+ [RaisesException] constructor(DOMString type, optional MessageEventInit eventInitDict = {});
[CachedAttribute=IsDataDirty, CallWith=ScriptState] readonly attribute any data;
readonly attribute DOMString origin;
readonly attribute DOMString lastEventId;
diff --git a/chromium/third_party/blink/renderer/core/events/message_event_test.cc b/chromium/third_party/blink/renderer/core/events/message_event_test.cc
new file mode 100644
index 00000000000..95e292f2631
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/events/message_event_test.cc
@@ -0,0 +1,105 @@
+// 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/events/message_event.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_source_code.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_testing.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+class MessageEventTest : public testing::Test {};
+
+TEST_F(MessageEventTest, AccountForStringMemory) {
+ constexpr int64_t string_size = 10000;
+ V8TestingScope scope;
+
+ scope.GetIsolate()->Enter();
+
+ // We are only interested in a string of size |string_size|. The content is
+ // irrelevant.
+ UChar* tmp;
+ WTF::String data =
+ WTF::String::CreateUninitialized(static_cast<unsigned>(string_size), tmp);
+
+ // We read the |AmountOfExternalAllocatedMemory| before and after allocating
+ // the |MessageEvent|. The difference has to be at least the string size.
+ // Afterwards we trigger a blocking GC to deallocated the |MessageEvent|
+ // again. After that the |AmountOfExternalAllocatedMemory| should be reduced
+ // by at least the string size again.
+ int64_t initial =
+ scope.GetIsolate()->AdjustAmountOfExternalAllocatedMemory(0);
+ MessageEvent::Create(data);
+
+ int64_t size_with_event =
+ scope.GetIsolate()->AdjustAmountOfExternalAllocatedMemory(0);
+ ASSERT_LE(initial + string_size, size_with_event);
+
+ ThreadState::Current()->CollectGarbage(
+ BlinkGC::CollectionType::kMajor, BlinkGC::kNoHeapPointersOnStack,
+ BlinkGC::kAtomicMarking, BlinkGC::kEagerSweeping,
+ BlinkGC::GCReason::kForcedGCForTesting);
+
+ int64_t size_after_gc =
+ scope.GetIsolate()->AdjustAmountOfExternalAllocatedMemory(0);
+ ASSERT_LE(size_after_gc + string_size, size_with_event);
+
+ scope.GetIsolate()->Exit();
+}
+
+TEST_F(MessageEventTest, AccountForArrayBufferMemory) {
+ constexpr int64_t buffer_size = 10000;
+ V8TestingScope scope;
+
+ scope.GetIsolate()->Enter();
+
+ scoped_refptr<SerializedScriptValue> serialized_script_value;
+ {
+ DOMArrayBuffer* array_buffer =
+ DOMArrayBuffer::Create(static_cast<size_t>(buffer_size), 1);
+ v8::Local<v8::Value> object = v8::Number::New(scope.GetIsolate(), 13);
+ Transferables transferables;
+ transferables.array_buffers.push_back(array_buffer);
+ ScriptState* script_state = scope.GetScriptState();
+ ExceptionState& exception_state = scope.GetExceptionState();
+
+ V8ScriptValueSerializer::Options serialize_options;
+ serialize_options.transferables = &transferables;
+ V8ScriptValueSerializer serializer(script_state, serialize_options);
+ serialized_script_value = serializer.Serialize(object, exception_state);
+ }
+ // We read the |AmountOfExternalAllocatedMemory| before and after allocating
+ // the |MessageEvent|. The difference has to be at least the buffer size.
+ // Afterwards we trigger a blocking GC to deallocated the |MessageEvent|
+ // again. After that the |AmountOfExternalAllocatedMemory| should be reduced
+ // by at least the buffer size again.
+ int64_t initial =
+ scope.GetIsolate()->AdjustAmountOfExternalAllocatedMemory(0);
+
+ MessagePortArray* ports = MakeGarbageCollected<MessagePortArray>(0);
+ MessageEvent::Create(ports, serialized_script_value);
+
+ int64_t size_with_event =
+ scope.GetIsolate()->AdjustAmountOfExternalAllocatedMemory(0);
+ ASSERT_LE(initial + buffer_size, size_with_event);
+
+ ThreadState::Current()->CollectGarbage(
+ BlinkGC::CollectionType::kMajor, BlinkGC::kNoHeapPointersOnStack,
+ BlinkGC::kAtomicMarking, BlinkGC::kEagerSweeping,
+ BlinkGC::GCReason::kForcedGCForTesting);
+
+ int64_t size_after_gc =
+ scope.GetIsolate()->AdjustAmountOfExternalAllocatedMemory(0);
+ ASSERT_LE(size_after_gc + buffer_size, size_with_event);
+
+ scope.GetIsolate()->Exit();
+}
+} // namespace blink
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 8c695e377b7..22d238ff173 100644
--- a/chromium/third_party/blink/renderer/core/events/mouse_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/mouse_event.cc
@@ -22,7 +22,8 @@
#include "third_party/blink/renderer/core/events/mouse_event.h"
-#include "third_party/blink/public/platform/web_pointer_properties.h"
+#include "third_party/blink/public/common/input/web_pointer_properties.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mouse_event_init.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/dom/events/event_path.h"
@@ -129,19 +130,18 @@ MouseEvent* MouseEvent::Create(const AtomicString& event_type,
MouseEvent* MouseEvent::Create(const AtomicString& event_type,
AbstractView* view,
- Event* underlying_event,
+ const Event* underlying_event,
SimulatedClickCreationScope creation_scope) {
WebInputEvent::Modifiers modifiers = WebInputEvent::kNoModifiers;
- if (UIEventWithKeyState* key_state_event =
+ if (const UIEventWithKeyState* key_state_event =
FindEventWithKeyState(underlying_event)) {
modifiers = key_state_event->GetModifiers();
}
SyntheticEventType synthetic_type = kPositionless;
MouseEventInit* initializer = MouseEventInit::Create();
- if (underlying_event && underlying_event->IsMouseEvent()) {
+ if (const auto* mouse_event = DynamicTo<MouseEvent>(underlying_event)) {
synthetic_type = kRealOrIndistinguishable;
- MouseEvent* mouse_event = ToMouseEvent(underlying_event);
initializer->setScreenX(mouse_event->screenX());
initializer->setScreenY(mouse_event->screenY());
initializer->setSourceCapabilities(
@@ -167,7 +167,7 @@ MouseEvent* MouseEvent::Create(const AtomicString& event_type,
SimulatedClickCreationScope::kFromUserAgent);
created_event->SetUnderlyingEvent(underlying_event);
if (synthetic_type == kRealOrIndistinguishable) {
- MouseEvent* mouse_event = ToMouseEvent(created_event->UnderlyingEvent());
+ auto* mouse_event = To<MouseEvent>(created_event->UnderlyingEvent());
created_event->InitCoordinates(mouse_event->clientX(),
mouse_event->clientY());
}
@@ -223,11 +223,11 @@ void MouseEvent::SetCoordinatesFromWebPointerProperties(
const LocalDOMWindow* dom_window,
MouseEventInit* initializer) {
FloatPoint client_point;
- FloatPoint screen_point = web_pointer_properties.PositionInScreen();
+ FloatPoint screen_point(web_pointer_properties.PositionInScreen());
float scale_factor = 1.0f;
if (dom_window && dom_window->GetFrame() && dom_window->GetFrame()->View()) {
LocalFrame* frame = dom_window->GetFrame();
- FloatPoint root_frame_point = web_pointer_properties.PositionInWidget();
+ FloatPoint root_frame_point(web_pointer_properties.PositionInWidget());
if (Page* p = frame->GetPage()) {
if (p->GetPointerLockController().GetElement() &&
!p->GetPointerLockController().LockPending()) {
@@ -388,7 +388,7 @@ Node* MouseEvent::fromElement() const {
return target() ? target()->ToNode() : nullptr;
}
-void MouseEvent::Trace(blink::Visitor* visitor) {
+void MouseEvent::Trace(Visitor* visitor) {
visitor->Trace(related_target_);
UIEventWithKeyState::Trace(visitor);
}
@@ -484,7 +484,7 @@ void MouseEvent::ComputeRelativePosition() {
float inverse_zoom_factor = 1 / PageZoomFactor(this);
// Must have an updated layout tree for this math to work correctly.
- target_node->GetDocument().UpdateStyleAndLayout();
+ target_node->GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kInput);
// Adjust offsetLocation to be relative to the target's padding box.
if (const LayoutObject* layout_object = FindTargetLayoutObject(target_node)) {
@@ -555,24 +555,20 @@ int MouseEvent::layerY() {
: static_cast<int>(layer_location_.Y());
}
-double MouseEvent::offsetX() {
+double MouseEvent::offsetX() const {
if (!HasPosition())
return 0;
if (!has_cached_relative_position_)
- ComputeRelativePosition();
- return (RuntimeEnabledFeatures::FractionalMouseEventEnabled())
- ? offset_location_.X()
- : std::round(offset_location_.X());
+ const_cast<MouseEvent*>(this)->ComputeRelativePosition();
+ return std::round(offset_location_.X());
}
-double MouseEvent::offsetY() {
+double MouseEvent::offsetY() const {
if (!HasPosition())
return 0;
if (!has_cached_relative_position_)
- ComputeRelativePosition();
- return (RuntimeEnabledFeatures::FractionalMouseEventEnabled())
- ? offset_location_.Y()
- : std::round(offset_location_.Y());
+ const_cast<MouseEvent*>(this)->ComputeRelativePosition();
+ return std::round(offset_location_.Y());
}
} // namespace blink
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 83aa0014700..f9e084b3378 100644
--- a/chromium/third_party/blink/renderer/core/events/mouse_event.h
+++ b/chromium/third_party/blink/renderer/core/events/mouse_event.h
@@ -24,17 +24,19 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_MOUSE_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_MOUSE_EVENT_H_
-#include "third_party/blink/public/platform/web_menu_source_type.h"
+#include "third_party/blink/public/common/input/web_menu_source_type.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/events/simulated_click_options.h"
-#include "third_party/blink/renderer/core/events/mouse_event_init.h"
#include "third_party/blink/renderer/core/events/ui_event_with_key_state.h"
#include "third_party/blink/renderer/platform/geometry/double_point.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
+
class DataTransfer;
class EventDispatcher;
+class MouseEventInit;
class CORE_EXPORT MouseEvent : public UIEventWithKeyState {
DEFINE_WRAPPERTYPEINFO();
@@ -65,7 +67,7 @@ class CORE_EXPORT MouseEvent : public UIEventWithKeyState {
static MouseEvent* Create(const AtomicString& event_type,
AbstractView*,
- Event* underlying_event,
+ const Event* underlying_event,
SimulatedClickCreationScope);
MouseEvent(const AtomicString& type,
@@ -141,27 +143,19 @@ class CORE_EXPORT MouseEvent : public UIEventWithKeyState {
// Note that these values are adjusted to counter the effects of zoom, so that
// values exposed via DOM APIs are invariant under zooming.
virtual double screenX() const {
- return (RuntimeEnabledFeatures::FractionalMouseEventEnabled())
- ? screen_location_.X()
- : static_cast<int>(screen_location_.X());
+ return static_cast<int>(screen_location_.X());
}
virtual double screenY() const {
- return (RuntimeEnabledFeatures::FractionalMouseEventEnabled())
- ? screen_location_.Y()
- : static_cast<int>(screen_location_.Y());
+ return static_cast<int>(screen_location_.Y());
}
virtual double clientX() const {
- return (RuntimeEnabledFeatures::FractionalMouseEventEnabled())
- ? client_location_.X()
- : static_cast<int>(client_location_.X());
+ return static_cast<int>(client_location_.X());
}
virtual double clientY() const {
- return (RuntimeEnabledFeatures::FractionalMouseEventEnabled())
- ? client_location_.Y()
- : static_cast<int>(client_location_.Y());
+ return static_cast<int>(client_location_.Y());
}
int movementX() const { return movement_delta_.X(); }
@@ -170,20 +164,12 @@ class CORE_EXPORT MouseEvent : public UIEventWithKeyState {
int layerX();
int layerY();
- virtual double offsetX();
- virtual double offsetY();
+ virtual double offsetX() const;
+ virtual double offsetY() const;
- virtual double pageX() const {
- return (RuntimeEnabledFeatures::FractionalMouseEventEnabled())
- ? page_location_.X()
- : static_cast<int>(page_location_.X());
- }
+ virtual double pageX() const { return static_cast<int>(page_location_.X()); }
- virtual double pageY() const {
- return (RuntimeEnabledFeatures::FractionalMouseEventEnabled())
- ? page_location_.Y()
- : static_cast<int>(page_location_.Y());
- }
+ virtual double pageY() const { return static_cast<int>(page_location_.Y()); }
double x() const { return clientX(); }
double y() const { return clientY(); }
@@ -199,22 +185,20 @@ class CORE_EXPORT MouseEvent : public UIEventWithKeyState {
DispatchEventResult DispatchEvent(EventDispatcher&) override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
+
+ DoublePoint screen_location_;
+ DoublePoint client_location_;
+ DoublePoint page_location_; // zoomed CSS pixels
+ DoublePoint offset_location_; // zoomed CSS pixels
protected:
int16_t RawButton() const { return button_; }
void ReceivedTarget() override;
- // TODO(eirage): Move these coordinates related field back to private
- // when MouseEvent fractional flag is removed.
void ComputeRelativePosition();
- DoublePoint screen_location_;
- DoublePoint client_location_;
- DoublePoint page_location_; // zoomed CSS pixels
- DoublePoint offset_location_; // zoomed CSS pixels
-
bool has_cached_relative_position_ = false;
private:
@@ -252,7 +236,10 @@ class CORE_EXPORT MouseEvent : public UIEventWithKeyState {
WebMenuSourceType menu_source_type_;
};
-DEFINE_EVENT_TYPE_CASTS(MouseEvent);
+template <>
+struct DowncastTraits<MouseEvent> {
+ static bool AllowFrom(const Event& event) { return event.IsMouseEvent(); }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/events/mouse_event.idl b/chromium/third_party/blink/renderer/core/events/mouse_event.idl
index 75e6baf4c80..8ba6df58fe0 100644
--- a/chromium/third_party/blink/renderer/core/events/mouse_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/mouse_event.idl
@@ -20,10 +20,9 @@
// https://w3c.github.io/uievents/#interface-MouseEvent
[
- Constructor(DOMString type, optional MouseEventInit eventInitDict),
- ConstructorCallWith=ScriptState,
Exposed=Window
] interface MouseEvent : UIEvent {
+ [CallWith=ScriptState] constructor(DOMString type, optional MouseEventInit eventInitDict = {});
[HighEntropy, MeasureAs=MouseEventScreenX] readonly attribute double screenX;
[HighEntropy, MeasureAs=MouseEventScreenY] readonly attribute double screenY;
readonly attribute double clientX;
@@ -38,22 +37,21 @@
boolean getModifierState(DOMString keyArg);
// https://w3c.github.io/uievents/#idl-interface-MouseEvent-initializers
- // TODO(foolip): None of the initMouseEvent() arguments should be optional.
- [CallWith=ScriptState, Measure] void initMouseEvent([DefaultValue=Undefined] optional DOMString type,
- [DefaultValue=Undefined] optional boolean bubbles,
- [DefaultValue=Undefined] optional boolean cancelable,
- [DefaultValue=Undefined] optional Window? view,
- [DefaultValue=Undefined] optional long detail,
- [DefaultValue=Undefined] optional long screenX,
- [DefaultValue=Undefined] optional long screenY,
- [DefaultValue=Undefined] optional long clientX,
- [DefaultValue=Undefined] optional long clientY,
- [DefaultValue=Undefined] optional boolean ctrlKey,
- [DefaultValue=Undefined] optional boolean altKey,
- [DefaultValue=Undefined] optional boolean shiftKey,
- [DefaultValue=Undefined] optional boolean metaKey,
- [DefaultValue=Undefined] optional unsigned short button,
- [DefaultValue=Undefined] optional EventTarget? relatedTarget);
+ [CallWith=ScriptState, Measure] void initMouseEvent(DOMString type,
+ optional boolean bubbles = false,
+ optional boolean cancelable = false,
+ optional Window? view = null,
+ optional long detail = 0,
+ optional long screenX = 0,
+ optional long screenY = 0,
+ optional long clientX = 0,
+ optional long clientY = 0,
+ optional boolean ctrlKey = false,
+ optional boolean altKey = false,
+ optional boolean shiftKey = false,
+ optional boolean metaKey = false,
+ optional unsigned short button = 0,
+ optional EventTarget? relatedTarget = null);
readonly attribute double pageX;
readonly attribute double pageY;
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 e56e8a36af4..bd20b674660 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(blink::Visitor* visitor) {
+void MutationEvent::Trace(Visitor* visitor) {
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 0a6d0477935..9e46d5f6f93 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<Node> related_node_;
diff --git a/chromium/third_party/blink/renderer/core/events/mutation_event.idl b/chromium/third_party/blink/renderer/core/events/mutation_event.idl
index 562049599e0..0c34b81c77c 100644
--- a/chromium/third_party/blink/renderer/core/events/mutation_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/mutation_event.idl
@@ -31,12 +31,12 @@ interface MutationEvent : Event {
readonly attribute DOMString attrName;
readonly attribute unsigned short attrChange;
// TODO(foolip): None of the initMutationEvent() arguments should be optional.
- [Measure] void initMutationEvent([DefaultValue=Undefined] optional DOMString type,
- [DefaultValue=Undefined] optional boolean bubbles,
- [DefaultValue=Undefined] optional boolean cancelable,
- [DefaultValue=Undefined] optional Node? relatedNode,
- [DefaultValue=Undefined] optional DOMString prevValue,
- [DefaultValue=Undefined] optional DOMString newValue,
- [DefaultValue=Undefined] optional DOMString attrName,
- [DefaultValue=Undefined] optional unsigned short attrChange);
+ [Measure] void initMutationEvent(optional DOMString type = "undefined",
+ optional boolean bubbles = false,
+ optional boolean cancelable = false,
+ optional Node? relatedNode = null,
+ optional DOMString prevValue = "undefined",
+ optional DOMString newValue = "undefined",
+ optional DOMString attrName = "undefined",
+ optional unsigned short attrChange = 0);
};
diff --git a/chromium/third_party/blink/renderer/core/events/navigator_events.h b/chromium/third_party/blink/renderer/core/events/navigator_events.h
index feb55ed88bd..a78ff2589aa 100644
--- a/chromium/third_party/blink/renderer/core/events/navigator_events.h
+++ b/chromium/third_party/blink/renderer/core/events/navigator_events.h
@@ -31,13 +31,14 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_NAVIGATOR_EVENTS_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_NAVIGATOR_EVENTS_H_
+#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
namespace blink {
class Navigator;
-class NavigatorEvents {
+class CORE_EXPORT NavigatorEvents {
STATIC_ONLY(NavigatorEvents);
public:
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 41ece7756c0..dbfe9d301ca 100644
--- a/chromium/third_party/blink/renderer/core/events/overscroll_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/overscroll_event.cc
@@ -4,7 +4,10 @@
#include "third_party/blink/renderer/core/events/overscroll_event.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_overscroll_event_init.h"
+
namespace blink {
+
OverscrollEvent::OverscrollEvent(const AtomicString& type,
bool bubbles,
double delta_x,
@@ -20,7 +23,7 @@ OverscrollEvent::OverscrollEvent(const AtomicString& type,
delta_x_(initializer->deltaX()),
delta_y_(initializer->deltaY()) {}
-void OverscrollEvent::Trace(blink::Visitor* visitor) {
+void OverscrollEvent::Trace(Visitor* visitor) {
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 7b7e2b1a7e6..0db38ffbc7e 100644
--- a/chromium/third_party/blink/renderer/core/events/overscroll_event.h
+++ b/chromium/third_party/blink/renderer/core/events/overscroll_event.h
@@ -6,10 +6,11 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_OVERSCROLL_EVENT_H_
#include "third_party/blink/renderer/core/dom/events/event.h"
-#include "third_party/blink/renderer/core/events/overscroll_event_init.h"
namespace blink {
+class OverscrollEventInit;
+
class OverscrollEvent final : public Event {
DEFINE_WRAPPERTYPEINFO();
@@ -38,7 +39,7 @@ class OverscrollEvent final : public Event {
double deltaX() const { return delta_x_; }
double deltaY() const { return delta_y_; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
double delta_x_ = 0;
diff --git a/chromium/third_party/blink/renderer/core/events/overscroll_event.idl b/chromium/third_party/blink/renderer/core/events/overscroll_event.idl
index 6d67d990a4a..909255e1b3a 100644
--- a/chromium/third_party/blink/renderer/core/events/overscroll_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/overscroll_event.idl
@@ -5,9 +5,9 @@
// TODO(sahel): Add link to w3c. https://crbugs.com/907601
[
- Constructor(DOMString type, boolean bubbles, optional OverscrollEventInit eventInitDict),
RuntimeEnabled=OverscrollCustomization
] interface OverscrollEvent : Event {
+ constructor(DOMString type, boolean bubbles, optional OverscrollEventInit eventInitDict = {});
readonly attribute double deltaX;
readonly attribute double deltaY;
};
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 d96e160b1ef..038365fd079 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
@@ -25,6 +25,7 @@
#include "third_party/blink/renderer/core/events/page_transition_event.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_page_transition_event_init.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
namespace blink {
@@ -56,7 +57,7 @@ const AtomicString& PageTransitionEvent::InterfaceName() const {
return event_interface_names::kPageTransitionEvent;
}
-void PageTransitionEvent::Trace(blink::Visitor* visitor) {
+void PageTransitionEvent::Trace(Visitor* visitor) {
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 da175f11145..d899c9cffdd 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
@@ -28,10 +28,11 @@
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/event_type_names.h"
-#include "third_party/blink/renderer/core/events/page_transition_event_init.h"
namespace blink {
+class PageTransitionEventInit;
+
class PageTransitionEvent final : public Event {
DEFINE_WRAPPERTYPEINFO();
@@ -66,7 +67,7 @@ class PageTransitionEvent final : public Event {
bool persisted() const { return persisted_; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
// TODO(rakina): change to PageTransitionEventPersistence.
diff --git a/chromium/third_party/blink/renderer/core/events/page_transition_event.idl b/chromium/third_party/blink/renderer/core/events/page_transition_event.idl
index 9e85111400b..977ba8c561f 100644
--- a/chromium/third_party/blink/renderer/core/events/page_transition_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/page_transition_event.idl
@@ -26,9 +26,9 @@
// https://html.spec.whatwg.org/C/#the-pagetransitionevent-interface
[
- Constructor(DOMString type, optional PageTransitionEventInit eventInitDict),
// TODO(foolip): Exposed=(Window,Worker)
Exposed=Window
] interface PageTransitionEvent : Event {
+ constructor(DOMString type, optional PageTransitionEventInit eventInitDict = {});
readonly attribute boolean persisted;
};
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 9a44299252a..892bbc4bcfb 100644
--- a/chromium/third_party/blink/renderer/core/events/pointer_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/pointer_event.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/events/pointer_event.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_pointer_event_init.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/dom/events/event_path.h"
@@ -76,19 +77,19 @@ bool PointerEvent::IsPointerEvent() const {
return true;
}
-double PointerEvent::offsetX() {
+double PointerEvent::offsetX() const {
if (!HasPosition())
return 0;
if (!has_cached_relative_position_)
- ComputeRelativePosition();
+ const_cast<PointerEvent*>(this)->ComputeRelativePosition();
return offset_location_.X();
}
-double PointerEvent::offsetY() {
+double PointerEvent::offsetY() const {
if (!HasPosition())
return 0;
if (!has_cached_relative_position_)
- ComputeRelativePosition();
+ const_cast<PointerEvent*>(this)->ComputeRelativePosition();
return offset_location_.Y();
}
@@ -132,7 +133,7 @@ base::TimeTicks PointerEvent::OldestPlatformTimeStamp() const {
return this->PlatformTimeStamp();
}
-void PointerEvent::Trace(blink::Visitor* visitor) {
+void PointerEvent::Trace(Visitor* visitor) {
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 b8b7bfe1f87..c9e2c5f6e00 100644
--- a/chromium/third_party/blink/renderer/core/events/pointer_event.h
+++ b/chromium/third_party/blink/renderer/core/events/pointer_event.h
@@ -6,10 +6,12 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_POINTER_EVENT_H_
#include "third_party/blink/renderer/core/events/mouse_event.h"
-#include "third_party/blink/renderer/core/events/pointer_event_init.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
+class PointerEventInit;
+
class CORE_EXPORT PointerEvent final : public MouseEvent {
DEFINE_WRAPPERTYPEINFO();
@@ -58,8 +60,8 @@ class CORE_EXPORT PointerEvent final : public MouseEvent {
double pageX() const override { return page_location_.X(); }
double pageY() const override { return page_location_.Y(); }
- double offsetX() override;
- double offsetY() override;
+ double offsetX() const override;
+ double offsetY() const override;
void ReceivedTarget() override;
@@ -74,7 +76,7 @@ class CORE_EXPORT PointerEvent final : public MouseEvent {
DispatchEventResult DispatchEvent(EventDispatcher&) override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
PointerId pointer_id_;
@@ -96,7 +98,10 @@ class CORE_EXPORT PointerEvent final : public MouseEvent {
HeapVector<Member<PointerEvent>> predicted_events_;
};
-DEFINE_EVENT_TYPE_CASTS(PointerEvent);
+template <>
+struct DowncastTraits<PointerEvent> {
+ static bool AllowFrom(const Event& event) { return event.IsPointerEvent(); }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/events/pointer_event.idl b/chromium/third_party/blink/renderer/core/events/pointer_event.idl
index 1f39eec4f0f..fc1bddad1a5 100644
--- a/chromium/third_party/blink/renderer/core/events/pointer_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/pointer_event.idl
@@ -5,9 +5,9 @@
// https://w3c.github.io/pointerevents/#pointerevent-interface
[
- Constructor(DOMString type, optional PointerEventInit eventInitDict),
Exposed=Window
] interface PointerEvent : MouseEvent {
+ constructor(DOMString type, optional PointerEventInit eventInitDict = {});
[MeasureAs=PointerEventAttributeCount] readonly attribute long pointerId;
[MeasureAs=PointerEventAttributeCount] readonly attribute double width;
[MeasureAs=PointerEventAttributeCount] readonly attribute double height;
diff --git a/chromium/third_party/blink/renderer/core/events/pointer_event_factory.cc b/chromium/third_party/blink/renderer/core/events/pointer_event_factory.cc
index 4e80447f5a8..43009215f7d 100644
--- a/chromium/third_party/blink/renderer/core/events/pointer_event_factory.cc
+++ b/chromium/third_party/blink/renderer/core/events/pointer_event_factory.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/core/events/pointer_event_factory.h"
+#include "third_party/blink/public/platform/web_screen_info.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_pointer_event_init.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/page/chrome_client.h"
@@ -117,12 +119,12 @@ void UpdateCommonPointerEventInit(const WebPointerEvent& web_pointer_event,
// movementX/Y is type int for pointerevent, so we still need to truncated
// the coordinates before calculate movement.
pointer_event_init->setMovementX(
- base::saturated_cast<int>(web_pointer_event.PositionInScreen().x *
+ base::saturated_cast<int>(web_pointer_event.PositionInScreen().x() *
device_scale_factor) -
base::saturated_cast<int>(last_global_position.X() *
device_scale_factor));
pointer_event_init->setMovementY(
- base::saturated_cast<int>(web_pointer_event.PositionInScreen().y *
+ base::saturated_cast<int>(web_pointer_event.PositionInScreen().y() *
device_scale_factor) -
base::saturated_cast<int>(last_global_position.Y() *
device_scale_factor));
@@ -195,7 +197,7 @@ HeapVector<Member<PointerEvent>> PointerEventFactory::CreateEventSequence(
new_event_init,
static_cast<WebInputEvent::Modifiers>(event.GetModifiers()));
- last_global_position = event.PositionInScreen();
+ last_global_position = FloatPoint(event.PositionInScreen());
PointerEvent* pointer_event =
PointerEvent::Create(type, new_event_init, event.TimeStamp());
@@ -343,7 +345,7 @@ PointerEvent* PointerEventFactory::Create(
pointer_event_init->setPredictedEvents(predicted_pointer_events);
SetLastPosition(pointer_event_init->pointerId(),
- web_pointer_event.PositionInScreen(), event_type);
+ FloatPoint(web_pointer_event.PositionInScreen()), event_type);
return PointerEvent::Create(type, pointer_event_init,
web_pointer_event.TimeStamp());
}
@@ -375,7 +377,7 @@ FloatPoint PointerEventFactory::GetLastPointerPosition(
}
// If pointer_id is not in the map, returns the current position so the
// movement will be zero.
- return event.PositionInScreen();
+ return FloatPoint(event.PositionInScreen());
}
PointerEvent* PointerEventFactory::CreatePointerCancelEvent(
@@ -427,7 +429,7 @@ PointerEvent* PointerEventFactory::CreatePointerEventFrom(
SetEventSpecificFields(pointer_event_init, type);
- if (UIEventWithKeyState* key_state_event =
+ if (const UIEventWithKeyState* key_state_event =
FindEventWithKeyState(pointer_event)) {
UIEventWithKeyState::SetFromWebInputEventModifiers(
pointer_event_init, key_state_event->GetModifiers());
@@ -488,7 +490,7 @@ PointerEventFactory::~PointerEventFactory() {
void PointerEventFactory::Clear() {
for (int type = 0;
- type <= ToInt(WebPointerProperties::PointerType::kLastEntry); type++) {
+ type <= ToInt(WebPointerProperties::PointerType::kMaxValue); type++) {
primary_id_[type] = PointerEventFactory::kInvalidId;
id_count_[type] = 0;
}
diff --git a/chromium/third_party/blink/renderer/core/events/pointer_event_factory.h b/chromium/third_party/blink/renderer/core/events/pointer_event_factory.h
index 3122d6fc8e4..416958f9261 100644
--- a/chromium/third_party/blink/renderer/core/events/pointer_event_factory.h
+++ b/chromium/third_party/blink/renderer/core/events/pointer_event_factory.h
@@ -5,8 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_POINTER_EVENT_FACTORY_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_POINTER_EVENT_FACTORY_H_
-#include "third_party/blink/public/platform/web_pointer_event.h"
-#include "third_party/blink/public/platform/web_pointer_properties.h"
+#include "third_party/blink/public/common/input/web_pointer_event.h"
+#include "third_party/blink/public/common/input/web_pointer_properties.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/events/pointer_event.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -154,10 +154,9 @@ class CORE_EXPORT PointerEventFactory {
pointer_incoming_id_mapping_;
PointerIdKeyMap<PointerAttributes> pointer_id_mapping_;
int primary_id_[static_cast<int>(
- WebPointerProperties::PointerType::kLastEntry) +
+ WebPointerProperties::PointerType::kMaxValue) +
1];
- int id_count_[static_cast<int>(
- WebPointerProperties::PointerType::kLastEntry) +
+ int id_count_[static_cast<int>(WebPointerProperties::PointerType::kMaxValue) +
1];
PointerIdKeyMap<FloatPoint> pointer_id_last_position_mapping_;
diff --git a/chromium/third_party/blink/renderer/core/events/pointer_event_factory_test.cc b/chromium/third_party/blink/renderer/core/events/pointer_event_factory_test.cc
index fd680c5b14d..f0cd905c553 100644
--- a/chromium/third_party/blink/renderer/core/events/pointer_event_factory_test.cc
+++ b/chromium/third_party/blink/renderer/core/events/pointer_event_factory_test.cc
@@ -9,7 +9,7 @@
#include <limits>
#include "base/time/time.h"
-#include "third_party/blink/public/platform/web_pointer_properties.h"
+#include "third_party/blink/public/common/input/web_pointer_properties.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/page/page.h"
@@ -123,7 +123,7 @@ class PointerEventFactoryTest : public testing::Test {
pointer_event->pointerId(),
WebPointerProperties(1, WebPointerProperties::PointerType::kUnknown,
WebPointerProperties::Button::kNoButton,
- WebFloatPoint(50, 50), WebFloatPoint(20, 20)),
+ gfx::PointF(50, 50), gfx::PointF(20, 20)),
type),
FloatPoint(100, 100));
return pointer_event;
@@ -590,7 +590,7 @@ TEST_F(PointerEventFactoryTest, LastPointerPosition) {
expected_mouse_id_,
WebPointerProperties(1, WebPointerProperties::PointerType::kUnknown,
WebPointerProperties::Button::kNoButton,
- WebFloatPoint(50, 50), WebFloatPoint(20, 20)),
+ gfx::PointF(50, 50), gfx::PointF(20, 20)),
WebInputEvent::kPointerMove),
FloatPoint(20, 20));
}
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 7e917d71d11..47fe14831c2 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(blink::Visitor* visitor) {
+void PopStateEvent::Trace(Visitor* visitor) {
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 05390ec063e..d8452f95bd9 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
@@ -27,8 +27,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_POP_STATE_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_POP_STATE_EVENT_H_
+#include "third_party/blink/renderer/bindings/core/v8/v8_pop_state_event_init.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
-#include "third_party/blink/renderer/core/events/pop_state_event_init.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -62,7 +62,7 @@ class PopStateEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
scoped_refptr<SerializedScriptValue> serialized_state_;
diff --git a/chromium/third_party/blink/renderer/core/events/pop_state_event.idl b/chromium/third_party/blink/renderer/core/events/pop_state_event.idl
index 874f5e5848a..bf478ea554a 100644
--- a/chromium/third_party/blink/renderer/core/events/pop_state_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/pop_state_event.idl
@@ -27,10 +27,9 @@
// https://html.spec.whatwg.org/C/#the-popstateevent-interface
[
- Constructor(DOMString type, optional PopStateEventInit eventInitDict),
- ConstructorCallWith=ScriptState,
// TODO(foolip): Exposed=(Window,Worker)
Exposed=Window
] interface PopStateEvent : Event {
+ [CallWith=ScriptState] constructor(DOMString type, optional PopStateEventInit eventInitDict = {});
[Custom=Getter] readonly attribute any 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 ccfdd9462e0..8cb07d97a5e 100644
--- a/chromium/third_party/blink/renderer/core/events/progress_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/progress_event.cc
@@ -25,6 +25,7 @@
#include "third_party/blink/renderer/core/events/progress_event.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_progress_event_init.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
namespace blink {
@@ -52,7 +53,7 @@ const AtomicString& ProgressEvent::InterfaceName() const {
return event_interface_names::kProgressEvent;
}
-void ProgressEvent::Trace(blink::Visitor* visitor) {
+void ProgressEvent::Trace(Visitor* visitor) {
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 a9fa01da8df..9a3c3c26f8b 100644
--- a/chromium/third_party/blink/renderer/core/events/progress_event.h
+++ b/chromium/third_party/blink/renderer/core/events/progress_event.h
@@ -28,10 +28,11 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
-#include "third_party/blink/renderer/core/events/progress_event_init.h"
namespace blink {
+class ProgressEventInit;
+
class CORE_EXPORT ProgressEvent : public Event {
DEFINE_WRAPPERTYPEINFO();
@@ -64,7 +65,7 @@ class CORE_EXPORT ProgressEvent : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
bool length_computable_;
diff --git a/chromium/third_party/blink/renderer/core/events/progress_event.idl b/chromium/third_party/blink/renderer/core/events/progress_event.idl
index 5062deabf3c..72491678ae2 100644
--- a/chromium/third_party/blink/renderer/core/events/progress_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/progress_event.idl
@@ -26,9 +26,9 @@
// https://xhr.spec.whatwg.org/#interface-progressevent
[
- Constructor(DOMString type, optional ProgressEventInit eventInitDict),
- Exposed=(Window,DedicatedWorker,SharedWorker)
+ Exposed=(Window, DedicatedWorker, SharedWorker)
] interface ProgressEvent : Event {
+ constructor(DOMString type, optional ProgressEventInit eventInitDict = {});
readonly attribute boolean lengthComputable;
readonly attribute unsigned long long loaded;
readonly attribute unsigned long long total;
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 44f1173090f..3f44a93a846 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
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/events/promise_rejection_event.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_promise_rejection_event_init.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
@@ -54,7 +55,7 @@ bool PromiseRejectionEvent::CanBeDispatchedInWorld(
return world_->GetWorldId() == world.GetWorldId();
}
-void PromiseRejectionEvent::Trace(blink::Visitor* visitor) {
+void PromiseRejectionEvent::Trace(Visitor* visitor) {
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 7f3bb24c822..e56860a85f5 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
@@ -9,13 +9,14 @@
#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/events/event.h"
-#include "third_party/blink/renderer/core/events/promise_rejection_event_init.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h"
namespace blink {
+class PromiseRejectionEventInit;
+
class CORE_EXPORT PromiseRejectionEvent final : public Event {
DEFINE_WRAPPERTYPEINFO();
@@ -41,7 +42,7 @@ class CORE_EXPORT PromiseRejectionEvent final : public Event {
// observed across different worlds.
bool CanBeDispatchedInWorld(const DOMWrapperWorld&) const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
~PromiseRejectionEvent() override;
diff --git a/chromium/third_party/blink/renderer/core/events/promise_rejection_event.idl b/chromium/third_party/blink/renderer/core/events/promise_rejection_event.idl
index 1f1c7095b38..3f53e019b34 100644
--- a/chromium/third_party/blink/renderer/core/events/promise_rejection_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/promise_rejection_event.idl
@@ -5,10 +5,9 @@
// https://github.com/domenic/unhandled-rejections-browser-spec
[
- Constructor(DOMString type, PromiseRejectionEventInit eventInitDict),
- ConstructorCallWith=ScriptState,
Exposed=(Window,Worker)
] interface PromiseRejectionEvent : Event {
+ [CallWith=ScriptState] constructor(DOMString type, PromiseRejectionEventInit eventInitDict);
[Custom=Getter] readonly attribute Promise<any> promise;
[CallWith=ScriptState] readonly attribute any reason;
};
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 e8bdf209deb..7aef88ab13d 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(blink::Visitor* visitor) {
+void ResourceProgressEvent::Trace(Visitor* visitor) {
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 d18ff4f8f96..f1ac2639491 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
@@ -47,15 +47,6 @@ class CORE_EXPORT ResourceProgressEvent final : public ProgressEvent {
DEFINE_WRAPPERTYPEINFO();
public:
- static ResourceProgressEvent* Create(const AtomicString& type,
- bool length_computable,
- uint64_t loaded,
- uint64_t total,
- const String& url) {
- return MakeGarbageCollected<ResourceProgressEvent>(type, length_computable,
- loaded, total, url);
- }
-
ResourceProgressEvent(const AtomicString& type,
bool length_computable,
uint64_t loaded,
@@ -66,7 +57,7 @@ class CORE_EXPORT ResourceProgressEvent final : public ProgressEvent {
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
String url_;
diff --git a/chromium/third_party/blink/renderer/core/events/security_policy_violation_event.cc b/chromium/third_party/blink/renderer/core/events/security_policy_violation_event.cc
index 2893d3b4bf6..61089e3f721 100644
--- a/chromium/third_party/blink/renderer/core/events/security_policy_violation_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/security_policy_violation_event.cc
@@ -26,6 +26,8 @@
#include "third_party/blink/renderer/core/events/security_policy_violation_event.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_security_policy_violation_event_init.h"
+
namespace blink {
namespace {
@@ -37,11 +39,7 @@ const char kReport[] = "report";
SecurityPolicyViolationEvent::SecurityPolicyViolationEvent(
const AtomicString& type)
- : Event(type, Bubbles::kYes, Cancelable::kNo, ComposedMode::kComposed),
- disposition_(kContentSecurityPolicyHeaderTypeEnforce),
- line_number_(0),
- column_number_(0),
- status_code_(0) {}
+ : Event(type, Bubbles::kYes, Cancelable::kNo, ComposedMode::kComposed) {}
SecurityPolicyViolationEvent::SecurityPolicyViolationEvent(
const AtomicString& type,
@@ -60,8 +58,8 @@ SecurityPolicyViolationEvent::SecurityPolicyViolationEvent(
if (initializer->hasOriginalPolicy())
original_policy_ = initializer->originalPolicy();
disposition_ = initializer->disposition() == kReport
- ? kContentSecurityPolicyHeaderTypeReport
- : kContentSecurityPolicyHeaderTypeEnforce;
+ ? network::mojom::ContentSecurityPolicyType::kReport
+ : network::mojom::ContentSecurityPolicyType::kEnforce;
if (initializer->hasSourceFile())
source_file_ = initializer->sourceFile();
if (initializer->hasLineNumber())
@@ -78,9 +76,9 @@ const String& SecurityPolicyViolationEvent::disposition() const {
DEFINE_STATIC_LOCAL(const String, enforce, (kEnforce));
DEFINE_STATIC_LOCAL(const String, report, (kReport));
- if (disposition_ == kContentSecurityPolicyHeaderTypeReport)
- return report;
- return enforce;
+ return disposition_ == network::mojom::ContentSecurityPolicyType::kReport
+ ? report
+ : enforce;
}
} // namespace blink
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 8aad17c82a6..de7414c378e 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
@@ -26,13 +26,15 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_SECURITY_POLICY_VIOLATION_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_SECURITY_POLICY_VIOLATION_EVENT_H_
+#include "services/network/public/mojom/content_security_policy.mojom-shared.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
-#include "third_party/blink/renderer/core/events/security_policy_violation_event_init.h"
#include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h"
namespace blink {
+class SecurityPolicyViolationEventInit;
+
class SecurityPolicyViolationEvent final : public Event {
DEFINE_WRAPPERTYPEINFO();
@@ -70,7 +72,7 @@ class SecurityPolicyViolationEvent final : public Event {
return event_interface_names::kSecurityPolicyViolationEvent;
}
- void Trace(blink::Visitor* visitor) override { Event::Trace(visitor); }
+ void Trace(Visitor* visitor) override { Event::Trace(visitor); }
private:
String document_uri_;
@@ -79,12 +81,13 @@ class SecurityPolicyViolationEvent final : public Event {
String violated_directive_;
String effective_directive_;
String original_policy_;
- ContentSecurityPolicyHeaderType disposition_;
+ network::mojom::ContentSecurityPolicyType disposition_ =
+ network::mojom::ContentSecurityPolicyType::kEnforce;
String source_file_;
String sample_;
- int line_number_;
- int column_number_;
- uint16_t status_code_;
+ int line_number_ = 0;
+ int column_number_ = 0;
+ uint16_t status_code_ = 0;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/events/security_policy_violation_event.idl b/chromium/third_party/blink/renderer/core/events/security_policy_violation_event.idl
index cbf041b6d0c..12b334f52a7 100644
--- a/chromium/third_party/blink/renderer/core/events/security_policy_violation_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/security_policy_violation_event.idl
@@ -30,10 +30,10 @@ enum SecurityPolicyViolationEventDisposition {
};
[
- Constructor(DOMString type),
- Constructor(DOMString type, SecurityPolicyViolationEventInit eventInitDict),
Exposed=(Window,Worker)
] interface SecurityPolicyViolationEvent : Event {
+ constructor(DOMString type);
+ constructor(DOMString type, SecurityPolicyViolationEventInit eventInitDict);
// TODO(foolip): The spec says "documentURL".
[Measure] readonly attribute DOMString documentURI;
readonly attribute DOMString referrer;
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 afda4ad0a69..3e58609459e 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(blink::Visitor* visitor) {
+void TextEvent::Trace(Visitor* visitor) {
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 86743907992..f853b6eb8a7 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
TextEventInputType input_type_;
diff --git a/chromium/third_party/blink/renderer/core/events/text_event.idl b/chromium/third_party/blink/renderer/core/events/text_event.idl
index 37ea2536407..3395b932224 100644
--- a/chromium/third_party/blink/renderer/core/events/text_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/text_event.idl
@@ -35,10 +35,10 @@ interface TextEvent : UIEvent {
[Measure] readonly attribute DOMString data;
- [Measure] void initTextEvent([DefaultValue=Undefined] optional DOMString type,
- [DefaultValue=Undefined] optional boolean bubbles,
- [DefaultValue=Undefined] optional boolean cancelable,
- [DefaultValue=Undefined] optional Window? view,
- [DefaultValue=Undefined] optional DOMString data);
+ [Measure] void initTextEvent(optional DOMString type = "undefined",
+ optional boolean bubbles = false,
+ optional boolean cancelable = false,
+ optional Window? view = null,
+ optional DOMString data = "undefined");
};
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 874f5410cce..54a5a379039 100644
--- a/chromium/third_party/blink/renderer/core/events/touch_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/touch_event.cc
@@ -27,6 +27,7 @@
#include "third_party/blink/renderer/core/events/touch_event.h"
#include "third_party/blink/public/platform/web_coalesced_input_event.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_touch_event_init.h"
#include "third_party/blink/renderer/core/dom/events/event_dispatcher.h"
#include "third_party/blink/renderer/core/dom/events/event_path.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
@@ -54,8 +55,7 @@ const WebTouchEvent* GetWebTouchEvent(const WebCoalescedInputEvent& event) {
}
} // namespace
-TouchEvent::TouchEvent()
- : current_touch_action_(TouchAction::kTouchActionAuto) {}
+TouchEvent::TouchEvent() : current_touch_action_(TouchAction::kAuto) {}
TouchEvent::TouchEvent(const WebCoalescedInputEvent& event,
TouchList* touches,
@@ -92,7 +92,7 @@ TouchEvent::TouchEvent(const AtomicString& type,
touches_(TouchList::Create(initializer->touches())),
target_touches_(TouchList::Create(initializer->targetTouches())),
changed_touches_(TouchList::Create(initializer->changedTouches())),
- current_touch_action_(TouchAction::kTouchActionAuto) {}
+ current_touch_action_(TouchAction::kAuto) {}
TouchEvent::~TouchEvent() = default;
@@ -127,7 +127,7 @@ void TouchEvent::preventDefault() {
// Only enable the warning when the current touch action is auto because
// an author may use touch action but call preventDefault for interop with
// browsers that don't support touch-action.
- if (current_touch_action_ == TouchAction::kTouchActionAuto) {
+ if (current_touch_action_ == TouchAction::kAuto) {
id = "PreventDefaultPassive";
message =
"Unable to preventDefault inside passive event listener due to "
@@ -148,7 +148,7 @@ void TouchEvent::preventDefault() {
type() == event_type_names::kTouchmove) &&
local_dom_window) {
auto* local_frame = DynamicTo<LocalFrame>(view()->GetFrame());
- if (local_frame && current_touch_action_ == TouchAction::kTouchActionAuto) {
+ if (local_frame && current_touch_action_ == TouchAction::kAuto) {
switch (HandlingPassive()) {
case PassiveMode::kNotPassiveDefault:
UseCounter::Count(local_dom_window->document(),
@@ -173,7 +173,7 @@ bool TouchEvent::IsTouchStartOrFirstTouchMove() const {
return GetWebTouchEvent(*native_event_)->touch_start_or_first_touch_move;
}
-void TouchEvent::Trace(blink::Visitor* visitor) {
+void TouchEvent::Trace(Visitor* visitor) {
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 674a084e07a..90ca4041f33 100644
--- a/chromium/third_party/blink/renderer/core/events/touch_event.h
+++ b/chromium/third_party/blink/renderer/core/events/touch_event.h
@@ -27,16 +27,17 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_TOUCH_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_TOUCH_EVENT_H_
+#include "third_party/blink/public/common/input/web_touch_event.h"
#include "third_party/blink/public/platform/web_coalesced_input_event.h"
-#include "third_party/blink/public/platform/web_touch_event.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/events/touch_event_init.h"
#include "third_party/blink/renderer/core/events/ui_event_with_key_state.h"
#include "third_party/blink/renderer/core/input/touch_list.h"
#include "third_party/blink/renderer/platform/graphics/touch_action.h"
namespace blink {
+class TouchEventInit;
+
class CORE_EXPORT TouchEvent final : public UIEventWithKeyState {
DEFINE_WRAPPERTYPEINFO();
@@ -97,7 +98,7 @@ class CORE_EXPORT TouchEvent final : public UIEventWithKeyState {
DispatchEventResult DispatchEvent(EventDispatcher&) override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
bool IsTouchStartOrFirstTouchMove() const;
@@ -113,7 +114,10 @@ class CORE_EXPORT TouchEvent final : public UIEventWithKeyState {
std::unique_ptr<WebCoalescedInputEvent> native_event_;
};
-DEFINE_EVENT_TYPE_CASTS(TouchEvent);
+template <>
+struct DowncastTraits<TouchEvent> {
+ static bool AllowFrom(const Event& event) { return event.IsTouchEvent(); }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/events/touch_event.idl b/chromium/third_party/blink/renderer/core/events/touch_event.idl
index 50a667e0af8..80d28b6d7aa 100644
--- a/chromium/third_party/blink/renderer/core/events/touch_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/touch_event.idl
@@ -26,9 +26,9 @@
// https://w3c.github.io/touch-events/#touchevent-interface
[
- Constructor(DOMString type, optional TouchEventInit eventInitDict),
Exposed=Window
] interface TouchEvent : UIEvent {
+ constructor(DOMString type, optional TouchEventInit eventInitDict = {});
readonly attribute TouchList touches;
readonly attribute TouchList targetTouches;
readonly attribute TouchList changedTouches;
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 87f86b08ad8..6043493d59d 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
@@ -29,28 +29,23 @@
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/events/touch_event.h"
#include "third_party/blink/renderer/core/input/touch_list.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
-TouchEventContext* TouchEventContext::Create() {
- return MakeGarbageCollected<TouchEventContext>();
-}
-
TouchEventContext::TouchEventContext()
- : touches_(MakeGarbageCollected<TouchList>()),
- target_touches_(MakeGarbageCollected<TouchList>()),
- changed_touches_(MakeGarbageCollected<TouchList>()) {}
+ : touches_(TouchList::Create()),
+ target_touches_(TouchList::Create()),
+ changed_touches_(TouchList::Create()) {}
void TouchEventContext::HandleLocalEvents(Event& event) const {
- DCHECK(event.IsTouchEvent());
- TouchEvent& touch_event = ToTouchEvent(event);
+ DCHECK(IsA<TouchEvent>(event));
+ auto& touch_event = To<TouchEvent>(event);
touch_event.SetTouches(touches_);
touch_event.SetTargetTouches(target_touches_);
touch_event.SetChangedTouches(changed_touches_);
}
-void TouchEventContext::Trace(blink::Visitor* visitor) {
+void TouchEventContext::Trace(Visitor* visitor) {
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 3288741736a..b3ef5037392 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
@@ -36,8 +36,6 @@ class TouchList;
class TouchEventContext : public GarbageCollected<TouchEventContext> {
public:
- static TouchEventContext* Create();
-
TouchEventContext();
void HandleLocalEvents(Event&) const;
@@ -45,7 +43,7 @@ class TouchEventContext : public GarbageCollected<TouchEventContext> {
TouchList& TargetTouches() { return *target_touches_; }
TouchList& ChangedTouches() { return *changed_touches_; }
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
Member<TouchList> touches_;
diff --git a/chromium/third_party/blink/renderer/core/events/touch_event_test.cc b/chromium/third_party/blink/renderer/core/events/touch_event_test.cc
index ef62cd7ebb8..ff58660475f 100644
--- a/chromium/third_party/blink/renderer/core/events/touch_event_test.cc
+++ b/chromium/third_party/blink/renderer/core/events/touch_event_test.cc
@@ -70,7 +70,7 @@ class TouchEventTest : public PageTestBase {
web_touch_event.dispatch_type = dispatch_type;
return TouchEvent::Create(WebCoalescedInputEvent(web_touch_event), nullptr,
nullptr, nullptr, "touchstart", &Window(),
- TouchAction::kTouchActionAuto);
+ TouchAction::kAuto);
}
private:
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 f7840875aba..90f65a1cc3a 100644
--- a/chromium/third_party/blink/renderer/core/events/transition_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/transition_event.cc
@@ -26,6 +26,7 @@
#include "third_party/blink/renderer/core/events/transition_event.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_transition_event_init.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
namespace blink {
@@ -72,7 +73,7 @@ const AtomicString& TransitionEvent::InterfaceName() const {
return event_interface_names::kTransitionEvent;
}
-void TransitionEvent::Trace(blink::Visitor* visitor) {
+void TransitionEvent::Trace(Visitor* visitor) {
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 6038290e351..2c2574b1837 100644
--- a/chromium/third_party/blink/renderer/core/events/transition_event.h
+++ b/chromium/third_party/blink/renderer/core/events/transition_event.h
@@ -29,10 +29,11 @@
#include "third_party/blink/renderer/core/animation/animation_time_delta.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
-#include "third_party/blink/renderer/core/events/transition_event_init.h"
namespace blink {
+class TransitionEventInit;
+
class TransitionEvent final : public Event {
DEFINE_WRAPPERTYPEINFO();
@@ -67,7 +68,7 @@ class TransitionEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
String property_name_;
diff --git a/chromium/third_party/blink/renderer/core/events/transition_event.idl b/chromium/third_party/blink/renderer/core/events/transition_event.idl
index 7d09afc944b..3f07239a568 100644
--- a/chromium/third_party/blink/renderer/core/events/transition_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/transition_event.idl
@@ -27,9 +27,9 @@
// https://drafts.csswg.org/css-transitions/#transition-events
[
- Constructor(DOMString type, optional TransitionEventInit eventInitDict),
Exposed=Window
] interface TransitionEvent : Event {
+ constructor(DOMString type, optional TransitionEventInit eventInitDict = {});
readonly attribute DOMString propertyName;
readonly attribute double elapsedTime;
readonly attribute DOMString pseudoElement;
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 8b67e72c6a3..e54451dc2ae 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(blink::Visitor* visitor) {
+void UIEvent::Trace(Visitor* visitor) {
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 26bb1daac7f..63cfd9dc243 100644
--- a/chromium/third_party/blink/renderer/core/events/ui_event.h
+++ b/chromium/third_party/blink/renderer/core/events/ui_event.h
@@ -24,10 +24,11 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_UI_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_UI_EVENT_H_
+#include "third_party/blink/renderer/bindings/core/v8/v8_ui_event_init.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
-#include "third_party/blink/renderer/core/events/ui_event_init.h"
#include "third_party/blink/renderer/core/frame/dom_window.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -86,7 +87,7 @@ class CORE_EXPORT UIEvent : public Event {
virtual unsigned which() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<AbstractView> view_;
@@ -94,7 +95,10 @@ class CORE_EXPORT UIEvent : public Event {
Member<InputDeviceCapabilities> source_capabilities_;
};
-DEFINE_EVENT_TYPE_CASTS(UIEvent);
+template <>
+struct DowncastTraits<UIEvent> {
+ static bool AllowFrom(const Event& event) { return event.IsUIEvent(); }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/events/ui_event.idl b/chromium/third_party/blink/renderer/core/events/ui_event.idl
index ed34dba7c05..b7f2540ac48 100644
--- a/chromium/third_party/blink/renderer/core/events/ui_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/ui_event.idl
@@ -20,20 +20,19 @@
// https://w3c.github.io/uievents/#interface-UIEvent
[
- Constructor(DOMString type, optional UIEventInit eventInitDict),
Exposed=Window
] interface UIEvent : Event {
+ constructor(DOMString type, optional UIEventInit eventInitDict = {});
readonly attribute Window? view;
readonly attribute long detail;
readonly attribute InputDeviceCapabilities? sourceCapabilities;
// https://w3c.github.io/uievents/#idl-interface-UIEvent-initializers
- // TODO(foolip): None of the initUIEvent() arguments should be optional.
- [Measure] void initUIEvent([DefaultValue=Undefined] optional DOMString type,
- [DefaultValue=Undefined] optional boolean bubbles,
- [DefaultValue=Undefined] optional boolean cancelable,
- [DefaultValue=Undefined] optional Window? view,
- [DefaultValue=Undefined] optional long detail);
+ [Measure] void initUIEvent(DOMString type,
+ optional boolean bubbles = false,
+ optional boolean cancelable = false,
+ optional Window? view = null,
+ optional long detail = 0);
readonly attribute unsigned long which;
};
diff --git a/chromium/third_party/blink/renderer/core/events/ui_event_with_key_state.cc b/chromium/third_party/blink/renderer/core/events/ui_event_with_key_state.cc
index de489e9fb73..ffaf5d958c4 100644
--- a/chromium/third_party/blink/renderer/core/events/ui_event_with_key_state.cc
+++ b/chromium/third_party/blink/renderer/core/events/ui_event_with_key_state.cc
@@ -21,6 +21,7 @@
#include "third_party/blink/renderer/core/events/ui_event_with_key_state.h"
#include "build/build_config.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_event_modifier_init.h"
namespace blink {
@@ -154,10 +155,11 @@ void UIEventWithKeyState::InitModifiers(bool ctrl_key,
modifiers_ |= WebInputEvent::kMetaKey;
}
-UIEventWithKeyState* FindEventWithKeyState(Event* event) {
- for (Event* e = event; e; e = e->UnderlyingEvent())
+const UIEventWithKeyState* FindEventWithKeyState(const Event* event) {
+ for (const Event* e = event; e; e = e->UnderlyingEvent()) {
if (e->IsKeyboardEvent() || e->IsMouseEvent() || e->IsPointerEvent())
- return static_cast<UIEventWithKeyState*>(e);
+ return static_cast<const UIEventWithKeyState*>(e);
+ }
return nullptr;
}
diff --git a/chromium/third_party/blink/renderer/core/events/ui_event_with_key_state.h b/chromium/third_party/blink/renderer/core/events/ui_event_with_key_state.h
index 20f22b5d40e..7d5e5359e6a 100644
--- a/chromium/third_party/blink/renderer/core/events/ui_event_with_key_state.h
+++ b/chromium/third_party/blink/renderer/core/events/ui_event_with_key_state.h
@@ -24,13 +24,14 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_UI_EVENT_WITH_KEY_STATE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_UI_EVENT_WITH_KEY_STATE_H_
-#include "third_party/blink/public/platform/web_input_event.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/dom/events/event_modifier_init.h"
#include "third_party/blink/renderer/core/events/ui_event.h"
namespace blink {
+class EventModifierInit;
+
class CORE_EXPORT UIEventWithKeyState : public UIEvent {
public:
bool ctrlKey() const { return modifiers_ & WebInputEvent::kControlKey; }
@@ -91,7 +92,7 @@ class CORE_EXPORT UIEventWithKeyState : public UIEvent {
static bool new_tab_modifier_set_from_isolated_world_;
};
-UIEventWithKeyState* FindEventWithKeyState(Event*);
+const UIEventWithKeyState* FindEventWithKeyState(const Event*);
} // namespace blink
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 3d4c1d6f346..fa57fc5c2e2 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
@@ -14,13 +14,9 @@ class VisualViewportResizeEvent final : public Event {
VisualViewportResizeEvent();
~VisualViewportResizeEvent() override;
- static VisualViewportResizeEvent* Create() {
- return MakeGarbageCollected<VisualViewportResizeEvent>();
- }
-
void DoneDispatchingEventAtCurrentTarget() override;
- void Trace(blink::Visitor* visitor) override { Event::Trace(visitor); }
+ void Trace(Visitor* visitor) 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 8a9675e1325..7ec4ab25aba 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
@@ -14,13 +14,9 @@ class VisualViewportScrollEvent final : public Event {
VisualViewportScrollEvent();
~VisualViewportScrollEvent() override;
- static VisualViewportScrollEvent* Create() {
- return MakeGarbageCollected<VisualViewportScrollEvent>();
- }
-
void DoneDispatchingEventAtCurrentTarget() override;
- void Trace(blink::Visitor* visitor) override { Event::Trace(visitor); }
+ void Trace(Visitor* visitor) override { Event::Trace(visitor); }
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/events/web_input_event_conversion.cc b/chromium/third_party/blink/renderer/core/events/web_input_event_conversion.cc
index da06675f5aa..fcf3fc6b4af 100644
--- a/chromium/third_party/blink/renderer/core/events/web_input_event_conversion.cc
+++ b/chromium/third_party/blink/renderer/core/events/web_input_event_conversion.cc
@@ -59,7 +59,7 @@ float FrameScale(const LocalFrameView* frame_view) {
return scale;
}
-FloatPoint FrameTranslation(const LocalFrameView* frame_view) {
+gfx::Vector2dF FrameTranslation(const LocalFrameView* frame_view) {
IntPoint visual_viewport;
FloatSize overscroll_offset;
if (frame_view) {
@@ -71,8 +71,8 @@ FloatPoint FrameTranslation(const LocalFrameView* frame_view) {
root_view->GetPage()->GetChromeClient().ElasticOverscroll();
}
}
- return FloatPoint(visual_viewport.X() + overscroll_offset.Width(),
- visual_viewport.Y() + overscroll_offset.Height());
+ return gfx::Vector2dF(visual_viewport.X() + overscroll_offset.Width(),
+ visual_viewport.Y() + overscroll_offset.Height());
}
FloatPoint ConvertAbsoluteLocationForLayoutObjectFloat(
@@ -118,12 +118,12 @@ unsigned ToWebInputEventModifierFrom(WebMouseEvent::Button button) {
}
WebPointerEvent TransformWebPointerEvent(float frame_scale,
- FloatPoint frame_translate,
+ gfx::Vector2dF frame_translate,
const WebPointerEvent& event) {
- // frameScale is default initialized in debug builds to be 0.
- DCHECK_EQ(0, event.FrameScale());
- DCHECK_EQ(0, event.FrameTranslate().x);
- DCHECK_EQ(0, event.FrameTranslate().y);
+ // frameScale is default initialized to 1.
+ DCHECK_EQ(1, event.FrameScale());
+ DCHECK_EQ(0, event.FrameTranslate().x());
+ DCHECK_EQ(0, event.FrameTranslate().y());
WebPointerEvent result = event;
result.SetFrameScale(frame_scale);
result.SetFrameTranslate(frame_translate);
@@ -274,7 +274,7 @@ WebMouseEventBuilder::WebMouseEventBuilder(const LocalFrameView* plugin_parent,
time_stamp_ = event.PlatformTimeStamp();
modifiers_ = event.GetModifiers();
frame_scale_ = 1;
- frame_translate_ = WebFloatPoint();
+ frame_translate_ = gfx::Vector2dF();
// The mouse event co-ordinates should be generated from the co-ordinates of
// the touch point.
@@ -335,7 +335,7 @@ Vector<WebPointerEvent> TransformWebPointerEventVector(
LocalFrameView* frame_view,
const WebVector<const WebInputEvent*>& coalesced_events) {
float scale = FrameScale(frame_view);
- FloatPoint translation = FrameTranslation(frame_view);
+ gfx::Vector2dF translation = FrameTranslation(frame_view);
Vector<WebPointerEvent> result;
for (auto* const event : coalesced_events) {
DCHECK(WebInputEvent::IsPointerEventType(event->GetType()));
diff --git a/chromium/third_party/blink/renderer/core/events/web_input_event_conversion.h b/chromium/third_party/blink/renderer/core/events/web_input_event_conversion.h
index 81c55799996..9dc220ef02e 100644
--- a/chromium/third_party/blink/renderer/core/events/web_input_event_conversion.h
+++ b/chromium/third_party/blink/renderer/core/events/web_input_event_conversion.h
@@ -31,12 +31,12 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_WEB_INPUT_EVENT_CONVERSION_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_WEB_INPUT_EVENT_CONVERSION_H_
+#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/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/platform/web_coalesced_input_event.h"
-#include "third_party/blink/public/platform/web_input_event.h"
-#include "third_party/blink/public/platform/web_keyboard_event.h"
-#include "third_party/blink/public/platform/web_mouse_wheel_event.h"
-#include "third_party/blink/public/platform/web_pointer_event.h"
-#include "third_party/blink/public/platform/web_touch_event.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/scroll/scroll_types.h"
diff --git a/chromium/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc b/chromium/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc
index 4047e3baccf..8453864e754 100644
--- a/chromium/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc
+++ b/chromium/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc
@@ -33,6 +33,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/web/web_frame.h"
#include "third_party/blink/public/web/web_settings.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_keyboard_event_init.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"
@@ -125,7 +126,7 @@ TEST(WebInputEventConversionTest, InputEventsScaling) {
int page_height = 480;
web_view->MainFrameWidget()->Resize(WebSize(page_width, page_height));
web_view->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
web_view->SetPageScaleFactor(3);
@@ -147,8 +148,8 @@ TEST(WebInputEventConversionTest, InputEventsScaling) {
FlooredIntPoint(transformed_event.PositionInRootFrame());
EXPECT_EQ(5, position.X());
EXPECT_EQ(5, position.Y());
- EXPECT_EQ(15, transformed_event.PositionInScreen().x);
- EXPECT_EQ(15, transformed_event.PositionInScreen().y);
+ EXPECT_EQ(15, transformed_event.PositionInScreen().x());
+ EXPECT_EQ(15, transformed_event.PositionInScreen().y());
EXPECT_EQ(15, transformed_event.movement_x);
EXPECT_EQ(15, transformed_event.movement_y);
@@ -159,8 +160,8 @@ TEST(WebInputEventConversionTest, InputEventsScaling) {
WebInputEvent::kGestureScrollUpdate, WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- web_gesture_event.SetPositionInWidget(WebFloatPoint(15, 18));
- web_gesture_event.SetPositionInScreen(WebFloatPoint(20, 22));
+ web_gesture_event.SetPositionInWidget(gfx::PointF(15, 18));
+ web_gesture_event.SetPositionInScreen(gfx::PointF(20, 22));
web_gesture_event.data.scroll_update.delta_x = 45;
web_gesture_event.data.scroll_update.delta_y = 48;
web_gesture_event.data.scroll_update.velocity_x = 40;
@@ -174,8 +175,8 @@ TEST(WebInputEventConversionTest, InputEventsScaling) {
FlooredIntPoint(scaled_gesture_event.PositionInRootFrame());
EXPECT_EQ(5, position.X());
EXPECT_EQ(6, position.Y());
- EXPECT_EQ(20, scaled_gesture_event.PositionInScreen().x);
- EXPECT_EQ(22, scaled_gesture_event.PositionInScreen().y);
+ EXPECT_EQ(20, scaled_gesture_event.PositionInScreen().x());
+ EXPECT_EQ(22, scaled_gesture_event.PositionInScreen().y());
EXPECT_EQ(15, scaled_gesture_event.DeltaXInRootFrame());
EXPECT_EQ(16, scaled_gesture_event.DeltaYInRootFrame());
// TODO: The velocity values may need to be scaled to page scale in
@@ -191,8 +192,8 @@ TEST(WebInputEventConversionTest, InputEventsScaling) {
WebInputEvent::kGestureScrollEnd, WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- web_gesture_event.SetPositionInWidget(WebFloatPoint(15, 18));
- web_gesture_event.SetPositionInScreen(WebFloatPoint(20, 22));
+ web_gesture_event.SetPositionInWidget(gfx::PointF(15, 18));
+ web_gesture_event.SetPositionInScreen(gfx::PointF(20, 22));
WebGestureEvent scaled_gesture_event =
TransformWebGestureEvent(view, web_gesture_event);
@@ -200,8 +201,8 @@ TEST(WebInputEventConversionTest, InputEventsScaling) {
FlooredIntPoint(scaled_gesture_event.PositionInRootFrame());
EXPECT_EQ(5, position.X());
EXPECT_EQ(6, position.Y());
- EXPECT_EQ(20, scaled_gesture_event.PositionInScreen().x);
- EXPECT_EQ(22, scaled_gesture_event.PositionInScreen().y);
+ EXPECT_EQ(20, scaled_gesture_event.PositionInScreen().x());
+ EXPECT_EQ(22, scaled_gesture_event.PositionInScreen().y());
EXPECT_EQ(WebGestureEvent::InertialPhaseState::kUnknownMomentum,
scaled_gesture_event.InertialPhase());
}
@@ -216,7 +217,8 @@ TEST(WebInputEventConversionTest, InputEventsScaling) {
WebGestureEvent scaled_gesture_event =
TransformWebGestureEvent(view, web_gesture_event);
- IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+ IntSize area =
+ FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
EXPECT_EQ(5, area.Width());
EXPECT_EQ(5, area.Height());
}
@@ -231,7 +233,8 @@ TEST(WebInputEventConversionTest, InputEventsScaling) {
WebGestureEvent scaled_gesture_event =
TransformWebGestureEvent(view, web_gesture_event);
- IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+ IntSize area =
+ FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
EXPECT_EQ(10, area.Width());
EXPECT_EQ(10, area.Height());
}
@@ -246,7 +249,8 @@ TEST(WebInputEventConversionTest, InputEventsScaling) {
WebGestureEvent scaled_gesture_event =
TransformWebGestureEvent(view, web_gesture_event);
- IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+ IntSize area =
+ FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
EXPECT_EQ(3, area.Width());
EXPECT_EQ(3, area.Height());
}
@@ -261,7 +265,8 @@ TEST(WebInputEventConversionTest, InputEventsScaling) {
WebGestureEvent scaled_gesture_event =
TransformWebGestureEvent(view, web_gesture_event);
- IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+ IntSize area =
+ FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
EXPECT_EQ(6, area.Width());
EXPECT_EQ(6, area.Height());
}
@@ -276,7 +281,8 @@ TEST(WebInputEventConversionTest, InputEventsScaling) {
WebGestureEvent scaled_gesture_event =
TransformWebGestureEvent(view, web_gesture_event);
- IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+ IntSize area =
+ FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
EXPECT_EQ(5, area.Width());
EXPECT_EQ(5, area.Height());
}
@@ -291,7 +297,8 @@ TEST(WebInputEventConversionTest, InputEventsScaling) {
WebGestureEvent scaled_gesture_event =
TransformWebGestureEvent(view, web_gesture_event);
- IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+ IntSize area =
+ FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
EXPECT_EQ(5, area.Width());
EXPECT_EQ(5, area.Height());
}
@@ -301,13 +308,13 @@ TEST(WebInputEventConversionTest, InputEventsScaling) {
WebInputEvent::kPointerDown,
WebPointerProperties(1, WebPointerProperties::PointerType::kTouch,
WebPointerProperties::Button::kLeft,
- WebFloatPoint(10.8f, 10.5f),
- WebFloatPoint(10.8f, 10.5f), 30, 30),
+ gfx::PointF(10.8f, 10.5f),
+ gfx::PointF(10.8f, 10.5f), 30, 30),
6.6f, 9.9f);
- EXPECT_FLOAT_EQ(10.8f, web_pointer_event.PositionInScreen().x);
- EXPECT_FLOAT_EQ(10.5f, web_pointer_event.PositionInScreen().y);
- EXPECT_FLOAT_EQ(10.8f, web_pointer_event.PositionInWidget().x);
- EXPECT_FLOAT_EQ(10.5f, web_pointer_event.PositionInWidget().y);
+ EXPECT_FLOAT_EQ(10.8f, web_pointer_event.PositionInScreen().x());
+ EXPECT_FLOAT_EQ(10.5f, web_pointer_event.PositionInScreen().y());
+ EXPECT_FLOAT_EQ(10.8f, web_pointer_event.PositionInWidget().x());
+ EXPECT_FLOAT_EQ(10.5f, web_pointer_event.PositionInWidget().y());
EXPECT_FLOAT_EQ(6.6f, web_pointer_event.width);
EXPECT_FLOAT_EQ(9.9f, web_pointer_event.height);
EXPECT_EQ(30, web_pointer_event.movement_x);
@@ -316,10 +323,10 @@ TEST(WebInputEventConversionTest, InputEventsScaling) {
WebPointerEvent transformed_event =
TransformWebPointerEvent(view, web_pointer_event)
.WebPointerEventInRootFrame();
- EXPECT_FLOAT_EQ(10.8f, transformed_event.PositionInScreen().x);
- EXPECT_FLOAT_EQ(10.5f, transformed_event.PositionInScreen().y);
- EXPECT_FLOAT_EQ(3.6f, transformed_event.PositionInWidget().x);
- EXPECT_FLOAT_EQ(3.5f, transformed_event.PositionInWidget().y);
+ EXPECT_FLOAT_EQ(10.8f, transformed_event.PositionInScreen().x());
+ EXPECT_FLOAT_EQ(10.5f, transformed_event.PositionInScreen().y());
+ EXPECT_FLOAT_EQ(3.6f, transformed_event.PositionInWidget().x());
+ EXPECT_FLOAT_EQ(3.5f, transformed_event.PositionInWidget().y());
EXPECT_FLOAT_EQ(2.2f, transformed_event.width);
EXPECT_FLOAT_EQ(3.3f, transformed_event.height);
EXPECT_EQ(30, transformed_event.movement_x);
@@ -340,7 +347,7 @@ TEST(WebInputEventConversionTest, InputEventsTransform) {
int page_height = 480;
web_view->MainFrameWidget()->Resize(WebSize(page_width, page_height));
web_view->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
web_view->SetPageScaleFactor(2);
@@ -358,12 +365,12 @@ TEST(WebInputEventConversionTest, InputEventsTransform) {
WebMouseEvent transformed_event =
TransformWebMouseEvent(view, web_mouse_event);
- FloatPoint position = transformed_event.PositionInRootFrame();
+ gfx::PointF position = transformed_event.PositionInRootFrame();
- EXPECT_FLOAT_EQ(45, position.X());
- EXPECT_FLOAT_EQ(45, position.Y());
- EXPECT_EQ(90, transformed_event.PositionInScreen().x);
- EXPECT_EQ(90, transformed_event.PositionInScreen().y);
+ EXPECT_FLOAT_EQ(45, position.x());
+ EXPECT_FLOAT_EQ(45, position.y());
+ EXPECT_EQ(90, transformed_event.PositionInScreen().x());
+ EXPECT_EQ(90, transformed_event.PositionInScreen().y());
EXPECT_EQ(60, transformed_event.movement_x);
EXPECT_EQ(60, transformed_event.movement_y);
}
@@ -378,10 +385,10 @@ TEST(WebInputEventConversionTest, InputEventsTransform) {
web_mouse_event1.movement_y = 60;
WebMouseEvent web_mouse_event2 = web_mouse_event1;
- web_mouse_event2.SetPositionInWidget(web_mouse_event1.PositionInWidget().x,
- 120);
- web_mouse_event2.SetPositionInScreen(web_mouse_event1.PositionInScreen().x,
- 120);
+ web_mouse_event2.SetPositionInWidget(
+ web_mouse_event1.PositionInWidget().x(), 120);
+ web_mouse_event2.SetPositionInScreen(
+ web_mouse_event1.PositionInScreen().x(), 120);
web_mouse_event2.movement_y = 30;
WebVector<const WebInputEvent*> events;
@@ -392,20 +399,20 @@ TEST(WebInputEventConversionTest, InputEventsTransform) {
TransformWebMouseEventVector(view, events);
EXPECT_EQ(events.size(), coalescedevents.size());
- FloatPoint position = coalescedevents[0].PositionInRootFrame();
- EXPECT_FLOAT_EQ(45, position.X());
- EXPECT_FLOAT_EQ(45, position.Y());
- EXPECT_EQ(90, coalescedevents[0].PositionInScreen().x);
- EXPECT_EQ(90, coalescedevents[0].PositionInScreen().y);
+ gfx::PointF position = coalescedevents[0].PositionInRootFrame();
+ EXPECT_FLOAT_EQ(45, position.x());
+ EXPECT_FLOAT_EQ(45, position.y());
+ EXPECT_EQ(90, coalescedevents[0].PositionInScreen().x());
+ EXPECT_EQ(90, coalescedevents[0].PositionInScreen().y());
EXPECT_EQ(60, coalescedevents[0].movement_x);
EXPECT_EQ(60, coalescedevents[0].movement_y);
position = coalescedevents[1].PositionInRootFrame();
- EXPECT_FLOAT_EQ(45, position.X());
- EXPECT_FLOAT_EQ(60, position.Y());
- EXPECT_EQ(90, coalescedevents[1].PositionInScreen().x);
- EXPECT_EQ(120, coalescedevents[1].PositionInScreen().y);
+ EXPECT_FLOAT_EQ(45, position.x());
+ EXPECT_FLOAT_EQ(60, position.y());
+ EXPECT_EQ(90, coalescedevents[1].PositionInScreen().x());
+ EXPECT_EQ(120, coalescedevents[1].PositionInScreen().y());
EXPECT_EQ(60, coalescedevents[1].movement_x);
EXPECT_EQ(30, coalescedevents[1].movement_y);
@@ -416,19 +423,19 @@ TEST(WebInputEventConversionTest, InputEventsTransform) {
WebInputEvent::kGestureScrollUpdate, WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- web_gesture_event.SetPositionInWidget(WebFloatPoint(90, 90));
- web_gesture_event.SetPositionInScreen(WebFloatPoint(90, 90));
+ web_gesture_event.SetPositionInWidget(gfx::PointF(90, 90));
+ web_gesture_event.SetPositionInScreen(gfx::PointF(90, 90));
web_gesture_event.data.scroll_update.delta_x = 60;
web_gesture_event.data.scroll_update.delta_y = 60;
WebGestureEvent scaled_gesture_event =
TransformWebGestureEvent(view, web_gesture_event);
- FloatPoint position = scaled_gesture_event.PositionInRootFrame();
+ gfx::PointF position = scaled_gesture_event.PositionInRootFrame();
- EXPECT_FLOAT_EQ(45, position.X());
- EXPECT_FLOAT_EQ(45, position.Y());
- EXPECT_EQ(90, scaled_gesture_event.PositionInScreen().x);
- EXPECT_EQ(90, scaled_gesture_event.PositionInScreen().y);
+ EXPECT_FLOAT_EQ(45, position.x());
+ EXPECT_FLOAT_EQ(45, position.y());
+ EXPECT_EQ(90, scaled_gesture_event.PositionInScreen().x());
+ EXPECT_EQ(90, scaled_gesture_event.PositionInScreen().y());
EXPECT_EQ(30, scaled_gesture_event.DeltaXInRootFrame());
EXPECT_EQ(30, scaled_gesture_event.DeltaYInRootFrame());
}
@@ -443,7 +450,8 @@ TEST(WebInputEventConversionTest, InputEventsTransform) {
WebGestureEvent scaled_gesture_event =
TransformWebGestureEvent(view, web_gesture_event);
- IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+ IntSize area =
+ FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
EXPECT_EQ(15, area.Width());
EXPECT_EQ(15, area.Height());
}
@@ -458,7 +466,8 @@ TEST(WebInputEventConversionTest, InputEventsTransform) {
WebGestureEvent scaled_gesture_event =
TransformWebGestureEvent(view, web_gesture_event);
- IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+ IntSize area =
+ FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
EXPECT_EQ(15, area.Width());
EXPECT_EQ(15, area.Height());
}
@@ -473,7 +482,8 @@ TEST(WebInputEventConversionTest, InputEventsTransform) {
WebGestureEvent scaled_gesture_event =
TransformWebGestureEvent(view, web_gesture_event);
- IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+ IntSize area =
+ FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
EXPECT_EQ(15, area.Width());
EXPECT_EQ(15, area.Height());
}
@@ -488,7 +498,8 @@ TEST(WebInputEventConversionTest, InputEventsTransform) {
WebGestureEvent scaled_gesture_event =
TransformWebGestureEvent(view, web_gesture_event);
- IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+ IntSize area =
+ FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
EXPECT_EQ(15, area.Width());
EXPECT_EQ(15, area.Height());
}
@@ -503,7 +514,8 @@ TEST(WebInputEventConversionTest, InputEventsTransform) {
WebGestureEvent scaled_gesture_event =
TransformWebGestureEvent(view, web_gesture_event);
- IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+ IntSize area =
+ FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
EXPECT_EQ(15, area.Width());
EXPECT_EQ(15, area.Height());
}
@@ -518,7 +530,8 @@ TEST(WebInputEventConversionTest, InputEventsTransform) {
WebGestureEvent scaled_gesture_event =
TransformWebGestureEvent(view, web_gesture_event);
- IntSize area = FlooredIntSize(scaled_gesture_event.TapAreaInRootFrame());
+ IntSize area =
+ FlooredIntSize(FloatSize(scaled_gesture_event.TapAreaInRootFrame()));
EXPECT_EQ(15, area.Width());
EXPECT_EQ(15, area.Height());
}
@@ -528,17 +541,17 @@ TEST(WebInputEventConversionTest, InputEventsTransform) {
WebInputEvent::kPointerDown,
WebPointerProperties(1, WebPointerProperties::PointerType::kTouch,
WebPointerProperties::Button::kLeft,
- WebFloatPoint(90, 90), WebFloatPoint(90, 90)),
+ gfx::PointF(90, 90), gfx::PointF(90, 90)),
30, 30);
WebPointerEvent transformed_event =
TransformWebPointerEvent(view, web_pointer_event)
.WebPointerEventInRootFrame();
- EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().x);
- EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().y);
- EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().x);
- EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().y);
+ EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().x());
+ EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().y());
+ EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().x());
+ EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().y());
EXPECT_FLOAT_EQ(15, transformed_event.width);
EXPECT_FLOAT_EQ(15, transformed_event.height);
}
@@ -548,14 +561,14 @@ TEST(WebInputEventConversionTest, InputEventsTransform) {
WebInputEvent::kPointerDown,
WebPointerProperties(1, WebPointerProperties::PointerType::kTouch,
WebPointerProperties::Button::kLeft,
- WebFloatPoint(90, 90), WebFloatPoint(90, 90)),
+ gfx::PointF(90, 90), gfx::PointF(90, 90)),
30, 30);
WebPointerEvent web_pointer_event2(
WebInputEvent::kPointerDown,
WebPointerProperties(1, WebPointerProperties::PointerType::kTouch,
WebPointerProperties::Button::kLeft,
- WebFloatPoint(120, 90), WebFloatPoint(120, 90)),
+ gfx::PointF(120, 90), gfx::PointF(120, 90)),
60, 30);
WebVector<const WebInputEvent*> events;
@@ -568,18 +581,18 @@ TEST(WebInputEventConversionTest, InputEventsTransform) {
WebPointerEvent transformed_event =
coalescedevents[0].WebPointerEventInRootFrame();
- EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().x);
- EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().y);
- EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().x);
- EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().y);
+ EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().x());
+ EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().y());
+ EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().x());
+ EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().y());
EXPECT_FLOAT_EQ(15, transformed_event.width);
EXPECT_FLOAT_EQ(15, transformed_event.height);
transformed_event = coalescedevents[1].WebPointerEventInRootFrame();
- EXPECT_FLOAT_EQ(120, transformed_event.PositionInScreen().x);
- EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().y);
- EXPECT_FLOAT_EQ(60, transformed_event.PositionInWidget().x);
- EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().y);
+ EXPECT_FLOAT_EQ(120, transformed_event.PositionInScreen().x());
+ EXPECT_FLOAT_EQ(90, transformed_event.PositionInScreen().y());
+ EXPECT_FLOAT_EQ(60, transformed_event.PositionInWidget().x());
+ EXPECT_FLOAT_EQ(45, transformed_event.PositionInWidget().y());
EXPECT_FLOAT_EQ(30, transformed_event.width);
EXPECT_FLOAT_EQ(15, transformed_event.height);
}
@@ -597,7 +610,7 @@ TEST(WebInputEventConversionTest, InputEventsConversions) {
int page_height = 480;
web_view->MainFrameWidget()->Resize(WebSize(page_width, page_height));
web_view->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
LocalFrameView* view =
To<LocalFrame>(web_view->GetPage()->MainFrame())->View();
@@ -606,8 +619,8 @@ TEST(WebInputEventConversionTest, InputEventsConversions) {
WebInputEvent::kGestureTap, WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- web_gesture_event.SetPositionInWidget(WebFloatPoint(10, 10));
- web_gesture_event.SetPositionInScreen(WebFloatPoint(10, 10));
+ web_gesture_event.SetPositionInWidget(gfx::PointF(10, 10));
+ web_gesture_event.SetPositionInScreen(gfx::PointF(10, 10));
web_gesture_event.data.tap.tap_count = 1;
web_gesture_event.data.tap.width = 10;
web_gesture_event.data.tap.height = 10;
@@ -618,8 +631,8 @@ TEST(WebInputEventConversionTest, InputEventsConversions) {
FlooredIntPoint(scaled_gesture_event.PositionInRootFrame());
EXPECT_EQ(10.f, position.X());
EXPECT_EQ(10.f, position.Y());
- EXPECT_EQ(10.f, scaled_gesture_event.PositionInScreen().x);
- EXPECT_EQ(10.f, scaled_gesture_event.PositionInScreen().y);
+ EXPECT_EQ(10.f, scaled_gesture_event.PositionInScreen().x());
+ EXPECT_EQ(10.f, scaled_gesture_event.PositionInScreen().y());
EXPECT_EQ(1, scaled_gesture_event.TapCount());
}
}
@@ -636,7 +649,7 @@ TEST(WebInputEventConversionTest, VisualViewportOffset) {
int page_height = 480;
web_view->MainFrameWidget()->Resize(WebSize(page_width, page_height));
web_view->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
web_view->SetPageScaleFactor(2);
@@ -659,8 +672,8 @@ TEST(WebInputEventConversionTest, VisualViewportOffset) {
FlooredIntPoint(transformed_mouse_event.PositionInRootFrame());
EXPECT_EQ(5 + visual_offset.X(), position.X());
EXPECT_EQ(5 + visual_offset.Y(), position.Y());
- EXPECT_EQ(10, transformed_mouse_event.PositionInScreen().x);
- EXPECT_EQ(10, transformed_mouse_event.PositionInScreen().y);
+ EXPECT_EQ(10, transformed_mouse_event.PositionInScreen().x());
+ EXPECT_EQ(10, transformed_mouse_event.PositionInScreen().y());
}
{
@@ -676,8 +689,8 @@ TEST(WebInputEventConversionTest, VisualViewportOffset) {
FlooredIntPoint(scaled_mouse_wheel_event.PositionInRootFrame());
EXPECT_EQ(5 + visual_offset.X(), position.X());
EXPECT_EQ(5 + visual_offset.Y(), position.Y());
- EXPECT_EQ(10, scaled_mouse_wheel_event.PositionInScreen().x);
- EXPECT_EQ(10, scaled_mouse_wheel_event.PositionInScreen().y);
+ EXPECT_EQ(10, scaled_mouse_wheel_event.PositionInScreen().x());
+ EXPECT_EQ(10, scaled_mouse_wheel_event.PositionInScreen().y());
}
{
@@ -685,8 +698,8 @@ TEST(WebInputEventConversionTest, VisualViewportOffset) {
WebInputEvent::kGestureScrollUpdate, WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- web_gesture_event.SetPositionInWidget(WebFloatPoint(10, 10));
- web_gesture_event.SetPositionInScreen(WebFloatPoint(10, 10));
+ web_gesture_event.SetPositionInWidget(gfx::PointF(10, 10));
+ web_gesture_event.SetPositionInScreen(gfx::PointF(10, 10));
WebGestureEvent scaled_gesture_event =
TransformWebGestureEvent(view, web_gesture_event);
@@ -694,8 +707,8 @@ TEST(WebInputEventConversionTest, VisualViewportOffset) {
FlooredIntPoint(scaled_gesture_event.PositionInRootFrame());
EXPECT_EQ(5 + visual_offset.X(), position.X());
EXPECT_EQ(5 + visual_offset.Y(), position.Y());
- EXPECT_EQ(10, scaled_gesture_event.PositionInScreen().x);
- EXPECT_EQ(10, scaled_gesture_event.PositionInScreen().y);
+ EXPECT_EQ(10, scaled_gesture_event.PositionInScreen().x());
+ EXPECT_EQ(10, scaled_gesture_event.PositionInScreen().y());
}
{
@@ -703,24 +716,24 @@ TEST(WebInputEventConversionTest, VisualViewportOffset) {
WebInputEvent::kPointerDown,
WebPointerProperties(1, WebPointerProperties::PointerType::kTouch,
WebPointerProperties::Button::kLeft,
- WebFloatPoint(10.6f, 10.4f),
- WebFloatPoint(10.6f, 10.4f)),
+ gfx::PointF(10.6f, 10.4f),
+ gfx::PointF(10.6f, 10.4f)),
10, 10);
- EXPECT_FLOAT_EQ(10.6f, web_pointer_event.PositionInScreen().x);
- EXPECT_FLOAT_EQ(10.4f, web_pointer_event.PositionInScreen().y);
- EXPECT_FLOAT_EQ(10.6f, web_pointer_event.PositionInWidget().x);
- EXPECT_FLOAT_EQ(10.4f, web_pointer_event.PositionInWidget().y);
+ EXPECT_FLOAT_EQ(10.6f, web_pointer_event.PositionInScreen().x());
+ EXPECT_FLOAT_EQ(10.4f, web_pointer_event.PositionInScreen().y());
+ EXPECT_FLOAT_EQ(10.6f, web_pointer_event.PositionInWidget().x());
+ EXPECT_FLOAT_EQ(10.4f, web_pointer_event.PositionInWidget().y());
WebPointerEvent transformed_event =
TransformWebPointerEvent(view, web_pointer_event)
.WebPointerEventInRootFrame();
- EXPECT_FLOAT_EQ(10.6f, transformed_event.PositionInScreen().x);
- EXPECT_FLOAT_EQ(10.4f, transformed_event.PositionInScreen().y);
+ EXPECT_FLOAT_EQ(10.6f, transformed_event.PositionInScreen().x());
+ EXPECT_FLOAT_EQ(10.4f, transformed_event.PositionInScreen().y());
EXPECT_FLOAT_EQ(5.3f + visual_offset.X(),
- transformed_event.PositionInWidget().x);
+ transformed_event.PositionInWidget().x());
EXPECT_FLOAT_EQ(5.2f + visual_offset.Y(),
- transformed_event.PositionInWidget().y);
+ transformed_event.PositionInWidget().y());
}
}
@@ -736,13 +749,13 @@ TEST(WebInputEventConversionTest, ElasticOverscroll) {
int page_height = 480;
web_view->MainFrameWidget()->Resize(WebSize(page_width, page_height));
web_view->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
LocalFrameView* view =
To<LocalFrame>(web_view->GetPage()->MainFrame())->View();
gfx::Vector2dF elastic_overscroll(10, -20);
- web_view->MainFrameWidget()->ApplyViewportChanges(
+ web_view->MainFrameWidget()->ApplyViewportChangesForTesting(
{gfx::ScrollOffset(), elastic_overscroll, 1.0f, false, 0.0f});
// Just elastic overscroll.
@@ -758,14 +771,14 @@ TEST(WebInputEventConversionTest, ElasticOverscroll) {
IntPoint position =
FlooredIntPoint(transformed_mouse_event.PositionInRootFrame());
- EXPECT_EQ(web_mouse_event.PositionInWidget().x + elastic_overscroll.x(),
+ EXPECT_EQ(web_mouse_event.PositionInWidget().x() + elastic_overscroll.x(),
position.X());
- EXPECT_EQ(web_mouse_event.PositionInWidget().y + elastic_overscroll.y(),
+ EXPECT_EQ(web_mouse_event.PositionInWidget().y() + elastic_overscroll.y(),
position.Y());
- EXPECT_EQ(web_mouse_event.PositionInScreen().x,
- transformed_mouse_event.PositionInScreen().x);
- EXPECT_EQ(web_mouse_event.PositionInScreen().y,
- transformed_mouse_event.PositionInScreen().y);
+ EXPECT_EQ(web_mouse_event.PositionInScreen().x(),
+ transformed_mouse_event.PositionInScreen().x());
+ EXPECT_EQ(web_mouse_event.PositionInScreen().y(),
+ transformed_mouse_event.PositionInScreen().y());
}
// Elastic overscroll and pinch-zoom (this doesn't actually ever happen,
@@ -787,16 +800,16 @@ TEST(WebInputEventConversionTest, ElasticOverscroll) {
IntPoint position =
FlooredIntPoint(transformed_mouse_event.PositionInRootFrame());
- EXPECT_EQ(web_mouse_event.PositionInWidget().x / page_scale +
+ EXPECT_EQ(web_mouse_event.PositionInWidget().x() / page_scale +
visual_offset.X() + elastic_overscroll.x(),
position.X());
- EXPECT_EQ(web_mouse_event.PositionInWidget().y / page_scale +
+ EXPECT_EQ(web_mouse_event.PositionInWidget().y() / page_scale +
visual_offset.Y() + elastic_overscroll.y(),
position.Y());
- EXPECT_EQ(web_mouse_event.PositionInScreen().x,
- transformed_mouse_event.PositionInScreen().x);
- EXPECT_EQ(web_mouse_event.PositionInScreen().y,
- transformed_mouse_event.PositionInScreen().y);
+ EXPECT_EQ(web_mouse_event.PositionInScreen().x(),
+ transformed_mouse_event.PositionInScreen().x());
+ EXPECT_EQ(web_mouse_event.PositionInScreen().y(),
+ transformed_mouse_event.PositionInScreen().y());
}
}
@@ -813,10 +826,10 @@ TEST(WebInputEventConversionTest, ElasticOverscrollWithPageReload) {
int page_height = 480;
web_view->MainFrameWidget()->Resize(WebSize(page_width, page_height));
web_view->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
gfx::Vector2dF elastic_overscroll(10, -20);
- web_view->MainFrameWidget()->ApplyViewportChanges(
+ web_view->MainFrameWidget()->ApplyViewportChangesForTesting(
{gfx::ScrollOffset(), elastic_overscroll, 1.0f, false, 0.0f});
frame_test_helpers::ReloadFrame(
web_view_helper.GetWebView()->MainFrameImpl());
@@ -836,14 +849,14 @@ TEST(WebInputEventConversionTest, ElasticOverscrollWithPageReload) {
IntPoint position =
FlooredIntPoint(transformed_mouse_event.PositionInRootFrame());
- EXPECT_EQ(web_mouse_event.PositionInWidget().x + elastic_overscroll.x(),
+ EXPECT_EQ(web_mouse_event.PositionInWidget().x() + elastic_overscroll.x(),
position.X());
- EXPECT_EQ(web_mouse_event.PositionInWidget().y + elastic_overscroll.y(),
+ EXPECT_EQ(web_mouse_event.PositionInWidget().y() + elastic_overscroll.y(),
position.Y());
- EXPECT_EQ(web_mouse_event.PositionInScreen().x,
- transformed_mouse_event.PositionInScreen().x);
- EXPECT_EQ(web_mouse_event.PositionInScreen().y,
- transformed_mouse_event.PositionInScreen().y);
+ EXPECT_EQ(web_mouse_event.PositionInScreen().x(),
+ transformed_mouse_event.PositionInScreen().x());
+ EXPECT_EQ(web_mouse_event.PositionInScreen().y(),
+ transformed_mouse_event.PositionInScreen().y());
}
}
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 bdd390e7103..b1a96aac0ba 100644
--- a/chromium/third_party/blink/renderer/core/events/wheel_event.cc
+++ b/chromium/third_party/blink/renderer/core/events/wheel_event.cc
@@ -23,6 +23,7 @@
#include "third_party/blink/renderer/core/events/wheel_event.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_wheel_event_init.h"
#include "third_party/blink/renderer/core/clipboard/data_transfer.h"
#include "third_party/blink/renderer/core/dom/events/event_dispatcher.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
@@ -37,12 +38,10 @@ namespace {
unsigned ConvertDeltaMode(const WebMouseWheelEvent& event) {
// WebMouseWheelEvent only supports these units for the delta.
- DCHECK(
- event.delta_units == ui::input_types::ScrollGranularity::kScrollByPage ||
- event.delta_units == ui::input_types::ScrollGranularity::kScrollByPixel ||
- event.delta_units ==
- ui::input_types::ScrollGranularity::kScrollByPrecisePixel);
- return event.delta_units == ui::input_types::ScrollGranularity::kScrollByPage
+ DCHECK(event.delta_units == ui::ScrollGranularity::kScrollByPage ||
+ event.delta_units == ui::ScrollGranularity::kScrollByPixel ||
+ event.delta_units == ui::ScrollGranularity::kScrollByPrecisePixel);
+ return event.delta_units == ui::ScrollGranularity::kScrollByPage
? WheelEvent::kDomDeltaPage
: WheelEvent::kDomDeltaPixel;
}
@@ -85,6 +84,12 @@ WheelEvent* WheelEvent::Create(const WebMouseWheelEvent& event,
return MakeGarbageCollected<WheelEvent>(event, view);
}
+WheelEvent* WheelEvent::Create(const WebMouseWheelEvent& event,
+ const gfx::Vector2dF& delta_in_pixels,
+ AbstractView* view) {
+ return MakeGarbageCollected<WheelEvent>(event, delta_in_pixels, view);
+}
+
WheelEvent::WheelEvent()
: delta_x_(0), delta_y_(0), delta_z_(0), delta_mode_(kDomDeltaPixel) {}
@@ -118,6 +123,20 @@ WheelEvent::WheelEvent(const WebMouseWheelEvent& event, AbstractView* view)
delta_mode_(ConvertDeltaMode(event)),
native_event_(event) {}
+WheelEvent::WheelEvent(const WebMouseWheelEvent& event,
+ const gfx::Vector2dF& delta_in_pixels,
+ AbstractView* view)
+ : MouseEvent(event_type_names::kWheel,
+ GetMouseEventInitForWheel(event, view),
+ event.TimeStamp()),
+ wheel_delta_(event.wheel_ticks_x * kTickMultiplier,
+ event.wheel_ticks_y * kTickMultiplier),
+ delta_x_(delta_in_pixels.x()),
+ delta_y_(delta_in_pixels.y()),
+ delta_z_(0),
+ delta_mode_(WheelEvent::kDomDeltaPixel),
+ native_event_(event) {}
+
const AtomicString& WheelEvent::InterfaceName() const {
return event_interface_names::kWheelEvent;
}
@@ -163,7 +182,7 @@ DispatchEventResult WheelEvent::DispatchEvent(EventDispatcher& dispatcher) {
return dispatcher.Dispatch();
}
-void WheelEvent::Trace(blink::Visitor* visitor) {
+void WheelEvent::Trace(Visitor* visitor) {
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 63b491203de..357825d5275 100644
--- a/chromium/third_party/blink/renderer/core/events/wheel_event.h
+++ b/chromium/third_party/blink/renderer/core/events/wheel_event.h
@@ -26,19 +26,21 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_WHEEL_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_WHEEL_EVENT_H_
-#include "third_party/blink/public/platform/web_mouse_wheel_event.h"
+#include "third_party/blink/public/common/input/web_mouse_wheel_event.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/events/mouse_event.h"
-#include "third_party/blink/renderer/core/events/wheel_event_init.h"
#include "third_party/blink/renderer/platform/geometry/float_point.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
+class WheelEventInit;
+
class CORE_EXPORT WheelEvent final : public MouseEvent {
DEFINE_WRAPPERTYPEINFO();
public:
- enum { kTickMultiplier = 120 };
+ constexpr static int kTickMultiplier = 120;
enum DeltaMode { kDomDeltaPixel = 0, kDomDeltaLine, kDomDeltaPage };
@@ -47,6 +49,10 @@ class CORE_EXPORT WheelEvent final : public MouseEvent {
static WheelEvent* Create(const WebMouseWheelEvent& native_event,
AbstractView*);
+ static WheelEvent* Create(const WebMouseWheelEvent& native_event,
+ const gfx::Vector2dF& delta_in_pixels,
+ AbstractView*);
+
static WheelEvent* Create(const AtomicString& type,
const WheelEventInit* initializer) {
return MakeGarbageCollected<WheelEvent>(type, initializer);
@@ -55,6 +61,9 @@ class CORE_EXPORT WheelEvent final : public MouseEvent {
WheelEvent();
WheelEvent(const AtomicString&, const WheelEventInit*);
WheelEvent(const WebMouseWheelEvent&, AbstractView*);
+ WheelEvent(const WebMouseWheelEvent&,
+ const gfx::Vector2dF& delta_in_pixels,
+ AbstractView*);
double deltaX() const { return delta_x_; } // Positive when scrolling right.
double deltaY() const { return delta_y_; } // Positive when scrolling down.
@@ -82,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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
IntPoint wheel_delta_;
@@ -93,7 +102,10 @@ class CORE_EXPORT WheelEvent final : public MouseEvent {
WebMouseWheelEvent native_event_;
};
-DEFINE_EVENT_TYPE_CASTS(WheelEvent);
+template <>
+struct DowncastTraits<WheelEvent> {
+ static bool AllowFrom(const Event& event) { return event.IsWheelEvent(); }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/events/wheel_event.idl b/chromium/third_party/blink/renderer/core/events/wheel_event.idl
index c95ebd897a2..8ad0c31b739 100644
--- a/chromium/third_party/blink/renderer/core/events/wheel_event.idl
+++ b/chromium/third_party/blink/renderer/core/events/wheel_event.idl
@@ -22,9 +22,9 @@
// https://w3c.github.io/uievents/#interface-WheelEvent
[
- Constructor(DOMString type, optional WheelEventInit eventInitDict),
Exposed=Window
] interface WheelEvent : MouseEvent {
+ constructor(DOMString type, optional WheelEventInit eventInitDict = {});
// DeltaModeCode
const unsigned long DOM_DELTA_PIXEL = 0x00;
const unsigned long DOM_DELTA_LINE = 0x01;
diff --git a/chromium/third_party/blink/renderer/core/execution_context/BUILD.gn b/chromium/third_party/blink/renderer/core/execution_context/BUILD.gn
index 504e53734ca..88dfb8a31e1 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/execution_context/BUILD.gn
@@ -10,18 +10,18 @@ blink_core_sources("execution_context") {
"agent.h",
"agent_metrics_collector.cc",
"agent_metrics_collector.h",
- "context_lifecycle_notifier.cc",
- "context_lifecycle_notifier.h",
- "context_lifecycle_observer.cc",
- "context_lifecycle_observer.h",
- "context_lifecycle_state_observer.cc",
- "context_lifecycle_state_observer.h",
"execution_context.cc",
"execution_context.h",
+ "execution_context_lifecycle_observer.cc",
+ "execution_context_lifecycle_observer.h",
+ "execution_context_lifecycle_state_observer.cc",
+ "execution_context_lifecycle_state_observer.h",
"remote_security_context.cc",
"remote_security_context.h",
"security_context.cc",
"security_context.h",
+ "security_context_init.cc",
+ "security_context_init.h",
"window_agent.cc",
"window_agent.h",
"window_agent_factory.cc",
diff --git a/chromium/third_party/blink/renderer/core/execution_context/PausingAndFreezing.md b/chromium/third_party/blink/renderer/core/execution_context/PausingAndFreezing.md
index b9ebc9c9fb6..c400230bd4e 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/PausingAndFreezing.md
+++ b/chromium/third_party/blink/renderer/core/execution_context/PausingAndFreezing.md
@@ -18,17 +18,17 @@ There are 4 lifecycle states [defined](https://cs.chromium.org/chromium/src/thir
## kPaused
* Used for synchronous mechanisms for a single thread, eg. window.print, V8 inspector debugging.
-* Fires [ContextLifecycleStateObserver][ContextLifecycleStateObserver] changed for kPaused.
-* Some [ContextLifecycleStateObserver][ContextLifecycleStateObserver] may drop mojo connections.
+* Fires [ExecutionContextLifecycleStateObserver][ExecutionContextLifecycleStateObserver] changed for kPaused.
+* Some [ExecutionContextLifecycleStateObserver][ExecutionContextLifecycleStateObserver] may drop mojo connections.
* Not visible to page in terms of state transitions.
* Does *not* [freeze](https://wicg.github.io/page-lifecycle/spec.html#freeze-steps) or [resume](https://wicg.github.io/page-lifecycle/spec.html#resume-steps) the document.
* Pauses execution of [pausable task queues][TaskQueues] in MainThreadScheduler.
## kFrozen
* Used iframe feature policies, Resource Coordinator background policies. (Should be used for bfcache in the future)
-* Fires [ContextLifecycleStateObserver][ContextLifecycleStateObserver] change for kFrozen.
+* Fires [ExecutionContextLifecycleStateObserver][ExecutionContextLifecycleStateObserver] change for kFrozen.
* Executes [freeze](https://wicg.github.io/page-lifecycle/spec.html#freeze-steps) and [resume](https://wicg.github.io/page-lifecycle/spec.html#resume-steps) algorithms.
-* [Dedicated workers][DedicatedWorker] freeze via a [ContextLifecycleStateObserver][ContextLifecycleStateObserver] callback.
+* [Dedicated workers][DedicatedWorker] freeze via a [ExecutionContextLifecycleStateObserver][ExecutionContextLifecycleStateObserver] callback.
* Freezes execution of [frozen task queues][TaskQueues] in MainThreadScheduler.
* Pauses execution of [pausable task queues][TaskQueues] in MainThreadScheduler. (This is a proposed feature, with it we would remove the definition of frozen
task queues in the scheduler).
@@ -58,11 +58,11 @@ In order to freeze a worker/worklet an implementation will pauses execution of a
nested event loop. Only the none pausable tasks will execute in the nested event loop. Explicitly the Internal Worker task queue will
be used to resume the worker.
-To freeze workers the Workers themselves are [ContextLifecycleStateObservers][ContextLifecycleStateObserver] and they listen to
+To freeze workers the Workers themselves are [ExecutionContextLifecycleStateObservers][ExecutionContextLifecycleStateObserver] and they listen to
the kFrozen/kResume state of the owning execution context and then propagate that to their own execution context.
-[ContextLifecycleStateObserver]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.h
+[ExecutionContextLifecycleStateObserver]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h
[DedicatedWorker]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/workers/dedicated_worker.h
[PageScheduler]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
[TaskQueues]: https://chromium.googlesource.com/chromium/src/+/HEAD/third_party/blink/public/platform/TaskTypes.md
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 d4684a579a6..d25e979d9a4 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/agent.cc
+++ b/chromium/third_party/blink/renderer/core/execution_context/agent.cc
@@ -4,8 +4,8 @@
#include "third_party/blink/renderer/core/execution_context/agent.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/execution_context/execution_context.h"
#include "third_party/blink/renderer/platform/scheduler/public/event_loop.h"
namespace blink {
@@ -21,12 +21,12 @@ Agent::~Agent() = default;
void Agent::Trace(Visitor* visitor) {}
-void Agent::AttachExecutionContext(ExecutionContext* execution_context) {
- event_loop_->AttachScheduler(execution_context->GetScheduler());
+void Agent::AttachDocument(Document* document) {
+ event_loop_->AttachScheduler(document->GetScheduler());
}
-void Agent::DetachExecutionContext(ExecutionContext* execution_context) {
- event_loop_->DetachScheduler(execution_context->GetScheduler());
+void Agent::DetachDocument(Document* document) {
+ event_loop_->DetachScheduler(document->GetScheduler());
}
} // 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 5874d96961b..8adc23aa3ad 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 ExecutionContext;
+class Document;
// Corresponding spec concept is:
// https://html.spec.whatwg.org/C#integration-with-the-javascript-agent-formalism
@@ -31,16 +31,8 @@ class ExecutionContext;
// Agent is shared across a group of reachable and same-site frames.
class CORE_EXPORT Agent : public GarbageCollected<Agent> {
public:
- static Agent* CreateForWorkerOrWorklet(
- v8::Isolate* isolate,
- const base::UnguessableToken& cluster_id,
- std::unique_ptr<v8::MicrotaskQueue> microtask_queue = nullptr) {
- return MakeGarbageCollected<Agent>(isolate, cluster_id,
- std::move(microtask_queue));
- }
-
// Do not create the instance directly.
- // Use Agent::CreateForWorkerOrWorklet() or
+ // Use MakeGarbageCollected<Agent>() or
// WindowAgentFactory::GetAgentForOrigin().
Agent(v8::Isolate* isolate,
const base::UnguessableToken& cluster_id,
@@ -51,10 +43,10 @@ class CORE_EXPORT Agent : public GarbageCollected<Agent> {
return event_loop_;
}
- virtual void Trace(blink::Visitor*);
+ virtual void Trace(Visitor*);
- void AttachExecutionContext(ExecutionContext*);
- void DetachExecutionContext(ExecutionContext*);
+ void AttachDocument(Document*);
+ void DetachDocument(Document*);
const base::UnguessableToken& cluster_id() const { return 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 bd5ecee9fc4..202a52d8614 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
@@ -169,7 +169,7 @@ AgentMetricsCollector::GetAgentMetricsCollectorHost() {
return agent_metrics_collector_host_;
}
-void AgentMetricsCollector::Trace(blink::Visitor* visitor) {
+void AgentMetricsCollector::Trace(Visitor* visitor) {
visitor->Trace(agent_to_documents_map_);
}
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 a35b1cf437e..b92e88b857d 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
@@ -53,7 +53,7 @@ class AgentMetricsCollector final
void SetTickClockForTesting(const base::TickClock* clock) { clock_ = clock; }
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
void AddTimeToTotalAgents(int time_delta_to_add);
diff --git a/chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_notifier.cc b/chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_notifier.cc
deleted file mode 100644
index 187b7f52239..00000000000
--- a/chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_notifier.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- * 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:
- * 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.
- *
- */
-
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_notifier.h"
-
-#include "base/auto_reset.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.h"
-
-namespace blink {
-
-void ContextLifecycleNotifier::NotifyContextLifecycleStateChanged(
- mojom::FrameLifecycleState state) {
- ForEachObserver([&](ContextLifecycleObserver* observer) {
- if (observer->ObserverType() != ContextLifecycleObserver::kStateObjectType)
- return;
- ContextLifecycleStateObserver* state_observer =
- static_cast<ContextLifecycleStateObserver*>(observer);
-#if DCHECK_IS_ON()
- DCHECK_EQ(state_observer->GetExecutionContext(), Context());
- DCHECK(state_observer->UpdateStateIfNeededCalled());
-#endif
- state_observer->ContextLifecycleStateChanged(state);
- });
-}
-
-unsigned ContextLifecycleNotifier::ContextLifecycleStateObserverCount() const {
- DCHECK(!IsIteratingOverObservers());
- unsigned pausable_objects = 0;
- ForEachObserver([&](ContextLifecycleObserver* observer) {
- if (observer->ObserverType() != ContextLifecycleObserver::kStateObjectType)
- return;
- pausable_objects++;
- });
- return pausable_objects;
-}
-
-#if DCHECK_IS_ON()
-bool ContextLifecycleNotifier::Contains(
- ContextLifecycleStateObserver* object) const {
- DCHECK(!IsIteratingOverObservers());
- bool found = false;
- ForEachObserver([&](ContextLifecycleObserver* observer) {
- if (observer->ObserverType() != ContextLifecycleObserver::kStateObjectType)
- return;
- ContextLifecycleStateObserver* state_observer =
- static_cast<ContextLifecycleStateObserver*>(observer);
- if (state_observer == object)
- found = true;
- });
- return found;
-}
-#endif
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_notifier.h b/chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_notifier.h
deleted file mode 100644
index 3c2a6616a5d..00000000000
--- a/chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_notifier.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- * 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:
- * 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_CORE_EXECUTION_CONTEXT_CONTEXT_LIFECYCLE_NOTIFIER_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_EXECUTION_CONTEXT_CONTEXT_LIFECYCLE_NOTIFIER_H_
-
-#include "base/macros.h"
-#include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink-forward.h"
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/platform/lifecycle_notifier.h"
-
-namespace blink {
-
-class ContextLifecycleObserver;
-class ContextLifecycleStateObserver;
-class ExecutionContext;
-
-class CORE_EXPORT ContextLifecycleNotifier
- : public LifecycleNotifier<ExecutionContext, ContextLifecycleObserver> {
- public:
- void NotifyContextLifecycleStateChanged(mojom::FrameLifecycleState state);
-
- unsigned ContextLifecycleStateObserverCount() const;
-
-#if DCHECK_IS_ON()
- bool Contains(ContextLifecycleStateObserver*) const;
-#endif
- protected:
- // Need a default constructor to link core and modules separately.
- // If no default constructor, we will see an error: "constructor for
- // 'blink::ExecutionContext' must explicitly initialize the base class
- // 'blink::ContextLifecycleNotifier' which does not have a default
- // constructor ExecutionContext::ExecutionContext()".
- ContextLifecycleNotifier() = default;
-
- DISALLOW_COPY_AND_ASSIGN(ContextLifecycleNotifier);
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EXECUTION_CONTEXT_CONTEXT_LIFECYCLE_NOTIFIER_H_
diff --git a/chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_observer.cc b/chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_observer.cc
deleted file mode 100644
index 716c08435ff..00000000000
--- a/chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_observer.cc
+++ /dev/null
@@ -1,63 +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/execution_context/context_lifecycle_observer.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"
-
-namespace blink {
-
-ContextClient::ContextClient(ExecutionContext* execution_context)
- : execution_context_(execution_context) {}
-
-ContextClient::ContextClient(LocalFrame* frame)
- : execution_context_(frame ? frame->GetDocument() : nullptr) {}
-
-ExecutionContext* ContextClient::GetExecutionContext() const {
- return execution_context_ && !execution_context_->IsContextDestroyed()
- ? execution_context_.Get()
- : nullptr;
-}
-
-Document* ContextClient::GetDocument() const {
- return execution_context_
- ? DynamicTo<Document>(
- static_cast<ExecutionContext*>(execution_context_))
- : nullptr;
-}
-
-LocalFrame* ContextClient::GetFrame() const {
- auto* document = GetDocument();
- return document ? document->GetFrame() : nullptr;
-}
-
-void ContextClient::Trace(Visitor* visitor) {
- visitor->Trace(execution_context_);
-}
-
-LocalFrame* ContextLifecycleObserver::GetFrame() const {
- auto* document = DynamicTo<Document>(GetExecutionContext());
- return document ? document->GetFrame() : nullptr;
-}
-
-DOMWindowClient::DOMWindowClient(LocalDOMWindow* window)
- : dom_window_(window) {}
-
-DOMWindowClient::DOMWindowClient(LocalFrame* frame)
- : dom_window_(frame ? frame->DomWindow() : nullptr) {}
-
-LocalDOMWindow* DOMWindowClient::DomWindow() const {
- return dom_window_ && dom_window_->GetFrame() ? dom_window_ : nullptr;
-}
-
-LocalFrame* DOMWindowClient::GetFrame() const {
- return dom_window_ ? dom_window_->GetFrame() : nullptr;
-}
-
-void DOMWindowClient::Trace(Visitor* visitor) {
- visitor->Trace(dom_window_);
-}
-} // 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 2bfec434ddd..eaa55b5533c 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
@@ -27,14 +27,17 @@
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "base/metrics/histogram_macros.h"
+#include "third_party/blink/public/common/feature_policy/document_policy_features.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink.h"
+#include "third_party/blink/public/mojom/feature_policy/policy_disposition.mojom-blink.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/events/error_event.h"
#include "third_party/blink/renderer/core/execution_context/agent.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h"
#include "third_party/blink/renderer/core/fileapi/public_url_manager.h"
#include "third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
@@ -43,6 +46,7 @@
#include "third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/core/workers/worker_thread.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/fetch_client_settings_object_snapshot.h"
#include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
@@ -51,22 +55,15 @@
namespace blink {
-ExecutionContext::ExecutionContext(v8::Isolate* isolate,
- Agent* agent,
- OriginTrialContext* origin_trial_context)
+ExecutionContext::ExecutionContext(v8::Isolate* isolate)
: isolate_(isolate),
circular_sequential_id_(0),
in_dispatch_error_event_(false),
lifecycle_state_(mojom::FrameLifecycleState::kRunning),
is_context_destroyed_(false),
csp_delegate_(MakeGarbageCollected<ExecutionContextCSPDelegate>(*this)),
- agent_(agent),
- origin_trial_context_(origin_trial_context),
window_interaction_tokens_(0),
- referrer_policy_(network::mojom::ReferrerPolicy::kDefault) {
- if (origin_trial_context_)
- origin_trial_context_->BindExecutionContext(this);
-}
+ referrer_policy_(network::mojom::ReferrerPolicy::kDefault) {}
ExecutionContext::~ExecutionContext() = default;
@@ -77,6 +74,11 @@ ExecutionContext* ExecutionContext::From(const ScriptState* script_state) {
}
// static
+ExecutionContext* ExecutionContext::From(v8::Local<v8::Context> context) {
+ return ToExecutionContext(context);
+}
+
+// static
ExecutionContext* ExecutionContext::ForCurrentRealm(
const v8::FunctionCallbackInfo<v8::Value>& info) {
return ToExecutionContext(info.GetIsolate()->GetCurrentContext());
@@ -89,31 +91,73 @@ ExecutionContext* ExecutionContext::ForRelevantRealm(
}
void ExecutionContext::SetLifecycleState(mojom::FrameLifecycleState state) {
- bool was_paused = lifecycle_state_ != mojom::FrameLifecycleState::kRunning;
+ DCHECK(lifecycle_state_ != state);
lifecycle_state_ = state;
- NotifyContextLifecycleStateChanged(state);
- bool paused = lifecycle_state_ != mojom::FrameLifecycleState::kRunning;
-
- if (was_paused == paused)
- return;
-
- if (paused)
- TasksWerePaused();
- else
- TasksWereUnpaused();
+ context_lifecycle_observer_list_.ForEachObserver(
+ [&](ContextLifecycleObserver* observer) {
+ if (!observer->IsExecutionContextLifecycleObserver())
+ return;
+ ExecutionContextLifecycleObserver* execution_context_observer =
+ static_cast<ExecutionContextLifecycleObserver*>(observer);
+ if (execution_context_observer->ObserverType() !=
+ ExecutionContextLifecycleObserver::kStateObjectType)
+ return;
+ ExecutionContextLifecycleStateObserver* state_observer =
+ static_cast<ExecutionContextLifecycleStateObserver*>(
+ execution_context_observer);
+#if DCHECK_IS_ON()
+ DCHECK_EQ(state_observer->GetExecutionContext(), this);
+ DCHECK(state_observer->UpdateStateIfNeededCalled());
+#endif
+ state_observer->ContextLifecycleStateChanged(state);
+ });
}
void ExecutionContext::NotifyContextDestroyed() {
is_context_destroyed_ = true;
- ContextLifecycleNotifier::NotifyContextDestroyed();
+ context_lifecycle_observer_list_.ForEachObserver(
+ [](ContextLifecycleObserver* observer) {
+ observer->ContextDestroyed();
+ observer->ObserverListWillBeCleared();
+ });
+ context_lifecycle_observer_list_.Clear();
+}
+
+void ExecutionContext::AddContextLifecycleObserver(
+ ContextLifecycleObserver* observer) {
+ context_lifecycle_observer_list_.AddObserver(observer);
+}
+
+void ExecutionContext::RemoveContextLifecycleObserver(
+ ContextLifecycleObserver* observer) {
+ DCHECK(context_lifecycle_observer_list_.HasObserver(observer));
+ context_lifecycle_observer_list_.RemoveObserver(observer);
+}
+
+unsigned ExecutionContext::ContextLifecycleStateObserverCountForTesting()
+ const {
+ DCHECK(!context_lifecycle_observer_list_.IsIteratingOverObservers());
+ unsigned lifecycle_state_observers = 0;
+ context_lifecycle_observer_list_.ForEachObserver(
+ [&](ContextLifecycleObserver* observer) {
+ if (!observer->IsExecutionContextLifecycleObserver())
+ return;
+ if (static_cast<ExecutionContextLifecycleObserver*>(observer)
+ ->ObserverType() !=
+ ExecutionContextLifecycleObserver::kStateObjectType)
+ return;
+ lifecycle_state_observers++;
+ });
+ return lifecycle_state_observers;
}
void ExecutionContext::AddConsoleMessageImpl(mojom::ConsoleMessageSource source,
mojom::ConsoleMessageLevel level,
const String& message,
bool discard_duplicates) {
- AddConsoleMessage(ConsoleMessage::Create(source, level, message),
- discard_duplicates);
+ AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(source, level, message),
+ discard_duplicates);
}
void ExecutionContext::DispatchErrorEvent(
@@ -183,7 +227,7 @@ ContentSecurityPolicy* ExecutionContext::GetContentSecurityPolicyForWorld() {
return GetContentSecurityPolicy();
}
-const SecurityOrigin* ExecutionContext::GetSecurityOrigin() {
+const SecurityOrigin* ExecutionContext::GetSecurityOrigin() const {
return GetSecurityContext().GetSecurityOrigin();
}
@@ -191,12 +235,20 @@ SecurityOrigin* ExecutionContext::GetMutableSecurityOrigin() {
return GetSecurityContext().GetMutableSecurityOrigin();
}
-ContentSecurityPolicy* ExecutionContext::GetContentSecurityPolicy() {
+ContentSecurityPolicy* ExecutionContext::GetContentSecurityPolicy() const {
return GetSecurityContext().GetContentSecurityPolicy();
}
+mojom::blink::WebSandboxFlags ExecutionContext::GetSandboxFlags() const {
+ return GetSecurityContext().GetSandboxFlags();
+}
+
+bool ExecutionContext::IsSandboxed(mojom::blink::WebSandboxFlags mask) const {
+ return GetSecurityContext().IsSandboxed(mask);
+}
+
const base::UnguessableToken& ExecutionContext::GetAgentClusterID() const {
- return agent_->cluster_id();
+ return GetAgent()->cluster_id();
}
void ExecutionContext::AllowWindowInteraction() {
@@ -213,9 +265,12 @@ bool ExecutionContext::IsWindowInteractionAllowed() const {
return window_interaction_tokens_ > 0;
}
-bool ExecutionContext::IsSecureContext() const {
- String unused_error_message;
- return IsSecureContext(unused_error_message);
+bool ExecutionContext::IsSecureContext(String& error_message) const {
+ if (!IsSecureContext()) {
+ error_message = SecurityOrigin::IsPotentiallyTrustworthyErrorMessage();
+ return false;
+ }
+ return true;
}
// https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer
@@ -236,7 +291,7 @@ void ExecutionContext::ParseAndSetReferrerPolicy(const String& policies,
support_legacy_keywords ? kSupportReferrerPolicyLegacyKeywords
: kDoNotSupportReferrerPolicyLegacyKeywords,
&referrer_policy)) {
- AddConsoleMessage(ConsoleMessage::Create(
+ AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kRendering,
mojom::ConsoleMessageLevel::kError,
"Failed to set referrer policy: The value '" + policies +
@@ -270,13 +325,12 @@ void ExecutionContext::RemoveURLFromMemoryCache(const KURL& url) {
GetMemoryCache()->RemoveURLFromCache(url);
}
-void ExecutionContext::Trace(blink::Visitor* visitor) {
+void ExecutionContext::Trace(Visitor* visitor) {
visitor->Trace(public_url_manager_);
visitor->Trace(pending_exceptions_);
visitor->Trace(csp_delegate_);
- visitor->Trace(agent_);
- visitor->Trace(origin_trial_context_);
visitor->Trace(timers_);
+ visitor->Trace(context_lifecycle_observer_list_);
ContextLifecycleNotifier::Trace(visitor);
ConsoleLogger::Trace(visitor);
Supplementable<ExecutionContext>::Trace(visitor);
@@ -294,15 +348,15 @@ bool ExecutionContext::IsSameAgentCluster(
v8::MicrotaskQueue* ExecutionContext::GetMicrotaskQueue() const {
// TODO(keishi): Convert to DCHECK once we assign agents everywhere.
- if (!agent_)
+ if (!GetAgent())
return nullptr;
- DCHECK(agent_->event_loop());
- return agent_->event_loop()->microtask_queue();
+ DCHECK(GetAgent()->event_loop());
+ return GetAgent()->event_loop()->microtask_queue();
}
bool ExecutionContext::FeatureEnabled(OriginTrialFeature feature) const {
- return origin_trial_context_ &&
- origin_trial_context_->IsFeatureEnabled(feature);
+ return GetOriginTrialContext() &&
+ GetOriginTrialContext()->IsFeatureEnabled(feature);
}
void ExecutionContext::CountFeaturePolicyUsage(mojom::WebFeature feature) {
@@ -310,11 +364,11 @@ void ExecutionContext::CountFeaturePolicyUsage(mojom::WebFeature feature) {
}
bool ExecutionContext::FeaturePolicyFeatureObserved(
- mojom::FeaturePolicyFeature feature) {
+ mojom::blink::FeaturePolicyFeature feature) {
size_t feature_index = static_cast<size_t>(feature);
if (parsed_feature_policies_.size() == 0) {
parsed_feature_policies_.resize(
- static_cast<size_t>(mojom::FeaturePolicyFeature::kMaxValue) + 1);
+ static_cast<size_t>(mojom::blink::FeaturePolicyFeature::kMaxValue) + 1);
} else if (parsed_feature_policies_[feature_index]) {
return true;
}
@@ -322,9 +376,133 @@ bool ExecutionContext::FeaturePolicyFeatureObserved(
return false;
}
+void ExecutionContext::FeaturePolicyPotentialBehaviourChangeObserved(
+ mojom::blink::FeaturePolicyFeature feature) const {
+ size_t feature_index = static_cast<size_t>(feature);
+ if (feature_policy_behaviour_change_counted_.size() == 0) {
+ feature_policy_behaviour_change_counted_.resize(
+ static_cast<size_t>(mojom::blink::FeaturePolicyFeature::kMaxValue) + 1);
+ } else if (feature_policy_behaviour_change_counted_[feature_index]) {
+ return;
+ }
+ feature_policy_behaviour_change_counted_[feature_index] = true;
+ UMA_HISTOGRAM_ENUMERATION(
+ "Blink.UseCounter.FeaturePolicy.ProposalWouldChangeBehaviour", feature);
+}
+
+bool ExecutionContext::IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature feature,
+ ReportOptions report_on_failure,
+ const String& message,
+ const String& source_file) const {
+ PolicyValue threshold_value =
+ PolicyValue::CreateMaxPolicyValue(GetSecurityContext()
+ .GetFeaturePolicy()
+ ->GetFeatureList()
+ .at(feature)
+ .second);
+ return IsFeatureEnabled(feature, threshold_value, report_on_failure, message,
+ source_file);
+}
+
+bool ExecutionContext::IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature feature,
+ PolicyValue threshold_value,
+ ReportOptions report_on_failure,
+ const String& message,
+ const String& source_file) const {
+ if (report_on_failure == ReportOptions::kReportOnFailure) {
+ // We are expecting a violation report in case the feature is disabled in
+ // the context. Therefore, this qualifies as a potential violation (i.e.,
+ // if the feature was disabled it would generate a report).
+ CountPotentialFeaturePolicyViolation(feature);
+ }
+
+ bool should_report;
+ bool enabled = GetSecurityContext().IsFeatureEnabled(feature, threshold_value,
+ &should_report);
+
+ if (enabled) {
+ // Report if the proposed header semantics change would have affected the
+ // outcome. (https://crbug.com/937131)
+ const FeaturePolicy* policy = GetSecurityContext().GetFeaturePolicy();
+ url::Origin origin = GetSecurityOrigin()->ToUrlOrigin();
+ if (policy->GetProposedFeatureValueForOrigin(feature, origin) <
+ threshold_value) {
+ // Count that there was a change in this page load.
+ const_cast<ExecutionContext*>(this)->CountUse(
+ WebFeature::kFeaturePolicyProposalWouldChangeBehaviour);
+ // Record the specific feature whose behaviour was changed.
+ FeaturePolicyPotentialBehaviourChangeObserved(feature);
+ }
+ }
+
+ if (should_report && report_on_failure == ReportOptions::kReportOnFailure) {
+ mojom::blink::PolicyDisposition disposition =
+ enabled ? mojom::blink::PolicyDisposition::kReport
+ : mojom::blink::PolicyDisposition::kEnforce;
+ ReportFeaturePolicyViolation(feature, disposition, message, source_file);
+ }
+ return enabled;
+}
+
+bool ExecutionContext::IsFeatureEnabled(
+ mojom::blink::DocumentPolicyFeature feature,
+ ReportOptions report_option,
+ const String& message,
+ const String& source_file) const {
+ DCHECK(GetDocumentPolicyFeatureInfoMap().at(feature).default_value.Type() ==
+ mojom::blink::PolicyValueType::kBool);
+ return IsFeatureEnabled(feature, PolicyValue(true), report_option, message,
+ source_file);
+}
+
+bool ExecutionContext::IsFeatureEnabled(
+ mojom::blink::DocumentPolicyFeature feature,
+ PolicyValue threshold_value,
+ ReportOptions report_option,
+ const String& message,
+ const String& source_file) const {
+ // The default value for any feature should be true unless restricted by
+ // document policy
+ if (!RuntimeEnabledFeatures::DocumentPolicyEnabled(this))
+ return true;
+
+ SecurityContext::FeatureStatus status =
+ GetSecurityContext().IsFeatureEnabled(feature, threshold_value);
+ if (status.should_report &&
+ report_option == ReportOptions::kReportOnFailure) {
+ // If both |enabled| and |should_report| are true, the usage must have
+ // violated the report-only policy, i.e. |disposition| ==
+ // mojom::blink::PolicyDisposition::kReport.
+ ReportDocumentPolicyViolation(
+ feature,
+ status.enabled ? mojom::blink::PolicyDisposition::kReport
+ : mojom::blink::PolicyDisposition::kEnforce,
+ message, source_file);
+ }
+ return status.enabled;
+}
+
bool ExecutionContext::RequireTrustedTypes() const {
return GetSecurityContext().TrustedTypesRequiredByPolicy() &&
RuntimeEnabledFeatures::TrustedDOMTypesEnabled(this);
}
+String ExecutionContext::addressSpaceForBindings() const {
+ switch (GetSecurityContext().AddressSpace()) {
+ case network::mojom::IPAddressSpace::kPublic:
+ case network::mojom::IPAddressSpace::kUnknown:
+ return "public";
+
+ case network::mojom::IPAddressSpace::kPrivate:
+ return "private";
+
+ case network::mojom::IPAddressSpace::kLocal:
+ return "local";
+ }
+ NOTREACHED();
+ return "public";
+}
+
} // namespace blink
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 24d2752bade..b92345fd50d 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
@@ -36,29 +36,31 @@
#include "base/optional.h"
#include "base/unguessable_token.h"
#include "services/network/public/mojom/referrer_policy.mojom-blink-forward.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/public/mojom/feature_policy/policy_disposition.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink-forward.h"
#include "third_party/blink/renderer/bindings/core/v8/sanitize_script_errors.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_notifier.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/security_context.h"
#include "third_party/blink/renderer/core/feature_policy/feature_policy_parser_delegate.h"
#include "third_party/blink/renderer/core/frame/dom_timer_coordinator.h"
+#include "third_party/blink/renderer/platform/context_lifecycle_notifier.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap_observer_list.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/loader/fetch/console_logger.h"
#include "third_party/blink/renderer/platform/loader/fetch/https_state.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/supplementable.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "v8/include/v8.h"
namespace base {
class SingleThreadTaskRunner;
}
-namespace service_manager {
-class InterfaceProvider;
-}
-
namespace blink {
class Agent;
@@ -76,7 +78,6 @@ class LocalDOMWindow;
class OriginTrialContext;
class PublicURLManager;
class ResourceFetcher;
-class SecurityContext;
class SecurityOrigin;
class ScriptState;
class TrustedTypePolicyFactory;
@@ -88,11 +89,9 @@ enum ReasonForCallingCanExecuteScripts {
kNotAboutToExecuteScript
};
-enum class SecureContextMode { kInsecureContext, kSecureContext };
-
// An environment in which script can execute. This class exposes the common
// properties of script execution environments on the web (i.e, common between
-// script executing in a document and script executing in a worker), such as:
+// script executing in a window and script executing in a worker), such as:
//
// - a base URL for the resolution of relative URLs
// - a security context that defines the privileges associated with the
@@ -103,26 +102,27 @@ enum class SecureContextMode { kInsecureContext, kSecureContext };
// been closed permanently
// - a console logging facility for debugging
//
-// Typically, the ExecutionContext is an instance of Document or of
+// Typically, the ExecutionContext is an instance of LocalDOMWindow or of
// WorkerOrWorkletGlobalScope.
//
// Note that this is distinct from the notion of a ScriptState or v8::Context,
// which are associated with a single script context (with a single global
// object). For example, there are separate JavaScript globals for "main world"
// script written by a web author and an "isolated world" content script written
-// by an extension developer, but these share an ExecutionContext (the document)
+// by an extension developer, but these share an ExecutionContext (the window)
// in common.
-class CORE_EXPORT ExecutionContext : public ContextLifecycleNotifier,
- public Supplementable<ExecutionContext>,
+class CORE_EXPORT ExecutionContext : public Supplementable<ExecutionContext>,
+ public ContextLifecycleNotifier,
public ConsoleLogger,
public UseCounter,
public FeaturePolicyParserDelegate {
MERGE_GARBAGE_COLLECTED_MIXINS();
public:
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
static ExecutionContext* From(const ScriptState*);
+ static ExecutionContext* From(v8::Local<v8::Context>);
// Returns the ExecutionContext of the current realm.
static ExecutionContext* ForCurrentRealm(
@@ -150,10 +150,13 @@ class CORE_EXPORT ExecutionContext : public ContextLifecycleNotifier,
virtual bool ShouldInstallV8Extensions() const { return false; }
- const SecurityOrigin* GetSecurityOrigin();
+ const SecurityOrigin* GetSecurityOrigin() const;
SecurityOrigin* GetMutableSecurityOrigin();
- ContentSecurityPolicy* GetContentSecurityPolicy();
+ ContentSecurityPolicy* GetContentSecurityPolicy() const;
+
+ mojom::blink::WebSandboxFlags GetSandboxFlags() const;
+ bool IsSandboxed(mojom::blink::WebSandboxFlags mask) const;
// Returns the content security policy to be used based on the current
// JavaScript world we are in.
@@ -210,7 +213,7 @@ class CORE_EXPORT ExecutionContext : public ContextLifecycleNotifier,
virtual void RemoveURLFromMemoryCache(const KURL&);
void SetLifecycleState(mojom::FrameLifecycleState);
- void NotifyContextDestroyed() override;
+ void NotifyContextDestroyed();
using ConsoleLogger::AddConsoleMessage;
@@ -219,13 +222,6 @@ class CORE_EXPORT ExecutionContext : public ContextLifecycleNotifier,
AddConsoleMessageImpl(message, discard_duplicates);
}
- // TODO(haraken): Remove these methods by making the customers inherit from
- // ContextLifecycleObserver. ContextLifecycleObserver is a standard way to
- // observe context suspension/resumption.
- virtual bool TasksNeedPause() { return false; }
- virtual void TasksWerePaused() {}
- virtual void TasksWereUnpaused() {}
-
bool IsContextPaused() const;
bool IsContextDestroyed() const { return is_context_destroyed_; }
mojom::FrameLifecycleState ContextPauseState() const {
@@ -245,13 +241,13 @@ class CORE_EXPORT ExecutionContext : public ContextLifecycleNotifier,
// Decides whether this context is privileged, as described in
// https://w3c.github.io/webappsec-secure-contexts/#is-settings-object-contextually-secure.
- virtual bool IsSecureContext(String& error_message) const = 0;
- virtual bool IsSecureContext() const;
-
SecureContextMode GetSecureContextMode() const {
- return IsSecureContext() ? SecureContextMode::kSecureContext
- : SecureContextMode::kInsecureContext;
+ return GetSecurityContext().GetSecureContextMode();
+ }
+ bool IsSecureContext() const {
+ return GetSecureContextMode() == SecureContextMode::kSecureContext;
}
+ bool IsSecureContext(String& error_message) const;
// Returns a referrer to be used in the "Determine request's Referrer"
// algorithm defined in the Referrer Policy spec.
@@ -275,10 +271,6 @@ class CORE_EXPORT ExecutionContext : public ContextLifecycleNotifier,
virtual CoreProbeSink* GetProbeSink() { return nullptr; }
- virtual service_manager::InterfaceProvider* GetInterfaceProvider() {
- return nullptr;
- }
-
virtual BrowserInterfaceBrokerProxy& GetBrowserInterfaceBroker() = 0;
virtual FrameOrWorkerScheduler* GetScheduler() = 0;
@@ -286,12 +278,12 @@ class CORE_EXPORT ExecutionContext : public ContextLifecycleNotifier,
TaskType) = 0;
v8::Isolate* GetIsolate() const { return isolate_; }
- Agent* GetAgent() const { return agent_; }
+ Agent* GetAgent() const { return GetSecurityContext().GetAgent(); }
v8::MicrotaskQueue* GetMicrotaskQueue() const;
OriginTrialContext* GetOriginTrialContext() const {
- return origin_trial_context_;
+ return GetSecurityContext().GetOriginTrialContext();
}
virtual TrustedTypePolicyFactory* GetTrustedTypes() const { return nullptr; }
@@ -301,13 +293,64 @@ class CORE_EXPORT ExecutionContext : public ContextLifecycleNotifier,
bool FeatureEnabled(OriginTrialFeature) const override;
void CountFeaturePolicyUsage(mojom::WebFeature feature) override;
bool FeaturePolicyFeatureObserved(
- mojom::FeaturePolicyFeature feature) override;
-
+ mojom::blink::FeaturePolicyFeature feature) override;
+
+ // Tests whether the policy-controlled feature is enabled in this frame.
+ // Optionally sends a report to any registered reporting observers or
+ // Report-To endpoints, via ReportFeaturePolicyViolation(), if the feature is
+ // disabled. The optional ConsoleMessage will be sent to the console if
+ // present, or else a default message will be used instead.
+ bool IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature,
+ ReportOptions report_on_failure = ReportOptions::kDoNotReport,
+ const String& message = g_empty_string,
+ const String& source_file = g_empty_string) const;
+ bool IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature,
+ PolicyValue threshold_value,
+ ReportOptions report_on_failure = ReportOptions::kDoNotReport,
+ const String& message = g_empty_string,
+ const String& source_file = 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;
+
+ virtual void CountPotentialFeaturePolicyViolation(
+ mojom::blink::FeaturePolicyFeature) const {}
+
+ // Report policy violations is delegated to Document because in order
+ // to both remain const qualified and output console message, needs
+ // to call |frame_->Console().AddMessage()| directly.
+ virtual void ReportFeaturePolicyViolation(
+ mojom::blink::FeaturePolicyFeature,
+ mojom::blink::PolicyDisposition,
+ const String& message = g_empty_string,
+ const String& source_file = g_empty_string) const {}
+ virtual void ReportDocumentPolicyViolation(
+ mojom::blink::DocumentPolicyFeature,
+ mojom::blink::PolicyDisposition,
+ const String& message = g_empty_string,
+ const String& source_file = g_empty_string) const {}
+
+ String addressSpaceForBindings() const;
+
+ void AddContextLifecycleObserver(ContextLifecycleObserver*) override;
+ void RemoveContextLifecycleObserver(ContextLifecycleObserver*) override;
+ HeapObserverList<ContextLifecycleObserver>& ContextLifecycleObserverList() {
+ return context_lifecycle_observer_list_;
+ }
+ unsigned ContextLifecycleStateObserverCountForTesting() const;
protected:
- ExecutionContext(v8::Isolate* isolate,
- Agent* agent,
- OriginTrialContext* origin_trial_context);
+ explicit ExecutionContext(v8::Isolate* isolate);
~ExecutionContext() override;
private:
@@ -315,11 +358,15 @@ class CORE_EXPORT ExecutionContext : public ContextLifecycleNotifier,
void AddConsoleMessageImpl(mojom::ConsoleMessageSource,
mojom::ConsoleMessageLevel,
const String& message,
- bool discard_duplicates) final;
-
+ bool discard_duplicates) override;
virtual void AddConsoleMessageImpl(ConsoleMessage*,
bool discard_duplicates) = 0;
+ // Temporary method to record when the result of calling IsFeatureEnabled
+ // would change under the proposal in https://crbug.com/937131.
+ void FeaturePolicyPotentialBehaviourChangeObserved(
+ mojom::blink::FeaturePolicyFeature feature) const;
+
v8::Isolate* const isolate_;
bool DispatchErrorEventInternal(ErrorEvent*, SanitizeScriptErrors);
@@ -336,12 +383,10 @@ class CORE_EXPORT ExecutionContext : public ContextLifecycleNotifier,
const Member<ContentSecurityPolicyDelegate> csp_delegate_;
- Member<Agent> agent_;
-
- Member<OriginTrialContext> origin_trial_context_;
-
DOMTimerCoordinator timers_;
+ HeapObserverList<ContextLifecycleObserver> context_lifecycle_observer_list_;
+
// Counter that keeps track of how many window interaction calls are allowed
// for this ExecutionContext. Callers are expected to call
// |allowWindowInteraction()| and |consumeWindowInteraction()| in order to
@@ -355,6 +400,11 @@ class CORE_EXPORT ExecutionContext : public ContextLifecycleNotifier,
// The size of this vector is 0 until FeaturePolicyFeatureObserved is called.
Vector<bool> parsed_feature_policies_;
+ // Tracks which feature policy features have been logged in this execution
+ // context as to the FeaturePolicyProposalWouldChangeBehaviour
+ // histogram, in order not to overcount.
+ mutable Vector<bool> feature_policy_behaviour_change_counted_;
+
DISALLOW_COPY_AND_ASSIGN(ExecutionContext);
};
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
new file mode 100644
index 00000000000..b8fdc6e4d37
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.cc
@@ -0,0 +1,96 @@
+// 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/execution_context/execution_context_lifecycle_observer.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"
+
+namespace blink {
+
+ExecutionContextClient::ExecutionContextClient(
+ ExecutionContext* execution_context)
+ : execution_context_(execution_context) {}
+
+ExecutionContextClient::ExecutionContextClient(LocalFrame* frame)
+ : execution_context_(frame ? frame->GetDocument()->ToExecutionContext()
+ : nullptr) {}
+
+ExecutionContext* ExecutionContextClient::GetExecutionContext() const {
+ return execution_context_ && !execution_context_->IsContextDestroyed()
+ ? execution_context_.Get()
+ : nullptr;
+}
+
+Document* ExecutionContextClient::GetDocument() const {
+ return execution_context_
+ ? Document::DynamicFrom(
+ static_cast<ExecutionContext*>(execution_context_))
+ : nullptr;
+}
+
+LocalFrame* ExecutionContextClient::GetFrame() const {
+ auto* document = GetDocument();
+ return document ? document->GetFrame() : nullptr;
+}
+
+void ExecutionContextClient::Trace(Visitor* visitor) {
+ visitor->Trace(execution_context_);
+}
+
+ExecutionContextLifecycleObserver::ExecutionContextLifecycleObserver()
+ : observer_type_(kGenericType) {}
+
+ExecutionContextLifecycleObserver::ExecutionContextLifecycleObserver(
+ Document* document,
+ Type type)
+ : ExecutionContextLifecycleObserver(
+ document ? document->ToExecutionContext() : nullptr,
+ type) {}
+
+ExecutionContextLifecycleObserver::ExecutionContextLifecycleObserver(
+ ExecutionContext* execution_context,
+ Type type)
+ : observer_type_(type) {
+ SetExecutionContext(execution_context);
+}
+
+ExecutionContext* ExecutionContextLifecycleObserver::GetExecutionContext()
+ const {
+ return static_cast<ExecutionContext*>(GetContextLifecycleNotifier());
+}
+
+void ExecutionContextLifecycleObserver::SetExecutionContext(
+ ExecutionContext* execution_context) {
+ SetContextLifecycleNotifier(execution_context);
+}
+
+LocalFrame* ExecutionContextLifecycleObserver::GetFrame() const {
+ auto* document = Document::DynamicFrom(GetExecutionContext());
+ return document ? document->GetFrame() : nullptr;
+}
+
+void ExecutionContextLifecycleObserver::Trace(Visitor* visitor) {
+ ContextLifecycleObserver::Trace(visitor);
+}
+
+DOMWindowClient::DOMWindowClient(LocalDOMWindow* window)
+ : dom_window_(window) {}
+
+DOMWindowClient::DOMWindowClient(LocalFrame* frame)
+ : dom_window_(frame ? frame->DomWindow() : nullptr) {}
+
+LocalDOMWindow* DOMWindowClient::DomWindow() const {
+ return dom_window_ && dom_window_->GetFrame() ? dom_window_ : nullptr;
+}
+
+LocalFrame* DOMWindowClient::GetFrame() const {
+ return dom_window_ ? dom_window_->GetFrame() : nullptr;
+}
+
+void DOMWindowClient::Trace(Visitor* visitor) {
+ visitor->Trace(dom_window_);
+}
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h b/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h
index 58576ba6ff1..c3d1d99bcf8 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h
+++ b/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h
@@ -24,23 +24,23 @@
*
*/
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EXECUTION_CONTEXT_CONTEXT_LIFECYCLE_OBSERVER_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_EXECUTION_CONTEXT_CONTEXT_LIFECYCLE_OBSERVER_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EXECUTION_CONTEXT_EXECUTION_CONTEXT_LIFECYCLE_OBSERVER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_EXECUTION_CONTEXT_EXECUTION_CONTEXT_LIFECYCLE_OBSERVER_H_
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/execution_context/execution_context.h"
-#include "third_party/blink/renderer/platform/lifecycle_observer.h"
+#include "third_party/blink/renderer/platform/context_lifecycle_observer.h"
namespace blink {
+class ExecutionContext;
class Document;
class LocalDOMWindow;
class LocalFrame;
-// ContextClient and ContextLifecycleObserver are helpers to associate an
-// object with an ExecutionContext. It is unsafe to access an associated GC
-// object, *including via GetExecutionContext()*, in the destructor of a GC
-// object.
+// ExecutionContextClient and ExecutionContextLifecycleObserver are helpers to
+// associate an object with an ExecutionContext. It is unsafe to access an
+// associated GC object, *including via GetExecutionContext()*, in the
+// destructor of a GC object.
//
// To discourage incorrect usage, these objects both start returning null
// once the execution context shuts down. For a document, this occurs when
@@ -48,22 +48,23 @@ class LocalFrame;
// scope, this occurs when it shuts down.
//
// * If an object only needs to refer to a valid ExecutionContext but does not
-// need to stop or suspend any activity, it should be a ContextClient.
+// need to stop or suspend any activity, it should be a
+// ExecutionContextClient.
// * If an object associated with an ExecutionContext has shutdown logic to
// perform, such as halting activity or disconnecting from longer-lived
// objects, it should be a PausableObject.
// * If an object additionally must suspend its activity during pause (see
-// context_lifecycle_state_observer.h), it should be a
-// ContextLifecycleStateObserver (and thus, transitively, also a
-// ContextLifecycleObserver).
+// execution_context_lifecycle_state_observer.h), it should be a
+// ExecutionContextLifecycleStateObserver (and thus, transitively, also a
+// ExecutionContextLifecycleObserver).
//
// If your object has activity which requires that it be kept alive, even if no
// other object has a reference to it, consider whether your object should also
// derive from ActiveScriptWrappable.
-// ContextClient provides access to the associated execution context until it is
-// shut down (e.g. for a document, at navigation or frame detach).
-class CORE_EXPORT ContextClient : public GarbageCollectedMixin {
+// ExecutionContextClient provides access to the associated execution context
+// until it is shut down (e.g. for a document, at navigation or frame detach).
+class CORE_EXPORT ExecutionContextClient : public GarbageCollectedMixin {
public:
// Returns the execution context until it is detached.
// From then on, returns null instead.
@@ -79,16 +80,16 @@ class CORE_EXPORT ContextClient : public GarbageCollectedMixin {
void Trace(Visitor*) override;
protected:
- explicit ContextClient(ExecutionContext*);
- explicit ContextClient(LocalFrame*);
+ explicit ExecutionContextClient(ExecutionContext*);
+ explicit ExecutionContextClient(LocalFrame*);
private:
WeakMember<ExecutionContext> execution_context_;
};
-// ContextLifecycleObserver provides an additional ContextDestroyed() hook
-// to execute cleanup code when a context is shut down (e.g. for a document,
-// at navigation or frame detach -- not when its destructor runs).
+// ExecutionContextLifecycleObserver provides an additional ContextDestroyed()
+// hook to execute cleanup code when a context is shut down (e.g. for a
+// document, at navigation or frame detach -- not when its destructor runs).
//
// Execution context associated objects which have ongoing activity,
// registration with objects which outlive the context, or resources which
@@ -98,17 +99,17 @@ class CORE_EXPORT ContextClient : public GarbageCollectedMixin {
//
// If there is ongoing activity associated with the object, consider whether it
// needs to be paused when execution is suspended (see
-// ContextLifecycleStateObserver).
+// ExecutionContextLifecycleStateObserver).
//
-// If none of the above applies, prefer the simpler ContextClient.
-class CORE_EXPORT ContextLifecycleObserver
- : public LifecycleObserver<ExecutionContext, ContextLifecycleObserver> {
+// If none of the above applies, prefer the simpler ExecutionContextClient.
+class CORE_EXPORT ExecutionContextLifecycleObserver
+ : public ContextLifecycleObserver {
public:
- virtual void ContextDestroyed(ExecutionContext*) {}
// Returns the execution context until it is detached.
// From then on, returns null instead.
- ExecutionContext* GetExecutionContext() const { return LifecycleContext(); }
+ ExecutionContext* GetExecutionContext() const;
+ virtual void SetExecutionContext(ExecutionContext*);
// If associated with a live document, returns the associated frame.
// Returns null otherwise.
@@ -121,10 +122,20 @@ class CORE_EXPORT ContextLifecycleObserver
Type ObserverType() const { return observer_type_; }
+ bool IsExecutionContextLifecycleObserver() const override { return true; }
+
+ void Trace(Visitor*) override;
+
protected:
- explicit ContextLifecycleObserver(ExecutionContext* execution_context,
- Type type = kGenericType)
- : LifecycleObserver(execution_context), observer_type_(type) {}
+ ExecutionContextLifecycleObserver();
+ // TODO(crbug.com/1029822): This is a shim to enable migrating
+ // ExecutionContext to LocalDOMWindow.
+ explicit ExecutionContextLifecycleObserver(Document*,
+ Type type = kGenericType);
+
+ explicit ExecutionContextLifecycleObserver(
+ ExecutionContext* execution_context,
+ Type type = kGenericType);
private:
Type observer_type_;
@@ -139,19 +150,20 @@ class CORE_EXPORT ContextLifecycleObserver
// Both can safely be used up until destruction; i.e., unsafe to
// call upon in a destructor.
//
-// If the object is a per-ExecutionContext thing, use ContextClient/
-// ContextLifecycleObserver. If the object is a per-DOMWindow thing, use
-// DOMWindowClient. Basically, DOMWindowClient is expected to be used (only)
+// If the object is a per-ExecutionContext thing, use ExecutionContextClient/
+// ExecutionContextLifecycleObserver. If the object is a per-DOMWindow thing,
+// use DOMWindowClient. Basically, DOMWindowClient is expected to be used (only)
// for objects directly held by LocalDOMWindow. Other objects should use
-// ContextClient/ContextLifecycleObserver.
+// ExecutionContextClient/ExecutionContextLifecycleObserver.
//
// There is a subtle difference between the timing when the context gets
// detached and the timing when the window gets detached. In common cases,
// these two happen at the same timing. The only exception is a case where
// a frame navigates from an initial empty document to another same-origin
// document. In this case, a Document is recreated but a DOMWindow is reused.
-// Hence, in the navigated document ContextClient::getExecutionContext()
-// returns null while DOMWindowClient::domWindow() keeps returning the window.
+// Hence, in the navigated document
+// ExecutionContextClient::GetExecutionContext() returns null while
+// DOMWindowClient::domWindow() keeps returning the window.
class CORE_EXPORT DOMWindowClient : public GarbageCollectedMixin {
public:
LocalDOMWindow* DomWindow() const;
@@ -169,4 +181,4 @@ class CORE_EXPORT DOMWindowClient : public GarbageCollectedMixin {
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EXECUTION_CONTEXT_CONTEXT_LIFECYCLE_OBSERVER_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EXECUTION_CONTEXT_EXECUTION_CONTEXT_LIFECYCLE_OBSERVER_H_
diff --git a/chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.cc b/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.cc
index af05dba4015..328edfa5c62 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.cc
+++ b/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.cc
@@ -24,23 +24,30 @@
*
*/
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h"
#include "third_party/blink/public/mojom/frame/lifecycle.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/platform/instrumentation/instance_counters.h"
namespace blink {
-ContextLifecycleStateObserver::ContextLifecycleStateObserver(
+ExecutionContextLifecycleStateObserver::ExecutionContextLifecycleStateObserver(
ExecutionContext* execution_context)
- : ContextLifecycleObserver(execution_context, kStateObjectType) {
+ : ExecutionContextLifecycleObserver(execution_context, kStateObjectType) {
DCHECK(!execution_context || execution_context->IsContextThread());
InstanceCounters::IncrementCounter(
InstanceCounters::kContextLifecycleStateObserverCounter);
}
-ContextLifecycleStateObserver::~ContextLifecycleStateObserver() {
+ExecutionContextLifecycleStateObserver::ExecutionContextLifecycleStateObserver(
+ Document* document)
+ : ExecutionContextLifecycleStateObserver(
+ document ? document->ToExecutionContext() : nullptr) {}
+
+ExecutionContextLifecycleStateObserver::
+ ~ExecutionContextLifecycleStateObserver() {
InstanceCounters::DecrementCounter(
InstanceCounters::kContextLifecycleStateObserverCounter);
@@ -49,27 +56,30 @@ ContextLifecycleStateObserver::~ContextLifecycleStateObserver() {
#endif
}
-void ContextLifecycleStateObserver::UpdateStateIfNeeded() {
+void ExecutionContextLifecycleStateObserver::UpdateStateIfNeeded() {
#if DCHECK_IS_ON()
DCHECK(!update_state_if_needed_called_);
update_state_if_needed_called_ = true;
#endif
if (ExecutionContext* context = GetExecutionContext()) {
#if DCHECK_IS_ON()
- DCHECK(context->Contains(this));
+ DCHECK(context->ContextLifecycleObserverList().HasObserver(this));
#endif
- mojom::FrameLifecycleState pause_state = context->ContextPauseState();
- if (pause_state != mojom::FrameLifecycleState::kRunning)
+ mojom::blink::FrameLifecycleState pause_state =
+ context->ContextPauseState();
+ if (pause_state != mojom::blink::FrameLifecycleState::kRunning)
ContextLifecycleStateChanged(pause_state);
}
}
-void ContextLifecycleStateObserver::DidMoveToNewExecutionContext(
+void ExecutionContextLifecycleStateObserver::SetExecutionContext(
ExecutionContext* context) {
- SetContext(context);
+ ExecutionContextLifecycleObserver::SetExecutionContext(context);
+ if (!context)
+ return;
if (context->IsContextDestroyed()) {
- ContextDestroyed(context);
+ ContextDestroyed();
return;
}
ContextLifecycleStateChanged(context->ContextPauseState());
diff --git a/chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.h b/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h
index 7aa2c45ce3a..01f0955e521 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.h
+++ b/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h
@@ -24,18 +24,18 @@
*
*/
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EXECUTION_CONTEXT_CONTEXT_LIFECYCLE_STATE_OBSERVER_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_EXECUTION_CONTEXT_CONTEXT_LIFECYCLE_STATE_OBSERVER_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EXECUTION_CONTEXT_EXECUTION_CONTEXT_LIFECYCLE_STATE_OBSERVER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_EXECUTION_CONTEXT_EXECUTION_CONTEXT_LIFECYCLE_STATE_OBSERVER_H_
#include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
namespace blink {
-// A ContextLifecycleStateObserver responds to situations where Blink is
-// pausing a context or freezing a frame.
+// A ExecutionContextLifecycleStateObserver responds to situations where Blink
+// is pausing a context or freezing a frame.
//
// Context lifecycle state changes can happen in cases such as:
// - modal dialogs during script execution (e.g. window.alert, window.print)
@@ -51,10 +51,13 @@ namespace blink {
//
// https://html.spec.whatwg.org/C/#pause
// https://wicg.github.io/page-lifecycle/spec.html
-class CORE_EXPORT ContextLifecycleStateObserver
- : public ContextLifecycleObserver {
+class CORE_EXPORT ExecutionContextLifecycleStateObserver
+ : public ExecutionContextLifecycleObserver {
public:
- explicit ContextLifecycleStateObserver(ExecutionContext*);
+ explicit ExecutionContextLifecycleStateObserver(ExecutionContext*);
+ // TODO(crbug.com/1029822): This is a shim to enable migrating
+ // ExecutionContext to LocalDOMWindow.
+ explicit ExecutionContextLifecycleStateObserver(Document*);
// UpdateStateIfNeeded() should be called exactly once after object
// construction to synchronize the suspend state with that in
@@ -67,12 +70,12 @@ class CORE_EXPORT ContextLifecycleStateObserver
#endif
virtual void ContextLifecycleStateChanged(
- mojom::FrameLifecycleState state) = 0;
+ mojom::blink::FrameLifecycleState state) = 0;
- void DidMoveToNewExecutionContext(ExecutionContext*);
+ void SetExecutionContext(ExecutionContext*) override;
protected:
- virtual ~ContextLifecycleStateObserver();
+ virtual ~ExecutionContextLifecycleStateObserver();
private:
#if DCHECK_IS_ON()
@@ -82,4 +85,4 @@ class CORE_EXPORT ContextLifecycleStateObserver
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EXECUTION_CONTEXT_CONTEXT_LIFECYCLE_STATE_OBSERVER_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EXECUTION_CONTEXT_EXECUTION_CONTEXT_LIFECYCLE_STATE_OBSERVER_H_
diff --git a/chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer_test.cc b/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer_test.cc
index 03e217d0de7..4382e97201c 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer_test.cc
+++ b/chromium/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer_test.cc
@@ -28,7 +28,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h"
#include <memory>
#include "testing/gmock/include/gmock/gmock.h"
@@ -36,82 +36,98 @@
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
+using testing::AnyNumber;
+
namespace blink {
-class MockContextLifecycleStateObserver final
- : public GarbageCollected<MockContextLifecycleStateObserver>,
- public ContextLifecycleStateObserver {
- USING_GARBAGE_COLLECTED_MIXIN(MockContextLifecycleStateObserver);
+class MockExecutionContextLifecycleStateObserver final
+ : public GarbageCollected<MockExecutionContextLifecycleStateObserver>,
+ public ExecutionContextLifecycleStateObserver {
+ USING_GARBAGE_COLLECTED_MIXIN(MockExecutionContextLifecycleStateObserver);
public:
- explicit MockContextLifecycleStateObserver(ExecutionContext* context)
- : ContextLifecycleStateObserver(context) {}
+ explicit MockExecutionContextLifecycleStateObserver(ExecutionContext* context)
+ : ExecutionContextLifecycleStateObserver(context) {}
- void Trace(blink::Visitor* visitor) override {
- ContextLifecycleStateObserver::Trace(visitor);
+ void Trace(Visitor* visitor) override {
+ ExecutionContextLifecycleStateObserver::Trace(visitor);
}
MOCK_METHOD1(ContextLifecycleStateChanged, void(mojom::FrameLifecycleState));
- MOCK_METHOD1(ContextDestroyed, void(ExecutionContext*));
+ MOCK_METHOD0(ContextDestroyed, void());
};
-class ContextLifecycleStateObserverTest : public testing::Test {
+class ExecutionContextLifecycleStateObserverTest : public testing::Test {
protected:
- ContextLifecycleStateObserverTest();
+ ExecutionContextLifecycleStateObserverTest();
Document& SrcDocument() const { return src_page_holder_->GetDocument(); }
Document& DestDocument() const { return dest_page_holder_->GetDocument(); }
- MockContextLifecycleStateObserver& Observer() { return *observer_; }
+ MockExecutionContextLifecycleStateObserver& Observer() { return *observer_; }
private:
std::unique_ptr<DummyPageHolder> src_page_holder_;
std::unique_ptr<DummyPageHolder> dest_page_holder_;
- Persistent<MockContextLifecycleStateObserver> observer_;
+ Persistent<MockExecutionContextLifecycleStateObserver> observer_;
};
-ContextLifecycleStateObserverTest::ContextLifecycleStateObserverTest()
+ExecutionContextLifecycleStateObserverTest::
+ ExecutionContextLifecycleStateObserverTest()
: src_page_holder_(std::make_unique<DummyPageHolder>(IntSize(800, 600))),
dest_page_holder_(std::make_unique<DummyPageHolder>(IntSize(800, 600))),
- observer_(MakeGarbageCollected<MockContextLifecycleStateObserver>(
- &src_page_holder_->GetDocument())) {
+ observer_(
+ MakeGarbageCollected<MockExecutionContextLifecycleStateObserver>(
+ src_page_holder_->GetDocument().ToExecutionContext())) {
observer_->UpdateStateIfNeeded();
}
-TEST_F(ContextLifecycleStateObserverTest, NewContextObserved) {
+TEST_F(ExecutionContextLifecycleStateObserverTest, NewContextObserved) {
unsigned initial_src_count =
- SrcDocument().ContextLifecycleStateObserverCount();
+ SrcDocument()
+ .ToExecutionContext()
+ ->ContextLifecycleStateObserverCountForTesting();
unsigned initial_dest_count =
- DestDocument().ContextLifecycleStateObserverCount();
+ DestDocument()
+ .ToExecutionContext()
+ ->ContextLifecycleStateObserverCountForTesting();
EXPECT_CALL(Observer(), ContextLifecycleStateChanged(
mojom::FrameLifecycleState::kRunning));
- Observer().DidMoveToNewExecutionContext(&DestDocument());
+ EXPECT_CALL(Observer(), ContextDestroyed()).Times(AnyNumber());
+ Observer().SetExecutionContext(DestDocument().ToExecutionContext());
EXPECT_EQ(initial_src_count - 1,
- SrcDocument().ContextLifecycleStateObserverCount());
+ SrcDocument()
+ .ToExecutionContext()
+ ->ContextLifecycleStateObserverCountForTesting());
EXPECT_EQ(initial_dest_count + 1,
- DestDocument().ContextLifecycleStateObserverCount());
+ DestDocument()
+ .ToExecutionContext()
+ ->ContextLifecycleStateObserverCountForTesting());
}
-TEST_F(ContextLifecycleStateObserverTest, MoveToActiveDocument) {
+TEST_F(ExecutionContextLifecycleStateObserverTest, MoveToActiveDocument) {
EXPECT_CALL(Observer(), ContextLifecycleStateChanged(
mojom::FrameLifecycleState::kRunning));
- Observer().DidMoveToNewExecutionContext(&DestDocument());
+ EXPECT_CALL(Observer(), ContextDestroyed()).Times(AnyNumber());
+ Observer().SetExecutionContext(DestDocument().ToExecutionContext());
}
-TEST_F(ContextLifecycleStateObserverTest, MoveToSuspendedDocument) {
- DestDocument().SetLifecycleState(mojom::FrameLifecycleState::kFrozen);
+TEST_F(ExecutionContextLifecycleStateObserverTest, MoveToSuspendedDocument) {
+ DestDocument().ToExecutionContext()->SetLifecycleState(
+ mojom::FrameLifecycleState::kFrozen);
EXPECT_CALL(Observer(), ContextLifecycleStateChanged(
mojom::FrameLifecycleState::kFrozen));
- Observer().DidMoveToNewExecutionContext(&DestDocument());
+ EXPECT_CALL(Observer(), ContextDestroyed()).Times(AnyNumber());
+ Observer().SetExecutionContext(DestDocument().ToExecutionContext());
}
-TEST_F(ContextLifecycleStateObserverTest, MoveToStoppedDocument) {
+TEST_F(ExecutionContextLifecycleStateObserverTest, MoveToStoppedDocument) {
DestDocument().Shutdown();
- EXPECT_CALL(Observer(), ContextDestroyed(&DestDocument()));
- Observer().DidMoveToNewExecutionContext(&DestDocument());
+ EXPECT_CALL(Observer(), ContextDestroyed());
+ Observer().SetExecutionContext(DestDocument().ToExecutionContext());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/execution_context/remote_security_context.cc b/chromium/third_party/blink/renderer/core/execution_context/remote_security_context.cc
index f2670bd81c9..e97fffea95a 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/remote_security_context.cc
+++ b/chromium/third_party/blink/renderer/core/execution_context/remote_security_context.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/execution_context/remote_security_context.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/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -11,7 +12,8 @@
namespace blink {
-RemoteSecurityContext::RemoteSecurityContext() : SecurityContext() {
+RemoteSecurityContext::RemoteSecurityContext()
+ : SecurityContext(SecurityContextInit(), kRemote) {
// RemoteSecurityContext's origin is expected to stay uninitialized until
// we set it using replicated origin data from the browser process.
DCHECK(!GetSecurityOrigin());
@@ -24,10 +26,6 @@ RemoteSecurityContext::RemoteSecurityContext() : SecurityContext() {
// grantUniversalAccess().
}
-void RemoteSecurityContext::Trace(blink::Visitor* visitor) {
- SecurityContext::Trace(visitor);
-}
-
void RemoteSecurityContext::SetReplicatedOrigin(
scoped_refptr<SecurityOrigin> origin) {
DCHECK(origin);
@@ -41,11 +39,12 @@ void RemoteSecurityContext::ResetReplicatedContentSecurityPolicy() {
GetContentSecurityPolicy()->SetupSelf(*GetSecurityOrigin());
}
-void RemoteSecurityContext::ResetAndEnforceSandboxFlags(WebSandboxFlags flags) {
+void RemoteSecurityContext::ResetAndEnforceSandboxFlags(
+ mojom::blink::WebSandboxFlags flags) {
sandbox_flags_ = flags;
- if (IsSandboxed(WebSandboxFlags::kOrigin) && GetSecurityOrigin() &&
- !GetSecurityOrigin()->IsOpaque()) {
+ if (IsSandboxed(mojom::blink::WebSandboxFlags::kOrigin) &&
+ GetSecurityOrigin() && !GetSecurityOrigin()->IsOpaque()) {
SetSecurityOrigin(GetSecurityOrigin()->DeriveNewOpaqueOrigin());
}
}
diff --git a/chromium/third_party/blink/renderer/core/execution_context/remote_security_context.h b/chromium/third_party/blink/renderer/core/execution_context/remote_security_context.h
index 854b508c9d4..00042b460d8 100644
--- a/chromium/third_party/blink/renderer/core/execution_context/remote_security_context.h
+++ b/chromium/third_party/blink/renderer/core/execution_context/remote_security_context.h
@@ -12,19 +12,13 @@
namespace blink {
-class CORE_EXPORT RemoteSecurityContext
- : public GarbageCollected<RemoteSecurityContext>,
- public SecurityContext {
- USING_GARBAGE_COLLECTED_MIXIN(RemoteSecurityContext);
-
+class CORE_EXPORT RemoteSecurityContext final : public SecurityContext {
public:
RemoteSecurityContext();
- void Trace(blink::Visitor*) override;
-
void SetReplicatedOrigin(scoped_refptr<SecurityOrigin>);
void ResetReplicatedContentSecurityPolicy();
- void ResetAndEnforceSandboxFlags(WebSandboxFlags flags);
+ void ResetAndEnforceSandboxFlags(mojom::blink::WebSandboxFlags flags);
// Constructs the enforcement FeaturePolicy struct for this security context.
// The resulting FeaturePolicy is a combination of:
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 fca43e4be19..0d2018299ae 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
@@ -28,47 +28,20 @@
#include "base/metrics/histogram_macros.h"
#include "services/network/public/mojom/ip_address_space.mojom-blink.h"
+#include "third_party/blink/public/common/feature_policy/document_policy_features.h"
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy.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"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
namespace blink {
-namespace {
-
-// Bucketize image metrics into percentage in the following fashion:
-// if an image's metrics is 0.1, it will be represented as 1 percent
-// if an image's metrics is 5, it will be represented as 50 percents.
-int BucketizeImageMetrics(double ratio) {
- int ratio_percent = 10 * ratio;
- if (ratio_percent < 0)
- return 0;
- return ratio_percent > 100 ? 100 : ratio_percent;
-}
-
-inline const char* GetImagePolicyHistogramName(
- mojom::FeaturePolicyFeature feature) {
- switch (feature) {
- case mojom::FeaturePolicyFeature::kUnoptimizedLossyImages:
- return "Blink.UseCounter.FeaturePolicy.LossyImageCompression";
- case mojom::FeaturePolicyFeature::kUnoptimizedLosslessImages:
- return "Blink.UseCounter.FeaturePolicy.LosslessImageCompression";
- case mojom::FeaturePolicyFeature::kUnoptimizedLosslessImagesStrict:
- return "Blink.UseCounter.FeaturePolicy.StrictLosslessImageCompression";
- case mojom::FeaturePolicyFeature::kOversizedImages:
- return "Blink.UseCounter.FeaturePolicy.ImageDownscalingRatio";
- default:
- NOTREACHED();
- break;
- }
- return "";
-}
-
-} // namespace
-
// static
WTF::Vector<unsigned> SecurityContext::SerializeInsecureNavigationSet(
const InsecureNavigationsSet& set) {
@@ -83,27 +56,50 @@ WTF::Vector<unsigned> SecurityContext::SerializeInsecureNavigationSet(
return serialized;
}
-SecurityContext::SecurityContext()
- : SecurityContext(nullptr, WebSandboxFlags::kNone, nullptr) {}
-
-SecurityContext::SecurityContext(scoped_refptr<SecurityOrigin> origin,
- WebSandboxFlags sandbox_flags,
- std::unique_ptr<FeaturePolicy> feature_policy)
- : sandbox_flags_(sandbox_flags),
- security_origin_(std::move(origin)),
- feature_policy_(std::move(feature_policy)),
+SecurityContext::SecurityContext(const SecurityContextInit& init,
+ SecurityContextType context_type)
+ : sandbox_flags_(init.GetSandboxFlags()),
+ security_origin_(init.GetSecurityOrigin()),
+ feature_policy_(init.CreateFeaturePolicy()),
+ report_only_feature_policy_(init.CreateReportOnlyFeaturePolicy()),
+ document_policy_(init.CreateDocumentPolicy()),
+ report_only_document_policy_(init.CreateReportOnlyDocumentPolicy()),
+ content_security_policy_(init.GetCSP()),
address_space_(network::mojom::IPAddressSpace::kUnknown),
- insecure_request_policy_(kLeaveInsecureRequestsAlone),
- require_safe_types_(false) {}
-
-SecurityContext::~SecurityContext() = default;
-
-void SecurityContext::Trace(blink::Visitor* visitor) {
+ insecure_request_policy_(
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone),
+ require_safe_types_(false),
+ context_type_(context_type),
+ agent_(init.GetAgent()),
+ secure_context_mode_(init.GetSecureContextMode()),
+ origin_trial_context_(init.GetOriginTrialContext()),
+ bind_csp_immediately_(init.BindCSPImmediately()) {}
+
+void SecurityContext::Trace(Visitor* visitor) {
visitor->Trace(content_security_policy_);
+ visitor->Trace(agent_);
+ visitor->Trace(origin_trial_context_);
}
void SecurityContext::SetSecurityOrigin(
scoped_refptr<SecurityOrigin> security_origin) {
+ // Enforce that we don't change access, we might change the reference (via
+ // IsolatedCopy but we can't change the security policy).
+ CHECK(security_origin);
+ // The purpose of this check is to ensure that the SecurityContext does not
+ // change after script has executed in the ExecutionContext. If this is a
+ // RemoteSecurityContext, then there is no local script execution, so it is
+ // safe for the SecurityOrigin to change.
+ // Exempting null ExecutionContexts is also necessary because RemoteFrames and
+ // RemoteSecurityContexts do not change when a cross-origin navigation happens
+ // remotely.
+ CHECK(context_type_ == kRemote || !security_origin_ ||
+ security_origin_->CanAccess(security_origin.get()));
+ security_origin_ = std::move(security_origin);
+}
+
+void SecurityContext::SetSecurityOriginForTesting(
+ scoped_refptr<SecurityOrigin> security_origin) {
security_origin_ = std::move(security_origin);
}
@@ -112,30 +108,14 @@ void SecurityContext::SetContentSecurityPolicy(
content_security_policy_ = content_security_policy;
}
-bool SecurityContext::IsSandboxed(WebSandboxFlags mask) const {
+bool SecurityContext::IsSandboxed(mojom::blink::WebSandboxFlags mask) const {
if (RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) {
- mojom::FeaturePolicyFeature feature =
+ mojom::blink::FeaturePolicyFeature feature =
FeaturePolicy::FeatureForSandboxFlag(mask);
- if (feature != mojom::FeaturePolicyFeature::kNotFound)
+ if (feature != mojom::blink::FeaturePolicyFeature::kNotFound)
return !feature_policy_->IsFeatureEnabled(feature);
}
- return (sandbox_flags_ & mask) != WebSandboxFlags::kNone;
-}
-
-String SecurityContext::addressSpaceForBindings() const {
- switch (address_space_) {
- case network::mojom::IPAddressSpace::kPublic:
- case network::mojom::IPAddressSpace::kUnknown:
- return "public";
-
- case network::mojom::IPAddressSpace::kPrivate:
- return "private";
-
- case network::mojom::IPAddressSpace::kLocal:
- return "local";
- }
- NOTREACHED();
- return "public";
+ return (sandbox_flags_ & mask) != mojom::blink::WebSandboxFlags::kNone;
}
void SecurityContext::SetRequireTrustedTypes() {
@@ -154,114 +134,57 @@ bool SecurityContext::TrustedTypesRequiredByPolicy() const {
void SecurityContext::SetFeaturePolicy(
std::unique_ptr<FeaturePolicy> feature_policy) {
- // This method should be called before a FeaturePolicy has been created.
- DCHECK(!feature_policy_);
feature_policy_ = std::move(feature_policy);
}
-// Uses the parent enforcing policy as the basis for the report-only policy.
-void SecurityContext::AddReportOnlyFeaturePolicy(
- const ParsedFeaturePolicy& parsed_report_only_header,
- const ParsedFeaturePolicy& container_policy,
- const FeaturePolicy* parent_feature_policy) {
- report_only_feature_policy_ = FeaturePolicy::CreateFromParentPolicy(
- parent_feature_policy, container_policy, security_origin_->ToUrlOrigin());
- report_only_feature_policy_->SetHeaderPolicy(parsed_report_only_header);
-}
-
void SecurityContext::SetDocumentPolicyForTesting(
std::unique_ptr<DocumentPolicy> document_policy) {
document_policy_ = std::move(document_policy);
}
-bool SecurityContext::IsFeatureEnabled(mojom::FeaturePolicyFeature feature,
- ReportOptions report_on_failure,
- const String& message,
- const String& source_file) const {
+bool SecurityContext::IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature feature) const {
return IsFeatureEnabled(
- feature,
- PolicyValue::CreateMaxPolicyValue(
- feature_policy_->GetFeatureList().at(feature).second),
- report_on_failure, message, source_file);
+ feature, PolicyValue::CreateMaxPolicyValue(
+ feature_policy_->GetFeatureList().at(feature).second));
}
-bool SecurityContext::IsFeatureEnabled(mojom::FeaturePolicyFeature feature,
- PolicyValue threshold_value,
- ReportOptions report_on_failure,
- const String& message,
- const String& source_file) const {
- if (report_on_failure == ReportOptions::kReportOnFailure) {
- // We are expecting a violation report in case the feature is disabled in
- // the context. Therefore, this qualifies as a potential violation (i.e.,
- // if the feature was disabled it would generate a report).
- CountPotentialFeaturePolicyViolation(feature);
+bool SecurityContext::IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature feature,
+ PolicyValue threshold_value,
+ bool* should_report) const {
+ DCHECK(feature_policy_);
+ bool feature_policy_result =
+ feature_policy_->IsFeatureEnabled(feature, threshold_value);
+ bool report_only_feature_policy_result =
+ !report_only_feature_policy_ ||
+ report_only_feature_policy_->IsFeatureEnabled(feature, threshold_value);
+
+ if (should_report) {
+ *should_report =
+ !feature_policy_result || !report_only_feature_policy_result;
}
- bool document_policy_result =
- !(RuntimeEnabledFeatures::DocumentPolicyEnabled() && document_policy_) ||
- (document_policy_->IsFeatureSupported(feature) &&
- document_policy_->IsFeatureEnabled(feature, threshold_value));
-
- FeatureEnabledState state = GetFeatureEnabledState(feature, threshold_value);
- if (state == FeatureEnabledState::kEnabled)
- return document_policy_result;
- if (report_on_failure == ReportOptions::kReportOnFailure) {
- ReportFeaturePolicyViolation(
- feature,
- (state == FeatureEnabledState::kReportOnly
- ? mojom::FeaturePolicyDisposition::kReport
- : mojom::FeaturePolicyDisposition::kEnforce),
- message, source_file);
- }
- return (state != FeatureEnabledState::kDisabled) && document_policy_result;
+ return feature_policy_result;
}
-FeatureEnabledState SecurityContext::GetFeatureEnabledState(
- mojom::FeaturePolicyFeature feature) const {
- return GetFeatureEnabledState(
- feature, PolicyValue::CreateMaxPolicyValue(
- feature_policy_->GetFeatureList().at(feature).second));
+bool SecurityContext::IsFeatureEnabled(
+ mojom::blink::DocumentPolicyFeature feature) const {
+ DCHECK(GetDocumentPolicyFeatureInfoMap().at(feature).default_value.Type() ==
+ mojom::blink::PolicyValueType::kBool);
+ return IsFeatureEnabled(feature, PolicyValue(true)).enabled;
}
-FeatureEnabledState SecurityContext::GetFeatureEnabledState(
- mojom::FeaturePolicyFeature feature,
+SecurityContext::FeatureStatus SecurityContext::IsFeatureEnabled(
+ mojom::blink::DocumentPolicyFeature feature,
PolicyValue threshold_value) const {
- // The policy should always be initialized before checking it to ensure we
- // properly inherit the parent policy.
- DCHECK(feature_policy_);
-
- // Log metrics for unoptimized-*-images and oversized-images policies.
- if ((feature >= mojom::FeaturePolicyFeature::kUnoptimizedLossyImages &&
- feature <=
- mojom::FeaturePolicyFeature::kUnoptimizedLosslessImagesStrict) ||
- feature == mojom::FeaturePolicyFeature::kOversizedImages) {
- // Only log metrics if an image policy is specified.
- // If an image policy is specified, the policy value would be less than the
- // max value, otherwise by default the policy value is set to be the max
- // value.
- const auto max_value =
- PolicyValue::CreateMaxPolicyValue(mojom::PolicyValueType::kDecDouble);
- if (!feature_policy_->IsFeatureEnabled(feature, max_value) &&
- threshold_value < max_value) {
- STATIC_HISTOGRAM_POINTER_GROUP(
- GetImagePolicyHistogramName(feature), static_cast<int>(feature),
- static_cast<int>(
- mojom::FeaturePolicyFeature::kUnoptimizedLosslessImagesStrict) +
- 1,
- Add(BucketizeImageMetrics(threshold_value.DoubleValue())),
- base::LinearHistogram::FactoryGet(
- GetImagePolicyHistogramName(feature), 0, 100, 101, 0x1));
- }
- }
- if (feature_policy_->IsFeatureEnabled(feature, threshold_value)) {
- if (report_only_feature_policy_ &&
- !report_only_feature_policy_->IsFeatureEnabled(feature,
- threshold_value)) {
- return FeatureEnabledState::kReportOnly;
- }
- return FeatureEnabledState::kEnabled;
- }
- return FeatureEnabledState::kDisabled;
+ DCHECK(document_policy_);
+ bool policy_result =
+ document_policy_->IsFeatureEnabled(feature, threshold_value);
+ bool report_only_policy_result =
+ !report_only_document_policy_ ||
+ report_only_document_policy_->IsFeatureEnabled(feature, threshold_value);
+ return {policy_result, !policy_result || !report_only_policy_result};
}
} // namespace blink
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 4dab816dd24..1f7d760a026 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
@@ -34,9 +34,10 @@
#include "services/network/public/mojom/ip_address_space.mojom-blink-forward.h"
#include "third_party/blink/public/common/feature_policy/document_policy.h"
#include "third_party/blink/public/common/frame/sandbox_flags.h"
+#include "third_party/blink/public/mojom/feature_policy/document_policy_feature.mojom-blink-forward.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/public/platform/web_insecure_request_policy.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink-forward.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -46,18 +47,22 @@
namespace blink {
+class Agent;
class ContentSecurityPolicy;
class FeaturePolicy;
class PolicyValue;
+class OriginTrialContext;
+class SecurityContextInit;
class SecurityOrigin;
struct ParsedFeaturePolicyDeclaration;
using ParsedFeaturePolicy = std::vector<ParsedFeaturePolicyDeclaration>;
+enum class SecureContextMode { kInsecureContext, kSecureContext };
+
// Whether to report policy violations when checking whether a feature is
// enabled.
enum class ReportOptions { kReportOnFailure, kDoNotReport };
-enum class FeatureEnabledState { kDisabled, kReportOnly, kEnabled };
// Defines the security properties (such as the security origin, content
// security policy, and other restrictions) of an environment in which
@@ -67,9 +72,16 @@ enum class FeatureEnabledState { kDisabled, kReportOnly, kEnabled };
// out-of-process) environments do not have an ExecutionContext in the local
// process (as execution cannot occur locally), they do have a SecurityContext
// to allow those properties to be queried.
-class CORE_EXPORT SecurityContext : public GarbageCollectedMixin {
+class CORE_EXPORT SecurityContext {
+ DISALLOW_NEW();
+
public:
- void Trace(blink::Visitor*) override;
+ enum SecurityContextType { kLocal, kRemote };
+
+ SecurityContext(const SecurityContextInit&, SecurityContextType context_type);
+ virtual ~SecurityContext() = default;
+
+ void Trace(Visitor*);
using InsecureNavigationsSet = HashSet<unsigned, WTF::AlreadyHashed>;
static WTF::Vector<unsigned> SerializeInsecureNavigationSet(
@@ -83,20 +95,27 @@ class CORE_EXPORT SecurityContext : public GarbageCollectedMixin {
ContentSecurityPolicy* GetContentSecurityPolicy() const {
return content_security_policy_.Get();
}
+ void SetContentSecurityPolicy(ContentSecurityPolicy*);
- // Explicitly override the security origin for this security context.
- // Note: It is dangerous to change the security origin of a script context
- // that already contains content.
- virtual void SetSecurityOrigin(scoped_refptr<SecurityOrigin>);
+ // Explicitly override the security origin for this security context with
+ // safety CHECKs.
+ void SetSecurityOrigin(scoped_refptr<SecurityOrigin>);
- WebSandboxFlags GetSandboxFlags() const { return sandbox_flags_; }
- bool IsSandboxed(WebSandboxFlags mask) const;
+ // Like SetSecurityOrigin(), but no security CHECKs.
+ void SetSecurityOriginForTesting(scoped_refptr<SecurityOrigin>);
+
+ mojom::blink::WebSandboxFlags GetSandboxFlags() const {
+ return sandbox_flags_;
+ }
+ bool IsSandboxed(mojom::blink::WebSandboxFlags mask) const;
+ void ApplySandboxFlags(mojom::blink::WebSandboxFlags flags) {
+ sandbox_flags_ |= flags;
+ }
void SetAddressSpace(network::mojom::IPAddressSpace space) {
address_space_ = space;
}
network::mojom::IPAddressSpace AddressSpace() const { return address_space_; }
- String addressSpaceForBindings() const;
void SetRequireTrustedTypes();
void SetRequireTrustedTypesForTesting(); // Skips sanity checks.
@@ -119,10 +138,10 @@ class CORE_EXPORT SecurityContext : public GarbageCollectedMixin {
}
// https://w3c.github.io/webappsec-upgrade-insecure-requests/#insecure-requests-policy
- void SetInsecureRequestPolicy(WebInsecureRequestPolicy policy) {
+ void SetInsecureRequestPolicy(mojom::blink::InsecureRequestPolicy policy) {
insecure_request_policy_ = policy;
}
- WebInsecureRequestPolicy GetInsecureRequestPolicy() const {
+ mojom::blink::InsecureRequestPolicy GetInsecureRequestPolicy() const {
return insecure_request_policy_;
}
@@ -130,66 +149,73 @@ class CORE_EXPORT SecurityContext : public GarbageCollectedMixin {
return feature_policy_.get();
}
void SetFeaturePolicy(std::unique_ptr<FeaturePolicy> feature_policy);
- void AddReportOnlyFeaturePolicy(
- const ParsedFeaturePolicy& parsed_report_only_header,
- const ParsedFeaturePolicy& container_policy,
- const FeaturePolicy* parent_feature_policy);
const DocumentPolicy* GetDocumentPolicy() const {
return document_policy_.get();
}
+
+ const DocumentPolicy* GetReportOnlyDocumentPolicy() const {
+ return report_only_document_policy_.get();
+ }
+
void SetDocumentPolicyForTesting(
std::unique_ptr<DocumentPolicy> document_policy);
// Tests whether the policy-controlled feature is enabled in this frame.
- // Optionally sends a report to any registered reporting observers or
- // Report-To endpoints, via ReportFeaturePolicyViolation(), if the feature is
- // disabled. The optional ConsoleMessage will be sent to the console if
- // present, or else a default message will be used instead.
- bool IsFeatureEnabled(
- mojom::FeaturePolicyFeature,
- ReportOptions report_on_failure = ReportOptions::kDoNotReport,
- const String& message = g_empty_string,
- const String& source_file = g_empty_string) const;
- bool IsFeatureEnabled(
- mojom::FeaturePolicyFeature,
- PolicyValue threshold_value,
- ReportOptions report_on_failure = ReportOptions::kDoNotReport,
- const String& message = g_empty_string,
- const String& source_file = g_empty_string) const;
- FeatureEnabledState GetFeatureEnabledState(mojom::FeaturePolicyFeature) const;
- FeatureEnabledState GetFeatureEnabledState(mojom::FeaturePolicyFeature,
- PolicyValue threshold_value) const;
- virtual void CountPotentialFeaturePolicyViolation(
- mojom::FeaturePolicyFeature) const {}
- virtual void ReportFeaturePolicyViolation(
- mojom::FeaturePolicyFeature,
- mojom::FeaturePolicyDisposition,
- const String& message = g_empty_string,
- const String& source_file = g_empty_string) const {}
+ // Use ExecutionContext::IsFeatureEnabled if a failure should be reported.
+ // |should_report| is an extra return value that indicates whether
+ // the potential violation should be reported.
+ bool IsFeatureEnabled(mojom::blink::FeaturePolicyFeature) const;
+ bool IsFeatureEnabled(mojom::blink::FeaturePolicyFeature,
+ PolicyValue threshold_value,
+ bool* should_report = nullptr) const;
+
+ bool IsFeatureEnabled(mojom::blink::DocumentPolicyFeature) const;
+ struct FeatureStatus {
+ bool enabled; /* Whether the feature is enabled. */
+ bool should_report; /* Whether a report should be sent. */
+ };
+ FeatureStatus IsFeatureEnabled(mojom::blink::DocumentPolicyFeature,
+ PolicyValue threshold_value) const;
+
+ Agent* GetAgent() const { return agent_; }
+
+ OriginTrialContext* GetOriginTrialContext() const {
+ return origin_trial_context_;
+ }
- protected:
- SecurityContext();
- SecurityContext(scoped_refptr<SecurityOrigin> origin,
- WebSandboxFlags sandbox_flags,
- std::unique_ptr<FeaturePolicy> feature_policy);
- virtual ~SecurityContext();
+ SecureContextMode GetSecureContextMode() const {
+ // secure_context_mode_ is not initialized for RemoteSecurityContexts.
+ DCHECK_EQ(context_type_, kLocal);
+ return secure_context_mode_;
+ }
- void SetContentSecurityPolicy(ContentSecurityPolicy*);
+ void SetSecureContextModeForTesting(SecureContextMode mode) {
+ secure_context_mode_ = mode;
+ }
- WebSandboxFlags sandbox_flags_;
+ bool BindCSPImmediately() const { return bind_csp_immediately_; }
+
+ protected:
+ mojom::blink::WebSandboxFlags sandbox_flags_;
scoped_refptr<SecurityOrigin> security_origin_;
std::unique_ptr<FeaturePolicy> feature_policy_;
std::unique_ptr<FeaturePolicy> report_only_feature_policy_;
std::unique_ptr<DocumentPolicy> document_policy_;
+ std::unique_ptr<DocumentPolicy> report_only_document_policy_;
private:
Member<ContentSecurityPolicy> content_security_policy_;
network::mojom::IPAddressSpace address_space_;
- WebInsecureRequestPolicy insecure_request_policy_;
+ mojom::blink::InsecureRequestPolicy insecure_request_policy_;
InsecureNavigationsSet insecure_navigations_to_upgrade_;
bool require_safe_types_;
+ const SecurityContextType context_type_;
+ 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
new file mode 100644
index 00000000000..b667fa50ad6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/execution_context/security_context_init.cc
@@ -0,0 +1,522 @@
+// 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/execution_context/security_context_init.h"
+
+#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/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_frame.h"
+#include "third_party/blink/renderer/core/frame/local_frame_client.h"
+#include "third_party/blink/renderer/core/frame/settings.h"
+#include "third_party/blink/renderer/core/html/imports/html_imports_controller.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/origin_trials/origin_trial_context.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/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/web_test_support.h"
+
+namespace blink {
+namespace {
+
+// Helper function to filter out features that are not in origin trial in
+// ParsedDocumentPolicy.
+DocumentPolicy::ParsedDocumentPolicy FilterByOriginTrial(
+ const DocumentPolicy::ParsedDocumentPolicy& parsed_policy,
+ SecurityContextInit* init) {
+ DocumentPolicy::ParsedDocumentPolicy filtered_policy;
+ for (auto i = parsed_policy.feature_state.begin(),
+ last = parsed_policy.feature_state.end();
+ i != last;) {
+ if (!DisabledByOriginTrial(i->first, init))
+ filtered_policy.feature_state.insert(*i);
+ ++i;
+ }
+ for (auto i = parsed_policy.endpoint_map.begin(),
+ last = parsed_policy.endpoint_map.end();
+ i != last;) {
+ if (!DisabledByOriginTrial(i->first, init))
+ filtered_policy.endpoint_map.insert(*i);
+ ++i;
+ }
+ return filtered_policy;
+}
+
+} // namespace
+
+// This is the constructor used by RemoteSecurityContext
+SecurityContextInit::SecurityContextInit()
+ : SecurityContextInit(nullptr, 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)
+ : security_origin_(std::move(origin)),
+ origin_trials_(origin_trials),
+ agent_(agent),
+ secure_context_mode_(security_origin_ &&
+ security_origin_->IsPotentiallyTrustworthy()
+ ? SecureContextMode::kSecureContext
+ : SecureContextMode::kInsecureContext) {}
+
+// 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);
+
+ // The secure context state is based on the origin.
+ InitializeSecureContextMode(initializer);
+
+ // Initialize origin trials, requires the post sandbox flags
+ // security origin and secure context state.
+ InitializeOriginTrials(initializer);
+
+ // Initialize feature policy, depends on origin trials.
+ InitializeFeaturePolicy(initializer);
+
+ // Initialize document policy.
+ InitializeDocumentPolicy(initializer);
+
+ // Initialize the agent. Depends on security origin.
+ InitializeAgent(initializer);
+}
+
+bool SecurityContextInit::FeaturePolicyFeatureObserved(
+ mojom::blink::FeaturePolicyFeature feature) {
+ if (parsed_feature_policies_.Contains(feature))
+ return true;
+ parsed_feature_policies_.insert(feature);
+ return false;
+}
+
+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.ToExecutionContext()->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);
+}
+
+void SecurityContextInit::InitializeContentSecurityPolicy(
+ const DocumentInit& initializer) {
+ auto* frame = initializer.GetFrame();
+ ContentSecurityPolicy* last_origin_document_csp =
+ frame ? frame->Loader().GetLastOriginDocumentCSP() : nullptr;
+
+ KURL url;
+ if (initializer.ShouldSetURL())
+ url = initializer.Url().IsEmpty() ? BlankURL() : initializer.Url();
+
+ // Alias certain security properties from |owner_document|. Used for the
+ // case of about:blank pages inheriting the security properties of their
+ // requestor context.
+ //
+ // Note that this is currently somewhat broken; Blink always inherits from
+ // the parent or opener, even though it should actually be inherited from
+ // the request initiator.
+ if (url.IsEmpty() && initializer.HasSecurityContext() &&
+ !initializer.OriginToCommit() && initializer.OwnerDocument()) {
+ last_origin_document_csp =
+ initializer.OwnerDocument()->GetContentSecurityPolicy();
+ }
+
+ csp_ = initializer.GetContentSecurityPolicy();
+
+ if (!csp_) {
+ if (initializer.ImportsController()) {
+ // If this document is an HTML import, grab a reference to its master
+ // document's Content Security Policy. We don't bind the CSP's delegate
+ // in 'InitSecurityPolicy' in this case, as we can't rebind the master
+ // document's policy object: The Content Security Policy's delegate
+ // needs to remain set to the master document.
+ csp_ =
+ initializer.ImportsController()->Master()->GetContentSecurityPolicy();
+ return;
+ }
+
+ csp_ = MakeGarbageCollected<ContentSecurityPolicy>();
+ bind_csp_immediately_ = true;
+ }
+
+ // We should inherit the navigation initiator CSP if the document is loaded
+ // using a local-scheme url.
+ //
+ // Note: about:srcdoc inherits CSP from its parent, not from its initiator.
+ // In this case, the initializer.GetContentSecurityPolicy() is used.
+ if (last_origin_document_csp && !url.IsAboutSrcdocURL() &&
+ (url.IsEmpty() || url.ProtocolIsAbout() || url.ProtocolIsData() ||
+ url.ProtocolIs("blob") || url.ProtocolIs("filesystem"))) {
+ csp_->CopyStateFrom(last_origin_document_csp);
+ }
+
+ if (initializer.GetType() == DocumentInit::Type::kPlugin) {
+ if (last_origin_document_csp) {
+ csp_->CopyPluginTypesFrom(last_origin_document_csp);
+ return;
+ }
+
+ // TODO(andypaicu): This should inherit the origin document's plugin types
+ // but because this could be a OOPIF document it might not have access. In
+ // this situation we fallback on using the parent/opener:
+ if (frame) {
+ Frame* inherit_from = frame->Tree().Parent() ? frame->Tree().Parent()
+ : frame->Client()->Opener();
+ if (inherit_from && frame != inherit_from) {
+ csp_->CopyPluginTypesFrom(
+ inherit_from->GetSecurityContext()->GetContentSecurityPolicy());
+ }
+ }
+ }
+}
+
+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_ |= (mojom::blink::WebSandboxFlags::kAll &
+ ~(mojom::blink::WebSandboxFlags::kPopups |
+ mojom::blink::WebSandboxFlags::
+ kPropagatesToAuxiliaryBrowsingContexts));
+ }
+}
+
+void SecurityContextInit::InitializeOrigin(const DocumentInit& initializer) {
+ scoped_refptr<SecurityOrigin> document_origin =
+ initializer.GetDocumentOrigin();
+ if ((sandbox_flags_ & mojom::blink::WebSandboxFlags::kOrigin) !=
+ 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) {
+ // Because Document-Policy http header is parsed in DocumentLoader,
+ // when origin trial context is not initialized yet.
+ // Needs to filter out features that are not in origin trial after
+ // we have origin trial information available.
+ document_policy_ = FilterByOriginTrial(initializer.GetDocumentPolicy(), this);
+
+ base::Optional<DocumentPolicy::ParsedDocumentPolicy>
+ report_only_parsed_policy = DocumentPolicyParser::Parse(
+ initializer.ReportOnlyDocumentPolicyHeader());
+ if (report_only_parsed_policy) {
+ report_only_document_policy_ =
+ FilterByOriginTrial(*report_only_parsed_policy, this);
+ }
+}
+
+void SecurityContextInit::InitializeFeaturePolicy(
+ const DocumentInit& initializer) {
+ initialized_feature_policy_state_ = true;
+ // If we are a HTMLViewSourceDocument we use container, header or
+ // inherited policies. https://crbug.com/898688. Don't set any from the
+ // initializer or frame below.
+ if (initializer.GetType() == DocumentInit::Type::kViewSource)
+ return;
+
+ auto* frame = initializer.GetFrame();
+ // For a main frame, get inherited feature policy from the opener if any.
+ if (frame && frame->IsMainFrame() && !frame->OpenerFeatureState().empty())
+ frame_for_opener_feature_state_ = frame;
+
+ feature_policy_header_ = FeaturePolicyParser::ParseHeader(
+ initializer.FeaturePolicyHeader(), security_origin_,
+ &feature_policy_parse_messages_, this);
+
+ report_only_feature_policy_header_ = FeaturePolicyParser::ParseHeader(
+ initializer.ReportOnlyFeaturePolicyHeader(), security_origin_,
+ &report_only_feature_policy_parse_messages_, this);
+
+ if (sandbox_flags_ != mojom::blink::WebSandboxFlags::kNone &&
+ RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) {
+ // The sandbox flags might have come from CSP header or the browser; in
+ // such cases the sandbox is not part of the container policy. They are
+ // added to the header policy (which specifically makes sense in the case
+ // of CSP sandbox).
+ ApplySandboxFlagsToParsedFeaturePolicy(sandbox_flags_,
+ feature_policy_header_);
+ }
+
+ if (frame && frame->Owner()) {
+ container_policy_ =
+ initializer.GetFramePolicy().value_or(FramePolicy()).container_policy;
+ }
+
+ // TODO(icelland): This is problematic querying sandbox flags before
+ // feature policy is initialized.
+ if (RuntimeEnabledFeatures::BlockingFocusWithoutUserActivationEnabled() &&
+ frame && frame->Tree().Parent() &&
+ (sandbox_flags_ & mojom::blink::WebSandboxFlags::kNavigation) !=
+ mojom::blink::WebSandboxFlags::kNone) {
+ // Enforcing the policy for sandbox frames (for context see
+ // https://crbug.com/954349).
+ DisallowFeatureIfNotPresent(
+ mojom::blink::FeaturePolicyFeature::kFocusWithoutUserActivation,
+ container_policy_);
+ }
+
+ if (frame && !frame->IsMainFrame())
+ parent_frame_ = frame->Tree().Parent();
+}
+
+std::unique_ptr<FeaturePolicy>
+SecurityContextInit::CreateReportOnlyFeaturePolicy() const {
+ // For non-Document initialization, returns nullptr directly.
+ if (!initialized_feature_policy_state_)
+ return nullptr;
+
+ // If header not present, returns nullptr directly.
+ if (report_only_feature_policy_header_.empty())
+ return nullptr;
+
+ // Report-only feature policy only takes effect when it is stricter than
+ // enforced feature policy, i.e. when enforced feature policy allows a feature
+ // while report-only feature policy do not. In such scenario, a report-only
+ // policy violation report will be generated, but the feature is still allowed
+ // to be used. Since child frames cannot loosen enforced feature policy, there
+ // is no need to inherit parent policy and container policy for report-only
+ // feature policy. For inherited policies, the behavior is dominated by
+ // enforced feature policy.
+ DCHECK(security_origin_);
+ std::unique_ptr<FeaturePolicy> report_only_policy =
+ FeaturePolicy::CreateFromParentPolicy(nullptr /* parent_policy */,
+ {} /* container_policy */,
+ security_origin_->ToUrlOrigin());
+ report_only_policy->SetHeaderPolicy(report_only_feature_policy_header_);
+ return report_only_policy;
+}
+
+std::unique_ptr<FeaturePolicy> SecurityContextInit::CreateFeaturePolicy()
+ const {
+ // For non-Document initialization, returns nullptr directly.
+ if (!initialized_feature_policy_state_)
+ return nullptr;
+
+ // Feature policy should either come from a parent in the case of an
+ // embedded child frame, or from an opener if any when a new window is
+ // created by an opener. A main frame without an opener would not have a
+ // parent policy nor an opener feature state.
+ DCHECK(!parent_frame_ || !frame_for_opener_feature_state_);
+ std::unique_ptr<FeaturePolicy> feature_policy;
+ if (!frame_for_opener_feature_state_ ||
+ !RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) {
+ auto* parent_feature_policy =
+ parent_frame_ ? parent_frame_->GetSecurityContext()->GetFeaturePolicy()
+ : nullptr;
+ feature_policy = FeaturePolicy::CreateFromParentPolicy(
+ parent_feature_policy, container_policy_,
+ security_origin_->ToUrlOrigin());
+ } else {
+ DCHECK(!parent_frame_);
+ feature_policy = FeaturePolicy::CreateWithOpenerPolicy(
+ frame_for_opener_feature_state_->OpenerFeatureState(),
+ security_origin_->ToUrlOrigin());
+ }
+ feature_policy->SetHeaderPolicy(feature_policy_header_);
+ return feature_policy;
+}
+
+std::unique_ptr<DocumentPolicy> SecurityContextInit::CreateDocumentPolicy()
+ const {
+ return DocumentPolicy::CreateWithHeaderPolicy(document_policy_);
+}
+
+std::unique_ptr<DocumentPolicy>
+SecurityContextInit::CreateReportOnlyDocumentPolicy() const {
+ return report_only_document_policy_.feature_state.empty()
+ ? nullptr
+ : DocumentPolicy::CreateWithHeaderPolicy(
+ report_only_document_policy_);
+}
+
+void SecurityContextInit::InitializeSecureContextMode(
+ const DocumentInit& initializer) {
+ auto* frame = initializer.GetFrame();
+ if (!security_origin_->IsPotentiallyTrustworthy()) {
+ secure_context_mode_ = SecureContextMode::kInsecureContext;
+ } else if (SchemeRegistry::SchemeShouldBypassSecureContextCheck(
+ security_origin_->Protocol())) {
+ secure_context_mode_ = SecureContextMode::kSecureContext;
+ } else if (frame) {
+ Frame* parent = frame->Tree().Parent();
+ while (parent) {
+ if (!parent->GetSecurityContext()
+ ->GetSecurityOrigin()
+ ->IsPotentiallyTrustworthy()) {
+ secure_context_mode_ = SecureContextMode::kInsecureContext;
+ break;
+ }
+ parent = parent->Tree().Parent();
+ }
+ if (!secure_context_mode_.has_value())
+ secure_context_mode_ = SecureContextMode::kSecureContext;
+ } else {
+ secure_context_mode_ = SecureContextMode::kInsecureContext;
+ }
+ bool is_secure = secure_context_mode_ == SecureContextMode::kSecureContext;
+ if (GetSandboxFlags() != mojom::blink::WebSandboxFlags::kNone) {
+ feature_count_.insert(
+ is_secure ? WebFeature::kSecureContextCheckForSandboxedOriginPassed
+ : WebFeature::kSecureContextCheckForSandboxedOriginFailed);
+ }
+ feature_count_.insert(is_secure ? WebFeature::kSecureContextCheckPassed
+ : WebFeature::kSecureContextCheckFailed);
+}
+
+void SecurityContextInit::InitializeOriginTrials(
+ const DocumentInit& initializer) {
+ DCHECK(secure_context_mode_.has_value());
+ origin_trials_ = MakeGarbageCollected<OriginTrialContext>();
+
+ const String& header_value = initializer.OriginTrialsHeader();
+
+ if (header_value.IsEmpty())
+ return;
+ std::unique_ptr<Vector<String>> tokens(
+ OriginTrialContext::ParseHeaderValue(header_value));
+ 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());
+}
+
+} // 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
new file mode 100644
index 00000000000..5546eafbd70
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/execution_context/security_context_init.h
@@ -0,0 +1,117 @@
+// 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_EXECUTION_CONTEXT_SECURITY_CONTEXT_INIT_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_EXECUTION_CONTEXT_SECURITY_CONTEXT_INIT_H_
+
+#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/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;
+class Frame;
+class LocalFrame;
+class OriginTrialContext;
+class SecurityOrigin;
+
+class CORE_EXPORT SecurityContextInit : public FeaturePolicyParserDelegate {
+ STACK_ALLOCATED();
+
+ public:
+ SecurityContextInit();
+ SecurityContextInit(scoped_refptr<SecurityOrigin>,
+ OriginTrialContext*,
+ Agent*);
+ explicit SecurityContextInit(const DocumentInit&);
+
+ const scoped_refptr<SecurityOrigin>& GetSecurityOrigin() const {
+ return security_origin_;
+ }
+
+ mojom::blink::WebSandboxFlags GetSandboxFlags() const {
+ return sandbox_flags_;
+ }
+
+ ContentSecurityPolicy* GetCSP() const { return csp_; }
+
+ // Returns nullptr if SecurityContext is used for non-Document contexts(i.e.,
+ // workers and tests).
+ std::unique_ptr<FeaturePolicy> CreateFeaturePolicy() const;
+ // Returns nullptr if SecurityContext is used for non-Document contexts(i.e.,
+ // workers and tests).
+ // Returns nullptr if there is no 'Feature-Policy-Report-Only' header present
+ // in http response.
+ std::unique_ptr<FeaturePolicy> CreateReportOnlyFeaturePolicy() const;
+
+ std::unique_ptr<DocumentPolicy> CreateDocumentPolicy() const;
+ std::unique_ptr<DocumentPolicy> CreateReportOnlyDocumentPolicy() const;
+
+ const ParsedFeaturePolicy& FeaturePolicyHeader() const {
+ return feature_policy_header_;
+ }
+
+ 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);
+ }
+
+ 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_;
+ mojom::blink::WebSandboxFlags sandbox_flags_ =
+ mojom::blink::WebSandboxFlags::kNone;
+ 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_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EXECUTION_CONTEXT_SECURITY_CONTEXT_INIT_H_
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 fa2ca8aefb4..bdabde9a120 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 4267ac4afc3..bd423bf4123 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(blink::Visitor* visitor) {
+void WindowAgentFactory::Trace(Visitor* visitor) {
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 c289564e841..2e1bfb36450 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(blink::Visitor*);
+ void Trace(Visitor*);
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 069f2e17000..347d7237ce5 100644
--- a/chromium/third_party/blink/renderer/core/exported/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/exported/BUILD.gn
@@ -1,6 +1,7 @@
# 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.
+import("//build/config/dcheck_always_on.gni")
import("//third_party/blink/renderer/core/core.gni")
blink_core_sources("exported") {
@@ -24,6 +25,8 @@ blink_core_sources("exported") {
"web_dom_message_event.cc",
"web_element.cc",
"web_element_collection.cc",
+ "web_external_widget_impl.cc",
+ "web_external_widget_impl.h",
"web_form_control_element.cc",
"web_form_element.cc",
"web_form_element_observer_impl.cc",
@@ -48,7 +51,6 @@ blink_core_sources("exported") {
"web_navigation_params.cc",
"web_node.cc",
"web_option_element.cc",
- "web_page_importance_signals.cc",
"web_page_popup_impl.cc",
"web_page_popup_impl.h",
"web_performance.cc",
@@ -61,7 +63,6 @@ blink_core_sources("exported") {
"web_remote_frame_impl.h",
"web_render_theme.cc",
"web_scoped_page_pauser.cc",
- "web_scoped_user_gesture.cc",
"web_scoped_window_focus_allowed_indicator.cc",
"web_script_controller.cc",
"web_script_source.cc",
@@ -75,11 +76,19 @@ blink_core_sources("exported") {
"web_shared_worker_impl.cc",
"web_shared_worker_impl.h",
"web_text_checking_result.cc",
- "web_user_gesture_indicator.cc",
"web_v8_context_snapshot.cc",
"web_view_impl.cc",
"web_view_impl.h",
]
+ if (is_debug || dcheck_always_on) {
+ sources += [ "web_disallow_transition_scope.cc" ]
+ }
+
+ deps = [
+ "//ui/base/cursor",
+ "//ui/base/mojom:cursor_type_blink",
+ ]
+
defines = [ "BLINK_IMPLEMENTATION=1" ]
}
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 914a3ef227a..cb7aa76af1c 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
@@ -38,12 +38,12 @@
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "third_party/blink/public/common/blob/blob_utils.h"
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
-#include "third_party/blink/public/common/frame/user_activation_update_type.h"
+#include "third_party/blink/public/mojom/frame/navigation_initiator.mojom-blink.h"
+#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom-blink-forward.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider_client.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_media_player_source.h"
-#include "third_party/blink/public/platform/web_scroll_into_view_params.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/public/platform/web_url_error.h"
@@ -158,6 +158,75 @@ void ResetWheelAndTouchEventHandlerProperties(LocalFrame& frame) {
cc::EventListenerProperties::kNone);
}
+// TODO(arthursonzogni): Remove this when BeginNavigation will be sent directly
+// from blink.
+WebContentSecurityPolicySourceExpression ConvertToPublic(
+ network::mojom::blink::CSPSourcePtr source) {
+ return {source->scheme,
+ source->host,
+ source->is_host_wildcard ? kWebWildcardDispositionHasWildcard
+ : kWebWildcardDispositionNoWildcard,
+ source->port,
+ source->is_port_wildcard ? kWebWildcardDispositionHasWildcard
+ : kWebWildcardDispositionNoWildcard,
+ source->path};
+}
+
+// TODO(arthursonzogni): Remove this when BeginNavigation will be sent directly
+// from blink.
+WebContentSecurityPolicySourceList ConvertToPublic(
+ network::mojom::blink::CSPSourceListPtr source_list) {
+ WebVector<WebContentSecurityPolicySourceExpression> sources(
+ source_list->sources.size());
+ for (size_t i = 0; i < sources.size(); ++i)
+ sources[i] = ConvertToPublic(std::move(source_list->sources[i]));
+ return {source_list->allow_self, source_list->allow_star,
+ source_list->allow_response_redirects, std::move(sources)};
+}
+
+// TODO(arthursonzogni): Remove this when BeginNavigation will be sent directly
+// from blink.
+WebString ConvertToPublic(
+ network::mojom::blink::CSPDirectiveName directive_name) {
+ using CSPDirectiveName = network::mojom::blink::CSPDirectiveName;
+ switch (directive_name) {
+ case CSPDirectiveName::DefaultSrc:
+ return "default-src";
+ case CSPDirectiveName::ChildSrc:
+ return "child-src";
+ case CSPDirectiveName::FrameSrc:
+ return "frame-src";
+ case CSPDirectiveName::FormAction:
+ return "form-action";
+ case CSPDirectiveName::UpgradeInsecureRequests:
+ return "upgrade-insecure-requests";
+ case CSPDirectiveName::NavigateTo:
+ return "navigate-to";
+ case CSPDirectiveName::FrameAncestors:
+ return "frame-ancestors";
+ case CSPDirectiveName::Unknown:
+ NOTREACHED();
+ return "";
+ };
+}
+
+// TODO(arthursonzogni): Remove this when BeginNavigation will be sent directly
+// from blink.
+WebContentSecurityPolicy ConvertToPublic(
+ network::mojom::blink::ContentSecurityPolicyPtr policy) {
+ WebVector<WebContentSecurityPolicyDirective> directives(
+ policy->directives.size());
+ size_t i = 0;
+ for (auto& directive : policy->directives) {
+ directives[i++] = {ConvertToPublic(directive.key),
+ ConvertToPublic(std::move(directive.value))};
+ }
+
+ return {policy->header->type, policy->header->source,
+ std::move(directives), std::move(policy->report_endpoints),
+ policy->header->header_value, policy->use_reporting_api};
+}
+
} // namespace
LocalFrameClientImpl::LocalFrameClientImpl(WebLocalFrameImpl* frame)
@@ -165,7 +234,7 @@ LocalFrameClientImpl::LocalFrameClientImpl(WebLocalFrameImpl* frame)
LocalFrameClientImpl::~LocalFrameClientImpl() = default;
-void LocalFrameClientImpl::Trace(blink::Visitor* visitor) {
+void LocalFrameClientImpl::Trace(Visitor* visitor) {
visitor->Trace(web_frame_);
LocalFrameClient::Trace(visitor);
}
@@ -179,9 +248,17 @@ WebContentCaptureClient* LocalFrameClientImpl::GetWebContentCaptureClient()
return web_frame_->ContentCaptureClient();
}
-void LocalFrameClientImpl::DidCreateNewDocument() {
+void LocalFrameClientImpl::DidCreateInitialEmptyDocument() {
if (web_frame_->Client())
- web_frame_->Client()->DidCreateNewDocument();
+ web_frame_->Client()->DidCreateInitialEmptyDocument();
+}
+
+void LocalFrameClientImpl::DidCommitJavascriptUrlNavigation(
+ DocumentLoader* loader) {
+ if (web_frame_->Client()) {
+ web_frame_->Client()->DidCommitJavascriptUrlNavigation(
+ WebDocumentLoaderImpl::FromDocumentLoader(loader));
+ }
}
void LocalFrameClientImpl::DispatchDidClearWindowObjectInMainWorld() {
@@ -404,23 +481,9 @@ void LocalFrameClientImpl::DidFinishSameDocumentNavigation(
}
}
-void LocalFrameClientImpl::DispatchDidStartProvisionalLoad(
- DocumentLoader* loader) {
- if (web_frame_->Client()) {
- web_frame_->Client()->DidStartProvisionalLoad(
- WebDocumentLoaderImpl::FromDocumentLoader(loader));
- }
-}
-
void LocalFrameClientImpl::DispatchDidReceiveTitle(const String& title) {
if (web_frame_->Client()) {
- web_frame_->Client()->DidReceiveTitle(title, kWebTextDirectionLeftToRight);
- }
-}
-
-void LocalFrameClientImpl::DispatchDidChangeIcons(IconType type) {
- if (web_frame_->Client()) {
- web_frame_->Client()->DidChangeIcon(static_cast<WebIconURL::Type>(type));
+ web_frame_->Client()->DidReceiveTitle(title);
}
}
@@ -434,7 +497,7 @@ void LocalFrameClientImpl::DispatchDidCommitLoad(
}
if (web_frame_->Client()) {
- web_frame_->Client()->DidCommitProvisionalLoad(
+ web_frame_->Client()->DidCommitNavigation(
WebHistoryItem(item), commit_type,
global_object_reuse_policy == GlobalObjectReusePolicy::kCreateNew);
if (web_frame_->GetFrame()->IsLocalRoot()) {
@@ -463,7 +526,7 @@ void LocalFrameClientImpl::DispatchDidFinishLoad() {
void LocalFrameClientImpl::BeginNavigation(
const ResourceRequest& request,
- network::mojom::RequestContextFrameType frame_type,
+ mojom::RequestContextFrameType frame_type,
Document* origin_document,
DocumentLoader* document_loader,
WebNavigationType type,
@@ -473,12 +536,13 @@ void LocalFrameClientImpl::BeginNavigation(
bool is_client_redirect,
TriggeringEventInfo triggering_event_info,
HTMLFormElement* form,
- ContentSecurityPolicyDisposition
+ network::mojom::CSPDisposition
should_check_main_world_content_security_policy,
mojo::PendingRemote<mojom::blink::BlobURLToken> blob_url_token,
base::TimeTicks input_start_time,
const String& href_translate,
- WebContentSecurityPolicyList initiator_csp,
+ WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr> initiator_csp,
+ network::mojom::blink::CSPSourcePtr initiator_self_source,
network::mojom::IPAddressSpace initiator_address_space,
mojo::PendingRemote<mojom::blink::NavigationInitiator>
navigation_initiator) {
@@ -486,7 +550,7 @@ void LocalFrameClientImpl::BeginNavigation(
return;
auto navigation_info = std::make_unique<WebNavigationInfo>();
- navigation_info->url_request = WrappedResourceRequest(request);
+ navigation_info->url_request.CopyFrom(WrappedResourceRequest(request));
navigation_info->frame_type = frame_type;
navigation_info->navigation_type = type;
navigation_info->navigation_policy = static_cast<WebNavigationPolicy>(policy);
@@ -495,16 +559,20 @@ void LocalFrameClientImpl::BeginNavigation(
navigation_info->is_client_redirect = is_client_redirect;
navigation_info->triggering_event_info = triggering_event_info;
navigation_info->should_check_main_world_content_security_policy =
- should_check_main_world_content_security_policy ==
- kCheckContentSecurityPolicy
- ? kWebContentSecurityPolicyDispositionCheck
- : kWebContentSecurityPolicyDispositionDoNotCheck;
+ should_check_main_world_content_security_policy;
navigation_info->blob_url_token = blob_url_token.PassPipe();
navigation_info->input_start = input_start_time;
- navigation_info->initiator_csp = std::move(initiator_csp);
+ for (auto& policy : initiator_csp) {
+ navigation_info->initiator_csp.emplace_back(
+ ConvertToPublic(std::move(policy)));
+ }
+ if (initiator_self_source) {
+ navigation_info->initiator_self_source =
+ ConvertToPublic(std::move(initiator_self_source));
+ }
navigation_info->initiator_address_space = initiator_address_space;
- navigation_info->navigation_initiator_handle =
- navigation_initiator.PassPipe();
+ navigation_info->navigation_initiator_remote =
+ std::move(navigation_initiator);
// Can be null.
LocalFrame* local_parent_frame = GetLocalParentFrame(web_frame_);
@@ -535,7 +603,8 @@ void LocalFrameClientImpl::BeginNavigation(
frame->Client()->Opener() == ToCoreFrame(web_frame_);
navigation_info->initiator_frame_has_download_sandbox_flag =
frame->GetSecurityContext() &&
- frame->GetSecurityContext()->IsSandboxed(WebSandboxFlags::kDownloads);
+ frame->GetSecurityContext()->IsSandboxed(
+ mojom::blink::WebSandboxFlags::kDownloads);
navigation_info->initiator_frame_is_ad = frame->IsAdSubframe();
}
@@ -551,8 +620,9 @@ void LocalFrameClientImpl::BeginNavigation(
// stack is not available here.
std::unique_ptr<SourceLocation> source_location =
origin_document
- ? SourceLocation::Capture(origin_document)
- : SourceLocation::Capture(web_frame_->GetFrame()->GetDocument());
+ ? SourceLocation::Capture(origin_document->ToExecutionContext())
+ : SourceLocation::Capture(
+ web_frame_->GetFrame()->GetDocument()->ToExecutionContext());
if (source_location && !source_location->IsUnknown()) {
navigation_info->source_location.url = source_location->Url();
navigation_info->source_location.line_number =
@@ -563,7 +633,7 @@ void LocalFrameClientImpl::BeginNavigation(
std::unique_ptr<Vector<OriginTrialFeature>> initiator_origin_trial_features =
OriginTrialContext::GetEnabledNavigationFeatures(
- web_frame_->GetFrame()->GetDocument());
+ web_frame_->GetFrame()->GetDocument()->ToExecutionContext());
if (initiator_origin_trial_features) {
navigation_info->initiator_origin_trial_features.reserve(
initiator_origin_trial_features->size());
@@ -603,37 +673,11 @@ void LocalFrameClientImpl::DidStartLoading() {
}
}
-void LocalFrameClientImpl::ProgressEstimateChanged(double progress_estimate) {
- if (web_frame_->Client())
- web_frame_->Client()->DidChangeLoadProgress(progress_estimate);
-}
-
void LocalFrameClientImpl::DidStopLoading() {
if (web_frame_->Client())
web_frame_->Client()->DidStopLoading();
}
-void LocalFrameClientImpl::ForwardResourceTimingToParent(
- const WebResourceTimingInfo& info) {
- web_frame_->Client()->ForwardResourceTimingToParent(info);
-}
-
-void LocalFrameClientImpl::DownloadURL(
- const ResourceRequest& request,
- network::mojom::RedirectMode cross_origin_redirect_behavior) {
- if (!web_frame_->Client())
- return;
- DCHECK(web_frame_->GetFrame()->GetDocument());
- mojo::PendingRemote<mojom::blink::BlobURLToken> blob_url_token;
- if (request.Url().ProtocolIs("blob")) {
- web_frame_->GetFrame()->GetDocument()->GetPublicURLManager().Resolve(
- request.Url(), blob_url_token.InitWithNewPipeAndPassReceiver());
- }
- web_frame_->Client()->DownloadURL(WrappedResourceRequest(request),
- cross_origin_redirect_behavior,
- blob_url_token.PassPipe());
-}
-
bool LocalFrameClientImpl::NavigateBackForward(int offset) const {
WebViewImpl* webview = web_frame_->ViewImpl();
DCHECK(webview->Client());
@@ -647,15 +691,11 @@ bool LocalFrameClientImpl::NavigateBackForward(int offset) const {
bool has_user_gesture =
LocalFrame::HasTransientUserActivation(web_frame_->GetFrame());
- web_frame_->Client()->NavigateBackForwardSoon(offset, has_user_gesture);
+ web_frame_->GetFrame()->GetLocalFrameHostRemote().GoToEntryAtOffset(
+ offset, has_user_gesture);
return true;
}
-void LocalFrameClientImpl::DidAccessInitialDocument() {
- if (web_frame_->Client())
- web_frame_->Client()->DidAccessInitialDocument();
-}
-
void LocalFrameClientImpl::DidRunInsecureContent(const SecurityOrigin* origin,
const KURL& insecure_url) {
if (web_frame_->Client()) {
@@ -684,6 +724,12 @@ void LocalFrameClientImpl::DidChangePerformanceTiming() {
web_frame_->Client()->DidChangePerformanceTiming();
}
+void LocalFrameClientImpl::DidObserveInputDelay(base::TimeDelta input_delay) {
+ if (web_frame_->Client()) {
+ web_frame_->Client()->DidObserveInputDelay(input_delay);
+ }
+}
+
void LocalFrameClientImpl::DidChangeCpuTiming(base::TimeDelta time) {
if (web_frame_->Client())
web_frame_->Client()->DidChangeCpuTiming(time);
@@ -740,11 +786,13 @@ void LocalFrameClientImpl::SelectorMatchChanged(
DocumentLoader* LocalFrameClientImpl::CreateDocumentLoader(
LocalFrame* frame,
WebNavigationType navigation_type,
+ ContentSecurityPolicy* content_security_policy,
std::unique_ptr<WebNavigationParams> navigation_params,
std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) {
DCHECK(frame);
WebDocumentLoaderImpl* document_loader =
MakeGarbageCollected<WebDocumentLoaderImpl>(frame, navigation_type,
+ content_security_policy,
std::move(navigation_params));
document_loader->SetExtraData(std::move(extra_data));
if (web_frame_->Client())
@@ -770,8 +818,12 @@ String LocalFrameClientImpl::UserAgent() {
return user_agent_;
}
-blink::UserAgentMetadata LocalFrameClientImpl::UserAgentMetadata() {
- // TODO(mkwst): Support devtools override.
+base::Optional<UserAgentMetadata> LocalFrameClientImpl::UserAgentMetadata() {
+ bool ua_override_on = web_frame_->Client() &&
+ !web_frame_->Client()->UserAgentOverride().IsEmpty();
+ if (ua_override_on)
+ return web_frame_->Client()->UserAgentMetadataOverride();
+
if (user_agent_metadata_.brand.empty())
user_agent_metadata_ = Platform::Current()->UserAgentMetadata();
return user_agent_metadata_;
@@ -879,20 +931,16 @@ void LocalFrameClientImpl::DidChangeFramePolicy(
}
void LocalFrameClientImpl::DidSetFramePolicyHeaders(
- WebSandboxFlags sandbox_flags,
- const ParsedFeaturePolicy& parsed_header) {
+ mojom::blink::WebSandboxFlags sandbox_flags,
+ const ParsedFeaturePolicy& feature_policy_header,
+ const DocumentPolicy::FeatureState& document_policy_header) {
if (web_frame_->Client()) {
web_frame_->Client()->DidSetFramePolicyHeaders(
- static_cast<WebSandboxFlags>(sandbox_flags), parsed_header);
+ static_cast<mojom::blink::WebSandboxFlags>(sandbox_flags),
+ feature_policy_header, document_policy_header);
}
}
-void LocalFrameClientImpl::DidAddContentSecurityPolicies(
- const blink::WebVector<WebContentSecurityPolicy>& policies) {
- if (web_frame_->Client())
- web_frame_->Client()->DidAddContentSecurityPolicies(policies);
-}
-
void LocalFrameClientImpl::DidChangeFrameOwnerProperties(
HTMLFrameOwnerElement* frame_element) {
if (!web_frame_->Client())
@@ -902,17 +950,12 @@ void LocalFrameClientImpl::DidChangeFrameOwnerProperties(
WebFrame::FromFrame(frame_element->ContentFrame()),
WebFrameOwnerProperties(
frame_element->BrowsingContextContainerName(),
- frame_element->ScrollingMode(), frame_element->MarginWidth(),
+ frame_element->ScrollbarMode(), frame_element->MarginWidth(),
frame_element->MarginHeight(), frame_element->AllowFullscreen(),
frame_element->AllowPaymentRequest(), frame_element->IsDisplayNone(),
frame_element->RequiredCsp()));
}
-bool LocalFrameClientImpl::ShouldBlockWebGL() {
- DCHECK(web_frame_->Client());
- return web_frame_->Client()->ShouldBlockWebGL();
-}
-
std::unique_ptr<WebServiceWorkerProvider>
LocalFrameClientImpl::CreateServiceWorkerProvider() {
if (!web_frame_->Client())
@@ -951,30 +994,11 @@ KURL LocalFrameClientImpl::OverrideFlashEmbedWithHTML(const KURL& url) {
return web_frame_->Client()->OverrideFlashEmbedWithHTML(WebURL(url));
}
-void LocalFrameClientImpl::NotifyUserActivation(
- bool need_browser_verification) {
- DCHECK(web_frame_->Client());
- UserActivationUpdateType update_type =
- need_browser_verification
- ? UserActivationUpdateType::
- kNotifyActivationPendingBrowserVerification
- : UserActivationUpdateType::kNotifyActivation;
- web_frame_->Client()->UpdateUserActivationState(update_type);
+void LocalFrameClientImpl::NotifyUserActivation() {
if (WebAutofillClient* autofill_client = web_frame_->AutofillClient())
autofill_client->UserGestureObserved();
}
-void LocalFrameClientImpl::ConsumeUserActivation() {
- DCHECK(web_frame_->Client());
- web_frame_->Client()->UpdateUserActivationState(
- UserActivationUpdateType::kConsumeTransientActivation);
-}
-
-void LocalFrameClientImpl::SetHasReceivedUserGestureBeforeNavigation(
- bool value) {
- web_frame_->Client()->SetHasReceivedUserGestureBeforeNavigation(value);
-}
-
void LocalFrameClientImpl::AbortClientNavigation() {
if (web_frame_->Client())
web_frame_->Client()->AbortClientNavigation();
@@ -994,11 +1018,6 @@ LocalFrameClientImpl::CreateURLLoaderFactory() {
return web_frame_->Client()->CreateURLLoaderFactory();
}
-service_manager::InterfaceProvider*
-LocalFrameClientImpl::GetInterfaceProvider() {
- return web_frame_->Client()->GetInterfaceProvider();
-}
-
blink::BrowserInterfaceBrokerProxy&
LocalFrameClientImpl::GetBrowserInterfaceBroker() {
return *web_frame_->Client()->GetBrowserInterfaceBroker();
@@ -1013,31 +1032,10 @@ void LocalFrameClientImpl::AnnotatedRegionsChanged() {
web_frame_->Client()->DraggableRegionsChanged();
}
-void LocalFrameClientImpl::DidBlockNavigation(
- const KURL& blocked_url,
- const KURL& initiator_url,
- blink::NavigationBlockedReason reason) {
- web_frame_->Client()->DidBlockNavigation(blocked_url, initiator_url, reason);
-}
-
base::UnguessableToken LocalFrameClientImpl::GetDevToolsFrameToken() const {
return web_frame_->Client()->GetDevToolsFrameToken();
}
-void LocalFrameClientImpl::ScrollRectToVisibleInParentFrame(
- const WebRect& rect_to_scroll,
- const WebScrollIntoViewParams& params) {
- web_frame_->Client()->ScrollRectToVisibleInParentFrame(rect_to_scroll,
- params);
-}
-
-void LocalFrameClientImpl::BubbleLogicalScrollInParentFrame(
- ScrollDirection direction,
- ScrollGranularity granularity) {
- web_frame_->Client()->BubbleLogicalScrollInParentFrame(direction,
- granularity);
-}
-
String LocalFrameClientImpl::evaluateInInspectorOverlayForTesting(
const String& script) {
if (WebDevToolsAgentImpl* devtools = DevToolsAgent())
@@ -1071,6 +1069,18 @@ void LocalFrameClientImpl::FrameRectsChanged(const IntRect& frame_rect) {
web_frame_->Client()->FrameRectsChanged(frame_rect);
}
+void LocalFrameClientImpl::FocusedElementChanged(Element* element) {
+ DCHECK(web_frame_->Client());
+ web_frame_->Client()->FocusedElementChanged(element);
+}
+
+void LocalFrameClientImpl::OnMainFrameDocumentIntersectionChanged(
+ const IntRect& intersection_rect) {
+ DCHECK(web_frame_->Client());
+ web_frame_->Client()->OnMainFrameDocumentIntersectionChanged(
+ intersection_rect);
+}
+
bool LocalFrameClientImpl::IsPluginHandledExternally(
HTMLPlugInElement& plugin_element,
const KURL& resource_url,
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 d3e0914e70a..74f08e06333 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
@@ -36,16 +36,15 @@
#include "base/memory/scoped_refptr.h"
-#include "mojo/public/cpp/bindings/binding_set.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 "third_party/blink/public/platform/web_insecure_request_policy.h"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -54,20 +53,20 @@ class WebDevToolsAgentImpl;
class WebLocalFrameImpl;
class WebSpellCheckPanelHostClient;
enum class GlobalObjectReusePolicy;
-struct WebScrollIntoViewParams;
class LocalFrameClientImpl final : public LocalFrameClient {
public:
explicit LocalFrameClientImpl(WebLocalFrameImpl*);
~LocalFrameClientImpl() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
WebLocalFrameImpl* GetWebFrame() const override;
// LocalFrameClient ----------------------------------------------
WebContentCaptureClient* GetWebContentCaptureClient() const override;
- void DidCreateNewDocument() override;
+ void DidCreateInitialEmptyDocument() override;
+ void DidCommitJavascriptUrlNavigation(DocumentLoader*) override;
// Notifies the WebView delegate that the JS window object has been cleared,
// giving it a chance to bind native objects to the window before script
// parsing begins.
@@ -102,9 +101,7 @@ class LocalFrameClientImpl final : public LocalFrameClient {
void DidFinishSameDocumentNavigation(HistoryItem*,
WebHistoryCommitType,
bool content_initiated) override;
- void DispatchDidStartProvisionalLoad(DocumentLoader*) override;
void DispatchDidReceiveTitle(const String&) override;
- void DispatchDidChangeIcons(IconType) override;
void DispatchDidCommitLoad(HistoryItem*,
WebHistoryCommitType,
GlobalObjectReusePolicy) override;
@@ -114,7 +111,7 @@ class LocalFrameClientImpl final : public LocalFrameClient {
void BeginNavigation(
const ResourceRequest&,
- network::mojom::RequestContextFrameType,
+ mojom::RequestContextFrameType,
Document* origin_document,
DocumentLoader*,
WebNavigationType,
@@ -124,28 +121,26 @@ class LocalFrameClientImpl final : public LocalFrameClient {
bool is_client_redirect,
TriggeringEventInfo,
HTMLFormElement*,
- ContentSecurityPolicyDisposition should_bypass_main_world_csp,
+ network::mojom::CSPDisposition should_bypass_main_world_csp,
mojo::PendingRemote<mojom::blink::BlobURLToken>,
base::TimeTicks input_start_time,
const String& href_translate,
- WebContentSecurityPolicyList,
+ WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr>
+ initiator_csp,
+ network::mojom::blink::CSPSourcePtr initiator_self_source,
network::mojom::IPAddressSpace,
mojo::PendingRemote<mojom::blink::NavigationInitiator>) override;
void DispatchWillSendSubmitEvent(HTMLFormElement*) override;
void DidStartLoading() override;
void DidStopLoading() override;
- void ProgressEstimateChanged(double progress_estimate) override;
- void ForwardResourceTimingToParent(const WebResourceTimingInfo&) override;
- void DownloadURL(const ResourceRequest&,
- network::mojom::RedirectMode) override;
bool NavigateBackForward(int offset) const override;
- void DidAccessInitialDocument() override;
void DidRunInsecureContent(const SecurityOrigin*,
const KURL& insecure_url) override;
void DidDispatchPingLoader(const KURL&) override;
void DidDisplayContentWithCertificateErrors() override;
void DidRunContentWithCertificateErrors() override;
void DidChangePerformanceTiming() override;
+ void DidObserveInputDelay(base::TimeDelta) override;
void DidChangeCpuTiming(base::TimeDelta) override;
void DidObserveLoadingBehavior(LoadingBehaviorFlag) override;
void DidObserveNewFeatureUsage(mojom::WebFeature) override;
@@ -164,6 +159,7 @@ class LocalFrameClientImpl final : public LocalFrameClient {
DocumentLoader* CreateDocumentLoader(
LocalFrame*,
WebNavigationType,
+ ContentSecurityPolicy*,
std::unique_ptr<WebNavigationParams> navigation_params,
std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) override;
@@ -173,7 +169,7 @@ class LocalFrameClientImpl final : public LocalFrameClient {
DocumentLoader* document_loader,
std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) override;
WTF::String UserAgent() override;
- blink::UserAgentMetadata UserAgentMetadata() override;
+ base::Optional<blink::UserAgentMetadata> UserAgentMetadata() override;
WTF::String DoNotTrackValue() override;
void TransitionToCommittedForNewPage() override;
LocalFrame* CreateFrame(const WTF::AtomicString& name,
@@ -203,14 +199,11 @@ class LocalFrameClientImpl final : public LocalFrameClient {
void DidChangeName(const String&) override;
void DidChangeFramePolicy(Frame* child_frame, const FramePolicy&) override;
void DidSetFramePolicyHeaders(
- WebSandboxFlags,
- const ParsedFeaturePolicy& parsed_header) override;
- void DidAddContentSecurityPolicies(
- const blink::WebVector<WebContentSecurityPolicy>&) override;
+ mojom::blink::WebSandboxFlags,
+ const ParsedFeaturePolicy& fp_header,
+ const blink::DocumentPolicy::FeatureState& dp_header) override;
void DidChangeFrameOwnerProperties(HTMLFrameOwnerElement*) override;
- bool ShouldBlockWebGL() override;
-
std::unique_ptr<WebServiceWorkerProvider> CreateServiceWorkerProvider()
override;
WebContentSettingsClient* GetContentSettingsClient() override;
@@ -223,10 +216,7 @@ class LocalFrameClientImpl final : public LocalFrameClient {
KURL OverrideFlashEmbedWithHTML(const KURL&) override;
- void NotifyUserActivation(bool need_browser_verification) override;
- void ConsumeUserActivation() override;
-
- void SetHasReceivedUserGestureBeforeNavigation(bool value) override;
+ void NotifyUserActivation() override;
void AbortClientNavigation() override;
@@ -236,8 +226,6 @@ class LocalFrameClientImpl final : public LocalFrameClient {
std::unique_ptr<WebURLLoaderFactory> CreateURLLoaderFactory() override;
- service_manager::InterfaceProvider* GetInterfaceProvider() override;
-
blink::BrowserInterfaceBrokerProxy& GetBrowserInterfaceBroker() override;
AssociatedInterfaceProvider* GetRemoteNavigationAssociatedInterfaces()
@@ -245,19 +233,8 @@ class LocalFrameClientImpl final : public LocalFrameClient {
void AnnotatedRegionsChanged() override;
- void DidBlockNavigation(const KURL& blocked_url,
- const KURL& initiator_url,
- blink::NavigationBlockedReason reason) override;
-
base::UnguessableToken GetDevToolsFrameToken() const override;
- void ScrollRectToVisibleInParentFrame(
- const WebRect&,
- const WebScrollIntoViewParams&) override;
-
- void BubbleLogicalScrollInParentFrame(ScrollDirection direction,
- ScrollGranularity granularity) override;
-
String evaluateInInspectorOverlayForTesting(const String& script) override;
bool HandleCurrentKeyboardEvent() override;
@@ -270,6 +247,11 @@ class LocalFrameClientImpl final : public LocalFrameClient {
void FrameRectsChanged(const IntRect&) override;
+ void FocusedElementChanged(Element* element) override;
+
+ void OnMainFrameDocumentIntersectionChanged(
+ const IntRect& intersection_rect) override;
+
bool IsPluginHandledExternally(HTMLPlugInElement&,
const KURL&,
const String&) override;
@@ -305,11 +287,12 @@ class LocalFrameClientImpl final : public LocalFrameClient {
blink::UserAgentMetadata user_agent_metadata_;
};
-DEFINE_TYPE_CASTS(LocalFrameClientImpl,
- LocalFrameClient,
- client,
- client->IsLocalFrameClientImpl(),
- client.IsLocalFrameClientImpl());
+template <>
+struct DowncastTraits<LocalFrameClientImpl> {
+ static bool AllowFrom(const LocalFrameClient& client) {
+ return client.IsLocalFrameClientImpl();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/exported/local_frame_client_impl_test.cc b/chromium/third_party/blink/renderer/core/exported/local_frame_client_impl_test.cc
index 72d5ced22c5..8dc3268dd7d 100644
--- a/chromium/third_party/blink/renderer/core/exported/local_frame_client_impl_test.cc
+++ b/chromium/third_party/blink/renderer/core/exported/local_frame_client_impl_test.cc
@@ -69,8 +69,10 @@ class LocalFrameClientImplTest : public testing::Test {
void TearDown() override {
// Tearing down the WebView by resetting the helper will call
// UserAgentOverride() in order to store the information for detached
- // requests.
- EXPECT_CALL(WebLocalFrameClient(), UserAgentOverride());
+ // requests. This will happen twice since UserAgentOverride() is called
+ // for UserAgentMetadata() saving as well.
+ EXPECT_CALL(WebLocalFrameClient(), UserAgentOverride())
+ .WillRepeatedly(Return(WebString()));
helper_.Reset();
}
@@ -86,7 +88,7 @@ class LocalFrameClientImplTest : public testing::Test {
return web_frame_client_;
}
LocalFrameClient& GetLocalFrameClient() {
- return *ToLocalFrameClientImpl(MainFrame()->GetFrame()->Client());
+ return *To<LocalFrameClientImpl>(MainFrame()->GetFrame()->Client());
}
private:
diff --git a/chromium/third_party/blink/renderer/core/exported/prerendering_test.cc b/chromium/third_party/blink/renderer/core/exported/prerendering_test.cc
index 0b11b32af89..66cd92d9c1b 100644
--- a/chromium/third_party/blink/renderer/core/exported/prerendering_test.cc
+++ b/chromium/third_party/blink/renderer/core/exported/prerendering_test.cc
@@ -33,11 +33,12 @@
#include <memory>
#include "base/memory/ptr_util.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/common/prerender/prerender_rel_type.h"
+#include "third_party/blink/public/mojom/prerender/prerender.mojom-blink.h"
#include "third_party/blink/public/platform/web_cache.h"
-#include "third_party/blink/public/platform/web_prerender.h"
-#include "third_party/blink/public/platform/web_prerendering_support.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
#include "third_party/blink/public/web/web_frame.h"
@@ -57,111 +58,111 @@ namespace blink {
namespace {
-WebURL ToWebURL(const char* url) {
- return WebURL(blink::url_test_helpers::ToKURL(url));
-}
-
class TestWebPrerendererClient : public WebPrerendererClient {
public:
TestWebPrerendererClient() = default;
virtual ~TestWebPrerendererClient() = default;
- void SetExtraDataForNextPrerender(WebPrerender::ExtraData* extra_data) {
- DCHECK(!extra_data_);
- extra_data_ = base::WrapUnique(extra_data);
- }
-
- WebPrerender ReleaseWebPrerender() {
- DCHECK(!web_prerenders_.empty());
- WebPrerender retval(web_prerenders_.front());
- web_prerenders_.pop_front();
- return retval;
- }
-
- bool empty() const { return web_prerenders_.empty(); }
-
- void Clear() { web_prerenders_.clear(); }
-
private:
- // From WebPrerendererClient:
- void WillAddPrerender(WebPrerender* prerender) override {
- prerender->SetExtraData(extra_data_.release());
-
- DCHECK(!prerender->IsNull());
- web_prerenders_.push_back(*prerender);
- }
-
bool IsPrefetchOnly() override { return false; }
-
- std::unique_ptr<WebPrerender::ExtraData> extra_data_;
- std::list<WebPrerender> web_prerenders_;
};
-class TestPrerenderingSupport : public WebPrerenderingSupport {
+class MockPrerender : public mojom::blink::PrerenderHandle {
public:
- TestPrerenderingSupport() { Initialize(this); }
-
- ~TestPrerenderingSupport() override { Shutdown(); }
-
- void Clear() {
- added_prerenders_.clear();
- canceled_prerenders_.clear();
- abandoned_prerenders_.clear();
+ explicit MockPrerender(
+ mojom::blink::PrerenderAttributesPtr attributes,
+ mojo::PendingRemote<mojom::blink::PrerenderHandleClient> client,
+ mojo::PendingReceiver<mojom::blink::PrerenderHandle> handle)
+ : attributes_(std::move(attributes)),
+ client_(std::move(client)),
+ receiver_(this, std::move(handle)) {}
+ ~MockPrerender() override = default;
+
+ const KURL& Url() const { return attributes_->url; }
+ uint32_t RelTypes() const { return attributes_->rel_types; }
+
+ // Returns the number of times |Cancel| was called.
+ size_t CancelCount() const { return cancel_count_; }
+
+ // Returns the number of times |Abandon| was called.
+ size_t AbandonCount() const { return abandon_count_; }
+
+ // Used to simulate state changes of the mock prerendered web page. These
+ // calls spin the message loop so that the client's receiver side gets a
+ // chance to run.
+ void NotifyDidStartPrerender() {
+ client_->OnPrerenderStart();
+ test::RunPendingTasks();
}
-
- size_t TotalCount() const {
- return added_prerenders_.size() + canceled_prerenders_.size() +
- abandoned_prerenders_.size();
+ void NotifyDidSendDOMContentLoadedForPrerender() {
+ client_->OnPrerenderDomContentLoaded();
+ test::RunPendingTasks();
}
-
- size_t AddCount(const WebPrerender& prerender) const {
- return std::count_if(added_prerenders_.begin(), added_prerenders_.end(),
- [&prerender](const WebPrerender& other) {
- return other.ToPrerender() ==
- prerender.ToPrerender();
- });
+ void NotifyDidSendLoadForPrerender() {
+ client_->OnPrerenderStopLoading();
+ test::RunPendingTasks();
}
-
- size_t CancelCount(const WebPrerender& prerender) const {
- return std::count_if(
- canceled_prerenders_.begin(), canceled_prerenders_.end(),
- [&prerender](const WebPrerender& other) {
- return other.ToPrerender() == prerender.ToPrerender();
- });
+ void NotifyDidStopPrerender() {
+ client_->OnPrerenderStop();
+ test::RunPendingTasks();
}
- size_t AbandonCount(const WebPrerender& prerender) const {
- return std::count_if(
- abandoned_prerenders_.begin(), abandoned_prerenders_.end(),
- [&prerender](const WebPrerender& other) {
- return other.ToPrerender() == prerender.ToPrerender();
- });
- }
+ // mojom::blink::PrerenderHandle implementation
+ void Cancel() override { cancel_count_++; }
+ void Abandon() override { abandon_count_++; }
private:
- // From WebPrerenderingSupport:
- void Add(const WebPrerender& prerender) override {
- added_prerenders_.push_back(prerender);
- }
+ mojom::blink::PrerenderAttributesPtr attributes_;
+ mojo::Remote<mojom::blink::PrerenderHandleClient> client_;
+ mojo::Receiver<mojom::blink::PrerenderHandle> receiver_;
+ size_t cancel_count_ = 0;
+ size_t abandon_count_ = 0;
+};
- void Cancel(const WebPrerender& prerender) override {
- canceled_prerenders_.push_back(prerender);
+class MockPrerenderProcessor : public mojom::blink::PrerenderProcessor {
+ public:
+ MockPrerenderProcessor() = default;
+ ~MockPrerenderProcessor() override = default;
+
+ // Returns the number of times |AddPrerender| was called.
+ size_t AddCount() const { return add_count_; }
+
+ std::unique_ptr<MockPrerender> ReleasePrerender() {
+ std::unique_ptr<MockPrerender> rv;
+ if (!prerenders_.empty()) {
+ rv = std::move(prerenders_.front());
+ prerenders_.pop();
+ }
+ return rv;
}
- void Abandon(const WebPrerender& prerender) override {
- abandoned_prerenders_.push_back(prerender);
+ void Bind(mojo::ScopedMessagePipeHandle message_pipe_handle) {
+ receiver_set_.Add(this,
+ mojo::PendingReceiver<mojom::blink::PrerenderProcessor>(
+ std::move(message_pipe_handle)));
}
- void PrefetchFinished() override {}
+ // mojom::blink::PrerenderProcessor implementation
+ void AddPrerender(
+ mojom::blink::PrerenderAttributesPtr attributes,
+ mojo::PendingRemote<mojom::blink::PrerenderHandleClient> client,
+ mojo::PendingReceiver<mojom::blink::PrerenderHandle> handle) override {
+ prerenders_.push(std::make_unique<MockPrerender>(
+ std::move(attributes), std::move(client), std::move(handle)));
+ add_count_++;
+ }
- Vector<WebPrerender> added_prerenders_;
- Vector<WebPrerender> canceled_prerenders_;
- Vector<WebPrerender> abandoned_prerenders_;
+ private:
+ mojo::ReceiverSet<mojom::blink::PrerenderProcessor> receiver_set_;
+ std::queue<std::unique_ptr<MockPrerender>> prerenders_;
+ size_t add_count_ = 0;
};
class PrerenderingTest : public testing::Test {
public:
~PrerenderingTest() override {
+ if (web_view_helper_.GetWebView())
+ UnregisterMockPrerenderProcessor();
url_test_helpers::UnregisterAllURLsAndClearMemoryCache();
}
@@ -174,6 +175,14 @@ class PrerenderingTest : public testing::Test {
web_view_helper_.Initialize();
web_view_helper_.GetWebView()->SetPrerendererClient(&prerenderer_client_);
+ web_view_helper_.LocalMainFrame()
+ ->GetFrame()
+ ->GetBrowserInterfaceBroker()
+ .SetBinderForTesting(
+ mojom::blink::PrerenderProcessor::Name_,
+ WTF::BindRepeating(&MockPrerenderProcessor::Bind,
+ WTF::Unretained(&mock_prerender_processor_)));
+
frame_test_helpers::LoadFrame(
web_view_helper_.GetWebView()->MainFrameImpl(),
std::string(base_url) + file_name);
@@ -182,13 +191,17 @@ class PrerenderingTest : public testing::Test {
void NavigateAway() {
frame_test_helpers::LoadFrame(
web_view_helper_.GetWebView()->MainFrameImpl(), "about:blank");
+ test::RunPendingTasks();
}
void Close() {
+ UnregisterMockPrerenderProcessor();
web_view_helper_.LocalMainFrame()->CollectGarbageForTesting();
web_view_helper_.Reset();
WebCache::Clear();
+
+ test::RunPendingTasks();
}
Element& Console() {
@@ -216,17 +229,24 @@ class PrerenderingTest : public testing::Test {
void ExecuteScript(const char* code) {
web_view_helper_.LocalMainFrame()->ExecuteScript(
WebScriptSource(WebString::FromUTF8(code)));
- }
-
- TestPrerenderingSupport* PrerenderingSupport() {
- return &prerendering_support_;
+ test::RunPendingTasks();
}
TestWebPrerendererClient* PrerendererClient() { return &prerenderer_client_; }
+ MockPrerenderProcessor* PrerenderProcessor() {
+ return &mock_prerender_processor_;
+ }
private:
- TestPrerenderingSupport prerendering_support_;
+ void UnregisterMockPrerenderProcessor() {
+ web_view_helper_.LocalMainFrame()
+ ->GetFrame()
+ ->GetBrowserInterfaceBroker()
+ .SetBinderForTesting(mojom::blink::PrerenderProcessor::Name_, {});
+ }
+
TestWebPrerendererClient prerenderer_client_;
+ MockPrerenderProcessor mock_prerender_processor_;
frame_test_helpers::WebViewHelper web_view_helper_;
};
@@ -236,28 +256,30 @@ class PrerenderingTest : public testing::Test {
TEST_F(PrerenderingTest, SinglePrerender) {
Initialize("http://www.foo.com/", "prerender/single_prerender.html");
- WebPrerender web_prerender = PrerendererClient()->ReleaseWebPrerender();
- EXPECT_FALSE(web_prerender.IsNull());
- EXPECT_EQ(ToWebURL("http://prerender.com/"), web_prerender.Url());
+ std::unique_ptr<MockPrerender> prerender =
+ PrerenderProcessor()->ReleasePrerender();
+ EXPECT_TRUE(prerender);
+ EXPECT_EQ(KURL("http://prerender.com/"), prerender->Url());
EXPECT_EQ(static_cast<unsigned>(kPrerenderRelTypePrerender),
- web_prerender.RelTypes());
+ prerender->RelTypes());
- EXPECT_EQ(1u, PrerenderingSupport()->AddCount(web_prerender));
- EXPECT_EQ(1u, PrerenderingSupport()->TotalCount());
+ EXPECT_EQ(1u, PrerenderProcessor()->AddCount());
+ EXPECT_EQ(0u, prerender->CancelCount());
+ EXPECT_EQ(0u, prerender->AbandonCount());
- web_prerender.DidStartPrerender();
+ prerender->NotifyDidStartPrerender();
EXPECT_EQ(1u, ConsoleLength());
EXPECT_EQ("webkitprerenderstart", ConsoleAt(0));
- web_prerender.DidSendDOMContentLoadedForPrerender();
+ prerender->NotifyDidSendDOMContentLoadedForPrerender();
EXPECT_EQ(2u, ConsoleLength());
EXPECT_EQ("webkitprerenderdomcontentloaded", ConsoleAt(1));
- web_prerender.DidSendLoadForPrerender();
+ prerender->NotifyDidSendLoadForPrerender();
EXPECT_EQ(3u, ConsoleLength());
EXPECT_EQ("webkitprerenderload", ConsoleAt(2));
- web_prerender.DidStopPrerender();
+ prerender->NotifyDidStopPrerender();
EXPECT_EQ(4u, ConsoleLength());
EXPECT_EQ("webkitprerenderstop", ConsoleAt(3));
}
@@ -265,86 +287,71 @@ TEST_F(PrerenderingTest, SinglePrerender) {
TEST_F(PrerenderingTest, CancelPrerender) {
Initialize("http://www.foo.com/", "prerender/single_prerender.html");
- WebPrerender web_prerender = PrerendererClient()->ReleaseWebPrerender();
- EXPECT_FALSE(web_prerender.IsNull());
+ std::unique_ptr<MockPrerender> prerender =
+ PrerenderProcessor()->ReleasePrerender();
+ EXPECT_TRUE(prerender);
- EXPECT_EQ(1u, PrerenderingSupport()->AddCount(web_prerender));
- EXPECT_EQ(1u, PrerenderingSupport()->TotalCount());
+ EXPECT_EQ(1u, PrerenderProcessor()->AddCount());
+ EXPECT_EQ(0u, prerender->CancelCount());
+ EXPECT_EQ(0u, prerender->AbandonCount());
ExecuteScript("removePrerender()");
- EXPECT_EQ(1u, PrerenderingSupport()->CancelCount(web_prerender));
- EXPECT_EQ(2u, PrerenderingSupport()->TotalCount());
+ EXPECT_EQ(1u, PrerenderProcessor()->AddCount());
+ EXPECT_EQ(1u, prerender->CancelCount());
+ EXPECT_EQ(0u, prerender->AbandonCount());
}
TEST_F(PrerenderingTest, AbandonPrerender) {
Initialize("http://www.foo.com/", "prerender/single_prerender.html");
- WebPrerender web_prerender = PrerendererClient()->ReleaseWebPrerender();
- EXPECT_FALSE(web_prerender.IsNull());
+ std::unique_ptr<MockPrerender> prerender =
+ PrerenderProcessor()->ReleasePrerender();
+ EXPECT_TRUE(prerender);
- EXPECT_EQ(1u, PrerenderingSupport()->AddCount(web_prerender));
- EXPECT_EQ(1u, PrerenderingSupport()->TotalCount());
+ EXPECT_EQ(1u, PrerenderProcessor()->AddCount());
+ EXPECT_EQ(0u, prerender->CancelCount());
+ EXPECT_EQ(0u, prerender->AbandonCount());
NavigateAway();
- EXPECT_EQ(1u, PrerenderingSupport()->AbandonCount(web_prerender));
- EXPECT_EQ(2u, PrerenderingSupport()->TotalCount());
+ EXPECT_EQ(1u, PrerenderProcessor()->AddCount());
+ EXPECT_EQ(0u, prerender->CancelCount());
+ EXPECT_EQ(1u, prerender->AbandonCount());
// Check that the prerender does not emit an extra cancel when
// garbage-collecting everything.
Close();
- EXPECT_EQ(2u, PrerenderingSupport()->TotalCount());
-}
-
-TEST_F(PrerenderingTest, ExtraData) {
- class TestExtraData : public WebPrerender::ExtraData {
- public:
- explicit TestExtraData(bool* alive) : alive_(alive) { *alive = true; }
-
- ~TestExtraData() override { *alive_ = false; }
-
- private:
- bool* alive_;
- };
-
- bool alive = false;
- {
- PrerendererClient()->SetExtraDataForNextPrerender(
- new TestExtraData(&alive));
- Initialize("http://www.foo.com/", "prerender/single_prerender.html");
- EXPECT_TRUE(alive);
-
- WebPrerender web_prerender = PrerendererClient()->ReleaseWebPrerender();
-
- ExecuteScript("removePrerender()");
- Close();
- PrerenderingSupport()->Clear();
- }
- EXPECT_FALSE(alive);
+ EXPECT_EQ(1u, PrerenderProcessor()->AddCount());
+ EXPECT_EQ(0u, prerender->CancelCount());
+ EXPECT_EQ(1u, prerender->AbandonCount());
}
TEST_F(PrerenderingTest, TwoPrerenders) {
Initialize("http://www.foo.com/", "prerender/multiple_prerenders.html");
- WebPrerender first_prerender = PrerendererClient()->ReleaseWebPrerender();
- EXPECT_FALSE(first_prerender.IsNull());
- EXPECT_EQ(ToWebURL("http://first-prerender.com/"), first_prerender.Url());
+ std::unique_ptr<MockPrerender> first_prerender =
+ PrerenderProcessor()->ReleasePrerender();
+ EXPECT_TRUE(first_prerender);
+ EXPECT_EQ(KURL("http://first-prerender.com/"), first_prerender->Url());
- WebPrerender second_prerender = PrerendererClient()->ReleaseWebPrerender();
- EXPECT_FALSE(first_prerender.IsNull());
- EXPECT_EQ(ToWebURL("http://second-prerender.com/"), second_prerender.Url());
+ std::unique_ptr<MockPrerender> second_prerender =
+ PrerenderProcessor()->ReleasePrerender();
+ EXPECT_TRUE(first_prerender);
+ EXPECT_EQ(KURL("http://second-prerender.com/"), second_prerender->Url());
- EXPECT_EQ(1u, PrerenderingSupport()->AddCount(first_prerender));
- EXPECT_EQ(1u, PrerenderingSupport()->AddCount(second_prerender));
- EXPECT_EQ(2u, PrerenderingSupport()->TotalCount());
+ EXPECT_EQ(2u, PrerenderProcessor()->AddCount());
+ EXPECT_EQ(0u, first_prerender->CancelCount());
+ EXPECT_EQ(0u, first_prerender->AbandonCount());
+ EXPECT_EQ(0u, second_prerender->CancelCount());
+ EXPECT_EQ(0u, second_prerender->AbandonCount());
- first_prerender.DidStartPrerender();
+ first_prerender->NotifyDidStartPrerender();
EXPECT_EQ(1u, ConsoleLength());
EXPECT_EQ("first_webkitprerenderstart", ConsoleAt(0));
- second_prerender.DidStartPrerender();
+ second_prerender->NotifyDidStartPrerender();
EXPECT_EQ(2u, ConsoleLength());
EXPECT_EQ("second_webkitprerenderstart", ConsoleAt(1));
}
@@ -352,71 +359,95 @@ TEST_F(PrerenderingTest, TwoPrerenders) {
TEST_F(PrerenderingTest, TwoPrerendersRemovingFirstThenNavigating) {
Initialize("http://www.foo.com/", "prerender/multiple_prerenders.html");
- WebPrerender first_prerender = PrerendererClient()->ReleaseWebPrerender();
- WebPrerender second_prerender = PrerendererClient()->ReleaseWebPrerender();
+ std::unique_ptr<MockPrerender> first_prerender =
+ PrerenderProcessor()->ReleasePrerender();
+ std::unique_ptr<MockPrerender> second_prerender =
+ PrerenderProcessor()->ReleasePrerender();
- EXPECT_EQ(1u, PrerenderingSupport()->AddCount(first_prerender));
- EXPECT_EQ(1u, PrerenderingSupport()->AddCount(second_prerender));
- EXPECT_EQ(2u, PrerenderingSupport()->TotalCount());
+ EXPECT_EQ(2u, PrerenderProcessor()->AddCount());
+ EXPECT_EQ(0u, first_prerender->CancelCount());
+ EXPECT_EQ(0u, first_prerender->AbandonCount());
+ EXPECT_EQ(0u, second_prerender->CancelCount());
+ EXPECT_EQ(0u, second_prerender->AbandonCount());
ExecuteScript("removeFirstPrerender()");
- EXPECT_EQ(1u, PrerenderingSupport()->CancelCount(first_prerender));
- EXPECT_EQ(3u, PrerenderingSupport()->TotalCount());
+ EXPECT_EQ(2u, PrerenderProcessor()->AddCount());
+ EXPECT_EQ(1u, first_prerender->CancelCount());
+ EXPECT_EQ(0u, first_prerender->AbandonCount());
+ EXPECT_EQ(0u, second_prerender->CancelCount());
+ EXPECT_EQ(0u, second_prerender->AbandonCount());
NavigateAway();
- EXPECT_EQ(1u, PrerenderingSupport()->AbandonCount(second_prerender));
- EXPECT_EQ(4u, PrerenderingSupport()->TotalCount());
+ EXPECT_EQ(2u, PrerenderProcessor()->AddCount());
+ EXPECT_EQ(1u, first_prerender->CancelCount());
+ EXPECT_EQ(0u, first_prerender->AbandonCount());
+ EXPECT_EQ(0u, second_prerender->CancelCount());
+ EXPECT_EQ(1u, second_prerender->AbandonCount());
}
TEST_F(PrerenderingTest, TwoPrerendersAddingThird) {
Initialize("http://www.foo.com/", "prerender/multiple_prerenders.html");
- WebPrerender first_prerender = PrerendererClient()->ReleaseWebPrerender();
- WebPrerender second_prerender = PrerendererClient()->ReleaseWebPrerender();
+ std::unique_ptr<MockPrerender> first_prerender =
+ PrerenderProcessor()->ReleasePrerender();
+ std::unique_ptr<MockPrerender> second_prerender =
+ PrerenderProcessor()->ReleasePrerender();
- EXPECT_EQ(1u, PrerenderingSupport()->AddCount(first_prerender));
- EXPECT_EQ(1u, PrerenderingSupport()->AddCount(second_prerender));
- EXPECT_EQ(2u, PrerenderingSupport()->TotalCount());
+ EXPECT_EQ(2u, PrerenderProcessor()->AddCount());
+ EXPECT_EQ(0u, first_prerender->CancelCount());
+ EXPECT_EQ(0u, first_prerender->AbandonCount());
+ EXPECT_EQ(0u, second_prerender->CancelCount());
+ EXPECT_EQ(0u, second_prerender->AbandonCount());
ExecuteScript("addThirdPrerender()");
- WebPrerender third_prerender = PrerendererClient()->ReleaseWebPrerender();
- EXPECT_EQ(1u, PrerenderingSupport()->AddCount(third_prerender));
- EXPECT_EQ(3u, PrerenderingSupport()->TotalCount());
+ std::unique_ptr<MockPrerender> third_prerender =
+ PrerenderProcessor()->ReleasePrerender();
+
+ EXPECT_EQ(3u, PrerenderProcessor()->AddCount());
+ EXPECT_EQ(0u, first_prerender->CancelCount());
+ EXPECT_EQ(0u, first_prerender->AbandonCount());
+ EXPECT_EQ(0u, second_prerender->CancelCount());
+ EXPECT_EQ(0u, second_prerender->AbandonCount());
+ EXPECT_EQ(0u, third_prerender->CancelCount());
+ EXPECT_EQ(0u, third_prerender->AbandonCount());
}
TEST_F(PrerenderingTest, ShortLivedClient) {
Initialize("http://www.foo.com/", "prerender/single_prerender.html");
- WebPrerender web_prerender = PrerendererClient()->ReleaseWebPrerender();
- EXPECT_FALSE(web_prerender.IsNull());
+ std::unique_ptr<MockPrerender> prerender =
+ PrerenderProcessor()->ReleasePrerender();
+ EXPECT_TRUE(prerender);
- EXPECT_EQ(1u, PrerenderingSupport()->AddCount(web_prerender));
- EXPECT_EQ(1u, PrerenderingSupport()->TotalCount());
+ EXPECT_EQ(1u, PrerenderProcessor()->AddCount());
+ EXPECT_EQ(0u, prerender->CancelCount());
+ EXPECT_EQ(0u, prerender->AbandonCount());
NavigateAway();
Close();
// This test passes if this next line doesn't crash.
- web_prerender.DidStartPrerender();
+ prerender->NotifyDidStartPrerender();
}
TEST_F(PrerenderingTest, FastRemoveElement) {
Initialize("http://www.foo.com/", "prerender/single_prerender.html");
- WebPrerender web_prerender = PrerendererClient()->ReleaseWebPrerender();
- EXPECT_FALSE(web_prerender.IsNull());
+ std::unique_ptr<MockPrerender> prerender =
+ PrerenderProcessor()->ReleasePrerender();
+ EXPECT_TRUE(prerender);
- EXPECT_EQ(1u, PrerenderingSupport()->AddCount(web_prerender));
- EXPECT_EQ(1u, PrerenderingSupport()->TotalCount());
+ EXPECT_EQ(1u, PrerenderProcessor()->AddCount());
+ EXPECT_EQ(0u, prerender->CancelCount());
+ EXPECT_EQ(0u, prerender->AbandonCount());
// Race removing & starting the prerender against each other, as if the
// element was removed very quickly.
ExecuteScript("removePrerender()");
- EXPECT_FALSE(web_prerender.IsNull());
- web_prerender.DidStartPrerender();
+ prerender->NotifyDidStartPrerender();
// The page should be totally disconnected from the Prerender at this point,
// so the console should not have updated.
@@ -426,41 +457,48 @@ TEST_F(PrerenderingTest, FastRemoveElement) {
TEST_F(PrerenderingTest, MutateTarget) {
Initialize("http://www.foo.com/", "prerender/single_prerender.html");
- WebPrerender web_prerender = PrerendererClient()->ReleaseWebPrerender();
- EXPECT_FALSE(web_prerender.IsNull());
- EXPECT_EQ(ToWebURL("http://prerender.com/"), web_prerender.Url());
+ std::unique_ptr<MockPrerender> prerender =
+ PrerenderProcessor()->ReleasePrerender();
+ EXPECT_TRUE(prerender);
+ EXPECT_EQ(KURL("http://prerender.com/"), prerender->Url());
- EXPECT_EQ(1u, PrerenderingSupport()->AddCount(web_prerender));
- EXPECT_EQ(0u, PrerenderingSupport()->CancelCount(web_prerender));
- EXPECT_EQ(1u, PrerenderingSupport()->TotalCount());
+ EXPECT_EQ(1u, PrerenderProcessor()->AddCount());
+ EXPECT_EQ(0u, prerender->CancelCount());
+ EXPECT_EQ(0u, prerender->AbandonCount());
// Change the href of this prerender, make sure this is treated as a remove
// and add.
ExecuteScript("mutateTarget()");
- EXPECT_EQ(1u, PrerenderingSupport()->CancelCount(web_prerender));
- WebPrerender mutated_prerender = PrerendererClient()->ReleaseWebPrerender();
- EXPECT_EQ(ToWebURL("http://mutated.com/"), mutated_prerender.Url());
- EXPECT_EQ(1u, PrerenderingSupport()->AddCount(web_prerender));
- EXPECT_EQ(1u, PrerenderingSupport()->AddCount(mutated_prerender));
- EXPECT_EQ(3u, PrerenderingSupport()->TotalCount());
+ std::unique_ptr<MockPrerender> mutated_prerender =
+ PrerenderProcessor()->ReleasePrerender();
+ EXPECT_EQ(KURL("http://mutated.com/"), mutated_prerender->Url());
+
+ EXPECT_EQ(2u, PrerenderProcessor()->AddCount());
+ EXPECT_EQ(1u, prerender->CancelCount());
+ EXPECT_EQ(0u, prerender->AbandonCount());
+ EXPECT_EQ(0u, mutated_prerender->CancelCount());
+ EXPECT_EQ(0u, mutated_prerender->AbandonCount());
}
TEST_F(PrerenderingTest, MutateRel) {
Initialize("http://www.foo.com/", "prerender/single_prerender.html");
- WebPrerender web_prerender = PrerendererClient()->ReleaseWebPrerender();
- EXPECT_FALSE(web_prerender.IsNull());
- EXPECT_EQ(ToWebURL("http://prerender.com/"), web_prerender.Url());
+ std::unique_ptr<MockPrerender> prerender =
+ PrerenderProcessor()->ReleasePrerender();
+ EXPECT_TRUE(prerender);
+ EXPECT_EQ(KURL("http://prerender.com/"), prerender->Url());
- EXPECT_EQ(1u, PrerenderingSupport()->AddCount(web_prerender));
- EXPECT_EQ(0u, PrerenderingSupport()->CancelCount(web_prerender));
- EXPECT_EQ(1u, PrerenderingSupport()->TotalCount());
+ EXPECT_EQ(1u, PrerenderProcessor()->AddCount());
+ EXPECT_EQ(0u, prerender->CancelCount());
+ EXPECT_EQ(0u, prerender->AbandonCount());
// Change the rel of this prerender, make sure this is treated as a remove.
ExecuteScript("mutateRel()");
- EXPECT_EQ(1u, PrerenderingSupport()->CancelCount(web_prerender));
- EXPECT_EQ(2u, PrerenderingSupport()->TotalCount());
+
+ EXPECT_EQ(1u, PrerenderProcessor()->AddCount());
+ EXPECT_EQ(1u, prerender->CancelCount());
+ EXPECT_EQ(0u, prerender->AbandonCount());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/exported/web_array_buffer.cc b/chromium/third_party/blink/renderer/core/exported/web_array_buffer.cc
index bff77059967..4a9b988ff2d 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_array_buffer.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_array_buffer.cc
@@ -54,9 +54,9 @@ void* WebArrayBuffer::Data() const {
return nullptr;
}
-unsigned WebArrayBuffer::ByteLength() const {
+size_t WebArrayBuffer::ByteLengthAsSizeT() const {
if (!IsNull())
- return private_->DeprecatedByteLengthAsUnsigned();
+ return private_->ByteLengthAsSizeT();
return 0;
}
diff --git a/chromium/third_party/blink/renderer/core/exported/web_console_message.cc b/chromium/third_party/blink/renderer/core/exported/web_console_message.cc
index 4e973424974..050b19c235f 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_console_message.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_console_message.cc
@@ -8,6 +8,7 @@
#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/inspector/console_message.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -19,10 +20,10 @@ void WebConsoleMessage::LogWebConsoleMessage(v8::Local<v8::Context> context,
return;
LocalFrame* frame = nullptr;
- if (auto* document = DynamicTo<Document>(execution_context))
+ if (auto* document = Document::DynamicFrom(execution_context))
frame = document->GetFrame();
execution_context->AddConsoleMessage(
- ConsoleMessage::CreateFromWebConsoleMessage(message, frame));
+ MakeGarbageCollected<ConsoleMessage>(message, frame));
}
} // namespace blink
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 45c81c83fb4..68112cb646e 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
@@ -179,14 +179,12 @@ class ClientMessageLoopAdapter : public MainThreadDebugger::ClientMessageLoop {
}
}
- bool QuitForPageWait() {
- if (running_for_page_wait_) {
- running_for_page_wait_ = false;
- if (!running_for_debug_break_)
- DoQuit();
- return true;
- }
- return false;
+ void RunIfWaitingForDebugger(LocalFrame* frame) override {
+ if (!running_for_page_wait_)
+ return;
+ running_for_page_wait_ = false;
+ if (!running_for_debug_break_)
+ DoQuit();
}
void DoQuit() {
@@ -198,12 +196,6 @@ class ClientMessageLoopAdapter : public MainThreadDebugger::ClientMessageLoop {
WebFrameWidgetBase::SetIgnoreInputEvents(false);
}
- void RunIfWaitingForDebugger(LocalFrame* frame) override {
- // If we've paused for Page.waitForDebugger, handle it ourselves.
- if (QuitForPageWait())
- return;
- }
-
bool running_for_debug_break_;
bool running_for_page_wait_;
std::unique_ptr<Platform::NestedMessageLoopRunner> message_loop_;
@@ -252,6 +244,10 @@ void WebDevToolsAgentImpl::AttachSession(DevToolsSession* session,
session->V8Session());
session->Append(dom_debugger_agent);
+ InspectorPerformanceAgent* performance_agent =
+ MakeGarbageCollected<InspectorPerformanceAgent>(inspected_frames);
+ session->Append(performance_agent);
+
session->Append(MakeGarbageCollected<InspectorDOMSnapshotAgent>(
inspected_frames, dom_debugger_agent));
@@ -261,9 +257,6 @@ void WebDevToolsAgentImpl::AttachSession(DevToolsSession* session,
session->Append(MakeGarbageCollected<InspectorMemoryAgent>(inspected_frames));
session->Append(
- MakeGarbageCollected<InspectorPerformanceAgent>(inspected_frames));
-
- session->Append(
MakeGarbageCollected<InspectorApplicationCacheAgent>(inspected_frames));
auto* page_agent = MakeGarbageCollected<InspectorPageAgent>(
@@ -284,7 +277,9 @@ void WebDevToolsAgentImpl::AttachSession(DevToolsSession* session,
session->Append(
MakeGarbageCollected<InspectorIOAgent>(isolate, session->V8Session()));
- session->Append(MakeGarbageCollected<InspectorAuditsAgent>(network_agent));
+ session->Append(MakeGarbageCollected<InspectorAuditsAgent>(
+ network_agent,
+ &inspected_frames->Root()->GetPage()->GetInspectorIssueStorage()));
session->Append(MakeGarbageCollected<InspectorMediaAgent>(inspected_frames));
@@ -343,7 +338,7 @@ WebDevToolsAgentImpl::WebDevToolsAgentImpl(
WebDevToolsAgentImpl::~WebDevToolsAgentImpl() {}
-void WebDevToolsAgentImpl::Trace(blink::Visitor* visitor) {
+void WebDevToolsAgentImpl::Trace(Visitor* visitor) {
visitor->Trace(agent_);
visitor->Trace(network_agents_);
visitor->Trace(page_agents_);
@@ -379,11 +374,12 @@ void WebDevToolsAgentImpl::DetachSession(DevToolsSession* session) {
Thread::Current()->RemoveTaskObserver(this);
}
-void WebDevToolsAgentImpl::InspectElement(const WebPoint& point_in_local_root) {
- WebFloatRect rect(point_in_local_root.x, point_in_local_root.y, 0, 0);
+void WebDevToolsAgentImpl::InspectElement(
+ const gfx::Point& point_in_local_root) {
+ WebFloatRect rect(point_in_local_root.x(), point_in_local_root.y(), 0, 0);
web_local_frame_impl_->FrameWidgetImpl()->Client()->ConvertWindowToViewport(
&rect);
- WebPoint point(rect.x, rect.y);
+ gfx::PointF point(rect.x, rect.y);
HitTestRequest::HitTestRequestType hit_type =
HitTestRequest::kMove | HitTestRequest::kReadOnly |
@@ -392,7 +388,7 @@ void WebDevToolsAgentImpl::InspectElement(const WebPoint& point_in_local_root) {
WebMouseEvent dummy_event(WebInputEvent::kMouseDown,
WebInputEvent::kNoModifiers,
base::TimeTicks::Now());
- dummy_event.SetPositionInWidget(point.x, point.y);
+ dummy_event.SetPositionInWidget(point);
IntPoint transformed_point = FlooredIntPoint(
TransformWebMouseEvent(web_local_frame_impl_->GetFrameView(), dummy_event)
.PositionInRootFrame());
@@ -414,9 +410,13 @@ void WebDevToolsAgentImpl::InspectElement(const WebPoint& point_in_local_root) {
}
}
-void WebDevToolsAgentImpl::DebuggerTaskStarted() {}
+void WebDevToolsAgentImpl::DebuggerTaskStarted() {
+ probe::WillStartDebuggerTask(probe_sink_);
+}
-void WebDevToolsAgentImpl::DebuggerTaskFinished() {}
+void WebDevToolsAgentImpl::DebuggerTaskFinished() {
+ probe::DidFinishDebuggerTask(probe_sink_);
+}
void WebDevToolsAgentImpl::DidCommitLoadForLocalFrame(LocalFrame* frame) {
resource_container_->DidCommitLoadForLocalFrame(frame);
@@ -436,6 +436,17 @@ void WebDevToolsAgentImpl::PageLayoutInvalidated(bool resized) {
it.value->PageLayoutInvalidated(resized);
}
+void WebDevToolsAgentImpl::DidShowNewWindow() {
+ if (!wait_for_debugger_when_shown_)
+ return;
+ wait_for_debugger_when_shown_ = false;
+ WaitForDebugger();
+}
+
+void WebDevToolsAgentImpl::WaitForDebuggerWhenShown() {
+ wait_for_debugger_when_shown_ = true;
+}
+
void WebDevToolsAgentImpl::WaitForDebugger() {
ClientMessageLoopAdapter::PauseForPageWait(web_local_frame_impl_);
}
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 864aef646e6..78f38f0b9c3 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(blink::Visitor*);
+ virtual void Trace(Visitor*);
DevToolsAgent* GetDevToolsAgent() const { return agent_.Get(); }
void WillBeDestroyed();
@@ -90,6 +90,9 @@ class CORE_EXPORT WebDevToolsAgentImpl final
bool ScreencastEnabled();
String NavigationInitiatorInfo(LocalFrame*);
String EvaluateInOverlayForTesting(const String& script);
+ void DidShowNewWindow();
+
+ void WaitForDebuggerWhenShown();
private:
friend class ClientMessageLoopAdapter;
@@ -97,7 +100,7 @@ class CORE_EXPORT WebDevToolsAgentImpl final
// DevToolsAgent::Client implementation.
void AttachSession(DevToolsSession*, bool restore) override;
void DetachSession(DevToolsSession*) override;
- void InspectElement(const WebPoint& point_in_local_root) override;
+ void InspectElement(const gfx::Point& point_in_local_root) override;
void DebuggerTaskStarted() override;
void DebuggerTaskFinished() override;
@@ -125,6 +128,7 @@ class CORE_EXPORT WebDevToolsAgentImpl final
Member<InspectorResourceContainer> resource_container_;
Member<Node> node_to_inspect_;
bool include_view_agents_;
+ bool wait_for_debugger_when_shown_ = false;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/exported/web_disallow_transition_scope.cc b/chromium/third_party/blink/renderer/core/exported/web_disallow_transition_scope.cc
new file mode 100644
index 00000000000..e94290cbdb5
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/exported/web_disallow_transition_scope.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/public/web/web_disallow_transition_scope.h"
+
+#include "third_party/blink/public/web/web_document.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/dom/document_lifecycle.h"
+
+namespace blink {
+
+WebDisallowTransitionScope::WebDisallowTransitionScope(
+ WebDocument* web_document)
+ : document_lifecycle_(Lifecycle(web_document)) {
+ document_lifecycle_.IncrementNoTransitionCount();
+}
+
+WebDisallowTransitionScope::~WebDisallowTransitionScope() {
+ document_lifecycle_.DecrementNoTransitionCount();
+}
+
+DocumentLifecycle& WebDisallowTransitionScope::Lifecycle(
+ WebDocument* web_document) const {
+ Document* document = *web_document;
+ return document->Lifecycle();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/exported/web_disallow_transition_scope_test.cc b/chromium/third_party/blink/renderer/core/exported/web_disallow_transition_scope_test.cc
new file mode 100644
index 00000000000..54d58c47794
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/exported/web_disallow_transition_scope_test.cc
@@ -0,0 +1,62 @@
+// 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/public/web/web_disallow_transition_scope.h"
+
+#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_local_frame_impl.h"
+
+namespace blink {
+
+using blink::frame_test_helpers::WebViewHelper;
+
+class WebDisallowTransitionScopeTest : public testing::Test {
+ protected:
+ Document* TopDocument() const;
+ WebDocument TopWebDocument() const;
+
+ WebViewHelper web_view_helper_;
+};
+
+Document* WebDisallowTransitionScopeTest::TopDocument() const {
+ return To<LocalFrame>(web_view_helper_.GetWebView()->GetPage()->MainFrame())
+ ->GetDocument();
+}
+
+WebDocument WebDisallowTransitionScopeTest::TopWebDocument() const {
+ return web_view_helper_.LocalMainFrame()->GetDocument();
+}
+
+#if !defined(OS_ANDROID)
+// TODO(crbug.com/1067036): the death test fails on Android.
+TEST_F(WebDisallowTransitionScopeTest, TestDisallowTransition) {
+ // Make the death test thread-safe. For more info, see:
+ // https://github.com/google/googletest/blob/master/googletest/docs/advanced.md#death-tests-and-threads
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+
+ web_view_helper_.InitializeAndLoad("about:blank");
+
+ WebDocument web_doc = TopWebDocument();
+ Document* core_doc = TopDocument();
+
+ // Legal transition.
+ core_doc->Lifecycle().AdvanceTo(DocumentLifecycle::kLayoutClean);
+
+ {
+ // Illegal transition.
+ WebDisallowTransitionScope disallow(&web_doc);
+ EXPECT_DEATH(core_doc->Lifecycle().EnsureStateAtMost(
+ DocumentLifecycle::kVisualUpdatePending),
+ "Cannot rewind document lifecycle");
+ }
+
+ // Legal transition.
+ core_doc->Lifecycle().EnsureStateAtMost(
+ DocumentLifecycle::kVisualUpdatePending);
+}
+#endif
+
+} // namespace blink
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 ac64a05c005..eeff125b12b 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_document.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_document.cc
@@ -48,17 +48,21 @@
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/editing/ephemeral_range.h"
#include "third_party/blink/renderer/core/editing/iterators/text_iterator.h"
+#include "third_party/blink/renderer/core/frame/visual_viewport.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/html/forms/html_form_element.h"
#include "third_party/blink/renderer/core/html/html_all_collection.h"
#include "third_party/blink/renderer/core/html/html_body_element.h"
#include "third_party/blink/renderer/core/html/html_collection.h"
+#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/html/html_head_element.h"
#include "third_party/blink/renderer/core/html/html_link_element.h"
+#include "third_party/blink/renderer/core/html/plugin_document.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/loader/document_loader.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/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
@@ -118,7 +122,7 @@ WebLocalFrame* WebDocument::GetFrame() const {
}
bool WebDocument::IsHTMLDocument() const {
- return ConstUnwrap<Document>()->IsHTMLDocument();
+ return IsA<HTMLDocument>(ConstUnwrap<Document>());
}
bool WebDocument::IsXHTMLDocument() const {
@@ -126,7 +130,7 @@ bool WebDocument::IsXHTMLDocument() const {
}
bool WebDocument::IsPluginDocument() const {
- return ConstUnwrap<Document>()->IsPluginDocument();
+ return IsA<PluginDocument>(ConstUnwrap<Document>());
}
WebURL WebDocument::BaseURL() const {
@@ -137,7 +141,7 @@ ukm::SourceId WebDocument::GetUkmSourceId() const {
return ConstUnwrap<Document>()->UkmSourceID();
}
-WebURL WebDocument::SiteForCookies() const {
+net::SiteForCookies WebDocument::SiteForCookies() const {
return ConstUnwrap<Document>()->SiteForCookies();
}
@@ -272,6 +276,14 @@ void WebDocument::SetShowBeforeUnloadDialog(bool show_dialog) {
doc->SetShowBeforeUnloadDialog(show_dialog);
}
+uint64_t WebDocument::GetVisualViewportScrollingElementIdForTesting() {
+ return blink::To<Document>(private_.Get())
+ ->GetPage()
+ ->GetVisualViewport()
+ .GetScrollElementId()
+ .GetStableId();
+}
+
WebDocument::WebDocument(Document* elem) : WebNode(elem) {}
DEFINE_WEB_NODE_TYPE_CASTS(WebDocument, ConstUnwrap<Node>()->IsDocumentNode())
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 c0e5af9d524..ac9c8e538ab 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
@@ -45,6 +45,7 @@
#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/loader/subresource_filter.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/mhtml/archive_resource.h"
#include "third_party/blink/renderer/platform/mhtml/mhtml_archive.h"
@@ -121,8 +122,12 @@ void WebDocumentLoaderImpl::SetExtraData(
WebDocumentLoaderImpl::WebDocumentLoaderImpl(
LocalFrame* frame,
WebNavigationType navigation_type,
+ ContentSecurityPolicy* content_security_policy,
std::unique_ptr<WebNavigationParams> navigation_params)
- : DocumentLoader(frame, navigation_type, std::move(navigation_params)),
+ : DocumentLoader(frame,
+ navigation_type,
+ content_security_policy,
+ std::move(navigation_params)),
response_wrapper_(DocumentLoader::GetResponse()) {}
WebDocumentLoaderImpl::~WebDocumentLoaderImpl() {
@@ -137,15 +142,17 @@ void WebDocumentLoaderImpl::DetachFromFrame(bool flush_microtask_queue) {
void WebDocumentLoaderImpl::SetSubresourceFilter(
WebDocumentSubresourceFilter* subresource_filter) {
- DocumentLoader::SetSubresourceFilter(SubresourceFilter::Create(
- *GetFrame()->GetDocument(), base::WrapUnique(subresource_filter)));
+ DocumentLoader::SetSubresourceFilter(MakeGarbageCollected<SubresourceFilter>(
+ GetFrame()->GetDocument()->ToExecutionContext(),
+ base::WrapUnique(subresource_filter)));
}
void WebDocumentLoaderImpl::SetLoadingHintsProvider(
std::unique_ptr<blink::WebLoadingHintsProvider> loading_hints_provider) {
DocumentLoader::SetPreviewsResourceLoadingHints(
PreviewsResourceLoadingHints::CreateFromLoadingHintsProvider(
- *GetFrame()->GetDocument(), std::move(loading_hints_provider)));
+ *GetFrame()->GetDocument()->ToExecutionContext(),
+ std::move(loading_hints_provider)));
}
void WebDocumentLoaderImpl::SetServiceWorkerNetworkProvider(
@@ -191,7 +198,7 @@ bool WebDocumentLoaderImpl::IsListingFtpDirectory() const {
return DocumentLoader::IsListingFtpDirectory();
}
-void WebDocumentLoaderImpl::Trace(blink::Visitor* visitor) {
+void WebDocumentLoaderImpl::Trace(Visitor* visitor) {
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 86bc91d729c..cfef7567b18 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
@@ -44,6 +44,8 @@
namespace blink {
+class ContentSecurityPolicy;
+
// Extends blink::DocumentLoader to attach |extra_data_| to store data that can
// be set/get via the WebDocumentLoader interface.
class CORE_EXPORT WebDocumentLoaderImpl final : public DocumentLoader,
@@ -51,6 +53,7 @@ class CORE_EXPORT WebDocumentLoaderImpl final : public DocumentLoader,
public:
WebDocumentLoaderImpl(LocalFrame*,
WebNavigationType navigation_type,
+ ContentSecurityPolicy*,
std::unique_ptr<WebNavigationParams> navigation_params);
static WebDocumentLoaderImpl* FromDocumentLoader(DocumentLoader* loader) {
@@ -87,7 +90,7 @@ class CORE_EXPORT WebDocumentLoaderImpl final : public DocumentLoader,
bool HadUserGesture() const override;
bool IsListingFtpDirectory() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 d9b8a5601bb..a14aabd78ea 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
@@ -69,14 +69,13 @@ class TestDocumentSubresourceFilter : public WebDocumentSubresourceFilter {
class SubresourceFilteringWebFrameClient
: public frame_test_helpers::TestWebFrameClient {
public:
- void DidStartProvisionalLoad(WebDocumentLoader* data_source) override {
- // Normally, the filter should be set when the load is committed. For
- // the sake of this test, however, inject it earlier to verify that it
- // is not consulted for the main resource load.
+ void DidCommitNavigation(const WebHistoryItem&,
+ WebHistoryCommitType,
+ bool) override {
subresource_filter_ =
new TestDocumentSubresourceFilter(load_policy_for_next_load_);
subresource_filter_->AddToBlacklist("1x1.png");
- data_source->SetSubresourceFilter(subresource_filter_);
+ Frame()->GetDocumentLoader()->SetSubresourceFilter(subresource_filter_);
}
void SetLoadPolicyFromNextLoad(
diff --git a/chromium/third_party/blink/renderer/core/exported/web_document_test.cc b/chromium/third_party/blink/renderer/core/exported/web_document_test.cc
index bdb8f080ded..1ec21b5b683 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_document_test.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_document_test.cc
@@ -128,25 +128,37 @@ TEST_F(WebDocumentTest, InsertAndRemoveStyleSheet) {
style_after_removing.VisitedDependentColor(GetCSSPropertyColor()));
}
+namespace {
+
+// This is the public key which the test below will use to enable origin
+// trial features. Trial tokens for use in tests can be created with the
+// tool in /tools/origin_trials/generate_token.py, using the private key
+// contained in /tools/origin_trials/eftest.key.
+static const uint8_t kOriginTrialPublicKey[] = {
+ 0x75, 0x10, 0xac, 0xf9, 0x3a, 0x1c, 0xb8, 0xa9, 0x28, 0x70, 0xd2,
+ 0x9a, 0xd0, 0x0b, 0x59, 0xe1, 0xac, 0x2b, 0xb7, 0xd5, 0xca, 0x1f,
+ 0x64, 0x90, 0x08, 0x8e, 0xa8, 0xe0, 0x56, 0x3a, 0x04, 0xd0,
+};
+
+} // anonymous namespace
+
// Origin Trial Policy which vends the test public key so that the token
// can be validated.
class TestOriginTrialPolicy : public blink::OriginTrialPolicy {
- bool IsOriginTrialsSupported() const override { return true; }
- base::StringPiece GetPublicKey() const override {
- // This is the public key which the test below will use to enable origin
- // trial features. Trial tokens for use in tests can be created with the
- // tool in /tools/origin_trials/generate_token.py, using the private key
- // contained in /tools/origin_trials/eftest.key.
- static const uint8_t kOriginTrialPublicKey[] = {
- 0x75, 0x10, 0xac, 0xf9, 0x3a, 0x1c, 0xb8, 0xa9, 0x28, 0x70, 0xd2,
- 0x9a, 0xd0, 0x0b, 0x59, 0xe1, 0xac, 0x2b, 0xb7, 0xd5, 0xca, 0x1f,
- 0x64, 0x90, 0x08, 0x8e, 0xa8, 0xe0, 0x56, 0x3a, 0x04, 0xd0,
- };
- return base::StringPiece(
+ public:
+ TestOriginTrialPolicy() {
+ public_keys_.push_back(base::StringPiece(
reinterpret_cast<const char*>(kOriginTrialPublicKey),
- base::size(kOriginTrialPublicKey));
+ base::size(kOriginTrialPublicKey)));
+ }
+ bool IsOriginTrialsSupported() const override { return true; }
+ std::vector<base::StringPiece> GetPublicKeys() const override {
+ return public_keys_;
}
bool IsOriginSecure(const GURL& url) const override { return true; }
+
+ private:
+ std::vector<base::StringPiece> public_keys_;
};
TEST_F(WebDocumentTest, OriginTrialDisabled) {
@@ -318,11 +330,18 @@ bool OriginsEqual(const char* path,
->IsSameOriginWith(origin.get());
}
+bool SiteForCookiesEqual(const char* path,
+ const net::SiteForCookies& site_for_cookies) {
+ KURL ref_url = ToOriginA(path);
+ ref_url.SetPort(80); // url::Origin takes exception with :0.
+ return net::SiteForCookies::FromUrl(ref_url).IsEquivalent(site_for_cookies);
+}
+
TEST_F(WebDocumentFirstPartyTest, Empty) {
Load(g_empty_file);
- ASSERT_TRUE(OriginsEqual(
- g_empty_file, SecurityOrigin::Create(TopDocument()->SiteForCookies())));
+ ASSERT_TRUE(
+ SiteForCookiesEqual(g_empty_file, TopDocument()->SiteForCookies()));
ASSERT_TRUE(OriginsEqual(g_empty_file, TopDocument()->TopFrameOrigin()));
}
@@ -332,18 +351,16 @@ TEST_F(WebDocumentFirstPartyTest, EmptySandbox) {
ASSERT_TRUE(TopDocument()->TopFrameOrigin()->IsOpaque())
<< TopDocument()->TopFrameOrigin()->ToUrlOrigin().GetDebugString();
- ASSERT_EQ(NullURL(), TopDocument()->SiteForCookies());
+ ASSERT_TRUE(TopDocument()->SiteForCookies().IsNull());
}
TEST_F(WebDocumentFirstPartyTest, NestedOriginA) {
Load(g_nested_origin_a);
ASSERT_TRUE(
- OriginsEqual(g_nested_origin_a,
- SecurityOrigin::Create(TopDocument()->SiteForCookies())));
- ASSERT_TRUE(
- OriginsEqual(g_nested_origin_a,
- SecurityOrigin::Create(NestedDocument()->SiteForCookies())));
+ SiteForCookiesEqual(g_nested_origin_a, TopDocument()->SiteForCookies()));
+ ASSERT_TRUE(SiteForCookiesEqual(g_nested_origin_a,
+ NestedDocument()->SiteForCookies()));
ASSERT_TRUE(OriginsEqual(g_nested_origin_a, TopDocument()->TopFrameOrigin()));
ASSERT_TRUE(
@@ -353,12 +370,10 @@ TEST_F(WebDocumentFirstPartyTest, NestedOriginA) {
TEST_F(WebDocumentFirstPartyTest, NestedOriginSubA) {
Load(g_nested_origin_sub_a);
- ASSERT_TRUE(
- OriginsEqual(g_nested_origin_sub_a,
- SecurityOrigin::Create(TopDocument()->SiteForCookies())));
- ASSERT_TRUE(
- OriginsEqual(g_nested_origin_sub_a,
- SecurityOrigin::Create(NestedDocument()->SiteForCookies())));
+ ASSERT_TRUE(SiteForCookiesEqual(g_nested_origin_sub_a,
+ TopDocument()->SiteForCookies()));
+ ASSERT_TRUE(SiteForCookiesEqual(g_nested_origin_sub_a,
+ NestedDocument()->SiteForCookies()));
ASSERT_TRUE(
OriginsEqual(g_nested_origin_sub_a, TopDocument()->TopFrameOrigin()));
@@ -369,12 +384,10 @@ TEST_F(WebDocumentFirstPartyTest, NestedOriginSubA) {
TEST_F(WebDocumentFirstPartyTest, NestedOriginSecureA) {
Load(g_nested_origin_secure_a);
- ASSERT_TRUE(
- OriginsEqual(g_nested_origin_secure_a,
- SecurityOrigin::Create(TopDocument()->SiteForCookies())));
- ASSERT_TRUE(
- OriginsEqual(g_nested_origin_secure_a,
- SecurityOrigin::Create(NestedDocument()->SiteForCookies())));
+ ASSERT_TRUE(SiteForCookiesEqual(g_nested_origin_secure_a,
+ TopDocument()->SiteForCookies()));
+ ASSERT_TRUE(SiteForCookiesEqual(g_nested_origin_secure_a,
+ NestedDocument()->SiteForCookies()));
ASSERT_TRUE(
OriginsEqual(g_nested_origin_secure_a, TopDocument()->TopFrameOrigin()));
@@ -385,15 +398,12 @@ TEST_F(WebDocumentFirstPartyTest, NestedOriginSecureA) {
TEST_F(WebDocumentFirstPartyTest, NestedOriginAInOriginA) {
Load(g_nested_origin_a_in_origin_a);
- ASSERT_TRUE(
- OriginsEqual(g_nested_origin_a_in_origin_a,
- SecurityOrigin::Create(TopDocument()->SiteForCookies())));
- ASSERT_TRUE(
- OriginsEqual(g_nested_origin_a_in_origin_a,
- SecurityOrigin::Create(NestedDocument()->SiteForCookies())));
- ASSERT_TRUE(OriginsEqual(
- g_nested_origin_a_in_origin_a,
- SecurityOrigin::Create(NestedNestedDocument()->SiteForCookies())));
+ ASSERT_TRUE(SiteForCookiesEqual(g_nested_origin_a_in_origin_a,
+ TopDocument()->SiteForCookies()));
+ ASSERT_TRUE(SiteForCookiesEqual(g_nested_origin_a_in_origin_a,
+ NestedDocument()->SiteForCookies()));
+ ASSERT_TRUE(SiteForCookiesEqual(g_nested_origin_a_in_origin_a,
+ NestedNestedDocument()->SiteForCookies()));
ASSERT_TRUE(OriginsEqual(g_nested_origin_a_in_origin_a,
TopDocument()->TopFrameOrigin()));
@@ -404,11 +414,10 @@ TEST_F(WebDocumentFirstPartyTest, NestedOriginAInOriginA) {
TEST_F(WebDocumentFirstPartyTest, NestedOriginAInOriginB) {
Load(g_nested_origin_a_in_origin_b);
- ASSERT_TRUE(
- OriginsEqual(g_nested_origin_a_in_origin_b,
- SecurityOrigin::Create(TopDocument()->SiteForCookies())));
- ASSERT_EQ(NullURL(), NestedDocument()->SiteForCookies());
- ASSERT_EQ(NullURL(), NestedNestedDocument()->SiteForCookies());
+ ASSERT_TRUE(SiteForCookiesEqual(g_nested_origin_a_in_origin_b,
+ TopDocument()->SiteForCookies()));
+ ASSERT_TRUE(NestedDocument()->SiteForCookies().IsNull());
+ ASSERT_TRUE(NestedNestedDocument()->SiteForCookies().IsNull());
ASSERT_TRUE(OriginsEqual(g_nested_origin_a_in_origin_b,
TopDocument()->TopFrameOrigin()));
@@ -422,9 +431,8 @@ TEST_F(WebDocumentFirstPartyTest, NestedOriginB) {
Load(g_nested_origin_b);
ASSERT_TRUE(
- OriginsEqual(g_nested_origin_b,
- SecurityOrigin::Create(TopDocument()->SiteForCookies())));
- ASSERT_EQ(NullURL(), NestedDocument()->SiteForCookies());
+ SiteForCookiesEqual(g_nested_origin_b, TopDocument()->SiteForCookies()));
+ ASSERT_TRUE(NestedDocument()->SiteForCookies().IsNull());
ASSERT_TRUE(OriginsEqual(g_nested_origin_b, TopDocument()->TopFrameOrigin()));
ASSERT_TRUE(
@@ -434,13 +442,11 @@ TEST_F(WebDocumentFirstPartyTest, NestedOriginB) {
TEST_F(WebDocumentFirstPartyTest, NestedOriginBInOriginA) {
Load(g_nested_origin_b_in_origin_a);
- ASSERT_TRUE(
- OriginsEqual(g_nested_origin_b_in_origin_a,
- SecurityOrigin::Create(TopDocument()->SiteForCookies())));
- ASSERT_TRUE(
- OriginsEqual(g_nested_origin_b_in_origin_a,
- SecurityOrigin::Create(NestedDocument()->SiteForCookies())));
- ASSERT_EQ(NullURL(), NestedNestedDocument()->SiteForCookies());
+ ASSERT_TRUE(SiteForCookiesEqual(g_nested_origin_b_in_origin_a,
+ TopDocument()->SiteForCookies()));
+ ASSERT_TRUE(SiteForCookiesEqual(g_nested_origin_b_in_origin_a,
+ NestedDocument()->SiteForCookies()));
+ ASSERT_TRUE(NestedNestedDocument()->SiteForCookies().IsNull());
ASSERT_TRUE(OriginsEqual(g_nested_origin_b_in_origin_a,
TopDocument()->TopFrameOrigin()));
@@ -453,11 +459,10 @@ TEST_F(WebDocumentFirstPartyTest, NestedOriginBInOriginA) {
TEST_F(WebDocumentFirstPartyTest, NestedOriginBInOriginB) {
Load(g_nested_origin_b_in_origin_b);
- ASSERT_TRUE(
- OriginsEqual(g_nested_origin_b_in_origin_b,
- SecurityOrigin::Create(TopDocument()->SiteForCookies())));
- ASSERT_EQ(NullURL(), NestedDocument()->SiteForCookies());
- ASSERT_EQ(NullURL(), NestedNestedDocument()->SiteForCookies());
+ ASSERT_TRUE(SiteForCookiesEqual(g_nested_origin_b_in_origin_b,
+ TopDocument()->SiteForCookies()));
+ ASSERT_TRUE(NestedDocument()->SiteForCookies().IsNull());
+ ASSERT_TRUE(NestedNestedDocument()->SiteForCookies().IsNull());
ASSERT_TRUE(OriginsEqual(g_nested_origin_b_in_origin_b,
TopDocument()->TopFrameOrigin()));
@@ -471,11 +476,9 @@ TEST_F(WebDocumentFirstPartyTest, NestedSrcdoc) {
Load(g_nested_src_doc);
ASSERT_TRUE(
- OriginsEqual(g_nested_src_doc,
- SecurityOrigin::Create(TopDocument()->SiteForCookies())));
- ASSERT_TRUE(
- OriginsEqual(g_nested_src_doc,
- SecurityOrigin::Create(NestedDocument()->SiteForCookies())));
+ SiteForCookiesEqual(g_nested_src_doc, TopDocument()->SiteForCookies()));
+ ASSERT_TRUE(SiteForCookiesEqual(g_nested_src_doc,
+ NestedDocument()->SiteForCookies()));
ASSERT_TRUE(OriginsEqual(g_nested_src_doc, TopDocument()->TopFrameOrigin()));
ASSERT_TRUE(
@@ -485,9 +488,9 @@ TEST_F(WebDocumentFirstPartyTest, NestedSrcdoc) {
TEST_F(WebDocumentFirstPartyTest, NestedData) {
Load(g_nested_data);
- ASSERT_TRUE(OriginsEqual(
- g_nested_data, SecurityOrigin::Create(TopDocument()->SiteForCookies())));
- ASSERT_EQ(NullURL(), NestedDocument()->SiteForCookies());
+ ASSERT_TRUE(
+ SiteForCookiesEqual(g_nested_data, TopDocument()->SiteForCookies()));
+ ASSERT_TRUE(NestedDocument()->SiteForCookies().IsNull());
ASSERT_TRUE(OriginsEqual(g_nested_data, TopDocument()->TopFrameOrigin()));
ASSERT_TRUE(OriginsEqual(g_nested_data, NestedDocument()->TopFrameOrigin()));
@@ -499,15 +502,12 @@ TEST_F(WebDocumentFirstPartyTest,
SchemeRegistry::RegisterURLSchemeAsFirstPartyWhenTopLevel("http");
- ASSERT_TRUE(
- OriginsEqual(g_nested_origin_a_in_origin_b,
- SecurityOrigin::Create(TopDocument()->SiteForCookies())));
- ASSERT_TRUE(
- OriginsEqual(g_nested_origin_a_in_origin_b,
- SecurityOrigin::Create(NestedDocument()->SiteForCookies())));
- ASSERT_TRUE(OriginsEqual(
- g_nested_origin_a_in_origin_b,
- SecurityOrigin::Create(NestedNestedDocument()->SiteForCookies())));
+ ASSERT_TRUE(SiteForCookiesEqual(g_nested_origin_a_in_origin_b,
+ TopDocument()->SiteForCookies()));
+ ASSERT_TRUE(SiteForCookiesEqual(g_nested_origin_a_in_origin_b,
+ NestedDocument()->SiteForCookies()));
+ ASSERT_TRUE(SiteForCookiesEqual(g_nested_origin_a_in_origin_b,
+ NestedNestedDocument()->SiteForCookies()));
ASSERT_TRUE(OriginsEqual(g_nested_origin_a_in_origin_b,
TopDocument()->TopFrameOrigin()));
@@ -521,8 +521,12 @@ TEST_F(WebDocumentFirstPartyTest, FileScheme) {
web_view_helper_.InitializeAndLoad(std::string("file:///") +
g_nested_origin_a);
- EXPECT_EQ("file:///", TopDocument()->SiteForCookies().GetString());
- EXPECT_EQ(NullURL(), NestedDocument()->SiteForCookies());
+ net::SiteForCookies top_site_for_cookies = TopDocument()->SiteForCookies();
+ EXPECT_EQ("file", top_site_for_cookies.scheme());
+ EXPECT_EQ("", top_site_for_cookies.registrable_domain());
+
+ // Nested a.com is 3rd-party to file://
+ EXPECT_TRUE(NestedDocument()->SiteForCookies().IsNull());
}
} // namespace blink
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 a90e1dfb191..2a867cd9bb1 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
@@ -50,14 +50,15 @@ WebDOMMessageEvent::WebDOMMessageEvent(
const WebFrame* source_frame,
const WebDocument& target_document,
WebVector<MessagePortChannel> channels)
- : WebDOMMessageEvent(MessageEvent::Create()) {
+ : WebDOMMessageEvent(MessageEvent::Create(), base::nullopt) {
DOMWindow* window = nullptr;
if (source_frame)
window = WebFrame::ToCoreFrame(*source_frame)->DomWindow();
MessagePortArray* ports = nullptr;
if (!target_document.IsNull()) {
Document* core_document = target_document;
- ports = MessagePort::EntanglePorts(*core_document, std::move(channels));
+ ports = MessagePort::EntanglePorts(*core_document->ToExecutionContext(),
+ std::move(channels));
}
// TODO(esprehn): Chromium always passes empty string for lastEventId, is that
// right?
@@ -70,16 +71,17 @@ WebDOMMessageEvent::WebDOMMessageEvent(TransferableMessage message,
const WebString& origin,
const WebFrame* source_frame,
const WebDocument& target_document)
- : WebDOMMessageEvent(MessageEvent::Create()) {
+ : WebDOMMessageEvent(MessageEvent::Create(),
+ message.locked_agent_cluster_id) {
DOMWindow* window = nullptr;
if (source_frame)
window = WebFrame::ToCoreFrame(*source_frame)->DomWindow();
- locked_agent_cluster_id_ = message.locked_agent_cluster_id;
BlinkTransferableMessage msg = ToBlinkTransferableMessage(std::move(message));
MessagePortArray* ports = nullptr;
if (!target_document.IsNull()) {
Document* core_document = target_document;
- ports = MessagePort::EntanglePorts(*core_document, std::move(msg.ports));
+ ports = MessagePort::EntanglePorts(*core_document->ToExecutionContext(),
+ std::move(msg.ports));
}
UserActivation* user_activation = nullptr;
@@ -94,6 +96,11 @@ WebDOMMessageEvent::WebDOMMessageEvent(TransferableMessage message,
"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 {
@@ -107,6 +114,7 @@ TransferableMessage WebDOMMessageEvent::AsMessage() {
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) {
diff --git a/chromium/third_party/blink/renderer/core/exported/web_element.cc b/chromium/third_party/blink/renderer/core/exported/web_element.cc
index 7f5533306d2..ae143342c1e 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_element.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_element.cc
@@ -44,6 +44,7 @@
#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "ui/gfx/geometry/size.h"
namespace blink {
@@ -125,7 +126,7 @@ WebString WebElement::TextContent() const {
}
WebString WebElement::InnerHTML() const {
- return ConstUnwrap<Element>()->InnerHTMLAsString();
+ return ConstUnwrap<Element>()->innerHTML();
}
bool WebElement::IsAutonomousCustomElement() const {
@@ -149,14 +150,33 @@ WebRect WebElement::BoundsInViewport() const {
}
SkBitmap WebElement::ImageContents() {
- if (IsNull())
- return {};
- Image* image = Unwrap<Element>()->ImageContents();
+ Image* image = GetImage();
if (!image)
return {};
return image->AsSkBitmapForCurrentFrame(kRespectImageOrientation);
}
+std::vector<uint8_t> WebElement::CopyOfImageData() {
+ Image* image = GetImage();
+ if (!image || !image->Data())
+ return std::vector<uint8_t>();
+ return image->Data()->CopyAs<std::vector<uint8_t>>();
+}
+
+std::string WebElement::ImageExtension() {
+ Image* image = GetImage();
+ if (!image)
+ return std::string();
+ return image->FilenameExtension().Utf8();
+}
+
+gfx::Size WebElement::GetImageSize() {
+ Image* image = GetImage();
+ if (!image)
+ return gfx::Size();
+ return gfx::Size(image->width(), image->height());
+}
+
void WebElement::RequestFullscreen() {
Element* element = Unwrap<Element>();
Fullscreen::RequestFullscreen(*element);
@@ -175,4 +195,10 @@ WebElement::operator Element*() const {
return blink::To<Element>(private_.Get());
}
+Image* WebElement::GetImage() {
+ if (IsNull())
+ return nullptr;
+ return Unwrap<Element>()->ImageContents();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/exported/web_element_test.cc b/chromium/third_party/blink/renderer/core/exported/web_element_test.cc
index 1cb2230f63c..afb7af9a7a5 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_element_test.cc
@@ -7,10 +7,10 @@
#include <memory>
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_shadow_root_init.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/dom/shadow_root.h"
-#include "third_party/blink/renderer/core/dom/shadow_root_init.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
@@ -24,7 +24,7 @@ class WebElementTest : public PageTestBase {
};
void WebElementTest::InsertHTML(String html) {
- GetDocument().documentElement()->SetInnerHTMLFromString(html);
+ GetDocument().documentElement()->setInnerHTML(html);
}
WebElement WebElementTest::TestElement() {
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
new file mode 100644
index 00000000000..c755f171654
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/exported/web_external_widget_impl.cc
@@ -0,0 +1,96 @@
+// 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/exported/web_external_widget_impl.h"
+
+#include "cc/trees/layer_tree_host.h"
+#include "third_party/blink/renderer/platform/widget/widget_base.h"
+
+namespace blink {
+
+std::unique_ptr<WebExternalWidget> WebExternalWidget::Create(
+ WebExternalWidgetClient* client,
+ const blink::WebURL& debug_url,
+ CrossVariantMojoAssociatedRemote<mojom::blink::WidgetHostInterfaceBase>
+ widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::blink::WidgetInterfaceBase>
+ widget) {
+ return std::make_unique<WebExternalWidgetImpl>(
+ client, debug_url, std::move(widget_host), std::move(widget));
+}
+
+WebExternalWidgetImpl::WebExternalWidgetImpl(
+ WebExternalWidgetClient* client,
+ const WebURL& debug_url,
+ CrossVariantMojoAssociatedRemote<mojom::blink::WidgetHostInterfaceBase>
+ widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::blink::WidgetInterfaceBase>
+ widget)
+ : client_(client),
+ debug_url_(debug_url),
+ widget_base_(std::make_unique<WidgetBase>(this,
+ std::move(widget_host),
+ std::move(widget))) {
+ DCHECK(client_);
+}
+
+WebExternalWidgetImpl::~WebExternalWidgetImpl() = default;
+
+void WebExternalWidgetImpl::SetCompositorHosts(
+ cc::LayerTreeHost* layer_tree_host,
+ cc::AnimationHost* animation_host) {
+ widget_base_->SetCompositorHosts(layer_tree_host, animation_host);
+}
+
+void WebExternalWidgetImpl::SetCompositorVisible(bool visible) {
+ widget_base_->SetCompositorVisible(visible);
+}
+
+void WebExternalWidgetImpl::UpdateVisualState() {
+ widget_base_->UpdateVisualState();
+}
+
+void WebExternalWidgetImpl::WillBeginCompositorFrame() {
+ widget_base_->WillBeginCompositorFrame();
+}
+
+WebHitTestResult WebExternalWidgetImpl::HitTestResultAt(const gfx::Point&) {
+ NOTIMPLEMENTED();
+ return {};
+}
+
+WebURL WebExternalWidgetImpl::GetURLForDebugTrace() {
+ return debug_url_;
+}
+
+WebSize WebExternalWidgetImpl::Size() {
+ return size_;
+}
+
+void WebExternalWidgetImpl::Resize(const WebSize& size) {
+ if (size_ == size)
+ return;
+ size_ = size;
+ client_->DidResize(gfx::Size(size));
+}
+
+WebInputEventResult WebExternalWidgetImpl::HandleInputEvent(
+ const WebCoalescedInputEvent& coalesced_event) {
+ return client_->HandleInputEvent(coalesced_event);
+}
+
+WebInputEventResult WebExternalWidgetImpl::DispatchBufferedTouchEvents() {
+ return client_->DispatchBufferedTouchEvents();
+}
+
+void WebExternalWidgetImpl::SetRootLayer(scoped_refptr<cc::Layer> layer) {
+ widget_base_->LayerTreeHost()->SetNonBlinkManagedRootLayer(layer);
+}
+
+void WebExternalWidgetImpl::RecordTimeToFirstActivePaint(
+ base::TimeDelta duration) {
+ client_->RecordTimeToFirstActivePaint(duration);
+}
+
+} // 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
new file mode 100644
index 00000000000..7f014b64c9c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/exported/web_external_widget_impl.h
@@ -0,0 +1,62 @@
+// 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_EXPORTED_WEB_EXTERNAL_WIDGET_IMPL_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_EXTERNAL_WIDGET_IMPL_H_
+
+#include "third_party/blink/public/web/web_external_widget.h"
+
+#include "third_party/blink/public/mojom/page/widget.mojom-blink.h"
+#include "third_party/blink/public/platform/cross_variant_mojo_util.h"
+#include "third_party/blink/public/platform/web_url.h"
+#include "third_party/blink/renderer/platform/widget/widget_base_client.h"
+
+namespace blink {
+class WidgetBase;
+
+class WebExternalWidgetImpl : public WebExternalWidget,
+ public WidgetBaseClient {
+ public:
+ WebExternalWidgetImpl(
+ WebExternalWidgetClient* client,
+ const WebURL& debug_url,
+ CrossVariantMojoAssociatedRemote<mojom::blink::WidgetHostInterfaceBase>
+ widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::blink::WidgetInterfaceBase>
+ widget);
+ ~WebExternalWidgetImpl() override;
+
+ // WebWidget overrides:
+ void SetCompositorHosts(cc::LayerTreeHost*, cc::AnimationHost*) override;
+ void SetCompositorVisible(bool visible) override;
+ void UpdateVisualState() override;
+ void WillBeginCompositorFrame() override;
+ WebHitTestResult HitTestResultAt(const gfx::Point&) override;
+ WebURL GetURLForDebugTrace() override;
+ WebSize Size() override;
+ void Resize(const WebSize& size) override;
+ WebInputEventResult HandleInputEvent(
+ const WebCoalescedInputEvent& coalesced_event) override;
+ WebInputEventResult DispatchBufferedTouchEvents() override;
+
+ // WebExternalWidget overrides:
+ void SetRootLayer(scoped_refptr<cc::Layer>) override;
+
+ // WidgetBaseClient overrides:
+ void DispatchRafAlignedInput(base::TimeTicks frame_time) override {}
+ void BeginMainFrame(base::TimeTicks last_frame_time) override {}
+ void RecordTimeToFirstActivePaint(base::TimeDelta duration) override;
+ void UpdateLifecycle(WebLifecycleUpdate requested_update,
+ DocumentUpdateReason reason) override {}
+
+ private:
+ WebExternalWidgetClient* const client_;
+ const WebURL debug_url_;
+ WebSize size_;
+ std::unique_ptr<WidgetBase> widget_base_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_EXTERNAL_WIDGET_IMPL_H_
diff --git a/chromium/third_party/blink/renderer/core/exported/web_form_control_element.cc b/chromium/third_party/blink/renderer/core/exported/web_form_control_element.cc
index a91ce32c47e..9db79042d88 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_form_control_element.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_form_control_element.cc
@@ -30,6 +30,7 @@
#include "third_party/blink/public/web/web_form_control_element.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/html/forms/html_form_control_element.h"
@@ -131,32 +132,34 @@ void WebFormControlElement::SetValue(const WebString& value, bool send_events) {
}
}
+void WebFormControlElement::DispatchFocusEvent() {
+ Unwrap<Element>()->DispatchFocusEvent(
+ nullptr, mojom::blink::FocusType::kForward, nullptr);
+}
+
+void WebFormControlElement::DispatchBlurEvent() {
+ Unwrap<Element>()->DispatchBlurEvent(
+ nullptr, mojom::blink::FocusType::kForward, nullptr);
+}
+
void WebFormControlElement::SetAutofillValue(const WebString& value) {
// The input and change events will be sent in setValue.
if (IsA<HTMLInputElement>(*private_) || IsA<HTMLTextAreaElement>(*private_)) {
- if (!Focused()) {
- Unwrap<Element>()->DispatchFocusEvent(nullptr, kWebFocusTypeForward,
- nullptr);
- }
+ if (!Focused())
+ DispatchFocusEvent();
Unwrap<Element>()->DispatchScopedEvent(
*Event::CreateBubble(event_type_names::kKeydown));
Unwrap<TextControlElement>()->SetAutofillValue(value);
Unwrap<Element>()->DispatchScopedEvent(
*Event::CreateBubble(event_type_names::kKeyup));
- if (!Focused()) {
- Unwrap<Element>()->DispatchBlurEvent(nullptr, kWebFocusTypeForward,
- nullptr);
- }
+ if (!Focused())
+ DispatchBlurEvent();
} else if (auto* select = DynamicTo<HTMLSelectElement>(*private_)) {
- if (!Focused()) {
- Unwrap<Element>()->DispatchFocusEvent(nullptr, kWebFocusTypeForward,
- nullptr);
- }
+ if (!Focused())
+ DispatchFocusEvent();
select->setValue(value, true);
- if (!Focused()) {
- Unwrap<Element>()->DispatchBlurEvent(nullptr, kWebFocusTypeForward,
- nullptr);
- }
+ if (!Focused())
+ DispatchBlurEvent();
}
}
@@ -175,8 +178,9 @@ void WebFormControlElement::SetSuggestedValue(const WebString& value) {
input->SetSuggestedValue(value);
} else if (auto* textarea = DynamicTo<HTMLTextAreaElement>(*private_)) {
textarea->SetSuggestedValue(value);
- } else if (auto* select = DynamicTo<HTMLSelectElement>(*private_))
+ } else if (auto* select = DynamicTo<HTMLSelectElement>(*private_)) {
select->SetSuggestedValue(value);
+ }
}
WebString WebFormControlElement::SuggestedValue() const {
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 41c1d5a2865..a4065dbc2eb 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
@@ -6,9 +6,9 @@
#include "third_party/blink/public/web/web_form_control_element.h"
#include "third_party/blink/public/web/web_form_element.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mutation_observer_init.h"
#include "third_party/blink/renderer/core/css/css_computed_style_declaration.h"
#include "third_party/blink/renderer/core/dom/mutation_observer.h"
-#include "third_party/blink/renderer/core/dom/mutation_observer_init.h"
#include "third_party/blink/renderer/core/dom/mutation_record.h"
#include "third_party/blink/renderer/core/dom/static_node_list.h"
#include "third_party/blink/renderer/core/html/forms/html_form_element.h"
@@ -27,7 +27,7 @@ class WebFormElementObserverImpl::ObserverCallback
void Disconnect();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<HTMLElement> element_;
@@ -62,7 +62,7 @@ WebFormElementObserverImpl::ObserverCallback::ObserverCallback(
ExecutionContext*
WebFormElementObserverImpl::ObserverCallback::GetExecutionContext() const {
- return element_ ? &element_->GetDocument() : nullptr;
+ return element_ ? element_->GetDocument().ToExecutionContext() : nullptr;
}
void WebFormElementObserverImpl::ObserverCallback::Deliver(
@@ -138,7 +138,7 @@ void WebFormElementObserverImpl::Disconnect() {
self_keep_alive_.Clear();
}
-void WebFormElementObserverImpl::Trace(blink::Visitor* visitor) {
+void WebFormElementObserverImpl::Trace(Visitor* visitor) {
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 6cca4509067..90c03eeb302 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(blink::Visitor*);
+ virtual void Trace(Visitor*);
private:
class ObserverCallback;
diff --git a/chromium/third_party/blink/renderer/core/exported/web_frame.cc b/chromium/third_party/blink/renderer/core/exported/web_frame.cc
index 6e095c46546..91353f0821a 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_frame.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_frame.cc
@@ -6,8 +6,9 @@
#include <algorithm>
#include "third_party/blink/public/common/frame/sandbox_flags.h"
+#include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
#include "third_party/blink/public/web/web_element.h"
-#include "third_party/blink/public/web/web_frame_owner_properties.h"
#include "third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h"
#include "third_party/blink/renderer/core/dom/increment_load_event_delay_count.h"
#include "third_party/blink/renderer/core/exported/web_remote_frame_impl.h"
@@ -128,7 +129,7 @@ bool WebFrame::Swap(WebFrame* frame) {
ToTraceValue(&local_frame));
}
} else {
- ToWebRemoteFrameImpl(frame)->InitializeCoreFrame(
+ To<WebRemoteFrameImpl>(frame)->InitializeCoreFrame(
*page, owner, name, &old_frame->window_agent_factory());
}
@@ -158,14 +159,7 @@ WebSecurityOrigin WebFrame::GetSecurityOrigin() const {
ToCoreFrame(*this)->GetSecurityContext()->GetSecurityOrigin());
}
-void WebFrame::SetFrameOwnerPolicy(const FramePolicy& frame_policy) {
- // At the moment, this is only used to replicate sandbox flags and container
- // policy for frames with a remote owner.
- To<RemoteFrameOwner>(ToCoreFrame(*this)->Owner())
- ->SetFramePolicy(frame_policy);
-}
-
-WebInsecureRequestPolicy WebFrame::GetInsecureRequestPolicy() const {
+mojom::blink::InsecureRequestPolicy WebFrame::GetInsecureRequestPolicy() const {
return ToCoreFrame(*this)->GetSecurityContext()->GetInsecureRequestPolicy();
}
@@ -175,32 +169,6 @@ WebVector<unsigned> WebFrame::GetInsecureRequestToUpgrade() const {
return SecurityContext::SerializeInsecureNavigationSet(set);
}
-void WebFrame::SetFrameOwnerProperties(
- const WebFrameOwnerProperties& properties) {
- // At the moment, this is only used to replicate frame owner properties
- // for frames with a remote owner.
- auto* owner = To<RemoteFrameOwner>(ToCoreFrame(*this)->Owner());
-
- Frame* frame = ToCoreFrame(*this);
- DCHECK(frame);
-
- if (auto* local_frame = DynamicTo<LocalFrame>(frame)) {
- local_frame->GetDocument()->WillChangeFrameOwnerProperties(
- properties.margin_width, properties.margin_height,
- static_cast<ScrollbarMode>(properties.scrolling_mode),
- properties.is_display_none);
- }
-
- owner->SetBrowsingContextContainerName(properties.name);
- owner->SetScrollingMode(properties.scrolling_mode);
- owner->SetMarginWidth(properties.margin_width);
- owner->SetMarginHeight(properties.margin_height);
- owner->SetAllowFullscreen(properties.allow_fullscreen);
- owner->SetAllowPaymentRequest(properties.allow_payment_request);
- owner->SetIsDisplayNone(properties.is_display_none);
- owner->SetRequiredCsp(properties.required_csp);
-}
-
WebFrame* WebFrame::Opener() const {
return opener_;
}
@@ -334,20 +302,21 @@ WebFrame::~WebFrame() {
opened_frame_tracker_.reset(nullptr);
}
-void WebFrame::TraceFrame(Visitor* visitor, WebFrame* frame) {
+void WebFrame::TraceFrame(Visitor* visitor, const WebFrame* frame) {
if (!frame)
return;
- if (auto* web_local_frame = DynamicTo<WebLocalFrameImpl>(frame))
- visitor->Trace(web_local_frame);
- else
- visitor->Trace(ToWebRemoteFrameImpl(frame));
+ if (frame->IsWebLocalFrame()) {
+ visitor->Trace(To<WebLocalFrameImpl>(frame));
+ } else {
+ visitor->Trace(To<WebRemoteFrameImpl>(frame));
+ }
}
-void WebFrame::TraceFrames(Visitor* visitor, WebFrame* frame) {
+void WebFrame::TraceFrames(Visitor* visitor, const WebFrame* frame) {
DCHECK(frame);
TraceFrame(visitor, frame->parent_);
- for (WebFrame* child = frame->FirstChild(); child;
+ for (const WebFrame* child = frame->FirstChild(); child;
child = child->NextSibling())
TraceFrame(visitor, child);
}
@@ -373,16 +342,9 @@ Frame* WebFrame::ToCoreFrame(const WebFrame& frame) {
if (auto* web_local_frame = DynamicTo<WebLocalFrameImpl>(&frame))
return web_local_frame->GetFrame();
if (frame.IsWebRemoteFrame())
- return ToWebRemoteFrameImpl(frame).GetFrame();
+ return To<WebRemoteFrameImpl>(frame).GetFrame();
NOTREACHED();
return nullptr;
}
-STATIC_ASSERT_ENUM(WebFrameOwnerProperties::ScrollingMode::kAuto,
- ScrollbarMode::kAuto);
-STATIC_ASSERT_ENUM(WebFrameOwnerProperties::ScrollingMode::kAlwaysOff,
- ScrollbarMode::kAlwaysOff);
-STATIC_ASSERT_ENUM(WebFrameOwnerProperties::ScrollingMode::kAlwaysOn,
- ScrollbarMode::kAlwaysOn);
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/exported/web_frame_content_dumper.cc b/chromium/third_party/blink/renderer/core/exported/web_frame_content_dumper.cc
index 00938e8b69f..f71a66f0a10 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_frame_content_dumper.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_frame_content_dumper.cc
@@ -6,6 +6,7 @@
#include "base/stl_util.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_view.h"
#include "third_party/blink/renderer/core/editing/ephemeral_range.h"
@@ -103,7 +104,7 @@ WebString WebFrameContentDumper::DumpWebViewAsText(WebView* web_view,
DCHECK(web_view->MainFrameWidget());
web_view->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
StringBuilder text;
FrameContentAsPlainText(max_chars, To<WebLocalFrameImpl>(frame)->GetFrame(),
diff --git a/chromium/third_party/blink/renderer/core/exported/web_frame_serializer.cc b/chromium/third_party/blink/renderer/core/exported/web_frame_serializer.cc
index a877daff812..fa35bdfc70a 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_frame_serializer.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_frame_serializer.cc
@@ -40,356 +40,23 @@
#include "third_party/blink/public/web/web_frame_serializer_client.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/dom/shadow_root.h"
-#include "third_party/blink/renderer/core/exported/web_remote_frame_impl.h"
-#include "third_party/blink/renderer/core/frame/frame.h"
#include "third_party/blink/renderer/core/frame/frame_serializer.h"
-#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
-#include "third_party/blink/renderer/core/frame/remote_frame.h"
#include "third_party/blink/renderer/core/frame/web_frame_serializer_impl.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.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_element_base.h"
-#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
-#include "third_party/blink/renderer/core/html/html_head_element.h"
-#include "third_party/blink/renderer/core/html/html_image_element.h"
-#include "third_party/blink/renderer/core/html/html_link_element.h"
-#include "third_party/blink/renderer/core/html/html_table_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/core/layout/layout_box.h"
-#include "third_party/blink/renderer/core/loader/document_loader.h"
-#include "third_party/blink/renderer/core/loader/frame_loader.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/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
-#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/mhtml/mhtml_archive.h"
-#include "third_party/blink/renderer/platform/mhtml/mhtml_parser.h"
#include "third_party/blink/renderer/platform/mhtml/serialized_resource.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/assertions.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/hash_set.h"
-#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
#include "third_party/blink/renderer/platform/wtf/text/string_concatenate.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
-namespace {
-
-const int kPopupOverlayZIndexThreshold = 50;
-const char kShadowModeAttributeName[] = "shadowmode";
-const char kShadowDelegatesFocusAttributeName[] = "shadowdelegatesfocus";
-
-// Returns a Content-ID to be used for the given frame.
-// See rfc2557 - section 8.3 - "Use of the Content-ID header and CID URLs".
-// Format note - the returned string should be of the form "<foo@bar.com>"
-// (i.e. the strings should include the angle brackets).
-String GetContentID(Frame* frame) {
- String frame_id = String(ToTraceValue(frame).data());
- return "<frame-" + frame_id + "@mhtml.blink>";
-}
-
-class MHTMLFrameSerializerDelegate final : public FrameSerializer::Delegate {
- STACK_ALLOCATED();
-
- public:
- MHTMLFrameSerializerDelegate(
- WebFrameSerializer::MHTMLPartsGenerationDelegate&,
- HeapHashSet<WeakMember<const Element>>&);
- ~MHTMLFrameSerializerDelegate() override = default;
- bool ShouldIgnoreElement(const Element&) override;
- bool ShouldIgnoreAttribute(const Element&, const Attribute&) override;
- bool RewriteLink(const Element&, String& rewritten_link) override;
- bool ShouldSkipResourceWithURL(const KURL&) override;
- Vector<Attribute> GetCustomAttributes(const Element&) override;
- std::pair<Node*, Element*> GetAuxiliaryDOMTree(const Element&) const override;
- bool ShouldCollectProblemMetric() override;
-
- private:
- bool ShouldIgnoreHiddenElement(const Element&);
- bool ShouldIgnoreMetaElement(const Element&);
- bool ShouldIgnorePopupOverlayElement(const Element&);
- void GetCustomAttributesForImageElement(const HTMLImageElement&,
- Vector<Attribute>*);
-
- WebFrameSerializer::MHTMLPartsGenerationDelegate& web_delegate_;
- HeapHashSet<WeakMember<const Element>>& shadow_template_elements_;
- bool popup_overlays_skipped_;
-
- DISALLOW_COPY_AND_ASSIGN(MHTMLFrameSerializerDelegate);
-};
-
-MHTMLFrameSerializerDelegate::MHTMLFrameSerializerDelegate(
- WebFrameSerializer::MHTMLPartsGenerationDelegate& web_delegate,
- HeapHashSet<WeakMember<const Element>>& shadow_template_elements)
- : web_delegate_(web_delegate),
- shadow_template_elements_(shadow_template_elements),
- popup_overlays_skipped_(false) {}
-
-bool MHTMLFrameSerializerDelegate::ShouldIgnoreElement(const Element& element) {
- if (ShouldIgnoreHiddenElement(element))
- return true;
- if (ShouldIgnoreMetaElement(element))
- return true;
- if (web_delegate_.RemovePopupOverlay() &&
- ShouldIgnorePopupOverlayElement(element)) {
- return true;
- }
- // Remove <link> for stylesheets that do not load.
- auto* html_link_element = DynamicTo<HTMLLinkElement>(element);
- if (html_link_element && html_link_element->RelAttribute().IsStyleSheet() &&
- !html_link_element->sheet()) {
- return true;
- }
- return false;
-}
-
-bool MHTMLFrameSerializerDelegate::ShouldIgnoreHiddenElement(
- const Element& element) {
- // If an iframe is in the head, it will be moved to the body when the page is
- // being loaded. But if an iframe is injected into the head later, it will
- // stay there and not been displayed. To prevent it from being brought to the
- // saved page and cause it being displayed, we should not include it.
- if (IsA<HTMLIFrameElement>(element) &&
- Traversal<HTMLHeadElement>::FirstAncestor(element)) {
- return true;
- }
-
- // Do not include the element that is marked with hidden attribute.
- if (element.FastHasAttribute(html_names::kHiddenAttr))
- return true;
-
- // Do not include the hidden form element.
- auto* html_element_element = DynamicTo<HTMLInputElement>(&element);
- return html_element_element &&
- html_element_element->type() == input_type_names::kHidden;
-}
-
-bool MHTMLFrameSerializerDelegate::ShouldIgnoreMetaElement(
- const Element& element) {
- // Do not include meta elements that declare Content-Security-Policy
- // directives. They should have already been enforced when the original
- // document is loaded. Since only the rendered resources are encapsulated in
- // the saved MHTML page, there is no need to carry the directives. If they
- // are still kept in the MHTML, child frames that are referred to using cid:
- // scheme could be prevented from loading.
- if (!IsA<HTMLMetaElement>(element))
- return false;
- if (!element.FastHasAttribute(html_names::kContentAttr))
- return false;
- const AtomicString& http_equiv =
- element.FastGetAttribute(html_names::kHttpEquivAttr);
- return http_equiv == "Content-Security-Policy";
-}
-
-bool MHTMLFrameSerializerDelegate::ShouldIgnorePopupOverlayElement(
- const Element& element) {
- // The element should be visible.
- LayoutBox* box = element.GetLayoutBox();
- if (!box)
- return false;
-
- // The bounding box of the element should contain center point of the
- // viewport.
- LocalDOMWindow* window = element.GetDocument().domWindow();
- DCHECK(window);
- int center_x = window->innerWidth() / 2;
- int center_y = window->innerHeight() / 2;
- if (Page* page = element.GetDocument().GetPage()) {
- center_x = page->GetChromeClient().WindowToViewportScalar(
- window->GetFrame(), center_x);
- center_y = page->GetChromeClient().WindowToViewportScalar(
- window->GetFrame(), center_y);
- }
- LayoutPoint center_point(center_x, center_y);
- if (!box->FrameRect().Contains(center_point))
- return false;
-
- // The z-index should be greater than the threshold.
- if (box->Style()->ZIndex() < kPopupOverlayZIndexThreshold)
- return false;
-
- popup_overlays_skipped_ = true;
-
- return true;
-}
-
-bool MHTMLFrameSerializerDelegate::ShouldIgnoreAttribute(
- const Element& element,
- const Attribute& attribute) {
- // TODO(fgorski): Presence of srcset attribute causes MHTML to not display
- // images, as only the value of src is pulled into the archive. Discarding
- // srcset prevents the problem. Long term we should make sure to MHTML plays
- // nicely with srcset.
- if (IsA<HTMLImageElement>(element) &&
- (attribute.LocalName() == html_names::kSrcsetAttr ||
- attribute.LocalName() == html_names::kSizesAttr)) {
- return true;
- }
-
- // Do not save ping attribute since anyway the ping will be blocked from
- // MHTML.
- if (IsA<HTMLAnchorElement>(element) &&
- attribute.LocalName() == html_names::kPingAttr) {
- return true;
- }
-
- // The special attribute in a template element to denote the shadow DOM
- // should only be generated from MHTML serialization. If it is found in the
- // original page, it should be ignored.
- if (IsA<HTMLTemplateElement>(element) &&
- (attribute.LocalName() == kShadowModeAttributeName ||
- attribute.LocalName() == kShadowDelegatesFocusAttributeName) &&
- !shadow_template_elements_.Contains(&element)) {
- return true;
- }
-
- // If srcdoc attribute for frame elements will be rewritten as src attribute
- // containing link instead of html contents, don't ignore the attribute.
- // Bail out now to avoid the check in Element::isScriptingAttribute.
- bool is_src_doc_attribute = IsHTMLFrameElementBase(element) &&
- attribute.GetName() == html_names::kSrcdocAttr;
- String new_link_for_the_element;
- if (is_src_doc_attribute && RewriteLink(element, new_link_for_the_element))
- return false;
-
- // Drop integrity attribute for those links with subresource loaded.
- auto* html_link_element = DynamicTo<HTMLLinkElement>(element);
- if (attribute.LocalName() == html_names::kIntegrityAttr &&
- html_link_element && html_link_element->sheet()) {
- return true;
- }
-
- // Do not include attributes that contain javascript. This is because the
- // script will not be executed when a MHTML page is being loaded.
- return element.IsScriptingAttribute(attribute);
-}
-
-bool MHTMLFrameSerializerDelegate::RewriteLink(const Element& element,
- String& rewritten_link) {
- auto* frame_owner = DynamicTo<HTMLFrameOwnerElement>(element);
- if (!frame_owner)
- return false;
-
- Frame* frame = frame_owner->ContentFrame();
- if (!frame)
- return false;
-
- WebString content_id = GetContentID(frame);
- KURL cid_uri = MHTMLParser::ConvertContentIDToURI(content_id);
- DCHECK(cid_uri.IsValid());
- rewritten_link = cid_uri.GetString();
- return true;
-}
-
-bool MHTMLFrameSerializerDelegate::ShouldSkipResourceWithURL(const KURL& url) {
- return web_delegate_.ShouldSkipResource(url);
-}
-
-Vector<Attribute> MHTMLFrameSerializerDelegate::GetCustomAttributes(
- const Element& element) {
- Vector<Attribute> attributes;
-
- if (auto* image = DynamicTo<HTMLImageElement>(element)) {
- GetCustomAttributesForImageElement(*image, &attributes);
- }
-
- return attributes;
-}
-
-bool MHTMLFrameSerializerDelegate::ShouldCollectProblemMetric() {
- return web_delegate_.UsePageProblemDetectors();
-}
-
-void MHTMLFrameSerializerDelegate::GetCustomAttributesForImageElement(
- const HTMLImageElement& element,
- Vector<Attribute>* attributes) {
- // Currently only the value of src is pulled into the archive and the srcset
- // attribute is ignored (see shouldIgnoreAttribute() above). If the device
- // has a higher DPR, a different image from srcset could be loaded instead.
- // When this occurs, we should provide the rendering width and height for
- // <img> element if not set.
-
- // The image should be loaded and participate the layout.
- ImageResourceContent* image = element.CachedImage();
- if (!image || !image->HasImage() || image->ErrorOccurred() ||
- !element.GetLayoutObject()) {
- return;
- }
-
- // The width and height attributes should not be set.
- if (element.FastHasAttribute(html_names::kWidthAttr) ||
- element.FastHasAttribute(html_names::kHeightAttr)) {
- return;
- }
-
- // Check if different image is loaded. naturalWidth/naturalHeight will return
- // the image size adjusted with current DPR.
- if (((int)element.naturalWidth()) == image->GetImage()->width() &&
- ((int)element.naturalHeight()) == image->GetImage()->height()) {
- return;
- }
-
- Attribute width_attribute(html_names::kWidthAttr,
- AtomicString::Number(element.LayoutBoxWidth()));
- attributes->push_back(width_attribute);
- Attribute height_attribute(html_names::kHeightAttr,
- AtomicString::Number(element.LayoutBoxHeight()));
- attributes->push_back(height_attribute);
-}
-
-std::pair<Node*, Element*> MHTMLFrameSerializerDelegate::GetAuxiliaryDOMTree(
- const Element& element) const {
- ShadowRoot* shadow_root = element.GetShadowRoot();
- if (!shadow_root)
- return std::pair<Node*, Element*>();
-
- String shadow_mode;
- switch (shadow_root->GetType()) {
- case ShadowRootType::kUserAgent:
- // No need to serialize.
- return std::pair<Node*, Element*>();
- case ShadowRootType::V0:
- shadow_mode = "v0";
- break;
- case ShadowRootType::kOpen:
- shadow_mode = "open";
- break;
- case ShadowRootType::kClosed:
- shadow_mode = "closed";
- break;
- }
-
- // Put the shadow DOM content inside a template element. A special attribute
- // is set to tell the mode of the shadow DOM.
- auto* template_element = MakeGarbageCollected<Element>(
- html_names::kTemplateTag, &(element.GetDocument()));
- template_element->setAttribute(
- QualifiedName(g_null_atom, kShadowModeAttributeName, g_null_atom),
- AtomicString(shadow_mode));
- if (shadow_root->GetType() != ShadowRootType::V0 &&
- shadow_root->delegatesFocus()) {
- template_element->setAttribute(
- QualifiedName(g_null_atom, kShadowDelegatesFocusAttributeName,
- g_null_atom),
- g_empty_atom);
- }
- shadow_template_elements_.insert(template_element);
-
- return std::pair<Node*, Element*>(shadow_root, template_element);
-}
-
-} // namespace
-
WebThreadSafeData WebFrameSerializer::GenerateMHTMLHeader(
const WebString& boundary,
WebLocalFrame* frame,
@@ -432,8 +99,8 @@ WebThreadSafeData WebFrameSerializer::GenerateMHTMLParts(
SCOPED_BLINK_UMA_HISTOGRAM_TIMER(
"PageSerialization.MhtmlGeneration.SerializationTime.SingleFrame");
HeapHashSet<WeakMember<const Element>> shadow_template_elements;
- MHTMLFrameSerializerDelegate core_delegate(*web_delegate,
- shadow_template_elements);
+ FrameSerializerDelegateImpl core_delegate(*web_delegate,
+ shadow_template_elements);
FrameSerializer serializer(resources, core_delegate);
serializer.SerializeFrame(*frame);
}
@@ -453,9 +120,9 @@ WebThreadSafeData WebFrameSerializer::GenerateMHTMLParts(
"PageSerialization.MhtmlGeneration.EncodingTime.SingleFrame");
// Frame is the 1st resource (see FrameSerializer::serializeFrame doc
// comment). Frames get a Content-ID header.
- MHTMLArchive::GenerateMHTMLPart(boundary, GetContentID(frame),
- encoding_policy, resources.TakeFirst(),
- *output->MutableData());
+ MHTMLArchive::GenerateMHTMLPart(
+ boundary, FrameSerializerDelegateImpl::GetContentID(frame),
+ encoding_policy, resources.TakeFirst(), *output->MutableData());
while (!resources.IsEmpty()) {
TRACE_EVENT0("page-serialization",
"WebFrameSerializer::generateMHTMLParts encoding");
diff --git a/chromium/third_party/blink/renderer/core/exported/web_frame_serializer_sanitization_test.cc b/chromium/third_party/blink/renderer/core/exported/web_frame_serializer_sanitization_test.cc
index 843e9afb11d..7417837c7a2 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_frame_serializer_sanitization_test.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_frame_serializer_sanitization_test.cc
@@ -89,7 +89,7 @@ class WebFrameSerializerSanitizationTest : public testing::Test {
RegisterMockedFileURLLoad(parsed_url, file_path, mime_type);
frame_test_helpers::LoadFrame(MainFrameImpl(), url.Utf8().c_str());
MainFrameImpl()->GetFrame()->View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
MainFrameImpl()->GetFrame()->GetDocument()->UpdateStyleAndLayoutTree();
test::RunPendingTasks();
}
@@ -109,10 +109,10 @@ class WebFrameSerializerSanitizationTest : public testing::Test {
&host_element->AttachShadowRootInternal(shadow_type, delegates_focus);
}
shadow_root->SetDelegatesFocus(delegates_focus);
- shadow_root->SetInnerHTMLFromString(String::FromUTF8(shadow_content),
- ASSERT_NO_EXCEPTION);
+ shadow_root->setInnerHTML(String::FromUTF8(shadow_content),
+ ASSERT_NO_EXCEPTION);
scope.GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
return shadow_root;
}
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 b0e2b6f54f2..2fdbd4b3e2a 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
@@ -30,32 +30,38 @@
#include "third_party/blink/public/web/web_frame.h"
-#include <stdarg.h>
-
+#include <initializer_list>
#include <limits>
#include <memory>
+#include "base/bind_helpers.h"
#include "base/stl_util.h"
#include "build/build_config.h"
#include "cc/input/overscroll_behavior.h"
#include "cc/layers/picture_layer.h"
#include "cc/trees/layer_tree_host.h"
-#include "cc/trees/scroll_and_scale_set.h"
-#include "mojo/public/cpp/bindings/binding.h"
+#include "cc/trees/scroll_node.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/self_owned_receiver.h"
+#include "mojo/public/cpp/system/data_pipe_drainer.h"
+#include "mojo/public/cpp/system/data_pipe_utils.h"
#include "skia/public/mojom/skcolor.mojom-blink.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/public/common/context_menu_data/edit_flags.h"
#include "third_party/blink/public/common/frame/frame_owner_element_type.h"
+#include "third_party/blink/public/common/input/web_keyboard_event.h"
#include "third_party/blink/public/common/page/launching_process_state.h"
+#include "third_party/blink/public/mojom/blob/blob.mojom-blink.h"
+#include "third_party/blink/public/mojom/blob/data_element.mojom-blink.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/public/mojom/frame/find_in_page.mojom-blink.h"
+#include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink.h"
#include "third_party/blink/public/platform/web_cache.h"
#include "third_party/blink/public/platform/web_coalesced_input_event.h"
#include "third_party/blink/public/platform/web_float_rect.h"
-#include "third_party/blink/public/platform/web_keyboard_event.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/public/platform/web_url_loader_client.h"
@@ -70,6 +76,7 @@
#include "third_party/blink/public/web/web_frame_content_dumper.h"
#include "third_party/blink/public/web/web_frame_widget.h"
#include "third_party/blink/public/web/web_history_item.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_navigation_timings.h"
#include "third_party/blink/public/web/web_print_params.h"
@@ -83,14 +90,15 @@
#include "third_party/blink/public/web/web_text_check_client.h"
#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_user_gesture_indicator.h"
#include "third_party/blink/public/web/web_view_client.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"
#include "third_party/blink/renderer/bindings/core/v8/v8_node.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_pointer_event_init.h"
#include "third_party/blink/renderer/core/clipboard/data_transfer.h"
#include "third_party/blink/renderer/core/clipboard/system_clipboard.h"
+#include "third_party/blink/renderer/core/css/css_page_rule.h"
#include "third_party/blink/renderer/core/css/media_values.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
#include "third_party/blink/renderer/core/css/resolver/viewport_style_resolver.h"
@@ -103,6 +111,7 @@
#include "third_party/blink/renderer/core/editing/finder/text_finder.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/editing/markers/document_marker_controller.h"
+#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/mouse_event.h"
@@ -148,12 +157,14 @@
#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
#include "third_party/blink/renderer/core/testing/fake_local_frame_host.h"
#include "third_party/blink/renderer/core/testing/fake_remote_frame_host.h"
+#include "third_party/blink/renderer/core/testing/mock_clipboard_host.h"
#include "third_party/blink/renderer/core/testing/null_execution_context.h"
+#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/core/testing/scoped_fake_plugin_registry.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/bindings/microtask.h"
-#include "third_party/blink/renderer/platform/cursor.h"
+#include "third_party/blink/renderer/platform/blob/testing/fake_blob.h"
#include "third_party/blink/renderer/platform/exported/wrapped_resource_request.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/keyboard_codes.h"
@@ -183,14 +194,6 @@ using testing::_;
namespace blink {
-::std::ostream& operator<<(::std::ostream& os, const WebFloatSize& size) {
- return os << "WebFloatSize: [" << size.width << ", " << size.height << "]";
-}
-
-::std::ostream& operator<<(::std::ostream& os, const WebFloatPoint& point) {
- return os << "WebFloatPoint: [" << point.x << ", " << point.y << "]";
-}
-
namespace {
template <typename Function>
@@ -203,10 +206,28 @@ void ForAllGraphicsLayers(GraphicsLayer& layer, const Function& function) {
}
}
+const cc::ScrollNode* GetScrollNode(const cc::Layer* layer) {
+ return layer->layer_tree_host()
+ ->property_trees()
+ ->scroll_tree.FindNodeFromElementId(layer->element_id());
+}
+
} // namespace
const int kTouchPointPadding = 32;
+const cc::OverscrollBehavior kOverscrollBehaviorAuto =
+ cc::OverscrollBehavior(cc::OverscrollBehavior::OverscrollBehaviorType::
+ kOverscrollBehaviorTypeAuto);
+
+const cc::OverscrollBehavior kOverscrollBehaviorContain =
+ cc::OverscrollBehavior(cc::OverscrollBehavior::OverscrollBehaviorType::
+ kOverscrollBehaviorTypeContain);
+
+const cc::OverscrollBehavior kOverscrollBehaviorNone =
+ cc::OverscrollBehavior(cc::OverscrollBehavior::OverscrollBehaviorType::
+ kOverscrollBehaviorTypeNone);
+
class WebFrameTest : public testing::Test {
protected:
WebFrameTest()
@@ -325,9 +346,9 @@ class WebFrameTest : public testing::Test {
// Both sets the inner html and runs the document lifecycle.
void InitializeWithHTML(LocalFrame& frame, const String& html_content) {
- frame.GetDocument()->body()->SetInnerHTMLFromString(html_content);
+ frame.GetDocument()->body()->setInnerHTML(html_content);
frame.GetDocument()->View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
}
WebFrame* LastChild(WebFrame* frame) { return frame->last_child_; }
@@ -379,7 +400,7 @@ class WebFrameTest : public testing::Test {
void UpdateAllLifecyclePhases(WebViewImpl* web_view) {
web_view->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
}
static void GetElementAndCaretBoundsForFocusedEditableElement(
@@ -523,21 +544,25 @@ TEST_F(WebFrameTest, RequestExecuteV8Function) {
web_view_helper.InitializeAndLoad(base_url_ + "foo.html");
auto callback = [](const v8::FunctionCallbackInfo<v8::Value>& info) {
- info.GetReturnValue().Set(V8String(info.GetIsolate(), "hello"));
+ EXPECT_EQ(2, info.Length());
+ EXPECT_TRUE(info[0]->IsUndefined());
+ info.GetReturnValue().Set(info[1]);
};
- v8::HandleScope scope(v8::Isolate::GetCurrent());
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ v8::HandleScope scope(isolate);
v8::Local<v8::Context> context =
web_view_helper.LocalMainFrame()->MainWorldScriptContext();
ScriptExecutionCallbackHelper callback_helper(context);
v8::Local<v8::Function> function =
v8::Function::New(context, callback).ToLocalChecked();
+ v8::Local<v8::Value> args[] = {v8::Undefined(isolate),
+ V8String(isolate, "hello")};
web_view_helper.GetWebView()
->MainFrame()
->ToWebLocalFrame()
- ->RequestExecuteV8Function(context, function,
- v8::Undefined(context->GetIsolate()), 0,
- nullptr, &callback_helper);
+ ->RequestExecuteV8Function(context, function, v8::Undefined(isolate),
+ base::size(args), args, &callback_helper);
RunPendingTasks();
EXPECT_TRUE(callback_helper.DidComplete());
EXPECT_EQ("hello", callback_helper.StringValue());
@@ -841,7 +866,7 @@ class WebFrameCSSCallbackTest : public testing::Test {
void ExecuteScript(const WebString& code) {
frame_->ExecuteScript(WebScriptSource(code));
frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
RunPendingTasks();
}
@@ -865,7 +890,7 @@ TEST_F(WebFrameCSSCallbackTest, AuthorStyleSheet) {
selectors.push_back(WebString::FromUTF8("div.initial_on"));
frame_->GetDocument().WatchCSSSelectors(WebVector<WebString>(selectors));
frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
RunPendingTasks();
EXPECT_EQ(1, UpdateCount());
EXPECT_THAT(MatchedSelectors(), ElementsAre("div.initial_on"));
@@ -874,7 +899,7 @@ TEST_F(WebFrameCSSCallbackTest, AuthorStyleSheet) {
selectors.push_back(WebString::FromUTF8("div.initial_off"));
Doc().WatchCSSSelectors(WebVector<WebString>(selectors));
frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
RunPendingTasks();
EXPECT_EQ(2, UpdateCount());
EXPECT_THAT(MatchedSelectors(),
@@ -883,7 +908,7 @@ TEST_F(WebFrameCSSCallbackTest, AuthorStyleSheet) {
// Check that we can turn off callbacks for certain selectors.
Doc().WatchCSSSelectors(WebVector<WebString>());
frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
RunPendingTasks();
EXPECT_EQ(3, UpdateCount());
EXPECT_THAT(MatchedSelectors(), ElementsAre());
@@ -1001,7 +1026,7 @@ TEST_F(WebFrameCSSCallbackTest, DisplayContents) {
Vector<WebString> selectors(1u, WebString::FromUTF8("span"));
Doc().WatchCSSSelectors(WebVector<WebString>(selectors));
frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
RunPendingTasks();
EXPECT_EQ(1, UpdateCount()) << "Match elements in display:contents trees.";
@@ -1037,7 +1062,7 @@ TEST_F(WebFrameCSSCallbackTest, Reparenting) {
selectors.push_back(WebString::FromUTF8("span"));
Doc().WatchCSSSelectors(WebVector<WebString>(selectors));
frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
RunPendingTasks();
EXPECT_EQ(1, UpdateCount());
@@ -1062,7 +1087,7 @@ TEST_F(WebFrameCSSCallbackTest, MultiSelector) {
selectors.push_back(WebString::FromUTF8("span,p"));
Doc().WatchCSSSelectors(WebVector<WebString>(selectors));
frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
RunPendingTasks();
EXPECT_EQ(1, UpdateCount());
@@ -1079,7 +1104,7 @@ TEST_F(WebFrameCSSCallbackTest, InvalidSelector) {
selectors.push_back(WebString::FromUTF8("p span")); // Not compound.
Doc().WatchCSSSelectors(WebVector<WebString>(selectors));
frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
RunPendingTasks();
EXPECT_EQ(1, UpdateCount());
@@ -1918,7 +1943,6 @@ TEST_F(WebFrameTest, SetForceZeroLayoutHeightWorksWithWrapContentMode) {
scroll_node->ContainerRect());
EXPECT_EQ(IntSize(viewport_width, viewport_height),
scroll_node->ContentsSize());
- EXPECT_FALSE(scroll_container->CcLayer()->masks_to_bounds());
}
TEST_F(WebFrameTest, SetForceZeroLayoutHeight) {
@@ -2086,8 +2110,7 @@ TEST_F(WebFrameTest, FrameOwnerPropertiesMargin) {
LocalFrameView* frame_view = local_frame->GetFrameView();
frame_view->Resize(800, 600);
frame_view->SetNeedsLayout();
- frame_view->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ frame_view->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
// Expect scrollbars to be enabled by default.
EXPECT_NE(nullptr, frame_view->LayoutViewport()->HorizontalScrollbar());
EXPECT_NE(nullptr, frame_view->LayoutViewport()->VerticalScrollbar());
@@ -2099,8 +2122,7 @@ TEST_F(WebFrameTest, FrameOwnerPropertiesScrolling) {
WebFrameOwnerProperties properties;
// Turn off scrolling in the subframe.
- properties.scrolling_mode =
- WebFrameOwnerProperties::ScrollingMode::kAlwaysOff;
+ properties.scrollbar_mode = mojom::blink::ScrollbarMode::kAlwaysOff;
WebLocalFrameImpl* local_frame = frame_test_helpers::CreateLocalChild(
*helper.RemoteMainFrame(), "frameName", properties);
@@ -3158,19 +3180,19 @@ TEST_F(WebFrameTest, updateOverlayScrollbarLayers)
}
void SetScaleAndScrollAndLayout(WebViewImpl* web_view,
- WebPoint scroll,
+ const gfx::Point& scroll,
float scale) {
web_view->SetPageScaleFactor(scale);
- web_view->MainFrameImpl()->SetScrollOffset(WebSize(scroll.x, scroll.y));
+ web_view->MainFrameImpl()->SetScrollOffset(WebSize(scroll.x(), scroll.y()));
web_view->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
}
void SimulatePageScale(WebViewImpl* web_view_impl, float& scale) {
float scale_delta =
web_view_impl->FakePageScaleAnimationPageScaleForTesting() /
web_view_impl->PageScaleFactor();
- web_view_impl->MainFrameWidget()->ApplyViewportChanges(
+ web_view_impl->MainFrameWidget()->ApplyViewportChangesForTesting(
{gfx::ScrollOffset(), gfx::Vector2dF(), scale_delta, false, 0, 0,
cc::BrowserControlsState::kBoth});
scale = web_view_impl->PageScaleFactor();
@@ -3245,8 +3267,7 @@ TEST_F(WebFrameTest, DivAutoZoomParamsTest) {
// FIXME: Looks like we are missing EXPECTs here.
scale = web_view_helper.GetWebView()->MinimumPageScaleFactor();
- SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), WebPoint(0, 0),
- scale);
+ SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), gfx::Point(), scale);
// Test double-tap zooming into tall div.
WebRect tall_block_bound = ComputeBlockBoundHelper(
@@ -3286,7 +3307,7 @@ TEST_F(WebFrameTest, DivAutoZoomWideDivTest) {
gfx::Point point(div.x + 50, div.y + 50);
float scale;
SetScaleAndScrollAndLayout(
- web_view_helper.GetWebView(), WebPoint(0, 0),
+ web_view_helper.GetWebView(), gfx::Point(),
(web_view_helper.GetWebView()->MinimumPageScaleFactor()) *
(1 + double_tap_zoom_already_legible_ratio) / 2);
@@ -3353,7 +3374,7 @@ TEST_F(WebFrameTest, DivAutoZoomMultipleDivsTest) {
gfx::Point bottom_point(bottom_div.x + 50, bottom_div.y + 50);
float scale;
SetScaleAndScrollAndLayout(
- web_view_helper.GetWebView(), WebPoint(0, 0),
+ web_view_helper.GetWebView(), gfx::Point(),
(web_view_helper.GetWebView()->MinimumPageScaleFactor()) *
(1 + double_tap_zoom_already_legible_ratio) / 2);
@@ -3369,9 +3390,11 @@ TEST_F(WebFrameTest, DivAutoZoomMultipleDivsTest) {
// back to the div.
SimulateDoubleTap(web_view_helper.GetWebView(), top_point, scale);
EXPECT_FLOAT_EQ(1, scale);
- web_view_helper.GetWebView()->MainFrameWidget()->ApplyViewportChanges(
- {gfx::ScrollOffset(), gfx::Vector2dF(), 0.6f, false, 0, 0,
- cc::BrowserControlsState::kBoth});
+ web_view_helper.GetWebView()
+ ->MainFrameWidget()
+ ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+ 0.6f, false, 0, 0,
+ cc::BrowserControlsState::kBoth});
SimulateDoubleTap(web_view_helper.GetWebView(), bottom_point, scale);
EXPECT_FLOAT_EQ(1, scale);
SimulateDoubleTap(web_view_helper.GetWebView(), bottom_point, scale);
@@ -3380,9 +3403,11 @@ TEST_F(WebFrameTest, DivAutoZoomMultipleDivsTest) {
// If we didn't yet get an auto-zoom update and a second double-tap arrives,
// should go back to minimum scale.
- web_view_helper.GetWebView()->MainFrameWidget()->ApplyViewportChanges(
- {gfx::ScrollOffset(), gfx::Vector2dF(), 1.1f, false, 0, 0,
- cc::BrowserControlsState::kBoth});
+ web_view_helper.GetWebView()
+ ->MainFrameWidget()
+ ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+ 1.1f, false, 0, 0,
+ cc::BrowserControlsState::kBoth});
WebRect block_bounds =
ComputeBlockBoundHelper(web_view_helper.GetWebView(), top_point, false);
@@ -3424,7 +3449,7 @@ TEST_F(WebFrameTest, DivAutoZoomScaleBoundsTest) {
web_view_helper.GetWebView()->MinimumPageScaleFactor() *
double_tap_zoom_already_legible_ratio;
SetScaleAndScrollAndLayout(
- web_view_helper.GetWebView(), WebPoint(0, 0),
+ web_view_helper.GetWebView(), gfx::Point(),
(web_view_helper.GetWebView()->MinimumPageScaleFactor()) *
(1 + double_tap_zoom_already_legible_ratio) / 2);
SimulateDoubleTap(web_view_helper.GetWebView(), double_tap_point, scale);
@@ -3436,9 +3461,11 @@ TEST_F(WebFrameTest, DivAutoZoomScaleBoundsTest) {
EXPECT_FLOAT_EQ(1, scale);
// Zoom in to reset double_tap_zoom_in_effect flag.
- web_view_helper.GetWebView()->MainFrameWidget()->ApplyViewportChanges(
- {gfx::ScrollOffset(), gfx::Vector2dF(), 1.1f, false, 0, 0,
- cc::BrowserControlsState::kBoth});
+ web_view_helper.GetWebView()
+ ->MainFrameWidget()
+ ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+ 1.1f, false, 0, 0,
+ cc::BrowserControlsState::kBoth});
// 1 < minimumPageScale < doubleTapZoomAlreadyLegibleScale
web_view_helper.GetWebView()->SetDefaultPageScaleLimits(1.1f, 4);
UpdateAllLifecyclePhases(web_view_helper.GetWebView());
@@ -3446,7 +3473,7 @@ TEST_F(WebFrameTest, DivAutoZoomScaleBoundsTest) {
web_view_helper.GetWebView()->MinimumPageScaleFactor() *
double_tap_zoom_already_legible_ratio;
SetScaleAndScrollAndLayout(
- web_view_helper.GetWebView(), WebPoint(0, 0),
+ web_view_helper.GetWebView(), gfx::Point(),
(web_view_helper.GetWebView()->MinimumPageScaleFactor()) *
(1 + double_tap_zoom_already_legible_ratio) / 2);
SimulateDoubleTap(web_view_helper.GetWebView(), double_tap_point, scale);
@@ -3458,9 +3485,11 @@ TEST_F(WebFrameTest, DivAutoZoomScaleBoundsTest) {
EXPECT_FLOAT_EQ(double_tap_zoom_already_legible_scale, scale);
// Zoom in to reset double_tap_zoom_in_effect flag.
- web_view_helper.GetWebView()->MainFrameWidget()->ApplyViewportChanges(
- {gfx::ScrollOffset(), gfx::Vector2dF(), 1.1f, false, 0, 0,
- cc::BrowserControlsState::kBoth});
+ web_view_helper.GetWebView()
+ ->MainFrameWidget()
+ ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+ 1.1f, false, 0, 0,
+ cc::BrowserControlsState::kBoth});
// minimumPageScale < 1 < doubleTapZoomAlreadyLegibleScale
web_view_helper.GetWebView()->SetDefaultPageScaleLimits(0.95f, 4);
UpdateAllLifecyclePhases(web_view_helper.GetWebView());
@@ -3468,7 +3497,7 @@ TEST_F(WebFrameTest, DivAutoZoomScaleBoundsTest) {
web_view_helper.GetWebView()->MinimumPageScaleFactor() *
double_tap_zoom_already_legible_ratio;
SetScaleAndScrollAndLayout(
- web_view_helper.GetWebView(), WebPoint(0, 0),
+ web_view_helper.GetWebView(), gfx::Point(),
(web_view_helper.GetWebView()->MinimumPageScaleFactor()) *
(1 + double_tap_zoom_already_legible_ratio) / 2);
SimulateDoubleTap(web_view_helper.GetWebView(), double_tap_point, scale);
@@ -3511,7 +3540,7 @@ TEST_F(WebFrameTest, DivAutoZoomScaleLegibleScaleTest) {
// maximumLegibleScaleFactor
float legible_scale = maximum_legible_scale_factor;
SetScaleAndScrollAndLayout(
- web_view_helper.GetWebView(), WebPoint(0, 0),
+ web_view_helper.GetWebView(), gfx::Point(),
(web_view_helper.GetWebView()->MinimumPageScaleFactor()) *
(1 + double_tap_zoom_already_legible_ratio) / 2);
float double_tap_zoom_already_legible_scale =
@@ -3528,9 +3557,11 @@ TEST_F(WebFrameTest, DivAutoZoomScaleLegibleScaleTest) {
EXPECT_FLOAT_EQ(legible_scale, scale);
// Zoom in to reset double_tap_zoom_in_effect flag.
- web_view_helper.GetWebView()->MainFrameWidget()->ApplyViewportChanges(
- {gfx::ScrollOffset(), gfx::Vector2dF(), 1.1f, false, 0, 0,
- cc::BrowserControlsState::kBoth});
+ web_view_helper.GetWebView()
+ ->MainFrameWidget()
+ ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+ 1.1f, false, 0, 0,
+ cc::BrowserControlsState::kBoth});
// 1 < maximumLegibleScaleFactor < minimumPageScale <
// doubleTapZoomAlreadyLegibleScale
web_view_helper.GetWebView()->SetDefaultPageScaleLimits(1.0f, 4);
@@ -3539,7 +3570,7 @@ TEST_F(WebFrameTest, DivAutoZoomScaleLegibleScaleTest) {
web_view_helper.GetWebView()->MinimumPageScaleFactor() *
double_tap_zoom_already_legible_ratio;
SetScaleAndScrollAndLayout(
- web_view_helper.GetWebView(), WebPoint(0, 0),
+ web_view_helper.GetWebView(), gfx::Point(),
(web_view_helper.GetWebView()->MinimumPageScaleFactor()) *
(1 + double_tap_zoom_already_legible_ratio) / 2);
SimulateDoubleTap(web_view_helper.GetWebView(), double_tap_point, scale);
@@ -3551,9 +3582,11 @@ TEST_F(WebFrameTest, DivAutoZoomScaleLegibleScaleTest) {
EXPECT_FLOAT_EQ(double_tap_zoom_already_legible_scale, scale);
// Zoom in to reset double_tap_zoom_in_effect flag.
- web_view_helper.GetWebView()->MainFrameWidget()->ApplyViewportChanges(
- {gfx::ScrollOffset(), gfx::Vector2dF(), 1.1f, false, 0, 0,
- cc::BrowserControlsState::kBoth});
+ web_view_helper.GetWebView()
+ ->MainFrameWidget()
+ ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+ 1.1f, false, 0, 0,
+ cc::BrowserControlsState::kBoth});
// minimumPageScale < 1 < maximumLegibleScaleFactor <
// doubleTapZoomAlreadyLegibleScale
web_view_helper.GetWebView()->SetDefaultPageScaleLimits(0.95f, 4);
@@ -3562,7 +3595,7 @@ TEST_F(WebFrameTest, DivAutoZoomScaleLegibleScaleTest) {
web_view_helper.GetWebView()->MinimumPageScaleFactor() *
double_tap_zoom_already_legible_ratio;
SetScaleAndScrollAndLayout(
- web_view_helper.GetWebView(), WebPoint(0, 0),
+ web_view_helper.GetWebView(), gfx::Point(),
(web_view_helper.GetWebView()->MinimumPageScaleFactor()) *
(1 + double_tap_zoom_already_legible_ratio) / 2);
SimulateDoubleTap(web_view_helper.GetWebView(), double_tap_point, scale);
@@ -3574,9 +3607,11 @@ TEST_F(WebFrameTest, DivAutoZoomScaleLegibleScaleTest) {
EXPECT_FLOAT_EQ(double_tap_zoom_already_legible_scale, scale);
// Zoom in to reset double_tap_zoom_in_effect flag.
- web_view_helper.GetWebView()->MainFrameWidget()->ApplyViewportChanges(
- {gfx::ScrollOffset(), gfx::Vector2dF(), 1.1f, false, 0, 0,
- cc::BrowserControlsState::kBoth});
+ web_view_helper.GetWebView()
+ ->MainFrameWidget()
+ ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+ 1.1f, false, 0, 0,
+ cc::BrowserControlsState::kBoth});
// minimumPageScale < 1 < doubleTapZoomAlreadyLegibleScale <
// maximumLegibleScaleFactor
web_view_helper.GetWebView()->SetDefaultPageScaleLimits(0.9f, 4);
@@ -3585,7 +3620,7 @@ TEST_F(WebFrameTest, DivAutoZoomScaleLegibleScaleTest) {
web_view_helper.GetWebView()->MinimumPageScaleFactor() *
double_tap_zoom_already_legible_ratio;
SetScaleAndScrollAndLayout(
- web_view_helper.GetWebView(), WebPoint(0, 0),
+ web_view_helper.GetWebView(), gfx::Point(),
(web_view_helper.GetWebView()->MinimumPageScaleFactor()) *
(1 + double_tap_zoom_already_legible_ratio) / 2);
SimulateDoubleTap(web_view_helper.GetWebView(), double_tap_point, scale);
@@ -3631,7 +3666,7 @@ TEST_F(WebFrameTest, DivAutoZoomScaleFontScaleFactorTest) {
// accessibilityFontScaleFactor
float legible_scale = accessibility_font_scale_factor;
SetScaleAndScrollAndLayout(
- web_view_helper.GetWebView(), WebPoint(0, 0),
+ web_view_helper.GetWebView(), gfx::Point(),
(web_view_helper.GetWebView()->MinimumPageScaleFactor()) *
(1 + double_tap_zoom_already_legible_ratio) / 2);
float double_tap_zoom_already_legible_scale =
@@ -3648,9 +3683,11 @@ TEST_F(WebFrameTest, DivAutoZoomScaleFontScaleFactorTest) {
EXPECT_FLOAT_EQ(legible_scale, scale);
// Zoom in to reset double_tap_zoom_in_effect flag.
- web_view_helper.GetWebView()->MainFrameWidget()->ApplyViewportChanges(
- {gfx::ScrollOffset(), gfx::Vector2dF(), 1.1f, false, 0, 0,
- cc::BrowserControlsState::kBoth});
+ web_view_helper.GetWebView()
+ ->MainFrameWidget()
+ ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+ 1.1f, false, 0, 0,
+ cc::BrowserControlsState::kBoth});
// 1 < accessibilityFontScaleFactor < minimumPageScale <
// doubleTapZoomAlreadyLegibleScale
web_view_helper.GetWebView()->SetDefaultPageScaleLimits(1.0f, 4);
@@ -3659,7 +3696,7 @@ TEST_F(WebFrameTest, DivAutoZoomScaleFontScaleFactorTest) {
web_view_helper.GetWebView()->MinimumPageScaleFactor() *
double_tap_zoom_already_legible_ratio;
SetScaleAndScrollAndLayout(
- web_view_helper.GetWebView(), WebPoint(0, 0),
+ web_view_helper.GetWebView(), gfx::Point(),
(web_view_helper.GetWebView()->MinimumPageScaleFactor()) *
(1 + double_tap_zoom_already_legible_ratio) / 2);
SimulateDoubleTap(web_view_helper.GetWebView(), double_tap_point, scale);
@@ -3671,9 +3708,11 @@ TEST_F(WebFrameTest, DivAutoZoomScaleFontScaleFactorTest) {
EXPECT_FLOAT_EQ(double_tap_zoom_already_legible_scale, scale);
// Zoom in to reset double_tap_zoom_in_effect flag.
- web_view_helper.GetWebView()->MainFrameWidget()->ApplyViewportChanges(
- {gfx::ScrollOffset(), gfx::Vector2dF(), 1.1f, false, 0, 0,
- cc::BrowserControlsState::kBoth});
+ web_view_helper.GetWebView()
+ ->MainFrameWidget()
+ ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+ 1.1f, false, 0, 0,
+ cc::BrowserControlsState::kBoth});
// minimumPageScale < 1 < accessibilityFontScaleFactor <
// doubleTapZoomAlreadyLegibleScale
web_view_helper.GetWebView()->SetDefaultPageScaleLimits(0.95f, 4);
@@ -3682,7 +3721,7 @@ TEST_F(WebFrameTest, DivAutoZoomScaleFontScaleFactorTest) {
web_view_helper.GetWebView()->MinimumPageScaleFactor() *
double_tap_zoom_already_legible_ratio;
SetScaleAndScrollAndLayout(
- web_view_helper.GetWebView(), WebPoint(0, 0),
+ web_view_helper.GetWebView(), gfx::Point(),
(web_view_helper.GetWebView()->MinimumPageScaleFactor()) *
(1 + double_tap_zoom_already_legible_ratio) / 2);
SimulateDoubleTap(web_view_helper.GetWebView(), double_tap_point, scale);
@@ -3694,9 +3733,11 @@ TEST_F(WebFrameTest, DivAutoZoomScaleFontScaleFactorTest) {
EXPECT_FLOAT_EQ(double_tap_zoom_already_legible_scale, scale);
// Zoom in to reset double_tap_zoom_in_effect flag.
- web_view_helper.GetWebView()->MainFrameWidget()->ApplyViewportChanges(
- {gfx::ScrollOffset(), gfx::Vector2dF(), 1.1f, false, 0, 0,
- cc::BrowserControlsState::kBoth});
+ web_view_helper.GetWebView()
+ ->MainFrameWidget()
+ ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+ 1.1f, false, 0, 0,
+ cc::BrowserControlsState::kBoth});
// minimumPageScale < 1 < doubleTapZoomAlreadyLegibleScale <
// accessibilityFontScaleFactor
web_view_helper.GetWebView()->SetDefaultPageScaleLimits(0.9f, 4);
@@ -3705,7 +3746,7 @@ TEST_F(WebFrameTest, DivAutoZoomScaleFontScaleFactorTest) {
web_view_helper.GetWebView()->MinimumPageScaleFactor() *
double_tap_zoom_already_legible_ratio;
SetScaleAndScrollAndLayout(
- web_view_helper.GetWebView(), WebPoint(0, 0),
+ web_view_helper.GetWebView(), gfx::Point(),
(web_view_helper.GetWebView()->MinimumPageScaleFactor()) *
(1 + double_tap_zoom_already_legible_ratio) / 2);
SimulateDoubleTap(web_view_helper.GetWebView(), double_tap_point, scale);
@@ -3791,7 +3832,7 @@ TEST_F(WebFrameTest, DontZoomInOnFocusedInTouchAction) {
web_view_helper.GetWebView()->FakePageScaleAnimationPageScaleForTesting(),
0);
- SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), WebPoint(0, 0),
+ SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), gfx::Point(),
initial_scale);
ASSERT_EQ(initial_scale, web_view_helper.GetWebView()->PageScaleFactor());
@@ -3806,7 +3847,7 @@ TEST_F(WebFrameTest, DontZoomInOnFocusedInTouchAction) {
web_view_helper.GetWebView()->FakePageScaleAnimationPageScaleForTesting(),
initial_scale);
- SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), WebPoint(0, 0),
+ SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), gfx::Point(),
initial_scale);
ASSERT_EQ(initial_scale, web_view_helper.GetWebView()->PageScaleFactor());
@@ -3857,13 +3898,13 @@ TEST_F(WebFrameTest, DivScrollIntoEditableTest) {
.GetElementById("EditBoxWithText")
.To<WebInputElement>()
.SetSelectionRange(1000, 1000);
- SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), WebPoint(0, 0), 1);
+ SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), gfx::Point(), 1);
WebRect rect, caret;
web_view_helper.GetWebView()->SelectionBounds(caret, rect);
// Set the page scale to be smaller than the minimal readable scale.
float initial_scale = min_readable_caret_height / caret.height * 0.5f;
- SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), WebPoint(0, 0),
+ SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), gfx::Point(),
initial_scale);
float scale;
@@ -3888,7 +3929,7 @@ TEST_F(WebFrameTest, DivScrollIntoEditableTest) {
viewport_width = 200;
viewport_height = 150;
web_view_helper.Resize(WebSize(viewport_width, viewport_height));
- SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), WebPoint(0, 0),
+ SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), gfx::Point(),
initial_scale);
GetElementAndCaretBoundsForFocusedEditableElement(
web_view_helper, element_bounds, caret_bounds);
@@ -3902,7 +3943,7 @@ TEST_F(WebFrameTest, DivScrollIntoEditableTest) {
EXPECT_NEAR(h_scroll, scroll.X(), 2);
EXPECT_NEAR(min_readable_caret_height / caret.height, scale, 0.1);
- SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), WebPoint(0, 0),
+ SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), gfx::Point(),
initial_scale);
// Move focus to edit box with text.
web_view_helper.GetWebView()->AdvanceFocus(false);
@@ -3965,13 +4006,13 @@ TEST_F(WebFrameTest, DivScrollIntoEditablePreservePageScaleTest) {
.GetElementById("EditBoxWithText")
.To<WebInputElement>()
.SetSelectionRange(0, 0);
- SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), WebPoint(0, 0), 1);
+ SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), gfx::Point(), 1);
WebRect rect, caret;
web_view_helper.GetWebView()->SelectionBounds(caret, rect);
// Set the page scale to be twice as large as the minimal readable scale.
float new_scale = kMinReadableCaretHeight / caret.height * 2.0;
- SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), WebPoint(0, 0),
+ SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), gfx::Point(),
new_scale);
float scale;
@@ -3997,7 +4038,7 @@ TEST_F(WebFrameTest, DivScrollIntoEditablePreservePageScaleTest) {
new_scale = 3.0;
h_scroll = 200;
SetScaleAndScrollAndLayout(web_view_helper.GetWebView(),
- WebPoint(h_scroll, 0), new_scale);
+ gfx::Point(h_scroll, 0), new_scale);
GetElementAndCaretBoundsForFocusedEditableElement(
web_view_helper, element_bounds, caret_bounds);
web_view_helper.GetWebView()->ComputeScaleAndScrollForEditableElementRects(
@@ -4048,7 +4089,7 @@ TEST_F(WebFrameTest, DivScrollIntoEditableTestZoomToLegibleScaleDisabled) {
// Set the page scale to be smaller than the minimal readable scale.
float initial_scale = 0.25f;
- SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), WebPoint(0, 0),
+ SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), gfx::Point(),
initial_scale);
float scale;
@@ -4121,7 +4162,7 @@ TEST_F(WebFrameTest, DivScrollIntoEditableTestWithDeviceScaleFactor) {
// Set the page scale to be smaller than the minimal readable scale.
float initial_scale = 0.5f;
- SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), WebPoint(0, 0),
+ SetScaleAndScrollAndLayout(web_view_helper.GetWebView(), gfx::Point(),
initial_scale);
ASSERT_EQ(web_view_helper.GetWebView()->PageScaleFactor(), initial_scale);
@@ -4155,14 +4196,14 @@ TEST_F(WebFrameTest, CharacterIndexAtPointWithPinchZoom) {
// Move the visual viewport to the start of the target div containing the
// text.
web_view_helper.GetWebView()->SetPageScaleFactor(2);
- web_view_helper.GetWebView()->SetVisualViewportOffset(WebFloatPoint(100, 50));
+ web_view_helper.GetWebView()->SetVisualViewportOffset(gfx::PointF(100, 50));
WebLocalFrame* main_frame =
web_view_helper.GetWebView()->MainFrame()->ToWebLocalFrame();
// 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.
- size_t ix = main_frame->CharacterIndexForPoint(WebPoint(100, 15));
+ size_t ix = main_frame->CharacterIndexForPoint(gfx::Point(100, 15));
EXPECT_EQ(5ul, ix);
}
@@ -4180,7 +4221,7 @@ TEST_F(WebFrameTest, FirstRectForCharacterRangeWithPinchZoom) {
WebRect old_rect;
main_frame->FirstRectForCharacterRange(0, 5, old_rect);
- WebFloatPoint visual_offset(100, 130);
+ gfx::PointF visual_offset(100, 130);
float scale = 2;
web_view_helper.GetWebView()->SetPageScaleFactor(scale);
web_view_helper.GetWebView()->SetVisualViewportOffset(visual_offset);
@@ -4188,8 +4229,8 @@ TEST_F(WebFrameTest, FirstRectForCharacterRangeWithPinchZoom) {
WebRect rect;
main_frame->FirstRectForCharacterRange(0, 5, rect);
- EXPECT_EQ((old_rect.x - visual_offset.x) * scale, rect.x);
- EXPECT_EQ((old_rect.y - visual_offset.y) * scale, rect.y);
+ EXPECT_EQ((old_rect.x - visual_offset.x()) * scale, rect.x);
+ EXPECT_EQ((old_rect.y - visual_offset.y()) * scale, rect.y);
EXPECT_EQ(old_rect.width * scale, rect.width);
EXPECT_EQ(old_rect.height * scale, rect.height);
}
@@ -4229,9 +4270,9 @@ class ClearScrollStateOnCommitWebFrameClient
~ClearScrollStateOnCommitWebFrameClient() override = default;
// frame_test_helpers::TestWebFrameClient:
- void DidCommitProvisionalLoad(const WebHistoryItem&,
- WebHistoryCommitType,
- bool) override {
+ void DidCommitNavigation(const WebHistoryItem&,
+ WebHistoryCommitType,
+ bool) override {
Frame()->View()->ResetScrollAndScaleState();
}
};
@@ -4332,7 +4373,7 @@ TEST_F(WebFrameTest, ClearFocusedNodeTest) {
"iframe_clear_focused_node_test.html");
// Clear the focused node.
- web_view_helper.GetWebView()->ClearFocusedElement();
+ web_view_helper.GetWebView()->FocusedElement()->blur();
// Now retrieve the FocusedNode and test it should be null.
EXPECT_EQ(nullptr, web_view_helper.GetWebView()->FocusedElement());
@@ -4815,7 +4856,7 @@ class TestFindInPageClient : public mojom::blink::FindInPageClient {
}
void SetActiveMatch(int request_id,
- const WebRect& active_match_rect,
+ const gfx::Rect& active_match_rect,
int active_match_ordinal,
mojom::blink::FindMatchUpdateType final_update) final {
active_index_ = active_match_ordinal;
@@ -4872,7 +4913,7 @@ TEST_F(WebFrameTest, FindInPageMatchRects) {
RunPendingTasks();
EXPECT_TRUE(find_in_page_client.FindResultsAreReady());
- WebVector<WebFloatRect> web_match_rects =
+ WebVector<gfx::RectF> web_match_rects =
main_frame->EnsureTextFinder().FindMatchRects();
ASSERT_EQ(static_cast<size_t>(kNumResults), web_match_rects.size());
int rects_version = main_frame->GetFindInPage()->FindMatchMarkersVersion();
@@ -4896,8 +4937,10 @@ TEST_F(WebFrameTest, FindInPageMatchRects) {
// Verify that the expected match rect also matches the currently active
// match. Compare the enclosing rects to prevent precision issues caused by
// CSS transforms.
- FloatRect active_match = main_frame->GetFindInPage()->ActiveFindMatchRect();
- EXPECT_EQ(EnclosingIntRect(active_match), EnclosingIntRect(result_rect));
+ gfx::RectF active_match =
+ main_frame->GetFindInPage()->ActiveFindMatchRect();
+ EXPECT_EQ(EnclosingIntRect(FloatRect(active_match)),
+ EnclosingIntRect(result_rect));
// The rects version should not have changed.
EXPECT_EQ(main_frame->GetFindInPage()->FindMatchMarkersVersion(),
@@ -5400,18 +5443,18 @@ TEST_F(WebFrameTest, FindInPageForcedRedoOfFindInPage) {
EXPECT_EQ(2, find_in_page_client.ActiveIndex());
}
-static WebPoint TopLeft(const WebRect& rect) {
- return WebPoint(rect.x, rect.y);
+static gfx::Point TopLeft(const WebRect& rect) {
+ return gfx::Point(rect.x, rect.y);
}
-static WebPoint BottomRightMinusOne(const WebRect& rect) {
+static gfx::Point BottomRightMinusOne(const WebRect& rect) {
// FIXME: If we don't subtract 1 from the x- and y-coordinates of the
// selection bounds, selectRange() will select the *next* element. That's
// strictly correct, as hit-testing checks the pixel to the lower-right of
// the input coordinate, but it's a wart on the API.
if (rect.width > 0)
- return WebPoint(rect.x + rect.width - 1, rect.y + rect.height - 1);
- return WebPoint(rect.x + rect.width, rect.y + rect.height - 1);
+ return gfx::Point(rect.x + rect.width - 1, rect.y + rect.height - 1);
+ return gfx::Point(rect.x + rect.width, rect.y + rect.height - 1);
}
static WebRect ElementBounds(WebLocalFrame* frame, const WebString& id) {
@@ -5580,7 +5623,7 @@ TEST_F(WebFrameTest, SelectRangeDivContentEditable) {
web_view_helper.GetWebView()->MainFrameWidget()->SelectionBounds(
start_web_rect, end_web_rect);
- frame->SelectRange(BottomRightMinusOne(end_web_rect), WebPoint(0, 0));
+ frame->SelectRange(BottomRightMinusOne(end_web_rect), gfx::Point());
EXPECT_EQ("16-char header. This text is initially selected.",
SelectionAsString(frame));
@@ -5599,7 +5642,7 @@ TEST_F(WebFrameTest, SelectRangeDivContentEditable) {
web_view_helper.GetWebView()->MainFrameWidget()->SelectionBounds(
start_web_rect, end_web_rect);
- frame->SelectRange(TopLeft(start_web_rect), WebPoint(640, 480));
+ frame->SelectRange(TopLeft(start_web_rect), gfx::Point(640, 480));
EXPECT_EQ("This text is initially selected. 16-char footer.",
SelectionAsString(frame));
}
@@ -5625,7 +5668,7 @@ TEST_F(WebFrameTest, DISABLED_SelectRangeSpanContentEditable) {
web_view_helper.GetWebView()->MainFrameWidget()->SelectionBounds(
start_web_rect, end_web_rect);
- frame->SelectRange(BottomRightMinusOne(end_web_rect), WebPoint(0, 0));
+ frame->SelectRange(BottomRightMinusOne(end_web_rect), gfx::Point());
EXPECT_EQ("16-char header. This text is initially selected.",
SelectionAsString(frame));
@@ -5645,7 +5688,7 @@ TEST_F(WebFrameTest, DISABLED_SelectRangeSpanContentEditable) {
EXPECT_EQ("This text is initially selected.", SelectionAsString(frame));
web_view_helper.GetWebView()->MainFrameWidget()->SelectionBounds(
start_web_rect, end_web_rect);
- frame->SelectRange(TopLeft(start_web_rect), WebPoint(640, 480));
+ frame->SelectRange(TopLeft(start_web_rect), gfx::Point(640, 480));
EXPECT_EQ("This text is initially selected. 16-char footer.",
SelectionAsString(frame));
}
@@ -5773,11 +5816,11 @@ TEST_F(WebFrameTest, MoveRangeSelectionExtent) {
web_view_helper.GetWebView()->MainFrameWidget()->SelectionBounds(
start_web_rect, end_web_rect);
- frame->MoveRangeSelectionExtent(WebPoint(640, 480));
+ frame->MoveRangeSelectionExtent(gfx::Point(640, 480));
EXPECT_EQ("This text is initially selected. 16-char footer.",
SelectionAsString(frame));
- frame->MoveRangeSelectionExtent(WebPoint(0, 0));
+ frame->MoveRangeSelectionExtent(gfx::Point());
EXPECT_EQ("16-char header. ", SelectionAsString(frame));
// Reset with swapped base and extent.
@@ -5785,10 +5828,10 @@ TEST_F(WebFrameTest, MoveRangeSelectionExtent) {
BottomRightMinusOne(start_web_rect));
EXPECT_EQ("This text is initially selected.", SelectionAsString(frame));
- frame->MoveRangeSelectionExtent(WebPoint(640, 480));
+ frame->MoveRangeSelectionExtent(gfx::Point(640, 480));
EXPECT_EQ(" 16-char footer.", SelectionAsString(frame));
- frame->MoveRangeSelectionExtent(WebPoint(0, 0));
+ frame->MoveRangeSelectionExtent(gfx::Point());
EXPECT_EQ("16-char header. This text is initially selected.",
SelectionAsString(frame));
@@ -5845,7 +5888,7 @@ TEST_F(WebFrameTest, MoveRangeSelectionExtentScollsInputField) {
.RootEditableElement()
->scrollLeft());
frame->MoveRangeSelectionExtent(
- WebPoint(end_web_rect.x + 500, end_web_rect.y));
+ gfx::Point(end_web_rect.x + 500, end_web_rect.y));
EXPECT_GE(frame->GetFrame()
->Selection()
.ComputeVisibleSelectionInDOMTree()
@@ -5924,8 +5967,7 @@ TEST_F(WebFrameTest, SmartClipDataWithPinchZoom) {
web_view_helper.Resize(WebSize(500, 500));
UpdateAllLifecyclePhases(web_view_helper.GetWebView());
web_view_helper.GetWebView()->SetPageScaleFactor(1.5);
- web_view_helper.GetWebView()->SetVisualViewportOffset(
- WebFloatPoint(167, 100));
+ web_view_helper.GetWebView()->SetVisualViewportOffset(gfx::PointF(167, 100));
WebRect crop_rect(200, 38, 228, 75);
frame->ExtractSmartClipData(crop_rect, clip_text, clip_html, clip_rect);
EXPECT_EQ(kExpectedClipText, clip_text);
@@ -6020,32 +6062,32 @@ TEST_F(WebFrameTest, SelectRangeStaysHorizontallyAlignedWhenMoved) {
frame->ExecuteScript(WebScriptSource("selectRange();"));
web_view_helper.GetWebView()->MainFrameWidget()->SelectionBounds(
initial_start_rect, initial_end_rect);
- WebPoint moved_start(TopLeft(initial_start_rect));
+ gfx::Point moved_start(TopLeft(initial_start_rect));
- moved_start.y += 40;
+ moved_start.Offset(0, 40);
frame->SelectRange(moved_start, BottomRightMinusOne(initial_end_rect));
web_view_helper.GetWebView()->MainFrameWidget()->SelectionBounds(start_rect,
end_rect);
EXPECT_EQ(start_rect, initial_start_rect);
EXPECT_EQ(end_rect, initial_end_rect);
- moved_start.y -= 80;
+ moved_start.Offset(0, -80);
frame->SelectRange(moved_start, BottomRightMinusOne(initial_end_rect));
web_view_helper.GetWebView()->MainFrameWidget()->SelectionBounds(start_rect,
end_rect);
EXPECT_EQ(start_rect, initial_start_rect);
EXPECT_EQ(end_rect, initial_end_rect);
- WebPoint moved_end(BottomRightMinusOne(initial_end_rect));
+ gfx::Point moved_end(BottomRightMinusOne(initial_end_rect));
- moved_end.y += 40;
+ moved_end.Offset(0, 40);
frame->SelectRange(TopLeft(initial_start_rect), moved_end);
web_view_helper.GetWebView()->MainFrameWidget()->SelectionBounds(start_rect,
end_rect);
EXPECT_EQ(start_rect, initial_start_rect);
EXPECT_EQ(end_rect, initial_end_rect);
- moved_end.y -= 80;
+ moved_end.Offset(0, -80);
frame->SelectRange(TopLeft(initial_start_rect), moved_end);
web_view_helper.GetWebView()->MainFrameWidget()->SelectionBounds(start_rect,
end_rect);
@@ -6070,16 +6112,16 @@ TEST_F(WebFrameTest, MoveCaretStaysHorizontallyAlignedWhenMoved) {
frame->ExecuteScript(WebScriptSource("selectCaret();"));
web_view_helper.GetWebView()->MainFrameWidget()->SelectionBounds(
initial_start_rect, initial_end_rect);
- WebPoint move_to(TopLeft(initial_start_rect));
+ gfx::Point move_to(TopLeft(initial_start_rect));
- move_to.y += 40;
+ move_to.Offset(0, 40);
frame->MoveCaretSelection(move_to);
web_view_helper.GetWebView()->MainFrameWidget()->SelectionBounds(start_rect,
end_rect);
EXPECT_EQ(start_rect, initial_start_rect);
EXPECT_EQ(end_rect, initial_end_rect);
- move_to.y -= 80;
+ move_to.Offset(0, -80);
frame->MoveCaretSelection(move_to);
web_view_helper.GetWebView()->MainFrameWidget()->SelectionBounds(start_rect,
end_rect);
@@ -6274,12 +6316,12 @@ class CompositedSelectionBoundsTest
}
}
- void RunTestWithMultipleFiles(const char* test_file, ...) {
- va_list aux_files;
- va_start(aux_files, test_file);
- while (const char* aux_file = va_arg(aux_files, const char*))
- RegisterMockedHttpURLLoad(aux_file);
- va_end(aux_files);
+ void RunTestWithMultipleFiles(
+ const char* test_file,
+ std::initializer_list<const char*> auxiliary_files) {
+ for (const char* auxiliary_file : auxiliary_files) {
+ RegisterMockedHttpURLLoad(auxiliary_file);
+ }
RunTest(test_file);
}
@@ -6328,7 +6370,7 @@ TEST_F(CompositedSelectionBoundsTest, SplitLayer) {
}
TEST_F(CompositedSelectionBoundsTest, Iframe) {
RunTestWithMultipleFiles("composited_selection_bounds_iframe.html",
- "composited_selection_bounds_basic.html", nullptr);
+ {"composited_selection_bounds_basic.html"});
}
TEST_F(CompositedSelectionBoundsTest, Editable) {
RunTest("composited_selection_bounds_editable.html");
@@ -6354,9 +6396,9 @@ class TestWillInsertBodyWebFrameClient
~TestWillInsertBodyWebFrameClient() override = default;
// frame_test_helpers::TestWebFrameClient:
- void DidCommitProvisionalLoad(const WebHistoryItem&,
- WebHistoryCommitType,
- bool) override {
+ void DidCommitNavigation(const WebHistoryItem&,
+ WebHistoryCommitType,
+ bool) override {
did_load_ = true;
}
@@ -6390,7 +6432,7 @@ TEST_F(WebFrameTest, MoveCaretSelectionTowardsWindowPointWithNoSelection) {
WebFrame* frame = web_view_helper.GetWebView()->MainFrame();
// This test passes if this doesn't crash.
- frame->ToWebLocalFrame()->MoveCaretSelection(WebPoint(0, 0));
+ frame->ToWebLocalFrame()->MoveCaretSelection(gfx::Point());
}
class TextCheckClient : public WebTextCheckClient {
@@ -6648,7 +6690,7 @@ TEST_F(WebFrameTest, SpellcheckResultErasesMarkers) {
.GetIdleSpellCheckController()
.ForceInvocationForTesting();
- document->UpdateStyleAndLayout();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_FALSE(exception_state.HadException());
auto range = EphemeralRange::RangeOfContents(*element);
@@ -6708,13 +6750,12 @@ TEST_F(WebFrameTest, SpellcheckResultsSavedInDocument) {
document->Markers().Markers()[0]->GetType());
}
-class TestAccessInitialDocumentWebFrameClient
- : public frame_test_helpers::TestWebFrameClient {
+class TestAccessInitialDocumentLocalFrameHost : public FakeLocalFrameHost {
public:
- TestAccessInitialDocumentWebFrameClient() = default;
- ~TestAccessInitialDocumentWebFrameClient() override = default;
+ TestAccessInitialDocumentLocalFrameHost() = default;
+ ~TestAccessInitialDocumentLocalFrameHost() override = default;
- // frame_test_helpers::TestWebFrameClient:
+ // FakeLocalFrameHost:
void DidAccessInitialDocument() override { ++did_access_initial_document_; }
// !!!!!!!!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!!!!!
@@ -6727,153 +6768,169 @@ class TestAccessInitialDocumentWebFrameClient
};
TEST_F(WebFrameTest, DidAccessInitialDocumentBody) {
- TestAccessInitialDocumentWebFrameClient web_frame_client;
+ TestAccessInitialDocumentLocalFrameHost frame_host;
+ frame_test_helpers::TestWebFrameClient web_frame_client;
+ frame_host.Init(web_frame_client.GetRemoteNavigationAssociatedInterfaces());
frame_test_helpers::WebViewHelper web_view_helper;
web_view_helper.Initialize(&web_frame_client);
RunPendingTasks();
- EXPECT_EQ(0, web_frame_client.did_access_initial_document_);
+ EXPECT_EQ(0, frame_host.did_access_initial_document_);
// Create another window that will try to access it.
frame_test_helpers::WebViewHelper new_web_view_helper;
WebViewImpl* new_view = new_web_view_helper.InitializeWithOpener(
web_view_helper.GetWebView()->MainFrame());
RunPendingTasks();
- EXPECT_EQ(0, web_frame_client.did_access_initial_document_);
+ EXPECT_EQ(0, frame_host.did_access_initial_document_);
// Access the initial document by modifying the body.
new_view->MainFrameImpl()->ExecuteScript(
WebScriptSource("window.opener.document.body.innerHTML += 'Modified';"));
RunPendingTasks();
- EXPECT_EQ(1, web_frame_client.did_access_initial_document_);
+ EXPECT_EQ(1, frame_host.did_access_initial_document_);
web_view_helper.Reset();
}
TEST_F(WebFrameTest, DidAccessInitialDocumentOpen) {
- TestAccessInitialDocumentWebFrameClient web_frame_client;
+ TestAccessInitialDocumentLocalFrameHost frame_host;
+ frame_test_helpers::TestWebFrameClient web_frame_client;
+ frame_host.Init(web_frame_client.GetRemoteNavigationAssociatedInterfaces());
frame_test_helpers::WebViewHelper web_view_helper;
web_view_helper.Initialize(&web_frame_client);
RunPendingTasks();
- EXPECT_EQ(0, web_frame_client.did_access_initial_document_);
+ EXPECT_EQ(0, frame_host.did_access_initial_document_);
// Create another window that will try to access it.
frame_test_helpers::WebViewHelper new_web_view_helper;
WebViewImpl* new_view = new_web_view_helper.InitializeWithOpener(
web_view_helper.GetWebView()->MainFrame());
RunPendingTasks();
- EXPECT_EQ(0, web_frame_client.did_access_initial_document_);
+ EXPECT_EQ(0, frame_host.did_access_initial_document_);
// Access the initial document by calling document.open(), which allows
// arbitrary modification of the initial document.
new_view->MainFrameImpl()->ExecuteScript(
WebScriptSource("window.opener.document.open();"));
RunPendingTasks();
- EXPECT_EQ(1, web_frame_client.did_access_initial_document_);
+ EXPECT_EQ(1, frame_host.did_access_initial_document_);
web_view_helper.Reset();
}
TEST_F(WebFrameTest, DidAccessInitialDocumentNavigator) {
- TestAccessInitialDocumentWebFrameClient web_frame_client;
+ TestAccessInitialDocumentLocalFrameHost frame_host;
+ frame_test_helpers::TestWebFrameClient web_frame_client;
+ frame_host.Init(web_frame_client.GetRemoteNavigationAssociatedInterfaces());
frame_test_helpers::WebViewHelper web_view_helper;
web_view_helper.Initialize(&web_frame_client);
RunPendingTasks();
- EXPECT_EQ(0, web_frame_client.did_access_initial_document_);
+ EXPECT_EQ(0, frame_host.did_access_initial_document_);
// Create another window that will try to access it.
frame_test_helpers::WebViewHelper new_web_view_helper;
WebViewImpl* new_view = new_web_view_helper.InitializeWithOpener(
web_view_helper.GetWebView()->MainFrame());
RunPendingTasks();
- EXPECT_EQ(0, web_frame_client.did_access_initial_document_);
+ EXPECT_EQ(0, frame_host.did_access_initial_document_);
// Access the initial document to get to the navigator object.
new_view->MainFrameImpl()->ExecuteScript(
WebScriptSource("console.log(window.opener.navigator);"));
RunPendingTasks();
- EXPECT_EQ(1, web_frame_client.did_access_initial_document_);
+ EXPECT_EQ(1, frame_host.did_access_initial_document_);
web_view_helper.Reset();
}
TEST_F(WebFrameTest, DidAccessInitialDocumentViaJavascriptUrl) {
- TestAccessInitialDocumentWebFrameClient web_frame_client;
+ TestAccessInitialDocumentLocalFrameHost frame_host;
+ frame_test_helpers::TestWebFrameClient web_frame_client;
+ frame_host.Init(web_frame_client.GetRemoteNavigationAssociatedInterfaces());
frame_test_helpers::WebViewHelper web_view_helper;
web_view_helper.Initialize(&web_frame_client);
RunPendingTasks();
- EXPECT_EQ(0, web_frame_client.did_access_initial_document_);
+ EXPECT_EQ(0, frame_host.did_access_initial_document_);
// Access the initial document from a javascript: URL.
frame_test_helpers::LoadFrame(web_view_helper.GetWebView()->MainFrameImpl(),
"javascript:document.body.appendChild(document."
"createTextNode('Modified'))");
- EXPECT_EQ(1, web_frame_client.did_access_initial_document_);
+ EXPECT_EQ(1, frame_host.did_access_initial_document_);
web_view_helper.Reset();
}
TEST_F(WebFrameTest, DidAccessInitialDocumentBodyBeforeModalDialog) {
- TestAccessInitialDocumentWebFrameClient web_frame_client;
+ TestAccessInitialDocumentLocalFrameHost frame_host;
+ frame_test_helpers::TestWebFrameClient web_frame_client;
+ frame_host.Init(web_frame_client.GetRemoteNavigationAssociatedInterfaces());
frame_test_helpers::WebViewHelper web_view_helper;
web_view_helper.Initialize(&web_frame_client);
RunPendingTasks();
- EXPECT_EQ(0, web_frame_client.did_access_initial_document_);
+ EXPECT_EQ(0, frame_host.did_access_initial_document_);
// Create another window that will try to access it.
frame_test_helpers::WebViewHelper new_web_view_helper;
WebViewImpl* new_view = new_web_view_helper.InitializeWithOpener(
web_view_helper.GetWebView()->MainFrame());
RunPendingTasks();
- EXPECT_EQ(0, web_frame_client.did_access_initial_document_);
+ EXPECT_EQ(0, frame_host.did_access_initial_document_);
// Access the initial document by modifying the body.
new_view->MainFrameImpl()->ExecuteScript(
WebScriptSource("window.opener.document.body.innerHTML += 'Modified';"));
- EXPECT_EQ(1, web_frame_client.did_access_initial_document_);
+ RunPendingTasks();
+ EXPECT_EQ(1, frame_host.did_access_initial_document_);
// Run a modal dialog, which used to run a nested run loop and require
// a special case for notifying about the access.
new_view->MainFrameImpl()->ExecuteScript(
WebScriptSource("window.opener.confirm('Modal');"));
- EXPECT_EQ(2, web_frame_client.did_access_initial_document_);
+ RunPendingTasks();
+ EXPECT_EQ(1, frame_host.did_access_initial_document_);
// Ensure that we don't notify again later.
RunPendingTasks();
- EXPECT_EQ(2, web_frame_client.did_access_initial_document_);
+ EXPECT_EQ(1, frame_host.did_access_initial_document_);
web_view_helper.Reset();
}
TEST_F(WebFrameTest, DidWriteToInitialDocumentBeforeModalDialog) {
- TestAccessInitialDocumentWebFrameClient web_frame_client;
+ TestAccessInitialDocumentLocalFrameHost frame_host;
+ frame_test_helpers::TestWebFrameClient web_frame_client;
+ frame_host.Init(web_frame_client.GetRemoteNavigationAssociatedInterfaces());
frame_test_helpers::WebViewHelper web_view_helper;
web_view_helper.Initialize(&web_frame_client);
RunPendingTasks();
- EXPECT_EQ(0, web_frame_client.did_access_initial_document_);
+ EXPECT_EQ(0, frame_host.did_access_initial_document_);
// Create another window that will try to access it.
frame_test_helpers::WebViewHelper new_web_view_helper;
WebViewImpl* new_view = new_web_view_helper.InitializeWithOpener(
web_view_helper.GetWebView()->MainFrame());
RunPendingTasks();
- EXPECT_EQ(0, web_frame_client.did_access_initial_document_);
+ EXPECT_EQ(0, frame_host.did_access_initial_document_);
// Access the initial document with document.write, which moves us past the
// initial empty document state of the state machine.
new_view->MainFrameImpl()->ExecuteScript(
WebScriptSource("window.opener.document.write('Modified'); "
"window.opener.document.close();"));
- EXPECT_EQ(1, web_frame_client.did_access_initial_document_);
+ RunPendingTasks();
+ EXPECT_EQ(1, frame_host.did_access_initial_document_);
// Run a modal dialog, which used to run a nested run loop and require
// a special case for notifying about the access.
new_view->MainFrameImpl()->ExecuteScript(
WebScriptSource("window.opener.confirm('Modal');"));
- EXPECT_EQ(1, web_frame_client.did_access_initial_document_);
+ RunPendingTasks();
+ EXPECT_EQ(1, frame_host.did_access_initial_document_);
// Ensure that we don't notify again later.
RunPendingTasks();
- EXPECT_EQ(1, web_frame_client.did_access_initial_document_);
+ EXPECT_EQ(1, frame_host.did_access_initial_document_);
web_view_helper.Reset();
}
@@ -6928,9 +6985,11 @@ TEST_F(WebFrameTest, CompositorScrollIsUserScrollLongPage) {
// Do a compositor scroll, verify that this is counted as a user scroll.
scrollable_area->DidScroll(FloatPoint(0, 1));
- web_view_helper.GetWebView()->MainFrameWidget()->ApplyViewportChanges(
- {gfx::ScrollOffset(), gfx::Vector2dF(), 1.7f, false, 0, 0,
- cc::BrowserControlsState::kBoth});
+ web_view_helper.GetWebView()
+ ->MainFrameWidget()
+ ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+ 1.7f, false, 0, 0,
+ cc::BrowserControlsState::kBoth});
EXPECT_TRUE(client.WasFrameScrolled());
EXPECT_TRUE(initial_scroll_state.was_scrolled_by_user);
@@ -6939,9 +6998,11 @@ TEST_F(WebFrameTest, CompositorScrollIsUserScrollLongPage) {
// The page scale 1.0f and scroll.
scrollable_area->DidScroll(FloatPoint(0, 2));
- web_view_helper.GetWebView()->MainFrameWidget()->ApplyViewportChanges(
- {gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, false, 0, 0,
- cc::BrowserControlsState::kBoth});
+ web_view_helper.GetWebView()
+ ->MainFrameWidget()
+ ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+ 1.0f, false, 0, 0,
+ cc::BrowserControlsState::kBoth});
EXPECT_TRUE(client.WasFrameScrolled());
EXPECT_TRUE(initial_scroll_state.was_scrolled_by_user);
client.Reset();
@@ -6949,18 +7010,22 @@ TEST_F(WebFrameTest, CompositorScrollIsUserScrollLongPage) {
// No scroll event if there is no scroll delta.
scrollable_area->DidScroll(FloatPoint(0, 2));
- web_view_helper.GetWebView()->MainFrameWidget()->ApplyViewportChanges(
- {gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, false, 0, 0,
- cc::BrowserControlsState::kBoth});
+ web_view_helper.GetWebView()
+ ->MainFrameWidget()
+ ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+ 1.0f, false, 0, 0,
+ cc::BrowserControlsState::kBoth});
EXPECT_FALSE(client.WasFrameScrolled());
EXPECT_FALSE(initial_scroll_state.was_scrolled_by_user);
client.Reset();
// Non zero page scale and scroll.
scrollable_area->DidScroll(FloatPoint(9, 15));
- web_view_helper.GetWebView()->MainFrameWidget()->ApplyViewportChanges(
- {gfx::ScrollOffset(), gfx::Vector2dF(), 0.6f, false, 0, 0,
- cc::BrowserControlsState::kBoth});
+ web_view_helper.GetWebView()
+ ->MainFrameWidget()
+ ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+ 0.6f, false, 0, 0,
+ cc::BrowserControlsState::kBoth});
EXPECT_TRUE(client.WasFrameScrolled());
EXPECT_TRUE(initial_scroll_state.was_scrolled_by_user);
client.Reset();
@@ -6999,11 +7064,12 @@ TEST_F(WebFrameTest, SiteForCookiesForRedirect) {
frame_test_helpers::WebViewHelper web_view_helper;
web_view_helper.InitializeAndLoad(base_url_ + "first_party_redirect.html");
- EXPECT_TRUE(SecurityOrigin::AreSameOrigin(web_view_helper.GetWebView()
- ->MainFrameImpl()
- ->GetDocument()
- .SiteForCookies(),
- redirect_url));
+ EXPECT_TRUE(
+ web_view_helper.GetWebView()
+ ->MainFrameImpl()
+ ->GetDocument()
+ .SiteForCookies()
+ .IsEquivalent(net::SiteForCookies::FromUrl(ToKURL(redirect))));
}
class TestNewWindowWebViewClient
@@ -7018,7 +7084,7 @@ class TestNewWindowWebViewClient
const WebWindowFeatures&,
const WebString&,
WebNavigationPolicy,
- WebSandboxFlags,
+ mojom::blink::WebSandboxFlags,
const FeaturePolicy::FeatureState&,
const SessionStorageNamespaceId&) override {
EXPECT_TRUE(false);
@@ -7445,13 +7511,15 @@ TEST_F(WebFrameTest, IPAddressSpace) {
params->navigation_timings.fetch_start = base::TimeTicks::Now();
params->is_browser_initiated = true;
params->ip_address_space = value;
- web_view_helper.LocalMainFrame()->CommitNavigation(
- std::move(params), nullptr, base::DoNothing::Once());
+ web_view_helper.LocalMainFrame()->CommitNavigation(std::move(params),
+ nullptr);
frame_test_helpers::PumpPendingRequestsForFrameToLoad(
web_view_helper.LocalMainFrame());
- ExecutionContext* context =
- web_view->MainFrameImpl()->GetFrame()->GetDocument();
+ ExecutionContext* context = web_view->MainFrameImpl()
+ ->GetFrame()
+ ->GetDocument()
+ ->ToExecutionContext();
EXPECT_EQ(value, context->GetSecurityContext().AddressSpace());
}
}
@@ -7495,56 +7563,14 @@ TEST_F(WebFrameTest, SameDocumentHistoryNavigationCommitType) {
EXPECT_EQ(kWebBackForwardCommit, client.LastCommitType());
}
-class TestHistoryChildWebFrameClient
- : public frame_test_helpers::TestWebFrameClient {
- public:
- TestHistoryChildWebFrameClient() = default;
- ~TestHistoryChildWebFrameClient() override = default;
-
- // frame_test_helpers::TestWebFrameClient:
- void DidStartProvisionalLoad(WebDocumentLoader* document_loader) override {
- replaces_current_history_item_ =
- document_loader->ReplacesCurrentHistoryItem();
- }
-
- bool ReplacesCurrentHistoryItem() { return replaces_current_history_item_; }
-
- private:
- bool replaces_current_history_item_ = false;
-};
-
-class TestHistoryWebFrameClient
- : public frame_test_helpers::TestWebFrameClient {
- public:
- TestHistoryWebFrameClient() = default;
- ~TestHistoryWebFrameClient() override = default;
-
- // frame_test_helpers::TestWebFrameClient:
- WebLocalFrame* CreateChildFrame(WebLocalFrame* parent,
- WebTreeScopeType scope,
- const WebString& name,
- const WebString& fallback_name,
- const FramePolicy&,
- const WebFrameOwnerProperties&,
- FrameOwnerElementType) override {
- return CreateLocalChild(*parent, scope, &child_client_);
- }
-
- TestHistoryChildWebFrameClient& ChildClient() { return child_client_; }
-
- private:
- TestHistoryChildWebFrameClient child_client_;
-};
-
// Tests that the first navigation in an initially blank subframe will result in
// a history entry being replaced and not a new one being added.
TEST_F(WebFrameTest, FirstBlankSubframeNavigation) {
RegisterMockedHttpURLLoad("history.html");
RegisterMockedHttpURLLoad("find.html");
- TestHistoryWebFrameClient client;
frame_test_helpers::WebViewHelper web_view_helper;
- web_view_helper.InitializeAndLoad("about:blank", &client);
+ web_view_helper.InitializeAndLoad("about:blank");
WebLocalFrame* frame = web_view_helper.LocalMainFrame();
@@ -7552,17 +7578,16 @@ TEST_F(WebFrameTest, FirstBlankSubframeNavigation) {
"document.body.appendChild(document.createElement('iframe'))")));
auto* iframe = To<WebLocalFrameImpl>(frame->FirstChild());
- ASSERT_EQ(&client.ChildClient(), iframe->Client());
std::string url1 = base_url_ + "history.html";
frame_test_helpers::LoadFrame(iframe, url1);
EXPECT_EQ(url1, iframe->GetDocument().Url().GetString().Utf8());
- EXPECT_TRUE(client.ChildClient().ReplacesCurrentHistoryItem());
+ EXPECT_TRUE(iframe->GetDocumentLoader()->ReplacesCurrentHistoryItem());
std::string url2 = base_url_ + "find.html";
frame_test_helpers::LoadFrame(iframe, url2);
EXPECT_EQ(url2, iframe->GetDocument().Url().GetString().Utf8());
- EXPECT_FALSE(client.ChildClient().ReplacesCurrentHistoryItem());
+ EXPECT_FALSE(iframe->GetDocumentLoader()->ReplacesCurrentHistoryItem());
}
// Tests that a navigation in a frame with a non-blank initial URL will create
@@ -7571,9 +7596,8 @@ TEST_F(WebFrameTest, FirstNonBlankSubframeNavigation) {
RegisterMockedHttpURLLoad("history.html");
RegisterMockedHttpURLLoad("find.html");
- TestHistoryWebFrameClient client;
frame_test_helpers::WebViewHelper web_view_helper;
- web_view_helper.InitializeAndLoad("about:blank", &client);
+ web_view_helper.InitializeAndLoad("about:blank");
WebLocalFrame* frame = web_view_helper.LocalMainFrame();
@@ -7590,7 +7614,7 @@ TEST_F(WebFrameTest, FirstNonBlankSubframeNavigation) {
std::string url2 = base_url_ + "find.html";
frame_test_helpers::LoadFrame(iframe, url2);
EXPECT_EQ(url2, iframe->GetDocument().Url().GetString().Utf8());
- EXPECT_FALSE(client.ChildClient().ReplacesCurrentHistoryItem());
+ EXPECT_FALSE(iframe->GetDocumentLoader()->ReplacesCurrentHistoryItem());
}
// Test verifies that layout will change a layer's scrollable attibutes
@@ -7612,8 +7636,9 @@ TEST_F(WebFrameTest, overflowHiddenRewrite) {
ASSERT_TRUE(cc_scroll_layer);
// Verify that the cc::Layer is not scrollable initially.
- ASSERT_FALSE(cc_scroll_layer->GetUserScrollableHorizontal());
- ASSERT_FALSE(cc_scroll_layer->GetUserScrollableVertical());
+ auto* scroll_node = GetScrollNode(cc_scroll_layer);
+ ASSERT_FALSE(scroll_node->user_scrollable_horizontal);
+ ASSERT_FALSE(scroll_node->user_scrollable_vertical);
// Call javascript to make the layer scrollable, and verify it.
WebLocalFrameImpl* frame = web_view_helper.LocalMainFrame();
@@ -7621,8 +7646,9 @@ TEST_F(WebFrameTest, overflowHiddenRewrite) {
UpdateAllLifecyclePhases(web_view_helper.GetWebView());
cc_scroll_layer = frame_view->GetScrollableArea()->LayerForScrolling();
- ASSERT_TRUE(cc_scroll_layer->GetUserScrollableHorizontal());
- ASSERT_TRUE(cc_scroll_layer->GetUserScrollableVertical());
+ scroll_node = GetScrollNode(cc_scroll_layer);
+ ASSERT_TRUE(scroll_node->user_scrollable_horizontal);
+ ASSERT_TRUE(scroll_node->user_scrollable_vertical);
}
// Test that currentHistoryItem reflects the current page, not the provisional
@@ -7749,14 +7775,14 @@ TEST_F(WebFrameTest, FrameViewScrollAccountsForBrowserControls) {
// Simulate the browser controls showing by 20px, thus shrinking the viewport
// and allowing it to scroll an additional 20px.
- web_view->MainFrameWidget()->ApplyViewportChanges(
+ web_view->MainFrameWidget()->ApplyViewportChangesForTesting(
{gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, false,
20.0f / browser_controls_height, 0, cc::BrowserControlsState::kBoth});
EXPECT_EQ(ScrollOffset(0, 1920),
frame_view->LayoutViewport()->MaximumScrollOffset());
// Show more, make sure the scroll actually gets clamped.
- web_view->MainFrameWidget()->ApplyViewportChanges(
+ web_view->MainFrameWidget()->ApplyViewportChangesForTesting(
{gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, false,
20.0f / browser_controls_height, 0, cc::BrowserControlsState::kBoth});
web_view->MainFrameImpl()->SetScrollOffset(WebSize(0, 2000));
@@ -7764,16 +7790,16 @@ TEST_F(WebFrameTest, FrameViewScrollAccountsForBrowserControls) {
frame_view->LayoutViewport()->GetScrollOffset());
// Hide until there's 10px showing.
- web_view->MainFrameWidget()->ApplyViewportChanges(
+ web_view->MainFrameWidget()->ApplyViewportChangesForTesting(
{gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, false,
-30.0f / browser_controls_height, 0, cc::BrowserControlsState::kBoth});
EXPECT_EQ(ScrollOffset(0, 1910),
frame_view->LayoutViewport()->MaximumScrollOffset());
// Simulate a LayoutEmbeddedContent::resize. The frame is resized to
- // accomodate the browser controls and Blink's view of the browser controls
+ // accommodate the browser controls and Blink's view of the browser controls
// matches that of the CC
- web_view->MainFrameWidget()->ApplyViewportChanges(
+ web_view->MainFrameWidget()->ApplyViewportChangesForTesting(
{gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, false,
30.0f / browser_controls_height, 0, cc::BrowserControlsState::kBoth});
web_view->ResizeWithBrowserControls(WebSize(100, 60), 40.0f, 0, true);
@@ -7782,7 +7808,7 @@ TEST_F(WebFrameTest, FrameViewScrollAccountsForBrowserControls) {
frame_view->LayoutViewport()->MaximumScrollOffset());
// Now simulate hiding.
- web_view->MainFrameWidget()->ApplyViewportChanges(
+ web_view->MainFrameWidget()->ApplyViewportChangesForTesting(
{gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, false,
-10.0f / browser_controls_height, 0, cc::BrowserControlsState::kBoth});
EXPECT_EQ(ScrollOffset(0, 1930),
@@ -7790,7 +7816,7 @@ TEST_F(WebFrameTest, FrameViewScrollAccountsForBrowserControls) {
// Reset to original state: 100px widget height, browser controls fully
// hidden.
- web_view->MainFrameWidget()->ApplyViewportChanges(
+ web_view->MainFrameWidget()->ApplyViewportChangesForTesting(
{gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, false,
-30.0f / browser_controls_height, 0, cc::BrowserControlsState::kBoth});
web_view->ResizeWithBrowserControls(WebSize(100, 100),
@@ -7803,13 +7829,13 @@ TEST_F(WebFrameTest, FrameViewScrollAccountsForBrowserControls) {
// should allow an extra 0.5px of scrolling in the visual viewport. Make
// sure we're not losing any pixels when applying the adjustment on the
// main frame.
- web_view->MainFrameWidget()->ApplyViewportChanges(
+ web_view->MainFrameWidget()->ApplyViewportChangesForTesting(
{gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, false,
1.0f / browser_controls_height, 0, cc::BrowserControlsState::kBoth});
EXPECT_EQ(ScrollOffset(0, 1901),
frame_view->LayoutViewport()->MaximumScrollOffset());
- web_view->MainFrameWidget()->ApplyViewportChanges(
+ web_view->MainFrameWidget()->ApplyViewportChangesForTesting(
{gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, false,
2.0f / browser_controls_height, 0, cc::BrowserControlsState::kBoth});
EXPECT_EQ(ScrollOffset(0, 1903),
@@ -7911,10 +7937,14 @@ TEST_F(WebFrameTest, FullscreenLayerNonScrollable) {
cc::Layer* visual_viewport_scroll_layer =
frame_view->GetPage()->GetVisualViewport().LayerForScrolling();
- ASSERT_FALSE(layout_viewport_scroll_layer->GetUserScrollableHorizontal());
- ASSERT_FALSE(layout_viewport_scroll_layer->GetUserScrollableVertical());
- ASSERT_FALSE(visual_viewport_scroll_layer->GetUserScrollableHorizontal());
- ASSERT_FALSE(visual_viewport_scroll_layer->GetUserScrollableVertical());
+ auto* layout_viewport_scroll_node =
+ GetScrollNode(layout_viewport_scroll_layer);
+ ASSERT_FALSE(layout_viewport_scroll_node->user_scrollable_horizontal);
+ ASSERT_FALSE(layout_viewport_scroll_node->user_scrollable_vertical);
+ auto* visual_viewport_scroll_node =
+ GetScrollNode(visual_viewport_scroll_layer);
+ ASSERT_FALSE(visual_viewport_scroll_node->user_scrollable_horizontal);
+ ASSERT_FALSE(visual_viewport_scroll_node->user_scrollable_vertical);
// Verify that the viewports are scrollable upon exiting fullscreen.
EXPECT_EQ(div_fullscreen, Fullscreen::FullscreenElementFrom(*document));
@@ -7926,10 +7956,12 @@ TEST_F(WebFrameTest, FullscreenLayerNonScrollable) {
frame_view->GetScrollableArea()->LayerForScrolling();
visual_viewport_scroll_layer =
frame_view->GetPage()->GetVisualViewport().LayerForScrolling();
- ASSERT_TRUE(layout_viewport_scroll_layer->GetUserScrollableHorizontal());
- ASSERT_TRUE(layout_viewport_scroll_layer->GetUserScrollableVertical());
- ASSERT_TRUE(visual_viewport_scroll_layer->GetUserScrollableHorizontal());
- ASSERT_TRUE(visual_viewport_scroll_layer->GetUserScrollableVertical());
+ layout_viewport_scroll_node = GetScrollNode(layout_viewport_scroll_layer);
+ ASSERT_TRUE(layout_viewport_scroll_node->user_scrollable_horizontal);
+ ASSERT_TRUE(layout_viewport_scroll_node->user_scrollable_vertical);
+ visual_viewport_scroll_node = GetScrollNode(visual_viewport_scroll_layer);
+ ASSERT_TRUE(visual_viewport_scroll_node->user_scrollable_horizontal);
+ ASSERT_TRUE(visual_viewport_scroll_node->user_scrollable_vertical);
}
TEST_F(WebFrameTest, FullscreenMainFrame) {
@@ -7949,9 +7981,10 @@ TEST_F(WebFrameTest, FullscreenMainFrame) {
->View()
->LayoutViewport()
->LayerForScrolling();
- ASSERT_TRUE(cc_scroll_layer->scrollable());
- ASSERT_TRUE(cc_scroll_layer->GetUserScrollableHorizontal());
- ASSERT_TRUE(cc_scroll_layer->GetUserScrollableVertical());
+ auto* scroll_node = GetScrollNode(cc_scroll_layer);
+ ASSERT_TRUE(scroll_node->scrollable);
+ ASSERT_TRUE(scroll_node->user_scrollable_horizontal);
+ ASSERT_TRUE(scroll_node->user_scrollable_vertical);
LocalFrame* frame = web_view_impl->MainFrameImpl()->GetFrame();
Document* document = frame->GetDocument();
@@ -7972,15 +8005,17 @@ TEST_F(WebFrameTest, FullscreenMainFrame) {
->View()
->LayoutViewport()
->LayerForScrolling();
- ASSERT_TRUE(cc_scroll_layer->scrollable());
- ASSERT_TRUE(cc_scroll_layer->GetUserScrollableHorizontal());
- ASSERT_TRUE(cc_scroll_layer->GetUserScrollableVertical());
+ scroll_node = GetScrollNode(cc_scroll_layer);
+ ASSERT_TRUE(scroll_node->scrollable);
+ ASSERT_TRUE(scroll_node->user_scrollable_horizontal);
+ ASSERT_TRUE(scroll_node->user_scrollable_vertical);
// Verify the main frame still behaves correctly after a resize.
web_view_helper.Resize(WebSize(viewport_height, viewport_width));
- ASSERT_TRUE(cc_scroll_layer->scrollable());
- ASSERT_TRUE(cc_scroll_layer->GetUserScrollableHorizontal());
- ASSERT_TRUE(cc_scroll_layer->GetUserScrollableVertical());
+ scroll_node = GetScrollNode(cc_scroll_layer);
+ ASSERT_TRUE(scroll_node->scrollable);
+ ASSERT_TRUE(scroll_node->user_scrollable_horizontal);
+ ASSERT_TRUE(scroll_node->user_scrollable_vertical);
}
TEST_F(WebFrameTest, FullscreenSubframe) {
@@ -8416,19 +8451,21 @@ TEST_F(WebFrameTest, WebXrImmersiveOverlay) {
web_widget_client.layer_tree_host();
LocalFrame* frame = web_view_impl->MainFrameImpl()->GetFrame();
-
Document* document = frame->GetDocument();
- EXPECT_FALSE(document->IsImmersiveArOverlay());
- document->SetIsImmersiveArOverlay(true);
- EXPECT_TRUE(document->IsImmersiveArOverlay());
Element* overlay = document->getElementById("overlay");
EXPECT_FALSE(Fullscreen::IsFullscreenElement(*overlay));
EXPECT_EQ(SkColorGetA(layer_tree_host->background_color()), SK_AlphaOPAQUE);
- // Fullscreen should work without separate user activation while in ArOverlay
- // mode.
+ // It's not legal to switch the fullscreen element while in immersive-ar mode,
+ // so set the fullscreen element first before activating that. This requires
+ // user activation.
+ LocalFrame::NotifyUserActivation(frame);
Fullscreen::RequestFullscreen(*overlay);
+ EXPECT_FALSE(document->IsXrOverlay());
+ document->SetIsXrOverlay(true, overlay);
+ EXPECT_TRUE(document->IsXrOverlay());
+
web_view_impl->MainFrameWidget()->DidEnterFullscreen();
UpdateAllLifecyclePhases(web_view_impl);
EXPECT_TRUE(Fullscreen::IsFullscreenElement(*overlay));
@@ -8503,7 +8540,7 @@ TEST_F(WebFrameTest, WebXrImmersiveOverlay) {
UpdateAllLifecyclePhases(web_view_impl);
EXPECT_FALSE(Fullscreen::IsFullscreenElement(*overlay));
EXPECT_EQ(SkColorGetA(layer_tree_host->background_color()), SK_AlphaOPAQUE);
- document->SetIsImmersiveArOverlay(false);
+ document->SetIsXrOverlay(false, overlay);
}
TEST_F(WebFrameTest, LayoutBlockPercentHeightDescendants) {
@@ -8956,7 +8993,7 @@ class SwapMainFrameWhenTitleChangesWebFrameClient
~SwapMainFrameWhenTitleChangesWebFrameClient() override = default;
// frame_test_helpers::TestWebFrameClient:
- void DidReceiveTitle(const WebString& title, WebTextDirection) override {
+ void DidReceiveTitle(const WebString& title) override {
if (title.IsEmpty())
return;
@@ -9141,6 +9178,8 @@ TEST_F(WebFrameSwapTest, EventsOnDisconnectedSubDocumentSkipped) {
WebFrame* target_frame = MainFrame()->FirstChild()->NextSibling();
EXPECT_TRUE(target_frame);
SwapAndVerifySubframeConsistency("local->remote", target_frame, remote_frame);
+ remote_frame->SetReplicatedOrigin(
+ WebSecurityOrigin(SecurityOrigin::CreateUniqueOpaque()), false);
WebLocalFrameImpl* local_child = frame_test_helpers::CreateLocalChild(
*remote_frame, "local-inside-remote");
@@ -9154,8 +9193,7 @@ TEST_F(WebFrameSwapTest, EventsOnDisconnectedSubDocumentSkipped) {
event_registry.DidAddEventHandler(
*child_document, EventHandlerRegistry::kTouchStartOrMoveEventBlocking);
// Passes if this does not crash or DCHECK.
- main_frame->View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ main_frame->View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
}
TEST_F(WebFrameSwapTest, EventsOnDisconnectedElementSkipped) {
@@ -9163,6 +9201,8 @@ TEST_F(WebFrameSwapTest, EventsOnDisconnectedElementSkipped) {
WebFrame* target_frame = MainFrame()->FirstChild()->NextSibling();
EXPECT_TRUE(target_frame);
SwapAndVerifySubframeConsistency("local->remote", target_frame, remote_frame);
+ remote_frame->SetReplicatedOrigin(
+ WebSecurityOrigin(SecurityOrigin::CreateUniqueOpaque()), false);
WebLocalFrameImpl* local_child = frame_test_helpers::CreateLocalChild(
*remote_frame, "local-inside-remote");
@@ -9182,8 +9222,7 @@ TEST_F(WebFrameSwapTest, EventsOnDisconnectedElementSkipped) {
*child_document->body(),
EventHandlerRegistry::kTouchStartOrMoveEventBlocking);
// Passes if this does not crash or DCHECK.
- main_frame->View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ main_frame->View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
}
TEST_F(WebFrameSwapTest, SwapParentShouldDetachChildren) {
@@ -9422,9 +9461,9 @@ class RemoteToLocalSwapWebFrameClient
~RemoteToLocalSwapWebFrameClient() override = default;
// frame_test_helpers::TestWebFrameClient:
- void DidCommitProvisionalLoad(const WebHistoryItem&,
- WebHistoryCommitType history_commit_type,
- bool) override {
+ void DidCommitNavigation(const WebHistoryItem&,
+ WebHistoryCommitType history_commit_type,
+ bool) override {
history_commit_type_ = history_commit_type;
remote_frame_->Swap(Frame());
}
@@ -9493,11 +9532,11 @@ class RemoteNavigationClient
void Navigate(const WebURLRequest& request,
bool should_replace_current_entry,
bool is_opener_navigation,
- bool has_download_sandbox_flag,
+ bool initiator_frame_has_download_sandbox_flag,
bool blocking_downloads_in_sandbox_enabled,
bool initiator_frame_is_ad,
mojo::ScopedMessagePipeHandle) override {
- last_request_ = request;
+ last_request_.CopyFrom(request);
}
const WebURLRequest& LastRequest() const { return last_request_; }
@@ -9608,10 +9647,9 @@ TEST_F(WebFrameTest, NavigateRemoteToLocalWithOpener) {
// Create a popup with a remote frame and set its opener to the main frame.
frame_test_helpers::WebViewHelper popup_helper;
- popup_helper.InitializeRemote(
- nullptr, SecurityOrigin::CreateFromString("http://foo.com"));
+ popup_helper.InitializeRemoteWithOpener(
+ main_frame, nullptr, SecurityOrigin::CreateFromString("http://foo.com"));
WebRemoteFrame* popup_remote_frame = popup_helper.RemoteMainFrame();
- popup_remote_frame->SetOpener(main_frame);
EXPECT_FALSE(main_frame->GetSecurityOrigin().CanAccess(
popup_remote_frame->GetSecurityOrigin()));
@@ -9648,9 +9686,9 @@ class CommitTypeWebFrameClient : public frame_test_helpers::TestWebFrameClient {
~CommitTypeWebFrameClient() override = default;
// frame_test_helpers::TestWebFrameClient:
- void DidCommitProvisionalLoad(const WebHistoryItem&,
- WebHistoryCommitType history_commit_type,
- bool) override {
+ void DidCommitNavigation(const WebHistoryItem&,
+ WebHistoryCommitType history_commit_type,
+ bool) override {
history_commit_type_ = history_commit_type;
}
@@ -9711,7 +9749,7 @@ TEST_F(WebFrameTest, FrameWidgetTest) {
WebGestureEvent event(WebInputEvent::kGestureTap, WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(WebFloatPoint(20, 20));
+ event.SetPositionInWidget(gfx::PointF(20, 20));
child_frame->FrameWidget()->HandleInputEvent(WebCoalescedInputEvent(event));
EXPECT_TRUE(child_widget_client.DidHandleGestureEvent());
@@ -9959,11 +9997,11 @@ TEST_F(WebFrameTest, SiteForCookiesFromChildWithRemoteMainFrame) {
RegisterMockedHttpURLLoad("foo.html");
frame_test_helpers::LoadFrame(local_frame, base_url_ + "foo.html");
- EXPECT_EQ(WebURL(NullURL()), local_frame->GetDocument().SiteForCookies());
+ EXPECT_TRUE(local_frame->GetDocument().SiteForCookies().IsNull());
SchemeRegistry::RegisterURLSchemeAsFirstPartyWhenTopLevel("http");
- EXPECT_EQ(WebURL(ToKURL(not_base_url_)),
- local_frame->GetDocument().SiteForCookies());
+ EXPECT_TRUE(net::SiteForCookies::FromUrl(ToKURL(not_base_url_))
+ .IsEquivalent(local_frame->GetDocument().SiteForCookies()));
SchemeRegistry::RemoveURLSchemeAsFirstPartyWhenTopLevel("http");
}
@@ -10027,11 +10065,10 @@ class OverscrollWebWidgetClient
: public frame_test_helpers::TestWebWidgetClient {
public:
MOCK_METHOD4(DidOverscroll,
- void(const WebFloatSize&,
- const WebFloatSize&,
- const WebFloatPoint&,
- const WebFloatSize&));
- MOCK_METHOD1(SetOverscrollBehavior, void(const cc::OverscrollBehavior&));
+ void(const gfx::Vector2dF&,
+ const gfx::Vector2dF&,
+ const gfx::PointF&,
+ const gfx::Vector2dF&));
};
class WebFrameOverscrollTest
@@ -10049,7 +10086,7 @@ class WebFrameOverscrollTest
GetParam());
// TODO(wjmaclean): Make sure that touchpad device is only ever used for
// gesture scrolling event types.
- event.SetPositionInWidget(WebFloatPoint(100, 100));
+ event.SetPositionInWidget(gfx::PointF(100, 100));
if (type == WebInputEvent::kGestureScrollUpdate) {
event.data.scroll_update.delta_x = delta_x;
event.data.scroll_update.delta_y = delta_y;
@@ -10092,7 +10129,6 @@ TEST_P(WebFrameOverscrollTest,
RegisterMockedHttpURLLoad("overscroll/overscroll.html");
frame_test_helpers::WebViewHelper web_view_helper;
- EXPECT_CALL(client, SetOverscrollBehavior(cc::OverscrollBehavior()));
web_view_helper.InitializeAndLoad(base_url_ + "overscroll/overscroll.html",
nullptr, nullptr, &client,
ConfigureAndroid);
@@ -10101,18 +10137,21 @@ TEST_P(WebFrameOverscrollTest,
// Calculation of accumulatedRootOverscroll and unusedDelta on multiple
// scrollUpdate.
ScrollBegin(&web_view_helper, -300, -316);
- EXPECT_CALL(client, DidOverscroll(WebFloatSize(8, 16), WebFloatSize(8, 16),
- WebFloatPoint(100, 100), WebFloatSize()));
+ EXPECT_CALL(client,
+ DidOverscroll(gfx::Vector2dF(8, 16), gfx::Vector2dF(8, 16),
+ gfx::PointF(100, 100), gfx::Vector2dF()));
ScrollUpdate(&web_view_helper, -308, -316);
Mock::VerifyAndClearExpectations(&client);
- EXPECT_CALL(client, DidOverscroll(WebFloatSize(0, 13), WebFloatSize(8, 29),
- WebFloatPoint(100, 100), WebFloatSize()));
+ EXPECT_CALL(client,
+ DidOverscroll(gfx::Vector2dF(0, 13), gfx::Vector2dF(8, 29),
+ gfx::PointF(100, 100), gfx::Vector2dF()));
ScrollUpdate(&web_view_helper, 0, -13);
Mock::VerifyAndClearExpectations(&client);
- EXPECT_CALL(client, DidOverscroll(WebFloatSize(20, 13), WebFloatSize(28, 42),
- WebFloatPoint(100, 100), WebFloatSize()));
+ EXPECT_CALL(client,
+ DidOverscroll(gfx::Vector2dF(20, 13), gfx::Vector2dF(28, 42),
+ gfx::PointF(100, 100), gfx::Vector2dF()));
ScrollUpdate(&web_view_helper, -20, -13);
Mock::VerifyAndClearExpectations(&client);
@@ -10127,8 +10166,8 @@ TEST_P(WebFrameOverscrollTest,
// Overscroll is reported.
EXPECT_CALL(client,
- DidOverscroll(WebFloatSize(0, -701), WebFloatSize(0, -701),
- WebFloatPoint(100, 100), WebFloatSize()));
+ DidOverscroll(gfx::Vector2dF(0, -701), gfx::Vector2dF(0, -701),
+ gfx::PointF(100, 100), gfx::Vector2dF()));
ScrollUpdate(&web_view_helper, 0, 1000);
Mock::VerifyAndClearExpectations(&client);
@@ -10144,7 +10183,6 @@ TEST_P(WebFrameOverscrollTest,
RegisterMockedHttpURLLoad("overscroll/div-overscroll.html");
frame_test_helpers::WebViewHelper web_view_helper;
- EXPECT_CALL(client, SetOverscrollBehavior(cc::OverscrollBehavior()));
web_view_helper.InitializeAndLoad(
base_url_ + "overscroll/div-overscroll.html", nullptr, nullptr, &client,
ConfigureAndroid);
@@ -10161,8 +10199,9 @@ TEST_P(WebFrameOverscrollTest,
ScrollBegin(&web_view_helper, 0, -100);
// Now On Scrolling DIV, scroll is bubbled and root layer is over-scrolled.
- EXPECT_CALL(client, DidOverscroll(WebFloatSize(0, 100), WebFloatSize(0, 100),
- WebFloatPoint(100, 100), WebFloatSize()));
+ EXPECT_CALL(client,
+ DidOverscroll(gfx::Vector2dF(0, 100), gfx::Vector2dF(0, 100),
+ gfx::PointF(100, 100), gfx::Vector2dF()));
ScrollUpdate(&web_view_helper, 0, -100);
ScrollUpdate(&web_view_helper, 0, -100);
Mock::VerifyAndClearExpectations(&client);
@@ -10171,8 +10210,8 @@ TEST_P(WebFrameOverscrollTest,
// being run in a WebView without a size. This test should be fixed along with
// the bug, crbug.com/589320.
// Page scrolls vertically, but over-scrolls horizontally.
- // EXPECT_CALL(client, didOverscroll(WebFloatSize(-100, 0), WebFloatSize(-100,
- // 0), WebFloatPoint(100, 100), WebFloatSize()));
+ // EXPECT_CALL(client, didOverscroll(gfx::Vector2dF(-100, 0),
+ // gfx::Vector2dF(-100, 0), gfx::PointF(100, 100), gfx::Vector2dF()));
// ScrollUpdate(&webViewHelper, 100, 50);
// Mock::VerifyAndClearExpectations(&client);
@@ -10182,8 +10221,8 @@ TEST_P(WebFrameOverscrollTest,
// Mock::VerifyAndClearExpectations(&client);
// Page scrolls horizontally, but over-scrolls vertically.
- // EXPECT_CALL(client, didOverscroll(WebFloatSize(0, 100), WebFloatSize(0,
- // 100), WebFloatPoint(100, 100), WebFloatSize()));
+ // EXPECT_CALL(client, didOverscroll(gfx::Vector2dF(0, 100), gfx::Vector2dF(0,
+ // 100), gfx::PointF(100, 100), gfx::Vector2dF()));
// ScrollUpdate(&webViewHelper, -100, -100);
// Mock::VerifyAndClearExpectations(&client);
}
@@ -10193,7 +10232,6 @@ TEST_P(WebFrameOverscrollTest, RootLayerOverscrolledOnInnerDivOverScroll) {
RegisterMockedHttpURLLoad("overscroll/div-overscroll.html");
frame_test_helpers::WebViewHelper web_view_helper;
- EXPECT_CALL(client, SetOverscrollBehavior(cc::OverscrollBehavior()));
web_view_helper.InitializeAndLoad(
base_url_ + "overscroll/div-overscroll.html", nullptr, nullptr, &client,
ConfigureAndroid);
@@ -10210,8 +10248,9 @@ TEST_P(WebFrameOverscrollTest, RootLayerOverscrolledOnInnerDivOverScroll) {
ScrollBegin(&web_view_helper, 0, -150);
// Now On Scrolling DIV, scroll is bubbled and root layer is over-scrolled.
- EXPECT_CALL(client, DidOverscroll(WebFloatSize(0, 50), WebFloatSize(0, 50),
- WebFloatPoint(100, 100), WebFloatSize()));
+ EXPECT_CALL(client,
+ DidOverscroll(gfx::Vector2dF(0, 50), gfx::Vector2dF(0, 50),
+ gfx::PointF(100, 100), gfx::Vector2dF()));
ScrollUpdate(&web_view_helper, 0, -150);
Mock::VerifyAndClearExpectations(&client);
}
@@ -10222,7 +10261,6 @@ TEST_P(WebFrameOverscrollTest, RootLayerOverscrolledOnInnerIFrameOverScroll) {
RegisterMockedHttpURLLoad("overscroll/scrollable-iframe.html");
frame_test_helpers::WebViewHelper web_view_helper;
- EXPECT_CALL(client, SetOverscrollBehavior(cc::OverscrollBehavior()));
web_view_helper.InitializeAndLoad(
base_url_ + "overscroll/iframe-overscroll.html", nullptr, nullptr,
&client, ConfigureAndroid);
@@ -10245,8 +10283,9 @@ TEST_P(WebFrameOverscrollTest, RootLayerOverscrolledOnInnerIFrameOverScroll) {
ScrollBegin(&web_view_helper, 0, -150);
// Now On Scrolling IFrame, scroll is bubbled and root layer is over-scrolled.
- EXPECT_CALL(client, DidOverscroll(WebFloatSize(0, 50), WebFloatSize(0, 50),
- WebFloatPoint(100, 100), WebFloatSize()));
+ EXPECT_CALL(client,
+ DidOverscroll(gfx::Vector2dF(0, 50), gfx::Vector2dF(0, 50),
+ gfx::PointF(100, 100), gfx::Vector2dF()));
ScrollUpdate(&web_view_helper, 0, -150);
Mock::VerifyAndClearExpectations(&client);
@@ -10258,7 +10297,6 @@ TEST_P(WebFrameOverscrollTest, ScaledPageRootLayerOverscrolled) {
RegisterMockedHttpURLLoad("overscroll/overscroll.html");
frame_test_helpers::WebViewHelper web_view_helper;
- EXPECT_CALL(client, SetOverscrollBehavior(cc::OverscrollBehavior()));
WebViewImpl* web_view_impl = web_view_helper.InitializeAndLoad(
base_url_ + "overscroll/overscroll.html", nullptr, nullptr, &client,
ConfigureAndroid);
@@ -10269,25 +10307,27 @@ 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(WebFloatSize(0, -30), WebFloatSize(0, -30),
- WebFloatPoint(99, 99), WebFloatSize()));
+ EXPECT_CALL(client,
+ DidOverscroll(gfx::Vector2dF(0, -30), gfx::Vector2dF(0, -30),
+ gfx::PointF(99, 99), gfx::Vector2dF()));
ScrollUpdate(&web_view_helper, 0, 30);
Mock::VerifyAndClearExpectations(&client);
- EXPECT_CALL(client, DidOverscroll(WebFloatSize(0, -30), WebFloatSize(0, -60),
- WebFloatPoint(99, 99), WebFloatSize()));
+ EXPECT_CALL(client,
+ DidOverscroll(gfx::Vector2dF(0, -30), gfx::Vector2dF(0, -60),
+ gfx::PointF(99, 99), gfx::Vector2dF()));
ScrollUpdate(&web_view_helper, 0, 30);
Mock::VerifyAndClearExpectations(&client);
EXPECT_CALL(client,
- DidOverscroll(WebFloatSize(-30, -30), WebFloatSize(-30, -90),
- WebFloatPoint(99, 99), WebFloatSize()));
+ DidOverscroll(gfx::Vector2dF(-30, -30), gfx::Vector2dF(-30, -90),
+ gfx::PointF(99, 99), gfx::Vector2dF()));
ScrollUpdate(&web_view_helper, 30, 30);
Mock::VerifyAndClearExpectations(&client);
EXPECT_CALL(client,
- DidOverscroll(WebFloatSize(-30, 0), WebFloatSize(-60, -90),
- WebFloatPoint(99, 99), WebFloatSize()));
+ DidOverscroll(gfx::Vector2dF(-30, 0), gfx::Vector2dF(-60, -90),
+ gfx::PointF(99, 99), gfx::Vector2dF()));
ScrollUpdate(&web_view_helper, 30, 0);
Mock::VerifyAndClearExpectations(&client);
@@ -10302,7 +10342,6 @@ TEST_P(WebFrameOverscrollTest, NoOverscrollForSmallvalues) {
RegisterMockedHttpURLLoad("overscroll/overscroll.html");
frame_test_helpers::WebViewHelper web_view_helper;
- EXPECT_CALL(client, SetOverscrollBehavior(cc::OverscrollBehavior()));
web_view_helper.InitializeAndLoad(base_url_ + "overscroll/overscroll.html",
nullptr, nullptr, &client,
ConfigureAndroid);
@@ -10310,20 +10349,20 @@ TEST_P(WebFrameOverscrollTest, NoOverscrollForSmallvalues) {
ScrollBegin(&web_view_helper, 10, 10);
EXPECT_CALL(client,
- DidOverscroll(WebFloatSize(-10, -10), WebFloatSize(-10, -10),
- WebFloatPoint(100, 100), WebFloatSize()));
+ DidOverscroll(gfx::Vector2dF(-10, -10), gfx::Vector2dF(-10, -10),
+ gfx::PointF(100, 100), gfx::Vector2dF()));
ScrollUpdate(&web_view_helper, 10, 10);
Mock::VerifyAndClearExpectations(&client);
- EXPECT_CALL(client,
- DidOverscroll(WebFloatSize(0, -0.10), WebFloatSize(-10, -10.10),
- WebFloatPoint(100, 100), WebFloatSize()));
+ EXPECT_CALL(client, DidOverscroll(gfx::Vector2dF(0, -0.10),
+ gfx::Vector2dF(-10, -10.10),
+ gfx::PointF(100, 100), gfx::Vector2dF()));
ScrollUpdate(&web_view_helper, 0, 0.10);
Mock::VerifyAndClearExpectations(&client);
- EXPECT_CALL(client, DidOverscroll(WebFloatSize(-0.10, 0),
- WebFloatSize(-10.10, -10.10),
- WebFloatPoint(100, 100), WebFloatSize()));
+ EXPECT_CALL(client, DidOverscroll(gfx::Vector2dF(-0.10, 0),
+ gfx::Vector2dF(-10.10, -10.10),
+ gfx::PointF(100, 100), gfx::Vector2dF()));
ScrollUpdate(&web_view_helper, 0.10, 0);
Mock::VerifyAndClearExpectations(&client);
@@ -10363,7 +10402,6 @@ TEST_P(WebFrameOverscrollTest, OverscrollBehaviorGoesToCompositor) {
RegisterMockedHttpURLLoad("overscroll/overscroll.html");
frame_test_helpers::WebViewHelper web_view_helper;
- EXPECT_CALL(client, SetOverscrollBehavior(cc::OverscrollBehavior()));
web_view_helper.InitializeAndLoad(base_url_ + "overscroll/overscroll.html",
nullptr, nullptr, &client,
ConfigureAndroid);
@@ -10371,47 +10409,43 @@ TEST_P(WebFrameOverscrollTest, OverscrollBehaviorGoesToCompositor) {
WebLocalFrame* mainFrame =
web_view_helper.GetWebView()->MainFrame()->ToWebLocalFrame();
- EXPECT_CALL(client, SetOverscrollBehavior(cc::OverscrollBehavior(
- cc::OverscrollBehavior::OverscrollBehaviorType::
- kOverscrollBehaviorTypeAuto)));
+ EXPECT_EQ(web_view_helper.GetLayerTreeHost()->overscroll_behavior(),
+ cc::OverscrollBehavior());
mainFrame->ExecuteScript(
WebScriptSource(WebString("document.body.style="
"'overscroll-behavior: auto;'")));
-
ScrollBegin(&web_view_helper, 100, 116);
- EXPECT_CALL(client,
- DidOverscroll(WebFloatSize(-100, -100), WebFloatSize(-100, -100),
- WebFloatPoint(100, 100), WebFloatSize()));
+ EXPECT_CALL(client, DidOverscroll(gfx::Vector2dF(-100, -100),
+ gfx::Vector2dF(-100, -100),
+ gfx::PointF(100, 100), gfx::Vector2dF()));
ScrollUpdate(&web_view_helper, 100, 100);
Mock::VerifyAndClearExpectations(&client);
+ EXPECT_EQ(web_view_helper.GetLayerTreeHost()->overscroll_behavior(),
+ kOverscrollBehaviorAuto);
- EXPECT_CALL(client, SetOverscrollBehavior(cc::OverscrollBehavior(
- cc::OverscrollBehavior::OverscrollBehaviorType::
- kOverscrollBehaviorTypeContain)));
mainFrame->ExecuteScript(
WebScriptSource(WebString("document.body.style="
"'overscroll-behavior: contain;'")));
-
ScrollBegin(&web_view_helper, 100, 116);
- EXPECT_CALL(client,
- DidOverscroll(WebFloatSize(-100, -100), WebFloatSize(-200, -200),
- WebFloatPoint(100, 100), WebFloatSize()));
+ EXPECT_CALL(client, DidOverscroll(gfx::Vector2dF(-100, -100),
+ gfx::Vector2dF(-200, -200),
+ gfx::PointF(100, 100), gfx::Vector2dF()));
ScrollUpdate(&web_view_helper, 100, 100);
Mock::VerifyAndClearExpectations(&client);
+ EXPECT_EQ(web_view_helper.GetLayerTreeHost()->overscroll_behavior(),
+ kOverscrollBehaviorContain);
- EXPECT_CALL(client, SetOverscrollBehavior(cc::OverscrollBehavior(
- cc::OverscrollBehavior::OverscrollBehaviorType::
- kOverscrollBehaviorTypeNone)));
mainFrame->ExecuteScript(
WebScriptSource(WebString("document.body.style="
"'overscroll-behavior: none;'")));
-
ScrollBegin(&web_view_helper, 100, 116);
- EXPECT_CALL(client,
- DidOverscroll(WebFloatSize(-100, -100), WebFloatSize(-300, -300),
- WebFloatPoint(100, 100), WebFloatSize()));
+ EXPECT_CALL(client, DidOverscroll(gfx::Vector2dF(-100, -100),
+ gfx::Vector2dF(-300, -300),
+ gfx::PointF(100, 100), gfx::Vector2dF()));
ScrollUpdate(&web_view_helper, 100, 100);
Mock::VerifyAndClearExpectations(&client);
+ EXPECT_EQ(web_view_helper.GetLayerTreeHost()->overscroll_behavior(),
+ kOverscrollBehaviorNone);
}
TEST_P(WebFrameOverscrollTest, OnlyMainFrameOverscrollBehaviorHasEffect) {
@@ -10420,7 +10454,6 @@ TEST_P(WebFrameOverscrollTest, OnlyMainFrameOverscrollBehaviorHasEffect) {
RegisterMockedHttpURLLoad("overscroll/scrollable-iframe.html");
frame_test_helpers::WebViewHelper web_view_helper;
- EXPECT_CALL(client, SetOverscrollBehavior(cc::OverscrollBehavior()));
web_view_helper.InitializeAndLoad(
base_url_ + "overscroll/iframe-overscroll.html", nullptr, nullptr,
&client, ConfigureAndroid);
@@ -10435,32 +10468,29 @@ TEST_P(WebFrameOverscrollTest, OnlyMainFrameOverscrollBehaviorHasEffect) {
->MainFrame()
->FirstChild()
->ToWebLocalFrame();
- EXPECT_CALL(client, SetOverscrollBehavior(cc::OverscrollBehavior(
- cc::OverscrollBehavior::OverscrollBehaviorType::
- kOverscrollBehaviorTypeAuto)));
subframe->ExecuteScript(
WebScriptSource(WebString("document.body.style="
"'overscroll-behavior: none;'")));
ScrollBegin(&web_view_helper, 100, 116);
- EXPECT_CALL(client,
- DidOverscroll(WebFloatSize(-100, -100), WebFloatSize(-100, -100),
- WebFloatPoint(100, 100), WebFloatSize()));
+ EXPECT_CALL(client, DidOverscroll(gfx::Vector2dF(-100, -100),
+ gfx::Vector2dF(-100, -100),
+ gfx::PointF(100, 100), gfx::Vector2dF()));
ScrollUpdate(&web_view_helper, 100, 100);
Mock::VerifyAndClearExpectations(&client);
+ EXPECT_EQ(web_view_helper.GetLayerTreeHost()->overscroll_behavior(),
+ kOverscrollBehaviorAuto);
- EXPECT_CALL(client, SetOverscrollBehavior(cc::OverscrollBehavior(
- cc::OverscrollBehavior::OverscrollBehaviorType::
- kOverscrollBehaviorTypeContain)));
mainFrame->ExecuteScript(
WebScriptSource(WebString("document.body.style="
"'overscroll-behavior: contain;'")));
-
- EXPECT_CALL(client,
- DidOverscroll(WebFloatSize(-100, -100), WebFloatSize(-200, -200),
- WebFloatPoint(100, 100), WebFloatSize()));
+ EXPECT_CALL(client, DidOverscroll(gfx::Vector2dF(-100, -100),
+ gfx::Vector2dF(-200, -200),
+ gfx::PointF(100, 100), gfx::Vector2dF()));
ScrollUpdate(&web_view_helper, 100, 100);
Mock::VerifyAndClearExpectations(&client);
+ EXPECT_EQ(web_view_helper.GetLayerTreeHost()->overscroll_behavior(),
+ kOverscrollBehaviorContain);
}
TEST_F(WebFrameTest, OrientationFrameDetach) {
@@ -10497,18 +10527,19 @@ TEST_F(WebFrameTest, ImageDocumentLoadResponseEnd) {
Document* document = web_view->MainFrameImpl()->GetFrame()->GetDocument();
EXPECT_TRUE(document);
- EXPECT_TRUE(document->IsImageDocument());
+ EXPECT_TRUE(IsA<ImageDocument>(document));
- ImageDocument* img_document = ToImageDocument(document);
- ImageResource* resource = img_document->CachedImageResourceDeprecated();
+ auto* img_document = To<ImageDocument>(document);
+ ImageResourceContent* image_content = img_document->CachedImage();
- EXPECT_TRUE(resource);
- EXPECT_NE(base::TimeTicks(), resource->LoadResponseEnd());
+ EXPECT_TRUE(image_content);
+ EXPECT_NE(base::TimeTicks(), image_content->LoadResponseEnd());
DocumentLoader* loader = document->Loader();
EXPECT_TRUE(loader);
- EXPECT_EQ(loader->GetTiming().ResponseEnd(), resource->LoadResponseEnd());
+ EXPECT_EQ(loader->GetTiming().ResponseEnd(),
+ image_content->LoadResponseEnd());
}
TEST_F(WebFrameTest, CopyImageDocument) {
@@ -10522,60 +10553,76 @@ TEST_F(WebFrameTest, CopyImageDocument) {
Document* document = web_frame->GetFrame()->GetDocument();
ASSERT_TRUE(document);
- EXPECT_TRUE(document->IsImageDocument());
- EXPECT_TRUE(SystemClipboard::GetInstance().ReadAvailableTypes().IsEmpty());
+ EXPECT_TRUE(IsA<ImageDocument>(document));
+
+ // Setup a mock clipboard host.
+ PageTestBase::MockClipboardHostProvider mock_clipboard_host_provider(
+ web_frame->GetFrame()->GetBrowserInterfaceBroker());
+
+ SystemClipboard* system_clipboard =
+ document->GetFrame()->GetSystemClipboard();
+ ASSERT_TRUE(system_clipboard);
+
+ EXPECT_TRUE(system_clipboard->ReadAvailableTypes().IsEmpty());
bool result = web_frame->ExecuteCommand("Copy");
test::RunPendingTasks();
EXPECT_TRUE(result);
- Vector<String> types = SystemClipboard::GetInstance().ReadAvailableTypes();
+ Vector<String> types = system_clipboard->ReadAvailableTypes();
EXPECT_EQ(2u, types.size());
EXPECT_EQ("text/html", types[0]);
EXPECT_EQ("image/png", types[1]);
// Clear clipboard data
- SystemClipboard::GetInstance().WritePlainText("");
- SystemClipboard::GetInstance().CommitWrite();
+ system_clipboard->WritePlainText("");
+ system_clipboard->CommitWrite();
}
-class CallbackOrderingWebFrameClient
- : public frame_test_helpers::TestWebFrameClient {
- public:
- CallbackOrderingWebFrameClient() : callback_count_(0) {}
- ~CallbackOrderingWebFrameClient() override = default;
+TEST_F(WebFrameTest, CopyTextInImageDocument) {
+ // If Javascript inserts other contents into an image document, we should be
+ // able to copy those contents, not just the image itself.
- // frame_test_helpers::TestWebFrameClient:
- void DidStartLoading() override {
- EXPECT_EQ(0, callback_count_++);
- frame_test_helpers::TestWebFrameClient::DidStartLoading();
- }
- void DidStartProvisionalLoad(WebDocumentLoader*) override {
- EXPECT_EQ(1, callback_count_++);
- }
- void DidCommitProvisionalLoad(const WebHistoryItem&,
- WebHistoryCommitType,
- bool) override {
- EXPECT_EQ(2, callback_count_++);
- }
- void DidFinishDocumentLoad() override { EXPECT_EQ(3, callback_count_++); }
- void DidHandleOnloadEvents() override { EXPECT_EQ(4, callback_count_++); }
- void DidFinishLoad() override { EXPECT_EQ(5, callback_count_++); }
- void DidStopLoading() override {
- EXPECT_EQ(6, callback_count_++);
- frame_test_helpers::TestWebFrameClient::DidStopLoading();
- }
+ RegisterMockedHttpURLLoadWithMimeType("white-1x1.png", "image/png");
+ frame_test_helpers::WebViewHelper web_view_helper;
+ web_view_helper.InitializeAndLoad(base_url_ + "white-1x1.png");
+ WebViewImpl* web_view = web_view_helper.GetWebView();
+ WebLocalFrameImpl* web_frame = web_view->MainFrameImpl();
+ Document* document = web_frame->GetFrame()->GetDocument();
- private:
- int callback_count_;
-};
+ ASSERT_TRUE(document);
+ EXPECT_TRUE(IsA<ImageDocument>(document));
-TEST_F(WebFrameTest, CallbackOrdering) {
- RegisterMockedHttpURLLoad("foo.html");
- CallbackOrderingWebFrameClient client;
- frame_test_helpers::WebViewHelper web_view_helper;
- web_view_helper.InitializeAndLoad(base_url_ + "foo.html", &client);
+ Node* text = document->createTextNode("copy me");
+ document->body()->appendChild(text);
+ document->GetFrame()->Selection().SetSelection(
+ SelectionInDOMTree::Builder().SelectAllChildren(*text).Build(),
+ SetSelectionOptions());
+
+ // Setup a mock clipboard host.
+ PageTestBase::MockClipboardHostProvider mock_clipboard_host_provider(
+ web_frame->GetFrame()->GetBrowserInterfaceBroker());
+
+ SystemClipboard* system_clipboard =
+ document->GetFrame()->GetSystemClipboard();
+ ASSERT_TRUE(system_clipboard);
+
+ EXPECT_TRUE(system_clipboard->ReadAvailableTypes().IsEmpty());
+
+ bool result = web_frame->ExecuteCommand("Copy");
+ test::RunPendingTasks();
+
+ EXPECT_TRUE(result);
+
+ Vector<String> types = system_clipboard->ReadAvailableTypes();
+ EXPECT_EQ(2u, types.size());
+ EXPECT_EQ("text/plain", types[0]);
+ EXPECT_EQ("text/html", types[1]);
+
+ // Clear clipboard data
+ system_clipboard->WritePlainText("");
+ system_clipboard->CommitWrite();
}
class TestRemoteFrameHostForVisibility : public FakeRemoteFrameHost {
@@ -10613,11 +10660,9 @@ class WebRemoteFrameVisibilityChangeTest : public WebFrameTest {
void ExecuteScriptOnMainFrame(const WebScriptSource& script) {
MainFrame()->ExecuteScript(script);
- MainFrame()->View()->MainFrameWidget()->BeginFrame(base::TimeTicks::Now(),
- false);
- MainFrame()->View()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
- MainFrame()->View()->MainFrameWidget()->DidBeginFrame();
+ web_view_helper_.GetWebView()
+ ->MainFrameWidgetBase()
+ ->SynchronouslyCompositeForTesting(base::TimeTicks::Now());
RunPendingTasks();
}
@@ -10708,11 +10753,9 @@ class WebLocalFrameVisibilityChangeTest
void ExecuteScriptOnMainFrame(const WebScriptSource& script) {
MainFrame()->ExecuteScript(script);
- MainFrame()->View()->MainFrameWidget()->BeginFrame(base::TimeTicks::Now(),
- false);
- MainFrame()->View()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
- MainFrame()->View()->MainFrameWidget()->DidBeginFrame();
+ web_view_helper_.GetWebView()
+ ->MainFrameWidgetBase()
+ ->SynchronouslyCompositeForTesting(base::TimeTicks::Now());
RunPendingTasks();
}
@@ -10851,23 +10894,117 @@ TEST(WebFrameGlobalReuseTest, ReuseForMainFrameIfEnabled) {
.ToLocalChecked()));
}
-class SaveImageFromDataURLWebFrameClient
- : public frame_test_helpers::TestWebFrameClient {
+// This class intercepts the registration of Blob instances.
+//
+// Given that the content of the Blob is known (data URL)
+// it gets the data from the DataElement's BytesProvider, and creates
+// FakeBlob's accordingly.
+class BlobRegistryForSaveImageFromDataURL : public mojom::blink::BlobRegistry {
public:
- SaveImageFromDataURLWebFrameClient() = default;
- ~SaveImageFromDataURLWebFrameClient() override = default;
+ void Register(mojo::PendingReceiver<mojom::blink::Blob> blob,
+ const String& uuid,
+ const String& content_type,
+ const String& content_disposition,
+ Vector<mojom::blink::DataElementPtr> elements,
+ RegisterCallback callback) override {
+ DCHECK_EQ(elements.size(), 1u);
+ DCHECK(elements[0]->is_bytes());
+
+ auto& element0 = elements[0];
+ const auto& bytes = element0->get_bytes();
+ auto length = bytes->length;
+ String body(reinterpret_cast<const char*>(bytes->embedded_data->data()),
+ static_cast<uint32_t>(length));
+ mojo::MakeSelfOwnedReceiver(std::make_unique<FakeBlob>(uuid, body),
+ std::move(blob));
+ std::move(callback).Run();
+ }
+
+ void RegisterFromStream(
+ const String& content_type,
+ const String& content_disposition,
+ uint64_t expected_length,
+ mojo::ScopedDataPipeConsumerHandle,
+ mojo::PendingAssociatedRemote<mojom::blink::ProgressClient>,
+ RegisterFromStreamCallback) override {
+ NOTREACHED();
+ }
+
+ void GetBlobFromUUID(mojo::PendingReceiver<mojom::blink::Blob>,
+ const String& uuid,
+ GetBlobFromUUIDCallback) override {
+ NOTREACHED();
+ }
+
+ void URLStoreForOrigin(
+ const scoped_refptr<const SecurityOrigin>&,
+ mojo::PendingAssociatedReceiver<mojom::blink::BlobURLStore>) override {
+ NOTREACHED();
+ }
+};
- // WebLocalFrameClient:
- void SaveImageFromDataURL(const WebString& data_url) override {
- data_url_ = data_url;
+// blink::mojom::LocalFrameHost instance that intecepts DownloadURL() mojo
+// calls and reads the blob data URL sent by the renderer accordingly.
+class TestLocalFrameHostForSaveImageFromDataURL : public FakeLocalFrameHost {
+ public:
+ TestLocalFrameHostForSaveImageFromDataURL()
+ : blob_registry_receiver_(
+ &blob_registry_,
+ blob_registry_remote_.BindNewPipeAndPassReceiver()) {
+ BlobDataHandle::SetBlobRegistryForTesting(blob_registry_remote_.get());
+ }
+ ~TestLocalFrameHostForSaveImageFromDataURL() override {
+ BlobDataHandle::SetBlobRegistryForTesting(nullptr);
}
- // Local methods
- const WebString& Result() const { return data_url_; }
- void Reset() { data_url_ = WebString(); }
+ // 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::ScopedDataPipeProducerHandle producer_handle;
+ mojo::ScopedDataPipeConsumerHandle consumer_handle;
+ auto result =
+ mojo::CreateDataPipe(nullptr, &producer_handle, &consumer_handle);
+ DCHECK(result == MOJO_RESULT_OK);
+
+ blob->ReadAll(std::move(producer_handle), mojo::NullRemote());
+
+ DataPipeDrainerClient client(&data_url_);
+ auto data_pipe_drainer = std::make_unique<mojo::DataPipeDrainer>(
+ &client, std::move(consumer_handle));
+ client.Run();
+ }
+
+ const String& Result() const { return data_url_; }
+ void Reset() { data_url_ = String(); }
private:
- WebString data_url_;
+ // Helper class to copy a blob to a string.
+ class DataPipeDrainerClient : public mojo::DataPipeDrainer::Client {
+ public:
+ explicit DataPipeDrainerClient(String* output)
+ : run_loop_(base::RunLoop::Type::kNestableTasksAllowed),
+ output_(output) {}
+ void Run() { run_loop_.Run(); }
+
+ void OnDataAvailable(const void* data, size_t num_bytes) override {
+ *output_ = String(reinterpret_cast<const char*>(data), num_bytes);
+ }
+ void OnDataComplete() override { run_loop_.Quit(); }
+
+ private:
+ base::RunLoop run_loop_;
+ String* output_;
+ };
+
+ BlobRegistryForSaveImageFromDataURL blob_registry_;
+ mojo::Remote<mojom::blink::BlobRegistry> blob_registry_remote_;
+ mojo::Receiver<mojom::blink::BlobRegistry> blob_registry_receiver_;
+
+ // Data URL retrieved from the blob.
+ String data_url_;
};
TEST_F(WebFrameTest, SaveImageAt) {
@@ -10878,37 +11015,50 @@ TEST_F(WebFrameTest, SaveImageAt) {
url_test_helpers::RegisterMockedURLLoad(
ToKURL("http://test"), test::CoreTestDataPath("white-1x1.png"));
- frame_test_helpers::WebViewHelper helper;
- SaveImageFromDataURLWebFrameClient client;
- WebViewImpl* web_view = helper.InitializeAndLoad(url, &client);
+ TestLocalFrameHostForSaveImageFromDataURL frame_host;
+ frame_test_helpers::TestWebFrameClient web_frame_client;
+ frame_host.Init(web_frame_client.GetRemoteNavigationAssociatedInterfaces());
+ frame_test_helpers::WebViewHelper web_view_helper;
+ RunPendingTasks();
+
+ WebViewImpl* web_view =
+ web_view_helper.InitializeAndLoad(url, &web_frame_client);
web_view->MainFrameWidget()->Resize(WebSize(400, 400));
UpdateAllLifecyclePhases(web_view);
- WebLocalFrame* local_frame = web_view->MainFrameImpl();
+ LocalFrame* local_frame = To<LocalFrame>(web_view->GetPage()->MainFrame());
+
+ frame_host.Reset();
+ local_frame->SaveImageAt(gfx::Point(1, 1));
+ // Note that in this test does not use RunPendingTasks() since
+ // TestLocalFrameHostForSaveImageFromDataURL trigger its own loops, so nesting
+ // must be allowed.
+ base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
- client.Reset();
- local_frame->SaveImageAt(WebPoint(1, 1));
EXPECT_EQ(
- WebString::FromUTF8("data:image/gif;base64"
- ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="),
- client.Result());
+ String::FromUTF8("data:image/gif;base64"
+ ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="),
+ frame_host.Result());
- client.Reset();
- local_frame->SaveImageAt(WebPoint(1, 2));
- EXPECT_EQ(WebString(), client.Result());
+ frame_host.Reset();
+
+ local_frame->SaveImageAt(gfx::Point(1, 2));
+ base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
+ EXPECT_EQ(String(), frame_host.Result());
web_view->SetPageScaleFactor(4);
- web_view->SetVisualViewportOffset(WebFloatPoint(1, 1));
+ web_view->SetVisualViewportOffset(gfx::PointF(1, 1));
- client.Reset();
- local_frame->SaveImageAt(WebPoint(3, 3));
+ frame_host.Reset();
+ local_frame->SaveImageAt(gfx::Point(3, 3));
+ base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
EXPECT_EQ(
- WebString::FromUTF8("data:image/gif;base64"
- ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="),
- client.Result());
+ String::FromUTF8("data:image/gif;base64"
+ ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="),
+ frame_host.Result());
// Explicitly reset to break dependency on locally scoped client.
- helper.Reset();
+ web_view_helper.Reset();
}
TEST_F(WebFrameTest, SaveImageWithImageMap) {
@@ -10917,65 +11067,76 @@ TEST_F(WebFrameTest, SaveImageWithImageMap) {
// via the WebViewHelper instance in each test case.
RegisterMockedURLLoadFromBase(base_url_, "image-map.html");
+ TestLocalFrameHostForSaveImageFromDataURL frame_host;
frame_test_helpers::WebViewHelper helper;
- SaveImageFromDataURLWebFrameClient client;
+ frame_test_helpers::TestWebFrameClient client;
+ frame_host.Init(client.GetRemoteNavigationAssociatedInterfaces());
WebViewImpl* web_view = helper.InitializeAndLoad(url, &client);
web_view->MainFrameWidget()->Resize(WebSize(400, 400));
+ RunPendingTasks();
- WebLocalFrame* local_frame = web_view->MainFrameImpl();
+ LocalFrame* local_frame = To<LocalFrame>(web_view->GetPage()->MainFrame());
- client.Reset();
- local_frame->SaveImageAt(WebPoint(25, 25));
+ frame_host.Reset();
+ local_frame->SaveImageAt(gfx::Point(25, 25));
+ base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
EXPECT_EQ(
- WebString::FromUTF8("data:image/gif;base64"
- ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="),
- client.Result());
+ String::FromUTF8("data:image/gif;base64"
+ ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="),
+ frame_host.Result());
- client.Reset();
- local_frame->SaveImageAt(WebPoint(75, 25));
+ frame_host.Reset();
+ local_frame->SaveImageAt(gfx::Point(75, 25));
+ base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
EXPECT_EQ(
- WebString::FromUTF8("data:image/gif;base64"
- ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="),
- client.Result());
+ String::FromUTF8("data:image/gif;base64"
+ ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="),
+ frame_host.Result());
- client.Reset();
- local_frame->SaveImageAt(WebPoint(125, 25));
- EXPECT_EQ(WebString(), client.Result());
+ frame_host.Reset();
+ local_frame->SaveImageAt(gfx::Point(125, 25));
+ base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
+ EXPECT_EQ(String(), frame_host.Result());
// Explicitly reset to break dependency on locally scoped client.
helper.Reset();
}
TEST_F(WebFrameTest, CopyImageWithImageMap) {
- SaveImageFromDataURLWebFrameClient client;
-
std::string url = base_url_ + "image-map.html";
// TODO(crbug.com/751425): We should use the mock functionality
// via the WebViewHelper instance in each test case.
RegisterMockedURLLoadFromBase(base_url_, "image-map.html");
+ TestLocalFrameHostForSaveImageFromDataURL frame_host;
frame_test_helpers::WebViewHelper helper;
+ frame_test_helpers::TestWebFrameClient client;
+ frame_host.Init(client.GetRemoteNavigationAssociatedInterfaces());
WebViewImpl* web_view = helper.InitializeAndLoad(url, &client);
web_view->MainFrameWidget()->Resize(WebSize(400, 400));
+ RunPendingTasks();
- client.Reset();
- WebLocalFrame* local_frame = web_view->MainFrameImpl();
- local_frame->SaveImageAt(WebPoint(25, 25));
+ frame_host.Reset();
+ LocalFrame* local_frame = To<LocalFrame>(web_view->GetPage()->MainFrame());
+ local_frame->SaveImageAt(gfx::Point(25, 25));
+ base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
EXPECT_EQ(
- WebString::FromUTF8("data:image/gif;base64"
- ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="),
- client.Result());
+ String::FromUTF8("data:image/gif;base64"
+ ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="),
+ frame_host.Result());
- client.Reset();
- local_frame->SaveImageAt(WebPoint(75, 25));
+ frame_host.Reset();
+ local_frame->SaveImageAt(gfx::Point(75, 25));
+ base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
EXPECT_EQ(
- WebString::FromUTF8("data:image/gif;base64"
- ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="),
- client.Result());
-
- client.Reset();
- local_frame->SaveImageAt(WebPoint(125, 25));
- EXPECT_EQ(WebString(), client.Result());
+ String::FromUTF8("data:image/gif;base64"
+ ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="),
+ frame_host.Result());
+
+ frame_host.Reset();
+ local_frame->SaveImageAt(gfx::Point(125, 25));
+ base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
+ EXPECT_EQ(String(), frame_host.Result());
// Explicitly reset to break dependency on locally scoped client.
helper.Reset();
}
@@ -11147,9 +11308,9 @@ TEST_F(WebFrameTest, ImageDocumentDecodeError) {
Document* document =
To<LocalFrame>(helper.GetWebView()->GetPage()->MainFrame())
->GetDocument();
- EXPECT_TRUE(document->IsImageDocument());
+ EXPECT_TRUE(IsA<ImageDocument>(document));
EXPECT_EQ(ResourceStatus::kDecodeError,
- ToImageDocument(document)->CachedImage()->GetContentStatus());
+ To<ImageDocument>(document)->CachedImage()->GetContentStatus());
}
// Ensure that the root layer -- whose size is ordinarily derived from the
@@ -11296,8 +11457,8 @@ TEST_F(WebFrameTest, MouseOverDifferntNodeClearsTooltip) {
// Mouse over link. Mouse cursor should be hand.
WebMouseEvent mouse_move_over_link_event(
WebInputEvent::kMouseMove,
- WebFloatPoint(div1_tag->OffsetLeft() + 5, div1_tag->OffsetTop() + 5),
- WebFloatPoint(div1_tag->OffsetLeft() + 5, div1_tag->OffsetTop() + 5),
+ gfx::PointF(div1_tag->OffsetLeft() + 5, div1_tag->OffsetTop() + 5),
+ gfx::PointF(div1_tag->OffsetLeft() + 5, div1_tag->OffsetTop() + 5),
WebPointerProperties::Button::kNoButton, 0, WebInputEvent::kNoModifiers,
base::TimeTicks::Now());
mouse_move_over_link_event.SetFrameScale(1);
@@ -11316,8 +11477,8 @@ TEST_F(WebFrameTest, MouseOverDifferntNodeClearsTooltip) {
WebMouseEvent mouse_move_event(
WebInputEvent::kMouseMove,
- WebFloatPoint(div2_tag->OffsetLeft() + 5, div2_tag->OffsetTop() + 5),
- WebFloatPoint(div2_tag->OffsetLeft() + 5, div2_tag->OffsetTop() + 5),
+ gfx::PointF(div2_tag->OffsetLeft() + 5, div2_tag->OffsetTop() + 5),
+ gfx::PointF(div2_tag->OffsetLeft() + 5, div2_tag->OffsetTop() + 5),
WebPointerProperties::Button::kNoButton, 0, WebInputEvent::kNoModifiers,
base::TimeTicks::Now());
mouse_move_event.SetFrameScale(1);
@@ -11383,8 +11544,8 @@ TEST_F(WebFrameSimTest, HitTestWithIgnoreClippingAtNegativeOffset) {
auto* frame_view = To<LocalFrame>(WebView().GetPage()->MainFrame())->View();
- frame_view->GetScrollableArea()->SetScrollOffset(ScrollOffset(0, 600),
- kProgrammaticScroll);
+ frame_view->GetScrollableArea()->SetScrollOffset(
+ ScrollOffset(0, 600), mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
HitTestRequest request = HitTestRequest::kMove | HitTestRequest::kReadOnly |
@@ -11426,8 +11587,8 @@ TEST_F(WebFrameSimTest, TickmarksDocumentRelative) {
auto* frame = To<WebLocalFrameImpl>(WebView().MainFrame());
auto* frame_view = To<LocalFrame>(WebView().GetPage()->MainFrame())->View();
- frame_view->GetScrollableArea()->SetScrollOffset(ScrollOffset(3000, 1000),
- kProgrammaticScroll);
+ frame_view->GetScrollableArea()->SetScrollOffset(
+ ScrollOffset(3000, 1000), mojom::blink::ScrollType::kProgrammatic);
auto options = mojom::blink::FindOptions::New();
options->run_synchronously_for_testing = true;
WebString search_text = WebString::FromUTF8("test");
@@ -11489,8 +11650,8 @@ TEST_F(WebFrameSimTest, FindInPageSelectNextMatch) {
IntRect box1_rect = box1->GetLayoutObject()->AbsoluteBoundingBoxRect();
IntRect box2_rect = box2->GetLayoutObject()->AbsoluteBoundingBoxRect();
- frame_view->GetScrollableArea()->SetScrollOffset(ScrollOffset(3000, 1000),
- kProgrammaticScroll);
+ frame_view->GetScrollableArea()->SetScrollOffset(
+ ScrollOffset(3000, 1000), mojom::blink::ScrollType::kProgrammatic);
auto options = mojom::blink::FindOptions::New();
options->run_synchronously_for_testing = true;
WebString search_text = WebString::FromUTF8("test");
@@ -11502,7 +11663,7 @@ TEST_F(WebFrameSimTest, FindInPageSelectNextMatch) {
frame->EnsureTextFinder().StartScopingStringMatches(kFindIdentifier,
search_text, *options);
- WebVector<WebFloatRect> web_match_rects =
+ WebVector<gfx::RectF> web_match_rects =
frame->EnsureTextFinder().FindMatchRects();
ASSERT_EQ(2ul, web_match_rects.size());
@@ -11628,8 +11789,8 @@ TEST_F(WebFrameSimTest, TestScrollFocusedEditableElementIntoView) {
LocalFrameView* frame_view = frame->View();
IntRect inputRect(200, 600, 100, 20);
- frame_view->GetScrollableArea()->SetScrollOffset(ScrollOffset(0, 0),
- kProgrammaticScroll);
+ frame_view->GetScrollableArea()->SetScrollOffset(
+ ScrollOffset(0, 0), mojom::blink::ScrollType::kProgrammatic);
ASSERT_EQ(FloatPoint(),
frame_view->GetScrollableArea()->VisibleContentRect().Location());
@@ -11644,7 +11805,7 @@ TEST_F(WebFrameSimTest, TestScrollFocusedEditableElementIntoView) {
frame_view->LayoutViewport()->SetScrollOffset(
ToFloatSize(FloatPoint(
WebView().FakePageScaleAnimationTargetPositionForTesting())),
- kProgrammaticScroll);
+ mojom::blink::ScrollType::kProgrammatic);
EXPECT_TRUE(frame_view->GetScrollableArea()->VisibleContentRect().Contains(
inputRect));
@@ -11675,7 +11836,7 @@ TEST_F(WebFrameSimTest, TestScrollFocusedEditableElementIntoView) {
frame_view->GetScrollableArea()->SetScrollOffset(
ToFloatSize(FloatPoint(
WebView().FakePageScaleAnimationTargetPositionForTesting())),
- kProgrammaticScroll);
+ mojom::blink::ScrollType::kProgrammatic);
EXPECT_TRUE(frame_view->GetScrollableArea()->VisibleContentRect().Contains(
inputRect));
@@ -11739,8 +11900,8 @@ TEST_F(WebFrameSimTest, TestScrollFocusedEditableInRootScroller) {
WebView().AdvanceFocus(false);
- rs_controller.RootScrollerArea()->SetScrollOffset(ScrollOffset(0, 300),
- kProgrammaticScroll);
+ rs_controller.RootScrollerArea()->SetScrollOffset(
+ ScrollOffset(0, 300), mojom::blink::ScrollType::kProgrammatic);
LocalFrameView* frame_view = frame->View();
IntRect inputRect(200, 700, 100, 20);
@@ -11760,8 +11921,8 @@ TEST_F(WebFrameSimTest, TestScrollFocusedEditableInRootScroller) {
ScrollOffset target_offset = ToFloatSize(
FloatPoint(WebView().FakePageScaleAnimationTargetPositionForTesting()));
- rs_controller.RootScrollerArea()->SetScrollOffset(target_offset,
- kProgrammaticScroll);
+ rs_controller.RootScrollerArea()->SetScrollOffset(
+ target_offset, mojom::blink::ScrollType::kProgrammatic);
EXPECT_TRUE(frame_view->GetScrollableArea()->VisibleContentRect().Contains(
inputRect));
@@ -11962,7 +12123,8 @@ TEST_F(WebFrameSimTest, DoubleTapZoomWhileScrolled) {
// Center the target in the screen.
frame_view->GetScrollableArea()->SetScrollOffset(
- ScrollOffset(2000 - 440, 3000 - 450), kProgrammaticScroll);
+ ScrollOffset(2000 - 440, 3000 - 450),
+ mojom::blink::ScrollType::kProgrammatic);
Element* target = GetDocument().QuerySelector("#target");
DOMRect* rect = target->getBoundingClientRect();
ASSERT_EQ(440, rect->left());
@@ -11979,8 +12141,8 @@ TEST_F(WebFrameSimTest, DoubleTapZoomWhileScrolled) {
FloatPoint(WebView().FakePageScaleAnimationTargetPositionForTesting()));
float new_scale = WebView().FakePageScaleAnimationPageScaleForTesting();
visual_viewport.SetScale(new_scale);
- frame_view->GetScrollableArea()->SetScrollOffset(new_offset,
- kProgrammaticScroll);
+ frame_view->GetScrollableArea()->SetScrollOffset(
+ new_offset, mojom::blink::ScrollType::kProgrammatic);
EXPECT_FLOAT_EQ(1, visual_viewport.Scale());
EXPECT_TRUE(frame_view->GetScrollableArea()->VisibleContentRect().Contains(
@@ -12058,7 +12220,8 @@ TEST_F(WebFrameSimTest, ScrollFocusedEditableIntoViewNoLayoutObject) {
input->focus();
ScrollableArea* area = GetDocument().View()->LayoutViewport();
- area->SetScrollOffset(ScrollOffset(0, 0), kProgrammaticScroll);
+ area->SetScrollOffset(ScrollOffset(0, 0),
+ mojom::blink::ScrollType::kProgrammatic);
ASSERT_TRUE(input->GetLayoutObject());
ASSERT_EQ(input, WebView().FocusedElement());
@@ -12205,7 +12368,7 @@ TEST_F(WebFrameSimTest, LayoutViewportExceedsLayoutOverflow) {
WebView().ResizeWithBrowserControls(WebSize(400, 600), 60, 0, false);
Compositor().BeginFrame();
- // ContentsSize() should grow to accomodate new visible size.
+ // ContentsSize() should grow to accommodate new visible size.
ASSERT_EQ(600, area->VisibleHeight());
ASSERT_EQ(IntSize(400, 600), area->ContentsSize());
}
@@ -12275,10 +12438,6 @@ TEST_F(WebFrameTest, NoLoadingCompletionCallbacksInDetach) {
EXPECT_TRUE(false) << "didFinishLoad() should not have been called.";
}
- void DispatchLoad() override {
- EXPECT_TRUE(false) << "dispatchLoad() should not have been called.";
- }
-
bool DidCallFrameDetached() const { return did_call_frame_detached_; }
bool DidCallDidStopLoading() const { return did_call_did_stop_loading_; }
bool DidCallDidFinishDocumentLoad() const {
@@ -12416,7 +12575,7 @@ bool TestSelectAll(const std::string& html) {
ToKURL("about:blank"));
web_view->MainFrameWidget()->Resize(WebSize(500, 300));
web_view->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
RunPendingTasks();
web_view->SetInitialFocus(false);
RunPendingTasks();
@@ -12710,68 +12869,6 @@ TEST_F(WebFrameTest, RecordSameDocumentNavigationToHistogram) {
tester.ExpectTotalCount(histogramName, 3);
}
-TEST_F(WebFrameTest, DidScrollCallbackAfterScrollableAreaChanges) {
- frame_test_helpers::WebViewHelper web_view_helper;
- web_view_helper.Initialize();
- web_view_helper.Resize(WebSize(200, 200));
- WebViewImpl* web_view = web_view_helper.GetWebView();
-
- InitializeWithHTML(*web_view->MainFrameImpl()->GetFrame(),
- "<style>"
- " #scrollable {"
- " height: 100px;"
- " width: 100px;"
- " overflow: scroll;"
- " will-change: transform;"
- " }"
- " #forceScroll { height: 120px; width: 50px; }"
- "</style>"
- "<div id='scrollable'>"
- " <div id='forceScroll'></div>"
- "</div>");
-
- UpdateAllLifecyclePhases(web_view);
-
- Document* document = web_view->MainFrameImpl()->GetFrame()->GetDocument();
- Element* scrollable = document->getElementById("scrollable");
-
- auto* scrollable_area =
- ToLayoutBox(scrollable->GetLayoutObject())->GetScrollableArea();
- EXPECT_NE(nullptr, scrollable_area);
-
- // We should have a composited layer for scrolling due to will-change.
- cc::Layer* cc_scroll_layer = scrollable_area->LayerForScrolling();
- EXPECT_NE(nullptr, cc_scroll_layer);
-
- // Ensure a synthetic impl-side scroll offset propagates to the scrollable
- // area using the DidScroll callback.
- EXPECT_EQ(ScrollOffset(), scrollable_area->GetScrollOffset());
- cc::ScrollAndScaleSet scroll_and_scale_set;
- scroll_and_scale_set.scrolls.push_back({scrollable_area->GetScrollElementId(),
- gfx::ScrollOffset(0, 1),
- base::nullopt});
- cc_scroll_layer->layer_tree_host()->ApplyScrollAndScale(
- &scroll_and_scale_set);
- UpdateAllLifecyclePhases(web_view);
- EXPECT_EQ(ScrollOffset(0, 1), scrollable_area->GetScrollOffset());
-
- // Make the scrollable area non-scrollable.
- scrollable->setAttribute(html_names::kStyleAttr, "overflow: visible");
-
- // Update layout without updating compositing state.
- WebLocalFrame* frame = web_view_helper.LocalMainFrame();
- frame->ExecuteScript(
- WebScriptSource("var forceLayoutFromScript = scrollable.offsetTop;"));
- EXPECT_EQ(document->Lifecycle().GetState(), DocumentLifecycle::kLayoutClean);
-
- EXPECT_EQ(nullptr,
- ToLayoutBox(scrollable->GetLayoutObject())->GetScrollableArea());
-
- // The web scroll layer has not been deleted yet and we should be able to
- // apply impl-side offsets without crashing.
- cc_scroll_layer->SetScrollOffsetFromImplSide(gfx::ScrollOffset(0, 3));
-}
-
static void TestFramePrinting(WebLocalFrameImpl* frame) {
WebPrintParams print_params;
WebSize page_size(500, 500);
@@ -12804,11 +12901,15 @@ TEST_F(WebFrameTest, ExecuteCommandProducesUserGesture) {
web_view_helper.InitializeAndLoad("about:blank");
WebLocalFrameImpl* frame = web_view_helper.LocalMainFrame();
- EXPECT_FALSE(frame->GetFrame()->HasBeenActivated());
+ // Setup a mock clipboard host.
+ PageTestBase::MockClipboardHostProvider mock_clipboard_host_provider(
+ frame->GetFrame()->GetBrowserInterfaceBroker());
+
+ EXPECT_FALSE(frame->GetFrame()->HasStickyUserActivation());
frame->ExecuteScript(WebScriptSource(WebString("document.execCommand('copy');")));
- EXPECT_FALSE(frame->GetFrame()->HasBeenActivated());
+ EXPECT_FALSE(frame->GetFrame()->HasStickyUserActivation());
frame->ExecuteCommand(WebString::FromUTF8("Paste"));
- EXPECT_TRUE(frame->GetFrame()->HasBeenActivated());
+ EXPECT_TRUE(frame->GetFrame()->HasStickyUserActivation());
}
TEST_F(WebFrameTest, GetCanonicalUrlForSharingNone) {
@@ -12895,12 +12996,12 @@ TEST_F(WebFrameSimTest, EnterFullscreenResetScrollAndScaleState) {
EXPECT_EQ(0.5f, WebView().PageScaleFactor());
WebView().SetPageScaleFactor(2.0f);
WebView().MainFrameImpl()->SetScrollOffset(WebSize(94, 111));
- WebView().SetVisualViewportOffset(WebFloatPoint(12, 20));
+ WebView().SetVisualViewportOffset(gfx::PointF(12, 20));
EXPECT_EQ(2.0f, WebView().PageScaleFactor());
EXPECT_EQ(94, WebView().MainFrameImpl()->GetScrollOffset().width);
EXPECT_EQ(111, WebView().MainFrameImpl()->GetScrollOffset().height);
- EXPECT_EQ(12, WebView().VisualViewportOffset().x);
- EXPECT_EQ(20, WebView().VisualViewportOffset().y);
+ EXPECT_EQ(12, WebView().VisualViewportOffset().x());
+ EXPECT_EQ(20, WebView().VisualViewportOffset().y());
auto* frame = To<LocalFrame>(WebView().GetPage()->MainFrame());
Element* element = frame->GetDocument()->body();
@@ -12915,13 +13016,59 @@ TEST_F(WebFrameSimTest, EnterFullscreenResetScrollAndScaleState) {
// Confirm that exiting fullscreen restores back to default values.
WebView().MainFrameWidget()->DidExitFullscreen();
WebView().MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
EXPECT_EQ(0.5f, WebView().PageScaleFactor());
EXPECT_EQ(94, WebView().MainFrameImpl()->GetScrollOffset().width);
EXPECT_EQ(111, WebView().MainFrameImpl()->GetScrollOffset().height);
- EXPECT_EQ(0, WebView().VisualViewportOffset().x);
- EXPECT_EQ(0, WebView().VisualViewportOffset().y);
+ EXPECT_EQ(0, WebView().VisualViewportOffset().x());
+ EXPECT_EQ(0, WebView().VisualViewportOffset().y());
+}
+
+TEST_F(WebFrameSimTest, GetPageSizeType) {
+ WebView().MainFrameWidget()->Resize(WebSize(500, 500));
+
+ SimRequest request("https://example.com/test.html", "text/html");
+ LoadURL("https://example.com/test.html");
+ request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ @page {}
+ </style>
+ )HTML");
+
+ Compositor().BeginFrame();
+ RunPendingTasks();
+
+ const struct {
+ const char* size;
+ PageSizeType page_size_type;
+ } test_cases[] = {
+ {"auto", PageSizeType::kAuto},
+ {"portrait", PageSizeType::kPortrait},
+ {"landscape", PageSizeType::kLandscape},
+ {"a4", PageSizeType::kFixed},
+ {"letter", PageSizeType::kFixed},
+ {"a4 portrait", PageSizeType::kFixed},
+ {"letter landscape", PageSizeType::kFixed},
+ {"10in", PageSizeType::kFixed},
+ {"10in 12cm", PageSizeType::kFixed},
+ };
+
+ auto* main_frame = WebView().MainFrame()->ToWebLocalFrame();
+ auto* doc = To<LocalFrame>(WebView().GetPage()->MainFrame())->GetDocument();
+ auto* sheet = To<CSSStyleSheet>(doc->StyleSheets().item(0));
+ CSSStyleDeclaration* style_decl =
+ To<CSSPageRule>(sheet->cssRules(ASSERT_NO_EXCEPTION)->item(0))->style();
+
+ // Initially empty @page rule.
+ EXPECT_EQ(PageSizeType::kAuto, main_frame->GetPageSizeType(1));
+
+ for (const auto& test : test_cases) {
+ style_decl->setProperty(doc->ToExecutionContext(), "size", test.size, "",
+ ASSERT_NO_EXCEPTION);
+ EXPECT_EQ(test.page_size_type, main_frame->GetPageSizeType(1));
+ }
}
TEST_F(WebFrameTest, MediaQueriesInLocalFrameInsideRemote) {
@@ -12947,7 +13094,7 @@ TEST_F(WebFrameTest, MediaQueriesInLocalFrameInsideRemote) {
helper.Reset();
}
-TEST_F(WebFrameTest, RemoteViewportIntersection) {
+TEST_F(WebFrameTest, RemoteViewportAndMainframeIntersections) {
frame_test_helpers::WebViewHelper helper;
helper.InitializeRemote();
WebLocalFrameImpl* local_frame = frame_test_helpers::CreateLocalChild(
@@ -12974,32 +13121,149 @@ TEST_F(WebFrameTest, RemoteViewportIntersection) {
// Simulate the local child frame being positioned at (7, -11) in the parent's
// viewport, indicating that the top 11px of the child's content is clipped
- // by the parent.
+ // by the parent. Let the local child frame be at (7, 40) in the parent
+ // element.
WebFrameWidget* widget = local_frame->FrameWidget();
ASSERT_TRUE(widget);
- WebPoint viewport_offset(7, -11);
+ gfx::Point viewport_offset(7, -11);
WebRect viewport_intersection(0, 11, 200, 89);
+ // TODO(https://crbug/1084786): Mainframe document intersections need to be
+ // transformed into the coordinate system of the main frame from the child
+ // frame's.
+ WebRect mainframe_intersection(0, 0, 200, 140);
FrameOcclusionState occlusion_state = FrameOcclusionState::kUnknown;
- widget->SetRemoteViewportIntersection({viewport_offset, viewport_intersection,
- viewport_intersection,
- occlusion_state});
+ widget->SetRemoteViewportIntersection(
+ {viewport_offset, viewport_intersection, mainframe_intersection,
+ viewport_intersection, occlusion_state});
// The viewport intersection should be applied by the layout geometry mapping
// code when these flags are used.
- int flags = kTraverseDocumentBoundaries | kApplyRemoteRootFrameOffset;
+ int viewport_intersection_flags =
+ kTraverseDocumentBoundaries | kApplyRemoteRootFrameOffset;
// Expectation is: (target location) + (viewport offset) = (20, 10) + (7, -11)
- PhysicalOffset offset =
- target->GetLayoutObject()->LocalToAbsolutePoint(PhysicalOffset(), flags);
+ PhysicalOffset offset = target->GetLayoutObject()->LocalToAbsolutePoint(
+ PhysicalOffset(), viewport_intersection_flags);
EXPECT_EQ(PhysicalOffset(27, -1), offset);
PhysicalRect rect(0, 0, 25, 35);
local_frame->GetFrame()
->GetDocument()
->GetLayoutView()
- ->MapToVisualRectInAncestorSpace(nullptr, rect, flags,
- kDefaultVisualRectFlags);
+ ->MapToVisualRectInAncestorSpace(
+ nullptr, rect, viewport_intersection_flags, kDefaultVisualRectFlags);
EXPECT_EQ(PhysicalRect(7, 0, 25, 24), rect);
+
+ // Without the main frame overflow clip the rect should not be clipped and the
+ // coordinates returned are the rects coordinates in the viewport space.
+ PhysicalRect mainframe_rect(0, 0, 25, 35);
+ local_frame->GetFrame()
+ ->GetDocument()
+ ->GetLayoutView()
+ ->MapToVisualRectInAncestorSpace(nullptr, mainframe_rect,
+ viewport_intersection_flags,
+ kDontApplyMainFrameOverflowClip);
+ EXPECT_EQ(PhysicalRect(7, -11, 25, 35), mainframe_rect);
+}
+
+class TestUpdateFaviconURLLocalFrameHost : public FakeLocalFrameHost {
+ public:
+ TestUpdateFaviconURLLocalFrameHost() = default;
+ ~TestUpdateFaviconURLLocalFrameHost() override = default;
+
+ // FakeLocalFrameHost:
+ void UpdateFaviconURL(
+ WTF::Vector<blink::mojom::blink::FaviconURLPtr> favicon_urls) override {
+ did_notify_ = true;
+ }
+
+ bool did_notify_ = false;
+};
+
+// Ensure the render view sends favicon url update events correctly.
+TEST_F(WebFrameTest, FaviconURLUpdateEvent) {
+ TestUpdateFaviconURLLocalFrameHost frame_host;
+ frame_test_helpers::TestWebFrameClient web_frame_client;
+ frame_host.Init(web_frame_client.GetRemoteNavigationAssociatedInterfaces());
+ frame_test_helpers::WebViewHelper web_view_helper;
+ web_view_helper.Initialize(&web_frame_client);
+ RunPendingTasks();
+
+ WebViewImpl* web_view = web_view_helper.GetWebView();
+ LocalFrame* frame = web_view->MainFrameImpl()->GetFrame();
+
+ // An event should be sent when a favicon url exists.
+ frame->GetDocument()->documentElement()->setInnerHTML(
+ "<html>"
+ "<head>"
+ "<link rel='icon' href='http://www.google.com/favicon.ico'>"
+ "</head>"
+ "</html>");
+ RunPendingTasks();
+
+ EXPECT_TRUE(frame_host.did_notify_);
+
+ frame_host.did_notify_ = false;
+
+ // An event should not be sent if no favicon url exists. This is an assumption
+ // made by some of Chrome's favicon handling.
+ frame->GetDocument()->documentElement()->setInnerHTML(
+ "<html>"
+ "<head>"
+ "</head>"
+ "</html>");
+ RunPendingTasks();
+
+ EXPECT_FALSE(frame_host.did_notify_);
+ web_view_helper.Reset();
+}
+
+class TestFocusedElementChangedLocalFrameHost : public FakeLocalFrameHost {
+ public:
+ TestFocusedElementChangedLocalFrameHost() = default;
+ ~TestFocusedElementChangedLocalFrameHost() override = default;
+
+ // FakeLocalFrameHost:
+ void FocusedElementChanged(bool is_editable_element,
+ const gfx::Rect& bounds_in_frame_widget) override {
+ did_notify_ = true;
+ }
+
+ bool did_notify_ = false;
+};
+
+TEST_F(WebFrameTest, FocusElementCallsFocusedElementChanged) {
+ TestFocusedElementChangedLocalFrameHost frame_host;
+ frame_test_helpers::TestWebFrameClient web_frame_client;
+ frame_host.Init(web_frame_client.GetRemoteNavigationAssociatedInterfaces());
+ frame_test_helpers::WebViewHelper web_view_helper;
+ web_view_helper.Initialize(&web_frame_client);
+ RunPendingTasks();
+ auto* main_frame = web_view_helper.GetWebView()->MainFrameImpl();
+
+ main_frame->GetFrame()->GetDocument()->documentElement()->setInnerHTML(
+ "<input id='test1' value='hello1'></input>"
+ "<input id='test2' value='hello2'></input>");
+ RunPendingTasks();
+
+ EXPECT_FALSE(frame_host.did_notify_);
+
+ main_frame->ExecuteScript(
+ WebScriptSource(WebString("document.getElementById('test1').focus();")));
+ RunPendingTasks();
+ EXPECT_TRUE(frame_host.did_notify_);
+ frame_host.did_notify_ = false;
+
+ main_frame->ExecuteScript(
+ WebScriptSource(WebString("document.getElementById('test2').focus();")));
+ RunPendingTasks();
+ EXPECT_TRUE(frame_host.did_notify_);
+ frame_host.did_notify_ = false;
+
+ main_frame->ExecuteScript(
+ WebScriptSource(WebString("document.getElementById('test2').blur();")));
+ RunPendingTasks();
+ EXPECT_TRUE(frame_host.did_notify_);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/exported/web_history_item.cc b/chromium/third_party/blink/renderer/core/exported/web_history_item.cc
index c47371bf074..f6c3cb349d2 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_history_item.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_history_item.cc
@@ -30,9 +30,7 @@
#include "third_party/blink/public/web/web_history_item.h"
-#include "third_party/blink/public/platform/web_float_point.h"
#include "third_party/blink/public/platform/web_http_body.h"
-#include "third_party/blink/public/platform/web_point.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/web_serialized_script_value.h"
@@ -41,6 +39,7 @@
#include "third_party/blink/renderer/platform/network/encoded_form_data.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
+#include "ui/gfx/geometry/point.h"
namespace blink {
@@ -88,30 +87,30 @@ void WebHistoryItem::SetTarget(const WebString& target) {
target_ = target;
}
-WebFloatPoint WebHistoryItem::VisualViewportScrollOffset() const {
+gfx::PointF WebHistoryItem::VisualViewportScrollOffset() const {
const auto& scroll_and_view_state = private_->GetViewState();
ScrollOffset offset =
scroll_and_view_state
? scroll_and_view_state->visual_viewport_scroll_offset_
: ScrollOffset();
- return WebFloatPoint(offset.Width(), offset.Height());
+ return gfx::PointF(offset.Width(), offset.Height());
}
void WebHistoryItem::SetVisualViewportScrollOffset(
- const WebFloatPoint& scroll_offset) {
+ const gfx::PointF& scroll_offset) {
private_->SetVisualViewportScrollOffset(ToScrollOffset(scroll_offset));
}
-WebPoint WebHistoryItem::GetScrollOffset() const {
+gfx::Point WebHistoryItem::GetScrollOffset() const {
const auto& scroll_and_view_state = private_->GetViewState();
ScrollOffset offset = scroll_and_view_state
? scroll_and_view_state->scroll_offset_
: ScrollOffset();
- return WebPoint(offset.Width(), offset.Height());
+ return gfx::Point(offset.Width(), offset.Height());
}
-void WebHistoryItem::SetScrollOffset(const WebPoint& scroll_offset) {
- private_->SetScrollOffset(ScrollOffset(scroll_offset.x, scroll_offset.y));
+void WebHistoryItem::SetScrollOffset(const gfx::Point& scroll_offset) {
+ private_->SetScrollOffset(ScrollOffset(scroll_offset.x(), scroll_offset.y()));
}
float WebHistoryItem::PageScaleFactor() const {
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 6a61243bfaf..e10a1a25bc1 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
@@ -25,7 +25,6 @@
#include "third_party/blink/public/web/web_hit_test_result.h"
-#include "third_party/blink/public/platform/web_point.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/public/web/web_element.h"
#include "third_party/blink/public/web/web_node.h"
@@ -43,7 +42,7 @@ class WebHitTestResultPrivate final
WebHitTestResultPrivate(const HitTestResult&);
WebHitTestResultPrivate(const WebHitTestResultPrivate&);
- void Trace(blink::Visitor* visitor) { visitor->Trace(result_); }
+ void Trace(Visitor* visitor) { visitor->Trace(result_); }
const HitTestResult& Result() const { return result_; }
private:
@@ -62,11 +61,11 @@ WebNode WebHitTestResult::GetNode() const {
return WebNode(private_->Result().InnerNode());
}
-WebPoint WebHitTestResult::LocalPoint() const {
+gfx::Point WebHitTestResult::LocalPoint() const {
return RoundedIntPoint(private_->Result().LocalPoint());
}
-WebPoint WebHitTestResult::LocalPointWithoutContentBoxOffset() const {
+gfx::Point WebHitTestResult::LocalPointWithoutContentBoxOffset() const {
IntPoint local_point = RoundedIntPoint(private_->Result().LocalPoint());
LayoutObject* object = private_->Result().GetLayoutObject();
if (object->IsBox()) {
@@ -102,6 +101,10 @@ bool WebHitTestResult::IsContentEditable() const {
return private_->Result().IsContentEditable();
}
+uint64_t WebHitTestResult::GetScrollableContainerId() const {
+ return private_->Result().GetScrollableContainer().GetStableId();
+}
+
WebHitTestResult::WebHitTestResult(const HitTestResult& result)
: private_(MakeGarbageCollected<WebHitTestResultPrivate>(result)) {}
diff --git a/chromium/third_party/blink/renderer/core/exported/web_image.cc b/chromium/third_party/blink/renderer/core/exported/web_image.cc
index d616a8d9703..3b89ae23885 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_image.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_image.cc
@@ -114,7 +114,8 @@ WebVector<SkBitmap> WebImage::FramesFromData(const WebData& data) {
const bool data_complete = true;
std::unique_ptr<ImageDecoder> decoder(ImageDecoder::Create(
data, data_complete, ImageDecoder::kAlphaPremultiplied,
- ImageDecoder::kDefaultBitDepth, ColorBehavior::Ignore()));
+ ImageDecoder::kDefaultBitDepth, ColorBehavior::Ignore(),
+ ImageDecoder::OverrideAllowDecodeToYuv::kDeny));
if (!decoder || !decoder->IsSizeAvailable())
return {};
@@ -147,7 +148,8 @@ WebVector<WebImage::AnimationFrame> WebImage::AnimationFromData(
const bool data_complete = true;
std::unique_ptr<ImageDecoder> decoder(ImageDecoder::Create(
data, data_complete, ImageDecoder::kAlphaPremultiplied,
- ImageDecoder::kDefaultBitDepth, ColorBehavior::Ignore()));
+ ImageDecoder::kDefaultBitDepth, ColorBehavior::Ignore(),
+ ImageDecoder::OverrideAllowDecodeToYuv::kDeny));
if (!decoder || !decoder->IsSizeAvailable() || decoder->FrameCount() == 0)
return {};
diff --git a/chromium/third_party/blink/renderer/core/exported/web_image_test.cc b/chromium/third_party/blink/renderer/core/exported/web_image_test.cc
index 92e5e7cdfa3..7238cb70b25 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_image_test.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_image_test.cc
@@ -33,6 +33,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/web_data.h"
#include "third_party/blink/public/platform/web_size.h"
+#include "third_party/blink/renderer/core/testing/scoped_mock_overlay_scrollbars.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
@@ -44,7 +45,10 @@ static scoped_refptr<SharedBuffer> ReadFile(const char* file_name) {
return test::ReadFromFile(file_path);
}
-TEST(WebImageTest, PNGImage) {
+class WebImageTest : public testing::Test,
+ private ScopedMockOverlayScrollbars {};
+
+TEST_F(WebImageTest, PNGImage) {
scoped_refptr<SharedBuffer> data = ReadFile("white-1x1.png");
ASSERT_TRUE(data.get());
@@ -54,7 +58,7 @@ TEST(WebImageTest, PNGImage) {
EXPECT_EQ(SkColorSetARGB(255, 255, 255, 255), image.getColor(0, 0));
}
-TEST(WebImageTest, ICOImage) {
+TEST_F(WebImageTest, ICOImage) {
scoped_refptr<SharedBuffer> data = ReadFile("black-and-white.ico");
ASSERT_TRUE(data.get());
@@ -68,7 +72,7 @@ TEST(WebImageTest, ICOImage) {
EXPECT_EQ(SkColorSetARGB(255, 0, 0, 0), images[1].getColor(0, 0));
}
-TEST(WebImageTest, ICOValidHeaderMissingBitmap) {
+TEST_F(WebImageTest, ICOValidHeaderMissingBitmap) {
scoped_refptr<SharedBuffer> data =
ReadFile("valid_header_missing_bitmap.ico");
ASSERT_TRUE(data.get());
@@ -77,7 +81,7 @@ TEST(WebImageTest, ICOValidHeaderMissingBitmap) {
ASSERT_TRUE(images.empty());
}
-TEST(WebImageTest, BadImage) {
+TEST_F(WebImageTest, BadImage) {
const char kBadImage[] = "hello world";
WebVector<SkBitmap> images = WebImage::FramesFromData(WebData(kBadImage));
ASSERT_EQ(0u, images.size());
@@ -87,7 +91,7 @@ TEST(WebImageTest, BadImage) {
EXPECT_TRUE(image.isNull());
}
-TEST(WebImageTest, DecodeSVGDesiredSize) {
+TEST_F(WebImageTest, DecodeSVGDesiredSize) {
const char kImage[] =
"<svg xmlns='http://www.w3.org/2000/svg' width='32'"
" height='32'></svg>";
@@ -98,7 +102,7 @@ TEST(WebImageTest, DecodeSVGDesiredSize) {
EXPECT_EQ(image.height(), 16);
}
-TEST(WebImageTest, DecodeSVGDesiredSizeAspectRatioOnly) {
+TEST_F(WebImageTest, DecodeSVGDesiredSizeAspectRatioOnly) {
const char kImageAspectRatioOne[] =
"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'></svg>";
SkBitmap image =
@@ -118,7 +122,7 @@ TEST(WebImageTest, DecodeSVGDesiredSizeAspectRatioOnly) {
EXPECT_EQ(image.height(), 16);
}
-TEST(WebImageTest, DecodeSVGDesiredSizeEmpty) {
+TEST_F(WebImageTest, DecodeSVGDesiredSizeEmpty) {
const char kImage[] =
"<svg xmlns='http://www.w3.org/2000/svg' width='32'"
" height='32'></svg>";
@@ -129,7 +133,7 @@ TEST(WebImageTest, DecodeSVGDesiredSizeEmpty) {
EXPECT_EQ(image.height(), 32);
}
-TEST(WebImageTest, DecodeSVGInvalidImage) {
+TEST_F(WebImageTest, DecodeSVGInvalidImage) {
const char kBogusImage[] = "bogus";
SkBitmap image = WebImage::DecodeSVG(WebData(kBogusImage), WebSize(16, 16));
EXPECT_TRUE(image.empty());
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 018b09ba44b..93c945ace72 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(blink::Visitor* visitor) {
+void WebInputMethodControllerImpl::Trace(Visitor* visitor) {
visitor->Trace(web_frame_);
}
@@ -114,7 +114,7 @@ bool WebInputMethodControllerImpl::FinishComposingText(
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kInput);
return GetInputMethodController().FinishComposingText(
selection_behavior == WebInputMethodController::kKeepSelection
@@ -141,7 +141,7 @@ bool WebInputMethodControllerImpl::CommitText(
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kInput);
if (!replacement_range.IsNull()) {
return GetInputMethodController().ReplaceText(
@@ -174,12 +174,18 @@ WebTextInputType WebInputMethodControllerImpl::TextInputType() {
return GetFrame()->GetInputMethodController().TextInputType();
}
-void WebInputMethodControllerImpl::GetLayoutBounds(WebRect& control_bounds,
- WebRect& selection_bounds) {
+void WebInputMethodControllerImpl::GetLayoutBounds(WebRect* control_bounds,
+ WebRect* selection_bounds) {
+ GetInputMethodController().GetLayoutBounds(control_bounds, selection_bounds);
+}
+
+bool WebInputMethodControllerImpl::IsInputPanelPolicyManual() const {
if (IsEditContextActive()) {
- return GetInputMethodController().GetActiveEditContext()->GetLayoutBounds(
- control_bounds, selection_bounds);
+ return GetInputMethodController()
+ .GetActiveEditContext()
+ ->IsInputPanelPolicyManual();
}
+ return false; // Default should always be automatic.
}
WebRange WebInputMethodControllerImpl::CompositionRange() {
@@ -198,7 +204,7 @@ WebRange WebInputMethodControllerImpl::CompositionRange() {
Element* editable =
GetFrame()->Selection().RootEditableElementOrDocumentElement();
- editable->GetDocument().UpdateStyleAndLayout();
+ editable->GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kInput);
return PlainTextRange::Create(*editable, range);
}
@@ -237,7 +243,7 @@ WebRange WebInputMethodControllerImpl::GetSelectionOffsets() const {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kInput);
return GetFrame()->GetInputMethodController().GetSelectionOffsets();
}
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 422c24566a2..afb2d962e6d 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
@@ -49,11 +49,12 @@ class CORE_EXPORT WebInputMethodControllerImpl
WebRange GetSelectionOffsets() const override;
- void GetLayoutBounds(WebRect& control_bounds,
- WebRect& selection_bounds) override;
+ void GetLayoutBounds(WebRect* control_bounds,
+ WebRect* selection_bounds) override;
+ bool IsInputPanelPolicyManual() const override;
bool IsEditContextActive() const override;
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
LocalFrame* GetFrame() const;
diff --git a/chromium/third_party/blink/renderer/core/exported/web_local_frame_client.cc b/chromium/third_party/blink/renderer/core/exported/web_local_frame_client.cc
index ca2ff02504a..6048f7b65ad 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_local_frame_client.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_local_frame_client.cc
@@ -5,25 +5,11 @@
#include "third_party/blink/public/web/web_local_frame_client.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
namespace blink {
-service_manager::InterfaceProvider*
-WebLocalFrameClient::GetInterfaceProvider() {
- static service_manager::InterfaceProvider* interface_provider = []() {
- auto* interface_provider = new service_manager::InterfaceProvider();
- mojo::PendingRemote<service_manager::mojom::InterfaceProvider> provider;
- ignore_result(provider.InitWithNewPipeAndPassReceiver());
- interface_provider->Bind(std::move(provider));
- return interface_provider;
- }();
-
- return interface_provider;
-}
-
BrowserInterfaceBrokerProxy* WebLocalFrameClient::GetBrowserInterfaceBroker() {
// TODO(dtapuska): We should make this interface a pure virtual so we don't
// have this implementation in the base class.
diff --git a/chromium/third_party/blink/renderer/core/exported/web_local_frame_client_test.cc b/chromium/third_party/blink/renderer/core/exported/web_local_frame_client_test.cc
new file mode 100644
index 00000000000..b8579aa3e42
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/exported/web_local_frame_client_test.cc
@@ -0,0 +1,126 @@
+// 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 test makes assertions about the order of various callbacks in the (very
+// large) WebLocalFrameClient interface.
+
+#include "third_party/blink/public/web/web_local_frame_client.h"
+
+#include <utility>
+
+#include "testing/gmock/include/gmock/gmock.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_local_frame_impl.h"
+#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+using blink::url_test_helpers::ToKURL;
+
+namespace blink {
+
+namespace {
+
+class CallTrackingTestWebLocalFrameClient
+ : public frame_test_helpers::TestWebFrameClient {
+ public:
+ void DidCreateDocumentLoader(WebDocumentLoader* loader) override {
+ calls_.push_back("DidCreateDocumentLoader");
+ TestWebFrameClient::DidCreateDocumentLoader(loader);
+ }
+
+ void DidCommitNavigation(
+ const WebHistoryItem& item,
+ WebHistoryCommitType type,
+ bool should_reset_browser_interface_broker) override {
+ calls_.push_back("DidCommitNavigation");
+ TestWebFrameClient::DidCommitNavigation(
+ item, type, should_reset_browser_interface_broker);
+ }
+
+ void DidCreateInitialEmptyDocument() override {
+ calls_.push_back("DidCreateInitialEmptyDocument");
+ TestWebFrameClient::DidCreateInitialEmptyDocument();
+ }
+
+ void DidCreateDocumentElement() override {
+ calls_.push_back("DidCreateDocumentElement");
+ TestWebFrameClient::DidCreateDocumentElement();
+ }
+
+ void RunScriptsAtDocumentElementAvailable() override {
+ calls_.push_back("RunScriptsAtDocumentElementAvailable");
+ TestWebFrameClient::RunScriptsAtDocumentElementAvailable();
+ }
+
+ void DidFinishDocumentLoad() override {
+ calls_.push_back("DidFinishDocumentLoad");
+ TestWebFrameClient::DidFinishDocumentLoad();
+ }
+
+ void RunScriptsAtDocumentReady(bool document_is_empty) override {
+ calls_.push_back("RunScriptsAtDocumentReady");
+ TestWebFrameClient::RunScriptsAtDocumentReady(document_is_empty);
+ }
+
+ void RunScriptsAtDocumentIdle() override {
+ calls_.push_back("RunScriptsAtDocumentIdle");
+ TestWebFrameClient::RunScriptsAtDocumentIdle();
+ }
+
+ void DidHandleOnloadEvents() override {
+ calls_.push_back("DidHandleOnloadEvents");
+ TestWebFrameClient::DidHandleOnloadEvents();
+ }
+
+ void DidFinishLoad() override {
+ calls_.push_back("DidFinishLoad");
+ TestWebFrameClient::DidFinishLoad();
+ }
+
+ Vector<String> TakeCalls() { return std::exchange(calls_, {}); }
+
+ private:
+ Vector<String> calls_;
+};
+
+TEST(WebLocalFrameClientTest, Basic) {
+ CallTrackingTestWebLocalFrameClient client;
+ frame_test_helpers::WebViewHelper web_view_helper;
+
+ // Initialize() should populate the main frame with the initial empty document
+ // and nothing more than that.
+ web_view_helper.Initialize(&client);
+ EXPECT_THAT(client.TakeCalls(),
+ testing::ElementsAre("DidCreateDocumentLoader",
+ "DidCreateInitialEmptyDocument",
+ "DidCreateDocumentElement",
+ "RunScriptsAtDocumentElementAvailable"));
+
+ frame_test_helpers::LoadHTMLString(web_view_helper.LocalMainFrame(),
+ "<p>Hello world!</p>",
+ ToKURL("https://example.com/"));
+ EXPECT_THAT(
+ client.TakeCalls(),
+ testing::ElementsAre(
+ // TODO(https://crbug.com/1057229): RunScriptsAtDocumentIdle really
+ // should not be here, but there might be a bug where a truly empty
+ // initial document doesn't fire document_idle due to an early return
+ // in FrameLoader::FinishedParsing()...
+ "RunScriptsAtDocumentIdle", "DidCreateDocumentLoader",
+ "DidCommitNavigation", "DidCreateDocumentElement",
+ "RunScriptsAtDocumentElementAvailable", "DidFinishDocumentLoad",
+ "RunScriptsAtDocumentReady", "RunScriptsAtDocumentIdle",
+ "DidHandleOnloadEvents", "DidFinishLoad"));
+}
+
+// TODO(dcheng): Add test cases for iframes (i.e. iframe with no source, iframe
+// with explicit source of about:blank, et cetera)
+
+// TODO(dcheng): Add Javascript URL tests too.
+
+} // namespace
+
+} // namespace blink
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 df6f05ce082..b7b31685fa0 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
@@ -29,7 +29,7 @@ std::unique_ptr<WebNavigationParams> WebNavigationParams::CreateFromInfo(
auto result = std::make_unique<WebNavigationParams>();
result->url = info.url_request.Url();
result->http_method = info.url_request.HttpMethod();
- result->referrer = info.url_request.HttpHeaderField(http_names::kReferer);
+ result->referrer = info.url_request.ReferrerString();
result->referrer_policy = info.url_request.GetReferrerPolicy();
result->http_body = info.url_request.HttpBody();
result->http_content_type =
diff --git a/chromium/third_party/blink/renderer/core/exported/web_node.cc b/chromium/third_party/blink/renderer/core/exported/web_node.cc
index acba6e35496..6f310ea676a 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_node.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_node.cc
@@ -51,6 +51,7 @@
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
+#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
namespace blink {
@@ -209,6 +210,13 @@ bool WebNode::Focused() const {
return private_->IsFocused();
}
+uint64_t WebNode::ScrollingElementIdForTesting() const {
+ return private_->GetLayoutBox()
+ ->GetScrollableArea()
+ ->GetScrollElementId()
+ .GetStableId();
+}
+
WebPluginContainer* WebNode::PluginContainer() const {
return private_->GetWebPluginContainer();
}
diff --git a/chromium/third_party/blink/renderer/core/exported/web_node_test.cc b/chromium/third_party/blink/renderer/core/exported/web_node_test.cc
index a839796dadb..b3e2b4c4c25 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_node_test.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_node_test.cc
@@ -21,7 +21,7 @@ namespace blink {
class WebNodeTest : public PageTestBase {
protected:
void SetInnerHTML(const String& html) {
- GetDocument().documentElement()->SetInnerHTMLFromString(html);
+ GetDocument().documentElement()->setInnerHTML(html);
}
WebNode Root() { return WebNode(GetDocument().documentElement()); }
diff --git a/chromium/third_party/blink/renderer/core/exported/web_page_importance_signals.cc b/chromium/third_party/blink/renderer/core/exported/web_page_importance_signals.cc
deleted file mode 100644
index 079d2223ffc..00000000000
--- a/chromium/third_party/blink/renderer/core/exported/web_page_importance_signals.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/public/web/web_page_importance_signals.h"
-
-#include "third_party/blink/public/web/web_view_client.h"
-
-namespace blink {
-
-void WebPageImportanceSignals::Reset() {
- had_form_interaction_ = false;
- if (observer_)
- observer_->PageImportanceSignalsChanged();
-}
-
-void WebPageImportanceSignals::SetHadFormInteraction() {
- had_form_interaction_ = true;
- if (observer_)
- observer_->PageImportanceSignalsChanged();
-}
-
-void WebPageImportanceSignals::OnCommitLoad() {
- Reset();
-}
-
-} // 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 ec9a1c46da3..68313af7437 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
@@ -33,7 +33,6 @@
#include "cc/animation/animation_host.h"
#include "cc/layers/picture_layer.h"
-#include "third_party/blink/public/platform/web_cursor_info.h"
#include "third_party/blink/public/platform/web_float_rect.h"
#include "third_party/blink/public/web/web_view_client.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache_base.h"
@@ -68,7 +67,9 @@
#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/keyboard_codes.h"
+#include "third_party/blink/renderer/platform/text/text_direction.h"
#include "third_party/blink/renderer/platform/web_test_support.h"
+#include "third_party/blink/renderer/platform/widget/widget_base.h"
namespace blink {
@@ -132,8 +133,21 @@ class PagePopupChromeClient final : public EmptyChromeClient {
// (provided by WebViewTestProxy or WebWidgetTestProxy) runs the composite
// step for the current popup. We don't run popup tests with a compositor
// thread.
- WebWidgetClient* widget_client =
- popup_->web_view_->MainFrameImpl()->FrameWidgetImpl()->Client();
+ WebLocalFrameImpl* web_frame = popup_->web_view_->MainFrameImpl();
+ WebWidgetClient* widget_client = nullptr;
+
+ if (web_frame) {
+ widget_client = web_frame->FrameWidgetImpl()->Client();
+ } else {
+ // We'll enter this case for a popup in an out-of-proc iframe.
+ // Get the WidgetClient for the frame of the popup's owner element,
+ // instead of the WebView's MainFrame.
+ Element& popup_owner_element = popup_->popup_client_->OwnerElement();
+ WebLocalFrameImpl* web_local_frame_impl = WebLocalFrameImpl::FromFrame(
+ popup_owner_element.GetDocument().GetFrame());
+ widget_client = web_local_frame_impl->FrameWidgetImpl()->Client();
+ }
+
widget_client->ScheduleAnimation();
return;
}
@@ -142,13 +156,13 @@ class PagePopupChromeClient final : public EmptyChromeClient {
void AttachCompositorAnimationTimeline(CompositorAnimationTimeline* timeline,
LocalFrame*) override {
- popup_->animation_host_->AddAnimationTimeline(
+ popup_->widget_base_->AnimationHost()->AddAnimationTimeline(
timeline->GetAnimationTimeline());
}
void DetachCompositorAnimationTimeline(CompositorAnimationTimeline* timeline,
LocalFrame*) override {
- popup_->animation_host_->RemoveAnimationTimeline(
+ popup_->widget_base_->AnimationHost()->RemoveAnimationTimeline(
timeline->GetAnimationTimeline());
}
@@ -161,8 +175,8 @@ class PagePopupChromeClient final : public EmptyChromeClient {
IntSize MinimumWindowSize() const override { return IntSize(0, 0); }
- void SetCursor(const Cursor& cursor, LocalFrame* local_frame) override {
- popup_->WidgetClient()->DidChangeCursor(WebCursorInfo(cursor));
+ void SetCursor(const ui::Cursor& cursor, LocalFrame* local_frame) override {
+ popup_->WidgetClient()->DidChangeCursor(cursor);
}
void SetEventListenerProperties(
@@ -187,17 +201,7 @@ class PagePopupChromeClient final : public EmptyChromeClient {
}
void SetTouchAction(LocalFrame* frame, TouchAction touch_action) override {
- DCHECK(frame);
- WebLocalFrameImpl* web_frame = WebLocalFrameImpl::FromFrame(frame);
- // TODO(https://crbug.com/844547): check if we are setting touch action on
- // pop up window or not.
- if (!web_frame)
- return;
- WebFrameWidget* widget = web_frame->LocalRoot()->FrameWidget();
- if (!widget)
- return;
- if (WebWidgetClient* client = To<WebFrameWidgetBase>(widget)->Client())
- client->SetTouchAction(static_cast<WebTouchAction>(touch_action));
+ // Touch action is not used in the compositor for WebPagePopup.
}
void AttachRootLayer(scoped_refptr<cc::Layer> layer,
@@ -210,13 +214,13 @@ class PagePopupChromeClient final : public EmptyChromeClient {
TextDirection dir) override {
if (popup_->WidgetClient()) {
popup_->WidgetClient()->SetToolTipText(tooltip_text,
- ToWebTextDirection(dir));
+ ToBaseTextDirection(dir));
}
}
void InjectGestureScrollEvent(LocalFrame& local_frame,
WebGestureDevice device,
- const blink::WebFloatSize& delta,
+ const gfx::Vector2dF& delta,
ScrollGranularity granularity,
cc::ElementId scrollable_area_element_id,
WebInputEvent::Type injected_type) override {
@@ -241,8 +245,16 @@ bool PagePopupFeaturesClient::IsEnabled(Document*,
// WebPagePopupImpl ----------------------------------------------------------
-WebPagePopupImpl::WebPagePopupImpl(WebPagePopupClient* client)
- : web_page_popup_client_(client) {
+WebPagePopupImpl::WebPagePopupImpl(
+ WebPagePopupClient* client,
+ CrossVariantMojoAssociatedRemote<mojom::blink::WidgetHostInterfaceBase>
+ widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::blink::WidgetInterfaceBase>
+ widget)
+ : web_page_popup_client_(client),
+ widget_base_(std::make_unique<WidgetBase>(this,
+ std::move(widget_host),
+ std::move(widget))) {
DCHECK(client);
}
@@ -289,12 +301,12 @@ void WebPagePopupImpl::Initialize(WebViewImpl* web_view,
/* InterfaceRegistry* */ nullptr);
frame->SetPagePopupOwner(popup_client_->OwnerElement());
frame->SetView(MakeGarbageCollected<LocalFrameView>(*frame));
+ PagePopupSupplement::Install(*frame, *this, popup_client_);
frame->Init();
frame->View()->SetParentVisible(true);
frame->View()->SetSelfVisible(true);
DCHECK(frame->DomWindow());
- PagePopupSupplement::Install(*frame, *this, popup_client_);
DCHECK_EQ(popup_client_->OwnerElement().GetDocument().ExistingAXObjectCache(),
frame->GetDocument()->ExistingAXObjectCache());
if (AXObjectCache* cache = frame->GetDocument()->ExistingAXObjectCache()) {
@@ -302,7 +314,7 @@ void WebPagePopupImpl::Initialize(WebViewImpl* web_view,
cache->ChildrenChanged(&popup_client_->OwnerElement());
}
- page_->AnimationHostInitialized(*animation_host_, nullptr);
+ page_->AnimationHostInitialized(*widget_base_->AnimationHost(), nullptr);
scoped_refptr<SharedBuffer> data = SharedBuffer::Create();
popup_client_->WriteDocument(data.get());
@@ -313,11 +325,23 @@ void WebPagePopupImpl::Initialize(WebViewImpl* web_view,
SetFocus(true);
}
-void WebPagePopupImpl::SetAnimationHost(cc::AnimationHost* animation_host) {
- // The WebWidgetClient is given |this| as its WebWidget but it is set up
- // before Initialize() is called on |this|. So we store the |animation_host_|
- // here, but finish setting it up in Initialize().
- animation_host_ = animation_host;
+void WebPagePopupImpl::SetCompositorHosts(cc::LayerTreeHost* layer_tree_host,
+ cc::AnimationHost* animation_host) {
+ // Careful Initialize() is called after SetCompositorHosts, so don't do
+ // much work here.
+ widget_base_->SetCompositorHosts(layer_tree_host, animation_host);
+}
+
+void WebPagePopupImpl::SetCompositorVisible(bool visible) {
+ widget_base_->SetCompositorVisible(visible);
+}
+
+void WebPagePopupImpl::UpdateVisualState() {
+ widget_base_->UpdateVisualState();
+}
+
+void WebPagePopupImpl::WillBeginCompositorFrame() {
+ widget_base_->WillBeginCompositorFrame();
}
void WebPagePopupImpl::PostMessageToPopup(const String& message) {
@@ -351,9 +375,8 @@ void WebPagePopupImpl::SetWindowRect(const IntRect& rect_in_screen) {
}
void WebPagePopupImpl::SetRootLayer(scoped_refptr<cc::Layer> layer) {
- is_accelerated_compositing_active_ = !!layer;
root_layer_ = std::move(layer);
- WidgetClient()->SetRootLayer(root_layer_);
+ widget_base_->LayerTreeHost()->SetRootLayer(root_layer_);
}
void WebPagePopupImpl::SetSuppressFrameRequestsWorkaroundFor704763Only(
@@ -364,22 +387,22 @@ void WebPagePopupImpl::SetSuppressFrameRequestsWorkaroundFor704763Only(
suppress_frame_requests);
}
-void WebPagePopupImpl::BeginFrame(base::TimeTicks last_frame_time, bool) {
- if (!page_)
- return;
- // FIXME: This should use lastFrameTimeMonotonic but doing so
- // breaks tests.
- PageWidgetDelegate::Animate(*page_, base::TimeTicks::Now());
+void WebPagePopupImpl::BeginFrame(base::TimeTicks last_frame_time) {
+ widget_base_->BeginMainFrame(last_frame_time);
+}
+
+void WebPagePopupImpl::RecordTimeToFirstActivePaint(base::TimeDelta duration) {
+ WidgetClient()->RecordTimeToFirstActivePaint(duration);
}
-void WebPagePopupImpl::UpdateLifecycle(LifecycleUpdate requested_update,
- LifecycleUpdateReason reason) {
+void WebPagePopupImpl::UpdateLifecycle(WebLifecycleUpdate requested_update,
+ DocumentUpdateReason reason) {
if (!page_)
return;
// Popups always update their lifecycle in the context of the containing
// document's lifecycle, so explicitly override the reason.
PageWidgetDelegate::UpdateLifecycle(*page_, MainFrame(), requested_update,
- WebWidget::LifecycleUpdateReason::kOther);
+ DocumentUpdateReason::kPagePopup);
}
void WebPagePopupImpl::Resize(const WebSize& new_size_in_viewport) {
@@ -418,6 +441,18 @@ WebInputEventResult WebPagePopupImpl::HandleKeyEvent(
return MainFrame().GetEventHandler().KeyEvent(event);
}
+void WebPagePopupImpl::BeginMainFrame(base::TimeTicks last_frame_time) {
+ if (!page_)
+ return;
+ // FIXME: This should use lastFrameTimeMonotonic but doing so
+ // breaks tests.
+ PageWidgetDelegate::Animate(*page_, base::TimeTicks::Now());
+}
+
+void WebPagePopupImpl::DispatchRafAlignedInput(base::TimeTicks frame_time) {
+ WidgetClient()->DispatchRafAlignedInput(frame_time);
+}
+
WebInputEventResult WebPagePopupImpl::HandleCharEvent(
const WebKeyboardEvent& event) {
if (suppress_next_keypress_event_) {
@@ -433,8 +468,8 @@ WebInputEventResult WebPagePopupImpl::HandleGestureEvent(
return WebInputEventResult::kNotHandled;
if ((event.GetType() == WebInputEvent::kGestureTap ||
event.GetType() == WebInputEvent::kGestureTapDown) &&
- !IsViewportPointInWindow(event.PositionInWidget().x,
- event.PositionInWidget().y)) {
+ !IsViewportPointInWindow(event.PositionInWidget().x(),
+ event.PositionInWidget().y())) {
Cancel();
return WebInputEventResult::kNotHandled;
}
@@ -445,8 +480,8 @@ WebInputEventResult WebPagePopupImpl::HandleGestureEvent(
void WebPagePopupImpl::HandleMouseDown(LocalFrame& main_frame,
const WebMouseEvent& event) {
- if (IsViewportPointInWindow(event.PositionInWidget().x,
- event.PositionInWidget().y))
+ if (IsViewportPointInWindow(event.PositionInWidget().x(),
+ event.PositionInWidget().y()))
PageWidgetEventHandler::HandleMouseDown(main_frame, event);
else
Cancel();
@@ -455,8 +490,8 @@ void WebPagePopupImpl::HandleMouseDown(LocalFrame& main_frame,
WebInputEventResult WebPagePopupImpl::HandleMouseWheel(
LocalFrame& main_frame,
const WebMouseWheelEvent& event) {
- if (IsViewportPointInWindow(event.PositionInWidget().x,
- event.PositionInWidget().y))
+ if (IsViewportPointInWindow(event.PositionInWidget().x(),
+ event.PositionInWidget().y()))
return PageWidgetEventHandler::HandleMouseWheel(main_frame, event);
Cancel();
return WebInputEventResult::kNotHandled;
@@ -535,9 +570,8 @@ void WebPagePopupImpl::Close() {
Cancel();
}
- is_accelerated_compositing_active_ = false;
- animation_host_ = nullptr;
web_page_popup_client_ = nullptr;
+ widget_base_.reset();
// Self-delete on Close().
Release();
@@ -597,11 +631,11 @@ LocalDOMWindow* WebPagePopupImpl::Window() {
return MainFrame().DomWindow();
}
-WebPoint WebPagePopupImpl::PositionRelativeToOwner() {
+gfx::Point WebPagePopupImpl::PositionRelativeToOwner() {
WebRect root_window_rect = WindowRectInScreen();
WebRect window_rect = WindowRectInScreen();
- return WebPoint(window_rect.x - root_window_rect.x,
- window_rect.y - root_window_rect.y);
+ return gfx::Point(window_rect.x - root_window_rect.x,
+ window_rect.y - root_window_rect.y);
}
WebDocument WebPagePopupImpl::GetDocument() {
@@ -623,7 +657,12 @@ WebRect WebPagePopupImpl::WindowRectInScreen() const {
// WebPagePopup ----------------------------------------------------------------
-WebPagePopup* WebPagePopup::Create(WebPagePopupClient* client) {
+WebPagePopup* WebPagePopup::Create(
+ WebPagePopupClient* client,
+ CrossVariantMojoAssociatedRemote<mojom::blink::WidgetHostInterfaceBase>
+ widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::blink::WidgetInterfaceBase>
+ widget) {
CHECK(client);
// A WebPagePopupImpl instance usually has two references.
// - One owned by the instance itself. It represents the visible widget.
@@ -631,7 +670,8 @@ WebPagePopup* WebPagePopup::Create(WebPagePopupClient* client) {
// WebPagePopupImpl to close.
// We need them because the closing operation is asynchronous and the widget
// can be closed while the WebViewImpl is unaware of it.
- auto popup = base::AdoptRef(new WebPagePopupImpl(client));
+ auto popup = base::AdoptRef(
+ new WebPagePopupImpl(client, std::move(widget_host), std::move(widget)));
popup->AddRef();
return popup.get();
}
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 8fea472cedb..fbdb7bad95e 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
@@ -32,11 +32,15 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_PAGE_POPUP_IMPL_H_
#include "base/macros.h"
+#include "third_party/blink/public/mojom/page/widget.mojom-blink.h"
+#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/page/page_popup.h"
#include "third_party/blink/renderer/core/page/page_widget_delegate.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/widget/widget_base_client.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
namespace cc {
@@ -50,11 +54,13 @@ class PagePopupChromeClient;
class PagePopupClient;
class WebViewImpl;
class LocalDOMWindow;
+class WidgetBase;
class CORE_EXPORT WebPagePopupImpl final : public WebPagePopup,
public PageWidgetEventHandler,
public PagePopup,
- public RefCounted<WebPagePopupImpl> {
+ public RefCounted<WebPagePopupImpl>,
+ public WidgetBaseClient {
USING_FAST_MALLOC(WebPagePopupImpl);
public:
@@ -94,9 +100,12 @@ class CORE_EXPORT WebPagePopupImpl final : public WebPagePopup,
// WebWidget implementation.
WebInputEventResult DispatchBufferedTouchEvents() override;
+ void SetCompositorVisible(bool visible) override;
+ void UpdateVisualState() override;
+ void WillBeginCompositorFrame() override;
// WebPagePopup implementation.
- WebPoint PositionRelativeToOwner() override;
+ gfx::Point PositionRelativeToOwner() override;
WebDocument GetDocument() override;
WebPagePopupClient* GetClientForTesting() const override;
@@ -107,25 +116,26 @@ class CORE_EXPORT WebPagePopupImpl final : public WebPagePopup,
WebInputEventResult HandleKeyEvent(const WebKeyboardEvent&) override;
private:
+ // WidgetBaseClient overrides:
+ void DispatchRafAlignedInput(base::TimeTicks frame_time) override;
+ void BeginMainFrame(base::TimeTicks last_frame_time) override;
+ void RecordTimeToFirstActivePaint(base::TimeDelta duration) override;
+ void SetSuppressFrameRequestsWorkaroundFor704763Only(bool) final;
+
// WebWidget implementation.
// NOTE: The WebWidget may still be used after requesting the popup to be
// closed and destroyed. But the Page and the MainFrame are destroyed
// immediately. So all methods (outside of initialization) that are part
// of the WebWidget need to check if close has already been initiated (they
// can do so by checking |page_|) and not crash! https://crbug.com/906340
- void SetAnimationHost(cc::AnimationHost*) override;
- void SetSuppressFrameRequestsWorkaroundFor704763Only(bool) final;
- void BeginFrame(base::TimeTicks last_frame_time,
- bool record_main_frame_metrics) override;
- void UpdateLifecycle(LifecycleUpdate requested_update,
- LifecycleUpdateReason reason) override;
+ void SetCompositorHosts(cc::LayerTreeHost*, cc::AnimationHost*) override;
+ void BeginFrame(base::TimeTicks last_frame_time) override;
+ void UpdateLifecycle(WebLifecycleUpdate requested_update,
+ DocumentUpdateReason reason) override;
void Resize(const WebSize&) override;
void Close() override;
WebInputEventResult HandleInputEvent(const WebCoalescedInputEvent&) override;
void SetFocus(bool) override;
- bool IsAcceleratedCompositingActive() const override {
- return is_accelerated_compositing_active_;
- }
WebURL GetURLForDebugTrace() override;
WebHitTestResult HitTestResultAt(const gfx::Point&) override { return {}; }
@@ -147,7 +157,12 @@ class CORE_EXPORT WebPagePopupImpl final : public WebPagePopup,
AXObject* RootAXObject() override;
void SetWindowRect(const IntRect&) override;
- explicit WebPagePopupImpl(WebPagePopupClient*);
+ WebPagePopupImpl(
+ WebPagePopupClient*,
+ CrossVariantMojoAssociatedRemote<mojom::blink::WidgetHostInterfaceBase>
+ widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::blink::WidgetInterfaceBase>
+ widget);
void DestroyPage();
void SetRootLayer(scoped_refptr<cc::Layer>);
@@ -165,13 +180,15 @@ class CORE_EXPORT WebPagePopupImpl final : public WebPagePopup,
PagePopupClient* popup_client_;
bool closing_ = false;
- cc::AnimationHost* animation_host_ = nullptr;
scoped_refptr<cc::Layer> root_layer_;
base::TimeTicks raf_aligned_input_start_time_;
- bool is_accelerated_compositing_active_ = false;
bool suppress_next_keypress_event_ = false;
+ // Base functionality all widgets have. This is a member as to avoid
+ // complicated inheritance structures.
+ std::unique_ptr<WidgetBase> widget_base_;
+
friend class WebPagePopup;
friend class PagePopupChromeClient;
@@ -180,8 +197,11 @@ class CORE_EXPORT WebPagePopupImpl final : public WebPagePopup,
// WebPagePopupImpl is the only implementation of WebPagePopup and PagePopup, so
// no further checking required.
-DEFINE_TYPE_CASTS(WebPagePopupImpl, WebPagePopup, widget, true, true);
-DEFINE_TYPE_CASTS(WebPagePopupImpl, PagePopup, popup, true, true);
+template <>
+struct DowncastTraits<WebPagePopupImpl> {
+ static bool AllowFrom(const WebPagePopup& widget) { return true; }
+ static bool AllowFrom(const PagePopup& popup) { return true; }
+};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_PAGE_POPUP_IMPL_H_
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 dc3e68cc3f4..e29242e7423 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_performance.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_performance.cc
@@ -65,6 +65,10 @@ double WebPerformance::NavigationStart() const {
return MillisecondsToSeconds(private_->timing()->navigationStart());
}
+base::TimeTicks WebPerformance::NavigationStartAsMonotonicTime() const {
+ return private_->timing()->NavigationStartAsMonotonicTime();
+}
+
double WebPerformance::InputForNavigationStart() const {
return MillisecondsToSeconds(private_->timing()->inputStart());
}
@@ -146,10 +150,6 @@ double WebPerformance::LoadEventEnd() const {
return MillisecondsToSeconds(private_->timing()->loadEventEnd());
}
-double WebPerformance::FirstLayout() const {
- return MillisecondsToSeconds(private_->timing()->FirstLayout());
-}
-
double WebPerformance::FirstPaint() const {
return MillisecondsToSeconds(private_->timing()->FirstPaint());
}
@@ -162,6 +162,10 @@ double WebPerformance::FirstContentfulPaint() const {
return MillisecondsToSeconds(private_->timing()->FirstContentfulPaint());
}
+base::TimeTicks WebPerformance::FirstContentfulPaintAsMonotonicTime() const {
+ return private_->timing()->FirstContentfulPaintAsMonotonicTime();
+}
+
double WebPerformance::FirstMeaningfulPaint() const {
return MillisecondsToSeconds(private_->timing()->FirstMeaningfulPaint());
}
@@ -187,33 +191,25 @@ uint64_t WebPerformance::LargestTextPaintSize() const {
return private_->timing()->LargestTextPaintSize();
}
-double WebPerformance::PageInteractive() const {
- return MillisecondsToSeconds(private_->timing()->PageInteractive());
-}
-
-double WebPerformance::PageInteractiveDetection() const {
- return MillisecondsToSeconds(private_->timing()->PageInteractiveDetection());
-}
-
-double WebPerformance::FirstInputInvalidatingInteractive() const {
+double WebPerformance::FirstInputOrScrollNotifiedTimestamp() const {
return MillisecondsToSeconds(
- private_->timing()->FirstInputInvalidatingInteractive());
+ private_->timing()->FirstInputOrScrollNotifiedTimestamp());
}
-double WebPerformance::FirstInputDelay() const {
- return MillisecondsToSeconds(private_->timing()->FirstInputDelay());
+base::Optional<base::TimeDelta> WebPerformance::FirstInputDelay() const {
+ return private_->timing()->FirstInputDelay();
}
-double WebPerformance::FirstInputTimestamp() const {
- return MillisecondsToSeconds(private_->timing()->FirstInputTimestamp());
+base::Optional<base::TimeDelta> WebPerformance::FirstInputTimestamp() const {
+ return private_->timing()->FirstInputTimestamp();
}
-double WebPerformance::LongestInputDelay() const {
- return MillisecondsToSeconds(private_->timing()->LongestInputDelay());
+base::Optional<base::TimeDelta> WebPerformance::LongestInputDelay() const {
+ return private_->timing()->LongestInputDelay();
}
-double WebPerformance::LongestInputTimestamp() const {
- return MillisecondsToSeconds(private_->timing()->LongestInputTimestamp());
+base::Optional<base::TimeDelta> WebPerformance::LongestInputTimestamp() const {
+ return private_->timing()->LongestInputTimestamp();
}
double WebPerformance::ParseStart() const {
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 df68d3c8fa1..dc8ef5e532a 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
@@ -32,11 +32,10 @@
#include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h"
#include "build/build_config.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_coalesced_input_event.h"
-#include "third_party/blink/public/platform/web_cursor_info.h"
#include "third_party/blink/public/platform/web_drag_data.h"
-#include "third_party/blink/public/platform/web_input_event.h"
#include "third_party/blink/public/platform/web_rect.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_url.h"
@@ -102,10 +101,13 @@
#include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
#include "third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h"
-#include "third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/keyboard_codes.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/wtf/assertions.h"
+#include "ui/base/cursor/cursor.h"
+#include "ui/base/mojom/cursor_type.mojom-blink.h"
namespace blink {
@@ -137,8 +139,7 @@ void WebPluginContainerImpl::UpdateAllLifecyclePhases() {
if (!web_plugin_)
return;
- web_plugin_->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kOther);
+ web_plugin_->UpdateAllLifecyclePhases(DocumentUpdateReason::kPlugin);
}
void WebPluginContainerImpl::Paint(GraphicsContext& context,
@@ -150,20 +151,21 @@ void WebPluginContainerImpl::Paint(GraphicsContext& context,
return;
if (WantsWheelEvents()) {
- ScrollHitTestDisplayItem::Record(
- context, *GetLayoutEmbeddedContent(), DisplayItem::kPluginScrollHitTest,
- nullptr, GetLayoutEmbeddedContent()->FirstFragment().VisualRect());
+ context.GetPaintController().RecordScrollHitTestData(
+ *GetLayoutEmbeddedContent(), DisplayItem::kPluginScrollHitTest, nullptr,
+ GetLayoutEmbeddedContent()->FirstFragment().VisualRect());
}
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() && layer_) {
layer_->SetBounds(gfx::Size(Size()));
layer_->SetIsDrawable(true);
layer_->SetHitTestable(true);
+ auto offset = GetLayoutEmbeddedContent()->ReplacedContentRect().offset;
// When compositing is after paint, composited plugins should have their
// layers inserted rather than invoking WebPlugin::paint.
RecordForeignLayer(context, *element_->GetLayoutObject(),
DisplayItem::kForeignLayerPlugin, layer_,
- FloatPoint(DocumentLocation()));
+ FloatPoint(offset));
return;
}
@@ -212,7 +214,8 @@ void WebPluginContainerImpl::InvalidateRect(const IntRect& rect) {
layout_object->InvalidatePaintRectangle(PhysicalRect(dirty_rect));
}
-void WebPluginContainerImpl::SetFocused(bool focused, WebFocusType focus_type) {
+void WebPluginContainerImpl::SetFocused(bool focused,
+ mojom::blink::FocusType focus_type) {
web_plugin_->UpdateFocus(focused, focus_type);
}
@@ -237,18 +240,18 @@ void WebPluginContainerImpl::HandleEvent(Event& event) {
// http://devedge-temp.mozilla.org/library/manuals/2002/plugin/1.0/structures5.html#1000000
// Don't take the documentation as truth, however. There are many cases
// where mozilla behaves differently than the spec.
- if (event.IsMouseEvent())
- HandleMouseEvent(ToMouseEvent(event));
- else if (event.IsWheelEvent())
- HandleWheelEvent(ToWheelEvent(event));
- else if (event.IsKeyboardEvent())
- HandleKeyboardEvent(ToKeyboardEvent(event));
- else if (event.IsTouchEvent())
- HandleTouchEvent(ToTouchEvent(event));
- else if (event.IsGestureEvent())
- HandleGestureEvent(ToGestureEvent(event));
- else if (event.IsDragEvent() && web_plugin_->CanProcessDrag())
- HandleDragEvent(ToDragEvent(event));
+ if (auto* mouse_event = DynamicTo<MouseEvent>(event))
+ HandleMouseEvent(*mouse_event);
+ else if (auto* wheel_event = DynamicTo<WheelEvent>(event))
+ HandleWheelEvent(*wheel_event);
+ else if (auto* keyboard_event = DynamicTo<KeyboardEvent>(event))
+ HandleKeyboardEvent(*keyboard_event);
+ else if (auto* touch_event = DynamicTo<TouchEvent>(event))
+ HandleTouchEvent(*touch_event);
+ else if (auto* gesture_event = DynamicTo<GestureEvent>(event))
+ HandleGestureEvent(*gesture_event);
+ else if (IsA<DragEvent>(event) && web_plugin_->CanProcessDrag())
+ HandleDragEvent(To<DragEvent>(event));
// FIXME: it would be cleaner if EmbeddedContentView::HandleEvent returned
// true/false and HTMLPluginElement called SetDefaultHandled or
@@ -306,7 +309,7 @@ void WebPluginContainerImpl::ReportFindInPageSelection(int identifier,
if (!frame)
return;
frame->GetFindInPage()->ReportFindInPageSelection(
- identifier, index, blink::WebRect(), false /* final_update */);
+ identifier, index, gfx::Rect(), false /* final_update */);
}
float WebPluginContainerImpl::DeviceScaleFactor() {
@@ -336,11 +339,6 @@ void WebPluginContainerImpl::SetCcLayer(cc::Layer* new_layer,
prevent_contents_opaque_changes == prevent_contents_opaque_changes_)
return;
- if (layer_)
- GraphicsLayer::UnregisterContentsLayer(layer_);
- if (new_layer)
- GraphicsLayer::RegisterContentsLayer(new_layer);
-
layer_ = new_layer;
prevent_contents_opaque_changes_ = prevent_contents_opaque_changes;
@@ -397,25 +395,36 @@ void WebPluginContainerImpl::Copy() {
if (!web_plugin_->HasSelection())
return;
- SystemClipboard::GetInstance().WriteHTML(
+ LocalFrame* frame = element_->GetDocument().GetFrame();
+ frame->GetSystemClipboard()->WriteHTML(
web_plugin_->SelectionAsMarkup(), KURL(), web_plugin_->SelectionAsText());
- SystemClipboard::GetInstance().CommitWrite();
+ frame->GetSystemClipboard()->CommitWrite();
}
bool WebPluginContainerImpl::ExecuteEditCommand(const WebString& name) {
- if (web_plugin_->ExecuteEditCommand(name))
- return true;
-
- if (name != "Copy")
- return false;
-
- Copy();
- return true;
+ return ExecuteEditCommand(name, WebString());
}
bool WebPluginContainerImpl::ExecuteEditCommand(const WebString& name,
const WebString& value) {
- return web_plugin_->ExecuteEditCommand(name, value);
+ DCHECK(value.IsEmpty());
+
+ // If the clipboard contains something other than text (e.g. an image),
+ // ReadPlainText() returns an empty string. The empty string is then pasted,
+ // replacing any selected text. This behavior is consistent with that of HTML
+ // text form fields.
+ String text;
+ if (name == "Paste" || name == "PasteAndMatchStyle") {
+ LocalFrame* frame = element_->GetDocument().GetFrame();
+ text = frame->GetSystemClipboard()->ReadPlainText();
+ }
+
+ // If copying or cutting, make sure to copy the plugin text to the clipboard
+ // before executing the command.
+ if (name == "Copy" || (name == "Cut" && web_plugin_->CanEditText()))
+ Copy();
+
+ return web_plugin_->ExecuteEditCommand(name, text);
}
// static
@@ -442,8 +451,8 @@ void WebPluginContainerImpl::DispatchProgressEvent(const WebString& type,
if (url.IsEmpty()) {
event = ProgressEvent::Create(type, length_computable, loaded, total);
} else {
- event = ResourceProgressEvent::Create(type, length_computable, loaded,
- total, url);
+ event = MakeGarbageCollected<ResourceProgressEvent>(type, length_computable,
+ loaded, total, url);
}
element_->DispatchEvent(*event);
}
@@ -463,10 +472,6 @@ void WebPluginContainerImpl::InvalidateRect(const WebRect& rect) {
InvalidateRect(static_cast<IntRect>(rect));
}
-void WebPluginContainerImpl::ScrollRect(const WebRect& rect) {
- InvalidateRect(rect);
-}
-
void WebPluginContainerImpl::ScheduleAnimation() {
if (auto* frame_view = element_->GetDocument().View())
frame_view->ScheduleAnimation();
@@ -642,24 +647,24 @@ void WebPluginContainerImpl::SetWantsWheelEvents(bool wants_wheel_events) {
LocalFrameView* frame_view = element_->GetDocument().GetFrame()->View();
scrolling_coordinator->NotifyGeometryChanged(frame_view);
- // Scroll hit test display items depend on wheel events. The scroll
- // hit test display items paint in the background phase.
+ // Scroll hit test data depend on wheel events. They are painted in the
+ // background phase.
GetLayoutEmbeddedContent()->SetBackgroundNeedsFullPaintInvalidation();
}
}
}
}
-WebPoint WebPluginContainerImpl::RootFrameToLocalPoint(
- const WebPoint& point_in_root_frame) {
- WebPoint point_in_content =
- ParentFrameView()->ConvertFromRootFrame(point_in_root_frame);
+gfx::Point WebPluginContainerImpl::RootFrameToLocalPoint(
+ const gfx::Point& point_in_root_frame) {
+ gfx::Point point_in_content =
+ ParentFrameView()->ConvertFromRootFrame(IntPoint(point_in_root_frame));
return RoundedIntPoint(element_->GetLayoutObject()->AbsoluteToLocalPoint(
PhysicalOffset(point_in_content)));
}
-WebPoint WebPluginContainerImpl::LocalToRootFramePoint(
- const WebPoint& point_in_local) {
+gfx::Point WebPluginContainerImpl::LocalToRootFramePoint(
+ const gfx::Point& point_in_local) {
IntPoint absolute_point =
RoundedIntPoint(element_->GetLayoutObject()->LocalToAbsolutePoint(
PhysicalOffset(point_in_local)));
@@ -737,7 +742,7 @@ bool WebPluginContainerImpl::WantsWheelEvents() const {
WebPluginContainerImpl::WebPluginContainerImpl(HTMLPlugInElement& element,
WebPlugin* web_plugin)
: EmbeddedContentView(IntRect()),
- ContextClient(element.GetDocument().GetFrame()),
+ ExecutionContextClient(element.GetDocument().GetFrame()),
element_(element),
web_plugin_(web_plugin),
layer_(nullptr),
@@ -778,10 +783,7 @@ void WebPluginContainerImpl::Dispose() {
web_plugin_ = nullptr;
}
- if (layer_) {
- GraphicsLayer::UnregisterContentsLayer(layer_);
- layer_ = nullptr;
- }
+ layer_ = nullptr;
}
void WebPluginContainerImpl::SetFrameRect(const IntRect& rect) {
@@ -793,9 +795,9 @@ void WebPluginContainerImpl::SetFrameRect(const IntRect& rect) {
PropagateFrameRects();
}
-void WebPluginContainerImpl::Trace(blink::Visitor* visitor) {
+void WebPluginContainerImpl::Trace(Visitor* visitor) {
visitor->Trace(element_);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
void WebPluginContainerImpl::HandleMouseEvent(MouseEvent& event) {
@@ -813,10 +815,10 @@ void WebPluginContainerImpl::HandleMouseEvent(MouseEvent& event) {
if (event.type() == event_type_names::kMousedown)
FocusPlugin();
- WebCursorInfo cursor_info;
+ ui::Cursor cursor(ui::mojom::blink::CursorType::kPointer);
if (web_plugin_ && web_plugin_->HandleInputEvent(
- WebCoalescedInputEvent(transformed_event),
- cursor_info) != WebInputEventResult::kNotHandled)
+ WebCoalescedInputEvent(transformed_event), &cursor) !=
+ WebInputEventResult::kNotHandled)
event.SetDefaultHandled();
// A windowless plugin can change the cursor in response to a mouse move
@@ -826,11 +828,11 @@ void WebPluginContainerImpl::HandleMouseEvent(MouseEvent& event) {
if (!page)
return;
page->GetChromeClient().SetCursorForPlugin(
- cursor_info, &parent->GetFrame().LocalFrameRoot());
+ cursor, &parent->GetFrame().LocalFrameRoot());
}
void WebPluginContainerImpl::HandleDragEvent(MouseEvent& event) {
- DCHECK(event.IsDragEvent());
+ DCHECK(IsA<DragEvent>(event));
WebDragStatus drag_status = kWebDragStatusUnknown;
if (event.type() == event_type_names::kDragenter)
@@ -849,10 +851,10 @@ void WebPluginContainerImpl::HandleDragEvent(MouseEvent& event) {
WebDragData drag_data = data_transfer->GetDataObject()->ToWebDragData();
WebDragOperationsMask drag_operation_mask =
static_cast<WebDragOperationsMask>(data_transfer->SourceOperation());
- WebFloatPoint drag_screen_location(event.screenX(), event.screenY());
+ gfx::PointF drag_screen_location(event.screenX(), event.screenY());
IntPoint location(Location());
- WebFloatPoint drag_location(event.AbsoluteLocation().X() - location.X(),
- event.AbsoluteLocation().Y() - location.Y());
+ gfx::PointF drag_location(event.AbsoluteLocation().X() - location.X(),
+ event.AbsoluteLocation().Y() - location.Y());
web_plugin_->HandleDragStatusUpdate(drag_status, drag_data,
drag_operation_mask, drag_location,
@@ -860,7 +862,8 @@ void WebPluginContainerImpl::HandleDragEvent(MouseEvent& event) {
}
void WebPluginContainerImpl::HandleWheelEvent(WheelEvent& event) {
- WebFloatPoint absolute_location = event.NativeEvent().PositionInRootFrame();
+ FloatPoint absolute_location =
+ FloatPoint(event.NativeEvent().PositionInRootFrame());
// Translate the root frame position to content coordinates.
absolute_location =
@@ -871,9 +874,9 @@ void WebPluginContainerImpl::HandleWheelEvent(WheelEvent& event) {
WebMouseWheelEvent translated_event = event.NativeEvent().FlattenTransform();
translated_event.SetPositionInWidget(local_point.X(), local_point.Y());
- WebCursorInfo cursor_info;
+ ui::Cursor dummy_cursor;
if (web_plugin_->HandleInputEvent(WebCoalescedInputEvent(translated_event),
- cursor_info) !=
+ &dummy_cursor) !=
WebInputEventResult::kNotHandled)
event.SetDefaultHandled();
}
@@ -894,9 +897,9 @@ void WebPluginContainerImpl::HandleKeyboardEvent(KeyboardEvent& event) {
if (web_plugin_->SupportsEditCommands())
web_frame->Client()->HandleCurrentKeyboardEvent();
- WebCursorInfo cursor_info;
+ ui::Cursor dummy_cursor;
if (web_plugin_->HandleInputEvent(WebCoalescedInputEvent(web_event),
- cursor_info) !=
+ &dummy_cursor) !=
WebInputEventResult::kNotHandled) {
event.SetDefaultHandled();
}
@@ -955,8 +958,8 @@ WebTouchEvent WebPluginContainerImpl::TransformTouchEvent(
LocalFrameView* parent = ParentFrameView();
for (unsigned i = 0; i < transformed_event.touches_length; ++i) {
- WebFloatPoint absolute_location =
- transformed_event.touches[i].PositionInWidget();
+ FloatPoint absolute_location =
+ FloatPoint(transformed_event.touches[i].PositionInWidget());
// Translate the root frame position to content coordinates.
absolute_location = parent->ConvertFromRootFrame(absolute_location);
@@ -999,8 +1002,8 @@ void WebPluginContainerImpl::HandleTouchEvent(TouchEvent& event) {
WebCoalescedInputEvent transformed_event =
TransformCoalescedTouchEvent(*event.NativeEvent());
- WebCursorInfo cursor_info;
- if (web_plugin_->HandleInputEvent(transformed_event, cursor_info) !=
+ ui::Cursor dummy_cursor;
+ if (web_plugin_->HandleInputEvent(transformed_event, &dummy_cursor) !=
WebInputEventResult::kNotHandled)
event.SetDefaultHandled();
// FIXME: Can a plugin change the cursor from a touch-event callback?
@@ -1021,17 +1024,17 @@ void WebPluginContainerImpl::HandleGestureEvent(GestureEvent& event) {
// Take a copy of the event and translate it into the coordinate
// system of the plugin.
WebGestureEvent translated_event = event.NativeEvent();
- WebFloatPoint absolute_root_frame_location =
+ gfx::PointF absolute_root_frame_location =
event.NativeEvent().PositionInRootFrame();
FloatPoint local_point =
element_->GetLayoutObject()->AbsoluteToLocalFloatPoint(
- absolute_root_frame_location);
+ FloatPoint(absolute_root_frame_location));
translated_event.FlattenTransform();
translated_event.SetPositionInWidget(local_point);
- WebCursorInfo cursor_info;
+ ui::Cursor dummy_cursor;
if (web_plugin_->HandleInputEvent(WebCoalescedInputEvent(translated_event),
- cursor_info) !=
+ &dummy_cursor) !=
WebInputEventResult::kNotHandled) {
event.SetDefaultHandled();
return;
@@ -1046,9 +1049,9 @@ void WebPluginContainerImpl::SynthesizeMouseEventIfPossible(TouchEvent& event) {
if (web_event.GetType() == WebInputEvent::kUndefined)
return;
- WebCursorInfo cursor_info;
+ ui::Cursor dummy_cursor;
if (web_plugin_->HandleInputEvent(WebCoalescedInputEvent(web_event),
- cursor_info) !=
+ &dummy_cursor) !=
WebInputEventResult::kNotHandled)
event.SetDefaultHandled();
}
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 242fd3e1d97..3d8e13cd55f 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
@@ -33,14 +33,15 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_PLUGIN_CONTAINER_IMPL_H_
#include "base/memory/scoped_refptr.h"
+#include "third_party/blink/public/common/input/web_touch_event.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
#include "third_party/blink/public/platform/web_coalesced_input_event.h"
-#include "third_party/blink/public/platform/web_focus_type.h"
-#include "third_party/blink/public/platform/web_touch_event.h"
#include "third_party/blink/public/web/web_plugin_container.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/frame/embedded_content_view.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace cc {
@@ -70,7 +71,7 @@ class CORE_EXPORT WebPluginContainerImpl final
: public GarbageCollected<WebPluginContainerImpl>,
public EmbeddedContentView,
public WebPluginContainer,
- public ContextClient {
+ public ExecutionContextClient {
USING_GARBAGE_COLLECTED_MIXIN(WebPluginContainerImpl);
USING_PRE_FINALIZER(WebPluginContainerImpl, PreFinalize);
@@ -106,7 +107,7 @@ class CORE_EXPORT WebPluginContainerImpl final
bool WantsWheelEvents() const;
void UpdateAllLifecyclePhases();
void InvalidateRect(const IntRect&);
- void SetFocused(bool, WebFocusType);
+ void SetFocused(bool, mojom::blink::FocusType);
void HandleEvent(Event&);
bool IsErrorplaceholder();
void EventListenersRemoved();
@@ -123,7 +124,6 @@ class CORE_EXPORT WebPluginContainerImpl final
void EnqueueMessageEvent(const WebDOMMessageEvent&) override;
void Invalidate() override;
void InvalidateRect(const WebRect&) override;
- void ScrollRect(const WebRect&) override;
void ScheduleAnimation() override;
void ReportGeometry() override;
v8::Local<v8::Object> V8ObjectForElement() override;
@@ -132,8 +132,8 @@ class CORE_EXPORT WebPluginContainerImpl final
bool IsRectTopmost(const WebRect&) override;
void RequestTouchEventType(TouchEventRequestType) override;
void SetWantsWheelEvents(bool) override;
- WebPoint RootFrameToLocalPoint(const WebPoint&) override;
- WebPoint LocalToRootFramePoint(const WebPoint&) override;
+ gfx::Point RootFrameToLocalPoint(const gfx::Point&) override;
+ gfx::Point LocalToRootFramePoint(const gfx::Point&) override;
// Non-Oilpan, this cannot be null. With Oilpan, it will be
// null when in a disposed state, pending finalization during the next GC.
@@ -186,7 +186,7 @@ class CORE_EXPORT WebPluginContainerImpl final
void DidFinishLoading();
void DidFailLoading(const ResourceError&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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(); }
@@ -239,18 +239,16 @@ class CORE_EXPORT WebPluginContainerImpl final
bool wants_wheel_events_;
};
-DEFINE_TYPE_CASTS(WebPluginContainerImpl,
- EmbeddedContentView,
- embedded_content_view,
- embedded_content_view->IsPluginView(),
- embedded_content_view.IsPluginView());
-// Unlike EmbeddedContentView, we need not worry about object type for
-// container. WebPluginContainerImpl is the only subclass of WebPluginContainer.
-DEFINE_TYPE_CASTS(WebPluginContainerImpl,
- WebPluginContainer,
- container,
- true,
- true);
+template <>
+struct DowncastTraits<WebPluginContainerImpl> {
+ static bool AllowFrom(const EmbeddedContentView& embedded_content_view) {
+ return embedded_content_view.IsPluginView();
+ }
+ // Unlike EmbeddedContentView, we need not worry about object type for
+ // container. WebPluginContainerImpl is the only subclass of
+ // WebPluginContainer.
+ static bool AllowFrom(const WebPluginContainer& container) { return true; }
+};
} // namespace blink
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 94928608fe8..67a0066eef8 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
@@ -37,9 +37,9 @@
#include "cc/layers/layer.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/frame/frame_owner_element_type.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/platform/web_coalesced_input_event.h"
-#include "third_party/blink/public/platform/web_mouse_wheel_event.h"
-#include "third_party/blink/public/platform/web_pointer_event.h"
#include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_element.h"
@@ -60,6 +60,7 @@
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/testing/fake_web_plugin.h"
+#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/core/testing/scoped_fake_plugin_registry.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h"
@@ -76,7 +77,7 @@ using blink::test::RunPendingTasks;
namespace blink {
-class WebPluginContainerTest : public testing::Test {
+class WebPluginContainerTest : public PageTestBase {
public:
WebPluginContainerTest() : base_url_("http://www.test.com/") {}
@@ -104,7 +105,7 @@ class WebPluginContainerTest : public testing::Test {
void UpdateAllLifecyclePhases(WebViewImpl* web_view) {
web_view->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
}
protected:
@@ -158,7 +159,7 @@ class TestPluginWithEditableText : public FakeWebPlugin {
public:
static TestPluginWithEditableText* FromContainer(WebElement* element) {
WebPlugin* plugin =
- ToWebPluginContainerImpl(element->PluginContainer())->Plugin();
+ To<WebPluginContainerImpl>(element->PluginContainer())->Plugin();
return static_cast<TestPluginWithEditableText*>(plugin);
}
@@ -221,6 +222,10 @@ class TestPluginWebFrameClient : public frame_test_helpers::TestWebFrameClient {
}
public:
+ TestPluginWebFrameClient() {
+ mock_clipboard_host_provider_.Install(*GetBrowserInterfaceBroker());
+ }
+
void OnPrintPage() { printed_page_ = true; }
bool PrintedAtLeastOnePage() const { return printed_page_; }
void SetHasEditableText(bool has_editable_text) {
@@ -230,6 +235,7 @@ class TestPluginWebFrameClient : public frame_test_helpers::TestWebFrameClient {
private:
bool printed_page_ = false;
bool has_editable_text_ = false;
+ PageTestBase::MockClipboardHostProvider mock_clipboard_host_provider_;
};
void TestPlugin::PrintPage(int page_number, cc::PaintCanvas* canvas) {
@@ -242,7 +248,7 @@ void EnablePlugins(WebView* web_view, const WebSize& size) {
web_view->GetSettings()->SetPluginsEnabled(true);
web_view->MainFrameWidget()->Resize(size);
web_view->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
RunPendingTasks();
}
@@ -253,17 +259,17 @@ WebPluginContainer* GetWebPluginContainer(WebViewImpl* web_view,
return element.PluginContainer();
}
-String ReadClipboard() {
+String ReadClipboard(LocalFrame& frame) {
// Run all tasks in a message loop to allow asynchronous clipboard writing
// to happen before reading from it synchronously.
test::RunPendingTasks();
- return SystemClipboard::GetInstance().ReadPlainText();
+ return frame.GetSystemClipboard()->ReadPlainText();
}
-void ClearClipboardBuffer() {
- SystemClipboard::GetInstance().WritePlainText(String(""));
- SystemClipboard::GetInstance().CommitWrite();
- EXPECT_EQ(String(""), ReadClipboard());
+void ClearClipboardBuffer(LocalFrame& frame) {
+ frame.GetSystemClipboard()->WritePlainText(String(""));
+ frame.GetSystemClipboard()->CommitWrite();
+ EXPECT_EQ(String(""), ReadClipboard(frame));
}
void CreateAndHandleKeyboardEvent(WebElement* plugin_container_one_element,
@@ -274,7 +280,7 @@ void CreateAndHandleKeyboardEvent(WebElement* plugin_container_one_element,
WebInputEvent::GetStaticTimeStampForTests());
web_keyboard_event.windows_key_code = key_code;
KeyboardEvent* key_event = KeyboardEvent::Create(web_keyboard_event, nullptr);
- ToWebPluginContainerImpl(plugin_container_one_element->PluginContainer())
+ To<WebPluginContainerImpl>(plugin_container_one_element->PluginContainer())
->HandleEvent(*key_event);
}
@@ -282,7 +288,7 @@ void ExecuteContextMenuCommand(WebViewImpl* web_view,
const WebString& command_name) {
auto event = frame_test_helpers::CreateMouseEvent(
WebMouseEvent::kMouseDown, WebMouseEvent::Button::kRight,
- WebPoint(30, 30), 0);
+ IntPoint(30, 30), 0);
event.click_count = 1;
web_view->MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(event));
@@ -304,26 +310,26 @@ TEST_F(WebPluginContainerTest, WindowToLocalPointTest) {
WebPluginContainer* plugin_container_one =
GetWebPluginContainer(web_view, WebString::FromUTF8("translated-plugin"));
DCHECK(plugin_container_one);
- WebPoint point1 =
- plugin_container_one->RootFrameToLocalPoint(WebPoint(10, 10));
- ASSERT_EQ(0, point1.x);
- ASSERT_EQ(0, point1.y);
- WebPoint point2 =
- plugin_container_one->RootFrameToLocalPoint(WebPoint(100, 100));
- ASSERT_EQ(90, point2.x);
- ASSERT_EQ(90, point2.y);
+ gfx::Point point1 =
+ plugin_container_one->RootFrameToLocalPoint(gfx::Point(10, 10));
+ ASSERT_EQ(0, point1.x());
+ ASSERT_EQ(0, point1.y());
+ gfx::Point point2 =
+ plugin_container_one->RootFrameToLocalPoint(gfx::Point(100, 100));
+ ASSERT_EQ(90, point2.x());
+ ASSERT_EQ(90, point2.y());
WebPluginContainer* plugin_container_two =
GetWebPluginContainer(web_view, WebString::FromUTF8("rotated-plugin"));
DCHECK(plugin_container_two);
- WebPoint point3 =
- plugin_container_two->RootFrameToLocalPoint(WebPoint(0, 10));
- ASSERT_EQ(10, point3.x);
- ASSERT_EQ(0, point3.y);
- WebPoint point4 =
- plugin_container_two->RootFrameToLocalPoint(WebPoint(-10, 10));
- ASSERT_EQ(10, point4.x);
- ASSERT_EQ(10, point4.y);
+ gfx::Point point3 =
+ plugin_container_two->RootFrameToLocalPoint(gfx::Point(0, 10));
+ ASSERT_EQ(10, point3.x());
+ ASSERT_EQ(0, point3.y());
+ gfx::Point point4 =
+ plugin_container_two->RootFrameToLocalPoint(gfx::Point(-10, 10));
+ ASSERT_EQ(10, point4.x());
+ ASSERT_EQ(10, point4.y());
}
TEST_F(WebPluginContainerTest, LocalToWindowPointTest) {
@@ -338,25 +344,26 @@ TEST_F(WebPluginContainerTest, LocalToWindowPointTest) {
WebPluginContainer* plugin_container_one =
GetWebPluginContainer(web_view, WebString::FromUTF8("translated-plugin"));
DCHECK(plugin_container_one);
- WebPoint point1 = plugin_container_one->LocalToRootFramePoint(WebPoint(0, 0));
- ASSERT_EQ(10, point1.x);
- ASSERT_EQ(10, point1.y);
- WebPoint point2 =
- plugin_container_one->LocalToRootFramePoint(WebPoint(90, 90));
- ASSERT_EQ(100, point2.x);
- ASSERT_EQ(100, point2.y);
+ gfx::Point point1 =
+ plugin_container_one->LocalToRootFramePoint(gfx::Point(0, 0));
+ ASSERT_EQ(10, point1.x());
+ ASSERT_EQ(10, point1.y());
+ gfx::Point point2 =
+ plugin_container_one->LocalToRootFramePoint(gfx::Point(90, 90));
+ ASSERT_EQ(100, point2.x());
+ ASSERT_EQ(100, point2.y());
WebPluginContainer* plugin_container_two =
GetWebPluginContainer(web_view, WebString::FromUTF8("rotated-plugin"));
DCHECK(plugin_container_two);
- WebPoint point3 =
- plugin_container_two->LocalToRootFramePoint(WebPoint(10, 0));
- ASSERT_EQ(0, point3.x);
- ASSERT_EQ(10, point3.y);
- WebPoint point4 =
- plugin_container_two->LocalToRootFramePoint(WebPoint(10, 10));
- ASSERT_EQ(-10, point4.x);
- ASSERT_EQ(10, point4.y);
+ gfx::Point point3 =
+ plugin_container_two->LocalToRootFramePoint(gfx::Point(10, 0));
+ ASSERT_EQ(0, point3.x());
+ ASSERT_EQ(10, point3.y());
+ gfx::Point point4 =
+ plugin_container_two->LocalToRootFramePoint(gfx::Point(10, 10));
+ ASSERT_EQ(-10, point4.x());
+ ASSERT_EQ(10, point4.y());
}
// Verifies executing the command 'Copy' results in copying to the clipboard.
@@ -376,8 +383,10 @@ TEST_F(WebPluginContainerTest, Copy) {
->getElementById("translated-plugin")
->focus();
EXPECT_TRUE(web_view->MainFrame()->ToWebLocalFrame()->ExecuteCommand("Copy"));
- EXPECT_EQ(String("x"), ReadClipboard());
- ClearClipboardBuffer();
+
+ LocalFrame* local_frame = web_view->MainFrameImpl()->GetFrame();
+ EXPECT_EQ(String("x"), ReadClipboard(*local_frame));
+ ClearClipboardBuffer(*local_frame);
}
TEST_F(WebPluginContainerTest, CopyFromContextMenu) {
@@ -391,24 +400,27 @@ TEST_F(WebPluginContainerTest, CopyFromContextMenu) {
// Make sure the right-click + command works in common scenario.
ExecuteContextMenuCommand(web_view, "Copy");
- EXPECT_EQ(String("x"), ReadClipboard());
- ClearClipboardBuffer();
+
+ LocalFrame* local_frame = web_view->MainFrameImpl()->GetFrame();
+ EXPECT_EQ(String("x"), ReadClipboard(*local_frame));
+ ClearClipboardBuffer(*local_frame);
auto event = frame_test_helpers::CreateMouseEvent(
WebMouseEvent::kMouseDown, WebMouseEvent::Button::kRight,
- WebPoint(30, 30), 0);
+ IntPoint(30, 30), 0);
event.click_count = 1;
// Now, let's try a more complex scenario:
// 1) open the context menu. This will focus the plugin.
web_view->MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(event));
// 2) document blurs the plugin, because it can.
- web_view->ClearFocusedElement();
+ web_view->FocusedElement()->blur();
// 3) Copy should still operate on the context node, even though the focus had
// shifted.
EXPECT_TRUE(web_view->MainFrameImpl()->ExecuteCommand("Copy"));
- EXPECT_EQ(String("x"), ReadClipboard());
- ClearClipboardBuffer();
+
+ EXPECT_EQ(String("x"), ReadClipboard(*local_frame));
+ ClearClipboardBuffer(*local_frame);
}
// Verifies |Ctrl-C| and |Ctrl-Insert| keyboard events, results in copying to
@@ -429,13 +441,14 @@ TEST_F(WebPluginContainerTest, CopyInsertKeyboardEventsTest) {
kEditingModifier | WebInputEvent::kNumLockOn | WebInputEvent::kIsLeft);
CreateAndHandleKeyboardEvent(&plugin_container_one_element, modifier_key,
VKEY_C);
- EXPECT_EQ(String("x"), ReadClipboard());
- ClearClipboardBuffer();
+ LocalFrame* local_frame = web_view->MainFrameImpl()->GetFrame();
+ EXPECT_EQ(String("x"), ReadClipboard(*local_frame));
+ ClearClipboardBuffer(*local_frame);
CreateAndHandleKeyboardEvent(&plugin_container_one_element, modifier_key,
VKEY_INSERT);
- EXPECT_EQ(String("x"), ReadClipboard());
- ClearClipboardBuffer();
+ EXPECT_EQ(String("x"), ReadClipboard(*local_frame));
+ ClearClipboardBuffer(*local_frame);
}
// Verifies |Ctrl-X| and |Shift-Delete| keyboard events, results in the "Cut"
@@ -634,7 +647,7 @@ class EventTestPlugin : public FakeWebPlugin {
WebInputEventResult HandleInputEvent(
const WebCoalescedInputEvent& coalesced_event,
- WebCursorInfo&) override {
+ ui::Cursor*) override {
const WebInputEvent& event = coalesced_event.Event();
coalesced_event_count_ = coalesced_event.CoalescedEventSize();
last_event_type_ = event.GetType();
@@ -643,15 +656,15 @@ class EventTestPlugin : public FakeWebPlugin {
event.GetType() == WebInputEvent::kMouseWheel) {
const WebMouseEvent& mouse_event =
static_cast<const WebMouseEvent&>(event);
- last_event_location_ = IntPoint(mouse_event.PositionInWidget().x,
- mouse_event.PositionInWidget().y);
+ last_event_location_ = IntPoint(mouse_event.PositionInWidget().x(),
+ mouse_event.PositionInWidget().y());
} else if (WebInputEvent::IsTouchEventType(event.GetType())) {
const WebTouchEvent& touch_event =
static_cast<const WebTouchEvent&>(event);
if (touch_event.touches_length == 1) {
last_event_location_ =
- IntPoint(touch_event.touches[0].PositionInWidget().x,
- touch_event.touches[0].PositionInWidget().y);
+ IntPoint(touch_event.touches[0].PositionInWidget().x(),
+ touch_event.touches[0].PositionInWidget().y());
} else {
last_event_location_ = IntPoint();
}
@@ -702,7 +715,7 @@ TEST_F(WebPluginContainerTest, GestureLongPressReachesPlugin) {
// First, send an event that doesn't hit the plugin to verify that the
// plugin doesn't receive it.
- event.SetPositionInWidget(WebFloatPoint(0, 0));
+ event.SetPositionInWidget(gfx::PointF());
web_view->MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(event));
RunPendingTasks();
@@ -713,7 +726,7 @@ TEST_F(WebPluginContainerTest, GestureLongPressReachesPlugin) {
// it.
WebRect rect = plugin_container_one_element.BoundsInViewport();
event.SetPositionInWidget(
- WebFloatPoint(rect.x + rect.width / 2, rect.y + rect.height / 2));
+ gfx::PointF(rect.x + rect.width / 2, rect.y + rect.height / 2));
web_view->MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(event));
RunPendingTasks();
@@ -741,7 +754,7 @@ TEST_F(WebPluginContainerTest, MouseEventButtons) {
WebMouseEvent event = frame_test_helpers::CreateMouseEvent(
WebMouseEvent::kMouseMove, WebMouseEvent::Button::kNoButton,
- WebPoint(30, 30),
+ IntPoint(30, 30),
WebInputEvent::kMiddleButtonDown | WebInputEvent::kShiftKey);
WebRect rect = plugin_container_one_element.BoundsInViewport();
@@ -815,8 +828,8 @@ TEST_F(WebPluginContainerTest, TouchEventScrolled) {
WebPointerProperties(
1, WebPointerProperties::PointerType::kTouch,
WebPointerProperties::Button::kLeft,
- WebFloatPoint(rect.x + rect.width / 2, rect.y + rect.height / 2),
- WebFloatPoint(rect.x + rect.width / 2, rect.y + rect.height / 2)),
+ gfx::PointF(rect.x + rect.width / 2, rect.y + rect.height / 2),
+ gfx::PointF(rect.x + rect.width / 2, rect.y + rect.height / 2)),
1.0f, 1.0f);
web_view->MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(event));
@@ -857,8 +870,8 @@ TEST_F(WebPluginContainerTest, TouchEventScrolledWithCoalescedTouches) {
WebPointerProperties(
1, WebPointerProperties::PointerType::kTouch,
WebPointerProperties::Button::kLeft,
- WebFloatPoint(rect.x + rect.width / 2, rect.y + rect.height / 2),
- WebFloatPoint(rect.x + rect.width / 2, rect.y + rect.height / 2)),
+ gfx::PointF(rect.x + rect.width / 2, rect.y + rect.height / 2),
+ gfx::PointF(rect.x + rect.width / 2, rect.y + rect.height / 2)),
1.0f, 1.0f);
WebCoalescedInputEvent coalesced_event(event);
@@ -880,10 +893,10 @@ TEST_F(WebPluginContainerTest, TouchEventScrolledWithCoalescedTouches) {
WebInputEvent::kPointerMove,
WebPointerProperties(1, WebPointerProperties::PointerType::kTouch,
WebPointerProperties::Button::kLeft,
- WebFloatPoint(rect.x + rect.width / 2 + 1,
- rect.y + rect.height / 2 + 1),
- WebFloatPoint(rect.x + rect.width / 2 + 1,
- rect.y + rect.height / 2 + 1)),
+ gfx::PointF(rect.x + rect.width / 2 + 1,
+ rect.y + rect.height / 2 + 1),
+ gfx::PointF(rect.x + rect.width / 2 + 1,
+ rect.y + rect.height / 2 + 1)),
1.0f, 1.0f);
WebCoalescedInputEvent coalesced_event(event1);
@@ -892,19 +905,19 @@ TEST_F(WebPluginContainerTest, TouchEventScrolledWithCoalescedTouches) {
WebInputEvent::kPointerMove,
WebPointerProperties(1, WebPointerProperties::PointerType::kTouch,
WebPointerProperties::Button::kLeft,
- WebFloatPoint(rect.x + rect.width / 2 + 2,
- rect.y + rect.height / 2 + 2),
- WebFloatPoint(rect.x + rect.width / 2 + 2,
- rect.y + rect.height / 2 + 2)),
+ gfx::PointF(rect.x + rect.width / 2 + 2,
+ rect.y + rect.height / 2 + 2),
+ gfx::PointF(rect.x + rect.width / 2 + 2,
+ rect.y + rect.height / 2 + 2)),
1.0f, 1.0f);
WebPointerEvent event3(
WebInputEvent::kPointerMove,
WebPointerProperties(1, WebPointerProperties::PointerType::kTouch,
WebPointerProperties::Button::kLeft,
- WebFloatPoint(rect.x + rect.width / 2 + 3,
- rect.y + rect.height / 2 + 3),
- WebFloatPoint(rect.x + rect.width / 2 + 3,
- rect.y + rect.height / 2 + 3)),
+ gfx::PointF(rect.x + rect.width / 2 + 3,
+ rect.y + rect.height / 2 + 3),
+ gfx::PointF(rect.x + rect.width / 2 + 3,
+ rect.y + rect.height / 2 + 3)),
1.0f, 1.0f);
coalesced_event.AddCoalescedEvent(event2);
@@ -1109,8 +1122,8 @@ TEST_F(WebPluginContainerTest, TouchEventZoomed) {
WebPointerProperties(
1, WebPointerProperties::PointerType::kTouch,
WebPointerProperties::Button::kLeft,
- WebFloatPoint(rect.x + rect.width / 2, rect.y + rect.height / 2),
- WebFloatPoint(rect.x + rect.width / 2, rect.y + rect.height / 2)),
+ gfx::PointF(rect.x + rect.width / 2, rect.y + rect.height / 2),
+ gfx::PointF(rect.x + rect.width / 2, rect.y + rect.height / 2)),
1.0f, 1.0f);
web_view->MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(event));
@@ -1134,8 +1147,8 @@ TEST_F(WebPluginContainerTest, IsRectTopmostTest) {
base_url_ + "plugin_container.html", &plugin_web_frame_client);
EnablePlugins(web_view, WebSize(300, 300));
- WebPluginContainerImpl* plugin_container_impl =
- ToWebPluginContainerImpl(GetWebPluginContainer(
+ auto* plugin_container_impl =
+ To<WebPluginContainerImpl>(GetWebPluginContainer(
web_view, WebString::FromUTF8("translated-plugin")));
plugin_container_impl->SetFrameRect(IntRect(0, 0, 300, 300));
@@ -1158,15 +1171,15 @@ TEST_F(WebPluginContainerTest, IsRectTopmostTestWithOddAndEvenDimensions) {
base_url_ + "plugin_container.html", &plugin_web_frame_client);
EnablePlugins(web_view, WebSize(300, 300));
- WebPluginContainerImpl* even_plugin_container_impl =
- ToWebPluginContainerImpl(GetWebPluginContainer(
+ auto* even_plugin_container_impl =
+ To<WebPluginContainerImpl>(GetWebPluginContainer(
web_view, WebString::FromUTF8("translated-plugin")));
even_plugin_container_impl->SetFrameRect(IntRect(0, 0, 300, 300));
auto even_rect = even_plugin_container_impl->GetElement().BoundsInViewport();
EXPECT_TRUE(even_plugin_container_impl->IsRectTopmost(even_rect));
- WebPluginContainerImpl* odd_plugin_container_impl =
- ToWebPluginContainerImpl(GetWebPluginContainer(
+ auto* odd_plugin_container_impl =
+ To<WebPluginContainerImpl>(GetWebPluginContainer(
web_view, WebString::FromUTF8("odd-dimensions-plugin")));
odd_plugin_container_impl->SetFrameRect(IntRect(0, 0, 300, 300));
auto odd_rect = odd_plugin_container_impl->GetElement().BoundsInViewport();
@@ -1189,8 +1202,8 @@ TEST_F(WebPluginContainerTest, ClippedRectsForIframedElement) {
->ToWebLocalFrame()
->GetDocument()
.GetElementById("translated-plugin");
- WebPluginContainerImpl* plugin_container_impl =
- ToWebPluginContainerImpl(plugin_element.PluginContainer());
+ auto* plugin_container_impl =
+ To<WebPluginContainerImpl>(plugin_element.PluginContainer());
DCHECK(plugin_container_impl);
@@ -1221,8 +1234,8 @@ TEST_F(WebPluginContainerTest, ClippedRectsForShiftedIframedElement) {
web_view->MainFrame()->FirstChild()->ToWebLocalFrame();
WebElement plugin_element =
iframe->GetDocument().GetElementById("plugin-hidden-before-scroll");
- WebPluginContainerImpl* plugin_container_impl =
- ToWebPluginContainerImpl(plugin_element.PluginContainer());
+ auto* plugin_container_impl =
+ To<WebPluginContainerImpl>(plugin_element.PluginContainer());
DCHECK(plugin_container_impl);
@@ -1315,8 +1328,8 @@ TEST_F(WebPluginContainerTest, ClippedRectsForSubpixelPositionedPlugin) {
WebElement plugin_element =
web_view->MainFrameImpl()->GetDocument().GetElementById(
"subpixel-positioned-plugin");
- WebPluginContainerImpl* plugin_container_impl =
- ToWebPluginContainerImpl(plugin_element.PluginContainer());
+ auto* plugin_container_impl =
+ To<WebPluginContainerImpl>(plugin_element.PluginContainer());
DCHECK(plugin_container_impl);
@@ -1360,8 +1373,8 @@ TEST_F(WebPluginContainerTest, TopmostAfterDetachTest) {
base_url_ + "plugin_container.html", &plugin_web_frame_client);
EnablePlugins(web_view, WebSize(300, 300));
- WebPluginContainerImpl* plugin_container_impl =
- ToWebPluginContainerImpl(GetWebPluginContainer(
+ auto* plugin_container_impl =
+ To<WebPluginContainerImpl>(GetWebPluginContainer(
web_view, WebString::FromUTF8("translated-plugin")));
plugin_container_impl->SetFrameRect(IntRect(0, 0, 300, 300));
@@ -1426,7 +1439,7 @@ TEST_F(WebPluginContainerTest, CompositedPluginCAP) {
auto paint_controller = std::make_unique<PaintController>();
paint_controller->UpdateCurrentPaintChunkProperties(
- base::nullopt, PropertyTreeState::Root());
+ nullptr, PropertyTreeState::Root());
GraphicsContext graphics_context(*paint_controller);
container->Paint(graphics_context, kGlobalPaintNormalPhase,
CullRect(IntRect(10, 10, 400, 300)));
diff --git a/chromium/third_party/blink/renderer/core/exported/web_plugin_document.cc b/chromium/third_party/blink/renderer/core/exported/web_plugin_document.cc
index 4bc1e22cf48..6a553490f86 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_plugin_document.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_plugin_document.cc
@@ -50,7 +50,7 @@ WebPluginDocument::WebPluginDocument(PluginDocument* elem)
DEFINE_WEB_NODE_TYPE_CASTS(WebPluginDocument,
IsDocumentNode() &&
- ConstUnwrap<Document>()->IsPluginDocument())
+ IsA<PluginDocument>(ConstUnwrap<Document>()))
WebPluginDocument& WebPluginDocument::operator=(PluginDocument* elem) {
private_ = elem;
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 401affe3e8e..56ec1b3c20e 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
@@ -7,10 +7,10 @@
#include <utility>
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
#include "third_party/blink/public/platform/web_float_rect.h"
#include "third_party/blink/public/platform/web_intrinsic_sizing_info.h"
#include "third_party/blink/public/platform/web_rect.h"
-#include "third_party/blink/public/platform/web_scroll_into_view_params.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_frame_owner_properties.h"
#include "third_party/blink/public/web/web_performance.h"
@@ -34,8 +34,6 @@
#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/timing/dom_window_performance.h"
-#include "third_party/blink/renderer/core/timing/window_performance.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
#include "third_party/blink/renderer/platform/geometry/float_quad.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
@@ -46,15 +44,6 @@
namespace blink {
-namespace {
-FloatRect DeNormalizeRect(const WebFloatRect& normalized, const IntRect& base) {
- FloatRect result = normalized;
- result.Scale(base.Width(), base.Height());
- result.MoveBy(FloatPoint(base.Location()));
- return result;
-}
-} // namespace
-
WebRemoteFrame* WebRemoteFrame::Create(
WebTreeScopeType scope,
WebRemoteFrameClient* client,
@@ -133,7 +122,7 @@ WebRemoteFrameImpl* WebRemoteFrameImpl::CreateForPortal(
WebRemoteFrameImpl::~WebRemoteFrameImpl() = default;
-void WebRemoteFrameImpl::Trace(blink::Visitor* visitor) {
+void WebRemoteFrameImpl::Trace(Visitor* visitor) {
visitor->Trace(frame_client_);
visitor->Trace(frame_);
WebFrame::TraceFrames(visitor, this);
@@ -191,10 +180,16 @@ WebLocalFrame* WebRemoteFrameImpl::CreateLocalChild(
InsertAfter(child, previous_sibling);
auto* owner = MakeGarbageCollected<RemoteFrameOwner>(
frame_policy, frame_owner_properties, frame_owner_element_type);
+
+ WindowAgentFactory* window_agent_factory = nullptr;
+ if (opener) {
+ window_agent_factory = &ToCoreFrame(*opener)->window_agent_factory();
+ } else if (!frame_policy.disallow_document_access) {
+ window_agent_factory = &GetFrame()->window_agent_factory();
+ }
+
child->InitializeCoreFrame(*GetFrame()->GetPage(), owner, name,
- opener
- ? &ToCoreFrame(*opener)->window_agent_factory()
- : &GetFrame()->window_agent_factory());
+ window_agent_factory);
DCHECK(child->GetFrame());
return child;
}
@@ -226,10 +221,15 @@ WebRemoteFrame* WebRemoteFrameImpl::CreateRemoteChild(
AppendChild(child);
auto* owner = MakeGarbageCollected<RemoteFrameOwner>(
frame_policy, WebFrameOwnerProperties(), frame_owner_element_type);
+ WindowAgentFactory* window_agent_factory = nullptr;
+ if (opener) {
+ window_agent_factory = &ToCoreFrame(*opener)->window_agent_factory();
+ } else if (!frame_policy.disallow_document_access) {
+ window_agent_factory = &GetFrame()->window_agent_factory();
+ }
+
child->InitializeCoreFrame(*GetFrame()->GetPage(), owner, name,
- opener
- ? &ToCoreFrame(*opener)->window_agent_factory()
- : &GetFrame()->window_agent_factory());
+ window_agent_factory);
return child;
}
@@ -260,10 +260,10 @@ void WebRemoteFrameImpl::SetReplicatedOrigin(
is_potentially_trustworthy_opaque_origin);
}
-void WebRemoteFrameImpl::SetReplicatedSandboxFlags(WebSandboxFlags flags) {
+void WebRemoteFrameImpl::SetReplicatedSandboxFlags(
+ mojom::blink::WebSandboxFlags flags) {
DCHECK(GetFrame());
- GetFrame()->GetSecurityContext()->ResetAndEnforceSandboxFlags(
- static_cast<SandboxFlags>(flags));
+ GetFrame()->SetReplicatedSandboxFlags(flags);
}
void WebRemoteFrameImpl::SetReplicatedName(const WebString& name) {
@@ -286,58 +286,33 @@ void WebRemoteFrameImpl::AddReplicatedContentSecurityPolicyHeader(
GetFrame()
->GetSecurityContext()
->GetContentSecurityPolicy()
- ->AddPolicyFromHeaderValue(
- header_value, static_cast<ContentSecurityPolicyHeaderType>(type),
- static_cast<ContentSecurityPolicyHeaderSource>(source));
+ ->AddPolicyFromHeaderValue(header_value, type, source);
}
void WebRemoteFrameImpl::ResetReplicatedContentSecurityPolicy() {
- GetFrame()->GetSecurityContext()->ResetReplicatedContentSecurityPolicy();
+ GetFrame()->ResetReplicatedContentSecurityPolicy();
}
void WebRemoteFrameImpl::SetReplicatedInsecureRequestPolicy(
- WebInsecureRequestPolicy policy) {
+ mojom::blink::InsecureRequestPolicy policy) {
DCHECK(GetFrame());
- GetFrame()->GetSecurityContext()->SetInsecureRequestPolicy(policy);
+ GetFrame()->SetInsecureRequestPolicy(policy);
}
void WebRemoteFrameImpl::SetReplicatedInsecureNavigationsSet(
const WebVector<unsigned>& set) {
DCHECK(GetFrame());
- GetFrame()->GetSecurityContext()->SetInsecureNavigationsSet(set);
-}
-
-void WebRemoteFrameImpl::ForwardResourceTimingToParent(
- const WebResourceTimingInfo& info) {
- auto* parent_frame = To<WebLocalFrameImpl>(Parent()->ToWebLocalFrame());
- HTMLFrameOwnerElement* owner_element =
- To<HTMLFrameOwnerElement>(frame_->Owner());
- DCHECK(owner_element);
- // TODO(https://crbug.com/900700): Take a Mojo pending receiver for
- // WorkerTimingContainer for navigation from the calling function.
- DOMWindowPerformance::performance(*parent_frame->GetFrame()->DomWindow())
- ->AddResourceTiming(info, owner_element->localName(),
- mojo::NullReceiver() /* worker_timing_receiver */);
+ GetFrame()->SetInsecureNavigationsSet(set);
}
-void WebRemoteFrameImpl::SetNeedsOcclusionTracking(bool needs_tracking) {
- GetFrame()->View()->SetNeedsOcclusionTracking(needs_tracking);
+void WebRemoteFrameImpl::SetReplicatedAdFrameType(
+ mojom::blink::AdFrameType ad_frame_type) {
+ DCHECK(GetFrame());
+ GetFrame()->SetReplicatedAdFrameType(ad_frame_type);
}
void WebRemoteFrameImpl::DidStartLoading() {
- GetFrame()->SetIsLoading(true);
-}
-
-void WebRemoteFrameImpl::DidStopLoading() {
- GetFrame()->SetIsLoading(false);
-
- // When a subframe finishes loading, the parent should check if *all*
- // subframes have finished loading (which may mean that the parent can declare
- // that the parent itself has finished loading). This remote-subframe-focused
- // code has a local-subframe equivalent in FrameLoader::DidFinishNavigation.
- Frame* parent = GetFrame()->Tree().Parent();
- if (parent)
- parent->CheckCompleted();
+ GetFrame()->DidStartLoading();
}
bool WebRemoteFrameImpl::IsIgnoredForHitTest() const {
@@ -345,105 +320,19 @@ bool WebRemoteFrameImpl::IsIgnoredForHitTest() const {
}
void WebRemoteFrameImpl::UpdateUserActivationState(
- UserActivationUpdateType update_type) {
- switch (update_type) {
- case UserActivationUpdateType::kNotifyActivation:
- GetFrame()->NotifyUserActivationInLocalTree();
- break;
- case UserActivationUpdateType::kConsumeTransientActivation:
- GetFrame()->ConsumeTransientUserActivationInLocalTree();
- break;
- case UserActivationUpdateType::kClearActivation:
- GetFrame()->ClearUserActivationInLocalTree();
- break;
- case UserActivationUpdateType::kNotifyActivationPendingBrowserVerification:
- NOTREACHED() << "Unexpected UserActivationUpdateType from browser";
- break;
- }
+ mojom::blink::UserActivationUpdateType update_type) {
+ GetFrame()->UpdateUserActivationState(update_type);
}
void WebRemoteFrameImpl::TransferUserActivationFrom(
blink::WebRemoteFrame* source_frame) {
GetFrame()->TransferUserActivationFrom(
- ToWebRemoteFrameImpl(source_frame)->GetFrame());
-}
-
-void WebRemoteFrameImpl::ScrollRectToVisible(
- const WebRect& rect_to_scroll,
- const WebScrollIntoViewParams& params) {
- Element* owner_element = frame_->DeprecatedLocalOwner();
- LayoutObject* owner_object = owner_element->GetLayoutObject();
- if (!owner_object) {
- // The LayoutObject could be nullptr by the time we get here. For instance
- // <iframe>'s style might have been set to 'display: none' right after
- // scrolling starts in the OOPIF's process (see https://crbug.com/777811).
- return;
- }
-
- // Schedule the scroll.
- PhysicalRect absolute_rect = owner_object->LocalToAncestorRect(
- PhysicalRect(rect_to_scroll), owner_object->View());
-
- if (!params.zoom_into_rect ||
- !owner_object->GetDocument().GetFrame()->LocalFrameRoot().IsMainFrame()) {
- owner_object->ScrollRectToVisible(absolute_rect, params);
- return;
- }
+ To<WebRemoteFrameImpl>(source_frame)->GetFrame());
+}
- // ZoomAndScrollToFocusedEditableElementRect will scroll only the layout and
- // visual viewports. Ensure the element is actually visible in the viewport
- // scrolling layer. (i.e. isn't clipped by some other content).
- WebScrollIntoViewParams new_params(params);
- new_params.stop_at_main_frame_layout_viewport = true;
- absolute_rect = owner_object->ScrollRectToVisible(absolute_rect, new_params);
-
- // This is due to something such as scroll focused editable element into
- // view on Android which also requires an automatic zoom into legible scale.
- // This is handled by main frame's WebView.
- WebViewImpl* view_impl = static_cast<WebViewImpl*>(View());
- IntRect rect_in_document =
- view_impl->MainFrameImpl()->GetFrame()->View()->RootFrameToDocument(
- EnclosingIntRect(
- owner_element->GetDocument().View()->ConvertToRootFrame(
- absolute_rect)));
- IntRect element_bounds_in_document = EnclosingIntRect(
- DeNormalizeRect(params.relative_element_bounds, rect_in_document));
- IntRect caret_bounds_in_document = EnclosingIntRect(
- DeNormalizeRect(params.relative_caret_bounds, rect_in_document));
- view_impl->ZoomAndScrollToFocusedEditableElementRect(
- element_bounds_in_document, caret_bounds_in_document, true);
-}
-
-void WebRemoteFrameImpl::BubbleLogicalScroll(WebScrollDirection direction,
- ScrollGranularity granularity) {
- Frame* parent_frame = GetFrame()->Tree().Parent();
- DCHECK(parent_frame);
- DCHECK(parent_frame->IsLocalFrame());
-
- parent_frame->BubbleLogicalScrollFromChildFrame(direction, granularity,
- GetFrame());
-}
-
-void WebRemoteFrameImpl::IntrinsicSizingInfoChanged(
- const WebIntrinsicSizingInfo& web_sizing_info) {
- FrameOwner* owner = GetFrame()->Owner();
- // Only communication from HTMLPluginElement-owned subframes is allowed
- // at present. This includes <embed> and <object> tags.
- if (!owner || !owner->IsPlugin())
- return;
-
- IntrinsicSizingInfo sizing_info;
- sizing_info.size = web_sizing_info.size;
- sizing_info.aspect_ratio = web_sizing_info.aspect_ratio;
- sizing_info.has_width = web_sizing_info.has_width;
- sizing_info.has_height = web_sizing_info.has_height;
- frame_->View()->SetIntrinsicSizeInfo(sizing_info);
-
- owner->IntrinsicSizingInfoChanged();
-}
-
-void WebRemoteFrameImpl::SetHasReceivedUserGestureBeforeNavigation(bool value) {
- GetFrame()->SetDocumentHasReceivedUserGestureBeforeNavigation(value);
+void WebRemoteFrameImpl::SetHadStickyUserActivationBeforeNavigation(
+ bool value) {
+ GetFrame()->SetHadStickyUserActivationBeforeNavigation(value);
}
v8::Local<v8::Object> WebRemoteFrameImpl::GlobalProxy() const {
@@ -456,15 +345,6 @@ WebRect WebRemoteFrameImpl::GetCompositingRect() {
return GetFrame()->View()->GetCompositingRect();
}
-void WebRemoteFrameImpl::RenderFallbackContent() const {
- // TODO(ekaramad): If the owner renders its own content, then the current
- // ContentFrame() should detach and free-up the OOPIF process (see
- // https://crbug.com/850223).
- auto* owner = frame_->DeprecatedLocalOwner();
- DCHECK(IsA<HTMLObjectElement>(owner));
- owner->RenderFallbackContent(frame_);
-}
-
WebRemoteFrameImpl::WebRemoteFrameImpl(
WebTreeScopeType scope,
WebRemoteFrameClient* client,
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 fc8045ec76b..defdadc82b4 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
@@ -5,12 +5,14 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_REMOTE_FRAME_IMPL_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_REMOTE_FRAME_IMPL_H_
-#include "third_party/blink/public/platform/web_insecure_request_policy.h"
+#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom-blink-forward.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink-forward.h"
#include "third_party/blink/public/web/web_remote_frame.h"
#include "third_party/blink/public/web/web_remote_frame_client.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/frame/remote_frame.h"
#include "third_party/blink/renderer/platform/heap/self_keep_alive.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace cc {
class Layer;
@@ -24,7 +26,6 @@ class RemoteFrameClientImpl;
enum class WebFrameLoadType;
class WebView;
struct WebRect;
-struct WebScrollIntoViewParams;
class WindowAgentFactory;
class CORE_EXPORT WebRemoteFrameImpl final
@@ -77,7 +78,7 @@ class CORE_EXPORT WebRemoteFrameImpl final
void SetReplicatedOrigin(
const WebSecurityOrigin&,
bool is_potentially_trustworthy_opaque_origin) override;
- void SetReplicatedSandboxFlags(WebSandboxFlags) override;
+ void SetReplicatedSandboxFlags(mojom::blink::WebSandboxFlags) override;
void SetReplicatedName(const WebString&) override;
void SetReplicatedFeaturePolicyHeaderAndOpenerPolicies(
const ParsedFeaturePolicy& parsed_header,
@@ -87,24 +88,19 @@ class CORE_EXPORT WebRemoteFrameImpl final
network::mojom::ContentSecurityPolicyType,
network::mojom::ContentSecurityPolicySource) override;
void ResetReplicatedContentSecurityPolicy() override;
- void SetReplicatedInsecureRequestPolicy(WebInsecureRequestPolicy) override;
+ void SetReplicatedInsecureRequestPolicy(
+ mojom::blink::InsecureRequestPolicy) override;
void SetReplicatedInsecureNavigationsSet(const WebVector<unsigned>&) override;
- void ForwardResourceTimingToParent(const WebResourceTimingInfo&) override;
- void SetNeedsOcclusionTracking(bool) override;
+ void SetReplicatedAdFrameType(
+ mojom::blink::AdFrameType ad_frame_type) override;
void DidStartLoading() override;
- void DidStopLoading() override;
bool IsIgnoredForHitTest() const override;
- void UpdateUserActivationState(UserActivationUpdateType) override;
+ void UpdateUserActivationState(
+ mojom::blink::UserActivationUpdateType) override;
void TransferUserActivationFrom(blink::WebRemoteFrame* source_frame) override;
- void ScrollRectToVisible(const WebRect&,
- const WebScrollIntoViewParams&) override;
- void BubbleLogicalScroll(WebScrollDirection direction,
- ScrollGranularity granularity) override;
- void IntrinsicSizingInfoChanged(const WebIntrinsicSizingInfo&) override;
- void SetHasReceivedUserGestureBeforeNavigation(bool value) override;
+ void SetHadStickyUserActivationBeforeNavigation(bool value) override;
v8::Local<v8::Object> GlobalProxy() const override;
WebRect GetCompositingRect() override;
- void RenderFallbackContent() const override;
void InitializeCoreFrame(Page&,
FrameOwner*,
@@ -116,7 +112,7 @@ class CORE_EXPORT WebRemoteFrameImpl final
static WebRemoteFrameImpl* FromFrame(RemoteFrame&);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
friend class RemoteFrameClientImpl;
@@ -144,11 +140,12 @@ class CORE_EXPORT WebRemoteFrameImpl final
SelfKeepAlive<WebRemoteFrameImpl> self_keep_alive_;
};
-DEFINE_TYPE_CASTS(WebRemoteFrameImpl,
- WebFrame,
- frame,
- frame->IsWebRemoteFrame(),
- frame.IsWebRemoteFrame());
+template <>
+struct DowncastTraits<WebRemoteFrameImpl> {
+ static bool AllowFrom(const WebFrame& frame) {
+ return frame.IsWebRemoteFrame();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/exported/web_scoped_user_gesture.cc b/chromium/third_party/blink/renderer/core/exported/web_scoped_user_gesture.cc
deleted file mode 100644
index ac3f7aa9a9b..00000000000
--- a/chromium/third_party/blink/renderer/core/exported/web_scoped_user_gesture.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2011 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/public/web/web_scoped_user_gesture.h"
-
-#include "third_party/blink/renderer/core/frame/local_frame.h"
-#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
-
-namespace blink {
-
-WebScopedUserGesture::WebScopedUserGesture(WebLocalFrame* frame) {
- LocalFrame::NotifyUserActivation(
- frame ? To<WebLocalFrameImpl>(frame)->GetFrame() : nullptr);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/exported/web_scoped_window_focus_allowed_indicator.cc b/chromium/third_party/blink/renderer/core/exported/web_scoped_window_focus_allowed_indicator.cc
index fa40c6ba49d..549eef50079 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_scoped_window_focus_allowed_indicator.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_scoped_window_focus_allowed_indicator.cc
@@ -40,7 +40,8 @@ WebScopedWindowFocusAllowedIndicator::WebScopedWindowFocusAllowedIndicator(
WebDocument* web_document) {
Document* document = web_document->Unwrap<Document>();
DCHECK(document);
- private_.reset(new ScopedWindowFocusAllowedIndicator(document));
+ private_.reset(
+ new ScopedWindowFocusAllowedIndicator(document->ToExecutionContext()));
}
WebScopedWindowFocusAllowedIndicator::~WebScopedWindowFocusAllowedIndicator() =
diff --git a/chromium/third_party/blink/renderer/core/exported/web_scoped_window_focus_allowed_indicator_test.cc b/chromium/third_party/blink/renderer/core/exported/web_scoped_window_focus_allowed_indicator_test.cc
index eab4348567f..be2e44fd906 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_scoped_window_focus_allowed_indicator_test.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_scoped_window_focus_allowed_indicator_test.cc
@@ -33,25 +33,27 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
TEST(WebScopedWindowFocusAllowedIndicatorTest, Basic) {
- Persistent<Document> document = MakeGarbageCollected<Document>();
+ auto dummy = std::make_unique<DummyPageHolder>();
+ auto* document = &dummy->GetDocument();
WebDocument web_document(document);
- EXPECT_FALSE(document->IsWindowInteractionAllowed());
+ EXPECT_FALSE(document->ToExecutionContext()->IsWindowInteractionAllowed());
{
WebScopedWindowFocusAllowedIndicator indicator1(&web_document);
- EXPECT_TRUE(document->IsWindowInteractionAllowed());
+ EXPECT_TRUE(document->ToExecutionContext()->IsWindowInteractionAllowed());
{
WebScopedWindowFocusAllowedIndicator indicator2(&web_document);
- EXPECT_TRUE(document->IsWindowInteractionAllowed());
+ EXPECT_TRUE(document->ToExecutionContext()->IsWindowInteractionAllowed());
}
- EXPECT_TRUE(document->IsWindowInteractionAllowed());
+ EXPECT_TRUE(document->ToExecutionContext()->IsWindowInteractionAllowed());
}
- EXPECT_FALSE(document->IsWindowInteractionAllowed());
+ EXPECT_FALSE(document->ToExecutionContext()->IsWindowInteractionAllowed());
}
} // 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 ce3bb3a1647..075b02ab8d5 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
@@ -770,6 +770,11 @@ void WebSettingsImpl::SetForceDarkModeEnabled(bool enabled) {
settings_->SetForceDarkModeEnabled(enabled);
}
+void WebSettingsImpl::SetPreferredColorScheme(
+ PreferredColorScheme color_scheme) {
+ settings_->SetPreferredColorScheme(color_scheme);
+}
+
void WebSettingsImpl::SetNavigationControls(
NavigationControls navigation_controls) {
settings_->SetNavigationControls(navigation_controls);
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 9720f986cca..deb6bb33e14 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
@@ -220,6 +220,7 @@ class CORE_EXPORT WebSettingsImpl final : public WebSettings {
void SetLazyImageFirstKFullyLoad4G(int) override;
void SetForceDarkModeEnabled(bool) override;
+ void SetPreferredColorScheme(PreferredColorScheme) override;
void SetNavigationControls(NavigationControls) override;
bool RenderVSyncNotificationEnabled() const {
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 aa09f9c3cc4..7582cdbd3a1 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,10 +31,14 @@
#include "third_party/blink/renderer/core/exported/web_shared_worker_impl.h"
#include <memory>
+#include "base/memory/ptr_util.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "services/network/public/mojom/fetch_api.mojom-shared.h"
#include "third_party/blink/public/mojom/browser_interface_broker.mojom-blink.h"
#include "third_party/blink/public/mojom/devtools/devtools_agent.mojom-blink.h"
+#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"
@@ -84,7 +88,7 @@ void WebSharedWorkerImpl::TerminateWorkerThread() {
asked_to_terminate_ = true;
if (!worker_thread_) {
- client_->WorkerScriptLoadFailed();
+ client_->WorkerScriptLoadFailed(/*error_message=*/"");
// The worker thread hasn't been started yet. Immediately notify the client
// of worker termination.
client_->WorkerContextDestroyed();
@@ -102,7 +106,14 @@ void WebSharedWorkerImpl::CountFeature(WebFeature feature) {
void WebSharedWorkerImpl::DidFailToFetchClassicScript() {
DCHECK(IsMainThread());
- client_->WorkerScriptLoadFailed();
+ client_->WorkerScriptLoadFailed("Failed to fetch a worker script.");
+ TerminateWorkerThread();
+ // DidTerminateWorkerThread() will be called asynchronously.
+}
+
+void WebSharedWorkerImpl::DidFailToFetchModuleScript() {
+ DCHECK(IsMainThread());
+ client_->WorkerScriptLoadFailed("Failed to fetch a worker script.");
TerminateWorkerThread();
// DidTerminateWorkerThread() will be called asynchronously.
}
@@ -112,6 +123,11 @@ void WebSharedWorkerImpl::DidEvaluateClassicScript(bool success) {
client_->WorkerScriptEvaluated(success);
}
+void WebSharedWorkerImpl::DidEvaluateModuleScript(bool success) {
+ DCHECK(IsMainThread());
+ client_->WorkerScriptEvaluated(success);
+}
+
void WebSharedWorkerImpl::DidCloseWorkerGlobalScope() {
DCHECK(IsMainThread());
client_->WorkerContextClosed();
@@ -150,51 +166,51 @@ void WebSharedWorkerImpl::ConnectTaskOnWorkerThread(
void WebSharedWorkerImpl::StartWorkerContext(
const WebURL& script_request_url,
+ mojom::ScriptType script_type,
+ network::mojom::CredentialsMode credentials_mode,
const WebString& name,
+ WebSecurityOrigin constructor_origin,
const WebString& user_agent,
+ const UserAgentMetadata& ua_metadata,
const WebString& content_security_policy,
network::mojom::ContentSecurityPolicyType policy_type,
network::mojom::IPAddressSpace creation_address_space,
+ 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,
bool pause_worker_context_on_start) {
DCHECK(IsMainThread());
+ CHECK(constructor_origin.Get()->CanAccessSharedWorkers());
// Creates 'outside settings' used in the "Processing model" algorithm in the
// HTML spec:
// https://html.spec.whatwg.org/C/#worker-processing-model
- //
- // TODO(nhiroki): According to the spec, the 'outside settings' should
- // correspond to the Document that called 'new SharedWorker()'. The browser
- // process should pass it up to here.
- scoped_refptr<const SecurityOrigin> starter_origin =
- SecurityOrigin::Create(script_request_url);
auto* outside_settings_object =
MakeGarbageCollected<FetchClientSettingsObjectSnapshot>(
/*global_object_url=*/script_request_url,
- /*base_url=*/script_request_url, starter_origin,
- network::mojom::ReferrerPolicy::kDefault,
- /*outgoing_referrer=*/String(),
- CalculateHttpsState(starter_origin.get()),
+ /*base_url=*/script_request_url, constructor_origin,
+ outside_fetch_client_settings_object.referrer_policy,
+ outside_fetch_client_settings_object.outgoing_referrer.GetString(),
+ CalculateHttpsState(constructor_origin.Get()),
AllowedByNosniff::MimeTypeCheck::kLaxForWorker,
creation_address_space,
- /*insecure_request_policy=*/kBlockAllMixedContent,
+ outside_fetch_client_settings_object.insecure_requests_policy ==
+ mojom::blink::InsecureRequestsPolicy::kUpgrade
+ ? mojom::blink::InsecureRequestPolicy::kUpgradeInsecureRequests |
+ mojom::blink::InsecureRequestPolicy::kBlockAllMixedContent
+ : mojom::blink::InsecureRequestPolicy::kBlockAllMixedContent,
FetchClientSettingsObject::InsecureNavigationsSet());
scoped_refptr<WebWorkerFetchContext> web_worker_fetch_context =
client_->CreateWorkerFetchContext();
DCHECK(web_worker_fetch_context);
- // TODO(nhiroki); Set |script_type| to mojom::ScriptType::kModule for module
- // fetch (https://crbug.com/824646).
- mojom::ScriptType script_type = mojom::ScriptType::kClassic;
-
- bool starter_secure_context =
- starter_origin->IsPotentiallyTrustworthy() ||
+ bool constructor_secure_context =
+ constructor_origin.IsPotentiallyTrustworthy() ||
SchemeRegistry::SchemeShouldBypassSecureContextCheck(
- starter_origin->Protocol());
+ constructor_origin.Protocol());
auto worker_settings = std::make_unique<WorkerSettings>(
false /* disable_reading_from_canvas */,
@@ -203,15 +219,20 @@ void WebSharedWorkerImpl::StartWorkerContext(
false /* strictly_block_blockable_mixed_content */,
GenericFontFamilySettings());
- // Some params (e.g., referrer policy, address space, CSP) passed to
- // GlobalScopeCreationParams are dummy values. They will be updated after
- // worker script fetch on the worker thread.
+ // CSP headers for parent Window's CSP.
+ Vector<CSPHeaderAndType> outside_csp_headers;
+ outside_csp_headers.ReserveInitialCapacity(1);
+ outside_csp_headers.UncheckedAppend(
+ CSPHeaderAndType(content_security_policy, policy_type));
+
+ // Some params (e.g. address space) passed to GlobalScopeCreationParams are
+ // dummy values. They will be updated after worker script fetch on the worker
+ // thread.
auto creation_params = std::make_unique<GlobalScopeCreationParams>(
- script_request_url, script_type,
- OffMainThreadWorkerScriptFetchOption::kEnabled, name, user_agent,
- std::move(web_worker_fetch_context), Vector<CSPHeaderAndType>(),
+ script_request_url, script_type, name, user_agent, ua_metadata,
+ std::move(web_worker_fetch_context), outside_csp_headers,
outside_settings_object->GetReferrerPolicy(),
- outside_settings_object->GetSecurityOrigin(), starter_secure_context,
+ outside_settings_object->GetSecurityOrigin(), constructor_secure_context,
outside_settings_object->GetHttpsState(),
MakeGarbageCollected<WorkerClients>(),
std::make_unique<SharedWorkerContentSettingsProxy>(
@@ -248,10 +269,19 @@ void WebSharedWorkerImpl::StartWorkerContext(
GetWorkerThread()->Start(std::move(creation_params), thread_startup_data,
std::move(devtools_params));
- GetWorkerThread()->FetchAndRunClassicScript(
- script_request_url, outside_settings_object->CopyData(),
- nullptr /* outside_resource_timing_notifier */,
- v8_inspector::V8StackTraceId());
+ switch (script_type) {
+ case mojom::ScriptType::kClassic:
+ GetWorkerThread()->FetchAndRunClassicScript(
+ script_request_url, outside_settings_object->CopyData(),
+ nullptr /* outside_resource_timing_notifier */,
+ v8_inspector::V8StackTraceId());
+ break;
+ case mojom::ScriptType::kModule:
+ GetWorkerThread()->FetchAndRunModuleScript(
+ script_request_url, outside_settings_object->CopyData(),
+ nullptr /* outside_resource_timing_notifier */, credentials_mode);
+ break;
+ }
// We are now ready to inspect worker thread.
client_->WorkerReadyForInspection(devtools_agent_remote.PassPipe(),
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 2c732995531..13006f67bd3 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
@@ -38,7 +38,11 @@
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#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/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/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"
#include "third_party/blink/renderer/core/workers/shared_worker_reporting_proxy.h"
@@ -68,11 +72,16 @@ class CORE_EXPORT WebSharedWorkerImpl final : public WebSharedWorker {
// WebSharedWorker methods:
void StartWorkerContext(
const WebURL&,
+ mojom::ScriptType,
+ network::mojom::CredentialsMode,
const WebString& name,
+ WebSecurityOrigin constructor_origin,
const WebString& user_agent,
+ const blink::UserAgentMetadata& ua_metadata,
const WebString& content_security_policy,
network::mojom::ContentSecurityPolicyType,
network::mojom::IPAddressSpace,
+ const WebFetchClientSettingsObject& outside_fetch_client_settings_object,
const base::UnguessableToken& appcache_host_id,
const base::UnguessableToken& devtools_worker_token,
mojo::ScopedMessagePipeHandle content_settings_handle,
@@ -84,7 +93,9 @@ class CORE_EXPORT WebSharedWorkerImpl final : public WebSharedWorker {
// Callback methods for SharedWorkerReportingProxy.
void CountFeature(WebFeature);
void DidFailToFetchClassicScript();
+ void DidFailToFetchModuleScript();
void DidEvaluateClassicScript(bool success);
+ void DidEvaluateModuleScript(bool success);
void DidCloseWorkerGlobalScope();
// This synchronously destroys |this|.
void DidTerminateWorkerThread();
diff --git a/chromium/third_party/blink/renderer/core/exported/web_user_gesture_indicator.cc b/chromium/third_party/blink/renderer/core/exported/web_user_gesture_indicator.cc
deleted file mode 100644
index 6ca9b37f7b9..00000000000
--- a/chromium/third_party/blink/renderer/core/exported/web_user_gesture_indicator.cc
+++ /dev/null
@@ -1,60 +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 "third_party/blink/public/web/web_user_gesture_indicator.h"
-
-#include "third_party/blink/renderer/core/frame/frame.h"
-#include "third_party/blink/renderer/core/frame/local_frame.h"
-#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
-
-namespace blink {
-
-bool WebUserGestureIndicator::IsProcessingUserGesture(WebLocalFrame* frame) {
- return LocalFrame::HasTransientUserActivation(
- frame ? To<WebLocalFrameImpl>(frame)->GetFrame() : nullptr);
-}
-
-bool WebUserGestureIndicator::ConsumeUserGesture(
- WebLocalFrame* frame,
- UserActivationUpdateSource update_source) {
- return LocalFrame::ConsumeTransientUserActivation(
- frame ? To<WebLocalFrameImpl>(frame)->GetFrame() : nullptr,
- update_source);
-
- ;
-}
-
-bool WebUserGestureIndicator::ProcessedUserGestureSinceLoad(
- WebLocalFrame* frame) {
- DCHECK(frame);
- return To<WebLocalFrameImpl>(frame)->GetFrame()->HasBeenActivated();
-}
-
-} // namespace blink
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 2e2b9575063..43fc2bb2de6 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
@@ -35,17 +35,17 @@
#include "base/auto_reset.h"
#include "base/memory/scoped_refptr.h"
+#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "cc/layers/picture_layer.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/features.h"
-#include "third_party/blink/public/common/media/media_player_action.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
+#include "third_party/blink/public/common/input/web_menu_source_type.h"
#include "third_party/blink/public/common/page/page_zoom.h"
-#include "third_party/blink/public/common/plugin/plugin_action.h"
-#include "third_party/blink/public/platform/web_float_point.h"
-#include "third_party/blink/public/platform/web_input_event.h"
-#include "third_party/blink/public/platform/web_menu_source_type.h"
-#include "third_party/blink/public/platform/web_scroll_into_view_params.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
+#include "third_party/blink/public/platform/interface_registry.h"
#include "third_party/blink/public/platform/web_text_autosizer_page_info.h"
#include "third_party/blink/public/platform/web_text_input_info.h"
#include "third_party/blink/public/platform/web_url_request.h"
@@ -145,7 +145,6 @@
#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/core/timing/window_performance.h"
-#include "third_party/blink/renderer/platform/cursor.h"
#include "third_party/blink/renderer/platform/fonts/font_cache.h"
#include "third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
@@ -162,6 +161,7 @@
#include "third_party/blink/renderer/platform/scheduler/public/page_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
+#include "third_party/blink/renderer/platform/widget/widget_base.h"
#include "ui/gfx/skia_util.h"
@@ -234,19 +234,23 @@ class EmptyEventListener final : public NativeEventListener {
WebView* WebView::Create(WebViewClient* client,
bool is_hidden,
bool compositing_enabled,
- WebView* opener) {
+ WebView* opener,
+ mojo::ScopedInterfaceEndpointHandle page_handle) {
return WebViewImpl::Create(client, is_hidden, compositing_enabled,
- static_cast<WebViewImpl*>(opener));
+ static_cast<WebViewImpl*>(opener),
+ std::move(page_handle));
}
-WebViewImpl* WebViewImpl::Create(WebViewClient* client,
- bool is_hidden,
- bool compositing_enabled,
- WebViewImpl* opener) {
+WebViewImpl* WebViewImpl::Create(
+ WebViewClient* client,
+ bool is_hidden,
+ bool compositing_enabled,
+ WebViewImpl* opener,
+ mojo::ScopedInterfaceEndpointHandle page_handle) {
// Take a self-reference for WebViewImpl that is released by calling Close(),
// then return a raw pointer to the caller.
- auto web_view = base::AdoptRef(
- new WebViewImpl(client, is_hidden, compositing_enabled, opener));
+ auto web_view = base::AdoptRef(new WebViewImpl(
+ client, is_hidden, compositing_enabled, opener, std::move(page_handle)));
web_view->AddRef();
return web_view.get();
}
@@ -270,13 +274,17 @@ void WebViewImpl::SetPrerendererClient(
WebViewImpl::WebViewImpl(WebViewClient* client,
bool is_hidden,
bool does_composite,
- WebViewImpl* opener)
+ WebViewImpl* opener,
+ mojo::ScopedInterfaceEndpointHandle page_handle)
: as_view_(client),
chrome_client_(MakeGarbageCollected<ChromeClientImpl>(this)),
minimum_zoom_level_(PageZoomFactorToZoomLevel(kMinimumPageZoomFactor)),
maximum_zoom_level_(PageZoomFactorToZoomLevel(kMaximumPageZoomFactor)),
does_composite_(does_composite),
- fullscreen_controller_(std::make_unique<FullscreenController>(this)) {
+ fullscreen_controller_(std::make_unique<FullscreenController>(this)),
+ receiver_(this,
+ mojo::PendingAssociatedReceiver<mojom::blink::PageBroadcast>(
+ std::move(page_handle))) {
if (!AsView().client) {
DCHECK(!does_composite_);
}
@@ -301,7 +309,6 @@ WebViewImpl::WebViewImpl(WebViewClient* client,
AllInstances().insert(this);
- page_importance_signals_.SetObserver(client);
resize_viewport_anchor_ =
MakeGarbageCollected<ResizeViewportAnchor>(*AsView().page);
}
@@ -354,8 +361,8 @@ void WebViewImpl::HandleMouseDown(LocalFrame& main_frame,
// If the hit node is a plugin but a scrollbar is over it don't start mouse
// capture because it will interfere with the scrollbar receiving events.
if (event.button == WebMouseEvent::Button::kLeft) {
- HitTestLocation location(
- main_frame.View()->ConvertFromRootFrame(event.PositionInWidget()));
+ HitTestLocation location(main_frame.View()->ConvertFromRootFrame(
+ FloatPoint(event.PositionInWidget())));
HitTestResult result(
main_frame.GetEventHandler().HitTestResultAtLocation(location));
result.SetToShadowHostIfInRestrictedShadowRoot();
@@ -364,9 +371,10 @@ void WebViewImpl::HandleMouseDown(LocalFrame& main_frame,
if (!result.GetScrollbar() && hit_node && hit_node->GetLayoutObject() &&
hit_node->GetLayoutObject()->IsEmbeddedObject() && html_element &&
html_element->IsPluginElement()) {
- mouse_capture_element_ = ToHTMLPlugInElement(hit_node);
+ mouse_capture_element_ = To<HTMLPlugInElement>(hit_node);
main_frame.Client()->SetMouseCapture(true);
- TRACE_EVENT_ASYNC_BEGIN0("input", "capturing mouse", this);
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("input", "capturing mouse",
+ TRACE_ID_LOCAL(this));
}
}
@@ -411,7 +419,7 @@ void WebViewImpl::MouseContextMenu(const WebMouseEvent& event) {
TransformWebMouseEvent(MainFrameImpl()->GetFrameView(), event);
transformed_event.menu_source_type = kMenuSourceMouse;
PhysicalOffset position_in_root_frame = PhysicalOffset::FromFloatPointRound(
- transformed_event.PositionInRootFrame());
+ FloatPoint(transformed_event.PositionInRootFrame()));
// Find the right target frame. See issue 1186900.
HitTestResult result = HitTestResultForRootFramePos(position_in_root_frame);
@@ -641,7 +649,7 @@ bool WebViewImpl::StartPageScaleAnimation(const IntPoint& target_position,
if (view && view->GetScrollableArea()) {
view->GetScrollableArea()->SetScrollOffset(
ScrollOffset(clamped_point.x(), clamped_point.y()),
- kProgrammaticScroll);
+ mojom::blink::ScrollType::kProgrammatic);
}
return false;
@@ -655,7 +663,7 @@ bool WebViewImpl::StartPageScaleAnimation(const IntPoint& target_position,
fake_page_scale_animation_use_anchor_ = use_anchor;
fake_page_scale_animation_page_scale_factor_ = new_scale;
} else {
- MainFrameImpl()->FrameWidgetImpl()->Client()->StartPageScaleAnimation(
+ MainFrameImpl()->FrameWidgetImpl()->StartPageScaleAnimation(
static_cast<gfx::Vector2d>(target_position), use_anchor, new_scale,
duration);
}
@@ -954,6 +962,8 @@ static bool ShowsHandCursor(Node* node, LocalFrame* frame) {
frame->GetEventHandler().UseHandCursor(node, node->IsLink()));
}
+// This is for tap (link) highlight and is tested in
+// link_highlight_impl_test.cc.
Node* WebViewImpl::BestTapNode(
const GestureEventWithHitTestResults& targeted_tap_event) {
TRACE_EVENT0("input", "WebViewImpl::bestTapNode");
@@ -1001,6 +1011,14 @@ Node* WebViewImpl::BestTapNode(
ShowsHandCursor(cursor_defining_ancestor,
page->DeprecatedLocalMainFrame()));
+ // This happens in cases like:
+ // <div style="display: contents; cursor: pointer">Text</div>.
+ // The text node inherits cursor: pointer and the div doesn't have a
+ // LayoutObject, so |best_touch_node| is the text node here. We should not
+ // return the text node because it can't have touch actions.
+ if (best_touch_node->IsTextNode())
+ return nullptr;
+
return best_touch_node;
}
@@ -1008,8 +1026,8 @@ void WebViewImpl::EnableTapHighlightAtPoint(
const GestureEventWithHitTestResults& targeted_tap_event) {
Node* touch_node = BestTapNode(targeted_tap_event);
GetPage()->GetLinkHighlight().SetTapHighlight(touch_node);
- UpdateLifecycle(WebWidget::LifecycleUpdate::kAll,
- WebWidget::LifecycleUpdateReason::kOther);
+ UpdateLifecycle(WebLifecycleUpdate::kAll,
+ DocumentUpdateReason::kTapHighlight);
}
void WebViewImpl::AnimateDoubleTapZoom(const gfx::Point& point_in_root_frame,
@@ -1141,7 +1159,7 @@ WebPagePopupImpl* WebViewImpl::OpenPagePopup(PagePopupClient* client) {
// CreatePopup returns nullptr if this renderer process is about to die.
if (!popup_widget)
return nullptr;
- page_popup_ = ToWebPagePopupImpl(popup_widget);
+ page_popup_ = To<WebPagePopupImpl>(popup_widget);
page_popup_->Initialize(this, client);
EnablePopupMouseWheelEventListener(frame);
return page_popup_.get();
@@ -1154,7 +1172,7 @@ void WebViewImpl::CancelPagePopup() {
void WebViewImpl::ClosePagePopup(PagePopup* popup) {
DCHECK(popup);
- WebPagePopupImpl* popup_impl = ToWebPagePopupImpl(popup);
+ auto* popup_impl = To<WebPagePopupImpl>(popup);
DCHECK_EQ(page_popup_.get(), popup_impl);
if (page_popup_.get() != popup_impl)
return;
@@ -1213,28 +1231,11 @@ void WebViewImpl::Close() {
DCHECK(AllInstances().Contains(this));
AllInstances().erase(this);
- if (does_composite_) {
- // This must occur before WillBeDestroyed, since detaching the main frame
- // will also destroy the WebWidgetClient and the AnimationHost.
- // TODO(danakj): Since the AnimationHost will be destroyed anyways, there
- // is probably no good reason to do this at all.
- GetPage()->WillCloseAnimationHost(nullptr);
- }
-
// Initiate shutdown for the entire frameset. This will cause a lot of
// notifications to be sent. This will detach all frames in this WebView's
// frame tree.
AsView().page->WillBeDestroyed();
- // The main frame being detached in WillBeDestroyed() will make use of this
- // which happens in Page::WillBeDestroyed(). But since the RenderWidget lives
- // |animation_host_| through its WebFrameWidget, before causing the
- // forever (https://crbug.com/419087), the WebWidget is not closed elsewhere.
- // WebWidgetClient and the AnimationHost to be destroyed. So this is nulled
- // So we close it here but try to simulate the same ordering by closing it
- // out after detaching the main frame.
- animation_host_ = nullptr;
-
// TODO(bokan): Temporary debugging added to diagnose
// https://crbug.com/992315. Somehow we're synchronously calling
// WebViewImpl::Close while handling an input event.
@@ -1257,7 +1258,8 @@ void WebViewImpl::ResizeVisualViewport(const WebSize& new_size) {
GetPage()->GetVisualViewport().ClampToBoundaries();
}
-void WebViewImpl::UpdateICBAndResizeViewport() {
+void WebViewImpl::UpdateICBAndResizeViewport(
+ const IntSize& visible_viewport_size) {
// We'll keep the initial containing block size from changing when the top
// controls hide so that the ICB will always be the same size as the
// viewport with the browser controls shown.
@@ -1265,7 +1267,8 @@ void WebViewImpl::UpdateICBAndResizeViewport() {
if (GetBrowserControls().PermittedState() ==
cc::BrowserControlsState::kBoth &&
!GetBrowserControls().ShrinkViewport()) {
- icb_size.Expand(0, -GetBrowserControls().TotalHeight());
+ icb_size.Expand(0, -(GetBrowserControls().TotalHeight() -
+ GetBrowserControls().TotalMinHeight()));
}
GetPageScaleConstraintsSet().DidChangeInitialContainingBlockSize(icb_size);
@@ -1277,13 +1280,18 @@ void WebViewImpl::UpdateICBAndResizeViewport() {
.GetViewportDescription());
UpdateMainFrameLayoutSize();
- GetPage()->GetVisualViewport().SetSize(size_);
+ GetPage()->GetVisualViewport().SetSize(visible_viewport_size);
if (MainFrameImpl()->GetFrameView()) {
MainFrameImpl()->GetFrameView()->SetInitialViewportSize(icb_size);
if (!MainFrameImpl()->GetFrameView()->NeedsLayout())
resize_viewport_anchor_->ResizeFrameView(MainFrameSize());
}
+
+ // The boundaries are not properly established until after the frame view is
+ // also resized, as demonstrated by
+ // VisualViewportTest.TestBrowserControlsAdjustmentAndResize.
+ GetPage()->GetVisualViewport().ClampToBoundaries();
}
void WebViewImpl::UpdateBrowserControlsConstraint(
@@ -1292,7 +1300,7 @@ void WebViewImpl::UpdateBrowserControlsConstraint(
GetBrowserControls().PermittedState();
GetBrowserControls().UpdateConstraintsAndState(
- constraint, cc::BrowserControlsState::kBoth, false);
+ constraint, cc::BrowserControlsState::kBoth);
// If the controls are going from a locked hidden to unlocked state, or vice
// versa, the ICB size needs to change but we can't rely on getting a
@@ -1302,7 +1310,7 @@ void WebViewImpl::UpdateBrowserControlsConstraint(
constraint == cc::BrowserControlsState::kBoth) ||
(old_permitted_state == cc::BrowserControlsState::kBoth &&
constraint == cc::BrowserControlsState::kHidden)) {
- UpdateICBAndResizeViewport();
+ UpdateICBAndResizeViewport(GetPage()->GetVisualViewport().Size());
}
}
@@ -1324,11 +1332,10 @@ void WebViewImpl::DidUpdateBrowserControls() {
if (!main_frame)
return;
- WebWidgetClient* client = main_frame->LocalRootFrameWidget()->Client();
- DCHECK(client);
- client->SetBrowserControlsShownRatio(GetBrowserControls().TopShownRatio(),
+ WebFrameWidgetBase* widget = main_frame->LocalRootFrameWidget();
+ widget->SetBrowserControlsShownRatio(GetBrowserControls().TopShownRatio(),
GetBrowserControls().BottomShownRatio());
- client->SetBrowserControlsParams(GetBrowserControls().Params());
+ widget->SetBrowserControlsParams(GetBrowserControls().Params());
VisualViewport& visual_viewport = GetPage()->GetVisualViewport();
@@ -1349,7 +1356,9 @@ BrowserControls& WebViewImpl::GetBrowserControls() {
return GetPage()->GetBrowserControls();
}
-void WebViewImpl::ResizeViewWhileAnchored(cc::BrowserControlsParams params) {
+void WebViewImpl::ResizeViewWhileAnchored(
+ cc::BrowserControlsParams params,
+ const IntSize& visible_viewport_size) {
DCHECK(MainFrameImpl());
GetBrowserControls().SetParams(params);
@@ -1360,7 +1369,7 @@ void WebViewImpl::ResizeViewWhileAnchored(cc::BrowserControlsParams params) {
TextAutosizer::DeferUpdatePageInfo defer_update_page_info(GetPage());
LocalFrameView* frame_view = MainFrameImpl()->GetFrameView();
IntSize old_size = frame_view->Size();
- UpdateICBAndResizeViewport();
+ UpdateICBAndResizeViewport(visible_viewport_size);
IntSize new_size = frame_view->Size();
frame_view->MarkViewportConstrainedObjectsForLayout(
old_size.Width() != new_size.Width(),
@@ -1369,11 +1378,10 @@ void WebViewImpl::ResizeViewWhileAnchored(cc::BrowserControlsParams params) {
fullscreen_controller_->UpdateSize();
- // Update lifecyle phases immediately to recalculate the minimum scale limit
+ // Update lifecycle phases immediately to recalculate the minimum scale limit
// for rotation anchoring, and to make sure that no lifecycle states are
// stale if this WebView is embedded in another one.
- UpdateLifecycle(WebWidget::LifecycleUpdate::kAll,
- WebWidget::LifecycleUpdateReason::kOther);
+ UpdateLifecycle(WebLifecycleUpdate::kAll, DocumentUpdateReason::kSizeChange);
}
void WebViewImpl::ResizeWithBrowserControls(
@@ -1382,28 +1390,35 @@ void WebViewImpl::ResizeWithBrowserControls(
float bottom_controls_height,
bool browser_controls_shrink_layout) {
ResizeWithBrowserControls(
- new_size, {top_controls_height, GetBrowserControls().TopMinHeight(),
- bottom_controls_height, GetBrowserControls().BottomMinHeight(),
- GetBrowserControls().AnimateHeightChanges(),
- browser_controls_shrink_layout});
+ new_size, new_size,
+ {top_controls_height, GetBrowserControls().TopMinHeight(),
+ bottom_controls_height, GetBrowserControls().BottomMinHeight(),
+ GetBrowserControls().AnimateHeightChanges(),
+ browser_controls_shrink_layout});
}
void WebViewImpl::ResizeWithBrowserControls(
- const WebSize& new_size,
+ const WebSize& main_frame_widget_size,
+ const WebSize& visible_viewport_size,
cc::BrowserControlsParams browser_controls_params) {
- if (should_auto_resize_)
+ if (should_auto_resize_) {
+ // When auto-resizing only the viewport size comes from the browser, while
+ // the widget size is determined in the renderer.
+ ResizeVisualViewport(visible_viewport_size);
return;
+ }
- if (size_ == new_size &&
+ if (size_ == main_frame_widget_size &&
+ GetPage()->GetVisualViewport().Size() == IntSize(visible_viewport_size) &&
GetBrowserControls().Params() == browser_controls_params)
return;
if (GetPage()->MainFrame() && !GetPage()->MainFrame()->IsLocalFrame()) {
// Viewport resize for a remote main frame does not require any
// particular action, but the state needs to reflect the correct size
- // so that it can be used for initalization if the main frame gets
+ // so that it can be used for initialization if the main frame gets
// swapped to a LocalFrame at a later time.
- size_ = new_size;
+ size_ = main_frame_widget_size;
GetPageScaleConstraintsSet().DidChangeInitialContainingBlockSize(size_);
GetPage()->GetVisualViewport().SetSize(size_);
GetPage()->GetBrowserControls().SetParams(browser_controls_params);
@@ -1422,19 +1437,20 @@ void WebViewImpl::ResizeWithBrowserControls(
bool is_rotation =
GetPage()->GetSettings().GetMainFrameResizesAreOrientationChanges() &&
- size_.width && ContentsSize().Width() && new_size.width != size_.width &&
+ size_.width && ContentsSize().Width() &&
+ main_frame_widget_size.width != size_.width &&
!fullscreen_controller_->IsFullscreenOrTransitioning();
- size_ = new_size;
+ size_ = main_frame_widget_size;
FloatSize viewport_anchor_coords(viewportAnchorCoordX, viewportAnchorCoordY);
if (is_rotation) {
RotationViewportAnchor anchor(*view, visual_viewport,
viewport_anchor_coords,
GetPageScaleConstraintsSet());
- ResizeViewWhileAnchored(browser_controls_params);
+ ResizeViewWhileAnchored(browser_controls_params, visible_viewport_size);
} else {
ResizeViewportAnchor::ResizeScope resize_scope(*resize_viewport_anchor_);
- ResizeViewWhileAnchored(browser_controls_params);
+ ResizeViewWhileAnchored(browser_controls_params, visible_viewport_size);
}
SendResizeEventForMainFrame();
}
@@ -1460,17 +1476,20 @@ void WebViewImpl::DidExitFullscreen() {
fullscreen_controller_->DidExitFullscreen();
}
-void WebViewImpl::SetWebWidget(WebWidget* widget) {
+void WebViewImpl::SetMainFrameWidgetBase(WebFrameWidgetBase* widget) {
web_widget_ = widget;
}
+WebFrameWidgetBase* WebViewImpl::MainFrameWidgetBase() {
+ return web_widget_;
+}
+
void WebViewImpl::SetSuppressFrameRequestsWorkaroundFor704763Only(
bool suppress_frame_requests) {
AsView().page->Animator().SetSuppressFrameRequestsWorkaroundFor704763Only(
suppress_frame_requests);
}
-void WebViewImpl::BeginFrame(base::TimeTicks last_frame_time,
- bool record_main_frame_metrics) {
+void WebViewImpl::BeginFrame(base::TimeTicks last_frame_time) {
TRACE_EVENT1("blink", "WebViewImpl::beginFrame", "frameTime",
last_frame_time);
DCHECK(!last_frame_time.is_null());
@@ -1478,12 +1497,10 @@ void WebViewImpl::BeginFrame(base::TimeTicks last_frame_time,
if (!MainFrameImpl())
return;
- if (RuntimeEnabledFeatures::UpdateHoverAtBeginFrameEnabled()) {
- MainFrameImpl()
- ->GetFrame()
- ->GetEventHandler()
- .RecomputeMouseHoverStateIfNeeded();
- }
+ MainFrameImpl()
+ ->GetFrame()
+ ->GetEventHandler()
+ .RecomputeMouseHoverStateIfNeeded();
if (LocalFrameView* view = MainFrameImpl()->GetFrameView()) {
if (FragmentAnchor* anchor = view->GetFragmentAnchor())
@@ -1494,7 +1511,7 @@ void WebViewImpl::BeginFrame(base::TimeTicks last_frame_time,
MainFrameImpl()->GetFrame()->GetDocument()->Lifecycle());
base::Optional<LocalFrameUkmAggregator::ScopedUkmHierarchicalTimer> ukm_timer;
- if (record_main_frame_metrics) {
+ if (WidgetBase::ShouldRecordBeginMainFrameMetrics()) {
ukm_timer.emplace(MainFrameImpl()
->GetFrame()
->View()
@@ -1514,22 +1531,6 @@ void WebViewImpl::DidBeginFrame() {
}
}
-void WebViewImpl::BeginRafAlignedInput() {
- if (MainFrameImpl()) {
- raf_aligned_input_start_time_.emplace(base::TimeTicks::Now());
- }
-}
-
-void WebViewImpl::EndRafAlignedInput() {
- if (MainFrameImpl()) {
- DCHECK(raf_aligned_input_start_time_);
- MainFrameImpl()->GetFrame()->View()->EnsureUkmAggregator().RecordSample(
- LocalFrameUkmAggregator::kHandleInputEvents,
- raf_aligned_input_start_time_.value(), base::TimeTicks::Now());
- }
- raf_aligned_input_start_time_.reset();
-}
-
void WebViewImpl::BeginUpdateLayers() {
if (MainFrameImpl())
update_layers_start_time_.emplace(base::TimeTicks::Now());
@@ -1552,12 +1553,15 @@ void WebViewImpl::BeginCommitCompositorFrame() {
}
}
-void WebViewImpl::EndCommitCompositorFrame() {
+void WebViewImpl::EndCommitCompositorFrame(base::TimeTicks commit_start_time) {
// Some tests call this without ever beginning a frame.
if (MainFrameImpl() && commit_compositor_frame_start_time_) {
- MainFrameImpl()->GetFrame()->View()->EnsureUkmAggregator().RecordSample(
- LocalFrameUkmAggregator::kProxyCommit,
- commit_compositor_frame_start_time_.value(), base::TimeTicks::Now());
+ MainFrameImpl()
+ ->GetFrame()
+ ->View()
+ ->EnsureUkmAggregator()
+ .RecordImplCompositorSample(commit_compositor_frame_start_time_.value(),
+ commit_start_time, base::TimeTicks::Now());
}
commit_compositor_frame_start_time_.reset();
}
@@ -1569,7 +1573,9 @@ void WebViewImpl::RecordStartOfFrameMetrics() {
MainFrameImpl()->GetFrame()->View()->EnsureUkmAggregator().BeginMainFrame();
}
-void WebViewImpl::RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) {
+void WebViewImpl::RecordEndOfFrameMetrics(
+ base::TimeTicks frame_begin_time,
+ cc::ActiveFrameSequenceTrackers trackers) {
if (!MainFrameImpl())
return;
@@ -1577,7 +1583,8 @@ void WebViewImpl::RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) {
->GetFrame()
->View()
->EnsureUkmAggregator()
- .RecordEndOfFrameMetrics(frame_begin_time, base::TimeTicks::Now());
+ .RecordEndOfFrameMetrics(frame_begin_time, base::TimeTicks::Now(),
+ trackers);
}
std::unique_ptr<cc::BeginMainFrameMetrics>
@@ -1592,8 +1599,8 @@ WebViewImpl::GetBeginMainFrameMetrics() {
.GetBeginMainFrameMetrics();
}
-void WebViewImpl::UpdateLifecycle(WebWidget::LifecycleUpdate requested_update,
- WebWidget::LifecycleUpdateReason reason) {
+void WebViewImpl::UpdateLifecycle(WebLifecycleUpdate requested_update,
+ DocumentUpdateReason reason) {
TRACE_EVENT0("blink", "WebViewImpl::updateAllLifecyclePhases");
if (!MainFrameImpl())
return;
@@ -1603,13 +1610,12 @@ void WebViewImpl::UpdateLifecycle(WebWidget::LifecycleUpdate requested_update,
PageWidgetDelegate::UpdateLifecycle(
*AsView().page, *MainFrameImpl()->GetFrame(), requested_update, reason);
- if (requested_update != WebWidget::LifecycleUpdate::kAll)
+ if (requested_update != WebLifecycleUpdate::kAll)
return;
// There is no background color for non-composited WebViews (eg printing).
if (does_composite_) {
- MainFrameImpl()->FrameWidgetImpl()->Client()->SetBackgroundColor(
- BackgroundColor());
+ MainFrameImpl()->FrameWidgetImpl()->SetBackgroundColor(BackgroundColor());
}
if (LocalFrameView* view = MainFrameImpl()->GetFrameView()) {
@@ -1642,7 +1648,7 @@ void WebViewImpl::UpdateLifecycle(WebWidget::LifecycleUpdate requested_update,
void WebViewImpl::PaintContent(cc::PaintCanvas* canvas, const gfx::Rect& rect) {
// This should only be used when compositing is not being used for this
// WebView, and it is painting into the recording of its parent.
- DCHECK(!IsAcceleratedCompositingActive());
+ DCHECK(!does_composite_);
// Non-composited WebViews always have a local main frame.
DCHECK(MainFrameImpl());
@@ -1676,8 +1682,10 @@ void WebViewImpl::ThemeChanged() {
}
void WebViewImpl::EnterFullscreen(LocalFrame& frame,
- const FullscreenOptions* options) {
- fullscreen_controller_->EnterFullscreen(frame, options);
+ const FullscreenOptions* options,
+ bool for_cross_process_descendant) {
+ fullscreen_controller_->EnterFullscreen(frame, options,
+ for_cross_process_descendant);
}
void WebViewImpl::ExitFullscreen(LocalFrame& frame) {
@@ -1873,7 +1881,8 @@ void WebViewImpl::OnFallbackCursorModeToggled(bool is_on) {
}
void WebViewImpl::MouseCaptureLost() {
- TRACE_EVENT_ASYNC_END0("input", "capturing mouse", this);
+ TRACE_EVENT_NESTABLE_ASYNC_END0("input", "capturing mouse",
+ TRACE_ID_LOCAL(this));
mouse_capture_element_ = nullptr;
if (AsView().page->DeprecatedLocalMainFrame())
AsView().page->DeprecatedLocalMainFrame()->Client()->SetMouseCapture(false);
@@ -1927,7 +1936,8 @@ void WebViewImpl::SetFocus(bool enable) {
// TODO(editing-dev): The use of
// UpdateStyleAndLayout needs to be audited.
// See http://crbug.com/590369 for more details.
- focused_frame->GetDocument()->UpdateStyleAndLayout();
+ focused_frame->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kFocus);
focused_frame->GetInputMethodController().FinishComposingText(
InputMethodController::kKeepSelection);
@@ -1961,10 +1971,6 @@ bool WebViewImpl::SelectionBounds(WebRect& anchor_web,
return true;
}
-bool WebViewImpl::IsAcceleratedCompositingActive() const {
- return !!root_layer_;
-}
-
void WebViewImpl::DidAcquirePointerLock() {
if (MainFrameImpl())
MainFrameImpl()->FrameWidget()->DidAcquirePointerLock();
@@ -2030,29 +2036,33 @@ WebLocalFrameImpl* WebViewImpl::MainFrameImpl() const {
void WebViewImpl::DidAttachLocalMainFrame() {
DCHECK(MainFrameImpl());
+ LocalFrame* local_frame = MainFrameImpl()->GetFrame();
+ local_frame->WasAttachedAsLocalMainFrame();
+
+ local_frame->GetRemoteNavigationAssociatedInterfaces()->GetInterface(
+ local_main_frame_host_remote_.BindNewEndpointAndPassReceiver());
+
if (does_composite_) {
WebWidgetClient* widget_client =
MainFrameImpl()->FrameWidgetImpl()->Client();
// When attaching a local main frame, set up any state on the compositor.
- widget_client->SetBackgroundColor(BackgroundColor());
+ MainFrameImpl()->FrameWidgetImpl()->SetBackgroundColor(BackgroundColor());
auto& viewport = GetPage()->GetVisualViewport();
widget_client->SetPageScaleStateAndLimits(
viewport.Scale(), viewport.IsPinchGestureActive(),
MinimumPageScaleFactor(), MaximumPageScaleFactor());
// Prevent main frame updates while the main frame is loading until enough
// progress is made and BeginMainFrames are explicitly asked for.
- scoped_defer_main_frame_update_ = widget_client->DeferMainFrameUpdate();
+ scoped_defer_main_frame_update_ =
+ MainFrameImpl()->FrameWidgetImpl()->DeferMainFrameUpdate();
}
}
void WebViewImpl::DidDetachLocalMainFrame() {
// The WebWidgetClient that generated the |scoped_defer_main_frame_update_|
// for a local main frame is going away.
- // TODO(crbug.com/419087): For now, the WebWidgetClient (aka RenderWidget)
- // is not destroyed, so this comment is not true, but it will be in the
- // future. All references between |this| and the WebWidgetClient should be
- // dropped regardless.
scoped_defer_main_frame_update_ = nullptr;
+ local_main_frame_host_remote_.reset();
}
WebLocalFrame* WebViewImpl::FocusedFrame() {
@@ -2084,33 +2094,8 @@ void WebViewImpl::SetInitialFocus(bool reverse) {
document->ClearFocusedElement();
}
GetPage()->GetFocusController().SetInitialFocus(
- reverse ? kWebFocusTypeBackward : kWebFocusTypeForward);
-}
-
-void WebViewImpl::ClearFocusedElement() {
- Frame* frame = FocusedCoreFrame();
-
- auto* local_frame = DynamicTo<LocalFrame>(frame);
- if (!local_frame)
- return;
-
- Document* document = local_frame->GetDocument();
- if (!document)
- return;
-
- Element* old_focused_element = document->FocusedElement();
- document->ClearFocusedElement();
- if (!old_focused_element)
- return;
-
- // If a text field has focus, we need to make sure the selection controller
- // knows to remove selection from it. Otherwise, the text field is still
- // processing keyboard events even though focus has been moved to the page and
- // keystrokes get eaten as a result.
- document->UpdateStyleAndLayoutTree();
- if (HasEditableStyle(*old_focused_element) ||
- old_focused_element->IsTextControl())
- local_frame->Selection().Clear();
+ reverse ? mojom::blink::FocusType::kBackward
+ : mojom::blink::FocusType::kForward);
}
// TODO(dglazkov): Remove and replace with Node:hasEditableStyle.
@@ -2139,7 +2124,7 @@ bool WebViewImpl::ScrollFocusedEditableElementIntoView() {
if (!element || !IsElementEditable(element))
return false;
- element->GetDocument().UpdateStyleAndLayout();
+ element->GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kSelection);
LayoutObject* layout_object = element->GetLayoutObject();
if (!layout_object)
@@ -2150,13 +2135,14 @@ bool WebViewImpl::ScrollFocusedEditableElementIntoView() {
// only the visual and layout viewports. We'll call ScrollRectToVisible with
// the stop_at_main_frame_layout_viewport param to ensure the element is
// actually visible in the page.
- WebScrollIntoViewParams params(ScrollAlignment::kAlignCenterIfNeeded,
- ScrollAlignment::kAlignCenterIfNeeded,
- kProgrammaticScroll, false,
- kScrollBehaviorInstant);
- params.stop_at_main_frame_layout_viewport = true;
+ auto params = ScrollAlignment::CreateScrollIntoViewParams(
+ ScrollAlignment::CenterIfNeeded(), ScrollAlignment::CenterIfNeeded(),
+ mojom::blink::ScrollType::kProgrammatic, false,
+ mojom::blink::ScrollBehavior::kInstant);
+ params->stop_at_main_frame_layout_viewport = true;
layout_object->ScrollRectToVisible(
- PhysicalRect(layout_object->AbsoluteBoundingBoxRect()), params);
+ PhysicalRect(layout_object->AbsoluteBoundingBoxRect()),
+ std::move(params));
ZoomAndScrollToFocusedEditableElementRect(
main_frame_view->RootFrameToDocument(
@@ -2185,7 +2171,7 @@ bool WebViewImpl::ShouldZoomToLegibleScale(const Element& element) {
// back out.
TouchAction action =
touch_action_util::ComputeEffectiveTouchAction(element);
- if (!(action & TouchAction::kTouchActionPinchZoom))
+ if (!(static_cast<int>(action) & static_cast<int>(TouchAction::kPinchZoom)))
zoom_into_legible_scale = false;
}
@@ -2193,8 +2179,8 @@ bool WebViewImpl::ShouldZoomToLegibleScale(const Element& element) {
}
void WebViewImpl::ZoomAndScrollToFocusedEditableElementRect(
- const IntRect& element_bounds_in_document,
- const IntRect& caret_bounds_in_document,
+ const WebRect& element_bounds_in_document,
+ const WebRect& caret_bounds_in_document,
bool zoom_into_legible_scale) {
float scale;
IntPoint scroll;
@@ -2328,16 +2314,17 @@ void WebViewImpl::ComputeScaleAndScrollForEditableElementRects(
}
void WebViewImpl::AdvanceFocus(bool reverse) {
- GetPage()->GetFocusController().AdvanceFocus(reverse ? kWebFocusTypeBackward
- : kWebFocusTypeForward);
+ GetPage()->GetFocusController().AdvanceFocus(
+ reverse ? mojom::blink::FocusType::kBackward
+ : mojom::blink::FocusType::kForward);
}
-void WebViewImpl::AdvanceFocusAcrossFrames(WebFocusType type,
+void WebViewImpl::AdvanceFocusAcrossFrames(mojom::blink::FocusType type,
WebRemoteFrame* from,
WebLocalFrame* to) {
// TODO(alexmos): Pass in proper with sourceCapabilities.
GetPage()->GetFocusController().AdvanceFocusAcrossFrames(
- type, ToWebRemoteFrameImpl(from)->GetFrame(),
+ type, To<WebRemoteFrameImpl>(from)->GetFrame(),
To<WebLocalFrameImpl>(to)->GetFrame());
}
@@ -2350,8 +2337,8 @@ void WebViewImpl::PropagateZoomFactorToLocalFrameRoots(Frame* frame,
auto* local_frame = DynamicTo<LocalFrame>(frame);
if (local_frame && local_frame->IsLocalRoot()) {
if (Document* document = local_frame->GetDocument()) {
- if (!document->IsPluginDocument() ||
- !ToPluginDocument(document)->GetPluginView()) {
+ auto* plugin_document = DynamicTo<PluginDocument>(document);
+ if (!plugin_document || !plugin_document->GetPluginView()) {
local_frame->SetPageZoomFactor(zoom_factor);
}
}
@@ -2418,19 +2405,19 @@ float WebViewImpl::ClampPageScaleFactorToLimits(float scale_factor) const {
scale_factor);
}
-void WebViewImpl::SetVisualViewportOffset(const WebFloatPoint& offset) {
+void WebViewImpl::SetVisualViewportOffset(const gfx::PointF& offset) {
DCHECK(GetPage());
- GetPage()->GetVisualViewport().SetLocation(offset);
+ GetPage()->GetVisualViewport().SetLocation(FloatPoint(offset));
}
-WebFloatPoint WebViewImpl::VisualViewportOffset() const {
+gfx::PointF WebViewImpl::VisualViewportOffset() const {
DCHECK(GetPage());
return GetPage()->GetVisualViewport().VisibleRect().Location();
}
-WebFloatSize WebViewImpl::VisualViewportSize() const {
+gfx::SizeF WebViewImpl::VisualViewportSize() const {
DCHECK(GetPage());
- return GetPage()->GetVisualViewport().VisibleRect().Size();
+ return gfx::SizeF(GetPage()->GetVisualViewport().VisibleRect().Size());
}
void WebViewImpl::SetPageScaleFactorAndLocation(float scale_factor,
@@ -2445,12 +2432,9 @@ void WebViewImpl::SetPageScaleFactorAndLocation(float scale_factor,
void WebViewImpl::SetPageScaleFactor(float scale_factor) {
DCHECK(GetPage());
+ DCHECK(MainFrameImpl());
- scale_factor = ClampPageScaleFactorToLimits(scale_factor);
- if (scale_factor == PageScaleFactor())
- return;
-
- GetPage()->GetVisualViewport().SetScale(scale_factor);
+ MainFrameImpl()->GetFrame()->SetScaleFactor(scale_factor);
}
void WebViewImpl::SetDeviceScaleFactor(float scale_factor) {
@@ -2472,6 +2456,18 @@ void WebViewImpl::SetZoomFactorForDeviceScaleFactor(
SetZoomLevel(zoom_level_);
}
+void WebViewImpl::SetPageLifecycleState(
+ mojom::blink::PageLifecycleStatePtr state,
+ SetPageLifecycleStateCallback callback) {
+ Page* page = GetPage();
+ if (!page)
+ return;
+ Scheduler()->SetPageFrozen(state->is_frozen);
+
+ // Tell the browser that the freezing or resuming was successful.
+ std::move(callback).Run();
+}
+
void WebViewImpl::EnableAutoResizeMode(const WebSize& min_size,
const WebSize& max_size) {
should_auto_resize_ = true;
@@ -2632,14 +2628,14 @@ void WebViewImpl::UpdatePageDefinedViewportConstraints(
UpdateMainFrameLayoutSize();
}
-void WebViewImpl::SetTextAutosizePageInfo(
+void WebViewImpl::SetTextAutosizerPageInfo(
const WebTextAutosizerPageInfo& page_info) {
Frame* root_frame = GetPage()->MainFrame();
DCHECK(root_frame->IsRemoteFrame());
if (page_info == GetPage()->TextAutosizerPageInfo())
return;
- GetPage()->SetTextAutosizePageInfo(page_info);
+ GetPage()->SetTextAutosizerPageInfo(page_info);
TextAutosizer::UpdatePageInfoInAllFrames(root_frame);
}
@@ -2688,13 +2684,56 @@ WebSize WebViewImpl::ContentsPreferredMinimumSize() {
// Needed for computing MinPreferredWidth.
FontCachePurgePreventer fontCachePurgePreventer;
int width_scaled = document->GetLayoutView()
- ->MinPreferredLogicalWidth()
- .Round(); // Already accounts for zoom.
+ ->PreferredLogicalWidths()
+ .min_size.Round(); // Already accounts for zoom.
int height_scaled =
document->documentElement()->GetLayoutBox()->ScrollHeight().Round();
return IntSize(width_scaled, height_scaled);
}
+void WebViewImpl::UpdatePreferredSize() {
+ // We don't always want to send the change messages over IPC, only if we've
+ // been put in that mode by getting a |ViewMsg_EnablePreferredSizeChangedMode|
+ // message.
+ if (!send_preferred_size_changes_ || !MainFrameImpl())
+ return;
+
+ if (!needs_preferred_size_update_)
+ return;
+ needs_preferred_size_update_ = false;
+
+ WebSize web_size = ContentsPreferredMinimumSize();
+ WebRect web_rect(0, 0, web_size.width, web_size.height);
+ MainFrameImpl()->LocalRootFrameWidget()->Client()->ConvertViewportToWindow(
+ &web_rect);
+ WebSize size(web_rect.width, web_rect.height);
+
+ if (size != preferred_size_) {
+ preferred_size_ = size;
+ local_main_frame_host_remote_->ContentsPreferredSizeChanged(
+ gfx::Size(size));
+ }
+}
+
+void WebViewImpl::EnablePreferredSizeChangedMode() {
+ if (send_preferred_size_changes_)
+ return;
+ send_preferred_size_changes_ = true;
+ needs_preferred_size_update_ = true;
+
+ // We need to ensure |UpdatePreferredSize| gets called. If a layout is needed,
+ // force an update here which will call |DidUpdateMainFrameLayout|.
+ if (MainFrameWidget()) {
+ MainFrameWidget()->UpdateLifecycle(WebLifecycleUpdate::kLayout,
+ DocumentUpdateReason::kSizeChange);
+ }
+
+ // If a layout was not needed, |DidUpdateMainFrameLayout| will not be called.
+ // We explicitly update the preferred size here to ensure the preferred size
+ // notification is sent.
+ UpdatePreferredSize();
+}
+
float WebViewImpl::DefaultMinimumPageScaleFactor() const {
return GetPageScaleConstraintsSet().DefaultConstraints().minimum_scale;
}
@@ -2725,8 +2764,10 @@ void WebViewImpl::ResetScrollAndScaleState() {
if (LocalFrameView* frame_view = main_local_frame->View()) {
ScrollableArea* scrollable_area = frame_view->LayoutViewport();
- if (!scrollable_area->GetScrollOffset().IsZero())
- scrollable_area->SetScrollOffset(ScrollOffset(), kProgrammaticScroll);
+ if (!scrollable_area->GetScrollOffset().IsZero()) {
+ scrollable_area->SetScrollOffset(ScrollOffset(),
+ mojom::blink::ScrollType::kProgrammatic);
+ }
}
if (Document* document = main_local_frame->GetDocument()) {
@@ -2739,36 +2780,6 @@ void WebViewImpl::ResetScrollAndScaleState() {
GetPageScaleConstraintsSet().SetNeedsReset(true);
}
-void WebViewImpl::PerformPluginAction(const PluginAction& action,
- const gfx::Point& location) {
- // FIXME: Location is probably in viewport coordinates
- HitTestResult result =
- HitTestResultForRootFramePos(PhysicalOffset(IntPoint(location)));
- Node* node = result.InnerNode();
- if (!IsA<HTMLObjectElement>(*node) && !IsA<HTMLEmbedElement>(*node))
- return;
-
- LayoutObject* object = node->GetLayoutObject();
- if (object && object->IsLayoutEmbeddedContent()) {
- WebPluginContainerImpl* plugin_view =
- ToLayoutEmbeddedContent(object)->Plugin();
- if (plugin_view) {
- switch (action.type) {
- case PluginAction::kRotate90Clockwise:
- plugin_view->Plugin()->RotateView(
- WebPlugin::kRotationType90Clockwise);
- break;
- case PluginAction::kRotate90Counterclockwise:
- plugin_view->Plugin()->RotateView(
- WebPlugin::kRotationType90Counterclockwise);
- break;
- default:
- NOTREACHED();
- }
- }
- }
-}
-
void WebViewImpl::AudioStateChanged(bool is_audio_playing) {
GetPage()->GetPageScheduler()->AudioStateChanged(is_audio_playing);
}
@@ -2942,7 +2953,8 @@ void WebViewImpl::SetBaseBackgroundColorOverride(SkColor color) {
MainFrameImpl()
->GetFrame()
->View()
- ->UpdateLifecycleToCompositingCleanPlusScrolling();
+ ->UpdateLifecycleToCompositingCleanPlusScrolling(
+ DocumentUpdateReason::kBaseColor);
}
UpdateBaseBackgroundColor();
}
@@ -2958,7 +2970,8 @@ void WebViewImpl::ClearBaseBackgroundColorOverride() {
MainFrameImpl()
->GetFrame()
->View()
- ->UpdateLifecycleToCompositingCleanPlusScrolling();
+ ->UpdateLifecycleToCompositingCleanPlusScrolling(
+ DocumentUpdateReason::kBaseColor);
}
UpdateBaseBackgroundColor();
}
@@ -3005,10 +3018,8 @@ void WebViewImpl::DidCommitLoad(bool is_new_navigation,
should_dispatch_first_layout_after_finished_parsing_ = true;
should_dispatch_first_layout_after_finished_loading_ = true;
- if (is_new_navigation) {
+ if (is_new_navigation)
GetPageScaleConstraintsSet().SetNeedsReset(true);
- page_importance_signals_.OnCommitLoad();
- }
}
// Give the visual viewport's scroll layer its initial size.
@@ -3048,6 +3059,7 @@ void WebViewImpl::MainFrameLayoutUpdated() {
return;
AsView().client->DidUpdateMainFrameLayout();
+ needs_preferred_size_update_ = true;
}
void WebViewImpl::DidChangeContentsSize() {
@@ -3082,7 +3094,8 @@ void WebViewImpl::PageScaleFactorChanged() {
MainFrameImpl()->FrameWidgetImpl()->Client()->SetPageScaleStateAndLimits(
viewport.Scale(), viewport.IsPinchGestureActive(),
MinimumPageScaleFactor(), MaximumPageScaleFactor());
- AsView().client->PageScaleFactorChanged(viewport.Scale());
+
+ local_main_frame_host_remote_->ScaleFactorChanged(viewport.Scale());
if (dev_tools_emulator_->HasViewportOverride()) {
TransformationMatrix device_emulation_transform =
@@ -3106,8 +3119,7 @@ void WebViewImpl::SetBackgroundColorOverride(SkColor color) {
background_color_override_enabled_ = true;
background_color_override_ = color;
if (MainFrameImpl()) {
- MainFrameImpl()->FrameWidgetImpl()->Client()->SetBackgroundColor(
- BackgroundColor());
+ MainFrameImpl()->FrameWidgetImpl()->SetBackgroundColor(BackgroundColor());
}
}
@@ -3116,8 +3128,7 @@ void WebViewImpl::ClearBackgroundColorOverride() {
background_color_override_enabled_ = false;
if (MainFrameImpl()) {
- MainFrameImpl()->FrameWidgetImpl()->Client()->SetBackgroundColor(
- BackgroundColor());
+ MainFrameImpl()->FrameWidgetImpl()->SetBackgroundColor(BackgroundColor());
}
}
@@ -3132,10 +3143,6 @@ void WebViewImpl::SetMainFrameOverlayColor(SkColor color) {
local_frame->SetMainFrameColorOverlay(color);
}
-WebPageImportanceSignals* WebViewImpl::PageImportanceSignals() {
- return &page_importance_signals_;
-}
-
Element* WebViewImpl::FocusedElement() const {
LocalFrame* frame = AsView().page->GetFocusController().FocusedFrame();
if (!frame)
@@ -3198,28 +3205,23 @@ bool WebViewImpl::TabsToLinks() const {
return tabs_to_links_;
}
-void WebViewImpl::SetRootLayer(scoped_refptr<cc::Layer> layer) {
+void WebViewImpl::DidChangeRootLayer(bool root_layer_exists) {
if (!MainFrameImpl()) {
- DCHECK(!layer);
+ DCHECK(!root_layer_exists);
return;
}
-
- root_layer_ = std::move(layer);
- WebWidgetClient* widget_client = MainFrameImpl()->FrameWidgetImpl()->Client();
- if (root_layer_) {
+ if (root_layer_exists) {
UpdateDeviceEmulationTransform();
- widget_client->SetRootLayer(root_layer_);
} else {
- widget_client->SetRootLayer(nullptr);
-
// When the document in an already-attached main frame is being replaced by
- // a navigation then SetRootLayer(nullptr) will be called. Since we are
+ // a navigation then DidChangeRootLayer(false) will be called. Since we are
// navigating, defer BeginMainFrames until the new document is ready for
// them.
//
// TODO(crbug.com/936696): This should not be needed once we always swap
// frames when swapping documents.
- scoped_defer_main_frame_update_ = widget_client->DeferMainFrameUpdate();
+ scoped_defer_main_frame_update_ =
+ MainFrameImpl()->FrameWidgetImpl()->DeferMainFrameUpdate();
}
}
@@ -3229,13 +3231,6 @@ void WebViewImpl::InvalidateRect(const IntRect& rect) {
AsView().client->DidInvalidateRect(rect);
}
-void WebViewImpl::SetAnimationHost(cc::AnimationHost* animation_host) {
- DCHECK(does_composite_);
- animation_host_ = animation_host;
-
- AsView().page->AnimationHostInitialized(*animation_host_, nullptr);
-}
-
void WebViewImpl::ApplyViewportChanges(const ApplyViewportChangesArgs& args) {
VisualViewport& visual_viewport = GetPage()->GetVisualViewport();
@@ -3263,10 +3258,8 @@ void WebViewImpl::ApplyViewportChanges(const ApplyViewportChangesArgs& args) {
args.elastic_overscroll_delta.y());
UpdateBrowserControlsConstraint(args.browser_controls_constraint);
- if (args.scroll_gesture_did_end &&
- RuntimeEnabledFeatures::UpdateHoverAtBeginFrameEnabled()) {
+ if (args.scroll_gesture_did_end)
MainFrameImpl()->GetFrame()->GetEventHandler().MarkHoverStateDirty();
- }
}
void WebViewImpl::RecordManipulationTypeCounts(cc::ManipulationInfo info) {
@@ -3353,9 +3346,7 @@ void WebViewImpl::UpdateDeviceEmulationTransform() {
// pick ideal raster scales.
// TODO(wjmaclean): This is only done on the main frame's widget currently,
// it should update all local frames.
- WebWidgetClient* widget_client =
- MainFrameImpl()->FrameWidgetImpl()->Client();
- widget_client->ForceRecalculateRasterScales();
+ MainFrameImpl()->FrameWidgetImpl()->SetNeedsRecalculateRasterScales();
}
}
@@ -3463,13 +3454,19 @@ void WebViewImpl::RestorePageFromBackForwardCache(
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(PageVisibilityState::kVisible, /*is_initial_state=*/false);
}
-WebWidget* WebViewImpl::MainFrameWidget() {
+WebFrameWidget* WebViewImpl::MainFrameWidget() {
return web_widget_;
}
@@ -3485,6 +3482,10 @@ int32_t WebViewImpl::AutoplayFlagsForTest() {
return AsView().page->AutoplayFlags();
}
+WebSize WebViewImpl::GetPreferredSizeForTest() {
+ return preferred_size_;
+}
+
void WebViewImpl::StopDeferringMainFrameUpdate() {
DCHECK(MainFrameImpl());
scoped_defer_main_frame_update_ = nullptr;
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 7161adf9368..60cfa746367 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
@@ -35,20 +35,22 @@
#include "base/memory/scoped_refptr.h"
#include "build/build_config.h"
+#include "mojo/public/cpp/bindings/associated_receiver.h"
+#include "mojo/public/cpp/bindings/associated_remote.h"
+#include "third_party/blink/public/common/input/web_gesture_event.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
+#include "third_party/blink/public/mojom/frame/frame.mojom-blink.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/manifest/display_mode.mojom-shared.h"
-#include "third_party/blink/public/platform/web_float_size.h"
-#include "third_party/blink/public/platform/web_gesture_event.h"
-#include "third_party/blink/public/platform/web_input_event.h"
+#include "third_party/blink/public/mojom/page/page.mojom-blink.h"
#include "third_party/blink/public/platform/web_input_event_result.h"
-#include "third_party/blink/public/platform/web_point.h"
#include "third_party/blink/public/platform/web_rect.h"
#include "third_party/blink/public/platform/web_size.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/web_frame_widget.h"
#include "third_party/blink/public/web/web_navigation_policy.h"
-#include "third_party/blink/public/web/web_page_importance_signals.h"
#include "third_party/blink/public/web/web_view.h"
-#include "third_party/blink/public/web/web_widget.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/exported/web_page_popup_impl.h"
#include "third_party/blink/renderer/core/frame/resize_viewport_anchor.h"
@@ -68,7 +70,6 @@
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace cc {
-class Layer;
struct BeginMainFrameMetrics;
class ScopedDeferMainFrameUpdate;
}
@@ -93,6 +94,7 @@ class WebLocalFrameImpl;
class WebRemoteFrame;
class WebSettingsImpl;
class WebViewClient;
+class WebFrameWidgetBase;
struct WebTextAutosizerPageInfo;
@@ -100,12 +102,14 @@ using PaintHoldingCommitTrigger = cc::PaintHoldingCommitTrigger;
class CORE_EXPORT WebViewImpl final : public WebView,
public RefCounted<WebViewImpl>,
- public PageWidgetEventHandler {
+ public PageWidgetEventHandler,
+ public mojom::blink::PageBroadcast {
public:
static WebViewImpl* Create(WebViewClient*,
bool is_hidden,
bool compositing_enabled,
- WebViewImpl* opener);
+ WebViewImpl* opener,
+ mojo::ScopedInterfaceEndpointHandle page_handle);
// All calls to Create() should be balanced with a call to Close(). This
// synchronously destroys the WebViewImpl.
@@ -133,24 +137,28 @@ class CORE_EXPORT WebViewImpl final : public WebView,
void SetDomainRelaxationForbidden(bool, const WebString& scheme) override;
void SetWindowFeatures(const WebWindowFeatures&) override;
void SetOpenedByDOM() override;
- void ResizeWithBrowserControls(const WebSize&,
+ void ResizeWithBrowserControls(const WebSize& main_frame_widget_size,
float top_controls_height,
float bottom_controls_height,
bool browser_controls_shrink_layout) override;
- void ResizeWithBrowserControls(const WebSize&,
+ void ResizeWithBrowserControls(const WebSize& main_frame_widget_size,
+ const WebSize& visible_viewport_size,
cc::BrowserControlsParams) override;
WebFrame* MainFrame() override;
WebLocalFrame* FocusedFrame() override;
void SetFocusedFrame(WebFrame*) override;
void SetInitialFocus(bool reverse) override;
- void ClearFocusedElement() override;
void SmoothScroll(int target_x,
int target_y,
base::TimeDelta duration) override;
void AdvanceFocus(bool reverse) override;
- void AdvanceFocusAcrossFrames(WebFocusType,
+ void AdvanceFocusAcrossFrames(mojom::blink::FocusType,
WebRemoteFrame* from,
WebLocalFrame* to) override;
+ void ZoomAndScrollToFocusedEditableElementRect(
+ const WebRect& element_bounds_in_document,
+ const WebRect& caret_bounds_in_document,
+ bool zoom_into_legible_scale) override;
double ZoomLevel() override;
double SetZoomLevel(double) override;
float TextZoomFactor() override;
@@ -162,19 +170,18 @@ class CORE_EXPORT WebViewImpl final : public WebView,
void SetInitialPageScaleOverride(float) override;
void SetMaximumLegibleScale(float) override;
void SetPageScaleFactor(float) override;
- void SetVisualViewportOffset(const WebFloatPoint&) override;
- WebFloatPoint VisualViewportOffset() const override;
- WebFloatSize VisualViewportSize() const override;
+ void SetVisualViewportOffset(const gfx::PointF&) override;
+ gfx::PointF VisualViewportOffset() const override;
+ gfx::SizeF VisualViewportSize() const override;
void ResizeVisualViewport(const WebSize&) override;
void Resize(const WebSize&) override;
WebSize GetSize() override;
void ResetScrollAndScaleState() override;
void SetIgnoreViewportTagScaleLimits(bool) override;
WebSize ContentsPreferredMinimumSize() override;
+ void UpdatePreferredSize() override;
+ void EnablePreferredSizeChangedMode() override;
void SetDisplayMode(blink::mojom::DisplayMode) override;
- void AnimateDoubleTapZoom(const gfx::Point&,
- const WebRect& block_bounds) override;
- void ZoomToFindInPageRect(const WebRect&) override;
void SetDeviceScaleFactor(float) override;
void SetZoomFactorForDeviceScaleFactor(float) override;
float ZoomFactorForDeviceScaleFactor() override {
@@ -183,7 +190,6 @@ class CORE_EXPORT WebViewImpl final : public WebView,
void EnableAutoResizeMode(const WebSize& min_size,
const WebSize& max_size) override;
void DisableAutoResizeMode() override;
- void PerformPluginAction(const PluginAction&, const gfx::Point&) override;
void AudioStateChanged(bool is_audio_playing) override;
WebHitTestResult HitTestResultAt(const gfx::Point&);
WebHitTestResult HitTestResultForTap(const gfx::Point&,
@@ -196,21 +202,33 @@ class CORE_EXPORT WebViewImpl final : public WebView,
void CancelPagePopup() override;
WebPagePopupImpl* GetPagePopup() const override { return page_popup_.get(); }
void SetMainFrameOverlayColor(SkColor) override;
- WebPageImportanceSignals* PageImportanceSignals() override;
void AcceptLanguagesChanged() override;
void SetPageFrozen(bool frozen) override;
void PutPageIntoBackForwardCache() override;
void RestorePageFromBackForwardCache(
base::TimeTicks navigation_start) override;
- WebWidget* MainFrameWidget() override;
+ WebFrameWidget* MainFrameWidget() override;
void SetBaseBackgroundColor(SkColor) override;
- void SetBackgroundColorOverride(SkColor) override;
- void ClearBackgroundColorOverride() override;
- void SetBaseBackgroundColorOverride(SkColor) override;
- void ClearBaseBackgroundColorOverride() override;
void SetInsidePortal(bool inside_portal) override;
void PaintContent(cc::PaintCanvas*, const gfx::Rect&) override;
- void SetTextAutosizePageInfo(const WebTextAutosizerPageInfo&) override;
+ void SetTextAutosizerPageInfo(const WebTextAutosizerPageInfo&) override;
+
+ // Overrides the page's background and base background color. You
+ // can use this to enforce a transparent background, which is useful if you
+ // want to have some custom background rendered behind the widget.
+ //
+ // These may are only called for composited WebViews.
+ void SetBackgroundColorOverride(SkColor);
+ void ClearBackgroundColorOverride();
+ void SetBaseBackgroundColorOverride(SkColor);
+ void ClearBaseBackgroundColorOverride();
+
+ // Requests a page-scale animation based on the specified point/rect.
+ void AnimateDoubleTapZoom(const gfx::Point&, const WebRect& block_bounds);
+
+ // mojom::blink::PageBroadcast method:
+ void SetPageLifecycleState(mojom::blink::PageLifecycleStatePtr state,
+ SetPageLifecycleStateCallback callback) override;
float DefaultMinimumPageScaleFactor() const;
float DefaultMaximumPageScaleFactor() const;
@@ -320,6 +338,9 @@ class CORE_EXPORT WebViewImpl final : public WebView,
// a plugin can update its own zoom, say because of its own UI.
void FullFramePluginZoomLevelChanged(double zoom_level);
+ // Requests a page-scale animation based on the specified rect.
+ void ZoomToFindInPageRect(const WebRect&);
+
void ComputeScaleAndScrollForBlockRect(
const gfx::Point& hit_point,
const WebRect& block_rect,
@@ -345,7 +366,9 @@ class CORE_EXPORT WebViewImpl final : public WebView,
return fake_page_scale_animation_use_anchor_;
}
- void EnterFullscreen(LocalFrame&, const FullscreenOptions*);
+ void EnterFullscreen(LocalFrame&,
+ const FullscreenOptions*,
+ bool for_cross_process_descendant);
void ExitFullscreen(LocalFrame&);
void FullscreenElementChanged(Element* old_element, Element* new_element);
@@ -359,8 +382,6 @@ class CORE_EXPORT WebViewImpl final : public WebView,
WebSettingsImpl* SettingsImpl();
- cc::AnimationHost* AnimationHost() const { return animation_host_; }
-
BrowserControls& GetBrowserControls();
// Called anytime browser controls layout height or content offset have
// changed.
@@ -372,6 +393,7 @@ class CORE_EXPORT WebViewImpl final : public WebView,
void AddAutoplayFlags(int32_t) override;
void ClearAutoplayFlags() override;
int32_t AutoplayFlagsForTest() override;
+ WebSize GetPreferredSizeForTest() override;
WebSize Size();
IntSize MainFrameSize();
@@ -392,10 +414,6 @@ class CORE_EXPORT WebViewImpl final : public WebView,
WebInputMethodController* GetActiveWebInputMethodController() const;
bool ShouldZoomToLegibleScale(const Element&);
- void ZoomAndScrollToFocusedEditableElementRect(
- const IntRect& element_bounds_in_document,
- const IntRect& caret_bounds_in_document,
- bool zoom_into_legible_scale);
// Allows main frame updates to occur if they were previously blocked. They
// are blocked during loading a navigation, to allow Blink to proceed without
@@ -411,7 +429,8 @@ class CORE_EXPORT WebViewImpl final : public WebView,
void DidEnterFullscreen();
void DidExitFullscreen();
- void SetWebWidget(WebWidget* widget);
+ void SetMainFrameWidgetBase(WebFrameWidgetBase* widget);
+ WebFrameWidgetBase* MainFrameWidgetBase();
private:
FRIEND_TEST_ALL_PREFIXES(WebFrameTest, DivScrollIntoEditableTest);
@@ -441,22 +460,19 @@ class CORE_EXPORT WebViewImpl final : public WebView,
// These are temporary methods to allow WebViewFrameWidget to delegate to
// WebViewImpl. We expect to eventually move these out.
- void SetAnimationHost(cc::AnimationHost*);
void SetSuppressFrameRequestsWorkaroundFor704763Only(bool);
- void BeginFrame(base::TimeTicks last_frame_time,
- bool record_main_frame_metrics);
+ void BeginFrame(base::TimeTicks last_frame_time);
void DidBeginFrame();
- void BeginRafAlignedInput();
- void EndRafAlignedInput();
void BeginUpdateLayers();
void EndUpdateLayers();
void BeginCommitCompositorFrame();
- void EndCommitCompositorFrame();
+ void EndCommitCompositorFrame(base::TimeTicks commit_start_time);
void RecordStartOfFrameMetrics();
- void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time);
+ void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time,
+ cc::ActiveFrameSequenceTrackers trackers);
std::unique_ptr<cc::BeginMainFrameMetrics> GetBeginMainFrameMetrics();
- void UpdateLifecycle(WebWidget::LifecycleUpdate requested_update,
- WebWidget::LifecycleUpdateReason reason);
+ void UpdateLifecycle(WebLifecycleUpdate requested_update,
+ DocumentUpdateReason reason);
void ThemeChanged();
WebInputEventResult HandleInputEvent(const WebCoalescedInputEvent&);
WebInputEventResult DispatchBufferedTouchEvents();
@@ -470,7 +486,6 @@ class CORE_EXPORT WebViewImpl final : public WebView,
void MouseCaptureLost();
void SetFocus(bool enable) override;
bool SelectionBounds(WebRect& anchor, WebRect& focus) const;
- bool IsAcceleratedCompositingActive() const;
void DidAcquirePointerLock();
void DidNotAcquirePointerLock();
void DidLosePointerLock();
@@ -487,22 +502,23 @@ class CORE_EXPORT WebViewImpl final : public WebView,
IntSize ContentsSize() const;
void UpdateBrowserControlsConstraint(cc::BrowserControlsState constraint);
- void UpdateICBAndResizeViewport();
- void ResizeViewWhileAnchored(cc::BrowserControlsParams params);
+ void UpdateICBAndResizeViewport(const IntSize& visible_viewport_size);
+ void ResizeViewWhileAnchored(cc::BrowserControlsParams params,
+ const IntSize& visible_viewport_size);
void UpdateBaseBackgroundColor();
WebViewImpl(WebViewClient*,
bool is_hidden,
bool does_composite,
- WebViewImpl* opener);
+ WebViewImpl* opener,
+ mojo::ScopedInterfaceEndpointHandle page_handle);
~WebViewImpl() override;
HitTestResult HitTestResultForRootFramePos(const PhysicalOffset&);
void ConfigureAutoResizeMode();
- void SetIsAcceleratedCompositingActive(bool);
void DoComposite();
void ReallocateRenderer();
@@ -534,7 +550,7 @@ class CORE_EXPORT WebViewImpl final : public WebView,
float DeviceScaleFactor() const;
- void SetRootLayer(scoped_refptr<cc::Layer>);
+ void DidChangeRootLayer(bool root_layer_exists);
LocalFrame* FocusedLocalFrameInWidget() const;
LocalFrame* FocusedLocalFrameAvailableForIme() const;
@@ -658,9 +674,7 @@ class CORE_EXPORT WebViewImpl final : public WebView,
// the client return a null compositor. We should make things more consistent
// and clear.
const bool does_composite_;
- cc::AnimationHost* animation_host_ = nullptr;
- scoped_refptr<cc::Layer> root_layer_;
bool matches_heuristics_for_gpu_rasterization_ = false;
std::unique_ptr<FullscreenController> fullscreen_controller_;
@@ -684,6 +698,17 @@ class CORE_EXPORT WebViewImpl final : public WebView,
FloatSize elastic_overscroll_;
+ // If true, we send IPC messages when |preferred_size_| changes.
+ bool send_preferred_size_changes_ = false;
+
+ // Whether the preferred size may have changed and |UpdatePreferredSize| needs
+ // to be called.
+ bool needs_preferred_size_update_ = true;
+
+ // Cache the preferred size of the page in order to prevent sending the IPC
+ // when layout() recomputes but doesn't actually change sizes.
+ WebSize preferred_size_;
+
Persistent<EventListener> popup_mouse_wheel_event_listener_;
// The local root whose document has |popup_mouse_wheel_event_listener_|
@@ -692,9 +717,7 @@ class CORE_EXPORT WebViewImpl final : public WebView,
// The WebWidget for the main frame. This is expected to be unset when the
// WebWidget destroys itself.
- WebWidget* web_widget_ = nullptr;
-
- WebPageImportanceSignals page_importance_signals_;
+ WeakPersistent<WebFrameWidgetBase> web_widget_;
// We defer commits when transitioning to a new page. ChromeClientImpl calls
// StopDeferringCommits() to release this when a new page is loaded.
@@ -703,15 +726,17 @@ class CORE_EXPORT WebViewImpl final : public WebView,
Persistent<ResizeViewportAnchor> resize_viewport_anchor_;
+ // Handle to the local main frame host. Only valid when the MainFrame is
+ // local.
+ mojo::AssociatedRemote<mojom::blink::LocalMainFrameHost>
+ local_main_frame_host_remote_;
+
// Set when a measurement begins, reset when the measurement is taken.
- base::Optional<base::TimeTicks> raf_aligned_input_start_time_;
base::Optional<base::TimeTicks> update_layers_start_time_;
base::Optional<base::TimeTicks> commit_compositor_frame_start_time_;
-};
-// We have no ways to check if the specified WebView is an instance of
-// WebViewImpl because WebViewImpl is the only implementation of WebView.
-DEFINE_TYPE_CASTS(WebViewImpl, WebView, webView, true, true);
+ mojo::AssociatedReceiver<mojom::blink::PageBroadcast> receiver_;
+};
} // namespace blink
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 a9897ddc511..5239942bb0d 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
@@ -34,6 +34,7 @@
#include <memory>
#include <string>
+#include "base/bind_helpers.h"
#include "base/stl_util.h"
#include "base/test/test_mock_time_task_runner.h"
#include "base/time/time.h"
@@ -48,15 +49,14 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/common/frame/frame_owner_element_type.h"
+#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/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_coalesced_input_event.h"
-#include "third_party/blink/public/platform/web_cursor_info.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_float_point.h"
-#include "third_party/blink/public/platform/web_input_event.h"
-#include "third_party/blink/public/platform/web_keyboard_event.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"
@@ -70,12 +70,12 @@
#include "third_party/blink/public/web/web_frame_widget.h"
#include "third_party/blink/public/web/web_hit_test_result.h"
#include "third_party/blink/public/web/web_input_method_controller.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_print_params.h"
#include "third_party/blink/public/web/web_script_source.h"
#include "third_party/blink/public/web/web_settings.h"
#include "third_party/blink/public/web/web_tree_scope_type.h"
-#include "third_party/blink/public/web/web_user_gesture_indicator.h"
#include "third_party/blink/public/web/web_view_client.h"
#include "third_party/blink/public/web/web_widget.h"
#include "third_party/blink/public/web/web_widget_client.h"
@@ -100,9 +100,12 @@
#include "third_party/blink/renderer/core/html/forms/external_date_time_chooser.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/html/html_document.h"
#include "third_party/blink/renderer/core/html/html_iframe_element.h"
#include "third_party/blink/renderer/core/html/html_object_element.h"
+#include "third_party/blink/renderer/core/html/html_span_element.h"
#include "third_party/blink/renderer/core/inspector/dev_tools_emulator.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/loader/document_loader.h"
#include "third_party/blink/renderer/core/loader/frame_load_request.h"
@@ -120,9 +123,12 @@
#include "third_party/blink/renderer/core/scroll/scroll_types.h"
#include "third_party/blink/renderer/core/testing/color_scheme_helper.h"
#include "third_party/blink/renderer/core/testing/fake_web_plugin.h"
+#include "third_party/blink/renderer/core/testing/mock_clipboard_host.h"
+#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/core/timing/event_timing.h"
#include "third_party/blink/renderer/core/timing/window_performance.h"
+#include "third_party/blink/renderer/platform/cursors.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
#include "third_party/blink/renderer/platform/geometry/int_size.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
@@ -136,6 +142,8 @@
#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
+#include "ui/base/cursor/cursor.h"
+#include "ui/base/mojom/cursor_type.mojom-blink.h"
#include "ui/events/keycodes/dom/dom_key.h"
#include "v8/include/v8.h"
@@ -144,7 +152,6 @@
#endif
#if BUILDFLAG(ENABLE_UNHANDLED_TAP)
-#include "mojo/public/cpp/bindings/strong_binding.h"
#include "third_party/blink/public/mojom/unhandled_tap_notifier/unhandled_tap_notifier.mojom-blink.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
#endif // BUILDFLAG(ENABLE_UNHANDLED_TAP)
@@ -209,11 +216,11 @@ class TapHandlingWebWidgetClient
void DidHandleGestureEvent(const WebGestureEvent& event,
bool event_cancelled) override {
if (event.GetType() == WebInputEvent::kGestureTap) {
- tap_x_ = event.PositionInWidget().x;
- tap_y_ = event.PositionInWidget().y;
+ tap_x_ = event.PositionInWidget().x();
+ tap_y_ = event.PositionInWidget().y();
} else if (event.GetType() == WebInputEvent::kGestureLongPress) {
- longpress_x_ = event.PositionInWidget().x;
- longpress_y_ = event.PositionInWidget().y;
+ longpress_x_ = event.PositionInWidget().x();
+ longpress_y_ = event.PositionInWidget().y();
}
}
@@ -294,7 +301,7 @@ class WebViewTest : public testing::Test {
void UpdateAllLifecyclePhases() {
web_view_helper_.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
}
InteractiveDetector* GetTestInteractiveDetector(Document& document) {
@@ -324,6 +331,11 @@ static std::string HitTestElementId(WebView* view, int x, int y) {
return hit_test_result.GetNode().To<WebElement>().GetAttribute("id").Utf8();
}
+static Color OutlineColor(Element* element) {
+ return element->GetComputedStyle()->VisitedDependentColor(
+ GetCSSPropertyOutlineColor());
+}
+
TEST_F(WebViewTest, HitTestVideo) {
// Test that hit tests on parts of a video element result in hits on the video
// element itself as opposed to its child elements.
@@ -497,7 +509,9 @@ TEST_F(WebViewTest, SetBaseBackgroundColorBeforeMainFrame) {
frame_test_helpers::TestWebWidgetClient web_widget_client;
WebViewImpl* web_view = static_cast<WebViewImpl*>(
WebView::Create(&web_view_client, false,
- /*compositing_enabled=*/true, nullptr));
+ /*compositing_enabled=*/true, nullptr,
+ mojo::ScopedInterfaceEndpointHandle()));
+
EXPECT_NE(SK_ColorBLUE, web_view->BackgroundColor());
// WebView does not have a frame yet, but we should still be able to set the
// background color.
@@ -512,8 +526,15 @@ TEST_F(WebViewTest, SetBaseBackgroundColorBeforeMainFrame) {
{
// Copy the steps done from WebViewHelper::InitializeWithOpener() to set up
// the appropriate pointers!
- web_view->SetAnimationHost(web_widget_client.animation_host());
- blink::WebFrameWidget::CreateForMainFrame(&web_widget_client, frame);
+ WebFrameWidget* widget = blink::WebFrameWidget::CreateForMainFrame(
+ &web_widget_client, frame,
+ CrossVariantMojoAssociatedRemote<mojom::FrameWidgetHostInterfaceBase>(),
+ CrossVariantMojoAssociatedReceiver<mojom::FrameWidgetInterfaceBase>(),
+ CrossVariantMojoAssociatedRemote<mojom::WidgetHostInterfaceBase>(),
+ CrossVariantMojoAssociatedReceiver<mojom::WidgetInterfaceBase>());
+ widget->SetCompositorHosts(web_widget_client.layer_tree_host(),
+ web_widget_client.animation_host());
+ widget->SetCompositorVisible(true);
web_view->DidAttachLocalMainFrame();
}
@@ -574,9 +595,8 @@ TEST_F(WebViewTest, SetBaseBackgroundColorWithColorScheme) {
ScopedCSSColorSchemeForTest enable_color_scheme(true);
WebViewImpl* web_view = web_view_helper_.Initialize();
- ColorSchemeHelper color_scheme_helper;
- color_scheme_helper.SetPreferredColorScheme(*(web_view->GetPage()),
- PreferredColorScheme::kLight);
+ ColorSchemeHelper color_scheme_helper(*(web_view->GetPage()));
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kLight);
web_view->SetBaseBackgroundColor(SK_ColorBLUE);
WebURL base_url = url_test_helpers::ToKURL("http://example.com/");
@@ -588,8 +608,7 @@ TEST_F(WebViewTest, SetBaseBackgroundColorWithColorScheme) {
LocalFrameView* frame_view = web_view->MainFrameImpl()->GetFrame()->View();
EXPECT_EQ(Color(0, 0, 255), frame_view->BaseBackgroundColor());
- color_scheme_helper.SetPreferredColorScheme(*(web_view->GetPage()),
- PreferredColorScheme::kDark);
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kDark);
UpdateAllLifecyclePhases();
EXPECT_EQ(Color::kBlack, frame_view->BaseBackgroundColor());
@@ -599,8 +618,7 @@ TEST_F(WebViewTest, SetBaseBackgroundColorWithColorScheme) {
web_view->SetBaseBackgroundColor(SK_ColorBLUE);
EXPECT_EQ(Color::kBlack, frame_view->BaseBackgroundColor());
- color_scheme_helper.SetPreferredColorScheme(*(web_view->GetPage()),
- PreferredColorScheme::kLight);
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kLight);
UpdateAllLifecyclePhases();
EXPECT_EQ(Color(0, 0, 255), frame_view->BaseBackgroundColor());
}
@@ -613,7 +631,7 @@ TEST_F(WebViewTest, FocusIsInactive) {
web_view->MainFrameWidget()->SetFocus(true);
web_view->SetIsActive(true);
WebLocalFrameImpl* frame = web_view->MainFrameImpl();
- EXPECT_TRUE(frame->GetFrame()->GetDocument()->IsHTMLDocument());
+ EXPECT_TRUE(IsA<HTMLDocument>(frame->GetFrame()->GetDocument()));
Document* document = frame->GetFrame()->GetDocument();
EXPECT_TRUE(document->hasFocus());
@@ -674,6 +692,60 @@ TEST_F(WebViewTest, DocumentHasFocus) {
EXPECT_EQ("document.hasFocus(): true", log_element.TextContent());
}
+TEST_F(WebViewTest, PlatformColorsChangedOnDeviceEmulation) {
+ WebViewImpl* web_view_impl = web_view_helper_.Initialize();
+ WebURL base_url = url_test_helpers::ToKURL("http://example.com/");
+ frame_test_helpers::LoadHTMLString(
+ web_view_impl->MainFrameImpl(),
+ "<style>"
+ " span { outline-color: -webkit-focus-ring-color; }"
+ "</style>"
+ "<span id='span1'></span>",
+ base_url);
+ UpdateAllLifecyclePhases();
+
+ WebDeviceEmulationParams params;
+ params.screen_position = WebDeviceEmulationParams::kMobile;
+
+ Document& document =
+ *web_view_impl->MainFrameImpl()->GetFrame()->GetDocument();
+
+ Element* span1 = document.getElementById("span1");
+ ASSERT_TRUE(span1);
+
+ // Check non-MobileLayoutTheme color.
+ Color original = LayoutTheme::GetTheme().FocusRingColor();
+ EXPECT_EQ(original, OutlineColor(span1));
+
+ // Set the focus ring color for the mobile theme to something known.
+ Color custom_color = MakeRGB(123, 145, 167);
+ {
+ ScopedMobileLayoutThemeForTest mobile_layout_theme_enabled(true);
+ LayoutTheme::GetTheme().SetCustomFocusRingColor(custom_color);
+ }
+
+ EXPECT_NE(custom_color, original);
+ web_view_impl->EnableDeviceEmulation(params);
+
+ // All <span>s should have the custom outline color, and not (for example)
+ // the original color fetched from cache.
+ auto* span2 = MakeGarbageCollected<HTMLSpanElement>(document);
+ document.body()->AppendChild(span2);
+ UpdateAllLifecyclePhases();
+ EXPECT_EQ(custom_color, OutlineColor(span1));
+ EXPECT_EQ(custom_color, OutlineColor(span2));
+
+ // Disable mobile emulation. All <span>s should once again have the
+ // original outline color.
+ web_view_impl->DisableDeviceEmulation();
+ auto* span3 = MakeGarbageCollected<HTMLSpanElement>(document);
+ document.body()->AppendChild(span3);
+ UpdateAllLifecyclePhases();
+ EXPECT_EQ(original, OutlineColor(span1));
+ EXPECT_EQ(original, OutlineColor(span2));
+ EXPECT_EQ(original, OutlineColor(span3));
+}
+
TEST_F(WebViewTest, ActiveState) {
RegisterMockedHttpURLLoad("visible_iframe.html");
WebView* web_view =
@@ -736,7 +808,7 @@ TEST_F(WebViewTest, HitTestResultAtWithPageScaleAndPan) {
positive_result.Reset();
// Pan around the zoomed in page so the image is not visible in viewport.
- web_view->SetVisualViewportOffset(WebFloatPoint(100, 100));
+ web_view->SetVisualViewportOffset(gfx::PointF(100, 100));
WebHitTestResult negative_result2 = web_view->HitTestResultAt(hit_point);
EXPECT_FALSE(
negative_result2.GetNode().To<WebElement>().HasHTMLTagName("img"));
@@ -794,7 +866,7 @@ TEST_F(WebViewTest, HitTestResultForTapWithTapAreaPageScaleAndPan) {
// Zoom in and pan around the page so the image is not visible in viewport.
web_view->SetPageScaleFactor(2.0f);
- web_view->SetVisualViewportOffset(WebFloatPoint(100, 100));
+ web_view->SetVisualViewportOffset(gfx::PointF(100, 100));
WebHitTestResult negative_result2 =
web_view->HitTestResultForTap(hit_point, tap_area);
EXPECT_FALSE(
@@ -934,7 +1006,7 @@ void WebViewTest::TestTextInputType(WebTextInputType expected_type,
web_view->SetInitialFocus(false);
EXPECT_EQ(expected_type, controller->TextInputType());
EXPECT_EQ(expected_type, controller->TextInputInfo().type);
- web_view->ClearFocusedElement();
+ web_view->FocusedElement()->blur();
EXPECT_EQ(kWebTextInputTypeNone, controller->TextInputType());
EXPECT_EQ(kWebTextInputTypeNone, controller->TextInputInfo().type);
}
@@ -1144,7 +1216,7 @@ TEST_F(WebViewTest, LongPressOutsideInputShouldNotSelectPlaceholderText) {
WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(WebFloatPoint(100, 150));
+ event.SetPositionInWidget(gfx::PointF(100, 150));
EXPECT_EQ(WebInputEventResult::kHandledSystem,
web_view->MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(event)));
@@ -1647,8 +1719,10 @@ TEST_F(WebViewTest, SetCompositionFromExistingText) {
base_url_ + "input_field_populated.html");
web_view->SetInitialFocus(false);
WebVector<WebImeTextSpan> ime_text_spans(static_cast<size_t>(1));
- ime_text_spans[0] = WebImeTextSpan(WebImeTextSpan::Type::kComposition, 0, 4,
- ui::mojom::ImeTextSpanThickness::kThin, 0);
+ ime_text_spans[0] =
+ WebImeTextSpan(WebImeTextSpan::Type::kComposition, 0, 4,
+ ui::mojom::ImeTextSpanThickness::kThin,
+ ui::mojom::ImeTextSpanUnderlineStyle::kSolid, 0, 0);
WebLocalFrameImpl* frame = web_view->MainFrameImpl();
WebInputMethodController* active_input_method_controller =
frame->GetInputMethodController();
@@ -1674,8 +1748,10 @@ TEST_F(WebViewTest, SetCompositionFromExistingTextInTextArea) {
base_url_ + "text_area_populated.html");
web_view->SetInitialFocus(false);
WebVector<WebImeTextSpan> ime_text_spans(static_cast<size_t>(1));
- ime_text_spans[0] = WebImeTextSpan(WebImeTextSpan::Type::kComposition, 0, 4,
- ui::mojom::ImeTextSpanThickness::kThin, 0);
+ ime_text_spans[0] =
+ WebImeTextSpan(WebImeTextSpan::Type::kComposition, 0, 4,
+ ui::mojom::ImeTextSpanThickness::kThin,
+ ui::mojom::ImeTextSpanUnderlineStyle::kSolid, 0, 0);
WebLocalFrameImpl* frame = web_view->MainFrameImpl();
WebInputMethodController* active_input_method_controller =
frame->FrameWidget()->GetActiveWebInputMethodController();
@@ -1715,8 +1791,10 @@ TEST_F(WebViewTest, SetCompositionFromExistingTextInRichText) {
base_url_ + "content_editable_rich_text.html");
web_view->SetInitialFocus(false);
WebVector<WebImeTextSpan> ime_text_spans(static_cast<size_t>(1));
- ime_text_spans[0] = WebImeTextSpan(WebImeTextSpan::Type::kComposition, 0, 4,
- ui::mojom::ImeTextSpanThickness::kThin, 0);
+ ime_text_spans[0] =
+ WebImeTextSpan(WebImeTextSpan::Type::kComposition, 0, 4,
+ ui::mojom::ImeTextSpanThickness::kThin,
+ ui::mojom::ImeTextSpanUnderlineStyle::kSolid, 0, 0);
WebLocalFrameImpl* frame = web_view->MainFrameImpl();
frame->SetEditableSelectionOffsets(1, 1);
WebDocument document = web_view->MainFrameImpl()->GetDocument();
@@ -1807,7 +1885,8 @@ TEST_F(WebViewTest, IsSelectionAnchorFirst) {
WebRect anchor;
WebRect focus;
web_view->MainFrameWidget()->SelectionBounds(anchor, focus);
- frame->SelectRange(WebPoint(focus.x, focus.y), WebPoint(anchor.x, anchor.y));
+ frame->SelectRange(gfx::Point(focus.x, focus.y),
+ gfx::Point(anchor.x, anchor.y));
EXPECT_FALSE(frame->IsSelectionAnchorFirst());
}
@@ -1862,12 +1941,13 @@ TEST_F(
EXPECT_EQ(focused_elements[i].next_previous_flags, next_previous_flags);
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- current_focus, kWebFocusTypeForward);
+ current_focus, mojom::blink::FocusType::kForward);
if (next_focus) {
EXPECT_EQ(next_focus->GetIdAttribute(),
focused_elements[i + 1].element_id);
}
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeForward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kForward);
}
// Now focus will stay on previous focus itself, because it has no next
// element.
@@ -1882,12 +1962,13 @@ TEST_F(
EXPECT_EQ(focused_elements[i].next_previous_flags, next_previous_flags);
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- current_focus, kWebFocusTypeBackward);
+ current_focus, mojom::blink::FocusType::kBackward);
if (next_focus) {
EXPECT_EQ(next_focus->GetIdAttribute(),
focused_elements[i - 1].element_id);
}
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeBackward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kBackward);
}
// Now focus will stay on previous focus itself, because it has no previous
// element.
@@ -1904,17 +1985,19 @@ TEST_F(
next_previous_flags);
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- button1, kWebFocusTypeForward);
+ button1, mojom::blink::FocusType::kForward);
EXPECT_EQ(next_focus->GetIdAttribute(), "contenteditable1");
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeForward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kForward);
Element* content_editable1 = document->getElementById("contenteditable1");
EXPECT_EQ(content_editable1, document->FocusedElement());
button1->focus();
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- button1, kWebFocusTypeBackward);
+ button1, mojom::blink::FocusType::kBackward);
EXPECT_EQ(next_focus->GetIdAttribute(), "input1");
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeBackward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kBackward);
EXPECT_EQ(input1, document->FocusedElement());
Element* anchor1 = document->getElementById("anchor1");
@@ -1925,18 +2008,20 @@ TEST_F(
EXPECT_EQ(0, next_previous_flags);
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- anchor1, kWebFocusTypeForward);
+ anchor1, mojom::blink::FocusType::kForward);
EXPECT_EQ(next_focus, nullptr);
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeForward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kForward);
// Since anchor is not a form control element, next/previous element will
// be null, hence focus will stay same as it is.
EXPECT_EQ(anchor1, document->FocusedElement());
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- anchor1, kWebFocusTypeBackward);
+ anchor1, mojom::blink::FocusType::kBackward);
EXPECT_EQ(next_focus, nullptr);
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeBackward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kBackward);
EXPECT_EQ(anchor1, document->FocusedElement());
// Navigation of elements which is not part of any forms.
@@ -1948,17 +2033,19 @@ TEST_F(
EXPECT_EQ(default_text_input_flags, next_previous_flags);
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- text_area3, kWebFocusTypeForward);
+ text_area3, mojom::blink::FocusType::kForward);
EXPECT_EQ(next_focus, nullptr);
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeForward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kForward);
// No Next/Previous element to this element because it's not part of any
// form. Hence focus won't change wrt NEXT/PREVIOUS.
EXPECT_EQ(text_area3, document->FocusedElement());
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- text_area3, kWebFocusTypeBackward);
+ text_area3, mojom::blink::FocusType::kBackward);
EXPECT_EQ(next_focus, nullptr);
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeBackward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kBackward);
EXPECT_EQ(text_area3, document->FocusedElement());
// Navigation from an element which is part of a form but not an editable
@@ -1971,43 +2058,47 @@ TEST_F(
EXPECT_EQ(kWebTextInputFlagHavePreviousFocusableElement, next_previous_flags);
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- button2, kWebFocusTypeForward);
+ button2, mojom::blink::FocusType::kForward);
EXPECT_EQ(next_focus, nullptr);
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeForward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kForward);
// No Next element to this element because it's not part of any form.
// Hence focus won't change wrt NEXT.
EXPECT_EQ(button2, document->FocusedElement());
Element* text_area2 = document->getElementById("textarea2");
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- button2, kWebFocusTypeBackward);
+ button2, mojom::blink::FocusType::kBackward);
EXPECT_EQ(next_focus, text_area2);
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeBackward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kBackward);
// Since button is a form control element from form1, ensuring focus is set
// at correct position.
EXPECT_EQ(text_area2, document->FocusedElement());
Element* content_editable2 = document->getElementById("contenteditable2");
document->SetFocusedElement(
- content_editable2,
- FocusParams(SelectionBehaviorOnFocus::kNone, kWebFocusTypeNone, nullptr));
+ content_editable2, FocusParams(SelectionBehaviorOnFocus::kNone,
+ mojom::blink::FocusType::kNone, nullptr));
next_previous_flags =
active_input_method_controller->ComputeWebTextInputNextPreviousFlags();
// No Next/Previous element for elements outside form.
EXPECT_EQ(0, next_previous_flags);
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- content_editable2, kWebFocusTypeForward);
+ content_editable2, mojom::blink::FocusType::kForward);
EXPECT_EQ(next_focus, nullptr);
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeForward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kForward);
// No Next/Previous element to this element because it's not part of any
// form. Hence focus won't change wrt NEXT/PREVIOUS.
EXPECT_EQ(content_editable2, document->FocusedElement());
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- content_editable2, kWebFocusTypeBackward);
+ content_editable2, mojom::blink::FocusType::kBackward);
EXPECT_EQ(next_focus, nullptr);
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeBackward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kBackward);
EXPECT_EQ(content_editable2, document->FocusedElement());
// Navigation of elements which is having invalid form attribute and hence
@@ -2021,17 +2112,19 @@ TEST_F(
EXPECT_EQ(default_text_input_flags, next_previous_flags);
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- text_area4, kWebFocusTypeForward);
+ text_area4, mojom::blink::FocusType::kForward);
EXPECT_EQ(next_focus, nullptr);
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeForward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kForward);
// No Next/Previous element to this element because it's not part of any
// form. Hence focus won't change wrt NEXT/PREVIOUS.
EXPECT_EQ(text_area4, document->FocusedElement());
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- text_area4, kWebFocusTypeBackward);
+ text_area4, mojom::blink::FocusType::kBackward);
EXPECT_EQ(next_focus, nullptr);
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeBackward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kBackward);
EXPECT_EQ(text_area4, document->FocusedElement());
web_view_helper_.Reset();
@@ -2081,12 +2174,13 @@ TEST_F(
EXPECT_EQ(focused_elements[i].next_previous_flags, next_previous_flags);
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- current_focus, kWebFocusTypeForward);
+ current_focus, mojom::blink::FocusType::kForward);
if (next_focus) {
EXPECT_EQ(next_focus->GetIdAttribute(),
focused_elements[i + 1].element_id);
}
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeForward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kForward);
}
// Now focus will stay on previous focus itself, because it has no next
// element.
@@ -2101,12 +2195,13 @@ TEST_F(
EXPECT_EQ(focused_elements[i].next_previous_flags, next_previous_flags);
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- current_focus, kWebFocusTypeBackward);
+ current_focus, mojom::blink::FocusType::kBackward);
if (next_focus) {
EXPECT_EQ(next_focus->GetIdAttribute(),
focused_elements[i - 1].element_id);
}
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeBackward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kBackward);
}
// Now focus will stay on previous focus itself, because it has no previous
// element.
@@ -2122,17 +2217,19 @@ TEST_F(
EXPECT_EQ(0, next_previous_flags);
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- anchor2, kWebFocusTypeForward);
+ anchor2, mojom::blink::FocusType::kForward);
EXPECT_EQ(next_focus, nullptr);
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeForward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kForward);
// Since anchor is not a form control element, next/previous element will
// be null, hence focus will stay same as it is.
EXPECT_EQ(anchor2, document->FocusedElement());
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- anchor2, kWebFocusTypeBackward);
+ anchor2, mojom::blink::FocusType::kBackward);
EXPECT_EQ(next_focus, nullptr);
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeBackward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kBackward);
EXPECT_EQ(anchor2, document->FocusedElement());
web_view_helper_.Reset();
@@ -2182,12 +2279,13 @@ TEST_F(WebViewTest, MoveFocusToNextFocusableElementInFormWithTabIndexElements) {
EXPECT_EQ(focused_elements[i].next_previous_flags, next_previous_flags);
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- current_focus, kWebFocusTypeForward);
+ current_focus, mojom::blink::FocusType::kForward);
if (next_focus) {
EXPECT_EQ(next_focus->GetIdAttribute(),
focused_elements[i + 1].element_id);
}
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeForward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kForward);
}
// No next editable element which is focusable with proper tab index, hence
// staying on previous focus.
@@ -2203,12 +2301,13 @@ TEST_F(WebViewTest, MoveFocusToNextFocusableElementInFormWithTabIndexElements) {
EXPECT_EQ(focused_elements[i].next_previous_flags, next_previous_flags);
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- current_focus, kWebFocusTypeBackward);
+ current_focus, mojom::blink::FocusType::kBackward);
if (next_focus) {
EXPECT_EQ(next_focus->GetIdAttribute(),
focused_elements[i - 1].element_id);
}
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeBackward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kBackward);
}
// Now focus will stay on previous focus itself, because it has no previous
// element.
@@ -2221,16 +2320,18 @@ TEST_F(WebViewTest, MoveFocusToNextFocusableElementInFormWithTabIndexElements) {
Element* input6 = document->getElementById("input6");
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- content_editable5, kWebFocusTypeForward);
+ content_editable5, mojom::blink::FocusType::kForward);
EXPECT_EQ(next_focus, input6);
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeForward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kForward);
EXPECT_EQ(input6, document->FocusedElement());
content_editable5->focus();
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- content_editable5, kWebFocusTypeBackward);
+ content_editable5, mojom::blink::FocusType::kBackward);
EXPECT_EQ(next_focus, text_area6);
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeBackward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kBackward);
EXPECT_EQ(text_area6, document->FocusedElement());
web_view_helper_.Reset();
@@ -2272,12 +2373,13 @@ TEST_F(WebViewTest,
EXPECT_EQ(focused_elements[i].next_previous_flags, next_previous_flags);
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- current_focus, kWebFocusTypeForward);
+ current_focus, mojom::blink::FocusType::kForward);
if (next_focus) {
EXPECT_EQ(next_focus->GetIdAttribute(),
focused_elements[i + 1].element_id);
}
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeForward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kForward);
}
// No next editable element which is focusable, hence staying on previous
// focus.
@@ -2293,12 +2395,13 @@ TEST_F(WebViewTest,
EXPECT_EQ(focused_elements[i].next_previous_flags, next_previous_flags);
next_focus =
document->GetPage()->GetFocusController().NextFocusableElementInForm(
- current_focus, kWebFocusTypeBackward);
+ current_focus, mojom::blink::FocusType::kBackward);
if (next_focus) {
EXPECT_EQ(next_focus->GetIdAttribute(),
focused_elements[i - 1].element_id);
}
- web_view->MainFrameImpl()->AdvanceFocusInForm(kWebFocusTypeBackward);
+ web_view->MainFrameImpl()->GetFrame()->AdvanceFocusInForm(
+ mojom::blink::FocusType::kBackward);
}
// Now focus will stay on previous focus itself, because it has no previous
// element.
@@ -2381,7 +2484,7 @@ TEST_F(WebViewTest, BackForwardRestoreScroll) {
base_url_ + "back_forward_restore_scroll.html");
web_view_impl->MainFrameWidget()->Resize(WebSize(640, 480));
web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
// Emulate a user scroll
web_view_impl->MainFrameImpl()->SetScrollOffset(WebSize(0, 900));
@@ -2391,9 +2494,10 @@ TEST_F(WebViewTest, BackForwardRestoreScroll) {
main_frame_local->Loader().GetDocumentLoader()->GetHistoryItem();
// Click an anchor
- main_frame_local->Loader().StartNavigation(FrameLoadRequest(
+ FrameLoadRequest request_a(
main_frame_local->GetDocument(),
- ResourceRequest(main_frame_local->GetDocument()->CompleteURL("#a"))));
+ ResourceRequest(main_frame_local->GetDocument()->CompleteURL("#a")));
+ main_frame_local->Loader().StartNavigation(request_a);
Persistent<HistoryItem> item2 =
main_frame_local->Loader().GetDocumentLoader()->GetHistoryItem();
@@ -2407,22 +2511,33 @@ TEST_F(WebViewTest, BackForwardRestoreScroll) {
main_frame_local->Loader().GetDocumentLoader()->CommitSameDocumentNavigation(
item1->Url(), WebFrameLoadType::kBackForward, item1.Get(),
ClientRedirectPolicy::kNotClientRedirect, nullptr, false, nullptr);
+ web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(
+ DocumentUpdateReason::kTest);
// Click a different anchor
- main_frame_local->Loader().StartNavigation(FrameLoadRequest(
+ FrameLoadRequest request_b(
main_frame_local->GetDocument(),
- ResourceRequest(main_frame_local->GetDocument()->CompleteURL("#b"))));
+ ResourceRequest(main_frame_local->GetDocument()->CompleteURL("#b")));
+ main_frame_local->Loader().StartNavigation(request_b);
Persistent<HistoryItem> item3 =
main_frame_local->Loader().GetDocumentLoader()->GetHistoryItem();
+ web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(
+ DocumentUpdateReason::kTest);
// Go back, then forward. The scroll position should be properly set on the
// forward navigation.
main_frame_local->Loader().GetDocumentLoader()->CommitSameDocumentNavigation(
item1->Url(), WebFrameLoadType::kBackForward, item1.Get(),
ClientRedirectPolicy::kNotClientRedirect, nullptr, false, nullptr);
+
main_frame_local->Loader().GetDocumentLoader()->CommitSameDocumentNavigation(
item3->Url(), WebFrameLoadType::kBackForward, item3.Get(),
ClientRedirectPolicy::kNotClientRedirect, nullptr, false, nullptr);
+ // The scroll offset is only applied via invoking the anchor via the main
+ // lifecycle, or a forced layout.
+ // TODO(chrishtr): At the moment, WebLocalFrameImpl::GetScrollOffset() does
+ // not force a layout. Script-exposed scroll offset-reading methods do,
+ // however. It seems wrong not to force a layout.
EXPECT_EQ(0, web_view_impl->MainFrameImpl()->GetScrollOffset().width);
EXPECT_GT(web_view_impl->MainFrameImpl()->GetScrollOffset().height, 2000);
}
@@ -2516,8 +2631,8 @@ static void DragAndDropURL(WebViewImpl* web_view, const std::string& url) {
item.string_data = WebString::FromUTF8(url);
drag_data.AddItem(item);
- const WebFloatPoint client_point(0, 0);
- const WebFloatPoint screen_point(0, 0);
+ const gfx::PointF client_point;
+ const gfx::PointF screen_point;
WebFrameWidget* widget = web_view->MainFrameImpl()->FrameWidget();
widget->DragTargetDragEnter(drag_data, client_point, screen_point,
kWebDragOperationCopy, 0);
@@ -2614,14 +2729,14 @@ TEST_F(WebViewTest, ClientTapHandling) {
WebGestureEvent event(WebInputEvent::kGestureTap, WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(WebFloatPoint(3, 8));
+ event.SetPositionInWidget(gfx::PointF(3, 8));
web_view->MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(event));
RunPendingTasks();
EXPECT_EQ(3, client.TapX());
EXPECT_EQ(8, client.TapY());
client.Reset();
event.SetType(WebInputEvent::kGestureLongPress);
- event.SetPositionInWidget(WebFloatPoint(25, 7));
+ event.SetPositionInWidget(gfx::PointF(25, 7));
web_view->MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(event));
RunPendingTasks();
EXPECT_EQ(25, client.LongpressX());
@@ -2636,18 +2751,24 @@ TEST_F(WebViewTest, ClientTapHandlingNullWebViewClient) {
// internal WebViewClient on demand if the supplied WebViewClient is null.
WebViewImpl* web_view = static_cast<WebViewImpl*>(
WebView::Create(nullptr, false,
- /*compositing_enabled=*/false, nullptr));
+ /*compositing_enabled=*/false, nullptr,
+ mojo::ScopedInterfaceEndpointHandle()));
frame_test_helpers::TestWebFrameClient web_frame_client;
frame_test_helpers::TestWebWidgetClient web_widget_client;
WebLocalFrame* local_frame = WebLocalFrame::CreateMainFrame(
web_view, &web_frame_client, nullptr, nullptr);
web_frame_client.Bind(local_frame);
- blink::WebFrameWidget::CreateForMainFrame(&web_widget_client, local_frame);
+ blink::WebFrameWidget::CreateForMainFrame(
+ &web_widget_client, local_frame,
+ CrossVariantMojoAssociatedRemote<mojom::FrameWidgetHostInterfaceBase>(),
+ CrossVariantMojoAssociatedReceiver<mojom::FrameWidgetInterfaceBase>(),
+ CrossVariantMojoAssociatedRemote<mojom::WidgetHostInterfaceBase>(),
+ CrossVariantMojoAssociatedReceiver<mojom::WidgetInterfaceBase>());
WebGestureEvent event(WebInputEvent::kGestureTap, WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(WebFloatPoint(3, 8));
+ event.SetPositionInWidget(gfx::PointF(3, 8));
EXPECT_EQ(WebInputEventResult::kNotHandled,
web_view->MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(event)));
@@ -2668,7 +2789,7 @@ TEST_F(WebViewTest, LongPressEmptyDiv) {
WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(WebFloatPoint(250, 150));
+ event.SetPositionInWidget(gfx::PointF(250, 150));
EXPECT_EQ(WebInputEventResult::kNotHandled,
web_view->MainFrameWidget()->HandleInputEvent(
@@ -2689,7 +2810,7 @@ TEST_F(WebViewTest, LongPressEmptyDivAlwaysShow) {
WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(WebFloatPoint(250, 150));
+ event.SetPositionInWidget(gfx::PointF(250, 150));
EXPECT_EQ(WebInputEventResult::kHandledSystem,
web_view->MainFrameWidget()->HandleInputEvent(
@@ -2710,7 +2831,7 @@ TEST_F(WebViewTest, LongPressObject) {
WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(WebFloatPoint(10, 10));
+ event.SetPositionInWidget(gfx::PointF(10, 10));
EXPECT_NE(WebInputEventResult::kHandledSystem,
web_view->MainFrameWidget()->HandleInputEvent(
@@ -2735,7 +2856,7 @@ TEST_F(WebViewTest, LongPressObjectFallback) {
WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(WebFloatPoint(10, 10));
+ event.SetPositionInWidget(gfx::PointF(10, 10));
EXPECT_EQ(WebInputEventResult::kHandledSystem,
web_view->MainFrameWidget()->HandleInputEvent(
@@ -2760,7 +2881,7 @@ TEST_F(WebViewTest, LongPressImage) {
WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(WebFloatPoint(10, 10));
+ event.SetPositionInWidget(gfx::PointF(10, 10));
EXPECT_EQ(WebInputEventResult::kHandledSystem,
web_view->MainFrameWidget()->HandleInputEvent(
@@ -2785,7 +2906,7 @@ TEST_F(WebViewTest, LongPressVideo) {
WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(WebFloatPoint(10, 10));
+ event.SetPositionInWidget(gfx::PointF(10, 10));
EXPECT_EQ(WebInputEventResult::kHandledSystem,
web_view->MainFrameWidget()->HandleInputEvent(
@@ -2806,7 +2927,7 @@ TEST_F(WebViewTest, LongPressLink) {
WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(WebFloatPoint(500, 300));
+ event.SetPositionInWidget(gfx::PointF(500, 300));
EXPECT_EQ(WebInputEventResult::kHandledSystem,
web_view->MainFrameWidget()->HandleInputEvent(
@@ -2894,7 +3015,7 @@ TEST_F(WebViewTest, LongPressEmptyEditableSelection) {
WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(WebFloatPoint(10, 10));
+ event.SetPositionInWidget(gfx::PointF(10, 10));
EXPECT_EQ(WebInputEventResult::kHandledSystem,
web_view->MainFrameWidget()->HandleInputEvent(
@@ -2914,7 +3035,7 @@ TEST_F(WebViewTest, LongPressEmptyNonEditableSelection) {
WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(WebFloatPoint(300, 300));
+ event.SetPositionInWidget(gfx::PointF(300, 300));
WebLocalFrameImpl* frame = web_view->MainFrameImpl();
EXPECT_EQ(WebInputEventResult::kHandledSystem,
@@ -2999,7 +3120,7 @@ TEST_F(WebViewTest, TouchDoesntSelectEmptyTextarea) {
WebGestureEvent event(WebInputEvent::kGestureTap, WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(WebFloatPoint(100, 25));
+ event.SetPositionInWidget(gfx::PointF(100, 25));
event.data.tap.tap_count = 2;
web_view->MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(event));
@@ -3229,14 +3350,17 @@ class MiddleClickAutoscrollWebWidgetClient
public:
// WebWidgetClient methods
- void DidChangeCursor(const WebCursorInfo& cursor) override {
- last_cursor_type_ = cursor.type;
+ void DidChangeCursor(const ui::Cursor& cursor) override {
+ last_cursor_type_ = cursor.type();
}
- ui::CursorType GetLastCursorType() const { return last_cursor_type_; }
+ ui::mojom::blink::CursorType GetLastCursorType() const {
+ return last_cursor_type_;
+ }
private:
- ui::CursorType last_cursor_type_ = ui::CursorType::kPointer;
+ ui::mojom::blink::CursorType last_cursor_type_ =
+ ui::mojom::blink::CursorType::kPointer;
};
TEST_F(WebViewTest, MiddleClickAutoscrollCursor) {
@@ -3256,10 +3380,10 @@ TEST_F(WebViewTest, MiddleClickAutoscrollCursor) {
struct CursorTests {
int resize_width;
int resize_height;
- ui::CursorType expected_cursor;
- } cursor_tests[] = {{100, 100, MiddlePanningCursor().GetType()},
- {1010, 100, MiddlePanningVerticalCursor().GetType()},
- {100, 2010, MiddlePanningHorizontalCursor().GetType()}};
+ ui::mojom::blink::CursorType expected_cursor;
+ } cursor_tests[] = {{100, 100, MiddlePanningCursor().type()},
+ {1010, 100, MiddlePanningVerticalCursor().type()},
+ {100, 2010, MiddlePanningHorizontalCursor().type()}};
for (const CursorTests current_test : cursor_tests) {
WebViewImpl* web_view = web_view_helper_.InitializeAndLoad(
@@ -3269,6 +3393,14 @@ TEST_F(WebViewTest, MiddleClickAutoscrollCursor) {
UpdateAllLifecyclePhases();
RunPendingTasks();
+ LocalFrame* local_frame =
+ To<WebLocalFrameImpl>(web_view->MainFrame())->GetFrame();
+
+ // Setup a mock clipboard. On linux, middle click can paste from the
+ // clipboard, so the input handler below will access the clipboard.
+ PageTestBase::MockClipboardHostProvider mock_clip_host_provider(
+ local_frame->GetBrowserInterfaceBroker());
+
WebMouseEvent mouse_event(WebInputEvent::kMouseDown,
WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests());
@@ -3285,13 +3417,10 @@ TEST_F(WebViewTest, MiddleClickAutoscrollCursor) {
EXPECT_EQ(current_test.expected_cursor, client.GetLastCursorType());
- LocalFrame* local_frame =
- To<WebLocalFrameImpl>(web_view->MainFrame())->GetFrame();
-
// Even if a plugin tries to change the cursor type, that should be ignored
// during middle-click autoscroll.
- web_view->GetChromeClient().SetCursorForPlugin(
- WebCursorInfo(PointerCursor()), local_frame);
+ web_view->GetChromeClient().SetCursorForPlugin(PointerCursor(),
+ local_frame);
EXPECT_EQ(current_test.expected_cursor, client.GetLastCursorType());
// End middle-click autoscroll.
@@ -3302,9 +3431,8 @@ TEST_F(WebViewTest, MiddleClickAutoscrollCursor) {
web_view->MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(mouse_event));
- web_view->GetChromeClient().SetCursorForPlugin(WebCursorInfo(IBeamCursor()),
- local_frame);
- EXPECT_EQ(IBeamCursor().GetType(), client.GetLastCursorType());
+ web_view->GetChromeClient().SetCursorForPlugin(IBeamCursor(), local_frame);
+ EXPECT_EQ(IBeamCursor().type(), client.GetLastCursorType());
}
// Explicitly reset to break dependency on locally scoped client.
@@ -3336,7 +3464,7 @@ TEST_F(WebViewTest, ShowPressOnTransformedLink) {
WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(WebFloatPoint(20, 20));
+ event.SetPositionInWidget(gfx::PointF(20, 20));
// Just make sure we don't hit any asserts.
web_view_impl->MainFrameWidget()->HandleInputEvent(
@@ -3545,7 +3673,7 @@ class ViewCreatingWebViewClient : public frame_test_helpers::TestWebViewClient {
const WebWindowFeatures&,
const WebString& name,
WebNavigationPolicy,
- WebSandboxFlags,
+ mojom::blink::WebSandboxFlags,
const FeaturePolicy::FeatureState&,
const SessionStorageNamespaceId&) override {
return web_view_helper_.InitializeWithOpener(opener);
@@ -3629,7 +3757,7 @@ class ViewReusingWebViewClient : public frame_test_helpers::TestWebViewClient {
const WebWindowFeatures&,
const WebString& name,
WebNavigationPolicy,
- WebSandboxFlags,
+ mojom::blink::WebSandboxFlags,
const FeaturePolicy::FeatureState&,
const SessionStorageNamespaceId&) override {
return web_view_;
@@ -3847,7 +3975,8 @@ TEST_F(WebViewTest, AddFrameInCloseURLUnload) {
RegisterMockedHttpURLLoad("add_frame_in_unload.html");
web_view_helper_.InitializeAndLoad(base_url_ + "add_frame_in_unload.html",
&frame_client);
- web_view_helper_.LocalMainFrame()->DispatchUnloadEvent();
+ // Dispatch unload event.
+ web_view_helper_.LocalMainFrame()->GetFrame()->ClosePage(base::DoNothing());
EXPECT_EQ(0, frame_client.Count());
web_view_helper_.Reset();
}
@@ -4074,8 +4203,8 @@ TEST_F(WebViewTest, TextInputFlags) {
// autocapitalize is set to none.
auto* input_element = To<HTMLInputElement>(document->getElementById("input"));
document->SetFocusedElement(
- input_element,
- FocusParams(SelectionBehaviorOnFocus::kNone, kWebFocusTypeNone, nullptr));
+ input_element, FocusParams(SelectionBehaviorOnFocus::kNone,
+ mojom::blink::FocusType::kNone, nullptr));
web_view_impl->MainFrameWidget()->SetFocus(true);
WebTextInputInfo info1 = active_input_method_controller->TextInputInfo();
EXPECT_EQ(kWebTextInputFlagAutocompleteOff | kWebTextInputFlagAutocorrectOff |
@@ -4087,8 +4216,8 @@ TEST_F(WebViewTest, TextInputFlags) {
// autocapitalize is set to sentences.
input_element = To<HTMLInputElement>(document->getElementById("input2"));
document->SetFocusedElement(
- input_element,
- FocusParams(SelectionBehaviorOnFocus::kNone, kWebFocusTypeNone, nullptr));
+ input_element, FocusParams(SelectionBehaviorOnFocus::kNone,
+ mojom::blink::FocusType::kNone, nullptr));
web_view_impl->MainFrameWidget()->SetFocus(true);
WebTextInputInfo info2 = active_input_method_controller->TextInputInfo();
EXPECT_EQ(kWebTextInputFlagAutocompleteOn | kWebTextInputFlagAutocorrectOn |
@@ -4101,8 +4230,8 @@ TEST_F(WebViewTest, TextInputFlags) {
auto* text_area_element =
To<HTMLTextAreaElement>(document->getElementById("textarea"));
document->SetFocusedElement(
- text_area_element,
- FocusParams(SelectionBehaviorOnFocus::kNone, kWebFocusTypeNone, nullptr));
+ text_area_element, FocusParams(SelectionBehaviorOnFocus::kNone,
+ mojom::blink::FocusType::kNone, nullptr));
web_view_impl->MainFrameWidget()->SetFocus(true);
WebTextInputInfo info3 = active_input_method_controller->TextInputInfo();
EXPECT_EQ(kWebTextInputFlagAutocapitalizeSentences, info3.flags);
@@ -4184,7 +4313,7 @@ TEST_F(WebViewTest, CompositionIsUserGesture) {
frame->FrameWidget()->GetActiveWebInputMethodController()->SetComposition(
WebString::FromUTF8(std::string("hello").c_str()),
WebVector<WebImeTextSpan>(), WebRange(), 3, 3));
- EXPECT_TRUE(WebUserGestureIndicator::IsProcessingUserGesture(frame));
+ EXPECT_TRUE(frame->HasTransientUserActivation());
EXPECT_EQ(1, client.TextChanges());
EXPECT_TRUE(frame->HasMarkedText());
@@ -4362,7 +4491,6 @@ class MojoTestHelper {
WebViewImpl* web_view_;
frame_test_helpers::WebViewHelper& web_view_helper_;
frame_test_helpers::TestWebFrameClient web_frame_client_;
- std::unique_ptr<service_manager::InterfaceProvider::TestApi> test_api_;
};
// Mock implementation of the UnhandledTapNotifier Mojo receiver, for testing
@@ -4385,8 +4513,8 @@ class MockUnhandledTapNotifierImpl : public mojom::blink::UnhandledTapNotifier {
font_size_ = unhandled_tap_info->font_size_in_pixels;
}
bool WasUnhandledTap() const { return was_unhandled_tap_; }
- int GetTappedXPos() const { return tapped_position_.X(); }
- int GetTappedYPos() const { return tapped_position_.Y(); }
+ int GetTappedXPos() const { return tapped_position_.x(); }
+ int GetTappedYPos() const { return tapped_position_.y(); }
int GetFontSize() const { return font_size_; }
int GetElementTextRunLength() const { return element_text_run_length_; }
void Reset() {
@@ -4399,7 +4527,7 @@ class MockUnhandledTapNotifierImpl : public mojom::blink::UnhandledTapNotifier {
private:
bool was_unhandled_tap_ = false;
- IntPoint tapped_position_;
+ gfx::Point tapped_position_;
int element_text_run_length_ = 0;
int font_size_ = 0;
@@ -4421,7 +4549,7 @@ class ShowUnhandledTapTest : public WebViewTest {
web_view_ = mojo_test_helper_->WebView();
web_view_->MainFrameWidget()->Resize(WebSize(500, 300));
web_view_->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
RunPendingTasks();
WebLocalFrameImpl* web_local_frame = web_view_->MainFrameImpl();
@@ -4501,13 +4629,13 @@ TEST_F(ShowUnhandledTapTest, ShowUnhandledTapUIIfNeeded) {
constexpr float visual_y = 10.f;
web_view_->SetPageScaleFactor(scale);
- web_view_->SetVisualViewportOffset(WebFloatPoint(visual_x, visual_y));
+ web_view_->SetVisualViewportOffset(gfx::PointF(visual_x, visual_y));
Tap("target");
// Ensure position didn't change as a result of scroll into view.
- ASSERT_EQ(visual_x, web_view_->VisualViewportOffset().x);
- ASSERT_EQ(visual_y, web_view_->VisualViewportOffset().y);
+ ASSERT_EQ(visual_x, web_view_->VisualViewportOffset().x());
+ ASSERT_EQ(visual_y, web_view_->VisualViewportOffset().y());
EXPECT_TRUE(mock_notifier_.WasUnhandledTap());
@@ -4579,12 +4707,12 @@ TEST_F(WebViewTest, WebSubstringUtil) {
web_view->MainFrameWidget()->Resize(WebSize(400, 400));
WebLocalFrameImpl* frame = web_view->MainFrameImpl();
- WebPoint baseline_point;
+ gfx::Point baseline_point;
NSAttributedString* result = WebSubstringUtil::AttributedSubstringInRange(
frame, 10, 3, &baseline_point);
ASSERT_TRUE(!!result);
- WebPoint point(baseline_point.x, baseline_point.y);
+ gfx::Point point(baseline_point);
result = WebSubstringUtil::AttributedWordAtPoint(frame->FrameWidget(), point,
baseline_point);
ASSERT_TRUE(!!result);
@@ -4595,7 +4723,7 @@ TEST_F(WebViewTest, WebSubstringUtil) {
&baseline_point);
ASSERT_TRUE(!!result);
- point = WebPoint(baseline_point.x, baseline_point.y);
+ point = baseline_point;
result = WebSubstringUtil::AttributedWordAtPoint(frame->FrameWidget(), point,
baseline_point);
ASSERT_TRUE(!!result);
@@ -4609,14 +4737,14 @@ TEST_F(WebViewTest, WebSubstringUtilBaselinePoint) {
web_view->MainFrameWidget()->Resize(WebSize(400, 400));
WebLocalFrameImpl* frame = web_view->MainFrameImpl();
- WebPoint old_point;
+ gfx::Point old_point;
WebSubstringUtil::AttributedSubstringInRange(frame, 3, 1, &old_point);
- WebPoint new_point;
+ gfx::Point new_point;
WebSubstringUtil::AttributedSubstringInRange(frame, 3, 20, &new_point);
- EXPECT_EQ(old_point.x, new_point.x);
- EXPECT_EQ(old_point.y, new_point.y);
+ EXPECT_EQ(old_point.x(), new_point.x());
+ EXPECT_EQ(old_point.y(), new_point.y());
}
TEST_F(WebViewTest, WebSubstringUtilPinchZoom) {
@@ -4628,22 +4756,22 @@ TEST_F(WebViewTest, WebSubstringUtilPinchZoom) {
WebLocalFrameImpl* frame = web_view->MainFrameImpl();
NSAttributedString* result = nil;
- WebPoint baseline_point;
+ gfx::Point baseline_point;
result = WebSubstringUtil::AttributedSubstringInRange(frame, 10, 3,
&baseline_point);
ASSERT_TRUE(!!result);
web_view->SetPageScaleFactor(3);
- WebPoint point_after_zoom;
+ gfx::Point point_after_zoom;
result = WebSubstringUtil::AttributedSubstringInRange(frame, 10, 3,
&point_after_zoom);
ASSERT_TRUE(!!result);
// We won't have moved by a full factor of 3 because of the translations, but
// we should move by a factor of >2.
- EXPECT_LT(2 * baseline_point.x, point_after_zoom.x);
- EXPECT_LT(2 * baseline_point.y, point_after_zoom.y);
+ EXPECT_LT(2 * baseline_point.x(), point_after_zoom.x());
+ EXPECT_LT(2 * baseline_point.y(), point_after_zoom.y());
}
TEST_F(WebViewTest, WebSubstringUtilIframe) {
@@ -4658,28 +4786,28 @@ TEST_F(WebViewTest, WebSubstringUtilIframe) {
WebLocalFrameImpl* child_frame = WebLocalFrameImpl::FromFrame(
To<LocalFrame>(main_frame->GetFrame()->Tree().FirstChild()));
- WebPoint baseline_point;
+ gfx::Point baseline_point;
NSAttributedString* result = WebSubstringUtil::AttributedSubstringInRange(
child_frame, 11, 7, &baseline_point);
ASSERT_NE(result, nullptr);
- WebPoint point(baseline_point.x, baseline_point.y);
+ gfx::Point point(baseline_point);
result = WebSubstringUtil::AttributedWordAtPoint(main_frame->FrameWidget(),
point, baseline_point);
ASSERT_NE(result, nullptr);
- int y_before_change = baseline_point.y;
+ int y_before_change = baseline_point.y();
// Now move the <iframe> down by 100px.
main_frame->ExecuteScript(WebScriptSource(
"document.querySelector('iframe').style.marginTop = '100px';"));
- point = WebPoint(point.x, point.y + 100);
+ point = gfx::Point(point.x(), point.y() + 100);
result = WebSubstringUtil::AttributedWordAtPoint(main_frame->FrameWidget(),
point, baseline_point);
ASSERT_NE(result, nullptr);
- EXPECT_EQ(y_before_change, baseline_point.y - 100);
+ EXPECT_EQ(y_before_change, baseline_point.y() - 100);
}
#endif
@@ -4722,7 +4850,7 @@ TEST_F(WebViewTest, PasswordFieldEditingIsUserGesture) {
frame->FrameWidget()->GetActiveWebInputMethodController()->CommitText(
WebString::FromUTF8(std::string("hello").c_str()),
empty_ime_text_spans, WebRange(), 0));
- EXPECT_TRUE(WebUserGestureIndicator::IsProcessingUserGesture(frame));
+ EXPECT_TRUE(frame->HasTransientUserActivation());
EXPECT_EQ(1, client.TextChanges());
frame->SetAutofillClient(nullptr);
}
@@ -4855,7 +4983,7 @@ TEST_F(WebViewTest, ForceAndResetViewport) {
// Override applies transform, sets visible rect, and disables
// visual viewport clipping.
TransformationMatrix matrix =
- dev_tools_emulator->ForceViewportForTesting(WebFloatPoint(50, 55), 2.f);
+ dev_tools_emulator->ForceViewportForTesting(gfx::PointF(50, 55), 2.f);
expected_matrix.MakeIdentity().Scale(2.f).Translate(-50, -55);
EXPECT_EQ(expected_matrix, matrix);
{
@@ -4865,8 +4993,8 @@ TEST_F(WebViewTest, ForceAndResetViewport) {
}
// Setting new override discards previous one.
- matrix = dev_tools_emulator->ForceViewportForTesting(
- WebFloatPoint(5.4f, 10.5f), 1.5f);
+ matrix = dev_tools_emulator->ForceViewportForTesting(gfx::PointF(5.4f, 10.5f),
+ 1.5f);
expected_matrix.MakeIdentity().Scale(1.5f).Translate(-5.4f, -10.5f);
EXPECT_EQ(expected_matrix, matrix);
{
@@ -4904,7 +5032,7 @@ TEST_F(WebViewTest, ViewportOverrideIntegratesDeviceMetricsOffsetAndScale) {
EXPECT_EQ(expected_matrix, web_view_impl->GetDeviceEmulationTransform());
// Device metrics offset and scale are applied before viewport override.
- emulation_params.viewport_offset = WebFloatPoint(5, 10);
+ emulation_params.viewport_offset = gfx::PointF(5, 10);
emulation_params.viewport_scale = 1.5f;
web_view_impl->EnableDeviceEmulation(emulation_params);
expected_matrix.MakeIdentity()
@@ -4932,10 +5060,11 @@ TEST_F(WebViewTest, ViewportOverrideAdaptsToScaleAndScroll) {
// account.
web_view_impl->SetPageScaleFactor(1.5f);
frame_view->LayoutViewport()->SetScrollOffset(
- ScrollOffset(100, 150), kProgrammaticScroll, kScrollBehaviorInstant);
+ ScrollOffset(100, 150), mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kInstant);
WebDeviceEmulationParams emulation_params;
- emulation_params.viewport_offset = WebFloatPoint(50, 55);
+ emulation_params.viewport_offset = gfx::PointF(50, 55);
emulation_params.viewport_scale = 2.f;
web_view_impl->EnableDeviceEmulation(emulation_params);
expected_matrix.MakeIdentity()
@@ -4944,27 +5073,28 @@ TEST_F(WebViewTest, ViewportOverrideAdaptsToScaleAndScroll) {
.Translate(100, 150)
.Scale(1. / 1.5f);
EXPECT_EQ(expected_matrix, web_view_impl->GetDeviceEmulationTransform());
- // Page scroll and scale are irrelevant for visible rect.
+ // Scale is irrelevant for visible rect.
{
IntRect visible_rect(1, 2, 3, 4);
dev_tools_emulator->OverrideVisibleRect(IntSize(100, 150), &visible_rect);
- EXPECT_EQ(IntRect(50, 55, 50, 75), visible_rect); // Was modified.
+ EXPECT_EQ(IntRect(50 - 100, 55 - 150, 50, 75), visible_rect);
}
// Transform adapts to scroll changes.
frame_view->LayoutViewport()->SetScrollOffset(
- ScrollOffset(50, 55), kProgrammaticScroll, kScrollBehaviorInstant);
+ ScrollOffset(50, 55), mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kInstant);
expected_matrix.MakeIdentity()
.Scale(2.f)
.Translate(-50, -55)
.Translate(50, 55)
.Scale(1. / 1.5f);
EXPECT_EQ(expected_matrix, web_view_impl->GetDeviceEmulationTransform());
- // Visible rect doesn't change.
+ // Visible rect adapts to scroll change.
{
IntRect visible_rect(1, 2, 3, 4);
dev_tools_emulator->OverrideVisibleRect(IntSize(100, 150), &visible_rect);
- EXPECT_EQ(IntRect(50, 55, 50, 75), visible_rect); // Was modified.
+ EXPECT_EQ(IntRect(50 - 50, 55 - 55, 50, 75), visible_rect);
}
// Transform adapts to page scale changes.
@@ -4979,7 +5109,7 @@ TEST_F(WebViewTest, ViewportOverrideAdaptsToScaleAndScroll) {
{
IntRect visible_rect(1, 2, 3, 4);
dev_tools_emulator->OverrideVisibleRect(IntSize(100, 150), &visible_rect);
- EXPECT_EQ(IntRect(50, 55, 50, 75), visible_rect); // Was modified.
+ EXPECT_EQ(IntRect(50 - 50, 55 - 55, 50, 75), visible_rect);
}
}
@@ -5226,8 +5356,9 @@ TEST_F(WebViewTest, DetachPluginInLayout) {
To<HTMLObjectElement>(main_frame->GetDocument()->body()->firstChild());
EXPECT_TRUE(plugin_element->OwnedPlugin());
- plugin_element->style()->setCSSText(main_frame->GetDocument(),
- "display: none", ASSERT_NO_EXCEPTION);
+ plugin_element->style()->setCSSText(
+ main_frame->GetDocument()->ToExecutionContext(), "display: none",
+ ASSERT_NO_EXCEPTION);
EXPECT_TRUE(plugin_element->OwnedPlugin());
UpdateAllLifecyclePhases();
EXPECT_FALSE(plugin_element->OwnedPlugin());
@@ -5254,7 +5385,7 @@ TEST_F(WebViewTest, FirstInputDelayReported) {
InteractiveDetector* interactive_detector =
GetTestInteractiveDetector(*document);
- EXPECT_TRUE(interactive_detector->GetFirstInputDelay().is_zero());
+ EXPECT_FALSE(interactive_detector->GetFirstInputDelay().has_value());
WebKeyboardEvent key_event1(WebInputEvent::kRawKeyDown,
WebInputEvent::kNoModifiers,
@@ -5266,9 +5397,11 @@ TEST_F(WebViewTest, FirstInputDelayReported) {
web_view->MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(key_event1));
- EXPECT_NEAR(50, interactive_detector->GetFirstInputDelay().InMillisecondsF(),
+ EXPECT_TRUE(interactive_detector->GetFirstInputDelay().has_value());
+ EXPECT_NEAR(50,
+ (*interactive_detector->GetFirstInputDelay()).InMillisecondsF(),
0.01);
- EXPECT_EQ(70, (interactive_detector->GetFirstInputTimestamp() - start_time)
+ EXPECT_EQ(70, (*interactive_detector->GetFirstInputTimestamp() - start_time)
.InMillisecondsF());
// Sending a second event won't change the FirstInputDelay.
@@ -5282,9 +5415,10 @@ TEST_F(WebViewTest, FirstInputDelayReported) {
web_view->MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(key_event2));
- EXPECT_NEAR(50, interactive_detector->GetFirstInputDelay().InMillisecondsF(),
+ EXPECT_NEAR(50,
+ (*interactive_detector->GetFirstInputDelay()).InMillisecondsF(),
0.01);
- EXPECT_EQ(70, (interactive_detector->GetFirstInputTimestamp() - start_time)
+ EXPECT_EQ(70, (*interactive_detector->GetFirstInputTimestamp() - start_time)
.InMillisecondsF());
}
@@ -5306,7 +5440,7 @@ TEST_F(WebViewTest, LongestInputDelayReported) {
InteractiveDetector* interactive_detector =
GetTestInteractiveDetector(*document);
- EXPECT_TRUE(interactive_detector->GetLongestInputDelay().is_zero());
+ EXPECT_FALSE(interactive_detector->GetLongestInputDelay().has_value());
WebKeyboardEvent key_event1(WebInputEvent::kRawKeyDown,
WebInputEvent::kNoModifiers,
@@ -5341,7 +5475,7 @@ TEST_F(WebViewTest, LongestInputDelayReported) {
WebCoalescedInputEvent(key_event3));
EXPECT_NEAR(100,
- interactive_detector->GetLongestInputDelay().InMillisecondsF(),
+ (*interactive_detector->GetLongestInputDelay()).InMillisecondsF(),
0.01);
EXPECT_EQ(longest_input_timestamp,
interactive_detector->GetLongestInputTimestamp());
@@ -5432,7 +5566,7 @@ TEST_F(WebViewTest, LongestInputDelayPageBackgroundedDuringQueuing) {
InteractiveDetector* interactive_detector =
GetTestInteractiveDetector(*document);
- EXPECT_TRUE(interactive_detector->GetLongestInputDelay().is_zero());
+ EXPECT_FALSE(interactive_detector->GetLongestInputDelay().has_value());
WebKeyboardEvent key_event1(WebInputEvent::kRawKeyDown,
WebInputEvent::kNoModifiers,
@@ -5462,8 +5596,9 @@ TEST_F(WebViewTest, LongestInputDelayPageBackgroundedDuringQueuing) {
web_view->MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(key_event2));
- EXPECT_NEAR(
- 50, interactive_detector->GetLongestInputDelay().InMillisecondsF(), 0.01);
+ EXPECT_NEAR(50,
+ (*interactive_detector->GetLongestInputDelay()).InMillisecondsF(),
+ 0.01);
EXPECT_EQ(key_event1_time, interactive_detector->GetLongestInputTimestamp());
}
@@ -5501,7 +5636,7 @@ TEST_F(WebViewTest, LongestInputDelayPageBackgroundedAtNavStart) {
web_view->MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(key_event));
- EXPECT_TRUE(interactive_detector->GetLongestInputDelay().is_zero());
+ EXPECT_FALSE(interactive_detector->GetLongestInputDelay().has_value());
}
// Tests page backgrounding outside of input queuing time does not affect
@@ -5523,7 +5658,7 @@ TEST_F(WebViewTest, LongestInputDelayPageBackgroundedNotDuringQueuing) {
InteractiveDetector* interactive_detector =
GetTestInteractiveDetector(*document);
- EXPECT_TRUE(interactive_detector->GetLongestInputDelay().is_zero());
+ EXPECT_FALSE(interactive_detector->GetLongestInputDelay().has_value());
web_view->SetVisibilityState(PageVisibilityState::kHidden,
/*initial_state=*/false);
@@ -5543,8 +5678,9 @@ TEST_F(WebViewTest, LongestInputDelayPageBackgroundedNotDuringQueuing) {
web_view->MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(key_event));
- EXPECT_NEAR(
- 50, interactive_detector->GetLongestInputDelay().InMillisecondsF(), 0.01);
+ EXPECT_NEAR(50,
+ (*interactive_detector->GetLongestInputDelay()).InMillisecondsF(),
+ 0.01);
EXPECT_EQ(key_event_time, interactive_detector->GetLongestInputTimestamp());
}
@@ -5587,7 +5723,7 @@ TEST_F(WebViewTest, PointerDownUpFirstInputDelay) {
// We don't know if this pointer event will result in a scroll or not, so we
// can't report its delay. We don't consider a scroll to be meaningful input.
- EXPECT_TRUE(interactive_detector->GetFirstInputDelay().is_zero());
+ EXPECT_FALSE(interactive_detector->GetFirstInputDelay().has_value());
// When we receive a pointer up, we report the delay of the pointer down.
WebPointerEvent pointer_up(
@@ -5598,9 +5734,10 @@ TEST_F(WebViewTest, PointerDownUpFirstInputDelay) {
web_view->MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(pointer_up));
- EXPECT_NEAR(50, interactive_detector->GetFirstInputDelay().InMillisecondsF(),
+ EXPECT_NEAR(50,
+ (*interactive_detector->GetFirstInputDelay()).InMillisecondsF(),
0.01);
- EXPECT_EQ(70, (interactive_detector->GetFirstInputTimestamp() - start_time)
+ EXPECT_EQ(70, (*interactive_detector->GetFirstInputTimestamp() - start_time)
.InMillisecondsF());
}
@@ -5666,8 +5803,9 @@ TEST_F(WebViewTest, FirstInputDelayExcludesProcessingTime) {
web_view->MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(key_event));
+ EXPECT_TRUE(interactive_detector->GetFirstInputDelay().has_value());
base::TimeDelta first_input_delay =
- interactive_detector->GetFirstInputDelay();
+ *interactive_detector->GetFirstInputDelay();
EXPECT_EQ(5000, first_input_delay.InMillisecondsF());
web_view_helper_.Reset(); // Remove dependency on locally scoped client.
@@ -5712,7 +5850,7 @@ TEST_F(WebViewTest, LongestInputDelayExcludesProcessingTime) {
WebCoalescedInputEvent(key_event));
base::TimeDelta longest_input_delay =
- interactive_detector->GetLongestInputDelay();
+ *interactive_detector->GetLongestInputDelay();
EXPECT_EQ(5000, longest_input_delay.InMillisecondsF());
web_view_helper_.Reset(); // Remove dependency on locally scoped client.
@@ -5724,9 +5862,8 @@ TEST_F(WebViewTest, RootLayerAttachment) {
// Do a lifecycle update that includes compositing but not paint. Hit test
// events are an example of a real case where this occurs
// (see: WebViewTest::ClientTapHandling).
- web_view->MainFrameWidget()->UpdateLifecycle(
- WebFrameWidget::LifecycleUpdate::kPrePaint,
- WebWidget::LifecycleUpdateReason::kTest);
+ web_view->MainFrameWidget()->UpdateLifecycle(WebLifecycleUpdate::kPrePaint,
+ DocumentUpdateReason::kTest);
// Layers (including the root layer) should not be attached until the paint
// lifecycle phase.
@@ -5734,9 +5871,8 @@ TEST_F(WebViewTest, RootLayerAttachment) {
EXPECT_FALSE(layer_tree_host->root_layer());
// Do a full lifecycle update and ensure that the root layer has been added.
- web_view->MainFrameWidget()->UpdateLifecycle(
- WebFrameWidget::LifecycleUpdate::kAll,
- WebWidget::LifecycleUpdateReason::kTest);
+ web_view->MainFrameWidget()->UpdateLifecycle(WebLifecycleUpdate::kAll,
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(layer_tree_host->root_layer());
}
@@ -5804,7 +5940,7 @@ TEST_F(WebViewTest, LongPressImageAndThenLongTapImage) {
WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(WebFloatPoint(10, 10));
+ event.SetPositionInWidget(gfx::PointF(10, 10));
EXPECT_EQ(WebInputEventResult::kHandledSystem,
web_view->MainFrameWidget()->HandleInputEvent(
@@ -5818,7 +5954,7 @@ TEST_F(WebViewTest, LongPressImageAndThenLongTapImage) {
WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- tap_event.SetPositionInWidget(WebFloatPoint(10, 10));
+ tap_event.SetPositionInWidget(gfx::PointF(10, 10));
EXPECT_EQ(WebInputEventResult::kNotHandled,
web_view->MainFrameWidget()->HandleInputEvent(
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/BUILD.gn b/chromium/third_party/blink/renderer/core/feature_policy/BUILD.gn
index 3f209b49da7..b5ad4779db6 100644
--- a/chromium/third_party/blink/renderer/core/feature_policy/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/feature_policy/BUILD.gn
@@ -6,6 +6,8 @@ import("//third_party/blink/renderer/core/core.gni")
blink_core_sources("feature_policy") {
sources = [
+ "document_policy_parser.cc",
+ "document_policy_parser.h",
"dom_document_policy.h",
"dom_feature_policy.cc",
"dom_feature_policy.h",
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/document_policy.dict b/chromium/third_party/blink/renderer/core/feature_policy/document_policy.dict
new file mode 100644
index 00000000000..dbdc5ea1ed4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/feature_policy/document_policy.dict
@@ -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.
+
+"font-display-late-swap"
+"unoptimized-lossless-images"
+"unoptimized-lossless-images-strict"
+"unoptimized-lossy-images"
+"oversized-images"
+"="
+"bpp"
+"no-"
+";"
+","
+"0"
+"1"
+".0"
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/document_policy_corpus/1 b/chromium/third_party/blink/renderer/core/feature_policy/document_policy_corpus/1
new file mode 100644
index 00000000000..c1e2f03a8ac
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/feature_policy/document_policy_corpus/1
@@ -0,0 +1 @@
+no-font-display-late-swap \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/document_policy_corpus/2 b/chromium/third_party/blink/renderer/core/feature_policy/document_policy_corpus/2
new file mode 100644
index 00000000000..d3635d4466e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/feature_policy/document_policy_corpus/2
@@ -0,0 +1 @@
+unoptimized-lossless-images;bpp=2.0 \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/document_policy_features.json5 b/chromium/third_party/blink/renderer/core/feature_policy/document_policy_features.json5
new file mode 100644
index 00000000000..de197f9e3be
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/feature_policy/document_policy_features.json5
@@ -0,0 +1,93 @@
+{
+ // All document policy (https://w3c.github.io/webappsec-feature-policy/document-policy.html)
+ // features are defined here.
+ // All Features have to be defined in FeaturePolicyFeature enum as well
+ // (defined in third_party/blink/public/mojom/feature_policy/feature_policy.mojom).
+ // The enum value has to have the same name as the feature name here.
+
+ parameters: {
+ // document_policy_name: "FEATURE_NAME" is used to specify the policy name
+ // which gets parsed from the header or the policy attribute.
+ document_policy_name: {},
+ value_name: {},
+ // value type allowed in mojom::PolicyValueType which is defined in
+ // third_party/blink/public/mojom/feature_policy/policy_value.mojom.
+ value_type: {},
+ // valid c++ expression strings, e.g. true/false, 1.0, -1.
+ // or use reserved keyword 'min'/'max'.
+ default_value: {},
+ // "depends_on" specifies relationship to runtime features defined
+ // in "runtime_enabled_features.json5":
+ // depends_on: ["feature1", "feature2", ...]
+ // * If the depends_on features are *only* runtime features, the feature is
+ // available if any of the runtime features are enabled.
+ // * If the depends_on list includes origin trial features, the feature is
+ // available if any of the origin trial features are enabled.
+ depends_on: {
+ default: [],
+ valid_type: "list",
+ },
+ },
+
+ data: [
+ {
+ name: "FontDisplay",
+ document_policy_name: "font-display-late-swap",
+ value_name: "",
+ value_type: "Bool",
+ default_value: "true",
+ depends_on: ["ExperimentalProductivityFeatures"],
+ },
+ {
+ name: "UnoptimizedLosslessImages",
+ document_policy_name: "unoptimized-lossless-images",
+ value_name: "bpp",
+ value_type: "DecDouble",
+ default_value: "max",
+ depends_on: ["UnoptimizedImagePolicies"],
+ },
+ {
+ // The ForceLoadAtTop policy lets pages opt-out of scrolling that
+ // automatically happens on page load. This includes fragment scrolls,
+ // text fragment scrolls (i.e. this provides an opt-out for the Scroll To
+ // Text feature), and scroll restoration.
+ name: "ForceLoadAtTop",
+ document_policy_name: "force-load-at-top",
+ value_name: "",
+ value_type: "Bool",
+ default_value: "false",
+ },
+ {
+ name: "UnoptimizedLosslessImagesStrict",
+ document_policy_name: "unoptimized-lossless-images-strict",
+ value_name: "bpp",
+ value_type: "DecDouble",
+ default_value: "max",
+ depends_on: ["UnoptimizedImagePolicies"],
+ },
+ {
+ name: "UnoptimizedLossyImages",
+ document_policy_name: "unoptimized-lossy-images",
+ value_name: "bpp",
+ value_type: "DecDouble",
+ default_value: "max",
+ depends_on: ["UnoptimizedImagePolicies"],
+ },
+ {
+ name: "OversizedImages",
+ document_policy_name: "oversized-images",
+ value_name: "scale",
+ value_type: "DecDouble",
+ default_value: "max",
+ depends_on: ["UnoptimizedImagePolicies"],
+ },
+ {
+ name: "UnsizedMedia",
+ document_policy_name: "unsized-media",
+ value_name: "",
+ value_type: "Bool",
+ default_value: "true",
+ depends_on: ["UnsizedMediaPolicy"],
+ },
+ ],
+}
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/document_policy_fuzzer.cc b/chromium/third_party/blink/renderer/core/feature_policy/document_policy_fuzzer.cc
new file mode 100644
index 00000000000..1685869a15a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/feature_policy/document_policy_fuzzer.cc
@@ -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.
+
+#include "third_party/blink/renderer/core/feature_policy/document_policy_parser.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/testing/blink_fuzzer_test_support.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ static blink::BlinkFuzzerTestSupport test_support =
+ blink::BlinkFuzzerTestSupport();
+ blink::DocumentPolicyParser::Parse(WTF::String(data, size));
+ return 0;
+}
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/document_policy_parser.cc b/chromium/third_party/blink/renderer/core/feature_policy/document_policy_parser.cc
new file mode 100644
index 00000000000..41fa9ea07c1
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/feature_policy/document_policy_parser.cc
@@ -0,0 +1,182 @@
+// 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/feature_policy/document_policy_parser.h"
+
+#include "net/http/structured_headers.h"
+#include "third_party/blink/public/mojom/feature_policy/policy_value.mojom-blink-forward.h"
+
+namespace blink {
+
+namespace {
+
+base::Optional<PolicyValue> ItemToPolicyValue(
+ const net::structured_headers::Item& item) {
+ switch (item.Type()) {
+ case net::structured_headers::Item::ItemType::kIntegerType:
+ return PolicyValue(static_cast<double>(item.GetInteger()));
+ case net::structured_headers::Item::ItemType::kDecimalType:
+ return PolicyValue(item.GetDecimal());
+ default:
+ return base::nullopt;
+ }
+}
+
+base::Optional<std::string> ItemToString(
+ const net::structured_headers::Item& item) {
+ if (item.Type() != net::structured_headers::Item::ItemType::kTokenType)
+ return base::nullopt;
+ return item.GetString();
+}
+
+struct ParsedFeature {
+ mojom::blink::DocumentPolicyFeature feature;
+ PolicyValue policy_value;
+ base::Optional<std::string> endpoint_group;
+};
+
+base::Optional<ParsedFeature> ParseFeature(
+ const net::structured_headers::ParameterizedMember& directive,
+ const DocumentPolicyNameFeatureMap& name_feature_map,
+ const DocumentPolicyFeatureInfoMap& feature_info_map) {
+ ParsedFeature parsed_feature;
+
+ // Directives must not be inner lists.
+ if (directive.member_is_inner_list)
+ return base::nullopt;
+
+ const net::structured_headers::Item& feature_token =
+ directive.member.front().item;
+
+ // The item in directive should be token type.
+ if (!feature_token.is_token())
+ return base::nullopt;
+
+ // No directive can currently have more than two parameters, including
+ // 'report-to'.
+ if (directive.params.size() > 2)
+ return base::nullopt;
+
+ std::string feature_name = feature_token.GetString();
+ auto feature_iter = name_feature_map.find(feature_name);
+
+ // Parse feature_name string to DocumentPolicyFeature.
+ if (feature_iter != name_feature_map.end()) {
+ parsed_feature.feature = feature_iter->second;
+ } else if (feature_name.size() > 3 && feature_name.substr(0, 3) == "no-") {
+ // Handle "no-" prefix.
+ feature_iter = name_feature_map.find(feature_name.substr(3));
+ if (feature_iter != name_feature_map.end()) {
+ parsed_feature.feature = feature_iter->second;
+ // "no-" prefix is exclusively for policy with Boolean policy value.
+ if (feature_info_map.at(parsed_feature.feature).default_value.Type() !=
+ mojom::blink::PolicyValueType::kBool)
+ return base::nullopt;
+ parsed_feature.policy_value = PolicyValue(false);
+ } else {
+ return base::nullopt; // Unrecognized feature name.
+ }
+ } else {
+ return base::nullopt; // Unrecognized feature name.
+ }
+
+ // Handle boolean value.
+ // For document policy that has a boolean policy value, policy value is not
+ // specified as directive param. Instead, the value is expressed using "no-"
+ // prefix, e.g. for feature X, "X" itself in header should be parsed as true,
+ // "no-X" should be parsed as false.
+ if (feature_info_map.at(parsed_feature.feature).default_value.Type() ==
+ mojom::blink::PolicyValueType::kBool &&
+ parsed_feature.policy_value.Type() ==
+ mojom::blink::PolicyValueType::kNull)
+ parsed_feature.policy_value = PolicyValue(true);
+
+ for (const auto& param : directive.params) {
+ const std::string& param_name = param.first;
+ // Handle "report-to" param. "report-to" is an optional param for
+ // Document-Policy header that specifies the endpoint group that the policy
+ // should send report to. If left unspecified, no report will be send upon
+ // policy violation.
+ if (param_name == "report-to") {
+ base::Optional<std::string> endpoint_group = ItemToString(param.second);
+ if (!endpoint_group)
+ return base::nullopt;
+ parsed_feature.endpoint_group = *endpoint_group;
+ } else {
+ // Handle policy value. For all non-boolean policy value types, they
+ // should be specified as FeatureX;f=xxx, with f representing the
+ // |feature_param_name| and xxx representing policy value.
+
+ // |param_name| does not match param_name in config.
+ if (param_name !=
+ feature_info_map.at(parsed_feature.feature).feature_param_name)
+ return base::nullopt;
+ // |parsed_feature.policy_value| should not be assigned yet.
+ DCHECK(parsed_feature.policy_value.Type() ==
+ mojom::blink::PolicyValueType::kNull);
+
+ base::Optional<PolicyValue> policy_value =
+ ItemToPolicyValue(param.second);
+ if (!policy_value)
+ return base::nullopt;
+ parsed_feature.policy_value = *policy_value;
+ }
+ }
+
+ // |parsed_feature.policy_value| should be initialized.
+ if (parsed_feature.policy_value.Type() ==
+ mojom::blink::PolicyValueType::kNull)
+ return base::nullopt;
+
+ return parsed_feature;
+}
+
+} // namespace
+
+// static
+base::Optional<DocumentPolicy::ParsedDocumentPolicy>
+DocumentPolicyParser::Parse(const String& policy_string) {
+ return ParseInternal(policy_string, GetDocumentPolicyNameFeatureMap(),
+ GetDocumentPolicyFeatureInfoMap(),
+ GetAvailableDocumentPolicyFeatures());
+}
+
+// static
+base::Optional<DocumentPolicy::ParsedDocumentPolicy>
+DocumentPolicyParser::ParseInternal(
+ const String& policy_string,
+ const DocumentPolicyNameFeatureMap& name_feature_map,
+ const DocumentPolicyFeatureInfoMap& feature_info_map,
+ const DocumentPolicyFeatureSet& available_features) {
+ auto root = net::structured_headers::ParseList(policy_string.Ascii());
+ if (!root)
+ return base::nullopt;
+
+ DocumentPolicy::ParsedDocumentPolicy parse_result;
+ for (const net::structured_headers::ParameterizedMember& directive :
+ root.value()) {
+ base::Optional<ParsedFeature> parsed_feature_option =
+ ParseFeature(directive, name_feature_map, feature_info_map);
+ // If a feature fails parsing, ignore the entry.
+ if (!parsed_feature_option)
+ continue;
+
+ ParsedFeature parsed_feature = *parsed_feature_option;
+
+ // If feature is not available, i.e. not enabled, ignore the entry.
+ if (available_features.find(parsed_feature.feature) ==
+ available_features.end())
+ continue;
+
+ parse_result.feature_state.emplace(parsed_feature.feature,
+ std::move(parsed_feature.policy_value));
+ if (parsed_feature.endpoint_group) {
+ parse_result.endpoint_map.emplace(parsed_feature.feature,
+ *parsed_feature.endpoint_group);
+ }
+ }
+ return parse_result;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/document_policy_parser.h b/chromium/third_party/blink/renderer/core/feature_policy/document_policy_parser.h
new file mode 100644
index 00000000000..660b703081c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/feature_policy/document_policy_parser.h
@@ -0,0 +1,33 @@
+// 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_FEATURE_POLICY_DOCUMENT_POLICY_PARSER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_FEATURE_POLICY_DOCUMENT_POLICY_PARSER_H_
+
+#include "third_party/blink/public/common/feature_policy/document_policy.h"
+#include "third_party/blink/public/common/feature_policy/document_policy_features.h"
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/feature_policy/feature_policy_helper.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+
+namespace blink {
+class CORE_EXPORT DocumentPolicyParser {
+ STATIC_ONLY(DocumentPolicyParser);
+
+ public:
+ // Parse document policy header and 'policy' attribute on iframe to
+ // DocumentPolicy::FeatureState.
+ static base::Optional<DocumentPolicy::ParsedDocumentPolicy> Parse(
+ const String& policy_string);
+
+ // Internal parsing method for testing.
+ static base::Optional<DocumentPolicy::ParsedDocumentPolicy> ParseInternal(
+ const String& policy_string,
+ const DocumentPolicyNameFeatureMap& name_feature_map,
+ const DocumentPolicyFeatureInfoMap& feature_info_map,
+ const DocumentPolicyFeatureSet& available_features);
+};
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FEATURE_POLICY_DOCUMENT_POLICY_PARSER_H_
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
new file mode 100644
index 00000000000..61e6fbc2fa3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/feature_policy/document_policy_parser_test.cc
@@ -0,0 +1,175 @@
+// 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/feature_policy/document_policy_parser.h"
+
+#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 {
+
+using DocumentPolicyParserTest = ::testing::Test;
+
+const char* const kValidPolicies[] = {
+ "", // An empty policy.
+ " ", // An empty policy.
+ "font-display-late-swap",
+ "no-font-display-late-swap",
+ "unoptimized-lossless-images;bpp=1.0",
+ "unoptimized-lossless-images;bpp=2",
+ "unoptimized-lossless-images;bpp=2.0,no-font-display-late-swap",
+ "no-font-display-late-swap,unoptimized-lossless-images;bpp=2.0",
+ "no-font-display-late-swap;report-to=default,unoptimized-lossless-images;"
+ "bpp=2.0",
+ "no-font-display-late-swap;report-to=default,unoptimized-lossless-images;"
+ "bpp=2.0;report-to=default",
+ "no-font-display-late-swap;report-to=default,unoptimized-lossless-images;"
+ "report-to=default;bpp=2.0",
+ "no-font-display-late-swap;report-to=default,unoptimized-lossless-images;"
+ "report-to=endpoint;bpp=2.0",
+};
+
+const char* const kInvalidPolicies[] = {
+ "bad-feature-name", "no-bad-feature-name",
+ "font-display-late-swap;value=true", // unnecessary param
+ "unoptimized-lossless-images;bpp=?0", // wrong type of param
+ "unoptimized-lossless-images;ppb=2", // wrong param key
+ "\"font-display-late-swap\"", // policy member should be token instead of
+ // string
+ "();bpp=2", // empty feature token
+ "(font-display-late-swap unoptimized-lossless-images);bpp=2", // too many
+ // feature
+ // tokens
+ "unoptimized-lossless-images;report-to=default", // missing param
+ "font-display-late-swap;report-to=\"default\"", // report-to member should
+ // be token instead of
+ // string
+};
+
+// TODO(chenleihu): find a DocumentPolicyFeature name start with 'f' < c < 'n'
+// to further strengthen the test on proving "no-" prefix is not counted as part
+// of feature name for ordering.
+const std::pair<DocumentPolicy::FeatureState, std::string>
+ kPolicySerializationTestCases[] = {
+ {{{blink::mojom::DocumentPolicyFeature::kFontDisplay,
+ PolicyValue(false)},
+ {blink::mojom::DocumentPolicyFeature::kUnoptimizedLosslessImages,
+ PolicyValue(1.0)}},
+ "no-font-display-late-swap, unoptimized-lossless-images;bpp=1.0"},
+ // Changing ordering of FeatureState element should not affect
+ // serialization result.
+ {{{blink::mojom::DocumentPolicyFeature::kUnoptimizedLosslessImages,
+ PolicyValue(1.0)},
+ {blink::mojom::DocumentPolicyFeature::kFontDisplay,
+ PolicyValue(false)}},
+ "no-font-display-late-swap, unoptimized-lossless-images;bpp=1.0"},
+ // Flipping boolean-valued policy from false to true should not affect
+ // result ordering of feature.
+ {{{blink::mojom::DocumentPolicyFeature::kFontDisplay,
+ PolicyValue(true)},
+ {blink::mojom::DocumentPolicyFeature::kUnoptimizedLosslessImages,
+ PolicyValue(1.0)}},
+ "font-display-late-swap, unoptimized-lossless-images;bpp=1.0"}};
+
+const std::pair<const char*, DocumentPolicy::ParsedDocumentPolicy>
+ kPolicyParseTestCases[] = {
+ {"no-font-display-late-swap,unoptimized-lossless-images;bpp=1",
+ {{{blink::mojom::DocumentPolicyFeature::kFontDisplay,
+ PolicyValue(false)},
+ {blink::mojom::DocumentPolicyFeature::kUnoptimizedLosslessImages,
+ PolicyValue(1.0)}},
+ {} /* endpoint_map */}},
+ // White-space is allowed in some positions in structured-header.
+ {"no-font-display-late-swap, unoptimized-lossless-images;bpp=1",
+ {{{blink::mojom::DocumentPolicyFeature::kFontDisplay,
+ PolicyValue(false)},
+ {blink::mojom::DocumentPolicyFeature::kUnoptimizedLosslessImages,
+ PolicyValue(1.0)}},
+ {} /* endpoint_map */}},
+ {"no-font-display-late-swap,unoptimized-lossless-images;bpp=1;report-"
+ "to=default",
+ {{{blink::mojom::DocumentPolicyFeature::kFontDisplay,
+ PolicyValue(false)},
+ {blink::mojom::DocumentPolicyFeature::kUnoptimizedLosslessImages,
+ PolicyValue(1.0)}},
+ {{blink::mojom::DocumentPolicyFeature::kUnoptimizedLosslessImages,
+ "default"}}}},
+ {"no-font-display-late-swap;report-to=default,unoptimized-lossless-"
+ "images;bpp=1",
+ {{{blink::mojom::DocumentPolicyFeature::kFontDisplay,
+ PolicyValue(false)},
+ {blink::mojom::DocumentPolicyFeature::kUnoptimizedLosslessImages,
+ PolicyValue(1.0)}},
+ {{blink::mojom::DocumentPolicyFeature::kFontDisplay, "default"}}}}};
+
+const DocumentPolicy::FeatureState kParsedPolicies[] = {
+ {}, // An empty policy
+ {{mojom::DocumentPolicyFeature::kFontDisplay, PolicyValue(false)}},
+ {{mojom::DocumentPolicyFeature::kFontDisplay, PolicyValue(true)}},
+ {{mojom::DocumentPolicyFeature::kUnoptimizedLosslessImages,
+ PolicyValue(1.0)}},
+ {{mojom::DocumentPolicyFeature::kFontDisplay, PolicyValue(true)},
+ {mojom::DocumentPolicyFeature::kUnoptimizedLosslessImages,
+ PolicyValue(1.0)}}};
+
+// Serialize and then Parse the result of serialization should cancel each
+// other out, i.e. d == Parse(Serialize(d)).
+// The other way s == Serialize(Parse(s)) is not always true because structured
+// header allows some optional white spaces in its parsing targets and floating
+// point numbers will be rounded, e.g. bpp=1 will be parsed to PolicyValue(1.0)
+// and get serialized to bpp=1.0.
+TEST_F(DocumentPolicyParserTest, SerializeAndParse) {
+ for (const auto& policy : kParsedPolicies) {
+ const base::Optional<std::string> policy_string =
+ DocumentPolicy::Serialize(policy);
+ ASSERT_TRUE(policy_string.has_value());
+ const base::Optional<DocumentPolicy::ParsedDocumentPolicy> reparsed_policy =
+ DocumentPolicyParser::Parse(policy_string.value().c_str());
+
+ ASSERT_TRUE(reparsed_policy.has_value());
+ EXPECT_EQ(reparsed_policy.value().feature_state, policy);
+ }
+}
+
+TEST_F(DocumentPolicyParserTest, ParseValidPolicy) {
+ for (const char* policy : kValidPolicies) {
+ EXPECT_NE(DocumentPolicyParser::Parse(policy), base::nullopt)
+ << "Should parse " << policy;
+ }
+}
+
+TEST_F(DocumentPolicyParserTest, ParseInvalidPolicy) {
+ for (const char* policy : kInvalidPolicies) {
+ EXPECT_EQ(DocumentPolicyParser::Parse(policy),
+ base::make_optional(DocumentPolicy::ParsedDocumentPolicy{}))
+ << "Should fail to parse " << policy;
+ }
+}
+
+TEST_F(DocumentPolicyParserTest, SerializeResultShouldMatch) {
+ for (const auto& test_case : kPolicySerializationTestCases) {
+ const DocumentPolicy::FeatureState& policy = test_case.first;
+ const std::string& expected = test_case.second;
+ const auto result = DocumentPolicy::Serialize(policy);
+
+ ASSERT_TRUE(result.has_value());
+ EXPECT_EQ(result.value(), expected);
+ }
+}
+
+TEST_F(DocumentPolicyParserTest, ParseResultShouldMatch) {
+ for (const auto& test_case : kPolicyParseTestCases) {
+ const char* input = test_case.first;
+ const DocumentPolicy::ParsedDocumentPolicy& expected = test_case.second;
+ const auto result = DocumentPolicyParser::Parse(input);
+
+ ASSERT_TRUE(result.has_value());
+ EXPECT_EQ(result.value(), expected);
+ }
+}
+
+} // 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 12ab34ad6e2..7b2e7ab79e2 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,14 +19,14 @@ class CORE_EXPORT DOMDocumentPolicy final : public DOMFeaturePolicy {
// Create a new DOMDocumentPolicy, which is associated with |document|.
explicit DOMDocumentPolicy(Document* document) : document_(document) {}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(document_);
ScriptWrappable::Trace(visitor);
}
protected:
const FeaturePolicy* GetPolicy() const override {
- return document_->GetFeaturePolicy();
+ return document_->GetSecurityContext().GetFeaturePolicy();
}
Document* GetDocument() const override { return document_; }
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 ba83bbfe77a..d5ebc9620df 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
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/feature_policy/feature_policy_parser.h"
#include "third_party/blink/renderer/core/inspector/console_message.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/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
@@ -38,7 +39,7 @@ bool DOMFeaturePolicy::allowsFeature(ScriptState* script_state,
scoped_refptr<const SecurityOrigin> origin =
SecurityOrigin::CreateFromString(url);
if (!origin || origin->IsOpaque()) {
- GetDocument()->AddConsoleMessage(ConsoleMessage::Create(
+ GetDocument()->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kWarning,
"Invalid origin url for feature '" + feature + "': " + url + "."));
@@ -112,12 +113,12 @@ Vector<String> DOMFeaturePolicy::getAllowlistForFeature(
void DOMFeaturePolicy::AddWarningForUnrecognizedFeature(
const String& feature) const {
- GetDocument()->AddConsoleMessage(ConsoleMessage::Create(
+ GetDocument()->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther, mojom::ConsoleMessageLevel::kWarning,
"Unrecognized feature: '" + feature + "'."));
}
-void DOMFeaturePolicy::Trace(blink::Visitor* visitor) {
+void DOMFeaturePolicy::Trace(Visitor* visitor) {
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 277a4f34f7a..41b956de3d0 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 3e9db3b2a45..9c3841fb26e 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
@@ -9,7 +9,6 @@
"document-domain"
"document-write"
"encrypted-media"
-"font-display-late-swap"
"forms"
"fullscreen"
"geolocation"
@@ -23,25 +22,21 @@
"midi"
"modals"
"orientation-lock"
-"oversized-images"
"payment"
"picture-in-picture"
"pointer-lock"
"popups"
"presentation"
+"screen-wake-lock"
"scripts"
"serial"
"speaker"
"sync-script"
"sync-xkr"
"top-navigation"
-"unoptimized-lossless-images"
-"unoptimized-lossless-images-strict"
-"unoptimized-lossy-images"
"unsized-media"
"usb"
"vertical-scroll"
-"wake-lock"
"vr"
"\"https://example.com/\""
"*"
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 8a70579c1df..7e0db368b83 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
@@ -94,6 +94,16 @@
depends_on: ["FeaturePolicyForClientHints"],
},
{
+ name: "ClientHintUAMobile",
+ feature_policy_name: "ch-ua-mobile",
+ depends_on: ["FeaturePolicyForClientHints"],
+ },
+ {
+ name: "ClientHintUAFullVersion",
+ feature_policy_name: "ch-ua-full-version",
+ depends_on: ["FeaturePolicyForClientHints"],
+ },
+ {
name: "ClientHintViewportWidth",
feature_policy_name: "ch-viewport-width",
depends_on: ["FeaturePolicyForClientHints"],
@@ -137,11 +147,6 @@
depends_on: ["BlockingFocusWithoutUserActivation"],
},
{
- name: "FontDisplay",
- feature_policy_name: "font-display-late-swap",
- depends_on: ["ExperimentalProductivityFeatures"],
- },
- {
name: "FormSubmission",
feature_policy_name: "forms",
depends_on: ["FeaturePolicyForSandbox"],
@@ -211,11 +216,6 @@
depends_on: ["FeaturePolicyForSandbox"],
},
{
- name: "OversizedImages",
- feature_policy_name: "oversized-images",
- depends_on: ["UnoptimizedImagePolicies"],
- },
- {
name: "Payment",
feature_policy_name: "payment",
depends_on: ["PaymentRequest"],
@@ -246,6 +246,11 @@
depends_on: ["WebAuthenticationFeaturePolicy"],
},
{
+ name: "ScreenWakeLock",
+ feature_policy_name: "screen-wake-lock",
+ depends_on: ["WakeLock"],
+ },
+ {
name: "Script",
feature_policy_name: "scripts",
depends_on: ["FeaturePolicyForSandbox"],
@@ -270,24 +275,9 @@
depends_on: ["FeaturePolicyForSandbox"],
},
{
- name: "UnoptimizedLosslessImages",
- feature_policy_name: "unoptimized-lossless-images",
- depends_on: ["UnoptimizedImagePolicies"],
- },
- {
- name: "UnoptimizedLosslessImagesStrict",
- feature_policy_name: "unoptimized-lossless-images-strict",
- depends_on: ["UnoptimizedImagePolicies"],
- },
- {
- name: "UnoptimizedLossyImages",
- feature_policy_name: "unoptimized-lossy-images",
- depends_on: ["UnoptimizedImagePolicies"],
- },
- {
- name: "UnsizedMedia",
- feature_policy_name: "unsized-media",
- depends_on: ["UnsizedMediaPolicy"],
+ name: "TrustTokenRedemption",
+ feature_policy_name: "trust-token-redemption",
+ depends_on: ["TrustTokens"],
},
{
name: "Usb",
@@ -300,11 +290,6 @@
depends_on: ["ExperimentalProductivityFeatures"],
},
{
- name: "WakeLock",
- feature_policy_name: "wake-lock",
- depends_on: ["WakeLock"],
- },
- {
name: "WebXr",
feature_policy_name: "xr-spatial-tracking",
depends_on: ["WebXR"],
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_helper.h b/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_helper.h
index c1796b27d37..74dde545b59 100644
--- a/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_helper.h
+++ b/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_helper.h
@@ -6,13 +6,19 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_FEATURE_POLICY_FEATURE_POLICY_HELPER_H_
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
+#include "third_party/blink/public/mojom/feature_policy/document_policy_feature.mojom-blink-forward.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/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
-using FeatureNameMap = HashMap<String, mojom::FeaturePolicyFeature>;
+using FeatureNameMap = HashMap<String, mojom::blink::FeaturePolicyFeature>;
+using DocumentPolicyFeatureSet =
+ HashSet<mojom::blink::DocumentPolicyFeature,
+ IntHash<mojom::blink::DocumentPolicyFeature>>;
class FeatureContext;
@@ -22,10 +28,21 @@ class FeatureContext;
// policy object.
const FeatureNameMap& GetDefaultFeatureNameMap();
-// Returns true if this feature is currently disabled by an origin trial (it is
-// origin trial controlled, and the origin trial is not enabled).
+// This method defines the feature names which will be recognized by the parser
+// for the Document-Policy HTTP header and the <iframe> "policy" attribute, as
+// well as the features which will be recognized by the document or iframe
+// policy object.
+const DocumentPolicyFeatureSet& GetAvailableDocumentPolicyFeatures();
+
+// Returns true if this FeaturePolicyFeature is currently disabled by an origin
+// trial (it is origin trial controlled, and the origin trial is not enabled).
+// The first String param should be a name of FeaturePolicyFeature.
bool DisabledByOriginTrial(const String&, FeatureContext*);
+// Returns true if this DocumentPolicyFeature is currently disabled by an origin
+// trial (it is origin trial controlled, and the origin trial is not enabled).
+bool DisabledByOriginTrial(mojom::blink::DocumentPolicyFeature,
+ FeatureContext*);
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FEATURE_POLICY_FEATURE_POLICY_HELPER_H_
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 2c0cb2e96b3..0c08fe742ce 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
@@ -67,7 +67,8 @@ ParsedFeaturePolicy FeaturePolicyParser::Parse(
return allowlists;
}
- std::bitset<static_cast<size_t>(mojom::FeaturePolicyFeature::kMaxValue) + 1>
+ std::bitset<
+ static_cast<size_t>(mojom::blink::FeaturePolicyFeature::kMaxValue) + 1>
features_specified;
HashSet<FeaturePolicyAllowlistType> allowlist_types_used;
@@ -114,7 +115,8 @@ ParsedFeaturePolicy FeaturePolicyParser::Parse(
continue;
}
- mojom::FeaturePolicyFeature feature = feature_names.at(feature_name);
+ mojom::blink::FeaturePolicyFeature feature =
+ feature_names.at(feature_name);
mojom::PolicyValueType feature_type =
FeaturePolicy::GetDefaultFeatureList().at(feature).second;
// If a policy has already been specified for the current feature, drop
@@ -143,30 +145,6 @@ ParsedFeaturePolicy FeaturePolicyParser::Parse(
bool allowlist_includes_none = false;
bool allowlist_includes_origin = false;
- // Detect usage of UnoptimizedImagePolicies origin trial.
- if (feature == mojom::FeaturePolicyFeature::kOversizedImages ||
- feature == mojom::FeaturePolicyFeature::kUnoptimizedLossyImages ||
- feature == mojom::FeaturePolicyFeature::kUnoptimizedLosslessImages ||
- feature ==
- mojom::FeaturePolicyFeature::kUnoptimizedLosslessImagesStrict) {
- if (delegate) {
- delegate->CountFeaturePolicyUsage(
- mojom::WebFeature::kUnoptimizedImagePolicies);
- }
- // Don't analyze allowlists for origin trial features.
- count_allowlist_type = false;
- }
-
- // Detect usage of UnsizedMediaPolicy origin trial
- if (feature == mojom::FeaturePolicyFeature::kUnsizedMedia) {
- if (delegate) {
- delegate->CountFeaturePolicyUsage(
- mojom::WebFeature::kUnsizedMediaPolicy);
- }
- // Don't analyze allowlists for origin trial features.
- count_allowlist_type = false;
- }
-
ParsedFeaturePolicyDeclaration allowlist(feature, feature_type);
// TODO(loonybear): fallback value should be parsed from the new syntax.
allowlist.fallback_value = GetFallbackValueForFeature(feature);
@@ -359,21 +337,7 @@ ParsedFeaturePolicy FeaturePolicyParser::Parse(
// parse the policy value for each parameterized feature, and for non
// parameterized feature (i.e. boolean-type policy value).
PolicyValue FeaturePolicyParser::GetFallbackValueForFeature(
- mojom::FeaturePolicyFeature feature) {
- if (feature == mojom::FeaturePolicyFeature::kOversizedImages) {
- return PolicyValue(2.0);
- }
- if (feature == mojom::FeaturePolicyFeature::kUnoptimizedLossyImages) {
- // Lossy images default to at most 0.5 bytes per pixel.
- return PolicyValue(0.5);
- }
- if (feature == mojom::FeaturePolicyFeature::kUnoptimizedLosslessImages ||
- feature ==
- mojom::FeaturePolicyFeature::kUnoptimizedLosslessImagesStrict) {
- // Lossless images default to at most 1 byte per pixel.
- return PolicyValue(1.0);
- }
-
+ mojom::blink::FeaturePolicyFeature feature) {
return PolicyValue(false);
}
@@ -423,7 +387,7 @@ void FeaturePolicyParser::ParseValueForFuzzer(
ParseValueForType(feature_type, value_string, &ok);
}
-bool IsFeatureDeclared(mojom::FeaturePolicyFeature feature,
+bool IsFeatureDeclared(mojom::blink::FeaturePolicyFeature feature,
const ParsedFeaturePolicy& policy) {
return std::any_of(policy.begin(), policy.end(),
[feature](const auto& declaration) {
@@ -431,7 +395,7 @@ bool IsFeatureDeclared(mojom::FeaturePolicyFeature feature,
});
}
-bool RemoveFeatureIfPresent(mojom::FeaturePolicyFeature feature,
+bool RemoveFeatureIfPresent(mojom::blink::FeaturePolicyFeature feature,
ParsedFeaturePolicy& policy) {
auto new_end = std::remove_if(policy.begin(), policy.end(),
[feature](const auto& declaration) {
@@ -443,7 +407,7 @@ bool RemoveFeatureIfPresent(mojom::FeaturePolicyFeature feature,
return true;
}
-bool DisallowFeatureIfNotPresent(mojom::FeaturePolicyFeature feature,
+bool DisallowFeatureIfNotPresent(mojom::blink::FeaturePolicyFeature feature,
ParsedFeaturePolicy& policy) {
if (IsFeatureDeclared(feature, policy))
return false;
@@ -454,8 +418,9 @@ bool DisallowFeatureIfNotPresent(mojom::FeaturePolicyFeature feature,
return true;
}
-bool AllowFeatureEverywhereIfNotPresent(mojom::FeaturePolicyFeature feature,
- ParsedFeaturePolicy& policy) {
+bool AllowFeatureEverywhereIfNotPresent(
+ mojom::blink::FeaturePolicyFeature feature,
+ ParsedFeaturePolicy& policy) {
if (IsFeatureDeclared(feature, policy))
return false;
blink::mojom::PolicyValueType feature_type =
@@ -467,13 +432,13 @@ bool AllowFeatureEverywhereIfNotPresent(mojom::FeaturePolicyFeature feature,
return true;
}
-void DisallowFeature(mojom::FeaturePolicyFeature feature,
+void DisallowFeature(mojom::blink::FeaturePolicyFeature feature,
ParsedFeaturePolicy& policy) {
RemoveFeatureIfPresent(feature, policy);
DisallowFeatureIfNotPresent(feature, policy);
}
-void AllowFeatureEverywhere(mojom::FeaturePolicyFeature feature,
+void AllowFeatureEverywhere(mojom::blink::FeaturePolicyFeature feature,
ParsedFeaturePolicy& policy) {
RemoveFeatureIfPresent(feature, policy);
AllowFeatureEverywhereIfNotPresent(feature, policy);
@@ -488,7 +453,7 @@ const Vector<String> GetAvailableFeatures(ExecutionContext* execution_context) {
return available_features;
}
-const String& GetNameForFeature(mojom::FeaturePolicyFeature feature) {
+const String& GetNameForFeature(mojom::blink::FeaturePolicyFeature feature) {
for (const auto& entry : GetDefaultFeatureNameMap()) {
if (entry.value == feature)
return entry.key;
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 7a9725ccce2..371b1fc3e31 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
@@ -98,43 +98,44 @@ class CORE_EXPORT FeaturePolicyParser {
private:
static PolicyValue GetFallbackValueForFeature(
- mojom::FeaturePolicyFeature feature);
+ mojom::blink::FeaturePolicyFeature feature);
static PolicyValue ParseValueForType(mojom::PolicyValueType feature_type,
const String& value_string,
bool* ok);
};
// Returns true iff any declaration in the policy is for the given feature.
-CORE_EXPORT bool IsFeatureDeclared(mojom::FeaturePolicyFeature,
+CORE_EXPORT bool IsFeatureDeclared(mojom::blink::FeaturePolicyFeature,
const ParsedFeaturePolicy&);
// Removes any declaration in the policy for the given feature. Returns true if
// the policy was modified.
-CORE_EXPORT bool RemoveFeatureIfPresent(mojom::FeaturePolicyFeature,
+CORE_EXPORT bool RemoveFeatureIfPresent(mojom::blink::FeaturePolicyFeature,
ParsedFeaturePolicy&);
// If no declaration in the policy exists already for the feature, adds a
// declaration which disallows the feature in all origins. Returns true if the
// policy was modified.
-CORE_EXPORT bool DisallowFeatureIfNotPresent(mojom::FeaturePolicyFeature,
+CORE_EXPORT bool DisallowFeatureIfNotPresent(mojom::blink::FeaturePolicyFeature,
ParsedFeaturePolicy&);
// If no declaration in the policy exists already for the feature, adds a
// declaration which allows the feature in all origins. Returns true if the
// policy was modified.
-CORE_EXPORT bool AllowFeatureEverywhereIfNotPresent(mojom::FeaturePolicyFeature,
- ParsedFeaturePolicy&);
+CORE_EXPORT bool AllowFeatureEverywhereIfNotPresent(
+ mojom::blink::FeaturePolicyFeature,
+ ParsedFeaturePolicy&);
// Replaces any existing declarations in the policy for the given feature with
// a declaration which disallows the feature in all origins.
-CORE_EXPORT void DisallowFeature(mojom::FeaturePolicyFeature,
+CORE_EXPORT void DisallowFeature(mojom::blink::FeaturePolicyFeature,
ParsedFeaturePolicy&);
// Replaces any existing declarations in the policy for the given feature with
// a declaration which allows the feature in all origins.
-CORE_EXPORT void AllowFeatureEverywhere(mojom::FeaturePolicyFeature,
+CORE_EXPORT void AllowFeatureEverywhere(mojom::blink::FeaturePolicyFeature,
ParsedFeaturePolicy&);
-CORE_EXPORT const String& GetNameForFeature(mojom::FeaturePolicyFeature);
+CORE_EXPORT const String& GetNameForFeature(mojom::blink::FeaturePolicyFeature);
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_parser_delegate.h b/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_parser_delegate.h
index 96323722eef..fdef900d8d4 100644
--- a/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_parser_delegate.h
+++ b/chromium/third_party/blink/renderer/core/feature_policy/feature_policy_parser_delegate.h
@@ -15,7 +15,7 @@ class FeaturePolicyParserDelegate : public FeatureContext {
public:
virtual void CountFeaturePolicyUsage(mojom::WebFeature feature) = 0;
virtual bool FeaturePolicyFeatureObserved(
- mojom::FeaturePolicyFeature feature) = 0;
+ mojom::blink::FeaturePolicyFeature feature) = 0;
};
} // namespace blink
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 a3e903e3e32..1abaea5b1e9 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
@@ -54,14 +54,6 @@ const char* const kValidPolicies[] = {
"fullscreen " ORIGIN_A "(false)",
"fullscreen " ORIGIN_A "(True)",
"fullscreen " ORIGIN_A "(TRUE)",
- "oversized-images " ORIGIN_A "(2.0)",
- "oversized-images " ORIGIN_A "(0.0)",
- "oversized-images " ORIGIN_A "(4)",
- "oversized-images " ORIGIN_A "(20000)",
- "oversized-images " ORIGIN_A "(2e50)",
- "oversized-images " ORIGIN_A "(inf)",
- "oversized-images " ORIGIN_A "(Inf)",
- "oversized-images " ORIGIN_A "(INF)",
"fullscreen " ORIGIN_A "; payment *, geolocation 'self'"};
const char* const kInvalidPolicies[] = {
@@ -77,12 +69,6 @@ const char* const kInvalidPolicies[] = {
"fullscreen(true)",
"fullscreen " ORIGIN_A "(notabool)",
"fullscreen " ORIGIN_A "(2.0)",
- "oversized-images " ORIGIN_A "(true)",
- "oversized-images " ORIGIN_A "(Something else)",
- "oversized-images " ORIGIN_A "(1",
- "oversized-images " ORIGIN_A "(-1)",
- "oversized-images " ORIGIN_A "(1.2.3)",
- "oversized-images " ORIGIN_A "(1.a.3)",
"fullscreen " ORIGIN_A "()"};
// Names of UMA histograms
@@ -111,11 +97,9 @@ class FeaturePolicyParserTest : public testing::Test {
url::Origin expected_url_origin_c_ = url::Origin::Create(GURL(ORIGIN_C));
const FeatureNameMap test_feature_name_map = {
- {"fullscreen", blink::mojom::FeaturePolicyFeature::kFullscreen},
- {"payment", blink::mojom::FeaturePolicyFeature::kPayment},
- {"geolocation", blink::mojom::FeaturePolicyFeature::kGeolocation},
- {"oversized-images",
- blink::mojom::FeaturePolicyFeature::kOversizedImages}};
+ {"fullscreen", blink::mojom::blink::FeaturePolicyFeature::kFullscreen},
+ {"payment", blink::mojom::blink::FeaturePolicyFeature::kPayment},
+ {"geolocation", blink::mojom::blink::FeaturePolicyFeature::kGeolocation}};
const PolicyValue min_value = PolicyValue(false);
const PolicyValue max_value = PolicyValue(true);
@@ -172,7 +156,7 @@ TEST_F(FeaturePolicyParserTest, PolicyParsedCorrectly) {
&messages, test_feature_name_map);
EXPECT_EQ(1UL, parsed_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kGeolocation,
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kGeolocation,
parsed_policy[0].feature);
EXPECT_GE(min_value, parsed_policy[0].fallback_value);
EXPECT_GE(min_value, parsed_policy[0].opaque_value);
@@ -185,7 +169,7 @@ TEST_F(FeaturePolicyParserTest, PolicyParsedCorrectly) {
origin_b_.get(), &messages,
test_feature_name_map);
EXPECT_EQ(1UL, parsed_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kGeolocation,
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kGeolocation,
parsed_policy[0].feature);
EXPECT_LE(max_value, parsed_policy[0].fallback_value);
EXPECT_LE(max_value, parsed_policy[0].opaque_value);
@@ -198,19 +182,21 @@ TEST_F(FeaturePolicyParserTest, PolicyParsedCorrectly) {
"payment 'self'",
origin_a_.get(), origin_b_.get(), &messages, test_feature_name_map);
EXPECT_EQ(3UL, parsed_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kGeolocation,
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kGeolocation,
parsed_policy[0].feature);
EXPECT_LE(max_value, parsed_policy[0].fallback_value);
EXPECT_LE(max_value, parsed_policy[0].opaque_value);
EXPECT_EQ(0UL, parsed_policy[0].values.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, parsed_policy[1].feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen,
+ parsed_policy[1].feature);
EXPECT_GE(min_value, parsed_policy[1].fallback_value);
EXPECT_GE(min_value, parsed_policy[1].opaque_value);
EXPECT_EQ(2UL, parsed_policy[1].values.size());
auto it = parsed_policy[1].values.begin();
EXPECT_TRUE(it->first.IsSameOriginWith(expected_url_origin_b_));
EXPECT_TRUE((++it)->first.IsSameOriginWith(expected_url_origin_c_));
- EXPECT_EQ(mojom::FeaturePolicyFeature::kPayment, parsed_policy[2].feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kPayment,
+ parsed_policy[2].feature);
EXPECT_GE(min_value, parsed_policy[2].fallback_value);
EXPECT_GE(min_value, parsed_policy[2].opaque_value);
EXPECT_EQ(1UL, parsed_policy[2].values.size());
@@ -224,19 +210,21 @@ TEST_F(FeaturePolicyParserTest, PolicyParsedCorrectly) {
"payment 'self' badorigin",
origin_a_.get(), origin_b_.get(), &messages, test_feature_name_map);
EXPECT_EQ(3UL, parsed_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kGeolocation,
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kGeolocation,
parsed_policy[0].feature);
EXPECT_LE(max_value, parsed_policy[0].fallback_value);
EXPECT_LE(max_value, parsed_policy[0].opaque_value);
EXPECT_EQ(0UL, parsed_policy[0].values.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, parsed_policy[1].feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen,
+ parsed_policy[1].feature);
EXPECT_GE(min_value, parsed_policy[1].fallback_value);
EXPECT_GE(min_value, parsed_policy[1].opaque_value);
EXPECT_EQ(2UL, parsed_policy[1].values.size());
it = parsed_policy[1].values.begin();
EXPECT_TRUE(it->first.IsSameOriginWith(expected_url_origin_b_));
EXPECT_TRUE((++it)->first.IsSameOriginWith(expected_url_origin_c_));
- EXPECT_EQ(mojom::FeaturePolicyFeature::kPayment, parsed_policy[2].feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kPayment,
+ parsed_policy[2].feature);
EXPECT_GE(min_value, parsed_policy[2].fallback_value);
EXPECT_GE(min_value, parsed_policy[2].opaque_value);
EXPECT_EQ(1UL, parsed_policy[2].values.size());
@@ -248,20 +236,22 @@ TEST_F(FeaturePolicyParserTest, PolicyParsedCorrectly) {
origin_a_.get(), nullptr,
&messages, test_feature_name_map);
EXPECT_EQ(3UL, parsed_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kGeolocation,
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kGeolocation,
parsed_policy[0].feature);
EXPECT_GE(min_value, parsed_policy[0].fallback_value);
EXPECT_GE(min_value, parsed_policy[0].opaque_value);
EXPECT_EQ(1UL, parsed_policy[0].values.size());
EXPECT_TRUE(parsed_policy[0].values.begin()->first.IsSameOriginWith(
expected_url_origin_a_));
- EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, parsed_policy[1].feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen,
+ parsed_policy[1].feature);
EXPECT_GE(min_value, parsed_policy[1].fallback_value);
EXPECT_GE(min_value, parsed_policy[1].opaque_value);
EXPECT_EQ(1UL, parsed_policy[1].values.size());
EXPECT_TRUE(parsed_policy[1].values.begin()->first.IsSameOriginWith(
expected_url_origin_a_));
- EXPECT_EQ(mojom::FeaturePolicyFeature::kPayment, parsed_policy[2].feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kPayment,
+ parsed_policy[2].feature);
EXPECT_GE(min_value, parsed_policy[2].opaque_value);
EXPECT_EQ(1UL, parsed_policy[2].values.size());
EXPECT_TRUE(parsed_policy[2].values.begin()->first.IsSameOriginWith(
@@ -286,7 +276,7 @@ TEST_F(FeaturePolicyParserTest, PolicyParsedCorrectlyForOpaqueOrigins) {
test_feature_name_map);
EXPECT_EQ(1UL, parsed_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kGeolocation,
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kGeolocation,
parsed_policy[0].feature);
EXPECT_GE(min_value, parsed_policy[0].fallback_value);
EXPECT_LE(max_value, parsed_policy[0].opaque_value);
@@ -298,7 +288,7 @@ TEST_F(FeaturePolicyParserTest, PolicyParsedCorrectlyForOpaqueOrigins) {
test_feature_name_map);
EXPECT_EQ(1UL, parsed_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kGeolocation,
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kGeolocation,
parsed_policy[0].feature);
EXPECT_GE(min_value, parsed_policy[0].fallback_value);
EXPECT_LE(max_value, parsed_policy[0].opaque_value);
@@ -310,7 +300,7 @@ TEST_F(FeaturePolicyParserTest, PolicyParsedCorrectlyForOpaqueOrigins) {
test_feature_name_map);
EXPECT_EQ(1UL, parsed_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kGeolocation,
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kGeolocation,
parsed_policy[0].feature);
EXPECT_LE(max_value, parsed_policy[0].fallback_value);
EXPECT_LE(max_value, parsed_policy[0].opaque_value);
@@ -322,7 +312,7 @@ TEST_F(FeaturePolicyParserTest, PolicyParsedCorrectlyForOpaqueOrigins) {
opaque_origin.get(), &messages, test_feature_name_map);
EXPECT_EQ(1UL, parsed_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kGeolocation,
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kGeolocation,
parsed_policy[0].feature);
EXPECT_GE(min_value, parsed_policy[0].fallback_value);
EXPECT_GE(min_value, parsed_policy[0].opaque_value);
@@ -337,7 +327,7 @@ TEST_F(FeaturePolicyParserTest, PolicyParsedCorrectlyForOpaqueOrigins) {
opaque_origin.get(), &messages, test_feature_name_map);
EXPECT_EQ(1UL, parsed_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kGeolocation,
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kGeolocation,
parsed_policy[0].feature);
EXPECT_GE(min_value, parsed_policy[0].fallback_value);
EXPECT_LE(max_value, parsed_policy[0].opaque_value);
@@ -356,7 +346,8 @@ TEST_F(FeaturePolicyParserTest, BooleanPolicyParametersParsedCorrectly) {
origin_a_.get(), origin_b_.get(),
&messages, test_feature_name_map);
EXPECT_EQ(1UL, parsed_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, parsed_policy[0].feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen,
+ parsed_policy[0].feature);
EXPECT_EQ(min_value, parsed_policy[0].fallback_value);
EXPECT_EQ(min_value, parsed_policy[0].opaque_value);
EXPECT_EQ(1UL, parsed_policy[0].values.size());
@@ -370,7 +361,8 @@ TEST_F(FeaturePolicyParserTest, BooleanPolicyParametersParsedCorrectly) {
FeaturePolicyParser::Parse("fullscreen (true)", origin_a_.get(), nullptr,
&messages, test_feature_name_map);
EXPECT_EQ(1UL, parsed_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, parsed_policy[0].feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen,
+ parsed_policy[0].feature);
EXPECT_EQ(min_value, parsed_policy[0].fallback_value);
EXPECT_EQ(min_value, parsed_policy[0].opaque_value);
EXPECT_EQ(1UL, parsed_policy[0].values.size());
@@ -386,7 +378,8 @@ TEST_F(FeaturePolicyParserTest, BooleanPolicyParametersParsedCorrectly) {
origin_a_.get(), opaque_origin,
&messages, test_feature_name_map);
EXPECT_EQ(1UL, parsed_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, parsed_policy[0].feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen,
+ parsed_policy[0].feature);
EXPECT_EQ(min_value, parsed_policy[0].fallback_value);
EXPECT_EQ(max_value, parsed_policy[0].opaque_value);
EXPECT_EQ(0UL, parsed_policy[0].values.size());
@@ -397,7 +390,8 @@ TEST_F(FeaturePolicyParserTest, BooleanPolicyParametersParsedCorrectly) {
&messages, test_feature_name_map);
EXPECT_EQ(1UL, parsed_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, parsed_policy[0].feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen,
+ parsed_policy[0].feature);
EXPECT_EQ(min_value, parsed_policy[0].fallback_value);
EXPECT_EQ(min_value, parsed_policy[0].opaque_value);
EXPECT_EQ(1UL, parsed_policy[0].values.size());
@@ -411,7 +405,8 @@ TEST_F(FeaturePolicyParserTest, BooleanPolicyParametersParsedCorrectly) {
&messages, test_feature_name_map);
EXPECT_EQ(1UL, parsed_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, parsed_policy[0].feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen,
+ parsed_policy[0].feature);
EXPECT_EQ(min_value, parsed_policy[0].fallback_value);
EXPECT_EQ(min_value, parsed_policy[0].opaque_value);
EXPECT_EQ(0UL, parsed_policy[0].values.size());
@@ -422,156 +417,13 @@ TEST_F(FeaturePolicyParserTest, BooleanPolicyParametersParsedCorrectly) {
&messages, test_feature_name_map);
EXPECT_EQ(1UL, parsed_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, parsed_policy[0].feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen,
+ parsed_policy[0].feature);
EXPECT_EQ(max_value, parsed_policy[0].fallback_value);
EXPECT_EQ(max_value, parsed_policy[0].opaque_value);
EXPECT_EQ(0UL, parsed_policy[0].values.size());
}
-TEST_F(FeaturePolicyParserTest, DoublePolicyParametersParsedCorrectly) {
- Vector<String> messages;
- ParsedFeaturePolicy parsed_policy;
-
- // 'self'(inf)
- parsed_policy = FeaturePolicyParser::Parse("oversized-images 'self'(inf)",
- origin_a_.get(), origin_b_.get(),
- &messages, test_feature_name_map);
- EXPECT_EQ(1UL, parsed_policy.size());
-
- EXPECT_EQ(mojom::FeaturePolicyFeature::kOversizedImages,
- parsed_policy[0].feature);
- EXPECT_EQ(default_double_value, parsed_policy[0].fallback_value);
- EXPECT_EQ(default_double_value, parsed_policy[0].opaque_value);
- EXPECT_EQ(1UL, parsed_policy[0].values.size());
- EXPECT_TRUE(parsed_policy[0].values.begin()->first.IsSameOriginWith(
- expected_url_origin_a_));
- EXPECT_EQ(max_double_value, parsed_policy[0].values.begin()->second);
-
- // 'self'(1.5)
- parsed_policy = FeaturePolicyParser::Parse("oversized-images 'self'(1.5)",
- origin_a_.get(), origin_b_.get(),
- &messages, test_feature_name_map);
- EXPECT_EQ(1UL, parsed_policy.size());
-
- EXPECT_EQ(mojom::FeaturePolicyFeature::kOversizedImages,
- parsed_policy[0].feature);
- EXPECT_EQ(default_double_value, parsed_policy[0].fallback_value);
- EXPECT_EQ(default_double_value, parsed_policy[0].opaque_value);
- EXPECT_EQ(1UL, parsed_policy[0].values.size());
- EXPECT_TRUE(parsed_policy[0].values.begin()->first.IsSameOriginWith(
- expected_url_origin_a_));
- EXPECT_EQ(sample_double_value, parsed_policy[0].values.begin()->second);
-
- // *(inf)
- parsed_policy = FeaturePolicyParser::Parse("oversized-images *(inf)",
- origin_a_.get(), origin_b_.get(),
- &messages, test_feature_name_map);
- EXPECT_EQ(1UL, parsed_policy.size());
-
- EXPECT_EQ(mojom::FeaturePolicyFeature::kOversizedImages,
- parsed_policy[0].feature);
- EXPECT_EQ(max_double_value, parsed_policy[0].fallback_value);
- EXPECT_EQ(max_double_value, parsed_policy[0].opaque_value);
- EXPECT_EQ(0UL, parsed_policy[0].values.size());
-
- // *(0)
- parsed_policy = FeaturePolicyParser::Parse("oversized-images *(0)",
- origin_a_.get(), origin_b_.get(),
- &messages, test_feature_name_map);
- EXPECT_EQ(1UL, parsed_policy.size());
-
- EXPECT_EQ(mojom::FeaturePolicyFeature::kOversizedImages,
- parsed_policy[0].feature);
- EXPECT_EQ(min_double_value, parsed_policy[0].fallback_value);
- EXPECT_EQ(min_double_value, parsed_policy[0].opaque_value);
- EXPECT_EQ(0UL, parsed_policy[0].values.size());
-
- // *(1.5)
- parsed_policy = FeaturePolicyParser::Parse("oversized-images *(1.5)",
- origin_a_.get(), origin_b_.get(),
- &messages, test_feature_name_map);
- EXPECT_EQ(1UL, parsed_policy.size());
-
- EXPECT_EQ(mojom::FeaturePolicyFeature::kOversizedImages,
- parsed_policy[0].feature);
- EXPECT_EQ(sample_double_value, parsed_policy[0].fallback_value);
- EXPECT_EQ(sample_double_value, parsed_policy[0].opaque_value);
- EXPECT_EQ(0UL, parsed_policy[0].values.size());
-
- // 'self'(1.5) 'src'(inf)
- // Fallbacks should be default values.
- parsed_policy = FeaturePolicyParser::Parse(
- "oversized-images 'self'(1.5) 'src'(inf)", origin_a_.get(),
- origin_b_.get(), &messages, test_feature_name_map);
- EXPECT_EQ(1UL, parsed_policy.size());
-
- EXPECT_EQ(mojom::FeaturePolicyFeature::kOversizedImages,
- parsed_policy[0].feature);
- EXPECT_EQ(default_double_value, parsed_policy[0].fallback_value);
- EXPECT_EQ(default_double_value, parsed_policy[0].opaque_value);
- EXPECT_EQ(2UL, parsed_policy[0].values.size());
- auto origin_and_value = parsed_policy[0].values.begin();
- EXPECT_TRUE(origin_and_value->first.IsSameOriginWith(expected_url_origin_a_));
- EXPECT_EQ(sample_double_value, origin_and_value->second);
- origin_and_value++;
- EXPECT_TRUE(origin_and_value->first.IsSameOriginWith(expected_url_origin_b_));
- EXPECT_EQ(max_double_value, origin_and_value->second);
-
- // *(1.5) 'src'(inf)
- // Fallbacks should be 1.5
- parsed_policy = FeaturePolicyParser::Parse(
- "oversized-images *(1.5) 'src'(inf)", origin_a_.get(), origin_b_.get(),
- &messages, test_feature_name_map);
- EXPECT_EQ(1UL, parsed_policy.size());
-
- EXPECT_EQ(mojom::FeaturePolicyFeature::kOversizedImages,
- parsed_policy[0].feature);
- EXPECT_EQ(sample_double_value, parsed_policy[0].fallback_value);
- EXPECT_EQ(sample_double_value, parsed_policy[0].opaque_value);
- EXPECT_EQ(1UL, parsed_policy[0].values.size());
- origin_and_value = parsed_policy[0].values.begin();
- EXPECT_TRUE(origin_and_value->first.IsSameOriginWith(expected_url_origin_b_));
- EXPECT_EQ(max_double_value, origin_and_value->second);
-
- // Test policy: 'self'(1.5) https://example.org(inf)
- // Fallbacks should be default value.
- parsed_policy = FeaturePolicyParser::Parse(
- "oversized-images 'self'(1.5) " ORIGIN_C "(inf)", origin_a_.get(),
- origin_b_.get(), &messages, test_feature_name_map);
- EXPECT_EQ(1UL, parsed_policy.size());
-
- EXPECT_EQ(mojom::FeaturePolicyFeature::kOversizedImages,
- parsed_policy[0].feature);
- EXPECT_EQ(default_double_value, parsed_policy[0].fallback_value);
- EXPECT_EQ(default_double_value, parsed_policy[0].opaque_value);
- EXPECT_EQ(2UL, parsed_policy[0].values.size());
- origin_and_value = parsed_policy[0].values.begin();
- EXPECT_TRUE(origin_and_value->first.IsSameOriginWith(expected_url_origin_a_));
- EXPECT_EQ(sample_double_value, origin_and_value->second);
- origin_and_value++;
- EXPECT_TRUE(origin_and_value->first.IsSameOriginWith(expected_url_origin_c_));
- EXPECT_EQ(max_double_value, origin_and_value->second);
-
- // Test policy: 'self'(1.5) https://example.org(inf) *(0)
- // Fallbacks should be 0.
- parsed_policy = FeaturePolicyParser::Parse(
- "oversized-images 'self'(1.5) " ORIGIN_C "(inf) *(0)", origin_a_.get(),
- origin_b_.get(), &messages, test_feature_name_map);
- EXPECT_EQ(1UL, parsed_policy.size());
-
- EXPECT_EQ(mojom::FeaturePolicyFeature::kOversizedImages,
- parsed_policy[0].feature);
- EXPECT_EQ(min_double_value, parsed_policy[0].fallback_value);
- EXPECT_EQ(min_double_value, parsed_policy[0].opaque_value);
- EXPECT_EQ(2UL, parsed_policy[0].values.size());
- origin_and_value = parsed_policy[0].values.begin();
- EXPECT_TRUE(origin_and_value->first.IsSameOriginWith(expected_url_origin_a_));
- EXPECT_EQ(sample_double_value, origin_and_value->second);
- origin_and_value++;
- EXPECT_TRUE(origin_and_value->first.IsSameOriginWith(expected_url_origin_c_));
- EXPECT_EQ(max_double_value, origin_and_value->second);
-}
-
TEST_F(FeaturePolicyParserTest, RedundantBooleanItemsRemoved) {
Vector<String> messages;
ParsedFeaturePolicy parsed_policy;
@@ -582,7 +434,8 @@ TEST_F(FeaturePolicyParserTest, RedundantBooleanItemsRemoved) {
&messages, test_feature_name_map);
EXPECT_EQ(1UL, parsed_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, parsed_policy[0].feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen,
+ parsed_policy[0].feature);
EXPECT_EQ(max_value, parsed_policy[0].fallback_value);
EXPECT_EQ(max_value, parsed_policy[0].opaque_value);
EXPECT_EQ(0UL, parsed_policy[0].values.size());
@@ -593,7 +446,8 @@ TEST_F(FeaturePolicyParserTest, RedundantBooleanItemsRemoved) {
&messages, test_feature_name_map);
EXPECT_EQ(1UL, parsed_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, parsed_policy[0].feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen,
+ parsed_policy[0].feature);
EXPECT_EQ(min_value, parsed_policy[0].fallback_value);
EXPECT_EQ(min_value, parsed_policy[0].opaque_value);
EXPECT_EQ(0UL, parsed_policy[0].values.size());
@@ -603,52 +457,13 @@ TEST_F(FeaturePolicyParserTest, RedundantBooleanItemsRemoved) {
origin_a_.get(), origin_b_.get(),
&messages, test_feature_name_map);
EXPECT_EQ(1UL, parsed_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, parsed_policy[0].feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen,
+ parsed_policy[0].feature);
EXPECT_EQ(min_value, parsed_policy[0].fallback_value);
EXPECT_EQ(min_value, parsed_policy[0].opaque_value);
EXPECT_EQ(0UL, parsed_policy[0].values.size());
}
-TEST_F(FeaturePolicyParserTest, RedundantDoubleItemsRemoved) {
- Vector<String> messages;
- ParsedFeaturePolicy parsed_policy;
-
- // 'self'(1.5) *(1.5)
- parsed_policy = FeaturePolicyParser::Parse(
- "oversized-images 'self'(1.5) *(1.5)", origin_a_.get(), origin_b_.get(),
- &messages, test_feature_name_map);
- EXPECT_EQ(1UL, parsed_policy.size());
-
- EXPECT_EQ(mojom::FeaturePolicyFeature::kOversizedImages,
- parsed_policy[0].feature);
- EXPECT_EQ(sample_double_value, parsed_policy[0].fallback_value);
- EXPECT_EQ(sample_double_value, parsed_policy[0].opaque_value);
- EXPECT_EQ(0UL, parsed_policy[0].values.size());
-
- // 'self'(inf)
- parsed_policy = FeaturePolicyParser::Parse("oversized-images 'self'(2.0)",
- origin_a_.get(), origin_b_.get(),
- &messages, test_feature_name_map);
- EXPECT_EQ(1UL, parsed_policy.size());
-
- EXPECT_EQ(mojom::FeaturePolicyFeature::kOversizedImages,
- parsed_policy[0].feature);
- EXPECT_EQ(default_double_value, parsed_policy[0].fallback_value);
- EXPECT_EQ(default_double_value, parsed_policy[0].opaque_value);
- EXPECT_EQ(0UL, parsed_policy[0].values.size());
-
- // (inf)
- parsed_policy = FeaturePolicyParser::Parse("oversized-images (2.0)",
- origin_a_.get(), origin_b_.get(),
- &messages, test_feature_name_map);
- EXPECT_EQ(1UL, parsed_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kOversizedImages,
- parsed_policy[0].feature);
- EXPECT_EQ(default_double_value, parsed_policy[0].fallback_value);
- EXPECT_EQ(default_double_value, parsed_policy[0].opaque_value);
- EXPECT_EQ(0UL, parsed_policy[0].values.size());
-}
-
// Test histogram counting the use of feature policies in header.
TEST_F(FeaturePolicyParserTest, HeaderHistogram) {
const char* histogram_name = "Blink.UseCounter.FeaturePolicy.Header";
@@ -660,10 +475,11 @@ TEST_F(FeaturePolicyParserTest, HeaderHistogram) {
tester.ExpectTotalCount(histogram_name, 2);
tester.ExpectBucketCount(
histogram_name,
- static_cast<int>(blink::mojom::FeaturePolicyFeature::kPayment), 1);
+ static_cast<int>(blink::mojom::blink::FeaturePolicyFeature::kPayment), 1);
tester.ExpectBucketCount(
histogram_name,
- static_cast<int>(blink::mojom::FeaturePolicyFeature::kFullscreen), 1);
+ static_cast<int>(blink::mojom::blink::FeaturePolicyFeature::kFullscreen),
+ 1);
}
// Test counting the use of each feature policy only once per header.
@@ -682,10 +498,12 @@ TEST_F(FeaturePolicyParserTest, HistogramMultiple) {
tester.ExpectTotalCount(histogram_name, 3);
tester.ExpectBucketCount(
histogram_name,
- static_cast<int>(blink::mojom::FeaturePolicyFeature::kGeolocation), 1);
+ static_cast<int>(blink::mojom::blink::FeaturePolicyFeature::kGeolocation),
+ 1);
tester.ExpectBucketCount(
histogram_name,
- static_cast<int>(blink::mojom::FeaturePolicyFeature::kFullscreen), 1);
+ static_cast<int>(blink::mojom::blink::FeaturePolicyFeature::kFullscreen),
+ 1);
}
// Test histogram counting the use of feature policies via "allow"
@@ -705,13 +523,15 @@ TEST_F(FeaturePolicyParserTest, AllowHistogramSameDocument) {
tester.ExpectTotalCount(histogram_name, 3);
tester.ExpectBucketCount(
histogram_name,
- static_cast<int>(blink::mojom::FeaturePolicyFeature::kPayment), 1);
+ static_cast<int>(blink::mojom::blink::FeaturePolicyFeature::kPayment), 1);
tester.ExpectBucketCount(
histogram_name,
- static_cast<int>(blink::mojom::FeaturePolicyFeature::kFullscreen), 1);
+ static_cast<int>(blink::mojom::blink::FeaturePolicyFeature::kFullscreen),
+ 1);
tester.ExpectBucketCount(
histogram_name,
- static_cast<int>(blink::mojom::FeaturePolicyFeature::kGeolocation), 1);
+ static_cast<int>(blink::mojom::blink::FeaturePolicyFeature::kGeolocation),
+ 1);
}
// Test histogram counting the use of feature policies via "allow"
@@ -732,109 +552,15 @@ TEST_F(FeaturePolicyParserTest, AllowHistogramDifferentDocument) {
tester.ExpectTotalCount(histogram_name, 4);
tester.ExpectBucketCount(
histogram_name,
- static_cast<int>(blink::mojom::FeaturePolicyFeature::kPayment), 1);
+ static_cast<int>(blink::mojom::blink::FeaturePolicyFeature::kPayment), 1);
tester.ExpectBucketCount(
histogram_name,
- static_cast<int>(blink::mojom::FeaturePolicyFeature::kFullscreen), 2);
+ static_cast<int>(blink::mojom::blink::FeaturePolicyFeature::kFullscreen),
+ 2);
tester.ExpectBucketCount(
histogram_name,
- static_cast<int>(blink::mojom::FeaturePolicyFeature::kGeolocation), 1);
-}
-
-TEST_F(FeaturePolicyParserTest, ParseParameterizedFeatures) {
- Vector<String> messages;
-
- scoped_refptr<SecurityOrigin> opaque_origin =
- SecurityOrigin::CreateUniqueOpaque();
-
- // Simple policy with *.
- ParsedFeaturePolicy parsed_policy = FeaturePolicyParser::Parse(
- "oversized-images *", origin_a_.get(), opaque_origin.get(), &messages,
- test_feature_name_map);
- EXPECT_EQ(1UL, parsed_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kOversizedImages,
- parsed_policy[0].feature);
- EXPECT_EQ(max_double_value, parsed_policy[0].fallback_value);
- EXPECT_EQ(max_double_value, parsed_policy[0].opaque_value);
- EXPECT_EQ(0UL, parsed_policy[0].values.size());
-
- // Policy with explicit origins
- parsed_policy = FeaturePolicyParser::Parse(
- "oversized-images https://example.net 'src'", origin_a_.get(),
- opaque_origin.get(), &messages, test_feature_name_map);
- EXPECT_EQ(1UL, parsed_policy.size());
-
- EXPECT_EQ(mojom::FeaturePolicyFeature::kOversizedImages,
- parsed_policy[0].feature);
- EXPECT_GE(default_double_value, parsed_policy[0].fallback_value);
- EXPECT_LE(max_double_value, parsed_policy[0].opaque_value);
- EXPECT_EQ(1UL, parsed_policy[0].values.size());
- EXPECT_LE(max_double_value, parsed_policy[0].values.begin()->second);
-}
-
-// These declarations should each trigger the Unoptimized Images origin trial
-// use counter.
-const char* const kUnoptimizedImagesOriginTrialPolicyDeclarations[] = {
- "unoptimized-lossy-images", "unoptimized-lossless-images",
- "unoptimized-lossless-images-strict", "oversized-images",
- "oversized-images; fullscreen", "fullscreen; oversized-images",
- "oversized-images 'self'(2.0)", "oversized-images 'none'",
- "unoptimized-lossy-images *(0.125)"};
-
-TEST_F(FeaturePolicyParserTest, UnoptimizedImagesOriginTrialFeatureUseCounter) {
- Vector<String> messages;
-
- // Validate that features which are not in the origin trial do not trigger
- // the use counter.
- {
- auto dummy = std::make_unique<DummyPageHolder>();
- FeaturePolicyParser::ParseHeader("payment; fullscreen", origin_a_.get(),
- &messages, &dummy->GetDocument());
- EXPECT_FALSE(dummy->GetDocument().IsUseCounted(
- WebFeature::kUnoptimizedImagePolicies));
- }
-
- // Validate that declarations which should trigger the use counter do.
- for (const char* declaration :
- kUnoptimizedImagesOriginTrialPolicyDeclarations) {
- auto dummy = std::make_unique<DummyPageHolder>();
- FeaturePolicyParser::ParseHeader(declaration, origin_a_.get(), &messages,
- &dummy->GetDocument());
- EXPECT_TRUE(dummy->GetDocument().IsUseCounted(
- WebFeature::kUnoptimizedImagePolicies))
- << declaration
- << " should trigger the Unoptimized Images origin trial use counter.";
- }
-}
-
-// These declarations should each trigger the Unsized Media origin trial use
-// counter.
-const char* const kUnsizedMediaOriginTrialPolicyDeclarations[] = {
- "unsized-media", "unsized-media; fullscreen", "fullscreen; unsized-media",
- "unsized-media 'self'", "unsized-media 'none'"};
-
-TEST_F(FeaturePolicyParserTest, UnsizedMediaOriginTrialFeatureUseCounter) {
- Vector<String> messages;
-
- // Validate that features which are not in the origin trial do not trigger
- // the use counter.
- {
- auto dummy = std::make_unique<DummyPageHolder>();
- FeaturePolicyParser::ParseHeader("payment; fullscreen", origin_a_.get(),
- &messages, &dummy->GetDocument());
- EXPECT_FALSE(
- dummy->GetDocument().IsUseCounted(WebFeature::kUnsizedMediaPolicy));
- }
-
- // Validate that declarations which should trigger the use counter do.
- for (const char* declaration : kUnsizedMediaOriginTrialPolicyDeclarations) {
- auto dummy = std::make_unique<DummyPageHolder>();
- FeaturePolicyParser::ParseHeader(declaration, origin_a_.get(), &messages,
- &dummy->GetDocument());
- EXPECT_TRUE(
- dummy->GetDocument().IsUseCounted(WebFeature::kUnsizedMediaPolicy))
- << declaration << " should trigger the origin trial use counter.";
- }
+ static_cast<int>(blink::mojom::blink::FeaturePolicyFeature::kGeolocation),
+ 1);
}
// Tests the use counter for comma separator in declarations.
@@ -1074,26 +800,6 @@ TEST_F(FeaturePolicyAllowlistHistogramTest, SrcInAttributeHistogram) {
tester.ExpectTotalCount(kAllowlistAttributeHistogram, 1);
}
-TEST_F(FeaturePolicyAllowlistHistogramTest, OriginTrialFeaturesNotRecorded) {
- Vector<String> messages;
- HistogramTester tester;
-
- auto dummy = std::make_unique<DummyPageHolder>();
- const char* unoptimizedimages_declaration =
- "unoptimized-lossy-images;"
- "unoptimized-lossless-images;"
- "unoptimized-lossless-images-strict;"
- "oversized-images *;";
- const char* unsizedmedia_declaration = "unsized-media *";
- FeaturePolicyParser::ParseHeader(unoptimizedimages_declaration,
- origin_a_.get(), &messages,
- &dummy->GetDocument());
- FeaturePolicyParser::ParseHeader(unsizedmedia_declaration, origin_a_.get(),
- &messages, &dummy->GetDocument());
-
- tester.ExpectTotalCount(kAllowlistHeaderHistogram, 0);
-}
-
// Test policy mutation methods
class FeaturePolicyMutationTest : public testing::Test {
protected:
@@ -1107,7 +813,7 @@ class FeaturePolicyMutationTest : public testing::Test {
// Returns true if the policy contains a declaration for the feature which
// allows it in all origins.
- bool IsFeatureAllowedEverywhere(mojom::FeaturePolicyFeature feature,
+ bool IsFeatureAllowedEverywhere(mojom::blink::FeaturePolicyFeature feature,
const ParsedFeaturePolicy& policy) {
const auto& result = std::find_if(policy.begin(), policy.end(),
[feature](const auto& declaration) {
@@ -1118,12 +824,11 @@ class FeaturePolicyMutationTest : public testing::Test {
return result->feature == feature && result->fallback_value >= max_value &&
result->opaque_value >= max_value && result->values.empty();
- return true;
}
// Returns true if the policy contains a declaration for the feature which
// disallows it in all origins.
- bool IsFeatureDisallowedEverywhere(mojom::FeaturePolicyFeature feature,
+ bool IsFeatureDisallowedEverywhere(mojom::blink::FeaturePolicyFeature feature,
const ParsedFeaturePolicy& policy) {
const auto& result = std::find_if(policy.begin(), policy.end(),
[feature](const auto& declaration) {
@@ -1134,7 +839,6 @@ class FeaturePolicyMutationTest : public testing::Test {
return result->feature == feature && result->fallback_value <= min_value &&
result->opaque_value <= min_value && result->values.empty();
- return true;
}
const PolicyValue min_value = PolicyValue(false);
@@ -1145,11 +849,11 @@ class FeaturePolicyMutationTest : public testing::Test {
PolicyValue::CreateMaxPolicyValue(mojom::PolicyValueType::kDecDouble);
ParsedFeaturePolicy test_policy = {
- {mojom::FeaturePolicyFeature::kFullscreen,
+ {mojom::blink::FeaturePolicyFeature::kFullscreen,
std::map<url::Origin, PolicyValue>{{url_origin_a_, PolicyValue(true)},
{url_origin_b_, PolicyValue(true)}},
PolicyValue(false), PolicyValue(false)},
- {mojom::FeaturePolicyFeature::kGeolocation,
+ {mojom::blink::FeaturePolicyFeature::kGeolocation,
std::map<url::Origin, PolicyValue>{{url_origin_a_, PolicyValue(true)}},
PolicyValue(false), PolicyValue(false)}};
@@ -1157,160 +861,162 @@ class FeaturePolicyMutationTest : public testing::Test {
};
TEST_F(FeaturePolicyMutationTest, TestIsFeatureDeclared) {
- EXPECT_TRUE(
- IsFeatureDeclared(mojom::FeaturePolicyFeature::kFullscreen, test_policy));
- EXPECT_TRUE(IsFeatureDeclared(mojom::FeaturePolicyFeature::kGeolocation,
+ EXPECT_TRUE(IsFeatureDeclared(mojom::blink::FeaturePolicyFeature::kFullscreen,
test_policy));
+ EXPECT_TRUE(IsFeatureDeclared(
+ mojom::blink::FeaturePolicyFeature::kGeolocation, test_policy));
EXPECT_FALSE(
- IsFeatureDeclared(mojom::FeaturePolicyFeature::kUsb, test_policy));
- EXPECT_FALSE(
- IsFeatureDeclared(mojom::FeaturePolicyFeature::kNotFound, test_policy));
+ IsFeatureDeclared(mojom::blink::FeaturePolicyFeature::kUsb, test_policy));
+ EXPECT_FALSE(IsFeatureDeclared(mojom::blink::FeaturePolicyFeature::kNotFound,
+ test_policy));
}
TEST_F(FeaturePolicyMutationTest, TestIsFeatureDeclaredWithEmptyPolicy) {
- EXPECT_FALSE(IsFeatureDeclared(mojom::FeaturePolicyFeature::kFullscreen,
+ EXPECT_FALSE(IsFeatureDeclared(
+ mojom::blink::FeaturePolicyFeature::kFullscreen, empty_policy));
+ EXPECT_FALSE(IsFeatureDeclared(mojom::blink::FeaturePolicyFeature::kNotFound,
empty_policy));
- EXPECT_FALSE(
- IsFeatureDeclared(mojom::FeaturePolicyFeature::kNotFound, empty_policy));
}
TEST_F(FeaturePolicyMutationTest, TestRemoveAbsentFeature) {
ASSERT_EQ(2UL, test_policy.size());
- EXPECT_FALSE(
- IsFeatureDeclared(mojom::FeaturePolicyFeature::kPayment, test_policy));
- EXPECT_FALSE(RemoveFeatureIfPresent(mojom::FeaturePolicyFeature::kPayment,
- test_policy));
+ EXPECT_FALSE(IsFeatureDeclared(mojom::blink::FeaturePolicyFeature::kPayment,
+ test_policy));
+ EXPECT_FALSE(RemoveFeatureIfPresent(
+ mojom::blink::FeaturePolicyFeature::kPayment, test_policy));
ASSERT_EQ(2UL, test_policy.size());
- EXPECT_FALSE(
- IsFeatureDeclared(mojom::FeaturePolicyFeature::kPayment, test_policy));
+ EXPECT_FALSE(IsFeatureDeclared(mojom::blink::FeaturePolicyFeature::kPayment,
+ test_policy));
}
TEST_F(FeaturePolicyMutationTest, TestRemoveFromEmptyPolicy) {
ASSERT_EQ(0UL, empty_policy.size());
- EXPECT_FALSE(RemoveFeatureIfPresent(mojom::FeaturePolicyFeature::kPayment,
- test_policy));
+ EXPECT_FALSE(RemoveFeatureIfPresent(
+ mojom::blink::FeaturePolicyFeature::kPayment, test_policy));
ASSERT_EQ(0UL, empty_policy.size());
}
TEST_F(FeaturePolicyMutationTest, TestRemoveFeatureIfPresent) {
ASSERT_EQ(2UL, test_policy.size());
- EXPECT_TRUE(
- IsFeatureDeclared(mojom::FeaturePolicyFeature::kFullscreen, test_policy));
- EXPECT_TRUE(RemoveFeatureIfPresent(mojom::FeaturePolicyFeature::kFullscreen,
- test_policy));
+ EXPECT_TRUE(IsFeatureDeclared(mojom::blink::FeaturePolicyFeature::kFullscreen,
+ test_policy));
+ EXPECT_TRUE(RemoveFeatureIfPresent(
+ mojom::blink::FeaturePolicyFeature::kFullscreen, test_policy));
EXPECT_EQ(1UL, test_policy.size());
- EXPECT_FALSE(
- IsFeatureDeclared(mojom::FeaturePolicyFeature::kFullscreen, test_policy));
+ EXPECT_FALSE(IsFeatureDeclared(
+ mojom::blink::FeaturePolicyFeature::kFullscreen, test_policy));
// Attempt to remove the feature again
- EXPECT_FALSE(RemoveFeatureIfPresent(mojom::FeaturePolicyFeature::kFullscreen,
- test_policy));
+ EXPECT_FALSE(RemoveFeatureIfPresent(
+ mojom::blink::FeaturePolicyFeature::kFullscreen, test_policy));
EXPECT_EQ(1UL, test_policy.size());
- EXPECT_FALSE(
- IsFeatureDeclared(mojom::FeaturePolicyFeature::kFullscreen, test_policy));
+ EXPECT_FALSE(IsFeatureDeclared(
+ mojom::blink::FeaturePolicyFeature::kFullscreen, test_policy));
}
TEST_F(FeaturePolicyMutationTest, TestRemoveFeatureIfPresentOnSecondFeature) {
ASSERT_EQ(2UL, test_policy.size());
- EXPECT_TRUE(IsFeatureDeclared(mojom::FeaturePolicyFeature::kGeolocation,
- test_policy));
- EXPECT_TRUE(RemoveFeatureIfPresent(mojom::FeaturePolicyFeature::kGeolocation,
- test_policy));
+ EXPECT_TRUE(IsFeatureDeclared(
+ mojom::blink::FeaturePolicyFeature::kGeolocation, test_policy));
+ EXPECT_TRUE(RemoveFeatureIfPresent(
+ mojom::blink::FeaturePolicyFeature::kGeolocation, test_policy));
ASSERT_EQ(1UL, test_policy.size());
- EXPECT_FALSE(IsFeatureDeclared(mojom::FeaturePolicyFeature::kGeolocation,
- test_policy));
+ EXPECT_FALSE(IsFeatureDeclared(
+ mojom::blink::FeaturePolicyFeature::kGeolocation, test_policy));
// Attempt to remove the feature again
- EXPECT_FALSE(RemoveFeatureIfPresent(mojom::FeaturePolicyFeature::kGeolocation,
- test_policy));
+ EXPECT_FALSE(RemoveFeatureIfPresent(
+ mojom::blink::FeaturePolicyFeature::kGeolocation, test_policy));
EXPECT_EQ(1UL, test_policy.size());
- EXPECT_FALSE(IsFeatureDeclared(mojom::FeaturePolicyFeature::kGeolocation,
- test_policy));
+ EXPECT_FALSE(IsFeatureDeclared(
+ mojom::blink::FeaturePolicyFeature::kGeolocation, test_policy));
}
TEST_F(FeaturePolicyMutationTest, TestRemoveAllFeatures) {
ASSERT_EQ(2UL, test_policy.size());
- EXPECT_TRUE(RemoveFeatureIfPresent(mojom::FeaturePolicyFeature::kFullscreen,
- test_policy));
- EXPECT_TRUE(RemoveFeatureIfPresent(mojom::FeaturePolicyFeature::kGeolocation,
- test_policy));
+ EXPECT_TRUE(RemoveFeatureIfPresent(
+ mojom::blink::FeaturePolicyFeature::kFullscreen, test_policy));
+ EXPECT_TRUE(RemoveFeatureIfPresent(
+ mojom::blink::FeaturePolicyFeature::kGeolocation, test_policy));
EXPECT_EQ(0UL, test_policy.size());
- EXPECT_FALSE(
- IsFeatureDeclared(mojom::FeaturePolicyFeature::kFullscreen, test_policy));
- EXPECT_FALSE(IsFeatureDeclared(mojom::FeaturePolicyFeature::kGeolocation,
- test_policy));
+ EXPECT_FALSE(IsFeatureDeclared(
+ mojom::blink::FeaturePolicyFeature::kFullscreen, test_policy));
+ EXPECT_FALSE(IsFeatureDeclared(
+ mojom::blink::FeaturePolicyFeature::kGeolocation, test_policy));
}
TEST_F(FeaturePolicyMutationTest, TestDisallowIfNotPresent) {
ParsedFeaturePolicy copy = test_policy;
// Try to disallow a feature which already exists
EXPECT_FALSE(DisallowFeatureIfNotPresent(
- mojom::FeaturePolicyFeature::kFullscreen, copy));
+ mojom::blink::FeaturePolicyFeature::kFullscreen, copy));
ASSERT_EQ(copy, test_policy);
// Disallow a new feature
- EXPECT_TRUE(
- DisallowFeatureIfNotPresent(mojom::FeaturePolicyFeature::kPayment, copy));
+ EXPECT_TRUE(DisallowFeatureIfNotPresent(
+ mojom::blink::FeaturePolicyFeature::kPayment, copy));
EXPECT_EQ(3UL, copy.size());
// Verify that the feature is, in fact, now disallowed everywhere
EXPECT_TRUE(IsFeatureDisallowedEverywhere(
- mojom::FeaturePolicyFeature::kPayment, copy));
+ mojom::blink::FeaturePolicyFeature::kPayment, copy));
}
TEST_F(FeaturePolicyMutationTest, TestAllowEverywhereIfNotPresent) {
ParsedFeaturePolicy copy = test_policy;
// Try to allow a feature which already exists
EXPECT_FALSE(AllowFeatureEverywhereIfNotPresent(
- mojom::FeaturePolicyFeature::kFullscreen, copy));
+ mojom::blink::FeaturePolicyFeature::kFullscreen, copy));
ASSERT_EQ(copy, test_policy);
// Allow a new feature
EXPECT_TRUE(AllowFeatureEverywhereIfNotPresent(
- mojom::FeaturePolicyFeature::kPayment, copy));
+ mojom::blink::FeaturePolicyFeature::kPayment, copy));
EXPECT_EQ(3UL, copy.size());
// Verify that the feature is, in fact, allowed everywhere
- EXPECT_TRUE(
- IsFeatureAllowedEverywhere(mojom::FeaturePolicyFeature::kPayment, copy));
+ EXPECT_TRUE(IsFeatureAllowedEverywhere(
+ mojom::blink::FeaturePolicyFeature::kPayment, copy));
}
TEST_F(FeaturePolicyMutationTest, TestDisallowUnconditionally) {
// Try to disallow a feature which already exists
- DisallowFeature(mojom::FeaturePolicyFeature::kFullscreen, test_policy);
+ DisallowFeature(mojom::blink::FeaturePolicyFeature::kFullscreen, test_policy);
// Should not have changed the number of declarations
EXPECT_EQ(2UL, test_policy.size());
// Verify that the feature is, in fact, now disallowed everywhere
EXPECT_TRUE(IsFeatureDisallowedEverywhere(
- mojom::FeaturePolicyFeature::kFullscreen, test_policy));
+ mojom::blink::FeaturePolicyFeature::kFullscreen, test_policy));
}
TEST_F(FeaturePolicyMutationTest, TestDisallowNewFeatureUnconditionally) {
// Try to disallow a feature which does not yet exist
- DisallowFeature(mojom::FeaturePolicyFeature::kPayment, test_policy);
+ DisallowFeature(mojom::blink::FeaturePolicyFeature::kPayment, test_policy);
// Should have added a new declaration
EXPECT_EQ(3UL, test_policy.size());
// Verify that the feature is, in fact, now disallowed everywhere
EXPECT_TRUE(IsFeatureDisallowedEverywhere(
- mojom::FeaturePolicyFeature::kPayment, test_policy));
+ mojom::blink::FeaturePolicyFeature::kPayment, test_policy));
}
TEST_F(FeaturePolicyMutationTest, TestAllowUnconditionally) {
// Try to allow a feature which already exists
- AllowFeatureEverywhere(mojom::FeaturePolicyFeature::kFullscreen, test_policy);
+ AllowFeatureEverywhere(mojom::blink::FeaturePolicyFeature::kFullscreen,
+ test_policy);
// Should not have changed the number of declarations
EXPECT_EQ(2UL, test_policy.size());
// Verify that the feature is, in fact, now allowed everywhere
EXPECT_TRUE(IsFeatureAllowedEverywhere(
- mojom::FeaturePolicyFeature::kFullscreen, test_policy));
+ mojom::blink::FeaturePolicyFeature::kFullscreen, test_policy));
}
TEST_F(FeaturePolicyMutationTest, TestAllowNewFeatureUnconditionally) {
// Try to allow a feature which does not yet exist
- AllowFeatureEverywhere(mojom::FeaturePolicyFeature::kPayment, test_policy);
+ AllowFeatureEverywhere(mojom::blink::FeaturePolicyFeature::kPayment,
+ test_policy);
// Should have added a new declaration
EXPECT_EQ(3UL, test_policy.size());
// Verify that the feature is, in fact, now allowed everywhere
- EXPECT_TRUE(IsFeatureAllowedEverywhere(mojom::FeaturePolicyFeature::kPayment,
- test_policy));
+ EXPECT_TRUE(IsFeatureAllowedEverywhere(
+ mojom::blink::FeaturePolicyFeature::kPayment, test_policy));
}
class FeaturePolicyViolationHistogramTest : public testing::Test {
@@ -1330,21 +1036,23 @@ TEST_F(FeaturePolicyViolationHistogramTest, PotentialViolation) {
auto dummy_page_holder_ = std::make_unique<DummyPageHolder>();
// Probing feature state should not count.
dummy_page_holder_->GetDocument().IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kPayment);
+ 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(
- mojom::FeaturePolicyFeature::kPayment, ReportOptions::kReportOnFailure);
+ 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(
- mojom::FeaturePolicyFeature::kPayment, ReportOptions::kReportOnFailure);
+ 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(
- mojom::FeaturePolicyFeature::kFullscreen,
+ 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 c6adca5e826..4ee1e44fe22 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
@@ -34,11 +34,11 @@ class IFramePolicy final : public DOMFeaturePolicy {
const ParsedFeaturePolicy& container_policy,
scoped_refptr<const SecurityOrigin> src_origin) override {
policy_ = FeaturePolicy::CreateFromParentPolicy(
- parent_document_->GetFeaturePolicy(), container_policy,
- src_origin->ToUrlOrigin());
+ parent_document_->GetSecurityContext().GetFeaturePolicy(),
+ container_policy, src_origin->ToUrlOrigin());
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(parent_document_);
DOMFeaturePolicy::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/layout_animations_policy.cc b/chromium/third_party/blink/renderer/core/feature_policy/layout_animations_policy.cc
index d6740e81f01..3f2fc6a7cc0 100644
--- a/chromium/third_party/blink/renderer/core/feature_policy/layout_animations_policy.cc
+++ b/chromium/third_party/blink/renderer/core/feature_policy/layout_animations_policy.cc
@@ -6,7 +6,7 @@
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
#include "third_party/blink/renderer/core/css/properties/css_property.h"
-#include "third_party/blink/renderer/core/execution_context/security_context.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/feature_policy/feature_policy_parser.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
@@ -17,7 +17,7 @@ String GetViolationMessage(const CSSProperty& property) {
"Feature policy violation: CSS property '%s' violates feature policy "
"'%s' which is disabled in this document",
property.GetPropertyNameString().Utf8().c_str(),
- GetNameForFeature(mojom::FeaturePolicyFeature::kLayoutAnimations)
+ GetNameForFeature(mojom::blink::FeaturePolicyFeature::kLayoutAnimations)
.Utf8()
.c_str());
}
@@ -38,20 +38,11 @@ LayoutAnimationsPolicy::AffectedCSSProperties() {
// static
void LayoutAnimationsPolicy::ReportViolation(
const CSSProperty& animated_property,
- const SecurityContext& security_context) {
+ const ExecutionContext& context) {
DCHECK(AffectedCSSProperties().Contains(&animated_property));
- auto state = security_context.GetFeatureEnabledState(
- mojom::FeaturePolicyFeature::kLayoutAnimations);
- security_context.CountPotentialFeaturePolicyViolation(
- mojom::FeaturePolicyFeature::kLayoutAnimations);
- if (state == FeatureEnabledState::kEnabled)
- return;
- security_context.ReportFeaturePolicyViolation(
- mojom::FeaturePolicyFeature::kLayoutAnimations,
- state == FeatureEnabledState::kReportOnly
- ? mojom::FeaturePolicyDisposition::kReport
- : mojom::FeaturePolicyDisposition::kEnforce,
- GetViolationMessage(animated_property));
+ context.IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kLayoutAnimations,
+ ReportOptions::kReportOnFailure, GetViolationMessage(animated_property));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/feature_policy/layout_animations_policy.h b/chromium/third_party/blink/renderer/core/feature_policy/layout_animations_policy.h
index d2d5bced360..f82862c0376 100644
--- a/chromium/third_party/blink/renderer/core/feature_policy/layout_animations_policy.h
+++ b/chromium/third_party/blink/renderer/core/feature_policy/layout_animations_policy.h
@@ -12,7 +12,7 @@
namespace blink {
class CSSProperty;
-class SecurityContext;
+class ExecutionContext;
// Helper methods for for 'layout-animations' (kLayoutAnimations) feature
// policy.
@@ -25,11 +25,11 @@ class LayoutAnimationsPolicy {
static const HashSet<const CSSProperty*>& AffectedCSSProperties();
// Generates a violation report for the blocked |animation_property| only if
- // the feature 'layout-animations' is disabled in |security_context|. Invoking
+ // the feature 'layout-animations' is disabled in |document|. Invoking
// this method emits a potential violation of the 'layout-animations' policy
// which is tracked by Blink.UserCounters.FeaturePolicy.PotentialViolation.
static void ReportViolation(const CSSProperty& animated_property,
- const SecurityContext& security_context);
+ const ExecutionContext& context);
private:
LayoutAnimationsPolicy();
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 26b725dbec5..0630be0a044 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
@@ -8,8 +8,8 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.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/feature_policy/feature_policy_parser.h"
+#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
namespace blink {
@@ -25,18 +25,27 @@ using testing::UnorderedElementsAre;
class PolicyTest : public testing::Test {
public:
void SetUp() override {
- DocumentInit init =
- DocumentInit::Create()
- .WithOriginToCommit(SecurityOrigin::CreateFromString(kSelfOrigin))
- .WithFeaturePolicyHeader(
- "fullscreen *; payment 'self'; midi 'none'; camera 'self' "
- "https://example.com https://example.net");
- document_ = MakeGarbageCollected<Document>(init);
+ 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);
+ feature_policy->SetHeaderPolicy(header);
+
+ auto& security_context = page_holder_->GetDocument().GetSecurityContext();
+ security_context.SetSecurityOriginForTesting(origin);
+ security_context.SetFeaturePolicy(std::move(feature_policy));
}
DOMFeaturePolicy* GetPolicy() const { return policy_; }
protected:
+ std::unique_ptr<DummyPageHolder> page_holder_;
Persistent<Document> document_;
Persistent<DOMFeaturePolicy> policy_;
};
@@ -45,7 +54,8 @@ class DOMDocumentPolicyTest : public PolicyTest {
public:
void SetUp() override {
PolicyTest::SetUp();
- policy_ = MakeGarbageCollected<DOMDocumentPolicy>(document_);
+ policy_ =
+ MakeGarbageCollected<DOMDocumentPolicy>(&page_holder_->GetDocument());
}
};
@@ -54,7 +64,7 @@ class IFramePolicyTest : public PolicyTest {
void SetUp() override {
PolicyTest::SetUp();
policy_ = MakeGarbageCollected<IFramePolicy>(
- document_, ParsedFeaturePolicy(),
+ &page_holder_->GetDocument(), ParsedFeaturePolicy(),
SecurityOrigin::CreateFromString(kSelfOrigin));
}
};
diff --git a/chromium/third_party/blink/renderer/core/fetch/BUILD.gn b/chromium/third_party/blink/renderer/core/fetch/BUILD.gn
index c1716b2723f..c48584c91e3 100644
--- a/chromium/third_party/blink/renderer/core/fetch/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/fetch/BUILD.gn
@@ -40,6 +40,8 @@ blink_core_sources("fetch") {
"request.h",
"response.cc",
"response.h",
+ "trust_token_to_mojom.cc",
+ "trust_token_to_mojom.h",
]
if (is_win && is_component_build) {
@@ -50,7 +52,5 @@ blink_core_sources("fetch") {
jumbo_excluded_sources = [ "body.cc" ]
}
- public_deps = [
- "//third_party/blink/renderer/platform",
- ]
+ public_deps = [ "//third_party/blink/renderer/platform" ]
}
diff --git a/chromium/third_party/blink/renderer/core/fetch/DEPS b/chromium/third_party/blink/renderer/core/fetch/DEPS
index d2ac7738a1e..628e2fdb106 100644
--- a/chromium/third_party/blink/renderer/core/fetch/DEPS
+++ b/chromium/third_party/blink/renderer/core/fetch/DEPS
@@ -1,10 +1,9 @@
include_rules = [
"+gin/public",
- "+mojo/public/cpp/bindings/binding_set.h",
"+mojo/public/cpp/system/data_pipe.h",
"+mojo/public/cpp/system/data_pipe_utils.h",
"+mojo/public/cpp/system/simple_watcher.h",
"+net/base/request_priority.h",
- "+services/network/public/cpp/content_security_policy.h",
+ "+services/network/public/cpp/content_security_policy/content_security_policy.h",
"+url/gurl.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 f5d551137b1..148926a43aa 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(blink::Visitor* visitor) {
+void BlobBytesConsumer::Trace(Visitor* visitor) {
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 98b967fdd3d..4cc789a8858 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<ExecutionContext> execution_context_;
diff --git a/chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer_test.cc b/chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer_test.cc
index f1b1b1f5c08..6c7c84392ba 100644
--- a/chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer_test.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/blob_bytes_consumer_test.cc
@@ -8,6 +8,7 @@
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/fetch/bytes_consumer_test_util.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/loader/threadable_loader.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/platform/blob/blob_data.h"
@@ -66,8 +67,8 @@ TEST_F(BlobBytesConsumerTest, TwoPhaseRead) {
String body = "hello, world";
scoped_refptr<BlobDataHandle> blob_data_handle = CreateBlob(body);
- BlobBytesConsumer* consumer =
- MakeGarbageCollected<BlobBytesConsumer>(&GetDocument(), blob_data_handle);
+ BlobBytesConsumer* consumer = MakeGarbageCollected<BlobBytesConsumer>(
+ GetFrame().DomWindow(), blob_data_handle);
EXPECT_EQ(PublicState::kReadableOrWaiting, consumer->GetPublicState());
EXPECT_FALSE(DidStartLoading());
@@ -90,8 +91,8 @@ TEST_F(BlobBytesConsumerTest, TwoPhaseRead) {
TEST_F(BlobBytesConsumerTest, CancelBeforeStarting) {
scoped_refptr<BlobDataHandle> blob_data_handle = CreateBlob("foo bar");
- BlobBytesConsumer* consumer =
- MakeGarbageCollected<BlobBytesConsumer>(&GetDocument(), blob_data_handle);
+ BlobBytesConsumer* consumer = MakeGarbageCollected<BlobBytesConsumer>(
+ GetFrame().DomWindow(), blob_data_handle);
BlobBytesConsumerTestClient* client =
MakeGarbageCollected<BlobBytesConsumerTestClient>();
consumer->SetClient(client);
@@ -108,8 +109,8 @@ TEST_F(BlobBytesConsumerTest, CancelBeforeStarting) {
TEST_F(BlobBytesConsumerTest, CancelAfterStarting) {
scoped_refptr<BlobDataHandle> blob_data_handle = CreateBlob("foo bar");
- BlobBytesConsumer* consumer =
- MakeGarbageCollected<BlobBytesConsumer>(&GetDocument(), blob_data_handle);
+ BlobBytesConsumer* consumer = MakeGarbageCollected<BlobBytesConsumer>(
+ GetFrame().DomWindow(), blob_data_handle);
BlobBytesConsumerTestClient* client =
MakeGarbageCollected<BlobBytesConsumerTestClient>();
consumer->SetClient(client);
@@ -130,8 +131,8 @@ TEST_F(BlobBytesConsumerTest, CancelAfterStarting) {
TEST_F(BlobBytesConsumerTest, DrainAsBlobDataHandle) {
String body = "hello, world";
scoped_refptr<BlobDataHandle> blob_data_handle = CreateBlob(body);
- BlobBytesConsumer* consumer =
- MakeGarbageCollected<BlobBytesConsumer>(&GetDocument(), blob_data_handle);
+ BlobBytesConsumer* consumer = MakeGarbageCollected<BlobBytesConsumer>(
+ GetFrame().DomWindow(), blob_data_handle);
EXPECT_EQ(PublicState::kReadableOrWaiting, consumer->GetPublicState());
EXPECT_FALSE(DidStartLoading());
@@ -150,8 +151,8 @@ TEST_F(BlobBytesConsumerTest, DrainAsBlobDataHandle_2) {
scoped_refptr<BlobDataHandle> blob_data_handle =
BlobDataHandle::Create("uuid", "", std::numeric_limits<uint64_t>::max(),
CreateBlob("foo bar")->CloneBlobRemote());
- BlobBytesConsumer* consumer =
- MakeGarbageCollected<BlobBytesConsumer>(&GetDocument(), blob_data_handle);
+ BlobBytesConsumer* consumer = MakeGarbageCollected<BlobBytesConsumer>(
+ GetFrame().DomWindow(), blob_data_handle);
EXPECT_EQ(PublicState::kReadableOrWaiting, consumer->GetPublicState());
EXPECT_FALSE(DidStartLoading());
@@ -170,8 +171,8 @@ TEST_F(BlobBytesConsumerTest, DrainAsBlobDataHandle_3) {
scoped_refptr<BlobDataHandle> blob_data_handle =
BlobDataHandle::Create("uuid", "", std::numeric_limits<uint64_t>::max(),
CreateBlob("foo bar")->CloneBlobRemote());
- BlobBytesConsumer* consumer =
- MakeGarbageCollected<BlobBytesConsumer>(&GetDocument(), blob_data_handle);
+ BlobBytesConsumer* consumer = MakeGarbageCollected<BlobBytesConsumer>(
+ GetFrame().DomWindow(), blob_data_handle);
EXPECT_EQ(PublicState::kReadableOrWaiting, consumer->GetPublicState());
EXPECT_FALSE(DidStartLoading());
@@ -185,8 +186,8 @@ TEST_F(BlobBytesConsumerTest, DrainAsBlobDataHandle_3) {
TEST_F(BlobBytesConsumerTest, DrainAsFormData) {
String body = "hello, world";
scoped_refptr<BlobDataHandle> blob_data_handle = CreateBlob(body);
- BlobBytesConsumer* consumer =
- MakeGarbageCollected<BlobBytesConsumer>(&GetDocument(), blob_data_handle);
+ BlobBytesConsumer* consumer = MakeGarbageCollected<BlobBytesConsumer>(
+ GetFrame().DomWindow(), blob_data_handle);
EXPECT_EQ(PublicState::kReadableOrWaiting, consumer->GetPublicState());
EXPECT_FALSE(DidStartLoading());
@@ -205,7 +206,7 @@ TEST_F(BlobBytesConsumerTest, DrainAsFormData) {
TEST_F(BlobBytesConsumerTest, ConstructedFromNullHandle) {
BlobBytesConsumer* consumer =
- MakeGarbageCollected<BlobBytesConsumer>(&GetDocument(), nullptr);
+ MakeGarbageCollected<BlobBytesConsumer>(GetFrame().DomWindow(), nullptr);
const char* buffer = nullptr;
size_t available;
EXPECT_EQ(BytesConsumer::PublicState::kClosed, consumer->GetPublicState());
diff --git a/chromium/third_party/blink/renderer/core/fetch/body.cc b/chromium/third_party/blink/renderer/core/fetch/body.cc
index 5653e7d7833..437db5482c5 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(resolver_);
FetchDataLoader::Client::Trace(visitor);
}
@@ -351,12 +351,13 @@ ScriptPromise Body::text(ScriptState* script_state,
}
ReadableStream* Body::body() {
- auto* execution_context = GetExecutionContext();
- if (execution_context->IsServiceWorkerGlobalScope()) {
- execution_context->CountUse(WebFeature::kFetchBodyStreamInServiceWorker);
- } else {
- execution_context->CountUse(
- WebFeature::kFetchBodyStreamOutsideServiceWorker);
+ if (auto* execution_context = GetExecutionContext()) {
+ if (execution_context->IsServiceWorkerGlobalScope()) {
+ execution_context->CountUse(WebFeature::kFetchBodyStreamInServiceWorker);
+ } else {
+ execution_context->CountUse(
+ WebFeature::kFetchBodyStreamOutsideServiceWorker);
+ }
}
if (!BodyBuffer())
@@ -399,7 +400,7 @@ bool Body::IsBodyUsedForDCheck(ExceptionState& exception_state) {
BodyBuffer()->IsStreamDisturbedForDCheck(exception_state);
}
-Body::Body(ExecutionContext* context) : ContextClient(context) {}
+Body::Body(ExecutionContext* context) : ExecutionContextClient(context) {}
void Body::RejectInvalidConsumption(ScriptState* script_state,
ExceptionState& exception_state) {
diff --git a/chromium/third_party/blink/renderer/core/fetch/body.h b/chromium/third_party/blink/renderer/core/fetch/body.h
index 48c6e4ef8a8..f238092dfbf 100644
--- a/chromium/third_party/blink/renderer/core/fetch/body.h
+++ b/chromium/third_party/blink/renderer/core/fetch/body.h
@@ -9,7 +9,7 @@
#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"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/wtf/text/wtf_string.h"
@@ -31,7 +31,7 @@ class ScriptState;
// implementation.
class CORE_EXPORT Body : public ScriptWrappable,
public ActiveScriptWrappable<Body>,
- public ContextClient {
+ public ExecutionContextClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(Body);
@@ -67,9 +67,9 @@ class CORE_EXPORT Body : public ScriptWrappable,
// ScriptWrappable override.
bool HasPendingActivity() const override;
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
ScriptWrappable::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
protected:
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 40c391e120b..815ad1d51fd 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
@@ -29,7 +29,7 @@ namespace blink {
class BodyStreamBuffer::LoaderClient final
: public GarbageCollected<LoaderClient>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public FetchDataLoader::Client {
USING_GARBAGE_COLLECTED_MIXIN(LoaderClient);
@@ -37,7 +37,7 @@ class BodyStreamBuffer::LoaderClient final
LoaderClient(ExecutionContext* execution_context,
BodyStreamBuffer* buffer,
FetchDataLoader::Client* client)
- : ContextLifecycleObserver(execution_context),
+ : ExecutionContextLifecycleObserver(execution_context),
buffer_(buffer),
client_(client) {}
@@ -84,50 +84,70 @@ class BodyStreamBuffer::LoaderClient final
void Abort() override { NOTREACHED(); }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(buffer_);
visitor->Trace(client_);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
FetchDataLoader::Client::Trace(visitor);
}
private:
- void ContextDestroyed(ExecutionContext*) override { buffer_->StopLoading(); }
+ void ContextDestroyed() override { buffer_->StopLoading(); }
Member<BodyStreamBuffer> buffer_;
Member<FetchDataLoader::Client> client_;
DISALLOW_COPY_AND_ASSIGN(LoaderClient);
};
-BodyStreamBuffer::BodyStreamBuffer(ScriptState* script_state,
+// Use a Create() method to split construction from initialisation.
+// Initialisation may result in nested calls to ContextDestroyed() and so is not
+// safe to do during construction.
+
+// static
+BodyStreamBuffer* BodyStreamBuffer::Create(
+ ScriptState* script_state,
+ BytesConsumer* consumer,
+ AbortSignal* signal,
+ scoped_refptr<BlobDataHandle> side_data_blob) {
+ auto* buffer = MakeGarbageCollected<BodyStreamBuffer>(
+ PassKey(), script_state, consumer, signal, std::move(side_data_blob));
+ buffer->Init();
+ return buffer;
+}
+
+BodyStreamBuffer::BodyStreamBuffer(PassKey,
+ ScriptState* script_state,
BytesConsumer* consumer,
- AbortSignal* signal)
+ AbortSignal* signal,
+ scoped_refptr<BlobDataHandle> side_data_blob)
: UnderlyingSourceBase(script_state),
script_state_(script_state),
consumer_(consumer),
signal_(signal),
- made_from_readable_stream_(false) {
- // inside_create_stream_ is set to track down the cause of the crash in
- // https://crbug.com/1007162.
- // TODO(ricea): Remove it and the CHECK once the cause is found.
- inside_create_stream_ = true;
- CHECK(consumer_);
+ side_data_blob_(std::move(side_data_blob)),
+ made_from_readable_stream_(false) {}
+
+void BodyStreamBuffer::Init() {
+ DCHECK(consumer_);
stream_ =
ReadableStream::CreateWithCountQueueingStrategy(script_state_, this, 0);
stream_broken_ = !stream_;
- // TODO(ricea): Remove this and the CHECK once https://crbug.com/1007162 is
- // fixed.
- inside_create_stream_ = false;
- CHECK(consumer_);
+ // ContextDestroyed() can be called inside the ReadableStream constructor when
+ // a worker thread is being terminated. See https://crbug.com/1007162 for
+ // details. If consumer_ is null, assume that this happened and this object
+ // will never actually be used, and so it is fine to skip the rest of
+ // initialisation.
+ if (!consumer_)
+ return;
consumer_->SetClient(this);
- if (signal) {
- if (signal->aborted()) {
+ if (signal_) {
+ if (signal_->aborted()) {
Abort();
} else {
- signal->AddAlgorithm(
+ signal_->AddAlgorithm(
WTF::Bind(&BodyStreamBuffer::Abort, WrapWeakPersistent(this)));
}
}
@@ -135,11 +155,13 @@ BodyStreamBuffer::BodyStreamBuffer(ScriptState* script_state,
}
BodyStreamBuffer::BodyStreamBuffer(ScriptState* script_state,
- ReadableStream* stream)
+ ReadableStream* stream,
+ scoped_refptr<BlobDataHandle> side_data_blob)
: UnderlyingSourceBase(script_state),
script_state_(script_state),
stream_(stream),
signal_(nullptr),
+ side_data_blob_(std::move(side_data_blob)),
made_from_readable_stream_(true) {
DCHECK(stream_);
}
@@ -223,6 +245,7 @@ void BodyStreamBuffer::Tee(BodyStreamBuffer** branch1,
DCHECK(!IsStreamDisturbedForDCheck(exception_state));
*branch1 = nullptr;
*branch2 = nullptr;
+ scoped_refptr<BlobDataHandle> side_data_blob = TakeSideDataBlob();
if (made_from_readable_stream_) {
if (stream_broken_) {
@@ -242,8 +265,10 @@ void BodyStreamBuffer::Tee(BodyStreamBuffer** branch1,
return;
}
- *branch1 = MakeGarbageCollected<BodyStreamBuffer>(script_state_, stream1);
- *branch2 = MakeGarbageCollected<BodyStreamBuffer>(script_state_, stream2);
+ *branch1 = MakeGarbageCollected<BodyStreamBuffer>(script_state_, stream1,
+ side_data_blob);
+ *branch2 = MakeGarbageCollected<BodyStreamBuffer>(script_state_, stream2,
+ side_data_blob);
return;
}
BytesConsumer* dest1 = nullptr;
@@ -256,9 +281,9 @@ void BodyStreamBuffer::Tee(BodyStreamBuffer** branch1,
BytesConsumerTee(ExecutionContext::From(script_state_), handle, &dest1,
&dest2);
*branch1 =
- MakeGarbageCollected<BodyStreamBuffer>(script_state_, dest1, signal_);
+ BodyStreamBuffer::Create(script_state_, dest1, signal_, side_data_blob);
*branch2 =
- MakeGarbageCollected<BodyStreamBuffer>(script_state_, dest2, signal_);
+ BodyStreamBuffer::Create(script_state_, dest2, signal_, side_data_blob);
}
ScriptPromise BodyStreamBuffer::pull(ScriptState* script_state) {
@@ -309,9 +334,9 @@ bool BodyStreamBuffer::HasPendingActivity() const {
return loader_;
}
-void BodyStreamBuffer::ContextDestroyed(ExecutionContext* destroyed_context) {
+void BodyStreamBuffer::ContextDestroyed() {
CancelConsumer();
- UnderlyingSourceBase::ContextDestroyed(destroyed_context);
+ UnderlyingSourceBase::ContextDestroyed();
}
base::Optional<bool> BodyStreamBuffer::IsStreamReadable(
@@ -388,7 +413,11 @@ bool BodyStreamBuffer::IsAborted() {
return signal_->aborted();
}
-void BodyStreamBuffer::Trace(blink::Visitor* visitor) {
+scoped_refptr<BlobDataHandle> BodyStreamBuffer::TakeSideDataBlob() {
+ return std::move(side_data_blob_);
+}
+
+void BodyStreamBuffer::Trace(Visitor* visitor) {
visitor->Trace(script_state_);
visitor->Trace(stream_);
visitor->Trace(consumer_);
@@ -426,10 +455,8 @@ void BodyStreamBuffer::GetError() {
}
void BodyStreamBuffer::CancelConsumer() {
+ side_data_blob_.reset();
if (consumer_) {
- // TODO(ricea): Remove this CHECK once the cause of
- // https://crbug.com/1007162 is found.
- CHECK(!inside_create_stream_);
consumer_->Cancel();
consumer_ = nullptr;
}
@@ -518,6 +545,8 @@ BytesConsumer* BodyStreamBuffer::ReleaseHandle(
DCHECK(!IsStreamLockedForDCheck(exception_state));
DCHECK(!IsStreamDisturbedForDCheck(exception_state));
+ side_data_blob_.reset();
+
if (stream_broken_) {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidStateError,
@@ -543,9 +572,6 @@ BytesConsumer* BodyStreamBuffer::ReleaseHandle(
if (exception_state.HadException())
return nullptr;
- // TODO(ricea): Remove this CHECK once the cause of https://crbug.com/1007162
- // is found.
- CHECK(!inside_create_stream_);
BytesConsumer* consumer = consumer_.Release();
CloseAndLockAndDisturb(exception_state);
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 e38a66a69f1..bac00bcb6b1 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
@@ -7,6 +7,7 @@
#include <memory>
#include "base/optional.h"
+#include "base/util/type_safety/pass_key.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"
@@ -30,14 +31,29 @@ class CORE_EXPORT BodyStreamBuffer final : public UnderlyingSourceBase,
USING_GARBAGE_COLLECTED_MIXIN(BodyStreamBuffer);
public:
+ using PassKey = util::PassKey<BodyStreamBuffer>;
+
+ // Create a BodyStreamBuffer for |consumer|.
// |consumer| must not have a client.
- // This function must be called with entering an appropriate V8 context.
+ // This function must be called after entering an appropriate V8 context.
// |signal| should be non-null when this BodyStreamBuffer is associated with a
// Response that was created by fetch().
+ static BodyStreamBuffer* Create(
+ ScriptState*,
+ BytesConsumer* consumer,
+ AbortSignal* signal,
+ scoped_refptr<BlobDataHandle> side_data_blob = nullptr);
+
+ // Create() should be used instead of calling this constructor directly.
+ BodyStreamBuffer(PassKey,
+ ScriptState*,
+ BytesConsumer* consumer,
+ AbortSignal* signal,
+ scoped_refptr<BlobDataHandle> side_data_blob);
+
BodyStreamBuffer(ScriptState*,
- BytesConsumer* /* consumer */,
- AbortSignal* /* signal */);
- BodyStreamBuffer(ScriptState*, ReadableStream* stream);
+ ReadableStream* stream,
+ scoped_refptr<BlobDataHandle> side_data_blob = nullptr);
ReadableStream* Stream() { return stream_; }
@@ -55,7 +71,7 @@ class CORE_EXPORT BodyStreamBuffer final : public UnderlyingSourceBase,
ScriptPromise pull(ScriptState*) override;
ScriptPromise Cancel(ScriptState*, ScriptValue reason) override;
bool HasPendingActivity() const override;
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
// BytesConsumer::Client
void OnStateChange() override;
@@ -73,11 +89,24 @@ class CORE_EXPORT BodyStreamBuffer final : public UnderlyingSourceBase,
bool IsAborted();
- void Trace(blink::Visitor*) override;
+ // Take the blob representing any side data associated with this body
+ // stream. This must be called before the body is drained or begins
+ // loading.
+ scoped_refptr<BlobDataHandle> TakeSideDataBlob();
+ scoped_refptr<BlobDataHandle> GetSideDataBlobForTest() const {
+ return side_data_blob_;
+ }
+
+ void Trace(Visitor*) override;
private:
class LoaderClient;
+ // This method exists to avoid re-entrancy inside the BodyStreamBuffer
+ // constructor. It is called by Create(). It should not be called after
+ // using the ReadableStream* constructor.
+ void Init();
+
BytesConsumer* ReleaseHandle(ExceptionState&);
void Abort();
void Close();
@@ -104,15 +133,15 @@ class CORE_EXPORT BodyStreamBuffer final : public UnderlyingSourceBase,
// We need this to ensure that we detect that abort has been signalled
// correctly.
Member<AbortSignal> signal_;
+ // Additional side data associated with this body stream. It should only be
+ // retained until the body is drained or starts loading. Client code, such
+ // as service workers, can call TakeSideDataBlob() prior to consumption.
+ scoped_refptr<BlobDataHandle> side_data_blob_;
bool stream_needs_more_ = false;
bool made_from_readable_stream_;
bool in_process_data_ = false;
bool stream_broken_ = false;
- // TODO(ricea): Remove this once the cause of https://crbug.com/1007162 has
- // been established.
- bool inside_create_stream_ = 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 99f4be5142b..821593825d6 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
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/fetch/body_stream_buffer.h"
#include <memory>
+#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
@@ -21,6 +22,7 @@
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/blob/blob_data.h"
#include "third_party/blink/renderer/platform/blob/blob_url.h"
+#include "third_party/blink/renderer/platform/blob/testing/fake_blob.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/loader/fetch/bytes_consumer.h"
@@ -75,6 +77,12 @@ class BodyStreamBufferTest : public testing::Test {
}
return r;
}
+ scoped_refptr<BlobDataHandle> CreateBlob(const String& body) {
+ auto data = std::make_unique<BlobData>();
+ data->AppendText(body, false);
+ uint64_t length = data->length();
+ return BlobDataHandle::Create(std::move(data), length);
+ }
};
class MockFetchDataLoader : public FetchDataLoader {
@@ -109,13 +117,17 @@ TEST_F(BodyStreamBufferTest, Tee) {
EXPECT_CALL(checkpoint, Call(3));
EXPECT_CALL(checkpoint, Call(4));
+ scoped_refptr<BlobDataHandle> side_data_blob = CreateBlob("side data");
+
ReplayingBytesConsumer* src = MakeGarbageCollected<ReplayingBytesConsumer>(
scope.GetDocument().GetTaskRunner(TaskType::kNetworking));
src->Add(Command(Command::kData, "hello, "));
src->Add(Command(Command::kData, "world"));
src->Add(Command(Command::kDone));
- BodyStreamBuffer* buffer = MakeGarbageCollected<BodyStreamBuffer>(
- scope.GetScriptState(), src, nullptr);
+ BodyStreamBuffer* buffer =
+ BodyStreamBuffer::Create(scope.GetScriptState(), src,
+ /* abort_signal = */ nullptr, side_data_blob);
+ EXPECT_EQ(side_data_blob, buffer->GetSideDataBlobForTest());
BodyStreamBuffer* new1;
BodyStreamBuffer* new2;
@@ -125,6 +137,10 @@ TEST_F(BodyStreamBufferTest, Tee) {
EXPECT_TRUE(buffer->IsStreamDisturbed(exception_state).value_or(false));
EXPECT_FALSE(buffer->HasPendingActivity());
+ EXPECT_EQ(nullptr, buffer->GetSideDataBlobForTest());
+ EXPECT_EQ(side_data_blob, new1->GetSideDataBlobForTest());
+ EXPECT_EQ(side_data_blob, new2->GetSideDataBlobForTest());
+
checkpoint.Call(0);
new1->StartLoading(FetchDataLoader::CreateLoaderAsString(
TextResourceDecoderOptions::CreateUTF8Decode()),
@@ -214,20 +230,18 @@ TEST_F(BodyStreamBufferTest, TeeFromHandleMadeFromStream) {
TEST_F(BodyStreamBufferTest, DrainAsBlobDataHandle) {
V8TestingScope scope;
- auto data = std::make_unique<BlobData>();
- data->AppendText("hello", false);
- auto size = data->length();
- scoped_refptr<BlobDataHandle> blob_data_handle =
- BlobDataHandle::Create(std::move(data), size);
- BodyStreamBuffer* buffer = MakeGarbageCollected<BodyStreamBuffer>(
+ scoped_refptr<BlobDataHandle> blob_data_handle = CreateBlob("hello");
+ scoped_refptr<BlobDataHandle> side_data_blob = CreateBlob("side data");
+ BodyStreamBuffer* buffer = BodyStreamBuffer::Create(
scope.GetScriptState(),
MakeGarbageCollected<BlobBytesConsumer>(scope.GetExecutionContext(),
blob_data_handle),
- nullptr);
+ /* 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->HasPendingActivity());
+ EXPECT_EQ(side_data_blob, buffer->GetSideDataBlobForTest());
scoped_refptr<BlobDataHandle> output_blob_data_handle =
buffer->DrainAsBlobDataHandle(
BytesConsumer::BlobSizePolicy::kAllowBlobWithInvalidSize,
@@ -236,6 +250,7 @@ TEST_F(BodyStreamBufferTest, DrainAsBlobDataHandle) {
EXPECT_TRUE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(false));
EXPECT_TRUE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(false));
EXPECT_FALSE(buffer->HasPendingActivity());
+ EXPECT_EQ(nullptr, buffer->GetSideDataBlobForTest());
EXPECT_EQ(blob_data_handle, output_blob_data_handle);
}
@@ -244,12 +259,15 @@ TEST_F(BodyStreamBufferTest, DrainAsBlobDataHandleReturnsNull) {
// This BytesConsumer is not drainable.
BytesConsumer* src = MakeGarbageCollected<ReplayingBytesConsumer>(
scope.GetDocument().GetTaskRunner(TaskType::kNetworking));
- BodyStreamBuffer* buffer = MakeGarbageCollected<BodyStreamBuffer>(
- scope.GetScriptState(), src, nullptr);
+ scoped_refptr<BlobDataHandle> side_data_blob = CreateBlob("side data");
+ BodyStreamBuffer* buffer =
+ 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->HasPendingActivity());
+ EXPECT_EQ(side_data_blob, buffer->GetSideDataBlobForTest());
EXPECT_FALSE(buffer->DrainAsBlobDataHandle(
BytesConsumer::BlobSizePolicy::kAllowBlobWithInvalidSize,
@@ -258,6 +276,7 @@ TEST_F(BodyStreamBufferTest, DrainAsBlobDataHandleReturnsNull) {
EXPECT_FALSE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(true));
EXPECT_FALSE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true));
EXPECT_FALSE(buffer->HasPendingActivity());
+ EXPECT_EQ(side_data_blob, buffer->GetSideDataBlobForTest());
}
TEST_F(BodyStreamBufferTest,
@@ -292,22 +311,25 @@ TEST_F(BodyStreamBufferTest, DrainAsFormData) {
data->append("name2", "value2");
scoped_refptr<EncodedFormData> input_form_data =
data->EncodeMultiPartFormData();
+ scoped_refptr<BlobDataHandle> side_data_blob = CreateBlob("side data");
- BodyStreamBuffer* buffer = MakeGarbageCollected<BodyStreamBuffer>(
+ BodyStreamBuffer* buffer = BodyStreamBuffer::Create(
scope.GetScriptState(),
MakeGarbageCollected<FormDataBytesConsumer>(scope.GetExecutionContext(),
input_form_data),
- nullptr);
+ /* 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->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_FALSE(buffer->HasPendingActivity());
+ EXPECT_EQ(nullptr, buffer->GetSideDataBlobForTest());
EXPECT_EQ(output_form_data->FlattenToString(),
input_form_data->FlattenToString());
}
@@ -317,18 +339,22 @@ TEST_F(BodyStreamBufferTest, DrainAsFormDataReturnsNull) {
// This BytesConsumer is not drainable.
BytesConsumer* src = MakeGarbageCollected<ReplayingBytesConsumer>(
scope.GetDocument().GetTaskRunner(TaskType::kNetworking));
- BodyStreamBuffer* buffer = MakeGarbageCollected<BodyStreamBuffer>(
- scope.GetScriptState(), src, nullptr);
+ scoped_refptr<BlobDataHandle> side_data_blob = CreateBlob("side data");
+ BodyStreamBuffer* buffer =
+ 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->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->HasPendingActivity());
+ EXPECT_EQ(side_data_blob, buffer->GetSideDataBlobForTest());
}
TEST_F(BodyStreamBufferTest,
@@ -370,11 +396,15 @@ TEST_F(BodyStreamBufferTest, LoadBodyStreamBufferAsArrayBuffer) {
src->Add(Command(Command::kWait));
src->Add(Command(Command::kData, "hello"));
src->Add(Command(Command::kDone));
- BodyStreamBuffer* buffer = MakeGarbageCollected<BodyStreamBuffer>(
- scope.GetScriptState(), src, nullptr);
+ scoped_refptr<BlobDataHandle> side_data_blob = CreateBlob("side data");
+ BodyStreamBuffer* buffer =
+ BodyStreamBuffer::Create(scope.GetScriptState(), src,
+ /* abort_signal = */ nullptr, side_data_blob);
+ EXPECT_EQ(side_data_blob, buffer->GetSideDataBlobForTest());
buffer->StartLoading(FetchDataLoader::CreateLoaderAsArrayBuffer(), 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->HasPendingActivity());
@@ -408,11 +438,15 @@ TEST_F(BodyStreamBufferTest, LoadBodyStreamBufferAsBlob) {
src->Add(Command(Command::kWait));
src->Add(Command(Command::kData, "hello"));
src->Add(Command(Command::kDone));
- BodyStreamBuffer* buffer = MakeGarbageCollected<BodyStreamBuffer>(
- scope.GetScriptState(), src, nullptr);
+ scoped_refptr<BlobDataHandle> side_data_blob = CreateBlob("side data");
+ BodyStreamBuffer* buffer =
+ BodyStreamBuffer::Create(scope.GetScriptState(), src,
+ /* abort_signal = */ nullptr, side_data_blob);
+ EXPECT_EQ(side_data_blob, buffer->GetSideDataBlobForTest());
buffer->StartLoading(FetchDataLoader::CreateLoaderAsBlobHandle("text/plain"),
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->HasPendingActivity());
@@ -442,12 +476,16 @@ TEST_F(BodyStreamBufferTest, LoadBodyStreamBufferAsString) {
src->Add(Command(Command::kWait));
src->Add(Command(Command::kData, "hello"));
src->Add(Command(Command::kDone));
- BodyStreamBuffer* buffer = MakeGarbageCollected<BodyStreamBuffer>(
- scope.GetScriptState(), src, nullptr);
+ scoped_refptr<BlobDataHandle> side_data_blob = CreateBlob("side data");
+ BodyStreamBuffer* buffer =
+ BodyStreamBuffer::Create(scope.GetScriptState(), src,
+ /* abort_signal = */ nullptr, side_data_blob);
+ EXPECT_EQ(side_data_blob, buffer->GetSideDataBlobForTest());
buffer->StartLoading(FetchDataLoader::CreateLoaderAsString(
TextResourceDecoderOptions::CreateUTF8Decode()),
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->HasPendingActivity());
@@ -471,14 +509,17 @@ TEST_F(BodyStreamBufferTest, LoadClosedHandle) {
EXPECT_CALL(*client, DidFetchDataLoadedString(String("")));
EXPECT_CALL(checkpoint, Call(2));
- BodyStreamBuffer* buffer = MakeGarbageCollected<BodyStreamBuffer>(
- scope.GetScriptState(), BytesConsumer::CreateClosed(), nullptr);
+ scoped_refptr<BlobDataHandle> side_data_blob = CreateBlob("side data");
+ BodyStreamBuffer* buffer = BodyStreamBuffer::Create(
+ scope.GetScriptState(), BytesConsumer::CreateClosed(),
+ /* abort_signal = */ nullptr, side_data_blob);
EXPECT_TRUE(buffer->IsStreamClosed(ASSERT_NO_EXCEPTION).value_or(false));
EXPECT_FALSE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(true));
EXPECT_FALSE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true));
EXPECT_FALSE(buffer->HasPendingActivity());
+ EXPECT_EQ(nullptr, buffer->GetSideDataBlobForTest());
checkpoint.Call(1);
buffer->StartLoading(FetchDataLoader::CreateLoaderAsString(
@@ -501,15 +542,18 @@ TEST_F(BodyStreamBufferTest, LoadErroredHandle) {
EXPECT_CALL(*client, DidFetchDataLoadFailed());
EXPECT_CALL(checkpoint, Call(2));
- BodyStreamBuffer* buffer = MakeGarbageCollected<BodyStreamBuffer>(
+ scoped_refptr<BlobDataHandle> side_data_blob = CreateBlob("side data");
+ BodyStreamBuffer* buffer = BodyStreamBuffer::Create(
scope.GetScriptState(),
- BytesConsumer::CreateErrored(BytesConsumer::Error()), nullptr);
+ BytesConsumer::CreateErrored(BytesConsumer::Error()),
+ /* abort_signal = */ nullptr, side_data_blob);
EXPECT_TRUE(buffer->IsStreamErrored(ASSERT_NO_EXCEPTION).value_or(false));
EXPECT_FALSE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(true));
EXPECT_FALSE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true));
EXPECT_FALSE(buffer->HasPendingActivity());
+ EXPECT_EQ(nullptr, buffer->GetSideDataBlobForTest());
checkpoint.Call(1);
buffer->StartLoading(FetchDataLoader::CreateLoaderAsString(
@@ -537,8 +581,8 @@ TEST_F(BodyStreamBufferTest, LoaderShouldBeKeptAliveByBodyStreamBuffer) {
src->Add(Command(Command::kWait));
src->Add(Command(Command::kData, "hello"));
src->Add(Command(Command::kDone));
- Persistent<BodyStreamBuffer> buffer = MakeGarbageCollected<BodyStreamBuffer>(
- scope.GetScriptState(), src, nullptr);
+ Persistent<BodyStreamBuffer> buffer =
+ BodyStreamBuffer::Create(scope.GetScriptState(), src, nullptr);
buffer->StartLoading(FetchDataLoader::CreateLoaderAsString(
TextResourceDecoderOptions::CreateUTF8Decode()),
client, ASSERT_NO_EXCEPTION);
@@ -555,8 +599,8 @@ TEST_F(BodyStreamBufferTest, SourceShouldBeCanceledWhenCanceled) {
MakeGarbageCollected<ReplayingBytesConsumer>(
scope.GetDocument().GetTaskRunner(TaskType::kNetworking));
- BodyStreamBuffer* buffer = MakeGarbageCollected<BodyStreamBuffer>(
- scope.GetScriptState(), consumer, nullptr);
+ BodyStreamBuffer* buffer =
+ BodyStreamBuffer::Create(scope.GetScriptState(), consumer, nullptr);
ScriptValue reason(scope.GetIsolate(),
V8String(scope.GetIsolate(), "reason"));
EXPECT_FALSE(consumer->IsCancelled());
@@ -571,8 +615,8 @@ TEST_F(BodyStreamBufferTest, NestedPull) {
src->Add(Command(Command::kWait));
src->Add(Command(Command::kData, "hello"));
src->Add(Command(Command::kError));
- Persistent<BodyStreamBuffer> buffer = MakeGarbageCollected<BodyStreamBuffer>(
- scope.GetScriptState(), src, nullptr);
+ Persistent<BodyStreamBuffer> buffer =
+ BodyStreamBuffer::Create(scope.GetScriptState(), src, nullptr);
auto result =
scope.GetScriptState()->GetContext()->Global()->CreateDataProperty(
@@ -599,8 +643,8 @@ TEST_F(BodyStreamBufferTest, NullAbortSignalIsNotAborted) {
// This BytesConsumer is not drainable.
BytesConsumer* src = MakeGarbageCollected<ReplayingBytesConsumer>(
scope.GetDocument().GetTaskRunner(TaskType::kNetworking));
- BodyStreamBuffer* buffer = MakeGarbageCollected<BodyStreamBuffer>(
- scope.GetScriptState(), src, nullptr);
+ BodyStreamBuffer* buffer =
+ BodyStreamBuffer::Create(scope.GetScriptState(), src, nullptr);
EXPECT_FALSE(buffer->IsAborted());
}
@@ -611,8 +655,8 @@ TEST_F(BodyStreamBufferTest, AbortSignalMakesAborted) {
BytesConsumer* src = MakeGarbageCollected<ReplayingBytesConsumer>(
scope.GetDocument().GetTaskRunner(TaskType::kNetworking));
auto* signal = MakeGarbageCollected<AbortSignal>(scope.GetExecutionContext());
- BodyStreamBuffer* buffer = MakeGarbageCollected<BodyStreamBuffer>(
- scope.GetScriptState(), src, signal);
+ BodyStreamBuffer* buffer =
+ BodyStreamBuffer::Create(scope.GetScriptState(), src, signal);
EXPECT_FALSE(buffer->IsAborted());
signal->SignalAbort();
@@ -643,8 +687,8 @@ TEST_F(BodyStreamBufferTest,
EXPECT_CALL(checkpoint, Call(3));
auto* signal = MakeGarbageCollected<AbortSignal>(scope.GetExecutionContext());
- BodyStreamBuffer* buffer = MakeGarbageCollected<BodyStreamBuffer>(
- scope.GetScriptState(), src, signal);
+ BodyStreamBuffer* buffer =
+ BodyStreamBuffer::Create(scope.GetScriptState(), src, signal);
checkpoint.Call(1);
signal->SignalAbort();
@@ -677,8 +721,8 @@ TEST_F(BodyStreamBufferTest, AbortAfterStartLoadingCallsDataLoaderClientAbort) {
EXPECT_CALL(checkpoint, Call(3));
auto* signal = MakeGarbageCollected<AbortSignal>(scope.GetExecutionContext());
- BodyStreamBuffer* buffer = MakeGarbageCollected<BodyStreamBuffer>(
- scope.GetScriptState(), src, signal);
+ BodyStreamBuffer* buffer =
+ BodyStreamBuffer::Create(scope.GetScriptState(), src, signal);
checkpoint.Call(1);
buffer->StartLoading(loader, client, ASSERT_NO_EXCEPTION);
@@ -712,8 +756,8 @@ TEST_F(BodyStreamBufferTest,
EXPECT_CALL(checkpoint, Call(3));
auto* signal = MakeGarbageCollected<AbortSignal>(scope.GetExecutionContext());
- BodyStreamBuffer* buffer = MakeGarbageCollected<BodyStreamBuffer>(
- scope.GetScriptState(), src, signal);
+ BodyStreamBuffer* buffer =
+ BodyStreamBuffer::Create(scope.GetScriptState(), src, signal);
checkpoint.Call(1);
buffer->StartLoading(loader, client, ASSERT_NO_EXCEPTION);
@@ -725,6 +769,22 @@ TEST_F(BodyStreamBufferTest,
checkpoint.Call(3);
}
+TEST_F(BodyStreamBufferTest, TakeSideDataBlob) {
+ V8TestingScope scope;
+ scoped_refptr<BlobDataHandle> blob_data_handle = CreateBlob("hello");
+ scoped_refptr<BlobDataHandle> side_data_blob = CreateBlob("side data");
+ BodyStreamBuffer* buffer = BodyStreamBuffer::Create(
+ scope.GetScriptState(),
+ MakeGarbageCollected<BlobBytesConsumer>(scope.GetExecutionContext(),
+ blob_data_handle),
+ /* abort_signal = */ nullptr, side_data_blob);
+
+ EXPECT_EQ(side_data_blob, buffer->GetSideDataBlobForTest());
+ EXPECT_EQ(side_data_blob, buffer->TakeSideDataBlob());
+ EXPECT_EQ(nullptr, buffer->GetSideDataBlobForTest());
+ EXPECT_EQ(nullptr, buffer->TakeSideDataBlob());
+}
+
} // namespace
} // namespace blink
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 7250ffd1b29..1492d51b897 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
private:
Vector<char> buffer_;
@@ -268,7 +268,7 @@ class TeeHelper final : public GarbageCollected<TeeHelper>,
bool IsCancelled() const { return is_cancelled_; }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(execution_context_);
visitor->Trace(tee_);
visitor->Trace(client_);
diff --git a/chromium/third_party/blink/renderer/core/fetch/bytes_consumer_tee_test.cc b/chromium/third_party/blink/renderer/core/fetch/bytes_consumer_tee_test.cc
index c62fa37dba4..227e49a418f 100644
--- a/chromium/third_party/blink/renderer/core/fetch/bytes_consumer_tee_test.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/bytes_consumer_tee_test.cc
@@ -7,6 +7,7 @@
#include "base/memory/scoped_refptr.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/fetch/bytes_consumer_test_util.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/platform/blob/blob_data.h"
#include "third_party/blink/renderer/platform/loader/testing/bytes_consumer_test_reader.h"
@@ -131,7 +132,7 @@ TEST_F(BytesConsumerTeeTest, CreateDone) {
BytesConsumer* dest1 = nullptr;
BytesConsumer* dest2 = nullptr;
- BytesConsumerTee(&GetDocument(), src, &dest1, &dest2);
+ BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);
auto result1 = (MakeGarbageCollected<BytesConsumerTestReader>(dest1))->Run();
auto result2 = (MakeGarbageCollected<BytesConsumerTestReader>(dest2))->Run();
@@ -166,7 +167,7 @@ TEST_F(BytesConsumerTeeTest, TwoPhaseRead) {
BytesConsumer* dest1 = nullptr;
BytesConsumer* dest2 = nullptr;
- BytesConsumerTee(&GetDocument(), src, &dest1, &dest2);
+ BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);
EXPECT_EQ(BytesConsumer::PublicState::kReadableOrWaiting,
dest1->GetPublicState());
@@ -198,7 +199,7 @@ TEST_F(BytesConsumerTeeTest, TwoPhaseReadWithDataAndDone) {
BytesConsumer* dest1 = nullptr;
BytesConsumer* dest2 = nullptr;
- BytesConsumerTee(&GetDocument(), src, &dest1, &dest2);
+ BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);
EXPECT_EQ(BytesConsumer::PublicState::kReadableOrWaiting,
dest1->GetPublicState());
@@ -229,7 +230,7 @@ TEST_F(BytesConsumerTeeTest, Error) {
BytesConsumer* dest1 = nullptr;
BytesConsumer* dest2 = nullptr;
- BytesConsumerTee(&GetDocument(), src, &dest1, &dest2);
+ BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);
EXPECT_EQ(BytesConsumer::PublicState::kErrored, dest1->GetPublicState());
EXPECT_EQ(BytesConsumer::PublicState::kErrored, dest2->GetPublicState());
@@ -262,7 +263,7 @@ TEST_F(BytesConsumerTeeTest, Cancel) {
BytesConsumer* dest1 = nullptr;
BytesConsumer* dest2 = nullptr;
- BytesConsumerTee(&GetDocument(), src, &dest1, &dest2);
+ BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);
EXPECT_EQ(BytesConsumer::PublicState::kReadableOrWaiting,
dest1->GetPublicState());
@@ -292,7 +293,7 @@ TEST_F(BytesConsumerTeeTest, CancelShouldNotAffectTheOtherDestination) {
BytesConsumer* dest1 = nullptr;
BytesConsumer* dest2 = nullptr;
- BytesConsumerTee(&GetDocument(), src, &dest1, &dest2);
+ BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);
EXPECT_EQ(BytesConsumer::PublicState::kReadableOrWaiting,
dest1->GetPublicState());
@@ -327,7 +328,7 @@ TEST_F(BytesConsumerTeeTest, CancelShouldNotAffectTheOtherDestination2) {
BytesConsumer* dest1 = nullptr;
BytesConsumer* dest2 = nullptr;
- BytesConsumerTee(&GetDocument(), src, &dest1, &dest2);
+ BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);
EXPECT_EQ(BytesConsumer::PublicState::kReadableOrWaiting,
dest1->GetPublicState());
@@ -357,7 +358,7 @@ TEST_F(BytesConsumerTeeTest, BlobHandle) {
BytesConsumer* dest1 = nullptr;
BytesConsumer* dest2 = nullptr;
- BytesConsumerTee(&GetDocument(), src, &dest1, &dest2);
+ BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);
scoped_refptr<BlobDataHandle> dest_blob_data_handle1 =
dest1->DrainAsBlobDataHandle(
@@ -379,7 +380,7 @@ TEST_F(BytesConsumerTeeTest, BlobHandleWithInvalidSize) {
BytesConsumer* dest1 = nullptr;
BytesConsumer* dest2 = nullptr;
- BytesConsumerTee(&GetDocument(), src, &dest1, &dest2);
+ BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);
scoped_refptr<BlobDataHandle> dest_blob_data_handle1 =
dest1->DrainAsBlobDataHandle(
@@ -399,7 +400,7 @@ TEST_F(BytesConsumerTeeTest, FormData) {
BytesConsumer* dest1 = nullptr;
BytesConsumer* dest2 = nullptr;
- BytesConsumerTee(&GetDocument(), src, &dest1, &dest2);
+ BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);
scoped_refptr<EncodedFormData> dest_form_data1 = dest1->DrainAsFormData();
scoped_refptr<EncodedFormData> dest_form_data2 = dest2->DrainAsFormData();
@@ -416,7 +417,7 @@ TEST_F(BytesConsumerTeeTest, ConsumerCanBeErroredInTwoPhaseRead) {
BytesConsumer* dest1 = nullptr;
BytesConsumer* dest2 = nullptr;
- BytesConsumerTee(&GetDocument(), src, &dest1, &dest2);
+ BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);
BytesConsumerTestClient* client =
MakeGarbageCollected<BytesConsumerTestClient>();
dest1->SetClient(client);
@@ -450,7 +451,7 @@ TEST_F(BytesConsumerTeeTest,
BytesConsumer* dest1 = nullptr;
BytesConsumer* dest2 = nullptr;
- BytesConsumerTee(&GetDocument(), src, &dest1, &dest2);
+ BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);
dest1->SetClient(client);
@@ -487,7 +488,7 @@ TEST_F(BytesConsumerTeeTest,
BytesConsumer* dest1 = nullptr;
BytesConsumer* dest2 = nullptr;
- BytesConsumerTee(&GetDocument(), src, &dest1, &dest2);
+ BytesConsumerTee(GetFrame().DomWindow(), src, &dest1, &dest2);
dest1->SetClient(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 f7a206d6cc3..41ade535ece 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
FetchDataLoader::Client::Trace(visitor);
}
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 04b0599e6bc..50cfd7c5141 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(consumer_);
visitor->Trace(client_);
FetchDataLoader::Trace(visitor);
@@ -352,7 +352,7 @@ class FetchDataLoaderAsFormData final : public FetchDataLoader,
multipart_parser_->Cancel();
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 6f8a8be55e0..070f97a1d98 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(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) 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(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
};
} // namespace blink
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 9be817069cd..b7bb616e2e8 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
@@ -50,7 +50,7 @@ class CORE_EXPORT FetchHeaderList final
static bool IsValidHeaderName(const String&);
static bool IsValidHeaderValue(const String&);
- void Trace(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
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 d3e79d1d93c..5c62a59abe1 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_manager.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_manager.cc
@@ -15,6 +15,7 @@
#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/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_response_init.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/execution_context/execution_context.h"
@@ -24,10 +25,10 @@
#include "third_party/blink/renderer/core/fetch/form_data_bytes_consumer.h"
#include "third_party/blink/renderer/core/fetch/place_holder_bytes_consumer.h"
#include "third_party/blink/renderer/core/fetch/response.h"
-#include "third_party/blink/renderer/core/fetch/response_init.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/frame.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/loader/subresource_integrity_helper.h"
#include "third_party/blink/renderer/core/loader/threadable_loader.h"
@@ -55,6 +56,7 @@
#include "third_party/blink/renderer/platform/loader/subresource_integrity.h"
#include "third_party/blink/renderer/platform/network/http_names.h"
#include "third_party/blink/renderer/platform/network/network_utils.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/scheme_registry.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -66,6 +68,7 @@
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
+using network::mojom::CredentialsMode;
using network::mojom::FetchResponseType;
using network::mojom::RedirectMode;
using network::mojom::RequestMode;
@@ -96,7 +99,7 @@ class FetchManager::Loader final
bool is_isolated_world,
AbortSignal*);
~Loader() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// ThreadableLoaderClient implementation.
bool WillFollowRedirect(const KURL&, const ResourceResponse&) override;
@@ -197,7 +200,7 @@ class FetchManager::Loader final
bool IsFinished() const { return finished_; }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(body_);
visitor->Trace(updater_);
visitor->Trace(response_);
@@ -225,7 +228,6 @@ class FetchManager::Loader final
void PerformDataFetch();
void Failed(const String& message);
void NotifyFinished();
- Document* GetDocument() const;
ExecutionContext* GetExecutionContext() { return execution_context_; }
Member<FetchManager> fetch_manager_;
@@ -267,7 +269,7 @@ FetchManager::Loader::~Loader() {
DCHECK(!threadable_loader_);
}
-void FetchManager::Loader::Trace(blink::Visitor* visitor) {
+void FetchManager::Loader::Trace(Visitor* visitor) {
visitor->Trace(fetch_manager_);
visitor->Trace(resolver_);
visitor->Trace(fetch_request_data_);
@@ -317,9 +319,6 @@ void FetchManager::Loader::DidReceiveResponse(
const ResourceResponse& response) {
// Verify that we're dealing with the URL we expect (which could be an
// HTTPS-upgraded variant of `url_list_.back()`.
- //
- // TODO(horo): This check could be false when we will use the response url
- // in service worker responses. (crbug.com/553535)
DCHECK(
response.CurrentRequestUrl() == url_list_.back() ||
(response.CurrentRequestUrl().ProtocolIs("https") &&
@@ -352,8 +351,6 @@ void FetchManager::Loader::DidReceiveResponse(
case RequestMode::kCors:
case RequestMode::kCorsWithForcedPreflight:
case RequestMode::kNavigate:
- case RequestMode::kNavigateNestedFrame:
- case RequestMode::kNavigateNestedObject:
PerformNetworkError("Fetch API cannot load " +
fetch_request_data_->Url().GetString() +
". Redirects to data: URL are allowed only when "
@@ -377,8 +374,6 @@ void FetchManager::Loader::DidReceiveResponse(
tainting = FetchRequestData::kCorsTainting;
break;
case RequestMode::kNavigate:
- case RequestMode::kNavigateNestedFrame:
- case RequestMode::kNavigateNestedObject:
LOG(FATAL);
break;
}
@@ -409,8 +404,7 @@ void FetchManager::Loader::DidReceiveResponse(
place_holder_body_ = MakeGarbageCollected<PlaceHolderBytesConsumer>();
FetchResponseData* response_data = FetchResponseData::CreateWithBuffer(
- MakeGarbageCollected<BodyStreamBuffer>(script_state, place_holder_body_,
- signal_));
+ BodyStreamBuffer::Create(script_state, place_holder_body_, signal_));
response_data->SetStatus(response.HttpStatusCode());
if (response.CurrentRequestUrl().ProtocolIsAbout() ||
response.CurrentRequestUrl().ProtocolIsData() ||
@@ -447,6 +441,12 @@ void FetchManager::Loader::DidReceiveResponse(
network::mojom::FetchResponseSource::kNetwork);
}
+ // Note if the response was loaded with credentials enabled.
+ response_data->SetLoadedWithCredentials(
+ fetch_request_data_->Credentials() == CredentialsMode::kInclude ||
+ (fetch_request_data_->Credentials() == CredentialsMode::kSameOrigin &&
+ tainting == FetchRequestData::kBasicTainting));
+
FetchResponseData* tainted_response = nullptr;
DCHECK(!(network_utils::IsRedirectResponseCode(response_http_status_code_) &&
@@ -462,7 +462,7 @@ void FetchManager::Loader::DidReceiveResponse(
tainted_response = response_data->CreateBasicFilteredResponse();
break;
case FetchRequestData::kCorsTainting: {
- WebHTTPHeaderSet header_names = cors::ExtractCorsExposedHeaderNamesList(
+ HTTPHeaderSet header_names = cors::ExtractCorsExposedHeaderNamesList(
fetch_request_data_->Credentials(), response);
tainted_response =
response_data->CreateCorsFilteredResponse(header_names);
@@ -520,11 +520,11 @@ void FetchManager::Loader::DidFinishLoading(uint64_t) {
finished_ = true;
- if (GetDocument() && GetDocument()->GetFrame() &&
- GetDocument()->GetFrame()->GetPage() &&
+ auto* window = DynamicTo<LocalDOMWindow>(execution_context_.Get());
+ if (window && window->GetFrame() &&
cors::IsOkStatus(response_http_status_code_)) {
- GetDocument()->GetFrame()->GetPage()->GetChromeClient().AjaxSucceeded(
- GetDocument()->GetFrame());
+ window->GetFrame()->GetPage()->GetChromeClient().AjaxSucceeded(
+ window->GetFrame());
}
NotifyFinished();
}
@@ -537,10 +537,6 @@ void FetchManager::Loader::DidFailRedirectCheck() {
Failed(String());
}
-Document* FetchManager::Loader::GetDocument() const {
- return DynamicTo<Document>(execution_context_.Get());
-}
-
void FetchManager::Loader::Start(ExceptionState& exception_state) {
// "1. If |request|'s url contains a Known HSTS Host, modify it per the
// requirements of the 'URI [sic] Loading and Port Mapping' chapter of HTTP
@@ -583,7 +579,7 @@ void FetchManager::Loader::Start(ExceptionState& exception_state) {
if (fetch_request_data_->Origin()->CanReadContent(url) ||
(fetch_request_data_->IsolatedWorldOrigin() &&
fetch_request_data_->IsolatedWorldOrigin()->CanReadContent(url)) ||
- network::IsNavigationRequestMode(fetch_request_data_->Mode())) {
+ fetch_request_data_->Mode() == network::mojom::RequestMode::kNavigate) {
// "The result of performing a scheme fetch using request."
PerformSchemeFetch(exception_state);
return;
@@ -708,8 +704,10 @@ void FetchManager::Loader::PerformHTTPFetch(ExceptionState& exception_state) {
request.SetRequestorOrigin(fetch_request_data_->Origin());
request.SetIsolatedWorldOrigin(fetch_request_data_->IsolatedWorldOrigin());
request.SetRequestContext(fetch_request_data_->Context());
+ request.SetRequestDestination(fetch_request_data_->Destination());
request.SetHttpMethod(fetch_request_data_->Method());
request.SetFetchWindowId(fetch_request_data_->WindowId());
+ request.SetTrustTokenParams(fetch_request_data_->TrustTokenParams());
switch (fetch_request_data_->Mode()) {
case RequestMode::kSameOrigin:
@@ -719,8 +717,6 @@ void FetchManager::Loader::PerformHTTPFetch(ExceptionState& exception_state) {
request.SetMode(fetch_request_data_->Mode());
break;
case RequestMode::kNavigate:
- case RequestMode::kNavigateNestedFrame:
- case RequestMode::kNavigateNestedObject:
// NetworkService (i.e. CorsURLLoaderFactory::IsSane) rejects kNavigate
// requests coming from renderers, so using kSameOrigin here.
// TODO(lukasza): Tweak CorsURLLoaderFactory::IsSane to accept kNavigate
@@ -762,7 +758,8 @@ void FetchManager::Loader::PerformHTTPFetch(ExceptionState& exception_state) {
request.SetSkipServiceWorker(is_isolated_world_);
if (fetch_request_data_->Keepalive()) {
- if (cors::IsCorsEnabledRequestMode(fetch_request_data_->Mode()) &&
+ if (!RuntimeEnabledFeatures::OutOfBlinkCorsEnabled() &&
+ cors::IsCorsEnabledRequestMode(fetch_request_data_->Mode()) &&
(!cors::IsCorsSafelistedMethod(request.HttpMethod()) ||
!cors::ContainsOnlyCorsSafelistedOrForbiddenHeaders(
request.HttpHeaderFields()))) {
@@ -817,6 +814,7 @@ void FetchManager::Loader::PerformDataFetch() {
ResourceRequest request(fetch_request_data_->Url());
request.SetRequestorOrigin(fetch_request_data_->Origin());
request.SetRequestContext(fetch_request_data_->Context());
+ request.SetRequestDestination(fetch_request_data_->Destination());
request.SetUseStreamOnResponse(true);
request.SetHttpMethod(fetch_request_data_->Method());
request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit);
@@ -841,9 +839,9 @@ void FetchManager::Loader::Failed(const String& message) {
if (execution_context_->IsContextDestroyed())
return;
if (!message.IsEmpty()) {
- execution_context_->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kError, message));
+ execution_context_->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kError, message));
}
if (resolver_) {
ScriptState* state = resolver_->GetScriptState();
@@ -860,7 +858,7 @@ void FetchManager::Loader::NotifyFinished() {
}
FetchManager::FetchManager(ExecutionContext* execution_context)
- : ContextLifecycleObserver(execution_context) {}
+ : ExecutionContextLifecycleObserver(execution_context) {}
ScriptPromise FetchManager::Fetch(ScriptState* script_state,
FetchRequestData* request,
@@ -877,6 +875,7 @@ ScriptPromise FetchManager::Fetch(ScriptState* script_state,
}
request->SetContext(mojom::RequestContextType::FETCH);
+ request->SetDestination(network::mojom::RequestDestination::kEmpty);
auto* loader = MakeGarbageCollected<Loader>(
GetExecutionContext(), this, resolver, request,
@@ -890,7 +889,7 @@ ScriptPromise FetchManager::Fetch(ScriptState* script_state,
return promise;
}
-void FetchManager::ContextDestroyed(ExecutionContext*) {
+void FetchManager::ContextDestroyed() {
for (auto& loader : loaders_)
loader->Dispose();
}
@@ -900,9 +899,9 @@ void FetchManager::OnLoaderFinished(Loader* loader) {
loader->Dispose();
}
-void FetchManager::Trace(blink::Visitor* visitor) {
+void FetchManager::Trace(Visitor* visitor) {
visitor->Trace(loaders_);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 332dcd8e67a..6b5c87c25ff 100644
--- a/chromium/third_party/blink/renderer/core/fetch/fetch_manager.h
+++ b/chromium/third_party/blink/renderer/core/fetch/fetch_manager.h
@@ -7,7 +7,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/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
@@ -18,8 +18,9 @@ class ExecutionContext;
class FetchRequestData;
class ScriptState;
-class CORE_EXPORT FetchManager final : public GarbageCollected<FetchManager>,
- public ContextLifecycleObserver {
+class CORE_EXPORT FetchManager final
+ : public GarbageCollected<FetchManager>,
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(FetchManager);
public:
@@ -29,9 +30,9 @@ class CORE_EXPORT FetchManager final : public GarbageCollected<FetchManager>,
FetchRequestData*,
AbortSignal*,
ExceptionState&);
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 6f62d48b412..dbafa4d4649 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
@@ -78,7 +78,7 @@ FetchRequestData* FetchRequestData::Create(
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 (DeprecatedEqualIgnoringCase(pair.key, "referer"))
+ if (EqualIgnoringASCIICase(pair.key, "referer"))
continue;
if (for_service_worker_fetch_event == ForServiceWorkerFetchEvent::kTrue &&
IsExcludedHeaderForServiceWorkerFetchEvent(pair.key)) {
@@ -89,20 +89,25 @@ FetchRequestData* FetchRequestData::Create(
if (fetch_api_request.blob) {
DCHECK(!fetch_api_request.body);
- request->SetBuffer(MakeGarbageCollected<BodyStreamBuffer>(
+ 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(MakeGarbageCollected<BodyStreamBuffer>(
+ request->SetBuffer(BodyStreamBuffer::Create(
script_state,
MakeGarbageCollected<FormDataBytesConsumer>(
ExecutionContext::From(script_state), fetch_api_request.body),
nullptr /* AbortSignal */));
}
- request->SetContext(fetch_api_request.request_context_type);
+ // Context is always set to FETCH later, so we don't copy it
+ // from fetch_api_request here.
+ // TODO(crbug.com/1045925): Remove this comment too when
+ // we deprecate SetContext.
+
+ request->SetDestination(fetch_api_request.destination);
request->SetReferrerString(AtomicString(Referrer::NoReferrer()));
if (fetch_api_request.referrer) {
if (!fetch_api_request.referrer->url.IsEmpty())
@@ -132,6 +137,7 @@ FetchRequestData* FetchRequestData::CloneExceptBody() {
request->origin_ = origin_;
request->isolated_world_origin_ = isolated_world_origin_;
request->context_ = context_;
+ request->destination_ = destination_;
request->referrer_string_ = referrer_string_;
request->referrer_policy_ = referrer_policy_;
request->mode_ = mode_;
@@ -146,6 +152,7 @@ FetchRequestData* FetchRequestData::CloneExceptBody() {
request->keepalive_ = keepalive_;
request->is_history_navigation_ = is_history_navigation_;
request->window_id_ = window_id_;
+ request->trust_token_params_ = trust_token_params_;
return request;
}
@@ -173,7 +180,7 @@ FetchRequestData* FetchRequestData::Pass(ScriptState* script_state,
FetchRequestData* request = FetchRequestData::CloneExceptBody();
if (buffer_) {
request->buffer_ = buffer_;
- buffer_ = MakeGarbageCollected<BodyStreamBuffer>(
+ buffer_ = BodyStreamBuffer::Create(
script_state, BytesConsumer::CreateClosed(), nullptr /* AbortSignal */);
buffer_->CloseAndLockAndDisturb(exception_state);
if (exception_state.HadException())
@@ -189,6 +196,7 @@ FetchRequestData::FetchRequestData()
: method_(http_names::kGET),
header_list_(MakeGarbageCollected<FetchHeaderList>()),
context_(mojom::RequestContextType::UNSPECIFIED),
+ destination_(network::mojom::RequestDestination::kEmpty),
referrer_string_(Referrer::ClientReferrerString()),
referrer_policy_(network::mojom::ReferrerPolicy::kDefault),
mode_(network::mojom::RequestMode::kNoCors),
@@ -200,7 +208,7 @@ FetchRequestData::FetchRequestData()
priority_(ResourceLoadPriority::kUnresolved),
keepalive_(false) {}
-void FetchRequestData::Trace(blink::Visitor* visitor) {
+void FetchRequestData::Trace(Visitor* visitor) {
visitor->Trace(buffer_);
visitor->Trace(header_list_);
}
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 babd99bdeaf..f33e8ff3b58 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
@@ -12,8 +12,9 @@
#include "mojo/public/cpp/bindings/remote.h"
#include "services/network/public/mojom/fetch_api.mojom-blink-forward.h"
#include "services/network/public/mojom/referrer_policy.mojom-blink-forward.h"
+#include "services/network/public/mojom/trust_tokens.mojom-blink.h"
#include "services/network/public/mojom/url_loader_factory.mojom-blink.h"
-#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink-forward.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/core/fetch/body_stream_buffer.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -52,6 +53,12 @@ class CORE_EXPORT FetchRequestData final
const KURL& Url() const { return url_; }
mojom::RequestContextType Context() const { return context_; }
void SetContext(mojom::RequestContextType context) { context_ = context; }
+ network::mojom::RequestDestination Destination() const {
+ return destination_;
+ }
+ void SetDestination(network::mojom::RequestDestination destination) {
+ destination_ = destination;
+ }
scoped_refptr<const SecurityOrigin> Origin() const { return origin_; }
void SetOrigin(scoped_refptr<const SecurityOrigin> origin) {
origin_ = std::move(origin);
@@ -118,7 +125,17 @@ class CORE_EXPORT FetchRequestData final
const base::UnguessableToken& WindowId() const { return window_id_; }
void SetWindowId(const base::UnguessableToken& id) { window_id_ = id; }
- void Trace(blink::Visitor*);
+ const base::Optional<network::mojom::blink::TrustTokenParams>&
+ TrustTokenParams() const {
+ return trust_token_params_;
+ }
+ void SetTrustTokenParams(
+ base::Optional<network::mojom::blink::TrustTokenParams>
+ trust_token_params) {
+ trust_token_params_ = std::move(trust_token_params);
+ }
+
+ void Trace(Visitor*);
private:
FetchRequestData* CloneExceptBody();
@@ -128,6 +145,7 @@ class CORE_EXPORT FetchRequestData final
Member<FetchHeaderList> header_list_;
// FIXME: Support m_skipServiceWorkerFlag;
mojom::RequestContextType context_;
+ network::mojom::RequestDestination destination_;
scoped_refptr<const SecurityOrigin> origin_;
scoped_refptr<const SecurityOrigin> isolated_world_origin_;
// FIXME: Support m_forceOriginHeaderFlag;
@@ -143,6 +161,7 @@ class CORE_EXPORT FetchRequestData final
mojom::FetchCacheMode cache_mode_;
network::mojom::RedirectMode redirect_;
mojom::FetchImportanceMode importance_;
+ base::Optional<network::mojom::blink::TrustTokenParams> trust_token_params_;
// FIXME: Support m_useURLCredentialsFlag;
// FIXME: Support m_redirectCount;
Tainting response_tainting_;
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 f5f4be9a5ab..9609acb0e92 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
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/core/fetch/fetch_response_data.h"
-#include "services/network/public/cpp/content_security_policy.h"
+#include "services/network/public/cpp/content_security_policy/content_security_policy.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/mojom/content_security_policy.mojom-blink.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_response.mojom-blink.h"
@@ -41,30 +41,45 @@ blink::CSPSourceListPtr ConvertToBlink(CSPSourceListPtr source_list) {
sources.push_back(ConvertToBlink(std::move(it)));
return blink::CSPSourceList::New(std::move(sources), source_list->allow_self,
- source_list->allow_star);
+ source_list->allow_star,
+ source_list->allow_response_redirects);
}
-blink::CSPDirective::Name ConvertToBlink(CSPDirective::Name name) {
- return static_cast<blink::CSPDirective::Name>(name);
+blink::CSPDirectiveName ConvertToBlink(CSPDirectiveName name) {
+ return static_cast<blink::CSPDirectiveName>(name);
}
-blink::CSPDirectivePtr ConvertToBlink(CSPDirectivePtr csp) {
- return blink::CSPDirective::New(ConvertToBlink(csp->name),
- ConvertToBlink(std::move(csp->source_list)));
+blink::ContentSecurityPolicyHeaderPtr ConvertToBlink(
+ ContentSecurityPolicyHeaderPtr header) {
+ return blink::ContentSecurityPolicyHeader::New(
+ String::FromUTF8(header->header_value), header->type, header->source);
}
-blink::ContentSecurityPolicyPtr ConvertToBlink(ContentSecurityPolicyPtr csp) {
- WTF::Vector<blink::CSPDirectivePtr> directives;
- for (auto& directive : csp->directives)
- directives.push_back(ConvertToBlink(std::move(directive)));
+blink::ContentSecurityPolicyPtr ConvertToBlink(
+ ContentSecurityPolicyPtr policy_in) {
+ auto policy = blink::ContentSecurityPolicy::New();
- WTF::Vector<WTF::String> report_endpoints;
- for (auto& endpoint : csp->report_endpoints)
- report_endpoints.push_back(String::FromUTF8(endpoint));
+ policy->header = ConvertToBlink(std::move(policy_in->header));
+ policy->use_reporting_api = policy_in->use_reporting_api;
- return blink::ContentSecurityPolicy::New(std::move(directives),
- csp->use_reporting_api,
- std::move(report_endpoints));
+ for (auto& directive : policy_in->directives) {
+ policy->directives.insert(ConvertToBlink(directive.first),
+ ConvertToBlink(std::move(directive.second)));
+ }
+
+ for (auto& endpoint : policy_in->report_endpoints)
+ policy->report_endpoints.push_back(String::FromUTF8(endpoint));
+
+ return policy;
+}
+
+WTF::Vector<blink::ContentSecurityPolicyPtr> ConvertToBlink(
+ std::vector<ContentSecurityPolicyPtr> policies) {
+ WTF::Vector<blink::ContentSecurityPolicyPtr> blink_policies;
+ for (auto& policy : policies)
+ blink_policies.push_back(ConvertToBlink(std::move(policy)));
+
+ return blink_policies;
}
} // namespace mojom
@@ -74,10 +89,10 @@ namespace blink {
namespace {
-Vector<String> HeaderSetToVector(const WebHTTPHeaderSet& headers) {
+Vector<String> HeaderSetToVector(const HTTPHeaderSet& headers) {
Vector<String> result;
result.ReserveInitialCapacity(SafeCast<wtf_size_t>(headers.size()));
- // WebHTTPHeaderSet stores headers using Latin1 encoding.
+ // HTTPHeaderSet stores headers using Latin1 encoding.
for (const auto& header : headers)
result.push_back(String(header.data(), header.size()));
return result;
@@ -128,7 +143,7 @@ FetchResponseData* FetchResponseData::CreateBasicFilteredResponse() const {
}
FetchResponseData* FetchResponseData::CreateCorsFilteredResponse(
- const WebHTTPHeaderSet& exposed_headers) const {
+ const HTTPHeaderSet& exposed_headers) const {
DCHECK_EQ(type_, Type::kDefault);
// "A CORS filtered response is a filtered response whose type is |CORS|,
// header list excludes all headers in internal response's header list,
@@ -312,7 +327,7 @@ mojom::blink::FetchAPIResponsePtr FetchResponseData::PopulateFetchAPIResponse(
response->cache_storage_cache_name = cache_storage_cache_name_;
response->cors_exposed_header_names =
HeaderSetToVector(cors_exposed_header_names_);
- response->side_data_blob = side_data_blob_;
+ response->loaded_with_credentials = loaded_with_credentials_;
for (const auto& header : HeaderList()->List())
response->headers.insert(header.first, header.second);
@@ -322,16 +337,22 @@ mojom::blink::FetchAPIResponsePtr FetchResponseData::PopulateFetchAPIResponse(
if (base::FeatureList::IsEnabled(
network::features::kOutOfBlinkFrameAncestors)) {
String content_security_policy_header;
+ std::vector<network::mojom::ContentSecurityPolicyPtr> policies;
if (HeaderList()->Get("content-security-policy",
content_security_policy_header)) {
- network::ContentSecurityPolicy policy;
- if (policy.Parse(request_url,
- StringUTF8Adaptor(content_security_policy_header)
- .AsStringPiece())) {
- response->content_security_policy =
- ConvertToBlink(policy.TakeContentSecurityPolicy());
- }
+ network::AddContentSecurityPolicyFromHeaders(
+ StringUTF8Adaptor(content_security_policy_header).AsStringPiece(),
+ network::mojom::ContentSecurityPolicyType::kEnforce, request_url,
+ &policies);
+ }
+ if (HeaderList()->Get("content-security-policy-report-only",
+ content_security_policy_header)) {
+ network::AddContentSecurityPolicyFromHeaders(
+ StringUTF8Adaptor(content_security_policy_header).AsStringPiece(),
+ network::mojom::ContentSecurityPolicyType::kReport, request_url,
+ &policies);
}
+ response->content_security_policy = ConvertToBlink(std::move(policies));
}
return response;
}
@@ -345,7 +366,8 @@ FetchResponseData::FetchResponseData(Type type,
status_(status),
status_message_(status_message),
header_list_(MakeGarbageCollected<FetchHeaderList>()),
- response_time_(base::Time::Now()) {}
+ response_time_(base::Time::Now()),
+ loaded_with_credentials_(false) {}
void FetchResponseData::ReplaceBodyStreamBuffer(BodyStreamBuffer* buffer) {
if (type_ == Type::kBasic || type_ == Type::kCors) {
@@ -358,7 +380,7 @@ void FetchResponseData::ReplaceBodyStreamBuffer(BodyStreamBuffer* buffer) {
}
}
-void FetchResponseData::Trace(blink::Visitor* visitor) {
+void FetchResponseData::Trace(Visitor* visitor) {
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 30d5523f0cc..0c2af0c626a 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
@@ -12,10 +12,10 @@
#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"
-#include "third_party/blink/public/platform/web_http_header_set.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/fetch/body_stream_buffer.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/network/http_header_set.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
@@ -49,7 +49,7 @@ class CORE_EXPORT FetchResponseData final
FetchResponseData* CreateBasicFilteredResponse() const;
FetchResponseData* CreateCorsFilteredResponse(
- const WebHTTPHeaderSet& exposed_headers) const;
+ const HTTPHeaderSet& exposed_headers) const;
FetchResponseData* CreateOpaqueFilteredResponse() const;
FetchResponseData* CreateOpaqueRedirectFilteredResponse() const;
@@ -77,7 +77,7 @@ class CORE_EXPORT FetchResponseData final
String InternalMIMEType() const;
base::Time ResponseTime() const { return response_time_; }
String CacheStorageCacheName() const { return cache_storage_cache_name_; }
- const WebHTTPHeaderSet& CorsExposedHeaderNames() const {
+ const HTTPHeaderSet& CorsExposedHeaderNames() const {
return cors_exposed_header_names_;
}
@@ -99,11 +99,12 @@ class CORE_EXPORT FetchResponseData final
void SetCacheStorageCacheName(const String& cache_storage_cache_name) {
cache_storage_cache_name_ = cache_storage_cache_name;
}
- void SetCorsExposedHeaderNames(const WebHTTPHeaderSet& header_names) {
+ void SetCorsExposedHeaderNames(const HTTPHeaderSet& header_names) {
cors_exposed_header_names_ = header_names;
}
- void SetSideDataBlob(scoped_refptr<BlobDataHandle> blob) {
- side_data_blob_ = std::move(blob);
+ bool LoadedWithCredentials() const { return loaded_with_credentials_; }
+ void SetLoadedWithCredentials(bool loaded_with_credentials) {
+ loaded_with_credentials_ = loaded_with_credentials;
}
// If the type is Default, replaces |buffer_|.
@@ -116,7 +117,7 @@ class CORE_EXPORT FetchResponseData final
mojom::blink::FetchAPIResponsePtr PopulateFetchAPIResponse(
const KURL& request_url);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
network::mojom::FetchResponseType type_;
@@ -131,8 +132,8 @@ class CORE_EXPORT FetchResponseData final
String mime_type_;
base::Time response_time_;
String cache_storage_cache_name_;
- WebHTTPHeaderSet cors_exposed_header_names_;
- scoped_refptr<BlobDataHandle> side_data_blob_;
+ HTTPHeaderSet cors_exposed_header_names_;
+ bool loaded_with_credentials_;
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 d68661c6eab..af072b5bcbd 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
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/core/fetch/fetch_response_data.h"
+#include "base/test/scoped_feature_list.h"
+#include "services/network/public/cpp/features.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_response.mojom-blink.h"
#include "third_party/blink/renderer/core/fetch/fetch_header_list.h"
@@ -95,7 +97,7 @@ TEST_F(FetchResponseDataTest, ToFetchAPIResponseBasicType) {
TEST_F(FetchResponseDataTest, CorsFilter) {
FetchResponseData* internal_response = CreateInternalResponse();
FetchResponseData* cors_response_data =
- internal_response->CreateCorsFilteredResponse(WebHTTPHeaderSet());
+ internal_response->CreateCorsFilteredResponse(HTTPHeaderSet());
EXPECT_EQ(internal_response, cors_response_data->InternalResponse());
@@ -130,7 +132,7 @@ TEST_F(FetchResponseDataTest,
TEST_F(FetchResponseDataTest, CorsFilterWithEmptyHeaderSet) {
FetchResponseData* internal_response = CreateInternalResponse();
FetchResponseData* cors_response_data =
- internal_response->CreateCorsFilteredResponse(WebHTTPHeaderSet());
+ internal_response->CreateCorsFilteredResponse(HTTPHeaderSet());
EXPECT_EQ(internal_response, cors_response_data->InternalResponse());
@@ -151,7 +153,7 @@ TEST_F(FetchResponseDataTest,
"set-cookie, bar");
FetchResponseData* cors_response_data =
- internal_response->CreateCorsFilteredResponse(WebHTTPHeaderSet());
+ internal_response->CreateCorsFilteredResponse(HTTPHeaderSet());
EXPECT_EQ(internal_response, cors_response_data->InternalResponse());
@@ -167,7 +169,7 @@ TEST_F(FetchResponseDataTest,
TEST_F(FetchResponseDataTest, CorsFilterWithExplicitHeaderSet) {
FetchResponseData* internal_response = CreateInternalResponse();
- WebHTTPHeaderSet exposed_headers;
+ HTTPHeaderSet exposed_headers;
exposed_headers.insert("set-cookie");
exposed_headers.insert("bar");
@@ -186,7 +188,7 @@ TEST_F(FetchResponseDataTest, CorsFilterWithExplicitHeaderSet) {
TEST_F(FetchResponseDataTest, ToFetchAPIResponseCorsType) {
FetchResponseData* internal_response = CreateInternalResponse();
FetchResponseData* cors_response_data =
- internal_response->CreateCorsFilteredResponse(WebHTTPHeaderSet());
+ internal_response->CreateCorsFilteredResponse(HTTPHeaderSet());
mojom::blink::FetchAPIResponsePtr fetch_api_response =
cors_response_data->PopulateFetchAPIResponse(KURL());
@@ -263,4 +265,25 @@ TEST_F(FetchResponseDataTest, DefaultResponseTime) {
EXPECT_FALSE(internal_response->ResponseTime().is_null());
}
+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'");
+ internal_response->HeaderList()->Append("content-security-policy-report-only",
+ "frame-ancestors 'none'");
+
+ mojom::blink::FetchAPIResponsePtr fetch_api_response =
+ internal_response->PopulateFetchAPIResponse(KURL());
+ auto& csp = fetch_api_response->content_security_policy;
+
+ EXPECT_EQ(csp.size(), 2U);
+ EXPECT_EQ(csp[0]->header->type,
+ network::mojom::ContentSecurityPolicyType::kEnforce);
+ EXPECT_EQ(csp[1]->header->type,
+ network::mojom::ContentSecurityPolicyType::kReport);
+}
+
} // namespace blink
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 c1db31250ee..80ce8b92387 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(blob_bytes_consumer_);
BytesConsumer::Trace(visitor);
}
@@ -497,12 +497,14 @@ FormDataBytesConsumer::FormDataBytesConsumer(const String& string)
UTF8Encoding().Encode(string, WTF::kNoUnencodables)))) {}
FormDataBytesConsumer::FormDataBytesConsumer(DOMArrayBuffer* buffer)
- : FormDataBytesConsumer(buffer->Data(),
- buffer->DeprecatedByteLengthAsUnsigned()) {}
+ : FormDataBytesConsumer(
+ buffer->Data(),
+ base::checked_cast<wtf_size_t>(buffer->ByteLengthAsSizeT())) {}
FormDataBytesConsumer::FormDataBytesConsumer(DOMArrayBufferView* view)
- : FormDataBytesConsumer(view->BaseAddress(),
- view->deprecatedByteLengthAsUnsigned()) {}
+ : FormDataBytesConsumer(
+ view->BaseAddress(),
+ base::checked_cast<wtf_size_t>(view->byteLengthAsSizeT())) {}
FormDataBytesConsumer::FormDataBytesConsumer(const void* data, wtf_size_t size)
: impl_(MakeGarbageCollected<SimpleFormDataBytesConsumer>(
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 3f7dc10554f..fd06b7d51cd 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 5207fd4d7bc..56cf200312c 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
@@ -14,6 +14,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/web_http_body.h"
#include "third_party/blink/renderer/core/fetch/bytes_consumer_test_util.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/html/forms/form_data.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
@@ -189,10 +190,10 @@ TEST_F(FormDataBytesConsumerTest, TwoPhaseReadFromSimpleFormData) {
data->AppendData("foo", 3);
data->AppendData("hoge", 4);
- auto result =
- (MakeGarbageCollected<BytesConsumerTestReader>(
- MakeGarbageCollected<FormDataBytesConsumer>(&GetDocument(), data)))
- ->Run();
+ auto result = (MakeGarbageCollected<BytesConsumerTestReader>(
+ MakeGarbageCollected<FormDataBytesConsumer>(
+ GetFrame().DomWindow(), data)))
+ ->Run();
EXPECT_EQ(Result::kDone, result.first);
EXPECT_EQ("foohoge",
BytesConsumerTestUtil::CharVectorToString(result.second));
@@ -202,7 +203,7 @@ TEST_F(FormDataBytesConsumerTest, TwoPhaseReadFromComplexFormData) {
scoped_refptr<EncodedFormData> data = ComplexFormData();
auto* underlying = MakeGarbageCollected<MockBytesConsumer>();
auto* consumer = MakeGarbageCollected<FormDataBytesConsumer>(
- &GetDocument(), data, underlying);
+ GetFrame().DomWindow(), data, underlying);
Checkpoint checkpoint;
const char* buffer = nullptr;
@@ -277,7 +278,7 @@ TEST_F(FormDataBytesConsumerTest, DrainAsBlobDataHandleFromSimpleFormData) {
data->EncodeMultiPartFormData();
BytesConsumer* consumer = MakeGarbageCollected<FormDataBytesConsumer>(
- &GetDocument(), input_form_data);
+ GetFrame().DomWindow(), input_form_data);
scoped_refptr<BlobDataHandle> blob_data_handle =
consumer->DrainAsBlobDataHandle();
ASSERT_TRUE(blob_data_handle);
@@ -296,7 +297,7 @@ TEST_F(FormDataBytesConsumerTest, DrainAsBlobDataHandleFromComplexFormData) {
scoped_refptr<EncodedFormData> input_form_data = ComplexFormData();
BytesConsumer* consumer = MakeGarbageCollected<FormDataBytesConsumer>(
- &GetDocument(), input_form_data);
+ GetFrame().DomWindow(), input_form_data);
scoped_refptr<BlobDataHandle> blob_data_handle =
consumer->DrainAsBlobDataHandle();
ASSERT_TRUE(blob_data_handle);
@@ -345,7 +346,7 @@ TEST_F(FormDataBytesConsumerTest, DrainAsFormDataFromSimpleFormData) {
data->EncodeMultiPartFormData();
BytesConsumer* consumer = MakeGarbageCollected<FormDataBytesConsumer>(
- &GetDocument(), input_form_data);
+ GetFrame().DomWindow(), input_form_data);
EXPECT_EQ(input_form_data, consumer->DrainAsFormData());
EXPECT_FALSE(consumer->DrainAsBlobDataHandle());
const char* buffer = nullptr;
@@ -358,7 +359,7 @@ TEST_F(FormDataBytesConsumerTest, DrainAsFormDataFromComplexFormData) {
scoped_refptr<EncodedFormData> input_form_data = ComplexFormData();
BytesConsumer* consumer = MakeGarbageCollected<FormDataBytesConsumer>(
- &GetDocument(), input_form_data);
+ GetFrame().DomWindow(), input_form_data);
EXPECT_EQ(input_form_data, consumer->DrainAsFormData());
EXPECT_FALSE(consumer->DrainAsBlobDataHandle());
const char* buffer = nullptr;
@@ -385,7 +386,7 @@ TEST_F(FormDataBytesConsumerTest, BeginReadAffectsDraining) {
TEST_F(FormDataBytesConsumerTest, BeginReadAffectsDrainingWithComplexFormData) {
auto* underlying = MakeGarbageCollected<MockBytesConsumer>();
BytesConsumer* consumer = MakeGarbageCollected<FormDataBytesConsumer>(
- &GetDocument(), ComplexFormData(), underlying);
+ GetFrame().DomWindow(), ComplexFormData(), underlying);
const char* buffer = nullptr;
size_t available = 0;
@@ -424,7 +425,7 @@ TEST_F(FormDataBytesConsumerTest, SetClientWithComplexFormData) {
auto* underlying = MakeGarbageCollected<MockBytesConsumer>();
auto* consumer = MakeGarbageCollected<FormDataBytesConsumer>(
- &GetDocument(), input_form_data, underlying);
+ GetFrame().DomWindow(), input_form_data, underlying);
Checkpoint checkpoint;
InSequence s;
@@ -446,7 +447,7 @@ TEST_F(FormDataBytesConsumerTest, CancelWithComplexFormData) {
auto* underlying = MakeGarbageCollected<MockBytesConsumer>();
auto* consumer = MakeGarbageCollected<FormDataBytesConsumer>(
- &GetDocument(), input_form_data, underlying);
+ GetFrame().DomWindow(), input_form_data, underlying);
Checkpoint checkpoint;
InSequence s;
@@ -462,8 +463,8 @@ TEST_F(FormDataBytesConsumerTest, CancelWithComplexFormData) {
// Tests consuming an EncodedFormData with data pipe elements.
TEST_F(FormDataBytesConsumerTest, DataPipeFormData) {
scoped_refptr<EncodedFormData> input_form_data = DataPipeFormData();
- auto* consumer = MakeGarbageCollected<FormDataBytesConsumer>(&GetDocument(),
- input_form_data);
+ auto* consumer = MakeGarbageCollected<FormDataBytesConsumer>(
+ GetFrame().DomWindow(), input_form_data);
auto* reader = MakeGarbageCollected<BytesConsumerTestReader>(consumer);
std::pair<BytesConsumer::Result, Vector<char>> result = reader->Run();
EXPECT_EQ(Result::kDone, result.first);
@@ -474,8 +475,8 @@ TEST_F(FormDataBytesConsumerTest, DataPipeFormData) {
// Tests DrainAsFormData() on an EncodedFormData with data pipe elements.
TEST_F(FormDataBytesConsumerTest, DataPipeFormData_DrainAsFormData) {
scoped_refptr<EncodedFormData> input_form_data = DataPipeFormData();
- auto* consumer = MakeGarbageCollected<FormDataBytesConsumer>(&GetDocument(),
- input_form_data);
+ auto* consumer = MakeGarbageCollected<FormDataBytesConsumer>(
+ GetFrame().DomWindow(), input_form_data);
scoped_refptr<EncodedFormData> drained_form_data =
consumer->DrainAsFormData();
EXPECT_EQ(*input_form_data, *drained_form_data);
@@ -488,8 +489,8 @@ TEST_F(FormDataBytesConsumerTest,
DataPipeFormData_DrainAsFormDataWhileReading) {
// Create the consumer and start reading.
scoped_refptr<EncodedFormData> input_form_data = DataPipeFormData();
- auto* consumer = MakeGarbageCollected<FormDataBytesConsumer>(&GetDocument(),
- input_form_data);
+ auto* consumer = MakeGarbageCollected<FormDataBytesConsumer>(
+ GetFrame().DomWindow(), input_form_data);
const char* buffer = nullptr;
size_t available = 0;
EXPECT_EQ(BytesConsumer::Result::kOk,
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 c9085a018fc..80d8de09a20 100644
--- a/chromium/third_party/blink/renderer/core/fetch/global_fetch.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/global_fetch.cc
@@ -4,9 +4,9 @@
#include "third_party/blink/renderer/core/fetch/global_fetch.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_request_init.h"
#include "third_party/blink/renderer/core/fetch/fetch_manager.h"
#include "third_party/blink/renderer/core/fetch/request.h"
-#include "third_party/blink/renderer/core/fetch/request_init.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/core/workers/worker_global_scope.h"
@@ -88,7 +88,7 @@ class GlobalFetchImpl final : public GarbageCollected<GlobalFetchImpl<T>>,
return promise;
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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(blink::Visitor* visitor) {}
+void GlobalFetch::ScopedFetcher::Trace(Visitor* visitor) {}
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 c94a0e90428..f401074a8ec 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 45764179bed..893ecc97fe9 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(blink::Visitor* visitor) {
+void Headers::Trace(Visitor* visitor) {
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 3b05567055c..045bec08cdf 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
// These methods should only be called when size() would return 0.
diff --git a/chromium/third_party/blink/renderer/core/fetch/headers.idl b/chromium/third_party/blink/renderer/core/fetch/headers.idl
index 102691f5494..5b0388d8cc7 100644
--- a/chromium/third_party/blink/renderer/core/fetch/headers.idl
+++ b/chromium/third_party/blink/renderer/core/fetch/headers.idl
@@ -9,10 +9,9 @@ typedef (sequence<sequence<ByteString>> or record<ByteString, ByteString>) Heade
// https://fetch.spec.whatwg.org/#headers-class
[
- Constructor(optional HeadersInit init),
- Exposed=(Window,Worker),
- RaisesException=Constructor
+ Exposed=(Window,Worker)
] interface Headers {
+ [RaisesException] constructor(optional HeadersInit init);
[RaisesException] void append(ByteString name, ByteString value);
[ImplementedAs=remove, RaisesException] void delete(ByteString key);
[RaisesException] ByteString? get(ByteString key);
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 4be2be009e1..2f3383b1201 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(blink::Visitor* visitor) {
+void MultipartParser::Trace(Visitor* visitor) {
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 009d060efb7..210efffac61 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(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) override {}
};
MultipartParser(Vector<char> boundary, Client*);
@@ -50,7 +50,7 @@ class CORE_EXPORT MultipartParser final
bool IsCancelled() const { return state_ == State::kCancelled; }
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
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 46fae70c843..a5c44e81103 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(blink::Visitor* visitor) {
+void PlaceHolderBytesConsumer::Trace(Visitor* visitor) {
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 0d244ad37ed..09ef3a30d6a 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(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) 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 70c033afaea..383f9d4bde4 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(consumer_);
ScriptFunction::Trace(visitor);
}
@@ -84,7 +84,7 @@ class ReadableStreamBytesConsumer::OnRejected final : public ScriptFunction {
return v;
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(consumer_);
ScriptFunction::Trace(visitor);
}
@@ -123,7 +123,16 @@ BytesConsumer::Result ReadableStreamBytesConsumer::BeginRead(
is_reading_ = true;
ScriptState::Scope scope(script_state_);
DCHECK(reader_);
- reader_->read(script_state_)
+
+ ExceptionState exception_state(script_state_->GetIsolate(),
+ ExceptionState::kUnknownContext, "", "");
+
+ ScriptPromise script_promise =
+ reader_->read(script_state_, exception_state);
+ if (exception_state.HadException())
+ script_promise = ScriptPromise::Reject(script_state_, exception_state);
+
+ script_promise
.Then(OnFulfilled::CreateFunction(script_state_, this),
OnRejected::CreateFunction(script_state_, this))
.MarkAsHandled();
@@ -168,7 +177,7 @@ BytesConsumer::Error ReadableStreamBytesConsumer::GetError() const {
return Error("Failed to read from a ReadableStream.");
}
-void ReadableStreamBytesConsumer::Trace(blink::Visitor* visitor) {
+void ReadableStreamBytesConsumer::Trace(Visitor* visitor) {
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 ec071176862..8a74a038f90 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 1999d6956d1..fd8affae8f9 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(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) 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 7029071fd93..ee851d89091 100644
--- a/chromium/third_party/blink/renderer/core/fetch/request.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/request.cc
@@ -4,10 +4,13 @@
#include "third_party/blink/renderer/core/fetch/request.h"
+#include "base/optional.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "services/network/public/cpp/request_destination.h"
#include "services/network/public/cpp/request_mode.h"
+#include "services/network/public/mojom/trust_tokens.mojom-blink.h"
#include "third_party/blink/public/common/blob/blob_utils.h"
-#include "third_party/blink/public/common/loader/request_destination.h"
+#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.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/dictionary.h"
@@ -18,6 +21,9 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer_view.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_blob.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_form_data.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_readable_stream.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_request_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_trust_token.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_url_search_params.h"
#include "third_party/blink/renderer/core/dom/abort_signal.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -25,7 +31,8 @@
#include "third_party/blink/renderer/core/fetch/body_stream_buffer.h"
#include "third_party/blink/renderer/core/fetch/fetch_manager.h"
#include "third_party/blink/renderer/core/fetch/form_data_bytes_consumer.h"
-#include "third_party/blink/renderer/core/fetch/request_init.h"
+#include "third_party/blink/renderer/core/fetch/trust_token.h"
+#include "third_party/blink/renderer/core/fetch/trust_token_to_mojom.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
#include "third_party/blink/renderer/core/fileapi/public_url_manager.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
@@ -50,6 +57,12 @@
namespace blink {
+namespace {
+
+using network::mojom::blink::TrustTokenOperationType;
+
+} // namespace
+
FetchRequestData* CreateCopyOfFetchRequestDataForFetch(
ScriptState* script_state,
const FetchRequestData* original) {
@@ -81,6 +94,7 @@ FetchRequestData* CreateCopyOfFetchRequestDataForFetch(
request->SetURLLoaderFactory(std::move(factory_clone));
}
request->SetWindowId(original->WindowId());
+ request->SetTrustTokenParams(original->TrustTokenParams());
return request;
}
@@ -89,7 +103,7 @@ static bool AreAnyMembersPresent(const RequestInit* init) {
init->hasReferrer() || init->hasReferrerPolicy() || init->hasMode() ||
init->hasCredentials() || init->hasCache() || init->hasRedirect() ||
init->hasIntegrity() || init->hasKeepalive() ||
- init->hasImportance() || init->hasSignal();
+ init->hasImportance() || init->hasSignal() || init->hasTrustToken();
}
static BodyStreamBuffer* ExtractBody(ScriptState* script_state,
@@ -104,7 +118,7 @@ static BodyStreamBuffer* ExtractBody(ScriptState* script_state,
if (V8Blob::HasInstance(body, isolate)) {
Blob* blob = V8Blob::ToImpl(body.As<v8::Object>());
- return_buffer = MakeGarbageCollected<BodyStreamBuffer>(
+ return_buffer = BodyStreamBuffer::Create(
script_state,
MakeGarbageCollected<BlobBytesConsumer>(execution_context,
blob->GetBlobDataHandle()),
@@ -114,7 +128,13 @@ static BodyStreamBuffer* ExtractBody(ScriptState* script_state,
// Avoid calling into V8 from the following constructor parameters, which
// is potentially unsafe.
DOMArrayBuffer* array_buffer = V8ArrayBuffer::ToImpl(body.As<v8::Object>());
- return_buffer = MakeGarbageCollected<BodyStreamBuffer>(
+ if (!base::CheckedNumeric<wtf_size_t>(array_buffer->ByteLengthAsSizeT())
+ .IsValid()) {
+ exception_state.ThrowRangeError(
+ "The provided ArrayBuffer exceeds the maximum supported size");
+ return nullptr;
+ }
+ return_buffer = BodyStreamBuffer::Create(
script_state, MakeGarbageCollected<FormDataBytesConsumer>(array_buffer),
nullptr /* AbortSignal */);
} else if (body->IsArrayBufferView()) {
@@ -122,7 +142,14 @@ static BodyStreamBuffer* ExtractBody(ScriptState* script_state,
// is potentially unsafe.
DOMArrayBufferView* array_buffer_view =
V8ArrayBufferView::ToImpl(body.As<v8::Object>());
- return_buffer = MakeGarbageCollected<BodyStreamBuffer>(
+ if (!base::CheckedNumeric<wtf_size_t>(
+ array_buffer_view->byteLengthAsSizeT())
+ .IsValid()) {
+ exception_state.ThrowRangeError(
+ "The provided ArrayBufferView exceeds the maximum supported size");
+ return nullptr;
+ }
+ return_buffer = BodyStreamBuffer::Create(
script_state,
MakeGarbageCollected<FormDataBytesConsumer>(array_buffer_view),
nullptr /* AbortSignal */);
@@ -133,19 +160,19 @@ static BodyStreamBuffer* ExtractBody(ScriptState* script_state,
// FormDataEncoder::generateUniqueBoundaryString.
content_type = AtomicString("multipart/form-data; boundary=") +
form_data->Boundary().data();
- return_buffer = MakeGarbageCollected<BodyStreamBuffer>(
- script_state,
- MakeGarbageCollected<FormDataBytesConsumer>(execution_context,
- std::move(form_data)),
- nullptr /* AbortSignal */);
+ return_buffer =
+ BodyStreamBuffer::Create(script_state,
+ MakeGarbageCollected<FormDataBytesConsumer>(
+ execution_context, std::move(form_data)),
+ nullptr /* AbortSignal */);
} else if (V8URLSearchParams::HasInstance(body, isolate)) {
scoped_refptr<EncodedFormData> form_data =
V8URLSearchParams::ToImpl(body.As<v8::Object>())->ToEncodedFormData();
- return_buffer = MakeGarbageCollected<BodyStreamBuffer>(
- script_state,
- MakeGarbageCollected<FormDataBytesConsumer>(execution_context,
- std::move(form_data)),
- nullptr /* AbortSignal */);
+ return_buffer =
+ BodyStreamBuffer::Create(script_state,
+ MakeGarbageCollected<FormDataBytesConsumer>(
+ execution_context, std::move(form_data)),
+ nullptr /* AbortSignal */);
content_type = "application/x-www-form-urlencoded;charset=UTF-8";
} else {
String string = NativeValueTraits<IDLUSVString>::NativeValue(
@@ -153,7 +180,7 @@ static BodyStreamBuffer* ExtractBody(ScriptState* script_state,
if (exception_state.HadException())
return nullptr;
- return_buffer = MakeGarbageCollected<BodyStreamBuffer>(
+ return_buffer = BodyStreamBuffer::Create(
script_state, MakeGarbageCollected<FormDataBytesConsumer>(string),
nullptr /* AbortSignal */);
content_type = "text/plain;charset=UTF-8";
@@ -283,7 +310,7 @@ Request* Request::CreateRequestWithRequestOrString(
// "If any of |init|'s members are present, then:"
if (AreAnyMembersPresent(init)) {
// "If |request|'s |mode| is "navigate", then set it to "same-origin".
- if (network::IsNavigationRequestMode(request->Mode()))
+ if (request->Mode() == network::mojom::RequestMode::kNavigate)
request->SetMode(network::mojom::RequestMode::kSameOrigin);
// TODO(yhirano): Implement the following substep:
@@ -404,9 +431,10 @@ Request* Request::CreateRequestWithRequestOrString(
// "If |credentials| is non-null, set |request|'s credentials mode to
// |credentials|."
- network::mojom::CredentialsMode credentials_mode;
- if (ParseCredentialsMode(init->credentials(), &credentials_mode)) {
- request->SetCredentials(credentials_mode);
+ base::Optional<network::mojom::CredentialsMode> credentials_result =
+ ParseCredentialsMode(init->credentials());
+ if (credentials_result) {
+ request->SetCredentials(credentials_result.value());
} else if (!input_request) {
request->SetCredentials(network::mojom::CredentialsMode::kSameOrigin);
}
@@ -479,6 +507,30 @@ Request* Request::CreateRequestWithRequestOrString(
signal = init->signal();
}
+ if (init->hasTrustToken()) {
+ network::mojom::blink::TrustTokenParams params;
+ if (!ConvertTrustTokenToMojom(*init->trustToken(), &exception_state,
+ &params)) {
+ // Whenever parsing the trustToken argument fails, we expect a suitable
+ // exception to be thrown.
+ DCHECK(exception_state.HadException());
+ return nullptr;
+ }
+
+ if ((params.type == TrustTokenOperationType::kRedemption ||
+ params.type == TrustTokenOperationType::kSigning) &&
+ !execution_context->IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kTrustTokenRedemption)) {
+ exception_state.ThrowTypeError(
+ "trustToken: Redemption ('srr-token-redemption') and signing "
+ "('send-srr') operations require that the trust-token-redemption "
+ "Feature Policy feature be enabled.");
+ return nullptr;
+ }
+
+ request->SetTrustTokenParams(std::move(params));
+ }
+
// "Let |r| be a new Request object associated with |request| and a new
// Headers object whose guard is "request"."
Request* r = Request::Create(script_state, request);
@@ -536,8 +588,17 @@ Request* Request::CreateRequestWithRequestOrString(
// "If |init|’s body member is present and is non-null, then:"
if (!init_body.IsEmpty() && !init_body->IsNull()) {
- // TODO(yhirano): Throw if keepalive flag is set and body is a
- // ReadableStream. We don't support body stream setting for Request yet.
+ // - If |init|["keepalive"] exists and is true, then set |body| and
+ // |Content-Type| to the result of extracting |init|["body"], with the
+ // |keepalive| flag set.
+ // From "extract a body":
+ // - If the keepalive flag is set, then throw a TypeError.
+ if (init->hasKeepalive() && init->keepalive() &&
+ V8ReadableStream::HasInstance(init_body, script_state->GetIsolate())) {
+ exception_state.ThrowTypeError(
+ "Keepalive request cannot have a ReadableStream body.");
+ return nullptr;
+ }
// Perform the following steps:
// - "Let |stream| and |Content-Type| be the result of extracting
@@ -571,7 +632,7 @@ Request* Request::CreateRequestWithRequestOrString(
// non-null, run these substeps:"
if (input_request && input_request->BodyBuffer()) {
// "Let |dummyStream| be an empty ReadableStream object."
- auto* dummy_stream = MakeGarbageCollected<BodyStreamBuffer>(
+ auto* dummy_stream = BodyStreamBuffer::Create(
script_state, BytesConsumer::CreateClosed(), nullptr);
// "Set |input|'s request's body to a new body whose stream is
// |dummyStream|."
@@ -638,21 +699,15 @@ Request* Request::Create(
return MakeGarbageCollected<Request>(script_state, data);
}
-bool Request::ParseCredentialsMode(const String& credentials_mode,
- network::mojom::CredentialsMode* result) {
- if (credentials_mode == "omit") {
- *result = network::mojom::CredentialsMode::kOmit;
- return true;
- }
- if (credentials_mode == "same-origin") {
- *result = network::mojom::CredentialsMode::kSameOrigin;
- return true;
- }
- if (credentials_mode == "include") {
- *result = network::mojom::CredentialsMode::kInclude;
- return true;
- }
- return false;
+base::Optional<network::mojom::CredentialsMode> Request::ParseCredentialsMode(
+ const String& credentials_mode) {
+ if (credentials_mode == "omit")
+ return network::mojom::CredentialsMode::kOmit;
+ if (credentials_mode == "same-origin")
+ return network::mojom::CredentialsMode::kSameOrigin;
+ if (credentials_mode == "include")
+ return network::mojom::CredentialsMode::kInclude;
+ return base::nullopt;
}
Request::Request(ScriptState* script_state,
@@ -685,7 +740,7 @@ const KURL& Request::url() const {
String Request::destination() const {
// "The destination attribute’s getter must return request’s destination."
- return GetRequestDestinationFromContext(request_->Context());
+ return network::RequestDestinationToString(request_->Destination());
}
String Request::referrer() const {
@@ -715,8 +770,7 @@ String Request::getReferrerPolicy() const {
return "same-origin";
case network::mojom::ReferrerPolicy::kStrictOrigin:
return "strict-origin";
- case network::mojom::ReferrerPolicy::
- kNoReferrerWhenDowngradeOriginWhenCrossOrigin:
+ case network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin:
return "strict-origin-when-cross-origin";
}
NOTREACHED();
@@ -735,8 +789,6 @@ String Request::mode() const {
case network::mojom::RequestMode::kCorsWithForcedPreflight:
return "cors";
case network::mojom::RequestMode::kNavigate:
- case network::mojom::RequestMode::kNavigateNestedFrame:
- case network::mojom::RequestMode::kNavigateNestedObject:
return "navigate";
}
NOTREACHED();
@@ -857,6 +909,7 @@ mojom::blink::FetchAPIRequestPtr Request::CreateFetchAPIRequest() const {
fetch_api_request->integrity = request_->Integrity();
fetch_api_request->is_history_navigation = request_->IsHistoryNavigation();
fetch_api_request->request_context_type = request_->Context();
+ fetch_api_request->destination = request_->Destination();
// Strip off the fragment part of URL. So far, all callers expect the fragment
// to be excluded.
@@ -867,7 +920,7 @@ mojom::blink::FetchAPIRequestPtr Request::CreateFetchAPIRequest() const {
HTTPHeaderMap headers;
for (const auto& header : headers_->HeaderList()->List()) {
- if (DeprecatedEqualIgnoringCase(header.first, "referer"))
+ if (EqualIgnoringASCIICase(header.first, "referer"))
continue;
AtomicString key(header.first);
AtomicString value(header.second);
@@ -909,7 +962,14 @@ mojom::RequestContextType Request::GetRequestContextType() const {
return request_->Context();
}
-void Request::Trace(blink::Visitor* visitor) {
+network::mojom::RequestDestination Request::GetRequestDestination() const {
+ if (!request_) {
+ return network::mojom::RequestDestination::kEmpty;
+ }
+ return request_->Destination();
+}
+
+void Request::Trace(Visitor* visitor) {
Body::Trace(visitor);
visitor->Trace(request_);
visitor->Trace(headers_);
diff --git a/chromium/third_party/blink/renderer/core/fetch/request.h b/chromium/third_party/blink/renderer/core/fetch/request.h
index f77e360f429..04a2a59158e 100644
--- a/chromium/third_party/blink/renderer/core/fetch/request.h
+++ b/chromium/third_party/blink/renderer/core/fetch/request.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_REQUEST_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_REQUEST_H_
+#include "base/optional.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/platform/web_url_request.h"
@@ -61,10 +62,8 @@ class CORE_EXPORT Request final : public Body {
Request(ScriptState*, FetchRequestData*, Headers*, AbortSignal*);
Request(ScriptState*, FetchRequestData*);
- // Returns false if |credentials_mode| doesn't represent a valid credentials
- // mode.
- static bool ParseCredentialsMode(const String& credentials_mode,
- network::mojom::CredentialsMode*);
+ static base::Optional<network::mojom::CredentialsMode> ParseCredentialsMode(
+ const String& credentials_mode);
// From Request.idl:
String method() const;
@@ -94,8 +93,9 @@ class CORE_EXPORT Request final : public Body {
return request_->Buffer();
}
mojom::RequestContextType GetRequestContextType() const;
+ network::mojom::RequestDestination GetRequestDestination() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
const FetchRequestData* GetRequest() const { return request_; }
diff --git a/chromium/third_party/blink/renderer/core/fetch/request.idl b/chromium/third_party/blink/renderer/core/fetch/request.idl
index 2b5e12b3a44..a275fe5450d 100644
--- a/chromium/third_party/blink/renderer/core/fetch/request.idl
+++ b/chromium/third_party/blink/renderer/core/fetch/request.idl
@@ -11,8 +11,8 @@ enum RequestDestination { "", "audio", "audioworklet", "document", "embed", "fon
enum RequestMode { "navigate", "same-origin", "no-cors", "cors" };
enum RequestCredentials { "omit", "same-origin", "include" };
enum RequestRedirect { "follow", "error", "manual" };
-enum RequestCache { "default", "no-store", "reload", "no-cache", "force-cache",
- "only-if-cached" };
+enum RequestCache { "default", "no-store", "reload", "no-cache", "force-cache",
+ "only-if-cached" };
enum RequestImportance {"low", "auto", "high"};
// https://w3c.github.io/webappsec-referrer-policy/#referrer-policies
@@ -31,11 +31,9 @@ enum ReferrerPolicy {
[
ActiveScriptWrappable,
- Constructor(RequestInfo input, optional RequestInit requestInitDict),
- ConstructorCallWith=ScriptState,
- Exposed=(Window,Worker),
- RaisesException=Constructor
+ Exposed=(Window,Worker)
] interface Request {
+ [CallWith=ScriptState, RaisesException] constructor(RequestInfo input, optional RequestInit init = {});
readonly attribute ByteString method;
readonly attribute USVString url;
[ImplementedAs=getHeaders, SameObject] readonly attribute Headers headers;
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 82e7336ae8e..62428ff3a14 100644
--- a/chromium/third_party/blink/renderer/core/fetch/request_init.idl
+++ b/chromium/third_party/blink/renderer/core/fetch/request_init.idl
@@ -23,6 +23,7 @@ dictionary RequestInit {
boolean keepalive;
[RuntimeEnabled=PriorityHints] RequestImportance importance;
AbortSignal? signal;
+ [RuntimeEnabled=TrustTokens, SecureContext] TrustToken trustToken;
// 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 9ec15264b7e..f37d4d239b3 100644
--- a/chromium/third_party/blink/renderer/core/fetch/request_test.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/request_test.cc
@@ -59,7 +59,8 @@ TEST(ServiceWorkerRequestTest, FromAndToFetchAPIRequest) {
const String referrer = "http://www.referrer.com/";
const network::mojom::ReferrerPolicy kReferrerPolicy =
network::mojom::ReferrerPolicy::kAlways;
- const mojom::RequestContextType kContext = mojom::RequestContextType::AUDIO;
+ const network::mojom::RequestDestination kDestination =
+ network::mojom::RequestDestination::kAudio;
const network::mojom::RequestMode kMode =
network::mojom::RequestMode::kNavigate;
const network::mojom::CredentialsMode kCredentialsMode =
@@ -74,7 +75,7 @@ TEST(ServiceWorkerRequestTest, FromAndToFetchAPIRequest) {
fetch_api_request->credentials_mode = kCredentialsMode;
fetch_api_request->cache_mode = kCacheMode;
fetch_api_request->redirect_mode = kRedirectMode;
- fetch_api_request->request_context_type = kContext;
+ fetch_api_request->destination = kDestination;
for (int i = 0; headers[i].key; ++i) {
fetch_api_request->headers.insert(String(headers[i].key),
String(headers[i].value));
@@ -113,7 +114,6 @@ TEST(ServiceWorkerRequestTest, FromAndToFetchAPIRequest) {
EXPECT_EQ(kCredentialsMode, second_fetch_api_request->credentials_mode);
EXPECT_EQ(kCacheMode, second_fetch_api_request->cache_mode);
EXPECT_EQ(kRedirectMode, second_fetch_api_request->redirect_mode);
- EXPECT_EQ(kContext, second_fetch_api_request->request_context_type);
EXPECT_EQ(referrer, second_fetch_api_request->referrer->url);
EXPECT_EQ(network::mojom::ReferrerPolicy::kAlways,
second_fetch_api_request->referrer->policy);
diff --git a/chromium/third_party/blink/renderer/core/fetch/response.cc b/chromium/third_party/blink/renderer/core/fetch/response.cc
index 484b882b76c..9ca8b435767 100644
--- a/chromium/third_party/blink/renderer/core/fetch/response.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/response.cc
@@ -17,12 +17,12 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_blob.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_form_data.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_readable_stream.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_response_init.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_url_search_params.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/fetch/blob_bytes_consumer.h"
#include "third_party/blink/renderer/core/fetch/body_stream_buffer.h"
#include "third_party/blink/renderer/core/fetch/form_data_bytes_consumer.h"
-#include "third_party/blink/renderer/core/fetch/response_init.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/html/forms/form_data.h"
@@ -54,7 +54,7 @@ FetchResponseData* FilterResponseDataInternal(
return response->CreateBasicFilteredResponse();
break;
case network::mojom::FetchResponseType::kCors: {
- WebHTTPHeaderSet header_names;
+ HTTPHeaderSet header_names;
for (const auto& header : headers)
header_names.insert(header.Ascii());
return response->CreateCorsFilteredResponse(header_names);
@@ -85,11 +85,11 @@ FetchResponseData* CreateFetchResponseDataFromFetchAPIResponse(
script_state, fetch_api_response);
if (fetch_api_response.blob) {
- response->ReplaceBodyStreamBuffer(MakeGarbageCollected<BodyStreamBuffer>(
+ response->ReplaceBodyStreamBuffer(BodyStreamBuffer::Create(
script_state,
MakeGarbageCollected<BlobBytesConsumer>(
ExecutionContext::From(script_state), fetch_api_response.blob),
- nullptr /* AbortSignal */));
+ nullptr /* AbortSignal */, fetch_api_response.side_data_blob));
}
// Filter the response according to |fetch_api_response|'s ResponseType.
@@ -148,7 +148,7 @@ Response* Response::Create(ScriptState* script_state,
// https://crbug.com/335871.
} else if (V8Blob::HasInstance(body, isolate)) {
Blob* blob = V8Blob::ToImpl(body.As<v8::Object>());
- body_buffer = MakeGarbageCollected<BodyStreamBuffer>(
+ body_buffer = BodyStreamBuffer::Create(
script_state,
MakeGarbageCollected<BlobBytesConsumer>(execution_context,
blob->GetBlobDataHandle()),
@@ -158,18 +158,32 @@ Response* Response::Create(ScriptState* script_state,
// Avoid calling into V8 from the following constructor parameters, which
// is potentially unsafe.
DOMArrayBuffer* array_buffer = V8ArrayBuffer::ToImpl(body.As<v8::Object>());
- body_buffer = MakeGarbageCollected<BodyStreamBuffer>(
- script_state, MakeGarbageCollected<FormDataBytesConsumer>(array_buffer),
- nullptr /* AbortSignal */);
+ if (!base::CheckedNumeric<wtf_size_t>(array_buffer->ByteLengthAsSizeT())
+ .IsValid()) {
+ exception_state.ThrowRangeError(
+ "The provided ArrayBuffer exceeds the maximum supported size");
+ } else {
+ body_buffer = BodyStreamBuffer::Create(
+ script_state,
+ MakeGarbageCollected<FormDataBytesConsumer>(array_buffer),
+ nullptr /* AbortSignal */);
+ }
} else if (body->IsArrayBufferView()) {
// Avoid calling into V8 from the following constructor parameters, which
// is potentially unsafe.
DOMArrayBufferView* array_buffer_view =
V8ArrayBufferView::ToImpl(body.As<v8::Object>());
- body_buffer = MakeGarbageCollected<BodyStreamBuffer>(
- script_state,
- MakeGarbageCollected<FormDataBytesConsumer>(array_buffer_view),
- nullptr /* AbortSignal */);
+ if (!base::CheckedNumeric<wtf_size_t>(
+ array_buffer_view->byteLengthAsSizeT())
+ .IsValid()) {
+ exception_state.ThrowRangeError(
+ "The provided ArrayBufferView exceeds the maximum supported size");
+ } else {
+ body_buffer = BodyStreamBuffer::Create(
+ script_state,
+ MakeGarbageCollected<FormDataBytesConsumer>(array_buffer_view),
+ nullptr /* AbortSignal */);
+ }
} else if (V8FormData::HasInstance(body, isolate)) {
scoped_refptr<EncodedFormData> form_data =
V8FormData::ToImpl(body.As<v8::Object>())->EncodeMultiPartFormData();
@@ -177,19 +191,19 @@ Response* Response::Create(ScriptState* script_state,
// FormDataEncoder::generateUniqueBoundaryString.
content_type = AtomicString("multipart/form-data; boundary=") +
form_data->Boundary().data();
- body_buffer = MakeGarbageCollected<BodyStreamBuffer>(
- script_state,
- MakeGarbageCollected<FormDataBytesConsumer>(execution_context,
- std::move(form_data)),
- nullptr /* AbortSignal */);
+ body_buffer =
+ BodyStreamBuffer::Create(script_state,
+ MakeGarbageCollected<FormDataBytesConsumer>(
+ execution_context, std::move(form_data)),
+ nullptr /* AbortSignal */);
} else if (V8URLSearchParams::HasInstance(body, isolate)) {
scoped_refptr<EncodedFormData> form_data =
V8URLSearchParams::ToImpl(body.As<v8::Object>())->ToEncodedFormData();
- body_buffer = MakeGarbageCollected<BodyStreamBuffer>(
- script_state,
- MakeGarbageCollected<FormDataBytesConsumer>(execution_context,
- std::move(form_data)),
- nullptr /* AbortSignal */);
+ body_buffer =
+ BodyStreamBuffer::Create(script_state,
+ MakeGarbageCollected<FormDataBytesConsumer>(
+ execution_context, std::move(form_data)),
+ nullptr /* AbortSignal */);
content_type = "application/x-www-form-urlencoded;charset=UTF-8";
} else if (V8ReadableStream::HasInstance(body, isolate)) {
UseCounter::Count(execution_context,
@@ -201,7 +215,7 @@ Response* Response::Create(ScriptState* script_state,
isolate, body, exception_state);
if (exception_state.HadException())
return nullptr;
- body_buffer = MakeGarbageCollected<BodyStreamBuffer>(
+ body_buffer = BodyStreamBuffer::Create(
script_state, MakeGarbageCollected<FormDataBytesConsumer>(string),
nullptr /* AbortSignal */);
content_type = "text/plain;charset=UTF-8";
@@ -370,7 +384,8 @@ FetchResponseData* Response::CreateUnfilteredFetchResponseDataWithoutBody(
response->SetResponseTime(fetch_api_response.response_time);
response->SetCacheStorageCacheName(
fetch_api_response.cache_storage_cache_name);
- response->SetSideDataBlob(fetch_api_response.side_data_blob);
+ response->SetLoadedWithCredentials(
+ fetch_api_response.loaded_with_credentials);
for (const auto& header : fetch_api_response.headers)
response->HeaderList()->Append(header.key, header.value);
@@ -539,7 +554,7 @@ FetchHeaderList* Response::InternalHeaderList() const {
return response_->InternalHeaderList();
}
-void Response::Trace(blink::Visitor* visitor) {
+void Response::Trace(Visitor* visitor) {
Body::Trace(visitor);
visitor->Trace(response_);
visitor->Trace(headers_);
diff --git a/chromium/third_party/blink/renderer/core/fetch/response.h b/chromium/third_party/blink/renderer/core/fetch/response.h
index 025462825b4..758d6042a7c 100644
--- a/chromium/third_party/blink/renderer/core/fetch/response.h
+++ b/chromium/third_party/blink/renderer/core/fetch/response.h
@@ -86,7 +86,7 @@ class CORE_EXPORT Response final : public Body {
// ScriptWrappable
bool HasPendingActivity() const final;
- // Does not contain the blob response body.
+ // Does not contain the blob response body or any side data blob.
// |request_url| is the current request URL that resulted in the response. It
// is needed to process some response headers (e.g. CSP).
// TODO(lfg, kinuko): The FetchResponseData::url_list_ should include the
@@ -121,7 +121,7 @@ class CORE_EXPORT Response final : public Body {
FetchHeaderList* InternalHeaderList() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
// A version of IsBodyUsed() which catches exceptions and returns
diff --git a/chromium/third_party/blink/renderer/core/fetch/response.idl b/chromium/third_party/blink/renderer/core/fetch/response.idl
index dac40e50960..1ae9071c6c5 100644
--- a/chromium/third_party/blink/renderer/core/fetch/response.idl
+++ b/chromium/third_party/blink/renderer/core/fetch/response.idl
@@ -8,13 +8,11 @@ enum ResponseType { "basic", "cors", "default", "error", "opaque", "opaqueredire
[
ActiveScriptWrappable,
+ Exposed=(Window,Worker)
+] interface Response {
// TODO(yhirano): We use "any" for body because the IDL processor doesn't
// recognize ReadableStream implemented with V8 extras. Fix it.
- Constructor(optional any body, optional ResponseInit init),
- ConstructorCallWith=ScriptState,
- Exposed=(Window,Worker),
- RaisesException=Constructor
-] interface Response {
+ [CallWith=ScriptState, RaisesException] constructor(optional any body, optional ResponseInit init = {});
[CallWith=ScriptState, NewObject] static Response error();
[CallWith=ScriptState, NewObject, RaisesException] static Response redirect(USVString url, optional unsigned short status = 302);
readonly attribute ResponseType type;
diff --git a/chromium/third_party/blink/renderer/core/fetch/response_test.cc b/chromium/third_party/blink/renderer/core/fetch/response_test.cc
index 019b2009aa9..a2808538d1e 100644
--- a/chromium/third_party/blink/renderer/core/fetch/response_test.cc
+++ b/chromium/third_party/blink/renderer/core/fetch/response_test.cc
@@ -13,6 +13,7 @@
#include "third_party/blink/renderer/core/fetch/bytes_consumer_test_util.h"
#include "third_party/blink/renderer/core/fetch/fetch_response_data.h"
#include "third_party/blink/renderer/core/frame/frame.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
@@ -35,7 +36,7 @@ TEST(ServiceWorkerResponseTest, FromFetchResponseData) {
url_list.push_back(url);
fetch_response_data->SetURLList(url_list);
Response* response =
- Response::Create(&page->GetDocument(), fetch_response_data);
+ Response::Create(page->GetFrame().DomWindow(), fetch_response_data);
DCHECK(response);
EXPECT_EQ(url, response->url());
}
@@ -100,7 +101,7 @@ BodyStreamBuffer* CreateHelloWorldBuffer(ScriptState* script_state) {
src->Add(Command(Command::kData, "Hello, "));
src->Add(Command(Command::kData, "world"));
src->Add(Command(Command::kDone));
- return MakeGarbageCollected<BodyStreamBuffer>(script_state, src, nullptr);
+ return BodyStreamBuffer::Create(script_state, src, nullptr);
}
TEST(ServiceWorkerResponseTest, BodyStreamBufferCloneDefault) {
@@ -164,7 +165,7 @@ TEST(ServiceWorkerResponseTest, BodyStreamBufferCloneOpaque) {
TEST(ServiceWorkerResponseTest, BodyStreamBufferCloneError) {
V8TestingScope scope;
- BodyStreamBuffer* buffer = MakeGarbageCollected<BodyStreamBuffer>(
+ BodyStreamBuffer* buffer = BodyStreamBuffer::Create(
scope.GetScriptState(),
BytesConsumer::CreateErrored(BytesConsumer::Error()), nullptr);
FetchResponseData* fetch_response_data =
diff --git a/chromium/third_party/blink/renderer/core/fetch/trust_token.idl b/chromium/third_party/blink/renderer/core/fetch/trust_token.idl
new file mode 100644
index 00000000000..a2b595ec9ac
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/fetch/trust_token.idl
@@ -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.
+
+enum RefreshPolicy { "none", "refresh" };
+enum OperationType { "token-request", "send-srr", "srr-token-redemption" };
+enum SignRequestData { "omit", "include", "headers-only" };
+
+// A TrustToken object represents a request to execute a Trust Tokens protocol
+// operation (https://github.com/wicg/trust-token-api).
+dictionary TrustToken {
+ // |type| is the only required parameter; all other parameters are necessary
+ // only for certain operations.
+ required OperationType type;
+
+ // --- Parameters only for token redemption
+ // The following parameters are ignored unless |type| is
+ // "srr-token-redemption":
+ // 1. refreshPolicy
+ RefreshPolicy refreshPolicy = "none";
+
+ // --- Parameters only for request signing
+ // The following parameters are ignored unless |type| is "send-srr":
+ // 1. |issuer|
+ // 2. |additionalSignedHeaders|
+ // 3. |includeTimestampHeader|
+ // 4. |signRequestData|
+ //
+ // Additionally, |issuer| is required when |type| is "send-srr".
+ USVString issuer;
+ sequence<USVString> additionalSignedHeaders;
+ boolean includeTimestampHeader = false;
+ SignRequestData signRequestData = "omit";
+};
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
new file mode 100644
index 00000000000..1fe53b72d8b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/fetch/trust_token_to_mojom.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/fetch/trust_token_to_mojom.h"
+
+namespace blink {
+
+bool ConvertTrustTokenToMojom(const TrustToken& in,
+ ExceptionState* exception_state,
+ network::mojom::blink::TrustTokenParams* out) {
+ DCHECK(in.hasType()); // field is required in IDL
+ if (in.type() == "token-request") {
+ out->type = network::mojom::blink::TrustTokenOperationType::kIssuance;
+ return true;
+ }
+
+ if (in.type() == "srr-token-redemption") {
+ out->type = network::mojom::blink::TrustTokenOperationType::kRedemption;
+
+ DCHECK(in.hasRefreshPolicy()); // default is defined
+ out->include_timestamp_header = in.includeTimestampHeader();
+
+ if (in.refreshPolicy() == "none") {
+ out->refresh_policy =
+ network::mojom::blink::TrustTokenRefreshPolicy::kUseCached;
+ } else if (in.refreshPolicy() == "refresh") {
+ out->refresh_policy =
+ network::mojom::blink::TrustTokenRefreshPolicy::kRefresh;
+ }
+ return true;
+ }
+
+ DCHECK_EQ(in.type(), "send-srr"); // final possible value of the input enum
+ out->type = network::mojom::blink::TrustTokenOperationType::kSigning;
+
+ if (in.hasSignRequestData()) {
+ if (in.signRequestData() == "omit") {
+ out->sign_request_data =
+ network::mojom::blink::TrustTokenSignRequestData::kOmit;
+ } else if (in.signRequestData() == "include") {
+ out->sign_request_data =
+ network::mojom::blink::TrustTokenSignRequestData::kInclude;
+ } else if (in.signRequestData() == "headers-only") {
+ out->sign_request_data =
+ network::mojom::blink::TrustTokenSignRequestData::kHeadersOnly;
+ }
+ }
+
+ if (in.hasAdditionalSignedHeaders()) {
+ out->additional_signed_headers = in.additionalSignedHeaders();
+ }
+
+ DCHECK(in.hasIncludeTimestampHeader()); // default is defined
+ out->include_timestamp_header = in.includeTimestampHeader();
+
+ if (in.hasIssuer()) {
+ // Two conditions on the issuer:
+ // 1. HTTP or HTTPS (because much Trust Tokens protocol state is
+ // stored keyed by issuer origin, requiring HTTP or HTTPS is a way to ensure
+ // these origins serialize to unique values);
+ // 2. potentially trustworthy (a security requirement).
+ KURL parsed_url = KURL(in.issuer());
+ if (!parsed_url.ProtocolIsInHTTPFamily()) {
+ exception_state->ThrowTypeError(
+ "trustToken: operation type 'send-srr' requires that the 'issuer' "
+ "field parse to a HTTP(S) origin, but it did not: " +
+ in.issuer());
+ return false;
+ }
+ out->issuer = blink::SecurityOrigin::Create(parsed_url);
+ if (!out->issuer->IsPotentiallyTrustworthy()) {
+ exception_state->ThrowTypeError(
+ "trustToken: operation type 'send-srr' requires that the 'issuer' "
+ "field parse to a secure origin, but it did not: " +
+ in.issuer());
+ return false;
+ }
+ } else {
+ exception_state->ThrowTypeError(
+ "trustToken: operation type 'send-srr' requires that the 'issuer' "
+ "field "
+ "be present and parse to a secure HTTP(S) URL, but it was missing.");
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/fetch/trust_token_to_mojom.h b/chromium/third_party/blink/renderer/core/fetch/trust_token_to_mojom.h
new file mode 100644
index 00000000000..a18f2a245b8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/fetch/trust_token_to_mojom.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_FETCH_TRUST_TOKEN_TO_MOJOM_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_TRUST_TOKEN_TO_MOJOM_H_
+
+#include "services/network/public/mojom/trust_tokens.mojom-blink.h"
+#include "third_party/blink/renderer/core/fetch/trust_token.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+
+namespace blink {
+
+// Converts an IDL trustToken object to its Mojo counterpart.
+// The elements of trustToken (and of TrustTokenParams) comprise:
+// - an operation type, always populated
+// - remaining elements partitioned into groups of parameters used for specific
+// operations.
+//
+// The method sets only |type| and the fields corresponding to the operation
+// specified by |type|, namely
+// - for issuance, no additional fields;
+// - for redemption, |refresh_policy|;
+// - for signing: |issuer|, |additional_signed_headers|, |sign_request_data|,
+// and |include_timestamp_header|.
+//
+// Performs some validity checking against inputs:
+// - for signing, |issuer| must be provided and must be a valid HTTP(S) URL.
+// If this validation fails, throws a TypeError against |exception_state| and
+// returns false.
+bool ConvertTrustTokenToMojom(const TrustToken& in,
+ ExceptionState* exception_state,
+ network::mojom::blink::TrustTokenParams* out);
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_TRUST_TOKEN_TO_MOJOM_H_
diff --git a/chromium/third_party/blink/renderer/core/fetch/window_fetch.idl b/chromium/third_party/blink/renderer/core/fetch/window_fetch.idl
index a6170ea1a8e..75b91796b71 100644
--- a/chromium/third_party/blink/renderer/core/fetch/window_fetch.idl
+++ b/chromium/third_party/blink/renderer/core/fetch/window_fetch.idl
@@ -2,8 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// https://fetch.spec.whatwg.org/#fetch-method
+
[
ImplementedAs=GlobalFetch
] partial interface Window {
- [CallWith=ScriptState, NewObject, RaisesException] Promise<Response> fetch(RequestInfo input, optional RequestInit init);
+ [CallWith=ScriptState, NewObject, RaisesException] Promise<Response> fetch(RequestInfo input, optional RequestInit init = {});
};
diff --git a/chromium/third_party/blink/renderer/core/fetch/worker_fetch.idl b/chromium/third_party/blink/renderer/core/fetch/worker_fetch.idl
index b210f6cfee6..e6d276dbb3e 100644
--- a/chromium/third_party/blink/renderer/core/fetch/worker_fetch.idl
+++ b/chromium/third_party/blink/renderer/core/fetch/worker_fetch.idl
@@ -2,8 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// https://fetch.spec.whatwg.org/#fetch-method
+
[
ImplementedAs=GlobalFetch
] partial interface WorkerGlobalScope {
- [CallWith=ScriptState, NewObject, RaisesException] Promise<Response> fetch(RequestInfo input, optional RequestInit init);
+ [CallWith=ScriptState, NewObject, RaisesException] Promise<Response> fetch(RequestInfo input, optional RequestInit init = {});
};
diff --git a/chromium/third_party/blink/renderer/core/fileapi/blob.cc b/chromium/third_party/blink/renderer/core/fileapi/blob.cc
index 8d9fbf000a2..9ef29e6f396 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/blob.cc
+++ b/chromium/third_party/blink/renderer/core/fileapi/blob.cc
@@ -33,10 +33,10 @@
#include <memory>
#include <utility>
+#include "third_party/blink/renderer/bindings/core/v8/v8_blob_property_bag.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/fetch/blob_bytes_consumer.h"
#include "third_party/blink/renderer/core/fetch/body_stream_buffer.h"
-#include "third_party/blink/renderer/core/fileapi/blob_property_bag.h"
#include "third_party/blink/renderer/core/fileapi/file_reader_loader.h"
#include "third_party/blink/renderer/core/fileapi/file_reader_loader_client.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
@@ -216,7 +216,7 @@ Blob* Blob::slice(int64_t start,
}
ReadableStream* Blob::stream(ScriptState* script_state) const {
- BodyStreamBuffer* body_buffer = MakeGarbageCollected<BodyStreamBuffer>(
+ BodyStreamBuffer* body_buffer = BodyStreamBuffer::Create(
script_state,
MakeGarbageCollected<BlobBytesConsumer>(
ExecutionContext::From(script_state), blob_data_handle_),
diff --git a/chromium/third_party/blink/renderer/core/fileapi/blob.idl b/chromium/third_party/blink/renderer/core/fileapi/blob.idl
index 3bc8654e922..404de753562 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/blob.idl
+++ b/chromium/third_party/blink/renderer/core/fileapi/blob.idl
@@ -32,17 +32,16 @@
typedef (ArrayBuffer or ArrayBufferView or Blob or USVString) BlobPart;
[
- Constructor(optional sequence<BlobPart> blobParts, optional BlobPropertyBag options),
- ConstructorCallWith=ExecutionContext,
Exposed=(Window,Worker),
Serializable
] interface Blob {
+ [CallWith=ExecutionContext] constructor(optional sequence<BlobPart> blobParts, optional BlobPropertyBag options = {});
readonly attribute unsigned long long size;
readonly attribute DOMString type;
// TODO(jsbell): start and end arguments should be [Clamp]
[RaisesException] Blob slice(optional long long start, optional long long end, optional DOMString contentType);
- [CallWith=ScriptState, RuntimeEnabled=BlobReadMethods] ReadableStream stream();
- [CallWith=ScriptState, RuntimeEnabled=BlobReadMethods] Promise<USVString> text();
- [CallWith=ScriptState, RuntimeEnabled=BlobReadMethods] Promise<ArrayBuffer> arrayBuffer();
+ [CallWith=ScriptState] ReadableStream stream();
+ [CallWith=ScriptState] Promise<USVString> text();
+ [CallWith=ScriptState] Promise<ArrayBuffer> arrayBuffer();
};
diff --git a/chromium/third_party/blink/renderer/core/fileapi/file.cc b/chromium/third_party/blink/renderer/core/fileapi/file.cc
index b94b64e094c..bd08b09bfa6 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/file.cc
+++ b/chromium/third_party/blink/renderer/core/fileapi/file.cc
@@ -29,7 +29,7 @@
#include "third_party/blink/public/platform/file_path_conversion.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/renderer/core/fileapi/file_property_bag.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_file_property_bag.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/html/forms/form_controller.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -239,7 +239,6 @@ File::File(const String& name,
has_backing_file_(false),
user_visibility_(File::kIsNotUserVisible),
name_(name),
- snapshot_size_(Blob::size()),
snapshot_modification_time_(modification_time) {
uint64_t size = Blob::size();
if (size != std::numeric_limits<uint64_t>::max())
@@ -272,9 +271,9 @@ File::File(const KURL& file_system_url,
name_(DecodeURLEscapeSequences(file_system_url.LastPathComponent(),
DecodeURLMode::kUTF8OrIsomorphic)),
file_system_url_(file_system_url),
+ snapshot_size_(metadata.length),
snapshot_modification_time_(metadata.modification_time) {
- if (metadata.length >= 0)
- snapshot_size_ = metadata.length;
+ DCHECK_GE(metadata.length, 0);
}
File::File(const File& other)
@@ -296,14 +295,11 @@ File* File::Clone(const String& name) const {
}
base::Time File::LastModifiedTime() const {
+ CaptureSnapshotIfNeeded();
+
if (HasValidSnapshotMetadata() && snapshot_modification_time_)
return *snapshot_modification_time_;
- base::Optional<base::Time> modification_time;
- if (HasBackingFile() && GetFileModificationTime(path_, modification_time) &&
- modification_time)
- return *modification_time;
-
// lastModified / lastModifiedDate getters should return the current time
// when the last modification time isn't known.
return base::Time::Now();
@@ -322,16 +318,21 @@ ScriptValue File::lastModifiedDate(ScriptState* script_state) const {
ToV8(LastModifiedTime(), script_state));
}
+base::Optional<base::Time> File::LastModifiedTimeForSerialization() const {
+ CaptureSnapshotIfNeeded();
+
+ return snapshot_modification_time_;
+}
+
uint64_t File::size() const {
- if (HasValidSnapshotMetadata())
- return *snapshot_size_;
+ CaptureSnapshotIfNeeded();
// FIXME: JavaScript cannot represent sizes as large as uint64_t, we need
// to come up with an exception to throw if file size is not representable.
- int64_t size;
- if (!HasBackingFile() || !GetFileSize(path_, size))
- return 0;
- return static_cast<uint64_t>(size);
+ if (HasValidSnapshotMetadata())
+ return *snapshot_size_;
+
+ return 0;
}
Blob* File::slice(int64_t start,
@@ -341,44 +342,30 @@ Blob* File::slice(int64_t start,
if (!has_backing_file_)
return Blob::slice(start, end, content_type, exception_state);
- // FIXME: This involves synchronous file operation. We need to figure out how
- // to make it asynchronous.
- uint64_t size;
- base::Optional<base::Time> modification_time;
- CaptureSnapshot(size, modification_time);
- ClampSliceOffsets(size, start, end);
+ // FIXME: Calling size triggers capturing a snapshot, if we don't have one
+ // already. This involves synchronous file operation. We need to figure out
+ // how to make it asynchronous (or make sure snapshot state is always passed
+ // in when creating a File instance).
+ ClampSliceOffsets(size(), start, end);
uint64_t length = end - start;
auto blob_data = std::make_unique<BlobData>();
blob_data->SetContentType(NormalizeType(content_type));
DCHECK(!path_.IsEmpty());
- blob_data->AppendFile(path_, start, length, modification_time);
+ blob_data->AppendFile(path_, start, length, snapshot_modification_time_);
return MakeGarbageCollected<Blob>(
BlobDataHandle::Create(std::move(blob_data), length));
}
-void File::CaptureSnapshot(
- uint64_t& snapshot_size,
- base::Optional<base::Time>& snapshot_modification_time) const {
- if (HasValidSnapshotMetadata()) {
- snapshot_size = *snapshot_size_;
- snapshot_modification_time = snapshot_modification_time_;
+void File::CaptureSnapshotIfNeeded() const {
+ if (HasValidSnapshotMetadata() && snapshot_modification_time_)
return;
- }
- // Obtains a snapshot of the file by capturing its current size and
- // modification time. This is used when we slice a file for the first time.
- // If we fail to retrieve the size or modification time, probably due to that
- // the file has been deleted, 0 size is returned.
- FileMetadata metadata;
- if (!HasBackingFile() || !GetFileMetadata(path_, metadata)) {
- snapshot_size = 0;
- snapshot_modification_time = base::nullopt;
- return;
+ uint64_t snapshot_size;
+ if (GetBlobDataHandle()->CaptureSnapshot(&snapshot_size,
+ &snapshot_modification_time_)) {
+ snapshot_size_ = snapshot_size;
}
-
- snapshot_size = static_cast<uint64_t>(metadata.length);
- snapshot_modification_time = metadata.modification_time;
}
void File::AppendTo(BlobData& blob_data) const {
@@ -389,11 +376,9 @@ void File::AppendTo(BlobData& blob_data) const {
// FIXME: This involves synchronous file operation. We need to figure out how
// to make it asynchronous.
- uint64_t size;
- base::Optional<base::Time> modification_time;
- CaptureSnapshot(size, modification_time);
+ CaptureSnapshotIfNeeded();
DCHECK(!path_.IsEmpty());
- blob_data.AppendFile(path_, 0, size, modification_time);
+ blob_data.AppendFile(path_, 0, *snapshot_size_, snapshot_modification_time_);
}
bool File::HasSameSource(const File& other) const {
diff --git a/chromium/third_party/blink/renderer/core/fileapi/file.h b/chromium/third_party/blink/renderer/core/fileapi/file.h
index 7ea8ad8fd16..e9707e037d0 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/file.h
+++ b/chromium/third_party/blink/renderer/core/fileapi/file.h
@@ -83,14 +83,13 @@ class CORE_EXPORT File final : public Blob {
last_modified, std::move(blob_data_handle));
}
static File* CreateFromIndexedSerialization(
- const String& path,
const String& name,
uint64_t size,
const base::Optional<base::Time>& last_modified,
scoped_refptr<BlobDataHandle> blob_data_handle) {
- return MakeGarbageCollected<File>(path, name, String(), kIsNotUserVisible,
- true, size, last_modified,
- std::move(blob_data_handle));
+ return MakeGarbageCollected<File>(
+ String(), name, String(), kIsNotUserVisible, true, size, last_modified,
+ std::move(blob_data_handle));
}
// For session restore feature.
@@ -205,18 +204,20 @@ class CORE_EXPORT File final : public Blob {
// If the modification time isn't known, the current time is returned.
base::Time LastModifiedTime() const;
+ // Similar to |LastModifiedTime()|, except this returns base::nullopt rather
+ // than the current time if the modified time is unknown.
+ // This is used by SerializedScriptValue to serialize the last modified time
+ // of a File object.
+ // This method calls CaptureSnapshotIfNeeded, and thus can involve synchronous
+ // IPC and file operations.
+ base::Optional<base::Time> LastModifiedTimeForSerialization() const;
+
UserVisibility GetUserVisibility() const { return user_visibility_; }
// Returns the relative path of this file in the context of a directory
// selection.
const String& webkitRelativePath() const { return relative_path_; }
- // Note that this involves synchronous file operation. Think twice before
- // calling this function.
- void CaptureSnapshot(
- uint64_t& snapshot_size,
- base::Optional<base::Time>& snapshot_modification_time) const;
-
// Returns true if this has a valid snapshot metadata
// (i.e. snapshot_size_.has_value()).
bool HasValidSnapshotMetadata() const { return snapshot_size_.has_value(); }
@@ -229,7 +230,9 @@ class CORE_EXPORT File final : public Blob {
bool AppendToControlState(FormControlState& state);
private:
- void InvalidateSnapshotMetadata() { snapshot_size_.reset(); }
+ // Note that this involves synchronous file operation. Think twice before
+ // calling this function.
+ void CaptureSnapshotIfNeeded() const;
#if DCHECK_IS_ON()
// Instances backed by a file must have an empty file system URL.
@@ -251,8 +254,8 @@ class CORE_EXPORT File final : public Blob {
// we retrieve the latest metadata synchronously in size(),
// LastModifiedTime() and slice().
// Otherwise, the snapshot metadata are used directly in those methods.
- base::Optional<uint64_t> snapshot_size_;
- const base::Optional<base::Time> snapshot_modification_time_;
+ mutable base::Optional<uint64_t> snapshot_size_;
+ mutable base::Optional<base::Time> snapshot_modification_time_;
String relative_path_;
};
diff --git a/chromium/third_party/blink/renderer/core/fileapi/file.idl b/chromium/third_party/blink/renderer/core/fileapi/file.idl
index e5cf6cc926f..4339a27e87c 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/file.idl
+++ b/chromium/third_party/blink/renderer/core/fileapi/file.idl
@@ -26,11 +26,10 @@
// https://w3c.github.io/FileAPI/#file-section
[
- Constructor(sequence<BlobPart> fileBits, USVString fileName, optional FilePropertyBag options),
- ConstructorCallWith=ExecutionContext,
Exposed=(Window,Worker),
Serializable
] interface File : Blob {
+ [CallWith=ExecutionContext] constructor(sequence<BlobPart> fileBits, USVString fileName, optional FilePropertyBag options = {});
readonly attribute DOMString name;
readonly attribute long long lastModified;
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 323cae340e2..4d9ef43b18a 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(blink::Visitor* visitor) {
+void FileList::Trace(Visitor* visitor) {
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 934bf5d8b28..b66623bfd8d 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
HeapVector<Member<File>> files_;
diff --git a/chromium/third_party/blink/renderer/core/fileapi/file_list_test.cc b/chromium/third_party/blink/renderer/core/fileapi/file_list_test.cc
index 6190cc6dbc7..74b343813b5 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/file_list_test.cc
+++ b/chromium/third_party/blink/renderer/core/fileapi/file_list_test.cc
@@ -42,8 +42,10 @@ TEST(FileListTest, pathsForUserVisibleFiles) {
{
KURL url(
"filesystem:http://example.com/isolated/hash/visible-non-native-file");
- file_list->Append(File::CreateForFileSystemFile(url, FileMetadata(),
- File::kIsUserVisible));
+ FileMetadata metadata;
+ metadata.length = 0;
+ file_list->Append(
+ File::CreateForFileSystemFile(url, metadata, File::kIsUserVisible));
}
// Not user visible file system URL file.
@@ -51,8 +53,10 @@ TEST(FileListTest, pathsForUserVisibleFiles) {
KURL url(
"filesystem:http://example.com/isolated/hash/"
"not-visible-non-native-file");
- file_list->Append(File::CreateForFileSystemFile(url, FileMetadata(),
- File::kIsNotUserVisible));
+ FileMetadata metadata;
+ metadata.length = 0;
+ file_list->Append(
+ File::CreateForFileSystemFile(url, metadata, File::kIsNotUserVisible));
}
Vector<base::FilePath> paths = file_list->PathsForUserVisibleFiles();
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 be64b8a7647..e556e849c64 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(pending_readers_);
visitor->Trace(running_readers_);
Supplement<ExecutionContext>::Trace(visitor);
@@ -198,7 +198,7 @@ FileReader* FileReader::Create(ExecutionContext* context) {
}
FileReader::FileReader(ExecutionContext* context)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
state_(kEmpty),
loading_state_(kLoadingStateNone),
still_firing_events_(false),
@@ -212,12 +212,13 @@ const AtomicString& FileReader::InterfaceName() const {
return event_target_names::kFileReader;
}
-void FileReader::ContextDestroyed(ExecutionContext* destroyed_context) {
+void FileReader::ContextDestroyed() {
// The delayed abort task tidies up and advances to the DONE state.
if (loading_state_ == kLoadingStateAborted)
return;
if (HasPendingActivity()) {
+ ExecutionContext* destroyed_context = GetExecutionContext();
ThrottlingController::FinishReader(
destroyed_context, this,
ThrottlingController::RemoveReader(destroyed_context, this));
@@ -292,7 +293,8 @@ void FileReader::ReadInternal(Blob* blob,
// A document loader will not load new resources once the Document has
// detached from its frame.
- if (IsA<Document>(context) && !To<Document>(context)->GetFrame()) {
+ Document* document = Document::DynamicFrom(context);
+ if (document && !document->GetFrame()) {
exception_state.ThrowDOMException(
DOMExceptionCode::kAbortError,
"Reading from a Document-detached FileReader is not supported.");
@@ -474,10 +476,10 @@ void FileReader::FireEvent(const AtomicString& type) {
}
}
-void FileReader::Trace(blink::Visitor* visitor) {
+void FileReader::Trace(Visitor* visitor) {
visitor->Trace(error_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 1b45c604844..7e763d550e8 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/file_reader.h
+++ b/chromium/third_party/blink/renderer/core/fileapi/file_reader.h
@@ -36,7 +36,7 @@
#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/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/fileapi/file_reader_loader.h"
#include "third_party/blink/renderer/core/fileapi/file_reader_loader_client.h"
#include "third_party/blink/renderer/core/probe/async_task_id.h"
@@ -53,7 +53,7 @@ class StringOrArrayBuffer;
class CORE_EXPORT FileReader final : public EventTargetWithInlineData,
public ActiveScriptWrappable<FileReader>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public FileReaderLoaderClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(FileReader);
@@ -78,8 +78,8 @@ class CORE_EXPORT FileReader final : public EventTargetWithInlineData,
void result(ScriptState*, StringOrArrayBuffer& result_attribute) const;
probe::AsyncTaskId* async_task_id() { return &async_task_id_; }
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
// ScriptWrappable
bool HasPendingActivity() const final;
@@ -87,7 +87,7 @@ class CORE_EXPORT FileReader final : public EventTargetWithInlineData,
// EventTarget
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
// FileReaderLoaderClient
@@ -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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
class ThrottlingController;
diff --git a/chromium/third_party/blink/renderer/core/fileapi/file_reader.idl b/chromium/third_party/blink/renderer/core/fileapi/file_reader.idl
index ab2c692417e..06537670696 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/file_reader.idl
+++ b/chromium/third_party/blink/renderer/core/fileapi/file_reader.idl
@@ -33,10 +33,9 @@
[
ActiveScriptWrappable,
- Constructor,
- ConstructorCallWith=ExecutionContext,
Exposed=(Window,Worker)
] interface FileReader : EventTarget {
+ [CallWith=ExecutionContext] constructor();
// async read methods
[RaisesException] void readAsArrayBuffer(Blob blob);
[RaisesException] void readAsBinaryString(Blob blob);
diff --git a/chromium/third_party/blink/renderer/core/fileapi/file_reader_loader.cc b/chromium/third_party/blink/renderer/core/fileapi/file_reader_loader.cc
index cfc1297a5bf..361e00b3a8a 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/file_reader_loader.cc
+++ b/chromium/third_party/blink/renderer/core/fileapi/file_reader_loader.cc
@@ -67,17 +67,11 @@ FileReaderLoader::FileReaderLoader(
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
: read_type_(read_type),
client_(client),
- // TODO(https://crbug.com/957651): task_runner should never be null, but
- // if it is make sure SimpleWatcher doesn't crash and just use a default
- // task runner instead for now.
- handle_watcher_(
- FROM_HERE,
- mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC,
- task_runner ? task_runner : base::SequencedTaskRunnerHandle::Get()),
+ handle_watcher_(FROM_HERE,
+ mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC,
+ task_runner),
task_runner_(std::move(task_runner)) {
- // TODO(https://crbug.com/957651): Change this into a DCHECK once we figured
- // out where code is passing in a null task runner,
- CHECK(task_runner_);
+ DCHECK(task_runner_);
}
FileReaderLoader::~FileReaderLoader() {
@@ -147,7 +141,7 @@ DOMArrayBuffer* FileReaderLoader::ArrayBufferResult() {
SafeCast<size_t>(bytes_loaded_));
}
- array_buffer_result_ = DOMArrayBuffer::Create(raw_data_);
+ array_buffer_result_ = DOMArrayBuffer::Create(std::move(raw_data_));
DCHECK_EQ(raw_data_.DataLength(), 0u);
raw_data_.Reset();
return array_buffer_result_;
diff --git a/chromium/third_party/blink/renderer/core/fileapi/file_reader_loader.h b/chromium/third_party/blink/renderer/core/fileapi/file_reader_loader.h
index 2ac325d052c..31682e59302 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/file_reader_loader.h
+++ b/chromium/third_party/blink/renderer/core/fileapi/file_reader_loader.h
@@ -38,7 +38,6 @@
#include "third_party/blink/public/mojom/blob/blob.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/fileapi/file_error.h"
-#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h"
#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -174,6 +173,9 @@ class CORE_EXPORT FileReaderLoader : public mojom::blink::BlobReaderClient {
mojo::ScopedDataPipeConsumerHandle consumer_handle_;
mojo::SimpleWatcher handle_watcher_;
+ // TODO(crbug.com/937038, crbug.com/1049056): Make FileReaderLoaderClient
+ // GarbageCollected. It will then be possible to use the HeapMojoReceiver
+ // wrapper for receiver_.
mojo::Receiver<mojom::blink::BlobReaderClient> receiver_{this};
bool received_all_data_ = false;
bool received_on_complete_ = false;
diff --git a/chromium/third_party/blink/renderer/core/fileapi/file_reader_sync.idl b/chromium/third_party/blink/renderer/core/fileapi/file_reader_sync.idl
index 2f8ef263c0c..9f7d0281042 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/file_reader_sync.idl
+++ b/chromium/third_party/blink/renderer/core/fileapi/file_reader_sync.idl
@@ -31,11 +31,9 @@
// https://w3c.github.io/FileAPI/#FileReaderSync
[
- Exposed=(DedicatedWorker,SharedWorker),
- Constructor,
- ConstructorCallWith=ExecutionContext,
- Measure
+ Exposed=(DedicatedWorker,SharedWorker)
] interface FileReaderSync {
+ [CallWith=ExecutionContext, Measure] constructor();
[RaisesException] ArrayBuffer readAsArrayBuffer(Blob blob);
[RaisesException] DOMString readAsBinaryString(Blob blob);
[RaisesException] DOMString readAsText(Blob blob, optional DOMString label);
diff --git a/chromium/third_party/blink/renderer/core/fileapi/file_test.cc b/chromium/third_party/blink/renderer/core/fileapi/file_test.cc
index 399d9aa9adc..53daeaf7560 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/file_test.cc
+++ b/chromium/third_party/blink/renderer/core/fileapi/file_test.cc
@@ -4,53 +4,58 @@
#include "third_party/blink/renderer/core/fileapi/file.h"
+#include "base/task/post_task.h"
+#include "base/task/thread_pool.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
+#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/file/file_utilities.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/platform/blob/testing/fake_blob.h"
#include "third_party/blink/renderer/platform/file_metadata.h"
#include "third_party/blink/renderer/platform/heap/heap.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"
namespace blink {
namespace {
-class MockFileUtilitiesHost : public mojom::blink::FileUtilitiesHost {
+class MockBlob : public FakeBlob {
public:
- MockFileUtilitiesHost()
- : broker_(*Platform::Current()->GetBrowserInterfaceBroker()) {
- broker_.SetBinderForTesting(
- FileUtilitiesHost::Name_,
- WTF::BindRepeating(&MockFileUtilitiesHost::BindReceiver,
- WTF::Unretained(this)));
- RebindFileUtilitiesForTesting();
+ static void Create(File* file, base::Time modified_time) {
+ mojo::PendingRemote<mojom::blink::Blob> remote;
+ PostCrossThreadTask(
+ *base::ThreadPool::CreateSingleThreadTaskRunner({}), FROM_HERE,
+ CrossThreadBindOnce(
+ [](const String& uuid,
+ mojo::PendingReceiver<mojom::blink::Blob> receiver,
+ base::Time modified_time) {
+ mojo::MakeSelfOwnedReceiver(
+ std::make_unique<MockBlob>(uuid, modified_time),
+ std::move(receiver));
+ },
+ file->Uuid(), remote.InitWithNewPipeAndPassReceiver(),
+ modified_time));
+ file->GetBlobDataHandle()->SetBlobRemoteForTesting(std::move(remote));
}
- ~MockFileUtilitiesHost() override {
- broker_.SetBinderForTesting(FileUtilitiesHost::Name_, {});
- RebindFileUtilitiesForTesting();
- }
-
- void SetFileInfoToBeReturned(const base::File::Info info) {
- file_info_ = info;
- }
+ MockBlob(const String& uuid, base::Time modified_time)
+ : FakeBlob(uuid), modified_time_(modified_time) {}
- private:
- void BindReceiver(mojo::ScopedMessagePipeHandle handle) {
- receivers_.Add(this,
- mojo::PendingReceiver<FileUtilitiesHost>(std::move(handle)));
+ void Clone(mojo::PendingReceiver<mojom::blink::Blob> receiver) override {
+ mojo::MakeSelfOwnedReceiver(
+ std::make_unique<MockBlob>(uuid_, modified_time_), std::move(receiver));
}
- // FileUtilitiesHost function:
- void GetFileInfo(const base::FilePath& path,
- GetFileInfoCallback callback) override {
- std::move(callback).Run(file_info_);
+ void CaptureSnapshot(CaptureSnapshotCallback callback) override {
+ std::move(callback).Run(
+ /*size=*/0, NullableTimeToOptionalTime(modified_time_));
}
- ThreadSafeBrowserInterfaceBrokerProxy& broker_;
- mojo::ReceiverSet<FileUtilitiesHost> receivers_;
- base::File::Info file_info_;
+ private:
+ base::Time modified_time_;
};
void ExpectTimestampIsNow(const File& file) {
@@ -65,12 +70,9 @@ void ExpectTimestampIsNow(const File& file) {
} // namespace
TEST(FileTest, NativeFileWithoutTimestamp) {
- MockFileUtilitiesHost host;
- base::File::Info info;
- info.last_modified = base::Time();
- host.SetFileInfoToBeReturned(info);
-
auto* const file = MakeGarbageCollected<File>("/native/path");
+ MockBlob::Create(file, base::Time());
+
EXPECT_TRUE(file->HasBackingFile());
EXPECT_EQ("/native/path", file->GetPath());
EXPECT_TRUE(file->FileSystemURL().IsEmpty());
@@ -78,24 +80,18 @@ TEST(FileTest, NativeFileWithoutTimestamp) {
}
TEST(FileTest, NativeFileWithUnixEpochTimestamp) {
- MockFileUtilitiesHost host;
- base::File::Info info;
- info.last_modified = base::Time::UnixEpoch();
- host.SetFileInfoToBeReturned(info);
-
auto* const file = MakeGarbageCollected<File>("/native/path");
+ MockBlob::Create(file, base::Time::UnixEpoch());
+
EXPECT_TRUE(file->HasBackingFile());
EXPECT_EQ(0, file->lastModified());
EXPECT_EQ(base::Time::UnixEpoch(), file->LastModifiedTime());
}
TEST(FileTest, NativeFileWithApocalypseTimestamp) {
- MockFileUtilitiesHost host;
- base::File::Info info;
- info.last_modified = base::Time::Max();
- host.SetFileInfoToBeReturned(info);
-
auto* const file = MakeGarbageCollected<File>("/native/path");
+ MockBlob::Create(file, base::Time::Max());
+
EXPECT_TRUE(file->HasBackingFile());
EXPECT_EQ((base::Time::Max() - base::Time::UnixEpoch()).InMilliseconds(),
@@ -219,6 +215,7 @@ TEST(FileTest, FileSystemFileWithApocalypseTimestamp) {
TEST(FileTest, fileSystemFileWithoutNativeSnapshot) {
KURL url("filesystem:http://example.com/isolated/hash/non-native-file");
FileMetadata metadata;
+ metadata.length = 0;
File* const file =
File::CreateForFileSystemFile(url, metadata, File::kIsUserVisible);
EXPECT_FALSE(file->HasBackingFile());
@@ -244,6 +241,7 @@ TEST(FileTest, hsaSameSource) {
KURL url_a("filesystem:http://example.com/isolated/hash/non-native-file-A");
KURL url_b("filesystem:http://example.com/isolated/hash/non-native-file-B");
FileMetadata metadata;
+ metadata.length = 0;
File* const file_system_file_a1 =
File::CreateForFileSystemFile(url_a, metadata, File::kIsUserVisible);
File* const file_system_file_a2 =
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 933ead60174..87bad05d26f 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
@@ -30,6 +30,7 @@
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "third_party/blink/public/common/blob/blob_utils.h"
#include "third_party/blink/public/mojom/blob/blob_registry.mojom-blink.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/fileapi/url_registry.h"
#include "third_party/blink/renderer/platform/blob/blob_data.h"
#include "third_party/blink/renderer/platform/blob/blob_url.h"
@@ -52,7 +53,7 @@ static void RemoveFromNullOriginMapIfNecessary(const KURL& blob_url) {
} // namespace
PublicURLManager::PublicURLManager(ExecutionContext* context)
- : ContextLifecycleObserver(context), is_stopped_(false) {}
+ : ExecutionContextLifecycleObserver(context), is_stopped_(false) {}
String PublicURLManager::RegisterURL(URLRegistrable* registrable) {
if (is_stopped_)
@@ -146,7 +147,7 @@ void PublicURLManager::Resolve(
url_store_->ResolveForNavigation(url, std::move(token_receiver));
}
-void PublicURLManager::ContextDestroyed(ExecutionContext*) {
+void PublicURLManager::ContextDestroyed() {
if (is_stopped_)
return;
@@ -164,8 +165,8 @@ void PublicURLManager::ContextDestroyed(ExecutionContext*) {
url_store_.reset();
}
-void PublicURLManager::Trace(blink::Visitor* visitor) {
- ContextLifecycleObserver::Trace(visitor);
+void PublicURLManager::Trace(Visitor* visitor) {
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 ed87d4567b7..3ba1a72ef63 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
@@ -31,7 +31,7 @@
#include "services/network/public/mojom/url_loader_factory.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/blob/blob_url_store.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
@@ -46,7 +46,7 @@ class URLRegistrable;
class CORE_EXPORT PublicURLManager final
: public GarbageCollected<PublicURLManager>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(PublicURLManager);
public:
@@ -68,10 +68,10 @@ class CORE_EXPORT PublicURLManager final
// If the URL fails to resolve the request will simply be disconnected.
void Resolve(const KURL&, mojo::PendingReceiver<mojom::blink::BlobURLToken>);
- // ContextLifecycleObserver interface.
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver interface.
+ void ContextDestroyed() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void SetURLStoreForTesting(
mojo::AssociatedRemote<mojom::blink::BlobURLStore> url_store) {
diff --git a/chromium/third_party/blink/renderer/core/fileapi/public_url_manager_test.cc b/chromium/third_party/blink/renderer/core/fileapi/public_url_manager_test.cc
index ad715b0dcfe..5360c48ca5b 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/public_url_manager_test.cc
+++ b/chromium/third_party/blink/renderer/core/fileapi/public_url_manager_test.cc
@@ -73,7 +73,7 @@ class PublicURLManagerTest : public testing::Test {
execution_context_ = MakeGarbageCollected<NullExecutionContext>();
// By default this creates a unique origin, which is exactly what this test
// wants.
- execution_context_->SetUpSecurityContext();
+ execution_context_->SetUpSecurityContextForTesting();
mojo::AssociatedRemote<BlobURLStore> url_store_remote;
url_store_receiver_.Bind(
@@ -149,7 +149,7 @@ TEST_F(PublicURLManagerTest, RegisterMojoBlob) {
TEST_F(PublicURLManagerTest, RevokeValidNonRegisteredURL) {
execution_context_->SetURL(KURL("http://example.com/foo/bar"));
- execution_context_->SetUpSecurityContext();
+ execution_context_->SetUpSecurityContextForTesting();
KURL url = KURL("blob:http://example.com/id");
url_manager().Revoke(url);
@@ -160,7 +160,7 @@ TEST_F(PublicURLManagerTest, RevokeValidNonRegisteredURL) {
TEST_F(PublicURLManagerTest, RevokeInvalidURL) {
execution_context_->SetURL(KURL("http://example.com/foo/bar"));
- execution_context_->SetUpSecurityContext();
+ execution_context_->SetUpSecurityContextForTesting();
KURL invalid_scheme_url = KURL("blb:http://example.com/id");
KURL fragment_url = KURL("blob:http://example.com/id#fragment");
diff --git a/chromium/third_party/blink/renderer/core/fileapi/url_file_api.h b/chromium/third_party/blink/renderer/core/fileapi/url_file_api.h
index 692a648fbf0..9911859427d 100644
--- a/chromium/third_party/blink/renderer/core/fileapi/url_file_api.h
+++ b/chromium/third_party/blink/renderer/core/fileapi/url_file_api.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FILEAPI_URL_FILE_API_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FILEAPI_URL_FILE_API_H_
+#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -15,7 +16,7 @@ class ExecutionContext;
class ScriptState;
class Blob;
-class URLFileAPI {
+class CORE_EXPORT URLFileAPI {
STATIC_ONLY(URLFileAPI);
public:
diff --git a/chromium/third_party/blink/renderer/core/frame/BUILD.gn b/chromium/third_party/blink/renderer/core/frame/BUILD.gn
index 109f359512e..f6c78c5dde4 100644
--- a/chromium/third_party/blink/renderer/core/frame/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/frame/BUILD.gn
@@ -27,6 +27,8 @@ blink_core_sources("frame") {
"csp/media_list_directive.h",
"csp/navigation_initiator_impl.cc",
"csp/navigation_initiator_impl.h",
+ "csp/require_trusted_types_for_directive.cc",
+ "csp/require_trusted_types_for_directive.h",
"csp/source_list_directive.cc",
"csp/source_list_directive.h",
"csp/string_list_directive.cc",
@@ -43,6 +45,8 @@ blink_core_sources("frame") {
"device_single_window_event_controller.h",
"display_cutout_client_impl.cc",
"display_cutout_client_impl.h",
+ "document_policy_violation_report_body.cc",
+ "document_policy_violation_report_body.h",
"dom_timer.cc",
"dom_timer.h",
"dom_timer_coordinator.cc",
@@ -73,6 +77,8 @@ blink_core_sources("frame") {
"frame_owner.h",
"frame_serializer.cc",
"frame_serializer.h",
+ "frame_serializer_delegate_impl.cc",
+ "frame_serializer_delegate_impl.h",
"frame_types.h",
"frame_view.cc",
"frame_view.h",
@@ -82,8 +88,6 @@ blink_core_sources("frame") {
"fullscreen_controller.h",
"history.cc",
"history.h",
- "hosts_using_features.cc",
- "hosts_using_features.h",
"intervention.cc",
"intervention.h",
"intervention_report_body.cc",
@@ -118,12 +122,16 @@ blink_core_sources("frame") {
"navigator_on_line.h",
"navigator_scheduling.cc",
"navigator_scheduling.h",
+ "navigator_ua.cc",
+ "navigator_ua.h",
+ "navigator_ua_data.cc",
+ "navigator_ua_data.h",
"navigator_user_activation.cc",
"navigator_user_activation.h",
- "navigator_user_agent.cc",
- "navigator_user_agent.h",
"opened_frame_tracker.cc",
"opened_frame_tracker.h",
+ "overlay_interstitial_ad_detector.cc",
+ "overlay_interstitial_ad_detector.h",
"page_scale_constraints.cc",
"page_scale_constraints.h",
"page_scale_constraints_set.cc",
@@ -177,6 +185,8 @@ blink_core_sources("frame") {
"settings_delegate.h",
"smart_clip.cc",
"smart_clip.h",
+ "sticky_frame_tracker.cc",
+ "sticky_frame_tracker.h",
"test_report_body.cc",
"test_report_body.h",
"use_counter_helper.cc",
@@ -203,4 +213,10 @@ blink_core_sources("frame") {
"window_or_worker_global_scope.cc",
"window_or_worker_global_scope.h",
]
+
+ deps = [
+ "//skia",
+ "//ui/base/cursor",
+ "//ui/base/mojom:cursor_type_blink",
+ ]
}
diff --git a/chromium/third_party/blink/renderer/core/frame/DEPS b/chromium/third_party/blink/renderer/core/frame/DEPS
index 81acd30f8fe..2bc0bcb5041 100644
--- a/chromium/third_party/blink/renderer/core/frame/DEPS
+++ b/chromium/third_party/blink/renderer/core/frame/DEPS
@@ -8,4 +8,10 @@ specific_include_rules = {
"local_frame_view.cc": [
"+cc/tiles/frame_viewer_instrumentation.h",
],
+ "remote_frame_view.cc": [
+ "+components/paint_preview/common/paint_preview_tracker.h",
+ ],
+ "web_frame_widget_base.cc": [
+ "+cc/trees/swap_promise.h",
+ ],
}
diff --git a/chromium/third_party/blink/renderer/core/frame/PRESUBMIT.py b/chromium/third_party/blink/renderer/core/frame/PRESUBMIT.py
deleted file mode 100644
index 302f6ab8258..00000000000
--- a/chromium/third_party/blink/renderer/core/frame/PRESUBMIT.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Blink frame presubmit script
-
-See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
-for more details about the presubmit API built into gcl.
-"""
-
-CSS_PROPERTY_ID_HEADER_PATH = (
- 'third_party/blink/public/mojom/use_counter/css_property_id.mojom')
-
-def _RunUseCounterChecks(input_api, output_api):
- for f in input_api.AffectedFiles():
- if f.LocalPath().endswith('use_counter.cc'):
- use_counter_cpp_file = f
- break
- else:
- return []
-
- largest_found_bucket = 0
- expected_max_bucket = 0
-
- # Looking for a line like "case CSSPropertyID::kGrid: return 453;"
- bucket_finder = input_api.re.compile(
- r'case CSSPropertyID::k\w+:\s*return\s*(\d+);')
-
- # Looking for a line like "const int32 kMaximumCSSSampleId = 452;"
- expected_max_finder = input_api.re.compile(
- r'const int32 kMaximumCSSSampleId = (\d+);')
-
- for f in input_api.change.AffectedFiles():
- if f.AbsoluteLocalPath().endswith(CSS_PROPERTY_ID_HEADER_PATH):
- expected_max_match = expected_max_finder.search(
- '\n'.join(f.NewContents()))
- break
- else:
- return []
-
- if expected_max_match:
- expected_max_bucket = int(expected_max_match.group(1))
-
- for bucket_match in bucket_finder.finditer(
- '\n'.join(use_counter_cpp_file.NewContents())):
-
- bucket = int(bucket_match.group(1))
- largest_found_bucket = max(largest_found_bucket, bucket)
-
- if largest_found_bucket != expected_max_bucket:
- if input_api.is_committing:
- message_type = output_api.PresubmitError
- else:
- message_type = output_api.PresubmitPromptWarning
-
- return [message_type(
- 'Largest found CSSProperty bucket Id (%d) does not match '
- 'maximumCSSSampleId (%d)' % (
- largest_found_bucket, expected_max_bucket),
- items=[use_counter_cpp_file.LocalPath(),
- CSS_PROPERTY_ID_HEADER_PATH])]
-
- return []
-
-
-def CheckChangeOnUpload(input_api, output_api):
- results = []
- results.extend(_RunUseCounterChecks(input_api, output_api))
- return results
-
-
-def CheckChangeOnCommit(input_api, output_api):
- results = []
- results.extend(_RunUseCounterChecks(input_api, output_api))
- return results
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 da2592a0738..9476585d36b 100644
--- a/chromium/third_party/blink/renderer/core/frame/ad_tracker.cc
+++ b/chromium/third_party/blink/renderer/core/frame/ad_tracker.cc
@@ -16,6 +16,7 @@
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
+#include "v8/include/v8.h"
namespace blink {
@@ -23,7 +24,7 @@ namespace {
bool IsKnownAdExecutionContext(ExecutionContext* execution_context) {
// TODO(jkarlin): Do the same check for worker contexts.
- if (auto* document = DynamicTo<Document>(execution_context)) {
+ if (auto* document = Document::DynamicFrom(execution_context)) {
LocalFrame* frame = document->GetFrame();
if (frame && frame->IsAdSubframe())
return true;
@@ -37,10 +38,10 @@ namespace features {
// Controls whether the AdTracker will look across async stacks to determine if
// the currently running stack is ad related.
const base::Feature kAsyncStackAdTagging{"AsyncStackAdTagging",
- base::FEATURE_DISABLED_BY_DEFAULT};
+ base::FEATURE_ENABLED_BY_DEFAULT};
-// Controls whether the AdTracker analyzes the whole pseudo-stack or just the
-// top of the stack when detecting ads.
+// Controls whether the AdTracker analyzes the bottom and top of the stack or
+// just the top of the stack when detecting ads.
const base::Feature kTopOfStackAdTagging{"TopOfStackAdTagging",
base::FEATURE_DISABLED_BY_DEFAULT};
} // namespace features
@@ -50,7 +51,7 @@ AdTracker* AdTracker::FromExecutionContext(
ExecutionContext* execution_context) {
if (!execution_context)
return nullptr;
- if (auto* document = DynamicTo<Document>(execution_context)) {
+ if (auto* document = Document::DynamicFrom(execution_context)) {
LocalFrame* frame = document->GetFrame();
if (frame) {
return frame->GetAdTracker();
@@ -79,11 +80,24 @@ void AdTracker::Shutdown() {
local_root_ = nullptr;
}
-String AdTracker::ScriptAtTopOfStack(ExecutionContext* execution_context) {
- std::unique_ptr<blink::SourceLocation> current_stack_trace =
- SourceLocation::Capture(execution_context);
- // TODO(jkarlin): Url() sometimes returns String(), why?
- return current_stack_trace ? current_stack_trace->Url() : "";
+String AdTracker::ScriptAtTopOfStack() {
+ // 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::Isolate* isolate = v8::Isolate::GetCurrent();
+ DCHECK(isolate);
+
+ v8::Local<v8::StackTrace> stack_trace =
+ v8::StackTrace::CurrentStackTrace(isolate, /*frame_limit=*/1);
+ if (stack_trace.IsEmpty() || stack_trace->GetFrameCount() < 1)
+ return String();
+
+ 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 String();
+
+ return ToCoreString(script_name);
}
ExecutionContext* AdTracker::GetCurrentExecutionContext() {
@@ -156,7 +170,7 @@ bool AdTracker::CalculateIfAdSubresource(ExecutionContext* execution_context,
// Check if the document loading the resource is an ad or if any executing
// script is an ad.
known_ad = known_ad || IsKnownAdExecutionContext(execution_context) ||
- IsAdScriptInStack();
+ IsAdScriptInStack(StackType::kBottomAndTop);
// If it is a script marked as an ad and it's not in an ad context, append it
// to the known ad script set. We don't need to keep track of ad scripts in ad
@@ -175,7 +189,7 @@ void AdTracker::DidCreateAsyncTask(probe::AsyncTaskId* task) {
if (!async_stack_enabled_)
return;
- if (IsAdScriptInStack())
+ if (IsAdScriptInStack(StackType::kBottomAndTop))
task->SetAdTask();
}
@@ -197,7 +211,7 @@ void AdTracker::DidFinishAsyncTask(probe::AsyncTaskId* task) {
running_ad_async_tasks_ -= 1;
}
-bool AdTracker::IsAdScriptInStack() {
+bool AdTracker::IsAdScriptInStack(StackType stack_type) {
if (num_ads_in_stack_ > 0 || running_ad_async_tasks_ > 0)
return true;
@@ -210,10 +224,14 @@ bool AdTracker::IsAdScriptInStack() {
if (IsKnownAdExecutionContext(execution_context))
return true;
- // The pseudo-stack contains entry points into the stack (e.g., when v8 is
- // executed) but not the entire stack. It's cheap to retrieve the top of the
- // stack so scan that as well.
- String top_script = ScriptAtTopOfStack(execution_context);
+ if (stack_type == StackType::kBottomOnly)
+ return false;
+
+ // The stack scanned by the AdTracker contains entry points into the stack
+ // (e.g., when v8 is executed) but not the entire stack. For a small cost we
+ // can also check the top of the stack (this is much cheaper than getting the
+ // full stack from v8).
+ String top_script = ScriptAtTopOfStack();
if (!top_script.IsEmpty() && IsKnownAdScript(execution_context, top_script))
return true;
@@ -243,7 +261,7 @@ void AdTracker::AppendToKnownAdScripts(ExecutionContext& execution_context,
add_result.stored_value->value.insert(url);
}
-void AdTracker::Trace(blink::Visitor* visitor) {
+void AdTracker::Trace(Visitor* visitor) {
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 562d4330aae..04e15e4221a 100644
--- a/chromium/third_party/blink/renderer/core/frame/ad_tracker.h
+++ b/chromium/third_party/blink/renderer/core/frame/ad_tracker.h
@@ -35,6 +35,7 @@ CORE_EXPORT extern const base::Feature kTopOfStackAdTagging;
// The tracker is maintained per local root.
class CORE_EXPORT AdTracker : public GarbageCollected<AdTracker> {
public:
+ enum class StackType { kBottomOnly, kBottomAndTop };
// Finds an AdTracker for a given ExecutionContext.
static AdTracker* FromExecutionContext(ExecutionContext*);
@@ -69,10 +70,15 @@ class CORE_EXPORT AdTracker : public GarbageCollected<AdTracker> {
void DidFinishAsyncTask(probe::AsyncTaskId* task);
// Returns true if any script in the pseudo call stack has previously been
- // identified as an ad resource.
- bool IsAdScriptInStack();
+ // identified as an ad resource, if the current ExecutionContext is a known ad
+ // execution context, or if the script at the top of isolate's
+ // stack is ad script. Whether to look at just the bottom of the
+ // stack or the top and bottom is indicated by |stack_type|. kBottomAndTop is
+ // generally best as it catches more ads, but if you're calling very
+ // frequently then consider just the bottom of the stack for performance sake.
+ bool IsAdScriptInStack(StackType stack_type);
- virtual void Trace(blink::Visitor*);
+ virtual void Trace(Visitor*);
void Shutdown();
explicit AdTracker(LocalFrame*);
@@ -80,7 +86,7 @@ class CORE_EXPORT AdTracker : public GarbageCollected<AdTracker> {
protected:
// Protected for testing.
- virtual String ScriptAtTopOfStack(ExecutionContext*);
+ virtual String ScriptAtTopOfStack();
virtual ExecutionContext* GetCurrentExecutionContext();
private:
@@ -107,7 +113,13 @@ class CORE_EXPORT AdTracker : public GarbageCollected<AdTracker> {
// The number of ad-related async tasks currently running in the stack.
uint32_t running_ad_async_tasks_ = 0;
+ // True if the AdTracker looks not only at the current V8 stack for ad script
+ // but also at the previous asynchronous stacks that caused this current
+ // callstack to run (e.g., registered callbacks).
const bool async_stack_enabled_;
+
+ // True if the TopOfStack experiment is running, which forces the AdTracker to
+ // ignore the bottom of stack frames when looking for ad script.
const bool top_of_stack_only_;
DISALLOW_COPY_AND_ASSIGN(AdTracker);
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 ab0711e3162..8f86535abab 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
@@ -10,7 +10,9 @@
#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/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/html/html_image_element.h"
#include "third_party/blink/renderer/core/probe/async_task_id.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
@@ -23,6 +25,11 @@ namespace blink {
namespace {
+const unsigned char kSmallGifData[] = {0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x00, 0x2c,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
+ 0x00, 0x00, 0x02, 0x00, 0x3b};
+
class TestAdTracker : public AdTracker {
public:
explicit TestAdTracker(LocalFrame* frame) : AdTracker(frame) {}
@@ -44,11 +51,12 @@ class TestAdTracker : public AdTracker {
return is_ad_.at(url);
}
- protected:
- String ScriptAtTopOfStack(ExecutionContext* execution_context) override {
- if (script_at_top_.IsEmpty())
- return AdTracker::ScriptAtTopOfStack(execution_context);
+ void SetSimTest() { sim_test_ = true; }
+ protected:
+ String ScriptAtTopOfStack() override {
+ if (sim_test_)
+ return AdTracker::ScriptAtTopOfStack();
return script_at_top_;
}
@@ -80,6 +88,7 @@ class TestAdTracker : public AdTracker {
String script_at_top_;
Member<ExecutionContext> execution_context_;
String ad_suffix_;
+ bool sim_test_ = false;
};
} // namespace
@@ -96,22 +105,30 @@ class AdTrackerTest : public testing::Test {
if (ad_tracker_)
ad_tracker_->Shutdown();
ad_tracker_ = MakeGarbageCollected<TestAdTracker>(GetFrame());
- ad_tracker_->SetExecutionContext(&page_holder_->GetDocument());
+ ad_tracker_->SetExecutionContext(
+ page_holder_->GetDocument().ToExecutionContext());
}
void WillExecuteScript(const String& script_url) {
- ad_tracker_->WillExecuteScript(&page_holder_->GetDocument(),
- String(script_url));
+ ad_tracker_->WillExecuteScript(
+ page_holder_->GetDocument().ToExecutionContext(), String(script_url));
}
void DidExecuteScript() { ad_tracker_->DidExecuteScript(); }
bool AnyExecutingScriptsTaggedAsAdResource() {
- return ad_tracker_->IsAdScriptInStack();
+ return AnyExecutingScriptsTaggedAsAdResourceWithStackType(
+ AdTracker::StackType::kBottomAndTop);
+ }
+
+ bool AnyExecutingScriptsTaggedAsAdResourceWithStackType(
+ AdTracker::StackType stack_type) {
+ return ad_tracker_->IsAdScriptInStack(stack_type);
}
void AppendToKnownAdScripts(const String& url) {
- ad_tracker_->AppendToKnownAdScripts(page_holder_->GetDocument(), url);
+ ad_tracker_->AppendToKnownAdScripts(
+ *page_holder_->GetDocument().ToExecutionContext(), url);
}
Persistent<TestAdTracker> ad_tracker_;
@@ -137,6 +154,29 @@ TEST_F(AdTrackerTest, AnyExecutingScriptsTaggedAsAdResource) {
EXPECT_TRUE(AnyExecutingScriptsTaggedAsAdResource());
}
+TEST_F(AdTrackerTest, BottomScriptTaggedAsAdResource) {
+ AppendToKnownAdScripts("https://example.com/ad.js");
+
+ WillExecuteScript("https://example.com/ad.js");
+ ad_tracker_->SetScriptAtTopOfStack("https://example.com/vanilla.js");
+ EXPECT_TRUE(AnyExecutingScriptsTaggedAsAdResourceWithStackType(
+ AdTracker::StackType::kBottomAndTop));
+ EXPECT_TRUE(AnyExecutingScriptsTaggedAsAdResourceWithStackType(
+ AdTracker::StackType::kBottomOnly));
+}
+
+TEST_F(AdTrackerTest, TopScriptTaggedAsAdResource) {
+ AppendToKnownAdScripts("https://example.com/ad.js");
+
+ WillExecuteScript("https://example.com/vanilla.js");
+ ad_tracker_->SetScriptAtTopOfStack("https://example.com/ad.js");
+
+ EXPECT_TRUE(AnyExecutingScriptsTaggedAsAdResourceWithStackType(
+ AdTracker::StackType::kBottomAndTop));
+ EXPECT_FALSE(AnyExecutingScriptsTaggedAsAdResourceWithStackType(
+ AdTracker::StackType::kBottomOnly));
+}
+
TEST_F(AdTrackerTest, TopOfStackOnly_NoAdsOnTop) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(features::kTopOfStackAdTagging);
@@ -188,6 +228,8 @@ TEST_F(AdTrackerTest, TopOfStackIncluded) {
ad_tracker_->SetScriptAtTopOfStack(ad_script_url);
EXPECT_TRUE(AnyExecutingScriptsTaggedAsAdResource());
+ EXPECT_FALSE(AnyExecutingScriptsTaggedAsAdResourceWithStackType(
+ AdTracker::StackType::kBottomOnly));
ad_tracker_->SetScriptAtTopOfStack("https://www.example.com/baz.js");
EXPECT_FALSE(AnyExecutingScriptsTaggedAsAdResource());
@@ -287,6 +329,7 @@ class AdTrackerSimTest : public SimTest {
LoadURL("https://example.com/test.html");
ad_tracker_ = MakeGarbageCollected<TestAdTracker>(GetDocument().GetFrame());
+ ad_tracker_->SetSimTest();
GetDocument().GetFrame()->SetAdTrackerForTesting(ad_tracker_);
}
@@ -325,8 +368,8 @@ TEST_F(AdTrackerSimTest, ScriptLoadedWhileExecutingAdScript) {
vanilla_script.Complete("");
- EXPECT_TRUE(IsKnownAdScript(&GetDocument(), kAdUrl));
- EXPECT_TRUE(IsKnownAdScript(&GetDocument(), kVanillaUrl));
+ EXPECT_TRUE(IsKnownAdScript(GetDocument().ToExecutionContext(), kAdUrl));
+ EXPECT_TRUE(IsKnownAdScript(GetDocument().ToExecutionContext(), kVanillaUrl));
EXPECT_TRUE(ad_tracker_->RequestWithUrlTaggedAsAd(kAdUrl));
EXPECT_TRUE(ad_tracker_->RequestWithUrlTaggedAsAd(kVanillaUrl));
}
@@ -355,9 +398,11 @@ TEST_F(AdTrackerSimTest, ScriptDetectedByContext) {
// Now run unknown script in the child's context. It should be considered an
// ad based on context alone.
- ad_tracker_->SetExecutionContext(child_frame->GetDocument());
+ ad_tracker_->SetExecutionContext(
+ child_frame->GetDocument()->ToExecutionContext());
ad_tracker_->SetScriptAtTopOfStack("foo.js");
- EXPECT_TRUE(ad_tracker_->IsAdScriptInStack());
+ EXPECT_TRUE(
+ ad_tracker_->IsAdScriptInStack(AdTracker::StackType::kBottomAndTop));
}
TEST_F(AdTrackerSimTest, RedirectToAdUrl) {
@@ -465,9 +510,9 @@ TEST_F(AdTrackerSimTest, ImageLoadedWhileExecutingAdScriptAsyncEnabled) {
GetDocument().GetFrame()->SetAdTrackerForTesting(ad_tracker_);
const char kAdUrl[] = "https://example.com/ad_script.js";
- const char kVanillaUrl[] = "https://example.com/vanilla_image.jpg";
+ const char kVanillaUrl[] = "https://example.com/vanilla_image.gif";
SimSubresourceRequest ad_resource(kAdUrl, "text/javascript");
- SimSubresourceRequest vanilla_image(kVanillaUrl, "image/jpeg");
+ SimSubresourceRequest vanilla_image(kVanillaUrl, "image/gif");
ad_tracker_->SetAdSuffix("ad_script.js");
@@ -475,21 +520,37 @@ TEST_F(AdTrackerSimTest, ImageLoadedWhileExecutingAdScriptAsyncEnabled) {
ad_resource.Complete(R"SCRIPT(
image = document.createElement("img");
- image.src = "vanilla_image.jpg";
+ image.src = "vanilla_image.gif";
document.body.appendChild(image);
)SCRIPT");
// Wait for script to run.
base::RunLoop().RunUntilIdle();
- vanilla_image.Complete("");
+ // Put the gif bytes in a Vector to avoid difficulty with
+ // non null-terminated char*.
+ Vector<char> gif;
+ gif.Append(kSmallGifData, sizeof(kSmallGifData));
- EXPECT_TRUE(IsKnownAdScript(&GetDocument(), kAdUrl));
+ vanilla_image.Complete(gif);
+
+ EXPECT_TRUE(IsKnownAdScript(GetDocument().ToExecutionContext(), kAdUrl));
EXPECT_TRUE(ad_tracker_->RequestWithUrlTaggedAsAd(kAdUrl));
// Image loading is async, so we should catch this when async stacks are
// monitored.
EXPECT_TRUE(ad_tracker_->RequestWithUrlTaggedAsAd(kVanillaUrl));
+
+ // Walk through the DOM to get the image element.
+ Element* doc_element = GetDocument().documentElement();
+ Element* body_element = Traversal<Element>::LastChild(*doc_element);
+ HTMLImageElement* image_element =
+ Traversal<HTMLImageElement>::FirstChild(*body_element);
+
+ // When async stacks are monitored, we should also tag the
+ // HTMLImageElement as ad-related.
+ ASSERT_TRUE(image_element);
+ EXPECT_TRUE(image_element->IsAdRelated());
}
// Image loaded by ad script is tagged as ad.
@@ -503,9 +564,9 @@ TEST_F(AdTrackerSimTest, ImageLoadedWhileExecutingAdScriptAsyncDisabled) {
GetDocument().GetFrame()->SetAdTrackerForTesting(ad_tracker_);
const char kAdUrl[] = "https://example.com/ad_script.js";
- const char kVanillaUrl[] = "https://example.com/vanilla_image.jpg";
+ const char kVanillaUrl[] = "https://example.com/vanilla_image.gif";
SimSubresourceRequest ad_resource(kAdUrl, "text/javascript");
- SimSubresourceRequest vanilla_image(kVanillaUrl, "image/jpeg");
+ SimSubresourceRequest vanilla_image(kVanillaUrl, "image/gif");
ad_tracker_->SetAdSuffix("ad_script.js");
@@ -513,21 +574,78 @@ TEST_F(AdTrackerSimTest, ImageLoadedWhileExecutingAdScriptAsyncDisabled) {
ad_resource.Complete(R"SCRIPT(
image = document.createElement("img");
- image.src = "vanilla_image.jpg";
+ image.src = "vanilla_image.gif";
document.body.appendChild(image);
)SCRIPT");
// Wait for script to run.
base::RunLoop().RunUntilIdle();
- vanilla_image.Complete("");
+ // Put the gif bytes in a Vector to avoid difficulty with
+ // non null-terminated char*.
+ Vector<char> gif;
+ gif.Append(kSmallGifData, sizeof(kSmallGifData));
+
+ vanilla_image.Complete(gif);
- EXPECT_TRUE(IsKnownAdScript(&GetDocument(), kAdUrl));
+ EXPECT_TRUE(IsKnownAdScript(GetDocument().ToExecutionContext(), kAdUrl));
EXPECT_TRUE(ad_tracker_->RequestWithUrlTaggedAsAd(kAdUrl));
// Image loading is async, so we won't catch this when async stacks aren't
// monitored.
EXPECT_FALSE(ad_tracker_->RequestWithUrlTaggedAsAd(kVanillaUrl));
+
+ // Walk through the DOM to get the image element.
+ Element* doc_element = GetDocument().documentElement();
+ Element* body_element = Traversal<Element>::LastChild(*doc_element);
+ HTMLImageElement* image_element =
+ Traversal<HTMLImageElement>::FirstChild(*body_element);
+
+ // When async stacks are not monitored, we do not tag the
+ // HTMLImageElement as ad-related.
+ ASSERT_TRUE(image_element);
+ EXPECT_FALSE(image_element->IsAdRelated());
+}
+
+// Image loaded by ad script is tagged as ad.
+TEST_F(AdTrackerSimTest, DataURLImageLoadedWhileExecutingAdScriptAsyncEnabled) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(features::kAsyncStackAdTagging);
+
+ // Reset the AdTracker so that it gets the latest base::Feature value on
+ // construction.
+ ad_tracker_ = MakeGarbageCollected<TestAdTracker>(GetDocument().GetFrame());
+ GetDocument().GetFrame()->SetAdTrackerForTesting(ad_tracker_);
+
+ const char kAdUrl[] = "https://example.com/ad_script.js";
+ SimSubresourceRequest ad_resource(kAdUrl, "text/javascript");
+
+ ad_tracker_->SetAdSuffix("ad_script.js");
+
+ main_resource_->Complete("<body></body><script src=ad_script.js></script>");
+
+ ad_resource.Complete(R"SCRIPT(
+ image = document.createElement("img");
+ image.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=";
+ document.body.appendChild(image);
+ )SCRIPT");
+
+ // Wait for script to run.
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(IsKnownAdScript(GetDocument().ToExecutionContext(), kAdUrl));
+ EXPECT_TRUE(ad_tracker_->RequestWithUrlTaggedAsAd(kAdUrl));
+
+ // Walk through the DOM to get the image element.
+ Element* doc_element = GetDocument().documentElement();
+ Element* body_element = Traversal<Element>::LastChild(*doc_element);
+ HTMLImageElement* image_element =
+ Traversal<HTMLImageElement>::FirstChild(*body_element);
+
+ // When async stacks are monitored, we should also tag the
+ // HTMLImageElement as ad-related.
+ ASSERT_TRUE(image_element);
+ EXPECT_TRUE(image_element->IsAdRelated());
}
// Frame loaded by ad script is tagged as ad.
@@ -555,7 +673,7 @@ TEST_F(AdTrackerSimTest, FrameLoadedWhileExecutingAdScript) {
vanilla_page.Complete("<img src=vanilla_img.jpg></img>");
vanilla_image.Complete("");
- EXPECT_TRUE(IsKnownAdScript(&GetDocument(), kAdUrl));
+ EXPECT_TRUE(IsKnownAdScript(GetDocument().ToExecutionContext(), kAdUrl));
EXPECT_TRUE(ad_tracker_->RequestWithUrlTaggedAsAd(kAdUrl));
Frame* child_frame = GetDocument().GetFrame()->Tree().FirstChild();
EXPECT_TRUE(To<LocalFrame>(child_frame)->IsAdSubframe());
@@ -596,10 +714,11 @@ TEST_F(AdTrackerSimTest, Contexts) {
// in the main frame's context.
Frame* subframe = GetDocument().GetFrame()->Tree().FirstChild();
auto* local_subframe = To<LocalFrame>(subframe);
- EXPECT_TRUE(IsKnownAdScript(local_subframe->GetDocument(),
- String("https://example.com/library.js")));
+ EXPECT_TRUE(
+ IsKnownAdScript(local_subframe->GetDocument()->ToExecutionContext(),
+ String("https://example.com/library.js")));
- EXPECT_FALSE(IsKnownAdScript(&GetDocument(),
+ EXPECT_FALSE(IsKnownAdScript(GetDocument().ToExecutionContext(),
String("https://example.com/library.js")));
}
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 b688e7b269f..85dc13c2646 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)
: DOMWindowClient(frame), type_(type) {}
-void BarProp::Trace(blink::Visitor* visitor) {
+void BarProp::Trace(Visitor* visitor) {
ScriptWrappable::Trace(visitor);
DOMWindowClient::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 668e75a3cb9..5f1d7148259 100644
--- a/chromium/third_party/blink/renderer/core/frame/bar_prop.h
+++ b/chromium/third_party/blink/renderer/core/frame/bar_prop.h
@@ -29,7 +29,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_BAR_PROP_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_BAR_PROP_H_
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -55,7 +55,7 @@ class BarProp final : public ScriptWrappable, public DOMWindowClient {
bool visible() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 cdb13668349..a780ffcc61d 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(blink::Visitor* visitor) {
+void BrowserControls::Trace(Visitor* visitor) {
visitor->Trace(page_);
}
@@ -96,6 +96,32 @@ FloatSize BrowserControls::ScrollBy(FloatSize pending_delta) {
return pending_delta - applied_delta;
}
+void BrowserControls::ScrollEnd() {
+ if ((top_shown_ratio_ == TopMinShownRatio() || top_shown_ratio_ == 1) &&
+ (bottom_shown_ratio_ == BottomMinShownRatio() ||
+ bottom_shown_ratio_ == 1)) {
+ return;
+ }
+
+ // Both threshold values are copied from LayerTreeSettings, which are used in
+ // BrowserControlsOffsetManager::ScrollEnd.
+ constexpr float kTopControlsShowThreshold = 0.5f;
+ constexpr float kTopControlsHideThreshold = 0.5f;
+ float normalized_top_ratio =
+ (top_shown_ratio_ - TopMinShownRatio()) / (1.f - TopMinShownRatio());
+ if (normalized_top_ratio >= 1.f - kTopControlsHideThreshold) {
+ // If we're showing so much that the hide threshold won't trigger, show.
+ UpdateConstraintsAndState(permitted_state_,
+ cc::BrowserControlsState::kShown);
+ } else if (normalized_top_ratio < kTopControlsShowThreshold) {
+ // If we're showing so little that the show threshold won't trigger, hide.
+ UpdateConstraintsAndState(permitted_state_,
+ cc::BrowserControlsState::kHidden);
+ } else {
+ NOTREACHED();
+ }
+}
+
void BrowserControls::ResetBaseline() {
accumulated_scroll_delta_ = 0;
baseline_top_content_offset_ = ContentOffset();
@@ -118,8 +144,10 @@ float BrowserControls::BottomContentOffset() {
}
void BrowserControls::SetShownRatio(float top_ratio, float bottom_ratio) {
- top_ratio = clampTo(top_ratio, 0.f, 1.f);
- bottom_ratio = clampTo(bottom_ratio, 0.f, 1.f);
+ // The ratios can be > 1 during height change animations, so we shouldn't
+ // clamp the values.
+ top_ratio = std::max(0.f, top_ratio);
+ bottom_ratio = std::max(0.f, bottom_ratio);
if (top_shown_ratio_ == top_ratio && bottom_shown_ratio_ == bottom_ratio)
return;
@@ -131,14 +159,22 @@ void BrowserControls::SetShownRatio(float top_ratio, float bottom_ratio) {
void BrowserControls::UpdateConstraintsAndState(
cc::BrowserControlsState constraints,
- cc::BrowserControlsState current,
- bool animate) {
+ cc::BrowserControlsState current) {
permitted_state_ = constraints;
DCHECK(!(constraints == cc::BrowserControlsState::kShown &&
current == cc::BrowserControlsState::kHidden));
DCHECK(!(constraints == cc::BrowserControlsState::kHidden &&
current == cc::BrowserControlsState::kShown));
+
+ if (current == cc::BrowserControlsState::kShown) {
+ top_shown_ratio_ = 1;
+ bottom_shown_ratio_ = 1;
+ } else if (current == cc::BrowserControlsState::kHidden) {
+ top_shown_ratio_ = TopMinShownRatio();
+ bottom_shown_ratio_ = BottomMinShownRatio();
+ }
+ page_->GetChromeClient().DidUpdateBrowserControls();
}
void BrowserControls::SetParams(cc::BrowserControlsParams params) {
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 11930e0e854..a1361b15617 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(blink::Visitor*);
+ void Trace(Visitor*);
// The height the top controls are hidden; used for viewport adjustments
// while the controls are resizing.
@@ -41,6 +41,7 @@ class CORE_EXPORT BrowserControls final
float BottomHeight() const { return params_.bottom_controls_height; }
float BottomMinHeight() const { return params_.bottom_controls_min_height; }
float TotalHeight() const { return TopHeight() + BottomHeight(); }
+ float TotalMinHeight() const { return TopMinHeight() + BottomMinHeight(); }
bool ShrinkViewport() const {
return params_.browser_controls_shrink_blink_size;
}
@@ -55,8 +56,7 @@ class CORE_EXPORT BrowserControls final
void SetShownRatio(float top_ratio, float bottom_ratio);
void UpdateConstraintsAndState(cc::BrowserControlsState constraints,
- cc::BrowserControlsState current,
- bool animate);
+ cc::BrowserControlsState current);
void ScrollBegin();
@@ -64,6 +64,8 @@ class CORE_EXPORT BrowserControls final
// scroll amount.
FloatSize ScrollBy(FloatSize scroll_delta);
+ void ScrollEnd();
+
cc::BrowserControlsState PermittedState() const { return permitted_state_; }
private:
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 d89f7de38f7..a42014e9d50 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
@@ -145,7 +145,7 @@ class BrowserControlsTest : public testing::Test,
void UpdateAllLifecyclePhases() {
GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
}
private:
@@ -169,7 +169,7 @@ class BrowserControlsSimTest : public SimTest {
WebView().GetSettings()->SetMainFrameResizesAreOrientationChanges(true);
WebView().GetSettings()->SetShrinksViewportContentToFit(true);
WebView().SetDefaultPageScaleLimits(0.25f, 5);
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kShown,
false);
WebView().ResizeWithBrowserControls(WebSize(412, 604), 56.f, 50.f, true);
@@ -330,10 +330,12 @@ TEST_F(BrowserControlsTest, MAYBE(ShowBottomControlsOnScrollUp)) {
GenerateEvent(WebInputEvent::kGestureScrollBegin));
web_view->MainFrameWidget()->HandleInputEvent(
GenerateEvent(WebInputEvent::kGestureScrollUpdate, 0, 25.f));
+ EXPECT_FLOAT_EQ(0.5f, web_view->GetBrowserControls().BottomShownRatio());
+
web_view->MainFrameWidget()->HandleInputEvent(
GenerateEvent(WebInputEvent::kGestureScrollEnd));
EXPECT_FLOAT_EQ(0.f, web_view->GetBrowserControls().ContentOffset());
- EXPECT_FLOAT_EQ(0.5f, web_view->GetBrowserControls().BottomShownRatio());
+ EXPECT_FLOAT_EQ(1.f, web_view->GetBrowserControls().BottomShownRatio());
EXPECT_EQ(ScrollOffset(0, 25),
GetFrame()->View()->LayoutViewport()->GetScrollOffset());
}
@@ -346,8 +348,8 @@ TEST_F(BrowserControlsTest, MAYBE(ScrollDownThenUp)) {
web_view->ResizeWithBrowserControls(web_view->MainFrameWidget()->Size(), 50.f,
0, true);
web_view->GetBrowserControls().SetShownRatio(1, 1);
- GetFrame()->View()->GetScrollableArea()->SetScrollOffset(ScrollOffset(0, 100),
- kProgrammaticScroll);
+ GetFrame()->View()->GetScrollableArea()->SetScrollOffset(
+ ScrollOffset(0, 100), mojom::blink::ScrollType::kProgrammatic);
web_view->MainFrameWidget()->HandleInputEvent(
GenerateEvent(WebInputEvent::kGestureScrollBegin));
@@ -399,8 +401,8 @@ TEST_F(BrowserControlsTest, MAYBE(ScrollUpThenDown)) {
web_view->ResizeWithBrowserControls(web_view->MainFrameWidget()->Size(), 50.f,
0, false);
web_view->GetBrowserControls().SetShownRatio(0, 0);
- GetFrame()->View()->GetScrollableArea()->SetScrollOffset(ScrollOffset(0, 100),
- kProgrammaticScroll);
+ GetFrame()->View()->GetScrollableArea()->SetScrollOffset(
+ ScrollOffset(0, 100), mojom::blink::ScrollType::kProgrammatic);
web_view->MainFrameWidget()->HandleInputEvent(
GenerateEvent(WebInputEvent::kGestureScrollBegin));
@@ -541,46 +543,58 @@ TEST_F(BrowserControlsTest, MAYBE(ScrollableSubregionScrollFirst)) {
web_view->ResizeWithBrowserControls(web_view->MainFrameWidget()->Size(), 50.f,
0, true);
web_view->GetBrowserControls().SetShownRatio(1, 1);
- GetFrame()->View()->GetScrollableArea()->SetScrollOffset(ScrollOffset(0, 50),
- kProgrammaticScroll);
+ GetFrame()->View()->GetScrollableArea()->SetScrollOffset(
+ ScrollOffset(0, 50), mojom::blink::ScrollType::kProgrammatic);
// Test scroll down
- // Scroll down should scroll the overflow div first but browser controls and
- // main frame should not scroll.
+ // A full scroll down should scroll the overflow div first but browser
+ // controls and main frame should not scroll.
VerticalScroll(-800.f);
EXPECT_FLOAT_EQ(50.f, web_view->GetBrowserControls().ContentOffset());
EXPECT_EQ(ScrollOffset(0, 50),
GetFrame()->View()->LayoutViewport()->GetScrollOffset());
- // Continued scroll down should start hiding browser controls but main frame
+ // Now scroll down should start hiding browser controls but main frame
// should not scroll.
- VerticalScroll(-40.f);
+ GetWebView()->MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollBegin, 0, -40.f));
+ GetWebView()->MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollUpdate, 0, -40.f));
EXPECT_FLOAT_EQ(10.f, web_view->GetBrowserControls().ContentOffset());
EXPECT_EQ(ScrollOffset(0, 50),
GetFrame()->View()->LayoutViewport()->GetScrollOffset());
// Continued scroll down should scroll down the main frame
- VerticalScroll(-40.f);
+ GetWebView()->MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollUpdate, 0, -40.f));
+ GetWebView()->MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollEnd));
EXPECT_FLOAT_EQ(0.f, web_view->GetBrowserControls().ContentOffset());
EXPECT_EQ(ScrollOffset(0, 80),
GetFrame()->View()->LayoutViewport()->GetScrollOffset());
// Test scroll up
- // scroll up should scroll overflow div first
+ // A full scroll up should scroll overflow div first
VerticalScroll(800.f);
EXPECT_FLOAT_EQ(0.f, web_view->GetBrowserControls().ContentOffset());
EXPECT_EQ(ScrollOffset(0, 80),
GetFrame()->View()->LayoutViewport()->GetScrollOffset());
- // Continued scroll up should start showing browser controls but main frame
+ // Now scroll up should start showing browser controls but main frame
// should not scroll.
- VerticalScroll(40.f);
+ GetWebView()->MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollBegin, 0, 40.f));
+ GetWebView()->MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollUpdate, 0, 40.f));
EXPECT_FLOAT_EQ(40.f, web_view->GetBrowserControls().ContentOffset());
EXPECT_EQ(ScrollOffset(0, 80),
GetFrame()->View()->LayoutViewport()->GetScrollOffset());
- // Continued scroll down up scroll up the main frame
- VerticalScroll(40.f);
+ // Continued scroll up scroll up the main frame
+ GetWebView()->MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollUpdate, 0, 40.f));
+ GetWebView()->MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollEnd));
EXPECT_FLOAT_EQ(50.f, web_view->GetBrowserControls().ContentOffset());
EXPECT_EQ(ScrollOffset(0, 50),
GetFrame()->View()->LayoutViewport()->GetScrollOffset());
@@ -592,46 +606,58 @@ TEST_F(BrowserControlsTest, MAYBE(ScrollableIframeScrollFirst)) {
web_view->ResizeWithBrowserControls(web_view->MainFrameWidget()->Size(), 50.f,
0, true);
web_view->GetBrowserControls().SetShownRatio(1, 1);
- GetFrame()->View()->GetScrollableArea()->SetScrollOffset(ScrollOffset(0, 50),
- kProgrammaticScroll);
+ GetFrame()->View()->GetScrollableArea()->SetScrollOffset(
+ ScrollOffset(0, 50), mojom::blink::ScrollType::kProgrammatic);
// Test scroll down
- // Scroll down should scroll the iframe first but browser controls and main
- // frame should not scroll.
+ // A full scroll down should scroll the iframe first but browser controls and
+ // main frame should not scroll.
VerticalScroll(-800.f);
EXPECT_FLOAT_EQ(50.f, web_view->GetBrowserControls().ContentOffset());
EXPECT_EQ(ScrollOffset(0, 50),
GetFrame()->View()->LayoutViewport()->GetScrollOffset());
- // Continued scroll down should start hiding browser controls but main frame
+ // Now scroll down should start hiding browser controls but main frame
// should not scroll.
- VerticalScroll(-40.f);
+ GetWebView()->MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollBegin, 0, -40.f));
+ GetWebView()->MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollUpdate, 0, -40.f));
EXPECT_FLOAT_EQ(10.f, web_view->GetBrowserControls().ContentOffset());
EXPECT_EQ(ScrollOffset(0, 50),
GetFrame()->View()->LayoutViewport()->GetScrollOffset());
// Continued scroll down should scroll down the main frame
- VerticalScroll(-40.f);
+ GetWebView()->MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollUpdate, 0, -40.f));
+ GetWebView()->MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollEnd));
EXPECT_FLOAT_EQ(0.f, web_view->GetBrowserControls().ContentOffset());
EXPECT_EQ(ScrollOffset(0, 80),
GetFrame()->View()->LayoutViewport()->GetScrollOffset());
// Test scroll up
- // scroll up should scroll iframe first
+ // A full scroll up should scroll iframe first
VerticalScroll(800.f);
EXPECT_FLOAT_EQ(0.f, web_view->GetBrowserControls().ContentOffset());
EXPECT_EQ(ScrollOffset(0, 80),
GetFrame()->View()->LayoutViewport()->GetScrollOffset());
- // Continued scroll up should start showing browser controls but main frame
+ // Now scroll up should start showing browser controls but main frame
// should not scroll.
- VerticalScroll(40.f);
+ GetWebView()->MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollBegin, 0, 40.f));
+ GetWebView()->MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollUpdate, 0, 40.f));
EXPECT_FLOAT_EQ(40.f, web_view->GetBrowserControls().ContentOffset());
EXPECT_EQ(ScrollOffset(0, 80),
GetFrame()->View()->LayoutViewport()->GetScrollOffset());
- // Continued scroll down up scroll up the main frame
- VerticalScroll(40.f);
+ // Continued scroll up scroll up the main frame
+ GetWebView()->MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollUpdate, 0, 40.f));
+ GetWebView()->MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollEnd));
EXPECT_FLOAT_EQ(50.f, web_view->GetBrowserControls().ContentOffset());
EXPECT_EQ(ScrollOffset(0, 50),
GetFrame()->View()->LayoutViewport()->GetScrollOffset());
@@ -669,8 +695,8 @@ TEST_F(BrowserControlsTest, MAYBE(ZeroHeightMeansNoEffect)) {
web_view->ResizeWithBrowserControls(web_view->MainFrameWidget()->Size(), 0, 0,
false);
web_view->GetBrowserControls().SetShownRatio(0, 0);
- GetFrame()->View()->GetScrollableArea()->SetScrollOffset(ScrollOffset(0, 100),
- kProgrammaticScroll);
+ GetFrame()->View()->GetScrollableArea()->SetScrollOffset(
+ ScrollOffset(0, 100), mojom::blink::ScrollType::kProgrammatic);
EXPECT_FLOAT_EQ(0.f, web_view->GetBrowserControls().ContentOffset());
@@ -701,16 +727,30 @@ TEST_F(BrowserControlsTest, MAYBE(ScrollUpPastLimitDoesNotHide)) {
// Fully scroll frameview but visualviewport remains scrollable
web_view->MainFrameImpl()->SetScrollOffset(WebSize(0, 10000));
GetVisualViewport().SetLocation(FloatPoint(0, 0));
- VerticalScroll(-10.f);
+ GetWebView()->MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollBegin, 0, -10.f));
+ GetWebView()->MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollUpdate, 0, -10.f));
EXPECT_FLOAT_EQ(40, web_view->GetBrowserControls().ContentOffset());
+ GetWebView()->MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollEnd));
+ EXPECT_FLOAT_EQ(50, web_view->GetBrowserControls().ContentOffset());
+
web_view->GetBrowserControls().SetShownRatio(1, 1);
// Fully scroll visual veiwport but frameview remains scrollable
web_view->MainFrameImpl()->SetScrollOffset(WebSize(0, 0));
GetVisualViewport().SetLocation(FloatPoint(0, 10000));
- VerticalScroll(-20.f);
+ GetWebView()->MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollBegin, 0, -20.f));
+ GetWebView()->MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollUpdate, 0, -20.f));
EXPECT_FLOAT_EQ(30, web_view->GetBrowserControls().ContentOffset());
+ GetWebView()->MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollEnd));
+ EXPECT_FLOAT_EQ(50, web_view->GetBrowserControls().ContentOffset());
+
web_view->GetBrowserControls().SetShownRatio(1, 1);
// Fully scroll both frameview and visual viewport
web_view->MainFrameImpl()->SetScrollOffset(WebSize(0, 10000));
@@ -742,10 +782,10 @@ TEST_F(BrowserControlsSimTest, MAYBE(StateConstraints)) {
Compositor().BeginFrame();
GetDocument().View()->GetScrollableArea()->SetScrollOffset(
- ScrollOffset(0, 100), kProgrammaticScroll);
+ ScrollOffset(0, 100), mojom::blink::ScrollType::kProgrammatic);
// Setting permitted state should change the content offset to match the
// constraint.
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kShown, cc::BrowserControlsState::kShown,
false);
Compositor().BeginFrame();
@@ -764,7 +804,7 @@ TEST_F(BrowserControlsSimTest, MAYBE(StateConstraints)) {
// Setting permitted state should change content offset to match the
// constraint.
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kHidden, cc::BrowserControlsState::kHidden,
false);
Compositor().BeginFrame();
@@ -777,7 +817,7 @@ TEST_F(BrowserControlsSimTest, MAYBE(StateConstraints)) {
GetDocument().View()->LayoutViewport()->GetScrollOffset());
// Setting permitted state to "both" should not change content offset.
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kBoth, false);
Compositor().BeginFrame();
EXPECT_FLOAT_EQ(0, WebView().GetBrowserControls().ContentOffset());
@@ -794,21 +834,28 @@ TEST_F(BrowserControlsSimTest, MAYBE(StateConstraints)) {
GetDocument().View()->LayoutViewport()->GetScrollOffset());
// Setting permitted state to "both" should not change an in-flight offset.
- VerticalScroll(20.f);
+ WebView().MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollBegin, 0, 20.f));
+ WebView().MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollUpdate, 0, 20.f));
EXPECT_FLOAT_EQ(20, WebView().GetBrowserControls().ContentOffset());
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+
+ WebView().MainFrameWidget()->HandleInputEvent(
+ GenerateEvent(WebInputEvent::kGestureScrollEnd));
+ EXPECT_FLOAT_EQ(0, WebView().GetBrowserControls().ContentOffset());
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kBoth, false);
Compositor().BeginFrame();
- EXPECT_FLOAT_EQ(20, WebView().GetBrowserControls().ContentOffset());
+ EXPECT_FLOAT_EQ(0, WebView().GetBrowserControls().ContentOffset());
// Setting just the constraint should affect the content offset.
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kHidden, cc::BrowserControlsState::kBoth,
false);
Compositor().BeginFrame();
EXPECT_FLOAT_EQ(0, WebView().GetBrowserControls().ContentOffset());
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kShown, cc::BrowserControlsState::kBoth, false);
Compositor().BeginFrame();
EXPECT_FLOAT_EQ(50, WebView().GetBrowserControls().ContentOffset());
@@ -821,7 +868,7 @@ TEST_F(BrowserControlsTest, MAYBE(DontAffectLayoutHeight)) {
WebViewImpl* web_view = Initialize("percent-height.html");
web_view->ResizeWithBrowserControls(WebSize(400, 300), 100.f, 0, true);
web_view->GetBrowserControls().UpdateConstraintsAndState(
- cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kShown, false);
+ cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kShown);
web_view->GetBrowserControls().SetShownRatio(1, 1);
UpdateAllLifecyclePhases();
@@ -892,7 +939,7 @@ TEST_F(BrowserControlsSimTest, MAYBE(AffectLayoutHeightWhenConstrained)) {
Compositor().BeginFrame();
WebView().ResizeWithBrowserControls(WebSize(400, 300), 100.f, 0, true);
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kShown, false);
Compositor().BeginFrame();
@@ -910,7 +957,7 @@ TEST_F(BrowserControlsSimTest, MAYBE(AffectLayoutHeightWhenConstrained)) {
// Now lock the controls in a hidden state. The layout and elements should
// resize without a WebView::resize.
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kHidden, cc::BrowserControlsState::kBoth,
false);
Compositor().BeginFrame();
@@ -922,7 +969,7 @@ TEST_F(BrowserControlsSimTest, MAYBE(AffectLayoutHeightWhenConstrained)) {
// Unlock the controls, the sizes should change even though the controls are
// still hidden.
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kBoth, false);
Compositor().BeginFrame();
@@ -932,7 +979,7 @@ TEST_F(BrowserControlsSimTest, MAYBE(AffectLayoutHeightWhenConstrained)) {
EXPECT_EQ(300, GetDocument().GetFrame()->View()->GetLayoutSize().Height());
// Now lock the controls in a shown state.
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kShown, cc::BrowserControlsState::kBoth, false);
WebView().ResizeWithBrowserControls(WebSize(400, 300), 100.f, 0, true);
Compositor().BeginFrame();
@@ -944,7 +991,7 @@ TEST_F(BrowserControlsSimTest, MAYBE(AffectLayoutHeightWhenConstrained)) {
// Shown -> Hidden
WebView().ResizeWithBrowserControls(WebSize(400, 400), 100.f, 0, false);
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kHidden, cc::BrowserControlsState::kBoth,
false);
Compositor().BeginFrame();
@@ -956,14 +1003,14 @@ TEST_F(BrowserControlsSimTest, MAYBE(AffectLayoutHeightWhenConstrained)) {
// Go from Unlocked and showing, to locked and hidden but issue the resize
// before the constraint update to check for race issues.
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kShown, false);
WebView().ResizeWithBrowserControls(WebSize(400, 300), 100.f, 0, true);
Compositor().BeginFrame();
ASSERT_EQ(300, GetDocument().GetFrame()->View()->GetLayoutSize().Height());
WebView().ResizeWithBrowserControls(WebSize(400, 400), 100.f, 0, false);
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kHidden, cc::BrowserControlsState::kHidden,
false);
Compositor().BeginFrame();
@@ -980,7 +1027,7 @@ TEST_F(BrowserControlsTest, MAYBE(DontAffectVHUnits)) {
WebViewImpl* web_view = Initialize("vh-height.html");
web_view->ResizeWithBrowserControls(WebSize(400, 300), 100.f, 0, true);
web_view->GetBrowserControls().UpdateConstraintsAndState(
- cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kShown, false);
+ cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kShown);
web_view->GetBrowserControls().SetShownRatio(1, 1);
UpdateAllLifecyclePhases();
@@ -1022,7 +1069,7 @@ TEST_F(BrowserControlsTest, MAYBE(DontAffectVHUnitsWithScale)) {
WebViewImpl* web_view = Initialize("vh-height-width-800.html");
web_view->ResizeWithBrowserControls(WebSize(400, 300), 100.f, 0, true);
web_view->GetBrowserControls().UpdateConstraintsAndState(
- cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kShown, false);
+ cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kShown);
web_view->GetBrowserControls().SetShownRatio(1, 1);
UpdateAllLifecyclePhases();
@@ -1072,7 +1119,7 @@ TEST_F(BrowserControlsTest, MAYBE(DontAffectVHUnitsUseLayoutSize)) {
WebViewImpl* web_view = Initialize("vh-height-width-800-extra-wide.html");
web_view->ResizeWithBrowserControls(WebSize(400, 300), 100.f, 0, true);
web_view->GetBrowserControls().UpdateConstraintsAndState(
- cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kShown, false);
+ cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kShown);
web_view->GetBrowserControls().SetShownRatio(1, 1);
UpdateAllLifecyclePhases();
@@ -1088,6 +1135,140 @@ TEST_F(BrowserControlsTest, MAYBE(DontAffectVHUnitsUseLayoutSize)) {
EXPECT_EQ(800, GetFrame()->View()->ViewportSizeForViewportUnits().Height());
}
+// Ensure that vh units are correctly calculated when a top controls min-height
+// is set.
+TEST_F(BrowserControlsTest, MAYBE(VHUnitsWithTopMinHeight)) {
+ // Initialize with the browser controls showing.
+ // Top controls height: 100, top controls min-height: 20.
+ WebViewImpl* web_view = Initialize("vh-height.html");
+ web_view->ResizeWithBrowserControls(WebSize(400, 300), WebSize(400, 300),
+ {100, 20, 0, 0, false, true});
+ web_view->GetBrowserControls().UpdateConstraintsAndState(
+ cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kShown);
+ web_view->GetBrowserControls().SetShownRatio(1, 1);
+ UpdateAllLifecyclePhases();
+
+ ASSERT_EQ(100.f, web_view->GetBrowserControls().ContentOffset());
+
+ // 'vh' units should be based on the viewport when the browser controls are
+ // hidden. However, the viewport height will be limited by the min-height
+ // since the top controls can't completely hide.
+ Element* abs_pos = GetElementById(WebString::FromUTF8("abs"));
+ Element* fixed_pos = GetElementById(WebString::FromUTF8("fixed"));
+ float div_height = 0.5f * (300 + (100 - 20));
+ EXPECT_FLOAT_EQ(div_height, abs_pos->getBoundingClientRect()->height());
+ EXPECT_FLOAT_EQ(div_height, fixed_pos->getBoundingClientRect()->height());
+
+ // The size used for viewport units should be reduced by the top controls
+ // min-height.
+ EXPECT_EQ(380, GetFrame()->View()->ViewportSizeForViewportUnits().Height());
+
+ // Scroll the top controls to hide. They won't scroll past the min-height.
+ VerticalScroll(-100.f);
+ web_view->ResizeWithBrowserControls(WebSize(400, 380), WebSize(400, 380),
+ {100, 20, 0, 0, false, false});
+ UpdateAllLifecyclePhases();
+
+ ASSERT_EQ(20.f, web_view->GetBrowserControls().ContentOffset());
+
+ // vh units should be static with respect to the browser controls so neither
+ // <div> should change size are a result of the browser controls hiding.
+ EXPECT_FLOAT_EQ(190.f, abs_pos->getBoundingClientRect()->height());
+ EXPECT_FLOAT_EQ(190.f, fixed_pos->getBoundingClientRect()->height());
+
+ // The viewport size used for vh units should not change as a result of top
+ // controls hiding.
+ ASSERT_EQ(380, GetFrame()->View()->ViewportSizeForViewportUnits().Height());
+}
+
+// Ensure that vh units are correctly calculated when a bottom controls
+// min-height is set.
+TEST_F(BrowserControlsTest, MAYBE(VHUnitsWithBottomMinHeight)) {
+ // Initialize with the browser controls showing.
+ // Top controls height: 100, top controls min-height: 20.
+ // Bottom controls height: 50, bottom controls min-height: 10.
+ WebViewImpl* web_view = Initialize("vh-height.html");
+ web_view->ResizeWithBrowserControls(WebSize(400, 250), WebSize(400, 250),
+ {100, 20, 50, 10, false, true});
+ web_view->GetBrowserControls().UpdateConstraintsAndState(
+ cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kShown);
+ web_view->GetBrowserControls().SetShownRatio(1, 1);
+ UpdateAllLifecyclePhases();
+
+ EXPECT_FLOAT_EQ(100.f, web_view->GetBrowserControls().ContentOffset());
+
+ // 'vh' units should be based on the viewport when the browser controls are
+ // hidden. However, the viewport height will be limited by the min-height
+ // since the top and bottom controls can't completely hide.
+ Element* abs_pos = GetElementById(WebString::FromUTF8("abs"));
+ Element* fixed_pos = GetElementById(WebString::FromUTF8("fixed"));
+ float div_height = 0.5f * (250 + (100 - 20) + (50 - 10));
+ EXPECT_FLOAT_EQ(div_height, abs_pos->getBoundingClientRect()->height());
+ EXPECT_FLOAT_EQ(div_height, fixed_pos->getBoundingClientRect()->height());
+
+ // The size used for viewport units should be reduced by the top/bottom
+ // controls min-height.
+ EXPECT_EQ(370, GetFrame()->View()->ViewportSizeForViewportUnits().Height());
+
+ // Scroll the controls to hide. They won't scroll past the min-height.
+ VerticalScroll(-100.f);
+ web_view->ResizeWithBrowserControls(WebSize(400, 370), WebSize(400, 370),
+ {100, 20, 50, 10, false, false});
+ UpdateAllLifecyclePhases();
+
+ EXPECT_FLOAT_EQ(20.f, web_view->GetBrowserControls().ContentOffset());
+ EXPECT_FLOAT_EQ(10.f, web_view->GetBrowserControls().BottomContentOffset());
+
+ // vh units should be static with respect to the browser controls so neither
+ // <div> should change size are a result of the browser controls hiding.
+ EXPECT_FLOAT_EQ(185.f, abs_pos->getBoundingClientRect()->height());
+ EXPECT_FLOAT_EQ(185.f, fixed_pos->getBoundingClientRect()->height());
+
+ // The viewport size used for vh units should not change as a result of the
+ // controls hiding.
+ ASSERT_EQ(370, GetFrame()->View()->ViewportSizeForViewportUnits().Height());
+}
+
+// Ensure that vh units are correctly calculated with changing min-heights.
+TEST_F(BrowserControlsTest, MAYBE(VHUnitsWithMinHeightsChanging)) {
+ // Initialize with the browser controls showing.
+ // Top controls height: 100, top controls min-height: 20.
+ // Bottom controls height: 50, bottom controls min-height: 10.
+ WebViewImpl* web_view = Initialize("vh-height.html");
+ web_view->ResizeWithBrowserControls(WebSize(400, 250), WebSize(400, 250),
+ {100, 20, 50, 10, false, true});
+ web_view->GetBrowserControls().UpdateConstraintsAndState(
+ cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kShown);
+ web_view->GetBrowserControls().SetShownRatio(1, 1);
+ UpdateAllLifecyclePhases();
+
+ EXPECT_FLOAT_EQ(100.f, web_view->GetBrowserControls().ContentOffset());
+
+ // 'vh' units should be based on the viewport when the browser controls are
+ // hidden. However, the viewport height will be limited by the min-height
+ // since the top and bottom controls can't completely hide.
+ Element* abs_pos = GetElementById(WebString::FromUTF8("abs"));
+ Element* fixed_pos = GetElementById(WebString::FromUTF8("fixed"));
+ float div_height = 0.5f * (250 + (100 - 20) + (50 - 10));
+ EXPECT_FLOAT_EQ(div_height, abs_pos->getBoundingClientRect()->height());
+ EXPECT_FLOAT_EQ(div_height, fixed_pos->getBoundingClientRect()->height());
+
+ // The size used for viewport units should be reduced by the top/bottom
+ // controls min-height.
+ EXPECT_EQ(370, GetFrame()->View()->ViewportSizeForViewportUnits().Height());
+
+ // Make the min-heights 0.
+ web_view->ResizeWithBrowserControls(WebSize(400, 250), WebSize(400, 250),
+ {100, 0, 50, 0, false, true});
+ UpdateAllLifecyclePhases();
+
+ // The viewport size used for vh units should be updated to reflect the change
+ // to the min-heights.
+ float height = 250 + (100 - 0) + (50 - 0);
+ ASSERT_EQ(height,
+ GetFrame()->View()->ViewportSizeForViewportUnits().Height());
+}
+
// This tests that the viewport remains anchored when browser controls are
// brought in while the document is fully scrolled. This normally causes
// clamping of the visual viewport to keep it bounded by the layout viewport
@@ -1108,7 +1289,7 @@ TEST_F(BrowserControlsTest,
web_view->ResizeWithBrowserControls(WebSize(800, layout_viewport_height),
browser_controls_height, 0, true);
web_view->GetBrowserControls().UpdateConstraintsAndState(
- cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kShown, false);
+ cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kShown);
web_view->GetBrowserControls().SetShownRatio(1, 1);
UpdateAllLifecyclePhases();
@@ -1171,7 +1352,8 @@ TEST_F(BrowserControlsTest,
GetVisualViewport().ClampToBoundaries();
view->LayoutViewport()->SetScrollOffset(
- view->LayoutViewport()->GetScrollOffset(), kProgrammaticScroll);
+ view->LayoutViewport()->GetScrollOffset(),
+ mojom::blink::ScrollType::kProgrammatic);
ASSERT_EQ(80.f, web_view->GetBrowserControls().ContentOffset());
EXPECT_EQ(expected_root_offset, root_viewport->GetScrollOffset().Height());
@@ -1219,7 +1401,7 @@ TEST_F(BrowserControlsSimTest, MAYBE(ViewportUnitsWhenControlsLocked)) {
<div id="spacer"></div>
)HTML");
WebView().ResizeWithBrowserControls(WebSize(400, 300), 100.f, 0, true);
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kShown, false);
Compositor().BeginFrame();
@@ -1232,7 +1414,7 @@ TEST_F(BrowserControlsSimTest, MAYBE(ViewportUnitsWhenControlsLocked)) {
// Lock the browser controls to hidden.
{
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kHidden, cc::BrowserControlsState::kHidden,
false);
WebView().ResizeWithBrowserControls(WebSize(400, 400), 100.f, 0, false);
@@ -1253,7 +1435,7 @@ TEST_F(BrowserControlsSimTest, MAYBE(ViewportUnitsWhenControlsLocked)) {
// Lock the browser controls to shown. This should cause the vh units to
// behave as usual by including the browser controls region in 100vh.
{
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kShown, cc::BrowserControlsState::kShown,
false);
WebView().ResizeWithBrowserControls(WebSize(400, 300), 100.f, 0, true);
@@ -1316,8 +1498,7 @@ TEST_F(BrowserControlsTest, MAYBE(GrowingHeightKeepsTopControlsHidden)) {
bottom_height, false);
web_view->GetBrowserControls().UpdateConstraintsAndState(
- cc::BrowserControlsState::kHidden, cc::BrowserControlsState::kHidden,
- false);
+ cc::BrowserControlsState::kHidden, cc::BrowserControlsState::kHidden);
// As we expand the top controls height while hidden, the content offset
// shouldn't change.
@@ -1459,12 +1640,12 @@ TEST_F(BrowserControlsSimTest, MixAnimatedAndNonAnimatedUpdateState) {
ASSERT_EQ(1.f, WebView().GetBrowserControls().TopShownRatio());
// Kick off a non-animated clamp to hide the top controls.
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kHidden, cc::BrowserControlsState::kBoth,
false /* animated */);
// Now kick off an animated one to do the same thing.
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kHidden, cc::BrowserControlsState::kBoth,
true /* animated */);
@@ -1507,7 +1688,7 @@ TEST_F(BrowserControlsSimTest, HideAnimated) {
ASSERT_EQ(1.f, WebView().GetBrowserControls().BottomShownRatio());
// Kick off an animated hide.
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kHidden,
true /* animated */);
@@ -1541,7 +1722,7 @@ TEST_F(BrowserControlsSimTest, ShowAnimated) {
)HTML");
Compositor().BeginFrame();
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kHidden,
false);
@@ -1551,7 +1732,7 @@ TEST_F(BrowserControlsSimTest, ShowAnimated) {
ASSERT_EQ(0.f, WebView().GetBrowserControls().BottomShownRatio());
// Kick off an animated show.
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kShown,
true /* animated */);
@@ -1594,22 +1775,20 @@ TEST_F(BrowserControlsSimTest, ConstraintDoesntClampRatioInBlink) {
{
// Pass a hidden constraint to Blink (without going through CC). Make sure
- // the shown ratio doesn't change since CC is repsonsible for updating the
+ // the shown ratio doesn't change since CC is responsible for updating the
// ratio.
WebView().GetBrowserControls().UpdateConstraintsAndState(
- cc::BrowserControlsState::kHidden, cc::BrowserControlsState::kBoth,
- true /* animated */);
+ cc::BrowserControlsState::kHidden, cc::BrowserControlsState::kBoth);
EXPECT_EQ(1.f, WebView().GetBrowserControls().TopShownRatio());
EXPECT_EQ(1.f, WebView().GetBrowserControls().BottomShownRatio());
WebView().GetBrowserControls().UpdateConstraintsAndState(
- cc::BrowserControlsState::kHidden, cc::BrowserControlsState::kBoth,
- false /* animated */);
+ cc::BrowserControlsState::kHidden, cc::BrowserControlsState::kBoth);
EXPECT_EQ(1.f, WebView().GetBrowserControls().TopShownRatio());
EXPECT_EQ(1.f, WebView().GetBrowserControls().BottomShownRatio());
// Constrain the controls to hidden from the compositor. This should
// actually cause the controls to hide when we commit.
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kHidden,
false /* animated */);
Compositor().BeginFrame();
@@ -1622,19 +1801,17 @@ TEST_F(BrowserControlsSimTest, ConstraintDoesntClampRatioInBlink) {
// Pass a shown constraint to Blink (without going through CC). Make sure
// the shown ratio doesn't change.
WebView().GetBrowserControls().UpdateConstraintsAndState(
- cc::BrowserControlsState::kShown, cc::BrowserControlsState::kBoth,
- true /* animated */);
+ cc::BrowserControlsState::kShown, cc::BrowserControlsState::kBoth);
EXPECT_EQ(0.f, WebView().GetBrowserControls().TopShownRatio());
EXPECT_EQ(0.f, WebView().GetBrowserControls().BottomShownRatio());
WebView().GetBrowserControls().UpdateConstraintsAndState(
- cc::BrowserControlsState::kShown, cc::BrowserControlsState::kBoth,
- false /* animated */);
+ cc::BrowserControlsState::kShown, cc::BrowserControlsState::kBoth);
EXPECT_EQ(0.f, WebView().GetBrowserControls().TopShownRatio());
EXPECT_EQ(0.f, WebView().GetBrowserControls().BottomShownRatio());
// Constrain the controls to hidden from the compositor. This should
// actually cause the controls to hide when we commit.
- Compositor().layer_tree_host().UpdateBrowserControlsState(
+ Compositor().layer_tree_host()->UpdateBrowserControlsState(
cc::BrowserControlsState::kBoth, cc::BrowserControlsState::kShown,
false /* animated */);
Compositor().BeginFrame();
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 1617629f688..80d48328047 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
@@ -28,17 +28,19 @@
#include <memory>
#include <utility>
+#include "base/debug/dump_without_crashing.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/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_url_request.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/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_security_policy_violation_event_init.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_string_list.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/events/event_queue.h"
-#include "third_party/blink/renderer/core/events/security_policy_violation_event_init.h"
#include "third_party/blink/renderer/core/frame/csp/csp_directive_list.h"
#include "third_party/blink/renderer/core/frame/csp/csp_source.h"
#include "third_party/blink/renderer/core/frame/csp/media_list_directive.h"
@@ -52,6 +54,7 @@
#include "third_party/blink/renderer/core/html/html_script_element.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.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/json/json_values.h"
#include "third_party/blink/renderer/platform/loader/fetch/integrity_metadata.h"
@@ -72,20 +75,23 @@
namespace blink {
+using network::mojom::ContentSecurityPolicySource;
+using network::mojom::ContentSecurityPolicyType;
+
namespace {
// Helper function that returns true if the given |header_type| should be
// checked when the CheckHeaderType is |check_header_type|.
bool CheckHeaderTypeMatches(
ContentSecurityPolicy::CheckHeaderType check_header_type,
- ContentSecurityPolicyHeaderType header_type) {
+ ContentSecurityPolicyType header_type) {
switch (check_header_type) {
case ContentSecurityPolicy::CheckHeaderType::kCheckAll:
return true;
case ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly:
- return header_type == kContentSecurityPolicyHeaderTypeReport;
+ return header_type == ContentSecurityPolicyType::kReport;
case ContentSecurityPolicy::CheckHeaderType::kCheckEnforce:
- return header_type == kContentSecurityPolicyHeaderTypeEnforce;
+ return header_type == ContentSecurityPolicyType::kEnforce;
}
NOTREACHED();
return false;
@@ -134,12 +140,11 @@ bool ContentSecurityPolicy::IsNonceableElement(const Element* element) {
return nonceable;
}
-static WebFeature GetUseCounterHelperType(
- ContentSecurityPolicyHeaderType type) {
+static WebFeature GetUseCounterHelperType(ContentSecurityPolicyType type) {
switch (type) {
- case kContentSecurityPolicyHeaderTypeEnforce:
+ case ContentSecurityPolicyType::kEnforce:
return WebFeature::kContentSecurityPolicy;
- case kContentSecurityPolicyHeaderTypeReport:
+ case ContentSecurityPolicyType::kReport:
return WebFeature::kContentSecurityPolicyReportOnly;
}
NOTREACHED();
@@ -151,9 +156,10 @@ ContentSecurityPolicy::ContentSecurityPolicy()
override_inline_style_allowed_(false),
script_hash_algorithms_used_(kContentSecurityPolicyHashAlgorithmNone),
style_hash_algorithms_used_(kContentSecurityPolicyHashAlgorithmNone),
- sandbox_mask_(WebSandboxFlags::kNone),
+ sandbox_mask_(mojom::blink::WebSandboxFlags::kNone),
require_trusted_types_(false),
- insecure_request_policy_(kLeaveInsecureRequestsAlone) {}
+ insecure_request_policy_(
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone) {}
bool ContentSecurityPolicy::IsBound() {
return delegate_;
@@ -194,13 +200,20 @@ void ContentSecurityPolicy::ApplyPolicySideEffectsToDelegate() {
// Set mixed content checking and sandbox flags, then dump all the parsing
// error messages, then poke at histograms.
- if (sandbox_mask_ != WebSandboxFlags::kNone) {
+ if (sandbox_mask_ != mojom::blink::WebSandboxFlags::kNone) {
Count(WebFeature::kSandboxViaCSP);
delegate_->SetSandboxFlags(sandbox_mask_);
}
- if (require_trusted_types_)
- delegate_->SetRequireTrustedTypes();
+ if (require_trusted_types_) {
+ if (delegate_->GetSecureContextMode() ==
+ SecureContextMode::kSecureContext) {
+ delegate_->SetRequireTrustedTypes();
+ Count(WebFeature::kTrustedTypesEnabled);
+ } else {
+ ReportNonsecureTrustedTypes();
+ }
+ }
delegate_->AddInsecureRequestPolicy(insecure_request_policy_);
@@ -217,10 +230,55 @@ void ContentSecurityPolicy::ApplyPolicySideEffectsToDelegate() {
Count(WebFeature::kCSPWithStrictDynamic);
}
- if (policy->AllowEval(SecurityViolationReportingPolicy::kSuppressReporting,
+ if (policy->AllowEval(ReportingDisposition::kSuppressReporting,
kWillNotThrowException, g_empty_string)) {
Count(WebFeature::kCSPWithUnsafeEval);
}
+
+ // We consider a policy to be "reasonably secure" if it:
+ //
+ // 1. Asserts `object-src 'none'`.
+ // 2. Asserts `base-uri 'none'` or `base-uri 'self'`.
+ // 3. Avoids URL-based matching, in favor of hashes and nonces.
+ //
+ // https://chromium.googlesource.com/chromium/src/+/master/docs/security/web-mitigation-metrics.md
+ // has more detail.
+ if (policy->IsObjectRestrictionReasonable()) {
+ Count(policy->HeaderType() == ContentSecurityPolicyType::kEnforce
+ ? WebFeature::kCSPWithReasonableObjectRestrictions
+ : WebFeature::kCSPROWithReasonableObjectRestrictions);
+ }
+ if (policy->IsBaseRestrictionReasonable()) {
+ Count(policy->HeaderType() == ContentSecurityPolicyType::kEnforce
+ ? WebFeature::kCSPWithReasonableBaseRestrictions
+ : WebFeature::kCSPROWithReasonableBaseRestrictions);
+ }
+ if (policy->IsScriptRestrictionReasonable()) {
+ Count(policy->HeaderType() == ContentSecurityPolicyType::kEnforce
+ ? WebFeature::kCSPWithReasonableScriptRestrictions
+ : WebFeature::kCSPROWithReasonableScriptRestrictions);
+ }
+ if (policy->IsObjectRestrictionReasonable() &&
+ policy->IsBaseRestrictionReasonable() &&
+ policy->IsScriptRestrictionReasonable()) {
+ Count(policy->HeaderType() == ContentSecurityPolicyType::kEnforce
+ ? WebFeature::kCSPWithReasonableRestrictions
+ : WebFeature::kCSPROWithReasonableRestrictions);
+
+ if (!policy->AllowDynamic(
+ ContentSecurityPolicy::DirectiveType::kScriptSrcElem)) {
+ Count(policy->HeaderType() == ContentSecurityPolicyType::kEnforce
+ ? WebFeature::kCSPWithBetterThanReasonableRestrictions
+ : WebFeature::kCSPROWithBetterThanReasonableRestrictions);
+ }
+ }
+ if (policy->RequiresTrustedTypes()) {
+ Count(policy->IsReportOnly() ? WebFeature::kTrustedTypesEnabledReportOnly
+ : WebFeature::kTrustedTypesEnabledEnforcing);
+ }
+ if (policy->TrustedTypesAllowDuplicates()) {
+ Count(WebFeature::kTrustedTypesAllowDuplicates);
+ }
}
// We disable 'eval()' even in the case of report-only policies, and rely on
@@ -232,7 +290,7 @@ void ContentSecurityPolicy::ApplyPolicySideEffectsToDelegate() {
ContentSecurityPolicy::~ContentSecurityPolicy() = default;
-void ContentSecurityPolicy::Trace(blink::Visitor* visitor) {
+void ContentSecurityPolicy::Trace(Visitor* visitor) {
visitor->Trace(delegate_);
visitor->Trace(policies_);
visitor->Trace(console_messages_);
@@ -260,23 +318,24 @@ void ContentSecurityPolicy::CopyPluginTypesFrom(
void ContentSecurityPolicy::DidReceiveHeaders(
const ContentSecurityPolicyResponseHeaders& headers) {
- if (headers.ShouldParseWasmEval()) {
+ if (headers.ShouldParseWasmEval())
supports_wasm_eval_ = true;
- }
- if (!headers.ContentSecurityPolicy().IsEmpty())
+ if (!headers.ContentSecurityPolicy().IsEmpty()) {
AddAndReportPolicyFromHeaderValue(headers.ContentSecurityPolicy(),
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
- if (!headers.ContentSecurityPolicyReportOnly().IsEmpty())
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
+ }
+ if (!headers.ContentSecurityPolicyReportOnly().IsEmpty()) {
AddAndReportPolicyFromHeaderValue(headers.ContentSecurityPolicyReportOnly(),
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kHTTP);
+ }
}
void ContentSecurityPolicy::DidReceiveHeader(
const String& header,
- ContentSecurityPolicyHeaderType type,
- ContentSecurityPolicyHeaderSource source) {
+ ContentSecurityPolicyType type,
+ ContentSecurityPolicySource source) {
AddAndReportPolicyFromHeaderValue(header, type, source);
// This might be called after we've been bound to a delegate. For example, a
@@ -314,16 +373,16 @@ bool ContentSecurityPolicy::ShouldEnforceEmbeddersPolicy(
void ContentSecurityPolicy::AddPolicyFromHeaderValue(
const String& header,
- ContentSecurityPolicyHeaderType type,
- ContentSecurityPolicyHeaderSource source) {
+ ContentSecurityPolicyType type,
+ ContentSecurityPolicySource source) {
// If this is a report-only header inside a <meta> element, bail out.
- if (source == kContentSecurityPolicyHeaderSourceMeta &&
- type == kContentSecurityPolicyHeaderTypeReport) {
+ if (source == ContentSecurityPolicySource::kMeta &&
+ type == ContentSecurityPolicyType::kReport) {
ReportReportOnlyInMeta(header);
return;
}
- if (source == kContentSecurityPolicyHeaderSourceHTTP)
+ if (source == ContentSecurityPolicySource::kHTTP)
header_delivered_ = true;
Vector<UChar> characters;
@@ -357,22 +416,18 @@ void ContentSecurityPolicy::AddPolicyFromHeaderValue(
}
}
-void ContentSecurityPolicy::ReportAccumulatedHeaders(
- LocalFrameClient* client) const {
- // Notify the embedder about headers that have accumulated before the
- // navigation got committed. See comments in
- // addAndReportPolicyFromHeaderValue for more details and context.
- DCHECK(client);
- WebVector<WebContentSecurityPolicy> policies(policies_.size());
- for (wtf_size_t i = 0; i < policies_.size(); ++i)
- policies[i] = policies_[i]->ExposeForNavigationalChecks();
- client->DidAddContentSecurityPolicies(policies);
+void ContentSecurityPolicy::ReportAccumulatedHeaders(LocalFrame* frame) const {
+ WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr> policies;
+ for (const auto& policy : policies_)
+ policies.push_back(policy->ExposeForNavigationalChecks());
+ frame->GetLocalFrameHostRemote().DidAddContentSecurityPolicies(
+ std::move(policies));
}
void ContentSecurityPolicy::AddAndReportPolicyFromHeaderValue(
const String& header,
- ContentSecurityPolicyHeaderType type,
- ContentSecurityPolicyHeaderSource source) {
+ ContentSecurityPolicyType type,
+ ContentSecurityPolicySource source) {
wtf_size_t previous_policy_count = policies_.size();
AddPolicyFromHeaderValue(header, type, source);
// Notify about the new header, so that it can be reported back to the
@@ -384,15 +439,15 @@ void ContentSecurityPolicy::AddAndReportPolicyFromHeaderValue(
// TODO(arthursonzogni): policies are actually replicated (1) and some of
// them are enforced on the browser process (2). Stop doing (1) when (2) is
// finished.
- WebVector<WebContentSecurityPolicy> policies(policies_.size() -
- previous_policy_count);
+ WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr> policies(
+ policies_.size() - previous_policy_count);
for (wtf_size_t i = previous_policy_count; i < policies_.size(); ++i) {
policies[i - previous_policy_count] =
policies_[i]->ExposeForNavigationalChecks();
}
if (delegate_)
- delegate_->DidAddContentSecurityPolicies(policies);
+ delegate_->DidAddContentSecurityPolicies(std::move(policies));
}
void ContentSecurityPolicy::SetOverrideAllowInlineStyle(bool value) {
@@ -479,7 +534,7 @@ bool ContentSecurityPolicy::AllowInline(
const String& nonce,
const String& context_url,
const WTF::OrdinalNumber& context_line,
- SecurityViolationReportingPolicy reporting_policy) const {
+ ReportingDisposition reporting_disposition) const {
DCHECK(element || inline_type == InlineType::kScriptAttribute ||
inline_type == InlineType::kNavigation);
@@ -506,7 +561,7 @@ bool ContentSecurityPolicy::AllowInline(
is_allowed &=
CheckHashAgainstPolicy(csp_hash_values, policy, inline_type) ||
policy->AllowInline(inline_type, element, content, nonce, context_url,
- context_line, reporting_policy);
+ context_line, reporting_disposition);
}
return is_allowed;
@@ -525,25 +580,33 @@ bool ContentSecurityPolicy::IsScriptInlineType(InlineType inline_type) {
}
}
+bool ContentSecurityPolicy::ShouldCheckEval() const {
+ for (const auto& policy : policies_) {
+ if (policy->ShouldCheckEval())
+ return true;
+ }
+ return IsRequireTrustedTypes();
+}
+
bool ContentSecurityPolicy::AllowEval(
- SecurityViolationReportingPolicy reporting_policy,
+ ReportingDisposition reporting_disposition,
ContentSecurityPolicy::ExceptionStatus exception_status,
const String& script_content) const {
bool is_allowed = true;
for (const auto& policy : policies_) {
- is_allowed &=
- policy->AllowEval(reporting_policy, exception_status, script_content);
+ is_allowed &= policy->AllowEval(reporting_disposition, exception_status,
+ script_content);
}
return is_allowed;
}
bool ContentSecurityPolicy::AllowWasmEval(
- SecurityViolationReportingPolicy reporting_policy,
+ ReportingDisposition reporting_disposition,
ContentSecurityPolicy::ExceptionStatus exception_status,
const String& script_content) const {
bool is_allowed = true;
for (const auto& policy : policies_) {
- is_allowed &= policy->AllowWasmEval(reporting_policy, exception_status,
+ is_allowed &= policy->AllowWasmEval(reporting_disposition, exception_status,
script_content);
}
return is_allowed;
@@ -551,9 +614,8 @@ bool ContentSecurityPolicy::AllowWasmEval(
String ContentSecurityPolicy::EvalDisabledErrorMessage() const {
for (const auto& policy : policies_) {
- if (policy->ShouldDisableEval()) {
+ if (policy->ShouldDisableEval())
return policy->EvalDisabledErrorMessage();
- }
}
return String();
}
@@ -562,9 +624,10 @@ bool ContentSecurityPolicy::AllowPluginType(
const String& type,
const String& type_attribute,
const KURL& url,
- SecurityViolationReportingPolicy reporting_policy) const {
+ ReportingDisposition reporting_disposition) const {
for (const auto& policy : policies_) {
- if (!policy->AllowPluginType(type, type_attribute, url, reporting_policy))
+ if (!policy->AllowPluginType(type, type_attribute, url,
+ reporting_disposition))
return false;
}
return true;
@@ -575,10 +638,10 @@ bool ContentSecurityPolicy::AllowPluginTypeForDocument(
const String& type,
const String& type_attribute,
const KURL& url,
- SecurityViolationReportingPolicy reporting_policy) const {
+ ReportingDisposition reporting_disposition) const {
if (document.GetContentSecurityPolicy() &&
!document.GetContentSecurityPolicy()->AllowPluginType(
- type, type_attribute, url, reporting_policy))
+ type, type_attribute, url, reporting_disposition))
return false;
return true;
@@ -588,12 +651,12 @@ bool ContentSecurityPolicy::AllowRequestWithoutIntegrity(
mojom::RequestContextType context,
const KURL& url,
RedirectStatus redirect_status,
- SecurityViolationReportingPolicy reporting_policy,
+ ReportingDisposition reporting_disposition,
CheckHeaderType check_header_type) const {
for (const auto& policy : policies_) {
if (CheckHeaderTypeMatches(check_header_type, policy->HeaderType()) &&
!policy->AllowRequestWithoutIntegrity(context, url, redirect_status,
- reporting_policy))
+ reporting_disposition))
return false;
}
return true;
@@ -671,11 +734,11 @@ bool ContentSecurityPolicy::AllowRequest(
const IntegrityMetadataSet& integrity_metadata,
ParserDisposition parser_disposition,
RedirectStatus redirect_status,
- SecurityViolationReportingPolicy reporting_policy,
+ ReportingDisposition reporting_disposition,
CheckHeaderType check_header_type) const {
if (integrity_metadata.IsEmpty() &&
!AllowRequestWithoutIntegrity(context, url, redirect_status,
- reporting_policy, check_header_type)) {
+ reporting_disposition, check_header_type)) {
return false;
}
@@ -683,7 +746,7 @@ bool ContentSecurityPolicy::AllowRequest(
GetDirectiveTypeFromRequestContextType(context);
if (!type)
return true;
- return AllowFromSource(*type, url, redirect_status, reporting_policy,
+ return AllowFromSource(*type, url, redirect_status, reporting_disposition,
check_header_type, nonce, integrity_metadata,
parser_disposition);
}
@@ -700,7 +763,7 @@ bool ContentSecurityPolicy::AllowFromSource(
ContentSecurityPolicy::DirectiveType type,
const KURL& url,
RedirectStatus redirect_status,
- SecurityViolationReportingPolicy reporting_policy,
+ ReportingDisposition reporting_disposition,
CheckHeaderType check_header_type,
const String& nonce,
const IntegrityMetadataSet& hashes,
@@ -739,9 +802,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_policy,
- nonce, hashes, parser_disposition);
+ is_allowed &= policy->AllowFromSource(type, url, redirect_status,
+ reporting_disposition, nonce, hashes,
+ parser_disposition);
}
return is_allowed;
@@ -757,10 +820,11 @@ bool ContentSecurityPolicy::AllowBaseURI(const KURL& url) const {
bool ContentSecurityPolicy::AllowConnectToSource(
const KURL& url,
RedirectStatus redirect_status,
- SecurityViolationReportingPolicy reporting_policy,
+ ReportingDisposition reporting_disposition,
CheckHeaderType check_header_type) const {
return AllowFromSource(ContentSecurityPolicy::DirectiveType::kConnectSrc, url,
- redirect_status, reporting_policy, check_header_type);
+ redirect_status, reporting_disposition,
+ check_header_type);
}
bool ContentSecurityPolicy::AllowFormAction(const KURL& url) const {
@@ -771,10 +835,11 @@ bool ContentSecurityPolicy::AllowFormAction(const KURL& url) const {
bool ContentSecurityPolicy::AllowImageFromSource(
const KURL& url,
RedirectStatus redirect_status,
- SecurityViolationReportingPolicy reporting_policy,
+ ReportingDisposition reporting_disposition,
CheckHeaderType check_header_type) const {
return AllowFromSource(ContentSecurityPolicy::DirectiveType::kImgSrc, url,
- redirect_status, reporting_policy, check_header_type);
+ redirect_status, reporting_disposition,
+ check_header_type);
}
bool ContentSecurityPolicy::AllowMediaFromSource(const KURL& url) const {
@@ -791,10 +856,10 @@ bool ContentSecurityPolicy::AllowScriptFromSource(
const IntegrityMetadataSet& hashes,
ParserDisposition parser_disposition,
RedirectStatus redirect_status,
- SecurityViolationReportingPolicy reporting_policy,
+ ReportingDisposition reporting_disposition,
CheckHeaderType check_header_type) const {
return AllowFromSource(ContentSecurityPolicy::DirectiveType::kScriptSrcElem,
- url, redirect_status, reporting_policy,
+ url, redirect_status, reporting_disposition,
check_header_type, nonce, hashes, parser_disposition);
}
@@ -820,10 +885,10 @@ bool ContentSecurityPolicy::AllowTrustedTypePolicy(const String& policy_name,
bool ContentSecurityPolicy::AllowAncestors(
LocalFrame* frame,
const KURL& url,
- SecurityViolationReportingPolicy reporting_policy) const {
+ ReportingDisposition reporting_disposition) const {
bool is_allowed = true;
for (const auto& policy : policies_)
- is_allowed &= policy->AllowAncestors(frame, url, reporting_policy);
+ is_allowed &= policy->AllowAncestors(frame, url, reporting_disposition);
return is_allowed;
}
@@ -837,10 +902,12 @@ bool ContentSecurityPolicy::IsFrameAncestorsEnforced() const {
bool ContentSecurityPolicy::AllowTrustedTypeAssignmentFailure(
const String& message,
- const String& sample) const {
+ const String& sample,
+ const String& sample_prefix) const {
bool allow = true;
for (const auto& policy : policies_) {
- allow &= policy->AllowTrustedTypeAssignmentFailure(message, sample);
+ allow &= policy->AllowTrustedTypeAssignmentFailure(message, sample,
+ sample_prefix);
}
return allow;
}
@@ -872,11 +939,13 @@ void ContentSecurityPolicy::RequireTrustedTypes() {
}
void ContentSecurityPolicy::EnforceStrictMixedContentChecking() {
- insecure_request_policy_ |= kBlockAllMixedContent;
+ insecure_request_policy_ |=
+ mojom::blink::InsecureRequestPolicy::kBlockAllMixedContent;
}
void ContentSecurityPolicy::UpgradeInsecureRequests() {
- insecure_request_policy_ |= kUpgradeInsecureRequests;
+ insecure_request_policy_ |=
+ mojom::blink::InsecureRequestPolicy::kUpgradeInsecureRequests;
}
static String StripURLForUseInReport(
@@ -916,10 +985,11 @@ static void GatherSecurityPolicyViolationEventData(
const KURL& blocked_url,
const String& header,
RedirectStatus redirect_status,
- ContentSecurityPolicyHeaderType header_type,
+ ContentSecurityPolicyType header_type,
ContentSecurityPolicy::ViolationType violation_type,
std::unique_ptr<SourceLocation> source_location,
- const String& script_source) {
+ const String& script_source,
+ const String& sample_prefix) {
if (effective_type == ContentSecurityPolicy::DirectiveType::kFrameAncestors) {
// If this load was blocked via 'frame-ancestors', then the URL of
// |document| has not yet been initialized. In this case, we'll set both
@@ -961,7 +1031,7 @@ static void GatherSecurityPolicyViolationEventData(
init->setViolatedDirective(effective_directive);
init->setEffectiveDirective(effective_directive);
init->setOriginalPolicy(header);
- init->setDisposition(header_type == kContentSecurityPolicyHeaderTypeEnforce
+ init->setDisposition(header_type == ContentSecurityPolicyType::kEnforce
? "enforce"
: "report");
init->setStatusCode(0);
@@ -1000,10 +1070,23 @@ static void GatherSecurityPolicyViolationEventData(
init->setColumnNumber(0);
}
+ // Build the sample string. CSP demands that the sample is restricted to
+ // 40 characters (kMaxSampleLength), to prevent inadvertent exfiltration of
+ // user data. For some use cases, we also have a sample prefix, which
+ // must not depend on user data and where we will apply the sample limit
+ // separately.
+ StringBuilder sample;
+ if (!sample_prefix.IsEmpty()) {
+ sample.Append(sample_prefix.StripWhiteSpace().Left(
+ ContentSecurityPolicy::kMaxSampleLength));
+ sample.Append("|");
+ }
if (!script_source.IsEmpty()) {
- init->setSample(script_source.StripWhiteSpace().Left(
+ sample.Append(script_source.StripWhiteSpace().Left(
ContentSecurityPolicy::kMaxSampleLength));
}
+ if (!sample.IsEmpty())
+ init->setSample(sample.ToString());
}
void ContentSecurityPolicy::ReportViolation(
@@ -1014,13 +1097,14 @@ void ContentSecurityPolicy::ReportViolation(
const Vector<String>& report_endpoints,
bool use_reporting_api,
const String& header,
- ContentSecurityPolicyHeaderType header_type,
+ ContentSecurityPolicyType header_type,
ViolationType violation_type,
std::unique_ptr<SourceLocation> source_location,
LocalFrame* context_frame,
RedirectStatus redirect_status,
Element* element,
- const String& source) {
+ const String& source,
+ const String& source_prefix) {
DCHECK(violation_type == kURLViolation || blocked_url.IsEmpty());
// TODO(lukasza): Support sending reports from OOPIFs -
@@ -1029,7 +1113,9 @@ void ContentSecurityPolicy::ReportViolation(
if (!delegate_ && !context_frame) {
DCHECK(effective_type == DirectiveType::kChildSrc ||
effective_type == DirectiveType::kFrameSrc ||
- effective_type == DirectiveType::kPluginTypes);
+ effective_type == DirectiveType::kPluginTypes ||
+ effective_type == DirectiveType::kTrustedTypes ||
+ effective_type == DirectiveType::kRequireTrustedTypesFor);
return;
}
@@ -1050,7 +1136,7 @@ void ContentSecurityPolicy::ReportViolation(
GatherSecurityPolicyViolationEventData(
violation_data, relevant_delegate, directive_text, effective_type,
blocked_url, header, redirect_status, header_type, violation_type,
- std::move(source_location), source);
+ std::move(source_location), source, source_prefix);
// TODO(mkwst): Obviously, we shouldn't hit this check, as extension-loaded
// resources should be allowed regardless. We apparently do, however, so
@@ -1162,6 +1248,13 @@ void ContentSecurityPolicy::ReportValueForEmptyDirective(const String& name,
"'. The directive has been applied, and the value ignored.");
}
+void ContentSecurityPolicy::ReportNonsecureTrustedTypes() {
+ LogToConsole(
+ "The Content Security Policy directive "
+ "'require-trusted-types-for' only has an effect in a secure "
+ "context. The directive has been ignored.");
+}
+
void ContentSecurityPolicy::ReportInvalidInReportOnly(const String& name) {
LogToConsole("The Content Security Policy directive '" + name +
"' is ignored when delivered in a report-only policy.");
@@ -1314,8 +1407,8 @@ void ContentSecurityPolicy::ReportMissingReportURI(const String& policy) {
void ContentSecurityPolicy::LogToConsole(const String& message,
mojom::ConsoleMessageLevel level) {
- LogToConsole(ConsoleMessage::Create(mojom::ConsoleMessageSource::kSecurity,
- level, message));
+ LogToConsole(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kSecurity, level, message));
}
void ContentSecurityPolicy::LogToConsole(ConsoleMessage* console_message,
@@ -1452,6 +1545,8 @@ const char* ContentSecurityPolicy::GetDirectiveName(const DirectiveType& type) {
return "report-to";
case DirectiveType::kNavigateTo:
return "navigate-to";
+ case DirectiveType::kRequireTrustedTypesFor:
+ return "require-trusted-types-for";
case DirectiveType::kUndefined:
NOTREACHED();
return "";
@@ -1497,6 +1592,8 @@ ContentSecurityPolicy::DirectiveType ContentSecurityPolicy::GetDirectiveType(
return DirectiveType::kReportURI;
if (name == "require-sri-for")
return DirectiveType::kRequireSRIFor;
+ if (name == "require-trusted-types-for")
+ return DirectiveType::kRequireTrustedTypesFor;
if (name == "trusted-types")
return DirectiveType::kTrustedTypes;
if (name == "sandbox")
@@ -1571,8 +1668,8 @@ bool ContentSecurityPolicy::IsValidCSPAttr(const String& attr,
auto* attr_policy = MakeGarbageCollected<ContentSecurityPolicy>();
attr_policy->AddPolicyFromHeaderValue(attr,
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
if (!attr_policy->console_messages_.IsEmpty() ||
attr_policy->policies_.size() != 1) {
return false;
@@ -1589,9 +1686,9 @@ bool ContentSecurityPolicy::IsValidCSPAttr(const String& attr,
}
auto* context_policy = MakeGarbageCollected<ContentSecurityPolicy>();
- context_policy->AddPolicyFromHeaderValue(
- context_required_csp, kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ context_policy->AddPolicyFromHeaderValue(context_required_csp,
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
DCHECK(context_policy->console_messages_.IsEmpty() &&
context_policy->policies_.size() == 1);
@@ -1599,21 +1696,16 @@ bool ContentSecurityPolicy::IsValidCSPAttr(const String& attr,
return context_policy->Subsumes(*attr_policy);
}
-WebContentSecurityPolicyList
+WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr>
ContentSecurityPolicy::ExposeForNavigationalChecks() const {
- WebContentSecurityPolicyList list;
- for (const auto& policy : policies_) {
- list.policies.emplace_back(policy->ExposeForNavigationalChecks());
- }
-
- if (self_source_)
- list.self_source = self_source_->ExposeForNavigationalChecks();
-
+ WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr> list;
+ for (const auto& policy : policies_)
+ list.push_back(policy->ExposeForNavigationalChecks());
return list;
}
bool ContentSecurityPolicy::HasPolicyFromSource(
- ContentSecurityPolicyHeaderSource source) const {
+ ContentSecurityPolicySource source) const {
for (const auto& policy : policies_) {
if (policy->HeaderSource() == source)
return true;
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 101100a01f8..54d3b7c35e7 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
@@ -29,9 +29,10 @@
#include <memory>
#include <utility>
+#include "services/network/public/mojom/content_security_policy.mojom-blink.h"
#include "third_party/blink/public/mojom/devtools/console_message.mojom-blink.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink-forward.h"
#include "third_party/blink/public/platform/web_content_security_policy_struct.h"
-#include "third_party/blink/public/platform/web_insecure_request_policy.h"
#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/execution_context/security_context.h"
@@ -43,8 +44,8 @@
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h"
#include "third_party/blink/renderer/platform/network/http_parsers.h"
+#include "third_party/blink/renderer/platform/weborigin/reporting_disposition.h"
#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
-#include "third_party/blink/renderer/platform/weborigin/security_violation_reporting_policy.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
#include "third_party/blink/renderer/platform/wtf/text/text_position.h"
@@ -64,7 +65,6 @@ class CSPSource;
class Document;
class Element;
class ExecutionContext;
-class LocalFrameClient;
class LocalFrame;
class KURL;
class ResourceRequest;
@@ -73,10 +73,11 @@ class SecurityPolicyViolationEventInit;
class SourceLocation;
enum class ResourceType : uint8_t;
-using SandboxFlags = WebSandboxFlags;
+using SandboxFlags = mojom::blink::WebSandboxFlags;
typedef HeapVector<Member<CSPDirectiveList>> CSPDirectiveListVector;
typedef HeapVector<Member<ConsoleMessage>> ConsoleMessageVector;
-typedef std::pair<String, ContentSecurityPolicyHeaderType> CSPHeaderAndType;
+typedef std::pair<String, network::mojom::ContentSecurityPolicyType>
+ CSPHeaderAndType;
using RedirectStatus = ResourceRequest::RedirectStatus;
// A delegate interface to implement violation reporting, support for some
@@ -88,6 +89,10 @@ class CORE_EXPORT ContentSecurityPolicyDelegate : public GarbageCollectedMixin {
// See https://w3c.github.io/webappsec-csp/#policy-self-origin.
virtual const SecurityOrigin* GetSecurityOrigin() = 0;
+ // Returns the SecureContextMode for the context to which the delegate is
+ // bound.
+ virtual SecureContextMode GetSecureContextMode() = 0;
+
// Returns the URL this content security policy is bound to.
// Used for https://w3c.github.io/webappsec-csp/#violation-url and so.
// Note: Url() is used for several purposes that are specced slightly
@@ -98,7 +103,8 @@ class CORE_EXPORT ContentSecurityPolicyDelegate : public GarbageCollectedMixin {
// Directives support.
virtual void SetSandboxFlags(SandboxFlags) = 0;
virtual void SetRequireTrustedTypes() = 0;
- virtual void AddInsecureRequestPolicy(WebInsecureRequestPolicy) = 0;
+ virtual void AddInsecureRequestPolicy(
+ mojom::blink::InsecureRequestPolicy) = 0;
// Violation reporting.
@@ -125,7 +131,7 @@ class CORE_EXPORT ContentSecurityPolicyDelegate : public GarbageCollectedMixin {
virtual void ReportBlockedScriptExecutionToInspector(
const String& directive_text) = 0;
virtual void DidAddContentSecurityPolicies(
- const blink::WebVector<WebContentSecurityPolicy>&) = 0;
+ WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr>) = 0;
};
class CORE_EXPORT ContentSecurityPolicy final
@@ -191,6 +197,7 @@ class CORE_EXPORT ContentSecurityPolicy final
kUndefined,
kUpgradeInsecureRequests,
kWorkerSrc,
+ kRequireTrustedTypesFor,
};
// CheckHeaderType can be passed to Allow*FromSource methods to control which
@@ -211,7 +218,7 @@ class CORE_EXPORT ContentSecurityPolicy final
ContentSecurityPolicy();
~ContentSecurityPolicy();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
bool IsBound();
void BindToDelegate(ContentSecurityPolicyDelegate&);
@@ -222,31 +229,38 @@ class CORE_EXPORT ContentSecurityPolicy final
void DidReceiveHeaders(const ContentSecurityPolicyResponseHeaders&);
void DidReceiveHeader(const String&,
- ContentSecurityPolicyHeaderType,
- ContentSecurityPolicyHeaderSource);
+ network::mojom::ContentSecurityPolicyType,
+ network::mojom::ContentSecurityPolicySource);
void AddPolicyFromHeaderValue(const String&,
- ContentSecurityPolicyHeaderType,
- ContentSecurityPolicyHeaderSource);
- void ReportAccumulatedHeaders(LocalFrameClient*) const;
+ network::mojom::ContentSecurityPolicyType,
+ network::mojom::ContentSecurityPolicySource);
+ void ReportAccumulatedHeaders(LocalFrame*) const;
Vector<CSPHeaderAndType> Headers() const;
+ // Returns whether or not the Javascript code generation should call back the
+ // CSP checker before any script evaluation from a string attempts.
+ //
+ // CSP has two mechanisms for controlling eval: script-src and TrustedTypes.
+ // This returns true when any of those should to be checked.
+ bool ShouldCheckEval() const;
+
// When the reporting status is |SendReport|, the |ExceptionStatus|
// should indicate whether the caller will throw a JavaScript
// exception in the event of a violation. When the caller will throw
// an exception, ContentSecurityPolicy does not log a violation
// message to the console because it would be redundant.
- bool AllowEval(SecurityViolationReportingPolicy,
+ bool AllowEval(ReportingDisposition,
ExceptionStatus,
const String& script_content) const;
- bool AllowWasmEval(SecurityViolationReportingPolicy,
+ bool AllowWasmEval(ReportingDisposition,
ExceptionStatus,
const String& script_content) const;
- bool AllowPluginType(const String& type,
- const String& type_attribute,
- const KURL&,
- SecurityViolationReportingPolicy =
- SecurityViolationReportingPolicy::kReport) const;
+ bool AllowPluginType(
+ const String& type,
+ const String& type_attribute,
+ const KURL&,
+ ReportingDisposition = ReportingDisposition::kReport) const;
// Checks whether the plugin type should be allowed in the given
// document; enforces the CSP rule that PluginDocuments inherit
// plugin-types directives from the parent document.
@@ -255,22 +269,21 @@ class CORE_EXPORT ContentSecurityPolicy final
const String& type,
const String& type_attribute,
const KURL&,
- SecurityViolationReportingPolicy =
- SecurityViolationReportingPolicy::kReport) const;
+ ReportingDisposition = ReportingDisposition::kReport) const;
// AllowFromSource() wrappers.
bool AllowBaseURI(const KURL&) const;
- bool AllowConnectToSource(const KURL&,
- RedirectStatus = RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy =
- SecurityViolationReportingPolicy::kReport,
- CheckHeaderType = CheckHeaderType::kCheckAll) const;
+ bool AllowConnectToSource(
+ const KURL&,
+ RedirectStatus = RedirectStatus::kNoRedirect,
+ ReportingDisposition = ReportingDisposition::kReport,
+ CheckHeaderType = CheckHeaderType::kCheckAll) const;
bool AllowFormAction(const KURL&) const;
- bool AllowImageFromSource(const KURL&,
- RedirectStatus = RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy =
- SecurityViolationReportingPolicy::kReport,
- CheckHeaderType = CheckHeaderType::kCheckAll) const;
+ bool AllowImageFromSource(
+ const KURL&,
+ RedirectStatus = RedirectStatus::kNoRedirect,
+ ReportingDisposition = ReportingDisposition::kReport,
+ CheckHeaderType = CheckHeaderType::kCheckAll) const;
bool AllowMediaFromSource(const KURL&) const;
bool AllowObjectFromSource(const KURL&) const;
bool AllowScriptFromSource(
@@ -279,8 +292,7 @@ class CORE_EXPORT ContentSecurityPolicy final
const IntegrityMetadataSet&,
ParserDisposition,
RedirectStatus = RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy =
- SecurityViolationReportingPolicy::kReport,
+ ReportingDisposition = ReportingDisposition::kReport,
CheckHeaderType = CheckHeaderType::kCheckAll) const;
bool AllowWorkerContextFromSource(const KURL&) const;
@@ -304,8 +316,7 @@ class CORE_EXPORT ContentSecurityPolicy final
const String& nonce,
const String& context_url,
const WTF::OrdinalNumber& context_line,
- SecurityViolationReportingPolicy =
- SecurityViolationReportingPolicy::kReport) const;
+ ReportingDisposition = ReportingDisposition::kReport) const;
static bool IsScriptInlineType(InlineType);
@@ -315,18 +326,17 @@ class CORE_EXPORT ContentSecurityPolicy final
// request was redirected, but this is not a concern for ancestors,
// because a child frame can't manipulate the URL of a cross-origin
// parent.
- bool AllowAncestors(LocalFrame*,
- const KURL&,
- SecurityViolationReportingPolicy =
- SecurityViolationReportingPolicy::kReport) const;
+ bool AllowAncestors(
+ LocalFrame*,
+ const KURL&,
+ ReportingDisposition = ReportingDisposition::kReport) const;
bool IsFrameAncestorsEnforced() const;
bool AllowRequestWithoutIntegrity(
mojom::RequestContextType,
const KURL&,
RedirectStatus = RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy =
- SecurityViolationReportingPolicy::kReport,
+ ReportingDisposition = ReportingDisposition::kReport,
CheckHeaderType = CheckHeaderType::kCheckAll) const;
bool AllowRequest(mojom::RequestContextType,
@@ -335,14 +345,15 @@ class CORE_EXPORT ContentSecurityPolicy final
const IntegrityMetadataSet&,
ParserDisposition,
RedirectStatus = RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy =
- SecurityViolationReportingPolicy::kReport,
+ ReportingDisposition = ReportingDisposition::kReport,
CheckHeaderType = CheckHeaderType::kCheckAll) const;
// Determine whether to enforce the assignment failure. Also handle reporting.
// Returns whether enforcing Trusted Types CSP directives are present.
- bool AllowTrustedTypeAssignmentFailure(const String& message,
- const String& sample = String()) const;
+ bool AllowTrustedTypeAssignmentFailure(
+ const String& message,
+ const String& sample = String(),
+ const String& sample_prefix = String()) const;
void UsesScriptHashAlgorithms(uint8_t content_security_policy_hash_algorithm);
void UsesStyleHashAlgorithms(uint8_t content_security_policy_hash_algorithm);
@@ -379,6 +390,7 @@ class CORE_EXPORT ContentSecurityPolicy final
void ReportMetaOutsideHead(const String&);
void ReportValueForEmptyDirective(const String& directive_name,
const String& value);
+ void ReportNonsecureTrustedTypes();
// If a frame is passed in, the report will be sent using it as a context. If
// no frame is passed in, the report will be sent via this object's
@@ -393,13 +405,14 @@ class CORE_EXPORT ContentSecurityPolicy final
const Vector<String>& report_endpoints,
bool use_reporting_api,
const String& header,
- ContentSecurityPolicyHeaderType,
+ network::mojom::ContentSecurityPolicyType,
ViolationType,
std::unique_ptr<SourceLocation>,
LocalFrame* = nullptr,
RedirectStatus = RedirectStatus::kFollowedRedirect,
Element* = nullptr,
- const String& source = g_empty_string);
+ const String& source = g_empty_string,
+ const String& source_prefix = g_empty_string);
// 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
@@ -421,7 +434,7 @@ class CORE_EXPORT ContentSecurityPolicy final
// |m_insecureRequestPolicy|
void EnforceStrictMixedContentChecking();
void UpgradeInsecureRequests();
- WebInsecureRequestPolicy GetInsecureRequestPolicy() const {
+ mojom::blink::InsecureRequestPolicy GetInsecureRequestPolicy() const {
return insecure_request_policy_;
}
@@ -466,7 +479,8 @@ class CORE_EXPORT ContentSecurityPolicy final
// for certain navigational checks. We create a string version of the relevant
// CSP directives to be passed around with the request. This allows us to
// perform these checks in NavigationRequest::CheckContentSecurityPolicy.
- WebContentSecurityPolicyList ExposeForNavigationalChecks() const;
+ WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr>
+ ExposeForNavigationalChecks() const;
// Retrieves the parsed sandbox flags. A lot of the time the execution
// context will be used for all sandbox checks but there are situations
@@ -474,7 +488,7 @@ class CORE_EXPORT ContentSecurityPolicy final
// there is no execution context to enforce the sandbox flags.
SandboxFlags GetSandboxMask() const { return sandbox_mask_; }
- bool HasPolicyFromSource(ContentSecurityPolicyHeaderSource) const;
+ bool HasPolicyFromSource(network::mojom::ContentSecurityPolicySource) const;
static bool IsScriptDirective(
ContentSecurityPolicy::DirectiveType directive_type) {
@@ -513,9 +527,10 @@ class CORE_EXPORT ContentSecurityPolicy final
const String& message,
mojom::ConsoleMessageLevel = mojom::ConsoleMessageLevel::kError);
- void AddAndReportPolicyFromHeaderValue(const String&,
- ContentSecurityPolicyHeaderType,
- ContentSecurityPolicyHeaderSource);
+ void AddAndReportPolicyFromHeaderValue(
+ const String&,
+ network::mojom::ContentSecurityPolicyType,
+ network::mojom::ContentSecurityPolicySource);
bool ShouldSendViolationReport(const String&) const;
void DidSendViolationReport(const String&);
@@ -527,8 +542,7 @@ class CORE_EXPORT ContentSecurityPolicy final
bool AllowFromSource(ContentSecurityPolicy::DirectiveType,
const KURL&,
RedirectStatus = RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy =
- SecurityViolationReportingPolicy::kReport,
+ ReportingDisposition = ReportingDisposition::kReport,
CheckHeaderType = CheckHeaderType::kCheckAll,
const String& = String(),
const IntegrityMetadataSet& = IntegrityMetadataSet(),
@@ -566,7 +580,7 @@ class CORE_EXPORT ContentSecurityPolicy final
SandboxFlags sandbox_mask_;
bool require_trusted_types_;
String disable_eval_error_message_;
- WebInsecureRequestPolicy insecure_request_policy_;
+ mojom::blink::InsecureRequestPolicy insecure_request_policy_;
Member<CSPSource> self_source_;
String self_protocol_;
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy_fuzzer.cc b/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy_fuzzer.cc
index c3e310e818e..b6d50a9e7a0 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy_fuzzer.cc
+++ b/chromium/third_party/blink/renderer/core/frame/csp/content_security_policy_fuzzer.cc
@@ -29,7 +29,8 @@ int LLVMFuzzerInitialize(int* argc, char*** argv) {
// has all possible sandbox flags set on the document already when the
// CSP is bound.
scoped_refptr<SharedBuffer> empty_document_data = SharedBuffer::Create();
- g_page_holder->GetFrame().Loader().ForceSandboxFlags(WebSandboxFlags::kAll);
+ g_page_holder->GetFrame().Loader().ForceSandboxFlags(
+ mojom::blink::WebSandboxFlags::kAll);
g_page_holder->GetFrame().ForceSynchronousDocumentInstall(
"text/html", empty_document_data);
return 0;
@@ -43,15 +44,16 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// 1st bit: header type.
// 2nd bit: header source: HTTP (or other)
// 3rd bit: header source: Meta or OriginPolicy (if not HTTP)
- ContentSecurityPolicyHeaderType header_type =
- hash & 0x01 ? kContentSecurityPolicyHeaderTypeEnforce
- : kContentSecurityPolicyHeaderTypeReport;
- ContentSecurityPolicyHeaderSource header_source =
- kContentSecurityPolicyHeaderSourceHTTP;
+ network::mojom::ContentSecurityPolicyType header_type =
+ hash & 0x01 ? network::mojom::ContentSecurityPolicyType::kEnforce
+ : network::mojom::ContentSecurityPolicyType::kReport;
+ network::mojom::ContentSecurityPolicySource header_source =
+ network::mojom::ContentSecurityPolicySource::kHTTP;
if (hash & 0x02) {
- header_source = (hash & 0x04)
- ? kContentSecurityPolicyHeaderSourceMeta
- : kContentSecurityPolicyHeaderSourceOriginPolicy;
+ header_source =
+ (hash & 0x04)
+ ? network::mojom::ContentSecurityPolicySource::kMeta
+ : network::mojom::ContentSecurityPolicySource::kOriginPolicy;
}
// Construct and initialize a policy from the 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 4b9ff4dd921..e6206ef33ec 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
@@ -5,11 +5,12 @@
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/web_insecure_request_policy.h"
+#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/document_init.h"
#include "third_party/blink/renderer/core/frame/csp/csp_directive_list.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"
#include "third_party/blink/renderer/platform/crypto.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
@@ -24,6 +25,9 @@
namespace blink {
+using network::mojom::ContentSecurityPolicySource;
+using network::mojom::ContentSecurityPolicyType;
+
class ContentSecurityPolicyTest : public testing::Test {
public:
ContentSecurityPolicyTest()
@@ -37,8 +41,8 @@ class ContentSecurityPolicyTest : public testing::Test {
NullExecutionContext* CreateExecutionContext() {
NullExecutionContext* context =
MakeGarbageCollected<NullExecutionContext>();
- context->SetUpSecurityContext();
- context->SetSecurityOrigin(secure_origin);
+ context->SetUpSecurityContextForTesting();
+ context->GetSecurityContext().SetSecurityOriginForTesting(secure_origin);
return context;
}
@@ -51,33 +55,46 @@ class ContentSecurityPolicyTest : public testing::Test {
TEST_F(ContentSecurityPolicyTest, ParseInsecureRequestPolicy) {
struct TestCase {
const char* header;
- WebInsecureRequestPolicy expected_policy;
- } cases[] = {{"default-src 'none'", kLeaveInsecureRequestsAlone},
- {"upgrade-insecure-requests", kUpgradeInsecureRequests},
- {"block-all-mixed-content", kBlockAllMixedContent},
- {"upgrade-insecure-requests; block-all-mixed-content",
- kUpgradeInsecureRequests | kBlockAllMixedContent},
- {"upgrade-insecure-requests, block-all-mixed-content",
- kUpgradeInsecureRequests | kBlockAllMixedContent}};
+ mojom::blink::InsecureRequestPolicy expected_policy;
+ } cases[] = {
+ {"default-src 'none'",
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone},
+ {"upgrade-insecure-requests",
+ mojom::blink::InsecureRequestPolicy::kUpgradeInsecureRequests},
+ {"block-all-mixed-content",
+ mojom::blink::InsecureRequestPolicy::kBlockAllMixedContent},
+ {"upgrade-insecure-requests; block-all-mixed-content",
+ mojom::blink::InsecureRequestPolicy::kUpgradeInsecureRequests |
+ mojom::blink::InsecureRequestPolicy::kBlockAllMixedContent},
+ {"upgrade-insecure-requests, block-all-mixed-content",
+ mojom::blink::InsecureRequestPolicy::kUpgradeInsecureRequests |
+ mojom::blink::InsecureRequestPolicy::kBlockAllMixedContent}};
// Enforced
for (const auto& test : cases) {
SCOPED_TRACE(testing::Message()
<< "[Enforce] Header: `" << test.header << "`");
csp = MakeGarbageCollected<ContentSecurityPolicy>();
- csp->DidReceiveHeader(test.header, kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ csp->DidReceiveHeader(test.header, ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_EQ(test.expected_policy, csp->GetInsecureRequestPolicy());
- DocumentInit init = DocumentInit::Create()
- .WithOriginToCommit(secure_origin)
- .WithURL(secure_url);
- auto* document = MakeGarbageCollected<Document>(init);
- csp->BindToDelegate(document->GetContentSecurityPolicyDelegate());
- EXPECT_EQ(test.expected_policy, document->GetInsecureRequestPolicy());
- bool expect_upgrade = test.expected_policy & kUpgradeInsecureRequests;
- EXPECT_EQ(expect_upgrade, document->InsecureNavigationsToUpgrade().Contains(
- document->Url().Host().Impl()->GetHash()));
+ auto dummy = std::make_unique<DummyPageHolder>();
+ dummy->GetDocument().SetURL(secure_url);
+ auto& security_context = dummy->GetDocument().GetSecurityContext();
+ security_context.SetSecurityOriginForTesting(secure_origin);
+
+ csp->BindToDelegate(
+ dummy->GetDocument().GetContentSecurityPolicyDelegate());
+ EXPECT_EQ(test.expected_policy,
+ security_context.GetInsecureRequestPolicy());
+ bool expect_upgrade =
+ (test.expected_policy &
+ mojom::blink::InsecureRequestPolicy::kUpgradeInsecureRequests) !=
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone;
+ EXPECT_EQ(expect_upgrade,
+ security_context.InsecureNavigationsToUpgrade().Contains(
+ dummy->GetDocument().Url().Host().Impl()->GetHash()));
}
// Report-Only
@@ -85,27 +102,30 @@ TEST_F(ContentSecurityPolicyTest, ParseInsecureRequestPolicy) {
SCOPED_TRACE(testing::Message()
<< "[Report-Only] Header: `" << test.header << "`");
csp = MakeGarbageCollected<ContentSecurityPolicy>();
- csp->DidReceiveHeader(test.header, kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceHTTP);
- EXPECT_EQ(kLeaveInsecureRequestsAlone, csp->GetInsecureRequestPolicy());
+ csp->DidReceiveHeader(test.header, ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kHTTP);
+ EXPECT_EQ(mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone,
+ csp->GetInsecureRequestPolicy());
execution_context = CreateExecutionContext();
- execution_context->SetSecurityOrigin(secure_origin);
+ execution_context->GetSecurityContext().SetSecurityOrigin(secure_origin);
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
- EXPECT_EQ(kLeaveInsecureRequestsAlone,
- execution_context->GetInsecureRequestPolicy());
- EXPECT_FALSE(execution_context->InsecureNavigationsToUpgrade().Contains(
- secure_origin->Host().Impl()->GetHash()));
+ EXPECT_EQ(
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone,
+ execution_context->GetSecurityContext().GetInsecureRequestPolicy());
+ EXPECT_FALSE(execution_context->GetSecurityContext()
+ .InsecureNavigationsToUpgrade()
+ .Contains(secure_origin->Host().Impl()->GetHash()));
}
}
TEST_F(ContentSecurityPolicyTest, CopyStateFrom) {
csp->DidReceiveHeader("script-src 'none'; plugin-types application/x-type-1",
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kHTTP);
csp->DidReceiveHeader("img-src http://example.com",
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kHTTP);
const KURL example_url("http://example.com");
const KURL not_example_url("http://not-example.com");
@@ -115,31 +135,31 @@ TEST_F(ContentSecurityPolicyTest, CopyStateFrom) {
EXPECT_FALSE(csp2->AllowScriptFromSource(
example_url, String(), IntegrityMetadataSet(), kParserInserted,
ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting,
+ ReportingDisposition::kSuppressReporting,
ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly));
- EXPECT_TRUE(csp2->AllowPluginType(
- "application/x-type-1", "application/x-type-1", example_url,
- SecurityViolationReportingPolicy::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,
- SecurityViolationReportingPolicy::kSuppressReporting,
+ ReportingDisposition::kSuppressReporting,
ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly));
EXPECT_FALSE(csp2->AllowImageFromSource(
not_example_url, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting,
+ ReportingDisposition::kSuppressReporting,
ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly));
- EXPECT_FALSE(csp2->AllowPluginType(
- "application/x-type-2", "application/x-type-2", example_url,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ EXPECT_FALSE(csp2->AllowPluginType("application/x-type-2",
+ "application/x-type-2", example_url,
+ ReportingDisposition::kSuppressReporting));
}
TEST_F(ContentSecurityPolicyTest, CopyPluginTypesFrom) {
csp->DidReceiveHeader("script-src 'none'; plugin-types application/x-type-1",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
csp->DidReceiveHeader("img-src http://example.com",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
const KURL example_url("http://example.com");
const KURL not_example_url("http://not-example.com");
@@ -149,51 +169,51 @@ TEST_F(ContentSecurityPolicyTest, CopyPluginTypesFrom) {
EXPECT_TRUE(csp2->AllowScriptFromSource(
example_url, String(), IntegrityMetadataSet(), kParserInserted,
ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
- EXPECT_TRUE(csp2->AllowPluginType(
- "application/x-type-1", "application/x-type-1", example_url,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ 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,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(csp2->AllowImageFromSource(
not_example_url, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
- EXPECT_FALSE(csp2->AllowPluginType(
- "application/x-type-2", "application/x-type-2", example_url,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
+ EXPECT_FALSE(csp2->AllowPluginType("application/x-type-2",
+ "application/x-type-2", example_url,
+ ReportingDisposition::kSuppressReporting));
}
TEST_F(ContentSecurityPolicyTest, IsFrameAncestorsEnforced) {
csp->DidReceiveHeader("script-src 'none';",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_FALSE(csp->IsFrameAncestorsEnforced());
csp->DidReceiveHeader("frame-ancestors 'self'",
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_FALSE(csp->IsFrameAncestorsEnforced());
csp->DidReceiveHeader("frame-ancestors 'self'",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(csp->IsFrameAncestorsEnforced());
}
TEST_F(ContentSecurityPolicyTest, IsActiveForConnectionsWithConnectSrc) {
EXPECT_FALSE(csp->IsActiveForConnections());
csp->DidReceiveHeader("connect-src 'none';",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(csp->IsActiveForConnections());
}
TEST_F(ContentSecurityPolicyTest, IsActiveForConnectionsWithDefaultSrc) {
EXPECT_FALSE(csp->IsActiveForConnections());
csp->DidReceiveHeader("default-src 'none';",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(csp->IsActiveForConnections());
}
@@ -202,12 +222,12 @@ TEST_F(ContentSecurityPolicyTest, IsActiveForConnectionsWithDefaultSrc) {
TEST_F(ContentSecurityPolicyTest, FrameAncestorsInMeta) {
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
csp->DidReceiveHeader("frame-ancestors 'none';",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceMeta);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kMeta);
EXPECT_FALSE(csp->IsFrameAncestorsEnforced());
csp->DidReceiveHeader("frame-ancestors 'none';",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(csp->IsFrameAncestorsEnforced());
}
@@ -215,14 +235,15 @@ TEST_F(ContentSecurityPolicyTest, FrameAncestorsInMeta) {
// delivered in <meta> elements.
TEST_F(ContentSecurityPolicyTest, SandboxInMeta) {
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
- EXPECT_EQ(WebSandboxFlags::kNone, csp->GetSandboxMask());
- csp->DidReceiveHeader("sandbox;", kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceMeta);
- EXPECT_EQ(WebSandboxFlags::kNone, csp->GetSandboxMask());
- execution_context->SetSandboxFlags(WebSandboxFlags::kAll);
- csp->DidReceiveHeader("sandbox;", kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
- EXPECT_EQ(WebSandboxFlags::kAll, csp->GetSandboxMask());
+ EXPECT_EQ(mojom::blink::WebSandboxFlags::kNone, csp->GetSandboxMask());
+ csp->DidReceiveHeader("sandbox;", ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kMeta);
+ EXPECT_EQ(mojom::blink::WebSandboxFlags::kNone, csp->GetSandboxMask());
+ execution_context->GetSecurityContext().ApplySandboxFlags(
+ mojom::blink::WebSandboxFlags::kAll);
+ csp->DidReceiveHeader("sandbox;", ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
+ EXPECT_EQ(mojom::blink::WebSandboxFlags::kAll, csp->GetSandboxMask());
}
// Tests that report-uri directives are discarded from policies
@@ -234,12 +255,12 @@ TEST_F(ContentSecurityPolicyTest, ReportURIInMeta) {
const UChar* begin = characters.data();
const UChar* end = begin + characters.size();
CSPDirectiveList* directive_list(CSPDirectiveList::Create(
- csp, begin, end, kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceMeta));
+ csp, begin, end, ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kMeta));
EXPECT_TRUE(directive_list->ReportEndpoints().IsEmpty());
- directive_list = CSPDirectiveList::Create(
- csp, begin, end, kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ directive_list = CSPDirectiveList::Create(csp, begin, end,
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_FALSE(directive_list->ReportEndpoints().IsEmpty());
}
@@ -250,50 +271,50 @@ TEST_F(ContentSecurityPolicyTest, ObjectSrc) {
const KURL url("https://example.test");
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
csp->DidReceiveHeader("object-src 'none';",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceMeta);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kMeta);
EXPECT_FALSE(csp->AllowRequest(
mojom::RequestContextType::OBJECT, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(csp->AllowRequest(
mojom::RequestContextType::EMBED, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(csp->AllowRequest(
mojom::RequestContextType::PLUGIN, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
}
TEST_F(ContentSecurityPolicyTest, ConnectSrc) {
const KURL url("https://example.test");
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
csp->DidReceiveHeader("connect-src 'none';",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceMeta);
- EXPECT_FALSE(
- csp->AllowRequest(mojom::RequestContextType::SUBRESOURCE, url, String(),
- IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
- EXPECT_FALSE(
- csp->AllowRequest(mojom::RequestContextType::XML_HTTP_REQUEST, url,
- String(), IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kMeta);
+ EXPECT_FALSE(csp->AllowRequest(mojom::RequestContextType::SUBRESOURCE, url,
+ String(), IntegrityMetadataSet(),
+ kParserInserted,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
+ EXPECT_FALSE(csp->AllowRequest(mojom::RequestContextType::XML_HTTP_REQUEST,
+ url, String(), IntegrityMetadataSet(),
+ kParserInserted,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(csp->AllowRequest(
mojom::RequestContextType::BEACON, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(csp->AllowRequest(
mojom::RequestContextType::FETCH, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(csp->AllowRequest(
mojom::RequestContextType::PLUGIN, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
}
// Tests that requests for scripts and styles are blocked
// if `require-sri-for` delivered in HTTP header requires integrity be present
@@ -304,74 +325,74 @@ TEST_F(ContentSecurityPolicyTest, RequireSRIForInHeaderMissingIntegrity) {
MakeGarbageCollected<ContentSecurityPolicy>();
policy->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
policy->DidReceiveHeader("require-sri-for script style",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_FALSE(policy->AllowRequest(
mojom::RequestContextType::SCRIPT, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(policy->AllowRequest(
mojom::RequestContextType::IMPORT, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(policy->AllowRequest(
mojom::RequestContextType::STYLE, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
- EXPECT_FALSE(policy->AllowRequest(
- mojom::RequestContextType::SERVICE_WORKER, url, String(),
- IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
- EXPECT_FALSE(policy->AllowRequest(
- mojom::RequestContextType::SHARED_WORKER, url, String(),
- IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
+ EXPECT_FALSE(
+ policy->AllowRequest(mojom::RequestContextType::SERVICE_WORKER, url,
+ String(), IntegrityMetadataSet(), kParserInserted,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
+ EXPECT_FALSE(
+ policy->AllowRequest(mojom::RequestContextType::SHARED_WORKER, url,
+ String(), IntegrityMetadataSet(), kParserInserted,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(policy->AllowRequest(
mojom::RequestContextType::WORKER, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::IMAGE, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
// Report
policy = MakeGarbageCollected<ContentSecurityPolicy>();
policy->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
policy->DidReceiveHeader("require-sri-for script style",
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::SCRIPT, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::IMPORT, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::STYLE, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(
- mojom::RequestContextType::SERVICE_WORKER, url, String(),
- IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(
- mojom::RequestContextType::SHARED_WORKER, url, String(),
- IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
+ EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::SERVICE_WORKER,
+ url, String(), IntegrityMetadataSet(),
+ kParserInserted,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
+ EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::SHARED_WORKER,
+ url, String(), IntegrityMetadataSet(),
+ kParserInserted,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::WORKER, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::IMAGE, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
}
// Tests that requests for scripts and styles are allowed
@@ -387,75 +408,75 @@ TEST_F(ContentSecurityPolicyTest, RequireSRIForInHeaderPresentIntegrity) {
MakeGarbageCollected<ContentSecurityPolicy>();
policy->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
policy->DidReceiveHeader("require-sri-for script style",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::SCRIPT, url, String(), integrity_metadata,
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::IMPORT, url, String(), integrity_metadata,
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::STYLE, url, String(), integrity_metadata,
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(
- mojom::RequestContextType::SERVICE_WORKER, url, String(),
- integrity_metadata, kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(
- mojom::RequestContextType::SHARED_WORKER, url, String(),
- integrity_metadata, kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
+ EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::SERVICE_WORKER,
+ url, String(), integrity_metadata,
+ kParserInserted,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
+ EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::SHARED_WORKER,
+ url, String(), integrity_metadata,
+ kParserInserted,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::WORKER, url, String(), integrity_metadata,
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::IMAGE, url, String(), integrity_metadata,
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ 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",
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::SCRIPT, url, String(), integrity_metadata,
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::IMPORT, url, String(), integrity_metadata,
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::STYLE, url, String(), integrity_metadata,
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(
- mojom::RequestContextType::SERVICE_WORKER, url, String(),
- integrity_metadata, kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(
- mojom::RequestContextType::SHARED_WORKER, url, String(),
- integrity_metadata, kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
+ EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::SERVICE_WORKER,
+ url, String(), integrity_metadata,
+ kParserInserted,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
+ EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::SHARED_WORKER,
+ url, String(), integrity_metadata,
+ kParserInserted,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::WORKER, url, String(), integrity_metadata,
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::IMAGE, url, String(), integrity_metadata,
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
}
// Tests that requests for scripts and styles are blocked
@@ -467,75 +488,75 @@ TEST_F(ContentSecurityPolicyTest, RequireSRIForInMetaMissingIntegrity) {
MakeGarbageCollected<ContentSecurityPolicy>();
policy->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
policy->DidReceiveHeader("require-sri-for script style",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceMeta);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kMeta);
EXPECT_FALSE(policy->AllowRequest(
mojom::RequestContextType::SCRIPT, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(policy->AllowRequest(
mojom::RequestContextType::IMPORT, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(policy->AllowRequest(
mojom::RequestContextType::STYLE, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
- EXPECT_FALSE(policy->AllowRequest(
- mojom::RequestContextType::SERVICE_WORKER, url, String(),
- IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
- EXPECT_FALSE(policy->AllowRequest(
- mojom::RequestContextType::SHARED_WORKER, url, String(),
- IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
+ EXPECT_FALSE(
+ policy->AllowRequest(mojom::RequestContextType::SERVICE_WORKER, url,
+ String(), IntegrityMetadataSet(), kParserInserted,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
+ EXPECT_FALSE(
+ policy->AllowRequest(mojom::RequestContextType::SHARED_WORKER, url,
+ String(), IntegrityMetadataSet(), kParserInserted,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(policy->AllowRequest(
mojom::RequestContextType::WORKER, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::IMAGE, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ 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",
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceMeta);
+ ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kMeta);
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::SCRIPT, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::IMPORT, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::STYLE, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(
- mojom::RequestContextType::SERVICE_WORKER, url, String(),
- IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(
- mojom::RequestContextType::SHARED_WORKER, url, String(),
- IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
+ EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::SERVICE_WORKER,
+ url, String(), IntegrityMetadataSet(),
+ kParserInserted,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
+ EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::SHARED_WORKER,
+ url, String(), IntegrityMetadataSet(),
+ kParserInserted,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::WORKER, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::IMAGE, url, String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
}
// Tests that requests for scripts and styles are allowed
@@ -551,75 +572,75 @@ TEST_F(ContentSecurityPolicyTest, RequireSRIForInMetaPresentIntegrity) {
MakeGarbageCollected<ContentSecurityPolicy>();
policy->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
policy->DidReceiveHeader("require-sri-for script style",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceMeta);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kMeta);
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::SCRIPT, url, String(), integrity_metadata,
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::IMPORT, url, String(), integrity_metadata,
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::STYLE, url, String(), integrity_metadata,
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(
- mojom::RequestContextType::SERVICE_WORKER, url, String(),
- integrity_metadata, kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(
- mojom::RequestContextType::SHARED_WORKER, url, String(),
- integrity_metadata, kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
+ EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::SERVICE_WORKER,
+ url, String(), integrity_metadata,
+ kParserInserted,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
+ EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::SHARED_WORKER,
+ url, String(), integrity_metadata,
+ kParserInserted,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::WORKER, url, String(), integrity_metadata,
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::IMAGE, url, String(), integrity_metadata,
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ 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",
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceMeta);
+ ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kMeta);
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::SCRIPT, url, String(), integrity_metadata,
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::IMPORT, url, String(), integrity_metadata,
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::STYLE, url, String(), integrity_metadata,
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(
- mojom::RequestContextType::SERVICE_WORKER, url, String(),
- integrity_metadata, kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
- EXPECT_TRUE(policy->AllowRequest(
- mojom::RequestContextType::SHARED_WORKER, url, String(),
- integrity_metadata, kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
+ EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::SERVICE_WORKER,
+ url, String(), integrity_metadata,
+ kParserInserted,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
+ EXPECT_TRUE(policy->AllowRequest(mojom::RequestContextType::SHARED_WORKER,
+ url, String(), integrity_metadata,
+ kParserInserted,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::WORKER, url, String(), integrity_metadata,
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(policy->AllowRequest(
mojom::RequestContextType::IMAGE, url, String(), integrity_metadata,
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
}
TEST_F(ContentSecurityPolicyTest, NonceSinglePolicy) {
@@ -652,9 +673,8 @@ TEST_F(ContentSecurityPolicyTest, NonceSinglePolicy) {
MakeGarbageCollected<ContentSecurityPolicy>();
policy->BindToDelegate(
execution_context->GetContentSecurityPolicyDelegate());
- policy->DidReceiveHeader(test.policy,
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ policy->DidReceiveHeader(test.policy, ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_EQ(test.allowed, policy->AllowScriptFromSource(
resource, String(test.nonce),
IntegrityMetadataSet(), kParserInserted));
@@ -666,13 +686,12 @@ TEST_F(ContentSecurityPolicyTest, NonceSinglePolicy) {
policy = MakeGarbageCollected<ContentSecurityPolicy>();
policy->BindToDelegate(
execution_context->GetContentSecurityPolicyDelegate());
- policy->DidReceiveHeader(test.policy,
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceHTTP);
+ policy->DidReceiveHeader(test.policy, ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(policy->AllowScriptFromSource(
resource, String(test.nonce), IntegrityMetadataSet(), kParserInserted,
ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kReport,
+ ReportingDisposition::kReport,
ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly));
// If this is expected to generate a violation, we should have sent a
// report, even though we don't deny access in `allowScriptFromSource`:
@@ -699,8 +718,9 @@ TEST_F(ContentSecurityPolicyTest, NonceInline) {
WTF::OrdinalNumber context_line;
// We need document for HTMLScriptElement tests.
- DocumentInit init = DocumentInit::Create().WithOriginToCommit(secure_origin);
- auto* document = MakeGarbageCollected<Document>(init);
+ auto dummy = std::make_unique<DummyPageHolder>();
+ auto& document = dummy->GetDocument();
+ document.GetSecurityContext().SetSecurityOriginForTesting(secure_origin);
for (const auto& test : cases) {
SCOPED_TRACE(testing::Message() << "Policy: `" << test.policy
@@ -708,15 +728,15 @@ TEST_F(ContentSecurityPolicyTest, NonceInline) {
unsigned expected_reports = test.allowed ? 0u : 1u;
auto* element = MakeGarbageCollected<HTMLScriptElement>(
- *document, CreateElementFlags::ByParser());
+ document, CreateElementFlags::ByParser());
// Enforce 'script-src'
Persistent<ContentSecurityPolicy> policy =
MakeGarbageCollected<ContentSecurityPolicy>();
- policy->BindToDelegate(document->GetContentSecurityPolicyDelegate());
+ policy->BindToDelegate(document.GetContentSecurityPolicyDelegate());
policy->DidReceiveHeader(String("script-src ") + test.policy,
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_EQ(test.allowed,
policy->AllowInline(ContentSecurityPolicy::InlineType::kScript,
element, content, String(test.nonce),
@@ -725,10 +745,10 @@ TEST_F(ContentSecurityPolicyTest, NonceInline) {
// Enforce 'style-src'
policy = MakeGarbageCollected<ContentSecurityPolicy>();
- policy->BindToDelegate(document->GetContentSecurityPolicyDelegate());
+ policy->BindToDelegate(document.GetContentSecurityPolicyDelegate());
policy->DidReceiveHeader(String("style-src ") + test.policy,
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_EQ(test.allowed,
policy->AllowInline(ContentSecurityPolicy::InlineType::kStyle,
element, content, String(test.nonce),
@@ -737,10 +757,10 @@ TEST_F(ContentSecurityPolicyTest, NonceInline) {
// Report 'script-src'
policy = MakeGarbageCollected<ContentSecurityPolicy>();
- policy->BindToDelegate(document->GetContentSecurityPolicyDelegate());
+ policy->BindToDelegate(document.GetContentSecurityPolicyDelegate());
policy->DidReceiveHeader(String("script-src ") + test.policy,
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(policy->AllowInline(ContentSecurityPolicy::InlineType::kScript,
element, content, String(test.nonce),
context_url, context_line));
@@ -748,10 +768,10 @@ TEST_F(ContentSecurityPolicyTest, NonceInline) {
// Report 'style-src'
policy = MakeGarbageCollected<ContentSecurityPolicy>();
- policy->BindToDelegate(document->GetContentSecurityPolicyDelegate());
+ policy->BindToDelegate(document.GetContentSecurityPolicyDelegate());
policy->DidReceiveHeader(String("style-src ") + test.policy,
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(policy->AllowInline(ContentSecurityPolicy::InlineType::kStyle,
element, content, String(test.nonce),
context_url, context_line));
@@ -821,22 +841,20 @@ TEST_F(ContentSecurityPolicyTest, NonceMultiplePolicy) {
MakeGarbageCollected<ContentSecurityPolicy>();
policy->BindToDelegate(
execution_context->GetContentSecurityPolicyDelegate());
- policy->DidReceiveHeader(test.policy1,
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
- policy->DidReceiveHeader(test.policy2,
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceHTTP);
+ policy->DidReceiveHeader(test.policy1, ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
+ policy->DidReceiveHeader(test.policy2, ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_EQ(test.allowed1,
policy->AllowScriptFromSource(
resource, String(test.nonce), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kReport,
+ ReportingDisposition::kReport,
ContentSecurityPolicy::CheckHeaderType::kCheckEnforce));
EXPECT_TRUE(policy->AllowScriptFromSource(
resource, String(test.nonce), IntegrityMetadataSet(), kParserInserted,
ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kReport,
+ ReportingDisposition::kReport,
ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly));
EXPECT_EQ(expected_reports, policy->violation_reports_sent_.size());
@@ -844,22 +862,20 @@ TEST_F(ContentSecurityPolicyTest, NonceMultiplePolicy) {
policy = MakeGarbageCollected<ContentSecurityPolicy>();
policy->BindToDelegate(
execution_context->GetContentSecurityPolicyDelegate());
- policy->DidReceiveHeader(test.policy1,
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceHTTP);
- policy->DidReceiveHeader(test.policy2,
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ policy->DidReceiveHeader(test.policy1, ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kHTTP);
+ policy->DidReceiveHeader(test.policy2, ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(policy->AllowScriptFromSource(
resource, String(test.nonce), IntegrityMetadataSet(), kParserInserted,
ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kReport,
+ ReportingDisposition::kReport,
ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly));
EXPECT_EQ(test.allowed2,
policy->AllowScriptFromSource(
resource, String(test.nonce), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kReport,
+ ReportingDisposition::kReport,
ContentSecurityPolicy::CheckHeaderType::kCheckEnforce));
EXPECT_EQ(expected_reports, policy->violation_reports_sent_.size());
@@ -867,17 +883,15 @@ TEST_F(ContentSecurityPolicyTest, NonceMultiplePolicy) {
policy = MakeGarbageCollected<ContentSecurityPolicy>();
policy->BindToDelegate(
execution_context->GetContentSecurityPolicyDelegate());
- policy->DidReceiveHeader(test.policy1,
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
- policy->DidReceiveHeader(test.policy2,
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ policy->DidReceiveHeader(test.policy1, ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
+ policy->DidReceiveHeader(test.policy2, ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_EQ(test.allowed1 && test.allowed2,
policy->AllowScriptFromSource(
resource, String(test.nonce), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kReport,
+ ReportingDisposition::kReport,
ContentSecurityPolicy::CheckHeaderType::kCheckEnforce));
EXPECT_EQ(expected_reports, policy->violation_reports_sent_.size());
@@ -885,16 +899,14 @@ TEST_F(ContentSecurityPolicyTest, NonceMultiplePolicy) {
policy = MakeGarbageCollected<ContentSecurityPolicy>();
policy->BindToDelegate(
execution_context->GetContentSecurityPolicyDelegate());
- policy->DidReceiveHeader(test.policy1,
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceHTTP);
- policy->DidReceiveHeader(test.policy2,
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceHTTP);
+ policy->DidReceiveHeader(test.policy1, ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kHTTP);
+ policy->DidReceiveHeader(test.policy2, ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(policy->AllowScriptFromSource(
resource, String(test.nonce), IntegrityMetadataSet(), kParserInserted,
ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kReport,
+ ReportingDisposition::kReport,
ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly));
EXPECT_EQ(expected_reports, policy->violation_reports_sent_.size());
}
@@ -1010,67 +1022,68 @@ TEST_F(ContentSecurityPolicyTest, Subsumes) {
EXPECT_TRUE(other->Subsumes(*csp));
csp->DidReceiveHeader("default-src http://example.com;",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
// If this CSP is not empty, the other must not be empty either.
EXPECT_FALSE(csp->Subsumes(*other));
EXPECT_TRUE(other->Subsumes(*csp));
// Report-only policies do not impact subsumption.
other->DidReceiveHeader("default-src http://example.com;",
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_FALSE(csp->Subsumes(*other));
// CSPDirectiveLists have to subsume.
other->DidReceiveHeader("default-src http://example.com https://another.com;",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_FALSE(csp->Subsumes(*other));
// `other` is stricter than `this`.
other->DidReceiveHeader("default-src https://example.com;",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(csp->Subsumes(*other));
}
TEST_F(ContentSecurityPolicyTest, RequestsAllowedWhenBypassingCSP) {
const KURL base;
execution_context = CreateExecutionContext();
- execution_context->SetSecurityOrigin(secure_origin); // https://example.com
- execution_context->SetURL(secure_url); // https://example.com
+ execution_context->GetSecurityContext().SetSecurityOrigin(
+ secure_origin); // https://example.com
+ execution_context->SetURL(secure_url); // https://example.com
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
csp->DidReceiveHeader("default-src https://example.com",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
- EXPECT_TRUE(csp->AllowRequest(
- mojom::RequestContextType::OBJECT, KURL(base, "https://example.com/"),
- String(), IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ EXPECT_TRUE(csp->AllowRequest(mojom::RequestContextType::OBJECT,
+ KURL(base, "https://example.com/"), String(),
+ IntegrityMetadataSet(), kParserInserted,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(csp->AllowRequest(
mojom::RequestContextType::OBJECT, KURL(base, "https://not-example.com/"),
String(), IntegrityMetadataSet(), kParserInserted,
ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
// Register "https" as bypassing CSP, which should now bypass it entirely
SchemeRegistry::RegisterURLSchemeAsBypassingContentSecurityPolicy("https");
- EXPECT_TRUE(csp->AllowRequest(
- mojom::RequestContextType::OBJECT, KURL(base, "https://example.com/"),
- String(), IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ EXPECT_TRUE(csp->AllowRequest(mojom::RequestContextType::OBJECT,
+ KURL(base, "https://example.com/"), String(),
+ IntegrityMetadataSet(), kParserInserted,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(csp->AllowRequest(
mojom::RequestContextType::OBJECT, KURL(base, "https://not-example.com/"),
String(), IntegrityMetadataSet(), kParserInserted,
ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
SchemeRegistry::RemoveURLSchemeRegisteredAsBypassingContentSecurityPolicy(
"https");
@@ -1078,26 +1091,27 @@ TEST_F(ContentSecurityPolicyTest, RequestsAllowedWhenBypassingCSP) {
TEST_F(ContentSecurityPolicyTest, FilesystemAllowedWhenBypassingCSP) {
const KURL base;
execution_context = CreateExecutionContext();
- execution_context->SetSecurityOrigin(secure_origin); // https://example.com
- execution_context->SetURL(secure_url); // https://example.com
+ execution_context->GetSecurityContext().SetSecurityOrigin(
+ secure_origin); // https://example.com
+ execution_context->SetURL(secure_url); // https://example.com
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
csp->DidReceiveHeader("default-src https://example.com",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_FALSE(
csp->AllowRequest(mojom::RequestContextType::OBJECT,
KURL(base, "filesystem:https://example.com/file.txt"),
String(), IntegrityMetadataSet(), kParserInserted,
ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(csp->AllowRequest(
mojom::RequestContextType::OBJECT,
KURL(base, "filesystem:https://not-example.com/file.txt"), String(),
IntegrityMetadataSet(), kParserInserted,
ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
// Register "https" as bypassing CSP, which should now bypass it entirely
SchemeRegistry::RegisterURLSchemeAsBypassingContentSecurityPolicy("https");
@@ -1107,14 +1121,14 @@ TEST_F(ContentSecurityPolicyTest, FilesystemAllowedWhenBypassingCSP) {
KURL(base, "filesystem:https://example.com/file.txt"),
String(), IntegrityMetadataSet(), kParserInserted,
ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(csp->AllowRequest(
mojom::RequestContextType::OBJECT,
KURL(base, "filesystem:https://not-example.com/file.txt"), String(),
IntegrityMetadataSet(), kParserInserted,
ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
SchemeRegistry::RemoveURLSchemeRegisteredAsBypassingContentSecurityPolicy(
"https");
@@ -1123,25 +1137,26 @@ TEST_F(ContentSecurityPolicyTest, FilesystemAllowedWhenBypassingCSP) {
TEST_F(ContentSecurityPolicyTest, BlobAllowedWhenBypassingCSP) {
const KURL base;
execution_context = CreateExecutionContext();
- execution_context->SetSecurityOrigin(secure_origin); // https://example.com
- execution_context->SetURL(secure_url); // https://example.com
+ execution_context->GetSecurityContext().SetSecurityOrigin(
+ secure_origin); // https://example.com
+ execution_context->SetURL(secure_url); // https://example.com
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
csp->DidReceiveHeader("default-src https://example.com",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_FALSE(csp->AllowRequest(
mojom::RequestContextType::OBJECT,
KURL(base, "blob:https://example.com/"), String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
- EXPECT_FALSE(
- csp->AllowRequest(mojom::RequestContextType::OBJECT,
- KURL(base, "blob:https://not-example.com/"), String(),
- IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ EXPECT_FALSE(csp->AllowRequest(mojom::RequestContextType::OBJECT,
+ KURL(base, "blob:https://not-example.com/"),
+ String(), IntegrityMetadataSet(),
+ kParserInserted,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
// Register "https" as bypassing CSP, which should now bypass it entirely
SchemeRegistry::RegisterURLSchemeAsBypassingContentSecurityPolicy("https");
@@ -1150,14 +1165,14 @@ TEST_F(ContentSecurityPolicyTest, BlobAllowedWhenBypassingCSP) {
mojom::RequestContextType::OBJECT,
KURL(base, "blob:https://example.com/"), String(), IntegrityMetadataSet(),
kParserInserted, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
- EXPECT_TRUE(
- csp->AllowRequest(mojom::RequestContextType::OBJECT,
- KURL(base, "blob:https://not-example.com/"), String(),
- IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ EXPECT_TRUE(csp->AllowRequest(mojom::RequestContextType::OBJECT,
+ KURL(base, "blob:https://not-example.com/"),
+ String(), IntegrityMetadataSet(),
+ kParserInserted,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
SchemeRegistry::RemoveURLSchemeRegisteredAsBypassingContentSecurityPolicy(
"https");
@@ -1166,12 +1181,12 @@ TEST_F(ContentSecurityPolicyTest, BlobAllowedWhenBypassingCSP) {
TEST_F(ContentSecurityPolicyTest, CSPBypassDisabledWhenSchemeIsPrivileged) {
const KURL base;
execution_context = CreateExecutionContext();
- execution_context->SetSecurityOrigin(secure_origin);
+ execution_context->GetSecurityContext().SetSecurityOrigin(secure_origin);
execution_context->SetURL(BlankURL());
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
csp->DidReceiveHeader("script-src http://example.com",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
const KURL allowed_url("http://example.com/script.js");
const KURL http_url("http://not-example.com/script.js");
@@ -1190,19 +1205,19 @@ TEST_F(ContentSecurityPolicyTest, CSPBypassDisabledWhenSchemeIsPrivileged) {
EXPECT_TRUE(csp->AllowScriptFromSource(
allowed_url, String(), IntegrityMetadataSet(), kNotParserInserted,
ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(csp->AllowScriptFromSource(
http_url, String(), IntegrityMetadataSet(), kNotParserInserted,
ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(csp->AllowScriptFromSource(
blob_url, String(), IntegrityMetadataSet(), kNotParserInserted,
ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(csp->AllowScriptFromSource(
filesystem_url, String(), IntegrityMetadataSet(), kNotParserInserted,
ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
SchemeRegistry::RemoveURLSchemeRegisteredAsBypassingContentSecurityPolicy(
"http");
@@ -1348,28 +1363,25 @@ TEST_F(ContentSecurityPolicyTest, IsValidCSPAttrTest) {
}
TEST_F(ContentSecurityPolicyTest, TrustedTypesNoDirective) {
- execution_context->SetRequireTrustedTypesForTesting();
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
- csp->DidReceiveHeader("", kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ csp->DidReceiveHeader("", ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", false));
EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", true));
}
TEST_F(ContentSecurityPolicyTest, TrustedTypesSimpleDirective) {
- execution_context->SetRequireTrustedTypesForTesting();
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
csp->DidReceiveHeader("trusted-types one two three",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
}
TEST_F(ContentSecurityPolicyTest, TrustedTypesWhitespace) {
- execution_context->SetRequireTrustedTypesForTesting();
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
csp->DidReceiveHeader("trusted-types one\ntwo\rthree",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(csp->AllowTrustedTypePolicy("one", false));
EXPECT_TRUE(csp->AllowTrustedTypePolicy("two", false));
EXPECT_TRUE(csp->AllowTrustedTypePolicy("three", false));
@@ -1379,31 +1391,57 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypesWhitespace) {
}
TEST_F(ContentSecurityPolicyTest, TrustedTypesEmpty) {
- execution_context->SetRequireTrustedTypesForTesting();
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
- csp->DidReceiveHeader("trusted-types",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ csp->DidReceiveHeader("trusted-types", ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_FALSE(csp->AllowTrustedTypePolicy("somepolicy", false));
EXPECT_FALSE(csp->AllowTrustedTypePolicy("somepolicy", true));
}
TEST_F(ContentSecurityPolicyTest, TrustedTypesStar) {
- execution_context->SetRequireTrustedTypesForTesting();
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
- csp->DidReceiveHeader("trusted-types *",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ csp->DidReceiveHeader("trusted-types *", ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
+ EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", false));
+ EXPECT_FALSE(csp->AllowTrustedTypePolicy("somepolicy", true));
+}
+
+TEST_F(ContentSecurityPolicyTest, TrustedTypesStarMix) {
+ csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
+ csp->DidReceiveHeader("trusted-types abc * def",
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
+ EXPECT_TRUE(csp->AllowTrustedTypePolicy("abc", false));
+ EXPECT_TRUE(csp->AllowTrustedTypePolicy("def", false));
+ EXPECT_TRUE(csp->AllowTrustedTypePolicy("ghi", false));
+ EXPECT_FALSE(csp->AllowTrustedTypePolicy("abc", true));
+ EXPECT_FALSE(csp->AllowTrustedTypePolicy("def", true));
+ EXPECT_FALSE(csp->AllowTrustedTypePolicy("ghi", true));
+}
+
+TEST_F(ContentSecurityPolicyTest, TrustedTypeDupe) {
+ csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
+ csp->DidReceiveHeader("trusted-types somepolicy 'allow-duplicates'",
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
+ EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", false));
+ EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", true));
+}
+
+TEST_F(ContentSecurityPolicyTest, TrustedTypeDupeStar) {
+ csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
+ csp->DidReceiveHeader("trusted-types * 'allow-duplicates'",
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", false));
EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", true));
}
TEST_F(ContentSecurityPolicyTest, TrustedTypesReserved) {
- execution_context->SetRequireTrustedTypesForTesting();
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
csp->DidReceiveHeader("trusted-types one \"two\" 'three'",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(csp->AllowTrustedTypePolicy("one", false));
EXPECT_TRUE(csp->AllowTrustedTypePolicy("one", false));
@@ -1419,77 +1457,88 @@ TEST_F(ContentSecurityPolicyTest, TrustedTypesReserved) {
}
TEST_F(ContentSecurityPolicyTest, TrustedTypesReportingStar) {
- execution_context->SetRequireTrustedTypesForTesting();
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
- csp->DidReceiveHeader("trusted-types *",
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceHTTP);
+ csp->DidReceiveHeader("trusted-types *", ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", false));
EXPECT_TRUE(csp->AllowTrustedTypePolicy("somepolicy", true));
}
TEST_F(ContentSecurityPolicyTest, TrustedTypeReportingSimple) {
- execution_context->SetRequireTrustedTypesForTesting();
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
csp->DidReceiveHeader("trusted-types a b c",
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(csp->AllowTrustedTypePolicy("a", false));
EXPECT_TRUE(csp->AllowTrustedTypePolicy("a", true));
}
TEST_F(ContentSecurityPolicyTest, TrustedTypeEnforce) {
- execution_context->SetRequireTrustedTypesForTesting();
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
csp->DidReceiveHeader("trusted-types one\ntwo\rthree",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
- EXPECT_TRUE(csp->IsRequireTrustedTypes());
- EXPECT_FALSE(csp->AllowTrustedTypeAssignmentFailure("blabla"));
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
+ EXPECT_FALSE(csp->IsRequireTrustedTypes());
+ EXPECT_TRUE(csp->AllowTrustedTypeAssignmentFailure("blabla"));
}
TEST_F(ContentSecurityPolicyTest, TrustedTypeReport) {
- execution_context->SetRequireTrustedTypesForTesting();
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
csp->DidReceiveHeader("trusted-types one\ntwo\rthree",
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceHTTP);
- EXPECT_TRUE(csp->IsRequireTrustedTypes());
+ ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kHTTP);
+ EXPECT_FALSE(csp->IsRequireTrustedTypes());
EXPECT_TRUE(csp->AllowTrustedTypeAssignmentFailure("blabla"));
}
TEST_F(ContentSecurityPolicyTest, TrustedTypeReportAndEnforce) {
- execution_context->SetRequireTrustedTypesForTesting();
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
- csp->DidReceiveHeader("trusted-types one",
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceHTTP);
+ csp->DidReceiveHeader("trusted-types one", ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kHTTP);
csp->DidReceiveHeader("trusted-types two",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
- EXPECT_TRUE(csp->IsRequireTrustedTypes());
- EXPECT_FALSE(csp->AllowTrustedTypeAssignmentFailure("blabla"));
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
+ EXPECT_FALSE(csp->IsRequireTrustedTypes());
+ EXPECT_TRUE(csp->AllowTrustedTypeAssignmentFailure("blabla"));
}
TEST_F(ContentSecurityPolicyTest, TrustedTypeReportAndNonTTEnforce) {
- execution_context->SetRequireTrustedTypesForTesting();
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
- csp->DidReceiveHeader("trusted-types one",
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceHTTP);
- csp->DidReceiveHeader("script-src none",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
- EXPECT_TRUE(csp->IsRequireTrustedTypes());
+ csp->DidReceiveHeader("trusted-types one", ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kHTTP);
+ csp->DidReceiveHeader("script-src none", ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
+ EXPECT_FALSE(csp->IsRequireTrustedTypes());
EXPECT_TRUE(csp->AllowTrustedTypeAssignmentFailure("blabla"));
}
+TEST_F(ContentSecurityPolicyTest, RequireTrustedTypeForEnforce) {
+ execution_context->GetSecurityContext().SetRequireTrustedTypesForTesting();
+ csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
+ csp->DidReceiveHeader("require-trusted-types-for ''",
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
+ EXPECT_FALSE(csp->IsRequireTrustedTypes());
+
+ csp->DidReceiveHeader("require-trusted-types-for 'script'",
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
+ EXPECT_TRUE(csp->IsRequireTrustedTypes());
+}
+
+TEST_F(ContentSecurityPolicyTest, RequireTrustedTypeForReport) {
+ execution_context->GetSecurityContext().SetRequireTrustedTypesForTesting();
+ csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
+ csp->DidReceiveHeader("require-trusted-types-for 'script'",
+ ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kHTTP);
+ EXPECT_TRUE(csp->IsRequireTrustedTypes());
+}
+
TEST_F(ContentSecurityPolicyTest, DefaultPolicy) {
- execution_context->SetRequireTrustedTypesForTesting();
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
- csp->DidReceiveHeader("trusted-types *",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ csp->DidReceiveHeader("trusted-types *", ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
EXPECT_TRUE(csp->AllowTrustedTypePolicy("default", false));
EXPECT_FALSE(csp->AllowTrustedTypePolicy("default", true));
}
@@ -1501,8 +1550,8 @@ TEST_F(ContentSecurityPolicyTest, DirectiveNameCaseInsensitive) {
// Directive name is case insensitive.
csp = MakeGarbageCollected<ContentSecurityPolicy>();
csp->DidReceiveHeader("sCrIpt-sRc http://example.com",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
EXPECT_TRUE(csp->AllowScriptFromSource(
@@ -1515,8 +1564,7 @@ TEST_F(ContentSecurityPolicyTest, DirectiveNameCaseInsensitive) {
csp = MakeGarbageCollected<ContentSecurityPolicy>();
csp->DidReceiveHeader(
"SCRipt-SRC http://example.com; script-src http://not-example.com;",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ ContentSecurityPolicyType::kEnforce, ContentSecurityPolicySource::kHTTP);
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
EXPECT_TRUE(csp->AllowScriptFromSource(
@@ -1547,17 +1595,17 @@ TEST_F(ContentSecurityPolicyTest, EmptyCSPIsNoOp) {
EXPECT_TRUE(csp->AllowInline(
ContentSecurityPolicy::InlineType::kScriptAttribute, element, source,
String() /* nonce */, context_url, ordinal_number));
- EXPECT_TRUE(csp->AllowEval(SecurityViolationReportingPolicy::kReport,
+ EXPECT_TRUE(csp->AllowEval(ReportingDisposition::kReport,
ContentSecurityPolicy::kWillNotThrowException,
g_empty_string));
- EXPECT_TRUE(csp->AllowWasmEval(SecurityViolationReportingPolicy::kReport,
+ EXPECT_TRUE(csp->AllowWasmEval(ReportingDisposition::kReport,
ContentSecurityPolicy::kWillNotThrowException,
g_empty_string));
EXPECT_TRUE(csp->AllowPluginType("application/x-type-1",
"application/x-type-1", example_url));
EXPECT_TRUE(csp->AllowPluginTypeForDocument(
*document, "application/x-type-1", "application/x-type-1", example_url,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
ContentSecurityPolicy::DirectiveType types_to_test[] = {
ContentSecurityPolicy::DirectiveType::kBaseURI,
@@ -1605,12 +1653,12 @@ TEST_F(ContentSecurityPolicyTest, EmptyCSPIsNoOp) {
EXPECT_FALSE(csp->IsActive());
EXPECT_FALSE(csp->IsActiveForConnections());
EXPECT_TRUE(csp->FallbackUrlForPlugin().IsEmpty());
- EXPECT_EQ(kLeaveInsecureRequestsAlone, csp->GetInsecureRequestPolicy());
+ EXPECT_EQ(mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone,
+ csp->GetInsecureRequestPolicy());
EXPECT_FALSE(csp->HasHeaderDeliveredPolicy());
EXPECT_FALSE(csp->SupportsWasmEval());
- EXPECT_EQ(WebSandboxFlags::kNone, csp->GetSandboxMask());
- EXPECT_FALSE(
- csp->HasPolicyFromSource(kContentSecurityPolicyHeaderSourceHTTP));
+ EXPECT_EQ(mojom::blink::WebSandboxFlags::kNone, csp->GetSandboxMask());
+ EXPECT_FALSE(csp->HasPolicyFromSource(ContentSecurityPolicySource::kHTTP));
}
TEST_F(ContentSecurityPolicyTest, OpaqueOriginBeforeBind) {
@@ -1623,13 +1671,149 @@ TEST_F(ContentSecurityPolicyTest, OpaqueOriginBeforeBind) {
execution_context = CreateExecutionContext();
csp->BindToDelegate(execution_context->GetContentSecurityPolicyDelegate());
csp->DidReceiveHeader("default-src 'self';",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceMeta);
- EXPECT_TRUE(
- csp->AllowRequest(mojom::RequestContextType::SUBRESOURCE, url, String(),
- IntegrityMetadataSet(), kParserInserted,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kMeta);
+ EXPECT_TRUE(csp->AllowRequest(mojom::RequestContextType::SUBRESOURCE, url,
+ String(), IntegrityMetadataSet(),
+ kParserInserted,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
+}
+
+TEST_F(ContentSecurityPolicyTest, ReasonableRestrictionMetrics) {
+ struct TestCase {
+ const char* header;
+ bool expected_object;
+ bool expected_base;
+ bool expected_script;
+ } cases[] = {{"object-src 'none'", true, false, false},
+ {"object-src 'none'; base-uri 'none'", true, true, false},
+ {"object-src 'none'; base-uri 'none'; script-src 'none'", true,
+ true, true},
+ {"object-src 'none'; base-uri 'none'; script-src 'nonce-abc'",
+ true, true, true},
+ {"object-src 'none'; base-uri 'none'; script-src 'sha256-abc'",
+ true, true, true},
+ {"object-src 'none'; base-uri 'none'; script-src 'nonce-abc' "
+ "'strict-dynamic'",
+ true, true, true},
+ {"object-src 'none'; base-uri 'none'; script-src 'sha256-abc' "
+ "'strict-dynamic'",
+ true, true, true},
+ {"object-src 'none'; base-uri 'none'; script-src 'sha256-abc' "
+ "https://example.com/",
+ true, true, false},
+ {"object-src 'none'; base-uri 'none'; script-src 'sha256-abc' "
+ "https://example.com/ 'strict-dynamic'",
+ true, true, true}};
+
+ // Enforced
+ for (const auto& test : cases) {
+ SCOPED_TRACE(testing::Message()
+ << "[Enforce] Header: `" << test.header << "`");
+ csp = MakeGarbageCollected<ContentSecurityPolicy>();
+ csp->DidReceiveHeader(test.header, ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
+ auto dummy = std::make_unique<DummyPageHolder>();
+ csp->BindToDelegate(
+ dummy->GetDocument().GetContentSecurityPolicyDelegate());
+
+ EXPECT_EQ(test.expected_object,
+ dummy->GetDocument().IsUseCounted(
+ WebFeature::kCSPWithReasonableObjectRestrictions));
+ EXPECT_EQ(test.expected_base,
+ dummy->GetDocument().IsUseCounted(
+ WebFeature::kCSPWithReasonableBaseRestrictions));
+ EXPECT_EQ(test.expected_script,
+ dummy->GetDocument().IsUseCounted(
+ WebFeature::kCSPWithReasonableScriptRestrictions));
+ EXPECT_EQ(
+ test.expected_object && test.expected_base && test.expected_script,
+ dummy->GetDocument().IsUseCounted(
+ WebFeature::kCSPWithReasonableRestrictions));
+ }
+
+ // Report-Only
+ for (const auto& test : cases) {
+ SCOPED_TRACE(testing::Message()
+ << "[ReportOnly] Header: `" << test.header << "`");
+ csp = MakeGarbageCollected<ContentSecurityPolicy>();
+ csp->DidReceiveHeader(test.header, ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kHTTP);
+ auto dummy = std::make_unique<DummyPageHolder>();
+ csp->BindToDelegate(
+ dummy->GetDocument().GetContentSecurityPolicyDelegate());
+
+ EXPECT_EQ(test.expected_object,
+ dummy->GetDocument().IsUseCounted(
+ WebFeature::kCSPROWithReasonableObjectRestrictions));
+ EXPECT_EQ(test.expected_base,
+ dummy->GetDocument().IsUseCounted(
+ WebFeature::kCSPROWithReasonableBaseRestrictions));
+ EXPECT_EQ(test.expected_script,
+ dummy->GetDocument().IsUseCounted(
+ WebFeature::kCSPROWithReasonableScriptRestrictions));
+ EXPECT_EQ(
+ test.expected_object && test.expected_base && test.expected_script,
+ dummy->GetDocument().IsUseCounted(
+ WebFeature::kCSPROWithReasonableRestrictions));
+ }
+}
+
+TEST_F(ContentSecurityPolicyTest, BetterThanReasonableRestrictionMetrics) {
+ struct TestCase {
+ const char* header;
+ bool expected;
+ } cases[] = {
+ {"object-src 'none'", false},
+ {"object-src 'none'; base-uri 'none'", false},
+ {"object-src 'none'; base-uri 'none'; script-src 'none'", true},
+ {"object-src 'none'; base-uri 'none'; script-src 'nonce-abc'", true},
+ {"object-src 'none'; base-uri 'none'; script-src 'sha256-abc'", true},
+ {"object-src 'none'; base-uri 'none'; script-src 'nonce-abc' "
+ "'strict-dynamic'",
+ false},
+ {"object-src 'none'; base-uri 'none'; script-src 'sha256-abc' "
+ "'strict-dynamic'",
+ false},
+ {"object-src 'none'; base-uri 'none'; script-src 'sha256-abc' "
+ "https://example.com/",
+ false},
+ {"object-src 'none'; base-uri 'none'; script-src 'sha256-abc' "
+ "https://example.com/ 'strict-dynamic'",
+ false}};
+
+ // Enforced
+ for (const auto& test : cases) {
+ SCOPED_TRACE(testing::Message()
+ << "[Enforce] Header: `" << test.header << "`");
+ csp = MakeGarbageCollected<ContentSecurityPolicy>();
+ csp->DidReceiveHeader(test.header, ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicySource::kHTTP);
+ auto dummy = std::make_unique<DummyPageHolder>();
+ csp->BindToDelegate(
+ dummy->GetDocument().GetContentSecurityPolicyDelegate());
+
+ EXPECT_EQ(test.expected,
+ dummy->GetDocument().IsUseCounted(
+ WebFeature::kCSPWithBetterThanReasonableRestrictions));
+ }
+
+ // Report-Only
+ for (const auto& test : cases) {
+ SCOPED_TRACE(testing::Message()
+ << "[ReportOnly] Header: `" << test.header << "`");
+ csp = MakeGarbageCollected<ContentSecurityPolicy>();
+ csp->DidReceiveHeader(test.header, ContentSecurityPolicyType::kReport,
+ ContentSecurityPolicySource::kHTTP);
+ auto dummy = std::make_unique<DummyPageHolder>();
+ csp->BindToDelegate(
+ dummy->GetDocument().GetContentSecurityPolicyDelegate());
+
+ EXPECT_EQ(test.expected,
+ dummy->GetDocument().IsUseCounted(
+ WebFeature::kCSPROWithBetterThanReasonableRestrictions));
+ }
}
} // namespace blink
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 3bdaebfe99f..668ab028ce5 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
@@ -7,13 +7,12 @@
#include "base/macros.h"
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
-class ContentSecurityPolicy;
-
class CORE_EXPORT CSPDirective : public GarbageCollected<CSPDirective> {
public:
CSPDirective(const String& name,
@@ -21,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(blink::Visitor* visitor) { visitor->Trace(policy_); }
+ virtual void Trace(Visitor* visitor) { 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 238eb29a8b5..faa75575624 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
@@ -8,6 +8,7 @@
#include <utility>
#include "services/network/public/cpp/features.h"
+#include "services/network/public/mojom/content_security_policy.mojom-shared.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/dom/space_split_string.h"
@@ -17,6 +18,7 @@
#include "third_party/blink/renderer/core/html/html_script_element.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/platform/crypto.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/content_security_policy_parsers.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -124,9 +126,12 @@ ContentSecurityPolicy::DirectiveType GetDirectiveTypeForAllowHashFromInlineType(
} // namespace
+using network::mojom::ContentSecurityPolicySource;
+using network::mojom::ContentSecurityPolicyType;
+
CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy,
- ContentSecurityPolicyHeaderType type,
- ContentSecurityPolicyHeaderSource source)
+ ContentSecurityPolicyType type,
+ ContentSecurityPolicySource source)
: policy_(policy),
header_type_(type),
header_source_(source),
@@ -136,13 +141,12 @@ CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy,
require_sri_for_(RequireSRIForToken::kNone),
use_reporting_api_(false) {}
-CSPDirectiveList* CSPDirectiveList::Create(
- ContentSecurityPolicy* policy,
- const UChar* begin,
- const UChar* end,
- ContentSecurityPolicyHeaderType type,
- ContentSecurityPolicyHeaderSource source,
- bool should_parse_wasm_eval) {
+CSPDirectiveList* CSPDirectiveList::Create(ContentSecurityPolicy* policy,
+ const UChar* begin,
+ const UChar* end,
+ ContentSecurityPolicyType type,
+ ContentSecurityPolicySource source,
+ bool should_parse_wasm_eval) {
CSPDirectiveList* directives =
MakeGarbageCollected<CSPDirectiveList>(policy, type, source);
directives->Parse(begin, end, should_parse_wasm_eval);
@@ -159,7 +163,7 @@ CSPDirectiveList* CSPDirectiveList::Create(
->GetText() +
"\".\n";
directives->SetEvalDisabledErrorMessage(message);
- } else if (directives->trusted_types_) {
+ } else if (directives->RequiresTrustedTypes()) {
String message =
"Refused to evaluate a string as JavaScript because this document "
"requires 'Trusted Type' assignment.";
@@ -167,7 +171,7 @@ CSPDirectiveList* CSPDirectiveList::Create(
}
if (directives->IsReportOnly() &&
- source != kContentSecurityPolicyHeaderSourceMeta &&
+ source != ContentSecurityPolicySource::kMeta &&
directives->ReportEndpoints().IsEmpty()) {
policy->ReportMissingReportURI(
String(begin, static_cast<wtf_size_t>(end - begin)));
@@ -183,12 +187,13 @@ void CSPDirectiveList::ReportViolation(
const KURL& blocked_url,
ResourceRequest::RedirectStatus redirect_status,
ContentSecurityPolicy::ViolationType violation_type,
- const String& sample) const {
+ const String& sample,
+ const String& sample_prefix) const {
String message =
IsReportOnly() ? "[Report Only] " + console_message : console_message;
- policy_->LogToConsole(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kError, message));
+ policy_->LogToConsole(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kSecurity,
+ mojom::ConsoleMessageLevel::kError, message));
policy_->ReportViolation(directive_text, effective_type, message, blocked_url,
report_endpoints_, use_reporting_api_, header_,
header_type_, violation_type,
@@ -196,7 +201,7 @@ void CSPDirectiveList::ReportViolation(
nullptr, // localFrame
redirect_status,
nullptr, // Element*
- sample);
+ sample, sample_prefix);
}
void CSPDirectiveList::ReportViolationWithFrame(
@@ -207,10 +212,10 @@ void CSPDirectiveList::ReportViolationWithFrame(
LocalFrame* frame) const {
String message =
IsReportOnly() ? "[Report Only] " + console_message : console_message;
- policy_->LogToConsole(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kError, message),
- frame);
+ policy_->LogToConsole(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kSecurity,
+ mojom::ConsoleMessageLevel::kError, message),
+ frame);
policy_->ReportViolation(directive_text, effective_type, message, blocked_url,
report_endpoints_, use_reporting_api_, header_,
header_type_, ContentSecurityPolicy::kURLViolation,
@@ -230,7 +235,7 @@ void CSPDirectiveList::ReportViolationWithLocation(
IsReportOnly() ? "[Report Only] " + console_message : console_message;
std::unique_ptr<SourceLocation> source_location =
SourceLocation::Capture(context_url, context_line.OneBasedInt(), 0);
- policy_->LogToConsole(ConsoleMessage::Create(
+ policy_->LogToConsole(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kSecurity,
mojom::ConsoleMessageLevel::kError, message, source_location->Clone()));
policy_->ReportViolation(directive_text, effective_type, message, blocked_url,
@@ -255,7 +260,7 @@ void CSPDirectiveList::ReportEvalViolation(
// a violation.)
if (IsReportOnly() ||
exception_status == ContentSecurityPolicy::kWillNotThrowException) {
- ConsoleMessage* console_message = ConsoleMessage::Create(
+ auto* console_message = MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kSecurity,
mojom::ConsoleMessageLevel::kError, report_message);
policy_->LogToConsole(console_message);
@@ -329,15 +334,17 @@ void CSPDirectiveList::ReportMixedContent(
bool CSPDirectiveList::AllowTrustedTypeAssignmentFailure(
const String& message,
- const String& sample) const {
- if (!trusted_types_)
+ const String& sample,
+ const String& sample_prefix) const {
+ if (!require_trusted_types_for_ || !require_trusted_types_for_->require())
return true;
- ReportViolation(ContentSecurityPolicy::GetDirectiveName(
- ContentSecurityPolicy::DirectiveType::kTrustedTypes),
- ContentSecurityPolicy::DirectiveType::kTrustedTypes, message,
- KURL(), RedirectStatus::kFollowedRedirect,
- ContentSecurityPolicy::kTrustedTypesSinkViolation, sample);
+ ReportViolation(
+ ContentSecurityPolicy::GetDirectiveName(
+ ContentSecurityPolicy::DirectiveType::kRequireTrustedTypesFor),
+ ContentSecurityPolicy::DirectiveType::kRequireTrustedTypesFor, message,
+ KURL(), RedirectStatus::kFollowedRedirect,
+ ContentSecurityPolicy::kTrustedTypesSinkViolation, sample, sample_prefix);
return IsReportOnly();
}
@@ -441,8 +448,8 @@ bool CSPDirectiveList::AllowRequestWithoutIntegrity(
mojom::RequestContextType context,
const KURL& url,
ResourceRequest::RedirectStatus redirect_status,
- SecurityViolationReportingPolicy reporting_policy) const {
- if (reporting_policy == SecurityViolationReportingPolicy::kReport)
+ ReportingDisposition reporting_disposition) const {
+ if (reporting_disposition == ReportingDisposition::kReport)
return CheckRequestWithoutIntegrityAndReportViolation(context, url,
redirect_status);
return DenyIfEnforcingPolicy() || CheckRequestWithoutIntegrity(context);
@@ -678,7 +685,7 @@ bool CSPDirectiveList::AllowInline(
const String& nonce,
const String& context_url,
const WTF::OrdinalNumber& context_line,
- SecurityViolationReportingPolicy reporting_policy) const {
+ ReportingDisposition reporting_disposition) const {
ContentSecurityPolicy::DirectiveType type =
GetDirectiveTypeForAllowInlineFromInlineType(inline_type);
@@ -693,7 +700,7 @@ bool CSPDirectiveList::AllowInline(
AllowDynamic(type)) {
return true;
}
- if (reporting_policy == SecurityViolationReportingPolicy::kReport) {
+ if (reporting_disposition == ReportingDisposition::kReport) {
String hash_value;
switch (inline_type) {
case ContentSecurityPolicy::InlineType::kNavigation:
@@ -741,11 +748,15 @@ bool CSPDirectiveList::AllowInline(
return !directive || directive->AllowAllInline();
}
+bool CSPDirectiveList::ShouldCheckEval() const {
+ return script_src_ && !script_src_->AllowEval();
+}
+
bool CSPDirectiveList::AllowEval(
- SecurityViolationReportingPolicy reporting_policy,
+ ReportingDisposition reporting_disposition,
ContentSecurityPolicy::ExceptionStatus exception_status,
const String& content) const {
- if (reporting_policy == SecurityViolationReportingPolicy::kReport) {
+ if (reporting_disposition == ReportingDisposition::kReport) {
return CheckEvalAndReportViolation(
OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc),
"Refused to evaluate a string as JavaScript because 'unsafe-eval' is "
@@ -759,10 +770,10 @@ bool CSPDirectiveList::AllowEval(
}
bool CSPDirectiveList::AllowWasmEval(
- SecurityViolationReportingPolicy reporting_policy,
+ ReportingDisposition reporting_disposition,
ContentSecurityPolicy::ExceptionStatus exception_status,
const String& content) const {
- if (reporting_policy == SecurityViolationReportingPolicy::kReport) {
+ if (reporting_disposition == ReportingDisposition::kReport) {
return CheckWasmEvalAndReportViolation(
OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc),
"Refused to compile or instantiate WebAssembly module because "
@@ -776,21 +787,21 @@ bool CSPDirectiveList::AllowWasmEval(
}
bool CSPDirectiveList::ShouldDisableEvalBecauseScriptSrc() const {
- return !AllowEval(SecurityViolationReportingPolicy::kSuppressReporting,
+ return !AllowEval(ReportingDisposition::kSuppressReporting,
ContentSecurityPolicy::kWillNotThrowException,
g_empty_string);
}
bool CSPDirectiveList::ShouldDisableEvalBecauseTrustedTypes() const {
- return trusted_types_;
+ return RequiresTrustedTypes();
}
bool CSPDirectiveList::AllowPluginType(
const String& type,
const String& type_attribute,
const KURL& url,
- SecurityViolationReportingPolicy reporting_policy) const {
- return reporting_policy == SecurityViolationReportingPolicy::kReport
+ ReportingDisposition reporting_disposition) const {
+ return reporting_disposition == ReportingDisposition::kReport
? CheckMediaTypeAndReportViolation(
plugin_types_.Get(), type, type_attribute,
"Refused to load '" + url.ElidedString() + "' (MIME type '" +
@@ -804,7 +815,7 @@ bool CSPDirectiveList::AllowFromSource(
ContentSecurityPolicy::DirectiveType type,
const KURL& url,
ResourceRequest::RedirectStatus redirect_status,
- SecurityViolationReportingPolicy reporting_policy,
+ ReportingDisposition reporting_disposition,
const String& nonce,
const IntegrityMetadataSet& hashes,
ParserDisposition parser_disposition) const {
@@ -846,7 +857,7 @@ bool CSPDirectiveList::AllowFromSource(
}
bool result =
- reporting_policy == SecurityViolationReportingPolicy::kReport
+ reporting_disposition == ReportingDisposition::kReport
? CheckSourceAndReportViolation(OperativeDirective(type), url, type,
redirect_status)
: CheckSource(OperativeDirective(type), url, redirect_status);
@@ -883,8 +894,8 @@ bool CSPDirectiveList::AllowTrustedTypePolicy(const String& policy_name,
bool CSPDirectiveList::AllowAncestors(
LocalFrame* frame,
const KURL& url,
- SecurityViolationReportingPolicy reporting_policy) const {
- return reporting_policy == SecurityViolationReportingPolicy::kReport
+ ReportingDisposition reporting_disposition) const {
+ return reporting_disposition == ReportingDisposition::kReport
? CheckAncestorsAndReportViolation(
OperativeDirective(
ContentSecurityPolicy::DirectiveType::kFrameAncestors),
@@ -1121,7 +1132,7 @@ void CSPDirectiveList::ParseReportURI(const String& name, const String& value) {
// Remove report-uri in meta policies, per
// https://html.spec.whatwg.org/C/#attr-meta-http-equiv-content-security-policy.
- if (header_source_ == kContentSecurityPolicyHeaderSourceMeta) {
+ if (header_source_ == ContentSecurityPolicySource::kMeta) {
policy_->ReportInvalidDirectiveInMeta(name);
return;
}
@@ -1193,7 +1204,7 @@ void CSPDirectiveList::SetCSPDirective(const String& name,
// Remove frame-ancestors directives in meta policies, per
// https://www.w3.org/TR/CSP2/#delivery-html-meta-element.
- if (header_source_ == kContentSecurityPolicyHeaderSourceMeta &&
+ if (header_source_ == ContentSecurityPolicySource::kMeta &&
ContentSecurityPolicy::GetDirectiveType(name) ==
ContentSecurityPolicy::DirectiveType::kFrameAncestors) {
policy_->ReportInvalidDirectiveInMeta(name);
@@ -1207,7 +1218,7 @@ void CSPDirectiveList::ApplySandboxPolicy(const String& name,
const String& sandbox_policy) {
// Remove sandbox directives in meta policies, per
// https://www.w3.org/TR/CSP2/#delivery-html-meta-element.
- if (header_source_ == kContentSecurityPolicyHeaderSourceMeta) {
+ if (header_source_ == ContentSecurityPolicySource::kMeta) {
policy_->ReportInvalidDirectiveInMeta(name);
return;
}
@@ -1229,17 +1240,29 @@ void CSPDirectiveList::ApplySandboxPolicy(const String& name,
policy_->ReportInvalidSandboxFlags(invalid_tokens);
}
-void CSPDirectiveList::RequireTrustedTypes(const String& name,
- const String& value) {
+void CSPDirectiveList::AddTrustedTypes(const String& name,
+ const String& value) {
if (trusted_types_) {
policy_->ReportDuplicateDirective(name);
return;
}
- policy_->RequireTrustedTypes();
trusted_types_ =
MakeGarbageCollected<StringListDirective>(name, value, policy_);
}
+void CSPDirectiveList::RequireTrustedTypesFor(const String& name,
+ const String& value) {
+ if (require_trusted_types_for_) {
+ policy_->ReportDuplicateDirective(name);
+ return;
+ }
+ require_trusted_types_for_ =
+ MakeGarbageCollected<RequireTrustedTypesForDirective>(name, value,
+ policy_);
+ if (require_trusted_types_for_->require())
+ policy_->RequireTrustedTypes();
+}
+
void CSPDirectiveList::EnforceStrictMixedContentChecking(const String& name,
const String& value) {
if (strict_mixed_content_checking_enforced_) {
@@ -1344,7 +1367,10 @@ void CSPDirectiveList::AddDirective(const String& name, const String& value) {
base::FeatureList::IsEnabled(network::features::kReporting)) {
ParseReportTo(name, value);
} else if (type == ContentSecurityPolicy::DirectiveType::kTrustedTypes) {
- RequireTrustedTypes(name, value);
+ AddTrustedTypes(name, value);
+ } else if (type ==
+ ContentSecurityPolicy::DirectiveType::kRequireTrustedTypesFor) {
+ RequireTrustedTypesFor(name, value);
} else if (policy_->ExperimentalFeaturesEnabled()) {
if (type == ContentSecurityPolicy::DirectiveType::kRequireSRIFor) {
ParseRequireSRIFor(name, value);
@@ -1565,38 +1591,82 @@ bool CSPDirectiveList::Subsumes(const CSPDirectiveListVector& other) {
return plugin_types_->Subsumes(plugin_types_other);
}
-WebContentSecurityPolicy CSPDirectiveList::ExposeForNavigationalChecks() const {
- WebContentSecurityPolicy policy;
- policy.disposition =
- static_cast<network::mojom::ContentSecurityPolicyType>(header_type_);
- policy.source =
- static_cast<network::mojom::ContentSecurityPolicySource>(header_source_);
- for (const auto& directive :
- {child_src_, default_src_, form_action_, frame_src_, navigate_to_}) {
- if (directive) {
- policy.directives.emplace_back(WebContentSecurityPolicyDirective{
- directive->DirectiveName(),
- directive->ExposeForNavigationalChecks()});
- }
+network::mojom::blink::ContentSecurityPolicyPtr
+CSPDirectiveList::ExposeForNavigationalChecks() const {
+ using CSPDirectiveName = network::mojom::blink::CSPDirectiveName;
+
+ auto policy = network::mojom::blink::ContentSecurityPolicy::New();
+
+ policy->use_reporting_api = use_reporting_api_;
+ policy->report_endpoints = report_endpoints_;
+ policy->header = network::mojom::blink::ContentSecurityPolicyHeader::New(
+ header_, header_type_, header_source_);
+
+ if (child_src_) {
+ policy->directives.Set(CSPDirectiveName::ChildSrc,
+ child_src_->ExposeForNavigationalChecks());
}
- if (upgrade_insecure_requests_) {
- policy.directives.emplace_back(WebContentSecurityPolicyDirective{
- blink::WebString("upgrade-insecure-requests"),
- WebContentSecurityPolicySourceList()});
+
+ if (default_src_) {
+ policy->directives.Set(CSPDirectiveName::DefaultSrc,
+ default_src_->ExposeForNavigationalChecks());
}
- for (const auto& report_endpoint : ReportEndpoints()) {
- policy.report_endpoints.emplace_back(report_endpoint);
+ if (form_action_) {
+ policy->directives.Set(CSPDirectiveName::FormAction,
+ form_action_->ExposeForNavigationalChecks());
}
- policy.use_reporting_api = use_reporting_api_;
+ if (frame_src_) {
+ policy->directives.Set(CSPDirectiveName::FrameSrc,
+ frame_src_->ExposeForNavigationalChecks());
+ }
- policy.header = Header();
+ if (navigate_to_) {
+ policy->directives.Set(CSPDirectiveName::NavigateTo,
+ navigate_to_->ExposeForNavigationalChecks());
+ }
+
+ if (upgrade_insecure_requests_) {
+ auto empty_source_list = network::mojom::blink::CSPSourceList::New(
+ WTF::Vector<network::mojom::blink::CSPSourcePtr>(), false, false,
+ false);
+ policy->directives.Set(CSPDirectiveName::UpgradeInsecureRequests,
+ std::move(empty_source_list));
+ }
return policy;
}
-void CSPDirectiveList::Trace(blink::Visitor* visitor) {
+bool CSPDirectiveList::IsObjectRestrictionReasonable() const {
+ SourceListDirective* object_src =
+ OperativeDirective(ContentSecurityPolicy::DirectiveType::kObjectSrc);
+ return object_src && object_src->IsNone();
+}
+
+bool CSPDirectiveList::IsBaseRestrictionReasonable() const {
+ return base_uri_ && (base_uri_->IsNone() || base_uri_->IsSelf());
+}
+
+bool CSPDirectiveList::IsScriptRestrictionReasonable() const {
+ SourceListDirective* script_src =
+ OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc);
+
+ // If no `script-src` enforcement occurs, or it allows any and all inline
+ // script, the restriction is not reasonable.
+ if (!script_src || script_src->AllowAllInline())
+ return false;
+
+ if (script_src->IsNone())
+ return true;
+
+ // Policies containing `'strict-dynamic'` are reasonable, as that keyword
+ // ensures that host-based expressions and `'unsafe-inline'` are ignored.
+ return script_src->IsHashOrNoncePresent() &&
+ (script_src->AllowDynamic() || !script_src->AllowsURLBasedMatching());
+}
+
+void CSPDirectiveList::Trace(Visitor* visitor) {
visitor->Trace(policy_);
visitor->Trace(plugin_types_);
visitor->Trace(base_uri_);
@@ -1621,6 +1691,7 @@ void CSPDirectiveList::Trace(blink::Visitor* visitor) {
visitor->Trace(worker_src_);
visitor->Trace(navigate_to_);
visitor->Trace(trusted_types_);
+ visitor->Trace(require_trusted_types_for_);
}
} // namespace blink
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 e9cfe4ab06b..6bf18836d1d 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
@@ -6,9 +6,9 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_CSP_CSP_DIRECTIVE_LIST_H_
#include "base/macros.h"
-#include "third_party/blink/public/platform/web_content_security_policy.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/csp/media_list_directive.h"
+#include "third_party/blink/renderer/core/frame/csp/require_trusted_types_for_directive.h"
#include "third_party/blink/renderer/core/frame/csp/source_list_directive.h"
#include "third_party/blink/renderer/core/frame/csp/string_list_directive.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -16,7 +16,7 @@
#include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h"
#include "third_party/blink/renderer/platform/network/http_parsers.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
-#include "third_party/blink/renderer/platform/weborigin/security_violation_reporting_policy.h"
+#include "third_party/blink/renderer/platform/weborigin/reporting_disposition.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -34,21 +34,23 @@ class CORE_EXPORT CSPDirectiveList final
static CSPDirectiveList* Create(ContentSecurityPolicy*,
const UChar* begin,
const UChar* end,
- ContentSecurityPolicyHeaderType,
- ContentSecurityPolicyHeaderSource,
+ network::mojom::ContentSecurityPolicyType,
+ network::mojom::ContentSecurityPolicySource,
bool should_parse_wasm_eval = false);
CSPDirectiveList(ContentSecurityPolicy*,
- ContentSecurityPolicyHeaderType,
- ContentSecurityPolicyHeaderSource);
+ network::mojom::ContentSecurityPolicyType,
+ network::mojom::ContentSecurityPolicySource);
void Parse(const UChar* begin,
const UChar* end,
bool should_parse_wasm_eval = false);
const String& Header() const { return header_; }
- ContentSecurityPolicyHeaderType HeaderType() const { return header_type_; }
- ContentSecurityPolicyHeaderSource HeaderSource() const {
+ network::mojom::ContentSecurityPolicyType HeaderType() const {
+ return header_type_;
+ }
+ network::mojom::ContentSecurityPolicySource HeaderSource() const {
return header_source_;
}
@@ -58,23 +60,27 @@ class CORE_EXPORT CSPDirectiveList final
const String& nonce,
const String& context_url,
const WTF::OrdinalNumber& context_line,
- SecurityViolationReportingPolicy) const;
+ ReportingDisposition) const;
+
+ // Returns whether or not the Javascript code generation should call back the
+ // CSP checker before any script evaluation from a string is being made.
+ bool ShouldCheckEval() const;
- bool AllowEval(SecurityViolationReportingPolicy,
+ bool AllowEval(ReportingDisposition,
ContentSecurityPolicy::ExceptionStatus,
const String& script_content) const;
- bool AllowWasmEval(SecurityViolationReportingPolicy,
+ bool AllowWasmEval(ReportingDisposition,
ContentSecurityPolicy::ExceptionStatus,
const String& script_content) const;
bool AllowPluginType(const String& type,
const String& type_attribute,
const KURL&,
- SecurityViolationReportingPolicy) const;
+ ReportingDisposition) const;
bool AllowFromSource(ContentSecurityPolicy::DirectiveType,
const KURL&,
ResourceRequest::RedirectStatus,
- SecurityViolationReportingPolicy,
+ ReportingDisposition,
const String& nonce = String(),
const IntegrityMetadataSet& = IntegrityMetadataSet(),
ParserDisposition = kParserInserted) const;
@@ -88,19 +94,18 @@ class CORE_EXPORT CSPDirectiveList final
// request was redirected, but this is not a concern for ancestors,
// because a child frame can't manipulate the URL of a cross-origin
// parent.
- bool AllowAncestors(LocalFrame*,
- const KURL&,
- SecurityViolationReportingPolicy) const;
+ bool AllowAncestors(LocalFrame*, const KURL&, ReportingDisposition) const;
bool AllowDynamic(ContentSecurityPolicy::DirectiveType) const;
bool AllowDynamicWorker() const;
bool AllowRequestWithoutIntegrity(mojom::RequestContextType,
const KURL&,
ResourceRequest::RedirectStatus,
- SecurityViolationReportingPolicy) const;
+ ReportingDisposition) const;
bool AllowTrustedTypeAssignmentFailure(const String& message,
- const String& sample) const;
+ const String& sample,
+ const String& sample_prefix) const;
bool StrictMixedContentChecking() const {
return strict_mixed_content_checking_enforced_;
@@ -118,7 +123,7 @@ class CORE_EXPORT CSPDirectiveList final
return eval_disabled_error_message_;
}
bool IsReportOnly() const {
- return header_type_ == kContentSecurityPolicyHeaderTypeReport;
+ return header_type_ == network::mojom::ContentSecurityPolicyType::kReport;
}
bool IsActiveForConnections() const {
return OperativeDirective(
@@ -157,9 +162,31 @@ class CORE_EXPORT CSPDirectiveList final
// * navigate-to
// The exported directives only contains sources that affect navigation. For
// instance it doesn't contains 'unsafe-inline' or 'unsafe-eval'
- WebContentSecurityPolicy ExposeForNavigationalChecks() const;
+ network::mojom::blink::ContentSecurityPolicyPtr ExposeForNavigationalChecks()
+ const;
+
+ // We consider `object-src` restrictions to be reasonable iff they're
+ // equivalent to `object-src 'none'`.
+ bool IsObjectRestrictionReasonable() const;
+
+ // We consider `base-uri` restrictions to be reasonable iff they're equivalent
+ // to `base-uri 'none'` or `base-uri 'self'`.
+ bool IsBaseRestrictionReasonable() const;
+
+ // We consider `script-src` restrictions to be reasonable iff they're not
+ // URL-based (e.g. they contain only nonces and hashes, or they use
+ // 'strict-dynamic'). Neither `'unsafe-eval'` nor `'unsafe-hashes'` affect
+ // this judgement.
+ bool IsScriptRestrictionReasonable() const;
+
+ bool RequiresTrustedTypes() const {
+ return require_trusted_types_for_ && require_trusted_types_for_->require();
+ }
+ bool TrustedTypesAllowDuplicates() const {
+ return trusted_types_ && trusted_types_->IsAllowDuplicates();
+ }
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
FRIEND_TEST_ALL_PREFIXES(CSPDirectiveListTest, IsMatchingNoncePresent);
@@ -182,7 +209,8 @@ class CORE_EXPORT CSPDirectiveList final
void EnforceStrictMixedContentChecking(const String& name,
const String& value);
void EnableInsecureRequestsUpgrade(const String& name, const String& value);
- void RequireTrustedTypes(const String& name, const String& value);
+ void AddTrustedTypes(const String& name, const String& value);
+ void RequireTrustedTypesFor(const String& name, const String& value);
template <class CSPDirectiveType>
void SetCSPDirective(const String& name,
@@ -200,7 +228,8 @@ class CORE_EXPORT CSPDirectiveList final
ResourceRequest::RedirectStatus,
ContentSecurityPolicy::ViolationType violation_type =
ContentSecurityPolicy::kURLViolation,
- const String& sample = String()) const;
+ const String& sample = String(),
+ const String& sample_prefix = String()) const;
void ReportViolationWithFrame(const String& directive_text,
const ContentSecurityPolicy::DirectiveType,
const String& console_message,
@@ -295,8 +324,8 @@ class CORE_EXPORT CSPDirectiveList final
Member<ContentSecurityPolicy> policy_;
String header_;
- ContentSecurityPolicyHeaderType header_type_;
- ContentSecurityPolicyHeaderSource header_source_;
+ network::mojom::ContentSecurityPolicyType header_type_;
+ network::mojom::ContentSecurityPolicySource header_source_;
bool has_sandbox_policy_;
@@ -327,6 +356,7 @@ class CORE_EXPORT CSPDirectiveList final
Member<SourceListDirective> worker_src_;
Member<SourceListDirective> navigate_to_;
Member<StringListDirective> trusted_types_;
+ Member<RequireTrustedTypesForDirective> require_trusted_types_for_;
uint8_t require_sri_for_;
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 2cc39ba3de8..67855995a13 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
@@ -22,6 +22,9 @@
namespace blink {
+using network::mojom::ContentSecurityPolicySource;
+using network::mojom::ContentSecurityPolicyType;
+
class CSPDirectiveListTest : public testing::Test {
public:
CSPDirectiveListTest() : csp(MakeGarbageCollected<ContentSecurityPolicy>()) {}
@@ -31,10 +34,10 @@ class CSPDirectiveListTest : public testing::Test {
*SecurityOrigin::CreateFromString("https://example.test/image.png"));
}
- CSPDirectiveList* CreateList(const String& list,
- ContentSecurityPolicyHeaderType type,
- ContentSecurityPolicyHeaderSource source =
- kContentSecurityPolicyHeaderSourceHTTP) {
+ CSPDirectiveList* CreateList(
+ const String& list,
+ ContentSecurityPolicyType type,
+ ContentSecurityPolicySource source = ContentSecurityPolicySource::kHTTP) {
Vector<UChar> characters;
list.AppendTo(characters);
const UChar* begin = characters.data();
@@ -59,10 +62,9 @@ TEST_F(CSPDirectiveListTest, Header) {
for (const auto& test : cases) {
Member<CSPDirectiveList> directive_list =
- CreateList(test.list, kContentSecurityPolicyHeaderTypeReport);
+ CreateList(test.list, ContentSecurityPolicyType::kReport);
EXPECT_EQ(test.expected, directive_list->Header());
- directive_list =
- CreateList(test.list, kContentSecurityPolicyHeaderTypeEnforce);
+ directive_list = CreateList(test.list, ContentSecurityPolicyType::kEnforce);
EXPECT_EQ(test.expected, directive_list->Header());
}
}
@@ -134,7 +136,7 @@ TEST_F(CSPDirectiveListTest, IsMatchingNoncePresent) {
for (const auto& test : cases) {
// Report-only
Member<CSPDirectiveList> directive_list =
- CreateList(test.list, kContentSecurityPolicyHeaderTypeReport);
+ CreateList(test.list, ContentSecurityPolicyType::kReport);
Member<SourceListDirective> directive =
directive_list->OperativeDirective(test.type);
EXPECT_EQ(test.expected,
@@ -144,8 +146,7 @@ TEST_F(CSPDirectiveListTest, IsMatchingNoncePresent) {
EXPECT_FALSE(directive_list->IsMatchingNoncePresent(directive, String()));
// Enforce
- directive_list =
- CreateList(test.list, kContentSecurityPolicyHeaderTypeEnforce);
+ directive_list = CreateList(test.list, ContentSecurityPolicyType::kEnforce);
directive = directive_list->OperativeDirective(test.type);
EXPECT_EQ(test.expected,
directive_list->IsMatchingNoncePresent(directive, test.nonce));
@@ -211,23 +212,22 @@ TEST_F(CSPDirectiveListTest, AllowScriptFromSourceNoNonce) {
// Report-only
Member<CSPDirectiveList> directive_list =
- CreateList(test.list, kContentSecurityPolicyHeaderTypeReport);
+ CreateList(test.list, ContentSecurityPolicyType::kReport);
EXPECT_EQ(test.expected,
directive_list->AllowFromSource(
ContentSecurityPolicy::DirectiveType::kScriptSrcElem,
script_src, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting,
- String(), IntegrityMetadataSet(), kParserInserted));
+ ReportingDisposition::kSuppressReporting, String(),
+ IntegrityMetadataSet(), kParserInserted));
// Enforce
- directive_list =
- CreateList(test.list, kContentSecurityPolicyHeaderTypeEnforce);
+ directive_list = CreateList(test.list, ContentSecurityPolicyType::kEnforce);
EXPECT_EQ(test.expected,
directive_list->AllowFromSource(
ContentSecurityPolicy::DirectiveType::kScriptSrcElem,
script_src, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting,
- String(), IntegrityMetadataSet(), kParserInserted));
+ ReportingDisposition::kSuppressReporting, String(),
+ IntegrityMetadataSet(), kParserInserted));
}
}
@@ -268,77 +268,76 @@ TEST_F(CSPDirectiveListTest, AllowFromSourceWithNonce) {
const KURL resource(test.url);
// Report-only 'script-src'
- Member<CSPDirectiveList> directive_list =
- CreateList(String("script-src ") + test.list,
- kContentSecurityPolicyHeaderTypeReport);
+ 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,
- SecurityViolationReportingPolicy::kSuppressReporting,
- String(test.nonce), IntegrityMetadataSet(), kParserInserted));
+ ReportingDisposition::kSuppressReporting, String(test.nonce),
+ IntegrityMetadataSet(), kParserInserted));
// Enforce 'script-src'
directive_list = CreateList(String("script-src ") + test.list,
- kContentSecurityPolicyHeaderTypeEnforce);
+ ContentSecurityPolicyType::kEnforce);
EXPECT_EQ(test.expected,
directive_list->AllowFromSource(
ContentSecurityPolicy::DirectiveType::kScriptSrcElem,
resource, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting,
- String(test.nonce), IntegrityMetadataSet(), kParserInserted));
+ ReportingDisposition::kSuppressReporting, String(test.nonce),
+ IntegrityMetadataSet(), kParserInserted));
// Report-only 'style-src'
directive_list = CreateList(String("style-src ") + test.list,
- kContentSecurityPolicyHeaderTypeReport);
- EXPECT_EQ(test.expected,
- directive_list->AllowFromSource(
- ContentSecurityPolicy::DirectiveType::kStyleSrcElem, resource,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting,
- String(test.nonce)));
+ ContentSecurityPolicyType::kReport);
+ EXPECT_EQ(
+ test.expected,
+ directive_list->AllowFromSource(
+ ContentSecurityPolicy::DirectiveType::kStyleSrcElem, resource,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting, String(test.nonce)));
// Enforce 'style-src'
directive_list = CreateList(String("style-src ") + test.list,
- kContentSecurityPolicyHeaderTypeEnforce);
- EXPECT_EQ(test.expected,
- directive_list->AllowFromSource(
- ContentSecurityPolicy::DirectiveType::kStyleSrcElem, resource,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting,
- String(test.nonce)));
+ ContentSecurityPolicyType::kEnforce);
+ EXPECT_EQ(
+ test.expected,
+ directive_list->AllowFromSource(
+ ContentSecurityPolicy::DirectiveType::kStyleSrcElem, resource,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting, String(test.nonce)));
// Report-only 'style-src'
directive_list = CreateList(String("default-src ") + test.list,
- kContentSecurityPolicyHeaderTypeReport);
- EXPECT_EQ(test.expected,
- directive_list->AllowFromSource(
- ContentSecurityPolicy::DirectiveType::kScriptSrcElem,
- resource, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting,
- String(test.nonce)));
- EXPECT_EQ(test.expected,
- directive_list->AllowFromSource(
- ContentSecurityPolicy::DirectiveType::kStyleSrcElem, resource,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting,
- String(test.nonce)));
+ ContentSecurityPolicyType::kReport);
+ EXPECT_EQ(
+ test.expected,
+ directive_list->AllowFromSource(
+ ContentSecurityPolicy::DirectiveType::kScriptSrcElem, resource,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting, String(test.nonce)));
+ EXPECT_EQ(
+ test.expected,
+ directive_list->AllowFromSource(
+ ContentSecurityPolicy::DirectiveType::kStyleSrcElem, resource,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting, String(test.nonce)));
// Enforce 'style-src'
directive_list = CreateList(String("default-src ") + test.list,
- kContentSecurityPolicyHeaderTypeEnforce);
+ ContentSecurityPolicyType::kEnforce);
EXPECT_EQ(test.expected,
directive_list->AllowFromSource(
ContentSecurityPolicy::DirectiveType::kScriptSrcElem,
resource, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting,
- String(test.nonce), IntegrityMetadataSet(), kParserInserted));
- EXPECT_EQ(test.expected,
- directive_list->AllowFromSource(
- ContentSecurityPolicy::DirectiveType::kStyleSrcElem, resource,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting,
- String(test.nonce)));
+ ReportingDisposition::kSuppressReporting, String(test.nonce),
+ IntegrityMetadataSet(), kParserInserted));
+ EXPECT_EQ(
+ test.expected,
+ directive_list->AllowFromSource(
+ ContentSecurityPolicy::DirectiveType::kStyleSrcElem, resource,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting, String(test.nonce)));
}
}
@@ -421,25 +420,24 @@ TEST_F(CSPDirectiveListTest, AllowScriptFromSourceWithHash) {
integrity_metadata));
// Report-only 'script-src'
- Member<CSPDirectiveList> directive_list =
- CreateList(String("script-src ") + test.list,
- kContentSecurityPolicyHeaderTypeReport);
+ 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,
- SecurityViolationReportingPolicy::kSuppressReporting,
- String(), integrity_metadata, kParserInserted));
+ ReportingDisposition::kSuppressReporting, String(),
+ integrity_metadata, kParserInserted));
// Enforce 'script-src'
directive_list = CreateList(String("script-src ") + test.list,
- kContentSecurityPolicyHeaderTypeEnforce);
+ ContentSecurityPolicyType::kEnforce);
EXPECT_EQ(test.expected,
directive_list->AllowFromSource(
ContentSecurityPolicy::DirectiveType::kScriptSrcElem,
resource, ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting,
- String(), integrity_metadata, kParserInserted));
+ ReportingDisposition::kSuppressReporting, String(),
+ integrity_metadata, kParserInserted));
}
}
@@ -549,20 +547,18 @@ TEST_F(CSPDirectiveListTest, allowRequestWithoutIntegrity) {
const KURL resource(test.url);
// Report-only
Member<CSPDirectiveList> directive_list =
- CreateList(test.list, kContentSecurityPolicyHeaderTypeReport);
+ CreateList(test.list, ContentSecurityPolicyType::kReport);
EXPECT_EQ(true, directive_list->AllowRequestWithoutIntegrity(
test.context, resource,
ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
// Enforce
- directive_list =
- CreateList(test.list, kContentSecurityPolicyHeaderTypeEnforce);
- EXPECT_EQ(test.expected,
- directive_list->AllowRequestWithoutIntegrity(
- test.context, resource,
- ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ directive_list = CreateList(test.list, ContentSecurityPolicyType::kEnforce);
+ EXPECT_EQ(test.expected, directive_list->AllowRequestWithoutIntegrity(
+ test.context, resource,
+ ResourceRequest::RedirectStatus::kNoRedirect,
+ ReportingDisposition::kSuppressReporting));
}
}
@@ -603,12 +599,12 @@ TEST_F(CSPDirectiveListTest, WorkerSrc) {
SCOPED_TRACE(test.list);
const KURL resource("https://example.test/worker.js");
Member<CSPDirectiveList> directive_list =
- CreateList(test.list, kContentSecurityPolicyHeaderTypeEnforce);
+ CreateList(test.list, ContentSecurityPolicyType::kEnforce);
EXPECT_EQ(test.allowed,
directive_list->AllowFromSource(
ContentSecurityPolicy::DirectiveType::kWorkerSrc, resource,
ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
}
}
@@ -649,12 +645,12 @@ TEST_F(CSPDirectiveListTest, WorkerSrcChildSrcFallback) {
SCOPED_TRACE(test.list);
const KURL resource("https://example.test/worker.js");
Member<CSPDirectiveList> directive_list =
- CreateList(test.list, kContentSecurityPolicyHeaderTypeEnforce);
+ CreateList(test.list, ContentSecurityPolicyType::kEnforce);
EXPECT_EQ(test.allowed,
directive_list->AllowFromSource(
ContentSecurityPolicy::DirectiveType::kWorkerSrc, resource,
ResourceRequest::RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
}
}
@@ -662,7 +658,7 @@ TEST_F(CSPDirectiveListTest, SubsumesBasedOnCSPSourcesOnly) {
CSPDirectiveList* a = CreateList(
"script-src http://*.one.com; img-src https://one.com "
"http://two.com/imgs/",
- kContentSecurityPolicyHeaderTypeEnforce);
+ ContentSecurityPolicyType::kEnforce);
struct TestCase {
const Vector<const char*> policies;
@@ -722,13 +718,12 @@ TEST_F(CSPDirectiveListTest, SubsumesBasedOnCSPSourcesOnly) {
};
CSPDirectiveList* empty_a =
- CreateList("", kContentSecurityPolicyHeaderTypeEnforce);
+ CreateList("", ContentSecurityPolicyType::kEnforce);
for (const auto& test : cases) {
HeapVector<Member<CSPDirectiveList>> list_b;
for (auto* const policy : test.policies) {
- list_b.push_back(
- CreateList(policy, kContentSecurityPolicyHeaderTypeEnforce));
+ list_b.push_back(CreateList(policy, ContentSecurityPolicyType::kEnforce));
}
EXPECT_EQ(test.expected, a->Subsumes(list_b));
@@ -830,12 +825,13 @@ TEST_F(CSPDirectiveListTest, SubsumesIfNoneIsPresent) {
for (const auto& test : cases) {
CSPDirectiveList* a =
- CreateList(test.policy_a, kContentSecurityPolicyHeaderTypeEnforce);
+ CreateList(test.policy_a, ContentSecurityPolicyType::kEnforce);
HeapVector<Member<CSPDirectiveList>> list_b;
- for (auto* const policy_b : test.policies_b)
+ for (auto* const policy_b : test.policies_b) {
list_b.push_back(
- CreateList(policy_b, kContentSecurityPolicyHeaderTypeEnforce));
+ CreateList(policy_b, ContentSecurityPolicyType::kEnforce));
+ }
EXPECT_EQ(test.expected, a->Subsumes(list_b));
}
@@ -912,12 +908,13 @@ TEST_F(CSPDirectiveListTest, SubsumesPluginTypes) {
for (const auto& test : cases) {
CSPDirectiveList* a =
- CreateList(test.policy_a, kContentSecurityPolicyHeaderTypeEnforce);
+ CreateList(test.policy_a, ContentSecurityPolicyType::kEnforce);
HeapVector<Member<CSPDirectiveList>> list_b;
- for (auto* const policy_b : test.policies_b)
+ for (auto* const policy_b : test.policies_b) {
list_b.push_back(
- CreateList(policy_b, kContentSecurityPolicyHeaderTypeEnforce));
+ CreateList(policy_b, ContentSecurityPolicyType::kEnforce));
+ }
EXPECT_EQ(test.expected, a->Subsumes(list_b));
}
@@ -974,8 +971,7 @@ TEST_F(CSPDirectiveListTest, OperativeDirectiveGivenType) {
all_directives << name << " http://" << name << ".com; ";
}
- CSPDirectiveList* empty =
- CreateList("", kContentSecurityPolicyHeaderTypeEnforce);
+ CSPDirectiveList* empty = CreateList("", ContentSecurityPolicyType::kEnforce);
std::string directive_string;
CSPDirectiveList* directive_list;
@@ -993,7 +989,7 @@ TEST_F(CSPDirectiveListTest, OperativeDirectiveGivenType) {
while (!test.fallback_list.IsEmpty()) {
directive_list = CreateList(directive_string.c_str(),
- kContentSecurityPolicyHeaderTypeEnforce);
+ ContentSecurityPolicyType::kEnforce);
CSPDirective* operative_directive =
directive_list->OperativeDirective(test.directive);
@@ -1026,7 +1022,7 @@ TEST_F(CSPDirectiveListTest, OperativeDirectiveGivenType) {
// chain we should ensure that there is no unexpected directive outside of
// the fallback chain that is returned.
directive_list = CreateList(directive_string.c_str(),
- kContentSecurityPolicyHeaderTypeEnforce);
+ ContentSecurityPolicyType::kEnforce);
EXPECT_FALSE(directive_list->OperativeDirective(test.directive));
}
}
@@ -1048,7 +1044,7 @@ TEST_F(CSPDirectiveListTest, GetSourceVector) {
HeapVector<Member<CSPDirectiveList>> policy_vector;
for (auto* const policy : policies) {
policy_vector.push_back(
- CreateList(policy, kContentSecurityPolicyHeaderTypeEnforce));
+ CreateList(policy, ContentSecurityPolicyType::kEnforce));
}
HeapVector<Member<SourceListDirective>> result =
CSPDirectiveList::GetSourceVector(
@@ -1102,15 +1098,14 @@ TEST_F(CSPDirectiveListTest, GetSourceVector) {
HeapVector<Member<CSPDirectiveList>> policy_vector;
for (auto* const policy : policies) {
policy_vector.push_back(
- CreateList(policy, kContentSecurityPolicyHeaderTypeEnforce));
+ CreateList(policy, ContentSecurityPolicyType::kEnforce));
}
// Append current test's policy.
std::stringstream current_directive;
const char* name = ContentSecurityPolicy::GetDirectiveName(test.directive);
current_directive << name << " http://" << name << ".com;";
- policy_vector.push_back(
- CreateList(current_directive.str().c_str(),
- kContentSecurityPolicyHeaderTypeEnforce));
+ policy_vector.push_back(CreateList(current_directive.str().c_str(),
+ ContentSecurityPolicyType::kEnforce));
HeapVector<Member<SourceListDirective>> result =
CSPDirectiveList::GetSourceVector(test.directive, policy_vector);
@@ -1136,9 +1131,8 @@ TEST_F(CSPDirectiveListTest, GetSourceVector) {
EXPECT_EQ(actual_child, test.expected_child_src);
// If another default-src is added that should only impact Fetch Directives
- policy_vector.push_back(
- CreateList("default-src https://default-src.com;",
- kContentSecurityPolicyHeaderTypeEnforce));
+ policy_vector.push_back(CreateList("default-src https://default-src.com;",
+ ContentSecurityPolicyType::kEnforce));
size_t udpated_total =
test.type != kNoDefault ? test.expected_total + 1 : test.expected_total;
EXPECT_EQ(
@@ -1155,9 +1149,8 @@ TEST_F(CSPDirectiveListTest, GetSourceVector) {
// If another child-src is added that should only impact frame-src and
// child-src
- policy_vector.push_back(
- CreateList("child-src http://child-src.com;",
- kContentSecurityPolicyHeaderTypeEnforce));
+ policy_vector.push_back(CreateList("child-src http://child-src.com;",
+ ContentSecurityPolicyType::kEnforce));
udpated_total = test.type == kChildAndDefault ||
test.directive ==
ContentSecurityPolicy::DirectiveType::kChildSrc
@@ -1175,9 +1168,8 @@ TEST_F(CSPDirectiveListTest, GetSourceVector) {
// If we add sandbox, nothing should change since it is currenly not
// considered.
- policy_vector.push_back(
- CreateList("sandbox http://sandbox.com;",
- kContentSecurityPolicyHeaderTypeEnforce));
+ policy_vector.push_back(CreateList("sandbox http://sandbox.com;",
+ ContentSecurityPolicyType::kEnforce));
EXPECT_EQ(
CSPDirectiveList::GetSourceVector(test.directive, policy_vector).size(),
udpated_total);
@@ -1192,67 +1184,67 @@ TEST_F(CSPDirectiveListTest, GetSourceVector) {
TEST_F(CSPDirectiveListTest, ReportEndpointsProperlyParsed) {
struct TestCase {
const char* policy;
- ContentSecurityPolicyHeaderSource header_source;
+ ContentSecurityPolicySource header_source;
Vector<String> expected_endpoints;
bool expected_use_reporting_api;
} cases[] = {
- {"script-src 'self';", kContentSecurityPolicyHeaderSourceHTTP, {}, false},
+ {"script-src 'self';", ContentSecurityPolicySource::kHTTP, {}, false},
{"script-src 'self'; report-uri https://example.com",
- kContentSecurityPolicyHeaderSourceHTTP,
+ ContentSecurityPolicySource::kHTTP,
{"https://example.com"},
false},
{"script-src 'self'; report-uri https://example.com "
"https://example2.com",
- kContentSecurityPolicyHeaderSourceHTTP,
+ ContentSecurityPolicySource::kHTTP,
{"https://example.com", "https://example2.com"},
false},
{"script-src 'self'; report-uri https://example.com",
- kContentSecurityPolicyHeaderSourceMeta,
+ ContentSecurityPolicySource::kMeta,
{},
false},
{"script-src 'self'; report-to group",
- kContentSecurityPolicyHeaderSourceHTTP,
+ ContentSecurityPolicySource::kHTTP,
{"group"},
true},
// report-to supersedes report-uri
{"script-src 'self'; report-to group; report-uri https://example.com",
- kContentSecurityPolicyHeaderSourceHTTP,
+ ContentSecurityPolicySource::kHTTP,
{"group"},
true},
{"script-src 'self'; report-to group",
- kContentSecurityPolicyHeaderSourceMeta,
+ ContentSecurityPolicySource::kMeta,
{"group"},
true},
{"script-src 'self'; report-to group; report-to group2;",
- kContentSecurityPolicyHeaderSourceHTTP,
+ ContentSecurityPolicySource::kHTTP,
{"group"},
true},
{"script-src 'self'; report-to group; report-uri https://example.com; "
"report-to group2",
- kContentSecurityPolicyHeaderSourceHTTP,
+ ContentSecurityPolicySource::kHTTP,
{"group"},
true},
{"script-src 'self'; report-uri https://example.com; report-to group; "
"report-to group2",
- kContentSecurityPolicyHeaderSourceHTTP,
+ ContentSecurityPolicySource::kHTTP,
{"group"},
true},
{"script-src 'self'; report-uri https://example.com "
"https://example2.com; report-to group",
- kContentSecurityPolicyHeaderSourceHTTP,
+ ContentSecurityPolicySource::kHTTP,
{"group"},
true},
{"script-src 'self'; report-uri https://example.com; report-to group; "
"report-uri https://example.com",
- kContentSecurityPolicyHeaderSourceHTTP,
+ ContentSecurityPolicySource::kHTTP,
{"group"},
true},
};
for (const auto& test : cases) {
// Test both enforce and report, there should not be a difference
- for (const auto& header_type : {kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderTypeReport}) {
+ for (const auto& header_type : {ContentSecurityPolicyType::kEnforce,
+ ContentSecurityPolicyType::kReport}) {
Member<CSPDirectiveList> directive_list =
CreateList(test.policy, header_type, test.header_source);
@@ -1271,4 +1263,110 @@ TEST_F(CSPDirectiveListTest, ReportEndpointsProperlyParsed) {
}
}
+TEST_F(CSPDirectiveListTest, ReasonableObjectRestriction) {
+ struct TestCase {
+ const char* list;
+ bool expected;
+ } cases[] = {// Insufficient restriction!
+ {"img-src *", false},
+ {"object-src *", false},
+ {"object-src https://very.safe.test/", false},
+ {"object-src https:", false},
+ {"script-src *", false},
+ {"script-src https://very.safe.test/", false},
+ {"script-src https:", false},
+ {"script-src 'none'; object-src *", false},
+ {"script-src 'none'; object-src https://very.safe.test/", false},
+ {"script-src 'none'; object-src https:", false},
+
+ // Sufficient restrictions!
+ {"default-src 'none'", true},
+ {"object-src 'none'", true},
+ {"object-src 'none'; script-src 'unsafe-inline'", true},
+ {"object-src 'none'; script-src *", true}};
+
+ for (const auto& test : cases) {
+ SCOPED_TRACE(testing::Message() << "List: `" << test.list << "`");
+ Member<CSPDirectiveList> directive_list =
+ CreateList(test.list, ContentSecurityPolicyType::kReport);
+ EXPECT_EQ(test.expected, directive_list->IsObjectRestrictionReasonable());
+ directive_list = CreateList(test.list, ContentSecurityPolicyType::kEnforce);
+ EXPECT_EQ(test.expected, directive_list->IsObjectRestrictionReasonable());
+ }
+}
+
+TEST_F(CSPDirectiveListTest, ReasonableBaseRestriction) {
+ struct TestCase {
+ const char* list;
+ bool expected;
+ } cases[] = {// Insufficient restriction!
+ {"default-src 'none'", false},
+ {"base-uri https://very.safe.test/", false},
+ {"base-uri *", false},
+ {"base-uri https:", false},
+
+ // Sufficient restrictions!
+ {"base-uri 'none'", true},
+ {"base-uri 'self'", true}};
+
+ for (const auto& test : cases) {
+ SCOPED_TRACE(testing::Message() << "List: `" << test.list << "`");
+ Member<CSPDirectiveList> directive_list =
+ CreateList(test.list, ContentSecurityPolicyType::kReport);
+ EXPECT_EQ(test.expected, directive_list->IsBaseRestrictionReasonable());
+ directive_list = CreateList(test.list, ContentSecurityPolicyType::kEnforce);
+ EXPECT_EQ(test.expected, directive_list->IsBaseRestrictionReasonable());
+ }
+}
+
+TEST_F(CSPDirectiveListTest, ReasonableScriptRestriction) {
+ struct TestCase {
+ const char* list;
+ bool expected;
+ } cases[] = {
+ // Insufficient restriction!
+ {"img-src *", false},
+ {"script-src *", false},
+ {"script-src https://very.safe.test/", false},
+ {"script-src https:", false},
+ {"default-src 'none'; script-src *", false},
+ {"default-src 'none'; script-src https://very.safe.test/", false},
+ {"default-src 'none'; script-src https:", false},
+
+ // Sufficient restrictions!
+ {"default-src 'none'", true},
+ {"script-src 'none'", true},
+ {"script-src 'nonce-abc'", true},
+ {"script-src 'sha256-abc'", true},
+ {"script-src 'nonce-abc' 'unsafe-inline'", true},
+ {"script-src 'sha256-abc' 'unsafe-inline'", true},
+ {"script-src 'nonce-abc' 'strict-dynamic'", true},
+ {"script-src 'sha256-abc' 'strict-dynamic'", true},
+ {"script-src 'nonce-abc' 'unsafe-inline' 'strict-dynamic'", true},
+ {"script-src 'sha256-abc' 'unsafe-inline' 'strict-dynamic'", true},
+ {"script-src 'nonce-abc' 'unsafe-inline' 'unsafe-eval' 'unsafe-hashes'",
+ true},
+ {"script-src 'sha256-abc' 'unsafe-inline' 'unsafe-eval' 'unsafe-hashes'",
+ true},
+ {"script-src 'nonce-abc' 'strict-dynamic' 'unsafe-eval' 'unsafe-hashes'",
+ true},
+ {"script-src 'sha256-abc' 'strict-dynamic' 'unsafe-eval' 'unsafe-hashes'",
+ true},
+ {"script-src 'nonce-abc' 'unsafe-inline' 'strict-dynamic' 'unsafe-eval' "
+ "'unsafe-hashes'",
+ true},
+ {"script-src 'sha256-abc' 'unsafe-inline' 'strict-dynamic' 'unsafe-eval' "
+ "'unsafe-hashes'",
+ true}};
+
+ for (const auto& test : cases) {
+ SCOPED_TRACE(testing::Message() << "List: `" << test.list << "`");
+ Member<CSPDirectiveList> directive_list =
+ CreateList(test.list, ContentSecurityPolicyType::kReport);
+ EXPECT_EQ(test.expected, directive_list->IsScriptRestrictionReasonable());
+ directive_list = CreateList(test.list, ContentSecurityPolicyType::kEnforce);
+ EXPECT_EQ(test.expected, directive_list->IsScriptRestrictionReasonable());
+ }
+}
+
} // namespace blink
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 c076dcf9d86..691cc1d7f4f 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
@@ -290,25 +290,20 @@ bool CSPSource::FirstSubsumesSecond(
return true;
}
-WebContentSecurityPolicySourceExpression
-CSPSource::ExposeForNavigationalChecks() const {
- WebContentSecurityPolicySourceExpression source_expression;
- source_expression.scheme = scheme_;
- source_expression.host = host_;
- source_expression.is_host_wildcard =
- static_cast<WebWildcardDisposition>(host_wildcard_);
- source_expression.port = port_;
- source_expression.is_port_wildcard =
- static_cast<WebWildcardDisposition>(port_wildcard_);
- source_expression.path = path_;
- return source_expression;
+network::mojom::blink::CSPSourcePtr CSPSource::ExposeForNavigationalChecks()
+ const {
+ return network::mojom::blink::CSPSource::New(
+ scheme_ ? scheme_ : "", // scheme
+ host_ ? host_ : "", // host
+ port_ == 0 ? -1 /* url::PORT_UNSPECIFIED */ : port_, // port
+ path_ ? path_ : "", // path
+ host_wildcard_ == kHasWildcard, // is_host_wildcard
+ port_wildcard_ == kHasWildcard // is_port_wildcard
+ );
}
-void CSPSource::Trace(blink::Visitor* visitor) {
+void CSPSource::Trace(Visitor* visitor) {
visitor->Trace(policy_);
}
-STATIC_ASSERT_ENUM(kWebWildcardDispositionNoWildcard, CSPSource::kNoWildcard);
-STATIC_ASSERT_ENUM(kWebWildcardDispositionHasWildcard, CSPSource::kHasWildcard);
-
} // namespace blink
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 5c3bd9e9ffc..c48fa3e6e03 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
@@ -65,9 +65,9 @@ class CORE_EXPORT CSPSource final : public GarbageCollected<CSPSource> {
static bool FirstSubsumesSecond(const HeapVector<Member<CSPSource>>&,
const HeapVector<Member<CSPSource>>&);
- WebContentSecurityPolicySourceExpression ExposeForNavigationalChecks() const;
+ network::mojom::blink::CSPSourcePtr ExposeForNavigationalChecks() const;
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
FRIEND_TEST_ALL_PREFIXES(CSPSourceTest, IsSimilar);
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/csp_violation_report_body.h b/chromium/third_party/blink/renderer/core/frame/csp/csp_violation_report_body.h
index 08803a85c41..b0b2393b5c5 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/csp_violation_report_body.h
+++ b/chromium/third_party/blink/renderer/core/frame/csp/csp_violation_report_body.h
@@ -7,7 +7,7 @@
#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
-#include "third_party/blink/renderer/core/events/security_policy_violation_event_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_security_policy_violation_event_init.h"
#include "third_party/blink/renderer/core/frame/location_report_body.h"
namespace blink {
@@ -32,13 +32,13 @@ class CORE_EXPORT CSPViolationReportBody : public LocationReportBody {
~CSPViolationReportBody() override = default;
- String documentURL() const { return document_url_; }
- String referrer() const { return referrer_; }
- String blockedURL() const { return blocked_url_; }
- String effectiveDirective() const { return effective_directive_; }
- String originalPolicy() const { return original_policy_; }
- String sample() const { return sample_; }
- String disposition() const { return disposition_; }
+ const String& documentURL() const { return document_url_; }
+ const String& referrer() const { return referrer_; }
+ const String& blockedURL() const { return blocked_url_; }
+ const String& effectiveDirective() const { return effective_directive_; }
+ const String& originalPolicy() const { return original_policy_; }
+ const String& sample() const { return sample_; }
+ const String& disposition() const { return disposition_; }
uint16_t statusCode() const { return status_code_; }
void BuildJSONValue(V8ObjectBuilder& builder) const override;
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 85372467195..151bb266e1b 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
@@ -4,12 +4,15 @@
#include "third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.h"
+#include "third_party/blink/public/common/security_context/insecure_request_policy.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.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/events/security_policy_violation_event.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/execution_context/security_context.h"
#include "third_party/blink/renderer/core/frame/csp/csp_violation_report_body.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/report.h"
@@ -29,7 +32,7 @@ ExecutionContextCSPDelegate::ExecutionContextCSPDelegate(
ExecutionContext& execution_context)
: execution_context_(&execution_context) {}
-void ExecutionContextCSPDelegate::Trace(blink::Visitor* visitor) {
+void ExecutionContextCSPDelegate::Trace(Visitor* visitor) {
visitor->Trace(execution_context_);
ContentSecurityPolicyDelegate::Trace(visitor);
}
@@ -38,6 +41,10 @@ const SecurityOrigin* ExecutionContextCSPDelegate::GetSecurityOrigin() {
return execution_context_->GetSecurityOrigin();
}
+SecureContextMode ExecutionContextCSPDelegate::GetSecureContextMode() {
+ return GetSecurityContext().GetSecureContextMode();
+}
+
const KURL& ExecutionContextCSPDelegate::Url() const {
return execution_context_->Url();
}
@@ -60,7 +67,7 @@ void ExecutionContextCSPDelegate::SetSandboxFlags(SandboxFlags mask) {
// already been set on the security context. Meta tags can't set them
// and we should have already constructed the document with the correct
// sandbox flags from CSP already.
- WebSandboxFlags flags = GetSecurityContext().GetSandboxFlags();
+ mojom::blink::WebSandboxFlags flags = GetSecurityContext().GetSandboxFlags();
CHECK_EQ(flags | mask, flags);
}
@@ -69,7 +76,7 @@ void ExecutionContextCSPDelegate::SetRequireTrustedTypes() {
}
void ExecutionContextCSPDelegate::AddInsecureRequestPolicy(
- WebInsecureRequestPolicy policy) {
+ mojom::blink::InsecureRequestPolicy policy) {
SecurityContext& security_context = GetSecurityContext();
Document* document = GetDocument();
@@ -82,7 +89,9 @@ void ExecutionContextCSPDelegate::AddInsecureRequestPolicy(
document->DidEnforceInsecureRequestPolicy();
// Upgrade Insecure Requests: Update the set of insecure URLs to upgrade.
- if (policy & kUpgradeInsecureRequests) {
+ if ((policy &
+ mojom::blink::InsecureRequestPolicy::kUpgradeInsecureRequests) !=
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone) {
// Spec: Enforcing part of:
// https://w3c.github.io/webappsec-upgrade-insecure-requests/#delivery
// Step 3. Let tuple be a tuple of the protected resource’s URL's host and
@@ -171,8 +180,9 @@ void ExecutionContextCSPDelegate::PostViolationReport(
auto* body = MakeGarbageCollected<CSPViolationReportBody>(violation_data);
Report* observed_report = MakeGarbageCollected<Report>(
ReportType::kCSPViolation, Url().GetString(), body);
- ReportingContext::From(document)->QueueReport(
- observed_report, use_reporting_api ? report_endpoints : Vector<String>());
+ ReportingContext::From(document->ToExecutionContext())
+ ->QueueReport(observed_report,
+ use_reporting_api ? report_endpoints : Vector<String>());
if (use_reporting_api)
return;
@@ -218,10 +228,17 @@ void ExecutionContextCSPDelegate::ReportBlockedScriptExecutionToInspector(
}
void ExecutionContextCSPDelegate::DidAddContentSecurityPolicies(
- const blink::WebVector<WebContentSecurityPolicy>& policies) {
+ WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr> policies) {
Document* document = GetDocument();
- if (document && document->GetFrame())
- document->GetFrame()->Client()->DidAddContentSecurityPolicies(policies);
+ if (!document)
+ return;
+
+ LocalFrame* frame = document->GetFrame();
+ if (!frame)
+ return;
+
+ frame->GetLocalFrameHostRemote().DidAddContentSecurityPolicies(
+ std::move(policies));
}
SecurityContext& ExecutionContextCSPDelegate::GetSecurityContext() {
@@ -229,7 +246,8 @@ SecurityContext& ExecutionContextCSPDelegate::GetSecurityContext() {
}
Document* ExecutionContextCSPDelegate::GetDocument() {
- return DynamicTo<Document>(execution_context_.Get());
+ auto* window = DynamicTo<LocalDOMWindow>(execution_context_.Get());
+ return window ? window->document() : nullptr;
}
void ExecutionContextCSPDelegate::DispatchViolationEventInternal(
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 1f0e419ad53..426ee795c37 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
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_CSP_EXECUTION_CONTEXT_CSP_DELEGATE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_CSP_EXECUTION_CONTEXT_CSP_DELEGATE_H_
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
namespace blink {
@@ -21,14 +22,15 @@ class ExecutionContextCSPDelegate final
public:
explicit ExecutionContextCSPDelegate(ExecutionContext&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// ContentSecurityPolicyDelegate overrides:
const SecurityOrigin* GetSecurityOrigin() override;
+ SecureContextMode GetSecureContextMode() override;
const KURL& Url() const override;
void SetSandboxFlags(SandboxFlags) override;
void SetRequireTrustedTypes() override;
- void AddInsecureRequestPolicy(WebInsecureRequestPolicy) override;
+ void AddInsecureRequestPolicy(mojom::blink::InsecureRequestPolicy) override;
std::unique_ptr<SourceLocation> GetSourceLocation() override;
base::Optional<uint16_t> GetStatusCode() override;
String GetDocumentReferrer() override;
@@ -45,7 +47,7 @@ class ExecutionContextCSPDelegate final
void ReportBlockedScriptExecutionToInspector(
const String& directive_text) override;
void DidAddContentSecurityPolicies(
- const blink::WebVector<WebContentSecurityPolicy>&) override;
+ WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr>) override;
private:
SecurityContext& GetSecurityContext();
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 00317ab9dee..bce1d06fba9 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
@@ -4,53 +4,54 @@
#include "third_party/blink/renderer/core/frame/csp/navigation_initiator_impl.h"
+#include "services/network/public/mojom/content_security_policy.mojom-blink.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/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
NavigationInitiatorImpl::NavigationInitiatorImpl(Document& document)
- : document_(document) {}
+ : navigation_initiator_receivers_(document.GetExecutionContext()),
+ document_(document) {
+ DCHECK(document.GetExecutionContext());
+}
void NavigationInitiatorImpl::Trace(Visitor* visitor) {
visitor->Trace(document_);
+ visitor->Trace(navigation_initiator_receivers_);
}
void NavigationInitiatorImpl::SendViolationReport(
- mojom::blink::CSPViolationParamsPtr violation_params) {
- std::unique_ptr<SourceLocation> source_location =
- std::make_unique<SourceLocation>(
- violation_params->source_location->url,
- violation_params->source_location->line_number,
- violation_params->source_location->column_number, nullptr);
-
- Vector<String> report_endpoints;
- for (const String& end_point : violation_params->report_endpoints)
- report_endpoints.push_back(end_point);
-
- document_->AddConsoleMessage(ConsoleMessage::Create(
+ network::mojom::blink::CSPViolationPtr violation) {
+ auto source_location = std::make_unique<SourceLocation>(
+ violation->source_location->url, violation->source_location->line,
+ violation->source_location->column, nullptr);
+
+ document_->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kError, violation_params->console_message));
+ mojom::ConsoleMessageLevel::kError, violation->console_message));
+
document_->GetContentSecurityPolicy()->ReportViolation(
- violation_params->directive,
- ContentSecurityPolicy::GetDirectiveType(
- violation_params->effective_directive),
- violation_params->console_message, KURL(violation_params->blocked_url),
- report_endpoints, violation_params->use_reporting_api,
- violation_params->header,
- static_cast<ContentSecurityPolicyHeaderType>(
- violation_params->disposition),
+ violation->directive,
+ ContentSecurityPolicy::GetDirectiveType(violation->effective_directive),
+ violation->console_message, KURL(violation->blocked_url),
+ violation->report_endpoints, violation->use_reporting_api,
+ violation->header, violation->type,
ContentSecurityPolicy::ViolationType::kURLViolation,
std::move(source_location), nullptr /* LocalFrame */,
- violation_params->after_redirect ? RedirectStatus::kFollowedRedirect
- : RedirectStatus::kNoRedirect,
+ violation->after_redirect ? RedirectStatus::kFollowedRedirect
+ : RedirectStatus::kNoRedirect,
nullptr /* Element */);
}
-void NavigationInitiatorImpl::Dispose() {
- navigation_initiator_receivers_.Clear();
+void NavigationInitiatorImpl::BindReceiver(
+ mojo::PendingReceiver<mojom::blink::NavigationInitiator> receiver) {
+ navigation_initiator_receivers_.Add(
+ this, std::move(receiver),
+ document_->GetTaskRunner(TaskType::kNetworking));
}
} // namespace blink
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 836878e917b..7a9e2f7c8f5 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
@@ -6,8 +6,11 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_CSP_NAVIGATION_INITIATOR_IMPL_H_
#include "mojo/public/cpp/bindings/receiver_set.h"
+#include "services/network/public/mojom/content_security_policy.mojom-forward.h"
#include "third_party/blink/public/mojom/frame/navigation_initiator.mojom-blink.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
namespace blink {
@@ -16,28 +19,23 @@ class Document;
class NavigationInitiatorImpl
: public GarbageCollected<NavigationInitiatorImpl>,
public mojom::blink::NavigationInitiator {
- USING_PRE_FINALIZER(NavigationInitiatorImpl, Dispose);
-
public:
explicit NavigationInitiatorImpl(Document& document);
void Trace(Visitor* visitor);
// mojom::blink::NavigationInitiator override:
void SendViolationReport(
- mojom::blink::CSPViolationParamsPtr violation_params) override;
+ network::mojom::blink::CSPViolationPtr violation_params) override;
void BindReceiver(
- mojo::PendingReceiver<mojom::blink::NavigationInitiator> receiver) {
- navigation_initiator_receivers_.Add(this, std::move(receiver));
- }
+ mojo::PendingReceiver<mojom::blink::NavigationInitiator> receiver);
private:
- void Dispose();
-
// A list of all the navigation_initiator receivers owned by the owner
// document. Used to report CSP violations that result from CSP blocking
// navigation requests that were initiated by the owner document.
- mojo::ReceiverSet<mojom::blink::NavigationInitiator>
+ HeapMojoReceiverSet<mojom::blink::NavigationInitiator,
+ HeapMojoWrapperMode::kWithoutContextObserver>
navigation_initiator_receivers_;
Member<Document> document_;
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
new file mode 100644
index 00000000000..bf7e58714fa
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/csp/require_trusted_types_for_directive.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 "require_trusted_types_for_directive.h"
+
+namespace blink {
+
+RequireTrustedTypesForDirective::RequireTrustedTypesForDirective(
+ const String& name,
+ const String& value,
+ ContentSecurityPolicy* policy)
+ : CSPDirective(name, value, policy),
+ require_trusted_types_for_script_(false) {
+ Vector<String> list;
+ value.SimplifyWhiteSpace().Split(' ', false, list);
+
+ for (const String& v : list) {
+ // The only value in the sink group is 'script'.
+ // https://w3c.github.io/webappsec-trusted-types/dist/spec/#trusted-types-sink-group
+ if (v == "'script'") {
+ require_trusted_types_for_script_ = true;
+ break;
+ }
+ }
+}
+
+bool RequireTrustedTypesForDirective::require() const {
+ return require_trusted_types_for_script_;
+}
+
+void RequireTrustedTypesForDirective::Trace(Visitor* visitor) {
+ CSPDirective::Trace(visitor);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..933ee499bf6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/csp/require_trusted_types_for_directive.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_FRAME_CSP_REQUIRE_TRUSTED_TYPES_FOR_DIRECTIVE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_CSP_REQUIRE_TRUSTED_TYPES_FOR_DIRECTIVE_H_
+
+#include "third_party/blink/renderer/core/frame/csp/csp_directive.h"
+
+namespace blink {
+
+class ContentSecurityPolicy;
+
+class CORE_EXPORT RequireTrustedTypesForDirective final : public CSPDirective {
+ public:
+ RequireTrustedTypesForDirective(const String& name,
+ const String& value,
+ ContentSecurityPolicy*);
+ void Trace(Visitor*) override;
+ bool require() const;
+
+ private:
+ bool require_trusted_types_for_script_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_CSP_REQUIRE_TRUSTED_TYPES_FOR_DIRECTIVE_H_
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/require_trusted_types_for_directive_test.cc b/chromium/third_party/blink/renderer/core/frame/csp/require_trusted_types_for_directive_test.cc
new file mode 100644
index 00000000000..c2a48f4a3cb
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/csp/require_trusted_types_for_directive_test.cc
@@ -0,0 +1,31 @@
+// 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/csp/require_trusted_types_for_directive.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace blink {
+
+TEST(RequireTrustedTypesForDirectiveTest, TestSinks) {
+ struct {
+ const char* directive;
+ const bool result;
+ } test_cases[] = {{"'script'", true},
+ {"*", false},
+ {"", false},
+ {"''", false},
+ {"script", false},
+ {"'script' 'css'", true},
+ {"'script' 'script'", true}};
+
+ for (const auto& test_case : test_cases) {
+ RequireTrustedTypesForDirective directive("require-trusted-types-for",
+ test_case.directive, nullptr);
+ SCOPED_TRACE(testing::Message() << " require-trusted-types-for "
+ << test_case.directive << ";");
+ EXPECT_EQ(directive.require(), test_case.result);
+ }
+}
+} // namespace blink
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 273ee8147df..f1b00288541 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
@@ -124,6 +124,12 @@ bool SourceListDirective::IsNone() const {
!allow_dynamic_ && !nonces_.size() && !hashes_.size();
}
+bool SourceListDirective::IsSelf() const {
+ return allow_self_ && !list_.size() && !allow_star_ && !allow_inline_ &&
+ !allow_unsafe_hashes_ && !allow_eval_ && !allow_wasm_eval_ &&
+ !allow_dynamic_ && !nonces_.size() && !hashes_.size();
+}
+
uint8_t SourceListDirective::HashAlgorithmsUsed() const {
return hash_algorithms_used_;
}
@@ -133,6 +139,10 @@ bool SourceListDirective::IsHashOrNoncePresent() const {
hash_algorithms_used_ != kContentSecurityPolicyHashAlgorithmNone;
}
+bool SourceListDirective::AllowsURLBasedMatching() const {
+ return !allow_dynamic_ && (list_.size() || allow_star_ || allow_self_);
+}
+
// source-list = *WSP [ source *( 1*WSP source ) *WSP ]
// / *WSP "'none'" *WSP
//
@@ -786,17 +796,14 @@ bool SourceListDirective::Subsumes(
return CSPSource::FirstSubsumesSecond(normalized_a, normalized_b);
}
-WebContentSecurityPolicySourceList
+network::mojom::blink::CSPSourceListPtr
SourceListDirective::ExposeForNavigationalChecks() const {
- WebContentSecurityPolicySourceList source_list;
- source_list.allow_self = allow_self_;
- source_list.allow_star = allow_star_;
- source_list.allow_redirects = allow_redirects_;
- WebVector<WebContentSecurityPolicySourceExpression> list(list_.size());
- for (wtf_size_t i = 0; i < list_.size(); ++i)
- list[i] = list_[i]->ExposeForNavigationalChecks();
- source_list.sources.Swap(list);
- return source_list;
+ WTF::Vector<network::mojom::blink::CSPSourcePtr> sources;
+ for (const auto& source : list_)
+ sources.push_back(source->ExposeForNavigationalChecks());
+
+ return network::mojom::blink::CSPSourceList::New(
+ std::move(sources), allow_self_, allow_star_, allow_redirects_);
}
bool SourceListDirective::SubsumesNoncesAndHashes(
@@ -911,7 +918,7 @@ HeapVector<Member<CSPSource>> SourceListDirective::GetIntersectCSPSources(
return normalized;
}
-void SourceListDirective::Trace(blink::Visitor* visitor) {
+void SourceListDirective::Trace(Visitor* visitor) {
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 28429354a4a..08d3092a3c9 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
@@ -6,7 +6,6 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_CSP_SOURCE_LIST_DIRECTIVE_H_
#include "base/macros.h"
-#include "third_party/blink/public/platform/web_content_security_policy.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/frame/csp/csp_directive.h"
#include "third_party/blink/renderer/core/frame/csp/csp_source.h"
@@ -26,7 +25,7 @@ class CORE_EXPORT SourceListDirective final : public CSPDirective {
SourceListDirective(const String& name,
const String& value,
ContentSecurityPolicy*);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void Parse(const UChar* begin, const UChar* end);
@@ -46,18 +45,20 @@ class CORE_EXPORT SourceListDirective final : public CSPDirective {
bool AllowUnsafeHashes() const;
bool AllowReportSample() const;
bool IsNone() const;
+ bool IsSelf() const;
bool IsHashOrNoncePresent() const;
uint8_t HashAlgorithmsUsed() const;
bool AllowAllInline() const;
+ bool AllowsURLBasedMatching() const;
- // The algorothm is described more extensively here:
+ // The algorithm is described more extensively here:
// https://w3c.github.io/webappsec-csp/embedded/#subsume-source-list
bool Subsumes(const HeapVector<Member<SourceListDirective>>&) const;
// Export a subset of the source list that affect navigation.
// It contains every source-expressions, '*', 'none' and 'self'.
// It doesn't contain 'unsafe-inline' or 'unsafe-eval' for instance.
- WebContentSecurityPolicySourceList ExposeForNavigationalChecks() const;
+ network::mojom::blink::CSPSourceListPtr ExposeForNavigationalChecks() const;
String DirectiveName() const { return directive_name_; }
private:
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/source_list_directive_test.cc b/chromium/third_party/blink/renderer/core/frame/csp/source_list_directive_test.cc
index 80dd85238b9..55cca68f3c7 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/source_list_directive_test.cc
+++ b/chromium/third_party/blink/renderer/core/frame/csp/source_list_directive_test.cc
@@ -5,10 +5,9 @@
#include "third_party/blink/renderer/core/frame/csp/source_list_directive.h"
#include "testing/gtest/include/gtest/gtest.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/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/csp/csp_source.h"
+#include "third_party/blink/renderer/core/testing/null_execution_context.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -33,23 +32,19 @@ class SourceListDirectiveTest : public testing::Test {
void SetUp() override {
KURL secure_url("https://example.test/image.png");
- scoped_refptr<SecurityOrigin> secure_origin(
+ context = MakeGarbageCollected<NullExecutionContext>();
+ context->GetSecurityContext().SetSecurityOrigin(
SecurityOrigin::Create(secure_url));
- DocumentInit init =
- DocumentInit::Create().WithOriginToCommit(secure_origin);
- document = MakeGarbageCollected<Document>(init);
- csp->BindToDelegate(document->GetContentSecurityPolicyDelegate());
+ csp->BindToDelegate(context->GetContentSecurityPolicyDelegate());
}
ContentSecurityPolicy* SetUpWithOrigin(const String& origin) {
KURL secure_url(origin);
- scoped_refptr<SecurityOrigin> secure_origin(
+ auto* context = MakeGarbageCollected<NullExecutionContext>();
+ context->GetSecurityContext().SetSecurityOrigin(
SecurityOrigin::Create(secure_url));
- DocumentInit init =
- DocumentInit::Create().WithOriginToCommit(secure_origin);
- auto* document = MakeGarbageCollected<Document>(init);
auto* csp = MakeGarbageCollected<ContentSecurityPolicy>();
- csp->BindToDelegate(document->GetContentSecurityPolicyDelegate());
+ csp->BindToDelegate(context->GetContentSecurityPolicyDelegate());
return csp;
}
@@ -60,7 +55,7 @@ class SourceListDirectiveTest : public testing::Test {
}
Persistent<ContentSecurityPolicy> csp;
- Persistent<Document> document;
+ Persistent<ExecutionContext> context;
};
TEST_F(SourceListDirectiveTest, BasicMatchingNone) {
@@ -827,14 +822,104 @@ TEST_F(SourceListDirectiveTest, IsNone) {
};
for (const auto& test : cases) {
+ SCOPED_TRACE(test.sources);
SourceListDirective script_src("script-src", test.sources, csp.Get());
EXPECT_EQ(script_src.IsNone(), test.expected);
- SourceListDirective style_src("form-action", test.sources, csp.Get());
- EXPECT_EQ(style_src.IsNone(), test.expected);
+ SourceListDirective form_action("form-action", test.sources, csp.Get());
+ EXPECT_EQ(form_action.IsNone(), test.expected);
- SourceListDirective img_src("frame-src", test.sources, csp.Get());
- EXPECT_EQ(style_src.IsNone(), test.expected);
+ SourceListDirective frame_src("frame-src", test.sources, csp.Get());
+ EXPECT_EQ(frame_src.IsNone(), test.expected);
+ }
+}
+
+TEST_F(SourceListDirectiveTest, IsSelf) {
+ struct TestCase {
+ String sources;
+ bool expected;
+ } cases[] = {
+ // Source list is 'self'.
+ {"'self'", true},
+ {"'self' 'none'", true},
+
+ // Source list is not 'self'.
+ {"'none'", false},
+ {"http://example1.com/foo/", false},
+ {"'sha512-321cba'", false},
+ {"'nonce-yay'", false},
+ {"'strict-dynamic'", false},
+ {"'sha512-321cba' http://example1.com/foo/", false},
+ {"http://example1.com/foo/ 'sha512-321cba'", false},
+ {"http://example1.com/foo/ 'nonce-yay'", false},
+ {"'self' 'sha512-321cba' http://example1.com/foo/", false},
+ {"'self' http://example1.com/foo/ 'sha512-321cba'", false},
+ {"'self' http://example1.com/foo/ 'nonce-yay'", false},
+ {"'sha512-321cba' 'nonce-yay'", false},
+ {"http://example1.com/foo/ 'sha512-321cba' 'nonce-yay'", false},
+ {"http://example1.com/foo/ 'sha512-321cba' 'nonce-yay'", false},
+ {" 'sha512-321cba' 'nonce-yay' 'strict-dynamic'", false},
+ };
+
+ for (const auto& test : cases) {
+ SCOPED_TRACE(test.sources);
+ SourceListDirective script_src("script-src", test.sources, csp.Get());
+ EXPECT_EQ(script_src.IsSelf(), test.expected);
+
+ SourceListDirective form_action("form-action", test.sources, csp.Get());
+ EXPECT_EQ(form_action.IsSelf(), test.expected);
+
+ SourceListDirective frame_src("frame-src", test.sources, csp.Get());
+ EXPECT_EQ(frame_src.IsSelf(), test.expected);
+ }
+}
+
+TEST_F(SourceListDirectiveTest, AllowsURLBasedMatching) {
+ struct TestCase {
+ String sources;
+ bool expected;
+ } cases[] = {
+ // No URL-based matching.
+ {"'none'", false},
+ {"'sha256-abcdefg'", false},
+ {"'nonce-abc'", false},
+ {"'nonce-abce' 'sha256-abcdefg'", false},
+
+ // Strict-dynamic.
+ {"'sha256-abcdefg' 'strict-dynamic'", false},
+ {"'nonce-abce' 'strict-dynamic'", false},
+ {"'nonce-abce' 'sha256-abcdefg' 'strict-dynamic'", false},
+ {"'sha256-abcdefg' 'strict-dynamic' https:", false},
+ {"'nonce-abce' 'strict-dynamic' http://example.test", false},
+ {"'nonce-abce' 'sha256-abcdefg' 'strict-dynamic' *://example.test",
+ false},
+
+ // URL-based.
+ {"*", true},
+ {"'self'", true},
+ {"http:", true},
+ {"http: https:", true},
+ {"http: 'none'", true},
+ {"http: https: 'none'", true},
+ {"'sha256-abcdefg' https://example.test", true},
+ {"'nonce-abc' https://example.test", true},
+ {"'nonce-abce' 'sha256-abcdefg' https://example.test", true},
+ {"'sha256-abcdefg' https://example.test 'none'", true},
+ {"'nonce-abc' https://example.test 'none'", true},
+ {"'nonce-abce' 'sha256-abcdefg' https://example.test 'none'", true},
+
+ };
+
+ for (const auto& test : cases) {
+ SCOPED_TRACE(test.sources);
+ SourceListDirective script_src("script-src", test.sources, csp.Get());
+ EXPECT_EQ(script_src.AllowsURLBasedMatching(), test.expected);
+
+ SourceListDirective form_action("form-action", test.sources, csp.Get());
+ EXPECT_EQ(form_action.AllowsURLBasedMatching(), test.expected);
+
+ SourceListDirective frame_src("frame-src", test.sources, csp.Get());
+ EXPECT_EQ(frame_src.AllowsURLBasedMatching(), test.expected);
}
}
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 ce7bab53f4d..049db709c2c 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
@@ -14,46 +14,65 @@ namespace blink {
StringListDirective::StringListDirective(const String& name,
const String& value,
ContentSecurityPolicy* policy)
- : CSPDirective(name, value, policy), allow_any_(false) {
+ : CSPDirective(name, value, policy),
+ allow_any_(false),
+ allow_duplicates_(false) {
// Turn whitespace-y characters into ' ' and then split on ' ' into list_.
value.SimplifyWhiteSpace().Split(' ', false, list_);
- // A single entry "*" means all values are allowed.
- if (list_.size() == 1 && list_.at(0) == "*") {
- allow_any_ = true;
- list_.clear();
- }
+ auto drop_fn = [this](const String& value) -> bool {
+ return !AllowOrProcessValue(value);
+ };
// There appears to be no wtf::Vector equivalent to STLs erase(from, to)
// method, so we can't do the canonical .erase(remove_if(..), end) and have
// to emulate this:
- list_.Shrink(
- std::remove_if(list_.begin(), list_.end(), &IsInvalidStringValue) -
- list_.begin());
+ list_.Shrink(std::remove_if(list_.begin(), list_.end(), drop_fn) -
+ list_.begin());
+}
+
+bool StringListDirective::IsPolicyName(const String& name) {
+ // This implements tt-policy-name from
+ // https://w3c.github.io/webappsec-trusted-types/dist/spec/#trusted-types-csp-directive/
+ return name.Find(&IsNotPolicyNameChar) == kNotFound;
}
-// TODO(vogelheim): If StringListDirective will be used in contexts other than
-// TrustedTypes, this needs to be made configurable or
-// over-rideable.
-bool StringListDirective::IsInvalidStringValue(const String& str) {
- // TODO(vogelheim): Update this as the Trusted Type spec evolves.
+bool StringListDirective::IsNotPolicyNameChar(UChar c) {
+ // This implements the negation of one char of tt-policy-name from
+ // https://w3c.github.io/webappsec-trusted-types/dist/spec/#trusted-types-csp-directive/
+ bool is_name_char = (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z') || c == '-' || c == '#' ||
+ c == '=' || c == '_' || c == '/' || c == '@' ||
+ c == '.' || c == '%';
+ return !is_name_char;
+}
- // Currently, Trusted Type demands that quoted strings are treated as
- // placeholders (and thus cannot be policy names). We'll just disallow any
- // string with quote marks in them.
- return str.Contains('\'') || str.Contains('"');
+bool StringListDirective::AllowOrProcessValue(const String& src) {
+ DCHECK_EQ(src, src.StripWhiteSpace());
+ // Handle keywords and special tokens first:
+ if (src == "'allow-duplicates'") {
+ allow_duplicates_ = true;
+ return false;
+ }
+ if (src == "*") {
+ allow_any_ = true;
+ return false;
+ }
+ return IsPolicyName(src);
}
bool StringListDirective::Allows(const String& string_piece,
bool is_duplicate) {
- if (string_piece == "default" && is_duplicate)
+ if (is_duplicate && !allow_duplicates_)
+ return false;
+ if (is_duplicate && string_piece == "default")
+ return false;
+ if (!IsPolicyName(string_piece))
return false;
- if (allow_any_)
- return true;
- return list_.Contains(string_piece) && !is_duplicate;
+ return allow_any_ || list_.Contains(string_piece);
}
-void StringListDirective::Trace(blink::Visitor* visitor) {
+void StringListDirective::Trace(Visitor* visitor) {
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 97672b8ae79..0547c8d7175 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,15 +18,22 @@ class CORE_EXPORT StringListDirective final : public CSPDirective {
StringListDirective(const String& name,
const String& value,
ContentSecurityPolicy*);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
bool Allows(const String& string_piece, bool is_duplicate);
+ bool IsAllowDuplicates() const { return allow_duplicates_; }
private:
- // Determine whether a given string in the string list is valid.
- static bool IsInvalidStringValue(const String& str);
+ // Determine whether a given string is a valid policy name or a special token
+ // ("*" or "'allow-duplicates'"). In the token case, set the appropriate flags
+ // as a side effect.
+ bool AllowOrProcessValue(const String& src);
+
+ static bool IsPolicyName(const String& name);
+ static bool IsNotPolicyNameChar(UChar c);
Vector<String> list_;
bool allow_any_;
+ bool allow_duplicates_;
};
} // namespace blink
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
new file mode 100644
index 00000000000..4d59a0a8f5d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/csp/string_list_directive_test.cc
@@ -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.
+
+#include "third_party/blink/renderer/core/frame/csp/string_list_directive.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace blink {
+
+TEST(StringListDirectiveTest, TestAllowLists) {
+ struct {
+ const char* directive;
+ const char* should_be_allowed;
+ const char* should_not_be_allowed;
+ bool allow_dupes;
+ } test_cases[] = {
+ {"bla", "bla", "blubb", false},
+ {"*", "bla blubb", "", false},
+ {"", "", "bla blubb", false},
+ {"*", "bla a.b 123 a-b", "'bla' abc*def a,e a+b", false},
+ {"* 'allow-duplicates'", "bla blubb", "", true},
+ {"'allow-duplicates' *", "bla blubb", "", true},
+ {"bla 'allow-duplicates'", "bla", "blubb", true},
+ {"'allow-duplicates' bla", "bla", "blub", true},
+ {"'allow-duplicates'", "", "bla blub", true},
+ {"'allow-duplicates' bla blubb", "bla blubb", "blubber", true},
+ };
+
+ for (const auto& test_case : test_cases) {
+ StringListDirective directive("trusted-types", test_case.directive,
+ nullptr);
+
+ Vector<String> allowed;
+ String(test_case.should_be_allowed).Split(' ', allowed);
+ for (const String& value : allowed) {
+ SCOPED_TRACE(testing::Message()
+ << " trusted-types " << test_case.directive
+ << "; allow: " << value);
+ EXPECT_TRUE(directive.Allows(value, false));
+ EXPECT_EQ(directive.Allows(value, true), test_case.allow_dupes);
+ }
+
+ Vector<String> not_allowed;
+ String(test_case.should_not_be_allowed).Split(' ', not_allowed);
+ for (const String& value : not_allowed) {
+ SCOPED_TRACE(testing::Message()
+ << " trusted-types " << test_case.directive
+ << "; do not allow: " << value);
+ EXPECT_FALSE(directive.Allows(value, false));
+ EXPECT_FALSE(directive.Allows(value, true));
+ }
+ }
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/dactyloscoper.cc b/chromium/third_party/blink/renderer/core/frame/dactyloscoper.cc
index c384ff49f7c..380a735ecf8 100644
--- a/chromium/third_party/blink/renderer/core/frame/dactyloscoper.cc
+++ b/chromium/third_party/blink/renderer/core/frame/dactyloscoper.cc
@@ -21,7 +21,7 @@ void Dactyloscoper::Record(ExecutionContext* context, WebFeature feature) {
// TODO: Workers.
if (!context)
return;
- if (auto* document = DynamicTo<Document>(context)) {
+ if (auto* document = Document::DynamicFrom(context)) {
if (DocumentLoader* loader = document->Loader())
loader->GetDactyloscoper().Record(feature);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/deprecation.cc b/chromium/third_party/blink/renderer/core/frame/deprecation.cc
index a3482f4fe4f..62e4ed0ee68 100644
--- a/chromium/third_party/blink/renderer/core/frame/deprecation.cc
+++ b/chromium/third_party/blink/renderer/core/frame/deprecation.cc
@@ -22,6 +22,7 @@
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/date_math.h"
@@ -60,6 +61,8 @@ enum Milestone {
kM80 = 80,
kM81 = 81,
kM82 = 82,
+ kM83 = 83,
+ kM84 = 84,
};
// Returns estimated milestone dates as milliseconds since January 1, 1970.
@@ -97,9 +100,17 @@ base::Time::Exploded MilestoneDate(Milestone milestone) {
case kM80:
return {2020, 2, 0, 4, 4};
case kM81:
- return {2020, 3, 0, 17, 4};
+ return {2020, 4, 0, 7, 4};
case kM82:
- return {2020, 4, 0, 28, 4};
+ // This release was cancelled, so this is the (new) M83 date.
+ // https://groups.google.com/a/chromium.org/d/msg/chromium-dev/N1NxbSVOZas/ySlEKDKkBgAJ
+ return {2020, 5, 0, 18, 4};
+ case kM83:
+ return {2020, 5, 0, 18, 4};
+ case kM84:
+ // This release is not yet scheduled, so this date is a guess.
+ // https://groups.google.com/a/chromium.org/d/msg/chromium-dev/N1NxbSVOZas/ySlEKDKkBgAJ
+ return {2020, 6, 0, 29, 4};
}
NOTREACHED();
@@ -401,16 +412,6 @@ DeprecationInfo GetDeprecationInfo(WebFeature feature) {
#undef kWebComponentsV0DeprecationPost
- case WebFeature::kPresentationRequestStartInsecureOrigin:
- case WebFeature::kPresentationReceiverInsecureOrigin:
- return {
- "PresentationInsecureOrigin", kM72,
- String("Using the Presentation API on insecure origins is "
- "deprecated and will be removed in M72. You should consider "
- "switching your application to a secure origin, such as "
- "HTTPS. See "
- "https://goo.gl/rStTGz for more details.")};
-
case WebFeature::kLocalCSSFileExtensionRejected:
return {"LocalCSSFileExtensionRejected", kM64,
String("CSS cannot be loaded from `file:` URLs unless they end "
@@ -480,13 +481,13 @@ DeprecationInfo GetDeprecationInfo(WebFeature feature) {
MilestoneString(kM72).Ascii().c_str())};
case WebFeature::kNoSysexWebMIDIWithoutPermission:
- return {"NoSysexWebMIDIWithoutPermission", kM77,
+ return {"NoSysexWebMIDIWithoutPermission", kM82,
String::Format(
"Web MIDI will ask a permission to use even if the sysex is "
- "not specified in the MIDIOptions since %s. See "
+ "not specified in the MIDIOptions since around %s. See "
"https://www.chromestatus.com/feature/5138066234671104 for "
"more details.",
- MilestoneString(kM77).Ascii().c_str())};
+ MilestoneString(kM82).Ascii().c_str())};
case WebFeature::kCustomCursorIntersectsViewport:
return {
@@ -501,165 +502,12 @@ DeprecationInfo GetDeprecationInfo(WebFeature feature) {
ReplacedWillBeRemoved("Atomics.wake", "Atomics.notify", kM76,
"6228189936353280")};
- case WebFeature::kCSSValueAppearanceCheckboxForOthersRendered:
- return {"CSSValueAppearanceCheckboxForOthersRendered", kM79,
- WillBeRemoved("'-webkit-appearance: checkbox' for elements other "
- "than input[type=checkbox]",
- kM79, "5070237827334144")};
- case WebFeature::kCSSValueAppearanceRadioForOthersRendered:
- return {"CSSValueAppearanceRadioForOthersRendered", kM79,
- WillBeRemoved("'-webkit-appearance: radio' for elements other "
- "than input[type=radio]",
- kM79, "5070237827334144")};
- case WebFeature::kCSSValueAppearancePushButtonForOthersRendered:
- return {
- "CSSValueAppearancePushButtonForOthersRendered", kM79,
- WillBeRemoved(
- "'-webkit-appearance: push-button' for elements other than "
- "input[type=button], input[type=reset], and input[type=submit]",
- kM79, "5070237827334144")};
- case WebFeature::kCSSValueAppearanceSquareButtonForOthersRendered:
- return {"CSSValueAppearanceSquareButtonForOthersRendered", kM79,
- WillBeRemoved("'-webkit-appearance: square-button' for elements "
- "other than input[type=color]",
- kM79, "5070237827334144")};
- case WebFeature::kCSSValueAppearanceButtonForAnchor:
- return {"CSSValueAppearanceSquareButtonForAnchor", kM79,
- WillBeRemoved("'-webkit-appearance: button' for a", kM79,
- "5070237827334144")};
- case WebFeature::kCSSValueAppearanceButtonForSelectRendered:
- return {
- "CSSValueAppearanceButtonForSelectRendered", kM79,
- WillBeRemoved("'-webkit-appearance: button' for drop-down box select",
- kM79, "5070237827334144")};
- case WebFeature::kCSSValueAppearanceInnerSpinButtonForOthersRendered:
- return {"CSSValueAppearanceInnerSpinButtonForOthersRendered", kM79,
- WillBeRemoved("'-webkit-appearance: inner-spin-button' for "
- "elements other than :-webkit-inner-spin-button",
- kM79, "5070237827334144")};
- case WebFeature::kCSSValueAppearanceListboxForOthersRendered:
- return {"CSSValueAppearanceListboxForOthersRendered", kM79,
- WillBeRemoved("'-webkit-appearance: listbox' for "
- "elements other than listbox select",
- kM79, "5070237827334144")};
- case WebFeature::kCSSValueAppearanceMenuListForOthersRendered:
- return {
- "CSSValueAppearanceMenuListForOthersRendered", kM79,
- WillBeRemoved(
-#if defined(OS_ANDROID)
- "'-webkit-appearance: menulist' for elements other "
- "than drop-down box select, input[type=color][list], "
- "input[type=date], "
- "input[type=datetime-local], input[type=month], "
- "input[type=time], and input[type=week]",
-#else
- "'-webkit-appearance: menulist' for elements other "
- "than select and input[type=color][list]",
-#endif
- kM79, "5070237827334144")
- };
- case WebFeature::kCSSValueAppearanceMenuListButtonForOthersRendered:
- return {
- "CSSValueAppearanceMenuListButtonForOthersRendered", kM79,
- WillBeRemoved(
-#if defined(OS_ANDROID)
- "'-webkit-appearance: menulist-button' for elements other "
- "than drop-down box select, input[type=color][list], "
- "input[type=date], "
- "input[type=datetime-local], input[type=month], "
- "input[type=time], and input[type=week]",
-#else
- "'-webkit-appearance: menulist-button' for elements other "
- "than select and input[type=color][list]",
-#endif
- kM79, "5070237827334144")
- };
- case WebFeature::kCSSValueAppearanceMeterForOthersRendered:
- return {"CSSValueAppearanceMeterForOthersRendered", kM79,
- WillBeRemoved("'-webkit-appearance: meter' for "
- "elements other than meter",
- kM79, "5070237827334144")};
- case WebFeature::kCSSValueAppearanceProgressBarForOthersRendered:
- return {"CSSValueAppearanceProgressBarForOthersRendered", kM79,
- WillBeRemoved("'-webkit-appearance: progress-bar' for "
- "elements other than progress",
- kM79, "5070237827334144")};
- case WebFeature::kCSSValueAppearanceSliderHorizontalForOthersRendered:
- return {"CSSValueAppearanceSliderHorizontalForOthersRendered", kM79,
- WillBeRemoved("'-webkit-appearance: slider-horizontal' for "
- "elements other than input[type=range]",
- kM79, "5070237827334144")};
- case WebFeature::kCSSValueAppearanceSliderVerticalForOthersRendered:
- return {"CSSValueAppearanceSliderVerticalForOthersRendered", kM79,
- WillBeRemoved("'-webkit-appearance: slider-vertical' for "
- "elements other than input[type=range]",
- kM79, "5070237827334144")};
- case WebFeature::kCSSValueAppearanceSliderThumbHorizontalForOthersRendered:
- return {"CSSValueAppearanceSliderThumbHorizontalForOthersRendered", kM79,
- WillBeRemoved("'-webkit-appearance: sliderthumb-horizontal' for "
- "elements other than ::-webkit-slider-thumb and "
- "::-webkit-media-slider-thumb",
- kM79, "5070237827334144")};
- case WebFeature::kCSSValueAppearanceSliderThumbVerticalForOthersRendered:
- return {"CSSValueAppearanceSliderThumbVerticalForOthersRendered", kM79,
- WillBeRemoved("'-webkit-appearance: sliderthumb-vertical' for "
- "elements other than ::-webkit-slider-thumb and "
- "::-webkit-media-slider-thumb",
- kM79, "5070237827334144")};
- case WebFeature::kCSSValueAppearanceSearchFieldForOthersRendered:
- return {"CSSValueAppearanceSearchFieldForOthersRendered", kM79,
- WillBeRemoved("'-webkit-appearance: searchfield' for "
- "elements other than input[type=search]",
- kM79, "5070237827334144")};
- case WebFeature::kCSSValueAppearanceSearchCancelForOthers2Rendered:
- return {
- "CSSValueAppearanceSearchCancelForOthers2Rendered", kM79,
- WillBeRemoved("'-webkit-appearance: searchfield-cancel-button' for "
- "elements other than ::-webkit-clear-button and "
- "::-webkit-search-cancel-button",
- kM79, "5070237827334144")};
- case WebFeature::kCSSValueAppearanceTextFieldForOthersRendered:
- return {
- "CSSValueAppearanceTextFieldForOthersRendered", kM79,
- WillBeRemoved(
- "'-webkit-appearance: textfield' for "
-#if defined(OS_ANDROID)
- "elements other than input[type=email], input[type=number], "
- "input[type=password], input[type=search], input[type=tel], "
- "input[type=text], input[type=url]",
-#else
- "elements other than input[type=email], input[type=number], "
- "input[type=password], input[type=search], input[type=tel], "
- "input[type=text], input[type=url], input[type=date], "
- "input[type=datetime-local], input[type=month], "
- "input[type=time], and input[type=week]",
-#endif
- kM79, "5070237827334144")
- };
- case WebFeature::kCSSValueAppearanceTextAreaForOthersRendered:
- return {"CSSValueAppearanceTextAreaForOthersRendered", kM79,
- WillBeRemoved("'-webkit-appearance: textarea' for "
- "elements other than textarea",
- kM79, "5070237827334144")};
- case WebFeature::kARIAHelpAttribute:
- return {"ARIAHelpAttribute", kM80,
- WillBeRemoved("'aria-help'", kM80, "5645050857914368")};
-
case WebFeature::kXRSupportsSession:
return {"XRSupportsSession", kM80,
ReplacedBy(
"supportsSession()",
"isSessionSupported() and check the resolved boolean value")};
- case WebFeature::kCSSValueAppearanceButtonForBootstrapLooseSelectorRendered:
- case WebFeature::kCSSValueAppearanceButtonForOthers2Rendered:
- // The below DeprecationInfo::id doesn't match to WebFeature enums
- // intentionally.
- return {"CSSValueAppearanceButtonForOthersRendered", kM80,
- WillBeRemoved("'-webkit-appearance: button' for "
- "elements other than <button> and <input "
- "type=button/color/reset/submit>",
- kM80, "4867142128238592")};
case WebFeature::kObsoleteWebrtcTlsVersion:
return {"ObsoleteWebRtcCipherSuite", kM81,
String::Format(
@@ -668,6 +516,17 @@ DeprecationInfo GetDeprecationInfo(WebFeature feature) {
"Please check with your partner to have this fixed.",
MilestoneString(kM81).Ascii().c_str())};
+ case WebFeature::kCssStyleSheetReplaceWithImport:
+ return {
+ "CssStyleSheetReplaceWithImport", kM84,
+ String::Format(
+ "Support for calls to CSSStyleSheet.replace() with stylesheet "
+ "text that includes @import has been deprecated, and will be "
+ "removed in %s. See "
+ "https://chromestatus.com/feature/4735925877735424 for more "
+ "details.",
+ MilestoneString(kM84).Ascii().c_str())};
+
// Features that aren't deprecated don't have a deprecation message.
default:
return {"NotDeprecated", kUnknown, ""};
@@ -681,8 +540,6 @@ namespace blink {
Deprecation::Deprecation() : mute_count_(0) {
}
-Deprecation::~Deprecation() = default;
-
void Deprecation::ClearSuppression() {
css_property_deprecation_bits_.reset();
features_deprecation_bits_.reset();
@@ -726,9 +583,9 @@ void Deprecation::WarnOnDeprecatedProperties(
String message = DeprecationMessage(unresolved_property);
if (!message.IsEmpty()) {
page->GetDeprecation().Suppress(unresolved_property);
- ConsoleMessage* console_message =
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kDeprecation,
- mojom::ConsoleMessageLevel::kWarning, message);
+ auto* console_message = MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kDeprecation,
+ mojom::ConsoleMessageLevel::kWarning, message);
frame->Console().AddMessage(console_message);
}
}
@@ -753,7 +610,25 @@ void Deprecation::CountDeprecation(const Document& document,
Deprecation::CountDeprecation(document.Loader(), feature);
}
+void Deprecation::CountDeprecation(Document* document, WebFeature feature) {
+ if (!document)
+ return;
+
+ Deprecation::CountDeprecation(document->ToExecutionContext(), feature);
+}
+
void Deprecation::CountDeprecation(DocumentLoader* loader, WebFeature feature) {
+ Deprecation::CountDeprecation(loader, feature, /*count_usage=*/true);
+}
+
+void Deprecation::DeprecationWarningOnly(DocumentLoader* loader,
+ WebFeature feature) {
+ Deprecation::CountDeprecation(loader, feature, /*count_usage=*/false);
+}
+
+void Deprecation::CountDeprecation(DocumentLoader* loader,
+ WebFeature feature,
+ bool count_usage) {
if (!loader)
return;
LocalFrame* frame = loader->GetFrame();
@@ -765,7 +640,8 @@ void Deprecation::CountDeprecation(DocumentLoader* loader, WebFeature feature) {
return;
page->GetDeprecation().SetReported(feature);
- UseCounter::Count(loader, feature);
+ if (count_usage)
+ UseCounter::Count(loader, feature);
GenerateReport(frame, feature);
}
@@ -789,7 +665,7 @@ void Deprecation::GenerateReport(const LocalFrame* frame, WebFeature feature) {
// Send the deprecation message to the console as a warning.
DCHECK(!info.message.IsEmpty());
- ConsoleMessage* console_message = ConsoleMessage::Create(
+ auto* console_message = MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kDeprecation,
mojom::ConsoleMessageLevel::kWarning, info.message);
frame->Console().AddMessage(console_message);
@@ -815,7 +691,7 @@ void Deprecation::GenerateReport(const LocalFrame* frame, WebFeature feature) {
// Send the deprecation report to the Reporting API and any
// ReportingObservers.
- ReportingContext::From(document)->QueueReport(report);
+ ReportingContext::From(document->ToExecutionContext())->QueueReport(report);
}
// static
diff --git a/chromium/third_party/blink/renderer/core/frame/deprecation.h b/chromium/third_party/blink/renderer/core/frame/deprecation.h
index 07dc3dc9104..eaf82b6c67b 100644
--- a/chromium/third_party/blink/renderer/core/frame/deprecation.h
+++ b/chromium/third_party/blink/renderer/core/frame/deprecation.h
@@ -27,7 +27,6 @@ class CORE_EXPORT Deprecation final {
public:
Deprecation();
- ~Deprecation();
static void WarnOnDeprecatedProperties(const LocalFrame*,
CSSPropertyID unresolved_property);
@@ -45,6 +44,11 @@ class CORE_EXPORT Deprecation final {
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.
@@ -66,6 +70,8 @@ class CORE_EXPORT Deprecation final {
// ReportingObservers. Also sends the deprecation message to the console.
static void GenerateReport(const LocalFrame*, WebFeature);
+ static void CountDeprecation(DocumentLoader*, WebFeature, bool count_usage);
+
// To minimize the report/console spam from frames coming and going, report
// each deprecation at most once per page load per renderer process.
std::bitset<static_cast<size_t>(WebFeature::kNumberOfFeatures)>
diff --git a/chromium/third_party/blink/renderer/core/frame/deprecation_report_body.h b/chromium/third_party/blink/renderer/core/frame/deprecation_report_body.h
index e389ecb2b09..b3439a8ea5b 100644
--- a/chromium/third_party/blink/renderer/core/frame/deprecation_report_body.h
+++ b/chromium/third_party/blink/renderer/core/frame/deprecation_report_body.h
@@ -24,8 +24,8 @@ class CORE_EXPORT DeprecationReportBody : public LocationReportBody {
~DeprecationReportBody() override = default;
- String id() const { return id_; }
- String message() const { return message_; }
+ const String& id() const { return id_; }
+ const String& message() const { return message_; }
ScriptValue anticipatedRemoval(ScriptState* script_state) const;
base::Optional<base::Time> AnticipatedRemoval() const;
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 44f49c5bd47..325ef998a3d 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
@@ -92,16 +92,16 @@ bool DeviceSingleWindowEventController::IsSameSecurityOriginAsMainFrame()
}
bool DeviceSingleWindowEventController::CheckPolicyFeatures(
- const Vector<mojom::FeaturePolicyFeature>& features) const {
+ const Vector<mojom::blink::FeaturePolicyFeature>& features) const {
const Document& document = GetDocument();
return std::all_of(features.begin(), features.end(),
- [&document](mojom::FeaturePolicyFeature feature) {
+ [&document](mojom::blink::FeaturePolicyFeature feature) {
return document.IsFeatureEnabled(
feature, ReportOptions::kReportOnFailure);
});
}
-void DeviceSingleWindowEventController::Trace(blink::Visitor* visitor) {
+void DeviceSingleWindowEventController::Trace(Visitor* visitor) {
visitor->Trace(document_);
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 e66045abeb7..b32550afba1 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
@@ -24,7 +24,7 @@ class CORE_EXPORT DeviceSingleWindowEventController
// Inherited from PlatformEventController.
void DidUpdateData() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// Inherited from LocalDOMWindow::EventListenerObserver.
void DidAddEventListener(LocalDOMWindow*, const AtomicString&) override;
@@ -37,7 +37,7 @@ class CORE_EXPORT DeviceSingleWindowEventController
Document& GetDocument() const { return *document_; }
bool IsSameSecurityOriginAsMainFrame() const;
bool CheckPolicyFeatures(
- const Vector<mojom::FeaturePolicyFeature>& features) const;
+ const Vector<mojom::blink::FeaturePolicyFeature>& features) const;
void DispatchDeviceEvent(Event*);
diff --git a/chromium/third_party/blink/renderer/core/frame/document_loading_rendering_test.cc b/chromium/third_party/blink/renderer/core/frame/document_loading_rendering_test.cc
index 1e0ad9f5e25..43fcb6b1c69 100644
--- a/chromium/third_party/blink/renderer/core/frame/document_loading_rendering_test.cc
+++ b/chromium/third_party/blink/renderer/core/frame/document_loading_rendering_test.cc
@@ -118,6 +118,7 @@ TEST_F(DocumentLoadingRenderingTest,
// Sheet finishes loading, but no documentElement yet so don't resume.
css_resource.Complete("a { color: red; }");
+ test::RunPendingTasks();
EXPECT_TRUE(Compositor().DeferMainFrameUpdate());
// Root inserted so resume.
@@ -155,6 +156,7 @@ TEST_F(DocumentLoadingRenderingTest, ShouldResumeCommitsAfterSheetsLoadForXml) {
// Sheet finished, so resume commits.
css_resource.Finish();
+ test::RunPendingTasks();
EXPECT_FALSE(Compositor().DeferMainFrameUpdate());
}
@@ -260,7 +262,8 @@ TEST_F(DocumentLoadingRenderingTest,
// executing a script that reads offsetTop in the child frame could do this.
auto* child_frame =
To<HTMLIFrameElement>(GetDocument().getElementById("frame"));
- child_frame->contentDocument()->UpdateStyleAndLayout();
+ child_frame->contentDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kTest);
auto frame2 = Compositor().BeginFrame();
@@ -457,7 +460,7 @@ TEST_F(DocumentLoadingRenderingTest, StableSVGStopStylingWhileLoadingImport) {
const auto recalc_and_check = [this]() {
GetDocument().GetStyleEngine().MarkAllElementsForStyleRecalc(
StyleChangeReasonForTracing::Create("test reason"));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Element* element = GetDocument().getElementById("test");
ASSERT_NE(nullptr, element);
diff --git a/chromium/third_party/blink/renderer/core/frame/document_policy_violation_report_body.cc b/chromium/third_party/blink/renderer/core/frame/document_policy_violation_report_body.cc
new file mode 100644
index 00000000000..0c7de40eaf2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/document_policy_violation_report_body.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/document_policy_violation_report_body.h"
+
+namespace blink {
+
+void DocumentPolicyViolationReportBody::BuildJSONValue(
+ V8ObjectBuilder& builder) const {
+ LocationReportBody::BuildJSONValue(builder);
+ builder.AddString("featureId", featureId());
+ builder.AddString("disposition", disposition());
+ builder.AddStringOrNull("message", message());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/document_policy_violation_report_body.h b/chromium/third_party/blink/renderer/core/frame/document_policy_violation_report_body.h
new file mode 100644
index 00000000000..12d84653edf
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/document_policy_violation_report_body.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_FRAME_DOCUMENT_POLICY_VIOLATION_REPORT_BODY_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_DOCUMENT_POLICY_VIOLATION_REPORT_BODY_H_
+
+#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
+#include "third_party/blink/renderer/core/frame/location_report_body.h"
+
+namespace blink {
+
+class CORE_EXPORT DocumentPolicyViolationReportBody
+ : public LocationReportBody {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ DocumentPolicyViolationReportBody(const String& feature_id,
+ const String& message,
+ const String& disposition)
+ : feature_id_(feature_id), message_(message), disposition_(disposition) {}
+
+ DocumentPolicyViolationReportBody(
+ const String& feature_id,
+ const String& message,
+ const String& disposition,
+ // URL of the resource that violated the document policy.
+ const String& resource_url)
+ : LocationReportBody(resource_url),
+ feature_id_(feature_id),
+ message_(message),
+ disposition_(disposition) {}
+
+ const String& featureId() const { return feature_id_; }
+ const String& disposition() const { return disposition_; }
+ const String& message() const { return message_; }
+ void BuildJSONValue(V8ObjectBuilder& builder) const override;
+
+ ~DocumentPolicyViolationReportBody() override = default;
+
+ private:
+ const String feature_id_;
+ const String message_;
+ const String disposition_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_DOCUMENT_POLICY_VIOLATION_REPORT_BODY_H_
diff --git a/chromium/third_party/blink/renderer/core/frame/document_policy_violation_report_body.idl b/chromium/third_party/blink/renderer/core/frame/document_policy_violation_report_body.idl
new file mode 100644
index 00000000000..6b7d3102da9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/document_policy_violation_report_body.idl
@@ -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.
+
+// https://w3c.github.io/webappsec-feature-policy/document-policy.html#reporting
+
+[
+ NoInterfaceObject
+] interface DocumentPolicyViolationReportBody : ReportBody {
+ readonly attribute DOMString featureId;
+ readonly attribute DOMString? sourceFile;
+ readonly attribute unsigned long? lineNumber;
+ readonly attribute unsigned long? columnNumber;
+ readonly attribute DOMString disposition;
+ readonly attribute DOMString? message;
+ [CallWith=ScriptState] object toJSON();
+};
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 816ed3f5140..0f441655cbc 100644
--- a/chromium/third_party/blink/renderer/core/frame/dom_timer.cc
+++ b/chromium/third_party/blink/renderer/core/frame/dom_timer.cc
@@ -61,7 +61,7 @@ void DOMTimer::RemoveByID(ExecutionContext* context, int timeout_id) {
inspector_timer_remove_event::Data(context, timeout_id));
// Eagerly unregister as ExecutionContext observer.
if (timer)
- timer->ClearContext();
+ timer->SetExecutionContext(nullptr);
}
DOMTimer::DOMTimer(ExecutionContext* context,
@@ -69,7 +69,7 @@ DOMTimer::DOMTimer(ExecutionContext* context,
base::TimeDelta interval,
bool single_shot,
int timeout_id)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
TimerBase(context->GetTaskRunner(TaskType::kJavascriptTimer)),
timeout_id_(timeout_id),
nesting_level_(context->Timers()->TimerNestingLevel() + 1),
@@ -118,7 +118,7 @@ void DOMTimer::Stop() {
TimerBase::Stop();
}
-void DOMTimer::ContextDestroyed(ExecutionContext*) {
+void DOMTimer::ContextDestroyed() {
Stop();
}
@@ -171,12 +171,12 @@ void DOMTimer::Fired() {
execution_context->Timers()->SetTimerNestingLevel(0);
// Eagerly unregister as ExecutionContext observer.
- ClearContext();
+ SetExecutionContext(nullptr);
}
-void DOMTimer::Trace(blink::Visitor* visitor) {
+void DOMTimer::Trace(Visitor* visitor) {
visitor->Trace(action_);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 190a2cfccff..3c7f6cb162f 100644
--- a/chromium/third_party/blink/renderer/core/frame/dom_timer.h
+++ b/chromium/third_party/blink/renderer/core/frame/dom_timer.h
@@ -29,7 +29,7 @@
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/probe/async_task_id.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -41,7 +41,7 @@ class ExecutionContext;
class ScheduledAction;
class CORE_EXPORT DOMTimer final : public GarbageCollected<DOMTimer>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public TimerBase,
public NameClient {
USING_GARBAGE_COLLECTED_MIXIN(DOMTimer);
@@ -63,16 +63,16 @@ class CORE_EXPORT DOMTimer final : public GarbageCollected<DOMTimer>,
int timeout_id);
~DOMTimer() override;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
// Pre finalizer is needed to promptly stop this Timer object.
// Otherwise timer events might fire at an object that's slated for
// destruction (when lazily swept), but some of its members (m_action) may
// already have been finalized & must not be accessed.
void Dispose();
-
- void Trace(blink::Visitor*) override;
+
+ void Trace(Visitor*) 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 38f944190eb..8a88f5d0774 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(blink::Visitor* visitor) {
+void DOMTimerCoordinator::Trace(Visitor* visitor) {
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 5038b573b65..ca8dd281d22 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(blink::Visitor*); // Oilpan.
+ void Trace(Visitor*); // 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 3193bcc417a..1d506e52c96 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(blink::Visitor* visitor) {
+void DOMVisualViewport::Trace(Visitor* visitor) {
visitor->Trace(window_);
EventTargetWithInlineData::Trace(visitor);
}
@@ -91,7 +91,7 @@ float DOMVisualViewport::pageLeft() const {
if (!view || !view->LayoutViewport())
return 0;
- frame->GetDocument()->UpdateStyleAndLayout();
+ frame->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
float viewport_x = page->GetVisualViewport().GetScrollOffset().Width() +
view->LayoutViewport()->GetScrollOffset().Width();
return AdjustForAbsoluteZoom::AdjustScroll(viewport_x,
@@ -111,7 +111,7 @@ float DOMVisualViewport::pageTop() const {
if (!view || !view->LayoutViewport())
return 0;
- frame->GetDocument()->UpdateStyleAndLayout();
+ frame->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
float viewport_y = page->GetVisualViewport().GetScrollOffset().Height() +
view->LayoutViewport()->GetScrollOffset().Height();
return AdjustForAbsoluteZoom::AdjustScroll(viewport_y,
@@ -125,7 +125,8 @@ double DOMVisualViewport::width() const {
if (!frame->IsMainFrame()) {
// Update layout to ensure scrollbars are up-to-date.
- frame->GetDocument()->UpdateStyleAndLayout();
+ frame->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kJavaScript);
auto* scrollable_area = frame->View()->LayoutViewport();
float width =
scrollable_area->VisibleContentRect(kExcludeScrollbars).Width();
@@ -146,7 +147,8 @@ double DOMVisualViewport::height() const {
if (!frame->IsMainFrame()) {
// Update layout to ensure scrollbars are up-to-date.
- frame->GetDocument()->UpdateStyleAndLayout();
+ frame->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kJavaScript);
auto* scrollable_area = frame->View()->LayoutViewport();
float height =
scrollable_area->VisibleContentRect(kExcludeScrollbars).Height();
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 3a0f832b246..56ec60551e9 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 d7e274a5e26..0bf6a7d15ad 100644
--- a/chromium/third_party/blink/renderer/core/frame/dom_window.cc
+++ b/chromium/third_party/blink/renderer/core/frame/dom_window.cc
@@ -7,6 +7,7 @@
#include <memory>
#include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_window_post_message_options.h"
#include "third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/events/message_event.h"
@@ -20,7 +21,6 @@
#include "third_party/blink/renderer/core/frame/location.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/window_post_message_options.h"
#include "third_party/blink/renderer/core/input/input_device_capabilities.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/loader/mixed_content_checker.h"
@@ -28,6 +28,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/core/probe/core_probes.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/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -44,10 +45,21 @@ DOMWindow::~DOMWindow() {
DCHECK(!frame_);
}
-v8::Local<v8::Object> DOMWindow::Wrap(v8::Isolate* isolate,
- v8::Local<v8::Object> creation_context) {
- NOTREACHED();
- return v8::Local<v8::Object>();
+v8::Local<v8::Value> DOMWindow::Wrap(v8::Isolate* isolate,
+ v8::Local<v8::Object> creation_context) {
+ // TODO(yukishiino): Get understanding of why it's possible to initialize
+ // the context after the frame is detached. And then, remove the following
+ // lines. See also https://crbug.com/712638 .
+ Frame* frame = GetFrame();
+ if (!frame)
+ return v8::Null(isolate);
+
+ // TODO(yukishiino): Make this function always return the non-empty handle
+ // even if the frame is detached because the global proxy must always exist
+ // per spec.
+ ScriptState* script_state = ScriptState::From(isolate->GetCurrentContext());
+ return frame->GetWindowProxy(script_state->World())
+ ->GlobalProxyIfNotDetached();
}
v8::Local<v8::Object> DOMWindow::AssociateWithWrapper(
@@ -233,19 +245,23 @@ String DOMWindow::CrossDomainAccessErrorMessage(
KURL target_url = local_dom_window
? local_dom_window->document()->Url()
: KURL(NullURL(), target_origin->ToString());
- if (GetFrame()->GetSecurityContext()->IsSandboxed(WebSandboxFlags::kOrigin) ||
- accessing_window->document()->IsSandboxed(WebSandboxFlags::kOrigin)) {
+ if (GetFrame()->GetSecurityContext()->IsSandboxed(
+ mojom::blink::WebSandboxFlags::kOrigin) ||
+ accessing_window->document()->IsSandboxed(
+ mojom::blink::WebSandboxFlags::kOrigin)) {
message = "Blocked a frame at \"" +
SecurityOrigin::Create(active_url)->ToString() +
"\" from accessing a frame at \"" +
SecurityOrigin::Create(target_url)->ToString() + "\". ";
if (GetFrame()->GetSecurityContext()->IsSandboxed(
- WebSandboxFlags::kOrigin) &&
- accessing_window->document()->IsSandboxed(WebSandboxFlags::kOrigin))
+ mojom::blink::WebSandboxFlags::kOrigin) &&
+ accessing_window->document()->IsSandboxed(
+ mojom::blink::WebSandboxFlags::kOrigin))
return "Sandbox access violation: " + message +
" Both frames are sandboxed and lack the \"allow-same-origin\" "
"flag.";
- if (GetFrame()->GetSecurityContext()->IsSandboxed(WebSandboxFlags::kOrigin))
+ if (GetFrame()->GetSecurityContext()->IsSandboxed(
+ mojom::blink::WebSandboxFlags::kOrigin))
return "Sandbox access violation: " + message +
" The frame being accessed is sandboxed and lacks the "
"\"allow-same-origin\" flag.";
@@ -317,10 +333,10 @@ void DOMWindow::Close(LocalDOMWindow* incumbent_window) {
if (!page->OpenedByDOM() && GetFrame()->Client()->BackForwardLength() > 1 &&
!allow_scripts_to_close_windows) {
active_document->domWindow()->GetFrameConsole()->AddMessage(
- ConsoleMessage::Create(
+ MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning,
- "Scripts may close only the windows that were opened by it."));
+ "Scripts may close only the windows that were opened by them."));
return;
}
@@ -370,7 +386,7 @@ void DOMWindow::focus(v8::Isolate* isolate) {
DCHECK(IsMainThread());
allow_focus =
opener() && (opener() != this) &&
- (To<Document>(incumbent_execution_context)->domWindow() == opener());
+ (Document::From(incumbent_execution_context)->domWindow() == opener());
}
// If we're a top level window, bring the window to the front.
@@ -467,7 +483,7 @@ void DOMWindow::DoPostMessage(scoped_refptr<SerializedScriptValue> message,
if (!source_document->GetContentSecurityPolicy()->AllowConnectToSource(
target_url, RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting)) {
+ ReportingDisposition::kSuppressReporting)) {
UseCounter::Count(
source_document,
WebFeature::kPostMessageOutgoingWouldBeBlockedByConnectSrc);
@@ -517,7 +533,7 @@ void DOMWindow::DoPostMessage(scoped_refptr<SerializedScriptValue> message,
SchedulePostMessage(event, std::move(target), source_document);
}
-void DOMWindow::Trace(blink::Visitor* visitor) {
+void DOMWindow::Trace(Visitor* visitor) {
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 50a6a7b2084..d4fff638cd1 100644
--- a/chromium/third_party/blink/renderer/core/frame/dom_window.h
+++ b/chromium/third_party/blink/renderer/core/frame/dom_window.h
@@ -58,14 +58,14 @@ class CORE_EXPORT DOMWindow : public EventTargetWithInlineData {
}
// GarbageCollected overrides:
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
virtual bool IsLocalDOMWindow() const = 0;
virtual bool IsRemoteDOMWindow() const = 0;
// ScriptWrappable overrides:
- v8::Local<v8::Object> Wrap(v8::Isolate*,
- v8::Local<v8::Object> creation_context) final;
+ v8::Local<v8::Value> Wrap(v8::Isolate*,
+ v8::Local<v8::Object> creation_context) final;
v8::Local<v8::Object> AssociateWithWrapper(
v8::Isolate*,
const WrapperTypeInfo*,
diff --git a/chromium/third_party/blink/renderer/core/frame/embedded_content_view.h b/chromium/third_party/blink/renderer/core/frame/embedded_content_view.h
index ca0dac687b8..b3a68297be9 100644
--- a/chromium/third_party/blink/renderer/core/frame/embedded_content_view.h
+++ b/chromium/third_party/blink/renderer/core/frame/embedded_content_view.h
@@ -78,10 +78,6 @@ class CORE_EXPORT EmbeddedContentView : public GarbageCollectedMixin {
virtual void SelfVisibleChanged() {}
virtual void ParentVisibleChanged() {}
void SetAttached(bool attached) { is_attached_ = attached; }
- // Location() is in frame coordinates, DocumentLocation() is in document
- // coordinates. For more information:
- // http://www.chromium.org/developers/design-documents/blink-coordinate-spaces
- IntPoint DocumentLocation() const { return frame_rect_.Location(); }
private:
// Note that frame_rect_ is actually in document coordinates, but the
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 435d28af748..b331361c7da 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
@@ -4,7 +4,8 @@
#include "third_party/blink/renderer/core/frame/event_handler_registry.h"
-#include "third_party/blink/renderer/core/dom/events/event_listener_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_event_listener_options.h"
+#include "third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.h"
#include "third_party/blink/renderer/core/events/event_util.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -334,7 +335,7 @@ void EventHandlerRegistry::NotifyDidAddOrRemoveEventHandlerTarget(
}
}
-void EventHandlerRegistry::Trace(blink::Visitor* visitor) {
+void EventHandlerRegistry::Trace(Visitor* visitor) {
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 06cbeef4813..ad606b7719d 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
@@ -78,7 +78,7 @@ class CORE_EXPORT EventHandlerRegistry final
// references to handlers that are no longer related to it.
void DocumentDetached(Document&);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
enum ChangeOperation {
diff --git a/chromium/third_party/blink/renderer/core/frame/feature_policy_violation_report_body.h b/chromium/third_party/blink/renderer/core/frame/feature_policy_violation_report_body.h
index 85251a46a90..3e8fa482cbb 100644
--- a/chromium/third_party/blink/renderer/core/frame/feature_policy_violation_report_body.h
+++ b/chromium/third_party/blink/renderer/core/frame/feature_policy_violation_report_body.h
@@ -31,9 +31,9 @@ class CORE_EXPORT FeaturePolicyViolationReportBody : public LocationReportBody {
message_(message),
disposition_(disposition) {}
- String featureId() const { return feature_id_; }
- String disposition() const { return disposition_; }
- String message() const { return message_; }
+ const String& featureId() const { return feature_id_; }
+ const String& disposition() const { return disposition_; }
+ const String& message() const { return message_; }
void BuildJSONValue(V8ObjectBuilder& builder) const override;
~FeaturePolicyViolationReportBody() override = default;
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 ddbbb1c3a5f..f020300af2d 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
@@ -62,6 +62,10 @@ void FindInPage::Find(int request_id,
const String& search_text,
mojom::blink::FindOptionsPtr options) {
DCHECK(!search_text.IsEmpty());
+
+ // Record the fact that we have a find-in-page request.
+ frame_->GetFrame()->GetDocument()->MarkHasFindInPageRequest();
+
blink::WebPlugin* plugin = GetWebPluginForFind();
// Check if the plugin still exists in the document.
if (plugin) {
@@ -90,6 +94,12 @@ void FindInPage::Find(int request_id,
bool result = false;
bool active_now = false;
+ if (!options->find_next) {
+ // 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) {
@@ -166,9 +176,13 @@ bool FindInPage::FindInternal(int identifier,
// Unlikely, but just in case we try to find-in-page on a detached frame.
DCHECK(frame_->GetFrame()->GetPage());
+ auto forced_activatable_locks =
+ frame_->GetFrame()->GetDocument()->GetScopedForceActivatableLocks();
+
// Up-to-date, clean tree is required for finding text in page, since it
// relies on TextIterator to look over the text.
- frame_->GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ frame_->GetFrame()->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kFindInPage);
return EnsureTextFinder().Find(identifier, search_text, options,
wrap_within_frame, active_now);
@@ -209,15 +223,15 @@ int FindInPage::FindMatchMarkersVersion() const {
return 0;
}
-WebFloatRect FindInPage::ActiveFindMatchRect() {
+gfx::RectF FindInPage::ActiveFindMatchRect() {
if (GetTextFinder())
return GetTextFinder()->ActiveFindMatchRect();
- return WebFloatRect();
+ return gfx::RectF();
}
void FindInPage::ActivateNearestFindResult(int request_id,
- const WebFloatPoint& point) {
- WebRect active_match_rect;
+ const gfx::PointF& point) {
+ gfx::Rect active_match_rect;
const int ordinal =
EnsureTextFinder().SelectNearestFindMatch(point, &active_match_rect);
if (ordinal == -1) {
@@ -239,17 +253,17 @@ void FindInPage::SetClient(
client_.Bind(std::move(remote));
}
-void FindInPage::GetNearestFindResult(const WebFloatPoint& point,
+void FindInPage::GetNearestFindResult(const gfx::PointF& point,
GetNearestFindResultCallback callback) {
float distance;
- EnsureTextFinder().NearestFindMatch(point, &distance);
+ EnsureTextFinder().NearestFindMatch(FloatPoint(point), &distance);
std::move(callback).Run(distance);
}
void FindInPage::FindMatchRects(int current_version,
FindMatchRectsCallback callback) {
int rects_version = FindMatchMarkersVersion();
- Vector<WebFloatRect> rects;
+ Vector<gfx::RectF> rects;
if (current_version != rects_version)
rects = EnsureTextFinder().FindMatchRects();
std::move(callback).Run(rects_version, rects, ActiveFindMatchRect());
@@ -333,7 +347,7 @@ void FindInPage::ReportFindInPageMatchCount(int request_id,
void FindInPage::ReportFindInPageSelection(int request_id,
int active_match_ordinal,
- const blink::WebRect& selection_rect,
+ const gfx::Rect& selection_rect,
bool final_update) {
// In tests, |client_| might not be set.
if (!client_)
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 1f835bfdec9..281aeaa6234 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
@@ -16,7 +16,7 @@
#include "third_party/blink/public/web/web_plugin_container.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/editing/finder/text_finder.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
@@ -24,7 +24,6 @@ namespace blink {
class WebLocalFrameImpl;
class WebString;
-struct WebFloatRect;
class CORE_EXPORT FindInPage final : public GarbageCollected<FindInPage>,
public mojom::blink::FindInPage {
@@ -44,13 +43,13 @@ class CORE_EXPORT FindInPage final : public GarbageCollected<FindInPage>,
// Returns the bounding box of the active find-in-page match marker or an
// empty rect if no such marker exists. The rect is returned in find-in-page
// coordinates.
- WebFloatRect ActiveFindMatchRect();
+ gfx::RectF ActiveFindMatchRect();
void ReportFindInPageMatchCount(int request_id, int count, bool final_update);
void ReportFindInPageSelection(int request_id,
int active_match_ordinal,
- const blink::WebRect& selection_rect,
+ const gfx::Rect& selection_rect,
bool final_update);
// mojom::blink::FindInPage overrides
@@ -60,14 +59,14 @@ class CORE_EXPORT FindInPage final : public GarbageCollected<FindInPage>,
void SetClient(mojo::PendingRemote<mojom::blink::FindInPageClient>) final;
- void ActivateNearestFindResult(int request_id, const WebFloatPoint&) final;
+ void ActivateNearestFindResult(int request_id, const gfx::PointF&) final;
// Stops the current find-in-page, following the given |action|
void StopFinding(mojom::StopFindAction action) final;
// Returns the distance (squared) to the closest find-in-page match from the
// provided point, in find-in-page coordinates.
- void GetNearestFindResult(const WebFloatPoint&,
+ void GetNearestFindResult(const gfx::PointF&,
GetNearestFindResultCallback) final;
// Returns the bounding boxes of the find-in-page match markers in the frame,
@@ -94,7 +93,7 @@ class CORE_EXPORT FindInPage final : public GarbageCollected<FindInPage>,
void Dispose();
- void Trace(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
visitor->Trace(text_finder_);
visitor->Trace(frame_);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/find_in_page_test.cc b/chromium/third_party/blink/renderer/core/frame/find_in_page_test.cc
index 9f51782771f..0529e32f7c4 100644
--- a/chromium/third_party/blink/renderer/core/frame/find_in_page_test.cc
+++ b/chromium/third_party/blink/renderer/core/frame/find_in_page_test.cc
@@ -57,11 +57,11 @@ class FindInPageCallbackReceiver {
bool IsCalled() { return is_called; }
void AssertFindMatchRects(int expected_version,
- const WebVector<WebFloatRect>& expected_rects,
- const WebFloatRect& expected_active_match_rect,
+ const WebVector<gfx::RectF>& expected_rects,
+ const gfx::RectF& expected_active_match_rect,
int actual_version,
- const Vector<WebFloatRect>& actual_rects,
- const WebFloatRect& actual_active_match_rect) {
+ const Vector<gfx::RectF>& actual_rects,
+ const gfx::RectF& actual_active_match_rect) {
is_called = true;
EXPECT_EQ(expected_version, actual_version);
EXPECT_EQ(expected_rects.size(), actual_rects.size());
@@ -76,8 +76,8 @@ class FindInPageCallbackReceiver {
};
TEST_F(FindInPageTest, FindMatchRectsReturnsCorrectRects) {
- GetDocument().body()->SetInnerHTMLFromString("aAaAbBaBbAaAaA");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().body()->setInnerHTML("aAaAbBaBbAaAaA");
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
int identifier = 0;
WebString search_text(String("aA"));
diff --git a/chromium/third_party/blink/renderer/core/frame/frame.cc b/chromium/third_party/blink/renderer/core/frame/frame.cc
index 78b5c772007..4f85a218063 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame.cc
+++ b/chromium/third_party/blink/renderer/core/frame/frame.cc
@@ -32,6 +32,7 @@
#include <memory>
+#include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom-blink.h"
#include "third_party/blink/public/web/web_local_frame_client.h"
#include "third_party/blink/public/web/web_remote_frame_client.h"
#include "third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h"
@@ -40,14 +41,17 @@
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/execution_context/window_agent_factory.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/frame/remote_frame_owner.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/html/html_frame_element_base.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/core/loader/empty_clients.h"
+#include "third_party/blink/renderer/core/loader/form_submission.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/probe/core_probes.h"
+#include "third_party/blink/renderer/core/xmlhttprequest/main_thread_disallow_synchronous_xhr_scope.h"
#include "third_party/blink/renderer/platform/instrumentation/instance_counters.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_error.h"
@@ -61,7 +65,7 @@ Frame::~Frame() {
DCHECK(IsDetached());
}
-void Frame::Trace(blink::Visitor* visitor) {
+void Frame::Trace(Visitor* visitor) {
visitor->Trace(tree_node_);
visitor->Trace(page_);
visitor->Trace(owner_);
@@ -77,6 +81,7 @@ void Frame::Detach(FrameDetachType type) {
// Detach() can be re-entered, so this can't simply DCHECK(IsAttached()).
DCHECK(!IsDetached());
lifecycle_.AdvanceTo(FrameLifecycle::kDetaching);
+ MainThreadDisallowSynchronousXHRScope disallow_synchronous_xhr;
DetachImpl(type);
@@ -128,7 +133,7 @@ bool Frame::IsMainFrame() const {
return !Tree().Parent();
}
-bool Frame::IsCrossOriginSubframe() const {
+bool Frame::IsCrossOriginToMainFrame() const {
DCHECK(GetSecurityContext());
const SecurityOrigin* security_origin =
GetSecurityContext()->GetSecurityOrigin();
@@ -136,6 +141,18 @@ bool Frame::IsCrossOriginSubframe() const {
Tree().Top().GetSecurityContext()->GetSecurityOrigin());
}
+bool Frame::IsCrossOriginToParentFrame() const {
+ DCHECK(GetSecurityContext());
+ if (IsMainFrame())
+ return false;
+ Frame* parent = Tree().Parent();
+ const SecurityOrigin* parent_security_origin =
+ parent->GetSecurityContext()->GetSecurityOrigin();
+ const SecurityOrigin* security_origin =
+ GetSecurityContext()->GetSecurityOrigin();
+ return !security_origin->CanAccess(parent_security_origin);
+}
+
HTMLFrameOwnerElement* Frame::DeprecatedLocalOwner() const {
return DynamicTo<HTMLFrameOwnerElement>(owner_.Get());
}
@@ -296,6 +313,7 @@ Frame::Frame(FrameClient* client,
: tree_node_(this),
page_(&page),
owner_(owner),
+ ad_frame_type_(mojom::blink::AdFrameType::kNonAd),
client_(client),
window_proxy_manager_(window_proxy_manager),
navigation_rate_limiter_(*this),
@@ -328,6 +346,33 @@ void Frame::FocusImpl() {
this, false /* notify_embedder */);
}
+void Frame::ApplyFrameOwnerProperties(
+ mojom::blink::FrameOwnerPropertiesPtr properties) {
+ // At the moment, this is only used to replicate frame owner properties
+ // for frames with a remote owner.
+ auto* owner = To<RemoteFrameOwner>(Owner());
+
+ owner->SetBrowsingContextContainerName(properties->name);
+ owner->SetScrollbarMode(properties->scrollbar_mode);
+ owner->SetMarginWidth(properties->margin_width);
+ owner->SetMarginHeight(properties->margin_height);
+ owner->SetAllowFullscreen(properties->allow_fullscreen);
+ owner->SetAllowPaymentRequest(properties->allow_payment_request);
+ owner->SetIsDisplayNone(properties->is_display_none);
+ owner->SetRequiredCsp(properties->required_csp);
+}
+
+void Frame::ScheduleFormSubmission(FrameScheduler* scheduler,
+ FormSubmission* form_submission) {
+ form_submit_navigation_task_ = PostCancellableTask(
+ *scheduler->GetTaskRunner(TaskType::kDOMManipulation), FROM_HERE,
+ WTF::Bind(&FormSubmission::Navigate, WrapPersistent(form_submission)));
+}
+
+void Frame::CancelFormSubmission() {
+ form_submit_navigation_task_.Cancel();
+}
+
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 955b8ec3b84..d36fb54eb17 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame.h
+++ b/chromium/third_party/blink/renderer/core/frame/frame.h
@@ -31,9 +31,11 @@
#include "base/optional.h"
#include "base/unguessable_token.h"
-#include "third_party/blink/public/common/feature_policy/feature_policy.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"
+#include "third_party/blink/public/mojom/ad_tagging/ad_frame.mojom-blink.h"
+#include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom-blink-forward.h"
#include "third_party/blink/public/web/web_frame_load_type.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/frame/frame_lifecycle.h"
@@ -44,6 +46,7 @@
#include "third_party/blink/renderer/core/scroll/scroll_types.h"
#include "third_party/blink/renderer/platform/graphics/touch_action.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
namespace blink {
@@ -54,6 +57,8 @@ class DOMWrapperWorld;
class Document;
class FrameClient;
class FrameOwner;
+class FrameScheduler;
+class FormSubmission;
class HTMLFrameOwnerElement;
class LayoutEmbeddedContent;
class LocalFrame;
@@ -67,9 +72,6 @@ class WindowAgentFactory;
enum class FrameDetachType { kRemove, kSwap };
-// Status of user gesture.
-enum class UserGestureStatus { kActive, kNone };
-
// Frame is the base class of LocalFrame and RemoteFrame and should only contain
// functionality shared between both. In particular, any method related to
// input, layout, or painting probably belongs on LocalFrame.
@@ -77,12 +79,12 @@ class CORE_EXPORT Frame : public GarbageCollected<Frame> {
public:
virtual ~Frame();
- virtual void Trace(blink::Visitor*);
+ virtual void Trace(Visitor*);
virtual bool IsLocalFrame() const = 0;
virtual bool IsRemoteFrame() const = 0;
- virtual void Navigate(const FrameLoadRequest&, WebFrameLoadType) = 0;
+ virtual void Navigate(FrameLoadRequest&, WebFrameLoadType) = 0;
void Detach(FrameDetachType);
void DisconnectOwnerElement();
@@ -103,13 +105,23 @@ class CORE_EXPORT Frame : public GarbageCollected<Frame> {
// reach out to site-isolation-dev@chromium.org.
bool IsMainFrame() const;
- // Note that the result of this function should not be cached: a frame is
- // not necessarily detached when it is navigated, so the return value can
- // change.
- // In addition, this function will always return true for a detached frame.
+ // Returns true if and only if:
+ // - this frame is a subframe
+ // - it is cross-origin to the main frame
+ //
+ // Important notes:
+ // - This function is not appropriate for determining if a subframe is
+ // cross-origin to its parent (see: |IsCrossOriginToParentFrame|).
+ // - The return value must NOT be cached. A frame can be reused across
+ // navigations, so the return value can change over time.
+ // - The return value is inaccurate for a detached frame: it always
+ // returns true when the frame is detached.
// TODO(dcheng): Move this to LocalDOMWindow and figure out the right
// behavior for detached windows.
- bool IsCrossOriginSubframe() const;
+ bool IsCrossOriginToMainFrame() const;
+ // Returns true if this frame is a subframe and is cross-origin to the parent
+ // frame. See |IsCrossOriginToMainFrame| for important notes.
+ bool IsCrossOriginToParentFrame() const;
FrameOwner* Owner() const;
void SetOwner(FrameOwner*);
@@ -120,7 +132,7 @@ class CORE_EXPORT Frame : public GarbageCollected<Frame> {
FrameTree& Tree() const;
ChromeClient& GetChromeClient() const;
- virtual SecurityContext* GetSecurityContext() const = 0;
+ virtual const SecurityContext* GetSecurityContext() const = 0;
Frame* FindUnsafeParentScrollPropagationBoundary();
@@ -162,27 +174,43 @@ class CORE_EXPORT Frame : public GarbageCollected<Frame> {
// This should never be called from outside Frame or WebFrame.
void ClearUserActivationInLocalTree();
- bool HasBeenActivated() const {
+ // Returns the transient user activation state of this frame.
+ bool HasTransientUserActivation() const {
+ return user_activation_state_.IsActive();
+ }
+
+ // Returns the sticky user activation state of this frame.
+ bool HasStickyUserActivation() const {
return user_activation_state_.HasBeenActive();
}
- void ClearActivation() { user_activation_state_.Clear(); }
+ // Resets the user activation state of this frame.
+ void ClearUserActivation() { user_activation_state_.Clear(); }
// Transfers user activation state from |other| frame into |this|.
void TransferUserActivationFrom(Frame* other);
- void SetDocumentHasReceivedUserGestureBeforeNavigation(bool value) {
- has_received_user_gesture_before_nav_ = value;
+ void SetHadStickyUserActivationBeforeNavigation(bool value) {
+ had_sticky_user_activation_before_nav_ = value;
}
- bool HasReceivedUserGestureBeforeNavigation() const {
- return has_received_user_gesture_before_nav_;
+ bool HadStickyUserActivationBeforeNavigation() const {
+ return had_sticky_user_activation_before_nav_;
}
bool IsAttached() const {
return lifecycle_.GetState() == FrameLifecycle::kAttached;
}
+ // Ad Tagging
+ bool IsAdSubframe() const {
+ return ad_frame_type_ != mojom::blink::AdFrameType::kNonAd;
+ }
+
+ bool IsAdRoot() const {
+ return ad_frame_type_ == mojom::blink::AdFrameType::kRootAd;
+ }
+
// Called to make a frame inert or non-inert. A frame is inert when there
// is a modal dialog displayed within an ancestor frame, and this frame
// itself is not within the dialog.
@@ -197,9 +225,10 @@ class CORE_EXPORT Frame : public GarbageCollected<Frame> {
// Continues to bubble logical scroll from |child| in this frame.
// Returns true if the scroll was consumed locally.
- virtual bool BubbleLogicalScrollFromChildFrame(ScrollDirection direction,
- ScrollGranularity granularity,
- Frame* child) = 0;
+ virtual bool BubbleLogicalScrollFromChildFrame(
+ mojom::blink::ScrollDirection direction,
+ ScrollGranularity granularity,
+ Frame* child) = 0;
const base::UnguessableToken& GetDevToolsFrameToken() const {
return devtools_frame_token_;
@@ -229,6 +258,15 @@ class CORE_EXPORT Frame : public GarbageCollected<Frame> {
opener_feature_state_ = state;
}
+ const DocumentPolicy::FeatureState& GetRequiredDocumentPolicy() const {
+ return required_document_policy_;
+ }
+
+ void SetRequiredDocumentPolicy(
+ const DocumentPolicy::FeatureState& required_document_policy) {
+ required_document_policy_ = required_document_policy;
+ }
+
WindowAgentFactory& window_agent_factory() const {
return *window_agent_factory_;
}
@@ -236,9 +274,16 @@ class CORE_EXPORT Frame : public GarbageCollected<Frame> {
bool GetVisibleToHitTesting() const { return visible_to_hit_testing_; }
void UpdateVisibleToHitTesting();
+ void ScheduleFormSubmission(FrameScheduler* scheduler,
+ FormSubmission* form_submission);
+ void CancelFormSubmission();
+
// Called when the focus controller changes the focus to this frame.
virtual void DidFocus() = 0;
+ virtual IntSize GetMainFrameViewportSize() const = 0;
+ virtual IntPoint GetMainFrameScrollOffset() const = 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
@@ -269,27 +314,36 @@ class CORE_EXPORT Frame : public GarbageCollected<Frame> {
void FocusImpl();
+ void ApplyFrameOwnerProperties(
+ mojom::blink::FrameOwnerPropertiesPtr properties);
+
mutable FrameTree tree_node_;
Member<Page> page_;
Member<FrameOwner> owner_;
Member<DOMWindow> dom_window_;
- // The user activation state of the current frame. See |UserActivationState|
- // for details on how this state is maintained.
- UserActivationState user_activation_state_;
-
- bool has_received_user_gesture_before_nav_ = false;
-
// This is set to true if this is a subframe, and the frame element in the
// parent frame's document becomes inert. This should always be false for
// the main frame.
bool is_inert_ = false;
- TouchAction inherited_effective_touch_action_ = TouchAction::kTouchActionAuto;
+ TouchAction inherited_effective_touch_action_ = TouchAction::kAuto;
bool visible_to_hit_testing_ = true;
+ // Type of frame detected by heuristics checking if the frame was created
+ // for advertising purposes. It's per-frame (as opposed to per-document)
+ // because when an iframe is created on behalf of ad script that same frame is
+ // not typically reused for non-ad purposes.
+ //
+ // For LocalFrame, it might be (1) calculated directly in the renderer based
+ // on script in the stack, or (2) replicated from the browser process, or (3)
+ // signaled from the browser process at ready-to-commit time. For RemoteFrame,
+ // it might be (1) replicated from the browser process or (2) signaled from
+ // the browser process at ready-to-commit time.
+ mojom::blink::AdFrameType ad_frame_type_;
+
private:
Member<FrameClient> client_;
const Member<WindowProxyManager> window_proxy_manager_;
@@ -301,12 +355,33 @@ class CORE_EXPORT Frame : public GarbageCollected<Frame> {
// frames.
FeaturePolicy::FeatureState opener_feature_state_;
+ // The required document policy for any subframes of this frame.
+ // Note: current frame's document policy might not conform to
+ // |required_document_policy_| here, as the Require-Document-Policy HTTP
+ // header can specify required document policy which only takes effect for
+ // subtree frames.
+ DocumentPolicy::FeatureState required_document_policy_;
+
Member<WindowAgentFactory> window_agent_factory_;
// TODO(sashab): Investigate if this can be represented with m_lifecycle.
bool is_loading_;
base::UnguessableToken devtools_frame_token_;
base::Optional<std::string> trace_value_;
+
+ // The user activation state of the current frame. See |UserActivationState|
+ // for details on how this state is maintained.
+ UserActivationState user_activation_state_;
+
+ // The sticky user activation state of the current frame before eTLD+1
+ // navigation. This is used in autoplay.
+ bool had_sticky_user_activation_before_nav_ = false;
+
+ // This task is used for the async step in form submission when a form is
+ // targeting this frame. http://html.spec.whatwg.org/C/#plan-to-navigate
+ // The reason it is stored here is so that it can handle both LocalFrames and
+ // RemoteFrames, and so it can be canceled by FrameLoader.
+ TaskHandle form_submit_navigation_task_;
};
inline FrameClient* Frame::Client() const {
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 672bd191591..5efbc23b286 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_client.h
+++ b/chromium/third_party/blink/renderer/core/frame/frame_client.h
@@ -33,6 +33,9 @@ class CORE_EXPORT FrameClient : public GarbageCollected<FrameClient> {
virtual unsigned BackForwardLength() = 0;
+ virtual void OnMainFrameDocumentIntersectionChanged(
+ const IntRect& intersection_rect) {}
+
virtual base::UnguessableToken GetDevToolsFrameToken() const = 0;
// Transfers user activation state from |source_frame| to the this frame.
@@ -40,7 +43,7 @@ class CORE_EXPORT FrameClient : public GarbageCollected<FrameClient> {
virtual ~FrameClient() = default;
- virtual void Trace(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
};
} // 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 e3b419f61af..25d8991f8dd 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_console.cc
+++ b/chromium/third_party/blink/renderer/core/frame/frame_console.cc
@@ -29,6 +29,7 @@
#include "third_party/blink/renderer/core/frame/frame_console.h"
#include <memory>
+
#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
@@ -37,6 +38,7 @@
#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"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_error.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
@@ -58,7 +60,8 @@ bool FrameConsole::AddMessageToStorage(ConsoleMessage* console_message,
if (!frame_->GetDocument() || !frame_->GetPage())
return false;
return frame_->GetPage()->GetConsoleMessageStorage().AddConsoleMessage(
- frame_->GetDocument(), console_message, discard_duplicates);
+ frame_->GetDocument()->ToExecutionContext(), console_message,
+ discard_duplicates);
}
void FrameConsole::ReportMessageToClient(mojom::ConsoleMessageSource source,
@@ -105,7 +108,7 @@ void FrameConsole::ReportResourceResponseReceived(
"Failed to load resource: the server responded with a status of " +
String::Number(response.HttpStatusCode()) + " (" +
response.HttpStatusText() + ')';
- ConsoleMessage* console_message = ConsoleMessage::CreateForRequest(
+ auto* console_message = MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kNetwork, mojom::ConsoleMessageLevel::kError,
message, response.CurrentRequestUrl().GetString(), loader,
request_identifier);
@@ -123,12 +126,12 @@ void FrameConsole::DidFailLoading(DocumentLoader* loader,
message.Append(": ");
message.Append(error.LocalizedDescription());
}
- AddMessageToStorage(ConsoleMessage::CreateForRequest(
+ AddMessageToStorage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kNetwork, mojom::ConsoleMessageLevel::kError,
message.ToString(), error.FailingURL(), loader, request_identifier));
}
-void FrameConsole::Trace(blink::Visitor* visitor) {
+void FrameConsole::Trace(Visitor* visitor) {
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 e1e9114b494..bf7a3835b64 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(blink::Visitor*);
+ void Trace(Visitor*);
private:
Member<LocalFrame> frame_;
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 180bfb9fef0..62132d741d5 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
@@ -60,7 +60,7 @@ class FrameOverlayTest : public testing::Test, public PaintTestConfigurations {
GetWebView()->MainFrameWidget()->Resize(
WebSize(kViewportWidth, kViewportHeight));
GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
}
WebViewImpl* GetWebView() const { return helper_.GetWebView(); }
@@ -118,7 +118,7 @@ TEST_P(FrameOverlayTest, DeviceEmulationScale) {
params.scale = 1.5;
GetWebView()->EnableDeviceEmulation(params);
GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
std::unique_ptr<FrameOverlay> frame_overlay = CreateSolidYellowOverlay();
frame_overlay->UpdatePrePaint();
@@ -166,7 +166,7 @@ TEST_P(FrameOverlayTest, VisualRect) {
std::unique_ptr<FrameOverlay> frame_overlay = CreateSolidYellowOverlay();
frame_overlay->UpdatePrePaint();
GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
EXPECT_EQ(IntRect(0, 0, kViewportWidth, kViewportHeight),
frame_overlay->VisualRect());
}
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 ee333c89353..a96fde63504 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_owner.h
+++ b/chromium/third_party/blink/renderer/core/frame/frame_owner.h
@@ -6,8 +6,8 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_FRAME_OWNER_H_
#include "third_party/blink/public/common/frame/frame_policy.h"
+#include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/scroll/scroll_types.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
@@ -26,7 +26,7 @@ class CORE_EXPORT FrameOwner : public GarbageCollectedMixin {
public:
virtual ~FrameOwner() = default;
- void Trace(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) override {}
virtual bool IsLocal() const = 0;
virtual bool IsRemote() const = 0;
@@ -66,11 +66,10 @@ class CORE_EXPORT FrameOwner : public GarbageCollectedMixin {
// container.
// https://html.spec.whatwg.org/C/#browsing-context-container
virtual AtomicString BrowsingContextContainerName() const = 0;
- virtual ScrollbarMode ScrollingMode() const = 0;
+ virtual mojom::blink::ScrollbarMode ScrollbarMode() const = 0;
virtual int MarginWidth() const = 0;
virtual int MarginHeight() const = 0;
virtual bool AllowFullscreen() const = 0;
- virtual bool DisallowDocumentAccess() const = 0;
virtual bool AllowPaymentRequest() const = 0;
virtual bool IsDisplayNone() const = 0;
virtual AtomicString RequiredCsp() const = 0;
@@ -112,7 +111,7 @@ class FrameSwapScope {
}
private:
- Member<FrameOwner> frame_owner_;
+ FrameOwner* frame_owner_;
};
// TODO(dcheng): This class is an internal implementation detail of provisional
@@ -124,7 +123,7 @@ class CORE_EXPORT DummyFrameOwner final
USING_GARBAGE_COLLECTED_MIXIN(DummyFrameOwner);
public:
- void Trace(blink::Visitor* visitor) override { FrameOwner::Trace(visitor); }
+ void Trace(Visitor* visitor) override { FrameOwner::Trace(visitor); }
// FrameOwner overrides:
Frame* ContentFrame() const override { return nullptr; }
@@ -143,11 +142,12 @@ class CORE_EXPORT DummyFrameOwner final
AtomicString BrowsingContextContainerName() const override {
return AtomicString();
}
- ScrollbarMode ScrollingMode() const override { return ScrollbarMode::kAuto; }
+ mojom::blink::ScrollbarMode ScrollbarMode() const override {
+ return mojom::blink::ScrollbarMode::kAuto;
+ }
int MarginWidth() const override { return -1; }
int MarginHeight() const override { return -1; }
bool AllowFullscreen() const override { return false; }
- bool DisallowDocumentAccess() const override { return false; }
bool AllowPaymentRequest() const override { return false; }
bool IsDisplayNone() const override { return false; }
AtomicString RequiredCsp() const override { return g_null_atom; }
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 ae279b70825..eabf1e156b3 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_serializer.cc
+++ b/chromium/third_party/blink/renderer/core/frame/frame_serializer.cc
@@ -30,8 +30,8 @@
#include "third_party/blink/renderer/core/frame/frame_serializer.h"
-#include "base/feature_list.h"
-#include "third_party/blink/public/common/features.h"
+#include "base/metrics/histogram.h"
+#include "base/metrics/histogram_functions.h"
#include "third_party/blink/renderer/core/css/css_font_face_rule.h"
#include "third_party/blink/renderer/core/css/css_font_face_src_value.h"
#include "third_party/blink/renderer/core/css/css_image_value.h"
@@ -77,13 +77,6 @@
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/uuid.h"
-namespace {
-
-const int32_t secondsToMicroseconds = 1000 * 1000;
-const int32_t maxSerializationTimeUmaMicroseconds = 10 * secondsToMicroseconds;
-
-} // namespace
-
namespace blink {
class SerializerMarkupAccumulator : public MarkupAccumulator {
@@ -113,7 +106,7 @@ class SerializerMarkupAccumulator : public MarkupAccumulator {
FrameSerializer::Delegate& delegate_;
FrameSerializerResourceDelegate& resource_delegate_;
- Member<Document> document_;
+ Document* document_;
// Elements with links rewritten via appendAttribute method.
HeapHashSet<Member<const Element>> elements_with_rewritten_links_;
@@ -124,8 +117,9 @@ SerializerMarkupAccumulator::SerializerMarkupAccumulator(
FrameSerializerResourceDelegate& resource_delegate,
Document& document)
: MarkupAccumulator(kResolveAllURLs,
- document.IsHTMLDocument() ? SerializationType::kHTML
- : SerializationType::kXML),
+ IsA<HTMLDocument>(document) ? SerializationType::kHTML
+ : SerializationType::kXML,
+ kNoShadowRoots),
delegate_(delegate),
resource_delegate_(resource_delegate),
document_(&document) {}
@@ -238,7 +232,7 @@ void SerializerMarkupAccumulator::AppendAttribute(const Element& element,
const Attribute& attribute) {
// Check if link rewriting can affect the attribute.
bool is_link_attribute = element.HasLegalLinkAttribute(attribute.GetName());
- bool is_src_doc_attribute = IsHTMLFrameElementBase(element) &&
+ bool is_src_doc_attribute = IsA<HTMLFrameElementBase>(element) &&
attribute.GetName() == html_names::kSrcdocAttr;
if (is_link_attribute || is_src_doc_attribute) {
// Check if the delegate wants to do link rewriting for the element.
@@ -273,7 +267,7 @@ std::pair<Node*, Element*> SerializerMarkupAccumulator::GetAuxiliaryDOMTree(
void SerializerMarkupAccumulator::AppendAttributeValue(
const String& attribute_value) {
MarkupFormatter::AppendAttributeValue(markup_, attribute_value,
- document_->IsHTMLDocument());
+ IsA<HTMLDocument>(document_));
}
void SerializerMarkupAccumulator::AppendRewrittenAttribute(
@@ -319,9 +313,8 @@ void FrameSerializer::SerializeFrame(const LocalFrame& frame) {
KURL url = document.Url();
// If frame is an image document, add the image and don't continue
- if (document.IsImageDocument()) {
- ImageDocument& image_document = ToImageDocument(document);
- AddImageToResources(image_document.CachedImage(), url);
+ if (auto* image_document = DynamicTo<ImageDocument>(document)) {
+ AddImageToResources(image_document->CachedImage(), url);
return;
}
@@ -345,29 +338,28 @@ void FrameSerializer::SerializeFrame(const LocalFrame& frame) {
if (should_collect_problem_metric_) {
// Report detectors through UMA.
- // We're having exact 21 buckets for percentage because we want to have 5%
- // in each bucket to avoid potential spikes in the distribution.
- UMA_HISTOGRAM_COUNTS_100(
+ // Note: some of these histograms used 21 buckets to try to ensure each
+ // bucket covered 5% of the range. Unfortunately, there was an off-by-one
+ // error... but changing the meaning of buckets is annoying.
+ base::UmaHistogramCounts100(
"PageSerialization.ProblemDetection.TotalImageCount",
total_image_count_);
if (total_image_count_ > 0) {
DCHECK_LE(loaded_image_count_, total_image_count_);
- DEFINE_STATIC_LOCAL(
- LinearHistogram, image_histogram,
- ("PageSerialization.ProblemDetection.LoadedImagePercentage", 1, 100,
- 21));
- image_histogram.Count(loaded_image_count_ * 100 / total_image_count_);
+ base::LinearHistogram::FactoryGet(
+ "PageSerialization.ProblemDetection.LoadedImagePercentage", 1, 100,
+ 21, base::HistogramBase::kUmaTargetedHistogramFlag)
+ ->Add(loaded_image_count_ * 100 / total_image_count_);
}
- UMA_HISTOGRAM_COUNTS_100("PageSerialization.ProblemDetection.TotalCSSCount",
- total_css_count_);
+ base::UmaHistogramCounts100(
+ "PageSerialization.ProblemDetection.TotalCSSCount", total_css_count_);
if (total_css_count_ > 0) {
DCHECK_LE(loaded_css_count_, total_css_count_);
- DEFINE_STATIC_LOCAL(
- LinearHistogram, css_histogram,
- ("PageSerialization.ProblemDetection.LoadedCSSPercentage", 1, 100,
- 21));
- css_histogram.Count(loaded_css_count_ * 100 / total_css_count_);
+ base::LinearHistogram::FactoryGet(
+ "PageSerialization.ProblemDetection.LoadedCSSPercentage", 1, 100, 21,
+ base::HistogramBase::kUmaTargetedHistogramFlag)
+ ->Add(loaded_css_count_ * 100 / total_css_count_);
}
should_collect_problem_metric_ = false;
}
@@ -413,8 +405,7 @@ void FrameSerializer::AddResourceForElement(Document& document,
} else if (const auto* style = DynamicTo<HTMLStyleElement>(element)) {
if (CSSStyleSheet* sheet = style->sheet())
SerializeCSSStyleSheet(*sheet, NullURL());
- } else if (IsHTMLPlugInElement(element)) {
- const auto* plugin = ToHTMLPlugInElement(&element);
+ } else if (const auto* plugin = DynamicTo<HTMLPlugInElement>(&element)) {
if (plugin->IsImageType() && plugin->ImageLoader()) {
KURL image_url = document.CompleteURL(plugin->Url());
ImageResourceContent* cached_image = plugin->ImageLoader()->GetContent();
@@ -487,10 +478,9 @@ void FrameSerializer::SerializeCSSStyleSheet(CSSStyleSheet& style_sheet,
if (css_start_time != base::TimeTicks()) {
is_serializing_css_ = false;
- DEFINE_STATIC_LOCAL(CustomCountHistogram, css_histogram,
- ("PageSerialization.SerializationTime.CSSElement", 0,
- maxSerializationTimeUmaMicroseconds, 50));
- css_histogram.CountMicroseconds(base::TimeTicks::Now() - css_start_time);
+ base::UmaHistogramMicrosecondsTimes(
+ "PageSerialization.SerializationTime.CSSElement",
+ base::TimeTicks::Now() - css_start_time);
}
}
@@ -580,11 +570,9 @@ void FrameSerializer::AddImageToResources(ImageResourceContent* image,
// If we're already reporting time for CSS serialization don't report it for
// this image to avoid reporting the same time twice.
if (!is_serializing_css_) {
- DEFINE_STATIC_LOCAL(CustomCountHistogram, image_histogram,
- ("PageSerialization.SerializationTime.ImageElement", 0,
- maxSerializationTimeUmaMicroseconds, 50));
- image_histogram.CountMicroseconds(base::TimeTicks::Now() -
- image_start_time);
+ base::UmaHistogramMicrosecondsTimes(
+ "PageSerialization.SerializationTime.ImageElement",
+ base::TimeTicks::Now() - image_start_time);
}
}
@@ -632,19 +620,18 @@ void FrameSerializer::RetrieveResourcesForCSSValue(const CSSValue& css_value,
if (font_face_src_value->IsLocal())
return;
- if (base::FeatureList::IsEnabled(
- features::kHtmlImportsRequestInitiatorLock) &&
- document.ImportsController()) {
+ if (document.ImportsController()) {
if (Document* context_document = document.ContextDocument()) {
// For @imports from HTML imported Documents, we use the
// 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.
- AddFontToResources(
- font_face_src_value->Fetch(context_document, nullptr));
+ AddFontToResources(font_face_src_value->Fetch(
+ context_document->ToExecutionContext(), nullptr));
}
} else {
- AddFontToResources(font_face_src_value->Fetch(&document, nullptr));
+ AddFontToResources(
+ font_face_src_value->Fetch(document.ToExecutionContext(), nullptr));
}
} else if (const auto* css_value_list = DynamicTo<CSSValueList>(css_value)) {
for (unsigned i = 0; i < css_value_list->length(); i++)
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
new file mode 100644
index 00000000000..ac111ef3ef1
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.cc
@@ -0,0 +1,320 @@
+// 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/frame_serializer_delegate_impl.h"
+
+#include "third_party/blink/public/web/web_frame_serializer.h"
+#include "third_party/blink/renderer/core/dom/attribute.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/dom/element_traversal.h"
+#include "third_party/blink/renderer/core/dom/shadow_root.h"
+#include "third_party/blink/renderer/core/frame/frame.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
+#include "third_party/blink/renderer/core/html/html_anchor_element.h"
+#include "third_party/blink/renderer/core/html/html_frame_element_base.h"
+#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
+#include "third_party/blink/renderer/core/html/html_head_element.h"
+#include "third_party/blink/renderer/core/html/html_iframe_element.h"
+#include "third_party/blink/renderer/core/html/html_image_element.h"
+#include "third_party/blink/renderer/core/html/html_link_element.h"
+#include "third_party/blink/renderer/core/html/html_meta_element.h"
+#include "third_party/blink/renderer/core/html/html_template_element.h"
+#include "third_party/blink/renderer/core/html/link_rel_attribute.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/core/layout/layout_box.h"
+#include "third_party/blink/renderer/core/layout/layout_object.h"
+#include "third_party/blink/renderer/core/loader/resource/image_resource_content.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/platform/geometry/layout_point.h"
+#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/mhtml/mhtml_parser.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
+#include "third_party/blink/renderer/platform/wtf/assertions.h"
+#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
+
+namespace blink {
+
+namespace {
+
+const int kPopupOverlayZIndexThreshold = 50;
+const char kShadowModeAttributeName[] = "shadowmode";
+const char kShadowDelegatesFocusAttributeName[] = "shadowdelegatesfocus";
+
+} // namespace
+
+// static
+String FrameSerializerDelegateImpl::GetContentID(Frame* frame) {
+ DCHECK(frame);
+ String frame_id = String(frame->ToTraceValue().data());
+ return "<frame-" + frame_id + "@mhtml.blink>";
+}
+
+FrameSerializerDelegateImpl::FrameSerializerDelegateImpl(
+ WebFrameSerializer::MHTMLPartsGenerationDelegate& web_delegate,
+ HeapHashSet<WeakMember<const Element>>& shadow_template_elements)
+ : web_delegate_(web_delegate),
+ shadow_template_elements_(shadow_template_elements),
+ popup_overlays_skipped_(false) {}
+
+bool FrameSerializerDelegateImpl::ShouldIgnoreElement(const Element& element) {
+ if (ShouldIgnoreHiddenElement(element))
+ return true;
+ if (ShouldIgnoreMetaElement(element))
+ return true;
+ if (web_delegate_.RemovePopupOverlay() &&
+ ShouldIgnorePopupOverlayElement(element)) {
+ return true;
+ }
+ // Remove <link> for stylesheets that do not load.
+ auto* html_link_element = DynamicTo<HTMLLinkElement>(element);
+ if (html_link_element && html_link_element->RelAttribute().IsStyleSheet() &&
+ !html_link_element->sheet()) {
+ return true;
+ }
+ return false;
+}
+
+bool FrameSerializerDelegateImpl::ShouldIgnoreHiddenElement(
+ const Element& element) {
+ // If an iframe is in the head, it will be moved to the body when the page is
+ // being loaded. But if an iframe is injected into the head later, it will
+ // stay there and not been displayed. To prevent it from being brought to the
+ // saved page and cause it being displayed, we should not include it.
+ if (IsA<HTMLIFrameElement>(element) &&
+ Traversal<HTMLHeadElement>::FirstAncestor(element)) {
+ return true;
+ }
+
+ // Do not include the element that is marked with hidden attribute.
+ if (element.FastHasAttribute(html_names::kHiddenAttr))
+ return true;
+
+ // Do not include the hidden form element.
+ auto* html_element_element = DynamicTo<HTMLInputElement>(&element);
+ return html_element_element &&
+ html_element_element->type() == input_type_names::kHidden;
+}
+
+bool FrameSerializerDelegateImpl::ShouldIgnoreMetaElement(
+ const Element& element) {
+ // Do not include meta elements that declare Content-Security-Policy
+ // directives. They should have already been enforced when the original
+ // document is loaded. Since only the rendered resources are encapsulated in
+ // the saved MHTML page, there is no need to carry the directives. If they
+ // are still kept in the MHTML, child frames that are referred to using cid:
+ // scheme could be prevented from loading.
+ if (!IsA<HTMLMetaElement>(element))
+ return false;
+ if (!element.FastHasAttribute(html_names::kContentAttr))
+ return false;
+ const AtomicString& http_equiv =
+ element.FastGetAttribute(html_names::kHttpEquivAttr);
+ return http_equiv == "Content-Security-Policy";
+}
+
+bool FrameSerializerDelegateImpl::ShouldIgnorePopupOverlayElement(
+ const Element& element) {
+ // The element should be visible.
+ LayoutBox* box = element.GetLayoutBox();
+ if (!box)
+ return false;
+
+ // The bounding box of the element should contain center point of the
+ // viewport.
+ LocalDOMWindow* window = element.GetDocument().domWindow();
+ DCHECK(window);
+ int center_x = window->innerWidth() / 2;
+ int center_y = window->innerHeight() / 2;
+ if (Page* page = element.GetDocument().GetPage()) {
+ center_x = page->GetChromeClient().WindowToViewportScalar(
+ window->GetFrame(), center_x);
+ center_y = page->GetChromeClient().WindowToViewportScalar(
+ window->GetFrame(), center_y);
+ }
+ LayoutPoint center_point(center_x, center_y);
+ if (!box->FrameRect().Contains(center_point))
+ return false;
+
+ // The z-index should be greater than the threshold.
+ if (box->Style()->ZIndex() < kPopupOverlayZIndexThreshold)
+ return false;
+
+ popup_overlays_skipped_ = true;
+
+ return true;
+}
+
+bool FrameSerializerDelegateImpl::ShouldIgnoreAttribute(
+ const Element& element,
+ const Attribute& attribute) {
+ // TODO(fgorski): Presence of srcset attribute causes MHTML to not display
+ // images, as only the value of src is pulled into the archive. Discarding
+ // srcset prevents the problem. Long term we should make sure to MHTML plays
+ // nicely with srcset.
+ if (IsA<HTMLImageElement>(element) &&
+ (attribute.LocalName() == html_names::kSrcsetAttr ||
+ attribute.LocalName() == html_names::kSizesAttr)) {
+ return true;
+ }
+
+ // Do not save ping attribute since anyway the ping will be blocked from
+ // MHTML.
+ if (IsA<HTMLAnchorElement>(element) &&
+ attribute.LocalName() == html_names::kPingAttr) {
+ return true;
+ }
+
+ // The special attribute in a template element to denote the shadow DOM
+ // should only be generated from MHTML serialization. If it is found in the
+ // original page, it should be ignored.
+ if (IsA<HTMLTemplateElement>(element) &&
+ (attribute.LocalName() == kShadowModeAttributeName ||
+ attribute.LocalName() == kShadowDelegatesFocusAttributeName) &&
+ !shadow_template_elements_.Contains(&element)) {
+ return true;
+ }
+
+ // If srcdoc attribute for frame elements will be rewritten as src attribute
+ // containing link instead of html contents, don't ignore the attribute.
+ // Bail out now to avoid the check in Element::isScriptingAttribute.
+ bool is_src_doc_attribute = IsA<HTMLFrameElementBase>(element) &&
+ attribute.GetName() == html_names::kSrcdocAttr;
+ String new_link_for_the_element;
+ if (is_src_doc_attribute && RewriteLink(element, new_link_for_the_element))
+ return false;
+
+ // Drop integrity attribute for those links with subresource loaded.
+ auto* html_link_element = DynamicTo<HTMLLinkElement>(element);
+ if (attribute.LocalName() == html_names::kIntegrityAttr &&
+ html_link_element && html_link_element->sheet()) {
+ return true;
+ }
+
+ // Do not include attributes that contain javascript. This is because the
+ // script will not be executed when a MHTML page is being loaded.
+ return element.IsScriptingAttribute(attribute);
+}
+
+bool FrameSerializerDelegateImpl::RewriteLink(const Element& element,
+ String& rewritten_link) {
+ auto* frame_owner = DynamicTo<HTMLFrameOwnerElement>(element);
+ if (!frame_owner)
+ return false;
+
+ Frame* frame = frame_owner->ContentFrame();
+ if (!frame)
+ return false;
+
+ WebString content_id = GetContentID(frame);
+ KURL cid_uri = MHTMLParser::ConvertContentIDToURI(content_id);
+ DCHECK(cid_uri.IsValid());
+ rewritten_link = cid_uri.GetString();
+ return true;
+}
+
+bool FrameSerializerDelegateImpl::ShouldSkipResourceWithURL(const KURL& url) {
+ return web_delegate_.ShouldSkipResource(url);
+}
+
+Vector<Attribute> FrameSerializerDelegateImpl::GetCustomAttributes(
+ const Element& element) {
+ Vector<Attribute> attributes;
+
+ if (auto* image = DynamicTo<HTMLImageElement>(element)) {
+ GetCustomAttributesForImageElement(*image, &attributes);
+ }
+
+ return attributes;
+}
+
+bool FrameSerializerDelegateImpl::ShouldCollectProblemMetric() {
+ return web_delegate_.UsePageProblemDetectors();
+}
+
+void FrameSerializerDelegateImpl::GetCustomAttributesForImageElement(
+ const HTMLImageElement& element,
+ Vector<Attribute>* attributes) {
+ // Currently only the value of src is pulled into the archive and the srcset
+ // attribute is ignored (see shouldIgnoreAttribute() above). If the device
+ // has a higher DPR, a different image from srcset could be loaded instead.
+ // When this occurs, we should provide the rendering width and height for
+ // <img> element if not set.
+
+ // The image should be loaded and participate the layout.
+ ImageResourceContent* image = element.CachedImage();
+ if (!image || !image->HasImage() || image->ErrorOccurred() ||
+ !element.GetLayoutObject()) {
+ return;
+ }
+
+ // The width and height attributes should not be set.
+ if (element.FastHasAttribute(html_names::kWidthAttr) ||
+ element.FastHasAttribute(html_names::kHeightAttr)) {
+ return;
+ }
+
+ // Check if different image is loaded. naturalWidth/naturalHeight will return
+ // the image size adjusted with current DPR.
+ if ((static_cast<int>(element.naturalWidth())) ==
+ image->GetImage()->width() &&
+ (static_cast<int>(element.naturalHeight())) ==
+ image->GetImage()->height()) {
+ return;
+ }
+
+ Attribute width_attribute(html_names::kWidthAttr,
+ AtomicString::Number(element.LayoutBoxWidth()));
+ attributes->push_back(width_attribute);
+ Attribute height_attribute(html_names::kHeightAttr,
+ AtomicString::Number(element.LayoutBoxHeight()));
+ attributes->push_back(height_attribute);
+}
+
+std::pair<Node*, Element*> FrameSerializerDelegateImpl::GetAuxiliaryDOMTree(
+ const Element& element) const {
+ ShadowRoot* shadow_root = element.GetShadowRoot();
+ if (!shadow_root)
+ return std::pair<Node*, Element*>();
+
+ String shadow_mode;
+ switch (shadow_root->GetType()) {
+ case ShadowRootType::kUserAgent:
+ // No need to serialize.
+ return std::pair<Node*, Element*>();
+ case ShadowRootType::V0:
+ shadow_mode = "v0";
+ break;
+ case ShadowRootType::kOpen:
+ shadow_mode = "open";
+ break;
+ case ShadowRootType::kClosed:
+ shadow_mode = "closed";
+ break;
+ }
+
+ // Put the shadow DOM content inside a template element. A special attribute
+ // is set to tell the mode of the shadow DOM.
+ auto* template_element = MakeGarbageCollected<Element>(
+ html_names::kTemplateTag, &(element.GetDocument()));
+ template_element->setAttribute(
+ QualifiedName(g_null_atom, kShadowModeAttributeName, g_null_atom),
+ AtomicString(shadow_mode));
+ if (shadow_root->GetType() != ShadowRootType::V0 &&
+ shadow_root->delegatesFocus()) {
+ template_element->setAttribute(
+ QualifiedName(g_null_atom, kShadowDelegatesFocusAttributeName,
+ g_null_atom),
+ g_empty_atom);
+ }
+ shadow_template_elements_.insert(template_element);
+
+ return std::pair<Node*, Element*>(shadow_root, template_element);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.h b/chromium/third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.h
new file mode 100644
index 00000000000..d9c82cfa0e5
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.h
@@ -0,0 +1,62 @@
+// 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_FRAME_SERIALIZER_DELEGATE_IMPL_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_FRAME_SERIALIZER_DELEGATE_IMPL_H_
+
+#include "third_party/blink/renderer/core/frame/frame_serializer.h"
+
+#include "third_party/blink/public/web/web_frame_serializer.h"
+#include "third_party/blink/renderer/core/dom/element.h"
+#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
+#include "third_party/blink/renderer/platform/heap/member.h"
+
+namespace blink {
+
+class Frame;
+class KURL;
+class HTMLImageElement;
+
+// An implementation of FrameSerializer's delegate which is used to serialize a
+// frame to a MHTML file.
+class FrameSerializerDelegateImpl final : public FrameSerializer::Delegate {
+ STACK_ALLOCATED();
+
+ public:
+ // Returns a Content-ID to be used for the given frame.
+ // See rfc2557 - section 8.3 - "Use of the Content-ID header and CID URLs".
+ // Format note - the returned string should be of the form "<foo@bar.com>"
+ // (i.e. the strings should include the angle brackets).
+ static String GetContentID(Frame* frame);
+
+ FrameSerializerDelegateImpl(WebFrameSerializer::MHTMLPartsGenerationDelegate&,
+ HeapHashSet<WeakMember<const Element>>&);
+ ~FrameSerializerDelegateImpl() override = default;
+
+ // FrameSerializer::Delegate implementation.
+ bool ShouldIgnoreElement(const Element&) override;
+ bool ShouldIgnoreAttribute(const Element&, const Attribute&) override;
+ bool RewriteLink(const Element&, String& rewritten_link) override;
+ bool ShouldSkipResourceWithURL(const KURL&) override;
+ Vector<Attribute> GetCustomAttributes(const Element&) override;
+ std::pair<Node*, Element*> GetAuxiliaryDOMTree(const Element&) const override;
+ bool ShouldCollectProblemMetric() override;
+
+ private:
+ bool ShouldIgnoreHiddenElement(const Element&);
+ bool ShouldIgnoreMetaElement(const Element&);
+ bool ShouldIgnorePopupOverlayElement(const Element&);
+ void GetCustomAttributesForImageElement(const HTMLImageElement&,
+ Vector<Attribute>*);
+
+ WebFrameSerializer::MHTMLPartsGenerationDelegate& web_delegate_;
+ HeapHashSet<WeakMember<const Element>>& shadow_template_elements_;
+ bool popup_overlays_skipped_;
+
+ DISALLOW_COPY_AND_ASSIGN(FrameSerializerDelegateImpl);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_FRAME_SERIALIZER_DELEGATE_IMPL_H_
diff --git a/chromium/third_party/blink/renderer/core/frame/frame_test.cc b/chromium/third_party/blink/renderer/core/frame/frame_test.cc
index 56ff72a8b44..13084aa51a7 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_test.cc
+++ b/chromium/third_party/blink/renderer/core/frame/frame_test.cc
@@ -20,9 +20,9 @@ class FrameTest : public PageTestBase {
PageTestBase::SetUp();
Navigate("https://example.com/", false);
- ASSERT_FALSE(GetDocument().GetFrame()->HasBeenActivated());
+ ASSERT_FALSE(GetDocument().GetFrame()->HasStickyUserActivation());
ASSERT_FALSE(
- GetDocument().GetFrame()->HasReceivedUserGestureBeforeNavigation());
+ GetDocument().GetFrame()->HadStickyUserActivationBeforeNavigation());
}
void Navigate(const String& destinationUrl, bool user_activated) {
@@ -51,115 +51,115 @@ class FrameTest : public PageTestBase {
TEST_F(FrameTest, NoGesture) {
// A nullptr LocalFrame* will not set user gesture state.
LocalFrame::NotifyUserActivation(nullptr);
- EXPECT_FALSE(GetDocument().GetFrame()->HasBeenActivated());
+ EXPECT_FALSE(GetDocument().GetFrame()->HasStickyUserActivation());
}
TEST_F(FrameTest, PossiblyExisting) {
// A non-null LocalFrame* will set state, but a subsequent nullptr Document*
// token will not override it.
LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
- EXPECT_TRUE(GetDocument().GetFrame()->HasBeenActivated());
+ EXPECT_TRUE(GetDocument().GetFrame()->HasStickyUserActivation());
LocalFrame::NotifyUserActivation(nullptr);
- EXPECT_TRUE(GetDocument().GetFrame()->HasBeenActivated());
+ EXPECT_TRUE(GetDocument().GetFrame()->HasStickyUserActivation());
}
TEST_F(FrameTest, NavigateDifferentDomain) {
LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
- EXPECT_TRUE(GetDocument().GetFrame()->HasBeenActivated());
+ EXPECT_TRUE(GetDocument().GetFrame()->HasStickyUserActivation());
EXPECT_FALSE(
- GetDocument().GetFrame()->HasReceivedUserGestureBeforeNavigation());
+ GetDocument().GetFrame()->HadStickyUserActivationBeforeNavigation());
// Navigate to a different Document. In the main frame, user gesture state
// will get reset. State will not persist since the domain has changed.
NavigateDifferentDomain();
- EXPECT_FALSE(GetDocument().GetFrame()->HasBeenActivated());
+ EXPECT_FALSE(GetDocument().GetFrame()->HasStickyUserActivation());
EXPECT_FALSE(
- GetDocument().GetFrame()->HasReceivedUserGestureBeforeNavigation());
+ GetDocument().GetFrame()->HadStickyUserActivationBeforeNavigation());
}
TEST_F(FrameTest, NavigateSameDomainMultipleTimes) {
LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
- EXPECT_TRUE(GetDocument().GetFrame()->HasBeenActivated());
+ EXPECT_TRUE(GetDocument().GetFrame()->HasStickyUserActivation());
EXPECT_FALSE(
- GetDocument().GetFrame()->HasReceivedUserGestureBeforeNavigation());
+ GetDocument().GetFrame()->HadStickyUserActivationBeforeNavigation());
// Navigate to a different Document in the same domain. In the main frame,
// user gesture state will get reset, but persisted state will be true.
NavigateSameDomain("page1");
- EXPECT_FALSE(GetDocument().GetFrame()->HasBeenActivated());
+ EXPECT_FALSE(GetDocument().GetFrame()->HasStickyUserActivation());
EXPECT_TRUE(
- GetDocument().GetFrame()->HasReceivedUserGestureBeforeNavigation());
+ GetDocument().GetFrame()->HadStickyUserActivationBeforeNavigation());
// Navigate to a different Document in the same domain, the persisted
// state will be true.
NavigateSameDomain("page2");
- EXPECT_FALSE(GetDocument().GetFrame()->HasBeenActivated());
+ EXPECT_FALSE(GetDocument().GetFrame()->HasStickyUserActivation());
EXPECT_TRUE(
- GetDocument().GetFrame()->HasReceivedUserGestureBeforeNavigation());
+ GetDocument().GetFrame()->HadStickyUserActivationBeforeNavigation());
// Navigate to the same URL in the same domain, the persisted state
// will be true, but the user gesture state will be reset.
NavigateSameDomain("page2");
- EXPECT_FALSE(GetDocument().GetFrame()->HasBeenActivated());
+ EXPECT_FALSE(GetDocument().GetFrame()->HasStickyUserActivation());
EXPECT_TRUE(
- GetDocument().GetFrame()->HasReceivedUserGestureBeforeNavigation());
+ GetDocument().GetFrame()->HadStickyUserActivationBeforeNavigation());
// Navigate to a different Document in the same domain, the persisted
// state will be true.
NavigateSameDomain("page3");
- EXPECT_FALSE(GetDocument().GetFrame()->HasBeenActivated());
+ EXPECT_FALSE(GetDocument().GetFrame()->HasStickyUserActivation());
EXPECT_TRUE(
- GetDocument().GetFrame()->HasReceivedUserGestureBeforeNavigation());
+ GetDocument().GetFrame()->HadStickyUserActivationBeforeNavigation());
}
TEST_F(FrameTest, NavigateSameDomainDifferentDomain) {
LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
- EXPECT_TRUE(GetDocument().GetFrame()->HasBeenActivated());
+ EXPECT_TRUE(GetDocument().GetFrame()->HasStickyUserActivation());
EXPECT_FALSE(
- GetDocument().GetFrame()->HasReceivedUserGestureBeforeNavigation());
+ GetDocument().GetFrame()->HadStickyUserActivationBeforeNavigation());
// Navigate to a different Document in the same domain. In the main frame,
// user gesture state will get reset, but persisted state will be true.
NavigateSameDomain("page1");
- EXPECT_FALSE(GetDocument().GetFrame()->HasBeenActivated());
+ EXPECT_FALSE(GetDocument().GetFrame()->HasStickyUserActivation());
EXPECT_TRUE(
- GetDocument().GetFrame()->HasReceivedUserGestureBeforeNavigation());
+ GetDocument().GetFrame()->HadStickyUserActivationBeforeNavigation());
// Navigate to a different Document in a different domain, the persisted
// state will be reset.
NavigateDifferentDomain();
- EXPECT_FALSE(GetDocument().GetFrame()->HasBeenActivated());
+ EXPECT_FALSE(GetDocument().GetFrame()->HasStickyUserActivation());
EXPECT_FALSE(
- GetDocument().GetFrame()->HasReceivedUserGestureBeforeNavigation());
+ GetDocument().GetFrame()->HadStickyUserActivationBeforeNavigation());
}
TEST_F(FrameTest, NavigateSameDomainNoGesture) {
- EXPECT_FALSE(GetDocument().GetFrame()->HasBeenActivated());
+ EXPECT_FALSE(GetDocument().GetFrame()->HasStickyUserActivation());
EXPECT_FALSE(
- GetDocument().GetFrame()->HasReceivedUserGestureBeforeNavigation());
+ GetDocument().GetFrame()->HadStickyUserActivationBeforeNavigation());
NavigateSameDomain("page1", false);
- EXPECT_FALSE(GetDocument().GetFrame()->HasBeenActivated());
+ EXPECT_FALSE(GetDocument().GetFrame()->HasStickyUserActivation());
EXPECT_FALSE(
- GetDocument().GetFrame()->HasReceivedUserGestureBeforeNavigation());
+ GetDocument().GetFrame()->HadStickyUserActivationBeforeNavigation());
}
TEST_F(FrameTest, UserActivationInterfaceTest) {
// Initially both sticky and transient bits are false.
- EXPECT_FALSE(GetDocument().GetFrame()->HasBeenActivated());
+ EXPECT_FALSE(GetDocument().GetFrame()->HasStickyUserActivation());
EXPECT_FALSE(
LocalFrame::HasTransientUserActivation(GetDocument().GetFrame()));
LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
// Now both sticky and transient bits are true, hence consumable.
- EXPECT_TRUE(GetDocument().GetFrame()->HasBeenActivated());
+ EXPECT_TRUE(GetDocument().GetFrame()->HasStickyUserActivation());
EXPECT_TRUE(LocalFrame::HasTransientUserActivation(GetDocument().GetFrame()));
EXPECT_TRUE(
LocalFrame::ConsumeTransientUserActivation(GetDocument().GetFrame()));
// After consumption, only the transient bit resets to false.
- EXPECT_TRUE(GetDocument().GetFrame()->HasBeenActivated());
+ EXPECT_TRUE(GetDocument().GetFrame()->HasStickyUserActivation());
EXPECT_FALSE(
LocalFrame::HasTransientUserActivation(GetDocument().GetFrame()));
EXPECT_FALSE(
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 a76c3434b3c..e3a9ffc405a 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
@@ -34,9 +34,12 @@
#include <utility>
#include "base/bind.h"
+#include "base/bind_helpers.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"
#include "cc/trees/layer_tree_settings.h"
+#include "cc/trees/render_frame_metadata_observer.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/frame/frame_policy.h"
@@ -123,9 +126,7 @@ void LoadFrameDontWait(WebLocalFrame* frame, const WebURL& url) {
params->navigation_timings.fetch_start = base::TimeTicks::Now();
params->is_browser_initiated = true;
FillNavigationParamsResponse(params.get());
- impl->CommitNavigation(
- std::move(params), nullptr /* extra_data */,
- base::DoNothing::Once() /* call_before_attaching_new_document */);
+ impl->CommitNavigation(std::move(params), nullptr /* extra_data */);
}
}
@@ -142,9 +143,8 @@ void LoadHTMLString(WebLocalFrame* frame,
std::unique_ptr<WebNavigationParams> navigation_params =
WebNavigationParams::CreateWithHTMLString(html, base_url);
navigation_params->tick_clock = clock;
- impl->CommitNavigation(
- std::move(navigation_params), nullptr /* extra_data */,
- base::DoNothing::Once() /* call_before_attaching_new_document */);
+ impl->CommitNavigation(std::move(navigation_params),
+ nullptr /* extra_data */);
PumpPendingRequestsForFrameToLoad(frame);
}
@@ -160,9 +160,7 @@ void LoadHistoryItem(WebLocalFrame* frame,
params->navigation_timings.navigation_start = base::TimeTicks::Now();
params->navigation_timings.fetch_start = base::TimeTicks::Now();
FillNavigationParamsResponse(params.get());
- impl->CommitNavigation(
- std::move(params), nullptr /* extra_data */,
- base::DoNothing::Once() /* call_before_attaching_new_document */);
+ impl->CommitNavigation(std::move(params), nullptr /* extra_data */);
PumpPendingRequestsForFrameToLoad(frame);
}
@@ -235,7 +233,8 @@ WebLocalFrameImpl* CreateProvisional(WebRemoteFrame& old_frame,
std::unique_ptr<TestWebFrameClient> owned_client;
client = CreateDefaultClientIfNeeded(client, owned_client);
auto* frame = To<WebLocalFrameImpl>(WebLocalFrame::CreateProvisional(
- client, nullptr, &old_frame, FramePolicy()));
+ client, nullptr, &old_frame, FramePolicy(),
+ WebFrame::ToCoreFrame(old_frame)->Tree().GetName()));
client->Bind(frame, std::move(owned_client));
std::unique_ptr<TestWebWidgetClient> widget_client;
// Create a local root, if necessary.
@@ -243,14 +242,28 @@ WebLocalFrameImpl* CreateProvisional(WebRemoteFrame& old_frame,
widget_client = std::make_unique<TestWebWidgetClient>();
// TODO(dcheng): The main frame widget currently has a special case.
// Eliminate this once WebView is no longer a WebWidget.
- WebFrameWidget::CreateForMainFrame(widget_client.get(), frame);
+ WebFrameWidget* frame_widget = WebFrameWidget::CreateForMainFrame(
+ widget_client.get(), frame,
+ CrossVariantMojoAssociatedRemote<mojom::FrameWidgetHostInterfaceBase>(),
+ CrossVariantMojoAssociatedReceiver<mojom::FrameWidgetInterfaceBase>(),
+ CrossVariantMojoAssociatedRemote<mojom::WidgetHostInterfaceBase>(),
+ CrossVariantMojoAssociatedReceiver<mojom::WidgetInterfaceBase>());
+ widget_client->SetFrameWidget(frame_widget);
+ // The WebWidget requires the compositor to be set before it is used.
+ frame_widget->SetCompositorHosts(widget_client->layer_tree_host(),
+ widget_client->animation_host());
} else if (frame->Parent()->IsWebRemoteFrame()) {
widget_client = std::make_unique<TestWebWidgetClient>();
- WebFrameWidget* frame_widget =
- WebFrameWidget::CreateForChildLocalRoot(widget_client.get(), frame);
- // The WebWidget requires an AnimationHost to be set, either by the
- // WebWidgetClient itself or by someone else. We do that here.
- frame_widget->SetAnimationHost(widget_client->animation_host());
+ WebFrameWidget* frame_widget = WebFrameWidget::CreateForChildLocalRoot(
+ widget_client.get(), frame,
+ CrossVariantMojoAssociatedRemote<mojom::FrameWidgetHostInterfaceBase>(),
+ CrossVariantMojoAssociatedReceiver<mojom::FrameWidgetInterfaceBase>(),
+ CrossVariantMojoAssociatedRemote<mojom::WidgetHostInterfaceBase>(),
+ CrossVariantMojoAssociatedReceiver<mojom::WidgetInterfaceBase>());
+ widget_client->SetFrameWidget(frame_widget);
+ // The WebWidget requires the compositor to be set before it is used.
+ frame_widget->SetCompositorHosts(widget_client->layer_tree_host(),
+ widget_client->animation_host());
frame_widget->Resize(WebSize());
}
if (widget_client)
@@ -285,11 +298,16 @@ WebLocalFrameImpl* CreateLocalChild(WebRemoteFrame& parent,
std::unique_ptr<TestWebWidgetClient> owned_widget_client;
widget_client =
CreateDefaultClientIfNeeded(widget_client, owned_widget_client);
- WebFrameWidget* frame_widget =
- WebFrameWidget::CreateForChildLocalRoot(widget_client, frame);
- // The WebWidget requires an AnimationHost to be set, either by the
- // WebWidgetClient itself or by someone else. We do that here.
- frame_widget->SetAnimationHost(widget_client->animation_host());
+ WebFrameWidget* frame_widget = WebFrameWidget::CreateForChildLocalRoot(
+ widget_client, frame,
+ CrossVariantMojoAssociatedRemote<mojom::FrameWidgetHostInterfaceBase>(),
+ CrossVariantMojoAssociatedReceiver<mojom::FrameWidgetInterfaceBase>(),
+ CrossVariantMojoAssociatedRemote<mojom::WidgetHostInterfaceBase>(),
+ CrossVariantMojoAssociatedReceiver<mojom::WidgetInterfaceBase>());
+ // The WebWidget requires the compositor to be set before it is used.
+ frame_widget->SetCompositorHosts(widget_client->layer_tree_host(),
+ widget_client->animation_host());
+ widget_client->SetFrameWidget(frame_widget);
// Set an initial size for subframes.
if (frame->Parent())
frame_widget->Resize(WebSize());
@@ -304,7 +322,7 @@ WebRemoteFrameImpl* CreateRemoteChild(
TestWebRemoteFrameClient* client) {
std::unique_ptr<TestWebRemoteFrameClient> owned_client;
client = CreateDefaultClientIfNeeded(client, owned_client);
- auto* frame = ToWebRemoteFrameImpl(parent.CreateRemoteChild(
+ auto* frame = To<WebRemoteFrameImpl>(parent.CreateRemoteChild(
WebTreeScopeType::kDocument, name, FramePolicy(),
FrameOwnerElementType::kIframe, client,
InterfaceRegistry::GetEmptyInterfaceRegistry(),
@@ -312,8 +330,7 @@ WebRemoteFrameImpl* CreateRemoteChild(
client->Bind(frame, std::move(owned_client));
if (!security_origin)
security_origin = SecurityOrigin::CreateUniqueOpaque();
- frame->GetFrame()->GetSecurityContext()->SetReplicatedOrigin(
- std::move(security_origin));
+ frame->GetFrame()->SetReplicatedOrigin(std::move(security_origin), false);
return frame;
}
@@ -347,13 +364,18 @@ WebViewImpl* WebViewHelper::InitializeWithOpener(
test_web_widget_client_ = CreateDefaultClientIfNeeded(
web_widget_client, owned_test_web_widget_client_);
- // TODO(danakj): Make this part of attaching the main frame's WebFrameWidget.
- // This happens before CreateForMainFrame as the WebFrameWidget binding to the
- // WebLocalFrameImpl sets up animations.
- web_view_->SetAnimationHost(test_web_widget_client_->animation_host());
// TODO(dcheng): The main frame widget currently has a special case.
// Eliminate this once WebView is no longer a WebWidget.
- blink::WebFrameWidget::CreateForMainFrame(test_web_widget_client_, frame);
+ WebFrameWidget* widget = blink::WebFrameWidget::CreateForMainFrame(
+ test_web_widget_client_, frame,
+ CrossVariantMojoAssociatedRemote<mojom::FrameWidgetHostInterfaceBase>(),
+ CrossVariantMojoAssociatedReceiver<mojom::FrameWidgetInterfaceBase>(),
+ CrossVariantMojoAssociatedRemote<mojom::WidgetHostInterfaceBase>(),
+ CrossVariantMojoAssociatedReceiver<mojom::WidgetInterfaceBase>());
+ // The WebWidget requires the compositor to be set before it is used.
+ widget->SetCompositorHosts(test_web_widget_client_->layer_tree_host(),
+ test_web_widget_client_->animation_host());
+ test_web_widget_client_->SetFrameWidget(widget);
// We inform the WebView when it has a local main frame attached once the
// WebFrame it fully set up and the WebWidgetClient is initialized (which is
// the case by this point).
@@ -399,6 +421,16 @@ WebViewImpl* WebViewHelper::InitializeAndLoad(
}
WebViewImpl* WebViewHelper::InitializeRemote(
+ TestWebRemoteFrameClient* client,
+ scoped_refptr<SecurityOrigin> security_origin,
+ TestWebViewClient* web_view_client,
+ TestWebWidgetClient* web_widget_client) {
+ return InitializeRemoteWithOpener(nullptr, client, security_origin,
+ web_view_client, web_widget_client);
+}
+
+WebViewImpl* WebViewHelper::InitializeRemoteWithOpener(
+ WebFrame* opener,
TestWebRemoteFrameClient* web_remote_frame_client,
scoped_refptr<SecurityOrigin> security_origin,
TestWebViewClient* web_view_client,
@@ -413,18 +445,15 @@ WebViewImpl* WebViewHelper::InitializeRemote(
WebRemoteFrameImpl* frame = WebRemoteFrameImpl::CreateMainFrame(
web_view_, web_remote_frame_client,
InterfaceRegistry::GetEmptyInterfaceRegistry(),
- web_remote_frame_client->GetAssociatedInterfaceProvider(), nullptr);
+ web_remote_frame_client->GetAssociatedInterfaceProvider(), opener);
web_remote_frame_client->Bind(frame,
std::move(owned_web_remote_frame_client));
if (!security_origin)
security_origin = SecurityOrigin::CreateUniqueOpaque();
- frame->GetFrame()->GetSecurityContext()->SetReplicatedOrigin(
- std::move(security_origin));
+ frame->GetFrame()->SetReplicatedOrigin(std::move(security_origin), false);
test_web_widget_client_ = CreateDefaultClientIfNeeded(
web_widget_client, owned_test_web_widget_client_);
- web_view_->SetAnimationHost(test_web_widget_client_->animation_host());
-
return web_view_;
}
@@ -455,7 +484,7 @@ WebLocalFrameImpl* WebViewHelper::LocalMainFrame() const {
}
WebRemoteFrameImpl* WebViewHelper::RemoteMainFrame() const {
- return ToWebRemoteFrameImpl(web_view_->MainFrame());
+ return To<WebRemoteFrameImpl>(web_view_->MainFrame());
}
void WebViewHelper::Resize(WebSize size) {
@@ -469,7 +498,8 @@ void WebViewHelper::InitializeWebView(TestWebViewClient* web_view_client,
web_view_ = static_cast<WebViewImpl*>(
WebView::Create(test_web_view_client_,
/*is_hidden=*/false,
- /*compositing_enabled=*/true, opener));
+ /*compositing_enabled=*/true, opener,
+ mojo::ScopedInterfaceEndpointHandle()));
// This property must be set at initialization time, it is not supported to be
// changed afterward, and does nothing.
web_view_->GetSettings()->SetViewportEnabled(viewport_enabled_);
@@ -497,8 +527,7 @@ void WebViewHelper::InitializeWebView(TestWebViewClient* web_view_client,
int TestWebFrameClient::loads_in_progress_ = 0;
TestWebFrameClient::TestWebFrameClient()
- : interface_provider_(new service_manager::InterfaceProvider()),
- associated_interface_provider_(new AssociatedInterfaceProvider(nullptr)),
+ : associated_interface_provider_(new AssociatedInterfaceProvider(nullptr)),
effective_connection_type_(WebEffectiveConnectionType::kTypeUnknown) {}
TestWebFrameClient::~TestWebFrameClient() = default;
@@ -573,9 +602,7 @@ void TestWebFrameClient::CommitNavigation(
auto params = WebNavigationParams::CreateFromInfo(*info);
if (info->archive_status != WebNavigationInfo::ArchiveStatus::Present)
FillNavigationParamsResponse(params.get());
- frame_->CommitNavigation(
- std::move(params), nullptr /* extra_data */,
- base::DoNothing::Once() /* call_before_attaching_new_document */);
+ frame_->CommitNavigation(std::move(params), nullptr /* extra_data */);
}
WebEffectiveConnectionType TestWebFrameClient::GetEffectiveConnectionType() {
@@ -622,10 +649,6 @@ void TestWebRemoteFrameClient::FrameDetached(DetachType type) {
self_owned_.reset();
}
-content::LayerTreeView* LayerTreeViewFactory::Initialize() {
- return Initialize(/*delegate=*/nullptr);
-}
-
content::LayerTreeView* LayerTreeViewFactory::Initialize(
content::LayerTreeViewDelegate* specified_delegate) {
cc::LayerTreeSettings settings;
@@ -635,27 +658,22 @@ content::LayerTreeView* LayerTreeViewFactory::Initialize(
settings.use_layer_lists = true;
layer_tree_view_ = std::make_unique<content::LayerTreeView>(
- specified_delegate ? specified_delegate : &delegate_,
- Thread::Current()->GetTaskRunner(),
+ specified_delegate, Thread::Current()->GetTaskRunner(),
/*compositor_thread=*/nullptr, &test_task_graph_runner_,
&fake_thread_scheduler_);
layer_tree_view_->Initialize(settings,
std::make_unique<cc::TestUkmRecorderFactory>());
+ layer_tree_view_->SetVisible(true);
return layer_tree_view_.get();
}
-TestWebWidgetClient::TestWebWidgetClient(
- content::LayerTreeViewDelegate* delegate) {
- layer_tree_view_ = layer_tree_view_factory_.Initialize(delegate);
+TestWebWidgetClient::TestWebWidgetClient() {
+ layer_tree_view_ = layer_tree_view_factory_.Initialize(this);
animation_host_ = layer_tree_view_->animation_host();
}
-void TestWebWidgetClient::SetRootLayer(scoped_refptr<cc::Layer> layer) {
- layer_tree_host()->SetRootLayer(std::move(layer));
-}
-
-void TestWebWidgetClient::SetBackgroundColor(SkColor color) {
- layer_tree_host()->set_background_color(color);
+void TestWebWidgetClient::SetFrameWidget(WebFrameWidget* widget) {
+ frame_widget_ = widget;
}
void TestWebWidgetClient::SetPageScaleStateAndLimits(
@@ -669,7 +687,7 @@ void TestWebWidgetClient::SetPageScaleStateAndLimits(
void TestWebWidgetClient::InjectGestureScrollEvent(
WebGestureDevice device,
- const WebFloatSize& delta,
+ const gfx::Vector2dF& delta,
ScrollGranularity granularity,
cc::ElementId scrollable_area_element_id,
WebInputEvent::Type injected_type) {
@@ -678,38 +696,8 @@ void TestWebWidgetClient::InjectGestureScrollEvent(
injected_scroll_gesture_data_.push_back(data);
}
-void TestWebWidgetClient::SetHaveScrollEventHandlers(bool have_handlers) {
- have_scroll_event_handlers_ = have_handlers;
-}
-
-void TestWebWidgetClient::SetEventListenerProperties(
- cc::EventListenerClass event_class,
- cc::EventListenerProperties properties) {
- layer_tree_host()->SetEventListenerProperties(event_class, properties);
-}
-
-cc::EventListenerProperties TestWebWidgetClient::EventListenerProperties(
- cc::EventListenerClass event_class) const {
- return layer_tree_host()->event_listener_properties(event_class);
-}
-
-std::unique_ptr<cc::ScopedDeferMainFrameUpdate>
-TestWebWidgetClient::DeferMainFrameUpdate() {
- return layer_tree_host()->DeferMainFrameUpdate();
-}
-
-void TestWebWidgetClient::StartDeferringCommits(base::TimeDelta timeout) {
- layer_tree_host()->StartDeferringCommits(timeout);
-}
-
-void TestWebWidgetClient::StopDeferringCommits(
- cc::PaintHoldingCommitTrigger trigger) {
- layer_tree_host()->StopDeferringCommits(trigger);
-}
-
-void TestWebWidgetClient::RegisterSelection(
- const cc::LayerSelection& selection) {
- layer_tree_host()->RegisterSelection(selection);
+bool TestWebWidgetClient::HaveScrollEventHandlers() const {
+ return layer_tree_host()->have_scroll_event_handlers();
}
void TestWebWidgetClient::DidMeaningfulLayout(
@@ -727,18 +715,32 @@ void TestWebWidgetClient::DidMeaningfulLayout(
}
}
-void TestWebWidgetClient::SetBrowserControlsShownRatio(float top_ratio,
- float bottom_ratio) {
- layer_tree_host()->SetBrowserControlsShownRatio(top_ratio, bottom_ratio);
+viz::FrameSinkId TestWebWidgetClient::GetFrameSinkId() {
+ return viz::FrameSinkId();
+}
+
+void TestWebWidgetClient::BeginMainFrame(base::TimeTicks frame_time) {
+ frame_widget_->BeginFrame(frame_time);
}
-void TestWebWidgetClient::SetBrowserControlsParams(
- cc::BrowserControlsParams params) {
- layer_tree_host()->SetBrowserControlsParams(params);
+void TestWebWidgetClient::DidBeginMainFrame() {
+ frame_widget_->DidBeginFrame();
}
-viz::FrameSinkId TestWebWidgetClient::GetFrameSinkId() {
- return viz::FrameSinkId();
+void TestWebWidgetClient::UpdateVisualState() {
+ frame_widget_->UpdateVisualState();
+}
+
+void TestWebWidgetClient::ApplyViewportChanges(
+ const ApplyViewportChangesArgs& args) {
+ frame_widget_->ApplyViewportChanges(args);
+}
+
+void TestWebWidgetClient::RequestNewLayerTreeFrameSink(
+ LayerTreeFrameSinkCallback callback) {
+ // Make a valid LayerTreeFrameSink so the compositor will generate begin main
+ // frames.
+ std::move(callback).Run(cc::FakeLayerTreeFrameSink::Create3d(), nullptr);
}
void TestWebViewClient::DestroyChildViews() {
@@ -750,7 +752,7 @@ WebView* TestWebViewClient::CreateView(WebLocalFrame* opener,
const WebWindowFeatures&,
const WebString& name,
WebNavigationPolicy,
- WebSandboxFlags,
+ mojom::blink::WebSandboxFlags,
const FeaturePolicy::FeatureState&,
const SessionStorageNamespaceId&) {
auto webview_helper = std::make_unique<WebViewHelper>();
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 5181fbf3ad6..35504d96582 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
@@ -42,12 +42,11 @@
#include "cc/trees/layer_tree_host.h"
#include "content/renderer/compositor/layer_tree_view.h"
#include "content/test/stub_layer_tree_view_delegate.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/common/frame/frame_owner_element_type.h"
+#include "third_party/blink/public/common/input/web_mouse_event.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink-forward.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/scheduler/test/web_fake_thread_scheduler.h"
-#include "third_party/blink/public/platform/web_mouse_event.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/web/web_frame_owner_properties.h"
@@ -186,59 +185,44 @@ class LayerTreeViewFactory {
DISALLOW_NEW();
public:
- // Use this to make a LayerTreeView with a stub delegate.
- content::LayerTreeView* Initialize();
// Use this to specify a delegate instead of using a stub.
content::LayerTreeView* Initialize(content::LayerTreeViewDelegate*);
private:
- content::StubLayerTreeViewDelegate delegate_;
cc::TestTaskGraphRunner test_task_graph_runner_;
blink::scheduler::WebFakeThreadScheduler fake_thread_scheduler_;
std::unique_ptr<content::LayerTreeView> layer_tree_view_;
};
struct InjectedScrollGestureData {
- WebFloatSize delta;
+ gfx::Vector2dF delta;
ScrollGranularity granularity;
CompositorElementId scrollable_area_element_id;
WebInputEvent::Type type;
};
-class TestWebWidgetClient : public WebWidgetClient {
+class TestWebWidgetClient : public WebWidgetClient,
+ public content::StubLayerTreeViewDelegate {
public:
- // If no delegate is given, a stub is used.
- explicit TestWebWidgetClient(content::LayerTreeViewDelegate* = nullptr);
+ TestWebWidgetClient();
~TestWebWidgetClient() override = default;
+ // This method must be called just after the allocation of |widget| and
+ // before usage of this class occurs.
+ void SetFrameWidget(WebFrameWidget* widget);
+
// WebWidgetClient implementation.
void ScheduleAnimation() override { animation_scheduled_ = true; }
- void SetRootLayer(scoped_refptr<cc::Layer> layer) override;
- void RegisterSelection(const cc::LayerSelection& selection) override;
- void SetBackgroundColor(SkColor color) override;
void SetPageScaleStateAndLimits(float page_scale_factor,
bool is_pinch_gesture_active,
float minimum,
float maximum) override;
void InjectGestureScrollEvent(WebGestureDevice device,
- const WebFloatSize& delta,
+ const gfx::Vector2dF& delta,
ScrollGranularity granularity,
cc::ElementId scrollable_area_element_id,
WebInputEvent::Type injected_type) override;
- void SetHaveScrollEventHandlers(bool) override;
- void SetEventListenerProperties(
- cc::EventListenerClass event_class,
- cc::EventListenerProperties properties) override;
- cc::EventListenerProperties EventListenerProperties(
- cc::EventListenerClass event_class) const override;
- std::unique_ptr<cc::ScopedDeferMainFrameUpdate> DeferMainFrameUpdate()
- override;
- void StartDeferringCommits(base::TimeDelta timeout) override;
- void StopDeferringCommits(cc::PaintHoldingCommitTrigger) override;
void DidMeaningfulLayout(WebMeaningfulLayout) override;
- void SetBrowserControlsShownRatio(float top_ratio,
- float bottom_ratio) override;
- void SetBrowserControlsParams(cc::BrowserControlsParams) override;
viz::FrameSinkId GetFrameSinkId() override;
cc::LayerTreeHost* layer_tree_host() {
@@ -249,11 +233,10 @@ class TestWebWidgetClient : public WebWidgetClient {
}
cc::AnimationHost* animation_host() { return animation_host_; }
- bool AnimationScheduled() { return animation_scheduled_; }
+ bool AnimationScheduled() const { return animation_scheduled_; }
void ClearAnimationScheduled() { animation_scheduled_ = false; }
- // Returns the last value given to SetHaveScrollEventHandlers().
- bool HaveScrollEventHandlers() const { return have_scroll_event_handlers_; }
+ bool HaveScrollEventHandlers() const;
int VisuallyNonEmptyLayoutCount() const {
return visually_non_empty_layout_count_;
@@ -269,13 +252,22 @@ class TestWebWidgetClient : public WebWidgetClient {
return injected_scroll_gesture_data_;
}
+ protected:
+ // LayerTreeViewDelegate implementation.
+ void BeginMainFrame(base::TimeTicks frame_time) override;
+ void DidBeginMainFrame() override;
+ void UpdateVisualState() override;
+ void ApplyViewportChanges(const ApplyViewportChangesArgs& args) override;
+ void RequestNewLayerTreeFrameSink(
+ LayerTreeFrameSinkCallback callback) override;
+
private:
+ WebFrameWidget* frame_widget_ = nullptr;
content::LayerTreeView* layer_tree_view_ = nullptr;
cc::AnimationHost* animation_host_ = nullptr;
LayerTreeViewFactory layer_tree_view_factory_;
Vector<InjectedScrollGestureData> injected_scroll_gesture_data_;
bool animation_scheduled_ = false;
- bool have_scroll_event_handlers_ = false;
int visually_non_empty_layout_count_ = 0;
int finished_parsing_layout_count_ = 0;
int finished_loading_layout_count_ = 0;
@@ -296,7 +288,7 @@ class TestWebViewClient : public WebViewClient {
const WebWindowFeatures&,
const WebString& name,
WebNavigationPolicy,
- WebSandboxFlags,
+ mojom::blink::WebSandboxFlags,
const FeaturePolicy::FeatureState&,
const SessionStorageNamespaceId&) override;
@@ -348,14 +340,22 @@ class WebViewHelper : public ScopedMockOverlayScrollbars {
TestWebWidgetClient* = nullptr,
void (*update_settings_func)(WebSettings*) = nullptr);
- // Creates and initializes the WebView with a main WebRemoteFrame. Passing
- // nullptr as the SecurityOrigin results in a frame with a unique security
- // origin.
+ // Same as InitializeRemoteWithOpener(), but always sets the opener to null.
WebViewImpl* InitializeRemote(TestWebRemoteFrameClient* = nullptr,
scoped_refptr<SecurityOrigin> = nullptr,
TestWebViewClient* = nullptr,
TestWebWidgetClient* = nullptr);
+ // Creates and initializes the WebView with a main WebRemoteFrame. Passing
+ // nullptr as the SecurityOrigin results in a frame with a unique security
+ // origin.
+ WebViewImpl* InitializeRemoteWithOpener(
+ WebFrame* opener,
+ TestWebRemoteFrameClient* = nullptr,
+ scoped_refptr<SecurityOrigin> = nullptr,
+ TestWebViewClient* = nullptr,
+ TestWebWidgetClient* = nullptr);
+
// Load the 'Ahem' font to this WebView.
// The 'Ahem' font is the only font whose font metrics is consistent across
// platforms, but it's not guaranteed to be available.
@@ -432,9 +432,6 @@ class TestWebFrameClient : public WebLocalFrameClient {
FrameOwnerElementType) override;
void DidStartLoading() override;
void DidStopLoading() override;
- service_manager::InterfaceProvider* GetInterfaceProvider() override {
- return interface_provider_.get();
- }
std::unique_ptr<blink::WebURLLoaderFactory> CreateURLLoaderFactory()
override {
// TODO(kinuko,toyoshim): Stop using Platform's URLLoaderFactory, but create
@@ -461,10 +458,6 @@ class TestWebFrameClient : public WebLocalFrameClient {
// If set to a non-null value, self-deletes on frame detach.
std::unique_ptr<TestWebFrameClient> self_owned_;
- // Use service_manager::InterfaceProvider::TestApi to provide test interfaces
- // through this client.
- std::unique_ptr<service_manager::InterfaceProvider> interface_provider_;
-
std::unique_ptr<AssociatedInterfaceProvider> associated_interface_provider_;
// This is null from when the client is created until it is initialized with
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 b7eae97648b..e52d60795fb 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_view.cc
+++ b/chromium/third_party/blink/renderer/core/frame/frame_view.cc
@@ -30,7 +30,7 @@ bool FrameView::CanThrottleRenderingForPropagation() const {
return false;
Frame& frame = GetFrame();
LayoutEmbeddedContent* owner = frame.OwnerLayoutObject();
- return !owner && frame.IsCrossOriginSubframe();
+ return !owner && frame.IsCrossOriginToMainFrame();
}
bool FrameView::DisplayLockedInParentFrame() {
@@ -42,18 +42,21 @@ bool FrameView::DisplayLockedInParentFrame() {
return owner && DisplayLockUtilities::NearestLockedInclusiveAncestor(*owner);
}
-void FrameView::UpdateViewportIntersection(unsigned flags,
+bool FrameView::UpdateViewportIntersection(unsigned flags,
bool needs_occlusion_tracking) {
+ bool can_skip_sticky_frame_tracking =
+ flags & IntersectionObservation::kCanSkipStickyFrameTracking;
+
if (!(flags & IntersectionObservation::kImplicitRootObserversNeedUpdate))
- return;
+ return can_skip_sticky_frame_tracking;
// This should only run in child frames.
Frame& frame = GetFrame();
HTMLFrameOwnerElement* owner_element = frame.DeprecatedLocalOwner();
if (!owner_element)
- return;
+ return can_skip_sticky_frame_tracking;
Document& owner_document = owner_element->GetDocument();
IntPoint viewport_offset;
- IntRect viewport_intersection;
+ IntRect viewport_intersection, mainframe_document_intersection;
DocumentLifecycle::LifecycleState parent_lifecycle_state =
owner_document.Lifecycle().GetState();
FrameOcclusionState occlusion_state =
@@ -103,23 +106,52 @@ void FrameView::UpdateViewportIntersection(unsigned flags,
PhysicalOffset content_box_offset =
owner_layout_object->PhysicalContentBoxOffset();
- if (NeedsViewportOffset()) {
- viewport_offset =
- RoundedIntPoint(owner_layout_object->LocalToAbsolutePoint(
- content_box_offset,
- kTraverseDocumentBoundaries | kApplyRemoteRootFrameOffset));
+ if (NeedsViewportOffset() || !can_skip_sticky_frame_tracking) {
+ 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
+ // to the space of the iframe's contents.
+ TransformState parent_frame_to_iframe_content_transform(
+ TransformState::kUnapplyInverseTransformDirection);
+ // First transform to box coordinates of the iframe element...
+ owner_layout_object->MapAncestorToLocal(
+ nullptr, parent_frame_to_iframe_content_transform, 0);
+ // ... then apply content_box_offset to translate to the coordinate of the
+ // child frame.
+ parent_frame_to_iframe_content_transform.Move(
+ owner_layout_object->PhysicalContentBoxOffset());
+ TransformationMatrix matrix =
+ parent_frame_to_iframe_content_transform.AccumulatedTransform()
+ .Inverse();
if (geometry.IsIntersecting()) {
- // geometry.IntersectionRect() is in the coordinate system of the document
- // containing the iframe. First map it down to border-box coordinates for
- // the iframe, then apply content_box_offset to translate to the
- // coordinates of the child frame.
- PhysicalRect intersection_rect = owner_layout_object->AncestorToLocalRect(
- nullptr, geometry.IntersectionRect());
- intersection_rect.Move(-content_box_offset);
-
- // Don't let EnclosingIntRect turn an empty rect into a non-empty one.
+ PhysicalRect intersection_rect = PhysicalRect::EnclosingRect(
+ matrix.ProjectQuad(FloatRect(geometry.IntersectionRect()))
+ .BoundingBox());
+
+ // Don't let EnclosingRect turn an empty rect into a non-empty one.
if (intersection_rect.IsEmpty()) {
viewport_intersection =
IntRect(FlooredIntPoint(intersection_rect.offset), IntSize());
@@ -127,6 +159,21 @@ void FrameView::UpdateViewportIntersection(unsigned flags,
viewport_intersection = EnclosingIntRect(intersection_rect);
}
}
+
+ PhysicalRect mainframe_intersection_rect;
+ if (!geometry.UnclippedIntersectionRect().IsEmpty()) {
+ mainframe_intersection_rect = PhysicalRect::EnclosingRect(
+ matrix.ProjectQuad(FloatRect(geometry.UnclippedIntersectionRect()))
+ .BoundingBox());
+
+ if (mainframe_intersection_rect.IsEmpty()) {
+ mainframe_document_intersection = IntRect(
+ FlooredIntPoint(mainframe_intersection_rect.offset), IntSize());
+ } else {
+ mainframe_document_intersection =
+ EnclosingIntRect(mainframe_intersection_rect);
+ }
+ }
} else if (occlusion_state == FrameOcclusionState::kGuaranteedNotOccluded) {
// If the parent LocalFrameView is throttled and out-of-date, then we can't
// get any useful information.
@@ -134,10 +181,17 @@ void FrameView::UpdateViewportIntersection(unsigned flags,
}
SetViewportIntersection(
- {viewport_offset, viewport_intersection, WebRect(), occlusion_state});
+ {viewport_offset, viewport_intersection, mainframe_document_intersection,
+ WebRect(), occlusion_state, frame.GetMainFrameViewportSize(),
+ frame.GetMainFrameScrollOffset(), can_skip_sticky_frame_tracking});
UpdateFrameVisibility(!viewport_intersection.IsEmpty());
+ if (ShouldReportMainFrameIntersection()) {
+ GetFrame().Client()->OnMainFrameDocumentIntersectionChanged(
+ mainframe_document_intersection);
+ }
+
// We don't throttle 0x0 or display:none iframes, because in practice they are
// sometimes used to drive UI logic.
bool hidden_for_throttling = viewport_intersection.IsEmpty() &&
@@ -149,6 +203,7 @@ void 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) {
@@ -204,4 +259,10 @@ 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 64991d0ad30..aa5e42ac59a 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_view.h
+++ b/chromium/third_party/blink/renderer/core/frame/frame_view.h
@@ -8,6 +8,7 @@
#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"
@@ -16,7 +17,11 @@ namespace blink {
class Frame;
struct IntrinsicSizingInfo;
-class CORE_EXPORT FrameView : public EmbeddedContentView {
+// 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 {
public:
FrameView(const IntRect& frame_rect) : EmbeddedContentView(frame_rect) {}
~FrameView() override = default;
@@ -39,6 +44,7 @@ class CORE_EXPORT FrameView : public EmbeddedContentView {
bool CanThrottleRenderingForPropagation() const;
bool IsFrameView() const override { return true; }
+ virtual bool ShouldReportMainFrameIntersection() const { return false; }
Frame& GetFrame() const;
blink::mojom::FrameVisibility GetFrameVisibility() const {
@@ -61,7 +67,8 @@ class CORE_EXPORT FrameView : public EmbeddedContentView {
const ViewportIntersectionState& intersection_state) = 0;
virtual void VisibilityForThrottlingChanged() = 0;
virtual bool LifecycleUpdatesThrottled() const { return false; }
- void UpdateViewportIntersection(unsigned, bool);
+ // Returns whether we can skip tracking sticky frames.
+ bool UpdateViewportIntersection(unsigned, bool);
// FrameVisibility is tracked by the browser process, which may suppress
// lifecycle updates for a frame outside the viewport.
void UpdateFrameVisibility(bool);
@@ -71,12 +78,15 @@ class CORE_EXPORT FrameView : public EmbeddedContentView {
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 1d3be31f8d3..ea22088c7f5 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
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/frame/frame_view_auto_size_info.h"
#include "base/auto_reset.h"
+#include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink.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/layout/layout_box.h"
@@ -18,7 +19,7 @@ FrameViewAutoSizeInfo::FrameViewAutoSizeInfo(LocalFrameView* view)
DCHECK(frame_view_);
}
-void FrameViewAutoSizeInfo::Trace(blink::Visitor* visitor) {
+void FrameViewAutoSizeInfo::Trace(Visitor* visitor) {
visitor->Trace(frame_view_);
}
@@ -63,7 +64,7 @@ void FrameViewAutoSizeInfo::AutoSizeIfNeeded() {
// second iteration.
for (int i = 0; i < 2; i++) {
// Update various sizes including contentsSize, scrollHeight, etc.
- document->UpdateStyleAndLayout();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kSizeChange);
auto* layout_view = document->GetLayoutView();
if (!layout_view)
@@ -72,7 +73,7 @@ void FrameViewAutoSizeInfo::AutoSizeIfNeeded() {
// TODO(bokan): This code doesn't handle subpixel sizes correctly. Because
// of that, it's forced to maintain all the special ScrollbarMode code
// below. https://crbug.com/812311.
- int width = layout_view->MinPreferredLogicalWidth().ToInt();
+ int width = layout_view->PreferredLogicalWidths().min_size.ToInt();
LayoutBox* document_layout_box = document_element->GetLayoutBox();
if (!document_layout_box)
@@ -92,7 +93,7 @@ void FrameViewAutoSizeInfo::AutoSizeIfNeeded() {
// already greater the maximum.
} else if (new_size.Height() > max_auto_size_.Height() &&
// If we have a real vertical scrollbar, it's already included in
- // MinPreferredLogicalWidth, so don't add a hypothetical one.
+ // PreferredLogicalWidths(), so don't add a hypothetical one.
!layout_viewport->HasVerticalScrollbar()) {
new_size.Expand(
layout_viewport->HypotheticalScrollbarThickness(kVerticalScrollbar),
@@ -106,15 +107,17 @@ void FrameViewAutoSizeInfo::AutoSizeIfNeeded() {
// Bound the dimensions by the max bounds and determine what scrollbars to
// show.
- ScrollbarMode horizontal_scrollbar_mode = ScrollbarMode::kAlwaysOff;
+ mojom::blink::ScrollbarMode horizontal_scrollbar_mode =
+ mojom::blink::ScrollbarMode::kAlwaysOff;
if (new_size.Width() > max_auto_size_.Width()) {
new_size.SetWidth(max_auto_size_.Width());
- horizontal_scrollbar_mode = ScrollbarMode::kAlwaysOn;
+ horizontal_scrollbar_mode = mojom::blink::ScrollbarMode::kAlwaysOn;
}
- ScrollbarMode vertical_scrollbar_mode = ScrollbarMode::kAlwaysOff;
+ mojom::blink::ScrollbarMode vertical_scrollbar_mode =
+ mojom::blink::ScrollbarMode::kAlwaysOff;
if (new_size.Height() > max_auto_size_.Height()) {
new_size.SetHeight(max_auto_size_.Height());
- vertical_scrollbar_mode = ScrollbarMode::kAlwaysOn;
+ vertical_scrollbar_mode = mojom::blink::ScrollbarMode::kAlwaysOn;
}
if (new_size == size)
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 c66b4c26227..b83e4ecbbd9 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(blink::Visitor*);
+ void Trace(Visitor*);
private:
Member<LocalFrameView> frame_view_;
diff --git a/chromium/third_party/blink/renderer/core/frame/fullscreen_controller.cc b/chromium/third_party/blink/renderer/core/frame/fullscreen_controller.cc
index a55fa4c9786..3a19bd8bd4a 100644
--- a/chromium/third_party/blink/renderer/core/frame/fullscreen_controller.cc
+++ b/chromium/third_party/blink/renderer/core/frame/fullscreen_controller.cc
@@ -33,14 +33,15 @@
#include "base/memory/ptr_util.h"
#include "third_party/blink/public/mojom/frame/fullscreen.mojom-blink.h"
#include "third_party/blink/public/web/web_local_frame_client.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_fullscreen_options.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/exported/web_view_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/page_scale_constraints_set.h"
+#include "third_party/blink/renderer/core/frame/screen.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/fullscreen/fullscreen_options.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/page/spatial_navigation.h"
@@ -60,29 +61,16 @@ void FullscreenController::DidEnterFullscreen() {
return;
UpdatePageScaleConstraints(false);
- web_view_base_->SetPageScaleFactor(1.0f);
- web_view_base_->SetVisualViewportOffset(FloatPoint());
- state_ = State::kFullscreen;
-
- // Notify all pending local frames in order that we have entered fullscreen.
- for (LocalFrame* frame : *pending_frames_) {
- if (frame) {
- if (Document* document = frame->GetDocument())
- Fullscreen::DidEnterFullscreen(*document);
- }
+ // Only reset the scale for the local main frame.
+ if (web_view_base_->MainFrameImpl()) {
+ web_view_base_->SetPageScaleFactor(1.0f);
+ web_view_base_->SetVisualViewportOffset(FloatPoint());
}
- // Notify all local frames that we have entered fullscreen.
- for (Frame* frame = web_view_base_->GetPage()->MainFrame(); frame;
- frame = frame->Tree().TraverseNext()) {
- auto* local_frame = DynamicTo<LocalFrame>(frame);
- if (!local_frame)
- continue;
- if (Document* document = local_frame->GetDocument())
- Fullscreen::DidEnterFullscreen(*document);
- }
- pending_frames_->clear();
+ state_ = State::kFullscreen;
+
+ NotifyFramesOfFullscreenEntry(true /* success */);
// TODO(foolip): If the top level browsing context (main frame) ends up with
// no fullscreen element, exit fullscreen again to recover.
@@ -123,7 +111,8 @@ void FullscreenController::DidExitFullscreen() {
}
void FullscreenController::EnterFullscreen(LocalFrame& frame,
- const FullscreenOptions* options) {
+ const FullscreenOptions* options,
+ bool for_cross_process_descendant) {
// TODO(dtapuska): If we are already in fullscreen. If the options are
// different than the currently requested one we may wish to request
// fullscreen mode again.
@@ -157,8 +146,23 @@ void FullscreenController::EnterFullscreen(LocalFrame& frame,
return;
DCHECK(state_ == State::kInitial);
- frame.GetLocalFrameHostRemote().EnterFullscreen(
- mojom::blink::FullscreenOptions::New(options->navigationUI() != "hide"));
+ auto fullscreen_options = mojom::blink::FullscreenOptions::New();
+ fullscreen_options->prefers_navigation_bar =
+ options->navigationUI() != "hide";
+ if (options->hasScreen()) {
+ DCHECK(RuntimeEnabledFeatures::WindowPlacementEnabled());
+ if (options->screen()->DisplayId() != Screen::kInvalidDisplayId)
+ fullscreen_options->display_id = options->screen()->DisplayId();
+ }
+
+ // Don't send redundant EnterFullscreen message to the browser for the
+ // ancestor frames if the subframe has already entered fullscreen.
+ if (!for_cross_process_descendant) {
+ frame.GetLocalFrameHostRemote().EnterFullscreen(
+ std::move(fullscreen_options),
+ WTF::Bind(&FullscreenController::EnterFullscreenCallback,
+ WTF::Unretained(this)));
+ }
state_ = State::kEnteringFullscreen;
}
@@ -233,6 +237,40 @@ void FullscreenController::RestoreBackgroundColorOverride() {
}
}
+void FullscreenController::NotifyFramesOfFullscreenEntry(bool granted) {
+ // Notify all pending local frames in order whether or not we successfully
+ // entered fullscreen.
+ for (LocalFrame* frame : *pending_frames_) {
+ if (frame) {
+ if (Document* document = frame->GetDocument()) {
+ Fullscreen::DidResolveEnterFullscreenRequest(*document, granted);
+ }
+ }
+ }
+
+ // Notify all local frames whether or not we successfully entered fullscreen.
+ for (Frame* frame = web_view_base_->GetPage()->MainFrame(); frame;
+ frame = frame->Tree().TraverseNext()) {
+ auto* local_frame = DynamicTo<LocalFrame>(frame);
+ if (!local_frame)
+ continue;
+ if (Document* document = local_frame->GetDocument()) {
+ Fullscreen::DidResolveEnterFullscreenRequest(*document, granted);
+ }
+ }
+ pending_frames_->clear();
+}
+
+void FullscreenController::EnterFullscreenCallback(bool granted) {
+ if (granted) {
+ // If the fullscreen is granted, then the VisualPropertiesUpdated message
+ // will later be fired and the state will be updated then.
+ } else {
+ state_ = State::kInitial;
+ NotifyFramesOfFullscreenEntry(false /* granted */);
+ }
+}
+
void FullscreenController::UpdateSize() {
DCHECK(web_view_base_->GetPage());
diff --git a/chromium/third_party/blink/renderer/core/frame/fullscreen_controller.h b/chromium/third_party/blink/renderer/core/frame/fullscreen_controller.h
index 726ac9aa872..c24aa660d65 100644
--- a/chromium/third_party/blink/renderer/core/frame/fullscreen_controller.h
+++ b/chromium/third_party/blink/renderer/core/frame/fullscreen_controller.h
@@ -58,7 +58,9 @@ class CORE_EXPORT FullscreenController {
// Called by Fullscreen (via ChromeClient) to request entering or exiting
// fullscreen.
- void EnterFullscreen(LocalFrame&, const FullscreenOptions*);
+ void EnterFullscreen(LocalFrame&,
+ const FullscreenOptions*,
+ bool for_cross_process_descendant);
void ExitFullscreen(LocalFrame&);
// Called by content::RenderWidget (via WebWidget) to notify that we've
@@ -79,6 +81,10 @@ class CORE_EXPORT FullscreenController {
void UpdatePageScaleConstraints(bool reset_constraints);
void RestoreBackgroundColorOverride();
+ void NotifyFramesOfFullscreenEntry(bool granted);
+
+ void EnterFullscreenCallback(bool granted);
+
WebViewImpl* web_view_base_;
// State is used to avoid unnecessary enter/exit requests.
diff --git a/chromium/third_party/blink/renderer/core/frame/history.cc b/chromium/third_party/blink/renderer/core/frame/history.cc
index e5871ef46e7..8a9110005b6 100644
--- a/chromium/third_party/blink/renderer/core/frame/history.cc
+++ b/chromium/third_party/blink/renderer/core/frame/history.cc
@@ -38,6 +38,7 @@
#include "third_party/blink/renderer/core/page/page.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/heap/heap.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -62,7 +63,7 @@ bool EqualIgnoringQueryAndFragment(const KURL& a, const KURL& b) {
History::History(LocalFrame* frame)
: DOMWindowClient(frame), last_state_object_requested_(nullptr) {}
-void History::Trace(blink::Visitor* visitor) {
+void History::Trace(Visitor* visitor) {
ScriptWrappable::Trace(visitor);
DOMWindowClient::Trace(visitor);
}
@@ -77,15 +78,19 @@ unsigned History::length(ExceptionState& exception_state) const {
return GetFrame()->Client()->BackForwardLength();
}
-SerializedScriptValue* History::state(ExceptionState& exception_state) {
+ScriptValue History::state(v8::Isolate* isolate,
+ ExceptionState& exception_state) {
if (!GetFrame()) {
exception_state.ThrowSecurityError(
"May not use a History object associated with a Document that is not "
"fully active");
- return nullptr;
+ return ScriptValue::CreateNull(isolate);
}
last_state_object_requested_ = StateInternal();
- return last_state_object_requested_.get();
+ if (!last_state_object_requested_)
+ return ScriptValue::CreateNull(isolate);
+ return ScriptValue(isolate,
+ last_state_object_requested_->Deserialize(isolate));
}
SerializedScriptValue* History::StateInternal() const {
@@ -180,7 +185,7 @@ void History::go(ScriptState* script_state,
DCHECK(IsMainThread());
Document* active_document =
- To<Document>(ExecutionContext::From(script_state));
+ Document::From(ExecutionContext::From(script_state));
if (!active_document)
return;
@@ -195,9 +200,10 @@ void History::go(ScriptState* script_state,
return;
if (delta) {
- if (Page* page = GetFrame()->GetPage())
- page->HistoryNavigationVirtualTimePauser().PauseVirtualTime();
- GetFrame()->Client()->NavigateBackForward(delta);
+ if (GetFrame()->Client()->NavigateBackForward(delta)) {
+ if (Page* page = GetFrame()->GetPage())
+ page->HistoryNavigationVirtualTimePauser().PauseVirtualTime();
+ }
} else {
// We intentionally call reload() for the current frame if delta is zero.
// Otherwise, navigation happens on the root frame.
@@ -207,19 +213,52 @@ void History::go(ScriptState* script_state,
}
}
-void History::pushState(scoped_refptr<SerializedScriptValue> data,
+void History::pushState(v8::Isolate* isolate,
+ const ScriptValue& data,
const String& title,
const String& url,
ExceptionState& exception_state) {
- StateObjectAdded(std::move(data), title, url, ScrollRestorationInternal(),
- WebFrameLoadType::kStandard, exception_state);
+ WebFrameLoadType load_type = WebFrameLoadType::kStandard;
+ // Navigations in portal contexts do not create back/forward entries.
+ if (GetFrame() && GetFrame()->GetPage() &&
+ GetFrame()->GetPage()->InsidePortal()) {
+ GetFrame()->GetDocument()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning,
+ "Use of history.pushState in a portal context "
+ "is treated as history.replaceState."),
+ /* discard_duplicates */ true);
+ load_type = WebFrameLoadType::kReplaceCurrentItem;
+ }
+
+ scoped_refptr<SerializedScriptValue> serialized_data =
+ SerializedScriptValue::Serialize(isolate, data.V8Value(),
+ SerializedScriptValue::SerializeOptions(
+ SerializedScriptValue::kForStorage),
+ exception_state);
+ if (exception_state.HadException())
+ return;
+
+ StateObjectAdded(std::move(serialized_data), title, url,
+ ScrollRestorationInternal(), load_type, exception_state);
}
-void History::replaceState(scoped_refptr<SerializedScriptValue> data,
+void History::replaceState(v8::Isolate* isolate,
+ const ScriptValue& data,
const String& title,
const String& url,
ExceptionState& exception_state) {
- StateObjectAdded(std::move(data), title, url, ScrollRestorationInternal(),
+ scoped_refptr<SerializedScriptValue> serialized_data =
+ SerializedScriptValue::Serialize(isolate, data.V8Value(),
+ SerializedScriptValue::SerializeOptions(
+ SerializedScriptValue::kForStorage),
+ exception_state);
+ if (exception_state.HadException())
+ return;
+
+ StateObjectAdded(std::move(serialized_data), title, url,
+ ScrollRestorationInternal(),
WebFrameLoadType::kReplaceCurrentItem, exception_state);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/history.h b/chromium/third_party/blink/renderer/core/frame/history.h
index 2c3af98a16f..a08a0f66f40 100644
--- a/chromium/third_party/blink/renderer/core/frame/history.h
+++ b/chromium/third_party/blink/renderer/core/frame/history.h
@@ -29,7 +29,7 @@
#include "base/gtest_prod_util.h"
#include "third_party/blink/public/web/web_frame_load_type.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/loader/frame_loader_types.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -53,18 +53,20 @@ class CORE_EXPORT History final : public ScriptWrappable,
explicit History(LocalFrame*);
unsigned length(ExceptionState&) const;
- SerializedScriptValue* state(ExceptionState&);
+ ScriptValue state(v8::Isolate*, ExceptionState&);
void back(ScriptState*, ExceptionState&);
void forward(ScriptState*, ExceptionState&);
void go(ScriptState*, int delta, ExceptionState&);
- void pushState(scoped_refptr<SerializedScriptValue>,
+ void pushState(v8::Isolate* isolate,
+ const ScriptValue& data,
const String& title,
const String& url,
ExceptionState&);
- void replaceState(scoped_refptr<SerializedScriptValue> data,
+ void replaceState(v8::Isolate* isolate,
+ const ScriptValue& data,
const String& title,
const String& url,
ExceptionState& exception_state);
@@ -75,7 +77,7 @@ class CORE_EXPORT History final : public ScriptWrappable,
bool stateChanged() const;
bool IsSameAsCurrentState(SerializedScriptValue*) const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 87f36912142..a2b8ebd6d6a 100644
--- a/chromium/third_party/blink/renderer/core/frame/history.idl
+++ b/chromium/third_party/blink/renderer/core/frame/history.idl
@@ -32,11 +32,10 @@ enum ScrollRestoration {"auto", "manual"};
] interface History {
[MeasureAs=HistoryLength, RaisesException] readonly attribute unsigned long length;
[Measure, RaisesException] attribute ScrollRestoration scrollRestoration;
- // TODO(foolip): The SerializedScriptValue type should be any.
- [CachedAttribute=stateChanged, RaisesException] readonly attribute SerializedScriptValue state;
+ [CachedAttribute=stateChanged, CallWith=Isolate, RaisesException] readonly attribute any state;
[CallWith=ScriptState, RaisesException] void go(optional long delta = 0);
[CallWith=ScriptState, RaisesException] void back();
[CallWith=ScriptState, RaisesException] void forward();
- [MeasureAs=HistoryPushState, RaisesException] void pushState(SerializedScriptValue data, DOMString title, optional DOMString? url = null);
- [MeasureAs=HistoryReplaceState, RaisesException] void replaceState(SerializedScriptValue data, DOMString title, optional DOMString? url = null);
+ [CallWith=Isolate, MeasureAs=HistoryPushState, RaisesException] void pushState(any data, DOMString title, optional DOMString? url = null);
+ [CallWith=Isolate, MeasureAs=HistoryReplaceState, RaisesException] void replaceState(any data, DOMString title, optional DOMString? url = null);
};
diff --git a/chromium/third_party/blink/renderer/core/frame/hosts_using_features.cc b/chromium/third_party/blink/renderer/core/frame/hosts_using_features.cc
deleted file mode 100644
index cc91ef2f41d..00000000000
--- a/chromium/third_party/blink/renderer/core/frame/hosts_using_features.cc
+++ /dev/null
@@ -1,172 +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/frame/hosts_using_features.h"
-
-#include "third_party/blink/public/platform/platform.h"
-#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/frame/local_dom_window.h"
-#include "third_party/blink/renderer/core/page/page.h"
-#include "third_party/blink/renderer/platform/bindings/script_state.h"
-
-namespace blink {
-
-HostsUsingFeatures::~HostsUsingFeatures() {
- UpdateMeasurementsAndClear();
-}
-
-HostsUsingFeatures::Value::Value() : count_bits_(0) {}
-
-void HostsUsingFeatures::CountAnyWorld(Document& document, Feature feature) {
- document.HostsUsingFeaturesValue().Count(feature);
-}
-
-void HostsUsingFeatures::CountMainWorldOnly(const ScriptState* script_state,
- Document& document,
- Feature feature) {
- if (!script_state || !script_state->World().IsMainWorld())
- return;
- CountAnyWorld(document, feature);
-}
-
-static Document* DocumentFromEventTarget(EventTarget& target) {
- ExecutionContext* execution_context = target.GetExecutionContext();
- if (!execution_context)
- return nullptr;
- if (auto* document = DynamicTo<Document>(execution_context))
- return document;
- if (LocalDOMWindow* executing_window = execution_context->ExecutingWindow())
- return executing_window->document();
- return nullptr;
-}
-
-void HostsUsingFeatures::CountHostOrIsolatedWorldHumanReadableName(
- const ScriptState* script_state,
- EventTarget& target,
- Feature feature) {
- if (!script_state)
- return;
- Document* document = DocumentFromEventTarget(target);
- if (!document)
- return;
- if (script_state->World().IsMainWorld()) {
- document->HostsUsingFeaturesValue().Count(feature);
- return;
- }
-}
-
-void HostsUsingFeatures::Value::Count(Feature feature) {
- DCHECK(feature < Feature::kNumberOfFeatures);
- count_bits_ |= 1 << static_cast<unsigned>(feature);
-}
-
-void HostsUsingFeatures::Clear() {
- url_and_values_.clear();
-}
-
-void HostsUsingFeatures::DocumentDetached(Document& document) {
- HostsUsingFeatures::Value counter = document.HostsUsingFeaturesValue();
- if (counter.IsEmpty())
- return;
-
- const KURL& url = document.Url();
- if (!url.ProtocolIsInHTTPFamily())
- return;
-
- url_and_values_.push_back(std::make_pair(url, counter));
- document.HostsUsingFeaturesValue().Clear();
- DCHECK(document.HostsUsingFeaturesValue().IsEmpty());
-}
-
-void HostsUsingFeatures::UpdateMeasurementsAndClear() {
- if (!url_and_values_.IsEmpty()) {
- RecordHostToRappor();
- RecordETLDPlus1ToRappor();
- url_and_values_.clear();
- }
-}
-
-void HostsUsingFeatures::RecordHostToRappor() {
- DCHECK(!url_and_values_.IsEmpty());
-
- // Aggregate values by hosts.
- HashMap<String, HostsUsingFeatures::Value> aggregated_by_host;
- for (const auto& url_and_value : url_and_values_) {
- DCHECK(!url_and_value.first.IsEmpty());
- auto result = aggregated_by_host.insert(url_and_value.first.Host(),
- url_and_value.second);
- if (!result.is_new_entry)
- result.stored_value->value.Aggregate(url_and_value.second);
- }
-
- // Report to RAPPOR.
- for (auto& host_and_value : aggregated_by_host)
- host_and_value.value.RecordHostToRappor(host_and_value.key);
-}
-
-void HostsUsingFeatures::RecordETLDPlus1ToRappor() {
- DCHECK(!url_and_values_.IsEmpty());
-
- // Aggregate values by URL.
- HashMap<String, HostsUsingFeatures::Value> aggregated_by_url;
- for (const auto& url_and_value : url_and_values_) {
- DCHECK(!url_and_value.first.IsEmpty());
- auto result =
- aggregated_by_url.insert(url_and_value.first, url_and_value.second);
- if (!result.is_new_entry)
- result.stored_value->value.Aggregate(url_and_value.second);
- }
-
- // Report to RAPPOR.
- for (auto& url_and_value : aggregated_by_url)
- url_and_value.value.RecordETLDPlus1ToRappor(KURL(url_and_value.key));
-}
-
-void HostsUsingFeatures::Value::Aggregate(HostsUsingFeatures::Value other) {
- count_bits_ |= other.count_bits_;
-}
-
-void HostsUsingFeatures::Value::RecordHostToRappor(const String& host) {
- if (Get(Feature::kFullscreenInsecureHost))
- Platform::Current()->RecordRappor(
- "PowerfulFeatureUse.Host.Fullscreen.Insecure", host);
- if (Get(Feature::kGeolocationInsecureHost))
- Platform::Current()->RecordRappor(
- "PowerfulFeatureUse.Host.Geolocation.Insecure", host);
- if (Get(Feature::kApplicationCacheManifestSelectInsecureHost))
- Platform::Current()->RecordRappor(
- "PowerfulFeatureUse.Host.ApplicationCacheManifestSelect.Insecure",
- host);
- if (Get(Feature::kApplicationCacheAPIInsecureHost))
- Platform::Current()->RecordRappor(
- "PowerfulFeatureUse.Host.ApplicationCacheAPI.Insecure", host);
-}
-
-void HostsUsingFeatures::Value::RecordETLDPlus1ToRappor(const KURL& url) {
- if (Get(Feature::kGetUserMediaInsecureHost))
- Platform::Current()->RecordRapporURL(
- "PowerfulFeatureUse.ETLDPlus1.GetUserMedia.Insecure", WebURL(url));
- if (Get(Feature::kGetUserMediaSecureHost))
- Platform::Current()->RecordRapporURL(
- "PowerfulFeatureUse.ETLDPlus1.GetUserMedia.Secure", WebURL(url));
- if (Get(Feature::kRTCPeerConnectionAudio))
- Platform::Current()->RecordRapporURL("RTCPeerConnection.Audio",
- WebURL(url));
- if (Get(Feature::kRTCPeerConnectionVideo))
- Platform::Current()->RecordRapporURL("RTCPeerConnection.Video",
- WebURL(url));
- if (Get(Feature::kRTCPeerConnectionDataChannel))
- Platform::Current()->RecordRapporURL("RTCPeerConnection.DataChannel",
- WebURL(url));
- if (Get(Feature::kRTCPeerConnectionUsed) &&
- !Get(Feature::kRTCPeerConnectionAudio) &&
- !Get(Feature::kRTCPeerConnectionVideo) &&
- !Get(Feature::kRTCPeerConnectionDataChannel)) {
- Platform::Current()->RecordRapporURL("RTCPeerConnection.Unconnected",
- WebURL(url));
- }
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/hosts_using_features.h b/chromium/third_party/blink/renderer/core/frame/hosts_using_features.h
deleted file mode 100644
index ce681b51c78..00000000000
--- a/chromium/third_party/blink/renderer/core/frame/hosts_using_features.h
+++ /dev/null
@@ -1,93 +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_FRAME_HOSTS_USING_FEATURES_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_HOSTS_USING_FEATURES_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/weborigin/kurl.h"
-#include "third_party/blink/renderer/platform/wtf/hash_map.h"
-#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
-
-namespace blink {
-
-class Document;
-class EventTarget;
-class ScriptState;
-
-class CORE_EXPORT HostsUsingFeatures {
- DISALLOW_NEW();
-
- public:
- ~HostsUsingFeatures();
-
- // Features for RAPPOR. Do not reorder or remove!
- enum class Feature {
- kElementCreateShadowRoot_Unused,
- kDocumentRegisterElement_Unused,
- kEventPath_Unused,
- kDeviceMotionInsecureHost_Unused,
- kDeviceOrientationInsecureHost_Unused,
- kFullscreenInsecureHost,
- kGeolocationInsecureHost,
- kGetUserMediaInsecureHost,
- kGetUserMediaSecureHost,
- kElementAttachShadow_Unused,
- kApplicationCacheManifestSelectInsecureHost,
- kApplicationCacheAPIInsecureHost,
- kRTCPeerConnectionAudio,
- kRTCPeerConnectionVideo,
- kRTCPeerConnectionDataChannel,
- kRTCPeerConnectionUsed, // Used to compute the "unconnected PCs" feature
-
- kNumberOfFeatures // This must be the last item.
- };
-
- static void CountAnyWorld(Document&, Feature);
- static void CountMainWorldOnly(const ScriptState*, Document&, Feature);
- static void CountHostOrIsolatedWorldHumanReadableName(const ScriptState*,
- EventTarget&,
- Feature);
-
- void DocumentDetached(Document&);
- void UpdateMeasurementsAndClear();
-
- class CORE_EXPORT Value {
- DISALLOW_NEW();
-
- public:
- Value();
-
- bool IsEmpty() const { return !count_bits_; }
- void Clear() { count_bits_ = 0; }
-
- void Count(Feature);
- bool Get(Feature feature) const {
- return count_bits_ & (1 << static_cast<unsigned>(feature));
- }
-
- void Aggregate(Value);
- void RecordHostToRappor(const String& host);
- void RecordETLDPlus1ToRappor(const KURL&);
-
- private:
- unsigned count_bits_ : static_cast<unsigned>(Feature::kNumberOfFeatures);
- };
-
- void Clear();
-
- private:
- void RecordHostToRappor();
- void RecordNamesToRappor();
- void RecordETLDPlus1ToRappor();
-
- Vector<std::pair<KURL, HostsUsingFeatures::Value>, 1> url_and_values_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_HOSTS_USING_FEATURES_H_
diff --git a/chromium/third_party/blink/renderer/core/frame/intervention.cc b/chromium/third_party/blink/renderer/core/frame/intervention.cc
index 443beec1b02..e7737916d6b 100644
--- a/chromium/third_party/blink/renderer/core/frame/intervention.cc
+++ b/chromium/third_party/blink/renderer/core/frame/intervention.cc
@@ -13,6 +13,7 @@
#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/inspector/console_message.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
@@ -25,9 +26,9 @@ void Intervention::GenerateReport(const LocalFrame* frame,
// Send the message to the console.
Document* document = frame->GetDocument();
- document->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kIntervention,
- mojom::ConsoleMessageLevel::kError, message));
+ document->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kIntervention,
+ mojom::ConsoleMessageLevel::kError, message));
if (!frame->Client())
return;
@@ -40,7 +41,7 @@ void Intervention::GenerateReport(const LocalFrame* frame,
// Send the intervention report to the Reporting API and any
// ReportingObservers.
- ReportingContext::From(document)->QueueReport(report);
+ ReportingContext::From(document->ToExecutionContext())->QueueReport(report);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/intervention_report_body.h b/chromium/third_party/blink/renderer/core/frame/intervention_report_body.h
index 3b7fdfb4a11..47f7ec8818a 100644
--- a/chromium/third_party/blink/renderer/core/frame/intervention_report_body.h
+++ b/chromium/third_party/blink/renderer/core/frame/intervention_report_body.h
@@ -20,8 +20,8 @@ class CORE_EXPORT InterventionReportBody : public LocationReportBody {
~InterventionReportBody() override = default;
- String id() const { return id_; }
- String message() const { return message_; }
+ const String& id() const { return id_; }
+ const String& message() const { return message_; }
void BuildJSONValue(V8ObjectBuilder& builder) const override;
private:
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 29d229558bd..558e2a8b2da 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
@@ -30,6 +30,7 @@
#include <utility>
#include "cc/input/snap_selection_strategy.h"
+#include "third_party/blink/public/common/browser_interface_broker_proxy.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_screen_info.h"
@@ -37,6 +38,7 @@
#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/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"
#include "third_party/blink/renderer/bindings/core/v8/window_proxy.h"
#include "third_party/blink/renderer/core/accessibility/ax_context.h"
@@ -50,17 +52,20 @@
#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"
#include "third_party/blink/renderer/core/dom/frame_request_callback_collection.h"
+#include "third_party/blink/renderer/core/dom/scriptable_document_parser.h"
#include "third_party/blink/renderer/core/dom/scripted_idle_task_controller.h"
-#include "third_party/blink/renderer/core/dom/sink_document.h"
#include "third_party/blink/renderer/core/editing/editor.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#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/context_lifecycle_observer.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"
#include "third_party/blink/renderer/core/frame/bar_prop.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/dom_visual_viewport.h"
@@ -74,16 +79,17 @@
#include "third_party/blink/renderer/core/frame/navigator.h"
#include "third_party/blink/renderer/core/frame/sandbox_flags.h"
#include "third_party/blink/renderer/core/frame/screen.h"
-#include "third_party/blink/renderer/core/frame/scroll_to_options.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#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/custom/custom_element_registry.h"
#include "third_party/blink/renderer/core/html/forms/form_controller.h"
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
+#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_trace_events.h"
+#include "third_party/blink/renderer/core/inspector/main_thread_debugger.h"
#include "third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/loader/appcache/application_cache.h"
@@ -105,8 +111,11 @@
#include "third_party/blink/renderer/platform/bindings/microtask.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/wtf/cross_thread_functional.h"
namespace blink {
@@ -212,6 +221,7 @@ static void UntrackAllBeforeUnloadEventListeners(LocalDOMWindow* dom_window) {
LocalDOMWindow::LocalDOMWindow(LocalFrame& frame)
: DOMWindow(frame),
+ ExecutionContext(V8PerIsolateData::MainThreadIsolate()),
visualViewport_(MakeGarbageCollected<DOMVisualViewport>(this)),
unused_preloads_timer_(frame.GetTaskRunner(TaskType::kInternalDefault),
this,
@@ -244,8 +254,7 @@ TrustedTypePolicyFactory* LocalDOMWindow::trustedTypes() const {
return trusted_types_.Get();
}
-Document* LocalDOMWindow::CreateDocument(const String& mime_type,
- const DocumentInit& init,
+Document* LocalDOMWindow::CreateDocument(const DocumentInit& init,
bool force_xhtml) {
Document* document = nullptr;
if (force_xhtml) {
@@ -253,14 +262,7 @@ Document* LocalDOMWindow::CreateDocument(const String& mime_type,
// XSLTProcessor::createDocumentFromSource().
document = MakeGarbageCollected<Document>(init);
} else {
- document = DOMImplementation::createDocument(
- mime_type, init,
- init.GetFrame() ? init.GetFrame()->InViewSourceMode() : false);
- if (document->IsPluginDocument() &&
- document->IsSandboxed(WebSandboxFlags::kPlugins)) {
- // document->Shutdown();
- document = MakeGarbageCollected<SinkDocument>(init);
- }
+ document = DOMImplementation::createDocument(init);
}
return document;
@@ -271,16 +273,203 @@ LocalDOMWindow* LocalDOMWindow::From(const ScriptState* script_state) {
return blink::ToLocalDOMWindow(script_state->GetContext());
}
-Document* LocalDOMWindow::InstallNewDocument(const String& mime_type,
- const DocumentInit& init,
+bool LocalDOMWindow::IsContextThread() const {
+ return IsMainThread();
+}
+
+bool LocalDOMWindow::ShouldInstallV8Extensions() const {
+ return GetFrame()->Client()->AllowScriptExtensions();
+}
+
+ContentSecurityPolicy* LocalDOMWindow::GetContentSecurityPolicyForWorld() {
+ return document()->GetContentSecurityPolicyForWorld();
+}
+
+const KURL& LocalDOMWindow::Url() const {
+ return document()->Url();
+}
+
+const KURL& LocalDOMWindow::BaseURL() const {
+ return document()->BaseURL();
+}
+
+KURL LocalDOMWindow::CompleteURL(const String& url) const {
+ return document()->CompleteURL(url);
+}
+
+void LocalDOMWindow::DisableEval(const String& error_message) {
+ if (GetFrame())
+ GetFrame()->GetScriptController().DisableEval(error_message);
+}
+
+String LocalDOMWindow::UserAgent() const {
+ return document()->UserAgent();
+}
+
+HttpsState LocalDOMWindow::GetHttpsState() const {
+ return document()->GetHttpsState();
+}
+
+ResourceFetcher* LocalDOMWindow::Fetcher() const {
+ return document()->Fetcher();
+}
+
+SecurityContext& LocalDOMWindow::GetSecurityContext() {
+ return document()->GetSecurityContext();
+}
+
+const SecurityContext& LocalDOMWindow::GetSecurityContext() const {
+ return document()->GetSecurityContext();
+}
+
+bool LocalDOMWindow::CanExecuteScripts(
+ ReasonForCallingCanExecuteScripts reason) {
+ return document()->CanExecuteScripts(reason);
+}
+
+void LocalDOMWindow::ExceptionThrown(ErrorEvent* event) {
+ MainThreadDebugger::Instance()->ExceptionThrown(this, event);
+}
+
+String LocalDOMWindow::OutgoingReferrer() const {
+ return document()->OutgoingReferrer();
+}
+
+network::mojom::ReferrerPolicy LocalDOMWindow::GetReferrerPolicy() const {
+ network::mojom::ReferrerPolicy policy = ExecutionContext::GetReferrerPolicy();
+ // For srcdoc documents without their own policy, walk up the frame
+ // tree to find the document that is either not a srcdoc or doesn't
+ // have its own policy. This algorithm is defined in
+ // https://html.spec.whatwg.org/C/#set-up-a-window-environment-settings-object.
+ if (!GetFrame() || policy != network::mojom::ReferrerPolicy::kDefault ||
+ !document()->IsSrcdocDocument()) {
+ return policy;
+ }
+ LocalFrame* frame = To<LocalFrame>(GetFrame()->Tree().Parent());
+ return frame->DomWindow()->GetReferrerPolicy();
+}
+
+CoreProbeSink* LocalDOMWindow::GetProbeSink() {
+ return document()->GetProbeSink();
+}
+
+BrowserInterfaceBrokerProxy& LocalDOMWindow::GetBrowserInterfaceBroker() {
+ if (!GetFrame())
+ return GetEmptyBrowserInterfaceBroker();
+
+ return GetFrame()->GetBrowserInterfaceBroker();
+}
+
+FrameOrWorkerScheduler* LocalDOMWindow::GetScheduler() {
+ if (GetFrame())
+ return GetFrame()->GetFrameScheduler();
+ if (!detached_scheduler_)
+ detached_scheduler_ = scheduler::CreateDummyFrameScheduler();
+ return detached_scheduler_.get();
+}
+
+scoped_refptr<base::SingleThreadTaskRunner> LocalDOMWindow::GetTaskRunner(
+ TaskType type) {
+ return document()->GetTaskRunner(type);
+}
+
+void LocalDOMWindow::CountPotentialFeaturePolicyViolation(
+ mojom::blink::FeaturePolicyFeature feature) const {
+ document()->CountPotentialFeaturePolicyViolation(feature);
+}
+
+void LocalDOMWindow::ReportFeaturePolicyViolation(
+ mojom::blink::FeaturePolicyFeature feature,
+ mojom::blink::PolicyDisposition disposition,
+ const String& message,
+ const String& source_file) const {
+ document()->ReportFeaturePolicyViolation(feature, disposition, message,
+ source_file);
+}
+
+void LocalDOMWindow::ReportDocumentPolicyViolation(
+ mojom::blink::DocumentPolicyFeature feature,
+ mojom::blink::PolicyDisposition disposition,
+ const String& message,
+ const String& source_file) const {
+ document()->ReportDocumentPolicyViolation(feature, disposition, message,
+ source_file);
+}
+
+static void RunAddConsoleMessageTask(mojom::ConsoleMessageSource source,
+ mojom::ConsoleMessageLevel level,
+ const String& message,
+ LocalDOMWindow* window,
+ bool discard_duplicates) {
+ window->AddConsoleMessageImpl(
+ MakeGarbageCollected<ConsoleMessage>(source, level, message),
+ discard_duplicates);
+}
+
+void LocalDOMWindow::AddConsoleMessageImpl(ConsoleMessage* console_message,
+ bool discard_duplicates) {
+ if (!IsContextThread()) {
+ PostCrossThreadTask(
+ *GetTaskRunner(TaskType::kInternalInspector), FROM_HERE,
+ CrossThreadBindOnce(
+ &RunAddConsoleMessageTask, console_message->Source(),
+ console_message->Level(), console_message->Message(),
+ WrapCrossThreadPersistent(this), discard_duplicates));
+ return;
+ }
+
+ if (!GetFrame())
+ return;
+
+ if (document() && console_message->Location()->IsUnknown()) {
+ // TODO(dgozman): capture correct location at call places instead.
+ unsigned line_number = 0;
+ if (!document()->IsInDocumentWrite() &&
+ document()->GetScriptableDocumentParser()) {
+ ScriptableDocumentParser* parser =
+ document()->GetScriptableDocumentParser();
+ if (parser->IsParsingAtLineNumber())
+ line_number = parser->LineNumber().OneBasedInt();
+ }
+ Vector<DOMNodeId> nodes(console_message->Nodes());
+ console_message = MakeGarbageCollected<ConsoleMessage>(
+ console_message->Source(), console_message->Level(),
+ console_message->Message(),
+ std::make_unique<SourceLocation>(Url().GetString(), line_number, 0,
+ nullptr));
+ console_message->SetNodes(GetFrame(), std::move(nodes));
+ }
+
+ GetFrame()->Console().AddMessage(console_message, discard_duplicates);
+}
+
+void LocalDOMWindow::CountUse(mojom::WebFeature feature) {
+ if (!GetFrame())
+ return;
+ if (auto* loader = GetFrame()->Loader().GetDocumentLoader())
+ loader->CountUse(feature);
+}
+
+void LocalDOMWindow::CountDeprecation(mojom::WebFeature feature) {
+ document()->CountDeprecation(feature);
+}
+
+Document* LocalDOMWindow::InstallNewDocument(const DocumentInit& init,
bool force_xhtml) {
DCHECK_EQ(init.GetFrame(), GetFrame());
ClearDocument();
- document_ = CreateDocument(mime_type, init, force_xhtml);
+ document_ = CreateDocument(init, force_xhtml);
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_;
@@ -288,7 +477,8 @@ Document* LocalDOMWindow::InstallNewDocument(const String& mime_type,
document_->GetViewportData().UpdateViewportDescription();
if (FrameScheduler* frame_scheduler = GetFrame()->GetFrameScheduler()) {
frame_scheduler->TraceUrlChange(document_->Url().GetString());
- frame_scheduler->SetCrossOrigin(GetFrame()->IsCrossOriginSubframe());
+ frame_scheduler->SetCrossOriginToMainFrame(
+ GetFrame()->IsCrossOriginToMainFrame());
}
if (GetFrame()->GetPage() && GetFrame()->View()) {
@@ -414,7 +604,7 @@ void LocalDOMWindow::Dispose() {
}
ExecutionContext* LocalDOMWindow::GetExecutionContext() const {
- return document_.Get();
+ return const_cast<LocalDOMWindow*>(this);
}
const LocalDOMWindow* LocalDOMWindow::ToLocalDOMWindow() const {
@@ -431,6 +621,13 @@ MediaQueryList* LocalDOMWindow::matchMedia(const String& media) {
}
void LocalDOMWindow::FrameDestroyed() {
+ // 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();
+ NotifyContextDestroyed();
RemoveAllEventListeners();
DisconnectFromFrame();
}
@@ -442,7 +639,6 @@ void LocalDOMWindow::RegisterEventListenerObserver(
void LocalDOMWindow::Reset() {
DCHECK(document());
- DCHECK(document()->IsContextDestroyed());
FrameDestroyed();
screen_ = nullptr;
@@ -561,6 +757,8 @@ FrameConsole* LocalDOMWindow::GetFrameConsole() const {
}
ApplicationCache* LocalDOMWindow::applicationCache() const {
+ DCHECK(RuntimeEnabledFeatures::AppCacheEnabled(
+ document()->ToExecutionContext()));
if (!IsCurrentlyDisplayedInFrame())
return nullptr;
if (!isSecureContext()) {
@@ -585,14 +783,16 @@ void LocalDOMWindow::SchedulePostMessage(
// 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);
+ std::unique_ptr<SourceLocation> location =
+ SourceLocation::Capture(source->ToExecutionContext());
document_->GetTaskRunner(TaskType::kPostedMessage)
- ->PostTask(
- FROM_HERE,
- WTF::Bind(&LocalDOMWindow::DispatchPostMessage, WrapPersistent(this),
- WrapPersistent(event), std::move(target),
- std::move(location), source->GetAgentClusterID()));
- probe::AsyncTaskScheduled(document(), "postMessage", event->async_task_id());
+ ->PostTask(FROM_HERE,
+ WTF::Bind(&LocalDOMWindow::DispatchPostMessage,
+ WrapPersistent(this), WrapPersistent(event),
+ std::move(target), std::move(location),
+ source->ToExecutionContext()->GetAgentClusterID()));
+ probe::AsyncTaskScheduled(document()->ToExecutionContext(), "postMessage",
+ event->async_task_id());
}
void LocalDOMWindow::DispatchPostMessage(
@@ -600,11 +800,12 @@ void LocalDOMWindow::DispatchPostMessage(
scoped_refptr<const SecurityOrigin> intended_target_origin,
std::unique_ptr<SourceLocation> location,
const base::UnguessableToken& source_agent_cluster_id) {
- probe::AsyncTask async_task(document(), event->async_task_id());
+ probe::AsyncTask async_task(document()->ToExecutionContext(),
+ event->async_task_id());
if (!IsCurrentlyDisplayedInFrame())
return;
- event->EntangleMessagePorts(document());
+ event->EntangleMessagePorts(document()->ToExecutionContext());
DispatchMessageEventWithOriginCheck(intended_target_origin.get(), event,
std::move(location),
@@ -629,7 +830,7 @@ void LocalDOMWindow::DispatchMessageEventWithOriginCheck(
"The target origin provided ('" + intended_target_origin->ToString() +
"') does not match the recipient window's origin ('" +
document()->GetSecurityOrigin()->ToString() + "').");
- ConsoleMessage* console_message = ConsoleMessage::Create(
+ auto* console_message = MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kSecurity,
mojom::ConsoleMessageLevel::kError, message, std::move(location));
GetFrameConsole()->AddMessage(console_message);
@@ -640,7 +841,7 @@ void LocalDOMWindow::DispatchMessageEventWithOriginCheck(
KURL sender(event->origin());
if (!document()->GetContentSecurityPolicy()->AllowConnectToSource(
sender, RedirectStatus::kNoRedirect,
- SecurityViolationReportingPolicy::kSuppressReporting)) {
+ ReportingDisposition::kSuppressReporting)) {
UseCounter::Count(
document(), WebFeature::kPostMessageIncomingWouldBeBlockedByConnectSrc);
}
@@ -657,13 +858,12 @@ void LocalDOMWindow::DispatchMessageEventWithOriginCheck(
}
}
if (event->IsLockedToAgentCluster()) {
- if (!document()->IsSameAgentCluster(source_agent_cluster_id)) {
+ if (!document()->ToExecutionContext()->IsSameAgentCluster(
+ source_agent_cluster_id)) {
UseCounter::Count(
document(),
WebFeature::kMessageEventSharedArrayBufferDifferentAgentCluster);
- // TODO(dtapuska): Make sure this generates an error. See
- // https://crbug.com/1028736
- // event = MessageEvent::CreateError(event->origin(), event->source());
+ event = MessageEvent::CreateError(event->origin(), event->source());
} else {
scoped_refptr<SecurityOrigin> sender_origin =
SecurityOrigin::Create(sender);
@@ -697,11 +897,12 @@ Element* LocalDOMWindow::frameElement() const {
void LocalDOMWindow::blur() {}
void LocalDOMWindow::print(ScriptState* script_state) {
- if (!GetFrame())
- return;
-
- Page* page = GetFrame()->GetPage();
- if (!page)
+ // 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;
if (script_state &&
@@ -714,11 +915,14 @@ void LocalDOMWindow::print(ScriptState* script_state) {
return;
}
+ if (!GetFrame()->IsMainFrame() && !GetFrame()->IsCrossOriginToMainFrame()) {
+ document()->CountUse(WebFeature::kSameOriginIframeWindowPrint);
+ }
document()->CountUseOnlyInCrossOriginIframe(
WebFeature::kCrossOriginWindowPrint);
should_print_when_finished_loading_ = false;
- page->GetChromeClient().Print(GetFrame());
+ GetFrame()->GetPage()->GetChromeClient().Print(GetFrame());
}
void LocalDOMWindow::stop() {
@@ -731,9 +935,9 @@ void LocalDOMWindow::alert(ScriptState* script_state, const String& message) {
if (!GetFrame())
return;
- if (document()->IsSandboxed(WebSandboxFlags::kModals)) {
+ if (document()->IsSandboxed(mojom::blink::WebSandboxFlags::kModals)) {
UseCounter::Count(document(), WebFeature::kDialogInSandboxedContext);
- GetFrameConsole()->AddMessage(ConsoleMessage::Create(
+ GetFrameConsole()->AddMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kSecurity,
mojom::ConsoleMessageLevel::kError,
"Ignored call to 'alert()'. The document is sandboxed, and the "
@@ -751,6 +955,9 @@ void LocalDOMWindow::alert(ScriptState* script_state, const String& message) {
if (!page)
return;
+ if (!GetFrame()->IsMainFrame() && !GetFrame()->IsCrossOriginToMainFrame()) {
+ document()->CountUse(WebFeature::kSameOriginIframeWindowAlert);
+ }
document()->CountUseOnlyInCrossOriginIframe(
WebFeature::kCrossOriginWindowAlert);
@@ -761,9 +968,9 @@ bool LocalDOMWindow::confirm(ScriptState* script_state, const String& message) {
if (!GetFrame())
return false;
- if (document()->IsSandboxed(WebSandboxFlags::kModals)) {
+ if (document()->IsSandboxed(mojom::blink::WebSandboxFlags::kModals)) {
UseCounter::Count(document(), WebFeature::kDialogInSandboxedContext);
- GetFrameConsole()->AddMessage(ConsoleMessage::Create(
+ GetFrameConsole()->AddMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kSecurity,
mojom::ConsoleMessageLevel::kError,
"Ignored call to 'confirm()'. The document is sandboxed, and the "
@@ -781,6 +988,9 @@ bool LocalDOMWindow::confirm(ScriptState* script_state, const String& message) {
if (!page)
return false;
+ if (!GetFrame()->IsMainFrame() && !GetFrame()->IsCrossOriginToMainFrame()) {
+ document()->CountUse(WebFeature::kSameOriginIframeWindowConfirm);
+ }
document()->CountUseOnlyInCrossOriginIframe(
WebFeature::kCrossOriginWindowConfirm);
@@ -793,9 +1003,9 @@ String LocalDOMWindow::prompt(ScriptState* script_state,
if (!GetFrame())
return String();
- if (document()->IsSandboxed(WebSandboxFlags::kModals)) {
+ if (document()->IsSandboxed(mojom::blink::WebSandboxFlags::kModals)) {
UseCounter::Count(document(), WebFeature::kDialogInSandboxedContext);
- GetFrameConsole()->AddMessage(ConsoleMessage::Create(
+ GetFrameConsole()->AddMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kSecurity,
mojom::ConsoleMessageLevel::kError,
"Ignored call to 'prompt()'. The document is sandboxed, and the "
@@ -818,6 +1028,9 @@ String LocalDOMWindow::prompt(ScriptState* script_state,
default_value, return_value))
return return_value;
+ if (!GetFrame()->IsMainFrame() && !GetFrame()->IsCrossOriginToMainFrame()) {
+ document()->CountUse(WebFeature::kSameOriginIframeWindowPrompt);
+ }
document()->CountUseOnlyInCrossOriginIframe(
WebFeature::kCrossOriginWindowPrompt);
@@ -836,7 +1049,7 @@ bool LocalDOMWindow::find(const String& string,
// Up-to-date, clean tree is required for finding text in page, since it
// relies on TextIterator to look over the text.
- document()->UpdateStyleAndLayout();
+ document()->UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
// FIXME (13016): Support searchInFrames and showDialog
FindOptions options =
@@ -898,14 +1111,17 @@ IntSize LocalDOMWindow::GetViewportSize() const {
// enabled, the initial page scale depends on the content width and is set
// after a layout, perform one now so queries during page load will use the
// up to date viewport.
- if (page->GetSettings().GetViewportEnabled() && GetFrame()->IsMainFrame())
- document()->UpdateStyleAndLayout();
+ if (page->GetSettings().GetViewportEnabled() && GetFrame()->IsMainFrame()) {
+ document()->UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
+ }
// FIXME: This is potentially too much work. We really only need to know the
// dimensions of the parent frame's layoutObject.
if (Frame* parent = GetFrame()->Tree().Parent()) {
- if (auto* parent_local_frame = DynamicTo<LocalFrame>(parent))
- parent_local_frame->GetDocument()->UpdateStyleAndLayout();
+ if (auto* parent_local_frame = DynamicTo<LocalFrame>(parent)) {
+ parent_local_frame->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kJavaScript);
+ }
}
return document()->View()->Size();
@@ -971,7 +1187,7 @@ double LocalDOMWindow::scrollX() const {
if (!view)
return 0;
- document()->UpdateStyleAndLayout();
+ document()->UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
// TODO(bokan): This is wrong when the document.rootScroller is non-default.
// crbug.com/505516.
@@ -988,7 +1204,7 @@ double LocalDOMWindow::scrollY() const {
if (!view)
return 0;
- document()->UpdateStyleAndLayout();
+ document()->UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
// TODO(bokan): This is wrong when the document.rootScroller is non-default.
// crbug.com/505516.
@@ -1074,7 +1290,7 @@ void LocalDOMWindow::scrollBy(const ScrollToOptions* scroll_to_options) const {
if (!IsCurrentlyDisplayedInFrame())
return;
- document()->UpdateStyleAndLayout();
+ document()->UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
LocalFrameView* view = GetFrame()->View();
if (!view)
@@ -1103,17 +1319,19 @@ void LocalDOMWindow::scrollBy(const ScrollToOptions* scroll_to_options) const {
std::unique_ptr<cc::SnapSelectionStrategy> strategy =
cc::SnapSelectionStrategy::CreateForEndAndDirection(
- gfx::ScrollOffset(current_position), gfx::ScrollOffset(scaled_delta));
+ gfx::ScrollOffset(current_position), gfx::ScrollOffset(scaled_delta),
+ RuntimeEnabledFeatures::FractionalScrollOffsetsEnabled());
new_scaled_position =
viewport->GetSnapPositionAndSetTarget(*strategy).value_or(
new_scaled_position);
- ScrollBehavior scroll_behavior = kScrollBehaviorAuto;
+ mojom::blink::ScrollBehavior scroll_behavior =
+ mojom::blink::ScrollBehavior::kAuto;
ScrollableArea::ScrollBehaviorFromString(scroll_to_options->behavior(),
scroll_behavior);
viewport->SetScrollOffset(
viewport->ScrollPositionToOffset(new_scaled_position),
- kProgrammaticScroll, scroll_behavior);
+ mojom::blink::ScrollType::kProgrammatic, scroll_behavior);
}
void LocalDOMWindow::scrollTo(double x, double y) const {
@@ -1139,7 +1357,7 @@ void LocalDOMWindow::scrollTo(const ScrollToOptions* scroll_to_options) const {
// clamped, which is never the case for (0, 0).
if (!scroll_to_options->hasLeft() || !scroll_to_options->hasTop() ||
scroll_to_options->left() || scroll_to_options->top()) {
- document()->UpdateStyleAndLayout();
+ document()->UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
}
float scaled_x = 0.0f;
@@ -1172,12 +1390,13 @@ void LocalDOMWindow::scrollTo(const ScrollToOptions* scroll_to_options) const {
new_scaled_position =
viewport->GetSnapPositionAndSetTarget(*strategy).value_or(
new_scaled_position);
- ScrollBehavior scroll_behavior = kScrollBehaviorAuto;
+ mojom::blink::ScrollBehavior scroll_behavior =
+ mojom::blink::ScrollBehavior::kAuto;
ScrollableArea::ScrollBehaviorFromString(scroll_to_options->behavior(),
scroll_behavior);
viewport->SetScrollOffset(
viewport->ScrollPositionToOffset(new_scaled_position),
- kProgrammaticScroll, scroll_behavior);
+ mojom::blink::ScrollType::kProgrammatic, scroll_behavior);
}
void LocalDOMWindow::moveBy(int x, int y) const {
@@ -1292,6 +1511,14 @@ void LocalDOMWindow::queueMicrotask(V8VoidFunction* callback) {
WrapPersistent(callback), nullptr));
}
+const Vector<String>& LocalDOMWindow::originPolicyIds() const {
+ return origin_policy_ids_;
+}
+
+void LocalDOMWindow::SetOriginPolicyIds(const Vector<String>& ids) {
+ origin_policy_ids_ = ids;
+}
+
int LocalDOMWindow::requestIdleCallback(V8IdleRequestCallback* callback,
const IdleRequestOptions* options) {
if (Document* document = this->document()) {
@@ -1404,9 +1631,9 @@ void LocalDOMWindow::WarnUnusedPreloads(TimerBase* base) {
"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(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning, message));
+ GetFrameConsole()->AddMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning, message));
}
}
@@ -1498,9 +1725,9 @@ void LocalDOMWindow::PrintErrorMessage(const String& message) const {
if (message.IsEmpty())
return;
- GetFrameConsole()->AddMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kError, message));
+ GetFrameConsole()->AddMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kError, message));
}
DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
@@ -1562,13 +1789,13 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
// an embedder-initiated navigation. FrameLoader assumes no responsibility
// for generating an embedder-initiated navigation's referrer, so we need to
// ensure the proper referrer is set now.
- // TODO(domfarolino): Stop setting ResourceRequest's HTTP Referrer and store
- // this is a separate member. See https://crbug.com/850813.
- frame_request.GetResourceRequest().SetHttpReferrer(
- SecurityPolicy::GenerateReferrer(
- active_document->GetReferrerPolicy(), completed_url,
- window_features.noreferrer ? Referrer::NoReferrer()
- : active_document->OutgoingReferrer()));
+ Referrer referrer = SecurityPolicy::GenerateReferrer(
+ active_document->GetReferrerPolicy(), completed_url,
+ window_features.noreferrer ? Referrer::NoReferrer()
+ : active_document->OutgoingReferrer());
+ frame_request.GetResourceRequest().SetReferrerString(referrer.referrer);
+ frame_request.GetResourceRequest().SetReferrerPolicy(
+ referrer.referrer_policy);
frame_request.GetResourceRequest().SetHasUserGesture(
LocalFrame::HasTransientUserActivation(GetFrame()));
@@ -1608,7 +1835,7 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
return result.frame->DomWindow();
}
-void LocalDOMWindow::Trace(blink::Visitor* visitor) {
+void LocalDOMWindow::Trace(Visitor* visitor) {
visitor->Trace(document_);
visitor->Trace(screen_);
visitor->Trace(history_);
@@ -1628,6 +1855,7 @@ void LocalDOMWindow::Trace(blink::Visitor* visitor) {
visitor->Trace(event_listener_observers_);
visitor->Trace(trusted_types_);
DOMWindow::Trace(visitor);
+ ExecutionContext::Trace(visitor);
Supplementable<LocalDOMWindow>::Trace(visitor);
}
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 91dd27d2a49..7494c6d34a6 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
@@ -83,6 +83,7 @@ enum PageTransitionEventPersistence {
// Note: if you're thinking of returning something DOM-related by reference,
// please ping dcheng@chromium.org first. You probably don't want to do that.
class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
+ public ExecutionContext,
public Supplementable<LocalDOMWindow> {
USING_GARBAGE_COLLECTED_MIXIN(LocalDOMWindow);
USING_PRE_FINALIZER(LocalDOMWindow, Dispose);
@@ -96,9 +97,7 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
virtual void DidRemoveAllEventListeners(LocalDOMWindow*) = 0;
};
- static Document* CreateDocument(const String& mime_type,
- const DocumentInit&,
- bool force_xhtml);
+ static Document* CreateDocument(const DocumentInit&, bool force_xhtml);
static LocalDOMWindow* From(const ScriptState*);
@@ -107,11 +106,64 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
LocalFrame* GetFrame() const { return To<LocalFrame>(DOMWindow::GetFrame()); }
- void Trace(blink::Visitor*) override;
-
- Document* InstallNewDocument(const String& mime_type,
- const DocumentInit&,
- bool force_xhtml);
+ void Trace(Visitor*) 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;
+ ContentSecurityPolicy* GetContentSecurityPolicyForWorld() final;
+ const KURL& Url() const final;
+ const KURL& BaseURL() const final;
+ KURL CompleteURL(const String&) const final;
+ void DisableEval(const String& error_message) final;
+ LocalDOMWindow* ExecutingWindow() const final {
+ // TODO(crbug.com/1029822): This const_cast is gross.
+ return const_cast<LocalDOMWindow*>(this);
+ }
+ String UserAgent() const final;
+ HttpsState GetHttpsState() const final;
+ ResourceFetcher* Fetcher() const final;
+ SecurityContext& GetSecurityContext() final;
+ const SecurityContext& GetSecurityContext() const final;
+ bool CanExecuteScripts(ReasonForCallingCanExecuteScripts) final;
+ void ExceptionThrown(ErrorEvent*) final;
+ EventTarget* ErrorEventTarget() final { return this; }
+ String OutgoingReferrer() const final;
+ network::mojom::ReferrerPolicy GetReferrerPolicy() const final;
+ CoreProbeSink* GetProbeSink() final;
+ BrowserInterfaceBrokerProxy& GetBrowserInterfaceBroker() final;
+ FrameOrWorkerScheduler* GetScheduler() final;
+ scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(TaskType) final;
+ TrustedTypePolicyFactory* GetTrustedTypes() const final {
+ return trustedTypes();
+ }
+ void CountPotentialFeaturePolicyViolation(
+ mojom::blink::FeaturePolicyFeature) const final;
+ void ReportFeaturePolicyViolation(
+ mojom::blink::FeaturePolicyFeature,
+ mojom::blink::PolicyDisposition,
+ const String& message = g_empty_string,
+ // If source_file is set to empty string,
+ // current JS file would be used as source_file instead.
+ const String& source_file = g_empty_string) const final;
+ void ReportDocumentPolicyViolation(
+ mojom::blink::DocumentPolicyFeature,
+ mojom::blink::PolicyDisposition,
+ const String& message = g_empty_string,
+ // If source_file is set to empty string,
+ // current JS file would be used as source_file instead.
+ const String& source_file = g_empty_string) const final;
+
+ void AddConsoleMessageImpl(ConsoleMessage*, bool discard_duplicates) final;
+
+ // UseCounter orverrides:
+ void CountUse(mojom::WebFeature feature) final;
+ void CountDeprecation(mojom::WebFeature feature) final;
+
+ Document* InstallNewDocument(const DocumentInit&, bool force_xhtml);
// EventTarget overrides:
ExecutionContext* GetExecutionContext() const override;
@@ -228,6 +280,10 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
// https://html.spec.whatwg.org/C/#windoworworkerglobalscope-mixin
void queueMicrotask(V8VoidFunction*);
+ // https://wicg.github.io/origin-policy/#monkeypatch-html-windoworworkerglobalscope
+ const Vector<String>& originPolicyIds() const;
+ void SetOriginPolicyIds(const Vector<String>&);
+
// Idle callback extensions
int requestIdleCallback(V8IdleRequestCallback*, const IdleRequestOptions*);
void cancelIdleCallback(int id);
@@ -248,12 +304,6 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
DEFINE_ATTRIBUTE_EVENT_LISTENER(search, kSearch)
- DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitanimationstart, kWebkitAnimationStart)
- DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitanimationiteration,
- kWebkitAnimationIteration)
- DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitanimationend, kWebkitAnimationEnd)
- DEFINE_ATTRIBUTE_EVENT_LISTENER(webkittransitionend, kWebkitTransitionEnd)
-
DEFINE_ATTRIBUTE_EVENT_LISTENER(orientationchange, kOrientationchange)
void RegisterEventListenerObserver(EventListenerObserver*);
@@ -374,6 +424,8 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
String status_;
String default_status_;
+ Vector<String> origin_policy_ids_;
+
mutable Member<ApplicationCache> application_cache_;
scoped_refptr<SerializedScriptValue> pending_state_object_;
@@ -381,10 +433,22 @@ class CORE_EXPORT LocalDOMWindow final : public DOMWindow,
HeapHashSet<WeakMember<EventListenerObserver>> event_listener_observers_;
mutable Member<TrustedTypePolicyFactory> trusted_types_;
+
+ // A dummy scheduler to return when the window is detached.
+ // All operations on it result in no-op, but due to this it's safe to
+ // use the returned value of GetScheduler() without additional checks.
+ // A task posted to a task runner obtained from one of its task runners
+ // will be forwarded to the default task runner.
+ // TODO(altimin): We should be able to remove it after we complete
+ // frame:document lifetime refactoring.
+ std::unique_ptr<FrameOrWorkerScheduler> detached_scheduler_;
};
template <>
struct DowncastTraits<LocalDOMWindow> {
+ static bool AllowFrom(const ExecutionContext& context) {
+ return context.IsDocument();
+ }
static bool AllowFrom(const DOMWindow& window) {
return window.IsLocalDOMWindow();
}
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 0aa1376a948..3c78d008993 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame.cc
@@ -34,22 +34,34 @@
#include <memory>
#include <utility>
+#include "base/metrics/histogram_functions.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"
#include "services/network/public/cpp/features.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
+#include "services/network/public/mojom/content_security_policy.mojom-blink.h"
#include "skia/public/mojom/skcolor.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/frame/blocked_navigation_types.h"
+#include "third_party/blink/public/common/features.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/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_owner_properties.mojom-blink.h"
#include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink.h"
-#include "third_party/blink/public/platform/interface_provider.h"
+#include "third_party/blink/public/mojom/frame/media_player_action.mojom-blink.h"
+#include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink.h"
#include "third_party/blink/public/platform/interface_registry.h"
#include "third_party/blink/public/platform/scheduler/web_resource_loading_task_runner_handle.h"
+#include "third_party/blink/public/platform/url_conversion.h"
#include "third_party/blink/public/platform/web_content_settings_client.h"
+#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/web/web_content_capture_client.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"
#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
#include "third_party/blink/renderer/core/content_capture/content_capture_manager.h"
@@ -72,25 +84,37 @@
#include "third_party/blink/renderer/core/editing/surrounding_text.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"
#include "third_party/blink/renderer/core/frame/ad_tracker.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/event_handler_registry.h"
#include "third_party/blink/renderer/core/frame/frame_console.h"
#include "third_party/blink/renderer/core/frame/frame_overlay.h"
+#include "third_party/blink/renderer/core/frame/frame_serializer.h"
+#include "third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.h"
#include "third_party/blink/renderer/core/frame/intervention.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
+#include "third_party/blink/renderer/core/frame/page_scale_constraints_set.h"
#include "third_party/blink/renderer/core/frame/performance_monitor.h"
+#include "third_party/blink/renderer/core/frame/picture_in_picture_controller.h"
+#include "third_party/blink/renderer/core/frame/remote_frame_owner.h"
#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/settings.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"
#include "third_party/blink/renderer/core/html/html_frame_element_base.h"
#include "third_party/blink/renderer/core/html/html_plugin_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/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.h"
#include "third_party/blink/renderer/core/inspector/inspector_task_runner.h"
#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.h"
@@ -101,6 +125,7 @@
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/loader/frame_load_request.h"
#include "third_party/blink/renderer/core/loader/idleness_detector.h"
+#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/plugin_data.h"
@@ -113,6 +138,7 @@
#include "third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h"
#include "third_party/blink/renderer/core/svg/svg_document_extensions.h"
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
+#include "third_party/blink/renderer/platform/blob/blob_data.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h"
@@ -120,22 +146,26 @@
#include "third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_properties.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/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/json/json_values.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
+#include "third_party/blink/renderer/platform/mhtml/serialized_resource.h"
#include "third_party/blink/renderer/platform/network/network_state_notifier.h"
#include "third_party/blink/renderer/platform/network/network_utils.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/wtf/std_lib_extras.h"
+#include "ui/gfx/geometry/point.h"
namespace blink {
namespace {
+// Maximum number of burst download requests allowed.
+const int kBurstDownloadLimit = 10;
+
inline float ParentPageZoomFactor(LocalFrame* frame) {
auto* parent_local_frame = DynamicTo<LocalFrame>(frame->Tree().Parent());
return parent_local_frame ? parent_local_frame->PageZoomFactor() : 1;
@@ -146,6 +176,98 @@ inline float ParentTextZoomFactor(LocalFrame* frame) {
return parent_local_frame ? parent_local_frame->TextZoomFactor() : 1;
}
+// 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) {
+ 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();
+}
+
+HitTestResult HitTestResultForRootFramePos(
+ LocalFrame* main_frame,
+ const PhysicalOffset& pos_in_root_frame) {
+ DCHECK(main_frame->IsMainFrame());
+
+ HitTestLocation location(
+ main_frame->View()->ConvertFromRootFrame(pos_in_root_frame));
+ HitTestResult result = main_frame->GetEventHandler().HitTestResultAtLocation(
+ location, HitTestRequest::kReadOnly | HitTestRequest::kActive);
+ result.SetToShadowHostIfInRestrictedShadowRoot();
+ return result;
+}
+
+class WebBundleGenerationDelegate
+ : public WebFrameSerializer::MHTMLPartsGenerationDelegate {
+ STACK_ALLOCATED();
+
+ public:
+ WebBundleGenerationDelegate() = default;
+ ~WebBundleGenerationDelegate() = default;
+
+ WebBundleGenerationDelegate(const WebBundleGenerationDelegate&) = delete;
+ WebBundleGenerationDelegate& operator=(const WebBundleGenerationDelegate&) =
+ delete;
+
+ bool ShouldSkipResource(const WebURL& url) override { return false; }
+ bool UseBinaryEncoding() override { return false; }
+ bool RemovePopupOverlay() override { return false; }
+ bool UsePageProblemDetectors() override { return false; }
+};
+
+class ResourceSnapshotForWebBundleImpl
+ : public data_decoder::mojom::blink::ResourceSnapshotForWebBundle {
+ public:
+ explicit ResourceSnapshotForWebBundleImpl(Deque<SerializedResource> resources)
+ : resources_(std::move(resources)) {}
+ ~ResourceSnapshotForWebBundleImpl() override = default;
+
+ ResourceSnapshotForWebBundleImpl(const ResourceSnapshotForWebBundleImpl&) =
+ delete;
+ ResourceSnapshotForWebBundleImpl& operator=(
+ const ResourceSnapshotForWebBundleImpl&) = delete;
+
+ // data_decoder::mojom::blink::ResourceSnapshotForWebBundle:
+ void GetResourceCount(GetResourceCountCallback callback) override {
+ std::move(callback).Run(resources_.size());
+ }
+ void GetResourceInfo(uint64_t index,
+ GetResourceInfoCallback callback) override {
+ if (index >= resources_.size()) {
+ std::move(callback).Run(nullptr);
+ return;
+ }
+ const auto& resource = resources_.at(SafeCast<WTF::wtf_size_t>(index));
+ auto info = data_decoder::mojom::blink::SerializedResourceInfo::New();
+ info->url = resource.url;
+ info->mime_type = resource.mime_type;
+ info->size = resource.data ? resource.data->size() : 0;
+ std::move(callback).Run(std::move(info));
+ }
+ void GetResourceBody(uint64_t index,
+ GetResourceBodyCallback callback) override {
+ if (index >= resources_.size()) {
+ std::move(callback).Run(base::nullopt);
+ return;
+ }
+ const auto& resource = resources_.at(SafeCast<WTF::wtf_size_t>(index));
+ if (!resource.data) {
+ std::move(callback).Run(base::nullopt);
+ return;
+ }
+ std::move(callback).Run(
+ mojo_base::BigBuffer(resource.data->CopyAs<std::vector<uint8_t>>()));
+ }
+
+ private:
+ const Deque<SerializedResource> resources_;
+};
+
} // namespace
template class CORE_TEMPLATE_EXPORT Supplement<LocalFrame>;
@@ -211,8 +333,8 @@ void LocalFrame::CreateView(const IntSize& viewport_size,
}
if (Owner()) {
- View()->SetCanHaveScrollbars(Owner()->ScrollingMode() !=
- ScrollbarMode::kAlwaysOff);
+ View()->SetCanHaveScrollbars(Owner()->ScrollbarMode() !=
+ mojom::blink::ScrollbarMode::kAlwaysOff);
}
}
@@ -224,7 +346,7 @@ LocalFrame::~LocalFrame() {
InstanceCounters::DecrementCounter(InstanceCounters::kAdSubframeCounter);
}
-void LocalFrame::Trace(blink::Visitor* visitor) {
+void LocalFrame::Trace(Visitor* visitor) {
visitor->Trace(ad_tracker_);
visitor->Trace(probe_sink_);
visitor->Trace(performance_monitor_);
@@ -244,6 +366,8 @@ void LocalFrame::Trace(blink::Visitor* visitor) {
visitor->Trace(text_suggestion_controller_);
visitor->Trace(smooth_scroll_sequencer_);
visitor->Trace(content_capture_manager_);
+ visitor->Trace(system_clipboard_);
+ visitor->Trace(raw_system_clipboard_);
Frame::Trace(visitor);
Supplementable<LocalFrame>::Trace(visitor);
}
@@ -255,7 +379,7 @@ bool LocalFrame::IsLocalRoot() const {
return Tree().Parent()->IsRemoteFrame();
}
-void LocalFrame::Navigate(const FrameLoadRequest& request,
+void LocalFrame::Navigate(FrameLoadRequest& request,
WebFrameLoadType frame_load_type) {
if (!navigation_rate_limiter().CanProceed())
return;
@@ -267,13 +391,25 @@ void LocalFrame::Navigate(const FrameLoadRequest& request,
// create a new back/forward item. The spec only explicitly mentions this in
// the context of navigating an iframe.
if (!GetDocument()->LoadEventFinished() &&
- !HasTransientUserActivation(this)) {
+ !HasTransientUserActivation(this) &&
+ request.ClientRedirectReason() !=
+ ClientNavigationReason::kAnchorClick) {
frame_load_type = WebFrameLoadType::kReplaceCurrentItem;
}
}
+
+ // Navigations in portal contexts do not create back/forward entries.
+ // TODO(mcnee): Similarly, we need to restrict orphaned contexts.
+ if (GetPage()->InsidePortal() &&
+ frame_load_type == WebFrameLoadType::kStandard) {
+ frame_load_type = WebFrameLoadType::kReplaceCurrentItem;
+ }
+
+ const ClientNavigationReason client_redirect_reason =
+ request.ClientRedirectReason();
loader_.StartNavigation(request, frame_load_type);
- if (request.ClientRedirectReason() != ClientNavigationReason::kNone)
+ if (client_redirect_reason != ClientNavigationReason::kNone)
probe::FrameClearedScheduledNavigation(this);
}
@@ -319,7 +455,7 @@ void LocalFrame::DetachImpl(FrameDetachType type) {
// frames, and those event handlers might start a new subresource load in this
// frame which should be stopped by Detach.
loader_.Detach();
- GetDocument()->Shutdown();
+ DomWindow()->FrameDestroyed();
if (content_capture_manager_) {
content_capture_manager_->Shutdown();
@@ -364,13 +500,12 @@ void LocalFrame::DetachImpl(FrameDetachType type) {
GetEventHandlerRegistry().DidRemoveAllEventHandlers(*DomWindow());
- DomWindow()->FrameDestroyed();
-
probe::FrameDetachedFromParent(this);
supplements_.clear();
frame_scheduler_.reset();
receiver_.reset();
+ main_frame_receiver_.reset();
WeakIdentifierMap<LocalFrame>::NotifyObjectDestroyed(this);
}
@@ -382,8 +517,8 @@ void LocalFrame::CheckCompleted() {
GetDocument()->CheckCompleted();
}
-SecurityContext* LocalFrame::GetSecurityContext() const {
- return GetDocument();
+const SecurityContext* LocalFrame::GetSecurityContext() const {
+ return GetDocument() ? &GetDocument()->GetSecurityContext() : nullptr;
}
void LocalFrame::PrintNavigationErrorMessage(const Frame& target_frame,
@@ -409,9 +544,9 @@ void LocalFrame::PrintNavigationErrorMessage(const Frame& target_frame,
}
void LocalFrame::PrintNavigationWarning(const String& message) {
- console_->AddMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning, message));
+ console_->AddMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning, message));
}
bool LocalFrame::ShouldClose() {
@@ -441,13 +576,20 @@ void LocalFrame::DidAttachDocument() {
GetInputMethodController().DidAttachDocument(document);
GetSpellChecker().DidAttachDocument(document);
GetTextSuggestionController().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_;
}
void LocalFrame::Reload(WebFrameLoadType load_type) {
DCHECK(IsReloadLoadType(load_type));
if (!loader_.GetDocumentLoader()->GetHistoryItem())
return;
- FrameLoadRequest request = FrameLoadRequest(
+ FrameLoadRequest request(
nullptr, loader_.ResourceRequestForReload(
load_type, ClientRedirectPolicy::kClientRedirect));
request.SetClientRedirectReason(ClientNavigationReason::kReload);
@@ -459,7 +601,7 @@ void LocalFrame::Reload(WebFrameLoadType load_type) {
}
LocalWindowProxy* LocalFrame::WindowProxy(DOMWrapperWorld& world) {
- return ToLocalWindowProxy(Frame::GetWindowProxy(world));
+ return To<LocalWindowProxy>(Frame::GetWindowProxy(world));
}
LocalDOMWindow* LocalFrame::DomWindow() const {
@@ -467,11 +609,10 @@ LocalDOMWindow* LocalFrame::DomWindow() const {
}
void LocalFrame::SetDOMWindow(LocalDOMWindow* dom_window) {
- if (dom_window)
- GetScriptController().ClearWindowProxy();
-
+ DCHECK(dom_window);
if (this->DomWindow())
this->DomWindow()->Reset();
+ GetScriptController().ClearWindowProxy();
dom_window_ = dom_window;
}
@@ -558,7 +699,7 @@ void LocalFrame::SetInheritedEffectiveTouchAction(TouchAction touch_action) {
}
bool LocalFrame::BubbleLogicalScrollFromChildFrame(
- ScrollDirection direction,
+ mojom::blink::ScrollDirection direction,
ScrollGranularity granularity,
Frame* child) {
FrameOwner* owner = child->Owner();
@@ -628,7 +769,7 @@ void LocalFrame::SetPrinting(bool printing,
maximum_shrink_ratio);
} else {
if (LayoutView* layout_view = View()->GetLayoutView()) {
- layout_view->SetPreferredLogicalWidthsDirty();
+ layout_view->SetIntrinsicLogicalWidthsDirty();
layout_view->SetNeedsLayout(layout_invalidation_reason::kPrintingChanged);
layout_view->SetShouldDoFullPaintInvalidationForViewAndAllDescendants();
}
@@ -741,16 +882,16 @@ void LocalFrame::SetPageAndTextZoomFactors(float page_zoom_factor,
}
}
- document->MediaQueryAffectingValueChanged();
+ document->MediaQueryAffectingValueChanged(MediaValueChange::kOther);
document->GetStyleEngine().MarkViewportStyleDirty();
document->GetStyleEngine().MarkAllElementsForStyleRecalc(
StyleChangeReasonForTracing::Create(style_change_reason::kZoom));
if (View() && View()->DidFirstLayout())
- document->UpdateStyleAndLayout();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kSizeChange);
}
void LocalFrame::DeviceScaleFactorChanged() {
- GetDocument()->MediaQueryAffectingValueChanged();
+ GetDocument()->MediaQueryAffectingValueChanged(MediaValueChange::kOther);
GetDocument()->GetStyleEngine().MarkViewportStyleDirty();
GetDocument()->GetStyleEngine().MarkAllElementsForStyleRecalc(
StyleChangeReasonForTracing::Create(style_change_reason::kZoom));
@@ -785,7 +926,9 @@ PositionWithAffinity LocalFrame::PositionForPoint(
const PhysicalOffset& frame_point) {
HitTestLocation location(frame_point);
HitTestResult result = GetEventHandler().HitTestResultAtLocation(location);
- Node* node = result.InnerNodeOrImageMapImage();
+ Node* node = result.InnerPossiblyPseudoNode();
+ if (node && !node->IsPseudoElement())
+ node = result.InnerNodeOrImageMapImage();
if (!node)
return PositionWithAffinity();
LayoutObject* layout_object = node->GetLayoutObject();
@@ -874,7 +1017,6 @@ LocalFrame::LocalFrame(LocalFrameClient* client,
page_zoom_factor_(ParentPageZoomFactor(this)),
text_zoom_factor_(ParentTextZoomFactor(this)),
in_view_source_mode_(false),
- ad_frame_type_(mojom::AdFrameType::kNonAd),
inspector_task_runner_(InspectorTaskRunner::Create(
GetTaskRunner(TaskType::kInternalInspector))),
interface_registry_(interface_registry
@@ -984,7 +1126,8 @@ bool LocalFrame::CanNavigate(const Frame& target_frame,
return false;
}
- if (GetSecurityContext()->IsSandboxed(WebSandboxFlags::kNavigation)) {
+ if (GetSecurityContext()->IsSandboxed(
+ mojom::blink::WebSandboxFlags::kNavigation)) {
if (!target_frame.Tree().IsDescendantOf(this) &&
!target_frame.IsMainFrame()) {
PrintNavigationErrorMessage(
@@ -999,8 +1142,10 @@ bool LocalFrame::CanNavigate(const Frame& target_frame,
// 'allow-popups' flag is specified, or if the
if (target_frame.IsMainFrame() && target_frame != Tree().Top() &&
GetSecurityContext()->IsSandboxed(
- WebSandboxFlags::kPropagatesToAuxiliaryBrowsingContexts) &&
- (GetSecurityContext()->IsSandboxed(WebSandboxFlags::kPopups) ||
+ mojom::blink::WebSandboxFlags::
+ kPropagatesToAuxiliaryBrowsingContexts) &&
+ (GetSecurityContext()->IsSandboxed(
+ mojom::blink::WebSandboxFlags::kPopups) ||
target_frame.Client()->Opener() != this)) {
PrintNavigationErrorMessage(
target_frame,
@@ -1013,9 +1158,10 @@ bool LocalFrame::CanNavigate(const Frame& target_frame,
// Top navigation is forbidden unless opted-in. allow-top-navigation or
// allow-top-navigation-by-user-activation will also skips origin checks.
if (target_frame == Tree().Top()) {
- if (GetSecurityContext()->IsSandboxed(WebSandboxFlags::kTopNavigation) &&
+ if (GetSecurityContext()->IsSandboxed(
+ mojom::blink::WebSandboxFlags::kTopNavigation) &&
GetSecurityContext()->IsSandboxed(
- WebSandboxFlags::kTopNavigationByUserActivation)) {
+ mojom::blink::WebSandboxFlags::kTopNavigationByUserActivation)) {
PrintNavigationErrorMessage(
target_frame,
"The frame attempting navigation of the top-level window is "
@@ -1024,15 +1170,16 @@ bool LocalFrame::CanNavigate(const Frame& target_frame,
return false;
}
- if (GetSecurityContext()->IsSandboxed(WebSandboxFlags::kTopNavigation) &&
+ if (GetSecurityContext()->IsSandboxed(
+ mojom::blink::WebSandboxFlags::kTopNavigation) &&
!GetSecurityContext()->IsSandboxed(
- WebSandboxFlags::kTopNavigationByUserActivation) &&
+ mojom::blink::WebSandboxFlags::kTopNavigationByUserActivation) &&
!LocalFrame::HasTransientUserActivation(this)) {
// With only 'allow-top-navigation-by-user-activation' (but not
// 'allow-top-navigation'), top navigation requires a user gesture.
- Client()->DidBlockNavigation(
+ GetLocalFrameHostRemote().DidBlockNavigation(
destination_url, GetDocument()->Url(),
- blink::NavigationBlockedReason::kRedirectWithNoUserGestureSandbox);
+ mojom::NavigationBlockedReason::kRedirectWithNoUserGestureSandbox);
PrintNavigationErrorMessage(
target_frame,
"The frame attempting navigation of the top-level window is "
@@ -1080,7 +1227,7 @@ bool LocalFrame::CanNavigate(const Frame& target_frame,
// A frame navigating its top may blocked if the document initiating
// the navigation has never received a user gesture and the navigation
// isn't same-origin with the target.
- if (HasBeenActivated() ||
+ if (HasStickyUserActivation() ||
target_frame.GetSecurityContext()->GetSecurityOrigin()->CanAccess(
SecurityOrigin::Create(destination_url).get())) {
return true;
@@ -1105,9 +1252,10 @@ bool LocalFrame::CanNavigate(const Frame& target_frame,
"but is neither same-origin with its target nor has it received a "
"user gesture. See "
"https://www.chromestatus.com/features/5851021045661696.");
- Client()->DidBlockNavigation(
+ GetLocalFrameHostRemote().DidBlockNavigation(
destination_url, GetDocument()->Url(),
- blink::NavigationBlockedReason::kRedirectWithNoUserGesture);
+ mojom::NavigationBlockedReason::kRedirectWithNoUserGesture);
+
} else {
PrintNavigationErrorMessage(target_frame,
"The frame attempting navigation is neither "
@@ -1119,17 +1267,17 @@ bool LocalFrame::CanNavigate(const Frame& target_frame,
void LocalFrame::SetIsAdSubframeIfNecessary() {
DCHECK(ad_tracker_);
+ if (IsAdSubframe())
+ return;
+
Frame* parent = Tree().Parent();
if (!parent)
return;
- // If the parent frame is local, directly determine if it's an ad. If it's
- // remote, then it is up to the embedder that moved this frame out-of-
- // process to set this frame as an ad via SetIsAdSubframe before commit.
- auto* parent_local_frame = DynamicTo<LocalFrame>(parent);
- bool parent_is_ad = parent_local_frame && parent_local_frame->IsAdSubframe();
+ bool parent_is_ad = parent->IsAdSubframe();
- if (parent_is_ad || ad_tracker_->IsAdScriptInStack()) {
+ if (parent_is_ad ||
+ ad_tracker_->IsAdScriptInStack(AdTracker::StackType::kBottomAndTop)) {
SetIsAdSubframe(parent_is_ad ? blink::mojom::AdFrameType::kChildAd
: blink::mojom::AdFrameType::kRootAd);
}
@@ -1152,11 +1300,6 @@ ContentCaptureManager* LocalFrame::GetContentCaptureManager() {
return content_capture_manager_;
}
-service_manager::InterfaceProvider& LocalFrame::GetInterfaceProvider() {
- DCHECK(Client());
- return *Client()->GetInterfaceProvider();
-}
-
BrowserInterfaceBrokerProxy& LocalFrame::GetBrowserInterfaceBroker() {
DCHECK(Client());
return Client()->GetBrowserInterfaceBroker();
@@ -1172,6 +1315,15 @@ LocalFrameClient* LocalFrame::Client() const {
return static_cast<LocalFrameClient*>(Frame::Client());
}
+FrameWidget* LocalFrame::GetWidgetForLocalRoot() {
+ WebLocalFrameImpl* web_frame = WebLocalFrameImpl::FromFrame(this);
+ if (!web_frame)
+ return nullptr;
+ // This WebFrameWidgetBase upcasts to a FrameWidget which is the interface
+ // exposed to Blink core.
+ return web_frame->LocalRootFrameWidget();
+}
+
WebContentSettingsClient* LocalFrame::GetContentSettingsClient() {
return Client() ? Client()->GetContentSettingsClient() : nullptr;
}
@@ -1263,6 +1415,12 @@ LocalFrame::LazyLoadImageSetting LocalFrame::GetLazyLoadImageSetting() const {
}
bool LocalFrame::ShouldForceDeferScript() const {
+ // Check if we should not defer script in subframe.
+ if (base::FeatureList::IsEnabled(features::kDisableForceDeferInChildFrames) &&
+ !IsLocalRoot()) {
+ return false;
+ }
+
// Check if enabled by runtime feature (for testing/evaluation) or if enabled
// by PreviewsState (for live intervention).
return RuntimeEnabledFeatures::ForceDeferScriptInterventionEnabled() ||
@@ -1278,8 +1436,8 @@ WebURLLoaderFactory* LocalFrame::GetURLLoaderFactory() {
}
WebPluginContainerImpl* LocalFrame::GetWebPluginContainer(Node* node) const {
- if (GetDocument() && GetDocument()->IsPluginDocument()) {
- return ToPluginDocument(GetDocument())->GetPluginView();
+ if (auto* plugin_document = DynamicTo<PluginDocument>(GetDocument())) {
+ return plugin_document->GetPluginView();
}
if (!node) {
DCHECK(GetDocument());
@@ -1329,10 +1487,19 @@ bool LocalFrame::ClipsContent() const {
void LocalFrame::SetViewportIntersectionFromParent(
const ViewportIntersectionState& intersection_state) {
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; neither the viewport offset nor the compositing bounds will
- // affect IntersectionObserver.
+ // has changed, or if we cannot skip sticky frame tracking; 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;
@@ -1345,6 +1512,25 @@ void LocalFrame::SetViewportIntersectionFromParent(
}
}
+IntSize LocalFrame::GetMainFrameViewportSize() const {
+ LocalFrame& local_root = LocalFrameRoot();
+ return local_root.IsMainFrame()
+ ? local_root.View()
+ ->GetScrollableArea()
+ ->VisibleContentRect()
+ .Size()
+ : IntSize(local_root.intersection_state_.main_frame_viewport_size);
+}
+
+IntPoint LocalFrame::GetMainFrameScrollOffset() const {
+ LocalFrame& local_root = LocalFrameRoot();
+ return local_root.IsMainFrame()
+ ? FlooredIntPoint(
+ local_root.View()->GetScrollableArea()->GetScrollOffset())
+ : IntPoint(
+ local_root.intersection_state_.main_frame_scroll_offset);
+}
+
FrameOcclusionState LocalFrame::GetOcclusionState() const {
// TODO(dcheng): Get rid of this branch for the main frame.
if (IsMainFrame())
@@ -1375,8 +1561,9 @@ void LocalFrame::ForceSynchronousDocumentInstall(
GetDocument()->Shutdown();
DomWindow()->InstallNewDocument(
- mime_type,
- DocumentInit::Create().WithDocumentLoader(loader_.GetDocumentLoader()),
+ DocumentInit::Create()
+ .WithDocumentLoader(loader_.GetDocumentLoader())
+ .WithTypeFrom(mime_type),
false);
loader_.StateMachine()->AdvanceTo(
FrameLoaderStateMachine::kCommittedFirstRealLoad);
@@ -1387,7 +1574,7 @@ void LocalFrame::ForceSynchronousDocumentInstall(
GetDocument()->Parser()->AppendBytes(segment.data(), segment.size());
GetDocument()->Parser()->Finish();
- // Upon loading of SVGIamges, log PageVisits in UseCounter.
+ // Upon loading of SVGImages, log PageVisits in UseCounter.
// Do not track PageVisits for inspector, web page popups, and validation
// message overlays (the other callers of this method).
if (GetDocument()->IsSVGDocument())
@@ -1407,14 +1594,6 @@ bool LocalFrame::IsProvisional() const {
return Owner()->ContentFrame() != this;
}
-bool LocalFrame::IsAdSubframe() const {
- return ad_frame_type_ != blink::mojom::AdFrameType::kNonAd;
-}
-
-bool LocalFrame::IsAdRoot() const {
- return ad_frame_type_ == blink::mojom::AdFrameType::kRootAd;
-}
-
void LocalFrame::SetIsAdSubframe(blink::mojom::AdFrameType ad_frame_type) {
DCHECK(!IsMainFrame());
@@ -1521,7 +1700,7 @@ void LocalFrame::NotifyUserActivation(LocalFrame* frame,
// static
bool LocalFrame::HasTransientUserActivation(LocalFrame* frame) {
- return frame ? frame->HasTransientUserActivation() : false;
+ return frame ? frame->Frame::HasTransientUserActivation() : false;
}
// static
@@ -1532,18 +1711,23 @@ bool LocalFrame::ConsumeTransientUserActivation(
}
void LocalFrame::NotifyUserActivation(bool need_browser_verification) {
- Client()->NotifyUserActivation(need_browser_verification);
+ mojom::blink::UserActivationUpdateType update_type =
+ need_browser_verification
+ ? mojom::blink::UserActivationUpdateType::
+ kNotifyActivationPendingBrowserVerification
+ : mojom::blink::UserActivationUpdateType::kNotifyActivation;
+
+ GetLocalFrameHostRemote().UpdateUserActivationState(update_type);
+ Client()->NotifyUserActivation();
NotifyUserActivationInLocalTree();
}
-bool LocalFrame::HasTransientUserActivation() {
- return user_activation_state_.IsActive();
-}
-
bool LocalFrame::ConsumeTransientUserActivation(
UserActivationUpdateSource update_source) {
- if (update_source == UserActivationUpdateSource::kRenderer)
- Client()->ConsumeUserActivation();
+ if (update_source == UserActivationUpdateSource::kRenderer) {
+ GetLocalFrameHostRemote().UpdateUserActivationState(
+ mojom::blink::UserActivationUpdateType::kConsumeTransientActivation);
+ }
return ConsumeTransientUserActivationInLocalTree();
}
@@ -1613,7 +1797,7 @@ void LocalFrame::PaintFrameColorOverlay(GraphicsContext& context) {
}
void LocalFrame::ForciblyPurgeV8Memory() {
- GetDocument()->NotifyContextDestroyed();
+ DomWindow()->NotifyContextDestroyed();
WindowProxyManager* window_proxy_manager = GetWindowProxyManager();
window_proxy_manager->ClearForV8MemoryPurge();
@@ -1662,9 +1846,8 @@ void LocalFrame::DidResume() {
const base::TimeTicks resume_event_start = base::TimeTicks::Now();
GetDocument()->DispatchEvent(*Event::Create(event_type_names::kResume));
const base::TimeTicks resume_event_end = base::TimeTicks::Now();
- DEFINE_STATIC_LOCAL(CustomCountHistogram, resume_histogram,
- ("DocumentEventTiming.ResumeDuration", 0, 10000000, 50));
- resume_histogram.CountMicroseconds(resume_event_end - resume_event_start);
+ base::UmaHistogramMicrosecondsTimes("DocumentEventTiming.ResumeDuration",
+ resume_event_end - resume_event_start);
// TODO(fmeawad): Move the following logic to the page once we have a
// PageResourceCoordinator in Blink
if (auto* document_resource_coordinator =
@@ -1676,14 +1859,15 @@ void LocalFrame::DidResume() {
void LocalFrame::PauseContext() {
GetDocument()->Fetcher()->SetDefersLoading(true);
- GetDocument()->SetLifecycleState(lifecycle_state_);
+ GetDocument()->ToExecutionContext()->SetLifecycleState(lifecycle_state_);
Loader().SetDefersLoading(true);
GetFrameScheduler()->SetPaused(true);
}
void LocalFrame::UnpauseContext() {
GetDocument()->Fetcher()->SetDefersLoading(false);
- GetDocument()->SetLifecycleState(mojom::FrameLifecycleState::kRunning);
+ GetDocument()->ToExecutionContext()->SetLifecycleState(
+ mojom::FrameLifecycleState::kRunning);
Loader().SetDefersLoading(false);
GetFrameScheduler()->SetPaused(false);
}
@@ -1744,7 +1928,7 @@ void LocalFrame::SetLifecycleState(mojom::FrameLifecycleState state) {
}
void LocalFrame::MaybeLogAdClickNavigation() {
- if (HasTransientUserActivation() && IsAdSubframe())
+ if (HasTransientUserActivation(this) && IsAdSubframe())
UseCounter::Count(GetDocument(), WebFeature::kAdClickNavigation);
}
@@ -1785,6 +1969,35 @@ void LocalFrame::FinishedLoading(FrameLoader::NavigationFinishState state) {
}
}
+void LocalFrame::UpdateFaviconURL() {
+ if (!IsMainFrame())
+ return;
+
+ // The URL to the icon may be in the header. As such, only
+ // ask the loader for the icon if it's finished loading.
+ if (!GetDocument()->LoadEventFinished())
+ return;
+
+ int icon_types_mask =
+ 1 << static_cast<int>(mojom::blink::FaviconIconType::kFavicon) |
+ 1 << static_cast<int>(mojom::blink::FaviconIconType::kTouchIcon) |
+ 1 << static_cast<int>(
+ mojom::blink::FaviconIconType::kTouchPrecomposedIcon);
+ Vector<IconURL> icon_urls = GetDocument()->IconURLs(icon_types_mask);
+ if (icon_urls.IsEmpty())
+ return;
+
+ Vector<mojom::blink::FaviconURLPtr> urls;
+ urls.ReserveCapacity(icon_urls.size());
+ for (const auto& icon_url : icon_urls) {
+ urls.push_back(mojom::blink::FaviconURL::New(
+ icon_url.icon_url_, icon_url.icon_type_, icon_url.sizes_));
+ }
+ DCHECK_EQ(icon_urls.size(), urls.size());
+
+ GetLocalFrameHostRemote().UpdateFaviconURL(std::move(urls));
+}
+
void LocalFrame::SetIsCapturingMediaCallback(
IsCapturingMediaCallback callback) {
is_capturing_media_callback_ = std::move(callback);
@@ -1795,10 +2008,130 @@ bool LocalFrame::IsCapturingMedia() const {
: false;
}
+SystemClipboard* LocalFrame::GetSystemClipboard() {
+ if (!system_clipboard_)
+ system_clipboard_ = MakeGarbageCollected<SystemClipboard>(this);
+
+ return system_clipboard_.Get();
+}
+
+RawSystemClipboard* LocalFrame::GetRawSystemClipboard() {
+ if (!raw_system_clipboard_)
+ raw_system_clipboard_ = MakeGarbageCollected<RawSystemClipboard>(this);
+
+ return raw_system_clipboard_.Get();
+}
+
+void LocalFrame::WasAttachedAsLocalMainFrame() {
+ GetInterfaceRegistry()->AddAssociatedInterface(WTF::BindRepeating(
+ &LocalFrame::BindToMainFrameReceiver, WrapWeakPersistent(this)));
+}
+
void LocalFrame::EvictFromBackForwardCache() {
GetLocalFrameHostRemote().EvictFromBackForwardCache();
}
+void LocalFrame::AnimateDoubleTapZoom(const gfx::Point& point,
+ const gfx::Rect& rect) {
+ GetPage()->GetChromeClient().AnimateDoubleTapZoom(point, rect);
+}
+
+void LocalFrame::SetScaleFactor(float scale_factor) {
+ DCHECK(IsMainFrame());
+
+ const PageScaleConstraints& constraints =
+ GetPage()->GetPageScaleConstraintsSet().FinalConstraints();
+ scale_factor = constraints.ClampToConstraints(scale_factor);
+ if (scale_factor == GetPage()->GetVisualViewport().Scale())
+ return;
+ GetPage()->GetVisualViewport().SetScale(scale_factor);
+}
+
+void LocalFrame::ClosePage(
+ mojom::blink::LocalMainFrame::ClosePageCallback completion_callback) {
+ SECURITY_CHECK(IsMainFrame());
+
+ // There are two ways to close a page:
+ //
+ // 1/ Via webview()->Close() that currently sets the WebView's delegate_ to
+ // NULL, and prevent any JavaScript dialogs in the onunload handler from
+ // appearing.
+ //
+ // 2/ Calling the FrameLoader's CloseURL method directly.
+ //
+ // TODO(creis): Having a single way to close that can run onunload is also
+ // useful for fixing http://b/issue?id=753080.
+
+ SubframeLoadingDisabler disabler(GetDocument());
+ // https://html.spec.whatwg.org/C/browsing-the-web.html#unload-a-document
+ // The ignore-opens-during-unload counter of a Document must be incremented
+ // when unloading itself.
+ IgnoreOpensDuringUnloadCountIncrementer ignore_opens_during_unload(
+ GetDocument());
+ Loader().DispatchUnloadEvent(nullptr, nullptr);
+
+ std::move(completion_callback).Run();
+}
+
+void LocalFrame::PluginActionAt(const gfx::Point& location,
+ mojom::blink::PluginActionType action) {
+ SECURITY_CHECK(IsMainFrame());
+
+ // TODO(bokan): Location is probably in viewport coordinates
+ HitTestResult result =
+ HitTestResultForRootFramePos(this, PhysicalOffset(IntPoint(location)));
+ Node* node = result.InnerNode();
+ if (!IsA<HTMLObjectElement>(*node) && !IsA<HTMLEmbedElement>(*node))
+ return;
+
+ LayoutObject* object = node->GetLayoutObject();
+ if (!object || !object->IsLayoutEmbeddedContent())
+ return;
+
+ WebPluginContainerImpl* plugin_view =
+ ToLayoutEmbeddedContent(object)->Plugin();
+ if (!plugin_view)
+ return;
+
+ switch (action) {
+ case mojom::blink::PluginActionType::kRotate90Clockwise:
+ plugin_view->Plugin()->RotateView(WebPlugin::kRotationType90Clockwise);
+ return;
+ case mojom::blink::PluginActionType::kRotate90Counterclockwise:
+ plugin_view->Plugin()->RotateView(
+ WebPlugin::kRotationType90Counterclockwise);
+ return;
+ }
+ NOTREACHED();
+}
+
+void LocalFrame::SetInitialFocus(bool reverse) {
+ GetDocument()->ClearFocusedElement();
+ GetPage()->GetFocusController().SetInitialFocus(
+ reverse ? mojom::blink::FocusType::kBackward
+ : mojom::blink::FocusType::kForward);
+}
+
+void LocalFrame::EnablePreferredSizeChangedMode() {
+ GetPage()->GetChromeClient().EnablePreferredSizeChangedMode();
+}
+
+void LocalFrame::ZoomToFindInPageRect(const gfx::Rect& rect_in_root_frame) {
+ GetPage()->GetChromeClient().ZoomToFindInPageRect(
+ WebRect(rect_in_root_frame));
+}
+
+HitTestResult LocalFrame::HitTestResultForVisualViewportPos(
+ const IntPoint& pos_in_viewport) {
+ IntPoint root_frame_point(
+ GetPage()->GetVisualViewport().ViewportToRootFrame(pos_in_viewport));
+ HitTestLocation location(View()->ConvertFromRootFrame(root_frame_point));
+ HitTestResult result = GetEventHandler().HitTestResultAtLocation(
+ location, HitTestRequest::kReadOnly | HitTestRequest::kActive);
+ result.SetToShadowHostIfInRestrictedShadowRoot();
+ return result;
+}
+
void LocalFrame::DidChangeVisibleToHitTesting() {
// LayoutEmbeddedContent does not propagate style updates to descendants.
// Need to update the field manually.
@@ -1826,6 +2159,18 @@ mojom::blink::LocalFrameHost& LocalFrame::GetLocalFrameHostRemote() {
return *local_frame_host_remote_.get();
}
+void LocalFrame::SetEmbeddingToken(
+ const base::UnguessableToken& embedding_token) {
+ DCHECK(Tree().Parent());
+ DCHECK(Tree().Parent()->IsRemoteFrame());
+ embedding_token_ = embedding_token;
+}
+
+const base::Optional<base::UnguessableToken>& LocalFrame::GetEmbeddingToken()
+ const {
+ return embedding_token_;
+}
+
void LocalFrame::GetTextSurroundingSelection(
uint32_t max_length,
GetTextSurroundingSelectionCallback callback) {
@@ -1851,6 +2196,15 @@ void LocalFrame::SendInterventionReport(const String& id,
Intervention::GenerateReport(this, id, message);
}
+void LocalFrame::SetFrameOwnerProperties(
+ mojom::blink::FrameOwnerPropertiesPtr properties) {
+ GetDocument()->WillChangeFrameOwnerProperties(
+ properties->margin_width, properties->margin_height,
+ properties->scrollbar_mode, properties->is_display_none);
+
+ Frame::ApplyFrameOwnerProperties(std::move(properties));
+}
+
void LocalFrame::NotifyUserActivation() {
NotifyUserActivation(false);
}
@@ -1859,11 +2213,15 @@ void LocalFrame::AddMessageToConsole(mojom::blink::ConsoleMessageLevel level,
const WTF::String& message,
bool discard_duplicates) {
GetDocument()->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kOther, level,
- message),
+ MakeGarbageCollected<ConsoleMessage>(mojom::ConsoleMessageSource::kOther,
+ level, message),
discard_duplicates);
}
+void LocalFrame::AddInspectorIssue(mojom::blink::InspectorIssueInfoPtr info) {
+ GetDocument()->AddInspectorIssue(InspectorIssue::Create(std::move(info)));
+}
+
void LocalFrame::Collapse(bool collapsed) {
FrameOwner* owner = Owner();
To<HTMLFrameOwnerElement>(owner)->SetCollapsed(collapsed);
@@ -1878,6 +2236,293 @@ void LocalFrame::Focus() {
FocusImpl();
}
+void LocalFrame::ClearFocusedElement() {
+ Document* document = GetDocument();
+ Element* old_focused_element = document->FocusedElement();
+ document->ClearFocusedElement();
+ if (!old_focused_element)
+ return;
+
+ // If a text field has focus, we need to make sure the selection controller
+ // knows to remove selection from it. Otherwise, the text field is still
+ // processing keyboard events even though focus has been moved to the page and
+ // keystrokes get eaten as a result.
+ document->UpdateStyleAndLayoutTree();
+ if (HasEditableStyle(*old_focused_element) ||
+ old_focused_element->IsTextControl())
+ Selection().Clear();
+}
+
+void LocalFrame::GetResourceSnapshotForWebBundle(
+ mojo::PendingReceiver<
+ data_decoder::mojom::blink::ResourceSnapshotForWebBundle> receiver) {
+ Deque<SerializedResource> resources;
+
+ HeapHashSet<WeakMember<const Element>> shadow_template_elements;
+ WebBundleGenerationDelegate web_delegate;
+ FrameSerializerDelegateImpl core_delegate(web_delegate,
+ shadow_template_elements);
+ FrameSerializer serializer(resources, core_delegate);
+ serializer.SerializeFrame(*this);
+
+ mojo::MakeSelfOwnedReceiver(
+ std::make_unique<ResourceSnapshotForWebBundleImpl>(std::move(resources)),
+ std::move(receiver));
+}
+
+void LocalFrame::CopyImageAtViewportPoint(const IntPoint& viewport_point) {
+ HitTestResult result = HitTestResultForVisualViewportPos(viewport_point);
+ if (!IsA<HTMLCanvasElement>(result.InnerNodeOrImageMapImage()) &&
+ result.AbsoluteImageURL().IsEmpty()) {
+ // There isn't actually an image at these coordinates. Might be because
+ // the window scrolled while the context menu was open or because the page
+ // changed itself between when we thought there was an image here and when
+ // we actually tried to retrieve the image.
+ //
+ // FIXME: implement a cache of the most recent HitTestResult to avoid having
+ // to do two hit tests.
+ return;
+ }
+
+ // TODO(editing-dev): The use of UpdateStyleAndLayout
+ // needs to be audited. See http://crbug.com/590369 for more details.
+ GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
+
+ GetEditor().CopyImage(result);
+}
+
+void LocalFrame::CopyImageAt(const gfx::Point& window_point) {
+ blink::WebFloatRect viewport_position(window_point.x(), window_point.y(), 0,
+ 0);
+ GetPage()->GetChromeClient().WindowToViewportRect(*this, &viewport_position);
+ CopyImageAtViewportPoint(IntPoint(viewport_position.x, viewport_position.y));
+}
+
+void LocalFrame::SaveImageAt(const gfx::Point& window_point) {
+ blink::WebFloatRect viewport_position(window_point.x(), window_point.y(), 0,
+ 0);
+ GetPage()->GetChromeClient().WindowToViewportRect(*this, &viewport_position);
+
+ IntPoint location(viewport_position.x, viewport_position.y);
+ Node* node =
+ HitTestResultForVisualViewportPos(location).InnerNodeOrImageMapImage();
+ if (!node || !(IsA<HTMLCanvasElement>(*node) || IsA<HTMLImageElement>(*node)))
+ return;
+
+ String url = To<Element>(*node).ImageSourceURL();
+ if (!KURL(NullURL(), url).ProtocolIsData())
+ return;
+
+ auto params = mojom::blink::DownloadURLParams::New();
+ params->data_url_blob = DataURLToMessagePipeHandle(url);
+ GetLocalFrameHostRemote().DownloadURL(std::move(params));
+}
+
+void LocalFrame::ReportBlinkFeatureUsage(
+ const Vector<mojom::blink::WebFeature>& features) {
+ DCHECK(!features.IsEmpty());
+
+ // Assimilate all features used/performed by the browser into UseCounter.
+ auto* document = GetDocument();
+ DCHECK(document);
+ for (const auto& feature : features)
+ document->CountUse(feature);
+}
+
+void LocalFrame::RenderFallbackContent() {
+ // TODO(ekaramad): If the owner renders its own content, then the current
+ // ContentFrame() should detach (see https://crbug.com/850223).
+ auto* owner = DeprecatedLocalOwner();
+ DCHECK(IsA<HTMLObjectElement>(owner));
+ owner->RenderFallbackContent(this);
+}
+
+void LocalFrame::BeforeUnload(bool is_reload, BeforeUnloadCallback callback) {
+ base::TimeTicks before_unload_start_time = base::TimeTicks::Now();
+
+ // This will execute the BeforeUnload event in this frame and all of its
+ // local descendant frames, including children of remote frames. The browser
+ // process will send separate IPCs to dispatch beforeunload in any
+ // out-of-process child frames.
+ bool proceed = Loader().ShouldClose(is_reload);
+
+ DCHECK(!callback.is_null());
+ base::TimeTicks before_unload_end_time = base::TimeTicks::Now();
+ std::move(callback).Run(proceed, before_unload_start_time,
+ before_unload_end_time);
+}
+
+void LocalFrame::MediaPlayerActionAtViewportPoint(
+ const IntPoint& viewport_position,
+ const blink::mojom::blink::MediaPlayerActionType type,
+ bool enable) {
+ HitTestResult result = HitTestResultForVisualViewportPos(viewport_position);
+ Node* node = result.InnerNode();
+ if (!IsA<HTMLVideoElement>(*node) && !IsA<HTMLAudioElement>(*node))
+ return;
+
+ auto* media_element = To<HTMLMediaElement>(node);
+ switch (type) {
+ case blink::mojom::blink::MediaPlayerActionType::kPlay:
+ if (enable)
+ media_element->Play();
+ else
+ media_element->pause();
+ break;
+ case blink::mojom::blink::MediaPlayerActionType::kMute:
+ media_element->setMuted(enable);
+ break;
+ case blink::mojom::blink::MediaPlayerActionType::kLoop:
+ media_element->SetLoop(enable);
+ break;
+ case blink::mojom::blink::MediaPlayerActionType::kControls:
+ media_element->SetBooleanAttribute(html_names::kControlsAttr, enable);
+ break;
+ case blink::mojom::blink::MediaPlayerActionType::kPictureInPicture:
+ DCHECK(IsA<HTMLVideoElement>(media_element));
+ if (enable) {
+ PictureInPictureController::From(node->GetDocument())
+ .EnterPictureInPicture(To<HTMLVideoElement>(media_element),
+ nullptr /* promise */,
+ nullptr /* options */);
+ } else {
+ PictureInPictureController::From(node->GetDocument())
+ .ExitPictureInPicture(To<HTMLVideoElement>(media_element), nullptr);
+ }
+
+ break;
+ }
+}
+
+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(
+ request.Url(), blob_url_token.InitWithNewPipeAndPassReceiver());
+ }
+
+ DownloadURL(request, cross_origin_redirect_behavior,
+ blob_url_token.PassPipe());
+}
+
+void LocalFrame::DownloadURL(
+ const ResourceRequest& request,
+ network::mojom::blink::RedirectMode cross_origin_redirect_behavior,
+ mojo::ScopedMessagePipeHandle blob_url_token) {
+ if (ShouldThrottleDownload())
+ return;
+
+ auto params = mojom::blink::DownloadURLParams::New();
+ const KURL& url = request.Url();
+ // Pass data URL through blob.
+ if (url.ProtocolIs("data")) {
+ params->url = KURL();
+ params->data_url_blob = DataURLToMessagePipeHandle(url.GetString());
+ } else {
+ params->url = url;
+ }
+
+ params->referrer = mojom::blink::Referrer::New();
+ params->referrer->url = KURL(request.ReferrerString());
+ params->referrer->policy = request.GetReferrerPolicy();
+ params->initiator_origin = request.RequestorOrigin();
+ if (request.GetSuggestedFilename().has_value())
+ params->suggested_name = *request.GetSuggestedFilename();
+ params->cross_origin_redirects = cross_origin_redirect_behavior;
+ params->blob_url_token = std::move(blob_url_token);
+
+ GetLocalFrameHostRemote().DownloadURL(std::move(params));
+}
+
+void LocalFrame::MediaPlayerActionAt(
+ const gfx::Point& window_point,
+ blink::mojom::blink::MediaPlayerActionPtr action) {
+ blink::WebFloatRect viewport_position(window_point.x(), window_point.y(), 0,
+ 0);
+ GetPage()->GetChromeClient().WindowToViewportRect(*this, &viewport_position);
+ IntPoint location(viewport_position.x, viewport_position.y);
+
+ MediaPlayerActionAtViewportPoint(location, action->type, action->enable);
+}
+
+void LocalFrame::AdvanceFocusInForm(mojom::blink::FocusType focus_type) {
+ auto* focused_frame = GetPage()->GetFocusController().FocusedFrame();
+ if (focused_frame != this)
+ return;
+
+ DCHECK(GetDocument());
+ Element* element = GetDocument()->FocusedElement();
+ if (!element)
+ return;
+
+ Element* next_element =
+ GetPage()->GetFocusController().NextFocusableElementInForm(element,
+ focus_type);
+ if (!next_element)
+ return;
+
+ next_element->scrollIntoViewIfNeeded(true /*centerIfNeeded*/);
+ next_element->focus();
+}
+
+void LocalFrame::ReportContentSecurityPolicyViolation(
+ network::mojom::blink::CSPViolationPtr violation) {
+ auto source_location = std::make_unique<SourceLocation>(
+ violation->source_location->url, violation->source_location->line,
+ violation->source_location->column, nullptr);
+
+ console_->AddMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kSecurity,
+ mojom::ConsoleMessageLevel::kError, violation->console_message,
+ source_location->Clone()));
+
+ auto directive_type =
+ ContentSecurityPolicy::GetDirectiveType(violation->effective_directive);
+ LocalFrame* context_frame =
+ directive_type == ContentSecurityPolicy::DirectiveType::kFrameAncestors
+ ? this
+ : nullptr;
+
+ GetDocument()->GetContentSecurityPolicy()->ReportViolation(
+ violation->directive, directive_type, violation->console_message,
+ violation->blocked_url, violation->report_endpoints,
+ violation->use_reporting_api, violation->header, violation->type,
+ ContentSecurityPolicy::ViolationType::kURLViolation,
+ std::move(source_location), context_frame,
+ violation->after_redirect ? RedirectStatus::kFollowedRedirect
+ : RedirectStatus::kNoRedirect,
+ nullptr /* Element */);
+}
+
+void LocalFrame::DidUpdateFramePolicy(const FramePolicy& frame_policy) {
+ // At the moment, this is only used to replicate sandbox flags and container
+ // policy for frames with a remote owner.
+ SECURITY_CHECK(IsA<RemoteFrameOwner>(Owner()));
+ To<RemoteFrameOwner>(Owner())->SetFramePolicy(frame_policy);
+}
+
+bool LocalFrame::ShouldThrottleDownload() {
+ const auto now = base::TimeTicks::Now();
+ if (num_burst_download_requests_ == 0) {
+ burst_download_start_time_ = now;
+ } else if (num_burst_download_requests_ >= kBurstDownloadLimit) {
+ static constexpr auto kBurstDownloadLimitResetInterval =
+ base::TimeDelta::FromSeconds(1);
+ if (now - burst_download_start_time_ > kBurstDownloadLimitResetInterval) {
+ num_burst_download_requests_ = 1;
+ burst_download_start_time_ = now;
+ return false;
+ }
+ return true;
+ }
+
+ num_burst_download_requests_++;
+ return false;
+}
+
void LocalFrame::BindToReceiver(
blink::LocalFrame* frame,
mojo::PendingAssociatedReceiver<mojom::blink::LocalFrame> receiver) {
@@ -1887,4 +2532,13 @@ void LocalFrame::BindToReceiver(
frame->GetTaskRunner(blink::TaskType::kInternalDefault));
}
+void LocalFrame::BindToMainFrameReceiver(
+ blink::LocalFrame* frame,
+ mojo::PendingAssociatedReceiver<mojom::blink::LocalMainFrame> receiver) {
+ DCHECK(frame);
+ frame->main_frame_receiver_.Bind(
+ std::move(receiver),
+ frame->GetTaskRunner(blink::TaskType::kInternalDefault));
+}
+
} // namespace blink
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 10b5a419b62..30763d3fc99 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame.h
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame.h
@@ -39,20 +39,24 @@
#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/ad_tagging/ad_frame.mojom-blink-forward.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"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/loader/pause_subresource_loading_handle.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/reporting/reporting.mojom-blink.h"
#include "third_party/blink/public/mojom/web_feature/web_feature.mojom-blink-forward.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/viewport_intersection_state.h"
+#include "third_party/blink/renderer/core/clipboard/raw_system_clipboard.h"
+#include "third_party/blink/renderer/core/clipboard/system_clipboard.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/weak_identifier_map.h"
#include "third_party/blink/renderer/core/editing/forward.h"
#include "third_party/blink/renderer/core/frame/frame.h"
#include "third_party/blink/renderer/core/frame/frame_types.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
+#include "third_party/blink/renderer/core/inspector/inspector_issue.h"
#include "third_party/blink/renderer/core/loader/frame_loader.h"
#include "third_party/blink/renderer/platform/graphics/touch_action.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -65,8 +69,8 @@ namespace base {
class SingleThreadTaskRunner;
}
-namespace service_manager {
-class InterfaceProvider;
+namespace gfx {
+class Point;
}
namespace blink {
@@ -86,6 +90,7 @@ class FrameConsole;
class FrameOverlay;
// class FrameScheduler;
class FrameSelection;
+class FrameWidget;
class InputMethodController;
class InspectorTraceEvents;
class CoreProbeSink;
@@ -115,7 +120,8 @@ extern template class CORE_EXTERN_TEMPLATE_EXPORT Supplement<LocalFrame>;
class CORE_EXPORT LocalFrame final : public Frame,
public FrameScheduler::Delegate,
public Supplementable<LocalFrame>,
- public mojom::blink::LocalFrame {
+ public mojom::blink::LocalFrame,
+ public mojom::blink::LocalMainFrame {
USING_GARBAGE_COLLECTED_MIXIN(LocalFrame);
public:
@@ -135,10 +141,10 @@ class CORE_EXPORT LocalFrame final : public Frame,
// Frame overrides:
~LocalFrame() override;
- void Trace(blink::Visitor*) override;
- void Navigate(const FrameLoadRequest&, WebFrameLoadType) override;
+ void Trace(Visitor*) override;
+ void Navigate(FrameLoadRequest&, WebFrameLoadType) override;
bool ShouldClose() override;
- SecurityContext* GetSecurityContext() const override;
+ const SecurityContext* GetSecurityContext() const override;
void PrintNavigationErrorMessage(const Frame&, const char* reason);
void PrintNavigationWarning(const String&);
bool DetachDocument() override;
@@ -150,9 +156,10 @@ class CORE_EXPORT LocalFrame final : public Frame,
// subtree, updating the inert bit on all descendant frames.
void SetIsInert(bool) override;
void SetInheritedEffectiveTouchAction(TouchAction) override;
- bool BubbleLogicalScrollFromChildFrame(ScrollDirection direction,
- ScrollGranularity granularity,
- Frame* child) override;
+ bool BubbleLogicalScrollFromChildFrame(
+ mojom::blink::ScrollDirection direction,
+ ScrollGranularity granularity,
+ Frame* child) override;
void DidFocus() override;
void DidChangeThemeColor();
@@ -280,8 +287,6 @@ class CORE_EXPORT LocalFrame final : public Frame,
// navigation at a later time.
bool CanNavigate(const Frame&, const KURL& destination_url = KURL());
- service_manager::InterfaceProvider& GetInterfaceProvider();
-
BrowserInterfaceBrokerProxy& GetBrowserInterfaceBroker();
InterfaceRegistry* GetInterfaceRegistry() { return interface_registry_; }
@@ -301,6 +306,13 @@ class CORE_EXPORT LocalFrame final : public Frame,
LocalFrameClient* Client() const;
+ // Returns the widget for this frame, or from the nearest ancestor which is a
+ // local root. It is never null for frames in ordinary Pages (which means the
+ // Page is inside a WebView), except very early in initialization. For frames
+ // in a non-ordinary Page (without a WebView, such as in unit tests, popups,
+ // devtools), it will always be null.
+ FrameWidget* GetWidgetForLocalRoot();
+
WebContentSettingsClient* GetContentSettingsClient();
PluginData* GetPluginData() const;
@@ -340,14 +352,26 @@ class CORE_EXPORT LocalFrame final : public Frame,
// remote ancestor frames and their respective scroll positions, clips, etc.
void SetViewportIntersectionFromParent(const ViewportIntersectionState&);
+ IntSize GetMainFrameViewportSize() const override;
+ IntPoint GetMainFrameScrollOffset() const override;
+
// See viewport_intersection_state.h for more info on these methods.
- IntPoint RemoteViewportOffset() const {
+ gfx::Point RemoteViewportOffset() const {
return intersection_state_.viewport_offset;
}
IntRect RemoteViewportIntersection() const {
return intersection_state_.viewport_intersection;
}
+ IntRect RemoteMainFrameDocumentIntersection() const {
+ return intersection_state_.main_frame_document_intersection;
+ }
+
+ bool CanSkipStickyFrameTracking() const {
+ return intersection_state_.can_skip_sticky_frame_tracking;
+ }
+
FrameOcclusionState GetOcclusionState() const;
+
bool NeedsOcclusionTracking() const;
// Replaces the initial empty document with a Document suitable for
@@ -367,12 +391,9 @@ class CORE_EXPORT LocalFrame final : public Frame,
// be removed.
bool IsProvisional() const;
- // True if AdTracker heuristics have determined that this frame is an ad.
- // Calculated in the constructor but LocalFrames created on behalf of OOPIF
- // aren't set until just before commit (ReadyToCommitNavigation time) by the
- // embedder.
- bool IsAdSubframe() const;
- bool IsAdRoot() const;
+ // Called in the constructor if AdTracker heuristics have determined that this
+ // frame is an ad; LocalFrames created on behalf of OOPIF aren't set until
+ // just before commit (ReadyToCommitNavigation time) by the embedder.
void SetIsAdSubframe(blink::mojom::AdFrameType ad_frame_type);
// Updates the frame color overlay to match the highlight ad setting.
@@ -397,7 +418,8 @@ class CORE_EXPORT LocalFrame final : public Frame,
const mojo::Remote<mojom::blink::ReportingServiceProxy>& GetReportingService()
const;
- // Returns the frame host ptr.
+ // Returns the frame host ptr. The interface returned is backed by an
+ // associated interface with the legacy Chrome IPC channel.
mojom::blink::LocalFrameHost& GetLocalFrameHostRemote();
// Overlays a color on top of this LocalFrameView if it is associated with
@@ -444,6 +466,8 @@ class CORE_EXPORT LocalFrame final : public Frame,
void FinishedLoading(FrameLoader::NavigationFinishState);
+ void UpdateFaviconURL();
+
using IsCapturingMediaCallback = base::RepeatingCallback<bool()>;
void SetIsCapturingMediaCallback(IsCapturingMediaCallback callback);
bool IsCapturingMedia() const;
@@ -454,18 +478,86 @@ class CORE_EXPORT LocalFrame final : public Frame,
void SetPrescientNetworkingForTesting(
std::unique_ptr<WebPrescientNetworking> prescient_networking);
+ void SetEmbeddingToken(const base::UnguessableToken& embedding_token);
+ const base::Optional<base::UnguessableToken>& GetEmbeddingToken() const;
+
+ void CopyImageAtViewportPoint(const IntPoint& viewport_point);
+ void MediaPlayerActionAtViewportPoint(
+ const IntPoint& viewport_position,
+ const blink::mojom::blink::MediaPlayerActionType type,
+ bool enable);
+
+ // Handle the request as a download. If the request is for a blob: URL,
+ // a BlobURLToken should be provided as |blob_url_token| to ensure the
+ // correct blob gets downloaded.
+ void DownloadURL(
+ const ResourceRequest& request,
+ network::mojom::blink::RedirectMode cross_origin_redirect_behavior);
+ void DownloadURL(
+ const ResourceRequest& request,
+ network::mojom::blink::RedirectMode cross_origin_redirect_behavior,
+ mojo::ScopedMessagePipeHandle blob_url_token);
+
// blink::mojom::LocalFrame overrides:
void GetTextSurroundingSelection(
uint32_t max_length,
GetTextSurroundingSelectionCallback callback) final;
void SendInterventionReport(const String& id, const String& message) final;
+ void SetFrameOwnerProperties(
+ mojom::blink::FrameOwnerPropertiesPtr properties) final;
void NotifyUserActivation() final;
void AddMessageToConsole(mojom::blink::ConsoleMessageLevel level,
const WTF::String& message,
bool discard_duplicates) final;
+ void AddInspectorIssue(mojom::blink::InspectorIssueInfoPtr) final;
void Collapse(bool collapsed) final;
void EnableViewSourceMode() final;
void Focus() final;
+ void ClearFocusedElement() final;
+ void GetResourceSnapshotForWebBundle(
+ mojo::PendingReceiver<
+ data_decoder::mojom::blink::ResourceSnapshotForWebBundle> receiver)
+ final;
+ void CopyImageAt(const gfx::Point& window_point) final;
+ void SaveImageAt(const gfx::Point& window_point) final;
+ void ReportBlinkFeatureUsage(const Vector<mojom::blink::WebFeature>&) final;
+ void RenderFallbackContent() final;
+ void BeforeUnload(bool is_reload, BeforeUnloadCallback callback) final;
+ void MediaPlayerActionAt(
+ const gfx::Point& window_point,
+ blink::mojom::blink::MediaPlayerActionPtr action) final;
+ void AdvanceFocusInForm(mojom::blink::FocusType focus_type) final;
+ void ReportContentSecurityPolicyViolation(
+ network::mojom::blink::CSPViolationPtr csp_violation) final;
+ // Updates the snapshotted policy attributes (sandbox flags and feature policy
+ // container policy) in the frame's FrameOwner. This is used when this frame's
+ // parent is in another process and it dynamically updates this frame's
+ // sandbox flags or container policy. The new policy won't take effect until
+ // the next navigation.
+ void DidUpdateFramePolicy(const FramePolicy& frame_policy) final;
+
+ // blink::mojom::LocalMainFrame overrides:
+ void AnimateDoubleTapZoom(const gfx::Point& point,
+ const gfx::Rect& rect) override;
+ void SetScaleFactor(float scale) override;
+ void ClosePage(
+ mojom::blink::LocalMainFrame::ClosePageCallback callback) override;
+ // Performs the specified plugin action on the node at the given location.
+ void PluginActionAt(const gfx::Point& location,
+ mojom::blink::PluginActionType action) override;
+ void SetInitialFocus(bool reverse) override;
+ void EnablePreferredSizeChangedMode() override;
+ void ZoomToFindInPageRect(const gfx::Rect& rect_in_root_frame) override;
+
+ SystemClipboard* GetSystemClipboard();
+ RawSystemClipboard* GetRawSystemClipboard();
+
+ // 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;
private:
friend class FrameNavigationDisabler;
@@ -504,9 +596,6 @@ class CORE_EXPORT LocalFrame final : public Frame,
// Activates the user activation states of this frame and all its ancestors.
void NotifyUserActivation(bool need_browser_verification);
- // Returns the transient user activation state of this frame
- bool HasTransientUserActivation();
-
// Consumes and returns the transient user activation state this frame, after
// updating all other frames in the frame tree.
bool ConsumeTransientUserActivation(UserActivationUpdateSource update_source);
@@ -520,9 +609,17 @@ class CORE_EXPORT LocalFrame final : public Frame,
void EvictFromBackForwardCache();
+ HitTestResult HitTestResultForVisualViewportPos(
+ const IntPoint& pos_in_viewport);
+
+ bool ShouldThrottleDownload();
+
static void BindToReceiver(
blink::LocalFrame* frame,
mojo::PendingAssociatedReceiver<mojom::blink::LocalFrame> receiver);
+ static void BindToMainFrameReceiver(
+ blink::LocalFrame* frame,
+ mojo::PendingAssociatedReceiver<mojom::blink::LocalMainFrame> receiver);
std::unique_ptr<FrameScheduler> frame_scheduler_;
@@ -560,12 +657,6 @@ class CORE_EXPORT LocalFrame final : public Frame,
bool in_view_source_mode_;
- // Type of frame detected by heuristics checking if the frame was created
- // for advertising purposes. It's per-frame (as opposed to per-document)
- // because when an iframe is created on behalf of ad script that same frame is
- // not typically reused for non-ad purposes.
- mojom::AdFrameType ad_frame_type_;
-
Member<CoreProbeSink> probe_sink_;
scoped_refptr<InspectorTaskRunner> inspector_task_runner_;
Member<PerformanceMonitor> performance_monitor_;
@@ -603,6 +694,8 @@ class CORE_EXPORT LocalFrame final : public Frame,
std::unique_ptr<FrameOverlay> frame_color_overlay_;
+ base::Optional<base::UnguessableToken> embedding_token_;
+
mojom::FrameLifecycleState lifecycle_state_;
base::Optional<mojom::FrameLifecycleState> pending_lifecycle_state_;
@@ -610,6 +703,25 @@ class CORE_EXPORT LocalFrame final : public Frame,
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};
+
+ // Variable to control burst of download requests.
+ int num_burst_download_requests_ = 0;
+ base::TimeTicks burst_download_start_time_;
+
+ // Access to the global sanitized system clipboard.
+ 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 {
@@ -677,7 +789,7 @@ class FrameNavigationDisabler {
~FrameNavigationDisabler();
private:
- Member<LocalFrame> frame_;
+ LocalFrame* frame_;
DISALLOW_COPY_AND_ASSIGN(FrameNavigationDisabler);
};
@@ -713,7 +825,7 @@ class ScopedFrameBlamer {
private:
void LeaveContext();
- Member<LocalFrame> frame_;
+ LocalFrame* frame_;
DISALLOW_COPY_AND_ASSIGN(ScopedFrameBlamer);
};
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 a49ecf33a1a..5faee38f8a7 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
@@ -33,9 +33,11 @@
#include <memory>
+#include "base/optional.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_remote.h"
+#include "services/network/public/mojom/content_security_policy.mojom-blink-forward.h"
#include "services/network/public/mojom/ip_address_space.mojom-blink-forward.h"
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
#include "third_party/blink/public/common/loader/loading_behavior_flag.h"
@@ -45,10 +47,8 @@
#include "third_party/blink/public/mojom/portal/portal.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/use_counter/css_property_id.mojom-blink-forward.h"
#include "third_party/blink/public/platform/scheduler/web_scoped_virtual_time_pauser.h"
-#include "third_party/blink/public/platform/web_content_security_policy_struct.h"
#include "third_party/blink/public/platform/web_content_settings_client.h"
#include "third_party/blink/public/platform/web_effective_connection_type.h"
-#include "third_party/blink/public/platform/web_insecure_request_policy.h"
#include "third_party/blink/public/platform/web_worker_fetch_context.h"
#include "third_party/blink/public/web/web_frame_load_type.h"
#include "third_party/blink/public/web/web_history_commit_type.h"
@@ -76,16 +76,13 @@
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "v8/include/v8.h"
-namespace service_manager {
-class InterfaceProvider;
-} // namespace service_manager
-
namespace blink {
namespace mojom {
enum class WebFeature : int32_t;
} // namespace mojom
class AssociatedInterfaceProvider;
+class ContentSecurityPolicy;
class Document;
class DocumentLoader;
class HTMLFormElement;
@@ -107,10 +104,8 @@ class WebMediaPlayer;
class WebMediaPlayerClient;
class WebMediaPlayerSource;
class WebRemotePlaybackClient;
-struct WebResourceTimingInfo;
class WebServiceWorkerProvider;
class WebSpellCheckPanelHostClient;
-struct WebScrollIntoViewParams;
class WebTextCheckClient;
class CORE_EXPORT LocalFrameClient : public FrameClient {
@@ -135,9 +130,7 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
virtual void DidFinishSameDocumentNavigation(HistoryItem*,
WebHistoryCommitType,
bool content_initiated) {}
- virtual void DispatchDidStartProvisionalLoad(DocumentLoader*) = 0;
virtual void DispatchDidReceiveTitle(const String&) = 0;
- virtual void DispatchDidChangeIcons(IconType) = 0;
virtual void DispatchDidCommitLoad(HistoryItem*,
WebHistoryCommitType,
GlobalObjectReusePolicy) = 0;
@@ -148,7 +141,7 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
virtual void BeginNavigation(
const ResourceRequest&,
- network::mojom::RequestContextFrameType,
+ mojom::RequestContextFrameType,
Document* origin_document,
DocumentLoader*,
WebNavigationType,
@@ -158,33 +151,24 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
bool is_client_redirect,
TriggeringEventInfo,
HTMLFormElement*,
- ContentSecurityPolicyDisposition
+ network::mojom::CSPDisposition
should_check_main_world_content_security_policy,
mojo::PendingRemote<mojom::blink::BlobURLToken>,
base::TimeTicks input_start_time,
const String& href_translate,
- WebContentSecurityPolicyList,
+ WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr>
+ initiator_csp,
+ network::mojom::blink::CSPSourcePtr initiator_self_source,
network::mojom::IPAddressSpace,
mojo::PendingRemote<mojom::blink::NavigationInitiator>) = 0;
virtual void DispatchWillSendSubmitEvent(HTMLFormElement*) = 0;
virtual void DidStartLoading() = 0;
- virtual void ProgressEstimateChanged(double progress_estimate) = 0;
virtual void DidStopLoading() = 0;
- virtual void ForwardResourceTimingToParent(const WebResourceTimingInfo&) = 0;
-
- virtual void DownloadURL(const ResourceRequest&,
- network::mojom::RedirectMode) = 0;
-
virtual bool NavigateBackForward(int offset) const = 0;
- // Another page has accessed the initial empty document of this frame. It is
- // no longer safe to display a provisional URL, since a URL spoof is now
- // possible.
- virtual void DidAccessInitialDocument() {}
-
// The indicated security origin has run active content (such as a script)
// from an insecure source. Note that the insecure content can spread to
// other frames in the same origin.
@@ -198,6 +182,8 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
// Will be called when |PerformanceTiming| events are updated
virtual void DidChangePerformanceTiming() {}
+ // Will be called when an |InputEvent| is observed.
+ virtual void DidObserveInputDelay(base::TimeDelta input_delay) {}
// Will be called when |CpuTiming| events are updated
virtual void DidChangeCpuTiming(base::TimeDelta time) {}
@@ -240,6 +226,7 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
virtual DocumentLoader* CreateDocumentLoader(
LocalFrame*,
WebNavigationType,
+ ContentSecurityPolicy*,
std::unique_ptr<WebNavigationParams> navigation_params,
std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) = 0;
@@ -248,7 +235,7 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) = 0;
virtual String UserAgent() = 0;
- virtual blink::UserAgentMetadata UserAgentMetadata() = 0;
+ virtual base::Optional<blink::UserAgentMetadata> UserAgentMetadata() = 0;
virtual String DoNotTrackValue() = 0;
@@ -292,7 +279,8 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
virtual WebRemotePlaybackClient* CreateWebRemotePlaybackClient(
HTMLMediaElement&) = 0;
- virtual void DidCreateNewDocument() = 0;
+ virtual void DidCreateInitialEmptyDocument() = 0;
+ virtual void DidCommitJavascriptUrlNavigation(DocumentLoader*) = 0;
virtual void DispatchDidClearWindowObjectInMainWorld() = 0;
virtual void DocumentElementAvailable() = 0;
virtual void RunScriptsAtDocumentElementAvailable() = 0;
@@ -319,20 +307,12 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
virtual void DidChangeFramePolicy(Frame* child_frame, const FramePolicy&) {}
virtual void DidSetFramePolicyHeaders(
- WebSandboxFlags,
- const ParsedFeaturePolicy& parsed_header) {}
-
- // Called when a set of new Content Security Policies is added to the frame's
- // document. This can be triggered by handling of HTTP headers, handling of
- // <meta> element, or by inheriting CSP from the parent (in case of
- // about:blank).
- virtual void DidAddContentSecurityPolicies(
- const blink::WebVector<WebContentSecurityPolicy>&) {}
+ mojom::blink::WebSandboxFlags,
+ const ParsedFeaturePolicy& feature_policy_header,
+ const DocumentPolicy::FeatureState& document_policy_header) {}
virtual void DidChangeFrameOwnerProperties(HTMLFrameOwnerElement*) {}
- virtual bool ShouldBlockWebGL() { return false; }
-
virtual std::unique_ptr<WebServiceWorkerProvider>
CreateServiceWorkerProvider() = 0;
@@ -350,25 +330,12 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
virtual BlameContext* GetFrameBlameContext() { return nullptr; }
- virtual service_manager::InterfaceProvider* GetInterfaceProvider() {
- return nullptr;
- }
-
virtual BrowserInterfaceBrokerProxy& GetBrowserInterfaceBroker() = 0;
virtual AssociatedInterfaceProvider*
GetRemoteNavigationAssociatedInterfaces() = 0;
- // Notify the embedder that the associated frame has user activation so that
- // the replicated states in the browser and other renderers can be updated.
- virtual void NotifyUserActivation(bool need_browser_verification) {}
-
- // Tell the embedder that the associated frame has consumed user activation so
- // that the replicated states in the browser and other renderers can be
- // updated.
- virtual void ConsumeUserActivation() {}
-
- virtual void SetHasReceivedUserGestureBeforeNavigation(bool value) {}
+ virtual void NotifyUserActivation() {}
virtual void AbortClientNavigation() {}
@@ -380,20 +347,6 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
virtual void AnnotatedRegionsChanged() = 0;
- virtual void DidBlockNavigation(const KURL& blocked_url,
- const KURL& initiator_urk,
- blink::NavigationBlockedReason reason) {}
-
- // Called when the corresponding frame should be scrolled in a remote parent
- // frame.
- virtual void ScrollRectToVisibleInParentFrame(
- const WebRect&,
- const WebScrollIntoViewParams&) {}
-
- virtual void BubbleLogicalScrollInParentFrame(
- ScrollDirection direction,
- ScrollGranularity granularity) = 0;
-
virtual void SetVirtualTimePauser(
WebScopedVirtualTimePauser virtual_time_pauser) {}
@@ -409,6 +362,8 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
virtual void FrameRectsChanged(const IntRect&) {}
+ virtual void FocusedElementChanged(Element* element) {}
+
// Returns true when the contents of plugin are handled externally. This means
// the plugin element will own a content frame but the frame is than used
// externally to load the required handelrs.
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 a417e92455d..0d63d5a2b8e 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
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/dom/node_computed_style.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/core_unit_test_helper.h"
@@ -107,4 +108,81 @@ TEST_F(LocalFrameTest,
page_holder->GetFrame().GetLazyLoadImageSetting());
}
+namespace {
+
+void TestGreenDiv(DummyPageHolder& page_holder) {
+ const Document& doc = page_holder.GetDocument();
+ Element* div = doc.getElementById("div");
+ ASSERT_TRUE(div);
+ ASSERT_TRUE(div->GetComputedStyle());
+ EXPECT_EQ(MakeRGB(0, 128, 0), div->GetComputedStyle()->VisitedDependentColor(
+ GetCSSPropertyColor()));
+}
+
+} // namespace
+
+TEST_F(LocalFrameTest, ForceSynchronousDocumentInstall_XHTMLStyleInBody) {
+ auto page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
+
+ scoped_refptr<SharedBuffer> data = SharedBuffer::Create();
+ data->Append(
+ "<html xmlns='http://www.w3.org/1999/xhtml'><body><style>div { color: "
+ "green }</style><div id='div'></div></body></html>",
+ static_cast<size_t>(118));
+ page_holder->GetFrame().ForceSynchronousDocumentInstall("text/xml", data);
+ TestGreenDiv(*page_holder);
+}
+
+TEST_F(LocalFrameTest, ForceSynchronousDocumentInstall_XHTMLLinkInBody) {
+ auto page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
+
+ scoped_refptr<SharedBuffer> data = SharedBuffer::Create();
+ data->Append(
+ "<html xmlns='http://www.w3.org/1999/xhtml'><body><link rel='stylesheet' "
+ "href='data:text/css,div{color:green}' /><div "
+ "id='div'></div></body></html>",
+ static_cast<size_t>(146));
+ page_holder->GetFrame().ForceSynchronousDocumentInstall("text/xml", data);
+ TestGreenDiv(*page_holder);
+}
+
+TEST_F(LocalFrameTest, ForceSynchronousDocumentInstall_XHTMLStyleInHead) {
+ auto page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
+
+ scoped_refptr<SharedBuffer> data = SharedBuffer::Create();
+ data->Append(
+ "<html xmlns='http://www.w3.org/1999/xhtml'><head><style>div { color: "
+ "green }</style></head><body><div id='div'></div></body></html>",
+ static_cast<size_t>(131));
+ page_holder->GetFrame().ForceSynchronousDocumentInstall("text/xml", data);
+ TestGreenDiv(*page_holder);
+}
+
+TEST_F(LocalFrameTest, ForceSynchronousDocumentInstall_XHTMLLinkInHead) {
+ auto page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
+
+ scoped_refptr<SharedBuffer> data = SharedBuffer::Create();
+ data->Append(
+ "<html xmlns='http://www.w3.org/1999/xhtml'><head><link rel='stylesheet' "
+ "href='data:text/css,div{color:green}' /></head><body><div "
+ "id='div'></div></body></html>",
+ static_cast<size_t>(159));
+ page_holder->GetFrame().ForceSynchronousDocumentInstall("text/xml", data);
+ TestGreenDiv(*page_holder);
+}
+
+TEST_F(LocalFrameTest, ForceSynchronousDocumentInstall_XMLStyleSheet) {
+ auto page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
+
+ scoped_refptr<SharedBuffer> data = SharedBuffer::Create();
+ data->Append(
+ "<?xml-stylesheet type='text/css' "
+ "href='data:text/css,div{color:green}'?><html "
+ "xmlns='http://www.w3.org/1999/xhtml'><body><div "
+ "id='div'></div></body></html>",
+ static_cast<size_t>(155));
+ page_holder->GetFrame().ForceSynchronousDocumentInstall("text/xml", data);
+ TestGreenDiv(*page_holder);
+}
+
} // namespace blink
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 70b0dbc8571..5cbb3af800a 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
@@ -139,6 +139,14 @@ LocalFrameUkmAggregator::LocalFrameUkmAggregator(int64_t source_id,
uma_percentage_name.ToString().Utf8().c_str(), 0, 10000000, 50));
}
}
+
+ // Make space in the current sample.
+ current_sample_.sub_metrics_durations.Grow(static_cast<wtf_size_t>(kCount));
+ current_sample_.sub_metric_percentages.Grow(static_cast<wtf_size_t>(kCount));
+}
+
+LocalFrameUkmAggregator::~LocalFrameUkmAggregator() {
+ ReportUpdateTimeEvent();
}
LocalFrameUkmAggregator::ScopedUkmHierarchicalTimer
@@ -157,6 +165,8 @@ LocalFrameUkmAggregator::GetBeginMainFrameMetrics() {
// Use the main_frame_percentage_records_ because they are the ones that
// only count time between the Begin and End of a main frame update.
+ // Do not report hit testing because it is a sub-portion of the other
+ // metrics and would result in double counting.
std::unique_ptr<cc::BeginMainFrameMetrics> metrics_data =
std::make_unique<cc::BeginMainFrameMetrics>();
metrics_data->handle_input_events =
@@ -203,10 +213,10 @@ void LocalFrameUkmAggregator::RecordForcedStyleLayoutUMA(
if (!calls_to_next_forced_style_layout_uma_) {
auto& record = absolute_metric_records_[kForcedStyleAndLayout];
record.uma_counter->CountMicroseconds(duration);
- if (is_before_fcp_)
- record.pre_fcp_uma_counter->CountMicroseconds(duration);
- else
+ if (fcp_state_ == kHavePassedFCP)
record.post_fcp_uma_counter->CountMicroseconds(duration);
+ else
+ record.pre_fcp_uma_counter->CountMicroseconds(duration);
calls_to_next_forced_style_layout_uma_ =
base::RandInt(0, mean_calls_between_forced_style_layout_uma_ * 2);
} else {
@@ -217,67 +227,27 @@ void LocalFrameUkmAggregator::RecordForcedStyleLayoutUMA(
void LocalFrameUkmAggregator::DidReachFirstContentfulPaint(
bool are_painting_main_frame) {
- DCHECK(is_before_fcp_);
-
- is_before_fcp_ = false;
+ DCHECK(fcp_state_ != kHavePassedFCP);
if (!are_painting_main_frame) {
DCHECK(AllMetricsAreZero());
return;
}
-#define CASE_FOR_ID(name) \
- case k##name: \
- builder.Set##name(absolute_record.pre_fcp_aggregate.InMicroseconds()); \
- break
-
- ukm::builders::Blink_PageLoad builder(source_id_);
- builder.SetMainFrame(primary_metric_.pre_fcp_aggregate.InMicroseconds());
- primary_metric_.uma_aggregate_counter->CountMicroseconds(
- primary_metric_.pre_fcp_aggregate);
- for (unsigned i = 0; i < (unsigned)kCount; ++i) {
- auto& absolute_record = absolute_metric_records_[i];
- if (absolute_record.uma_aggregate_counter) {
- absolute_record.uma_aggregate_counter->CountMicroseconds(
- absolute_record.pre_fcp_aggregate);
- }
-
- switch (static_cast<MetricId>(i)) {
- CASE_FOR_ID(Compositing);
- CASE_FOR_ID(CompositingCommit);
- CASE_FOR_ID(IntersectionObservation);
- CASE_FOR_ID(Paint);
- CASE_FOR_ID(PrePaint);
- CASE_FOR_ID(StyleAndLayout);
- CASE_FOR_ID(Style);
- CASE_FOR_ID(Layout);
- CASE_FOR_ID(ForcedStyleAndLayout);
- CASE_FOR_ID(ScrollingCoordinator);
- CASE_FOR_ID(HandleInputEvents);
- CASE_FOR_ID(Animate);
- CASE_FOR_ID(UpdateLayers);
- CASE_FOR_ID(ProxyCommit);
- case kCount:
- case kMainFrame:
- NOTREACHED();
- break;
- }
- }
- builder.Record(recorder_);
-
-#undef CASE_FOR_ID
+ fcp_state_ = kThisFrameReachedFCP;
}
void LocalFrameUkmAggregator::RecordSample(size_t metric_index,
base::TimeTicks start,
base::TimeTicks end) {
base::TimeDelta duration = end - start;
+ bool is_pre_fcp = (fcp_state_ != kHavePassedFCP);
// Accumulate for UKM and record the UMA
DCHECK_LT(metric_index, absolute_metric_records_.size());
auto& record = absolute_metric_records_[metric_index];
record.interval_duration += duration;
- if (is_before_fcp_)
+ if (is_pre_fcp)
record.pre_fcp_aggregate += duration;
// Record the UMA
// ForcedStyleAndLayout happen so frequently on some pages that we overflow
@@ -288,7 +258,7 @@ void LocalFrameUkmAggregator::RecordSample(size_t metric_index,
RecordForcedStyleLayoutUMA(duration);
} else {
record.uma_counter->CountMicroseconds(duration);
- if (is_before_fcp_) {
+ if (is_pre_fcp) {
record.pre_fcp_uma_counter->CountMicroseconds(duration);
} else {
record.post_fcp_uma_counter->CountMicroseconds(duration);
@@ -304,8 +274,33 @@ void LocalFrameUkmAggregator::RecordSample(size_t metric_index,
}
}
-void LocalFrameUkmAggregator::RecordEndOfFrameMetrics(base::TimeTicks start,
- base::TimeTicks end) {
+void LocalFrameUkmAggregator::RecordImplCompositorSample(
+ base::TimeTicks requested,
+ base::TimeTicks started,
+ base::TimeTicks completed) {
+ // Record the time spent waiting for the commit based on requested
+ // (which came from ProxyImpl::BeginMainFrame) and started as reported by
+ // the impl thread. If started is zero, no time was spent
+ // processing. This can only happen if the commit was aborted because there
+ // was no change and we did not wait for the impl thread at all. Attribute
+ // all time to the compositor commit so as to not imply that wait time was
+ // consumed.
+ if (started == base::TimeTicks()) {
+ RecordSample(kImplCompositorCommit, requested, completed);
+ } else {
+ 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(
+ base::TimeTicks start,
+ base::TimeTicks end,
+ cc::ActiveFrameSequenceTrackers trackers) {
// Any of the early out's in LocalFrameView::UpdateLifecyclePhases
// will mean we are not in a main frame update. Recording is triggered
// higher in the stack, so we cannot know to avoid calling this method.
@@ -318,17 +313,19 @@ void LocalFrameUkmAggregator::RecordEndOfFrameMetrics(base::TimeTicks start,
in_main_frame_update_ = false;
base::TimeDelta duration = end - start;
+ bool report_as_pre_fcp = (fcp_state_ != kHavePassedFCP);
+ bool report_fcp_metrics = (fcp_state_ == kThisFrameReachedFCP);
// Record UMA
primary_metric_.uma_counter->CountMicroseconds(duration);
- if (is_before_fcp_)
+ if (report_as_pre_fcp)
primary_metric_.pre_fcp_uma_counter->CountMicroseconds(duration);
else
primary_metric_.post_fcp_uma_counter->CountMicroseconds(duration);
// Record primary time information
primary_metric_.interval_duration = duration;
- if (is_before_fcp_)
+ if (report_as_pre_fcp)
primary_metric_.pre_fcp_aggregate += duration;
// Compute all the dependent metrics, after finding which bucket we're in
@@ -349,55 +346,139 @@ void LocalFrameUkmAggregator::RecordEndOfFrameMetrics(base::TimeTicks start,
// Record here to avoid resetting the ratios before this data point is
// recorded.
- UpdateEventTimeAndRecordEventIfNeeded();
+ UpdateEventTimeAndUpdateSampleIfNeeded(trackers);
+
+ // Report the FCP metrics, if necessary, after updating the sample so that
+ // the sample has been recorded for the frame that produced FCP.
+ if (report_fcp_metrics) {
+ ReportPreFCPEvent();
+ ReportUpdateTimeEvent();
+ // Update the state to prevent future reporting.
+ fcp_state_ = kHavePassedFCP;
+ }
// Reset for the next frame.
ResetAllMetrics();
}
-void LocalFrameUkmAggregator::UpdateEventTimeAndRecordEventIfNeeded() {
- // TODO(schenney) Adjust the mean sample interval so that we do not
- // get our events throttled by the UKM system. For M-73 only 1 in 212
- // events are being sent.
- if (!frames_to_next_event_) {
- RecordEvent();
- frames_to_next_event_ += SampleFramesToNextEvent();
+void LocalFrameUkmAggregator::UpdateEventTimeAndUpdateSampleIfNeeded(
+ cc::ActiveFrameSequenceTrackers trackers) {
+ // Update the frame count first, because it must include this frame
+ frames_since_last_report_++;
+
+ // Regardless of test requests, always capture the first frame.
+ if (frames_since_last_report_ == 1) {
+ UpdateSample(trackers);
+ return;
}
- DCHECK_GT(frames_to_next_event_, 0u);
- --frames_to_next_event_;
+
+ // Exit if in testing and we do not want to update this frame
+ if (next_frame_sample_control_for_test_ == kMustNotChooseNextFrame)
+ return;
+
+ // Update the sample with probability 1/frames_since_last_report_, or if
+ // testing demand is.
+ if ((next_frame_sample_control_for_test_ == kMustChooseNextFrame) ||
+ base::RandDouble() < 1 / static_cast<double>(frames_since_last_report_)) {
+ UpdateSample(trackers);
+ }
+}
+
+void LocalFrameUkmAggregator::UpdateSample(
+ cc::ActiveFrameSequenceTrackers trackers) {
+ current_sample_.primary_metric_duration = primary_metric_.interval_duration;
+ float primary_metric_in_microseconds =
+ primary_metric_.interval_duration.InMicrosecondsF();
+ for (unsigned i = 0; i < static_cast<unsigned>(kCount); ++i) {
+ current_sample_.sub_metrics_durations[i] =
+ absolute_metric_records_[i].interval_duration;
+ current_sample_.sub_metric_percentages[i] = static_cast<unsigned>(floor(
+ main_frame_percentage_records_[i].interval_duration.InMicrosecondsF() *
+ 100.0 / primary_metric_in_microseconds));
+ }
+ current_sample_.trackers = trackers;
}
-void LocalFrameUkmAggregator::RecordEvent() {
-#define CASE_FOR_ID(name) \
- case k##name: \
- builder.Set##name(absolute_record.interval_duration.InMicroseconds()) \
- .Set##name##Percentage(percentage); \
+void LocalFrameUkmAggregator::ReportPreFCPEvent() {
+#define CASE_FOR_ID(name) \
+ case k##name: \
+ builder.Set##name(absolute_record.pre_fcp_aggregate.InMicroseconds()); \
break
- ukm::builders::Blink_UpdateTime builder(source_id_);
- builder.SetMainFrame(primary_metric_.interval_duration.InMicroseconds());
- builder.SetMainFrameIsBeforeFCP(is_before_fcp_);
- for (unsigned i = 0; i < (unsigned)kCount; ++i) {
+ ukm::builders::Blink_PageLoad builder(source_id_);
+ builder.SetMainFrame(primary_metric_.pre_fcp_aggregate.InMicroseconds());
+ primary_metric_.uma_aggregate_counter->CountMicroseconds(
+ primary_metric_.pre_fcp_aggregate);
+ for (unsigned i = 0; i < static_cast<unsigned>(kCount); ++i) {
auto& absolute_record = absolute_metric_records_[i];
- auto& percentage_record = main_frame_percentage_records_[i];
- unsigned percentage = (unsigned)floor(
- percentage_record.interval_duration.InMicrosecondsF() * 100.0 /
- primary_metric_.interval_duration.InMicrosecondsF());
+ if (absolute_record.uma_aggregate_counter) {
+ absolute_record.uma_aggregate_counter->CountMicroseconds(
+ absolute_record.pre_fcp_aggregate);
+ }
+
switch (static_cast<MetricId>(i)) {
CASE_FOR_ID(Compositing);
CASE_FOR_ID(CompositingCommit);
+ CASE_FOR_ID(ImplCompositorCommit);
CASE_FOR_ID(IntersectionObservation);
CASE_FOR_ID(Paint);
CASE_FOR_ID(PrePaint);
- CASE_FOR_ID(StyleAndLayout);
CASE_FOR_ID(Style);
CASE_FOR_ID(Layout);
CASE_FOR_ID(ForcedStyleAndLayout);
+ CASE_FOR_ID(HitTestDocumentUpdate);
CASE_FOR_ID(ScrollingCoordinator);
CASE_FOR_ID(HandleInputEvents);
CASE_FOR_ID(Animate);
CASE_FOR_ID(UpdateLayers);
CASE_FOR_ID(ProxyCommit);
+ CASE_FOR_ID(WaitForCommit);
+ case kCount:
+ case kMainFrame:
+ NOTREACHED();
+ break;
+ }
+ }
+ builder.Record(recorder_);
+#undef CASE_FOR_ID
+}
+
+void LocalFrameUkmAggregator::ReportUpdateTimeEvent() {
+ // Don't report if we haven't generated any samples.
+ if (!frames_since_last_report_)
+ return;
+
+#define CASE_FOR_ID(name, index) \
+ case k##name: \
+ builder \
+ .Set##name( \
+ current_sample_.sub_metrics_durations[index].InMicroseconds()) \
+ .Set##name##Percentage(current_sample_.sub_metric_percentages[index]); \
+ break
+
+ ukm::builders::Blink_UpdateTime builder(source_id_);
+ builder.SetMainFrame(
+ current_sample_.primary_metric_duration.InMicroseconds());
+ builder.SetMainFrameIsBeforeFCP(fcp_state_ != kHavePassedFCP);
+ builder.SetMainFrameReasons(current_sample_.trackers);
+ for (unsigned i = 0; i < static_cast<unsigned>(kCount); ++i) {
+ switch (static_cast<MetricId>(i)) {
+ CASE_FOR_ID(Compositing, i);
+ CASE_FOR_ID(CompositingCommit, i);
+ CASE_FOR_ID(ImplCompositorCommit, i);
+ CASE_FOR_ID(IntersectionObservation, i);
+ CASE_FOR_ID(Paint, i);
+ CASE_FOR_ID(PrePaint, i);
+ CASE_FOR_ID(Style, i);
+ CASE_FOR_ID(Layout, i);
+ CASE_FOR_ID(ForcedStyleAndLayout, i);
+ CASE_FOR_ID(HitTestDocumentUpdate, i);
+ CASE_FOR_ID(ScrollingCoordinator, i);
+ 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:
NOTREACHED();
@@ -406,6 +487,9 @@ void LocalFrameUkmAggregator::RecordEvent() {
}
builder.Record(recorder_);
#undef CASE_FOR_ID
+
+ // Reset the frames since last report to ensure correct sampling.
+ frames_since_last_report_ = 0;
}
void LocalFrameUkmAggregator::ResetAllMetrics() {
@@ -416,38 +500,6 @@ void LocalFrameUkmAggregator::ResetAllMetrics() {
record.reset();
}
-unsigned LocalFrameUkmAggregator::SampleFramesToNextEvent() {
- // Return the test interval if set
- if (frames_to_next_event_for_test_)
- return frames_to_next_event_for_test_;
-
- // Sample from an exponential distribution to give a poisson distribution
- // of samples per time unit, then weigh it with an exponential multiplier to
- // give a few samples in rapid succession (for frames early in the page's
- // life) then exponentially fewer as the page lives longer.
- // RandDouble() returns [0,1), but we need (0,1]. If RandDouble() is
- // uniformly random, so is 1-RandDouble(), so use it to adjust the range.
- // When RandDouble returns 0.0, as it could, we will get a float_sample of
- // 0, causing underflow in UpdateEventTimeAndRecordIfNeeded. So rejection
- // sample until we get a positive count.
- double float_sample = 0;
- do {
- float_sample = -(sample_rate_multiplier_ *
- std::exp(samples_so_far_ / sample_decay_rate_) *
- std::log(1.0 - base::RandDouble()));
- } while (float_sample == 0);
- // float_sample is positive, so we don't need to worry about underflow.
- // After around 100 samples we will end up with a super high
- // sample. That's OK because it just means we'll stop reporting metrics
- // for that session, but we do need to be careful about overflow and NaN.
- samples_so_far_++;
- unsigned unsigned_sample =
- std::isnan(float_sample)
- ? UINT_MAX
- : base::saturated_cast<unsigned>(std::ceil(float_sample));
- return unsigned_sample;
-}
-
bool LocalFrameUkmAggregator::AllMetricsAreZero() {
if (primary_metric_.interval_duration.InMicroseconds())
return false;
@@ -459,4 +511,12 @@ bool LocalFrameUkmAggregator::AllMetricsAreZero() {
return true;
}
+void LocalFrameUkmAggregator::ChooseNextFrameForTest() {
+ next_frame_sample_control_for_test_ = kMustChooseNextFrame;
+}
+
+void LocalFrameUkmAggregator::DoNotChooseNextFrameForTest() {
+ next_frame_sample_control_for_test_ = kMustNotChooseNextFrame;
+}
+
} // namespace blink
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 f2702ff605c..ef31447acc5 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
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_LOCAL_FRAME_UKM_AGGREGATOR_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_LOCAL_FRAME_UKM_AGGREGATOR_H_
+#include "cc/metrics/frame_sequence_tracker.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -34,7 +35,7 @@ namespace blink {
// - recorder: UkmRecorder which will handle the events
//
// The aggregator manages all of the UKM and UMA names for LocalFrameView.
-// It constructs and takes ownership the UMA counters when constructed
+// It constructs and takes ownership of the UMA counters when constructed
// itself. We do this to localize all UMA and UKM metrics in one place, so
// that adding a metric is localized to the cc file of this class, protected
// from errors that might arise when adding names in multiple places.
@@ -52,12 +53,11 @@ namespace blink {
// primary time and computes metrics that depend on it. UMA metrics are updated
// at this time.
//
-// A UKM event is generated according to a sampling strategy. A record is always
-// generated on the first lifecycle update, and then additional samples are
-// taken at random frames simulating a poisson process with mean number of
-// frames between events of mean_frames_between_samples_. The first primary
-// metric recording after the frame count has passed will produce an event with
-// all the data for that frame (i.e. the period since the last BeginMainFrame).
+// A UKM event is generated according to a sampling strategy, with the goal
+// being to choose one frame to report before First Contentful Paint and
+// one frame to report during the subsequent document lifetime. We maintain
+// a copy of the current sample, and randomly choose to update it on each frame
+// such that any given frame is equally likely to be the final sample.
//
// Sample usage (see also SCOPED_UMA_AND_UKM_TIMER):
// std::unique_ptr<UkmHierarchicalTimeAggregator> aggregator(
@@ -74,9 +74,10 @@ namespace blink {
// // At this point data for kMetric2 is recorded.
// ...
// // When the primary time completes
-// aggregator->RecordEndOfFrameMetrics(time_delta);
+// aggregator->RecordEndOfFrameMetrics(start, end, trackers);
// // This records a primary sample and the sub-metrics that depend on it.
-// // It may generate an event.
+// // It may generate an event. trackers is a bit encoding of the active frame
+//. // sequence trackers, informing us of why the BeginMainFrame was requested.
//
// In the example above, the event name is "my_event". It will measure 7
// metrics:
@@ -129,18 +130,20 @@ class CORE_EXPORT LocalFrameUkmAggregator
enum MetricId {
kCompositing,
kCompositingCommit,
+ kImplCompositorCommit,
kIntersectionObservation,
kPaint,
kPrePaint,
- kStyleAndLayout, // Remove for M-80
kStyle,
kLayout,
kForcedStyleAndLayout,
+ kHitTestDocumentUpdate,
kScrollingCoordinator,
kHandleInputEvents,
kAnimate,
kUpdateLayers,
kProxyCommit,
+ kWaitForCommit,
kCount,
kMainFrame
};
@@ -165,18 +168,20 @@ class CORE_EXPORT LocalFrameUkmAggregator
static const Vector<MetricInitializationData>* data =
new Vector<MetricInitializationData>{{"Compositing", true},
{"CompositingCommit", true},
+ {"ImplCompositorCommit", true},
{"IntersectionObservation", true},
{"Paint", true},
{"PrePaint", true},
- {"StyleAndLayout", true},
{"Style", true},
{"Layout", true},
{"ForcedStyleAndLayout", true},
+ {"HitTestDocumentUpdate", true},
{"ScrollingCoordinator", true},
{"HandleInputEvents", true},
{"Animate", true},
{"UpdateLayers", false},
- {"ProxyCommit", true}};
+ {"ProxyCommit", true},
+ {"WaitForCommit", true}};
return *data;
}
@@ -218,7 +223,7 @@ class CORE_EXPORT LocalFrameUkmAggregator
};
LocalFrameUkmAggregator(int64_t source_id, ukm::UkmRecorder*);
- ~LocalFrameUkmAggregator() = default;
+ ~LocalFrameUkmAggregator();
// Create a scoped timer with the index of the metric. Note the index must
// correspond to the matching index in metric_names.
@@ -227,8 +232,11 @@ class CORE_EXPORT LocalFrameUkmAggregator
// Record a main frame time metric, that also computes the ratios for the
// sub-metrics and generates UMA samples. UKM is only reported when
// BeginMainFrame() had been called. All counters are cleared when this method
- // is called.
- void RecordEndOfFrameMetrics(base::TimeTicks start, base::TimeTicks end);
+ // is called. trackers is a bit encoding of the active frame sequence
+ // trackers, telling us the reasons for requesting a BeginMainFrame.
+ void RecordEndOfFrameMetrics(base::TimeTicks start,
+ base::TimeTicks end,
+ cc::ActiveFrameSequenceTrackers trackers);
// Record a sample for a sub-metric. This should only be used when
// a ScopedUkmHierarchicalTimer cannot be used (such as when the timed
@@ -237,12 +245,22 @@ class CORE_EXPORT LocalFrameUkmAggregator
base::TimeTicks start,
base::TimeTicks end);
+ // Record a sample for the impl-side compositor processing.
+ // - requested is the time the renderer proxy requests a commit
+ // - started is the time the impl thread begins processing the request
+ // - completed is the time the renderer proxy receives notification that the
+ // commit is complete.
+ void RecordImplCompositorSample(base::TimeTicks requested,
+ base::TimeTicks started,
+ base::TimeTicks completed);
+
// Mark the beginning of a main frame update.
void BeginMainFrame();
// Inform the aggregator that we have reached First Contentful Paint.
- // The UKM event reports this and UMA for aggregated contributions to
- // FCP are reported if are_painting_main_frame is true.
+ // The UKM event for the pre-FCP period will be recorded and UMA for
+ // aggregated contributions to FCP are reported if are_painting_main_frame
+ // is true.
void DidReachFirstContentfulPaint(bool are_painting_main_frame);
bool InMainFrameUpdate() { return in_main_frame_update_; }
@@ -278,21 +296,36 @@ class CORE_EXPORT LocalFrameUkmAggregator
void reset() { interval_duration = base::TimeDelta(); }
};
- void UpdateEventTimeAndRecordEventIfNeeded();
- void RecordEvent();
+ struct SampleToRecord {
+ base::TimeDelta primary_metric_duration;
+ Vector<base::TimeDelta> sub_metrics_durations;
+ Vector<unsigned> sub_metric_percentages;
+ cc::ActiveFrameSequenceTrackers trackers;
+ };
+
+ void UpdateEventTimeAndUpdateSampleIfNeeded(
+ cc::ActiveFrameSequenceTrackers trackers);
+ void UpdateSample(cc::ActiveFrameSequenceTrackers trackers);
void ResetAllMetrics();
- unsigned SampleFramesToNextEvent();
+
+ // Reports the current sample to the UKM system. Called on the first main
+ // frame update after First Contentful Paint and at destruction. Also resets
+ // the frame count.
+ void ReportUpdateTimeEvent();
+
+ // Reports the Blink.PageLoad to the UKM system. Called on the first main
+ // frame after First Contentful Paint.
+ void ReportPreFCPEvent();
// Implements throttling of the ForcedStyleAndLayoutUMA metric.
void RecordForcedStyleLayoutUMA(base::TimeDelta& duration);
- // To test event sampling. This and all future intervals will be the given
- // frame count, until this is called again.
- void FramesToNextEventForTest(unsigned num_frames) {
- frames_to_next_event_for_test_ = num_frames;
- }
+ // To test event sampling. Controls whether we update the current sample
+ // on the next frame, or do not. Values persist until explicitly changed.
+ void ChooseNextFrameForTest();
+ void DoNotChooseNextFrameForTest();
- // Used to check that we only for the MainFrame of a document.
+ // Used to check that we record only for the MainFrame of a document.
bool AllMetricsAreZero();
// The caller is the owner of the |clock|. The |clock| must outlive the
@@ -310,32 +343,36 @@ class CORE_EXPORT LocalFrameUkmAggregator
Vector<AbsoluteMetricRecord> absolute_metric_records_;
Vector<MainFramePercentageRecord> main_frame_percentage_records_;
- // Sampling control. We use a Poisson process with an exponential decay
- // multiplier. The goal is to get many randomly distributed samples early
- // during page load and initial interaction, then samples at an exponentially
- // decreasing rate to effectively cap the number of samples. The particular
- // parameters chosen here give roughly 10-15 samples in the first 100 frames,
- // decaying to several hours between samples by the 40th sample. The
- // multiplier value should be tuned to achieve a total sample count that
- // avoids throttling by the UKM system.
- double sample_decay_rate_ = 3;
- double sample_rate_multiplier_ = 1;
- unsigned samples_so_far_ = 0;
- unsigned frames_to_next_event_ = 0;
+ // The current sample to report. When RecordEvent() is called we
+ // check for uniform_random[0,1) < 1 / n where n is the number of frames
+ // we have seen (including this one). If true, we replace the sample with
+ // the current frame data. The result is a uniformly randomly chosen frame
+ // in the period between the frame counter being reset and the recording
+ // to the UKM system of the current sample.
+ // This process is designed to get maximum utility while only sending 2
+ // events per page load, which in turn maximizes client counts.
+ SampleToRecord current_sample_;
+ unsigned frames_since_last_report_ = 0;
// Control for the ForcedStyleAndUpdate UMA metric sampling
unsigned mean_calls_between_forced_style_layout_uma_ = 100;
unsigned calls_to_next_forced_style_layout_uma_ = 0;
- // Test data, used for SampleFramesToNextEvent if present
- unsigned frames_to_next_event_for_test_ = 0;
-
// Set by BeginMainFrame() and cleared in RecordMEndOfFrameMetrics.
// Main frame metrics are only recorded if this is true.
bool in_main_frame_update_ = false;
- // Record whether or not it is before the First Contentful Paint.
- bool is_before_fcp_ = true;
+ // A bitfield maintaining state for first contentful paint.
+ enum FCPState { kBeforeFCPSignal, kThisFrameReachedFCP, kHavePassedFCP };
+ FCPState fcp_state_ = kBeforeFCPSignal;
+
+ // A bitfield used to control updating the sample for tests.
+ enum SampleControlForTest {
+ kNoPreference,
+ kMustChooseNextFrame,
+ kMustNotChooseNextFrame
+ };
+ SampleControlForTest next_frame_sample_control_for_test_ = kNoPreference;
DISALLOW_COPY_AND_ASSIGN(LocalFrameUkmAggregator);
};
diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc b/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc
index 461e22d6e4d..dbf505058c8 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc
@@ -49,14 +49,9 @@ class LocalFrameUkmAggregatorTest : public testing::Test {
"Percentage";
}
- void FramesToNextEventForTest(unsigned delta) {
- aggregator().FramesToNextEventForTest(delta);
- }
-
- unsigned FramesToNextEvent() { return aggregator().frames_to_next_event_; }
- unsigned SamplesSoFar() { return aggregator().samples_so_far_; }
- unsigned SampleFramesToNextEvent() {
- return aggregator().SampleFramesToNextEvent();
+ void ChooseNextFrameForTest() { aggregator().ChooseNextFrameForTest(); }
+ void DoNotChooseNextFrameForTest() {
+ aggregator().DoNotChooseNextFrameForTest();
}
base::TimeTicks Now() { return test_task_runner_->NowTicks(); }
@@ -64,38 +59,42 @@ class LocalFrameUkmAggregatorTest : public testing::Test {
protected:
scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner_;
- void VerifyUpdateEntries(unsigned expected_num_entries,
- unsigned expected_primary_metric,
- unsigned expected_sub_metric,
- unsigned expected_percentage,
- bool expected_before_fcp) {
+ void VerifyUpdateEntry(unsigned index,
+ unsigned expected_primary_metric,
+ unsigned expected_sub_metric,
+ unsigned expected_percentage,
+ unsigned expected_reasons,
+ bool expected_before_fcp) {
auto entries = recorder().GetEntriesByName("Blink.UpdateTime");
- EXPECT_EQ(entries.size(), expected_num_entries);
-
- for (auto* entry : entries) {
- EXPECT_TRUE(
- ukm::TestUkmRecorder::EntryHasMetric(entry, GetPrimaryMetricName()));
- const int64_t* primary_metric_value =
- ukm::TestUkmRecorder::GetEntryMetric(entry, GetPrimaryMetricName());
- EXPECT_NEAR(*primary_metric_value / 1e3, expected_primary_metric, 0.001);
- for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) {
- EXPECT_TRUE(
- ukm::TestUkmRecorder::EntryHasMetric(entry, GetMetricName(i)));
- const int64_t* metric_value =
- ukm::TestUkmRecorder::GetEntryMetric(entry, GetMetricName(i));
- EXPECT_NEAR(*metric_value / 1e3, expected_sub_metric, 0.001);
-
- EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(
- entry, GetPercentageMetricName(i)));
- const int64_t* metric_percentage = ukm::TestUkmRecorder::GetEntryMetric(
- entry, GetPercentageMetricName(i));
- EXPECT_NEAR(*metric_percentage, expected_percentage, 0.001);
- }
+ EXPECT_GT(entries.size(), index);
+
+ auto* entry = entries[index];
+ EXPECT_TRUE(
+ ukm::TestUkmRecorder::EntryHasMetric(entry, GetPrimaryMetricName()));
+ const int64_t* primary_metric_value =
+ ukm::TestUkmRecorder::GetEntryMetric(entry, GetPrimaryMetricName());
+ EXPECT_NEAR(*primary_metric_value / 1e3, expected_primary_metric, 0.001);
+ for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) {
EXPECT_TRUE(
- ukm::TestUkmRecorder::EntryHasMetric(entry, "MainFrameIsBeforeFCP"));
- EXPECT_EQ(expected_before_fcp, *ukm::TestUkmRecorder::GetEntryMetric(
- entry, "MainFrameIsBeforeFCP"));
+ ukm::TestUkmRecorder::EntryHasMetric(entry, GetMetricName(i)));
+ const int64_t* metric_value =
+ ukm::TestUkmRecorder::GetEntryMetric(entry, GetMetricName(i));
+ EXPECT_NEAR(*metric_value / 1e3, expected_sub_metric, 0.001);
+
+ EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(
+ entry, GetPercentageMetricName(i)));
+ const int64_t* metric_percentage = ukm::TestUkmRecorder::GetEntryMetric(
+ entry, GetPercentageMetricName(i));
+ EXPECT_NEAR(*metric_percentage, expected_percentage, 0.001);
}
+ EXPECT_TRUE(
+ ukm::TestUkmRecorder::EntryHasMetric(entry, "MainFrameIsBeforeFCP"));
+ EXPECT_EQ(expected_before_fcp, *ukm::TestUkmRecorder::GetEntryMetric(
+ entry, "MainFrameIsBeforeFCP"));
+ EXPECT_TRUE(
+ ukm::TestUkmRecorder::EntryHasMetric(entry, "MainFrameReasons"));
+ EXPECT_EQ(expected_reasons,
+ *ukm::TestUkmRecorder::GetEntryMetric(entry, "MainFrameReasons"));
}
void VerifyAggregatedEntries(unsigned expected_num_entries,
@@ -120,6 +119,27 @@ class LocalFrameUkmAggregatorTest : public testing::Test {
}
}
+ void SimulateFrame(base::TimeTicks start_time,
+ unsigned millisecond_per_step,
+ cc::ActiveFrameSequenceTrackers trackers,
+ bool mark_fcp = false) {
+ aggregator().BeginMainFrame();
+ for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) {
+ auto timer = aggregator().GetScopedTimer(i);
+ if (mark_fcp && i == static_cast<int>(LocalFrameUkmAggregator::kPaint))
+ aggregator().DidReachFirstContentfulPaint(true);
+ test_task_runner_->FastForwardBy(
+ base::TimeDelta::FromMilliseconds(millisecond_per_step));
+ }
+ aggregator().RecordEndOfFrameMetrics(start_time, Now(), trackers);
+ }
+
+ bool SampleMatchesIteration(int64_t iteration_count) {
+ return aggregator()
+ .current_sample_.sub_metrics_durations[0]
+ .InMilliseconds() == iteration_count;
+ }
+
private:
scoped_refptr<LocalFrameUkmAggregator> aggregator_;
ukm::TestUkmRecorder recorder_;
@@ -141,6 +161,8 @@ TEST_F(LocalFrameUkmAggregatorTest, EmptyEventsNotRecorded) {
}
TEST_F(LocalFrameUkmAggregatorTest, FirstFrameIsRecorded) {
+ // Verifies that we always get a sample when we report at least one frame.
+
// Although the tests use a mock clock, the UKM aggregator checks if the
// system has a high resolution clock before recording results. As a result,
// the tests will fail if the system does not have a high resolution clock.
@@ -150,138 +172,76 @@ TEST_F(LocalFrameUkmAggregatorTest, FirstFrameIsRecorded) {
// The initial interval is always zero, so we should see one set of metrics
// for the initial frame, regardless of the initial interval.
base::TimeTicks start_time = Now();
- FramesToNextEventForTest(1);
unsigned millisecond_for_step = 1;
- aggregator().BeginMainFrame();
- for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) {
- auto timer =
- aggregator().GetScopedTimer(i % LocalFrameUkmAggregator::kCount);
- test_task_runner_->FastForwardBy(
- base::TimeDelta::FromMilliseconds(millisecond_for_step));
- }
- aggregator().RecordEndOfFrameMetrics(start_time, Now());
+ SimulateFrame(start_time, millisecond_for_step, 12);
+
+ // Metrics are not reported until destruction.
+ EXPECT_EQ(recorder().entries_count(), 0u);
+ // Reset the aggregator. Should record one pre-FCP metric.
+ ResetAggregator();
EXPECT_EQ(recorder().entries_count(), 1u);
float expected_primary_metric =
millisecond_for_step * LocalFrameUkmAggregator::kCount;
float expected_sub_metric = millisecond_for_step;
float expected_percentage =
- floor(100.0 / (float)LocalFrameUkmAggregator::kCount);
-
- VerifyUpdateEntries(1u, expected_primary_metric, expected_sub_metric,
- expected_percentage, true);
-
- // Reset the aggregator. Should not record any more.
- ResetAggregator();
+ floor(100.0 / static_cast<float>(LocalFrameUkmAggregator::kCount));
- VerifyUpdateEntries(1u, expected_primary_metric, expected_sub_metric,
- expected_percentage, true);
+ VerifyUpdateEntry(0u, expected_primary_metric, expected_sub_metric,
+ expected_percentage, 12, true);
}
-TEST_F(LocalFrameUkmAggregatorTest, EventsRecordedAtIntervals) {
+TEST_F(LocalFrameUkmAggregatorTest, PreAndPostFCPAreRecorded) {
+ // Confirm that we get at least one frame pre-FCP and one post-FCP.
+
// Although the tests use a mock clock, the UKM aggregator checks if the
// system has a high resolution clock before recording results. As a result,
// the tests will fail if the system does not have a high resolution clock.
if (!base::TimeTicks::IsHighResolution())
return;
- // The records should be recorded in the first frame after every interval,
- // and no sooner.
-
- // If we claim we are past FCP, the event should indicate that.
- aggregator().DidReachFirstContentfulPaint(true);
-
- // Set the first sample interval to 2.
- FramesToNextEventForTest(2);
+ // The initial interval is always zero, so we should see one set of metrics
+ // for the initial frame, regardless of the initial interval.
+ base::TimeTicks start_time = Now();
unsigned millisecond_per_step = 50 / (LocalFrameUkmAggregator::kCount + 1);
- unsigned millisecond_per_frame =
- millisecond_per_step * (LocalFrameUkmAggregator::kCount + 1);
+ SimulateFrame(start_time, millisecond_per_step, 4, true);
- base::TimeTicks start_time = Now();
- aggregator().BeginMainFrame();
- for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) {
- auto timer = aggregator().GetScopedTimer(i);
- test_task_runner_->FastForwardBy(
- base::TimeDelta::FromMilliseconds(millisecond_per_step));
- }
- test_task_runner_->FastForwardBy(
- base::TimeDelta::FromMilliseconds(millisecond_per_step));
- aggregator().RecordEndOfFrameMetrics(start_time, Now());
+ // We marked FCP when we simulated, so we should report something. There
+ // should be 2 entries because the aggregated pre-FCP metric also reported.
+ EXPECT_EQ(recorder().entries_count(), 2u);
- // We should have a sample after the very first step, regardless of the
- // interval. The FirstFrameIsRecorded test above also tests this. There
- // should be 2 entries because the aggregated pre-fcp event has also
- // been recorded.
+ float expected_primary_metric =
+ millisecond_per_step * LocalFrameUkmAggregator::kCount;
+ float expected_sub_metric = millisecond_per_step;
float expected_percentage =
- floor(millisecond_per_step * 100.0 / (float)millisecond_per_frame);
- VerifyUpdateEntries(1u, millisecond_per_frame, millisecond_per_step,
- expected_percentage, false);
+ floor(100.0 / static_cast<float>(LocalFrameUkmAggregator::kCount));
- // Another step does not get us past the sample interval.
- start_time = Now();
- aggregator().BeginMainFrame();
- for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) {
- auto timer = aggregator().GetScopedTimer(i);
- test_task_runner_->FastForwardBy(
- base::TimeDelta::FromMilliseconds(millisecond_per_step));
- }
- test_task_runner_->FastForwardBy(
- base::TimeDelta::FromMilliseconds(millisecond_per_step));
- aggregator().RecordEndOfFrameMetrics(start_time, Now());
+ VerifyUpdateEntry(0u, expected_primary_metric, expected_sub_metric,
+ expected_percentage, 4, true);
- VerifyUpdateEntries(1u, millisecond_per_frame, millisecond_per_step,
- expected_percentage, false);
+ // Take another step. Should reset the frame count and report the first post-
+ // fcp frame. A failure here iundicates that we did not reset the frame,
+ // or that we are incorrectly tracking pre/post fcp.
+ unsigned millisecond_per_frame =
+ millisecond_per_step * LocalFrameUkmAggregator::kCount;
- // Another step should tick us past the sample interval.
- // Note that the sample is a single frame, so even if we've taken
- // multiple steps we should see just one frame's time.
start_time = Now();
- aggregator().BeginMainFrame();
- for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) {
- auto timer = aggregator().GetScopedTimer(i);
- test_task_runner_->FastForwardBy(
- base::TimeDelta::FromMilliseconds(millisecond_per_step));
- }
- test_task_runner_->FastForwardBy(
- base::TimeDelta::FromMilliseconds(millisecond_per_step));
- aggregator().RecordEndOfFrameMetrics(start_time, Now());
+ SimulateFrame(start_time, millisecond_per_step, 4);
- VerifyUpdateEntries(2u, millisecond_per_frame, millisecond_per_step,
- expected_percentage, false);
-
- // Step one more frame so we don't sample again.
- start_time = Now();
- aggregator().BeginMainFrame();
- for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) {
- auto timer = aggregator().GetScopedTimer(i);
- test_task_runner_->FastForwardBy(
- base::TimeDelta::FromMilliseconds(millisecond_per_step));
- }
- test_task_runner_->FastForwardBy(
- base::TimeDelta::FromMilliseconds(millisecond_per_step));
- aggregator().RecordEndOfFrameMetrics(start_time, Now());
+ // Need to destruct to report
+ ResetAggregator();
- // Should be no more samples.
- VerifyUpdateEntries(2u, millisecond_per_frame, millisecond_per_step,
- expected_percentage, false);
+ // We should have a sample after the very first step, regardless of the
+ // interval. The FirstFrameIsRecorded test above also tests this. There
+ // should be 3 entries because the aggregated pre-fcp event has also
+ // been recorded.
+ EXPECT_EQ(recorder().entries_count(), 3u);
- // And one more step to generate one more sample
- start_time = Now();
- aggregator().BeginMainFrame();
- for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) {
- auto timer = aggregator().GetScopedTimer(i);
- test_task_runner_->FastForwardBy(
- base::TimeDelta::FromMilliseconds(millisecond_per_step));
- }
- test_task_runner_->FastForwardBy(
- base::TimeDelta::FromMilliseconds(millisecond_per_step));
- aggregator().RecordEndOfFrameMetrics(start_time, Now());
-
- // We should have 3 more events, once for the prior interval and 2 for the
- // new interval.
- VerifyUpdateEntries(3u, millisecond_per_frame, millisecond_per_step,
- expected_percentage, false);
+ expected_percentage = floor(millisecond_per_step * 100.0 /
+ static_cast<float>(millisecond_per_frame));
+ VerifyUpdateEntry(1u, millisecond_per_frame, millisecond_per_step,
+ expected_percentage, 4, false);
}
TEST_F(LocalFrameUkmAggregatorTest, AggregatedPreFCPEventRecorded) {
@@ -291,49 +251,30 @@ TEST_F(LocalFrameUkmAggregatorTest, AggregatedPreFCPEventRecorded) {
if (!base::TimeTicks::IsHighResolution())
return;
- // Set the first sample interval to 5. We shouldn't need to record an
+ // Be sure to not choose the next frame. We shouldn't need to record an
// UpdateTime metric in order to record an aggregated metric.
- FramesToNextEventForTest(5);
+ DoNotChooseNextFrameForTest();
unsigned millisecond_per_step = 50 / (LocalFrameUkmAggregator::kCount + 1);
unsigned millisecond_per_frame =
- millisecond_per_step * (LocalFrameUkmAggregator::kCount + 1);
+ millisecond_per_step * (LocalFrameUkmAggregator::kCount);
base::TimeTicks start_time = Now();
- aggregator().BeginMainFrame();
- for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) {
- auto timer = aggregator().GetScopedTimer(i);
- test_task_runner_->FastForwardBy(
- base::TimeDelta::FromMilliseconds(millisecond_per_step));
- }
- test_task_runner_->FastForwardBy(
- base::TimeDelta::FromMilliseconds(millisecond_per_step));
- aggregator().RecordEndOfFrameMetrics(start_time, Now());
+ SimulateFrame(start_time, millisecond_per_step, 3);
// We should not have an aggregated metric yet because we have not reached
- // FCP.
- VerifyAggregatedEntries(0u, millisecond_per_frame, millisecond_per_step);
+ // FCP. We shouldn't have any other kind of metric either.
+ EXPECT_EQ(recorder().entries_count(), 0u);
- // Another step does not get us past the sample interval.
+ // Another step marking FCP this time.
+ ChooseNextFrameForTest();
start_time = Now();
- aggregator().BeginMainFrame();
- for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) {
- auto timer = aggregator().GetScopedTimer(i);
- test_task_runner_->FastForwardBy(
- base::TimeDelta::FromMilliseconds(millisecond_per_step));
- }
- test_task_runner_->FastForwardBy(
- base::TimeDelta::FromMilliseconds(millisecond_per_step));
- aggregator().RecordEndOfFrameMetrics(start_time, Now());
+ SimulateFrame(start_time, millisecond_per_step, 3, true);
- // Still no aggregated record because we have not reached FCP.
- VerifyAggregatedEntries(0u, millisecond_per_frame, millisecond_per_step);
-
- // If we claim we are past FCP, the event should indicate that.
- aggregator().DidReachFirstContentfulPaint(true);
-
- // Now we should have an aggregated metric.
+ // Now we should have an aggregated metric, plus the pre-FCP update metric
+ EXPECT_EQ(recorder().entries_count(), 2u);
VerifyAggregatedEntries(1u, 2 * millisecond_per_frame,
2 * millisecond_per_step);
+ ResetAggregator();
}
TEST_F(LocalFrameUkmAggregatorTest, LatencyDataIsPopulated) {
@@ -343,9 +284,8 @@ TEST_F(LocalFrameUkmAggregatorTest, LatencyDataIsPopulated) {
if (!base::TimeTicks::IsHighResolution())
return;
- // The initial interval is always zero, so we should see one set of metrics
- // for the initial frame, regardless of the initial interval.
- FramesToNextEventForTest(1);
+ // We always record the first frame. Din't use the SimulateFrame method
+ // because we need to populate before the end of the frame.
unsigned millisecond_for_step = 1;
aggregator().BeginMainFrame();
for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) {
@@ -355,7 +295,6 @@ TEST_F(LocalFrameUkmAggregatorTest, LatencyDataIsPopulated) {
base::TimeDelta::FromMilliseconds(millisecond_for_step));
}
- // Need to populate before the end of the frame.
std::unique_ptr<cc::BeginMainFrameMetrics> metrics_data =
aggregator().GetBeginMainFrameMetrics();
EXPECT_EQ(metrics_data->handle_input_events.InMillisecondsF(),
@@ -373,22 +312,28 @@ TEST_F(LocalFrameUkmAggregatorTest, LatencyDataIsPopulated) {
millisecond_for_step);
// Do not check the value in metrics_data.update_layers because it
// is not set by the aggregator.
+ ResetAggregator();
}
-TEST_F(LocalFrameUkmAggregatorTest, SampleFramesGoesToMaxUnsigned) {
- // This will time out if the exponential decay in sample rate does not
- // happen. It should not take too many iterations to reach maximum time
- // between samples.
- unsigned initial_sample_count = SamplesSoFar();
- unsigned last_sample_count = initial_sample_count;
- unsigned frames_to_next_event = FramesToNextEvent();
- while (frames_to_next_event < UINT_MAX) {
- frames_to_next_event = SampleFramesToNextEvent();
- EXPECT_GT(frames_to_next_event, 0u);
- EXPECT_EQ(last_sample_count + 1, SamplesSoFar());
- last_sample_count++;
+TEST_F(LocalFrameUkmAggregatorTest, SampleDoesChange) {
+ // To write a test that the sample eventually changes we need to let it very
+ // occasionally time out or fail. We'll go up to 100,000 tries for an update,
+ // so this should not hit on average once every 100,000 test runs. One flake
+ // in 100,000 seems acceptable.
+
+ // Generate the first frame. We will look for a change from this frame.
+ unsigned millisecond_for_step = 1;
+ SimulateFrame(base::TimeTicks(), millisecond_for_step, 0);
+
+ unsigned iteration_count = 2;
+ bool new_sample = false;
+ while (iteration_count < 100000u && !new_sample) {
+ millisecond_for_step = iteration_count;
+ SimulateFrame(base::TimeTicks(), millisecond_for_step, 0);
+ new_sample = SampleMatchesIteration(static_cast<int64_t>(iteration_count));
+ ++iteration_count;
}
- EXPECT_NE(initial_sample_count, last_sample_count);
+ EXPECT_LT(iteration_count, 100000u);
}
} // namespace blink
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 889b5da440b..afab16121f7 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
@@ -37,10 +37,13 @@
#include "cc/input/main_thread_scrolling_reason.h"
#include "cc/layers/picture_layer.h"
#include "cc/tiles/frame_viewer_instrumentation.h"
+#include "cc/trees/layer_tree_host.h"
#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink.h"
+#include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_rect.h"
-#include "third_party/blink/public/platform/web_scroll_into_view_params.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_scroll_into_view_options.h"
#include "third_party/blink/renderer/core/accessibility/apply_dark_mode.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
#include "third_party/blink/renderer/core/animation/document_animations.h"
@@ -65,7 +68,6 @@
#include "third_party/blink/renderer/core/frame/remote_frame.h"
#include "third_party/blink/renderer/core/frame/remote_frame_view.h"
#include "third_party/blink/renderer/core/frame/root_frame_viewport.h"
-#include "third_party/blink/renderer/core/frame/scroll_into_view_options.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/frame/web_local_frame_impl.h"
@@ -104,7 +106,6 @@
#include "third_party/blink/renderer/core/page/frame_tree.h"
#include "third_party/blink/renderer/core/page/link_highlight.h"
#include "third_party/blink/renderer/core/page/page.h"
-#include "third_party/blink/renderer/core/page/print_context.h"
#include "third_party/blink/renderer/core/page/scrolling/fragment_anchor.h"
#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h"
#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_context.h"
@@ -141,6 +142,7 @@
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h"
#include "third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h"
+#include "third_party/blink/renderer/platform/graphics/paint/graphics_layer_display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
@@ -151,6 +153,9 @@
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
#include "third_party/blink/renderer/platform/web_test_support.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/cursor/cursor.h"
+#include "ui/base/mojom/cursor_type.mojom-blink.h"
// Used to check for dirty layouts violating document lifecycle rules.
// If arg evaluates to true, the program will continue. If arg evaluates to
@@ -167,24 +172,18 @@
namespace blink {
namespace {
-// Page dimensions in pixels at 72 DPI.
-constexpr int kA4PortraitPageWidth = 595;
-constexpr int kA4PortraitPageHeight = 842;
-constexpr int kLetterPortraitPageWidth = 612;
-constexpr int kLetterPortraitPageHeight = 792;
-
// Logs a UseCounter for the size of the cursor that will be set. This will be
// used for compatibility analysis to determine whether the maximum size can be
// reduced.
-void LogCursorSizeCounter(LocalFrame* frame, const Cursor& cursor) {
+void LogCursorSizeCounter(LocalFrame* frame, const ui::Cursor& cursor) {
DCHECK(frame);
- Image* image = cursor.GetImage();
- if (!image)
+ SkBitmap bitmap = cursor.custom_bitmap();
+ if (cursor.type() != ui::mojom::blink::CursorType::kCustom || bitmap.isNull())
return;
// Should not overflow, this calculation is done elsewhere when determining
// whether the cursor exceeds its maximum size (see event_handler.cc).
- IntSize scaled_size = image->Size();
- scaled_size.Scale(1 / cursor.ImageScaleFactor());
+ auto scaled_size = IntSize(bitmap.width(), bitmap.height());
+ scaled_size.Scale(1 / cursor.image_scale_factor());
if (scaled_size.Width() > 64 || scaled_size.Height() > 64) {
UseCounter::Count(frame->GetDocument(), WebFeature::kCursorImageGT64x64);
} else if (scaled_size.Width() > 32 || scaled_size.Height() > 32) {
@@ -255,9 +254,9 @@ LocalFrameView::LocalFrameView(LocalFrame& frame, IntRect frame_rect)
needs_update_geometries_(false),
root_layer_did_scroll_(false),
frame_timing_requests_dirty_(true),
- // The compositor throttles the main frame using deferred commits, we
- // can't throttle it here or it seems the root compositor doesn't get
- // setup properly.
+ // The compositor throttles the main frame using deferred begin main frame
+ // updates. We can't throttle it here or it seems the root compositor
+ // doesn't get setup properly.
lifecycle_updates_throttled_(!GetFrame().IsMainFrame()),
current_update_lifecycle_phases_target_state_(
DocumentLifecycle::kUninitialized),
@@ -280,8 +279,8 @@ LocalFrameView::LocalFrameView(LocalFrame& frame, IntRect frame_rect)
#endif
{
// Propagate the marginwidth/height and scrolling modes to the view.
- if (frame_->Owner() &&
- frame_->Owner()->ScrollingMode() == ScrollbarMode::kAlwaysOff)
+ if (frame_->Owner() && frame_->Owner()->ScrollbarMode() ==
+ mojom::blink::ScrollbarMode::kAlwaysOff)
SetCanHaveScrollbars(false);
}
@@ -291,7 +290,7 @@ LocalFrameView::~LocalFrameView() {
#endif
}
-void LocalFrameView::Trace(blink::Visitor* visitor) {
+void LocalFrameView::Trace(Visitor* visitor) {
visitor->Trace(frame_);
visitor->Trace(fragment_anchor_);
visitor->Trace(scrollable_areas_);
@@ -302,7 +301,6 @@ void LocalFrameView::Trace(blink::Visitor* visitor) {
visitor->Trace(viewport_scrollable_area_);
visitor->Trace(anchoring_adjustment_queue_);
visitor->Trace(scroll_event_queue_);
- visitor->Trace(print_context_);
visitor->Trace(paint_timing_detector_);
visitor->Trace(lifecycle_observers_);
}
@@ -340,7 +338,8 @@ void LocalFrameView::ForAllChildLocalFrameViews(const Function& function) {
}
}
-// Call function for each non-throttled frame view in pre tree order.
+// Call function for each non-throttled frame view in pre-order. If this logic
+// is updated, consider updating |ForAllThrottledLocalFrameViews| too.
template <typename Function>
void LocalFrameView::ForAllNonThrottledLocalFrameViews(
const Function& function) {
@@ -359,6 +358,48 @@ void LocalFrameView::ForAllNonThrottledLocalFrameViews(
}
}
+// Call function for each throttled frame view in pre-order. If this logic is
+// updated, consider updating |ForAllNonThrottledLocalFrameViews| too.
+template <typename Function>
+void LocalFrameView::ForAllThrottledLocalFrameViews(const Function& function) {
+ if (!ShouldThrottleRendering())
+ return;
+
+ function(*this);
+
+ for (Frame* child = frame_->Tree().FirstChild(); child;
+ child = child->Tree().NextSibling()) {
+ auto* child_local_frame = DynamicTo<LocalFrame>(child);
+ if (!child_local_frame)
+ continue;
+ if (LocalFrameView* child_view = child_local_frame->View())
+ child_view->ForAllNonThrottledLocalFrameViews(function);
+ }
+}
+
+template <typename Function>
+void LocalFrameView::ForAllRemoteFrameViews(const Function& function) {
+ for (Frame* child = frame_->Tree().FirstChild(); child;
+ child = child->Tree().NextSibling()) {
+ if (child->IsLocalFrame()) {
+ To<LocalFrame>(child)->View()->ForAllRemoteFrameViews(function);
+ } else {
+ DCHECK(child->IsRemoteFrame());
+ if (RemoteFrameView* view = To<RemoteFrame>(child)->View())
+ function(*view);
+ }
+ }
+ if (Document* document = frame_->GetDocument()) {
+ for (PortalContents* portal :
+ DocumentPortals::From(*document).GetPortals()) {
+ if (RemoteFrame* frame = portal->GetFrame()) {
+ if (RemoteFrameView* view = frame->View())
+ function(*view);
+ }
+ }
+ }
+}
+
void LocalFrameView::Dispose() {
CHECK(!IsInPerformLayout());
@@ -387,8 +428,6 @@ void LocalFrameView::Dispose() {
if (owner_element && owner_element->OwnedEmbeddedContentView() == this)
owner_element->SetEmbeddedContentView(nullptr);
- ClearPrintContext();
-
ukm_aggregator_.reset();
layout_shift_tracker_->Dispose();
@@ -582,7 +621,7 @@ void LocalFrameView::PerformPreLayoutTasks() {
document->GetStyleEngine().MediaQueryAffectedByViewportChange()) ||
(was_resized && main_frame_rotation &&
document->GetStyleEngine().MediaQueryAffectedByDeviceChange())) {
- document->MediaQueryAffectingValueChanged();
+ document->MediaQueryAffectingValueChanged(MediaValueChange::kSize);
} else if (was_resized) {
document->EvaluateMediaQueryList();
}
@@ -810,10 +849,10 @@ void LocalFrameView::UpdateLayout() {
last_viewport_size_ = GetLayoutSize();
last_zoom_factor_ = GetLayoutView()->StyleRef().Zoom();
- ScrollbarMode h_mode;
- ScrollbarMode v_mode;
+ mojom::blink::ScrollbarMode h_mode;
+ mojom::blink::ScrollbarMode v_mode;
GetLayoutView()->CalculateScrollbarModes(h_mode, v_mode);
- if (v_mode == ScrollbarMode::kAuto) {
+ if (v_mode == mojom::blink::ScrollbarMode::kAuto) {
GetLayoutView()
->GetScrollableArea()
->ForceVerticalScrollbarForFirstLayout();
@@ -883,16 +922,19 @@ void LocalFrameView::UpdateLayout() {
TRACE_DISABLED_BY_DEFAULT("blink.debug.layout.trees"), "LayoutTree", this,
TracedLayoutObject::Create(*GetLayoutView(), true));
- GetLayoutView()->Compositor()->DidLayout();
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ GetLayoutView()->Compositor()->DidLayout();
layout_count_for_testing_++;
if (AXObjectCache* cache = document->ExistingAXObjectCache()) {
const KURL& url = document->Url();
if (url.IsValid() && !url.IsAboutBlankURL()) {
+ // TODO(kschmi) move HandleLayoutComplete to the accessibility lifecycle
+ // stage. crbug.com/1062122
cache->HandleLayoutComplete(document);
- cache->ProcessUpdatesAfterLayout(*document);
}
}
+
UpdateDocumentAnnotatedRegions();
CheckDoesNotNeedLayout();
@@ -930,22 +972,27 @@ void LocalFrameView::UpdateLayout() {
}
void LocalFrameView::WillStartForcedLayout() {
- // UpdateLayoutIgnoringPendingStyleSheets is re-entrant for auto-sizing
- // and plugins. So keep track of stack depth.
+ // UpdateLayout is re-entrant for auto-sizing and plugins. So keep
+ // track of stack depth to include all the time in the top-level call.
forced_layout_stack_depth_++;
if (forced_layout_stack_depth_ > 1)
return;
forced_layout_start_time_ = base::TimeTicks::Now();
}
-void LocalFrameView::DidFinishForcedLayout() {
+void LocalFrameView::DidFinishForcedLayout(DocumentUpdateReason reason) {
CHECK_GT(forced_layout_stack_depth_, (unsigned)0);
forced_layout_stack_depth_--;
if (!forced_layout_stack_depth_ && base::TimeTicks::IsHighResolution()) {
LocalFrameUkmAggregator& aggregator = EnsureUkmAggregator();
aggregator.RecordSample(
- (size_t)LocalFrameUkmAggregator::kForcedStyleAndLayout,
+ static_cast<size_t>(LocalFrameUkmAggregator::kForcedStyleAndLayout),
forced_layout_start_time_, base::TimeTicks::Now());
+ if (reason == DocumentUpdateReason::kHitTest) {
+ aggregator.RecordSample(
+ static_cast<size_t>(LocalFrameUkmAggregator::kHitTestDocumentUpdate),
+ forced_layout_start_time_, base::TimeTicks::Now());
+ }
}
}
@@ -982,8 +1029,9 @@ FloatSize LocalFrameView::ViewportSizeForViewportUnits() const {
// zoom factor when use-zoom-for-dsf is enabled on Android. Confirm this
// works correctly when that's turned on. https://crbug.com/737777.
float page_scale_at_layout_width = viewport_width / layout_size.Width();
- layout_size.Expand(
- 0, browser_controls.TotalHeight() / page_scale_at_layout_width);
+ layout_size.Expand(0, (browser_controls.TotalHeight() -
+ browser_controls.TotalMinHeight()) /
+ page_scale_at_layout_width);
}
}
@@ -1020,11 +1068,28 @@ void LocalFrameView::RunIntersectionObserverSteps() {
!frame_->GetDocument()->IsActive()) {
return;
}
+
+ if (frame_->IsMainFrame()) {
+ EnsureOverlayInterstitialAdDetector().MaybeFireDetection(frame_.Get());
+
+ // Report the main frame's document intersection with itself.
+ LayoutObject* layout_object = GetLayoutView();
+ IntRect main_frame_dimensions =
+ ToLayoutBox(layout_object)->PixelSnappedLayoutOverflowRect();
+ GetFrame().Client()->OnMainFrameDocumentIntersectionChanged(WebRect(
+ 0, 0, main_frame_dimensions.Width(), main_frame_dimensions.Height()));
+ }
+
TRACE_EVENT0("blink,benchmark",
"LocalFrameView::UpdateViewportIntersectionsForSubtree");
SCOPED_UMA_AND_UKM_TIMER(EnsureUkmAggregator(),
LocalFrameUkmAggregator::kIntersectionObservation);
- bool needs_occlusion_tracking = UpdateViewportIntersectionsForSubtree(0);
+
+ unsigned flags = 0;
+ if (frame_->CanSkipStickyFrameTracking())
+ flags |= IntersectionObservation::kCanSkipStickyFrameTracking;
+
+ bool needs_occlusion_tracking = UpdateViewportIntersectionsForSubtree(flags);
if (FrameOwner* owner = frame_->Owner())
owner->SetNeedsOcclusionTracking(needs_occlusion_tracking);
#if DCHECK_IS_ON()
@@ -1038,7 +1103,8 @@ void LocalFrameView::ForceUpdateViewportIntersections() {
// update; but we can't wait for a lifecycle update to run them, because a
// hidden frame won't run lifecycle updates. Force layout and run them now.
DocumentLifecycle::DisallowThrottlingScope disallow_throttling(Lifecycle());
- UpdateLifecycleToCompositingCleanPlusScrolling();
+ UpdateLifecycleToCompositingCleanPlusScrolling(
+ DocumentUpdateReason::kIntersectionObservation);
UpdateViewportIntersectionsForSubtree(
IntersectionObservation::kImplicitRootObserversNeedUpdate |
IntersectionObservation::kIgnoreDelay);
@@ -1110,7 +1176,7 @@ void LocalFrameView::AddPartToUpdate(LayoutEmbeddedObject& object) {
Node* node = object.GetNode();
DCHECK(node);
if (IsA<HTMLObjectElement>(*node) || IsA<HTMLEmbedElement>(*node))
- ToHTMLPlugInElement(node)->SetNeedsPluginUpdate(true);
+ To<HTMLPlugInElement>(node)->SetNeedsPluginUpdate(true);
part_update_set_.insert(&object);
}
@@ -1121,8 +1187,10 @@ void LocalFrameView::SetDisplayMode(blink::mojom::DisplayMode mode) {
display_mode_ = mode;
- if (frame_->GetDocument())
- frame_->GetDocument()->MediaQueryAffectingValueChanged();
+ if (frame_->GetDocument()) {
+ frame_->GetDocument()->MediaQueryAffectingValueChanged(
+ MediaValueChange::kOther);
+ }
}
void LocalFrameView::SetDisplayShape(DisplayShape display_shape) {
@@ -1131,14 +1199,17 @@ void LocalFrameView::SetDisplayShape(DisplayShape display_shape) {
display_shape_ = display_shape;
- if (frame_->GetDocument())
- frame_->GetDocument()->MediaQueryAffectingValueChanged();
+ if (frame_->GetDocument()) {
+ frame_->GetDocument()->MediaQueryAffectingValueChanged(
+ MediaValueChange::kOther);
+ }
}
void LocalFrameView::SetMediaType(const AtomicString& media_type) {
DCHECK(frame_->GetDocument());
media_type_ = media_type;
- frame_->GetDocument()->MediaQueryAffectingValueChanged();
+ frame_->GetDocument()->MediaQueryAffectingValueChanged(
+ MediaValueChange::kOther);
}
AtomicString LocalFrameView::MediaType() const {
@@ -1160,6 +1231,7 @@ void LocalFrameView::AdjustMediaTypeForPrinting(bool printing) {
media_type_when_not_printing_ = g_null_atom;
}
+ frame_->GetDocument()->GetStyleEngine().MarkViewportStyleDirty();
frame_->GetDocument()->GetStyleEngine().MarkAllElementsForStyleRecalc(
StyleChangeReasonForTracing::Create(
style_change_reason::kStyleSheetChange));
@@ -1169,11 +1241,6 @@ void LocalFrameView::AddBackgroundAttachmentFixedObject(LayoutObject* object) {
DCHECK(!background_attachment_fixed_objects_.Contains(object));
background_attachment_fixed_objects_.insert(object);
- if (ScrollingCoordinator* scrolling_coordinator =
- this->GetScrollingCoordinator()) {
- scrolling_coordinator
- ->FrameViewHasBackgroundAttachmentFixedObjectsDidChange(this);
- }
// Ensure main thread scrolling reasons are recomputed.
SetNeedsPaintPropertyUpdate();
@@ -1186,11 +1253,6 @@ void LocalFrameView::RemoveBackgroundAttachmentFixedObject(
DCHECK(background_attachment_fixed_objects_.Contains(object));
background_attachment_fixed_objects_.erase(object);
- if (ScrollingCoordinator* scrolling_coordinator =
- this->GetScrollingCoordinator()) {
- scrolling_coordinator
- ->FrameViewHasBackgroundAttachmentFixedObjectsDidChange(this);
- }
// Ensure main thread scrolling reasons are recomputed.
SetNeedsPaintPropertyUpdate();
@@ -1211,7 +1273,7 @@ bool LocalFrameView::RequiresMainThreadScrollingForBackgroundAttachmentFixed()
DCHECK(!object->BackgroundTransfersToView());
// If the background is viewport background and it paints onto the main
// graphics layer only, then it doesn't need main thread scrolling.
- if (object->IsLayoutView() &&
+ if (IsA<LayoutView>(object) &&
object->GetBackgroundPaintLocation() == kBackgroundPaintInGraphicsLayer)
return false;
return true;
@@ -1221,24 +1283,12 @@ void LocalFrameView::AddViewportConstrainedObject(LayoutObject& object) {
if (!viewport_constrained_objects_)
viewport_constrained_objects_ = std::make_unique<ObjectSet>();
- if (!viewport_constrained_objects_->Contains(&object)) {
- viewport_constrained_objects_->insert(&object);
-
- if (ScrollingCoordinator* scrolling_coordinator =
- this->GetScrollingCoordinator())
- scrolling_coordinator->FrameViewFixedObjectsDidChange(this);
- }
+ viewport_constrained_objects_->insert(&object);
}
void LocalFrameView::RemoveViewportConstrainedObject(LayoutObject& object) {
- if (viewport_constrained_objects_ &&
- viewport_constrained_objects_->Contains(&object)) {
+ if (viewport_constrained_objects_)
viewport_constrained_objects_->erase(&object);
-
- if (ScrollingCoordinator* scrolling_coordinator =
- this->GetScrollingCoordinator())
- scrolling_coordinator->FrameViewFixedObjectsDidChange(this);
- }
}
void LocalFrameView::ViewportSizeChanged(bool width_changed,
@@ -1262,6 +1312,8 @@ void LocalFrameView::ViewportSizeChanged(bool width_changed,
layout_view->GetScrollableArea()->ClampScrollOffsetAfterOverflowChange();
}
+ // TODO(pdr): |UsesCompositing()| will be false with CompositeAfterPaint but
+ // do we need to do these updates?
if (layout_view->UsesCompositing()) {
layout_view->Layer()->SetNeedsCompositingInputsUpdate();
SetNeedsPaintPropertyUpdate();
@@ -1392,11 +1444,11 @@ void LocalFrameView::ProcessUrlFragment(const KURL& url,
if (anchor) {
fragment_anchor_ = anchor;
fragment_anchor_->Installed();
-
- // Layout needs to be clean for scrolling but if layout is needed, we'll
- // invoke after layout is completed so no need to do it here.
- if (!NeedsLayout())
- InvokeFragmentAnchor();
+ // Post-load, same-document navigations need to schedule a frame in which
+ // the fragment anchor will be invoked. It will be done after layout as
+ // part of the lifecycle.
+ if (same_document_navigation)
+ ScheduleAnimation();
}
}
@@ -1464,6 +1516,8 @@ void LocalFrameView::UpdateCompositedSelectionIfNeeded() {
void LocalFrameView::SetNeedsCompositingUpdate(
CompositingUpdateType update_type) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ return;
if (auto* layout_view = GetLayoutView()) {
if (frame_->GetDocument()->IsActive())
layout_view->Compositor()->SetNeedsCompositingUpdate(update_type);
@@ -1482,9 +1536,6 @@ void LocalFrameView::HandleLoadCompleted() {
// reduce the size of the frame.
if (auto_size_info_)
auto_size_info_->AutoSizeIfNeeded();
-
- if (fragment_anchor_)
- fragment_anchor_->DidCompleteLoad();
}
void LocalFrameView::ClearLayoutSubtreeRoot(const LayoutObject& root) {
@@ -1770,7 +1821,7 @@ bool LocalFrameView::UpdatePlugins() {
for (const auto& embedded_object : objects) {
LayoutEmbeddedObject& object = *embedded_object;
- HTMLPlugInElement* element = ToHTMLPlugInElement(object.GetNode());
+ auto* element = To<HTMLPlugInElement>(object.GetNode());
// The object may have already been destroyed (thus node cleared),
// but LocalFrameView holds a manual ref, so it won't have been deleted.
@@ -1837,12 +1888,7 @@ void LocalFrameView::PerformPostLayoutTasks() {
// send the right mouse out/over events.
// TODO(lanwei): we should check whether the mouse is inside the frame before
// dirtying the hover state.
- if (RuntimeEnabledFeatures::UpdateHoverAtBeginFrameEnabled()) {
- frame_->LocalFrameRoot().GetEventHandler().MarkHoverStateDirty();
- } else {
- frame_->GetEventHandler().MayUpdateHoverWhenContentUnderMouseChanged(
- MouseEventManager::UpdateHoverReason::kLayoutOrStyleChanged);
- }
+ frame_->LocalFrameRoot().GetEventHandler().MarkHoverStateDirty();
UpdateGeometriesIfNeeded();
@@ -1856,11 +1902,6 @@ void LocalFrameView::PerformPostLayoutTasks() {
this->GetScrollingCoordinator()) {
scrolling_coordinator->NotifyGeometryChanged(this);
}
- SnapCoordinator& snap_coordinator =
- frame_->GetDocument()->GetSnapCoordinator();
- snap_coordinator.UpdateAllSnapContainerData();
- if (RuntimeEnabledFeatures::ScrollSnapAfterLayoutEnabled())
- snap_coordinator.ReSnapAllContainers();
SendResizeEventIfNeeded();
}
@@ -1965,7 +2006,7 @@ Color LocalFrameView::DocumentBackgroundColor() const {
// backdrop.
if (Document* doc = frame_->GetDocument()) {
if (Element* element = Fullscreen::FullscreenElementFrom(*doc)) {
- if (doc->IsImmersiveArOverlay()) {
+ if (doc->IsXrOverlay()) {
// Use the fullscreened element's background directly. Don't bother
// blending with the backdrop since that's transparent.
if (LayoutObject* layout_object = element->GetLayoutObject()) {
@@ -2046,41 +2087,62 @@ void LocalFrameView::UpdateGeometriesIfNeeded() {
views.clear();
}
-void LocalFrameView::UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason reason) {
- GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhases(
+bool LocalFrameView::UpdateAllLifecyclePhases(DocumentUpdateReason reason) {
+ bool updated = GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhases(
DocumentLifecycle::kPaintClean, reason);
+
+#if DCHECK_IS_ON()
+ if (updated) {
+ // This function should return true iff all non-throttled frames are in the
+ // kPaintClean lifecycle state.
+ ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
+ DCHECK_EQ(frame_view.Lifecycle().GetState(),
+ DocumentLifecycle::kPaintClean);
+ });
+
+ // A required intersection observation should run throttled frames to
+ // kLayoutClean.
+ ForAllThrottledLocalFrameViews([](LocalFrameView& frame_view) {
+ DCHECK(frame_view.intersection_observation_state_ != kRequired ||
+ frame_view.Lifecycle().GetState() >=
+ DocumentLifecycle::kLayoutClean);
+ });
+ }
+#endif
+
+ return updated;
}
// TODO(schenney): add a scrolling update lifecycle phase.
// TODO(schenney): Pass a LifecycleUpdateReason in here
-bool LocalFrameView::UpdateLifecycleToCompositingCleanPlusScrolling() {
+bool LocalFrameView::UpdateLifecycleToCompositingCleanPlusScrolling(
+ DocumentUpdateReason reason) {
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
- return UpdateAllLifecyclePhasesExceptPaint();
+ return UpdateAllLifecyclePhasesExceptPaint(reason);
return GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhases(
- DocumentLifecycle::kCompositingClean,
- DocumentLifecycle::LifecycleUpdateReason::kOther);
+ DocumentLifecycle::kCompositingClean, reason);
}
// TODO(schenney): Pass a LifecycleUpdateReason in here
-bool LocalFrameView::UpdateLifecycleToCompositingInputsClean() {
+bool LocalFrameView::UpdateLifecycleToCompositingInputsClean(
+ DocumentUpdateReason reason) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ return UpdateAllLifecyclePhasesExceptPaint(reason);
return GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhases(
- DocumentLifecycle::kCompositingInputsClean,
- DocumentLifecycle::LifecycleUpdateReason::kOther);
+ DocumentLifecycle::kCompositingInputsClean, reason);
}
// TODO(schenney): Pass a LifecycleUpdateReason in here
-bool LocalFrameView::UpdateAllLifecyclePhasesExceptPaint() {
+bool LocalFrameView::UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason reason) {
return GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhases(
- DocumentLifecycle::kPrePaintClean,
- DocumentLifecycle::LifecycleUpdateReason::kOther);
+ DocumentLifecycle::kPrePaintClean, reason);
}
void LocalFrameView::UpdateLifecyclePhasesForPrinting() {
auto* local_frame_view_root = GetFrame().LocalFrameRoot().View();
local_frame_view_root->UpdateLifecyclePhases(
- DocumentLifecycle::kPrePaintClean,
- DocumentLifecycle::LifecycleUpdateReason::kOther);
+ DocumentLifecycle::kPrePaintClean, DocumentUpdateReason::kPrinting);
auto* detached_frame_view = this;
while (detached_frame_view->IsAttached() &&
@@ -2097,16 +2159,14 @@ void LocalFrameView::UpdateLifecyclePhasesForPrinting() {
// was not reached in some phases during during |local_frame_view_root->
// UpdateLifecyclePhasesnormal()|. We need the subtree to be ready for
// painting.
- detached_frame_view->UpdateLifecyclePhases(
- DocumentLifecycle::kPrePaintClean,
- DocumentLifecycle::LifecycleUpdateReason::kOther);
+ detached_frame_view->UpdateLifecyclePhases(DocumentLifecycle::kPrePaintClean,
+ DocumentUpdateReason::kPrinting);
}
// TODO(schenney): Pass a LifecycleUpdateReason in here
-bool LocalFrameView::UpdateLifecycleToLayoutClean() {
+bool LocalFrameView::UpdateLifecycleToLayoutClean(DocumentUpdateReason reason) {
return GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhases(
- DocumentLifecycle::kLayoutClean,
- DocumentLifecycle::LifecycleUpdateReason::kOther);
+ DocumentLifecycle::kLayoutClean, reason);
}
void LocalFrameView::ScheduleVisualUpdateForPaintInvalidationIfNeeded() {
@@ -2122,87 +2182,57 @@ void LocalFrameView::ScheduleVisualUpdateForPaintInvalidationIfNeeded() {
// phase of this cycle.
}
-void LocalFrameView::SetNeedsForcedResizeObservations() {
- if (auto* controller =
- GetFrame().GetDocument()->GetResizeObserverController())
- controller->SetNeedsForcedResizeObservations();
-}
-
-void LocalFrameView::NotifyResizeObservers() {
+bool LocalFrameView::NotifyResizeObservers(
+ DocumentLifecycle::LifecycleState target_state) {
+ // Return true if lifecycles need to be re-run
TRACE_EVENT0("blink,benchmark", "LocalFrameView::NotifyResizeObservers");
+
+ if (target_state < DocumentLifecycle::kPaintClean)
+ return false;
+
// Controller exists only if ResizeObserver was created.
if (!GetFrame().GetDocument()->GetResizeObserverController())
- return;
+ return false;
ResizeObserverController& resize_controller =
frame_->GetDocument()->EnsureResizeObserverController();
- DCHECK(Lifecycle().GetState() >= DocumentLifecycle::kLayoutClean);
-
- size_t min_depth = 0;
- for (min_depth = resize_controller.GatherObservations(0);
- min_depth != ResizeObserverController::kDepthBottom;
- min_depth = resize_controller.GatherObservations(min_depth)) {
- resize_controller.DeliverObservations();
- GetFrame().GetDocument()->UpdateStyleAndLayout(Document::IsNotForcedLayout);
- }
-
- if (resize_controller.SkippedObservations()) {
- resize_controller.ClearObservations();
- ErrorEvent* error = ErrorEvent::Create(
- "ResizeObserver loop limit exceeded",
- SourceLocation::Capture(frame_->GetDocument()), nullptr);
- // We're using |SanitizeScriptErrors::kDoNotSanitize| as the error is made
- // by blink itself.
- // TODO(yhirano): Reconsider this.
- frame_->GetDocument()->DispatchErrorEvent(
- error, SanitizeScriptErrors::kDoNotSanitize);
- // Ensure notifications will get delivered in next cycle.
- ScheduleAnimation();
- }
+ DCHECK(Lifecycle().GetState() >= DocumentLifecycle::kPrePaintClean);
- DCHECK(!GetLayoutView()->NeedsLayout());
-}
+ size_t min_depth = resize_controller.GatherObservations();
-void LocalFrameView::DispatchEventsForPrintingOnAllFrames() {
- DCHECK(frame_->IsMainFrame());
- for (Frame* current_frame = frame_; current_frame;
- current_frame = current_frame->Tree().TraverseNext(frame_)) {
- auto* current_local_frame = DynamicTo<LocalFrame>(current_frame);
- if (current_local_frame)
- current_local_frame->GetDocument()->DispatchEventsForPrinting();
+ if (min_depth != ResizeObserverController::kDepthBottom) {
+ resize_controller.DeliverObservations();
+ } else {
+ // Observation depth limit reached
+ if (resize_controller.SkippedObservations()) {
+ resize_controller.ClearObservations();
+ ErrorEvent* error = ErrorEvent::Create(
+ "ResizeObserver loop limit exceeded",
+ SourceLocation::Capture(frame_->GetDocument()->ToExecutionContext()),
+ nullptr);
+ // We're using |SanitizeScriptErrors::kDoNotSanitize| as the error is made
+ // by blink itself.
+ // TODO(yhirano): Reconsider this.
+ frame_->GetDocument()->ToExecutionContext()->DispatchErrorEvent(
+ error, SanitizeScriptErrors::kDoNotSanitize);
+ // Ensure notifications will get delivered in next cycle.
+ ScheduleAnimation();
+ DCHECK(Lifecycle().GetState() >= DocumentLifecycle::kPrePaintClean);
+ }
+ if (Lifecycle().GetState() >= DocumentLifecycle::kPrePaintClean)
+ return false;
}
-}
-void LocalFrameView::SetupPrintContext() {
- if (frame_->GetDocument()->Printing())
- return;
- if (!print_context_) {
- print_context_ = MakeGarbageCollected<PrintContext>(
- frame_, /*use_printing_layout=*/true);
- }
- if (frame_->GetSettings())
- frame_->GetSettings()->SetShouldPrintBackgrounds(true);
- bool is_us = DefaultLanguage() == "en-US";
- int width = is_us ? kLetterPortraitPageWidth : kA4PortraitPageWidth;
- int height = is_us ? kLetterPortraitPageHeight : kA4PortraitPageHeight;
- print_context_->BeginPrintMode(width, height);
- print_context_->ComputePageRects(FloatSize(width, height));
- DispatchEventsForPrintingOnAllFrames();
-}
-
-void LocalFrameView::ClearPrintContext() {
- if (!print_context_)
- return;
- print_context_->EndPrintMode();
- print_context_.Clear();
+ // Lifecycle needs to be run again because Resize Observer affected layout
+ return true;
}
// TODO(leviw): We don't assert lifecycle information from documents in child
// WebPluginContainerImpls.
bool LocalFrameView::UpdateLifecyclePhases(
DocumentLifecycle::LifecycleState target_state,
- DocumentLifecycle::LifecycleUpdateReason reason) {
+ DocumentUpdateReason reason) {
// If the lifecycle is postponed, which can happen if the inspector requests
// it, then we shouldn't update any lifecycle phases.
if (UNLIKELY(frame_->GetDocument() &&
@@ -2226,6 +2256,7 @@ bool LocalFrameView::UpdateLifecyclePhases(
// Only the following target states are supported.
DCHECK(target_state == DocumentLifecycle::kLayoutClean ||
+ target_state == DocumentLifecycle::kAccessibilityClean ||
target_state == DocumentLifecycle::kCompositingInputsClean ||
target_state == DocumentLifecycle::kCompositingClean ||
target_state == DocumentLifecycle::kPrePaintClean ||
@@ -2255,6 +2286,7 @@ bool LocalFrameView::UpdateLifecyclePhases(
// separate bool.
base::AutoReset<bool> past_layout_lifecycle_resetter(
&past_layout_lifecycle_update_, false);
+ base::AutoReset<bool> in_lifecycle_scope(&in_lifecycle_update_, true);
// If we're throttling, then we don't need to update lifecycle phases. The
// throttling status will get updated in RunPostLifecycleSteps().
@@ -2262,7 +2294,6 @@ bool LocalFrameView::UpdateLifecyclePhases(
return Lifecycle().GetState() == target_state;
}
- base::AutoReset<bool> in_lifecycle_scope(&in_lifecycle_update_, true);
lifecycle_data_.start_time = base::TimeTicks::Now();
++lifecycle_data_.count;
@@ -2276,13 +2307,17 @@ bool LocalFrameView::UpdateLifecyclePhases(
});
}
- // If we're in PrintBrowser mode, setup a print context.
- // TODO(vmpstr): It doesn't seem like we need to do this every lifecycle
- // update, but rather once somewhere at creation time.
- if (RuntimeEnabledFeatures::PrintBrowserEnabled())
- SetupPrintContext();
- else
- ClearPrintContext();
+ {
+ TRACE_EVENT0(
+ "blink",
+ "LocalFrameView::UpdateLifecyclePhases - start of lifecycle tasks");
+ ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
+ WTF::Vector<base::OnceClosure> tasks;
+ frame_view.start_of_lifecycle_tasks_.swap(tasks);
+ for (auto& task : tasks)
+ std::move(task).Run();
+ });
+ }
// Run the lifecycle updates.
UpdateLifecyclePhasesInternal(target_state);
@@ -2297,44 +2332,78 @@ bool LocalFrameView::UpdateLifecyclePhases(
});
}
+ // Hit testing metrics include the entire time processing a document update
+ // in preparation for a hit test.
+ if (reason == DocumentUpdateReason::kHitTest) {
+ LocalFrameUkmAggregator& aggregator = EnsureUkmAggregator();
+ aggregator.RecordSample(
+ static_cast<size_t>(LocalFrameUkmAggregator::kHitTestDocumentUpdate),
+ lifecycle_data_.start_time, base::TimeTicks::Now());
+ }
+
return Lifecycle().GetState() == target_state;
}
void LocalFrameView::UpdateLifecyclePhasesInternal(
DocumentLifecycle::LifecycleState target_state) {
- bool run_more_lifecycle_phases =
- RunStyleAndLayoutLifecyclePhases(target_state);
- if (!run_more_lifecycle_phases)
- return;
- DCHECK(Lifecycle().GetState() >= DocumentLifecycle::kLayoutClean);
+ // Run style, layout, compositing and prepaint lifecycle phases and deliver
+ // resize observations if required. Resize observer callbacks/delegates have
+ // the potential to dirty layout (until loop limit is reached) and therefore
+ // the above lifecycle phases need to be re-run until the limit is reached
+ // or no layout is pending.
+ while (true) {
+ bool run_more_lifecycle_phases =
+ RunStyleAndLayoutLifecyclePhases(target_state);
+ if (!run_more_lifecycle_phases)
+ return;
+ DCHECK(Lifecycle().GetState() >= DocumentLifecycle::kLayoutClean);
- if (!GetLayoutView())
- return;
+ if (!GetLayoutView())
+ return;
+ {
+ // We need scoping braces here because this
+ // DisallowLayoutInvalidationScope is meant to be in effect during
+ // pre-paint, but not during ResizeObserver.
#if DCHECK_IS_ON()
- DisallowLayoutInvalidationScope disallow_layout_invalidation(this);
+ DisallowLayoutInvalidationScope disallow_layout_invalidation(this);
#endif
- {
- TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
- "SetLayerTreeId", TRACE_EVENT_SCOPE_THREAD, "data",
- inspector_set_layer_tree_id::Data(frame_.Get()));
- TRACE_EVENT1("devtools.timeline", "UpdateLayerTree", "data",
- inspector_update_layer_tree_event::Data(frame_.Get()));
-
- run_more_lifecycle_phases = RunCompositingLifecyclePhase(target_state);
- if (!run_more_lifecycle_phases)
- return;
+ DCHECK_GE(target_state, DocumentLifecycle::kAccessibilityClean);
+ run_more_lifecycle_phases = RunAccessibilityLifecyclePhase(target_state);
+ DCHECK(ShouldThrottleRendering() || !ExistingAXObjectCache() ||
+ Lifecycle().GetState() == DocumentLifecycle::kAccessibilityClean);
+ if (!run_more_lifecycle_phases)
+ return;
+
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
+ "SetLayerTreeId", TRACE_EVENT_SCOPE_THREAD, "data",
+ inspector_set_layer_tree_id::Data(frame_.Get()));
+ TRACE_EVENT1("devtools.timeline", "UpdateLayerTree", "data",
+ inspector_update_layer_tree_event::Data(frame_.Get()));
+
+ run_more_lifecycle_phases = RunCompositingLifecyclePhase(target_state);
+ if (!run_more_lifecycle_phases)
+ return;
+
+ // TODO(pdr): PrePaint should be under the "Paint" devtools timeline step
+ // when CompositeAfterPaint is enabled.
+ run_more_lifecycle_phases = RunPrePaintLifecyclePhase(target_state);
+ DCHECK(ShouldThrottleRendering() ||
+ Lifecycle().GetState() >= DocumentLifecycle::kPrePaintClean);
+ if (!run_more_lifecycle_phases)
+ return;
+ }
- // TODO(pdr): PrePaint should be under the "Paint" devtools timeline step
- // when CompositeAfterPaint is enabled.
- run_more_lifecycle_phases = RunPrePaintLifecyclePhase(target_state);
- DCHECK(ShouldThrottleRendering() ||
- Lifecycle().GetState() >= DocumentLifecycle::kPrePaintClean);
+ run_more_lifecycle_phases = RunResizeObserverSteps(target_state);
if (!run_more_lifecycle_phases)
- return;
+ break;
}
-
+ // Layout invalidation scope was disabled for resize observer
+ // re-enable it for subsequent steps
+#if DCHECK_IS_ON()
+ DisallowLayoutInvalidationScope disallow_layout_invalidation(this);
+#endif
// Now that we have run the lifecycle up to paint, we can reset
// |need_paint_phase_after_throttling_| so that the paint phase will
// properly see us as being throttled (if that was the only reason we remained
@@ -2344,20 +2413,39 @@ void LocalFrameView::UpdateLifecyclePhasesInternal(
DCHECK_EQ(target_state, DocumentLifecycle::kPaintClean);
RunPaintLifecyclePhase();
DCHECK(ShouldThrottleRendering() ||
- (frame_->GetDocument()->IsCapturingLayout() &&
- !RuntimeEnabledFeatures::PrintBrowserEnabled()) ||
+ frame_->GetDocument()->IsCapturingLayout() ||
Lifecycle().GetState() == DocumentLifecycle::kPaintClean);
+
+ ForAllRemoteFrameViews(
+ [](RemoteFrameView& frame_view) { frame_view.UpdateCompositingRect(); });
+}
+
+bool LocalFrameView::RunResizeObserverSteps(
+ DocumentLifecycle::LifecycleState target_state) {
+ bool re_run_lifecycles = false;
+ if (target_state == DocumentLifecycle::kPaintClean) {
+ ForAllNonThrottledLocalFrameViews(
+ [&re_run_lifecycles](LocalFrameView& frame_view) {
+ bool result =
+ frame_view.NotifyResizeObservers(DocumentLifecycle::kPaintClean);
+ re_run_lifecycles = re_run_lifecycles || result;
+ });
+ }
+ if (!re_run_lifecycles) {
+ ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
+ ResizeObserverController& resize_controller =
+ frame_view.frame_->GetDocument()->EnsureResizeObserverController();
+ resize_controller.ClearMinDepth();
+ });
+ }
+ return re_run_lifecycles;
}
bool LocalFrameView::RunStyleAndLayoutLifecyclePhases(
DocumentLifecycle::LifecycleState target_state) {
TRACE_EVENT0("blink,benchmark",
"LocalFrameView::RunStyleAndLayoutLifecyclePhases");
- {
- SCOPED_UMA_AND_UKM_TIMER(EnsureUkmAggregator(),
- LocalFrameUkmAggregator::kStyleAndLayout);
- UpdateStyleAndLayoutIfNeededRecursive();
- }
+ UpdateStyleAndLayoutIfNeededRecursive();
DCHECK(Lifecycle().GetState() >= DocumentLifecycle::kLayoutClean);
frame_->GetDocument()
@@ -2397,23 +2485,18 @@ bool LocalFrameView::RunStyleAndLayoutLifecyclePhases(
frame_view.PerformScrollAnchoringAdjustments();
});
+ frame_->GetDocument()->PerformScrollSnappingTasks();
+
EnqueueScrollEvents();
frame_->GetPage()->GetValidationMessageClient().LayoutOverlay();
if (target_state == DocumentLifecycle::kPaintClean) {
- ForAllNonThrottledLocalFrameViews(
- [](LocalFrameView& frame_view) { frame_view.NotifyResizeObservers(); });
-
ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
frame_view.NotifyFrameRectsChangedIfNeeded();
});
}
- // If we exceed the number of re-layouts during ResizeObserver notifications,
- // then we shouldn't continue with the lifecycle updates. At that time, we
- // have scheduled an animation and we'll try again.
- DCHECK(Lifecycle().GetState() >= DocumentLifecycle::kLayoutClean ||
- Lifecycle().GetState() == DocumentLifecycle::kVisualUpdatePending);
+
return Lifecycle().GetState() >= DocumentLifecycle::kLayoutClean;
}
@@ -2428,7 +2511,18 @@ bool LocalFrameView::RunCompositingLifecyclePhase(
SCOPED_UMA_AND_UKM_TIMER(EnsureUkmAggregator(),
LocalFrameUkmAggregator::kCompositing);
layout_view->Compositor()->UpdateIfNeededRecursive(target_state);
- } else {
+ }
+
+ return target_state > DocumentLifecycle::kCompositingClean;
+}
+
+bool LocalFrameView::RunPrePaintLifecyclePhase(
+ DocumentLifecycle::LifecycleState target_state) {
+ TRACE_EVENT0("blink,benchmark", "LocalFrameView::RunPrePaintLifecyclePhase");
+
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ // TODO(pdr): This descendant dependent treewalk should be integrated into
+ // the prepaint tree walk.
#if DCHECK_IS_ON()
SetIsUpdatingDescendantDependentFlags(true);
#endif
@@ -2441,13 +2535,6 @@ bool LocalFrameView::RunCompositingLifecyclePhase(
#endif
}
- return target_state > DocumentLifecycle::kCompositingClean;
-}
-
-bool LocalFrameView::RunPrePaintLifecyclePhase(
- DocumentLifecycle::LifecycleState target_state) {
- TRACE_EVENT0("blink,benchmark", "LocalFrameView::RunPrePaintLifecyclePhase");
-
ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
frame_view.Lifecycle().AdvanceTo(DocumentLifecycle::kInPrePaint);
if (frame_view.CanThrottleRendering()) {
@@ -2502,12 +2589,7 @@ void LocalFrameView::RunPaintLifecyclePhase() {
// While printing or capturing a paint preview of a document, the paint walk
// is done into a special canvas. There is no point doing a normal paint step
// (or animations update) when in this mode.
- //
- // RuntimeEnabledFeatures::PrintBrowserEnabled is a mode which runs the
- // browser normally, but renders every page as if it were being printed.
- // See crbug.com/667547
- bool is_capturing_layout = frame_->GetDocument()->IsCapturingLayout() &&
- !RuntimeEnabledFeatures::PrintBrowserEnabled();
+ bool is_capturing_layout = frame_->GetDocument()->IsCapturingLayout();
if (!is_capturing_layout)
PaintTree();
@@ -2528,9 +2610,11 @@ void LocalFrameView::RunPaintLifecyclePhase() {
for (PaintLayerScrollableArea* area : *animating_scrollable_areas)
area->UpdateCompositorScrollAnimations();
}
- DocumentAnimations::UpdateAnimations(
- frame_view.GetLayoutView()->GetDocument(),
- DocumentLifecycle::kPaintClean, paint_artifact_compositor_.get());
+ frame_view.GetLayoutView()
+ ->GetDocument()
+ .GetDocumentAnimations()
+ .UpdateAnimations(DocumentLifecycle::kPaintClean,
+ paint_artifact_compositor_.get());
});
// Initialize animation properties in the newly created paint property
@@ -2573,6 +2657,22 @@ void LocalFrameView::RunPaintLifecyclePhase() {
}
}
+bool LocalFrameView::RunAccessibilityLifecyclePhase(
+ DocumentLifecycle::LifecycleState target_state) {
+ TRACE_EVENT0("blink,benchmark",
+ "LocalFrameView::RunAccessibilityLifecyclePhase");
+ ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
+ if (AXObjectCache* cache = frame_view.ExistingAXObjectCache()) {
+ frame_view.Lifecycle().AdvanceTo(DocumentLifecycle::kInAccessibility);
+ cache->ProcessDeferredAccessibilityEvents(
+ *frame_view.GetFrame().GetDocument());
+ frame_view.Lifecycle().AdvanceTo(DocumentLifecycle::kAccessibilityClean);
+ }
+ });
+
+ return target_state > DocumentLifecycle::kAccessibilityClean;
+}
+
void LocalFrameView::EnqueueScrollAnchoringAdjustment(
ScrollableArea* scrollable_area) {
anchoring_adjustment_queue_.insert(scrollable_area);
@@ -2596,7 +2696,7 @@ void LocalFrameView::PerformScrollAnchoringAdjustments() {
AnchoringAdjustmentQueue queue_copy = anchoring_adjustment_queue_;
anchoring_adjustment_queue_.clear();
- for (WeakMember<ScrollableArea>& scroller : queue_copy) {
+ for (const WeakMember<ScrollableArea>& scroller : queue_copy) {
if (scroller) {
DCHECK(scroller->GetScrollAnchor());
scroller->GetScrollAnchor()->Adjust();
@@ -2606,7 +2706,7 @@ void LocalFrameView::PerformScrollAnchoringAdjustments() {
void LocalFrameView::EnqueueScrollEvents() {
ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
- for (WeakMember<PaintLayerScrollableArea>& scroller :
+ for (const WeakMember<PaintLayerScrollableArea>& scroller :
frame_view.scroll_event_queue_) {
if (scroller)
scroller->EnqueueScrollEventIfNeeded();
@@ -2656,16 +2756,13 @@ static void CollectDrawableLayersForLayerListRecursively(
const GraphicsLayer* root) {
ForAllDrawableGraphicsLayers(
root,
- [&](const GraphicsLayer* layer) {
- RecordGraphicsLayerAsForeignLayer(
- context, DisplayItem::kForeignLayerWrapper, *layer);
- },
+ [&](const GraphicsLayer* layer) { RecordGraphicsLayer(context, *layer); },
[&](const GraphicsLayer* layer, cc::Layer* contents_layer) {
RecordForeignLayer(
context, *layer, DisplayItem::kForeignLayerContentsWrapper,
contents_layer,
FloatPoint(layer->GetContentsOffsetFromTransformNode()),
- layer->GetContentsPropertyTreeState());
+ &layer->GetContentsPropertyTreeState());
});
}
@@ -2675,7 +2772,7 @@ static void UpdateLayerDebugInfoRecursively(const GraphicsLayer* root) {
[](const GraphicsLayer* layer) {
PaintArtifactCompositor::UpdateLayerDebugInfo(
layer->CcLayer(),
- PaintChunk::Id(*layer, DisplayItem::kForeignLayerWrapper),
+ PaintChunk::Id(*layer, DisplayItem::kGraphicsLayerWrapper),
layer->GetCompositingReasons(),
layer->GetRasterInvalidationTracking());
},
@@ -2722,9 +2819,6 @@ void LocalFrameView::PaintTree() {
paint_controller_->UpdateUMACountsOnFullyCached();
} else {
GraphicsContext graphics_context(*paint_controller_);
- if (RuntimeEnabledFeatures::PrintBrowserEnabled())
- graphics_context.SetPrinting(true);
-
if (Settings* settings = frame_->GetSettings()) {
graphics_context.SetDarkMode(
BuildDarkModeSettings(*settings, *GetLayoutView()));
@@ -2764,8 +2858,8 @@ void LocalFrameView::PaintTree() {
layout_view->Compositor()->PaintRootGraphicsLayer()) {
bool painted = PaintGraphicsLayerRecursively(root_graphics_layer);
if (painted) {
- // If the painted result changed, the painted hit test display items may
- // have changed which will affect the mapped hit test geometry.
+ // If the painted result changed, the recorded hit test data may have
+ // changed which will affect the mapped hit test geometry.
if (GetScrollingCoordinator())
GetScrollingCoordinator()->NotifyGeometryChanged(this);
}
@@ -2982,8 +3076,9 @@ void LocalFrameView::UpdateStyleAndLayoutIfNeededRecursive() {
if (Lifecycle().GetState() < DocumentLifecycle::kLayoutClean)
Lifecycle().AdvanceTo(DocumentLifecycle::kLayoutClean);
- if (AXObjectCache* cache = GetFrame().GetDocument()->ExistingAXObjectCache())
- cache->ProcessUpdatesAfterLayout(*GetFrame().GetDocument());
+ // If we're restoring a scroll position from history, that takes precedence
+ // over scrolling to the anchor in the URL.
+ frame_->GetDocument()->ApplyScrollRestorationLogic();
// Ensure that we become visually non-empty eventually.
// TODO(esprehn): This should check isRenderingReady() instead.
@@ -3015,8 +3110,8 @@ void LocalFrameView::DisableAutoSizeMode() {
ScheduleRelayout();
// Since autosize mode forces the scrollbar mode, change them to being auto.
- GetLayoutView()->SetAutosizeScrollbarModes(ScrollbarMode::kAuto,
- ScrollbarMode::kAuto);
+ GetLayoutView()->SetAutosizeScrollbarModes(
+ mojom::blink::ScrollbarMode::kAuto, mojom::blink::ScrollbarMode::kAuto);
auto_size_info_.Clear();
}
@@ -3040,7 +3135,7 @@ void LocalFrameView::ForceLayoutForPagination(
static_cast<LayoutUnit>(page_logical_height);
layout_view->SetLogicalWidth(floored_page_logical_width);
layout_view->SetPageLogicalHeight(floored_page_logical_height);
- layout_view->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ layout_view->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kPrintingChanged);
UpdateLayout();
@@ -3076,8 +3171,9 @@ void LocalFrameView::ForceLayoutForPagination(
static_cast<LayoutUnit>(page_logical_height);
layout_view->SetLogicalWidth(floored_page_logical_width);
layout_view->SetPageLogicalHeight(floored_page_logical_height);
- layout_view->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
- layout_invalidation_reason::kPrintingChanged);
+ layout_view
+ ->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
+ layout_invalidation_reason::kPrintingChanged);
UpdateLayout();
PhysicalRect updated_document_rect(layout_view->DocumentRect());
@@ -3367,7 +3463,7 @@ void LocalFrameView::SetTracksRasterInvalidations(
return;
// Ensure the document is up-to-date before tracking invalidations.
- UpdateAllLifecyclePhases(DocumentLifecycle::LifecycleUpdateReason::kTest);
+ UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
for (Frame* frame = &frame_->Tree().Top(); frame;
frame = frame->Tree().TraverseNext()) {
@@ -3398,17 +3494,6 @@ void LocalFrameView::ScheduleAnimation(base::TimeDelta delay) {
client->ScheduleAnimation(this, delay);
}
-bool LocalFrameView::FrameIsScrollableDidChange() {
- DCHECK(GetFrame().IsLocalRoot());
- return GetScrollingContext()->WasScrollable() !=
- LayoutViewport()->ScrollsOverflow();
-}
-
-void LocalFrameView::ClearFrameIsScrollableDidChange() {
- GetScrollingContext()->SetWasScrollable(
- GetFrame().LocalFrameRoot().View()->LayoutViewport()->ScrollsOverflow());
-}
-
void LocalFrameView::ScrollableAreasDidChange() {
// Layout may update scrollable area bounding boxes. It also sets the same
// dirty flag making this one redundant (See
@@ -3534,7 +3619,7 @@ AXObjectCache* LocalFrameView::ExistingAXObjectCache() const {
return nullptr;
}
-void LocalFrameView::SetCursor(const Cursor& cursor) {
+void LocalFrameView::SetCursor(const ui::Cursor& cursor) {
Page* page = GetFrame().GetPage();
if (!page || frame_->GetEventHandler().IsMousePositionUnknown())
return;
@@ -3633,14 +3718,14 @@ ScrollableArea* LocalFrameView::ScrollableAreaWithElementId(
void LocalFrameView::ScrollRectToVisibleInRemoteParent(
const PhysicalRect& rect_to_scroll,
- const WebScrollIntoViewParams& params) {
+ mojom::blink::ScrollIntoViewParamsPtr params) {
DCHECK(GetFrame().IsLocalRoot() && !GetFrame().IsMainFrame() &&
safe_to_propagate_scroll_to_parent_);
PhysicalRect new_rect = ConvertToRootFrame(rect_to_scroll);
- GetFrame().Client()->ScrollRectToVisibleInParentFrame(
- WebRect(new_rect.X().ToInt(), new_rect.Y().ToInt(),
- new_rect.Width().ToInt(), new_rect.Height().ToInt()),
- params);
+ frame_->GetLocalFrameHostRemote().ScrollRectToVisibleInParentFrame(
+ gfx::Rect(new_rect.X().ToInt(), new_rect.Y().ToInt(),
+ new_rect.Width().ToInt(), new_rect.Height().ToInt()),
+ std::move(params));
}
void LocalFrameView::NotifyFrameRectsChangedIfNeeded() {
@@ -3747,9 +3832,6 @@ void LocalFrameView::PaintOutsideOfLifecycle(
const CullRect& cull_rect) {
DCHECK(PaintOutsideOfLifecycleIsAllowed(context, *this));
- base::AutoReset<bool> past_layout_lifecycle_resetter(
- &past_layout_lifecycle_update_, true);
-
ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
frame_view.Lifecycle().AdvanceTo(DocumentLifecycle::kInPaint);
});
@@ -3767,9 +3849,6 @@ void LocalFrameView::PaintContentsOutsideOfLifecycle(
const CullRect& cull_rect) {
DCHECK(PaintOutsideOfLifecycleIsAllowed(context, *this));
- base::AutoReset<bool> past_layout_lifecycle_resetter(
- &past_layout_lifecycle_update_, true);
-
ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) {
frame_view.Lifecycle().AdvanceTo(DocumentLifecycle::kInPaint);
});
@@ -3976,7 +4055,8 @@ bool LocalFrameView::UpdateViewportIntersectionsForSubtree(
intersection_observation_state_ = kNotNeeded;
}
- UpdateViewportIntersection(flags, needs_occlusion_tracking);
+ if (UpdateViewportIntersection(flags, needs_occlusion_tracking))
+ flags |= IntersectionObservation::kCanSkipStickyFrameTracking;
for (Frame* child = frame_->Tree().FirstChild(); child;
child = child->Tree().NextSibling()) {
@@ -4006,7 +4086,7 @@ void LocalFrameView::DeliverSynchronousIntersectionObservations() {
});
}
-void LocalFrameView::CrossOriginStatusChanged() {
+void LocalFrameView::CrossOriginToMainFrameChanged() {
// If any of these conditions hold, then a change in cross-origin status does
// not affect throttling.
if (lifecycle_updates_throttled_ || IsSubtreeThrottled() ||
@@ -4023,6 +4103,11 @@ void LocalFrameView::CrossOriginStatusChanged() {
true);
}
+void LocalFrameView::CrossOriginToParentFrameChanged() {
+ if (auto* owner = frame_->DeprecatedLocalOwner())
+ owner->FrameCrossOriginToParentFrameChanged();
+}
+
void LocalFrameView::VisibilityForThrottlingChanged() {
if (FrameScheduler* frame_scheduler = frame_->GetFrameScheduler()) {
// TODO(szager): Per crbug.com/994443, maybe this should be:
@@ -4150,6 +4235,9 @@ unsigned LocalFrameView::GetIntersectionObservationFlags(
// applies to the entire frame tree.
flags |= (parent_flags & IntersectionObservation::kIgnoreDelay);
+ flags |=
+ (parent_flags & IntersectionObservation::kCanSkipStickyFrameTracking);
+
return flags;
}
@@ -4162,10 +4250,17 @@ bool LocalFrameView::ShouldThrottleRendering() const {
return false;
}
- // Only lifecycle phases up to layout are needed to generate an
- // intersection observation.
- return intersection_observation_state_ != kRequired ||
- GetFrame().LocalFrameRoot().View()->past_layout_lifecycle_update_;
+ if (intersection_observation_state_ == kRequired) {
+ auto* local_frame_root_view = GetFrame().LocalFrameRoot().View();
+ // When doing a lifecycle update required by intersection observer, we can
+ // throttle lifecycle states after layout. Outside of lifecycle updates,
+ // the frame should be considered throttled because it is not fully updating
+ // the lifecycle.
+ return !local_frame_root_view->in_lifecycle_update_ ||
+ local_frame_root_view->past_layout_lifecycle_update_;
+ }
+
+ return true;
}
bool LocalFrameView::CanThrottleRendering() const {
@@ -4179,7 +4274,7 @@ bool LocalFrameView::CanThrottleRendering() const {
// cross-origin frames must already communicate with asynchronous messages,
// so they should be able to tolerate some delay in receiving replies from a
// throttled peer.
- return IsHiddenForThrottling() && frame_->IsCrossOriginSubframe();
+ return IsHiddenForThrottling() && frame_->IsCrossOriginToMainFrame();
}
void LocalFrameView::UpdateRenderThrottlingStatus(bool hidden_for_throttling,
@@ -4343,13 +4438,16 @@ String LocalFrameView::MainThreadScrollingReasonsAsText() {
return String(cc::MainThreadScrollingReason::AsText(reasons).c_str());
}
-bool LocalFrameView::MapToVisualRectInRemoteRootFrame(PhysicalRect& rect) {
+bool LocalFrameView::MapToVisualRectInRemoteRootFrame(
+ PhysicalRect& rect,
+ bool apply_overflow_clip) {
DCHECK(frame_->IsLocalRoot());
// This is the top-level frame, so no mapping necessary.
if (frame_->IsMainFrame())
return true;
- bool result = rect.InclusiveIntersect(
- PhysicalRect(frame_->RemoteViewportIntersection()));
+ bool result = rect.InclusiveIntersect(PhysicalRect(
+ apply_overflow_clip ? frame_->RemoteViewportIntersection()
+ : frame_->RemoteMainFrameDocumentIntersection()));
if (result)
rect.Move(PhysicalOffset(GetFrame().RemoteViewportOffset()));
return result;
@@ -4394,6 +4492,10 @@ void LocalFrameView::UnregisterFromLifecycleNotifications(
lifecycle_observers_.erase(observer);
}
+void LocalFrameView::EnqueueStartOfLifecycleTask(base::OnceClosure closure) {
+ start_of_lifecycle_tasks_.push_back(std::move(closure));
+}
+
#if DCHECK_IS_ON()
LocalFrameView::DisallowLayoutInvalidationScope::
DisallowLayoutInvalidationScope(LocalFrameView* view)
@@ -4422,9 +4524,7 @@ void LocalFrameView::UpdateLayerDebugInfoEnabled() {
DCHECK(frame_->IsLocalRoot());
#if DCHECK_IS_ON()
DCHECK(layer_debug_info_enabled_);
- return;
-#endif
-
+#else
bool should_enable =
cc::frame_viewer_instrumentation::IsTracingLayerTreeSnapshots() ||
WebTestSupport::IsRunningWebTest() ||
@@ -4433,6 +4533,16 @@ void LocalFrameView::UpdateLayerDebugInfoEnabled() {
layer_debug_info_enabled_ = should_enable;
SetPaintArtifactCompositorNeedsUpdate();
}
+#endif
+}
+
+OverlayInterstitialAdDetector&
+LocalFrameView::EnsureOverlayInterstitialAdDetector() {
+ if (!overlay_interstitial_ad_detector_) {
+ overlay_interstitial_ad_detector_ =
+ std::make_unique<OverlayInterstitialAdDetector>();
+ }
+ return *overlay_interstitial_ad_detector_.get();
}
} // 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 b6a2a604e54..076606e9eed 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
@@ -28,12 +28,16 @@
#include <memory>
+#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/manifest/display_mode.mojom-shared.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/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"
@@ -56,11 +60,14 @@ class Layer;
enum class PaintHoldingCommitTrigger;
}
+namespace ui {
+class Cursor;
+}
+
namespace blink {
class AXObjectCache;
class ChromeClient;
class CompositorAnimationTimeline;
-class Cursor;
class DocumentLifecycle;
class FloatRect;
class FloatSize;
@@ -82,7 +89,6 @@ class PaintArtifactCompositor;
class PaintController;
class PaintLayerScrollableArea;
class PaintTimingDetector;
-class PrintContext;
class RootFrameViewport;
class ScrollableArea;
class Scrollbar;
@@ -96,7 +102,6 @@ struct AnnotatedRegionValue;
struct IntrinsicSizingInfo;
struct PhysicalOffset;
struct PhysicalRect;
-struct WebScrollIntoViewParams;
typedef uint64_t DOMTimeStamp;
using LayerTreeFlags = unsigned;
@@ -125,8 +130,8 @@ class CORE_EXPORT LocalFrameView final
: public GarbageCollectedMixin {
public:
// These are called when the lifecycle updates start/finish.
- virtual void WillStartLifecycleUpdate(const LocalFrameView&) = 0;
- virtual void DidFinishLifecycleUpdate(const LocalFrameView&) = 0;
+ virtual void WillStartLifecycleUpdate(const LocalFrameView&) {}
+ virtual void DidFinishLifecycleUpdate(const LocalFrameView&) {}
};
explicit LocalFrameView(LocalFrame&);
@@ -164,7 +169,7 @@ class CORE_EXPORT LocalFrameView final
// Methods to capture forced layout metrics.
void WillStartForcedLayout();
- void DidFinishForcedLayout();
+ void DidFinishForcedLayout(DocumentUpdateReason);
void ClearLayoutSubtreeRoot(const LayoutObject&);
void AddOrthogonalWritingModeRoot(LayoutBox&);
@@ -240,8 +245,6 @@ class CORE_EXPORT LocalFrameView final
bool GetIntrinsicSizingInfo(IntrinsicSizingInfo&) const override;
bool HasIntrinsicSizingInfo() const override;
- void UpdateAcceleratedCompositingSettings();
-
void UpdateCountersAfterStyleChange();
void Dispose() override;
@@ -327,8 +330,8 @@ class CORE_EXPORT LocalFrameView final
// lifecycle update (e.g., based on visibility) and will not end up being
// PaintClean. Set |reason| to indicate the reason for this update,
// for metrics purposes.
- void UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason reason);
+ // Returns whether the lifecycle was successfully updated to PaintClean.
+ bool UpdateAllLifecyclePhases(DocumentUpdateReason reason);
// Computes the style, layout, compositing and pre-paint lifecycle stages
// if needed.
@@ -336,7 +339,7 @@ class CORE_EXPORT LocalFrameView final
// state >= PrePaintClean, unless the frame was throttled or inactive.
// Returns whether the lifecycle was successfully updated to the
// desired state.
- bool UpdateAllLifecyclePhasesExceptPaint();
+ bool UpdateAllLifecyclePhasesExceptPaint(DocumentUpdateReason reason);
// Printing needs everything up-to-date except paint (which will be done
// specially). We may also print a detached frame or a descendant of a
@@ -348,21 +351,22 @@ class CORE_EXPORT LocalFrameView final
// throttling is allowed), unless the frame was throttled or inactive.
// Returns whether the lifecycle was successfully updated to the
// desired state.
- bool UpdateLifecycleToCompositingCleanPlusScrolling();
+ bool UpdateLifecycleToCompositingCleanPlusScrolling(
+ DocumentUpdateReason reason);
// Computes the style, layout, and compositing inputs lifecycle stages if
// needed. After calling this method, all frames will be in a lifecycle state
// >= CompositingInputsClean, unless the frame was throttled or inactive.
// Returns whether the lifecycle was successfully updated to the
// desired state.
- bool UpdateLifecycleToCompositingInputsClean();
+ bool UpdateLifecycleToCompositingInputsClean(DocumentUpdateReason reason);
// Computes only the style and layout lifecycle stages.
// After calling this method, all frames will be in a lifecycle
// state >= LayoutClean, unless the frame was throttled or inactive.
// Returns whether the lifecycle was successfully updated to the
// desired state.
- bool UpdateLifecycleToLayoutClean();
+ bool UpdateLifecycleToLayoutClean(DocumentUpdateReason reason);
bool InLifecycleUpdate() { return in_lifecycle_update_; }
void SetInLifecycleUpdateForTest(bool val) { in_lifecycle_update_ = val; }
@@ -422,7 +426,7 @@ class CORE_EXPORT LocalFrameView final
bool ShouldSetCursor() const;
- void SetCursor(const Cursor&);
+ void SetCursor(const ui::Cursor&);
// FIXME: Remove this method once plugin loading is decoupled from layout.
void FlushAnyPendingPostLayoutTasks();
@@ -548,8 +552,11 @@ class CORE_EXPORT LocalFrameView final
void Hide() override;
bool IsLocalFrameView() const override { return true; }
+ // TODO(https://crbug/1085175): Re-enable reporting main frame intersections
+ // once intersections are in the root document coordinate system.
+ bool ShouldReportMainFrameIntersection() const override { return false; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void NotifyPageThatContentAreaWillPaint() const;
// Returns the scrollable area for the frame. For the root frame, this will
@@ -613,11 +620,13 @@ class CORE_EXPORT LocalFrameView final
bool HasVisibleSlowRepaintViewportConstrainedObjects() const;
- bool MapToVisualRectInRemoteRootFrame(PhysicalRect&);
+ bool MapToVisualRectInRemoteRootFrame(PhysicalRect& rect,
+ bool apply_overflow_clip = true);
void MapLocalToRemoteRootFrame(TransformState&);
- void CrossOriginStatusChanged();
+ void CrossOriginToMainFrameChanged();
+ void CrossOriginToParentFrameChanged();
// The visual viewport can supply scrollbars.
void VisualViewportScrollbarsChanged();
@@ -641,18 +650,12 @@ class CORE_EXPORT LocalFrameView final
// When the frame is a local root and not a main frame, any recursive
// scrolling should continue in the parent process.
void ScrollRectToVisibleInRemoteParent(const PhysicalRect&,
- const WebScrollIntoViewParams&);
+ mojom::blink::ScrollIntoViewParamsPtr);
PaintArtifactCompositor* GetPaintArtifactCompositor() const;
const cc::Layer* RootCcLayer() const;
- // Keeps track of whether the scrollable state for the LocalRoot has changed
- // since ScrollingCoordinator last checked. Only ScrollingCoordinator should
- // ever call the clearing function.
- bool FrameIsScrollableDidChange();
- void ClearFrameIsScrollableDidChange();
-
// Should be called whenever this LocalFrameView adds or removes a
// scrollable area, or gains/loses a composited layer.
void ScrollableAreasDidChange();
@@ -686,9 +689,15 @@ class CORE_EXPORT LocalFrameView final
void RegisterForLifecycleNotifications(LifecycleNotificationObserver*);
void UnregisterFromLifecycleNotifications(LifecycleNotificationObserver*);
- // Sets whether all ResizeObservers should check all their ResizeObservations
- // for a resize. This is needed when exiting a display lock.
- void SetNeedsForcedResizeObservations();
+ // Enqueue tasks to be run at the start of the next lifecycle. These tasks
+ // will run right after `WillStartLifecycleUpdate()` on the lifecycle
+ // notification observers.
+ void EnqueueStartOfLifecycleTask(base::OnceClosure);
+
+ // For testing way to steal the start-of-lifecycle tasks.
+ WTF::Vector<base::OnceClosure> TakeStartOfLifecycleTasksForTest() {
+ return std::move(start_of_lifecycle_tasks_);
+ }
protected:
void FrameRectsChanged(const IntRect&) override;
@@ -733,15 +742,10 @@ class CORE_EXPORT LocalFrameView final
LayoutSVGRoot* EmbeddedReplacedContent() const;
- void DispatchEventsForPrintingOnAllFrames();
-
- void SetupPrintContext();
- void ClearPrintContext();
-
- // Returns whether the lifecycle was succesfully updated to the
+ // Returns whether the lifecycle was successfully updated to the
// target state.
bool UpdateLifecyclePhases(DocumentLifecycle::LifecycleState target_state,
- DocumentLifecycle::LifecycleUpdateReason reason);
+ DocumentUpdateReason reason);
// The internal version that does the work after the proper context and checks
// have passed in the above function call.
void UpdateLifecyclePhasesInternal(
@@ -752,6 +756,8 @@ class CORE_EXPORT LocalFrameView final
// earlier if we don't need to run future lifecycle phases.
bool RunStyleAndLayoutLifecyclePhases(
DocumentLifecycle::LifecycleState target_state);
+ bool RunAccessibilityLifecyclePhase(
+ DocumentLifecycle::LifecycleState target_state);
bool RunCompositingLifecyclePhase(
DocumentLifecycle::LifecycleState target_state);
bool RunPrePaintLifecyclePhase(
@@ -823,10 +829,17 @@ class CORE_EXPORT LocalFrameView final
template <typename Function>
void ForAllNonThrottledLocalFrameViews(const Function&);
+ template <typename Function>
+ void ForAllThrottledLocalFrameViews(const Function&);
+
+ template <typename Function>
+ void ForAllRemoteFrameViews(const Function&);
+
bool UpdateViewportIntersectionsForSubtree(unsigned parent_flags) override;
void DeliverSynchronousIntersectionObservations();
- void NotifyResizeObservers();
+ bool NotifyResizeObservers(DocumentLifecycle::LifecycleState target_state);
+ bool RunResizeObserverSteps(DocumentLifecycle::LifecycleState target_state);
bool CheckLayoutInvalidationIsAllowed() const;
@@ -836,6 +849,10 @@ class CORE_EXPORT LocalFrameView final
void UpdateLayerDebugInfoEnabled();
+ // Return the interstitial-ad detector for this frame, creating it if
+ // necessary.
+ OverlayInterstitialAdDetector& EnsureOverlayInterstitialAdDetector();
+
LayoutSize size_;
typedef HashSet<scoped_refptr<LayoutEmbeddedObject>> EmbeddedObjectSet;
@@ -973,8 +990,6 @@ class CORE_EXPORT LocalFrameView final
unsigned forced_layout_stack_depth_;
base::TimeTicks forced_layout_start_time_;
- Member<PrintContext> print_context_;
-
// From the beginning of the document, how many frames have painted.
size_t paint_frame_count_;
@@ -991,6 +1006,12 @@ class CORE_EXPORT LocalFrameView final
// it can clear the painted output.
bool need_paint_phase_after_throttling_ = false;
+ std::unique_ptr<OverlayInterstitialAdDetector>
+ overlay_interstitial_ad_detector_;
+
+ // These tasks will be run at the beginning of the next lifecycle.
+ WTF::Vector<base::OnceClosure> start_of_lifecycle_tasks_;
+
#if DCHECK_IS_ON()
bool is_updating_descendant_dependent_flags_;
#endif
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 cd6a8f1f198..eae22851688 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
@@ -7,6 +7,7 @@
#include <memory>
#include "testing/gmock/include/gmock/gmock.h"
+#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/layout/layout_view.h"
@@ -114,16 +115,16 @@ TEST_F(LocalFrameViewTest, HideTooltipWhenScrollPositionChanges) {
EXPECT_CALL(GetAnimationMockChromeClient(),
MockSetToolTip(GetDocument().GetFrame(), String(), _));
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(1, 1),
- kUserScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(1, 1), mojom::blink::ScrollType::kUser);
// Programmatic scrolling should not dismiss the tooltip, so setToolTip
// should not be called for this invocation.
EXPECT_CALL(GetAnimationMockChromeClient(),
MockSetToolTip(GetDocument().GetFrame(), String(), _))
.Times(0);
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(2, 2),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(2, 2), mojom::blink::ScrollType::kProgrammatic);
}
// NoOverflowInIncrementVisuallyNonEmptyPixelCount tests fail if the number of
@@ -157,8 +158,8 @@ TEST_F(LocalFrameViewTest,
sticky->Layer()->UpdateAncestorOverflowLayer(nullptr);
// This call should not crash.
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 100),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 100), mojom::blink::ScrollType::kProgrammatic);
}
TEST_F(LocalFrameViewTest, UpdateLifecyclePhasesForPrintingDetachedFrame) {
@@ -181,8 +182,8 @@ TEST_F(LocalFrameViewTest, CanHaveScrollbarsIfScrollingAttrEqualsNoChanged) {
SetBodyInnerHTML("<iframe scrolling='no'></iframe>");
EXPECT_FALSE(ChildDocument().View()->CanHaveScrollbars());
- ChildDocument().WillChangeFrameOwnerProperties(0, 0, ScrollbarMode::kAlwaysOn,
- false);
+ ChildDocument().WillChangeFrameOwnerProperties(
+ 0, 0, mojom::blink::ScrollbarMode::kAlwaysOn, false);
EXPECT_TRUE(ChildDocument().View()->CanHaveScrollbars());
}
@@ -343,9 +344,9 @@ TEST_F(SimTest, FragmentNavChangesFocusWhileRenderingBlocked) {
<< "Scroll offset changed while rendering is blocked";
// Force a layout.
- anchor->style()->setProperty(&GetDocument(), "display", "block", String(),
- ASSERT_NO_EXCEPTION);
- GetDocument().UpdateStyleAndLayout();
+ anchor->style()->setProperty(GetDocument().ToExecutionContext(), "display",
+ "block", String(), ASSERT_NO_EXCEPTION);
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_EQ(GetDocument().body(), GetDocument().ActiveElement())
<< "Active element changed due to layout while rendering is blocked";
@@ -385,7 +386,7 @@ TEST_F(SimTest, ForcedLayoutWithIncompleteSVGChildFrame) {
// Mark the top-level document for layout and then force layout. This will
// cause the layout tree in the <object> object to be built.
GetDocument().View()->SetNeedsLayout();
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
svg_resource.Finish();
}
diff --git a/chromium/third_party/blink/renderer/core/frame/location.cc b/chromium/third_party/blink/renderer/core/frame/location.cc
index 1d21eaac874..63deafc4f52 100644
--- a/chromium/third_party/blink/renderer/core/frame/location.cc
+++ b/chromium/third_party/blink/renderer/core/frame/location.cc
@@ -49,13 +49,17 @@ Location::Location(DOMWindow* dom_window)
: dom_window_(dom_window),
fragment_directive_(MakeGarbageCollected<FragmentDirective>()) {}
-void Location::Trace(blink::Visitor* visitor) {
+void Location::Trace(Visitor* visitor) {
visitor->Trace(dom_window_);
visitor->Trace(fragment_directive_);
ScriptWrappable::Trace(visitor);
}
inline const KURL& Location::Url() const {
+ const KURL& web_bundle_claimed_url = GetDocument()->WebBundleClaimedUrl();
+ if (web_bundle_claimed_url.IsValid()) {
+ return web_bundle_claimed_url;
+ }
const KURL& url = GetDocument()->Url();
if (!url.IsValid()) {
// Use "about:blank" while the page is still loading (before we have a
diff --git a/chromium/third_party/blink/renderer/core/frame/location.h b/chromium/third_party/blink/renderer/core/frame/location.h
index 5708dec7dd7..64013637445 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
// Note: it is only valid to call this if this is a Location object for a
diff --git a/chromium/third_party/blink/renderer/core/frame/location.idl b/chromium/third_party/blink/renderer/core/frame/location.idl
index dd303cec87d..4ebab78e28f 100644
--- a/chromium/third_party/blink/renderer/core/frame/location.idl
+++ b/chromium/third_party/blink/renderer/core/frame/location.idl
@@ -63,5 +63,5 @@
// TODO(foolip): Location does not have a valueOf() override in the spec.
// See the comment in Location.h for the purpose of this.
- [NotEnumerable, CallWith=ThisValue, Unforgeable] any valueOf();
+ [DisableInNewIDLCompiler, NotEnumerable, CallWith=ThisValue, Unforgeable] any valueOf();
};
diff --git a/chromium/third_party/blink/renderer/core/frame/location_report_body.h b/chromium/third_party/blink/renderer/core/frame/location_report_body.h
index 208ea7b196f..c7f86ba18ed 100644
--- a/chromium/third_party/blink/renderer/core/frame/location_report_body.h
+++ b/chromium/third_party/blink/renderer/core/frame/location_report_body.h
@@ -20,10 +20,10 @@ class CORE_EXPORT LocationReportBody : public ReportBody {
: source_file_(location->Url()),
line_number_(location->IsUnknown()
? base::nullopt
- : base::Optional<uint32_t>{location->LineNumber()}),
- column_number_(location->IsUnknown() ? base::nullopt
- : base::Optional<uint32_t>{
- location->ColumnNumber()}) {}
+ : base::make_optional(location->LineNumber())),
+ column_number_(location->IsUnknown()
+ ? base::nullopt
+ : base::make_optional(location->ColumnNumber())) {}
LocationReportBody() : LocationReportBody(SourceLocation::Capture()) {}
@@ -36,14 +36,17 @@ class CORE_EXPORT LocationReportBody : public ReportBody {
~LocationReportBody() override = default;
- String sourceFile() const { return source_file_; }
+ const String& sourceFile() const { return source_file_; }
- uint32_t lineNumber(bool& is_null) const {
+ base::Optional<uint32_t> lineNumber() const { return line_number_; }
+ base::Optional<uint32_t> columnNumber() const { return column_number_; }
+
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ uint32_t lineNumber(bool& is_null) const { // DEPRECATED
is_null = !line_number_.has_value();
return line_number_.value_or(0);
}
-
- uint32_t columnNumber(bool& is_null) const {
+ uint32_t columnNumber(bool& is_null) const { // DEPRECATED
is_null = !column_number_.has_value();
return column_number_.value_or(0);
}
@@ -52,8 +55,8 @@ class CORE_EXPORT LocationReportBody : public ReportBody {
protected:
const String source_file_;
- base::Optional<uint32_t> line_number_;
- base::Optional<uint32_t> column_number_;
+ const base::Optional<uint32_t> line_number_;
+ const base::Optional<uint32_t> column_number_;
};
} // namespace blink
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 f1ccd5881a9..b73fafeae55 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
@@ -28,6 +28,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "base/bind_helpers.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/web_string.h"
@@ -76,9 +77,7 @@ class MHTMLLoadingTest : public testing::Test {
body_loader->Write(*buffer);
body_loader->Finish();
params->body_loader = std::move(body_loader);
- frame->CommitNavigation(
- std::move(params), nullptr /* extra_data */,
- base::DoNothing::Once() /* call_before_attaching_new_document */);
+ frame->CommitNavigation(std::move(params), nullptr /* extra_data */);
frame_test_helpers::PumpPendingRequestsForFrameToLoad(frame);
}
@@ -120,9 +119,10 @@ TEST_F(MHTMLLoadingTest, EnforceSandboxFlags) {
// Full sandboxing with the exception to new top-level windows should be
// turned on.
- EXPECT_EQ(WebSandboxFlags::kAll &
- ~(WebSandboxFlags::kPopups |
- WebSandboxFlags::kPropagatesToAuxiliaryBrowsingContexts),
+ EXPECT_EQ(mojom::blink::WebSandboxFlags::kAll &
+ ~(mojom::blink::WebSandboxFlags::kPopups |
+ mojom::blink::WebSandboxFlags::
+ kPropagatesToAuxiliaryBrowsingContexts),
document->GetSandboxFlags());
// MHTML document should be loaded into unique origin.
@@ -140,9 +140,10 @@ TEST_F(MHTMLLoadingTest, EnforceSandboxFlags) {
Document* child_document = child_frame->GetDocument();
ASSERT_TRUE(child_document);
- EXPECT_EQ(WebSandboxFlags::kAll &
- ~(WebSandboxFlags::kPopups |
- WebSandboxFlags::kPropagatesToAuxiliaryBrowsingContexts),
+ EXPECT_EQ(mojom::blink::WebSandboxFlags::kAll &
+ ~(mojom::blink::WebSandboxFlags::kPopups |
+ mojom::blink::WebSandboxFlags::
+ kPropagatesToAuxiliaryBrowsingContexts),
child_document->GetSandboxFlags());
// MHTML document should be loaded into unique origin.
@@ -166,9 +167,10 @@ TEST_F(MHTMLLoadingTest, EnforceSandboxFlagsInXSLT) {
// Full sandboxing with the exception to new top-level windows should be
// turned on.
- EXPECT_EQ(WebSandboxFlags::kAll &
- ~(WebSandboxFlags::kPopups |
- WebSandboxFlags::kPropagatesToAuxiliaryBrowsingContexts),
+ EXPECT_EQ(mojom::blink::WebSandboxFlags::kAll &
+ ~(mojom::blink::WebSandboxFlags::kPopups |
+ mojom::blink::WebSandboxFlags::
+ kPropagatesToAuxiliaryBrowsingContexts),
document->GetSandboxFlags());
// MHTML document should be loaded into unique origin.
@@ -213,7 +215,7 @@ TEST_F(MHTMLLoadingTest, FormControlElements) {
Document* document = frame->GetDocument();
ASSERT_TRUE(document);
- ClassCollection* formControlElements = document->getElementsByClassName("fc");
+ HTMLCollection* formControlElements = document->getElementsByClassName("fc");
ASSERT_TRUE(formControlElements);
for (Element* element : *formControlElements)
EXPECT_TRUE(element->IsDisabledFormControl());
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 e27564fc767..c46a968b9a4 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
@@ -7,6 +7,7 @@
#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/inspector/console_message.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
@@ -15,7 +16,7 @@ NavigationRateLimiter::NavigationRateLimiter(Frame& frame)
time_first_count_(base::TimeTicks::Now()),
enabled(frame_->GetSettings()->GetShouldProtectAgainstIpcFlooding()) {}
-void NavigationRateLimiter::Trace(blink::Visitor* visitor) {
+void NavigationRateLimiter::Trace(Visitor* visitor) {
visitor->Trace(frame_);
}
@@ -48,7 +49,7 @@ bool NavigationRateLimiter::CanProceed() {
if (!error_message_sent_) {
error_message_sent_ = true;
if (auto* local_frame = DynamicTo<LocalFrame>(frame_.Get())) {
- local_frame->Console().AddMessage(ConsoleMessage::Create(
+ local_frame->Console().AddMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning,
"Throttling navigation to prevent the browser from hanging. See "
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 0250fc245f7..41568264e30 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(blink::Visitor*);
+ void Trace(Visitor*);
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 6d0c3d3961d..f00fb00e14c 100644
--- a/chromium/third_party/blink/renderer/core/frame/navigator.cc
+++ b/chromium/third_party/blink/renderer/core/frame/navigator.cc
@@ -38,7 +38,8 @@
namespace blink {
Navigator::Navigator(LocalFrame* frame)
- : NavigatorLanguage(frame ? frame->GetDocument() : nullptr),
+ : NavigatorLanguage(frame ? frame->GetDocument()->ToExecutionContext()
+ : nullptr),
DOMWindowClient(frame) {}
String Navigator::productSub() const {
@@ -82,7 +83,12 @@ UserAgentMetadata Navigator::GetUserAgentMetadata() const {
if (!GetFrame() || !GetFrame()->GetPage())
return blink::UserAgentMetadata();
- return GetFrame()->Loader().UserAgentMetadata();
+ base::Optional<UserAgentMetadata> maybe_ua_metadata =
+ GetFrame()->Loader().UserAgentMetadata();
+ if (maybe_ua_metadata.has_value())
+ return maybe_ua_metadata.value();
+ else
+ return blink::UserAgentMetadata();
}
bool Navigator::cookieEnabled() const {
@@ -108,11 +114,18 @@ String Navigator::GetAcceptLanguages() {
return accept_languages;
}
-void Navigator::Trace(blink::Visitor* visitor) {
+void Navigator::Trace(Visitor* visitor) {
ScriptWrappable::Trace(visitor);
NavigatorLanguage::Trace(visitor);
DOMWindowClient::Trace(visitor);
Supplementable<Navigator>::Trace(visitor);
}
+ExecutionContext* Navigator::GetUAExecutionContext() const {
+ if (GetFrame() && GetFrame()->GetDocument()) {
+ return GetFrame()->GetDocument()->GetExecutionContext();
+ }
+ return nullptr;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/navigator.h b/chromium/third_party/blink/renderer/core/frame/navigator.h
index 4572df017cf..b01e1a2c6f0 100644
--- a/chromium/third_party/blink/renderer/core/frame/navigator.h
+++ b/chromium/third_party/blink/renderer/core/frame/navigator.h
@@ -22,13 +22,13 @@
#include "third_party/blink/public/common/user_agent/user_agent_metadata.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/frame/navigator_concurrent_hardware.h"
#include "third_party/blink/renderer/core/frame/navigator_device_memory.h"
#include "third_party/blink/renderer/core/frame/navigator_id.h"
#include "third_party/blink/renderer/core/frame/navigator_language.h"
#include "third_party/blink/renderer/core/frame/navigator_on_line.h"
-#include "third_party/blink/renderer/core/frame/navigator_user_agent.h"
+#include "third_party/blink/renderer/core/frame/navigator_ua.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"
@@ -44,7 +44,7 @@ class CORE_EXPORT Navigator final : public ScriptWrappable,
public NavigatorID,
public NavigatorLanguage,
public NavigatorOnLine,
- public NavigatorUserAgent,
+ public NavigatorUA,
public DOMWindowClient,
public Supplementable<Navigator> {
DEFINE_WRAPPERTYPEINFO();
@@ -69,7 +69,10 @@ class CORE_EXPORT Navigator final : public ScriptWrappable,
UserAgentMetadata GetUserAgentMetadata() const override;
void SetUserAgentMetadataForTesting(UserAgentMetadata);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
+
+ protected:
+ ExecutionContext* GetUAExecutionContext() const override;
private:
UserAgentMetadata metadata_;
diff --git a/chromium/third_party/blink/renderer/core/frame/navigator.idl b/chromium/third_party/blink/renderer/core/frame/navigator.idl
index f13febb148e..9a1f030202f 100644
--- a/chromium/third_party/blink/renderer/core/frame/navigator.idl
+++ b/chromium/third_party/blink/renderer/core/frame/navigator.idl
@@ -41,4 +41,4 @@ Navigator includes NavigatorID;
Navigator includes NavigatorLanguage;
Navigator includes NavigatorOnLine;
Navigator includes NavigatorAutomationInformation;
-Navigator includes NavigatorUserAgent;
+Navigator includes NavigatorUA;
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 863d2d2a3b0..061e738dfb9 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(blink::Visitor* visitor) {
+void NavigatorLanguage::Trace(Visitor* visitor) {
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 86e1e6e7b23..f122170940b 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 3ca2c271fae..84f746ac71b 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(blink::Visitor* visitor) {
+void NavigatorScheduling::Trace(Visitor* visitor) {
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 90e39bc8d2a..ac4caf75fb3 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
static NavigatorScheduling& From(Navigator&);
diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_ua.cc b/chromium/third_party/blink/renderer/core/frame/navigator_ua.cc
new file mode 100644
index 00000000000..09d4cd858c3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/navigator_ua.cc
@@ -0,0 +1,26 @@
+// 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/frame/navigator_ua.h"
+
+namespace blink {
+
+NavigatorUAData* NavigatorUA::userAgentData() {
+ NavigatorUAData* ua_data =
+ MakeGarbageCollected<NavigatorUAData>(GetUAExecutionContext());
+
+ UserAgentMetadata metadata = GetUserAgentMetadata();
+ ua_data->AddBrand(String::FromUTF8(metadata.brand),
+ String::FromUTF8(metadata.major_version));
+ ua_data->SetMobile(metadata.mobile);
+ ua_data->SetPlatform(String::FromUTF8(metadata.platform),
+ String::FromUTF8(metadata.platform_version));
+ ua_data->SetArchitecture(String::FromUTF8(metadata.architecture));
+ ua_data->SetModel(String::FromUTF8(metadata.model));
+ ua_data->SetUAFullVersion(String::FromUTF8(metadata.full_version));
+
+ return ua_data;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_user_agent.h b/chromium/third_party/blink/renderer/core/frame/navigator_ua.h
index def5dda212e..17dbc9dfcb1 100644
--- a/chromium/third_party/blink/renderer/core/frame/navigator_user_agent.h
+++ b/chromium/third_party/blink/renderer/core/frame/navigator_ua.h
@@ -2,24 +2,25 @@
// 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_NAVIGATOR_USER_AGENT_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATOR_USER_AGENT_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATOR_UA_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATOR_UA_H_
#include "third_party/blink/public/common/user_agent/user_agent_metadata.h"
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/frame/navigator_ua_data.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
-class ScriptPromise;
-class ScriptState;
-class CORE_EXPORT NavigatorUserAgent {
+class CORE_EXPORT NavigatorUA {
public:
- ScriptPromise getUserAgent(ScriptState*);
+ NavigatorUAData* userAgentData();
+ protected:
virtual UserAgentMetadata GetUserAgentMetadata() const = 0;
+ virtual ExecutionContext* GetUAExecutionContext() const = 0;
};
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATOR_USER_AGENT_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATOR_UA_H_
diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_user_agent.idl b/chromium/third_party/blink/renderer/core/frame/navigator_ua.idl
index a7bbe071b5d..1b2360ca4b8 100644
--- a/chromium/third_party/blink/renderer/core/frame/navigator_user_agent.idl
+++ b/chromium/third_party/blink/renderer/core/frame/navigator_ua.idl
@@ -5,8 +5,7 @@
// https://github.com/WICG/ua-client-hints
[
- RuntimeEnabled=UserAgentClientHint,
- Exposed=Window
-] interface mixin NavigatorUserAgent {
- [SecureContext, CallWith=ScriptState] Promise<UserAgent> getUserAgent();
+ RuntimeEnabled=UserAgentClientHint
+] interface mixin NavigatorUA {
+ [SecureContext] readonly attribute NavigatorUAData userAgentData;
};
diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_ua_brand_version.idl b/chromium/third_party/blink/renderer/core/frame/navigator_ua_brand_version.idl
new file mode 100644
index 00000000000..f19769b5d3d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/navigator_ua_brand_version.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/ua-client-hints
+
+dictionary NavigatorUABrandVersion {
+ DOMString brand;
+ DOMString version;
+};
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
new file mode 100644
index 00000000000..c0c00cbc876
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/navigator_ua_data.cc
@@ -0,0 +1,94 @@
+// 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/navigator_ua_data.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_ua_data_values.h"
+#include "third_party/blink/renderer/core/page/page.h"
+
+namespace blink {
+
+NavigatorUAData::NavigatorUAData(ExecutionContext* context)
+ : ExecutionContextClient(context) {
+ NavigatorUABrandVersion* dict = NavigatorUABrandVersion::Create();
+ dict->setBrand("");
+ dict->setVersion("");
+ empty_brand_set_.push_back(dict);
+}
+
+void NavigatorUAData::AddBrand(const String& brand, const String& version) {
+ NavigatorUABrandVersion* dict = NavigatorUABrandVersion::Create();
+ dict->setBrand(brand);
+ dict->setVersion(version);
+ brand_set_.push_back(dict);
+}
+
+void NavigatorUAData::SetMobile(bool mobile) {
+ is_mobile_ = mobile;
+}
+
+void NavigatorUAData::SetPlatform(const String& brand, const String& version) {
+ platform_ = brand;
+ platform_version_ = version;
+}
+
+void NavigatorUAData::SetArchitecture(const String& architecture) {
+ architecture_ = architecture;
+}
+
+void NavigatorUAData::SetModel(const String& model) {
+ model_ = model;
+}
+
+void NavigatorUAData::SetUAFullVersion(const String& ua_full_version) {
+ ua_full_version_ = ua_full_version;
+}
+
+bool NavigatorUAData::mobile() const {
+ if (GetExecutionContext()) {
+ return is_mobile_;
+ }
+ return false;
+}
+
+const HeapVector<Member<NavigatorUABrandVersion>>& NavigatorUAData::uaList()
+ const {
+ if (GetExecutionContext()) {
+ return brand_set_;
+ }
+ return empty_brand_set_;
+}
+
+ScriptPromise NavigatorUAData::getHighEntropyValues(
+ ScriptState* script_state,
+ Vector<String>& hints) const {
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ ScriptPromise promise = resolver->Promise();
+ UADataValues* values = MakeGarbageCollected<UADataValues>();
+ for (const String& hint : hints) {
+ if (hint == "platform") {
+ values->setPlatform(platform_);
+ } else if (hint == "platformVersion") {
+ values->setPlatformVersion(platform_version_);
+ } else if (hint == "architecture") {
+ values->setArchitecture(architecture_);
+ } else if (hint == "model") {
+ values->setModel(model_);
+ } else if (hint == "uaFullVersion") {
+ values->setUaFullVersion(ua_full_version_);
+ }
+ }
+ resolver->Resolve(values);
+ return promise;
+}
+
+void NavigatorUAData::Trace(Visitor* visitor) {
+ visitor->Trace(brand_set_);
+ visitor->Trace(empty_brand_set_);
+ ScriptWrappable::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..49e69793312
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/navigator_ua_data.h
@@ -0,0 +1,56 @@
+// 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_NAVIGATOR_UA_DATA_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATOR_UA_DATA_H_
+
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_navigator_ua_brand_version.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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 ScriptState;
+
+class NavigatorUAData : public ScriptWrappable, ExecutionContextClient {
+ DEFINE_WRAPPERTYPEINFO();
+ USING_GARBAGE_COLLECTED_MIXIN(NavigatorUAData);
+
+ public:
+ static NavigatorUAData* Create(ExecutionContext* context) {
+ return MakeGarbageCollected<NavigatorUAData>(context);
+ }
+
+ explicit NavigatorUAData(ExecutionContext* context);
+
+ void AddBrand(const String& brand, const String& version);
+ void SetMobile(bool mobile);
+ void SetPlatform(const String& brand, const String& version);
+ void SetArchitecture(const String& architecture);
+ void SetModel(const String& model);
+ void SetUAFullVersion(const String& uaFullVersion);
+
+ // IDL implementation
+ const HeapVector<Member<NavigatorUABrandVersion>>& uaList() const;
+ bool mobile() const;
+ ScriptPromise getHighEntropyValues(ScriptState*, Vector<String>&) const;
+
+ void Trace(Visitor* visitor) final;
+
+ private:
+ HeapVector<Member<NavigatorUABrandVersion>> brand_set_;
+ HeapVector<Member<NavigatorUABrandVersion>> empty_brand_set_;
+ bool is_mobile_ = false;
+ String platform_;
+ String platform_version_;
+ String architecture_;
+ String model_;
+ String ua_full_version_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATOR_UA_DATA_H_
diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_ua_data.idl b/chromium/third_party/blink/renderer/core/frame/navigator_ua_data.idl
new file mode 100644
index 00000000000..5e0e6a10f20
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/navigator_ua_data.idl
@@ -0,0 +1,14 @@
+// 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/ua-client-hints
+
+[
+ RuntimeEnabled=UserAgentClientHint,
+ Exposed=(Window,Worker)
+] interface NavigatorUAData {
+ readonly attribute FrozenArray<NavigatorUABrandVersion> uaList;
+ readonly attribute boolean mobile;
+ [CallWith=ScriptState] Promise<UADataValues> getHighEntropyValues(sequence<DOMString> hints);
+};
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 681807ab8d1..6d62537d078 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(blink::Visitor* visitor) {
+void NavigatorUserActivation::Trace(Visitor* visitor) {
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 0baeffb2ca9..229091242b6 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
static NavigatorUserActivation& From(Navigator&);
diff --git a/chromium/third_party/blink/renderer/core/frame/navigator_user_agent.cc b/chromium/third_party/blink/renderer/core/frame/navigator_user_agent.cc
deleted file mode 100644
index 28b939f7f2f..00000000000
--- a/chromium/third_party/blink/renderer/core/frame/navigator_user_agent.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/frame/navigator_user_agent.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/frame/user_agent.h"
-
-namespace blink {
-
-ScriptPromise NavigatorUserAgent::getUserAgent(ScriptState* script_state) {
- auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
- ScriptPromise promise = resolver->Promise();
-
- blink::UserAgentMetadata metadata = GetUserAgentMetadata();
- blink::UserAgent* idl_metadata = blink::UserAgent::Create();
-
- idl_metadata->setBrand(String::FromUTF8(metadata.brand));
- idl_metadata->setVersion(String::FromUTF8(metadata.full_version));
- idl_metadata->setPlatform(String::FromUTF8(metadata.platform));
- idl_metadata->setArchitecture(String::FromUTF8(metadata.architecture));
- idl_metadata->setModel(String::FromUTF8(metadata.model));
- resolver->Resolve(idl_metadata);
-
- return promise;
-}
-
-} // namespace blink
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
new file mode 100644
index 00000000000..3c699046130
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/overlay_interstitial_ad_detector.cc
@@ -0,0 +1,109 @@
+// 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/overlay_interstitial_ad_detector.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/scroll/scrollable_area.h"
+
+namespace blink {
+
+namespace {
+
+constexpr base::TimeDelta kFireInterval = base::TimeDelta::FromSeconds(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) {
+ 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.
+ if (style->HasViewportConstrainedPosition() ||
+ style->HasStickyConstrainedPosition()) {
+ return true;
+ }
+
+ if (style->GetPosition() == EPosition::kAbsolute)
+ return !object->StyleRef().ScrollsOverflow();
+
+ return false;
+}
+
+bool IsInterstitialAd(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_)
+ return;
+
+ DCHECK(main_frame->GetDocument());
+ DCHECK(main_frame->ContentLayoutObject());
+
+ base::Time current_time = base::Time::Now();
+ if (!last_detection_time_.has_value() ||
+ current_time - last_detection_time_.value() >= kFireInterval) {
+ IntSize main_frame_size =
+ main_frame->View()->GetScrollableArea()->VisibleContentRect().Size();
+ 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 && IsInterstitialAd(element)) {
+ UseCounter::Count(main_frame->GetDocument(),
+ WebFeature::kOverlayInterstitialAd);
+ done_detection_ = true;
+ }
+ last_detection_time_ = current_time;
+ }
+}
+
+} // 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
new file mode 100644
index 00000000000..eb81875e614
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/overlay_interstitial_ad_detector.h
@@ -0,0 +1,32 @@
+// 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_OVERLAY_INTERSTITIAL_AD_DETECTOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_OVERLAY_INTERSTITIAL_AD_DETECTOR_H_
+
+#include "base/optional.h"
+#include "base/time/time.h"
+#include "third_party/blink/renderer/core/core_export.h"
+
+namespace blink {
+
+class LocalFrame;
+
+class CORE_EXPORT OverlayInterstitialAdDetector {
+ public:
+ OverlayInterstitialAdDetector() = default;
+ ~OverlayInterstitialAdDetector() = default;
+
+ void MaybeFireDetection(LocalFrame* main_frame);
+
+ private:
+ base::Optional<base::Time> last_detection_time_;
+ bool done_detection_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(OverlayInterstitialAdDetector);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_OVERLAY_INTERSTITIAL_AD_DETECTOR_H_
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 55ba414bb37..4f303ba6317 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(blink::Visitor* visitor) {
+void PageScaleConstraintsSet::Trace(Visitor* visitor) {
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 d80144cba13..641e88a1ec6 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(blink::Visitor*);
+ void Trace(Visitor*);
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 d1efb2c0d0b..a95f9754017 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
@@ -14,11 +14,12 @@
#include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_persistent_value_vector.h"
#include "third_party/blink/renderer/bindings/core/v8/window_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/bindings/trace_wrapper_v8_reference.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/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -34,7 +35,7 @@ class WebScriptExecutor : public PausableScriptExecutor::Executor {
Vector<v8::Local<v8::Value>> Execute(LocalFrame*) override;
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(sources_);
PausableScriptExecutor::Executor::Trace(visitor);
}
@@ -88,7 +89,7 @@ class V8FunctionExecutor : public PausableScriptExecutor::Executor {
private:
TraceWrapperV8Reference<v8::Function> function_;
TraceWrapperV8Reference<v8::Value> receiver_;
- V8PersistentValueVector<v8::Value> args_;
+ HeapVector<TraceWrapperV8Reference<v8::Value>> args_;
};
V8FunctionExecutor::V8FunctionExecutor(v8::Isolate* isolate,
@@ -96,26 +97,25 @@ V8FunctionExecutor::V8FunctionExecutor(v8::Isolate* isolate,
v8::Local<v8::Value> receiver,
int argc,
v8::Local<v8::Value> argv[])
- : function_(isolate, function),
- receiver_(isolate, receiver),
- args_(isolate) {
- args_.ReserveCapacity(argc);
+ : function_(isolate, function), receiver_(isolate, receiver) {
+ args_.ReserveCapacity(SafeCast<wtf_size_t>(argc));
for (int i = 0; i < argc; ++i)
- args_.Append(argv[i]);
+ args_.push_back(TraceWrapperV8Reference<v8::Value>(isolate, argv[i]));
}
Vector<v8::Local<v8::Value>> V8FunctionExecutor::Execute(LocalFrame* frame) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
Vector<v8::Local<v8::Value>> results;
v8::Local<v8::Value> single_result;
+
Vector<v8::Local<v8::Value>> args;
- wtf_size_t args_size = SafeCast<wtf_size_t>(args_.Size());
- args.ReserveCapacity(args_size);
- for (wtf_size_t i = 0; i < args_size; ++i)
- args.push_back(args_.Get(i));
+ args.ReserveCapacity(args_.size());
+ for (wtf_size_t i = 0; i < args_.size(); ++i)
+ args.push_back(args_[i].NewLocal(isolate));
+
{
if (V8ScriptRunner::CallFunction(function_.NewLocal(isolate),
- frame->GetDocument(),
+ frame->GetDocument()->ToExecutionContext(),
receiver_.NewLocal(isolate), args.size(),
args.data(), ToIsolate(frame))
.ToLocal(&single_result))
@@ -127,6 +127,7 @@ Vector<v8::Local<v8::Value>> V8FunctionExecutor::Execute(LocalFrame* frame) {
void V8FunctionExecutor::Trace(Visitor* visitor) {
visitor->Trace(function_);
visitor->Trace(receiver_);
+ visitor->Trace(args_);
PausableScriptExecutor::Executor::Trace(visitor);
}
@@ -155,10 +156,7 @@ void PausableScriptExecutor::CreateAndRun(
executor->Run();
}
-void PausableScriptExecutor::ContextDestroyed(
- ExecutionContext* destroyed_context) {
- ContextLifecycleObserver::ContextDestroyed(destroyed_context);
-
+void PausableScriptExecutor::ContextDestroyed() {
if (callback_) {
// Though the context is (about to be) destroyed, the callback is invoked
// with a vector of v8::Local<>s, which implies that creating v8::Locals
@@ -189,7 +187,7 @@ PausableScriptExecutor::PausableScriptExecutor(
ScriptState* script_state,
WebScriptExecutionCallback* callback,
Executor* executor)
- : ContextLifecycleObserver(frame->GetDocument()),
+ : ExecutionContextLifecycleObserver(frame->GetDocument()),
script_state_(script_state),
callback_(callback),
blocking_option_(kNonBlocking),
@@ -218,7 +216,7 @@ void PausableScriptExecutor::RunAsync(BlockingOption blocking) {
DCHECK(context);
blocking_option_ = blocking;
if (blocking_option_ == kOnloadBlocking)
- To<Document>(GetExecutionContext())->IncrementLoadEventDelayCount();
+ Document::From(GetExecutionContext())->IncrementLoadEventDelayCount();
task_handle_ = PostCancellableTask(
*context->GetTaskRunner(TaskType::kJavascriptTimer), FROM_HERE,
@@ -234,7 +232,7 @@ void PausableScriptExecutor::ExecuteAndDestroySelf() {
ScriptState::Scope script_scope(script_state_);
Vector<v8::Local<v8::Value>> results =
- executor_->Execute(To<Document>(GetExecutionContext())->GetFrame());
+ executor_->Execute(Document::From(GetExecutionContext())->GetFrame());
// The script may have removed the frame, in which case contextDestroyed()
// will have handled the disposal/callback.
@@ -242,7 +240,7 @@ void PausableScriptExecutor::ExecuteAndDestroySelf() {
return;
if (blocking_option_ == kOnloadBlocking)
- To<Document>(GetExecutionContext())->DecrementLoadEventDelayCount();
+ Document::From(GetExecutionContext())->DecrementLoadEventDelayCount();
if (callback_)
callback_->Completed(results);
@@ -251,15 +249,21 @@ void PausableScriptExecutor::ExecuteAndDestroySelf() {
}
void PausableScriptExecutor::Dispose() {
- // Remove object as a ContextLifecycleObserver.
- ContextLifecycleObserver::ClearContext();
+ // Remove object as a ExecutionContextLifecycleObserver.
+ // TODO(keishi): Remove IsIteratingOverObservers() check when
+ // HeapObserverList() supports removal while iterating.
+ if (!GetExecutionContext()
+ ->ContextLifecycleObserverList()
+ .IsIteratingOverObservers()) {
+ SetExecutionContext(nullptr);
+ }
task_handle_.Cancel();
}
-void PausableScriptExecutor::Trace(blink::Visitor* visitor) {
+void PausableScriptExecutor::Trace(Visitor* visitor) {
visitor->Trace(script_state_);
visitor->Trace(executor_);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 59374a677fd..6c3444de353 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
@@ -7,7 +7,7 @@
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
@@ -23,7 +23,7 @@ class WebScriptExecutionCallback;
class CORE_EXPORT PausableScriptExecutor final
: public GarbageCollected<PausableScriptExecutor>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(PausableScriptExecutor);
public:
@@ -44,7 +44,7 @@ class CORE_EXPORT PausableScriptExecutor final
virtual Vector<v8::Local<v8::Value>> Execute(LocalFrame*) = 0;
- virtual void Trace(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
};
PausableScriptExecutor(LocalFrame*,
@@ -60,9 +60,9 @@ class CORE_EXPORT PausableScriptExecutor final
void Run();
void RunAsync(BlockingOption);
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 2d599718a21..26ae7e33046 100644
--- a/chromium/third_party/blink/renderer/core/frame/performance_monitor.cc
+++ b/chromium/third_party/blink/renderer/core/frame/performance_monitor.cc
@@ -17,7 +17,6 @@
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/parser/html_document_parser.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
namespace blink {
@@ -53,7 +52,7 @@ void PerformanceMonitor::ReportGenericViolation(
// static
PerformanceMonitor* PerformanceMonitor::Monitor(
const ExecutionContext* context) {
- const auto* document = DynamicTo<Document>(context);
+ const auto* document = Document::DynamicFrom(context);
if (!document)
return nullptr;
LocalFrame* frame = document->GetFrame();
@@ -149,7 +148,7 @@ void PerformanceMonitor::DidExecuteScript() {
void PerformanceMonitor::UpdateTaskAttribution(ExecutionContext* context) {
// If |context| is not a document, unable to attribute a frame context.
- auto* document = DynamicTo<Document>(context);
+ auto* document = Document::DynamicFrom(context);
if (!document)
return;
@@ -264,8 +263,8 @@ void PerformanceMonitor::DocumentWriteFetchScript(Document* document) {
if (!enabled_)
return;
String text = "Parser was blocked due to document.write(<script>)";
- InnerReportGenericViolation(document, kBlockedParser, text, base::TimeDelta(),
- nullptr);
+ InnerReportGenericViolation(document->ToExecutionContext(), kBlockedParser,
+ text, base::TimeDelta(), nullptr);
}
void PerformanceMonitor::WillProcessTask(base::TimeTicks start_time) {
@@ -342,7 +341,7 @@ void PerformanceMonitor::InnerReportGenericViolation(
}
}
-void PerformanceMonitor::Trace(blink::Visitor* visitor) {
+void PerformanceMonitor::Trace(Visitor* visitor) {
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 be66da93d77..eadc7cf8495 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(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) override {}
};
static void ReportGenericViolation(ExecutionContext*,
@@ -104,7 +104,7 @@ class CORE_EXPORT PerformanceMonitor final
explicit PerformanceMonitor(LocalFrame*);
~PerformanceMonitor() override;
- virtual void Trace(blink::Visitor*);
+ virtual void Trace(Visitor*);
private:
friend class PerformanceMonitorTest;
diff --git a/chromium/third_party/blink/renderer/core/frame/performance_monitor_test.cc b/chromium/third_party/blink/renderer/core/frame/performance_monitor_test.cc
index 692c8ddcec7..349beab1d42 100644
--- a/chromium/third_party/blink/renderer/core/frame/performance_monitor_test.cc
+++ b/chromium/third_party/blink/renderer/core/frame/performance_monitor_test.cc
@@ -25,13 +25,13 @@ class PerformanceMonitorTest : public testing::Test {
return page_holder_->GetDocument().GetFrame();
}
ExecutionContext* GetExecutionContext() const {
- return &page_holder_->GetDocument();
+ return page_holder_->GetDocument().ToExecutionContext();
}
LocalFrame* AnotherFrame() const {
return another_page_holder_->GetDocument().GetFrame();
}
ExecutionContext* AnotherExecutionContext() const {
- return &another_page_holder_->GetDocument();
+ return another_page_holder_->GetDocument().ToExecutionContext();
}
void WillExecuteScript(ExecutionContext* execution_context) {
@@ -91,7 +91,7 @@ String PerformanceMonitorTest::FrameContextURL() {
// This is reported only if there is a single frameContext URL.
if (monitor_->task_has_multiple_contexts_)
return g_empty_string;
- return To<Document>(monitor_->task_execution_context_.Get())
+ return Document::From(monitor_->task_execution_context_.Get())
->location()
->toString();
}
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 a509a164f63..71bcdc95faa 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(blink::Visitor* visitor) {
+void PictureInPictureController::Trace(Visitor* visitor) {
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 ff0e9a50e02..152a0eaa218 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 aa45285528c..18273936e12 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(blink::Visitor* visitor) {
+void PlatformEventController::Trace(Visitor* visitor) {
visitor->Trace(document_);
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 ff31b860783..078167cf7ce 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
@@ -14,6 +14,8 @@
namespace blink {
+class Document;
+
// Base controller class for registering controllers with a dispatcher.
// It watches page visibility and calls stopUpdating when page is not visible.
// It provides a DidUpdateData() callback method which is called when new data
@@ -26,7 +28,7 @@ class CORE_EXPORT PlatformEventController : public PageVisibilityObserver {
// This is called when new data becomes available.
virtual void DidUpdateData() = 0;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
Document* GetDocument() const { return document_; }
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 56b20b19396..a84604b4dd9 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(blink::Visitor* visitor) {
+void PlatformEventDispatcher::Trace(Visitor* visitor) {
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 2f1aa2645c5..0cff75e29ee 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 c79897bd768..22123570212 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
@@ -17,7 +17,7 @@ ExecutionContext* RemoteDOMWindow::GetExecutionContext() const {
return nullptr;
}
-void RemoteDOMWindow::Trace(blink::Visitor* visitor) {
+void RemoteDOMWindow::Trace(Visitor* visitor) {
DOMWindow::Trace(visitor);
}
@@ -61,8 +61,11 @@ void RemoteDOMWindow::ForwardPostMessage(
if (!GetFrame())
return;
+ base::Optional<base::UnguessableToken> agent_cluster;
+ if (event->IsLockedToAgentCluster())
+ agent_cluster = source->GetExecutionContext()->GetAgentClusterID();
GetFrame()->Client()->ForwardPostMessage(event, std::move(target),
- source->GetFrame());
+ agent_cluster, 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 ad0435e84e6..a88ca19aedd 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void blur() override;
void FrameDetached();
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 54f36de829d..04c16e3882d 100644
--- a/chromium/third_party/blink/renderer/core/frame/remote_frame.cc
+++ b/chromium/third_party/blink/renderer/core/frame/remote_frame.cc
@@ -6,19 +6,29 @@
#include "cc/layers/surface_layer.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
+#include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom-blink.h"
+#include "third_party/blink/public/mojom/frame/intrinsic_sizing_info.mojom-blink.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
#include "third_party/blink/public/platform/interface_registry.h"
+#include "third_party/blink/public/web/web_frame.h"
+#include "third_party/blink/public/web/web_view.h"
+#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/frame/csp/content_security_policy.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/remote_dom_window.h"
#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/fullscreen/fullscreen.h"
-#include "third_party/blink/renderer/core/fullscreen/fullscreen_options.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/layout/geometry/physical_rect.h"
+#include "third_party/blink/renderer/core/layout/intrinsic_sizing_info.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/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"
@@ -26,6 +36,7 @@
#include "third_party/blink/renderer/core/page/plugin_script_forbidden_scope.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
+#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object.h"
@@ -37,6 +48,16 @@
namespace blink {
+namespace {
+FloatRect DeNormalizeRect(const gfx::RectF& normalized, const IntRect& base) {
+ FloatRect result(normalized);
+ result.Scale(base.Width(), base.Height());
+ result.MoveBy(FloatPoint(base.Location()));
+ return result;
+}
+
+} // namespace
+
RemoteFrame::RemoteFrame(
RemoteFrameClient* client,
Page& page,
@@ -48,8 +69,7 @@ RemoteFrame::RemoteFrame(
page,
owner,
MakeGarbageCollected<RemoteWindowProxyManager>(*this),
- inheriting_agent_factory),
- security_context_(MakeGarbageCollected<RemoteSecurityContext>()) {
+ inheriting_agent_factory) {
dom_window_ = MakeGarbageCollected<RemoteDOMWindow>(*this);
interface_registry->AddAssociatedInterface(WTF::BindRepeating(
@@ -68,29 +88,29 @@ RemoteFrame::~RemoteFrame() {
DCHECK(!view_);
}
-void RemoteFrame::Trace(blink::Visitor* visitor) {
+void RemoteFrame::Trace(Visitor* visitor) {
visitor->Trace(view_);
visitor->Trace(security_context_);
Frame::Trace(visitor);
}
-void RemoteFrame::Navigate(const FrameLoadRequest& passed_request,
+void RemoteFrame::Navigate(FrameLoadRequest& frame_request,
WebFrameLoadType frame_load_type) {
if (!navigation_rate_limiter().CanProceed())
return;
- FrameLoadRequest frame_request(passed_request);
- frame_request.SetFrameType(
- IsMainFrame() ? network::mojom::RequestContextFrameType::kTopLevel
- : network::mojom::RequestContextFrameType::kNested);
+ frame_request.SetFrameType(IsMainFrame()
+ ? mojom::RequestContextFrameType::kTopLevel
+ : mojom::RequestContextFrameType::kNested);
const KURL& url = frame_request.GetResourceRequest().Url();
if (!frame_request.CanDisplay(url)) {
if (frame_request.OriginDocument()) {
- frame_request.OriginDocument()->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kError,
- "Not allowed to load local resource: " + url.ElidedString()));
+ frame_request.OriginDocument()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kSecurity,
+ mojom::ConsoleMessageLevel::kError,
+ "Not allowed to load local resource: " + url.ElidedString()));
}
return;
}
@@ -110,9 +130,18 @@ void RemoteFrame::Navigate(const FrameLoadRequest& passed_request,
: nullptr;
MixedContentChecker::UpgradeInsecureRequest(
frame_request.GetResourceRequest(), fetch_client_settings_object,
- frame_request.OriginDocument(), frame_request.GetFrameType(),
+ frame_request.OriginDocument()
+ ? frame_request.OriginDocument()->ToExecutionContext()
+ : nullptr,
+ frame_request.GetFrameType(),
frame ? frame->GetContentSettingsClient() : nullptr);
+ // Navigations in portal contexts do not create back/forward entries.
+ if (GetPage()->InsidePortal() &&
+ frame_load_type == WebFrameLoadType::kStandard) {
+ frame_load_type = WebFrameLoadType::kReplaceCurrentItem;
+ }
+
bool is_opener_navigation = false;
bool initiator_frame_has_download_sandbox_flag = false;
bool initiator_frame_is_ad = false;
@@ -121,24 +150,19 @@ void RemoteFrame::Navigate(const FrameLoadRequest& passed_request,
is_opener_navigation = frame->Client()->Opener() == this;
initiator_frame_has_download_sandbox_flag =
frame->GetSecurityContext() &&
- frame->GetSecurityContext()->IsSandboxed(WebSandboxFlags::kDownloads);
+ frame->GetSecurityContext()->IsSandboxed(
+ mojom::blink::WebSandboxFlags::kDownloads);
initiator_frame_is_ad = frame->IsAdSubframe();
- if (passed_request.ClientRedirectReason() !=
- ClientNavigationReason::kNone) {
+ if (frame_request.ClientRedirectReason() != ClientNavigationReason::kNone) {
probe::FrameRequestedNavigation(frame, this, url,
- passed_request.ClientRedirectReason());
+ frame_request.ClientRedirectReason());
}
}
- bool current_frame_has_download_sandbox_flag =
- GetSecurityContext() &&
- GetSecurityContext()->IsSandboxed(WebSandboxFlags::kDownloads);
- bool has_download_sandbox_flag = initiator_frame_has_download_sandbox_flag ||
- current_frame_has_download_sandbox_flag;
-
Client()->Navigate(frame_request.GetResourceRequest(),
frame_load_type == WebFrameLoadType::kReplaceCurrentItem,
- is_opener_navigation, has_download_sandbox_flag,
+ is_opener_navigation,
+ initiator_frame_has_download_sandbox_flag,
initiator_frame_is_ad, frame_request.GetBlobURLToken());
}
@@ -172,11 +196,11 @@ bool RemoteFrame::DetachDocument() {
void RemoteFrame::CheckCompleted() {
// Notify the client so that the corresponding LocalFrame can do the check.
- Client()->CheckCompleted();
+ GetRemoteFrameHostRemote().CheckCompleted();
}
-RemoteSecurityContext* RemoteFrame::GetSecurityContext() const {
- return security_context_.Get();
+const RemoteSecurityContext* RemoteFrame::GetSecurityContext() const {
+ return &security_context_;
}
bool RemoteFrame::ShouldClose() {
@@ -187,7 +211,7 @@ bool RemoteFrame::ShouldClose() {
void RemoteFrame::SetIsInert(bool inert) {
if (inert != is_inert_)
- Client()->SetIsInert(inert);
+ GetRemoteFrameHostRemote().SetIsInert(inert);
is_inert_ = inert;
}
@@ -198,15 +222,53 @@ void RemoteFrame::SetInheritedEffectiveTouchAction(TouchAction touch_action) {
}
bool RemoteFrame::BubbleLogicalScrollFromChildFrame(
- ScrollDirection direction,
+ mojom::blink::ScrollDirection direction,
ScrollGranularity granularity,
Frame* child) {
DCHECK(child->Client());
- To<LocalFrame>(child)->Client()->BubbleLogicalScrollInParentFrame(
- direction, granularity);
+ To<LocalFrame>(child)
+ ->GetLocalFrameHostRemote()
+ .BubbleLogicalScrollInParentFrame(direction, granularity);
return false;
}
+void RemoteFrame::RenderFallbackContent() {
+ // TODO(ekaramad): If the owner renders its own content, then the current
+ // ContentFrame() should detach and free-up the OOPIF process (see
+ // https://crbug.com/850223).
+ auto* owner = DeprecatedLocalOwner();
+ DCHECK(IsA<HTMLObjectElement>(owner));
+ owner->RenderFallbackContent(this);
+}
+
+void RemoteFrame::AddResourceTimingFromChild(
+ mojom::blink::ResourceTimingInfoPtr timing) {
+ HTMLFrameOwnerElement* owner_element = To<HTMLFrameOwnerElement>(Owner());
+ DCHECK(owner_element);
+
+ // TODO(https://crbug.com/900700): Take a Mojo pending receiver for
+ // 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());
+}
+
+void RemoteFrame::DidStartLoading() {
+ SetIsLoading(true);
+}
+
+void RemoteFrame::DidStopLoading() {
+ SetIsLoading(false);
+
+ // When a subframe finishes loading, the parent should check if *all*
+ // subframes have finished loading (which may mean that the parent can declare
+ // that the parent itself has finished loading). This remote-subframe-focused
+ // code has a local-subframe equivalent in FrameLoader::DidFinishNavigation.
+ Frame* parent = Tree().Parent();
+ if (parent)
+ parent->CheckCompleted();
+}
+
void RemoteFrame::DidFocus() {
GetRemoteFrameHostRemote().DidFocusFrame();
}
@@ -260,6 +322,20 @@ void RemoteFrame::SetReplicatedFeaturePolicyHeaderAndOpenerPolicies(
ApplyReplicatedFeaturePolicyHeader();
}
+void RemoteFrame::SetReplicatedSandboxFlags(
+ mojom::blink::WebSandboxFlags flags) {
+ security_context_.ResetAndEnforceSandboxFlags(flags);
+}
+
+void RemoteFrame::SetInsecureRequestPolicy(
+ mojom::blink::InsecureRequestPolicy policy) {
+ security_context_.SetInsecureRequestPolicy(policy);
+}
+
+void RemoteFrame::SetInsecureNavigationsSet(const WebVector<unsigned>& set) {
+ security_context_.SetInsecureNavigationsSet(set);
+}
+
void RemoteFrame::WillEnterFullscreen() {
// This should only ever be called when the FrameOwner is local.
HTMLFrameOwnerElement* owner_element = To<HTMLFrameOwnerElement>(Owner());
@@ -281,13 +357,32 @@ void RemoteFrame::WillEnterFullscreen() {
Fullscreen::RequestType::kPrefixedForCrossProcessDescendant);
}
+void RemoteFrame::AddReplicatedContentSecurityPolicies(
+ WTF::Vector<network::mojom::blink::ContentSecurityPolicyHeaderPtr>
+ headers) {
+ for (auto& header : headers) {
+ GetSecurityContext()->GetContentSecurityPolicy()->AddPolicyFromHeaderValue(
+ header->header_value, header->type, header->source);
+ }
+}
+
void RemoteFrame::ResetReplicatedContentSecurityPolicy() {
- GetSecurityContext()->ResetReplicatedContentSecurityPolicy();
+ security_context_.ResetReplicatedContentSecurityPolicy();
}
void RemoteFrame::EnforceInsecureNavigationsSet(
const WTF::Vector<uint32_t>& set) {
- GetSecurityContext()->SetInsecureNavigationsSet(set);
+ security_context_.SetInsecureNavigationsSet(set);
+}
+
+void RemoteFrame::SetFrameOwnerProperties(
+ mojom::blink::FrameOwnerPropertiesPtr properties) {
+ Frame::ApplyFrameOwnerProperties(std::move(properties));
+}
+
+void RemoteFrame::EnforceInsecureRequestPolicy(
+ mojom::blink::InsecureRequestPolicy policy) {
+ SetInsecureRequestPolicy(policy);
}
void RemoteFrame::SetReplicatedOrigin(
@@ -296,7 +391,7 @@ void RemoteFrame::SetReplicatedOrigin(
scoped_refptr<SecurityOrigin> security_origin = origin->IsolatedCopy();
security_origin->SetOpaqueOriginIsPotentiallyTrustworthy(
is_potentially_trustworthy_unique_origin);
- GetSecurityContext()->SetReplicatedOrigin(security_origin);
+ security_context_.SetReplicatedOrigin(security_origin);
ApplyReplicatedFeaturePolicyHeader();
// If the origin of a remote frame changed, the accessibility object for the
@@ -314,6 +409,15 @@ void RemoteFrame::SetReplicatedOrigin(
}
}
+void RemoteFrame::SetReplicatedAdFrameType(
+ mojom::blink::AdFrameType ad_frame_type) {
+ if (ad_frame_type_ == mojom::blink::AdFrameType::kNonAd) {
+ ad_frame_type_ = ad_frame_type;
+ } else {
+ DCHECK_EQ(ad_frame_type_, ad_frame_type);
+ }
+}
+
void RemoteFrame::DispatchLoadEventForFrameOwner() {
DCHECK(Owner()->IsLocal());
Owner()->DispatchLoad();
@@ -328,6 +432,189 @@ void RemoteFrame::Focus() {
FocusImpl();
}
+void RemoteFrame::SetHadStickyUserActivationBeforeNavigation(bool value) {
+ Frame::SetHadStickyUserActivationBeforeNavigation(value);
+}
+
+void RemoteFrame::SetNeedsOcclusionTracking(bool needs_tracking) {
+ View()->SetNeedsOcclusionTracking(needs_tracking);
+}
+
+void RemoteFrame::BubbleLogicalScroll(mojom::blink::ScrollDirection direction,
+ ui::ScrollGranularity granularity) {
+ Frame* parent_frame = Client()->Parent();
+ DCHECK(parent_frame);
+ DCHECK(parent_frame->IsLocalFrame());
+
+ parent_frame->BubbleLogicalScrollFromChildFrame(direction, granularity, this);
+}
+
+void RemoteFrame::UpdateUserActivationState(
+ mojom::blink::UserActivationUpdateType update_type) {
+ switch (update_type) {
+ case mojom::blink::UserActivationUpdateType::kNotifyActivation:
+ NotifyUserActivationInLocalTree();
+ break;
+ case mojom::blink::UserActivationUpdateType::kConsumeTransientActivation:
+ ConsumeTransientUserActivationInLocalTree();
+ break;
+ case mojom::blink::UserActivationUpdateType::kClearActivation:
+ ClearUserActivationInLocalTree();
+ break;
+ case mojom::blink::UserActivationUpdateType::
+ kNotifyActivationPendingBrowserVerification:
+ NOTREACHED() << "Unexpected UserActivationUpdateType from browser";
+ break;
+ }
+}
+
+void RemoteFrame::SetEmbeddingToken(
+ const base::UnguessableToken& embedding_token) {
+ FrameOwner* owner = Owner();
+ To<HTMLFrameOwnerElement>(owner)->SetEmbeddingToken(embedding_token);
+}
+
+void RemoteFrame::SetPageFocus(bool is_focused) {
+ WebFrame::FromFrame(this)->View()->SetFocus(is_focused);
+}
+
+void RemoteFrame::ScrollRectToVisible(
+ const gfx::Rect& rect_to_scroll,
+ mojom::blink::ScrollIntoViewParamsPtr params) {
+ Element* owner_element = DeprecatedLocalOwner();
+ LayoutObject* owner_object = owner_element->GetLayoutObject();
+ if (!owner_object) {
+ // The LayoutObject could be nullptr by the time we get here. For instance
+ // <iframe>'s style might have been set to 'display: none' right after
+ // scrolling starts in the OOPIF's process (see https://crbug.com/777811).
+ return;
+ }
+
+ // Schedule the scroll.
+ PhysicalRect absolute_rect = owner_object->LocalToAncestorRect(
+ PhysicalRect(LayoutUnit(rect_to_scroll.x()),
+ LayoutUnit(rect_to_scroll.y()),
+ LayoutUnit(rect_to_scroll.width()),
+ LayoutUnit(rect_to_scroll.height())),
+ owner_object->View());
+
+ if (!params->zoom_into_rect ||
+ !owner_object->GetDocument().GetFrame()->LocalFrameRoot().IsMainFrame()) {
+ owner_object->ScrollRectToVisible(absolute_rect, std::move(params));
+ return;
+ }
+
+ // ZoomAndScrollToFocusedEditableElementRect will scroll only the layout and
+ // visual viewports. Ensure the element is actually visible in the viewport
+ // scrolling layer. (i.e. isn't clipped by some other content).
+ auto relative_element_bounds = params->relative_element_bounds;
+ auto relative_caret_bounds = params->relative_caret_bounds;
+
+ params->stop_at_main_frame_layout_viewport = true;
+ absolute_rect =
+ owner_object->ScrollRectToVisible(absolute_rect, std::move(params));
+
+ IntRect rect_in_document =
+ owner_object->GetDocument()
+ .GetFrame()
+ ->LocalFrameRoot()
+ .View()
+ ->RootFrameToDocument(EnclosingIntRect(
+ owner_element->GetDocument().View()->ConvertToRootFrame(
+ absolute_rect)));
+ IntRect element_bounds_in_document = EnclosingIntRect(
+ DeNormalizeRect(relative_element_bounds, rect_in_document));
+ IntRect caret_bounds_in_document = EnclosingIntRect(
+ DeNormalizeRect(relative_caret_bounds, rect_in_document));
+
+ // This is due to something such as scroll focused editable element into
+ // view on Android which also requires an automatic zoom into legible scale.
+ // This is handled by main frame's WebView.
+ WebFrame::FromFrame(this)->View()->ZoomAndScrollToFocusedEditableElementRect(
+ element_bounds_in_document, caret_bounds_in_document, true);
+}
+
+void RemoteFrame::IntrinsicSizingInfoOfChildChanged(
+ mojom::blink::IntrinsicSizingInfoPtr info) {
+ FrameOwner* owner = Owner();
+ // Only communication from HTMLPluginElement-owned subframes is allowed
+ // at present. This includes <embed> and <object> tags.
+ if (!owner || !owner->IsPlugin())
+ return;
+
+ // TODO(https://crbug.com/1044304): Should either remove the native
+ // C++ Blink type and use the Mojo type everywhere or typemap the
+ // Mojo type to the pre-existing native C++ Blink type.
+ IntrinsicSizingInfo sizing_info;
+ sizing_info.size = FloatSize(info->size);
+ sizing_info.aspect_ratio = FloatSize(info->aspect_ratio);
+ sizing_info.has_width = info->has_width;
+ sizing_info.has_height = info->has_height;
+ View()->SetIntrinsicSizeInfo(sizing_info);
+
+ owner->IntrinsicSizingInfoChanged();
+}
+
+// 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
+// considered effective immediately.
+//
+// These flags / policy are needed on the remote frame's SecurityContext to
+// ensure that sandbox flags and feature policy are inherited properly if this
+// proxy ever parents a local frame.
+void RemoteFrame::DidSetFramePolicyHeaders(
+ mojom::blink::WebSandboxFlags sandbox_flags,
+ const Vector<ParsedFeaturePolicyDeclaration>& parsed_feature_policy) {
+ SetReplicatedSandboxFlags(sandbox_flags);
+ // Convert from WTF::Vector<ParsedFeaturePolicyDeclaration>
+ // to std::vector<ParsedFeaturePolicyDeclaration>, since ParsedFeaturePolicy
+ // is an alias for the later.
+ //
+ // TODO(crbug.com/1047273): Remove this conversion by switching
+ // ParsedFeaturePolicy to operate over Vector
+ ParsedFeaturePolicy parsed_feature_policy_copy(parsed_feature_policy.size());
+ for (size_t i = 0; i < parsed_feature_policy.size(); ++i)
+ parsed_feature_policy_copy[i] = parsed_feature_policy[i];
+ SetReplicatedFeaturePolicyHeaderAndOpenerPolicies(
+ parsed_feature_policy_copy, FeaturePolicy::FeatureState());
+}
+
+// Update the proxy's FrameOwner with new sandbox flags and container policy
+// that were set by its parent in another process.
+//
+// Normally, when a frame's sandbox attribute is changed dynamically, the
+// frame's FrameOwner is updated with the new sandbox flags right away, while
+// the frame's SecurityContext is updated when the frame is navigated and the
+// new sandbox flags take effect.
+//
+// Currently, there is no use case for a proxy's pending FrameOwner sandbox
+// flags, so there's no message sent to proxies when the sandbox attribute is
+// first updated. Instead, the active flags are updated when they take effect,
+// by OnDidSetActiveSandboxFlags. The proxy's FrameOwner flags are updated here
+// with the caveat that the FrameOwner won't learn about updates to its flags
+// until they take effect.
+void RemoteFrame::DidUpdateFramePolicy(const FramePolicy& frame_policy) {
+ // At the moment, this is only used to replicate sandbox flags and container
+ // policy for frames with a remote owner.
+ SECURITY_CHECK(IsA<RemoteFrameOwner>(Owner()));
+ To<RemoteFrameOwner>(Owner())->SetFramePolicy(frame_policy);
+}
+
+IntSize RemoteFrame::GetMainFrameViewportSize() const {
+ HTMLFrameOwnerElement* owner = DeprecatedLocalOwner();
+ DCHECK(owner);
+ DCHECK(owner->GetDocument().GetFrame());
+ return owner->GetDocument().GetFrame()->GetMainFrameViewportSize();
+}
+
+IntPoint RemoteFrame::GetMainFrameScrollOffset() const {
+ HTMLFrameOwnerElement* owner = DeprecatedLocalOwner();
+ DCHECK(owner);
+ DCHECK(owner->GetDocument().GetFrame());
+ return owner->GetDocument().GetFrame()->GetMainFrameScrollOffset();
+}
+
bool RemoteFrame::IsIgnoredForHitTest() const {
HTMLFrameOwnerElement* owner = DeprecatedLocalOwner();
if (!owner || !owner->GetLayoutObject())
@@ -342,13 +629,10 @@ void RemoteFrame::SetCcLayer(cc::Layer* cc_layer,
bool is_surface_layer) {
DCHECK(Owner());
- if (cc_layer_)
- GraphicsLayer::UnregisterContentsLayer(cc_layer_);
cc_layer_ = cc_layer;
prevent_contents_opaque_changes_ = prevent_contents_opaque_changes;
is_surface_layer_ = is_surface_layer;
if (cc_layer_) {
- GraphicsLayer::RegisterContentsLayer(cc_layer_);
if (is_surface_layer) {
static_cast<cc::SurfaceLayer*>(cc_layer_)->SetHasPointerEventsNone(
IsIgnoredForHitTest());
@@ -358,7 +642,8 @@ void RemoteFrame::SetCcLayer(cc::Layer* cc_layer,
To<HTMLFrameOwnerElement>(Owner())->SetNeedsCompositingUpdate();
}
-void RemoteFrame::AdvanceFocus(WebFocusType type, LocalFrame* source) {
+void RemoteFrame::AdvanceFocus(mojom::blink::FocusType type,
+ LocalFrame* source) {
Client()->AdvanceFocus(type, source);
}
@@ -384,7 +669,7 @@ void RemoteFrame::ApplyReplicatedFeaturePolicyHeader() {
container_policy = Owner()->GetFramePolicy().container_policy;
const FeaturePolicy::FeatureState& opener_feature_state =
OpenerFeatureState();
- GetSecurityContext()->InitializeFeaturePolicy(
+ security_context_.InitializeFeaturePolicy(
feature_policy_header_, container_policy, parent_feature_policy,
opener_feature_state.empty() ? nullptr : &opener_feature_state);
}
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 aff03f68896..15767ce1b4b 100644
--- a/chromium/third_party/blink/renderer/core/frame/remote_frame.h
+++ b/chromium/third_party/blink/renderer/core/frame/remote_frame.h
@@ -8,7 +8,10 @@
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "third_party/blink/public/mojom/frame/frame.mojom-blink.h"
-#include "third_party/blink/public/platform/web_focus_type.h"
+#include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom-blink-forward.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
+#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/execution_context/remote_security_context.h"
#include "third_party/blink/renderer/core/frame/frame.h"
@@ -41,9 +44,9 @@ class CORE_EXPORT RemoteFrame final : public Frame,
~RemoteFrame() override;
// Frame overrides:
- void Trace(blink::Visitor*) override;
- void Navigate(const FrameLoadRequest&, WebFrameLoadType) override;
- RemoteSecurityContext* GetSecurityContext() const override;
+ void Trace(Visitor*) override;
+ void Navigate(FrameLoadRequest&, WebFrameLoadType) override;
+ const RemoteSecurityContext* GetSecurityContext() const override;
bool DetachDocument() override;
void CheckCompleted() override;
bool ShouldClose() override;
@@ -51,10 +54,13 @@ class CORE_EXPORT RemoteFrame final : public Frame,
void RemoveBackForwardCacheEviction() override {}
void SetIsInert(bool) override;
void SetInheritedEffectiveTouchAction(TouchAction) override;
- bool BubbleLogicalScrollFromChildFrame(ScrollDirection direction,
- ScrollGranularity granularity,
- Frame* child) override;
+ bool BubbleLogicalScrollFromChildFrame(
+ mojom::blink::ScrollDirection direction,
+ ScrollGranularity granularity,
+ Frame* child) override;
void DidFocus() override;
+ void AddResourceTimingFromChild(
+ mojom::blink::ResourceTimingInfoPtr timing) override;
void SetCcLayer(cc::Layer*,
bool prevent_contents_opaque_changes,
@@ -64,7 +70,7 @@ class CORE_EXPORT RemoteFrame final : public Frame,
return prevent_contents_opaque_changes_;
}
- void AdvanceFocus(WebFocusType, LocalFrame* source);
+ void AdvanceFocus(mojom::blink::FocusType, LocalFrame* source);
void SetView(RemoteFrameView*);
void CreateView();
@@ -83,16 +89,59 @@ class CORE_EXPORT RemoteFrame final : public Frame,
const ParsedFeaturePolicy& parsed_header,
const FeaturePolicy::FeatureState&);
- // blink::mojom::LocalFrame overrides:
+ void SetReplicatedSandboxFlags(mojom::blink::WebSandboxFlags);
+ void SetInsecureRequestPolicy(mojom::blink::InsecureRequestPolicy);
+ void SetInsecureNavigationsSet(const WebVector<unsigned>&);
+
+ // blink::mojom::RemoteFrame overrides:
void WillEnterFullscreen() override;
+ void AddReplicatedContentSecurityPolicies(
+ WTF::Vector<network::mojom::blink::ContentSecurityPolicyHeaderPtr>
+ headers) override;
void ResetReplicatedContentSecurityPolicy() override;
void EnforceInsecureNavigationsSet(const WTF::Vector<uint32_t>& set) override;
+ void SetFrameOwnerProperties(
+ mojom::blink::FrameOwnerPropertiesPtr properties) override;
+ void EnforceInsecureRequestPolicy(
+ mojom::blink::InsecureRequestPolicy policy) override;
void SetReplicatedOrigin(
const scoped_refptr<const SecurityOrigin>& origin,
bool is_potentially_trustworthy_unique_origin) override;
+ void SetReplicatedAdFrameType(
+ mojom::blink::AdFrameType ad_frame_type) override;
void DispatchLoadEventForFrameOwner() override;
void Collapse(bool collapsed) final;
void Focus() override;
+ void SetHadStickyUserActivationBeforeNavigation(bool value) override;
+ void SetNeedsOcclusionTracking(bool needs_tracking) override;
+ void BubbleLogicalScroll(mojom::blink::ScrollDirection direction,
+ ui::ScrollGranularity granularity) override;
+ void UpdateUserActivationState(
+ mojom::blink::UserActivationUpdateType) override;
+ void SetEmbeddingToken(
+ const base::UnguessableToken& embedding_token) override;
+ void SetPageFocus(bool is_focused) override;
+ void RenderFallbackContent() override;
+ void ScrollRectToVisible(
+ const gfx::Rect& rect_to_scroll,
+ mojom::blink::ScrollIntoViewParamsPtr params) override;
+ void DidStartLoading() override;
+ void DidStopLoading() override;
+ void IntrinsicSizingInfoOfChildChanged(
+ mojom::blink::IntrinsicSizingInfoPtr sizing_info) override;
+ void DidSetFramePolicyHeaders(
+ mojom::blink::WebSandboxFlags,
+ const WTF::Vector<ParsedFeaturePolicyDeclaration>&) override;
+ // Updates the snapshotted policy attributes (sandbox flags and feature policy
+ // container policy) in the frame's FrameOwner. This is used when this frame's
+ // parent is in another process and it dynamically updates this frame's
+ // sandbox flags or container policy. The new policy won't take effect until
+ // the next navigation.
+ void DidUpdateFramePolicy(const FramePolicy& frame_policy) override;
+
+ // Called only when this frame has a local frame owner.
+ IntSize GetMainFrameViewportSize() const override;
+ IntPoint GetMainFrameScrollOffset() const override;
private:
// Frame protected overrides:
@@ -111,7 +160,7 @@ class CORE_EXPORT RemoteFrame final : public Frame,
mojo::PendingAssociatedReceiver<mojom::blink::RemoteFrame> receiver);
Member<RemoteFrameView> view_;
- Member<RemoteSecurityContext> security_context_;
+ RemoteSecurityContext security_context_;
cc::Layer* cc_layer_ = nullptr;
bool prevent_contents_opaque_changes_ = false;
bool is_surface_layer_ = false;
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 a54101c09fe..e73cc62bcef 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
@@ -8,7 +8,6 @@
#include "cc/paint/paint_canvas.h"
#include "third_party/blink/public/mojom/blob/blob_url_store.mojom-blink-forward.h"
#include "third_party/blink/public/platform/viewport_intersection_state.h"
-#include "third_party/blink/public/platform/web_focus_type.h"
#include "third_party/blink/public/web/web_frame_load_type.h"
#include "third_party/blink/renderer/core/frame/frame_client.h"
#include "third_party/blink/renderer/core/frame/frame_types.h"
@@ -32,19 +31,17 @@ class RemoteFrameClient : public FrameClient {
virtual void Navigate(const ResourceRequest&,
bool should_replace_current_entry,
bool is_opener_navigation,
- bool has_download_sandbox_flag,
+ bool initiator_frame_has_download_sandbox_flag,
bool initiator_frame_is_ad,
mojo::PendingRemote<mojom::blink::BlobURLToken>) = 0;
unsigned BackForwardLength() override = 0;
- // Notifies the remote frame to check whether it is done loading, after one
- // of its children finishes loading.
- virtual void CheckCompleted() = 0;
-
// Forwards a postMessage for a remote frame.
- virtual void ForwardPostMessage(MessageEvent*,
- scoped_refptr<const SecurityOrigin> target,
- LocalFrame* source_frame) const = 0;
+ 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
@@ -56,12 +53,7 @@ class RemoteFrameClient : public FrameClient {
virtual void UpdateRemoteViewportIntersection(
const ViewportIntersectionState& intersection_state) = 0;
- virtual void AdvanceFocus(WebFocusType, LocalFrame* source) = 0;
-
- virtual void SetIsInert(bool) = 0;
-
- virtual void UpdateRenderThrottlingStatus(bool isThrottled,
- bool subtreeThrottled) = 0;
+ virtual void AdvanceFocus(mojom::blink::FocusType, LocalFrame* source) = 0;
virtual uint32_t Print(const IntRect&, cc::PaintCanvas*) const = 0;
};
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 2e0089d39e8..ec1271d743a 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
@@ -39,7 +39,7 @@ Frame* ToCoreFrame(WebFrame* frame) {
RemoteFrameClientImpl::RemoteFrameClientImpl(WebRemoteFrameImpl* web_frame)
: web_frame_(web_frame) {}
-void RemoteFrameClientImpl::Trace(blink::Visitor* visitor) {
+void RemoteFrameClientImpl::Trace(Visitor* visitor) {
visitor->Trace(web_frame_);
RemoteFrameClient::Trace(visitor);
}
@@ -102,7 +102,7 @@ void RemoteFrameClientImpl::Navigate(
const ResourceRequest& request,
bool should_replace_current_entry,
bool is_opener_navigation,
- bool has_download_sandbox_flag,
+ bool initiator_frame_has_download_sandbox_flag,
bool initiator_frame_is_ad,
mojo::PendingRemote<mojom::blink::BlobURLToken> blob_url_token) {
bool blocking_downloads_in_sandbox_enabled =
@@ -110,7 +110,7 @@ void RemoteFrameClientImpl::Navigate(
if (web_frame_->Client()) {
web_frame_->Client()->Navigate(
WrappedResourceRequest(request), should_replace_current_entry,
- is_opener_navigation, has_download_sandbox_flag,
+ is_opener_navigation, initiator_frame_has_download_sandbox_flag,
blocking_downloads_in_sandbox_enabled, initiator_frame_is_ad,
blob_url_token.PassPipe());
}
@@ -124,18 +124,16 @@ unsigned RemoteFrameClientImpl::BackForwardLength() {
return 2;
}
-void RemoteFrameClientImpl::CheckCompleted() {
- web_frame_->Client()->CheckCompleted();
-}
-
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));
+ WebSecurityOrigin(std::move(target)),
+ WebDOMMessageEvent(event, cluster_id));
}
}
@@ -150,23 +148,12 @@ void RemoteFrameClientImpl::UpdateRemoteViewportIntersection(
web_frame_->Client()->UpdateRemoteViewportIntersection(intersection_state);
}
-void RemoteFrameClientImpl::AdvanceFocus(WebFocusType type,
+void RemoteFrameClientImpl::AdvanceFocus(mojom::blink::FocusType type,
LocalFrame* source) {
web_frame_->Client()->AdvanceFocus(type,
WebLocalFrameImpl::FromFrame(source));
}
-void RemoteFrameClientImpl::SetIsInert(bool inert) {
- web_frame_->Client()->SetIsInert(inert);
-}
-
-void RemoteFrameClientImpl::UpdateRenderThrottlingStatus(
- bool is_throttled,
- bool subtree_throttled) {
- web_frame_->Client()->UpdateRenderThrottlingStatus(is_throttled,
- subtree_throttled);
-}
-
uint32_t RemoteFrameClientImpl::Print(const IntRect& rect,
cc::PaintCanvas* canvas) const {
return web_frame_->Client()->Print(rect, canvas);
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 2620d58c969..382e4f8214b 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
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_REMOTE_FRAME_CLIENT_IMPL_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_REMOTE_FRAME_CLIENT_IMPL_H_
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/frame/remote_frame_client.h"
namespace cc {
@@ -18,7 +19,7 @@ class RemoteFrameClientImpl final : public RemoteFrameClient {
public:
explicit RemoteFrameClientImpl(WebRemoteFrameImpl*);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// FrameClient overrides:
bool InShadowTree() const override;
@@ -39,18 +40,15 @@ class RemoteFrameClientImpl final : public RemoteFrameClient {
bool initiator_frame_is_ad,
mojo::PendingRemote<mojom::blink::BlobURLToken>) override;
unsigned BackForwardLength() override;
- void CheckCompleted() 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(WebFocusType, LocalFrame*) override;
- void SetIsInert(bool) override;
- void UpdateRenderThrottlingStatus(bool is_throttled,
- bool subtree_throttled) override;
+ void AdvanceFocus(mojom::blink::FocusType, LocalFrame*) override;
uint32_t Print(const IntRect&, cc::PaintCanvas*) const 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 9d6fdfa644f..525f18e1705 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
@@ -4,7 +4,6 @@
#include "third_party/blink/renderer/core/frame/remote_frame_owner.h"
-#include "third_party/blink/public/platform/web_resource_timing_info.h"
#include "third_party/blink/public/web/web_local_frame_client.h"
#include "third_party/blink/renderer/core/exported/web_remote_frame_impl.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -23,8 +22,7 @@ RemoteFrameOwner::RemoteFrameOwner(
: frame_policy_(frame_policy),
browsing_context_container_name_(
static_cast<String>(frame_owner_properties.name)),
- scrolling_(
- static_cast<ScrollbarMode>(frame_owner_properties.scrolling_mode)),
+ scrollbar_(frame_owner_properties.scrollbar_mode),
margin_width_(frame_owner_properties.margin_width),
margin_height_(frame_owner_properties.margin_height),
allow_fullscreen_(frame_owner_properties.allow_fullscreen),
@@ -34,14 +32,13 @@ RemoteFrameOwner::RemoteFrameOwner(
required_csp_(frame_owner_properties.required_csp),
frame_owner_element_type_(frame_owner_element_type) {}
-void RemoteFrameOwner::Trace(blink::Visitor* visitor) {
+void RemoteFrameOwner::Trace(Visitor* visitor) {
visitor->Trace(frame_);
FrameOwner::Trace(visitor);
}
-void RemoteFrameOwner::SetScrollingMode(
- WebFrameOwnerProperties::ScrollingMode mode) {
- scrolling_ = static_cast<ScrollbarMode>(mode);
+void RemoteFrameOwner::SetScrollbarMode(mojom::blink::ScrollbarMode mode) {
+ scrollbar_ = mode;
}
void RemoteFrameOwner::SetContentFrame(Frame& frame) {
@@ -55,16 +52,17 @@ void RemoteFrameOwner::ClearContentFrame() {
void RemoteFrameOwner::AddResourceTiming(const ResourceTimingInfo& info) {
LocalFrame* frame = To<LocalFrame>(frame_.Get());
- WebResourceTimingInfo resource_timing = Performance::GenerateResourceTiming(
- *frame->Tree().Parent()->GetSecurityContext()->GetSecurityOrigin(), info,
- *frame->GetDocument());
- frame->Client()->ForwardResourceTimingToParent(resource_timing);
+ mojom::blink::ResourceTimingInfoPtr resource_timing =
+ Performance::GenerateResourceTiming(
+ *frame->Tree().Parent()->GetSecurityContext()->GetSecurityOrigin(),
+ info, *frame->GetDocument()->ToExecutionContext());
+ frame->GetLocalFrameHostRemote().ForwardResourceTimingToParent(
+ std::move(resource_timing));
}
void RemoteFrameOwner::DispatchLoad() {
- WebLocalFrameImpl* web_frame =
- WebLocalFrameImpl::FromFrame(To<LocalFrame>(*frame_));
- web_frame->Client()->DispatchLoad();
+ auto& local_frame_host = To<LocalFrame>(*frame_).GetLocalFrameHostRemote();
+ local_frame_host.DispatchLoad();
}
void RemoteFrameOwner::RenderFallbackContent(Frame* failed_frame) {
@@ -73,9 +71,7 @@ void RemoteFrameOwner::RenderFallbackContent(Frame* failed_frame) {
DCHECK(failed_frame->IsLocalFrame());
LocalFrame* local_frame = To<LocalFrame>(failed_frame);
DCHECK(local_frame->IsProvisional() || ContentFrame() == local_frame);
- WebLocalFrameImpl::FromFrame(local_frame)
- ->Client()
- ->RenderFallbackContentInParentProcess();
+ local_frame->GetLocalFrameHostRemote().RenderFallbackContentInParentProcess();
}
void RemoteFrameOwner::IntrinsicSizingInfoChanged() {
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 56e4b566ea4..a75f1badd8f 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
@@ -7,6 +7,7 @@
#include "third_party/blink/public/common/frame/frame_owner_element_type.h"
#include "third_party/blink/public/common/frame/frame_policy.h"
+#include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink.h"
#include "third_party/blink/public/web/web_frame_owner_properties.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/frame/frame_owner.h"
@@ -47,11 +48,12 @@ class CORE_EXPORT RemoteFrameOwner final
AtomicString BrowsingContextContainerName() const override {
return browsing_context_container_name_;
}
- ScrollbarMode ScrollingMode() const override { return scrolling_; }
+ mojom::blink::ScrollbarMode ScrollbarMode() const override {
+ return scrollbar_;
+ }
int MarginWidth() const override { return margin_width_; }
int MarginHeight() const override { return margin_height_; }
bool AllowFullscreen() const override { return allow_fullscreen_; }
- bool DisallowDocumentAccess() const override { return true; }
bool AllowPaymentRequest() const override { return allow_payment_request_; }
bool IsDisplayNone() const override { return is_display_none_; }
AtomicString RequiredCsp() const override { return required_csp_; }
@@ -63,7 +65,7 @@ class CORE_EXPORT RemoteFrameOwner final
void SetBrowsingContextContainerName(const WebString& name) {
browsing_context_container_name_ = name;
}
- void SetScrollingMode(WebFrameOwnerProperties::ScrollingMode);
+ void SetScrollbarMode(mojom::blink::ScrollbarMode);
void SetMarginWidth(int margin_width) { margin_width_ = margin_width; }
void SetMarginHeight(int margin_height) { margin_height_ = margin_height; }
void SetAllowFullscreen(bool allow_fullscreen) {
@@ -79,7 +81,7 @@ class CORE_EXPORT RemoteFrameOwner final
required_csp_ = required_csp;
}
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
// Intentionally private to prevent redundant checks when the type is
@@ -90,7 +92,7 @@ class CORE_EXPORT RemoteFrameOwner final
Member<Frame> frame_;
FramePolicy frame_policy_;
AtomicString browsing_context_container_name_;
- ScrollbarMode scrolling_;
+ mojom::blink::ScrollbarMode scrollbar_;
int margin_width_;
int margin_height_;
bool allow_fullscreen_;
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 711144fc9cd..f6a342c248f 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
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/frame/remote_frame_view.h"
+#include "components/paint_preview/common/paint_preview_tracker.h"
#include "third_party/blink/public/common/frame/frame_owner_element_type.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -18,6 +19,7 @@
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
+#include "third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h"
namespace blink {
@@ -88,10 +90,11 @@ bool RemoteFrameView::UpdateViewportIntersectionsForSubtree(
void RemoteFrameView::SetViewportIntersection(
const ViewportIntersectionState& intersection_state) {
- if (intersection_state != last_intersection_state_) {
- last_intersection_state_ = intersection_state;
- remote_frame_->Client()->UpdateRemoteViewportIntersection(
- intersection_state);
+ ViewportIntersectionState new_state(intersection_state);
+ new_state.compositor_visible_rect = WebRect(compositing_rect_);
+ if (new_state != last_intersection_state_) {
+ last_intersection_state_ = new_state;
+ remote_frame_->Client()->UpdateRemoteViewportIntersection(new_state);
}
}
@@ -105,10 +108,11 @@ void RemoteFrameView::SetNeedsOcclusionTracking(bool needs_tracking) {
}
}
-IntRect RemoteFrameView::GetCompositingRect() {
+void RemoteFrameView::UpdateCompositingRect() {
+ compositing_rect_ = IntRect();
LocalFrameView* local_root_view = ParentLocalRootFrameView();
if (!local_root_view || !remote_frame_->OwnerLayoutObject())
- return IntRect();
+ return;
// For main frames we constrain the rect that gets painted to the viewport.
// If the local frame root is an OOPIF itself, then we use the root's
@@ -124,11 +128,9 @@ IntRect RemoteFrameView::GetCompositingRect() {
// being compared to the frame size.
PhysicalRect viewport_rect =
remote_frame_->OwnerLayoutObject()->AncestorToLocalRect(
- local_root_view->GetLayoutView(),
- PhysicalRect(PhysicalOffset(), PhysicalSize(viewport_size)),
- kTraverseDocumentBoundaries);
- IntSize converted_viewport_size = EnclosingIntRect(viewport_rect).Size();
-
+ nullptr, PhysicalRect(PhysicalOffset(), PhysicalSize(viewport_size)),
+ kApplyRemoteRootFrameOffset | kTraverseDocumentBoundaries);
+ compositing_rect_ = EnclosingIntRect(viewport_rect);
IntSize frame_size = Size();
// Iframes that fit within the window viewport get fully rastered. For
@@ -139,22 +141,15 @@ IntRect RemoteFrameView::GetCompositingRect() {
// 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?
- converted_viewport_size.Scale(1.3f);
- converted_viewport_size.SetWidth(
- std::min(frame_size.Width(), converted_viewport_size.Width()));
- converted_viewport_size.SetHeight(
- std::min(frame_size.Height(), converted_viewport_size.Height()));
- IntPoint expanded_origin;
- const IntRect& last_rect = last_intersection_state_.viewport_intersection;
- if (!last_rect.IsEmpty()) {
- IntSize expanded_size =
- last_rect.Size().ExpandedTo(converted_viewport_size);
- expanded_size -= last_rect.Size();
- expanded_size.Scale(0.5f, 0.5f);
- expanded_origin = last_rect.Location() - expanded_size;
- expanded_origin.ClampNegativeToZero();
- }
- return IntRect(expanded_origin, converted_viewport_size);
+ compositing_rect_.InflateX(ceilf(viewport_rect.Width() * 0.15f));
+ compositing_rect_.InflateY(ceilf(viewport_rect.Height() * 0.15f));
+ compositing_rect_.SetWidth(
+ std::min(frame_size.Width(), compositing_rect_.Width()));
+ compositing_rect_.SetHeight(
+ std::min(frame_size.Height(), compositing_rect_.Height()));
+ IntPoint compositing_rect_location = compositing_rect_.Location();
+ compositing_rect_location.ClampNegativeToZero();
+ compositing_rect_.SetLocation(compositing_rect_location);
}
void RemoteFrameView::Dispose() {
@@ -201,25 +196,36 @@ void RemoteFrameView::Paint(GraphicsContext& context,
const GlobalPaintFlags flags,
const CullRect& rect,
const IntSize& paint_offset) const {
- // Painting remote frames is only for printing.
- if (!context.Printing())
- return;
-
if (!rect.Intersects(FrameRect()))
return;
- DrawingRecorder recorder(context, *GetFrame().OwnerLayoutObject(),
- DisplayItem::kDocumentBackground);
- context.Save();
- context.Translate(paint_offset.Width(), paint_offset.Height());
-
- DCHECK(context.Canvas());
- // Inform the remote frame to print.
- uint32_t content_id = Print(FrameRect(), context.Canvas());
+ if (context.IsPrintingOrPaintingPreview()) {
+ DrawingRecorder recorder(context, *GetFrame().OwnerLayoutObject(),
+ DisplayItem::kDocumentBackground);
+ context.Save();
+ context.Translate(paint_offset.Width(), paint_offset.Height());
+ DCHECK(context.Canvas());
+
+ uint32_t content_id = 0;
+ if (context.Printing()) {
+ // Inform the remote frame to print.
+ content_id = Print(FrameRect(), context.Canvas());
+ } else if (context.IsPaintingPreview()) {
+ // Inform the remote frame to capture a paint preview.
+ content_id = CapturePaintPreview(FrameRect(), context.Canvas());
+ }
+ // Record the place holder id on canvas.
+ context.Canvas()->recordCustomData(content_id);
+ context.Restore();
+ }
- // Record the place holder id on canvas.
- context.Canvas()->recordCustomData(content_id);
- context.Restore();
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
+ GetFrame().GetCcLayer()) {
+ auto offset = GetLayoutEmbeddedContent()->ReplacedContentRect().offset;
+ RecordForeignLayer(context, *GetFrame().OwnerLayoutObject(),
+ DisplayItem::kForeignLayerRemoteFrame,
+ GetFrame().GetCcLayer(), FloatPoint(offset));
+ }
}
void RemoteFrameView::UpdateGeometry() {
@@ -248,10 +254,8 @@ void RemoteFrameView::ParentVisibleChanged() {
void RemoteFrameView::VisibilityForThrottlingChanged() {
TRACE_EVENT0("blink", "RemoteFrameView::VisibilityForThrottlingChanged");
- if (!remote_frame_->Client())
- return;
- remote_frame_->Client()->UpdateRenderThrottlingStatus(IsHiddenForThrottling(),
- IsSubtreeThrottled());
+ remote_frame_->GetRemoteFrameHostRemote().UpdateRenderThrottlingStatus(
+ IsHiddenForThrottling(), IsSubtreeThrottled());
}
void RemoteFrameView::VisibilityChanged(
@@ -287,7 +291,35 @@ uint32_t RemoteFrameView::Print(const IntRect& rect,
return remote_frame_->Client()->Print(rect, canvas);
}
-void RemoteFrameView::Trace(blink::Visitor* visitor) {
+uint32_t RemoteFrameView::CapturePaintPreview(const IntRect& rect,
+ cc::PaintCanvas* canvas) const {
+ auto* tracker = canvas->GetPaintPreviewTracker();
+ DCHECK(tracker); // |tracker| must exist or there is a bug upstream.
+
+ // Create a placeholder ID that maps to an embedding token.
+ HTMLFrameOwnerElement* owner = remote_frame_->DeprecatedLocalOwner();
+ DCHECK(owner);
+
+ // RACE: there is a possibility that the embedding token will be null and
+ // still be in a valid state. This can occur is the frame has recently
+ // navigated and the embedding token hasn't propagated from the FrameTreeNode
+ // to this HTMLFrameOwnerElement yet (over IPC). If the token is null the
+ // failure can be handled gracefully by simply ignoring the subframe in the
+ // result.
+ base::Optional<base::UnguessableToken> maybe_embedding_token =
+ owner->GetEmbeddingToken();
+ if (!maybe_embedding_token.has_value())
+ return 0;
+ uint32_t content_id =
+ tracker->CreateContentForRemoteFrame(rect, maybe_embedding_token.value());
+
+ // Send a request to the browser to trigger a capture of the remote frame.
+ remote_frame_->GetRemoteFrameHostRemote()
+ .CapturePaintPreviewOfCrossProcessSubframe(rect, tracker->Guid());
+ return content_id;
+}
+
+void RemoteFrameView::Trace(Visitor* visitor) {
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 a4655607b06..c226f2ccb39 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
@@ -70,12 +70,15 @@ class RemoteFrameView final : public GarbageCollected<RemoteFrameView>,
// Compute the interest rect of this frame in its unscrolled space. This may
// be used by the OOPIF's compositor to limit the amount of rastered tiles,
- // and reduce the number of paint-ops generated.
- IntRect GetCompositingRect();
+ // and reduce the number of paint-ops generated. UpdateCompositingRect must be
+ // called before the parent frame commits a compositor frame.
+ void UpdateCompositingRect();
+ IntRect GetCompositingRect() const { return compositing_rect_; }
uint32_t Print(const IntRect&, cc::PaintCanvas*) const;
+ uint32_t CapturePaintPreview(const IntRect&, cc::PaintCanvas*) const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
bool NeedsViewportOffset() const override { return true; }
@@ -97,6 +100,7 @@ class RemoteFrameView final : public GarbageCollected<RemoteFrameView>,
// details.
Member<RemoteFrame> remote_frame_;
ViewportIntersectionState last_intersection_state_;
+ IntRect compositing_rect_;
IntrinsicSizingInfo intrinsic_sizing_info_;
bool has_intrinsic_sizing_info_ = false;
diff --git a/chromium/third_party/blink/renderer/core/frame/report.cc b/chromium/third_party/blink/renderer/core/frame/report.cc
index 46d331d3890..10c53d8ad82 100644
--- a/chromium/third_party/blink/renderer/core/frame/report.cc
+++ b/chromium/third_party/blink/renderer/core/frame/report.cc
@@ -8,6 +8,7 @@ namespace blink {
constexpr const char ReportType::kDeprecation[];
constexpr const char ReportType::kFeaturePolicyViolation[];
+constexpr const char ReportType::kDocumentPolicyViolation[];
constexpr const char ReportType::kIntervention[];
constexpr const char ReportType::kCSPViolation[];
diff --git a/chromium/third_party/blink/renderer/core/frame/report.h b/chromium/third_party/blink/renderer/core/frame/report.h
index 3cadb410219..27ca7ab2617 100644
--- a/chromium/third_party/blink/renderer/core/frame/report.h
+++ b/chromium/third_party/blink/renderer/core/frame/report.h
@@ -17,6 +17,8 @@ struct CORE_EXPORT ReportType {
static constexpr const char kDeprecation[] = "deprecation";
static constexpr const char kFeaturePolicyViolation[] =
"feature-policy-violation";
+ static constexpr const char kDocumentPolicyViolation[] =
+ "document-policy-violation";
static constexpr const char kIntervention[] = "intervention";
static constexpr const char kCSPViolation[] = "csp-violation";
};
@@ -34,7 +36,7 @@ class CORE_EXPORT Report : public ScriptWrappable {
String url() const { return url_; }
ReportBody* body() const { return body_; }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 2ded1e30241..fbbc1b1b1a9 100644
--- a/chromium/third_party/blink/renderer/core/frame/reporting_context.cc
+++ b/chromium/third_party/blink/renderer/core/frame/reporting_context.cc
@@ -6,10 +6,12 @@
#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/task_type.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/csp/csp_violation_report_body.h"
#include "third_party/blink/renderer/core/frame/deprecation_report_body.h"
+#include "third_party/blink/renderer/core/frame/document_policy_violation_report_body.h"
#include "third_party/blink/renderer/core/frame/feature_policy_violation_report_body.h"
#include "third_party/blink/renderer/core/frame/intervention_report_body.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -25,7 +27,9 @@ namespace blink {
const char ReportingContext::kSupplementName[] = "ReportingContext";
ReportingContext::ReportingContext(ExecutionContext& context)
- : Supplement<ExecutionContext>(context), execution_context_(context) {}
+ : Supplement<ExecutionContext>(context),
+ execution_context_(context),
+ reporting_service_(&context) {}
// static
ReportingContext* ReportingContext::From(ExecutionContext* context) {
@@ -80,10 +84,11 @@ void ReportingContext::UnregisterObserver(ReportingObserver* observer) {
observers_.erase(observer);
}
-void ReportingContext::Trace(blink::Visitor* visitor) {
+void ReportingContext::Trace(Visitor* visitor) {
visitor->Trace(observers_);
visitor->Trace(report_buffer_);
visitor->Trace(execution_context_);
+ visitor->Trace(reporting_service_);
Supplement<ExecutionContext>::Trace(visitor);
}
@@ -104,11 +109,12 @@ void ReportingContext::CountReport(Report* report) {
UseCounter::Count(execution_context_, feature);
}
-const mojo::Remote<mojom::blink::ReportingServiceProxy>&
+const HeapMojoRemote<mojom::blink::ReportingServiceProxy>&
ReportingContext::GetReportingService() const {
- if (!reporting_service_) {
+ if (!reporting_service_.is_bound()) {
Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
- reporting_service_.BindNewPipeAndPassReceiver());
+ reporting_service_.BindNewPipeAndPassReceiver(
+ execution_context_->GetTaskRunner(TaskType::kMiscPlatformAPI)));
}
return reporting_service_;
}
@@ -118,7 +124,8 @@ void ReportingContext::SendToReportingAPI(Report* report,
const String& type = report->type();
if (!(type == ReportType::kCSPViolation || type == ReportType::kDeprecation ||
type == ReportType::kFeaturePolicyViolation ||
- type == ReportType::kIntervention)) {
+ type == ReportType::kIntervention ||
+ type == ReportType::kDocumentPolicyViolation)) {
return;
}
@@ -138,19 +145,13 @@ void ReportingContext::SendToReportingAPI(Report* report,
const CSPViolationReportBody* body =
static_cast<CSPViolationReportBody*>(report->body());
GetReportingService()->QueueCspViolationReport(
- url,
- endpoint,
- body->documentURL() ? body->documentURL() : "",
- body->referrer(),
- body->blockedURL(),
+ url, endpoint, body->documentURL() ? body->documentURL() : "",
+ body->referrer(), body->blockedURL(),
body->effectiveDirective() ? body->effectiveDirective() : "",
body->originalPolicy() ? body->originalPolicy() : "",
- body->sourceFile(),
- body->sample(),
- body->disposition() ? body->disposition() : "",
- body->statusCode(),
- line_number,
- column_number);
+ body->sourceFile(), body->sample(),
+ body->disposition() ? body->disposition() : "", body->statusCode(),
+ line_number, column_number);
} else if (type == ReportType::kDeprecation) {
// Send the deprecation report.
const DeprecationReportBody* body =
@@ -172,6 +173,14 @@ void ReportingContext::SendToReportingAPI(Report* report,
GetReportingService()->QueueInterventionReport(
url, body->id(), body->message(), body->sourceFile(), line_number,
column_number);
+ } else if (type == ReportType::kDocumentPolicyViolation) {
+ const DocumentPolicyViolationReportBody* body =
+ static_cast<DocumentPolicyViolationReportBody*>(report->body());
+ // Send the document policy violation report.
+ GetReportingService()->QueueDocumentPolicyViolationReport(
+ url, endpoint, body->featureId(), body->disposition(),
+ "Document policy violation", body->sourceFile(), line_number,
+ column_number);
}
}
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 ab5ca79012e..67a26a9becd 100644
--- a/chromium/third_party/blink/renderer/core/frame/reporting_context.h
+++ b/chromium/third_party/blink/renderer/core/frame/reporting_context.h
@@ -5,10 +5,10 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_REPORTING_CONTEXT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_REPORTING_CONTEXT_H_
-#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/reporting/reporting.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
#include "third_party/blink/renderer/platform/supplementable.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -43,14 +43,14 @@ class CORE_EXPORT ReportingContext final
void RegisterObserver(ReportingObserver*);
void UnregisterObserver(ReportingObserver*);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
// Counts the use of a report type via UseCounter.
void CountReport(Report*);
- const mojo::Remote<mojom::blink::ReportingServiceProxy>& GetReportingService()
- const;
+ const HeapMojoRemote<mojom::blink::ReportingServiceProxy>&
+ GetReportingService() const;
// Send |report| via the Reporting API to |endpoint|.
void SendToReportingAPI(Report* report, const String& endpoint) const;
@@ -61,7 +61,8 @@ class CORE_EXPORT ReportingContext final
// This is declared mutable so that the service endpoint can be cached by
// const methods.
- mutable mojo::Remote<mojom::blink::ReportingServiceProxy> reporting_service_;
+ mutable HeapMojoRemote<mojom::blink::ReportingServiceProxy>
+ reporting_service_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/reporting_context_test.cc b/chromium/third_party/blink/renderer/core/frame/reporting_context_test.cc
index e8115ad5b8c..4b7212311bd 100644
--- a/chromium/third_party/blink/renderer/core/frame/reporting_context_test.cc
+++ b/chromium/third_party/blink/renderer/core/frame/reporting_context_test.cc
@@ -101,6 +101,18 @@ class MockReportingServiceProxy : public mojom::blink::ReportingServiceProxy {
std::move(reached_callback_).Run();
}
+ void QueueDocumentPolicyViolationReport(const KURL& url,
+ const String& endpoint,
+ const String& policy_id,
+ const String& disposition,
+ const String& message,
+ const String& source_file,
+ int32_t line_number,
+ int32_t column_number) override {
+ if (reached_callback_)
+ std::move(reached_callback_).Run();
+ }
+
ThreadSafeBrowserInterfaceBrokerProxy& broker_;
mojo::ReceiverSet<ReportingServiceProxy> receivers_;
base::OnceClosure reached_callback_;
@@ -122,7 +134,7 @@ TEST_F(ReportingContextTest, CountQueuedReports) {
// Send the deprecation report to the Reporting API and any
// ReportingObservers.
- ReportingContext::From(&dummy_page_holder->GetDocument())
+ ReportingContext::From(dummy_page_holder->GetDocument().ToExecutionContext())
->QueueReport(report);
// tester.ExpectTotalCount("Blink.UseCounter.Features.DeprecationReport", 1);
// The potential violation for an already recorded violation does not count
@@ -141,7 +153,7 @@ TEST_F(ReportingContextTest, DeprecationReportContent) {
"FeatureId", base::Time::FromJsTime(1000), "Test report");
auto* report =
MakeGarbageCollected<Report>("deprecation", doc.Url().GetString(), body);
- ReportingContext::From(&doc)->QueueReport(report);
+ ReportingContext::From(doc.ToExecutionContext())->QueueReport(report);
run_loop.Run();
EXPECT_TRUE(reporting_service.DeprecationReportAnticipatedRemoval());
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 a296b0485a8..8421647b389 100644
--- a/chromium/third_party/blink/renderer/core/frame/reporting_observer.cc
+++ b/chromium/third_party/blink/renderer/core/frame/reporting_observer.cc
@@ -25,7 +25,7 @@ ReportingObserver* ReportingObserver::Create(
ReportingObserver::ReportingObserver(ExecutionContext* execution_context,
V8ReportingObserverCallback* callback,
ReportingObserverOptions* options)
- : ContextClient(execution_context),
+ : ExecutionContextClient(execution_context),
execution_context_(execution_context),
callback_(callback),
options_(options),
@@ -88,13 +88,13 @@ HeapVector<Member<Report>> ReportingObserver::takeRecords() {
return reports;
}
-void ReportingObserver::Trace(blink::Visitor* visitor) {
+void ReportingObserver::Trace(Visitor* visitor) {
visitor->Trace(execution_context_);
visitor->Trace(callback_);
visitor->Trace(options_);
visitor->Trace(report_queue_);
ScriptWrappable::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 4865ed31b60..23bb86d8b9f 100644
--- a/chromium/third_party/blink/renderer/core/frame/reporting_observer.h
+++ b/chromium/third_party/blink/renderer/core/frame/reporting_observer.h
@@ -7,10 +7,10 @@
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_reporting_observer_callback.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_reporting_observer_options.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/frame/report.h"
-#include "third_party/blink/renderer/core/frame/reporting_observer_options.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
@@ -21,7 +21,7 @@ class Report;
class CORE_EXPORT ReportingObserver final
: public ScriptWrappable,
public ActiveScriptWrappable<ReportingObserver>,
- public ContextClient {
+ public ExecutionContextClient {
USING_GARBAGE_COLLECTED_MIXIN(ReportingObserver);
DEFINE_WRAPPERTYPEINFO();
@@ -58,7 +58,7 @@ class CORE_EXPORT ReportingObserver final
void disconnect();
HeapVector<Member<Report>> takeRecords();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<ExecutionContext> execution_context_;
diff --git a/chromium/third_party/blink/renderer/core/frame/reporting_observer.idl b/chromium/third_party/blink/renderer/core/frame/reporting_observer.idl
index a248a08fcd1..134e31d61ab 100644
--- a/chromium/third_party/blink/renderer/core/frame/reporting_observer.idl
+++ b/chromium/third_party/blink/renderer/core/frame/reporting_observer.idl
@@ -7,10 +7,9 @@
callback ReportingObserverCallback = void (sequence<Report> reports, ReportingObserver observer);
[
- Constructor(ReportingObserverCallback callback, optional ReportingObserverOptions options),
- ConstructorCallWith=ExecutionContext,
ActiveScriptWrappable
] interface ReportingObserver {
+ [CallWith=ExecutionContext] constructor(ReportingObserverCallback callback, optional ReportingObserverOptions options = {});
void observe();
void disconnect();
ReportList takeRecords();
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 7401c0387e0..a2ec79b4827 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
@@ -30,18 +30,18 @@ class CORE_EXPORT ResizeViewportAnchor final
STACK_ALLOCATED();
public:
- explicit ResizeScope(ResizeViewportAnchor& anchor) : anchor_(anchor) {
+ explicit ResizeScope(ResizeViewportAnchor& anchor) : anchor_(&anchor) {
anchor_->BeginScope();
}
~ResizeScope() { anchor_->EndScope(); }
private:
- Member<ResizeViewportAnchor> anchor_;
+ ResizeViewportAnchor* anchor_;
};
void ResizeFrameView(const IntSize&);
- void Trace(blink::Visitor* visitor) { visitor->Trace(page_); }
+ void Trace(Visitor* visitor) { 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 c7b59db75b5..b27420f1e02 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
@@ -6,8 +6,9 @@
#include "base/barrier_closure.h"
#include "cc/input/snap_selection_strategy.h"
-#include "third_party/blink/public/platform/web_scroll_into_view_params.h"
+#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink.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/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/scroll_anchor.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
@@ -47,7 +48,7 @@ FloatRect GetUserScrollableRect(const ScrollableArea& area) {
} // namespace
RootFrameViewport::RootFrameViewport(ScrollableArea& visual_viewport,
ScrollableArea& layout_viewport)
- : visual_viewport_(visual_viewport) {
+ : visual_viewport_(visual_viewport), should_restore_scroll_(false) {
SetLayoutViewport(layout_viewport);
}
@@ -93,15 +94,16 @@ PhysicalRect RootFrameViewport::RootContentsToLayoutViewportContents(
void RootFrameViewport::RestoreToAnchor(const ScrollOffset& target_offset) {
// Clamp the scroll offset of each viewport now so that we force any invalid
// offsets to become valid so we can compute the correct deltas.
- VisualViewport().SetScrollOffset(VisualViewport().GetScrollOffset(),
- kProgrammaticScroll);
+ GetVisualViewport().SetScrollOffset(GetVisualViewport().GetScrollOffset(),
+ mojom::blink::ScrollType::kProgrammatic);
LayoutViewport().SetScrollOffset(LayoutViewport().GetScrollOffset(),
- kProgrammaticScroll);
+ mojom::blink::ScrollType::kProgrammatic);
ScrollOffset delta = target_offset - GetScrollOffset();
- VisualViewport().SetScrollOffset(VisualViewport().GetScrollOffset() + delta,
- kProgrammaticScroll);
+ GetVisualViewport().SetScrollOffset(
+ GetVisualViewport().GetScrollOffset() + delta,
+ mojom::blink::ScrollType::kProgrammatic);
delta = target_offset - GetScrollOffset();
@@ -116,11 +118,12 @@ void RootFrameViewport::RestoreToAnchor(const ScrollOffset& target_offset) {
LayoutViewport().SetScrollOffset(
ScrollOffset(LayoutViewport().ScrollOffsetInt() + layout_delta),
- kProgrammaticScroll);
+ mojom::blink::ScrollType::kProgrammatic);
delta = target_offset - GetScrollOffset();
- VisualViewport().SetScrollOffset(VisualViewport().GetScrollOffset() + delta,
- kProgrammaticScroll);
+ GetVisualViewport().SetScrollOffset(
+ GetVisualViewport().GetScrollOffset() + delta,
+ mojom::blink::ScrollType::kProgrammatic);
}
void RootFrameViewport::DidUpdateVisualViewport() {
@@ -167,7 +170,7 @@ void RootFrameViewport::UpdateScrollAnimator() {
}
ScrollOffset RootFrameViewport::ScrollOffsetFromScrollAnimators() const {
- return VisualViewport().GetScrollAnimator().CurrentOffset() +
+ return GetVisualViewport().GetScrollAnimator().CurrentOffset() +
LayoutViewport().GetScrollAnimator().CurrentOffset();
}
@@ -175,7 +178,7 @@ IntRect RootFrameViewport::VisibleContentRect(
IncludeScrollbarsInRect scrollbar_inclusion) const {
return IntRect(
IntPoint(ScrollOffsetInt()),
- VisualViewport().VisibleContentRect(scrollbar_inclusion).Size());
+ GetVisualViewport().VisibleContentRect(scrollbar_inclusion).Size());
}
PhysicalRect RootFrameViewport::VisibleScrollSnapportRect(
@@ -189,9 +192,9 @@ PhysicalRect RootFrameViewport::VisibleScrollSnapportRect(
PhysicalRect visual_rect_in_content(
PhysicalOffset::FromFloatSizeRound(
LayoutViewport().GetScrollOffset() +
- VisualViewport().GetScrollAnimator().CurrentOffset()),
+ GetVisualViewport().GetScrollAnimator().CurrentOffset()),
PhysicalSize(
- VisualViewport().VisibleContentRect(scrollbar_inclusion).Size()));
+ GetVisualViewport().VisibleContentRect(scrollbar_inclusion).Size()));
PhysicalRect visible_scroll_snapport =
Intersection(visual_rect_in_content, frame_rect_in_content);
@@ -240,22 +243,59 @@ IntRect RootFrameViewport::ScrollCornerRect() const {
return LayoutViewport().ScrollCornerRect();
}
-void RootFrameViewport::SetScrollOffset(const ScrollOffset& offset,
- ScrollType scroll_type,
- ScrollBehavior scroll_behavior,
- ScrollCallback on_finish) {
+void RootFrameViewport::ApplyPendingHistoryRestoreScrollOffset() {
+ if (!pending_view_state_)
+ return;
+
+ bool should_restore_scale = pending_view_state_->page_scale_factor_;
+
+ // For main frame restore scale and visual viewport position
+ ScrollOffset visual_viewport_offset(
+ pending_view_state_->visual_viewport_scroll_offset_);
+
+ // If the visual viewport's offset is (-1, -1) it means the history item
+ // is an old version of HistoryItem so distribute the scroll between
+ // the main frame and the visual viewport as best as we can.
+ if (visual_viewport_offset.Width() == -1 &&
+ visual_viewport_offset.Height() == -1) {
+ visual_viewport_offset = pending_view_state_->scroll_offset_ -
+ LayoutViewport().GetScrollOffset();
+ }
+
+ auto* visual_viewport = static_cast<VisualViewport*>(&GetVisualViewport());
+ if (should_restore_scale && should_restore_scroll_) {
+ visual_viewport->SetScaleAndLocation(
+ pending_view_state_->page_scale_factor_,
+ visual_viewport->IsPinchGestureActive(),
+ FloatPoint(visual_viewport_offset));
+ } else if (should_restore_scale) {
+ visual_viewport->SetScale(pending_view_state_->page_scale_factor_);
+ } else if (should_restore_scroll_) {
+ visual_viewport->SetLocation(FloatPoint(visual_viewport_offset));
+ }
+
+ should_restore_scroll_ = false;
+
+ pending_view_state_.reset();
+}
+
+void RootFrameViewport::SetScrollOffset(
+ const ScrollOffset& offset,
+ mojom::blink::ScrollType scroll_type,
+ mojom::blink::ScrollBehavior scroll_behavior,
+ ScrollCallback on_finish) {
UpdateScrollAnimator();
- if (scroll_behavior == kScrollBehaviorAuto)
+ if (scroll_behavior == mojom::blink::ScrollBehavior::kAuto)
scroll_behavior = ScrollBehaviorStyle();
- if (scroll_type == kAnchoringScroll) {
+ if (scroll_type == mojom::blink::ScrollType::kAnchoring) {
DistributeScrollBetweenViewports(offset, scroll_type, scroll_behavior,
kLayoutViewport, std::move(on_finish));
return;
}
- if (scroll_behavior == kScrollBehaviorSmooth) {
+ if (scroll_behavior == mojom::blink::ScrollBehavior::kSmooth) {
DistributeScrollBetweenViewports(offset, scroll_type, scroll_behavior,
kVisualViewport, std::move(on_finish));
return;
@@ -266,7 +306,7 @@ void RootFrameViewport::SetScrollOffset(const ScrollOffset& offset,
std::move(on_finish));
}
-ScrollBehavior RootFrameViewport::ScrollBehaviorStyle() const {
+mojom::blink::ScrollBehavior RootFrameViewport::ScrollBehaviorStyle() const {
return LayoutViewport().ScrollBehaviorStyle();
}
@@ -278,7 +318,7 @@ ScrollOffset RootFrameViewport::ClampToUserScrollableOffset(
const ScrollOffset& offset) const {
ScrollOffset scroll_offset = offset;
FloatRect user_scrollable = GetUserScrollableRect(LayoutViewport()) +
- GetUserScrollableRect(VisualViewport());
+ GetUserScrollableRect(GetVisualViewport());
scroll_offset.SetWidth(clampTo(scroll_offset.Width(), user_scrollable.X(),
user_scrollable.MaxX()));
scroll_offset.SetHeight(clampTo(scroll_offset.Height(), user_scrollable.Y(),
@@ -288,7 +328,7 @@ ScrollOffset RootFrameViewport::ClampToUserScrollableOffset(
PhysicalRect RootFrameViewport::ScrollIntoView(
const PhysicalRect& rect_in_absolute,
- const WebScrollIntoViewParams& params) {
+ const mojom::blink::ScrollIntoViewParamsPtr& params) {
PhysicalRect scroll_snapport_rect = VisibleScrollSnapportRect();
PhysicalRect rect_in_document = rect_in_absolute;
@@ -297,9 +337,9 @@ PhysicalRect RootFrameViewport::ScrollIntoView(
ScrollOffset new_scroll_offset =
ClampScrollOffset(ScrollAlignment::GetScrollOffsetToExpose(
- scroll_snapport_rect, rect_in_document, params.GetScrollAlignmentX(),
- params.GetScrollAlignmentY(), GetScrollOffset()));
- if (params.GetScrollType() == kUserScroll)
+ scroll_snapport_rect, rect_in_document, *params->align_x.get(),
+ *params->align_y.get(), GetScrollOffset()));
+ if (params->type == mojom::blink::ScrollType::kUser)
new_scroll_offset = ClampToUserScrollableOffset(new_scroll_offset);
FloatPoint end_point = ScrollOffsetToPosition(new_scroll_offset);
@@ -312,17 +352,15 @@ PhysicalRect RootFrameViewport::ScrollIntoView(
}
if (new_scroll_offset != GetScrollOffset()) {
- if (params.is_for_scroll_sequence) {
- DCHECK(params.GetScrollType() == kProgrammaticScroll ||
- params.GetScrollType() == kUserScroll);
- ScrollBehavior behavior = DetermineScrollBehavior(
- params.GetScrollBehavior(),
- GetLayoutBox()->StyleRef().GetScrollBehavior());
+ if (params->is_for_scroll_sequence) {
+ DCHECK(params->type == mojom::blink::ScrollType::kProgrammatic ||
+ params->type == mojom::blink::ScrollType::kUser);
+ mojom::blink::ScrollBehavior behavior = DetermineScrollBehavior(
+ params->behavior, GetLayoutBox()->StyleRef().GetScrollBehavior());
GetSmoothScrollSequencer()->QueueAnimation(this, new_scroll_offset,
behavior);
} else {
- ScrollableArea::SetScrollOffset(new_scroll_offset,
- params.GetScrollType());
+ ScrollableArea::SetScrollOffset(new_scroll_offset, params->type);
}
}
@@ -334,16 +372,18 @@ PhysicalRect RootFrameViewport::ScrollIntoView(
return rect_in_document;
}
-void RootFrameViewport::UpdateScrollOffset(const ScrollOffset& offset,
- ScrollType scroll_type) {
- DistributeScrollBetweenViewports(offset, scroll_type, kScrollBehaviorInstant,
+void RootFrameViewport::UpdateScrollOffset(
+ const ScrollOffset& offset,
+ mojom::blink::ScrollType scroll_type) {
+ DistributeScrollBetweenViewports(offset, scroll_type,
+ mojom::blink::ScrollBehavior::kInstant,
kVisualViewport);
}
void RootFrameViewport::DistributeScrollBetweenViewports(
const ScrollOffset& offset,
- ScrollType scroll_type,
- ScrollBehavior behavior,
+ mojom::blink::ScrollType scroll_type,
+ mojom::blink::ScrollBehavior behavior,
ViewportToScrollFirst scroll_first,
ScrollCallback on_finish) {
// Make sure we use the scroll offsets as reported by each viewport's
@@ -362,9 +402,9 @@ void RootFrameViewport::DistributeScrollBetweenViewports(
}
ScrollableArea& primary =
- scroll_first == kVisualViewport ? VisualViewport() : LayoutViewport();
+ scroll_first == kVisualViewport ? GetVisualViewport() : LayoutViewport();
ScrollableArea& secondary =
- scroll_first == kVisualViewport ? LayoutViewport() : VisualViewport();
+ scroll_first == kVisualViewport ? LayoutViewport() : GetVisualViewport();
ScrollOffset target_offset = primary.ClampScrollOffset(
primary.GetScrollAnimator().CurrentOffset() + delta);
@@ -402,22 +442,22 @@ IntSize RootFrameViewport::ScrollOffsetInt() const {
ScrollOffset RootFrameViewport::GetScrollOffset() const {
return LayoutViewport().GetScrollOffset() +
- VisualViewport().GetScrollOffset();
+ GetVisualViewport().GetScrollOffset();
}
IntSize RootFrameViewport::MinimumScrollOffsetInt() const {
return IntSize(LayoutViewport().MinimumScrollOffsetInt() +
- VisualViewport().MinimumScrollOffsetInt());
+ GetVisualViewport().MinimumScrollOffsetInt());
}
IntSize RootFrameViewport::MaximumScrollOffsetInt() const {
return LayoutViewport().MaximumScrollOffsetInt() +
- VisualViewport().MaximumScrollOffsetInt();
+ GetVisualViewport().MaximumScrollOffsetInt();
}
ScrollOffset RootFrameViewport::MaximumScrollOffset() const {
return LayoutViewport().MaximumScrollOffset() +
- VisualViewport().MaximumScrollOffset();
+ GetVisualViewport().MaximumScrollOffset();
}
IntSize RootFrameViewport::ClampScrollOffset(
@@ -446,7 +486,7 @@ bool RootFrameViewport::ScrollbarsCanBeActive() const {
bool RootFrameViewport::UserInputScrollable(
ScrollbarOrientation orientation) const {
- return VisualViewport().UserInputScrollable(orientation) ||
+ return GetVisualViewport().UserInputScrollable(orientation) ||
LayoutViewport().UserInputScrollable(orientation);
}
@@ -499,7 +539,8 @@ ScrollResult RootFrameViewport::UserScroll(
// scroll delta, regardless of how much will actually scroll, but we need to
// know how much to leave for the layout viewport.
FloatSize visual_consumed_delta =
- VisualViewport().GetScrollAnimator().ComputeDeltaToConsume(pixel_delta);
+ GetVisualViewport().GetScrollAnimator().ComputeDeltaToConsume(
+ pixel_delta);
// Split the remaining delta between scrollable and unscrollable axes of the
// layout viewport. We only pass a delta to the scrollable axes and remember
@@ -529,7 +570,7 @@ ScrollResult RootFrameViewport::UserScroll(
// not through the ScrollableAreas?
if (visual_consumed_delta == pixel_delta) {
ScrollResult visual_result =
- VisualViewport().GetScrollAnimator().UserScroll(
+ GetVisualViewport().GetScrollAnimator().UserScroll(
granularity, visual_consumed_delta, run_on_return.Release());
return visual_result;
}
@@ -537,8 +578,9 @@ ScrollResult RootFrameViewport::UserScroll(
ScrollableArea::ScrollCallback callback = run_on_return.Release();
auto all_done = callback ? base::BarrierClosure(2, std::move(callback))
: base::RepeatingClosure();
- ScrollResult visual_result = VisualViewport().GetScrollAnimator().UserScroll(
- granularity, visual_consumed_delta, all_done);
+ ScrollResult visual_result =
+ GetVisualViewport().GetScrollAnimator().UserScroll(
+ granularity, visual_consumed_delta, all_done);
ScrollResult layout_result = LayoutViewport().GetScrollAnimator().UserScroll(
granularity, scrollable_axis_delta, all_done);
@@ -564,8 +606,8 @@ CompositorElementId RootFrameViewport::GetScrollElementId() const {
CompositorElementId RootFrameViewport::GetScrollbarElementId(
ScrollbarOrientation orientation) {
- return VisualViewport().VisualViewportSuppliesScrollbars()
- ? VisualViewport().GetScrollbarElementId(orientation)
+ return GetVisualViewport().VisualViewportSuppliesScrollbars()
+ ? GetVisualViewport().GetScrollbarElementId(orientation)
: LayoutViewport().GetScrollbarElementId(orientation);
}
@@ -580,25 +622,25 @@ SmoothScrollSequencer* RootFrameViewport::GetSmoothScrollSequencer() const {
void RootFrameViewport::ServiceScrollAnimations(double monotonic_time) {
ScrollableArea::ServiceScrollAnimations(monotonic_time);
LayoutViewport().ServiceScrollAnimations(monotonic_time);
- VisualViewport().ServiceScrollAnimations(monotonic_time);
+ GetVisualViewport().ServiceScrollAnimations(monotonic_time);
}
void RootFrameViewport::UpdateCompositorScrollAnimations() {
ScrollableArea::UpdateCompositorScrollAnimations();
LayoutViewport().UpdateCompositorScrollAnimations();
- VisualViewport().UpdateCompositorScrollAnimations();
+ GetVisualViewport().UpdateCompositorScrollAnimations();
}
void RootFrameViewport::CancelProgrammaticScrollAnimation() {
ScrollableArea::CancelProgrammaticScrollAnimation();
LayoutViewport().CancelProgrammaticScrollAnimation();
- VisualViewport().CancelProgrammaticScrollAnimation();
+ GetVisualViewport().CancelProgrammaticScrollAnimation();
}
void RootFrameViewport::ClearScrollableArea() {
ScrollableArea::ClearScrollableArea();
LayoutViewport().ClearScrollableArea();
- VisualViewport().ClearScrollableArea();
+ GetVisualViewport().ClearScrollableArea();
}
ScrollbarTheme& RootFrameViewport::GetPageScrollbarTheme() const {
@@ -619,12 +661,28 @@ bool RootFrameViewport::SetTargetSnapAreaElementIds(
return LayoutViewport().SetTargetSnapAreaElementIds(snap_target_ids);
}
+bool RootFrameViewport::SnapContainerDataNeedsUpdate() const {
+ return LayoutViewport().SnapContainerDataNeedsUpdate();
+}
+
+void RootFrameViewport::SetSnapContainerDataNeedsUpdate(bool needs_update) {
+ LayoutViewport().SetSnapContainerDataNeedsUpdate(needs_update);
+}
+
+bool RootFrameViewport::NeedsResnap() const {
+ return LayoutViewport().NeedsResnap();
+}
+
+void RootFrameViewport::SetNeedsResnap(bool needs_resnap) {
+ LayoutViewport().SetNeedsResnap(needs_resnap);
+}
+
base::Optional<FloatPoint> RootFrameViewport::GetSnapPositionAndSetTarget(
const cc::SnapSelectionStrategy& strategy) {
return LayoutViewport().GetSnapPositionAndSetTarget(strategy);
}
-void RootFrameViewport::Trace(blink::Visitor* visitor) {
+void RootFrameViewport::Trace(Visitor* visitor) {
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 2b70633aba1..7ced411e8b4 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
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_ROOT_FRAME_VIEWPORT_H_
#include "base/single_thread_task_runner.h"
+#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
#include "third_party/blink/renderer/platform/graphics/scroll_types.h"
@@ -15,7 +16,6 @@ namespace blink {
class LocalFrameView;
struct PhysicalRect;
-struct WebScrollIntoViewParams;
// ScrollableArea for the root frame's viewport. This class ties together the
// concepts of layout and visual viewports, used in pinch-to-zoom. This class
@@ -35,7 +35,7 @@ class CORE_EXPORT RootFrameViewport final
RootFrameViewport(ScrollableArea& visual_viewport,
ScrollableArea& layout_viewport);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void SetLayoutViewport(ScrollableArea&);
ScrollableArea& LayoutViewport() const;
@@ -58,11 +58,12 @@ class CORE_EXPORT RootFrameViewport final
// ScrollableArea Implementation
bool IsRootFrameViewport() const override { return true; }
void SetScrollOffset(const ScrollOffset&,
- ScrollType,
- ScrollBehavior,
+ mojom::blink::ScrollType,
+ mojom::blink::ScrollBehavior,
ScrollCallback on_finish) override;
- PhysicalRect ScrollIntoView(const PhysicalRect&,
- const WebScrollIntoViewParams&) override;
+ PhysicalRect ScrollIntoView(
+ const PhysicalRect&,
+ const mojom::blink::ScrollIntoViewParamsPtr&) override;
IntRect VisibleContentRect(
IncludeScrollbarsInRect = kExcludeScrollbars) const override;
PhysicalRect VisibleScrollSnapportRect(
@@ -77,7 +78,8 @@ class CORE_EXPORT RootFrameViewport final
int ScrollSize(ScrollbarOrientation) const override;
bool IsScrollCornerVisible() const override;
IntRect ScrollCornerRect() const override;
- void UpdateScrollOffset(const ScrollOffset&, ScrollType) override;
+ void UpdateScrollOffset(const ScrollOffset&,
+ mojom::blink::ScrollType) override;
IntSize ScrollOffsetInt() const override;
ScrollOffset GetScrollOffset() const override;
IntSize MinimumScrollOffsetInt() const override;
@@ -113,7 +115,7 @@ class CORE_EXPORT RootFrameViewport final
void ServiceScrollAnimations(double) override;
void UpdateCompositorScrollAnimations() override;
void CancelProgrammaticScrollAnimation() override;
- ScrollBehavior ScrollBehaviorStyle() const override;
+ mojom::blink::ScrollBehavior ScrollBehaviorStyle() const override;
WebColorScheme UsedColorScheme() const override;
void ClearScrollableArea() override;
LayoutBox* GetLayoutBox() const override;
@@ -122,12 +124,32 @@ class CORE_EXPORT RootFrameViewport final
unsigned = 0) const final;
scoped_refptr<base::SingleThreadTaskRunner> GetTimerTaskRunner() const final;
ScrollbarTheme& GetPageScrollbarTheme() const override;
+
+ // RootFrameViewport delegates these scroll-snap methods to its layout
+ // viewport.
const cc::SnapContainerData* GetSnapContainerData() const override;
void SetSnapContainerData(base::Optional<cc::SnapContainerData>) override;
bool SetTargetSnapAreaElementIds(cc::TargetSnapAreaElementIds) override;
+ bool SnapContainerDataNeedsUpdate() const override;
+ void SetSnapContainerDataNeedsUpdate(bool) override;
+ bool NeedsResnap() const override;
+ void SetNeedsResnap(bool) override;
base::Optional<FloatPoint> GetSnapPositionAndSetTarget(
const cc::SnapSelectionStrategy& strategy) override;
+ void SetPendingHistoryRestoreScrollOffset(
+ const HistoryItem::ViewState& view_state,
+ bool should_restore_scroll) override {
+ pending_view_state_ = view_state;
+ should_restore_scroll_ = should_restore_scroll;
+ }
+
+ void ApplyPendingHistoryRestoreScrollOffset() override;
+
+ bool HasPendingHistoryRestoreScrollOffset() override {
+ return !!pending_view_state_;
+ }
+
private:
FRIEND_TEST_ALL_PREFIXES(RootFrameViewportTest, DistributeScrollOrder);
@@ -137,8 +159,8 @@ class CORE_EXPORT RootFrameViewport final
void DistributeScrollBetweenViewports(
const ScrollOffset&,
- ScrollType,
- ScrollBehavior,
+ mojom::blink::ScrollType,
+ mojom::blink::ScrollBehavior,
ViewportToScrollFirst,
ScrollCallback on_finish = ScrollCallback());
@@ -147,7 +169,7 @@ class CORE_EXPORT RootFrameViewport final
// class' animator so use this method to pull updated values when necessary.
void UpdateScrollAnimator();
- ScrollableArea& VisualViewport() const {
+ ScrollableArea& GetVisualViewport() const {
DCHECK(visual_viewport_);
return *visual_viewport_;
}
@@ -156,6 +178,8 @@ class CORE_EXPORT RootFrameViewport final
Member<ScrollableArea> visual_viewport_;
Member<ScrollableArea> layout_viewport_;
+ base::Optional<HistoryItem::ViewState> pending_view_state_;
+ bool should_restore_scroll_;
};
template <>
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 a7a01feda7e..e7fdd6c72b3 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
@@ -8,7 +8,7 @@
#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_scroll_into_view_params.h"
+#include "third_party/blink/renderer/core/frame/visual_viewport.h"
#include "third_party/blink/renderer/core/scroll/scroll_alignment.h"
#include "third_party/blink/renderer/core/scroll/scroll_types.h"
#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
@@ -82,16 +82,16 @@ class ScrollableAreaStub : public GarbageCollected<ScrollableAreaStub>,
DEFINE_STATIC_LOCAL(ScrollbarThemeOverlayMock, theme, ());
return theme;
}
+ bool ScrollAnimatorEnabled() const override { return true; }
- void Trace(blink::Visitor* visitor) override {
- ScrollableArea::Trace(visitor);
- }
+ void Trace(Visitor* visitor) override { ScrollableArea::Trace(visitor); }
protected:
CompositorElementId GetScrollElementId() const override {
return CompositorElementId();
}
- void UpdateScrollOffset(const ScrollOffset& offset, ScrollType) override {
+ void UpdateScrollOffset(const ScrollOffset& offset,
+ mojom::blink::ScrollType) override {
scroll_offset_ = offset;
}
bool ShouldUseIntegerScrollOffset() const override { return true; }
@@ -213,7 +213,7 @@ TEST_F(RootFrameViewportTest, UserInputScrollable) {
// Layout viewport shouldn't scroll since it's not horizontally scrollable,
// but visual viewport should.
- root_frame_viewport->UserScroll(ScrollGranularity::kScrollByPixel,
+ root_frame_viewport->UserScroll(ScrollGranularity::kScrollByPrecisePixel,
FloatSize(300, 0),
ScrollableArea::ScrollCallback());
EXPECT_EQ(ScrollOffset(0, 0), layout_viewport->GetScrollOffset());
@@ -221,7 +221,7 @@ TEST_F(RootFrameViewportTest, UserInputScrollable) {
EXPECT_EQ(ScrollOffset(50, 0), root_frame_viewport->GetScrollOffset());
// Vertical scrolling should be unaffected.
- root_frame_viewport->UserScroll(ScrollGranularity::kScrollByPixel,
+ root_frame_viewport->UserScroll(ScrollGranularity::kScrollByPrecisePixel,
FloatSize(0, 300),
ScrollableArea::ScrollCallback());
EXPECT_EQ(ScrollOffset(0, 150), layout_viewport->GetScrollOffset());
@@ -231,9 +231,9 @@ TEST_F(RootFrameViewportTest, UserInputScrollable) {
// Try the same checks as above but for the vertical direction.
// ===============================================
- root_frame_viewport->SetScrollOffset(ScrollOffset(), kProgrammaticScroll,
- kScrollBehaviorInstant,
- ScrollableArea::ScrollCallback());
+ root_frame_viewport->SetScrollOffset(
+ ScrollOffset(), mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kInstant, ScrollableArea::ScrollCallback());
// Disable just the layout viewport's vertical scrolling, the
// RootFrameViewport should remain scrollable overall.
@@ -245,7 +245,7 @@ TEST_F(RootFrameViewportTest, UserInputScrollable) {
// Layout viewport shouldn't scroll since it's not vertically scrollable,
// but visual viewport should.
- root_frame_viewport->UserScroll(ScrollGranularity::kScrollByPixel,
+ root_frame_viewport->UserScroll(ScrollGranularity::kScrollByPrecisePixel,
FloatSize(0, 300),
ScrollableArea::ScrollCallback());
EXPECT_EQ(ScrollOffset(0, 0), layout_viewport->GetScrollOffset());
@@ -253,7 +253,7 @@ TEST_F(RootFrameViewportTest, UserInputScrollable) {
EXPECT_EQ(ScrollOffset(0, 75), root_frame_viewport->GetScrollOffset());
// Horizontal scrolling should be unaffected.
- root_frame_viewport->UserScroll(ScrollGranularity::kScrollByPixel,
+ root_frame_viewport->UserScroll(ScrollGranularity::kScrollByPrecisePixel,
FloatSize(300, 0),
ScrollableArea::ScrollCallback());
EXPECT_EQ(ScrollOffset(100, 0), layout_viewport->GetScrollOffset());
@@ -276,35 +276,38 @@ TEST_F(RootFrameViewportTest, TestScrollAnimatorUpdatedBeforeScroll) {
visual_viewport->SetScale(2);
- visual_viewport->SetScrollOffset(ScrollOffset(50, 75), kProgrammaticScroll);
+ visual_viewport->SetScrollOffset(ScrollOffset(50, 75),
+ mojom::blink::ScrollType::kProgrammatic);
EXPECT_EQ(ScrollOffset(50, 75), root_frame_viewport->GetScrollOffset());
// If the scroll animator doesn't update, it will still think it's at (0, 0)
// and so it may early exit.
- root_frame_viewport->SetScrollOffset(ScrollOffset(0, 0), kProgrammaticScroll,
- kScrollBehaviorInstant,
- ScrollableArea::ScrollCallback());
+ root_frame_viewport->SetScrollOffset(
+ ScrollOffset(0, 0), mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kInstant, ScrollableArea::ScrollCallback());
EXPECT_EQ(ScrollOffset(0, 0), root_frame_viewport->GetScrollOffset());
EXPECT_EQ(ScrollOffset(0, 0), visual_viewport->GetScrollOffset());
// Try again for userScroll()
- visual_viewport->SetScrollOffset(ScrollOffset(50, 75), kProgrammaticScroll);
+ visual_viewport->SetScrollOffset(ScrollOffset(50, 75),
+ mojom::blink::ScrollType::kProgrammatic);
EXPECT_EQ(ScrollOffset(50, 75), root_frame_viewport->GetScrollOffset());
- root_frame_viewport->UserScroll(ScrollGranularity::kScrollByPixel,
+ root_frame_viewport->UserScroll(ScrollGranularity::kScrollByPrecisePixel,
FloatSize(-50, 0),
ScrollableArea::ScrollCallback());
EXPECT_EQ(ScrollOffset(0, 75), root_frame_viewport->GetScrollOffset());
EXPECT_EQ(ScrollOffset(0, 75), visual_viewport->GetScrollOffset());
// Make sure the layout viewport is also accounted for.
- root_frame_viewport->SetScrollOffset(ScrollOffset(0, 0), kProgrammaticScroll,
- kScrollBehaviorInstant,
- ScrollableArea::ScrollCallback());
- layout_viewport->SetScrollOffset(ScrollOffset(100, 150), kProgrammaticScroll);
+ root_frame_viewport->SetScrollOffset(
+ ScrollOffset(0, 0), mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kInstant, ScrollableArea::ScrollCallback());
+ layout_viewport->SetScrollOffset(ScrollOffset(100, 150),
+ mojom::blink::ScrollType::kProgrammatic);
EXPECT_EQ(ScrollOffset(100, 150), root_frame_viewport->GetScrollOffset());
- root_frame_viewport->UserScroll(ScrollGranularity::kScrollByPixel,
+ root_frame_viewport->UserScroll(ScrollGranularity::kScrollByPrecisePixel,
FloatSize(-100, 0),
ScrollableArea::ScrollCallback());
EXPECT_EQ(ScrollOffset(0, 150), root_frame_viewport->GetScrollOffset());
@@ -329,82 +332,86 @@ TEST_F(RootFrameViewportTest, ScrollIntoView) {
visual_viewport->SetViewportSize(IntSize(100, 100));
root_frame_viewport->ScrollIntoView(
layout_viewport->DocumentToFrame(PhysicalRect(100, 250, 50, 50)),
- WebScrollIntoViewParams(ScrollAlignment::kAlignToEdgeIfNeeded,
- ScrollAlignment::kAlignToEdgeIfNeeded,
- kProgrammaticScroll, true,
- kScrollBehaviorInstant));
+ ScrollAlignment::CreateScrollIntoViewParams(
+ ScrollAlignment::ToEdgeIfNeeded(), ScrollAlignment::ToEdgeIfNeeded(),
+ mojom::blink::ScrollType::kProgrammatic, true,
+ mojom::blink::ScrollBehavior::kInstant));
EXPECT_EQ(ScrollOffset(50, 150), layout_viewport->GetScrollOffset());
EXPECT_EQ(ScrollOffset(0, 50), visual_viewport->GetScrollOffset());
root_frame_viewport->ScrollIntoView(
layout_viewport->DocumentToFrame(PhysicalRect(25, 75, 50, 50)),
- WebScrollIntoViewParams(ScrollAlignment::kAlignToEdgeIfNeeded,
- ScrollAlignment::kAlignToEdgeIfNeeded,
- kProgrammaticScroll, true,
- kScrollBehaviorInstant));
+ ScrollAlignment::CreateScrollIntoViewParams(
+ ScrollAlignment::ToEdgeIfNeeded(), ScrollAlignment::ToEdgeIfNeeded(),
+ mojom::blink::ScrollType::kProgrammatic, true,
+ mojom::blink::ScrollBehavior::kInstant));
EXPECT_EQ(ScrollOffset(25, 75), layout_viewport->GetScrollOffset());
EXPECT_EQ(ScrollOffset(0, 0), visual_viewport->GetScrollOffset());
// Reset the visual viewport's size, scale the page, and repeat the test
visual_viewport->SetViewportSize(IntSize(100, 150));
visual_viewport->SetScale(2);
- root_frame_viewport->SetScrollOffset(ScrollOffset(), kProgrammaticScroll,
- kScrollBehaviorInstant,
- ScrollableArea::ScrollCallback());
+ root_frame_viewport->SetScrollOffset(
+ ScrollOffset(), mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kInstant, ScrollableArea::ScrollCallback());
root_frame_viewport->ScrollIntoView(
layout_viewport->DocumentToFrame(PhysicalRect(50, 75, 50, 75)),
- WebScrollIntoViewParams(ScrollAlignment::kAlignToEdgeIfNeeded,
- ScrollAlignment::kAlignToEdgeIfNeeded,
- kProgrammaticScroll, true,
- kScrollBehaviorInstant));
+ ScrollAlignment::CreateScrollIntoViewParams(
+ ScrollAlignment::ToEdgeIfNeeded(), ScrollAlignment::ToEdgeIfNeeded(),
+ mojom::blink::ScrollType::kProgrammatic, true,
+ mojom::blink::ScrollBehavior::kInstant));
EXPECT_EQ(ScrollOffset(0, 0), layout_viewport->GetScrollOffset());
EXPECT_EQ(ScrollOffset(50, 75), visual_viewport->GetScrollOffset());
root_frame_viewport->ScrollIntoView(
layout_viewport->DocumentToFrame(PhysicalRect(190, 290, 10, 10)),
- WebScrollIntoViewParams(ScrollAlignment::kAlignToEdgeIfNeeded,
- ScrollAlignment::kAlignToEdgeIfNeeded,
- kProgrammaticScroll, true,
- kScrollBehaviorInstant));
+ ScrollAlignment::CreateScrollIntoViewParams(
+ ScrollAlignment::ToEdgeIfNeeded(), ScrollAlignment::ToEdgeIfNeeded(),
+ mojom::blink::ScrollType::kProgrammatic, true,
+ mojom::blink::ScrollBehavior::kInstant));
EXPECT_EQ(ScrollOffset(100, 150), layout_viewport->GetScrollOffset());
EXPECT_EQ(ScrollOffset(50, 75), visual_viewport->GetScrollOffset());
// Scrolling into view the viewport rect itself should be a no-op.
visual_viewport->SetViewportSize(IntSize(100, 100));
visual_viewport->SetScale(1.5f);
- visual_viewport->SetScrollOffset(ScrollOffset(0, 10), kProgrammaticScroll);
- layout_viewport->SetScrollOffset(ScrollOffset(50, 50), kProgrammaticScroll);
- root_frame_viewport->SetScrollOffset(
- root_frame_viewport->GetScrollOffset(), kProgrammaticScroll,
- kScrollBehaviorInstant, ScrollableArea::ScrollCallback());
+ visual_viewport->SetScrollOffset(ScrollOffset(0, 10),
+ mojom::blink::ScrollType::kProgrammatic);
+ layout_viewport->SetScrollOffset(ScrollOffset(50, 50),
+ mojom::blink::ScrollType::kProgrammatic);
+ root_frame_viewport->SetScrollOffset(root_frame_viewport->GetScrollOffset(),
+ mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kInstant,
+ ScrollableArea::ScrollCallback());
root_frame_viewport->ScrollIntoView(
layout_viewport->DocumentToFrame(PhysicalRect(
root_frame_viewport->VisibleContentRect(kExcludeScrollbars))),
- WebScrollIntoViewParams(ScrollAlignment::kAlignToEdgeIfNeeded,
- ScrollAlignment::kAlignToEdgeIfNeeded,
- kProgrammaticScroll, true,
- kScrollBehaviorInstant));
+ ScrollAlignment::CreateScrollIntoViewParams(
+ ScrollAlignment::ToEdgeIfNeeded(), ScrollAlignment::ToEdgeIfNeeded(),
+ mojom::blink::ScrollType::kProgrammatic, true,
+ mojom::blink::ScrollBehavior::kInstant));
EXPECT_EQ(ScrollOffset(50, 50), layout_viewport->GetScrollOffset());
EXPECT_EQ(ScrollOffset(0, 10), visual_viewport->GetScrollOffset());
root_frame_viewport->ScrollIntoView(
layout_viewport->DocumentToFrame(PhysicalRect(
root_frame_viewport->VisibleContentRect(kExcludeScrollbars))),
- WebScrollIntoViewParams(ScrollAlignment::kAlignCenterAlways,
- ScrollAlignment::kAlignCenterAlways,
- kProgrammaticScroll, true,
- kScrollBehaviorInstant));
+ ScrollAlignment::CreateScrollIntoViewParams(
+ ScrollAlignment::CenterAlways(), ScrollAlignment::CenterAlways(),
+ mojom::blink::ScrollType::kProgrammatic, true,
+ mojom::blink::ScrollBehavior::kInstant));
EXPECT_EQ(ScrollOffset(50, 50), layout_viewport->GetScrollOffset());
EXPECT_EQ(ScrollOffset(0, 10), visual_viewport->GetScrollOffset());
root_frame_viewport->ScrollIntoView(
layout_viewport->DocumentToFrame(PhysicalRect(
root_frame_viewport->VisibleContentRect(kExcludeScrollbars))),
- WebScrollIntoViewParams(
- ScrollAlignment::kAlignTopAlways, ScrollAlignment::kAlignTopAlways,
- kProgrammaticScroll, true, kScrollBehaviorInstant));
+ ScrollAlignment::CreateScrollIntoViewParams(
+ ScrollAlignment::TopAlways(), ScrollAlignment::TopAlways(),
+ mojom::blink::ScrollType::kProgrammatic, true,
+ mojom::blink::ScrollBehavior::kInstant));
EXPECT_EQ(ScrollOffset(50, 50), layout_viewport->GetScrollOffset());
EXPECT_EQ(ScrollOffset(0, 10), visual_viewport->GetScrollOffset());
}
@@ -424,31 +431,31 @@ TEST_F(RootFrameViewportTest, SetScrollOffset) {
// Ensure that the visual viewport scrolls first.
root_frame_viewport->SetScrollOffset(
- ScrollOffset(100, 100), kProgrammaticScroll, kScrollBehaviorInstant,
- ScrollableArea::ScrollCallback());
+ ScrollOffset(100, 100), mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kInstant, ScrollableArea::ScrollCallback());
EXPECT_EQ(ScrollOffset(100, 100), visual_viewport->GetScrollOffset());
EXPECT_EQ(ScrollOffset(0, 0), layout_viewport->GetScrollOffset());
// Scroll to the visual viewport's extent, the layout viewport should scroll
// the remainder.
root_frame_viewport->SetScrollOffset(
- ScrollOffset(300, 400), kProgrammaticScroll, kScrollBehaviorInstant,
- ScrollableArea::ScrollCallback());
+ ScrollOffset(300, 400), mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kInstant, ScrollableArea::ScrollCallback());
EXPECT_EQ(ScrollOffset(250, 250), visual_viewport->GetScrollOffset());
EXPECT_EQ(ScrollOffset(50, 150), layout_viewport->GetScrollOffset());
// Only the layout viewport should scroll further. Make sure it doesn't scroll
// out of bounds.
root_frame_viewport->SetScrollOffset(
- ScrollOffset(780, 1780), kProgrammaticScroll, kScrollBehaviorInstant,
- ScrollableArea::ScrollCallback());
+ ScrollOffset(780, 1780), mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kInstant, ScrollableArea::ScrollCallback());
EXPECT_EQ(ScrollOffset(250, 250), visual_viewport->GetScrollOffset());
EXPECT_EQ(ScrollOffset(500, 1500), layout_viewport->GetScrollOffset());
// Scroll all the way back.
- root_frame_viewport->SetScrollOffset(ScrollOffset(0, 0), kProgrammaticScroll,
- kScrollBehaviorInstant,
- ScrollableArea::ScrollCallback());
+ root_frame_viewport->SetScrollOffset(
+ ScrollOffset(0, 0), mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kInstant, ScrollableArea::ScrollCallback());
EXPECT_EQ(ScrollOffset(0, 0), visual_viewport->GetScrollOffset());
EXPECT_EQ(ScrollOffset(0, 0), layout_viewport->GetScrollOffset());
}
@@ -466,8 +473,8 @@ TEST_F(RootFrameViewportTest, VisibleContentRect) {
*visual_viewport, *layout_viewport);
root_frame_viewport->SetScrollOffset(
- ScrollOffset(100, 75), kProgrammaticScroll, kScrollBehaviorInstant,
- ScrollableArea::ScrollCallback());
+ ScrollOffset(100, 75), mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kInstant, ScrollableArea::ScrollCallback());
EXPECT_EQ(IntPoint(100, 75),
root_frame_viewport->VisibleContentRect().Location());
@@ -497,7 +504,8 @@ TEST_F(RootFrameViewportTest, ViewportScrollOrder) {
visual_viewport->SetScale(2);
root_frame_viewport->SetScrollOffset(
- ScrollOffset(40, 40), kUserScroll, kScrollBehaviorInstant,
+ ScrollOffset(40, 40), mojom::blink::ScrollType::kUser,
+ mojom::blink::ScrollBehavior::kInstant,
ScrollableArea::ScrollCallback(base::BindOnce(
[](ScrollableArea* visual_viewport, ScrollableArea* layout_viewport) {
EXPECT_EQ(ScrollOffset(40, 40), visual_viewport->GetScrollOffset());
@@ -508,7 +516,8 @@ TEST_F(RootFrameViewportTest, ViewportScrollOrder) {
EXPECT_EQ(ScrollOffset(0, 0), layout_viewport->GetScrollOffset());
root_frame_viewport->SetScrollOffset(
- ScrollOffset(60, 60), kProgrammaticScroll, kScrollBehaviorInstant,
+ ScrollOffset(60, 60), mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kInstant,
ScrollableArea::ScrollCallback(base::BindOnce(
[](ScrollableArea* visual_viewport, ScrollableArea* layout_viewport) {
EXPECT_EQ(ScrollOffset(50, 50), visual_viewport->GetScrollOffset());
@@ -536,9 +545,9 @@ TEST_F(RootFrameViewportTest, SetAlternateLayoutViewport) {
visual_viewport->SetScale(2);
- root_frame_viewport->SetScrollOffset(ScrollOffset(100, 100), kUserScroll,
- kScrollBehaviorInstant,
- ScrollableArea::ScrollCallback());
+ root_frame_viewport->SetScrollOffset(
+ ScrollOffset(100, 100), mojom::blink::ScrollType::kUser,
+ mojom::blink::ScrollBehavior::kInstant, ScrollableArea::ScrollCallback());
EXPECT_EQ(ScrollOffset(50, 50), visual_viewport->GetScrollOffset());
EXPECT_EQ(ScrollOffset(50, 50), layout_viewport->GetScrollOffset());
EXPECT_EQ(ScrollOffset(100, 100), root_frame_viewport->GetScrollOffset());
@@ -548,9 +557,9 @@ TEST_F(RootFrameViewportTest, SetAlternateLayoutViewport) {
EXPECT_EQ(ScrollOffset(0, 0), alternate_scroller->GetScrollOffset());
EXPECT_EQ(ScrollOffset(50, 50), root_frame_viewport->GetScrollOffset());
- root_frame_viewport->SetScrollOffset(ScrollOffset(200, 200), kUserScroll,
- kScrollBehaviorInstant,
- ScrollableArea::ScrollCallback());
+ root_frame_viewport->SetScrollOffset(
+ ScrollOffset(200, 200), mojom::blink::ScrollType::kUser,
+ mojom::blink::ScrollBehavior::kInstant, ScrollableArea::ScrollCallback());
EXPECT_EQ(ScrollOffset(50, 50), visual_viewport->GetScrollOffset());
EXPECT_EQ(ScrollOffset(150, 150), alternate_scroller->GetScrollOffset());
EXPECT_EQ(ScrollOffset(200, 200), root_frame_viewport->GetScrollOffset());
@@ -575,8 +584,8 @@ TEST_F(RootFrameViewportTest, DistributeScrollOrder) {
visual_viewport->SetScale(2);
root_frame_viewport->DistributeScrollBetweenViewports(
- ScrollOffset(60, 60), kProgrammaticScroll, kScrollBehaviorSmooth,
- RootFrameViewport::kVisualViewport,
+ ScrollOffset(60, 60), mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kSmooth, RootFrameViewport::kVisualViewport,
ScrollableArea::ScrollCallback(base::BindOnce(
[](ScrollableArea* visual_viewport, ScrollableArea* layout_viewport) {
EXPECT_EQ(ScrollOffset(50, 50), visual_viewport->GetScrollOffset());
@@ -592,4 +601,28 @@ TEST_F(RootFrameViewportTest, DistributeScrollOrder) {
EXPECT_EQ(ScrollOffset(10, 10), layout_viewport->GetScrollOffset());
}
+class RootFrameViewportRenderTest : public RenderingTest {
+ public:
+ RootFrameViewportRenderTest()
+ : RenderingTest(MakeGarbageCollected<EmptyLocalFrameClient>()) {}
+};
+
+TEST_F(RootFrameViewportRenderTest,
+ ApplyPendingHistoryRestoreScrollOffsetTwice) {
+ HistoryItem::ViewState view_state;
+ view_state.page_scale_factor_ = 1.5;
+ RootFrameViewport* root_frame_viewport = static_cast<RootFrameViewport*>(
+ GetDocument().View()->GetScrollableArea());
+ root_frame_viewport->SetPendingHistoryRestoreScrollOffset(view_state, false);
+ root_frame_viewport->ApplyPendingHistoryRestoreScrollOffset();
+
+ // Override the 1.5 scale with 1.0.
+ GetDocument().GetPage()->GetVisualViewport().SetScale(1.0f);
+
+ // The second call to ApplyPendingHistoryRestoreScrollOffset should
+ // do nothing, since the history was already restored.
+ root_frame_viewport->ApplyPendingHistoryRestoreScrollOffset();
+ EXPECT_EQ(1.0f, GetDocument().GetPage()->GetVisualViewport().Scale());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/rotation_viewport_anchor.cc b/chromium/third_party/blink/renderer/core/frame/rotation_viewport_anchor.cc
index ce59e84dc12..5777570912f 100644
--- a/chromium/third_party/blink/renderer/core/frame/rotation_viewport_anchor.cc
+++ b/chromium/third_party/blink/renderer/core/frame/rotation_viewport_anchor.cc
@@ -104,6 +104,7 @@ RotationViewportAnchor::RotationViewportAnchor(
PageScaleConstraintsSet& page_scale_constraints_set)
: root_frame_view_(&root_frame_view),
visual_viewport_(&visual_viewport),
+ anchor_node_(nullptr),
anchor_in_inner_view_coords_(anchor_in_inner_view_coords),
page_scale_constraints_set_(&page_scale_constraints_set) {
SetAnchor();
@@ -127,7 +128,7 @@ void RotationViewportAnchor::SetAnchor() {
visual_viewport_in_document_ =
FloatPoint(root_frame_viewport->VisibleContentRect().Location());
- anchor_node_.Clear();
+ anchor_node_ = nullptr;
anchor_node_bounds_ = PhysicalRect();
anchor_in_node_coords_ = FloatSize();
normalized_visual_viewport_offset_ = FloatSize();
@@ -194,7 +195,8 @@ void RotationViewportAnchor::RestoreToAnchor() {
visual_viewport_origin);
LayoutViewport().SetScrollOffset(
- ToScrollOffset(FloatPoint(main_frame_origin)), kProgrammaticScroll);
+ ToScrollOffset(FloatPoint(main_frame_origin)),
+ mojom::blink::ScrollType::kProgrammatic);
// Set scale before location, since location can be clamped on setting scale.
visual_viewport_->SetScale(new_page_scale_factor);
@@ -251,7 +253,7 @@ FloatPoint RotationViewportAnchor::GetInnerOrigin(
root_frame_view_->GetRootFrameViewport();
const PhysicalRect current_node_bounds_in_layout_viewport =
root_frame_viewport->RootContentsToLayoutViewportContents(
- *root_frame_view_.Get(), current_node_bounds);
+ *root_frame_view_, current_node_bounds);
// Compute the new anchor point relative to the node position
FloatSize anchor_offset_from_node(
diff --git a/chromium/third_party/blink/renderer/core/frame/rotation_viewport_anchor.h b/chromium/third_party/blink/renderer/core/frame/rotation_viewport_anchor.h
index 6eb40056cf8..538536b9ed8 100644
--- a/chromium/third_party/blink/renderer/core/frame/rotation_viewport_anchor.h
+++ b/chromium/third_party/blink/renderer/core/frame/rotation_viewport_anchor.h
@@ -48,8 +48,8 @@ class CORE_EXPORT RotationViewportAnchor {
FloatPoint& visual_viewport_offset) const;
ScrollableArea& LayoutViewport() const;
- Member<LocalFrameView> root_frame_view_;
- Member<VisualViewport> visual_viewport_;
+ LocalFrameView* root_frame_view_;
+ VisualViewport* visual_viewport_;
float old_page_scale_factor_;
float old_minimum_page_scale_factor_;
@@ -61,7 +61,7 @@ class CORE_EXPORT RotationViewportAnchor {
// normalized to the outer viewport size.
FloatSize normalized_visual_viewport_offset_;
- Member<Node> anchor_node_;
+ Node* anchor_node_;
// In Document coordinates.
PhysicalRect anchor_node_bounds_;
@@ -69,7 +69,7 @@ class CORE_EXPORT RotationViewportAnchor {
FloatSize anchor_in_inner_view_coords_;
FloatSize anchor_in_node_coords_;
- Member<PageScaleConstraintsSet> page_scale_constraints_set_;
+ PageScaleConstraintsSet* page_scale_constraints_set_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/rotation_viewport_anchor_test.cc b/chromium/third_party/blink/renderer/core/frame/rotation_viewport_anchor_test.cc
index b9fd355b6dc..0b026f005a1 100644
--- a/chromium/third_party/blink/renderer/core/frame/rotation_viewport_anchor_test.cc
+++ b/chromium/third_party/blink/renderer/core/frame/rotation_viewport_anchor_test.cc
@@ -56,7 +56,7 @@ TEST_F(RotationViewportAnchorTest, SimpleAbsolutePosition) {
// Place the target at the top-center of the viewport. This is where the
// rotation anchor finds the node to anchor to.
layout_viewport->SetScrollOffset(ScrollOffset(3050 - 200, 4050),
- kProgrammaticScroll);
+ mojom::blink::ScrollType::kProgrammatic);
WebView().MainFrameWidget()->Resize(WebSize(600, 400));
Compositor().BeginFrame();
@@ -102,7 +102,7 @@ TEST_F(RotationViewportAnchorTest, PositionRelativeToViewportSize) {
ScrollOffset(target_position.X() -
WebView().MainFrameWidget()->Size().width / 2 + 25,
target_position.Y()),
- kProgrammaticScroll);
+ mojom::blink::ScrollType::kProgrammatic);
WebView().MainFrameWidget()->Resize(WebSize(600, 100));
Compositor().BeginFrame();
diff --git a/chromium/third_party/blink/renderer/core/frame/sandbox_flags.cc b/chromium/third_party/blink/renderer/core/frame/sandbox_flags.cc
index ef0979b2492..218f0234c33 100644
--- a/chromium/third_party/blink/renderer/core/frame/sandbox_flags.cc
+++ b/chromium/third_party/blink/renderer/core/frame/sandbox_flags.cc
@@ -39,22 +39,25 @@
namespace blink {
const SandboxFlagFeaturePolicyPairs& SandboxFlagsWithFeaturePolicies() {
- DEFINE_STATIC_LOCAL(
- SandboxFlagFeaturePolicyPairs, array,
- ({{WebSandboxFlags::kTopNavigation,
- mojom::FeaturePolicyFeature::kTopNavigation},
- {WebSandboxFlags::kForms, mojom::FeaturePolicyFeature::kFormSubmission},
- {WebSandboxFlags::kScripts, mojom::FeaturePolicyFeature::kScript},
- {WebSandboxFlags::kPopups, mojom::FeaturePolicyFeature::kPopups},
- {WebSandboxFlags::kPointerLock,
- mojom::FeaturePolicyFeature::kPointerLock},
- {WebSandboxFlags::kModals, mojom::FeaturePolicyFeature::kModals},
- {WebSandboxFlags::kOrientationLock,
- mojom::FeaturePolicyFeature::kOrientationLock},
- {WebSandboxFlags::kPresentationController,
- mojom::FeaturePolicyFeature::kPresentation},
- {WebSandboxFlags::kDownloads,
- mojom::FeaturePolicyFeature::kDownloads}}));
+ DEFINE_STATIC_LOCAL(SandboxFlagFeaturePolicyPairs, array,
+ ({{mojom::blink::WebSandboxFlags::kTopNavigation,
+ mojom::blink::FeaturePolicyFeature::kTopNavigation},
+ {mojom::blink::WebSandboxFlags::kForms,
+ mojom::blink::FeaturePolicyFeature::kFormSubmission},
+ {mojom::blink::WebSandboxFlags::kScripts,
+ mojom::blink::FeaturePolicyFeature::kScript},
+ {mojom::blink::WebSandboxFlags::kPopups,
+ mojom::blink::FeaturePolicyFeature::kPopups},
+ {mojom::blink::WebSandboxFlags::kPointerLock,
+ mojom::blink::FeaturePolicyFeature::kPointerLock},
+ {mojom::blink::WebSandboxFlags::kModals,
+ mojom::blink::FeaturePolicyFeature::kModals},
+ {mojom::blink::WebSandboxFlags::kOrientationLock,
+ mojom::blink::FeaturePolicyFeature::kOrientationLock},
+ {mojom::blink::WebSandboxFlags::kPresentationController,
+ mojom::blink::FeaturePolicyFeature::kPresentation},
+ {mojom::blink::WebSandboxFlags::kDownloads,
+ mojom::blink::FeaturePolicyFeature::kDownloads}}));
return array;
}
@@ -62,20 +65,22 @@ const SandboxFlagFeaturePolicyPairs& SandboxFlagsWithFeaturePolicies() {
// corresponding feature policies. With FeaturePolicyForSandbox, these flags
// are always removed from the set of sandbox flags set for a sandboxed
// <iframe> (those sandbox flags are now contained in the |ContainerPolicy|).
-WebSandboxFlags SandboxFlagsImplementedByFeaturePolicy() {
- DEFINE_STATIC_LOCAL(WebSandboxFlags, mask, (WebSandboxFlags::kNone));
- if (mask == WebSandboxFlags::kNone) {
+mojom::blink::WebSandboxFlags SandboxFlagsImplementedByFeaturePolicy() {
+ DEFINE_STATIC_LOCAL(mojom::blink::WebSandboxFlags, mask,
+ (mojom::blink::WebSandboxFlags::kNone));
+ if (mask == mojom::blink::WebSandboxFlags::kNone) {
for (const auto& pair : SandboxFlagsWithFeaturePolicies())
mask |= pair.first;
}
return mask;
}
-WebSandboxFlags ParseSandboxPolicy(const SpaceSplitString& policy,
- String& invalid_tokens_error_message) {
+mojom::blink::WebSandboxFlags ParseSandboxPolicy(
+ const SpaceSplitString& policy,
+ String& invalid_tokens_error_message) {
// http://www.w3.org/TR/html5/the-iframe-element.html#attr-iframe-sandbox
// Parse the unordered set of unique space-separated tokens.
- WebSandboxFlags flags = WebSandboxFlags::kAll;
+ mojom::blink::WebSandboxFlags flags = mojom::blink::WebSandboxFlags::kAll;
unsigned length = policy.size();
unsigned number_of_token_errors = 0;
StringBuilder token_errors;
@@ -84,37 +89,40 @@ WebSandboxFlags ParseSandboxPolicy(const SpaceSplitString& policy,
// Turn off the corresponding sandbox flag if it's set as "allowed".
String sandbox_token(policy[index]);
if (EqualIgnoringASCIICase(sandbox_token, "allow-same-origin")) {
- flags = flags & ~WebSandboxFlags::kOrigin;
+ flags = flags & ~mojom::blink::WebSandboxFlags::kOrigin;
} else if (EqualIgnoringASCIICase(sandbox_token, "allow-forms")) {
- flags = flags & ~WebSandboxFlags::kForms;
+ flags = flags & ~mojom::blink::WebSandboxFlags::kForms;
} else if (EqualIgnoringASCIICase(sandbox_token, "allow-scripts")) {
- flags = flags & ~WebSandboxFlags::kScripts;
- flags = flags & ~WebSandboxFlags::kAutomaticFeatures;
+ flags = flags & ~mojom::blink::WebSandboxFlags::kScripts;
+ flags = flags & ~mojom::blink::WebSandboxFlags::kAutomaticFeatures;
} else if (EqualIgnoringASCIICase(sandbox_token, "allow-top-navigation")) {
- flags = flags & ~WebSandboxFlags::kTopNavigation;
+ flags = flags & ~mojom::blink::WebSandboxFlags::kTopNavigation;
} else if (EqualIgnoringASCIICase(sandbox_token, "allow-popups")) {
- flags = flags & ~WebSandboxFlags::kPopups;
+ flags = flags & ~mojom::blink::WebSandboxFlags::kPopups;
} else if (EqualIgnoringASCIICase(sandbox_token, "allow-pointer-lock")) {
- flags = flags & ~WebSandboxFlags::kPointerLock;
+ flags = flags & ~mojom::blink::WebSandboxFlags::kPointerLock;
} else if (EqualIgnoringASCIICase(sandbox_token,
"allow-orientation-lock")) {
- flags = flags & ~WebSandboxFlags::kOrientationLock;
+ flags = flags & ~mojom::blink::WebSandboxFlags::kOrientationLock;
} else if (EqualIgnoringASCIICase(sandbox_token,
"allow-popups-to-escape-sandbox")) {
- flags = flags & ~WebSandboxFlags::kPropagatesToAuxiliaryBrowsingContexts;
+ flags = flags & ~mojom::blink::WebSandboxFlags::
+ kPropagatesToAuxiliaryBrowsingContexts;
} else if (EqualIgnoringASCIICase(sandbox_token, "allow-modals")) {
- flags = flags & ~WebSandboxFlags::kModals;
+ flags = flags & ~mojom::blink::WebSandboxFlags::kModals;
} else if (EqualIgnoringASCIICase(sandbox_token, "allow-presentation")) {
- flags = flags & ~WebSandboxFlags::kPresentationController;
+ flags = flags & ~mojom::blink::WebSandboxFlags::kPresentationController;
} else if (EqualIgnoringASCIICase(
sandbox_token, "allow-top-navigation-by-user-activation")) {
- flags = flags & ~WebSandboxFlags::kTopNavigationByUserActivation;
+ flags = flags &
+ ~mojom::blink::WebSandboxFlags::kTopNavigationByUserActivation;
} else if (EqualIgnoringASCIICase(sandbox_token, "allow-downloads")) {
- flags = flags & ~WebSandboxFlags::kDownloads;
+ flags = flags & ~mojom::blink::WebSandboxFlags::kDownloads;
} else if (RuntimeEnabledFeatures::StorageAccessAPIEnabled() &&
EqualIgnoringASCIICase(
sandbox_token, "allow-storage-access-by-user-activation")) {
- flags = flags & ~WebSandboxFlags::kStorageAccessByUserActivation;
+ flags = flags &
+ ~mojom::blink::WebSandboxFlags::kStorageAccessByUserActivation;
} else {
token_errors.Append(token_errors.IsEmpty() ? "'" : ", '");
token_errors.Append(sandbox_token);
@@ -135,17 +143,17 @@ WebSandboxFlags ParseSandboxPolicy(const SpaceSplitString& policy,
// Removes a certain set of flags from |sandbox_flags| for which we have feature
// policies implemented.
-WebSandboxFlags GetSandboxFlagsNotImplementedAsFeaturePolicy(
- WebSandboxFlags sandbox_flags) {
+mojom::blink::WebSandboxFlags GetSandboxFlagsNotImplementedAsFeaturePolicy(
+ mojom::blink::WebSandboxFlags sandbox_flags) {
// Punch all the sandbox flags which are converted to feature policy.
return sandbox_flags & ~SandboxFlagsImplementedByFeaturePolicy();
}
void ApplySandboxFlagsToParsedFeaturePolicy(
- WebSandboxFlags sandbox_flags,
+ mojom::blink::WebSandboxFlags sandbox_flags,
ParsedFeaturePolicy& parsed_feature_policy) {
for (const auto& pair : SandboxFlagsWithFeaturePolicies()) {
- if ((sandbox_flags & pair.first) != WebSandboxFlags::kNone)
+ if ((sandbox_flags & pair.first) != mojom::blink::WebSandboxFlags::kNone)
DisallowFeatureIfNotPresent(pair.second, parsed_feature_policy);
}
}
diff --git a/chromium/third_party/blink/renderer/core/frame/sandbox_flags.h b/chromium/third_party/blink/renderer/core/frame/sandbox_flags.h
index 4c5c622ef76..817d836fdf0 100644
--- a/chromium/third_party/blink/renderer/core/frame/sandbox_flags.h
+++ b/chromium/third_party/blink/renderer/core/frame/sandbox_flags.h
@@ -29,30 +29,35 @@
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
#include "third_party/blink/public/common/frame/sandbox_flags.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/core/dom/space_split_string.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
namespace blink {
using SandboxFlagFeaturePolicyPairs =
- Vector<std::pair<WebSandboxFlags, mojom::FeaturePolicyFeature>>;
+ Vector<std::pair<mojom::blink::WebSandboxFlags,
+ mojom::blink::FeaturePolicyFeature>>;
// Returns a vector of pairs of sandbox flags and the corresponding feature
// policies. This includes most but not all sandbox flags as some flags have not
// yet migrated to using feature policies.
const SandboxFlagFeaturePolicyPairs& SandboxFlagsWithFeaturePolicies();
-WebSandboxFlags ParseSandboxPolicy(const SpaceSplitString& policy,
- String& invalid_tokens_error_message);
+mojom::blink::WebSandboxFlags ParseSandboxPolicy(
+ const SpaceSplitString& policy,
+ String& invalid_tokens_error_message);
// With FeaturePolicyForSandbox most sandbox flags will be represented with
// features. This method returns the part of sandbox flags which were not mapped
// to corresponding features.
-WebSandboxFlags GetSandboxFlagsNotImplementedAsFeaturePolicy(WebSandboxFlags);
+mojom::blink::WebSandboxFlags GetSandboxFlagsNotImplementedAsFeaturePolicy(
+ mojom::blink::WebSandboxFlags);
// Applies the sandbox flags as parsed feature policies; If a flag is present
// both in the provided flags and in the parsed feature as a feature policy,
// the parsed policy takes precedence.
-void ApplySandboxFlagsToParsedFeaturePolicy(WebSandboxFlags,
+void ApplySandboxFlagsToParsedFeaturePolicy(mojom::blink::WebSandboxFlags,
ParsedFeaturePolicy&);
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/scheduling.cc b/chromium/third_party/blink/renderer/core/frame/scheduling.cc
index c9ca978675e..cd659ee2522 100644
--- a/chromium/third_party/blink/renderer/core/frame/scheduling.cc
+++ b/chromium/third_party/blink/renderer/core/frame/scheduling.cc
@@ -6,6 +6,7 @@
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/pending_user_input.h"
#include "third_party/blink/renderer/platform/scheduler/public/pending_user_input_type.h"
@@ -25,7 +26,7 @@ bool Scheduling::isInputPending(ScriptState* script_state,
// can on the main thread, restrict the API to the case where all frames in
// a process are part of the same site to avoid leaking cross-site inputs.
ExecutionContext::From(script_state)
- ->AddConsoleMessage(ConsoleMessage::Create(
+ ->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning,
"isInputPending requires site-per-process (crbug.com/910421)."));
@@ -50,7 +51,7 @@ bool Scheduling::isInputPending(ScriptState* script_state,
message.Append(input_type_string);
message.Append("\". Skipping.");
ExecutionContext::From(script_state)
- ->AddConsoleMessage(ConsoleMessage::Create(
+ ->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning, message.ToString()));
}
diff --git a/chromium/third_party/blink/renderer/core/frame/screen.cc b/chromium/third_party/blink/renderer/core/frame/screen.cc
index 2ce805d8147..835eb382387 100644
--- a/chromium/third_party/blink/renderer/core/frame/screen.cc
+++ b/chromium/third_party/blink/renderer/core/frame/screen.cc
@@ -49,12 +49,13 @@ WebScreenInfo GetScreenInfo(LocalFrame& frame) {
Screen::Screen(LocalFrame* frame) : DOMWindowClient(frame) {}
int Screen::height() const {
+ if (display_) {
+ DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled());
+ return display_->bounds.height();
+ }
LocalFrame* frame = GetFrame();
- if (!frame) {
- if (RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
- return display_->bounds.height;
+ if (!frame)
return 0;
- }
Page* page = frame->GetPage();
if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) {
WebScreenInfo screen_info = GetScreenInfo(*frame);
@@ -65,12 +66,13 @@ int Screen::height() const {
}
int Screen::width() const {
+ if (display_) {
+ DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled());
+ return display_->bounds.width();
+ }
LocalFrame* frame = GetFrame();
- if (!frame) {
- if (RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
- return display_->bounds.width;
+ if (!frame)
return 0;
- }
Page* page = frame->GetPage();
if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) {
WebScreenInfo screen_info = GetScreenInfo(*frame);
@@ -81,32 +83,28 @@ int Screen::width() const {
}
unsigned Screen::colorDepth() const {
+ if (display_) {
+ DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled());
+ return display_->color_depth;
+ }
LocalFrame* frame = GetFrame();
- if (!frame) {
- if (RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
- return display_->color_depth;
+ if (!frame)
return 0;
- }
return static_cast<unsigned>(GetScreenInfo(*frame).depth);
}
unsigned Screen::pixelDepth() const {
- LocalFrame* frame = GetFrame();
- if (!frame) {
- if (RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
- return display_->color_depth;
- return 0;
- }
- return static_cast<unsigned>(GetScreenInfo(*frame).depth);
+ return colorDepth();
}
int Screen::availLeft() const {
+ if (display_) {
+ DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled());
+ return display_->work_area.x();
+ }
LocalFrame* frame = GetFrame();
- if (!frame) {
- if (RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
- return display_->work_area.x;
+ if (!frame)
return 0;
- }
Page* page = frame->GetPage();
if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) {
WebScreenInfo screen_info = GetScreenInfo(*frame);
@@ -117,12 +115,13 @@ int Screen::availLeft() const {
}
int Screen::availTop() const {
+ if (display_) {
+ DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled());
+ return display_->work_area.y();
+ }
LocalFrame* frame = GetFrame();
- if (!frame) {
- if (RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
- return display_->work_area.y;
+ if (!frame)
return 0;
- }
Page* page = frame->GetPage();
if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) {
WebScreenInfo screen_info = GetScreenInfo(*frame);
@@ -133,12 +132,13 @@ int Screen::availTop() const {
}
int Screen::availHeight() const {
+ if (display_) {
+ DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled());
+ return display_->work_area.height();
+ }
LocalFrame* frame = GetFrame();
- if (!frame) {
- if (RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
- return display_->work_area.width;
+ if (!frame)
return 0;
- }
Page* page = frame->GetPage();
if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) {
WebScreenInfo screen_info = GetScreenInfo(*frame);
@@ -149,12 +149,13 @@ int Screen::availHeight() const {
}
int Screen::availWidth() const {
+ if (display_) {
+ DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled());
+ return display_->work_area.width();
+ }
LocalFrame* frame = GetFrame();
- if (!frame) {
- if (RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
- return display_->work_area.height;
+ if (!frame)
return 0;
- }
Page* page = frame->GetPage();
if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) {
WebScreenInfo screen_info = GetScreenInfo(*frame);
@@ -164,24 +165,28 @@ int Screen::availWidth() const {
return GetScreenInfo(*frame).available_rect.width;
}
-void Screen::Trace(blink::Visitor* visitor) {
+void Screen::Trace(Visitor* visitor) {
ScriptWrappable::Trace(visitor);
DOMWindowClient::Trace(visitor);
Supplementable<Screen>::Trace(visitor);
}
-Screen::Screen(display::mojom::blink::DisplayPtr display, bool primary)
+Screen::Screen(display::mojom::blink::DisplayPtr display,
+ bool internal,
+ bool primary)
: DOMWindowClient(static_cast<LocalFrame*>(nullptr)),
display_(std::move(display)),
+ internal_(internal),
primary_(primary) {}
int Screen::left() const {
+ if (display_) {
+ DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled());
+ return display_->bounds.x();
+ }
LocalFrame* frame = GetFrame();
- if (!frame) {
- if (RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
- return display_->bounds.x;
+ if (!frame)
return 0;
- }
Page* page = frame->GetPage();
if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) {
WebScreenInfo screen_info = GetScreenInfo(*frame);
@@ -192,12 +197,13 @@ int Screen::left() const {
}
int Screen::top() const {
+ if (display_) {
+ DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled());
+ return display_->bounds.y();
+ }
LocalFrame* frame = GetFrame();
- if (!frame) {
- if (RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
- return display_->bounds.y;
+ if (!frame)
return 0;
- }
Page* page = frame->GetPage();
if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) {
WebScreenInfo screen_info = GetScreenInfo(*frame);
@@ -208,37 +214,52 @@ int Screen::top() const {
}
bool Screen::internal() const {
- // TODO(http://crbug.com/994889): Implement this.
+ if (display_) {
+ DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled());
+ return internal_.has_value() && internal_.value();
+ }
+ // TODO(http://crbug.com/994889): Implement this for |window.screen|?
NOTIMPLEMENTED_LOG_ONCE();
return false;
}
bool Screen::primary() const {
- LocalFrame* frame = GetFrame();
- if (!frame && RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
+ if (display_) {
+ DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled());
return primary_.has_value() && primary_.value();
+ }
// TODO(http://crbug.com/994889): Implement this for |window.screen|?
NOTIMPLEMENTED_LOG_ONCE();
return false;
}
float Screen::scaleFactor() const {
+ if (display_) {
+ DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled());
+ return display_->device_scale_factor;
+ }
LocalFrame* frame = GetFrame();
- if (!frame) {
- if (RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
- return display_->device_scale_factor;
+ if (!frame)
return 0;
- }
return GetScreenInfo(*frame).device_scale_factor;
}
const String Screen::name() const {
// TODO(http://crbug.com/994889): Implement this.
NOTIMPLEMENTED_LOG_ONCE();
- LocalFrame* frame = GetFrame();
- if (!frame && RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
+ if (display_) {
+ DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled());
return "Generic Screen";
+ }
return String();
}
+int64_t Screen::DisplayId() const {
+ if (display_) {
+ DCHECK(RuntimeEnabledFeatures::ScreenEnumerationEnabled());
+ return display_->id;
+ }
+ return kInvalidDisplayId;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/screen.h b/chromium/third_party/blink/renderer/core/frame/screen.h
index 7fae08d21e2..8503ee5f9ef 100644
--- a/chromium/third_party/blink/renderer/core/frame/screen.h
+++ b/chromium/third_party/blink/renderer/core/frame/screen.h
@@ -31,7 +31,7 @@
#include "base/optional.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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,12 +60,14 @@ class CORE_EXPORT Screen final : public ScriptWrappable,
int availHeight() const;
int availWidth() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// Proposed extensions to the Screen interface.
- // https://github.com/spark008/screen-enumeration/blob/master/EXPLAINER.md
+ // https://github.com/webscreens/screen-enumeration
// TODO(msw): Resolve different info sources, caching, and lifetimes.
- Screen(display::mojom::blink::DisplayPtr display, bool primary);
+ Screen(display::mojom::blink::DisplayPtr display,
+ bool internal,
+ bool primary);
int left() const;
int top() const;
bool internal() const;
@@ -73,11 +75,19 @@ class CORE_EXPORT Screen final : public ScriptWrappable,
float scaleFactor() const;
const String name() const;
+ // Not web-exposed; for internal usage only.
+ static constexpr int64_t kInvalidDisplayId = -1;
+ int64_t DisplayId() const;
+
private:
// A static snapshot of the display's information, provided upon construction.
// This member is only valid for Screen objects obtained via the experimental
// Screen Enumeration API.
const display::mojom::blink::DisplayPtr display_;
+ // True if this is an internal display of the device; it is a static value
+ // provided upon construction. This member is only valid for Screen objects
+ // obtained via the experimental Screen Enumeration API.
+ const base::Optional<bool> internal_;
// True if this is the primary screen of the operating system; it is a static
// value provided upon construction. This member is only valid for Screen
// objects obtained via the experimental Screen Enumeration API.
diff --git a/chromium/third_party/blink/renderer/core/frame/screen.idl b/chromium/third_party/blink/renderer/core/frame/screen.idl
index 222872d9d83..d9f328eeb06 100644
--- a/chromium/third_party/blink/renderer/core/frame/screen.idl
+++ b/chromium/third_party/blink/renderer/core/frame/screen.idl
@@ -43,7 +43,7 @@
[HighEntropy, Measure] readonly attribute long availTop;
// Proposed
- // https://github.com/spark008/screen-enumeration/blob/master/EXPLAINER.md
+ // https://github.com/webscreens/screen-enumeration
[RuntimeEnabled=ScreenEnumeration] readonly attribute long left;
[RuntimeEnabled=ScreenEnumeration] readonly attribute long top;
[RuntimeEnabled=ScreenEnumeration] readonly attribute boolean internal;
diff --git a/chromium/third_party/blink/renderer/core/frame/screen_orientation_controller.cc b/chromium/third_party/blink/renderer/core/frame/screen_orientation_controller.cc
index 82f43d09950..a8ff1b8a489 100644
--- a/chromium/third_party/blink/renderer/core/frame/screen_orientation_controller.cc
+++ b/chromium/third_party/blink/renderer/core/frame/screen_orientation_controller.cc
@@ -15,7 +15,7 @@ ScreenOrientationController* ScreenOrientationController::From(
return Supplement<LocalFrame>::From<ScreenOrientationController>(frame);
}
-void ScreenOrientationController::Trace(blink::Visitor* visitor) {
+void ScreenOrientationController::Trace(Visitor* visitor) {
Supplement<LocalFrame>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/screen_orientation_controller.h b/chromium/third_party/blink/renderer/core/frame/screen_orientation_controller.h
index 4fe5279e0b1..fdda50f2e99 100644
--- a/chromium/third_party/blink/renderer/core/frame/screen_orientation_controller.h
+++ b/chromium/third_party/blink/renderer/core/frame/screen_orientation_controller.h
@@ -43,7 +43,7 @@ class CORE_EXPORT ScreenOrientationController
// unlocking.
virtual bool MaybeHasActiveLock() const = 0;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
explicit ScreenOrientationController(LocalFrame&);
diff --git a/chromium/third_party/blink/renderer/core/frame/settings.cc b/chromium/third_party/blink/renderer/core/frame/settings.cc
index e3f9c5850b4..0b21f31337a 100644
--- a/chromium/third_party/blink/renderer/core/frame/settings.cc
+++ b/chromium/third_party/blink/renderer/core/frame/settings.cc
@@ -94,12 +94,4 @@ void Settings::SetTextAutosizingWindowSizeOverride(
Invalidate(SettingsDelegate::kTextAutosizingChange);
}
-void Settings::SetForceDarkModeEnabled(bool enabled) {
- if (force_dark_mode_ == enabled)
- return;
- force_dark_mode_ = enabled;
- SetDarkModeEnabled(force_dark_mode_);
- Invalidate(SettingsDelegate::kColorSchemeChange);
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/frame/settings.h b/chromium/third_party/blink/renderer/core/frame/settings.h
index 17931964166..ca4fd6cdde9 100644
--- a/chromium/third_party/blink/renderer/core/frame/settings.h
+++ b/chromium/third_party/blink/renderer/core/frame/settings.h
@@ -32,6 +32,7 @@
#include "base/macros.h"
#include "third_party/blink/public/common/css/navigation_controls.h"
+#include "third_party/blink/public/common/css/preferred_color_scheme.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/web_effective_connection_type.h"
@@ -43,6 +44,7 @@
#include "third_party/blink/renderer/core/editing/selection_strategy.h"
#include "third_party/blink/renderer/core/frame/settings_delegate.h"
#include "third_party/blink/renderer/core/html/media/autoplay_policy.h"
+#include "third_party/blink/renderer/core/html/parser/parser_scripting_flag_policy.h"
#include "third_party/blink/renderer/core/html/track/text_track_kind_user_preference.h"
#include "third_party/blink/renderer/core/loader/frame_loader_types.h"
#include "third_party/blink/renderer/core/settings_macros.h"
@@ -81,9 +83,6 @@ class CORE_EXPORT Settings {
return text_autosizing_window_size_override_;
}
- void SetForceDarkModeEnabled(bool enabled);
- bool ForceDarkModeEnabled() const { return force_dark_mode_; }
-
SETTINGS_GETTERS_AND_SETTERS
void SetDelegate(SettingsDelegate*);
@@ -97,7 +96,6 @@ class CORE_EXPORT Settings {
IntSize text_autosizing_window_size_override_;
bool text_autosizing_enabled_ : 1;
bool bypass_csp_ = false;
- bool force_dark_mode_ = false;
SETTINGS_MEMBER_VARIABLES
diff --git a/chromium/third_party/blink/renderer/core/frame/settings.json5 b/chromium/third_party/blink/renderer/core/frame/settings.json5
index 9afd1304338..6d0831608f3 100644
--- a/chromium/third_party/blink/renderer/core/frame/settings.json5
+++ b/chromium/third_party/blink/renderer/core/frame/settings.json5
@@ -229,6 +229,7 @@
invalidate: "MediaControls",
},
+ // Only affects main thread scrolling
{
name: "scrollAnimatorEnabled",
initial: true,
@@ -551,6 +552,12 @@
initial: false,
},
+ {
+ name: "parserScriptingFlagPolicy",
+ initial: "ParserScriptingFlagPolicy::kOnlyIfScriptIsEnabled",
+ type: "ParserScriptingFlagPolicy"
+ },
+
// Forces Android Overlay Scrollbar for mobile emulator.
{
name: "forceAndroidOverlayScrollbar",
@@ -876,62 +883,62 @@
// Dark mode
//
{
- name: "darkModeEnabled",
+ name: "forceDarkModeEnabled",
initial: false,
- invalidate: "Paint",
+ invalidate: "ForceDark",
},
{
- name: "darkModeInversionAlgorithm",
+ name: "forceDarkModeInversionAlgorithm",
initial: "DarkModeInversionAlgorithm::kInvertLightnessLAB",
type: "DarkModeInversionAlgorithm",
- invalidate: "Paint",
+ invalidate: "ForceDark",
},
{
- name: "darkModeGrayscale",
+ name: "forceDarkModeGrayscale",
initial: false,
- invalidate: "Paint",
+ invalidate: "ForceDark",
},
{
- name: "darkModeContrast",
+ name: "forceDarkModeContrast",
initial: 0,
type: "double",
- invalidate: "Paint",
+ invalidate: "ForceDark",
},
{
- name: "darkModeClassifierType",
+ name: "forceDarkModeClassifierType",
initial: "DarkModeClassifierType::kGeneric",
type: "DarkModeClassifierType",
- invalidate: "Paint",
+ invalidate: "ForceDark",
},
{
- name: "darkModeImagePolicy",
+ name: "forceDarkModeImagePolicy",
initial: "DarkModeImagePolicy::kFilterNone",
type: "DarkModeImagePolicy",
- invalidate: "Paint",
+ invalidate: "ForceDark",
},
{
- name: "darkModePagePolicy",
+ name: "forceDarkModePagePolicy",
initial: "DarkModePagePolicy::kFilterByBackground",
type: "DarkModePagePolicy",
- invalidate: "Paint",
+ invalidate: "ForceDark",
},
{
- name: "darkModeTextBrightnessThreshold",
+ name: "forceDarkModeTextBrightnessThreshold",
initial: "150",
type: "int",
- invalidate: "Paint",
+ invalidate: "ForceDark",
},
{
- name: "darkModeBackgroundBrightnessThreshold",
+ name: "forceDarkModeBackgroundBrightnessThreshold",
initial: "205",
type: "int",
- invalidate: "Paint",
+ invalidate: "ForceDark",
},
{
- name: "darkModeImageGrayscale",
+ name: "forceDarkModeImageGrayscale",
initial: "0.0",
type: "float",
- invalidate: "Paint",
+ invalidate: "ForceDark",
},
{
name: "navigatorPlatformOverride",
@@ -1047,6 +1054,15 @@
type: "int",
},
+ // Preferred color scheme from the OS/application passed to the renderer for
+ // evaluating the prefers-color-scheme media query.
+ {
+ name: "preferredColorScheme",
+ initial: "PreferredColorScheme::kNoPreference",
+ invalidate: "ColorScheme",
+ type: "PreferredColorScheme",
+ },
+
// Preferred motion-reduction setting from the OS/application passed to the
// renderer for evaluating the prefers-reduced-motion media query.
{
diff --git a/chromium/third_party/blink/renderer/core/frame/settings_delegate.h b/chromium/third_party/blink/renderer/core/frame/settings_delegate.h
index 1b0bdcf39b7..cfedb831cd9 100644
--- a/chromium/third_party/blink/renderer/core/frame/settings_delegate.h
+++ b/chromium/third_party/blink/renderer/core/frame/settings_delegate.h
@@ -72,6 +72,8 @@ class CORE_EXPORT SettingsDelegate {
kColorSchemeChange,
kSpatialNavigationChange,
kUniversalAccessChange,
+ kVisionDeficiencyChange,
+ kForceDarkChange,
};
virtual void SettingsChanged(ChangeType) = 0;
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 2aabcdf8351..c863b1b5514 100644
--- a/chromium/third_party/blink/renderer/core/frame/smart_clip.cc
+++ b/chromium/third_party/blink/renderer/core/frame/smart_clip.cc
@@ -163,7 +163,7 @@ Node* SmartClip::FindBestOverlappingNode(Node* root_node,
IntRect node_rect = node->PixelSnappedBoundingBox();
auto* element = DynamicTo<Element>(node);
if (element &&
- DeprecatedEqualIgnoringCase(
+ EqualIgnoringASCIICase(
element->FastGetAttribute(html_names::kAriaHiddenAttr), "true")) {
node = NodeTraversal::NextSkippingChildren(*node, root_node);
continue;
diff --git a/chromium/third_party/blink/renderer/core/frame/smart_clip.h b/chromium/third_party/blink/renderer/core/frame/smart_clip.h
index 638753fa449..a0d1ae71640 100644
--- a/chromium/third_party/blink/renderer/core/frame/smart_clip.h
+++ b/chromium/third_party/blink/renderer/core/frame/smart_clip.h
@@ -80,7 +80,7 @@ class CORE_EXPORT SmartClip {
HeapVector<Member<Node>>& overlapping_node_info_table);
String ExtractTextFromNode(Node*);
- Member<LocalFrame> frame_;
+ LocalFrame* frame_;
};
} // namespace blink
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
new file mode 100644
index 00000000000..17b3b1ab698
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/sticky_frame_tracker.cc
@@ -0,0 +1,93 @@
+// 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
new file mode 100644
index 00000000000..c0807a3bd1b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/sticky_frame_tracker.h
@@ -0,0 +1,63 @@
+// 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
new file mode 100644
index 00000000000..4f5a463382d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/frame/sticky_frame_tracker_test.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 "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/test_report_body.h b/chromium/third_party/blink/renderer/core/frame/test_report_body.h
index 7e60bc8e481..9070bbdcdef 100644
--- a/chromium/third_party/blink/renderer/core/frame/test_report_body.h
+++ b/chromium/third_party/blink/renderer/core/frame/test_report_body.h
@@ -6,11 +6,12 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_TEST_REPORT_BODY_H_
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
+#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/frame/report_body.h"
namespace blink {
-class TestReportBody : public ReportBody {
+class CORE_EXPORT TestReportBody : public ReportBody {
DEFINE_WRAPPERTYPEINFO();
public:
diff --git a/chromium/third_party/blink/renderer/core/frame/user_agent.idl b/chromium/third_party/blink/renderer/core/frame/ua_data_values.idl
index 2223b791477..3def0d4d529 100644
--- a/chromium/third_party/blink/renderer/core/frame/user_agent.idl
+++ b/chromium/third_party/blink/renderer/core/frame/ua_data_values.idl
@@ -3,12 +3,11 @@
// found in the LICENSE file.
// https://github.com/WICG/ua-client-hints
-[
- Exposed=Window
-] dictionary UserAgent {
- DOMString brand = "";
- DOMString version = "";
+
+dictionary UADataValues {
DOMString platform = "";
+ DOMString platformVersion = "";
DOMString architecture = "";
DOMString model = "";
+ DOMString uaFullVersion = "";
};
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 6038cd29c75..d43ec30bcd6 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
@@ -25,6 +25,7 @@
#include "third_party/blink/renderer/core/frame/use_counter_helper.h"
+#include "base/metrics/histogram_macros.h"
#include "third_party/blink/renderer/core/css/css_style_sheet.h"
#include "third_party/blink/renderer/core/css/style_sheet_contents.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -37,7 +38,6 @@
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
@@ -79,24 +79,24 @@ void UseCounterHelper::RecordMeasurement(WebFeature feature,
if (features_recorded_[feature_id])
return;
if (commit_state_ >= kCommited)
- ReportAndTraceMeasurementByFeatureId(feature_id, source_frame);
+ ReportAndTraceMeasurementByFeatureId(feature, source_frame);
features_recorded_.set(feature_id);
}
void UseCounterHelper::ReportAndTraceMeasurementByFeatureId(
- int feature_id,
+ WebFeature feature,
const LocalFrame& source_frame) {
if (context_ != kDisabledContext) {
// Note that HTTPArchive tooling looks specifically for this event -
// see https://github.com/HTTPArchive/httparchive/issues/59
TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.feature_usage"),
- "FeatureFirstUsed", "feature", feature_id);
+ "FeatureFirstUsed", "feature", feature);
if (context_ != kDefaultContext)
- FeaturesHistogram().Count(feature_id);
+ CountFeature(feature);
if (LocalFrameClient* client = source_frame.Client())
- client->DidObserveNewFeatureUsage(static_cast<WebFeature>(feature_id));
- NotifyFeatureCounted(static_cast<WebFeature>(feature_id));
+ client->DidObserveNewFeatureUsage(feature);
+ NotifyFeatureCounted(feature);
}
}
@@ -116,7 +116,7 @@ void UseCounterHelper::ClearMeasurementForTesting(WebFeature feature) {
features_recorded_.reset(static_cast<size_t>(feature));
}
-void UseCounterHelper::Trace(blink::Visitor* visitor) {
+void UseCounterHelper::Trace(Visitor* visitor) {
visitor->Trace(observers_);
}
@@ -134,8 +134,10 @@ void UseCounterHelper::DidCommitLoad(const LocalFrame* frame) {
// browser side.
for (wtf_size_t feature_id = 0; feature_id < features_recorded_.size();
++feature_id) {
- if (features_recorded_[feature_id])
- ReportAndTraceMeasurementByFeatureId(feature_id, *frame);
+ if (features_recorded_[feature_id]) {
+ ReportAndTraceMeasurementByFeatureId(
+ static_cast<WebFeature>(feature_id), *frame);
+ }
}
for (wtf_size_t sample_id = 0; sample_id < css_recorded_.size();
++sample_id) {
@@ -147,7 +149,7 @@ void UseCounterHelper::DidCommitLoad(const LocalFrame* frame) {
// TODO(loonybear): move extension histogram to the browser side.
if (context_ == kExtensionContext || context_ == kFileContext) {
- FeaturesHistogram().Count(static_cast<int>(WebFeature::kPageVisits));
+ CountFeature(WebFeature::kPageVisits);
}
}
}
@@ -236,31 +238,26 @@ void UseCounterHelper::NotifyFeatureCounted(WebFeature feature) {
observers_.RemoveAll(to_be_removed);
}
-EnumerationHistogram& UseCounterHelper::FeaturesHistogram() const {
- DEFINE_STATIC_LOCAL(blink::EnumerationHistogram, extension_histogram,
- ("Blink.UseCounter.Extensions.Features",
- static_cast<int32_t>(WebFeature::kNumberOfFeatures)));
- DEFINE_STATIC_LOCAL(blink::EnumerationHistogram, file_histogram,
- ("Blink.UseCounter.File.Features",
- static_cast<int32_t>(WebFeature::kNumberOfFeatures)));
- // Track what features/properties have been reported to the browser side
- // histogram.
+void UseCounterHelper::CountFeature(WebFeature feature) const {
switch (context_) {
case kDefaultContext:
- // The default features histogram is being recorded on the browser side.
+ // Feature usage for the default context is recorded on the browser side.
+ // TODO(dcheng): Where?
NOTREACHED();
- break;
+ return;
case kExtensionContext:
- return extension_histogram;
+ UMA_HISTOGRAM_ENUMERATION("Blink.UseCounter.Extensions.Features", feature,
+ WebFeature::kNumberOfFeatures);
+ return;
case kFileContext:
- return file_histogram;
+ UMA_HISTOGRAM_ENUMERATION("Blink.UseCounter.File.Features", feature,
+ WebFeature::kNumberOfFeatures);
+ return;
case kDisabledContext:
NOTREACHED();
- break;
+ return;
}
NOTREACHED();
- blink::EnumerationHistogram* null = nullptr;
- return *null;
}
} // namespace blink
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 5b3a64628d1..cf5b705f409 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
@@ -42,7 +42,6 @@ namespace blink {
class DocumentLoader;
class Element;
-class EnumerationHistogram;
class LocalFrame;
// Utility class for muting UseCounter, for instance ignoring attributes
@@ -57,7 +56,7 @@ class UseCounterMuteScope {
~UseCounterMuteScope();
private:
- Member<DocumentLoader> loader_;
+ DocumentLoader* loader_;
};
// This class provides an implementation of UseCounter - see the class comment
@@ -101,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(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
};
// Repeated calls are ignored.
@@ -122,7 +121,7 @@ class CORE_EXPORT UseCounterHelper final {
void UnmuteForInspector();
void RecordMeasurement(WebFeature, const LocalFrame&);
- void ReportAndTraceMeasurementByFeatureId(int, const LocalFrame&);
+ void ReportAndTraceMeasurementByFeatureId(WebFeature, const LocalFrame&);
void ReportAndTraceMeasurementByCSSSampleId(int,
const LocalFrame*,
bool /*is_animated*/);
@@ -134,7 +133,7 @@ class CORE_EXPORT UseCounterHelper final {
void ClearMeasurementForTesting(WebFeature);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
friend class UseCounterHelperTest;
@@ -144,9 +143,7 @@ class CORE_EXPORT UseCounterHelper final {
// if kDisabledContext.
void NotifyFeatureCounted(WebFeature);
- EnumerationHistogram& FeaturesHistogram() const;
- EnumerationHistogram& CssHistogram() const;
- EnumerationHistogram& AnimatedCSSHistogram() const;
+ void CountFeature(WebFeature) const;
// If non-zero, ignore all 'count' calls completely.
unsigned mute_count_;
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 5debc4c1e58..b7e1b3ff789 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
@@ -61,8 +61,7 @@ class UseCounterHelperTest : public testing::Test {
HistogramTester histogram_tester_;
void UpdateAllLifecyclePhases(Document& document) {
- document.View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ document.View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
}
};
@@ -120,7 +119,7 @@ TEST_F(UseCounterHelperTest, CSSSelectorPseudoWhere) {
Document& document = dummy_page_holder->GetDocument();
WebFeature feature = WebFeature::kCSSSelectorPseudoWhere;
EXPECT_FALSE(document.IsUseCounted(feature));
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<style>.a+:where(.b, .c+.d) { color: red; }</style>");
EXPECT_TRUE(document.IsUseCounted(feature));
EXPECT_FALSE(document.IsUseCounted(WebFeature::kCSSSelectorPseudoIs));
@@ -143,7 +142,7 @@ TEST_F(UseCounterHelperTest, CSSSelectorPseudoAnyLink) {
Document& document = dummy_page_holder->GetDocument();
WebFeature feature = WebFeature::kCSSSelectorPseudoAnyLink;
EXPECT_FALSE(document.IsUseCounted(feature));
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<style>:any-link { color: red; }</style>");
EXPECT_TRUE(document.IsUseCounted(feature));
}
@@ -154,7 +153,7 @@ TEST_F(UseCounterHelperTest, CSSSelectorPseudoWebkitAnyLink) {
Document& document = dummy_page_holder->GetDocument();
WebFeature feature = WebFeature::kCSSSelectorPseudoWebkitAnyLink;
EXPECT_FALSE(document.IsUseCounted(feature));
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<style>:-webkit-any-link { color: red; }</style>");
EXPECT_TRUE(document.IsUseCounted(feature));
}
@@ -173,7 +172,7 @@ TEST_F(UseCounterHelperTest, CSSSelectorPseudoIs) {
Document& document = dummy_page_holder->GetDocument();
WebFeature feature = WebFeature::kCSSSelectorPseudoIs;
EXPECT_FALSE(document.IsUseCounted(feature));
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<style>.a+:is(.b, .c+.d) { color: red; }</style>");
EXPECT_TRUE(document.IsUseCounted(feature));
EXPECT_FALSE(document.IsUseCounted(WebFeature::kCSSSelectorPseudoWhere));
@@ -185,7 +184,7 @@ TEST_F(UseCounterHelperTest, CSSContainLayoutNonPositionedDescendants) {
Document& document = dummy_page_holder->GetDocument();
WebFeature feature = WebFeature::kCSSContainLayoutPositionedDescendants;
EXPECT_FALSE(document.IsUseCounted(feature));
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<div style='contain: layout;'>"
"</div>");
UpdateAllLifecyclePhases(document);
@@ -198,7 +197,7 @@ TEST_F(UseCounterHelperTest, CSSContainLayoutAbsolutelyPositionedDescendants) {
Document& document = dummy_page_holder->GetDocument();
WebFeature feature = WebFeature::kCSSContainLayoutPositionedDescendants;
EXPECT_FALSE(document.IsUseCounted(feature));
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<div style='contain: layout;'>"
" <div style='position: absolute;'></div>"
"</div>");
@@ -213,7 +212,7 @@ TEST_F(UseCounterHelperTest,
Document& document = dummy_page_holder->GetDocument();
WebFeature feature = WebFeature::kCSSContainLayoutPositionedDescendants;
EXPECT_FALSE(document.IsUseCounted(feature));
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<div style='position: relative; contain: layout;'>"
" <div style='position: absolute;'></div>"
"</div>");
@@ -227,7 +226,7 @@ TEST_F(UseCounterHelperTest, CSSContainLayoutFixedPositionedDescendants) {
Document& document = dummy_page_holder->GetDocument();
WebFeature feature = WebFeature::kCSSContainLayoutPositionedDescendants;
EXPECT_FALSE(document.IsUseCounted(feature));
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<div style='contain: layout;'>"
" <div style='position: fixed;'></div>"
"</div>");
@@ -242,7 +241,7 @@ TEST_F(UseCounterHelperTest,
Document& document = dummy_page_holder->GetDocument();
WebFeature feature = WebFeature::kCSSContainLayoutPositionedDescendants;
EXPECT_FALSE(document.IsUseCounted(feature));
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<div style='transform: translateX(100px); contain: layout;'>"
" <div style='position: fixed;'></div>"
"</div>");
@@ -256,7 +255,7 @@ TEST_F(UseCounterHelperTest, CSSGridLayoutPercentageColumnIndefiniteWidth) {
Document& document = dummy_page_holder->GetDocument();
WebFeature feature = WebFeature::kGridRowTrackPercentIndefiniteHeight;
EXPECT_FALSE(document.IsUseCounted(feature));
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<div style='display: inline-grid; grid-template-columns: 50%;'>"
"</div>");
UpdateAllLifecyclePhases(document);
@@ -269,7 +268,7 @@ TEST_F(UseCounterHelperTest, CSSGridLayoutPercentageRowIndefiniteHeight) {
Document& document = dummy_page_holder->GetDocument();
WebFeature feature = WebFeature::kGridRowTrackPercentIndefiniteHeight;
EXPECT_FALSE(document.IsUseCounted(feature));
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<div style='display: inline-grid; grid-template-rows: 50%;'>"
"</div>");
UpdateAllLifecyclePhases(document);
@@ -282,7 +281,7 @@ TEST_F(UseCounterHelperTest, CSSFlexibleBox) {
Document& document = dummy_page_holder->GetDocument();
WebFeature feature = WebFeature::kCSSFlexibleBox;
EXPECT_FALSE(document.IsUseCounted(feature));
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<div style='display: flex;'>flexbox</div>");
UpdateAllLifecyclePhases(document);
EXPECT_TRUE(document.IsUseCounted(feature));
@@ -294,7 +293,7 @@ TEST_F(UseCounterHelperTest, CSSFlexibleBoxInline) {
Document& document = dummy_page_holder->GetDocument();
WebFeature feature = WebFeature::kCSSFlexibleBox;
EXPECT_FALSE(document.IsUseCounted(feature));
- document.documentElement()->SetInnerHTMLFromString(
+ document.documentElement()->setInnerHTML(
"<div style='display: inline-flex;'>flexbox</div>");
UpdateAllLifecyclePhases(document);
EXPECT_TRUE(document.IsUseCounted(feature));
@@ -308,7 +307,7 @@ TEST_F(UseCounterHelperTest, CSSFlexibleBoxButton) {
Document& document = dummy_page_holder->GetDocument();
WebFeature feature = WebFeature::kCSSFlexibleBox;
EXPECT_FALSE(document.IsUseCounted(feature));
- document.documentElement()->SetInnerHTMLFromString("<button>button</button>");
+ document.documentElement()->setInnerHTML("<button>button</button>");
UpdateAllLifecyclePhases(document);
EXPECT_FALSE(document.IsUseCounted(feature));
}
@@ -370,7 +369,7 @@ TEST_F(UseCounterHelperTest, CSSUnknownNamespacePrefixInSelector) {
WebFeature feature = WebFeature::kCSSUnknownNamespacePrefixInSelector;
EXPECT_FALSE(document.IsUseCounted(feature));
- document.documentElement()->SetInnerHTMLFromString(R"HTML(
+ document.documentElement()->setInnerHTML(R"HTML(
<style>
@namespace svg url(http://www.w3.org/2000/svg);
svg|a {}
@@ -380,7 +379,7 @@ TEST_F(UseCounterHelperTest, CSSUnknownNamespacePrefixInSelector) {
UpdateAllLifecyclePhases(document);
EXPECT_FALSE(document.IsUseCounted(feature));
- document.documentElement()->SetInnerHTMLFromString("<style>foo|a {}</style>");
+ document.documentElement()->setInnerHTML("<style>foo|a {}</style>");
UpdateAllLifecyclePhases(document);
EXPECT_TRUE(document.IsUseCounted(feature));
}
@@ -391,7 +390,7 @@ TEST_F(UseCounterHelperTest, CSSSelectorHostContextInLiveProfile) {
Document& document = dummy_page_holder->GetDocument();
WebFeature feature = WebFeature::kCSSSelectorHostContextInLiveProfile;
- document.body()->SetInnerHTMLFromString(R"HTML(
+ document.body()->setInnerHTML(R"HTML(
<div id="parent">
<div id="host"></div>
</div>
@@ -404,7 +403,7 @@ TEST_F(UseCounterHelperTest, CSSSelectorHostContextInLiveProfile) {
UpdateAllLifecyclePhases(document);
EXPECT_FALSE(document.IsUseCounted(feature));
- shadow_root.SetInnerHTMLFromString(R"HTML(
+ shadow_root.setInnerHTML(R"HTML(
<style>
:host-context(#parent) span {
color: green
@@ -423,7 +422,7 @@ TEST_F(UseCounterHelperTest, CSSSelectorHostContextInSnapshotProfile) {
Document& document = dummy_page_holder->GetDocument();
WebFeature feature = WebFeature::kCSSSelectorHostContextInSnapshotProfile;
- document.body()->SetInnerHTMLFromString(R"HTML(
+ document.body()->setInnerHTML(R"HTML(
<div id="parent">
<div id="host"></div>
</div>
@@ -436,7 +435,7 @@ TEST_F(UseCounterHelperTest, CSSSelectorHostContextInSnapshotProfile) {
UpdateAllLifecyclePhases(document);
EXPECT_FALSE(document.IsUseCounted(feature));
- shadow_root.SetInnerHTMLFromString("<span></span>");
+ shadow_root.setInnerHTML("<span></span>");
UpdateAllLifecyclePhases(document);
EXPECT_FALSE(document.IsUseCounted(feature));
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 58edb1a9658..e69d1fcb8a6 100644
--- a/chromium/third_party/blink/renderer/core/frame/user_activation.cc
+++ b/chromium/third_party/blink/renderer/core/frame/user_activation.cc
@@ -11,7 +11,7 @@ namespace blink {
UserActivation* UserActivation::CreateSnapshot(LocalDOMWindow* window) {
LocalFrame* frame = window->GetFrame();
return MakeGarbageCollected<UserActivation>(
- frame ? frame->HasBeenActivated() : false,
+ frame ? frame->HasStickyUserActivation() : false,
LocalFrame::HasTransientUserActivation(frame));
}
@@ -22,7 +22,7 @@ UserActivation::UserActivation(LocalDOMWindow* window) : window_(window) {}
UserActivation::~UserActivation() = default;
-void UserActivation::Trace(blink::Visitor* visitor) {
+void UserActivation::Trace(Visitor* visitor) {
visitor->Trace(window_);
ScriptWrappable::Trace(visitor);
}
@@ -31,7 +31,7 @@ bool UserActivation::hasBeenActive() const {
LocalFrame* frame = window_ ? window_->GetFrame() : nullptr;
if (!frame)
return has_been_active_;
- return frame->HasBeenActivated();
+ return frame->HasStickyUserActivation();
}
bool UserActivation::isActive() const {
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 38d24cf1c15..5683c4b1d8e 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
bool hasBeenActive() const;
bool isActive() const;
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 e8ba80bad3e..0d3977949cd 100644
--- a/chromium/third_party/blink/renderer/core/frame/visual_viewport.cc
+++ b/chromium/third_party/blink/renderer/core/frame/visual_viewport.cc
@@ -32,10 +32,11 @@
#include <memory>
+#include "base/metrics/histogram_functions.h"
#include "cc/input/main_thread_scrolling_reason.h"
#include "cc/layers/scrollbar_layer_base.h"
+#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink.h"
#include "third_party/blink/public/platform/task_type.h"
-#include "third_party/blink/public/platform/web_scroll_into_view_params.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/local_frame_view.h"
@@ -67,7 +68,6 @@
#include "third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h"
#include "third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h"
@@ -174,8 +174,9 @@ PaintPropertyChangeType VisualViewport::UpdatePaintPropertyNodesIfNeeded(
}
{
- TransformPaintPropertyNode::State state{
- TransformationMatrix().Scale(Scale())};
+ TransformPaintPropertyNode::State state;
+ if (scale_ != 1.f)
+ state.transform_and_origin = {TransformationMatrix().Scale(scale_)};
state.flags.in_subtree_of_page_scale = false;
state.direct_compositing_reasons = CompositingReason::kWillChangeTransform;
state.compositor_element_id = page_scale_element_id_;
@@ -190,11 +191,8 @@ PaintPropertyChangeType VisualViewport::UpdatePaintPropertyNodesIfNeeded(
// As an optimization, attempt to directly update the compositor
// scale translation node and return kChangedOnlyCompositedValues which
// avoids an expensive PaintArtifactCompositor update.
- // TODO(crbug.com/953322): We need to implement this optimization for
- // CompositeAfterPaint as well.
- if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
- effective_change_type ==
- PaintPropertyChangeType::kChangedOnlySimpleValues) {
+ if (effective_change_type ==
+ PaintPropertyChangeType::kChangedOnlySimpleValues) {
if (auto* paint_artifact_compositor = GetPaintArtifactCompositor()) {
bool updated =
paint_artifact_compositor->DirectlyUpdatePageScaleTransform(
@@ -218,7 +216,6 @@ PaintPropertyChangeType VisualViewport::UpdatePaintPropertyNodesIfNeeded(
state.user_scrollable_horizontal =
UserInputScrollable(kHorizontalScrollbar);
state.user_scrollable_vertical = UserInputScrollable(kVerticalScrollbar);
- state.scrolls_inner_viewport = true;
state.max_scroll_offset_affected_by_page_scale = true;
state.compositor_element_id = GetScrollElementId();
@@ -273,11 +270,8 @@ PaintPropertyChangeType VisualViewport::UpdatePaintPropertyNodesIfNeeded(
// As an optimization, attempt to directly update the compositor
// translation node and return kChangedOnlyCompositedValues which avoids
// an expensive PaintArtifactCompositor update.
- // TODO(crbug.com/953322): We need to implement this optimization for
- // CompositeAfterPaint as well.
- if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
- effective_change_type ==
- PaintPropertyChangeType::kChangedOnlySimpleValues) {
+ if (effective_change_type ==
+ PaintPropertyChangeType::kChangedOnlySimpleValues) {
if (auto* paint_artifact_compositor = GetPaintArtifactCompositor()) {
bool updated =
paint_artifact_compositor->DirectlyUpdateScrollOffsetTransform(
@@ -341,17 +335,17 @@ VisualViewport::~VisualViewport() {
SendUMAMetrics();
}
-void VisualViewport::Trace(blink::Visitor* visitor) {
+void VisualViewport::Trace(Visitor* visitor) {
visitor->Trace(page_);
ScrollableArea::Trace(visitor);
}
-void VisualViewport::UpdateStyleAndLayout() const {
+void VisualViewport::UpdateStyleAndLayout(DocumentUpdateReason reason) const {
if (!MainFrame())
return;
if (Document* document = MainFrame()->GetDocument())
- document->UpdateStyleAndLayout();
+ document->UpdateStyleAndLayout(reason);
}
void VisualViewport::EnqueueScrollEvent() {
@@ -442,7 +436,7 @@ double VisualViewport::OffsetLeft() const {
if (!MainFrame())
return 0;
- UpdateStyleAndLayout();
+ UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
return VisibleRect().X() / MainFrame()->PageZoomFactor();
}
@@ -451,18 +445,18 @@ double VisualViewport::OffsetTop() const {
if (!MainFrame())
return 0;
- UpdateStyleAndLayout();
+ UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
return VisibleRect().Y() / MainFrame()->PageZoomFactor();
}
double VisualViewport::Width() const {
- UpdateStyleAndLayout();
+ UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
return VisibleWidthCSSPx();
}
double VisualViewport::Height() const {
- UpdateStyleAndLayout();
+ UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
return VisibleHeightCSSPx();
}
@@ -545,7 +539,7 @@ bool VisualViewport::DidSetScaleOrLocation(float scale,
// ScrollingCoordinator.
if (auto* coordinator = GetPage().GetScrollingCoordinator()) {
if (scroll_layer_)
- coordinator->UpdateCompositedScrollOffset(this);
+ coordinator->UpdateCompositorScrollOffset(*MainFrame(), *this);
}
EnqueueScrollEvent();
@@ -557,9 +551,6 @@ bool VisualViewport::DidSetScaleOrLocation(float scale,
if (!values_changed)
return false;
- MainFrame()->GetEventHandler().MayUpdateHoverWhenContentUnderMouseChanged(
- MouseEventManager::UpdateHoverReason::kScrollOffsetChanged);
-
probe::DidChangeViewport(MainFrame());
MainFrame()->Loader().SaveScrollState();
@@ -597,7 +588,7 @@ void VisualViewport::CreateLayers() {
LayerForScrollingDidChange(coordinator->GetCompositorAnimationTimeline());
InitializeScrollbars();
- coordinator->UpdateCompositedScrollOffset(this);
+ coordinator->UpdateCompositorScrollOffset(*MainFrame(), *this);
}
void VisualViewport::InitializeScrollbars() {
@@ -690,10 +681,11 @@ SmoothScrollSequencer* VisualViewport::GetSmoothScrollSequencer() const {
return &MainFrame()->GetSmoothScrollSequencer();
}
-void VisualViewport::SetScrollOffset(const ScrollOffset& offset,
- ScrollType scroll_type,
- ScrollBehavior scroll_behavior,
- ScrollCallback on_finish) {
+void VisualViewport::SetScrollOffset(
+ const ScrollOffset& offset,
+ mojom::blink::ScrollType scroll_type,
+ mojom::blink::ScrollBehavior scroll_behavior,
+ ScrollCallback on_finish) {
// We clamp the offset here, because the ScrollAnimator may otherwise be
// set to a non-clamped offset by ScrollableArea::setScrollOffset,
// which may lead to incorrect scrolling behavior in RootFrameViewport down
@@ -707,26 +699,32 @@ void VisualViewport::SetScrollOffset(const ScrollOffset& offset,
scroll_behavior, std::move(on_finish));
}
+void VisualViewport::SetScrollOffset(
+ const ScrollOffset& offset,
+ mojom::blink::ScrollType scroll_type,
+ mojom::blink::ScrollBehavior scroll_behavior) {
+ SetScrollOffset(offset, scroll_type, scroll_behavior, ScrollCallback());
+}
+
PhysicalRect VisualViewport::ScrollIntoView(
const PhysicalRect& rect_in_absolute,
- const WebScrollIntoViewParams& params) {
+ const mojom::blink::ScrollIntoViewParamsPtr& params) {
PhysicalRect scroll_snapport_rect = VisibleScrollSnapportRect();
ScrollOffset new_scroll_offset =
ClampScrollOffset(ScrollAlignment::GetScrollOffsetToExpose(
- scroll_snapport_rect, rect_in_absolute, params.GetScrollAlignmentX(),
- params.GetScrollAlignmentY(), GetScrollOffset()));
+ scroll_snapport_rect, rect_in_absolute, *params->align_x.get(),
+ *params->align_y.get(), GetScrollOffset()));
if (new_scroll_offset != GetScrollOffset()) {
- ScrollBehavior behavior = params.GetScrollBehavior();
- if (params.is_for_scroll_sequence) {
- DCHECK(params.GetScrollType() == kProgrammaticScroll ||
- params.GetScrollType() == kUserScroll);
+ if (params->is_for_scroll_sequence) {
+ DCHECK(params->type == mojom::blink::ScrollType::kProgrammatic ||
+ params->type == mojom::blink::ScrollType::kUser);
if (SmoothScrollSequencer* sequencer = GetSmoothScrollSequencer()) {
- sequencer->QueueAnimation(this, new_scroll_offset, behavior);
+ sequencer->QueueAnimation(this, new_scroll_offset, params->behavior);
}
} else {
- SetScrollOffset(new_scroll_offset, params.GetScrollType(), behavior,
+ SetScrollOffset(new_scroll_offset, params->type, params->behavior,
ScrollCallback());
}
}
@@ -850,14 +848,14 @@ WebColorScheme VisualViewport::UsedColorScheme() const {
}
void VisualViewport::UpdateScrollOffset(const ScrollOffset& position,
- ScrollType scroll_type) {
+ mojom::blink::ScrollType scroll_type) {
if (!DidSetScaleOrLocation(scale_, is_pinch_gesture_active_,
FloatPoint(position))) {
return;
}
if (IsExplicitScrollType(scroll_type)) {
NotifyRootFrameViewport();
- if (scroll_type != kCompositorScroll && scroll_layer_)
+ if (scroll_type != mojom::blink::ScrollType::kCompositor && scroll_layer_)
scroll_layer_->ShowScrollbars();
}
}
@@ -988,20 +986,16 @@ void VisualViewport::SendUMAMetrics() {
if (track_pinch_zoom_stats_for_page_) {
bool did_scale = max_page_scale_ > 0;
- DEFINE_STATIC_LOCAL(EnumerationHistogram, did_scale_histogram,
- ("Viewport.DidScalePage", 2));
- did_scale_histogram.Count(did_scale ? 1 : 0);
+ base::UmaHistogramBoolean("Viewport.DidScalePage", did_scale);
if (did_scale) {
int zoom_percentage = floor(max_page_scale_ * 100);
- // See the PageScaleFactor enumeration in histograms.xml for the bucket
- // ranges.
+ // Note: while defined as an exact linear histogram with 21 buckets here,
+ // the UMA itself is tagged as an enumeration (PageScaleFactor) in
+ // histograms.xml to make it easy to identify the buckets...
int bucket = floor(zoom_percentage / 25.f);
-
- DEFINE_STATIC_LOCAL(EnumerationHistogram, max_scale_histogram,
- ("Viewport.MaxPageScale", 21));
- max_scale_histogram.Count(bucket);
+ base::UmaHistogramExactLinear("Viewport.MaxPageScale", bucket, 21);
}
}
@@ -1093,7 +1087,7 @@ void VisualViewport::Paint(GraphicsContext& context) const {
("Inner Viewport Scroll Layer"));
RecordForeignLayer(context, debug_name_client,
DisplayItem::kForeignLayerViewportScroll, scroll_layer_,
- FloatPoint(), state);
+ FloatPoint(), &state);
}
if (scrollbar_layer_horizontal_) {
@@ -1104,7 +1098,7 @@ void VisualViewport::Paint(GraphicsContext& context) const {
RecordForeignLayer(
context, debug_name_client, DisplayItem::kForeignLayerViewportScrollbar,
scrollbar_layer_horizontal_,
- FloatPoint(0, size_.Height() - ScrollbarThickness()), state);
+ FloatPoint(0, size_.Height() - ScrollbarThickness()), &state);
}
if (scrollbar_layer_vertical_) {
@@ -1115,7 +1109,7 @@ void VisualViewport::Paint(GraphicsContext& context) const {
RecordForeignLayer(
context, debug_name_client, DisplayItem::kForeignLayerViewportScrollbar,
scrollbar_layer_vertical_,
- FloatPoint(size_.Width() - ScrollbarThickness(), 0), state);
+ FloatPoint(size_.Width() - ScrollbarThickness(), 0), &state);
}
}
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 eb4cc33d9b3..d2cdb057951 100644
--- a/chromium/third_party/blink/renderer/core/frame/visual_viewport.h
+++ b/chromium/third_party/blink/renderer/core/frame/visual_viewport.h
@@ -34,8 +34,10 @@
#include <memory>
#include "base/single_thread_task_runner.h"
+#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink-forward.h"
#include "third_party/blink/public/platform/web_size.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.h"
#include "third_party/blink/renderer/core/scroll/scroll_types.h"
#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
@@ -92,16 +94,15 @@ struct PaintPropertyTreeBuilderFragmentContext;
// +- horizontal_scrollbar_effect_node_
// +- vertical_scrollbar_effect_node_
//
-class CORE_EXPORT VisualViewport final
- : public GarbageCollected<VisualViewport>,
- public ScrollableArea {
+class CORE_EXPORT VisualViewport : public GarbageCollected<VisualViewport>,
+ public ScrollableArea {
USING_GARBAGE_COLLECTED_MIXIN(VisualViewport);
public:
explicit VisualViewport(Page&);
~VisualViewport() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void InitializeScrollbars();
@@ -175,11 +176,16 @@ class CORE_EXPORT VisualViewport final
ChromeClient* GetChromeClient() const override;
SmoothScrollSequencer* GetSmoothScrollSequencer() const override;
void SetScrollOffset(const ScrollOffset&,
- ScrollType,
- ScrollBehavior,
+ mojom::blink::ScrollType,
+ mojom::blink::ScrollBehavior,
ScrollCallback on_finish) override;
- PhysicalRect ScrollIntoView(const PhysicalRect&,
- const WebScrollIntoViewParams&) override;
+ void SetScrollOffset(const ScrollOffset&,
+ mojom::blink::ScrollType,
+ mojom::blink::ScrollBehavior =
+ mojom::blink::ScrollBehavior::kInstant) override;
+ PhysicalRect ScrollIntoView(
+ const PhysicalRect&,
+ const mojom::blink::ScrollIntoViewParamsPtr&) override;
bool IsThrottled() const override {
// VisualViewport is always in the main frame, so the frame does not get
// throttled.
@@ -204,7 +210,8 @@ class CORE_EXPORT VisualViewport final
CompositorElementId GetScrollElementId() const override;
bool ScrollAnimatorEnabled() const override;
void ScrollControlWasSetNeedsPaintInvalidation() override {}
- void UpdateScrollOffset(const ScrollOffset&, ScrollType) override;
+ void UpdateScrollOffset(const ScrollOffset&,
+ mojom::blink::ScrollType) override;
cc::Layer* LayerForScrolling() const override;
cc::Layer* LayerForHorizontalScrollbar() const override;
cc::Layer* LayerForVerticalScrollbar() const override;
@@ -213,7 +220,8 @@ class CORE_EXPORT VisualViewport final
CompositorAnimationTimeline* GetCompositorAnimationTimeline() const override;
IntRect VisibleContentRect(
IncludeScrollbarsInRect = kExcludeScrollbars) const override;
- scoped_refptr<base::SingleThreadTaskRunner> GetTimerTaskRunner() const final;
+ scoped_refptr<base::SingleThreadTaskRunner> GetTimerTaskRunner()
+ const override;
WebColorScheme UsedColorScheme() const override;
// VisualViewport scrolling may involve pinch zoom and gets routed through
@@ -271,7 +279,7 @@ class CORE_EXPORT VisualViewport final
const FloatPoint& location);
void CreateLayers();
- void UpdateStyleAndLayout() const;
+ void UpdateStyleAndLayout(DocumentUpdateReason) const;
void EnqueueScrollEvent();
void EnqueueResizeEvent();
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 dc25cd71c75..c0d594da78d 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
@@ -13,10 +13,9 @@
#include "cc/trees/transform_node.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/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/public/platform/web_coalesced_input_event.h"
-#include "third_party/blink/public/platform/web_input_event.h"
-#include "third_party/blink/public/platform/web_scroll_into_view_params.h"
#include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
#include "third_party/blink/public/web/web_ax_context.h"
#include "third_party/blink/public/web/web_context_menu_data.h"
@@ -72,8 +71,8 @@ using blink::url_test_helpers::ToKURL;
namespace blink {
::std::ostream& operator<<(::std::ostream& os, const WebContextMenuData& data) {
- return os << "Context menu location: [" << data.mouse_position.x << ", "
- << data.mouse_position.y << "]";
+ return os << "Context menu location: [" << data.mouse_position.x() << ", "
+ << data.mouse_position.y() << "]";
}
namespace {
@@ -122,13 +121,12 @@ class VisualViewportTest : public testing::Test,
void UpdateAllLifecyclePhases() {
WebView()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
}
void UpdateAllLifecyclePhasesExceptPaint() {
- WebView()->MainFrameWidget()->UpdateLifecycle(
- WebWidget::LifecycleUpdate::kPrePaint,
- WebWidget::LifecycleUpdateReason::kTest);
+ WebView()->MainFrameWidget()->UpdateLifecycle(WebLifecycleUpdate::kPrePaint,
+ DocumentUpdateReason::kTest);
}
PaintArtifactCompositor* paint_artifact_compositor() {
@@ -240,7 +238,9 @@ INSTANTIATE_PAINT_TEST_SUITE_P(VisualViewportTest);
// WebView resizes the VisualViewport.
TEST_P(VisualViewportTest, TestResize) {
InitializeWithDesktopSettings();
- WebView()->MainFrameWidget()->Resize(IntSize(320, 240));
+ WebView()->ResizeWithBrowserControls(
+ IntSize(320, 240), IntSize(320, 240),
+ WebView()->GetBrowserControls().Params());
NavigateTo("about:blank");
ForceFullCompositingUpdate();
@@ -254,7 +254,8 @@ TEST_P(VisualViewportTest, TestResize) {
// Resizing the WebView should change the VisualViewport.
web_view_size = IntSize(640, 480);
- WebView()->MainFrameWidget()->Resize(web_view_size);
+ WebView()->ResizeWithBrowserControls(
+ web_view_size, web_view_size, WebView()->GetBrowserControls().Params());
EXPECT_EQ(web_view_size, IntSize(WebView()->MainFrameWidget()->Size()));
EXPECT_EQ(web_view_size, visual_viewport.Size());
@@ -278,7 +279,8 @@ TEST_P(VisualViewportTest, TestVisibleContentRect) {
// Vertical scrollbar width and horizontal scrollbar height.
IntSize scrollbar_size = IntSize(15, 15);
- WebView()->MainFrameWidget()->Resize(size);
+ WebView()->ResizeWithBrowserControls(
+ size, size, WebView()->GetBrowserControls().Params());
// Scroll layout viewport and verify visibleContentRect.
WebView()->MainFrameImpl()->SetScrollOffset(WebSize(0, 50));
@@ -308,7 +310,9 @@ TEST_P(VisualViewportTest, TestVisibleContentRect) {
// make it appear to stay still). This caused bugs like crbug.com/453859.
TEST_P(VisualViewportTest, TestResizeAtFullyScrolledPreservesViewportLocation) {
InitializeWithDesktopSettings();
- WebView()->MainFrameWidget()->Resize(IntSize(800, 600));
+ WebView()->ResizeWithBrowserControls(
+ IntSize(800, 600), IntSize(800, 600),
+ WebView()->GetBrowserControls().Params());
RegisterMockedHttpURLLoad("content-width-1000.html");
NavigateTo(base_url_ + "content-width-1000.html");
@@ -319,8 +323,8 @@ TEST_P(VisualViewportTest, TestResizeAtFullyScrolledPreservesViewportLocation) {
visual_viewport.SetScale(2);
// Fully scroll both viewports.
- frame_view.LayoutViewport()->SetScrollOffset(ScrollOffset(10000, 10000),
- kProgrammaticScroll);
+ frame_view.LayoutViewport()->SetScrollOffset(
+ ScrollOffset(10000, 10000), mojom::blink::ScrollType::kProgrammatic);
visual_viewport.Move(FloatSize(10000, 10000));
// Sanity check.
@@ -334,12 +338,16 @@ TEST_P(VisualViewportTest, TestResizeAtFullyScrolledPreservesViewportLocation) {
// Shrink the WebView, this should cause both viewports to shrink and
// WebView should do whatever it needs to do to preserve the visible
// location.
- WebView()->MainFrameWidget()->Resize(IntSize(700, 550));
+ WebView()->ResizeWithBrowserControls(
+ IntSize(700, 550), IntSize(800, 600),
+ WebView()->GetBrowserControls().Params());
EXPECT_EQ(expected_location,
frame_view.GetScrollableArea()->VisibleContentRect().Location());
- WebView()->MainFrameWidget()->Resize(IntSize(800, 600));
+ WebView()->ResizeWithBrowserControls(
+ IntSize(800, 600), IntSize(800, 600),
+ WebView()->GetBrowserControls().Params());
EXPECT_EQ(expected_location,
frame_view.GetScrollableArea()->VisibleContentRect().Location());
@@ -581,10 +589,10 @@ TEST_P(VisualViewportTest, TestFractionalScrollOffsetIsNotOverwritten) {
NavigateTo(base_url_ + "200-by-800-viewport.html");
LocalFrameView& frame_view = *WebView()->MainFrameImpl()->GetFrameView();
- frame_view.LayoutViewport()->SetScrollOffset(ScrollOffset(0, 10.5),
- kProgrammaticScroll);
+ frame_view.LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 10.5), mojom::blink::ScrollType::kProgrammatic);
frame_view.LayoutViewport()->ScrollableArea::SetScrollOffset(
- ScrollOffset(10, 30.5), kCompositorScroll);
+ ScrollOffset(10, 30.5), mojom::blink::ScrollType::kCompositor);
EXPECT_EQ(30.5, frame_view.LayoutViewport()->GetScrollOffset().Height());
}
@@ -885,7 +893,7 @@ TEST_P(VisualViewportTest, TestTextSelectionHandles) {
NavigateTo(base_url_ + "pinch-viewport-input-field.html");
VisualViewport& visual_viewport = GetFrame()->GetPage()->GetVisualViewport();
- WebView()->SetInitialFocus(false);
+ To<LocalFrame>(WebView()->GetPage()->MainFrame())->SetInitialFocus(false);
WebRect original_anchor;
WebRect original_focus;
@@ -960,12 +968,12 @@ TEST_P(VisualViewportTest, TestRestoredFromHistoryItem) {
WebURL destination_url(
url_test_helpers::ToKURL(base_url_ + "200-by-300.html"));
item.SetURLString(destination_url.GetString());
- item.SetVisualViewportScrollOffset(WebFloatPoint(100, 120));
+ item.SetVisualViewportScrollOffset(gfx::PointF(100, 120));
item.SetPageScaleFactor(2);
frame_test_helpers::LoadHistoryItem(WebView()->MainFrameImpl(), item,
mojom::FetchCacheMode::kDefault);
-
+ UpdateAllLifecyclePhases();
VisualViewport& visual_viewport = GetFrame()->GetPage()->GetVisualViewport();
EXPECT_EQ(2, visual_viewport.Scale());
@@ -989,13 +997,13 @@ TEST_P(VisualViewportTest, TestRestoredFromLegacyHistoryItem) {
item.SetURLString(destination_url.GetString());
// (-1, -1) will be used if the HistoryItem is an older version prior to
// having visual viewport scroll offset.
- item.SetVisualViewportScrollOffset(WebFloatPoint(-1, -1));
- item.SetScrollOffset(WebPoint(120, 180));
+ item.SetVisualViewportScrollOffset(gfx::PointF(-1, -1));
+ item.SetScrollOffset(gfx::Point(120, 180));
item.SetPageScaleFactor(2);
frame_test_helpers::LoadHistoryItem(WebView()->MainFrameImpl(), item,
mojom::FetchCacheMode::kDefault);
-
+ UpdateAllLifecyclePhases();
VisualViewport& visual_viewport = GetFrame()->GetPage()->GetVisualViewport();
EXPECT_EQ(2, visual_viewport.Scale());
EXPECT_EQ(ScrollOffset(100, 150),
@@ -1016,8 +1024,8 @@ TEST_P(VisualViewportTest,
NavigateTo(base_url_ + "content-width-1000.html");
LocalFrameView* frame_view = WebView()->MainFrameImpl()->GetFrameView();
- frame_view->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 1000),
- kProgrammaticScroll);
+ frame_view->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 1000), mojom::blink::ScrollType::kProgrammatic);
EXPECT_EQ(IntSize(1000, 1000), frame_view->FrameRect().Size());
@@ -1072,8 +1080,8 @@ TEST_P(VisualViewportTest,
EXPECT_EQ("ir", mainFrame->SelectionAsText().Utf8());
WebView()->MainFrameWidget()->SelectionBounds(base_rect, extent_rect);
- WebPoint initialPoint(base_rect.x, base_rect.y);
- WebPoint endPoint(extent_rect.x, extent_rect.y);
+ gfx::Point initialPoint(base_rect.x, base_rect.y);
+ gfx::Point endPoint(extent_rect.x, extent_rect.y);
// Move the visual viewport over and make the selection in the same
// screen-space location. The selection should change to two characters to the
@@ -1115,7 +1123,7 @@ MATCHER_P2(ContextMenuAtLocation,
y,
std::string(negation ? "is" : "isn't") + " at expected location [" +
PrintToString(x) + ", " + PrintToString(y) + "]") {
- return arg.mouse_position.x == x && arg.mouse_position.y == y;
+ return arg.mouse_position.x() == x && arg.mouse_position.y() == y;
}
// Test that the context menu's location is correct in the presence of visual
@@ -1143,8 +1151,8 @@ TEST_P(VisualViewportTest, TestContextMenuShownInCorrectLocation) {
VisualViewportMockWebFrameClient mock_web_frame_client;
EXPECT_CALL(mock_web_frame_client,
ShowContextMenu(ContextMenuAtLocation(
- mouse_down_event.PositionInWidget().x,
- mouse_down_event.PositionInWidget().y)));
+ mouse_down_event.PositionInWidget().x(),
+ mouse_down_event.PositionInWidget().y())));
// Do a sanity check with no scale applied.
WebView()->MainFrameImpl()->SetClient(&mock_web_frame_client);
@@ -1166,8 +1174,8 @@ TEST_P(VisualViewportTest, TestContextMenuShownInCorrectLocation) {
visual_viewport.SetLocation(FloatPoint(60, 80));
EXPECT_CALL(mock_web_frame_client,
ShowContextMenu(ContextMenuAtLocation(
- mouse_down_event.PositionInWidget().x,
- mouse_down_event.PositionInWidget().y)));
+ mouse_down_event.PositionInWidget().x(),
+ mouse_down_event.PositionInWidget().y())));
mouse_down_event.button = WebMouseEvent::Button::kRight;
WebView()->MainFrameWidget()->HandleInputEvent(
@@ -1230,9 +1238,9 @@ TEST_P(VisualViewportTest, ScrollIntoViewFractionalOffset) {
// The element is already in the view so the scrollIntoView shouldn't move
// the viewport at all.
- WebView()->SetVisualViewportOffset(WebFloatPoint(250.25f, 100.25f));
- layout_viewport_scrollable_area->SetScrollOffset(ScrollOffset(0, 900.75),
- kProgrammaticScroll);
+ WebView()->SetVisualViewportOffset(gfx::PointF(250.25f, 100.25f));
+ layout_viewport_scrollable_area->SetScrollOffset(
+ ScrollOffset(0, 900.75), mojom::blink::ScrollType::kProgrammatic);
inputBox->scrollIntoViewIfNeeded(false);
if (RuntimeEnabledFeatures::FractionalScrollOffsetsEnabled()) {
@@ -1245,8 +1253,8 @@ TEST_P(VisualViewportTest, ScrollIntoViewFractionalOffset) {
EXPECT_EQ(FloatSize(250.25f, 100.25f), visual_viewport.GetScrollOffset());
// Change the fractional part of the frameview to one that would round down.
- layout_viewport_scrollable_area->SetScrollOffset(ScrollOffset(0, 900.125),
- kProgrammaticScroll);
+ layout_viewport_scrollable_area->SetScrollOffset(
+ ScrollOffset(0, 900.125), mojom::blink::ScrollType::kProgrammatic);
inputBox->scrollIntoViewIfNeeded(false);
if (RuntimeEnabledFeatures::FractionalScrollOffsetsEnabled()) {
@@ -1259,9 +1267,9 @@ TEST_P(VisualViewportTest, ScrollIntoViewFractionalOffset) {
EXPECT_EQ(FloatSize(250.25f, 100.25f), visual_viewport.GetScrollOffset());
// Repeat both tests above with the visual viewport at a high fractional.
- WebView()->SetVisualViewportOffset(WebFloatPoint(250.875f, 100.875f));
- layout_viewport_scrollable_area->SetScrollOffset(ScrollOffset(0, 900.75),
- kProgrammaticScroll);
+ WebView()->SetVisualViewportOffset(gfx::PointF(250.875f, 100.875f));
+ layout_viewport_scrollable_area->SetScrollOffset(
+ ScrollOffset(0, 900.75), mojom::blink::ScrollType::kProgrammatic);
inputBox->scrollIntoViewIfNeeded(false);
if (RuntimeEnabledFeatures::FractionalScrollOffsetsEnabled()) {
@@ -1274,8 +1282,8 @@ TEST_P(VisualViewportTest, ScrollIntoViewFractionalOffset) {
EXPECT_EQ(FloatSize(250.875f, 100.875f), visual_viewport.GetScrollOffset());
// Change the fractional part of the frameview to one that would round down.
- layout_viewport_scrollable_area->SetScrollOffset(ScrollOffset(0, 900.125),
- kProgrammaticScroll);
+ layout_viewport_scrollable_area->SetScrollOffset(
+ ScrollOffset(0, 900.125), mojom::blink::ScrollType::kProgrammatic);
inputBox->scrollIntoViewIfNeeded(false);
if (RuntimeEnabledFeatures::FractionalScrollOffsetsEnabled()) {
@@ -1288,9 +1296,9 @@ TEST_P(VisualViewportTest, ScrollIntoViewFractionalOffset) {
EXPECT_EQ(FloatSize(250.875f, 100.875f), visual_viewport.GetScrollOffset());
// Both viewports with a 0.5 fraction.
- WebView()->SetVisualViewportOffset(WebFloatPoint(250.5f, 100.5f));
- layout_viewport_scrollable_area->SetScrollOffset(ScrollOffset(0, 900.5),
- kProgrammaticScroll);
+ WebView()->SetVisualViewportOffset(gfx::PointF(250.5f, 100.5f));
+ layout_viewport_scrollable_area->SetScrollOffset(
+ ScrollOffset(0, 900.5), mojom::blink::ScrollType::kProgrammatic);
inputBox->scrollIntoViewIfNeeded(false);
if (RuntimeEnabledFeatures::FractionalScrollOffsetsEnabled()) {
@@ -1330,7 +1338,7 @@ TEST_P(VisualViewportTest, TestBrowserControlsAdjustment) {
EXPECT_EQ(IntSize(1000, 900), frame_view.FrameRect().Size());
// Simulate bringing down the browser controls by 20px.
- WebView()->MainFrameWidget()->ApplyViewportChanges(
+ WebView()->MainFrameWidget()->ApplyViewportChangesForTesting(
{gfx::ScrollOffset(), gfx::Vector2dF(), 1, false, 1, 0,
cc::BrowserControlsState::kBoth});
EXPECT_EQ(FloatSize(500, 430), visual_viewport.VisibleRect().Size());
@@ -1344,12 +1352,12 @@ TEST_P(VisualViewportTest, TestBrowserControlsAdjustment) {
// The outer viewport (LocalFrameView) should be affected as well.
frame_view.LayoutViewport()->ScrollBy(ScrollOffset(10000, 10000),
- kUserScroll);
+ mojom::blink::ScrollType::kUser);
EXPECT_EQ(expectedMaxLayoutViewportScrollOffset(visual_viewport, frame_view),
frame_view.LayoutViewport()->GetScrollOffset());
// Simulate bringing up the browser controls by 10.5px.
- WebView()->MainFrameWidget()->ApplyViewportChanges(
+ WebView()->MainFrameWidget()->ApplyViewportChangesForTesting(
{gfx::ScrollOffset(), gfx::Vector2dF(), 1, false, -10.5f / 20, 0,
cc::BrowserControlsState::kBoth});
EXPECT_FLOAT_SIZE_EQ(FloatSize(500, 440.5f),
@@ -1362,7 +1370,7 @@ TEST_P(VisualViewportTest, TestBrowserControlsAdjustment) {
// The outer viewport (LocalFrameView) should be affected as well.
frame_view.LayoutViewport()->ScrollBy(ScrollOffset(10000, 10000),
- kUserScroll);
+ mojom::blink::ScrollType::kUser);
EXPECT_EQ(expectedMaxLayoutViewportScrollOffset(visual_viewport, frame_view),
frame_view.LayoutViewport()->GetScrollOffset());
}
@@ -1385,7 +1393,7 @@ TEST_P(VisualViewportTest, TestBrowserControlsAdjustmentWithScale) {
// Simulate bringing down the browser controls by 20px. Since we're zoomed in,
// the browser controls take up half as much space (in document-space) than
// they do at an unzoomed level.
- WebView()->MainFrameWidget()->ApplyViewportChanges(
+ WebView()->MainFrameWidget()->ApplyViewportChangesForTesting(
{gfx::ScrollOffset(), gfx::Vector2dF(), 1, false, 1, 0,
cc::BrowserControlsState::kBoth});
EXPECT_EQ(FloatSize(250, 215), visual_viewport.VisibleRect().Size());
@@ -1396,20 +1404,20 @@ TEST_P(VisualViewportTest, TestBrowserControlsAdjustmentWithScale) {
// The outer viewport (LocalFrameView) should be affected as well.
frame_view.LayoutViewport()->ScrollBy(ScrollOffset(10000, 10000),
- kUserScroll);
+ mojom::blink::ScrollType::kUser);
ScrollOffset expected =
expectedMaxLayoutViewportScrollOffset(visual_viewport, frame_view);
EXPECT_EQ(expected, frame_view.LayoutViewport()->GetScrollOffset());
// Scale back out, LocalFrameView max scroll shouldn't have changed. Visual
- // viewport should be moved up to accomodate larger view.
- WebView()->MainFrameWidget()->ApplyViewportChanges(
+ // viewport should be moved up to accommodate larger view.
+ WebView()->MainFrameWidget()->ApplyViewportChangesForTesting(
{gfx::ScrollOffset(), gfx::Vector2dF(), 0.5f, false, 0, 0,
cc::BrowserControlsState::kBoth});
EXPECT_EQ(1, visual_viewport.Scale());
EXPECT_EQ(expected, frame_view.LayoutViewport()->GetScrollOffset());
frame_view.LayoutViewport()->ScrollBy(ScrollOffset(10000, 10000),
- kUserScroll);
+ mojom::blink::ScrollType::kUser);
EXPECT_EQ(expected, frame_view.LayoutViewport()->GetScrollOffset());
EXPECT_EQ(FloatSize(500, 860 - 430), visual_viewport.GetScrollOffset());
@@ -1417,13 +1425,13 @@ TEST_P(VisualViewportTest, TestBrowserControlsAdjustmentWithScale) {
EXPECT_EQ(FloatSize(500, 860 - 430), visual_viewport.GetScrollOffset());
// Scale out, use a scale that causes fractional rects.
- WebView()->MainFrameWidget()->ApplyViewportChanges(
+ WebView()->MainFrameWidget()->ApplyViewportChangesForTesting(
{gfx::ScrollOffset(), gfx::Vector2dF(), 0.8f, false, -1, 0,
cc::BrowserControlsState::kBoth});
EXPECT_EQ(FloatSize(625, 562.5), visual_viewport.VisibleRect().Size());
// Bring out the browser controls by 11
- WebView()->MainFrameWidget()->ApplyViewportChanges(
+ WebView()->MainFrameWidget()->ApplyViewportChangesForTesting(
{gfx::ScrollOffset(), gfx::Vector2dF(), 1, false, 11 / 20.f, 0,
cc::BrowserControlsState::kBoth});
EXPECT_EQ(FloatSize(625, 548.75), visual_viewport.VisibleRect().Size());
@@ -1434,7 +1442,7 @@ TEST_P(VisualViewportTest, TestBrowserControlsAdjustmentWithScale) {
visual_viewport.GetScrollOffset());
frame_view.LayoutViewport()->ScrollBy(ScrollOffset(10000, 10000),
- kUserScroll);
+ mojom::blink::ScrollType::kUser);
EXPECT_EQ(expectedMaxLayoutViewportScrollOffset(visual_viewport, frame_view),
frame_view.LayoutViewport()->GetScrollOffset());
}
@@ -1452,9 +1460,15 @@ TEST_P(VisualViewportTest, TestBrowserControlsAdjustmentAndResize) {
InitializeWithAndroidSettings();
// Initialize with browser controls showing and shrinking the Blink size.
+ cc::BrowserControlsParams controls;
+ controls.top_controls_height = browser_controls_height;
+ controls.browser_controls_shrink_blink_size = true;
+ // TODO(danakj): The browser (RenderWidgetHostImpl) doesn't shrink the widget
+ // size by the browser controls, only the visible_viewport_size, but this test
+ // shrinks and grows both.
WebView()->ResizeWithBrowserControls(
- WebSize(500, visual_viewport_height - browser_controls_height), 20, 0,
- true);
+ WebSize(500, visual_viewport_height - browser_controls_height),
+ WebSize(500, visual_viewport_height - browser_controls_height), controls);
WebView()->GetBrowserControls().SetShownRatio(1, 0);
RegisterMockedHttpURLLoad("content-width-1000.html");
@@ -1478,7 +1492,7 @@ TEST_P(VisualViewportTest, TestBrowserControlsAdjustmentAndResize) {
// process.
visual_viewport.Move(ScrollOffset(10000, 10000));
frame_view.LayoutViewport()->ScrollBy(ScrollOffset(10000, 10000),
- kUserScroll);
+ mojom::blink::ScrollType::kUser);
WebView()->GetBrowserControls().SetShownRatio(0, 0);
EXPECT_EQ(FloatSize(250, visual_viewport_height / page_scale),
@@ -1495,19 +1509,26 @@ TEST_P(VisualViewportTest, TestBrowserControlsAdjustmentAndResize) {
ScrollOffset total_expected = visual_viewport_expected + frame_view_expected;
- // Resize the widget to match the browser controls adjustment. Ensure that the
- // total offset (i.e. what the user sees) doesn't change because of clamping
- // the offsets to valid values.
- WebView()->ResizeWithBrowserControls(WebSize(500, visual_viewport_height), 20,
- 0, false);
+ // Resize the widget and visible viewport to match the browser controls
+ // adjustment. Ensure that the total offset (i.e. what the user sees) doesn't
+ // change because of clamping the offsets to valid values.
+ controls.browser_controls_shrink_blink_size = false;
+ WebView()->ResizeWithBrowserControls(WebSize(500, visual_viewport_height),
+ WebSize(500, visual_viewport_height),
+ controls);
EXPECT_EQ(IntSize(500, visual_viewport_height), visual_viewport.Size());
EXPECT_EQ(FloatSize(250, visual_viewport_height / page_scale),
visual_viewport.VisibleRect().Size());
EXPECT_EQ(IntSize(1000, layout_viewport_height),
frame_view.FrameRect().Size());
+
EXPECT_EQ(total_expected, visual_viewport.GetScrollOffset() +
frame_view.LayoutViewport()->GetScrollOffset());
+
+ EXPECT_EQ(visual_viewport_expected, visual_viewport.GetScrollOffset());
+ EXPECT_EQ(frame_view_expected,
+ frame_view.LayoutViewport()->GetScrollOffset());
}
// Tests that a scroll all the way to the bottom while showing the browser
@@ -1548,7 +1569,7 @@ TEST_P(VisualViewportTest, TestBrowserControlsShrinkAdjustmentAndResize) {
WebView()->GetBrowserControls().SetShownRatio(1, 0);
visual_viewport.Move(ScrollOffset(10000, 10000));
frame_view.LayoutViewport()->ScrollBy(ScrollOffset(10000, 10000),
- kUserScroll);
+ mojom::blink::ScrollType::kUser);
EXPECT_EQ(FloatSize(250, (visual_viewport_height - browser_controls_height) /
page_scale),
@@ -1592,7 +1613,7 @@ TEST_P(VisualViewportTest, TestTopControlHidingResizeDoesntClampMainFrame) {
InitializeWithAndroidSettings();
WebView()->ResizeWithBrowserControls(WebView()->MainFrameWidget()->Size(),
500, 0, false);
- WebView()->MainFrameWidget()->ApplyViewportChanges(
+ WebView()->MainFrameWidget()->ApplyViewportChangesForTesting(
{gfx::ScrollOffset(), gfx::Vector2dF(), 1, false, 1, 0,
cc::BrowserControlsState::kBoth});
WebView()->ResizeWithBrowserControls(WebSize(1000, 1000), 500, 0, true);
@@ -1604,12 +1625,12 @@ TEST_P(VisualViewportTest, TestTopControlHidingResizeDoesntClampMainFrame) {
// Scroll the LocalFrameView to the bottom of the page but "hide" the browser
// controls on the compositor side so the max scroll position should account
// for the full viewport height.
- WebView()->MainFrameWidget()->ApplyViewportChanges(
+ WebView()->MainFrameWidget()->ApplyViewportChangesForTesting(
{gfx::ScrollOffset(), gfx::Vector2dF(), 1, false, -1, 0,
cc::BrowserControlsState::kBoth});
LocalFrameView& frame_view = *WebView()->MainFrameImpl()->GetFrameView();
- frame_view.LayoutViewport()->SetScrollOffset(ScrollOffset(0, 10000),
- kProgrammaticScroll);
+ frame_view.LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 10000), mojom::blink::ScrollType::kProgrammatic);
EXPECT_EQ(500, frame_view.LayoutViewport()->GetScrollOffset().Height());
// Now send the resize, make sure the scroll offset doesn't change.
@@ -1663,8 +1684,7 @@ TEST_P(VisualViewportTest, TestChangingContentSizeAffectsScrollBounds) {
WebScriptSource("var content = document.getElementById(\"content\");"
"content.style.width = \"1500px\";"
"content.style.height = \"2400px\";"));
- frame_view.UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ frame_view.UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
const auto* scroll_node =
frame_view.GetLayoutView()->FirstFragment().PaintProperties()->Scroll();
@@ -1703,7 +1723,7 @@ TEST_P(VisualViewportTest, ElementBoundsInViewportSpaceAccountsForViewport) {
RegisterMockedHttpURLLoad("pinch-viewport-input-field.html");
NavigateTo(base_url_ + "pinch-viewport-input-field.html");
- WebView()->SetInitialFocus(false);
+ To<LocalFrame>(WebView()->GetPage()->MainFrame())->SetInitialFocus(false);
Element* input_element = WebView()->FocusedElement();
IntRect bounds = input_element->GetLayoutObject()->AbsoluteBoundingBoxRect();
@@ -1732,7 +1752,7 @@ TEST_P(VisualViewportTest, ElementVisibleBoundsInVisualViewport) {
NavigateTo(base_url_ + "viewport-select.html");
ASSERT_EQ(2.0f, WebView()->PageScaleFactor());
- WebView()->SetInitialFocus(false);
+ To<LocalFrame>(WebView()->GetPage()->MainFrame())->SetInitialFocus(false);
Element* element = WebView()->FocusedElement();
EXPECT_FALSE(element->VisibleBoundsInVisualViewport().IsEmpty());
@@ -1785,9 +1805,9 @@ TEST_P(VisualViewportTest, visualViewportIsInert) {
EXPECT_EQ(200, html->clientWidth());
EXPECT_EQ(300, html->clientHeight());
- visual_viewport.SetScrollOffset(ScrollOffset(10, 15), kProgrammaticScroll,
- kScrollBehaviorInstant,
- ScrollableArea::ScrollCallback());
+ visual_viewport.SetScrollOffset(
+ ScrollOffset(10, 15), mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kInstant, ScrollableArea::ScrollCallback());
ASSERT_EQ(10, visual_viewport.GetScrollOffset().Width());
ASSERT_EQ(15, visual_viewport.GetScrollOffset().Height());
@@ -1871,7 +1891,7 @@ TEST_P(VisualViewportTest, SlowScrollAfterImplScroll) {
VisualViewport& visual_viewport = GetFrame()->GetPage()->GetVisualViewport();
// Apply some scroll and scale from the impl-side.
- WebView()->MainFrameWidget()->ApplyViewportChanges(
+ WebView()->MainFrameWidget()->ApplyViewportChangesForTesting(
{gfx::ScrollOffset(300, 200), gfx::Vector2dF(0, 0), 2, false, 0, 0,
cc::BrowserControlsState::kBoth});
@@ -1919,9 +1939,9 @@ TEST_P(VisualViewportTest, AccessibilityHitTestWhileZoomedIn) {
WebAXContext ax_context(web_doc);
WebView()->SetPageScaleFactor(2);
- WebView()->SetVisualViewportOffset(WebFloatPoint(200, 230));
- frame_view.LayoutViewport()->SetScrollOffset(ScrollOffset(400, 1100),
- kProgrammaticScroll);
+ WebView()->SetVisualViewportOffset(gfx::PointF(200, 230));
+ frame_view.LayoutViewport()->SetScrollOffset(
+ ScrollOffset(400, 1100), mojom::blink::ScrollType::kProgrammatic);
// FIXME(504057): PaintLayerScrollableArea dirties the compositing state.
ForceFullCompositingUpdate();
@@ -1929,7 +1949,7 @@ TEST_P(VisualViewportTest, AccessibilityHitTestWhileZoomedIn) {
// Because of where the visual viewport is located, this should hit the bottom
// right target (target 4).
WebAXObject hitNode =
- WebAXObject::FromWebDocument(web_doc).HitTest(WebPoint(154, 165));
+ WebAXObject::FromWebDocument(web_doc).HitTest(gfx::Point(154, 165));
ax::mojom::NameFrom name_from;
WebVector<WebAXObject> name_objects;
EXPECT_EQ(std::string("Target4"),
@@ -1980,8 +2000,8 @@ TEST_P(VisualViewportTest, TestCoordinateTransforms) {
visual_viewport.RootFrameToViewport(FloatPoint(50.5, 62.4)));
// Scrolling the main frame should have no effect.
- frame_view.LayoutViewport()->SetScrollOffset(ScrollOffset(100, 120),
- kProgrammaticScroll);
+ frame_view.LayoutViewport()->SetScrollOffset(
+ ScrollOffset(100, 120), mojom::blink::ScrollType::kProgrammatic);
EXPECT_FLOAT_POINT_EQ(FloatPoint(50, 62), visual_viewport.ViewportToRootFrame(
FloatPoint(80, 100)));
EXPECT_FLOAT_POINT_EQ(
@@ -2001,7 +2021,7 @@ TEST_P(VisualViewportTest, WindowDimensionsOnLoad) {
Element* output = GetFrame()->GetDocument()->getElementById("output");
DCHECK(output);
- EXPECT_EQ("1600x1200", output->InnerHTMLAsString());
+ EXPECT_EQ("1600x1200", output->innerHTML());
}
// Similar to above but make sure the initial scale is updated with the content
@@ -2016,7 +2036,7 @@ TEST_P(VisualViewportTest, WindowDimensionsOnLoadWideContent) {
Element* output = GetFrame()->GetDocument()->getElementById("output");
DCHECK(output);
- EXPECT_EQ("2000x1500", output->InnerHTMLAsString());
+ EXPECT_EQ("2000x1500", output->innerHTML());
}
TEST_P(VisualViewportTest, ResizeWithScrollAnchoring) {
@@ -2027,8 +2047,8 @@ TEST_P(VisualViewportTest, ResizeWithScrollAnchoring) {
NavigateTo(base_url_ + "icb-relative-content.html");
LocalFrameView& frame_view = *WebView()->MainFrameImpl()->GetFrameView();
- frame_view.LayoutViewport()->SetScrollOffset(ScrollOffset(700, 500),
- kProgrammaticScroll);
+ frame_view.LayoutViewport()->SetScrollOffset(
+ ScrollOffset(700, 500), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhases();
WebView()->MainFrameWidget()->Resize(IntSize(800, 300));
@@ -2054,13 +2074,13 @@ TEST_P(VisualViewportTest, ResizeAnchoringWithRootScroller) {
GetFrame()->GetDocument()->setRootScroller(scroller, non_throw);
WebView()->SetPageScaleFactor(3.f);
- frame_view.GetScrollableArea()->SetScrollOffset(ScrollOffset(0, 400),
- kProgrammaticScroll);
+ frame_view.GetScrollableArea()->SetScrollOffset(
+ ScrollOffset(0, 400), mojom::blink::ScrollType::kProgrammatic);
VisualViewport& visual_viewport = WebView()->GetPage()->GetVisualViewport();
- visual_viewport.SetScrollOffset(ScrollOffset(0, 400), kProgrammaticScroll,
- kScrollBehaviorInstant,
- ScrollableArea::ScrollCallback());
+ visual_viewport.SetScrollOffset(
+ ScrollOffset(0, 400), mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kInstant, ScrollableArea::ScrollCallback());
WebView()->MainFrameWidget()->Resize(IntSize(800, 500));
@@ -2476,7 +2496,7 @@ TEST_F(VisualViewportSimTest, ScrollingContentsSmallerThanContainer) {
visual_viewport.GetScrollNode()->ContainerRect().Size());
EXPECT_EQ(IntSize(320, 480), visual_viewport.GetScrollNode()->ContentsSize());
- WebView().MainFrameWidget()->ApplyViewportChanges(
+ WebView().MainFrameWidget()->ApplyViewportChangesForTesting(
{gfx::ScrollOffset(1, 1), gfx::Vector2dF(), 2, false, 1, 0,
cc::BrowserControlsState::kBoth});
EXPECT_EQ(gfx::Size(320, 480), visual_viewport.LayerForScrolling()->bounds());
@@ -2525,11 +2545,11 @@ class VisualViewportScrollIntoViewTest : public VisualViewportSimTest {
bool is_for_scroll_sequence) {
WebDocument web_doc = WebView().MainFrameImpl()->GetDocument();
Element* bottom_element = web_doc.GetElementById(element_name);
- WebScrollIntoViewParams scroll_params(
- ScrollAlignment::kAlignToEdgeIfNeeded,
- ScrollAlignment::kAlignToEdgeIfNeeded, kProgrammaticScroll,
- /*make_visible_in_visual_viewport=*/true, kScrollBehaviorInstant,
- is_for_scroll_sequence);
+ auto scroll_params = ScrollAlignment::CreateScrollIntoViewParams(
+ ScrollAlignment::ToEdgeIfNeeded(), ScrollAlignment::ToEdgeIfNeeded(),
+ mojom::blink::ScrollType::kProgrammatic,
+ /*make_visible_in_visual_viewport=*/true,
+ mojom::blink::ScrollBehavior::kInstant, is_for_scroll_sequence);
WebView().GetPage()->GetVisualViewport().ScrollIntoView(
bottom_element->BoundingBox(), scroll_params);
}
@@ -2571,7 +2591,7 @@ TEST_P(VisualViewportTest, DeviceEmulation) {
EXPECT_FALSE(GetFrame()->View()->VisualViewportNeedsRepaint());
WebDeviceEmulationParams params;
- params.viewport_offset = WebFloatPoint();
+ params.viewport_offset = gfx::PointF();
params.viewport_scale = 1.f;
WebView()->EnableDeviceEmulation(params);
@@ -2582,19 +2602,20 @@ TEST_P(VisualViewportTest, DeviceEmulation) {
EXPECT_FALSE(GetFrame()->View()->VisualViewportNeedsRepaint());
// Set device mulation with viewport offset should repaint visual viewport.
- params.viewport_offset = WebFloatPoint(314, 159);
+ params.viewport_offset = gfx::PointF(314, 159);
WebView()->EnableDeviceEmulation(params);
UpdateAllLifecyclePhasesExceptPaint();
EXPECT_TRUE(GetFrame()->View()->VisualViewportNeedsRepaint());
ASSERT_TRUE(visual_viewport.GetDeviceEmulationTransformNode());
- EXPECT_EQ(FloatSize(-params.viewport_offset.x, -params.viewport_offset.y),
- visual_viewport.GetDeviceEmulationTransformNode()->Translation2D());
+ EXPECT_EQ(TransformationMatrix().Translate(-params.viewport_offset.x(),
+ -params.viewport_offset.y()),
+ visual_viewport.GetDeviceEmulationTransformNode()->Matrix());
UpdateAllLifecyclePhases();
EXPECT_FALSE(GetFrame()->View()->VisualViewportNeedsRepaint());
// Change device emulation with scale should not repaint visual viewport.
- params.viewport_offset = WebFloatPoint();
+ params.viewport_offset = gfx::PointF();
params.viewport_scale = 1.5f;
WebView()->EnableDeviceEmulation(params);
@@ -2662,7 +2683,7 @@ TEST_P(VisualViewportTest, PaintScrollbar) {
// Apply device emulation scale.
WebDeviceEmulationParams params;
- params.viewport_offset = WebFloatPoint();
+ params.viewport_offset = gfx::PointF();
params.viewport_scale = 1.5f;
WebView()->EnableDeviceEmulation(params);
UpdateAllLifecyclePhases();
@@ -2688,11 +2709,6 @@ TEST_P(VisualViewportTest, PaintScrollbar) {
// When a pinch-zoom occurs, the viewport scale and translation nodes can be
// directly updated without a PaintArtifactCompositor update.
TEST_P(VisualViewportTest, DirectPinchZoomPropertyUpdate) {
- // TODO(crbug.com/953322): Implement this optimization for
- // CompositeAfterPaint.
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
- return;
-
InitializeWithAndroidSettings();
RegisterMockedHttpURLLoad("200-by-800-viewport.html");
@@ -2752,10 +2768,10 @@ TEST_P(VisualViewportTest, InSubtreeOfPageScale) {
TEST_F(VisualViewportSimTest, UsedColorSchemeFromRootElement) {
ScopedCSSColorSchemeForTest color_scheme_enabled(true);
+ ScopedCSSColorSchemeUARenderingForTest color_scheme_ua_enabled(true);
- ColorSchemeHelper color_scheme_helper;
- color_scheme_helper.SetPreferredColorScheme(*(WebView().GetPage()),
- PreferredColorScheme::kDark);
+ ColorSchemeHelper color_scheme_helper(*(WebView().GetPage()));
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kDark);
WebView().MainFrameWidget()->Resize(WebSize(400, 600));
const VisualViewport& visual_viewport =
@@ -2794,8 +2810,12 @@ TEST_P(VisualViewportTest, SetLocationBeforePrePaint) {
EXPECT_EQ(FloatPoint(12, 34), visual_viewport.ScrollPosition());
// When we create the scrolling layer, we should update its scroll offset.
ASSERT_TRUE(visual_viewport.LayerForScrolling());
- EXPECT_EQ(gfx::ScrollOffset(12, 34),
- visual_viewport.LayerForScrolling()->CurrentScrollOffset());
+
+ auto* layer_tree_host = GetFrame()->View()->RootCcLayer()->layer_tree_host();
+ EXPECT_EQ(
+ gfx::ScrollOffset(12, 34),
+ layer_tree_host->property_trees()->scroll_tree.current_scroll_offset(
+ visual_viewport.GetScrollElementId()));
}
TEST_P(VisualViewportTest, ScrollbarGeometryOnSizeChange) {
diff --git a/chromium/third_party/blink/renderer/core/frame/web_frame_serializer_impl.cc b/chromium/third_party/blink/renderer/core/frame/web_frame_serializer_impl.cc
index ed21e87c13c..5a4df2a7244 100644
--- a/chromium/third_party/blink/renderer/core/frame/web_frame_serializer_impl.cc
+++ b/chromium/third_party/blink/renderer/core/frame/web_frame_serializer_impl.cc
@@ -86,6 +86,7 @@
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/html/forms/html_form_element.h"
#include "third_party/blink/renderer/core/html/html_all_collection.h"
+#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/html/html_frame_element_base.h"
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
@@ -123,7 +124,7 @@ WebFrameSerializerImpl::SerializeDomParam::SerializeDomParam(
: url(url),
text_encoding(text_encoding),
document(document),
- is_html_document(document->IsHTMLDocument()),
+ is_html_document(IsA<HTMLDocument>(document)),
have_seen_doc_type(false),
have_added_charset_declaration(false),
skip_meta_element(nullptr),
diff --git a/chromium/third_party/blink/renderer/core/frame/web_frame_serializer_impl.h b/chromium/third_party/blink/renderer/core/frame/web_frame_serializer_impl.h
index 36ab7b23b79..4509f859882 100644
--- a/chromium/third_party/blink/renderer/core/frame/web_frame_serializer_impl.h
+++ b/chromium/third_party/blink/renderer/core/frame/web_frame_serializer_impl.h
@@ -81,7 +81,7 @@ class WebFrameSerializerImpl {
private:
// Specified frame which need to be serialized;
- Member<WebLocalFrameImpl> specified_web_local_frame_impl_;
+ WebLocalFrameImpl* specified_web_local_frame_impl_;
// Pointer of WebFrameSerializerClient
WebFrameSerializerClient* client_;
// Pointer of WebFrameSerializer::LinkRewritingDelegate
@@ -103,12 +103,12 @@ class WebFrameSerializerImpl {
const KURL& url;
const WTF::TextEncoding& text_encoding;
- Member<Document> document;
+ Document* document;
bool is_html_document; // document.isHTMLDocument()
bool have_seen_doc_type;
bool have_added_charset_declaration;
// This meta element need to be skipped when serializing DOM.
- Member<const Element> skip_meta_element;
+ const Element* skip_meta_element;
bool have_added_xml_processing_directive;
// Flag indicates whether we have added additional contents before end tag.
// This flag will be re-assigned in each call of function
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 771b3237724..cce5caed45a 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
@@ -7,7 +7,11 @@
#include <memory>
#include <utility>
+#include "base/metrics/histogram_macros.h"
+#include "base/single_thread_task_runner.h"
#include "base/time/time.h"
+#include "cc/trees/layer_tree_host.h"
+#include "cc/trees/swap_promise.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_widget_client.h"
@@ -16,6 +20,7 @@
#include "third_party/blink/renderer/core/events/web_input_event_conversion.h"
#include "third_party/blink/renderer/core/events/wheel_event.h"
#include "third_party/blink/renderer/core/exported/web_view_impl.h"
+#include "third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.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/frame/web_local_frame_impl.h"
@@ -34,7 +39,19 @@
#include "third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl.h"
#include "third_party/blink/renderer/platform/graphics/compositor_mutator_client.h"
#include "third_party/blink/renderer/platform/graphics/paint_worklet_paint_dispatcher.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
+#include "third_party/blink/renderer/platform/widget/widget_base.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
+
+namespace WTF {
+template <>
+struct CrossThreadCopier<blink::WebReportTimeCallback>
+ : public CrossThreadCopierByValuePassThrough<blink::WebReportTimeCallback> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+} // namespace WTF
namespace blink {
@@ -51,8 +68,22 @@ STATIC_ASSERT_ENUM(kDragOperationEvery, kWebDragOperationEvery);
bool WebFrameWidgetBase::ignore_input_events_ = false;
-WebFrameWidgetBase::WebFrameWidgetBase(WebWidgetClient& client)
- : client_(&client) {}
+WebFrameWidgetBase::WebFrameWidgetBase(
+ WebWidgetClient& client,
+ CrossVariantMojoAssociatedRemote<mojom::blink::FrameWidgetHostInterfaceBase>
+ frame_widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::blink::FrameWidgetInterfaceBase>
+ frame_widget,
+ CrossVariantMojoAssociatedRemote<mojom::blink::WidgetHostInterfaceBase>
+ widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::blink::WidgetInterfaceBase>
+ widget)
+ : 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)) {}
WebFrameWidgetBase::~WebFrameWidgetBase() = default;
@@ -71,6 +102,8 @@ void WebFrameWidgetBase::Close() {
local_root_ = nullptr;
client_ = nullptr;
request_animation_after_delay_timer_.reset();
+ widget_base_.reset();
+ receiver_.reset();
}
WebLocalFrame* WebFrameWidgetBase::LocalRoot() const {
@@ -112,8 +145,8 @@ WebRect WebFrameWidgetBase::ComputeBlockBound(
WebDragOperation WebFrameWidgetBase::DragTargetDragEnter(
const WebDragData& web_drag_data,
- const WebFloatPoint& point_in_viewport,
- const WebFloatPoint& screen_point,
+ const gfx::PointF& point_in_viewport,
+ const gfx::PointF& screen_point,
WebDragOperationsMask operations_allowed,
int modifiers) {
DCHECK(!current_drag_data_);
@@ -126,8 +159,8 @@ WebDragOperation WebFrameWidgetBase::DragTargetDragEnter(
}
WebDragOperation WebFrameWidgetBase::DragTargetDragOver(
- const WebFloatPoint& point_in_viewport,
- const WebFloatPoint& screen_point,
+ const gfx::PointF& point_in_viewport,
+ const gfx::PointF& screen_point,
WebDragOperationsMask operations_allowed,
int modifiers) {
operations_allowed_ = operations_allowed;
@@ -137,8 +170,8 @@ WebDragOperation WebFrameWidgetBase::DragTargetDragOver(
}
void WebFrameWidgetBase::DragTargetDragLeave(
- const WebFloatPoint& point_in_viewport,
- const WebFloatPoint& screen_point) {
+ const gfx::PointF& point_in_viewport,
+ const gfx::PointF& screen_point) {
DCHECK(current_drag_data_);
// TODO(paulmeyer): It shouldn't be possible for |m_currentDragData| to be
@@ -151,9 +184,9 @@ void WebFrameWidgetBase::DragTargetDragLeave(
return;
}
- WebFloatPoint point_in_root_frame(ViewportToRootFrame(point_in_viewport));
- DragData drag_data(current_drag_data_.Get(), point_in_root_frame,
- screen_point,
+ gfx::PointF point_in_root_frame(ViewportToRootFrame(point_in_viewport));
+ DragData drag_data(current_drag_data_.Get(), FloatPoint(point_in_root_frame),
+ FloatPoint(screen_point),
static_cast<DragOperation>(operations_allowed_));
GetPage()->GetDragController().DragExited(&drag_data,
@@ -166,10 +199,10 @@ void WebFrameWidgetBase::DragTargetDragLeave(
}
void WebFrameWidgetBase::DragTargetDrop(const WebDragData& web_drag_data,
- const WebFloatPoint& point_in_viewport,
- const WebFloatPoint& screen_point,
+ const gfx::PointF& point_in_viewport,
+ const gfx::PointF& screen_point,
int modifiers) {
- WebFloatPoint point_in_root_frame(ViewportToRootFrame(point_in_viewport));
+ gfx::PointF point_in_root_frame(ViewportToRootFrame(point_in_viewport));
DCHECK(current_drag_data_);
current_drag_data_ = DataObject::Create(web_drag_data);
@@ -189,8 +222,9 @@ void WebFrameWidgetBase::DragTargetDrop(const WebDragData& web_drag_data,
if (!IgnoreInputEvents()) {
current_drag_data_->SetModifiers(modifiers);
- DragData drag_data(current_drag_data_.Get(), point_in_root_frame,
- screen_point,
+ DragData drag_data(current_drag_data_.Get(),
+ FloatPoint(point_in_root_frame),
+ FloatPoint(screen_point),
static_cast<DragOperation>(operations_allowed_));
GetPage()->GetDragController().PerformDrag(&drag_data,
@@ -200,10 +234,9 @@ void WebFrameWidgetBase::DragTargetDrop(const WebDragData& web_drag_data,
current_drag_data_ = nullptr;
}
-void WebFrameWidgetBase::DragSourceEndedAt(
- const WebFloatPoint& point_in_viewport,
- const WebFloatPoint& screen_point,
- WebDragOperation operation) {
+void WebFrameWidgetBase::DragSourceEndedAt(const gfx::PointF& point_in_viewport,
+ const gfx::PointF& screen_point,
+ WebDragOperation operation) {
if (!local_root_) {
// We should figure out why |local_root_| could be nullptr
// (https://crbug.com/792345).
@@ -214,8 +247,9 @@ void WebFrameWidgetBase::DragSourceEndedAt(
CancelDrag();
return;
}
- WebFloatPoint point_in_root_frame(
- GetPage()->GetVisualViewport().ViewportToRootFrame(point_in_viewport));
+ gfx::PointF point_in_root_frame(
+ GetPage()->GetVisualViewport().ViewportToRootFrame(
+ FloatPoint(point_in_viewport)));
WebMouseEvent fake_mouse_move(
WebInputEvent::kMouseMove, point_in_root_frame, screen_point,
@@ -230,6 +264,16 @@ void WebFrameWidgetBase::DragSourceSystemDragEnded() {
CancelDrag();
}
+void WebFrameWidgetBase::SetBackgroundOpaque(bool opaque) {
+ if (opaque) {
+ View()->ClearBaseBackgroundColorOverride();
+ View()->ClearBackgroundColorOverride();
+ } else {
+ View()->SetBaseBackgroundColorOverride(SK_ColorTRANSPARENT);
+ View()->SetBackgroundColorOverride(SK_ColorTRANSPARENT);
+ }
+}
+
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.
@@ -249,8 +293,8 @@ void WebFrameWidgetBase::StartDragging(network::mojom::ReferrerPolicy policy,
}
WebDragOperation WebFrameWidgetBase::DragTargetDragEnterOrOver(
- const WebFloatPoint& point_in_viewport,
- const WebFloatPoint& screen_point,
+ const gfx::PointF& point_in_viewport,
+ const gfx::PointF& screen_point,
DragAction drag_action,
int modifiers) {
DCHECK(current_drag_data_);
@@ -264,11 +308,11 @@ WebDragOperation WebFrameWidgetBase::DragTargetDragEnterOrOver(
return kWebDragOperationNone;
}
- WebFloatPoint point_in_root_frame(ViewportToRootFrame(point_in_viewport));
+ FloatPoint point_in_root_frame(ViewportToRootFrame(point_in_viewport));
current_drag_data_->SetModifiers(modifiers);
- DragData drag_data(current_drag_data_.Get(), point_in_root_frame,
- screen_point,
+ DragData drag_data(current_drag_data_.Get(), FloatPoint(point_in_root_frame),
+ FloatPoint(screen_point),
static_cast<DragOperation>(operations_allowed_));
DragOperation drag_operation =
@@ -310,9 +354,10 @@ void WebFrameWidgetBase::SendScrollEndEventFromImplSide(
target_node->GetDocument().EnqueueScrollEndEventForNode(target_node);
}
-WebFloatPoint WebFrameWidgetBase::ViewportToRootFrame(
- const WebFloatPoint& point_in_viewport) const {
- return GetPage()->GetVisualViewport().ViewportToRootFrame(point_in_viewport);
+gfx::PointF WebFrameWidgetBase::ViewportToRootFrame(
+ const gfx::PointF& point_in_viewport) const {
+ return GetPage()->GetVisualViewport().ViewportToRootFrame(
+ FloatPoint(point_in_viewport));
}
WebViewImpl* WebFrameWidgetBase::View() const {
@@ -346,11 +391,117 @@ void WebFrameWidgetBase::RequestDecode(
Client()->RequestDecode(image, std::move(callback));
}
-void WebFrameWidgetBase::Trace(blink::Visitor* visitor) {
+void WebFrameWidgetBase::Trace(Visitor* visitor) {
visitor->Trace(local_root_);
visitor->Trace(current_drag_data_);
}
+void WebFrameWidgetBase::SetNeedsRecalculateRasterScales() {
+ if (!View()->does_composite())
+ return;
+ widget_base_->LayerTreeHost()->SetNeedsRecalculateRasterScales();
+}
+
+void WebFrameWidgetBase::SetBackgroundColor(SkColor color) {
+ if (!View()->does_composite())
+ return;
+ widget_base_->LayerTreeHost()->set_background_color(color);
+}
+
+void WebFrameWidgetBase::SetOverscrollBehavior(
+ const cc::OverscrollBehavior& overscroll_behavior) {
+ if (!View()->does_composite())
+ return;
+ widget_base_->LayerTreeHost()->SetOverscrollBehavior(overscroll_behavior);
+}
+
+void WebFrameWidgetBase::RegisterSelection(cc::LayerSelection selection) {
+ if (!View()->does_composite())
+ return;
+ widget_base_->LayerTreeHost()->RegisterSelection(selection);
+}
+
+void WebFrameWidgetBase::StartPageScaleAnimation(
+ const gfx::Vector2d& destination,
+ bool use_anchor,
+ float new_page_scale,
+ base::TimeDelta duration) {
+ widget_base_->LayerTreeHost()->StartPageScaleAnimation(
+ destination, use_anchor, new_page_scale, duration);
+}
+
+void WebFrameWidgetBase::RequestBeginMainFrameNotExpected(bool request) {
+ if (!View()->does_composite())
+ return;
+ widget_base_->LayerTreeHost()->RequestBeginMainFrameNotExpected(request);
+}
+
+int WebFrameWidgetBase::GetLayerTreeId() {
+ if (!View()->does_composite())
+ return 0;
+ return widget_base_->LayerTreeHost()->GetId();
+}
+
+void WebFrameWidgetBase::SetHaveScrollEventHandlers(bool has_handlers) {
+ widget_base_->LayerTreeHost()->SetHaveScrollEventHandlers(has_handlers);
+}
+
+void WebFrameWidgetBase::SetEventListenerProperties(
+ cc::EventListenerClass listener_class,
+ cc::EventListenerProperties listener_properties) {
+ widget_base_->LayerTreeHost()->SetEventListenerProperties(
+ listener_class, listener_properties);
+}
+
+cc::EventListenerProperties WebFrameWidgetBase::EventListenerProperties(
+ cc::EventListenerClass listener_class) const {
+ return widget_base_->LayerTreeHost()->event_listener_properties(
+ listener_class);
+}
+
+void WebFrameWidgetBase::StartDeferringCommits(base::TimeDelta timeout) {
+ if (!View()->does_composite())
+ return;
+ widget_base_->LayerTreeHost()->StartDeferringCommits(timeout);
+}
+
+void WebFrameWidgetBase::StopDeferringCommits(
+ cc::PaintHoldingCommitTrigger triggger) {
+ if (!View()->does_composite())
+ return;
+ widget_base_->LayerTreeHost()->StopDeferringCommits(triggger);
+}
+
+std::unique_ptr<cc::ScopedDeferMainFrameUpdate>
+WebFrameWidgetBase::DeferMainFrameUpdate() {
+ return widget_base_->LayerTreeHost()->DeferMainFrameUpdate();
+}
+
+void WebFrameWidgetBase::SetBrowserControlsShownRatio(float top_ratio,
+ float bottom_ratio) {
+ widget_base_->LayerTreeHost()->SetBrowserControlsShownRatio(top_ratio,
+ bottom_ratio);
+}
+
+void WebFrameWidgetBase::SetBrowserControlsParams(
+ cc::BrowserControlsParams params) {
+ widget_base_->LayerTreeHost()->SetBrowserControlsParams(params);
+}
+
+cc::LayerTreeDebugState WebFrameWidgetBase::GetLayerTreeDebugState() {
+ return widget_base_->LayerTreeHost()->GetDebugState();
+}
+
+void WebFrameWidgetBase::SetLayerTreeDebugState(
+ const cc::LayerTreeDebugState& state) {
+ widget_base_->LayerTreeHost()->SetDebugState(state);
+}
+
+void WebFrameWidgetBase::SynchronouslyCompositeForTesting(
+ base::TimeTicks frame_time) {
+ widget_base_->LayerTreeHost()->Composite(frame_time, false);
+}
+
// TODO(665924): Remove direct dispatches of mouse events from
// PointerLockController, instead passing them through EventHandler.
void WebFrameWidgetBase::PointerLockMouseEvent(
@@ -430,6 +581,57 @@ WebLocalFrame* WebFrameWidgetBase::FocusedWebLocalFrameInWidget() const {
return WebLocalFrameImpl::FromFrame(FocusedLocalFrameInWidget());
}
+void WebFrameWidgetBase::SetCompositorHosts(cc::LayerTreeHost* layer_tree_host,
+ cc::AnimationHost* animation_host) {
+ widget_base_->SetCompositorHosts(layer_tree_host, animation_host);
+ GetPage()->AnimationHostInitialized(*AnimationHost(),
+ GetLocalFrameViewForAnimationScrolling());
+}
+
+void WebFrameWidgetBase::SetCompositorVisible(bool visible) {
+ widget_base_->SetCompositorVisible(visible);
+}
+
+void WebFrameWidgetBase::UpdateVisualState() {
+ widget_base_->UpdateVisualState();
+}
+
+void WebFrameWidgetBase::RecordTimeToFirstActivePaint(
+ base::TimeDelta duration) {
+ Client()->RecordTimeToFirstActivePaint(duration);
+}
+
+void WebFrameWidgetBase::BeginFrame(base::TimeTicks frame_time) {
+ widget_base_->BeginMainFrame(frame_time);
+}
+
+void WebFrameWidgetBase::WillBeginCompositorFrame() {
+ widget_base_->WillBeginCompositorFrame();
+}
+
+void WebFrameWidgetBase::DispatchRafAlignedInput(base::TimeTicks frame_time) {
+ base::TimeTicks raf_aligned_input_start_time;
+ if (LocalRootImpl() && WidgetBase::ShouldRecordBeginMainFrameMetrics()) {
+ raf_aligned_input_start_time = base::TimeTicks::Now();
+ }
+
+ Client()->DispatchRafAlignedInput(frame_time);
+
+ if (LocalRootImpl() && WidgetBase::ShouldRecordBeginMainFrameMetrics()) {
+ LocalRootImpl()->GetFrame()->View()->EnsureUkmAggregator().RecordSample(
+ LocalFrameUkmAggregator::kHandleInputEvents,
+ raf_aligned_input_start_time, base::TimeTicks::Now());
+ }
+}
+
+void WebFrameWidgetBase::ApplyViewportChangesForTesting(
+ const ApplyViewportChangesArgs& args) {
+ // TODO(dtapuska): Temporarily just call ApplyViewportChanges.
+ // ApplyViewportChanges will eventually be removed when compositing moves into
+ // |widget_base_|.
+ ApplyViewportChanges(args);
+}
+
void WebFrameWidgetBase::RequestAnimationAfterDelay(
const base::TimeDelta& delay) {
DCHECK(request_animation_after_delay_timer_.get());
@@ -451,7 +653,7 @@ base::WeakPtr<AnimationWorkletMutatorDispatcherImpl>
WebFrameWidgetBase::EnsureCompositorMutatorDispatcher(
scoped_refptr<base::SingleThreadTaskRunner>* mutator_task_runner) {
if (!mutator_task_runner_) {
- Client()->SetLayerTreeMutator(
+ widget_base_->LayerTreeHost()->SetLayerTreeMutator(
AnimationWorkletMutatorDispatcherImpl::CreateCompositorThreadClient(
&mutator_dispatcher_, &mutator_task_runner_));
}
@@ -461,13 +663,17 @@ WebFrameWidgetBase::EnsureCompositorMutatorDispatcher(
return mutator_dispatcher_;
}
+cc::AnimationHost* WebFrameWidgetBase::AnimationHost() const {
+ return widget_base_->AnimationHost();
+}
+
base::WeakPtr<PaintWorkletPaintDispatcher>
WebFrameWidgetBase::EnsureCompositorPaintDispatcher(
scoped_refptr<base::SingleThreadTaskRunner>* paint_task_runner) {
// We check paint_task_runner_ not paint_dispatcher_ because the dispatcher is
// a base::WeakPtr that should only be used on the compositor thread.
if (!paint_task_runner_) {
- Client()->SetPaintWorkletLayerPainterClient(
+ widget_base_->LayerTreeHost()->SetPaintWorkletLayerPainter(
PaintWorkletPaintDispatcher::CreateCompositorThreadPainter(
&paint_dispatcher_));
paint_task_runner_ = Thread::CompositorThread()->GetTaskRunner();
@@ -477,4 +683,153 @@ WebFrameWidgetBase::EnsureCompositorPaintDispatcher(
return paint_dispatcher_;
}
+// Enables measuring and reporting both presentation times and swap times in
+// swap promises.
+class ReportTimeSwapPromise : public cc::SwapPromise {
+ public:
+ ReportTimeSwapPromise(WebReportTimeCallback swap_time_callback,
+ WebReportTimeCallback presentation_time_callback,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ WebFrameWidgetBase* widget)
+ : swap_time_callback_(std::move(swap_time_callback)),
+ presentation_time_callback_(std::move(presentation_time_callback)),
+ task_runner_(std::move(task_runner)),
+ widget_(widget) {}
+ ~ReportTimeSwapPromise() override = default;
+
+ void DidActivate() override {}
+
+ void WillSwap(viz::CompositorFrameMetadata* metadata) override {
+ DCHECK_GT(metadata->frame_token, 0u);
+ // The interval between the current swap and its presentation time is
+ // reported in UMA (see corresponding code in DidSwap() below).
+ frame_token_ = metadata->frame_token;
+ }
+
+ void DidSwap() override {
+ DCHECK_GT(frame_token_, 0u);
+ PostCrossThreadTask(
+ *task_runner_, FROM_HERE,
+ CrossThreadBindOnce(
+ &RunCallbackAfterSwap, widget_, base::TimeTicks::Now(),
+ std::move(swap_time_callback_),
+ std::move(presentation_time_callback_), frame_token_));
+ }
+
+ cc::SwapPromise::DidNotSwapAction DidNotSwap(
+ DidNotSwapReason reason) override {
+ WebSwapResult result;
+ switch (reason) {
+ case cc::SwapPromise::DidNotSwapReason::SWAP_FAILS:
+ result = WebSwapResult::kDidNotSwapSwapFails;
+ break;
+ case cc::SwapPromise::DidNotSwapReason::COMMIT_FAILS:
+ result = WebSwapResult::kDidNotSwapCommitFails;
+ break;
+ case cc::SwapPromise::DidNotSwapReason::COMMIT_NO_UPDATE:
+ result = WebSwapResult::kDidNotSwapCommitNoUpdate;
+ break;
+ case cc::SwapPromise::DidNotSwapReason::ACTIVATION_FAILS:
+ result = WebSwapResult::kDidNotSwapActivationFails;
+ break;
+ }
+ // During a failed swap, return the current time regardless of whether we're
+ // using presentation or swap timestamps.
+ PostCrossThreadTask(
+ *task_runner_, FROM_HERE,
+ CrossThreadBindOnce(
+ [](WebSwapResult result, base::TimeTicks swap_time,
+ WebReportTimeCallback swap_time_callback,
+ WebReportTimeCallback presentation_time_callback) {
+ ReportTime(std::move(swap_time_callback), result, swap_time);
+ ReportTime(std::move(presentation_time_callback), result,
+ swap_time);
+ },
+ result, base::TimeTicks::Now(), std::move(swap_time_callback_),
+ std::move(presentation_time_callback_)));
+ return DidNotSwapAction::BREAK_PROMISE;
+ }
+
+ int64_t TraceId() const override { return 0; }
+
+ private:
+ static void RunCallbackAfterSwap(
+ WebFrameWidgetBase* widget,
+ base::TimeTicks swap_time,
+ WebReportTimeCallback swap_time_callback,
+ WebReportTimeCallback presentation_time_callback,
+ int frame_token) {
+ // If the widget was collected or the widget wasn't collected yet, but
+ // it was closed don't schedule a presentation callback.
+ if (widget && widget->Client()) {
+ widget->Client()->AddPresentationCallback(
+ frame_token,
+ WTF::Bind(&RunCallbackAfterPresentation,
+ std::move(presentation_time_callback), swap_time));
+ ReportTime(std::move(swap_time_callback), WebSwapResult::kDidSwap,
+ swap_time);
+ } else {
+ ReportTime(std::move(swap_time_callback), WebSwapResult::kDidSwap,
+ swap_time);
+ ReportTime(std::move(presentation_time_callback), WebSwapResult::kDidSwap,
+ swap_time);
+ }
+ }
+
+ static void RunCallbackAfterPresentation(
+ WebReportTimeCallback presentation_time_callback,
+ base::TimeTicks swap_time,
+ base::TimeTicks presentation_time) {
+ DCHECK(!swap_time.is_null());
+ bool presentation_time_is_valid =
+ !presentation_time.is_null() && (presentation_time > swap_time);
+ UMA_HISTOGRAM_BOOLEAN("PageLoad.Internal.Renderer.PresentationTime.Valid",
+ presentation_time_is_valid);
+ if (presentation_time_is_valid) {
+ // This measures from 1ms to 10seconds.
+ UMA_HISTOGRAM_TIMES(
+ "PageLoad.Internal.Renderer.PresentationTime.DeltaFromSwapTime",
+ presentation_time - swap_time);
+ }
+ ReportTime(std::move(presentation_time_callback), WebSwapResult::kDidSwap,
+ presentation_time_is_valid ? presentation_time : swap_time);
+ }
+
+ static void ReportTime(WebReportTimeCallback callback,
+ WebSwapResult result,
+ base::TimeTicks time) {
+ if (callback)
+ std::move(callback).Run(result, time);
+ }
+
+ WebReportTimeCallback swap_time_callback_;
+ WebReportTimeCallback presentation_time_callback_;
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+ CrossThreadWeakPersistent<WebFrameWidgetBase> widget_;
+ uint32_t frame_token_ = 0;
+
+ DISALLOW_COPY_AND_ASSIGN(ReportTimeSwapPromise);
+};
+
+void WebFrameWidgetBase::NotifySwapAndPresentationTimeInBlink(
+ WebReportTimeCallback swap_time_callback,
+ WebReportTimeCallback presentation_time_callback) {
+ NotifySwapAndPresentationTime(std::move(swap_time_callback),
+ std::move(presentation_time_callback));
+}
+
+void WebFrameWidgetBase::NotifySwapAndPresentationTime(
+ WebReportTimeCallback swap_time_callback,
+ WebReportTimeCallback presentation_time_callback) {
+ if (!View()->does_composite())
+ return;
+ widget_base_->LayerTreeHost()->QueueSwapPromise(
+ std::make_unique<ReportTimeSwapPromise>(
+ std::move(swap_time_callback), std::move(presentation_time_callback),
+ widget_base_->LayerTreeHost()
+ ->GetTaskRunnerProvider()
+ ->MainThreadTaskRunner(),
+ this));
+}
+
} // 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 43fbd634a4f..2663b0e651d 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
@@ -6,46 +6,67 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_WEB_FRAME_WIDGET_BASE_H_
#include "base/single_thread_task_runner.h"
+#include "cc/input/event_listener_properties.h"
+#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_gesture_device.h"
+#include "third_party/blink/public/mojom/page/widget.mojom-blink.h"
+#include "third_party/blink/public/platform/cross_variant_mojo_util.h"
#include "third_party/blink/public/platform/web_coalesced_input_event.h"
#include "third_party/blink/public/platform/web_drag_data.h"
-#include "third_party/blink/public/platform/web_gesture_device.h"
#include "third_party/blink/public/web/web_frame_widget.h"
#include "third_party/blink/renderer/core/clipboard/data_object.h"
#include "third_party/blink/renderer/core/core_export.h"
+#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/timer.h"
+#include "third_party/blink/renderer/platform/widget/frame_widget.h"
+#include "third_party/blink/renderer/platform/widget/widget_base_client.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
-namespace cc {
-class AnimationHost;
-class Layer;
-}
-
namespace gfx {
class Point;
+class PointF;
}
namespace blink {
class AnimationWorkletMutatorDispatcherImpl;
class HitTestResult;
+class LocalFrameView;
class Page;
class PageWidgetEventHandler;
class PaintWorkletPaintDispatcher;
class WebLocalFrameImpl;
class WebViewImpl;
+class WidgetBase;
struct IntrinsicSizingInfo;
-struct WebFloatPoint;
class CORE_EXPORT WebFrameWidgetBase
: public GarbageCollected<WebFrameWidgetBase>,
- public WebFrameWidget {
+ public WebFrameWidget,
+ public WidgetBaseClient,
+ public mojom::blink::FrameWidget,
+ public FrameWidget {
public:
- explicit WebFrameWidgetBase(WebWidgetClient&);
- virtual ~WebFrameWidgetBase();
-
- WebWidgetClient* Client() const { return client_; }
+ WebFrameWidgetBase(
+ WebWidgetClient&,
+ CrossVariantMojoAssociatedRemote<
+ mojom::blink::FrameWidgetHostInterfaceBase> frame_widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::blink::FrameWidgetInterfaceBase>
+ frame_widget,
+ CrossVariantMojoAssociatedRemote<mojom::blink::WidgetHostInterfaceBase>
+ widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::blink::WidgetInterfaceBase>
+ widget);
+ ~WebFrameWidgetBase() override;
+
+ // Returns the WebFrame that this widget is attached to. It will be a local
+ // root since only local roots have a widget attached.
WebLocalFrameImpl* LocalRootImpl() const { return local_root_; }
// Returns the bounding box of the block type node touched by the WebPoint.
@@ -70,35 +91,48 @@ class CORE_EXPORT WebFrameWidgetBase
base::WeakPtr<PaintWorkletPaintDispatcher> EnsureCompositorPaintDispatcher(
scoped_refptr<base::SingleThreadTaskRunner>* paint_task_runner);
- // Sets the root layer. The |layer| can be null when detaching the root layer.
- virtual void SetRootLayer(scoped_refptr<cc::Layer> layer) = 0;
-
- virtual cc::AnimationHost* AnimationHost() const = 0;
-
virtual HitTestResult CoreHitTestResultAt(const gfx::Point&) = 0;
+ // FrameWidget implementation.
+ WebWidgetClient* Client() const final { return client_; }
+ cc::AnimationHost* AnimationHost() const final;
+ void SetOverscrollBehavior(
+ const cc::OverscrollBehavior& overscroll_behavior) final;
+ void RequestAnimationAfterDelay(const base::TimeDelta&) final;
+ void RegisterSelection(cc::LayerSelection selection) final;
+ void RequestDecode(const cc::PaintImage&,
+ base::OnceCallback<void(bool)>) final;
+ void NotifySwapAndPresentationTimeInBlink(
+ WebReportTimeCallback swap_callback,
+ WebReportTimeCallback presentation_callback) final;
+ void RequestBeginMainFrameNotExpected(bool request) final;
+ int GetLayerTreeId() final;
+ void SetEventListenerProperties(cc::EventListenerClass,
+ cc::EventListenerProperties) final;
+ cc::EventListenerProperties EventListenerProperties(
+ cc::EventListenerClass) const final;
+
// WebFrameWidget implementation.
void Close() override;
WebLocalFrame* LocalRoot() const override;
WebDragOperation DragTargetDragEnter(const WebDragData&,
- const WebFloatPoint& point_in_viewport,
- const WebFloatPoint& screen_point,
+ const gfx::PointF& point_in_viewport,
+ const gfx::PointF& screen_point,
WebDragOperationsMask operations_allowed,
int modifiers) override;
- WebDragOperation DragTargetDragOver(const WebFloatPoint& point_in_viewport,
- const WebFloatPoint& screen_point,
+ WebDragOperation DragTargetDragOver(const gfx::PointF& point_in_viewport,
+ const gfx::PointF& screen_point,
WebDragOperationsMask operations_allowed,
int modifiers) override;
- void DragTargetDragLeave(const WebFloatPoint& point_in_viewport,
- const WebFloatPoint& screen_point) override;
+ void DragTargetDragLeave(const gfx::PointF& point_in_viewport,
+ const gfx::PointF& screen_point) override;
void DragTargetDrop(const WebDragData&,
- const WebFloatPoint& point_in_viewport,
- const WebFloatPoint& screen_point,
+ const gfx::PointF& point_in_viewport,
+ const gfx::PointF& screen_point,
int modifiers) override;
- void DragSourceEndedAt(const WebFloatPoint& point_in_viewport,
- const WebFloatPoint& screen_point,
+ void DragSourceEndedAt(const gfx::PointF& point_in_viewport,
+ const gfx::PointF& screen_point,
WebDragOperation) override;
- void DragSourceSystemDragEnded() override;
void SendOverscrollEventFromImplSide(
const gfx::Vector2dF& overscroll_delta,
cc::ElementId scroll_latched_element_id) override;
@@ -106,6 +140,12 @@ class CORE_EXPORT WebFrameWidgetBase
cc::ElementId scroll_latched_element_id) override;
WebLocalFrame* FocusedWebLocalFrameInWidget() const override;
+ void SetCompositorHosts(cc::LayerTreeHost*, cc::AnimationHost*) override;
+ void ApplyViewportChangesForTesting(
+ const ApplyViewportChangesArgs& args) override;
+ void NotifySwapAndPresentationTime(
+ WebReportTimeCallback swap_callback,
+ WebReportTimeCallback presentation_callback) override;
// Called when a drag-n-drop operation should begin.
void StartDragging(network::mojom::ReferrerPolicy,
@@ -123,9 +163,18 @@ class CORE_EXPORT WebFrameWidgetBase
void DidNotAcquirePointerLock() override;
void DidLosePointerLock() override;
void ShowContextMenu(WebMenuSourceType) override;
+ void BeginFrame(base::TimeTicks frame_time) final;
+ void SetCompositorVisible(bool visible) override;
+ void UpdateVisualState() override;
+ void WillBeginCompositorFrame() final;
- // Image decode functionality.
- void RequestDecode(const PaintImage&, base::OnceCallback<void(bool)>);
+ // WidgetBaseClient methods.
+ void DispatchRafAlignedInput(base::TimeTicks frame_time) override;
+ void RecordTimeToFirstActivePaint(base::TimeDelta duration) override;
+
+ // mojom::blink::FrameWidget methods.
+ void DragSourceSystemDragEnded() override;
+ void SetBackgroundOpaque(bool opaque) override;
// Called when the FrameView for this Widget's local root is created.
virtual void DidCreateLocalRootView() {}
@@ -136,9 +185,64 @@ class CORE_EXPORT WebFrameWidgetBase
// focused frame has a different local root.
LocalFrame* FocusedLocalFrameInWidget() const;
- void RequestAnimationAfterDelay(const base::TimeDelta&);
-
- virtual void Trace(blink::Visitor*);
+ virtual void Trace(Visitor*);
+
+ // 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
+ void SetNeedsRecalculateRasterScales();
+
+ // Sets the background color to be filled in as gutter behind/around the
+ // painted content. Non-composited WebViews need not implement this, as they
+ // paint into another widget which has a background color of its own.
+ void SetBackgroundColor(SkColor color);
+
+ // Starts an animation of the page scale to a target scale factor and scroll
+ // offset.
+ // If use_anchor is true, destination is a point on the screen that will
+ // remain fixed for the duration of the animation.
+ // If use_anchor is false, destination is the final top-left scroll position.
+ void StartPageScaleAnimation(const gfx::Vector2d& destination,
+ bool use_anchor,
+ float new_page_scale,
+ base::TimeDelta duration);
+
+ // Called to update if scroll events should be sent.
+ void SetHaveScrollEventHandlers(bool);
+
+ // Start deferring commits to the compositor, allowing document lifecycle
+ // updates without committing the layer tree. Commits are deferred
+ // until at most the given |timeout| has passed. If multiple calls are made
+ // when deferral is active then the initial timeout applies.
+ void StartDeferringCommits(base::TimeDelta timeout);
+ // Immediately stop deferring commits.
+ void StopDeferringCommits(cc::PaintHoldingCommitTrigger);
+
+ // Prevents any updates to the input for the layer tree, and the layer tree
+ // itself, and the layer tree from becoming visible.
+ std::unique_ptr<cc::ScopedDeferMainFrameUpdate> DeferMainFrameUpdate();
+
+ // Sets the amount that the top and bottom browser controls are showing, from
+ // 0 (hidden) to 1 (fully shown).
+ void SetBrowserControlsShownRatio(float top_ratio, float bottom_ratio);
+
+ // Set browser controls params. These params consist of top and bottom
+ // heights, min-heights, browser_controls_shrink_blink_size, and
+ // animate_browser_controls_height_changes. If
+ // animate_browser_controls_height_changes is set to true, changes to the
+ // browser controls height will be animated. If
+ // browser_controls_shrink_blink_size is set to true, then Blink shrunk the
+ // viewport clip layers by the top and bottom browser controls height. Top
+ // controls will translate the web page down and do not immediately scroll
+ // when hiding. The bottom controls scroll immediately and never translate the
+ // content (only clip it).
+ void SetBrowserControlsParams(cc::BrowserControlsParams params);
+
+ cc::LayerTreeDebugState GetLayerTreeDebugState();
+ void SetLayerTreeDebugState(const cc::LayerTreeDebugState& state);
+
+ // Ask compositor to composite a frame for testing. This will generate a
+ // BeginMainFrame, and update the document lifecycle.
+ void SynchronouslyCompositeForTesting(base::TimeTicks frame_time);
protected:
enum DragAction { kDragEnter, kDragOver };
@@ -147,14 +251,13 @@ class CORE_EXPORT WebFrameWidgetBase
// updating a drag over a target. If we're starting a drag, |isEntering|
// should be true.
WebDragOperation DragTargetDragEnterOrOver(
- const WebFloatPoint& point_in_viewport,
- const WebFloatPoint& screen_point,
+ const gfx::PointF& point_in_viewport,
+ const gfx::PointF& screen_point,
DragAction,
int modifiers);
// Helper function to call VisualViewport::viewportToRootFrame().
- WebFloatPoint ViewportToRootFrame(
- const WebFloatPoint& point_in_viewport) const;
+ gfx::PointF ViewportToRootFrame(const gfx::PointF& point_in_viewport) const;
WebViewImpl* View() const;
@@ -167,6 +270,11 @@ class CORE_EXPORT WebFrameWidgetBase
virtual PageWidgetEventHandler* GetPageWidgetEventHandler() = 0;
+ // Return the LocalFrameView used for animation scrolling. This is overridden
+ // by WebViewFrameWidget and should eventually be removed once null does not
+ // need to be passed for the main frame.
+ virtual LocalFrameView* GetLocalFrameViewForAnimationScrolling() = 0;
+
// A copy of the web drop data object we received from the browser.
Member<DataObject> current_drag_data_;
@@ -180,6 +288,10 @@ class CORE_EXPORT WebFrameWidgetBase
// current drop target in this WebView (the drop target can accept the drop).
WebDragOperation drag_operation_ = kWebDragOperationNone;
+ // Base functionality all widgets have. This is a member as to avoid
+ // complicated inheritance structures.
+ std::unique_ptr<WidgetBase> widget_base_;
+
private:
void CancelDrag();
void RequestAnimationAfterDelayTimerFired(TimerBase*);
@@ -210,6 +322,9 @@ 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_;
+
friend class WebViewImpl;
};
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 a799f241e99..dd8f1641e16 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
@@ -38,7 +38,6 @@
#include "build/build_config.h"
#include "cc/layers/picture_layer.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_scroll_into_view_params.h"
#include "third_party/blink/public/web/web_autofill_client.h"
#include "third_party/blink/public/web/web_element.h"
#include "third_party/blink/public/web/web_frame_widget.h"
@@ -85,6 +84,7 @@
#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/keyboard_codes.h"
+#include "third_party/blink/renderer/platform/widget/widget_base.h"
namespace blink {
namespace {
@@ -105,8 +105,17 @@ FloatRect NormalizeRect(const IntRect& to_normalize, const IntRect& base_rect) {
// WebFrameWidget ------------------------------------------------------------
-WebFrameWidget* WebFrameWidget::CreateForMainFrame(WebWidgetClient* client,
- WebLocalFrame* main_frame) {
+WebFrameWidget* WebFrameWidget::CreateForMainFrame(
+ WebWidgetClient* client,
+ WebLocalFrame* main_frame,
+ CrossVariantMojoAssociatedRemote<mojom::blink::FrameWidgetHostInterfaceBase>
+ mojo_frame_widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::blink::FrameWidgetInterfaceBase>
+ mojo_frame_widget,
+ CrossVariantMojoAssociatedRemote<mojom::blink::WidgetHostInterfaceBase>
+ mojo_widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::blink::WidgetInterfaceBase>
+ mojo_widget) {
DCHECK(client) << "A valid WebWidgetClient must be supplied.";
DCHECK(!main_frame->Parent()); // This is the main frame.
@@ -123,14 +132,24 @@ WebFrameWidget* WebFrameWidget::CreateForMainFrame(WebWidgetClient* client,
// caller needs to release by calling Close().
// TODO(dcheng): Remove the special bridge class for main frame widgets.
auto* widget = MakeGarbageCollected<WebViewFrameWidget>(
- util::PassKey<WebFrameWidget>(), *client, web_view_impl);
+ util::PassKey<WebFrameWidget>(), *client, web_view_impl,
+ std::move(mojo_frame_widget_host), std::move(mojo_frame_widget),
+ std::move(mojo_widget_host), std::move(mojo_widget));
widget->BindLocalRoot(*main_frame);
return widget;
}
WebFrameWidget* WebFrameWidget::CreateForChildLocalRoot(
WebWidgetClient* client,
- WebLocalFrame* local_root) {
+ WebLocalFrame* local_root,
+ CrossVariantMojoAssociatedRemote<mojom::blink::FrameWidgetHostInterfaceBase>
+ mojo_frame_widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::blink::FrameWidgetInterfaceBase>
+ mojo_frame_widget,
+ CrossVariantMojoAssociatedRemote<mojom::blink::WidgetHostInterfaceBase>
+ mojo_widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::blink::WidgetInterfaceBase>
+ mojo_widget) {
DCHECK(client) << "A valid WebWidgetClient must be supplied.";
DCHECK(local_root->Parent()); // This is not the main frame.
// Frames whose direct ancestor is a remote frame are local roots. Verify this
@@ -141,19 +160,34 @@ WebFrameWidget* WebFrameWidget::CreateForChildLocalRoot(
// Note: this isn't a leak, as the object has a self-reference that the
// caller needs to release by calling Close().
auto* widget = MakeGarbageCollected<WebFrameWidgetImpl>(
- util::PassKey<WebFrameWidget>(), *client);
+ util::PassKey<WebFrameWidget>(), *client,
+ std::move(mojo_frame_widget_host), std::move(mojo_frame_widget),
+ std::move(mojo_widget_host), std::move(mojo_widget));
widget->BindLocalRoot(*local_root);
return widget;
}
-WebFrameWidgetImpl::WebFrameWidgetImpl(util::PassKey<WebFrameWidget>,
- WebWidgetClient& client)
- : WebFrameWidgetBase(client),
+WebFrameWidgetImpl::WebFrameWidgetImpl(
+ util::PassKey<WebFrameWidget>,
+ WebWidgetClient& client,
+ CrossVariantMojoAssociatedRemote<mojom::blink::FrameWidgetHostInterfaceBase>
+ frame_widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::blink::FrameWidgetInterfaceBase>
+ frame_widget,
+ CrossVariantMojoAssociatedRemote<mojom::blink::WidgetHostInterfaceBase>
+ widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::blink::WidgetInterfaceBase>
+ widget)
+ : WebFrameWidgetBase(client,
+ std::move(frame_widget_host),
+ std::move(frame_widget),
+ std::move(widget_host),
+ std::move(widget)),
self_keep_alive_(PERSISTENT_FROM_HERE, this) {}
WebFrameWidgetImpl::~WebFrameWidgetImpl() = default;
-void WebFrameWidgetImpl::Trace(blink::Visitor* visitor) {
+void WebFrameWidgetImpl::Trace(Visitor* visitor) {
visitor->Trace(mouse_capture_element_);
WebFrameWidgetBase::Trace(visitor);
}
@@ -165,9 +199,6 @@ void WebFrameWidgetImpl::Close() {
WebFrameWidgetBase::Close();
- animation_host_ = nullptr;
- root_layer_ = nullptr;
-
self_keep_alive_.Clear();
}
@@ -255,8 +286,8 @@ void WebFrameWidgetImpl::SetSuppressFrameRequestsWorkaroundFor704763Only(
GetPage()->Animator().SetSuppressFrameRequestsWorkaroundFor704763Only(
suppress_frame_requests);
}
-void WebFrameWidgetImpl::BeginFrame(base::TimeTicks last_frame_time,
- bool record_main_frame_metrics) {
+
+void WebFrameWidgetImpl::BeginMainFrame(base::TimeTicks last_frame_time) {
TRACE_EVENT1("blink", "WebFrameWidgetImpl::beginFrame", "frameTime",
last_frame_time);
DCHECK(!last_frame_time.is_null());
@@ -266,7 +297,7 @@ void WebFrameWidgetImpl::BeginFrame(base::TimeTicks last_frame_time,
DocumentLifecycle::AllowThrottlingScope throttling_scope(
LocalRootImpl()->GetFrame()->GetDocument()->Lifecycle());
- if (record_main_frame_metrics) {
+ if (WidgetBase::ShouldRecordBeginMainFrameMetrics()) {
SCOPED_UMA_AND_UKM_TIMER(
LocalRootImpl()->GetFrame()->View()->EnsureUkmAggregator(),
LocalFrameUkmAggregator::kAnimate);
@@ -284,22 +315,6 @@ void WebFrameWidgetImpl::DidBeginFrame() {
PageWidgetDelegate::DidBeginFrame(*LocalRootImpl()->GetFrame());
}
-void WebFrameWidgetImpl::BeginRafAlignedInput() {
- if (LocalRootImpl()) {
- raf_aligned_input_start_time_.emplace(base::TimeTicks::Now());
- }
-}
-
-void WebFrameWidgetImpl::EndRafAlignedInput() {
- if (LocalRootImpl()) {
- DCHECK(raf_aligned_input_start_time_);
- LocalRootImpl()->GetFrame()->View()->EnsureUkmAggregator().RecordSample(
- LocalFrameUkmAggregator::kHandleInputEvents,
- raf_aligned_input_start_time_.value(), base::TimeTicks::Now());
- }
- raf_aligned_input_start_time_.reset();
-}
-
void WebFrameWidgetImpl::BeginUpdateLayers() {
if (LocalRootImpl())
update_layers_start_time_.emplace(base::TimeTicks::Now());
@@ -322,13 +337,15 @@ void WebFrameWidgetImpl::BeginCommitCompositorFrame() {
}
}
-void WebFrameWidgetImpl::EndCommitCompositorFrame() {
+void WebFrameWidgetImpl::EndCommitCompositorFrame(
+ base::TimeTicks commit_start_time) {
if (LocalRootImpl()) {
- // Some tests call this without ever beginning a frame, so don't check for
- // timing data.
- LocalRootImpl()->GetFrame()->View()->EnsureUkmAggregator().RecordSample(
- LocalFrameUkmAggregator::kProxyCommit,
- commit_compositor_frame_start_time_.value(), base::TimeTicks::Now());
+ LocalRootImpl()
+ ->GetFrame()
+ ->View()
+ ->EnsureUkmAggregator()
+ .RecordImplCompositorSample(commit_compositor_frame_start_time_.value(),
+ commit_start_time, base::TimeTicks::Now());
}
commit_compositor_frame_start_time_.reset();
}
@@ -341,7 +358,8 @@ void WebFrameWidgetImpl::RecordStartOfFrameMetrics() {
}
void WebFrameWidgetImpl::RecordEndOfFrameMetrics(
- base::TimeTicks frame_begin_time) {
+ base::TimeTicks frame_begin_time,
+ cc::ActiveFrameSequenceTrackers trackers) {
if (!LocalRootImpl())
return;
@@ -349,7 +367,8 @@ void WebFrameWidgetImpl::RecordEndOfFrameMetrics(
->GetFrame()
->View()
->EnsureUkmAggregator()
- .RecordEndOfFrameMetrics(frame_begin_time, base::TimeTicks::Now());
+ .RecordEndOfFrameMetrics(frame_begin_time, base::TimeTicks::Now(),
+ trackers);
}
std::unique_ptr<cc::BeginMainFrameMetrics>
@@ -364,8 +383,8 @@ WebFrameWidgetImpl::GetBeginMainFrameMetrics() {
.GetBeginMainFrameMetrics();
}
-void WebFrameWidgetImpl::UpdateLifecycle(LifecycleUpdate requested_update,
- LifecycleUpdateReason reason) {
+void WebFrameWidgetImpl::UpdateLifecycle(WebLifecycleUpdate requested_update,
+ DocumentUpdateReason reason) {
TRACE_EVENT0("blink", "WebFrameWidgetImpl::updateAllLifecyclePhases");
if (!LocalRootImpl())
return;
@@ -527,9 +546,10 @@ bool WebFrameWidgetImpl::ScrollFocusedEditableElementIntoView() {
return false;
PhysicalRect rect_to_scroll;
- WebScrollIntoViewParams params;
+ auto params = ScrollAlignment::CreateScrollIntoViewParams();
GetScrollParamsForFocusedEditableElement(*element, rect_to_scroll, params);
- element->GetLayoutObject()->ScrollRectToVisible(rect_to_scroll, params);
+ element->GetLayoutObject()->ScrollRectToVisible(rect_to_scroll,
+ std::move(params));
return true;
}
@@ -543,11 +563,9 @@ void WebFrameWidgetImpl::IntrinsicSizingInfoChanged(
Client()->IntrinsicSizingInfoChanged(web_sizing_info);
}
-void WebFrameWidgetImpl::ApplyViewportChanges(const ApplyViewportChangesArgs&) {
-}
-
void WebFrameWidgetImpl::MouseCaptureLost() {
- TRACE_EVENT_ASYNC_END0("input", "capturing mouse", this);
+ TRACE_EVENT_NESTABLE_ASYNC_END0("input", "capturing mouse",
+ TRACE_ID_LOCAL(this));
mouse_capture_element_ = nullptr;
}
@@ -588,7 +606,8 @@ void WebFrameWidgetImpl::SetFocus(bool enable) {
// TODO(editing-dev): The use of
// UpdateStyleAndLayout needs to be audited.
// See http://crbug.com/590369 for more details.
- focused_frame->GetDocument()->UpdateStyleAndLayout();
+ focused_frame->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kFocus);
focused_frame->GetInputMethodController().FinishComposingText(
InputMethodController::kKeepSelection);
@@ -616,10 +635,6 @@ bool WebFrameWidgetImpl::SelectionBounds(WebRect& anchor_web,
return true;
}
-bool WebFrameWidgetImpl::IsAcceleratedCompositingActive() const {
- return is_accelerated_compositing_active_;
-}
-
void WebFrameWidgetImpl::SetRemoteViewportIntersection(
const ViewportIntersectionState& intersection_state) {
// Remote viewports are only applicable to local frames with remote ancestors.
@@ -681,8 +696,8 @@ void WebFrameWidgetImpl::HandleMouseDown(LocalFrame& main_frame,
// Take capture on a mouse down on a plugin so we can send it mouse events.
// If the hit node is a plugin but a scrollbar is over it don't start mouse
// capture because it will interfere with the scrollbar receiving events.
- PhysicalOffset point(LayoutUnit(event.PositionInWidget().x),
- LayoutUnit(event.PositionInWidget().y));
+ PhysicalOffset point(LayoutUnit(event.PositionInWidget().x()),
+ LayoutUnit(event.PositionInWidget().y()));
if (event.button == WebMouseEvent::Button::kLeft) {
HitTestLocation location(
LocalRootImpl()->GetFrameView()->ConvertFromRootFrame(point));
@@ -695,8 +710,9 @@ void WebFrameWidgetImpl::HandleMouseDown(LocalFrame& main_frame,
if (!result.GetScrollbar() && hit_node && hit_node->GetLayoutObject() &&
hit_node->GetLayoutObject()->IsEmbeddedObject() && html_element &&
html_element->IsPluginElement()) {
- mouse_capture_element_ = ToHTMLPlugInElement(hit_node);
- TRACE_EVENT_ASYNC_BEGIN0("input", "capturing mouse", this);
+ mouse_capture_element_ = To<HTMLPlugInElement>(hit_node);
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("input", "capturing mouse",
+ TRACE_ID_LOCAL(this));
}
}
@@ -851,6 +867,10 @@ PageWidgetEventHandler* WebFrameWidgetImpl::GetPageWidgetEventHandler() {
return this;
}
+LocalFrameView* WebFrameWidgetImpl::GetLocalFrameViewForAnimationScrolling() {
+ return LocalRootImpl()->GetFrame()->View();
+}
+
WebInputEventResult WebFrameWidgetImpl::HandleKeyEvent(
const WebKeyboardEvent& event) {
DCHECK((event.GetType() == WebInputEvent::kRawKeyDown) ||
@@ -865,6 +885,17 @@ WebInputEventResult WebFrameWidgetImpl::HandleKeyEvent(
// event.
suppress_next_keypress_event_ = false;
+ // If there is a popup open, it should be the one processing the event,
+ // not the page.
+ scoped_refptr<WebPagePopupImpl> page_popup = View()->GetPagePopup();
+ if (page_popup) {
+ page_popup->HandleKeyEvent(event);
+ if (event.GetType() == WebInputEvent::kRawKeyDown) {
+ suppress_next_keypress_event_ = true;
+ }
+ return WebInputEventResult::kHandledSystem;
+ }
+
auto* frame = DynamicTo<LocalFrame>(FocusedCoreFrame());
if (!frame)
return WebInputEventResult::kNotHandled;
@@ -972,14 +1003,6 @@ Element* WebFrameWidgetImpl::FocusedElement() const {
return document->FocusedElement();
}
-void WebFrameWidgetImpl::SetAnimationHost(cc::AnimationHost* animation_host) {
- DCHECK(Client());
- animation_host_ = animation_host;
-
- GetPage()->AnimationHostInitialized(*animation_host_,
- LocalRootImpl()->GetFrame()->View());
-}
-
PaintLayerCompositor* WebFrameWidgetImpl::Compositor() const {
LocalFrame* frame = LocalRootImpl()->GetFrame();
if (!frame || !frame->GetDocument() || !frame->GetDocument()->GetLayoutView())
@@ -989,9 +1012,7 @@ PaintLayerCompositor* WebFrameWidgetImpl::Compositor() const {
}
void WebFrameWidgetImpl::SetRootLayer(scoped_refptr<cc::Layer> layer) {
- root_layer_ = std::move(layer);
-
- if (!root_layer_) {
+ if (!layer) {
// This notifies the WebFrameWidgetImpl that its LocalFrame tree is being
// detached.
return;
@@ -999,20 +1020,14 @@ void WebFrameWidgetImpl::SetRootLayer(scoped_refptr<cc::Layer> layer) {
// WebFrameWidgetImpl is used for child frames, which always have a
// transparent background color.
- Client()->SetBackgroundColor(SK_ColorTRANSPARENT);
+ widget_base_->LayerTreeHost()->set_background_color(SK_ColorTRANSPARENT);
// Pass the limits even though this is for subframes, as the limits will
// be needed in setting the raster scale.
Client()->SetPageScaleStateAndLimits(1.f, false /* is_pinch_gesture_active */,
View()->MinimumPageScaleFactor(),
View()->MaximumPageScaleFactor());
- // TODO(danakj): SetIsAcceleratedCompositingActive() also sets the root layer
- // if it's not null..
- Client()->SetRootLayer(root_layer_);
-}
-
-cc::AnimationHost* WebFrameWidgetImpl::AnimationHost() const {
- return animation_host_;
+ widget_base_->LayerTreeHost()->SetRootLayer(layer);
}
HitTestResult WebFrameWidgetImpl::CoreHitTestResultAt(
@@ -1062,7 +1077,7 @@ void WebFrameWidgetImpl::DidCreateLocalRootView() {
void WebFrameWidgetImpl::GetScrollParamsForFocusedEditableElement(
const Element& element,
PhysicalRect& rect_to_scroll,
- WebScrollIntoViewParams& params) {
+ mojom::blink::ScrollIntoViewParamsPtr& params) {
LocalFrameView& frame_view = *element.GetDocument().View();
IntRect absolute_element_bounds =
element.GetLayoutObject()->AbsoluteBoundingBoxRect();
@@ -1098,12 +1113,12 @@ void WebFrameWidgetImpl::GetScrollParamsForFocusedEditableElement(
}
}
- params.zoom_into_rect = View()->ShouldZoomToLegibleScale(element);
- params.relative_element_bounds = NormalizeRect(
+ params->zoom_into_rect = View()->ShouldZoomToLegibleScale(element);
+ params->relative_element_bounds = NormalizeRect(
Intersection(absolute_element_bounds, maximal_rect), maximal_rect);
- params.relative_caret_bounds = NormalizeRect(
+ params->relative_caret_bounds = NormalizeRect(
Intersection(absolute_caret_bounds, maximal_rect), maximal_rect);
- params.behavior = WebScrollIntoViewParams::kInstant;
+ params->behavior = mojom::blink::ScrollBehavior::kInstant;
rect_to_scroll = PhysicalRect(maximal_rect);
}
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 b339acdd287..eb9c8bb7208 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
@@ -37,8 +37,8 @@
#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "base/util/type_safety/pass_key.h"
+#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink-forward.h"
#include "third_party/blink/public/platform/web_coalesced_input_event.h"
-#include "third_party/blink/public/platform/web_point.h"
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/public/web/web_input_method_controller.h"
#include "third_party/blink/renderer/core/frame/web_frame_widget_base.h"
@@ -70,7 +70,17 @@ class WebFrameWidgetImpl;
class WebFrameWidgetImpl final : public WebFrameWidgetBase,
public PageWidgetEventHandler {
public:
- explicit WebFrameWidgetImpl(util::PassKey<WebFrameWidget>, WebWidgetClient&);
+ WebFrameWidgetImpl(
+ util::PassKey<WebFrameWidget>,
+ WebWidgetClient&,
+ CrossVariantMojoAssociatedRemote<
+ mojom::blink::FrameWidgetHostInterfaceBase> frame_widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::blink::FrameWidgetInterfaceBase>
+ frame_widget,
+ CrossVariantMojoAssociatedRemote<mojom::blink::WidgetHostInterfaceBase>
+ widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::blink::WidgetInterfaceBase>
+ widget);
~WebFrameWidgetImpl() override;
// WebWidget functions:
@@ -79,22 +89,19 @@ class WebFrameWidgetImpl final : public WebFrameWidgetBase,
void Resize(const WebSize&) override;
void DidEnterFullscreen() override;
void DidExitFullscreen() override;
- void SetSuppressFrameRequestsWorkaroundFor704763Only(bool) final;
- void BeginFrame(base::TimeTicks last_frame_time,
- bool record_main_frame_metrics) override;
void DidBeginFrame() override;
- void BeginRafAlignedInput() override;
- void EndRafAlignedInput() override;
void BeginUpdateLayers() override;
void EndUpdateLayers() override;
void BeginCommitCompositorFrame() override;
- void EndCommitCompositorFrame() override;
+ void EndCommitCompositorFrame(base::TimeTicks commit_start_time) override;
void RecordStartOfFrameMetrics() override;
- void RecordEndOfFrameMetrics(base::TimeTicks) override;
+ void RecordEndOfFrameMetrics(
+ base::TimeTicks,
+ cc::ActiveFrameSequenceTrackers trackers) override;
std::unique_ptr<cc::BeginMainFrameMetrics> GetBeginMainFrameMetrics()
override;
- void UpdateLifecycle(LifecycleUpdate requested_update,
- LifecycleUpdateReason reason) override;
+ void UpdateLifecycle(WebLifecycleUpdate requested_update,
+ DocumentUpdateReason reason) override;
void ThemeChanged() override;
WebHitTestResult HitTestResultAt(const gfx::Point&) override;
WebInputEventResult DispatchBufferedTouchEvents() override;
@@ -102,11 +109,9 @@ class WebFrameWidgetImpl final : public WebFrameWidgetBase,
void SetCursorVisibilityState(bool is_visible) override;
void OnFallbackCursorModeToggled(bool is_on) override;
- void ApplyViewportChanges(const ApplyViewportChangesArgs&) override;
void MouseCaptureLost() override;
void SetFocus(bool enable) override;
bool SelectionBounds(WebRect& anchor, WebRect& focus) const override;
- bool IsAcceleratedCompositingActive() const override;
void SetRemoteViewportIntersection(const ViewportIntersectionState&) override;
void SetIsInert(bool) override;
void SetInheritedEffectiveTouchAction(TouchAction) override;
@@ -127,22 +132,25 @@ class WebFrameWidgetImpl final : public WebFrameWidgetBase,
PaintLayerCompositor* Compositor() const;
// WebFrameWidgetBase overrides:
- void SetAnimationHost(cc::AnimationHost*) override;
bool ForSubframe() const override { return true; }
void IntrinsicSizingInfoChanged(const IntrinsicSizingInfo&) override;
void DidCreateLocalRootView() override;
-
- void SetRootLayer(scoped_refptr<cc::Layer>) override;
- cc::AnimationHost* AnimationHost() const override;
HitTestResult CoreHitTestResultAt(const gfx::Point&) override;
void ZoomToFindInPageRect(const WebRect& rect_in_root_frame) override;
+ // FrameWidget overrides:
+ void SetRootLayer(scoped_refptr<cc::Layer>) override;
+
+ // WidgetBaseClient overrides:
+ void BeginMainFrame(base::TimeTicks last_frame_time) override;
+ void SetSuppressFrameRequestsWorkaroundFor704763Only(bool) final;
+
void UpdateMainFrameLayoutSize();
// Event related methods:
void MouseContextMenu(const WebMouseEvent&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
friend class WebFrameWidget; // For WebFrameWidget::create.
@@ -164,6 +172,7 @@ class WebFrameWidgetImpl final : public WebFrameWidgetBase,
WebInputEventResult HandleCharEvent(const WebKeyboardEvent&) override;
PageWidgetEventHandler* GetPageWidgetEventHandler() override;
+ LocalFrameView* GetLocalFrameViewForAnimationScrolling() override;
LocalFrame* FocusedLocalFrameAvailableForIme() const;
@@ -174,23 +183,17 @@ class WebFrameWidgetImpl final : public WebFrameWidgetBase,
void GetScrollParamsForFocusedEditableElement(
const Element& element,
PhysicalRect& rect_to_scroll,
- WebScrollIntoViewParams& params);
+ mojom::blink::ScrollIntoViewParamsPtr& params);
base::Optional<WebSize> size_;
// If set, the (plugin) element which has mouse capture.
Member<HTMLPlugInElement> mouse_capture_element_;
- cc::AnimationHost* animation_host_ = nullptr;
- scoped_refptr<cc::Layer> root_layer_;
-
// Metrics gathering timing information
- base::Optional<base::TimeTicks> raf_aligned_input_start_time_;
base::Optional<base::TimeTicks> update_layers_start_time_;
base::Optional<base::TimeTicks> commit_compositor_frame_start_time_;
- bool is_accelerated_compositing_active_ = false;
-
bool suppress_next_keypress_event_ = false;
bool did_suspend_parsing_ = false;
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 8c984ae92de..2660078b0ed 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
@@ -89,7 +89,6 @@
#include <algorithm>
#include <memory>
-#include <set>
#include <utility>
#include "base/macros.h"
@@ -97,15 +96,13 @@
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "third_party/blink/public/common/frame/frame_owner_element_type.h"
-#include "third_party/blink/public/common/media/media_player_action.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
+#include "third_party/blink/public/mojom/frame/media_player_action.mojom-blink.h"
#include "third_party/blink/public/platform/interface_registry.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_double_size.h"
-#include "third_party/blink/public/platform/web_float_point.h"
#include "third_party/blink/public/platform/web_float_rect.h"
#include "third_party/blink/public/platform/web_isolated_world_info.h"
-#include "third_party/blink/public/platform/web_point.h"
#include "third_party/blink/public/platform/web_rect.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/platform/web_size.h"
@@ -122,7 +119,6 @@
#include "third_party/blink/public/web/web_form_element.h"
#include "third_party/blink/public/web/web_frame_owner_properties.h"
#include "third_party/blink/public/web/web_history_item.h"
-#include "third_party/blink/public/web/web_icon_url.h"
#include "third_party/blink/public/web/web_input_element.h"
#include "third_party/blink/public/web/web_local_frame_client.h"
#include "third_party/blink/public/web/web_manifest_manager.h"
@@ -135,7 +131,6 @@
#include "third_party/blink/public/web/web_range.h"
#include "third_party/blink/public/web/web_script_source.h"
#include "third_party/blink/public/web/web_serialized_script_value.h"
-#include "third_party/blink/public/web/web_text_direction.h"
#include "third_party/blink/public/web/web_tree_scope_type.h"
#include "third_party/blink/renderer/bindings/core/v8/binding_security.h"
#include "third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h"
@@ -149,11 +144,9 @@
#include "third_party/blink/renderer/core/clipboard/clipboard_utilities.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/icon_url.h"
-#include "third_party/blink/renderer/core/dom/ignore_opens_during_unload_count_incrementer.h"
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/dom/node_traversal.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
-
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
#include "third_party/blink/renderer/core/editing/editor.h"
#include "third_party/blink/renderer/core/editing/ephemeral_range.h"
@@ -189,7 +182,6 @@
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/page_scale_constraints_set.h"
#include "third_party/blink/renderer/core/frame/pausable_script_executor.h"
-#include "third_party/blink/renderer/core/frame/picture_in_picture_controller.h"
#include "third_party/blink/renderer/core/frame/remote_frame.h"
#include "third_party/blink/renderer/core/frame/remote_frame_owner.h"
#include "third_party/blink/renderer/core/frame/screen_orientation_controller.h"
@@ -208,8 +200,6 @@
#include "third_party/blink/renderer/core/html/html_iframe_element.h"
#include "third_party/blink/renderer/core/html/html_image_element.h"
#include "third_party/blink/renderer/core/html/html_link_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/plugin_document.h"
#include "third_party/blink/renderer/core/html/portal/document_portals.h"
#include "third_party/blink/renderer/core/html/portal/dom_window_portal_host.h"
@@ -220,6 +210,7 @@
#include "third_party/blink/renderer/core/input/context_menu_allowed_scope.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.h"
#include "third_party/blink/renderer/core/inspector/main_thread_debugger.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
@@ -263,6 +254,7 @@
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.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/weborigin/scheme_registry.h"
#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
@@ -471,7 +463,7 @@ class ChromePluginPrintContext final : public ChromePrintContext {
~ChromePluginPrintContext() override = default;
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(plugin_);
ChromePrintContext::Trace(visitor);
}
@@ -541,7 +533,7 @@ class PaintPreviewContext : public PrintContext {
LocalFrameView* frame_view = GetFrame()->View();
DCHECK(frame_view);
PropertyTreeState property_tree_state =
- frame_view->GetLayoutView()->FirstFragment().LocalBorderBoxProperties();
+ frame_view->GetLayoutView()->FirstFragment().ContentsProperties();
// This calls BeginRecording on |builder| with dimensions specified by the
// CullRect.
@@ -586,12 +578,25 @@ WebLocalFrame* WebLocalFrame::FrameForCurrentContext() {
return FrameForContext(context);
}
-WebLocalFrame* WebLocalFrame::FrameForContext(v8::Local<v8::Context> context) {
- return WebLocalFrameImpl::FromFrame(ToLocalFrameIfNotDetached(context));
+void WebLocalFrameImpl::NotifyUserActivation() {
+ LocalFrame::NotifyUserActivation(GetFrame());
+}
+
+bool WebLocalFrameImpl::HasStickyUserActivation() {
+ return GetFrame()->HasStickyUserActivation();
+}
+
+bool WebLocalFrameImpl::HasTransientUserActivation() {
+ return LocalFrame::HasTransientUserActivation(GetFrame());
}
-WebLocalFrame* WebLocalFrame::FromFrameOwnerElement(const WebElement& element) {
- return WebLocalFrameImpl::FromFrameOwnerElement(element);
+bool WebLocalFrameImpl::ConsumeTransientUserActivation(
+ UserActivationUpdateSource update_source) {
+ return LocalFrame::ConsumeTransientUserActivation(GetFrame(), update_source);
+}
+
+WebLocalFrame* WebLocalFrame::FrameForContext(v8::Local<v8::Context> context) {
+ return WebLocalFrameImpl::FromFrame(ToLocalFrameIfNotDetached(context));
}
bool WebLocalFrameImpl::IsWebLocalFrame() const {
@@ -636,14 +641,6 @@ void WebLocalFrameImpl::SetName(const WebString& name) {
GetFrame()->Tree().SetName(name, FrameTree::kReplicate);
}
-WebVector<WebIconURL> WebLocalFrameImpl::IconURLs(int icon_types_mask) const {
- // The URL to the icon may be in the header. As such, only
- // ask the loader for the icon if it's finished loading.
- if (GetFrame()->GetDocument()->LoadEventFinished())
- return GetFrame()->GetDocument()->IconURLs(icon_types_mask);
- return WebVector<WebIconURL>();
-}
-
void WebLocalFrameImpl::SetContentSettingsClient(
WebContentSettingsClient* client) {
content_settings_client_ = client;
@@ -677,7 +674,7 @@ WebSize WebLocalFrameImpl::GetScrollOffset() const {
void WebLocalFrameImpl::SetScrollOffset(const WebSize& offset) {
if (ScrollableArea* scrollable_area = LayoutViewport()) {
scrollable_area->SetScrollOffset(ScrollOffset(offset.width, offset.height),
- kProgrammaticScroll);
+ mojom::blink::ScrollType::kProgrammatic);
}
}
@@ -735,18 +732,6 @@ void WebLocalFrameImpl::SetIsAdSubframe(
GetFrame()->SetIsAdSubframe(ad_frame_type);
}
-void WebLocalFrameImpl::DispatchUnloadEvent() {
- if (!GetFrame())
- return;
- SubframeLoadingDisabler disabler(GetFrame()->GetDocument());
- // https://html.spec.whatwg.org/C/browsing-the-web.html#unload-a-document
- // The ignore-opens-during-unload counter of a Document must be incremented
- // when unloading itself.
- IgnoreOpensDuringUnloadCountIncrementer ignore_opens_during_unload(
- GetFrame()->GetDocument());
- GetFrame()->Loader().DispatchUnloadEvent(nullptr, nullptr);
-}
-
void WebLocalFrameImpl::ExecuteScript(const WebScriptSource& source) {
DCHECK(GetFrame());
v8::HandleScope handle_scope(ToIsolate(GetFrame()));
@@ -806,8 +791,10 @@ void WebLocalFrameImpl::SetIsolatedWorldInfo(int32_t world_id,
info.security_origin.Get()
? info.security_origin.Get()
->IsolatedCopy()
- ->GetOriginForAgentCluster(
- GetFrame()->GetDocument()->GetAgentClusterID())
+ ->GetOriginForAgentCluster(GetFrame()
+ ->GetDocument()
+ ->ToExecutionContext()
+ ->GetAgentClusterID())
: nullptr;
CHECK(info.content_security_policy.IsNull() || security_origin);
@@ -921,7 +908,7 @@ v8::MaybeLocal<v8::Value> WebLocalFrameImpl::CallFunctionEvenIfScriptDisabled(
v8::Local<v8::Value> argv[]) {
DCHECK(GetFrame());
return V8ScriptRunner::CallFunction(
- function, GetFrame()->GetDocument(), receiver, argc,
+ function, GetFrame()->GetDocument()->ToExecutionContext(), receiver, argc,
static_cast<v8::Local<v8::Value>*>(argv), ToIsolate(GetFrame()));
}
@@ -954,8 +941,8 @@ void WebLocalFrameImpl::StartReload(WebFrameLoadType frame_load_type) {
if (GetTextFinder())
GetTextFinder()->ClearActiveFindMatch();
- GetFrame()->Loader().StartNavigation(FrameLoadRequest(nullptr, request),
- frame_load_type);
+ FrameLoadRequest frame_load_request(nullptr, request);
+ GetFrame()->Loader().StartNavigation(frame_load_request, frame_load_type);
}
void WebLocalFrameImpl::ReloadImage(const WebNode& web_node) {
@@ -977,9 +964,9 @@ void WebLocalFrameImpl::StartNavigation(const WebURLRequest& request) {
if (GetTextFinder())
GetTextFinder()->ClearActiveFindMatch();
- GetFrame()->Loader().StartNavigation(
- FrameLoadRequest(nullptr, request.ToResourceRequest()),
- WebFrameLoadType::kStandard);
+ FrameLoadRequest frame_load_request(nullptr, request.ToResourceRequest());
+ GetFrame()->Loader().StartNavigation(frame_load_request,
+ WebFrameLoadType::kStandard);
}
void WebLocalFrameImpl::StopLoading() {
@@ -1025,19 +1012,12 @@ WebAssociatedURLLoader* WebLocalFrameImpl::CreateAssociatedURLLoader(
void WebLocalFrameImpl::ReplaceSelection(const WebString& text) {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kSelection);
GetFrame()->GetEditor().ReplaceSelection(text);
}
-void WebLocalFrameImpl::SetMarkedText(const WebString& text,
- unsigned location,
- unsigned length) {
- Vector<ImeTextSpan> decorations;
- GetFrame()->GetInputMethodController().SetComposition(text, decorations,
- location, length);
-}
-
void WebLocalFrameImpl::UnmarkText() {
GetFrame()->GetInputMethodController().CancelComposition();
}
@@ -1064,7 +1044,7 @@ bool WebLocalFrameImpl::FirstRectForCharacterRange(
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- editable->GetDocument().UpdateStyleAndLayout();
+ editable->GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
const EphemeralRange range =
PlainTextRange(location, location + length).CreateRange(*editable);
@@ -1077,12 +1057,12 @@ bool WebLocalFrameImpl::FirstRectForCharacterRange(
}
size_t WebLocalFrameImpl::CharacterIndexForPoint(
- const WebPoint& point_in_viewport) const {
+ const gfx::Point& point_in_viewport) const {
if (!GetFrame())
return kNotFound;
HitTestLocation location(
- GetFrame()->View()->ViewportToFrame(point_in_viewport));
+ GetFrame()->View()->ViewportToFrame(IntPoint(point_in_viewport)));
HitTestResult result = GetFrame()->GetEventHandler().HitTestResultAtLocation(
location, HitTestRequest::kReadOnly | HitTestRequest::kActive);
return GetFrame()->Selection().CharacterIndexForPoint(
@@ -1139,8 +1119,9 @@ bool WebLocalFrameImpl::IsCommandEnabled(const WebString& name) const {
return GetFrame()->GetEditor().IsCommandEnabled(name);
}
-bool WebLocalFrameImpl::SelectionTextDirection(WebTextDirection& start,
- WebTextDirection& end) const {
+bool WebLocalFrameImpl::SelectionTextDirection(
+ base::i18n::TextDirection& start,
+ base::i18n::TextDirection& end) const {
FrameSelection& selection = frame_->Selection();
if (!selection.IsAvailable()) {
// plugins/mouse-capture-inside-shadow.html reaches here
@@ -1149,15 +1130,15 @@ bool WebLocalFrameImpl::SelectionTextDirection(WebTextDirection& start,
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- frame_->GetDocument()->UpdateStyleAndLayout();
+ frame_->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kSelection);
if (selection.ComputeVisibleSelectionInDOMTree()
.ToNormalizedEphemeralRange()
.IsNull())
return false;
- start = ToWebTextDirection(PrimaryDirectionOf(
+ start = ToBaseTextDirection(PrimaryDirectionOf(
*selection.ComputeVisibleSelectionInDOMTree().Start().AnchorNode()));
- end = ToWebTextDirection(PrimaryDirectionOf(
+ end = ToBaseTextDirection(PrimaryDirectionOf(
*selection.ComputeVisibleSelectionInDOMTree().End().AnchorNode()));
return true;
}
@@ -1172,7 +1153,7 @@ bool WebLocalFrameImpl::IsSelectionAnchorFirst() const {
return selection.GetSelectionInDOMTree().IsBaseFirst();
}
-void WebLocalFrameImpl::SetTextDirection(WebTextDirection direction) {
+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.
@@ -1182,15 +1163,15 @@ void WebLocalFrameImpl::SetTextDirection(WebTextDirection direction) {
return;
switch (direction) {
- case kWebTextDirectionDefault:
+ case base::i18n::TextDirection::UNKNOWN_DIRECTION:
editor.SetBaseWritingDirection(WritingDirection::kNatural);
break;
- case kWebTextDirectionLeftToRight:
+ case base::i18n::TextDirection::LEFT_TO_RIGHT:
editor.SetBaseWritingDirection(WritingDirection::kLeftToRight);
break;
- case kWebTextDirectionRightToLeft:
+ case base::i18n::TextDirection::RIGHT_TO_LEFT:
editor.SetBaseWritingDirection(WritingDirection::kRightToLeft);
break;
@@ -1209,7 +1190,8 @@ void WebLocalFrameImpl::ReplaceMisspelledRange(const WebString& text) {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kSpellCheck);
GetFrame()->GetSpellChecker().ReplaceMisspelledRange(text);
}
@@ -1241,7 +1223,8 @@ bool WebLocalFrameImpl::HasSelection() const {
WebRange WebLocalFrameImpl::SelectionRange() const {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kSelection);
return GetFrame()
->Selection()
@@ -1258,7 +1241,8 @@ WebString WebLocalFrameImpl::SelectionAsText() const {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kSelection);
String text = GetFrame()->Selection().SelectedText(
TextIteratorBehavior::EmitsObjectReplacementCharacterBehavior());
@@ -1278,7 +1262,8 @@ WebString WebLocalFrameImpl::SelectionAsMarkup() const {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
// Selection normalization and markup generation require clean layout.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kSelection);
return GetFrame()->Selection().SelectedHTMLForClipboard();
}
@@ -1288,12 +1273,13 @@ bool WebLocalFrameImpl::SelectWordAroundCaret() {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kSelection);
return GetFrame()->Selection().SelectWordAroundCaret();
}
-void WebLocalFrameImpl::SelectRange(const WebPoint& base_in_viewport,
- const WebPoint& extent_in_viewport) {
+void WebLocalFrameImpl::SelectRange(const gfx::Point& base_in_viewport,
+ const gfx::Point& extent_in_viewport) {
MoveRangeSelection(base_in_viewport, extent_in_viewport);
}
@@ -1305,7 +1291,8 @@ void WebLocalFrameImpl::SelectRange(
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kSelection);
const EphemeralRange& range = web_range.CreateEphemeralRange(GetFrame());
if (range.IsNull())
@@ -1338,7 +1325,8 @@ void WebLocalFrameImpl::SelectRange(
WebString WebLocalFrameImpl::RangeAsText(const WebRange& web_range) {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kEditing);
DocumentLifecycle::DisallowTransitionScope disallow_transition(
GetFrame()->GetDocument()->Lifecycle());
@@ -1348,44 +1336,48 @@ WebString WebLocalFrameImpl::RangeAsText(const WebRange& web_range) {
TextIteratorBehavior::EmitsObjectReplacementCharacterBehavior());
}
-void WebLocalFrameImpl::MoveRangeSelectionExtent(const WebPoint& point) {
+void WebLocalFrameImpl::MoveRangeSelectionExtent(const gfx::Point& point) {
TRACE_EVENT0("blink", "WebLocalFrameImpl::moveRangeSelectionExtent");
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kSelection);
GetFrame()->Selection().MoveRangeSelectionExtent(
- GetFrame()->View()->ViewportToFrame(point));
+ GetFrame()->View()->ViewportToFrame(IntPoint(point)));
}
void WebLocalFrameImpl::MoveRangeSelection(
- const WebPoint& base_in_viewport,
- const WebPoint& extent_in_viewport,
+ const gfx::Point& base_in_viewport,
+ const gfx::Point& extent_in_viewport,
WebFrame::TextGranularity granularity) {
TRACE_EVENT0("blink", "WebLocalFrameImpl::moveRangeSelection");
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kSelection);
blink::TextGranularity blink_granularity = blink::TextGranularity::kCharacter;
if (granularity == WebFrame::kWordGranularity)
blink_granularity = blink::TextGranularity::kWord;
GetFrame()->Selection().MoveRangeSelection(
- GetFrame()->View()->ViewportToFrame(base_in_viewport),
- GetFrame()->View()->ViewportToFrame(extent_in_viewport),
+ GetFrame()->View()->ViewportToFrame(IntPoint(base_in_viewport)),
+ GetFrame()->View()->ViewportToFrame(IntPoint(extent_in_viewport)),
blink_granularity);
}
-void WebLocalFrameImpl::MoveCaretSelection(const WebPoint& point_in_viewport) {
+void WebLocalFrameImpl::MoveCaretSelection(
+ const gfx::Point& point_in_viewport) {
TRACE_EVENT0("blink", "WebLocalFrameImpl::moveCaretSelection");
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. see http://crbug.com/590369 for more details.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kSelection);
const IntPoint point_in_contents =
- GetFrame()->View()->ViewportToFrame(point_in_viewport);
+ GetFrame()->View()->ViewportToFrame(IntPoint(point_in_viewport));
GetFrame()->Selection().MoveCaretSelection(point_in_contents);
}
@@ -1394,7 +1386,8 @@ bool WebLocalFrameImpl::SetEditableSelectionOffsets(int start, int end) {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kSelection);
return GetFrame()->GetInputMethodController().SetEditableSelectionOffsets(
PlainTextRange(start, end));
@@ -1419,7 +1412,8 @@ bool WebLocalFrameImpl::SetCompositionFromExistingText(
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kEditing);
input_method_controller.SetCompositionFromExistingText(
ImeTextSpanVectorBuilder::Build(ime_text_spans), composition_start,
@@ -1443,7 +1437,8 @@ void WebLocalFrameImpl::ExtendSelectionAndDelete(int before, int after) {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kSelection);
GetFrame()->GetInputMethodController().ExtendSelectionAndDelete(before,
after);
@@ -1458,7 +1453,8 @@ void WebLocalFrameImpl::DeleteSurroundingText(int before, int after) {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kEditing);
GetFrame()->GetInputMethodController().DeleteSurroundingText(before, after);
}
@@ -1473,16 +1469,13 @@ void WebLocalFrameImpl::DeleteSurroundingTextInCodePoints(int before,
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kEditing);
GetFrame()->GetInputMethodController().DeleteSurroundingTextInCodePoints(
before, after);
}
-void WebLocalFrameImpl::SetCaretVisible(bool visible) {
- GetFrame()->Selection().SetCaretVisible(visible);
-}
-
WebPlugin* WebLocalFrameImpl::FocusedPluginIfInputMethodSupported() {
WebPluginContainerImpl* container = GetFrame()->GetWebPluginContainer();
if (container && container->SupportsInputMethod())
@@ -1547,7 +1540,7 @@ int WebLocalFrameImpl::PrintBegin(const WebPrintParams& print_params,
} else {
// We only support printing plugin nodes for now.
plugin_container =
- ToWebPluginContainerImpl(constrain_to_node.PluginContainer());
+ To<WebPluginContainerImpl>(constrain_to_node.PluginContainer());
}
if (plugin_container && plugin_container->SupportsPaginatedPrint()) {
@@ -1592,7 +1585,7 @@ bool WebLocalFrameImpl::GetPrintPresetOptionsForPlugin(
WebPrintPresetOptions* preset_options) {
WebPluginContainerImpl* plugin_container =
node.IsNull() ? GetFrame()->GetWebPluginContainer()
- : ToWebPluginContainerImpl(node.PluginContainer());
+ : To<WebPluginContainerImpl>(node.PluginContainer());
if (!plugin_container || !plugin_container->SupportsPaginatedPrint())
return false;
@@ -1615,13 +1608,8 @@ bool WebLocalFrameImpl::CapturePaintPreview(const WebRect& bounds,
return success;
}
-bool WebLocalFrameImpl::HasCustomPageSizeStyle(int page_index) {
- return GetFrame()->GetDocument()->StyleForPage(page_index)->PageSizeType() !=
- EPageSizeType::kAuto;
-}
-
-bool WebLocalFrameImpl::IsPageBoxVisible(int page_index) {
- return GetFrame()->GetDocument()->IsPageBoxVisible(page_index);
+PageSizeType WebLocalFrameImpl::GetPageSizeType(int page_index) {
+ return GetFrame()->GetDocument()->StyleForPage(page_index)->GetPageSizeType();
}
void WebLocalFrameImpl::PageSizeAndMarginsInPixels(int page_index,
@@ -1636,13 +1624,6 @@ void WebLocalFrameImpl::PageSizeAndMarginsInPixels(int page_index,
page_size = size;
}
-WebString WebLocalFrameImpl::PageProperty(const WebString& property_name,
- int page_index) {
- DCHECK(print_context_);
- return print_context_->PageProperty(GetFrame(), property_name.Utf8().c_str(),
- page_index);
-}
-
void WebLocalFrameImpl::PrintPagesForTesting(
cc::PaintCanvas* canvas,
const WebSize& page_size_in_pixels) {
@@ -1667,7 +1648,7 @@ WebLocalFrame* WebLocalFrame::CreateMainFrame(
InterfaceRegistry* interface_registry,
WebFrame* opener,
const WebString& name,
- WebSandboxFlags sandbox_flags,
+ mojom::blink::WebSandboxFlags sandbox_flags,
const FeaturePolicy::FeatureState& opener_feature_state) {
return WebLocalFrameImpl::CreateMainFrame(
web_view, client, interface_registry, opener, name, sandbox_flags,
@@ -1678,9 +1659,10 @@ WebLocalFrame* WebLocalFrame::CreateProvisional(
WebLocalFrameClient* client,
InterfaceRegistry* interface_registry,
WebFrame* previous_frame,
- const FramePolicy& frame_policy) {
- return WebLocalFrameImpl::CreateProvisional(client, interface_registry,
- previous_frame, frame_policy);
+ const FramePolicy& frame_policy,
+ const WebString& name) {
+ return WebLocalFrameImpl::CreateProvisional(
+ client, interface_registry, previous_frame, frame_policy, name);
}
WebLocalFrameImpl* WebLocalFrameImpl::CreateMainFrame(
@@ -1689,7 +1671,7 @@ WebLocalFrameImpl* WebLocalFrameImpl::CreateMainFrame(
InterfaceRegistry* interface_registry,
WebFrame* opener,
const WebString& name,
- WebSandboxFlags sandbox_flags,
+ mojom::blink::WebSandboxFlags sandbox_flags,
const FeaturePolicy::FeatureState& opener_feature_state) {
auto* frame = MakeGarbageCollected<WebLocalFrameImpl>(
util::PassKey<WebLocalFrameImpl>(), WebTreeScopeType::kDocument, client,
@@ -1708,17 +1690,20 @@ WebLocalFrameImpl* WebLocalFrameImpl::CreateProvisional(
WebLocalFrameClient* client,
blink::InterfaceRegistry* interface_registry,
WebFrame* previous_web_frame,
- const FramePolicy& frame_policy) {
+ const FramePolicy& frame_policy,
+ const WebString& name) {
DCHECK(client);
+ Frame* previous_frame = ToCoreFrame(*previous_web_frame);
+ DCHECK(name.IsEmpty() || name.Equals(previous_frame->Tree().GetName()));
auto* web_frame = MakeGarbageCollected<WebLocalFrameImpl>(
util::PassKey<WebLocalFrameImpl>(),
previous_web_frame->InShadowTree() ? WebTreeScopeType::kShadow
: WebTreeScopeType::kDocument,
client, interface_registry);
- Frame* previous_frame = ToCoreFrame(*previous_web_frame);
web_frame->SetParent(previous_web_frame->Parent());
web_frame->SetOpener(previous_web_frame->Opener());
- WebSandboxFlags sandbox_flags = WebSandboxFlags::kNone;
+ mojom::blink::WebSandboxFlags sandbox_flags =
+ mojom::blink::WebSandboxFlags::kNone;
FeaturePolicy::FeatureState feature_state;
if (!previous_frame->Owner()) {
// Provisional main frames need to force sandbox flags. This is necessary
@@ -1741,10 +1726,11 @@ WebLocalFrameImpl* WebLocalFrameImpl::CreateProvisional(
// observable, it will have the real FrameOwner, and any subsequent real
// documents will correctly inherit sandbox flags from the owner.
web_frame->InitializeCoreFrame(
- *previous_frame->GetPage(), MakeGarbageCollected<DummyFrameOwner>(),
- previous_frame->Tree().GetName(),
- &ToCoreFrame(*previous_web_frame)->window_agent_factory(), sandbox_flags,
- feature_state);
+ *previous_frame->GetPage(), MakeGarbageCollected<DummyFrameOwner>(), name,
+ frame_policy.disallow_document_access
+ ? nullptr
+ : &ToCoreFrame(*previous_web_frame)->window_agent_factory(),
+ sandbox_flags, feature_state);
LocalFrame* new_frame = web_frame->GetFrame();
new_frame->SetOwner(previous_frame->Owner());
@@ -1802,7 +1788,7 @@ WebLocalFrameImpl::~WebLocalFrameImpl() {
g_frame_count--;
}
-void WebLocalFrameImpl::Trace(blink::Visitor* visitor) {
+void WebLocalFrameImpl::Trace(Visitor* visitor) {
visitor->Trace(local_frame_client_);
visitor->Trace(find_in_page_);
visitor->Trace(frame_);
@@ -1822,7 +1808,7 @@ void WebLocalFrameImpl::InitializeCoreFrame(
FrameOwner* owner,
const AtomicString& name,
WindowAgentFactory* window_agent_factory,
- WebSandboxFlags sandbox_flags,
+ mojom::blink::WebSandboxFlags sandbox_flags,
const FeaturePolicy::FeatureState& opener_feature_state) {
SetCoreFrame(MakeGarbageCollected<LocalFrame>(local_frame_client_.Get(), page,
owner, window_agent_factory,
@@ -1861,7 +1847,7 @@ LocalFrame* WebLocalFrameImpl::CreateChildFrame(
: WebTreeScopeType::kShadow;
WebFrameOwnerProperties owner_properties(
owner_element->BrowsingContextContainerName(),
- owner_element->ScrollingMode(), owner_element->MarginWidth(),
+ owner_element->ScrollbarMode(), owner_element->MarginWidth(),
owner_element->MarginHeight(), owner_element->AllowFullscreen(),
owner_element->AllowPaymentRequest(), owner_element->IsDisplayNone(),
owner_element->RequiredCsp());
@@ -1880,7 +1866,7 @@ LocalFrame* WebLocalFrameImpl::CreateChildFrame(
webframe_child->InitializeCoreFrame(
*GetFrame()->GetPage(), owner_element, name,
- owner_element->DisallowDocumentAccess()
+ owner_element->GetFramePolicy().disallow_document_access
? nullptr
: &GetFrame()->window_agent_factory());
@@ -1896,12 +1882,12 @@ std::pair<RemoteFrame*, base::UnguessableToken> WebLocalFrameImpl::CreatePortal(
base::UnguessableToken portal_token;
std::tie(portal_frame, portal_token) = client_->CreatePortal(
portal_receiver.PassHandle(), portal_client.PassHandle(), portal);
- return {ToWebRemoteFrameImpl(portal_frame)->GetFrame(), portal_token};
+ return {To<WebRemoteFrameImpl>(portal_frame)->GetFrame(), portal_token};
}
RemoteFrame* WebLocalFrameImpl::AdoptPortal(HTMLPortalElement* portal) {
- WebRemoteFrameImpl* portal_frame =
- ToWebRemoteFrameImpl(client_->AdoptPortal(portal->GetToken(), portal));
+ auto* portal_frame =
+ To<WebRemoteFrameImpl>(client_->AdoptPortal(portal->GetToken(), portal));
return portal_frame->GetFrame();
}
@@ -1976,13 +1962,6 @@ WebLocalFrameImpl* WebLocalFrameImpl::FromFrame(LocalFrame& frame) {
return To<WebLocalFrameImpl>(client->GetWebFrame());
}
-WebLocalFrameImpl* WebLocalFrameImpl::FromFrameOwnerElement(Element* element) {
- auto* frame_owner_element = DynamicTo<HTMLFrameOwnerElement>(element);
- if (!frame_owner_element)
- return nullptr;
- return FromFrame(To<LocalFrame>(frame_owner_element->ContentFrame()));
-}
-
WebViewImpl* WebLocalFrameImpl::ViewImpl() const {
if (!GetFrame())
return nullptr;
@@ -1991,12 +1970,12 @@ WebViewImpl* WebLocalFrameImpl::ViewImpl() const {
void WebLocalFrameImpl::DidFailLoad(const ResourceError& error,
WebHistoryCommitType web_commit_type) {
- if (!Client())
- return;
- WebURLError web_error = error;
if (WebPluginContainerImpl* plugin = GetFrame()->GetWebPluginContainer())
plugin->DidFailLoading(error);
- Client()->DidFailLoad(web_error, web_commit_type);
+ WebDocumentLoader* document_loader = GetDocumentLoader();
+ DCHECK(document_loader);
+ GetFrame()->GetLocalFrameHostRemote().DidFailLoadWithError(
+ document_loader->GetUrl(), error.ErrorCode());
}
void WebLocalFrameImpl::DidFinish() {
@@ -2039,10 +2018,6 @@ WebContentCaptureClient* WebLocalFrameImpl::ContentCaptureClient() const {
return content_capture_client_;
}
-bool WebLocalFrameImpl::IsLocalRoot() const {
- return frame_->IsLocalRoot();
-}
-
bool WebLocalFrameImpl::IsProvisional() const {
return frame_->IsProvisional();
}
@@ -2062,19 +2037,14 @@ WebFrame* WebLocalFrameImpl::FindFrameByName(const WebString& name) {
return WebFrame::FromFrame(GetFrame()->Tree().FindFrameByName(name));
}
-bool WebLocalFrameImpl::ScrollTo(const gfx::Point& scrollPosition,
- bool animate,
- base::OnceClosure on_finish) {
- if (!GetFrame())
- return false;
- ScrollableArea* area = GetFrame()->View()->GetScrollableArea();
- ScrollOffset offset = area->ScrollPositionToOffset(
- FloatPoint(scrollPosition.x(), scrollPosition.y()));
- area->SetScrollOffset(
- offset, kProgrammaticScroll,
- animate ? kScrollBehaviorSmooth : kScrollBehaviorInstant,
- ScrollableArea::ScrollCallback(std::move(on_finish)));
- return true;
+void WebLocalFrameImpl::SetEmbeddingToken(
+ const base::UnguessableToken& embedding_token) {
+ frame_->SetEmbeddingToken(embedding_token);
+}
+
+const base::Optional<base::UnguessableToken>&
+WebLocalFrameImpl::GetEmbeddingToken() {
+ return frame_->GetEmbeddingToken();
}
void WebLocalFrameImpl::SendPings(const WebURL& destination_url) {
@@ -2095,15 +2065,13 @@ bool WebLocalFrameImpl::DispatchBeforeUnloadEvent(bool is_reload) {
void WebLocalFrameImpl::CommitNavigation(
std::unique_ptr<WebNavigationParams> navigation_params,
- std::unique_ptr<WebDocumentLoader::ExtraData> extra_data,
- base::OnceClosure call_before_attaching_new_document) {
+ std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) {
DCHECK(GetFrame());
DCHECK(!navigation_params->url.ProtocolIs("javascript"));
if (GetTextFinder())
GetTextFinder()->ClearActiveFindMatch();
- GetFrame()->Loader().CommitNavigation(
- std::move(navigation_params), std::move(extra_data),
- std::move(call_before_attaching_new_document));
+ GetFrame()->Loader().CommitNavigation(std::move(navigation_params),
+ std::move(extra_data));
}
blink::mojom::CommitResult WebLocalFrameImpl::CommitSameDocumentNavigation(
@@ -2135,7 +2103,7 @@ void WebLocalFrameImpl::LoadJavaScriptURL(const WebURL& url) {
LocalFrame::NotifyUserActivation(GetFrame());
GetFrame()->GetScriptController().ExecuteJavaScriptURL(
- url, kDoNotCheckContentSecurityPolicy);
+ url, network::mojom::CSPDisposition::DO_NOT_CHECK);
}
WebNavigationControl::FallbackContentResult
@@ -2149,51 +2117,6 @@ WebLocalFrameImpl::MaybeRenderFallbackContent(const WebURLError& error) const {
: NoLoadInProgress;
}
-void WebLocalFrameImpl::RenderFallbackContent() const {
- // TODO(ekaramad): If the owner renders its own content, then the current
- // ContentFrame() should detach (see https://crbug.com/850223).
- auto* owner = frame_->DeprecatedLocalOwner();
- DCHECK(IsA<HTMLObjectElement>(owner));
- owner->RenderFallbackContent(frame_);
-}
-
-// Called when a navigation is blocked because a Content Security Policy (CSP)
-// is infringed.
-void WebLocalFrameImpl::ReportContentSecurityPolicyViolation(
- const blink::WebContentSecurityPolicyViolation& violation) {
- AddMessageToConsole(blink::WebConsoleMessage(
- mojom::ConsoleMessageLevel::kError, violation.console_message,
- violation.source_location.url, violation.source_location.line_number,
- violation.source_location.column_number));
-
- std::unique_ptr<SourceLocation> source_location =
- std::make_unique<SourceLocation>(
- violation.source_location.url, violation.source_location.line_number,
- violation.source_location.column_number, nullptr);
-
- DCHECK(GetFrame() && GetFrame()->GetDocument());
- Document* document = GetFrame()->GetDocument();
- Vector<String> report_endpoints;
- for (const WebString& end_point : violation.report_endpoints)
- report_endpoints.push_back(end_point);
- auto directive_type =
- ContentSecurityPolicy::GetDirectiveType(violation.effective_directive);
- LocalFrame* context_frame =
- directive_type == ContentSecurityPolicy::DirectiveType::kFrameAncestors
- ? GetFrame()
- : nullptr;
- document->GetContentSecurityPolicy()->ReportViolation(
- violation.directive, directive_type, violation.console_message,
- violation.blocked_url, report_endpoints, violation.use_reporting_api,
- violation.header,
- static_cast<ContentSecurityPolicyHeaderType>(violation.disposition),
- ContentSecurityPolicy::ViolationType::kURLViolation,
- std::move(source_location), context_frame,
- violation.after_redirect ? RedirectStatus::kFollowedRedirect
- : RedirectStatus::kNoRedirect,
- nullptr /* Element */);
-}
-
bool WebLocalFrameImpl::IsLoading() const {
if (!GetFrame() || !GetFrame()->GetDocument())
return false;
@@ -2226,14 +2149,6 @@ bool WebLocalFrameImpl::HasCommittedFirstRealLoad() {
}
void WebLocalFrameImpl::BlinkFeatureUsageReport(
- const std::set<blink::mojom::WebFeature>& features) {
- DCHECK(!features.empty());
- // Assimilate all features used/performed by the browser into UseCounter.
- for (const auto& feature : features)
- UseCounter::Count(GetFrame()->GetDocument(), feature);
-}
-
-void WebLocalFrameImpl::BlinkFeatureUsageReport(
blink::mojom::WebFeature feature) {
UseCounter::Count(GetFrame()->GetDocument(), feature);
}
@@ -2269,6 +2184,15 @@ 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) {
+ 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) {
@@ -2292,16 +2216,6 @@ void WebLocalFrameImpl::SendOrientationChangeEvent() {
GetFrame()->DomWindow()->SendOrientationChangeEvent();
}
-void WebLocalFrameImpl::DidCallAddSearchProvider() {
- UseCounter::Count(GetFrame()->GetDocument(),
- WebFeature::kExternalAddSearchProvider);
-}
-
-void WebLocalFrameImpl::DidCallIsSearchProviderInstalled() {
- UseCounter::Count(GetFrame()->GetDocument(),
- WebFeature::kExternalIsSearchProviderInstalled);
-}
-
void WebLocalFrameImpl::DispatchMessageEventWithOriginCheck(
const WebSecurityOrigin& intended_target_origin,
const WebDOMMessageEvent& event) {
@@ -2343,7 +2257,7 @@ WebNode WebLocalFrameImpl::ContextMenuNode() const {
void WebLocalFrameImpl::WillBeDetached() {
// The |frame_widget_| can be null for frames in non-composited WebViews.
- if (IsLocalRoot() && frame_widget_)
+ if (frame_->IsLocalRoot() && frame_widget_)
frame_widget_->DidDetachLocalFrameTree();
if (dev_tools_agent_)
dev_tools_agent_->WillBeDestroyed();
@@ -2371,43 +2285,15 @@ WebFrameWidget* WebLocalFrameImpl::FrameWidget() const {
return frame_widget_;
}
-void WebLocalFrameImpl::CopyImageAt(const WebPoint& pos_in_viewport) {
- HitTestResult result = HitTestResultForVisualViewportPos(pos_in_viewport);
- if (!IsA<HTMLCanvasElement>(result.InnerNodeOrImageMapImage()) &&
- result.AbsoluteImageURL().IsEmpty()) {
- // There isn't actually an image at these coordinates. Might be because
- // the window scrolled while the context menu was open or because the page
- // changed itself between when we thought there was an image here and when
- // we actually tried to retreive the image.
- //
- // FIXME: implement a cache of the most recent HitTestResult to avoid having
- // to do two hit tests.
- return;
- }
-
- // TODO(editing-dev): The use of UpdateStyleAndLayout
- // needs to be audited. See http://crbug.com/590369 for more details.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
-
- GetFrame()->GetEditor().CopyImage(result);
+void WebLocalFrameImpl::CopyImageAtForTesting(
+ const gfx::Point& pos_in_viewport) {
+ GetFrame()->CopyImageAtViewportPoint(IntPoint(pos_in_viewport));
}
-void WebLocalFrameImpl::SaveImageAt(const WebPoint& pos_in_viewport) {
- Node* node = HitTestResultForVisualViewportPos(pos_in_viewport)
- .InnerNodeOrImageMapImage();
- if (!node || !(IsA<HTMLCanvasElement>(*node) || IsA<HTMLImageElement>(*node)))
- return;
-
- String url = To<Element>(*node).ImageSourceURL();
- if (!KURL(NullURL(), url).ProtocolIsData())
- return;
-
- client_->SaveImageFromDataURL(url);
-}
-
-WebSandboxFlags WebLocalFrameImpl::EffectiveSandboxFlagsForTesting() const {
+mojom::blink::WebSandboxFlags
+WebLocalFrameImpl::EffectiveSandboxFlagsForTesting() const {
if (!GetFrame())
- return WebSandboxFlags::kNone;
+ return mojom::blink::WebSandboxFlags::kNone;
SandboxFlags flags = GetFrame()->Loader().EffectiveSandboxFlags();
if (RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) {
// When some of sandbox flags set in the 'sandbox' attribute are implemented
@@ -2425,7 +2311,7 @@ WebSandboxFlags WebLocalFrameImpl::EffectiveSandboxFlagsForTesting() const {
->sandbox_flags_converted_to_feature_policies();
}
}
- return static_cast<WebSandboxFlags>(flags);
+ return static_cast<mojom::blink::WebSandboxFlags>(flags);
}
bool WebLocalFrameImpl::IsAllowedToDownload() const {
@@ -2437,15 +2323,15 @@ bool WebLocalFrameImpl::IsAllowedToDownload() const {
// allow downloads.
if (GetFrame()->Tree().Parent() &&
!GetFrame()->Tree().Parent()->GetSecurityContext()->IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kDownloads)) {
+ mojom::blink::FeaturePolicyFeature::kDownloads)) {
return false;
}
return !GetFrame()->Owner() ||
GetFrame()->Owner()->GetFramePolicy().allowed_to_download;
- } else {
- return (GetFrame()->Loader().EffectiveSandboxFlags() &
- WebSandboxFlags::kDownloads) == WebSandboxFlags::kNone;
}
+ return (GetFrame()->Loader().PendingEffectiveSandboxFlags() &
+ mojom::blink::WebSandboxFlags::kDownloads) ==
+ mojom::blink::WebSandboxFlags::kNone;
}
void WebLocalFrameImpl::UsageCountChromeLoadTimes(const WebString& metric) {
@@ -2506,8 +2392,8 @@ void WebLocalFrameImpl::ExtractSmartClipData(WebRect rect_in_viewport,
clip_text = clip_data.ClipData();
clip_rect = clip_data.RectInViewport();
- WebPoint start_point(rect_in_viewport.x, rect_in_viewport.y);
- WebPoint end_point(rect_in_viewport.x + rect_in_viewport.width,
+ IntPoint start_point(rect_in_viewport.x, rect_in_viewport.y);
+ IntPoint end_point(rect_in_viewport.x + rect_in_viewport.width,
rect_in_viewport.y + rect_in_viewport.height);
clip_html = CreateMarkupInRect(
GetFrame(), GetFrame()->View()->ViewportToFrame(start_point),
@@ -2542,79 +2428,22 @@ static String CreateMarkupInRect(LocalFrame* frame,
return CreateMarkup(end_position, start_position, create_markup_options);
}
-void WebLocalFrameImpl::AdvanceFocusInForm(WebFocusType focus_type) {
- DCHECK(GetFrame()->GetDocument());
- Element* element = GetFrame()->GetDocument()->FocusedElement();
- if (!element)
- return;
-
- Element* next_element =
- GetFrame()->GetPage()->GetFocusController().NextFocusableElementInForm(
- element, focus_type);
- if (!next_element)
- return;
-
- next_element->scrollIntoViewIfNeeded(true /*centerIfNeeded*/);
- next_element->focus();
-}
-
bool WebLocalFrameImpl::ShouldSuppressKeyboardForFocusedElement() {
if (!autofill_client_)
return false;
DCHECK(GetFrame()->GetDocument());
- auto* focused_form_control_element = ToHTMLFormControlElementOrNull(
+ auto* focused_form_control_element = DynamicTo<HTMLFormControlElement>(
GetFrame()->GetDocument()->FocusedElement());
return focused_form_control_element &&
autofill_client_->ShouldSuppressKeyboard(focused_form_control_element);
}
-void WebLocalFrameImpl::PerformMediaPlayerAction(
- const WebPoint& location,
- const MediaPlayerAction& action) {
- HitTestResult result = HitTestResultForVisualViewportPos(location);
- Node* node = result.InnerNode();
- if (!IsA<HTMLVideoElement>(*node) && !IsA<HTMLAudioElement>(*node))
- return;
-
- HTMLMediaElement* media_element = ToHTMLMediaElement(node);
- switch (action.type) {
- case MediaPlayerAction::Type::kPlay:
- if (action.enable)
- media_element->Play();
- else
- media_element->pause();
- break;
- case MediaPlayerAction::Type::kMute:
- media_element->setMuted(action.enable);
- break;
- case MediaPlayerAction::Type::kLoop:
- media_element->SetLoop(action.enable);
- break;
- case MediaPlayerAction::Type::kControls:
- media_element->SetBooleanAttribute(html_names::kControlsAttr,
- action.enable);
- break;
- case MediaPlayerAction::Type::kPictureInPicture:
- DCHECK(IsA<HTMLVideoElement>(media_element));
- if (action.enable) {
- PictureInPictureController::From(node->GetDocument())
- .EnterPictureInPicture(To<HTMLVideoElement>(media_element),
- nullptr /* promise */,
- nullptr /* options */);
- } else {
- PictureInPictureController::From(node->GetDocument())
- .ExitPictureInPicture(To<HTMLVideoElement>(media_element), nullptr);
- }
-
- break;
- }
-}
-
void WebLocalFrameImpl::OnPortalActivated(
const base::UnguessableToken& portal_token,
- mojo::ScopedInterfaceEndpointHandle portal_pipe,
- mojo::ScopedInterfaceEndpointHandle portal_client_pipe,
+ CrossVariantMojoAssociatedRemote<mojom::blink::PortalInterfaceBase> portal,
+ CrossVariantMojoAssociatedReceiver<mojom::blink::PortalClientInterfaceBase>
+ portal_client,
TransferableMessage data,
OnPortalActivatedCallback callback) {
LocalDOMWindow* window = GetFrame()->DomWindow();
@@ -2627,14 +2456,10 @@ void WebLocalFrameImpl::OnPortalActivated(
<< "portal activation is always cross-agent-cluster and should be "
"diagnosed early";
MessagePortArray* ports = MessagePort::EntanglePorts(
- *window->document(), std::move(blink_data.ports));
+ *window->document()->ToExecutionContext(), std::move(blink_data.ports));
PortalActivateEvent* event = PortalActivateEvent::Create(
- frame_.Get(), portal_token,
- mojo::PendingAssociatedRemote<mojom::blink::Portal>(
- std::move(portal_pipe), mojom::blink::Portal::Version_),
- mojo::PendingAssociatedReceiver<mojom::blink::PortalClient>(
- std::move(portal_client_pipe)),
+ frame_.Get(), portal_token, std::move(portal), std::move(portal_client),
std::move(blink_data.message), ports, std::move(callback));
ThreadDebugger* debugger = MainThreadDebugger::Instance();
@@ -2664,10 +2489,20 @@ void WebLocalFrameImpl::AddMessageToConsoleImpl(
bool discard_duplicates) {
DCHECK(GetFrame());
GetFrame()->GetDocument()->AddConsoleMessage(
- ConsoleMessage::CreateFromWebConsoleMessage(message, GetFrame()),
+ MakeGarbageCollected<ConsoleMessage>(message, GetFrame()),
discard_duplicates);
}
+void WebLocalFrameImpl::AddInspectorIssueImpl(
+ mojom::blink::InspectorIssueCode code) {
+ DCHECK(GetFrame());
+ auto info = mojom::blink::InspectorIssueInfo::New(
+ code, mojom::blink::InspectorIssueDetails::New(),
+ mojom::blink::AffectedResources::New());
+ GetFrame()->GetDocument()->AddInspectorIssue(
+ InspectorIssue::Create(std::move(info)));
+}
+
void WebLocalFrameImpl::SetTextCheckClient(
WebTextCheckClient* text_check_client) {
text_check_client_ = text_check_client;
@@ -2692,6 +2527,11 @@ Node* WebLocalFrameImpl::ContextMenuNodeInner() const {
.ContextMenuNodeForFrame(GetFrame());
}
+void WebLocalFrameImpl::WaitForDebuggerWhenShown() {
+ DCHECK(frame_->IsLocalRoot());
+ DevToolsAgentImpl()->WaitForDebuggerWhenShown();
+}
+
void WebLocalFrameImpl::SetDevToolsAgentImpl(WebDevToolsAgentImpl* agent) {
DCHECK(!dev_tools_agent_);
dev_tools_agent_ = agent;
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 e3d4a369e67..a8d2023b6b3 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
@@ -83,7 +83,6 @@ class WebSpellCheckPanelHostClient;
class WebView;
class WebViewImpl;
enum class WebFrameLoadType;
-struct WebContentSecurityPolicyViolation;
struct WebPrintParams;
class WindowAgentFactory;
@@ -111,31 +110,24 @@ class CORE_EXPORT WebLocalFrameImpl final
WebAutofillClient* AutofillClient() override;
void SetContentCaptureClient(WebContentCaptureClient*) override;
WebContentCaptureClient* ContentCaptureClient() const override;
- void DispatchUnloadEvent() override;
- WebVector<WebIconURL> IconURLs(int icon_types_mask) const override;
WebDocument GetDocument() const override;
WebString AssignedName() const override;
void SetName(const WebString&) override;
- bool IsLocalRoot() const override;
bool IsProvisional() const override;
WebLocalFrameImpl* LocalRoot() override;
WebFrameWidget* FrameWidget() const override;
WebFrame* FindFrameByName(const WebString& name) override;
- bool ScrollTo(const gfx::Point& scrollPosition,
- bool animate,
- base::OnceClosure on_finish) override;
+ void SetEmbeddingToken(
+ const base::UnguessableToken& embedding_token) override;
+ const base::Optional<base::UnguessableToken>& GetEmbeddingToken() override;
void SendPings(const WebURL& destination_url) override;
void StartReload(WebFrameLoadType) override;
void StartNavigation(const WebURLRequest&) override;
void EnableViewSourceMode(bool enable) override;
bool IsViewSourceModeEnabled() const override;
WebDocumentLoader* GetDocumentLoader() const override;
- void ReportContentSecurityPolicyViolation(
- const blink::WebContentSecurityPolicyViolation&) override;
void SetReferrerForRequest(WebURLRequest&, const WebURL& referrer) override;
bool IsNavigationScheduledWithin(base::TimeDelta interval) const override;
- void BlinkFeatureUsageReport(
- const std::set<blink::mojom::WebFeature>& features) override;
void BlinkFeatureUsageReport(blink::mojom::WebFeature feature) override;
void MixedContentFound(const WebURL& main_resource_url,
const WebURL& mixed_content_url,
@@ -144,16 +136,13 @@ class CORE_EXPORT WebLocalFrameImpl final
bool had_redirect,
const WebSourceLocation&) override;
void SendOrientationChangeEvent() override;
- bool IsPageBoxVisible(int page_index) override;
- bool HasCustomPageSizeStyle(int page_index) override;
+ PageSizeType GetPageSizeType(int page_index) override;
void PageSizeAndMarginsInPixels(int page_index,
WebDoubleSize& page_size,
int& margin_top,
int& margin_right,
int& margin_bottom,
int& margin_left) override;
- WebString PageProperty(const WebString& property_name,
- int page_index) override;
void ExecuteScript(const WebScriptSource&) override;
void ExecuteScriptInIsolatedWorld(int32_t world_id,
const WebScriptSource&) override;
@@ -194,46 +183,42 @@ class CORE_EXPORT WebLocalFrameImpl final
void BindDevToolsAgent(
mojo::ScopedInterfaceEndpointHandle devtools_agent_host_ptr_info,
mojo::ScopedInterfaceEndpointHandle devtools_agent_request) override;
- void SetMarkedText(const WebString&,
- unsigned location,
- unsigned length) override;
void UnmarkText() override;
bool HasMarkedText() const override;
WebRange MarkedRange() const override;
bool FirstRectForCharacterRange(unsigned location,
unsigned length,
WebRect&) const override;
- size_t CharacterIndexForPoint(const WebPoint&) const override;
+ size_t CharacterIndexForPoint(const gfx::Point&) const override;
bool ExecuteCommand(const WebString&) override;
bool ExecuteCommand(const WebString&, const WebString& value) override;
bool IsCommandEnabled(const WebString&) const override;
- bool SelectionTextDirection(WebTextDirection& start,
- WebTextDirection& end) const override;
+ bool SelectionTextDirection(base::i18n::TextDirection& start,
+ base::i18n::TextDirection& end) const override;
bool IsSelectionAnchorFirst() const override;
- void SetTextDirection(WebTextDirection) override;
+ void SetTextDirection(base::i18n::TextDirection) override;
bool HasSelection() const override;
WebRange SelectionRange() const override;
WebString SelectionAsText() const override;
WebString SelectionAsMarkup() const override;
bool SelectWordAroundCaret() override;
- void SelectRange(const WebPoint& base, const WebPoint& extent) override;
+ void SelectRange(const gfx::Point& base, const gfx::Point& extent) override;
void SelectRange(const WebRange&,
HandleVisibilityBehavior,
blink::mojom::SelectionMenuBehavior) override;
WebString RangeAsText(const WebRange&) override;
void MoveRangeSelection(
- const WebPoint& base,
- const WebPoint& extent,
+ const gfx::Point& base,
+ const gfx::Point& extent,
WebFrame::TextGranularity = kCharacterGranularity) override;
- void MoveCaretSelection(const WebPoint&) override;
+ void MoveCaretSelection(const gfx::Point&) override;
bool SetEditableSelectionOffsets(int start, int end) override;
bool SetCompositionFromExistingText(
int composition_start,
int composition_end,
const WebVector<WebImeTextSpan>& ime_text_spans) override;
void ExtendSelectionAndDelete(int before, int after) override;
- void SetCaretVisible(bool) override;
- void MoveRangeSelectionExtent(const WebPoint&) override;
+ void MoveRangeSelectionExtent(const gfx::Point&) override;
void ReplaceSelection(const WebString&) override;
void DeleteSurroundingText(int before, int after) override;
void DeleteSurroundingTextInCodePoints(int before, int after) override;
@@ -252,9 +237,8 @@ class CORE_EXPORT WebLocalFrameImpl final
const WebVector<WebString>& words) override;
void SetContentSettingsClient(WebContentSettingsClient*) override;
void ReloadImage(const WebNode&) override;
- void DidCallAddSearchProvider() override;
- void DidCallIsSearchProviderInstalled() override;
- WebSandboxFlags EffectiveSandboxFlagsForTesting() const override;
+ mojom::blink::WebSandboxFlags EffectiveSandboxFlagsForTesting()
+ const override;
bool IsAllowedToDownload() const override;
bool FindForTesting(int identifier,
const WebString& search_text,
@@ -265,17 +249,19 @@ class CORE_EXPORT WebLocalFrameImpl final
bool wrap_within_frame) override;
void SetTickmarks(const WebVector<WebRect>&) override;
WebNode ContextMenuNode() const override;
- void CopyImageAt(const WebPoint&) override;
- void SaveImageAt(const WebPoint&) override;
+ void CopyImageAtForTesting(const gfx::Point&) override;
void DispatchMessageEventWithOriginCheck(
const WebSecurityOrigin& intended_target_origin,
const WebDOMMessageEvent&) override;
void UsageCountChromeLoadTimes(const WebString& metric) override;
- void OnPortalActivated(const base::UnguessableToken& portal_token,
- mojo::ScopedInterfaceEndpointHandle portal_pipe,
- mojo::ScopedInterfaceEndpointHandle portal_client_pipe,
- TransferableMessage data,
- OnPortalActivatedCallback callback) override;
+ void OnPortalActivated(
+ const base::UnguessableToken& portal_token,
+ CrossVariantMojoAssociatedRemote<mojom::blink::PortalInterfaceBase>
+ portal,
+ CrossVariantMojoAssociatedReceiver<
+ mojom::blink::PortalClientInterfaceBase> portal_client,
+ TransferableMessage data,
+ OnPortalActivatedCallback callback) override;
void ForwardMessageFromHost(
TransferableMessage message,
const WebSecurityOrigin& source_origin,
@@ -301,28 +287,27 @@ class CORE_EXPORT WebLocalFrameImpl final
WebPrintPresetOptions*) override;
bool CapturePaintPreview(const WebRect& bounds,
cc::PaintCanvas* canvas) override;
- void AdvanceFocusInForm(WebFocusType) 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;
WebRect GetSelectionBoundsRectForTesting() const override;
- void PerformMediaPlayerAction(const WebPoint&,
- const MediaPlayerAction&) override;
void SetLifecycleState(mojom::FrameLifecycleState state) override;
void WasHidden() override;
void WasShown() override;
void SetAllowsCrossBrowsingInstanceFrameLookup() override;
-
- void CollectGarbageForTesting();
+ void NotifyUserActivation() override;
+ bool HasStickyUserActivation() override;
+ bool HasTransientUserActivation() override;
+ bool ConsumeTransientUserActivation(UserActivationUpdateSource) override;
// WebNavigationControl overrides:
bool DispatchBeforeUnloadEvent(bool) override;
void CommitNavigation(
std::unique_ptr<WebNavigationParams> navigation_params,
- std::unique_ptr<WebDocumentLoader::ExtraData> extra_data,
- base::OnceClosure call_before_attaching_new_document) override;
+ std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) override;
blink::mojom::CommitResult CommitSameDocumentNavigation(
const WebURL&,
WebFrameLoadType,
@@ -332,7 +317,6 @@ class CORE_EXPORT WebLocalFrameImpl final
void LoadJavaScriptURL(const WebURL&) override;
FallbackContentResult MaybeRenderFallbackContent(
const WebURLError&) const override;
- void RenderFallbackContent() const override;
void SetCommittedFirstRealLoad() override;
bool HasCommittedFirstRealLoad() override;
bool WillStartNavigation(
@@ -341,31 +325,38 @@ class CORE_EXPORT WebLocalFrameImpl final
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;
void InitializeCoreFrame(
Page&,
FrameOwner*,
const AtomicString& name,
WindowAgentFactory*,
- WebSandboxFlags sandbox_flags = WebSandboxFlags::kNone,
+ mojom::blink::WebSandboxFlags sandbox_flags =
+ mojom::blink::WebSandboxFlags::kNone,
const FeaturePolicy::FeatureState& opener_feature_state =
FeaturePolicy::FeatureState());
LocalFrame* GetFrame() const { return frame_.Get(); }
void WillBeDetached();
void WillDetachParent();
+ void CollectGarbageForTesting();
static WebLocalFrameImpl* CreateMainFrame(WebView*,
WebLocalFrameClient*,
InterfaceRegistry*,
WebFrame* opener,
const WebString& name,
- WebSandboxFlags,
+ mojom::blink::WebSandboxFlags,
const FeaturePolicy::FeatureState&);
static WebLocalFrameImpl* CreateProvisional(WebLocalFrameClient*,
InterfaceRegistry*,
WebFrame*,
- const FramePolicy&);
+ const FramePolicy&,
+ const WebString& name);
WebLocalFrameImpl(util::PassKey<WebLocalFrameImpl>,
WebTreeScopeType,
@@ -395,7 +386,6 @@ class CORE_EXPORT WebLocalFrameImpl final
static WebLocalFrameImpl* FromFrame(LocalFrame*);
static WebLocalFrameImpl* FromFrame(LocalFrame&);
- static WebLocalFrameImpl* FromFrameOwnerElement(Element*);
WebViewImpl* ViewImpl() const;
@@ -448,13 +438,15 @@ class CORE_EXPORT WebLocalFrameImpl final
// Returns true if our print context suggests using printing layout.
bool UsePrintingLayout() const;
- virtual void Trace(blink::Visitor*);
+ virtual void Trace(Visitor*);
protected:
// WebLocalFrame protected overrides:
void AddMessageToConsoleImpl(const WebConsoleMessage&,
bool discard_duplicates) override;
+ void AddInspectorIssueImpl(mojom::blink::InspectorIssueCode code) override;
+
private:
friend LocalFrameClientImpl;
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 6af3e589df4..74d711852ad 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
@@ -6,24 +6,40 @@
#include "third_party/blink/renderer/core/exported/web_view_impl.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
+#include "third_party/blink/renderer/platform/widget/widget_base.h"
namespace blink {
-WebViewFrameWidget::WebViewFrameWidget(util::PassKey<WebFrameWidget>,
- WebWidgetClient& client,
- WebViewImpl& web_view)
- : WebFrameWidgetBase(client),
+WebViewFrameWidget::WebViewFrameWidget(
+ util::PassKey<WebFrameWidget>,
+ WebWidgetClient& client,
+ WebViewImpl& web_view,
+ CrossVariantMojoAssociatedRemote<mojom::blink::FrameWidgetHostInterfaceBase>
+ frame_widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::blink::FrameWidgetInterfaceBase>
+ frame_widget,
+ CrossVariantMojoAssociatedRemote<mojom::blink::WidgetHostInterfaceBase>
+ widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::blink::WidgetInterfaceBase>
+ widget)
+ : WebFrameWidgetBase(client,
+ std::move(frame_widget_host),
+ std::move(frame_widget),
+ std::move(widget_host),
+ std::move(widget)),
web_view_(&web_view),
self_keep_alive_(PERSISTENT_FROM_HERE, this) {
- web_view_->SetWebWidget(this);
+ web_view_->SetMainFrameWidgetBase(this);
}
WebViewFrameWidget::~WebViewFrameWidget() = default;
void WebViewFrameWidget::Close() {
+ GetPage()->WillCloseAnimationHost(nullptr);
// Closing the WebViewFrameWidget happens in response to the local main frame
// being detached from the Page/WebViewImpl.
- web_view_->SetWebWidget(nullptr);
+ web_view_->SetMainFrameWidgetBase(nullptr);
web_view_ = nullptr;
WebFrameWidgetBase::Close();
self_keep_alive_.Clear();
@@ -50,21 +66,13 @@ void WebViewFrameWidget::SetSuppressFrameRequestsWorkaroundFor704763Only(
web_view_->SetSuppressFrameRequestsWorkaroundFor704763Only(
suppress_frame_requests);
}
-void WebViewFrameWidget::BeginFrame(base::TimeTicks last_frame_time,
- bool record_main_frame_metrics) {
- web_view_->BeginFrame(last_frame_time, record_main_frame_metrics);
-}
void WebViewFrameWidget::DidBeginFrame() {
web_view_->DidBeginFrame();
}
-void WebViewFrameWidget::BeginRafAlignedInput() {
- web_view_->BeginRafAlignedInput();
-}
-
-void WebViewFrameWidget::EndRafAlignedInput() {
- web_view_->EndRafAlignedInput();
+void WebViewFrameWidget::BeginMainFrame(base::TimeTicks last_frame_time) {
+ web_view_->BeginFrame(last_frame_time);
}
void WebViewFrameWidget::BeginUpdateLayers() {
@@ -79,8 +87,9 @@ void WebViewFrameWidget::BeginCommitCompositorFrame() {
web_view_->BeginCommitCompositorFrame();
}
-void WebViewFrameWidget::EndCommitCompositorFrame() {
- web_view_->EndCommitCompositorFrame();
+void WebViewFrameWidget::EndCommitCompositorFrame(
+ base::TimeTicks commit_start_time) {
+ web_view_->EndCommitCompositorFrame(commit_start_time);
}
void WebViewFrameWidget::RecordStartOfFrameMetrics() {
@@ -88,8 +97,9 @@ void WebViewFrameWidget::RecordStartOfFrameMetrics() {
}
void WebViewFrameWidget::RecordEndOfFrameMetrics(
- base::TimeTicks frame_begin_time) {
- web_view_->RecordEndOfFrameMetrics(frame_begin_time);
+ base::TimeTicks frame_begin_time,
+ cc::ActiveFrameSequenceTrackers trackers) {
+ web_view_->RecordEndOfFrameMetrics(frame_begin_time, trackers);
}
std::unique_ptr<cc::BeginMainFrameMetrics>
@@ -97,8 +107,8 @@ WebViewFrameWidget::GetBeginMainFrameMetrics() {
return web_view_->GetBeginMainFrameMetrics();
}
-void WebViewFrameWidget::UpdateLifecycle(LifecycleUpdate requested_update,
- LifecycleUpdateReason reason) {
+void WebViewFrameWidget::UpdateLifecycle(WebLifecycleUpdate requested_update,
+ DocumentUpdateReason reason) {
web_view_->UpdateLifecycle(requested_update, reason);
}
@@ -156,10 +166,6 @@ bool WebViewFrameWidget::SelectionBounds(WebRect& anchor,
return web_view_->SelectionBounds(anchor, focus);
}
-bool WebViewFrameWidget::IsAcceleratedCompositingActive() const {
- return web_view_->IsAcceleratedCompositingActive();
-}
-
WebURL WebViewFrameWidget::GetURLForDebugTrace() {
return web_view_->GetURLForDebugTrace();
}
@@ -177,16 +183,14 @@ bool WebViewFrameWidget::ScrollFocusedEditableElementIntoView() {
return web_view_->ScrollFocusedEditableElementIntoView();
}
-void WebViewFrameWidget::SetAnimationHost(cc::AnimationHost* host) {
- web_view_->SetAnimationHost(host);
-}
-
-void WebViewFrameWidget::SetRootLayer(scoped_refptr<cc::Layer> layer) {
- web_view_->SetRootLayer(layer);
-}
-
-cc::AnimationHost* WebViewFrameWidget::AnimationHost() const {
- return web_view_->AnimationHost();
+void WebViewFrameWidget::SetRootLayer(scoped_refptr<cc::Layer> root_layer) {
+ if (!web_view_->does_composite()) {
+ DCHECK(!root_layer);
+ return;
+ }
+ cc::LayerTreeHost* layer_tree_host = widget_base_->LayerTreeHost();
+ layer_tree_host->SetRootLayer(root_layer);
+ web_view_->DidChangeRootLayer(!!root_layer);
}
WebHitTestResult WebViewFrameWidget::HitTestResultAt(const gfx::Point& point) {
@@ -202,7 +206,7 @@ void WebViewFrameWidget::ZoomToFindInPageRect(
web_view_->ZoomToFindInPageRect(rect_in_root_frame);
}
-void WebViewFrameWidget::Trace(blink::Visitor* visitor) {
+void WebViewFrameWidget::Trace(Visitor* visitor) {
WebFrameWidgetBase::Trace(visitor);
}
@@ -210,4 +214,12 @@ PageWidgetEventHandler* WebViewFrameWidget::GetPageWidgetEventHandler() {
return web_view_.get();
}
+LocalFrameView* WebViewFrameWidget::GetLocalFrameViewForAnimationScrolling() {
+ // Scrolling for the root frame is special we need to pass null indicating
+ // we are at the top of the tree when setting up the Animation. Which will
+ // cause ownership of the timeline and animation host.
+ // See ScrollingCoordinator::AnimationHostInitialized.
+ return nullptr;
+}
+
} // namespace blink
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 c5680406429..1bc5f79982e 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
@@ -39,9 +39,18 @@ class WebWidgetClient;
// https://goo.gl/7yVrnb.
class CORE_EXPORT WebViewFrameWidget : public WebFrameWidgetBase {
public:
- explicit WebViewFrameWidget(util::PassKey<WebFrameWidget>,
- WebWidgetClient&,
- WebViewImpl&);
+ WebViewFrameWidget(
+ util::PassKey<WebFrameWidget>,
+ WebWidgetClient&,
+ WebViewImpl&,
+ CrossVariantMojoAssociatedRemote<
+ mojom::blink::FrameWidgetHostInterfaceBase> frame_widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::blink::FrameWidgetInterfaceBase>
+ frame_widget,
+ CrossVariantMojoAssociatedRemote<mojom::blink::WidgetHostInterfaceBase>
+ widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::blink::WidgetInterfaceBase>
+ widget);
~WebViewFrameWidget() override;
// WebWidget overrides:
@@ -50,22 +59,19 @@ class CORE_EXPORT WebViewFrameWidget : public WebFrameWidgetBase {
void Resize(const WebSize&) override;
void DidEnterFullscreen() override;
void DidExitFullscreen() override;
- void SetSuppressFrameRequestsWorkaroundFor704763Only(bool) final;
- void BeginFrame(base::TimeTicks last_frame_time,
- bool record_main_frame_metrics) override;
void DidBeginFrame() override;
- void BeginRafAlignedInput() override;
- void EndRafAlignedInput() override;
void BeginUpdateLayers() override;
void EndUpdateLayers() override;
void BeginCommitCompositorFrame() override;
- void EndCommitCompositorFrame() override;
+ void EndCommitCompositorFrame(base::TimeTicks commit_start_time) override;
void RecordStartOfFrameMetrics() override;
- void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) override;
+ void RecordEndOfFrameMetrics(
+ base::TimeTicks frame_begin_time,
+ cc::ActiveFrameSequenceTrackers trackers) override;
std::unique_ptr<cc::BeginMainFrameMetrics> GetBeginMainFrameMetrics()
override;
- void UpdateLifecycle(LifecycleUpdate requested_update,
- LifecycleUpdateReason reason) override;
+ void UpdateLifecycle(WebLifecycleUpdate requested_update,
+ DocumentUpdateReason reason) override;
void ThemeChanged() override;
WebInputEventResult HandleInputEvent(const WebCoalescedInputEvent&) override;
WebInputEventResult DispatchBufferedTouchEvents() override;
@@ -81,7 +87,6 @@ class CORE_EXPORT WebViewFrameWidget : public WebFrameWidgetBase {
void MouseCaptureLost() override;
void SetFocus(bool) override;
bool SelectionBounds(WebRect& anchor, WebRect& focus) const override;
- bool IsAcceleratedCompositingActive() const override;
WebURL GetURLForDebugTrace() override;
// WebFrameWidget overrides:
@@ -91,17 +96,22 @@ class CORE_EXPORT WebViewFrameWidget : public WebFrameWidgetBase {
WebHitTestResult HitTestResultAt(const gfx::Point&) override;
// WebFrameWidgetBase overrides:
- void SetAnimationHost(cc::AnimationHost*) override;
bool ForSubframe() const override { return false; }
- void SetRootLayer(scoped_refptr<cc::Layer>) override;
- cc::AnimationHost* AnimationHost() const override;
HitTestResult CoreHitTestResultAt(const gfx::Point&) override;
void ZoomToFindInPageRect(const WebRect& rect_in_root_frame) override;
- void Trace(blink::Visitor*) override;
+ // FrameWidget overrides:
+ void SetRootLayer(scoped_refptr<cc::Layer>) override;
+
+ // WidgetBaseClient overrides:
+ void BeginMainFrame(base::TimeTicks last_frame_time) override;
+ void SetSuppressFrameRequestsWorkaroundFor704763Only(bool) final;
+
+ void Trace(Visitor*) override;
private:
PageWidgetEventHandler* GetPageWidgetEventHandler() override;
+ LocalFrameView* GetLocalFrameViewForAnimationScrolling() override;
scoped_refptr<WebViewImpl> web_view_;
diff --git a/chromium/third_party/blink/renderer/core/frame/window.idl b/chromium/third_party/blink/renderer/core/frame/window.idl
index dfe1bbfc15b..47dd13efd72 100644
--- a/chromium/third_party/blink/renderer/core/frame/window.idl
+++ b/chromium/third_party/blink/renderer/core/frame/window.idl
@@ -74,7 +74,7 @@
// the user agent
[Affects=Nothing, LogActivity=GetterOnly] readonly attribute Navigator navigator;
- [LogActivity=GetterOnly, SecureContext=RestrictAppCacheToSecureContexts] readonly attribute ApplicationCache applicationCache;
+ [LogActivity=GetterOnly, SecureContext=RestrictAppCacheToSecureContexts, RuntimeEnabled=AppCache] readonly attribute ApplicationCache applicationCache;
// user prompts
[Measure, CallWith=ScriptState] void alert();
@@ -85,12 +85,14 @@
[CrossOrigin, CallWith=Isolate, RaisesException] void postMessage(any message, USVString targetOrigin, optional sequence<object> transfer = []);
- [CrossOrigin, CallWith=Isolate, RaisesException] void postMessage(any message, optional WindowPostMessageOptions options);
+ [CrossOrigin, CallWith=Isolate, RaisesException] void postMessage(any message, optional WindowPostMessageOptions options = {});
// WindowOrWorkerGlobalScope mixin
// https://html.spec.whatwg.org/C/#windoworworkerglobalscope-mixin
+ // https://wicg.github.io/origin-policy/#monkeypatch-html-windoworworkerglobalscope
[Replaceable] readonly attribute DOMString origin;
void queueMicrotask(VoidFunction callback);
+ [RuntimeEnabled=OriginPolicy, SameObject, SaveSameObject] readonly attribute FrozenArray<DOMString> originPolicyIds;
// AnimationFrameProvider mixin
// https://html.spec.whatwg.org/C/#animation-frames
@@ -108,7 +110,7 @@
// Cooperative Scheduling of Background Tasks
// https://www.w3.org/TR/requestidlecallback/#window_extensions
- [Measure] long requestIdleCallback(IdleRequestCallback callback, optional IdleRequestOptions options);
+ [Measure] long requestIdleCallback(IdleRequestCallback callback, optional IdleRequestOptions options = {});
void cancelIdleCallback(long handle);
// CSS Object Model (CSSOM)
@@ -135,11 +137,11 @@
[HighEntropy, MeasureAs=WindowPageXOffset, Replaceable] readonly attribute double pageXOffset;
[HighEntropy, MeasureAs=WindowScrollY, Replaceable] readonly attribute double scrollY;
[HighEntropy, MeasureAs=WindowPageYOffset, Replaceable] readonly attribute double pageYOffset;
- void scroll(optional ScrollToOptions options);
+ void scroll(optional ScrollToOptions options = {});
void scroll(unrestricted double x, unrestricted double y);
- void scrollTo(optional ScrollToOptions options);
+ void scrollTo(optional ScrollToOptions options = {});
void scrollTo(unrestricted double x, unrestricted double y);
- void scrollBy(optional ScrollToOptions options);
+ void scrollBy(optional ScrollToOptions options = {});
void scrollBy(unrestricted double x, unrestricted double y);
// Visual Viewport API
@@ -176,18 +178,18 @@
[RuntimeEnabled=AccessibilityObjectModel, CallWith=ScriptState] Promise<ComputedAccessibleNode> getComputedAccessibleNode(Element element);
// TODO(yhirano): Move this to url.idl when LegacyWindowAlias is supported.
- attribute URLConstructor webkitURL;
+ [DisableInNewIDLCompiler] attribute URLConstructor webkitURL;
// Non-standard APIs
[MeasureAs=WindowClientInformation, Replaceable] readonly attribute Navigator clientInformation;
[Replaceable, MeasureAs=WindowEvent, Custom=Getter, NotEnumerable] readonly attribute Event event;
- [MeasureAs=WindowFind] boolean find([DefaultValue=Undefined] optional DOMString string,
- [DefaultValue=Undefined] optional boolean caseSensitive,
- [DefaultValue=Undefined] optional boolean backwards,
- [DefaultValue=Undefined] optional boolean wrap,
- [DefaultValue=Undefined] optional boolean wholeWord,
- [DefaultValue=Undefined] optional boolean searchInFrames,
- [DefaultValue=Undefined] optional boolean showDialog);
+ [MeasureAs=WindowFind] boolean find(optional DOMString string = "",
+ optional boolean caseSensitive = false,
+ optional boolean backwards = false,
+ optional boolean wrap = false,
+ optional boolean wholeWord = false,
+ optional boolean searchInFrames = false,
+ optional boolean showDialog = false);
[MeasureAs=WindowOffscreenBuffering, Replaceable, NotEnumerable] readonly attribute boolean offscreenBuffering;
[HighEntropy, MeasureAs=WindowScreenLeft, Replaceable] readonly attribute long screenLeft;
[HighEntropy, MeasureAs=WindowScreenTop, Replaceable] readonly attribute long screenTop;
@@ -196,24 +198,18 @@
[MeasureAs=StyleMedia] readonly attribute StyleMedia styleMedia;
[DeprecateAs=PrefixedRequestAnimationFrame] long webkitRequestAnimationFrame(FrameRequestCallback callback);
[DeprecateAs=PrefixedCancelAnimationFrame, ImplementedAs=cancelAnimationFrame] void webkitCancelAnimationFrame(long id);
- [MeasureAs=PrefixedMutationObserverConstructor] attribute MutationObserverConstructor WebKitMutationObserver;
+ [DisableInNewIDLCompiler, MeasureAs=PrefixedMutationObserverConstructor] attribute MutationObserverConstructor WebKitMutationObserver;
// Event handler attributes
attribute EventHandler onsearch;
- // TODO(crbug.com/999895): Move to global_event_handlers.idl
- attribute EventHandler onwebkitanimationend;
- attribute EventHandler onwebkitanimationiteration;
- attribute EventHandler onwebkitanimationstart;
- attribute EventHandler onwebkittransitionend;
-
// https://w3c.github.io/webappsec-secure-contexts/#monkey-patching-global-object
readonly attribute boolean isSecureContext;
- attribute DOMMatrixConstructor WebKitCSSMatrix;
+ [DisableInNewIDLCompiler] attribute DOMMatrixConstructor WebKitCSSMatrix;
// TrustedTypes API: http://github.com/wicg/trusted-types
- [RuntimeEnabled=TrustedDOMTypes, Unforgeable] readonly attribute TrustedTypePolicyFactory trustedTypes;
+ [RuntimeEnabled=TrustedDOMTypes, SecureContext] readonly attribute TrustedTypePolicyFactory trustedTypes;
};
Window includes GlobalEventHandlers;
diff --git a/chromium/third_party/blink/renderer/core/frame/window_event_handlers.h b/chromium/third_party/blink/renderer/core/frame/window_event_handlers.h
index d9f5e87640d..787fdb5eadd 100644
--- a/chromium/third_party/blink/renderer/core/frame/window_event_handlers.h
+++ b/chromium/third_party/blink/renderer/core/frame/window_event_handlers.h
@@ -30,6 +30,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_WINDOW_EVENT_HANDLERS_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_WINDOW_EVENT_HANDLERS_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/platform/wtf/allocator/allocator.h"
@@ -55,6 +56,7 @@ class WindowEventHandlers {
DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(rejectionhandled,
kRejectionhandled)
DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(storage, kStorage)
+ DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(timezonechange, kTimezonechange)
DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(unhandledrejection,
kUnhandledrejection)
DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(unload, kUnload)
diff --git a/chromium/third_party/blink/renderer/core/frame/window_event_handlers.idl b/chromium/third_party/blink/renderer/core/frame/window_event_handlers.idl
index dba180e1816..48ed1316809 100644
--- a/chromium/third_party/blink/renderer/core/frame/window_event_handlers.idl
+++ b/chromium/third_party/blink/renderer/core/frame/window_event_handlers.idl
@@ -48,6 +48,7 @@
[RuntimeEnabled=Portals] attribute EventHandler onportalactivate;
attribute EventHandler onrejectionhandled;
attribute EventHandler onstorage;
+ [RuntimeEnabled=TimeZoneChangeEvent] attribute EventHandler ontimezonechange;
attribute EventHandler onunhandledrejection;
attribute EventHandler onunload;
};
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 f7879ea77b6..13d6a539a16 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
@@ -34,7 +34,6 @@
#include "base/containers/span.h"
#include "third_party/blink/renderer/bindings/core/v8/scheduled_action.h"
-#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_gc_for_context_dispose.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
@@ -47,7 +46,7 @@
#include "third_party/blink/renderer/core/workers/worker_global_scope.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/weborigin/security_violation_reporting_policy.h"
+#include "third_party/blink/renderer/platform/weborigin/reporting_disposition.h"
#include "third_party/blink/renderer/platform/wtf/text/base64.h"
#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
@@ -56,12 +55,11 @@ namespace blink {
static bool IsAllowed(ExecutionContext* execution_context,
bool is_eval,
const String& source) {
- if (execution_context->IsDocument()) {
- Document* document = static_cast<Document*>(execution_context);
+ if (Document* document = Document::DynamicFrom(execution_context)) {
if (!document->GetFrame())
return false;
if (is_eval && !document->GetContentSecurityPolicy()->AllowEval(
- SecurityViolationReportingPolicy::kReport,
+ ReportingDisposition::kReport,
ContentSecurityPolicy::kWillNotThrowException, source)) {
return false;
}
@@ -75,7 +73,7 @@ static bool IsAllowed(ExecutionContext* execution_context,
ContentSecurityPolicy* policy =
worker_global_scope->GetContentSecurityPolicy();
if (is_eval && policy &&
- !policy->AllowEval(SecurityViolationReportingPolicy::kReport,
+ !policy->AllowEval(ReportingDisposition::kReport,
ContentSecurityPolicy::kWillNotThrowException,
source)) {
return false;
@@ -149,31 +147,11 @@ int WindowOrWorkerGlobalScope::setTimeout(
base::TimeDelta::FromMilliseconds(timeout), true);
}
-int WindowOrWorkerGlobalScope::setTimeout(
- ScriptState* script_state,
- EventTarget& event_target,
- const StringOrTrustedScript& string_or_trusted_script,
- int timeout,
- const HeapVector<ScriptValue>& arguments,
- ExceptionState& exception_state) {
- ExecutionContext* execution_context = event_target.GetExecutionContext();
- Document* document = execution_context->IsDocument()
- ? static_cast<Document*>(execution_context)
- : nullptr;
- String handler = GetStringFromTrustedScript(string_or_trusted_script,
- document, exception_state);
- if (exception_state.HadException())
- return 0;
- return setTimeoutFromString(script_state, event_target, handler, timeout,
- arguments);
-}
-
-int WindowOrWorkerGlobalScope::setTimeoutFromString(
- ScriptState* script_state,
- EventTarget& event_target,
- const String& handler,
- int timeout,
- const HeapVector<ScriptValue>&) {
+int WindowOrWorkerGlobalScope::setTimeout(ScriptState* script_state,
+ EventTarget& event_target,
+ const String& handler,
+ int timeout,
+ const HeapVector<ScriptValue>&) {
ExecutionContext* execution_context = event_target.GetExecutionContext();
if (!IsAllowed(execution_context, true, handler))
return 0;
@@ -207,31 +185,11 @@ int WindowOrWorkerGlobalScope::setInterval(
base::TimeDelta::FromMilliseconds(timeout), false);
}
-int WindowOrWorkerGlobalScope::setInterval(
- ScriptState* script_state,
- EventTarget& event_target,
- const StringOrTrustedScript& string_or_trusted_script,
- int timeout,
- const HeapVector<ScriptValue>& arguments,
- ExceptionState& exception_state) {
- ExecutionContext* execution_context = event_target.GetExecutionContext();
- Document* document = execution_context->IsDocument()
- ? static_cast<Document*>(execution_context)
- : nullptr;
- String handler = GetStringFromTrustedScript(string_or_trusted_script,
- document, exception_state);
- if (exception_state.HadException())
- return 0;
- return setIntervalFromString(script_state, event_target, handler, timeout,
- arguments);
-}
-
-int WindowOrWorkerGlobalScope::setIntervalFromString(
- ScriptState* script_state,
- EventTarget& event_target,
- const String& handler,
- int timeout,
- const HeapVector<ScriptValue>&) {
+int WindowOrWorkerGlobalScope::setInterval(ScriptState* script_state,
+ EventTarget& event_target,
+ const String& handler,
+ int timeout,
+ const HeapVector<ScriptValue>&) {
ExecutionContext* execution_context = event_target.GetExecutionContext();
if (!IsAllowed(execution_context, true, handler))
return 0;
@@ -261,9 +219,10 @@ ScriptPromise WindowOrWorkerGlobalScope::createImageBitmap(
ScriptState* script_state,
EventTarget& event_target,
const ImageBitmapSourceUnion& bitmap_source,
- const ImageBitmapOptions* options) {
- return ImageBitmapFactories::CreateImageBitmap(script_state, event_target,
- bitmap_source, options);
+ const ImageBitmapOptions* options,
+ ExceptionState& exception_state) {
+ return ImageBitmapFactories::CreateImageBitmap(
+ script_state, event_target, bitmap_source, options, exception_state);
}
ScriptPromise WindowOrWorkerGlobalScope::createImageBitmap(
@@ -274,9 +233,11 @@ ScriptPromise WindowOrWorkerGlobalScope::createImageBitmap(
int sy,
int sw,
int sh,
- const ImageBitmapOptions* options) {
- return ImageBitmapFactories::CreateImageBitmap(
- script_state, event_target, bitmap_source, sx, sy, sw, sh, options);
+ const ImageBitmapOptions* options,
+ ExceptionState& exception_state) {
+ return ImageBitmapFactories::CreateImageBitmap(script_state, event_target,
+ bitmap_source, sx, sy, sw, sh,
+ options, exception_state);
}
} // 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 b378abf505d..bdeca3a180d 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
@@ -46,13 +46,12 @@ class ImageBitmapOptions;
class ScriptPromise;
class ScriptState;
class ScriptValue;
-class StringOrTrustedScript;
class V8Function;
typedef HTMLImageElementOrSVGImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrImageBitmapOrOffscreenCanvas
ImageBitmapSourceUnion;
-class WindowOrWorkerGlobalScope {
+class CORE_EXPORT WindowOrWorkerGlobalScope {
STATIC_ONLY(WindowOrWorkerGlobalScope);
public:
@@ -70,15 +69,9 @@ class WindowOrWorkerGlobalScope {
const HeapVector<ScriptValue>& arguments);
static int setTimeout(ScriptState*,
EventTarget&,
- const StringOrTrustedScript&,
+ const String& handler,
int timeout,
- const HeapVector<ScriptValue>&,
- ExceptionState&);
- static int setTimeoutFromString(ScriptState*,
- EventTarget&,
- const String& handler,
- int timeout,
- const HeapVector<ScriptValue>&);
+ const HeapVector<ScriptValue>&);
static int setInterval(ScriptState*,
EventTarget&,
V8Function* handler,
@@ -86,22 +79,17 @@ class WindowOrWorkerGlobalScope {
const HeapVector<ScriptValue>&);
static int setInterval(ScriptState*,
EventTarget&,
- const StringOrTrustedScript&,
+ const String& handler,
int timeout,
- const HeapVector<ScriptValue>&,
- ExceptionState&);
- static int setIntervalFromString(ScriptState*,
- EventTarget&,
- const String& handler,
- int timeout,
- const HeapVector<ScriptValue>&);
+ const HeapVector<ScriptValue>&);
static void clearTimeout(EventTarget&, int timeout_id);
static void clearInterval(EventTarget&, int timeout_id);
static ScriptPromise createImageBitmap(ScriptState*,
EventTarget&,
const ImageBitmapSourceUnion&,
- const ImageBitmapOptions*);
+ const ImageBitmapOptions*,
+ ExceptionState&);
static ScriptPromise createImageBitmap(ScriptState*,
EventTarget&,
const ImageBitmapSourceUnion&,
@@ -109,7 +97,8 @@ class WindowOrWorkerGlobalScope {
int sy,
int sw,
int sh,
- const ImageBitmapOptions*);
+ const ImageBitmapOptions*,
+ ExceptionState&);
};
} // 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 9acd0e6556c..b232605678e 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
@@ -25,9 +25,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// https://html.spec.whatwg.org/C/webappapis.html#windoworworkerglobalscope-mixin
-// https://html.spec.whatwg.org/C/timers-and-user-prompts.html#timers
-
// https://html.spec.whatwg.org/C/#imagebitmapsource
typedef (HTMLImageElement or
SVGImageElement or
@@ -38,6 +35,8 @@ typedef (HTMLImageElement or
ImageBitmap or
OffscreenCanvas) ImageBitmapSource;
+// https://html.spec.whatwg.org/C/#windoworworkerglobalscope-mixin
+// https://html.spec.whatwg.org/C/#timers
[
LegacyTreatAsPartialInterface,
Exposed=(Window,Worker)
@@ -48,15 +47,15 @@ typedef (HTMLImageElement or
// https://html.spec.whatwg.org/C/webappapis.html#windoworworkerglobalscope-mixin
[CallWith=ScriptState, RuntimeCallStatsCounter=WindowSetTimeout] long setTimeout(Function handler, optional long timeout = 0, any... arguments);
- [CallWith=ScriptState, RaisesException] long setTimeout(ScriptString handler, optional long timeout = 0, any... arguments);
+ [CallWith=ScriptState] long setTimeout(ScriptString handler, optional long timeout = 0, any... arguments);
void clearTimeout(optional long handle = 0);
[CallWith=ScriptState] long setInterval(Function handler, optional long timeout = 0, any... arguments);
- [CallWith=ScriptState, RaisesException] long setInterval(ScriptString handler, optional long timeout = 0, any... arguments);
+ [CallWith=ScriptState] long setInterval(ScriptString handler, optional long timeout = 0, any... arguments);
void clearInterval(optional long handle = 0);
// ImageBitmap
- [CallWith=ScriptState] Promise<ImageBitmap> createImageBitmap(
- ImageBitmapSource imageBitmap, optional ImageBitmapOptions options);
- [CallWith=ScriptState] Promise<ImageBitmap> createImageBitmap(
- ImageBitmapSource imageBitmap, long sx, long sy, long sw, long sh, optional ImageBitmapOptions options);
+ [CallWith=ScriptState, RaisesException] Promise<ImageBitmap> createImageBitmap(
+ ImageBitmapSource imageBitmap, optional ImageBitmapOptions options = {});
+ [CallWith=ScriptState, RaisesException] Promise<ImageBitmap> createImageBitmap(
+ ImageBitmapSource imageBitmap, long sx, long sy, long sw, long sh, optional ImageBitmapOptions options = {});
};
diff --git a/chromium/third_party/blink/renderer/core/fullscreen/document_fullscreen.cc b/chromium/third_party/blink/renderer/core/fullscreen/document_fullscreen.cc
index 9ae4c2287d5..8b384811f27 100644
--- a/chromium/third_party/blink/renderer/core/fullscreen/document_fullscreen.cc
+++ b/chromium/third_party/blink/renderer/core/fullscreen/document_fullscreen.cc
@@ -37,9 +37,11 @@ Element* DocumentFullscreen::fullscreenElement(Document& document) {
return Fullscreen::FullscreenElementForBindingFrom(document);
}
-ScriptPromise DocumentFullscreen::exitFullscreen(ScriptState* script_state,
- Document& document) {
- return Fullscreen::ExitFullscreen(document, script_state);
+ScriptPromise DocumentFullscreen::exitFullscreen(
+ ScriptState* script_state,
+ Document& document,
+ ExceptionState& exception_state) {
+ return Fullscreen::ExitFullscreen(document, script_state, &exception_state);
}
void DocumentFullscreen::webkitExitFullscreen(Document& document) {
diff --git a/chromium/third_party/blink/renderer/core/fullscreen/document_fullscreen.h b/chromium/third_party/blink/renderer/core/fullscreen/document_fullscreen.h
index cb64f05fd67..aa887165f50 100644
--- a/chromium/third_party/blink/renderer/core/fullscreen/document_fullscreen.h
+++ b/chromium/third_party/blink/renderer/core/fullscreen/document_fullscreen.h
@@ -36,13 +36,13 @@ namespace blink {
class Document;
class Element;
-class DocumentFullscreen {
+class CORE_EXPORT DocumentFullscreen {
STATIC_ONLY(DocumentFullscreen);
public:
static bool fullscreenEnabled(Document&);
static Element* fullscreenElement(Document&);
- static ScriptPromise exitFullscreen(ScriptState*, Document&);
+ static ScriptPromise exitFullscreen(ScriptState*, Document&, ExceptionState&);
static void webkitExitFullscreen(Document&);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(fullscreenchange, kFullscreenchange)
diff --git a/chromium/third_party/blink/renderer/core/fullscreen/document_fullscreen.idl b/chromium/third_party/blink/renderer/core/fullscreen/document_fullscreen.idl
index cc2cd81b497..82d64a42595 100644
--- a/chromium/third_party/blink/renderer/core/fullscreen/document_fullscreen.idl
+++ b/chromium/third_party/blink/renderer/core/fullscreen/document_fullscreen.idl
@@ -27,7 +27,7 @@
[LenientSetter] readonly attribute boolean fullscreenEnabled;
[LenientSetter, Unscopable, ImplementedAs=fullscreenElement] readonly attribute boolean fullscreen;
- [CallWith=ScriptState] Promise<void> exitFullscreen();
+ [CallWith=ScriptState, RaisesException] Promise<void> exitFullscreen();
attribute EventHandler onfullscreenchange;
attribute EventHandler onfullscreenerror;
diff --git a/chromium/third_party/blink/renderer/core/fullscreen/element_fullscreen.cc b/chromium/third_party/blink/renderer/core/fullscreen/element_fullscreen.cc
index 425e5967512..ab226fcaf27 100644
--- a/chromium/third_party/blink/renderer/core/fullscreen/element_fullscreen.cc
+++ b/chromium/third_party/blink/renderer/core/fullscreen/element_fullscreen.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/fullscreen/element_fullscreen.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_fullscreen_options.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
@@ -13,9 +14,11 @@ namespace blink {
ScriptPromise ElementFullscreen::requestFullscreen(
ScriptState* script_state,
Element& element,
- const FullscreenOptions* options) {
- return Fullscreen::RequestFullscreen(
- element, options, Fullscreen::RequestType::kUnprefixed, script_state);
+ const FullscreenOptions* options,
+ ExceptionState& exception_state) {
+ return Fullscreen::RequestFullscreen(element, options,
+ Fullscreen::RequestType::kUnprefixed,
+ script_state, &exception_state);
}
void ElementFullscreen::webkitRequestFullscreen(Element& element) {
diff --git a/chromium/third_party/blink/renderer/core/fullscreen/element_fullscreen.h b/chromium/third_party/blink/renderer/core/fullscreen/element_fullscreen.h
index ecca49b003d..04a2c5d74d9 100644
--- a/chromium/third_party/blink/renderer/core/fullscreen/element_fullscreen.h
+++ b/chromium/third_party/blink/renderer/core/fullscreen/element_fullscreen.h
@@ -7,21 +7,22 @@
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/fullscreen/fullscreen_options.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
namespace blink {
class Element;
+class FullscreenOptions;
-class ElementFullscreen {
+class CORE_EXPORT ElementFullscreen {
STATIC_ONLY(ElementFullscreen);
public:
static ScriptPromise requestFullscreen(ScriptState*,
Element&,
- const FullscreenOptions*);
+ const FullscreenOptions*,
+ ExceptionState& exception_state);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(fullscreenchange, kFullscreenchange)
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(fullscreenerror, kFullscreenerror)
diff --git a/chromium/third_party/blink/renderer/core/fullscreen/element_fullscreen.idl b/chromium/third_party/blink/renderer/core/fullscreen/element_fullscreen.idl
index 7bfb572c4b0..dcf12e39845 100644
--- a/chromium/third_party/blink/renderer/core/fullscreen/element_fullscreen.idl
+++ b/chromium/third_party/blink/renderer/core/fullscreen/element_fullscreen.idl
@@ -7,16 +7,16 @@
[
ImplementedAs=ElementFullscreen
] partial interface Element {
- [CallWith=ScriptState] Promise<void> requestFullscreen(optional FullscreenOptions options);
+ [CallWith=ScriptState, RaisesException] Promise<void> requestFullscreen(optional FullscreenOptions options = {});
attribute EventHandler onfullscreenchange;
attribute EventHandler onfullscreenerror;
// Mozilla version
- [LogActivity, LogAllWorlds, MeasureAs=PrefixedElementRequestFullScreen, ImplementedAs=webkitRequestFullscreen] void webkitRequestFullScreen(optional FullscreenOptions options);
+ [LogActivity, LogAllWorlds, MeasureAs=PrefixedElementRequestFullScreen, ImplementedAs=webkitRequestFullscreen] void webkitRequestFullScreen(optional FullscreenOptions options = {});
// W3C version
- [LogActivity, LogAllWorlds, MeasureAs=PrefixedElementRequestFullscreen] void webkitRequestFullscreen(optional FullscreenOptions options);
+ [LogActivity, LogAllWorlds, MeasureAs=PrefixedElementRequestFullscreen] void webkitRequestFullscreen(optional FullscreenOptions options = {});
attribute EventHandler onwebkitfullscreenchange;
attribute EventHandler onwebkitfullscreenerror;
diff --git a/chromium/third_party/blink/renderer/core/fullscreen/fullscreen.cc b/chromium/third_party/blink/renderer/core/fullscreen/fullscreen.cc
index 882f26714a2..8d336281208 100644
--- a/chromium/third_party/blink/renderer/core/fullscreen/fullscreen.cc
+++ b/chromium/third_party/blink/renderer/core/fullscreen/fullscreen.cc
@@ -33,18 +33,17 @@
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_fullscreen_options.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/dom/document.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
-#include "third_party/blink/renderer/core/frame/hosts_using_features.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"
#include "third_party/blink/renderer/core/frame/visual_viewport.h"
-#include "third_party/blink/renderer/core/fullscreen/fullscreen_options.h"
#include "third_party/blink/renderer/core/fullscreen/scoped_allow_fullscreen.h"
#include "third_party/blink/renderer/core/html/html_body_element.h"
#include "third_party/blink/renderer/core/html/html_iframe_element.h"
@@ -55,6 +54,7 @@
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/svg/svg_svg_element.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"
namespace blink {
@@ -217,18 +217,37 @@ bool AllowedToUseFullscreen(const Document& document,
// 2. If Feature Policy is enabled, return the policy for "fullscreen"
// feature.
- return document.IsFeatureEnabled(mojom::FeaturePolicyFeature::kFullscreen,
- report_on_failure);
+ return document.IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kFullscreen, report_on_failure);
}
bool AllowedToRequestFullscreen(Document& document) {
+ // WebXR DOM Overlay integration, cf.
+ // https://immersive-web.github.io/dom-overlays/
+ //
+ // The current implementation of WebXR's "dom-overlay" mode internally uses
+ // the Fullscreen API to show a single DOM element based on configuration at
+ // XR session start. The WebXR API doesn't support changing elements during
+ // the session, so to avoid inconsistencies between implementations we need
+ // to block changes via Fullscreen API while the XR session is active, while
+ // still allowing the XR code to set up fullscreen mode on session start.
+ if (ScopedAllowFullscreen::FullscreenAllowedReason() ==
+ ScopedAllowFullscreen::kXrOverlay) {
+ DVLOG(1) << __func__
+ << ": allowing fullscreen element setup for XR DOM overlay";
+ return true;
+ }
+ if (document.IsXrOverlay()) {
+ DVLOG(1) << __func__
+ << ": rejecting change of fullscreen element for XR DOM overlay";
+ return false;
+ }
+
// An algorithm is allowed to request fullscreen if one of the following is
// true:
- // The algorithm is triggered by a user activation.
- // We are doing experiment to see if there is any webpage breaking after we
- // only allow one fullscreen when the user activation state is active.
- if (LocalFrame::ConsumeTransientUserActivation(document.GetFrame()))
+ // The algorithm is triggered by a user activation.
+ if (LocalFrame::HasTransientUserActivation(document.GetFrame()))
return true;
// The algorithm is triggered by a user generated orientation change.
@@ -239,25 +258,12 @@ bool AllowedToRequestFullscreen(Document& document) {
return true;
}
- if (document.IsImmersiveArOverlay()) {
- // This is a workaround for lack of a user activation when an immersive-ar
- // session is starting. If the app sets an element fullscreen in the "Enter
- // AR" button click, that gets unfullscreened when the browser shows its AR
- // session consent prompt. By the time the session starts, the 5-second
- // timer for the initial user activation is likely to have expired. This
- // also allows switching the active fullscreen element during the session.
- // Note that exiting the immersive-ar session does FullyExitFullscreen to
- // ensure a consistent post-session state.
- DVLOG(1) << __func__ << ": allowing fullscreen immersive-ar DOM overlay";
- return true;
- }
-
String message = ExceptionMessages::FailedToExecute(
"requestFullscreen", "Element",
"API can only be initiated by a user gesture.");
- document.AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning, message));
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning, message));
return false;
}
@@ -434,8 +440,8 @@ HeapVector<Member<Document>> CollectDocumentsToUnfullscreen(Document& doc) {
// https://fullscreen.spec.whatwg.org/#run-the-fullscreen-rendering-steps
void FireEvent(const AtomicString& type, Element* element, Document* document) {
- DCHECK(document);
- DCHECK(element);
+ if (!document || !element)
+ return;
// |Document::EnqueueAnimationFrameTask()| is used instead of a "list of
// pending fullscreen events", so only the body of the "run the fullscreen
@@ -473,13 +479,8 @@ void EnqueueEvent(const AtomicString& type,
Fullscreen::RequestType request_type) {
const AtomicString& adjusted_type = AdjustEventType(type, request_type);
document.EnqueueAnimationFrameTask(WTF::Bind(FireEvent, adjusted_type,
- WrapPersistent(&element),
- WrapPersistent(&document)));
-}
-
-void DidEnterFullscreenTask(Document* document) {
- DCHECK(document);
- Fullscreen::DidEnterFullscreen(*document);
+ WrapWeakPersistent(&element),
+ WrapWeakPersistent(&document)));
}
} // anonymous namespace
@@ -543,17 +544,18 @@ bool Fullscreen::IsInFullscreenElementStack(const Element& element) {
}
Fullscreen::Fullscreen(Document& document)
- : Supplement<Document>(document), ContextLifecycleObserver(&document) {
+ : Supplement<Document>(document),
+ ExecutionContextLifecycleObserver(&document) {
document.SetHasFullscreenSupplement();
}
Fullscreen::~Fullscreen() = default;
Document* Fullscreen::GetDocument() {
- return To<Document>(LifecycleContext());
+ return Document::From(GetExecutionContext());
}
-void Fullscreen::ContextDestroyed(ExecutionContext*) {
+void Fullscreen::ContextDestroyed() {
pending_requests_.clear();
pending_exits_.clear();
}
@@ -570,7 +572,8 @@ void Fullscreen::RequestFullscreen(Element& pending) {
ScriptPromise Fullscreen::RequestFullscreen(Element& pending,
const FullscreenOptions* options,
RequestType request_type,
- ScriptState* script_state) {
+ ScriptState* script_state,
+ ExceptionState* exception_state) {
RequestFullscreenScope scope;
// 1. Let |pending| be the context object.
@@ -585,11 +588,10 @@ ScriptPromise Fullscreen::RequestFullscreen(Element& pending,
// 4. If |pendingDoc| is not fully active, then reject |promise| with a
// TypeError exception and return |promise|.
if (!document.IsActive() || !document.GetFrame()) {
- if (!script_state)
+ if (!exception_state)
return ScriptPromise();
- return ScriptPromise::Reject(
- script_state, V8ThrowException::CreateTypeError(
- script_state->GetIsolate(), "Document not active"));
+ exception_state->ThrowTypeError("Document not active");
+ return ScriptPromise();
}
if (script_state) {
@@ -604,13 +606,10 @@ ScriptPromise Fullscreen::RequestFullscreen(Element& pending,
// Use counters only need to be incremented in the process of the actual
// fullscreen element.
if (!for_cross_process_descendant) {
- if (document.IsSecureContext()) {
+ if (document.IsSecureContext())
UseCounter::Count(document, WebFeature::kFullscreenSecureOrigin);
- } else {
+ else
UseCounter::Count(document, WebFeature::kFullscreenInsecureOrigin);
- HostsUsingFeatures::CountAnyWorld(
- document, HostsUsingFeatures::Feature::kFullscreenInsecureHost);
- }
}
// 5. Let |error| be false.
@@ -640,7 +639,13 @@ ScriptPromise Fullscreen::RequestFullscreen(Element& pending,
From(document).pending_requests_.push_back(
MakeGarbageCollected<PendingRequest>(&pending, request_type, resolver));
LocalFrame& frame = *document.GetFrame();
- frame.GetChromeClient().EnterFullscreen(frame, options);
+ frame.GetChromeClient().EnterFullscreen(frame, options,
+ for_cross_process_descendant);
+
+ // After the first fullscreen request, the user activation should be
+ // consumed, and the following fullscreen requests should receive an error.
+ if (!for_cross_process_descendant)
+ LocalFrame::ConsumeTransientUserActivation(&frame);
} else {
// Note: Although we are past the "in parallel" point, it's OK to continue
// synchronously because when |error| is true, |ContinueRequestFullscreen()|
@@ -653,14 +658,19 @@ ScriptPromise Fullscreen::RequestFullscreen(Element& pending,
return promise;
}
-void Fullscreen::DidEnterFullscreen(Document& document) {
+void Fullscreen::DidResolveEnterFullscreenRequest(Document& document,
+ bool granted) {
// We may be called synchronously from within
// |FullscreenController::EnterFullscreen()| if we were already fullscreen,
// but must still not synchronously change the fullscreen element. Instead
// enqueue a microtask to continue.
if (RequestFullscreenScope::RunningRequestFullscreen()) {
- Microtask::EnqueueMicrotask(
- WTF::Bind(DidEnterFullscreenTask, WrapPersistent(&document)));
+ Microtask::EnqueueMicrotask(WTF::Bind(
+ [](Document* document, bool granted) {
+ DCHECK(document);
+ DidResolveEnterFullscreenRequest(*document, granted);
+ },
+ WrapPersistent(&document), granted));
return;
}
@@ -668,7 +678,7 @@ void Fullscreen::DidEnterFullscreen(Document& document) {
requests.swap(From(document).pending_requests_);
for (const Member<PendingRequest>& request : requests) {
ContinueRequestFullscreen(document, *request->element(), request->type(),
- request->resolver(), false /* error */);
+ request->resolver(), !granted);
}
}
@@ -784,12 +794,13 @@ void Fullscreen::FullyExitFullscreen(Document& document, bool ua_originated) {
DCHECK(IsSimpleFullscreenDocument(doc));
// 3. Exit fullscreen |document|.
- ExitFullscreen(doc, nullptr, ua_originated);
+ ExitFullscreen(doc, nullptr, nullptr, ua_originated);
}
// https://fullscreen.spec.whatwg.org/#exit-fullscreen
ScriptPromise Fullscreen::ExitFullscreen(Document& doc,
ScriptState* script_state,
+ ExceptionState* exception_state,
bool ua_originated) {
// 1. Let |promise| be a new promise.
// ScriptPromiseResolver is allocated after step 2.
@@ -798,11 +809,10 @@ ScriptPromise Fullscreen::ExitFullscreen(Document& doc,
// 2. If |doc| is not fully active or |doc|'s fullscreen element is null, then
// reject |promise| with a TypeError exception and return |promise|.
if (!doc.IsActive() || !doc.GetFrame() || !FullscreenElementFrom(doc)) {
- if (!script_state)
+ if (!exception_state)
return ScriptPromise();
- return ScriptPromise::Reject(
- script_state, V8ThrowException::CreateTypeError(
- script_state->GetIsolate(), "Document not active"));
+ exception_state->ThrowTypeError("Document not active");
+ return ScriptPromise();
}
if (script_state)
@@ -1005,7 +1015,7 @@ void Fullscreen::ElementRemoved(Element& node) {
// 3.1. If |node| is its node document's fullscreen element, exit fullscreen
// that document.
if (IsFullscreenElement(node)) {
- ExitFullscreen(document, nullptr, false);
+ ExitFullscreen(document);
} else {
// 3.2. Otherwise, unfullscreen |node| within its node document.
Unfullscreen(node);
@@ -1015,11 +1025,11 @@ void Fullscreen::ElementRemoved(Element& node) {
// layer. This is done in Element::RemovedFrom.
}
-void Fullscreen::Trace(blink::Visitor* visitor) {
+void Fullscreen::Trace(Visitor* visitor) {
visitor->Trace(pending_requests_);
visitor->Trace(pending_exits_);
Supplement<Document>::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
Fullscreen::PendingRequest::PendingRequest(Element* element,
@@ -1029,7 +1039,7 @@ Fullscreen::PendingRequest::PendingRequest(Element* element,
Fullscreen::PendingRequest::~PendingRequest() = default;
-void Fullscreen::PendingRequest::Trace(blink::Visitor* visitor) {
+void Fullscreen::PendingRequest::Trace(Visitor* visitor) {
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 87f1dd66759..7c6134b3687 100644
--- a/chromium/third_party/blink/renderer/core/fullscreen/fullscreen.h
+++ b/chromium/third_party/blink/renderer/core/fullscreen/fullscreen.h
@@ -35,7 +35,7 @@
#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/element.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
#include "third_party/blink/renderer/platform/supplementable.h"
#include "third_party/blink/renderer/platform/wtf/deque.h"
@@ -52,7 +52,7 @@ class ScriptPromiseResolver;
// actually enter and exit fullscreen it (indirectly) uses FullscreenController.
class CORE_EXPORT Fullscreen final : public GarbageCollected<Fullscreen>,
public Supplement<Document>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(Fullscreen);
public:
@@ -79,31 +79,34 @@ class CORE_EXPORT Fullscreen final : public GarbageCollected<Fullscreen>,
};
static void RequestFullscreen(Element&);
- static ScriptPromise RequestFullscreen(Element&,
- const FullscreenOptions*,
- RequestType,
- ScriptState* state = nullptr);
+ static ScriptPromise RequestFullscreen(
+ Element&,
+ const FullscreenOptions*,
+ RequestType,
+ ScriptState* state = nullptr,
+ ExceptionState* exception_state = nullptr);
static void FullyExitFullscreen(Document&, bool ua_originated = false);
static ScriptPromise ExitFullscreen(Document&,
ScriptState* state = nullptr,
+ ExceptionState* exception_state = nullptr,
bool ua_originated = false);
static bool FullscreenEnabled(Document&);
// Called by FullscreenController to notify that we've entered or exited
// fullscreen. All frames are notified, so there may be no pending request.
- static void DidEnterFullscreen(Document&);
+ static void DidResolveEnterFullscreenRequest(Document&, bool granted);
static void DidExitFullscreen(Document&);
static void DidUpdateSize(Element&);
static void ElementRemoved(Element&);
- // ContextLifecycleObserver:
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver:
+ void ContextDestroyed() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
static Fullscreen* FromIfExists(Document&);
@@ -132,7 +135,7 @@ class CORE_EXPORT Fullscreen final : public GarbageCollected<Fullscreen>,
RequestType type,
ScriptPromiseResolver* resolver);
virtual ~PendingRequest();
- virtual void Trace(blink::Visitor* visitor);
+ virtual void Trace(Visitor* visitor);
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 9664b919f43..3fb94501245 100644
--- a/chromium/third_party/blink/renderer/core/fullscreen/fullscreen_options.idl
+++ b/chromium/third_party/blink/renderer/core/fullscreen/fullscreen_options.idl
@@ -11,5 +11,8 @@ enum FullscreenNavigationUI {
};
dictionary FullscreenOptions {
- FullscreenNavigationUI navigationUI = "auto";
+ FullscreenNavigationUI navigationUI = "auto";
+
+ // https://github.com/webscreens/window-placement
+ [RuntimeEnabled=WindowPlacement] Screen? screen;
};
diff --git a/chromium/third_party/blink/renderer/core/fullscreen/scoped_allow_fullscreen.h b/chromium/third_party/blink/renderer/core/fullscreen/scoped_allow_fullscreen.h
index 541054b6b39..fb2b80f90dd 100644
--- a/chromium/third_party/blink/renderer/core/fullscreen/scoped_allow_fullscreen.h
+++ b/chromium/third_party/blink/renderer/core/fullscreen/scoped_allow_fullscreen.h
@@ -16,7 +16,7 @@ class CORE_EXPORT ScopedAllowFullscreen {
STACK_ALLOCATED();
public:
- enum Reason { kOrientationChange };
+ enum Reason { kOrientationChange, kXrOverlay };
static base::Optional<Reason> FullscreenAllowedReason();
explicit ScopedAllowFullscreen(Reason);
diff --git a/chromium/third_party/blink/renderer/core/geometry/BUILD.gn b/chromium/third_party/blink/renderer/core/geometry/BUILD.gn
index 7f26639be1d..6460e789fd0 100644
--- a/chromium/third_party/blink/renderer/core/geometry/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/geometry/BUILD.gn
@@ -22,5 +22,6 @@ blink_core_sources("geometry") {
"dom_rect_list.h",
"dom_rect_read_only.cc",
"dom_rect_read_only.h",
+ "geometry_util.h",
]
}
diff --git a/chromium/third_party/blink/renderer/core/geometry/dom_matrix.cc b/chromium/third_party/blink/renderer/core/geometry/dom_matrix.cc
index 1eeeeff62f4..3864d75561b 100644
--- a/chromium/third_party/blink/renderer/core/geometry/dom_matrix.cc
+++ b/chromium/third_party/blink/renderer/core/geometry/dom_matrix.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/geometry/dom_matrix.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_init.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/platform/transforms/affine_transform.h"
diff --git a/chromium/third_party/blink/renderer/core/geometry/dom_matrix.h b/chromium/third_party/blink/renderer/core/geometry/dom_matrix.h
index 8837f77357a..ed5e5558ca8 100644
--- a/chromium/third_party/blink/renderer/core/geometry/dom_matrix.h
+++ b/chromium/third_party/blink/renderer/core/geometry/dom_matrix.h
@@ -6,14 +6,14 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_GEOMETRY_DOM_MATRIX_H_
#include "third_party/blink/renderer/bindings/core/v8/string_or_unrestricted_double_sequence.h"
-#include "third_party/blink/renderer/core/geometry/dom_matrix_2d_init.h"
-#include "third_party/blink/renderer/core/geometry/dom_matrix_init.h"
#include "third_party/blink/renderer/core/geometry/dom_matrix_read_only.h"
#include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
namespace blink {
+class DOMMatrixInit;
+
class CORE_EXPORT DOMMatrix : public DOMMatrixReadOnly {
DEFINE_WRAPPERTYPEINFO();
diff --git a/chromium/third_party/blink/renderer/core/geometry/dom_matrix.idl b/chromium/third_party/blink/renderer/core/geometry/dom_matrix.idl
index 2af00ad9b11..5658f38b29f 100644
--- a/chromium/third_party/blink/renderer/core/geometry/dom_matrix.idl
+++ b/chromium/third_party/blink/renderer/core/geometry/dom_matrix.idl
@@ -5,13 +5,12 @@
// https://drafts.fxtf.org/geometry/#DOMMatrix
[
- Constructor(optional (DOMString or sequence<unrestricted double>) init),
- RaisesException=Constructor,
- ConstructorCallWith=ExecutionContext,
Exposed=(Window,Worker),
+ LegacyWindowAlias=WebKitCSSMatrix,
Serializable
] interface DOMMatrix : DOMMatrixReadOnly {
- [RaisesException, NewObject] static DOMMatrix fromMatrix(optional DOMMatrixInit other);
+ [CallWith=ExecutionContext, RaisesException] constructor(optional (DOMString or sequence<unrestricted double>) init);
+ [RaisesException, NewObject] static DOMMatrix fromMatrix(optional DOMMatrixInit other = {});
[RaisesException, NewObject] static DOMMatrix fromFloat32Array(Float32Array array32);
[RaisesException, NewObject] static DOMMatrix fromFloat64Array(Float64Array array64);
@@ -41,8 +40,8 @@
inherit attribute unrestricted double m44;
// Mutable transform methods
- [RaisesException] DOMMatrix multiplySelf(optional DOMMatrixInit other);
- [RaisesException] DOMMatrix preMultiplySelf(optional DOMMatrixInit other);
+ [RaisesException] DOMMatrix multiplySelf(optional DOMMatrixInit other = {});
+ [RaisesException] DOMMatrix preMultiplySelf(optional DOMMatrixInit other = {});
DOMMatrix translateSelf(optional unrestricted double tx = 0,
optional unrestricted double ty = 0,
optional unrestricted double tz = 0);
diff --git a/chromium/third_party/blink/renderer/core/geometry/dom_matrix_read_only.cc b/chromium/third_party/blink/renderer/core/geometry/dom_matrix_read_only.cc
index cf2da6af479..15e09b5754e 100644
--- a/chromium/third_party/blink/renderer/core/geometry/dom_matrix_read_only.cc
+++ b/chromium/third_party/blink/renderer/core/geometry/dom_matrix_read_only.cc
@@ -4,6 +4,9 @@
#include "third_party/blink/renderer/core/geometry/dom_matrix_read_only.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_2d_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_point_init.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
#include "third_party/blink/renderer/core/css/css_identifier_value.h"
#include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h"
@@ -11,9 +14,7 @@
#include "third_party/blink/renderer/core/css/parser/css_parser.h"
#include "third_party/blink/renderer/core/css/resolver/transform_builder.h"
#include "third_party/blink/renderer/core/geometry/dom_matrix.h"
-#include "third_party/blink/renderer/core/geometry/dom_matrix_init.h"
#include "third_party/blink/renderer/core/geometry/dom_point.h"
-#include "third_party/blink/renderer/core/geometry/dom_point_init.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
@@ -107,7 +108,7 @@ DOMMatrixReadOnly* DOMMatrixReadOnly::Create(
DOMMatrixReadOnly* DOMMatrixReadOnly::Create(
ExecutionContext* execution_context,
- StringOrUnrestrictedDoubleSequence& init,
+ const StringOrUnrestrictedDoubleSequence& init,
ExceptionState& exception_state) {
if (init.IsString()) {
if (!execution_context->IsDocument()) {
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 1d8e8d68cbe..6f0194aa793 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
@@ -8,7 +8,6 @@
#include <memory>
#include "third_party/blink/renderer/bindings/core/v8/string_or_unrestricted_double_sequence.h"
-#include "third_party/blink/renderer/core/geometry/dom_matrix_2d_init.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"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -21,6 +20,7 @@ namespace blink {
class DOMMatrix;
class DOMMatrixInit;
+class DOMMatrix2DInit;
class DOMPoint;
class DOMPointInit;
@@ -30,7 +30,7 @@ class CORE_EXPORT DOMMatrixReadOnly : public ScriptWrappable {
public:
static DOMMatrixReadOnly* Create(ExecutionContext*, ExceptionState&);
static DOMMatrixReadOnly* Create(ExecutionContext*,
- StringOrUnrestrictedDoubleSequence&,
+ const StringOrUnrestrictedDoubleSequence&,
ExceptionState&);
static DOMMatrixReadOnly* fromFloat32Array(NotShared<DOMFloat32Array>,
ExceptionState&);
@@ -130,9 +130,7 @@ class CORE_EXPORT DOMMatrixReadOnly : public ScriptWrappable {
AffineTransform GetAffineTransform() const;
- void Trace(blink::Visitor* visitor) override {
- ScriptWrappable::Trace(visitor);
- }
+ void Trace(Visitor* visitor) override { ScriptWrappable::Trace(visitor); }
protected:
void SetMatrixValueFromString(const ExecutionContext*,
diff --git a/chromium/third_party/blink/renderer/core/geometry/dom_matrix_read_only.idl b/chromium/third_party/blink/renderer/core/geometry/dom_matrix_read_only.idl
index dfc75bb8cf3..e1279dd0091 100644
--- a/chromium/third_party/blink/renderer/core/geometry/dom_matrix_read_only.idl
+++ b/chromium/third_party/blink/renderer/core/geometry/dom_matrix_read_only.idl
@@ -5,13 +5,11 @@
// https://drafts.fxtf.org/geometry/#DOMMatrix
[
- Constructor(optional (DOMString or sequence<unrestricted double>) init),
- RaisesException=Constructor,
- ConstructorCallWith=ExecutionContext,
Exposed=(Window,Worker),
Serializable
] interface DOMMatrixReadOnly {
- [RaisesException, NewObject] static DOMMatrixReadOnly fromMatrix(optional DOMMatrixInit other);
+ [CallWith=ExecutionContext, RaisesException] constructor(optional (DOMString or sequence<unrestricted double>) init);
+ [RaisesException, NewObject] static DOMMatrixReadOnly fromMatrix(optional DOMMatrixInit other = {});
[RaisesException, NewObject] static DOMMatrixReadOnly fromFloat32Array(Float32Array array32);
[RaisesException, NewObject] static DOMMatrixReadOnly fromFloat64Array(Float64Array array64);
@@ -70,12 +68,12 @@
optional unrestricted double angle = 0);
DOMMatrix skewX(optional unrestricted double sx = 0);
DOMMatrix skewY(optional unrestricted double sy = 0);
- [RaisesException] DOMMatrix multiply(optional DOMMatrixInit other);
+ [RaisesException] DOMMatrix multiply(optional DOMMatrixInit other = {});
DOMMatrix flipX();
DOMMatrix flipY();
DOMMatrix inverse();
- DOMPoint transformPoint(optional DOMPointInit point);
+ DOMPoint transformPoint(optional DOMPointInit point = {});
Float32Array toFloat32Array();
Float64Array toFloat64Array();
[Exposed=Window, RaisesException] stringifier;
diff --git a/chromium/third_party/blink/renderer/core/geometry/dom_matrix_test.cc b/chromium/third_party/blink/renderer/core/geometry/dom_matrix_test.cc
index 725fb2e20c9..70c750bf4ee 100644
--- a/chromium/third_party/blink/renderer/core/geometry/dom_matrix_test.cc
+++ b/chromium/third_party/blink/renderer/core/geometry/dom_matrix_test.cc
@@ -6,6 +6,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_init.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/geometry/dom_point.cc b/chromium/third_party/blink/renderer/core/geometry/dom_point.cc
index 7b05d53a4f5..cbb5c27babe 100644
--- a/chromium/third_party/blink/renderer/core/geometry/dom_point.cc
+++ b/chromium/third_party/blink/renderer/core/geometry/dom_point.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/core/geometry/dom_point.h"
-#include "third_party/blink/renderer/core/geometry/dom_point_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_point_init.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/geometry/dom_point.idl b/chromium/third_party/blink/renderer/core/geometry/dom_point.idl
index a2e04a2755d..1bdd4d03018 100644
--- a/chromium/third_party/blink/renderer/core/geometry/dom_point.idl
+++ b/chromium/third_party/blink/renderer/core/geometry/dom_point.idl
@@ -5,12 +5,12 @@
// https://drafts.fxtf.org/geometry/#DOMPoint
[
- Constructor(optional unrestricted double x = 0, optional unrestricted double y = 0,
- optional unrestricted double z = 0, optional unrestricted double w = 1),
Exposed=(Window,Worker),
Serializable
] interface DOMPoint : DOMPointReadOnly {
- [NewObject] static DOMPoint fromPoint(optional DOMPointInit other);
+ constructor(optional unrestricted double x = 0, optional unrestricted double y = 0,
+ optional unrestricted double z = 0, optional unrestricted double w = 1);
+ [NewObject] static DOMPoint fromPoint(optional DOMPointInit other = {});
inherit attribute unrestricted double x;
inherit attribute unrestricted double y;
inherit attribute unrestricted double z;
diff --git a/chromium/third_party/blink/renderer/core/geometry/dom_point_read_only.cc b/chromium/third_party/blink/renderer/core/geometry/dom_point_read_only.cc
index 57621db6760..023de531a8a 100644
--- a/chromium/third_party/blink/renderer/core/geometry/dom_point_read_only.cc
+++ b/chromium/third_party/blink/renderer/core/geometry/dom_point_read_only.cc
@@ -5,11 +5,11 @@
#include "third_party/blink/renderer/core/geometry/dom_point_read_only.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_point_init.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
-#include "third_party/blink/renderer/core/geometry/dom_matrix_init.h"
#include "third_party/blink/renderer/core/geometry/dom_matrix_read_only.h"
#include "third_party/blink/renderer/core/geometry/dom_point.h"
-#include "third_party/blink/renderer/core/geometry/dom_point_init.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/geometry/dom_point_read_only.idl b/chromium/third_party/blink/renderer/core/geometry/dom_point_read_only.idl
index 51791cfcdf0..fc84bc4a90e 100644
--- a/chromium/third_party/blink/renderer/core/geometry/dom_point_read_only.idl
+++ b/chromium/third_party/blink/renderer/core/geometry/dom_point_read_only.idl
@@ -5,19 +5,19 @@
// https://drafts.fxtf.org/geometry/#dompointreadonly
[
- Constructor(optional unrestricted double x = 0, optional unrestricted double y = 0,
- optional unrestricted double z = 0, optional unrestricted double w = 1),
Exposed=(Window,Worker),
Serializable
] interface DOMPointReadOnly {
- [NewObject] static DOMPointReadOnly fromPoint(optional DOMPointInit other);
+ constructor(optional unrestricted double x = 0, optional unrestricted double y = 0,
+ optional unrestricted double z = 0, optional unrestricted double w = 1);
+ [NewObject] static DOMPointReadOnly fromPoint(optional DOMPointInit other = {});
readonly attribute unrestricted double x;
readonly attribute unrestricted double y;
readonly attribute unrestricted double z;
readonly attribute unrestricted double w;
- [RaisesException] DOMPoint matrixTransform(optional DOMMatrixInit matrix);
+ [RaisesException, NewObject] DOMPoint matrixTransform(optional DOMMatrixInit matrix = {});
[CallWith=ScriptState, ImplementedAs=toJSONForBinding] object toJSON();
};
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 7060f5ca733..24e4016c1de 100644
--- a/chromium/third_party/blink/renderer/core/geometry/dom_quad.cc
+++ b/chromium/third_party/blink/renderer/core/geometry/dom_quad.cc
@@ -4,12 +4,13 @@
#include "third_party/blink/renderer/core/geometry/dom_quad.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_point_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_quad_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_rect_init.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
#include "third_party/blink/renderer/core/geometry/dom_point.h"
-#include "third_party/blink/renderer/core/geometry/dom_point_init.h"
-#include "third_party/blink/renderer/core/geometry/dom_quad_init.h"
#include "third_party/blink/renderer/core/geometry/dom_rect.h"
-#include "third_party/blink/renderer/core/geometry/dom_rect_init.h"
+#include "third_party/blink/renderer/core/geometry/geometry_util.h"
namespace blink {
namespace {
@@ -44,7 +45,7 @@ class DOMQuadPoint final : public DOMPoint {
quad_->set_needs_bounds_calculation(true);
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(quad_);
DOMPoint::Trace(visitor);
}
@@ -53,12 +54,14 @@ class DOMQuadPoint final : public DOMPoint {
WeakMember<DOMQuad> quad_;
};
-double min4(double a, double b, double c, double d) {
- return std::min(std::min(a, b), std::min(c, d));
+double NanSafeMin4(double a, double b, double c, double d) {
+ using geometry_util::NanSafeMin;
+ return NanSafeMin(NanSafeMin(a, b), NanSafeMin(c, d));
}
-double max4(double a, double b, double c, double d) {
- return std::max(std::max(a, b), std::max(c, d));
+double NanSafeMax4(double a, double b, double c, double d) {
+ using geometry_util::NanSafeMax;
+ return NanSafeMax(NanSafeMax(a, b), NanSafeMax(c, d));
}
} // namespace
@@ -90,10 +93,10 @@ DOMRect* DOMQuad::getBounds() {
}
void DOMQuad::CalculateBounds() {
- x_ = min4(p1()->x(), p2()->x(), p3()->x(), p4()->x());
- y_ = min4(p1()->y(), p2()->y(), p3()->y(), p4()->y());
- width_ = max4(p1()->x(), p2()->x(), p3()->x(), p4()->x()) - x_;
- height_ = max4(p1()->y(), p2()->y(), p3()->y(), p4()->y()) - y_;
+ x_ = NanSafeMin4(p1()->x(), p2()->x(), p3()->x(), p4()->x());
+ y_ = NanSafeMin4(p1()->y(), p2()->y(), p3()->y(), p4()->y());
+ width_ = NanSafeMax4(p1()->x(), p2()->x(), p3()->x(), p4()->x()) - x_;
+ height_ = NanSafeMax4(p1()->y(), p2()->y(), p3()->y(), p4()->y()) - y_;
needs_bounds_calculation_ = false;
}
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 450fb1045e3..86e80f1dbba 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(p1_);
visitor->Trace(p2_);
visitor->Trace(p3_);
diff --git a/chromium/third_party/blink/renderer/core/geometry/dom_quad.idl b/chromium/third_party/blink/renderer/core/geometry/dom_quad.idl
index 5f18cdf89df..8a589be18a5 100644
--- a/chromium/third_party/blink/renderer/core/geometry/dom_quad.idl
+++ b/chromium/third_party/blink/renderer/core/geometry/dom_quad.idl
@@ -5,13 +5,12 @@
// https://drafts.fxtf.org/geometry/#domquad
[
- Constructor(optional DOMPointInit p1, optional DOMPointInit p2, optional DOMPointInit p3, optional DOMPointInit p4),
Exposed=(Window,Worker),
Serializable
-]
-interface DOMQuad {
- [NewObject] static DOMQuad fromRect(optional DOMRectInit other);
- [NewObject] static DOMQuad fromQuad(optional DOMQuadInit other);
+] interface DOMQuad {
+ constructor(optional DOMPointInit p1 = {}, optional DOMPointInit p2 = {}, optional DOMPointInit p3 = {}, optional DOMPointInit p4 = {});
+ [NewObject] static DOMQuad fromRect(optional DOMRectInit other = {});
+ [NewObject] static DOMQuad fromQuad(optional DOMQuadInit other = {});
[SameObject] readonly attribute DOMPoint p1;
[SameObject] readonly attribute DOMPoint p2;
diff --git a/chromium/third_party/blink/renderer/core/geometry/dom_rect.cc b/chromium/third_party/blink/renderer/core/geometry/dom_rect.cc
index 7d519c4b33b..ab307fd688a 100644
--- a/chromium/third_party/blink/renderer/core/geometry/dom_rect.cc
+++ b/chromium/third_party/blink/renderer/core/geometry/dom_rect.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/core/geometry/dom_rect.h"
-#include "third_party/blink/renderer/core/geometry/dom_rect_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_rect_init.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/geometry/dom_rect.idl b/chromium/third_party/blink/renderer/core/geometry/dom_rect.idl
index 45171c08f1b..4e31035287a 100644
--- a/chromium/third_party/blink/renderer/core/geometry/dom_rect.idl
+++ b/chromium/third_party/blink/renderer/core/geometry/dom_rect.idl
@@ -5,14 +5,14 @@
// https://drafts.fxtf.org/geometry/#DOMRect
[
- Constructor(optional unrestricted double x = 0,
- optional unrestricted double y = 0,
- optional unrestricted double width = 0,
- optional unrestricted double height = 0),
Exposed=(Window,Worker),
Serializable
] interface DOMRect : DOMRectReadOnly {
- [NewObject] static DOMRect fromRect(optional DOMRectInit other);
+ constructor(optional unrestricted double x = 0,
+ optional unrestricted double y = 0,
+ optional unrestricted double width = 0,
+ optional unrestricted double height = 0);
+ [NewObject] static DOMRect fromRect(optional DOMRectInit other = {});
inherit attribute unrestricted double x;
inherit attribute unrestricted double y;
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 ca6fffe5d2c..80d4d731227 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(blink::Visitor* visitor) {
+void DOMRectList::Trace(Visitor* visitor) {
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 f3dc17bf273..718ce9e1755 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
@@ -39,16 +39,6 @@ class CORE_EXPORT DOMRectList final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- static DOMRectList* Create() { return MakeGarbageCollected<DOMRectList>(); }
- static DOMRectList* Create(const Vector<FloatQuad>& quads) {
- return MakeGarbageCollected<DOMRectList>(quads);
- }
-
- template <typename Rects>
- static DOMRectList* Create(const Rects& rects) {
- return MakeGarbageCollected<DOMRectList>(rects);
- }
-
DOMRectList();
template <typename Rects>
@@ -63,7 +53,7 @@ class CORE_EXPORT DOMRectList final : public ScriptWrappable {
unsigned length() const;
DOMRect* item(unsigned index);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
HeapVector<Member<DOMRect>> list_;
diff --git a/chromium/third_party/blink/renderer/core/geometry/dom_rect_read_only.cc b/chromium/third_party/blink/renderer/core/geometry/dom_rect_read_only.cc
index 60cfca3bbdb..7dfc9fde689 100644
--- a/chromium/third_party/blink/renderer/core/geometry/dom_rect_read_only.cc
+++ b/chromium/third_party/blink/renderer/core/geometry/dom_rect_read_only.cc
@@ -5,8 +5,8 @@
#include "third_party/blink/renderer/core/geometry/dom_rect_read_only.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_rect_init.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
-#include "third_party/blink/renderer/core/geometry/dom_rect_init.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/geometry/dom_rect_read_only.h b/chromium/third_party/blink/renderer/core/geometry/dom_rect_read_only.h
index 77398f0ee11..0c3f84ca4d8 100644
--- a/chromium/third_party/blink/renderer/core/geometry/dom_rect_read_only.h
+++ b/chromium/third_party/blink/renderer/core/geometry/dom_rect_read_only.h
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_GEOMETRY_DOM_RECT_READ_ONLY_H_
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/geometry/geometry_util.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
@@ -35,10 +36,10 @@ class CORE_EXPORT DOMRectReadOnly : public ScriptWrappable {
double width() const { return width_; }
double height() const { return height_; }
- double top() const { return std::min(y_, y_ + height_); }
- double right() const { return std::max(x_, x_ + width_); }
- double bottom() const { return std::max(y_, y_ + height_); }
- double left() const { return std::min(x_, x_ + width_); }
+ double top() const { return geometry_util::NanSafeMin(y_, y_ + height_); }
+ double right() const { return geometry_util::NanSafeMax(x_, x_ + width_); }
+ double bottom() const { return geometry_util::NanSafeMax(y_, y_ + height_); }
+ double left() const { return geometry_util::NanSafeMin(x_, x_ + width_); }
ScriptValue toJSONForBinding(ScriptState*) const;
diff --git a/chromium/third_party/blink/renderer/core/geometry/dom_rect_read_only.idl b/chromium/third_party/blink/renderer/core/geometry/dom_rect_read_only.idl
index 39f4a35096c..e26b3567156 100644
--- a/chromium/third_party/blink/renderer/core/geometry/dom_rect_read_only.idl
+++ b/chromium/third_party/blink/renderer/core/geometry/dom_rect_read_only.idl
@@ -5,12 +5,12 @@
// https://drafts.fxtf.org/geometry/#DOMRect
[
- Constructor(optional unrestricted double x = 0, optional unrestricted double y = 0,
- optional unrestricted double width = 0, optional unrestricted double height = 0),
Exposed=(Window,Worker),
Serializable
] interface DOMRectReadOnly {
- [NewObject] static DOMRectReadOnly fromRect(optional DOMRectInit other);
+ constructor(optional unrestricted double x = 0, optional unrestricted double y = 0,
+ optional unrestricted double width = 0, optional unrestricted double height = 0);
+ [NewObject] static DOMRectReadOnly fromRect(optional DOMRectInit other = {});
readonly attribute unrestricted double x;
readonly attribute unrestricted double y;
diff --git a/chromium/third_party/blink/renderer/core/geometry/geometry_util.h b/chromium/third_party/blink/renderer/core/geometry/geometry_util.h
new file mode 100644
index 00000000000..eb89fa1a251
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/geometry/geometry_util.h
@@ -0,0 +1,38 @@
+// 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_GEOMETRY_GEOMETRY_UTIL_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_GEOMETRY_GEOMETRY_UTIL_H_
+
+#include <algorithm>
+#include <cmath>
+#include <limits>
+
+namespace blink {
+
+namespace geometry_util {
+
+// Returns the minimum of |a| and |b|. If either operand is NaN, then NaN is
+// returned, consistent with Math.min() in JavaScript.
+inline double NanSafeMin(double a, double b) {
+ if (std::isnan(a) || std::isnan(b)) {
+ return std::numeric_limits<double>::quiet_NaN();
+ }
+ return std::min(a, b);
+}
+
+// Returns the maximum of |a| and |b|. If either operand is NaN, then NaN is
+// returned, consistent with Math.max() in JavaScript.
+inline double NanSafeMax(double a, double b) {
+ if (std::isnan(a) || std::isnan(b)) {
+ return std::numeric_limits<double>::quiet_NaN();
+ }
+ return std::max(a, b);
+}
+
+} // namespace geometry_util
+
+} // namespace blink
+
+#endif
diff --git a/chromium/third_party/blink/renderer/core/html/BUILD.gn b/chromium/third_party/blink/renderer/core/html/BUILD.gn
index 08ed3b97d48..de82c30b599 100644
--- a/chromium/third_party/blink/renderer/core/html/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/html/BUILD.gn
@@ -220,6 +220,8 @@ blink_core_sources("html") {
"forms/labels_node_list.h",
"forms/listed_element.cc",
"forms/listed_element.h",
+ "forms/menu_list_inner_element.cc",
+ "forms/menu_list_inner_element.h",
"forms/month_input_type.cc",
"forms/month_input_type.h",
"forms/multiple_fields_temporal_input_type_view.cc",
@@ -245,12 +247,16 @@ blink_core_sources("html") {
"forms/reset_input_type.h",
"forms/search_input_type.cc",
"forms/search_input_type.h",
+ "forms/select_type.cc",
+ "forms/select_type.h",
"forms/slider_thumb_element.cc",
"forms/slider_thumb_element.h",
"forms/spin_button_element.cc",
"forms/spin_button_element.h",
"forms/step_range.cc",
"forms/step_range.h",
+ "forms/submit_event.cc",
+ "forms/submit_event.h",
"forms/submit_input_type.cc",
"forms/submit_input_type.h",
"forms/telephone_input_type.cc",
@@ -470,8 +476,6 @@ blink_core_sources("html") {
"media/html_media_element.h",
"media/html_media_element_controls_list.cc",
"media/html_media_element_controls_list.h",
- "media/html_media_source.cc",
- "media/html_media_source.h",
"media/html_video_element.cc",
"media/html_video_element.h",
"media/media_controls.cc",
@@ -487,13 +491,15 @@ blink_core_sources("html") {
"media/media_fragment_uri_parser.h",
"media/media_remoting_interstitial.cc",
"media/media_remoting_interstitial.h",
+ "media/media_source.cc",
+ "media/media_source.h",
"media/picture_in_picture_interstitial.cc",
"media/picture_in_picture_interstitial.h",
"media/remote_playback_controller.cc",
"media/remote_playback_controller.h",
"media/remote_playback_observer.h",
- "media/video_request_animation_frame.cc",
- "media/video_request_animation_frame.h",
+ "media/video_frame_callback_requester.cc",
+ "media/video_frame_callback_requester.h",
"media/video_wake_lock.cc",
"media/video_wake_lock.h",
"plugin_document.cc",
@@ -574,11 +580,14 @@ blink_core_sources("html") {
"track/vtt/vtt_token.h",
"track/vtt/vtt_tokenizer.cc",
"track/vtt/vtt_tokenizer.h",
+ "trust_token_attribute_parsing.cc",
+ "trust_token_attribute_parsing.h",
"window_name_collection.cc",
"window_name_collection.h",
]
- jumbo_excluded_sources = [ "canvas/canvas_rendering_context.cc" ] # https://crbug.com/716395
+ jumbo_excluded_sources =
+ [ "canvas/canvas_rendering_context.cc" ] # https://crbug.com/716395
deps = [
"//services/metrics/public/cpp:metrics_cpp",
@@ -591,18 +600,109 @@ blink_core_sources("html") {
copy("form_controls_pickers_js") {
testonly = true
- sources = [
- "forms/resources/color_picker.js",
- ]
+ sources = [ "forms/resources/color_picker.js" ]
- outputs = [
- "{{source_gen_dir}}/{{source_file_part}}",
- ]
+ outputs = [ "{{source_gen_dir}}/{{source_file_part}}" ]
}
group("js_files_for_form_controls_web_tests") {
testonly = true
- data_deps = [
- ":form_controls_pickers_js",
+ data_deps = [ ":form_controls_pickers_js" ]
+}
+
+blink_core_tests("unit_tests") {
+ sources = [
+ "anchor_element_metrics_sender_test.cc",
+ "anchor_element_metrics_test.cc",
+ "canvas/canvas_async_blob_creator_test.cc",
+ "canvas/canvas_font_cache_test.cc",
+ "canvas/html_canvas_element_test.cc",
+ "canvas/image_data_test.cc",
+ "custom/custom_element_definition_test.cc",
+ "custom/custom_element_descriptor_test.cc",
+ "custom/custom_element_reaction_queue_test.cc",
+ "custom/custom_element_reaction_stack_test.cc",
+ "custom/custom_element_reaction_test_helpers.h",
+ "custom/custom_element_registry_test.cc",
+ "custom/custom_element_test.cc",
+ "custom/custom_element_test_helpers.cc",
+ "custom/custom_element_test_helpers.h",
+ "custom/custom_element_upgrade_sorter_test.cc",
+ "forms/email_input_type_test.cc",
+ "forms/external_date_time_chooser_test.cc",
+ "forms/external_popup_menu_test.cc",
+ "forms/file_input_type_test.cc",
+ "forms/form_controller_test.cc",
+ "forms/form_data_test.cc",
+ "forms/html_data_list_element_test.cc",
+ "forms/html_form_control_element_test.cc",
+ "forms/html_form_element_test.cc",
+ "forms/html_input_element_test.cc",
+ "forms/html_output_element_test.cc",
+ "forms/html_select_element_test.cc",
+ "forms/html_text_area_element_test.cc",
+ "forms/internal_popup_menu_test.cc",
+ "forms/option_list_test.cc",
+ "forms/password_input_type_test.cc",
+ "forms/step_range_test.cc",
+ "forms/text_control_element_test.cc",
+ "forms/type_ahead_test.cc",
+ "html_content_element_test.cc",
+ "html_dimension_test.cc",
+ "html_element_test.cc",
+ "html_embed_element_test.cc",
+ "html_frame_element_test.cc",
+ "html_iframe_element_test.cc",
+ "html_image_element_test.cc",
+ "html_link_element_sizes_attribute_test.cc",
+ "html_link_element_test.cc",
+ "html_meta_element_test.cc",
+ "html_object_element_test.cc",
+ "html_plugin_element_test.cc",
+ "html_script_element_test.cc",
+ "html_slot_element_test.cc",
+ "html_table_row_element_test.cc",
+ "image_document_test.cc",
+ "imports/html_import_sheets_test.cc",
+ "lazy_load_frame_observer_test.cc",
+ "lazy_load_image_observer_test.cc",
+ "link_element_loading_test.cc",
+ "link_rel_attribute_test.cc",
+ "media/autoplay_uma_helper_test.cc",
+ "media/html_media_element_event_listeners_test.cc",
+ "media/html_media_element_test.cc",
+ "media/html_media_test_helper.cc",
+ "media/html_media_test_helper.h",
+ "media/html_video_element_persistent_test.cc",
+ "media/html_video_element_test.cc",
+ "media/media_custom_controls_fullscreen_detector_test.cc",
+ "media/video_auto_fullscreen_test.cc",
+ "media/video_filling_viewport_test.cc",
+ "media/video_wake_lock_test.cc",
+ "parser/atomic_html_token_test.cc",
+ "parser/compact_html_token_test.cc",
+ "parser/html_document_parser_loading_test.cc",
+ "parser/html_document_parser_test.cc",
+ "parser/html_entity_parser_test.cc",
+ "parser/html_parser_idioms_test.cc",
+ "parser/html_parser_metrics_test.cc",
+ "parser/html_preload_scanner_document_test.cc",
+ "parser/html_preload_scanner_test.cc",
+ "parser/html_resource_preloader_test.cc",
+ "parser/html_srcset_parser_test.cc",
+ "parser/html_tokenizer_test.cc",
+ "parser/html_tree_builder_simulator_test.cc",
+ "parser/html_view_source_parser_test.cc",
+ "parser/text_resource_decoder_test.cc",
+ "portal/html_portal_element_test.cc",
+ "shadow/progress_shadow_element_test.cc",
+ "subresource_redirect_test.cc",
+ "time_ranges_test.cc",
+ "track/text_track_list_test.cc",
+ "track/vtt/buffered_line_reader_test.cc",
+ "track/vtt/vtt_scanner_test.cc",
+ "trust_token_attribute_parsing_test.cc",
]
+
+ deps = [ "//services/network/trust_tokens:test_support" ]
}
diff --git a/chromium/third_party/blink/renderer/core/html/DEPS b/chromium/third_party/blink/renderer/core/html/DEPS
new file mode 100644
index 00000000000..9eb654292f0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/DEPS
@@ -0,0 +1,5 @@
+specific_include_rules = {
+ "trust_token_attribute_parsing_test.cc": [
+ "+services/network/trust_tokens/test",
+ ],
+}
diff --git a/chromium/third_party/blink/renderer/core/html/anchor_element_metrics.cc b/chromium/third_party/blink/renderer/core/html/anchor_element_metrics.cc
index 4172e8ba876..04987385b04 100644
--- a/chromium/third_party/blink/renderer/core/html/anchor_element_metrics.cc
+++ b/chromium/third_party/blink/renderer/core/html/anchor_element_metrics.cc
@@ -18,7 +18,6 @@
#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/platform/geometry/int_size.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
diff --git a/chromium/third_party/blink/renderer/core/html/anchor_element_metrics.h b/chromium/third_party/blink/renderer/core/html/anchor_element_metrics.h
index 44585d1242c..52eb928f076 100644
--- a/chromium/third_party/blink/renderer/core/html/anchor_element_metrics.h
+++ b/chromium/third_party/blink/renderer/core/html/anchor_element_metrics.h
@@ -72,7 +72,7 @@ class CORE_EXPORT AnchorElementMetrics {
void RecordMetricsOnClick() const;
// The anchor element that this class is associated with.
- Member<const HTMLAnchorElement> anchor_element_;
+ const HTMLAnchorElement* anchor_element_;
// The ratio of the absolute/visible clickable region area of an anchor
// element, and the viewport area.
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 c08cce6006b..45cc716171c 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
@@ -7,6 +7,7 @@
#include "base/metrics/histogram_macros.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/platform/task_type.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/anchor_element_metrics.h"
@@ -74,7 +75,7 @@ void AnchorElementMetricsSender::SendAnchorMetricsVectorToBrowser(
return;
metrics_host_->ReportAnchorElementMetricsOnLoad(std::move(metrics),
- viewport_size);
+ gfx::Size(viewport_size));
has_onload_report_sent_ = true;
anchor_elements_.clear();
}
@@ -101,11 +102,12 @@ AnchorElementMetricsSender::GetAnchorElements() const {
void AnchorElementMetricsSender::Trace(Visitor* visitor) {
visitor->Trace(anchor_elements_);
+ visitor->Trace(metrics_host_);
Supplement<Document>::Trace(visitor);
}
bool AnchorElementMetricsSender::AssociateInterface() {
- if (metrics_host_)
+ if (metrics_host_.is_bound())
return true;
Document* document = GetSupplementable();
@@ -114,12 +116,15 @@ bool AnchorElementMetricsSender::AssociateInterface() {
return false;
document->GetBrowserInterfaceBroker().GetInterface(
- metrics_host_.BindNewPipeAndPassReceiver());
+ metrics_host_.BindNewPipeAndPassReceiver(
+ document->GetExecutionContext()->GetTaskRunner(
+ TaskType::kInternalDefault)));
return true;
}
AnchorElementMetricsSender::AnchorElementMetricsSender(Document& document)
- : Supplement<Document>(document) {
+ : Supplement<Document>(document),
+ metrics_host_(document.GetExecutionContext()) {
DCHECK(!document.ParentDocument());
}
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 0e5b24774b3..d421c1ba7c5 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
@@ -6,12 +6,12 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_ANCHOR_ELEMENT_METRICS_SENDER_H_
#include "base/macros.h"
-#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/loader/navigation_predictor.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/platform/geometry/int_size.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/supplementable.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -71,7 +71,7 @@ class CORE_EXPORT AnchorElementMetricsSender final
bool AssociateInterface();
// Browser host to which the anchor element metrics are sent.
- mojo::Remote<mojom::blink::AnchorElementMetricsHost> metrics_host_;
+ HeapMojoRemote<mojom::blink::AnchorElementMetricsHost> metrics_host_;
// Collection of anchor elements in the document. Use a HashSet to ensure that
// an element is inserted at most once.
diff --git a/chromium/third_party/blink/renderer/core/html/anchor_element_metrics_test.cc b/chromium/third_party/blink/renderer/core/html/anchor_element_metrics_test.cc
index a79912ee2cf..b5bc306edfd 100644
--- a/chromium/third_party/blink/renderer/core/html/anchor_element_metrics_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/anchor_element_metrics_test.cc
@@ -205,7 +205,8 @@ TEST_F(AnchorElementMetricsTest, AnchorFeatureExtract) {
// Scroll down to the anchor element.
GetDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, kViewportHeight * 1.5), kProgrammaticScroll);
+ ScrollOffset(0, kViewportHeight * 1.5),
+ mojom::blink::ScrollType::kProgrammatic);
auto feature2 =
AnchorElementMetrics::MaybeReportClickedMetricsOnClick(anchor_element)
@@ -267,7 +268,8 @@ TEST_F(AnchorElementMetricsTest, AnchorFeatureInIframe) {
// Scroll down the main frame.
GetDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, kViewportHeight * 1.8), kProgrammaticScroll);
+ ScrollOffset(0, kViewportHeight * 1.8),
+ mojom::blink::ScrollType::kProgrammatic);
auto feature2 =
AnchorElementMetrics::MaybeReportClickedMetricsOnClick(anchor_element)
@@ -279,7 +281,8 @@ TEST_F(AnchorElementMetricsTest, AnchorFeatureInIframe) {
// Scroll down inside iframe. Now the anchor element is visible.
subframe->View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, kViewportHeight * 0.2), kProgrammaticScroll);
+ ScrollOffset(0, kViewportHeight * 0.2),
+ mojom::blink::ScrollType::kProgrammatic);
auto feature3 =
AnchorElementMetrics::MaybeReportClickedMetricsOnClick(anchor_element)
diff --git a/chromium/third_party/blink/renderer/core/html/aria_properties.json5 b/chromium/third_party/blink/renderer/core/html/aria_properties.json5
index 6117c1e6113..b57f304ddc0 100644
--- a/chromium/third_party/blink/renderer/core/html/aria_properties.json5
+++ b/chromium/third_party/blink/renderer/core/html/aria_properties.json5
@@ -62,8 +62,6 @@
enum: ["false", "true", "menu", "listbox", "tree", "grid", "dialog"],
type: "token"
},
- // aria-help is not specced but we have historically supported it.
- {name: "aria-help", type: "string"},
{
name: "aria-hidden",
default: "undefined",
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 3d8b51d9113..98297281a3b 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
@@ -20,7 +20,6 @@
#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/image-encoders/image_encoder_utils.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.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/scheduler/public/thread_scheduler.h"
@@ -310,8 +309,10 @@ void CanvasAsyncBlobCreator::ScheduleAsyncBlobCreation(const double& quality) {
// deadlines (6.7s or 13s) bypass the web test running deadline (6s)
// and result in timeouts on different tests. We use
// enforce_idle_encoding_for_test_ to test idle encoding in unit tests.
+ // We also don't use idle tasks in workers because there's no proper idle
+ // queue there and tasks can take too long without requestAnimationFrame.
bool use_idle_encoding =
- (mime_type_ != kMimeTypeWebp) &&
+ WTF::IsMainThread() && (mime_type_ != kMimeTypeWebp) &&
(enforce_idle_encoding_for_test_ ||
!RuntimeEnabledFeatures::NoIdleEncodingForWebTestsEnabled());
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 fe400b9bc00..9a2c289975a 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
@@ -11,8 +11,8 @@
#include "base/single_thread_task_runner.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/image_encode_options.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"
@@ -50,8 +50,7 @@ class CORE_EXPORT CanvasAsyncBlobCreator
enum ToBlobFunctionType {
kHTMLCanvasToBlobCallback,
kHTMLCanvasConvertToBlobPromise,
- kOffscreenCanvasConvertToBlobPromise,
- kNumberOfToBlobFunctionTypes
+ kOffscreenCanvasConvertToBlobPromise
};
void ScheduleAsyncBlobCreation(const double& quality);
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 3d0c1185640..32388eb43c1 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
@@ -7,6 +7,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/html/canvas/image_data.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/platform/graphics/color_correction_test_utils.h"
@@ -33,7 +34,7 @@ class MockCanvasAsyncBlobCreator : public CanvasAsyncBlobCreator {
kHTMLCanvasToBlobCallback,
nullptr,
base::TimeTicks(),
- document,
+ document->GetExecutionContext(),
nullptr) {
if (fail_encoder_initialization)
fail_encoder_initialization_for_test_ = true;
@@ -293,7 +294,7 @@ TEST_F(CanvasAsyncBlobCreatorTest, ColorManagedConvertToBlob) {
source_bitmap_image, options,
CanvasAsyncBlobCreator::ToBlobFunctionType::
kHTMLCanvasConvertToBlobPromise,
- base::TimeTicks(), &GetDocument(), nullptr);
+ base::TimeTicks(), GetFrame().DomWindow(), nullptr);
ASSERT_TRUE(async_blob_creator->EncodeImageForConvertToBlobTest());
sk_sp<SkData> sk_data = SkData::MakeWithCopy(
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_draw_listener.h b/chromium/third_party/blink/renderer/core/html/canvas/canvas_draw_listener.h
index e745c09b710..7a0266b3868 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_draw_listener.h
+++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_draw_listener.h
@@ -9,10 +9,8 @@
#include "base/memory/weak_ptr.h"
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/skia/include/core/SkRefCnt.h"
-
-class SkImage;
namespace blink {
@@ -22,7 +20,7 @@ class CORE_EXPORT CanvasDrawListener : public GarbageCollectedMixin {
public:
virtual ~CanvasDrawListener();
virtual void SendNewFrame(
- sk_sp<SkImage>,
+ scoped_refptr<StaticBitmapImage>,
base::WeakPtr<WebGraphicsContext3DProviderWrapper>) = 0;
virtual bool NeedsNewFrame() const = 0;
virtual void RequestFrame() = 0;
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 da84ab47e1c..c86e35e067b 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
@@ -37,8 +37,6 @@ CanvasFontCache::CanvasFontCache(Document& document)
default_font_description.SetComputedSize(defaultFontSize);
default_font_style_ = ComputedStyle::Create();
default_font_style_->SetFontDescription(default_font_description);
- default_font_style_->GetFont().Update(
- default_font_style_->GetFont().GetFontSelector());
}
CanvasFontCache::~CanvasFontCache() {
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 09e5055466e..12047018871 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
@@ -42,7 +42,7 @@ CanvasRenderingContext* CanvasFontCacheTest::Context2D() const {
void CanvasFontCacheTest::SetUp() {
PageTestBase::SetUp();
- GetDocument().documentElement()->SetInnerHTMLFromString(
+ GetDocument().documentElement()->setInnerHTML(
"<body><canvas id='c'></canvas></body>");
UpdateAllLifecyclePhasesForTest();
canvas_element_ = To<HTMLCanvasElement>(GetDocument().getElementById("c"));
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 86478c5c04d..8e8782b0461 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
@@ -31,11 +31,11 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/geometry/float_size.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
+#include "third_party/blink/renderer/platform/graphics/image_orientation.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
namespace blink {
-class FloatRect;
class Image;
enum SourceImageStatus {
@@ -67,16 +67,12 @@ class CORE_EXPORT CanvasImageSource {
virtual bool IsImageBitmap() const { return false; }
virtual bool IsOffscreenCanvas() const { return false; }
- // Adjusts the source and destination rectangles for cases where the actual
- // source image is a subregion of the image returned by
- // getSourceImageForCanvas.
- virtual void AdjustDrawRects(FloatRect* src_rect, FloatRect* dst_rect) const {
- }
-
- virtual FloatSize ElementSize(const FloatSize& default_object_size) const = 0;
+ virtual FloatSize ElementSize(const FloatSize& default_object_size,
+ const RespectImageOrientationEnum) const = 0;
virtual FloatSize DefaultDestinationSize(
- const FloatSize& default_object_size) const {
- return ElementSize(default_object_size);
+ const FloatSize& default_object_size,
+ const RespectImageOrientationEnum respect_orientation) const {
+ return ElementSize(default_object_size, respect_orientation);
}
virtual const KURL& SourceURL() const { return BlankURL(); }
virtual bool IsOpaque() const { return false; }
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 51de8c31002..2793b17d823 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
@@ -40,9 +40,8 @@ CanvasRenderingContext::CanvasRenderingContext(
const CanvasContextCreationAttributesCore& attrs)
: host_(host),
color_params_(CanvasColorSpace::kSRGB,
- CanvasPixelFormat::kRGBA8,
- kNonOpaque,
- CanvasForceRGBA::kNotForced),
+ 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.
@@ -89,6 +88,8 @@ WTF::String CanvasRenderingContext::PixelFormatAsString() const {
return kRGBA8CanvasPixelFormatName;
case CanvasPixelFormat::kF16:
return kF16CanvasPixelFormatName;
+ case CanvasPixelFormat::kBGRA8:
+ return kBGRA8CanvasPixelFormatName;
};
CHECK(false);
return "";
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 787de816804..e14dd738e8c 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
@@ -51,6 +51,7 @@ constexpr const char* kRec2020CanvasColorSpaceName = "rec2020";
constexpr const char* kP3CanvasColorSpaceName = "p3";
constexpr const char* kRGBA8CanvasPixelFormatName = "uint8";
+constexpr const char* kBGRA8CanvasPixelFormatName = "uint8";
constexpr const char* kF16CanvasPixelFormatName = "float16";
class CORE_EXPORT CanvasRenderingContext : public ScriptWrappable,
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 116d2026856..6e4763718ca 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
@@ -5,8 +5,11 @@
#include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h"
#include "base/feature_list.h"
+#include "base/metrics/histogram_functions.h"
+#include "base/metrics/histogram_macros.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_image_encode_options.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h"
#include "third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h"
@@ -15,7 +18,6 @@
#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/skia/include/core/SkSurface.h"
namespace blink {
@@ -97,97 +99,9 @@ CanvasRenderingContextHost::GetOrCreateCanvasResourceProviderImpl(
: nullptr;
if (Is3d()) {
- CanvasResourceProvider::ResourceUsage usage;
- if (SharedGpuContext::IsGpuCompositingEnabled()) {
- if (LowLatencyEnabled()) {
- usage = CanvasResourceProvider::ResourceUsage::
- kAcceleratedDirect3DResourceUsage;
- } else {
- usage = CanvasResourceProvider::ResourceUsage::
- kAcceleratedCompositedResourceUsage;
- }
- } else {
- usage = CanvasResourceProvider::ResourceUsage::
- kSoftwareCompositedResourceUsage;
- }
-
- 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;
- }
-
- ReplaceResourceProvider(CanvasResourceProvider::CreateForCanvas(
- Size(), usage, SharedGpuContext::ContextProviderWrapper(),
- 0 /* msaa_sample_count */, FilterQuality(), ColorParams(),
- presentation_mode, std::move(dispatcher),
- RenderingContext()->IsOriginTopLeft()));
+ CreateCanvasResourceProvider3D(hint, dispatcher);
} else {
- DCHECK(Is2d());
- const bool want_acceleration =
- hint == kPreferAcceleration && ShouldAccelerate2dContext();
-
- CanvasResourceProvider::ResourceUsage usage;
- if (want_acceleration) {
- if (LowLatencyEnabled()) {
- usage = CanvasResourceProvider::ResourceUsage::
- kAcceleratedDirect2DResourceUsage;
- } else {
- usage = CanvasResourceProvider::ResourceUsage::
- kAcceleratedCompositedResourceUsage;
- }
- } else {
- usage = CanvasResourceProvider::ResourceUsage::
- kSoftwareCompositedResourceUsage;
- }
-
- uint8_t presentation_mode =
- CanvasResourceProvider::kDefaultPresentationMode;
- // 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;
- }
- // Allow swap chains only if the runtime feature is enabled and we're
- // in low latency mode too.
- if (base::FeatureList::IsEnabled(
- features::kLowLatencyCanvas2dSwapChain) &&
- LowLatencyEnabled() && want_acceleration) {
- presentation_mode |=
- CanvasResourceProvider::kAllowSwapChainPresentationMode;
- }
-
- // 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();
-
- ReplaceResourceProvider(CanvasResourceProvider::CreateForCanvas(
- Size(), usage, SharedGpuContext::ContextProviderWrapper(),
- GetMSAASampleCountFor2dContext(), FilterQuality(), ColorParams(),
- presentation_mode, std::move(dispatcher), is_origin_top_left));
-
- if (ResourceProvider()) {
- // Always save an initial frame, to support resetting the top level
- // matrix and clip.
- ResourceProvider()->Canvas()->save();
- ResourceProvider()->SetFilterQuality(FilterQuality());
- ResourceProvider()->SetResourceRecyclingEnabled(true);
- }
+ CreateCanvasResourceProvider2D(hint, dispatcher);
}
}
if (!ResourceProvider())
@@ -196,6 +110,117 @@ CanvasRenderingContextHost::GetOrCreateCanvasResourceProviderImpl(
return ResourceProvider();
}
+void CanvasRenderingContextHost::CreateCanvasResourceProvider3D(
+ AccelerationHint hint,
+ base::WeakPtr<CanvasResourceDispatcher> dispatcher) {
+ 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;
+ }
+ CanvasResourceProvider::ResourceUsage usage;
+
+ if (SharedGpuContext::IsGpuCompositingEnabled()) {
+ 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;
+ }
+ } else {
+ usage =
+ CanvasResourceProvider::ResourceUsage::kSoftwareCompositedResourceUsage;
+ }
+
+ base::UmaHistogramEnumeration("Blink.Canvas.ResourceProviderUsage", usage);
+ ReplaceResourceProvider(CanvasResourceProvider::Create(
+ Size(), usage, SharedGpuContext::ContextProviderWrapper(),
+ 0 /* msaa_sample_count */, FilterQuality(), ColorParams(),
+ presentation_mode, std::move(dispatcher),
+ RenderingContext()->IsOriginTopLeft()));
+ if (ResourceProvider() && ResourceProvider()->IsValid()) {
+ base::UmaHistogramBoolean("Blink.Canvas.ResourceProviderIsAccelerated",
+ ResourceProvider()->IsAccelerated());
+ base::UmaHistogramEnumeration("Blink.Canvas.ResourceProviderType",
+ ResourceProvider()->GetType());
+ }
+}
+
+void CanvasRenderingContextHost::CreateCanvasResourceProvider2D(
+ AccelerationHint hint,
+ base::WeakPtr<CanvasResourceDispatcher> dispatcher) {
+ DCHECK(Is2d());
+ const bool want_acceleration =
+ hint == kPreferAcceleration && ShouldAccelerate2dContext();
+
+ uint8_t presentation_mode = CanvasResourceProvider::kDefaultPresentationMode;
+ // 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;
+ }
+ if (base::FeatureList::IsEnabled(features::kLowLatencyCanvas2dSwapChain) &&
+ LowLatencyEnabled() && want_acceleration) {
+ presentation_mode |=
+ CanvasResourceProvider::kAllowSwapChainPresentationMode;
+ }
+
+ 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;
+ } else {
+ usage = CanvasResourceProvider::ResourceUsage::
+ kAcceleratedCompositedResourceUsage;
+ }
+ } else {
+ usage =
+ CanvasResourceProvider::ResourceUsage::kSoftwareCompositedResourceUsage;
+ }
+
+ // 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();
+
+ base::UmaHistogramEnumeration("Blink.Canvas.ResourceProviderUsage", usage);
+ ReplaceResourceProvider(CanvasResourceProvider::Create(
+ Size(), usage, SharedGpuContext::ContextProviderWrapper(),
+ GetMSAASampleCountFor2dContext(), FilterQuality(), ColorParams(),
+ presentation_mode, std::move(dispatcher), is_origin_top_left));
+
+ if (ResourceProvider()) {
+ if (ResourceProvider()->IsValid()) {
+ base::UmaHistogramBoolean("Blink.Canvas.ResourceProviderIsAccelerated",
+ ResourceProvider()->IsAccelerated());
+ base::UmaHistogramEnumeration("Blink.Canvas.ResourceProviderType",
+ ResourceProvider()->GetType());
+ }
+ ResourceProvider()->SetFilterQuality(FilterQuality());
+ ResourceProvider()->SetResourceRecyclingEnabled(true);
+ }
+}
+
CanvasColorParams CanvasRenderingContextHost::ColorParams() const {
if (RenderingContext())
return RenderingContext()->ColorParams();
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 851de57833e..e0503886bc6 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
@@ -10,7 +10,6 @@
#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/image_encode_options.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"
@@ -25,6 +24,7 @@ class CanvasRenderingContext;
class CanvasResource;
class CanvasResourceDispatcher;
class FontSelector;
+class ImageEncodeOptions;
class KURL;
class StaticBitmapImage;
@@ -110,6 +110,13 @@ class CORE_EXPORT CanvasRenderingContextHost : public CanvasResourceHost,
scoped_refptr<StaticBitmapImage> CreateTransparentImage(const IntSize&) const;
+ void CreateCanvasResourceProvider2D(
+ AccelerationHint hint,
+ base::WeakPtr<CanvasResourceDispatcher> dispatcher);
+ void CreateCanvasResourceProvider3D(
+ AccelerationHint hint,
+ base::WeakPtr<CanvasResourceDispatcher> dispatcher);
+
bool did_fail_to_create_resource_provider_ = false;
bool did_record_canvas_size_to_uma_ = false;
HostType host_type_ = kNone;
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 727f95a161e..487efcdd8ba 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,8 @@
#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"
+#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_image_encode_options.h"
#include "third_party/blink/renderer/core/css/css_font_selector.h"
#include "third_party/blink/renderer/core/css/style_engine.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -66,19 +68,17 @@
#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/core/imagebitmap/image_bitmap.h"
-#include "third_party/blink/renderer/core/imagebitmap/image_bitmap_options.h"
#include "third_party/blink/renderer/core/input_type_names.h"
#include "third_party/blink/renderer/core/layout/hit_test_canvas_result.h"
#include "third_party/blink/renderer/core/layout/layout_html_canvas.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/paint/compositing/paint_layer_compositor.h"
+#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#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_heuristic_parameters.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"
@@ -108,7 +108,7 @@ constexpr int kMinimumAccelerated2dCanvasSize = 128 * 129;
HTMLCanvasElement::HTMLCanvasElement(Document& document)
: HTMLElement(html_names::kCanvasTag, document),
- ContextLifecycleObserver(&document),
+ ExecutionContextLifecycleObserver(GetExecutionContext()),
PageVisibilityObserver(document.GetPage()),
CanvasRenderingContextHost(
CanvasRenderingContextHost::HostType::kCanvasHost),
@@ -140,11 +140,11 @@ void HTMLCanvasElement::Dispose() {
if (context_) {
UMA_HISTOGRAM_BOOLEAN("Blink.Canvas.HasRendered", bool(ResourceProvider()));
- if (ResourceProvider()) {
+ if (context_->Host()) {
UMA_HISTOGRAM_BOOLEAN("Blink.Canvas.IsComposited",
context_->IsComposited());
+ context_->DetachHost();
}
- context_->DetachHost();
context_ = nullptr;
}
@@ -154,10 +154,6 @@ void HTMLCanvasElement::Dispose() {
}
if (surface_layer_bridge_) {
- if (surface_layer_bridge_->GetCcLayer()) {
- GraphicsLayer::UnregisterContentsLayer(
- surface_layer_bridge_->GetCcLayer());
- }
// Observer has to be cleared out at this point. Otherwise the
// SurfaceLayerBridge may call back into the observer which is undefined
// behavior. In the worst case, the dead canvas element re-adds itself into
@@ -301,7 +297,7 @@ CanvasRenderingContext* HTMLCanvasElement::GetCanvasRenderingContextInternal(
// If this context is cross-origin, it should prefer to use the low-power GPU
LocalFrame* frame = GetDocument().GetFrame();
CanvasContextCreationAttributesCore recomputed_attributes = attributes;
- if (frame && frame->IsCrossOriginSubframe())
+ if (frame && frame->IsCrossOriginToMainFrame())
recomputed_attributes.power_preference = "low-power";
context_ = factory->Create(this, recomputed_attributes);
@@ -387,7 +383,12 @@ bool HTMLCanvasElement::IsWebGL2Enabled() const {
bool HTMLCanvasElement::IsWebGLBlocked() const {
Document& document = GetDocument();
LocalFrame* frame = document.GetFrame();
- return frame && frame->Client()->ShouldBlockWebGL();
+ if (!frame)
+ return false;
+
+ bool blocked = false;
+ frame->GetLocalFrameHostRemote().Are3DAPIsBlocked(&blocked);
+ return blocked;
}
void HTMLCanvasElement::DidDraw(const FloatRect& rect) {
@@ -490,13 +491,23 @@ void HTMLCanvasElement::DoDeferredPaintInvalidation() {
return;
}
LayoutBox* layout_box = GetLayoutBox();
+
+ FloatRect content_rect;
+ if (layout_box) {
+ if (layout_box->IsLayoutReplaced()) {
+ content_rect =
+ FloatRect(ToLayoutReplaced(layout_box)->ReplacedContentRect());
+ } else {
+ content_rect = FloatRect(layout_box->PhysicalContentBoxRect());
+ }
+ }
+
if (Is2d()) {
FloatRect src_rect(0, 0, Size().Width(), Size().Height());
dirty_rect_.Intersect(src_rect);
FloatRect invalidation_rect;
if (layout_box) {
- FloatRect content_rect(layout_box->PhysicalContentBoxRect());
FloatRect mapped_dirty_rect =
MapRect(dirty_rect_, src_rect, content_rect);
if (context_->IsComposited()) {
@@ -532,7 +543,6 @@ void HTMLCanvasElement::DoDeferredPaintInvalidation() {
// being stretched, so we need to account for color bleeding caused by the
// interpolation filter.
FloatRect src_rect(0, 0, Size().Width(), Size().Height());
- FloatRect content_rect(layout_box->PhysicalContentBoxRect());
if (content_rect.Width() > src_rect.Width() ||
content_rect.Height() > src_rect.Height()) {
dirty_rect_.Inflate(0.5);
@@ -541,9 +551,6 @@ void HTMLCanvasElement::DoDeferredPaintInvalidation() {
dirty_rect_.Intersect(src_rect);
PhysicalRect mapped_dirty_rect(
EnclosingIntRect(MapRect(dirty_rect_, src_rect, content_rect)));
- // For querying PaintLayer::GetCompositingState()
- // FIXME: is this invalidation using the correct compositing state?
- DisableCompositingQueryAsserts disabler;
layout_box->InvalidatePaintRectangle(mapped_dirty_rect);
}
dirty_rect_ = FloatRect();
@@ -602,7 +609,7 @@ void HTMLCanvasElement::Reset() {
if (layout_object->IsCanvas()) {
if (old_size != Size()) {
ToLayoutHTMLCanvas(layout_object)->CanvasSizeChanged();
- if (GetLayoutBox() && GetLayoutBox()->HasAcceleratedCompositing())
+ if (GetDocument().GetSettings()->GetAcceleratedCompositingEnabled())
GetLayoutBox()->ContentChanged(kCanvasChanged);
}
if (had_resource_provider)
@@ -617,7 +624,8 @@ bool HTMLCanvasElement::PaintsIntoCanvasBuffer() const {
DCHECK(context_);
if (!context_->IsComposited())
return true;
- if (GetLayoutBox() && GetLayoutBox()->HasAcceleratedCompositing())
+ auto* settings = GetDocument().GetSettings();
+ if (settings && settings->GetAcceleratedCompositingEnabled())
return false;
return true;
@@ -640,15 +648,15 @@ void HTMLCanvasElement::NotifyListenersCanvasChanged() {
if (listener_needs_new_frame_capture) {
SourceImageStatus status;
- scoped_refptr<Image> source_image =
- GetSourceImageForCanvas(&status, kPreferNoAcceleration, FloatSize());
+ scoped_refptr<StaticBitmapImage> source_image =
+ GetSourceImageForCanvasInternal(&status, kPreferNoAcceleration);
if (status != kNormalSourceImageStatus)
return;
- sk_sp<SkImage> image =
- source_image->PaintImageForCurrentFrame().GetSkImage();
for (CanvasDrawListener* listener : listeners_) {
- if (listener->NeedsNewFrame())
- listener->SendNewFrame(image, source_image->ContextProviderWrapper());
+ if (listener->NeedsNewFrame()) {
+ listener->SendNewFrame(source_image,
+ source_image->ContextProviderWrapper());
+ }
}
}
}
@@ -747,53 +755,51 @@ void HTMLCanvasElement::PaintInternal(GraphicsContext& context,
const PhysicalRect& r) {
context_->PaintRenderingResultsToCanvas(kFrontBuffer);
if (HasResourceProvider()) {
- if (!context.ContextDisabled()) {
- const ComputedStyle* style = GetComputedStyle();
- // For 2D Canvas, there are two ways of render Canvas for printing:
- // display list or image snapshot. Display list allows better PDF printing
- // and we prefer this method.
- // Here are the requirements for display list to be used:
- // 1. We must have had a full repaint of the Canvas after beginprint
- // event has been fired. Otherwise, we don't have a PaintRecord.
- // 2. CSS property 'image-rendering' must not be 'pixelated'.
-
- // display list rendering: we replay the last full PaintRecord, if Canvas
- // has been redraw since beginprint happened.
- if (IsPrinting() && !Is3d() && canvas2d_bridge_) {
- canvas2d_bridge_->FlushRecording();
- if (canvas2d_bridge_->getLastRecord()) {
- if (style && style->ImageRendering() != EImageRendering::kPixelated) {
- context.Canvas()->save();
- context.Canvas()->translate(r.X(), r.Y());
- context.Canvas()->scale(r.Width() / Size().Width(),
- r.Height() / Size().Height());
- context.Canvas()->drawPicture(canvas2d_bridge_->getLastRecord());
- context.Canvas()->restore();
- UMA_HISTOGRAM_BOOLEAN("Blink.Canvas.2DPrintingAsVector", true);
- return;
- }
+ const ComputedStyle* style = GetComputedStyle();
+ // For 2D Canvas, there are two ways of render Canvas for printing:
+ // display list or image snapshot. Display list allows better PDF printing
+ // and we prefer this method.
+ // Here are the requirements for display list to be used:
+ // 1. We must have had a full repaint of the Canvas after beginprint
+ // event has been fired. Otherwise, we don't have a PaintRecord.
+ // 2. CSS property 'image-rendering' must not be 'pixelated'.
+
+ // display list rendering: we replay the last full PaintRecord, if Canvas
+ // has been redraw since beginprint happened.
+ if (IsPrinting() && !Is3d() && canvas2d_bridge_) {
+ canvas2d_bridge_->FlushRecording();
+ if (canvas2d_bridge_->getLastRecord()) {
+ if (style && style->ImageRendering() != EImageRendering::kPixelated) {
+ context.Canvas()->save();
+ context.Canvas()->translate(r.X(), r.Y());
+ context.Canvas()->scale(r.Width() / Size().Width(),
+ r.Height() / Size().Height());
+ context.Canvas()->drawPicture(canvas2d_bridge_->getLastRecord());
+ context.Canvas()->restore();
+ UMA_HISTOGRAM_BOOLEAN("Blink.Canvas.2DPrintingAsVector", true);
+ return;
}
- UMA_HISTOGRAM_BOOLEAN("Blink.Canvas.2DPrintingAsVector", false);
- }
- // or image snapshot rendering: grab a snapshot and raster it.
- SkBlendMode composite_operator =
- !context_ || context_->CreationAttributes().alpha
- ? SkBlendMode::kSrcOver
- : SkBlendMode::kSrc;
- FloatRect src_rect = FloatRect(FloatPoint(), FloatSize(Size()));
- scoped_refptr<StaticBitmapImage> snapshot =
- canvas2d_bridge_
- ? canvas2d_bridge_->NewImageSnapshot(kPreferAcceleration)
- : (ResourceProvider() ? ResourceProvider()->Snapshot() : nullptr);
- if (snapshot) {
- // GraphicsContext cannot handle gpu resource serialization.
- snapshot = snapshot->MakeUnaccelerated();
- DCHECK(!snapshot->IsTextureBacked());
- context.DrawImage(snapshot.get(), Image::kSyncDecode,
- FloatRect(PixelSnappedIntRect(r)), &src_rect,
- style && style->HasFilterInducingProperty(),
- composite_operator);
}
+ UMA_HISTOGRAM_BOOLEAN("Blink.Canvas.2DPrintingAsVector", false);
+ }
+ // or image snapshot rendering: grab a snapshot and raster it.
+ SkBlendMode composite_operator =
+ !context_ || context_->CreationAttributes().alpha
+ ? SkBlendMode::kSrcOver
+ : SkBlendMode::kSrc;
+ FloatRect src_rect = FloatRect(FloatPoint(), FloatSize(Size()));
+ scoped_refptr<StaticBitmapImage> snapshot =
+ canvas2d_bridge_
+ ? canvas2d_bridge_->NewImageSnapshot(kPreferAcceleration)
+ : (ResourceProvider() ? ResourceProvider()->Snapshot() : nullptr);
+ if (snapshot) {
+ // GraphicsContext cannot handle gpu resource serialization.
+ snapshot = snapshot->MakeUnaccelerated();
+ DCHECK(!snapshot->IsTextureBacked());
+ context.DrawImage(snapshot.get(), Image::kSyncDecode,
+ FloatRect(PixelSnappedIntRect(r)), &src_rect,
+ style && style->HasFilterInducingProperty(),
+ composite_operator);
}
} else {
// When alpha is false, we should draw to opaque black.
@@ -977,7 +983,7 @@ void HTMLCanvasElement::toBlob(V8BlobCallback* callback,
async_creator = MakeGarbageCollected<CanvasAsyncBlobCreator>(
image_bitmap, options,
CanvasAsyncBlobCreator::kHTMLCanvasToBlobCallback, callback, start_time,
- &GetDocument());
+ GetExecutionContext());
}
if (async_creator) {
@@ -1050,7 +1056,8 @@ bool HTMLCanvasElement::ShouldAccelerate(AccelerationCriteria criteria) const {
// The following is necessary for handling the special case of canvases in
// the dev tools overlay, which run in a process that supports accelerated
// 2d canvas but in a special compositing context that does not.
- if (GetLayoutBox() && !GetLayoutBox()->HasAcceleratedCompositing())
+ auto* settings = GetDocument().GetSettings();
+ if (settings && !settings->GetAcceleratedCompositingEnabled())
return false;
// Avoid creating |contextProvider| until we're sure we want to try use it,
@@ -1140,7 +1147,7 @@ void HTMLCanvasElement::NotifyGpuContextLost() {
void HTMLCanvasElement::Trace(Visitor* visitor) {
visitor->Trace(listeners_);
visitor->Trace(context_);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
PageVisibilityObserver::Trace(visitor);
HTMLElement::Trace(visitor);
}
@@ -1184,7 +1191,7 @@ void HTMLCanvasElement::PageVisibilityChanged() {
DiscardResourceProvider();
}
-void HTMLCanvasElement::ContextDestroyed(ExecutionContext*) {
+void HTMLCanvasElement::ContextDestroyed() {
if (context_)
context_->Stop();
}
@@ -1203,14 +1210,13 @@ void HTMLCanvasElement::LayoutObjectDestroyed() {
}
void HTMLCanvasElement::DidMoveToNewDocument(Document& old_document) {
- ContextLifecycleObserver::SetContext(&GetDocument());
- PageVisibilityObserver::SetContext(GetDocument().GetPage());
+ SetExecutionContext(GetExecutionContext());
+ SetPage(GetDocument().GetPage());
HTMLElement::DidMoveToNewDocument(old_document);
}
void HTMLCanvasElement::WillDrawImageTo2DContext(CanvasImageSource* source) {
- if (canvas_heuristic_parameters::kEnableAccelerationToAvoidReadbacks &&
- SharedGpuContext::AllowSoftwareToAcceleratedCanvasUpgrade() &&
+ if (SharedGpuContext::AllowSoftwareToAcceleratedCanvasUpgrade() &&
source->IsAccelerated() && GetOrCreateCanvas2DLayerBridge() &&
!canvas2d_bridge_->IsAccelerated() &&
ShouldAccelerate(kIgnoreResourceLimitCriteria)) {
@@ -1226,6 +1232,12 @@ scoped_refptr<Image> HTMLCanvasElement::GetSourceImageForCanvas(
SourceImageStatus* status,
AccelerationHint hint,
const FloatSize&) {
+ return GetSourceImageForCanvasInternal(status, hint);
+}
+
+scoped_refptr<StaticBitmapImage>
+HTMLCanvasElement::GetSourceImageForCanvasInternal(SourceImageStatus* status,
+ AccelerationHint hint) {
if (!width() || !height()) {
*status = kZeroSizeCanvasSourceImageStatus;
return nullptr;
@@ -1242,21 +1254,21 @@ scoped_refptr<Image> HTMLCanvasElement::GetSourceImageForCanvas(
}
if (!context_) {
- scoped_refptr<Image> result = GetTransparentImage();
+ scoped_refptr<StaticBitmapImage> result = GetTransparentImage();
*status = result ? kNormalSourceImageStatus : kInvalidSourceImageStatus;
return result;
}
if (HasImageBitmapContext()) {
*status = kNormalSourceImageStatus;
- scoped_refptr<Image> result = context_->GetImage(hint);
+ scoped_refptr<StaticBitmapImage> result = context_->GetImage(hint);
if (!result)
result = GetTransparentImage();
*status = result ? kNormalSourceImageStatus : kInvalidSourceImageStatus;
return result;
}
- scoped_refptr<Image> image;
+ scoped_refptr<StaticBitmapImage> image;
// TODO(ccameron): Canvas should produce sRGB images.
// https://crbug.com/672299
if (Is3d()) {
@@ -1285,7 +1297,9 @@ bool HTMLCanvasElement::WouldTaintOrigin() const {
return !OriginClean();
}
-FloatSize HTMLCanvasElement::ElementSize(const FloatSize&) const {
+FloatSize HTMLCanvasElement::ElementSize(
+ const FloatSize&,
+ const RespectImageOrientationEnum) const {
if (context_ && HasImageBitmapContext()) {
scoped_refptr<Image> image = context_->GetImage(kPreferNoAcceleration);
if (image)
@@ -1305,11 +1319,13 @@ ScriptPromise HTMLCanvasElement::CreateImageBitmap(
ScriptState* script_state,
EventTarget& event_target,
base::Optional<IntRect> crop_rect,
- const ImageBitmapOptions* options) {
+ const ImageBitmapOptions* options,
+ ExceptionState& exception_state) {
DCHECK(event_target.ToLocalDOMWindow());
return ImageBitmapSource::FulfillImageBitmap(
- script_state, ImageBitmap::Create(this, crop_rect, options));
+ script_state, MakeGarbageCollected<ImageBitmap>(this, crop_rect, options),
+ exception_state);
}
void HTMLCanvasElement::SetOffscreenCanvasResource(
@@ -1425,12 +1441,10 @@ void HTMLCanvasElement::OnWebLayerUpdated() {
}
void HTMLCanvasElement::RegisterContentsLayer(cc::Layer* layer) {
- GraphicsLayer::RegisterContentsLayer(layer);
OnContentsCcLayerChanged();
}
void HTMLCanvasElement::UnregisterContentsLayer(cc::Layer* layer) {
- GraphicsLayer::UnregisterContentsLayer(layer);
OnContentsCcLayerChanged();
}
@@ -1493,20 +1507,30 @@ void HTMLCanvasElement::ReplaceExisting2dLayerBridge(
if (canvas2d_bridge_) {
image = canvas2d_bridge_->NewImageSnapshot(kPreferNoAcceleration);
// image can be null if allocation failed in which case we should just
- // abort the surface switch to reatain the old surface which is still
+ // abort the surface switch to retain the old surface which is still
// functional.
if (!image)
return;
}
- new_layer_bridge->SetCanvasResourceHost(this);
ReplaceResourceProvider(nullptr);
canvas2d_bridge_ = std::move(new_layer_bridge);
+ canvas2d_bridge_->SetCanvasResourceHost(this);
+
+ 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.
+ canvas->restoreToCount(1);
+ canvas->save();
+
+ // TODO(jochin): Consider using ResourceProvider()->RestoreBackBuffer() here
+ // to avoid all of this clip stack manipulation.
if (image)
canvas2d_bridge_->DrawFullImage(image->PaintImageForCurrentFrame());
- RestoreCanvasMatrixClipStack(canvas2d_bridge_->DrawingCanvas());
- canvas2d_bridge_->DidRestoreCanvasMatrixClipStack(
- canvas2d_bridge_->DrawingCanvas());
+ RestoreCanvasMatrixClipStack(canvas);
+ canvas2d_bridge_->DidRestoreCanvasMatrixClipStack(canvas);
+
UpdateMemoryUsage();
}
@@ -1525,7 +1549,7 @@ bool HTMLCanvasElement::HasImageBitmapContext() const {
return (type == CanvasRenderingContext::kContextImageBitmap);
}
-scoped_refptr<Image> HTMLCanvasElement::GetTransparentImage() {
+scoped_refptr<StaticBitmapImage> HTMLCanvasElement::GetTransparentImage() {
if (!transparent_image_ || transparent_image_.get()->Size() != Size())
transparent_image_ = CreateTransparentImage(Size());
return transparent_image_;
@@ -1547,4 +1571,8 @@ void HTMLCanvasElement::OnContentsCcLayerChanged() {
GetLayoutBoxModelObject()->Layer()->SetNeedsRepaint();
}
+RespectImageOrientationEnum HTMLCanvasElement::RespectImageOrientation() const {
+ return LayoutObject::ShouldRespectImageOrientation(GetLayoutObject());
+}
+
} // namespace blink
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 f1c64559b81..c929303ec30 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
@@ -36,9 +36,8 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_blob_callback.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/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h"
-#include "third_party/blink/renderer/core/html/canvas/image_encode_options.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap_source.h"
#include "third_party/blink/renderer/core/page/page_visibility_observer.h"
@@ -49,8 +48,8 @@
#include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types_3d.h"
-#include "third_party/blink/renderer/platform/graphics/image.h"
#include "third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.h"
+#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/surface_layer_bridge.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -97,7 +96,7 @@ typedef CanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextO
// this class and without overcomplicating context.
class CORE_EXPORT HTMLCanvasElement final
: public HTMLElement,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public PageVisibilityObserver,
public CanvasRenderingContextHost,
public WebSurfaceLayerBridgeObserver,
@@ -193,8 +192,8 @@ class CORE_EXPORT HTMLCanvasElement final
bool PushFrame(scoped_refptr<CanvasResource> image,
const SkIRect& damage_rect) override;
- // ContextLifecycleObserver and PageVisibilityObserver implementation
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver and PageVisibilityObserver implementation
+ void ContextDestroyed() override;
// PageVisibilityObserver implementation
void PageVisibilityChanged() override;
@@ -204,7 +203,8 @@ class CORE_EXPORT HTMLCanvasElement final
AccelerationHint,
const FloatSize&) override;
bool WouldTaintOrigin() const override;
- FloatSize ElementSize(const FloatSize&) const override;
+ FloatSize ElementSize(const FloatSize&,
+ const RespectImageOrientationEnum) const override;
bool IsCanvasElement() const override { return true; }
bool IsOpaque() const override;
bool IsAccelerated() const override;
@@ -234,7 +234,8 @@ class CORE_EXPORT HTMLCanvasElement final
ScriptPromise CreateImageBitmap(ScriptState*,
EventTarget&,
base::Optional<IntRect> crop_rect,
- const ImageBitmapOptions*) override;
+ const ImageBitmapOptions*,
+ ExceptionState&) override;
// OffscreenCanvasPlaceholder implementation.
void SetOffscreenCanvasResource(scoped_refptr<CanvasResource>,
@@ -302,6 +303,11 @@ class CORE_EXPORT HTMLCanvasElement final
// composited.
cc::Layer* ContentsCcLayer() const;
+ // Return the image orientation setting from the layout object, if available.
+ // In the absence of a layout object, kRespectImageOrientation will be
+ // returned.
+ RespectImageOrientationEnum RespectImageOrientation() const;
+
protected:
void DidMoveToNewDocument(Document& old_document) override;
@@ -344,12 +350,16 @@ class CORE_EXPORT HTMLCanvasElement final
bool HasImageBitmapContext() const;
// Returns the transparent image resource for this canvas.
- scoped_refptr<Image> GetTransparentImage();
+ scoped_refptr<StaticBitmapImage> GetTransparentImage();
CanvasRenderingContext* GetCanvasRenderingContextInternal(
const String&,
const CanvasContextCreationAttributesCore&);
+ scoped_refptr<StaticBitmapImage> GetSourceImageForCanvasInternal(
+ SourceImageStatus*,
+ AccelerationHint);
+
void OnContentsCcLayerChanged();
HeapHashSet<WeakMember<CanvasDrawListener>> listeners_;
@@ -391,7 +401,7 @@ class CORE_EXPORT HTMLCanvasElement final
// GPU Memory Management
mutable intptr_t externally_allocated_memory_;
- scoped_refptr<Image> transparent_image_ = nullptr;
+ scoped_refptr<StaticBitmapImage> transparent_image_ = nullptr;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.idl b/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.idl
index 27b54f80beb..d8f04c404a2 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.idl
+++ b/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.idl
@@ -40,7 +40,7 @@
[HighEntropy, MeasureAs=CanvasToBlob, RaisesException] void toBlob(BlobCallback _callback, optional DOMString type = "image/png", optional any quality);
- [HighEntropy, RuntimeEnabled=CanvasColorManagement, MeasureAs=CanvasConvertToBlob, RaisesException, CallWith=ScriptState] Promise<Blob> convertToBlob(optional ImageEncodeOptions options);
+ [HighEntropy, RuntimeEnabled=CanvasColorManagement, MeasureAs=CanvasConvertToBlob, RaisesException, CallWith=ScriptState] Promise<Blob> convertToBlob(optional ImageEncodeOptions options = {});
};
// https://html.spec.whatwg.org/C/#blobcallback
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 50256d97b59..eb28b745ed9 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
@@ -29,10 +29,10 @@
#include "third_party/blink/renderer/core/html/canvas/image_data.h"
#include "base/sys_byteorder.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_uint8_clamped_array.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
-#include "third_party/blink/renderer/core/imagebitmap/image_bitmap_options.h"
#include "third_party/blink/renderer/platform/graphics/color_behavior.h"
#include "third_party/skia/include/third_party/skcms/skcms.h"
#include "v8/include/v8.h"
@@ -56,7 +56,7 @@ bool ImageData::ValidateConstructorArguments(
const IntSize* size,
const unsigned& width,
const unsigned& height,
- const DOMArrayBufferView* data,
+ const NotShared<DOMArrayBufferView> data,
const ImageDataColorSettings* color_settings,
ExceptionState* exception_state) {
// We accept all the combinations of colorSpace and storageFormat in an
@@ -163,23 +163,26 @@ bool ImageData::ValidateConstructorArguments(
return true;
}
-DOMArrayBufferView* ImageData::AllocateAndValidateDataArray(
+NotShared<DOMArrayBufferView> ImageData::AllocateAndValidateDataArray(
const unsigned& length,
ImageDataStorageFormat storage_format,
ExceptionState* exception_state) {
if (!length)
- return nullptr;
+ return NotShared<DOMArrayBufferView>();
- DOMArrayBufferView* data_array = nullptr;
+ NotShared<DOMArrayBufferView> data_array;
switch (storage_format) {
case kUint8ClampedArrayStorageFormat:
- data_array = DOMUint8ClampedArray::CreateOrNull(length);
+ data_array = NotShared<DOMArrayBufferView>(
+ DOMUint8ClampedArray::CreateOrNull(length));
break;
case kUint16ArrayStorageFormat:
- data_array = DOMUint16Array::CreateOrNull(length);
+ data_array =
+ NotShared<DOMArrayBufferView>(DOMUint16Array::CreateOrNull(length));
break;
case kFloat32ArrayStorageFormat:
- data_array = DOMFloat32Array::CreateOrNull(length);
+ data_array =
+ NotShared<DOMArrayBufferView>(DOMFloat32Array::CreateOrNull(length));
break;
default:
NOTREACHED();
@@ -191,62 +194,51 @@ DOMArrayBufferView* ImageData::AllocateAndValidateDataArray(
expected_size != data_array->byteLengthAsSizeT())) {
if (exception_state)
exception_state->ThrowRangeError("Out of memory at ImageData creation");
- return nullptr;
+ return NotShared<DOMArrayBufferView>();
}
return data_array;
}
-DOMUint8ClampedArray* ImageData::AllocateAndValidateUint8ClampedArray(
+NotShared<DOMUint8ClampedArray> ImageData::AllocateAndValidateUint8ClampedArray(
const unsigned& length,
ExceptionState* exception_state) {
- DOMArrayBufferView* buffer_view = AllocateAndValidateDataArray(
+ NotShared<DOMUint8ClampedArray> buffer_view;
+ buffer_view = AllocateAndValidateDataArray(
length, kUint8ClampedArrayStorageFormat, exception_state);
- if (!buffer_view)
- return nullptr;
- DOMUint8ClampedArray* u8_array = const_cast<DOMUint8ClampedArray*>(
- static_cast<const DOMUint8ClampedArray*>(buffer_view));
- DCHECK(u8_array);
- return u8_array;
+ return buffer_view;
}
-DOMUint16Array* ImageData::AllocateAndValidateUint16Array(
+NotShared<DOMUint16Array> ImageData::AllocateAndValidateUint16Array(
const unsigned& length,
ExceptionState* exception_state) {
- DOMArrayBufferView* buffer_view = AllocateAndValidateDataArray(
- length, kUint16ArrayStorageFormat, exception_state);
- if (!buffer_view)
- return nullptr;
- DOMUint16Array* u16_array = const_cast<DOMUint16Array*>(
- static_cast<const DOMUint16Array*>(buffer_view));
- DCHECK(u16_array);
- return u16_array;
+ NotShared<DOMUint16Array> buffer_view;
+ buffer_view = AllocateAndValidateDataArray(length, kUint16ArrayStorageFormat,
+ exception_state);
+ return buffer_view;
}
-DOMFloat32Array* ImageData::AllocateAndValidateFloat32Array(
+NotShared<DOMFloat32Array> ImageData::AllocateAndValidateFloat32Array(
const unsigned& length,
ExceptionState* exception_state) {
- DOMArrayBufferView* buffer_view = AllocateAndValidateDataArray(
- length, kFloat32ArrayStorageFormat, exception_state);
- if (!buffer_view)
- return nullptr;
- DOMFloat32Array* f32_array = const_cast<DOMFloat32Array*>(
- static_cast<const DOMFloat32Array*>(buffer_view));
- DCHECK(f32_array);
- return f32_array;
+ NotShared<DOMFloat32Array> buffer_view;
+ buffer_view = AllocateAndValidateDataArray(length, kFloat32ArrayStorageFormat,
+ exception_state);
+ return buffer_view;
}
ImageData* ImageData::Create(const IntSize& size,
const ImageDataColorSettings* color_settings) {
- if (!ImageData::ValidateConstructorArguments(kParamSize, &size, 0, 0, nullptr,
- color_settings))
+ if (!ValidateConstructorArguments(kParamSize, &size, 0, 0,
+ NotShared<DOMArrayBufferView>(),
+ color_settings))
return nullptr;
ImageDataStorageFormat storage_format = kUint8ClampedArrayStorageFormat;
if (color_settings) {
storage_format =
ImageData::GetImageDataStorageFormat(color_settings->storageFormat());
}
- DOMArrayBufferView* data_array =
+ NotShared<DOMArrayBufferView> data_array =
AllocateAndValidateDataArray(4 * static_cast<unsigned>(size.Width()) *
static_cast<unsigned>(size.Height()),
storage_format);
@@ -322,12 +314,10 @@ ImageData* ImageData::Create(const IntSize& size,
ImageData* ImageData::Create(const IntSize& size,
NotShared<DOMArrayBufferView> data_array,
const ImageDataColorSettings* color_settings) {
- if (!ImageData::ValidateConstructorArguments(kParamSize | kParamData, &size,
- 0, 0, data_array.View(),
- color_settings))
+ if (!ImageData::ValidateConstructorArguments(
+ kParamSize | kParamData, &size, 0, 0, data_array, color_settings))
return nullptr;
- return MakeGarbageCollected<ImageData>(size, data_array.View(),
- color_settings);
+ return MakeGarbageCollected<ImageData>(size, data_array, color_settings);
}
static SkImageInfo GetImageInfo(scoped_refptr<StaticBitmapImage> image) {
@@ -373,7 +363,7 @@ ImageData* ImageData::Create(scoped_refptr<StaticBitmapImage> image,
if (!area.IsValid())
return nullptr;
// Create image data with f32 storage
- DOMFloat32Array* f32_array =
+ NotShared<DOMFloat32Array> f32_array =
ImageData::AllocateAndValidateFloat32Array(area.ValueOrDie(), nullptr);
if (!f32_array)
return nullptr;
@@ -382,20 +372,20 @@ ImageData* ImageData::Create(scoped_refptr<StaticBitmapImage> image,
image_info.minRowBytes(), 0, 0);
ImageDataColorSettings* color_settings =
CanvasColorParamsToImageDataColorSettings(color_params);
- return Create(image->Size(), NotShared<blink::DOMArrayBufferView>(f32_array),
- color_settings);
+ return Create(image->Size(), f32_array, color_settings);
}
ImageData* ImageData::Create(unsigned width,
unsigned height,
ExceptionState& exception_state) {
- if (!ImageData::ValidateConstructorArguments(kParamWidth | kParamHeight,
- nullptr, width, height, nullptr,
- nullptr, &exception_state))
+ if (!ImageData::ValidateConstructorArguments(
+ kParamWidth | kParamHeight, nullptr, width, height,
+ NotShared<DOMArrayBufferView>(), nullptr, &exception_state))
return nullptr;
- DOMArrayBufferView* byte_array = AllocateAndValidateDataArray(
- 4 * width * height, kUint8ClampedArrayStorageFormat, &exception_state);
+ NotShared<DOMUint8ClampedArray> byte_array =
+ AllocateAndValidateUint8ClampedArray(4 * width * height,
+ &exception_state);
return byte_array ? MakeGarbageCollected<ImageData>(IntSize(width, height),
byte_array)
: nullptr;
@@ -405,13 +395,13 @@ ImageData* ImageData::Create(NotShared<DOMUint8ClampedArray> data,
unsigned width,
ExceptionState& exception_state) {
if (!ImageData::ValidateConstructorArguments(kParamData | kParamWidth,
- nullptr, width, 0, data.View(),
- nullptr, &exception_state))
+ nullptr, width, 0, data, nullptr,
+ &exception_state))
return nullptr;
unsigned height =
- base::checked_cast<unsigned>(data.View()->lengthAsSizeT()) / (width * 4);
- return MakeGarbageCollected<ImageData>(IntSize(width, height), data.View());
+ base::checked_cast<unsigned>(data->lengthAsSizeT()) / (width * 4);
+ return MakeGarbageCollected<ImageData>(IntSize(width, height), data);
}
ImageData* ImageData::Create(NotShared<DOMUint8ClampedArray> data,
@@ -419,11 +409,11 @@ ImageData* ImageData::Create(NotShared<DOMUint8ClampedArray> data,
unsigned height,
ExceptionState& exception_state) {
if (!ImageData::ValidateConstructorArguments(
- kParamData | kParamWidth | kParamHeight, nullptr, width, height,
- data.View(), nullptr, &exception_state))
+ kParamData | kParamWidth | kParamHeight, nullptr, width, height, data,
+ nullptr, &exception_state))
return nullptr;
- return MakeGarbageCollected<ImageData>(IntSize(width, height), data.View());
+ return MakeGarbageCollected<ImageData>(IntSize(width, height), data);
}
ImageData* ImageData::CreateImageData(
@@ -432,13 +422,13 @@ ImageData* ImageData::CreateImageData(
const ImageDataColorSettings* color_settings,
ExceptionState& exception_state) {
if (!ImageData::ValidateConstructorArguments(
- kParamWidth | kParamHeight, nullptr, width, height, nullptr,
- color_settings, &exception_state))
+ kParamWidth | kParamHeight, nullptr, width, height,
+ NotShared<DOMArrayBufferView>(), color_settings, &exception_state))
return nullptr;
ImageDataStorageFormat storage_format =
ImageData::GetImageDataStorageFormat(color_settings->storageFormat());
- DOMArrayBufferView* buffer_view = AllocateAndValidateDataArray(
+ NotShared<DOMArrayBufferView> buffer_view = AllocateAndValidateDataArray(
4 * width * height, storage_format, &exception_state);
if (!buffer_view)
@@ -453,7 +443,7 @@ ImageData* ImageData::CreateImageData(ImageDataArray& data,
unsigned height,
ImageDataColorSettings* color_settings,
ExceptionState& exception_state) {
- DOMArrayBufferView* buffer_view = nullptr;
+ NotShared<DOMArrayBufferView> buffer_view;
// When pixels data is provided, we need to override the storage format of
// ImageDataColorSettings with the one that matches the data type of the
@@ -461,13 +451,13 @@ ImageData* ImageData::CreateImageData(ImageDataArray& data,
String storage_format_name;
if (data.IsUint8ClampedArray()) {
- buffer_view = data.GetAsUint8ClampedArray().View();
+ buffer_view = data.GetAsUint8ClampedArray();
storage_format_name = kUint8ClampedArrayStorageFormatName;
} else if (data.IsUint16Array()) {
- buffer_view = data.GetAsUint16Array().View();
+ buffer_view = data.GetAsUint16Array();
storage_format_name = kUint16ArrayStorageFormatName;
} else if (data.IsFloat32Array()) {
- buffer_view = data.GetAsFloat32Array().View();
+ buffer_view = data.GetAsFloat32Array();
storage_format_name = kFloat32ArrayStorageFormatName;
} else {
NOTREACHED();
@@ -495,8 +485,8 @@ ImageData* ImageData::CreateForTest(const IntSize& size) {
data_size.ValueOrDie() > v8::TypedArray::kMaxLength)
return nullptr;
- DOMUint8ClampedArray* byte_array =
- DOMUint8ClampedArray::CreateOrNull(data_size.ValueOrDie());
+ NotShared<DOMUint8ClampedArray> byte_array(
+ DOMUint8ClampedArray::CreateOrNull(data_size.ValueOrDie()));
if (!byte_array)
return nullptr;
@@ -507,7 +497,7 @@ ImageData* ImageData::CreateForTest(const IntSize& size) {
// to be validated on the call site.
ImageData* ImageData::CreateForTest(
const IntSize& size,
- DOMArrayBufferView* buffer_view,
+ NotShared<DOMArrayBufferView> buffer_view,
const ImageDataColorSettings* color_settings) {
return MakeGarbageCollected<ImageData>(size, buffer_view, color_settings);
}
@@ -527,7 +517,7 @@ ImageData* ImageData::CropRect(const IntRect& crop_rect, bool flip_y) {
return nullptr;
unsigned data_size = 4 * dst_rect.Width() * dst_rect.Height();
- DOMArrayBufferView* buffer_view = AllocateAndValidateDataArray(
+ NotShared<DOMArrayBufferView> buffer_view = AllocateAndValidateDataArray(
data_size,
ImageData::GetImageDataStorageFormat(color_settings_->storageFormat()));
if (!buffer_view)
@@ -562,15 +552,16 @@ ImageData* ImageData::CropRect(const IntRect& crop_rect, bool flip_y) {
ScriptPromise ImageData::CreateImageBitmap(ScriptState* script_state,
EventTarget& event_target,
base::Optional<IntRect> crop_rect,
- const ImageBitmapOptions* options) {
+ const ImageBitmapOptions* options,
+ ExceptionState& exception_state) {
if (BufferBase()->IsDetached()) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "The source data has been detached."));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "The source data has been detached.");
+ return ScriptPromise();
}
return ImageBitmapSource::FulfillImageBitmap(
- script_state, ImageBitmap::Create(this, crop_rect, options));
+ script_state, MakeGarbageCollected<ImageBitmap>(this, crop_rect, options),
+ exception_state);
}
v8::Local<v8::Object> ImageData::AssociateWithWrapper(
@@ -685,19 +676,19 @@ unsigned ImageData::StorageFormatDataSize(
return 1;
}
-DOMArrayBufferView*
+NotShared<DOMArrayBufferView>
ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat(
ArrayBufferContents& content,
CanvasPixelFormat pixel_format,
ImageDataStorageFormat storage_format) {
if (!content.DataLength())
- return nullptr;
+ return NotShared<DOMArrayBufferView>();
- if (pixel_format == CanvasPixelFormat::kRGBA8 &&
+ if (pixel_format == CanvasColorParams::GetNativeCanvasPixelFormat() &&
storage_format == kUint8ClampedArrayStorageFormat) {
DOMArrayBuffer* array_buffer = DOMArrayBuffer::Create(content);
- return DOMUint8ClampedArray::Create(array_buffer, 0,
- array_buffer->ByteLengthAsSizeT());
+ return NotShared<DOMArrayBufferView>(DOMUint8ClampedArray::Create(
+ array_buffer, 0, array_buffer->ByteLengthAsSizeT()));
}
skcms_PixelFormat src_format = skcms_PixelFormat_RGBA_8888;
@@ -709,10 +700,10 @@ ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat(
skcms_AlphaFormat alpha_format = skcms_AlphaFormat_Unpremul;
if (storage_format == kUint8ClampedArrayStorageFormat) {
- DOMUint8ClampedArray* u8_array =
+ NotShared<DOMUint8ClampedArray> u8_array =
AllocateAndValidateUint8ClampedArray(num_pixels * 4);
if (!u8_array)
- return nullptr;
+ return NotShared<DOMArrayBufferView>();
bool data_transform_successful = skcms_Transform(
content.Data(), src_format, alpha_format, nullptr, u8_array->Data(),
skcms_PixelFormat_RGBA_8888, alpha_format, nullptr, num_pixels);
@@ -721,9 +712,10 @@ ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat(
}
if (storage_format == kUint16ArrayStorageFormat) {
- DOMUint16Array* u16_array = AllocateAndValidateUint16Array(num_pixels * 4);
+ NotShared<DOMUint16Array> u16_array =
+ AllocateAndValidateUint16Array(num_pixels * 4);
if (!u16_array)
- return nullptr;
+ return NotShared<DOMArrayBufferView>();
bool data_transform_successful = skcms_Transform(
content.Data(), src_format, alpha_format, nullptr, u16_array->Data(),
skcms_PixelFormat_RGBA_16161616LE, alpha_format, nullptr, num_pixels);
@@ -731,9 +723,10 @@ ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat(
return u16_array;
}
- DOMFloat32Array* f32_array = AllocateAndValidateFloat32Array(num_pixels * 4);
+ NotShared<DOMFloat32Array> f32_array =
+ AllocateAndValidateFloat32Array(num_pixels * 4);
if (!f32_array)
- return nullptr;
+ return NotShared<DOMArrayBufferView>();
bool data_transform_successful = skcms_Transform(
content.Data(), src_format, alpha_format, nullptr, f32_array->Data(),
skcms_PixelFormat_RGBA_ffff, alpha_format, nullptr, num_pixels);
@@ -756,11 +749,12 @@ CanvasColorParams ImageData::GetCanvasColorParams() {
return CanvasColorParams();
CanvasColorSpace color_space =
ImageData::GetCanvasColorSpace(color_settings_->colorSpace());
- CanvasPixelFormat pixel_format = CanvasPixelFormat::kRGBA8;
- if (color_settings_->storageFormat() != kUint8ClampedArrayStorageFormatName)
- pixel_format = CanvasPixelFormat::kF16;
- return CanvasColorParams(color_space, pixel_format, kNonOpaque,
- CanvasForceRGBA::kNotForced);
+ return CanvasColorParams(
+ color_space,
+ color_settings_->storageFormat() != kUint8ClampedArrayStorageFormatName
+ ? CanvasPixelFormat::kF16
+ : CanvasColorParams::GetNativeCanvasPixelFormat(),
+ kNonOpaque);
}
bool ImageData::ImageDataInCanvasColorSettings(
@@ -774,8 +768,7 @@ bool ImageData::ImageDataInCanvasColorSettings(
return false;
CanvasColorParams canvas_color_params =
- CanvasColorParams(canvas_color_space, canvas_pixel_format, kNonOpaque,
- CanvasForceRGBA::kNotForced);
+ CanvasColorParams(canvas_color_space, canvas_pixel_format, kNonOpaque);
unsigned char* src_data = static_cast<unsigned char*>(BufferBase()->Data());
@@ -788,13 +781,16 @@ bool ImageData::ImageDataInCanvasColorSettings(
src_pixel_format = skcms_PixelFormat_RGBA_ffff;
skcms_PixelFormat dst_pixel_format = skcms_PixelFormat_RGBA_8888;
- if (canvas_pixel_format == CanvasPixelFormat::kRGBA8 &&
- u8_color_type == kN32ColorType &&
- kN32_SkColorType == kBGRA_8888_SkColorType) {
- dst_pixel_format = skcms_PixelFormat_BGRA_8888;
- } else if (canvas_pixel_format == CanvasPixelFormat::kF16) {
+ if (canvas_pixel_format == CanvasPixelFormat::kF16) {
dst_pixel_format = skcms_PixelFormat_RGBA_hhhh;
}
+#if SK_PMCOLOR_BYTE_ORDER(B, G, R, A)
+ else if (canvas_pixel_format ==
+ CanvasColorParams::GetNativeCanvasPixelFormat() &&
+ u8_color_type == kN32ColorType) {
+ dst_pixel_format = skcms_PixelFormat_BGRA_8888;
+ }
+#endif
skcms_AlphaFormat src_alpha_format = skcms_AlphaFormat_Unpremul;
skcms_AlphaFormat dst_alpha_format = skcms_AlphaFormat_Unpremul;
@@ -863,16 +859,16 @@ void ImageData::Trace(Visitor* visitor) {
}
ImageData::ImageData(const IntSize& size,
- DOMArrayBufferView* data,
+ NotShared<DOMArrayBufferView> data,
const ImageDataColorSettings* color_settings)
: size_(size), color_settings_(ImageDataColorSettings::Create()) {
DCHECK_GE(size.Width(), 0);
DCHECK_GE(size.Height(), 0);
DCHECK(data);
- data_ = nullptr;
- data_u16_ = nullptr;
- data_f32_ = nullptr;
+ data_.Clear();
+ data_u16_.Clear();
+ data_f32_.Clear();
if (color_settings) {
color_settings_->setColorSpace(color_settings->colorSpace());
@@ -891,8 +887,7 @@ ImageData::ImageData(const IntSize& size,
case kUint8ClampedArrayStorageFormat:
DCHECK(data->GetType() ==
DOMArrayBufferView::ViewType::kTypeUint8Clamped);
- data_ = const_cast<DOMUint8ClampedArray*>(
- static_cast<const DOMUint8ClampedArray*>(data));
+ data_ = data;
DCHECK(data_);
data_union_.SetUint8ClampedArray(data_);
SECURITY_CHECK(
@@ -902,8 +897,7 @@ ImageData::ImageData(const IntSize& size,
case kUint16ArrayStorageFormat:
DCHECK(data->GetType() == DOMArrayBufferView::ViewType::kTypeUint16);
- data_u16_ =
- const_cast<DOMUint16Array*>(static_cast<const DOMUint16Array*>(data));
+ data_u16_ = data;
DCHECK(data_u16_);
data_union_.SetUint16Array(data_u16_);
SECURITY_CHECK(
@@ -913,8 +907,7 @@ ImageData::ImageData(const IntSize& size,
case kFloat32ArrayStorageFormat:
DCHECK(data->GetType() == DOMArrayBufferView::ViewType::kTypeFloat32);
- data_f32_ = const_cast<DOMFloat32Array*>(
- static_cast<const DOMFloat32Array*>(data));
+ data_f32_ = data;
DCHECK(data_f32_);
data_union_.SetFloat32Array(data_f32_);
SECURITY_CHECK(
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 6bcc61fef27..6690cd30bb7 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
@@ -31,9 +31,9 @@
#include "base/numerics/checked_math.h"
#include "third_party/blink/renderer/bindings/core/v8/uint8_clamped_array_or_uint16_array_or_float32_array.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_image_data_color_settings.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h"
-#include "third_party/blink/renderer/core/html/canvas/image_data_color_settings.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap_source.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"
@@ -104,11 +104,11 @@ class CORE_EXPORT ImageData final : public ScriptWrappable,
static ImageData* CreateForTest(const IntSize&);
static ImageData* CreateForTest(const IntSize&,
- DOMArrayBufferView*,
+ NotShared<DOMArrayBufferView>,
const ImageDataColorSettings* = nullptr);
ImageData(const IntSize&,
- DOMArrayBufferView*,
+ NotShared<DOMArrayBufferView>,
const ImageDataColorSettings* = nullptr);
ImageData* CropRect(const IntRect&, bool flip_y = false);
@@ -119,7 +119,7 @@ class CORE_EXPORT ImageData final : public ScriptWrappable,
static ImageDataStorageFormat GetImageDataStorageFormat(const String&);
static unsigned StorageFormatDataSize(const String&);
static unsigned StorageFormatDataSize(ImageDataStorageFormat);
- static DOMArrayBufferView*
+ static NotShared<DOMArrayBufferView>
ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat(
ArrayBufferContents&,
CanvasPixelFormat,
@@ -156,7 +156,8 @@ class CORE_EXPORT ImageData final : public ScriptWrappable,
ScriptPromise CreateImageBitmap(ScriptState*,
EventTarget&,
base::Optional<IntRect> crop_rect,
- const ImageBitmapOptions*) override;
+ const ImageBitmapOptions*,
+ ExceptionState&) override;
void Trace(Visitor*) override;
@@ -170,7 +171,7 @@ class CORE_EXPORT ImageData final : public ScriptWrappable,
const IntSize* = nullptr,
const unsigned& = 0,
const unsigned& = 0,
- const DOMArrayBufferView* = nullptr,
+ const NotShared<DOMArrayBufferView> = NotShared<DOMArrayBufferView>(),
const ImageDataColorSettings* = nullptr,
ExceptionState* = nullptr);
@@ -178,24 +179,24 @@ class CORE_EXPORT ImageData final : public ScriptWrappable,
IntSize size_;
Member<ImageDataColorSettings> color_settings_;
ImageDataArray data_union_;
- Member<DOMUint8ClampedArray> data_;
- Member<DOMUint16Array> data_u16_;
- Member<DOMFloat32Array> data_f32_;
+ NotShared<DOMUint8ClampedArray> data_;
+ NotShared<DOMUint16Array> data_u16_;
+ NotShared<DOMFloat32Array> data_f32_;
- static DOMArrayBufferView* AllocateAndValidateDataArray(
+ static NotShared<DOMArrayBufferView> AllocateAndValidateDataArray(
const unsigned&,
ImageDataStorageFormat,
ExceptionState* = nullptr);
- static DOMUint8ClampedArray* AllocateAndValidateUint8ClampedArray(
+ static NotShared<DOMUint8ClampedArray> AllocateAndValidateUint8ClampedArray(
const unsigned&,
ExceptionState* = nullptr);
- static DOMUint16Array* AllocateAndValidateUint16Array(
+ static NotShared<DOMUint16Array> AllocateAndValidateUint16Array(
const unsigned&,
ExceptionState* = nullptr);
- static DOMFloat32Array* AllocateAndValidateFloat32Array(
+ static NotShared<DOMFloat32Array> AllocateAndValidateFloat32Array(
const unsigned&,
ExceptionState* = nullptr);
};
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_data.idl b/chromium/third_party/blink/renderer/core/html/canvas/image_data.idl
index 45eace16cc1..11907ae1ff1 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/image_data.idl
+++ b/chromium/third_party/blink/renderer/core/html/canvas/image_data.idl
@@ -32,12 +32,11 @@
typedef (Uint8ClampedArray or Uint16Array or Float32Array) ImageDataArray;
[
- Constructor(unsigned long sw, unsigned long sh),
- Constructor(Uint8ClampedArray data, unsigned long sw, optional unsigned long sh),
Exposed=(Window,Worker),
- RaisesException=Constructor,
Serializable
] interface ImageData {
+ [RaisesException] constructor(unsigned long sw, unsigned long sh);
+ [RaisesException] constructor(Uint8ClampedArray data, unsigned long sw, optional unsigned long sh);
[RuntimeEnabled=CanvasColorManagement] ImageDataColorSettings getColorSettings();
readonly attribute unsigned long width;
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 22d583835bd..15db4684f74 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
@@ -75,16 +75,16 @@ TEST_F(ImageDataTest,
// Testing CanvasPixelFormat::kRGBA8->
// kUint8ClampedArrayStorageFormat
- DOMArrayBufferView* data =
+ NotShared<DOMArrayBufferView> data(
ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat(
contents_rgba32, CanvasPixelFormat::kRGBA8,
- kUint8ClampedArrayStorageFormat);
+ kUint8ClampedArrayStorageFormat));
DCHECK(data->GetType() == DOMArrayBufferView::ViewType::kTypeUint8Clamped);
ColorCorrectionTestUtils::CompareColorCorrectedPixels(
data->BaseAddress(), rgba32_pixels, kNumPixels, kPixelFormat_8888,
kAlphaUnmultiplied, kNoUnpremulRoundTripTolerance);
- // Testing CanvasPixelFormat::kRGBA8prN32->
+ // Testing CanvasPixelFormat::kRGBA8->
// kUint16ArrayStorageFormat
data = ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat(
contents_rgba32_2, CanvasPixelFormat::kRGBA8, kUint16ArrayStorageFormat);
@@ -92,8 +92,7 @@ TEST_F(ImageDataTest,
ColorCorrectionTestUtils::CompareColorCorrectedPixels(
data->BaseAddress(), u16_pixels, kNumPixels, kPixelFormat_16161616,
kAlphaUnmultiplied, kUnpremulRoundTripTolerance);
-
- // Testing CanvasPixelFormat::kRGBA8prN32 ->
+ // Testing CanvasPixelFormat::kRGBA8 ->
// kFloat32ArrayStorageFormat
data = ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat(
contents_rgba32_2, CanvasPixelFormat::kRGBA8, kFloat32ArrayStorageFormat);
@@ -172,28 +171,28 @@ TEST_F(ImageDataTest, TestGetImageDataInCanvasColorSettings) {
0, 0, 0, 0, // Transparent
255, 192, 128, 64, // Decreasing values
93, 117, 205, 11}; // Random values
- unsigned data_length = 16;
+ size_t data_length = 16;
uint16_t* u16_pixels = new uint16_t[data_length];
- for (unsigned i = 0; i < data_length; i++)
+ for (size_t i = 0; i < data_length; i++)
u16_pixels[i] = u8_pixels[i] * 257;
float* f32_pixels = new float[data_length];
- for (unsigned i = 0; i < data_length; i++)
+ for (size_t i = 0; i < data_length; i++)
f32_pixels[i] = u8_pixels[i] / 255.0;
- DOMArrayBufferView* data_array = nullptr;
-
- DOMUint8ClampedArray* data_u8 =
- DOMUint8ClampedArray::Create(u8_pixels, data_length);
+ NotShared<DOMUint8ClampedArray> data_u8(
+ DOMUint8ClampedArray::Create(u8_pixels, data_length));
DCHECK(data_u8);
- EXPECT_EQ(data_length, data_u8->deprecatedLengthAsUnsigned());
- DOMUint16Array* data_u16 = DOMUint16Array::Create(u16_pixels, data_length);
+ EXPECT_EQ(data_length, data_u8->lengthAsSizeT());
+ NotShared<DOMUint16Array> data_u16(
+ DOMUint16Array::Create(u16_pixels, data_length));
DCHECK(data_u16);
- EXPECT_EQ(data_length, data_u16->deprecatedLengthAsUnsigned());
- DOMFloat32Array* data_f32 = DOMFloat32Array::Create(f32_pixels, data_length);
+ EXPECT_EQ(data_length, data_u16->lengthAsSizeT());
+ NotShared<DOMFloat32Array> data_f32(
+ DOMFloat32Array::Create(f32_pixels, data_length));
DCHECK(data_f32);
- EXPECT_EQ(data_length, data_f32->deprecatedLengthAsUnsigned());
+ EXPECT_EQ(data_length, data_f32->lengthAsSizeT());
ImageData* image_data = nullptr;
ImageDataColorSettings* color_settings = ImageDataColorSettings::Create();
@@ -211,17 +210,18 @@ TEST_F(ImageDataTest, TestGetImageDataInCanvasColorSettings) {
ImageData::CanvasColorSpaceName(image_data_color_spaces[i]));
for (unsigned j = 0; j < num_image_data_storage_formats; j++) {
+ NotShared<DOMArrayBufferView> data_array;
switch (image_data_storage_formats[j]) {
case kUint8ClampedArrayStorageFormat:
- data_array = static_cast<DOMArrayBufferView*>(data_u8);
+ data_array = data_u8;
color_settings->setStorageFormat(kUint8ClampedArrayStorageFormatName);
break;
case kUint16ArrayStorageFormat:
- data_array = static_cast<DOMArrayBufferView*>(data_u16);
+ data_array = data_u16;
color_settings->setStorageFormat(kUint16ArrayStorageFormatName);
break;
case kFloat32ArrayStorageFormat:
- data_array = static_cast<DOMArrayBufferView*>(data_f32);
+ data_array = data_f32;
color_settings->setStorageFormat(kFloat32ArrayStorageFormatName);
break;
default:
@@ -395,7 +395,7 @@ TEST_F(ImageDataTest, TestCropRect) {
// Source pixels
unsigned width = 20;
unsigned height = 20;
- unsigned data_length = width * height * 4;
+ size_t data_length = width * height * 4;
uint8_t* u8_pixels = new uint8_t[data_length];
uint16_t* u16_pixels = new uint16_t[data_length];
float* f32_pixels = new float[data_length];
@@ -427,30 +427,32 @@ TEST_F(ImageDataTest, TestCropRect) {
}
// Create ImageData objects
- DOMArrayBufferView* data_array = nullptr;
- DOMUint8ClampedArray* data_u8 =
- DOMUint8ClampedArray::Create(u8_pixels, data_length);
+ NotShared<DOMUint8ClampedArray> data_u8(
+ DOMUint8ClampedArray::Create(u8_pixels, data_length));
DCHECK(data_u8);
- EXPECT_EQ(data_length, data_u8->deprecatedLengthAsUnsigned());
- DOMUint16Array* data_u16 = DOMUint16Array::Create(u16_pixels, data_length);
+ EXPECT_EQ(data_length, data_u8->lengthAsSizeT());
+ NotShared<DOMUint16Array> data_u16(
+ DOMUint16Array::Create(u16_pixels, data_length));
DCHECK(data_u16);
- EXPECT_EQ(data_length, data_u16->deprecatedLengthAsUnsigned());
- DOMFloat32Array* data_f32 = DOMFloat32Array::Create(f32_pixels, data_length);
+ EXPECT_EQ(data_length, data_u16->lengthAsSizeT());
+ NotShared<DOMFloat32Array> data_f32(
+ DOMFloat32Array::Create(f32_pixels, data_length));
DCHECK(data_f32);
- EXPECT_EQ(data_length, data_f32->deprecatedLengthAsUnsigned());
+ EXPECT_EQ(data_length, data_f32->lengthAsSizeT());
ImageData* image_data = nullptr;
ImageData* cropped_image_data = nullptr;
bool test_passed = true;
for (int i = 0; i < num_image_data_storage_formats; i++) {
+ NotShared<DOMArrayBufferView> data_array;
if (image_data_storage_formats[i] == kUint8ClampedArrayStorageFormat)
- data_array = static_cast<DOMArrayBufferView*>(data_u8);
+ data_array = data_u8;
else if (image_data_storage_formats[i] == kUint16ArrayStorageFormat)
- data_array = static_cast<DOMArrayBufferView*>(data_u16);
+ data_array = data_u16;
else
- data_array = static_cast<DOMArrayBufferView*>(data_f32);
+ data_array = data_f32;
ImageDataColorSettings* color_settings = ImageDataColorSettings::Create();
color_settings->setStorageFormat(image_data_storage_format_names[i]);
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 15abb2f3633..86980200a42 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
@@ -38,11 +38,11 @@ const Element& ImageElementBase::GetElement() const {
}
bool ImageElementBase::IsSVGSource() const {
- return CachedImage() && CachedImage()->GetImage()->IsSVGImage();
+ return CachedImage() && IsA<SVGImage>(CachedImage()->GetImage());
}
bool ImageElementBase::IsImageElement() const {
- return CachedImage() && !CachedImage()->GetImage()->IsSVGImage();
+ return CachedImage() && !IsA<SVGImage>(CachedImage()->GetImage());
}
scoped_refptr<Image> ImageElementBase::GetSourceImageForCanvas(
@@ -61,9 +61,8 @@ scoped_refptr<Image> ImageElementBase::GetSourceImageForCanvas(
}
scoped_refptr<Image> source_image = image_content->GetImage();
- if (source_image->IsSVGImage()) {
+ if (auto* svg_image = DynamicTo<SVGImage>(source_image.get())) {
UseCounter::Count(GetElement().GetDocument(), WebFeature::kSVGInCanvas2D);
- SVGImage* svg_image = ToSVGImage(source_image.get());
FloatSize image_size = svg_image->ConcreteObjectSize(default_object_size);
source_image = SVGImageForContainer::Create(
svg_image, image_size, 1,
@@ -79,33 +78,21 @@ bool ImageElementBase::WouldTaintOrigin() const {
}
FloatSize ImageElementBase::ElementSize(
- const FloatSize& default_object_size) const {
+ const FloatSize& default_object_size,
+ const RespectImageOrientationEnum respect_orientation) const {
ImageResourceContent* image_content = CachedImage();
- if (!image_content)
+ if (!image_content || !image_content->HasImage())
return FloatSize();
-
Image* image = image_content->GetImage();
- if (image->IsSVGImage())
- return ToSVGImage(image)->ConcreteObjectSize(default_object_size);
-
- return FloatSize(
- image_content->IntrinsicSize(LayoutObject::ShouldRespectImageOrientation(
- GetElement().GetLayoutObject())));
+ if (auto* svg_image = DynamicTo<SVGImage>(image))
+ return svg_image->ConcreteObjectSize(default_object_size);
+ return FloatSize(image->Size(respect_orientation));
}
FloatSize ImageElementBase::DefaultDestinationSize(
- const FloatSize& default_object_size) const {
- ImageResourceContent* image_content = CachedImage();
- if (!image_content)
- return FloatSize();
-
- Image* image = image_content->GetImage();
- if (image->IsSVGImage())
- return ToSVGImage(image)->ConcreteObjectSize(default_object_size);
-
- return FloatSize(
- image_content->IntrinsicSize(LayoutObject::ShouldRespectImageOrientation(
- GetElement().GetLayoutObject())));
+ const FloatSize& default_object_size,
+ const RespectImageOrientationEnum respect_orientation) const {
+ return ElementSize(default_object_size, respect_orientation);
}
bool ImageElementBase::IsAccelerated() const {
@@ -128,46 +115,49 @@ IntSize ImageElementBase::BitmapSourceSize() const {
ImageResourceContent* image = CachedImage();
if (!image)
return IntSize();
- return image->IntrinsicSize(LayoutObject::ShouldRespectImageOrientation(
- GetElement().GetLayoutObject()));
+ // This method is called by ImageBitmap when creating and cropping the image.
+ // Return un-oriented size because the cropping must happen before
+ // orienting.
+ return image->IntrinsicSize(kDoNotRespectImageOrientation);
}
ScriptPromise ImageElementBase::CreateImageBitmap(
ScriptState* script_state,
EventTarget& event_target,
base::Optional<IntRect> crop_rect,
- const ImageBitmapOptions* options) {
+ const ImageBitmapOptions* options,
+ ExceptionState& exception_state) {
DCHECK(event_target.ToLocalDOMWindow());
ImageResourceContent* image_content = CachedImage();
if (!image_content) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "No image can be retrieved from the provided element."));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "No image can be retrieved from the provided element.");
+ return ScriptPromise();
}
Image* image = image_content->GetImage();
- if (image->IsSVGImage()) {
- if (!ToSVGImage(image)->HasIntrinsicDimensions() &&
+ if (auto* svg_image = DynamicTo<SVGImage>(image)) {
+ if (!svg_image->HasIntrinsicDimensions() &&
(!crop_rect &&
(!options->hasResizeWidth() || !options->hasResizeHeight()))) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "The image element contains an SVG image without intrinsic "
- "dimensions, and no resize options or crop region are "
- "specified."));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "The image element contains an SVG image without intrinsic "
+ "dimensions, and no resize options or crop region are "
+ "specified.");
+ return ScriptPromise();
}
return ImageBitmap::CreateAsync(this, crop_rect,
event_target.ToLocalDOMWindow()->document(),
script_state, options);
}
return ImageBitmapSource::FulfillImageBitmap(
- script_state, ImageBitmap::Create(
- this, crop_rect,
- event_target.ToLocalDOMWindow()->document(), options));
+ script_state,
+ MakeGarbageCollected<ImageBitmap>(
+ this, crop_rect, event_target.ToLocalDOMWindow()->document(),
+ options),
+ exception_state);
}
Image::ImageDecodingMode ImageElementBase::GetDecodingModeForPainting(
@@ -188,4 +178,9 @@ Image::ImageDecodingMode ImageElementBase::GetDecodingModeForPainting(
return decoding_mode_;
}
+RespectImageOrientationEnum ImageElementBase::RespectImageOrientation() const {
+ return LayoutObject::ShouldRespectImageOrientation(
+ GetElement().GetLayoutObject());
+}
+
} // namespace blink
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 0b8979db73d..25c5d8f8468 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
@@ -30,7 +30,8 @@ class CORE_EXPORT ImageElementBase : public CanvasImageSource,
ScriptPromise CreateImageBitmap(ScriptState*,
EventTarget&,
base::Optional<IntRect>,
- const ImageBitmapOptions*) override;
+ const ImageBitmapOptions*,
+ ExceptionState&) override;
scoped_refptr<Image> GetSourceImageForCanvas(SourceImageStatus*,
AccelerationHint,
@@ -38,9 +39,11 @@ class CORE_EXPORT ImageElementBase : public CanvasImageSource,
bool WouldTaintOrigin() const override;
- FloatSize ElementSize(const FloatSize& default_object_size) const override;
+ FloatSize ElementSize(const FloatSize& default_object_size,
+ const RespectImageOrientationEnum) const override;
FloatSize DefaultDestinationSize(
- const FloatSize& default_object_size) const override;
+ const FloatSize& default_object_size,
+ const RespectImageOrientationEnum) const override;
bool IsAccelerated() const override;
@@ -59,6 +62,11 @@ class CORE_EXPORT ImageElementBase : public CanvasImageSource,
// Used with HTMLImageElement and SVGImageElement types.
Image::ImageDecodingMode GetDecodingModeForPainting(PaintImage::Id);
+ // Return the image orientation setting from the layout object, if available.
+ // In the absence of a layout object, kRespectImageOrientation will be
+ // returned.
+ RespectImageOrientationEnum RespectImageOrientation() const;
+
protected:
Image::ImageDecodingMode decoding_mode_ =
Image::ImageDecodingMode::kUnspecifiedDecode;
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 8ec200154ae..bdbc4c5a9f9 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
@@ -3,7 +3,7 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/core/html/canvas/text_metrics.h"
-#include "third_party/blink/renderer/core/html/canvas/baselines.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_baselines.h"
#include "third_party/blink/renderer/platform/fonts/character_range.h"
namespace blink {
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 e73c0e0d299..2a3529a53e7 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
@@ -26,8 +26,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CANVAS_TEXT_METRICS_H_
#define 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/core_export.h"
-#include "third_party/blink/renderer/core/html/canvas/baselines.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/fonts/font.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
diff --git a/chromium/third_party/blink/renderer/core/html/cross_origin_attribute.cc b/chromium/third_party/blink/renderer/core/html/cross_origin_attribute.cc
index 12842ad43c5..3a078089406 100644
--- a/chromium/third_party/blink/renderer/core/html/cross_origin_attribute.cc
+++ b/chromium/third_party/blink/renderer/core/html/cross_origin_attribute.cc
@@ -9,7 +9,7 @@ namespace blink {
CrossOriginAttributeValue GetCrossOriginAttributeValue(const String& value) {
if (value.IsNull())
return kCrossOriginAttributeNotSet;
- if (DeprecatedEqualIgnoringCase(value, "use-credentials"))
+ if (EqualIgnoringASCIICase(value, "use-credentials"))
return kCrossOriginAttributeUseCredentials;
return kCrossOriginAttributeAnonymous;
}
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 d21c582052c..1a031cecfab 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
@@ -56,8 +56,7 @@ Vector<AtomicString>& CustomElement::EmbedderCustomElementNames() {
void CustomElement::AddEmbedderCustomElementName(const AtomicString& name) {
DCHECK_EQ(name, name.LowerASCII());
DCHECK(Document::IsValidName(name)) << name;
- DCHECK_EQ(HTMLElementType::kHTMLUnknownElement, htmlElementTypeForTag(name))
- << name;
+ DCHECK(!IsKnownBuiltinTagName(name)) << name;
DCHECK(!IsValidName(name, false)) << name;
if (EmbedderCustomElementNames().Contains(name))
@@ -69,8 +68,7 @@ void CustomElement::AddEmbedderCustomElementNameForTesting(
const AtomicString& name,
ExceptionState& exception_state) {
if (name != name.LowerASCII() || !Document::IsValidName(name) ||
- HTMLElementType::kHTMLUnknownElement != htmlElementTypeForTag(name) ||
- IsValidName(name, false)) {
+ IsKnownBuiltinTagName(name) || IsValidName(name, false)) {
exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
"Name cannot be used");
return;
@@ -105,14 +103,16 @@ bool CustomElement::ShouldCreateCustomElement(const QualifiedName& tag_name) {
}
bool CustomElement::ShouldCreateCustomizedBuiltinElement(
- const AtomicString& local_name) {
- return htmlElementTypeForTag(local_name) !=
+ const AtomicString& local_name,
+ const Document& document) {
+ return htmlElementTypeForTag(local_name, &document) !=
HTMLElementType::kHTMLUnknownElement;
}
bool CustomElement::ShouldCreateCustomizedBuiltinElement(
- const QualifiedName& tag_name) {
- return ShouldCreateCustomizedBuiltinElement(tag_name.LocalName()) &&
+ const QualifiedName& tag_name,
+ const Document& document) {
+ return ShouldCreateCustomizedBuiltinElement(tag_name.LocalName(), document) &&
tag_name.NamespaceURI() == html_names::xhtmlNamespaceURI;
}
@@ -205,7 +205,8 @@ Element* CustomElement::CreateUncustomizedOrUndefinedElement(
HTMLElement* CustomElement::CreateFailedElement(Document& document,
const QualifiedName& tag_name) {
- DCHECK(ShouldCreateCustomElement(tag_name));
+ CHECK(ShouldCreateCustomElement(tag_name))
+ << "HTMLUnknownElement with built-in tag name: " << tag_name;
// "create an element for a token":
// https://html.spec.whatwg.org/C/#create-an-element-for-the-token
diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element.h b/chromium/third_party/blink/renderer/core/html/custom/custom_element.h
index 172a3dc7eb8..16e077eb151 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/custom_element.h
+++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element.h
@@ -77,8 +77,10 @@ class CORE_EXPORT CustomElement {
static bool ShouldCreateCustomElement(const AtomicString& local_name);
static bool ShouldCreateCustomElement(const QualifiedName&);
static bool ShouldCreateCustomizedBuiltinElement(
- const AtomicString& local_name);
- static bool ShouldCreateCustomizedBuiltinElement(const QualifiedName&);
+ const AtomicString& local_name,
+ const Document&);
+ static bool ShouldCreateCustomizedBuiltinElement(const QualifiedName&,
+ const Document&);
// Look up a definition, and create an autonomous custom element if
// it's found.
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 6126e0d04c4..c5e4a121416 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
@@ -112,7 +112,7 @@ HTMLElement* CustomElementDefinition::CreateElementForConstructor(
document);
}
// TODO(davaajav): write this as one call to setCustomElementState instead of
- // two
+ // two.
element->SetCustomElementState(CustomElementState::kUndefined);
element->SetCustomElementDefinition(this);
return element;
@@ -123,8 +123,9 @@ HTMLElement* CustomElementDefinition::CreateElement(
Document& document,
const QualifiedName& tag_name,
CreateElementFlags flags) {
- DCHECK(CustomElement::ShouldCreateCustomElement(tag_name) ||
- CustomElement::ShouldCreateCustomizedBuiltinElement(tag_name))
+ DCHECK(
+ CustomElement::ShouldCreateCustomElement(tag_name) ||
+ CustomElement::ShouldCreateCustomizedBuiltinElement(tag_name, document))
<< tag_name;
// 5. If definition is non-null, and definition’s name is not equal to
@@ -142,14 +143,19 @@ HTMLElement* CustomElementDefinition::CreateElement(
result->SetCustomElementState(CustomElementState::kUndefined);
result->SetIsValue(Descriptor().GetName());
- // 5.3. If the synchronous custom elements flag is set, upgrade
- // element using definition.
- // 5.4. Otherwise, enqueue a custom element upgrade reaction given
- // result and definition.
- if (!flags.IsAsyncCustomElements())
+ if (!flags.IsAsyncCustomElements()) {
+ // 5.3 If the synchronous custom elements flag is set, then run this step
+ // while catching any exceptions:
+ // 1. Upgrade element using definition.
+ // If this step threw an exception, then:
+ // 1. Report the exception.
+ // 2. Set result's custom element state to "failed".
Upgrade(*result);
- else
+ } else {
+ // 5.4. Otherwise, enqueue a custom element upgrade reaction given
+ // result and definition.
EnqueueUpgradeReaction(*result);
+ }
return To<HTMLElement>(result);
}
@@ -175,7 +181,7 @@ HTMLElement* CustomElementDefinition::CreateElement(
CustomElementDefinition::ConstructionStackScope::ConstructionStackScope(
CustomElementDefinition& definition,
Element& element)
- : construction_stack_(definition.construction_stack_), element_(element) {
+ : construction_stack_(definition.construction_stack_), element_(&element) {
// Push the construction stack.
construction_stack_.push_back(&element);
depth_ = construction_stack_.size();
@@ -190,21 +196,39 @@ CustomElementDefinition::ConstructionStackScope::~ConstructionStackScope() {
// https://html.spec.whatwg.org/C/#concept-upgrade-an-element
void CustomElementDefinition::Upgrade(Element& element) {
- DCHECK_EQ(element.GetCustomElementState(), CustomElementState::kUndefined);
+ // 4.13.5.1 If element is custom, then return.
+ // 4.13.5.2 If element's custom element state is "failed", then return.
+ if (element.GetCustomElementState() == CustomElementState::kCustom ||
+ element.GetCustomElementState() == CustomElementState::kFailed) {
+ return;
+ }
+
+ // 4.13.5.3. Set element's custom element state to "failed".
+ element.SetCustomElementState(CustomElementState::kFailed);
+ // 4.13.5.4: For each attribute in element's attribute list, in order, enqueue
+ // a custom element callback reaction with element, callback name
+ // "attributeChangedCallback", and an argument list containing attribute's
+ // local name, null, attribute's value, and attribute's namespace.
if (!observed_attributes_.IsEmpty())
EnqueueAttributeChangedCallbackForAllAttributes(element);
+ // 4.13.5.5: If element is connected, then enqueue a custom element callback
+ // reaction with element, callback name "connectedCallback", and an empty
+ // argument list.
if (element.isConnected() && HasConnectedCallback())
EnqueueConnectedCallback(element);
bool succeeded = false;
{
+ // 4.13.5.6: Add element to the end of definition's construction stack.
ConstructionStackScope construction_stack_scope(*this, element);
+ // 4.13.5.8: Run the constructor, catching exceptions.
succeeded = RunConstructor(element);
}
if (!succeeded) {
- element.SetCustomElementState(CustomElementState::kFailed);
+ // 4.13.5.?: If the above steps threw an exception, then element's custom
+ // element state will remain "failed".
CustomElementReactionStack::Current().ClearQueue(element);
return;
}
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 e2c73857658..a3610a2c26f 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
@@ -136,7 +136,7 @@ class CORE_EXPORT CustomElementDefinition
private:
ConstructionStack& construction_stack_;
- Member<Element> element_;
+ Element* element_;
size_t depth_;
};
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 d2f544c3fb2..6450df0d6ec 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
@@ -143,8 +143,8 @@ class ResetCustomElementReactionStackForTest final {
CustomElementReactionStack& Stack() { return *stack_; }
private:
- Member<CustomElementReactionStack> stack_;
- Member<CustomElementReactionStack> old_stack_;
+ CustomElementReactionStack* stack_;
+ CustomElementReactionStack* old_stack_;
DISALLOW_COPY_AND_ASSIGN(ResetCustomElementReactionStackForTest);
};
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 216efea305a..59e806f5309 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
@@ -11,9 +11,9 @@
#include "third_party/blink/renderer/bindings/core/v8/script_custom_element_definition_builder.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_element_definition_options.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/dom/element_definition_options.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/frame/local_dom_window.h"
@@ -150,7 +150,7 @@ CustomElementDefinition* CustomElementRegistry::DefineInternal(
if (ThrowIfValidName(AtomicString(options->extends()), exception_state))
return nullptr;
// 7.2. If element interface is undefined element, throw exception
- if (htmlElementTypeForTag(extends) ==
+ if (htmlElementTypeForTag(extends, owner_->document()) ==
HTMLElementType::kHTMLUnknownElement) {
exception_state.ThrowDOMException(
DOMExceptionCode::kNotSupportedError,
diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.idl b/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.idl
index 986991b7968..144566b51d2 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.idl
+++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.idl
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://html.spec.whatwg.org/C/custom-elements.html#customelementregistry
+// https://html.spec.whatwg.org/C/#customelementregistry
[Exposed=Window]
interface CustomElementRegistry {
- [CallWith=ScriptState, CEReactions, CustomElementCallbacks, RaisesException, MeasureAs=CustomElementRegistryDefine] void define(DOMString name, CustomElementConstructor constructor, optional ElementDefinitionOptions options);
+ [CallWith=ScriptState, CEReactions, CustomElementCallbacks, RaisesException, MeasureAs=CustomElementRegistryDefine] void define(DOMString name, CustomElementConstructor constructor, optional ElementDefinitionOptions options = {});
any get(DOMString name);
[CallWith=ScriptState,RaisesException] Promise<void> whenDefined(DOMString name);
[CEReactions] void upgrade(Node root);
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 c2b430f64f2..c50d69d521f 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
@@ -8,13 +8,13 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/web/web_custom_element.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
-#include "third_party/blink/renderer/core/css/css_style_sheet_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_css_style_sheet_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_element_definition_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_shadow_root_init.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/element.h"
-#include "third_party/blink/renderer/core/dom/element_definition_options.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
-#include "third_party/blink/renderer/core/dom/shadow_root_init.h"
#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/custom_element.h"
diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_test.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_test.cc
index 1ea5764c0cd..d28b73f5cbc 100644
--- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_test.cc
@@ -9,6 +9,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_element_definition_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/html/custom/custom_element_definition.h"
@@ -159,7 +160,7 @@ TEST(CustomElementTest, StateByParser) {
"<font-face id=v0></font-face>";
auto page_holder = std::make_unique<DummyPageHolder>();
Document& document = page_holder->GetDocument();
- document.body()->SetInnerHTMLFromString(String::FromUTF8(body_content));
+ document.body()->setInnerHTML(String::FromUTF8(body_content));
struct {
const char* id;
@@ -234,7 +235,7 @@ TEST(CustomElementTest,
// create an element with an uppercase tag name
Document& document = holder->GetDocument();
- EXPECT_TRUE(document.IsHTMLDocument())
+ EXPECT_TRUE(IsA<HTMLDocument>(document))
<< "this test requires a HTML document";
Element* element = document.CreateElementForBinding("A-A", should_not_throw);
EXPECT_EQ(definition, element->GetCustomElementDefinition());
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 af5cc4358fe..915324b0e8b 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
@@ -8,7 +8,6 @@
#include "base/macros.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/dom/element_definition_options.h"
#include "third_party/blink/renderer/core/dom/qualified_name.h"
#include "third_party/blink/renderer/core/html/custom/ce_reactions_scope.h"
#include "third_party/blink/renderer/core/html/custom/custom_element_definition.h"
@@ -153,7 +152,7 @@ class CreateElement {
}
operator Element*() const {
- Document* document = document_.Get();
+ Document* document = document_;
if (!document)
document = MakeGarbageCollected<HTMLDocument>();
NonThrowableExceptionState no_exceptions;
@@ -166,7 +165,7 @@ class CreateElement {
}
private:
- Member<Document> document_;
+ Document* document_ = nullptr;
AtomicString namespace_uri_;
AtomicString local_name_;
AtomicString is_value_;
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 8f03e5412f5..f82ce78f372 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
@@ -7,10 +7,10 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_element_creation_options.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_shadow_root_init.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/dom/shadow_root.h"
-#include "third_party/blink/renderer/core/dom/shadow_root_init.h"
#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
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 946528c5dbd..d207f394d88 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
@@ -4,13 +4,13 @@
#include "third_party/blink/renderer/core/html/custom/element_internals.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_validity_state_flags.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
#include "third_party/blink/renderer/core/dom/dom_token_list.h"
#include "third_party/blink/renderer/core/dom/node_lists_node_data.h"
#include "third_party/blink/renderer/core/fileapi/file.h"
#include "third_party/blink/renderer/core/html/custom/custom_element.h"
#include "third_party/blink/renderer/core/html/custom/custom_element_registry.h"
-#include "third_party/blink/renderer/core/html/custom/validity_state_flags.h"
#include "third_party/blink/renderer/core/html/forms/form_controller.h"
#include "third_party/blink/renderer/core/html/forms/form_data.h"
#include "third_party/blink/renderer/core/html/forms/html_form_element.h"
@@ -47,7 +47,6 @@ class CustomStatesTokenList : public DOMTokenList {
};
ElementInternals::ElementInternals(HTMLElement& target) : target_(target) {
- value_.SetUSVString(String());
}
void ElementInternals::Trace(Visitor* visitor) {
@@ -301,6 +300,27 @@ Element* ElementInternals::GetElementAttribute(const QualifiedName& name) {
return element_vector->at(0);
}
+base::Optional<HeapVector<Member<Element>>>
+ElementInternals::GetElementArrayAttribute(const QualifiedName& name) const {
+ const auto& iter = explicitly_set_attr_elements_map_.find(name);
+ if (iter != explicitly_set_attr_elements_map_.end()) {
+ return *(iter->value);
+ }
+ return base::nullopt;
+}
+
+void ElementInternals::SetElementArrayAttribute(
+ const QualifiedName& name,
+ const base::Optional<HeapVector<Member<Element>>>& elements) {
+ if (elements) {
+ explicitly_set_attr_elements_map_.Set(
+ name,
+ MakeGarbageCollected<HeapVector<Member<Element>>>(elements.value()));
+ } else {
+ explicitly_set_attr_elements_map_.erase(name);
+ }
+}
+
HeapVector<Member<Element>> ElementInternals::GetElementArrayAttribute(
const QualifiedName& name,
bool is_null) {
@@ -328,8 +348,13 @@ void ElementInternals::SetElementArrayAttribute(
bool ElementInternals::IsTargetFormAssociated() const {
if (Target().IsFormAssociatedCustomElement())
return true;
- if (Target().GetCustomElementState() != CustomElementState::kUndefined)
+ // Custom element could be in the process of upgrading here, during which
+ // it will have state kFailed according to:
+ // https://html.spec.whatwg.org/multipage/custom-elements.html#upgrades
+ if (Target().GetCustomElementState() != CustomElementState::kUndefined &&
+ Target().GetCustomElementState() != CustomElementState::kFailed) {
return false;
+ }
// An element is in "undefined" state in its constructor JavaScript code.
// ElementInternals needs to handle elements to be form-associated same as
// form-associated custom elements because web authors want to call
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 1b5185eb781..dc4133e64e7 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
@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/bindings/core/v8/file_or_usv_string_or_form_data.h"
#include "third_party/blink/renderer/core/dom/qualified_name.h"
+#include "third_party/blink/renderer/core/html/forms/labels_node_list.h"
#include "third_party/blink/renderer/core/html/forms/listed_element.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
@@ -15,7 +16,6 @@ namespace blink {
class DOMTokenList;
class HTMLElement;
-class LabelsNodeList;
class ValidityStateFlags;
class CORE_EXPORT ElementInternals : public ScriptWrappable,
@@ -62,12 +62,18 @@ class CORE_EXPORT ElementInternals : public ScriptWrappable,
void SetElementAttribute(const QualifiedName& name, Element* element);
Element* GetElementAttribute(const QualifiedName& name);
+ base::Optional<HeapVector<Member<Element>>> GetElementArrayAttribute(
+ const QualifiedName& name) const;
+ void SetElementArrayAttribute(
+ const QualifiedName& name,
+ const base::Optional<HeapVector<Member<Element>>>& elements);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
HeapVector<Member<Element>> GetElementArrayAttribute(
const QualifiedName& name,
- bool is_null);
+ bool is_null); // DEPRECATED
void SetElementArrayAttribute(const QualifiedName&,
HeapVector<Member<Element>>,
- bool is_null);
+ bool is_null); // DEPRECATED
bool HasAttribute(const QualifiedName& attribute) const;
const HashMap<QualifiedName, AtomicString>& GetAttributes() const;
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 546036951ef..22b212dbb61 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
@@ -59,7 +59,7 @@ void V0CustomElementMicrotaskResolutionStep::Trace(Visitor* visitor) {
#if !defined(NDEBUG)
void V0CustomElementMicrotaskResolutionStep::Show(unsigned indent) {
fprintf(stderr, "%*sResolution: ", indent, "");
- element_->OuterHTMLAsString().Show();
+ element_->outerHTML().Show();
}
#endif
diff --git a/chromium/third_party/blink/renderer/core/html/document_all_name_collection.h b/chromium/third_party/blink/renderer/core/html/document_all_name_collection.h
index 8de9fcdc346..d8f7fba6a86 100644
--- a/chromium/third_party/blink/renderer/core/html/document_all_name_collection.h
+++ b/chromium/third_party/blink/renderer/core/html/document_all_name_collection.h
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_DOCUMENT_ALL_NAME_COLLECTION_H_
#include "third_party/blink/renderer/core/html/html_name_collection.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -21,11 +22,12 @@ class DocumentAllNameCollection final : public HTMLNameCollection {
bool ElementMatches(const Element&) const;
};
-DEFINE_TYPE_CASTS(DocumentAllNameCollection,
- LiveNodeListBase,
- collection,
- collection->GetType() == kDocumentAllNamedItems,
- collection.GetType() == kDocumentAllNamedItems);
+template <>
+struct DowncastTraits<DocumentAllNameCollection> {
+ static bool AllowFrom(const LiveNodeListBase& collection) {
+ return collection.GetType() == kDocumentAllNamedItems;
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/document_name_collection.h b/chromium/third_party/blink/renderer/core/html/document_name_collection.h
index 39f342cf0b9..3757a9f9baf 100644
--- a/chromium/third_party/blink/renderer/core/html/document_name_collection.h
+++ b/chromium/third_party/blink/renderer/core/html/document_name_collection.h
@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/html/html_name_collection.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -24,11 +25,12 @@ class DocumentNameCollection final : public HTMLNameCollection {
bool ElementMatches(const HTMLElement&) const;
};
-DEFINE_TYPE_CASTS(DocumentNameCollection,
- LiveNodeListBase,
- collection,
- collection->GetType() == kDocumentNamedItems,
- collection.GetType() == kDocumentNamedItems);
+template <>
+struct DowncastTraits<DocumentNameCollection> {
+ static bool AllowFrom(const LiveNodeListBase& collection) {
+ return collection.GetType() == kDocumentNamedItems;
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/forms/DEPS b/chromium/third_party/blink/renderer/core/html/forms/DEPS
index 4a90b3a5a0b..95b04a4250f 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/DEPS
+++ b/chromium/third_party/blink/renderer/core/html/forms/DEPS
@@ -1,5 +1,5 @@
specific_include_rules = {
"file_input_type_test.cc": [
"+base/run_loop.h",
- ]
-} \ No newline at end of file
+ ],
+}
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 c4525556389..6fc142b3b06 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
@@ -74,6 +74,10 @@ bool BaseButtonInputType::ShouldSaveAndRestoreFormControlState() const {
void BaseButtonInputType::AppendToFormData(FormData&) const {}
+bool BaseButtonInputType::TypeShouldForceLegacyLayout() const {
+ return true;
+}
+
LayoutObject* BaseButtonInputType::CreateLayoutObject(const ComputedStyle&,
LegacyLayout) const {
return new LayoutButton(&GetElement());
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 e0310279d72..b048c471560 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
@@ -54,6 +54,7 @@ class BaseButtonInputType : public InputType,
InputTypeView* CreateView() override;
bool ShouldSaveAndRestoreFormControlState() const override;
void AppendToFormData(FormData&) const override;
+ bool TypeShouldForceLegacyLayout() const override;
LayoutObject* CreateLayoutObject(const ComputedStyle&,
LegacyLayout) const override;
ValueMode GetValueMode() const override;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/base_temporal_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/base_temporal_input_type.cc
index 4e007f8fc74..ad6d6a6e29a 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/base_temporal_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/base_temporal_input_type.cc
@@ -104,6 +104,16 @@ String BaseTemporalInputType::RangeUnderflowText(const Decimal& minimum) const {
LocalizeValue(Serialize(minimum)));
}
+String BaseTemporalInputType::RangeInvalidText(const Decimal& minimum,
+ const Decimal& maximum) const {
+ DCHECK(minimum > maximum)
+ << "RangeInvalidText should only be called with minimum>maximum";
+
+ return GetLocale().QueryString(IDS_FORM_VALIDATION_RANGE_INVALID_DATETIME,
+ LocalizeValue(Serialize(minimum)),
+ LocalizeValue(Serialize(maximum)));
+}
+
Decimal BaseTemporalInputType::DefaultValueForStepUp() const {
return Decimal::FromDouble(
ConvertToLocalTime(base::Time::Now()).InMillisecondsF());
@@ -190,7 +200,11 @@ bool BaseTemporalInputType::ShouldRespectListAttribute() {
}
bool BaseTemporalInputType::ValueMissing(const String& value) const {
- return GetElement().IsRequired() && value.IsEmpty();
+ // For text-mode input elements (including dates), the value is missing only
+ // if it is mutable.
+ // https://html.spec.whatwg.org/multipage/input.html#the-required-attribute
+ return GetElement().IsRequired() && value.IsEmpty() &&
+ !GetElement().IsDisabledOrReadOnly();
}
bool BaseTemporalInputType::MayTriggerVirtualKeyboard() const {
diff --git a/chromium/third_party/blink/renderer/core/html/forms/base_temporal_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/base_temporal_input_type.h
index 13359fabe8b..b1e6cafa63e 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/base_temporal_input_type.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/base_temporal_input_type.h
@@ -69,6 +69,7 @@ class BaseTemporalInputType : public InputType {
bool has_hour,
bool has_minute,
bool has_second) const = 0;
+ virtual String AriaRoleForPickerIndicator() const = 0;
protected:
BaseTemporalInputType(HTMLInputElement& element) : InputType(element) {}
@@ -96,6 +97,8 @@ class BaseTemporalInputType : public InputType {
bool ValueMissing(const String&) const override;
String RangeOverflowText(const Decimal& maximum) const override;
String RangeUnderflowText(const Decimal& minimum) const override;
+ String RangeInvalidText(const Decimal& minimum,
+ const Decimal& maximum) const override;
Decimal DefaultValueForStepUp() const override;
bool IsSteppable() const override;
virtual String SerializeWithDate(const base::Optional<base::Time>&) const;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/base_text_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/base_text_input_type.cc
index 8fdc4798ee3..0f838dc1992 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/base_text_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/base_text_input_type.cc
@@ -28,6 +28,7 @@
#include "third_party/blink/renderer/core/html/forms/html_input_element.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/platform/heap/heap.h"
namespace blink {
@@ -88,11 +89,12 @@ bool BaseTextInputType::PatternMismatch(const String& value) const {
ScriptRegexp::UTF16));
if (!raw_regexp->IsValid()) {
GetElement().GetDocument().AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kRendering,
- mojom::ConsoleMessageLevel::kError,
- "Pattern attribute value " + raw_pattern +
- " is not a valid regular expression: " +
- raw_regexp->ExceptionMessage()));
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kRendering,
+ mojom::ConsoleMessageLevel::kError,
+ "Pattern attribute value " + raw_pattern +
+ " is not a valid regular expression: " +
+ raw_regexp->ExceptionMessage()));
regexp_.reset(raw_regexp.release());
pattern_for_regexp_ = raw_pattern;
return false;
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 1afa8214130..bcedfe36f09 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
@@ -56,12 +56,6 @@ class ClearButtonElement final : public HTMLDivElement {
Member<ClearButtonOwner> clear_button_owner_;
};
-DEFINE_TYPE_CASTS(ClearButtonElement,
- Element,
- element,
- element->IsClearButtonElement(),
- element.IsClearButtonElement());
-
template <>
struct DowncastTraits<ClearButtonElement> {
static bool AllowFrom(const Element& element) {
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 87bdbc0d9a5..051e20a4bdd 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
@@ -38,13 +38,17 @@ namespace blink {
class AXObject;
class Color;
+// This interface respresents a UI to choose a color.
class CORE_EXPORT ColorChooser : public GarbageCollectedMixin {
public:
ColorChooser();
virtual ~ColorChooser();
void Trace(Visitor* visitor) override {}
+ // Call to update the selection in the UI. Used to reflect value changes made
+ // by JS.
virtual void SetSelectedColor(const Color&) {}
+ // Call to close the UI.
virtual void EndChooser() {}
// Returns a root AXObject in the ColorChooser if it's available.
virtual AXObject* RootAXObject() = 0;
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 828b2cfba30..292e216ff7a 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
@@ -42,12 +42,15 @@ namespace blink {
class Element;
+// This class is the client for the ColorChooser.
class CORE_EXPORT ColorChooserClient : public GarbageCollectedMixin {
public:
virtual ~ColorChooserClient();
void Trace(Visitor* visitor) override {}
+ // Called when a color is chosen by the user in the ColorChooser UI.
virtual void DidChooseColor(const Color&) = 0;
+ // Called when ColorChooser UI was closed by the user.
virtual void DidEndChooser() = 0;
virtual Element& OwnerElement() const = 0;
virtual IntRect ElementRectRelativeToViewport() const = 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 4d48b286df1..f61b77e16fe 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
@@ -25,6 +25,8 @@
#include "third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.h"
+#include "build/build_config.h"
+#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/strings/grit/blink_strings.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -32,8 +34,10 @@
#include "third_party/blink/renderer/core/html/forms/chooser_resource_loader.h"
#include "third_party/blink/renderer/core/html/forms/color_chooser_client.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
+#include "third_party/blink/renderer/core/page/color_page_popup_controller.h"
#include "third_party/blink/renderer/core/page/page_popup.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
+#include "ui/base/ui_base_features.h"
namespace blink {
@@ -53,12 +57,8 @@ ColorChooserPopupUIController::ColorChooserPopupUIController(
popup_(nullptr),
locale_(Locale::DefaultLocale()) {}
-ColorChooserPopupUIController::~ColorChooserPopupUIController() = default;
-
-void ColorChooserPopupUIController::Dispose() {
- // Finalized earlier so as to access chrome_client_ while alive.
- CancelPopup();
- // ~ColorChooserUIController calls EndChooser().
+ColorChooserPopupUIController::~ColorChooserPopupUIController() {
+ DCHECK(!popup_);
}
void ColorChooserPopupUIController::Trace(Visitor* visitor) {
@@ -68,7 +68,7 @@ void ColorChooserPopupUIController::Trace(Visitor* visitor) {
void ColorChooserPopupUIController::OpenUI() {
if (client_->ShouldShowSuggestions() ||
- RuntimeEnabledFeatures::FormControlsRefreshEnabled())
+ features::IsFormControlsRefreshEnabled())
OpenPopup();
else
OpenColorChooser();
@@ -93,7 +93,7 @@ void ColorChooserPopupUIController::WriteDocument(SharedBuffer* data) {
void ColorChooserPopupUIController::WriteColorPickerDocument(
SharedBuffer* data) {
- DCHECK(RuntimeEnabledFeatures::FormControlsRefreshEnabled());
+ DCHECK(features::IsFormControlsRefreshEnabled());
IntRect anchor_rect_in_screen = chrome_client_->ViewportToScreen(
client_->ElementRectRelativeToViewport(), frame_->View());
@@ -102,7 +102,6 @@ void ColorChooserPopupUIController::WriteColorPickerDocument(
"<!DOCTYPE html><head><meta charset='UTF-8'><style>\n", data);
data->Append(ChooserResourceLoader::GetPickerCommonStyleSheet());
data->Append(ChooserResourceLoader::GetColorPickerStyleSheet());
-
PagePopupClient::AddString(
"</style></head><body>\n"
"<div id='main'>Loading...</div><script>\n"
@@ -113,6 +112,11 @@ void ColorChooserPopupUIController::WriteColorPickerDocument(
AddProperty("anchorRectInScreen", anchor_rect_in_screen, data);
AddProperty("zoomFactor", ScaledZoomFactor(), data);
AddProperty("shouldShowColorSuggestionPicker", false, data);
+ AddProperty("isEyeDropperEnabled", features::IsEyeDropperEnabled(), data);
+#if defined(OS_MACOSX)
+ AddProperty("isBorderTransparent", features::IsFormControlsRefreshEnabled(),
+ data);
+#endif
PagePopupClient::AddString("};\n", data);
data->Append(ChooserResourceLoader::GetPickerCommonJS());
data->Append(ChooserResourceLoader::GetColorPickerJS());
@@ -134,9 +138,8 @@ void ColorChooserPopupUIController::WriteColorSuggestionPickerDocument(
"<!DOCTYPE html><head><meta charset='UTF-8'><style>\n", data);
data->Append(ChooserResourceLoader::GetPickerCommonStyleSheet());
data->Append(ChooserResourceLoader::GetColorSuggestionPickerStyleSheet());
- if (RuntimeEnabledFeatures::FormControlsRefreshEnabled())
+ if (features::IsFormControlsRefreshEnabled())
data->Append(ChooserResourceLoader::GetColorPickerStyleSheet());
-
PagePopupClient::AddString(
"</style></head><body>\n"
"<div id='main'>Loading...</div><script>\n"
@@ -146,7 +149,7 @@ void ColorChooserPopupUIController::WriteColorSuggestionPickerDocument(
PagePopupClient::AddProperty(
"otherColorLabel", GetLocale().QueryString(IDS_FORM_OTHER_COLOR_LABEL),
data);
- if (RuntimeEnabledFeatures::FormControlsRefreshEnabled()) {
+ if (features::IsFormControlsRefreshEnabled()) {
PagePopupClient::AddProperty("selectedColor",
client_->CurrentColor().Serialized(), data);
}
@@ -154,11 +157,16 @@ void ColorChooserPopupUIController::WriteColorSuggestionPickerDocument(
AddProperty("zoomFactor", ScaledZoomFactor(), data);
AddProperty("shouldShowColorSuggestionPicker", true, data);
AddProperty("isFormControlsRefreshEnabled",
- RuntimeEnabledFeatures::FormControlsRefreshEnabled(), data);
+ features::IsFormControlsRefreshEnabled(), data);
+ AddProperty("isEyeDropperEnabled", features::IsEyeDropperEnabled(), data);
+#if defined(OS_MACOSX)
+ AddProperty("isBorderTransparent", features::IsFormControlsRefreshEnabled(),
+ data);
+#endif
PagePopupClient::AddString("};\n", data);
data->Append(ChooserResourceLoader::GetPickerCommonJS());
data->Append(ChooserResourceLoader::GetColorSuggestionPickerJS());
- if (RuntimeEnabledFeatures::FormControlsRefreshEnabled())
+ if (features::IsFormControlsRefreshEnabled())
data->Append(ChooserResourceLoader::GetColorPickerJS());
data->Append(ChooserResourceLoader::GetColorPickerCommonJS());
PagePopupClient::AddString("</script></body>\n", data);
@@ -176,7 +184,7 @@ void ColorChooserPopupUIController::SetValueAndClosePopup(
if (num_value == kColorPickerPopupActionSetValue)
SetValue(string_value);
if (num_value == kColorPickerPopupActionChooseOtherColor) {
- DCHECK(!RuntimeEnabledFeatures::FormControlsRefreshEnabled());
+ DCHECK(!features::IsFormControlsRefreshEnabled());
OpenColorChooser();
}
CancelPopup();
@@ -216,4 +224,24 @@ void ColorChooserPopupUIController::CancelPopup() {
chrome_client_->ClosePagePopup(popup_);
}
+PagePopupController* ColorChooserPopupUIController::CreatePagePopupController(
+ PagePopup& popup) {
+ return MakeGarbageCollected<ColorPagePopupController>(popup, this);
+}
+
+void ColorChooserPopupUIController::EyeDropperResponseHandler(bool success,
+ uint32_t color) {
+ // TODO(crbug.com/992297): update the color popup with the chosen value.
+}
+
+void ColorChooserPopupUIController::OpenEyeDropper() {
+ frame_->GetBrowserInterfaceBroker().GetInterface(
+ eye_dropper_chooser_.BindNewPipeAndPassReceiver());
+ eye_dropper_chooser_.set_disconnect_handler(WTF::Bind(
+ &ColorChooserPopupUIController::EndChooser, WrapWeakPersistent(this)));
+ eye_dropper_chooser_->Choose(
+ WTF::Bind(&ColorChooserPopupUIController::EyeDropperResponseHandler,
+ WrapWeakPersistent(this)));
+}
+
} // namespace blink
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 736b8697680..fd20189266e 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
@@ -35,12 +35,11 @@ namespace blink {
class ChromeClient;
class ColorChooserClient;
class PagePopup;
+class PagePopupController;
class CORE_EXPORT ColorChooserPopupUIController final
: public ColorChooserUIController,
public PagePopupClient {
- USING_PRE_FINALIZER(ColorChooserPopupUIController, Dispose);
-
public:
ColorChooserPopupUIController(LocalFrame*,
ChromeClient*,
@@ -57,19 +56,21 @@ class CORE_EXPORT ColorChooserPopupUIController final
// PagePopupClient functions:
void WriteDocument(SharedBuffer*) override;
- void SelectFontsFromOwnerDocument(Document&) override {}
Locale& GetLocale() override;
void SetValueAndClosePopup(int, const String&) override;
void SetValue(const String&) override;
void CancelPopup() override;
Element& OwnerElement() override;
void DidClosePopup() override;
+ PagePopupController* CreatePagePopupController(PagePopup&) override;
+
+ void OpenEyeDropper();
+ void EyeDropperResponseHandler(bool success, uint32_t color);
private:
ChromeClient& GetChromeClient() override;
void OpenPopup();
- void Dispose();
void WriteColorPickerDocument(SharedBuffer*);
void WriteColorSuggestionPickerDocument(SharedBuffer*);
@@ -77,6 +78,7 @@ class CORE_EXPORT ColorChooserPopupUIController final
Member<ChromeClient> chrome_client_;
PagePopup* popup_;
Locale& locale_;
+ mojo::Remote<mojom::blink::EyeDropperChooser> eye_dropper_chooser_;
};
} // namespace blink
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 bd31182d982..8bce77ac6c3 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
@@ -27,6 +27,7 @@
#include "third_party/blink/public/common/browser_interface_broker_proxy.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/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/html/forms/color_chooser_client.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
@@ -37,20 +38,19 @@ namespace blink {
ColorChooserUIController::ColorChooserUIController(
LocalFrame* frame,
blink::ColorChooserClient* client)
- : client_(client), frame_(frame) {}
+ : client_(client),
+ frame_(frame),
+ receiver_(this, frame->DomWindow()->GetExecutionContext()) {}
-ColorChooserUIController::~ColorChooserUIController() {}
+ColorChooserUIController::~ColorChooserUIController() = default;
void ColorChooserUIController::Trace(Visitor* visitor) {
+ visitor->Trace(receiver_);
visitor->Trace(frame_);
visitor->Trace(client_);
ColorChooser::Trace(visitor);
}
-void ColorChooserUIController::Dispose() {
- receiver_.reset();
-}
-
void ColorChooserUIController::OpenUI() {
OpenColorChooser();
}
@@ -80,8 +80,10 @@ void ColorChooserUIController::OpenColorChooser() {
color_chooser_factory_.BindNewPipeAndPassReceiver());
color_chooser_factory_->OpenColorChooser(
chooser_.BindNewPipeAndPassReceiver(),
- receiver_.BindNewPipeAndPassRemote(), client_->CurrentColor().Rgb(),
- client_->Suggestions());
+ receiver_.BindNewPipeAndPassRemote(
+ frame_->DomWindow()->GetExecutionContext()->GetTaskRunner(
+ TaskType::kUserInteraction)),
+ client_->CurrentColor().Rgb(), client_->Suggestions());
receiver_.set_disconnect_handler(WTF::Bind(
&ColorChooserUIController::EndChooser, WrapWeakPersistent(this)));
}
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 6d0012ac143..69168e082da 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
@@ -27,12 +27,13 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_COLOR_CHOOSER_UI_CONTROLLER_H_
#include <memory>
-#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/choosers/color_chooser.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/html/forms/color_chooser.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_wrapper_mode.h"
#include "third_party/blink/renderer/platform/text/platform_locale.h"
namespace blink {
@@ -45,7 +46,6 @@ class CORE_EXPORT ColorChooserUIController
public mojom::blink::ColorChooserClient,
public ColorChooser {
USING_GARBAGE_COLLECTED_MIXIN(ColorChooserUIController);
- USING_PRE_FINALIZER(ColorChooserUIController, Dispose);
public:
ColorChooserUIController(LocalFrame*, blink::ColorChooserClient*);
@@ -73,7 +73,9 @@ class CORE_EXPORT ColorChooserUIController
private:
mojo::Remote<mojom::blink::ColorChooserFactory> color_chooser_factory_;
- mojo::Receiver<mojom::blink::ColorChooserClient> receiver_{this};
+ HeapMojoReceiver<mojom::blink::ColorChooserClient,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ receiver_;
};
} // namespace blink
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 60a03ab4a07..75a2290469c 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
@@ -45,6 +45,7 @@
#include "third_party/blink/renderer/core/html/forms/html_option_element.h"
#include "third_party/blink/renderer/core/html/html_div_element.h"
#include "third_party/blink/renderer/core/input_type_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/page/chrome_client.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -52,6 +53,7 @@
#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/wtf_string.h"
+#include "ui/base/ui_base_features.h"
namespace blink {
@@ -150,7 +152,7 @@ void ColorInputType::HandleDOMActivateEvent(Event& event) {
return;
ChromeClient* chrome_client = GetChromeClient();
- if (chrome_client && !chooser_) {
+ if (chrome_client && !HasOpenedPopup()) {
UseCounter::Count(
document,
(event.UnderlyingEvent() && event.UnderlyingEvent()->isTrusted())
@@ -158,13 +160,23 @@ void ColorInputType::HandleDOMActivateEvent(Event& event) {
: WebFeature::kColorInputTypeChooserByUntrustedClick);
chooser_ = chrome_client->OpenColorChooser(document.GetFrame(), this,
ValueAsColor());
+ if (::features::IsFormControlsRefreshEnabled() &&
+ GetElement().GetLayoutObject()) {
+ // Invalidate paint to ensure that the focus ring is removed.
+ GetElement().GetLayoutObject()->SetShouldDoFullPaintInvalidation();
+ }
}
event.SetDefaultHandled();
}
void ColorInputType::ClosePopupView() {
- EndColorChooser();
+ if (chooser_)
+ chooser_->EndChooser();
+}
+
+bool ColorInputType::HasOpenedPopup() const {
+ return chooser_;
}
bool ColorInputType::ShouldRespectListAttribute() {
@@ -176,7 +188,7 @@ bool ColorInputType::TypeMismatchFor(const String& value) const {
}
void ColorInputType::WarnIfValueIsInvalid(const String& value) const {
- if (!DeprecatedEqualIgnoringCase(value, GetElement().SanitizeValue(value)))
+ if (!EqualIgnoringASCIICase(value, GetElement().SanitizeValue(value)))
AddWarningToConsole(
"The specified value %s does not conform to the required format. The "
"format is \"#rrggbb\" where rr, gg, bb are two-digit hexadecimal "
@@ -203,11 +215,11 @@ void ColorInputType::DidEndChooser() {
if (LayoutTheme::GetTheme().IsModalColorChooser())
GetElement().EnqueueChangeEvent();
chooser_.Clear();
-}
-
-void ColorInputType::EndColorChooser() {
- if (chooser_)
- chooser_->EndChooser();
+ if (::features::IsFormControlsRefreshEnabled() &&
+ GetElement().GetLayoutObject()) {
+ // Invalidate paint to ensure that the focus ring is shown.
+ GetElement().GetLayoutObject()->SetShouldDoFullPaintInvalidation();
+ }
}
void ColorInputType::UpdateView() {
@@ -275,4 +287,5 @@ ColorChooserClient* ColorInputType::GetColorChooserClient() {
return this;
}
+
} // namespace blink
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 19cfe68ddb0..2e75cb058aa 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
@@ -72,6 +72,7 @@ class ColorInputType final : public InputType,
void DidSetValue(const String&, bool value_changed) override;
void HandleDOMActivateEvent(Event&) override;
void ClosePopupView() override;
+ bool HasOpenedPopup() const override;
bool ShouldRespectListAttribute() override;
bool TypeMismatchFor(const String&) const override;
void WarnIfValueIsInvalid(const String&) const override;
@@ -79,7 +80,6 @@ class ColorInputType final : public InputType,
AXObject* PopupRootAXObject() override;
Color ValueAsColor() const;
- void EndColorChooser();
HTMLElement* ShadowColorSwatch() const;
Member<ColorChooser> chooser_;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/date_input_type.cc
index 4eb86fe8704..b0008e357be 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/date_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/date_input_type.cc
@@ -134,4 +134,8 @@ bool DateInputType::IsValidFormat(bool has_year,
return has_year && has_month && has_day;
}
+String DateInputType::AriaRoleForPickerIndicator() const {
+ return GetLocale().QueryString(IDS_AX_CALENDAR_SHOW_DATE_PICKER);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/date_input_type.h
index 24bac539a94..e2758b1e561 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/date_input_type.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/date_input_type.h
@@ -60,6 +60,7 @@ class DateInputType final : public BaseTemporalInputType {
bool has_hour,
bool has_minute,
bool has_second) const override;
+ String AriaRoleForPickerIndicator() const override;
};
} // namespace blink
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 ab96006c6cd..beb631c63c6 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
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/core/html/forms/date_time_chooser_impl.h"
+#include "build/build_config.h"
#include "third_party/blink/public/mojom/choosers/date_time_chooser.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/strings/grit/blink_strings.h"
@@ -46,6 +47,7 @@
#include "third_party/blink/renderer/platform/language.h"
#include "third_party/blink/renderer/platform/text/date_components.h"
#include "third_party/blink/renderer/platform/text/platform_locale.h"
+#include "ui/base/ui_base_features.h"
namespace blink {
@@ -124,11 +126,11 @@ void DateTimeChooserImpl::WriteDocument(SharedBuffer* data) {
AddString("<!DOCTYPE html><head><meta charset='UTF-8'><style>\n", data);
data->Append(ChooserResourceLoader::GetPickerCommonStyleSheet());
- if (!RuntimeEnabledFeatures::FormControlsRefreshEnabled())
+ if (!features::IsFormControlsRefreshEnabled())
data->Append(ChooserResourceLoader::GetPickerButtonStyleSheet());
data->Append(ChooserResourceLoader::GetSuggestionPickerStyleSheet());
data->Append(ChooserResourceLoader::GetCalendarPickerStyleSheet());
- if (RuntimeEnabledFeatures::FormControlsRefreshEnabled()) {
+ if (features::IsFormControlsRefreshEnabled()) {
data->Append(ChooserResourceLoader::GetCalendarPickerRefreshStyleSheet());
if (parameters_->type == input_type_names::kTime ||
parameters_->type == input_type_names::kDatetimeLocal) {
@@ -168,6 +170,16 @@ void DateTimeChooserImpl::WriteDocument(SharedBuffer* data) {
AddProperty("axShowPreviousMonth",
GetLocale().QueryString(IDS_AX_CALENDAR_SHOW_PREVIOUS_MONTH),
data);
+ AddProperty("axHourLabel", GetLocale().QueryString(IDS_AX_HOUR_FIELD_TEXT),
+ data);
+ AddProperty("axMinuteLabel",
+ GetLocale().QueryString(IDS_AX_MINUTE_FIELD_TEXT), data);
+ AddProperty("axSecondLabel",
+ GetLocale().QueryString(IDS_AX_SECOND_FIELD_TEXT), data);
+ AddProperty("axMillisecondLabel",
+ GetLocale().QueryString(IDS_AX_MILLISECOND_FIELD_TEXT), data);
+ AddProperty("axAmPmLabel", GetLocale().QueryString(IDS_AX_AM_PM_FIELD_TEXT),
+ data);
AddProperty("weekStartDay", locale_->FirstDayOfWeek(), data);
AddProperty("shortMonthLabels", locale_->ShortMonthLabels(), data);
AddProperty("dayLabels", locale_->WeekDayShortLabels(), data);
@@ -175,7 +187,11 @@ void DateTimeChooserImpl::WriteDocument(SharedBuffer* data) {
AddProperty("isLocaleRTL", locale_->IsRTL(), data);
AddProperty("isRTL", parameters_->is_anchor_element_rtl, data);
AddProperty("isFormControlsRefreshEnabled",
- RuntimeEnabledFeatures::FormControlsRefreshEnabled(), data);
+ features::IsFormControlsRefreshEnabled(), data);
+#if defined(OS_MACOSX)
+ AddProperty("isBorderTransparent", features::IsFormControlsRefreshEnabled(),
+ data);
+#endif
AddProperty("mode", parameters_->type.GetString(), data);
AddProperty("isAMPMFirst", parameters_->is_ampm_first, data);
AddProperty("hasAMPM", parameters_->has_ampm, data);
@@ -224,7 +240,7 @@ void DateTimeChooserImpl::WriteDocument(SharedBuffer* data) {
data->Append(ChooserResourceLoader::GetPickerCommonJS());
data->Append(ChooserResourceLoader::GetSuggestionPickerJS());
- if (RuntimeEnabledFeatures::FormControlsRefreshEnabled()) {
+ if (features::IsFormControlsRefreshEnabled()) {
data->Append(ChooserResourceLoader::GetMonthPickerJS());
if (parameters_->type == input_type_names::kTime) {
data->Append(ChooserResourceLoader::GetTimePickerJS());
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 1f9602acd70..22bca47ad27 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
@@ -60,7 +60,6 @@ class CORE_EXPORT DateTimeChooserImpl final : public DateTimeChooser,
private:
// PagePopupClient functions:
void WriteDocument(SharedBuffer*) override;
- void SelectFontsFromOwnerDocument(Document&) override {}
Locale& GetLocale() override;
void SetValueAndClosePopup(int, const String&) override;
void SetValue(const String&) override;
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 3e0d42db81c..a22fc3b2088 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
@@ -75,7 +75,7 @@ class DateTimeEditBuilder : private DateTimeFormat::TokenHandler {
DateTimeEditElement& EditElement() const;
- Member<DateTimeEditElement> edit_element_;
+ DateTimeEditElement* edit_element_;
const DateComponents date_value_;
const DateTimeEditElement::LayoutParameters& parameters_;
DateTimeNumericFieldElement::Range day_range_;
@@ -574,8 +574,7 @@ void DateTimeEditElement::BlurByOwner() {
scoped_refptr<ComputedStyle> DateTimeEditElement::CustomStyleForLayoutObject() {
// FIXME: This is a kind of layout. We might want to introduce new
// layoutObject.
- scoped_refptr<ComputedStyle> original_style = OriginalStyleForLayoutObject();
- scoped_refptr<ComputedStyle> style = ComputedStyle::Clone(*original_style);
+ scoped_refptr<ComputedStyle> style = OriginalStyleForLayoutObject();
float width = 0;
for (Node* child = FieldsWrapperElement()->firstChild(); child;
child = child->nextSibling()) {
@@ -598,12 +597,12 @@ scoped_refptr<ComputedStyle> DateTimeEditElement::CustomStyleForLayoutObject() {
return style;
}
-void DateTimeEditElement::DidBlurFromField(WebFocusType focus_type) {
+void DateTimeEditElement::DidBlurFromField(mojom::blink::FocusType focus_type) {
if (edit_control_owner_)
edit_control_owner_->DidBlurFromControl(focus_type);
}
-void DateTimeEditElement::DidFocusOnField(WebFocusType focus_type) {
+void DateTimeEditElement::DidFocusOnField(mojom::blink::FocusType focus_type) {
if (edit_control_owner_)
edit_control_owner_->DidFocusOnControl(focus_type);
}
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 ba1e86be80c..b241d8d00df 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
@@ -27,7 +27,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_DATE_TIME_EDIT_ELEMENT_H_
#include "base/macros.h"
-#include "third_party/blink/public/platform/web_focus_type.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/html/forms/date_time_field_element.h"
#include "third_party/blink/renderer/core/html/forms/step_range.h"
#include "third_party/blink/renderer/platform/text/date_components.h"
@@ -54,8 +54,8 @@ class DateTimeEditElement final : public HTMLDivElement,
class EditControlOwner : public GarbageCollectedMixin {
public:
virtual ~EditControlOwner();
- virtual void DidBlurFromControl(WebFocusType) = 0;
- virtual void DidFocusOnControl(WebFocusType) = 0;
+ virtual void DidBlurFromControl(mojom::blink::FocusType) = 0;
+ virtual void DidFocusOnControl(mojom::blink::FocusType) = 0;
virtual void EditControlValueChanged() = 0;
virtual String FormatDateTimeFieldsState(
const DateTimeFieldsState&) const = 0;
@@ -143,8 +143,8 @@ class DateTimeEditElement final : public HTMLDivElement,
bool IsDateTimeEditElement() const override;
// DateTimeFieldElement::FieldOwner functions.
- void DidBlurFromField(WebFocusType) override;
- void DidFocusOnField(WebFocusType) override;
+ void DidBlurFromField(mojom::blink::FocusType) override;
+ void DidFocusOnField(mojom::blink::FocusType) override;
void FieldValueChanged() override;
bool FocusOnNextField(const DateTimeFieldElement&) override;
bool FocusOnPreviousField(const DateTimeFieldElement&) override;
@@ -159,12 +159,6 @@ class DateTimeEditElement final : public HTMLDivElement,
DISALLOW_COPY_AND_ASSIGN(DateTimeEditElement);
};
-DEFINE_TYPE_CASTS(DateTimeEditElement,
- Element,
- element,
- element->IsDateTimeEditElement(),
- element.IsDateTimeEditElement());
-
template <>
struct DowncastTraits<DateTimeEditElement> {
static bool AllowFrom(const Element& element) {
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 e60c7175803..13dbe846f5b 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
@@ -55,20 +55,19 @@ float DateTimeFieldElement::ComputeTextWidth(const ComputedStyle& style,
}
void DateTimeFieldElement::DefaultEventHandler(Event& event) {
- if (event.IsKeyboardEvent()) {
- auto& keyboard_event = ToKeyboardEvent(event);
+ if (auto* keyboard_event = DynamicTo<KeyboardEvent>(event)) {
if (!IsDisabled() && !IsFieldOwnerDisabled() && !IsFieldOwnerReadOnly()) {
- HandleKeyboardEvent(keyboard_event);
- if (keyboard_event.DefaultHandled()) {
+ HandleKeyboardEvent(*keyboard_event);
+ if (keyboard_event->DefaultHandled()) {
if (field_owner_)
field_owner_->FieldDidChangeValueByKeyboard();
return;
}
}
- DefaultKeyboardEventHandler(keyboard_event);
+ DefaultKeyboardEventHandler(*keyboard_event);
if (field_owner_)
field_owner_->FieldDidChangeValueByKeyboard();
- if (keyboard_event.DefaultHandled())
+ if (keyboard_event->DefaultHandled())
return;
}
@@ -130,7 +129,8 @@ void DateTimeFieldElement::DefaultKeyboardEventHandler(
}
}
-void DateTimeFieldElement::SetFocused(bool value, WebFocusType focus_type) {
+void DateTimeFieldElement::SetFocused(bool value,
+ mojom::blink::FocusType focus_type) {
if (field_owner_) {
if (value) {
field_owner_->DidFocusOnField(focus_type);
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 ca56250f6d2..80abb99baa9 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
@@ -27,7 +27,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_DATE_TIME_FIELD_ELEMENT_H_
#include "base/macros.h"
-#include "third_party/blink/public/platform/web_focus_type.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/html/html_div_element.h"
#include "third_party/blink/renderer/core/html/html_span_element.h"
@@ -61,8 +61,8 @@ class DateTimeFieldElement : public HTMLSpanElement {
class FieldOwner : public GarbageCollectedMixin {
public:
virtual ~FieldOwner();
- virtual void DidBlurFromField(WebFocusType) = 0;
- virtual void DidFocusOnField(WebFocusType) = 0;
+ virtual void DidBlurFromField(mojom::blink::FocusType) = 0;
+ virtual void DidFocusOnField(mojom::blink::FocusType) = 0;
virtual void FieldValueChanged() = 0;
virtual bool FocusOnNextField(const DateTimeFieldElement&) = 0;
virtual bool FocusOnPreviousField(const DateTimeFieldElement&) = 0;
@@ -108,7 +108,7 @@ class DateTimeFieldElement : public HTMLSpanElement {
virtual int ValueForARIAValueNow() const;
// Node functions.
- void SetFocused(bool, WebFocusType) override;
+ void SetFocused(bool, mojom::blink::FocusType) override;
private:
void DefaultKeyboardEventHandler(KeyboardEvent&);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_time_local_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/date_time_local_input_type.cc
index 1fb0cb7203c..eb50355f5a2 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/date_time_local_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/date_time_local_input_type.cc
@@ -191,4 +191,8 @@ bool DateTimeLocalInputType::IsValidFormat(bool has_year,
return has_year && has_month && has_day && has_ampm && has_hour && has_minute;
}
+String DateTimeLocalInputType::AriaRoleForPickerIndicator() const {
+ return GetLocale().QueryString(IDS_AX_CALENDAR_SHOW_DATE_TIME_LOCAL_PICKER);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_time_local_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/date_time_local_input_type.h
index 65428f6a7ed..01a9e573efc 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/date_time_local_input_type.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/date_time_local_input_type.h
@@ -67,6 +67,7 @@ class DateTimeLocalInputType final : public BaseTemporalInputType {
bool has_hour,
bool has_minute,
bool has_second) const override;
+ String AriaRoleForPickerIndicator() const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_time_numeric_field_element.cc b/chromium/third_party/blink/renderer/core/html/forms/date_time_numeric_field_element.cc
index 3d15ec0fdce..68cc7e418b7 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/date_time_numeric_field_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/date_time_numeric_field_element.cc
@@ -94,8 +94,9 @@ int DateTimeNumericFieldElement::DefaultValueForStepUp() const {
return range_.minimum;
}
-void DateTimeNumericFieldElement::SetFocused(bool value,
- WebFocusType focus_type) {
+void DateTimeNumericFieldElement::SetFocused(
+ bool value,
+ mojom::blink::FocusType focus_type) {
if (!value) {
int type_ahead_value = TypeAheadValue();
type_ahead_buffer_.Clear();
diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_time_numeric_field_element.h b/chromium/third_party/blink/renderer/core/html/forms/date_time_numeric_field_element.h
index 1f7dd54292e..02c576c9ed0 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/date_time_numeric_field_element.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/date_time_numeric_field_element.h
@@ -27,7 +27,6 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_DATE_TIME_NUMERIC_FIELD_ELEMENT_H_
#include "base/macros.h"
-#include "third_party/blink/public/platform/web_focus_type.h"
#include "third_party/blink/renderer/core/html/forms/date_time_field_element.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
@@ -95,7 +94,7 @@ class DateTimeNumericFieldElement : public DateTimeFieldElement {
String Value() const final;
// Node functions.
- void SetFocused(bool, WebFocusType) final;
+ void SetFocused(bool, mojom::blink::FocusType) final;
String FormatValue(int) const;
int RoundUp(int) const;
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 8f61483d746..8ad4132abe3 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
@@ -26,6 +26,7 @@
#include "third_party/blink/renderer/core/html/forms/external_date_time_chooser.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
+#include "third_party/blink/public/platform/task_type.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/date_time_chooser_client.h"
@@ -57,23 +58,18 @@ static ui::mojom::TextInputType ToTextInputType(const AtomicString& source) {
ExternalDateTimeChooser::~ExternalDateTimeChooser() = default;
void ExternalDateTimeChooser::Trace(Visitor* visitor) {
+ visitor->Trace(date_time_chooser_);
visitor->Trace(client_);
DateTimeChooser::Trace(visitor);
}
ExternalDateTimeChooser::ExternalDateTimeChooser(DateTimeChooserClient* client)
- : client_(client) {
+ : date_time_chooser_(client->OwnerElement().GetExecutionContext()),
+ client_(client) {
DCHECK(!RuntimeEnabledFeatures::InputMultipleFieldsUIEnabled());
DCHECK(client);
}
-ExternalDateTimeChooser* ExternalDateTimeChooser::Create(
- DateTimeChooserClient* client) {
- ExternalDateTimeChooser* chooser =
- MakeGarbageCollected<ExternalDateTimeChooser>(client);
- return chooser;
-}
-
void ExternalDateTimeChooser::OpenDateTimeChooser(
LocalFrame* frame,
const DateTimeChooserParameters& parameters) {
@@ -108,12 +104,15 @@ bool ExternalDateTimeChooser::IsShowingDateTimeChooserUI() const {
mojom::blink::DateTimeChooser& ExternalDateTimeChooser::GetDateTimeChooser(
LocalFrame* frame) {
- if (!date_time_chooser_) {
+ if (!date_time_chooser_.is_bound()) {
frame->GetBrowserInterfaceBroker().GetInterface(
- date_time_chooser_.BindNewPipeAndPassReceiver());
+ date_time_chooser_.BindNewPipeAndPassReceiver(
+ // Per the spec, this is a user interaction.
+ // https://html.spec.whatwg.org/multipage/input.html#common-input-element-events
+ frame->GetTaskRunner(TaskType::kUserInteraction)));
}
- DCHECK(date_time_chooser_);
+ DCHECK(date_time_chooser_.is_bound());
return *date_time_chooser_.get();
}
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 ae2a00139fc..af6ff3007cf 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
@@ -26,10 +26,10 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_EXTERNAL_DATE_TIME_CHOOSER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_EXTERNAL_DATE_TIME_CHOOSER_H_
-#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/choosers/date_time_chooser.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/html/forms/date_time_chooser.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
namespace blink {
@@ -38,8 +38,6 @@ class LocalFrame;
class CORE_EXPORT ExternalDateTimeChooser final : public DateTimeChooser {
public:
- static ExternalDateTimeChooser* Create(DateTimeChooserClient*);
-
explicit ExternalDateTimeChooser(DateTimeChooserClient*);
~ExternalDateTimeChooser() override;
void Trace(Visitor*) override;
@@ -61,9 +59,9 @@ class CORE_EXPORT ExternalDateTimeChooser final : public DateTimeChooser {
mojom::blink::DateTimeChooser& GetDateTimeChooser(LocalFrame* frame);
- mojo::Remote<mojom::blink::DateTimeChooser> date_time_chooser_;
+ HeapMojoRemote<mojom::blink::DateTimeChooser> date_time_chooser_;
Member<DateTimeChooserClient> client_;
};
-}
+} // namespace blink
#endif
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 d47d454033b..4f705495a9b 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
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/html/forms/date_time_chooser_client.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
namespace blink {
@@ -64,7 +65,8 @@ TEST_F(ExternalDateTimeChooserTest, EndChooserShouldNotCrash) {
auto* document = MakeGarbageCollected<Document>();
auto* element = document->CreateRawElement(html_names::kInputTag);
auto* client = MakeGarbageCollected<TestDateTimeChooserClient>(element);
- auto* external_date_time_chooser = ExternalDateTimeChooser::Create(client);
+ auto* external_date_time_chooser =
+ MakeGarbageCollected<ExternalDateTimeChooser>(client);
client->SetDateTimeChooser(external_date_time_chooser);
external_date_time_chooser->ResponseHandler(true, 0);
}
@@ -77,7 +79,7 @@ TEST_F(ExternalDateTimeChooserTest, EndChooserShouldNotCrash) {
TEST_F(ExternalDateTimeChooserTest,
OpenDateTimeChooserShouldNotCrashWhenLabelAndValueIsTheSame) {
ScopedInputMultipleFieldsUIForTest input_multiple_fields_ui(false);
- GetDocument().documentElement()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().documentElement()->setInnerHTML(R"HTML(
<input id=test type="date" list="src" />
<datalist id="src">
<option value='2019-12-31'>Hint</option>
@@ -86,8 +88,8 @@ TEST_F(ExternalDateTimeChooserTest,
// value attribute.
</datalist>
)HTML");
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
+
GetDocument().View()->RunPostLifecycleSteps();
auto* input = To<HTMLInputElement>(GetDocument().getElementById("test"));
ASSERT_TRUE(input);
@@ -98,7 +100,8 @@ TEST_F(ExternalDateTimeChooserTest,
auto* client = MakeGarbageCollected<TestDateTimeChooserClient>(
GetDocument().documentElement());
- auto* external_date_time_chooser = ExternalDateTimeChooser::Create(client);
+ auto* external_date_time_chooser =
+ MakeGarbageCollected<ExternalDateTimeChooser>(client);
client->SetDateTimeChooser(external_date_time_chooser);
external_date_time_chooser->OpenDateTimeChooser(GetDocument().GetFrame(),
params);
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 b86f742cbd4..f7aab03b544 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
@@ -31,9 +31,9 @@
#include "third_party/blink/renderer/core/html/forms/external_popup_menu.h"
#include "build/build_config.h"
+#include "third_party/blink/public/common/input/web_mouse_event.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_coalesced_input_event.h"
-#include "third_party/blink/public/platform/web_mouse_event.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/public/web/web_external_popup_menu.h"
#include "third_party/blink/public/web/web_local_frame_client.h"
@@ -262,7 +262,7 @@ void ExternalPopupMenu::GetPopupMenuInfo(WebPopupMenuInfo& info,
}
popup_item.enabled = !item_element.IsDisabledFormControl();
const ComputedStyle& style = *owner_element.ItemComputedStyle(item_element);
- popup_item.text_direction = ToWebTextDirection(style.Direction());
+ popup_item.text_direction = ToBaseTextDirection(style.Direction());
popup_item.has_text_direction_override = IsOverride(style.GetUnicodeBidi());
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu_test.cc b/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu_test.cc
index 383f6a853c8..a493fa8b0c7 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu_test.cc
@@ -17,7 +17,7 @@
#include "third_party/blink/renderer/core/html/forms/html_select_element.h"
#include "third_party/blink/renderer/core/html/forms/popup_menu.h"
#include "third_party/blink/renderer/core/html_names.h"
-#include "third_party/blink/renderer/core/layout/layout_menu_list.h"
+#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
@@ -35,12 +35,12 @@ class ExternalPopupMenuDisplayNoneItemsTest : public PageTestBase {
PageTestBase::SetUp();
auto* element = MakeGarbageCollected<HTMLSelectElement>(GetDocument());
// Set the 4th an 5th items to have "display: none" property
- element->SetInnerHTMLFromString(
+ element->setInnerHTML(
"<option><option><option><option style='display:none;'><option "
"style='display:none;'><option><option>");
GetDocument().body()->AppendChild(element, ASSERT_NO_EXCEPTION);
owner_element_ = element;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
}
Persistent<HTMLSelectElement> owner_element_;
@@ -117,7 +117,7 @@ class ExternalPopupMenuTest : public testing::Test {
frame_test_helpers::LoadFrame(MainFrame(), base_url_ + file_name);
WebView()->MainFrameWidget()->Resize(WebSize(800, 600));
WebView()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
}
WebViewImpl* WebView() const { return helper_.GetWebView(); }
@@ -138,16 +138,16 @@ TEST_F(ExternalPopupMenuTest, PopupAccountsForVisualViewportTransform) {
WebView()->MainFrameWidget()->Resize(WebSize(100, 100));
WebView()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
auto* select = To<HTMLSelectElement>(
MainFrame()->GetFrame()->GetDocument()->getElementById("select"));
- LayoutMenuList* menu_list = ToLayoutMenuList(select->GetLayoutObject());
- ASSERT_TRUE(menu_list);
+ auto* layout_object = select->GetLayoutObject();
+ ASSERT_TRUE(layout_object);
VisualViewport& visual_viewport = WebView()->GetPage()->GetVisualViewport();
- IntRect rect_in_document = menu_list->AbsoluteBoundingBoxRect();
+ IntRect rect_in_document = layout_object->AbsoluteBoundingBoxRect();
constexpr int kScaleFactor = 2;
ScrollOffset scroll_delta(20, 30);
@@ -171,17 +171,17 @@ TEST_F(ExternalPopupMenuTest, DidAcceptIndex) {
auto* select = To<HTMLSelectElement>(
MainFrame()->GetFrame()->GetDocument()->getElementById("select"));
- LayoutMenuList* menu_list = ToLayoutMenuList(select->GetLayoutObject());
- ASSERT_TRUE(menu_list);
+ auto* layout_object = select->GetLayoutObject();
+ ASSERT_TRUE(layout_object);
select->ShowPopup();
ASSERT_TRUE(select->PopupIsVisible());
WebExternalPopupMenuClient* client =
- static_cast<ExternalPopupMenu*>(select->Popup());
+ static_cast<ExternalPopupMenu*>(select->PopupForTesting());
client->DidAcceptIndex(2);
EXPECT_FALSE(select->PopupIsVisible());
- ASSERT_EQ("2", menu_list->GetText().Utf8());
+ ASSERT_EQ("2", select->InnerElement().innerText().Utf8());
EXPECT_EQ(2, select->selectedIndex());
}
@@ -191,19 +191,19 @@ TEST_F(ExternalPopupMenuTest, DidAcceptIndices) {
auto* select = To<HTMLSelectElement>(
MainFrame()->GetFrame()->GetDocument()->getElementById("select"));
- LayoutMenuList* menu_list = ToLayoutMenuList(select->GetLayoutObject());
- ASSERT_TRUE(menu_list);
+ auto* layout_object = select->GetLayoutObject();
+ ASSERT_TRUE(layout_object);
select->ShowPopup();
ASSERT_TRUE(select->PopupIsVisible());
WebExternalPopupMenuClient* client =
- static_cast<ExternalPopupMenu*>(select->Popup());
+ static_cast<ExternalPopupMenu*>(select->PopupForTesting());
int indices[] = {2};
WebVector<int> indices_vector(indices, 1);
client->DidAcceptIndices(indices_vector);
EXPECT_FALSE(select->PopupIsVisible());
- EXPECT_EQ("2", menu_list->GetText());
+ EXPECT_EQ("2", select->InnerElement().innerText());
EXPECT_EQ(2, select->selectedIndex());
}
@@ -213,14 +213,14 @@ TEST_F(ExternalPopupMenuTest, DidAcceptIndicesClearSelect) {
auto* select = To<HTMLSelectElement>(
MainFrame()->GetFrame()->GetDocument()->getElementById("select"));
- LayoutMenuList* menu_list = ToLayoutMenuList(select->GetLayoutObject());
- ASSERT_TRUE(menu_list);
+ auto* layout_object = select->GetLayoutObject();
+ ASSERT_TRUE(layout_object);
select->ShowPopup();
ASSERT_TRUE(select->PopupIsVisible());
WebExternalPopupMenuClient* client =
- static_cast<ExternalPopupMenu*>(select->Popup());
+ static_cast<ExternalPopupMenu*>(select->PopupForTesting());
WebVector<int> indices;
client->DidAcceptIndices(indices);
EXPECT_FALSE(select->PopupIsVisible());
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 5e07aa092bd..62d3be9b859 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
@@ -24,7 +24,6 @@
#include "third_party/blink/public/platform/file_path_conversion.h"
#include "third_party/blink/public/strings/grit/blink_strings.h"
-#include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/events/keyboard_event.h"
@@ -34,10 +33,12 @@
#include "third_party/blink/renderer/core/html/forms/form_controller.h"
#include "third_party/blink/renderer/core/html/forms/form_data.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
+#include "third_party/blink/renderer/core/html/shadow/shadow_element_names.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/core/inspector/console_message.h"
-#include "third_party/blink/renderer/core/layout/layout_file_upload_control.h"
+#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
+#include "third_party/blink/renderer/core/layout/layout_object_factory.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/drag_data.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
@@ -162,9 +163,9 @@ void FileInputType::HandleDOMActivateEvent(Event& event) {
if (!LocalFrame::HasTransientUserActivation(document.GetFrame())) {
String message =
"File chooser dialog can only be shown with a user activation.";
- document.AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning, message));
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning, message));
return;
}
@@ -202,9 +203,18 @@ void FileInputType::HandleDOMActivateEvent(Event& event) {
event.SetDefaultHandled();
}
-LayoutObject* FileInputType::CreateLayoutObject(const ComputedStyle&,
- LegacyLayout) const {
- return new LayoutFileUploadControl(&GetElement());
+void FileInputType::CustomStyleForLayoutObject(ComputedStyle& style) {
+ style.SetShouldIgnoreOverflowPropertyForInlineBlockBaseline();
+}
+
+bool FileInputType::TypeShouldForceLegacyLayout() const {
+ return !RuntimeEnabledFeatures::LayoutNGForControlsEnabled();
+}
+
+LayoutObject* FileInputType::CreateLayoutObject(const ComputedStyle& style,
+ LegacyLayout legacy) const {
+ return LayoutObjectFactory::CreateFileUploadControl(GetElement(), style,
+ legacy);
}
InputType::ValueMode FileInputType::GetValueMode() const {
@@ -249,10 +259,8 @@ void FileInputType::SetValue(const String&,
return;
file_list_->clear();
- GetElement().SetNeedsStyleRecalc(
- kSubtreeStyleChange,
- StyleChangeReasonForTracing::Create(style_change_reason::kControlValue));
GetElement().SetNeedsValidityCheck();
+ UpdateView();
}
FileList* FileInputType::CreateFileList(const FileChooserFileInfoList& files,
@@ -317,8 +325,10 @@ void FileInputType::CountUsage() {
void FileInputType::CreateShadowSubtree() {
DCHECK(IsShadowHost(GetElement()));
- auto* button = MakeGarbageCollected<HTMLInputElement>(
- GetElement().GetDocument(), CreateElementFlags());
+ Document& document = GetElement().GetDocument();
+
+ auto* button =
+ MakeGarbageCollected<HTMLInputElement>(document, CreateElementFlags());
button->setType(input_type_names::kButton);
button->setAttribute(
html_names::kValueAttr,
@@ -326,25 +336,43 @@ void FileInputType::CreateShadowSubtree() {
GetElement().Multiple() ? IDS_FORM_MULTIPLE_FILES_BUTTON_LABEL
: IDS_FORM_FILE_BUTTON_LABEL)));
button->SetShadowPseudoId(AtomicString("-webkit-file-upload-button"));
+ button->setAttribute(html_names::kIdAttr,
+ shadow_element_names::FileUploadButton());
+ button->SetActive(GetElement().CanReceiveDroppedFiles());
GetElement().UserAgentShadowRoot()->AppendChild(button);
+
+ // The following element is used only in LayoutNG.
+ // See LayoutFileUploadControl::IsChildAllowed().
+ auto* span = document.CreateRawElement(html_names::kSpanTag);
+ // This element is hidden from AX trees for a historical reason.
+ span->setAttribute(html_names::kAriaHiddenAttr, "true");
+ GetElement().UserAgentShadowRoot()->AppendChild(span);
+
+ UpdateView();
+}
+
+HTMLInputElement* FileInputType::UploadButton() const {
+ Element* element = GetElement().UserAgentShadowRoot()->getElementById(
+ shadow_element_names::FileUploadButton());
+ CHECK(!element || IsA<HTMLInputElement>(element));
+ return To<HTMLInputElement>(element);
+}
+
+Node* FileInputType::FileStatusElement() const {
+ return GetElement().UserAgentShadowRoot()->lastChild();
}
void FileInputType::DisabledAttributeChanged() {
DCHECK(IsShadowHost(GetElement()));
- CHECK(!GetElement().UserAgentShadowRoot()->firstChild() ||
- IsA<Element>(GetElement().UserAgentShadowRoot()->firstChild()));
- if (Element* button =
- To<Element>(GetElement().UserAgentShadowRoot()->firstChild()))
+ if (Element* button = UploadButton()) {
button->SetBooleanAttribute(html_names::kDisabledAttr,
GetElement().IsDisabledFormControl());
+ }
}
void FileInputType::MultipleAttributeChanged() {
DCHECK(IsShadowHost(GetElement()));
- CHECK(!GetElement().UserAgentShadowRoot()->firstChild() ||
- IsA<Element>(GetElement().UserAgentShadowRoot()->firstChild()));
- if (Element* button =
- To<Element>(GetElement().UserAgentShadowRoot()->firstChild())) {
+ if (Element* button = UploadButton()) {
button->setAttribute(
html_names::kValueAttr,
AtomicString(GetLocale().QueryString(
@@ -373,10 +401,7 @@ bool FileInputType::SetFiles(FileList* files) {
GetElement().NotifyFormStateChanged();
GetElement().SetNeedsValidityCheck();
-
- if (GetElement().GetLayoutObject())
- GetElement().GetLayoutObject()->SetShouldDoFullPaintInvalidation();
-
+ UpdateView();
return files_changed;
}
@@ -520,4 +545,27 @@ void FileInputType::WillOpenPopup() {
}
}
+String FileInputType::FileStatusText() const {
+ Locale& locale = GetLocale();
+
+ if (file_list_->IsEmpty())
+ return locale.QueryString(IDS_FORM_FILE_NO_FILE_LABEL);
+
+ if (file_list_->length() == 1)
+ return LayoutTheme::GetTheme().DisplayNameForFile(*file_list_->item(0));
+
+ return locale.QueryString(
+ IDS_FORM_FILE_MULTIPLE_UPLOAD,
+ locale.ConvertToLocalizedNumber(String::Number(file_list_->length())));
+}
+
+void FileInputType::UpdateView() {
+ auto* layout_object = GetElement().GetLayoutObject();
+ if (layout_object && layout_object->IsFileUploadControl())
+ layout_object->SetShouldDoFullPaintInvalidation();
+
+ if (auto* span = FileStatusElement())
+ span->setTextContent(FileStatusText());
+}
+
} // namespace blink
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 256a75272dd..425bf6b8226 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
@@ -72,6 +72,8 @@ class CORE_EXPORT FileInputType final : public InputType,
bool ValueMissing(const String&) const override;
String ValueMissingText() const override;
void HandleDOMActivateEvent(Event&) override;
+ void CustomStyleForLayoutObject(ComputedStyle& style) override;
+ bool TypeShouldForceLegacyLayout() const override;
LayoutObject* CreateLayoutObject(const ComputedStyle&,
LegacyLayout) const override;
bool CanSetStringValue() const override;
@@ -88,10 +90,13 @@ class CORE_EXPORT FileInputType final : public InputType,
bool ReceiveDroppedFiles(const DragData*) override;
String DroppedFileSystemId() override;
void CreateShadowSubtree() override;
+ HTMLInputElement* UploadButton() const override;
void DisabledAttributeChanged() override;
void MultipleAttributeChanged() override;
String DefaultToolTip(const InputTypeView&) const override;
void CopyNonAttributeProperties(const HTMLInputElement&) override;
+ String FileStatusText() const override;
+ void UpdateView() override;
// KeyboardClickableInputTypeView overrides.
void HandleKeypressEvent(KeyboardEvent&) override;
@@ -106,6 +111,7 @@ class CORE_EXPORT FileInputType final : public InputType,
void WillOpenPopup() override;
void SetFilesFromDirectory(const String&);
+ Node* FileStatusElement() const;
Member<FileList> file_list_;
String dropped_file_system_id_;
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 3d30730b162..ebbb62c3b57 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
@@ -138,7 +138,7 @@ TEST(FileInputTypeTest, DropTouchesNoPopupOpeningObserver) {
std::make_unique<DummyPageHolder>(IntSize(), &page_clients);
Document& doc = page_holder->GetDocument();
- doc.body()->SetInnerHTMLFromString("<input type=file webkitdirectory>");
+ doc.body()->setInnerHTML("<input type=file webkitdirectory>");
auto& input = *To<HTMLInputElement>(doc.body()->firstChild());
base::RunLoop run_loop;
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 b9b161e40a4..681786d2c40 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
@@ -42,10 +42,6 @@ namespace blink {
namespace {
-// TODO(crbug.com/1008708): Remove this flag when we're sure the new behavior
-// is better than the previous one.
-constexpr bool kRestoreOnLoad = true;
-
inline HTMLFormElement* OwnerFormForState(const ListedElement& control) {
// Assume controls with form attribute have no owners because we restore
// state during parsing and form owners of such controls might be
@@ -62,8 +58,9 @@ const AtomicString& ControlType(const ListedElement& control) {
}
bool IsDirtyControl(const ListedElement& control) {
- if (control.IsFormControlElementWithState())
- return ToHTMLFormControlElementWithState(control).UserHasEditedTheField();
+ if (auto* form_control_element =
+ DynamicTo<HTMLFormControlElementWithState>(control))
+ return form_control_element->UserHasEditedTheField();
if (control.IsElementInternals()) {
// We have no ways to know the dirtiness of a form-associated custom
// element. Assume it is dirty if it has focus.
@@ -567,7 +564,7 @@ void FormController::WillDeleteForm(HTMLFormElement* form) {
}
void FormController::RestoreControlStateFor(ListedElement& control) {
- if (kRestoreOnLoad && !document_->HasFinishedParsing())
+ if (!document_->HasFinishedParsing())
return;
if (OwnerFormForState(control))
return;
@@ -575,7 +572,7 @@ void FormController::RestoreControlStateFor(ListedElement& control) {
}
void FormController::RestoreControlStateIn(HTMLFormElement& form) {
- if (kRestoreOnLoad && !document_->HasFinishedParsing())
+ if (!document_->HasFinishedParsing())
return;
EventQueueScope scope;
const ListedElement::List& elements = form.ListedElements();
@@ -619,8 +616,6 @@ void FormController::RestoreControlStateOnUpgrade(ListedElement& control) {
}
void FormController::ScheduleRestore() {
- if (!kRestoreOnLoad)
- return;
document_->GetTaskRunner(TaskType::kInternalLoading)
->PostTask(FROM_HERE,
WTF::Bind(&FormController::RestoreAllControlsInDocumentOrder,
@@ -628,8 +623,6 @@ void FormController::ScheduleRestore() {
}
void FormController::RestoreImmediately() {
- if (!kRestoreOnLoad)
- return;
if (did_restore_all_ || !HasControlStates())
return;
RestoreAllControlsInDocumentOrder();
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 b278e95decd..e54eefa6018 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
@@ -20,7 +20,7 @@ TEST(DocumentStateTest, ToStateVectorConnected) {
Element* html = doc.CreateRawElement(html_names::kHTMLTag);
doc.appendChild(html);
Node* body = html->appendChild(doc.CreateRawElement(html_names::kBodyTag));
- To<Element>(body)->SetInnerHTMLFromString("<select form='ff'></select>");
+ To<Element>(body)->setInnerHTML("<select form='ff'></select>");
DocumentState* document_state = doc.GetFormController().ControlStates();
Vector<String> state1 = document_state->ToStateVector();
// <signature>, <control-size>, <form-key>, <name>, <type>, <data-size(0)>
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 4ef6dba5b2d..1918cac770a 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
@@ -302,7 +302,7 @@ scoped_refptr<EncodedFormData> FormData::EncodeMultiPartFormData() {
auto* file = To<File>(entry->GetBlob());
// Do not add the file if the path is empty.
if (!file->GetPath().IsEmpty())
- form_data->AppendFile(file->GetPath());
+ form_data->AppendFile(file->GetPath(), file->LastModifiedTime());
} else {
form_data->AppendBlob(entry->GetBlob()->Uuid(),
entry->GetBlob()->GetBlobDataHandle());
diff --git a/chromium/third_party/blink/renderer/core/html/forms/form_data.idl b/chromium/third_party/blink/renderer/core/html/forms/form_data.idl
index 79c8e499142..cc98012eb62 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/form_data.idl
+++ b/chromium/third_party/blink/renderer/core/html/forms/form_data.idl
@@ -33,10 +33,9 @@
typedef (File or USVString) FormDataEntryValue;
[
- Constructor(optional HTMLFormElement form),
- RaisesException=Constructor,
Exposed=(Window,Worker)
] interface FormData {
+ [RaisesException] constructor(optional HTMLFormElement form);
void append(USVString name, USVString value);
[CallWith=ScriptState] void append(USVString name, Blob value, optional USVString filename);
[ImplementedAs=deleteEntry] void delete(USVString name);
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 9b077df8cc7..3e1d9bf0d70 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
@@ -4,9 +4,9 @@
#include "third_party/blink/renderer/core/html/forms/form_data_event.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_form_data_event_init.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
#include "third_party/blink/renderer/core/html/forms/form_data.h"
-#include "third_party/blink/renderer/core/html/forms/form_data_event_init.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/html/forms/form_data_event.idl b/chromium/third_party/blink/renderer/core/html/forms/form_data_event.idl
index 0b74add3f2a..84c7af0cc1e 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/form_data_event.idl
+++ b/chromium/third_party/blink/renderer/core/html/forms/form_data_event.idl
@@ -5,9 +5,8 @@
// https://html.spec.whatwg.org/C/#formdataevent
[
- Constructor(DOMString type, optional FormDataEventInit eventInitDict),
Exposed=Window
-]
-interface FormDataEvent : Event {
+] interface FormDataEvent : Event {
+ constructor(DOMString type, optional FormDataEventInit eventInitDict = {});
readonly attribute FormData formData;
};
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 ce51f88b4ca..f8fef662ad8 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
@@ -92,7 +92,7 @@ void HiddenInputType::SetValue(const String& sanitized_value,
}
void HiddenInputType::AppendToFormData(FormData& form_data) const {
- if (DeprecatedEqualIgnoringCase(GetElement().GetName(), "_charset_")) {
+ if (EqualIgnoringASCIICase(GetElement().GetName(), "_charset_")) {
form_data.AppendFromElement(GetElement().GetName(),
String(form_data.Encoding().GetName()));
return;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_button_element.cc b/chromium/third_party/blink/renderer/core/html/forms/html_button_element.cc
index 0171b21b096..e062da100d7 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_button_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_button_element.cc
@@ -27,7 +27,6 @@
#include "third_party/blink/renderer/core/dom/attribute.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/html/forms/form_data.h"
#include "third_party/blink/renderer/core/html/forms/html_form_element.h"
#include "third_party/blink/renderer/core/html_names.h"
@@ -45,8 +44,15 @@ void HTMLButtonElement::setType(const AtomicString& type) {
setAttribute(html_names::kTypeAttr, type);
}
-LayoutObject* HTMLButtonElement::CreateLayoutObject(const ComputedStyle&,
- LegacyLayout) {
+LayoutObject* HTMLButtonElement::CreateLayoutObject(const ComputedStyle& style,
+ LegacyLayout legacy) {
+ // https://html.spec.whatwg.org/C/#button-layout
+ EDisplay display = style.Display();
+ if (display == EDisplay::kInlineGrid || display == EDisplay::kGrid ||
+ display == EDisplay::kInlineFlex || display == EDisplay::kFlex ||
+ display == EDisplay::kInlineLayoutCustom ||
+ display == EDisplay::kLayoutCustom)
+ return HTMLFormControlElement::CreateLayoutObject(style, legacy);
return new LayoutButton(this);
}
@@ -84,9 +90,9 @@ bool HTMLButtonElement::IsPresentationAttribute(
void HTMLButtonElement::ParseAttribute(
const AttributeModificationParams& params) {
if (params.name == html_names::kTypeAttr) {
- if (DeprecatedEqualIgnoringCase(params.new_value, "reset"))
+ if (EqualIgnoringASCIICase(params.new_value, "reset"))
type_ = RESET;
- else if (DeprecatedEqualIgnoringCase(params.new_value, "button"))
+ else if (EqualIgnoringASCIICase(params.new_value, "button"))
type_ = BUTTON;
else
type_ = SUBMIT;
@@ -101,13 +107,6 @@ void HTMLButtonElement::ParseAttribute(
}
void HTMLButtonElement::DefaultEventHandler(Event& event) {
- DefaultEventHandlerInternal(event);
-
- if (event.type() == event_type_names::kDOMActivate && formOwner())
- formOwner()->DidActivateSubmitButton(this);
-}
-
-void HTMLButtonElement::DefaultEventHandlerInternal(Event& event) {
if (event.type() == event_type_names::kDOMActivate &&
!IsDisabledFormControl()) {
if (Form() && type_ == SUBMIT) {
@@ -120,33 +119,8 @@ void HTMLButtonElement::DefaultEventHandlerInternal(Event& event) {
}
}
- if (event.IsKeyboardEvent()) {
- if (event.type() == event_type_names::kKeydown &&
- ToKeyboardEvent(event).key() == " ") {
- SetActive(true);
- // No setDefaultHandled() - IE dispatches a keypress in this case.
- return;
- }
- if (event.type() == event_type_names::kKeypress) {
- switch (ToKeyboardEvent(event).charCode()) {
- case '\r':
- DispatchSimulatedClick(&event);
- event.SetDefaultHandled();
- return;
- case ' ':
- // Prevent scrolling down the page.
- event.SetDefaultHandled();
- return;
- }
- }
- if (event.type() == event_type_names::kKeyup &&
- ToKeyboardEvent(event).key() == " ") {
- if (IsActive())
- DispatchSimulatedClick(&event);
- event.SetDefaultHandled();
- return;
- }
- }
+ if (HandleKeyboardActivation(event))
+ return;
HTMLFormControlElement::DefaultEventHandler(event);
}
@@ -223,16 +197,4 @@ Node::InsertionNotificationRequest HTMLButtonElement::InsertedInto(
return request;
}
-EventDispatchHandlingState* HTMLButtonElement::PreDispatchEventHandler(
- Event& event) {
- if (Form() && CanBeSuccessfulSubmitButton())
- Form()->WillActivateSubmitButton(this);
- return nullptr;
-}
-
-void HTMLButtonElement::DidPreventDefault(const Event& event) {
- if (auto* form = formOwner())
- form->DidActivateSubmitButton(this);
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_button_element.h b/chromium/third_party/blink/renderer/core/html/forms/html_button_element.h
index 6071e0f1bc4..44437eeda26 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_button_element.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_button_element.h
@@ -78,13 +78,6 @@ class HTMLButtonElement final : public HTMLFormControlElement {
int DefaultTabIndex() const override;
- // TODO(crbug.com/1013385): Remove PreDispatchEventHandler, DidPreventDefault,
- // and DefaultEventHandlerInternal. They are here to temporarily fix form
- // double-submit.
- EventDispatchHandlingState* PreDispatchEventHandler(Event&) override;
- void DidPreventDefault(const Event&) final;
- void DefaultEventHandlerInternal(Event&);
-
Type type_;
bool is_activated_submit_;
};
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_data_list_element.cc b/chromium/third_party/blink/renderer/core/html/forms/html_data_list_element.cc
index d7faa3935f7..e6bfaae178f 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_data_list_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_data_list_element.cc
@@ -52,7 +52,7 @@ HTMLDataListOptionsCollection* HTMLDataListElement::options() {
void HTMLDataListElement::ChildrenChanged(const ChildrenChange& change) {
HTMLElement::ChildrenChanged(change);
- if (!change.by_parser) {
+ if (!change.ByParser()) {
GetTreeScope().GetIdTargetObserverRegistry().NotifyObservers(
GetIdAttribute());
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_data_list_element.h b/chromium/third_party/blink/renderer/core/html/forms/html_data_list_element.h
index 07460b9469e..84fb8779116 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_data_list_element.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_data_list_element.h
@@ -32,12 +32,11 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_HTML_DATA_LIST_ELEMENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_HTML_DATA_LIST_ELEMENT_H_
+#include "third_party/blink/renderer/core/html/forms/html_data_list_options_collection.h"
#include "third_party/blink/renderer/core/html/html_element.h"
namespace blink {
-class HTMLDataListOptionsCollection;
-
class CORE_EXPORT HTMLDataListElement final : public HTMLElement {
DEFINE_WRAPPERTYPEINFO();
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_data_list_options_collection.h b/chromium/third_party/blink/renderer/core/html/forms/html_data_list_options_collection.h
index 4b68f900289..94d5f68907e 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_data_list_options_collection.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_data_list_options_collection.h
@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/core/html/forms/html_option_element.h"
#include "third_party/blink/renderer/core/html/html_collection.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -28,11 +29,12 @@ class HTMLDataListOptionsCollection : public HTMLCollection {
bool ElementMatches(const HTMLElement&) const;
};
-DEFINE_TYPE_CASTS(HTMLDataListOptionsCollection,
- LiveNodeListBase,
- collection,
- collection->GetType() == kDataListOptions,
- collection.GetType() == kDataListOptions);
+template <>
+struct DowncastTraits<HTMLDataListOptionsCollection> {
+ static bool AllowFrom(const LiveNodeListBase& collection) {
+ return collection.GetType() == kDataListOptions;
+ }
+};
inline bool HTMLDataListOptionsCollection::ElementMatches(
const HTMLElement& element) const {
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_field_set_element.cc b/chromium/third_party/blink/renderer/core/html/forms/html_field_set_element.cc
index 4b63cb11b2a..e06b9e85ef3 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_field_set_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_field_set_element.cc
@@ -72,7 +72,7 @@ HTMLFieldSetElement::InvalidateDescendantDisabledStateAndFindFocusedOne(
{
EventDispatchForbiddenScope event_forbidden;
for (HTMLElement& element : Traversal<HTMLElement>::DescendantsOf(base)) {
- if (auto* control = ToHTMLFormControlElementOrNull(element))
+ if (auto* control = DynamicTo<HTMLFormControlElement>(element))
control->AncestorDisabledStateWasChanged();
else if (element.IsFormAssociatedCustomElement())
element.EnsureElementInternals().AncestorDisabledStateWasChanged();
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 1204ae261b3..7ef8db7a852 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
@@ -202,18 +202,6 @@ const AtomicString& HTMLFormControlElement::autocapitalize() const {
return g_empty_atom;
}
-void HTMLFormControlElement::AttachLayoutTree(AttachContext& context) {
- HTMLElement::AttachLayoutTree(context);
-
- if (!GetLayoutObject())
- return;
-
- // The call to updateFromElement() needs to go after the call through
- // to the base class's attachLayoutTree() because that can sometimes do a
- // close on the layoutObject.
- GetLayoutObject()->UpdateFromElement();
-}
-
void HTMLFormControlElement::DidMoveToNewDocument(Document& old_document) {
ListedElement::DidMoveToNewDocument(old_document);
HTMLElement::DidMoveToNewDocument(old_document);
@@ -243,10 +231,6 @@ void HTMLFormControlElement::DidChangeForm() {
formOwner()->InvalidateDefaultButtonStyle();
}
-void HTMLFormControlElement::DispatchChangeEvent() {
- DispatchScopedEvent(*Event::CreateBubble(event_type_names::kChange));
-}
-
HTMLFormElement* HTMLFormControlElement::formOwner() const {
return ListedElement::Form();
}
@@ -273,13 +257,6 @@ String HTMLFormControlElement::ResultForDialogSubmit() {
return FastGetAttribute(html_names::kValueAttr);
}
-void HTMLFormControlElement::DidRecalcStyle(const StyleRecalcChange change) {
- if (change.ReattachLayoutTree())
- return;
- if (LayoutObject* layout_object = GetLayoutObject())
- layout_object->UpdateFromElement();
-}
-
bool HTMLFormControlElement::SupportsFocus() const {
return !IsDisabledFormControl();
}
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 6761900c783..62c7a77395e 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
@@ -59,8 +59,6 @@ class CORE_EXPORT HTMLFormControlElement : public HTMLElement,
void Reset();
- void DispatchChangeEvent();
-
HTMLFormElement* formOwner() const final;
bool IsDisabledFormControl() const override;
@@ -137,7 +135,6 @@ class CORE_EXPORT HTMLFormControlElement : public HTMLElement,
void ParseAttribute(const AttributeModificationParams&) override;
virtual void RequiredAttributeChanged();
void DisabledAttributeChanged() override;
- void AttachLayoutTree(AttachContext&) override;
InsertionNotificationRequest InsertedInto(ContainerNode&) override;
void RemovedFrom(ContainerNode&) override;
void WillChangeForm() override;
@@ -146,9 +143,7 @@ class CORE_EXPORT HTMLFormControlElement : public HTMLElement,
bool SupportsFocus() const override;
bool IsKeyboardFocusable() const override;
- bool ShouldHaveFocusAppearance() const final;
-
- void DidRecalcStyle(const StyleRecalcChange) override;
+ bool ShouldHaveFocusAppearance() const override;
virtual void ResetImpl() {}
@@ -167,22 +162,24 @@ class CORE_EXPORT HTMLFormControlElement : public HTMLElement,
bool blocks_form_submission_ : 1;
};
-inline bool IsHTMLFormControlElement(const Element& element) {
- return element.IsFormControlElement();
+template <>
+inline bool IsElementOfType<const HTMLFormControlElement>(const Node& node) {
+ return IsA<HTMLFormControlElement>(node);
}
-
-DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLFormControlElement);
-
template <>
struct DowncastTraits<HTMLFormControlElement> {
static bool AllowFrom(const Node& node) {
- auto* element = DynamicTo<Element>(node);
- return element && element->IsFormControlElement();
+ auto* html_element = DynamicTo<HTMLElement>(node);
+ return html_element && AllowFrom(*html_element);
}
static bool AllowFrom(const ListedElement& control) {
return control.IsFormControlElement();
}
+ static bool AllowFrom(const HTMLElement& html_element) {
+ return html_element.IsFormControlElement();
+ }
};
+
} // namespace blink
#endif
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 da02126b3c2..db9caa6e8b2 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
@@ -133,7 +133,7 @@ TEST_F(HTMLFormControlElementTest, DoNotUpdateLayoutDuringDOMMutation) {
// ShowValidationMessage(). So calling it during DOM mutation is
// dangerous. This test ensures ShowValidationMessage() is NOT called in
// appendChild(). crbug.com/756408
- GetDocument().documentElement()->SetInnerHTMLFromString("<select></select>");
+ GetDocument().documentElement()->setInnerHTML("<select></select>");
auto* const select =
To<HTMLFormControlElement>(GetDocument().QuerySelector("select"));
auto* const optgroup =
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element_with_state.cc b/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element_with_state.cc
index 888e83b4120..f8f5337c034 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element_with_state.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element_with_state.cc
@@ -24,6 +24,7 @@
#include "third_party/blink/renderer/core/html/forms/html_form_control_element_with_state.h"
+#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/html/forms/html_form_element.h"
#include "third_party/blink/renderer/core/input_type_names.h"
@@ -275,6 +276,17 @@ bool HTMLFormControlElementWithState::ShouldSaveAndRestoreFormControlState()
return isConnected() && ShouldAutocomplete();
}
+void HTMLFormControlElementWithState::DispatchInputEvent() {
+ // Legacy 'input' event for forms set value and checked.
+ Event* event = Event::CreateBubble(event_type_names::kInput);
+ event->SetComposed(true);
+ DispatchScopedEvent(*event);
+}
+
+void HTMLFormControlElementWithState::DispatchChangeEvent() {
+ DispatchScopedEvent(*Event::CreateBubble(event_type_names::kChange));
+}
+
void HTMLFormControlElementWithState::FinishParsingChildren() {
HTMLFormControlElement::FinishParsingChildren();
ListedElement::TakeStateAndRestore();
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element_with_state.h b/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element_with_state.h
index 6f93afebb70..88b71eccf45 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element_with_state.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element_with_state.h
@@ -27,6 +27,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/html/forms/html_form_control_element.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -50,6 +51,9 @@ class CORE_EXPORT HTMLFormControlElementWithState
// This is only used in tests, to fake the user's action
void SetUserHasEditedTheFieldForTest() { user_has_edited_the_field_ = true; }
+ void DispatchInputEvent();
+ void DispatchChangeEvent();
+
protected:
bool user_has_edited_the_field_ = false;
HTMLFormControlElementWithState(const QualifiedName& tag_name, Document&);
@@ -58,18 +62,18 @@ class CORE_EXPORT HTMLFormControlElementWithState
bool IsFormControlElementWithState() const final;
private:
- bool TypeShouldForceLegacyLayout() const final { return true; }
int DefaultTabIndex() const override;
// https://html.spec.whatwg.org/C/#autofill-anchor-mantle
bool IsWearingAutofillAnchorMantle() const;
};
-DEFINE_TYPE_CASTS(HTMLFormControlElementWithState,
- ListedElement,
- control,
- control->IsFormControlElementWithState(),
- control.IsFormControlElementWithState());
+template <>
+struct DowncastTraits<HTMLFormControlElementWithState> {
+ static bool AllowFrom(const ListedElement& control) {
+ return control.IsFormControlElementWithState();
+ }
+};
} // namespace blink
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 8a33fc9fb8b..684265f7b26 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
@@ -68,11 +68,6 @@ class HTMLFormControlsCollection final : public HTMLCollection {
mutable Member<HTMLElement> cached_element_;
mutable unsigned cached_element_offset_in_array_;
};
-DEFINE_TYPE_CASTS(HTMLFormControlsCollection,
- LiveNodeListBase,
- collection,
- collection->GetType() == kFormControls,
- collection.GetType() == kFormControls);
} // namespace blink
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 0f277cd101a..aa0f521211e 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
@@ -28,10 +28,12 @@
#include <limits>
#include "base/auto_reset.h"
-#include "third_party/blink/public/platform/web_insecure_request_policy.h"
+#include "third_party/blink/public/common/security_context/insecure_request_policy.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/radio_node_list_or_element.h"
#include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
#include "third_party/blink/renderer/bindings/core/v8/script_event_listener.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_submit_event_init.h"
#include "third_party/blink/renderer/core/dom/attribute.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
@@ -51,6 +53,7 @@
#include "third_party/blink/renderer/core/html/forms/html_form_controls_collection.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/forms/radio_node_list.h"
+#include "third_party/blink/renderer/core/html/forms/submit_event.h"
#include "third_party/blink/renderer/core/html/html_collection.h"
#include "third_party/blink/renderer/core/html/html_dialog_element.h"
#include "third_party/blink/renderer/core/html/html_image_element.h"
@@ -89,8 +92,6 @@ void HTMLFormElement::Trace(Visitor* visitor) {
visitor->Trace(radio_button_group_scope_);
visitor->Trace(listed_elements_);
visitor->Trace(image_elements_);
- visitor->Trace(planned_navigation_);
- visitor->Trace(activated_submit_button_);
HTMLElement::Trace(visitor);
}
@@ -180,7 +181,7 @@ HTMLElement* HTMLFormElement::item(unsigned index) {
return elements()->item(index);
}
-void HTMLFormElement::SubmitImplicitly(Event& event,
+void HTMLFormElement::SubmitImplicitly(const Event& event,
bool from_implicit_submission_trigger) {
int submission_trigger_count = 0;
bool seen_default_button = false;
@@ -222,7 +223,7 @@ bool HTMLFormElement::ValidateInteractively() {
// Needs to update layout now because we'd like to call isFocusable(), which
// has !layoutObject()->needsLayout() assertion.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kFocus);
// Focus on the first focusable control and show a validation message.
for (const auto& unhandled : unhandled_invalid_controls) {
@@ -241,31 +242,31 @@ bool HTMLFormElement::ValidateInteractively() {
String message(
"An invalid form control with name='%name' is not focusable.");
message.Replace("%name", unhandled->GetName());
- GetDocument().AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kRendering,
- mojom::ConsoleMessageLevel::kError, message));
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kRendering,
+ mojom::ConsoleMessageLevel::kError, message));
}
}
return false;
}
void HTMLFormElement::PrepareForSubmission(
- Event* event,
+ const Event* event,
HTMLFormControlElement* submit_button) {
LocalFrame* frame = GetDocument().GetFrame();
if (!frame || is_submitting_ || in_user_js_submit_event_)
return;
if (!isConnected()) {
- GetDocument().AddConsoleMessage(ConsoleMessage::Create(
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning,
"Form submission canceled because the form is not connected"));
return;
}
- if (GetDocument().IsSandboxed(WebSandboxFlags::kForms)) {
- GetDocument().AddConsoleMessage(ConsoleMessage::Create(
+ if (GetDocument().IsSandboxed(mojom::blink::WebSandboxFlags::kForms)) {
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kSecurity,
mojom::ConsoleMessageLevel::kError,
"Blocked form submission to '" + attributes_.Action() +
@@ -282,7 +283,7 @@ void HTMLFormElement::PrepareForSubmission(
WebFeature::kFormSubmittedWithUnclosedFormControl);
if (RuntimeEnabledFeatures::UnclosedFormControlIsInvalidEnabled()) {
String tag_name = To<HTMLFormControlElement>(element)->tagName();
- GetDocument().AddConsoleMessage(ConsoleMessage::Create(
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kSecurity,
mojom::ConsoleMessageLevel::kError,
"Form submission failed, as the <" + tag_name +
@@ -314,41 +315,23 @@ void HTMLFormElement::PrepareForSubmission(
should_submit = false;
} else {
frame->Client()->DispatchWillSendSubmitEvent(this);
- should_submit =
- DispatchEvent(*Event::CreateCancelableBubble(
- event_type_names::kSubmit)) == DispatchEventResult::kNotCanceled;
+ SubmitEventInit* submit_event_init = SubmitEventInit::Create();
+ submit_event_init->setBubbles(true);
+ submit_event_init->setCancelable(true);
+ submit_event_init->setSubmitter(
+ submit_button ? &submit_button->ToHTMLElement() : nullptr);
+ should_submit = DispatchEvent(*MakeGarbageCollected<SubmitEvent>(
+ event_type_names::kSubmit, submit_event_init)) ==
+ DispatchEventResult::kNotCanceled;
}
}
if (should_submit) {
- planned_navigation_ = nullptr;
- Submit(event, submit_button);
+ ScheduleFormSubmission(event, submit_button);
}
- if (!planned_navigation_ || activated_submit_button_)
- return;
- base::AutoReset<bool> submit_scope(&is_submitting_, true);
- SubmitForm(planned_navigation_);
- planned_navigation_ = nullptr;
-}
-
-void HTMLFormElement::WillActivateSubmitButton(
- HTMLFormControlElement* element) {
- if (!activated_submit_button_)
- activated_submit_button_ = element;
-}
-
-void HTMLFormElement::DidActivateSubmitButton(HTMLFormControlElement* element) {
- if (activated_submit_button_ != element)
- return;
- activated_submit_button_ = nullptr;
- if (!planned_navigation_)
- return;
- base::AutoReset<bool> submit_scope(&is_submitting_, true);
- SubmitForm(planned_navigation_);
- planned_navigation_ = nullptr;
}
void HTMLFormElement::submitFromJavaScript() {
- Submit(nullptr, nullptr);
+ ScheduleFormSubmission(nullptr, nullptr);
}
void HTMLFormElement::requestSubmit(ExceptionState& exception_state) {
@@ -362,7 +345,7 @@ void HTMLFormElement::requestSubmit(HTMLElement* submitter,
// 1. If submitter was given, then:
if (submitter) {
// 1.1. If submitter is not a submit button, then throw a TypeError.
- control = ToHTMLFormControlElementOrNull(submitter);
+ control = DynamicTo<HTMLFormControlElement>(submitter);
// button[type] is a subset of input[type]. So it's ok to compare button's
// type and input_type_names.
if (!control || (control->type() != input_type_names::kSubmit &&
@@ -393,8 +376,9 @@ void HTMLFormElement::SubmitDialog(FormSubmission* form_submission) {
}
}
-void HTMLFormElement::Submit(Event* event,
- HTMLFormControlElement* submit_button) {
+void HTMLFormElement::ScheduleFormSubmission(
+ const Event* event,
+ HTMLFormControlElement* submit_button) {
LocalFrameView* view = GetDocument().View();
LocalFrame* frame = GetDocument().GetFrame();
if (!view || !frame || !frame->GetPage())
@@ -405,7 +389,7 @@ void HTMLFormElement::Submit(Event* event,
// or its active sandboxing flag set has its sandboxed forms browsing
// context flag set, then abort these steps without doing anything.
if (!isConnected()) {
- GetDocument().AddConsoleMessage(ConsoleMessage::Create(
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning,
"Form submission canceled because the form is not connected"));
@@ -413,11 +397,11 @@ void HTMLFormElement::Submit(Event* event,
}
if (is_constructing_entry_list_) {
- GetDocument().AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning,
- "Form submission canceled because the form is "
- "constructing entry list"));
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning,
+ "Form submission canceled because the form is "
+ "constructing entry list"));
return;
}
@@ -447,25 +431,90 @@ void HTMLFormElement::Submit(Event* event,
FormSubmission* form_submission =
FormSubmission::Create(this, attributes_, event, submit_button);
+ Frame* target_frame = form_submission->TargetFrame();
+
// 'formdata' event handlers might disconnect the form.
if (!isConnected()) {
- GetDocument().AddConsoleMessage(ConsoleMessage::Create(
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning,
"Form submission canceled because the form is not connected"));
return;
}
+
if (form_submission->Method() == FormSubmission::kDialogMethod) {
SubmitDialog(form_submission);
- } else if (in_user_js_submit_event_ || activated_submit_button_) {
- // Need to postpone the submission in order to make this cancelable by
- // another submission request.
- planned_navigation_ = form_submission;
- } else {
- // This runs JavaScript code if action attribute value is javascript:
- // protocol.
- SubmitForm(form_submission);
+ return;
+ }
+
+ DCHECK(form_submission->Method() == FormSubmission::kPostMethod ||
+ form_submission->Method() == FormSubmission::kGetMethod);
+ DCHECK(form_submission->Data());
+ DCHECK(form_submission->Form());
+ if (form_submission->Action().IsEmpty())
+ return;
+ if (GetDocument().IsSandboxed(mojom::blink::WebSandboxFlags::kForms)) {
+ // FIXME: This message should be moved off the console once a solution to
+ // https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kSecurity,
+ mojom::blink::ConsoleMessageLevel::kError,
+ "Blocked form submission to '" +
+ form_submission->Action().ElidedString() +
+ "' because the form's frame is sandboxed and the 'allow-forms' "
+ "permission is not set."));
+ return;
+ }
+
+ if (!GetDocument().GetContentSecurityPolicy()->AllowFormAction(
+ form_submission->Action())) {
+ return;
+ }
+
+ UseCounter::Count(GetDocument(), WebFeature::kFormsSubmitted);
+ if (MixedContentChecker::IsMixedFormAction(GetDocument().GetFrame(),
+ form_submission->Action())) {
+ UseCounter::Count(GetDocument(), WebFeature::kMixedContentFormsSubmitted);
+ }
+ if (FastHasAttribute(html_names::kDisabledAttr)) {
+ UseCounter::Count(GetDocument(),
+ WebFeature::kFormDisabledAttributePresentAndSubmit);
}
+
+ if (!target_frame)
+ return;
+
+ if (form_submission->Action().ProtocolIsJavaScript()) {
+ // For javascript urls, don't post a task to execute the form submission
+ // because we already get another task posted for it in
+ // Document::ProcessJavascriptUrl. If we post two tasks, the javascript will
+ // be run too late according to some tests.
+ form_submission->Navigate();
+ return;
+ }
+
+ FrameScheduler* scheduler = GetDocument().GetFrame()->GetFrameScheduler();
+
+ if (auto* target_local_frame = DynamicTo<LocalFrame>(target_frame)) {
+ if (!target_local_frame->IsNavigationAllowed())
+ return;
+
+ // Cancel parsing if the form submission is targeted at this frame.
+ if (target_local_frame == GetDocument().GetFrame() &&
+ !form_submission->Action().ProtocolIsJavaScript()) {
+ target_local_frame->GetDocument()->CancelParsing();
+ }
+
+ // Use the target frame's frame scheduler. If we can't due to targeting a
+ // RemoteFrame, then use the frame scheduler from the frame this form is in.
+ scheduler = target_local_frame->GetFrameScheduler();
+
+ // Cancel pending javascript url navigations for the target frame. This new
+ // form submission should take precedence over them.
+ target_local_frame->GetDocument()->CancelPendingJavaScriptUrls();
+ }
+
+ target_frame->ScheduleFormSubmission(scheduler, form_submission);
}
FormData* HTMLFormElement::ConstructEntryList(
@@ -496,46 +545,6 @@ FormData* HTMLFormElement::ConstructEntryList(
return &form_data;
}
-// Actually submit the form - navigate now.
-void HTMLFormElement::SubmitForm(FormSubmission* submission) {
- DCHECK(submission->Method() == FormSubmission::kPostMethod ||
- submission->Method() == FormSubmission::kGetMethod);
- DCHECK(submission->Data());
- DCHECK(submission->Form());
- if (submission->Action().IsEmpty())
- return;
- if (!GetDocument().IsActive())
- return;
- if (GetDocument().IsSandboxed(WebSandboxFlags::kForms)) {
- // FIXME: This message should be moved off the console once a solution to
- // https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
- GetDocument().AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kError,
- "Blocked form submission to '" + submission->Action().ElidedString() +
- "' because the form's frame is sandboxed and the 'allow-forms' "
- "permission is not set."));
- return;
- }
-
- if (!GetDocument().GetContentSecurityPolicy()->AllowFormAction(
- submission->Action())) {
- return;
- }
-
- UseCounter::Count(GetDocument(), WebFeature::kFormsSubmitted);
- if (MixedContentChecker::IsMixedFormAction(GetDocument().GetFrame(),
- submission->Action())) {
- UseCounter::Count(GetDocument(), WebFeature::kMixedContentFormsSubmitted);
- }
- if (FastHasAttribute(html_names::kDisabledAttr)) {
- UseCounter::Count(GetDocument(),
- WebFeature::kFormDisabledAttributePresentAndSubmit);
- }
-
- submission->Navigate();
-}
-
void HTMLFormElement::reset() {
LocalFrame* frame = GetDocument().GetFrame();
if (is_in_reset_function_ || !frame)
@@ -573,7 +582,9 @@ void HTMLFormElement::ParseAttribute(
// If we're not upgrading insecure requests, and the new action attribute is
// pointing to an insecure "action" location from a secure page it is marked
// as "passive" mixed content.
- if (GetDocument().GetInsecureRequestPolicy() & kUpgradeInsecureRequests)
+ if ((GetDocument().GetSecurityContext().GetInsecureRequestPolicy() &
+ mojom::blink::InsecureRequestPolicy::kUpgradeInsecureRequests) !=
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone)
return;
KURL action_url = GetDocument().CompleteURL(
attributes_.Action().IsEmpty() ? GetDocument().Url().GetString()
@@ -608,11 +619,6 @@ void HTMLFormElement::Disassociate(ListedElement& e) {
listed_elements_are_dirty_ = true;
listed_elements_.clear();
RemoveFromPastNamesMap(e.ToHTMLElement());
-
- if (activated_submit_button_ != &e)
- return;
- activated_submit_button_ = nullptr;
- planned_navigation_ = nullptr;
}
bool HTMLFormElement::IsURLAttribute(const Attribute& attribute) const {
@@ -835,7 +841,7 @@ void HTMLFormElement::GetNamedElements(
}
bool HTMLFormElement::ShouldAutocomplete() const {
- return !DeprecatedEqualIgnoringCase(
+ return !EqualIgnoringASCIICase(
FastGetAttribute(html_names::kAutocompleteAttr), "off");
}
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 3375fb2eb17..620c05a3cc9 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
@@ -71,13 +71,14 @@ class CORE_EXPORT HTMLFormElement final : public HTMLElement {
void Disassociate(HTMLImageElement&);
void DidAssociateByParser();
- void PrepareForSubmission(Event*, HTMLFormControlElement* submit_button);
+ void PrepareForSubmission(const Event*,
+ HTMLFormControlElement* submit_button);
void submitFromJavaScript();
void requestSubmit(ExceptionState& exception_state);
void requestSubmit(HTMLElement* submitter, ExceptionState& exception_state);
void reset();
- void SubmitImplicitly(Event&, bool from_implicit_submission_trigger);
+ void SubmitImplicitly(const Event&, bool from_implicit_submission_trigger);
String GetName() const;
@@ -115,12 +116,6 @@ class CORE_EXPORT HTMLFormElement final : public HTMLElement {
unsigned UniqueRendererFormId() const { return unique_renderer_form_id_; }
- // TODO(crbug.com/1013385): Remove WillActivateSubmitButton,
- // DidActivateSubmitButton, and RemovedAssociatedControlElement. They are
- // here temporarily to fix form double-submit.
- void WillActivateSubmitButton(HTMLFormControlElement* element);
- void DidActivateSubmitButton(HTMLFormControlElement* element);
-
private:
InsertionNotificationRequest InsertedInto(ContainerNode&) override;
void RemovedFrom(ContainerNode&) override;
@@ -137,9 +132,8 @@ class CORE_EXPORT HTMLFormElement final : public HTMLElement {
}
void SubmitDialog(FormSubmission*);
- void Submit(Event*, HTMLFormControlElement* submit_button);
-
- void SubmitForm(FormSubmission*);
+ void ScheduleFormSubmission(const Event*,
+ HTMLFormControlElement* submit_button);
void CollectListedElements(Node& root, ListedElement::List&) const;
void CollectImageElements(Node& root, HeapVector<Member<HTMLImageElement>>&);
@@ -168,11 +162,6 @@ class CORE_EXPORT HTMLFormElement final : public HTMLElement {
// Do not access image_elements_ directly. Use ImageElements() instead.
HeapVector<Member<HTMLImageElement>> image_elements_;
- // https://html.spec.whatwg.org/C/#planned-navigation
- // Unlike the specification, we use this only for web-exposed submit()
- // function in 'submit' event handler.
- Member<FormSubmission> planned_navigation_;
-
unsigned unique_renderer_form_id_;
bool is_submitting_ = false;
@@ -185,8 +174,6 @@ class CORE_EXPORT HTMLFormElement final : public HTMLElement {
bool has_elements_associated_by_form_attribute_ : 1;
bool did_finish_parsing_children_ : 1;
bool is_in_reset_function_ : 1;
-
- Member<HTMLFormControlElement> activated_submit_button_;
};
} // namespace blink
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 2ef0a61f534..ce0b6a33afb 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
@@ -32,7 +32,6 @@
#include "third_party/blink/public/mojom/choosers/date_time_chooser.mojom-blink.h"
#include "third_party/blink/public/platform/task_type.h"
-#include "third_party/blink/public/platform/web_scroll_into_view_params.h"
#include "third_party/blink/public/strings/grit/blink_strings.h"
#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
#include "third_party/blink/renderer/bindings/core/v8/script_event_listener.h"
@@ -50,6 +49,7 @@
#include "third_party/blink/renderer/core/events/before_text_inserted_event.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/fileapi/file_list.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
@@ -81,6 +81,7 @@
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/text/platform_locale.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
+#include "ui/base/ui_base_features.h"
namespace blink {
@@ -185,27 +186,27 @@ bool HTMLInputElement::IsValidValue(const String& value) const {
}
bool HTMLInputElement::TooLong() const {
- return willValidate() && TooLong(value(), kCheckDirtyFlag);
+ return TooLong(value(), kCheckDirtyFlag);
}
bool HTMLInputElement::TooShort() const {
- return willValidate() && TooShort(value(), kCheckDirtyFlag);
+ return TooShort(value(), kCheckDirtyFlag);
}
bool HTMLInputElement::TypeMismatch() const {
- return willValidate() && input_type_->TypeMismatch();
+ return input_type_->TypeMismatch();
}
bool HTMLInputElement::ValueMissing() const {
- return willValidate() && input_type_->ValueMissing(value());
+ return input_type_->ValueMissing(value());
}
bool HTMLInputElement::HasBadInput() const {
- return willValidate() && input_type_view_->HasBadInput();
+ return input_type_view_->HasBadInput();
}
bool HTMLInputElement::PatternMismatch() const {
- return willValidate() && input_type_->PatternMismatch(value());
+ return input_type_->PatternMismatch(value());
}
bool HTMLInputElement::TooLong(const String& value,
@@ -219,17 +220,16 @@ bool HTMLInputElement::TooShort(const String& value,
}
bool HTMLInputElement::RangeUnderflow() const {
- return willValidate() && input_type_->RangeUnderflow(value());
+ return input_type_->RangeUnderflow(value());
}
bool HTMLInputElement::RangeOverflow() const {
- return willValidate() && input_type_->RangeOverflow(value());
+ return input_type_->RangeOverflow(value());
}
String HTMLInputElement::validationMessage() const {
if (!willValidate())
return String();
-
if (CustomError())
return CustomValidationMessage();
@@ -237,7 +237,7 @@ String HTMLInputElement::validationMessage() const {
}
String HTMLInputElement::ValidationSubMessage() const {
- if (!willValidate() || CustomError())
+ if (CustomError())
return String();
return input_type_->ValidationMessage(*input_type_view_).second;
}
@@ -251,7 +251,7 @@ double HTMLInputElement::Maximum() const {
}
bool HTMLInputElement::StepMismatch() const {
- return willValidate() && input_type_->StepMismatch(value());
+ return input_type_->StepMismatch(value());
}
bool HTMLInputElement::GetAllowedValueStep(Decimal* step) const {
@@ -295,6 +295,16 @@ bool HTMLInputElement::MayTriggerVirtualKeyboard() const {
return input_type_->MayTriggerVirtualKeyboard();
}
+bool HTMLInputElement::ShouldHaveFocusAppearance() const {
+ // For FormControlsRefresh don't draw focus ring for an input that has its
+ // popup open.
+ if (::features::IsFormControlsRefreshEnabled() &&
+ input_type_view_->HasOpenedPopup())
+ return false;
+
+ return TextControlElement::ShouldHaveFocusAppearance();
+}
+
void HTMLInputElement::UpdateFocusAppearanceWithOptions(
SelectionBehaviorOnFocus selection_behavior,
const FocusOptions* options) {
@@ -312,11 +322,13 @@ void HTMLInputElement::UpdateFocusAppearanceWithOptions(
// TODO(tkent): scrollRectToVisible is a workaround of a bug of
// FrameSelection::revealSelection(). It doesn't scroll correctly in a
// case of RangeSelection. crbug.com/443061.
- GetDocument().EnsurePaintLocationDataValidForNode(this);
+ GetDocument().EnsurePaintLocationDataValidForNode(
+ this, DocumentUpdateReason::kFocus);
if (!options->preventScroll()) {
if (GetLayoutObject()) {
- GetLayoutObject()->ScrollRectToVisible(BoundingBoxForScrollIntoView(),
- WebScrollIntoViewParams());
+ GetLayoutObject()->ScrollRectToVisible(
+ BoundingBoxForScrollIntoView(),
+ ScrollAlignment::CreateScrollIntoViewParams());
}
if (GetDocument().GetFrame())
GetDocument().GetFrame()->Selection().RevealSelection();
@@ -343,7 +355,7 @@ void HTMLInputElement::EndEditing() {
void HTMLInputElement::DispatchFocusInEvent(
const AtomicString& event_type,
Element* old_focused_element,
- WebFocusType type,
+ mojom::blink::FocusType type,
InputDeviceCapabilities* source_capabilities) {
if (event_type == event_type_names::kDOMFocusIn)
input_type_view_->HandleFocusInEvent(old_focused_element, type);
@@ -597,6 +609,20 @@ bool HTMLInputElement::CanStartSelection() const {
return TextControlElement::CanStartSelection();
}
+base::Optional<uint32_t> HTMLInputElement::selectionStartForBinding(
+ ExceptionState& exception_state) const {
+ if (!input_type_->SupportsSelectionAPI())
+ return base::nullopt;
+ return TextControlElement::selectionStart();
+}
+
+base::Optional<uint32_t> HTMLInputElement::selectionEndForBinding(
+ ExceptionState& exception_state) const {
+ if (!input_type_->SupportsSelectionAPI())
+ return base::nullopt;
+ return TextControlElement::selectionEnd();
+}
+
unsigned HTMLInputElement::selectionStartForBinding(
bool& is_null,
ExceptionState& exception_state) const {
@@ -626,6 +652,32 @@ String HTMLInputElement::selectionDirectionForBinding(
}
void HTMLInputElement::setSelectionStartForBinding(
+ base::Optional<uint32_t> start,
+ ExceptionState& exception_state) {
+ if (!input_type_->SupportsSelectionAPI()) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "The input element's type ('" +
+ input_type_->FormControlType() +
+ "') does not support selection.");
+ return;
+ }
+ TextControlElement::setSelectionStart(start.value_or(0));
+}
+
+void HTMLInputElement::setSelectionEndForBinding(
+ base::Optional<uint32_t> end,
+ ExceptionState& exception_state) {
+ if (!input_type_->SupportsSelectionAPI()) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "The input element's type ('" +
+ input_type_->FormControlType() +
+ "') does not support selection.");
+ return;
+ }
+ TextControlElement::setSelectionEnd(end.value_or(0));
+}
+
+void HTMLInputElement::setSelectionStartForBinding(
unsigned start,
bool is_null,
ExceptionState& exception_state) {
@@ -751,7 +803,7 @@ void HTMLInputElement::ParseAttribute(
AddToRadioButtonGroup();
TextControlElement::ParseAttribute(params);
} else if (name == html_names::kAutocompleteAttr) {
- if (DeprecatedEqualIgnoringCase(value, "off")) {
+ if (EqualIgnoringASCIICase(value, "off")) {
autocomplete_ = kOff;
} else {
if (value.IsEmpty())
@@ -802,7 +854,7 @@ void HTMLInputElement::ParseAttribute(
size_ = size;
if (GetLayoutObject()) {
GetLayoutObject()
- ->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ ->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kAttributeChanged);
}
}
@@ -885,6 +937,11 @@ bool HTMLInputElement::LayoutObjectIsNeeded(const ComputedStyle& style) const {
TextControlElement::LayoutObjectIsNeeded(style);
}
+// TODO(crbug.com/1040826): Remove this override.
+bool HTMLInputElement::TypeShouldForceLegacyLayout() const {
+ return input_type_view_->TypeShouldForceLegacyLayout();
+}
+
LayoutObject* HTMLInputElement::CreateLayoutObject(const ComputedStyle& style,
LegacyLayout legacy) {
return input_type_view_->CreateLayoutObject(style, legacy);
@@ -961,12 +1018,13 @@ bool HTMLInputElement::HasBeenPasswordField() const {
}
void HTMLInputElement::DispatchChangeEventIfNeeded() {
- if (input_type_->ShouldSendChangeEventAfterCheckedChanged())
+ if (isConnected() && input_type_->ShouldSendChangeEventAfterCheckedChanged())
DispatchChangeEvent();
}
void HTMLInputElement::DispatchInputAndChangeEventIfNeeded() {
- if (input_type_->ShouldSendChangeEventAfterCheckedChanged()) {
+ if (isConnected() &&
+ input_type_->ShouldSendChangeEventAfterCheckedChanged()) {
DispatchInputEvent();
DispatchChangeEvent();
}
@@ -983,6 +1041,7 @@ void HTMLInputElement::setChecked(bool now_checked,
if (checked() == now_checked)
return;
+ input_type_->WillUpdateCheckedness(now_checked);
is_checked_ = now_checked;
if (RadioButtonGroupScope* scope = GetRadioButtonGroupScope())
@@ -1069,6 +1128,10 @@ String HTMLInputElement::value() const {
return g_empty_string;
}
+String HTMLInputElement::rawValue() const {
+ return input_type_view_->RawValue();
+}
+
String HTMLInputElement::ValueOrDefaultLabel() const {
String value = this->value();
if (!value.IsNull())
@@ -1150,23 +1213,6 @@ void HTMLInputElement::setValue(const String& value,
if (value_changed)
NotifyFormStateChanged();
-
- if (isConnected()) {
- if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache()) {
- auto* page = GetDocument().GetPage();
- auto* view = GetDocument().View();
- // Run the document lifecycle to ensure AX notifications fire,
- // even if the value didn't change.
- if (page && view) {
- // TODO(aboxhall): add a lifecycle phase for accessibility updates.
- if (!view->CanThrottleRendering())
- page->Animator().ScheduleVisualUpdate(GetDocument().GetFrame());
-
- GetDocument().Lifecycle().EnsureStateAtMost(
- DocumentLifecycle::kVisualUpdatePending);
- }
- }
- }
}
void HTMLInputElement::SetNonAttributeValue(const String& sanitized_value) {
@@ -1214,7 +1260,7 @@ void HTMLInputElement::setValueAsDate(ScriptState* script_state,
ExceptionState& exception_state) {
UseCounter::Count(GetDocument(), WebFeature::kInputElementValueAsDateSetter);
base::Optional<base::Time> date =
- NativeValueTraits<IDLDateOrNull>::NativeValue(
+ NativeValueTraits<IDLNullable<IDLDate>>::NativeValue(
script_state->GetIsolate(), value.V8Value(), exception_state);
if (exception_state.HadException())
return;
@@ -1278,12 +1324,12 @@ EventDispatchHandlingState* HTMLInputElement::PreDispatchEventHandler(
}
if (event.type() != event_type_names::kClick)
return nullptr;
- if (!event.IsMouseEvent() ||
- ToMouseEvent(event).button() !=
+
+ auto* mouse_event = DynamicTo<MouseEvent>(event);
+ if (!mouse_event ||
+ mouse_event->button() !=
static_cast<int16_t>(WebPointerProperties::Button::kLeft))
return nullptr;
- if (formOwner() && CanBeSuccessfulSubmitButton())
- formOwner()->WillActivateSubmitButton(this);
return input_type_view_->WillDispatchClick();
}
@@ -1296,29 +1342,19 @@ void HTMLInputElement::PostDispatchEventHandler(
*static_cast<ClickHandlingState*>(state));
}
-void HTMLInputElement::DidPreventDefault(const Event& event) {
- if (auto* form = formOwner())
- form->DidActivateSubmitButton(this);
-}
-
-void HTMLInputElement::DefaultEventHandler(Event& event) {
- DefaultEventHandlerInternal(event);
-
- if (event.type() == event_type_names::kDOMActivate && formOwner())
- formOwner()->DidActivateSubmitButton(this);
-}
-
-void HTMLInputElement::DefaultEventHandlerInternal(Event& evt) {
- if (evt.IsMouseEvent() && evt.type() == event_type_names::kClick &&
- ToMouseEvent(evt).button() ==
+void HTMLInputElement::DefaultEventHandler(Event& evt) {
+ auto* mouse_event = DynamicTo<MouseEvent>(evt);
+ if (mouse_event && evt.type() == event_type_names::kClick &&
+ mouse_event->button() ==
static_cast<int16_t>(WebPointerProperties::Button::kLeft)) {
- input_type_view_->HandleClickEvent(ToMouseEvent(evt));
+ input_type_view_->HandleClickEvent(To<MouseEvent>(evt));
if (evt.DefaultHandled())
return;
}
- if (evt.IsKeyboardEvent() && evt.type() == event_type_names::kKeydown) {
- input_type_view_->HandleKeydownEvent(ToKeyboardEvent(evt));
+ auto* keyboad_event = DynamicTo<KeyboardEvent>(evt);
+ if (keyboad_event && evt.type() == event_type_names::kKeydown) {
+ input_type_view_->HandleKeydownEvent(*keyboad_event);
if (evt.DefaultHandled())
return;
}
@@ -1349,14 +1385,14 @@ void HTMLInputElement::DefaultEventHandlerInternal(Event& evt) {
// Use key press event here since sending simulated mouse events
// on key down blocks the proper sending of the key press event.
- if (evt.IsKeyboardEvent() && evt.type() == event_type_names::kKeypress) {
- input_type_view_->HandleKeypressEvent(ToKeyboardEvent(evt));
+ if (keyboad_event && evt.type() == event_type_names::kKeypress) {
+ input_type_view_->HandleKeypressEvent(*keyboad_event);
if (evt.DefaultHandled())
return;
}
- if (evt.IsKeyboardEvent() && evt.type() == event_type_names::kKeyup) {
- input_type_view_->HandleKeyupEvent(ToKeyboardEvent(evt));
+ if (keyboad_event && evt.type() == event_type_names::kKeyup) {
+ input_type_view_->HandleKeyupEvent(*keyboad_event);
if (evt.DefaultHandled())
return;
}
@@ -1390,8 +1426,8 @@ void HTMLInputElement::DefaultEventHandlerInternal(Event& evt) {
static_cast<BeforeTextInsertedEvent&>(evt));
}
- if (evt.IsMouseEvent() && evt.type() == event_type_names::kMousedown) {
- input_type_view_->HandleMouseDownEvent(ToMouseEvent(evt));
+ if (mouse_event && evt.type() == event_type_names::kMousedown) {
+ input_type_view_->HandleMouseDownEvent(*mouse_event);
if (evt.DefaultHandled())
return;
}
@@ -1540,8 +1576,12 @@ void HTMLInputElement::SetCanReceiveDroppedFiles(
if (!!can_receive_dropped_files_ == can_receive_dropped_files)
return;
can_receive_dropped_files_ = can_receive_dropped_files;
- if (GetLayoutObject())
- GetLayoutObject()->UpdateFromElement();
+ if (HTMLInputElement* button = UploadButton())
+ button->SetActive(can_receive_dropped_files);
+}
+
+HTMLInputElement* HTMLInputElement::UploadButton() const {
+ return input_type_view_->UploadButton();
}
String HTMLInputElement::SanitizeValue(const String& proposed_value) const {
@@ -1647,9 +1687,8 @@ void HTMLInputElement::SelectColorInColorChooser(const Color& color) {
client->DidChooseColor(color);
}
-void HTMLInputElement::EndColorChooser() {
- if (ColorChooserClient* client = input_type_->GetColorChooserClient())
- client->DidEndChooser();
+void HTMLInputElement::EndColorChooserForTesting() {
+ input_type_view_->ClosePopupView();
}
HTMLElement* HTMLInputElement::list() const {
@@ -1779,24 +1818,16 @@ String HTMLInputElement::DefaultToolTip() const {
return input_type_->DefaultToolTip(*input_type_view_);
}
-bool HTMLInputElement::ShouldAppearIndeterminate() const {
- return input_type_->ShouldAppearIndeterminate();
+String HTMLInputElement::FileStatusText() const {
+ return input_type_view_->FileStatusText();
}
-bool HTMLInputElement::IsInRequiredRadioButtonGroup() {
- // TODO(tkent): Remove type check.
- DCHECK_EQ(type(), input_type_names::kRadio);
- if (RadioButtonGroupScope* scope = GetRadioButtonGroupScope())
- return scope->IsInRequiredGroup(this);
- return false;
+bool HTMLInputElement::ShouldApplyMiddleEllipsis() const {
+ return files() && files()->length() <= 1;
}
-HTMLInputElement* HTMLInputElement::CheckedRadioButtonForGroup() {
- if (checked())
- return this;
- if (RadioButtonGroupScope* scope = GetRadioButtonGroupScope())
- return scope->CheckedButtonForGroup(GetName());
- return nullptr;
+bool HTMLInputElement::ShouldAppearIndeterminate() const {
+ return input_type_->ShouldAppearIndeterminate();
}
RadioButtonGroupScope* HTMLInputElement::GetRadioButtonGroupScope() const {
@@ -1962,8 +1993,9 @@ bool HTMLInputElement::IsInteractiveContent() const {
}
scoped_refptr<ComputedStyle> HTMLInputElement::CustomStyleForLayoutObject() {
- return input_type_view_->CustomStyleForLayoutObject(
- OriginalStyleForLayoutObject());
+ scoped_refptr<ComputedStyle> style = OriginalStyleForLayoutObject();
+ input_type_view_->CustomStyleForLayoutObject(*style);
+ return style;
}
void HTMLInputElement::DidRecalcStyle(const StyleRecalcChange change) {
@@ -2013,4 +2045,8 @@ PaintLayerScrollableArea* HTMLInputElement::GetScrollableArea() const {
return Element::GetScrollableArea();
}
+bool HTMLInputElement::IsDraggedSlider() const {
+ return input_type_view_->IsDraggedSlider();
+}
+
} // namespace blink
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 67291f93ee4..9b0f10e05d9 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
@@ -26,6 +26,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_HTML_INPUT_ELEMENT_H_
#include "base/gtest_prod_util.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.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/create_element_flags.h"
@@ -127,6 +128,9 @@ class CORE_EXPORT HTMLInputElement
bool ShouldAppearChecked() const;
bool ShouldAppearIndeterminate() const override;
+ // Returns null if this isn't associated with any radio button group.
+ RadioButtonGroupScope* GetRadioButtonGroupScope() const;
+
unsigned size() const;
bool SizeShouldIncludeDecoration(int& preferred_size) const;
@@ -151,6 +155,8 @@ class CORE_EXPORT HTMLInputElement
bool IsValidValue(const String&) const;
bool HasDirtyValue() const;
+ String rawValue() const;
+
String SanitizeValue(const String&) const;
String LocalizeValue(const String&) const;
@@ -177,11 +183,22 @@ class CORE_EXPORT HTMLInputElement
// delay the 'input' event with EventQueueScope.
void SetValueFromRenderer(const String&);
- unsigned selectionStartForBinding(bool&, ExceptionState&) const;
- unsigned selectionEndForBinding(bool&, ExceptionState&) const;
+ base::Optional<uint32_t> selectionStartForBinding(ExceptionState&) const;
+ base::Optional<uint32_t> selectionEndForBinding(ExceptionState&) const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ unsigned selectionStartForBinding(bool&,
+ ExceptionState&) const; // DEPRECATED
+ unsigned selectionEndForBinding(bool&, ExceptionState&) const; // DEPRECATED
String selectionDirectionForBinding(ExceptionState&) const;
- void setSelectionStartForBinding(unsigned, bool is_null, ExceptionState&);
- void setSelectionEndForBinding(unsigned, bool is_null, ExceptionState&);
+ void setSelectionStartForBinding(base::Optional<uint32_t>, ExceptionState&);
+ void setSelectionEndForBinding(base::Optional<uint32_t>, ExceptionState&);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ void setSelectionStartForBinding(unsigned,
+ bool is_null,
+ ExceptionState&); // DEPRECATED
+ void setSelectionEndForBinding(unsigned,
+ bool is_null,
+ ExceptionState&); // DEPRECATED
void setSelectionDirectionForBinding(const String&, ExceptionState&);
void setSelectionRangeForBinding(unsigned start,
unsigned end,
@@ -232,6 +249,10 @@ class CORE_EXPORT HTMLInputElement
bool CanReceiveDroppedFiles() const;
void SetCanReceiveDroppedFiles(bool);
+ // Returns 'Choose File(s)' button in a file control. This returns
+ // nullptr for other input types.
+ HTMLInputElement* UploadButton() const;
+
void OnSearch();
void UpdateClearButtonVisibility();
@@ -245,9 +266,6 @@ class CORE_EXPORT HTMLInputElement
// Associated <datalist> options which match to the current INPUT value.
HeapVector<Member<HTMLOptionElement>> FilteredDataListOptions() const;
- HTMLInputElement* CheckedRadioButtonForGroup();
- bool IsInRequiredRadioButtonGroup();
-
// Functions for InputType classes.
void SetNonAttributeValue(const String&);
void SetNonAttributeValueByUserEdit(const String&);
@@ -257,10 +275,18 @@ class CORE_EXPORT HTMLInputElement
// For test purposes.
void SelectColorInColorChooser(const Color&);
- void EndColorChooser();
+ void EndColorChooserForTesting();
String DefaultToolTip() const override;
+ // Type=file only: Text not in the button such as "No file chosen". The string
+ // is not truncated by ellipsis.
+ // Return a null string for other types.
+ String FileStatusText() const;
+ // Returns true if an ellipsis should be injected at the middle of the text.
+ // This function is called only if text-overflow:ellipsis is specified.
+ bool ShouldApplyMiddleEllipsis() const;
+
unsigned height() const;
unsigned width() const;
void setHeight(unsigned);
@@ -315,6 +341,8 @@ class CORE_EXPORT HTMLInputElement
void SetHasBeenPasswordField() { has_been_password_field_ = true; }
+ bool IsDraggedSlider() const;
+
protected:
void DefaultEventHandler(Event&) override;
void CreateShadowSubtree();
@@ -332,6 +360,7 @@ class CORE_EXPORT HTMLInputElement
bool HasCustomFocusLogic() const final;
bool IsKeyboardFocusable() const final;
bool MayTriggerVirtualKeyboard() const final;
+ bool ShouldHaveFocusAppearance() const final;
bool IsEnumeratable() const final;
bool IsInteractiveContent() const final;
bool IsLabelable() const final;
@@ -361,6 +390,7 @@ class CORE_EXPORT HTMLInputElement
void CloneNonAttributePropertiesFrom(const Element&, CloneChildrenFlag) final;
+ bool TypeShouldForceLegacyLayout() const final;
void AttachLayoutTree(AttachContext&) final;
void AppendToFormData(FormData&) final;
@@ -372,11 +402,6 @@ class CORE_EXPORT HTMLInputElement
EventDispatchHandlingState* PreDispatchEventHandler(Event&) final;
void PostDispatchEventHandler(Event&, EventDispatchHandlingState*) final;
- // TODO(crbug.com/1013385): Remove DidPreventDefault and
- // DefaultEventHandlerInternal. They are here as a temporary fix for form
- // double-submit.
- void DidPreventDefault(const Event&) final;
- void DefaultEventHandlerInternal(Event& evt);
bool IsURLAttribute(const Attribute&) const final;
bool HasLegalLinkAttribute(const QualifiedName&) const final;
@@ -392,7 +417,7 @@ class CORE_EXPORT HTMLInputElement
void HandleBlurEvent() final;
void DispatchFocusInEvent(const AtomicString& event_type,
Element* old_focused_element,
- WebFocusType,
+ mojom::blink::FocusType,
InputDeviceCapabilities* source_capabilities) final;
bool IsOptionalFormControl() const final { return !IsRequiredFormControl(); }
@@ -409,8 +434,6 @@ class CORE_EXPORT HTMLInputElement
void SetListAttributeTargetObserver(ListAttributeTargetObserver*);
void ResetListAttributeTargetObserver();
- // Returns null if this isn't associated with any radio button group.
- RadioButtonGroupScope* GetRadioButtonGroupScope() const;
void AddToRadioButtonGroup();
void RemoveFromRadioButtonGroup();
scoped_refptr<ComputedStyle> CustomStyleForLayoutObject() override;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_input_element.idl b/chromium/third_party/blink/renderer/core/html/forms/html_input_element.idl
index 48bb6afc2a6..3c153f49fd6 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_input_element.idl
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_input_element.idl
@@ -81,6 +81,8 @@ enum SelectionMode { "select", "start", "end", "preserve" };
readonly attribute NodeList labels;
+ [RuntimeEnabled=InputElementRawValue] readonly attribute DOMString rawValue;
+
void select();
[RaisesException, ImplementedAs=selectionStartForBinding] attribute unsigned long? selectionStart;
[RaisesException, ImplementedAs=selectionEndForBinding] attribute unsigned long? selectionEnd;
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 f14da1cfcd8..baa2c174681 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
@@ -7,9 +7,9 @@
#include <memory>
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_keyboard_event_init.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/events/keyboard_event.h"
-#include "third_party/blink/renderer/core/events/keyboard_event_init.h"
#include "third_party/blink/renderer/core/fileapi/file_list.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/visual_viewport.h"
@@ -35,16 +35,16 @@ class HTMLInputElementTest : public PageTestBase {
};
TEST_F(HTMLInputElementTest, FilteredDataListOptionsNoList) {
- GetDocument().documentElement()->SetInnerHTMLFromString("<input id=test>");
+ GetDocument().documentElement()->setInnerHTML("<input id=test>");
EXPECT_TRUE(TestElement().FilteredDataListOptions().IsEmpty());
- GetDocument().documentElement()->SetInnerHTMLFromString(
+ GetDocument().documentElement()->setInnerHTML(
"<input id=test list=dl1><datalist id=dl1></datalist>");
EXPECT_TRUE(TestElement().FilteredDataListOptions().IsEmpty());
}
TEST_F(HTMLInputElementTest, FilteredDataListOptionsContain) {
- GetDocument().documentElement()->SetInnerHTMLFromString(
+ GetDocument().documentElement()->setInnerHTML(
"<input id=test value=BC list=dl2>"
"<datalist id=dl2>"
"<option>AbC DEF</option>"
@@ -56,7 +56,7 @@ TEST_F(HTMLInputElementTest, FilteredDataListOptionsContain) {
EXPECT_EQ("AbC DEF", options[0]->value().Utf8());
EXPECT_EQ("ghi", options[1]->value().Utf8());
- GetDocument().documentElement()->SetInnerHTMLFromString(
+ GetDocument().documentElement()->setInnerHTML(
"<input id=test value=i list=dl2>"
"<datalist id=dl2>"
"<option>I</option>"
@@ -70,7 +70,7 @@ TEST_F(HTMLInputElementTest, FilteredDataListOptionsContain) {
}
TEST_F(HTMLInputElementTest, FilteredDataListOptionsForMultipleEmail) {
- GetDocument().documentElement()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().documentElement()->setInnerHTML(R"HTML(
<input id=test value='foo@example.com, tkent' list=dl3 type=email
multiple>
<datalist id=dl3>
@@ -104,7 +104,7 @@ TEST_F(HTMLInputElementTest, NoAssertWhenMovedInNewDocument) {
// Create an input element with type "range" inside a document without frame.
To<HTMLBodyElement>(html->firstChild())
- ->SetInnerHTMLFromString("<input type='range' />");
+ ->setInnerHTML("<input type='range' />");
document_without_frame->AppendChild(html);
auto page_holder = std::make_unique<DummyPageHolder>();
@@ -154,7 +154,7 @@ TEST_F(HTMLInputElementTest, ImageTypeCrash) {
TEST_F(HTMLInputElementTest, RadioKeyDownDCHECKFailure) {
// crbug.com/697286
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<input type=radio name=g><input type=radio name=g>");
auto& radio1 = To<HTMLInputElement>(*GetDocument().body()->firstChild());
auto& radio2 = To<HTMLInputElement>(*radio1.nextSibling());
@@ -171,7 +171,7 @@ TEST_F(HTMLInputElementTest, RadioKeyDownDCHECKFailure) {
TEST_F(HTMLInputElementTest, DateTimeChooserSizeParamRespectsScale) {
GetDocument().SetCompatibilityMode(Document::kQuirksMode);
GetDocument().View()->GetFrame().GetPage()->GetVisualViewport().SetScale(2.f);
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<input type='date' style='width:200px;height:50px' />");
UpdateAllLifecyclePhasesForTest();
auto* input = To<HTMLInputElement>(GetDocument().body()->firstChild());
@@ -195,13 +195,13 @@ TEST_F(HTMLInputElementTest, StepDownOverflow) {
}
TEST_F(HTMLInputElementTest, CheckboxHasNoShadowRoot) {
- GetDocument().body()->SetInnerHTMLFromString("<input type='checkbox' />");
+ GetDocument().body()->setInnerHTML("<input type='checkbox' />");
auto* input = To<HTMLInputElement>(GetDocument().body()->firstChild());
EXPECT_EQ(nullptr, input->UserAgentShadowRoot());
}
TEST_F(HTMLInputElementTest, ChangingInputTypeCausesShadowRootToBeCreated) {
- GetDocument().body()->SetInnerHTMLFromString("<input type='checkbox' />");
+ GetDocument().body()->setInnerHTML("<input type='checkbox' />");
auto* input = To<HTMLInputElement>(GetDocument().body()->firstChild());
EXPECT_EQ(nullptr, input->UserAgentShadowRoot());
input->setAttribute(html_names::kTypeAttr, "text");
@@ -209,7 +209,7 @@ TEST_F(HTMLInputElementTest, ChangingInputTypeCausesShadowRootToBeCreated) {
}
TEST_F(HTMLInputElementTest, RepaintAfterClearingFile) {
- GetDocument().body()->SetInnerHTMLFromString("<input type='file' />");
+ GetDocument().body()->setInnerHTML("<input type='file' />");
auto* input = To<HTMLInputElement>(GetDocument().body()->firstChild());
FileChooserFileInfoList files;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_label_element.cc b/chromium/third_party/blink/renderer/core/html/forms/html_label_element.cc
index d7f564f3b8f..1e5895b2211 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_label_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_label_element.cc
@@ -24,6 +24,7 @@
#include "third_party/blink/renderer/core/html/forms/html_label_element.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
@@ -87,7 +88,7 @@ HTMLElement* HTMLLabelElement::control() const {
HTMLFormElement* HTMLLabelElement::form() const {
if (HTMLElement* control = this->control()) {
- if (auto* form_control_element = ToHTMLFormControlElementOrNull(control))
+ if (auto* form_control_element = DynamicTo<HTMLFormControlElement>(control))
return form_control_element->Form();
if (control->IsFormAssociatedCustomElement())
return control->EnsureElementInternals().Form();
@@ -169,7 +170,8 @@ void HTMLLabelElement::DefaultEventHandler(Event& evt) {
// click event to control element.
// Note: check if it is a MouseEvent because a click event may
// not be an instance of a MouseEvent if created by document.createEvent().
- if (evt.IsMouseEvent() && ToMouseEvent(evt).HasPosition()) {
+ auto* mouse_event = DynamicTo<MouseEvent>(evt);
+ if (mouse_event && mouse_event->HasPosition()) {
if (LocalFrame* frame = GetDocument().GetFrame()) {
// Check if there is a selection and click is not on the
// selection.
@@ -188,14 +190,14 @@ void HTMLLabelElement::DefaultEventHandler(Event& evt) {
// should pass click event to control element.
// Only in case of drag, *neither* we pass the click event,
// *nor* we focus the control element.
- if (is_label_text_selected && ToMouseEvent(evt).ClickCount() == 1)
+ if (is_label_text_selected && mouse_event->ClickCount() == 1)
return;
}
}
processing_click_ = true;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kInput);
if (element->IsMouseFocusable()) {
// If the label is *not* selected, or if the click happened on
// selection of label, only then focus the control element.
@@ -203,7 +205,7 @@ void HTMLLabelElement::DefaultEventHandler(Event& evt) {
// so do not focus the control element.
if (!is_label_text_selected) {
element->focus(FocusParams(SelectionBehaviorOnFocus::kRestore,
- kWebFocusTypeMouse, nullptr));
+ mojom::blink::FocusType::kMouse, nullptr));
}
}
@@ -236,7 +238,7 @@ void HTMLLabelElement::focus(const FocusParams& params) {
return;
}
- if (params.type == blink::kWebFocusTypeAccessKey)
+ if (params.type == blink::mojom::blink::FocusType::kAccessKey)
return;
// To match other browsers, always restore previous selection.
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_opt_group_element.cc b/chromium/third_party/blink/renderer/core/html/forms/html_opt_group_element.cc
index 3c09fa5d8c1..ae6b2f65cfd 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_opt_group_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_opt_group_element.cc
@@ -84,6 +84,30 @@ bool HTMLOptGroupElement::MatchesEnabledPseudoClass() const {
return !IsDisabledFormControl();
}
+void HTMLOptGroupElement::ChildrenChanged(const ChildrenChange& change) {
+ HTMLElement::ChildrenChanged(change);
+ auto* select = OwnerSelectElement();
+ if (!select)
+ return;
+ if (change.type == ChildrenChangeType::kElementInserted) {
+ if (auto* option = DynamicTo<HTMLOptionElement>(change.sibling_changed))
+ select->OptionInserted(*option, option->Selected());
+ } else if (change.type == ChildrenChangeType::kElementRemoved) {
+ if (auto* option = DynamicTo<HTMLOptionElement>(change.sibling_changed))
+ select->OptionRemoved(*option);
+ } else if (change.type == ChildrenChangeType::kAllChildrenRemoved) {
+ DCHECK(change.removed_nodes);
+ for (Node* node : *change.removed_nodes) {
+ if (auto* option = DynamicTo<HTMLOptionElement>(node))
+ select->OptionRemoved(*option);
+ }
+ }
+}
+
+bool HTMLOptGroupElement::ChildrenChangedAllChildrenRemovedNeedsList() const {
+ return true;
+}
+
Node::InsertionNotificationRequest HTMLOptGroupElement::InsertedInto(
ContainerNode& insertion_point) {
HTMLElement::InsertedInto(insertion_point);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_opt_group_element.h b/chromium/third_party/blink/renderer/core/html/forms/html_opt_group_element.h
index 693aa166b9b..a03db9bb975 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_opt_group_element.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_opt_group_element.h
@@ -52,6 +52,8 @@ class CORE_EXPORT HTMLOptGroupElement final : public HTMLElement {
~HTMLOptGroupElement() override;
bool SupportsFocus() const override;
+ void ChildrenChanged(const ChildrenChange& change) override;
+ bool ChildrenChangedAllChildrenRemovedNeedsList() const override;
void ParseAttribute(const AttributeModificationParams&) override;
void AccessKeyAction(bool send_mouse_events) override;
void DidAddUserAgentShadowRoot(ShadowRoot&) override;
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 01ce55d9a26..bce8b9e77da 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
@@ -182,6 +182,8 @@ void HTMLOptionElement::ParseAttribute(
SetSelected(!params.new_value.IsNull());
PseudoStateChanged(CSSSelector::kPseudoDefault);
} else if (name == html_names::kLabelAttr) {
+ if (HTMLSelectElement* select = OwnerSelectElement())
+ select->OptionElementChildrenChanged(*this);
UpdateLabel();
} else {
HTMLElement::ParseAttribute(params);
@@ -249,8 +251,7 @@ void HTMLOptionElement::SetSelectedState(bool selected) {
// notifications only when it's a listbox (and not a menu list). If
// there's no layoutObject, fire them anyway just to be safe (to make sure
// the AX tree is in sync).
- if (!select->GetLayoutObject() ||
- select->GetLayoutObject()->IsListBox()) {
+ if (!select->GetLayoutObject() || !select->UsesMenuList()) {
cache->ListboxOptionStateChanged(this);
cache->ListboxSelectedChildrenChanged(select);
}
@@ -338,30 +339,6 @@ String HTMLOptionElement::DefaultToolTip() const {
return String();
}
-Node::InsertionNotificationRequest HTMLOptionElement::InsertedInto(
- ContainerNode& insertion_point) {
- HTMLElement::InsertedInto(insertion_point);
- if (HTMLSelectElement* select = OwnerSelectElement()) {
- if (&insertion_point == select ||
- (IsA<HTMLOptGroupElement>(insertion_point) &&
- insertion_point.parentNode() == select))
- select->OptionInserted(*this, is_selected_);
- }
- return kInsertionDone;
-}
-
-void HTMLOptionElement::RemovedFrom(ContainerNode& insertion_point) {
- if (auto* select = DynamicTo<HTMLSelectElement>(insertion_point)) {
- if (!parentNode() || IsA<HTMLOptGroupElement>(*parentNode()))
- select->OptionRemoved(*this);
- } else if (IsA<HTMLOptGroupElement>(insertion_point)) {
- select = DynamicTo<HTMLSelectElement>(insertion_point.parentNode());
- if (select)
- select->OptionRemoved(*this);
- }
- HTMLElement::RemovedFrom(insertion_point);
-}
-
String HTMLOptionElement::CollectOptionInnerText() const {
StringBuilder text;
for (Node* node = firstChild(); node;) {
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 ce663f6bab0..87e6b6a698e 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
@@ -38,6 +38,13 @@ class CORE_EXPORT HTMLOptionElement final : public HTMLElement {
DEFINE_WRAPPERTYPEINFO();
public:
+ static HTMLOptionElement* CreateForJSConstructor(
+ Document& document,
+ const String& data,
+ ExceptionState& exception_state) {
+ return CreateForJSConstructor(document, data, AtomicString(), false, false,
+ exception_state);
+ }
static HTMLOptionElement* CreateForJSConstructor(Document&,
const String& data,
const AtomicString& value,
@@ -101,8 +108,6 @@ class CORE_EXPORT HTMLOptionElement final : public HTMLElement {
bool MatchesDefaultPseudoClass() const override;
bool MatchesEnabledPseudoClass() const override;
void ParseAttribute(const AttributeModificationParams&) override;
- InsertionNotificationRequest InsertedInto(ContainerNode&) override;
- void RemovedFrom(ContainerNode&) override;
void AccessKeyAction(bool) override;
void ChildrenChanged(const ChildrenChange&) override;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_option_element.idl b/chromium/third_party/blink/renderer/core/html/forms/html_option_element.idl
index fd2eb010c43..a243648d99e 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_option_element.idl
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_option_element.idl
@@ -21,13 +21,15 @@
// https://html.spec.whatwg.org/C/#the-option-element
[
+ ConstructorCallWith=Document,
Exposed=Window,
HTMLConstructor,
- NamedConstructor=Option(optional DOMString data = null,
- optional DOMString value = null,
+ NamedConstructor=Option(optional DOMString data = "",
+ optional DOMString value,
optional boolean defaultSelected = false,
optional boolean selected = false),
- ConstructorCallWith=Document,
+ NamedConstructor_CallWith=Document,
+ NamedConstructor_RaisesException,
RaisesException=Constructor
] interface HTMLOptionElement : HTMLElement {
[CEReactions, Reflect] attribute boolean disabled;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_options_collection.cc b/chromium/third_party/blink/renderer/core/html/forms/html_options_collection.cc
index 13c3d226f3d..569dfb38923 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_options_collection.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_options_collection.cc
@@ -94,17 +94,17 @@ void HTMLOptionsCollection::setLength(unsigned length,
To<HTMLSelectElement>(ownerNode()).setLength(length, exception_state);
}
-bool HTMLOptionsCollection::AnonymousIndexedSetter(
+IndexedPropertySetterResult HTMLOptionsCollection::AnonymousIndexedSetter(
unsigned index,
HTMLOptionElement* value,
ExceptionState& exception_state) {
auto& base = To<HTMLSelectElement>(ownerNode());
if (!value) { // undefined or null
base.remove(index);
- return true;
+ return IndexedPropertySetterResult::kIntercepted;
}
base.SetOption(index, value, exception_state);
- return true;
+ return IndexedPropertySetterResult::kIntercepted;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_options_collection.h b/chromium/third_party/blink/renderer/core/html/forms/html_options_collection.h
index 2f371ef293b..d9e50d98190 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_options_collection.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_options_collection.h
@@ -26,6 +26,8 @@
#include "third_party/blink/renderer/core/html/forms/html_option_element.h"
#include "third_party/blink/renderer/core/html/html_collection.h"
+#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -53,7 +55,9 @@ class HTMLOptionsCollection final : public HTMLCollection {
void setSelectedIndex(int);
void setLength(unsigned, ExceptionState&);
- bool AnonymousIndexedSetter(unsigned, HTMLOptionElement*, ExceptionState&);
+ IndexedPropertySetterResult AnonymousIndexedSetter(unsigned,
+ HTMLOptionElement*,
+ ExceptionState&);
bool ElementMatches(const HTMLElement&) const;
@@ -61,11 +65,12 @@ class HTMLOptionsCollection final : public HTMLCollection {
void SupportedPropertyNames(Vector<String>& names) override;
};
-DEFINE_TYPE_CASTS(HTMLOptionsCollection,
- LiveNodeListBase,
- collection,
- collection->GetType() == kSelectOptions,
- collection.GetType() == kSelectOptions);
+template <>
+struct DowncastTraits<HTMLOptionsCollection> {
+ static bool AllowFrom(const LiveNodeListBase& collection) {
+ return collection.GetType() == kSelectOptions;
+ }
+};
inline bool HTMLOptionsCollection::ElementMatches(
const HTMLElement& element) const {
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 a02e8b059ac..a5f4eb0657c 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
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/core/html/forms/html_select_element.h"
#include "build/build_config.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/strings/grit/blink_strings.h"
#include "third_party/blink/renderer/bindings/core/v8/html_element_or_long.h"
@@ -39,45 +40,38 @@
#include "third_party/blink/renderer/core/dom/attribute.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h"
-#include "third_party/blink/renderer/core/dom/mutation_observer.h"
-#include "third_party/blink/renderer/core/dom/mutation_observer_init.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/node_lists_node_data.h"
#include "third_party/blink/renderer/core/dom/node_traversal.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"
-#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/web_feature.h"
#include "third_party/blink/renderer/core/html/forms/form_controller.h"
#include "third_party/blink/renderer/core/html/forms/form_data.h"
#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/popup_menu.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"
#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/core/input/event_handler.h"
-#include "third_party/blink/renderer/core/input/input_device_capabilities.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#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_list_box.h"
-#include "third_party/blink/renderer/core/layout/layout_menu_list.h"
+#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
+#include "third_party/blink/renderer/core/layout/layout_object_factory.h"
#include "third_party/blink/renderer/core/layout/layout_theme.h"
-#include "third_party/blink/renderer/core/page/autoscroll_controller.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/page/spatial_navigation.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/platform/bindings/exception_state.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/text/platform_locale.h"
+#include "ui/base/ui_base_features.h"
namespace blink {
@@ -86,18 +80,21 @@ namespace blink {
// signed.
static const unsigned kMaxListItems = INT_MAX;
+// Default size when the multiple attribute is present but size attribute is
+// absent.
+const int kDefaultListBoxSize = 4;
+
HTMLSelectElement::HTMLSelectElement(Document& document)
: HTMLFormControlElementWithState(html_names::kSelectTag, document),
type_ahead_(this),
size_(0),
last_on_change_option_(nullptr),
is_multiple_(false),
- is_in_non_contiguous_selection_(false),
- active_selection_state_(false),
should_recalc_list_items_(false),
is_autofilled_by_preview_(false),
- index_to_select_on_cancel_(-1),
- popup_is_visible_(false) {
+ index_to_select_on_cancel_(-1) {
+ // Make sure SelectType is created after initializing |uses_menu_list_|.
+ select_type_ = SelectType::Create(*this);
SetHasCustomStyleCallbacks();
EnsureUserAgentShadowRoot();
}
@@ -106,7 +103,7 @@ HTMLSelectElement::~HTMLSelectElement() = default;
// static
bool HTMLSelectElement::CanAssignToSelectSlot(const Node& node) {
- // Even if options/optgroups are not rendered as children of LayoutMenuList,
+ // Even if options/optgroups are not rendered as children of menulist SELECT,
// we still need to add them to the flat tree through slotting since we need
// their ComputedStyle for popup rendering.
return node.HasTagName(html_names::kOptionTag) ||
@@ -163,9 +160,6 @@ String HTMLSelectElement::validationMessage() const {
}
bool HTMLSelectElement::ValueMissing() const {
- if (!willValidate())
- return false;
-
if (!IsRequired())
return false;
@@ -187,21 +181,48 @@ void HTMLSelectElement::SelectMultipleOptionsByPopup(
const Vector<int>& list_indices) {
DCHECK(UsesMenuList());
DCHECK(IsMultiple());
- for (wtf_size_t i = 0; i < list_indices.size(); ++i) {
- bool add_selection_if_not_first = i > 0;
- if (HTMLOptionElement* option = OptionAtListIndex(list_indices[i]))
- UpdateSelectedState(option, add_selection_if_not_first, false);
+
+ HeapHashSet<Member<HTMLOptionElement>> old_selection;
+ for (auto* option : GetOptionList()) {
+ if (option->Selected()) {
+ old_selection.insert(option);
+ option->SetSelectedState(false);
+ }
}
+
+ bool has_new_selection = false;
+ for (int list_index : list_indices) {
+ if (auto* option = OptionAtListIndex(list_index)) {
+ option->SetSelectedState(true);
+ option->SetDirty(true);
+ auto iter = old_selection.find(option);
+ if (iter != old_selection.end())
+ old_selection.erase(iter);
+ else
+ has_new_selection = true;
+ }
+ }
+
SetNeedsValidityCheck();
- // TODO(tkent): Using listBoxOnChange() is very confusing.
- ListBoxOnChange();
+ if (has_new_selection || !old_selection.IsEmpty()) {
+ DispatchInputEvent();
+ DispatchChangeEvent();
+ }
}
-bool HTMLSelectElement::UsesMenuList() const {
- if (LayoutTheme::GetTheme().DelegatesMenuListRendering())
- return true;
+unsigned HTMLSelectElement::ListBoxSize() const {
+ DCHECK(!UsesMenuList());
+ const unsigned specified_size = size();
+ if (specified_size >= 1)
+ return specified_size;
+ return kDefaultListBoxSize;
+}
- return !is_multiple_ && size_ <= 1;
+void HTMLSelectElement::UpdateUsesMenuList() {
+ if (LayoutTheme::GetTheme().DelegatesMenuListRendering())
+ uses_menu_list_ = true;
+ else
+ uses_menu_list_ = !is_multiple_ && size_ <= 1;
}
int HTMLSelectElement::ActiveSelectionEndListIndex() const {
@@ -269,8 +290,8 @@ void HTMLSelectElement::setValue(const String& value, bool send_events) {
flags |= kDispatchInputAndChangeEventFlag;
SelectOption(option, flags);
- if (send_events && previous_selected_option != option && !UsesMenuList())
- ListBoxOnChange();
+ if (send_events && previous_selected_option != option)
+ select_type_->ListBoxOnChange();
}
String HTMLSelectElement::SuggestedValue() const {
@@ -314,9 +335,10 @@ void HTMLSelectElement::ParseAttribute(
SetNeedsValidityCheck();
if (size_ != old_size) {
ChangeRendering();
+ UpdateUserAgentShadowTree(*UserAgentShadowRoot());
ResetToDefaultSelection();
- if (!UsesMenuList())
- SaveListboxActiveSelection();
+ select_type_->UpdateTextStyleAndContent();
+ select_type_->SaveListboxActiveSelection();
}
} else if (params.name == html_names::kMultipleAttr) {
ParseMultipleAttribute(params.new_value);
@@ -332,15 +354,29 @@ bool HTMLSelectElement::MayTriggerVirtualKeyboard() const {
return true;
}
+bool HTMLSelectElement::ShouldHaveFocusAppearance() const {
+ // For FormControlsRefresh don't draw focus ring for a select that has its
+ // popup open.
+ if (::features::IsFormControlsRefreshEnabled() && PopupIsVisible())
+ return false;
+
+ return HTMLFormControlElementWithState::ShouldHaveFocusAppearance();
+}
+
bool HTMLSelectElement::CanSelectAll() const {
return !UsesMenuList();
}
-LayoutObject* HTMLSelectElement::CreateLayoutObject(const ComputedStyle&,
- LegacyLayout) {
+bool HTMLSelectElement::TypeShouldForceLegacyLayout() const {
+ return UsesMenuList();
+}
+
+LayoutObject* HTMLSelectElement::CreateLayoutObject(
+ const ComputedStyle& style,
+ LegacyLayout legacy_layout) {
if (UsesMenuList())
- return new LayoutMenuList(this);
- return new LayoutListBox(this);
+ return LayoutObjectFactory::CreateFlexibleBox(*this, style, legacy_layout);
+ return LayoutObjectFactory::CreateBlockFlow(*this, style, legacy_layout);
}
HTMLCollection* HTMLSelectElement::selectedOptions() {
@@ -355,9 +391,9 @@ void HTMLSelectElement::OptionElementChildrenChanged(
const HTMLOptionElement& option) {
SetNeedsValidityCheck();
+ if (option.Selected())
+ select_type_->UpdateTextStyleAndContent();
if (GetLayoutObject()) {
- if (option.Selected() && UsesMenuList())
- GetLayoutObject()->UpdateFromElement();
if (AXObjectCache* cache =
GetLayoutObject()->GetDocument().ExistingAXObjectCache())
cache->ChildrenChanged(this);
@@ -385,7 +421,7 @@ void HTMLSelectElement::SetOption(unsigned index,
// We should check |index >= maxListItems| first to avoid integer overflow.
if (index >= kMaxListItems ||
GetListItems().size() + diff + 1 > kMaxListItems) {
- GetDocument().AddConsoleMessage(ConsoleMessage::Create(
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning,
String::Format("Blocked to expand the option list and set an option at "
@@ -418,7 +454,7 @@ void HTMLSelectElement::setLength(unsigned new_len,
// We should check |newLen > maxListItems| first to avoid integer overflow.
if (new_len > kMaxListItems ||
GetListItems().size() + new_len - length() > kMaxListItems) {
- GetDocument().AddConsoleMessage(ConsoleMessage::Create(
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning,
String::Format("Blocked to expand the option list to %u items. The "
@@ -469,246 +505,19 @@ HTMLOptionElement* HTMLSelectElement::OptionAtListIndex(int list_index) const {
return DynamicTo<HTMLOptionElement>(items[list_index].Get());
}
-// Returns the 1st valid OPTION |skip| items from |listIndex| in direction
-// |direction| if there is one.
-// Otherwise, it returns the valid OPTION closest to that boundary which is past
-// |listIndex| if there is one.
-// Otherwise, it returns nullptr.
-// Valid means that it is enabled and visible.
-HTMLOptionElement* HTMLSelectElement::NextValidOption(int list_index,
- SkipDirection direction,
- int skip) const {
- DCHECK(direction == kSkipBackwards || direction == kSkipForwards);
- const ListItems& list_items = GetListItems();
- HTMLOptionElement* last_good_option = nullptr;
- int size = list_items.size();
- for (list_index += direction; list_index >= 0 && list_index < size;
- list_index += direction) {
- --skip;
- HTMLElement* element = list_items[list_index];
- auto* option_element = DynamicTo<HTMLOptionElement>(element);
- if (!option_element)
- continue;
- if (option_element->IsDisplayNone())
- continue;
- if (element->IsDisabledFormControl())
- continue;
- if (!UsesMenuList() && !element->GetLayoutObject())
- continue;
- last_good_option = option_element;
- if (skip <= 0)
- break;
- }
- return last_good_option;
-}
-
-HTMLOptionElement* HTMLSelectElement::NextSelectableOption(
- HTMLOptionElement* start_option) const {
- return NextValidOption(start_option ? start_option->ListIndex() : -1,
- kSkipForwards, 1);
-}
-
-HTMLOptionElement* HTMLSelectElement::PreviousSelectableOption(
- HTMLOptionElement* start_option) const {
- return NextValidOption(
- start_option ? start_option->ListIndex() : GetListItems().size(),
- kSkipBackwards, 1);
-}
-
-HTMLOptionElement* HTMLSelectElement::FirstSelectableOption() const {
- // TODO(tkent): This is not efficient. nextSlectableOption(nullptr) is
- // faster.
- return NextValidOption(GetListItems().size(), kSkipBackwards, INT_MAX);
-}
-
-HTMLOptionElement* HTMLSelectElement::LastSelectableOption() const {
- // TODO(tkent): This is not efficient. previousSlectableOption(nullptr) is
- // faster.
- return NextValidOption(-1, kSkipForwards, INT_MAX);
-}
-
-// Returns the index of the next valid item one page away from |startIndex| in
-// direction |direction|.
-HTMLOptionElement* HTMLSelectElement::NextSelectableOptionPageAway(
- HTMLOptionElement* start_option,
- SkipDirection direction) const {
- const ListItems& items = GetListItems();
- // Can't use size_ because LayoutObject forces a minimum size.
- int page_size = 0;
- if (GetLayoutObject()->IsListBox()) {
- // -1 so we still show context.
- page_size = ToLayoutListBox(GetLayoutObject())->size() - 1;
- }
-
- // One page away, but not outside valid bounds.
- // If there is a valid option item one page away, the index is chosen.
- // If there is no exact one page away valid option, returns startIndex or
- // the most far index.
- int start_index = start_option ? start_option->ListIndex() : -1;
- int edge_index = (direction == kSkipForwards) ? 0 : (items.size() - 1);
- int skip_amount =
- page_size +
- ((direction == kSkipForwards) ? start_index : (edge_index - start_index));
- return NextValidOption(edge_index, direction, skip_amount);
-}
-
void HTMLSelectElement::SelectAll() {
- DCHECK(!UsesMenuList());
- if (!GetLayoutObject() || !is_multiple_)
- return;
-
- // Save the selection so it can be compared to the new selectAll selection
- // when dispatching change events.
- SaveLastSelection();
-
- active_selection_state_ = true;
- SetActiveSelectionAnchor(NextSelectableOption(nullptr));
- SetActiveSelectionEnd(PreviousSelectableOption(nullptr));
-
- UpdateListBoxSelection(false, false);
- ListBoxOnChange();
- SetNeedsValidityCheck();
-}
-
-void HTMLSelectElement::SaveLastSelection() {
- if (UsesMenuList()) {
- last_on_change_option_ = SelectedOption();
- return;
- }
-
- last_on_change_selection_.clear();
- for (auto& element : GetListItems()) {
- auto* option_element = DynamicTo<HTMLOptionElement>(element.Get());
- last_on_change_selection_.push_back(option_element &&
- option_element->Selected());
- }
+ select_type_->SelectAll();
}
void HTMLSelectElement::SetActiveSelectionAnchor(HTMLOptionElement* option) {
active_selection_anchor_ = option;
- if (!UsesMenuList())
- SaveListboxActiveSelection();
-}
-
-void HTMLSelectElement::SaveListboxActiveSelection() {
- // Cache the selection state so we can restore the old selection as the new
- // selection pivots around this anchor index.
- // Example:
- // 1. Press the mouse button on the second OPTION
- // active_selection_anchor_ points the second OPTION.
- // 2. Drag the mouse pointer onto the fifth OPTION
- // active_selection_end_ points the fifth OPTION, OPTIONs at 1-4 indices
- // are selected.
- // 3. Drag the mouse pointer onto the fourth OPTION
- // active_selection_end_ points the fourth OPTION, OPTIONs at 1-3 indices
- // are selected.
- // UpdateListBoxSelection needs to clear selection of the fifth OPTION.
- cached_state_for_active_selection_.resize(0);
- for (auto* const option : GetOptionList()) {
- cached_state_for_active_selection_.push_back(option->Selected());
- }
+ select_type_->SaveListboxActiveSelection();
}
void HTMLSelectElement::SetActiveSelectionEnd(HTMLOptionElement* option) {
active_selection_end_ = option;
}
-void HTMLSelectElement::UpdateListBoxSelection(bool deselect_other_options,
- bool scroll) {
- DCHECK(GetLayoutObject());
- DCHECK(GetLayoutObject()->IsListBox() || is_multiple_);
-
- int active_selection_anchor_index =
- active_selection_anchor_ ? active_selection_anchor_->index() : -1;
- int active_selection_end_index =
- active_selection_end_ ? active_selection_end_->index() : -1;
- int start =
- std::min(active_selection_anchor_index, active_selection_end_index);
- int end = std::max(active_selection_anchor_index, active_selection_end_index);
-
- int i = 0;
- for (auto* const option : GetOptionList()) {
- if (option->IsDisabledFormControl() || !option->GetLayoutObject()) {
- ++i;
- continue;
- }
- if (i >= start && i <= end) {
- option->SetSelectedState(active_selection_state_);
- option->SetDirty(true);
- } else if (deselect_other_options ||
- i >= static_cast<int>(
- cached_state_for_active_selection_.size())) {
- option->SetSelectedState(false);
- option->SetDirty(true);
- } else {
- option->SetSelectedState(cached_state_for_active_selection_[i]);
- }
- ++i;
- }
-
- UpdateMultiSelectListBoxFocus();
- SetNeedsValidityCheck();
- if (scroll)
- ScrollToSelection();
- NotifyFormStateChanged();
-}
-
-void HTMLSelectElement::ListBoxOnChange() {
- DCHECK(!UsesMenuList() || is_multiple_);
-
- const ListItems& items = GetListItems();
-
- // If the cached selection list is empty, or the size has changed, then fire
- // dispatchFormControlChangeEvent, and return early.
- // FIXME: Why? This looks unreasonable.
- if (last_on_change_selection_.IsEmpty() ||
- last_on_change_selection_.size() != items.size()) {
- DispatchChangeEvent();
- return;
- }
-
- // Update last_on_change_selection_ and fire a 'change' event.
- bool fire_on_change = false;
- for (unsigned i = 0; i < items.size(); ++i) {
- HTMLElement* element = items[i];
- auto* option_element = DynamicTo<HTMLOptionElement>(element);
- bool selected = option_element && option_element->Selected();
- if (selected != last_on_change_selection_[i])
- fire_on_change = true;
- last_on_change_selection_[i] = selected;
- }
-
- if (fire_on_change) {
- DispatchInputEvent();
- DispatchChangeEvent();
- }
-}
-
-void HTMLSelectElement::UpdateMultiSelectListBoxFocus() {
- if (!is_multiple_)
- return;
-
- for (auto* const option : GetOptionList()) {
- if (option->IsDisabledFormControl() || !option->GetLayoutObject())
- continue;
- bool is_focused =
- (option == active_selection_end_) && is_in_non_contiguous_selection_;
- option->SetMultiSelectFocusedState(is_focused);
- }
- ScrollToSelection();
-}
-
-void HTMLSelectElement::DispatchInputAndChangeEventForMenuList() {
- DCHECK(UsesMenuList());
-
- HTMLOptionElement* selected_option = SelectedOption();
- if (last_on_change_option_.Get() != selected_option) {
- last_on_change_option_ = selected_option;
- DispatchInputEvent();
- DispatchChangeEvent();
- }
-}
-
void HTMLSelectElement::ScrollToSelection() {
if (!IsFinishedParsingChildren())
return;
@@ -719,16 +528,6 @@ void HTMLSelectElement::ScrollToSelection() {
cache->ListboxActiveIndexChanged(this);
}
-void HTMLSelectElement::SetOptionsChangedOnLayoutObject() {
- if (LayoutObject* layout_object = GetLayoutObject()) {
- if (!UsesMenuList())
- return;
- ToLayoutMenuList(layout_object)
- ->SetNeedsLayoutAndPrefWidthsRecalc(
- layout_invalidation_reason::kMenuOptionsChanged);
- }
-}
-
const HTMLSelectElement::ListItems& HTMLSelectElement::GetListItems() const {
if (should_recalc_list_items_) {
RecalcListItems();
@@ -755,7 +554,7 @@ void HTMLSelectElement::SetRecalcListItems() {
should_recalc_list_items_ = true;
- SetOptionsChangedOnLayoutObject();
+ select_type_->MaximumOptionWidthMightBeChanged();
if (!isConnected()) {
if (HTMLOptionsCollection* collection =
CachedCollection<HTMLOptionsCollection>(kSelectOptions))
@@ -903,12 +702,7 @@ void HTMLSelectElement::SetSuggestedOption(HTMLOptionElement* option) {
return;
suggested_option_ = option;
- if (LayoutObject* layout_object = GetLayoutObject()) {
- layout_object->UpdateFromElement();
- ScrollToOption(option);
- }
- if (PopupIsVisible())
- popup_->UpdateFromElement(PopupMenu::kBySelectionChange);
+ select_type_->DidSetSuggestedOption(option);
}
void HTMLSelectElement::ScrollToOption(HTMLOptionElement* option) {
@@ -936,11 +730,23 @@ void HTMLSelectElement::ScrollToOptionTask() {
// OptionRemoved() makes sure option_to_scroll_to_ doesn't have an option with
// another owner.
DCHECK_EQ(option->OwnerSelectElement(), this);
- GetDocument().UpdateStyleAndLayout();
- if (!GetLayoutObject() || !GetLayoutObject()->IsListBox())
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kScroll);
+ if (!GetLayoutObject() || UsesMenuList())
return;
PhysicalRect bounds = option->BoundingBoxForScrollIntoView();
- ToLayoutListBox(GetLayoutObject())->ScrollToRect(bounds);
+
+ // The following code will not scroll parent boxes unlike ScrollRectToVisible.
+ auto* box = GetLayoutBox();
+ if (!box->HasOverflowClip())
+ return;
+ DCHECK(box->Layer());
+ DCHECK(box->Layer()->GetScrollableArea());
+ box->Layer()->GetScrollableArea()->ScrollIntoView(
+ bounds,
+ ScrollAlignment::CreateScrollIntoViewParams(
+ ScrollAlignment::ToEdgeIfNeeded(), ScrollAlignment::ToEdgeIfNeeded(),
+ mojom::blink::ScrollType::kProgrammatic, false,
+ mojom::blink::ScrollBehavior::kInstant));
}
void HTMLSelectElement::OptionSelectionStateChanged(HTMLOptionElement* option,
@@ -954,6 +760,41 @@ void HTMLSelectElement::OptionSelectionStateChanged(HTMLOptionElement* option,
ResetToDefaultSelection();
}
+void HTMLSelectElement::ChildrenChanged(const ChildrenChange& change) {
+ HTMLFormControlElementWithState::ChildrenChanged(change);
+ if (change.type == ChildrenChangeType::kElementInserted) {
+ if (auto* option = DynamicTo<HTMLOptionElement>(change.sibling_changed)) {
+ OptionInserted(*option, option->Selected());
+ } else if (auto* optgroup =
+ DynamicTo<HTMLOptGroupElement>(change.sibling_changed)) {
+ for (auto& option : Traversal<HTMLOptionElement>::ChildrenOf(*optgroup))
+ OptionInserted(option, option.Selected());
+ }
+ } else if (change.type == ChildrenChangeType::kElementRemoved) {
+ if (auto* option = DynamicTo<HTMLOptionElement>(change.sibling_changed)) {
+ OptionRemoved(*option);
+ } else if (auto* optgroup =
+ DynamicTo<HTMLOptGroupElement>(change.sibling_changed)) {
+ for (auto& option : Traversal<HTMLOptionElement>::ChildrenOf(*optgroup))
+ OptionRemoved(option);
+ }
+ } else if (change.type == ChildrenChangeType::kAllChildrenRemoved) {
+ DCHECK(change.removed_nodes);
+ for (Node* node : *change.removed_nodes) {
+ if (auto* option = DynamicTo<HTMLOptionElement>(node)) {
+ OptionRemoved(*option);
+ } else if (auto* optgroup = DynamicTo<HTMLOptGroupElement>(node)) {
+ for (auto& option : Traversal<HTMLOptionElement>::ChildrenOf(*optgroup))
+ OptionRemoved(option);
+ }
+ }
+ }
+}
+
+bool HTMLSelectElement::ChildrenChangedAllChildrenRemovedNeedsList() const {
+ return true;
+}
+
void HTMLSelectElement::OptionInserted(HTMLOptionElement& option,
bool option_is_selected) {
DCHECK_EQ(option.OwnerSelectElement(), this);
@@ -966,7 +807,7 @@ void HTMLSelectElement::OptionInserted(HTMLOptionElement& option,
ResetToDefaultSelection();
}
SetNeedsValidityCheck();
- last_on_change_selection_.clear();
+ select_type_->ClearLastOnChangeSelection();
if (!GetDocument().IsActive())
return;
@@ -997,7 +838,7 @@ void HTMLSelectElement::OptionRemoved(HTMLOptionElement& option) {
if (option.Selected())
SetAutofillState(WebAutofillState::kNotFilled);
SetNeedsValidityCheck();
- last_on_change_selection_.clear();
+ select_type_->ClearLastOnChangeSelection();
if (!GetDocument().IsActive())
return;
@@ -1013,12 +854,12 @@ void HTMLSelectElement::OptGroupInsertedOrRemoved(
HTMLOptGroupElement& optgroup) {
SetRecalcListItems();
SetNeedsValidityCheck();
- last_on_change_selection_.clear();
+ select_type_->ClearLastOnChangeSelection();
}
void HTMLSelectElement::HrInsertedOrRemoved(HTMLHRElement& hr) {
SetRecalcListItems();
- last_on_change_selection_.clear();
+ select_type_->ClearLastOnChangeSelection();
}
// TODO(tkent): This function is not efficient. It contains multiple O(N)
@@ -1057,40 +898,7 @@ void HTMLSelectElement::SelectOption(HTMLOptionElement* element,
SetActiveSelectionEnd(element);
}
- // Need to update last_on_change_option_ before
- // LayoutMenuList::UpdateFromElement.
- bool should_dispatch_events = false;
- if (UsesMenuList()) {
- should_dispatch_events = (flags & kDispatchInputAndChangeEventFlag) &&
- last_on_change_option_ != element;
- last_on_change_option_ = element;
- }
-
- // For the menu list case, this is what makes the selected element appear.
- if (LayoutObject* layout_object = GetLayoutObject())
- layout_object->UpdateFromElement();
- // PopupMenu::UpdateFromElement() posts an O(N) task.
- if (PopupIsVisible() && should_update_popup)
- popup_->UpdateFromElement(PopupMenu::kBySelectionChange);
-
- ScrollToSelection();
- SetNeedsValidityCheck();
-
- if (UsesMenuList()) {
- if (should_dispatch_events) {
- DispatchInputEvent();
- DispatchChangeEvent();
- }
- if (LayoutObject* layout_object = GetLayoutObject()) {
- // Need to check UsesMenuList() again because event handlers might
- // change the status.
- if (UsesMenuList()) {
- // DidSelectOption() is O(N) because of HTMLOptionElement::index().
- ToLayoutMenuList(layout_object)->DidSelectOption(element);
- }
- }
- }
-
+ select_type_->DidSelectOption(element, flags, should_update_popup);
NotifyFormStateChanged();
if (LocalFrame::HasTransientUserActivation(GetDocument().GetFrame()) &&
@@ -1104,29 +912,22 @@ void HTMLSelectElement::SelectOption(HTMLOptionElement* element,
void HTMLSelectElement::DispatchFocusEvent(
Element* old_focused_element,
- WebFocusType type,
+ mojom::blink::FocusType type,
InputDeviceCapabilities* source_capabilities) {
// Save the selection so it can be compared to the new selection when
// dispatching change events during blur event dispatch.
if (UsesMenuList())
- SaveLastSelection();
+ select_type_->SaveLastSelection();
HTMLFormControlElementWithState::DispatchFocusEvent(old_focused_element, type,
source_capabilities);
}
void HTMLSelectElement::DispatchBlurEvent(
Element* new_focused_element,
- WebFocusType type,
+ mojom::blink::FocusType type,
InputDeviceCapabilities* source_capabilities) {
type_ahead_.ResetSession();
- // We only need to fire change events here for menu lists, because we fire
- // change events for list boxes whenever the selection change is actually
- // made. This matches other browsers' behavior.
- if (UsesMenuList())
- DispatchInputAndChangeEventForMenuList();
- last_on_change_selection_.clear();
- if (PopupIsVisible())
- HidePopup();
+ select_type_->DidBlur();
HTMLFormControlElementWithState::DispatchBlurEvent(new_focused_element, type,
source_capabilities);
}
@@ -1240,6 +1041,7 @@ void HTMLSelectElement::RestoreFormControlState(const FormControlState& state) {
}
SetNeedsValidityCheck();
+ select_type_->UpdateTextStyleAndContent();
}
void HTMLSelectElement::ParseMultipleAttribute(const AtomicString& value) {
@@ -1248,6 +1050,7 @@ void HTMLSelectElement::ParseMultipleAttribute(const AtomicString& value) {
is_multiple_ = !value.IsNull();
SetNeedsValidityCheck();
ChangeRendering();
+ UpdateUserAgentShadowTree(*UserAgentShadowRoot());
// Restore selectedIndex after changing the multiple flag to preserve
// selection as single-line and multi-line has different defaults.
if (old_multiple != is_multiple_) {
@@ -1259,6 +1062,7 @@ void HTMLSelectElement::ParseMultipleAttribute(const AtomicString& value) {
else
ResetToDefaultSelection();
}
+ select_type_->UpdateTextStyleAndContent();
}
void HTMLSelectElement::AppendToFormData(FormData& form_data) {
@@ -1279,228 +1083,12 @@ void HTMLSelectElement::ResetImpl() {
option->SetDirty(false);
}
ResetToDefaultSelection();
+ select_type_->UpdateTextStyleAndContent();
SetNeedsValidityCheck();
}
-void HTMLSelectElement::HandlePopupOpenKeyboardEvent(Event& event) {
- focus();
- // Calling focus() may cause us to lose our layoutObject. Return true so
- // that our caller doesn't process the event further, but don't set
- // the event as handled.
- if (!GetLayoutObject() || !GetLayoutObject()->IsMenuList() ||
- IsDisabledFormControl())
- return;
- // Save the selection so it can be compared to the new selection when
- // dispatching change events during selectOption, which gets called from
- // selectOptionByPopup, which gets called after the user makes a selection
- // from the menu.
- SaveLastSelection();
- ShowPopup();
- event.SetDefaultHandled();
- return;
-}
-
-bool HTMLSelectElement::ShouldOpenPopupForKeyDownEvent(
- const KeyboardEvent& key_event) {
- const String& key = key_event.key();
- LayoutTheme& layout_theme = LayoutTheme::GetTheme();
-
- if (IsSpatialNavigationEnabled(GetDocument().GetFrame()))
- return false;
-
- return ((layout_theme.PopsMenuByArrowKeys() &&
- (key == "ArrowDown" || key == "ArrowUp")) ||
- (layout_theme.PopsMenuByAltDownUpOrF4Key() &&
- (key == "ArrowDown" || key == "ArrowUp") && key_event.altKey()) ||
- (layout_theme.PopsMenuByAltDownUpOrF4Key() &&
- (!key_event.altKey() && !key_event.ctrlKey() && key == "F4")));
-}
-
-bool HTMLSelectElement::ShouldOpenPopupForKeyPressEvent(
- const KeyboardEvent& event) {
- LayoutTheme& layout_theme = LayoutTheme::GetTheme();
- int key_code = event.keyCode();
-
- return ((layout_theme.PopsMenuBySpaceKey() && key_code == ' ' &&
- !type_ahead_.HasActiveSession(event)) ||
- (layout_theme.PopsMenuByReturnKey() && key_code == '\r'));
-}
-
-void HTMLSelectElement::MenuListDefaultEventHandler(Event& event) {
- // We need to make the layout tree up-to-date to have GetLayoutObject() give
- // the correct result below. An author event handler may have set display to
- // some element to none which will cause a layout tree detach.
- GetDocument().UpdateStyleAndLayoutTree();
-
- if (event.type() == event_type_names::kKeydown) {
- if (!GetLayoutObject() || !event.IsKeyboardEvent())
- return;
-
- auto& key_event = ToKeyboardEvent(event);
- if (ShouldOpenPopupForKeyDownEvent(key_event)) {
- HandlePopupOpenKeyboardEvent(event);
- return;
- }
-
- // When using spatial navigation, we want to be able to navigate away
- // from the select element when the user hits any of the arrow keys,
- // instead of changing the selection.
- if (IsSpatialNavigationEnabled(GetDocument().GetFrame())) {
- if (!active_selection_state_)
- return;
- }
-
- // The key handling below shouldn't be used for non spatial navigation
- // mode Mac
- if (LayoutTheme::GetTheme().PopsMenuByArrowKeys() &&
- !IsSpatialNavigationEnabled(GetDocument().GetFrame()))
- return;
-
- int ignore_modifiers = WebInputEvent::kShiftKey |
- WebInputEvent::kControlKey | WebInputEvent::kAltKey |
- WebInputEvent::kMetaKey;
- if (key_event.GetModifiers() & ignore_modifiers)
- return;
-
- const String& key = key_event.key();
- bool handled = true;
- const ListItems& list_items = GetListItems();
- HTMLOptionElement* option = SelectedOption();
- int list_index = option ? option->ListIndex() : -1;
-
- if (key == "ArrowDown" || key == "ArrowRight")
- option = NextValidOption(list_index, kSkipForwards, 1);
- else if (key == "ArrowUp" || key == "ArrowLeft")
- option = NextValidOption(list_index, kSkipBackwards, 1);
- else if (key == "PageDown")
- option = NextValidOption(list_index, kSkipForwards, 3);
- else if (key == "PageUp")
- option = NextValidOption(list_index, kSkipBackwards, 3);
- else if (key == "Home")
- option = NextValidOption(-1, kSkipForwards, 1);
- else if (key == "End")
- option = NextValidOption(list_items.size(), kSkipBackwards, 1);
- else
- handled = false;
-
- if (handled && option) {
- SelectOption(option, kDeselectOtherOptionsFlag | kMakeOptionDirtyFlag |
- kDispatchInputAndChangeEventFlag);
- }
-
- if (handled)
- event.SetDefaultHandled();
- }
-
- if (event.type() == event_type_names::kKeypress) {
- if (!GetLayoutObject() || !event.IsKeyboardEvent())
- return;
-
- int key_code = ToKeyboardEvent(event).keyCode();
- if (key_code == ' ' &&
- IsSpatialNavigationEnabled(GetDocument().GetFrame())) {
- // Use space to toggle arrow key handling for selection change or
- // spatial navigation.
- active_selection_state_ = !active_selection_state_;
- event.SetDefaultHandled();
- return;
- }
-
- auto& key_event = ToKeyboardEvent(event);
- if (ShouldOpenPopupForKeyPressEvent(key_event)) {
- HandlePopupOpenKeyboardEvent(event);
- return;
- }
-
- if (!LayoutTheme::GetTheme().PopsMenuByReturnKey() && key_code == '\r') {
- if (Form())
- Form()->SubmitImplicitly(event, false);
- DispatchInputAndChangeEventForMenuList();
- event.SetDefaultHandled();
- }
- }
-
- if (event.type() == event_type_names::kMousedown && event.IsMouseEvent() &&
- ToMouseEvent(event).button() ==
- static_cast<int16_t>(WebPointerProperties::Button::kLeft)) {
- InputDeviceCapabilities* source_capabilities =
- GetDocument()
- .domWindow()
- ->GetInputDeviceCapabilities()
- ->FiresTouchEvents(ToMouseEvent(event).FromTouch());
- focus(FocusParams(SelectionBehaviorOnFocus::kRestore, kWebFocusTypeNone,
- source_capabilities));
- if (GetLayoutObject() && GetLayoutObject()->IsMenuList() &&
- !IsDisabledFormControl()) {
- if (PopupIsVisible()) {
- HidePopup();
- } else {
- // Save the selection so it can be compared to the new selection
- // when we call onChange during selectOption, which gets called
- // from selectOptionByPopup, which gets called after the user
- // makes a selection from the menu.
- SaveLastSelection();
- // TODO(lanwei): Will check if we need to add
- // InputDeviceCapabilities here when select menu list gets
- // focus, see https://crbug.com/476530.
- ShowPopup();
- }
- }
- event.SetDefaultHandled();
- }
-}
-
-void HTMLSelectElement::UpdateSelectedState(HTMLOptionElement* clicked_option,
- bool multi,
- bool shift) {
- DCHECK(clicked_option);
- // Save the selection so it can be compared to the new selection when
- // dispatching change events during mouseup, or after autoscroll finishes.
- SaveLastSelection();
-
- active_selection_state_ = true;
-
- bool shift_select = is_multiple_ && shift;
- bool multi_select = is_multiple_ && multi && !shift;
-
- // Keep track of whether an active selection (like during drag selection),
- // should select or deselect.
- if (clicked_option->Selected() && multi_select) {
- active_selection_state_ = false;
- clicked_option->SetSelectedState(false);
- clicked_option->SetDirty(true);
- }
-
- // If we're not in any special multiple selection mode, then deselect all
- // other items, excluding the clicked option. If no option was clicked, then
- // this will deselect all items in the list.
- if (!shift_select && !multi_select)
- DeselectItemsWithoutValidation(clicked_option);
-
- // If the anchor hasn't been set, and we're doing a single selection or a
- // shift selection, then initialize the anchor to the first selected index.
- if (!active_selection_anchor_ && !multi_select)
- SetActiveSelectionAnchor(SelectedOption());
-
- // Set the selection state of the clicked option.
- if (!clicked_option->IsDisabledFormControl()) {
- clicked_option->SetSelectedState(true);
- clicked_option->SetDirty(true);
- }
-
- // If there was no selectedIndex() for the previous initialization, or If
- // we're doing a single selection, or a multiple selection (using cmd or
- // ctrl), then initialize the anchor index to the listIndex that just got
- // clicked.
- if (!active_selection_anchor_ || !shift_select)
- SetActiveSelectionAnchor(clicked_option);
-
- SetActiveSelectionEnd(clicked_option);
- UpdateListBoxSelection(!multi_select);
-}
-
-HTMLOptionElement* HTMLSelectElement::EventTargetOption(const Event& event) {
- return DynamicTo<HTMLOptionElement>(event.target()->ToNode());
+bool HTMLSelectElement::PopupIsVisible() const {
+ return select_type_->PopupIsVisible();
}
int HTMLSelectElement::ListIndexForOption(const HTMLOptionElement& option) {
@@ -1519,259 +1107,13 @@ AutoscrollController* HTMLSelectElement::GetAutoscrollController() const {
return nullptr;
}
-void HTMLSelectElement::HandleMouseRelease() {
- // We didn't start this click/drag on any options.
- if (last_on_change_selection_.IsEmpty())
- return;
- ListBoxOnChange();
-}
-
-void HTMLSelectElement::ListBoxDefaultEventHandler(Event& event) {
- if (event.type() == event_type_names::kGesturetap && event.IsGestureEvent()) {
- focus();
- // Calling focus() may cause us to lose our layoutObject or change the
- // layoutObject type, in which case do not want to handle the event.
- if (!GetLayoutObject() || !GetLayoutObject()->IsListBox())
- return;
-
- // Convert to coords relative to the list box if needed.
- auto& gesture_event = ToGestureEvent(event);
- if (HTMLOptionElement* option = EventTargetOption(gesture_event)) {
- if (!IsDisabledFormControl()) {
- UpdateSelectedState(option, true, gesture_event.shiftKey());
- ListBoxOnChange();
- }
- event.SetDefaultHandled();
- }
-
- } else if (event.type() == event_type_names::kMousedown &&
- event.IsMouseEvent() &&
- ToMouseEvent(event).button() ==
- static_cast<int16_t>(WebPointerProperties::Button::kLeft)) {
- focus();
- // Calling focus() may cause us to lose our layoutObject, in which case
- // do not want to handle the event.
- if (!GetLayoutObject() || !GetLayoutObject()->IsListBox() ||
- IsDisabledFormControl())
- return;
-
- // Convert to coords relative to the list box if needed.
- auto& mouse_event = ToMouseEvent(event);
- if (HTMLOptionElement* option = EventTargetOption(mouse_event)) {
- if (!option->IsDisabledFormControl()) {
-#if defined(OS_MACOSX)
- UpdateSelectedState(option, mouse_event.metaKey(),
- mouse_event.shiftKey());
-#else
- UpdateSelectedState(option, mouse_event.ctrlKey(),
- mouse_event.shiftKey());
-#endif
- }
- if (LocalFrame* frame = GetDocument().GetFrame())
- frame->GetEventHandler().SetMouseDownMayStartAutoscroll();
-
- event.SetDefaultHandled();
- }
-
- } else if (event.type() == event_type_names::kMousemove &&
- event.IsMouseEvent()) {
- auto& mouse_event = ToMouseEvent(event);
- if (mouse_event.button() !=
- static_cast<int16_t>(WebPointerProperties::Button::kLeft) ||
- !mouse_event.ButtonDown())
- return;
-
- LayoutObject* layout_object = GetLayoutObject();
- if (layout_object) {
- layout_object->GetFrameView()->UpdateAllLifecyclePhasesExceptPaint();
-
- if (Page* page = GetDocument().GetPage()) {
- page->GetAutoscrollController().StartAutoscrollForSelection(
- layout_object);
- }
- }
- // Mousedown didn't happen in this element.
- if (last_on_change_selection_.IsEmpty())
- return;
-
- if (HTMLOptionElement* option = EventTargetOption(mouse_event)) {
- if (!IsDisabledFormControl()) {
- if (is_multiple_) {
- // Only extend selection if there is something selected.
- if (!active_selection_anchor_)
- return;
-
- SetActiveSelectionEnd(option);
- UpdateListBoxSelection(false);
- } else {
- SetActiveSelectionAnchor(option);
- SetActiveSelectionEnd(option);
- UpdateListBoxSelection(true);
- }
- }
- }
-
- } else if (event.type() == event_type_names::kMouseup &&
- event.IsMouseEvent() &&
- ToMouseEvent(event).button() ==
- static_cast<int16_t>(WebPointerProperties::Button::kLeft) &&
- GetLayoutObject()) {
- if (GetDocument().GetPage() &&
- GetDocument()
- .GetPage()
- ->GetAutoscrollController()
- .AutoscrollInProgressFor(ToLayoutBox(GetLayoutObject())))
- GetDocument().GetPage()->GetAutoscrollController().StopAutoscroll();
- else
- HandleMouseRelease();
-
- } else if (event.type() == event_type_names::kKeydown) {
- if (!event.IsKeyboardEvent())
- return;
- const String& key = ToKeyboardEvent(event).key();
-
- bool handled = false;
- HTMLOptionElement* end_option = nullptr;
- if (!active_selection_end_) {
- // Initialize the end index
- if (key == "ArrowDown" || key == "PageDown") {
- HTMLOptionElement* start_option = LastSelectedOption();
- handled = true;
- if (key == "ArrowDown") {
- end_option = NextSelectableOption(start_option);
- } else {
- end_option =
- NextSelectableOptionPageAway(start_option, kSkipForwards);
- }
- } else if (key == "ArrowUp" || key == "PageUp") {
- HTMLOptionElement* start_option = SelectedOption();
- handled = true;
- if (key == "ArrowUp") {
- end_option = PreviousSelectableOption(start_option);
- } else {
- end_option =
- NextSelectableOptionPageAway(start_option, kSkipBackwards);
- }
- }
- } else {
- // Set the end index based on the current end index.
- if (key == "ArrowDown") {
- end_option = NextSelectableOption(active_selection_end_.Get());
- handled = true;
- } else if (key == "ArrowUp") {
- end_option = PreviousSelectableOption(active_selection_end_.Get());
- handled = true;
- } else if (key == "PageDown") {
- end_option = NextSelectableOptionPageAway(active_selection_end_.Get(),
- kSkipForwards);
- handled = true;
- } else if (key == "PageUp") {
- end_option = NextSelectableOptionPageAway(active_selection_end_.Get(),
- kSkipBackwards);
- handled = true;
- }
- }
- if (key == "Home") {
- end_option = FirstSelectableOption();
- handled = true;
- } else if (key == "End") {
- end_option = LastSelectableOption();
- handled = true;
- }
-
- if (IsSpatialNavigationEnabled(GetDocument().GetFrame())) {
- // Check if the selection moves to the boundary.
- if (key == "ArrowLeft" || key == "ArrowRight" ||
- ((key == "ArrowDown" || key == "ArrowUp") &&
- end_option == active_selection_end_))
- return;
- }
-
- bool is_control_key = false;
-#if defined(OS_MACOSX)
- is_control_key = ToKeyboardEvent(event).metaKey();
-#else
- is_control_key = ToKeyboardEvent(event).ctrlKey();
-#endif
-
- if (is_multiple_ && ToKeyboardEvent(event).keyCode() == ' ' &&
- is_control_key && active_selection_end_) {
- // Use ctrl+space to toggle selection change.
- ToggleSelection(*active_selection_end_);
- event.SetDefaultHandled();
- return;
- }
-
- if (end_option && handled) {
- // Save the selection so it can be compared to the new selection
- // when dispatching change events immediately after making the new
- // selection.
- SaveLastSelection();
-
- SetActiveSelectionEnd(end_option);
-
- is_in_non_contiguous_selection_ = is_multiple_ && is_control_key;
- bool select_new_item =
- !is_multiple_ || ToKeyboardEvent(event).shiftKey() ||
- (!IsSpatialNavigationEnabled(GetDocument().GetFrame()) &&
- !is_in_non_contiguous_selection_);
- if (select_new_item)
- active_selection_state_ = true;
- // If the anchor is uninitialized, or if we're going to deselect all
- // other options, then set the anchor index equal to the end index.
- bool deselect_others =
- !is_multiple_ ||
- (!ToKeyboardEvent(event).shiftKey() && select_new_item);
- if (!active_selection_anchor_ || deselect_others) {
- if (deselect_others)
- DeselectItemsWithoutValidation();
- SetActiveSelectionAnchor(active_selection_end_.Get());
- }
-
- ScrollToOption(end_option);
- if (select_new_item || is_in_non_contiguous_selection_) {
- if (select_new_item) {
- UpdateListBoxSelection(deselect_others);
- ListBoxOnChange();
- }
- UpdateMultiSelectListBoxFocus();
- } else {
- ScrollToSelection();
- }
-
- event.SetDefaultHandled();
- }
-
- } else if (event.type() == event_type_names::kKeypress) {
- if (!event.IsKeyboardEvent())
- return;
- int key_code = ToKeyboardEvent(event).keyCode();
-
- if (key_code == '\r') {
- if (Form())
- Form()->SubmitImplicitly(event, false);
- event.SetDefaultHandled();
- } else if (is_multiple_ && key_code == ' ' &&
- (IsSpatialNavigationEnabled(GetDocument().GetFrame()) ||
- is_in_non_contiguous_selection_)) {
- HTMLOptionElement* option = active_selection_end_;
- // If there's no active selection,
- // act as if "ArrowDown" had been pressed.
- if (!option)
- option = NextSelectableOption(LastSelectedOption());
- if (option) {
- // Use space to toggle selection change.
- ToggleSelection(*option);
- event.SetDefaultHandled();
- }
- }
- }
+LayoutBox* HTMLSelectElement::AutoscrollBox() {
+ return !UsesMenuList() ? GetLayoutBox() : nullptr;
}
-void HTMLSelectElement::ToggleSelection(HTMLOptionElement& option) {
- active_selection_state_ = !active_selection_state_;
- UpdateSelectedState(&option, true /*multi*/, false /*shift*/);
- ListBoxOnChange();
+void HTMLSelectElement::StopAutoscroll() {
+ if (!IsDisabledFormControl())
+ select_type_->HandleMouseRelease();
}
void HTMLSelectElement::DefaultEventHandler(Event& event) {
@@ -1788,19 +1130,17 @@ void HTMLSelectElement::DefaultEventHandler(Event& event) {
return;
}
- if (UsesMenuList())
- MenuListDefaultEventHandler(event);
- else
- ListBoxDefaultEventHandler(event);
- if (event.DefaultHandled())
+ if (select_type_->DefaultEventHandler(event)) {
+ event.SetDefaultHandled();
return;
+ }
- if (event.type() == event_type_names::kKeypress && event.IsKeyboardEvent()) {
- auto& keyboard_event = ToKeyboardEvent(event);
- if (!keyboard_event.ctrlKey() && !keyboard_event.altKey() &&
- !keyboard_event.metaKey() &&
- WTF::unicode::IsPrintableChar(keyboard_event.charCode())) {
- TypeAheadFind(keyboard_event);
+ auto* keyboard_event = DynamicTo<KeyboardEvent>(event);
+ if (event.type() == event_type_names::kKeypress && keyboard_event) {
+ if (!keyboard_event->ctrlKey() && !keyboard_event->altKey() &&
+ !keyboard_event->metaKey() &&
+ WTF::unicode::IsPrintableChar(keyboard_event->charCode())) {
+ TypeAheadFind(*keyboard_event);
event.SetDefaultHandled();
return;
}
@@ -1843,8 +1183,7 @@ void HTMLSelectElement::TypeAheadFind(const KeyboardEvent& event) {
SelectOption(OptionAtListIndex(index), kDeselectOtherOptionsFlag |
kMakeOptionDirtyFlag |
kDispatchInputAndChangeEventFlag);
- if (!UsesMenuList())
- ListBoxOnChange();
+ select_type_->ListBoxOnChange();
}
void HTMLSelectElement::SelectOptionByAccessKey(HTMLOptionElement* option) {
@@ -1870,7 +1209,7 @@ void HTMLSelectElement::SelectOptionByAccessKey(HTMLOptionElement* option) {
option->SetDirty(true);
if (UsesMenuList())
return;
- ListBoxOnChange();
+ select_type_->ListBoxOnChange();
ScrollToSelection();
}
@@ -1892,16 +1231,16 @@ void HTMLSelectElement::FinishParsingChildren() {
cache->ListboxActiveIndexChanged(this);
}
-bool HTMLSelectElement::AnonymousIndexedSetter(
+IndexedPropertySetterResult HTMLSelectElement::AnonymousIndexedSetter(
unsigned index,
HTMLOptionElement* value,
ExceptionState& exception_state) {
if (!value) { // undefined or null
remove(index);
- return true;
+ return IndexedPropertySetterResult::kIntercepted;
}
SetOption(index, value, exception_state);
- return true;
+ return IndexedPropertySetterResult::kIntercepted;
}
bool HTMLSelectElement::IsInteractiveContent() const {
@@ -1915,14 +1254,47 @@ void HTMLSelectElement::Trace(Visitor* visitor) {
visitor->Trace(active_selection_end_);
visitor->Trace(option_to_scroll_to_);
visitor->Trace(suggested_option_);
- visitor->Trace(popup_);
- visitor->Trace(popup_updater_);
+ visitor->Trace(select_type_);
HTMLFormControlElementWithState::Trace(visitor);
}
void HTMLSelectElement::DidAddUserAgentShadowRoot(ShadowRoot& root) {
+ // Even if UsesMenuList(), the <slot> is necessary to have ComputedStyles
+ // for <option>s. LayoutFlexibleBox::IsChildAllowed() rejects all of
+ // LayoutObject children except for MenuListInnerElement's.
root.AppendChild(
HTMLSlotElement::CreateUserAgentCustomAssignSlot(GetDocument()));
+ UpdateUserAgentShadowTree(root);
+ select_type_->UpdateTextStyleAndContent();
+}
+
+void HTMLSelectElement::UpdateUserAgentShadowTree(ShadowRoot& root) {
+ // Remove all children of the ShadowRoot except for <slot>.
+ Node* node = root.firstChild();
+ while (node) {
+ if (IsA<HTMLSlotElement>(node)) {
+ node = node->nextSibling();
+ } else {
+ auto* will_be_removed = node;
+ node = node->nextSibling();
+ 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());
+ }
+}
+
+Element& HTMLSelectElement::InnerElement() const {
+ DCHECK(UsesMenuList());
+ auto* inner_element = DynamicTo<Element>(UserAgentShadowRoot()->firstChild());
+ DCHECK(inner_element);
+ return *inner_element;
}
HTMLOptionElement* HTMLSelectElement::SpatialNavigationFocusedOption() {
@@ -1930,7 +1302,7 @@ HTMLOptionElement* HTMLSelectElement::SpatialNavigationFocusedOption() {
return nullptr;
HTMLOptionElement* focused_option = ActiveSelectionEnd();
if (!focused_option)
- focused_option = FirstSelectableOption();
+ focused_option = select_type_->FirstSelectableOption();
return focused_option;
}
@@ -1960,42 +1332,44 @@ const ComputedStyle* HTMLSelectElement::ItemComputedStyle(
}
LayoutUnit HTMLSelectElement::ClientPaddingLeft() const {
- if (GetLayoutObject() && GetLayoutObject()->IsMenuList())
- return ToLayoutMenuList(GetLayoutObject())->ClientPaddingLeft();
- return LayoutUnit();
+ DCHECK(UsesMenuList());
+ auto* this_box = GetLayoutBox();
+ if (!this_box || !InnerElement().GetLayoutBox())
+ return LayoutUnit();
+ LayoutTheme& theme = LayoutTheme::GetTheme();
+ const ComputedStyle& style = this_box->StyleRef();
+ int inner_padding =
+ style.IsLeftToRightDirection()
+ ? theme.PopupInternalPaddingStart(style)
+ : theme.PopupInternalPaddingEnd(GetDocument().GetFrame(), style);
+ return this_box->PaddingLeft() + inner_padding;
}
LayoutUnit HTMLSelectElement::ClientPaddingRight() const {
- if (GetLayoutObject() && GetLayoutObject()->IsMenuList())
- return ToLayoutMenuList(GetLayoutObject())->ClientPaddingRight();
- return LayoutUnit();
+ DCHECK(UsesMenuList());
+ auto* this_box = GetLayoutBox();
+ if (!this_box || !InnerElement().GetLayoutBox())
+ return LayoutUnit();
+ LayoutTheme& theme = LayoutTheme::GetTheme();
+ const ComputedStyle& style = this_box->StyleRef();
+ int inner_padding =
+ style.IsLeftToRightDirection()
+ ? theme.PopupInternalPaddingEnd(GetDocument().GetFrame(), style)
+ : theme.PopupInternalPaddingStart(style);
+ return this_box->PaddingRight() + inner_padding;
}
void HTMLSelectElement::PopupDidHide() {
- popup_is_visible_ = false;
- UnobserveTreeMutation();
- if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache()) {
- if (GetLayoutObject() && GetLayoutObject()->IsMenuList())
- cache->DidHideMenuListPopup(ToLayoutMenuList(GetLayoutObject()));
- }
+ select_type_->PopupDidHide();
}
void HTMLSelectElement::SetIndexToSelectOnCancel(int list_index) {
index_to_select_on_cancel_ = list_index;
- if (GetLayoutObject())
- GetLayoutObject()->UpdateFromElement();
+ select_type_->UpdateTextStyleAndContent();
}
-HTMLOptionElement* HTMLSelectElement::OptionToBeShown() const {
- if (HTMLOptionElement* option = OptionAtListIndex(index_to_select_on_cancel_))
- return option;
- if (suggested_option_)
- return suggested_option_;
- // TODO(tkent): We should not call optionToBeShown() in isMultiple() case.
- if (IsMultiple())
- return SelectedOption();
- DCHECK_EQ(SelectedOption(), last_on_change_option_);
- return last_on_change_option_;
+HTMLOptionElement* HTMLSelectElement::OptionToBeShownForTesting() const {
+ return select_type_->OptionToBeShown();
}
void HTMLSelectElement::SelectOptionByPopup(int list_index) {
@@ -2031,44 +1405,28 @@ void HTMLSelectElement::ProvisionalSelectionChanged(unsigned list_index) {
}
void HTMLSelectElement::ShowPopup() {
- if (PopupIsVisible())
- return;
- if (GetDocument().GetPage()->GetChromeClient().HasOpenedPopup())
- return;
- if (!GetLayoutObject() || !GetLayoutObject()->IsMenuList())
- return;
- if (VisibleBoundsInVisualViewport().IsEmpty())
- return;
-
- if (!popup_) {
- popup_ = GetDocument().GetPage()->GetChromeClient().OpenPopupMenu(
- *GetDocument().GetFrame(), *this);
- }
- if (!popup_)
- return;
-
- popup_is_visible_ = true;
- ObserveTreeMutation();
-
- LayoutMenuList* menu_list = ToLayoutMenuList(GetLayoutObject());
- popup_->Show();
- if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache())
- cache->DidShowMenuListPopup(menu_list);
+ select_type_->ShowPopup();
}
void HTMLSelectElement::HidePopup() {
- if (popup_)
- popup_->Hide();
+ select_type_->HidePopup();
+}
+
+PopupMenu* HTMLSelectElement::PopupForTesting() const {
+ return select_type_->PopupForTesting();
}
void HTMLSelectElement::DidRecalcStyle(const StyleRecalcChange change) {
HTMLFormControlElementWithState::DidRecalcStyle(change);
- if (!change.ReattachLayoutTree() && PopupIsVisible())
- popup_->UpdateFromElement(PopupMenu::kByStyleChange);
+ select_type_->DidRecalcStyle(change);
}
void HTMLSelectElement::AttachLayoutTree(AttachContext& context) {
HTMLFormControlElementWithState::AttachLayoutTree(context);
+ // The call to UpdateTextStyle() needs to go after the call through
+ // to the base class's AttachLayoutTree() because that can sometimes do a
+ // close on the LayoutObject.
+ select_type_->UpdateTextStyle();
if (const ComputedStyle* style = GetComputedStyle()) {
if (style->Visibility() != EVisibility::kHidden) {
@@ -2082,90 +1440,13 @@ void HTMLSelectElement::AttachLayoutTree(AttachContext& context) {
void HTMLSelectElement::DetachLayoutTree(bool performing_reattach) {
HTMLFormControlElementWithState::DetachLayoutTree(performing_reattach);
- if (popup_)
- popup_->DisconnectClient();
- popup_is_visible_ = false;
- popup_ = nullptr;
- UnobserveTreeMutation();
+ select_type_->DidDetachLayoutTree();
}
void HTMLSelectElement::ResetTypeAheadSessionForTesting() {
type_ahead_.ResetSession();
}
-// PopupUpdater notifies updates of the specified SELECT element subtree to
-// a PopupMenu object.
-class HTMLSelectElement::PopupUpdater : public MutationObserver::Delegate {
- public:
- explicit PopupUpdater(HTMLSelectElement& select)
- : select_(select), observer_(MutationObserver::Create(this)) {
- MutationObserverInit* init = MutationObserverInit::Create();
- init->setAttributeOldValue(true);
- init->setAttributes(true);
- // Observe only attributes which affect popup content.
- init->setAttributeFilter({"disabled", "label", "selected", "value"});
- init->setCharacterData(true);
- init->setCharacterDataOldValue(true);
- init->setChildList(true);
- init->setSubtree(true);
- observer_->observe(select_, init, ASSERT_NO_EXCEPTION);
- }
-
- ExecutionContext* GetExecutionContext() const override {
- return &select_->GetDocument();
- }
-
- void Deliver(const MutationRecordVector& records,
- MutationObserver&) override {
- // We disconnect the MutationObserver when a popup is closed. However
- // MutationObserver can call back after disconnection.
- if (!select_->PopupIsVisible())
- return;
- for (const auto& record : records) {
- if (record->type() == "attributes") {
- const auto& element = *To<Element>(record->target());
- if (record->oldValue() == element.getAttribute(record->attributeName()))
- continue;
- } else if (record->type() == "characterData") {
- if (record->oldValue() == record->target()->nodeValue())
- continue;
- }
- select_->DidMutateSubtree();
- return;
- }
- }
-
- void Dispose() { observer_->disconnect(); }
-
- void Trace(Visitor* visitor) override {
- visitor->Trace(select_);
- visitor->Trace(observer_);
- MutationObserver::Delegate::Trace(visitor);
- }
-
- private:
- Member<HTMLSelectElement> select_;
- Member<MutationObserver> observer_;
-};
-
-void HTMLSelectElement::ObserveTreeMutation() {
- DCHECK(!popup_updater_);
- popup_updater_ = MakeGarbageCollected<PopupUpdater>(*this);
-}
-
-void HTMLSelectElement::UnobserveTreeMutation() {
- if (!popup_updater_)
- return;
- popup_updater_->Dispose();
- popup_updater_ = nullptr;
-}
-
-void HTMLSelectElement::DidMutateSubtree() {
- DCHECK(PopupIsVisible());
- DCHECK(popup_);
- popup_->UpdateFromElement(PopupMenu::kByDOMChange);
-}
-
void HTMLSelectElement::CloneNonAttributePropertiesFrom(
const Element& source,
CloneChildrenFlag flag) {
@@ -2175,6 +1456,10 @@ void HTMLSelectElement::CloneNonAttributePropertiesFrom(
}
void HTMLSelectElement::ChangeRendering() {
+ select_type_->DidDetachLayoutTree();
+ UpdateUsesMenuList();
+ select_type_->WillBeDestroyed();
+ select_type_ = SelectType::Create(*this);
if (!InActiveDocument())
return;
// TODO(futhark): SetForceReattachLayoutTree() should be the correct way to
@@ -2185,4 +1470,8 @@ void HTMLSelectElement::ChangeRendering() {
style_change_reason::kControl));
}
+const ComputedStyle* HTMLSelectElement::OptionStyle() const {
+ return select_type_->OptionStyle();
+}
+
} // namespace blink
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 5bfbc9ccde4..314840a3f45 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
@@ -28,6 +28,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_HTML_SELECT_ELEMENT_H_
#include "base/gtest_prod_util.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/html/forms/html_form_control_element_with_state.h"
#include "third_party/blink/renderer/core/html/forms/html_options_collection.h"
@@ -46,6 +47,7 @@ class HTMLOptionElementOrHTMLOptGroupElement;
class HTMLElementOrLong;
class LayoutUnit;
class PopupMenu;
+class SelectType;
class CORE_EXPORT HTMLSelectElement final
: public HTMLFormControlElementWithState,
@@ -74,9 +76,12 @@ class CORE_EXPORT HTMLSelectElement final
// TODO(tkent): Rename |size| to |Size|. This is not an implementation of
// |size| IDL attribute.
unsigned size() const { return size_; }
+ // The number of items to be shown in the LisBox mode.
+ // Do not call this in the MenuList mode.
+ unsigned ListBoxSize() const;
bool IsMultiple() const { return is_multiple_; }
- bool UsesMenuList() const;
+ bool UsesMenuList() const { return uses_menu_list_; }
void add(const HTMLOptionElementOrHTMLOptGroupElement&,
const HTMLElementOrLong&,
@@ -122,7 +127,6 @@ class CORE_EXPORT HTMLSelectElement final
bool CanSelectAll() const;
void SelectAll();
- void ListBoxOnChange();
int ActiveSelectionEndListIndex() const;
HTMLOptionElement* ActiveSelectionEnd() const;
void SetActiveSelectionAnchor(HTMLOptionElement*);
@@ -132,13 +136,14 @@ class CORE_EXPORT HTMLSelectElement final
void OptionSelectionStateChanged(HTMLOptionElement*, bool option_is_selected);
void OptionInserted(HTMLOptionElement&, bool option_is_selected);
void OptionRemoved(HTMLOptionElement&);
- bool AnonymousIndexedSetter(unsigned, HTMLOptionElement*, ExceptionState&);
+ IndexedPropertySetterResult AnonymousIndexedSetter(unsigned,
+ HTMLOptionElement*,
+ ExceptionState&);
void OptGroupInsertedOrRemoved(HTMLOptGroupElement&);
void HrInsertedOrRemoved(HTMLHRElement&);
HTMLOptionElement* SpatialNavigationFocusedOption();
- void HandleMouseRelease();
int ListIndexForOption(const HTMLOptionElement&);
@@ -159,12 +164,14 @@ class CORE_EXPORT HTMLSelectElement final
// Provisional selection is a selection made using arrow keys or type ahead.
void ProvisionalSelectionChanged(unsigned);
void PopupDidHide();
- bool PopupIsVisible() const { return popup_is_visible_; }
- HTMLOptionElement* OptionToBeShown() const;
+ bool PopupIsVisible() const;
+ HTMLOptionElement* OptionToBeShownForTesting() const;
+ // Style of the selected OPTION. This is nullable, and only for
+ // the menulist mode.
+ const ComputedStyle* OptionStyle() const;
void ShowPopup();
void HidePopup();
- PopupMenu* Popup() const { return popup_.Get(); }
- void DidMutateSubtree();
+ PopupMenu* PopupForTesting() const;
void ResetTypeAheadSessionForTesting();
@@ -177,17 +184,22 @@ class CORE_EXPORT HTMLSelectElement final
void CloneNonAttributePropertiesFrom(const Element&,
CloneChildrenFlag) override;
+ // This should be called only if UsesMenuList().
+ Element& InnerElement() const;
+
private:
const AtomicString& FormControlType() const override;
bool MayTriggerVirtualKeyboard() const override;
+ bool ShouldHaveFocusAppearance() const final;
+
void DispatchFocusEvent(
Element* old_focused_element,
- WebFocusType,
+ mojom::blink::FocusType,
InputDeviceCapabilities* source_capabilities) override;
void DispatchBlurEvent(Element* new_focused_element,
- WebFocusType,
+ mojom::blink::FocusType,
InputDeviceCapabilities* source_capabilities) override;
bool CanStartSelection() const override { return false; }
@@ -199,9 +211,12 @@ class CORE_EXPORT HTMLSelectElement final
FormControlState SaveFormControlState() const override;
void RestoreFormControlState(const FormControlState&) override;
+ void ChildrenChanged(const ChildrenChange& change) override;
+ bool ChildrenChangedAllChildrenRemovedNeedsList() const override;
void ParseAttribute(const AttributeModificationParams&) override;
bool IsPresentationAttribute(const QualifiedName&) const override;
+ bool TypeShouldForceLegacyLayout() const override;
LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override;
void DidRecalcStyle(const StyleRecalcChange) override;
void AttachLayoutTree(AttachContext&) override;
@@ -211,15 +226,11 @@ class CORE_EXPORT HTMLSelectElement final
void DefaultEventHandler(Event&) override;
- void DispatchInputAndChangeEventForMenuList();
-
void SetRecalcListItems();
void RecalcListItems() const;
enum ResetReason { kResetReasonSelectedOptionRemoved, kResetReasonOthers };
void ResetToDefaultSelection(ResetReason = kResetReasonOthers);
void TypeAheadFind(const KeyboardEvent&);
- void SaveLastSelection();
- void SaveListboxActiveSelection();
// Returns the first selected OPTION, or nullptr.
HTMLOptionElement* SelectedOption() const;
@@ -241,37 +252,19 @@ class CORE_EXPORT HTMLSelectElement final
HTMLOptionElement* element_to_exclude = nullptr);
void ParseMultipleAttribute(const AtomicString&);
HTMLOptionElement* LastSelectedOption() const;
- void UpdateSelectedState(HTMLOptionElement*, bool multi, bool shift);
- void MenuListDefaultEventHandler(Event&);
- void HandlePopupOpenKeyboardEvent(Event&);
- bool ShouldOpenPopupForKeyDownEvent(const KeyboardEvent&);
- bool ShouldOpenPopupForKeyPressEvent(const KeyboardEvent&);
- void ListBoxDefaultEventHandler(Event&);
- void SetOptionsChangedOnLayoutObject();
wtf_size_t SearchOptionsForValue(const String&,
wtf_size_t list_index_start,
wtf_size_t list_index_end) const;
- void UpdateListBoxSelection(bool deselect_other_options, bool scroll = true);
- void UpdateMultiSelectListBoxFocus();
void SetIndexToSelectOnCancel(int list_index);
void SetSuggestedOption(HTMLOptionElement*);
- void ToggleSelection(HTMLOptionElement&);
// Returns nullptr if listIndex is out of bounds, or it doesn't point an
// HTMLOptionElement.
HTMLOptionElement* OptionAtListIndex(int list_index) const;
- enum SkipDirection { kSkipBackwards = -1, kSkipForwards = 1 };
- HTMLOptionElement* NextValidOption(int list_index,
- SkipDirection,
- int skip) const;
- HTMLOptionElement* NextSelectableOption(HTMLOptionElement*) const;
- HTMLOptionElement* PreviousSelectableOption(HTMLOptionElement*) const;
- HTMLOptionElement* FirstSelectableOption() const;
- HTMLOptionElement* LastSelectableOption() const;
- HTMLOptionElement* NextSelectableOptionPageAway(HTMLOptionElement*,
- SkipDirection) const;
- HTMLOptionElement* EventTargetOption(const Event&);
+
AutoscrollController* GetAutoscrollController() const;
+ LayoutBox* AutoscrollBox() override;
+ void StopAutoscroll() override;
void ScrollToOptionTask();
bool AreAuthorShadowsAllowed() const override { return false; }
@@ -282,18 +275,15 @@ class CORE_EXPORT HTMLSelectElement final
int OptionCount() const override;
String OptionAtIndex(int index) const override;
- void ObserveTreeMutation();
- void UnobserveTreeMutation();
-
+ void UpdateUsesMenuList();
// Apply changes to rendering as a result of attribute changes (multiple,
// size).
void ChangeRendering();
+ void UpdateUserAgentShadowTree(ShadowRoot& root);
// list_items_ contains HTMLOptionElement, HTMLOptGroupElement, and
// HTMLHRElement objects.
mutable ListItems list_items_;
- Vector<bool> last_on_change_selection_;
- Vector<bool> cached_state_for_active_selection_;
TypeAhead type_ahead_;
unsigned size_;
Member<HTMLOptionElement> last_on_change_option_;
@@ -301,22 +291,18 @@ class CORE_EXPORT HTMLSelectElement final
Member<HTMLOptionElement> active_selection_end_;
Member<HTMLOptionElement> option_to_scroll_to_;
Member<HTMLOptionElement> suggested_option_;
+ bool uses_menu_list_ = true;
bool is_multiple_;
- bool is_in_non_contiguous_selection_;
- bool active_selection_state_;
mutable bool should_recalc_list_items_;
bool is_autofilled_by_preview_;
- class PopupUpdater;
- Member<PopupUpdater> popup_updater_;
- Member<PopupMenu> popup_;
+ Member<SelectType> select_type_;
int index_to_select_on_cancel_;
- bool popup_is_visible_;
- FRIEND_TEST_ALL_PREFIXES(HTMLSelectElementTest, FirstSelectableOption);
- FRIEND_TEST_ALL_PREFIXES(HTMLSelectElementTest, LastSelectableOption);
- FRIEND_TEST_ALL_PREFIXES(HTMLSelectElementTest, NextSelectableOption);
- FRIEND_TEST_ALL_PREFIXES(HTMLSelectElementTest, PreviousSelectableOption);
+ friend class ListBoxSelectType;
+ friend class MenuListSelectType;
+ friend class SelectType;
+ friend class HTMLSelectElementTest;
};
} // namespace blink
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 8da70996dff..f92a9abb963 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
@@ -9,8 +9,11 @@
#include "testing/gtest/include/gtest/gtest.h"
#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/frame/settings.h"
#include "third_party/blink/renderer/core/html/forms/form_controller.h"
#include "third_party/blink/renderer/core/html/forms/html_form_element.h"
+#include "third_party/blink/renderer/core/html/forms/select_type.h"
+#include "third_party/blink/renderer/core/layout/layout_theme.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
@@ -19,11 +22,49 @@ namespace blink {
class HTMLSelectElementTest : public PageTestBase {
protected:
void SetUp() override;
+ void TearDown() override;
+
+ SelectType& GetSelectType(const HTMLSelectElement& select) {
+ return *select.select_type_;
+ }
+
+ HTMLOptionElement* FirstSelectableOption(const HTMLSelectElement& select) {
+ return GetSelectType(select).FirstSelectableOption();
+ }
+ HTMLOptionElement* LastSelectableOption(const HTMLSelectElement& select) {
+ return GetSelectType(select).LastSelectableOption();
+ }
+ HTMLOptionElement* NextSelectableOption(const HTMLSelectElement& select,
+ HTMLOptionElement* option) {
+ return GetSelectType(select).NextSelectableOption(option);
+ }
+ HTMLOptionElement* PreviousSelectableOption(const HTMLSelectElement& select,
+ HTMLOptionElement* option) {
+ return GetSelectType(select).PreviousSelectableOption(option);
+ }
+
+ bool FirstSelectIsConnectedAfterSelectMultiple(const Vector<int>& indices) {
+ auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
+ select->focus();
+ select->SelectMultipleOptionsByPopup(indices);
+ return select->isConnected();
+ }
+
+ private:
+ bool original_delegates_flag_;
};
void HTMLSelectElementTest::SetUp() {
PageTestBase::SetUp();
GetDocument().SetMimeType("text/html");
+ original_delegates_flag_ =
+ LayoutTheme::GetTheme().DelegatesMenuListRendering();
+}
+
+void HTMLSelectElementTest::TearDown() {
+ LayoutTheme::GetTheme().SetDelegatesMenuListRenderingForTesting(
+ original_delegates_flag_);
+ PageTestBase::TearDown();
}
TEST_F(HTMLSelectElementTest, SaveRestoreSelectSingleFormControlState) {
@@ -55,6 +96,8 @@ TEST_F(HTMLSelectElementTest, SaveRestoreSelectSingleFormControlState) {
EXPECT_EQ(2, To<HTMLSelectElement>(element)->selectedIndex());
EXPECT_FALSE(opt0->Selected());
EXPECT_TRUE(opt2->Selected());
+ EXPECT_EQ("!666",
+ To<HTMLSelectElement>(element)->InnerElement().textContent());
}
TEST_F(HTMLSelectElementTest, SaveRestoreSelectMultipleFormControlState) {
@@ -121,7 +164,8 @@ TEST_F(HTMLSelectElementTest, RestoreUnmatchedFormControlState) {
// Restore
select->RestoreFormControlState(select_state);
EXPECT_EQ(-1, To<HTMLSelectElement>(element)->selectedIndex());
- EXPECT_EQ(nullptr, To<HTMLSelectElement>(element)->OptionToBeShown());
+ EXPECT_EQ(nullptr,
+ To<HTMLSelectElement>(element)->OptionToBeShownForTesting());
}
TEST_F(HTMLSelectElementTest, VisibleBoundsInVisualViewport) {
@@ -149,13 +193,13 @@ TEST_F(HTMLSelectElementTest, FirstSelectableOption) {
{
SetHtmlInnerHTML("<select></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
- EXPECT_EQ(nullptr, select->FirstSelectableOption());
+ EXPECT_EQ(nullptr, FirstSelectableOption(*select));
}
{
SetHtmlInnerHTML(
"<select><option id=o1></option><option id=o2></option></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
- EXPECT_EQ("o1", select->FirstSelectableOption()->FastGetAttribute(
+ EXPECT_EQ("o1", FirstSelectableOption(*select)->FastGetAttribute(
html_names::kIdAttr));
}
{
@@ -163,7 +207,7 @@ TEST_F(HTMLSelectElementTest, FirstSelectableOption) {
"<select><option id=o1 disabled></option><option "
"id=o2></option></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
- EXPECT_EQ("o2", select->FirstSelectableOption()->FastGetAttribute(
+ EXPECT_EQ("o2", FirstSelectableOption(*select)->FastGetAttribute(
html_names::kIdAttr));
}
{
@@ -171,7 +215,7 @@ TEST_F(HTMLSelectElementTest, FirstSelectableOption) {
"<select><option id=o1 style='display:none'></option><option "
"id=o2></option></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
- EXPECT_EQ("o2", select->FirstSelectableOption()->FastGetAttribute(
+ EXPECT_EQ("o2", FirstSelectableOption(*select)->FastGetAttribute(
html_names::kIdAttr));
}
{
@@ -179,7 +223,7 @@ TEST_F(HTMLSelectElementTest, FirstSelectableOption) {
"<select><optgroup><option id=o1></option><option "
"id=o2></option></optgroup></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
- EXPECT_EQ("o1", select->FirstSelectableOption()->FastGetAttribute(
+ EXPECT_EQ("o1", FirstSelectableOption(*select)->FastGetAttribute(
html_names::kIdAttr));
}
}
@@ -188,13 +232,13 @@ TEST_F(HTMLSelectElementTest, LastSelectableOption) {
{
SetHtmlInnerHTML("<select></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
- EXPECT_EQ(nullptr, select->LastSelectableOption());
+ EXPECT_EQ(nullptr, LastSelectableOption(*select));
}
{
SetHtmlInnerHTML(
"<select><option id=o1></option><option id=o2></option></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
- EXPECT_EQ("o2", select->LastSelectableOption()->FastGetAttribute(
+ EXPECT_EQ("o2", LastSelectableOption(*select)->FastGetAttribute(
html_names::kIdAttr));
}
{
@@ -202,7 +246,7 @@ TEST_F(HTMLSelectElementTest, LastSelectableOption) {
"<select><option id=o1></option><option id=o2 "
"disabled></option></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
- EXPECT_EQ("o1", select->LastSelectableOption()->FastGetAttribute(
+ EXPECT_EQ("o1", LastSelectableOption(*select)->FastGetAttribute(
html_names::kIdAttr));
}
{
@@ -210,7 +254,7 @@ TEST_F(HTMLSelectElementTest, LastSelectableOption) {
"<select><option id=o1></option><option id=o2 "
"style='display:none'></option></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
- EXPECT_EQ("o1", select->LastSelectableOption()->FastGetAttribute(
+ EXPECT_EQ("o1", LastSelectableOption(*select)->FastGetAttribute(
html_names::kIdAttr));
}
{
@@ -218,7 +262,7 @@ TEST_F(HTMLSelectElementTest, LastSelectableOption) {
"<select><optgroup><option id=o1></option><option "
"id=o2></option></optgroup></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
- EXPECT_EQ("o2", select->LastSelectableOption()->FastGetAttribute(
+ EXPECT_EQ("o2", LastSelectableOption(*select)->FastGetAttribute(
html_names::kIdAttr));
}
}
@@ -227,49 +271,50 @@ TEST_F(HTMLSelectElementTest, NextSelectableOption) {
{
SetHtmlInnerHTML("<select></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
- EXPECT_EQ(nullptr, select->NextSelectableOption(nullptr));
+ EXPECT_EQ(nullptr, NextSelectableOption(*select, nullptr));
}
{
SetHtmlInnerHTML(
"<select><option id=o1></option><option id=o2></option></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
- EXPECT_EQ("o1", select->NextSelectableOption(nullptr)->FastGetAttribute(
- html_names::kIdAttr));
+ EXPECT_EQ("o1", NextSelectableOption(*select, nullptr)
+ ->FastGetAttribute(html_names::kIdAttr));
}
{
SetHtmlInnerHTML(
"<select><option id=o1 disabled></option><option "
"id=o2></option></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
- EXPECT_EQ("o2", select->NextSelectableOption(nullptr)->FastGetAttribute(
- html_names::kIdAttr));
+ EXPECT_EQ("o2", NextSelectableOption(*select, nullptr)
+ ->FastGetAttribute(html_names::kIdAttr));
}
{
SetHtmlInnerHTML(
"<select><option id=o1 style='display:none'></option><option "
"id=o2></option></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
- EXPECT_EQ("o2", select->NextSelectableOption(nullptr)->FastGetAttribute(
- html_names::kIdAttr));
+ EXPECT_EQ("o2", NextSelectableOption(*select, nullptr)
+ ->FastGetAttribute(html_names::kIdAttr));
}
{
SetHtmlInnerHTML(
"<select><optgroup><option id=o1></option><option "
"id=o2></option></optgroup></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
- EXPECT_EQ("o1", select->NextSelectableOption(nullptr)->FastGetAttribute(
- html_names::kIdAttr));
+ EXPECT_EQ("o1", NextSelectableOption(*select, nullptr)
+ ->FastGetAttribute(html_names::kIdAttr));
}
{
SetHtmlInnerHTML(
"<select><option id=o1></option><option id=o2></option></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
auto* option = To<HTMLOptionElement>(GetElementById("o1"));
- EXPECT_EQ("o2", select->NextSelectableOption(option)->FastGetAttribute(
- html_names::kIdAttr));
+ EXPECT_EQ("o2", NextSelectableOption(*select, option)
+ ->FastGetAttribute(html_names::kIdAttr));
- EXPECT_EQ(nullptr, select->NextSelectableOption(
- To<HTMLOptionElement>(GetElementById("o2"))));
+ EXPECT_EQ(nullptr,
+ NextSelectableOption(
+ *select, To<HTMLOptionElement>(GetElementById("o2"))));
}
{
SetHtmlInnerHTML(
@@ -277,8 +322,8 @@ TEST_F(HTMLSelectElementTest, NextSelectableOption) {
"id=o2></option></optgroup></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
auto* option = To<HTMLOptionElement>(GetElementById("o1"));
- EXPECT_EQ("o2", select->NextSelectableOption(option)->FastGetAttribute(
- html_names::kIdAttr));
+ EXPECT_EQ("o2", NextSelectableOption(*select, option)
+ ->FastGetAttribute(html_names::kIdAttr));
}
}
@@ -286,49 +331,50 @@ TEST_F(HTMLSelectElementTest, PreviousSelectableOption) {
{
SetHtmlInnerHTML("<select></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
- EXPECT_EQ(nullptr, select->PreviousSelectableOption(nullptr));
+ EXPECT_EQ(nullptr, PreviousSelectableOption(*select, nullptr));
}
{
SetHtmlInnerHTML(
"<select><option id=o1></option><option id=o2></option></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
- EXPECT_EQ("o2", select->PreviousSelectableOption(nullptr)->FastGetAttribute(
- html_names::kIdAttr));
+ EXPECT_EQ("o2", PreviousSelectableOption(*select, nullptr)
+ ->FastGetAttribute(html_names::kIdAttr));
}
{
SetHtmlInnerHTML(
"<select><option id=o1></option><option id=o2 "
"disabled></option></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
- EXPECT_EQ("o1", select->PreviousSelectableOption(nullptr)->FastGetAttribute(
- html_names::kIdAttr));
+ EXPECT_EQ("o1", PreviousSelectableOption(*select, nullptr)
+ ->FastGetAttribute(html_names::kIdAttr));
}
{
SetHtmlInnerHTML(
"<select><option id=o1></option><option id=o2 "
"style='display:none'></option></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
- EXPECT_EQ("o1", select->PreviousSelectableOption(nullptr)->FastGetAttribute(
- html_names::kIdAttr));
+ EXPECT_EQ("o1", PreviousSelectableOption(*select, nullptr)
+ ->FastGetAttribute(html_names::kIdAttr));
}
{
SetHtmlInnerHTML(
"<select><optgroup><option id=o1></option><option "
"id=o2></option></optgroup></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
- EXPECT_EQ("o2", select->PreviousSelectableOption(nullptr)->FastGetAttribute(
- html_names::kIdAttr));
+ EXPECT_EQ("o2", PreviousSelectableOption(*select, nullptr)
+ ->FastGetAttribute(html_names::kIdAttr));
}
{
SetHtmlInnerHTML(
"<select><option id=o1></option><option id=o2></option></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
auto* option = To<HTMLOptionElement>(GetElementById("o2"));
- EXPECT_EQ("o1", select->PreviousSelectableOption(option)->FastGetAttribute(
- html_names::kIdAttr));
+ EXPECT_EQ("o1", PreviousSelectableOption(*select, option)
+ ->FastGetAttribute(html_names::kIdAttr));
- EXPECT_EQ(nullptr, select->PreviousSelectableOption(
- To<HTMLOptionElement>(GetElementById("o1"))));
+ EXPECT_EQ(nullptr,
+ PreviousSelectableOption(
+ *select, To<HTMLOptionElement>(GetElementById("o1"))));
}
{
SetHtmlInnerHTML(
@@ -336,8 +382,8 @@ TEST_F(HTMLSelectElementTest, PreviousSelectableOption) {
"id=o2></option></optgroup></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
auto* option = To<HTMLOptionElement>(GetElementById("o2"));
- EXPECT_EQ("o1", select->PreviousSelectableOption(option)->FastGetAttribute(
- html_names::kIdAttr));
+ EXPECT_EQ("o1", PreviousSelectableOption(*select, option)
+ ->FastGetAttribute(html_names::kIdAttr));
}
}
@@ -401,7 +447,7 @@ TEST_F(HTMLSelectElementTest, SetRecalcListItemsByOptgroupRemoval) {
"<select><optgroup><option>sub1</option><option>sub2</option></"
"optgroup></select>");
auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
- select->SetInnerHTMLFromString("");
+ select->setInnerHTML("");
// PASS if setInnerHTML didn't have a check failure.
}
@@ -415,4 +461,109 @@ TEST_F(HTMLSelectElementTest, ScrollToOptionAfterLayoutCrash) {
)HTML");
}
+TEST_F(HTMLSelectElementTest, CrashOnAttachingMenuList) {
+ // crbug.com/1044834
+ // This test passes if no crash.
+ SetHtmlInnerHTML("<select><option selected style='direction:rtl'>o1");
+ GetDocument().UpdateStyleAndLayoutTree();
+ auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
+ ASSERT_TRUE(select->GetLayoutObject());
+
+ // Detach LayoutMenuList.
+ select->setAttribute("style", "display:none;");
+ GetDocument().UpdateStyleAndLayoutTree();
+ ASSERT_FALSE(select->GetLayoutObject());
+
+ // Attach LayoutMenuList again. It triggered null-dereference in
+ // LayoutMenuList::AdjustInnerStyle().
+ select->removeAttribute("style");
+ GetDocument().UpdateStyleAndLayoutTree();
+ ASSERT_TRUE(select->GetLayoutObject());
+}
+
+TEST_F(HTMLSelectElementTest, CrashOnAttachingMenuList2) {
+ // crbug.com/1065125
+ // This test passes if no crash.
+ SetHtmlInnerHTML("<select><optgroup><option>o1</select>");
+ auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild());
+ select->setTextContent("foo");
+
+ // Detach LayoutObject.
+ select->setAttribute("style", "display:none;");
+ GetDocument().UpdateStyleAndLayoutTree();
+
+ // Attach LayoutObject. It triggered a DCHECK failure in
+ // MenuListSelectType::OptionToBeShown()
+ select->removeAttribute("style");
+ GetDocument().UpdateStyleAndLayoutTree();
+}
+
+TEST_F(HTMLSelectElementTest, SlotAssignmentRecalcDuringOptionRemoval) {
+ // crbug.com/1056094
+ // This test passes if no CHECK failure about IsSlotAssignmentRecalcForbidden.
+ SetHtmlInnerHTML("<div dir=auto><select><option>option0");
+ auto* select = GetDocument().body()->firstChild()->firstChild();
+ auto* option = select->firstChild();
+ select->appendChild(option);
+ option->remove();
+}
+
+// crbug.com/1060039
+TEST_F(HTMLSelectElementTest, SelectMultipleOptionsByPopup) {
+ GetDocument().GetSettings()->SetScriptEnabled(true);
+ LayoutTheme::GetTheme().SetDelegatesMenuListRenderingForTesting(true);
+
+ // Select the same set of options.
+ {
+ SetHtmlInnerHTML(
+ "<select multiple onchange='this.remove();'>"
+ "<option>o0</option><option>o1</option></select>");
+ EXPECT_TRUE(FirstSelectIsConnectedAfterSelectMultiple(Vector<int>{}))
+ << "Onchange handler should not be executed.";
+ }
+ {
+ SetHtmlInnerHTML(
+ "<select multiple onchange='this.remove();'>"
+ "<option>o0</option><option selected>o1</option></select>");
+ EXPECT_TRUE(FirstSelectIsConnectedAfterSelectMultiple(Vector<int>{1}))
+ << "Onchange handler should not be executed.";
+ }
+
+ // 0 old selected options -> 1+ selected options
+ {
+ SetHtmlInnerHTML(
+ "<select multiple onchange='this.remove();'>"
+ "<option>o0</option><option>o1</option></select>");
+ EXPECT_FALSE(FirstSelectIsConnectedAfterSelectMultiple(Vector<int>{0}))
+ << "Onchange handler should be executed.";
+ }
+
+ // 1+ old selected options -> more selected options
+ {
+ SetHtmlInnerHTML(
+ "<select multiple onchange='this.remove();'>"
+ "<option>o0</option><option selected>o1</option></select>");
+ EXPECT_FALSE(FirstSelectIsConnectedAfterSelectMultiple(Vector<int>{0, 1}))
+ << "Onchange handler should be executed.";
+ }
+
+ // 1+ old selected options -> 0 selected options
+ {
+ SetHtmlInnerHTML(
+ "<select multiple onchange='this.remove();'>"
+ "<option>o0</option><option selected>o1</option></select>");
+ EXPECT_FALSE(FirstSelectIsConnectedAfterSelectMultiple(Vector<int>{}))
+ << "Onchange handler should be executed.";
+ }
+
+ // Multiple old selected options -> less selected options
+ {
+ SetHtmlInnerHTML(
+ "<select multiple onchange='this.remove();'>"
+ "<option selected>o0</option><option selected>o1</option></select>");
+ EXPECT_FALSE(FirstSelectIsConnectedAfterSelectMultiple(Vector<int>{1}))
+ << "Onchange handler should be executed.";
+ }
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_text_area_element.cc b/chromium/third_party/blink/renderer/core/html/forms/html_text_area_element.cc
index 4924dfa0d84..d10fd35c9af 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_text_area_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_text_area_element.cc
@@ -37,6 +37,8 @@
#include "third_party/blink/renderer/core/editing/iterators/text_iterator.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
#include "third_party/blink/renderer/core/events/before_text_inserted_event.h"
+#include "third_party/blink/renderer/core/events/drag_event.h"
+#include "third_party/blink/renderer/core/events/mouse_event.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/forms/form_controller.h"
#include "third_party/blink/renderer/core/html/forms/form_data.h"
@@ -69,6 +71,11 @@ static inline unsigned ComputeLengthForAPIValue(const String& text) {
return text.length() - crlf_count;
}
+static inline void ReplaceCRWithNewLine(String& text) {
+ text.Replace("\r\n", "\n");
+ text.Replace('\r', '\n');
+}
+
HTMLTextAreaElement::HTMLTextAreaElement(Document& document)
: TextControlElement(html_names::kTextareaTag, document),
rows_(kDefaultRows),
@@ -154,7 +161,7 @@ void HTMLTextAreaElement::ParseAttribute(
rows_ = rows;
if (GetLayoutObject()) {
GetLayoutObject()
- ->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ ->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kAttributeChanged);
}
}
@@ -167,7 +174,7 @@ void HTMLTextAreaElement::ParseAttribute(
cols_ = cols;
if (LayoutObject* layout_object = GetLayoutObject()) {
layout_object
- ->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ ->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kAttributeChanged);
}
}
@@ -176,11 +183,11 @@ void HTMLTextAreaElement::ParseAttribute(
// deprecated. The soft/hard /off values are a recommendation for HTML 4
// extension by IE and NS 4.
WrapMethod wrap;
- if (DeprecatedEqualIgnoringCase(value, "physical") ||
- DeprecatedEqualIgnoringCase(value, "hard") ||
- DeprecatedEqualIgnoringCase(value, "on"))
+ if (EqualIgnoringASCIICase(value, "physical") ||
+ EqualIgnoringASCIICase(value, "hard") ||
+ EqualIgnoringASCIICase(value, "on"))
wrap = kHardWrap;
- else if (DeprecatedEqualIgnoringCase(value, "off"))
+ else if (EqualIgnoringASCIICase(value, "off"))
wrap = kNoWrap;
else
wrap = kSoftWrap;
@@ -188,7 +195,7 @@ void HTMLTextAreaElement::ParseAttribute(
wrap_ = wrap;
if (LayoutObject* layout_object = GetLayoutObject()) {
layout_object
- ->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ ->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kAttributeChanged);
}
}
@@ -214,7 +221,7 @@ void HTMLTextAreaElement::AppendToFormData(FormData& form_data) {
if (GetName().IsEmpty())
return;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kForm);
const String& text =
(wrap_ == kHardWrap) ? ValueWithHardLineBreaks() : value();
@@ -264,7 +271,7 @@ void HTMLTextAreaElement::UpdateFocusAppearanceWithOptions(
void HTMLTextAreaElement::DefaultEventHandler(Event& event) {
if (GetLayoutObject() &&
- (event.IsMouseEvent() || event.IsDragEvent() ||
+ (IsA<MouseEvent>(event) || IsA<DragEvent>(event) ||
event.HasInterface(event_interface_names::kWheelEvent) ||
event.type() == event_type_names::kBlur)) {
ForwardEvent(event);
@@ -332,7 +339,7 @@ void HTMLTextAreaElement::HandleBeforeTextInsertedEvent(
if (IsFocused()) {
// TODO(editing-dev): Use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kForm);
selection_length = ComputeLengthForAPIValue(
GetDocument().GetFrame()->Selection().SelectedText());
@@ -397,8 +404,7 @@ void HTMLTextAreaElement::SetValueCommon(
// Code elsewhere normalizes line endings added by the user via the keyboard
// or pasting. We normalize line endings coming from JavaScript here.
String normalized_value = new_value;
- normalized_value.Replace("\r\n", "\n");
- normalized_value.Replace('\r', '\n');
+ ReplaceCRWithNewLine(normalized_value);
// Clear the suggested value. Use the base class version to not trigger a view
// update.
@@ -445,6 +451,10 @@ void HTMLTextAreaElement::SetValueCommon(
DispatchFormControlChangeEvent();
break;
+ case TextFieldEventBehavior::kDispatchInputEvent:
+ DispatchInputEvent();
+ break;
+
case TextFieldEventBehavior::kDispatchInputAndChangeEvent:
DispatchInputEvent();
DispatchFormControlChangeEvent();
@@ -503,10 +513,12 @@ String HTMLTextAreaElement::validationMessage() const {
bool HTMLTextAreaElement::ValueMissing() const {
// We should not call value() for performance.
- return willValidate() && ValueMissing(nullptr);
+ return ValueMissing(nullptr);
}
bool HTMLTextAreaElement::ValueMissing(const String* value) const {
+ // For textarea elements, the value is missing only if it is mutable.
+ // https://html.spec.whatwg.org/multipage/form-elements.html#attr-textarea-required
return IsRequiredFormControl() && !IsDisabledOrReadOnly() &&
(value ? *value : this->value()).IsEmpty();
}
@@ -602,7 +614,10 @@ void HTMLTextAreaElement::UpdatePlaceholderText() {
IsPlaceholderVisible() ? CSSValueID::kBlock : CSSValueID::kNone, true);
UserAgentShadowRoot()->InsertBefore(placeholder, InnerEditorElement());
}
- placeholder->setTextContent(placeholder_text);
+ String normalized_value = placeholder_text;
+ // https://html.spec.whatwg.org/multipage/form-elements.html#attr-textarea-placeholder
+ ReplaceCRWithNewLine(normalized_value);
+ placeholder->setTextContent(normalized_value);
}
String HTMLTextAreaElement::GetPlaceholderValue() const {
diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_text_area_element.h b/chromium/third_party/blink/renderer/core/html/forms/html_text_area_element.h
index 4980524e917..8700e494c15 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/html_text_area_element.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/html_text_area_element.h
@@ -117,6 +117,7 @@ class CORE_EXPORT HTMLTextAreaElement final : public TextControlElement {
const QualifiedName&,
const AtomicString&,
MutableCSSPropertyValueSet*) override;
+ bool TypeShouldForceLegacyLayout() const override { return true; }
LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override;
void AppendToFormData(FormData&) override;
void ResetImpl() override;
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 53857f6329a..53abd4c58ba 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
@@ -87,12 +87,12 @@ bool ImageInputType::SupportsValidation() const {
}
static IntPoint ExtractClickLocation(const Event& event) {
- if (!event.UnderlyingEvent() || !event.UnderlyingEvent()->IsMouseEvent())
+ const auto* mouse_event = DynamicTo<MouseEvent>(event.UnderlyingEvent());
+ if (!event.UnderlyingEvent() || !mouse_event)
return IntPoint();
- auto& mouse_event = *ToMouseEvent(event.UnderlyingEvent());
- if (!mouse_event.HasPosition())
+ if (!mouse_event->HasPosition())
return IntPoint();
- return IntPoint(mouse_event.offsetX(), mouse_event.offsetY());
+ return IntPoint(mouse_event->offsetX(), mouse_event->offsetY());
}
void ImageInputType::HandleDOMActivateEvent(Event& event) {
@@ -104,6 +104,10 @@ void ImageInputType::HandleDOMActivateEvent(Event& event) {
event.SetDefaultHandled();
}
+bool ImageInputType::TypeShouldForceLegacyLayout() const {
+ return true;
+}
+
LayoutObject* ImageInputType::CreateLayoutObject(const ComputedStyle& style,
LegacyLayout legacy) const {
if (use_fallback_content_)
@@ -188,7 +192,8 @@ unsigned ImageInputType::Height() const {
}
}
- GetElement().GetDocument().UpdateStyleAndLayout();
+ GetElement().GetDocument().UpdateStyleAndLayout(
+ DocumentUpdateReason::kJavaScript);
LayoutBox* box = GetElement().GetLayoutBox();
return box ? AdjustForAbsoluteZoom::AdjustInt(box->ContentHeight().ToInt(),
@@ -213,7 +218,8 @@ unsigned ImageInputType::Width() const {
}
}
- GetElement().GetDocument().UpdateStyleAndLayout();
+ GetElement().GetDocument().UpdateStyleAndLayout(
+ DocumentUpdateReason::kJavaScript);
LayoutBox* box = GetElement().GetLayoutBox();
return box ? AdjustForAbsoluteZoom::AdjustInt(box->ContentWidth().ToInt(),
@@ -277,13 +283,9 @@ void ImageInputType::CreateShadowSubtree() {
HTMLImageFallbackHelper::CreateAltTextShadowTree(GetElement());
}
-scoped_refptr<ComputedStyle> ImageInputType::CustomStyleForLayoutObject(
- scoped_refptr<ComputedStyle> new_style) {
- if (!use_fallback_content_)
- return new_style;
-
- return HTMLImageFallbackHelper::CustomStyleForAltText(GetElement(),
- std::move(new_style));
+void ImageInputType::CustomStyleForLayoutObject(ComputedStyle& style) {
+ if (use_fallback_content_)
+ HTMLImageFallbackHelper::CustomStyleForAltText(GetElement(), style);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/forms/image_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/image_input_type.h
index 01d26bee19d..647923dc7d3 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/image_input_type.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/image_input_type.h
@@ -41,8 +41,7 @@ namespace blink {
class ImageInputType final : public BaseButtonInputType {
public:
explicit ImageInputType(HTMLInputElement&);
- scoped_refptr<ComputedStyle> CustomStyleForLayoutObject(
- scoped_refptr<ComputedStyle>) override;
+ void CustomStyleForLayoutObject(ComputedStyle& style) override;
private:
void CountUsage() override;
@@ -51,6 +50,7 @@ class ImageInputType final : public BaseButtonInputType {
void AppendToFormData(FormData&) const override;
String ResultForDialogSubmit() const override;
bool SupportsValidation() const override;
+ bool TypeShouldForceLegacyLayout() const override;
LayoutObject* CreateLayoutObject(const ComputedStyle&,
LegacyLayout) const override;
void HandleDOMActivateEvent(Event&) override;
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 d0b43d21802..dbe99ae5e5b 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
@@ -70,6 +70,7 @@
#include "third_party/blink/renderer/core/layout/layout_theme.h"
#include "third_party/blink/renderer/core/page/page.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/json/json_values.h"
#include "third_party/blink/renderer/platform/text/platform_locale.h"
#include "third_party/blink/renderer/platform/text/text_break_iterator.h"
@@ -253,6 +254,8 @@ void InputType::SetValueAsDecimal(const Decimal& new_value,
void InputType::ReadingChecked() const {}
+void InputType::WillUpdateCheckedness(bool) {}
+
bool InputType::SupportsValidation() const {
return true;
}
@@ -296,7 +299,15 @@ bool InputType::RangeUnderflow(const String& value) const {
if (!numeric_value.IsFinite())
return false;
- return numeric_value < CreateStepRange(kRejectAny).Minimum();
+ StepRange step_range = CreateStepRange(kRejectAny);
+ if (step_range.HasReversedRange()) {
+ // With a reversed range, any value outside of the midnight-crossing valid
+ // range is considered underflow and overflow.
+ return numeric_value > step_range.Maximum() &&
+ numeric_value < step_range.Minimum();
+ } else {
+ return numeric_value < step_range.Minimum();
+ }
}
bool InputType::RangeOverflow(const String& value) const {
@@ -307,7 +318,15 @@ bool InputType::RangeOverflow(const String& value) const {
if (!numeric_value.IsFinite())
return false;
- return numeric_value > CreateStepRange(kRejectAny).Maximum();
+ StepRange step_range = CreateStepRange(kRejectAny);
+ if (step_range.HasReversedRange()) {
+ // With a reversed range, any value outside of the midnight-crossing valid
+ // range is considered underflow and overflow.
+ return numeric_value > step_range.Maximum() &&
+ numeric_value < step_range.Minimum();
+ } else {
+ return numeric_value > step_range.Maximum();
+ }
}
Decimal InputType::DefaultValueForStepUp() const {
@@ -389,6 +408,17 @@ String InputType::RangeUnderflowText(const Decimal&) const {
return String();
}
+String InputType::ReversedRangeOutOfRangeText(const Decimal&,
+ const Decimal&) const {
+ NOTREACHED();
+ return String();
+}
+
+String InputType::RangeInvalidText(const Decimal&, const Decimal&) const {
+ NOTREACHED();
+ return String();
+}
+
String InputType::TypeMismatchText() const {
return GetLocale().QueryString(IDS_FORM_VALIDATION_TYPE_MISMATCH);
}
@@ -444,6 +474,20 @@ std::pair<String, String> InputType::ValidationMessage(
StepRange step_range(CreateStepRange(kRejectAny));
+ if (step_range.Minimum() > step_range.Maximum() &&
+ !step_range.HasReversedRange()) {
+ return std::make_pair(
+ RangeInvalidText(step_range.Minimum(), step_range.Maximum()),
+ g_empty_string);
+ }
+
+ if (step_range.HasReversedRange() && numeric_value < step_range.Minimum() &&
+ numeric_value > step_range.Maximum()) {
+ return std::make_pair(
+ ReversedRangeOutOfRangeText(step_range.Minimum(), step_range.Maximum()),
+ g_empty_string);
+ }
+
if (numeric_value < step_range.Minimum())
return std::make_pair(RangeUnderflowText(step_range.Minimum()),
g_empty_string);
@@ -589,6 +633,9 @@ void InputType::SetValue(const String& sanitized_value,
case TextFieldEventBehavior::kDispatchChangeEvent:
GetElement().DispatchFormControlChangeEvent();
break;
+ case TextFieldEventBehavior::kDispatchInputEvent:
+ GetElement().DispatchInputEvent();
+ break;
case TextFieldEventBehavior::kDispatchInputAndChangeEvent:
GetElement().DispatchInputEvent();
GetElement().DispatchFormControlChangeEvent();
@@ -765,7 +812,7 @@ void InputType::ApplyStep(const Decimal& current,
Decimal new_value = current;
const AtomicString& step_string =
GetElement().FastGetAttribute(html_names::kStepAttr);
- if (!DeprecatedEqualIgnoringCase(step_string, "any") &&
+ if (!EqualIgnoringASCIICase(step_string, "any") &&
step_range.StepMismatch(current)) {
// Snap-to-step / clamping steps
// If the current value is not matched to step value:
@@ -786,10 +833,10 @@ void InputType::ApplyStep(const Decimal& current,
}
new_value = new_value + step_range.Step() * Decimal::FromDouble(count);
- if (!DeprecatedEqualIgnoringCase(step_string, "any"))
+ if (!EqualIgnoringASCIICase(step_string, "any"))
new_value = step_range.AlignValueForStep(current, new_value);
- // 7. If the element has a minimum, and value is less than that minimum,
+ // 8. If the element has a minimum, and value is less than that minimum,
// then set value to the smallest value that, when subtracted from the step
// base, is an integral multiple of the allowed value step, and that is more
// than or equal to minimum.
@@ -800,17 +847,23 @@ void InputType::ApplyStep(const Decimal& current,
new_value = aligned_minimum;
}
- // 8. If the element has a maximum, and value is greater than that maximum,
+ // 9. If the element has a maximum, and value is greater than that maximum,
// then set value to the largest value that, when subtracted from the step
// base, is an integral multiple of the allowed value step, and that is less
// than or equal to maximum.
if (new_value > step_range.Maximum())
new_value = aligned_maximum;
- // 9. Let value as string be the result of running the algorithm to convert
+ // 10. If either the method invoked was the stepDown() method and value is
+ // greater than valueBeforeStepping, or the method invoked was the stepUp()
+ // method and value is less than valueBeforeStepping, then return.
+ if ((count < 0 && current < new_value) || (count > 0 && current > new_value))
+ return;
+
+ // 11. Let value as string be the result of running the algorithm to convert
// a number to a string, as defined for the input element's type attribute's
// current state, on value.
- // 10. Set the value of the element to value as string.
+ // 12. Set the value of the element to value as string.
SetValueAsDecimal(new_value, event_behavior, exception_state);
if (AXObjectCache* cache = GetElement().GetDocument().ExistingAXObjectCache())
@@ -856,7 +909,7 @@ void InputType::StepUpFromLayoutObject(int n) {
// * If 0 is in-range, but not matched to step value
// - The value should be the larger matched value nearest to 0 if n > 0
// e.g. <input type=number min=-100 step=3> -> 2
- // - The value should be the smaler matched value nearest to 0 if n < 0
+ // - The value should be the smaller matched value nearest to 0 if n < 0
// e.g. <input type=number min=-100 step=3> -> -1
// As for date/datetime-local/month/time/week types, the current value is
// assumed as "the current local date/time".
@@ -941,12 +994,35 @@ Decimal InputType::FindStepBase(const Decimal& default_value) const {
return step_base;
}
+StepRange InputType::CreateReversibleStepRange(
+ AnyStepHandling any_step_handling,
+ const Decimal& step_base_default,
+ const Decimal& minimum_default,
+ const Decimal& maximum_default,
+ const StepRange::StepDescription& step_description) const {
+ return CreateStepRange(any_step_handling, step_base_default, minimum_default,
+ maximum_default, step_description,
+ /*supports_reversed_range=*/true);
+}
+
StepRange InputType::CreateStepRange(
AnyStepHandling any_step_handling,
const Decimal& step_base_default,
const Decimal& minimum_default,
const Decimal& maximum_default,
const StepRange::StepDescription& step_description) const {
+ return CreateStepRange(any_step_handling, step_base_default, minimum_default,
+ maximum_default, step_description,
+ /*supports_reversed_range=*/false);
+}
+
+StepRange InputType::CreateStepRange(
+ AnyStepHandling any_step_handling,
+ const Decimal& step_base_default,
+ const Decimal& minimum_default,
+ const Decimal& maximum_default,
+ const StepRange::StepDescription& step_description,
+ bool supports_reversed_range) const {
bool has_range_limitations = false;
const Decimal step_base = FindStepBase(step_base_default);
Decimal minimum =
@@ -964,17 +1040,20 @@ StepRange InputType::CreateStepRange(
const Decimal step = StepRange::ParseStep(
any_step_handling, step_description,
GetElement().FastGetAttribute(html_names::kStepAttr));
- return StepRange(step_base, minimum, maximum, has_range_limitations, step,
- step_description);
+ bool has_reversed_range =
+ has_range_limitations && supports_reversed_range && maximum < minimum;
+ return StepRange(step_base, minimum, maximum, has_range_limitations,
+ has_reversed_range, step, step_description);
}
void InputType::AddWarningToConsole(const char* message_format,
const String& value) const {
- GetElement().GetDocument().AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kRendering,
- mojom::ConsoleMessageLevel::kWarning,
- String::Format(message_format,
- JSONValue::QuoteString(value).Utf8().c_str())));
+ GetElement().GetDocument().AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kRendering,
+ mojom::ConsoleMessageLevel::kWarning,
+ String::Format(message_format,
+ JSONValue::QuoteString(value).Utf8().c_str())));
}
} // namespace blink
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 9f36023abe6..45ec3898704 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
@@ -104,7 +104,12 @@ class CORE_EXPORT InputType : public GarbageCollected<InputType> {
virtual void SetValueAsDecimal(const Decimal&,
TextFieldEventBehavior,
ExceptionState&) const;
+
+ // Functions related to 'checked'
+
virtual void ReadingChecked() const;
+ // The function is called just before updating checkedness.
+ virtual void WillUpdateCheckedness(bool new_checked);
// Validation functions
@@ -140,6 +145,10 @@ class CORE_EXPORT InputType : public GarbageCollected<InputType> {
virtual String BadInputText() const;
virtual String RangeOverflowText(const Decimal& maximum) const;
virtual String RangeUnderflowText(const Decimal& minimum) const;
+ virtual String ReversedRangeOutOfRangeText(const Decimal& minimum,
+ const Decimal& maximum) const;
+ virtual String RangeInvalidText(const Decimal& minimum,
+ const Decimal& maximum) const;
virtual String TypeMismatchText() const;
virtual String ValueMissingText() const;
virtual bool CanSetStringValue() const;
@@ -240,6 +249,11 @@ class CORE_EXPORT InputType : public GarbageCollected<InputType> {
const Decimal& minimum_default,
const Decimal& maximum_default,
const StepRange::StepDescription&) const;
+ StepRange CreateReversibleStepRange(AnyStepHandling,
+ const Decimal& step_base_default,
+ const Decimal& minimum_default,
+ const Decimal& maximum_default,
+ const StepRange::StepDescription&) const;
void AddWarningToConsole(const char* message_format,
const String& value) const;
@@ -252,6 +266,13 @@ class CORE_EXPORT InputType : public GarbageCollected<InputType> {
TextFieldEventBehavior,
ExceptionState&);
+ StepRange CreateStepRange(AnyStepHandling,
+ const Decimal& step_base_default,
+ const Decimal& minimum_default,
+ const Decimal& maximum_default,
+ const StepRange::StepDescription&,
+ bool supports_reversed_range) const;
+
Member<HTMLInputElement> element_;
DISALLOW_COPY_AND_ASSIGN(InputType);
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 ed41b3c08be..336cea6892e 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
@@ -74,28 +74,29 @@ void InputTypeView::DispatchSimulatedClickIfActive(KeyboardEvent& event) const {
void InputTypeView::AccessKeyAction(bool) {
GetElement().focus(FocusParams(SelectionBehaviorOnFocus::kReset,
- kWebFocusTypeNone, nullptr));
+ mojom::blink::FocusType::kNone, nullptr));
}
bool InputTypeView::ShouldSubmitImplicitly(const Event& event) {
- return event.IsKeyboardEvent() &&
- event.type() == event_type_names::kKeypress &&
- ToKeyboardEvent(event).charCode() == '\r';
+ auto* keyboard_event = DynamicTo<KeyboardEvent>(event);
+ return keyboard_event && event.type() == event_type_names::kKeypress &&
+ keyboard_event->charCode() == '\r';
}
HTMLFormElement* InputTypeView::FormForSubmission() const {
return GetElement().Form();
}
+bool InputTypeView::TypeShouldForceLegacyLayout() const {
+ return false;
+}
+
LayoutObject* InputTypeView::CreateLayoutObject(const ComputedStyle& style,
LegacyLayout legacy) const {
return LayoutObject::CreateObject(&GetElement(), style, legacy);
}
-scoped_refptr<ComputedStyle> InputTypeView::CustomStyleForLayoutObject(
- scoped_refptr<ComputedStyle> original_style) {
- return original_style;
-}
+void InputTypeView::CustomStyleForLayoutObject(ComputedStyle&) {}
TextDirection InputTypeView::ComputedTextDirection() {
return GetElement().ComputedStyleRef().Direction();
@@ -111,12 +112,16 @@ bool InputTypeView::HasCustomFocusLogic() const {
void InputTypeView::HandleBlurEvent() {}
-void InputTypeView::HandleFocusInEvent(Element*, WebFocusType) {}
+void InputTypeView::HandleFocusInEvent(Element*, mojom::blink::FocusType) {}
void InputTypeView::StartResourceLoading() {}
void InputTypeView::ClosePopupView() {}
+bool InputTypeView::HasOpenedPopup() const {
+ return false;
+}
+
bool InputTypeView::NeedsShadowSubtree() const {
return true;
}
@@ -128,6 +133,14 @@ void InputTypeView::DestroyShadowSubtree() {
root->RemoveChildren();
}
+HTMLInputElement* InputTypeView::UploadButton() const {
+ return nullptr;
+}
+
+String InputTypeView::FileStatusText() const {
+ return String();
+}
+
void InputTypeView::AltAttributeChanged() {}
void InputTypeView::SrcAttributeChanged() {}
@@ -181,6 +194,10 @@ void InputTypeView::RestoreFormControlState(const FormControlState& state) {
GetElement().setValue(state[0]);
}
+bool InputTypeView::IsDraggedSlider() const {
+ return false;
+}
+
bool InputTypeView::HasBadInput() const {
return false;
}
@@ -190,4 +207,8 @@ void ClickHandlingState::Trace(Visitor* visitor) {
EventDispatchHandlingState::Trace(visitor);
}
+String InputTypeView::RawValue() const {
+ return g_empty_string;
+}
+
} // namespace blink
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 ef47deadfda..cba7ed4d453 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
@@ -34,7 +34,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_INPUT_TYPE_VIEW_H_
#include "base/macros.h"
-#include "third_party/blink/public/platform/web_focus_type.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.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/platform/heap/handle.h"
@@ -91,7 +91,8 @@ class CORE_EXPORT InputTypeView : public GarbageCollectedMixin {
virtual bool ShouldSubmitImplicitly(const Event&);
virtual HTMLFormElement* FormForSubmission() const;
virtual bool HasCustomFocusLogic() const;
- virtual void HandleFocusInEvent(Element* old_focused_element, WebFocusType);
+ virtual void HandleFocusInEvent(Element* old_focused_element,
+ mojom::blink::FocusType);
virtual void HandleBlurEvent();
virtual void HandleDOMActivateEvent(Event&);
virtual void AccessKeyAction(bool send_mouse_events);
@@ -99,16 +100,23 @@ class CORE_EXPORT InputTypeView : public GarbageCollectedMixin {
void DispatchSimulatedClickIfActive(KeyboardEvent&) const;
virtual void SubtreeHasChanged();
+ virtual bool TypeShouldForceLegacyLayout() const;
virtual LayoutObject* CreateLayoutObject(const ComputedStyle&,
LegacyLayout) const;
- virtual scoped_refptr<ComputedStyle> CustomStyleForLayoutObject(
- scoped_refptr<ComputedStyle>);
+ virtual void CustomStyleForLayoutObject(ComputedStyle& style);
virtual TextDirection ComputedTextDirection();
virtual void StartResourceLoading();
virtual void ClosePopupView();
+ virtual bool HasOpenedPopup() const;
+
+ // Functions for shadow trees
+
virtual bool NeedsShadowSubtree() const;
virtual void CreateShadowSubtree();
virtual void DestroyShadowSubtree();
+ virtual HTMLInputElement* UploadButton() const;
+ virtual String FileStatusText() const;
+
virtual void MinOrMaxAttributeChanged();
virtual void StepAttributeChanged();
virtual void AltAttributeChanged();
@@ -129,10 +137,13 @@ class CORE_EXPORT InputTypeView : public GarbageCollectedMixin {
virtual bool HasFallbackContent() const { return false; }
virtual FormControlState SaveFormControlState() const;
virtual void RestoreFormControlState(const FormControlState&);
+ virtual bool IsDraggedSlider() const;
// Validation functions
virtual bool HasBadInput() const;
+ virtual String RawValue() const;
+
protected:
InputTypeView(HTMLInputElement& element) : element_(&element) {}
HTMLInputElement& GetElement() const { return *element_; }
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 5b3fa566f25..360545b4afe 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
@@ -5,9 +5,9 @@
#include "third_party/blink/renderer/core/html/forms/internal_popup_menu.h"
#include "build/build_config.h"
+#include "third_party/blink/public/common/input/web_mouse_event.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_mouse_event.h"
#include "third_party/blink/renderer/core/css/css_font_selector.h"
#include "third_party/blink/renderer/core/css/style_engine.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
@@ -31,6 +31,7 @@
#include "third_party/blink/renderer/platform/fonts/font_selector_client.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
#include "third_party/blink/renderer/platform/text/platform_locale.h"
+#include "ui/base/ui_base_features.h"
namespace blink {
@@ -286,6 +287,8 @@ void InternalPopupMenu::WriteDocument(SharedBuffer* data) {
AddProperty("scaleFactor", scale_factor, data);
bool is_rtl = !owner_style->IsLeftToRightDirection();
AddProperty("isRTL", is_rtl, data);
+ AddProperty("isFormControlsRefreshEnabled",
+ features::IsFormControlsRefreshEnabled(), data);
AddProperty("paddingStart",
is_rtl ? owner_element.ClientPaddingRight().ToDouble()
: owner_element.ClientPaddingLeft().ToDouble(),
@@ -411,11 +414,11 @@ void InternalPopupMenu::AddSeparator(ItemIterationContext& context,
PagePopupClient::AddString("},\n", data);
}
-void InternalPopupMenu::SelectFontsFromOwnerDocument(Document& document) {
+CSSFontSelector* InternalPopupMenu::CreateCSSFontSelector(
+ Document& popup_document) {
Document& owner_document = OwnerElement().GetDocument();
- document.GetStyleEngine().SetFontSelector(
- MakeGarbageCollected<PopupMenuCSSFontSelector>(
- &document, owner_document.GetStyleEngine().GetFontSelector()));
+ return MakeGarbageCollected<PopupMenuCSSFontSelector>(
+ &popup_document, owner_document.GetStyleEngine().GetFontSelector());
}
void InternalPopupMenu::SetValueAndClosePopup(int num_value,
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 b513ae14683..b6af0908fa0 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
@@ -12,6 +12,7 @@
namespace blink {
class ChromeClient;
+class CSSFontSelector;
class PagePopup;
class HTMLElement;
class HTMLHRElement;
@@ -49,7 +50,7 @@ class CORE_EXPORT InternalPopupMenu final : public PopupMenu,
// PagePopupClient functions:
void WriteDocument(SharedBuffer*) override;
- void SelectFontsFromOwnerDocument(Document&) override;
+ CSSFontSelector* CreateCSSFontSelector(Document& popup_document) override;
void SetValueAndClosePopup(int, const String&) override;
void SetValue(const String&) override;
void CancelPopup() override;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu_test.cc b/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu_test.cc
index 72c34bf2c8f..e74aa17fb04 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu_test.cc
@@ -25,14 +25,13 @@ TEST(InternalPopupMenuTest, WriteDocumentInStyleDirtyTree) {
auto dummy_page_holder_ =
std::make_unique<DummyPageHolder>(IntSize(800, 600));
Document& document = dummy_page_holder_->GetDocument();
- document.body()->SetInnerHTMLFromString(R"HTML(
+ document.body()->setInnerHTML(R"HTML(
<select id="select">
<option value="foo">Foo</option>
<option value="bar" style="display:none">Bar</option>
</select>
)HTML");
- document.View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ document.View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
auto* select = To<HTMLSelectElement>(document.getElementById("select"));
ASSERT_TRUE(select);
auto* menu = MakeGarbageCollected<InternalPopupMenu>(
@@ -50,7 +49,7 @@ TEST(InternalPopupMenuTest, ShowSelectDisplayNone) {
auto dummy_page_holder_ =
std::make_unique<DummyPageHolder>(IntSize(800, 600));
Document& document = dummy_page_holder_->GetDocument();
- document.body()->SetInnerHTMLFromString(R"HTML(
+ document.body()->setInnerHTML(R"HTML(
<div id="container">
<select id="select">
<option>1</option>
@@ -58,8 +57,8 @@ TEST(InternalPopupMenuTest, ShowSelectDisplayNone) {
</select>
</div>
)HTML");
- document.View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ document.View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
+
auto* div = document.getElementById("container");
auto* select = To<HTMLSelectElement>(document.getElementById("select"));
ASSERT_TRUE(select);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/labels_node_list.h b/chromium/third_party/blink/renderer/core/html/forms/labels_node_list.h
index ba26f27e7a7..106dae21b52 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/labels_node_list.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/labels_node_list.h
@@ -25,7 +25,6 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_LABELS_NODE_LIST_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_LABELS_NODE_LIST_H_
-#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/core/dom/live_node_list.h"
namespace blink {
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 53ef3614d4b..5bfc398d3bb 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
@@ -45,6 +45,7 @@
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/page/validation_message_client.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/text/bidi_text_run.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -314,8 +315,7 @@ void ListedElement::UpdateWillValidateCache() {
}
bool ListedElement::CustomError() const {
- return ToHTMLElement().willValidate() &&
- !custom_validation_message_.IsEmpty();
+ return !custom_validation_message_.IsEmpty();
}
bool ListedElement::HasBadInput() const {
@@ -371,7 +371,9 @@ void ListedElement::SetCustomValidationMessage(const String& message) {
}
String ListedElement::validationMessage() const {
- return CustomError() ? custom_validation_message_ : String();
+ return ToHTMLElement().willValidate() && CustomError()
+ ? custom_validation_message_
+ : String();
}
String ListedElement::ValidationSubMessage() const {
@@ -493,7 +495,7 @@ bool ListedElement::reportValidity() {
// Update layout now before calling IsFocusable(), which has
// !LayoutObject()->NeedsLayout() assertion.
HTMLElement& element = ToHTMLElement();
- element.GetDocument().UpdateStyleAndLayout();
+ element.GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kForm);
if (element.IsFocusable()) {
ShowValidationMessage();
return false;
@@ -503,8 +505,9 @@ bool ListedElement::reportValidity() {
"An invalid form control with name='%name' is not focusable.");
message.Replace("%name", GetName());
element.GetDocument().AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kRendering,
- mojom::ConsoleMessageLevel::kError, message));
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kRendering,
+ mojom::ConsoleMessageLevel::kError, message));
}
return false;
}
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
new file mode 100644
index 00000000000..abd197d33c8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/forms/menu_list_inner_element.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/html/forms/menu_list_inner_element.h"
+
+#include "third_party/blink/renderer/core/dom/node_computed_style.h"
+#include "third_party/blink/renderer/core/html/forms/html_select_element.h"
+#include "third_party/blink/renderer/core/layout/layout_theme.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
+
+namespace blink {
+
+MenuListInnerElement::MenuListInnerElement(Document& document)
+ : HTMLDivElement(document) {
+ SetHasCustomStyleCallbacks();
+}
+
+scoped_refptr<ComputedStyle>
+MenuListInnerElement::CustomStyleForLayoutObject() {
+ const ComputedStyle& parent_style = OwnerShadowHost()->ComputedStyleRef();
+ scoped_refptr<ComputedStyle> style =
+ ComputedStyle::CreateAnonymousStyleWithDisplay(parent_style,
+ EDisplay::kBlock);
+ style->SetFlexGrow(1);
+ style->SetFlexShrink(1);
+ // min-width: 0; is needed for correct shrinking.
+ style->SetMinWidth(Length::Fixed(0));
+ style->SetHasLineIfEmpty(true);
+ style->SetOverflowX(EOverflow::kHidden);
+ style->SetOverflowY(EOverflow::kHidden);
+ style->SetShouldIgnoreOverflowPropertyForInlineBlockBaseline();
+ style->SetTextOverflow(parent_style.TextOverflow());
+ style->SetUserModify(EUserModify::kReadOnly);
+
+ // 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
+ // center.
+ if (parent_style.AlignItemsPosition() == ItemPosition::kCenter) {
+ style->SetMarginTop(Length());
+ style->SetMarginBottom(Length());
+ style->SetAlignSelfPosition(ItemPosition::kFlexStart);
+ }
+
+ // We set margin-left/right instead of padding-left/right to clip text by
+ // 'overflow: hidden'.
+ LayoutTheme& theme = LayoutTheme::GetTheme();
+ Length margin_start =
+ Length::Fixed(theme.PopupInternalPaddingStart(parent_style));
+ Length margin_end = Length::Fixed(
+ theme.PopupInternalPaddingEnd(GetDocument().GetFrame(), parent_style));
+ if (parent_style.IsLeftToRightDirection()) {
+ style->SetTextAlign(ETextAlign::kLeft);
+ style->SetMarginLeft(margin_start);
+ style->SetMarginRight(margin_end);
+ } else {
+ style->SetTextAlign(ETextAlign::kRight);
+ style->SetMarginLeft(margin_end);
+ style->SetMarginRight(margin_start);
+ }
+ style->SetPaddingTop(
+ Length::Fixed(theme.PopupInternalPaddingTop(parent_style)));
+ style->SetPaddingBottom(
+ Length::Fixed(theme.PopupInternalPaddingBottom(parent_style)));
+
+ if (const ComputedStyle* option_style =
+ To<HTMLSelectElement>(OwnerShadowHost())->OptionStyle()) {
+ style->SetDirection(option_style->Direction());
+ style->SetUnicodeBidi(option_style->GetUnicodeBidi());
+ }
+
+ return style;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/forms/menu_list_inner_element.h b/chromium/third_party/blink/renderer/core/html/forms/menu_list_inner_element.h
new file mode 100644
index 00000000000..b3f7085cb59
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/forms/menu_list_inner_element.h
@@ -0,0 +1,21 @@
+// 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_FORMS_MENU_LIST_INNER_ELEMENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_MENU_LIST_INNER_ELEMENT_H_
+
+#include "third_party/blink/renderer/core/html/html_div_element.h"
+
+namespace blink {
+
+class MenuListInnerElement : public HTMLDivElement {
+ public:
+ explicit MenuListInnerElement(Document& document);
+
+ private:
+ scoped_refptr<ComputedStyle> CustomStyleForLayoutObject() override;
+};
+
+} // namespace blink
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_MENU_LIST_INNER_ELEMENT_H_
diff --git a/chromium/third_party/blink/renderer/core/html/forms/month_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/month_input_type.cc
index 807f7e5cafb..e72af81f289 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/month_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/month_input_type.cc
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/core/html/forms/month_input_type.h"
+#include "third_party/blink/public/strings/grit/blink_strings.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/html/forms/date_time_fields_state.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
@@ -168,4 +169,8 @@ bool MonthInputType::IsValidFormat(bool has_year,
return has_year && has_month;
}
+String MonthInputType::AriaRoleForPickerIndicator() const {
+ return GetLocale().QueryString(IDS_AX_CALENDAR_SHOW_MONTH_PICKER);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/forms/month_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/month_input_type.h
index 27feb7cf4ae..0bbd850b3be 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/month_input_type.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/month_input_type.h
@@ -66,6 +66,7 @@ class MonthInputType final : public BaseTemporalInputType {
bool has_hour,
bool has_minute,
bool has_second) const override;
+ String AriaRoleForPickerIndicator() const override;
};
} // namespace blink
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 665de490bc9..76092674346 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
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/css_value_keywords.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -56,6 +57,7 @@
#include "third_party/blink/renderer/platform/text/date_time_format.h"
#include "third_party/blink/renderer/platform/text/platform_locale.h"
#include "third_party/blink/renderer/platform/wtf/date_math.h"
+#include "ui/base/ui_base_features.h"
namespace blink {
@@ -162,9 +164,10 @@ ClearButtonElement* MultipleFieldsTemporalInputTypeView::GetClearButtonElement()
PickerIndicatorElement*
MultipleFieldsTemporalInputTypeView::GetPickerIndicatorElement() const {
- return ToPickerIndicatorElementOrDie(
- GetElement().UserAgentShadowRoot()->getElementById(
- shadow_element_names::PickerIndicator()));
+ auto* element = GetElement().UserAgentShadowRoot()->getElementById(
+ shadow_element_names::PickerIndicator());
+ CHECK(!element || IsA<PickerIndicatorElement>(element));
+ return To<PickerIndicatorElement>(element);
}
inline bool MultipleFieldsTemporalInputTypeView::ContainsFocusedShadowElement()
@@ -174,7 +177,7 @@ inline bool MultipleFieldsTemporalInputTypeView::ContainsFocusedShadowElement()
}
void MultipleFieldsTemporalInputTypeView::DidBlurFromControl(
- WebFocusType focus_type) {
+ mojom::blink::FocusType focus_type) {
// We don't need to call blur(). This function is called when control
// lost focus.
@@ -188,7 +191,7 @@ void MultipleFieldsTemporalInputTypeView::DidBlurFromControl(
}
void MultipleFieldsTemporalInputTypeView::DidFocusOnControl(
- WebFocusType focus_type) {
+ mojom::blink::FocusType focus_type) {
// We don't need to call focus(). This function is called when control
// got focus.
@@ -278,8 +281,7 @@ bool MultipleFieldsTemporalInputTypeView::
void MultipleFieldsTemporalInputTypeView::PickerIndicatorChooseValue(
const String& value) {
if (GetElement().IsValidValue(value)) {
- GetElement().setValue(value,
- TextFieldEventBehavior::kDispatchInputAndChangeEvent);
+ GetElement().setValue(value, TextFieldEventBehavior::kDispatchInputEvent);
return;
}
@@ -296,7 +298,6 @@ void MultipleFieldsTemporalInputTypeView::PickerIndicatorChooseValue(
if (date.ParseDate(value, 0, end) && end == value.length())
edit->SetOnlyYearMonthDay(date);
}
- GetElement().DispatchFormControlChangeEvent();
}
void MultipleFieldsTemporalInputTypeView::PickerIndicatorChooseValue(
@@ -304,11 +305,10 @@ void MultipleFieldsTemporalInputTypeView::PickerIndicatorChooseValue(
DCHECK(std::isfinite(value) || std::isnan(value));
if (std::isnan(value)) {
GetElement().setValue(g_empty_string,
- TextFieldEventBehavior::kDispatchInputAndChangeEvent);
+ TextFieldEventBehavior::kDispatchInputEvent);
} else {
- GetElement().setValueAsNumber(
- value, ASSERT_NO_EXCEPTION,
- TextFieldEventBehavior::kDispatchInputAndChangeEvent);
+ GetElement().setValueAsNumber(value, ASSERT_NO_EXCEPTION,
+ TextFieldEventBehavior::kDispatchInputEvent);
}
}
@@ -334,6 +334,14 @@ bool MultipleFieldsTemporalInputTypeView::SetupDateTimeChooserParameters(
return GetElement().SetupDateTimeChooserParameters(parameters);
}
+void MultipleFieldsTemporalInputTypeView::DidEndChooser() {
+ GetElement().EnqueueChangeEvent();
+}
+
+String MultipleFieldsTemporalInputTypeView::AriaRoleForPickerIndicator() const {
+ return input_type_->AriaRoleForPickerIndicator();
+}
+
MultipleFieldsTemporalInputTypeView::MultipleFieldsTemporalInputTypeView(
HTMLInputElement& element,
BaseTemporalInputType& input_type)
@@ -357,25 +365,17 @@ void MultipleFieldsTemporalInputTypeView::Blur() {
ClosePopupView();
}
-scoped_refptr<ComputedStyle>
-MultipleFieldsTemporalInputTypeView::CustomStyleForLayoutObject(
- scoped_refptr<ComputedStyle> original_style) {
- EDisplay original_display = original_style->Display();
+void MultipleFieldsTemporalInputTypeView::CustomStyleForLayoutObject(
+ ComputedStyle& style) {
+ EDisplay original_display = style.Display();
EDisplay new_display = original_display;
if (original_display == EDisplay::kInline ||
original_display == EDisplay::kInlineBlock)
new_display = EDisplay::kInlineFlex;
else if (original_display == EDisplay::kBlock)
new_display = EDisplay::kFlex;
- TextDirection content_direction = ComputedTextDirection();
- if (original_style->Direction() == content_direction &&
- original_display == new_display)
- return original_style;
-
- scoped_refptr<ComputedStyle> style = ComputedStyle::Clone(*original_style);
- style->SetDirection(content_direction);
- style->SetDisplay(new_display);
- return style;
+ style.SetDisplay(new_display);
+ style.SetDirection(ComputedTextDirection());
}
void MultipleFieldsTemporalInputTypeView::CreateShadowSubtree() {
@@ -388,7 +388,7 @@ void MultipleFieldsTemporalInputTypeView::CreateShadowSubtree() {
MakeGarbageCollected<DateTimeEditElement, Document&,
DateTimeEditElement::EditControlOwner&>(document,
*this));
- if (!RuntimeEnabledFeatures::FormControlsRefreshEnabled()) {
+ if (!features::IsFormControlsRefreshEnabled()) {
GetElement().UpdateView();
container->AppendChild(
MakeGarbageCollected<ClearButtonElement, Document&,
@@ -441,16 +441,18 @@ void MultipleFieldsTemporalInputTypeView::HandleClickEvent(MouseEvent& event) {
void MultipleFieldsTemporalInputTypeView::HandleFocusInEvent(
Element* old_focused_element,
- WebFocusType type) {
+ mojom::blink::FocusType type) {
DateTimeEditElement* edit = GetDateTimeEditElement();
if (!edit || is_destroying_shadow_subtree_)
return;
- if (type == kWebFocusTypeBackward) {
+ if (type == mojom::blink::FocusType::kBackward) {
if (GetElement().GetDocument().GetPage())
GetElement().GetDocument().GetPage()->GetFocusController().AdvanceFocus(
type);
- } else if (type == kWebFocusTypeNone || type == kWebFocusTypeMouse ||
- type == kWebFocusTypePage || type == kWebFocusTypeAccessKey) {
+ } else if (type == mojom::blink::FocusType::kNone ||
+ type == mojom::blink::FocusType::kMouse ||
+ type == mojom::blink::FocusType::kPage ||
+ type == mojom::blink::FocusType::kAccessKey) {
edit->FocusByOwner(old_focused_element);
} else {
edit->FocusByOwner();
@@ -488,7 +490,7 @@ void MultipleFieldsTemporalInputTypeView::HandleKeydownEvent(
((event.key() == "ArrowDown" && event.getModifierState("Alt")) ||
(LayoutTheme::GetTheme().ShouldOpenPickerWithF4Key() &&
event.key() == "F4") ||
- (RuntimeEnabledFeatures::FormControlsRefreshEnabled() &&
+ (features::IsFormControlsRefreshEnabled() &&
(event.key() == "Enter" || event.key() == " ")))) {
if (PickerIndicatorElement* element = GetPickerIndicatorElement())
element->OpenPopup();
@@ -606,6 +608,13 @@ void MultipleFieldsTemporalInputTypeView::ClosePopupView() {
picker->ClosePopup();
}
+bool MultipleFieldsTemporalInputTypeView::HasOpenedPopup() const {
+ if (PickerIndicatorElement* picker = GetPickerIndicatorElement())
+ return picker->HasOpenedPopup();
+
+ return false;
+}
+
void MultipleFieldsTemporalInputTypeView::ValueAttributeChanged() {
if (!GetElement().HasDirtyValue())
UpdateView();
@@ -687,4 +696,8 @@ AXObject* MultipleFieldsTemporalInputTypeView::PopupRootAXObject() {
return nullptr;
}
+String MultipleFieldsTemporalInputTypeView::RawValue() const {
+ return GetDateTimeEditElement()->innerText();
+}
+
} // namespace blink
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 7ec1c405cce..2f4522ade10 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
@@ -31,7 +31,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_MULTIPLE_FIELDS_TEMPORAL_INPUT_TYPE_VIEW_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_MULTIPLE_FIELDS_TEMPORAL_INPUT_TYPE_VIEW_H_
-#include "third_party/blink/public/platform/web_focus_type.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/html/forms/clear_button_element.h"
#include "third_party/blink/renderer/core/html/forms/date_time_edit_element.h"
#include "third_party/blink/renderer/core/html/forms/input_type_view.h"
@@ -58,10 +58,12 @@ class MultipleFieldsTemporalInputTypeView final
~MultipleFieldsTemporalInputTypeView() override;
void Trace(Visitor*) override;
+ String RawValue() const override;
+
private:
// DateTimeEditElement::EditControlOwner functions
- void DidBlurFromControl(WebFocusType) final;
- void DidFocusOnControl(WebFocusType) final;
+ void DidBlurFromControl(mojom::blink::FocusType) final;
+ void DidFocusOnControl(mojom::blink::FocusType) final;
void EditControlValueChanged() final;
String FormatDateTimeFieldsState(const DateTimeFieldsState&) const override;
bool IsEditControlOwnerDisabled() const final;
@@ -84,6 +86,8 @@ class MultipleFieldsTemporalInputTypeView final
void PickerIndicatorChooseValue(double) final;
Element& PickerOwnerElement() const final;
bool SetupDateTimeChooserParameters(DateTimeChooserParameters&) final;
+ void DidEndChooser() final;
+ String AriaRoleForPickerIndicator() const final;
// ClearButtonElement::ClearButtonOwner functions.
void FocusAndSelectClearButtonOwner() override;
@@ -93,14 +97,15 @@ class MultipleFieldsTemporalInputTypeView final
// InputTypeView functions
void Blur() final;
void ClosePopupView() override;
- scoped_refptr<ComputedStyle> CustomStyleForLayoutObject(
- scoped_refptr<ComputedStyle>) override;
+ bool HasOpenedPopup() const override;
+ void CustomStyleForLayoutObject(ComputedStyle& style) override;
void CreateShadowSubtree() final;
void DestroyShadowSubtree() final;
void DisabledAttributeChanged() final;
void ForwardEvent(Event&) final;
void HandleClickEvent(MouseEvent&) final;
- void HandleFocusInEvent(Element* old_focused_element, WebFocusType) final;
+ void HandleFocusInEvent(Element* old_focused_element,
+ mojom::blink::FocusType) final;
void HandleKeydownEvent(KeyboardEvent&) final;
bool HasBadInput() const override;
bool HasCustomFocusLogic() const final;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/number_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/number_input_type.cc
index 996addc47ea..d4548d0aba5 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/number_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/number_input_type.cc
@@ -153,7 +153,7 @@ bool NumberInputType::SizeShouldIncludeDecoration(int default_size,
const String step_string =
GetElement().FastGetAttribute(html_names::kStepAttr);
- if (DeprecatedEqualIgnoringCase(step_string, "any"))
+ if (EqualIgnoringASCIICase(step_string, "any"))
return false;
const Decimal minimum = ParseToDecimalForNumberType(
@@ -246,10 +246,7 @@ void NumberInputType::WarnIfValueIsInvalid(const String& value) const {
if (value.IsEmpty() || !GetElement().SanitizeValue(value).IsEmpty())
return;
AddWarningToConsole(
- "The specified value %s is not a valid number. The value must match to "
- "the following regular expression: "
- "-?(\\d+|\\d+\\.\\d+|\\.\\d+)([eE][-+]?\\d+)?",
- value);
+ "The specified value %s cannot be parsed, or is out of range.", value);
}
bool NumberInputType::HasBadInput() const {
@@ -283,7 +280,7 @@ void NumberInputType::MinOrMaxAttributeChanged() {
if (GetElement().GetLayoutObject()) {
GetElement()
.GetLayoutObject()
- ->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ ->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kAttributeChanged);
}
}
@@ -294,7 +291,7 @@ void NumberInputType::StepAttributeChanged() {
if (GetElement().GetLayoutObject()) {
GetElement()
.GetLayoutObject()
- ->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ ->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kAttributeChanged);
}
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/option_list.cc b/chromium/third_party/blink/renderer/core/html/forms/option_list.cc
index 1b990eebaed..3fb7638b0ff 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/option_list.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/option_list.cc
@@ -27,8 +27,7 @@ void OptionListIterator::Advance(HTMLOptionElement* previous) {
current_ = option;
return;
}
- if (IsA<HTMLOptGroupElement>(current) &&
- current->parentNode() == select_.Get()) {
+ if (IsA<HTMLOptGroupElement>(current) && current->parentNode() == select_) {
if ((current_ = Traversal<HTMLOptionElement>::FirstChild(*current)))
return;
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/option_list.h b/chromium/third_party/blink/renderer/core/html/forms/option_list.h
index cd3ea21d4e5..51f8a5960a5 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/option_list.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/option_list.h
@@ -18,7 +18,7 @@ class CORE_EXPORT OptionListIterator final {
public:
explicit OptionListIterator(const HTMLSelectElement* select)
- : select_(select) {
+ : select_(select), current_(nullptr) {
if (select_)
Advance(nullptr);
}
@@ -37,8 +37,8 @@ class CORE_EXPORT OptionListIterator final {
private:
void Advance(HTMLOptionElement* current);
- Member<const HTMLSelectElement> select_;
- Member<HTMLOptionElement> current_; // nullptr means we reached to the end.
+ const HTMLSelectElement* select_;
+ HTMLOptionElement* current_; // nullptr means we reached to the end.
};
// OptionList class is a lightweight version of HTMLOptionsCollection.
@@ -46,13 +46,13 @@ class OptionList final {
STACK_ALLOCATED();
public:
- explicit OptionList(const HTMLSelectElement& select) : select_(select) {}
+ explicit OptionList(const HTMLSelectElement& select) : select_(&select) {}
using Iterator = OptionListIterator;
Iterator begin() { return Iterator(select_); }
Iterator end() { return Iterator(nullptr); }
private:
- Member<const HTMLSelectElement> select_;
+ const HTMLSelectElement* select_;
};
} // namespace blink
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 863b8eb67c4..71941a49f9e 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
@@ -41,12 +41,12 @@ TEST_F(OptionListTest, Empty) {
}
TEST_F(OptionListTest, OptionOnly) {
- Select().SetInnerHTMLFromString(
+ Select().setInnerHTML(
"text<input><option id=o1></option><input><option "
"id=o2></option><input>");
auto* div = To<HTMLElement>(
Select().GetDocument().CreateRawElement(html_names::kDivTag));
- div->SetInnerHTMLFromString("<option id=o3></option>");
+ div->setInnerHTML("<option id=o3></option>");
Select().AppendChild(div);
OptionList list = Select().GetOptionList();
OptionList::Iterator iter = list.begin();
@@ -59,7 +59,7 @@ TEST_F(OptionListTest, OptionOnly) {
}
TEST_F(OptionListTest, Optgroup) {
- Select().SetInnerHTMLFromString(
+ Select().setInnerHTML(
"<optgroup><option id=g11></option><option id=g12></option></optgroup>"
"<optgroup><option id=g21></option></optgroup>"
"<optgroup></optgroup>"
@@ -80,7 +80,7 @@ TEST_F(OptionListTest, Optgroup) {
EXPECT_EQ(list.end(), iter);
To<HTMLElement>(Select().firstChild())
- ->SetInnerHTMLFromString(
+ ->setInnerHTML(
"<optgroup><option id=gg11></option></optgroup>"
"<option id=g11></option>");
list = Select().GetOptionList();
diff --git a/chromium/third_party/blink/renderer/core/html/forms/password_input_type_test.cc b/chromium/third_party/blink/renderer/core/html/forms/password_input_type_test.cc
index 0f8b2d17211..9dc42a72620 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/password_input_type_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/password_input_type_test.cc
@@ -51,10 +51,9 @@ class MockInsecureInputService : public mojom::blink::InsecureInputService {
TEST(PasswordInputTypeTest, DidEditFieldEvent) {
auto page_holder = std::make_unique<DummyPageHolder>(IntSize(2000, 2000));
MockInsecureInputService mock_service(page_holder->GetFrame());
- page_holder->GetDocument().body()->SetInnerHTMLFromString(
- "<input type='password'>");
+ page_holder->GetDocument().body()->setInnerHTML("<input type='password'>");
page_holder->GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
blink::test::RunPendingTasks();
EXPECT_EQ(0u, mock_service.DidEditFieldCalls());
// Simulate a text field edit.
@@ -77,12 +76,11 @@ TEST(PasswordInputTypeTest, DidEditFieldEventNotSentFromSecureContext) {
nullptr /* extra_data */);
blink::test::RunPendingTasks();
MockInsecureInputService mock_service(page_holder->GetFrame());
- page_holder->GetDocument().SetSecureContextStateForTesting(
- SecureContextState::kSecure);
- page_holder->GetDocument().body()->SetInnerHTMLFromString(
- "<input type='password'>");
+ page_holder->GetDocument().SetSecureContextModeForTesting(
+ SecureContextMode::kSecureContext);
+ page_holder->GetDocument().body()->setInnerHTML("<input type='password'>");
page_holder->GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
// Simulate a text field edit.
page_holder->GetDocument().MaybeQueueSendDidEditFieldInInsecureContext();
// No message should have been sent from a secure context.
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 544b8a6b204..50036ddb04b 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
@@ -40,6 +40,7 @@
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/platform/text/platform_locale.h"
#include "third_party/blink/renderer/platform/web_test_support.h"
+#include "ui/base/ui_base_features.h"
namespace blink {
@@ -59,7 +60,7 @@ PickerIndicatorElement::~PickerIndicatorElement() {
LayoutObject* PickerIndicatorElement::CreateLayoutObject(
const ComputedStyle& style,
LegacyLayout legacy) {
- if (RuntimeEnabledFeatures::FormControlsRefreshEnabled())
+ if (features::IsFormControlsRefreshEnabled())
return HTMLDivElement::CreateLayoutObject(style, legacy);
return new LayoutDetailsMarker(this);
@@ -72,12 +73,12 @@ void PickerIndicatorElement::DefaultEventHandler(Event& event) {
picker_indicator_owner_->IsPickerIndicatorOwnerDisabledOrReadOnly())
return;
+ auto* keyboard_event = DynamicTo<KeyboardEvent>(event);
if (event.type() == event_type_names::kClick) {
OpenPopup();
event.SetDefaultHandled();
- } else if (event.type() == event_type_names::kKeypress &&
- event.IsKeyboardEvent()) {
- int char_code = ToKeyboardEvent(event).charCode();
+ } else if (event.type() == event_type_names::kKeypress && keyboard_event) {
+ int char_code = keyboard_event->charCode();
if (char_code == ' ' || char_code == '\r') {
OpenPopup();
event.SetDefaultHandled();
@@ -109,10 +110,16 @@ void PickerIndicatorElement::DidChooseValue(double value) {
void PickerIndicatorElement::DidEndChooser() {
chooser_.Clear();
+ picker_indicator_owner_->DidEndChooser();
+ if (::features::IsFormControlsRefreshEnabled() &&
+ OwnerElement().GetLayoutObject()) {
+ // Invalidate paint to ensure that the focus ring is shown.
+ OwnerElement().GetLayoutObject()->SetShouldDoFullPaintInvalidation();
+ }
}
void PickerIndicatorElement::OpenPopup() {
- if (chooser_)
+ if (HasOpenedPopup())
return;
if (!GetDocument().GetPage())
return;
@@ -123,6 +130,11 @@ void PickerIndicatorElement::OpenPopup() {
return;
chooser_ = GetDocument().GetPage()->GetChromeClient().OpenDateTimeChooser(
GetDocument().GetFrame(), this, parameters);
+ if (::features::IsFormControlsRefreshEnabled() &&
+ OwnerElement().GetLayoutObject()) {
+ // Invalidate paint to ensure that the focus ring is removed.
+ OwnerElement().GetLayoutObject()->SetShouldDoFullPaintInvalidation();
+ }
}
Element& PickerIndicatorElement::OwnerElement() const {
@@ -136,6 +148,10 @@ void PickerIndicatorElement::ClosePopup() {
chooser_->EndChooser();
}
+bool PickerIndicatorElement::HasOpenedPopup() const {
+ return chooser_;
+}
+
void PickerIndicatorElement::DetachLayoutTree(bool performing_reattach) {
ClosePopup();
HTMLDivElement::DetachLayoutTree(performing_reattach);
@@ -160,7 +176,8 @@ void PickerIndicatorElement::DidNotifySubtreeInsertionsToDocument() {
return;
// Don't make this focusable if we are in web tests in order to avoid
// breaking existing tests.
- // FIXME: We should have a way to disable accessibility in web tests.
+ // TODO(crbug.com/1054048): We should have a way to disable accessibility in
+ // web tests. Once we do have it, this early return should be removed.
if (WebTestSupport::IsRunningWebTest())
return;
setAttribute(html_names::kTabindexAttr, "0");
@@ -168,7 +185,8 @@ void PickerIndicatorElement::DidNotifySubtreeInsertionsToDocument() {
setAttribute(html_names::kRoleAttr, "button");
setAttribute(
html_names::kAriaLabelAttr,
- AtomicString(GetLocale().QueryString(IDS_AX_CALENDAR_SHOW_DATE_PICKER)));
+ AtomicString(
+ this->picker_indicator_owner_->AriaRoleForPickerIndicator()));
}
void PickerIndicatorElement::Trace(Visitor* 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 df33806c889..4aa8b3237f8 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
@@ -37,8 +37,6 @@
namespace blink {
-class HTMLInputElement;
-
class PickerIndicatorElement final : public HTMLDivElement,
public DateTimeChooserClient {
USING_GARBAGE_COLLECTED_MIXIN(PickerIndicatorElement);
@@ -55,6 +53,8 @@ class PickerIndicatorElement final : public HTMLDivElement,
virtual void PickerIndicatorChooseValue(double) = 0;
virtual Element& PickerOwnerElement() const = 0;
virtual bool SetupDateTimeChooserParameters(DateTimeChooserParameters&) = 0;
+ virtual void DidEndChooser() = 0;
+ virtual String AriaRoleForPickerIndicator() const = 0;
};
PickerIndicatorElement(Document&, PickerIndicatorOwner&);
@@ -63,6 +63,7 @@ class PickerIndicatorElement final : public HTMLDivElement,
void OpenPopup();
void ClosePopup();
+ bool HasOpenedPopup() const;
bool WillRespondToMouseClickEvents() override;
void RemovePickerIndicatorOwner() { picker_indicator_owner_ = nullptr; }
AXObject* PopupRootAXObject() const;
@@ -81,17 +82,16 @@ class PickerIndicatorElement final : public HTMLDivElement,
InsertionNotificationRequest InsertedInto(ContainerNode&) override;
void DidNotifySubtreeInsertionsToDocument() override;
- HTMLInputElement* HostInput();
-
Member<PickerIndicatorOwner> picker_indicator_owner_;
Member<DateTimeChooser> chooser_;
};
-DEFINE_TYPE_CASTS(PickerIndicatorElement,
- Element,
- element,
- element->IsPickerIndicatorElement(),
- element.IsPickerIndicatorElement());
+template <>
+struct DowncastTraits<PickerIndicatorElement> {
+ static bool AllowFrom(const Element& element) {
+ return element.IsPickerIndicatorElement();
+ }
+};
} // namespace blink
#endif
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 08db5400d8b..9191f0d96a3 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
@@ -201,8 +201,6 @@ void RadioButtonGroup::Trace(Visitor* visitor) {
// RadioButtonGroup in the header.
RadioButtonGroupScope::RadioButtonGroupScope() = default;
-RadioButtonGroupScope::~RadioButtonGroupScope() = default;
-
void RadioButtonGroupScope::AddButton(HTMLInputElement* element) {
DCHECK_EQ(element->type(), input_type_names::kRadio);
if (element->GetName().IsEmpty())
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 11399c9d004..a6ba8d9f217 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,6 @@ class RadioButtonGroupScope {
public:
RadioButtonGroupScope();
- ~RadioButtonGroupScope();
void Trace(Visitor*);
void AddButton(HTMLInputElement*);
void UpdateCheckedState(HTMLInputElement*);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/radio_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/radio_input_type.cc
index 5b69b334e22..c3846016db6 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/radio_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/radio_input_type.cc
@@ -21,6 +21,7 @@
#include "third_party/blink/renderer/core/html/forms/radio_input_type.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/public/strings/grit/blink_strings.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
@@ -56,8 +57,33 @@ const AtomicString& RadioInputType::FormControlType() const {
}
bool RadioInputType::ValueMissing(const String&) const {
- return GetElement().IsInRequiredRadioButtonGroup() &&
- !GetElement().CheckedRadioButtonForGroup();
+ HTMLInputElement& input = GetElement();
+ if (auto* scope = input.GetRadioButtonGroupScope())
+ return scope->IsInRequiredGroup(&input) && !CheckedRadioButtonForGroup();
+
+ // This element is not managed by a RadioButtonGroupScope. We need to traverse
+ // the tree from TreeRoot.
+ DCHECK(!input.isConnected());
+ DCHECK(!input.formOwner());
+ const AtomicString& name = input.GetName();
+ if (name.IsEmpty())
+ return false;
+ bool is_required = false;
+ bool is_checked = false;
+ Node& root = input.TreeRoot();
+ for (auto* another = Traversal<HTMLInputElement>::InclusiveFirstWithin(root);
+ another; another = Traversal<HTMLInputElement>::Next(*another, &root)) {
+ if (another->type() != input_type_names::kRadio ||
+ another->GetName() != name || another->formOwner())
+ continue;
+ if (another->checked())
+ is_checked = true;
+ if (another->FastHasAttribute(html_names::kRequiredAttr))
+ is_required = true;
+ if (is_checked && is_required)
+ return false;
+ }
+ return is_required && !is_checked;
}
String RadioInputType::ValueMissingText() const {
@@ -110,7 +136,7 @@ void RadioInputType::HandleKeydownEvent(KeyboardEvent& event) {
: (key == "ArrowDown" || key == "ArrowRight");
// Force layout for isFocusable() in findNextFocusableRadioButtonInGroup().
- document.UpdateStyleAndLayout();
+ document.UpdateStyleAndLayout(DocumentUpdateReason::kInput);
// We can only stay within the form's children if the form hasn't been demoted
// to a leaf because of malformed HTML.
@@ -128,9 +154,9 @@ void RadioInputType::HandleKeydownEvent(KeyboardEvent& event) {
}
}
if (input_element) {
- document.SetFocusedElement(input_element,
- FocusParams(SelectionBehaviorOnFocus::kRestore,
- kWebFocusTypeNone, nullptr));
+ document.SetFocusedElement(
+ input_element, FocusParams(SelectionBehaviorOnFocus::kRestore,
+ mojom::blink::FocusType::kNone, nullptr));
input_element->DispatchSimulatedClick(&event, kSendNoEvents);
event.SetDefaultHandled();
return;
@@ -175,7 +201,7 @@ bool RadioInputType::IsKeyboardFocusable() const {
// Allow keyboard focus if we're checked or if nothing in the group is
// checked.
- return GetElement().checked() || !GetElement().CheckedRadioButtonForGroup();
+ return GetElement().checked() || !CheckedRadioButtonForGroup();
}
bool RadioInputType::ShouldSendChangeEventAfterCheckedChanged() {
@@ -197,7 +223,7 @@ ClickHandlingState* RadioInputType::WillDispatchClick() {
ClickHandlingState* state = MakeGarbageCollected<ClickHandlingState>();
state->checked = GetElement().checked();
- state->checked_radio_button = GetElement().CheckedRadioButtonForGroup();
+ state->checked_radio_button = CheckedRadioButtonForGroup();
GetElement().setChecked(true, TextFieldEventBehavior::kDispatchChangeEvent);
is_in_click_handler_ = true;
return state;
@@ -225,7 +251,7 @@ void RadioInputType::DidDispatchClick(Event& event,
}
bool RadioInputType::ShouldAppearIndeterminate() const {
- return !GetElement().CheckedRadioButtonForGroup();
+ return !CheckedRadioButtonForGroup();
}
HTMLInputElement* RadioInputType::NextRadioButtonInGroup(
@@ -247,4 +273,42 @@ HTMLInputElement* RadioInputType::NextRadioButtonInGroup(
return nullptr;
}
+HTMLInputElement* RadioInputType::CheckedRadioButtonForGroup() const {
+ HTMLInputElement& input = GetElement();
+ if (input.checked())
+ return &input;
+ if (auto* scope = input.GetRadioButtonGroupScope())
+ return scope->CheckedButtonForGroup(input.GetName());
+
+ // This element is not managed by a RadioButtonGroupScope. We need to traverse
+ // the tree from TreeRoot.
+ DCHECK(!input.isConnected());
+ DCHECK(!input.formOwner());
+ const AtomicString& name = input.GetName();
+ if (name.IsEmpty())
+ return nullptr;
+ Node& root = input.TreeRoot();
+ for (auto* another = Traversal<HTMLInputElement>::InclusiveFirstWithin(root);
+ another; another = Traversal<HTMLInputElement>::Next(*another, &root)) {
+ if (another->type() != input_type_names::kRadio ||
+ another->GetName() != name || another->formOwner())
+ continue;
+ if (another->checked())
+ return another;
+ }
+ return nullptr;
+}
+
+void RadioInputType::WillUpdateCheckedness(bool new_checked) {
+ if (!new_checked)
+ return;
+ if (GetElement().GetRadioButtonGroupScope()) {
+ // Buttons in RadioButtonGroupScope are handled in
+ // HTMLInputElement::setChecked().
+ return;
+ }
+ if (auto* input = CheckedRadioButtonForGroup())
+ input->setChecked(false);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/forms/radio_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/radio_input_type.h
index 5c0b43d43cb..f3050550000 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/radio_input_type.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/radio_input_type.h
@@ -46,6 +46,7 @@ class RadioInputType final : public BaseCheckableInputType {
private:
void CountUsage() override;
const AtomicString& FormControlType() const override;
+ void WillUpdateCheckedness(bool new_checked) override;
bool ValueMissing(const String&) const override;
String ValueMissingText() const override;
void HandleClickEvent(MouseEvent&) override;
@@ -59,6 +60,7 @@ class RadioInputType final : public BaseCheckableInputType {
HTMLInputElement* FindNextFocusableRadioButtonInGroup(HTMLInputElement*,
bool);
+ HTMLInputElement* CheckedRadioButtonForGroup() const;
};
} // namespace blink
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 fe1eb05d751..0eed4825627 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
@@ -144,8 +144,8 @@ StepRange RangeInputType::CreateStepRange(
// minimum/maximum.
// https://html.spec.whatwg.org/C/#range-state-(type=range):concept-input-min-default
const bool kHasRangeLimitations = true;
- return StepRange(step_base, minimum, maximum, kHasRangeLimitations, step,
- step_description);
+ return StepRange(step_base, minimum, maximum, kHasRangeLimitations,
+ /*has_reversed_range=*/false, step, step_description);
}
bool RangeInputType::IsSteppable() const {
@@ -185,7 +185,7 @@ void RangeInputType::HandleKeydownEvent(KeyboardEvent& event) {
// FIXME: We can't use stepUp() for the step value "any". So, we increase
// or decrease the value by 1/100 of the value range. Is it reasonable?
const Decimal step =
- DeprecatedEqualIgnoringCase(
+ EqualIgnoringASCIICase(
GetElement().FastGetAttribute(html_names::kStepAttr), "any")
? (step_range.Maximum() - step_range.Minimum()) / 100
: step_range.Step();
@@ -253,6 +253,10 @@ void RangeInputType::CreateShadowSubtree() {
GetElement().UserAgentShadowRoot()->AppendChild(container);
}
+bool RangeInputType::TypeShouldForceLegacyLayout() const {
+ return true;
+}
+
LayoutObject* RangeInputType::CreateLayoutObject(const ComputedStyle&,
LegacyLayout) const {
return new LayoutSlider(&GetElement());
@@ -314,10 +318,7 @@ void RangeInputType::WarnIfValueIsInvalid(const String& value) const {
if (value.IsEmpty() || !GetElement().SanitizeValue(value).IsEmpty())
return;
AddWarningToConsole(
- "The specified value %s is not a valid number. The value must match to "
- "the following regular expression: "
- "-?(\\d+|\\d+\\.\\d+|\\.\\d+)([eE][-+]?\\d+)?",
- value);
+ "The specified value %s cannot be parsed, or is out of range.", value);
}
void RangeInputType::DisabledAttributeChanged() {
@@ -419,4 +420,8 @@ void RangeInputType::ValueAttributeChanged() {
UpdateView();
}
+bool RangeInputType::IsDraggedSlider() const {
+ return GetSliderThumbElement()->IsActive();
+}
+
} // namespace blink
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 b4da9bce5a0..013379890dc 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
@@ -63,6 +63,7 @@ class RangeInputType final : public InputType, public InputTypeView {
bool IsSteppable() const override;
void HandleMouseDownEvent(MouseEvent&) override;
void HandleKeydownEvent(KeyboardEvent&) override;
+ bool TypeShouldForceLegacyLayout() const override;
LayoutObject* CreateLayoutObject(const ComputedStyle&,
LegacyLayout) const override;
void CreateShadowSubtree() override;
@@ -86,6 +87,7 @@ class RangeInputType final : public InputType, public InputTypeView {
// InputTypeView function:
void UpdateView() override;
void ValueAttributeChanged() override;
+ bool IsDraggedSlider() const override;
bool tick_mark_values_dirty_;
Vector<Decimal> tick_mark_values_;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/PRESUBMIT.py b/chromium/third_party/blink/renderer/core/html/forms/resources/PRESUBMIT.py
index f28465828fa..26b84f5fb5d 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/resources/PRESUBMIT.py
+++ b/chromium/third_party/blink/renderer/core/html/forms/resources/PRESUBMIT.py
@@ -2,13 +2,15 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+
def _CheckChangeOnUploadOrCommit(input_api, output_api):
- return input_api.canned_checks.CheckPatchFormatted(input_api, output_api,
- check_js=True)
+ return input_api.canned_checks.CheckPatchFormatted(
+ input_api, output_api, check_js=True)
+
def CheckChangeOnUpload(input_api, output_api):
- return _CheckChangeOnUploadOrCommit(input_api, output_api)
+ return _CheckChangeOnUploadOrCommit(input_api, output_api)
def CheckChangeOnCommit(input_api, output_api):
- return _CheckChangeOnUploadOrCommit(input_api, output_api)
+ return _CheckChangeOnUploadOrCommit(input_api, output_api)
diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/calendarPicker.js b/chromium/third_party/blink/renderer/core/html/forms/resources/calendarPicker.js
index d89a990d557..6380d4631f4 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/resources/calendarPicker.js
+++ b/chromium/third_party/blink/renderer/core/html/forms/resources/calendarPicker.js
@@ -59,6 +59,7 @@ var global = {
],
isLocaleRTL: false,
isFormControlsRefreshEnabled: false,
+ isBorderTransparent: false,
mode: 'date',
isAMPMFirst: false,
hasAMPM: false,
@@ -304,6 +305,40 @@ Day.prototype.next = function(offset) {
};
/**
+ * Given that 'this' is the Nth day of the month, returns the Nth
+ * day of the month that is specified by the parameter.
+ * Clips the date if necessary, e.g. if 'this' Day is October 31st and
+ * the parameter is a November, returns November 30th.
+ * @param {!Month} month
+ * @return {!Day}
+ */
+Day.prototype.thisRangeInMonth = function(month) {
+ var newDate = month.startDate();
+ var originalMonthInt = newDate.getUTCMonth();
+ newDate.setUTCDate(this.date);
+ if (newDate.getUTCMonth() != originalMonthInt) {
+ newDate.setUTCDate(0);
+ }
+ return Day.createFromDate(newDate);
+};
+
+/**
+ * @param {!Month} month
+ * @return {!boolean}
+ */
+Day.prototype.overlapsMonth = function(month) {
+ return (month.firstDay() <= this && month.lastDay() >= this);
+};
+
+/**
+ * @param {!Month} month
+ * @return {!boolean}
+ */
+Day.prototype.isFullyContainedInMonth = function(month) {
+ return (month.firstDay() <= this && month.lastDay() >= this);
+};
+
+/**
* @return {!Date}
*/
Day.prototype.startDate = function() {
@@ -569,6 +604,65 @@ Week.prototype.next = function(offset) {
};
/**
+ * Given that 'this' is the Nth week of the month, returns
+ * the Week that is the Nth week in the month specified
+ * by the parameter.
+ * Clips the date if necessary, e.g. if 'this' is the 5th week
+ * of a month that has 5 weeks and the parameter month only has
+ * 4 weeks, returns the 4th week of that month.
+ * @param {!Month} month
+ * @return {!Week}
+ */
+Week.prototype.thisRangeInMonth = function(month) {
+ var firstDateInCurrentMonth = this.startDate();
+ firstDateInCurrentMonth.setUTCDate(1);
+
+ var offsetInOriginalMonth =
+ Week._numberOfWeeksSinceDate(firstDateInCurrentMonth, this.startDate());
+
+ // Determine the first Monday in the new month (the week control shows weeks
+ // starting on Monday).
+ var firstWeekStartInNewMonth = month.startDate();
+ firstWeekStartInNewMonth.setUTCDate(
+ 1 +
+ ((DaysPerWeek + 1 - firstWeekStartInNewMonth.getUTCDay()) % DaysPerWeek));
+
+
+ // Find the Nth Monday in the month where N == offsetInOriginalMonth.
+ firstWeekStartInNewMonth.setUTCDate(
+ firstWeekStartInNewMonth.getUTCDate() +
+ (DaysPerWeek * offsetInOriginalMonth));
+
+ if (firstWeekStartInNewMonth.getUTCMonth() != month.month) {
+ // If we overshot into the next month (can happen if we were
+ // on the 5th week of the old month), go back to the last week
+ // of the target month.
+ firstWeekStartInNewMonth.setUTCDate(
+ firstWeekStartInNewMonth.getUTCDate() - DaysPerWeek);
+ }
+
+ return Week.createFromDate(firstWeekStartInNewMonth);
+};
+
+/**
+ * @param {!Month} month
+ * @return {!boolean}
+ */
+Week.prototype.overlapsMonth = function(month) {
+ return (
+ month.firstDay() <= this.lastDay() && month.lastDay() >= this.firstDay());
+};
+
+/**
+ * @param {!Month} month
+ * @return {!boolean}
+ */
+Week.prototype.isFullyContainedInMonth = function(month) {
+ return (
+ month.firstDay() <= this.firstDay() && month.lastDay() >= this.lastDay());
+};
+
+/**
* @return {!Date}
*/
Week.prototype.startDate = function() {
@@ -706,13 +800,6 @@ Month.createFromToday = function() {
};
/**
- * @return {!boolean}
- */
-Month.prototype.containsDay = function(day) {
- return this.year === day.year && this.month === day.month;
-};
-
-/**
* @param {!Month} other
* @return {!boolean}
*/
@@ -768,7 +855,7 @@ Month.prototype.firstDay = function() {
* @return {!Day}
*/
Month.prototype.middleDay = function() {
- return new Day(this.year, this.month, this.month === 2 ? 14 : 15);
+ return new Day(this.year, this.month, this.month === 1 ? 14 : 15);
};
/**
@@ -1666,10 +1753,17 @@ ListCell.prototype.setSelected = function(selected) {
if (this._selected === selected)
return;
this._selected = selected;
- if (this._selected)
+ if (this._selected) {
this.element.classList.add('selected');
- else
+ if (global.params.isFormControlsRefreshEnabled) {
+ this.element.setAttribute('aria-selected', true);
+ }
+ } else {
this.element.classList.remove('selected');
+ if (global.params.isFormControlsRefreshEnabled) {
+ this.element.setAttribute('aria-selected', false);
+ }
+ }
};
/**
@@ -1782,7 +1876,18 @@ ListView.prototype.addCellIfNecessary = function(row) {
if (cell)
return cell;
cell = this.prepareNewCell(row);
- cell.attachTo(this.scrollView.contentElement);
+
+ // Ensure that the DOM tree positions of the rows are in increasing
+ // chronological order. This is needed for correct application of
+ // the :hover selector for the week control, which spans across multiple
+ // calendar rows.
+ var rowIndices = Object.keys(this._cells);
+ var shouldPrepend = (rowIndices.length) > 0 && (row < rowIndices[0]);
+ cell.attachTo(
+ this.scrollView.contentElement,
+ shouldPrepend ? this.scrollView.contentElement.firstElementChild :
+ undefined);
+
cell.setWidth(this._width);
cell.setPosition(this.scrollView.contentPositionForContentOffset(
this.scrollOffsetForRow(row)));
@@ -2160,6 +2265,133 @@ ScrubbyScrollBar.prototype.onScrollTimer = function() {
this.scrollView.scrollBy(scrollAmount, false);
};
+// Mixin containing utilities for identifying and navigating between
+// valid day/week/month ranges.
+var DateRangeManager = {
+ _setValidDateConfig(config) {
+ this.config = {};
+
+ this.config.minimum = (typeof config.min !== 'undefined' && config.min) ?
+ parseDateString(config.min) :
+ this._dateTypeConstructor.Minimum;
+ this.config.maximum = (typeof config.max !== 'undefined' && config.max) ?
+ parseDateString(config.max) :
+ this._dateTypeConstructor.Maximum;
+ this.config.minimumValue = this.config.minimum.valueOf();
+ this.config.maximumValue = this.config.maximum.valueOf();
+ this.config.step = (typeof config.step !== 'undefined') ?
+ Number(config.step) :
+ this._dateTypeConstructor.DefaultStep;
+ this.config.stepBase = (typeof config.stepBase !== 'undefined') ?
+ Number(config.stepBase) :
+ this._dateTypeConstructor.DefaultStepBase;
+ },
+
+ _isValidForStep(value) {
+ // nextAllowedValue is the time closest (looking forward) to value that is
+ // within the interval specified by the step and the stepBase. This may
+ // be equal to value.
+ var nextAllowedValue =
+ (Math.ceil((value - this.config.stepBase) / this.config.step) *
+ this.config.step) +
+ this.config.stepBase;
+ // If the nextAllowedValue is between value and the next nearest possible time
+ // for this control type (determined by adding the smallest time interval, given
+ // by DefaultStep, to value) then we consider it to be valid.
+ return nextAllowedValue < (value + this._dateTypeConstructor.DefaultStep);
+ },
+
+ /**
+ * @param {!number} value
+ * @return {!boolean}
+ */
+ _outOfRange(value) {
+ return value < this.config.minimumValue || value > this.config.maximumValue;
+ },
+
+ /**
+ * @param {!DateType} dayOrWeekOrMonth
+ * @return {!boolean}
+ */
+ isValid(dayOrWeekOrMonth) {
+ var value = dayOrWeekOrMonth.valueOf();
+ return dayOrWeekOrMonth instanceof this._dateTypeConstructor &&
+ !this._outOfRange(value) && this._isValidForStep(value);
+ },
+
+ /**
+ * @param {!DayOrWeekOrMonth} dayOrWeekOrMonth
+ * @return {?DayOrWeekOrMonth}
+ */
+ getNearestValidRangeLookingForward(dayOrWeekOrMonth) {
+ if (dayOrWeekOrMonth < this.config.minimumValue) {
+ // Performance optimization: avoid wasting lots of time in the below
+ // loop if dayOrWeekOrMonth is significantly less than the min.
+ dayOrWeekOrMonth =
+ this._dateTypeConstructor.createFromValue(this.config.minimumValue);
+ }
+
+ while (!this.isValid(dayOrWeekOrMonth) &&
+ dayOrWeekOrMonth < this.config.maximumValue) {
+ dayOrWeekOrMonth = dayOrWeekOrMonth.next();
+ }
+
+ return this.isValid(dayOrWeekOrMonth) ? dayOrWeekOrMonth : null;
+ },
+
+ /**
+ * @param {!DayOrWeekOrMonth} dayOrWeekOrMonth
+ * @return {?DayOrWeekOrMonth}
+ */
+ getNearestValidRangeLookingBackward(dayOrWeekOrMonth) {
+ if (dayOrWeekOrMonth > this.config.maximumValue) {
+ // Performance optimization: avoid wasting lots of time in the below
+ // loop if dayOrWeekOrMonth is significantly greater than the max.
+ dayOrWeekOrMonth =
+ this._dateTypeConstructor.createFromValue(this.config.maximumValue);
+ }
+
+ while (!this.isValid(dayOrWeekOrMonth) &&
+ dayOrWeekOrMonth > this.config.minimumValue) {
+ dayOrWeekOrMonth = dayOrWeekOrMonth.previous();
+ }
+
+ return this.isValid(dayOrWeekOrMonth) ? dayOrWeekOrMonth : null;
+ },
+
+ /**
+ * @param {!DayOrWeekOrMonth} dayOrWeekOrMonth
+ * @param {!boolean} lookForwardFirst
+ * @return {?DayOrWeekOrMonth}
+ */
+ getNearestValidRange(dayOrWeekOrMonth, lookForwardFirst) {
+ var result = null;
+ if (lookForwardFirst) {
+ if (!(result =
+ this.getNearestValidRangeLookingForward(dayOrWeekOrMonth))) {
+ result = this.getNearestValidRangeLookingBackward(dayOrWeekOrMonth);
+ }
+ } else {
+ if (!(result =
+ this.getNearestValidRangeLookingBackward(dayOrWeekOrMonth))) {
+ result = this.getNearestValidRangeLookingForward(dayOrWeekOrMonth);
+ }
+ }
+
+ return result;
+ },
+
+ /**
+ * @param {!Day} day
+ * @param {!boolean} lookForwardFirst
+ * @return {?DayOrWeekOrMonth}
+ */
+ getValidRangeNearestToDay(day, lookForwardFirst) {
+ var dayOrWeekOrMonth = this._dateTypeConstructor.createFromDay(day);
+ return this.getNearestValidRange(dayOrWeekOrMonth, lookForwardFirst);
+ }
+};
+
/**
* @constructor
* @extends ListCell
@@ -2294,14 +2526,16 @@ YearListCell.prototype.setHeight = function(height) {
* @param {!Month} minimumMonth
* @param {!Month} maximumMonth
*/
-function YearListView(minimumMonth, maximumMonth) {
+function YearListView(minimumMonth, maximumMonth, config) {
ListView.call(this);
this.element.classList.add('year-list-view');
/**
* @type {?Month}
*/
- this.highlightedMonth = null;
+ if (!global.params.isFormControlsRefreshEnabled) {
+ this.highlightedMonth = null;
+ }
/**
* @type {?Month}
*/
@@ -2350,13 +2584,50 @@ function YearListView(minimumMonth, maximumMonth) {
this.scrubbyScrollBar = new ScrubbyScrollBar(this.scrollView);
this.scrubbyScrollBar.attachTo(this);
- this.element.addEventListener('mouseover', this.onMouseOver, false);
- this.element.addEventListener('mouseout', this.onMouseOut, false);
this.element.addEventListener('keydown', this.onKeyDown, false);
- this.element.addEventListener('touchstart', this.onTouchStart, false);
+ if (!global.params.isFormControlsRefreshEnabled) {
+ this.element.addEventListener('mouseover', this.onMouseOver, false);
+ this.element.addEventListener('mouseout', this.onMouseOut, false);
+ this.element.addEventListener('touchstart', this.onTouchStart, false);
+ }
+
+ if (global.params.isFormControlsRefreshEnabled && config &&
+ config.mode == 'month') {
+ this.type = 'month';
+ this._dateTypeConstructor = Month;
+
+ this._setValidDateConfig(config);
+
+ this._hadValidValueWhenOpened = false;
+ var initialSelection = parseDateString(config.currentValue);
+ if (initialSelection) {
+ this._hadValidValueWhenOpened = this.isValid(initialSelection);
+ this._selectedMonth = this.getNearestValidRange(
+ initialSelection, /*lookForwardFirst*/ true);
+ } else {
+ // Ensure that the next month closest to today is selected to start with so that
+ // the user can simply submit the popup to choose it.
+ this._selectedMonth = this.getValidRangeNearestToDay(
+ this._dateTypeConstructor.createFromToday(),
+ /*lookForwardFirst*/ true);
+ }
+
+ this._initialSelectedMonth = this._selectedMonth;
+ } else if (global.params.isFormControlsRefreshEnabled) {
+ // This is a month switcher menu embedded in another calendar control.
+ // Set up our config so that getNearestValidRangeLookingForward(Backward)
+ // when called on this YearListView will navigate by month.
+ this.config = {};
+ this.config.minimumValue = minimumMonth;
+ this.config.maximumValue = maximumMonth;
+ this.config.step = Month.DefaultStep;
+ this.config.stepBase = Month.DefaultStepBase;
+ this._dateTypeConstructor = Month;
+ }
}
YearListView.prototype = Object.create(ListView.prototype);
+Object.assign(YearListView.prototype, DateRangeManager);
YearListView._Height = YearListCell._SelectedHeight - 1;
YearListView._VisibleYearsRefresh = 4;
@@ -2504,9 +2775,11 @@ YearListView.prototype.onClick = function(event) {
if (this.selectedRow !== oldSelectedRow) {
// Always start with first month when changing the year.
const month = new Month(year, 0);
- this.highlightMonth(month);
- this.dispatchEvent(
- YearListView.EventTypeYearListViewDidSelectMonth, this, month);
+ if (!global.params.isFormControlsRefreshEnabled) {
+ this.highlightMonth(month);
+ this.dispatchEvent(
+ YearListView.EventTypeYearListViewDidSelectMonth, this, month);
+ }
this.scrollView.scrollTo(this.selectedRow * YearListCell.GetHeight(), true);
} else {
var monthButton = enclosingNodeOrSelfWithClass(
@@ -2517,7 +2790,9 @@ YearListView.prototype.onClick = function(event) {
this.dispatchEvent(
YearListView.EventTypeYearListViewDidSelectMonth, this,
new Month(year, month));
- this.hide();
+ if (!global.params.isFormControlsRefreshEnabled) {
+ this.hide();
+ }
}
};
@@ -2588,13 +2863,20 @@ YearListView.prototype.prepareNewCell = function(row) {
for (var i = 0; i < cell.monthButtons.length; ++i) {
var month = new Month(row + 1, i);
cell.monthButtons[i].id = month.toString();
- cell.monthButtons[i].setAttribute(
- 'aria-disabled',
- this._minimumMonth > month || this._maximumMonth < month ? 'true' :
- 'false');
+ if (global.params.isFormControlsRefreshEnabled && this.type === 'month') {
+ cell.monthButtons[i].setAttribute(
+ 'aria-disabled', this.isValid(month) ? 'false' : 'true');
+ } else {
+ cell.monthButtons[i].setAttribute(
+ 'aria-disabled',
+ this._minimumMonth > month || this._maximumMonth < month ? 'true' :
+ 'false');
+ }
cell.monthButtons[i].setAttribute('aria-label', month.toLocaleString());
+ cell.monthButtons[i].setAttribute('aria-selected', false);
}
- if (this.highlightedMonth && row === this.highlightedMonth.year - 1) {
+ if (!global.params.isFormControlsRefreshEnabled && this.highlightedMonth &&
+ row === this.highlightedMonth.year - 1) {
var monthButton = cell.monthButtons[this.highlightedMonth.month];
monthButton.classList.add(YearListCell.ClassNameHighlighted);
// aria-activedescendant assumes both elements have layoutObjects, and
@@ -2607,6 +2889,10 @@ YearListView.prototype.prepareNewCell = function(row) {
if (this._selectedMonth && (this._selectedMonth.year - 1) === row) {
var monthButton = cell.monthButtons[this._selectedMonth.month];
monthButton.classList.add(YearListCell.ClassNameSelected);
+ if (global.params.isFormControlsRefreshEnabled) {
+ this.element.setAttribute('aria-activedescendant', monthButton.id);
+ monthButton.setAttribute('aria-selected', true);
+ }
}
const todayMonth = Month.createFromToday();
if ((todayMonth.year - 1) === row) {
@@ -2691,8 +2977,10 @@ YearListView.prototype.select = function(row) {
this.selectedRow, YearListView.RowAnimationDirection.Opening);
if (selectedCell)
selectedCell.setSelected(true);
- var month = this.highlightedMonth ? this.highlightedMonth.month : 0;
- this.highlightMonth(new Month(this.selectedRow + 1, month));
+ if (!global.params.isFormControlsRefreshEnabled) {
+ var month = this.highlightedMonth ? this.highlightedMonth.month : 0;
+ this.highlightMonth(new Month(this.selectedRow + 1, month));
+ }
}
this.setNeedsUpdateCells(true);
};
@@ -2713,8 +3001,6 @@ YearListView.prototype.selectWithoutAnimating = function(row) {
selectedCell.setSelected(true);
selectedCell.setHeight(YearListCell.GetSelectedHeight());
}
- var month = this.highlightedMonth ? this.highlightedMonth.month : 0;
- this.highlightMonth(new Month(this.selectedRow + 1, month));
}
this.setNeedsUpdateCells(true);
};
@@ -2762,7 +3048,29 @@ YearListView.prototype.highlightMonth = function(month) {
};
YearListView.prototype.setSelectedMonth = function(month) {
+
+ var oldMonthButton = this.buttonForMonth(this._selectedMonth);
+ if (oldMonthButton) {
+ oldMonthButton.classList.remove(YearListCell.ClassNameSelected);
+ oldMonthButton.setAttribute('aria-selected', false);
+ }
+
this._selectedMonth = month;
+
+ var newMonthButton = this.buttonForMonth(this._selectedMonth);
+ if (newMonthButton) {
+ newMonthButton.classList.add(YearListCell.ClassNameSelected);
+ this.element.setAttribute('aria-activedescendant', newMonthButton.id);
+ newMonthButton.setAttribute('aria-selected', true);
+ }
+};
+
+YearListView.prototype.setSelectedMonthAndUpdateView = function(month) {
+ this.setSelectedMonth(month);
+
+ this.select(this._selectedMonth.year - 1);
+
+ this.scrollView.scrollTo(this.selectedRow * YearListCell.GetHeight(), true);
};
YearListView.prototype.showSelectedMonth = function() {
@@ -2780,7 +3088,9 @@ YearListView.prototype.show = function(month) {
this.scrollToRow(month.year - 1, false);
this.selectWithoutAnimating(month.year - 1);
- this.highlightMonth(month);
+ if (!global.params.isFormControlsRefreshEnabled) {
+ this.highlightMonth(month);
+ }
this.showSelectedMonth();
};
@@ -2795,8 +3105,11 @@ YearListView.prototype._moveHighlightTo = function(month) {
this.highlightMonth(month);
this.select(this.highlightedMonth.year - 1);
- this.dispatchEvent(
- YearListView.EventTypeYearListViewDidSelectMonth, this, month);
+ if (!global.params.isFormControlsRefreshEnabled) {
+ this.dispatchEvent(
+ YearListView.EventTypeYearListViewDidSelectMonth, this, month);
+ }
+
this.scrollView.scrollTo(this.selectedRow * YearListCell.GetHeight(), true);
return true;
};
@@ -2807,9 +3120,66 @@ YearListView.prototype._moveHighlightTo = function(month) {
YearListView.prototype.onKeyDown = function(event) {
var key = event.key;
var eventHandled = false;
- if (key == 't')
- eventHandled = this._moveHighlightTo(Month.createFromToday());
- else if (this.highlightedMonth) {
+ if (key == 't') {
+ if (!global.params.isFormControlsRefreshEnabled) {
+ eventHandled = this._moveHighlightTo(Month.createFromToday());
+ if (global.params.isFormControlsRefreshEnabled) {
+ this.dispatchEvent(
+ YearListView.EventTypeYearListViewDidSelectMonth, this,
+ this.highlightedMonth);
+ }
+ }
+ } else if (
+ global.params.isFormControlsRefreshEnabled && this._selectedMonth) {
+ if (global.params.isLocaleRTL ? key == 'ArrowRight' : key == 'ArrowLeft') {
+ var newSelection = this.getNearestValidRangeLookingBackward(
+ this._selectedMonth.previous());
+ if (newSelection) {
+ this.setSelectedMonthAndUpdateView(newSelection);
+ }
+ } else if (key == 'ArrowUp') {
+ var newSelection = this.getNearestValidRangeLookingBackward(
+ this._selectedMonth.previous(YearListCell.ButtonColumns));
+ if (newSelection) {
+ this.setSelectedMonthAndUpdateView(newSelection);
+ }
+ } else if (
+ global.params.isLocaleRTL ? key == 'ArrowLeft' : key == 'ArrowRight') {
+ var newSelection =
+ this.getNearestValidRangeLookingForward(this._selectedMonth.next());
+ if (newSelection) {
+ this.setSelectedMonthAndUpdateView(newSelection);
+ }
+ } else if (key == 'ArrowDown') {
+ var newSelection = this.getNearestValidRangeLookingForward(
+ this._selectedMonth.next(YearListCell.ButtonColumns));
+ if (newSelection) {
+ this.setSelectedMonthAndUpdateView(newSelection);
+ }
+ } else if (key == 'PageUp') {
+ var newSelection = this.getNearestValidRangeLookingBackward(
+ this._selectedMonth.previous(MonthsPerYear));
+ if (newSelection) {
+ this.setSelectedMonthAndUpdateView(newSelection);
+ }
+ } else if (key == 'PageDown') {
+ var newSelection = this.getNearestValidRangeLookingForward(
+ this._selectedMonth.next(MonthsPerYear));
+ if (newSelection) {
+ this.setSelectedMonthAndUpdateView(newSelection);
+ }
+ } else if (this.type !== 'month') {
+ if (key == 'Enter') {
+ this.dispatchEvent(
+ YearListView.EventTypeYearListViewDidSelectMonth, this,
+ this._selectedMonth);
+ } else if (key == 'Escape') {
+ this.hide();
+ eventHandled = true;
+ }
+ }
+ } else if (
+ !global.params.isFormControlsRefreshEnabled && this.highlightedMonth) {
if (global.params.isLocaleRTL ? key == 'ArrowRight' : key == 'ArrowLeft')
eventHandled = this._moveHighlightTo(this.highlightedMonth.previous());
else if (key == 'ArrowUp')
@@ -2884,7 +3254,15 @@ MonthPopupView.ClassNameMonthPopupView = 'month-popup-view';
MonthPopupView.prototype.show = function(initialMonth, calendarTableRect) {
this.isVisible = true;
- document.body.appendChild(this.element);
+ if (global.params.isFormControlsRefreshEnabled &&
+ global.params.mode == 'datetime-local') {
+ // Place the month popup under the datetimelocal-picker element so that the
+ // datetimelocal-picker element receives its keyboard and click events.
+ // For other calendar control types, these events are handled via the body element.
+ document.querySelector('datetimelocal-picker').appendChild(this.element);
+ } else {
+ document.body.appendChild(this.element);
+ }
this.yearListView.setWidth(calendarTableRect.width - 2);
this.yearListView.setHeight(YearListView.GetHeight());
if (global.params.isLocaleRTL)
@@ -3194,12 +3572,17 @@ CalendarHeaderView.prototype = Object.create(View.prototype);
CalendarHeaderView.Height = 24;
CalendarHeaderView.BottomMargin = 10;
+CalendarHeaderView.ClassNameCalendarNavigationButtonIconRefresh =
+ 'today-button-icon-refresh';
CalendarHeaderView._ForwardTriangle =
'<svg width=\'4\' height=\'7\'><polygon points=\'0,7 0,0, 4,3.5\' style=\'fill:#6e6e6e;\' /></svg>';
-CalendarHeaderView._ForwardTriangleRefresh =
- '<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\
- <path d=\"M15.3516 8.60156L8 15.9531L0.648438 8.60156L1.35156 7.89844L7.5 14.0469V0H8.5V14.0469L14.6484 7.89844L15.3516 8.60156Z\" fill=\"#101010\"/>\
- </svg>'
+CalendarHeaderView._ForwardTriangleRefresh = `<svg class="${
+ CalendarHeaderView
+ .ClassNameCalendarNavigationButtonIconRefresh}" width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <path class="${
+ CalendarHeaderView
+ .ClassNameCalendarNavigationButtonIconRefresh}" d="M15.3516 8.60156L8 15.9531L0.648438 8.60156L1.35156 7.89844L7.5 14.0469V0H8.5V14.0469L14.6484 7.89844L15.3516 8.60156Z" fill="#101010"/>
+ </svg>`;
CalendarHeaderView.GetForwardTriangle = function() {
if (global.params.isFormControlsRefreshEnabled) {
return CalendarHeaderView._ForwardTriangleRefresh;
@@ -3208,10 +3591,13 @@ CalendarHeaderView.GetForwardTriangle = function() {
};
CalendarHeaderView._BackwardTriangle =
'<svg width=\'4\' height=\'7\'><polygon points=\'0,3.5 4,7 4,0\' style=\'fill:#6e6e6e;\' /></svg>';
-CalendarHeaderView._BackwardTriangleRefresh =
- '<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\
- <path d=\"M14.6484 8.10156L8.5 1.95312V16H7.5V1.95312L1.35156 8.10156L0.648438 7.39844L8 0.046875L15.3516 7.39844L14.6484 8.10156Z\" fill=\"#101010\"/>\
- </svg>'
+CalendarHeaderView._BackwardTriangleRefresh = `<svg class="${
+ CalendarHeaderView
+ .ClassNameCalendarNavigationButtonIconRefresh}" width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <path class="${
+ CalendarHeaderView
+ .ClassNameCalendarNavigationButtonIconRefresh}" d="M14.6484 8.10156L8.5 1.95312V16H7.5V1.95312L1.35156 8.10156L0.648438 7.39844L8 0.046875L15.3516 7.39844L14.6484 8.10156Z" fill="#101010"/>
+ </svg>`;
CalendarHeaderView.GetBackwardTriangle = function() {
if (global.params.isFormControlsRefreshEnabled) {
return CalendarHeaderView._BackwardTriangleRefresh;
@@ -3240,15 +3626,17 @@ CalendarHeaderView.prototype.onCurrentMonthChanged = function() {
};
CalendarHeaderView.prototype.onNavigationButtonClick = function(sender) {
- if (sender === this._previousMonthButton)
+ if (sender === this._previousMonthButton) {
this.calendarPicker.setCurrentMonth(
this.calendarPicker.currentMonth().previous(),
CalendarPicker.NavigationBehavior.WithAnimation);
- else if (sender === this._nextMonthButton)
+ this.calendarPicker.ensureSelectionIsWithinCurrentMonth();
+ } else if (sender === this._nextMonthButton) {
this.calendarPicker.setCurrentMonth(
this.calendarPicker.currentMonth().next(),
CalendarPicker.NavigationBehavior.WithAnimation);
- else
+ this.calendarPicker.ensureSelectionIsWithinCurrentMonth();
+ } else
this.calendarPicker.selectRangeContainingDay(Day.createFromToday());
};
@@ -3536,6 +3924,7 @@ CalendarTableHeaderView.GetHeight = function() {
*/
function CalendarRowCell() {
ListCell.call(this);
+
this.element.classList.add(CalendarRowCell.ClassNameCalendarRowCell);
this.element.style.height = CalendarRowCell.GetHeight() + 'px';
this.element.setAttribute('role', 'row');
@@ -3678,8 +4067,10 @@ function CalendarTableView(calendarPicker) {
this._ignoreMouseOutUntillNextMouseOver = false;
this.element.addEventListener('click', this.onClick, false);
- this.element.addEventListener('mouseover', this.onMouseOver, false);
- this.element.addEventListener('mouseout', this.onMouseOut, false);
+ if (!global.params.isFormControlsRefreshEnabled) {
+ this.element.addEventListener('mouseover', this.onMouseOver, false);
+ this.element.addEventListener('mouseout', this.onMouseOut, false);
+ }
// You shouldn't be able to use the mouse wheel to scroll.
this.scrollView.element.removeEventListener(
@@ -3891,16 +4282,23 @@ CalendarTableView.prototype.updateCells = function() {
var dayCell = this._dayCells[dayString];
var day = dayCell.day;
dayCell.setIsToday(Day.createFromToday().equals(day));
- dayCell.setSelected(
- day >= firstDayInSelection && day <= lastDayInSelection);
- var isHighlighted = day >= firstDayInHighlight && day <= lastDayInHighlight;
- dayCell.setHighlighted(isHighlighted);
- if (isHighlighted) {
- if (firstDayInHighlight == lastDayInHighlight)
- activeCell = dayCell;
- else if (
- this.calendarPicker.type == 'month' && day == firstDayInHighlight)
+ var isSelected = (day >= firstDayInSelection && day <= lastDayInSelection);
+ dayCell.setSelected(isSelected);
+ if (global.params.isFormControlsRefreshEnabled) {
+ if (isSelected && firstDayInSelection == lastDayInSelection) {
activeCell = dayCell;
+ }
+ } else {
+ var isHighlighted =
+ day >= firstDayInHighlight && day <= lastDayInHighlight;
+ dayCell.setHighlighted(isHighlighted);
+ if (isHighlighted) {
+ if (firstDayInHighlight == lastDayInHighlight)
+ activeCell = dayCell;
+ else if (
+ this.calendarPicker.type == 'month' && day == firstDayInHighlight)
+ activeCell = dayCell;
+ }
}
dayCell.setIsInCurrentMonth(
day >= firstDayInCurrentMonth && day <= lastDayInCurrentMonth);
@@ -3910,11 +4308,18 @@ CalendarTableView.prototype.updateCells = function() {
for (var weekString in this._weekNumberCells) {
var weekNumberCell = this._weekNumberCells[weekString];
var week = weekNumberCell.week;
- var isWeekHighlighted = highlight && highlight.equals(week);
- weekNumberCell.setSelected(selection && selection.equals(week));
- weekNumberCell.setHighlighted(isWeekHighlighted);
- if (isWeekHighlighted)
- activeCell = weekNumberCell;
+ var isSelected = (selection && selection.equals(week));
+ weekNumberCell.setSelected(isSelected);
+ if (global.params.isFormControlsRefreshEnabled) {
+ if (isSelected) {
+ activeCell = weekNumberCell;
+ }
+ } else {
+ var isWeekHighlighted = highlight && highlight.equals(week);
+ weekNumberCell.setHighlighted(isWeekHighlighted);
+ if (isWeekHighlighted)
+ activeCell = weekNumberCell;
+ }
weekNumberCell.setDisabled(!this.calendarPicker.isValid(week));
}
}
@@ -3976,7 +4381,9 @@ CalendarTableView.prototype.throwAwayWeekNumberCell = function(weekNumberCell) {
function CalendarPicker(type, config) {
View.call(this, createElement('div', CalendarPicker.ClassNameCalendarPicker));
this.element.classList.add(CalendarPicker.ClassNamePreparing);
-
+ if (global.params.isBorderTransparent) {
+ this.element.style.borderColor = 'transparent';
+ }
/**
* @type {!string}
* @const
@@ -3988,12 +4395,13 @@ function CalendarPicker(type, config) {
this._dateTypeConstructor = Month;
else
this._dateTypeConstructor = Day;
- /**
- * @type {!Object}
- * @const
- */
- this.config = {};
- this._setConfig(config);
+
+ this._setValidDateConfig(config);
+
+ if (global.params.isFormControlsRefreshEnabled && this.type === 'week') {
+ this.element.classList.add(CalendarPicker.ClassNameWeekPicker);
+ }
+
/**
* @type {!Month}
* @const
@@ -4042,15 +4450,26 @@ function CalendarPicker(type, config) {
* @protected
*/
this._selection = null;
+
/**
* @type {?DateType}
* @protected
*/
- this._highlight = null;
+ if (!global.params.isFormControlsRefreshEnabled) {
+ this._highlight = null;
+ }
+
this.calendarTableView.element.addEventListener(
- 'keydown', this.onCalendarTableKeyDown, false);
+ 'keydown',
+ global.params.isFormControlsRefreshEnabled ?
+ this.onCalendarTableKeyDownRefresh :
+ this.onCalendarTableKeyDown,
+ false);
+
+ document.body.addEventListener('click', this.onBodyClick, false);
document.body.addEventListener('keydown', this.onBodyKeyDown, false);
+
window.addEventListener('resize', this.onWindowResize, false);
/**
@@ -4059,22 +4478,48 @@ function CalendarPicker(type, config) {
*/
this._height = -1;
+ this._hadValidValueWhenOpened = false;
+
var initialSelection = parseDateString(config.currentValue);
if (initialSelection) {
this.setCurrentMonth(
Month.createFromDay(initialSelection.middleDay()),
CalendarPicker.NavigationBehavior.None);
- this.setSelection(initialSelection);
- } else
+
+ if (global.params.isFormControlsRefreshEnabled) {
+ this._hadValidValueWhenOpened = this.isValid(initialSelection);
+ this.setSelection(this.getNearestValidRange(
+ initialSelection, /*lookForwardFirst*/ true));
+ } else {
+ this.setSelection(initialSelection);
+ }
+ } else {
this.setCurrentMonth(
Month.createFromToday(), CalendarPicker.NavigationBehavior.None);
+
+ if (global.params.isFormControlsRefreshEnabled) {
+ // Ensure that the next date closest to today is selected to start with so that
+ // the user can simply submit the popup to choose it.
+ this.setSelection(this.getValidRangeNearestToDay(
+ this._dateTypeConstructor.createFromToday(),
+ /*lookForwardFirst*/ true));
+ }
+ }
+
+ /**
+ * @type {?DateType}
+ * @protected
+ */
+ this._initialSelection = this._selection;
}
CalendarPicker.prototype = Object.create(View.prototype);
+Object.assign(CalendarPicker.prototype, DateRangeManager);
CalendarPicker.Padding = 10;
CalendarPicker.BorderWidth = 1;
CalendarPicker.ClassNameCalendarPicker = 'calendar-picker';
+CalendarPicker.ClassNameWeekPicker = 'week-picker';
CalendarPicker.ClassNamePreparing = 'preparing';
CalendarPicker.EventTypeCurrentMonthChanged = 'currentMonthChanged';
CalendarPicker.commitDelayMs = 100;
@@ -4088,6 +4533,10 @@ CalendarPicker.prototype.onWindowResize = function(event) {
window.removeEventListener('resize', this.onWindowResize, false);
};
+CalendarPicker.prototype.resetToInitialValue = function() {
+ this.setSelection(this._initialSelection);
+};
+
/**
* @param {!YearListView} sender
*/
@@ -4096,6 +4545,7 @@ CalendarPicker.prototype.onYearListViewDidHide = function(sender) {
this.calendarHeaderView.setDisabled(false);
if (global.params.isFormControlsRefreshEnabled) {
this.calendarTableView.element.style.visibility = 'visible';
+ this.calendarTableView.element.focus();
} else {
this.adjustHeight();
}
@@ -4108,6 +4558,11 @@ CalendarPicker.prototype.onYearListViewDidHide = function(sender) {
CalendarPicker.prototype.onYearListViewDidSelectMonth = function(
sender, month) {
this.setCurrentMonth(month, CalendarPicker.NavigationBehavior.None);
+
+ if (global.params.isFormControlsRefreshEnabled) {
+ this.ensureSelectionIsWithinCurrentMonth();
+ this.onYearListViewDidHide();
+ }
};
/**
@@ -4146,23 +4601,6 @@ CalendarPicker.prototype.onMonthPopupButtonClick = function(sender) {
}
};
-CalendarPicker.prototype._setConfig = function(config) {
- this.config.minimum = (typeof config.min !== 'undefined' && config.min) ?
- parseDateString(config.min) :
- this._dateTypeConstructor.Minimum;
- this.config.maximum = (typeof config.max !== 'undefined' && config.max) ?
- parseDateString(config.max) :
- this._dateTypeConstructor.Maximum;
- this.config.minimumValue = this.config.minimum.valueOf();
- this.config.maximumValue = this.config.maximum.valueOf();
- this.config.step = (typeof config.step !== undefined) ?
- Number(config.step) :
- this._dateTypeConstructor.DefaultStep;
- this.config.stepBase = (typeof config.stepBase !== 'undefined') ?
- Number(config.stepBase) :
- this._dateTypeConstructor.DefaultStepBase;
-};
-
/**
* @return {!Month}
*/
@@ -4289,6 +4727,13 @@ CalendarPicker.prototype.setSelection = function(dayOrWeekOrMonth) {
return;
if (this._selection && this._selection.equals(dayOrWeekOrMonth))
return;
+ if (this._selection && !dayOrWeekOrMonth) {
+ this._selection = null;
+ if (!global.params.isFormControlsRefreshEnabled) {
+ this._setHighlight(null);
+ }
+ return;
+ }
var firstDayInSelection = dayOrWeekOrMonth.firstDay();
var lastDayInSelection = dayOrWeekOrMonth.lastDay();
var candidateCurrentMonth = Month.createFromDay(firstDayInSelection);
@@ -4320,7 +4765,9 @@ CalendarPicker.prototype.setSelection = function(dayOrWeekOrMonth) {
candidateCurrentMonth,
CalendarPicker.NavigationBehavior.WithAnimation);
}
- this._setHighlight(dayOrWeekOrMonth);
+ if (!global.params.isFormControlsRefreshEnabled) {
+ this._setHighlight(dayOrWeekOrMonth);
+ }
if (!this.isValid(dayOrWeekOrMonth))
return;
this._selection = dayOrWeekOrMonth;
@@ -4377,41 +4824,84 @@ CalendarPicker.prototype._setHighlight = function(dayOrWeekOrMonth) {
};
/**
- * @param {!number} value
+ * @param {!Day} day
* @return {!boolean}
*/
-CalendarPicker.prototype._stepMismatch = function(value) {
- var nextAllowedValue =
- Math.ceil((value - this.config.stepBase) / this.config.step) *
- this.config.step +
- this.config.stepBase;
- return nextAllowedValue >= value + this._dateTypeConstructor.DefaultStep;
+CalendarPicker.prototype.isValidDay = function(day) {
+ return this.isValid(this._dateTypeConstructor.createFromDay(day));
};
/**
- * @param {!number} value
- * @return {!boolean}
+ * If the selection is not inside the month currently shown in the control,
+ * adjust the selection so that it is within the current month.
+ * The new selection value is determined in the following manner:
+ * 1) If the old selection is on the Nth day of the month, try to place it
+ * on the Nth day of the new month.
+ * 2) If the Nth day of the new month is not valid, choose the closest
+ * valid date that is within the new month.
+ * 3) If the next and previous valid date are equidistant and both within
+ * the new month, arbitrarily choose the older date.
*/
-CalendarPicker.prototype._outOfRange = function(value) {
- return value < this.config.minimumValue || value > this.config.maximumValue;
-};
+CalendarPicker.prototype.ensureSelectionIsWithinCurrentMonth = function() {
+ if (!this._selection)
+ return;
+ if (this._selection.isFullyContainedInMonth(this.currentMonth()))
+ return;
-/**
- * @param {!DateType} dayOrWeekOrMonth
- * @return {!boolean}
- */
-CalendarPicker.prototype.isValid = function(dayOrWeekOrMonth) {
- var value = dayOrWeekOrMonth.valueOf();
- return dayOrWeekOrMonth instanceof this._dateTypeConstructor &&
- !this._outOfRange(value) && !this._stepMismatch(value);
-};
+ var newSelection = null;
+ var currentRangeInNewMonth =
+ this._selection.thisRangeInMonth(this.currentMonth());
-/**
- * @param {!Day} day
- * @return {!boolean}
- */
-CalendarPicker.prototype.isValidDay = function(day) {
- return this.isValid(this._dateTypeConstructor.createFromDay(day));
+ if (this.isValid(currentRangeInNewMonth)) {
+ newSelection = currentRangeInNewMonth;
+ } else {
+ var validRangeLookingBackward =
+ this.getNearestValidRangeLookingBackward(currentRangeInNewMonth);
+ var validRangeLookingForward =
+ this.getNearestValidRangeLookingForward(currentRangeInNewMonth);
+ if (validRangeLookingBackward && validRangeLookingForward) {
+ var newMonthIsForwardOfSelection =
+ (currentRangeInNewMonth.firstDay() > this._selection.firstDay());
+ var [validRangeInDirectionOfAdvancement, validRangeAgainstDirectionOfAdvancement] =
+ newMonthIsForwardOfSelection ?
+ [validRangeLookingForward, validRangeLookingBackward] :
+ [validRangeLookingBackward, validRangeLookingForward];
+
+ if (!validRangeAgainstDirectionOfAdvancement.overlapsMonth(
+ this.currentMonth())) {
+ // If the range going against our direction of movement is not
+ // entirely within the new month, go with the range in the
+ // other direction to ensure we that we don't backtrack.
+ newSelection = validRangeInDirectionOfAdvancement;
+ } else if (!validRangeInDirectionOfAdvancement.overlapsMonth(
+ this.currentMonth())) {
+ newSelection = validRangeAgainstDirectionOfAdvancement;
+ } else {
+ // If both of the ranges are in the new month, select the closest one
+ // to the target date in the new month.
+ var diffFromForwardRange = Math.abs(
+ currentRangeInNewMonth.valueOf() -
+ validRangeLookingForward.valueOf());
+ var diffFromBackwardRange = Math.abs(
+ currentRangeInNewMonth.valueOf() -
+ validRangeLookingBackward.valueOf());
+ if (diffFromForwardRange < diffFromBackwardRange) {
+ newSelection = validRangeLookingForward;
+ } else { // In a tie, arbitrarily choose older date
+ newSelection = validRangeLookingBackward;
+ }
+ }
+ } else if (!validRangeLookingForward) {
+ newSelection = validRangeLookingBackward;
+ } else { // !validRangeLookingBackward
+ newSelection = validRangeLookingForward;
+ } // No additional clause because they can't both be null; we have a
+ // selection so there's at least one valid date.
+ }
+
+ if (newSelection) {
+ this.setSelection(newSelection);
+ }
};
/**
@@ -4435,9 +4925,79 @@ CalendarPicker.prototype._moveHighlight = function(dateRange) {
/**
* @param {?Event} event
*/
+CalendarPicker.prototype.onCalendarTableKeyDownRefresh = function(event) {
+ var key = event.key;
+ var offset = 0;
+
+ if (!event.target.matches('.today-button-refresh') && this._selection) {
+ switch (key) {
+ case 'PageUp':
+ var previousMonth = this.currentMonth().previous();
+ if (previousMonth && previousMonth >= this.config.minimumValue) {
+ this.setCurrentMonth(
+ previousMonth, CalendarPicker.NavigationBehavior.WithAnimation);
+ this.ensureSelectionIsWithinCurrentMonth();
+ }
+ break;
+ case 'PageDown':
+ var nextMonth = this.currentMonth().next();
+ if (nextMonth && nextMonth >= this.config.minimumValue) {
+ this.setCurrentMonth(
+ nextMonth, CalendarPicker.NavigationBehavior.WithAnimation);
+ this.ensureSelectionIsWithinCurrentMonth();
+ }
+ break;
+ case 'ArrowUp':
+ case 'ArrowDown':
+ case 'ArrowLeft':
+ case 'ArrowRight':
+ var upOrDownArrowStepSize =
+ this.type === 'date' || this.type === 'datetime-local' ?
+ DaysPerWeek :
+ 1;
+ if (global.params.isLocaleRTL ? key == 'ArrowRight' :
+ key == 'ArrowLeft') {
+ var newSelection = this.getNearestValidRangeLookingBackward(
+ this._selection.previous());
+ if (newSelection) {
+ this.setSelection(newSelection);
+ }
+ } else if (key == 'ArrowUp') {
+ var newSelection = this.getNearestValidRangeLookingBackward(
+ this._selection.previous(upOrDownArrowStepSize));
+ if (newSelection) {
+ this.setSelection(newSelection);
+ }
+ } else if (
+ global.params.isLocaleRTL ? key == 'ArrowLeft' :
+ key == 'ArrowRight') {
+ var newSelection =
+ this.getNearestValidRangeLookingForward(this._selection.next());
+ if (newSelection) {
+ this.setSelection(newSelection);
+ }
+ } else if (key == 'ArrowDown') {
+ var newSelection = this.getNearestValidRangeLookingForward(
+ this._selection.next(upOrDownArrowStepSize));
+ if (newSelection) {
+ this.setSelection(newSelection);
+ }
+ }
+ break;
+ };
+ }
+ // else if there is no selection it must be the case that there are no
+ // valid values (because min >= max). Otherwise we would have set the selection
+ // during initialization. In this case there's nothing to do.
+};
+
+/**
+ * @param {?Event} event
+ */
CalendarPicker.prototype.onCalendarTableKeyDown = function(event) {
var key = event.key;
var eventHandled = false;
+
if (key == 't') {
this.selectRangeContainingDay(Day.createFromToday());
eventHandled = true;
@@ -4456,19 +5016,20 @@ CalendarPicker.prototype.onCalendarTableKeyDown = function(event) {
eventHandled = true;
}
} else if (this._highlight) {
+ var upOrDownArrowStepSize =
+ this.type === 'date' || this.type === 'datetime-local' ? DaysPerWeek :
+ 1;
if (global.params.isLocaleRTL ? key == 'ArrowRight' : key == 'ArrowLeft') {
eventHandled = this._moveHighlight(this._highlight.previous());
} else if (key == 'ArrowUp') {
- eventHandled = this._moveHighlight(this._highlight.previous(
- this.type === 'date' || this.type === 'datetime-local' ? DaysPerWeek :
- 1));
+ eventHandled =
+ this._moveHighlight(this._highlight.previous(upOrDownArrowStepSize));
} else if (
global.params.isLocaleRTL ? key == 'ArrowLeft' : key == 'ArrowRight') {
eventHandled = this._moveHighlight(this._highlight.next());
} else if (key == 'ArrowDown') {
- eventHandled = this._moveHighlight(this._highlight.next(
- this.type === 'date' || this.type === 'datetime-local' ? DaysPerWeek :
- 1));
+ eventHandled =
+ this._moveHighlight(this._highlight.next(upOrDownArrowStepSize));
} else if (key == 'Enter') {
this.setSelectionAndCommit(this._highlight);
}
@@ -4520,42 +5081,115 @@ CalendarPicker.prototype.setHeight = function(height) {
/**
* @param {?Event} event
*/
+CalendarPicker.prototype.onBodyClick = function(event) {
+ if (global.params.isFormControlsRefreshEnabled &&
+ this.type !== 'datetime-local') {
+ if (event.target.matches(
+ '.calendar-navigation-button, .today-button-icon-refresh, .month-button')) {
+ window.pagePopupController.setValue(this.getSelectedValue());
+ }
+ }
+};
+
+/**
+ * @param {?Event} event
+ */
CalendarPicker.prototype.onBodyKeyDown = function(event) {
var key = event.key;
var eventHandled = false;
var offset = 0;
switch (key) {
case 'Escape':
- window.pagePopupController.closePopup();
- eventHandled = true;
+ // The datetime-local control handles submission/cancellation at
+ // the top level, so if we're in a datetime-local let event bubble
+ // up instead of handling it here.
+ if (global.params.isFormControlsRefreshEnabled) {
+ if (this.type !== 'datetime-local') {
+ if (!this._selection ||
+ (this._selection.equals(this._initialSelection))) {
+ window.pagePopupController.closePopup();
+ } else {
+ this.resetToInitialValue();
+ window.pagePopupController.setValue(
+ this._hadValidValueWhenOpened ?
+ this._initialSelection.toString() :
+ '');
+ }
+ }
+ } else {
+ window.pagePopupController.closePopup();
+ eventHandled = true;
+ }
+ break;
+ case 'ArrowUp':
+ case 'ArrowDown':
+ case 'ArrowLeft':
+ case 'ArrowRight':
+ case 'PageUp':
+ case 'PageDown':
+ if (global.params.isFormControlsRefreshEnabled &&
+ this.type !== 'datetime-local' &&
+ event.target.matches('.calendar-table-view') && this._selection) {
+ window.pagePopupController.setValue(this.getSelectedValue());
+ }
+ break;
+ case 'Enter':
+ // Submit the popup for an Enter keypress except when the user is
+ // hitting Enter to activate the month switcher button, Today button,
+ // or previous/next month arrows.
+ if (global.params.isFormControlsRefreshEnabled &&
+ this.type !== 'datetime-local') {
+ if (!event.target.matches(
+ '.calendar-navigation-button, .month-popup-button, .year-list-view')) {
+ if (this._selection) {
+ window.pagePopupController.setValueAndClosePopup(
+ 0, this.getSelectedValue());
+ } else {
+ // If there is no selection it must be the case that there are no
+ // valid values (because min >= max). There's nothing useful to do
+ // with the popup in this case so just close on Enter.
+ window.pagePopupController.closePopup();
+ }
+ } else if (event.target.matches(
+ '.calendar-navigation-button, .year-list-view')) {
+ // Navigating with the previous/next arrows may change selection,
+ // so push this change to the in-page control but don't
+ // close the popup.
+ window.pagePopupController.setValue(this.getSelectedValue());
+ }
+ }
break;
case 'm':
case 'M':
- offset = offset || 1; // Fall-through.
+ offset = offset || 1;
+ // Fall-through.
case 'y':
case 'Y':
- offset = offset || MonthsPerYear; // Fall-through.
+ offset = offset || MonthsPerYear;
+ // Fall-through.
case 'd':
case 'D':
- offset = offset || MonthsPerYear * 10;
- var oldFirstVisibleRow =
- this.calendarTableView
- .columnAndRowForDay(this.currentMonth().firstDay())
- .row;
- this.setCurrentMonth(
- event.shiftKey ? this.currentMonth().previous(offset) :
- this.currentMonth().next(offset),
- CalendarPicker.NavigationBehavior.WithAnimation);
- var newFirstVisibleRow =
- this.calendarTableView
- .columnAndRowForDay(this.currentMonth().firstDay())
- .row;
- if (this._highlight) {
- var highlightMiddleDay = this._highlight.middleDay();
- this.highlightRangeContainingDay(highlightMiddleDay.next(
- (newFirstVisibleRow - oldFirstVisibleRow) * DaysPerWeek));
+ if (!global.params.isFormControlsRefreshEnabled) {
+ offset = offset || MonthsPerYear * 10;
+ var oldFirstVisibleRow =
+ this.calendarTableView
+ .columnAndRowForDay(this.currentMonth().firstDay())
+ .row;
+ this.setCurrentMonth(
+ event.shiftKey ? this.currentMonth().previous(offset) :
+ this.currentMonth().next(offset),
+ CalendarPicker.NavigationBehavior.WithAnimation);
+ var newFirstVisibleRow =
+ this.calendarTableView
+ .columnAndRowForDay(this.currentMonth().firstDay())
+ .row;
+ if (this._highlight) {
+ var highlightMiddleDay = this._highlight.middleDay();
+ this.highlightRangeContainingDay(highlightMiddleDay.next(
+ (newFirstVisibleRow - oldFirstVisibleRow) * DaysPerWeek));
+ }
+ eventHandled = true;
}
- eventHandled = true;
break;
}
if (eventHandled) {
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 7ba4b2ba739..69a6fc615e6 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
@@ -4,7 +4,7 @@
*/
body {
- font: 12px sans-serif;
+ font-size: 12px;
}
.calendar-picker {
@@ -41,7 +41,7 @@ body {
}
.calendar-navigation-button:hover {
- background-color: #E5E5E5;
+ background-color: rgba(0, 117, 255, 0.3);
}
.calendar-navigation-button:disabled {
@@ -92,7 +92,7 @@ body {
border: 1px solid transparent !important;
border-radius: 2px;
color: #767676;
- padding: 1px;
+ padding: 1px !important;
text-align: center;
}
@@ -100,31 +100,61 @@ body {
color: #101010;
}
-.day-cell.highlighted,
-.month-button.highlighted,
-.week-number-cell.highlighted {
- background-color: #E5E5E5;
+.week-number-cell,
+.day-cell {
+ transition: color 0s;
+}
+
+/*
+* Highlight-when-hovered for cells in the month picker menu and standalone
+* month control
+*/
+.month-button:hover {
+ background-color: rgba(0, 117, 255, 0.3);
+}
+
+/*
+* Highlight-when-hovered for day cells except if this is a week picker
+*/
+:not(.week-picker) > .calendar-table-view > .scroll-view > .scroll-view-content
+ > .calendar-row-cell > .day-cell:not(.selected):hover {
+ background-color: rgba(0, 117, 255, 0.3);
+}
+
+/*
+* Highlight-when-hovered for week picker, in 3 parts:
+* 1. Highlight all cells in the hovered row except for Monday, because it
+* belongs to the previous week.
+* 2. Highlight Monday of the row after the hovered row, because it belongs to
+* this week
+* 3. Highlight the week number cell for the hovered week
+*/
+.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(0, 117, 255, 0.3);
}
.day-cell.selected,
.month-button.selected,
.week-number-cell.selected {
- background-color: #CECECE;
+ background-color: #0075FF;
+ color: #FFFFFF;
font-weight: bold;
}
-.day-cell.highlighted.today,
-.day-cell.today,
-.month-button.today {
- background-color: #6E6E6E;
- border: 0;
- color: #FFFFFF;
- font-weight: bold;
+.calendar-table-view:focus .day-cell.selected,
+.year-list-view:focus .month-button.selected,
+.calendar-table-view:focus .week-number-cell.selected {
+ outline: solid 2px -webkit-focus-ring-color;
+ outline-offset: -2px;
}
-.day-cell.selected.today,
-.month-button.selected.today {
- border: 2px solid #CECECE !important;
+.day-cell.today,
+.month-button.today {
+ border-color: #767676 !important;
}
.day-cell.disabled,
@@ -148,7 +178,7 @@ body {
}
.today-button-refresh:hover {
- background-color: #E5E5E5;
+ background-color: rgba(0, 117, 255, 0.3);
}
.today-button-refresh:disabled {
@@ -255,11 +285,39 @@ body {
color: WindowText;
}
- .day-cell.highlighted,
- .month-button.highlighted,
- .week-number-cell.highlighted {
- background-color: Window;
+ /*
+ * Highlight-when-hovered for cells in the month picker menu and standalone
+ * month control
+ */
+ .month-button:not(.selected):hover {
+ background-color: Window !important;
+ border-color: Highlight !important;
+ }
+
+ /*
+ * Highlight-when-hovered for day cells except if this is a week picker
+ */
+ :not(.week-picker) > .calendar-table-view > .scroll-view > .scroll-view-content
+ > .calendar-row-cell > .day-cell:not(.selected):hover {
+ background-color: Window !important;
+ border-color: Highlight !important;
+ }
+
+ /*
+ * Highlight-when-hovered for week picker, in 3 parts:
+ * 1. Highlight all cells in the hovered row except for Monday, because it
+ * belongs to the previous week.
+ * 2. Highlight Monday of the row after the hovered row, because it belongs to
+ * this week
+ * 3. Highlight the week number cell for the hovered week
+ */
+ .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) {
border-color: Highlight !important;
+ background-color: Window !important;
}
.day-cell.selected,
@@ -269,17 +327,15 @@ body {
color: Window;
}
- .day-cell.highlighted.today,
- .day-cell.today,
- .month-button.today {
- background-color: Highlight;
- border: 2px solid Window !important;
- color: Window;
+ .calendar-table-view:focus .day-cell.selected,
+ .year-list-view:focus .month-button.selected,
+ .calendar-table-view:focus .week-number-cell.selected {
+ outline: none;
}
- .day-cell.selected.today,
- .month-button.selected.today {
- border: 1px solid Window !important;
+ .day-cell.today,
+ .month-button.today {
+ border-color: WindowText !important;
}
.day-cell.disabled,
diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/colorSuggestionPicker.css b/chromium/third_party/blink/renderer/core/html/forms/resources/colorSuggestionPicker.css
index dfa50b795cb..5c7e7d331d9 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/resources/colorSuggestionPicker.css
+++ b/chromium/third_party/blink/renderer/core/html/forms/resources/colorSuggestionPicker.css
@@ -53,7 +53,7 @@ body.controls-refresh {
}
.controls-refresh .color-suggestion-picker-main {
- border: 0;
+ border: 1px solid #bfbfbf;
box-shadow: none;
padding: 8px 8px 4px 8px;
}
@@ -104,6 +104,11 @@ body.controls-refresh {
width: 4px;
}
+.controls-refresh .color-swatch:focus {
+ outline: solid 2px -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+
.other-color {
width: 100%;
margin: 4px 0 0 0;
@@ -114,7 +119,6 @@ body.controls-refresh {
border-color: transparent;
border-radius: 2px;
color: #000000;
- font-family: sans-serif;
font-size: 12px;
line-height: 16px;
margin: 0;
@@ -136,7 +140,7 @@ body.controls-refresh {
}
.controls-refresh .color-swatch:focus {
- border-color: Highlight;
+ outline-color: Highlight;
}
.controls-refresh .color-swatch-container {
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 ed9cc009f44..467b28893ee 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
@@ -3,10 +3,6 @@
* found in the LICENSE file.
*/
-body {
- font-family: sans-serif;
-}
-
.color-picker-main {
border: 0;
padding: 0;
@@ -14,14 +10,15 @@ body {
color-picker {
background: #FFFFFF;
+ border: 1px solid #bfbfbf;
display: flex;
flex-direction: column;
- height: 304px;
+ height: 250px;
width: 232px;
}
visual-color-picker {
- height: 59%;
+ height: 71.5%;
min-height: 0;
}
@@ -48,12 +45,33 @@ hue-slider {
}
eye-dropper {
+ border-radius: 2px;
height: 32px;
margin-left: 2%;
position: relative;
width: 32px;
}
+eye-dropper.hidden {
+ visibility: hidden;
+}
+
+eye-dropper:not(.selected):hover {
+ background-color: #F7F7F7;
+}
+
+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%;
@@ -70,7 +88,7 @@ color-well > canvas {
hue-slider > canvas {
border-radius: 2px;
- height: 11px;
+ height: 12px;
margin-top: 7%;
width: 100%;
}
@@ -83,6 +101,15 @@ color-selection-ring {
position: absolute;
}
+color-selection-ring:focus {
+ /* Simulate the outline using box-shadow because it follows the border radius
+ * (unlike outline).
+ */
+ box-shadow: 0px 0px 0px 2px;
+ color: -webkit-focus-ring-color;
+ outline: none;
+}
+
color-well > color-selection-ring {
height: 12px;
width: 12px;
@@ -126,7 +153,7 @@ input {
}
color-value-container > input:not(:first-child) {
- margin-left: 1%;
+ margin-left: 4%;
}
format-toggler {
@@ -167,31 +194,6 @@ channel-label {
width: 172px;
}
-submission-controls {
- align-items: center;
- border-top: 1px solid #CECECE;
- display: flex;
- flex-direction: row;
- height: 13%;
- min-height: 0;
-}
-
-#submission-controls-padding {
- height: 100%;
- width: 84%;
-}
-
-submission-button {
- padding: 3%;
- text-align: center;
- width: 8%;
-}
-
-submission-button:hover {
- background-color: #F3F3F3;
- border-radius: 2px;
-}
-
@media (forced-colors: active) {
color-viewer {
forced-color-adjust: none;
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 a91dcc38d09..f7396a8596b 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
@@ -424,15 +424,16 @@ class ColorPicker extends HTMLElement {
constructor(initialColor) {
super();
+ if (global.params.isBorderTransparent) {
+ this.style.borderColor = 'transparent';
+ }
+
this.selectedColor_ = initialColor;
+ this.colorWhenOpened_ = initialColor;
this.visualColorPicker_ = new VisualColorPicker(initialColor);
this.manualColorPicker_ = new ManualColorPicker(initialColor);
- this.submissionControls_ = new SubmissionControls(
- this.onSubmitButtonClick_, this.onCancelButtonClick_);
- this.append(
- this.visualColorPicker_, this.manualColorPicker_,
- this.submissionControls_);
+ this.append(this.visualColorPicker_, this.manualColorPicker_);
this.visualColorPicker_.addEventListener(
'visual-color-picker-initialized', this.initializeListeners_);
@@ -447,6 +448,8 @@ class ColorPicker extends HTMLElement {
this.addEventListener('format-change', this.updateFocusableElements_);
document.documentElement.addEventListener('keydown', this.onKeyDown_);
+
+ window.addEventListener('resize', this.onWindowResize_, {once: true});
}
get selectedColor() {
@@ -480,8 +483,11 @@ class ColorPicker extends HTMLElement {
this.processingManualColorChange_ = true;
this.visualColorPicker_.color = newColor;
this.processingManualColorChange_ = false;
+
+ const selectedValue = newColor.asHex();
+ window.pagePopupController.setValue(selectedValue);
}
- }
+ };
/**
* @param {!Event} event
@@ -492,24 +498,33 @@ class ColorPicker extends HTMLElement {
if (!this.processingManualColorChange_) {
this.selectedColor = newColor;
this.manualColorPicker_.color = newColor;
+
+ const selectedValue = newColor.asHex();
+ window.pagePopupController.setValue(selectedValue);
} else {
// We are making a visual color change in response to a manual color
// change. So we do not overwrite the manually specified values and do
// not change the selected color.
}
}
- }
+ };
/**
* @param {!Event} event
*/
onKeyDown_ = (event) => {
- switch(event.key) {
+ switch (event.key) {
case 'Enter':
- this.submissionControls_.submitButton.click();
+ window.pagePopupController.closePopup();
break;
case 'Escape':
- this.submissionControls_.cancelButton.click();
+ if (this.selectedColor.equals(this.colorWhenOpened_)) {
+ window.pagePopupController.closePopup();
+ } else {
+ this.manualColorPicker_.dispatchEvent(new CustomEvent(
+ 'manual-color-change',
+ {bubbles: true, detail: {color: this.colorWhenOpened_}}));
+ }
break;
case 'Tab':
event.preventDefault();
@@ -522,9 +537,8 @@ class ColorPicker extends HTMLElement {
this.focusableElements_.indexOf(document.activeElement);
let nextFocusIndex;
if (event.shiftKey) {
- nextFocusIndex = (currentFocusIndex > 0) ?
- currentFocusIndex - 1 :
- length - 1;
+ nextFocusIndex =
+ (currentFocusIndex > 0) ? currentFocusIndex - 1 : length - 1;
} else {
nextFocusIndex = (currentFocusIndex + 1) % length;
}
@@ -532,27 +546,20 @@ class ColorPicker extends HTMLElement {
}
break;
}
- }
+ };
updateFocusableElements_ = () => {
this.focusableElements_ = Array.from(this.querySelectorAll(
'color-value-container:not(.hidden-color-value-container) > input,' +
'[tabindex]:not([tabindex=\'-1\'])'));
- }
-
- static get COMMIT_DELAY_MS() {
- return 100;
- }
-
- onSubmitButtonClick_ = () => {
- const selectedValue = this.selectedColor_.asHex();
- window.setTimeout(function() {
- window.pagePopupController.setValueAndClosePopup(0, selectedValue);
- }, ColorPicker.COMMIT_DELAY_MS);
};
- onCancelButtonClick_ = () => {
- window.pagePopupController.closePopup();
+ onWindowResize_ = () => {
+ // Set focus on the first focusable element.
+ if (this.focusableElements_ === undefined) {
+ this.updateFocusableElements_();
+ }
+ this.focusableElements_[0].focus({preventScroll: true});
};
}
window.customElements.define('color-picker', ColorPicker);
@@ -602,6 +609,15 @@ class VisualColorPicker extends HTMLElement {
document.documentElement
.addEventListener('mousemove', this.onMouseMove_);
document.documentElement.addEventListener('mouseup', this.onMouseUp_);
+ this.colorWell_
+ .addEventListener('touchstart', this.onColorWellTouchStart_);
+ this.hueSlider_
+ .addEventListener('touchstart', this.onHueSliderTouchStart_);
+ document.documentElement
+ .addEventListener('touchstart', this.onTouchStart_);
+ document.documentElement
+ .addEventListener('touchmove', this.onTouchMove_);
+ document.documentElement.addEventListener('touchend', this.onTouchEnd_);
document.documentElement.addEventListener('keydown', this.onKeyDown_);
this.dispatchEvent(new CustomEvent('visual-color-picker-initialized'));
@@ -626,7 +642,7 @@ class VisualColorPicker extends HTMLElement {
event.preventDefault();
event.stopPropagation();
this.hueSlider_.focused = false;
- this.colorWell_.mouseDown(new Point(event.clientX, event.clientY));
+ this.colorWell_.pointerDown(new Point(event.clientX, event.clientY));
}
/**
@@ -636,7 +652,7 @@ class VisualColorPicker extends HTMLElement {
event.preventDefault();
event.stopPropagation();
this.colorWell_.focused = false;
- this.hueSlider_.mouseDown(new Point(event.clientX, event.clientY));
+ this.hueSlider_.pointerDown(new Point(event.clientX, event.clientY));
}
onMouseDown_ = () => {
@@ -649,13 +665,52 @@ class VisualColorPicker extends HTMLElement {
*/
onMouseMove_ = (event) => {
var point = new Point(event.clientX, event.clientY);
- this.colorWell_.mouseMove(point);
- this.hueSlider_.mouseMove(point);
+ this.colorWell_.pointerMove(point);
+ this.hueSlider_.pointerMove(point);
}
onMouseUp_ = () => {
- this.colorWell_.mouseUp();
- this.hueSlider_.mouseUp();
+ this.colorWell_.pointerUp();
+ this.hueSlider_.pointerUp();
+ }
+
+ /**
+ * @param {!Event} event
+ */
+ onColorWellTouchStart_ = (event) => {
+ event.preventDefault();
+ event.stopPropagation();
+ this.hueSlider_.focused = false;
+ this.colorWell_.pointerDown(new Point(event.touches[0].clientX, event.touches[0].clientY));
+ }
+
+ /**
+ * @param {!Event} event
+ */
+ onHueSliderTouchStart_ = (event) => {
+ event.preventDefault();
+ event.stopPropagation();
+ this.colorWell_.focused = false;
+ this.hueSlider_.pointerDown(new Point(event.touches[0].clientX, event.touches[0].clientY));
+ }
+
+ onTouchStart_ = () => {
+ this.colorWell_.focused = false;
+ this.hueSlider_.focused = false;
+ }
+
+ /**
+ * @param {!Event} event
+ */
+ onTouchMove_ = (event) => {
+ var point = new Point(event.touches[0].clientX, event.touches[0].clientY);
+ this.colorWell_.pointerMove(point);
+ this.hueSlider_.pointerMove(point);
+ }
+
+ onTouchEnd_ = () => {
+ this.colorWell_.pointerUp();
+ this.hueSlider_.pointerUp();
}
/**
@@ -700,7 +755,88 @@ window.customElements.define('visual-color-picker', VisualColorPicker);
* implementation.)
* TODO(http://crbug.com/992297): Implement eye dropper
*/
-class EyeDropper extends HTMLElement {}
+class EyeDropper extends HTMLElement {
+ constructor() {
+ super();
+
+ if (!global.params.isEyeDropperEnabled) {
+ this.classList.add('hidden');
+ return;
+ }
+
+ 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_);
+ }
+
+ onClick_ = () => {
+ event.preventDefault();
+ event.stopPropagation();
+ this.classList.add('selected');
+ window.pagePopupController.openEyeDropper();
+ };
+
+ /**
+ * @param {!Event} event
+ */
+ onKeyDown_ = (event) => {
+ switch (event.key) {
+ case 'Enter':
+ this.onClick_();
+ break;
+ }
+ };
+}
window.customElements.define('eye-dropper', EyeDropper);
/**
@@ -766,7 +902,7 @@ class ColorSelectionArea extends HTMLElement {
/**
* @param {!Point} point
*/
- mouseDown(point) {
+ pointerDown(point) {
this.colorSelectionRing_.focus({preventScroll: true});
this.colorSelectionRing_.drag = true;
this.moveColorSelectionRingTo_(point);
@@ -775,13 +911,13 @@ class ColorSelectionArea extends HTMLElement {
/**
* @param {!Point} point
*/
- mouseMove(point) {
+ pointerMove(point) {
if (this.colorSelectionRing_.drag) {
this.moveColorSelectionRingTo_(point);
}
}
- mouseUp() {
+ pointerUp() {
this.colorSelectionRing_.drag = false;
}
@@ -1011,6 +1147,7 @@ class ColorSelectionRing extends HTMLElement {
initialize() {
this.set(this.backingColorPalette_.left, this.backingColorPalette_.top);
+ this.onPositionChange_();
}
/**
@@ -1873,65 +2010,3 @@ class ChannelLabel extends HTMLElement {
}
}
window.customElements.define('channel-label', ChannelLabel);
-
-/**
- * SubmissionControls: Provides functionality to submit or discard a change.
- */
-class SubmissionControls extends HTMLElement {
- /**
- * @param {function} submitCallback executed if the submit button is clicked
- * @param {function} cancelCallback executed if the cancel button is clicked
- */
- constructor(submitCallback, cancelCallback) {
- super();
-
- const padding = document.createElement('span');
- padding.setAttribute('id', 'submission-controls-padding');
- this.append(padding);
-
- this.submitButton_ = new SubmissionButton(
- submitCallback,
- '<svg width="14" height="10" viewBox="0 0 14 10" fill="none" ' +
- 'xmlns="http://www.w3.org/2000/svg"><path d="M13.3516 ' +
- '1.35156L5 9.71094L0.648438 5.35156L1.35156 4.64844L5 ' +
- '8.28906L12.6484 0.648438L13.3516 1.35156Z" fill="WindowText"/></svg>');
- this.cancelButton_ = new SubmissionButton(
- cancelCallback,
- '<svg width="14" height="14" viewBox="0 0 14 14" fill="none" ' +
- 'xmlns="http://www.w3.org/2000/svg"><path d="M7.71094 7L13.1016 ' +
- '12.3984L12.3984 13.1016L7 7.71094L1.60156 13.1016L0.898438 ' +
- '12.3984L6.28906 7L0.898438 1.60156L1.60156 0.898438L7 ' +
- '6.28906L12.3984 0.898438L13.1016 1.60156L7.71094 7Z" ' +
- 'fill="WindowText"/></svg>');
- this.append(this.submitButton_, this.cancelButton_);
- }
-
- get submitButton() {
- return this.submitButton_;
- }
-
- get cancelButton() {
- return this.cancelButton_;
- }
-}
-window.customElements.define('submission-controls', SubmissionControls);
-
-/**
- * SubmissionButton: Button with a custom look that can be clicked for
- * a submission action.
- */
-class SubmissionButton extends HTMLElement {
- /**
- * @param {function} clickCallback executed when the button is clicked
- * @param {string} htmlString custom look for the button
- */
- constructor(clickCallback, htmlString) {
- super();
-
- this.setAttribute('tabIndex', '0');
- this.innerHTML = htmlString;
-
- this.addEventListener('click', clickCallback);
- }
-}
-window.customElements.define('submission-button', SubmissionButton);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker_common.js b/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker_common.js
index bdd671d2cf0..907aa31debe 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker_common.js
+++ b/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker_common.js
@@ -43,6 +43,9 @@ function initialize(args) {
document.body.classList.add('controls-refresh');
}
main.classList.add('color-suggestion-picker-main');
+ if (global.params.isBorderTransparent) {
+ main.style.borderColor = 'transparent';
+ }
errorString = validateColorSuggestionPickerArguments(args);
} else {
main.classList.add('color-picker-main');
diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/datetimelocal_picker.js b/chromium/third_party/blink/renderer/core/html/forms/resources/datetimelocal_picker.js
index 64f219fcaad..414bfde715b 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/resources/datetimelocal_picker.js
+++ b/chromium/third_party/blink/renderer/core/html/forms/resources/datetimelocal_picker.js
@@ -19,10 +19,9 @@ function initializeDateTimeLocalPicker(config) {
/**
* DateTimeLocalPicker: Custom element providing a datetime-local picker implementation.
- * DateTimeLocalPicker contains 3 parts:
+ * DateTimeLocalPicker contains 2 parts:
* - date picker
* - time picker
- * - submission controls
*/
class DateTimeLocalPicker extends HTMLElement {
constructor(config) {
@@ -34,34 +33,72 @@ class DateTimeLocalPicker extends HTMLElement {
this.timePicker_ = new TimePicker(config);
this.append(this.datePicker_.element, this.timePicker_);
- this.submissionControls_ = new SubmissionControls(
- this.onSubmitButtonClick_, this.onCancelButtonClick_);
- this.append(this.submissionControls_);
+ this.hadValidValueWhenOpened_ =
+ (config.currentValue !== '') && (this.datePicker_.selection() != null);
+ this.initialSelectedValue_ = this.selectedValue;
+
this.addEventListener('keydown', this.onKeyDown_);
+ this.addEventListener('click', this.onClick_);
window.addEventListener('resize', this.onWindowResize_, {once: true});
};
- onSubmitButtonClick_ = () => {
- const selectedValue = this.datePicker_.getSelectedValue() + 'T' +
- this.timePicker_.selectedValue;
- window.setTimeout(function() {
- window.pagePopupController.setValueAndClosePopup(0, selectedValue);
- }, 100);
- };
-
- onCancelButtonClick_ = () => {
- window.pagePopupController.closePopup();
- };
-
onKeyDown_ = (event) => {
switch (event.key) {
case 'Enter':
- this.submissionControls_.submitButton.click();
+ // Submit the popup for an Enter keypress except when the user is
+ // hitting Enter to activate the month switcher button, Today button,
+ // or previous/next month arrows.
+ if (!event.target.matches(
+ '.calendar-navigation-button, .month-popup-button, .year-list-view')) {
+ window.pagePopupController.setValueAndClosePopup(
+ 0, this.selectedValue);
+ } else if (event.target.matches(
+ '.calendar-navigation-button, .year-list-view')) {
+ // Navigating with the previous/next arrows may change selection,
+ // so push this change to the in-page control but don't
+ // close the popup.
+ window.pagePopupController.setValue(this.selectedValue);
+ }
break;
case 'Escape':
- this.submissionControls_.cancelButton.click();
+ if (this.selectedValue === this.initialSelectedValue_) {
+ window.pagePopupController.closePopup();
+ } else {
+ this.datePicker_.resetToInitialValue();
+ this.timePicker_.resetToInitialValue();
+ window.pagePopupController.setValue(
+ this.hadValidValueWhenOpened_ ? this.initialSelectedValue_ : '');
+ }
+ break;
+ case 'ArrowUp':
+ case 'ArrowDown':
+ case 'ArrowLeft':
+ case 'ArrowRight':
+ case 'PageUp':
+ case 'PageDown':
+ if (event.target.matches('.calendar-table-view, .time-column') &&
+ this.hasSelectedDate) {
+ window.pagePopupController.setValue(this.selectedValue);
+ }
+ // Stop the native scrolling behavior; the Time picker needs to manage
+ // its own scroll position.
+ event.preventDefault();
break;
+ case 'Home':
+ case 'End':
+ // Prevent an attempt to scroll to the end of
+ // of an infinitely looping time picker column.
+ event.preventDefault();
+ break;
+ }
+ };
+
+ onClick_ = (event) => {
+ if (event.target.matches(
+ '.day-cell, .time-cell, .today-button-refresh, .calendar-navigation-button, .year-list-view, .calendar-navigation-button, .today-button-icon-refresh, .month-button') &&
+ this.hasSelectedDate) {
+ window.pagePopupController.setValue(this.selectedValue);
}
};
@@ -69,6 +106,19 @@ class DateTimeLocalPicker extends HTMLElement {
this.datePicker_.calendarTableView.element.focus();
};
+ // This will be false if neither the initial value of the
+ // control nor today's date are within a valid date range defined
+ // by the 'step', 'min', and 'max' attributes of the control.
+ get hasSelectedDate() {
+ return (this.datePicker_.selection() != null);
+ }
+
+ get selectedValue() {
+ return this.hasSelectedDate ? (this.datePicker_.getSelectedValue() + 'T' +
+ this.timePicker_.selectedValue) :
+ '';
+ }
+
get height() {
return DateTimeLocalPicker.Height;
}
@@ -77,10 +127,6 @@ class DateTimeLocalPicker extends HTMLElement {
return this.datePicker_.width() + this.timePicker_.width;
}
- get submissionControls() {
- return this.submissionControls_;
- }
-
get datePicker() {
return this.datePicker_;
}
@@ -90,5 +136,5 @@ class DateTimeLocalPicker extends HTMLElement {
}
}
DateTimeLocalPicker.ClassName = 'datetimelocal-picker';
-DateTimeLocalPicker.Height = 320;
+DateTimeLocalPicker.Height = 280;
window.customElements.define('datetimelocal-picker', DateTimeLocalPicker);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/listPicker.css b/chromium/third_party/blink/renderer/core/html/forms/resources/listPicker.css
index d190f9dab12..be88651d93a 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/resources/listPicker.css
+++ b/chromium/third_party/blink/renderer/core/html/forms/resources/listPicker.css
@@ -16,3 +16,13 @@ option, optgroup {
.wrap option {
white-space: pre-wrap;
}
+
+.controls-refresh select {
+ border-radius: 0px;
+ outline: none;
+}
+
+.controls-refresh option:checked:enabled {
+ outline: solid 2px -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/listPicker.js b/chromium/third_party/blink/renderer/core/html/forms/resources/listPicker.js
index 8294f0b6d7e..0709fa0ee21 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/resources/listPicker.js
+++ b/chromium/third_party/blink/renderer/core/html/forms/resources/listPicker.js
@@ -21,6 +21,9 @@ function initialize(args) {
global.params = args;
var main = $('main');
main.innerHTML = '';
+ if (global.params.isFormControlsRefreshEnabled) {
+ document.body.classList.add('controls-refresh');
+ }
global.picker = new ListPicker(main, args);
}
@@ -37,7 +40,6 @@ function handleArgumentsTimeout() {
*/
function ListPicker(element, config) {
Picker.call(this, element, config);
- window.pagePopupController.selectFontsFromOwnerDocument(document);
this._selectElement = createElement('select');
this._selectElement.size = 20;
this._element.appendChild(this._selectElement);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/month_picker.js b/chromium/third_party/blink/renderer/core/html/forms/resources/month_picker.js
index 47cf5ee0c4a..5ebf0d6b6b3 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/resources/month_picker.js
+++ b/chromium/third_party/blink/renderer/core/html/forms/resources/month_picker.js
@@ -10,7 +10,10 @@
function initializeMonthPicker(config) {
global.picker = new MonthPicker(config);
main.append(global.picker);
- main.style.border = '1px solid transparent';
+ main.style.border = '1px solid #bfbfbf';
+ if (global.params.isBorderTransparent) {
+ main.style.borderColor = 'transparent';
+ }
main.style.height = (MonthPicker.Height - 2) + 'px';
main.style.width = (MonthPicker.Width - 2) + 'px';
resizeWindow(MonthPicker.Width, MonthPicker.Height);
@@ -29,7 +32,7 @@ class MonthPicker extends HTMLElement {
this.initializeFromConfig_(config);
this.yearListView_ =
- new YearListView(this.minimumMonth_, this.maximumMonth_);
+ new YearListView(this.minimumMonth_, this.maximumMonth_, config);
this.append(this.yearListView_.element);
this.initializeYearListView_();
@@ -38,6 +41,7 @@ class MonthPicker extends HTMLElement {
this.initializeTodayButton_();
window.addEventListener('resize', this.onWindowResize_);
+ this.addEventListener('keydown', this.onKeyDown_);
}
initializeFromConfig_ = (config) => {
@@ -49,20 +53,6 @@ class MonthPicker extends HTMLElement {
Month.Maximum;
this.minimumMonth_ = Month.createFromDay(minimum.firstDay());
this.maximumMonth_ = Month.createFromDay(maximum.lastDay());
-
- const initialSelection = parseDateString(config.currentValue);
- const initialSelectedMonth = initialSelection ?
- Month.createFromDay(initialSelection.middleDay()) :
- Month.createFromToday();
- this.initialValidSelection_ = false;
- if (initialSelectedMonth < this.minimumMonth_) {
- this.selectedMonth_ = this.minimumMonth_;
- } else if (initialSelectedMonth > this.maximumMonth_) {
- this.selectedMonth_ = this.maximumMonth_;
- } else {
- this.selectedMonth_ = initialSelectedMonth;
- this.initialValidSelection_ = initialSelection != null;
- }
};
initializeYearListView_ = () => {
@@ -78,26 +68,21 @@ class MonthPicker extends HTMLElement {
MonthPicker.YearWidth + 'px';
}
this.yearListView_.element.style.top = MonthPicker.YearPadding + 'px';
- if (this.initialValidSelection_) {
- this.yearListView_.setSelectedMonth(this.selectedMonth_);
- }
- this.yearListView_.show(this.selectedMonth_);
+
+ let yearForInitialScroll = this.selectedMonth ?
+ this.selectedMonth.year - 1 :
+ Month.createFromToday().year - 1;
+ this.yearListView_.scrollToRow(yearForInitialScroll, false);
+ this.yearListView_.selectWithoutAnimating(yearForInitialScroll);
+
this.yearListView_.on(
YearListView.EventTypeYearListViewDidSelectMonth,
this.onYearListViewDidSelectMonth_);
- this.yearListView_.on(
- YearListView.EventTypeYearListViewDidHide, this.onYearListViewDidHide_);
- };
-
- onYearListViewDidHide_ = (sender) => {
- const selectedValue = this.selectedMonth_.toString();
- window.setTimeout(function() {
- window.pagePopupController.setValueAndClosePopup(0, selectedValue);
- }, 100);
};
onYearListViewDidSelectMonth_ = (sender, month) => {
- this.selectedMonth_ = month;
+ const selectedValue = month.toString();
+ window.pagePopupController.setValueAndClosePopup(0, selectedValue);
};
initializeTodayButton_ = () => {
@@ -107,8 +92,7 @@ class MonthPicker extends HTMLElement {
this.todayButton_.element.classList.add(MonthPicker.ClassNameTodayButton);
const monthContainingToday = Month.createFromToday();
this.todayButton_.setDisabled(
- monthContainingToday < this.minimumMonth_ ||
- monthContainingToday > this.maximumMonth_);
+ !this.yearListView_.isValid(monthContainingToday));
this.todayButton_.on(
CalendarNavigationButton.EventTypeButtonClick,
this.onTodayButtonClick_);
@@ -116,15 +100,68 @@ class MonthPicker extends HTMLElement {
onTodayButtonClick_ = (sender) => {
const selectedValue = Month.createFromToday().toString();
- window.setTimeout(function() {
- window.pagePopupController.setValueAndClosePopup(0, selectedValue);
- }, 100);
+ window.pagePopupController.setValueAndClosePopup(0, selectedValue);
+ };
+
+ onKeyDown_ = (event) => {
+ switch (event.key) {
+ case 'Enter':
+ // Don't do anything here if user has hit Enter on 'This month'
+ // button. We'll handle that in this.onTodayButtonClick_.
+ if (!event.target.matches('.calendar-navigation-button')) {
+ if (this.selectedMonth) {
+ window.pagePopupController.setValueAndClosePopup(
+ 0, this.selectedMonth.toString());
+ } else {
+ window.pagePopupController.closePopup();
+ }
+ }
+ break;
+ case 'Escape':
+ if (!this.selectedMonth ||
+ (this.selectedMonth.equals(this.initialSelectedMonth))) {
+ window.pagePopupController.closePopup();
+ } else {
+ this.resetToInitialValue_();
+ window.pagePopupController.setValue(
+ this.hadValidValueWhenOpened ?
+ this.initialSelectedMonth.toString() :
+ '');
+ }
+ break;
+ case 'ArrowUp':
+ case 'ArrowDown':
+ case 'ArrowLeft':
+ case 'ArrowRight':
+ case 'PageUp':
+ case 'PageDown':
+ if (this.selectedMonth) {
+ window.pagePopupController.setValue(this.selectedMonth.toString());
+ }
+ break;
+ }
+ };
+
+ resetToInitialValue_ = () => {
+ this.yearListView_.setSelectedMonthAndUpdateView(this.initialSelectedMonth);
};
onWindowResize_ = (event) => {
window.removeEventListener('resize', this.onWindowResize_);
this.yearListView_.element.focus();
};
+
+ get selectedMonth() {
+ return this.yearListView_._selectedMonth;
+ };
+
+ get initialSelectedMonth() {
+ return this.yearListView_._initialSelectedMonth;
+ };
+
+ get hadValidValueWhenOpened() {
+ return this.yearListView_._hadValidValueWhenOpened;
+ };
}
MonthPicker.Width = 232;
MonthPicker.YearWidth = 194;
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 860e2a397f0..011130295f3 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
@@ -56,7 +56,7 @@
}
.controls-refresh .suggestion-list {
- border-color: transparent;
+ border-color: #bfbfbf;
padding: 4px;
}
@@ -69,6 +69,8 @@
.controls-refresh .suggestion-list-entry:focus {
background-color: #E5E5E5;
+ outline: solid 2px -webkit-focus-ring-color;
+ outline-offset: -2px;
}
.controls-refresh .suggestion-list-entry .title {
diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/suggestionPicker.js b/chromium/third_party/blink/renderer/core/html/forms/resources/suggestionPicker.js
index e42d5424a39..760c04e1022 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/resources/suggestionPicker.js
+++ b/chromium/third_party/blink/renderer/core/html/forms/resources/suggestionPicker.js
@@ -200,6 +200,9 @@ SuggestionPicker.prototype._layout = function() {
if (this._config.isLocaleRTL)
this._element.classList.add('locale-rtl');
this._containerElement = createElement('ul', 'suggestion-list');
+ if (global.params.isBorderTransparent) {
+ this._containerElement.style.borderColor = 'transparent';
+ }
this._containerElement.addEventListener(
'click', this._handleEntryClick.bind(this), false);
for (var i = 0; i < this._config.suggestionValues.length; ++i) {
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 ebd30d88d0c..2a460119fea 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
@@ -3,16 +3,12 @@
* found in the LICENSE file.
*/
-body {
- font-family: sans-serif;
-}
-
.time-picker {
background: #FFFFFF;
- border: 1px solid transparent;
+ border: 1px solid #bfbfbf;
display: flex;
flex-direction: column;
- height: 298px;
+ height: 258px;
}
.time-columns {
@@ -31,7 +27,7 @@ body {
outline: none;
overflow: scroll;
padding: 0;
- scroll-snap-type: y mandatory;
+ position: relative;
width: 52px;
}
@@ -46,57 +42,23 @@ body {
font-size: 14px;
height: 32px;
line-height: 32px;
- scroll-snap-align: start;
+ position: relative;
text-align: center;
width: 48px;
}
.time-cell:hover {
- background: #E5E5E5;
+ background-color: rgba(0, 117, 255, 0.3);
}
.time-cell.selected {
- background-color: #CECECE;
+ background-color: #0075FF;
+ color: #FFFFFF;
font-weight: bold;
}
.time-column:focus .time-cell.selected {
- border-color: highlight;
-}
-
-.submission-controls {
- align-items: center;
- border-top: 1px solid #CECECE;
- bottom: 0px;
- display: flex;
- flex-direction: row;
- height: 40px;
- position: absolute;
- width: 100%;
-}
-
-#submission-controls-padding {
- height: 100%;
- width: 84%;
-}
-
-.submission-button {
- background-color: #FFFFFF;
- border: 2px solid transparent;
- border-radius: 2px;
- height: 32px;
- margin: 4px;
- padding: 8px;
- width: 32px;
-}
-
-.submission-button:hover {
- background-color: #E5E5E5;
-}
-
-.submission-button:focus {
- border-color: highlight;
- outline: none;
+ border-color: #101010;
}
@media (forced-colors: active) {
@@ -119,22 +81,4 @@ body {
.time-column:focus .time-cell.selected {
border-color: WindowText;
}
-
- .submission-button {
- background-color: Window;
- forced-color-adjust: none;
- }
-
- .submission-button:hover {
- background-color: Window;
- border-color: Highlight;
- }
-
- .submission-button:focus {
- border-color: WindowText;
- }
-
- .submission-button path {
- fill: WindowText;
- }
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/time_picker.js b/chromium/third_party/blink/renderer/core/html/forms/resources/time_picker.js
index 8959e6bc4cc..62280830b9d 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/resources/time_picker.js
+++ b/chromium/third_party/blink/renderer/core/html/forms/resources/time_picker.js
@@ -27,7 +27,6 @@ const TimeColumnType = {
AMPM: 5,
};
-
/**
* Supported label types.
* @enum {number}
@@ -63,7 +62,7 @@ class Time {
this.minute_ = minute;
this.second_ = second;
this.millisecond_ = millisecond;
- }
+ };
next = (columnType) => {
switch (columnType) {
@@ -210,15 +209,15 @@ DateTime.ISOStringRegExp = /^(\d+)-(\d+)-(\d+)T(\d+):(\d+):?(\d*).?(\d*)/;
/**
* TimePicker: Custom element providing a time picker implementation.
- * TimePicker contains 2 parts:
- * - column container
- * - submission controls
*/
class TimePicker extends HTMLElement {
constructor(config) {
super();
this.className = TimePicker.ClassName;
+ if (global.params.isBorderTransparent) {
+ this.style.borderColor = 'transparent';
+ }
this.initializeFromConfig_(config);
this.timeColumns_ = new TimeColumns(this);
@@ -226,10 +225,8 @@ class TimePicker extends HTMLElement {
if (config.mode == 'time') {
// TimePicker doesn't handle the submission when used for non-time types.
- this.submissionControls_ = new SubmissionControls(
- this.onSubmitButtonClick_, this.onCancelButtonClick_);
- this.append(this.submissionControls_);
this.addEventListener('keydown', this.onKeyDown_);
+ this.addEventListener('click', this.onClick_);
}
window.addEventListener('resize', this.onWindowResize_, {once: true});
@@ -237,48 +234,70 @@ class TimePicker extends HTMLElement {
initializeFromConfig_ = (config) => {
const initialSelection = parseDateTimeString(config.currentValue, 'time');
- this.selectedTime_ =
+ this.initialSelectedTime_ =
initialSelection ? initialSelection : Time.currentTime();
+ this.hadValidValueWhenOpened_ = (initialSelection != null);
this.hasSecond_ = config.hasSecond;
this.hasMillisecond_ = config.hasMillisecond;
this.hasAMPM_ = config.hasAMPM;
};
- onSubmitButtonClick_ = () => {
- const selectedValue = this.selectedValue;
- window.setTimeout(function() {
- window.pagePopupController.setValueAndClosePopup(0, selectedValue);
- }, 100);
- };
-
- onCancelButtonClick_ = () => {
- window.pagePopupController.closePopup();
- };
-
onWindowResize_ = (event) => {
- // Scroll columns to the second half to allow scrolling up.
- this.timeColumns_.scrollColumnsToMiddle();
+ this.timeColumns_.scrollColumnsToSelectedCells();
this.timeColumns_.firstChild.focus();
};
onKeyDown_ = (event) => {
switch (event.key) {
case 'Enter':
- this.submissionControls_.submitButton.click();
+ window.pagePopupController.setValueAndClosePopup(0, this.selectedValue);
break;
case 'Escape':
- this.submissionControls_.cancelButton.click();
+ if (this.selectedValue ===
+ this.initialSelectedTime.toString(
+ this.hasSecond, this.hasMillisecond)) {
+ window.pagePopupController.closePopup();
+ } else {
+ this.resetToInitialValue();
+ window.pagePopupController.setValue(
+ this.hadValidValueWhenOpened ? this.selectedValue : '');
+ }
+ break;
+ case 'ArrowUp':
+ case 'ArrowDown':
+ window.pagePopupController.setValue(this.selectedValue);
+ event.stopPropagation();
+ event.preventDefault();
+ break;
+ case 'Home':
+ case 'End':
+ // Prevent an attempt to scroll to the end of
+ // of an infinitely looping column.
+ event.preventDefault();
break;
}
};
+ onClick_ = (event) => {
+ window.pagePopupController.setValue(this.selectedValue);
+ };
+
+ resetToInitialValue = () => {
+ this.timeColumns_.resetToInitialValues();
+ this.timeColumns_.scrollColumnsToSelectedCells();
+ }
+
get selectedValue() {
return this.timeColumns_.selectedValue().toString(
this.hasSecond, this.hasMillisecond);
}
- get selectedTime() {
- return this.selectedTime_;
+ get initialSelectedTime() {
+ return this.initialSelectedTime_;
+ }
+
+ get hadValidValueWhenOpened() {
+ return this.hadValidValueWhenOpened_;
}
get hasSecond() {
@@ -304,13 +323,9 @@ class TimePicker extends HTMLElement {
get timeColumns() {
return this.timeColumns_;
}
-
- get submissionControls() {
- return this.submissionControls_;
- }
}
TimePicker.ClassName = 'time-picker';
-TimePicker.Height = 300;
+TimePicker.Height = 260;
TimePicker.ColumnWidth = 56;
TimePicker.BorderWidth = 1;
window.customElements.define('time-picker', TimePicker);
@@ -379,15 +394,21 @@ class TimeColumns extends HTMLElement {
return new Time(hour, minute, second, millisecond);
};
- scrollColumnsToMiddle = () => {
- this.hourColumn_.scrollTop = this.hourColumn_.scrollHeight / 2;
- this.minuteColumn_.scrollTop = this.minuteColumn_.scrollHeight / 2;
+ resetToInitialValues =
+ () => {
+ Array.prototype.forEach.call(this.children, (column) => {
+ column.resetToInitialValue();
+ });
+ }
+
+ scrollColumnsToSelectedCells = () => {
+ this.hourColumn_.scrollToSelectedCell();
+ this.minuteColumn_.scrollToSelectedCell();
if (this.secondColumn_) {
- this.secondColumn_.scrollTop = this.secondColumn_.scrollHeight / 2;
+ this.secondColumn_.scrollToSelectedCell();
}
if (this.millisecondColumn_) {
- this.millisecondColumn_.scrollTop =
- this.millisecondColumn_.scrollHeight / 2;
+ this.millisecondColumn_.scrollToSelectedCell();
}
}
}
@@ -405,10 +426,24 @@ class TimeColumn extends HTMLUListElement {
this.className = TimeColumn.ClassName;
this.tabIndex = 0;
this.columnType_ = columnType;
+ this.setAttribute('role', 'listbox');
+ if (this.columnType_ === TimeColumnType.HOUR) {
+ this.setAttribute('aria-label', global.params.axHourLabel);
+ } else if (this.columnType_ === TimeColumnType.MINUTE) {
+ this.setAttribute('aria-label', global.params.axMinuteLabel);
+ } else if (this.columnType_ === TimeColumnType.SECOND) {
+ this.setAttribute('aria-label', global.params.axSecondLabel);
+ } else if (this.columnType_ === TimeColumnType.MILLISECOND) {
+ this.setAttribute('aria-label', global.params.axMillisecondLabel);
+ } else {
+ this.setAttribute('aria-label', global.params.axAmPmLabel);
+ }
+
if (this.columnType_ == TimeColumnType.AMPM) {
this.createAndInitializeAMPMCells_(timePicker);
} else {
this.createAndInitializeCells_(timePicker);
+ this.setupScrollHandler_();
}
this.addEventListener('click', this.onClick_);
@@ -417,23 +452,156 @@ class TimeColumn extends HTMLUListElement {
createAndInitializeCells_ = (timePicker) => {
const totalCells = Time.numberOfValues(this.columnType_, timePicker.hasAMPM);
- let currentTime = timePicker.selectedTime.clone();
+ let currentTime = timePicker.initialSelectedTime.clone();
+
+ // The granularity of millisecond cells is once cell per 100ms.
+ // But, we want to have a cell with the exact millisecond value of the
+ // in-page control, so we'll replace the millisecond cell closest to that
+ // value with the exact value. We do that by figuring out here which of
+ // the cells will be the closest one here, and then matching against that
+ // one in the subsequent loop.
+ let roundedMillisecondValue = 0;
+ if (this.columnType_ === TimeColumnType.MILLISECOND) {
+ let millisecondValue =
+ currentTime.value(TimeColumnType.MILLISECOND, timePicker.hasAMPM);
+ roundedMillisecondValue =
+ (100 * Math.floor((Number(millisecondValue) + 50.0) / 100.0)) % 1000;
+ }
+
+ let time = new Time(1, 1, 1, 100);
let cells = [];
- let duplicateCells = [];
- // In order to support a continuous looping navigation for up/down arrows,
- // the initial list of cells is doubled and middleTimeCell is kept
- // to inform where the duplicated cells begin.
+ let initialCellIndex = -1;
for (let i = 0; i < totalCells; i++) {
- let value = currentTime.value(this.columnType_, timePicker.hasAMPM);
+ let value = time.value(this.columnType_, timePicker.hasAMPM);
+
+ if (this.columnType_ === TimeColumnType.MILLISECOND &&
+ Number(value) === roundedMillisecondValue) {
+ // Set this cell to the exact ms value of the in-page control
+ value =
+ currentTime.value(TimeColumnType.MILLISECOND, timePicker.hasAMPM);
+ initialCellIndex = i;
+ } else if (
+ time.value(this.columnType_, timePicker.hasAMPM) ===
+ currentTime.value(this.columnType_, timePicker.hasAMPM)) {
+ initialCellIndex = i;
+ }
+
let timeCell = new TimeCell(value, localizeNumber(value));
- let duplicatedTimeCell = new TimeCell(value, localizeNumber(value));
cells.push(timeCell);
- duplicateCells.push(duplicatedTimeCell);
- currentTime.next(this.columnType_);
+
+ timeCell.initialOffsetTop = TimeColumn.CELL_HEIGHT * i;
+ timeCell.style.top = `${TimeColumn.SCROLL_OFFSET}px`;
+
+ time.next(this.columnType_);
+ }
+ this.selectedTimeCell = this.initialTimeCell_ = cells[initialCellIndex];
+ this.cellsInLayoutOrder = cells;
+ this.append(...cells);
+ };
+
+ /*
+ * Create a scroll handler that implements infinite looping scroll by
+ * rotating TimeCells up/down so that there is always at least one cell
+ * offscreen in the direction of the scroll. This activity should be
+ * invisible to the user.
+ */
+ setupScrollHandler_ = () => {
+ let lastScrollPosition = 0;
+ let upcomingSnapToCellEdge = null;
+ this.addEventListener('scroll', (event) => {
+ let isGoingDown = (this.scrollTop > lastScrollPosition);
+ lastScrollPosition = this.scrollTop;
+
+ // Rotate cells down until there is one cell beyond the bottom
+ // of the visible scroller area.
+ while (this.cellsInLayoutOrder[this.cellsInLayoutOrder.length - 1]
+ .offsetTop -
+ this.scrollTop - this.clientHeight <
+ TimeColumn.CELL_HEIGHT) {
+ this.rotateCells_(
+ /*topToBottom*/ true);
+ }
+
+ // Rotate cells up until there is one cell beyond the top
+ // of the visible scroller area.
+ while (this.scrollTop - this.cellsInLayoutOrder[0].offsetTop <
+ TimeColumn.CELL_HEIGHT * 2) {
+ this.rotateCells_(
+ /*topToBottom*/ false);
+ }
+
+ // Snap the scroll amount to the nearest TimeCell top edge 1 second
+ // after the user has stopped scrolling. This would be done with
+ // CSS scroll-snap-align, but it interferes with this scroll handler
+ // and causes jittery scrolling.
+ window.clearTimeout(upcomingSnapToCellEdge);
+ upcomingSnapToCellEdge =
+ window.setTimeout(() => {this.snapToCellEdge_(isGoingDown)}, 1000);
+ });
+ };
+
+ /*
+ * Scroll the column so that the top is aligned with the top edge of the
+ * nearest TimeCell in the given direction.
+ */
+ snapToCellEdge_ = (isGoingDown) => {
+ let offsetFromCellEdge =
+ (this.cellsInLayoutOrder[this.cellsInLayoutOrder.length - 1].offsetTop -
+ this.scrollTop) %
+ TimeColumn.CELL_HEIGHT;
+ if (isGoingDown) {
+ this.scrollTop += offsetFromCellEdge;
+ } else {
+ if (offsetFromCellEdge != 0) {
+ this.scrollTop -= TimeColumn.CELL_HEIGHT - offsetFromCellEdge;
+ }
+ }
+ };
+
+ // Ideally we would have truly infinite scrolling in both directions.
+ // However, the platform does not allow scrolling into negative scroll
+ // offsets. So, we start the column at a large positive scroll so that
+ // the column will be unlikely to hit the top during normal use.
+ static SCROLL_OFFSET = 100000;
+ static CELL_HEIGHT = 36; // Height of one TimeCell, including border
+
+ // Using position:absolute for TimeCells seems like the natural choice,
+ // but absolutely positioned children don't cause the TimeColumn scroll
+ // container to expand to hold the cells, so they fall off the end of
+ // the popup. Instead, we use relative positioning and use these
+ // helpers to convert to an "absolute" position that is easier to reason
+ // about when manipulating the layout position of the TimeCells.
+ static getCellAbsolutePosition = (cell) => {
+ let cellOffset = parseInt(cell.style.top.substring(
+ 0, cell.style.top.length - 2)); // Chop off the 'px'
+ return (cellOffset + cell.initialOffsetTop);
+ };
+ static setCellAbsolutePosition = (cell, absolutePosition) => {
+ cell.style.top = `${absolutePosition - cell.initialOffsetTop}px`;
+ };
+
+ // Take the top/bottom TimeCell in this column and move it to the
+ // bottom/top. This should only be done for offscreen cells so that
+ // it is invisible to the user -- but it ensures that the cells will
+ // always be visible wherever the user scrolls.
+ rotateCells_ = (topToBottom) => {
+ if (topToBottom) {
+ let topCell = this.cellsInLayoutOrder.shift();
+ let bottomCell =
+ this.cellsInLayoutOrder[this.cellsInLayoutOrder.length - 1];
+ let bottomCellAbsoluteOffset =
+ TimeColumn.getCellAbsolutePosition(bottomCell);
+ TimeColumn.setCellAbsolutePosition(
+ topCell, bottomCellAbsoluteOffset + TimeColumn.CELL_HEIGHT);
+ this.cellsInLayoutOrder.push(topCell);
+ } else {
+ let topCell = this.cellsInLayoutOrder[0];
+ let bottomCell = this.cellsInLayoutOrder.pop();
+ let absoluteTopCellOffset = TimeColumn.getCellAbsolutePosition(topCell);
+ TimeColumn.setCellAbsolutePosition(
+ bottomCell, absoluteTopCellOffset - TimeColumn.CELL_HEIGHT);
+ this.cellsInLayoutOrder.unshift(bottomCell);
}
- this.selectedTimeCell = duplicateCells[0];
- this.middleTimeCell_ = duplicateCells[0];
- this.append(...cells, ...duplicateCells);
};
createAndInitializeAMPMCells_ = (timePicker) => {
@@ -444,7 +612,7 @@ class TimeColumn extends HTMLUListElement {
cells.push(timeCell);
}
- if (timePicker.selectedTime.isAM()) {
+ if (timePicker.initialSelectedTime.isAM()) {
this.append(cells[Label.AM], cells[Label.PM]);
this.selectedTimeCell = cells[Label.AM];
} else {
@@ -458,40 +626,53 @@ class TimeColumn extends HTMLUListElement {
};
/**
- * Continuous looping navigation for up/down arrows is supported by:
- * - moving for ArrowUp to previous cell and for topmost cell which
- * has no previous, we are moving to the last cell from the first list
- * - moving for ArrowDown to next cell and for the last duplicated cell
- * which has no next, we are moving to the first cell from the duplicated list
+ * Continuous looping navigation for up/down arrows and scrolling is
+ * supported by rotating the layout positions of the TimeCells. This
+ * is done in a scroll event handler and the following keydown handler.
+ * Cells are rotated in before they are reached by the visible part of
+ * the scroller, so the user just sees an infinitely looping column.
*/
onKeyDown_ = (event) => {
- let eventHandled = false;
switch (event.key) {
case 'ArrowUp':
- const previousTimeCell = this.selectedTimeCell.previousSibling;
- if (previousTimeCell) {
- this.selectedTimeCell = previousTimeCell;
- previousTimeCell.scrollIntoViewIfNeeded(false);
- } else if (this.columnType != TimeColumnType.AMPM) {
- // move from the topmost cell to the last cell (the last cell is
- // the first one before the duplicated list).
- this.selectedTimeCell = this.middleTimeCell.previousSibling;
- this.selectedTimeCell.scrollIntoView();
+ const previousTimeCell = this.selectedTimeCell.previousSibling ?
+ this.selectedTimeCell.previousSibling :
+ this.lastElementChild;
+
+ if (this.scrollTop === 0 && previousTimeCell.offsetTop <= 0) {
+ // If the user somehow made it all the way to the top of the
+ // scroller, stop going up and rotating cells into negative
+ // offsets. This should not be a normal scenario.
+ break;
}
- eventHandled = true;
+
+ // Ensure that we don't run out of cells ahead of the selected cell in
+ // the event that the scroll event handler can't keep up. This can
+ // happen e.g. if the user holds down the arrow key.
+ if (this.columnType_ !== TimeColumnType.AMPM &&
+ this.selectedTimeCell === this.cellsInLayoutOrder[0]) {
+ this.rotateCells_(/*topToBottom*/ false);
+ }
+
+ this.selectedTimeCell = previousTimeCell;
+ this.selectedTimeCell.scrollIntoViewIfNeeded(false);
break;
case 'ArrowDown':
- const nextTimeCell = this.selectedTimeCell.nextSibling;
- if (nextTimeCell) {
- this.selectedTimeCell = nextTimeCell;
- nextTimeCell.scrollIntoViewIfNeeded(false);
- } else if (this.columnType != TimeColumnType.AMPM) {
- // move from the last duplicated cell to the first cell
- // of the duplicated list.
- this.selectedTimeCell = this.middleTimeCell;
- this.selectedTimeCell.scrollIntoView(false);
+ const nextTimeCell = this.selectedTimeCell.nextSibling ?
+ this.selectedTimeCell.nextSibling :
+ this.firstElementChild;
+
+ // Ensure that we don't run out of cells ahead of the selected cell in
+ // the event that the scroll event handler can't keep up. This can
+ // happen e.g. if the user holds down the arrow key.
+ if (this.columnType_ !== TimeColumnType.AMPM &&
+ this.selectedTimeCell ===
+ this.cellsInLayoutOrder[this.cellsInLayoutOrder.length - 1]) {
+ this.rotateCells_(/*topToBottom*/ true);
}
- eventHandled = true;
+
+ this.selectedTimeCell = nextTimeCell;
+ this.selectedTimeCell.scrollIntoViewIfNeeded(false);
break;
case 'ArrowLeft':
const previousTimeColumn = this.previousSibling;
@@ -506,12 +687,14 @@ class TimeColumn extends HTMLUListElement {
}
break;
}
+ };
- if (eventHandled) {
- event.stopPropagation();
- event.preventDefault();
+ scrollToSelectedCell = (cell) => {
+ while(this.cellsInLayoutOrder[1] != this.selectedTimeCell) {
+ this.rotateCells_(/*topToBottom*/true);
}
- };
+ this.scrollTop = this.selectedTimeCell.offsetTop;
+ }
get selectedTimeCell() {
return this.selectedTimeCell_;
@@ -520,14 +703,21 @@ class TimeColumn extends HTMLUListElement {
set selectedTimeCell(timeCell) {
if (this.selectedTimeCell_) {
this.selectedTimeCell_.classList.remove('selected');
+ this.selectedTimeCell_.removeAttribute('aria-selected');
}
this.selectedTimeCell_ = timeCell;
+ this.setAttribute('aria-activedescendant', timeCell.id);
this.selectedTimeCell_.classList.add('selected');
+ this.selectedTimeCell_.setAttribute('aria-selected', 'true');
}
- get middleTimeCell() {
- return this.middleTimeCell_;
- }
+ resetToInitialValue = () => {
+ if (this.columnType_ == TimeColumnType.AMPM) {
+ this.selectedTimeCell = this.firstChild;
+ } else {
+ this.selectedTimeCell = this.initialTimeCell_;
+ }
+ };
get columnType() {
return this.columnType_;
@@ -546,65 +736,16 @@ class TimeCell extends HTMLLIElement {
this.className = TimeCell.ClassName;
this.textContent = localizedValue;
this.value = value;
- };
-}
-TimeCell.ClassName = 'time-cell';
-window.customElements.define('time-cell', TimeCell, {extends: 'li'});
-
-/**
- * SubmissionControls: Provides functionality to submit or discard a change.
- */
-class SubmissionControls extends HTMLElement {
- constructor(submitCallback, cancelCallback) {
- super();
-
- const padding = document.createElement('span');
- padding.setAttribute('id', 'submission-controls-padding');
- this.append(padding);
-
- this.className = SubmissionControls.ClassName;
-
- this.submitButton_ = new SubmissionButton(
- submitCallback,
- '<svg width="14" height="10" viewBox="0 0 14 10" fill="none" ' +
- 'xmlns="http://www.w3.org/2000/svg"><path d="M13.3516 ' +
- '1.35156L5 9.71094L0.648438 5.35156L1.35156 4.64844L5 ' +
- '8.28906L12.6484 0.648438L13.3516 1.35156Z" fill="black"/></svg>');
- this.cancelButton_ = new SubmissionButton(
- cancelCallback,
- '<svg width="14" height="14" viewBox="0 0 14 14" fill="none" ' +
- 'xmlns="http://www.w3.org/2000/svg"><path d="M7.71094 7L13.1016 ' +
- '12.3984L12.3984 13.1016L7 7.71094L1.60156 13.1016L0.898438 ' +
- '12.3984L6.28906 7L0.898438 1.60156L1.60156 0.898438L7 ' +
- '6.28906L12.3984 0.898438L13.1016 1.60156L7.71094 7Z" ' +
- 'fill="black"/></svg>');
- this.append(this.submitButton_, this.cancelButton_);
- }
- get submitButton() {
- return this.submitButton_;
- }
+ this.setAttribute('role', 'option');
+ this.id = TimeCell.getNextUniqueId();
+ };
- get cancelButton() {
- return this.cancelButton_;
+ static getNextUniqueId() {
+ return `timeCell${TimeCell.idCount++}`;
}
-}
-SubmissionControls.ClassName = 'submission-controls';
-window.customElements.define('submission-controls', SubmissionControls);
-
-/**
- * SubmissionButton: Button with a custom look that can be clicked for
- * a submission action.
- */
-class SubmissionButton extends HTMLButtonElement {
- constructor(clickCallback, htmlString) {
- super();
- this.className = SubmissionButton.ClassName;
- this.innerHTML = htmlString;
- this.addEventListener('click', clickCallback);
- }
+ static idCount = 0;
}
-SubmissionButton.ClassName = 'submission-button';
-window.customElements.define(
- 'submission-button', SubmissionButton, {extends: 'button'});
+TimeCell.ClassName = 'time-cell';
+window.customElements.define('time-cell', TimeCell, {extends: 'li'});
diff --git a/chromium/third_party/blink/renderer/core/html/forms/search_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/search_input_type.cc
index 5b964f18b85..74fff77ea69 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/search_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/search_input_type.cc
@@ -31,6 +31,9 @@
#include "third_party/blink/renderer/core/html/forms/search_input_type.h"
#include "third_party/blink/public/platform/task_type.h"
+#include "third_party/blink/renderer/core/css/css_property_names.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/dom/shadow_root.h"
#include "third_party/blink/renderer/core/events/keyboard_event.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
@@ -39,7 +42,6 @@
#include "third_party/blink/renderer/core/html/shadow/shadow_element_names.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/core/layout/layout_search_field.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
@@ -56,11 +58,6 @@ void SearchInputType::CountUsage() {
CountUsageIfVisible(WebFeature::kInputTypeSearch);
}
-LayoutObject* SearchInputType::CreateLayoutObject(const ComputedStyle&,
- LegacyLayout) const {
- return new LayoutSearchField(&GetElement());
-}
-
const AtomicString& SearchInputType::FormControlType() const {
return input_type_names::kSearch;
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/search_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/search_input_type.h
index 34a6f6b89df..dd1ff43512a 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/search_input_type.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/search_input_type.h
@@ -42,8 +42,6 @@ class SearchInputType final : public BaseTextInputType {
private:
void CountUsage() override;
- LayoutObject* CreateLayoutObject(const ComputedStyle&,
- LegacyLayout) const override;
const AtomicString& FormControlType() const override;
bool NeedsContainer() const override;
void CreateShadowSubtree() override;
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
new file mode 100644
index 00000000000..345cbeb2682
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/forms/select_type.cc
@@ -0,0 +1,1252 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2011 Apple Inc. All rights
+ * reserved.
+ * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved.
+ * (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "third_party/blink/renderer/core/html/forms/select_type.h"
+
+#include "build/build_config.h"
+#include "third_party/blink/public/strings/grit/blink_strings.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/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/events/gesture_event.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/frame/local_dom_window.h"
+#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/popup_menu.h"
+#include "third_party/blink/renderer/core/input/event_handler.h"
+#include "third_party/blink/renderer/core/input/input_device_capabilities.h"
+#include "third_party/blink/renderer/core/layout/layout_box.h"
+#include "third_party/blink/renderer/core/page/autoscroll_controller.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/page/spatial_navigation.h"
+#include "third_party/blink/renderer/core/paint/paint_layer.h"
+#include "third_party/blink/renderer/platform/text/platform_locale.h"
+#include "ui/base/ui_base_features.h"
+
+namespace blink {
+
+class PopupUpdater;
+
+namespace {
+
+HTMLOptionElement* EventTargetOption(const Event& event) {
+ return DynamicTo<HTMLOptionElement>(event.target()->ToNode());
+}
+
+} // anonymous namespace
+
+class MenuListSelectType final : public SelectType {
+ public:
+ explicit MenuListSelectType(HTMLSelectElement& select) : SelectType(select) {}
+ void Trace(Visitor* visitor) override;
+
+ bool DefaultEventHandler(const Event& event) override;
+ void DidSelectOption(HTMLOptionElement* element,
+ HTMLSelectElement::SelectOptionFlags flags,
+ bool should_update_popup) override;
+ void DidBlur() override;
+ void DidDetachLayoutTree() override;
+ void DidRecalcStyle(const StyleRecalcChange change) override;
+ void DidSetSuggestedOption(HTMLOptionElement* option) override;
+ void SaveLastSelection() override;
+
+ void UpdateTextStyle() override { UpdateTextStyleInternal(); }
+ void UpdateTextStyleAndContent() override;
+ HTMLOptionElement* OptionToBeShown() const override;
+ const ComputedStyle* OptionStyle() const override {
+ return option_style_.get();
+ }
+ void MaximumOptionWidthMightBeChanged() const override;
+
+ void ShowPopup() override;
+ void HidePopup() override;
+ void PopupDidHide() override;
+ bool PopupIsVisible() const override;
+ PopupMenu* PopupForTesting() const override;
+
+ void DidMutateSubtree();
+
+ private:
+ bool ShouldOpenPopupForKeyDownEvent(const KeyboardEvent& event);
+ bool ShouldOpenPopupForKeyPressEvent(const KeyboardEvent& event);
+ // Returns true if this function handled the event.
+ bool HandlePopupOpenKeyboardEvent();
+ void SetPopupIsVisible(bool popup_is_visible);
+ void DispatchEventsIfSelectedOptionChanged();
+ String UpdateTextStyleInternal();
+ void DidUpdateActiveOption(HTMLOptionElement* option);
+ void ObserveTreeMutation();
+ void UnobserveTreeMutation();
+
+ Member<PopupMenu> popup_;
+ Member<PopupUpdater> popup_updater_;
+ scoped_refptr<const ComputedStyle> option_style_;
+ int ax_menulist_last_active_index_ = -1;
+ bool has_updated_menulist_active_option_ = false;
+ bool popup_is_visible_ = false;
+ bool snav_arrow_key_selection_ = false;
+};
+
+void MenuListSelectType::Trace(Visitor* visitor) {
+ visitor->Trace(popup_);
+ visitor->Trace(popup_updater_);
+ SelectType::Trace(visitor);
+}
+
+bool MenuListSelectType::DefaultEventHandler(const Event& event) {
+ // We need to make the layout tree up-to-date to have GetLayoutObject() give
+ // the correct result below. An author event handler may have set display to
+ // some element to none which will cause a layout tree detach.
+ select_->GetDocument().UpdateStyleAndLayoutTree();
+
+ const auto* key_event = DynamicTo<KeyboardEvent>(event);
+ if (event.type() == event_type_names::kKeydown) {
+ if (!select_->GetLayoutObject() || !key_event)
+ return false;
+
+ if (ShouldOpenPopupForKeyDownEvent(*key_event))
+ return HandlePopupOpenKeyboardEvent();
+
+ // When using spatial navigation, we want to be able to navigate away
+ // from the select element when the user hits any of the arrow keys,
+ // instead of changing the selection.
+ if (IsSpatialNavigationEnabled(select_->GetDocument().GetFrame())) {
+ if (!snav_arrow_key_selection_)
+ return false;
+ }
+
+ // The key handling below shouldn't be used for non spatial navigation
+ // mode Mac
+ if (LayoutTheme::GetTheme().PopsMenuByArrowKeys() &&
+ !IsSpatialNavigationEnabled(select_->GetDocument().GetFrame()))
+ return false;
+
+ int ignore_modifiers = WebInputEvent::kShiftKey |
+ WebInputEvent::kControlKey | WebInputEvent::kAltKey |
+ WebInputEvent::kMetaKey;
+ if (key_event->GetModifiers() & ignore_modifiers)
+ return false;
+
+ const String& key = key_event->key();
+ bool handled = true;
+ HTMLOptionElement* option = select_->SelectedOption();
+ int list_index = option ? option->ListIndex() : -1;
+
+ if (key == "ArrowDown" || key == "ArrowRight") {
+ option = NextValidOption(list_index, kSkipForwards, 1);
+ } else if (key == "ArrowUp" || key == "ArrowLeft") {
+ option = NextValidOption(list_index, kSkipBackwards, 1);
+ } else if (key == "PageDown") {
+ option = NextValidOption(list_index, kSkipForwards, 3);
+ } else if (key == "PageUp") {
+ option = NextValidOption(list_index, kSkipBackwards, 3);
+ } else if (key == "Home") {
+ option = FirstSelectableOption();
+ } else if (key == "End") {
+ option = LastSelectableOption();
+ } else {
+ handled = false;
+ }
+
+ if (handled && option) {
+ select_->SelectOption(
+ option, HTMLSelectElement::kDeselectOtherOptionsFlag |
+ HTMLSelectElement::kMakeOptionDirtyFlag |
+ HTMLSelectElement::kDispatchInputAndChangeEventFlag);
+ }
+ return handled;
+ }
+
+ if (event.type() == event_type_names::kKeypress) {
+ if (!select_->GetLayoutObject() || !key_event)
+ return false;
+
+ int key_code = key_event->keyCode();
+ if (key_code == ' ' &&
+ IsSpatialNavigationEnabled(select_->GetDocument().GetFrame())) {
+ // Use space to toggle arrow key handling for selection change or
+ // spatial navigation.
+ snav_arrow_key_selection_ = !snav_arrow_key_selection_;
+ return true;
+ }
+
+ if (ShouldOpenPopupForKeyPressEvent(*key_event))
+ return HandlePopupOpenKeyboardEvent();
+
+ if (!LayoutTheme::GetTheme().PopsMenuByReturnKey() && key_code == '\r') {
+ if (HTMLFormElement* form = select_->Form())
+ form->SubmitImplicitly(event, false);
+ DispatchEventsIfSelectedOptionChanged();
+ return true;
+ }
+ return false;
+ }
+
+ const auto* mouse_event = DynamicTo<MouseEvent>(event);
+ if (event.type() == event_type_names::kMousedown && mouse_event &&
+ mouse_event->button() ==
+ static_cast<int16_t>(WebPointerProperties::Button::kLeft)) {
+ InputDeviceCapabilities* source_capabilities =
+ select_->GetDocument()
+ .domWindow()
+ ->GetInputDeviceCapabilities()
+ ->FiresTouchEvents(mouse_event->FromTouch());
+ select_->focus(FocusParams(SelectionBehaviorOnFocus::kRestore,
+ mojom::blink::FocusType::kNone,
+ source_capabilities));
+ if (select_->GetLayoutObject() && !will_be_destroyed_ &&
+ !select_->IsDisabledFormControl()) {
+ if (PopupIsVisible()) {
+ HidePopup();
+ } else {
+ // Save the selection so it can be compared to the new selection
+ // when we call onChange during selectOption, which gets called
+ // from selectOptionByPopup, which gets called after the user
+ // makes a selection from the menu.
+ SaveLastSelection();
+ // TODO(lanwei): Will check if we need to add
+ // InputDeviceCapabilities here when select menu list gets
+ // focus, see https://crbug.com/476530.
+ ShowPopup();
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+bool MenuListSelectType::ShouldOpenPopupForKeyDownEvent(
+ const KeyboardEvent& event) {
+ const String& key = event.key();
+ LayoutTheme& layout_theme = LayoutTheme::GetTheme();
+
+ if (IsSpatialNavigationEnabled(select_->GetDocument().GetFrame()))
+ return false;
+
+ return ((layout_theme.PopsMenuByArrowKeys() &&
+ (key == "ArrowDown" || key == "ArrowUp")) ||
+ (layout_theme.PopsMenuByAltDownUpOrF4Key() &&
+ (key == "ArrowDown" || key == "ArrowUp") && event.altKey()) ||
+ (layout_theme.PopsMenuByAltDownUpOrF4Key() &&
+ (!event.altKey() && !event.ctrlKey() && key == "F4")));
+}
+
+bool MenuListSelectType::ShouldOpenPopupForKeyPressEvent(
+ const KeyboardEvent& event) {
+ LayoutTheme& layout_theme = LayoutTheme::GetTheme();
+ int key_code = event.keyCode();
+
+ return ((layout_theme.PopsMenuBySpaceKey() && key_code == ' ' &&
+ !select_->type_ahead_.HasActiveSession(event)) ||
+ (layout_theme.PopsMenuByReturnKey() && key_code == '\r'));
+}
+
+bool MenuListSelectType::HandlePopupOpenKeyboardEvent() {
+ select_->focus();
+ // Calling focus() may cause us to lose our LayoutObject. Return true so
+ // that our caller doesn't process the event further, but don't set
+ // the event as handled.
+ if (!select_->GetLayoutObject() || will_be_destroyed_ ||
+ select_->IsDisabledFormControl())
+ return false;
+ // Save the selection so it can be compared to the new selection when
+ // dispatching change events during SelectOption, which gets called from
+ // SelectOptionByPopup, which gets called after the user makes a selection
+ // from the menu.
+ SaveLastSelection();
+ ShowPopup();
+ return true;
+}
+
+void MenuListSelectType::ShowPopup() {
+ if (PopupIsVisible())
+ return;
+ Document& document = select_->GetDocument();
+ if (document.GetPage()->GetChromeClient().HasOpenedPopup())
+ return;
+ if (!select_->GetLayoutObject())
+ return;
+ if (select_->VisibleBoundsInVisualViewport().IsEmpty())
+ return;
+
+ if (!popup_) {
+ popup_ = document.GetPage()->GetChromeClient().OpenPopupMenu(
+ *document.GetFrame(), *select_);
+ }
+ if (!popup_)
+ return;
+
+ SetPopupIsVisible(true);
+ ObserveTreeMutation();
+
+ popup_->Show();
+ if (AXObjectCache* cache = document.ExistingAXObjectCache())
+ cache->DidShowMenuListPopup(select_->GetLayoutObject());
+}
+
+void MenuListSelectType::HidePopup() {
+ if (popup_)
+ popup_->Hide();
+}
+
+void MenuListSelectType::PopupDidHide() {
+ SetPopupIsVisible(false);
+ UnobserveTreeMutation();
+ if (AXObjectCache* cache = select_->GetDocument().ExistingAXObjectCache()) {
+ if (auto* layout_object = select_->GetLayoutObject())
+ cache->DidHideMenuListPopup(layout_object);
+ }
+}
+
+bool MenuListSelectType::PopupIsVisible() const {
+ return popup_is_visible_;
+}
+
+void MenuListSelectType::SetPopupIsVisible(bool popup_is_visible) {
+ popup_is_visible_ = popup_is_visible;
+ if (!::features::IsFormControlsRefreshEnabled())
+ return;
+ if (auto* layout_object = select_->GetLayoutObject()) {
+ // Invalidate paint to ensure that the focus ring is updated.
+ layout_object->SetShouldDoFullPaintInvalidation();
+ }
+}
+
+PopupMenu* MenuListSelectType::PopupForTesting() const {
+ return popup_.Get();
+}
+
+void MenuListSelectType::DidSelectOption(
+ HTMLOptionElement* element,
+ HTMLSelectElement::SelectOptionFlags flags,
+ bool should_update_popup) {
+ // Need to update last_on_change_option_ before UpdateFromElement().
+ const bool should_dispatch_events =
+ (flags & HTMLSelectElement::kDispatchInputAndChangeEventFlag) &&
+ select_->last_on_change_option_ != element;
+ select_->last_on_change_option_ = element;
+
+ UpdateTextStyleAndContent();
+ // PopupMenu::UpdateFromElement() posts an O(N) task.
+ if (PopupIsVisible() && should_update_popup)
+ popup_->UpdateFromElement(PopupMenu::kBySelectionChange);
+
+ SelectType::DidSelectOption(element, flags, should_update_popup);
+
+ if (should_dispatch_events) {
+ select_->DispatchInputEvent();
+ select_->DispatchChangeEvent();
+ }
+ if (select_->GetLayoutObject()) {
+ // Need to check will_be_destroyed_ because event handlers might
+ // disassociate |this| and select_.
+ if (!will_be_destroyed_) {
+ // DidUpdateActiveOption() is O(N) because of HTMLOptionElement::index().
+ DidUpdateActiveOption(element);
+ }
+ }
+}
+
+void MenuListSelectType::DispatchEventsIfSelectedOptionChanged() {
+ HTMLOptionElement* selected_option = select_->SelectedOption();
+ if (select_->last_on_change_option_.Get() != selected_option) {
+ select_->last_on_change_option_ = selected_option;
+ select_->DispatchInputEvent();
+ select_->DispatchChangeEvent();
+ }
+}
+
+void MenuListSelectType::DidBlur() {
+ // We only need to fire change events here for menu lists, because we fire
+ // change events for list boxes whenever the selection change is actually
+ // made. This matches other browsers' behavior.
+ DispatchEventsIfSelectedOptionChanged();
+ if (PopupIsVisible())
+ HidePopup();
+}
+
+void MenuListSelectType::DidSetSuggestedOption(HTMLOptionElement*) {
+ UpdateTextStyleAndContent();
+ if (PopupIsVisible())
+ popup_->UpdateFromElement(PopupMenu::kBySelectionChange);
+}
+
+void MenuListSelectType::SaveLastSelection() {
+ select_->last_on_change_option_ = select_->SelectedOption();
+}
+
+void MenuListSelectType::DidDetachLayoutTree() {
+ if (popup_)
+ popup_->DisconnectClient();
+ SetPopupIsVisible(false);
+ popup_ = nullptr;
+ UnobserveTreeMutation();
+}
+
+void MenuListSelectType::DidRecalcStyle(const StyleRecalcChange change) {
+ if (change.ReattachLayoutTree())
+ return;
+ UpdateTextStyle();
+ if (PopupIsVisible())
+ popup_->UpdateFromElement(PopupMenu::kByStyleChange);
+}
+
+String MenuListSelectType::UpdateTextStyleInternal() {
+ HTMLOptionElement* option = OptionToBeShown();
+ String text = g_empty_string;
+ const ComputedStyle* option_style = nullptr;
+
+ if (select_->IsMultiple()) {
+ unsigned selected_count = 0;
+ HTMLOptionElement* selected_option_element = nullptr;
+ for (auto* const option : select_->GetOptionList()) {
+ if (option->Selected()) {
+ if (++selected_count == 1)
+ selected_option_element = option;
+ }
+ }
+
+ if (selected_count == 1) {
+ text = selected_option_element->TextIndentedToRespectGroupLabel();
+ option_style = selected_option_element->GetComputedStyle();
+ } else {
+ Locale& locale = select_->GetLocale();
+ String localized_number_string =
+ locale.ConvertToLocalizedNumber(String::Number(selected_count));
+ text = locale.QueryString(IDS_FORM_SELECT_MENU_LIST_TEXT,
+ localized_number_string);
+ DCHECK(!option_style);
+ }
+ } else {
+ if (option) {
+ text = option->TextIndentedToRespectGroupLabel();
+ option_style = option->GetComputedStyle();
+ }
+ }
+ option_style_ = option_style;
+
+ auto& inner_element = select_->InnerElement();
+ const ComputedStyle* inner_style = inner_element.GetComputedStyle();
+ if (inner_style && option_style &&
+ ((option_style->Direction() != inner_style->Direction() ||
+ option_style->GetUnicodeBidi() != inner_style->GetUnicodeBidi()))) {
+ scoped_refptr<ComputedStyle> cloned_style =
+ ComputedStyle::Clone(*inner_style);
+ cloned_style->SetDirection(option_style->Direction());
+ cloned_style->SetUnicodeBidi(option_style->GetUnicodeBidi());
+ if (auto* inner_layout = inner_element.GetLayoutObject()) {
+ inner_layout->SetModifiedStyleOutsideStyleRecalc(
+ std::move(cloned_style), LayoutObject::ApplyStyleChanges::kYes);
+ } else {
+ inner_element.SetComputedStyle(std::move(cloned_style));
+ }
+ }
+ if (select_->GetLayoutObject())
+ DidUpdateActiveOption(option);
+
+ return text.StripWhiteSpace();
+}
+
+void MenuListSelectType::UpdateTextStyleAndContent() {
+ select_->InnerElement().firstChild()->setNodeValue(UpdateTextStyleInternal());
+ if (auto* box = select_->GetLayoutBox()) {
+ if (auto* cache = select_->GetDocument().ExistingAXObjectCache())
+ cache->TextChanged(box);
+ }
+}
+
+void MenuListSelectType::DidUpdateActiveOption(HTMLOptionElement* option) {
+ Document& document = select_->GetDocument();
+ if (!document.ExistingAXObjectCache())
+ return;
+
+ int option_index = option ? option->index() : -1;
+ if (ax_menulist_last_active_index_ == option_index)
+ return;
+ ax_menulist_last_active_index_ = option_index;
+
+ // We skip sending accessiblity notifications for the very first option,
+ // otherwise we get extra focus and select events that are undesired.
+ if (!has_updated_menulist_active_option_) {
+ has_updated_menulist_active_option_ = true;
+ return;
+ }
+
+ document.ExistingAXObjectCache()->HandleUpdateActiveMenuOption(
+ select_->GetLayoutObject(), option_index);
+}
+
+HTMLOptionElement* MenuListSelectType::OptionToBeShown() const {
+ if (auto* option =
+ select_->OptionAtListIndex(select_->index_to_select_on_cancel_))
+ return option;
+ if (select_->suggested_option_)
+ return select_->suggested_option_;
+ // TODO(tkent): We should not call OptionToBeShown() in IsMultiple() case.
+ if (select_->IsMultiple())
+ return select_->SelectedOption();
+ DCHECK_EQ(select_->SelectedOption(), select_->last_on_change_option_);
+ return select_->last_on_change_option_;
+}
+
+void MenuListSelectType::MaximumOptionWidthMightBeChanged() const {
+ if (LayoutObject* layout_object = select_->GetLayoutObject()) {
+ layout_object->SetNeedsLayoutAndIntrinsicWidthsRecalc(
+ layout_invalidation_reason::kMenuOptionsChanged);
+ }
+}
+
+// PopupUpdater notifies updates of the specified SELECT element subtree to
+// a PopupMenu object.
+class PopupUpdater : public MutationObserver::Delegate {
+ public:
+ explicit PopupUpdater(MenuListSelectType& select_type,
+ HTMLSelectElement& select)
+ : select_type_(select_type),
+ select_(select),
+ observer_(MutationObserver::Create(this)) {
+ MutationObserverInit* init = MutationObserverInit::Create();
+ init->setAttributeOldValue(true);
+ init->setAttributes(true);
+ // Observe only attributes which affect popup content.
+ init->setAttributeFilter({"disabled", "label", "selected", "value"});
+ init->setCharacterData(true);
+ init->setCharacterDataOldValue(true);
+ init->setChildList(true);
+ init->setSubtree(true);
+ observer_->observe(select_, init, ASSERT_NO_EXCEPTION);
+ }
+
+ ExecutionContext* GetExecutionContext() const override {
+ return select_->GetExecutionContext();
+ }
+
+ void Deliver(const MutationRecordVector& records,
+ MutationObserver&) override {
+ // We disconnect the MutationObserver when a popup is closed. However
+ // MutationObserver can call back after disconnection.
+ if (!select_type_->PopupIsVisible())
+ return;
+ for (const auto& record : records) {
+ if (record->type() == "attributes") {
+ const auto& element = *To<Element>(record->target());
+ if (record->oldValue() == element.getAttribute(record->attributeName()))
+ continue;
+ } else if (record->type() == "characterData") {
+ if (record->oldValue() == record->target()->nodeValue())
+ continue;
+ }
+ select_type_->DidMutateSubtree();
+ return;
+ }
+ }
+
+ void Dispose() { observer_->disconnect(); }
+
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(select_type_);
+ visitor->Trace(select_);
+ visitor->Trace(observer_);
+ MutationObserver::Delegate::Trace(visitor);
+ }
+
+ private:
+ Member<MenuListSelectType> select_type_;
+ Member<HTMLSelectElement> select_;
+ Member<MutationObserver> observer_;
+};
+
+void MenuListSelectType::ObserveTreeMutation() {
+ DCHECK(!popup_updater_);
+ popup_updater_ = MakeGarbageCollected<PopupUpdater>(*this, *select_);
+}
+
+void MenuListSelectType::UnobserveTreeMutation() {
+ if (!popup_updater_)
+ return;
+ popup_updater_->Dispose();
+ popup_updater_ = nullptr;
+}
+
+void MenuListSelectType::DidMutateSubtree() {
+ DCHECK(PopupIsVisible());
+ DCHECK(popup_);
+ popup_->UpdateFromElement(PopupMenu::kByDOMChange);
+}
+
+// ============================================================================
+
+class ListBoxSelectType final : public SelectType {
+ public:
+ explicit ListBoxSelectType(HTMLSelectElement& select) : SelectType(select) {}
+ bool DefaultEventHandler(const Event& event) override;
+ void DidBlur() override;
+ void DidSetSuggestedOption(HTMLOptionElement* option) override;
+ void SaveLastSelection() override;
+ void SelectAll() override;
+ void SaveListboxActiveSelection() override;
+ void HandleMouseRelease() override;
+ void ListBoxOnChange() override;
+ void ClearLastOnChangeSelection() override;
+
+ private:
+ HTMLOptionElement* NextSelectableOptionPageAway(HTMLOptionElement*,
+ SkipDirection) const;
+ // Update :-internal-multi-select-focus state of selected OPTIONs.
+ void UpdateMultiSelectFocus();
+ void ToggleSelection(HTMLOptionElement& option);
+ enum class SelectionMode {
+ kDeselectOthers,
+ kRange,
+ kNotChangeOthers,
+ };
+ void UpdateSelectedState(HTMLOptionElement* clicked_option,
+ SelectionMode mode);
+ void UpdateListBoxSelection(bool deselect_other_options, bool scroll = true);
+
+ Vector<bool> cached_state_for_active_selection_;
+ Vector<bool> last_on_change_selection_;
+ bool is_in_non_contiguous_selection_ = false;
+ bool active_selection_state_ = false;
+};
+
+bool ListBoxSelectType::DefaultEventHandler(const Event& event) {
+ const auto* mouse_event = DynamicTo<MouseEvent>(event);
+ const auto* gesture_event = DynamicTo<GestureEvent>(event);
+ if (event.type() == event_type_names::kGesturetap && gesture_event) {
+ select_->focus();
+ // Calling focus() may cause us to lose our layoutObject or change the
+ // layoutObject type, in which case do not want to handle the event.
+ if (!select_->GetLayoutObject() || will_be_destroyed_)
+ return false;
+
+ // Convert to coords relative to the list box if needed.
+ if (HTMLOptionElement* option = EventTargetOption(*gesture_event)) {
+ if (!select_->IsDisabledFormControl()) {
+ UpdateSelectedState(option, gesture_event->shiftKey()
+ ? SelectionMode::kRange
+ : SelectionMode::kNotChangeOthers);
+ ListBoxOnChange();
+ }
+ return true;
+ }
+ return false;
+ }
+
+ if (event.type() == event_type_names::kMousedown && mouse_event &&
+ mouse_event->button() ==
+ static_cast<int16_t>(WebPointerProperties::Button::kLeft)) {
+ select_->focus();
+ // Calling focus() may cause us to lose our layoutObject, in which case
+ // do not want to handle the event.
+ if (!select_->GetLayoutObject() || will_be_destroyed_ ||
+ select_->IsDisabledFormControl())
+ return false;
+
+ // Convert to coords relative to the list box if needed.
+ if (HTMLOptionElement* option = EventTargetOption(*mouse_event)) {
+ if (!option->IsDisabledFormControl()) {
+#if defined(OS_MACOSX)
+ const bool meta_or_ctrl = mouse_event->metaKey();
+#else
+ const bool meta_or_ctrl = mouse_event->ctrlKey();
+#endif
+ UpdateSelectedState(option, mouse_event->shiftKey()
+ ? SelectionMode::kRange
+ : meta_or_ctrl
+ ? SelectionMode::kNotChangeOthers
+ : SelectionMode::kDeselectOthers);
+ }
+ if (LocalFrame* frame = select_->GetDocument().GetFrame())
+ frame->GetEventHandler().SetMouseDownMayStartAutoscroll();
+
+ return true;
+ }
+ return false;
+ }
+
+ if (event.type() == event_type_names::kMousemove && mouse_event) {
+ if (mouse_event->button() !=
+ static_cast<int16_t>(WebPointerProperties::Button::kLeft) ||
+ !mouse_event->ButtonDown())
+ return false;
+
+ if (auto* layout_object = select_->GetLayoutObject()) {
+ layout_object->GetFrameView()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kScroll);
+
+ if (Page* page = select_->GetDocument().GetPage()) {
+ page->GetAutoscrollController().StartAutoscrollForSelection(
+ layout_object);
+ }
+ }
+ // Mousedown didn't happen in this element.
+ if (last_on_change_selection_.IsEmpty())
+ return false;
+
+ if (HTMLOptionElement* option = EventTargetOption(*mouse_event)) {
+ if (!select_->IsDisabledFormControl()) {
+ if (select_->is_multiple_) {
+ // Only extend selection if there is something selected.
+ if (!select_->active_selection_anchor_)
+ return false;
+
+ select_->SetActiveSelectionEnd(option);
+ UpdateListBoxSelection(false);
+ } else {
+ select_->SetActiveSelectionAnchor(option);
+ select_->SetActiveSelectionEnd(option);
+ UpdateListBoxSelection(true);
+ }
+ }
+ }
+ return false;
+ }
+
+ if (event.type() == event_type_names::kMouseup && mouse_event &&
+ mouse_event->button() ==
+ static_cast<int16_t>(WebPointerProperties::Button::kLeft) &&
+ select_->GetLayoutObject()) {
+ auto* page = select_->GetDocument().GetPage();
+ if (page && page->GetAutoscrollController().AutoscrollInProgressFor(
+ select_->GetLayoutBox()))
+ page->GetAutoscrollController().StopAutoscroll();
+ else
+ HandleMouseRelease();
+ return false;
+ }
+
+ if (event.type() == event_type_names::kKeydown) {
+ const auto* keyboard_event = DynamicTo<KeyboardEvent>(event);
+ if (!keyboard_event)
+ return false;
+ const String& key = keyboard_event->key();
+
+ bool handled = false;
+ HTMLOptionElement* end_option = nullptr;
+ if (!select_->active_selection_end_) {
+ // Initialize the end index
+ if (key == "ArrowDown" || key == "PageDown") {
+ HTMLOptionElement* start_option = select_->LastSelectedOption();
+ handled = true;
+ if (key == "ArrowDown") {
+ end_option = NextSelectableOption(start_option);
+ } else {
+ end_option =
+ NextSelectableOptionPageAway(start_option, kSkipForwards);
+ }
+ } else if (key == "ArrowUp" || key == "PageUp") {
+ HTMLOptionElement* start_option = select_->SelectedOption();
+ handled = true;
+ if (key == "ArrowUp") {
+ end_option = PreviousSelectableOption(start_option);
+ } else {
+ end_option =
+ NextSelectableOptionPageAway(start_option, kSkipBackwards);
+ }
+ }
+ } else {
+ // Set the end index based on the current end index.
+ if (key == "ArrowDown") {
+ end_option = NextSelectableOption(select_->active_selection_end_.Get());
+ handled = true;
+ } else if (key == "ArrowUp") {
+ end_option =
+ PreviousSelectableOption(select_->active_selection_end_.Get());
+ handled = true;
+ } else if (key == "PageDown") {
+ end_option = NextSelectableOptionPageAway(
+ select_->active_selection_end_.Get(), kSkipForwards);
+ handled = true;
+ } else if (key == "PageUp") {
+ end_option = NextSelectableOptionPageAway(
+ select_->active_selection_end_.Get(), kSkipBackwards);
+ handled = true;
+ }
+ }
+ if (key == "Home") {
+ end_option = FirstSelectableOption();
+ handled = true;
+ } else if (key == "End") {
+ end_option = LastSelectableOption();
+ handled = true;
+ }
+
+ if (IsSpatialNavigationEnabled(select_->GetDocument().GetFrame())) {
+ // Check if the selection moves to the boundary.
+ if (key == "ArrowLeft" || key == "ArrowRight" ||
+ ((key == "ArrowDown" || key == "ArrowUp") &&
+ end_option == select_->active_selection_end_))
+ return false;
+ }
+
+ bool is_control_key = false;
+#if defined(OS_MACOSX)
+ is_control_key = keyboard_event->metaKey();
+#else
+ is_control_key = keyboard_event->ctrlKey();
+#endif
+
+ if (select_->is_multiple_ && keyboard_event->keyCode() == ' ' &&
+ is_control_key && select_->active_selection_end_) {
+ // Use ctrl+space to toggle selection change.
+ ToggleSelection(*select_->active_selection_end_);
+ return true;
+ }
+
+ if (end_option && handled) {
+ // Save the selection so it can be compared to the new selection
+ // when dispatching change events immediately after making the new
+ // selection.
+ SaveLastSelection();
+
+ select_->SetActiveSelectionEnd(end_option);
+
+ is_in_non_contiguous_selection_ = select_->is_multiple_ && is_control_key;
+ bool select_new_item =
+ !select_->is_multiple_ || keyboard_event->shiftKey() ||
+ (!IsSpatialNavigationEnabled(select_->GetDocument().GetFrame()) &&
+ !is_in_non_contiguous_selection_);
+ if (select_new_item)
+ active_selection_state_ = true;
+ // If the anchor is uninitialized, or if we're going to deselect all
+ // 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 (deselect_others)
+ select_->DeselectItemsWithoutValidation();
+ select_->SetActiveSelectionAnchor(select_->active_selection_end_.Get());
+ }
+
+ select_->ScrollToOption(end_option);
+ if (select_new_item || is_in_non_contiguous_selection_) {
+ if (select_new_item) {
+ UpdateListBoxSelection(deselect_others);
+ ListBoxOnChange();
+ }
+ UpdateMultiSelectFocus();
+ } else {
+ select_->ScrollToSelection();
+ }
+
+ return true;
+ }
+ return false;
+ }
+
+ if (event.type() == event_type_names::kKeypress) {
+ auto* keyboard_event = DynamicTo<KeyboardEvent>(event);
+ if (!keyboard_event)
+ return false;
+ int key_code = keyboard_event->keyCode();
+
+ if (key_code == '\r') {
+ if (HTMLFormElement* form = select_->Form())
+ form->SubmitImplicitly(event, false);
+ return true;
+ } else if (select_->is_multiple_ && key_code == ' ' &&
+ (IsSpatialNavigationEnabled(select_->GetDocument().GetFrame()) ||
+ is_in_non_contiguous_selection_)) {
+ HTMLOptionElement* option = select_->active_selection_end_;
+ // If there's no active selection,
+ // act as if "ArrowDown" had been pressed.
+ if (!option)
+ option = NextSelectableOption(select_->LastSelectedOption());
+ if (option) {
+ // Use space to toggle selection change.
+ ToggleSelection(*option);
+ return true;
+ }
+ }
+ return false;
+ }
+ return false;
+}
+
+void ListBoxSelectType::DidBlur() {
+ ClearLastOnChangeSelection();
+}
+
+void ListBoxSelectType::DidSetSuggestedOption(HTMLOptionElement* option) {
+ if (select_->GetLayoutObject())
+ select_->ScrollToOption(option);
+}
+
+void ListBoxSelectType::SaveLastSelection() {
+ last_on_change_selection_.clear();
+ for (auto& element : select_->GetListItems()) {
+ auto* option_element = DynamicTo<HTMLOptionElement>(element.Get());
+ last_on_change_selection_.push_back(option_element &&
+ option_element->Selected());
+ }
+}
+
+void ListBoxSelectType::UpdateMultiSelectFocus() {
+ if (!select_->is_multiple_)
+ return;
+
+ 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_;
+ option->SetMultiSelectFocusedState(is_focused);
+ }
+ select_->ScrollToSelection();
+}
+
+void ListBoxSelectType::SelectAll() {
+ if (!select_->GetLayoutObject() || !select_->is_multiple_)
+ return;
+
+ // Save the selection so it can be compared to the new selectAll selection
+ // when dispatching change events.
+ SaveLastSelection();
+
+ active_selection_state_ = true;
+ select_->SetActiveSelectionAnchor(NextSelectableOption(nullptr));
+ select_->SetActiveSelectionEnd(PreviousSelectableOption(nullptr));
+
+ UpdateListBoxSelection(false, false);
+ ListBoxOnChange();
+ select_->SetNeedsValidityCheck();
+}
+
+// Returns the index of the next valid item one page away from |start_option|
+// in direction |direction|.
+HTMLOptionElement* ListBoxSelectType::NextSelectableOptionPageAway(
+ HTMLOptionElement* start_option,
+ SkipDirection direction) const {
+ const auto& items = select_->GetListItems();
+ // -1 so we still show context.
+ int page_size = select_->ListBoxSize() - 1;
+
+ // One page away, but not outside valid bounds.
+ // If there is a valid option item one page away, the index is chosen.
+ // If there is no exact one page away valid option, returns start_index or
+ // the most far index.
+ int start_index = start_option ? start_option->ListIndex() : -1;
+ int edge_index = (direction == kSkipForwards) ? 0 : (items.size() - 1);
+ int skip_amount =
+ page_size +
+ ((direction == kSkipForwards) ? start_index : (edge_index - start_index));
+ return NextValidOption(edge_index, direction, skip_amount);
+}
+
+void ListBoxSelectType::ToggleSelection(HTMLOptionElement& option) {
+ active_selection_state_ = !active_selection_state_;
+ UpdateSelectedState(&option, SelectionMode::kNotChangeOthers);
+ ListBoxOnChange();
+}
+
+void ListBoxSelectType::UpdateSelectedState(HTMLOptionElement* clicked_option,
+ SelectionMode mode) {
+ DCHECK(clicked_option);
+ // Save the selection so it can be compared to the new selection when
+ // dispatching change events during mouseup, or after autoscroll finishes.
+ SaveLastSelection();
+
+ active_selection_state_ = true;
+
+ if (!select_->is_multiple_)
+ mode = SelectionMode::kDeselectOthers;
+
+ // Keep track of whether an active selection (like during drag selection),
+ // should select or deselect.
+ if (clicked_option->Selected() && mode == SelectionMode::kNotChangeOthers) {
+ active_selection_state_ = false;
+ clicked_option->SetSelectedState(false);
+ clicked_option->SetDirty(true);
+ }
+
+ // If we're not in any special multiple selection mode, then deselect all
+ // other items, excluding the clicked OPTION. If no option was clicked, then
+ // this will deselect all items in the list.
+ if (mode == SelectionMode::kDeselectOthers)
+ select_->DeselectItemsWithoutValidation(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());
+
+ // Set the selection state of the clicked OPTION.
+ if (!clicked_option->IsDisabledFormControl()) {
+ clicked_option->SetSelectedState(true);
+ clicked_option->SetDirty(true);
+ }
+
+ // 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);
+
+ select_->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_;
+ 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);
+ const int end = std::max(anchor_index, end_index);
+
+ int i = 0;
+ for (auto* const option : select_->GetOptionList()) {
+ if (option->IsDisabledFormControl() || !option->GetLayoutObject()) {
+ ++i;
+ continue;
+ }
+ if (i >= start && i <= end) {
+ option->SetSelectedState(active_selection_state_);
+ option->SetDirty(true);
+ } else if (deselect_other_options ||
+ i >= static_cast<int>(
+ cached_state_for_active_selection_.size())) {
+ option->SetSelectedState(false);
+ option->SetDirty(true);
+ } else {
+ option->SetSelectedState(cached_state_for_active_selection_[i]);
+ }
+ ++i;
+ }
+
+ UpdateMultiSelectFocus();
+ select_->SetNeedsValidityCheck();
+ if (scroll)
+ select_->ScrollToSelection();
+ select_->NotifyFormStateChanged();
+}
+
+void ListBoxSelectType::SaveListboxActiveSelection() {
+ // Cache the selection state so we can restore the old selection as the new
+ // selection pivots around this anchor index.
+ // Example:
+ // 1. Press the mouse button on the second OPTION
+ // active_selection_anchor_ points the second OPTION.
+ // 2. Drag the mouse pointer onto the fifth OPTION
+ // active_selection_end_ points the fifth OPTION, OPTIONs at 1-4 indices
+ // are selected.
+ // 3. Drag the mouse pointer onto the fourth OPTION
+ // active_selection_end_ points the fourth OPTION, OPTIONs at 1-3 indices
+ // are selected.
+ // UpdateListBoxSelection needs to clear selection of the fifth OPTION.
+ cached_state_for_active_selection_.resize(0);
+ for (auto* const option : select_->GetOptionList()) {
+ cached_state_for_active_selection_.push_back(option->Selected());
+ }
+}
+
+void ListBoxSelectType::HandleMouseRelease() {
+ // We didn't start this click/drag on any options.
+ if (last_on_change_selection_.IsEmpty())
+ return;
+ ListBoxOnChange();
+}
+
+void ListBoxSelectType::ListBoxOnChange() {
+ const auto& items = select_->GetListItems();
+
+ // If the cached selection list is empty, or the size has changed, then fire
+ // 'change' event, and return early.
+ // FIXME: Why? This looks unreasonable.
+ if (last_on_change_selection_.IsEmpty() ||
+ last_on_change_selection_.size() != items.size()) {
+ select_->DispatchChangeEvent();
+ return;
+ }
+
+ // Update last_on_change_selection_ and fire a 'change' event.
+ bool fire_on_change = false;
+ for (unsigned i = 0; i < items.size(); ++i) {
+ HTMLElement* element = items[i];
+ auto* option_element = DynamicTo<HTMLOptionElement>(element);
+ bool selected = option_element && option_element->Selected();
+ if (selected != last_on_change_selection_[i])
+ fire_on_change = true;
+ last_on_change_selection_[i] = selected;
+ }
+
+ if (fire_on_change) {
+ select_->DispatchInputEvent();
+ select_->DispatchChangeEvent();
+ }
+}
+
+void ListBoxSelectType::ClearLastOnChangeSelection() {
+ last_on_change_selection_.clear();
+}
+
+// ============================================================================
+
+SelectType::SelectType(HTMLSelectElement& select) : select_(select) {}
+
+SelectType* SelectType::Create(HTMLSelectElement& select) {
+ if (select.UsesMenuList())
+ return MakeGarbageCollected<MenuListSelectType>(select);
+ else
+ return MakeGarbageCollected<ListBoxSelectType>(select);
+}
+
+void SelectType::WillBeDestroyed() {
+ will_be_destroyed_ = true;
+}
+
+void SelectType::Trace(Visitor* visitor) {
+ visitor->Trace(select_);
+}
+
+void SelectType::DidSelectOption(HTMLOptionElement*,
+ HTMLSelectElement::SelectOptionFlags,
+ bool) {
+ select_->ScrollToSelection();
+ select_->SetNeedsValidityCheck();
+}
+
+void SelectType::DidDetachLayoutTree() {}
+
+void SelectType::DidRecalcStyle(const StyleRecalcChange) {}
+
+void SelectType::UpdateTextStyle() {}
+
+void SelectType::UpdateTextStyleAndContent() {}
+
+HTMLOptionElement* SelectType::OptionToBeShown() const {
+ NOTREACHED();
+ return nullptr;
+}
+
+const ComputedStyle* SelectType::OptionStyle() const {
+ NOTREACHED();
+ return nullptr;
+}
+
+void SelectType::MaximumOptionWidthMightBeChanged() const {}
+
+void SelectType::SelectAll() {
+ NOTREACHED();
+}
+
+void SelectType::SaveListboxActiveSelection() {}
+
+void SelectType::HandleMouseRelease() {}
+
+void SelectType::ListBoxOnChange() {}
+
+void SelectType::ClearLastOnChangeSelection() {}
+
+void SelectType::ShowPopup() {
+ NOTREACHED();
+}
+
+void SelectType::HidePopup() {
+ NOTREACHED();
+}
+
+void SelectType::PopupDidHide() {
+ NOTREACHED();
+}
+
+bool SelectType::PopupIsVisible() const {
+ return false;
+}
+
+PopupMenu* SelectType::PopupForTesting() const {
+ NOTREACHED();
+ return nullptr;
+}
+
+// Returns the 1st valid OPTION |skip| items from |list_index| in direction
+// |direction| if there is one.
+// Otherwise, it returns the valid OPTION closest to that boundary which is past
+// |list_index| if there is one.
+// Otherwise, it returns nullptr.
+// Valid means that it is enabled and visible.
+HTMLOptionElement* SelectType::NextValidOption(int list_index,
+ SkipDirection direction,
+ int skip) const {
+ DCHECK(direction == kSkipBackwards || direction == kSkipForwards);
+ const auto& list_items = select_->GetListItems();
+ HTMLOptionElement* last_good_option = nullptr;
+ int size = list_items.size();
+ for (list_index += direction; list_index >= 0 && list_index < size;
+ list_index += direction) {
+ --skip;
+ HTMLElement* element = list_items[list_index];
+ auto* option_element = DynamicTo<HTMLOptionElement>(element);
+ if (!option_element)
+ continue;
+ if (option_element->IsDisplayNone())
+ continue;
+ if (element->IsDisabledFormControl())
+ continue;
+ if (!select_->UsesMenuList() && !element->GetLayoutObject())
+ continue;
+ last_good_option = option_element;
+ if (skip <= 0)
+ break;
+ }
+ return last_good_option;
+}
+
+HTMLOptionElement* SelectType::NextSelectableOption(
+ HTMLOptionElement* start_option) const {
+ return NextValidOption(start_option ? start_option->ListIndex() : -1,
+ kSkipForwards, 1);
+}
+
+HTMLOptionElement* SelectType::PreviousSelectableOption(
+ HTMLOptionElement* start_option) const {
+ return NextValidOption(
+ start_option ? start_option->ListIndex() : select_->GetListItems().size(),
+ kSkipBackwards, 1);
+}
+
+HTMLOptionElement* SelectType::FirstSelectableOption() const {
+ return NextValidOption(-1, kSkipForwards, 1);
+}
+
+HTMLOptionElement* SelectType::LastSelectableOption() const {
+ return NextValidOption(select_->GetListItems().size(), kSkipBackwards, 1);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..2ce4e1bcb56
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/forms/select_type.h
@@ -0,0 +1,84 @@
+// 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_FORMS_SELECT_TYPE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_SELECT_TYPE_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/html/forms/html_select_element.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+
+namespace blink {
+
+// SelectType class is an abstraction of the MenuList behavior and the ListBox
+// behavior of HTMLSelectElement.
+class SelectType : public GarbageCollected<SelectType> {
+ public:
+ // Creates an instance of a SelectType subclass depending on the current mode
+ // of |select|.
+ static SelectType* Create(HTMLSelectElement& select);
+ void WillBeDestroyed();
+ virtual void Trace(Visitor* visitor);
+
+ // 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);
+
+ virtual void DidBlur() = 0;
+ virtual void DidDetachLayoutTree();
+ virtual void DidRecalcStyle(const StyleRecalcChange change);
+ virtual void DidSetSuggestedOption(HTMLOptionElement* option) = 0;
+ virtual void SaveLastSelection() = 0;
+
+ // Update style of text in the CSS box on style or selected OPTION change.
+ virtual void UpdateTextStyle();
+
+ // Update style of text in the CSS box on style or selected OPTION change,
+ // and update the text.
+ virtual void UpdateTextStyleAndContent();
+
+ virtual HTMLOptionElement* OptionToBeShown() const;
+ virtual const ComputedStyle* OptionStyle() const;
+ virtual void MaximumOptionWidthMightBeChanged() const;
+
+ virtual void SelectAll();
+ virtual void SaveListboxActiveSelection();
+ virtual void HandleMouseRelease();
+ virtual void ListBoxOnChange();
+ // Clear OPTION selection information saved by SaveLastSelection().
+ // This is for ListBoxes.
+ virtual void ClearLastOnChangeSelection();
+
+ virtual void ShowPopup();
+ virtual void HidePopup();
+ virtual void PopupDidHide();
+ virtual bool PopupIsVisible() const;
+ virtual PopupMenu* PopupForTesting() const;
+
+ enum SkipDirection { kSkipBackwards = -1, kSkipForwards = 1 };
+ CORE_EXPORT HTMLOptionElement* NextSelectableOption(HTMLOptionElement*) const;
+ CORE_EXPORT HTMLOptionElement* PreviousSelectableOption(
+ HTMLOptionElement*) const;
+ CORE_EXPORT HTMLOptionElement* FirstSelectableOption() const;
+ CORE_EXPORT HTMLOptionElement* LastSelectableOption() const;
+
+ protected:
+ explicit SelectType(HTMLSelectElement& select);
+ HTMLOptionElement* NextValidOption(int list_index,
+ SkipDirection direction,
+ int skip) const;
+
+ const Member<HTMLSelectElement> select_;
+ bool will_be_destroyed_ = false;
+
+ private:
+ SelectType(const SelectType&) = delete;
+ SelectType& operator=(const SelectType&) = delete;
+};
+
+} // namespace blink
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_SELECT_TYPE_H_
diff --git a/chromium/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc b/chromium/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc
index a1cd68864ae..4c987d13ff6 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc
@@ -47,13 +47,10 @@
#include "third_party/blink/renderer/core/layout/layout_object_factory.h"
#include "third_party/blink/renderer/core/layout/layout_slider_container.h"
#include "third_party/blink/renderer/core/layout/layout_theme.h"
+#include "ui/base/ui_base_features.h"
namespace blink {
-inline static bool HasVerticalAppearance(HTMLInputElement* input) {
- return input->ComputedStyleRef().EffectiveAppearance() == kSliderVerticalPart;
-}
-
SliderThumbElement::SliderThumbElement(Document& document)
: HTMLDivElement(document), in_drag_mode_(false) {
SetHasCustomStyleCallbacks();
@@ -67,7 +64,7 @@ void SliderThumbElement::SetPositionFromValue() {
if (GetLayoutObject()) {
GetLayoutObject()->SetNeedsLayoutAndFullPaintInvalidation(
layout_invalidation_reason::kSliderValueChanged);
- if (RuntimeEnabledFeatures::FormControlsRefreshEnabled()) {
+ if (features::IsFormControlsRefreshEnabled()) {
HTMLInputElement* input(HostInput());
if (input && input->GetLayoutObject()) {
// the slider track selected value needs to be updated.
@@ -116,7 +113,7 @@ void SliderThumbElement::SetPositionFromPoint(const LayoutPoint& point) {
PhysicalOffset point_in_track =
track_box->AbsoluteToLocalPoint(PhysicalOffsetToBeNoop(point));
- bool is_vertical = HasVerticalAppearance(input);
+ const bool is_vertical = !thumb_box->StyleRef().IsHorizontalWritingMode();
bool is_left_to_right_direction =
thumb_box->StyleRef().IsLeftToRightDirection();
LayoutUnit track_size;
@@ -199,13 +196,13 @@ void SliderThumbElement::StopDragging() {
}
void SliderThumbElement::DefaultEventHandler(Event& event) {
- if (event.IsPointerEvent() &&
+ if (IsA<PointerEvent>(event) &&
event.type() == event_type_names::kLostpointercapture) {
StopDragging();
return;
}
- if (!event.IsMouseEvent()) {
+ if (!IsA<MouseEvent>(event)) {
HTMLDivElement::DefaultEventHandler(event);
return;
}
@@ -220,7 +217,7 @@ void SliderThumbElement::DefaultEventHandler(Event& event) {
return;
}
- auto& mouse_event = ToMouseEvent(event);
+ auto& mouse_event = To<MouseEvent>(event);
bool is_left_button =
mouse_event.button() ==
static_cast<int16_t>(WebPointerProperties::Button::kLeft);
@@ -348,8 +345,8 @@ LayoutObject* SliderContainerElement::CreateLayoutObject(const ComputedStyle&,
}
void SliderContainerElement::DefaultEventHandler(Event& event) {
- if (event.IsTouchEvent()) {
- HandleTouchEvent(ToTouchEvent(&event));
+ if (auto* touch_event = DynamicTo<TouchEvent>(event)) {
+ HandleTouchEvent(touch_event);
return;
}
}
@@ -430,10 +427,9 @@ bool SliderContainerElement::CanSlide() {
}
}
}
- if ((sliding_direction_ == kVertical &&
- slider_style->EffectiveAppearance() == kSliderHorizontalPart) ||
- (sliding_direction_ == kHorizontal &&
- slider_style->EffectiveAppearance() == kSliderVerticalPart)) {
+ bool is_horizontal = GetComputedStyle()->IsHorizontalWritingMode();
+ if ((sliding_direction_ == kVertical && is_horizontal) ||
+ (sliding_direction_ == kHorizontal && !is_horizontal)) {
return false;
}
return true;
@@ -486,14 +482,4 @@ void SliderContainerElement::RemoveAllEventListeners() {
has_touch_event_handler_ = false;
}
-scoped_refptr<ComputedStyle>
-SliderContainerElement::CustomStyleForLayoutObject() {
- HTMLInputElement* input = HostInput();
- DCHECK(input);
- scoped_refptr<ComputedStyle> style = OriginalStyleForLayoutObject();
- style->SetFlexDirection(HasVerticalAppearance(input) ? EFlexDirection::kColumn
- : EFlexDirection::kRow);
- return style;
-}
-
} // namespace blink
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 82977b7378d..cc4dd4d78f1 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
@@ -104,7 +104,6 @@ class SliderContainerElement final : public HTMLDivElement {
private:
LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override;
- scoped_refptr<ComputedStyle> CustomStyleForLayoutObject() final;
const AtomicString& ShadowPseudoId() const override;
Direction GetDirection(LayoutPoint&, LayoutPoint&);
bool CanSlide();
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 7dbfef38a01..24ea89a2682 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
@@ -62,7 +62,8 @@ void SpinButtonElement::DetachLayoutTree(bool performing_reattach) {
}
void SpinButtonElement::DefaultEventHandler(Event& event) {
- if (!event.IsMouseEvent()) {
+ auto* mouse_event = DynamicTo<MouseEvent>(event);
+ if (!mouse_event) {
if (!event.DefaultHandled())
HTMLDivElement::DefaultEventHandler(event);
return;
@@ -81,11 +82,10 @@ void SpinButtonElement::DefaultEventHandler(Event& event) {
return;
}
- auto& mouse_event = ToMouseEvent(event);
IntPoint local = RoundedIntPoint(box->AbsoluteToLocalFloatPoint(
- FloatPoint(mouse_event.AbsoluteLocation())));
- if (mouse_event.type() == event_type_names::kMousedown &&
- mouse_event.button() ==
+ FloatPoint(mouse_event->AbsoluteLocation())));
+ if (mouse_event->type() == event_type_names::kMousedown &&
+ mouse_event->button() ==
static_cast<int16_t>(WebPointerProperties::Button::kLeft)) {
if (box->PixelSnappedBorderBoxRect().Contains(local)) {
if (spin_button_owner_)
@@ -114,8 +114,8 @@ void SpinButtonElement::DefaultEventHandler(Event& event) {
}
event.SetDefaultHandled();
}
- } else if (mouse_event.type() == event_type_names::kMouseup &&
- mouse_event.button() ==
+ } else if (mouse_event->type() == event_type_names::kMouseup &&
+ mouse_event->button() ==
static_cast<int16_t>(WebPointerProperties::Button::kLeft)) {
ReleaseCapture();
} else if (event.type() == event_type_names::kMousemove) {
@@ -152,7 +152,7 @@ void SpinButtonElement::ForwardEvent(Event& event) {
if (!spin_button_owner_->ShouldSpinButtonRespondToWheelEvents())
return;
- DoStepAction(ToWheelEvent(event).wheelDeltaY());
+ DoStepAction(To<WheelEvent>(event).wheelDeltaY());
event.SetDefaultHandled();
}
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 d8ea6ddb19f..b4bcb5d9ebc 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
@@ -34,7 +34,8 @@ StepRange::StepRange()
step_(1),
step_base_(0),
has_step_(false),
- has_range_limitations_(false) {}
+ has_range_limitations_(false),
+ supports_reversed_range_(false) {}
StepRange::StepRange(const StepRange& step_range) = default;
@@ -42,6 +43,7 @@ StepRange::StepRange(const Decimal& step_base,
const Decimal& minimum,
const Decimal& maximum,
bool has_range_limitations,
+ bool supports_reversed_range,
const Decimal& step,
const StepDescription& step_description)
: maximum_(maximum),
@@ -50,7 +52,8 @@ StepRange::StepRange(const Decimal& step_base,
step_base_(step_base.IsFinite() ? step_base : 1),
step_description_(step_description),
has_step_(step.IsFinite()),
- has_range_limitations_(has_range_limitations) {
+ has_range_limitations_(has_range_limitations),
+ supports_reversed_range_(supports_reversed_range) {
DCHECK(maximum_.IsFinite());
DCHECK(minimum_.IsFinite());
DCHECK(step_.IsFinite());
@@ -100,7 +103,7 @@ Decimal StepRange::ParseStep(AnyStepHandling any_step_handling,
if (step_string.IsEmpty())
return step_description.DefaultValue();
- if (DeprecatedEqualIgnoringCase(step_string, "any")) {
+ if (EqualIgnoringASCIICase(step_string, "any")) {
switch (any_step_handling) {
case kRejectAny:
return Decimal::Nan();
@@ -183,4 +186,9 @@ Decimal StepRange::StepSnappedMaximum() const {
return aligned_maximum;
}
+// https://html.spec.whatwg.org/C/#has-a-reversed-range
+bool StepRange::HasReversedRange() const {
+ return supports_reversed_range_ && Maximum() < Minimum();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/forms/step_range.h b/chromium/third_party/blink/renderer/core/html/forms/step_range.h
index 796a496c438..70f2005da08 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/step_range.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/step_range.h
@@ -74,6 +74,7 @@ class CORE_EXPORT StepRange {
const Decimal& minimum,
const Decimal& maximum,
bool has_range_limitations,
+ bool supports_reversed_range,
const Decimal& step,
const StepDescription&);
@@ -85,6 +86,8 @@ class CORE_EXPORT StepRange {
Decimal Minimum() const { return minimum_; }
// https://html.spec.whatwg.org/C/#have-range-limitations
bool HasRangeLimitations() const { return has_range_limitations_; }
+ // https://html.spec.whatwg.org/C/#has-a-reversed-range
+ bool HasReversedRange() const;
static Decimal ParseStep(AnyStepHandling,
const StepDescription&,
const String&);
@@ -123,6 +126,7 @@ class CORE_EXPORT StepRange {
const StepDescription step_description_;
const bool has_step_;
const bool has_range_limitations_;
+ const bool supports_reversed_range_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/forms/step_range_test.cc b/chromium/third_party/blink/renderer/core/html/forms/step_range_test.cc
index eddc58b9b28..9916c50d8b7 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/step_range_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/step_range_test.cc
@@ -11,7 +11,8 @@ namespace blink {
TEST(StepRangeTest, ClampValueWithOutStepMatchedValue) {
// <input type=range value=200 min=0 max=100 step=1000>
StepRange step_range(Decimal(200), Decimal(0), Decimal(100), true,
- Decimal(1000), StepRange::StepDescription());
+ /*has_reversed_range=*/false, Decimal(1000),
+ StepRange::StepDescription());
EXPECT_EQ(Decimal(100), step_range.ClampValue(Decimal(200)));
EXPECT_EQ(Decimal(0), step_range.ClampValue(Decimal(-100)));
@@ -20,7 +21,8 @@ TEST(StepRangeTest, ClampValueWithOutStepMatchedValue) {
TEST(StepRangeTest, StepSnappedMaximum) {
// <input type=number value="1110" max=100 step="20">
StepRange step_range(Decimal::FromDouble(1110), Decimal(0), Decimal(100),
- true, Decimal(20), StepRange::StepDescription());
+ true, /*has_reversed_range=*/false, Decimal(20),
+ StepRange::StepDescription());
EXPECT_EQ(Decimal(90), step_range.StepSnappedMaximum());
// crbug.com/617809
@@ -28,9 +30,34 @@ TEST(StepRangeTest, StepSnappedMaximum) {
// value="8624024784918570374158793713225864658725102756338798521486349461900449498315865014065406918592181034633618363349807887404915072776534917803019477033072906290735591367789665757384135591225430117374220731087966"
// min=0 max=100 step="18446744073709551575">
StepRange step_range2(Decimal::FromDouble(8.62402e+207), Decimal(0),
- Decimal(100), true, Decimal::FromDouble(1.84467e+19),
+ Decimal(100), true, /*has_reversed_range=*/false,
+ Decimal::FromDouble(1.84467e+19),
StepRange::StepDescription());
EXPECT_FALSE(step_range2.StepSnappedMaximum().IsFinite());
}
+TEST(StepRangeTest, ReversedRange) {
+ // <input type=time min="23:00" max="01:00">
+ StepRange reversed_time_range(
+ /*step_base=*/Decimal::FromDouble(82800000),
+ /*minimum=*/Decimal::FromDouble(82800000),
+ /*maximum=*/Decimal::FromDouble(3600000),
+ /*has_range_limitations=*/true,
+ /*supports_reversed_range=*/true,
+ /*step=*/Decimal::FromDouble(60000),
+ /*step_description=*/StepRange::StepDescription());
+ EXPECT_TRUE(reversed_time_range.HasReversedRange());
+
+ // <input type=time min="01:00" max="23:00">
+ StepRange regular_time_range(
+ /*step_base=*/Decimal::FromDouble(3600000),
+ /*minimum=*/Decimal::FromDouble(3600000),
+ /*maximum=*/Decimal::FromDouble(82800000),
+ /*has_range_limitations=*/true,
+ /*supports_reversed_range=*/true,
+ /*step=*/Decimal::FromDouble(60000),
+ /*step_description=*/StepRange::StepDescription());
+ EXPECT_FALSE(regular_time_range.HasReversedRange());
+}
+
} // namespace blink
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
new file mode 100644
index 00000000000..04c84a91404
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/forms/submit_event.cc
@@ -0,0 +1,32 @@
+// 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/forms/submit_event.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/v8_submit_event_init.h"
+#include "third_party/blink/renderer/core/event_interface_names.h"
+#include "third_party/blink/renderer/core/html/html_element.h"
+
+namespace blink {
+
+SubmitEvent::SubmitEvent(const AtomicString& type,
+ const SubmitEventInit* event_init)
+ : Event(type, event_init),
+ submitter_(event_init ? event_init->submitter() : nullptr) {}
+
+SubmitEvent* SubmitEvent::Create(const AtomicString& type,
+ const SubmitEventInit* event_init) {
+ return MakeGarbageCollected<SubmitEvent>(type, event_init);
+}
+
+void SubmitEvent::Trace(Visitor* visitor) {
+ visitor->Trace(submitter_);
+ Event::Trace(visitor);
+}
+
+const AtomicString& SubmitEvent::InterfaceName() const {
+ return event_interface_names::kSubmitEvent;
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..2e242d3a791
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/forms/submit_event.h
@@ -0,0 +1,33 @@
+// 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_FORMS_SUBMIT_EVENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_SUBMIT_EVENT_H_
+
+#include "third_party/blink/renderer/core/dom/events/event.h"
+
+namespace blink {
+
+class HTMLElement;
+class SubmitEventInit;
+
+class SubmitEvent : public Event {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static SubmitEvent* Create(const AtomicString& type,
+ const SubmitEventInit* event_init);
+ SubmitEvent(const AtomicString& type, const SubmitEventInit* event_init);
+
+ void Trace(Visitor* visitor) override;
+ HTMLElement* submitter() const { return submitter_.Get(); }
+ const AtomicString& InterfaceName() const override;
+
+ private:
+ Member<HTMLElement> submitter_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_SUBMIT_EVENT_H_
diff --git a/chromium/third_party/blink/renderer/core/html/forms/submit_event.idl b/chromium/third_party/blink/renderer/core/html/forms/submit_event.idl
new file mode 100644
index 00000000000..06de5b4286c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/forms/submit_event.idl
@@ -0,0 +1,12 @@
+// 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://html.spec.whatwg.org/C/#submitevent
+
+[
+ Exposed=Window
+] interface SubmitEvent : Event {
+ constructor(DOMString type, optional SubmitEventInit eventInitDict = {});
+ readonly attribute HTMLElement? submitter;
+};
diff --git a/chromium/third_party/blink/renderer/core/html/forms/submit_event_init.idl b/chromium/third_party/blink/renderer/core/html/forms/submit_event_init.idl
new file mode 100644
index 00000000000..e38c93d7680
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/forms/submit_event_init.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://html.spec.whatwg.org/C/#submitevent
+
+dictionary SubmitEventInit : EventInit {
+ HTMLElement? submitter = null;
+};
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 418baf6f877..3792c0037a5 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
@@ -24,6 +24,7 @@
#include "third_party/blink/renderer/core/html/forms/text_control_element.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
#include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -82,7 +83,7 @@ TextControlElement::~TextControlElement() = default;
void TextControlElement::DispatchFocusEvent(
Element* old_focused_element,
- WebFocusType type,
+ mojom::blink::FocusType type,
InputDeviceCapabilities* source_capabilities) {
if (SupportsPlaceholder())
UpdatePlaceholderVisibility();
@@ -93,7 +94,7 @@ void TextControlElement::DispatchFocusEvent(
void TextControlElement::DispatchBlurEvent(
Element* new_focused_element,
- WebFocusType type,
+ mojom::blink::FocusType type,
InputDeviceCapabilities* source_capabilities) {
if (SupportsPlaceholder())
UpdatePlaceholderVisibility();
@@ -222,8 +223,8 @@ void TextControlElement::select() {
setSelectionRangeForBinding(0, std::numeric_limits<unsigned>::max());
// Avoid SelectionBehaviorOnFocus::Restore, which scrolls containers to show
// the selection.
- focus(
- FocusParams(SelectionBehaviorOnFocus::kNone, kWebFocusTypeNone, nullptr));
+ focus(FocusParams(SelectionBehaviorOnFocus::kNone,
+ mojom::blink::FocusType::kNone, nullptr));
RestoreCachedSelection();
}
@@ -246,7 +247,8 @@ void TextControlElement::ClearValueBeforeFirstUserEdit() {
value_before_first_user_edit_ = String();
}
-void TextControlElement::SetFocused(bool flag, WebFocusType focus_type) {
+void TextControlElement::SetFocused(bool flag,
+ mojom::blink::FocusType focus_type) {
HTMLFormControlElementWithState::SetFocused(flag, focus_type);
if (!flag)
@@ -972,11 +974,11 @@ String TextControlElement::DirectionForFormData() const {
if (dir_attribute_value.IsNull())
continue;
- if (DeprecatedEqualIgnoringCase(dir_attribute_value, "rtl") ||
- DeprecatedEqualIgnoringCase(dir_attribute_value, "ltr"))
+ if (EqualIgnoringASCIICase(dir_attribute_value, "rtl") ||
+ EqualIgnoringASCIICase(dir_attribute_value, "ltr"))
return dir_attribute_value;
- if (DeprecatedEqualIgnoringCase(dir_attribute_value, "auto")) {
+ if (EqualIgnoringASCIICase(dir_attribute_value, "auto")) {
bool is_auto;
TextDirection text_direction =
element->DirectionalityIfhasDirAutoAttribute(is_auto);
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 47c266d0474..740cab80101 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
@@ -27,7 +27,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_TEXT_CONTROL_ELEMENT_H_
#include "base/gtest_prod_util.h"
-#include "third_party/blink/public/platform/web_focus_type.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.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/html/forms/html_form_control_element_with_state.h"
@@ -45,6 +45,7 @@ enum TextFieldSelectionDirection {
enum class TextFieldEventBehavior {
kDispatchNoEvent,
kDispatchChangeEvent,
+ kDispatchInputEvent,
kDispatchInputAndChangeEvent
};
@@ -65,7 +66,7 @@ class CORE_EXPORT TextControlElement : public HTMLFormControlElementWithState {
void ForwardEvent(Event&);
- void SetFocused(bool, WebFocusType) override;
+ void SetFocused(bool, mojom::blink::FocusType) override;
// The derived class should return true if placeholder processing is needed.
virtual bool IsPlaceholderVisible() const = 0;
@@ -186,10 +187,10 @@ class CORE_EXPORT TextControlElement : public HTMLFormControlElementWithState {
static unsigned IndexForPosition(HTMLElement* inner_editor, const Position&);
void DispatchFocusEvent(Element* old_focused_element,
- WebFocusType,
+ mojom::blink::FocusType,
InputDeviceCapabilities* source_capabilities) final;
void DispatchBlurEvent(Element* new_focused_element,
- WebFocusType,
+ mojom::blink::FocusType,
InputDeviceCapabilities* source_capabilities) final;
void ScheduleSelectEvent();
void DisabledOrReadonlyAttributeChanged(const QualifiedName&);
@@ -202,7 +203,8 @@ class CORE_EXPORT TextControlElement : public HTMLFormControlElementWithState {
bool IsEmptySuggestedValue() const { return SuggestedValue().IsEmpty(); }
// Called in dispatchFocusEvent(), after placeholder process, before calling
// parent's dispatchFocusEvent().
- virtual void HandleFocusEvent(Element* /* oldFocusedNode */, WebFocusType) {}
+ virtual void HandleFocusEvent(Element* /* oldFocusedNode */,
+ mojom::blink::FocusType) {}
// Called in dispatchBlurEvent(), after placeholder process, before calling
// parent's dispatchBlurEvent().
virtual void HandleBlurEvent() {}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/text_control_element_test.cc b/chromium/third_party/blink/renderer/core/html/forms/text_control_element_test.cc
index 64536a9caa5..e5f900301bc 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/text_control_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/text_control_element_test.cc
@@ -30,8 +30,7 @@ class TextControlElementTest : public testing::Test {
HTMLInputElement& Input() const { return *input_; }
void UpdateAllLifecyclePhases() {
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
}
private:
@@ -49,7 +48,7 @@ void TextControlElementTest::SetUp() {
std::make_unique<DummyPageHolder>(IntSize(800, 600), &page_clients);
document_ = &dummy_page_holder_->GetDocument();
- document_->documentElement()->SetInnerHTMLFromString(
+ document_->documentElement()->setInnerHTML(
"<body><textarea id=textarea></textarea><input id=input /></body>");
UpdateAllLifecyclePhases();
text_control_ = ToTextControl(document_->getElementById("textarea"));
diff --git a/chromium/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc b/chromium/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc
index 88b66536810..c1f64e3421c 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/text_control_inner_elements.cc
@@ -39,19 +39,6 @@
namespace blink {
-TextControlInnerContainer::TextControlInnerContainer(Document& document)
- : HTMLDivElement(document) {
- setAttribute(html_names::kIdAttr, shadow_element_names::TextFieldContainer());
-}
-
-LayoutObject* TextControlInnerContainer::CreateLayoutObject(
- const ComputedStyle&,
- LegacyLayout) {
- return new LayoutTextControlInnerContainer(this);
-}
-
-// ---------------------------
-
EditingViewPortElement::EditingViewPortElement(Document& document)
: HTMLDivElement(document) {
SetHasCustomStyleCallbacks();
@@ -100,6 +87,17 @@ void TextControlInnerEditorElement::DefaultEventHandler(Event& event) {
if (shadow_ancestor)
shadow_ancestor->DefaultEventHandler(event);
}
+
+ if (event.type() == event_type_names::kScroll) {
+ // The scroller for a text control is inside of a shadow tree but the
+ // scroll event won't bubble past the shadow root and authors cannot add
+ // an event listener to it. Fire the scroll event at the shadow host so
+ // that the page can hear about the scroll.
+ Element* shadow_ancestor = OwnerShadowHost();
+ if (shadow_ancestor)
+ shadow_ancestor->DispatchEvent(event);
+ }
+
if (!event.DefaultHandled())
HTMLDivElement::DefaultEventHandler(event);
}
@@ -148,6 +146,8 @@ TextControlInnerEditorElement::CreateInnerEditorStyle() const {
? EUserModify::kReadOnly
: EUserModify::kReadWritePlaintextOnly);
text_block_style->SetDisplay(EDisplay::kBlock);
+ text_block_style->SetHasLineIfEmpty(true);
+ text_block_style->SetShouldIgnoreOverflowPropertyForInlineBlockBaseline();
if (!IsA<HTMLTextAreaElement>(host)) {
text_block_style->SetWhiteSpace(EWhiteSpace::kPre);
@@ -204,6 +204,7 @@ SearchFieldCancelButtonElement::SearchFieldCancelButtonElement(
void SearchFieldCancelButtonElement::DefaultEventHandler(Event& event) {
// If the element is visible, on mouseup, clear the value, and set selection
+ auto* mouse_event = DynamicTo<MouseEvent>(event);
auto* input = To<HTMLInputElement>(OwnerShadowHost());
if (!input || input->IsDisabledOrReadOnly()) {
if (!event.DefaultHandled())
@@ -211,8 +212,8 @@ void SearchFieldCancelButtonElement::DefaultEventHandler(Event& event) {
return;
}
- if (event.type() == event_type_names::kClick && event.IsMouseEvent() &&
- ToMouseEvent(event).button() ==
+ if (event.type() == event_type_names::kClick && mouse_event &&
+ mouse_event->button() ==
static_cast<int16_t>(WebPointerProperties::Button::kLeft)) {
input->SetValueForUser("");
input->SetAutofillState(WebAutofillState::kNotFilled);
@@ -250,7 +251,7 @@ void PasswordRevealButtonElement::DefaultEventHandler(Event& event) {
}
// Toggle the should-reveal-password state when clicked.
- if (event.type() == event_type_names::kClick && event.IsMouseEvent()) {
+ if (event.type() == event_type_names::kClick && IsA<MouseEvent>(event)) {
bool shouldRevealPassword = !input->ShouldRevealPassword();
input->SetShouldRevealPassword(shouldRevealPassword);
diff --git a/chromium/third_party/blink/renderer/core/html/forms/text_control_inner_elements.h b/chromium/third_party/blink/renderer/core/html/forms/text_control_inner_elements.h
index cd0ad1b92fa..f800144a200 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/text_control_inner_elements.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/text_control_inner_elements.h
@@ -32,15 +32,6 @@
namespace blink {
-class TextControlInnerContainer final : public HTMLDivElement {
- public:
- explicit TextControlInnerContainer(Document&);
-
- protected:
- LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override;
- bool TypeShouldForceLegacyLayout() const final { return true; }
-};
-
class EditingViewPortElement final : public HTMLDivElement {
public:
explicit EditingViewPortElement(Document&);
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 5953d45d82b..efb2e1ef525 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
@@ -35,7 +35,9 @@
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/events/before_text_inserted_event.h"
+#include "third_party/blink/renderer/core/events/drag_event.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/text_event.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/forms/form_data.h"
@@ -134,7 +136,10 @@ bool TextFieldInputType::IsTextField() const {
}
bool TextFieldInputType::ValueMissing(const String& value) const {
- return GetElement().IsRequired() && value.IsEmpty();
+ // For text-mode input elements, the value is missing only if it is mutable.
+ // https://html.spec.whatwg.org/multipage/input.html#the-required-attribute
+ return GetElement().IsRequired() && value.IsEmpty() &&
+ !GetElement().IsDisabledOrReadOnly();
}
bool TextFieldInputType::CanSetSuggestedValue() {
@@ -177,11 +182,14 @@ void TextFieldInputType::SetValue(const String& sanitized_value,
GetElement().DispatchFormControlChangeEvent();
break;
- case TextFieldEventBehavior::kDispatchInputAndChangeEvent: {
+ case TextFieldEventBehavior::kDispatchInputEvent:
+ GetElement().DispatchInputEvent();
+ break;
+
+ case TextFieldEventBehavior::kDispatchInputAndChangeEvent:
GetElement().DispatchInputEvent();
GetElement().DispatchFormControlChangeEvent();
break;
- }
case TextFieldEventBehavior::kDispatchNoEvent:
break;
@@ -226,12 +234,12 @@ void TextFieldInputType::ForwardEvent(Event& event) {
// input element.
if (GetElement().GetLayoutObject() &&
!GetElement().GetForceReattachLayoutTree() &&
- (event.IsMouseEvent() || event.IsDragEvent() ||
+ (IsA<MouseEvent>(event) || IsA<DragEvent>(event) ||
event.HasInterface(event_interface_names::kWheelEvent) ||
event.type() == event_type_names::kBlur ||
event.type() == event_type_names::kFocus)) {
- LayoutTextControlSingleLine* layout_text_control =
- ToLayoutTextControlSingleLine(GetElement().GetLayoutObject());
+ auto* layout_text_control =
+ To<LayoutTextControlSingleLine>(GetElement().GetLayoutObject());
if (event.type() == event_type_names::kBlur) {
if (LayoutBox* inner_editor_layout_object =
GetElement().InnerEditorElement()->GetLayoutBox()) {
@@ -239,8 +247,8 @@ void TextFieldInputType::ForwardEvent(Event& event) {
if (PaintLayer* inner_layer = inner_editor_layout_object->Layer()) {
if (PaintLayerScrollableArea* inner_scrollable_area =
inner_layer->GetScrollableArea()) {
- inner_scrollable_area->SetScrollOffset(ScrollOffset(0, 0),
- kProgrammaticScroll);
+ inner_scrollable_area->SetScrollOffset(
+ ScrollOffset(0, 0), mojom::blink::ScrollType::kProgrammatic);
}
}
}
@@ -268,6 +276,16 @@ bool TextFieldInputType::ShouldSubmitImplicitly(const Event& event) {
InputTypeView::ShouldSubmitImplicitly(event);
}
+void TextFieldInputType::CustomStyleForLayoutObject(ComputedStyle& style) {
+ // The flag is necessary in order that a text field <input> with non-'visible'
+ // overflow property doesn't change its baseline.
+ style.SetShouldIgnoreOverflowPropertyForInlineBlockBaseline();
+}
+
+bool TextFieldInputType::TypeShouldForceLegacyLayout() const {
+ return true;
+}
+
LayoutObject* TextFieldInputType::CreateLayoutObject(const ComputedStyle&,
LegacyLayout) const {
return new LayoutTextControlSingleLine(&GetElement());
@@ -294,7 +312,8 @@ void TextFieldInputType::CreateShadowSubtree() {
return;
}
- auto* container = MakeGarbageCollected<TextControlInnerContainer>(document);
+ auto* container = MakeGarbageCollected<HTMLDivElement>(document);
+ container->SetIdAttribute(shadow_element_names::TextFieldContainer());
container->SetShadowPseudoId(
AtomicString("-webkit-textfield-decoration-container"));
shadow_root->AppendChild(container);
@@ -352,8 +371,8 @@ void TextFieldInputType::ListAttributeTargetChanged() {
// FIXME: The following code is similar to createShadowSubtree(),
// but they are different. We should simplify the code by making
// containerElement mandatory.
- auto* rp_container =
- MakeGarbageCollected<TextControlInnerContainer>(document);
+ auto* rp_container = MakeGarbageCollected<HTMLDivElement>(document);
+ rp_container->SetIdAttribute(shadow_element_names::TextFieldContainer());
rp_container->SetShadowPseudoId(
AtomicString("-webkit-textfield-decoration-container"));
Element* inner_editor = GetElement().InnerEditorElement();
@@ -429,7 +448,8 @@ void TextFieldInputType::HandleBeforeTextInsertedEvent(
if (GetElement().IsFocused()) {
// TODO(editing-dev): Use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- GetElement().GetDocument().UpdateStyleAndLayout();
+ GetElement().GetDocument().UpdateStyleAndLayout(
+ DocumentUpdateReason::kEditing);
selection_length = GetElement()
.GetDocument()
@@ -573,4 +593,8 @@ void TextFieldInputType::SpinButtonDidReleaseMouseCapture(
GetElement().DispatchFormControlChangeEvent();
}
+String TextFieldInputType::RawValue() const {
+ return GetElement().InnerEditorElement()->innerText();
+}
+
} // namespace blink
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 595bed48801..0e7994ca51a 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
@@ -48,6 +48,8 @@ class TextFieldInputType : public InputType,
void Trace(Visitor*) override;
using InputType::GetElement;
+ String RawValue() const override;
+
protected:
TextFieldInputType(HTMLInputElement&);
~TextFieldInputType() override;
@@ -68,6 +70,8 @@ class TextFieldInputType : public InputType,
TextFieldEventBehavior,
TextControlSetValueSelection) override;
void UpdateView() override;
+ void CustomStyleForLayoutObject(ComputedStyle& style) override;
+ bool TypeShouldForceLegacyLayout() const override;
LayoutObject* CreateLayoutObject(const ComputedStyle&,
LegacyLayout) const override;
diff --git a/chromium/third_party/blink/renderer/core/html/forms/text_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/text_input_type.cc
index b9d42cef516..a611a0333df 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/text_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/text_input_type.cc
@@ -42,9 +42,9 @@ void TextInputType::CountUsage() {
CountUsageIfVisible(WebFeature::kInputTypeTextMaxLength);
const AtomicString& type =
GetElement().FastGetAttribute(html_names::kTypeAttr);
- if (DeprecatedEqualIgnoringCase(type, input_type_names::kDatetime))
+ if (EqualIgnoringASCIICase(type, input_type_names::kDatetime))
CountUsageIfVisible(WebFeature::kInputTypeDateTimeFallback);
- else if (DeprecatedEqualIgnoringCase(type, input_type_names::kWeek))
+ else if (EqualIgnoringASCIICase(type, input_type_names::kWeek))
CountUsageIfVisible(WebFeature::kInputTypeWeekFallback);
}
diff --git a/chromium/third_party/blink/renderer/core/html/forms/time_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/time_input_type.cc
index bbf3ccfc8d6..e56c81b5b43 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/time_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/time_input_type.cc
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/core/html/forms/time_input_type.h"
+#include "third_party/blink/public/strings/grit/blink_strings.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/html/forms/date_time_fields_state.h"
@@ -76,7 +77,7 @@ StepRange TimeInputType::CreateStepRange(
(kTimeDefaultStep, kTimeDefaultStepBase, kTimeStepScaleFactor,
StepRange::kScaledStepValueShouldBeInteger));
- return InputType::CreateStepRange(
+ return InputType::CreateReversibleStepRange(
any_step_handling, kTimeDefaultStepBase,
Decimal::FromDouble(DateComponents::MinimumTime()),
Decimal::FromDouble(DateComponents::MaximumTime()), step_description);
@@ -173,4 +174,16 @@ bool TimeInputType::IsValidFormat(bool has_year,
return has_hour && has_minute && has_ampm;
}
+String TimeInputType::AriaRoleForPickerIndicator() const {
+ return GetLocale().QueryString(IDS_AX_CALENDAR_SHOW_TIME_PICKER);
+}
+
+String TimeInputType::ReversedRangeOutOfRangeText(
+ const Decimal& minimum,
+ const Decimal& maximum) const {
+ return GetLocale().QueryString(
+ IDS_FORM_VALIDATION_REVERSED_RANGE_OUT_OF_RANGE_TIME,
+ LocalizeValue(Serialize(minimum)), LocalizeValue(Serialize(maximum)));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/forms/time_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/time_input_type.h
index 58711ec43f5..2b520a8899d 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/time_input_type.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/time_input_type.h
@@ -62,6 +62,9 @@ class TimeInputType final : public BaseTemporalInputType {
bool has_hour,
bool has_minute,
bool has_second) const override;
+ String AriaRoleForPickerIndicator() const override;
+ String ReversedRangeOutOfRangeText(const Decimal& minimum,
+ const Decimal& maximum) const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/forms/type_ahead_test.cc b/chromium/third_party/blink/renderer/core/html/forms/type_ahead_test.cc
index 5077a9152e2..dc43dbf7bb4 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/type_ahead_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/type_ahead_test.cc
@@ -6,7 +6,7 @@
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/web_keyboard_event.h"
+#include "third_party/blink/public/common/input/web_keyboard_event.h"
#include "third_party/blink/renderer/core/events/keyboard_event.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/html/forms/week_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/week_input_type.cc
index 3c53ffb9098..0501230b551 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/week_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/week_input_type.cc
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/core/html/forms/week_input_type.h"
+#include "third_party/blink/public/strings/grit/blink_strings.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/html/forms/date_time_fields_state.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
@@ -125,4 +126,8 @@ bool WeekInputType::IsValidFormat(bool has_year,
return has_year && has_week;
}
+String WeekInputType::AriaRoleForPickerIndicator() const {
+ return GetLocale().QueryString(IDS_AX_CALENDAR_SHOW_WEEK_PICKER);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/forms/week_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/week_input_type.h
index 783aeff2766..b8b176bbaad 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/week_input_type.h
+++ b/chromium/third_party/blink/renderer/core/html/forms/week_input_type.h
@@ -61,6 +61,7 @@ class WeekInputType final : public BaseTemporalInputType {
bool has_hour,
bool has_minute,
bool has_second) const override;
+ String AriaRoleForPickerIndicator() const override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/html_all_collection.h b/chromium/third_party/blink/renderer/core/html/html_all_collection.h
index c01c8bf2edb..f373796334c 100644
--- a/chromium/third_party/blink/renderer/core/html/html_all_collection.h
+++ b/chromium/third_party/blink/renderer/core/html/html_all_collection.h
@@ -45,12 +45,6 @@ class HTMLAllCollection final : public HTMLCollection {
void NamedGetter(const AtomicString& name, HTMLCollectionOrElement&);
};
-DEFINE_TYPE_CASTS(HTMLAllCollection,
- LiveNodeListBase,
- collection,
- collection->GetType() == kDocAll,
- collection.GetType() == kDocAll);
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_ALL_COLLECTION_H_
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 a3bd05511bd..eb2c6a47cfb 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
@@ -26,6 +26,7 @@
#include "base/metrics/histogram_macros.h"
#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_prescient_networking.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
@@ -77,7 +78,7 @@ bool ShouldInterveneDownloadByFramePolicy(LocalFrame* frame) {
should_intervene_download = true;
}
}
- if (document.IsSandboxed(WebSandboxFlags::kDownloads)) {
+ if (document.IsSandboxed(mojom::blink::WebSandboxFlags::kDownloads)) {
UseCounter::Count(document, WebFeature::kDownloadInSandbox);
if (RuntimeEnabledFeatures::BlockingDownloadsInSandboxEnabled())
should_intervene_download = true;
@@ -110,7 +111,7 @@ bool HTMLAnchorElement::SupportsFocus() const {
}
bool HTMLAnchorElement::ShouldHaveFocusAppearance() const {
- return (GetDocument().LastFocusType() != kWebFocusTypeMouse) ||
+ return (GetDocument().LastFocusType() != mojom::blink::FocusType::kMouse) ||
HTMLElement::SupportsFocus();
}
@@ -133,7 +134,8 @@ bool HTMLAnchorElement::IsKeyboardFocusable() const {
}
static void AppendServerMapMousePosition(StringBuilder& url, Event* event) {
- if (!event->IsMouseEvent())
+ auto* mouse_event = DynamicTo<MouseEvent>(event);
+ if (!mouse_event)
return;
DCHECK(event->target());
@@ -150,7 +152,7 @@ static void AppendServerMapMousePosition(StringBuilder& url, Event* event) {
// The coordinates sent in the query string are relative to the height and
// width of the image element, ignoring CSS transform/zoom.
FloatPoint map_point = layout_object->AbsoluteToLocalFloatPoint(
- FloatPoint(ToMouseEvent(event)->AbsoluteLocation()));
+ FloatPoint(mouse_event->AbsoluteLocation()));
// The origin (0,0) is at the upper left of the content area, inside the
// padding and border.
@@ -276,9 +278,9 @@ bool HTMLAnchorElement::CanStartSelection() const {
bool HTMLAnchorElement::draggable() const {
// Should be draggable if we have an href attribute.
const AtomicString& value = FastGetAttribute(html_names::kDraggableAttr);
- if (DeprecatedEqualIgnoringCase(value, "true"))
+ if (EqualIgnoringASCIICase(value, "true"))
return true;
- if (DeprecatedEqualIgnoringCase(value, "false"))
+ if (EqualIgnoringASCIICase(value, "false"))
return false;
return FastHasAttribute(html_names::kHrefAttr);
}
@@ -411,8 +413,7 @@ void HTMLAnchorElement::HandleClick(Event& event) {
static_cast<String>(FastGetAttribute(html_names::kDownloadAttr)));
request.SetRequestContext(mojom::RequestContextType::DOWNLOAD);
request.SetRequestorOrigin(GetDocument().GetSecurityOrigin());
- frame->Client()->DownloadURL(request,
- network::mojom::RedirectMode::kManual);
+ frame->DownloadURL(request, network::mojom::blink::RedirectMode::kManual);
return;
}
@@ -421,19 +422,13 @@ void HTMLAnchorElement::HandleClick(Event& event) {
const AtomicString& target = FastGetAttribute(html_names::kTargetAttr);
FrameLoadRequest frame_request(&GetDocument(), request);
frame_request.SetNavigationPolicy(NavigationPolicyFromEvent(&event));
+ frame_request.SetClientRedirectReason(ClientNavigationReason::kAnchorClick);
if (HasRel(kRelationNoReferrer)) {
frame_request.SetNoReferrer();
frame_request.SetNoOpener();
}
if (HasRel(kRelationNoOpener))
frame_request.SetNoOpener();
- if (RuntimeEnabledFeatures::HrefTranslateEnabled(&GetDocument()) &&
- FastHasAttribute(html_names::kHreftranslateAttr)) {
- frame_request.SetHrefTranslate(
- FastGetAttribute(html_names::kHreftranslateAttr));
- UseCounter::Count(GetDocument(),
- WebFeature::kHTMLAnchorElementHrefTranslateAttribute);
- }
frame_request.SetTriggeringEventInfo(
event.isTrusted() ? TriggeringEventInfo::kFromTrustedEvent
: TriggeringEventInfo::kFromUntrustedEvent);
@@ -447,24 +442,56 @@ void HTMLAnchorElement::HandleClick(Event& event) {
frame_request,
target.IsEmpty() ? GetDocument().BaseTarget() : target)
.frame;
- if (target_frame)
+
+ // If hrefTranslate is enabled and set restrict processing it
+ // to same frame or navigations with noopener set.
+ if (RuntimeEnabledFeatures::HrefTranslateEnabled(&GetDocument()) &&
+ FastHasAttribute(html_names::kHreftranslateAttr) &&
+ (target_frame == frame || frame_request.GetWindowFeatures().noopener)) {
+ frame_request.SetHrefTranslate(
+ FastGetAttribute(html_names::kHreftranslateAttr));
+ UseCounter::Count(GetDocument(),
+ WebFeature::kHTMLAnchorElementHrefTranslateAttribute);
+ }
+
+ if (target_frame) {
+ // If we also have a pending form submission, make sure this anchor
+ // navigation takes precedence over it, except in the case of href being
+ // a fragment, in which case pending form submissions should go through.
+ // In the case of a target RemoteFrame, don't cancel form submissions
+ // because we can't be sure what the remote document's urlForBinding is.
+ // In the case of href="javascript:", don't cancel form submissions because
+ // we have always let form submissions take precedence in this case.
+ // TODO(crbug.com/1053679): Remove this after making anchor navigations
+ // async like the spec says to do, which will also provide the desired
+ // behavior.
+ if (LocalFrame* target_local_frame = DynamicTo<LocalFrame>(target_frame)) {
+ KURL document_url = target_local_frame->GetDocument()->urlForBinding();
+ bool equal_ignoring_fragment =
+ completed_url.HasFragmentIdentifier() &&
+ EqualIgnoringFragmentIdentifier(completed_url, document_url);
+ if (!equal_ignoring_fragment && !completed_url.ProtocolIsJavaScript())
+ target_frame->CancelFormSubmission();
+ }
+
target_frame->Navigate(frame_request, WebFrameLoadType::kStandard);
+ }
}
bool IsEnterKeyKeydownEvent(Event& event) {
- return event.type() == event_type_names::kKeydown &&
- event.IsKeyboardEvent() && ToKeyboardEvent(event).key() == "Enter" &&
- !ToKeyboardEvent(event).repeat();
+ auto* keyboard_event = DynamicTo<KeyboardEvent>(event);
+ return event.type() == event_type_names::kKeydown && keyboard_event &&
+ keyboard_event->key() == "Enter" && !keyboard_event->repeat();
}
bool IsLinkClick(Event& event) {
+ auto* mouse_event = DynamicTo<MouseEvent>(event);
if ((event.type() != event_type_names::kClick &&
event.type() != event_type_names::kAuxclick) ||
- !event.IsMouseEvent()) {
+ !mouse_event) {
return false;
}
- auto& mouse_event = ToMouseEvent(event);
- int16_t button = mouse_event.button();
+ int16_t button = mouse_event->button();
return (button == static_cast<int16_t>(WebPointerProperties::Button::kLeft) ||
button ==
static_cast<int16_t>(WebPointerProperties::Button::kMiddle));
diff --git a/chromium/third_party/blink/renderer/core/html/html_area_element.cc b/chromium/third_party/blink/renderer/core/html/html_area_element.cc
index e890daa7266..b7630fa4075 100644
--- a/chromium/third_party/blink/renderer/core/html/html_area_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_area_element.cc
@@ -201,7 +201,7 @@ bool HTMLAreaElement::IsFocusableStyle() const {
}
void HTMLAreaElement::SetFocused(bool should_be_focused,
- WebFocusType focus_type) {
+ mojom::blink::FocusType focus_type) {
if (IsFocused() == should_be_focused)
return;
diff --git a/chromium/third_party/blink/renderer/core/html/html_area_element.h b/chromium/third_party/blink/renderer/core/html/html_area_element.h
index 2e6f36cc14a..b51388818d9 100644
--- a/chromium/third_party/blink/renderer/core/html/html_area_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_area_element.h
@@ -24,7 +24,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_AREA_ELEMENT_H_
#include <memory>
-#include "third_party/blink/public/platform/web_focus_type.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/html/html_anchor_element.h"
#include "third_party/blink/renderer/core/layout/geometry/physical_rect.h"
@@ -66,7 +66,7 @@ class CORE_EXPORT HTMLAreaElement final : public HTMLAnchorElement {
bool IsFocusableStyle() const override;
void UpdateFocusAppearanceWithOptions(SelectionBehaviorOnFocus,
const FocusOptions*) override;
- void SetFocused(bool, WebFocusType) override;
+ void SetFocused(bool, mojom::blink::FocusType) override;
enum Shape { kDefault, kPoly, kRect, kCircle };
void InvalidateCachedPath();
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 eb38ad06b84..084b45e3e6e 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
@@ -248,6 +248,7 @@
"onsuspend",
"onsubmit",
"ontimeupdate",
+ "ontimezonechange",
"ontoggle",
"ontouchstart",
"ontouchmove",
@@ -271,11 +272,11 @@
"placeholder",
"playsinline",
"ping",
+ "policy",
"poster",
"preload",
"pseudo",
"readonly",
- "rendersubtree",
"referrerpolicy",
"rel",
"required",
@@ -293,6 +294,8 @@
"scrolling",
"select",
"selected",
+ "shadowroot",
+ "shadowrootdelegatesfocus",
"shape",
"size",
"sizes",
@@ -315,6 +318,7 @@
"topmargin",
"translate",
"truespeed",
+ "trusttoken",
"type",
"usemap",
"valign",
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 f81c88d9ebf..eedcfd69ef1 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
@@ -62,13 +62,13 @@ void HTMLBodyElement::CollectStyleForPresentationAttribute(
const AtomicString& value,
MutableCSSPropertyValueSet* style) {
if (name == html_names::kBackgroundAttr) {
- String url = StripLeadingAndTrailingHTMLSpaces(value);
+ AtomicString url(StripLeadingAndTrailingHTMLSpaces(value));
if (!url.IsEmpty()) {
- CSSImageValue* image_value =
- CSSImageValue::Create(url, GetDocument().CompleteURL(url),
- Referrer(GetDocument().OutgoingReferrer(),
- GetDocument().GetReferrerPolicy()),
- OriginClean::kTrue);
+ CSSImageValue* image_value = MakeGarbageCollected<CSSImageValue>(
+ url, GetDocument().CompleteURL(url),
+ Referrer(GetDocument().OutgoingReferrer(),
+ GetDocument().GetReferrerPolicy()),
+ OriginClean::kTrue);
image_value->SetInitiator(localName());
style->SetProperty(
CSSPropertyValue(GetCSSPropertyBackgroundImage(), *image_value));
@@ -215,11 +215,16 @@ void HTMLBodyElement::ParseAttribute(
GetDocument().SetWindowAttributeEventListener(
event_type_names::kLanguagechange,
CreateAttributeEventListener(GetDocument().GetFrame(), name, value));
- } else if (RuntimeEnabledFeatures::PortalsEnabled() &&
+ } else if (RuntimeEnabledFeatures::PortalsEnabled(&GetDocument()) &&
name == html_names::kOnportalactivateAttr) {
GetDocument().SetWindowAttributeEventListener(
event_type_names::kPortalactivate,
CreateAttributeEventListener(GetDocument().GetFrame(), name, value));
+ } else if (RuntimeEnabledFeatures::TimeZoneChangeEventEnabled() &&
+ name == html_names::kOntimezonechangeAttr) {
+ GetDocument().SetWindowAttributeEventListener(
+ event_type_names::kTimezonechange,
+ CreateAttributeEventListener(GetDocument().GetFrame(), name, value));
} else {
HTMLElement::ParseAttribute(params);
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_br_element.cc b/chromium/third_party/blink/renderer/core/html/html_br_element.cc
index d81dd2d7e51..8320f200720 100644
--- a/chromium/third_party/blink/renderer/core/html/html_br_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_br_element.cc
@@ -47,7 +47,7 @@ void HTMLBRElement::CollectStyleForPresentationAttribute(
// <br clear> and <br clear=""> are just treated like <br> by Gecko, Mac IE,
// etc. -dwh
if (!value.IsEmpty()) {
- if (DeprecatedEqualIgnoringCase(value, "all")) {
+ if (EqualIgnoringASCIICase(value, "all")) {
AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kClear,
CSSValueID::kBoth);
} else {
@@ -62,9 +62,9 @@ void HTMLBRElement::CollectStyleForPresentationAttribute(
LayoutObject* HTMLBRElement::CreateLayoutObject(const ComputedStyle& style,
LegacyLayout legacy) {
- if (style.HasContent())
- return LayoutObject::CreateObject(this, style, legacy);
- return new LayoutBR(this);
+ if (style.ContentBehavesAsNormal())
+ return new LayoutBR(this);
+ return LayoutObject::CreateObject(this, style, legacy);
}
} // namespace blink
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 ecef92ef34b..384f50b80a4 100644
--- a/chromium/third_party/blink/renderer/core/html/html_collection.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_collection.cc
@@ -25,7 +25,6 @@
#include "third_party/blink/renderer/core/dom/class_collection.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
-#include "third_party/blink/renderer/core/dom/node_child_removal_tracker.h"
#include "third_party/blink/renderer/core/dom/node_rare_data.h"
#include "third_party/blink/renderer/core/html/document_all_name_collection.h"
#include "third_party/blink/renderer/core/html/document_name_collection.h"
@@ -201,12 +200,7 @@ unsigned HTMLCollection::length() const {
}
Element* HTMLCollection::item(unsigned offset) const {
- Element* element = collection_items_cache_.NodeAt(*this, offset);
- if (element && element->GetDocument().InDOMNodeRemovedHandler()) {
- if (NodeChildRemovalTracker::IsBeingRemoved(*element))
- GetDocument().CountDetachingNodeAccessInDOMNodeRemovedHandler();
- }
- return element;
+ return collection_items_cache_.NodeAt(*this, offset);
}
static inline bool IsMatchingHTMLElement(const HTMLCollection& html_collection,
@@ -219,9 +213,10 @@ static inline bool IsMatchingHTMLElement(const HTMLCollection& html_collection,
case kDocForms:
return element.HasTagName(html_names::kFormTag);
case kDocumentNamedItems:
- return ToDocumentNameCollection(html_collection).ElementMatches(element);
+ return To<DocumentNameCollection>(html_collection)
+ .ElementMatches(element);
case kDocumentAllNamedItems:
- return ToDocumentAllNameCollection(html_collection)
+ return To<DocumentAllNameCollection>(html_collection)
.ElementMatches(element);
case kTableTBodies:
return element.HasTagName(html_names::kTbodyTag);
@@ -231,13 +226,13 @@ static inline bool IsMatchingHTMLElement(const HTMLCollection& html_collection,
case kTSectionRows:
return element.HasTagName(html_names::kTrTag);
case kSelectOptions:
- return ToHTMLOptionsCollection(html_collection).ElementMatches(element);
+ return To<HTMLOptionsCollection>(html_collection).ElementMatches(element);
case kSelectedOptions: {
auto* option_element = DynamicTo<HTMLOptionElement>(element);
return option_element && option_element->Selected();
}
case kDataListOptions:
- return ToHTMLDataListOptionsCollection(html_collection)
+ return To<HTMLDataListOptionsCollection>(html_collection)
.ElementMatches(element);
case kMapAreas:
return element.HasTagName(html_names::kAreaTag);
@@ -257,7 +252,7 @@ static inline bool IsMatchingHTMLElement(const HTMLCollection& html_collection,
case kFormControls:
DCHECK(IsA<HTMLFieldSetElement>(html_collection.ownerNode()));
return IsA<HTMLObjectElement>(element) ||
- IsHTMLFormControlElement(element) ||
+ IsA<HTMLFormControlElement>(element) ||
element.IsFormAssociatedCustomElement();
case kClassCollectionType:
case kTagCollectionType:
@@ -283,17 +278,17 @@ inline bool HTMLCollection::ElementMatches(const Element& element) const {
case kNodeChildren:
return true;
case kClassCollectionType:
- return ToClassCollection(*this).ElementMatches(element);
+ return To<ClassCollection>(*this).ElementMatches(element);
case kTagCollectionType:
- return ToTagCollection(*this).ElementMatches(element);
+ return To<TagCollection>(*this).ElementMatches(element);
case kHTMLTagCollectionType:
- return ToHTMLTagCollection(*this).ElementMatches(element);
+ return To<HTMLTagCollection>(*this).ElementMatches(element);
case kTagCollectionNSType:
- return ToTagCollectionNS(*this).ElementMatches(element);
+ return To<TagCollectionNS>(*this).ElementMatches(element);
case kWindowNamedItems:
- return ToWindowNameCollection(*this).ElementMatches(element);
+ return To<WindowNameCollection>(*this).ElementMatches(element);
case kDocumentAllNamedItems:
- return ToDocumentAllNameCollection(*this).ElementMatches(element);
+ return To<DocumentAllNameCollection>(*this).ElementMatches(element);
default:
break;
}
@@ -317,7 +312,7 @@ class IsMatch {
}
private:
- Member<const HTMLCollectionType> list_;
+ const HTMLCollectionType* list_;
};
} // namespace
@@ -358,10 +353,10 @@ Element* HTMLCollection::TraverseToFirst() const {
switch (GetType()) {
case kHTMLTagCollectionType:
return ElementTraversal::FirstWithin(
- RootNode(), MakeIsMatch(ToHTMLTagCollection(*this)));
+ RootNode(), MakeIsMatch(To<HTMLTagCollection>(*this)));
case kClassCollectionType:
return ElementTraversal::FirstWithin(
- RootNode(), MakeIsMatch(ToClassCollection(*this)));
+ RootNode(), MakeIsMatch(To<ClassCollection>(*this)));
default:
if (OverridesItemAfter())
return VirtualItemAfter(nullptr);
@@ -387,11 +382,11 @@ Element* HTMLCollection::TraverseForwardToOffset(
case kHTMLTagCollectionType:
return TraverseMatchingElementsForwardToOffset(
current_element, &RootNode(), offset, current_offset,
- MakeIsMatch(ToHTMLTagCollection(*this)));
+ MakeIsMatch(To<HTMLTagCollection>(*this)));
case kClassCollectionType:
return TraverseMatchingElementsForwardToOffset(
current_element, &RootNode(), offset, current_offset,
- MakeIsMatch(ToClassCollection(*this)));
+ MakeIsMatch(To<ClassCollection>(*this)));
default:
if (OverridesItemAfter()) {
for (Element* next = VirtualItemAfter(&current_element); next;
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 d1388a8d853..3f12118654e 100644
--- a/chromium/third_party/blink/renderer/core/html/html_collection.h
+++ b/chromium/third_party/blink/renderer/core/html/html_collection.h
@@ -29,6 +29,7 @@
#include "third_party/blink/renderer/core/dom/live_node_list_base.h"
#include "third_party/blink/renderer/core/html/collection_items_cache.h"
#include "third_party/blink/renderer/core/html/collection_type.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
namespace blink {
@@ -60,7 +61,7 @@ class HTMLCollectionIterator {
}
private:
- Member<const CollectionType> collection_;
+ const CollectionType* collection_;
unsigned index_ = 0;
};
@@ -212,11 +213,12 @@ class CORE_EXPORT HTMLCollection : public ScriptWrappable,
mutable CollectionItemsCache<HTMLCollection, Element> collection_items_cache_;
};
-DEFINE_TYPE_CASTS(HTMLCollection,
- LiveNodeListBase,
- collection,
- IsHTMLCollectionType(collection->GetType()),
- IsHTMLCollectionType(collection.GetType()));
+template <>
+struct DowncastTraits<HTMLCollection> {
+ static bool AllowFrom(const LiveNodeListBase& collection) {
+ return IsHTMLCollectionType(collection.GetType());
+ }
+};
DISABLE_CFI_PERF
inline void HTMLCollection::InvalidateCacheForAttribute(
diff --git a/chromium/third_party/blink/renderer/core/html/html_content_element_test.cc b/chromium/third_party/blink/renderer/core/html/html_content_element_test.cc
index da7d4a26ef2..817bf59b8dd 100644
--- a/chromium/third_party/blink/renderer/core/html/html_content_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_content_element_test.cc
@@ -25,14 +25,13 @@ class HTMLContentElementTest : public testing::Test {
};
TEST_F(HTMLContentElementTest, FallbackRecalcForReattach) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<div id='host'></div>
)HTML");
Element* host = GetDocument().getElementById("host");
ShadowRoot& root = host->CreateV0ShadowRootForTesting();
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
auto* content = GetDocument().CreateRawElement(html_names::kContentTag);
auto* fallback = GetDocument().CreateRawElement(html_names::kSpanTag);
diff --git a/chromium/third_party/blink/renderer/core/html/html_dialog_element.cc b/chromium/third_party/blink/renderer/core/html/html_dialog_element.cc
index c3a5248aa83..77a0778e31c 100644
--- a/chromium/third_party/blink/renderer/core/html/html_dialog_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_dialog_element.cc
@@ -131,7 +131,7 @@ void HTMLDialogElement::close(const String& return_value) {
void HTMLDialogElement::ForceLayoutForCentering() {
centering_mode_ = kNeedsCentering;
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
if (centering_mode_ == kNeedsCentering)
SetNotCentered();
}
@@ -149,7 +149,7 @@ void HTMLDialogElement::show() {
// The layout must be updated here because setFocusForDialog calls
// Element::isFocusable, which requires an up-to-date layout.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
SetFocusForDialog(this);
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_div_element.cc b/chromium/third_party/blink/renderer/core/html/html_div_element.cc
index 3b7b6c5add2..460efac7d4e 100644
--- a/chromium/third_party/blink/renderer/core/html/html_div_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_div_element.cc
@@ -36,14 +36,14 @@ void HTMLDivElement::CollectStyleForPresentationAttribute(
const AtomicString& value,
MutableCSSPropertyValueSet* style) {
if (name == html_names::kAlignAttr) {
- if (DeprecatedEqualIgnoringCase(value, "middle") ||
- DeprecatedEqualIgnoringCase(value, "center")) {
+ if (EqualIgnoringASCIICase(value, "middle") ||
+ EqualIgnoringASCIICase(value, "center")) {
AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kTextAlign,
CSSValueID::kWebkitCenter);
- } else if (DeprecatedEqualIgnoringCase(value, "left")) {
+ } else if (EqualIgnoringASCIICase(value, "left")) {
AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kTextAlign,
CSSValueID::kWebkitLeft);
- } else if (DeprecatedEqualIgnoringCase(value, "right")) {
+ } else if (EqualIgnoringASCIICase(value, "right")) {
AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kTextAlign,
CSSValueID::kWebkitRight);
} else {
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 55ab1e23616..fa4c536df01 100644
--- a/chromium/third_party/blink/renderer/core/html/html_document.h
+++ b/chromium/third_party/blink/renderer/core/html/html_document.h
@@ -55,7 +55,12 @@ inline bool HTMLDocument::HasNamedItem(const AtomicString& name) {
return named_item_counts_.Contains(name);
}
-DEFINE_DOCUMENT_TYPE_CASTS(HTMLDocument);
+template <>
+struct DowncastTraits<HTMLDocument> {
+ static bool AllowFrom(const Document& document) {
+ return document.IsHTMLDocument();
+ }
+};
} // namespace blink
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 18999b78414..1c9bd6fa2c2 100644
--- a/chromium/third_party/blink/renderer/core/html/html_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_element.cc
@@ -61,6 +61,7 @@
#include "third_party/blink/renderer/core/html/forms/labels_node_list.h"
#include "third_party/blink/renderer/core/html/html_br_element.h"
#include "third_party/blink/renderer/core/html/html_dimension.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_template_element.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
@@ -135,7 +136,7 @@ const WebFeature kNoWebFeature = static_cast<WebFeature>(0);
} // anonymous namespace
String HTMLElement::DebugNodeName() const {
- if (GetDocument().IsHTMLDocument()) {
+ if (IsA<HTMLDocument>(GetDocument())) {
return TagQName().HasPrefix() ? Element::nodeName().UpperASCII()
: TagQName().LocalName().UpperASCII();
}
@@ -150,7 +151,7 @@ String HTMLElement::nodeName() const {
// chars that does not have to copy the string on a hit in the hash.
// FIXME: We should have a way to detect XHTML elements and replace the
// hasPrefix() check with it.
- if (GetDocument().IsHTMLDocument()) {
+ if (IsA<HTMLDocument>(GetDocument())) {
if (!TagQName().HasPrefix())
return TagQName().LocalNameUpper();
return Element::nodeName().UpperASCII();
@@ -253,9 +254,9 @@ bool HTMLElement::IsPresentationAttribute(const QualifiedName& name) const {
}
static inline bool IsValidDirAttribute(const AtomicString& value) {
- return DeprecatedEqualIgnoringCase(value, "auto") ||
- DeprecatedEqualIgnoringCase(value, "ltr") ||
- DeprecatedEqualIgnoringCase(value, "rtl");
+ return EqualIgnoringASCIICase(value, "auto") ||
+ EqualIgnoringASCIICase(value, "ltr") ||
+ EqualIgnoringASCIICase(value, "rtl");
}
void HTMLElement::CollectStyleForPresentationAttribute(
@@ -263,7 +264,7 @@ void HTMLElement::CollectStyleForPresentationAttribute(
const AtomicString& value,
MutableCSSPropertyValueSet* style) {
if (name == html_names::kAlignAttr) {
- if (DeprecatedEqualIgnoringCase(value, "middle")) {
+ if (EqualIgnoringASCIICase(value, "middle")) {
AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kTextAlign,
CSSValueID::kCenter);
} else {
@@ -271,7 +272,7 @@ void HTMLElement::CollectStyleForPresentationAttribute(
value);
}
} else if (name == html_names::kContenteditableAttr) {
- if (value.IsEmpty() || DeprecatedEqualIgnoringCase(value, "true")) {
+ if (value.IsEmpty() || EqualIgnoringASCIICase(value, "true")) {
AddPropertyToPresentationAttributeStyle(
style, CSSPropertyID::kWebkitUserModify, CSSValueID::kReadWrite);
AddPropertyToPresentationAttributeStyle(
@@ -283,7 +284,7 @@ void HTMLElement::CollectStyleForPresentationAttribute(
UseCounter::Count(GetDocument(),
WebFeature::kContentEditableTrueOnHTML);
}
- } else if (DeprecatedEqualIgnoringCase(value, "plaintext-only")) {
+ } else if (EqualIgnoringASCIICase(value, "plaintext-only")) {
AddPropertyToPresentationAttributeStyle(
style, CSSPropertyID::kWebkitUserModify,
CSSValueID::kReadWritePlaintextOnly);
@@ -293,7 +294,7 @@ void HTMLElement::CollectStyleForPresentationAttribute(
style, CSSPropertyID::kWebkitLineBreak, CSSValueID::kAfterWhiteSpace);
UseCounter::Count(GetDocument(),
WebFeature::kContentEditablePlainTextOnly);
- } else if (DeprecatedEqualIgnoringCase(value, "false")) {
+ } else if (EqualIgnoringASCIICase(value, "false")) {
AddPropertyToPresentationAttributeStyle(
style, CSSPropertyID::kWebkitUserModify, CSSValueID::kReadOnly);
}
@@ -302,17 +303,17 @@ void HTMLElement::CollectStyleForPresentationAttribute(
CSSValueID::kNone);
} else if (name == html_names::kDraggableAttr) {
UseCounter::Count(GetDocument(), WebFeature::kDraggableAttribute);
- if (DeprecatedEqualIgnoringCase(value, "true")) {
+ if (EqualIgnoringASCIICase(value, "true")) {
AddPropertyToPresentationAttributeStyle(
style, CSSPropertyID::kWebkitUserDrag, CSSValueID::kElement);
AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kUserSelect,
CSSValueID::kNone);
- } else if (DeprecatedEqualIgnoringCase(value, "false")) {
+ } else if (EqualIgnoringASCIICase(value, "false")) {
AddPropertyToPresentationAttributeStyle(
style, CSSPropertyID::kWebkitUserDrag, CSSValueID::kNone);
}
} else if (name == html_names::kDirAttr) {
- if (DeprecatedEqualIgnoringCase(value, "auto")) {
+ if (EqualIgnoringASCIICase(value, "auto")) {
AddPropertyToPresentationAttributeStyle(
style, CSSPropertyID::kUnicodeBidi,
UnicodeBidiAttributeForDirAuto(this));
@@ -600,8 +601,6 @@ AttributeTriggers* HTMLElement::TriggersForAttributeName(
kNoEvent, nullptr},
{html_names::kAriaHaspopupAttr, WebFeature::kARIAHasPopupAttribute,
kNoEvent, nullptr},
- {html_names::kAriaHelpAttr, WebFeature::kARIAHelpAttribute, kNoEvent,
- nullptr},
{html_names::kAriaHiddenAttr, WebFeature::kARIAHiddenAttribute, kNoEvent,
nullptr},
{html_names::kAriaInvalidAttr, WebFeature::kARIAInvalidAttribute,
@@ -743,12 +742,8 @@ void HTMLElement::ParseAttribute(const AttributeModificationParams& params) {
if (triggers->web_feature != kNoWebFeature) {
// Count usage of attributes but ignore attributes in user agent shadow DOM.
- if (!IsInUserAgentShadowRoot()) {
- if (triggers->web_feature == WebFeature::kARIAHelpAttribute)
- Deprecation::CountDeprecation(GetDocument(), triggers->web_feature);
- else
- UseCounter::Count(GetDocument(), triggers->web_feature);
- }
+ if (!IsInUserAgentShadowRoot())
+ UseCounter::Count(GetDocument(), triggers->web_feature);
}
if (triggers->function)
((*this).*(triggers->function))(params);
@@ -895,25 +890,25 @@ void HTMLElement::ApplyAlignmentAttributeToStyle(
CSSValueID float_value = CSSValueID::kInvalid;
CSSValueID vertical_align_value = CSSValueID::kInvalid;
- if (DeprecatedEqualIgnoringCase(alignment, "absmiddle")) {
+ if (EqualIgnoringASCIICase(alignment, "absmiddle")) {
vertical_align_value = CSSValueID::kMiddle;
- } else if (DeprecatedEqualIgnoringCase(alignment, "absbottom")) {
+ } else if (EqualIgnoringASCIICase(alignment, "absbottom")) {
vertical_align_value = CSSValueID::kBottom;
- } else if (DeprecatedEqualIgnoringCase(alignment, "left")) {
+ } else if (EqualIgnoringASCIICase(alignment, "left")) {
float_value = CSSValueID::kLeft;
vertical_align_value = CSSValueID::kTop;
- } else if (DeprecatedEqualIgnoringCase(alignment, "right")) {
+ } else if (EqualIgnoringASCIICase(alignment, "right")) {
float_value = CSSValueID::kRight;
vertical_align_value = CSSValueID::kTop;
- } else if (DeprecatedEqualIgnoringCase(alignment, "top")) {
+ } else if (EqualIgnoringASCIICase(alignment, "top")) {
vertical_align_value = CSSValueID::kTop;
- } else if (DeprecatedEqualIgnoringCase(alignment, "middle")) {
+ } else if (EqualIgnoringASCIICase(alignment, "middle")) {
vertical_align_value = CSSValueID::kWebkitBaselineMiddle;
- } else if (DeprecatedEqualIgnoringCase(alignment, "center")) {
+ } else if (EqualIgnoringASCIICase(alignment, "center")) {
vertical_align_value = CSSValueID::kMiddle;
- } else if (DeprecatedEqualIgnoringCase(alignment, "bottom")) {
+ } else if (EqualIgnoringASCIICase(alignment, "bottom")) {
vertical_align_value = CSSValueID::kBaseline;
- } else if (DeprecatedEqualIgnoringCase(alignment, "texttop")) {
+ } else if (EqualIgnoringASCIICase(alignment, "texttop")) {
vertical_align_value = CSSValueID::kTextTop;
}
@@ -938,11 +933,11 @@ String HTMLElement::contentEditable() const {
if (value.IsNull())
return "inherit";
- if (value.IsEmpty() || DeprecatedEqualIgnoringCase(value, "true"))
+ if (value.IsEmpty() || EqualIgnoringASCIICase(value, "true"))
return "true";
- if (DeprecatedEqualIgnoringCase(value, "false"))
+ if (EqualIgnoringASCIICase(value, "false"))
return "false";
- if (DeprecatedEqualIgnoringCase(value, "plaintext-only"))
+ if (EqualIgnoringASCIICase(value, "plaintext-only"))
return "plaintext-only";
return "inherit";
@@ -950,13 +945,13 @@ String HTMLElement::contentEditable() const {
void HTMLElement::setContentEditable(const String& enabled,
ExceptionState& exception_state) {
- if (DeprecatedEqualIgnoringCase(enabled, "true"))
+ if (EqualIgnoringASCIICase(enabled, "true"))
setAttribute(html_names::kContenteditableAttr, "true");
- else if (DeprecatedEqualIgnoringCase(enabled, "false"))
+ else if (EqualIgnoringASCIICase(enabled, "false"))
setAttribute(html_names::kContenteditableAttr, "false");
- else if (DeprecatedEqualIgnoringCase(enabled, "plaintext-only"))
+ else if (EqualIgnoringASCIICase(enabled, "plaintext-only"))
setAttribute(html_names::kContenteditableAttr, "plaintext-only");
- else if (DeprecatedEqualIgnoringCase(enabled, "inherit"))
+ else if (EqualIgnoringASCIICase(enabled, "inherit"))
removeAttribute(html_names::kContenteditableAttr);
else
exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
@@ -996,8 +991,8 @@ bool HTMLElement::isContentEditableForBinding() const {
}
bool HTMLElement::draggable() const {
- return DeprecatedEqualIgnoringCase(
- FastGetAttribute(html_names::kDraggableAttr), "true");
+ return EqualIgnoringASCIICase(FastGetAttribute(html_names::kDraggableAttr),
+ "true");
}
void HTMLElement::setDraggable(bool value) {
@@ -1031,10 +1026,9 @@ TranslateAttributeMode HTMLElement::GetTranslateAttributeMode() const {
if (value == g_null_atom)
return kTranslateAttributeInherit;
- if (DeprecatedEqualIgnoringCase(value, "yes") ||
- DeprecatedEqualIgnoringCase(value, ""))
+ if (EqualIgnoringASCIICase(value, "yes") || EqualIgnoringASCIICase(value, ""))
return kTranslateAttributeYes;
- if (DeprecatedEqualIgnoringCase(value, "no"))
+ if (EqualIgnoringASCIICase(value, "no"))
return kTranslateAttributeNo;
return kTranslateAttributeInherit;
@@ -1069,11 +1063,11 @@ static inline const AtomicString& ToValidDirValue(const AtomicString& value) {
DEFINE_STATIC_LOCAL(const AtomicString, rtl_value, ("rtl"));
DEFINE_STATIC_LOCAL(const AtomicString, auto_value, ("auto"));
- if (DeprecatedEqualIgnoringCase(value, ltr_value))
+ if (EqualIgnoringASCIICase(value, ltr_value))
return ltr_value;
- if (DeprecatedEqualIgnoringCase(value, rtl_value))
+ if (EqualIgnoringASCIICase(value, rtl_value))
return rtl_value;
- if (DeprecatedEqualIgnoringCase(value, auto_value))
+ if (EqualIgnoringASCIICase(value, auto_value))
return auto_value;
return g_null_atom;
}
@@ -1106,7 +1100,7 @@ bool HTMLElement::HasDirectionAuto() const {
// https://html.spec.whatwg.org/C/#the-bdi-element
const AtomicString& direction = FastGetAttribute(html_names::kDirAttr);
return (IsA<HTMLBDIElement>(*this) && direction == g_null_atom) ||
- DeprecatedEqualIgnoringCase(direction, "auto");
+ EqualIgnoringASCIICase(direction, "auto");
}
TextDirection HTMLElement::DirectionalityIfhasDirAutoAttribute(
@@ -1129,7 +1123,7 @@ TextDirection HTMLElement::Directionality() const {
while (node) {
// Skip bdi, script, style and text form controls.
auto* element = DynamicTo<Element>(node);
- if (DeprecatedEqualIgnoringCase(node->nodeName(), "bdi") ||
+ if (EqualIgnoringASCIICase(node->nodeName(), "bdi") ||
IsA<HTMLScriptElement>(*node) || IsA<HTMLStyleElement>(*node) ||
(element && element->IsTextControl()) ||
(element && element->ShadowPseudoId() == "-webkit-input-placeholder")) {
@@ -1218,11 +1212,8 @@ Node::InsertionNotificationRequest HTMLElement::InsertedInto(
// Process the superclass first to ensure that `InActiveDocument()` is
// updated.
Element::InsertedInto(insertion_point);
+ HideNonce();
- if (GetDocument().GetContentSecurityPolicy()->HasHeaderDeliveredPolicy() &&
- InActiveDocument() && FastHasAttribute(html_names::kNonceAttr)) {
- setAttribute(html_names::kNonceAttr, g_empty_atom);
- }
if (IsFormAssociatedCustomElement())
EnsureElementInternals().InsertedInto(insertion_point);
@@ -1343,7 +1334,7 @@ bool HTMLElement::ParseColorWithLegacyRules(const String& attribute_value,
String color_string = attribute_value.StripWhiteSpace();
// "transparent" doesn't apply a color either.
- if (DeprecatedEqualIgnoringCase(color_string, "transparent"))
+ if (EqualIgnoringASCIICase(color_string, "transparent"))
return false;
// If the string is a 3/6-digit hex color or a named CSS color, use that.
@@ -1387,8 +1378,9 @@ bool HTMLElement::IsInteractiveContent() const {
}
void HTMLElement::DefaultEventHandler(Event& event) {
- if (event.type() == event_type_names::kKeypress && event.IsKeyboardEvent()) {
- HandleKeypressEvent(ToKeyboardEvent(event));
+ auto* keyboard_event = DynamicTo<KeyboardEvent>(event);
+ if (event.type() == event_type_names::kKeypress && keyboard_event) {
+ HandleKeypressEvent(*keyboard_event);
if (event.DefaultHandled())
return;
}
@@ -1396,6 +1388,38 @@ void HTMLElement::DefaultEventHandler(Event& event) {
Element::DefaultEventHandler(event);
}
+bool HTMLElement::HandleKeyboardActivation(Event& event) {
+ auto* keyboard_event = DynamicTo<KeyboardEvent>(event);
+ if (keyboard_event) {
+ if (event.type() == event_type_names::kKeydown &&
+ keyboard_event->key() == " ") {
+ SetActive(true);
+ // No setDefaultHandled() - IE dispatches a keypress in this case.
+ return true;
+ }
+ if (event.type() == event_type_names::kKeypress) {
+ switch (keyboard_event->charCode()) {
+ case '\r':
+ DispatchSimulatedClick(&event);
+ event.SetDefaultHandled();
+ return true;
+ case ' ':
+ // Prevent scrolling down the page.
+ event.SetDefaultHandled();
+ return true;
+ }
+ }
+ if (event.type() == event_type_names::kKeyup &&
+ keyboard_event->key() == " ") {
+ if (IsActive())
+ DispatchSimulatedClick(&event);
+ event.SetDefaultHandled();
+ return true;
+ }
+ }
+ return false;
+}
+
bool HTMLElement::MatchesReadOnlyPseudoClass() const {
return !MatchesReadWritePseudoClass();
}
@@ -1405,10 +1429,10 @@ bool HTMLElement::MatchesReadWritePseudoClass() const {
const AtomicString& value =
FastGetAttribute(html_names::kContenteditableAttr);
- if (value.IsEmpty() || DeprecatedEqualIgnoringCase(value, "true") ||
- DeprecatedEqualIgnoringCase(value, "plaintext-only"))
+ if (value.IsEmpty() || EqualIgnoringASCIICase(value, "true") ||
+ EqualIgnoringASCIICase(value, "plaintext-only"))
return true;
- if (DeprecatedEqualIgnoringCase(value, "false"))
+ if (EqualIgnoringASCIICase(value, "false"))
return false;
// All other values should be treated as "inherit".
}
@@ -1436,7 +1460,8 @@ void HTMLElement::HandleKeypressEvent(KeyboardEvent& event) {
}
int HTMLElement::offsetLeftForBinding() {
- GetDocument().EnsurePaintLocationDataValidForNode(this);
+ GetDocument().EnsurePaintLocationDataValidForNode(
+ this, DocumentUpdateReason::kJavaScript);
Element* offset_parent = unclosedOffsetParent();
if (LayoutBoxModelObject* layout_object = GetLayoutBoxModelObject())
return AdjustForAbsoluteZoom::AdjustLayoutUnit(
@@ -1447,7 +1472,8 @@ int HTMLElement::offsetLeftForBinding() {
}
int HTMLElement::offsetTopForBinding() {
- GetDocument().EnsurePaintLocationDataValidForNode(this);
+ GetDocument().EnsurePaintLocationDataValidForNode(
+ this, DocumentUpdateReason::kJavaScript);
Element* offset_parent = unclosedOffsetParent();
if (LayoutBoxModelObject* layout_object = GetLayoutBoxModelObject())
return AdjustForAbsoluteZoom::AdjustLayoutUnit(
@@ -1458,7 +1484,8 @@ int HTMLElement::offsetTopForBinding() {
}
int HTMLElement::offsetWidthForBinding() {
- GetDocument().EnsurePaintLocationDataValidForNode(this);
+ GetDocument().EnsurePaintLocationDataValidForNode(
+ this, DocumentUpdateReason::kJavaScript);
Element* offset_parent = unclosedOffsetParent();
if (LayoutBoxModelObject* layout_object = GetLayoutBoxModelObject())
return AdjustForAbsoluteZoom::AdjustLayoutUnit(
@@ -1471,7 +1498,8 @@ int HTMLElement::offsetWidthForBinding() {
DISABLE_CFI_PERF
int HTMLElement::offsetHeightForBinding() {
- GetDocument().EnsurePaintLocationDataValidForNode(this);
+ GetDocument().EnsurePaintLocationDataValidForNode(
+ this, DocumentUpdateReason::kJavaScript);
Element* offset_parent = unclosedOffsetParent();
if (LayoutBoxModelObject* layout_object = GetLayoutBoxModelObject())
return AdjustForAbsoluteZoom::AdjustLayoutUnit(
@@ -1483,7 +1511,8 @@ int HTMLElement::offsetHeightForBinding() {
}
Element* HTMLElement::unclosedOffsetParent() {
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
LayoutObject* layout_object = GetLayoutObject();
if (!layout_object)
@@ -1504,7 +1533,7 @@ void HTMLElement::OnDirAttrChanged(const AttributeModificationParams& params) {
parent->AdjustDirectionalityIfNeededAfterChildAttributeChanged(this);
}
- if (DeprecatedEqualIgnoringCase(params.new_value, "auto"))
+ if (EqualIgnoringASCIICase(params.new_value, "auto"))
CalculateAndAdjustDirectionality();
}
@@ -1631,6 +1660,6 @@ void HTMLElement::FinishParsingChildren() {
void dumpInnerHTML(blink::HTMLElement*);
void dumpInnerHTML(blink::HTMLElement* element) {
- printf("%s\n", element->InnerHTMLAsString().Ascii().c_str());
+ printf("%s\n", element->innerHTML().Ascii().c_str());
}
#endif
diff --git a/chromium/third_party/blink/renderer/core/html/html_element.h b/chromium/third_party/blink/renderer/core/html/html_element.h
index 6da94b1c55e..6df6aae825a 100644
--- a/chromium/third_party/blink/renderer/core/html/html_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_element.h
@@ -25,6 +25,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/element.h"
+#include "third_party/blink/renderer/core/html/forms/labels_node_list.h"
#include "third_party/blink/renderer/platform/text/text_direction.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
@@ -38,7 +39,6 @@ class ExceptionState;
class FormAssociated;
class HTMLFormElement;
class KeyboardEvent;
-class LabelsNodeList;
class StringOrTrustedScript;
class StringTreatNullAsEmptyStringOrTrustedScript;
@@ -109,6 +109,7 @@ class CORE_EXPORT HTMLElement : public Element {
virtual bool IsHTMLUnknownElement() const { return false; }
virtual bool IsPluginElement() const { return false; }
+ virtual bool IsHTMLPortalElement() const { return false; }
// https://html.spec.whatwg.org/C/#category-label
virtual bool IsLabelable() const;
@@ -119,6 +120,10 @@ class CORE_EXPORT HTMLElement : public Element {
virtual bool IsInteractiveContent() const;
void DefaultEventHandler(Event&) override;
+ // Used to handle return/space key events and simulate clicks. Returns true
+ // if the event is handled.
+ bool HandleKeyboardActivation(Event& event);
+
static const AtomicString& EventNameForAttributeName(
const QualifiedName& attr_name);
@@ -215,19 +220,20 @@ class CORE_EXPORT HTMLElement : public Element {
void OnXMLLangAttrChanged(const AttributeModificationParams&);
};
-DEFINE_ELEMENT_TYPE_CASTS(HTMLElement, IsHTMLElement());
-
-template <>
-struct DowncastTraits<HTMLElement> {
- static bool AllowFrom(const Node& node) { return node.IsHTMLElement(); }
-};
-
template <typename T>
bool IsElementOfType(const HTMLElement&);
template <>
inline bool IsElementOfType<const HTMLElement>(const HTMLElement&) {
return true;
}
+template <>
+inline bool IsElementOfType<const HTMLElement>(const Node& node) {
+ return IsA<HTMLElement>(node);
+}
+template <>
+struct DowncastTraits<HTMLElement> {
+ static bool AllowFrom(const Node& node) { return node.IsHTMLElement(); }
+};
inline HTMLElement::HTMLElement(const QualifiedName& tag_name,
Document& document,
@@ -257,31 +263,6 @@ class HasHTMLTagName {
const HTMLQualifiedName& tag_name_;
};
-// This requires isHTML*Element(const Element&) and isHTML*Element(const
-// HTMLElement&). When the input element is an HTMLElement, we don't need to
-// check the namespace URI, just the local name.
-#define DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(thisType) \
- inline bool Is##thisType(const thisType* element); \
- inline bool Is##thisType(const thisType& element); \
- inline bool Is##thisType(const HTMLElement* element) { \
- return element && Is##thisType(*element); \
- } \
- inline bool Is##thisType(const Node& node) { \
- auto* html_element = DynamicTo<HTMLElement>(node); \
- return html_element ? Is##thisType(html_element) : false; \
- } \
- inline bool Is##thisType(const Node* node) { \
- return node && Is##thisType(*node); \
- } \
- inline bool Is##thisType(const Element* element) { \
- return element && Is##thisType(*element); \
- } \
- template <> \
- inline bool IsElementOfType<const thisType>(const HTMLElement& element) { \
- return Is##thisType(element); \
- } \
- DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(thisType)
-
} // namespace blink
#include "third_party/blink/renderer/core/html_element_type_helpers.h"
diff --git a/chromium/third_party/blink/renderer/core/html/html_embed_element.cc b/chromium/third_party/blink/renderer/core/html/html_embed_element.cc
index d46098534e3..7e2fd8dfe24 100644
--- a/chromium/third_party/blink/renderer/core/html/html_embed_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_embed_element.cc
@@ -52,7 +52,7 @@ HTMLEmbedElement::HTMLEmbedElement(Document& document,
const AttrNameToTrustedType& HTMLEmbedElement::GetCheckedAttributeTypes()
const {
DEFINE_STATIC_LOCAL(AttrNameToTrustedType, attribute_map,
- ({{"src", SpecificTrustedType::kTrustedScriptURL}}));
+ ({{"src", SpecificTrustedType::kScriptURL}}));
return attribute_map;
}
@@ -83,8 +83,8 @@ void HTMLEmbedElement::CollectStyleForPresentationAttribute(
const AtomicString& value,
MutableCSSPropertyValueSet* style) {
if (name == html_names::kHiddenAttr) {
- if (DeprecatedEqualIgnoringCase(value, "yes") ||
- DeprecatedEqualIgnoringCase(value, "true")) {
+ if (EqualIgnoringASCIICase(value, "yes") ||
+ EqualIgnoringASCIICase(value, "true")) {
AddPropertyToPresentationAttributeStyle(
style, CSSPropertyID::kWidth, 0,
CSSPrimitiveValue::UnitType::kPixels);
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 ca50bff4be0..fd0fbfb5cea 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
@@ -24,6 +24,7 @@
#include "third_party/blink/renderer/core/html/html_frame_element.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
+#include "third_party/blink/public/mojom/feature_policy/policy_value.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/html/html_frame_set_element.h"
#include "third_party/blink/renderer/core/html_names.h"
@@ -82,7 +83,8 @@ ParsedFeaturePolicy HTMLFrameElement::ConstructContainerPolicy(
// https://fullscreen.spec.whatwg.org/#model
ParsedFeaturePolicy container_policy;
ParsedFeaturePolicyDeclaration allowlist(
- mojom::FeaturePolicyFeature::kFullscreen, mojom::PolicyValueType::kBool);
+ mojom::blink::FeaturePolicyFeature::kFullscreen,
+ mojom::blink::PolicyValueType::kBool);
container_policy.push_back(allowlist);
return container_policy;
}
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 805abe36b02..c4018d9db27 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
@@ -30,6 +30,8 @@
#include "third_party/blink/renderer/core/dom/attribute.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/frame_console.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/local_frame_view.h"
@@ -37,16 +39,18 @@
#include "third_party/blink/renderer/core/frame/remote_frame_view.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/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/loader/frame_loader.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/platform/heap/heap.h"
namespace blink {
HTMLFrameElementBase::HTMLFrameElementBase(const QualifiedName& tag_name,
Document& document)
: HTMLFrameOwnerElement(tag_name, document),
- scrolling_mode_(ScrollbarMode::kAuto),
+ scrollbar_mode_(mojom::blink::ScrollbarMode::kAuto),
margin_width_(-1),
margin_height_(-1) {}
@@ -85,6 +89,21 @@ void HTMLFrameElementBase::OpenURL(bool replace_current_item) {
return;
KURL url = GetDocument().CompleteURL(url_);
+ // There is no (easy) way to tell if |url_| is relative at this point. That
+ // is determined in the KURL constructor. If we fail to create an absolute
+ // 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>(
+ mojom::ConsoleMessageSource::kRendering,
+ mojom::ConsoleMessageLevel::kWarning,
+ "Invalid relative frame source URL (" + url_ +
+ ") within data URL."));
+ }
+ }
+ }
LoadOrRedirectSubframe(url, frame_name_, replace_current_item);
}
@@ -115,13 +134,18 @@ void HTMLFrameElementBase::ParseAttribute(
} else if (name == html_names::kMarginheightAttr) {
SetMarginHeight(value.ToInt());
} else if (name == html_names::kScrollingAttr) {
- // Auto and yes both simply mean "allow scrolling." No means "don't allow
- // scrolling."
- if (DeprecatedEqualIgnoringCase(value, "auto") ||
- DeprecatedEqualIgnoringCase(value, "yes"))
- SetScrollingMode(ScrollbarMode::kAuto);
- else if (DeprecatedEqualIgnoringCase(value, "no"))
- SetScrollingMode(ScrollbarMode::kAlwaysOff);
+ // https://html.spec.whatwg.org/multipage/rendering.html#the-page:
+ // If [the scrolling] attribute's value is an ASCII
+ // case-insensitive match for the string "off", "noscroll", or "no", then
+ // the user agent is expected to prevent any scrollbars from being shown for
+ // the viewport of the Document's browsing context, regardless of the
+ // 'overflow' property that applies to that viewport.
+ if (EqualIgnoringASCIICase(value, "off") ||
+ EqualIgnoringASCIICase(value, "noscroll") ||
+ EqualIgnoringASCIICase(value, "no"))
+ SetScrollbarMode(mojom::blink::ScrollbarMode::kAlwaysOff);
+ else
+ SetScrollbarMode(mojom::blink::ScrollbarMode::kAuto);
} else if (name == html_names::kOnbeforeunloadAttr) {
// FIXME: should <frame> elements have beforeunload handlers?
SetAttributeEventListener(
@@ -137,8 +161,9 @@ void HTMLFrameElementBase::ParseAttribute(
scoped_refptr<const SecurityOrigin>
HTMLFrameElementBase::GetOriginForFeaturePolicy() const {
// Sandboxed frames have a unique origin.
- if ((GetFramePolicy().sandbox_flags & WebSandboxFlags::kOrigin) !=
- WebSandboxFlags::kNone)
+ if ((GetFramePolicy().sandbox_flags &
+ mojom::blink::WebSandboxFlags::kOrigin) !=
+ mojom::blink::WebSandboxFlags::kNone)
return SecurityOrigin::CreateUniqueOpaque();
// If the frame will inherit its origin from the owner, then use the owner's
@@ -201,7 +226,8 @@ int HTMLFrameElementBase::DefaultTabIndex() const {
return 0;
}
-void HTMLFrameElementBase::SetFocused(bool received, WebFocusType focus_type) {
+void HTMLFrameElementBase::SetFocused(bool received,
+ mojom::blink::FocusType focus_type) {
HTMLFrameOwnerElement::SetFocused(received, focus_type);
if (Page* page = GetDocument().GetPage()) {
if (received) {
@@ -231,15 +257,16 @@ bool HTMLFrameElementBase::IsHTMLContentAttribute(
HTMLFrameOwnerElement::IsHTMLContentAttribute(attribute);
}
-void HTMLFrameElementBase::SetScrollingMode(ScrollbarMode scrollbar_mode) {
- if (scrolling_mode_ == scrollbar_mode)
+void HTMLFrameElementBase::SetScrollbarMode(
+ mojom::blink::ScrollbarMode scrollbar_mode) {
+ if (scrollbar_mode_ == scrollbar_mode)
return;
if (contentDocument()) {
contentDocument()->WillChangeFrameOwnerProperties(
margin_width_, margin_height_, scrollbar_mode, IsDisplayNone());
}
- scrolling_mode_ = scrollbar_mode;
+ scrollbar_mode_ = scrollbar_mode;
FrameOwnerPropertiesChanged();
}
@@ -249,7 +276,7 @@ void HTMLFrameElementBase::SetMarginWidth(int margin_width) {
if (contentDocument()) {
contentDocument()->WillChangeFrameOwnerProperties(
- margin_width, margin_height_, scrolling_mode_, IsDisplayNone());
+ margin_width, margin_height_, scrollbar_mode_, IsDisplayNone());
}
margin_width_ = margin_width;
FrameOwnerPropertiesChanged();
@@ -261,7 +288,7 @@ void HTMLFrameElementBase::SetMarginHeight(int margin_height) {
if (contentDocument()) {
contentDocument()->WillChangeFrameOwnerProperties(
- margin_width_, margin_height, scrolling_mode_, IsDisplayNone());
+ margin_width_, margin_height, scrollbar_mode_, IsDisplayNone());
}
margin_height_ = margin_height;
FrameOwnerPropertiesChanged();
diff --git a/chromium/third_party/blink/renderer/core/html/html_frame_element_base.h b/chromium/third_party/blink/renderer/core/html/html_frame_element_base.h
index a20a97699ea..9da4e6b8aed 100644
--- a/chromium/third_party/blink/renderer/core/html/html_frame_element_base.h
+++ b/chromium/third_party/blink/renderer/core/html/html_frame_element_base.h
@@ -24,7 +24,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_FRAME_ELEMENT_BASE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_FRAME_ELEMENT_BASE_H_
-#include "third_party/blink/public/platform/web_focus_type.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
+#include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
@@ -35,7 +36,9 @@ class CORE_EXPORT HTMLFrameElementBase : public HTMLFrameOwnerElement {
bool CanContainRangeEndPoint() const final { return false; }
// FrameOwner overrides:
- ScrollbarMode ScrollingMode() const final { return scrolling_mode_; }
+ mojom::blink::ScrollbarMode ScrollbarMode() const final {
+ return scrollbar_mode_;
+ }
int MarginWidth() const final { return margin_width_; }
int MarginHeight() const final { return margin_height_; }
@@ -51,7 +54,7 @@ class CORE_EXPORT HTMLFrameElementBase : public HTMLFrameOwnerElement {
void DidNotifySubtreeInsertionsToDocument() final;
void AttachLayoutTree(AttachContext&) override;
- void SetScrollingMode(ScrollbarMode);
+ void SetScrollbarMode(mojom::blink::ScrollbarMode);
void SetMarginWidth(int);
void SetMarginHeight(int);
@@ -67,7 +70,7 @@ class CORE_EXPORT HTMLFrameElementBase : public HTMLFrameOwnerElement {
private:
bool SupportsFocus() const final;
int DefaultTabIndex() const final;
- void SetFocused(bool, WebFocusType) final;
+ void SetFocused(bool, mojom::blink::FocusType) final;
bool IsURLAttribute(const Attribute&) const final;
bool HasLegalLinkAttribute(const QualifiedName&) const final;
@@ -80,7 +83,7 @@ class CORE_EXPORT HTMLFrameElementBase : public HTMLFrameOwnerElement {
bool IsURLAllowed() const;
void OpenURL(bool replace_current_item = true);
- ScrollbarMode scrolling_mode_;
+ mojom::blink::ScrollbarMode scrollbar_mode_;
int margin_width_;
int margin_height_;
@@ -88,11 +91,21 @@ class CORE_EXPORT HTMLFrameElementBase : public HTMLFrameOwnerElement {
AtomicString frame_name_;
};
-inline bool IsHTMLFrameElementBase(const HTMLElement& element) {
- return IsA<HTMLFrameElement>(element) || IsA<HTMLIFrameElement>(element);
+template <>
+inline bool IsElementOfType<const HTMLFrameElementBase>(const Node& node) {
+ return IsA<HTMLFrameElementBase>(node);
}
-
-DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLFrameElementBase);
+template <>
+struct DowncastTraits<HTMLFrameElementBase> {
+ static bool AllowFrom(const Node& node) {
+ auto* html_element = DynamicTo<HTMLElement>(node);
+ return html_element && AllowFrom(*html_element);
+ }
+ static bool AllowFrom(const HTMLElement& html_element) {
+ return IsA<HTMLFrameElement>(html_element) ||
+ IsA<HTMLIFrameElement>(html_element);
+ }
+};
} // namespace blink
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 1f51546d661..8169d96f858 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
@@ -34,7 +34,7 @@ TEST_F(HTMLFrameElementTest, DefaultContainerPolicy) {
frame_element->GetFramePolicy().container_policy;
EXPECT_EQ(1UL, container_policy.size());
// Fullscreen should be disabled in this frame
- EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen,
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen,
container_policy[0].feature);
EXPECT_EQ(0UL, container_policy[0].values.size());
EXPECT_GE(PolicyValue(false), container_policy[0].fallback_value);
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 283c6919786..9be37732a9c 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
@@ -20,6 +20,7 @@
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
+#include "third_party/blink/public/common/features.h"
#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/renderer/core/accessibility/ax_object_cache.h"
@@ -224,6 +225,7 @@ void HTMLFrameOwnerElement::ClearContentFrame() {
DCHECK_EQ(content_frame_->Owner(), this);
content_frame_ = nullptr;
+ embedding_token_ = base::nullopt;
for (ContainerNode* node = this; node; node = node->ParentOrShadowHostNode())
node->DecrementConnectedSubframeCount();
@@ -271,7 +273,8 @@ DOMWindow* HTMLFrameOwnerElement::contentWindow() const {
return content_frame_ ? content_frame_->DomWindow() : nullptr;
}
-void HTMLFrameOwnerElement::SetSandboxFlags(WebSandboxFlags flags) {
+void HTMLFrameOwnerElement::SetSandboxFlags(
+ mojom::blink::WebSandboxFlags flags) {
frame_policy_.sandbox_flags = flags;
// Recalculate the container policy in case the allow-same-origin flag has
// changed.
@@ -285,6 +288,16 @@ void HTMLFrameOwnerElement::SetSandboxFlags(WebSandboxFlags flags) {
}
}
+void HTMLFrameOwnerElement::SetDisallowDocumentAccesss(bool disallowed) {
+ frame_policy_.disallow_document_access = 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_);
+ }
+}
+
bool HTMLFrameOwnerElement::IsKeyboardFocusable() const {
return content_frame_ && HTMLElement::IsKeyboardFocusable();
}
@@ -307,6 +320,33 @@ void HTMLFrameOwnerElement::UpdateContainerPolicy(Vector<String>* messages) {
}
}
+void HTMLFrameOwnerElement::UpdateRequiredPolicy() {
+ const auto* frame = GetDocument().GetFrame();
+ DCHECK(frame);
+ DocumentPolicy::FeatureState new_required_policy =
+ DocumentPolicy::MergeFeatureState(
+ ConstructRequiredPolicy(), /* self_required_policy */
+ frame->GetRequiredDocumentPolicy() /* parent_required_policy */);
+
+ // Filter out policies that are disabled by origin trials.
+ 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()))
+ frame_policy_.required_document_policy.insert(*i);
+ ++i;
+ }
+
+ if (ContentFrame()) {
+ frame->Client()->DidChangeFramePolicy(ContentFrame(), frame_policy_);
+ }
+}
+
+network::mojom::blink::TrustTokenParamsPtr
+HTMLFrameOwnerElement::ConstructTrustTokenParams() const {
+ return nullptr;
+}
+
void HTMLFrameOwnerElement::FrameOwnerPropertiesChanged() {
// Don't notify about updates if ContentFrame() is null, for example when
// the subframe hasn't been created yet; or if we are in the middle of
@@ -349,7 +389,7 @@ void HTMLFrameOwnerElement::SetEmbeddedContentView(
bool will_be_display_none = !embedded_content_view;
if (IsDisplayNone() != will_be_display_none) {
doc->WillChangeFrameOwnerProperties(
- MarginWidth(), MarginHeight(), ScrollingMode(), will_be_display_none);
+ MarginWidth(), MarginHeight(), ScrollbarMode(), will_be_display_none);
}
}
@@ -359,7 +399,7 @@ void HTMLFrameOwnerElement::SetEmbeddedContentView(
if (old_view->IsAttached()) {
old_view->DetachFromLayout();
if (old_view->IsPluginView())
- DisposePluginSoon(ToWebPluginContainerImpl(old_view));
+ DisposePluginSoon(To<WebPluginContainerImpl>(old_view));
else
old_view->Dispose();
}
@@ -423,11 +463,17 @@ bool HTMLFrameOwnerElement::LoadOrRedirectSubframe(
}
UpdateContainerPolicy();
+ UpdateRequiredPolicy();
KURL url_to_request = url.IsNull() ? BlankURL() : url;
- ResourceRequest request(url_to_request);
+ ResourceRequestHead request(url_to_request);
request.SetReferrerPolicy(ReferrerPolicyAttribute());
+ network::mojom::blink::TrustTokenParamsPtr trust_token_params =
+ ConstructTrustTokenParams();
+ if (trust_token_params)
+ request.SetTrustTokenParams(*trust_token_params);
+
if (ContentFrame()) {
// TODO(sclittle): Support lazily loading frame navigations.
FrameLoadRequest frame_load_request(&GetDocument(), request);
@@ -499,8 +545,8 @@ bool HTMLFrameOwnerElement::LoadOrRedirectSubframe(
}
}
- child_frame->Loader().StartNavigation(
- FrameLoadRequest(&GetDocument(), request), child_load_type);
+ FrameLoadRequest frame_load_request(&GetDocument(), request);
+ child_frame->Loader().StartNavigation(frame_load_request, child_load_type);
return true;
}
@@ -539,6 +585,20 @@ 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());
+ embedding_token_ = embedding_token;
+}
+
void HTMLFrameOwnerElement::Trace(Visitor* visitor) {
visitor->Trace(content_frame_);
visitor->Trace(embedded_content_view_);
@@ -550,7 +610,7 @@ void HTMLFrameOwnerElement::Trace(Visitor* visitor) {
bool HTMLFrameOwnerElement::IsLoadingFrameDefaultEagerEnforced() const {
return RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled() &&
!GetDocument().IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kLoadingFrameDefaultEager);
+ 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 b5cbf79824b..92cb4da9957 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
@@ -21,7 +21,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_FRAME_OWNER_ELEMENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_FRAME_OWNER_ELEMENT_H_
+#include "services/network/public/mojom/trust_tokens.mojom-blink-forward.h"
#include "third_party/blink/public/common/frame/frame_owner_element_type.h"
+#include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink.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/feature_policy/feature_policy_parser.h"
@@ -46,6 +48,7 @@ class WebPluginContainerImpl;
class CORE_EXPORT HTMLFrameOwnerElement : public HTMLElement,
public FrameOwner {
USING_GARBAGE_COLLECTED_MIXIN(HTMLFrameOwnerElement);
+
public:
~HTMLFrameOwnerElement() override;
@@ -73,6 +76,8 @@ class CORE_EXPORT HTMLFrameOwnerElement : public HTMLElement,
return embedded_content_view_;
}
+ void FrameCrossOriginToParentFrameChanged();
+
class PluginDisposeSuspendScope {
STACK_ALLOCATED();
@@ -107,11 +112,12 @@ class CORE_EXPORT HTMLFrameOwnerElement : public HTMLElement,
AtomicString BrowsingContextContainerName() const override {
return FastGetAttribute(html_names::kNameAttr);
}
- ScrollbarMode ScrollingMode() const override { return ScrollbarMode::kAuto; }
+ mojom::blink::ScrollbarMode ScrollbarMode() const override {
+ return mojom::blink::ScrollbarMode::kAuto;
+ }
int MarginWidth() const override { return -1; }
int MarginHeight() const override { return -1; }
bool AllowFullscreen() const override { return false; }
- bool DisallowDocumentAccess() const override { return false; }
bool AllowPaymentRequest() const override { return false; }
bool IsDisplayNone() const override { return !embedded_content_view_; }
AtomicString RequiredCsp() const override { return g_null_atom; }
@@ -124,15 +130,21 @@ 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_;
+ }
+
void Trace(Visitor*) override;
protected:
HTMLFrameOwnerElement(const QualifiedName& tag_name, Document&);
- void SetSandboxFlags(WebSandboxFlags);
+ void SetSandboxFlags(mojom::blink::WebSandboxFlags);
void SetAllowedToDownload(bool allowed) {
frame_policy_.allowed_to_download = allowed;
}
+ void SetDisallowDocumentAccesss(bool disallowed);
bool LoadOrRedirectSubframe(const KURL&,
const AtomicString& frame_name,
@@ -161,6 +173,21 @@ class CORE_EXPORT HTMLFrameOwnerElement : public HTMLElement,
// changes.
void UpdateContainerPolicy(Vector<String>* messages = nullptr);
+ // Return a document policy required policy for this frame, based on the
+ // frame attributes.
+ virtual DocumentPolicy::FeatureState ConstructRequiredPolicy() const {
+ return DocumentPolicy::FeatureState{};
+ }
+
+ // Update the required policy and notify the frame loader client of any
+ // changes.
+ void UpdateRequiredPolicy();
+
+ // Return a set of Trust Tokens parameters for requests for this frame,
+ // based on the frame attributes.
+ virtual network::mojom::blink::TrustTokenParamsPtr ConstructTrustTokenParams()
+ const;
+
private:
// Intentionally private to prevent redundant checks when the type is
// already HTMLFrameOwnerElement.
@@ -180,6 +207,7 @@ class CORE_EXPORT HTMLFrameOwnerElement : public HTMLElement,
Member<Frame> content_frame_;
Member<EmbeddedContentView> embedded_content_view_;
FramePolicy frame_policy_;
+ base::Optional<base::UnguessableToken> embedding_token_;
Member<LazyLoadFrameObserver> lazy_load_frame_observer_;
bool should_lazy_load_children_;
@@ -221,7 +249,7 @@ class SubframeLoadingDisabler {
CORE_EXPORT static SubtreeRootSet& DisabledSubtreeRoots();
- Member<Node> root_;
+ Node* root_;
};
template <>
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 9d4cb87fd93..5239ea86169 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
@@ -86,12 +86,12 @@ void HTMLFrameSetElement::ParseAttribute(
}
} else if (name == html_names::kFrameborderAttr) {
if (!value.IsNull()) {
- if (DeprecatedEqualIgnoringCase(value, "no") ||
- DeprecatedEqualIgnoringCase(value, "0")) {
+ if (EqualIgnoringASCIICase(value, "no") ||
+ EqualIgnoringASCIICase(value, "0")) {
frameborder_ = false;
frameborder_set_ = true;
- } else if (DeprecatedEqualIgnoringCase(value, "yes") ||
- DeprecatedEqualIgnoringCase(value, "1")) {
+ } else if (EqualIgnoringASCIICase(value, "yes") ||
+ EqualIgnoringASCIICase(value, "1")) {
frameborder_set_ = true;
}
} else {
@@ -202,11 +202,16 @@ void HTMLFrameSetElement::ParseAttribute(
GetDocument().SetWindowAttributeEventListener(
event_type_names::kLanguagechange,
CreateAttributeEventListener(GetDocument().GetFrame(), name, value));
- } else if (RuntimeEnabledFeatures::PortalsEnabled() &&
+ } else if (RuntimeEnabledFeatures::PortalsEnabled(&GetDocument()) &&
name == html_names::kOnportalactivateAttr) {
GetDocument().SetWindowAttributeEventListener(
event_type_names::kPortalactivate,
CreateAttributeEventListener(GetDocument().GetFrame(), name, value));
+ } else if (RuntimeEnabledFeatures::TimeZoneChangeEventEnabled() &&
+ name == html_names::kOntimezonechangeAttr) {
+ GetDocument().SetWindowAttributeEventListener(
+ event_type_names::kTimezonechange,
+ CreateAttributeEventListener(GetDocument().GetFrame(), name, value));
} else {
HTMLElement::ParseAttribute(params);
}
@@ -221,9 +226,9 @@ bool HTMLFrameSetElement::LayoutObjectIsNeeded(
LayoutObject* HTMLFrameSetElement::CreateLayoutObject(
const ComputedStyle& style,
LegacyLayout legacy) {
- if (style.HasContent())
- return LayoutObject::CreateObject(this, style, legacy);
- return new LayoutFrameSet(this);
+ if (style.ContentBehavesAsNormal())
+ return new LayoutFrameSet(this);
+ return LayoutObject::CreateObject(this, style, legacy);
}
void HTMLFrameSetElement::AttachLayoutTree(AttachContext& context) {
@@ -247,9 +252,10 @@ void HTMLFrameSetElement::AttachLayoutTree(AttachContext& context) {
}
void HTMLFrameSetElement::DefaultEventHandler(Event& evt) {
- if (evt.IsMouseEvent() && !noresize_ && GetLayoutObject() &&
+ auto* mouse_event = DynamicTo<MouseEvent>(evt);
+ if (mouse_event && !noresize_ && GetLayoutObject() &&
GetLayoutObject()->IsFrameSet()) {
- if (ToLayoutFrameSet(GetLayoutObject())->UserResize(ToMouseEvent(evt))) {
+ if (ToLayoutFrameSet(GetLayoutObject())->UserResize(*mouse_event)) {
evt.SetDefaultHandled();
return;
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_hr_element.cc b/chromium/third_party/blink/renderer/core/html/html_hr_element.cc
index 27bbf886243..b4ef56da63b 100644
--- a/chromium/third_party/blink/renderer/core/html/html_hr_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_hr_element.cc
@@ -48,13 +48,13 @@ void HTMLHRElement::CollectStyleForPresentationAttribute(
const AtomicString& value,
MutableCSSPropertyValueSet* style) {
if (name == html_names::kAlignAttr) {
- if (DeprecatedEqualIgnoringCase(value, "left")) {
+ if (EqualIgnoringASCIICase(value, "left")) {
AddPropertyToPresentationAttributeStyle(
style, CSSPropertyID::kMarginLeft, 0,
CSSPrimitiveValue::UnitType::kPixels);
AddPropertyToPresentationAttributeStyle(
style, CSSPropertyID::kMarginRight, CSSValueID::kAuto);
- } else if (DeprecatedEqualIgnoringCase(value, "right")) {
+ } else if (EqualIgnoringASCIICase(value, "right")) {
AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kMarginLeft,
CSSValueID::kAuto);
AddPropertyToPresentationAttributeStyle(
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 6613c5b9d05..8056ae5eb8b 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
@@ -24,22 +24,26 @@
#include "third_party/blink/renderer/core/html/html_iframe_element.h"
+#include "services/network/public/mojom/trust_tokens.mojom-blink.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
-#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_html.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_html_iframe_element.h"
#include "third_party/blink/renderer/core/css/css_property_names.h"
#include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/dom/element.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/feature_policy/iframe_policy.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/sandbox_flags.h"
#include "third_party/blink/renderer/core/html/html_document.h"
+#include "third_party/blink/renderer/core/html/trust_token_attribute_parsing.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/layout/layout_iframe.h"
#include "third_party/blink/renderer/core/loader/document_loader.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/json/json_parser.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
@@ -62,7 +66,7 @@ HTMLIFrameElement::~HTMLIFrameElement() = default;
const AttrNameToTrustedType& HTMLIFrameElement::GetCheckedAttributeTypes()
const {
DEFINE_STATIC_LOCAL(AttrNameToTrustedType, attribute_map,
- ({{"srcdoc", SpecificTrustedType::kTrustedHTML}}));
+ ({{"srcdoc", SpecificTrustedType::kHTML}}));
return attribute_map;
}
@@ -133,10 +137,10 @@ void HTMLIFrameElement::ParseAttribute(
const QualifiedName& name = params.name;
const AtomicString& value = params.new_value;
if (name == html_names::kNameAttr) {
- if (IsInDocumentTree() && GetDocument().IsHTMLDocument()) {
- HTMLDocument& document = ToHTMLDocument(GetDocument());
- document.RemoveNamedItem(name_);
- document.AddNamedItem(value);
+ auto* document = DynamicTo<HTMLDocument>(GetDocument());
+ if (document && IsInDocumentTree()) {
+ document->RemoveNamedItem(name_);
+ document->AddNamedItem(value);
}
AtomicString old_name = name_;
name_ = value;
@@ -147,19 +151,22 @@ void HTMLIFrameElement::ParseAttribute(
String invalid_tokens;
bool feature_policy_for_sandbox =
RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled();
- WebSandboxFlags current_flags =
+ mojom::blink::WebSandboxFlags current_flags =
value.IsNull()
- ? WebSandboxFlags::kNone
+ ? mojom::blink::WebSandboxFlags::kNone
: ParseSandboxPolicy(sandbox_->TokenSet(), invalid_tokens);
- SetAllowedToDownload((current_flags & WebSandboxFlags::kDownloads) ==
- WebSandboxFlags::kNone);
+ SetAllowedToDownload(
+ (current_flags & mojom::blink::WebSandboxFlags::kDownloads) ==
+ mojom::blink::WebSandboxFlags::kNone);
// With FeaturePolicyForSandbox, sandbox flags are represented as part of
// the container policies. However, not all sandbox flags are yet converted
// and for now the residue will stay around in the stored flags.
// (see https://crbug.com/812381).
- WebSandboxFlags sandbox_to_set = current_flags;
- sandbox_flags_converted_to_feature_policies_ = WebSandboxFlags::kNone;
- if (feature_policy_for_sandbox && current_flags != WebSandboxFlags::kNone) {
+ mojom::blink::WebSandboxFlags sandbox_to_set = current_flags;
+ sandbox_flags_converted_to_feature_policies_ =
+ mojom::blink::WebSandboxFlags::kNone;
+ if (feature_policy_for_sandbox &&
+ current_flags != mojom::blink::WebSandboxFlags::kNone) {
// Residue sandbox which will not be mapped to feature policies.
sandbox_to_set =
GetSandboxFlagsNotImplementedAsFeaturePolicy(current_flags);
@@ -169,7 +176,7 @@ void HTMLIFrameElement::ParseAttribute(
}
SetSandboxFlags(sandbox_to_set);
if (!invalid_tokens.IsNull()) {
- GetDocument().AddConsoleMessage(ConsoleMessage::Create(
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kError,
"Error while parsing the 'sandbox' attribute: " + invalid_tokens));
@@ -179,7 +186,7 @@ void HTMLIFrameElement::ParseAttribute(
UpdateContainerPolicy(&messages);
if (!messages.IsEmpty()) {
for (const String& message : messages) {
- GetDocument().AddConsoleMessage(ConsoleMessage::Create(
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kWarning, message));
}
@@ -220,7 +227,7 @@ void HTMLIFrameElement::ParseAttribute(
if (!ContentSecurityPolicy::IsValidCSPAttr(
value.GetString(), GetDocument().RequiredCSP().GetString())) {
required_csp_ = g_null_atom;
- GetDocument().AddConsoleMessage(ConsoleMessage::Create(
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kError,
"'csp' attribute is not a valid policy: " + value));
@@ -237,7 +244,7 @@ void HTMLIFrameElement::ParseAttribute(
UpdateContainerPolicy(&messages);
if (!messages.IsEmpty()) {
for (const String& message : messages) {
- GetDocument().AddConsoleMessage(ConsoleMessage::Create(
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kWarning, message));
}
@@ -247,10 +254,19 @@ void HTMLIFrameElement::ParseAttribute(
WebFeature::kFeaturePolicyAllowAttribute);
}
}
- } else if (name == html_names::kDisallowdocumentaccessAttr) {
- disallow_document_access_ = !value.IsNull();
+ } else if (name == html_names::kDisallowdocumentaccessAttr &&
+ RuntimeEnabledFeatures::DisallowDocumentAccessEnabled()) {
+ UseCounter::Count(GetDocument(), WebFeature::kDisallowDocumentAccess);
+ SetDisallowDocumentAccesss(!value.IsNull());
// We don't need to call tell the client frame properties
// changed since this attribute only stays inside the renderer.
+ } else if (name == html_names::kPolicyAttr) {
+ if (required_policy_ != value) {
+ required_policy_ = value;
+ UpdateRequiredPolicy();
+ }
+ } else if (name == html_names::kTrusttokenAttr) {
+ trust_token_ = value;
} else {
// Websites picked up a Chromium article that used this non-specified
// attribute which ended up changing shape after the specification process.
@@ -263,12 +279,12 @@ void HTMLIFrameElement::ParseAttribute(
WebFeature::kHTMLIFrameElementGestureMedia)) {
UseCounter::Count(GetDocument(),
WebFeature::kHTMLIFrameElementGestureMedia);
- GetDocument().AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kOther,
- mojom::ConsoleMessageLevel::kWarning,
- "<iframe gesture=\"media\"> is not supported. "
- "Use <iframe allow=\"autoplay\">, "
- "https://goo.gl/ximf56"));
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kOther,
+ mojom::ConsoleMessageLevel::kWarning,
+ "<iframe gesture=\"media\"> is not supported. "
+ "Use <iframe allow=\"autoplay\">, "
+ "https://goo.gl/ximf56"));
}
if (name == html_names::kSrcAttr)
@@ -277,6 +293,15 @@ void HTMLIFrameElement::ParseAttribute(
}
}
+// TODO(crbug.com/993790): Emit error message 'endpoint cannot be specified
+// on iframe attribute.'.
+DocumentPolicy::FeatureState HTMLIFrameElement::ConstructRequiredPolicy()
+ const {
+ return DocumentPolicyParser::Parse(required_policy_)
+ .value_or(DocumentPolicy::ParsedDocumentPolicy{})
+ .feature_state;
+}
+
ParsedFeaturePolicy HTMLIFrameElement::ConstructContainerPolicy(
Vector<String>* messages) const {
scoped_refptr<const SecurityOrigin> src_origin = GetOriginForFeaturePolicy();
@@ -293,10 +318,11 @@ ParsedFeaturePolicy HTMLIFrameElement::ConstructContainerPolicy(
// 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_ &
- WebSandboxFlags::kNavigation) != WebSandboxFlags::kNone) {
+ mojom::blink::WebSandboxFlags::kNavigation) !=
+ mojom::blink::WebSandboxFlags::kNone) {
for (const auto& pair : SandboxFlagsWithFeaturePolicies()) {
if ((sandbox_flags_converted_to_feature_policies_ & pair.first) !=
- WebSandboxFlags::kNone &&
+ mojom::blink::WebSandboxFlags::kNone &&
IsFeatureDeclared(pair.second, container_policy)) {
messages->push_back(String::Format(
"Allow and Sandbox attributes both mention '%s'. Allow will take "
@@ -317,7 +343,7 @@ ParsedFeaturePolicy HTMLIFrameElement::ConstructContainerPolicy(
// enable the feature for all origins.
if (AllowFullscreen()) {
bool policy_changed = AllowFeatureEverywhereIfNotPresent(
- mojom::FeaturePolicyFeature::kFullscreen, container_policy);
+ mojom::blink::FeaturePolicyFeature::kFullscreen, container_policy);
if (!policy_changed && messages) {
messages->push_back(
"Allow attribute will take precedence over 'allowfullscreen'.");
@@ -327,7 +353,7 @@ ParsedFeaturePolicy HTMLIFrameElement::ConstructContainerPolicy(
// set, enable the feature for all origins.
if (AllowPaymentRequest()) {
bool policy_changed = AllowFeatureEverywhereIfNotPresent(
- mojom::FeaturePolicyFeature::kPayment, container_policy);
+ mojom::blink::FeaturePolicyFeature::kPayment, container_policy);
if (!policy_changed && messages) {
messages->push_back(
"Allow attribute will take precedence over 'allowpaymentrequest'.");
@@ -357,13 +383,13 @@ Node::InsertionNotificationRequest HTMLIFrameElement::InsertedInto(
InsertionNotificationRequest result =
HTMLFrameElementBase::InsertedInto(insertion_point);
- if (insertion_point.IsInDocumentTree() && GetDocument().IsHTMLDocument()) {
- ToHTMLDocument(GetDocument()).AddNamedItem(name_);
-
+ auto* html_doc = DynamicTo<HTMLDocument>(GetDocument());
+ if (html_doc && insertion_point.IsInDocumentTree()) {
+ html_doc->AddNamedItem(name_);
if (!ContentSecurityPolicy::IsValidCSPAttr(
required_csp_, GetDocument().RequiredCSP().GetString())) {
if (!required_csp_.IsEmpty()) {
- GetDocument().AddConsoleMessage(ConsoleMessage::Create(
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kError,
"'csp' attribute is not a valid policy: " + required_csp_));
@@ -380,8 +406,9 @@ Node::InsertionNotificationRequest HTMLIFrameElement::InsertedInto(
void HTMLIFrameElement::RemovedFrom(ContainerNode& insertion_point) {
HTMLFrameElementBase::RemovedFrom(insertion_point);
- if (insertion_point.IsInDocumentTree() && GetDocument().IsHTMLDocument())
- ToHTMLDocument(GetDocument()).RemoveNamedItem(name_);
+ auto* html_doc = DynamicTo<HTMLDocument>(GetDocument());
+ if (html_doc && insertion_point.IsInDocumentTree())
+ html_doc->RemoveNamedItem(name_);
}
bool HTMLIFrameElement::IsInteractiveContent() const {
@@ -392,4 +419,55 @@ network::mojom::ReferrerPolicy HTMLIFrameElement::ReferrerPolicyAttribute() {
return referrer_policy_;
}
+network::mojom::blink::TrustTokenParamsPtr
+HTMLIFrameElement::ConstructTrustTokenParams() const {
+ if (!trust_token_)
+ return nullptr;
+
+ JSONParseError parse_error;
+ std::unique_ptr<JSONValue> parsed_attribute =
+ ParseJSON(trust_token_, &parse_error);
+ if (!parsed_attribute) {
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kOther,
+ mojom::blink::ConsoleMessageLevel::kError,
+ "iframe trusttoken attribute was invalid JSON: " + parse_error.message +
+ String::Format(" (line %d, col %d)", parse_error.line,
+ parse_error.column)));
+ return nullptr;
+ }
+
+ network::mojom::blink::TrustTokenParamsPtr parsed_params =
+ internal::TrustTokenParamsFromJson(std::move(parsed_attribute));
+ if (!parsed_params) {
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kOther,
+ mojom::blink::ConsoleMessageLevel::kError,
+ "Couldn't parse iframe trusttoken attribute (was it missing a "
+ "field?)"));
+ return nullptr;
+ }
+
+ // Trust token redemption and signing (but not issuance) require that the
+ // trust-token-redemption feature policy be present.
+ bool operation_requires_feature_policy =
+ parsed_params->type ==
+ network::mojom::blink::TrustTokenOperationType::kRedemption ||
+ parsed_params->type ==
+ network::mojom::blink::TrustTokenOperationType::kSigning;
+
+ if (operation_requires_feature_policy &&
+ (!GetDocument().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."));
+ return nullptr;
+ }
+
+ return parsed_params;
+}
+
} // namespace blink
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 f784f13e4a9..5040896b979 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
@@ -24,6 +24,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_IFRAME_ELEMENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_IFRAME_ELEMENT_H_
+#include "services/network/public/mojom/trust_tokens.mojom-blink-forward.h"
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
#include "third_party/blink/public/common/frame/frame_owner_element_type.h"
#include "third_party/blink/renderer/core/core_export.h"
@@ -55,12 +56,14 @@ class CORE_EXPORT HTMLIFrameElement final
ParsedFeaturePolicy ConstructContainerPolicy(
Vector<String>* /* messages */) const override;
+ DocumentPolicy::FeatureState ConstructRequiredPolicy() const override;
FrameOwnerElementType OwnerType() const final {
return FrameOwnerElementType::kIframe;
}
- WebSandboxFlags sandbox_flags_converted_to_feature_policies() const {
+ mojom::blink::WebSandboxFlags sandbox_flags_converted_to_feature_policies()
+ const {
return sandbox_flags_converted_to_feature_policies_;
}
@@ -84,28 +87,32 @@ class CORE_EXPORT HTMLIFrameElement final
network::mojom::ReferrerPolicy ReferrerPolicyAttribute() override;
+ network::mojom::blink::TrustTokenParamsPtr ConstructTrustTokenParams()
+ const override;
+
// FrameOwner overrides:
bool AllowFullscreen() const override { return allow_fullscreen_; }
bool AllowPaymentRequest() const override { return allow_payment_request_; }
- bool DisallowDocumentAccess() const override {
- return disallow_document_access_;
- }
AtomicString RequiredCsp() const override { return required_csp_; }
AtomicString name_;
AtomicString required_csp_;
AtomicString allow_;
+ AtomicString required_policy_; // policy attribute
+ // String attribute storing a JSON representation of the Trust Token
+ // parameters (in order to align with the fetch interface to the Trust Token
+ // API). If present, this is parsed in ConstructTrustTokenParams.
+ AtomicString trust_token_;
bool allow_fullscreen_;
bool allow_payment_request_;
bool collapsed_by_client_;
- bool disallow_document_access_;
Member<HTMLIFrameElementSandbox> sandbox_;
Member<DOMFeaturePolicy> policy_;
// This represents a subset of sandbox flags set through 'sandbox' attribute
// that will be converted to feature policies as part of the container
// policies.
- WebSandboxFlags sandbox_flags_converted_to_feature_policies_ =
- WebSandboxFlags::kNone;
+ mojom::blink::WebSandboxFlags sandbox_flags_converted_to_feature_policies_ =
+ mojom::blink::WebSandboxFlags::kNone;
network::mojom::ReferrerPolicy referrer_policy_;
};
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 571a8e2ae80..99283b0c160 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
@@ -49,8 +49,14 @@
// https://w3c.github.io/webappsec-feature-policy/#the-policy-object
[RuntimeEnabled=FeaturePolicyJavaScriptInterface] readonly attribute FeaturePolicy featurePolicy;
+ // Document Policy
+ [RuntimeEnabled=DocumentPolicy, CEReactions, Reflect] attribute DOMString policy;
+
[RuntimeEnabled=LazyFrameLoading, CEReactions, Reflect, ReflectOnly=("lazy", "eager", "auto"), ReflectMissing="auto", ReflectInvalid="auto"] attribute DOMString loading;
+ // Trust Tokens request parameters (https://github.com/wicg/trust-token-api)
+ [RuntimeEnabled=TrustTokens, SecureContext, Reflect] attribute DOMString trustToken;
+
// obsolete members
// https://html.spec.whatwg.org/C/#HTMLIFrameElement-partial
[CEReactions, Reflect] attribute DOMString align;
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 b0dfcc4290e..71f5cd53348 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
@@ -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/feature_policy/feature_policy_parser.h"
+#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
@@ -25,23 +26,25 @@ class HTMLIFrameElementTest : public testing::Test {
void SetUp() final {
const KURL document_url("http://example.com");
- DocumentInit init =
- DocumentInit::Create()
- .WithOriginToCommit(SecurityOrigin::Create(document_url))
- .WithURL(document_url);
- document_ = MakeGarbageCollected<Document>(init);
+ page_holder_ = std::make_unique<DummyPageHolder>(IntSize(800, 600));
+ document_ = &page_holder_->GetDocument();
+ document_->SetURL(document_url);
+ document_->GetSecurityContext().SetSecurityOriginForTesting(
+ SecurityOrigin::Create(document_url));
frame_element_ = MakeGarbageCollected<HTMLIFrameElement>(*document_);
}
void TearDown() final {
frame_element_.Clear();
document_.Clear();
+ page_holder_.reset();
}
protected:
const PolicyValue min_value = PolicyValue(false);
const PolicyValue max_value = PolicyValue(true);
+ std::unique_ptr<DummyPageHolder> page_holder_;
Persistent<Document> document_;
Persistent<HTMLIFrameElement> frame_element_;
};
@@ -163,7 +166,7 @@ TEST_F(HTMLIFrameElementTest, AllowAttributeContainerPolicy) {
frame_element_->GetFramePolicy().container_policy;
EXPECT_EQ(1UL, container_policy1.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen,
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen,
container_policy1[0].feature);
EXPECT_GE(min_value, container_policy1[0].fallback_value);
EXPECT_EQ(1UL, container_policy1[0].values.size());
@@ -177,12 +180,13 @@ TEST_F(HTMLIFrameElementTest, AllowAttributeContainerPolicy) {
frame_element_->GetFramePolicy().container_policy;
EXPECT_EQ(2UL, container_policy2.size());
EXPECT_TRUE(container_policy2[0].feature ==
- mojom::FeaturePolicyFeature::kFullscreen ||
+ mojom::blink::FeaturePolicyFeature::kFullscreen ||
container_policy2[1].feature ==
- mojom::FeaturePolicyFeature::kFullscreen);
- EXPECT_TRUE(
- container_policy2[0].feature == mojom::FeaturePolicyFeature::kPayment ||
- container_policy2[1].feature == mojom::FeaturePolicyFeature::kPayment);
+ mojom::blink::FeaturePolicyFeature::kFullscreen);
+ EXPECT_TRUE(container_policy2[0].feature ==
+ mojom::blink::FeaturePolicyFeature::kPayment ||
+ container_policy2[1].feature ==
+ mojom::blink::FeaturePolicyFeature::kPayment);
EXPECT_EQ(1UL, container_policy2[0].values.size());
EXPECT_EQ("http://example.net",
container_policy2[0].values.begin()->first.Serialize());
@@ -220,16 +224,17 @@ TEST_F(HTMLIFrameElementTest, CrossOriginSandboxAttributeContainerPolicy) {
frame_element_->GetFramePolicy().container_policy;
EXPECT_EQ(expected_number_of_sandbox_features + 1, container_policy.size());
- const auto& container_policy_item = std::find_if(
- container_policy.begin(), container_policy.end(),
- [](const auto& declaration) {
- return declaration.feature == mojom::FeaturePolicyFeature::kFullscreen;
- });
+ const auto& container_policy_item =
+ std::find_if(container_policy.begin(), container_policy.end(),
+ [](const auto& declaration) {
+ return declaration.feature ==
+ mojom::blink::FeaturePolicyFeature::kFullscreen;
+ });
EXPECT_NE(container_policy_item, container_policy.end())
<< "Fullscreen feature not found in container policy";
const ParsedFeaturePolicyDeclaration item = *container_policy_item;
- EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, item.feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen, item.feature);
EXPECT_GE(min_value, item.fallback_value);
EXPECT_LE(max_value, item.opaque_value);
EXPECT_EQ(0UL, item.values.size());
@@ -250,16 +255,17 @@ TEST_F(HTMLIFrameElementTest, SameOriginSandboxAttributeContainerPolicy) {
frame_element_->GetFramePolicy().container_policy;
EXPECT_EQ(expected_number_of_sandbox_features + 1, container_policy.size());
- const auto& container_policy_item = std::find_if(
- container_policy.begin(), container_policy.end(),
- [](const auto& declaration) {
- return declaration.feature == mojom::FeaturePolicyFeature::kFullscreen;
- });
+ const auto& container_policy_item =
+ std::find_if(container_policy.begin(), container_policy.end(),
+ [](const auto& declaration) {
+ return declaration.feature ==
+ mojom::blink::FeaturePolicyFeature::kFullscreen;
+ });
EXPECT_NE(container_policy_item, container_policy.end())
<< "Fullscreen feature not found in container policy";
const ParsedFeaturePolicyDeclaration item = *container_policy_item;
- EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, item.feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen, item.feature);
EXPECT_GE(min_value, item.fallback_value);
EXPECT_GE(min_value, item.opaque_value);
EXPECT_EQ(1UL, item.values.size());
@@ -282,12 +288,14 @@ TEST_F(HTMLIFrameElementTest, ConstructContainerPolicy) {
ParsedFeaturePolicy container_policy =
frame_element_->ConstructContainerPolicy(nullptr);
EXPECT_EQ(2UL, container_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kPayment, container_policy[0].feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kPayment,
+ container_policy[0].feature);
EXPECT_GE(min_value, container_policy[0].fallback_value);
EXPECT_EQ(1UL, container_policy[0].values.size());
EXPECT_TRUE(container_policy[0].values.begin()->first.IsSameOriginWith(
GetOriginForFeaturePolicy(frame_element_)->ToUrlOrigin()));
- EXPECT_EQ(mojom::FeaturePolicyFeature::kUsb, container_policy[1].feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kUsb,
+ container_policy[1].feature);
EXPECT_EQ(1UL, container_policy[1].values.size());
EXPECT_TRUE(container_policy[1].values.begin()->first.IsSameOriginWith(
GetOriginForFeaturePolicy(frame_element_)->ToUrlOrigin()));
@@ -301,7 +309,7 @@ TEST_F(HTMLIFrameElementTest, ConstructContainerPolicyWithAllowFullscreen) {
ParsedFeaturePolicy container_policy =
frame_element_->ConstructContainerPolicy(nullptr);
EXPECT_EQ(1UL, container_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen,
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen,
container_policy[0].feature);
EXPECT_LE(max_value, container_policy[0].fallback_value);
}
@@ -316,12 +324,14 @@ TEST_F(HTMLIFrameElementTest, ConstructContainerPolicyWithAllowPaymentRequest) {
ParsedFeaturePolicy container_policy =
frame_element_->ConstructContainerPolicy(nullptr);
EXPECT_EQ(2UL, container_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kUsb, container_policy[0].feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kUsb,
+ container_policy[0].feature);
EXPECT_GE(min_value, container_policy[0].fallback_value);
EXPECT_EQ(1UL, container_policy[0].values.size());
EXPECT_TRUE(container_policy[0].values.begin()->first.IsSameOriginWith(
GetOriginForFeaturePolicy(frame_element_)->ToUrlOrigin()));
- EXPECT_EQ(mojom::FeaturePolicyFeature::kPayment, container_policy[1].feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kPayment,
+ container_policy[1].feature);
}
// Test the ConstructContainerPolicy method when both "allowfullscreen" and
@@ -339,16 +349,18 @@ TEST_F(HTMLIFrameElementTest, ConstructContainerPolicyWithAllowAttributes) {
ParsedFeaturePolicy container_policy =
frame_element_->ConstructContainerPolicy(nullptr);
EXPECT_EQ(3UL, container_policy.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kPayment, container_policy[0].feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kPayment,
+ container_policy[0].feature);
EXPECT_GE(min_value, container_policy[0].fallback_value);
EXPECT_EQ(1UL, container_policy[0].values.size());
EXPECT_TRUE(container_policy[0].values.begin()->first.IsSameOriginWith(
GetOriginForFeaturePolicy(frame_element_)->ToUrlOrigin()));
- EXPECT_EQ(mojom::FeaturePolicyFeature::kUsb, container_policy[1].feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kUsb,
+ container_policy[1].feature);
EXPECT_EQ(1UL, container_policy[1].values.size());
EXPECT_TRUE(container_policy[1].values.begin()->first.IsSameOriginWith(
GetOriginForFeaturePolicy(frame_element_)->ToUrlOrigin()));
- EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen,
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen,
container_policy[2].feature);
}
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 0e8937f4e34..e40958fc877 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
@@ -25,6 +25,7 @@
#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_event_listener.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h"
#include "third_party/blink/renderer/core/css/css_property_names.h"
#include "third_party/blink/renderer/core/css/media_query_matcher.h"
#include "third_party/blink/renderer/core/css/media_values_dynamic.h"
@@ -38,18 +39,17 @@
#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/canvas/html_canvas_element.h"
+#include "third_party/blink/renderer/core/html/cross_origin_attribute.h"
#include "third_party/blink/renderer/core/html/forms/form_associated.h"
#include "third_party/blink/renderer/core/html/forms/html_form_element.h"
#include "third_party/blink/renderer/core/html/html_dimension.h"
#include "third_party/blink/renderer/core/html/html_image_fallback_helper.h"
#include "third_party/blink/renderer/core/html/html_picture_element.h"
#include "third_party/blink/renderer/core/html/html_source_element.h"
-#include "third_party/blink/renderer/core/html/media/media_element_parser_helpers.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/core/html/parser/html_srcset_parser.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
-#include "third_party/blink/renderer/core/imagebitmap/image_bitmap_options.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h"
#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
@@ -102,15 +102,13 @@ HTMLImageElement::HTMLImageElement(Document& document, bool created_by_parser)
form_was_set_by_parser_(false),
element_created_by_parser_(created_by_parser),
is_fallback_image_(false),
+ is_default_overridden_intrinsic_size_(
+ !document.IsImageDocument() &&
+ !document.IsFeatureEnabled(
+ mojom::blink::DocumentPolicyFeature::kUnsizedMedia)),
is_legacy_format_or_unoptimized_image_(false),
referrer_policy_(network::mojom::ReferrerPolicy::kDefault) {
SetHasCustomStyleCallbacks();
- if (media_element_parser_helpers::IsMediaElement(this) &&
- !document.IsFeatureEnabled(mojom::FeaturePolicyFeature::kUnsizedMedia)) {
- is_default_overridden_intrinsic_size_ = true;
- overridden_intrinsic_size_ =
- IntSize(LayoutReplaced::kDefaultWidth, LayoutReplaced::kDefaultHeight);
- }
}
HTMLImageElement::~HTMLImageElement() = default;
@@ -291,6 +289,24 @@ void HTMLImageElement::ParseAttribute(
// |importance| attribute to the loading pipeline takes place in
// ImageLoader.
UseCounter::Count(GetDocument(), WebFeature::kPriorityHints);
+ } else if (name == html_names::kCrossoriginAttr) {
+ // As per an image's relevant mutations [1], we must queue a new loading
+ // microtask when the `crossorigin` attribute state has changed. Note that
+ // the attribute value can change without the attribute state changing [2].
+ //
+ // [1]:
+ // https://html.spec.whatwg.org/multipage/images.html#relevant-mutations
+ // [2]: https://github.com/whatwg/html/issues/4533#issuecomment-483417499
+ CrossOriginAttributeValue new_crossorigin_state =
+ GetCrossOriginAttributeValue(params.new_value);
+ CrossOriginAttributeValue old_crossorigin_state =
+ GetCrossOriginAttributeValue(params.old_value);
+
+ if (new_crossorigin_state != old_crossorigin_state) {
+ // Update the current state so we can detect future state changes.
+ GetImageLoader().UpdateFromElement(
+ ImageLoader::kUpdateIgnorePreviousError, referrer_policy_);
+ }
} else {
HTMLElement::ParseAttribute(params);
}
@@ -445,8 +461,9 @@ void HTMLImageElement::RemovedFrom(ContainerNode& insertion_point) {
}
unsigned HTMLImageElement::width() {
- if (InActiveDocument())
- GetDocument().UpdateStyleAndLayout();
+ if (InActiveDocument()) {
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
+ }
if (!GetLayoutObject()) {
// check the attribute first for an explicit pixel value
@@ -468,8 +485,9 @@ unsigned HTMLImageElement::width() {
}
unsigned HTMLImageElement::height() {
- if (InActiveDocument())
- GetDocument().UpdateStyleAndLayout();
+ if (InActiveDocument()) {
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
+ }
if (!GetLayoutObject()) {
// check the attribute first for an explicit pixel value
@@ -491,9 +509,10 @@ unsigned HTMLImageElement::height() {
}
LayoutSize HTMLImageElement::DensityCorrectedIntrinsicDimensions() const {
- IntSize overridden_intrinsic_size = GetOverriddenIntrinsicSize();
- if (!overridden_intrinsic_size.IsEmpty())
- return LayoutSize(overridden_intrinsic_size);
+ if (IsDefaultIntrinsicSize()) {
+ return LayoutSize(LayoutReplaced::kDefaultWidth,
+ LayoutReplaced::kDefaultHeight);
+ }
ImageResourceContent* image_resource = GetImageLoader().GetContent();
if (!image_resource || !image_resource->HasImage())
return LayoutSize();
@@ -573,24 +592,20 @@ const QualifiedName& HTMLImageElement::SubResourceAttributeName() const {
bool HTMLImageElement::draggable() const {
// Image elements are draggable by default.
- return !DeprecatedEqualIgnoringCase(
- FastGetAttribute(html_names::kDraggableAttr), "false");
+ return !EqualIgnoringASCIICase(FastGetAttribute(html_names::kDraggableAttr),
+ "false");
}
void HTMLImageElement::setHeight(unsigned value) {
SetUnsignedIntegralAttribute(html_names::kHeightAttr, value);
}
-IntSize HTMLImageElement::GetOverriddenIntrinsicSize() const {
- return overridden_intrinsic_size_;
-}
-
void HTMLImageElement::setWidth(unsigned value) {
SetUnsignedIntegralAttribute(html_names::kWidthAttr, value);
}
int HTMLImageElement::x() const {
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
LayoutObject* r = GetLayoutObject();
if (!r)
return 0;
@@ -602,7 +617,7 @@ int HTMLImageElement::x() const {
}
int HTMLImageElement::y() const {
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
LayoutObject* r = GetLayoutObject();
if (!r)
return 0;
@@ -656,17 +671,17 @@ bool HTMLImageElement::IsInteractiveContent() const {
}
FloatSize HTMLImageElement::DefaultDestinationSize(
- const FloatSize& default_object_size) const {
+ const FloatSize& default_object_size,
+ const RespectImageOrientationEnum respect_orientation) const {
ImageResourceContent* image_content = CachedImage();
- if (!image_content)
+ if (!image_content || !image_content->HasImage())
return FloatSize();
Image* image = image_content->GetImage();
- if (image->IsSVGImage())
- return ToSVGImage(image)->ConcreteObjectSize(default_object_size);
+ if (auto* svg_image = DynamicTo<SVGImage>(image))
+ return svg_image->ConcreteObjectSize(default_object_size);
- LayoutSize size(image_content->IntrinsicSize(
- LayoutObject::ShouldRespectImageOrientation(GetLayoutObject())));
+ LayoutSize size(image->Size(respect_orientation));
if (GetLayoutObject() && GetLayoutObject()->IsLayoutImage() &&
image->HasIntrinsicSize())
size.Scale(ToLayoutImage(GetLayoutObject())->ImageDevicePixelRatio());
@@ -681,7 +696,8 @@ static bool SourceSizeValue(const Element* element,
if (exists)
UseCounter::Count(current_document, WebFeature::kSizes);
source_size =
- SizesAttributeParser(MediaValuesDynamic::Create(current_document), sizes)
+ SizesAttributeParser(MediaValuesDynamic::Create(current_document), sizes,
+ current_document.GetExecutionContext())
.length();
return exists;
}
@@ -737,6 +753,17 @@ void HTMLImageElement::SelectSourceURL(
EnsureCollapsedOrFallbackContent();
}
+void HTMLImageElement::StartLoadingImageDocument(
+ ImageResourceContent* image_content) {
+ // This element is being used to load an image in an ImageDocument. The
+ // provided ImageResource is owned/managed by the ImageDocumentParser. Set it
+ // on our ImageLoader and then update the 'src' attribute to reflect the URL
+ // of the image. This latter step will also initiate the load from the
+ // ImageLoader's PoV.
+ GetImageLoader().SetImageDocumentContent(image_content);
+ setAttribute(html_names::kSrcAttr, AtomicString(image_content->Url()));
+}
+
void HTMLImageElement::DidAddUserAgentShadowRoot(ShadowRoot&) {
HTMLImageFallbackHelper::CreateAltTextShadowTree(*this);
}
@@ -798,9 +825,11 @@ scoped_refptr<ComputedStyle> HTMLImageElement::CustomStyleForLayoutObject() {
case LayoutDisposition::kPrimaryContent: // Fall through.
case LayoutDisposition::kCollapsed:
return OriginalStyleForLayoutObject();
- case LayoutDisposition::kFallbackContent:
- return HTMLImageFallbackHelper::CustomStyleForAltText(
- *this, ComputedStyle::Clone(*OriginalStyleForLayoutObject()));
+ case LayoutDisposition::kFallbackContent: {
+ scoped_refptr<ComputedStyle> style = OriginalStyleForLayoutObject();
+ HTMLImageFallbackHelper::CustomStyleForAltText(*this, *style);
+ return style;
+ }
default:
NOTREACHED();
return nullptr;
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 83876cf0f5c..92800d28051 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
@@ -36,6 +36,7 @@
#include "third_party/blink/renderer/core/html/lazy_load_image_observer.h"
#include "third_party/blink/renderer/platform/geometry/int_size.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
+#include "third_party/blink/renderer/platform/graphics/image_orientation.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
@@ -100,9 +101,6 @@ class CORE_EXPORT HTMLImageElement final
ImageResourceContent* CachedImage() const {
return GetImageLoader().GetContent();
}
- ImageResource* CachedImageResourceForImageDocument() const {
- return GetImageLoader().ImageResourceForImageDocument();
- }
void LoadDeferredImage() {
GetImageLoader().LoadDeferredImage(referrer_policy_);
}
@@ -110,12 +108,11 @@ class CORE_EXPORT HTMLImageElement final
GetImageLoader().SetImageForTest(content);
}
- void SetLoadingImageDocument() { GetImageLoader().SetLoadingImageDocument(); }
+ void StartLoadingImageDocument(ImageResourceContent* image_content);
void setHeight(unsigned);
void setWidth(unsigned);
- IntSize GetOverriddenIntrinsicSize() const;
bool IsDefaultIntrinsicSize() const {
return is_default_overridden_intrinsic_size_;
}
@@ -143,7 +140,9 @@ class CORE_EXPORT HTMLImageElement final
bool IsCollapsed() const;
// CanvasImageSource interface implementation.
- FloatSize DefaultDestinationSize(const FloatSize&) const override;
+ FloatSize DefaultDestinationSize(
+ const FloatSize&,
+ const RespectImageOrientationEnum) const override;
// public so that HTMLPictureElement can call this as well.
void SelectSourceURL(ImageLoader::UpdateFromElementBehavior);
@@ -178,6 +177,10 @@ class CORE_EXPORT HTMLImageElement final
return is_legacy_format_or_unoptimized_image_;
}
+ // Keeps track of whether the image comes from an ad.
+ void SetIsAdRelated() { is_ad_related_ = true; }
+ bool IsAdRelated() const override { return is_ad_related_; }
+
protected:
// Controls how an image element appears in the layout. See:
// https://html.spec.whatwg.org/C/#image-request
@@ -245,21 +248,21 @@ class CORE_EXPORT HTMLImageElement final
float image_device_pixel_ratio_;
Member<HTMLSourceElement> source_;
LayoutDisposition layout_disposition_;
- unsigned form_was_set_by_parser_ : 1;
- unsigned element_created_by_parser_ : 1;
- unsigned is_fallback_image_ : 1;
- bool is_default_overridden_intrinsic_size_;
+ bool form_was_set_by_parser_ : 1;
+ bool element_created_by_parser_ : 1;
+ bool is_fallback_image_ : 1;
+ bool is_default_overridden_intrinsic_size_ : 1;
// This flag indicates if the image violates one or more optimized image
// policies. When any policy is violated, the image should be rendered as a
// placeholder image.
- bool is_legacy_format_or_unoptimized_image_;
+ bool is_legacy_format_or_unoptimized_image_ : 1;
network::mojom::ReferrerPolicy referrer_policy_;
- IntSize overridden_intrinsic_size_;
-
std::unique_ptr<LazyLoadImageObserver::VisibleLoadTimeMetrics>
visible_load_time_metrics_;
+
+ bool is_ad_related_ = false;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/html_image_element.idl b/chromium/third_party/blink/renderer/core/html/html_image_element.idl
index 794e413f6d5..bcd431f0d90 100644
--- a/chromium/third_party/blink/renderer/core/html/html_image_element.idl
+++ b/chromium/third_party/blink/renderer/core/html/html_image_element.idl
@@ -21,11 +21,12 @@
// https://html.spec.whatwg.org/C/#the-img-element
[
- Exposed=Window,
ActiveScriptWrappable,
ConstructorCallWith=Document,
+ Exposed=Window,
HTMLConstructor,
- NamedConstructor=Image(optional unsigned long width, optional unsigned long height)
+ NamedConstructor=Image(optional unsigned long width, optional unsigned long height),
+ NamedConstructor_CallWith=Document
] interface HTMLImageElement : HTMLElement {
[CEReactions, Reflect] attribute DOMString alt;
[CEReactions, Reflect, URL] attribute USVString src;
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 ca103c9d2cf..9d89a0001b7 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
@@ -104,8 +104,8 @@ class ImageFallbackContentBuilder {
}
private:
- Member<Element> place_holder_;
- Member<Element> broken_image_;
+ Element* place_holder_;
+ Element* broken_image_;
};
} // namespace
@@ -138,39 +138,38 @@ void HTMLImageFallbackHelper::CreateAltTextShadowTree(Element& element) {
element.EnsureUserAgentShadowRoot().AppendChild(container);
}
-scoped_refptr<ComputedStyle> HTMLImageFallbackHelper::CustomStyleForAltText(
- Element& element,
- scoped_refptr<ComputedStyle> new_style) {
+void HTMLImageFallbackHelper::CustomStyleForAltText(Element& element,
+ ComputedStyle& new_style) {
// If we have an author shadow root or have not created the UA shadow root
// yet, bail early. We can't use ensureUserAgentShadowRoot() here because that
// would alter the DOM tree during style recalc.
if (element.AuthorShadowRoot() || !element.UserAgentShadowRoot())
- return new_style;
+ return;
ImageFallbackContentBuilder fallback(*element.UserAgentShadowRoot());
// Input elements have a UA shadow root of their own. We may not have replaced
// it with fallback content yet.
if (!fallback.HasContentElements())
- return new_style;
+ return;
if (element.GetDocument().InQuirksMode()) {
// Mimic the behaviour of the image host by setting symmetric dimensions if
// only one dimension is specified.
- if (new_style->Width().IsSpecifiedOrIntrinsic() &&
- new_style->Height().IsAuto())
- new_style->SetHeight(new_style->Width());
- else if (new_style->Height().IsSpecifiedOrIntrinsic() &&
- new_style->Width().IsAuto())
- new_style->SetWidth(new_style->Height());
- if (new_style->Width().IsSpecifiedOrIntrinsic() &&
- new_style->Height().IsSpecifiedOrIntrinsic()) {
+ if (new_style.Width().IsSpecifiedOrIntrinsic() &&
+ new_style.Height().IsAuto())
+ new_style.SetHeight(new_style.Width());
+ else if (new_style.Height().IsSpecifiedOrIntrinsic() &&
+ new_style.Width().IsAuto())
+ new_style.SetWidth(new_style.Height());
+ if (new_style.Width().IsSpecifiedOrIntrinsic() &&
+ new_style.Height().IsSpecifiedOrIntrinsic()) {
fallback.AlignToBaseline();
}
}
bool image_has_intrinsic_dimensions =
- new_style->Width().IsSpecifiedOrIntrinsic() &&
- new_style->Height().IsSpecifiedOrIntrinsic();
+ new_style.Width().IsSpecifiedOrIntrinsic() &&
+ new_style.Height().IsSpecifiedOrIntrinsic();
bool image_has_no_alt_attribute = To<HTMLElement>(element).AltText().IsNull();
bool treat_as_replaced =
image_has_intrinsic_dimensions &&
@@ -184,22 +183,22 @@ scoped_refptr<ComputedStyle> HTMLImageFallbackHelper::CustomStyleForAltText(
// attribute, or the Document is in quirks mode The user agent is expected
// to treat the element as a replaced element whose content is the text that
// the element represents, if any."
- fallback.ShowAsReplaced(new_style->Width(), new_style->Height(),
- new_style->EffectiveZoom());
+ fallback.ShowAsReplaced(new_style.Width(), new_style.Height(),
+ new_style.EffectiveZoom());
// 16px for the image and 2px for its top/left border/padding offset.
int pixels_for_alt_image = 18;
- if (ImageSmallerThanAltImage(pixels_for_alt_image, new_style->Width(),
- new_style->Height())) {
+ if (ImageSmallerThanAltImage(pixels_for_alt_image, new_style.Width(),
+ new_style.Height())) {
fallback.HideBrokenImageIcon();
} else {
fallback.ShowBorder();
- fallback.ShowBrokenImageIcon(new_style->IsLeftToRightDirection());
+ fallback.ShowBrokenImageIcon(new_style.IsLeftToRightDirection());
}
} else {
- if (new_style->Display() == EDisplay::kInline) {
- new_style->SetWidth(Length());
- new_style->SetHeight(Length());
+ if (new_style.Display() == EDisplay::kInline) {
+ new_style.SetWidth(Length());
+ new_style.SetHeight(Length());
}
if (ElementRepresentsNothing(element)) {
// "If the element is an img element that represents nothing and the user
@@ -215,11 +214,9 @@ scoped_refptr<ComputedStyle> HTMLImageFallbackHelper::CustomStyleForAltText(
// the text, optionally with an icon indicating that an image is missing,
// so that the user can request the image be displayed or investigate why
// it is not rendering."
- fallback.ShowBrokenImageIcon(new_style->IsLeftToRightDirection());
+ fallback.ShowBrokenImageIcon(new_style.IsLeftToRightDirection());
}
}
-
- return new_style;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/html_image_fallback_helper.h b/chromium/third_party/blink/renderer/core/html/html_image_fallback_helper.h
index 8d7df65657f..7facc7fe01f 100644
--- a/chromium/third_party/blink/renderer/core/html/html_image_fallback_helper.h
+++ b/chromium/third_party/blink/renderer/core/html/html_image_fallback_helper.h
@@ -5,7 +5,6 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_IMAGE_FALLBACK_HELPER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_IMAGE_FALLBACK_HELPER_H_
-#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
namespace blink {
@@ -18,9 +17,7 @@ class HTMLImageFallbackHelper {
public:
static void CreateAltTextShadowTree(Element&);
- static scoped_refptr<ComputedStyle> CustomStyleForAltText(
- Element&,
- scoped_refptr<ComputedStyle> new_style);
+ static void CustomStyleForAltText(Element&, ComputedStyle& new_style);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/html_image_loader.cc b/chromium/third_party/blink/renderer/core/html/html_image_loader.cc
index 4383b9cd8bd..13f1560a022 100644
--- a/chromium/third_party/blink/renderer/core/html/html_image_loader.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_image_loader.cc
@@ -72,10 +72,13 @@ void HTMLImageLoader::ImageNotifyFinished(ImageResourceContent*) {
bool load_error = cached_image->ErrorOccurred();
if (auto* image = DynamicTo<HTMLImageElement>(*element)) {
- if (load_error)
+ if (load_error) {
image->EnsureCollapsedOrFallbackContent();
- else
+ } else {
+ if (cached_image->IsAdResource())
+ image->SetIsAdRelated();
image->EnsurePrimaryContent();
+ }
}
if (auto* input = DynamicTo<HTMLInputElement>(*element)) {
diff --git a/chromium/third_party/blink/renderer/core/html/html_li_element.cc b/chromium/third_party/blink/renderer/core/html/html_li_element.cc
index b70b0747cd0..b69d9524afb 100644
--- a/chromium/third_party/blink/renderer/core/html/html_li_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_li_element.cc
@@ -52,13 +52,13 @@ CSSValueID ListTypeToCSSValueID(const AtomicString& value) {
return CSSValueID::kUpperRoman;
if (value == "1")
return CSSValueID::kDecimal;
- if (DeprecatedEqualIgnoringCase(value, "disc"))
+ if (EqualIgnoringASCIICase(value, "disc"))
return CSSValueID::kDisc;
- if (DeprecatedEqualIgnoringCase(value, "circle"))
+ if (EqualIgnoringASCIICase(value, "circle"))
return CSSValueID::kCircle;
- if (DeprecatedEqualIgnoringCase(value, "square"))
+ if (EqualIgnoringASCIICase(value, "square"))
return CSSValueID::kSquare;
- if (DeprecatedEqualIgnoringCase(value, "none"))
+ if (EqualIgnoringASCIICase(value, "none"))
return CSSValueID::kNone;
return CSSValueID::kInvalid;
}
@@ -92,24 +92,6 @@ void HTMLLIElement::AttachLayoutTree(AttachContext& context) {
if (ListItemOrdinal* ordinal = ListItemOrdinal::Get(*this)) {
DCHECK(!GetDocument().ChildNeedsDistributionRecalc());
-
- // Find the enclosing list node.
- Element* list_node = nullptr;
- Element* current = this;
- while (!list_node) {
- current = LayoutTreeBuilderTraversal::ParentElement(*current);
- if (!current)
- break;
- if (IsA<HTMLUListElement>(*current) || IsA<HTMLOListElement>(*current))
- list_node = current;
- }
-
- // If we are not in a list, tell the layoutObject so it can position us
- // inside. We don't want to change our style to say "inside" since that
- // would affect nested nodes.
- if (!list_node)
- ordinal->SetNotInList(true, *this);
-
ParseValue(FastGetAttribute(html_names::kValueAttr), ordinal);
}
}
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 1be17605da1..f5efe07788b 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
@@ -56,7 +56,8 @@ namespace blink {
HTMLLinkElement::HTMLLinkElement(Document& document,
const CreateElementFlags flags)
: HTMLElement(html_names::kLinkTag, document),
- link_loader_(LinkLoader::Create(this)),
+ link_loader_(
+ MakeGarbageCollected<LinkLoader>(this, GetLoadingTaskRunner())),
referrer_policy_(network::mojom::ReferrerPolicy::kDefault),
sizes_(MakeGarbageCollected<DOMTokenList>(*this, html_names::kSizesAttr)),
rel_list_(MakeGarbageCollected<RelList>(this)),
@@ -79,7 +80,7 @@ void HTMLLinkElement::ParseAttribute(
// be silent.
if (LocalDOMWindow* window = GetDocument().ExecutingWindow()) {
if (LocalFrame* frame = window->GetFrame()) {
- frame->Console().AddMessage(ConsoleMessage::Create(
+ frame->Console().AddMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kRendering,
mojom::ConsoleMessageLevel::kWarning,
"HTML Imports is deprecated and has now been removed as of "
@@ -91,6 +92,16 @@ void HTMLLinkElement::ParseAttribute(
}
}
}
+ if (rel_attribute_.IsMonetization() && !GetDocument().ParentDocument()) {
+ // TODO(1031476): The Web Monetization specification is an unofficial
+ // draft, available at https://webmonetization.org/specification.html
+ // Currently it relies on a <meta> tag but there is an open issue about
+ // whether the <link rel="monetization"> should be used instead:
+ // https://github.com/interledger/webmonetization.org/issues/19
+ // For now, only use counters are implemented in Blink.
+ UseCounter::Count(&GetDocument(),
+ WebFeature::kHTMLLinkElementMonetization);
+ }
rel_list_->DidUpdateAttributeValue(params.old_value, value);
Process();
} else if (name == html_names::kHrefAttr) {
@@ -112,7 +123,7 @@ void HTMLLinkElement::ParseAttribute(
}
} else if (name == html_names::kSizesAttr) {
sizes_->DidUpdateAttributeValue(params.old_value, value);
- WebVector<WebSize> web_icon_sizes =
+ WebVector<gfx::Size> web_icon_sizes =
WebIconSizesParser::ParseIconSizes(value);
icon_sizes_.resize(SafeCast<wtf_size_t>(web_icon_sizes.size()));
for (wtf_size_t i = 0; i < icon_sizes_.size(); ++i)
@@ -251,9 +262,9 @@ Node::InsertionNotificationRequest HTMLLinkElement::InsertedInto(
if (!ShouldLoadLink() && IsInShadowTree()) {
String message = "HTML element <link> is ignored in shadow tree.";
- GetDocument().AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning, message));
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning, message));
return kInsertionDone;
}
@@ -387,8 +398,8 @@ bool HTMLLinkElement::HasLegalLinkAttribute(const QualifiedName& name) const {
const QualifiedName& HTMLLinkElement::SubResourceAttributeName() const {
// If the link element is not css, ignore it.
- if (DeprecatedEqualIgnoringCase(FastGetAttribute(html_names::kTypeAttr),
- "text/css")) {
+ if (EqualIgnoringASCIICase(FastGetAttribute(html_names::kTypeAttr),
+ "text/css")) {
// FIXME: Add support for extracting links of sub-resources which
// are inside style-sheet such as @import, @font-face, url(), etc.
return html_names::kHrefAttr;
@@ -415,11 +426,11 @@ bool HTMLLinkElement::Async() const {
return FastHasAttribute(html_names::kAsyncAttr);
}
-IconType HTMLLinkElement::GetIconType() const {
+mojom::blink::FaviconIconType HTMLLinkElement::GetIconType() const {
return rel_attribute_.GetIconType();
}
-const Vector<IntSize>& HTMLLinkElement::IconSizes() const {
+const Vector<gfx::Size>& HTMLLinkElement::IconSizes() const {
return icon_sizes_;
}
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 fc24de71cfd..9ba0c4ea32c 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
@@ -73,10 +73,10 @@ class CORE_EXPORT HTMLLinkElement final : public HTMLElement,
const AtomicString& GetType() const;
- IconType GetIconType() const;
+ mojom::blink::FaviconIconType GetIconType() const;
// the icon sizes as parsed from the HTML attribute
- const Vector<IntSize>& IconSizes() const;
+ const Vector<gfx::Size>& IconSizes() const;
bool Async() const;
@@ -164,7 +164,7 @@ class CORE_EXPORT HTMLLinkElement final : public HTMLElement,
String importance_;
network::mojom::ReferrerPolicy referrer_policy_;
Member<DOMTokenList> sizes_;
- Vector<IntSize> icon_sizes_;
+ Vector<gfx::Size> icon_sizes_;
Member<RelList> rel_list_;
LinkRelAttribute rel_attribute_;
String scope_;
diff --git a/chromium/third_party/blink/renderer/core/html/html_link_element_test.cc b/chromium/third_party/blink/renderer/core/html/html_link_element_test.cc
index da1baf5ae58..057f14136ab 100644
--- a/chromium/third_party/blink/renderer/core/html/html_link_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_link_element_test.cc
@@ -10,21 +10,79 @@
#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/testing/page_test_base.h"
+#include "third_party/blink/renderer/core/testing/sim/sim_compositor.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 {
class HTMLLinkElementTest : public PageTestBase {};
+class HTMLLinkElementSimTest : public SimTest {};
// This tests that we should ignore empty string value
// in href attribute value of the link element.
TEST_F(HTMLLinkElementTest, EmptyHrefAttribute) {
- GetDocument().documentElement()->SetInnerHTMLFromString(
+ GetDocument().documentElement()->setInnerHTML(
"<head>"
"<link rel=\"icon\" type=\"image/ico\" href=\"\" />"
"</head>");
- HTMLLinkElement* link_element =
- ToElement<HTMLLinkElement>(GetDocument().head()->firstChild());
+ auto* link_element = To<HTMLLinkElement>(GetDocument().head()->firstChild());
EXPECT_EQ(NullURL(), link_element->Href());
}
+// This tests whether Web Monetization counter is properly triggered.
+TEST_F(HTMLLinkElementTest, WebMonetizationCounter) {
+ // A <link rel="icon"> is not counted.
+ GetDocument().head()->setInnerHTML(R"HTML(
+ <link rel="icon" type="image/ico" href="">
+ )HTML");
+ EXPECT_FALSE(
+ GetDocument().IsUseCounted(WebFeature::kHTMLLinkElementMonetization));
+
+ // A <link rel="monetization"> is counted.
+ GetDocument().head()->setInnerHTML(R"HTML(
+ <link rel="monetization">
+ )HTML");
+ EXPECT_TRUE(
+ GetDocument().IsUseCounted(WebFeature::kHTMLLinkElementMonetization));
+
+ // However, it does not affect the counter for <meta name="monetization">.
+ EXPECT_FALSE(
+ GetDocument().IsUseCounted(WebFeature::kHTMLMetaElementMonetization));
+}
+
+TEST_F(HTMLLinkElementSimTest, WebMonetizationNotCountedInSubFrame) {
+ SimRequest main_resource("https://example.com/", "text/html");
+ SimRequest child_frame_resource("https://example.com/subframe.html",
+ "text/html");
+
+ LoadURL("https://example.com/");
+
+ main_resource.Complete(String::Format(
+ R"HTML(
+ <body onload='console.log("main body onload");'>
+ <iframe src='https://example.com/subframe.html'
+ onload='console.log("child frame element onload");'></iframe>
+ </body>)HTML"));
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+
+ child_frame_resource.Complete(String::Format(R"HTML(
+ <link rel="monetization">
+ )HTML"));
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+
+ // Ensure that main frame and subframe are loaded before checking the counter.
+ EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
+ EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));
+
+ // <link rel="monetization"> is not counted in subframes.
+ EXPECT_FALSE(
+ GetDocument().IsUseCounted(WebFeature::kHTMLLinkElementMonetization));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/html_map_element.cc b/chromium/third_party/blink/renderer/core/html/html_map_element.cc
index 7874efcdd2b..6f3d12006bc 100644
--- a/chromium/third_party/blink/renderer/core/html/html_map_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_map_element.cc
@@ -27,6 +27,7 @@
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/html/html_area_element.h"
#include "third_party/blink/renderer/core/html/html_collection.h"
+#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html/html_image_element.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
@@ -83,7 +84,7 @@ void HTMLMapElement::ParseAttribute(const AttributeModificationParams& params) {
if (params.name == html_names::kIdAttr) {
// Call base class so that hasID bit gets set.
HTMLElement::ParseAttribute(params);
- if (GetDocument().IsHTMLDocument())
+ if (IsA<HTMLDocument>(GetDocument()))
return;
}
if (isConnected())
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 2de092a7bb7..d12321171a9 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
@@ -25,11 +25,11 @@
#include <cstdlib>
#include "third_party/blink/renderer/bindings/core/v8/v8_html_marquee_element.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_keyframe_effect_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_optional_effect_timing.h"
#include "third_party/blink/renderer/core/animation/document_timeline.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/animation/keyframe_effect_options.h"
-#include "third_party/blink/renderer/core/animation/optional_effect_timing.h"
#include "third_party/blink/renderer/core/animation/string_keyframe.h"
#include "third_party/blink/renderer/core/animation/timing_input.h"
#include "third_party/blink/renderer/core/css/css_property_names.h"
@@ -270,7 +270,7 @@ void HTMLMarqueeElement::ContinueAnimation() {
if (!ShouldContinue())
return;
- if (player_ && player_->playState() == "paused") {
+ if (player_ && player_->PlayStateString() == "paused") {
player_->play();
return;
}
@@ -354,10 +354,11 @@ HTMLMarqueeElement::Metrics HTMLMarqueeElement::GetMetrics() {
}
if (IsHorizontal()) {
- mover_->style()->setProperty(&GetDocument(), "width", "-webkit-max-content",
- "important", ASSERT_NO_EXCEPTION);
+ mover_->style()->setProperty(GetExecutionContext(), "width",
+ "-webkit-max-content", "important",
+ ASSERT_NO_EXCEPTION);
} else {
- mover_->style()->setProperty(&GetDocument(), "height",
+ mover_->style()->setProperty(GetExecutionContext(), "height",
"-webkit-max-content", "important",
ASSERT_NO_EXCEPTION);
}
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 ebc3879cd94..853f518aeb3 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
@@ -37,6 +37,7 @@
#include "third_party/blink/renderer/core/loader/http_equiv.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/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/wtf/text/string_to_number.h"
namespace blink {
@@ -125,9 +126,9 @@ void HTMLMetaElement::ParseContentAttribute(
String message =
"Error parsing a meta element's content: ';' is not a valid key-value "
"pair separator. Please use ',' instead.";
- document->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kRendering,
- mojom::ConsoleMessageLevel::kWarning, message));
+ document->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kRendering,
+ mojom::ConsoleMessageLevel::kWarning, message));
}
}
@@ -430,9 +431,9 @@ void HTMLMetaElement::ReportViewportWarning(Document* document,
// FIXME: This message should be moved off the console once a solution to
// https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
- document->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kRendering,
- ViewportErrorMessageLevel(error_code), message));
+ document->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kRendering,
+ ViewportErrorMessageLevel(error_code), message));
}
void HTMLMetaElement::GetViewportDescriptionFromContentAttribute(
@@ -576,8 +577,8 @@ void HTMLMetaElement::ProcessContent() {
} else if (EqualIgnoringASCIICase(name_value, "referrer")) {
UseCounter::Count(&GetDocument(),
WebFeature::kHTMLMetaElementReferrerPolicy);
- GetDocument().ParseAndSetReferrerPolicy(content_value,
- true /* support legacy keywords */);
+ GetExecutionContext()->ParseAndSetReferrerPolicy(
+ content_value, true /* support legacy keywords */);
} else if (EqualIgnoringASCIICase(name_value, "handheldfriendly") &&
EqualIgnoringASCIICase(content_value, "true")) {
ProcessViewportContentAttribute("width=device-width",
@@ -585,6 +586,14 @@ void HTMLMetaElement::ProcessContent() {
} else if (EqualIgnoringASCIICase(name_value, "mobileoptimized")) {
ProcessViewportContentAttribute("width=device-width, initial-scale=1",
ViewportDescription::kMobileOptimizedMeta);
+ } else if (EqualIgnoringASCIICase(name_value, "monetization")) {
+ // TODO(1031476): The Web Monetization specification is an unofficial draft,
+ // available at https://webmonetization.org/specification.html
+ // For now, only use counters are implemented in Blink.
+ if (!GetDocument().ParentDocument()) {
+ UseCounter::Count(&GetDocument(),
+ WebFeature::kHTMLMetaElementMonetization);
+ }
}
}
@@ -605,6 +614,6 @@ const AtomicString& HTMLMetaElement::HttpEquiv() const {
}
const AtomicString& HTMLMetaElement::GetName() const {
- return GetNameAttribute();
+ return FastGetAttribute(html_names::kNameAttr);
}
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_meta_element_test.cc b/chromium/third_party/blink/renderer/core/html/html_meta_element_test.cc
index 63bdd6c5663..2351b8db905 100644
--- a/chromium/third_party/blink/renderer/core/html/html_meta_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_meta_element_test.cc
@@ -17,22 +17,24 @@
#include "third_party/blink/renderer/core/style/computed_style.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/core/testing/sim/sim_compositor.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/heap/heap.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.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"
namespace blink {
class HTMLMetaElementTest : public PageTestBase,
private ScopedDisplayCutoutAPIForTest,
private ScopedMetaColorSchemeForTest,
- private ScopedMediaQueryPrefersColorSchemeForTest,
private ScopedCSSColorSchemeForTest {
public:
HTMLMetaElementTest()
: ScopedDisplayCutoutAPIForTest(true),
ScopedMetaColorSchemeForTest(true),
- ScopedMediaQueryPrefersColorSchemeForTest(true),
ScopedCSSColorSchemeForTest(true) {}
void SetUp() override {
PageTestBase::SetUp();
@@ -70,7 +72,7 @@ class HTMLMetaElementTest : public PageTestBase,
private:
void LoadTestPageWithViewportFitValue(const String& value) {
- GetDocument().documentElement()->SetInnerHTMLFromString(
+ GetDocument().documentElement()->setInnerHTML(
"<head>"
"<meta name='viewport' content='viewport-fit=" +
value +
@@ -78,6 +80,7 @@ class HTMLMetaElementTest : public PageTestBase,
"</head>");
}
};
+class HTMLMetaElementSimTest : public SimTest {};
TEST_F(HTMLMetaElementTest, ViewportFit_Auto) {
EXPECT_EQ(mojom::ViewportFit::kAuto,
@@ -100,7 +103,7 @@ TEST_F(HTMLMetaElementTest, ViewportFit_Invalid) {
}
TEST_F(HTMLMetaElementTest, ColorSchemeProcessing_FirstWins) {
- GetDocument().head()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().head()->setInnerHTML(R"HTML(
<meta name="color-scheme" content="dark">
<meta name="color-scheme" content="light">
)HTML");
@@ -109,7 +112,7 @@ TEST_F(HTMLMetaElementTest, ColorSchemeProcessing_FirstWins) {
}
TEST_F(HTMLMetaElementTest, ColorSchemeProcessing_Remove) {
- GetDocument().head()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().head()->setInnerHTML(R"HTML(
<meta id="first-meta" name="color-scheme" content="dark">
<meta name="color-scheme" content="light">
)HTML");
@@ -122,7 +125,7 @@ TEST_F(HTMLMetaElementTest, ColorSchemeProcessing_Remove) {
}
TEST_F(HTMLMetaElementTest, ColorSchemeProcessing_InsertBefore) {
- GetDocument().head()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().head()->setInnerHTML(R"HTML(
<meta name="color-scheme" content="dark">
)HTML");
@@ -135,7 +138,7 @@ TEST_F(HTMLMetaElementTest, ColorSchemeProcessing_InsertBefore) {
}
TEST_F(HTMLMetaElementTest, ColorSchemeProcessing_AppendChild) {
- GetDocument().head()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().head()->setInnerHTML(R"HTML(
<meta name="color-scheme" content="dark">
)HTML");
@@ -147,7 +150,7 @@ TEST_F(HTMLMetaElementTest, ColorSchemeProcessing_AppendChild) {
}
TEST_F(HTMLMetaElementTest, ColorSchemeProcessing_SetAttribute) {
- GetDocument().head()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().head()->setInnerHTML(R"HTML(
<meta id="meta" name="color-scheme" content="dark">
)HTML");
@@ -160,7 +163,7 @@ TEST_F(HTMLMetaElementTest, ColorSchemeProcessing_SetAttribute) {
}
TEST_F(HTMLMetaElementTest, ColorSchemeProcessing_RemoveContentAttribute) {
- GetDocument().head()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().head()->setInnerHTML(R"HTML(
<meta id="meta" name="color-scheme" content="dark">
)HTML");
@@ -173,7 +176,7 @@ TEST_F(HTMLMetaElementTest, ColorSchemeProcessing_RemoveContentAttribute) {
}
TEST_F(HTMLMetaElementTest, ColorSchemeProcessing_RemoveNameAttribute) {
- GetDocument().head()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().head()->setInnerHTML(R"HTML(
<meta id="meta" name="color-scheme" content="dark">
)HTML");
@@ -222,9 +225,8 @@ TEST_F(HTMLMetaElementTest, ColorSchemeParsing) {
}
TEST_F(HTMLMetaElementTest, ColorSchemeForcedDarkeningAndMQ) {
- ColorSchemeHelper color_scheme_helper;
- color_scheme_helper.SetPreferredColorScheme(GetDocument(),
- PreferredColorScheme::kDark);
+ ColorSchemeHelper color_scheme_helper(GetDocument());
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kDark);
auto* media_query = GetDocument().GetMediaQueryMatcher().MatchMedia(
"(prefers-color-scheme: dark)");
@@ -243,7 +245,7 @@ TEST_F(HTMLMetaElementTest, ColorSchemeForcedDarkeningAndMQ) {
}
TEST_F(HTMLMetaElementTest, ReferrerPolicyWithoutContent) {
- GetDocument().head()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().head()->setInnerHTML(R"HTML(
<meta name="referrer" content="strict-origin">
<meta name="referrer" >
)HTML");
@@ -251,4 +253,60 @@ TEST_F(HTMLMetaElementTest, ReferrerPolicyWithoutContent) {
GetDocument().GetReferrerPolicy());
}
+// This tests whether Web Monetization counter is properly triggered.
+TEST_F(HTMLMetaElementTest, WebMonetizationCounter) {
+ // <meta> elements that don't have name equal to "monetization" or that lack
+ // a content attribute are not counted.
+ GetDocument().head()->setInnerHTML(R"HTML(
+ <meta name="color-scheme" content="dark">
+ <meta name="monetization">
+ )HTML");
+ EXPECT_FALSE(
+ GetDocument().IsUseCounted(WebFeature::kHTMLMetaElementMonetization));
+
+ // A <link rel="monetization"> with a content attribute is counted.
+ GetDocument().head()->setInnerHTML(R"HTML(
+ <meta name="monetization" content="$payment.pointer.url">
+ )HTML");
+ EXPECT_TRUE(
+ GetDocument().IsUseCounted(WebFeature::kHTMLMetaElementMonetization));
+
+ // However, it does not affect the counter for <link rel="monetization">.
+ EXPECT_FALSE(
+ GetDocument().IsUseCounted(WebFeature::kHTMLLinkElementMonetization));
+}
+
+TEST_F(HTMLMetaElementSimTest, WebMonetizationNotCountedInSubFrame) {
+ SimRequest main_resource("https://example.com/", "text/html");
+ SimRequest child_frame_resource("https://example.com/subframe.html",
+ "text/html");
+
+ LoadURL("https://example.com/");
+
+ main_resource.Complete(String::Format(
+ R"HTML(
+ <body onload='console.log("main body onload");'>
+ <iframe src='https://example.com/subframe.html'
+ onload='console.log("child frame element onload");'></iframe>
+ </body>)HTML"));
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+
+ child_frame_resource.Complete(String::Format(R"HTML(
+ <meta name="monetization" content="$payment.pointer.url">
+ )HTML"));
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+
+ // Ensure that main frame and subframe are loaded before checking the counter.
+ EXPECT_TRUE(ConsoleMessages().Contains("main body onload"));
+ EXPECT_TRUE(ConsoleMessages().Contains("child frame element onload"));
+
+ // <meta name="monetization"> is not counted in subframes.
+ EXPECT_FALSE(
+ GetDocument().IsUseCounted(WebFeature::kHTMLMetaElementMonetization));
+}
+
} // namespace blink
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 ed6f1c9e383..ada15e6ea4b 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
@@ -31,6 +31,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/instrumentation/use_counter.h"
+#include "ui/base/ui_base_features.h"
namespace blink {
@@ -183,15 +184,7 @@ void HTMLMeterElement::DidAddUserAgentShadowRoot(ShadowRoot& root) {
value_ = MakeGarbageCollected<HTMLDivElement>(GetDocument());
UpdateValueAppearance(0);
-
- if (RuntimeEnabledFeatures::FormControlsRefreshEnabled()) {
- auto* clip = MakeGarbageCollected<HTMLDivElement>(GetDocument());
- clip->SetShadowPseudoId(AtomicString("-internal-meter-clip"));
- bar->AppendChild(clip);
- clip->AppendChild(value_);
- } else {
- bar->AppendChild(value_);
- }
+ bar->AppendChild(value_);
inner->AppendChild(bar);
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 c71725eb164..3a6e50e713f 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
@@ -71,7 +71,6 @@ class CORE_EXPORT HTMLMeterElement final : public HTMLElement {
bool AreAuthorShadowsAllowed() const override { return false; }
bool IsLabelable() const override { return true; }
- bool TypeShouldForceLegacyLayout() const final { return true; }
LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override;
void ParseAttribute(const AttributeModificationParams&) override;
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 12b0d668813..6a2465ce913 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
@@ -66,8 +66,8 @@ void HTMLObjectElement::Trace(Visitor* visitor) {
const AttrNameToTrustedType& HTMLObjectElement::GetCheckedAttributeTypes()
const {
DEFINE_STATIC_LOCAL(AttrNameToTrustedType, attribute_map,
- ({{"data", SpecificTrustedType::kTrustedScriptURL},
- {"codebase", SpecificTrustedType::kTrustedScriptURL}}));
+ ({{"data", SpecificTrustedType::kScriptURL},
+ {"codebase", SpecificTrustedType::kScriptURL}}));
return attribute_map;
}
@@ -126,18 +126,6 @@ void HTMLObjectElement::ParseAttribute(
}
}
-static void MapDataParamToSrc(PluginParameters& plugin_params) {
- // Some plugins don't understand the "data" attribute of the OBJECT tag (i.e.
- // Real and WMP require "src" attribute).
- int src_index = plugin_params.FindStringInNames("src");
- int data_index = plugin_params.FindStringInNames("data");
-
- if (src_index == -1 && data_index != -1) {
- plugin_params.AppendNameWithValue("src",
- plugin_params.Values()[data_index]);
- }
-}
-
// TODO(schenney): crbug.com/572908 This function should not deal with url or
// serviceType!
void HTMLObjectElement::ParametersForPlugin(PluginParameters& plugin_params) {
@@ -161,13 +149,13 @@ void HTMLObjectElement::ParametersForPlugin(PluginParameters& plugin_params) {
// for compatibility, allow the resource's URL to be given by a param
// element with one of the common names if we know that resource points
// to a plugin.
- if (url_.IsEmpty() && !DeprecatedEqualIgnoringCase(name, "data") &&
+ if (url_.IsEmpty() && !EqualIgnoringASCIICase(name, "data") &&
HTMLParamElement::IsURLParameter(name)) {
SetUrl(StripLeadingAndTrailingHTMLSpaces(p->Value()));
}
// TODO(schenney): crbug.com/572908 serviceType calculation does not belong
// in this function.
- if (service_type_.IsEmpty() && DeprecatedEqualIgnoringCase(name, "type")) {
+ if (service_type_.IsEmpty() && EqualIgnoringASCIICase(name, "type")) {
wtf_size_t pos = p->Value().Find(";");
if (pos != kNotFound)
SetServiceType(p->Value().GetString().Left(pos));
@@ -183,7 +171,9 @@ void HTMLObjectElement::ParametersForPlugin(PluginParameters& plugin_params) {
plugin_params.AppendAttribute(attribute);
}
- MapDataParamToSrc(plugin_params);
+ // Some plugins don't understand the "data" attribute of the OBJECT tag (i.e.
+ // Real and WMP require "src" attribute).
+ plugin_params.MapDataParamToSrc();
}
bool HTMLObjectElement::HasFallbackContent() const {
@@ -395,7 +385,7 @@ bool HTMLObjectElement::ContainsJavaApplet() const {
for (HTMLElement& child : Traversal<HTMLElement>::ChildrenOf(*this)) {
if (IsA<HTMLParamElement>(child) &&
- DeprecatedEqualIgnoringCase(child.GetNameAttribute(), "type") &&
+ EqualIgnoringASCIICase(child.GetNameAttribute(), "type") &&
MIMETypeRegistry::IsJavaAppletMIMEType(
child.FastGetAttribute(html_names::kValueAttr).GetString()))
return true;
diff --git a/chromium/third_party/blink/renderer/core/html/html_object_element_test.cc b/chromium/third_party/blink/renderer/core/html/html_object_element_test.cc
index e69abf0ea5f..def6ca850c9 100644
--- a/chromium/third_party/blink/renderer/core/html/html_object_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_object_element_test.cc
@@ -25,7 +25,7 @@ class HTMLObjectElementTest : public testing::Test {
};
TEST_F(HTMLObjectElementTest, FallbackRecalcForReattach) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<object id='obj' data='dummy'></object>
)HTML");
@@ -35,8 +35,7 @@ TEST_F(HTMLObjectElementTest, FallbackRecalcForReattach) {
Node* slot = object->GetShadowRoot()->firstChild();
ASSERT_TRUE(slot);
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
object->RenderFallbackContent(nullptr);
GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc);
diff --git a/chromium/third_party/blink/renderer/core/html/html_or_foreign_element.idl b/chromium/third_party/blink/renderer/core/html/html_or_foreign_element.idl
index 8ee6971d8eb..a49710e81fa 100644
--- a/chromium/third_party/blink/renderer/core/html/html_or_foreign_element.idl
+++ b/chromium/third_party/blink/renderer/core/html/html_or_foreign_element.idl
@@ -11,7 +11,7 @@ interface mixin HTMLOrForeignElement {
[CEReactions, Reflect] attribute boolean autofocus;
[Affects=Nothing, CEReactions, CustomElementCallbacks] attribute long tabIndex;
- void focus(optional FocusOptions options);
+ void focus(optional FocusOptions options = {});
void blur();
};
diff --git a/chromium/third_party/blink/renderer/core/html/html_paragraph_element.cc b/chromium/third_party/blink/renderer/core/html/html_paragraph_element.cc
index b7811d5e690..938e28be96a 100644
--- a/chromium/third_party/blink/renderer/core/html/html_paragraph_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_paragraph_element.cc
@@ -36,14 +36,14 @@ void HTMLParagraphElement::CollectStyleForPresentationAttribute(
const AtomicString& value,
MutableCSSPropertyValueSet* style) {
if (name == html_names::kAlignAttr) {
- if (DeprecatedEqualIgnoringCase(value, "middle") ||
- DeprecatedEqualIgnoringCase(value, "center")) {
+ if (EqualIgnoringASCIICase(value, "middle") ||
+ EqualIgnoringASCIICase(value, "center")) {
AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kTextAlign,
CSSValueID::kWebkitCenter);
- } else if (DeprecatedEqualIgnoringCase(value, "left")) {
+ } else if (EqualIgnoringASCIICase(value, "left")) {
AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kTextAlign,
CSSValueID::kWebkitLeft);
- } else if (DeprecatedEqualIgnoringCase(value, "right")) {
+ } else if (EqualIgnoringASCIICase(value, "right")) {
AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kTextAlign,
CSSValueID::kWebkitRight);
} else {
diff --git a/chromium/third_party/blink/renderer/core/html/html_param_element.cc b/chromium/third_party/blink/renderer/core/html/html_param_element.cc
index 68d6bbc8618..dd219dd0b56 100644
--- a/chromium/third_party/blink/renderer/core/html/html_param_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_param_element.cc
@@ -24,6 +24,7 @@
#include "third_party/blink/renderer/core/dom/attribute.h"
#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html_names.h"
namespace blink {
@@ -34,7 +35,7 @@ HTMLParamElement::HTMLParamElement(Document& document)
const AtomicString& HTMLParamElement::GetName() const {
if (HasName())
return GetNameAttribute();
- return GetDocument().IsHTMLDocument() ? g_empty_atom : GetIdAttribute();
+ return IsA<HTMLDocument>(GetDocument()) ? g_empty_atom : GetIdAttribute();
}
const AtomicString& HTMLParamElement::Value() const {
@@ -46,11 +47,11 @@ const AtomicString& HTMLParamElement::Value() const {
// allow the resource's URL to be given by a param of the named "code",
// "data", "movie", "src" or "url".
bool HTMLParamElement::IsURLParameter(const String& name) {
- return DeprecatedEqualIgnoringCase(name, "code") ||
- DeprecatedEqualIgnoringCase(name, "data") ||
- DeprecatedEqualIgnoringCase(name, "movie") ||
- DeprecatedEqualIgnoringCase(name, "src") ||
- DeprecatedEqualIgnoringCase(name, "url");
+ return EqualIgnoringASCIICase(name, "code") ||
+ EqualIgnoringASCIICase(name, "data") ||
+ EqualIgnoringASCIICase(name, "movie") ||
+ EqualIgnoringASCIICase(name, "src") ||
+ EqualIgnoringASCIICase(name, "url");
}
bool HTMLParamElement::IsURLAttribute(const Attribute& attribute) const {
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 16a0c13eba1..a1564b5d615 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
@@ -23,6 +23,7 @@
#include "third_party/blink/renderer/core/html/html_plugin_element.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
+#include "third_party/blink/public/mojom/feature_policy/policy_value.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/loader/request_context_frame_type.mojom-blink.h"
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
@@ -52,7 +53,7 @@
#include "third_party/blink/renderer/core/page/plugin_data.h"
#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.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/resource_request.h"
#include "third_party/blink/renderer/platform/network/mime/mime_type_from_url.h"
@@ -94,12 +95,22 @@ void PluginParameters::AppendNameWithValue(const String& name,
values_.push_back(value);
}
-int PluginParameters::FindStringInNames(const String& str) {
- for (wtf_size_t i = 0; i < names_.size(); ++i) {
- if (DeprecatedEqualIgnoringCase(names_[i], str))
- return i;
+void PluginParameters::MapDataParamToSrc() {
+ auto* src = std::find_if(names_.begin(), names_.end(), [](auto name) {
+ return EqualIgnoringASCIICase(name, "src");
+ });
+
+ if (src != names_.end()) {
+ return;
+ }
+
+ auto* data = std::find_if(names_.begin(), names_.end(), [](auto name) {
+ return EqualIgnoringASCIICase(name, "data");
+ });
+
+ if (data != names_.end()) {
+ AppendNameWithValue("src", values_[data - names_.begin()]);
}
- return -1;
}
HTMLPlugInElement::HTMLPlugInElement(
@@ -149,7 +160,8 @@ void HTMLPlugInElement::SetPersistedPlugin(WebPluginContainerImpl* plugin) {
persisted_plugin_ = plugin;
}
-void HTMLPlugInElement::SetFocused(bool focused, WebFocusType focus_type) {
+void HTMLPlugInElement::SetFocused(bool focused,
+ mojom::blink::FocusType focus_type) {
WebPluginContainerImpl* plugin = OwnedPlugin();
if (plugin)
plugin->SetFocused(focused, focus_type);
@@ -228,7 +240,7 @@ void HTMLPlugInElement::AttachLayoutTree(AttachContext& context) {
ToLayoutImage(layout_object)->ImageResource();
image_resource->SetImageResource(image_loader_->GetContent());
}
- if (!layout_object->IsFloatingOrOutOfFlowPositioned())
+ if (layout_object->AffectsWhitespaceSiblings())
context.previous_in_flow = layout_object;
dispose_view_ = false;
@@ -269,7 +281,8 @@ ParsedFeaturePolicy HTMLPlugInElement::ConstructContainerPolicy(
// https://fullscreen.spec.whatwg.org/#model
ParsedFeaturePolicy container_policy;
ParsedFeaturePolicyDeclaration allowlist(
- mojom::FeaturePolicyFeature::kFullscreen, mojom::PolicyValueType::kBool);
+ mojom::blink::FeaturePolicyFeature::kFullscreen,
+ mojom::blink::PolicyValueType::kBool);
container_policy.push_back(allowlist);
return container_policy;
}
@@ -291,7 +304,8 @@ void HTMLPlugInElement::DetachLayoutTree(bool performing_reattach) {
// Only try to persist a plugin we actually own.
WebPluginContainerImpl* plugin = OwnedPlugin();
if (plugin && keep_plugin) {
- SetPersistedPlugin(ToWebPluginContainerImpl(ReleaseEmbeddedContentView()));
+ SetPersistedPlugin(
+ To<WebPluginContainerImpl>(ReleaseEmbeddedContentView()));
} else {
// A persisted plugin isn't processed and hooked up immediately
// (synchronously) when attaching the layout object, so it's possible that
@@ -391,7 +405,7 @@ WebPluginContainerImpl* HTMLPlugInElement::PluginEmbeddedContentView() const {
WebPluginContainerImpl* HTMLPlugInElement::OwnedPlugin() const {
EmbeddedContentView* view = OwnedEmbeddedContentView();
if (view && view->IsPluginView())
- return ToWebPluginContainerImpl(view);
+ return To<WebPluginContainerImpl>(view);
return nullptr;
}
@@ -458,7 +472,7 @@ LayoutEmbeddedContent* HTMLPlugInElement::LayoutEmbeddedContentForJSBindings()
// Needs to load the plugin immediatedly because this function is called
// when JavaScript code accesses the plugin.
// FIXME: Check if dispatching events here is safe.
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
if (auto* view = GetDocument().View())
view->FlushAnyPendingPostLayoutTasks();
@@ -642,7 +656,7 @@ bool HTMLPlugInElement::LoadPlugin(const KURL& url,
layout_object->GetFrameView()->AddPlugin(plugin);
} else {
bool load_manually =
- GetDocument().IsPluginDocument() && !GetDocument().ContainsPlugins();
+ IsA<PluginDocument>(GetDocument()) && !GetDocument().ContainsPlugins();
WebPluginContainerImpl* plugin = frame->Client()->CreatePlugin(
*this, url, plugin_params.Names(), plugin_params.Values(), mime_type,
load_manually);
@@ -676,7 +690,7 @@ bool HTMLPlugInElement::LoadPlugin(const KURL& url,
}
void HTMLPlugInElement::DispatchErrorEvent() {
- if (GetDocument().IsPluginDocument() && GetDocument().LocalOwner()) {
+ if (IsA<PluginDocument>(GetDocument()) && GetDocument().LocalOwner()) {
GetDocument().LocalOwner()->DispatchEvent(
*Event::Create(event_type_names::kError));
} else {
@@ -718,14 +732,14 @@ bool HTMLPlugInElement::AllowedToLoadObject(const KURL& url,
bool HTMLPlugInElement::AllowedToLoadPlugin(const KURL& url,
const String& mime_type) {
- if (GetDocument().IsSandboxed(WebSandboxFlags::kPlugins)) {
- GetDocument().AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kError,
- "Failed to load '" + url.ElidedString() +
- "' as a plugin, because the "
- "frame into which the plugin "
- "is loading is sandboxed."));
+ if (GetDocument().IsSandboxed(mojom::blink::WebSandboxFlags::kPlugins)) {
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kSecurity,
+ mojom::ConsoleMessageLevel::kError,
+ "Failed to load '" + url.ElidedString() +
+ "' as a plugin, because the "
+ "frame into which the plugin "
+ "is loading is sandboxed."));
return false;
}
return true;
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 b09c23dc2dc..56ffb6e89a6 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
@@ -52,7 +52,7 @@ class PluginParameters {
const Vector<String>& Values() const;
void AppendAttribute(const Attribute&);
void AppendNameWithValue(const String& name, const String& value);
- int FindStringInNames(const String&);
+ void MapDataParamToSrc();
private:
Vector<String> names_;
@@ -72,7 +72,7 @@ class CORE_EXPORT HTMLPlugInElement
bool HasPendingActivity() const final;
- void SetFocused(bool, WebFocusType) override;
+ void SetFocused(bool, mojom::blink::FocusType) override;
void ResetInstance();
// TODO(dcheng): Consider removing this, since HTMLEmbedElementLegacyCall
// and HTMLObjectElementLegacyCall usage is extremely low.
@@ -235,11 +235,20 @@ class CORE_EXPORT HTMLPlugInElement
bool dispose_view_ = false;
};
-inline bool IsHTMLPlugInElement(const HTMLElement& element) {
- return element.IsPluginElement();
+template <>
+inline bool IsElementOfType<const HTMLPlugInElement>(const Node& node) {
+ return IsA<HTMLPlugInElement>(node);
}
-
-DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLPlugInElement);
+template <>
+struct DowncastTraits<HTMLPlugInElement> {
+ static bool AllowFrom(const Node& node) {
+ auto* html_element = DynamicTo<HTMLElement>(node);
+ return html_element && AllowFrom(*html_element);
+ }
+ static bool AllowFrom(const HTMLElement& html_element) {
+ return html_element.IsPluginElement();
+ }
+};
} // namespace blink
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 28e4c33e289..985076f427b 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
@@ -108,11 +108,11 @@ TEST_P(HTMLPlugInElementTest, RemovePlugin) {
)HTML";
const char* container_type = GetParam();
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
String::Format(kDivWithPlugin, container_type, container_type));
auto* plugin =
- ToHTMLPlugInElement(GetDocument().getElementById("test_plugin"));
+ To<HTMLPlugInElement>(GetDocument().getElementById("test_plugin"));
ASSERT_TRUE(plugin);
EXPECT_EQ(container_type, plugin->tagName().LowerASCII());
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 2422cba1469..1fda09d556e 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
@@ -46,13 +46,14 @@ namespace blink {
HTMLScriptElement::HTMLScriptElement(Document& document,
const CreateElementFlags flags)
: HTMLElement(html_names::kScriptTag, document),
+ children_changed_by_api_(false),
loader_(InitializeScriptLoader(flags.IsCreatedByParser(),
flags.WasAlreadyStarted())) {}
const AttrNameToTrustedType& HTMLScriptElement::GetCheckedAttributeTypes()
const {
DEFINE_STATIC_LOCAL(AttrNameToTrustedType, attribute_map,
- ({{"src", SpecificTrustedType::kTrustedScriptURL}}));
+ ({{"src", SpecificTrustedType::kScriptURL}}));
return attribute_map;
}
@@ -74,6 +75,10 @@ void HTMLScriptElement::ChildrenChanged(const ChildrenChange& change) {
HTMLElement::ChildrenChanged(change);
if (change.IsChildInsertion())
loader_->ChildrenChanged();
+
+ // We'll record whether the script element children were ever changed by
+ // the API (as opposed to the parser).
+ children_changed_by_api_ |= !change.ByParser();
}
void HTMLScriptElement::DidMoveToNewDocument(Document& old_document) {
@@ -118,10 +123,8 @@ void HTMLScriptElement::DidNotifySubtreeInsertionsToDocument() {
loader_->DidNotifySubtreeInsertionsToDocument();
}
-void HTMLScriptElement::setText(
- const StringOrTrustedScript& string_or_trusted_script,
- ExceptionState& exception_state) {
- setTextContent(string_or_trusted_script, exception_state);
+void HTMLScriptElement::setText(const String& string) {
+ setTextContent(string);
}
void HTMLScriptElement::text(StringOrTrustedScript& result) {
@@ -131,20 +134,36 @@ void HTMLScriptElement::text(StringOrTrustedScript& result) {
void HTMLScriptElement::setInnerText(
const StringOrTrustedScript& string_or_trusted_script,
ExceptionState& exception_state) {
- String value = GetStringFromTrustedScript(string_or_trusted_script,
- &GetDocument(), exception_state);
+ String value = TrustedTypesCheckForScript(
+ string_or_trusted_script, GetExecutionContext(), exception_state);
if (!exception_state.HadException()) {
+ // https://w3c.github.io/webappsec-trusted-types/dist/spec/#setting-slot-values
+ // On setting, the innerText [...] perform the regular steps, and then set
+ // content object's [[ScriptText]] internal slot value [...].
HTMLElement::setInnerText(value, exception_state);
+ script_text_internal_slot_ = ParkableString(value.Impl());
}
}
+void HTMLScriptElement::setTextContent(const String& string) {
+ // https://w3c.github.io/webappsec-trusted-types/dist/spec/#setting-slot-values
+ // On setting, [..] textContent [..] perform the regular steps, and then set
+ // content object's [[ScriptText]] internal slot value [...].
+ Node::setTextContent(string);
+ script_text_internal_slot_ = ParkableString(string.Impl());
+}
+
void HTMLScriptElement::setTextContent(
const StringOrTrustedScript& string_or_trusted_script,
ExceptionState& exception_state) {
- String value = GetStringFromTrustedScript(string_or_trusted_script,
- &GetDocument(), exception_state);
+ String value = TrustedTypesCheckForScript(
+ string_or_trusted_script, GetExecutionContext(), exception_state);
if (!exception_state.HadException()) {
+ // https://w3c.github.io/webappsec-trusted-types/dist/spec/#setting-slot-values
+ // On setting, [..] textContent [..] perform the regular steps, and then set
+ // content object's [[ScriptText]] internal slot value [...].
Node::setTextContent(value);
+ script_text_internal_slot_ = ParkableString(value.Impl());
}
}
@@ -153,6 +172,19 @@ void HTMLScriptElement::setAsync(bool async) {
loader_->HandleAsyncAttribute();
}
+void HTMLScriptElement::FinishParsingChildren() {
+ Element::FinishParsingChildren();
+
+ // We normally expect the parser to finish parsing before any script gets
+ // a chance to manipulate the script. However, if script parsing gets
+ // deferrred (or similar; see crbug.com/1033101) then a script might get
+ // access to the HTMLScriptElement before. In this case, we cannot blindly
+ // accept the current TextFromChildren as a parser result.
+ DCHECK(children_changed_by_api_ || !script_text_internal_slot_.length());
+ if (!children_changed_by_api_)
+ script_text_internal_slot_ = ParkableString(TextFromChildren().Impl());
+}
+
bool HTMLScriptElement::async() const {
return FastHasAttribute(html_names::kAsyncAttr) || loader_->IsNonBlocking();
}
@@ -201,8 +233,12 @@ String HTMLScriptElement::ImportanceAttributeValue() const {
return FastGetAttribute(html_names::kImportanceAttr);
}
-String HTMLScriptElement::TextFromChildren() {
- return Element::TextFromChildren();
+String HTMLScriptElement::ChildTextContent() {
+ return TextFromChildren();
+}
+
+String HTMLScriptElement::ScriptTextInternalSlot() const {
+ return script_text_internal_slot_.ToString();
}
bool HTMLScriptElement::AsyncAttributeValue() const {
@@ -257,6 +293,10 @@ void HTMLScriptElement::SetScriptElementForBinding(
element.SetHTMLScriptElement(this);
}
+ScriptElementBase::Type HTMLScriptElement::GetScriptElementType() {
+ return ScriptElementBase::Type::kHTMLScriptElement;
+}
+
Element& HTMLScriptElement::CloneWithoutAttributesAndChildren(
Document& factory) const {
CreateElementFlags flags =
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 ca7f9f5f44c..dc5f7fb99a6 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
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/script/script_element_base.h"
#include "third_party/blink/renderer/core/script/script_loader.h"
+#include "third_party/blink/renderer/platform/bindings/parkable_string.h"
namespace blink {
@@ -48,9 +49,11 @@ class CORE_EXPORT HTMLScriptElement final : public HTMLElement,
const AttrNameToTrustedType& GetCheckedAttributeTypes() const override;
void text(StringOrTrustedScript& result);
- void setText(const StringOrTrustedScript&, ExceptionState&);
+ String text() { return TextFromChildren(); }
+ void setText(const String&);
void setInnerText(const StringOrTrustedScript&, ExceptionState&) override;
void setTextContent(const StringOrTrustedScript&, ExceptionState&) override;
+ void setTextContent(const String&) override;
void setAsync(bool);
bool async() const;
@@ -62,6 +65,8 @@ class CORE_EXPORT HTMLScriptElement final : public HTMLElement,
void Trace(Visitor*) override;
+ void FinishParsingChildren() override;
+
private:
void ParseAttribute(const AttributeModificationParams&) override;
InsertionNotificationRequest InsertedInto(ContainerNode&) override;
@@ -85,7 +90,8 @@ class CORE_EXPORT HTMLScriptElement final : public HTMLElement,
String IntegrityAttributeValue() const override;
String ReferrerPolicyAttributeValue() const override;
String ImportanceAttributeValue() const override;
- String TextFromChildren() override;
+ String ChildTextContent() override;
+ String ScriptTextInternalSlot() const override;
bool AsyncAttributeValue() const override;
bool DeferAttributeValue() const override;
bool HasSourceAttribute() const override;
@@ -103,8 +109,14 @@ class CORE_EXPORT HTMLScriptElement final : public HTMLElement,
void SetScriptElementForBinding(
HTMLScriptElementOrSVGScriptElement&) override;
+ Type GetScriptElementType() override;
+
Element& CloneWithoutAttributesAndChildren(Document&) const override;
+ // https://w3c.github.io/webappsec-trusted-types/dist/spec/#script-scripttext
+ ParkableString script_text_internal_slot_;
+ bool children_changed_by_api_;
+
Member<ScriptLoader> loader_;
};
diff --git a/chromium/third_party/blink/renderer/core/html/html_script_element.idl b/chromium/third_party/blink/renderer/core/html/html_script_element.idl
index 2d6feee429a..f92832a7cac 100644
--- a/chromium/third_party/blink/renderer/core/html/html_script_element.idl
+++ b/chromium/third_party/blink/renderer/core/html/html_script_element.idl
@@ -29,7 +29,7 @@
[CEReactions] attribute boolean async;
[CEReactions, Reflect] attribute boolean defer;
[CEReactions, Reflect, ReflectOnly=("anonymous","use-credentials"), ReflectEmpty="anonymous", ReflectInvalid="anonymous"] attribute DOMString? crossOrigin;
- [CEReactions, RaisesException=Setter] attribute ScriptString text;
+ [CEReactions] attribute ScriptString text;
[CEReactions, Reflect, ReflectOnly=("", "no-referrer", "no-referrer-when-downgrade", "same-origin", "origin", "strict-origin", "origin-when-cross-origin", "strict-origin-when-cross-origin", "unsafe-url"), ReflectEmpty="", ReflectInvalid=""] attribute DOMString? referrerPolicy;
[CEReactions, MeasureAs=PriorityHints, RuntimeEnabled=PriorityHints, Reflect, ReflectOnly=("low", "auto", "high"), ReflectMissing="auto", ReflectInvalid="auto"] attribute DOMString importance;
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
new file mode 100644
index 00000000000..2ea58d2feea
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/html_script_element_test.cc
@@ -0,0 +1,69 @@
+// 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/html_script_element.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/dom/create_element_flags.h"
+#include "third_party/blink/renderer/core/dom/text.h"
+#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
+
+namespace blink {
+
+class HTMLScriptElementTest : public testing::Test {
+ public:
+ void SetUp() override {
+ dummy_page_holder_ = std::make_unique<DummyPageHolder>();
+ }
+
+ Document& document() { return dummy_page_holder_->GetDocument(); }
+
+ HTMLScriptElement* MakeScript() {
+ HTMLScriptElement* script = To<HTMLScriptElement>(
+ document().body()->AppendChild(MakeGarbageCollected<HTMLScriptElement>(
+ document(), CreateElementFlags::ByParser())));
+ EXPECT_TRUE(script);
+ return script;
+ }
+
+ protected:
+ std::unique_ptr<DummyPageHolder> dummy_page_holder_;
+};
+
+TEST_F(HTMLScriptElementTest, ScriptTextInternalSlotSimple) {
+ HTMLScriptElement* script = MakeScript();
+ ScriptElementBase* script_base = script;
+ EXPECT_EQ(script_base->ScriptTextInternalSlot(), "");
+
+ script->ParserAppendChild(Text::Create(document(), "abc"));
+ EXPECT_EQ(script_base->ScriptTextInternalSlot(), "");
+
+ script->FinishParsingChildren();
+ EXPECT_EQ(script_base->ScriptTextInternalSlot(), "abc");
+}
+
+TEST_F(HTMLScriptElementTest, ScriptTextInternalSlotMultiple) {
+ HTMLScriptElement* script = MakeScript();
+ script->ParserAppendChild(Text::Create(document(), "abc"));
+ script->ParserAppendChild(Text::Create(document(), "def"));
+ script->ParserAppendChild(Text::Create(document(), "ghi"));
+ script->FinishParsingChildren();
+
+ ScriptElementBase* script_base = script;
+ EXPECT_EQ(script_base->ScriptTextInternalSlot(), "abcdefghi");
+}
+
+TEST_F(HTMLScriptElementTest,
+ ScriptTextInternalSlotScriptParsingInterruptedByApiCall) {
+ HTMLScriptElement* script = MakeScript();
+ script->ParserAppendChild(Text::Create(document(), "abc"));
+ script->AppendChild(Text::Create(document(), "def"));
+ script->ParserAppendChild(Text::Create(document(), "ghi"));
+ script->FinishParsingChildren();
+
+ ScriptElementBase* script_base = script;
+ EXPECT_EQ(script_base->ScriptTextInternalSlot(), "");
+}
+
+} // namespace blink
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 f88a1f593c8..fd8cc754219 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
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/core/html/html_slot_element.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_assigned_nodes_options.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/dom/events/event.h"
@@ -42,7 +43,6 @@
#include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/dom/whitespace_attacher.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
-#include "third_party/blink/renderer/core/html/assigned_nodes_options.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
@@ -171,13 +171,33 @@ const HeapVector<Member<Element>> HTMLSlotElement::AssignedElementsForBinding(
return elements;
}
-void HTMLSlotElement::assign(HeapVector<Member<Node>> nodes) {
- if (SupportsAssignment())
- ContainingShadowRoot()->GetSlotAssignment().SetNeedsAssignmentRecalc();
+void HTMLSlotElement::assign(HeapVector<Member<Node>> nodes,
+ ExceptionState& exception_state) {
+ if (!SupportsAssignment() || !ContainingShadowRoot()->IsManualSlotting()) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotAllowedError,
+ "This shadow root does not support manual slot assignment.");
+ return;
+ }
+
assigned_nodes_candidates_.clear();
+ auto* host = OwnerShadowHost();
+ bool has_invalid_node = false;
for (auto& node : nodes) {
+ if (node->parentNode() != host) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotAllowedError,
+ "Node: '" + node->nodeName() +
+ "' is invalid for manual slot assignment.");
+ assigned_nodes_candidates_.clear();
+ has_invalid_node = true;
+ break;
+ }
assigned_nodes_candidates_.insert(node);
}
+
+ if (!has_invalid_node)
+ ContainingShadowRoot()->GetSlotAssignment().SetNeedsAssignmentRecalc();
}
void HTMLSlotElement::AppendAssignedNode(Node& host_child) {
@@ -197,6 +217,11 @@ void HTMLSlotElement::ClearAssignedNodesAndFlatTreeChildren() {
void HTMLSlotElement::UpdateFlatTreeNodeDataForAssignedNodes() {
Node* previous = nullptr;
for (auto& current : assigned_nodes_) {
+ bool flat_tree_parent_changed = false;
+ if (!current->NeedsStyleRecalc() && !current->GetComputedStyle()) {
+ if (auto* node_data = current->GetFlatTreeNodeData())
+ flat_tree_parent_changed = !node_data->AssignedSlot();
+ }
FlatTreeNodeData& flat_tree_node_data = current->EnsureFlatTreeNodeData();
flat_tree_node_data.SetAssignedSlot(this);
flat_tree_node_data.SetPreviousInAssignedNodes(previous);
@@ -205,6 +230,8 @@ void HTMLSlotElement::UpdateFlatTreeNodeDataForAssignedNodes() {
previous->GetFlatTreeNodeData()->SetNextInAssignedNodes(current);
}
previous = current;
+ if (flat_tree_parent_changed)
+ current->FlatTreeParentChanged();
}
if (previous) {
DCHECK(previous->GetFlatTreeNodeData());
@@ -273,8 +300,10 @@ void HTMLSlotElement::AttachLayoutTree(AttachContext& context) {
void HTMLSlotElement::DetachLayoutTree(bool performing_reattach) {
if (SupportsAssignment()) {
const HeapVector<Member<Node>>& flat_tree_children = assigned_nodes_;
- for (auto& node : flat_tree_children)
- node->DetachLayoutTree(performing_reattach);
+ for (auto& node : flat_tree_children) {
+ if (node->GetDocument() == GetDocument())
+ node->DetachLayoutTree(performing_reattach);
+ }
}
HTMLElement::DetachLayoutTree(performing_reattach);
}
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 6a73f8f8320..f3d054d8136 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
@@ -110,7 +110,7 @@ class CORE_EXPORT HTMLSlotElement final : public HTMLElement {
static const AtomicString& UserAgentDefaultSlotName();
// For imperative Shadow DOM distribution APIs
- void assign(HeapVector<Member<Node>> nodes);
+ void assign(HeapVector<Member<Node>> nodes, ExceptionState&);
const HeapHashSet<Member<Node>>& AssignedNodesCandidate() const {
return assigned_nodes_candidates_;
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_slot_element.idl b/chromium/third_party/blink/renderer/core/html/html_slot_element.idl
index 3a69ddf1a71..ce9723fd78f 100644
--- a/chromium/third_party/blink/renderer/core/html/html_slot_element.idl
+++ b/chromium/third_party/blink/renderer/core/html/html_slot_element.idl
@@ -24,11 +24,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// https://w3c.github.io/webcomponents/spec/shadow/#the-slot-element
+// https://html.spec.whatwg.org/C/#the-slot-element
[HTMLConstructor]
interface HTMLSlotElement : HTMLElement {
[CEReactions, Reflect] attribute DOMString name;
- [ImplementedAs=AssignedNodesForBinding] sequence<Node> assignedNodes(optional AssignedNodesOptions options);
- [ImplementedAs=AssignedElementsForBinding] sequence<Element> assignedElements(optional AssignedNodesOptions options);
- [RuntimeEnabled=ManualSlotting] void assign(sequence<Node> nodes);
+ [ImplementedAs=AssignedNodesForBinding] sequence<Node> assignedNodes(optional AssignedNodesOptions options = {});
+ [ImplementedAs=AssignedElementsForBinding] sequence<Element> assignedElements(optional AssignedNodesOptions options = {});
+ [RuntimeEnabled=ManualSlotting, RaisesException] void assign(sequence<Node> nodes);
};
diff --git a/chromium/third_party/blink/renderer/core/html/html_slot_element_test.cc b/chromium/third_party/blink/renderer/core/html/html_slot_element_test.cc
index 745d1aa56c3..72c065d413f 100644
--- a/chromium/third_party/blink/renderer/core/html/html_slot_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_slot_element_test.cc
@@ -147,7 +147,7 @@ class HTMLSlotElementInDocumentTest : public testing::Test {
};
TEST_F(HTMLSlotElementInDocumentTest, RecalcAssignedNodeStyleForReattach) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<div id='host'><span id='span'></span></div>
)HTML");
@@ -157,12 +157,10 @@ TEST_F(HTMLSlotElementInDocumentTest, RecalcAssignedNodeStyleForReattach) {
ShadowRoot& shadow_root =
host.AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString(
- R"HTML(<span><slot /></span>)HTML");
+ shadow_root.setInnerHTML(R"HTML(<span><slot /></span>)HTML");
auto* shadow_span = To<Element>(shadow_root.firstChild());
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
shadow_span->setAttribute(html_names::kStyleAttr, "display:block");
@@ -174,7 +172,7 @@ TEST_F(HTMLSlotElementInDocumentTest, RecalcAssignedNodeStyleForReattach) {
}
TEST_F(HTMLSlotElementInDocumentTest, SlotableFallback) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<div id='host'></div>
)HTML");
@@ -182,8 +180,7 @@ TEST_F(HTMLSlotElementInDocumentTest, SlotableFallback) {
ShadowRoot& shadow_root =
host.AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString(
- R"HTML(<slot><span></span><!-- -->text</slot>)HTML");
+ shadow_root.setInnerHTML(R"HTML(<slot><span></span><!-- -->text</slot>)HTML");
auto* slot = To<HTMLSlotElement>(shadow_root.firstChild());
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 5131ef0b8ac..c65bd23aebe 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
@@ -73,9 +73,11 @@ void HTMLSourceElement::CreateMediaQueryList(const AtomicString& media) {
return;
}
- scoped_refptr<MediaQuerySet> set = MediaQuerySet::Create(media);
+ ExecutionContext* execution_context = GetExecutionContext();
+ scoped_refptr<MediaQuerySet> set =
+ MediaQuerySet::Create(media, execution_context);
media_query_list_ = MakeGarbageCollected<MediaQueryList>(
- &GetDocument(), &GetDocument().GetMediaQueryMatcher(), set);
+ execution_context, &GetDocument().GetMediaQueryMatcher(), set);
AddMediaQueryListListener();
}
@@ -88,7 +90,7 @@ Node::InsertionNotificationRequest HTMLSourceElement::InsertedInto(
ContainerNode& insertion_point) {
HTMLElement::InsertedInto(insertion_point);
Element* parent = parentElement();
- if (auto* media = ToHTMLMediaElementOrNull(parent))
+ if (auto* media = DynamicTo<HTMLMediaElement>(parent))
media->SourceWasAdded(this);
auto* html_picture_element = parent == insertion_point
@@ -105,7 +107,7 @@ void HTMLSourceElement::RemovedFrom(ContainerNode& removal_root) {
bool was_removed_from_parent = !parent;
if (was_removed_from_parent)
parent = DynamicTo<Element>(&removal_root);
- if (auto* media = ToHTMLMediaElementOrNull(parent))
+ if (auto* media = DynamicTo<HTMLMediaElement>(parent))
media->SourceWasRemoved(this);
if (auto* picture = DynamicTo<HTMLPictureElement>(parent)) {
RemoveMediaQueryListListener();
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 7810f7ab5f0..e49545b4d73 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
@@ -37,9 +37,7 @@ namespace blink {
HTMLStyleElement::HTMLStyleElement(Document& document,
const CreateElementFlags flags)
: HTMLElement(html_names::kStyleTag, document),
- StyleElement(&document, flags.IsCreatedByParser()),
- fired_load_(false),
- loaded_sheet_(false) {}
+ StyleElement(&document, flags.IsCreatedByParser()) {}
HTMLStyleElement::~HTMLStyleElement() = default;
@@ -49,7 +47,8 @@ void HTMLStyleElement::ParseAttribute(
sheet_->SetTitle(params.new_value);
} else if (params.name == html_names::kMediaAttr && isConnected() &&
GetDocument().IsActive() && sheet_) {
- sheet_->SetMediaQueries(MediaQuerySet::Create(params.new_value));
+ sheet_->SetMediaQueries(
+ MediaQuerySet::Create(params.new_value, GetExecutionContext()));
GetDocument().GetStyleEngine().MediaQueriesChangedInScope(GetTreeScope());
} else if (params.name == html_names::kTypeAttr) {
HTMLElement::ParseAttribute(params);
@@ -103,8 +102,9 @@ const AtomicString& HTMLStyleElement::type() const {
}
void HTMLStyleElement::DispatchPendingEvent(
- std::unique_ptr<IncrementLoadEventDelayCount> count) {
- if (loaded_sheet_) {
+ std::unique_ptr<IncrementLoadEventDelayCount> count,
+ bool is_load_event) {
+ if (is_load_event) {
if (GetDocument().HasListenerType(
Document::kLoadListenerAtCapturePhaseOrAtStyleElement))
DispatchEvent(*Event::Create(event_type_names::kLoad));
@@ -119,9 +119,6 @@ void HTMLStyleElement::DispatchPendingEvent(
void HTMLStyleElement::NotifyLoadedSheetAndAllCriticalSubresources(
LoadedSheetErrorStatus error_status) {
bool is_load_event = error_status == kNoErrorLoadingSubresource;
- if (fired_load_ && is_load_event)
- return;
- loaded_sheet_ = is_load_event;
// Per the spec this should post on the network task source.
// https://html.spec.whatwg.org/multipage/semantics.html#the-style-element
// This guarantees that the <style> will be applied before the next <script>
@@ -135,8 +132,8 @@ void HTMLStyleElement::NotifyLoadedSheetAndAllCriticalSubresources(
WTF::Bind(&HTMLStyleElement::DispatchPendingEvent,
WrapPersistent(this),
WTF::Passed(std::make_unique<IncrementLoadEventDelayCount>(
- GetDocument()))));
- fired_load_ = true;
+ GetDocument())),
+ is_load_event));
}
bool HTMLStyleElement::disabled() const {
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 ed768e1efea..e9c77140b26 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
@@ -49,7 +49,8 @@ class CORE_EXPORT HTMLStyleElement final : public HTMLElement,
private:
// Always call this asynchronously because this can cause synchronous
// Document load event and JavaScript execution.
- void DispatchPendingEvent(std::unique_ptr<IncrementLoadEventDelayCount>);
+ void DispatchPendingEvent(std::unique_ptr<IncrementLoadEventDelayCount>,
+ bool is_load_event);
// overload from HTMLElement
void ParseAttribute(const AttributeModificationParams&) override;
@@ -70,9 +71,6 @@ class CORE_EXPORT HTMLStyleElement final : public HTMLElement,
const AtomicString& media() const override;
const AtomicString& type() const override;
-
- bool fired_load_;
- bool loaded_sheet_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/html_summary_element.cc b/chromium/third_party/blink/renderer/core/html/html_summary_element.cc
index 4bfd172ef33..e10ff420f71 100644
--- a/chromium/third_party/blink/renderer/core/html/html_summary_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_summary_element.cc
@@ -84,14 +84,21 @@ bool HTMLSummaryElement::IsMainSummary() const {
return false;
}
-static bool IsClickableControl(Node* node) {
+bool HTMLSummaryElement::IsClickableControl(Node* node) {
auto* element = DynamicTo<Element>(node);
if (!element)
return false;
if (element->IsFormControlElement())
return true;
Element* host = element->OwnerShadowHost();
- return host && host->IsFormControlElement();
+ if (host && host->IsFormControlElement())
+ return true;
+ while (node && this != node) {
+ if (node->HasActivationBehavior())
+ return true;
+ node = node->ParentOrShadowHostNode();
+ }
+ return false;
}
bool HTMLSummaryElement::SupportsFocus() const {
@@ -112,15 +119,16 @@ void HTMLSummaryElement::DefaultEventHandler(Event& event) {
return;
}
- if (event.IsKeyboardEvent()) {
+ auto* keyboard_event = DynamicTo<KeyboardEvent>(event);
+ if (keyboard_event) {
if (event.type() == event_type_names::kKeydown &&
- ToKeyboardEvent(event).key() == " ") {
+ keyboard_event->key() == " ") {
SetActive(true);
// No setDefaultHandled() - IE dispatches a keypress in this case.
return;
}
if (event.type() == event_type_names::kKeypress) {
- switch (ToKeyboardEvent(event).charCode()) {
+ switch (keyboard_event->charCode()) {
case '\r':
DispatchSimulatedClick(&event);
event.SetDefaultHandled();
@@ -132,7 +140,7 @@ void HTMLSummaryElement::DefaultEventHandler(Event& event) {
}
}
if (event.type() == event_type_names::kKeyup &&
- ToKeyboardEvent(event).key() == " ") {
+ keyboard_event->key() == " ") {
if (IsActive())
DispatchSimulatedClick(&event);
event.SetDefaultHandled();
diff --git a/chromium/third_party/blink/renderer/core/html/html_summary_element.h b/chromium/third_party/blink/renderer/core/html/html_summary_element.h
index e5b5e5a6a7e..ca6c08fb475 100644
--- a/chromium/third_party/blink/renderer/core/html/html_summary_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_summary_element.h
@@ -46,6 +46,7 @@ class HTMLSummaryElement final : public HTMLElement {
bool SupportsFocus() const override;
int DefaultTabIndex() const override;
+ bool IsClickableControl(Node*);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/html_table_cell_element.h b/chromium/third_party/blink/renderer/core/html/html_table_cell_element.h
index 0208a918221..6382e301511 100644
--- a/chromium/third_party/blink/renderer/core/html/html_table_cell_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_table_cell_element.h
@@ -67,12 +67,21 @@ class CORE_EXPORT HTMLTableCellElement final : public HTMLTablePartElement {
const QualifiedName& SubResourceAttributeName() const override;
};
-inline bool IsHTMLTableCellElement(const HTMLElement& element) {
- return element.HasTagName(html_names::kTdTag) ||
- element.HasTagName(html_names::kThTag);
+template <>
+inline bool IsElementOfType<const HTMLTableCellElement>(const Node& node) {
+ return IsA<HTMLTableCellElement>(node);
}
-
-DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLTableCellElement);
+template <>
+struct DowncastTraits<HTMLTableCellElement> {
+ static bool AllowFrom(const Node& node) {
+ auto* html_element = DynamicTo<HTMLElement>(node);
+ return html_element && AllowFrom(*html_element);
+ }
+ static bool AllowFrom(const HTMLElement& html_element) {
+ return html_element.HasTagName(html_names::kTdTag) ||
+ html_element.HasTagName(html_names::kThTag);
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/html_table_col_element.cc b/chromium/third_party/blink/renderer/core/html/html_table_col_element.cc
index bab11e68028..4ccc1ed2c2f 100644
--- a/chromium/third_party/blink/renderer/core/html/html_table_col_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_table_col_element.cc
@@ -74,7 +74,7 @@ void HTMLTableColElement::ParseAttribute(
LayoutTableCol* col = ToLayoutTableCol(GetLayoutObject());
int new_width = Width().ToInt();
if (new_width != col->Size().Width()) {
- col->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ col->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kAttributeChanged);
}
}
diff --git a/chromium/third_party/blink/renderer/core/html/html_table_col_element.h b/chromium/third_party/blink/renderer/core/html/html_table_col_element.h
index e4816323409..fd73434e875 100644
--- a/chromium/third_party/blink/renderer/core/html/html_table_col_element.h
+++ b/chromium/third_party/blink/renderer/core/html/html_table_col_element.h
@@ -55,12 +55,22 @@ class CORE_EXPORT HTMLTableColElement final : public HTMLTablePartElement {
unsigned span_;
};
-inline bool IsHTMLTableColElement(const HTMLElement& element) {
- return element.HasTagName(html_names::kColTag) ||
- element.HasTagName(html_names::kColgroupTag);
+template <>
+inline bool IsElementOfType<const HTMLTableColElement>(const Node& node) {
+ return IsA<HTMLTableColElement>(node);
}
-
-DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLTableColElement);
+template <>
+struct DowncastTraits<HTMLTableColElement> {
+ static bool AllowFrom(const Node& node) {
+ auto* html_element = DynamicTo<HTMLElement>(node);
+ return html_element && AllowFrom(*html_element);
+ }
+ static bool AllowFrom(const HTMLElement& html_element) {
+ return html_element.HasTagName(html_names::kColTag) ||
+ html_element.HasTagName(html_names::kColgroupTag);
+ ;
+ }
+};
} // namespace blink
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 bec26e0c1db..21a123b5a2a 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
@@ -267,7 +267,7 @@ void HTMLTableElement::SetNeedsTableStyleRecalc() const {
element->SetNeedsStyleRecalc(
kLocalStyleChange,
StyleChangeReasonForTracing::FromAttribute(html_names::kRulesAttr));
- if (IsHTMLTableCellElement(*element))
+ if (IsA<HTMLTableCellElement>(*element))
element = ElementTraversal::NextSkippingChildren(*element, this);
else
element = ElementTraversal::Next(*element, this);
@@ -284,22 +284,22 @@ static bool GetBordersFromFrameAttributeValue(const AtomicString& value,
border_bottom = false;
border_left = false;
- if (DeprecatedEqualIgnoringCase(value, "above"))
+ if (EqualIgnoringASCIICase(value, "above"))
border_top = true;
- else if (DeprecatedEqualIgnoringCase(value, "below"))
+ else if (EqualIgnoringASCIICase(value, "below"))
border_bottom = true;
- else if (DeprecatedEqualIgnoringCase(value, "hsides"))
+ else if (EqualIgnoringASCIICase(value, "hsides"))
border_top = border_bottom = true;
- else if (DeprecatedEqualIgnoringCase(value, "vsides"))
+ else if (EqualIgnoringASCIICase(value, "vsides"))
border_left = border_right = true;
- else if (DeprecatedEqualIgnoringCase(value, "lhs"))
+ else if (EqualIgnoringASCIICase(value, "lhs"))
border_left = true;
- else if (DeprecatedEqualIgnoringCase(value, "rhs"))
+ else if (EqualIgnoringASCIICase(value, "rhs"))
border_right = true;
- else if (DeprecatedEqualIgnoringCase(value, "box") ||
- DeprecatedEqualIgnoringCase(value, "border"))
+ else if (EqualIgnoringASCIICase(value, "box") ||
+ EqualIgnoringASCIICase(value, "border"))
border_top = border_bottom = border_left = border_right = true;
- else if (!DeprecatedEqualIgnoringCase(value, "void"))
+ else if (!EqualIgnoringASCIICase(value, "void"))
return false;
return true;
}
@@ -327,11 +327,11 @@ void HTMLTableElement::CollectStyleForPresentationAttribute(
UseCounter::Count(
GetDocument(),
WebFeature::kHTMLTableElementPresentationAttributeBackground);
- CSSImageValue* image_value =
- CSSImageValue::Create(url, GetDocument().CompleteURL(url),
- Referrer(GetDocument().OutgoingReferrer(),
- GetDocument().GetReferrerPolicy()),
- OriginClean::kTrue);
+ CSSImageValue* image_value = MakeGarbageCollected<CSSImageValue>(
+ AtomicString(url), GetDocument().CompleteURL(url),
+ Referrer(GetDocument().OutgoingReferrer(),
+ GetDocument().GetReferrerPolicy()),
+ OriginClean::kTrue);
style->SetProperty(
CSSPropertyValue(GetCSSPropertyBackgroundImage(), *image_value));
}
@@ -347,7 +347,7 @@ void HTMLTableElement::CollectStyleForPresentationAttribute(
}
} else if (name == html_names::kAlignAttr) {
if (!value.IsEmpty()) {
- if (DeprecatedEqualIgnoringCase(value, "center")) {
+ if (EqualIgnoringASCIICase(value, "center")) {
AddPropertyToPresentationAttributeStyle(
style, CSSPropertyID::kMarginInlineStart, CSSValueID::kAuto);
AddPropertyToPresentationAttributeStyle(
@@ -425,15 +425,15 @@ void HTMLTableElement::ParseAttribute(
params.new_value, border_top, border_right, border_bottom, border_left);
} else if (name == html_names::kRulesAttr) {
rules_attr_ = kUnsetRules;
- if (DeprecatedEqualIgnoringCase(params.new_value, "none"))
+ if (EqualIgnoringASCIICase(params.new_value, "none"))
rules_attr_ = kNoneRules;
- else if (DeprecatedEqualIgnoringCase(params.new_value, "groups"))
+ else if (EqualIgnoringASCIICase(params.new_value, "groups"))
rules_attr_ = kGroupsRules;
- else if (DeprecatedEqualIgnoringCase(params.new_value, "rows"))
+ else if (EqualIgnoringASCIICase(params.new_value, "rows"))
rules_attr_ = kRowsRules;
- else if (DeprecatedEqualIgnoringCase(params.new_value, "cols"))
+ else if (EqualIgnoringASCIICase(params.new_value, "cols"))
rules_attr_ = kColsRules;
- else if (DeprecatedEqualIgnoringCase(params.new_value, "all"))
+ else if (EqualIgnoringASCIICase(params.new_value, "all"))
rules_attr_ = kAllRules;
} else if (params.name == html_names::kCellpaddingAttr) {
if (!params.new_value.IsEmpty()) {
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 8a6d3c15640..d3f59e00204 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
@@ -28,13 +28,13 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/html/html_element.h"
+#include "third_party/blink/renderer/core/html/html_table_rows_collection.h"
namespace blink {
class ExceptionState;
class HTMLCollection;
class HTMLTableCaptionElement;
-class HTMLTableRowsCollection;
class HTMLTableSectionElement;
class CORE_EXPORT HTMLTableElement final : public HTMLElement {
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 c9e312b3fe2..1d41ff2b6d4 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
@@ -60,25 +60,25 @@ void HTMLTablePartElement::CollectStyleForPresentationAttribute(
UseCounter::Count(
GetDocument(),
WebFeature::kHTMLTableElementPresentationAttributeBackground);
- CSSImageValue* image_value =
- CSSImageValue::Create(url, GetDocument().CompleteURL(url),
- Referrer(GetDocument().OutgoingReferrer(),
- GetDocument().GetReferrerPolicy()),
- OriginClean::kTrue);
+ CSSImageValue* image_value = MakeGarbageCollected<CSSImageValue>(
+ AtomicString(url), GetDocument().CompleteURL(url),
+ Referrer(GetDocument().OutgoingReferrer(),
+ GetDocument().GetReferrerPolicy()),
+ OriginClean::kTrue);
style->SetProperty(
CSSPropertyValue(GetCSSPropertyBackgroundImage(), *image_value));
}
} else if (name == html_names::kValignAttr) {
- if (DeprecatedEqualIgnoringCase(value, "top")) {
+ if (EqualIgnoringASCIICase(value, "top")) {
AddPropertyToPresentationAttributeStyle(
style, CSSPropertyID::kVerticalAlign, CSSValueID::kTop);
- } else if (DeprecatedEqualIgnoringCase(value, "middle")) {
+ } else if (EqualIgnoringASCIICase(value, "middle")) {
AddPropertyToPresentationAttributeStyle(
style, CSSPropertyID::kVerticalAlign, CSSValueID::kMiddle);
- } else if (DeprecatedEqualIgnoringCase(value, "bottom")) {
+ } else if (EqualIgnoringASCIICase(value, "bottom")) {
AddPropertyToPresentationAttributeStyle(
style, CSSPropertyID::kVerticalAlign, CSSValueID::kBottom);
- } else if (DeprecatedEqualIgnoringCase(value, "baseline")) {
+ } else if (EqualIgnoringASCIICase(value, "baseline")) {
AddPropertyToPresentationAttributeStyle(
style, CSSPropertyID::kVerticalAlign, CSSValueID::kBaseline);
} else {
@@ -86,17 +86,17 @@ void HTMLTablePartElement::CollectStyleForPresentationAttribute(
style, CSSPropertyID::kVerticalAlign, value);
}
} else if (name == html_names::kAlignAttr) {
- if (DeprecatedEqualIgnoringCase(value, "middle") ||
- DeprecatedEqualIgnoringCase(value, "center")) {
+ if (EqualIgnoringASCIICase(value, "middle") ||
+ EqualIgnoringASCIICase(value, "center")) {
AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kTextAlign,
CSSValueID::kWebkitCenter);
- } else if (DeprecatedEqualIgnoringCase(value, "absmiddle")) {
+ } else if (EqualIgnoringASCIICase(value, "absmiddle")) {
AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kTextAlign,
CSSValueID::kCenter);
- } else if (DeprecatedEqualIgnoringCase(value, "left")) {
+ } else if (EqualIgnoringASCIICase(value, "left")) {
AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kTextAlign,
CSSValueID::kWebkitLeft);
- } else if (DeprecatedEqualIgnoringCase(value, "right")) {
+ } else if (EqualIgnoringASCIICase(value, "right")) {
AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kTextAlign,
CSSValueID::kWebkitRight);
} else {
diff --git a/chromium/third_party/blink/renderer/core/html/html_table_rows_collection.h b/chromium/third_party/blink/renderer/core/html/html_table_rows_collection.h
index 4a03fcb7ea6..34334b46cc3 100644
--- a/chromium/third_party/blink/renderer/core/html/html_table_rows_collection.h
+++ b/chromium/third_party/blink/renderer/core/html/html_table_rows_collection.h
@@ -53,12 +53,6 @@ class HTMLTableRowsCollection final : public HTMLCollection {
Element* VirtualItemAfter(Element*) const override;
};
-DEFINE_TYPE_CASTS(HTMLTableRowsCollection,
- LiveNodeListBase,
- collection,
- collection->GetType() == kTableRows,
- collection.GetType() == kTableRows);
-
} // namespace blink
#endif
diff --git a/chromium/third_party/blink/renderer/core/html/html_tag_collection.cc b/chromium/third_party/blink/renderer/core/html/html_tag_collection.cc
index 7ad0c3589a5..ced90481987 100644
--- a/chromium/third_party/blink/renderer/core/html/html_tag_collection.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_tag_collection.cc
@@ -23,6 +23,7 @@
*/
#include "third_party/blink/renderer/core/html/html_tag_collection.h"
+#include "third_party/blink/renderer/core/html/html_document.h"
namespace blink {
@@ -30,7 +31,7 @@ HTMLTagCollection::HTMLTagCollection(ContainerNode& root_node,
const AtomicString& qualified_name)
: TagCollection(root_node, kHTMLTagCollectionType, qualified_name),
lowered_qualified_name_(qualified_name.LowerASCII()) {
- DCHECK(root_node.GetDocument().IsHTMLDocument());
+ DCHECK(IsA<HTMLDocument>(root_node.GetDocument()));
}
HTMLTagCollection::HTMLTagCollection(ContainerNode& root_node,
diff --git a/chromium/third_party/blink/renderer/core/html/html_tag_collection.h b/chromium/third_party/blink/renderer/core/html/html_tag_collection.h
index acdfe63c6c3..10f2b4effd7 100644
--- a/chromium/third_party/blink/renderer/core/html/html_tag_collection.h
+++ b/chromium/third_party/blink/renderer/core/html/html_tag_collection.h
@@ -27,6 +27,7 @@
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/tag_collection.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -46,11 +47,12 @@ class HTMLTagCollection final : public TagCollection {
AtomicString lowered_qualified_name_;
};
-DEFINE_TYPE_CASTS(HTMLTagCollection,
- LiveNodeListBase,
- collection,
- collection->GetType() == kHTMLTagCollectionType,
- collection.GetType() == kHTMLTagCollectionType);
+template <>
+struct DowncastTraits<HTMLTagCollection> {
+ static bool AllowFrom(const LiveNodeListBase& collection) {
+ return collection.GetType() == kHTMLTagCollectionType;
+ }
+};
inline bool HTMLTagCollection::ElementMatches(
const Element& test_element) const {
diff --git a/chromium/third_party/blink/renderer/core/html/html_tag_names.json5 b/chromium/third_party/blink/renderer/core/html/html_tag_names.json5
index 9150a6d5eb0..b85be229135 100644
--- a/chromium/third_party/blink/renderer/core/html/html_tag_names.json5
+++ b/chromium/third_party/blink/renderer/core/html/html_tag_names.json5
@@ -363,6 +363,9 @@
interfaceName: "HTMLPortalElement",
interfaceHeaderDir: "third_party/blink/renderer/core/html/portal",
runtimeEnabled: "Portals",
+ // Portals could be enabled in some documents but not others (due to
+ // origin trials), so we need custom type helpers.
+ noTypeHelpers: true,
},
"pre",
{
diff --git a/chromium/third_party/blink/renderer/core/html/html_ulist_element.cc b/chromium/third_party/blink/renderer/core/html/html_ulist_element.cc
index 2314fcd909b..bf0d71a2525 100644
--- a/chromium/third_party/blink/renderer/core/html/html_ulist_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_ulist_element.cc
@@ -43,16 +43,16 @@ void HTMLUListElement::CollectStyleForPresentationAttribute(
const AtomicString& value,
MutableCSSPropertyValueSet* style) {
if (name == html_names::kTypeAttr) {
- if (DeprecatedEqualIgnoringCase(value, "disc")) {
+ if (EqualIgnoringASCIICase(value, "disc")) {
AddPropertyToPresentationAttributeStyle(
style, CSSPropertyID::kListStyleType, CSSValueID::kDisc);
- } else if (DeprecatedEqualIgnoringCase(value, "circle")) {
+ } else if (EqualIgnoringASCIICase(value, "circle")) {
AddPropertyToPresentationAttributeStyle(
style, CSSPropertyID::kListStyleType, CSSValueID::kCircle);
- } else if (DeprecatedEqualIgnoringCase(value, "square")) {
+ } else if (EqualIgnoringASCIICase(value, "square")) {
AddPropertyToPresentationAttributeStyle(
style, CSSPropertyID::kListStyleType, CSSValueID::kSquare);
- } else if (DeprecatedEqualIgnoringCase(value, "none")) {
+ } else if (EqualIgnoringASCIICase(value, "none")) {
AddPropertyToPresentationAttributeStyle(
style, CSSPropertyID::kListStyleType, CSSValueID::kNone);
}
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 1cf2992d578..c737b7b2675 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
@@ -42,9 +42,9 @@
namespace blink {
-HTMLViewSourceDocument::HTMLViewSourceDocument(const DocumentInit& initializer,
- const String& mime_type)
- : HTMLDocument(initializer, kViewSourceDocumentClass), type_(mime_type) {
+HTMLViewSourceDocument::HTMLViewSourceDocument(const DocumentInit& initializer)
+ : HTMLDocument(initializer, kViewSourceDocumentClass),
+ type_(initializer.GetMimeType()) {
SetIsViewSource(true);
// FIXME: Why do view-source pages need to load in quirks mode?
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 5d79b2fa423..87bf8b54dc8 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
@@ -36,7 +36,7 @@ class HTMLToken;
class CORE_EXPORT HTMLViewSourceDocument final : public HTMLDocument {
public:
- HTMLViewSourceDocument(const DocumentInit&, const String& mime_type);
+ HTMLViewSourceDocument(const DocumentInit&);
void AddSource(const String&, HTMLToken&);
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 de80c76016a..3ae208645a9 100644
--- a/chromium/third_party/blink/renderer/core/html/image_document.cc
+++ b/chromium/third_party/blink/renderer/core/html/image_document.cc
@@ -31,6 +31,7 @@
#include "third_party/blink/renderer/core/dom/raw_data_document_parser.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/events/mouse_event.h"
+#include "third_party/blink/renderer/core/events/touch_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/local_frame_client.h"
@@ -95,12 +96,19 @@ class ImageDocumentParser : public RawDataDocumentParser {
: RawDataDocumentParser(document) {}
ImageDocument* GetDocument() const {
- return ToImageDocument(RawDataDocumentParser::GetDocument());
+ return To<ImageDocument>(RawDataDocumentParser::GetDocument());
+ }
+
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(image_resource_);
+ RawDataDocumentParser::Trace(visitor);
}
private:
void AppendBytes(const char*, size_t) override;
void Finish() override;
+
+ Member<ImageResource> image_resource_;
};
// --------
@@ -133,50 +141,49 @@ void ImageDocumentParser::AppendBytes(const char* data, size_t length) {
if (!allow_image)
return;
- if (GetDocument()->CachedImageResourceDeprecated()) {
- CHECK_LE(length, std::numeric_limits<unsigned>::max());
- // If decoding has already failed, there's no point in sending additional
- // data to the ImageResource.
- if (GetDocument()->CachedImageResourceDeprecated()->GetStatus() !=
- ResourceStatus::kDecodeError)
- GetDocument()->CachedImageResourceDeprecated()->AppendData(data, length);
+ if (!image_resource_) {
+ ResourceRequest request(GetDocument()->Url());
+ request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit);
+ image_resource_ = ImageResource::Create(request);
+ image_resource_->NotifyStartLoad();
+
+ GetDocument()->CreateDocumentStructure(image_resource_->GetContent());
+
+ if (IsStopped())
+ return;
+
+ if (DocumentLoader* loader = GetDocument()->Loader())
+ image_resource_->ResponseReceived(loader->GetResponse());
}
+ CHECK_LE(length, std::numeric_limits<unsigned>::max());
+ // If decoding has already failed, there's no point in sending additional
+ // data to the ImageResource.
+ if (image_resource_->GetStatus() != ResourceStatus::kDecodeError)
+ image_resource_->AppendData(data, length);
+
if (!IsDetached())
GetDocument()->ImageUpdated();
}
void ImageDocumentParser::Finish() {
- if (!IsStopped() && GetDocument()->ImageElement() &&
- GetDocument()->CachedImageResourceDeprecated()) {
+ if (!IsStopped() && image_resource_) {
// TODO(hiroshige): Use ImageResourceContent instead of ImageResource.
- ImageResource* cached_image =
- GetDocument()->CachedImageResourceDeprecated();
DocumentLoader* loader = GetDocument()->Loader();
- cached_image->SetResponse(loader->GetResponse());
- cached_image->Finish(
+ image_resource_->SetResponse(loader->GetResponse());
+ image_resource_->Finish(
loader->GetTiming().ResponseEnd(),
GetDocument()->GetTaskRunner(TaskType::kInternalLoading).get());
- // Report the natural image size in the page title, regardless of zoom
- // level. At a zoom level of 1 the image is guaranteed to have an integer
- // size.
- IntSize size = GetDocument()->ImageSize();
- if (size.Width()) {
- // Compute the title, we use the decoded filename of the resource, falling
- // back on the (decoded) hostname if there is no path.
- String file_name =
- DecodeURLEscapeSequences(GetDocument()->Url().LastPathComponent(),
- DecodeURLMode::kUTF8OrIsomorphic);
- if (file_name.IsEmpty())
- file_name = GetDocument()->Url().Host();
- GetDocument()->setTitle(ImageTitle(file_name, size));
+ if (GetDocument()->CachedImage()) {
+ GetDocument()->UpdateTitle();
+
if (IsDetached())
return;
- }
- GetDocument()->ImageUpdated();
- GetDocument()->ImageLoaded();
+ GetDocument()->ImageUpdated();
+ GetDocument()->ImageLoaded();
+ }
}
if (!IsDetached()) {
@@ -215,7 +222,8 @@ IntSize ImageDocument::ImageSize() const {
image_element_->GetLayoutObject()));
}
-void ImageDocument::CreateDocumentStructure() {
+void ImageDocument::CreateDocumentStructure(
+ ImageResourceContent* image_content) {
auto* root_element = MakeGarbageCollected<HTMLHtmlElement>(*this);
AppendChild(root_element);
root_element->InsertedByParser();
@@ -264,14 +272,8 @@ void ImageDocument::CreateDocumentStructure() {
image_element_ = MakeGarbageCollected<HTMLImageElement>(*this);
UpdateImageStyle();
- image_element_->SetLoadingImageDocument();
- image_element_->setAttribute(html_names::kSrcAttr,
- AtomicString(Url().GetString()));
+ image_element_->StartLoadingImageDocument(image_content);
body->AppendChild(image_element_.Get());
- if (Loader() && image_element_->CachedImageResourceForImageDocument()) {
- image_element_->CachedImageResourceForImageDocument()->ResponseReceived(
- Loader()->GetResponse());
- }
if (ShouldShrinkToFit()) {
// Add event listeners
@@ -292,6 +294,25 @@ void ImageDocument::CreateDocumentStructure() {
root_element->AppendChild(head);
root_element->AppendChild(body);
+
+ if (IsStopped())
+ image_element_ = nullptr;
+}
+
+void ImageDocument::UpdateTitle() {
+ // Report the natural image size in the page title, regardless of zoom
+ // level. At a zoom level of 1 the image is guaranteed to have an integer
+ // size.
+ IntSize size = ImageSize();
+ if (!size.Width())
+ return;
+ // Compute the title, we use the decoded filename of the resource, falling
+ // back on the (decoded) hostname if there is no path.
+ String file_name = DecodeURLEscapeSequences(Url().LastPathComponent(),
+ DecodeURLMode::kUTF8OrIsomorphic);
+ if (file_name.IsEmpty())
+ file_name = Url().Host();
+ setTitle(ImageTitle(file_name, size));
}
float ImageDocument::Scale() const {
@@ -349,7 +370,7 @@ void ImageDocument::ImageClicked(int x, int y) {
RestoreImageSize();
- UpdateStyleAndLayout();
+ UpdateStyleAndLayout(DocumentUpdateReason::kInput);
double scale = Scale();
double device_scale_factor =
@@ -362,7 +383,8 @@ void ImageDocument::ImageClicked(int x, int y) {
static_cast<float>(GetFrame()->View()->Height()) / 2;
GetFrame()->View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(scroll_x, scroll_y), kProgrammaticScroll);
+ ScrollOffset(scroll_x, scroll_y),
+ mojom::blink::ScrollType::kProgrammatic);
}
}
@@ -526,29 +548,11 @@ void ImageDocument::WindowSizeChanged() {
}
ImageResourceContent* ImageDocument::CachedImage() {
- if (!image_element_) {
- CreateDocumentStructure();
- if (IsStopped()) {
- image_element_ = nullptr;
- return nullptr;
- }
- }
-
+ if (!image_element_)
+ return nullptr;
return image_element_->CachedImage();
}
-ImageResource* ImageDocument::CachedImageResourceDeprecated() {
- if (!image_element_) {
- CreateDocumentStructure();
- if (IsStopped()) {
- image_element_ = nullptr;
- return nullptr;
- }
- }
-
- return image_element_->CachedImageResourceForImageDocument();
-}
-
bool ImageDocument::ShouldShrinkToFit() const {
// WebView automatically resizes to match the contents, causing an infinite
// loop as the contents then resize to match the window. To prevent this,
@@ -567,15 +571,14 @@ void ImageDocument::Trace(Visitor* visitor) {
// --------
void ImageEventListener::Invoke(ExecutionContext*, Event* event) {
+ auto* mouse_event = DynamicTo<MouseEvent>(event);
if (event->type() == event_type_names::kResize) {
doc_->WindowSizeChanged();
- } else if (event->type() == event_type_names::kClick &&
- event->IsMouseEvent()) {
- MouseEvent* mouse_event = ToMouseEvent(event);
+ } else if (event->type() == event_type_names::kClick && mouse_event) {
doc_->ImageClicked(mouse_event->x(), mouse_event->y());
} else if ((event->type() == event_type_names::kTouchend ||
event->type() == event_type_names::kTouchcancel) &&
- event->IsTouchEvent()) {
+ IsA<TouchEvent>(event)) {
doc_->UpdateImageStyle();
}
}
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 b129cf34494..a9aa1335792 100644
--- a/chromium/third_party/blink/renderer/core/html/image_document.h
+++ b/chromium/third_party/blink/renderer/core/html/image_document.h
@@ -25,14 +25,14 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_IMAGE_DOCUMENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_IMAGE_DOCUMENT_H_
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/renderer/core/html/html_div_element.h"
#include "third_party/blink/renderer/core/html/html_document.h"
-#include "third_party/blink/renderer/core/html/html_image_element.h"
namespace blink {
-class ImageResource;
+class HTMLDivElement;
+class HTMLImageElement;
+class ImageResourceContent;
+class IntSize;
class CORE_EXPORT ImageDocument final : public HTMLDocument {
public:
@@ -40,17 +40,16 @@ class CORE_EXPORT ImageDocument final : public HTMLDocument {
ImageResourceContent* CachedImage();
- // TODO(hiroshige): Remove this.
- ImageResource* CachedImageResourceDeprecated();
-
HTMLImageElement* ImageElement() const { return image_element_.Get(); }
IntSize ImageSize() const;
+ void CreateDocumentStructure(ImageResourceContent*);
void WindowSizeChanged();
void ImageUpdated();
void ImageClicked(int x, int y);
void ImageLoaded();
void UpdateImageStyle();
+ void UpdateTitle();
bool ShouldShrinkToFit() const;
void Trace(Visitor*) override;
@@ -58,8 +57,6 @@ class CORE_EXPORT ImageDocument final : public HTMLDocument {
private:
DocumentParser* CreateParser() override;
- void CreateDocumentStructure();
-
// Calculates how large the div needs to be to properly center the image.
int CalculateDivWidth();
@@ -97,7 +94,12 @@ class CORE_EXPORT ImageDocument final : public HTMLDocument {
FRIEND_TEST_ALL_PREFIXES(ImageDocumentViewportTest, DivWidthWithZoomForDSF);
};
-DEFINE_DOCUMENT_TYPE_CASTS(ImageDocument);
+template <>
+struct DowncastTraits<ImageDocument> {
+ static bool AllowFrom(const Document& document) {
+ return document.IsImageDocument();
+ }
+};
} // namespace blink
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 87128050642..5b4d48d44cb 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
@@ -13,6 +13,7 @@
#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/geometry/dom_rect.h"
+#include "third_party/blink/renderer/core/html/html_image_element.h"
#include "third_party/blink/renderer/core/loader/empty_clients.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
@@ -82,6 +83,7 @@ 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;
@@ -103,14 +105,17 @@ void ImageDocumentTest::CreateDocumentWithoutLoadingImage(int view_width,
FillWithEmptyClients(page_clients);
chrome_client_ = MakeGarbageCollected<WindowToViewportScalingChromeClient>();
page_clients.chrome_client = chrome_client_;
+ dummy_page_holder_ = nullptr;
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());
- frame.DomWindow()->InstallNewDocument("image/jpeg", init, false);
+ DocumentInit init =
+ DocumentInit::Create()
+ .WithDocumentLoader(frame.Loader().GetDocumentLoader())
+ .WithTypeFrom("image/jpeg");
+ frame.DomWindow()->InstallNewDocument(init, false);
frame.GetDocument()->SetURL(KURL("http://www.example.com/image.jpg"));
}
@@ -125,11 +130,16 @@ ImageDocument& ImageDocumentTest::GetDocument() const {
return *image_document;
}
-void ImageDocumentTest::LoadImage() {
+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();
}
@@ -222,6 +232,13 @@ TEST_F(ImageDocumentTest, DomInteractive) {
EXPECT_FALSE(GetDocument().GetTiming().DomInteractive().is_null());
}
+TEST_F(ImageDocumentTest, ImageSrcChangedBeforeFinish) {
+ CreateDocumentWithoutLoadingImage(80, 70);
+ DocumentParser* parser = StartLoadingImage();
+ GetDocument().ImageElement()->removeAttribute(html_names::kSrcAttr);
+ parser->Finish();
+}
+
#if defined(OS_ANDROID)
#define MAYBE(test) DISABLED_##test
#else
@@ -237,13 +254,8 @@ TEST_F(ImageDocumentTest, MAYBE(ImageCenteredAtDeviceScaleFactor)) {
GetDocument().ImageClicked(15, 27);
ScrollOffset offset =
GetDocument().GetFrame()->View()->LayoutViewport()->GetScrollOffset();
- if (RuntimeEnabledFeatures::FractionalScrollOffsetsEnabled()) {
- EXPECT_EQ(22.5f, offset.Width());
- EXPECT_EQ(42, offset.Height());
- } else {
- EXPECT_EQ(22, offset.Width());
- EXPECT_EQ(42, offset.Height());
- }
+ EXPECT_EQ(20, offset.Width());
+ EXPECT_EQ(20, offset.Height());
GetDocument().ImageClicked(20, 20);
@@ -252,10 +264,10 @@ TEST_F(ImageDocumentTest, MAYBE(ImageCenteredAtDeviceScaleFactor)) {
GetDocument().GetFrame()->View()->LayoutViewport()->GetScrollOffset();
if (RuntimeEnabledFeatures::FractionalScrollOffsetsEnabled()) {
EXPECT_EQ(11.25f, offset.Width());
- EXPECT_EQ(22.5f, offset.Height());
+ EXPECT_EQ(20, offset.Height());
} else {
EXPECT_EQ(11, offset.Width());
- EXPECT_EQ(22, offset.Height());
+ EXPECT_EQ(20, offset.Height());
}
}
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 7ebf6531892..301cb4a5ee8 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
@@ -108,7 +108,7 @@ Document* HTMLImportChild::GetDocument() const {
}
void HTMLImportChild::StateWillChange() {
- ToHTMLImportTreeRoot(Root())->ScheduleRecalcState();
+ To<HTMLImportTreeRoot>(Root())->ScheduleRecalcState();
}
void HTMLImportChild::StateDidChange() {
diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_import_state_resolver.h b/chromium/third_party/blink/renderer/core/html/imports/html_import_state_resolver.h
index 9ce231ed2cc..6935193bcc0 100644
--- a/chromium/third_party/blink/renderer/core/html/imports/html_import_state_resolver.h
+++ b/chromium/third_party/blink/renderer/core/html/imports/html_import_state_resolver.h
@@ -52,7 +52,7 @@ class HTMLImportStateResolver final {
bool ShouldBlockScriptExecution() const;
bool IsActive() const;
- Member<HTMLImport> import_;
+ HTMLImport* import_;
};
} // namespace blink
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 a97a05e2789..5bfb3fe17c2 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
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/html/imports/html_import.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/timer.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -48,11 +49,10 @@ class HTMLImportTreeRoot final : public HTMLImport, public NameClient {
ImportList imports_;
};
-DEFINE_TYPE_CASTS(HTMLImportTreeRoot,
- HTMLImport,
- import,
- import->IsRoot(),
- import.IsRoot());
+template <>
+struct DowncastTraits<HTMLImportTreeRoot> {
+ static bool AllowFrom(const HTMLImport& import) { return import.IsRoot(); }
+};
} // namespace blink
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 8a3ea3e4e23..89f0c961e2a 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
@@ -30,7 +30,6 @@
#include "third_party/blink/renderer/core/html/imports/html_imports_controller.h"
-#include "third_party/blink/public/common/features.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/html/imports/html_import_child.h"
@@ -121,9 +120,7 @@ HTMLImportChild* HTMLImportsController::Load(const Document& parent_document,
Master()->GetSecurityOrigin();
ResourceFetcher* fetcher = parent->GetDocument()->Fetcher();
- if (base::FeatureList::IsEnabled(
- features::kHtmlImportsRequestInitiatorLock) &&
- parent->GetDocument()->ImportsController()) {
+ if (parent->GetDocument()->ImportsController()) {
Document* context_document = parent->GetDocument()->ContextDocument();
if (!context_document)
return nullptr;
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 73df690828c..01ca5ecdf25 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
@@ -81,7 +81,7 @@ void LinkImport::Process() {
ResourceLoaderOptions options;
options.initiator_info.name = owner_->localName();
- FetchParameters params(resource_request, options);
+ FetchParameters params(std::move(resource_request), options);
params.SetCharset(GetCharset());
params.SetContentSecurityPolicyNonce(owner_->nonce());
diff --git a/chromium/third_party/blink/renderer/core/html/keywords.json5 b/chromium/third_party/blink/renderer/core/html/keywords.json5
index 5a5635bdf44..411fc0bb7da 100644
--- a/chromium/third_party/blink/renderer/core/html/keywords.json5
+++ b/chromium/third_party/blink/renderer/core/html/keywords.json5
@@ -6,6 +6,7 @@
metadata: {
namespace: "keywords",
export: "CORE_EXPORT",
+ allowDuplicates: true,
},
data: [
@@ -48,7 +49,7 @@
// https://wicg.github.io/priority-hints/#solution-0
"high",
"low",
- // "auto",
+ "auto",
// inputmode attribute
// https://html.spec.whatwg.org/C/#attr-inputmode
@@ -59,7 +60,7 @@
"email",
"numeric",
"decimal",
- // "search",
+ "search",
// invisible attribute
// https://github.com/rakina/searchable-invisible-dom
@@ -70,7 +71,7 @@
// https://github.com/scott-little/lazyload#ways-the-loading-attribute-can-be-used
"lazy",
"eager",
- // "auto",
+ "auto",
// referrerpolicy attribute
// https://w3c.github.io/webappsec-referrer-policy/#referrer-policies
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 17a280cf27e..24d34305f41 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
@@ -93,11 +93,12 @@ int GetLazyFrameLoadingViewportDistanceThresholdPx(const Document& document) {
} // namespace
struct LazyLoadFrameObserver::LazyLoadRequestInfo {
- LazyLoadRequestInfo(const ResourceRequest& resource_request,
+ LazyLoadRequestInfo(const ResourceRequestHead& passed_resource_request,
WebFrameLoadType frame_load_type)
- : resource_request(resource_request), frame_load_type(frame_load_type) {}
+ : resource_request(passed_resource_request),
+ frame_load_type(frame_load_type) {}
- const ResourceRequest resource_request;
+ ResourceRequestHead resource_request;
const WebFrameLoadType frame_load_type;
};
@@ -107,7 +108,7 @@ LazyLoadFrameObserver::LazyLoadFrameObserver(HTMLFrameOwnerElement& element)
LazyLoadFrameObserver::~LazyLoadFrameObserver() = default;
void LazyLoadFrameObserver::DeferLoadUntilNearViewport(
- const ResourceRequest& resource_request,
+ const ResourceRequestHead& resource_request,
WebFrameLoadType frame_load_type) {
DCHECK(!lazy_load_intersection_observer_);
DCHECK(!lazy_load_request_info_);
@@ -179,11 +180,11 @@ void LazyLoadFrameObserver::LoadImmediately() {
// Note that calling FrameLoader::StartNavigation() causes the
// |lazy_load_intersection_observer_| to be disconnected.
+ FrameLoadRequest request(&element_->GetDocument(),
+ scoped_request_info->resource_request);
To<LocalFrame>(element_->ContentFrame())
->Loader()
- .StartNavigation(FrameLoadRequest(&element_->GetDocument(),
- scoped_request_info->resource_request),
- scoped_request_info->frame_load_type);
+ .StartNavigation(request, scoped_request_info->frame_load_type);
DCHECK(!IsLazyLoadPending());
}
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 eec517758a1..d79cf667b74 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
@@ -17,7 +17,7 @@ namespace blink {
class IntersectionObserver;
class IntersectionObserverEntry;
class HTMLFrameOwnerElement;
-class ResourceRequest;
+class ResourceRequestHead;
class Visitor;
class LazyLoadFrameObserver final
@@ -44,7 +44,7 @@ class LazyLoadFrameObserver final
explicit LazyLoadFrameObserver(HTMLFrameOwnerElement&);
~LazyLoadFrameObserver();
- void DeferLoadUntilNearViewport(const ResourceRequest&, WebFrameLoadType);
+ void DeferLoadUntilNearViewport(const ResourceRequestHead&, WebFrameLoadType);
bool IsLazyLoadPending() const { return lazy_load_intersection_observer_; }
void CancelPendingLazyLoad();
diff --git a/chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer_test.cc b/chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer_test.cc
index b48d92a8e2f..f73980f6d1f 100644
--- a/chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer_test.cc
@@ -383,8 +383,8 @@ TEST_P(LazyLoadFramesParamsTest, BelowTheFoldButNearViewportFrame) {
ExpectVisibleLoadTimeHistogramSamplesIfApplicable(0, 0);
// Scroll down until the child frame is visible.
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 150),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 150), mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
@@ -493,7 +493,7 @@ TEST_P(LazyLoadFramesParamsTest, HiddenAndTinyFrames) {
// Scroll down to where the hidden frames are.
GetDocument().View()->LayoutViewport()->SetScrollOffset(
ScrollOffset(0, kViewportHeight + GetLoadingDistanceThreshold()),
- kProgrammaticScroll);
+ mojom::blink::ScrollType::kProgrammatic);
// All of the frames on the page are hidden or tiny, so no visible load time
// samples should have been recorded for them.
@@ -517,7 +517,7 @@ TEST_P(LazyLoadFramesParamsTest, LoadCrossOriginFrameFarFromViewport) {
// If LazyFrameLoading is enabled, then scroll down near the child frame to
// cause the child frame to start loading.
GetDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, 150), kProgrammaticScroll);
+ ScrollOffset(0, 150), mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
@@ -544,7 +544,7 @@ TEST_P(LazyLoadFramesParamsTest, LoadCrossOriginFrameFarFromViewport) {
// Scroll down so that the child frame is visible.
GetDocument().View()->LayoutViewport()->SetScrollOffset(
ScrollOffset(0, GetLoadingDistanceThreshold() + 150),
- kProgrammaticScroll);
+ mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
@@ -570,7 +570,7 @@ TEST_P(LazyLoadFramesParamsTest,
// Scroll down so that the child frame is visible.
GetDocument().View()->LayoutViewport()->SetScrollOffset(
ScrollOffset(0, GetLoadingDistanceThreshold() + 150),
- kProgrammaticScroll);
+ mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
@@ -622,7 +622,7 @@ TEST_P(LazyLoadFramesParamsTest, NestedFrameInCrossOriginFrameFarFromViewport) {
// If LazyFrameLoading is enabled, then scroll down near the child frame to
// cause the child frame to start loading.
GetDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, 150), kProgrammaticScroll);
+ ScrollOffset(0, 150), mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
@@ -847,7 +847,7 @@ TEST_P(LazyLoadFramesParamsTest,
// If LazyFrameLoading is enabled, then scroll down near the child frame to
// cause the child frame to start loading.
GetDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, 150), kProgrammaticScroll);
+ ScrollOffset(0, 150), mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
@@ -874,7 +874,7 @@ TEST_P(LazyLoadFramesParamsTest,
// Scroll down so that the child frame is visible.
GetDocument().View()->LayoutViewport()->SetScrollOffset(
ScrollOffset(0, GetLoadingDistanceThreshold() + 150),
- kProgrammaticScroll);
+ mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
@@ -974,7 +974,7 @@ TEST_P(LazyLoadFramesParamsTest,
// If LazyFrameLoading is enabled, then scroll down near the child frame to
// cause the child frame to start loading.
GetDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, 150), kProgrammaticScroll);
+ ScrollOffset(0, 150), mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
@@ -1214,7 +1214,7 @@ class LazyLoadFramesTest : public SimTest {
// Scroll down near the child frame to cause the child frame to start
// loading.
GetDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, 150), kProgrammaticScroll);
+ ScrollOffset(0, 150), mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
@@ -1255,7 +1255,7 @@ class LazyLoadFramesTest : public SimTest {
EXPECT_FALSE(ConsoleMessages().Contains("child frame element onload"));
GetDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, 150), kProgrammaticScroll);
+ ScrollOffset(0, 150), mojom::blink::ScrollType::kProgrammatic);
SimRequest child_frame_resource("https://crossorigin.com/subframe.html",
"text/html");
@@ -1269,7 +1269,7 @@ class LazyLoadFramesTest : public SimTest {
GetDocument().View()->LayoutViewport()->SetScrollOffset(
ScrollOffset(0, LazyLoadFramesTest::kViewportHeight +
LazyLoadFramesTest::kLoadingDistanceThresholdPx),
- kProgrammaticScroll);
+ mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
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 c87047f581a..32c4a33e9d4 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
@@ -23,6 +23,7 @@
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer.h"
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.h"
#include "third_party/blink/renderer/core/style/computed_style.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/network_state_notifier.h"
@@ -188,7 +189,7 @@ void LazyLoadImageObserver::StartMonitoringNearViewport(
if (deferral_message == DeferralMessage::kLoadEventsDeferred &&
!is_load_event_deferred_intervention_shown_) {
is_load_event_deferred_intervention_shown_ = true;
- root_document->AddConsoleMessage(ConsoleMessage::Create(
+ root_document->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kIntervention,
mojom::ConsoleMessageLevel::kInfo,
"Images loaded lazily and replaced with placeholders. Load events are "
@@ -197,7 +198,7 @@ void LazyLoadImageObserver::StartMonitoringNearViewport(
if (deferral_message == DeferralMessage::kMissingDimensionForLazy &&
!is_missing_dimension_intervention_shown_) {
is_missing_dimension_intervention_shown_ = true;
- root_document->AddConsoleMessage(ConsoleMessage::Create(
+ root_document->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kIntervention,
mojom::ConsoleMessageLevel::kInfo,
"An <img> element was lazyloaded with loading=lazy, but had no "
diff --git a/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc b/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc
index 28ae790ac1b..55a3944ebcb 100644
--- a/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc
@@ -139,7 +139,7 @@ class LazyLoadImagesSimTest : public ::testing::WithParamInterface<bool>,
if (is_lazyload_image_enabled) {
// Scroll down until the background image is visible.
GetDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, 10000), kProgrammaticScroll);
+ ScrollOffset(0, 10000), mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
image_resource.Complete(ReadTestImage());
@@ -183,7 +183,7 @@ class LazyLoadImagesSimTest : public ::testing::WithParamInterface<bool>,
if (is_lazyload_image_enabled) {
// Scroll down until the image element is visible.
GetDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, 10000), kProgrammaticScroll);
+ ScrollOffset(0, 10000), mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
image_resource.Complete(ReadTestImage());
@@ -238,7 +238,7 @@ TEST_P(LazyLoadImagesSimTest, CSSBackgroundImage) {
if (is_lazyload_image_enabled) {
// Scroll down until the background image is visible.
GetDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, 10000), kProgrammaticScroll);
+ ScrollOffset(0, 10000), mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
image_resource.Complete(ReadTestImage());
@@ -544,6 +544,7 @@ TEST_P(LazyLoadImagesParamsTest, NearViewport) {
kViewportHeight + GetLoadingDistanceThreshold() - 100));
css_resource.Complete("img { width: 50px; height: 50px; }");
+ test::RunPendingTasks();
Vector<char> full_image = ReadTestImage();
ASSERT_LT(2048U, full_image.size());
@@ -677,6 +678,7 @@ TEST_P(LazyLoadImagesParamsTest, FarFromViewport) {
kViewportHeight + GetLoadingDistanceThreshold() + 100));
css_resource.Complete("img { width: 50px; height: 50px; }");
+ test::RunPendingTasks();
Compositor().BeginFrame();
test::RunPendingTasks();
@@ -757,7 +759,7 @@ TEST_P(LazyLoadImagesParamsTest, FarFromViewport) {
if (RuntimeEnabledFeatures::LazyImageLoadingEnabled()) {
// Scroll down so that the images are near the viewport.
GetDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, 150), kProgrammaticScroll);
+ ScrollOffset(0, 150), mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
@@ -919,7 +921,7 @@ class LazyLoadAutomaticImagesTest : public SimTest {
// Scrolling down should trigger the fetch of the image.
GetDocument().View()->LayoutViewport()->SetScrollOffset(
ScrollOffset(0, kLoadingDistanceThreshold + kViewportHeight),
- kProgrammaticScroll);
+ mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
full_resource.Complete(ReadTestImage());
@@ -1150,7 +1152,7 @@ TEST_F(LazyLoadAutomaticImagesTest, FirstKImagesLoaded) {
// Scrolling down should trigger the fetch of the second image.
GetDocument().View()->LayoutViewport()->SetScrollOffset(
ScrollOffset(0, kLoadingDistanceThreshold + kViewportHeight),
- kProgrammaticScroll);
+ mojom::blink::ScrollType::kProgrammatic);
SimSubresourceRequest img2("https://example.com/image.png?id=2", "image/png");
Compositor().BeginFrame();
@@ -1268,8 +1270,8 @@ TEST_F(LazyLoadAutomaticImagesTest, ImageInsideLazyLoadedFrame) {
// Scroll down so that the iframe is near the viewport, but the images within
// it aren't near the viewport yet.
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 150),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 150), mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
@@ -1356,8 +1358,8 @@ TEST_F(LazyLoadAutomaticImagesTest, ImageInsideLazyLoadedFrame) {
"image/png");
// Scroll down so that all the images in the iframe are near the viewport.
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 250),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 250), mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
@@ -1413,7 +1415,7 @@ TEST_F(LazyLoadAutomaticImagesTest, LazyLoadDisabledOnReload) {
GetDocument().View()->LayoutViewport()->SetScrollOffset(
ScrollOffset(0, LazyLoadAutomaticImagesTest::kLoadingDistanceThreshold +
LazyLoadAutomaticImagesTest::kViewportHeight),
- kProgrammaticScroll);
+ mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
auto_image.Complete(ReadTestImage());
@@ -1439,11 +1441,12 @@ TEST_F(LazyLoadAutomaticImagesTest, LazyLoadDisabledOnReload) {
GetDocument().View()->LayoutViewport()->SetScrollOffset(
ScrollOffset(0, LazyLoadAutomaticImagesTest::kLoadingDistanceThreshold +
LazyLoadAutomaticImagesTest::kViewportHeight),
- kProgrammaticScroll);
+ mojom::blink::ScrollType::kProgrammatic);
SimSubresourceRequest lazy_image("https://example.com/image_lazy.png",
"image/png");
Compositor().BeginFrame();
test::RunPendingTasks();
+ Compositor().BeginFrame();
lazy_image.Complete(ReadTestImage());
test::RunPendingTasks();
histogram_tester.ExpectTotalCount(
@@ -1557,8 +1560,8 @@ TEST_F(LazyLoadAutomaticImagesTest, BelowTheFoldImageLoadedBeforeVisible) {
// Scroll down such that the image is within kLoadingDistanceThreshold of the
// viewport, but isn't visible yet.
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 200),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 200), mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
@@ -1576,7 +1579,7 @@ TEST_F(LazyLoadAutomaticImagesTest, BelowTheFoldImageLoadedBeforeVisible) {
// Scroll down such that the image is visible.
GetDocument().View()->LayoutViewport()->SetScrollOffset(
ScrollOffset(0, kViewportHeight + kLoadingDistanceThreshold),
- kProgrammaticScroll);
+ mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
@@ -1615,7 +1618,7 @@ TEST_F(LazyLoadAutomaticImagesTest, BelowTheFoldImageVisibleBeforeLoaded) {
// Scroll down such that the image is visible.
GetDocument().View()->LayoutViewport()->SetScrollOffset(
ScrollOffset(0, kViewportHeight + kLoadingDistanceThreshold),
- kProgrammaticScroll);
+ mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
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 f7fc3615a7c..c4d5fddf615 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
@@ -36,7 +36,7 @@
namespace blink {
LinkRelAttribute::LinkRelAttribute()
- : icon_type_(kInvalidIcon),
+ : icon_type_(mojom::blink::FaviconIconType::kInvalid),
is_style_sheet_(false),
is_alternate_(false),
is_dns_prefetch_(false),
@@ -49,7 +49,8 @@ LinkRelAttribute::LinkRelAttribute()
is_manifest_(false),
is_module_preload_(false),
is_service_worker_(false),
- is_canonical_(false) {}
+ is_canonical_(false),
+ is_monetization_(false) {}
LinkRelAttribute::LinkRelAttribute(const String& rel) : LinkRelAttribute() {
if (rel.IsEmpty())
@@ -59,46 +60,48 @@ LinkRelAttribute::LinkRelAttribute(const String& rel) : LinkRelAttribute() {
Vector<String> list;
rel_copy.Split(' ', list);
for (const String& link_type : list) {
- if (DeprecatedEqualIgnoringCase(link_type, "stylesheet")) {
+ if (EqualIgnoringASCIICase(link_type, "stylesheet")) {
if (!is_import_)
is_style_sheet_ = true;
- } else if (DeprecatedEqualIgnoringCase(link_type, "import")) {
+ } else if (EqualIgnoringASCIICase(link_type, "import")) {
if (!is_style_sheet_)
is_import_ = true;
- } else if (DeprecatedEqualIgnoringCase(link_type, "alternate")) {
+ } else if (EqualIgnoringASCIICase(link_type, "alternate")) {
is_alternate_ = true;
- } else if (DeprecatedEqualIgnoringCase(link_type, "icon")) {
+ } else if (EqualIgnoringASCIICase(link_type, "icon")) {
// This also allows "shortcut icon" since we just ignore the non-standard
// "shortcut" token.
// FIXME: This doesn't really follow the spec that requires "shortcut
// icon" to be the entire string
// http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#rel-icon
- icon_type_ = kFavicon;
- } else if (DeprecatedEqualIgnoringCase(link_type, "prefetch")) {
+ icon_type_ = mojom::blink::FaviconIconType::kFavicon;
+ } else if (EqualIgnoringASCIICase(link_type, "prefetch")) {
is_link_prefetch_ = true;
- } else if (DeprecatedEqualIgnoringCase(link_type, "dns-prefetch")) {
+ } else if (EqualIgnoringASCIICase(link_type, "dns-prefetch")) {
is_dns_prefetch_ = true;
- } else if (DeprecatedEqualIgnoringCase(link_type, "preconnect")) {
+ } else if (EqualIgnoringASCIICase(link_type, "preconnect")) {
is_preconnect_ = true;
- } else if (DeprecatedEqualIgnoringCase(link_type, "preload")) {
+ } else if (EqualIgnoringASCIICase(link_type, "preload")) {
is_link_preload_ = true;
- } else if (DeprecatedEqualIgnoringCase(link_type, "prerender")) {
+ } else if (EqualIgnoringASCIICase(link_type, "prerender")) {
is_link_prerender_ = true;
- } else if (DeprecatedEqualIgnoringCase(link_type, "next")) {
+ } else if (EqualIgnoringASCIICase(link_type, "next")) {
is_link_next_ = true;
- } else if (DeprecatedEqualIgnoringCase(link_type, "apple-touch-icon")) {
- icon_type_ = kTouchIcon;
- } else if (DeprecatedEqualIgnoringCase(link_type,
- "apple-touch-icon-precomposed")) {
- icon_type_ = kTouchPrecomposedIcon;
- } else if (DeprecatedEqualIgnoringCase(link_type, "manifest")) {
+ } else if (EqualIgnoringASCIICase(link_type, "apple-touch-icon")) {
+ icon_type_ = mojom::blink::FaviconIconType::kTouchIcon;
+ } else if (EqualIgnoringASCIICase(link_type,
+ "apple-touch-icon-precomposed")) {
+ icon_type_ = mojom::blink::FaviconIconType::kTouchPrecomposedIcon;
+ } else if (EqualIgnoringASCIICase(link_type, "manifest")) {
is_manifest_ = true;
- } else if (DeprecatedEqualIgnoringCase(link_type, "modulepreload")) {
+ } else if (EqualIgnoringASCIICase(link_type, "modulepreload")) {
is_module_preload_ = true;
- } else if (DeprecatedEqualIgnoringCase(link_type, "serviceworker")) {
+ } else if (EqualIgnoringASCIICase(link_type, "serviceworker")) {
is_service_worker_ = true;
- } else if (DeprecatedEqualIgnoringCase(link_type, "canonical")) {
+ } else if (EqualIgnoringASCIICase(link_type, "canonical")) {
is_canonical_ = true;
+ } else if (EqualIgnoringASCIICase(link_type, "monetization")) {
+ is_monetization_ = 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 709dceacc25..309cbcb0078 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
@@ -47,7 +47,7 @@ class CORE_EXPORT LinkRelAttribute {
explicit LinkRelAttribute(const String&);
bool IsStyleSheet() const { return is_style_sheet_; }
- IconType GetIconType() const { return icon_type_; }
+ mojom::blink::FaviconIconType GetIconType() const { return icon_type_; }
bool IsAlternate() const { return is_alternate_; }
bool IsDNSPrefetch() const { return is_dns_prefetch_; }
bool IsPreconnect() const { return is_preconnect_; }
@@ -60,9 +60,10 @@ class CORE_EXPORT LinkRelAttribute {
bool IsModulePreload() const { return is_module_preload_; }
bool IsServiceWorker() const { return is_service_worker_; }
bool IsCanonical() const { return is_canonical_; }
+ bool IsMonetization() const { return is_monetization_; }
private:
- IconType icon_type_;
+ mojom::blink::FaviconIconType icon_type_;
bool is_style_sheet_ : 1;
bool is_alternate_ : 1;
bool is_dns_prefetch_ : 1;
@@ -76,6 +77,7 @@ class CORE_EXPORT LinkRelAttribute {
bool is_module_preload_ : 1;
bool is_service_worker_ : 1;
bool is_canonical_ : 1;
+ bool is_monetization_ : 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 acb04e6a58d..c4a142ff0fa 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
@@ -37,7 +37,7 @@ namespace blink {
// TODO(dcheng): This is a bit gross. Refactor this to not take so many bools...
static inline void TestLinkRelAttribute(const String& value,
bool is_style_sheet,
- IconType icon_type,
+ mojom::blink::FaviconIconType icon_type,
bool is_alternate,
bool is_dns_prefetch,
bool is_link_prerender,
@@ -57,58 +57,89 @@ static inline void TestLinkRelAttribute(const String& value,
}
TEST(LinkRelAttributeTest, Constructor) {
- TestLinkRelAttribute("stylesheet", true, kInvalidIcon, false, false, false);
- TestLinkRelAttribute("sTyLeShEeT", true, kInvalidIcon, false, false, false);
+ TestLinkRelAttribute("stylesheet", true,
+ mojom::blink::FaviconIconType::kInvalid, false, false,
+ false);
+ TestLinkRelAttribute("sTyLeShEeT", true,
+ mojom::blink::FaviconIconType::kInvalid, false, false,
+ false);
- TestLinkRelAttribute("icon", false, kFavicon, false, false, false);
- TestLinkRelAttribute("iCoN", false, kFavicon, false, false, false);
- TestLinkRelAttribute("shortcut icon", false, kFavicon, false, false, false);
- TestLinkRelAttribute("sHoRtCuT iCoN", false, kFavicon, false, false, false);
+ TestLinkRelAttribute("icon", false, mojom::blink::FaviconIconType::kFavicon,
+ false, false, false);
+ TestLinkRelAttribute("iCoN", false, mojom::blink::FaviconIconType::kFavicon,
+ false, false, false);
+ TestLinkRelAttribute("shortcut icon", false,
+ mojom::blink::FaviconIconType::kFavicon, false, false,
+ false);
+ TestLinkRelAttribute("sHoRtCuT iCoN", false,
+ mojom::blink::FaviconIconType::kFavicon, false, false,
+ false);
- TestLinkRelAttribute("dns-prefetch", false, kInvalidIcon, false, true, false);
- TestLinkRelAttribute("dNs-pReFeTcH", false, kInvalidIcon, false, true, false);
- TestLinkRelAttribute("alternate dNs-pReFeTcH", false, kInvalidIcon, true,
- true, false);
+ TestLinkRelAttribute("dns-prefetch", false,
+ mojom::blink::FaviconIconType::kInvalid, false, true,
+ false);
+ TestLinkRelAttribute("dNs-pReFeTcH", false,
+ mojom::blink::FaviconIconType::kInvalid, false, true,
+ false);
+ TestLinkRelAttribute("alternate dNs-pReFeTcH", false,
+ mojom::blink::FaviconIconType::kInvalid, true, true,
+ false);
- TestLinkRelAttribute("apple-touch-icon", false, kTouchIcon, false, false,
+ TestLinkRelAttribute("apple-touch-icon", false,
+ mojom::blink::FaviconIconType::kTouchIcon, false, false,
false);
- TestLinkRelAttribute("aPpLe-tOuCh-IcOn", false, kTouchIcon, false, false,
+ TestLinkRelAttribute("aPpLe-tOuCh-IcOn", false,
+ mojom::blink::FaviconIconType::kTouchIcon, false, false,
false);
TestLinkRelAttribute("apple-touch-icon-precomposed", false,
- kTouchPrecomposedIcon, false, false, false);
+ mojom::blink::FaviconIconType::kTouchPrecomposedIcon,
+ false, false, false);
TestLinkRelAttribute("aPpLe-tOuCh-IcOn-pReCoMpOsEd", false,
- kTouchPrecomposedIcon, false, false, false);
+ mojom::blink::FaviconIconType::kTouchPrecomposedIcon,
+ false, false, false);
- TestLinkRelAttribute("alternate stylesheet", true, kInvalidIcon, true, false,
+ TestLinkRelAttribute("alternate stylesheet", true,
+ mojom::blink::FaviconIconType::kInvalid, true, false,
false);
- TestLinkRelAttribute("stylesheet alternate", true, kInvalidIcon, true, false,
+ TestLinkRelAttribute("stylesheet alternate", true,
+ mojom::blink::FaviconIconType::kInvalid, true, false,
false);
- TestLinkRelAttribute("aLtErNaTe sTyLeShEeT", true, kInvalidIcon, true, false,
+ TestLinkRelAttribute("aLtErNaTe sTyLeShEeT", true,
+ mojom::blink::FaviconIconType::kInvalid, true, false,
false);
- TestLinkRelAttribute("sTyLeShEeT aLtErNaTe", true, kInvalidIcon, true, false,
+ TestLinkRelAttribute("sTyLeShEeT aLtErNaTe", true,
+ mojom::blink::FaviconIconType::kInvalid, true, false,
false);
- TestLinkRelAttribute("stylesheet icon prerender aLtErNaTe", true, kFavicon,
- true, false, true);
- TestLinkRelAttribute("alternate icon stylesheet", true, kFavicon, true, false,
+ TestLinkRelAttribute("stylesheet icon prerender aLtErNaTe", true,
+ mojom::blink::FaviconIconType::kFavicon, true, false,
+ true);
+ TestLinkRelAttribute("alternate icon stylesheet", true,
+ mojom::blink::FaviconIconType::kFavicon, true, false,
false);
- TestLinkRelAttribute("import", false, kInvalidIcon, false, false, false,
- true);
- TestLinkRelAttribute("alternate import", false, kInvalidIcon, true, false,
+ TestLinkRelAttribute("import", false, mojom::blink::FaviconIconType::kInvalid,
+ false, false, false, true);
+ TestLinkRelAttribute("alternate import", false,
+ mojom::blink::FaviconIconType::kInvalid, true, false,
false, true);
- TestLinkRelAttribute("stylesheet import", true, kInvalidIcon, false, false,
+ TestLinkRelAttribute("stylesheet import", true,
+ mojom::blink::FaviconIconType::kInvalid, false, false,
false, false);
- TestLinkRelAttribute("preconnect", false, kInvalidIcon, false, false, false,
- false, true);
- TestLinkRelAttribute("pReCoNnEcT", false, kInvalidIcon, false, false, false,
- false, true);
-
- TestLinkRelAttribute("canonical", false, kInvalidIcon, false, false, false,
+ TestLinkRelAttribute("preconnect", false,
+ mojom::blink::FaviconIconType::kInvalid, false, false,
false, false, true);
- TestLinkRelAttribute("caNONiCAL", false, kInvalidIcon, false, false, false,
+ TestLinkRelAttribute("pReCoNnEcT", false,
+ mojom::blink::FaviconIconType::kInvalid, false, false,
false, false, true);
+
+ TestLinkRelAttribute("canonical", false,
+ mojom::blink::FaviconIconType::kInvalid, false, false,
+ false, false, false, true);
+ TestLinkRelAttribute("caNONiCAL", false,
+ mojom::blink::FaviconIconType::kInvalid, 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 ae57f6f82c0..c3b07b6bdaa 100644
--- a/chromium/third_party/blink/renderer/core/html/link_resource.cc
+++ b/chromium/third_party/blink/renderer/core/html/link_resource.cc
@@ -65,6 +65,10 @@ WTF::TextEncoding LinkResource::GetCharset() const {
return WTF::TextEncoding(charset);
}
+ExecutionContext* LinkResource::GetExecutionContext() {
+ return owner_->GetExecutionContext();
+}
+
void LinkResource::Trace(Visitor* visitor) {
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 912368cbf52..c149a9dbee6 100644
--- a/chromium/third_party/blink/renderer/core/html/link_resource.h
+++ b/chromium/third_party/blink/renderer/core/html/link_resource.h
@@ -39,6 +39,7 @@
namespace blink {
class Document;
+class ExecutionContext;
class HTMLLinkElement;
class LocalFrame;
@@ -66,6 +67,7 @@ class CORE_EXPORT LinkResource : public GarbageCollected<LinkResource> {
Document& GetDocument();
const Document& GetDocument() const;
WTF::TextEncoding GetCharset() const;
+ ExecutionContext* GetExecutionContext();
Member<HTMLLinkElement> owner_;
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 3e4c5c71e5f..7e88349611c 100644
--- a/chromium/third_party/blink/renderer/core/html/link_style.cc
+++ b/chromium/third_party/blink/renderer/core/html/link_style.cc
@@ -18,7 +18,6 @@
#include "third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.h"
#include "third_party/blink/renderer/core/loader/subresource_integrity_helper.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/loader/fetch/fetch_parameters.h"
#include "third_party/blink/renderer/platform/loader/subresource_integrity.h"
#include "third_party/blink/renderer/platform/network/mime/content_type.h"
@@ -75,7 +74,7 @@ void LinkStyle::NotifyFinished(Resource* resource) {
cached_style_sheet->IntegrityDisposition();
SubresourceIntegrityHelper::DoReport(
- GetDocument(), cached_style_sheet->IntegrityReportInfo());
+ *GetExecutionContext(), cached_style_sheet->IntegrityReportInfo());
if (disposition == ResourceIntegrityDisposition::kFailed) {
loading_ = false;
@@ -96,7 +95,8 @@ void LinkStyle::NotifyFinished(Resource* resource) {
if (sheet_)
ClearSheet();
sheet_ = MakeGarbageCollected<CSSStyleSheet>(parsed_sheet, *owner_);
- sheet_->SetMediaQueries(MediaQuerySet::Create(owner_->Media()));
+ sheet_->SetMediaQueries(
+ MediaQuerySet::Create(owner_->Media(), GetExecutionContext()));
if (owner_->IsInDocumentTree())
SetSheetTitle(owner_->title());
@@ -113,7 +113,8 @@ void LinkStyle::NotifyFinished(Resource* resource) {
ClearSheet();
sheet_ = MakeGarbageCollected<CSSStyleSheet>(style_sheet, *owner_);
- sheet_->SetMediaQueries(MediaQuerySet::Create(owner_->Media()));
+ sheet_->SetMediaQueries(
+ MediaQuerySet::Create(owner_->Media(), GetExecutionContext()));
if (owner_->IsInDocumentTree())
SetSheetTitle(owner_->title());
@@ -262,7 +263,8 @@ LinkStyle::LoadReturnValue LinkStyle::LoadStylesheetIfNeeded(
bool media_query_matches = true;
LocalFrame* frame = LoadingFrame();
if (!owner_->Media().IsEmpty() && frame) {
- scoped_refptr<MediaQuerySet> media = MediaQuerySet::Create(owner_->Media());
+ scoped_refptr<MediaQuerySet> media =
+ MediaQuerySet::Create(owner_->Media(), GetExecutionContext());
MediaQueryEvaluator evaluator(frame);
media_query_matches = evaluator.Eval(*media);
}
@@ -311,7 +313,8 @@ void LinkStyle::Process() {
WTF::TextEncoding charset = GetCharset();
- if (owner_->RelAttribute().GetIconType() != kInvalidIcon &&
+ if (owner_->RelAttribute().GetIconType() !=
+ mojom::blink::FaviconIconType::kInvalid &&
params.href.IsValid() && !params.href.IsEmpty()) {
if (!owner_->ShouldLoadLink())
return;
@@ -320,10 +323,8 @@ void LinkStyle::Process() {
if (!GetDocument().GetContentSecurityPolicy()->AllowImageFromSource(
params.href))
return;
- if (GetDocument().GetFrame() && GetDocument().GetFrame()->Client()) {
- GetDocument().GetFrame()->Client()->DispatchDidChangeIcons(
- owner_->RelAttribute().GetIconType());
- }
+ if (GetDocument().GetFrame())
+ GetDocument().GetFrame()->UpdateFaviconURL();
}
if (!sheet_ && !owner_->LoadLink(params))
diff --git a/chromium/third_party/blink/renderer/core/html/list_item_ordinal.cc b/chromium/third_party/blink/renderer/core/html/list_item_ordinal.cc
index 6c386828599..2a1d3069e25 100644
--- a/chromium/third_party/blink/renderer/core/html/list_item_ordinal.cc
+++ b/chromium/third_party/blink/renderer/core/html/list_item_ordinal.cc
@@ -35,8 +35,7 @@
namespace blink {
-ListItemOrdinal::ListItemOrdinal()
- : type_(kNeedsUpdate), not_in_list_(false), not_in_list_changed_(false) {}
+ListItemOrdinal::ListItemOrdinal() : type_(kNeedsUpdate) {}
bool ListItemOrdinal::IsList(const Node& node) {
return IsA<HTMLUListElement>(node) || IsA<HTMLOListElement>(node);
@@ -242,21 +241,6 @@ void ListItemOrdinal::ClearExplicitValue(const Node& item_node) {
InvalidateAfter(EnclosingList(&item_node), &item_node);
}
-void ListItemOrdinal::SetNotInList(bool not_in_list, const Node& item_node) {
- if (not_in_list_ == not_in_list)
- return;
-
- not_in_list_ = not_in_list;
- SetNotInListChanged(true);
- LayoutObject* layout_object = item_node.GetLayoutObject();
- if (layout_object->IsLayoutNGListItem())
- layout_object->NotifyOfSubtreeChange();
-}
-
-void ListItemOrdinal::SetNotInListChanged(bool changed) {
- not_in_list_changed_ = changed;
-}
-
unsigned ListItemOrdinal::ItemCountForOrderedList(
const HTMLOListElement* list_node) {
DCHECK(list_node);
diff --git a/chromium/third_party/blink/renderer/core/html/list_item_ordinal.h b/chromium/third_party/blink/renderer/core/html/list_item_ordinal.h
index c830556f3bd..957cf5a1fec 100644
--- a/chromium/third_party/blink/renderer/core/html/list_item_ordinal.h
+++ b/chromium/third_party/blink/renderer/core/html/list_item_ordinal.h
@@ -61,12 +61,6 @@ class CORE_EXPORT ListItemOrdinal {
void SetExplicitValue(int, const Node&);
void ClearExplicitValue(const Node&);
- // Get/set whether this item is in a list or not.
- bool NotInList() const { return not_in_list_; }
- void SetNotInList(bool, const Node&);
- bool NotInListChanged() const { return not_in_list_changed_; }
- void SetNotInListChanged(bool);
-
static bool IsList(const Node&);
static bool IsListItem(const Node&);
static bool IsListItem(const LayoutObject*);
@@ -113,8 +107,6 @@ class CORE_EXPORT ListItemOrdinal {
mutable int value_ = 0;
mutable unsigned type_ : 2; // ValueType
- unsigned not_in_list_ : 1;
- unsigned not_in_list_changed_ : 1;
};
} // 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 ad5f2bf0692..9e03caf66bb 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
@@ -20,6 +20,7 @@
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer.h"
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.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/network/network_state_notifier.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
@@ -88,12 +89,12 @@ bool AutoplayPolicy::IsDocumentAllowedToPlay(const Document& document) {
return false;
bool feature_policy_enabled =
- document.IsFeatureEnabled(mojom::FeaturePolicyFeature::kAutoplay);
+ document.IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kAutoplay);
for (Frame* frame = document.GetFrame(); frame;
frame = frame->Tree().Parent()) {
- if (frame->HasBeenActivated() ||
- frame->HasReceivedUserGestureBeforeNavigation()) {
+ if (frame->HasStickyUserActivation() ||
+ frame->HadStickyUserActivationBeforeNavigation()) {
return true;
}
@@ -218,9 +219,10 @@ bool AutoplayPolicy::RequestAutoplayUnmute() {
if (was_autoplaying_muted) {
if (IsGestureNeededForPlayback()) {
if (IsUsingDocumentUserActivationRequiredPolicy()) {
- element_->GetDocument().AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning, kWarningUnmuteFailed));
+ element_->GetDocument().AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning, kWarningUnmuteFailed));
}
autoplay_uma_helper_->RecordAutoplayUnmuteStatus(
@@ -361,12 +363,12 @@ void AutoplayPolicy::MaybeSetAutoplayInitiated() {
const Document& document = element_->GetDocument();
bool feature_policy_enabled =
- document.IsFeatureEnabled(mojom::FeaturePolicyFeature::kAutoplay);
+ document.IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kAutoplay);
for (Frame* frame = document.GetFrame(); frame;
frame = frame->Tree().Parent()) {
- if (frame->HasBeenActivated() ||
- frame->HasReceivedUserGestureBeforeNavigation()) {
+ if (frame->HasStickyUserActivation() ||
+ frame->HadStickyUserActivationBeforeNavigation()) {
autoplay_initiated_ = false;
break;
}
@@ -376,7 +378,8 @@ void AutoplayPolicy::MaybeSetAutoplayInitiated() {
}
bool AutoplayPolicy::ShouldAutoplay() {
- if (element_->GetDocument().IsSandboxed(WebSandboxFlags::kAutomaticFeatures))
+ if (element_->GetDocument().IsSandboxed(
+ mojom::blink::WebSandboxFlags::kAutomaticFeatures))
return false;
return element_->can_autoplay_ && element_->paused_ && element_->Autoplay();
}
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 a9a2f85e771..44d1e8e0e39 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
@@ -4,9 +4,9 @@
#include "third_party/blink/renderer/core/html/media/autoplay_uma_helper.h"
+#include "base/metrics/histogram_functions.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
-#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -39,9 +39,9 @@ int64_t GetUserGestureStatusForUkmMetric(LocalFrame* frame) {
if (LocalFrame::HasTransientUserActivation(frame))
result |= 0x01;
- if (frame->HasBeenActivated())
+ if (frame->HasStickyUserActivation())
result |= 0x02;
- if (frame->HasReceivedUserGestureBeforeNavigation())
+ if (frame->HadStickyUserActivationBeforeNavigation())
result |= 0x04;
return result;
@@ -50,25 +50,27 @@ int64_t GetUserGestureStatusForUkmMetric(LocalFrame* frame) {
} // namespace
AutoplayUmaHelper::AutoplayUmaHelper(HTMLMediaElement* element)
- : ContextLifecycleObserver(nullptr),
+ : ExecutionContextLifecycleObserver(
+ static_cast<ExecutionContext*>(nullptr)),
element_(element),
muted_video_play_method_intersection_observer_(nullptr),
is_visible_(false),
- muted_video_offscreen_duration_intersection_observer_(nullptr) {
-}
+ muted_video_offscreen_duration_intersection_observer_(nullptr) {}
AutoplayUmaHelper::~AutoplayUmaHelper() = default;
+static void RecordAutoplaySourceMetrics(HTMLMediaElement* element,
+ AutoplaySource source) {
+ if (IsA<HTMLVideoElement>(element)) {
+ base::UmaHistogramEnumeration("Media.Video.Autoplay", source);
+ if (element->muted())
+ base::UmaHistogramEnumeration("Media.Video.Autoplay.Muted", source);
+ return;
+ }
+ base::UmaHistogramEnumeration("Media.Audio.Autoplay", source);
+}
+
void AutoplayUmaHelper::OnAutoplayInitiated(AutoplaySource source) {
- DEFINE_STATIC_LOCAL(EnumerationHistogram, video_histogram,
- ("Media.Video.Autoplay",
- static_cast<int>(AutoplaySource::kNumberOfUmaSources)));
- DEFINE_STATIC_LOCAL(EnumerationHistogram, muted_video_histogram,
- ("Media.Video.Autoplay.Muted",
- static_cast<int>(AutoplaySource::kNumberOfUmaSources)));
- DEFINE_STATIC_LOCAL(EnumerationHistogram, audio_histogram,
- ("Media.Audio.Autoplay",
- static_cast<int>(AutoplaySource::kNumberOfUmaSources)));
// Autoplay already initiated
if (sources_.Contains(source))
@@ -77,26 +79,11 @@ void AutoplayUmaHelper::OnAutoplayInitiated(AutoplaySource source) {
sources_.insert(source);
// Record the source.
- if (IsA<HTMLVideoElement>(element_.Get())) {
- video_histogram.Count(static_cast<int>(source));
- if (element_->muted())
- muted_video_histogram.Count(static_cast<int>(source));
- } else {
- audio_histogram.Count(static_cast<int>(source));
- }
+ RecordAutoplaySourceMetrics(element_.Get(), source);
// Record dual source.
- if (sources_.size() ==
- static_cast<size_t>(AutoplaySource::kNumberOfSources)) {
- if (IsA<HTMLVideoElement>(element_.Get())) {
- video_histogram.Count(static_cast<int>(AutoplaySource::kDualSource));
- if (element_->muted())
- muted_video_histogram.Count(
- static_cast<int>(AutoplaySource::kDualSource));
- } else {
- audio_histogram.Count(static_cast<int>(AutoplaySource::kDualSource));
- }
- }
+ if (sources_.size() == kDualSourceSize)
+ RecordAutoplaySourceMetrics(element_.Get(), AutoplaySource::kDualSource);
element_->addEventListener(event_type_names::kPlaying, this, false);
@@ -124,18 +111,13 @@ void AutoplayUmaHelper::OnAutoplayInitiated(AutoplaySource source) {
void AutoplayUmaHelper::RecordAutoplayUnmuteStatus(
AutoplayUnmuteActionStatus status) {
- DEFINE_STATIC_LOCAL(
- EnumerationHistogram, autoplay_unmute_histogram,
- ("Media.Video.Autoplay.Muted.UnmuteAction",
- static_cast<int>(AutoplayUnmuteActionStatus::kNumberOfStatus)));
-
- autoplay_unmute_histogram.Count(static_cast<int>(status));
+ base::UmaHistogramEnumeration("Media.Video.Autoplay.Muted.UnmuteAction",
+ status);
// Record UKM event for unmute muted autoplay.
if (element_->GetDocument().IsInMainFrame()) {
int source = static_cast<int>(AutoplaySource::kAttribute);
- if (sources_.size() ==
- static_cast<size_t>(AutoplaySource::kNumberOfSources)) {
+ if (sources_.size() == kDualSourceSize) {
source = static_cast<int>(AutoplaySource::kDualSource);
} else if (sources_.Contains(AutoplaySource::kMethod)) {
source = static_cast<int>(AutoplaySource::kAttribute);
@@ -162,7 +144,7 @@ void AutoplayUmaHelper::DidMoveToNewDocument(Document& old_document) {
if (!ShouldListenToContextDestroyed())
return;
- SetContext(&element_->GetDocument());
+ SetExecutionContext(element_->GetExecutionContext());
}
void AutoplayUmaHelper::
@@ -212,7 +194,7 @@ void AutoplayUmaHelper::HandlePauseEvent() {
MaybeStopRecordingMutedVideoOffscreenDuration();
}
-void AutoplayUmaHelper::ContextDestroyed(ExecutionContext*) {
+void AutoplayUmaHelper::ContextDestroyed() {
HandleContextDestroyed();
}
@@ -233,7 +215,7 @@ void AutoplayUmaHelper::MaybeStartRecordingMutedVideoPlayMethodBecomeVisible() {
OnIntersectionChangedForMutedVideoPlayMethodBecomeVisible,
WrapWeakPersistent(this)));
muted_video_play_method_intersection_observer_->observe(element_);
- SetContext(&element_->GetDocument());
+ SetExecutionContext(element_->GetExecutionContext());
}
void AutoplayUmaHelper::MaybeStopRecordingMutedVideoPlayMethodBecomeVisible(
@@ -241,10 +223,9 @@ void AutoplayUmaHelper::MaybeStopRecordingMutedVideoPlayMethodBecomeVisible(
if (!muted_video_play_method_intersection_observer_)
return;
- DEFINE_STATIC_LOCAL(BooleanHistogram, histogram,
- ("Media.Video.Autoplay.Muted.PlayMethod.BecomesVisible"));
+ base::UmaHistogramBoolean(
+ "Media.Video.Autoplay.Muted.PlayMethod.BecomesVisible", visible);
- histogram.Count(visible);
muted_video_play_method_intersection_observer_->disconnect();
muted_video_play_method_intersection_observer_ = nullptr;
MaybeUnregisterContextDestroyedObserver();
@@ -268,7 +249,7 @@ void AutoplayUmaHelper::MaybeStartRecordingMutedVideoOffscreenDuration() {
WrapWeakPersistent(this)));
muted_video_offscreen_duration_intersection_observer_->observe(element_);
element_->addEventListener(event_type_names::kPause, this, false);
- SetContext(&element_->GetDocument());
+ SetExecutionContext(element_->GetExecutionContext());
}
void AutoplayUmaHelper::MaybeStopRecordingMutedVideoOffscreenDuration() {
@@ -296,8 +277,12 @@ void AutoplayUmaHelper::MaybeStopRecordingMutedVideoOffscreenDuration() {
}
void AutoplayUmaHelper::MaybeUnregisterContextDestroyedObserver() {
- if (!ShouldListenToContextDestroyed()) {
- SetContext(nullptr);
+ // TODO(keishi): Remove IsIteratingOverObservers() check when
+ // HeapObserverList() supports removal while iterating.
+ if (!ShouldListenToContextDestroyed() && !GetExecutionContext()
+ ->ContextLifecycleObserverList()
+ .IsIteratingOverObservers()) {
+ SetExecutionContext(nullptr);
}
}
@@ -314,7 +299,7 @@ bool AutoplayUmaHelper::ShouldListenToContextDestroyed() const {
void AutoplayUmaHelper::Trace(Visitor* visitor) {
NativeEventListener::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
visitor->Trace(element_);
visitor->Trace(muted_video_play_method_intersection_observer_);
visitor->Trace(muted_video_offscreen_duration_intersection_observer_);
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 a7a7412f39f..80c709bc43b 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
@@ -8,7 +8,7 @@
#include "third_party/blink/public/platform/web_media_player_client.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
@@ -19,28 +19,16 @@ enum class AutoplaySource {
kAttribute = 0,
// Autoplay comes from `play()` method.
kMethod = 1,
- // Used for checking dual source.
- kNumberOfSources = 2,
// Both sources are used.
kDualSource = 2,
- // This enum value must be last.
- kNumberOfUmaSources = 3,
+ kMaxValue = kDualSource,
};
// These values are used for histograms. Do not reorder.
enum class AutoplayUnmuteActionStatus {
kFailure = 0,
kSuccess = 1,
- kNumberOfStatus = 2,
-};
-
-// These values are used for histograms. Do not reorder.
-enum AutoplayBlockedReason {
- kAutoplayBlockedReasonDataSaver_DEPRECATED = 0,
- kAutoplayBlockedReasonSetting = 1,
- kAutoplayBlockedReasonDataSaverAndSetting_DEPRECATED = 2,
- // Keey at the end.
- kAutoplayBlockedReasonMax = 3
+ kMaxValue = kSuccess,
};
class Document;
@@ -49,14 +37,14 @@ class IntersectionObserver;
class IntersectionObserverEntry;
class CORE_EXPORT AutoplayUmaHelper : public NativeEventListener,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(AutoplayUmaHelper);
public:
explicit AutoplayUmaHelper(HTMLMediaElement*);
~AutoplayUmaHelper() override;
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
void OnAutoplayInitiated(AutoplaySource);
@@ -102,6 +90,11 @@ class CORE_EXPORT AutoplayUmaHelper : public NativeEventListener,
// The autoplay sources.
HashSet<AutoplaySource> sources_;
+ // |sources_| can be either contain 0, 1, or 2 distinct values. When
+ // |sources_.size() == 2|, that indicates there are dual sources responsible
+ // for autoplay.
+ static constexpr size_t kDualSourceSize = 2;
+
// The media element this UMA helper is attached to. |element| owns |this|.
Member<HTMLMediaElement> element_;
diff --git a/chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper_test.cc b/chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper_test.cc
index 1d9043a98c3..df3c7ef20bc 100644
--- a/chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper_test.cc
@@ -47,8 +47,8 @@ class AutoplayUmaHelperTest : public PageTestBase {
private:
void SetUp() override {
PageTestBase::SetUp();
- GetDocument().documentElement()->SetInnerHTMLFromString(
- "<video id=video></video>", ASSERT_NO_EXCEPTION);
+ GetDocument().documentElement()->setInnerHTML("<video id=video></video>",
+ ASSERT_NO_EXCEPTION);
HTMLMediaElement& element = MediaElement();
uma_helper_ = MakeGarbageCollected<MockAutoplayUmaHelper>(&element);
element.autoplay_policy_->autoplay_uma_helper_ = uma_helper_;
diff --git a/chromium/third_party/blink/renderer/core/html/media/html_audio_element.h b/chromium/third_party/blink/renderer/core/html/media/html_audio_element.h
index 89d7af81537..68d7a1ad013 100644
--- a/chromium/third_party/blink/renderer/core/html/media/html_audio_element.h
+++ b/chromium/third_party/blink/renderer/core/html/media/html_audio_element.h
@@ -51,7 +51,6 @@ class CORE_EXPORT HTMLAudioElement final : public HTMLMediaElement {
const WebString& remote_device_friendly_name) override {}
void MediaRemotingStopped(int error_code) override {}
void OnPictureInPictureStateChange() final { NOTREACHED(); }
- void ActivateViewportIntersectionMonitoring(bool) final {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/media/html_audio_element.idl b/chromium/third_party/blink/renderer/core/html/media/html_audio_element.idl
index 698f97b673a..3c84dc9d143 100644
--- a/chromium/third_party/blink/renderer/core/html/media/html_audio_element.idl
+++ b/chromium/third_party/blink/renderer/core/html/media/html_audio_element.idl
@@ -26,9 +26,10 @@
// https://html.spec.whatwg.org/C/#the-audio-element
[
+ ConstructorCallWith=Document,
Exposed=Window,
HTMLConstructor,
NamedConstructor=Audio(optional DOMString src),
- ConstructorCallWith=Document
+ NamedConstructor_CallWith=Document
] interface HTMLAudioElement : HTMLMediaElement {
};
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 bb8e7d76e23..f14430417bc 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
@@ -33,6 +33,7 @@
#include "base/debug/crash_logging.h"
#include "base/feature_list.h"
#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_functions.h"
#include "base/time/time.h"
#include "media/base/logging_override_if_enabled.h"
#include "media/base/media_switches.h"
@@ -69,10 +70,10 @@
#include "third_party/blink/renderer/core/html/html_source_element.h"
#include "third_party/blink/renderer/core/html/media/autoplay_policy.h"
#include "third_party/blink/renderer/core/html/media/html_media_element_controls_list.h"
-#include "third_party/blink/renderer/core/html/media/html_media_source.h"
#include "third_party/blink/renderer/core/html/media/media_controls.h"
#include "third_party/blink/renderer/core/html/media/media_error.h"
#include "third_party/blink/renderer/core/html/media/media_fragment_uri_parser.h"
+#include "third_party/blink/renderer/core/html/media/media_source.h"
#include "third_party/blink/renderer/core/html/time_ranges.h"
#include "third_party/blink/renderer/core/html/track/audio_track.h"
#include "third_party/blink/renderer/core/html/track/audio_track_list.h"
@@ -80,6 +81,7 @@
#include "third_party/blink/renderer/core/html/track/cue_timeline.h"
#include "third_party/blink/renderer/core/html/track/html_track_element.h"
#include "third_party/blink/renderer/core/html/track/inband_text_track.h"
+#include "third_party/blink/renderer/core/html/track/loadable_text_track.h"
#include "third_party/blink/renderer/core/html/track/text_track_container.h"
#include "third_party/blink/renderer/core/html/track/text_track_list.h"
#include "third_party/blink/renderer/core/html/track/video_track.h"
@@ -90,6 +92,7 @@
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.h"
#include "third_party/blink/renderer/core/layout/layout_media.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
+#include "third_party/blink/renderer/core/loader/mixed_content_checker.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/compositing/paint_layer_compositor.h"
@@ -100,7 +103,6 @@
#include "third_party/blink/renderer/platform/bindings/microtask.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.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/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h"
#include "third_party/blink/renderer/platform/network/mime/content_type.h"
@@ -133,25 +135,25 @@ using DocumentElementSetMap =
namespace {
// This enum is used to record histograms. Do not reorder.
-enum MediaControlsShow {
- kMediaControlsShowAttribute = 0,
- kMediaControlsShowFullscreen,
- kMediaControlsShowNoScript,
- kMediaControlsShowNotShown,
- kMediaControlsShowDisabledSettings,
- kMediaControlsShowMax
+enum class MediaControlsShow {
+ kAttribute = 0,
+ kFullscreen,
+ kNoScript,
+ kNotShown,
+ kDisabledSettings,
+ kMaxValue = kDisabledSettings,
};
// These values are used for the Media.MediaElement.ContentTypeResult histogram.
// Do not reorder.
-enum ContentTypeParseableResult {
+enum class ContentTypeParseableResult {
kIsSupportedParseable = 0,
kMayBeSupportedParseable,
kIsNotSupportedParseable,
kIsSupportedNotParseable,
kMayBeSupportedNotParseable,
kIsNotSupportedNotParseable,
- kContentTypeParseableMax
+ kMaxValue = kIsNotSupportedNotParseable,
};
// This enum is used to record histograms. Do not reorder.
@@ -160,7 +162,7 @@ enum class PlayPromiseRejectReason {
kNoSupportedSources,
kInterruptedByPause,
kInterruptedByLoad,
- kCount,
+ kMaxValue = kInterruptedByLoad,
};
static const base::TimeDelta kStalledNotificationInterval =
@@ -172,26 +174,30 @@ const double kMaxRate = 16.0;
void ReportContentTypeResultToUMA(String content_type,
MIMETypeRegistry::SupportsType result) {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- EnumerationHistogram, content_type_parseable_histogram,
- ("Media.MediaElement.ContentTypeParseable", kContentTypeParseableMax));
ParsedContentType parsed_content_type(content_type);
- ContentTypeParseableResult uma_result = kIsNotSupportedNotParseable;
+ ContentTypeParseableResult uma_result =
+ ContentTypeParseableResult::kIsNotSupportedNotParseable;
switch (result) {
case MIMETypeRegistry::kIsSupported:
- uma_result = parsed_content_type.IsValid() ? kIsSupportedParseable
- : kIsSupportedNotParseable;
+ uma_result = parsed_content_type.IsValid()
+ ? ContentTypeParseableResult::kIsSupportedParseable
+ : ContentTypeParseableResult::kIsSupportedNotParseable;
break;
case MIMETypeRegistry::kMayBeSupported:
- uma_result = parsed_content_type.IsValid() ? kMayBeSupportedParseable
- : kMayBeSupportedNotParseable;
+ uma_result =
+ parsed_content_type.IsValid()
+ ? ContentTypeParseableResult::kMayBeSupportedParseable
+ : ContentTypeParseableResult::kMayBeSupportedNotParseable;
break;
case MIMETypeRegistry::kIsNotSupported:
- uma_result = parsed_content_type.IsValid() ? kIsNotSupportedParseable
- : kIsNotSupportedNotParseable;
+ uma_result =
+ parsed_content_type.IsValid()
+ ? ContentTypeParseableResult::kIsNotSupportedParseable
+ : ContentTypeParseableResult::kIsNotSupportedNotParseable;
break;
}
- content_type_parseable_histogram.Count(uma_result);
+ base::UmaHistogramEnumeration("Media.MediaElement.ContentTypeParseable",
+ uma_result);
}
String UrlForLoggingMedia(const KURL& url) {
@@ -264,7 +270,7 @@ class AudioSourceProviderClientLockScope {
}
private:
- Member<AudioSourceProviderClient> client_;
+ AudioSourceProviderClient* client_;
};
const AtomicString& AudioKindToString(
@@ -361,16 +367,17 @@ String PreloadTypeToString(WebMediaPlayer::Preload preload_type) {
return String();
}
-bool IsDocumentCrossOrigin(Document& document) {
- const LocalFrame* frame = document.GetFrame();
- return frame && frame->IsCrossOriginSubframe();
+void RecordPlayPromiseRejected(PlayPromiseRejectReason reason) {
+ base::UmaHistogramEnumeration("Media.MediaElement.PlayPromiseReject", reason);
}
-void RecordPlayPromiseRejected(PlayPromiseRejectReason reason) {
- DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram,
- ("Media.MediaElement.PlayPromiseReject",
- static_cast<int>(PlayPromiseRejectReason::kCount)));
- histogram.Count(static_cast<int>(reason));
+void RecordShowControlsUsage(const HTMLMediaElement* element,
+ MediaControlsShow value) {
+ if (element->IsHTMLVideoElement()) {
+ base::UmaHistogramEnumeration("Media.Controls.Show.Video", value);
+ return;
+ }
+ base::UmaHistogramEnumeration("Media.Controls.Show.Audio", value);
}
bool IsValidPlaybackRate(double rate) {
@@ -446,7 +453,7 @@ void HTMLMediaElement::OnMediaControlsEnabledChange(Document* document) {
HTMLMediaElement::HTMLMediaElement(const QualifiedName& tag_name,
Document& document)
: HTMLElement(tag_name, document),
- ContextLifecycleStateObserver(&document),
+ ExecutionContextLifecycleStateObserver(GetExecutionContext()),
load_timer_(document.GetTaskRunner(TaskType::kInternalMedia),
this,
&HTMLMediaElement::LoadTimerFired),
@@ -588,7 +595,7 @@ void HTMLMediaElement::DidMoveToNewDocument(Document& old_document) {
// load event from within the destructor.
old_document.DecrementLoadEventDelayCount();
- ContextLifecycleStateObserver::DidMoveToNewExecutionContext(&GetDocument());
+ SetExecutionContext(GetExecutionContext());
HTMLElement::DidMoveToNewDocument(old_document);
}
@@ -1184,9 +1191,9 @@ void HTMLMediaElement::LoadResource(const WebMediaPlayerSource& source,
bool attempt_load = true;
- media_source_ = HTMLMediaSource::Lookup(url.GetString());
+ media_source_ = MediaSource::Lookup(url.GetString());
if (media_source_) {
- if (media_source_->AttachToElement(this)) {
+ if (media_source_->StartAttachingToMediaElement(this)) {
// If the associated feature is enabled, auto-revoke the MediaSource
// object URL that was used for attachment on successful (start of)
// attachment. This can help reduce memory bloat later if the app does not
@@ -1453,7 +1460,7 @@ void HTMLMediaElement::TextTrackReadyStateChanged(TextTrack* track) {
void HTMLMediaElement::TextTrackModeChanged(TextTrack* track) {
// Mark this track as "configured" so configureTextTracks won't change the
// mode again.
- if (track->TrackType() == TextTrack::kTrackElement)
+ if (IsA<LoadableTextTrack>(track))
track->SetHasBeenConfigured(true);
if (track->IsRendered()) {
@@ -1483,7 +1490,7 @@ bool HTMLMediaElement::IsSafeToLoadURL(const KURL& url,
LocalFrame* frame = GetDocument().GetFrame();
if (!frame || !GetDocument().GetSecurityOrigin()->CanDisplay(url)) {
if (action_if_invalid == kComplain) {
- GetDocument().AddConsoleMessage(ConsoleMessage::Create(
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kSecurity,
mojom::ConsoleMessageLevel::kError,
"Not allowed to load local resource: " + url.ElidedString()));
@@ -1515,10 +1522,6 @@ bool HTMLMediaElement::IsMediaDataCorsSameOrigin() const {
return !GetWebMediaPlayer()->WouldTaintOrigin();
}
-bool HTMLMediaElement::IsInCrossOriginFrame() const {
- return IsDocumentCrossOrigin(GetDocument());
-}
-
void HTMLMediaElement::StartProgressEventTimer() {
if (progress_event_timer_.IsActive())
return;
@@ -1757,6 +1760,10 @@ void HTMLMediaElement::ChangeNetworkStateFromLoadingToIdle() {
ScheduleEvent(event_type_names::kProgress);
ScheduleEvent(event_type_names::kSuspend);
SetNetworkState(kNetworkIdle);
+ } else {
+ // TODO(dalecurtis): Replace c-style casts in follow up patch.
+ DVLOG(1) << __func__ << "(" << (void*)this
+ << ") - Deferred network state change to idle for opaque media";
}
}
@@ -1799,6 +1806,32 @@ void HTMLMediaElement::SetReadyState(ReadyState state) {
web_media_player_) {
current_src_after_redirects_ =
KURL(web_media_player_->GetSrcAfterRedirects());
+
+ // Sometimes WebMediaPlayer may load a URL from an in memory cache, which
+ // skips notification of insecure content. Ensure we always notify the
+ // MixedContentChecker of what happened, even if the load was skipped.
+ if (LocalFrame* frame = GetDocument().GetFrame()) {
+ // We don't care about the return value here. The MixedContentChecker will
+ // internally notify for insecure content if it needs to regardless of
+ // what the return value ends up being for this call.
+ MixedContentChecker::ShouldBlockFetch(
+ frame,
+ HasVideo() ? mojom::blink::RequestContextType::VIDEO
+ : mojom::blink::RequestContextType::AUDIO,
+ // 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
+ // information cross-origin via CSP reports, so comparing URLs is
+ // sufficient for that purpose.
+ current_src_after_redirects_ == current_src_
+ ? ResourceRequest::RedirectStatus::kNoRedirect
+ : ResourceRequest::RedirectStatus::kFollowedRedirect,
+ current_src_after_redirects_);
+ }
+
+ // Prior to kHaveMetadata |network_state_| may be inaccurate to avoid side
+ // channel leaks. This be a no-op if nothing has changed.
+ NetworkStateChanged();
}
if (new_state > ready_state_maximum_)
@@ -2354,12 +2387,12 @@ void HTMLMediaElement::setPreload(const AtomicString& preload) {
WebMediaPlayer::Preload HTMLMediaElement::PreloadType() const {
const AtomicString& preload = FastGetAttribute(html_names::kPreloadAttr);
- if (DeprecatedEqualIgnoringCase(preload, "none")) {
+ if (EqualIgnoringASCIICase(preload, "none")) {
UseCounter::Count(GetDocument(), WebFeature::kHTMLMediaElementPreloadNone);
return WebMediaPlayer::kPreloadNone;
}
- if (DeprecatedEqualIgnoringCase(preload, "metadata")) {
+ if (EqualIgnoringASCIICase(preload, "metadata")) {
UseCounter::Count(GetDocument(),
WebFeature::kHTMLMediaElementPreloadMetadata);
return WebMediaPlayer::kPreloadMetaData;
@@ -2374,8 +2407,8 @@ WebMediaPlayer::Preload HTMLMediaElement::PreloadType() const {
// Per HTML spec, "The empty string ... maps to the Automatic state."
// https://html.spec.whatwg.org/C/#attr-media-preload
- if (DeprecatedEqualIgnoringCase(preload, "auto") ||
- DeprecatedEqualIgnoringCase(preload, "")) {
+ if (EqualIgnoringASCIICase(preload, "auto") ||
+ EqualIgnoringASCIICase(preload, "")) {
UseCounter::Count(GetDocument(), WebFeature::kHTMLMediaElementPreloadAuto);
return WebMediaPlayer::kPreloadAuto;
}
@@ -2587,31 +2620,31 @@ bool HTMLMediaElement::ShouldShowControls(
Settings* settings = GetDocument().GetSettings();
if (settings && !settings->GetMediaControlsEnabled()) {
if (record_metrics == RecordMetricsBehavior::kDoRecord)
- ShowControlsHistogram().Count(kMediaControlsShowDisabledSettings);
+ RecordShowControlsUsage(this, MediaControlsShow::kDisabledSettings);
return false;
}
if (FastHasAttribute(html_names::kControlsAttr)) {
if (record_metrics == RecordMetricsBehavior::kDoRecord)
- ShowControlsHistogram().Count(kMediaControlsShowAttribute);
+ RecordShowControlsUsage(this, MediaControlsShow::kAttribute);
return true;
}
if (IsFullscreen()) {
if (record_metrics == RecordMetricsBehavior::kDoRecord)
- ShowControlsHistogram().Count(kMediaControlsShowFullscreen);
+ RecordShowControlsUsage(this, MediaControlsShow::kFullscreen);
return true;
}
LocalFrame* frame = GetDocument().GetFrame();
if (frame && !GetDocument().CanExecuteScripts(kNotAboutToExecuteScript)) {
if (record_metrics == RecordMetricsBehavior::kDoRecord)
- ShowControlsHistogram().Count(kMediaControlsShowNoScript);
+ RecordShowControlsUsage(this, MediaControlsShow::kNoScript);
return true;
}
if (record_metrics == RecordMetricsBehavior::kDoRecord)
- ShowControlsHistogram().Count(kMediaControlsShowNotShown);
+ RecordShowControlsUsage(this, MediaControlsShow::kNotShown);
return false;
}
@@ -2922,7 +2955,7 @@ void HTMLMediaElement::RemoveTextTrack(WebInbandTextTrack* web_track) {
// This cast is safe because InbandTextTrack is the only concrete
// implementation of WebInbandTextTrackClient.
- InbandTextTrack* text_track = ToInbandTextTrack(web_track->Client());
+ auto* text_track = To<InbandTextTrack>(web_track->Client());
if (!text_track)
return;
@@ -2958,7 +2991,7 @@ TextTrack* HTMLMediaElement::addTextTrack(const AtomicString& kind,
// text track kind to kind, its text track label to label, its text
// track language to language, ..., and its text track list of cues to
// an empty list.
- TextTrack* text_track = TextTrack::Create(kind, label, language);
+ auto* text_track = MakeGarbageCollected<TextTrack>(kind, label, language);
// ..., its text track readiness state to the text track loaded state, ...
text_track->SetReadinessState(TextTrack::kLoaded);
@@ -3267,17 +3300,14 @@ void HTMLMediaElement::TimeChanged() {
// 4.8.12.9 steps 12-14. Needed if no ReadyState change is associated with the
// seek.
if (seeking_ && ready_state_ >= kHaveCurrentData &&
- !GetWebMediaPlayer()->Seeking())
+ !GetWebMediaPlayer()->Seeking()) {
FinishSeek();
-
- double now = CurrentPlaybackPosition();
- double dur = duration();
+ }
// When the current playback position reaches the end of the media resource
// when the direction of playback is forwards, then the user agent must follow
// these steps:
- if (!std::isnan(dur) && dur && now >= dur &&
- GetDirectionOfPlayback() == kForward) {
+ if (EndedPlayback(LoopCondition::kIgnored)) {
// If the media element has a loop attribute specified
if (Loop()) {
// then seek to the earliest possible position of the media resource and
@@ -3444,9 +3474,9 @@ bool HTMLMediaElement::CouldPlayIfEnoughData() const {
}
bool HTMLMediaElement::EndedPlayback(LoopCondition loop_condition) const {
- double dur = duration();
// If we have infinite duration, we'll never have played for long enough to
// have ended playback.
+ const double dur = duration();
if (std::isnan(dur) || dur == std::numeric_limits<double>::infinity())
return false;
@@ -3457,20 +3487,13 @@ bool HTMLMediaElement::EndedPlayback(LoopCondition loop_condition) const {
if (ready_state_ < kHaveMetadata)
return false;
- // and the current playback position is the end of the media resource and the
- // direction of playback is forwards, Either the media element does not have a
- // loop attribute specified,
- double now = CurrentPlaybackPosition();
-
- if (GetDirectionOfPlayback() == kForward) {
- return dur > 0 && now >= dur &&
+ DCHECK_EQ(GetDirectionOfPlayback(), kForward);
+ if (auto* wmp = GetWebMediaPlayer()) {
+ return wmp->IsEnded() &&
(loop_condition == LoopCondition::kIgnored || !Loop());
}
- // or the current playback position is the earliest possible position and the
- // direction of playback is backwards
- DCHECK_EQ(GetDirectionOfPlayback(), kBackward);
- return now <= EarliestPossiblePosition();
+ return false;
}
bool HTMLMediaElement::StoppedDueToErrors() const {
@@ -3578,8 +3601,8 @@ void HTMLMediaElement::ContextLifecycleStateChanged(
}
}
-void HTMLMediaElement::ContextDestroyed(ExecutionContext*) {
- DVLOG(3) << "contextDestroyed(" << (void*)this << ")";
+void HTMLMediaElement::ContextDestroyed() {
+ DVLOG(3) << "contextDestroyed(" << static_cast<void*>(this) << ")";
// Close the async event queue so that no events are enqueued.
CancelPendingEventsAndCallbacks();
@@ -3606,6 +3629,13 @@ void HTMLMediaElement::ContextDestroyed(ExecutionContext*) {
}
bool HTMLMediaElement::HasPendingActivity() const {
+ const auto result = HasPendingActivityInternal();
+ // TODO(dalecurtis): Replace c-style casts in followup patch.
+ DVLOG(3) << "HasPendingActivity(" << (void*)this << ") = " << result;
+ return result;
+}
+
+bool HTMLMediaElement::HasPendingActivityInternal() const {
// The delaying-the-load-event flag is set by resource selection algorithm
// when looking for a resource to load, before networkState has reached to
// kNetworkLoading.
@@ -3622,8 +3652,18 @@ bool HTMLMediaElement::HasPendingActivity() const {
// MediaSource API objects. This lets the group of objects be garbage
// collected if there is no pending activity nor reachability from a GC root,
// even while in kNetworkLoading.
- if (!media_source_ && network_state_ == kNetworkLoading)
- return true;
+ //
+ // We use the WebMediaPlayer's network state instead of |network_state_| since
+ // it's value is unreliable prior to ready state kHaveMetadata.
+ if (!media_source_) {
+ const auto* wmp = GetWebMediaPlayer();
+ if (!wmp) {
+ if (network_state_ == kNetworkLoading)
+ return true;
+ } else if (wmp->GetNetworkState() == WebMediaPlayer::kNetworkStateLoading) {
+ return true;
+ }
+ }
{
// Disable potential updating of playback position, as that will
@@ -3937,7 +3977,7 @@ WebMediaPlayer::CorsMode HTMLMediaElement::CorsMode() const {
FastGetAttribute(html_names::kCrossoriginAttr);
if (cross_origin_mode.IsNull())
return WebMediaPlayer::kCorsModeUnspecified;
- if (DeprecatedEqualIgnoringCase(cross_origin_mode, "use-credentials"))
+ if (EqualIgnoringASCIICase(cross_origin_mode, "use-credentials"))
return WebMediaPlayer::kCorsModeUseCredentials;
return WebMediaPlayer::kCorsModeAnonymous;
}
@@ -3948,17 +3988,13 @@ void HTMLMediaElement::SetCcLayer(cc::Layer* cc_layer) {
// We need to update the GraphicsLayer when the cc layer changes.
SetNeedsCompositingUpdate();
-
- if (cc_layer_)
- GraphicsLayer::UnregisterContentsLayer(cc_layer_);
cc_layer_ = cc_layer;
- if (cc_layer_)
- GraphicsLayer::RegisterContentsLayer(cc_layer_);
}
void HTMLMediaElement::MediaSourceOpened(WebMediaSource* web_media_source) {
SetShouldDelayLoadEvent(false);
- media_source_->SetWebMediaSourceAndOpen(base::WrapUnique(web_media_source));
+ media_source_->CompleteAttachingToMediaElement(
+ base::WrapUnique(web_media_source));
}
bool HTMLMediaElement::IsInteractiveContent() const {
@@ -3989,7 +4025,7 @@ void HTMLMediaElement::Trace(Visitor* visitor) {
visitor->Trace(lazy_load_intersection_observer_);
Supplementable<HTMLMediaElement>::Trace(visitor);
HTMLElement::Trace(visitor);
- ContextLifecycleStateObserver::Trace(visitor);
+ ExecutionContextLifecycleStateObserver::Trace(visitor);
}
void HTMLMediaElement::CreatePlaceholderTracksIfNecessary() {
@@ -4126,18 +4162,6 @@ void HTMLMediaElement::RejectPlayPromisesInternal(DOMExceptionCode code,
play_promise_reject_list_.clear();
}
-EnumerationHistogram& HTMLMediaElement::ShowControlsHistogram() const {
- if (IsHTMLVideoElement()) {
- DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram,
- ("Media.Controls.Show.Video", kMediaControlsShowMax));
- return histogram;
- }
-
- DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram,
- ("Media.Controls.Show.Audio", kMediaControlsShowMax));
- return histogram;
-}
-
void HTMLMediaElement::OnRemovedFromDocumentTimerFired(TimerBase*) {
if (InActiveDocument())
return;
@@ -4243,7 +4267,6 @@ void HTMLMediaElement::RequestMuted(bool muted) {
bool HTMLMediaElement::MediaShouldBeOpaque() const {
return !IsMediaDataCorsSameOrigin() && ready_state_ < kHaveMetadata &&
- !FastGetAttribute(html_names::kSrcAttr).IsEmpty() &&
EffectivePreloadType() != WebMediaPlayer::kPreloadNone;
}
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 cc7c8d09256..85851eb1cbc 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
@@ -31,18 +31,18 @@
#include "base/optional.h"
#include "base/timer/elapsed_timer.h"
-#include "third_party/blink/public/platform/web_audio_source_provider_client.h"
#include "third_party/blink/public/platform/web_media_player_client.h"
#include "third_party/blink/public/platform/webaudiosourceprovider_impl.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/core/core_export.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/html/media/media_controls.h"
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer.h"
#include "third_party/blink/renderer/platform/audio/audio_source_provider.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/media/web_audio_source_provider_client.h"
#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
#include "third_party/blink/renderer/platform/supplementable.h"
@@ -61,12 +61,11 @@ class AudioTrackList;
class AutoplayPolicy;
class ContentType;
class CueTimeline;
-class EnumerationHistogram;
class Event;
class EventQueue;
class ExceptionState;
class HTMLMediaElementControlsList;
-class HTMLMediaSource;
+class MediaSource;
class HTMLSourceElement;
class HTMLTrackElement;
class MediaError;
@@ -86,7 +85,7 @@ class CORE_EXPORT HTMLMediaElement
: public HTMLElement,
public Supplementable<HTMLMediaElement>,
public ActiveScriptWrappable<HTMLMediaElement>,
- public ContextLifecycleStateObserver,
+ public ExecutionContextLifecycleStateObserver,
private WebMediaPlayerClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(HTMLMediaElement);
@@ -199,7 +198,6 @@ class CORE_EXPORT HTMLMediaElement
TimeRanges* seekable() const;
bool ended() const;
bool Autoplay() const;
- bool ShouldAutoplay();
bool Loop() const;
void SetLoop(bool);
ScriptPromise playForBindings(ScriptState*);
@@ -245,11 +243,6 @@ class CORE_EXPORT HTMLMediaElement
TextTrackList* textTracks();
CueTimeline& GetCueTimeline();
- void addTextTrack(TextTrack*);
- void RemoveTextTrack(TextTrack*);
- void TextTracksChanged();
- void NotifyMediaPlayerOfTextTrackChanges();
-
// Implements the "forget the media element's media-resource-specific tracks"
// algorithm in the HTML5 spec.
void ForgetResourceSpecificTracks();
@@ -269,10 +262,10 @@ class CORE_EXPORT HTMLMediaElement
void DisableAutomaticTextTrackSelection();
// EventTarget function.
- // Both Node (via HTMLElement) and ContextLifecycleStateObserver define this
- // method, which causes an ambiguity error at compile time. This class's
- // constructor ensures that both implementations return document, so return
- // the result of one of them here.
+ // Both Node (via HTMLElement) and ExecutionContextLifecycleStateObserver
+ // define this method, which causes an ambiguity error at compile time. This
+ // class's constructor ensures that both implementations return document, so
+ // return the result of one of them here.
using HTMLElement::GetExecutionContext;
bool IsFullscreen() const;
@@ -311,9 +304,6 @@ class CORE_EXPORT HTMLMediaElement
// Checks to see if current media data is CORS-same-origin.
bool IsMediaDataCorsSameOrigin() const;
- // Returns this media element is in a cross-origin frame.
- bool IsInCrossOriginFrame() const;
-
void ScheduleEvent(Event*);
// Returns the "effective media volume" value as specified in the HTML5 spec.
@@ -382,6 +372,8 @@ class CORE_EXPORT HTMLMediaElement
friend class VideoWakeLockTest;
friend class PictureInPictureControllerTest;
+ bool HasPendingActivityInternal() const;
+
void ResetMediaPlayerAndMediaSource();
bool AlwaysCreateUserAgentShadowRoot() const final { return true; }
@@ -398,9 +390,9 @@ class CORE_EXPORT HTMLMediaElement
bool IsInteractiveContent() const final;
- // ContextLifecycleStateObserver functions.
+ // ExecutionContextLifecycleStateObserver functions.
void ContextLifecycleStateChanged(mojom::FrameLifecycleState) override;
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
virtual void UpdateDisplayState() {}
virtual void OnPlay() {}
@@ -453,6 +445,8 @@ class CORE_EXPORT HTMLMediaElement
void RequestPlay() final;
void RequestPause() final;
void RequestMuted(bool muted) final;
+ void RequestEnterPictureInPicture() override {}
+ void RequestExitPictureInPicture() override {}
void LoadTimerFired(TimerBase*);
void ProgressEventTimerFired(TimerBase*);
@@ -464,7 +458,6 @@ class CORE_EXPORT HTMLMediaElement
void Seek(double time);
void FinishSeek();
- void CheckIfSeekNeeded();
void AddPlayedRange(double start, double end);
// FIXME: Rename to scheduleNamedEvent for clarity.
@@ -511,7 +504,6 @@ class CORE_EXPORT HTMLMediaElement
// This does not stop autoplay visibility observation.
void PauseInternal();
- void UpdateVolume();
void UpdatePlayState();
bool PotentiallyPlaying() const;
bool StoppedDueToErrors() const;
@@ -564,8 +556,6 @@ class CORE_EXPORT HTMLMediaElement
void RejectPlayPromises(DOMExceptionCode, const String&);
void RejectPlayPromisesInternal(DOMExceptionCode, const String&);
- EnumerationHistogram& ShowControlsHistogram() const;
-
void OnRemovedFromDocumentTimerFired(TimerBase*);
Features GetFeatures() override;
@@ -636,14 +626,7 @@ class CORE_EXPORT HTMLMediaElement
DisplayMode display_mode_;
- // If any portion of an attached HTMLMediaElement (HTMLME) and the MediaSource
- // Extensions (MSE) API is alive (having pending activity or traceable from a
- // GC root), the whole group is not GC'ed. Here, using Member,
- // instead of Member, because |media_source_|'s wrapper needs to remain alive
- // at least to successfully dispatch any events enqueued by behavior of the
- // HTMLME+MSE API. It makes |media_source_|'s wrapper remain alive as long as
- // this HTMLMediaElement's wrapper is alive.
- Member<HTMLMediaSource> media_source_;
+ Member<MediaSource> media_source_;
// Stores "official playback position", updated periodically from "current
// playback position". Official playback position should not change while
@@ -767,11 +750,21 @@ class CORE_EXPORT HTMLMediaElement
Member<IntersectionObserver> lazy_load_intersection_observer_;
};
-inline bool IsHTMLMediaElement(const HTMLElement& element) {
- return IsA<HTMLAudioElement>(element) || IsA<HTMLVideoElement>(element);
+template <>
+inline bool IsElementOfType<const HTMLMediaElement>(const Node& node) {
+ return IsA<HTMLMediaElement>(node);
}
-
-DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLMediaElement);
+template <>
+struct DowncastTraits<HTMLMediaElement> {
+ static bool AllowFrom(const Node& node) {
+ auto* html_element = DynamicTo<HTMLElement>(node);
+ return html_element && AllowFrom(*html_element);
+ }
+ static bool AllowFrom(const HTMLElement& html_element) {
+ return IsA<HTMLAudioElement>(html_element) ||
+ IsA<HTMLVideoElement>(html_element);
+ }
+};
} // namespace blink
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 4d20e00704e..faeb17ce9f1 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
@@ -18,6 +18,7 @@
#include "third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.h"
#include "third_party/blink/renderer/core/loader/empty_clients.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
+#include "third_party/blink/renderer/platform/bindings/microtask.h"
#include "third_party/blink/renderer/platform/testing/empty_web_media_player.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
@@ -27,21 +28,22 @@ namespace blink {
namespace {
+static constexpr base::TimeDelta kFakeMediaPlayerAutoIncrementTimeDelta =
+ base::TimeDelta::FromMilliseconds(33);
+
// Most methods are faked rather than mocked. Faking avoids naggy warnings
// about unexpected calls. HTMLMediaElement <-> WebMediaplayer interface is
// highly complex and not generally the focus these tests (with the
// exception of the mocked methods).
class FakeWebMediaPlayer final : public EmptyWebMediaPlayer {
public:
- FakeWebMediaPlayer(WebMediaPlayerClient* client) : client_(client) {}
+ FakeWebMediaPlayer(WebMediaPlayerClient* client, Document* document)
+ : client_(client), document_(document) {}
MOCK_METHOD1(SetIsEffectivelyFullscreen,
void(blink::WebFullscreenVideoStatus));
double CurrentTime() const override {
- if (auto_advance_current_time_)
- current_time_++;
-
return current_time_;
}
@@ -56,6 +58,13 @@ class FakeWebMediaPlayer final : public EmptyWebMediaPlayer {
void Seek(double seconds) override { last_seek_time_ = seconds; }
+ void Play() override {
+ playing_ = true;
+ ScheduleTimeIncrement();
+ }
+ void Pause() override { playing_ = false; }
+ bool Paused() const override { return !playing_; }
+
void FinishSeek() {
ASSERT_GE(last_seek_time_, 0);
current_time_ = last_seek_time_;
@@ -64,24 +73,56 @@ class FakeWebMediaPlayer final : public EmptyWebMediaPlayer {
client_->TimeChanged();
}
- void SetAutoAdvanceCurrentTime(bool auto_advance) {
- auto_advance_current_time_ = auto_advance;
+ void SetAutoIncrementCurrentTime(bool auto_increment) {
+ auto_increment_current_time_ = auto_increment;
+ if (auto_increment) {
+ ScheduleTimeIncrement();
+ }
}
private:
+ void ScheduleTimeIncrement() {
+ if (scheduled_time_increment_) {
+ return;
+ }
+
+ document_->GetTaskRunner(TaskType::kInternalMediaRealTime)
+ ->PostDelayedTask(FROM_HERE,
+ base::BindOnce(&FakeWebMediaPlayer::AutoTimeIncrement,
+ base::Unretained(this)),
+ kFakeMediaPlayerAutoIncrementTimeDelta);
+ scheduled_time_increment_ = true;
+ }
+
+ void AutoTimeIncrement() {
+ if (!auto_increment_current_time_ || !playing_) {
+ return;
+ }
+
+ scheduled_time_increment_ = false;
+ current_time_ += kFakeMediaPlayerAutoIncrementTimeDelta.InSecondsF();
+ ScheduleTimeIncrement();
+
+ // Run V8 Microtasks (update OfficialPlaybackPosition)
+ Microtask::PerformCheckpoint(document_->GetIsolate());
+ }
+
WebMediaPlayerClient* client_;
+ WeakPersistent<Document> document_;
mutable double current_time_ = 0;
- bool auto_advance_current_time_ = false;
+ bool playing_ = false;
+ bool auto_increment_current_time_ = false;
+ bool scheduled_time_increment_ = false;
double last_seek_time_ = -1;
};
class MediaStubLocalFrameClient : public EmptyLocalFrameClient {
public:
std::unique_ptr<WebMediaPlayer> CreateWebMediaPlayer(
- HTMLMediaElement&,
+ HTMLMediaElement& element,
const WebMediaPlayerSource&,
WebMediaPlayerClient* client) override {
- return std::make_unique<FakeWebMediaPlayer>(client);
+ return std::make_unique<FakeWebMediaPlayer>(client, &element.GetDocument());
}
};
@@ -115,16 +156,11 @@ class HTMLMediaElementEventListenersTest : public PageTestBase {
MediaCustomControlsFullscreenDetector* FullscreenDetector() {
return Video()->custom_controls_fullscreen_detector_;
}
- bool IsCheckViewportIntersectionTimerActive(
- MediaCustomControlsFullscreenDetector* detector) {
- return detector->check_viewport_intersection_timer_.IsActive();
- }
};
TEST_F(HTMLMediaElementEventListenersTest, RemovingFromDocumentCollectsAll) {
EXPECT_EQ(Video(), nullptr);
- GetDocument().body()->SetInnerHTMLFromString(
- "<body><video controls></video></body>");
+ GetDocument().body()->setInnerHTML("<body><video controls></video></body>");
EXPECT_NE(Video(), nullptr);
EXPECT_TRUE(Video()->HasEventListeners());
EXPECT_NE(Controls(), nullptr);
@@ -134,7 +170,7 @@ TEST_F(HTMLMediaElementEventListenersTest, RemovingFromDocumentCollectsAll) {
WeakPersistent<MediaControls> weak_persistent_controls = Controls();
{
Persistent<HTMLVideoElement> persistent_video = Video();
- GetDocument().body()->SetInnerHTMLFromString("");
+ GetDocument().body()->setInnerHTML("");
// When removed from the document, the event listeners should have been
// dropped.
@@ -155,8 +191,7 @@ TEST_F(HTMLMediaElementEventListenersTest, RemovingFromDocumentCollectsAll) {
TEST_F(HTMLMediaElementEventListenersTest,
ReInsertingInDocumentCollectsControls) {
EXPECT_EQ(Video(), nullptr);
- GetDocument().body()->SetInnerHTMLFromString(
- "<body><video controls></video></body>");
+ GetDocument().body()->setInnerHTML("<body><video controls></video></body>");
EXPECT_NE(Video(), nullptr);
EXPECT_TRUE(Video()->HasEventListeners());
EXPECT_NE(Controls(), nullptr);
@@ -184,10 +219,8 @@ TEST_F(HTMLMediaElementEventListenersTest,
TEST_F(HTMLMediaElementEventListenersTest,
FullscreenDetectorTimerCancelledOnContextDestroy) {
- ScopedVideoFullscreenDetectionForTest video_fullscreen_detection(true);
-
EXPECT_EQ(Video(), nullptr);
- GetDocument().body()->SetInnerHTMLFromString("<body><video></video></body>");
+ GetDocument().body()->setInnerHTML("<body><video></video></body>");
Video()->SetSrc("http://example.com");
test::RunPendingTasks();
@@ -199,7 +232,8 @@ TEST_F(HTMLMediaElementEventListenersTest,
SimulateReadyState(HTMLMediaElement::kHaveMetadata);
LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
Fullscreen::RequestFullscreen(*Video());
- Fullscreen::DidEnterFullscreen(GetDocument());
+ Fullscreen::DidResolveEnterFullscreenRequest(GetDocument(),
+ true /* granted */);
test::RunPendingTasks();
@@ -221,8 +255,6 @@ TEST_F(HTMLMediaElementEventListenersTest,
// Document should not have listeners as the ExecutionContext is destroyed.
EXPECT_FALSE(persistent_document->HasEventListeners());
- // The timer should be cancelled when the ExecutionContext is destroyed.
- EXPECT_FALSE(IsCheckViewportIntersectionTimerActive(detector));
// Should only notify the kNotEffectivelyFullscreen value when
// ExecutionContext is destroyed.
EXPECT_EQ(1u, observed_results.size());
@@ -254,7 +286,7 @@ class HTMLMediaElementWithMockSchedulerTest
TEST_F(HTMLMediaElementWithMockSchedulerTest, OneTimeupdatePerSeek) {
testing::InSequence dummy;
- GetDocument().body()->SetInnerHTMLFromString("<body><video></video></body>");
+ GetDocument().body()->setInnerHTML("<body><video></video></body>");
// Set a src to trigger WebMediaPlayer creation.
Video()->SetSrc("http://example.com");
@@ -270,8 +302,7 @@ TEST_F(HTMLMediaElementWithMockSchedulerTest, OneTimeupdatePerSeek) {
SimulateReadyState(HTMLMediaElement::kHaveFutureData);
// Simulate advancing playback time.
- WebMediaPlayer()->SetAutoAdvanceCurrentTime(true);
-
+ WebMediaPlayer()->SetAutoIncrementCurrentTime(true);
Video()->Play();
// While playing, timeupdate should fire every 250 ms -> 4x per second as long
@@ -281,10 +312,11 @@ TEST_F(HTMLMediaElementWithMockSchedulerTest, OneTimeupdatePerSeek) {
// If media playback time is fixed, periodic timeupdate's should not continue
// to fire.
- WebMediaPlayer()->SetAutoAdvanceCurrentTime(false);
+ WebMediaPlayer()->SetAutoIncrementCurrentTime(false);
EXPECT_CALL(*timeupdate_handler, Invoke(_, _)).Times(0);
platform()->RunForPeriodSeconds(1);
+ // Per spec, pausing should fire `timeupdate`
EXPECT_CALL(*timeupdate_handler, Invoke(_, _)).Times(1);
Video()->pause();
platform()->RunUntilIdle();
@@ -292,8 +324,11 @@ TEST_F(HTMLMediaElementWithMockSchedulerTest, OneTimeupdatePerSeek) {
// Seek to some time in the past. A completed seek while paused should trigger
// a *single* timeupdate.
EXPECT_CALL(*timeupdate_handler, Invoke(_, _)).Times(1);
- ASSERT_GE(WebMediaPlayer()->CurrentTime(), 1);
- Video()->setCurrentTime(WebMediaPlayer()->CurrentTime() - 1);
+
+ // The WebMediaPlayer current time should have progressed to almost 1 second
+ // (Actually 0.99 due to |kFakeMediaPlayerAutoIncrementTimeDelta|).
+ ASSERT_GE(WebMediaPlayer()->CurrentTime(), 0.95);
+ Video()->setCurrentTime(0.5);
// Fake the callback from WebMediaPlayer to complete the seek.
WebMediaPlayer()->FinishSeek();
@@ -304,7 +339,7 @@ TEST_F(HTMLMediaElementWithMockSchedulerTest, OneTimeupdatePerSeek) {
TEST_F(HTMLMediaElementWithMockSchedulerTest, PeriodicTimeupdateAfterSeek) {
testing::InSequence dummy;
- GetDocument().body()->SetInnerHTMLFromString("<body><video></video></body>");
+ GetDocument().body()->setInnerHTML("<body><video></video></body>");
// Set a src to trigger WebMediaPlayer creation.
Video()->SetSrc("http://example.com");
@@ -320,8 +355,7 @@ TEST_F(HTMLMediaElementWithMockSchedulerTest, PeriodicTimeupdateAfterSeek) {
SimulateReadyState(HTMLMediaElement::kHaveFutureData);
// Simulate advancing playback time to enable periodic timeupdates.
- WebMediaPlayer()->SetAutoAdvanceCurrentTime(true);
-
+ WebMediaPlayer()->SetAutoIncrementCurrentTime(true);
Video()->Play();
// Advance a full periodic timeupdate interval (250 ms) and expect a single
@@ -340,8 +374,8 @@ TEST_F(HTMLMediaElementWithMockSchedulerTest, PeriodicTimeupdateAfterSeek) {
// While still in the middle of the periodic timeupdate interval, start and
// complete a seek and verify that a *non-periodic* timeupdate is fired.
EXPECT_CALL(*timeupdate_handler, Invoke(_, _)).Times(1);
- ASSERT_GE(WebMediaPlayer()->CurrentTime(), 1);
- Video()->setCurrentTime(WebMediaPlayer()->CurrentTime() - 1);
+ ASSERT_GE(WebMediaPlayer()->CurrentTime(), 0.3);
+ Video()->setCurrentTime(0.2);
WebMediaPlayer()->FinishSeek();
// Expect another timeupdate after FinishSeek due to
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 df41b7a211c..3fd83d9af3f 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
@@ -8,7 +8,9 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/autoplay/autoplay.mojom-blink.h"
+#include "third_party/blink/public/platform/web_media_player.h"
#include "third_party/blink/public/platform/web_media_player_source.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/media/html_audio_element.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
@@ -32,12 +34,17 @@ using ::testing::Return;
namespace blink {
+namespace {
+
class MockWebMediaPlayer : public EmptyWebMediaPlayer {
public:
MOCK_CONST_METHOD0(HasAudio, bool());
MOCK_CONST_METHOD0(HasVideo, bool());
MOCK_CONST_METHOD0(Duration, double());
MOCK_CONST_METHOD0(CurrentTime, double());
+ MOCK_CONST_METHOD0(IsEnded, bool());
+ MOCK_CONST_METHOD0(GetNetworkState, NetworkState());
+ MOCK_CONST_METHOD0(WouldTaintOrigin, bool());
MOCK_METHOD1(SetLatencyHint, void(double));
MOCK_METHOD1(EnabledAudioTracksChanged, void(const WebVector<TrackId>&));
MOCK_METHOD1(SelectedVideoTrackChanged, void(TrackId*));
@@ -70,6 +77,8 @@ class WebMediaStubLocalFrameClient : public EmptyLocalFrameClient {
enum class MediaTestParam { kAudio, kVideo };
+} // namespace
+
class HTMLMediaElementTest : public testing::TestWithParam<MediaTestParam> {
protected:
void SetUp() override {
@@ -79,19 +88,19 @@ 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, HasAudio())
- .WillRepeatedly(testing::Return(true));
- EXPECT_CALL(*mock_media_player, HasVideo())
- .WillRepeatedly(testing::Return(true));
- EXPECT_CALL(*mock_media_player, Duration())
- .WillRepeatedly(testing::Return(1.0));
- EXPECT_CALL(*mock_media_player, CurrentTime())
- .WillRepeatedly(testing::Return(0));
+ 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));
+ EXPECT_CALL(*mock_media_player, CurrentTime()).WillRepeatedly(Return(0));
EXPECT_CALL(*mock_media_player, Load(_, _, _))
.Times(AnyNumber())
.WillRepeatedly(Return(WebMediaPlayer::LoadTiming::kImmediate));
- EXPECT_CALL(*mock_media_player, DidLazyLoad)
- .WillRepeatedly(testing::Return(false));
+ EXPECT_CALL(*mock_media_player, DidLazyLoad).WillRepeatedly(Return(false));
+ EXPECT_CALL(*mock_media_player, WouldTaintOrigin)
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(*mock_media_player, GetNetworkState)
+ .WillRepeatedly(Return(WebMediaPlayer::kNetworkStateIdle));
+ EXPECT_CALL(*mock_media_player, SetLatencyHint(_)).Times(AnyNumber());
dummy_page_holder_ = std::make_unique<DummyPageHolder>(
IntSize(), nullptr,
@@ -125,6 +134,12 @@ class HTMLMediaElementTest : public testing::TestWithParam<MediaTestParam> {
Media()->SetReadyState(state);
}
+ void SetNetworkState(WebMediaPlayer::NetworkState state) {
+ Media()->SetNetworkState(state);
+ }
+
+ bool MediaShouldBeOpaque() const { return Media()->MediaShouldBeOpaque(); }
+
void SetError(MediaError* err) { Media()->MediaEngineError(err); }
void SimulateHighMediaEngagement() {
@@ -137,7 +152,7 @@ class HTMLMediaElementTest : public testing::TestWithParam<MediaTestParam> {
}
ExecutionContext* GetExecutionContext() const {
- return &dummy_page_holder_->GetDocument();
+ return dummy_page_holder_->GetFrame().DomWindow();
}
private:
@@ -262,7 +277,8 @@ TEST_P(HTMLMediaElementTest, CouldPlayIfEnoughDataRespondsToEnded) {
MockWebMediaPlayer* mock_wmpi =
reinterpret_cast<MockWebMediaPlayer*>(Media()->GetWebMediaPlayer());
- EXPECT_NE(mock_wmpi, nullptr);
+ ASSERT_NE(mock_wmpi, nullptr);
+ EXPECT_CALL(*mock_wmpi, IsEnded()).WillRepeatedly(Return(false));
EXPECT_TRUE(CouldPlayIfEnoughData());
// Playback can only end once the ready state is above kHaveMetadata.
@@ -274,7 +290,8 @@ TEST_P(HTMLMediaElementTest, CouldPlayIfEnoughDataRespondsToEnded) {
// Now advance current time to duration and verify ended state.
testing::Mock::VerifyAndClearExpectations(mock_wmpi);
EXPECT_CALL(*mock_wmpi, CurrentTime())
- .WillRepeatedly(testing::Return(Media()->duration()));
+ .WillRepeatedly(Return(Media()->duration()));
+ EXPECT_CALL(*mock_wmpi, IsEnded()).WillRepeatedly(Return(true));
EXPECT_FALSE(CouldPlayIfEnoughData());
EXPECT_TRUE(Media()->ended());
}
@@ -328,9 +345,9 @@ TEST_P(HTMLMediaElementTest, CouldPlayIfEnoughDataInfiniteStreamNeverEnds) {
test::RunPendingTasks();
EXPECT_CALL(*MockMediaPlayer(), Duration())
- .WillRepeatedly(testing::Return(std::numeric_limits<double>::infinity()));
+ .WillRepeatedly(Return(std::numeric_limits<double>::infinity()));
EXPECT_CALL(*MockMediaPlayer(), CurrentTime())
- .WillRepeatedly(testing::Return(std::numeric_limits<double>::infinity()));
+ .WillRepeatedly(Return(std::numeric_limits<double>::infinity()));
SetReadyState(HTMLMediaElement::kHaveMetadata);
EXPECT_FALSE(Media()->paused());
@@ -573,4 +590,20 @@ TEST_P(HTMLMediaElementTest, EmptyRedirectedSrcUsesOriginal) {
EXPECT_EQ(Media()->downloadURL(), Media()->currentSrc());
}
+TEST_P(HTMLMediaElementTest, NoPendingActivityEvenIfBeforeMetadata) {
+ Media()->SetSrc(SrcSchemeToURL(TestURLScheme::kHttp));
+ test::RunPendingTasks();
+
+ MockWebMediaPlayer* mock_wmpi =
+ reinterpret_cast<MockWebMediaPlayer*>(Media()->GetWebMediaPlayer());
+ EXPECT_CALL(*mock_wmpi, WouldTaintOrigin()).WillRepeatedly(Return(true));
+ EXPECT_NE(mock_wmpi, nullptr);
+
+ EXPECT_TRUE(MediaShouldBeOpaque());
+ EXPECT_TRUE(Media()->HasPendingActivity());
+ SetNetworkState(WebMediaPlayer::kNetworkStateIdle);
+ EXPECT_FALSE(Media()->HasPendingActivity());
+ EXPECT_TRUE(MediaShouldBeOpaque());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/media/html_media_test_helper.cc b/chromium/third_party/blink/renderer/core/html/media/html_media_test_helper.cc
index b0d7ce9580e..e739b33d1d1 100644
--- a/chromium/third_party/blink/renderer/core/html/media/html_media_test_helper.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/html_media_test_helper.cc
@@ -13,11 +13,18 @@ MediaStubLocalFrameClient::MediaStubLocalFrameClient(
std::unique_ptr<WebMediaPlayer> player)
: player_(std::move(player)) {}
+MediaStubLocalFrameClient::MediaStubLocalFrameClient(
+ std::unique_ptr<WebMediaPlayer> player,
+ bool allow_empty_player)
+ : player_(std::move(player)), allow_empty_player_(allow_empty_player) {}
+
std::unique_ptr<WebMediaPlayer> MediaStubLocalFrameClient::CreateWebMediaPlayer(
HTMLMediaElement&,
const WebMediaPlayerSource&,
WebMediaPlayerClient*) {
- DCHECK(player_) << " Empty injected player - already used?";
+ if (!allow_empty_player_)
+ DCHECK(player_) << " Empty injected player - already used?";
+
return std::move(player_);
}
diff --git a/chromium/third_party/blink/renderer/core/html/media/html_media_test_helper.h b/chromium/third_party/blink/renderer/core/html/media/html_media_test_helper.h
index 96bf556d529..0981db7c3a0 100644
--- a/chromium/third_party/blink/renderer/core/html/media/html_media_test_helper.h
+++ b/chromium/third_party/blink/renderer/core/html/media/html_media_test_helper.h
@@ -17,6 +17,8 @@ namespace test {
class MediaStubLocalFrameClient : public EmptyLocalFrameClient {
public:
explicit MediaStubLocalFrameClient(std::unique_ptr<WebMediaPlayer>);
+ MediaStubLocalFrameClient(std::unique_ptr<WebMediaPlayer>,
+ bool allow_empty_player);
std::unique_ptr<WebMediaPlayer> CreateWebMediaPlayer(
HTMLMediaElement&,
@@ -25,6 +27,7 @@ class MediaStubLocalFrameClient : public EmptyLocalFrameClient {
private:
std::unique_ptr<WebMediaPlayer> player_;
+ bool allow_empty_player_ = false;
DISALLOW_COPY_AND_ASSIGN(MediaStubLocalFrameClient);
};
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 b4c0d7be2ab..50740ddcf2a 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
@@ -28,9 +28,12 @@
#include <memory>
#include "base/bind_helpers.h"
+#include "base/metrics/histogram_functions.h"
#include "cc/paint/paint_canvas.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink.h"
#include "third_party/blink/public/platform/web_fullscreen_video_status.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_fullscreen_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h"
#include "third_party/blink/renderer/core/css/css_property_names.h"
#include "third_party/blink/renderer/core/dom/attribute.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -40,18 +43,16 @@
#include "third_party/blink/renderer/core/frame/picture_in_picture_controller.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
-#include "third_party/blink/renderer/core/fullscreen/fullscreen_options.h"
#include "third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.h"
-#include "third_party/blink/renderer/core/html/media/media_element_parser_helpers.h"
#include "third_party/blink/renderer/core/html/media/media_remoting_interstitial.h"
#include "third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.h"
-#include "third_party/blink/renderer/core/html/media/video_request_animation_frame.h"
+#include "third_party/blink/renderer/core/html/media/video_frame_callback_requester.h"
#include "third_party/blink/renderer/core/html/media/video_wake_lock.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/core/imagebitmap/image_bitmap.h"
-#include "third_party/blink/renderer/core/imagebitmap/image_bitmap_options.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
+#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.h"
#include "third_party/blink/renderer/core/layout/layout_image.h"
#include "third_party/blink/renderer/core/layout/layout_video.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
@@ -59,7 +60,6 @@
#include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
#include "third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.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/web_test_support.h"
@@ -68,13 +68,11 @@ namespace blink {
namespace {
-constexpr float kMostlyFillViewportThreshold = 0.85f;
-
// This enum is used to record histograms. Do not reorder.
enum VideoPersistenceControlsType {
- kVideoPersistenceControlsTypeNative = 0,
- kVideoPersistenceControlsTypeCustom,
- kVideoPersistenceControlsTypeCount
+ kNative = 0,
+ kCustom = 1,
+ kMaxValue = 1,
};
} // anonymous namespace
@@ -83,23 +81,23 @@ HTMLVideoElement::HTMLVideoElement(Document& document)
: HTMLMediaElement(html_names::kVideoTag, document),
remoting_interstitial_(nullptr),
picture_in_picture_interstitial_(nullptr),
- in_overlay_fullscreen_video_(false) {
+ is_persistent_(false),
+ is_auto_picture_in_picture_(false),
+ in_overlay_fullscreen_video_(false),
+ is_effectively_fullscreen_(false),
+ is_default_overridden_intrinsic_size_(
+ !document.IsMediaDocument() &&
+ !document.IsFeatureEnabled(
+ mojom::blink::DocumentPolicyFeature::kUnsizedMedia)),
+ video_has_played_(false),
+ mostly_filling_viewport_(false) {
if (document.GetSettings()) {
default_poster_url_ =
AtomicString(document.GetSettings()->GetDefaultVideoPosterURL());
}
- if (RuntimeEnabledFeatures::VideoFullscreenDetectionEnabled()) {
- custom_controls_fullscreen_detector_ =
- MakeGarbageCollected<MediaCustomControlsFullscreenDetector>(*this);
- }
-
- if (media_element_parser_helpers::IsMediaElement(this) &&
- !document.IsFeatureEnabled(mojom::FeaturePolicyFeature::kUnsizedMedia)) {
- is_default_overridden_intrinsic_size_ = true;
- overridden_intrinsic_size_ =
- IntSize(LayoutReplaced::kDefaultWidth, LayoutReplaced::kDefaultHeight);
- }
+ custom_controls_fullscreen_detector_ =
+ MakeGarbageCollected<MediaCustomControlsFullscreenDetector>(*this);
wake_lock_ = MakeGarbageCollected<VideoWakeLock>(*this);
@@ -113,7 +111,6 @@ void HTMLVideoElement::Trace(Visitor* visitor) {
visitor->Trace(wake_lock_);
visitor->Trace(remoting_interstitial_);
visitor->Trace(picture_in_picture_interstitial_);
- visitor->Trace(viewport_intersection_observer_);
Supplementable<HTMLVideoElement>::Trace(visitor);
HTMLMediaElement::Trace(visitor);
}
@@ -125,7 +122,7 @@ bool HTMLVideoElement::HasPendingActivity() const {
Node::InsertionNotificationRequest HTMLVideoElement::InsertedInto(
ContainerNode& insertion_point) {
- if (insertion_point.isConnected() && custom_controls_fullscreen_detector_)
+ if (insertion_point.isConnected())
custom_controls_fullscreen_detector_->Attach();
return HTMLMediaElement::InsertedInto(insertion_point);
@@ -133,18 +130,14 @@ Node::InsertionNotificationRequest HTMLVideoElement::InsertedInto(
void HTMLVideoElement::RemovedFrom(ContainerNode& insertion_point) {
HTMLMediaElement::RemovedFrom(insertion_point);
-
- if (custom_controls_fullscreen_detector_)
- custom_controls_fullscreen_detector_->Detach();
+ custom_controls_fullscreen_detector_->Detach();
OnBecamePersistentVideo(false);
}
-void HTMLVideoElement::ContextDestroyed(ExecutionContext* context) {
- if (custom_controls_fullscreen_detector_)
- custom_controls_fullscreen_detector_->ContextDestroyed();
-
- HTMLMediaElement::ContextDestroyed(context);
+void HTMLVideoElement::ContextDestroyed() {
+ custom_controls_fullscreen_detector_->ContextDestroyed();
+ HTMLMediaElement::ContextDestroyed();
}
bool HTMLVideoElement::LayoutObjectIsNeeded(const ComputedStyle& style) const {
@@ -239,30 +232,26 @@ void HTMLVideoElement::ParseAttribute(
}
unsigned HTMLVideoElement::videoWidth() const {
- if (overridden_intrinsic_size_.Width() > 0)
- return overridden_intrinsic_size_.Width();
+ if (is_default_overridden_intrinsic_size_)
+ return LayoutReplaced::kDefaultWidth;
if (!GetWebMediaPlayer())
return 0;
- return GetWebMediaPlayer()->NaturalSize().width;
+ return GetWebMediaPlayer()->NaturalSize().width();
}
unsigned HTMLVideoElement::videoHeight() const {
- if (overridden_intrinsic_size_.Height() > 0)
- return overridden_intrinsic_size_.Height();
+ if (is_default_overridden_intrinsic_size_)
+ return LayoutReplaced::kDefaultHeight;
if (!GetWebMediaPlayer())
return 0;
- return GetWebMediaPlayer()->NaturalSize().height;
+ return GetWebMediaPlayer()->NaturalSize().height();
}
IntSize HTMLVideoElement::videoVisibleSize() const {
- return GetWebMediaPlayer() ? IntSize(GetWebMediaPlayer()->VisibleRect())
+ return GetWebMediaPlayer() ? IntSize(GetWebMediaPlayer()->VisibleSize())
: IntSize();
}
-IntSize HTMLVideoElement::GetOverriddenIntrinsicSize() const {
- return overridden_intrinsic_size_;
-}
-
bool HTMLVideoElement::IsURLAttribute(const Attribute& attribute) const {
return attribute.GetName() == html_names::kPosterAttr ||
HTMLMediaElement::IsURLAttribute(attribute);
@@ -294,6 +283,14 @@ void HTMLVideoElement::SetDisplayMode(DisplayMode mode) {
GetLayoutObject()->UpdateFromElement();
}
+void HTMLVideoElement::UpdatePictureInPictureAvailability() {
+ if (!web_media_player_)
+ return;
+
+ web_media_player_->OnPictureInPictureAvailabilityChanged(
+ SupportsPictureInPicture());
+}
+
// TODO(zqzhang): this callback could be used to hide native controls instead of
// using a settings. See `HTMLMediaElement::onMediaControlsEnabledChange`.
void HTMLVideoElement::OnBecamePersistentVideo(bool value) {
@@ -303,13 +300,10 @@ void HTMLVideoElement::OnBecamePersistentVideo(bool value) {
// Record the type of video. If it is already fullscreen, it is a video with
// native controls, otherwise it is assumed to be with custom controls.
// This is only recorded when entering this mode.
- DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram,
- ("Media.VideoPersistence.ControlsType",
- kVideoPersistenceControlsTypeCount));
- if (IsFullscreen())
- histogram.Count(kVideoPersistenceControlsTypeNative);
- else
- histogram.Count(kVideoPersistenceControlsTypeCustom);
+ base::UmaHistogramEnumeration("Media.VideoPersistence.ControlsType",
+ IsFullscreen()
+ ? VideoPersistenceControlsType::kNative
+ : VideoPersistenceControlsType::kCustom);
Element* fullscreen_element =
Fullscreen::FullscreenElementFrom(GetDocument());
@@ -351,22 +345,6 @@ void HTMLVideoElement::OnBecamePersistentVideo(bool value) {
GetWebMediaPlayer()->OnDisplayTypeChanged(DisplayType());
}
-void HTMLVideoElement::ActivateViewportIntersectionMonitoring(bool activate) {
- if (activate && !viewport_intersection_observer_) {
- viewport_intersection_observer_ = IntersectionObserver::Create(
- {}, {kMostlyFillViewportThreshold}, &(GetDocument()),
- WTF::BindRepeating(&HTMLVideoElement::OnViewportIntersectionChanged,
- WrapWeakPersistent(this)),
- IntersectionObserver::kDeliverDuringPostLifecycleSteps,
- IntersectionObserver::kFractionOfRoot);
- viewport_intersection_observer_->observe(this);
- } else if (!activate && viewport_intersection_observer_) {
- viewport_intersection_observer_->disconnect();
- viewport_intersection_observer_ = nullptr;
- mostly_filling_viewport_ = false;
- }
-}
-
bool HTMLVideoElement::IsPersistent() const {
return is_persistent_;
}
@@ -379,6 +357,11 @@ void HTMLVideoElement::UpdateDisplayState() {
}
void HTMLVideoElement::OnPlay() {
+ if (!video_has_played_) {
+ video_has_played_ = true;
+ UpdatePictureInPictureAvailability();
+ }
+
if (!RuntimeEnabledFeatures::VideoAutoFullscreenEnabled() ||
FastHasAttribute(html_names::kPlaysinlineAttr)) {
return;
@@ -402,6 +385,8 @@ void HTMLVideoElement::OnLoadFinished() {
WrapWeakPersistent(this)));
lazy_load_intersection_observer_->observe(this);
}
+
+ UpdatePictureInPictureAvailability();
}
void HTMLVideoElement::PaintCurrentFrame(
@@ -491,7 +476,7 @@ bool HTMLVideoElement::PrepareVideoFrameForWebGL(
gpu::gles2::GLES2Interface* gl,
GLenum target,
GLuint texture,
- bool already_uploaded_id,
+ int already_uploaded_id,
WebMediaPlayer::VideoFrameUploadMetadata* out_metadata) {
if (!GetWebMediaPlayer())
return false;
@@ -553,8 +538,10 @@ void HTMLVideoElement::DidEnterFullscreen() {
// Cache this in case the player is destroyed before leaving fullscreen.
in_overlay_fullscreen_video_ = UsesOverlayFullscreenVideo();
if (in_overlay_fullscreen_video_) {
- GetDocument().GetLayoutView()->Compositor()->SetNeedsCompositingUpdate(
- kCompositingUpdateRebuildTree);
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ auto* compositor = GetDocument().GetLayoutView()->Compositor();
+ compositor->SetNeedsCompositingUpdate(kCompositingUpdateRebuildTree);
+ }
}
}
@@ -567,8 +554,10 @@ void HTMLVideoElement::DidExitFullscreen() {
}
if (in_overlay_fullscreen_video_) {
- GetDocument().GetLayoutView()->Compositor()->SetNeedsCompositingUpdate(
- kCompositingUpdateRebuildTree);
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ auto* compositor = GetDocument().GetLayoutView()->Compositor();
+ compositor->SetNeedsCompositingUpdate(kCompositingUpdateRebuildTree);
+ }
}
in_overlay_fullscreen_video_ = false;
@@ -582,13 +571,7 @@ void HTMLVideoElement::DidMoveToNewDocument(Document& old_document) {
if (image_loader_)
image_loader_->ElementDidMoveToNewDocument();
- if (viewport_intersection_observer_) {
- ActivateViewportIntersectionMonitoring(false);
- ActivateViewportIntersectionMonitoring(true);
- }
-
wake_lock_->ElementDidMoveToNewDocument();
-
HTMLMediaElement::DidMoveToNewDocument(old_document);
}
@@ -627,14 +610,8 @@ scoped_refptr<Image> HTMLVideoElement::GetSourceImageForCanvas(
// 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::Create(
- intrinsic_size,
- CanvasResourceProvider::ResourceUsage::kSoftwareResourceUsage,
- nullptr, // context_provider_wrapper
- 0, // msaa_sample_count
- kLow_SkFilterQuality, CanvasColorParams(),
- CanvasResourceProvider::kDefaultPresentationMode,
- nullptr); // canvas_resource_dispatcher
+ CanvasResourceProvider::CreateBitmapProvider(
+ intrinsic_size, kLow_SkFilterQuality, CanvasColorParams());
if (!resource_provider) {
*status = kInvalidSourceImageStatus;
return nullptr;
@@ -656,7 +633,9 @@ bool HTMLVideoElement::WouldTaintOrigin() const {
return !IsMediaDataCorsSameOrigin();
}
-FloatSize HTMLVideoElement::ElementSize(const FloatSize&) const {
+FloatSize HTMLVideoElement::ElementSize(
+ const FloatSize&,
+ const RespectImageOrientationEnum) const {
return FloatSize(videoWidth(), videoHeight());
}
@@ -668,26 +647,28 @@ ScriptPromise HTMLVideoElement::CreateImageBitmap(
ScriptState* script_state,
EventTarget& event_target,
base::Optional<IntRect> crop_rect,
- const ImageBitmapOptions* options) {
+ const ImageBitmapOptions* options,
+ ExceptionState& exception_state) {
DCHECK(event_target.ToLocalDOMWindow());
if (getNetworkState() == HTMLMediaElement::kNetworkEmpty) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "The provided element has not retrieved data."));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "The provided element has not retrieved data.");
+ return ScriptPromise();
}
if (getReadyState() <= HTMLMediaElement::kHaveMetadata) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "The provided element's player has no current data."));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "The provided element's player has no current data.");
+ return ScriptPromise();
}
return ImageBitmapSource::FulfillImageBitmap(
- script_state, ImageBitmap::Create(
- this, crop_rect,
- event_target.ToLocalDOMWindow()->document(), options));
+ script_state,
+ MakeGarbageCollected<ImageBitmap>(
+ this, crop_rect, event_target.ToLocalDOMWindow()->document(),
+ options),
+ exception_state);
}
void HTMLVideoElement::MediaRemotingStarted(
@@ -729,6 +710,17 @@ bool HTMLVideoElement::IsInAutoPIP() const {
return is_auto_picture_in_picture_;
}
+void HTMLVideoElement::RequestEnterPictureInPicture() {
+ PictureInPictureController::From(GetDocument())
+ .EnterPictureInPicture(this, nullptr /* promise */,
+ nullptr /* options */);
+}
+
+void HTMLVideoElement::RequestExitPictureInPicture() {
+ PictureInPictureController::From(GetDocument())
+ .ExitPictureInPicture(this, nullptr);
+}
+
void HTMLVideoElement::OnPictureInPictureStateChange() {
if (DisplayType() != WebMediaPlayer::DisplayType::kPictureInPicture ||
IsInAutoPIP()) {
@@ -772,13 +764,21 @@ void HTMLVideoElement::SetIsEffectivelyFullscreen(
blink::WebFullscreenVideoStatus status) {
is_effectively_fullscreen_ =
status != blink::WebFullscreenVideoStatus::kNotEffectivelyFullscreen;
-
if (GetWebMediaPlayer()) {
GetWebMediaPlayer()->SetIsEffectivelyFullscreen(status);
GetWebMediaPlayer()->OnDisplayTypeChanged(DisplayType());
}
}
+void HTMLVideoElement::SetIsDominantVisibleContent(bool is_dominant) {
+ if (mostly_filling_viewport_ != is_dominant) {
+ mostly_filling_viewport_ = is_dominant;
+ auto* player = GetWebMediaPlayer();
+ if (player)
+ player->BecameDominantVisibleContent(mostly_filling_viewport_);
+ }
+}
+
void HTMLVideoElement::AddedEventListener(
const AtomicString& event_type,
RegisteredEventListener& registered_listener) {
@@ -797,18 +797,6 @@ bool HTMLVideoElement::IsRemotingInterstitialVisible() const {
return remoting_interstitial_ && remoting_interstitial_->IsVisible();
}
-void HTMLVideoElement::OnViewportIntersectionChanged(
- const HeapVector<Member<IntersectionObserverEntry>>& entries) {
- const bool is_mostly_filling_viewport =
- (entries.back()->intersectionRatio() >= kMostlyFillViewportThreshold);
- if (mostly_filling_viewport_ == is_mostly_filling_viewport)
- return;
-
- mostly_filling_viewport_ = is_mostly_filling_viewport;
- if (web_media_player_)
- web_media_player_->BecameDominantVisibleContent(mostly_filling_viewport_);
-}
-
void HTMLVideoElement::OnIntersectionChangedForLazyLoad(
const HeapVector<Member<IntersectionObserverEntry>>& entries) {
bool is_visible = (entries.back()->intersectionRatio() > 0);
@@ -821,21 +809,22 @@ void HTMLVideoElement::OnIntersectionChangedForLazyLoad(
}
void HTMLVideoElement::OnWebMediaPlayerCreated() {
- if (RuntimeEnabledFeatures::VideoRequestAnimationFrameEnabled()) {
- if (auto* video_raf = VideoRequestAnimationFrame::From(*this))
- video_raf->OnWebMediaPlayerCreated();
+ if (RuntimeEnabledFeatures::RequestVideoFrameCallbackEnabled()) {
+ if (auto* vfc_requester = VideoFrameCallbackRequester::From(*this))
+ vfc_requester->OnWebMediaPlayerCreated();
}
}
-void HTMLVideoElement::OnRequestAnimationFrame(
- base::TimeTicks presentation_time,
- base::TimeTicks expected_presentation_time,
- uint32_t presented_frames_counter,
- const media::VideoFrame& presented_frame) {
- DCHECK(RuntimeEnabledFeatures::VideoRequestAnimationFrameEnabled());
- VideoRequestAnimationFrame::From(*this)->OnRequestAnimationFrame(
- presentation_time, expected_presentation_time, presented_frames_counter,
- presented_frame);
+void HTMLVideoElement::AttributeChanged(
+ const AttributeModificationParams& params) {
+ HTMLElement::AttributeChanged(params);
+ if (params.name == html_names::kDisablepictureinpictureAttr)
+ UpdatePictureInPictureAvailability();
+}
+
+void HTMLVideoElement::OnRequestVideoFrameCallback() {
+ DCHECK(RuntimeEnabledFeatures::RequestVideoFrameCallbackEnabled());
+ VideoFrameCallbackRequester::From(*this)->OnRequestVideoFrameCallback();
}
} // namespace blink
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 3c1874cc9a8..5fb512df678 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
@@ -71,7 +71,6 @@ class CORE_EXPORT HTMLVideoElement final
IntSize videoVisibleSize() const;
- IntSize GetOverriddenIntrinsicSize() const;
bool IsDefaultIntrinsicSize() const {
return is_default_overridden_intrinsic_size_;
}
@@ -147,7 +146,7 @@ class CORE_EXPORT HTMLVideoElement final
gpu::gles2::GLES2Interface*,
GLenum target,
GLuint texture,
- bool already_uploaded_id,
+ int already_uploaded_id,
WebMediaPlayer::VideoFrameUploadMetadata* out_metadata);
bool ShouldDisplayPosterImage() const { return GetDisplayMode() == kPoster; }
@@ -162,7 +161,8 @@ class CORE_EXPORT HTMLVideoElement final
const FloatSize&) override;
bool IsVideoElement() const override { return true; }
bool WouldTaintOrigin() const override;
- FloatSize ElementSize(const FloatSize&) const override;
+ FloatSize ElementSize(const FloatSize&,
+ const RespectImageOrientationEnum) const override;
const KURL& SourceURL() const override { return currentSrc(); }
bool IsHTMLVideoElement() const override { return true; }
// Video elements currently always go through RAM when used as a canvas image
@@ -174,15 +174,12 @@ class CORE_EXPORT HTMLVideoElement final
ScriptPromise CreateImageBitmap(ScriptState*,
EventTarget&,
base::Optional<IntRect> crop_rect,
- const ImageBitmapOptions*) override;
+ const ImageBitmapOptions*,
+ ExceptionState&) override;
// WebMediaPlayerClient implementation.
void OnBecamePersistentVideo(bool) final;
- void ActivateViewportIntersectionMonitoring(bool) final;
- void OnRequestAnimationFrame(base::TimeTicks presentation_time,
- base::TimeTicks expected_presentation_time,
- uint32_t presented_frames_counter,
- const media::VideoFrame& presented_frame) final;
+ void OnRequestVideoFrameCallback() final;
bool IsPersistent() const;
@@ -193,6 +190,8 @@ class CORE_EXPORT HTMLVideoElement final
void MediaRemotingStopped(int error_code) final;
WebMediaPlayer::DisplayType DisplayType() const final;
bool IsInAutoPIP() const final;
+ void RequestEnterPictureInPicture() final;
+ void RequestExitPictureInPicture() final;
void OnPictureInPictureStateChange() final;
// Used by the PictureInPictureController as callback when the video element
@@ -201,6 +200,7 @@ class CORE_EXPORT HTMLVideoElement final
void OnExitedPictureInPicture();
void SetIsEffectivelyFullscreen(blink::WebFullscreenVideoStatus);
+ void SetIsDominantVisibleContent(bool is_dominant);
void SetImageForTest(ImageResourceContent* content) {
if (!image_loader_)
@@ -218,14 +218,16 @@ class CORE_EXPORT HTMLVideoElement final
void OnWebMediaPlayerCreated() final;
+ void AttributeChanged(const AttributeModificationParams& params) override;
+
private:
friend class MediaCustomControlsFullscreenDetectorTest;
friend class HTMLMediaElementEventListenersTest;
friend class HTMLVideoElementPersistentTest;
friend class VideoFillingViewportTest;
- // ContextLifecycleStateObserver functions.
- void ContextDestroyed(ExecutionContext*) final;
+ // ExecutionContextLifecycleStateObserver functions.
+ void ContextDestroyed() final;
bool LayoutObjectIsNeeded(const ComputedStyle&) const override;
LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override;
@@ -246,8 +248,8 @@ class CORE_EXPORT HTMLVideoElement final
void DidMoveToNewDocument(Document& old_document) override;
void SetDisplayMode(DisplayMode) override;
- void OnViewportIntersectionChanged(
- const HeapVector<Member<IntersectionObserverEntry>>& entries);
+ void UpdatePictureInPictureAvailability();
+
void OnIntersectionChangedForLazyLoad(
const HeapVector<Member<IntersectionObserverEntry>>& entries);
@@ -264,28 +266,26 @@ class CORE_EXPORT HTMLVideoElement final
// Represents whether the video is 'persistent'. It is used for videos with
// custom controls that are in auto-pip (Android). This boolean is used by a
// CSS rule.
- bool is_persistent_ = false;
+ bool is_persistent_ : 1;
// Whether the video is currently in auto-pip (Android). It is not similar to
// a video being in regular Picture-in-Picture mode.
- bool is_auto_picture_in_picture_ = false;
+ bool is_auto_picture_in_picture_ : 1;
// Whether this element is in overlay fullscreen mode.
- bool in_overlay_fullscreen_video_;
+ bool in_overlay_fullscreen_video_ : 1;
// Whether the video element should be considered as fullscreen with regards
// to display type and other UI features. This does not mean the DOM element
// is fullscreen.
- bool is_effectively_fullscreen_ = false;
+ bool is_effectively_fullscreen_ : 1;
- IntSize overridden_intrinsic_size_;
- bool is_default_overridden_intrinsic_size_;
+ bool is_default_overridden_intrinsic_size_ : 1;
- // The following is always false unless viewport intersection monitoring is
- // turned on via ActivateViewportIntersectionMonitoring().
- bool mostly_filling_viewport_ = false;
+ bool video_has_played_ : 1;
- Member<IntersectionObserver> viewport_intersection_observer_;
+ // True, if the video element occupies most of the viewport.
+ bool mostly_filling_viewport_ : 1;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/media/html_video_element_persistent_test.cc b/chromium/third_party/blink/renderer/core/html/media/html_video_element_persistent_test.cc
index 28eb8331c21..5fa7e5ae10b 100644
--- a/chromium/third_party/blink/renderer/core/html/media/html_video_element_persistent_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/html_video_element_persistent_test.cc
@@ -8,8 +8,8 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_fullscreen_options.h"
#include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
-#include "third_party/blink/renderer/core/fullscreen/fullscreen_options.h"
#include "third_party/blink/renderer/core/html/html_div_element.h"
#include "third_party/blink/renderer/core/loader/empty_clients.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
@@ -21,7 +21,10 @@ namespace {
class FullscreenMockChromeClient : public EmptyChromeClient {
public:
- MOCK_METHOD2(EnterFullscreen, void(LocalFrame&, const FullscreenOptions*));
+ MOCK_METHOD3(EnterFullscreen,
+ void(LocalFrame&,
+ const FullscreenOptions*,
+ bool for_cross_process_descendant));
MOCK_METHOD1(ExitFullscreen, void(LocalFrame&));
};
@@ -40,7 +43,7 @@ class HTMLVideoElementPersistentTest : public PageTestBase {
clients.chrome_client = chrome_client_.Get();
PageTestBase::SetupPageWithClients(&clients);
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<body><div><video></video></div></body>");
}
@@ -59,7 +62,8 @@ class HTMLVideoElementPersistentTest : public PageTestBase {
FullscreenMockChromeClient& GetMockChromeClient() { return *chrome_client_; }
void SimulateDidEnterFullscreen() {
- Fullscreen::DidEnterFullscreen(GetDocument());
+ Fullscreen::DidResolveEnterFullscreenRequest(GetDocument(),
+ true /* granted */);
}
void SimulateDidExitFullscreen() {
@@ -97,7 +101,7 @@ TEST_F(HTMLVideoElementPersistentTest, nothingIsFullscreen) {
TEST_F(HTMLVideoElementPersistentTest, videoIsFullscreen) {
EXPECT_EQ(FullscreenElement(), nullptr);
- EXPECT_CALL(GetMockChromeClient(), EnterFullscreen(_, _)).Times(1);
+ EXPECT_CALL(GetMockChromeClient(), EnterFullscreen(_, _, _)).Times(1);
EXPECT_CALL(GetMockChromeClient(), ExitFullscreen(_)).Times(0);
LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
@@ -123,7 +127,7 @@ TEST_F(HTMLVideoElementPersistentTest, videoIsFullscreen) {
TEST_F(HTMLVideoElementPersistentTest, divIsFullscreen) {
EXPECT_EQ(FullscreenElement(), nullptr);
- EXPECT_CALL(GetMockChromeClient(), EnterFullscreen(_, _)).Times(1);
+ EXPECT_CALL(GetMockChromeClient(), EnterFullscreen(_, _, _)).Times(1);
EXPECT_CALL(GetMockChromeClient(), ExitFullscreen(_)).Times(0);
LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
@@ -156,7 +160,7 @@ TEST_F(HTMLVideoElementPersistentTest, divIsFullscreen) {
TEST_F(HTMLVideoElementPersistentTest, exitFullscreenBeforePersistence) {
EXPECT_EQ(FullscreenElement(), nullptr);
- EXPECT_CALL(GetMockChromeClient(), EnterFullscreen(_, _)).Times(1);
+ EXPECT_CALL(GetMockChromeClient(), EnterFullscreen(_, _, _)).Times(1);
EXPECT_CALL(GetMockChromeClient(), ExitFullscreen(_)).Times(1);
LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
@@ -185,7 +189,7 @@ TEST_F(HTMLVideoElementPersistentTest, exitFullscreenBeforePersistence) {
TEST_F(HTMLVideoElementPersistentTest, internalPseudoClassOnlyUAStyleSheet) {
EXPECT_EQ(FullscreenElement(), nullptr);
- EXPECT_CALL(GetMockChromeClient(), EnterFullscreen(_, _)).Times(1);
+ EXPECT_CALL(GetMockChromeClient(), EnterFullscreen(_, _, _)).Times(1);
EXPECT_CALL(GetMockChromeClient(), ExitFullscreen(_)).Times(0);
DummyExceptionStateForTesting exception_state;
@@ -233,7 +237,7 @@ TEST_F(HTMLVideoElementPersistentTest, internalPseudoClassOnlyUAStyleSheet) {
TEST_F(HTMLVideoElementPersistentTest, removeContainerWhilePersisting) {
EXPECT_EQ(FullscreenElement(), nullptr);
- EXPECT_CALL(GetMockChromeClient(), EnterFullscreen(_, _)).Times(1);
+ EXPECT_CALL(GetMockChromeClient(), EnterFullscreen(_, _, _)).Times(1);
EXPECT_CALL(GetMockChromeClient(), ExitFullscreen(_)).Times(1);
LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
@@ -254,7 +258,7 @@ TEST_F(HTMLVideoElementPersistentTest, removeContainerWhilePersisting) {
TEST_F(HTMLVideoElementPersistentTest, removeVideoWhilePersisting) {
EXPECT_EQ(FullscreenElement(), nullptr);
- EXPECT_CALL(GetMockChromeClient(), EnterFullscreen(_, _)).Times(1);
+ EXPECT_CALL(GetMockChromeClient(), EnterFullscreen(_, _, _)).Times(1);
EXPECT_CALL(GetMockChromeClient(), ExitFullscreen(_)).Times(0);
LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
@@ -280,7 +284,7 @@ TEST_F(HTMLVideoElementPersistentTest, removeVideoWithLayerWhilePersisting) {
DivElement()->AppendChild(span);
span->AppendChild(VideoElement());
- EXPECT_CALL(GetMockChromeClient(), EnterFullscreen(_, _)).Times(1);
+ EXPECT_CALL(GetMockChromeClient(), EnterFullscreen(_, _, _)).Times(1);
EXPECT_CALL(GetMockChromeClient(), ExitFullscreen(_)).Times(0);
LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
@@ -301,7 +305,7 @@ TEST_F(HTMLVideoElementPersistentTest, removeVideoWithLayerWhilePersisting) {
TEST_F(HTMLVideoElementPersistentTest, containsPersistentVideoScopedToFS) {
EXPECT_EQ(FullscreenElement(), nullptr);
- EXPECT_CALL(GetMockChromeClient(), EnterFullscreen(_, _)).Times(1);
+ EXPECT_CALL(GetMockChromeClient(), EnterFullscreen(_, _, _)).Times(1);
EXPECT_CALL(GetMockChromeClient(), ExitFullscreen(_)).Times(0);
LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
diff --git a/chromium/third_party/blink/renderer/core/html/media/html_video_element_test.cc b/chromium/third_party/blink/renderer/core/html/media/html_video_element_test.cc
index 954f311ad05..d18d9a18204 100644
--- a/chromium/third_party/blink/renderer/core/html/media/html_video_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/html_video_element_test.cc
@@ -24,6 +24,8 @@ using testing::_;
namespace blink {
+namespace {
+
class HTMLVideoElementMockMediaPlayer : public EmptyWebMediaPlayer {
public:
MOCK_METHOD1(SetIsEffectivelyFullscreen, void(WebFullscreenVideoStatus));
@@ -31,13 +33,14 @@ class HTMLVideoElementMockMediaPlayer : public EmptyWebMediaPlayer {
MOCK_CONST_METHOD0(HasAvailableVideoFrame, bool());
};
+} // namespace
+
class HTMLVideoElementTest : public PageTestBase {
public:
void SetUp() override {
auto mock_media_player =
std::make_unique<HTMLVideoElementMockMediaPlayer>();
media_player_ = mock_media_player.get();
-
SetupPageWithClients(nullptr,
MakeGarbageCollected<test::MediaStubLocalFrameClient>(
std::move(mock_media_player)),
@@ -74,14 +77,16 @@ TEST_F(HTMLVideoElementTest, PictureInPictureInterstitialAndTextContainer) {
video()->UpdateTextTrackDisplay();
// Simulate entering Picture-in-Picture.
- EXPECT_CALL(*MockWebMediaPlayer(), OnDisplayTypeChanged(_));
+ EXPECT_CALL(*MockWebMediaPlayer(),
+ OnDisplayTypeChanged(WebMediaPlayer::DisplayType::kInline));
video()->OnEnteredPictureInPicture();
// Simulate that text track are displayed again.
video()->UpdateTextTrackDisplay();
EXPECT_EQ(3u, video()->EnsureUserAgentShadowRoot().CountChildren());
-
+ EXPECT_CALL(*MockWebMediaPlayer(),
+ OnDisplayTypeChanged(WebMediaPlayer::DisplayType::kInline));
// Reset cc::layer to avoid crashes depending on timing.
SetFakeCcLayer(nullptr);
}
@@ -94,13 +99,18 @@ TEST_F(HTMLVideoElementTest, PictureInPictureInterstitial_Reattach) {
video()->SetSrc("http://example.com/foo.mp4");
test::RunPendingTasks();
- EXPECT_CALL(*MockWebMediaPlayer(), OnDisplayTypeChanged(_));
+ EXPECT_CALL(*MockWebMediaPlayer(),
+ OnDisplayTypeChanged(WebMediaPlayer::DisplayType::kInline));
EXPECT_CALL(*MockWebMediaPlayer(), HasAvailableVideoFrame())
.WillRepeatedly(testing::Return(true));
// Simulate entering Picture-in-Picture.
video()->OnEnteredPictureInPicture();
+ EXPECT_CALL(*MockWebMediaPlayer(),
+ OnDisplayTypeChanged(WebMediaPlayer::DisplayType::kInline))
+ .Times(3);
+
// Try detaching and reattaching. This should not crash.
GetDocument().body()->removeChild(video());
GetDocument().body()->appendChild(video());
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 79fdf9fa33b..9955b98391a 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
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
+#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -19,22 +20,64 @@ using blink::WebFullscreenVideoStatus;
namespace {
-constexpr base::TimeDelta kCheckFullscreenInterval =
- base::TimeDelta::FromSeconds(1);
-constexpr float kMostlyFillViewportThresholdOfOccupationProportion = 0.85f;
-constexpr float kMostlyFillViewportThresholdOfVisibleProportion = 0.75f;
+// If a video takes more that this much of the viewport, it's counted as
+// fullscreen without applying the fullscreen heuristics.
+// (Assuming we're in the fullscreen mode.)
+constexpr float kMostlyFillViewportIntersectionThreshold = 0.85f;
+
+// If a video takes less that this much of the viewport, we don't
+// apply the fullscreen heuristics and just declare it not fullscreen.
+// A portrait ultrawide video (21:9) playing on a landscape ultrawide screen
+// takes about 18% of the screen, that's why 15% looks like a reasonable
+// lowerbound of a real-world fullscreen video.
+constexpr float kMinPossibleFullscreenIntersectionThreshold = 0.15f;
+
+// This is how much of the viewport around the video can be taken by
+// margins and framing for it to still be counted as fullscreen.
+// It is measured only in the dominant direction, because of potential ratio
+// mismatch that would cause big margins in the other direction.
+// For example: portrain video on a landscape screen.
+constexpr float kMaxAllowedVideoMarginRatio = 0.15;
+
+// This is how much of the video can be hidden by something
+// before it is nor longer counted as fullscreen.
+// This helps to disregard custom controls, ads, accidental markup mistakes.
+constexpr float kMaxAllowedPortionOfVideoOffScreen = 0.25;
+
+// This heuristic handles a case of videos with an aspect ratio
+// different from the screen's aspect ratio.
+// Examples: A 4:3 video playing on a 16:9 screen.
+// A portrait video playing on a landscape screen.
+// In a nutshell:
+// 1. The video should occupy most of the viewport in at least one dimension.
+// 2. The video should be almost fully visible on the screen.
+bool IsFullscreenVideoOfDifferentRatio(const IntSize& video_size,
+ const IntSize& viewport_size,
+ const IntSize& intersection_size) {
+ if (video_size.IsEmpty() || viewport_size.IsEmpty())
+ return false;
+
+ const float x_occupation_proportion =
+ 1.0f * intersection_size.Width() / viewport_size.Width();
+ const float y_occupation_proportion =
+ 1.0f * intersection_size.Height() / viewport_size.Height();
+
+ // The video should occupy most of the viewport in at least one dimension.
+ if (std::max(x_occupation_proportion, y_occupation_proportion) <
+ (1.0 - kMaxAllowedVideoMarginRatio)) {
+ return false;
+ }
+
+ // The video should be almost fully visible on the screen.
+ return video_size.Area() * (1.0 - kMaxAllowedPortionOfVideoOffScreen) <=
+ intersection_size.Area();
+}
} // anonymous namespace
MediaCustomControlsFullscreenDetector::MediaCustomControlsFullscreenDetector(
HTMLVideoElement& video)
- : video_element_(video),
- viewport_intersection_observer_(nullptr),
- check_viewport_intersection_timer_(
- video.GetDocument().GetTaskRunner(TaskType::kInternalMedia),
- this,
- &MediaCustomControlsFullscreenDetector::
- OnCheckViewportIntersectionTimerFired) {
+ : video_element_(video), viewport_intersection_observer_(nullptr) {
if (VideoElement().isConnected())
Attach();
}
@@ -46,13 +89,31 @@ void MediaCustomControlsFullscreenDetector::Attach() {
event_type_names::kWebkitfullscreenchange, this, true);
VideoElement().GetDocument().addEventListener(
event_type_names::kFullscreenchange, this, true);
+
+ // Ideally we'd like to monitor all minute intersection changes here,
+ // because any change can potentially affect the fullscreen heuristics,
+ // but it's not practical from perf point of view. Given that the heuristics
+ // are more of a guess that exact science, it wouldn't be well spent CPU
+ // cycles anyway. That's why the observer only triggers on 10% steps in
+ // viewport area occupation.
+ const WTF::Vector<float> thresholds{
+ kMinPossibleFullscreenIntersectionThreshold,
+ 0.2,
+ 0.3,
+ 0.4,
+ 0.5,
+ 0.6,
+ 0.7,
+ 0.8,
+ kMostlyFillViewportIntersectionThreshold};
viewport_intersection_observer_ = IntersectionObserver::Create(
- {}, {}, &(video_element_->GetDocument()),
+ {}, thresholds, &(video_element_->GetDocument()),
WTF::BindRepeating(
&MediaCustomControlsFullscreenDetector::OnIntersectionChanged,
WrapWeakPersistent(this)),
IntersectionObserver::kDeliverDuringPostLifecycleSteps,
- IntersectionObserver::kFractionOfTarget, 0, false, true);
+ IntersectionObserver::kFractionOfRoot, 0, false, true);
+ viewport_intersection_observer_->observe(&VideoElement());
}
void MediaCustomControlsFullscreenDetector::Detach() {
@@ -66,48 +127,10 @@ void MediaCustomControlsFullscreenDetector::Detach() {
event_type_names::kWebkitfullscreenchange, this, true);
VideoElement().GetDocument().removeEventListener(
event_type_names::kFullscreenchange, this, true);
- check_viewport_intersection_timer_.Stop();
-
VideoElement().SetIsEffectivelyFullscreen(
WebFullscreenVideoStatus::kNotEffectivelyFullscreen);
}
-bool MediaCustomControlsFullscreenDetector::ComputeIsDominantVideoForTests(
- const IntSize& target_size,
- const IntSize& root_size,
- const IntSize& intersection_size) {
- if (target_size.IsEmpty() || root_size.IsEmpty())
- return false;
-
- const float x_occupation_proportion =
- 1.0f * intersection_size.Width() / root_size.Width();
- const float y_occupation_proportion =
- 1.0f * intersection_size.Height() / root_size.Height();
-
- // If the viewport is mostly occupied by the video, return true.
- if (std::min(x_occupation_proportion, y_occupation_proportion) >=
- kMostlyFillViewportThresholdOfOccupationProportion) {
- return true;
- }
-
- // If neither of the dimensions of the viewport is mostly occupied by the
- // video, return false.
- if (std::max(x_occupation_proportion, y_occupation_proportion) <
- kMostlyFillViewportThresholdOfOccupationProportion) {
- return false;
- }
-
- // If the video is mostly visible in the indominant dimension, return true.
- // Otherwise return false.
- if (x_occupation_proportion > y_occupation_proportion) {
- return target_size.Height() *
- kMostlyFillViewportThresholdOfVisibleProportion <
- intersection_size.Height();
- }
- return target_size.Width() * kMostlyFillViewportThresholdOfVisibleProportion <
- intersection_size.Width();
-}
-
void MediaCustomControlsFullscreenDetector::Invoke(ExecutionContext* context,
Event* event) {
DCHECK(event->type() == event_type_names::kLoadedmetadata ||
@@ -118,52 +141,16 @@ void MediaCustomControlsFullscreenDetector::Invoke(ExecutionContext* context,
if (VideoElement().getReadyState() < HTMLMediaElement::kHaveMetadata)
return;
- if (!VideoElement().isConnected() || !IsVideoOrParentFullscreen()) {
- check_viewport_intersection_timer_.Stop();
-
- VideoElement().SetIsEffectivelyFullscreen(
- WebFullscreenVideoStatus::kNotEffectivelyFullscreen);
- return;
- }
-
- check_viewport_intersection_timer_.StartOneShot(kCheckFullscreenInterval,
- FROM_HERE);
+ TriggerObservation();
}
void MediaCustomControlsFullscreenDetector::ContextDestroyed() {
Detach();
}
-void MediaCustomControlsFullscreenDetector::
- OnCheckViewportIntersectionTimerFired(TimerBase*) {
- DCHECK(IsVideoOrParentFullscreen());
- if (viewport_intersection_observer_)
- viewport_intersection_observer_->observe(&VideoElement());
-}
-
-void MediaCustomControlsFullscreenDetector::OnIntersectionChanged(
- const HeapVector<Member<IntersectionObserverEntry>>& entries) {
- if (!viewport_intersection_observer_ || !VideoElement().GetLayoutObject())
- return;
-
- // We only want a single notification, then stop observing.
- viewport_intersection_observer_->disconnect();
-
- const IntersectionGeometry& geometry = entries.back()->GetGeometry();
-
- // Target and intersection rects must be converted from CSS to device pixels.
- float zoom = VideoElement().GetLayoutObject()->StyleRef().EffectiveZoom();
- PhysicalSize target_size = geometry.TargetRect().size;
- target_size.Scale(zoom);
- PhysicalSize intersection_size = geometry.IntersectionRect().size;
- intersection_size.Scale(zoom);
- PhysicalSize root_size = geometry.RootRect().size;
-
- bool is_dominant = ComputeIsDominantVideoForTests(
- RoundedIntSize(target_size), RoundedIntSize(root_size),
- RoundedIntSize(intersection_size));
-
- if (!is_dominant) {
+void MediaCustomControlsFullscreenDetector::ReportEffectivelyFullscreen(
+ bool effectively_fullscreen) {
+ if (!effectively_fullscreen) {
VideoElement().SetIsEffectivelyFullscreen(
WebFullscreenVideoStatus::kNotEffectivelyFullscreen);
return;
@@ -174,6 +161,7 @@ void MediaCustomControlsFullscreenDetector::OnIntersectionChanged(
!RuntimeEnabledFeatures::PictureInPictureEnabled() &&
!VideoElement().FastHasAttribute(
html_names::kDisablepictureinpictureAttr);
+
if (picture_in_picture_allowed) {
VideoElement().SetIsEffectivelyFullscreen(
WebFullscreenVideoStatus::kFullscreenAndPictureInPictureEnabled);
@@ -183,6 +171,57 @@ void MediaCustomControlsFullscreenDetector::OnIntersectionChanged(
}
}
+void MediaCustomControlsFullscreenDetector::OnIntersectionChanged(
+ const HeapVector<Member<IntersectionObserverEntry>>& entries) {
+ if (!viewport_intersection_observer_ || entries.IsEmpty())
+ return;
+
+ auto* layout = VideoElement().GetLayoutObject();
+ if (!layout || entries.back()->intersectionRatio() <
+ kMinPossibleFullscreenIntersectionThreshold) {
+ // Video is not shown at all.
+ VideoElement().SetIsDominantVisibleContent(false);
+ ReportEffectivelyFullscreen(false);
+ return;
+ }
+
+ const bool is_mostly_filling_viewport =
+ entries.back()->intersectionRatio() >=
+ kMostlyFillViewportIntersectionThreshold;
+ VideoElement().SetIsDominantVisibleContent(is_mostly_filling_viewport);
+
+ if (!IsVideoOrParentFullscreen()) {
+ // The video is outside of a fullscreen element.
+ // This is definitely not a fullscreen video experience.
+ ReportEffectivelyFullscreen(false);
+ return;
+ }
+
+ if (is_mostly_filling_viewport) {
+ // Video takes most part (85%) of the screen, report fullscreen.
+ ReportEffectivelyFullscreen(true);
+ return;
+ }
+
+ const IntersectionGeometry& geometry = entries.back()->GetGeometry();
+ IntSize target_size = RoundedIntSize(geometry.TargetRect().size);
+ IntSize intersection_size = RoundedIntSize(geometry.IntersectionRect().size);
+ IntSize root_size = RoundedIntSize(geometry.RootRect().size);
+
+ ReportEffectivelyFullscreen(IsFullscreenVideoOfDifferentRatio(
+ target_size, root_size, intersection_size));
+}
+
+void MediaCustomControlsFullscreenDetector::TriggerObservation() {
+ if (!viewport_intersection_observer_)
+ return;
+
+ // Removing and re-adding the observable element is just a way to
+ // trigger the observation callback and reevaluate the intersection ratio.
+ viewport_intersection_observer_->unobserve(&VideoElement());
+ viewport_intersection_observer_->observe(&VideoElement());
+}
+
bool MediaCustomControlsFullscreenDetector::IsVideoOrParentFullscreen() {
Element* fullscreen_element =
Fullscreen::FullscreenElementFrom(VideoElement().GetDocument());
@@ -198,4 +237,14 @@ void MediaCustomControlsFullscreenDetector::Trace(Visitor* visitor) {
visitor->Trace(viewport_intersection_observer_);
}
+// static
+bool MediaCustomControlsFullscreenDetector::
+ IsFullscreenVideoOfDifferentRatioForTesting(
+ const IntSize& video_size,
+ const IntSize& viewport_size,
+ const IntSize& intersection_size) {
+ return IsFullscreenVideoOfDifferentRatio(video_size, viewport_size,
+ intersection_size);
+}
+
} // namespace blink
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 a03841b66e9..fcd75bfd8a9 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
@@ -13,13 +13,19 @@
namespace blink {
class HTMLVideoElement;
-class IntSize;
class TimerBase;
+// This class tracks the state and size of HTMLVideoElement and reports to it
+// two signals
+// 1. If a given video occupies a large part of the viewport (85%),
+// it is reported via HTMLVideoElement::SetIsDominantVisibleContent.
+// 2. If a given video occupies a large part of the viewport (85%) and
+// any of the video's parent elements are in fullscreen mode, it is reported
+// via SetIsEffectivelyFullscreen.
class CORE_EXPORT MediaCustomControlsFullscreenDetector final
: public NativeEventListener {
public:
- explicit MediaCustomControlsFullscreenDetector(HTMLVideoElement&);
+ explicit MediaCustomControlsFullscreenDetector(HTMLVideoElement& video);
void Attach();
void Detach();
@@ -29,6 +35,7 @@ class CORE_EXPORT MediaCustomControlsFullscreenDetector final
void Invoke(ExecutionContext*, Event*) override;
void Trace(Visitor*) override;
+ void TriggerObservation();
private:
friend class MediaCustomControlsFullscreenDetectorTest;
@@ -39,18 +46,16 @@ class CORE_EXPORT MediaCustomControlsFullscreenDetector final
void OnCheckViewportIntersectionTimerFired(TimerBase*);
void OnIntersectionChanged(
const HeapVector<Member<IntersectionObserverEntry>>&);
-
bool IsVideoOrParentFullscreen();
-
- static bool ComputeIsDominantVideoForTests(const IntSize& target_size,
- const IntSize& root_size,
- const IntSize& intersection_size);
+ void ReportEffectivelyFullscreen(bool);
+ static bool IsFullscreenVideoOfDifferentRatioForTesting(
+ const IntSize& video_size,
+ const IntSize& viewport_size,
+ const IntSize& intersection_size);
// `video_element_` owns |this|.
Member<HTMLVideoElement> video_element_;
Member<IntersectionObserver> viewport_intersection_observer_;
- TaskRunnerTimer<MediaCustomControlsFullscreenDetector>
- check_viewport_intersection_timer_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector_test.cc b/chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector_test.cc
index 1fec7c4877c..b8523b8b409 100644
--- a/chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector_test.cc
@@ -13,23 +13,7 @@
namespace blink {
-namespace {
-
-struct VideoTestParam {
- String description;
- IntRect target_rect;
- bool expected_result;
-};
-
-} // anonymous namespace
-
-class MediaCustomControlsFullscreenDetectorTest
- : public testing::Test,
- private ScopedVideoFullscreenDetectionForTest {
- public:
- MediaCustomControlsFullscreenDetectorTest()
- : ScopedVideoFullscreenDetectionForTest(true) {}
-
+class MediaCustomControlsFullscreenDetectorTest : public testing::Test {
protected:
void SetUp() override {
page_holder_ = std::make_unique<DummyPageHolder>();
@@ -66,12 +50,11 @@ class MediaCustomControlsFullscreenDetectorTest
return false;
}
- static bool ComputeIsDominantVideo(const IntRect& target_rect,
- const IntRect& root_rect,
- const IntRect& intersection_rect) {
+ static bool IsFullscreen(IntRect target, IntRect screen) {
+ IntRect intersection = Intersection(target, screen);
return MediaCustomControlsFullscreenDetector::
- ComputeIsDominantVideoForTests(target_rect.Size(), root_rect.Size(),
- intersection_rect.Size());
+ IsFullscreenVideoOfDifferentRatioForTesting(
+ target.Size(), screen.Size(), intersection.Size());
}
private:
@@ -80,33 +63,30 @@ class MediaCustomControlsFullscreenDetectorTest
Persistent<HTMLVideoElement> video_;
};
-TEST_F(MediaCustomControlsFullscreenDetectorTest, computeIsDominantVideo) {
- // TestWithParam cannot be applied here as IntRect needs the memory allocator
- // to be initialized, but the array of parameters is statically initialized,
- // which is before the memory allocation initialization.
- VideoTestParam test_params[] = {
- {"xCompleteFill", {0, 0, 100, 50}, true},
- {"yCompleteFill", {0, 0, 50, 100}, true},
- {"xyCompleteFill", {0, 0, 100, 100}, true},
- {"xIncompleteFillTooSmall", {0, 0, 84, 50}, false},
- {"yIncompleteFillTooSmall", {0, 0, 50, 84}, false},
- {"xIncompleteFillJustRight", {0, 0, 86, 50}, true},
- {"yIncompleteFillJustRight", {0, 0, 50, 86}, true},
- {"xVisibleProportionTooSmall", {-26, 0, 100, 100}, false},
- {"yVisibleProportionTooSmall", {0, -26, 100, 100}, false},
- {"xVisibleProportionJustRight", {-24, 0, 100, 100}, true},
- {"yVisibleProportionJustRight", {0, -24, 100, 100}, true},
- };
-
- IntRect root_rect(0, 0, 100, 100);
-
- for (const VideoTestParam& test_param : test_params) {
- const IntRect& target_rect = test_param.target_rect;
- IntRect intersection_rect = Intersection(target_rect, root_rect);
- EXPECT_EQ(test_param.expected_result,
- ComputeIsDominantVideo(target_rect, root_rect, intersection_rect))
- << test_param.description << " failed";
- }
+TEST_F(MediaCustomControlsFullscreenDetectorTest, heuristicForAspectRatios) {
+ IntRect screen(0, 0, 1920, 1080);
+
+ EXPECT_TRUE(IsFullscreen({0, 130, 1920, 820}, screen))
+ << "Ultrawide screen (21:9)";
+ EXPECT_TRUE(IsFullscreen({240, 0, 1440, 1080}, screen))
+ << "Standard TV (4:3)";
+ EXPECT_TRUE(IsFullscreen({656, 0, 607, 1080}, screen))
+ << "Full HD, but portrait (9:16)";
+
+ EXPECT_TRUE(IsFullscreen({0, -100, 1920, 1080}, screen))
+ << "Normal fullscreen video but scrolled a bit up.";
+ EXPECT_TRUE(IsFullscreen({100, 0, 1920, 1080}, screen))
+ << "Normal fullscreen video but scrolled a bit right.";
+
+ EXPECT_FALSE(IsFullscreen({0, -300, 1920, 1080}, screen))
+ << "Normal fullscreen video but scrolled a great deal up.";
+ EXPECT_FALSE(IsFullscreen({490, 0, 1920, 1080}, screen))
+ << "Normal fullscreen video but scrolled a great deal right.";
+
+ EXPECT_FALSE(IsFullscreen({0, 0, 800, 600}, screen)) << "Small video";
+ EXPECT_FALSE(IsFullscreen({500, 100, 1024, 768}, screen))
+ << "Another small video";
+ EXPECT_FALSE(IsFullscreen({0, 0, 0, 0}, screen)) << "Hidden video";
}
TEST_F(MediaCustomControlsFullscreenDetectorTest,
@@ -143,7 +123,7 @@ TEST_F(MediaCustomControlsFullscreenDetectorTest,
TEST_F(MediaCustomControlsFullscreenDetectorTest,
hasListenersAfterAddToDocumentByParser) {
- GetDocument().body()->SetInnerHTMLFromString("<body><video></video></body>");
+ GetDocument().body()->setInnerHTML("<body><video></video></body>");
EXPECT_TRUE(CheckEventListenerRegistered(GetDocument(),
event_type_names::kFullscreenchange,
diff --git a/chromium/third_party/blink/renderer/core/html/media/media_document.cc b/chromium/third_party/blink/renderer/core/html/media/media_document.cc
index 8050a56cda2..effd4c6e08b 100644
--- a/chromium/third_party/blink/renderer/core/html/media/media_document.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/media_document.cc
@@ -140,15 +140,15 @@ void MediaDocument::DefaultEventHandler(Event& event) {
if (!target_node)
return;
- if (event.type() == event_type_names::kKeydown && event.IsKeyboardEvent()) {
+ auto* keyboard_event = DynamicTo<KeyboardEvent>(event);
+ if (event.type() == event_type_names::kKeydown && keyboard_event) {
HTMLVideoElement* video =
Traversal<HTMLVideoElement>::FirstWithin(*target_node);
if (!video)
return;
- auto& keyboard_event = ToKeyboardEvent(event);
- if (keyboard_event.key() == " " ||
- keyboard_event.keyCode() == VKEY_MEDIA_PLAY_PAUSE) {
+ if (keyboard_event->key() == " " ||
+ keyboard_event->keyCode() == VKEY_MEDIA_PLAY_PAUSE) {
// space or media key (play/pause)
video->TogglePlayState();
event.SetDefaultHandled();
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 916c8525e61..eb358a1d903 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
@@ -6,43 +6,22 @@
#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/dom/element.h"
-#include "third_party/blink/renderer/core/frame/local_frame.h"
-#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
-#include "third_party/blink/renderer/core/html_element_type_helpers.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_view.h"
-#include "third_party/blink/renderer/core/svg_element_type_helpers.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
namespace media_element_parser_helpers {
-bool IsMediaElement(const Element* element) {
- if ((IsA<HTMLImageElement>(element) || IsA<SVGImageElement>(element)) &&
- !element->GetDocument().IsImageDocument())
- return true;
- if (IsA<HTMLVideoElement>(element) &&
- !element->GetDocument().IsMediaDocument())
- return true;
- return false;
-}
-
-void ReportUnsizedMediaViolation(const LayoutObject* layout_object,
- bool send_report) {
+void CheckUnsizedMediaViolation(const LayoutObject* layout_object,
+ bool send_report) {
const ComputedStyle& style = layout_object->StyleRef();
- if (!style.LogicalWidth().IsSpecified() &&
- !style.LogicalHeight().IsSpecified()) {
- layout_object->GetDocument().CountPotentialFeaturePolicyViolation(
- mojom::FeaturePolicyFeature::kUnsizedMedia);
- if (send_report) {
- layout_object->GetDocument().ReportFeaturePolicyViolation(
- mojom::FeaturePolicyFeature::kUnsizedMedia,
- mojom::FeaturePolicyDisposition::kEnforce);
- }
+ bool is_unsized = !style.LogicalWidth().IsSpecified() &&
+ !style.LogicalHeight().IsSpecified();
+ if (is_unsized) {
+ layout_object->GetDocument().IsFeatureEnabled(
+ mojom::blink::DocumentPolicyFeature::kUnsizedMedia,
+ send_report ? ReportOptions::kReportOnFailure
+ : ReportOptions::kDoNotReport);
}
}
diff --git a/chromium/third_party/blink/renderer/core/html/media/media_element_parser_helpers.h b/chromium/third_party/blink/renderer/core/html/media/media_element_parser_helpers.h
index 19082961385..57a1dd2d376 100644
--- a/chromium/third_party/blink/renderer/core/html/media/media_element_parser_helpers.h
+++ b/chromium/third_party/blink/renderer/core/html/media/media_element_parser_helpers.h
@@ -5,25 +5,18 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_MEDIA_ELEMENT_PARSER_HELPERS_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_MEDIA_ELEMENT_PARSER_HELPERS_H_
-#include "third_party/blink/renderer/platform/geometry/int_size.h"
-
namespace blink {
-class Element;
class LayoutObject;
namespace media_element_parser_helpers {
-// Returns true for elements that are either <img>, <svg:image> or <video> that
-// are not in an image or media document; returns false otherwise.
-bool IsMediaElement(const Element* element);
-
// When |layout_object| is not properly styled (according to
// FeaturePolicyFeature::kUnsizedMedia) this invocation counts a potential
// violation. If |send_report| is set, then an actual violation report is
// generated.
-void ReportUnsizedMediaViolation(const LayoutObject* layout_object,
- bool send_report);
+void CheckUnsizedMediaViolation(const LayoutObject* layout_object,
+ bool send_report);
} // namespace media_element_parser_helpers
diff --git a/chromium/third_party/blink/renderer/core/html/media/html_media_source.cc b/chromium/third_party/blink/renderer/core/html/media/media_source.cc
index 9eab808eed2..5122cb9f10c 100644
--- a/chromium/third_party/blink/renderer/core/html/media/html_media_source.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/media_source.cc
@@ -28,13 +28,13 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "third_party/blink/renderer/core/html/media/html_media_source.h"
+#include "third_party/blink/renderer/core/html/media/media_source.h"
namespace blink {
-URLRegistry* HTMLMediaSource::registry_ = nullptr;
+URLRegistry* MediaSource::registry_ = nullptr;
-void HTMLMediaSource::SetRegistry(URLRegistry* registry) {
+void MediaSource::SetRegistry(URLRegistry* registry) {
DCHECK(!registry_);
registry_ = registry;
}
diff --git a/chromium/third_party/blink/renderer/core/html/media/html_media_source.h b/chromium/third_party/blink/renderer/core/html/media/media_source.h
index 4e89100cea4..b1a935b4949 100644
--- a/chromium/third_party/blink/renderer/core/html/media/html_media_source.h
+++ b/chromium/third_party/blink/renderer/core/html/media/media_source.h
@@ -28,8 +28,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_HTML_MEDIA_SOURCE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_HTML_MEDIA_SOURCE_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_MEDIA_SOURCE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_MEDIA_SOURCE_H_
#include <memory>
#include "third_party/blink/public/platform/web_time_range.h"
@@ -45,25 +45,33 @@ class HTMLMediaElement;
class TimeRanges;
class TrackBase;
-class CORE_EXPORT HTMLMediaSource : public URLRegistrable,
- public GarbageCollectedMixin {
+class CORE_EXPORT MediaSource : public URLRegistrable,
+ public GarbageCollectedMixin {
public:
static void SetRegistry(URLRegistry*);
- static HTMLMediaSource* Lookup(const String& url) {
- return registry_ ? static_cast<HTMLMediaSource*>(registry_->Lookup(url))
+ static MediaSource* Lookup(const String& url) {
+ return registry_ ? static_cast<MediaSource*>(registry_->Lookup(url))
: nullptr;
}
- // Called when an HTMLMediaElement is attempting to attach to this object,
- // and helps enforce attachment to at most one element at a time.
- // If already attached, returns false. Otherwise, must be in
- // 'closed' state, and returns true to indicate attachment success.
+ // These two methods are called in sequence when an HTMLMediaElement is
+ // attempting to attach to this object. The WebMediaSource is not available
+ // to the element initially, so between the two calls, the attachment could be
+ // considered partially setup.
+ // If already attached, StartAttachingToMediaElement() returns false.
+ // Otherwise, must be in 'closed' state, and returns true to indicate
+ // attachment success.
+ // CompleteAttachingToMediaElement() provides the MediaSource with the
+ // underlying WebMediaSource, enabling parsing of media provided by the
+ // application for playback, for example.
// Reattachment allowed by first calling close() (even if already in
// 'closed').
// Once attached, the source uses the element to synchronously service some
// API operations like duration change that may need to initiate seek.
- virtual bool AttachToElement(HTMLMediaElement*) = 0;
- virtual void SetWebMediaSourceAndOpen(std::unique_ptr<WebMediaSource>) = 0;
+ virtual bool StartAttachingToMediaElement(HTMLMediaElement*) = 0;
+ virtual void CompleteAttachingToMediaElement(
+ std::unique_ptr<WebMediaSource>) = 0;
+
virtual void Close() = 0;
virtual bool IsClosed() const = 0;
virtual double duration() const = 0;
@@ -87,4 +95,4 @@ class CORE_EXPORT HTMLMediaSource : public URLRegistrable,
} // namespace blink
-#endif
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_MEDIA_SOURCE_H_
diff --git a/chromium/third_party/blink/renderer/core/html/media/video_auto_fullscreen_test.cc b/chromium/third_party/blink/renderer/core/html/media/video_auto_fullscreen_test.cc
index 254dcf9f5a7..261a8002fe4 100644
--- a/chromium/third_party/blink/renderer/core/html/media/video_auto_fullscreen_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/video_auto_fullscreen_test.cc
@@ -27,7 +27,9 @@ class VideoAutoFullscreenFrameHost : public FakeLocalFrameHost {
public:
VideoAutoFullscreenFrameHost() = default;
- void EnterFullscreen(mojom::blink::FullscreenOptionsPtr options) override {
+ void EnterFullscreen(mojom::blink::FullscreenOptionsPtr options,
+ EnterFullscreenCallback callback) override {
+ std::move(callback).Run(true);
Thread::Current()->GetTaskRunner()->PostTask(
FROM_HERE,
WTF::Bind(
diff --git a/chromium/third_party/blink/renderer/core/html/media/video_filling_viewport_test.cc b/chromium/third_party/blink/renderer/core/html/media/video_filling_viewport_test.cc
index 2c8002c0f01..65afd035488 100644
--- a/chromium/third_party/blink/renderer/core/html/media/video_filling_viewport_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/video_filling_viewport_test.cc
@@ -28,14 +28,9 @@ class VideoFillingViewportTest : public SimTest {
return element->mostly_filling_viewport_;
}
- void ActivateViewportIntersectionMonitoring(HTMLVideoElement* element,
- bool enable) {
- element->ActivateViewportIntersectionMonitoring(enable);
- EXPECT_EQ(enable, !!element->viewport_intersection_observer_);
- }
-
void DoCompositeAndPropagate() {
- Compositor().BeginFrame();
+ if (Compositor().NeedsBeginFrame())
+ Compositor().BeginFrame();
test::RunPendingTasks();
}
@@ -60,16 +55,10 @@ TEST_F(VideoFillingViewportTest, MostlyFillingViewport) {
)HTML");
Compositor().BeginFrame();
- HTMLVideoElement* element =
- ToElement<HTMLVideoElement>(GetDocument().getElementById("video"));
+ auto* element = To<HTMLVideoElement>(GetDocument().getElementById("video"));
- ActivateViewportIntersectionMonitoring(element, true);
DoCompositeAndPropagate();
EXPECT_TRUE(IsMostlyFillingViewport(element));
-
- ActivateViewportIntersectionMonitoring(element, false);
- EXPECT_FALSE(Compositor().NeedsBeginFrame());
- EXPECT_FALSE(IsMostlyFillingViewport(element));
}
TEST_F(VideoFillingViewportTest, NotMostlyFillingViewport) {
@@ -85,9 +74,7 @@ TEST_F(VideoFillingViewportTest, NotMostlyFillingViewport) {
)HTML");
Compositor().BeginFrame();
- HTMLVideoElement* element =
- ToElement<HTMLVideoElement>(GetDocument().getElementById("video"));
- ActivateViewportIntersectionMonitoring(element, true);
+ auto* element = To<HTMLVideoElement>(GetDocument().getElementById("video"));
DoCompositeAndPropagate();
EXPECT_FALSE(IsMostlyFillingViewport(element));
}
@@ -105,10 +92,8 @@ TEST_F(VideoFillingViewportTest, FillingViewportChanged) {
)HTML");
Compositor().BeginFrame();
- HTMLVideoElement* element =
- ToElement<HTMLVideoElement>(GetDocument().getElementById("video"));
+ auto* element = To<HTMLVideoElement>(GetDocument().getElementById("video"));
- ActivateViewportIntersectionMonitoring(element, true);
DoCompositeAndPropagate();
EXPECT_TRUE(IsMostlyFillingViewport(element));
@@ -132,10 +117,8 @@ TEST_F(VideoFillingViewportTest, LargeVideo) {
)HTML");
Compositor().BeginFrame();
- HTMLVideoElement* element =
- ToElement<HTMLVideoElement>(GetDocument().getElementById("video"));
+ auto* element = To<HTMLVideoElement>(GetDocument().getElementById("video"));
- ActivateViewportIntersectionMonitoring(element, true);
DoCompositeAndPropagate();
EXPECT_TRUE(IsMostlyFillingViewport(element));
}
@@ -153,10 +136,8 @@ TEST_F(VideoFillingViewportTest, VideoScrollOutHalf) {
)HTML");
Compositor().BeginFrame();
- HTMLVideoElement* element =
- ToElement<HTMLVideoElement>(GetDocument().getElementById("video"));
+ auto* element = To<HTMLVideoElement>(GetDocument().getElementById("video"));
- ActivateViewportIntersectionMonitoring(element, true);
DoCompositeAndPropagate();
EXPECT_TRUE(IsMostlyFillingViewport(element));
diff --git a/chromium/third_party/blink/renderer/core/html/media/video_request_animation_frame.cc b/chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.cc
index 42288d18ade..d0998e37e35 100644
--- a/chromium/third_party/blink/renderer/core/html/media/video_request_animation_frame.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.cc
@@ -2,29 +2,29 @@
// 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/media/video_request_animation_frame.h"
+#include "third_party/blink/renderer/core/html/media/video_frame_callback_requester.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
namespace blink {
-VideoRequestAnimationFrame::VideoRequestAnimationFrame(
+VideoFrameCallbackRequester::VideoFrameCallbackRequester(
HTMLVideoElement& element)
: Supplement<HTMLVideoElement>(element) {}
// static
-VideoRequestAnimationFrame* VideoRequestAnimationFrame::From(
+VideoFrameCallbackRequester* VideoFrameCallbackRequester::From(
HTMLVideoElement& element) {
- return Supplement<HTMLVideoElement>::From<VideoRequestAnimationFrame>(
+ return Supplement<HTMLVideoElement>::From<VideoFrameCallbackRequester>(
element);
}
-void VideoRequestAnimationFrame::Trace(blink::Visitor* visitor) {
+void VideoFrameCallbackRequester::Trace(Visitor* visitor) {
Supplement<HTMLVideoElement>::Trace(visitor);
}
// static
-const char VideoRequestAnimationFrame::kSupplementName[] =
- "VideoRequestAnimationFrame";
+const char VideoFrameCallbackRequester::kSupplementName[] =
+ "VideoFrameCallbackRequester";
} // namespace blink
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
new file mode 100644
index 00000000000..7f4dff1cb39
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.h
@@ -0,0 +1,42 @@
+// 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_HTML_MEDIA_VIDEO_FRAME_CALLBACK_REQUESTER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_VIDEO_FRAME_CALLBACK_REQUESTER_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/supplementable.h"
+
+namespace blink {
+
+class HTMLVideoElement;
+
+// Interface defining what the HTMLVideoElement should be aware
+// of in order to support the <video>.requestVideoFrameCallback() API.
+class CORE_EXPORT VideoFrameCallbackRequester
+ : public GarbageCollected<VideoFrameCallbackRequester>,
+ public Supplement<HTMLVideoElement> {
+ USING_GARBAGE_COLLECTED_MIXIN(VideoFrameCallbackRequester);
+
+ public:
+ static const char kSupplementName[];
+
+ static VideoFrameCallbackRequester* From(HTMLVideoElement&);
+
+ virtual ~VideoFrameCallbackRequester() = default;
+
+ void Trace(Visitor*) override;
+
+ virtual void OnWebMediaPlayerCreated() = 0;
+ virtual void OnRequestVideoFrameCallback() = 0;
+
+ protected:
+ explicit VideoFrameCallbackRequester(HTMLVideoElement&);
+ DISALLOW_COPY_AND_ASSIGN(VideoFrameCallbackRequester);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_VIDEO_FRAME_CALLBACK_REQUESTER_H_
diff --git a/chromium/third_party/blink/renderer/core/html/media/video_request_animation_frame.h b/chromium/third_party/blink/renderer/core/html/media/video_request_animation_frame.h
deleted file mode 100644
index 6fcfeb6ff07..00000000000
--- a/chromium/third_party/blink/renderer/core/html/media/video_request_animation_frame.h
+++ /dev/null
@@ -1,50 +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_HTML_MEDIA_VIDEO_REQUEST_ANIMATION_FRAME_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_VIDEO_REQUEST_ANIMATION_FRAME_H_
-
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
-#include "third_party/blink/renderer/platform/supplementable.h"
-
-namespace media {
-class VideoFrame;
-}
-
-namespace blink {
-
-class HTMLVideoElement;
-
-// Interface that defines the interfaces that HTMLVideoElement should be aware
-// of in order to support the <video>.requestAnimationFrame() API.
-class CORE_EXPORT VideoRequestAnimationFrame
- : public GarbageCollected<VideoRequestAnimationFrame>,
- public Supplement<HTMLVideoElement> {
- USING_GARBAGE_COLLECTED_MIXIN(VideoRequestAnimationFrame);
-
- public:
- static const char kSupplementName[];
-
- static VideoRequestAnimationFrame* From(HTMLVideoElement&);
-
- virtual ~VideoRequestAnimationFrame() = default;
-
- void Trace(blink::Visitor*) override;
-
- virtual void OnWebMediaPlayerCreated() = 0;
- virtual void OnRequestAnimationFrame(
- base::TimeTicks presentation_time,
- base::TimeTicks expected_presentation_time,
- uint32_t presented_frames_counter,
- const media::VideoFrame&) = 0;
-
- protected:
- explicit VideoRequestAnimationFrame(HTMLVideoElement&);
- DISALLOW_COPY_AND_ASSIGN(VideoRequestAnimationFrame);
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_VIDEO_REQUEST_ANIMATION_FRAME_H_
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 eebb27cd3c5..795497623bf 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
@@ -12,12 +12,13 @@
#include "third_party/blink/renderer/core/frame/picture_in_picture_controller.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/core/html/media/remote_playback_controller.h"
+#include "third_party/blink/renderer/core/page/page.h"
namespace blink {
VideoWakeLock::VideoWakeLock(HTMLVideoElement& video)
: PageVisibilityObserver(video.GetDocument().GetPage()),
- ContextLifecycleStateObserver(&video.GetDocument()),
+ ExecutionContextLifecycleStateObserver(video.GetExecutionContext()),
video_element_(video) {
VideoElement().addEventListener(event_type_names::kPlaying, this, true);
VideoElement().addEventListener(event_type_names::kPause, this, true);
@@ -36,8 +37,7 @@ VideoWakeLock::VideoWakeLock(HTMLVideoElement& video)
}
void VideoWakeLock::ElementDidMoveToNewDocument() {
- ContextLifecycleStateObserver::DidMoveToNewExecutionContext(
- &VideoElement().GetDocument());
+ SetExecutionContext(VideoElement().GetExecutionContext());
}
void VideoWakeLock::PageVisibilityChanged() {
@@ -47,7 +47,7 @@ void VideoWakeLock::PageVisibilityChanged() {
void VideoWakeLock::Trace(Visitor* visitor) {
NativeEventListener::Trace(visitor);
PageVisibilityObserver::Trace(visitor);
- ContextLifecycleStateObserver::Trace(visitor);
+ ExecutionContextLifecycleStateObserver::Trace(visitor);
visitor->Trace(video_element_);
}
@@ -78,7 +78,7 @@ void VideoWakeLock::ContextLifecycleStateChanged(mojom::FrameLifecycleState) {
Update();
}
-void VideoWakeLock::ContextDestroyed(ExecutionContext*) {
+void VideoWakeLock::ContextDestroyed() {
Update();
}
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 9565003d936..33f6d17a4de 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
@@ -9,7 +9,7 @@
#include "services/device/public/mojom/wake_lock.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h"
#include "third_party/blink/renderer/core/html/media/remote_playback_observer.h"
#include "third_party/blink/renderer/core/page/page_visibility_observer.h"
@@ -27,10 +27,11 @@ class HTMLVideoElement;
// merge all the requests and take the appropriate system wake lock.
// VideoWakeLock only uses "screen" related wake lock: it prevents the screen
// from locking on mobile or the lockscreen to show up on desktop.
-class CORE_EXPORT VideoWakeLock final : public NativeEventListener,
- public PageVisibilityObserver,
- public RemotePlaybackObserver,
- public ContextLifecycleStateObserver {
+class CORE_EXPORT VideoWakeLock final
+ : public NativeEventListener,
+ public PageVisibilityObserver,
+ public RemotePlaybackObserver,
+ public ExecutionContextLifecycleStateObserver {
USING_GARBAGE_COLLECTED_MIXIN(VideoWakeLock);
public:
@@ -47,9 +48,9 @@ class CORE_EXPORT VideoWakeLock final : public NativeEventListener,
void OnRemotePlaybackStateChanged(
mojom::blink::PresentationConnectionState) final;
- // ContextLifecycleStateObserver
+ // ExecutionContextLifecycleStateObserver
void ContextLifecycleStateChanged(mojom::FrameLifecycleState) override;
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
bool active_for_tests() const { return active_; }
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 f64b8f8756e..1ca7a8c4e0c 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
@@ -12,6 +12,7 @@
#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/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/picture_in_picture_controller.h"
#include "third_party/blink/renderer/core/html/media/html_media_test_helper.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
@@ -38,7 +39,7 @@ class VideoWakeLockPictureInPictureSession
void Update(uint32_t player_id,
const base::Optional<viz::SurfaceId>&,
- const blink::WebSize&,
+ const gfx::Size&,
bool show_play_pause_button) final {}
private:
@@ -62,7 +63,7 @@ class VideoWakeLockPictureInPictureService
void StartSession(
uint32_t,
const base::Optional<viz::SurfaceId>&,
- const blink::WebSize&,
+ const gfx::Size&,
bool,
mojo::PendingRemote<mojom::blink::PictureInPictureSessionObserver>,
StartSessionCallback callback) final {
@@ -70,7 +71,7 @@ class VideoWakeLockPictureInPictureService
session_.reset(new VideoWakeLockPictureInPictureSession(
session_remote.InitWithNewPipeAndPassReceiver()));
- std::move(callback).Run(std::move(session_remote), WebSize());
+ std::move(callback).Run(std::move(session_remote), gfx::Size());
}
private:
@@ -123,12 +124,12 @@ class VideoWakeLockTest : public PageTestBase {
void SetFakeCcLayer(cc::Layer* layer) { video_->SetCcLayer(layer); }
void SimulatePlaying() {
- video_wake_lock_->Invoke(&GetDocument(),
+ video_wake_lock_->Invoke(GetFrame().DomWindow(),
Event::Create(event_type_names::kPlaying));
}
void SimulatePause() {
- video_wake_lock_->Invoke(&GetDocument(),
+ video_wake_lock_->Invoke(GetFrame().DomWindow(),
Event::Create(event_type_names::kPause));
}
@@ -150,14 +151,18 @@ class VideoWakeLockTest : public PageTestBase {
}
void SimulateContextPause() {
- GetDocument().SetLifecycleState(mojom::FrameLifecycleState::kPaused);
+ GetFrame().DomWindow()->SetLifecycleState(
+ mojom::FrameLifecycleState::kPaused);
}
void SimulateContextRunning() {
- GetDocument().SetLifecycleState(mojom::FrameLifecycleState::kRunning);
+ GetFrame().DomWindow()->SetLifecycleState(
+ mojom::FrameLifecycleState::kRunning);
}
- void SimulateContextDestroyed() { GetDocument().NotifyContextDestroyed(); }
+ void SimulateContextDestroyed() {
+ GetFrame().DomWindow()->NotifyContextDestroyed();
+ }
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 83e917e1e90..43eb9f797d7 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/html/parser/BUILD.gn
@@ -35,6 +35,8 @@ blink_core_sources("parser") {
"html_meta_charset_parser.h",
"html_parser_idioms.cc",
"html_parser_idioms.h",
+ "html_parser_metrics.cc",
+ "html_parser_metrics.h",
"html_parser_options.cc",
"html_parser_options.h",
"html_parser_reentry_permit.cc",
@@ -62,6 +64,7 @@ blink_core_sources("parser") {
"input_stream_preprocessor.h",
"markup_tokenizer_inlines.h",
"nesting_level_incrementer.h",
+ "parser_scripting_flag_policy.h",
"parser_synchronization_policy.h",
"preload_request.cc",
"preload_request.h",
@@ -85,9 +88,7 @@ blink_core_sources("parser") {
}
fuzzer_test("blink_html_tokenizer_fuzzer") {
- sources = [
- "html_tokenizer_fuzzer.cc",
- ]
+ sources = [ "html_tokenizer_fuzzer.cc" ]
deps = [
"../../:core",
"../../../platform:blink_fuzzer_test_support",
diff --git a/chromium/third_party/blink/renderer/core/html/parser/OWNERS b/chromium/third_party/blink/renderer/core/html/parser/OWNERS
index 23b641cfa1f..2812e39384d 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/OWNERS
+++ b/chromium/third_party/blink/renderer/core/html/parser/OWNERS
@@ -1,6 +1,7 @@
+csharrison@chromium.org
kouhei@chromium.org
+masonfreed@chromium.org
yoavweiss@chromium.org
-csharrison@chromium.org
# TEAM: loading-dev@chromium.org
# COMPONENT: Blink>HTML>Parser
diff --git a/chromium/third_party/blink/renderer/core/html/parser/background_html_parser.cc b/chromium/third_party/blink/renderer/core/html/parser/background_html_parser.cc
index 83c6e31cef2..6bc906f027b 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/background_html_parser.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/background_html_parser.cc
@@ -33,7 +33,6 @@
#include "third_party/blink/renderer/core/html/parser/html_document_parser.h"
#include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h"
#include "third_party/blink/renderer/core/html_names.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -164,6 +163,7 @@ void BackgroundHTMLParser::Finish() {
}
void BackgroundHTMLParser::Stop() {
+ ClearParser();
delete this;
}
@@ -175,6 +175,10 @@ void BackgroundHTMLParser::ForcePlaintextForTextDocument() {
tokenizer_->SetState(HTMLTokenizer::kPLAINTEXTState);
}
+void BackgroundHTMLParser::ClearParser() {
+ parser_.Clear();
+}
+
void BackgroundHTMLParser::MarkEndOfFile() {
DCHECK(!input_.Current().IsClosed());
input_.Append(String(&kEndOfFileMarker, 1));
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 5b94d6ebf6a..de2b5d96511 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
@@ -56,7 +56,7 @@ class BackgroundHTMLParser {
public:
Configuration();
HTMLParserOptions options;
- base::WeakPtr<HTMLDocumentParser> parser;
+ WeakPersistent<HTMLDocumentParser> parser;
std::unique_ptr<TextResourceDecoder> decoder;
};
@@ -74,7 +74,7 @@ class BackgroundHTMLParser {
USING_FAST_MALLOC(Checkpoint);
public:
- base::WeakPtr<HTMLDocumentParser> parser;
+ WeakPersistent<HTMLDocumentParser> parser;
std::unique_ptr<HTMLToken> token;
std::unique_ptr<HTMLTokenizer> tokenizer;
HTMLTreeBuilderSimulator::State tree_builder_state;
@@ -93,6 +93,8 @@ class BackgroundHTMLParser {
void ForcePlaintextForTextDocument();
+ void ClearParser();
+
private:
BackgroundHTMLParser(std::unique_ptr<Configuration>,
scoped_refptr<base::SingleThreadTaskRunner>);
@@ -111,7 +113,7 @@ class BackgroundHTMLParser {
std::unique_ptr<HTMLTokenizer> tokenizer_;
HTMLTreeBuilderSimulator tree_builder_simulator_;
HTMLParserOptions options_;
- base::WeakPtr<HTMLDocumentParser> parser_;
+ WeakPersistent<HTMLDocumentParser> parser_;
CompactHTMLTokenStream pending_tokens_;
PreloadRequestStream pending_preloads_;
diff --git a/chromium/third_party/blink/renderer/core/html/parser/css_preload_scanner.cc b/chromium/third_party/blink/renderer/core/html/parser/css_preload_scanner.cc
index 1dd67036707..279776cb0b0 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/css_preload_scanner.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/css_preload_scanner.cc
@@ -236,7 +236,7 @@ static String ParseCSSStringOrURL(const String& string) {
}
void CSSPreloadScanner::EmitRule(const SegmentedString& source) {
- if (DeprecatedEqualIgnoringCase(rule_, "import")) {
+ if (EqualIgnoringASCIICase(rule_, "import")) {
String url = ParseCSSStringOrURL(rule_value_.ToString());
TextPosition position =
TextPosition(source.CurrentLine(), source.CurrentColumn());
@@ -250,7 +250,7 @@ void CSSPreloadScanner::EmitRule(const SegmentedString& source) {
requests_->push_back(std::move(request));
}
state_ = kInitial;
- } else if (DeprecatedEqualIgnoringCase(rule_, "charset"))
+ } else if (EqualIgnoringASCIICase(rule_, "charset"))
state_ = kInitial;
else
state_ = kDoneParsingImportRules;
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 e5b8596cb60..88bf8c170a1 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
@@ -300,7 +300,7 @@ void HTMLConstructionSite::AttachLater(ContainerNode* parent,
DCHECK(ScriptingContentIsAllowed(parser_content_policy_) || !element ||
!element->IsScriptElement());
DCHECK(PluginContentIsAllowed(parser_content_policy_) ||
- !IsHTMLPlugInElement(child));
+ !IsA<HTMLPlugInElement>(child));
HTMLConstructionSiteTask task(HTMLConstructionSiteTask::kInsert);
task.parent = parent;
@@ -572,16 +572,15 @@ void HTMLConstructionSite::SetCompatibilityModeFromDoctype(
"-//W3C//DTD HTML Experimental 970421//") ||
public_id.StartsWithIgnoringASCIICase("-//W3C//DTD W3 HTML//") ||
public_id.StartsWithIgnoringASCIICase("-//W3O//DTD W3 HTML 3.0//") ||
- DeprecatedEqualIgnoringCase(public_id,
- "-//W3O//DTD W3 HTML Strict 3.0//EN//") ||
+ EqualIgnoringASCIICase(public_id,
+ "-//W3O//DTD W3 HTML Strict 3.0//EN//") ||
public_id.StartsWithIgnoringASCIICase(
"-//WebTechs//DTD Mozilla HTML 2.0//") ||
public_id.StartsWithIgnoringASCIICase(
"-//WebTechs//DTD Mozilla HTML//") ||
- DeprecatedEqualIgnoringCase(public_id,
- "-/W3C/DTD HTML 4.0 Transitional/EN") ||
- DeprecatedEqualIgnoringCase(public_id, "HTML") ||
- DeprecatedEqualIgnoringCase(
+ EqualIgnoringASCIICase(public_id, "-/W3C/DTD HTML 4.0 Transitional/EN") ||
+ EqualIgnoringASCIICase(public_id, "HTML") ||
+ EqualIgnoringASCIICase(
system_id,
"http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd") ||
(system_id.IsEmpty() && public_id.StartsWithIgnoringASCIICase(
@@ -844,7 +843,7 @@ CreateElementFlags HTMLConstructionSite::GetCreateElementFlags() const {
: CreateElementFlags::ByParser();
}
-inline Document& HTMLConstructionSite::OwnerDocumentForCurrentNode() {
+Document& HTMLConstructionSite::OwnerDocumentForCurrentNode() {
if (auto* template_element = DynamicTo<HTMLTemplateElement>(*CurrentNode()))
return template_element->content()->GetDocument();
return CurrentNode()->GetDocument();
@@ -919,8 +918,15 @@ Element* HTMLConstructionSite::CreateElement(
// reactions stack."
CEReactionsScope reactions;
- // 7.
- element = definition->CreateAutonomousCustomElementSync(document, tag_name);
+ // "7. Let element be the result of creating an element given document,
+ // localName, given namespace, null, and is. If will execute script is true,
+ // set the synchronous custom elements flag; otherwise, leave it unset."
+ // TODO(crbug.com/1080673): We clear the CreatedbyParser flag here, so that
+ // elements get fully constructed. Some elements (e.g. HTMLInputElement)
+ // 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));
// "8. Append each attribute in the given token to element." We don't use
// setAttributes here because the custom element constructor may have
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 81914e59108..eb81ef312c7 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
@@ -43,6 +43,7 @@
#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html/parser/atomic_html_token.h"
#include "third_party/blink/renderer/core/html/parser/background_html_parser.h"
+#include "third_party/blink/renderer/core/html/parser/html_parser_metrics.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_scheduler.h"
#include "third_party/blink/renderer/core/html/parser/html_resource_preloader.h"
#include "third_party/blink/renderer/core/html/parser/html_tree_builder.h"
@@ -58,7 +59,6 @@
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.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/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -70,6 +70,16 @@
namespace blink {
+static size_t g_discarded_token_count_for_testing = 0;
+
+void ResetDiscardedTokenCountForTesting() {
+ g_discarded_token_count_for_testing = 0;
+}
+
+size_t GetDiscardedTokenCountForTesting() {
+ return g_discarded_token_count_for_testing;
+}
+
// 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(
@@ -89,7 +99,7 @@ static HTMLTokenizer::State TokenizerStateForContextElement(
context_tag.Matches(html_names::kIFrameTag) ||
context_tag.Matches(html_names::kNoembedTag) ||
(context_tag.Matches(html_names::kNoscriptTag) &&
- options.script_enabled) ||
+ options.scripting_flag) ||
context_tag.Matches(html_names::kNoframesTag))
return report_errors ? HTMLTokenizer::kRAWTEXTState
: HTMLTokenizer::kPLAINTEXTState;
@@ -101,6 +111,32 @@ static HTMLTokenizer::State TokenizerStateForContextElement(
return HTMLTokenizer::kDataState;
}
+class ScopedYieldTimer {
+ public:
+ // This object is created at the start of a block of parsing, and will
+ // report the time since the last block yielded if known.
+ ScopedYieldTimer(std::unique_ptr<base::ElapsedTimer>* timer,
+ HTMLParserMetrics* metrics_reporter)
+ : timer_(timer), reporting_metrics_(metrics_reporter) {
+ if (!reporting_metrics_ || !(*timer_))
+ return;
+
+ metrics_reporter->AddYieldInterval((*timer_)->Elapsed());
+ timer_->reset();
+ }
+
+ // The destructor creates a new timer, which will keep track of time until
+ // the next block starts.
+ ~ScopedYieldTimer() {
+ if (reporting_metrics_)
+ *timer_ = std::make_unique<base::ElapsedTimer>();
+ }
+
+ private:
+ std::unique_ptr<base::ElapsedTimer>* timer_;
+ bool reporting_metrics_;
+};
+
HTMLDocumentParser::HTMLDocumentParser(HTMLDocument& document,
ParserSynchronizationPolicy sync_policy)
: HTMLDocumentParser(document, kAllowScriptingContent, sync_policy) {
@@ -131,7 +167,6 @@ HTMLDocumentParser::HTMLDocumentParser(Document& document,
ParserContentPolicy content_policy,
ParserSynchronizationPolicy sync_policy)
: ScriptableDocumentParser(document, content_policy),
- ContextLifecycleStateObserver(&document),
options_(&document),
reentry_permit_(HTMLParserReentryPermit::Create()),
token_(sync_policy == kForceSynchronousParsing
@@ -160,7 +195,15 @@ HTMLDocumentParser::HTMLDocumentParser(Document& document,
// Threading is not allowed in prefetch mode.
DCHECK(!document.IsPrefetchOnly() || !ShouldUseThreading());
- UpdateStateIfNeeded();
+ // Report metrics for async document parsing only. The document
+ // must be main frame to meet UKM requirements, and must have a high
+ // resolution clock for high quality data.
+ if (sync_policy == kAllowAsynchronousParsing && document.GetFrame() &&
+ document.GetFrame()->IsMainFrame() &&
+ base::TimeTicks::IsHighResolution()) {
+ metrics_reporter_ = std::make_unique<HTMLParserMetrics>(
+ document.UkmSourceID(), document.UkmRecorder());
+ }
// Don't create preloader for parsing clipboard content.
if (content_policy == kDisallowScriptingAndPluginContent)
@@ -194,7 +237,6 @@ void HTMLDocumentParser::Trace(Visitor* visitor) {
visitor->Trace(script_runner_);
visitor->Trace(preloader_);
ScriptableDocumentParser::Trace(visitor);
- ContextLifecycleStateObserver::Trace(visitor);
HTMLParserScriptRunnerHost::Trace(visitor);
}
@@ -269,7 +311,7 @@ bool HTMLDocumentParser::IsParsingFragment() const {
}
void HTMLDocumentParser::PumpTokenizerIfPossible() {
- CheckIfBodyStylesheetAdded();
+ CheckIfBlockingStylesheetAdded();
if (IsStopped() || IsPaused())
return;
@@ -285,7 +327,9 @@ void HTMLDocumentParser::ResumeParsingAfterYield() {
DCHECK(ShouldUseThreading());
DCHECK(have_background_parser_);
- CheckIfBodyStylesheetAdded();
+ ScopedYieldTimer(&yield_timer_, metrics_reporter_.get());
+
+ CheckIfBlockingStylesheetAdded();
if (IsStopped() || IsPaused())
return;
@@ -301,7 +345,7 @@ void HTMLDocumentParser::RunScriptsForPausedTreeBuilder() {
// We will not have a scriptRunner when parsing a DocumentFragment.
if (script_runner_)
script_runner_->ProcessScriptElement(script_element, script_start_position);
- CheckIfBodyStylesheetAdded();
+ CheckIfBlockingStylesheetAdded();
}
bool HTMLDocumentParser::CanTakeNextToken() {
@@ -335,7 +379,8 @@ void HTMLDocumentParser::EnqueueTokenizedChunk(
// Note that on commit, the loader dispatched preloads for all the non-media
// links.
GetDocument()->Loader()->DispatchLinkHeaderPreloads(
- chunk->viewport, PreloadHelper::kOnlyLoadMedia);
+ base::OptionalOrNullptr(chunk->viewport),
+ PreloadHelper::kOnlyLoadMedia);
tried_loading_link_headers_ = true;
if (GetDocument()->Loader()->GetPrefetchedSignedExchangeManager()) {
// Link header preloads for prefetched signed exchanges won't be started
@@ -390,12 +435,8 @@ void HTMLDocumentParser::EnqueueTokenizedChunk(
speculations_.push_back(std::move(chunk));
- if (!IsPaused() && !IsScheduledForUnpause()) {
- if (GetDocument()->IsContextPaused())
- parser_scheduler_->ForceUnpauseAfterYield();
- else
- parser_scheduler_->ScheduleForUnpause();
- }
+ if (!IsPaused() && !IsScheduledForUnpause())
+ parser_scheduler_->ScheduleForUnpause();
}
void HTMLDocumentParser::DidReceiveEncodingDataFromBackgroundParser(
@@ -453,16 +494,14 @@ void HTMLDocumentParser::DiscardSpeculationsAndResumeFrom(
std::unique_ptr<TokenizedChunk> last_chunk_before_script,
std::unique_ptr<HTMLToken> token,
std::unique_ptr<HTMLTokenizer> tokenizer) {
- weak_factory_.InvalidateWeakPtrs();
+ // Clear back ref.
+ background_parser_->ClearParser();
size_t discarded_token_count = 0;
for (const auto& speculation : speculations_) {
discarded_token_count += speculation->tokens.size();
}
- DEFINE_STATIC_LOCAL(CustomCountHistogram, discarded_token_count_histogram,
- ("Parser.DiscardedTokenCount", 1, 100000, 50));
- discarded_token_count_histogram.Count(
- base::saturated_cast<base::Histogram::Sample>(discarded_token_count));
+ g_discarded_token_count_for_testing += discarded_token_count;
speculations_.clear();
pending_csp_meta_token_ = nullptr;
@@ -470,7 +509,7 @@ void HTMLDocumentParser::DiscardSpeculationsAndResumeFrom(
std::unique_ptr<BackgroundHTMLParser::Checkpoint> checkpoint =
std::make_unique<BackgroundHTMLParser::Checkpoint>();
- checkpoint->parser = weak_factory_.GetWeakPtr();
+ checkpoint->parser = this;
checkpoint->token = std::move(token);
checkpoint->tokenizer = std::move(tokenizer);
checkpoint->tree_builder_state =
@@ -490,7 +529,8 @@ void HTMLDocumentParser::DiscardSpeculationsAndResumeFrom(
}
size_t HTMLDocumentParser::ProcessTokenizedChunkFromBackgroundParser(
- std::unique_ptr<TokenizedChunk> pop_chunk) {
+ std::unique_ptr<TokenizedChunk> pop_chunk,
+ bool* reached_end_of_file) {
TRACE_EVENT_WITH_FLOW0(
"blink,loading",
"HTMLDocumentParser::processTokenizedChunkFromBackgroundParser",
@@ -551,6 +591,7 @@ size_t HTMLDocumentParser::ProcessTokenizedChunkFromBackgroundParser(
// There should never be any chunks after the EOF.
DCHECK(speculations_.IsEmpty());
PrepareToStopParsing();
+ *reached_end_of_file = true;
break;
}
@@ -595,17 +636,18 @@ void HTMLDocumentParser::PumpPendingSpeculations() {
probe::ParseHTML probe(GetDocument(), this);
SpeculationsPumpSession session(pump_speculations_session_nesting_level_);
+ bool reached_end_of_file = false;
while (!speculations_.IsEmpty()) {
DCHECK(!IsScheduledForUnpause());
- size_t element_token_count =
- ProcessTokenizedChunkFromBackgroundParser(speculations_.TakeFirst());
+ size_t element_token_count = ProcessTokenizedChunkFromBackgroundParser(
+ speculations_.TakeFirst(), &reached_end_of_file);
session.AddedElementTokens(element_token_count);
// Always check IsParsing first as document_ may be null. Surprisingly,
// IsScheduledForUnpause() may be set here as a result of
// ProcessTokenizedChunkFromBackgroundParser running arbitrary javascript
// which invokes nested event loops. (e.g. inspector breakpoints)
- CheckIfBodyStylesheetAdded();
+ CheckIfBlockingStylesheetAdded();
if (!IsParsing() || IsPaused() || IsScheduledForUnpause())
break;
@@ -614,6 +656,13 @@ void HTMLDocumentParser::PumpPendingSpeculations() {
session, speculations_.front()->starting_script))
break;
}
+
+ if (metrics_reporter_) {
+ metrics_reporter_->AddChunk(session.ElapsedTime(),
+ session.ProcessedElementTokens());
+ if (reached_end_of_file)
+ metrics_reporter_->ReportMetricsAtParseEnd();
+ }
}
void HTMLDocumentParser::ForcePlaintextForTextDocument() {
@@ -697,7 +746,7 @@ void HTMLDocumentParser::ConstructTreeFromHTMLToken() {
Token().Clear();
tree_builder_->ConstructTree(&atomic_token);
- CheckIfBodyStylesheetAdded();
+ CheckIfBlockingStylesheetAdded();
// FIXME: ConstructTree may synchronously cause Document to be detached.
if (!token_)
@@ -714,7 +763,7 @@ void HTMLDocumentParser::ConstructTreeFromCompactHTMLToken(
DCHECK(!GetDocument()->IsPrefetchOnly());
AtomicHTMLToken token(compact_token);
tree_builder_->ConstructTree(&token);
- CheckIfBodyStylesheetAdded();
+ CheckIfBlockingStylesheetAdded();
}
bool HTMLDocumentParser::HasInsertionPoint() {
@@ -775,7 +824,7 @@ void HTMLDocumentParser::StartBackgroundParser() {
std::unique_ptr<BackgroundHTMLParser::Configuration> config =
std::make_unique<BackgroundHTMLParser::Configuration>();
config->options = options_;
- config->parser = weak_factory_.GetWeakPtr();
+ config->parser = this;
config->decoder = TakeDecoder();
// The background parser is created on the main thread, but may otherwise
@@ -808,7 +857,6 @@ void HTMLDocumentParser::StopBackgroundParser() {
// Make this sync, as lsan triggers on some unittests if the task runner is
// used.
background_parser_->Stop();
- weak_factory_.InvalidateWeakPtrs();
}
void HTMLDocumentParser::Append(const String& input_source) {
@@ -1010,7 +1058,7 @@ void HTMLDocumentParser::ResumeParsingAfterPause() {
DCHECK(!IsExecutingScript());
DCHECK(!IsPaused());
- CheckIfBodyStylesheetAdded();
+ CheckIfBlockingStylesheetAdded();
if (IsStopped() || IsPaused())
return;
@@ -1099,7 +1147,7 @@ void HTMLDocumentParser::DidLoadAllPendingParserBlockingStylesheets() {
added_pending_parser_blocking_stylesheet_ = false;
}
-void HTMLDocumentParser::CheckIfBodyStylesheetAdded() {
+void HTMLDocumentParser::CheckIfBlockingStylesheetAdded() {
if (added_pending_parser_blocking_stylesheet_) {
added_pending_parser_blocking_stylesheet_ = false;
is_waiting_for_stylesheets_ = true;
@@ -1119,16 +1167,6 @@ void HTMLDocumentParser::ParseDocumentFragment(
parser->Detach();
}
-void HTMLDocumentParser::ContextLifecycleStateChanged(
- mojom::FrameLifecycleState state) {
- if (!parser_scheduler_)
- return;
- if (state == mojom::FrameLifecycleState::kRunning)
- parser_scheduler_->Unpause();
- else
- parser_scheduler_->Pause();
-}
-
void HTMLDocumentParser::AppendBytes(const char* data, size_t length) {
if (!length || IsStopped())
return;
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 9e98f0fe52f..ac73abc6eeb 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
@@ -32,7 +32,6 @@
#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"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.h"
#include "third_party/blink/renderer/core/html/parser/background_html_input_stream.h"
#include "third_party/blink/renderer/core/html/parser/html_input_stream.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_options.h"
@@ -59,14 +58,20 @@ class DocumentEncodingData;
class DocumentFragment;
class Element;
class HTMLDocument;
+class HTMLParserMetrics;
class HTMLParserScheduler;
class HTMLParserScriptRunner;
class HTMLPreloadScanner;
class HTMLResourcePreloader;
class HTMLTreeBuilder;
+// 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
+// different level, so it won't have to make assertions about internal state.
+void CORE_EXPORT ResetDiscardedTokenCountForTesting();
+size_t CORE_EXPORT GetDiscardedTokenCountForTesting();
+
class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser,
- public ContextLifecycleStateObserver,
private HTMLParserScriptRunnerHost {
USING_GARBAGE_COLLECTED_MIXIN(HTMLDocumentParser);
USING_PRE_FINALIZER(HTMLDocumentParser, Dispose);
@@ -102,8 +107,6 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser,
bool IsParsingAtLineNumber() const final;
OrdinalNumber LineNumber() const final;
- void ContextLifecycleStateChanged(mojom::FrameLifecycleState) final;
-
HTMLParserReentryPermit* ReentryPermit() { return reentry_permit_.get(); }
struct TokenizedChunk {
@@ -159,7 +162,7 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser,
void ExecuteScriptsWaitingForResources() final;
void DidAddPendingParserBlockingStylesheet() final;
void DidLoadAllPendingParserBlockingStylesheets() final;
- void CheckIfBodyStylesheetAdded();
+ void CheckIfBlockingStylesheetAdded();
void DocumentElementAvailable() override;
// HTMLParserScriptRunnerHost
@@ -178,7 +181,8 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser,
std::unique_ptr<HTMLToken>,
std::unique_ptr<HTMLTokenizer>);
size_t ProcessTokenizedChunkFromBackgroundParser(
- std::unique_ptr<TokenizedChunk>);
+ std::unique_ptr<TokenizedChunk>,
+ bool*);
void PumpPendingSpeculations();
bool CanTakeNextToken();
@@ -245,6 +249,11 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser,
Member<HTMLResourcePreloader> preloader_;
PreloadRequestStream queued_preloads_;
+ // Metrics gathering and reporting
+ std::unique_ptr<HTMLParserMetrics> metrics_reporter_;
+ // A timer for how long we are inactive after yielding
+ std::unique_ptr<base::ElapsedTimer> yield_timer_;
+
// If this is non-null, then there is a meta CSP token somewhere in the
// speculation buffer. Preloads will be deferred until a token matching this
// pointer is parsed and the CSP policy is applied. Note that this pointer
@@ -264,8 +273,6 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser,
bool tried_loading_link_headers_;
bool added_pending_parser_blocking_stylesheet_;
bool is_waiting_for_stylesheets_;
-
- base::WeakPtrFactory<HTMLDocumentParser> weak_factory_{this};
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_document_parser_loading_test.cc b/chromium/third_party/blink/renderer/core/html/parser/html_document_parser_loading_test.cc
index cf1a4f2c9a9..54ec8d65eb3 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_document_parser_loading_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_document_parser_loading_test.cc
@@ -8,7 +8,6 @@
#include "third_party/blink/renderer/core/dom/document.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/histogram_tester.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
namespace blink {
@@ -16,9 +15,9 @@ namespace blink {
class HTMLDocumentParserSimTest : public SimTest {
protected:
HTMLDocumentParserSimTest() {
+ ResetDiscardedTokenCountForTesting();
Document::SetThreadedParsingEnabledForTesting(true);
}
- HistogramTester histogram_;
};
class HTMLDocumentParserLoadingTest : public HTMLDocumentParserSimTest,
@@ -432,7 +431,7 @@ TEST_F(HTMLDocumentParserSimTest, NoRewindNoDocWrite) {
)HTML");
test::RunPendingTasks();
- histogram_.ExpectTotalCount("Parser.DiscardedTokenCount", 0);
+ EXPECT_EQ(0U, GetDiscardedTokenCountForTesting());
}
TEST_F(HTMLDocumentParserSimTest, RewindBrokenToken) {
@@ -447,7 +446,7 @@ TEST_F(HTMLDocumentParserSimTest, RewindBrokenToken) {
)HTML");
test::RunPendingTasks();
- histogram_.ExpectTotalCount("Parser.DiscardedTokenCount", 1);
+ EXPECT_EQ(2U, GetDiscardedTokenCountForTesting());
}
TEST_F(HTMLDocumentParserSimTest, RewindDifferentNamespace) {
@@ -462,7 +461,7 @@ TEST_F(HTMLDocumentParserSimTest, RewindDifferentNamespace) {
)HTML");
test::RunPendingTasks();
- histogram_.ExpectTotalCount("Parser.DiscardedTokenCount", 1);
+ EXPECT_EQ(2U, GetDiscardedTokenCountForTesting());
}
TEST_F(HTMLDocumentParserSimTest, NoRewindSaneDocWrite1) {
@@ -476,7 +475,7 @@ TEST_F(HTMLDocumentParserSimTest, NoRewindSaneDocWrite1) {
"</script>");
test::RunPendingTasks();
- histogram_.ExpectTotalCount("Parser.DiscardedTokenCount", 0);
+ EXPECT_EQ(0U, GetDiscardedTokenCountForTesting());
}
TEST_F(HTMLDocumentParserSimTest, NoRewindSaneDocWrite2) {
@@ -491,7 +490,7 @@ TEST_F(HTMLDocumentParserSimTest, NoRewindSaneDocWrite2) {
)HTML");
test::RunPendingTasks();
- histogram_.ExpectTotalCount("Parser.DiscardedTokenCount", 0);
+ EXPECT_EQ(0U, GetDiscardedTokenCountForTesting());
}
TEST_F(HTMLDocumentParserSimTest, NoRewindSaneDocWriteWithTitle) {
@@ -511,7 +510,7 @@ TEST_F(HTMLDocumentParserSimTest, NoRewindSaneDocWriteWithTitle) {
)HTML");
test::RunPendingTasks();
- histogram_.ExpectTotalCount("Parser.DiscardedTokenCount", 0);
+ EXPECT_EQ(0U, GetDiscardedTokenCountForTesting());
}
} // 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 33750cefc73..d74f07df6a4 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
@@ -6,7 +6,6 @@
#include <memory>
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/web_prerendering_support.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/loader/prerenderer_client.h"
@@ -24,27 +23,11 @@ class MockPrerendererClient : public PrerendererClient {
: PrerendererClient(page, nullptr), is_prefetch_only_(is_prefetch_only) {}
private:
- void WillAddPrerender(Prerender*) override {}
bool IsPrefetchOnly() override { return is_prefetch_only_; }
bool is_prefetch_only_;
};
-class MockWebPrerenderingSupport : public WebPrerenderingSupport {
- public:
- MockWebPrerenderingSupport() { Initialize(this); }
-
- void Add(const WebPrerender&) override {}
- void Cancel(const WebPrerender&) override {}
- void Abandon(const WebPrerender&) override {}
- void PrefetchFinished() override { prefetch_finished_ = true; }
-
- bool IsPrefetchFinished() const { return prefetch_finished_; }
-
- private:
- bool prefetch_finished_ = false;
-};
-
class HTMLDocumentParserTest : public PageTestBase {
protected:
void SetUp() override {
@@ -60,19 +43,12 @@ class HTMLDocumentParserTest : public PageTestBase {
parser->SetDecoder(std::move(decoder));
return parser;
}
-
- bool PrefetchFinishedCleanly() {
- return prerendering_support_.IsPrefetchFinished();
- }
-
- private:
- MockWebPrerenderingSupport prerendering_support_;
};
} // namespace
TEST_F(HTMLDocumentParserTest, AppendPrefetch) {
- HTMLDocument& document = ToHTMLDocument(GetDocument());
+ auto& document = To<HTMLDocument>(GetDocument());
ProvidePrerendererClientTo(
*document.GetPage(),
MakeGarbageCollected<MockPrerendererClient>(*document.GetPage(), true));
@@ -90,11 +66,10 @@ TEST_F(HTMLDocumentParserTest, AppendPrefetch) {
// DCHECK).
static_cast<DocumentParser*>(parser)->Finish();
EXPECT_EQ(HTMLTokenizer::kDataState, parser->Tokenizer()->GetState());
- EXPECT_TRUE(PrefetchFinishedCleanly());
}
TEST_F(HTMLDocumentParserTest, AppendNoPrefetch) {
- HTMLDocument& document = ToHTMLDocument(GetDocument());
+ auto& document = To<HTMLDocument>(GetDocument());
EXPECT_FALSE(document.IsPrefetchOnly());
// Use ForceSynchronousParsing to allow calling append().
HTMLDocumentParser* parser = CreateParser(document);
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 598ed12a677..a4a13996c81 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
@@ -134,8 +134,6 @@ HTMLElementStack::HTMLElementStack()
body_element_(nullptr),
stack_depth_(0) {}
-HTMLElementStack::~HTMLElementStack() = default;
-
bool HTMLElementStack::HasOnlyOneElement() const {
return !TopRecord()->Next();
}
@@ -251,8 +249,8 @@ bool HTMLElementStack::IsHTMLIntegrationPoint(HTMLStackItem* item) {
item->GetAttributeItem(mathml_names::kEncodingAttr);
if (encoding_attr) {
const String& encoding = encoding_attr->Value();
- return DeprecatedEqualIgnoringCase(encoding, "text/html") ||
- DeprecatedEqualIgnoringCase(encoding, "application/xhtml+xml");
+ return EqualIgnoringASCIICase(encoding, "text/html") ||
+ EqualIgnoringASCIICase(encoding, "application/xhtml+xml");
}
return false;
}
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 bafb57a8d25..a433c82874c 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
@@ -45,7 +45,6 @@ class HTMLElementStack {
public:
HTMLElementStack();
- ~HTMLElementStack();
class ElementRecord final : public GarbageCollected<ElementRecord> {
public:
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_formatting_element_list.cc b/chromium/third_party/blink/renderer/core/html/parser/html_formatting_element_list.cc
index 9741293150a..8ade3c166af 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_formatting_element_list.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_formatting_element_list.cc
@@ -39,8 +39,6 @@ static const size_t kNoahsArkCapacity = 3;
HTMLFormattingElementList::HTMLFormattingElementList() = default;
-HTMLFormattingElementList::~HTMLFormattingElementList() = default;
-
Element* HTMLFormattingElementList::ClosestElementInScopeWithName(
const AtomicString& target_name) {
for (wtf_size_t i = 1; i <= entries_.size(); ++i) {
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 7d8e16b883e..f9c4f2a13cb 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
@@ -42,7 +42,6 @@ class HTMLFormattingElementList {
public:
HTMLFormattingElementList();
- ~HTMLFormattingElementList();
// Ideally Entry would be private, but HTMLTreeBuilder has to coordinate
// between the HTMLFormattingElementList and HTMLElementStack and needs access
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 fed483dae45..85a7b67b3c4 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
@@ -379,7 +379,7 @@ WTF::TextEncoding EncodingFromMetaAttributes(
const AtomicString& attribute_value = AtomicString(html_attribute.second);
if (ThreadSafeMatch(attribute_name, html_names::kHttpEquivAttr)) {
- if (DeprecatedEqualIgnoringCase(attribute_value, "content-type"))
+ if (EqualIgnoringASCIICase(attribute_value, "content-type"))
got_pragma = true;
} else if (ThreadSafeMatch(attribute_name, html_names::kCharsetAttr)) {
has_charset = true;
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_parser_metrics.cc b/chromium/third_party/blink/renderer/core/html/parser/html_parser_metrics.cc
new file mode 100644
index 00000000000..997ff68addd
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_parser_metrics.cc
@@ -0,0 +1,104 @@
+// 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/parser/html_parser_metrics.h"
+
+#include "base/metrics/histogram_macros.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
+
+namespace blink {
+
+HTMLParserMetrics::HTMLParserMetrics(int64_t source_id,
+ ukm::UkmRecorder* recorder)
+ : source_id_(source_id), recorder_(recorder) {}
+
+void HTMLParserMetrics::AddChunk(base::TimeDelta elapsed_time,
+ unsigned tokens_parsed) {
+ DCHECK(base::TimeTicks::IsHighResolution());
+
+ ++chunk_count_;
+
+ accumulated_parsing_time_ += elapsed_time;
+ if (elapsed_time < min_parsing_time_)
+ min_parsing_time_ = elapsed_time;
+ if (elapsed_time > max_parsing_time_)
+ max_parsing_time_ = elapsed_time;
+
+ total_tokens_parsed_ += tokens_parsed;
+ if (tokens_parsed < min_tokens_parsed_)
+ min_tokens_parsed_ = tokens_parsed;
+ if (tokens_parsed > max_tokens_parsed_)
+ max_tokens_parsed_ = tokens_parsed;
+}
+
+void HTMLParserMetrics::AddYieldInterval(base::TimeDelta elapsed_time) {
+ DCHECK(base::TimeTicks::IsHighResolution());
+
+ yield_count_++;
+
+ accumulated_yield_intervals_ += elapsed_time;
+ if (elapsed_time < min_yield_interval_)
+ min_yield_interval_ = elapsed_time;
+ if (elapsed_time > max_yield_interval_)
+ max_yield_interval_ = elapsed_time;
+}
+
+void HTMLParserMetrics::ReportMetricsAtParseEnd() {
+ // The various histogram limits were chosen based on initial UKM data.
+ UMA_HISTOGRAM_COUNTS_1000("Blink.HTMLParsing.ChunkCount", chunk_count_);
+ UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
+ "Blink.HTMLParsing.ParsingTimeMax", max_parsing_time_,
+ base::TimeDelta::FromMicroseconds(1), base::TimeDelta::FromSeconds(100),
+ 1000);
+ UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES("Blink.HTMLParsing.ParsingTimeMin",
+ min_parsing_time_,
+ base::TimeDelta::FromMicroseconds(1),
+ base::TimeDelta::FromSeconds(1), 100);
+ UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
+ "Blink.HTMLParsing.ParsingTimeTotal", accumulated_parsing_time_,
+ base::TimeDelta::FromMicroseconds(1), base::TimeDelta::FromSeconds(100),
+ 1000);
+ UMA_HISTOGRAM_COUNTS_1M("Blink.HTMLParsing.TokensParsedMax",
+ max_tokens_parsed_);
+ UMA_HISTOGRAM_COUNTS_10000("Blink.HTMLParsing.TokensParsedMin",
+ min_tokens_parsed_);
+ UMA_HISTOGRAM_COUNTS_1M("Blink.HTMLParsing.TokensParsedAverage",
+ total_tokens_parsed_ / chunk_count_);
+
+ // Only report yield data if we actually yielded.
+ if (max_yield_interval_ != base::TimeDelta()) {
+ UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
+ "Blink.HTMLParsing.YieldedTimeMax", max_yield_interval_,
+ base::TimeDelta::FromMicroseconds(1), base::TimeDelta::FromSeconds(100),
+ 1000);
+ UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
+ "Blink.HTMLParsing.YieldedTimeMin", min_yield_interval_,
+ base::TimeDelta::FromMicroseconds(1), base::TimeDelta::FromSeconds(10),
+ 100);
+ UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
+ "Blink.HTMLParsing.YieldedTimeAverage",
+ accumulated_yield_intervals_ / yield_count_,
+ base::TimeDelta::FromMicroseconds(1), base::TimeDelta::FromSeconds(10),
+ 100);
+ }
+
+ // Build and report UKM
+ ukm::builders::Blink_HTMLParsing builder(source_id_);
+ builder.SetChunkCount(chunk_count_);
+ builder.SetParsingTimeMax(max_parsing_time_.InMicroseconds());
+ builder.SetParsingTimeMin(min_parsing_time_.InMicroseconds());
+ builder.SetParsingTimeTotal(accumulated_parsing_time_.InMicroseconds());
+ builder.SetTokensParsedMax(max_tokens_parsed_);
+ builder.SetTokensParsedMin(min_tokens_parsed_);
+ builder.SetTokensParsedAverage(total_tokens_parsed_ / chunk_count_);
+ if (accumulated_yield_intervals_ != base::TimeDelta()) {
+ builder.SetYieldedTimeMax(max_yield_interval_.InMicroseconds());
+ builder.SetYieldedTimeMin(min_yield_interval_.InMicroseconds());
+ builder.SetYieldedTimeAverage(
+ accumulated_yield_intervals_.InMicroseconds() / yield_count_);
+ }
+ builder.Record(recorder_);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_parser_metrics.h b/chromium/third_party/blink/renderer/core/html/parser/html_parser_metrics.h
new file mode 100644
index 00000000000..e6c84aa70e7
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_parser_metrics.h
@@ -0,0 +1,56 @@
+// 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_PARSER_HTML_PARSER_METRICS_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PARSER_HTML_PARSER_METRICS_H_
+
+#include "base/time/time.h"
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
+
+namespace ukm {
+class UkmRecorder;
+}
+
+namespace blink {
+
+// Store and report metrics data for the HTMLDocumentParser.
+class CORE_EXPORT HTMLParserMetrics {
+ public:
+ HTMLParserMetrics(int64_t source_id, ukm::UkmRecorder*);
+ ~HTMLParserMetrics() = default;
+
+ void AddChunk(base::TimeDelta elapsed_time, unsigned tokens_parsed);
+
+ void AddYieldInterval(base::TimeDelta elapsed_time);
+
+ void ReportMetricsAtParseEnd();
+
+ private:
+ // UKM System data.
+ const int64_t source_id_;
+ ukm::UkmRecorder* const recorder_;
+
+ // Metrics data.
+ unsigned chunk_count_ = 0; // For computing averages.
+ base::TimeDelta accumulated_parsing_time_; // Constructed with 0 value
+ base::TimeDelta min_parsing_time_ = base::TimeDelta::Max();
+ base::TimeDelta max_parsing_time_; // Constructed with 0 value
+ unsigned total_tokens_parsed_ = 0;
+ unsigned min_tokens_parsed_ = UINT_MAX;
+ unsigned max_tokens_parsed_ = 0;
+
+ // Yield count may not equal chunk count - 1. That is, there is not
+ // always one yield between every pair of chunks.
+ unsigned yield_count_ = 0;
+ base::TimeDelta accumulated_yield_intervals_; // Constructed with 0 value
+ base::TimeDelta min_yield_interval_ = base::TimeDelta::Max();
+ base::TimeDelta max_yield_interval_; // Constructed with 0 value
+
+ DISALLOW_COPY_AND_ASSIGN(HTMLParserMetrics);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PARSER_HTML_PARSER_METRICS_H_
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_parser_metrics_test.cc b/chromium/third_party/blink/renderer/core/html/parser/html_parser_metrics_test.cc
new file mode 100644
index 00000000000..7f797d2b3f9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_parser_metrics_test.cc
@@ -0,0 +1,256 @@
+// 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/parser/html_parser_metrics.h"
+
+#include "base/test/metrics/histogram_tester.h"
+#include "base/test/test_mock_time_task_runner.h"
+#include "components/ukm/test_ukm_recorder.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_local_frame_impl.h"
+#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
+
+namespace blink {
+
+class HTMLParserMetricsTest : public testing::Test {
+ public:
+ HTMLParserMetricsTest() {
+ helper_.Initialize(nullptr, nullptr, nullptr, nullptr);
+ }
+
+ ~HTMLParserMetricsTest() override = default;
+
+ void SetUp() override {}
+
+ void TearDown() override {}
+
+ void LoadHTML(const std::string& html) {
+ frame_test_helpers::LoadHTMLString(helper_.GetWebView()->MainFrameImpl(),
+ html,
+ url_test_helpers::ToKURL("about:blank"));
+ }
+
+ protected:
+ frame_test_helpers::WebViewHelper helper_;
+};
+
+TEST_F(HTMLParserMetricsTest, ReportSingleChunk) {
+ // Although the tests use a mock clock, the metrics recorder checks if the
+ // system has a high resolution clock before recording results. As a result,
+ // the tests will fail if the system does not have a high resolution clock.
+ if (!base::TimeTicks::IsHighResolution())
+ return;
+
+ base::HistogramTester histogram_tester;
+ LoadHTML(R"HTML(
+ <div></div>
+ )HTML");
+
+ // Should have one of each metric, except the yield times because with
+ // a single chunk they should not report.
+ histogram_tester.ExpectTotalCount("Blink.HTMLParsing.ChunkCount", 1);
+ histogram_tester.ExpectTotalCount("Blink.HTMLParsing.ParsingTimeMax", 1);
+ histogram_tester.ExpectTotalCount("Blink.HTMLParsing.ParsingTimeMin", 1);
+ histogram_tester.ExpectTotalCount("Blink.HTMLParsing.ParsingTimeTotal", 1);
+ histogram_tester.ExpectTotalCount("Blink.HTMLParsing.TokensParsedMax", 1);
+ histogram_tester.ExpectTotalCount("Blink.HTMLParsing.TokensParsedMin", 1);
+ histogram_tester.ExpectTotalCount("Blink.HTMLParsing.TokensParsedAverage", 1);
+ histogram_tester.ExpectTotalCount("Blink.HTMLParsing.YieldedTimeMax", 0);
+ histogram_tester.ExpectTotalCount("Blink.HTMLParsing.YieldedTimeMin", 0);
+ histogram_tester.ExpectTotalCount("Blink.HTMLParsing.YieldedTimeAverage", 0);
+
+ // Expect specific values for the chunks and tokens counts
+ histogram_tester.ExpectUniqueSample("Blink.HTMLParsing.ChunkCount", 1, 1);
+ histogram_tester.ExpectUniqueSample("Blink.HTMLParsing.TokensParsedMax", 2,
+ 1);
+ histogram_tester.ExpectUniqueSample("Blink.HTMLParsing.TokensParsedMin", 2,
+ 1);
+ histogram_tester.ExpectUniqueSample("Blink.HTMLParsing.TokensParsedAverage",
+ 2, 1);
+
+ // Expect that the times have moved from the default and the max and min
+ // and total are all the same (within the same bucket)
+ std::vector<base::Bucket> parsing_time_max_buckets =
+ histogram_tester.GetAllSamples("Blink.HTMLParsing.ParsingTimeMax");
+ std::vector<base::Bucket> parsing_time_min_buckets =
+ histogram_tester.GetAllSamples("Blink.HTMLParsing.ParsingTimeMin");
+ std::vector<base::Bucket> parsing_time_total_buckets =
+ histogram_tester.GetAllSamples("Blink.HTMLParsing.ParsingTimeTotal");
+ EXPECT_EQ(parsing_time_max_buckets.size(), 1u);
+ EXPECT_EQ(parsing_time_min_buckets.size(), 1u);
+ EXPECT_EQ(parsing_time_total_buckets.size(), 1u);
+ EXPECT_GT(parsing_time_max_buckets[0].min, 0);
+ EXPECT_GT(parsing_time_min_buckets[0].min, 0);
+ EXPECT_GT(parsing_time_total_buckets[0].min, 0);
+}
+
+TEST_F(HTMLParserMetricsTest, HistogramReportsTwoChunks) {
+ // Although the tests use a mock clock, the metrics recorder checks if the
+ // system has a high resolution clock before recording results. As a result,
+ // the tests will fail if the system does not have a high resolution clock.
+ if (!base::TimeTicks::IsHighResolution())
+ return;
+
+ base::HistogramTester histogram_tester;
+
+ // This content exceeds the number of tokens before a script tag used as
+ // the yield threshold. If the yield threshold changes, this test will fail
+ // and/or need changing. See the HTMLParserScheduler::ShouldYield method for
+ // the current value of the constant.
+ LoadHTML(R"HTML(
+ <head></head>
+ <div></div><div></div><div></div><div></div><div></div><div></div>
+ <div></div><div></div><div></div><div></div><div></div><div></div>
+ <div></div><div></div><div></div><div></div><div></div><div></div>
+ <div></div><div></div><div></div><div></div><div></div><div></div>
+ <div></div><div></div><div></div><div></div><div></div><div></div>
+ <div></div><div></div><div></div><div></div><div></div><div></div>
+ <div></div><div></div><div></div><div></div><div></div><div></div>
+ <div></div><div></div><div></div><div></div><div></div><div></div>
+ <div></div><div></div><div></div><div></div><div></div><div></div>
+ <script>document.offsetTop</script>
+ )HTML");
+
+ // Should have one of each metric.
+ histogram_tester.ExpectTotalCount("Blink.HTMLParsing.ChunkCount", 1);
+ histogram_tester.ExpectTotalCount("Blink.HTMLParsing.ParsingTimeMax", 1);
+ histogram_tester.ExpectTotalCount("Blink.HTMLParsing.ParsingTimeMin", 1);
+ histogram_tester.ExpectTotalCount("Blink.HTMLParsing.ParsingTimeTotal", 1);
+ histogram_tester.ExpectTotalCount("Blink.HTMLParsing.TokensParsedMax", 1);
+ histogram_tester.ExpectTotalCount("Blink.HTMLParsing.TokensParsedMin", 1);
+ histogram_tester.ExpectTotalCount("Blink.HTMLParsing.TokensParsedAverage", 1);
+ histogram_tester.ExpectTotalCount("Blink.HTMLParsing.YieldedTimeMax", 1);
+ histogram_tester.ExpectTotalCount("Blink.HTMLParsing.YieldedTimeMin", 1);
+ histogram_tester.ExpectTotalCount("Blink.HTMLParsing.YieldedTimeAverage", 1);
+
+ // Expect specific values for the chunks and tokens counts
+ histogram_tester.ExpectUniqueSample("Blink.HTMLParsing.ChunkCount", 2, 1);
+ histogram_tester.ExpectUniqueSample("Blink.HTMLParsing.TokensParsedMax", 110,
+ 1);
+ histogram_tester.ExpectUniqueSample("Blink.HTMLParsing.TokensParsedMin", 0,
+ 1);
+ histogram_tester.ExpectUniqueSample("Blink.HTMLParsing.TokensParsedAverage",
+ 55, 1);
+
+ // For parse times, expect that the times have moved from the default.
+ std::vector<base::Bucket> parsing_time_max_buckets =
+ histogram_tester.GetAllSamples("Blink.HTMLParsing.ParsingTimeMax");
+ std::vector<base::Bucket> parsing_time_min_buckets =
+ histogram_tester.GetAllSamples("Blink.HTMLParsing.ParsingTimeMin");
+ std::vector<base::Bucket> parsing_time_total_buckets =
+ histogram_tester.GetAllSamples("Blink.HTMLParsing.ParsingTimeTotal");
+ EXPECT_EQ(parsing_time_max_buckets.size(), 1u);
+ EXPECT_EQ(parsing_time_min_buckets.size(), 1u);
+ EXPECT_EQ(parsing_time_total_buckets.size(), 1u);
+ EXPECT_GT(parsing_time_max_buckets[0].min, 0);
+ EXPECT_GT(parsing_time_min_buckets[0].min, 0);
+ EXPECT_GT(parsing_time_total_buckets[0].min, 0);
+
+ // For yields, the values should be the same because there was only one yield,
+ // but due to different histogram sizes we can't directly compare them.
+ std::vector<base::Bucket> yield_time_max_buckets =
+ histogram_tester.GetAllSamples("Blink.HTMLParsing.YieldedTimeMax");
+ std::vector<base::Bucket> yield_time_min_buckets =
+ histogram_tester.GetAllSamples("Blink.HTMLParsing.YieldedTimeMin");
+ std::vector<base::Bucket> yield_time_average_buckets =
+ histogram_tester.GetAllSamples("Blink.HTMLParsing.YieldedTimeAverage");
+ EXPECT_EQ(yield_time_max_buckets.size(), 1u);
+ EXPECT_EQ(yield_time_min_buckets.size(), 1u);
+ EXPECT_EQ(yield_time_average_buckets.size(), 1u);
+ EXPECT_GT(yield_time_max_buckets[0].min, 0);
+ EXPECT_GT(yield_time_min_buckets[0].min, 0);
+ EXPECT_GT(yield_time_average_buckets[0].min, 0);
+}
+
+TEST_F(HTMLParserMetricsTest, UkmStoresValuesCorrectly) {
+ // Although the tests use a mock clock, the metrics recorder checks if the
+ // system has a high resolution clock before recording results. As a result,
+ // the tests will fail if the system does not have a high resolution clock.
+ if (!base::TimeTicks::IsHighResolution())
+ return;
+
+ ukm::TestUkmRecorder recorder;
+ HTMLParserMetrics reporter(ukm::UkmRecorder::GetNewSourceID(), &recorder);
+
+ // Start with empty metrics
+ auto entries = recorder.GetEntriesByName("Blink.HTMLParsing");
+ EXPECT_EQ(entries.size(), 0u);
+
+ // Run a fictional sequence of calls
+ base::TimeDelta first_parse_time = base::TimeDelta::FromMicroseconds(20);
+ base::TimeDelta second_parse_time = base::TimeDelta::FromMicroseconds(10);
+ base::TimeDelta third_parse_time = base::TimeDelta::FromMicroseconds(30);
+ unsigned first_tokens_parsed = 50u;
+ unsigned second_tokens_parsed = 40u;
+ unsigned third_tokens_parsed = 60u;
+ base::TimeDelta first_yield_time = base::TimeDelta::FromMicroseconds(80);
+ base::TimeDelta second_yield_time = base::TimeDelta::FromMicroseconds(70);
+
+ reporter.AddChunk(first_parse_time, first_tokens_parsed);
+ reporter.AddYieldInterval(first_yield_time);
+ reporter.AddChunk(second_parse_time, second_tokens_parsed);
+ reporter.AddYieldInterval(second_yield_time);
+ reporter.AddChunk(third_parse_time, third_tokens_parsed);
+ reporter.ReportMetricsAtParseEnd();
+
+ // Check we have a single entry
+ entries = recorder.GetEntriesByName("Blink.HTMLParsing");
+ EXPECT_EQ(entries.size(), 1u);
+ auto* entry = entries[0];
+
+ // Verify all the values
+ EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, "ChunkCount"));
+ const int64_t* metric_value =
+ ukm::TestUkmRecorder::GetEntryMetric(entry, "ChunkCount");
+ EXPECT_EQ(*metric_value, 3);
+
+ EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, "ParsingTimeMax"));
+ metric_value = ukm::TestUkmRecorder::GetEntryMetric(entry, "ParsingTimeMax");
+ EXPECT_EQ(*metric_value, third_parse_time.InMicroseconds());
+
+ EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, "ParsingTimeMin"));
+ metric_value = ukm::TestUkmRecorder::GetEntryMetric(entry, "ParsingTimeMin");
+ EXPECT_EQ(*metric_value, second_parse_time.InMicroseconds());
+
+ EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, "ParsingTimeTotal"));
+ metric_value =
+ ukm::TestUkmRecorder::GetEntryMetric(entry, "ParsingTimeTotal");
+ EXPECT_EQ(*metric_value,
+ (first_parse_time + second_parse_time + third_parse_time)
+ .InMicroseconds());
+
+ EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, "TokensParsedMax"));
+ metric_value = ukm::TestUkmRecorder::GetEntryMetric(entry, "TokensParsedMax");
+ EXPECT_EQ(*metric_value, third_tokens_parsed);
+
+ EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, "TokensParsedMin"));
+ metric_value = ukm::TestUkmRecorder::GetEntryMetric(entry, "TokensParsedMin");
+ EXPECT_EQ(*metric_value, second_tokens_parsed);
+
+ EXPECT_TRUE(
+ ukm::TestUkmRecorder::EntryHasMetric(entry, "TokensParsedAverage"));
+ metric_value =
+ ukm::TestUkmRecorder::GetEntryMetric(entry, "TokensParsedAverage");
+ EXPECT_EQ(
+ *metric_value,
+ (first_tokens_parsed + second_tokens_parsed + third_tokens_parsed) / 3);
+
+ EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, "YieldedTimeMax"));
+ metric_value = ukm::TestUkmRecorder::GetEntryMetric(entry, "YieldedTimeMax");
+ EXPECT_EQ(*metric_value, first_yield_time.InMicroseconds());
+
+ EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, "YieldedTimeMin"));
+ metric_value = ukm::TestUkmRecorder::GetEntryMetric(entry, "YieldedTimeMin");
+ EXPECT_EQ(*metric_value, second_yield_time.InMicroseconds());
+
+ EXPECT_TRUE(
+ ukm::TestUkmRecorder::EntryHasMetric(entry, "YieldedTimeAverage"));
+ metric_value =
+ ukm::TestUkmRecorder::GetEntryMetric(entry, "YieldedTimeAverage");
+ EXPECT_EQ(*metric_value,
+ ((first_yield_time + second_yield_time) / 2).InMicroseconds());
+}
+
+} // namespace blink
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 494d91f99cf..a5c4119348f 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,19 +26,20 @@
#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/settings.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
HTMLParserOptions::HTMLParserOptions(Document* document) {
- if (!document)
+ if (!document || !document->GetFrame())
return;
- if (document->GetFrame()) {
- script_enabled = document->CanExecuteScripts(kNotAboutToExecuteScript);
- priority_hints_origin_trial_enabled =
- RuntimeEnabledFeatures::PriorityHintsEnabled(document);
- }
+ scripting_flag = (document->GetSettings()->GetParserScriptingFlagPolicy() ==
+ ParserScriptingFlagPolicy::kEnabled) ||
+ document->CanExecuteScripts(kNotAboutToExecuteScript);
+ priority_hints_origin_trial_enabled =
+ RuntimeEnabledFeatures::PriorityHintsEnabled(document);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_parser_options.h b/chromium/third_party/blink/renderer/core/html/parser/html_parser_options.h
index 50011d16d10..267d50f5383 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_parser_options.h
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_parser_options.h
@@ -37,7 +37,8 @@ class CORE_EXPORT HTMLParserOptions {
DISALLOW_NEW();
public:
- bool script_enabled = false;
+ // https://html.spec.whatwg.org/#scripting-flag
+ bool scripting_flag = false;
// TODO(domfarolino): Remove this when Priority Hints is no longer in an
// Origin Trial. See https://crbug.com/821464.
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 601f0eb325c..1559a1624ba 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
@@ -40,10 +40,6 @@ SpeculationsPumpSession::SpeculationsPumpSession(unsigned& nesting_level)
SpeculationsPumpSession::~SpeculationsPumpSession() = default;
-inline base::TimeDelta SpeculationsPumpSession::ElapsedTime() const {
- return start_time_.Elapsed();
-}
-
void SpeculationsPumpSession::AddedElementTokens(size_t count) {
processed_element_tokens_ += count;
}
@@ -51,9 +47,7 @@ void SpeculationsPumpSession::AddedElementTokens(size_t count) {
HTMLParserScheduler::HTMLParserScheduler(
HTMLDocumentParser* parser,
scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner)
- : parser_(parser),
- loading_task_runner_(std::move(loading_task_runner)),
- is_paused_with_active_timer_(false) {}
+ : parser_(parser), loading_task_runner_(std::move(loading_task_runner)) {}
HTMLParserScheduler::~HTMLParserScheduler() = default;
@@ -62,37 +56,18 @@ void HTMLParserScheduler::Trace(Visitor* visitor) {
}
bool HTMLParserScheduler::IsScheduledForUnpause() const {
- return is_paused_with_active_timer_ ||
- cancellable_continue_parse_task_handle_.IsActive();
+ return cancellable_continue_parse_task_handle_.IsActive();
}
void HTMLParserScheduler::ScheduleForUnpause() {
- DCHECK(!is_paused_with_active_timer_);
cancellable_continue_parse_task_handle_ =
PostCancellableTask(*loading_task_runner_, FROM_HERE,
WTF::Bind(&HTMLParserScheduler::ContinueParsing,
WrapWeakPersistent(this)));
}
-void HTMLParserScheduler::Pause() {
- DCHECK(!is_paused_with_active_timer_);
- if (!cancellable_continue_parse_task_handle_.IsActive())
- return;
- is_paused_with_active_timer_ = true;
- cancellable_continue_parse_task_handle_.Cancel();
-}
-
-void HTMLParserScheduler::Unpause() {
- DCHECK(!cancellable_continue_parse_task_handle_.IsActive());
- if (!is_paused_with_active_timer_)
- return;
- is_paused_with_active_timer_ = false;
- ScheduleForUnpause();
-}
-
void HTMLParserScheduler::Detach() {
cancellable_continue_parse_task_handle_.Cancel();
- is_paused_with_active_timer_ = false;
}
inline bool HTMLParserScheduler::ShouldYield(
@@ -131,11 +106,6 @@ bool HTMLParserScheduler::YieldIfNeeded(const SpeculationsPumpSession& session,
return false;
}
-void HTMLParserScheduler::ForceUnpauseAfterYield() {
- DCHECK(!cancellable_continue_parse_task_handle_.IsActive());
- is_paused_with_active_timer_ = true;
-}
-
void HTMLParserScheduler::ContinueParsing() {
parser_->ResumeParsingAfterYield();
}
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 9c63198537a..87d35d4a9f8 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
@@ -42,10 +42,10 @@ class SpeculationsPumpSession : public NestingLevelIncrementer {
STACK_ALLOCATED();
public:
- SpeculationsPumpSession(unsigned& nesting_level);
+ explicit SpeculationsPumpSession(unsigned& nesting_level);
~SpeculationsPumpSession();
- base::TimeDelta ElapsedTime() const;
+ base::TimeDelta ElapsedTime() const { return start_time_.Elapsed(); }
void AddedElementTokens(size_t count);
size_t ProcessedElementTokens() const { return processed_element_tokens_; }
@@ -64,18 +64,6 @@ class HTMLParserScheduler final : public GarbageCollected<HTMLParserScheduler> {
void ScheduleForUnpause();
bool YieldIfNeeded(const SpeculationsPumpSession&, bool starting_script);
- /**
- * Can only be called if this scheduler is paused. If this is called,
- * then after the scheduler is resumed by calling resume(), this call
- * ensures that HTMLDocumentParser::resumeAfterYield will be called. Used to
- * signal this scheduler that the background html parser sent chunks to
- * HTMLDocumentParser while it was paused.
- */
- void ForceUnpauseAfterYield();
-
- void Pause();
- void Unpause();
-
void Detach(); // Clear active tasks if any.
void Trace(Visitor*);
@@ -88,7 +76,6 @@ class HTMLParserScheduler final : public GarbageCollected<HTMLParserScheduler> {
scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_;
TaskHandle cancellable_continue_parse_task_handle_;
- bool is_paused_with_active_timer_;
DISALLOW_COPY_AND_ASSIGN(HTMLParserScheduler);
};
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 0d4a5339a14..c2410ab5a27 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
@@ -58,7 +58,6 @@
#include "third_party/blink/renderer/core/loader/subresource_integrity_helper.h"
#include "third_party/blink/renderer/core/origin_trials/origin_trials.h"
#include "third_party/blink/renderer/core/script/script_loader.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/loader/fetch/integrity_metadata.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource.h"
@@ -114,8 +113,10 @@ static String InitiatorFor(const StringImpl* tag_impl) {
static bool MediaAttributeMatches(const MediaValuesCached& media_values,
const String& attribute_value) {
+ // Since this is for preload scanning only, ExecutionContext-based origin
+ // trials for media queries are not needed.
scoped_refptr<MediaQuerySet> media_queries =
- MediaQuerySet::Create(attribute_value);
+ MediaQuerySet::Create(attribute_value, nullptr);
MediaQueryEvaluator media_query_evaluator(media_values);
return media_query_evaluator.Eval(*media_queries);
}
@@ -162,7 +163,8 @@ class TokenPreloadScanner::StartTagScanner {
if (Match(tag_impl_, html_names::kImgTag) ||
Match(tag_impl_, html_names::kSourceTag) ||
Match(tag_impl_, html_names::kLinkTag)) {
- source_size_ = SizesAttributeParser(media_values_, String()).length();
+ source_size_ =
+ SizesAttributeParser(media_values_, String(), nullptr).length();
return;
}
if (!Match(tag_impl_, html_names::kInputTag) &&
@@ -470,9 +472,10 @@ class TokenPreloadScanner::StartTagScanner {
img_src_url_ = attribute_value;
} else if (Match(attribute_name, html_names::kRelAttr)) {
LinkRelAttribute rel(attribute_value);
- link_is_style_sheet_ = rel.IsStyleSheet() && !rel.IsAlternate() &&
- rel.GetIconType() == kInvalidIcon &&
- !rel.IsDNSPrefetch();
+ link_is_style_sheet_ =
+ rel.IsStyleSheet() && !rel.IsAlternate() &&
+ rel.GetIconType() == mojom::blink::FaviconIconType::kInvalid &&
+ !rel.IsDNSPrefetch();
link_is_preconnect_ = rel.IsPreconnect();
link_is_preload_ = rel.IsLinkPreload();
link_is_modulepreload_ = rel.IsModulePreload();
@@ -517,8 +520,8 @@ class TokenPreloadScanner::StartTagScanner {
if (Match(attribute_name, html_names::kSrcAttr)) {
SetUrlToLoad(attribute_value, kDisallowURLReplacement);
} else if (Match(attribute_name, html_names::kTypeAttr)) {
- input_is_image_ = DeprecatedEqualIgnoringCase(attribute_value,
- input_type_names::kImage);
+ input_is_image_ =
+ EqualIgnoringASCIICase(attribute_value, input_type_names::kImage);
}
}
@@ -693,7 +696,7 @@ class TokenPreloadScanner::StartTagScanner {
void ParseSourceSize(const String& attribute_value) {
source_size_ =
- SizesAttributeParser(media_values_, attribute_value).length();
+ SizesAttributeParser(media_values_, attribute_value, nullptr).length();
source_size_set_ = true;
}
@@ -745,7 +748,7 @@ class TokenPreloadScanner::StartTagScanner {
mojom::FetchImportanceMode importance_;
bool importance_mode_set_;
String nonce_;
- Member<MediaValuesCached> media_values_;
+ MediaValuesCached* media_values_;
bool referrer_policy_set_;
network::mojom::ReferrerPolicy referrer_policy_;
bool integrity_attr_set_;
@@ -878,13 +881,13 @@ static void HandleMetaNameAttribute(
return;
String content_attribute_value(content_attribute->Value());
- if (DeprecatedEqualIgnoringCase(name_attribute_value, "viewport")) {
+ if (EqualIgnoringASCIICase(name_attribute_value, "viewport")) {
HandleMetaViewport(content_attribute_value, document_parameters,
media_values, viewport);
return;
}
- if (DeprecatedEqualIgnoringCase(name_attribute_value, "referrer")) {
+ if (EqualIgnoringASCIICase(name_attribute_value, "referrer")) {
HandleMetaReferrer(content_attribute_value, document_parameters,
css_scanner);
}
@@ -960,11 +963,11 @@ void TokenPreloadScanner::ScanCommon(
token.GetAttributeItem(html_names::kHttpEquivAttr);
if (equiv_attribute) {
String equiv_attribute_value(equiv_attribute->Value());
- if (DeprecatedEqualIgnoringCase(equiv_attribute_value,
- "content-security-policy")) {
+ if (EqualIgnoringASCIICase(equiv_attribute_value,
+ "content-security-policy")) {
*is_csp_meta_tag = true;
- } else if (DeprecatedEqualIgnoringCase(equiv_attribute_value,
- "accept-ch")) {
+ } else if (EqualIgnoringASCIICase(equiv_attribute_value,
+ "accept-ch")) {
const typename Token::Attribute* content_attribute =
token.GetAttributeItem(html_names::kContentAttr);
if (content_attribute) {
@@ -1097,7 +1100,8 @@ CachedDocumentParameters::CachedDocumentParameters(Document* document) {
viewport_meta_enabled = document->GetSettings() &&
document->GetSettings()->GetViewportMetaEnabled();
referrer_policy = document->GetReferrerPolicy();
- integrity_features = SubresourceIntegrityHelper::GetFeatures(document);
+ integrity_features =
+ SubresourceIntegrityHelper::GetFeatures(document->GetExecutionContext());
lazyload_policy_enforced = document->IsLazyLoadPolicyEnforced();
if (document->Loader() && document->Loader()->GetFrame()) {
lazy_load_image_setting =
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner_fuzzer.cc b/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner_fuzzer.cc
index 7247ddc7857..1929b81aacd 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner_fuzzer.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner_fuzzer.cc
@@ -40,7 +40,7 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
FuzzedDataProvider fuzzed_data(data, size);
HTMLParserOptions options;
- options.script_enabled = fuzzed_data.ConsumeBool();
+ options.scripting_flag = fuzzed_data.ConsumeBool();
std::unique_ptr<CachedDocumentParameters> document_parameters =
CachedDocumentParametersForFuzzing(fuzzed_data);
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 b4699156f62..9ac9b6412bf 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
@@ -146,7 +146,8 @@ class HTMLMockHTMLResourcePreloader : public ResourcePreloader {
PreloadRequestVerification(type, url, base_url, width, referrer_policy);
Resource* resource = preload_request_->Start(document);
ASSERT_TRUE(resource);
- EXPECT_EQ(expected_referrer, resource->GetResourceRequest().HttpReferrer());
+ EXPECT_EQ(expected_referrer,
+ resource->GetResourceRequest().ReferrerString());
}
void PreconnectRequestVerification(const String& host,
@@ -633,11 +634,11 @@ TEST_F(HTMLPreloadScannerTest, testMetaAcceptCH) {
"640w'>",
"blabla.gif", "http://example.test/", ResourceType::kImage, 0},
{"http://example.test",
- "<meta http-equiv='accept-ch' content='dpr \t'><img srcset='bla.gif "
+ "<meta http-equiv='accept-ch' content='dpr '><img srcset='bla.gif "
"320w, blabla.gif 640w'>",
"blabla.gif", "http://example.test/", ResourceType::kImage, 0, dpr},
{"http://example.test",
- "<meta http-equiv='accept-ch' content='bla,dpr \t'><img srcset='bla.gif "
+ "<meta http-equiv='accept-ch' content='bla,dpr '><img srcset='bla.gif "
"320w, blabla.gif 640w'>",
"blabla.gif", "http://example.test/", ResourceType::kImage, 0, dpr},
{"http://example.test",
@@ -662,7 +663,7 @@ TEST_F(HTMLPreloadScannerTest, testMetaAcceptCH) {
viewport_width},
{"http://example.test",
"<meta http-equiv='accept-ch' content=' viewport-width ,width, "
- "wutever, dpr \t'><img sizes='90vw' srcset='bla.gif 320w, blabla.gif "
+ "wutever, dpr '><img sizes='90vw' srcset='bla.gif 320w, blabla.gif "
"640w'>",
"blabla.gif", "http://example.test/", ResourceType::kImage, 450, all},
};
@@ -684,7 +685,7 @@ TEST_F(HTMLPreloadScannerTest, testMetaAcceptCHInsecureDocument) {
const PreloadScannerTestCase expect_no_client_hint = {
"http://example.test",
"<meta http-equiv='accept-ch' content=' viewport-width ,width, "
- "wutever, dpr \t'><img sizes='90vw' srcset='bla.gif 320w, blabla.gif "
+ "wutever, dpr '><img sizes='90vw' srcset='bla.gif 320w, blabla.gif "
"640w'>",
"blabla.gif",
"http://example.test/",
@@ -694,7 +695,7 @@ TEST_F(HTMLPreloadScannerTest, testMetaAcceptCHInsecureDocument) {
const PreloadScannerTestCase expect_client_hint = {
"http://example.test",
"<meta http-equiv='accept-ch' content=' viewport-width ,width, "
- "wutever, dpr \t'><img sizes='90vw' srcset='bla.gif 320w, blabla.gif "
+ "wutever, dpr '><img sizes='90vw' srcset='bla.gif 320w, blabla.gif "
"640w'>",
"blabla.gif",
"http://example.test/",
@@ -871,9 +872,7 @@ TEST_F(HTMLPreloadScannerTest, testReferrerPolicy) {
"referrerpolicy='strict-origin-when-cross-origin' "
"href='bla.gif'/>",
"bla.gif", "http://example.test/", ResourceType::kImage, 0,
- network::mojom::ReferrerPolicy::
- kNoReferrerWhenDowngradeOriginWhenCrossOrigin,
- nullptr},
+ network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin, nullptr},
{"http://example.test",
"<link rel='stylesheet' href='sheet.css' type='text/css'>", "sheet.css",
"http://example.test/", ResourceType::kCSSStyleSheet, 0,
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 4a040fb80b0..7d3025bbee5 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
@@ -32,12 +32,16 @@
#include "third_party/blink/renderer/core/html/parser/html_srcset_parser.h"
#include <algorithm>
+
+#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/platform/web_network_state_notifier.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/frame_console.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/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/core/inspector/console_message.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/json/json_values.h"
#include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
@@ -197,9 +201,10 @@ static void SrcsetError(Document* document, String message) {
StringBuilder error_message;
error_message.Append("Failed parsing 'srcset' attribute value since ");
error_message.Append(message);
- document->GetFrame()->Console().AddMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kOther, mojom::ConsoleMessageLevel::kError,
- error_message.ToString()));
+ document->GetFrame()->Console().AddMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kOther,
+ mojom::ConsoleMessageLevel::kError, error_message.ToString()));
}
}
@@ -328,14 +333,15 @@ static void ParseImageCandidatesFromSrcsetAttribute(
if (document) {
UseCounter::Count(document, WebFeature::kSrcsetDroppedCandidate);
if (document->GetFrame()) {
- document->GetFrame()->Console().AddMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kOther,
- mojom::ConsoleMessageLevel::kError,
- String("Dropped srcset candidate ") +
- JSONValue::QuoteString(
- String(image_url_start,
- static_cast<wtf_size_t>(image_url_end -
- image_url_start)))));
+ document->GetFrame()->Console().AddMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kOther,
+ mojom::ConsoleMessageLevel::kError,
+ String("Dropped srcset candidate ") +
+ JSONValue::QuoteString(
+ String(image_url_start,
+ static_cast<wtf_size_t>(image_url_end -
+ image_url_start)))));
}
}
continue;
@@ -444,8 +450,12 @@ static ImageCandidate PickBestImageCandidate(
de_duped_image_candidates.push_back(&image);
prev_density = image.Density();
}
+
unsigned winner =
- SelectionLogic(de_duped_image_candidates, device_scale_factor);
+ blink::WebNetworkStateNotifier::SaveDataEnabled() &&
+ base::FeatureList::IsEnabled(blink::features::kSaveDataImgSrcset)
+ ? 0
+ : SelectionLogic(de_duped_image_candidates, device_scale_factor);
DCHECK_LT(winner, de_duped_image_candidates.size());
winner = AvoidDownloadIfHigherDensityResourceIsInCache(
de_duped_image_candidates, winner, document);
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_srcset_parser.h b/chromium/third_party/blink/renderer/core/html/parser/html_srcset_parser.h
index 1270664c288..9af275482ca 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_srcset_parser.h
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_srcset_parser.h
@@ -41,7 +41,7 @@ namespace blink {
class Document;
-enum { kUninitializedDescriptor = -1 };
+constexpr int kUninitializedDescriptor = -1;
class DescriptorParsingResult {
STACK_ALLOCATED();
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_srcset_parser_test.cc b/chromium/third_party/blink/renderer/core/html/parser/html_srcset_parser_test.cc
index cc3aed6a9fe..9b8791ad9db 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_srcset_parser_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_srcset_parser_test.cc
@@ -4,9 +4,13 @@
#include "third_party/blink/renderer/core/html/parser/html_srcset_parser.h"
-#include "testing/gtest/include/gtest/gtest.h"
#include <limits.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/platform/web_network_state_notifier.h"
+
namespace blink {
typedef struct {
@@ -173,4 +177,150 @@ TEST(HTMLSrcsetParserTest, Basic) {
}
}
+TEST(HTMLSrcsetParserTest, SaveDataEnabledBasic) {
+ SrcsetParserTestCase test_cases[] = {
+ // 0
+ {2.0, 0.5, "", "data:,a 1w, data:,b 2x", "data:,a", 2.0, 1},
+ {2.0, 1, "", "data:,a 2w, data:,b 2x", "data:,a", 2.0, 2},
+ {2.0, -1, "", "1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
+ {2.0, -1, "", "1x.gif 1q, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {1.0, -1, "", "1x.gif 1q, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {1.0, -1, "", "1x.gif 1x 100h, 2x.gif 2x", "2x.gif", 2.0, -1}, // 5
+ {1.0, -1, "", "1x.gif 1x 100w, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {1.0, -1, "", "1x.gif 1x 100h 100w, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {2.0, -1, "", "1x.gif 1x, 2x.gif -2x", "1x.gif", 1.0, -1},
+ {2.0, -1, "", "0x.gif 0x", "0x.gif", 0.0, -1},
+ {2.0, -1, "", "0x.gif -0x", "0x.gif", 0.0, -1}, // 10
+ {2.0, -1, "", "neg.gif -2x", "", 1.0, -1},
+ {2.0, -1, "", "1x.gif 1x, 2x.gif 2q", "1x.gif", 1.0, -1},
+ {2.0, -1, "", "1x.gif, 2x.gif 2q", "1x.gif", 1.0, -1},
+ {2.0, -1, "", "1x.gif , 2x.gif 2q", "1x.gif", 1.0, -1},
+ {2.0, -1, "1x.gif 1x, 2x.gif 2x", "1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0,
+ -1}, // 15
+ {1.0, -1, "1x.gif 1x, 2x.gif 2x", "1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0,
+ -1},
+ {1.0, -1, "1x.gif 1x, 2x.gif 2x", "", "1x.gif 1x, 2x.gif 2x", 1.0, -1},
+ {2.0, -1, "src.gif", "1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
+ {1.0, -1, "src.gif", "1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
+ {1.0, -1, "src.gif", "2x.gif 2x", "src.gif", 1.0, -1}, // 20
+ {2.0, -1, "src.gif", "2x.gif 2x", "src.gif", 1.0, -1},
+ {2.0, -1, "src.gif", "2x.gif 2px", "src.gif", 1.0, -1},
+ {2.0, -1, "src.gif", "2x.gif 2ex", "src.gif", 1.0, -1},
+ {10.0, -1, "src.gif", "2x.gif 2e1x", "src.gif", 1.0, -1},
+ {2.0, -1, "src.gif", "2x.gif 2e1x", "src.gif", 1.0, -1}, // 25
+ {2.0, -1, "src.gif", "2x.gif +2x", "src.gif", 1.0, -1},
+ {1.5, -1, "src.gif", "2x.gif 2x", "src.gif", 1.0, -1},
+ {2.5, -1, "src.gif", "2x.gif 2x", "src.gif", 1.0, -1},
+ {2.5, -1, "src.gif", "2x.gif 2x, 3x.gif 3x", "src.gif", 1.0, -1},
+ {2.0, -1, "", "1x,, , x ,2x ", "1x", 1.0, -1}, // 30
+ {2.0, -1, "", "1x,, , x ,2x ", "1x", 1.0, -1},
+ {2.0, -1, "", ",,1x,, , x ,2x ", "1x", 1.0, -1},
+ {2.0, -1, "", ",,1x,,", "1x", 1.0, -1},
+ {2.0, -1, "", ",1x,", "1x", 1.0, -1},
+ {2.0, -1, "",
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg 1x, 2x.gif 2x",
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg", 1.0, -1}, // 35
+ {2.0, -1, "",
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg 2x, 1x.gif 1x", "1x.gif",
+ 1.0, -1},
+ {2.0, -1, "",
+ "1x,, , x ,2x , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif dx, "
+ "2x.gif 2x ,",
+ "1x", 1.0, -1},
+ {4.0, -1, "",
+ "1x,, , x ,2x , 1x.gif, 3x, 4x.gif 4x 100h, 5x.gif 5, dx.gif dx, "
+ "2x.gif 2x ,",
+ "1x", 1.0, -1},
+ {4.0, -1, "",
+ "1x,, , x ,2x , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif dx, "
+ "2x.gif 2x ,",
+ "1x", 1.0, -1},
+ {1.0, -1, "",
+ "1x,, , x ,2x , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif dx, "
+ "2x.gif 2x ,",
+ "1x", 1.0, -1}, // 40
+ {5.0, -1, "",
+ "1x,, , x ,2x , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif dx, "
+ "2x.gif 2x ,",
+ "1x", 1.0, -1},
+ {2.0, -1, "",
+ "1x.gif 1x, "
+ "data:image/"
+ "svg+xml;base64,"
+ "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGh"
+ "laWdodD0iMTAwIj4KCTxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPSJncm"
+ "VlbiIvPgo8L3N2Zz4K 2x",
+ "1x.gif", 1.0, -1},
+ {2.0, -1, "1x.gif",
+ "data:image/"
+ "svg+xml;base64,"
+ "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGh"
+ "laWdodD0iMTAwIj4KCTxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPSJncm"
+ "VlbiIvPgo8L3N2Zz4K 2x",
+ "1x.gif", 1.0, -1},
+ {2.0, -1, "1x.svg#red", "1x.svg#green 2x", "1x.svg#red", 1.0, -1},
+ {2.0, -1, "", "1x.svg#red 1x, 1x.svg#green 2x", "1x.svg#red", 1.0,
+ -1}, // 45
+ {1.0, 400, "", "400.gif 400w, 6000.gif 6000w", "400.gif", 1.0, 400},
+ {1.0, 400, "", "400.gif 400pw, 6000.gif 6000w", "6000.gif", 15.0, 6000},
+ {1.0, 400, "fallback.gif", "400.gif 400pw", "fallback.gif", 1.0, -1},
+ {1.0, 400, "fallback.gif", "400.gif +400w", "fallback.gif", 1.0, -1},
+ {1.0, 400, "", "400.gif 400w 400h, 6000.gif 6000w", "400.gif", 1.0,
+ 400}, // 50
+ {4.0, 400, "", "400.gif 400w, 6000.gif 6000w", "400.gif", 1.0, 400},
+ {3.8, 400, "", "400.gif 400w, 6000.gif 6000w", "400.gif", 1.0, 400},
+ {0.9, 800, "src.gif", "400.gif 400w", "400.gif", 0.5, 400},
+ {0.9, 800, "src.gif", "1x.gif 1x, 400.gif 400w", "400.gif", 0.5, 400},
+ {0.9, 800, "src.gif", "1x.gif 0.6x, 400.gif 400w", "400.gif", 0.5,
+ 400}, // 55
+ {0.9, 800, "src.gif", "1x.gif 1x, 400.gif 720w", "400.gif", 0.9, 720},
+ {0.9, 800, "src.gif", "1x.gif 1x, 400.gif 719w", "400.gif", 719.0 / 800.0,
+ 719},
+ {2.0, 800, "src.gif", "400.gif 400w", "400.gif", 0.5, 400},
+ {1.0, 400, "src.gif", "800.gif 800w", "800.gif", 2.0, 800},
+ {1.0, 400, "src.gif", "0.gif 0w, 800.gif 800w", "800.gif", 2.0,
+ 800}, // 60
+ {1.0, 400, "src.gif", "0.gif 0w, 2x.gif 2x", "src.gif", 1.0, -1},
+ {1.0, 400, "src.gif", "800.gif 2x, 1600.gif 1600w", "800.gif", 2.0, -1},
+ {1.0, 400, "", "400.gif 400w, 2x.gif 2x", "400.gif", 1.0, 400},
+ {2.0, 400, "", "400.gif 400w, 2x.gif 2x", "400.gif", 1.0, 400},
+ {1.0, 0, "", "400.gif 400w, 6000.gif 6000w", "400.gif",
+ std::numeric_limits<float>::infinity(), 400}, // 65
+ {2.0, -1, "", ", 1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
+ {1.0, -1, "", ",1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
+ {1.0, -1, "", ",1x.gif 1.x , 2x.gif 2x", "2x.gif", 2.0, -1},
+ {1.2, -1, "", ",1x.gif 1x, 1.4x.gif 1.4x, 2x.gif 2x", "1x.gif", 1.0, -1},
+ {1.0, -1, "", "inf.gif 0.00000000001x", "inf.gif", 1e-11, -1}, // 70
+ {1.0, -1, "", "data:,a ( , data:,b 1x, ), data:,c", "data:,c", 1.0, -1},
+ {1.0, 1, "", "data:,a 1w 1h", "data:,a", 1.0, 1},
+ {1.0, -1, "", ",1x.gif 1x future-descriptor(3x, 4h, whatever), 2x.gif 2x",
+ "2x.gif", 2.0, -1},
+ {2.0, -1, "", ",1x.gif 1x future-descriptor(3x, 4h, whatever), 2x.gif 2x",
+ "2x.gif", 2.0, -1},
+ {1.0, -1, "", "data:,a 1 w", "", 1.0, -1}, // 75
+ {1.0, -1, "", "data:,a 1 w", "", 1.0, -1},
+ {1.0, -1, "", "data:,a +1x", "", 1.0, -1},
+ {1.0, -1, "", "data:,a +1x", "", 1.0, -1},
+ {1.0, -1, "", "data:,a 1.0x", "data:,a", 1.0, -1},
+ {1.0, -1, "", "1%20and%202.gif 1x", "1%20and%202.gif", 1.0, -1}, // 80
+ {1.0, 700, "", "data:,a 0.5x, data:,b 1400w", "data:,a", 0.5, -1},
+ {0, 0, nullptr, nullptr, nullptr,
+ 0} // Do not remove the terminator line.
+ };
+
+ blink::WebNetworkStateNotifier::SetSaveDataEnabled(true);
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitWithFeatures({blink::features::kSaveDataImgSrcset},
+ {});
+ for (unsigned i = 0; test_cases[i].src_input; ++i) {
+ SrcsetParserTestCase test = test_cases[i];
+ ImageCandidate candidate = BestFitSourceForImageAttributes(
+ test.device_scale_factor, test.effective_size, test.src_input,
+ test.srcset_input);
+ ASSERT_EQ(test.output_density, candidate.Density());
+ ASSERT_EQ(test.output_resource_width, candidate.GetResourceWidth());
+ ASSERT_EQ(test.output_url, candidate.ToString().Ascii());
+ }
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_tokenizer.cc b/chromium/third_party/blink/renderer/core/html/parser/html_tokenizer.cc
index 5340cb22bab..241efc1df37 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_tokenizer.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_tokenizer.cc
@@ -1465,7 +1465,7 @@ void HTMLTokenizer::UpdateStateFor(const String& tag_name) {
ThreadSafeMatch(tag_name, html_names::kNoembedTag) ||
ThreadSafeMatch(tag_name, html_names::kNoframesTag) ||
(ThreadSafeMatch(tag_name, html_names::kNoscriptTag) &&
- options_.script_enabled))
+ options_.scripting_flag))
SetState(HTMLTokenizer::kRAWTEXTState);
}
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_tokenizer_fuzzer.cc b/chromium/third_party/blink/renderer/core/html/parser/html_tokenizer_fuzzer.cc
index e0fb488daa7..a21c158d304 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_tokenizer_fuzzer.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_tokenizer_fuzzer.cc
@@ -20,7 +20,7 @@ int FuzzTokenizer(const uint8_t* data, size_t size) {
// Use the first byte of fuzz data to randomize the tokenizer options.
HTMLParserOptions options;
- options.script_enabled = fuzzed_data_provider.ConsumeBool();
+ options.scripting_flag = fuzzed_data_provider.ConsumeBool();
std::unique_ptr<HTMLTokenizer> tokenizer =
std::make_unique<HTMLTokenizer>(options);
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 a33e0b6aca0..24f19c4dc6e 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
@@ -32,6 +32,7 @@
#include "third_party/blink/renderer/core/dom/document.h"
#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/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"
@@ -43,6 +44,7 @@
#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_names.h"
+#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/mathml_names.h"
#include "third_party/blink/renderer/core/svg_names.h"
#include "third_party/blink/renderer/core/xlink_names.h"
@@ -765,7 +767,7 @@ void HTMLTreeBuilder::ProcessStartTagForInBody(AtomicHTMLToken* token) {
Attribute* type_attribute = token->GetAttributeItem(html_names::kTypeAttr);
bool disable_frameset =
!type_attribute ||
- !DeprecatedEqualIgnoringCase(type_attribute->Value(), "hidden");
+ !EqualIgnoringASCIICase(type_attribute->Value(), "hidden");
tree_.ReconstructTheActiveFormattingElements();
tree_.InsertSelfClosingHTMLElementDestroyingToken(token);
@@ -812,7 +814,7 @@ void HTMLTreeBuilder::ProcessStartTagForInBody(AtomicHTMLToken* token) {
ProcessGenericRawTextStartTag(token);
return;
}
- if (token->GetName() == html_names::kNoscriptTag && options_.script_enabled) {
+ if (token->GetName() == html_names::kNoscriptTag && options_.scripting_flag) {
ProcessGenericRawTextStartTag(token);
return;
}
@@ -909,10 +911,50 @@ bool HTMLTreeBuilder::ProcessTemplateEndTag(AtomicHTMLToken* token) {
tree_.GenerateImpliedEndTags();
if (!tree_.CurrentStackItem()->HasTagName(html_names::kTemplateTag))
ParseError(token);
- tree_.OpenElements()->PopUntilPopped(html_names::kTemplateTag);
+ tree_.OpenElements()->PopUntil(html_names::kTemplateTag.LocalName());
+ HTMLStackItem* template_stack_item =
+ tree_.OpenElements()->TopRecord()->StackItem();
+ tree_.OpenElements()->Pop();
+ HTMLStackItem* shadow_host_stack_item =
+ tree_.OpenElements()->TopRecord()->StackItem();
tree_.ActiveFormattingElements()->ClearToLastMarker();
template_insertion_modes_.pop_back();
ResetInsertionModeAppropriately();
+ // Check for a declarative shadow root.
+ if (RuntimeEnabledFeatures::DeclarativeShadowDOMEnabled() &&
+ template_stack_item) {
+ if (Attribute* type_attribute = template_stack_item->GetAttributeItem(
+ html_names::kShadowrootAttr)) {
+ String shadow_mode = type_attribute->Value();
+ bool is_open = EqualIgnoringASCIICase(shadow_mode, "open");
+ if (is_open || EqualIgnoringASCIICase(shadow_mode, "closed")) {
+ DCHECK(template_stack_item->IsElementNode());
+ 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(1063157): Add an attribute for imperative slot assignment.
+ bool manual_slotting = false;
+ shadow_host_stack_item->GetElement()->AttachDeclarativeShadowRoot(
+ DynamicTo<HTMLTemplateElement>(template_stack_item->GetElement()),
+ is_open ? ShadowRootType::kOpen : ShadowRootType::kClosed,
+ delegates_focus ? FocusDelegation::kDelegateFocus
+ : FocusDelegation::kNone,
+ manual_slotting ? SlotAssignmentMode::kManual
+ : SlotAssignmentMode::kAuto);
+ } else {
+ tree_.OwnerDocumentForCurrentNode().AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kOther,
+ mojom::blink::ConsoleMessageLevel::kWarning,
+ "Invalid declarative shadowroot attribute value \"" +
+ shadow_mode +
+ "\". Valid values include \"open\" and \"closed\"."));
+ }
+ }
+ }
return true;
}
@@ -1012,7 +1054,7 @@ void HTMLTreeBuilder::ProcessStartTagForInTable(AtomicHTMLToken* token) {
if (token->GetName() == html_names::kInputTag) {
Attribute* type_attribute = token->GetAttributeItem(html_names::kTypeAttr);
if (type_attribute &&
- DeprecatedEqualIgnoringCase(type_attribute->Value(), "hidden")) {
+ EqualIgnoringASCIICase(type_attribute->Value(), "hidden")) {
ParseError(token);
tree_.InsertSelfClosingHTMLElementDestroyingToken(token);
return;
@@ -2628,7 +2670,7 @@ bool HTMLTreeBuilder::ProcessStartTagForInHead(AtomicHTMLToken* token) {
return true;
}
if (token->GetName() == html_names::kNoscriptTag) {
- if (options_.script_enabled) {
+ if (options_.scripting_flag) {
ProcessGenericRawTextStartTag(token);
return true;
}
diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder_simulator.cc b/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder_simulator.cc
index 3da53b045b1..ea11a426b6c 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder_simulator.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder_simulator.cc
@@ -191,7 +191,7 @@ HTMLTreeBuilderSimulator::SimulatedToken HTMLTreeBuilderSimulator::Simulate(
ThreadSafeMatch(tag_name, html_names::kNoembedTag) ||
ThreadSafeMatch(tag_name, html_names::kNoframesTag) ||
(ThreadSafeMatch(tag_name, html_names::kNoscriptTag) &&
- options_.script_enabled)) {
+ options_.scripting_flag)) {
tokenizer->SetState(HTMLTokenizer::kRAWTEXTState);
}
}
@@ -270,9 +270,9 @@ bool HTMLTreeBuilderSimulator::IsHTMLIntegrationPointForStartTag(
}
} else if (tokens_ns == SVG) {
// FIXME: It's very fragile that we special case foreignObject here to be
- // case-insensitive.
- if (DeprecatedEqualIgnoringCase(tag_name,
- svg_names::kForeignObjectTag.LocalName()))
+ // ASCII case-insensitive.
+ if (EqualIgnoringASCIICase(tag_name,
+ svg_names::kForeignObjectTag.LocalName()))
return true;
return ThreadSafeMatch(tag_name, svg_names::kDescTag) ||
ThreadSafeMatch(tag_name, svg_names::kTitleTag);
@@ -299,9 +299,9 @@ bool HTMLTreeBuilderSimulator::IsHTMLIntegrationPointForEndTag(
return ThreadSafeMatch(tag_name, mathml_names::kAnnotationXmlTag);
if (tokens_ns == SVG) {
// FIXME: It's very fragile that we special case foreignObject here to be
- // case-insensitive.
- if (DeprecatedEqualIgnoringCase(tag_name,
- svg_names::kForeignObjectTag.LocalName()))
+ // ASCII case-insensitive.
+ if (EqualIgnoringASCIICase(tag_name,
+ svg_names::kForeignObjectTag.LocalName()))
return true;
return ThreadSafeMatch(tag_name, svg_names::kDescTag) ||
ThreadSafeMatch(tag_name, svg_names::kTitleTag);
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 2e98f7e4ad8..3bd21514f75 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(), mime_type);
+ DocumentInit::Create().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_scripting_flag_policy.h b/chromium/third_party/blink/renderer/core/html/parser/parser_scripting_flag_policy.h
new file mode 100644
index 00000000000..48d44e856e0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/parser/parser_scripting_flag_policy.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PARSER_PARSER_SCRIPTING_FLAG_POLICY_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PARSER_PARSER_SCRIPTING_FLAG_POLICY_H_
+
+namespace blink {
+
+// Decides whether the scripting flag of the parser should be set to enabled.
+// https://html.spec.whatwg.org/#scripting-flag
+enum class ParserScriptingFlagPolicy { kOnlyIfScriptIsEnabled, kEnabled };
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PARSER_PARSER_SCRIPTING_FLAG_POLICY_H_
diff --git a/chromium/third_party/blink/renderer/core/html/parser/preload_request.cc b/chromium/third_party/blink/renderer/core/html/parser/preload_request.cc
index b90b9f0936b..a355cb13d0b 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/preload_request.cc
+++ b/chromium/third_party/blink/renderer/core/html/parser/preload_request.cc
@@ -28,6 +28,33 @@ KURL PreloadRequest::CompleteURL(Document* document) {
return document->CompleteURL(resource_url_);
}
+// static
+std::unique_ptr<PreloadRequest> PreloadRequest::CreateIfNeeded(
+ const String& initiator_name,
+ const TextPosition& initiator_position,
+ const String& resource_url,
+ const KURL& base_url,
+ ResourceType resource_type,
+ const network::mojom::ReferrerPolicy referrer_policy,
+ ReferrerSource referrer_source,
+ ResourceFetcher::IsImageSet is_image_set,
+ const FetchParameters::ResourceWidth& resource_width,
+ const ClientHintsPreferences& client_hints_preferences,
+ RequestType request_type) {
+ // Never preload data URLs. We also disallow relative ref URLs which become
+ // data URLs if the document's URL is a data URL. We don't want to create
+ // extra resource requests with data URLs to avoid copy / initialization
+ // overhead, which can be significant for large URLs.
+ if (resource_url.IsEmpty() || resource_url.StartsWith("#") ||
+ ProtocolIs(resource_url, "data")) {
+ return nullptr;
+ }
+ return base::WrapUnique(new PreloadRequest(
+ initiator_name, initiator_position, resource_url, base_url, resource_type,
+ resource_width, client_hints_preferences, request_type, referrer_policy,
+ referrer_source, is_image_set));
+}
+
Resource* PreloadRequest::Start(Document* document) {
DCHECK(IsMainThread());
@@ -47,6 +74,8 @@ Resource* PreloadRequest::Start(Document* document) {
resource_request.SetRequestContext(
ResourceFetcher::DetermineRequestContext(resource_type_, is_image_set_));
+ resource_request.SetRequestDestination(
+ ResourceFetcher::DetermineRequestDestination(resource_type_));
resource_request.SetFetchImportanceMode(importance_);
@@ -59,7 +88,7 @@ Resource* PreloadRequest::Start(Document* document) {
ResourceLoaderOptions options;
options.initiator_info = initiator_info;
- FetchParameters params(resource_request, options);
+ FetchParameters params(std::move(resource_request), options);
if (resource_type_ == ResourceType::kImportResource) {
const SecurityOrigin* security_origin =
@@ -116,8 +145,7 @@ Resource* PreloadRequest::Start(Document* document) {
params.SetLazyImagePlaceholder();
}
- return PreloadHelper::StartPreload(resource_type_, params,
- document->Fetcher());
+ return PreloadHelper::StartPreload(resource_type_, params, *document);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/parser/preload_request.h b/chromium/third_party/blink/renderer/core/html/parser/preload_request.h
index afb88f92b21..761f071fa3f 100644
--- a/chromium/third_party/blink/renderer/core/html/parser/preload_request.h
+++ b/chromium/third_party/blink/renderer/core/html/parser/preload_request.h
@@ -39,8 +39,6 @@ class CORE_EXPORT PreloadRequest {
enum ReferrerSource { kDocumentIsReferrer, kBaseUrlIsReferrer };
- // TODO(csharrison): Move the implementation to the cpp file when core/html
- // gets its own testing source set in html/BUILD.gn.
static std::unique_ptr<PreloadRequest> CreateIfNeeded(
const String& initiator_name,
const TextPosition& initiator_position,
@@ -54,20 +52,7 @@ class CORE_EXPORT PreloadRequest {
FetchParameters::ResourceWidth(),
const ClientHintsPreferences& client_hints_preferences =
ClientHintsPreferences(),
- RequestType request_type = kRequestTypePreload) {
- // Never preload data URLs. We also disallow relative ref URLs which become
- // data URLs if the document's URL is a data URL. We don't want to create
- // extra resource requests with data URLs to avoid copy / initialization
- // overhead, which can be significant for large URLs.
- if (resource_url.IsEmpty() || resource_url.StartsWith("#") ||
- ProtocolIs(resource_url, "data")) {
- return nullptr;
- }
- return base::WrapUnique(new PreloadRequest(
- initiator_name, initiator_position, resource_url, base_url,
- resource_type, resource_width, client_hints_preferences, request_type,
- referrer_policy, referrer_source, is_image_set));
- }
+ RequestType request_type = kRequestTypePreload);
Resource* Start(Document*);
@@ -167,25 +152,25 @@ class CORE_EXPORT PreloadRequest {
KURL CompleteURL(Document*);
- String initiator_name_;
- TextPosition initiator_position_;
- String resource_url_;
- KURL base_url_;
+ const String initiator_name_;
+ const TextPosition initiator_position_;
+ const String resource_url_;
+ const KURL base_url_;
String charset_;
- ResourceType resource_type_;
+ const ResourceType resource_type_;
mojom::ScriptType script_type_;
CrossOriginAttributeValue cross_origin_;
mojom::FetchImportanceMode importance_;
String nonce_;
FetchParameters::DeferOption defer_;
- FetchParameters::ResourceWidth resource_width_;
- ClientHintsPreferences client_hints_preferences_;
- RequestType request_type_;
- network::mojom::ReferrerPolicy referrer_policy_;
- ReferrerSource referrer_source_;
+ const FetchParameters::ResourceWidth resource_width_;
+ const ClientHintsPreferences client_hints_preferences_;
+ const RequestType request_type_;
+ const network::mojom::ReferrerPolicy referrer_policy_;
+ const ReferrerSource referrer_source_;
IntegrityMetadataSet integrity_metadata_;
bool from_insertion_scanner_;
- ResourceFetcher::IsImageSet is_image_set_;
+ const ResourceFetcher::IsImageSet is_image_set_;
bool is_lazy_load_image_enabled_;
};
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 8d4a4999220..5ff78584883 100644
--- a/chromium/third_party/blink/renderer/core/html/plugin_document.cc
+++ b/chromium/third_party/blink/renderer/core/html/plugin_document.cc
@@ -133,9 +133,9 @@ void PluginDocumentParser::CreateDocumentStructure() {
return;
}
- ToPluginDocument(GetDocument())->SetPluginNode(embed_element_);
+ To<PluginDocument>(GetDocument())->SetPluginNode(embed_element_);
- GetDocument()->UpdateStyleAndLayout();
+ GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kPlugin);
// We need the plugin to load synchronously so we can get the
// WebPluginContainerImpl below so flush the layout tasks now instead of
@@ -177,13 +177,12 @@ void PluginDocumentParser::StopParsing() {
}
WebPluginContainerImpl* PluginDocumentParser::GetPluginView() const {
- return ToPluginDocument(GetDocument())->GetPluginView();
+ return To<PluginDocument>(GetDocument())->GetPluginView();
}
-PluginDocument::PluginDocument(const DocumentInit& initializer,
- Color background_color)
+PluginDocument::PluginDocument(const DocumentInit& initializer)
: HTMLDocument(initializer, kPluginDocumentClass),
- background_color_(background_color) {
+ background_color_(initializer.GetPluginBackgroundColor()) {
SetCompatibilityMode(kQuirksMode);
LockCompatibilityMode();
if (GetScheduler()) {
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 998a4342a13..d2faa0e365e 100644
--- a/chromium/third_party/blink/renderer/core/html/plugin_document.h
+++ b/chromium/third_party/blink/renderer/core/html/plugin_document.h
@@ -36,7 +36,7 @@ class WebPluginContainerImpl;
class CORE_EXPORT PluginDocument final : public HTMLDocument {
public:
- PluginDocument(const DocumentInit&, Color background_color);
+ PluginDocument(const DocumentInit&);
void SetPluginNode(HTMLPlugInElement* plugin_node) {
plugin_node_ = plugin_node;
@@ -59,7 +59,12 @@ class CORE_EXPORT PluginDocument final : public HTMLDocument {
const Color background_color_;
};
-DEFINE_DOCUMENT_TYPE_CASTS(PluginDocument);
+template <>
+struct DowncastTraits<PluginDocument> {
+ static bool AllowFrom(const Document& document) {
+ return document.IsPluginDocument();
+ }
+};
} // namespace blink
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 dc78314b2eb..6d3bc25c35c 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
@@ -5,7 +5,6 @@
#include "third_party/blink/renderer/core/html/portal/html_portal_element.h"
#include <utility>
-#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/mojom/referrer.mojom-blink.h"
#include "third_party/blink/public/mojom/web_feature/web_feature.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_event_listener.h"
@@ -13,6 +12,8 @@
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_portal_activate_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_window_post_message_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/dom/node.h"
@@ -22,11 +23,10 @@
#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/remote_frame.h"
-#include "third_party/blink/renderer/core/frame/window_post_message_options.h"
+#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html/html_unknown_element.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/core/html/portal/document_portals.h"
-#include "third_party/blink/renderer/core/html/portal/portal_activate_options.h"
#include "third_party/blink/renderer/core/html/portal/portal_contents.h"
#include "third_party/blink/renderer/core/html/portal/portal_post_message_helper.h"
#include "third_party/blink/renderer/core/html_names.h"
@@ -97,11 +97,39 @@ void HTMLPortalElement::PortalContentsWillBeDestroyed(PortalContents* portal) {
portal_ = nullptr;
}
+bool HTMLPortalElement::CheckPortalsEnabledOrWarn() const {
+ Document& document = GetDocument();
+ if (RuntimeEnabledFeatures::PortalsEnabled(&document))
+ return true;
+
+ // TODO(jbroman): Consider linking to origin trial info if applicable.
+ document.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."));
+ return false;
+}
+
+bool HTMLPortalElement::CheckPortalsEnabledOrThrow(
+ ExceptionState& exception_state) const {
+ Document& document = GetDocument();
+ if (RuntimeEnabledFeatures::PortalsEnabled(&document))
+ 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.");
+ return false;
+}
+
// https://wicg.github.io/portals/#htmlportalelement-may-have-a-guest-browsing-context
HTMLPortalElement::GuestContentsEligibility
HTMLPortalElement::GetGuestContentsEligibility() const {
// Non-HTML documents aren't eligible at all.
- if (!GetDocument().IsHTMLDocument())
+ if (!IsA<HTMLDocument>(GetDocument()))
return GuestContentsEligibility::kIneligible;
LocalFrame* frame = GetDocument().GetFrame();
@@ -120,6 +148,9 @@ HTMLPortalElement::GetGuestContentsEligibility() const {
}
void HTMLPortalElement::Navigate() {
+ if (!CheckPortalsEnabledOrWarn())
+ return;
+
if (portal_) {
portal_->Navigate(GetNonEmptyURLAttribute(html_names::kSrcAttr),
ReferrerPolicyAttribute());
@@ -186,6 +217,8 @@ BlinkTransferableMessage ActivateDataAsMessage(
ScriptPromise HTMLPortalElement::activate(ScriptState* script_state,
PortalActivateOptions* options,
ExceptionState& exception_state) {
+ if (!CheckPortalsEnabledOrThrow(exception_state))
+ return ScriptPromise();
if (!portal_) {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidStateError,
@@ -231,6 +264,9 @@ void HTMLPortalElement::postMessage(ScriptState* script_state,
const ScriptValue& message,
const WindowPostMessageOptions* options,
ExceptionState& exception_state) {
+ if (!CheckPortalsEnabledOrThrow(exception_state))
+ return;
+
if (!portal_) {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidStateError,
@@ -274,23 +310,29 @@ const base::UnguessableToken& HTMLPortalElement::GetToken() const {
return portal_->GetToken();
}
-HTMLPortalElement::InsertionNotificationRequest HTMLPortalElement::InsertedInto(
+Node::InsertionNotificationRequest HTMLPortalElement::InsertedInto(
ContainerNode& node) {
auto result = HTMLFrameOwnerElement::InsertedInto(node);
+ if (!CheckPortalsEnabledOrWarn())
+ return result;
+
+ if (!SubframeLoadingDisabler::CanLoadFrame(*this))
+ return result;
+
switch (GetGuestContentsEligibility()) {
case GuestContentsEligibility::kIneligible:
return result;
case GuestContentsEligibility::kNotTopLevel:
- GetDocument().AddConsoleMessage(ConsoleMessage::Create(
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kRendering,
mojom::ConsoleMessageLevel::kWarning,
"Cannot use <portal> in a nested browsing context."));
return result;
case GuestContentsEligibility::kNotHTTPFamily:
- GetDocument().AddConsoleMessage(ConsoleMessage::Create(
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kRendering,
mojom::ConsoleMessageLevel::kWarning,
"<portal> use is restricted to the HTTP family."));
@@ -341,6 +383,12 @@ void HTMLPortalElement::RemovedFrom(ContainerNode& node) {
HTMLFrameOwnerElement::RemovedFrom(node);
}
+void HTMLPortalElement::DefaultEventHandler(Event& event) {
+ if (HandleKeyboardActivation(event))
+ return;
+ HTMLFrameOwnerElement::DefaultEventHandler(event);
+}
+
bool HTMLPortalElement::IsURLAttribute(const Attribute& attribute) const {
return attribute.GetName() == html_names::kSrcAttr ||
HTMLFrameOwnerElement::IsURLAttribute(attribute);
@@ -387,6 +435,10 @@ LayoutObject* HTMLPortalElement::CreateLayoutObject(const ComputedStyle& style,
return new LayoutIFrame(this);
}
+bool HTMLPortalElement::SupportsFocus() const {
+ return true;
+}
+
void HTMLPortalElement::DisconnectContentFrame() {
HTMLFrameOwnerElement::DisconnectContentFrame();
ConsumePortal();
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 a0c54d70ff2..42fe448d85a 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/wtf/casting.h"
namespace blink {
@@ -39,6 +40,8 @@ class CORE_EXPORT HTMLPortalElement : public HTMLFrameOwnerElement {
portal_client_receiver = {});
~HTMLPortalElement() override;
+ bool IsHTMLPortalElement() const final { return true; }
+
// ScriptWrappable overrides.
void Trace(Visitor* visitor) override;
@@ -77,6 +80,12 @@ class CORE_EXPORT HTMLPortalElement : public HTMLFrameOwnerElement {
void PortalContentsWillBeDestroyed(PortalContents*);
private:
+ // Checks whether the Portals feature is enabled for this document, and logs a
+ // warning to the developer if not. Doing basically anything with an
+ // HTMLPortalElement in a document which doesn't support portals is forbidden.
+ bool CheckPortalsEnabledOrWarn() const;
+ bool CheckPortalsEnabledOrThrow(ExceptionState&) const;
+
enum class GuestContentsEligibility {
// Can have a guest contents.
kEligible,
@@ -101,11 +110,13 @@ class CORE_EXPORT HTMLPortalElement : public HTMLFrameOwnerElement {
// Node overrides
InsertionNotificationRequest InsertedInto(ContainerNode&) override;
void RemovedFrom(ContainerNode&) override;
+ void DefaultEventHandler(Event&) override;
// Element overrides
bool IsURLAttribute(const Attribute&) const override;
void ParseAttribute(const AttributeModificationParams&) override;
LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override;
+ bool SupportsFocus() const override;
// HTMLFrameOwnerElement overrides
void DisconnectContentFrame() override;
@@ -124,6 +135,20 @@ class CORE_EXPORT HTMLPortalElement : public HTMLFrameOwnerElement {
bool was_just_adopted_ = false;
};
+// Type casting. Custom since adoption could lead to an HTMLPortalElement ending
+// up in a document that doesn't have Portals enabled.
+template <>
+struct DowncastTraits<HTMLPortalElement> {
+ static bool AllowFrom(const HTMLElement& element) {
+ return element.IsHTMLPortalElement();
+ }
+ static bool AllowFrom(const Node& node) {
+ if (const HTMLElement* html_element = DynamicTo<HTMLElement>(node))
+ return html_element->IsHTMLPortalElement();
+ return false;
+ }
+};
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PORTAL_HTML_PORTAL_ELEMENT_H_
diff --git a/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.idl b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.idl
index 4edb54326c1..088c7ff25d7 100644
--- a/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.idl
+++ b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.idl
@@ -9,10 +9,10 @@ interface HTMLPortalElement : HTMLElement {
[CEReactions, Reflect, URL] attribute USVString src;
[CEReactions, Reflect, ReflectOnly=("","no-referrer","origin","no-referrer-when-downgrade","origin-when-cross-origin","unsafe-url"), ReflectMissing="", ReflectInvalid=""] attribute DOMString referrerPolicy;
- [CallWith=ScriptState, RaisesException, Measure] Promise<void> activate(optional PortalActivateOptions options);
+ [CallWith=ScriptState, RaisesException, Measure] Promise<void> activate(optional PortalActivateOptions options = {});
[CallWith=ScriptState, RaisesException, Measure] void postMessage(any message, DOMString targetOrigin,
optional sequence<object> transfer = []);
- [CallWith=ScriptState, RaisesException, Measure] void postMessage(any message, optional WindowPostMessageOptions options);
+ [CallWith=ScriptState, RaisesException, Measure] void postMessage(any message, optional WindowPostMessageOptions options = {});
attribute EventHandler onmessage;
attribute EventHandler onmessageerror;
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
new file mode 100644
index 00000000000..7cbf44baa53
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element_test.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/core/html/portal/html_portal_element.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_portal_activate_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_window_post_message_options.h"
+#include "third_party/blink/renderer/core/dom/document.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/inspector/console_message_storage.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/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
+
+namespace blink {
+namespace {
+
+using HTMLPortalElementTest = PageTestBase;
+
+// Virtually all operations should bail out before anything else if this
+// HTMLPortalElement is not in a document where portals are enabled.
+//
+// For this test, we currently emulate this by just turning them off everywhere.
+// :)
+TEST_F(HTMLPortalElementTest, PortalsDisabledInDocument) {
+ Document& document = GetDocument();
+ auto* portal = MakeGarbageCollected<HTMLPortalElement>(document);
+ ScopedPortalsForTest disable_portals(false);
+ ASSERT_FALSE(RuntimeEnabledFeatures::PortalsEnabled(&document));
+
+ DummyExceptionStateForTesting exception_state;
+ ScriptState* script_state = ToScriptStateForMainWorld(&GetFrame());
+ const auto& console_messages = GetPage().GetConsoleMessageStorage();
+
+ portal->activate(script_state, MakeGarbageCollected<PortalActivateOptions>(),
+ exception_state);
+ EXPECT_TRUE(exception_state.HadException());
+ EXPECT_EQ(DOMExceptionCode::kNotSupportedError,
+ exception_state.CodeAs<DOMExceptionCode>());
+ exception_state.ClearException();
+
+ portal->postMessage(
+ script_state, ScriptValue::CreateNull(script_state->GetIsolate()),
+ MakeGarbageCollected<WindowPostMessageOptions>(), exception_state);
+ EXPECT_TRUE(exception_state.HadException());
+ EXPECT_EQ(DOMExceptionCode::kNotSupportedError,
+ exception_state.CodeAs<DOMExceptionCode>());
+ exception_state.ClearException();
+
+ auto next_console_message = console_messages.size();
+ GetDocument().body()->appendChild(portal, ASSERT_NO_EXCEPTION);
+ EXPECT_EQ(next_console_message + 1, console_messages.size());
+ EXPECT_TRUE(console_messages.at(next_console_message)
+ ->Message()
+ .Contains("was moved to a document"));
+
+ next_console_message = console_messages.size();
+ portal->setAttribute(html_names::kSrcAttr, String("http://example.com/"),
+ ASSERT_NO_EXCEPTION);
+ EXPECT_EQ(next_console_message + 1, console_messages.size());
+ EXPECT_TRUE(console_messages.at(next_console_message)
+ ->Message()
+ .Contains("was moved to a document"));
+}
+
+} // namespace
+} // namespace blink
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 bf52e696851..17116bee848 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
@@ -7,11 +7,11 @@
#include <utility>
#include "third_party/blink/public/mojom/portal/portal.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_portal_activate_event_init.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/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/portal/html_portal_element.h"
-#include "third_party/blink/renderer/core/html/portal/portal_activate_event_init.h"
#include "third_party/blink/renderer/core/messaging/message_port.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
@@ -105,7 +105,7 @@ ScriptValue PortalActivateEvent::data(ScriptState* script_state) {
return ScriptValue(isolate, value);
}
-void PortalActivateEvent::Trace(blink::Visitor* visitor) {
+void PortalActivateEvent::Trace(Visitor* visitor) {
Event::Trace(visitor);
visitor->Trace(document_);
visitor->Trace(adopted_portal_);
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 ca37c899308..41d3a4e0c41 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// Event overrides
const AtomicString& InterfaceName() const override;
diff --git a/chromium/third_party/blink/renderer/core/html/portal/portal_activate_event.idl b/chromium/third_party/blink/renderer/core/html/portal/portal_activate_event.idl
index 228b4090eca..7db3b3f08f2 100644
--- a/chromium/third_party/blink/renderer/core/html/portal/portal_activate_event.idl
+++ b/chromium/third_party/blink/renderer/core/html/portal/portal_activate_event.idl
@@ -4,8 +4,10 @@
// https://wicg.github.io/portals/#the-portalactivateevent-interface
-[Constructor(DOMString type, optional PortalActivateEventInit eventInitDict), Exposed=Window, RuntimeEnabled=Portals]
-interface PortalActivateEvent : Event {
+[
+ Exposed=Window, RuntimeEnabled=Portals
+] interface PortalActivateEvent : Event {
+ constructor(DOMString type, optional PortalActivateEventInit eventInitDict = {});
[CallWith=ScriptState, Measure] readonly attribute any data;
[RaisesException, Measure] HTMLPortalElement adoptPredecessor();
};
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 4ef0401a432..3c6dba14fce 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
@@ -8,8 +8,8 @@
#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"
-#include "third_party/blink/renderer/core/dom/document_shutdown_observer.h"
#include "third_party/blink/renderer/core/dom/increment_load_event_delay_count.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/frame/remote_frame.h"
#include "third_party/blink/renderer/core/html/portal/document_portals.h"
#include "third_party/blink/renderer/core/html/portal/html_portal_element.h"
@@ -33,7 +33,7 @@ PortalContents::PortalContents(
remote_portal_(std::move(remote_portal)),
portal_client_receiver_(this, std::move(portal_client_receiver)) {
remote_portal_.set_disconnect_handler(
- WTF::Bind(&PortalContents::Destroy, WrapWeakPersistent(this)));
+ WTF::Bind(&PortalContents::DisconnectHandler, WrapWeakPersistent(this)));
DocumentPortals::From(GetDocument()).RegisterPortalContents(this);
}
@@ -71,6 +71,23 @@ ScriptPromise PortalContents::Activate(ScriptState* script_state,
void PortalContents::OnActivateResponse(
mojom::blink::PortalActivateResult result) {
+ auto reject = [&](DOMExceptionCode code, const char* message) {
+ if (GetDocument().IsContextDestroyed())
+ return;
+
+ ScriptState* script_state = activate_resolver_->GetScriptState();
+ ScriptState::Scope scope(script_state);
+ // TODO(jbroman): It's slightly unfortunate to hard-code the string
+ // HTMLPortalElement here. Ideally this would be threaded through from
+ // there and carried with the ScriptPromiseResolver. See
+ // https://crbug.com/991544.
+ ExceptionState exception_state(script_state->GetIsolate(),
+ ExceptionState::kExecutionContext,
+ "HTMLPortalElement", "activate");
+ exception_state.ThrowDOMException(code, message);
+ activate_resolver_->Reject(exception_state);
+ };
+
bool should_destroy_contents = false;
switch (result) {
case mojom::blink::PortalActivateResult::kPredecessorWasAdopted:
@@ -82,24 +99,19 @@ void PortalContents::OnActivateResponse(
break;
case mojom::blink::PortalActivateResult::
- kRejectedDueToPredecessorNavigation: {
- if (!GetDocument().IsContextDestroyed()) {
- ScriptState* script_state = activate_resolver_->GetScriptState();
- ScriptState::Scope scope(script_state);
- // TODO(jbroman): It's slightly unfortunate to hard-code the string
- // HTMLPortalElement here. Ideally this would be threaded through from
- // there and carried with the ScriptPromiseResolver. See
- // https://crbug.com/991544.
- ExceptionState exception_state(script_state->GetIsolate(),
- ExceptionState::kExecutionContext,
- "HTMLPortalElement", "activate");
- exception_state.ThrowDOMException(
- DOMExceptionCode::kInvalidStateError,
- "A top-level navigation is in progress.");
- activate_resolver_->Reject(exception_state);
- }
+ kRejectedDueToPredecessorNavigation:
+ reject(DOMExceptionCode::kInvalidStateError,
+ "A top-level navigation is in progress.");
+ break;
+ case mojom::blink::PortalActivateResult::kRejectedDueToPortalNotReady:
+ reject(DOMExceptionCode::kInvalidStateError,
+ "The portal was not yet ready or was blocked.");
+ break;
+ case mojom::blink::PortalActivateResult::kDisconnected:
+ // Only called when |remote_portal_| is disconnected. This usually happens
+ // when the browser/test runner is being shut down.
+ activate_resolver_->Detach();
break;
- }
case mojom::blink::PortalActivateResult::kAbortedDueToBug:
// This should never happen. Ignore this and wait for the frame to be
// discarded by the browser, if it hasn't already.
@@ -130,7 +142,7 @@ void PortalContents::Navigate(
return;
if (!url.ProtocolIsInHTTPFamily()) {
- GetDocument().AddConsoleMessage(ConsoleMessage::Create(
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kRendering,
mojom::ConsoleMessageLevel::kWarning,
"Portals only allow navigation to protocols in the HTTP family."));
@@ -172,6 +184,12 @@ void PortalContents::Destroy() {
DocumentPortals::From(GetDocument()).DeregisterPortalContents(this);
}
+void PortalContents::DisconnectHandler() {
+ if (IsActivating())
+ OnActivateResponse(mojom::blink::PortalActivateResult::kDisconnected);
+ Destroy();
+}
+
void PortalContents::ForwardMessageFromGuest(
BlinkTransferableMessage message,
const scoped_refptr<const SecurityOrigin>& source_origin,
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 86f1da2db39..82270a20191 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
@@ -79,6 +79,10 @@ class PortalContents : public GarbageCollected<PortalContents>,
// down.
void Destroy();
+ // Called when the connection to the browser-side Portal object is lost.
+ // Cleans up any remaining state.
+ void DisconnectHandler();
+
// blink::mojom::PortalClient implementation
void ForwardMessageFromGuest(
BlinkTransferableMessage message,
@@ -97,7 +101,7 @@ class PortalContents : public GarbageCollected<PortalContents>,
void OnActivateResponse(mojom::blink::PortalActivateResult);
// The document which owns this contents.
- // TODO(jbroman): Should this be a DocumentShutdownObserver instead?
+ // TODO(jbroman): Should this be a ExecutionContextLifecycleObserver instead?
Member<Document> document_;
// The element which owns this contents, if any.
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 42b6924453f..5758bd24cfb 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
@@ -8,13 +8,14 @@
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_window_post_message_options.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_client.h"
-#include "third_party/blink/renderer/core/frame/window_post_message_options.h"
#include "third_party/blink/renderer/core/html/portal/dom_window_portal_host.h"
#include "third_party/blink/renderer/core/html/portal/portal_post_message_helper.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/wtf/text/atomic_string.h"
@@ -47,17 +48,13 @@ const AtomicString& PortalHost::InterfaceName() const {
}
ExecutionContext* PortalHost::GetExecutionContext() const {
- return GetSupplementable()->document();
+ return GetSupplementable();
}
PortalHost* PortalHost::ToPortalHost() {
return this;
}
-Document* PortalHost::GetDocument() const {
- return To<Document>(GetExecutionContext());
-}
-
void PortalHost::OnPortalActivated() {
portal_host_.reset();
}
@@ -86,8 +83,8 @@ void PortalHost::postMessage(ScriptState* script_state,
}
scoped_refptr<const SecurityOrigin> target_origin =
- PostMessageHelper::GetTargetOrigin(options, *GetDocument(),
- exception_state);
+ PostMessageHelper::GetTargetOrigin(
+ options, *GetSupplementable()->document(), exception_state);
if (exception_state.HadException())
return;
@@ -121,15 +118,15 @@ void PortalHost::ReceiveMessage(
BlinkTransferableMessage message,
scoped_refptr<const SecurityOrigin> source_origin,
scoped_refptr<const SecurityOrigin> target_origin) {
- DCHECK(GetDocument()->GetPage()->InsidePortal());
+ DCHECK(GetSupplementable()->GetFrame()->GetPage()->InsidePortal());
PortalPostMessageHelper::CreateAndDispatchMessageEvent(
this, std::move(message), source_origin, target_origin);
}
mojom::blink::PortalHost& PortalHost::GetPortalHostInterface() {
if (!portal_host_) {
- DCHECK(GetDocument()->GetFrame());
- GetDocument()
+ DCHECK(GetSupplementable()->GetFrame());
+ GetSupplementable()
->GetFrame()
->GetRemoteNavigationAssociatedInterfaces()
->GetInterface(&portal_host_);
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 b23977cb65b..49966b02916 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
@@ -9,12 +9,11 @@
#include "third_party/blink/public/mojom/portal/portal.mojom-blink.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/messaging/blink_transferable_message.h"
#include "third_party/blink/renderer/platform/supplementable.h"
namespace blink {
-class Document;
+struct BlinkTransferableMessage;
class ExecutionContext;
class LocalDOMWindow;
class ScriptValue;
@@ -39,8 +38,6 @@ class CORE_EXPORT PortalHost : public EventTargetWithInlineData,
ExecutionContext* GetExecutionContext() const override;
PortalHost* ToPortalHost() override;
- Document* GetDocument() const;
-
// Called immediately before dispatching the onactivate event.
void OnPortalActivated();
diff --git a/chromium/third_party/blink/renderer/core/html/portal/portal_host.idl b/chromium/third_party/blink/renderer/core/html/portal/portal_host.idl
index 572a089f793..4e2ea0c214c 100644
--- a/chromium/third_party/blink/renderer/core/html/portal/portal_host.idl
+++ b/chromium/third_party/blink/renderer/core/html/portal/portal_host.idl
@@ -9,7 +9,7 @@ interface PortalHost : EventTarget {
[RaisesException, CallWith=ScriptState, Measure] void postMessage(any message, DOMString targetOrigin,
optional sequence<object> transfer = []);
[RaisesException, CallWith=ScriptState, Measure] void postMessage(any message,
- optional WindowPostMessageOptions options);
+ optional WindowPostMessageOptions options = {});
attribute EventHandler onmessage;
attribute EventHandler onmessageerror;
diff --git a/chromium/third_party/blink/renderer/core/html/portal/portal_post_message_helper.cc b/chromium/third_party/blink/renderer/core/html/portal/portal_post_message_helper.cc
index 3bf3bb981ff..32a248ec934 100644
--- a/chromium/third_party/blink/renderer/core/html/portal/portal_post_message_helper.cc
+++ b/chromium/third_party/blink/renderer/core/html/portal/portal_post_message_helper.cc
@@ -7,11 +7,11 @@
#include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/transferables.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_window_post_message_options.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/events/message_event.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/user_activation.h"
-#include "third_party/blink/renderer/core/frame/window_post_message_options.h"
#include "third_party/blink/renderer/core/html/portal/html_portal_element.h"
#include "third_party/blink/renderer/core/inspector/main_thread_debugger.h"
#include "third_party/blink/renderer/core/inspector/thread_debugger.h"
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 254b3ef24d7..880f90548e4 100644
--- a/chromium/third_party/blink/renderer/core/html/rel_list.cc
+++ b/chromium/third_party/blink/renderer/core/html/rel_list.cc
@@ -18,6 +18,9 @@ RelList::RelList(Element* element)
: DOMTokenList(*element, html_names::kRelAttr) {}
static HashSet<AtomicString>& SupportedTokensLink() {
+ // There is a use counter for <link rel="monetization"> but the feature is
+ // actually not implemented yet, so "monetization" is not included in the
+ // list below. See https://crbug.com/1031476
DEFINE_STATIC_LOCAL(
HashSet<AtomicString>, tokens,
({
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 eeace5a16ac..e90e0993c0b 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
@@ -8,12 +8,23 @@
* using the refreshed controls UI.
*/
-input,
select,
select:-internal-list-box,
+input,
textarea {
- background-color: #ffffff;
- border-color: #767676;
+ background-color: -internal-light-dark-color(#ffffff, #3B3B3B);
+ border-color: -internal-light-dark-color(#767676, #C3C3C3);
+}
+
+input,
+input[type="email" i],
+input[type="number" i],
+input[type="password" i],
+input[type="search" i],
+input[type="tel" i],
+input[type="text" i],
+input[type="url" i] {
+ padding: 1px 2px;
}
input:disabled,
@@ -24,7 +35,7 @@ textarea:disabled {
input:disabled,
textarea:disabled {
- background-color: rgba(239, 239, 239, 0.3);
+ background-color: -internal-light-dark-color(rgba(239, 239, 239, 0.3), rgba(59, 59, 59, 0.3));
}
select:disabled {
@@ -37,8 +48,8 @@ input[type="reset" i],
input[type="color" i],
input[type="file" i]::-webkit-file-upload-button,
button {
- background-color: #efefef;
- border-color: #767676;
+ background-color: -internal-light-dark-color(#efefef, #4A4A4A);
+ border-color: -internal-light-dark-color(#767676, #C3C3C3);
}
input[type="button" i]:disabled,
@@ -47,9 +58,9 @@ input[type="reset" i]:disabled,
input[type="color" i]:disabled,
input[type="file" i]:disabled::-webkit-file-upload-button,
button:disabled {
- background-color: rgba(239, 239, 239, 0.3);
- border-color: rgba(118, 118, 118, 0.3);
- color: rgba(16, 16, 16, 0.3);
+ background-color: -internal-light-dark-color(rgba(239, 239, 239, 0.3), rgba(19, 1, 1, 0.3));
+ border-color: -internal-light-dark-color(rgba(118, 118, 118, 0.3), rgba(195, 195, 195, 0.3));
+ color: -internal-light-dark-color(rgba(16, 16, 16, 0.3), #aaaaaa);
}
input[type="password" i]::-internal-reveal {
@@ -83,38 +94,33 @@ input[type="range" i]:disabled {
color: #c5c5c5;
}
-meter::-webkit-meter-inner-element::before,
-meter::-webkit-meter-inner-element::after {
- display: block;
- content: "";
- height: 25%;
+meter::-webkit-meter-inner-element:-internal-shadow-host-has-appearance {
+ display: grid;
+ grid-template-rows: 1fr [line1] 2fr [line2] 1fr;
}
meter::-webkit-meter-bar {
- background: #efefef;
+ background: -internal-light-dark-color(#efefef, #4a4a4a);
border-width: thin;
- height: 50%;
+ grid-row-start: line1;
+ grid-row-end: line2;
border-style: solid;
border-color: rgba(118, 118, 118, 0.3);
border-radius: 20px;
box-sizing: border-box;
-}
-
-meter::-internal-meter-clip {
- clip-path: inset(0px round 20px);
- height: 100%;
+ overflow: hidden;
}
meter::-webkit-meter-optimum-value {
- background: #107c10;
+ background: -internal-light-dark-color(#107c10, #74b374)
}
meter::-webkit-meter-suboptimum-value {
- background: #ffb900;
+ background: -internal-light-dark-color(#ffb900, #f2c812)
}
meter::-webkit-meter-even-less-good-value {
- background: #d83b01;
+ background: -internal-light-dark-color(#d83b01, #e98f6d)
}
input[type="date" i]::-webkit-calendar-picker-indicator,
@@ -126,30 +132,45 @@ input[type="week" i]::-webkit-calendar-picker-indicator {
background-repeat: no-repeat;
background-size: contain;
height: 1.2em;
+ margin-inline-start: 24px;
opacity: 1;
outline: none;
padding-bottom: 2px;
- padding-inline-start: 27px;
+ padding-inline-start: 3px;
padding-inline-end: 3px;
padding-top: 2px;
width: 1.2em;
}
+input[type="date" i]::-webkit-calendar-picker-indicator:focus,
+input[type="datetime-local" i]::-webkit-calendar-picker-indicator:focus,
+input[type="month" i]::-webkit-calendar-picker-indicator:focus,
+input[type="week" i]::-webkit-calendar-picker-indicator:focus {
+ outline: solid 2px -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+
input[type="time" i]::-webkit-calendar-picker-indicator {
background-image: -webkit-image-set(url(images/time_icon.svg) 1x);
background-origin: content-box;
background-repeat: no-repeat;
background-size: contain;
height: 1.05em;
+ margin-inline-start: 8px;
opacity: 1;
outline: none;
padding-bottom: 3px;
- padding-inline-start: 11px;
+ padding-inline-start: 3px;
padding-inline-end: 3px;
padding-top: 3px;
width: 1.05em;
}
+input[type="time" i]::-webkit-calendar-picker-indicator:focus {
+ outline: solid 2px -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+
input::-webkit-calendar-picker-indicator:hover {
background-color: initial;
}
@@ -163,7 +184,7 @@ select:-internal-list-box {
}
select:-internal-list-box:enabled option:hover:enabled {
- background-color: #f3f3f3;
+ background-color: initial;
}
/* option selected */
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 590f2d574da..c35e7e764aa 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
@@ -10,8 +10,9 @@
@media forced-colors {
body {
- background-color: Window;
- color: WindowText;
+ background-color: Canvas;
+ color: CanvasText;
+ fill: currentColor;
}
:focus {
@@ -28,7 +29,7 @@
}
fieldset {
- border-color: WindowText;
+ border-color: CanvasText;
}
::placeholder {
@@ -37,9 +38,9 @@
input,
textarea {
- background: Window;
+ background: Canvas;
border-color: ButtonText;
- color: WindowText;
+ color: CanvasText;
}
input:hover,
@@ -82,8 +83,8 @@
input::-webkit-datetime-edit-second-field:focus,
input::-webkit-datetime-edit-week-field:focus,
input::-webkit-datetime-edit-year-field:focus {
- background-color: highlight;
- color: highlighttext;
+ background-color: Highlight;
+ color: HighlightText;
outline: none;
}
@@ -96,7 +97,7 @@
}
input[type="color"]::-webkit-color-swatch {
- border-color: WindowText !important;
+ border-color: CanvasText !important;
}
button,
@@ -134,7 +135,7 @@
}
select:-internal-list-box {
- background-color: Window !important;
+ background-color: Canvas !important;
border-color: ButtonText;
}
@@ -143,17 +144,19 @@
select:-internal-list-box option:disabled:hover,
select:-internal-list-box:disabled option,
select:-internal-list-box:disabled option:hover {
- background-color: Window !important;
+ background-color: Canvas !important;
color: GrayText !important;
}
/* option selected */
select:-internal-list-box:focus option:checked,
select:-internal-list-box:focus option:checked:hover,
+ select:-internal-list-box:focus option:checked:enabled:hover,
select:-internal-list-box option:checked,
- select:-internal-list-box option:checked:hover {
+ select:-internal-list-box option:checked:hover,
+ select:-internal-list-box:enabled option:checked:enabled:hover {
background-color: Highlight !important;
- color: Window !important;
+ color: Canvas !important;
forced-color-adjust: none;
}
@@ -165,19 +168,20 @@
select:-internal-list-box option:checked:disabled,
select:-internal-list-box option:checked:disabled:hover {
background-color: GrayText !important;
- color: Window !important;
+ color: Canvas !important;
forced-color-adjust: none;
}
select:-internal-list-box option:hover {
- background-color: Window;
- color: Highlight;
+ background-color: Highlight !important;
+ color: Canvas;
+ forced-color-adjust: none;
}
select {
- background: Window;
- border-color: WindowText;
- color: WindowText;
+ background: Canvas;
+ border-color: CanvasText;
+ color: CanvasText;
}
select:hover {
@@ -196,7 +200,7 @@
meter::-webkit-meter-bar {
background: ButtonFace;
- border-color: WindowText;
+ border-color: CanvasText;
}
meter::-webkit-meter-even-less-good-value,
@@ -204,4 +208,19 @@
meter::-webkit-meter-suboptimum-value {
background: Highlight;
}
-}
+
+ input:-internal-autofill-previewed,
+ textarea:-internal-autofill-previewed,
+ select:-internal-autofill-previewed {
+ color: WindowText !important;
+ background-color: Window !important;
+ }
+
+ input:-internal-autofill-selected,
+ textarea:-internal-autofill-selected,
+ select:-internal-autofill-selected {
+ color: WindowText !important;
+ background-color: Window !important;
+ }
+
+} \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/core/html/resources/html.css b/chromium/third_party/blink/renderer/core/html/resources/html.css
index 8a714d886e4..f348bcbcf55 100644
--- a/chromium/third_party/blink/renderer/core/html/resources/html.css
+++ b/chromium/third_party/blink/renderer/core/html/resources/html.css
@@ -25,7 +25,6 @@
html {
display: block;
- color: -internal-root-color;
}
/* children of the <head> element all have display:none */
@@ -248,7 +247,8 @@ table {
display: table;
border-collapse: separate;
border-spacing: 2px;
- border-color: gray
+ border-color: gray;
+ box-sizing: border-box
}
thead {
@@ -538,6 +538,7 @@ textarea::-internal-input-suggested {
from the scrollable area instead of from the overrides in
LayoutTextControl{Single,Multi}Line::Scroll{Height,Width}(). */
overflow: hidden !important;
+ overflow-anchor: none;
}
input[type="password" i] {
@@ -571,6 +572,7 @@ input[type="image" i] {
input:-internal-autofill-previewed,
textarea:-internal-autofill-previewed,
select:-internal-autofill-previewed {
+ -webkit-appearance:menulist-button;
background-color: #E8F0FE !important;
background-image:none !important;
color: -internal-light-dark-color(black, white) !important;
@@ -579,6 +581,7 @@ select:-internal-autofill-previewed {
input:-internal-autofill-selected,
textarea:-internal-autofill-selected,
select:-internal-autofill-selected {
+ -webkit-appearance:menulist-button;
background-color: #E8F0FE !important;
background-image:none !important;
color: -internal-light-dark-color(black, white) !important;
@@ -593,6 +596,7 @@ input[type="radio" i], input[type="checkbox" i] {
}
input[type="button" i], input[type="submit" i], input[type="reset" i] {
+ -internal-empty-line-height: fabricated;
-webkit-appearance: push-button; /* AutoAppearanceFor() should match to this. */
-webkit-user-select: none;
white-space: pre
@@ -610,7 +614,7 @@ input[type="button" i], input[type="submit" i], input[type="reset" i], input[typ
align-items: flex-start;
text-align: center;
cursor: default;
- color: ButtonText;
+ color: -internal-light-dark-color(ButtonText, #AAAAAA);
padding: 2px 6px 3px 6px;
border: 2px outset ButtonFace;
background-color: ButtonFace;
@@ -629,7 +633,7 @@ input[type="range" i] {
input[type="range" i]::-webkit-slider-container, input[type="range" i]::-webkit-media-slider-container {
-webkit-appearance: inherit; /* AutoAppearanceFor() should match to this. */
flex: 1;
- min-width: 0;
+ min-inline-size: 0;
box-sizing: border-box;
-webkit-user-modify: read-only !important;
display: flex;
@@ -637,7 +641,7 @@ input[type="range" i]::-webkit-slider-container, input[type="range" i]::-webkit-
input[type="range" i]::-webkit-slider-runnable-track {
flex: 1;
- min-width: 0;
+ min-inline-size: 0;
-webkit-align-self: center;
box-sizing: border-box;
diff --git a/chromium/third_party/blink/renderer/core/html/resources/images/calendar_icon.svg b/chromium/third_party/blink/renderer/core/html/resources/images/calendar_icon.svg
index c625f9d47b7..e2ce2f3fecb 100644
--- a/chromium/third_party/blink/renderer/core/html/resources/images/calendar_icon.svg
+++ b/chromium/third_party/blink/renderer/core/html/resources/images/calendar_icon.svg
@@ -1,3 +1 @@
-<svg width="16" height="15" viewBox="0 0 16 15" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path d="M6 6H7V7H6V6ZM9 12H10V13H9V12ZM12 6H13V7H12V6ZM9 6H10V7H9V6ZM6 8H7V9H6V8ZM3 8H4V9H3V8ZM12 8H13V9H12V8ZM9 8H10V9H9V8ZM6 10H7V11H6V10ZM3 10H4V11H3V10ZM12 10H13V11H12V10ZM9 10H10V11H9V10ZM6 12H7V13H6V12ZM3 12H4V13H3V12ZM16 1V15H0V1H3V0H4V1H12V0H13V1H16ZM1 2V4H15V2H13V3H12V2H4V3H3V2H1ZM15 14V5H1V14H15Z" fill="WindowText"/>
-</svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="15" viewBox="0 0 24 24"><path fill="WindowText" 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/resources/images/time_icon.svg b/chromium/third_party/blink/renderer/core/html/resources/images/time_icon.svg
index eedd2f1b9f6..71a94c0ba2c 100644
--- a/chromium/third_party/blink/renderer/core/html/resources/images/time_icon.svg
+++ b/chromium/third_party/blink/renderer/core/html/resources/images/time_icon.svg
@@ -1,3 +1 @@
-<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path d="M7 14C6.35417 14 5.73177 13.9167 5.13281 13.75C4.53906 13.5833 3.98177 13.349 3.46094 13.0469C2.94531 12.7396 2.47396 12.375 2.04688 11.9531C1.625 11.526 1.26042 11.0547 0.953125 10.5391C0.651042 10.0182 0.416667 9.46094 0.25 8.86719C0.0833333 8.26823 0 7.64583 0 7C0 6.35417 0.0833333 5.73438 0.25 5.14062C0.416667 4.54167 0.651042 3.98438 0.953125 3.46875C1.26042 2.94792 1.625 2.47656 2.04688 2.05469C2.47396 1.6276 2.94531 1.26302 3.46094 0.960938C3.98177 0.653646 4.53906 0.416667 5.13281 0.25C5.73177 0.0833333 6.35417 0 7 0C7.64583 0 8.26562 0.0833333 8.85938 0.25C9.45833 0.416667 10.0156 0.653646 10.5312 0.960938C11.0521 1.26302 11.5234 1.6276 11.9453 2.05469C12.3724 2.47656 12.737 2.94792 13.0391 3.46875C13.3464 3.98438 13.5833 4.54167 13.75 5.14062C13.9167 5.73438 14 6.35417 14 7C14 7.64583 13.9167 8.26823 13.75 8.86719C13.5833 9.46094 13.3464 10.0182 13.0391 10.5391C12.737 11.0547 12.3724 11.526 11.9453 11.9531C11.5234 12.375 11.0521 12.7396 10.5312 13.0469C10.0156 13.349 9.45833 13.5833 8.85938 13.75C8.26562 13.9167 7.64583 14 7 14ZM7 1C6.17188 1 5.39323 1.15885 4.66406 1.47656C3.9401 1.78906 3.30469 2.21875 2.75781 2.76562C2.21615 3.30729 1.78646 3.94271 1.46875 4.67188C1.15625 5.39583 1 6.17188 1 7C1 7.82812 1.15625 8.60677 1.46875 9.33594C1.78646 10.0599 2.21615 10.6953 2.75781 11.2422C3.30469 11.7839 3.9401 12.2135 4.66406 12.5312C5.39323 12.8438 6.17188 13 7 13C7.82812 13 8.60417 12.8438 9.32812 12.5312C10.0573 12.2135 10.6927 11.7839 11.2344 11.2422C11.7812 10.6953 12.2109 10.0599 12.5234 9.33594C12.8411 8.60677 13 7.82812 13 7C13 6.17188 12.8411 5.39583 12.5234 4.67188C12.2109 3.94271 11.7812 3.30729 11.2344 2.76562C10.6927 2.21875 10.0573 1.78906 9.32812 1.47656C8.60417 1.15885 7.82812 1 7 1ZM7 7V3H6V8H10V7H7Z" fill="WindowText"/>
-</svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24"><path fill="WindowText" d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"/><path d="M0 0h24v24H0z" fill="none"/><path d="M12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z"/></svg> \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc b/chromium/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc
index 8fd9326caf0..fd8b95bf73d 100644
--- a/chromium/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc
@@ -26,7 +26,7 @@ class ProgressShadowElementTest : public testing::Test {
};
TEST_F(ProgressShadowElementTest, LayoutObjectIsNeeded) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<progress id='prog' style='-webkit-appearance:none' />
)HTML");
@@ -37,8 +37,7 @@ TEST_F(ProgressShadowElementTest, LayoutObjectIsNeeded) {
auto* shadow_element = To<Element>(progress->GetShadowRoot()->firstChild());
ASSERT_TRUE(shadow_element);
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
progress->SetForceReattachLayoutTree();
GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc);
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 ccdca294b82..ae955ffa21f 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
@@ -89,11 +89,6 @@ const AtomicString& PasswordRevealButton() {
return name;
}
-const AtomicString& SearchDecoration() {
- DEFINE_STATIC_LOCAL(AtomicString, name, ("decoration"));
- return name;
-}
-
const AtomicString& SliderThumb() {
DEFINE_STATIC_LOCAL(AtomicString, name, ("thumb"));
return name;
@@ -109,6 +104,11 @@ const AtomicString& TextFieldContainer() {
return name;
}
+const AtomicString& FileUploadButton() {
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("file-upload-button"));
+ return name;
+}
+
const AtomicString& OptGroupLabel() {
DEFINE_STATIC_LOCAL(AtomicString, name, ("optgroup-label"));
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 3e8859e77cb..128f3ebd3de 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
@@ -48,11 +48,11 @@ const AtomicString& EditingViewPort();
const AtomicString& PickerIndicator();
const AtomicString& Placeholder();
const AtomicString& SearchClearButton();
-const AtomicString& SearchDecoration();
const AtomicString& PasswordRevealButton();
CORE_EXPORT const AtomicString& SliderThumb();
const AtomicString& SliderTrack();
const AtomicString& TextFieldContainer();
+const AtomicString& FileUploadButton();
const AtomicString& OptGroupLabel();
} // namespace shadow_element_names
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
new file mode 100644
index 00000000000..e7f15117ddf
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/subresource_redirect_test.cc
@@ -0,0 +1,120 @@
+// 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 <tuple>
+
+#include "base/test/scoped_feature_list.h"
+#include "third_party/blink/public/common/features.h"
+#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/frame/web_local_frame_impl.h"
+#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
+#include "third_party/blink/renderer/core/style/style_image.h"
+#include "third_party/blink/renderer/core/testing/sim/sim_compositor.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/loader/fetch/resource.h"
+#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
+#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
+#include "third_party/blink/renderer/platform/network/network_state_notifier.h"
+#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+
+namespace blink {
+
+namespace {
+
+Vector<char> ReadTestImage() {
+ return test::ReadFromFile(test::CoreTestDataPath("notifications/500x500.png"))
+ ->CopyAs<Vector<char>>();
+}
+
+class SubresourceRedirectSimTest
+ : public ::testing::WithParamInterface<std::tuple<bool, bool, bool>>,
+ public SimTest {
+ protected:
+ SubresourceRedirectSimTest()
+ : scoped_lazy_image_loading_for_test_(is_lazyload_image_enabled()),
+ scoped_automatic_lazy_image_loading_for_test_(
+ is_lazyload_image_enabled()) {
+ if (is_subresource_redirect_enabled())
+ scoped_feature_list_.InitAndEnableFeature(features::kSubresourceRedirect);
+ GetNetworkStateNotifier().SetSaveDataEnabled(is_save_data_enabled());
+ }
+
+ bool is_subresource_redirect_enabled() { return std::get<0>(GetParam()); }
+
+ bool is_lazyload_image_enabled() { return std::get<1>(GetParam()); }
+
+ bool is_save_data_enabled() { return std::get<2>(GetParam()); }
+
+ void LoadMainResource(const String& html_body) {
+ SimRequest main_resource("https://example.com/", "text/html");
+ LoadURL("https://example.com/");
+
+ main_resource.Complete(html_body);
+ GetDocument().UpdateStyleAndLayoutTree();
+ }
+
+ ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test_;
+ ScopedAutomaticLazyImageLoadingForTest
+ scoped_automatic_lazy_image_loading_for_test_;
+ base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+// 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>
+ #deferred_image {
+ height:200px;
+ background-image: url('img.png');
+ }
+ </style>
+ <div style='height:10000px;'></div>
+ <div id="deferred_image"></div>
+ )HTML"));
+
+ if (!is_lazyload_image_enabled())
+ image_resource.Complete(ReadTestImage());
+
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+
+ if (is_lazyload_image_enabled()) {
+ // Scroll down until the background image is visible.
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 10000), mojom::blink::ScrollType::kProgrammatic);
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+ image_resource.Complete(ReadTestImage());
+ }
+
+ WebURLRequest::PreviewsState previews_state =
+ GetDocument()
+ .Fetcher()
+ ->CachedResource(KURL("https://example.com/img.png"))
+ ->GetResourceRequest()
+ .GetPreviewsState();
+ // Subresource redirect previews bit should be set only if SaveData and
+ // SubresourceRedirect feature are enabled.
+ EXPECT_EQ(is_save_data_enabled() && is_subresource_redirect_enabled(),
+ (previews_state & WebURLRequest::kSubresourceRedirectOn) != 0);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ All,
+ SubresourceRedirectSimTest,
+ ::testing::Combine(::testing::Bool(), /* is_subresource_redirect_enabled */
+ ::testing::Bool(), /* is_lazyload_image_enabled */
+ ::testing::Bool()) /* is_save_data_enabled_*/);
+
+} // namespace
+
+} // namespace blink
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 380c3b2229a..c267eef9f57 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
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/html/track/track_base.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -41,7 +42,12 @@ class CORE_EXPORT AudioTrack final : public ScriptWrappable, public TrackBase {
bool enabled_;
};
-DEFINE_TRACK_TYPE_CASTS(AudioTrack, WebMediaPlayer::kAudioTrack);
+template <>
+struct DowncastTraits<AudioTrack> {
+ static bool AllowFrom(const TrackBase& track) {
+ return track.GetType() == WebMediaPlayer::kAudioTrack;
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/track/automatic_track_selection.cc b/chromium/third_party/blink/renderer/core/html/track/automatic_track_selection.cc
index 792173ddea8..6cd8cc49d03 100644
--- a/chromium/third_party/blink/renderer/core/html/track/automatic_track_selection.cc
+++ b/chromium/third_party/blink/renderer/core/html/track/automatic_track_selection.cc
@@ -23,8 +23,8 @@ class TrackGroup {
has_src_lang(false) {}
HeapVector<Member<TextTrack>> tracks;
- Member<TextTrack> visible_track;
- Member<TextTrack> default_track;
+ TextTrack* visible_track;
+ TextTrack* default_track;
GroupKind kind;
bool has_src_lang;
};
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 effc3865885..590529d72a9 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
@@ -324,9 +324,8 @@ void CueTimeline::UpdateActiveCues(double movie_time) {
// ... if the text track has a corresponding track element, to then fire a
// simple event named cuechange at the track element as well.
- if (track->TrackType() == TextTrack::kTrackElement) {
- HTMLTrackElement* track_element =
- ToLoadableTextTrack(track.Get())->TrackElement();
+ if (auto* loadable_text_track = DynamicTo<LoadableTextTrack>(track.Get())) {
+ HTMLTrackElement* track_element = loadable_text_track->TrackElement();
DCHECK(track_element);
media_element.ScheduleEvent(
CreateEventWithTarget(event_type_names::kCuechange, track_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 ec9d9550c20..cbfc68db7e8 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
@@ -69,8 +69,8 @@ class TrackDisplayUpdateScope {
STACK_ALLOCATED();
public:
- TrackDisplayUpdateScope(CueTimeline& cue_timeline) {
- cue_timeline_ = &cue_timeline;
+ TrackDisplayUpdateScope(CueTimeline& cue_timeline)
+ : cue_timeline_(&cue_timeline) {
cue_timeline_->BeginIgnoringUpdateRequests();
}
~TrackDisplayUpdateScope() {
@@ -79,7 +79,7 @@ class TrackDisplayUpdateScope {
}
private:
- Member<CueTimeline> cue_timeline_;
+ CueTimeline* cue_timeline_;
};
} // namespace blink
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 f43af152576..67d538e5186 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
@@ -73,8 +73,9 @@ Node::InsertionNotificationRequest HTMLTrackElement::InsertedInto(
}
void HTMLTrackElement::RemovedFrom(ContainerNode& insertion_point) {
- if (!parentNode() && IsHTMLMediaElement(insertion_point))
- ToHTMLMediaElement(insertion_point).DidRemoveTrackElement(this);
+ auto* html_media_element = DynamicTo<HTMLMediaElement>(insertion_point);
+ if (html_media_element && !parentNode())
+ html_media_element->DidRemoveTrackElement(this);
HTMLElement::RemovedFrom(insertion_point);
}
@@ -334,10 +335,7 @@ const AtomicString& HTMLTrackElement::MediaElementCrossOriginAttribute() const {
}
HTMLMediaElement* HTMLTrackElement::MediaElement() const {
- Element* parent = parentElement();
- if (IsHTMLMediaElement(parent))
- return ToHTMLMediaElement(parent);
- return nullptr;
+ return DynamicTo<HTMLMediaElement>(parentElement());
}
void HTMLTrackElement::Trace(Visitor* visitor) {
diff --git a/chromium/third_party/blink/renderer/core/html/track/inband_text_track.h b/chromium/third_party/blink/renderer/core/html/track/inband_text_track.h
index 06bd261e4df..2c509677382 100644
--- a/chromium/third_party/blink/renderer/core/html/track/inband_text_track.h
+++ b/chromium/third_party/blink/renderer/core/html/track/inband_text_track.h
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/core/html/track/text_track.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
class WebInbandTextTrack;
@@ -58,7 +59,10 @@ class InbandTextTrack final : public TextTrack,
// All concrete implementations of WebInbandTextTrackClient are
// InbandTextTracks.
-DEFINE_TYPE_CASTS(InbandTextTrack, WebInbandTextTrackClient, track, true, true);
+template <>
+struct DowncastTraits<InbandTextTrack> {
+ static bool AllowFrom(const WebInbandTextTrackClient& track) { return true; }
+};
} // namespace blink
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 e9b096d1deb..87b69cdf8b0 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
@@ -55,11 +55,12 @@ class LoadableTextTrack final : public TextTrack {
Member<HTMLTrackElement> track_element_;
};
-DEFINE_TYPE_CASTS(LoadableTextTrack,
- TextTrack,
- track,
- track->TrackType() == TextTrack::kTrackElement,
- track.TrackType() == TextTrack::kTrackElement);
+template <>
+struct DowncastTraits<LoadableTextTrack> {
+ static bool AllowFrom(const TextTrack& track) {
+ return track.TrackType() == TextTrack::kTrackElement;
+ }
+};
} // namespace blink
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 d8e3bc50371..e4459809417 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
@@ -32,6 +32,7 @@
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/html/track/track_base.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -50,20 +51,13 @@ class CORE_EXPORT TextTrack : public EventTargetWithInlineData,
USING_GARBAGE_COLLECTED_MIXIN(TextTrack);
public:
- static TextTrack* Create(const AtomicString& kind,
- const AtomicString& label,
- const AtomicString& language) {
- return MakeGarbageCollected<TextTrack>(kind, label, language, g_empty_atom,
- kAddTrack);
- }
-
enum TextTrackType { kTrackElement, kAddTrack, kInBand };
TextTrack(const AtomicString& kind,
const AtomicString& label,
const AtomicString& language,
- const AtomicString& id,
- TextTrackType);
+ const AtomicString& id = g_empty_atom,
+ TextTrackType = kAddTrack);
~TextTrack() override;
virtual void SetTrackList(TextTrackList*);
@@ -161,7 +155,12 @@ class CORE_EXPORT TextTrack : public EventTargetWithInlineData,
bool has_been_configured_;
};
-DEFINE_TRACK_TYPE_CASTS(TextTrack, WebMediaPlayer::kTextTrack);
+template <>
+struct DowncastTraits<TextTrack> {
+ static bool AllowFrom(const TrackBase& track) {
+ return track.GetType() == WebMediaPlayer::kTextTrack;
+ }
+};
} // namespace blink
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 f334d4d0c49..50a19852bdf 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
@@ -120,7 +120,7 @@ void TextTrackContainer::ObserveSizeChanges(Element& element) {
void TextTrackContainer::UpdateDefaultFontSize(
LayoutObject* media_layout_object) {
- if (!media_layout_object || !media_layout_object->IsVideo())
+ if (!media_layout_object || !IsA<LayoutVideo>(media_layout_object))
return;
// FIXME: The video size is used to calculate the font size (a workaround
// for lack of per-spec vh/vw support) but the whole media element is used
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 0f2118fd755..c5cfc997620 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
@@ -44,8 +44,8 @@ unsigned TextTrackList::length() const {
}
int TextTrackList::GetTrackIndex(TextTrack* text_track) {
- if (text_track->TrackType() == TextTrack::kTrackElement)
- return ToLoadableTextTrack(text_track)->TrackElementIndex();
+ if (auto* loadable_text_track = DynamicTo<LoadableTextTrack>(text_track))
+ return loadable_text_track->TrackElementIndex();
if (text_track->TrackType() == TextTrack::kAddTrack)
return element_tracks_.size() + add_track_tracks_.Find(text_track);
@@ -141,7 +141,7 @@ TextTrack* TextTrackList::getTrackById(const AtomicString& id) {
void TextTrackList::InvalidateTrackIndexesAfterTrack(TextTrack* track) {
HeapVector<Member<TextTrack>>* tracks = nullptr;
- if (track->TrackType() == TextTrack::kTrackElement) {
+ if (IsA<LoadableTextTrack>(track)) {
tracks = &element_tracks_;
for (const auto& add_track : add_track_tracks_)
add_track->InvalidateTrackIndex();
@@ -168,9 +168,9 @@ void TextTrackList::InvalidateTrackIndexesAfterTrack(TextTrack* track) {
void TextTrackList::Append(TextTrack* track) {
if (track->TrackType() == TextTrack::kAddTrack) {
add_track_tracks_.push_back(track);
- } else if (track->TrackType() == TextTrack::kTrackElement) {
+ } else if (auto* loadable_text_track = DynamicTo<LoadableTextTrack>(track)) {
// Insert tracks added for <track> element in tree order.
- wtf_size_t index = ToLoadableTextTrack(track)->TrackElementIndex();
+ wtf_size_t index = loadable_text_track->TrackElementIndex();
element_tracks_.insert(index, track);
} else if (track->TrackType() == TextTrack::kInBand) {
inband_tracks_.push_back(track);
@@ -189,7 +189,7 @@ void TextTrackList::Append(TextTrack* track) {
void TextTrackList::Remove(TextTrack* track) {
HeapVector<Member<TextTrack>>* tracks = nullptr;
- if (track->TrackType() == TextTrack::kTrackElement) {
+ if (IsA<LoadableTextTrack>(track)) {
tracks = &element_tracks_;
} else if (track->TrackType() == TextTrack::kAddTrack) {
tracks = &add_track_tracks_;
@@ -223,7 +223,7 @@ void TextTrackList::RemoveAllInbandTracks() {
bool TextTrackList::Contains(TextTrack* track) const {
const HeapVector<Member<TextTrack>>* tracks = nullptr;
- if (track->TrackType() == TextTrack::kTrackElement)
+ if (IsA<LoadableTextTrack>(track))
tracks = &element_tracks_;
else if (track->TrackType() == TextTrack::kAddTrack)
tracks = &add_track_tracks_;
diff --git a/chromium/third_party/blink/renderer/core/html/track/text_track_list_test.cc b/chromium/third_party/blink/renderer/core/html/track/text_track_list_test.cc
index cd4b2603159..2a5fab9ba74 100644
--- a/chromium/third_party/blink/renderer/core/html/track/text_track_list_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/track/text_track_list_test.cc
@@ -20,7 +20,7 @@ TEST(TextTrackListTest, InvalidateTrackIndexes) {
const size_t kNumTextTracks = 4;
TextTrack* text_tracks[kNumTextTracks];
for (size_t i = 0; i < kNumTextTracks; ++i) {
- text_tracks[i] = TextTrack::Create("subtitles", "", "");
+ text_tracks[i] = MakeGarbageCollected<TextTrack>("subtitles", "", "");
list->Append(text_tracks[i]);
}
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 535422abe2d..24d0448c33c 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
@@ -26,6 +26,7 @@
#include "third_party/blink/renderer/core/html/track/track_event.h"
#include "third_party/blink/public/platform/web_media_player.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_track_event_init.h"
#include "third_party/blink/renderer/bindings/core/v8/video_track_or_audio_track_or_text_track.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
#include "third_party/blink/renderer/core/html/track/audio_track.h"
@@ -65,13 +66,13 @@ void TrackEvent::track(VideoTrackOrAudioTrackOrTextTrack& return_value) {
switch (track_->GetType()) {
case WebMediaPlayer::kTextTrack:
- return_value.SetTextTrack(ToTextTrack(track_.Get()));
+ return_value.SetTextTrack(To<TextTrack>(track_.Get()));
break;
case WebMediaPlayer::kAudioTrack:
- return_value.SetAudioTrack(ToAudioTrack(track_.Get()));
+ return_value.SetAudioTrack(To<AudioTrack>(track_.Get()));
break;
case WebMediaPlayer::kVideoTrack:
- return_value.SetVideoTrack(ToVideoTrack(track_.Get()));
+ return_value.SetVideoTrack(To<VideoTrack>(track_.Get()));
break;
default:
NOTREACHED();
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 9c59e327d0d..6810fe194e2 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
@@ -28,10 +28,10 @@
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/html/track/track_base.h"
-#include "third_party/blink/renderer/core/html/track/track_event_init.h"
namespace blink {
+class TrackEventInit;
class VideoTrackOrAudioTrackOrTextTrack;
class CORE_EXPORT TrackEvent final : public Event {
diff --git a/chromium/third_party/blink/renderer/core/html/track/track_event.idl b/chromium/third_party/blink/renderer/core/html/track/track_event.idl
index 78dd8b7b2d8..c66e7ed05d0 100644
--- a/chromium/third_party/blink/renderer/core/html/track/track_event.idl
+++ b/chromium/third_party/blink/renderer/core/html/track/track_event.idl
@@ -26,8 +26,8 @@
// https://html.spec.whatwg.org/C/#the-trackevent-interface
[
- Exposed=Window,
- Constructor(DOMString type, optional TrackEventInit eventInitDict)
+ Exposed=Window
] interface TrackEvent : Event {
+ constructor(DOMString type, optional TrackEventInit eventInitDict = {});
readonly attribute (VideoTrack or AudioTrack or TextTrack)? 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 fcbd9a5367c..27b4c3b8e0a 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
@@ -8,7 +8,6 @@
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/core/html/track/track_event.h"
-#include "third_party/blink/renderer/core/html/track/track_event_init.h"
namespace blink {
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 8869e971ef8..a59fd126a47 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
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/html/track/track_base.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -45,7 +46,12 @@ class CORE_EXPORT VideoTrack final : public ScriptWrappable, public TrackBase {
bool selected_;
};
-DEFINE_TRACK_TYPE_CASTS(VideoTrack, WebMediaPlayer::kVideoTrack);
+template <>
+struct DowncastTraits<VideoTrack> {
+ static bool AllowFrom(const TrackBase& track) {
+ return track.GetType() == WebMediaPlayer::kVideoTrack;
+ }
+};
} // namespace blink
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 2a786fe32b3..80b58be649c 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(blink::Visitor* visitor) {
+void VTTCueBackgroundBox::Trace(Visitor* visitor) {
visitor->Trace(track_);
HTMLDivElement::Trace(visitor);
}
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 fe16a16a72b..0152de94d5d 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
@@ -219,9 +219,6 @@ class VTTCue final : public TextTrackCue {
bool display_tree_should_change_ : 1;
};
-// VTTCue is currently the only TextTrackCue subclass.
-DEFINE_TYPE_CASTS(VTTCue, TextTrackCue, cue, true, true);
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_TRACK_VTT_VTT_CUE_H_
diff --git a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.idl b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.idl
index 10fe378eba0..1d424d2c96e 100644
--- a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.idl
+++ b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.idl
@@ -36,10 +36,9 @@ enum DirectionSetting { "" /* horizontal */, "rl", "lr" };
enum AlignSetting { "start", "center", "end", "left", "right" };
[
- Exposed=Window,
- Constructor(double startTime, double endTime, DOMString text),
- ConstructorCallWith=Document
+ Exposed=Window
] interface VTTCue : TextTrackCue {
+ [CallWith=Document] constructor(double startTime, double endTime, DOMString text);
[RuntimeEnabled=WebVTTRegions] attribute VTTRegion? region;
attribute DirectionSetting vertical;
attribute boolean snapToLines;
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 90d64e2a8f1..ba0aef82404 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
@@ -137,7 +137,7 @@ void VTTElement::SetTrack(TextTrack* track) {
track_ = track;
}
-void VTTElement::Trace(blink::Visitor* visitor) {
+void VTTElement::Trace(Visitor* visitor) {
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 25a52b56d0b..9d26b2e9165 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 52d6335e61e..3d878c164b5 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
@@ -285,10 +285,8 @@ VTTParser::ParseState VTTParser::CollectWebVTTBlock(const String& line) {
if (line.StartsWith("STYLE") && StringView(line, kStyleIdentifierLength)
.IsAllSpecialCharacters<IsASpace>()) {
contains_style_block_ = true;
- if (RuntimeEnabledFeatures::EmbeddedVTTStylesheetsEnabled()) {
- current_content_.Clear();
- return kStyle;
- }
+ current_content_.Clear();
+ return kStyle;
}
}
@@ -437,10 +435,10 @@ class VTTTreeBuilder {
Document& GetDocument() const { return *document_; }
VTTToken token_;
- Member<ContainerNode> current_node_;
+ ContainerNode* current_node_ = nullptr;
Vector<AtomicString> language_stack_;
- Member<Document> document_;
- Member<TextTrack> track_;
+ Document* document_;
+ TextTrack* track_;
};
DocumentFragment* VTTTreeBuilder::BuildFromString(const String& cue_text) {
@@ -600,7 +598,7 @@ void VTTTreeBuilder::ConstructTreeFromToken(Document& document) {
if (node_type == kVTTNodeTypeNone)
break;
- auto* curr_vtt_element = DynamicTo<VTTElement>(current_node_.Get());
+ auto* curr_vtt_element = DynamicTo<VTTElement>(current_node_);
VTTNodeType current_type = curr_vtt_element
? curr_vtt_element->WebVTTNodeType()
: kVTTNodeTypeNone;
@@ -635,7 +633,7 @@ void VTTTreeBuilder::ConstructTreeFromToken(Document& document) {
// The only non-VTTElement would be the DocumentFragment root. (Text
// nodes and PIs will never appear as current_node_.)
- auto* curr_vtt_element = DynamicTo<VTTElement>(current_node_.Get());
+ auto* curr_vtt_element = DynamicTo<VTTElement>(current_node_);
if (!curr_vtt_element)
break;
diff --git a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.idl b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.idl
index e2cf419cc0f..876b0fcafc4 100644
--- a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.idl
+++ b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.idl
@@ -29,9 +29,9 @@ enum ScrollSetting { "" /* none */, "up" };
[
Exposed=Window,
- Constructor,
RuntimeEnabled=WebVTTRegions
] interface VTTRegion {
+ constructor();
attribute DOMString id;
[RaisesException=Setter] attribute double width;
attribute unsigned long lines;
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
new file mode 100644
index 00000000000..1143b619bda
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing.cc
@@ -0,0 +1,140 @@
+// 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/trust_token_attribute_parsing.h"
+#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/core/fetch/trust_token.h"
+#include "third_party/blink/renderer/platform/json/json_values.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+namespace internal {
+
+namespace {
+bool ParseType(const String& in, network::mojom::TrustTokenOperationType* out) {
+ if (in == "token-request") {
+ *out = network::mojom::TrustTokenOperationType::kIssuance;
+ return true;
+ } else if (in == "srr-token-redemption") {
+ *out = network::mojom::TrustTokenOperationType::kRedemption;
+ return true;
+ } else if (in == "send-srr") {
+ *out = network::mojom::TrustTokenOperationType::kSigning;
+ return true;
+ } else {
+ return false;
+ }
+}
+bool ParseRefreshPolicy(const String& in,
+ network::mojom::TrustTokenRefreshPolicy* out) {
+ if (in == "none") {
+ *out = network::mojom::TrustTokenRefreshPolicy::kUseCached;
+ return true;
+ } else if (in == "refresh") {
+ *out = network::mojom::TrustTokenRefreshPolicy::kRefresh;
+ return true;
+ }
+ return false;
+}
+bool ParseSignRequestData(const String& in,
+ network::mojom::TrustTokenSignRequestData* out) {
+ if (in == "omit") {
+ *out = network::mojom::TrustTokenSignRequestData::kOmit;
+ return true;
+ } else if (in == "headers-only") {
+ *out = network::mojom::TrustTokenSignRequestData::kHeadersOnly;
+ return true;
+ } else if (in == "include") {
+ *out = network::mojom::TrustTokenSignRequestData::kInclude;
+ return true;
+ }
+ return false;
+}
+} // namespace
+
+// Given a JSON representation of a Trust Token parameters struct, constructs
+// and returns the represented struct if the JSON representation is valid;
+// returns nullopt otherwise.
+network::mojom::blink::TrustTokenParamsPtr TrustTokenParamsFromJson(
+ std::unique_ptr<JSONValue> in) {
+ JSONObject* object = JSONObject::Cast(in.get());
+
+ if (!object)
+ return nullptr;
+
+ auto ret = network::mojom::blink::TrustTokenParams::New();
+
+ // |type| is required.
+ String type;
+ if (!object->GetString("type", &type))
+ return nullptr;
+ if (!ParseType(type, &ret->type))
+ return nullptr;
+
+ // |refreshPolicy| is optional.
+ if (JSONValue* refresh_policy = object->Get("refreshPolicy")) {
+ String str_policy;
+ if (!refresh_policy->AsString(&str_policy))
+ return nullptr;
+ if (!ParseRefreshPolicy(str_policy, &ret->refresh_policy))
+ return nullptr;
+ }
+
+ // |signRequestData| is optional.
+ if (JSONValue* sign_request_data = object->Get("signRequestData")) {
+ String str_sign_request_data;
+ if (!sign_request_data->AsString(&str_sign_request_data))
+ return nullptr;
+ if (!ParseSignRequestData(str_sign_request_data, &ret->sign_request_data)) {
+ return nullptr;
+ }
+ }
+
+ // |includeTimestampHeader| is optional.
+ if (JSONValue* include_timestamp_header =
+ object->Get("includeTimestampHeader")) {
+ if (!include_timestamp_header->AsBoolean(&ret->include_timestamp_header))
+ return nullptr;
+ }
+
+ // |issuer| is optional, but, if it's present, it must be a valid origin,
+ // potentially trustworthy, and HTTP or HTTPS.
+ if (JSONValue* issuer = object->Get("issuer")) {
+ String str_issuer;
+ if (!issuer->AsString(&str_issuer))
+ return nullptr;
+ ret->issuer = SecurityOrigin::CreateFromString(str_issuer);
+ if (!ret->issuer)
+ return nullptr;
+ if (!ret->issuer->IsPotentiallyTrustworthy())
+ return nullptr;
+ if (ret->issuer->Protocol() != "http" && ret->issuer->Protocol() != "https")
+ return nullptr;
+ }
+
+ // |additionalSignedHeaders| is optional.
+ if (JSONValue* additional_signed_headers =
+ object->Get("additionalSignedHeaders")) {
+ JSONArray* signed_headers_array =
+ JSONArray::Cast(additional_signed_headers);
+ if (!signed_headers_array)
+ return nullptr;
+
+ // Because of the characteristics of the Trust Tokens protocol, we expect
+ // roughly 2-5 elements in this array.
+ for (size_t i = 0; i < signed_headers_array->size(); ++i) {
+ String next;
+ if (!signed_headers_array->at(i)->AsString(&next))
+ return nullptr;
+ ret->additional_signed_headers.push_back(std::move(next));
+ }
+ }
+
+ return ret;
+}
+
+} // namespace internal
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing.h b/chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing.h
new file mode 100644
index 00000000000..f5a7ab03892
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing.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_HTML_TRUST_TOKEN_ATTRIBUTE_PARSING_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_TRUST_TOKEN_ATTRIBUTE_PARSING_H_
+
+#include "base/optional.h"
+#include "services/network/public/mojom/trust_tokens.mojom-blink-forward.h"
+#include "third_party/blink/renderer/core/core_export.h"
+
+namespace blink {
+
+class JSONValue;
+
+namespace internal {
+
+// Given a JSON representation of a Trust Token parameters struct, constructs
+// and returns the represented struct if the JSON representation is valid;
+// returns nullopt otherwise.
+CORE_EXPORT network::mojom::blink::TrustTokenParamsPtr TrustTokenParamsFromJson(
+ std::unique_ptr<JSONValue> in);
+
+} // namespace internal
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_TRUST_TOKEN_ATTRIBUTE_PARSING_H_
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
new file mode 100644
index 00000000000..75934f207ff
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing_test.cc
@@ -0,0 +1,233 @@
+// 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/trust_token_attribute_parsing.h"
+
+#include "services/network/public/mojom/trust_tokens.mojom-blink.h"
+#include "services/network/trust_tokens/test/trust_token_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/json/json_parser.h"
+#include "third_party/blink/renderer/platform/json/json_values.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+namespace internal {
+namespace {
+
+network::mojom::blink::TrustTokenParamsPtr NetworkParamsToBlinkParams(
+ network::mojom::TrustTokenParamsPtr params) {
+ auto ret = network::mojom::blink::TrustTokenParams::New();
+ ret->type = params->type;
+ ret->refresh_policy = params->refresh_policy;
+ ret->sign_request_data = params->sign_request_data;
+ ret->include_timestamp_header = params->include_timestamp_header;
+ if (params->issuer)
+ ret->issuer = SecurityOrigin::CreateFromUrlOrigin(*params->issuer);
+ for (const std::string& header : params->additional_signed_headers) {
+ ret->additional_signed_headers.push_back(String::FromUTF8(header));
+ }
+ return ret;
+}
+
+} // namespace
+
+using TrustTokenAttributeParsingSuccess =
+ ::testing::TestWithParam<network::TrustTokenTestParameters>;
+
+INSTANTIATE_TEST_SUITE_P(
+ WithIssuanceParams,
+ TrustTokenAttributeParsingSuccess,
+ ::testing::ValuesIn(network::kIssuanceTrustTokenTestParameters));
+INSTANTIATE_TEST_SUITE_P(
+ WithRedemptionParams,
+ TrustTokenAttributeParsingSuccess,
+ ::testing::ValuesIn(network::kRedemptionTrustTokenTestParameters));
+INSTANTIATE_TEST_SUITE_P(
+ WithSigningParams,
+ TrustTokenAttributeParsingSuccess,
+ ::testing::ValuesIn(network::kSigningTrustTokenTestParameters));
+
+// Test roundtrip serializations-then-deserializations for a collection of test
+// cases covering all possible values of all enum attributes, and all
+// possibilities (e.g. optional members present vs. not present) for all other
+// attributes.
+TEST_P(TrustTokenAttributeParsingSuccess, Roundtrip) {
+ network::mojom::TrustTokenParams network_expectation;
+ std::string input;
+
+ network::TrustTokenParametersAndSerialization
+ expected_params_and_serialization =
+ network::SerializeTrustTokenParametersAndConstructExpectation(
+ GetParam());
+
+ network::mojom::blink::TrustTokenParamsPtr expectation =
+ NetworkParamsToBlinkParams(
+ std::move(expected_params_and_serialization.params));
+
+ std::unique_ptr<JSONValue> json_value = ParseJSON(
+ String::FromUTF8(expected_params_and_serialization.serialized_params));
+ ASSERT_TRUE(json_value);
+ auto result = TrustTokenParamsFromJson(std::move(json_value));
+ ASSERT_TRUE(result);
+
+ // We can't use mojo's generated Equals method here because it doesn't play
+ // well with the "issuer" field's type of
+ // scoped_refptr<blink::SecurityOrigin>: in particular, the method does an
+ // address-to-address comparison of the pointers.
+ EXPECT_EQ(result->type, expectation->type);
+ EXPECT_EQ(result->refresh_policy, expectation->refresh_policy);
+ EXPECT_EQ(result->sign_request_data, expectation->sign_request_data);
+ EXPECT_EQ(result->include_timestamp_header,
+ expectation->include_timestamp_header);
+
+ EXPECT_EQ(!!result->issuer, !!expectation->issuer);
+ if (result->issuer)
+ EXPECT_EQ(result->issuer->ToString(), expectation->issuer->ToString());
+
+ EXPECT_EQ(result->additional_signed_headers,
+ expectation->additional_signed_headers);
+}
+
+TEST(TrustTokenAttributeParsing, NotADictionary) {
+ auto json = ParseJSON(R"(
+ 3
+ )");
+ ASSERT_TRUE(json);
+ ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
+}
+
+TEST(TrustTokenAttributeParsing, MissingType) {
+ auto json = ParseJSON(R"(
+ { }
+ )");
+ ASSERT_TRUE(json);
+ ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
+}
+
+TEST(TrustTokenAttributeParsing, TypeUnsafeType) {
+ auto json = ParseJSON(R"(
+ { "type": 3 }
+ )");
+ ASSERT_TRUE(json);
+ ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
+}
+
+TEST(TrustTokenAttributeParsing, InvalidType) {
+ auto json = ParseJSON(R"(
+ { "type": "not a valid type" }
+ )");
+ ASSERT_TRUE(json);
+ ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
+}
+
+TEST(TrustTokenAttributeParsing, TypeUnsafeRefreshPolicy) {
+ auto json = ParseJSON(R"(
+ { "type": "token-request",
+ "refreshPolicy": 3 }
+ )");
+ ASSERT_TRUE(json);
+ ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
+}
+
+TEST(TrustTokenAttributeParsing, InvalidRefreshPolicy) {
+ auto json = ParseJSON(R"(
+ { "type": "token-request",
+ "refreshPolicy": "not a valid refresh policy" }
+ )");
+ ASSERT_TRUE(json);
+ ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
+}
+
+TEST(TrustTokenAttributeParsing, TypeUnsafeSignRequestData) {
+ auto json = ParseJSON(R"(
+ { "type": "token-request",
+ "signRequestData": 3 }
+ )");
+ ASSERT_TRUE(json);
+ ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
+}
+
+TEST(TrustTokenAttributeParsing, InvalidSignRequestData) {
+ auto json = ParseJSON(R"(
+ { "type": "token-request",
+ "signRequestData": "not a member of the signRequestData enum" }
+ )");
+ ASSERT_TRUE(json);
+ ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
+}
+
+TEST(TrustTokenAttributeParsing, TypeUnsafeIncludeTimestampHeader) {
+ auto json = ParseJSON(R"(
+ { "type": "token-request",
+ "includeTimestampHeader": 3 }
+ )");
+ ASSERT_TRUE(json);
+ ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
+}
+
+TEST(TrustTokenAttributeParsing, TypeUnsafeIssuer) {
+ auto json = ParseJSON(R"(
+ { "type": "token-request",
+ "issuer": 3 }
+ )");
+ ASSERT_TRUE(json);
+ ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
+}
+
+// Test that the parser requires that |issuer| be a valid origin.
+TEST(TrustTokenAttributeParsing, NonUrlIssuer) {
+ JSONParseError err;
+ auto json = ParseJSON(R"(
+ { "type": "token-request",
+ "issuer": "not a URL" }
+ )",
+ &err);
+ ASSERT_TRUE(json);
+ ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
+}
+
+// Test that the parser requires that |issuer| be a potentially trustworthy
+// origin.
+TEST(TrustTokenAttributeParsing, InsecureIssuer) {
+ auto json = ParseJSON(R"(
+ { "type": "token-request",
+ "issuer": "http://not-potentially-trustworthy.example" }
+ )");
+ ASSERT_TRUE(json);
+ ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
+}
+
+// Test that the parser requires that |issuer| be a HTTP or HTTPS origin.
+TEST(TrustTokenAttributeParsing, NonHttpNonHttpsIssuer) {
+ auto json = ParseJSON(R"(
+ { "type": "token-request",
+ "issuer": "file:///" }
+ )");
+ ASSERT_TRUE(json);
+ ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
+}
+
+TEST(TrustTokenAttributeParsing, TypeUnsafeAdditionalSignedHeaders) {
+ auto json = ParseJSON(R"(
+ { "type": "token-request",
+ "additionalSignedHeaders": 3}
+ )");
+ ASSERT_TRUE(json);
+ ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
+}
+
+// Test that the parser requires that all members of the additionalSignedHeaders
+// be strings.
+TEST(TrustTokenAttributeParsing, TypeUnsafeAdditionalSignedHeader) {
+ auto json = ParseJSON(R"(
+ { "type": "token-request",
+ "additionalSignedHeaders": ["plausible header", 17] }
+ )");
+ ASSERT_TRUE(json);
+ ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json)));
+}
+
+} // namespace internal
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/html/window_name_collection.h b/chromium/third_party/blink/renderer/core/html/window_name_collection.h
index 36139c920c5..5b5ee581f05 100644
--- a/chromium/third_party/blink/renderer/core/html/window_name_collection.h
+++ b/chromium/third_party/blink/renderer/core/html/window_name_collection.h
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_WINDOW_NAME_COLLECTION_H_
#include "third_party/blink/renderer/core/html/html_name_collection.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -19,11 +20,12 @@ class WindowNameCollection final : public HTMLNameCollection {
bool ElementMatches(const Element&) const;
};
-DEFINE_TYPE_CASTS(WindowNameCollection,
- LiveNodeListBase,
- collection,
- collection->GetType() == kWindowNamedItems,
- collection.GetType() == kWindowNamedItems);
+template <>
+struct DowncastTraits<WindowNameCollection> {
+ static bool AllowFrom(const LiveNodeListBase& collection) {
+ return collection.GetType() == kWindowNamedItems;
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/imagebitmap/DEPS b/chromium/third_party/blink/renderer/core/imagebitmap/DEPS
new file mode 100644
index 00000000000..fd3e874642f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/imagebitmap/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+gpu/command_buffer/client",
+] \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/core/imagebitmap/OWNERS b/chromium/third_party/blink/renderer/core/imagebitmap/OWNERS
index c10da38a164..5ef87b1aa3f 100644
--- a/chromium/third_party/blink/renderer/core/imagebitmap/OWNERS
+++ b/chromium/third_party/blink/renderer/core/imagebitmap/OWNERS
@@ -1,5 +1,4 @@
fserb@chromium.org
-zakerinasab@chromium.org
# TEAM: paint-dev@chromium.org
# COMPONENT: Blink>Canvas
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 badef2c51ad..234ae964ad1 100644
--- a/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
+++ b/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
@@ -11,6 +11,7 @@
#include "base/numerics/checked_math.h"
#include "base/numerics/clamped_math.h"
#include "base/single_thread_task_runner.h"
+#include "gpu/command_buffer/client/shared_image_interface.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
#include "third_party/blink/renderer/core/html/canvas/image_data.h"
@@ -21,6 +22,7 @@
#include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.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/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/scheduler/public/worker_pool.h"
@@ -49,15 +51,6 @@ constexpr const char* kRec2020ImageBitmapColorSpaceConversion = "rec2020";
namespace {
-scoped_refptr<StaticBitmapImage> CreateImage(
- sk_sp<SkImage> skia_image,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper> context) {
- if (skia_image->isTextureBacked()) {
- return AcceleratedStaticBitmapImage::CreateFromSkImage(skia_image, context);
- }
- return UnacceleratedStaticBitmapImage::Create(skia_image);
-}
-
// The following two functions are helpers used in cropImage
static inline IntRect NormalizeRect(const IntRect& rect) {
int x = rect.X();
@@ -194,7 +187,7 @@ bool DstBufferSizeHasOverflow(const ImageBitmap::ParsedOptions& options) {
return false;
}
-SkImageInfo GetSkImageInfo(const scoped_refptr<StaticBitmapImage>& input) {
+SkImageInfo GetSkImageInfo(const scoped_refptr<Image>& input) {
auto image = input->PaintImageForCurrentFrame().GetSkImage();
return SkImageInfo::Make(image->width(), image->height(), image->colorType(),
image->alphaType(), image->refColorSpace());
@@ -235,10 +228,40 @@ static inline bool ShouldAvoidPremul(
return options.source_is_unpremul && !options.premultiply_alpha;
}
+std::unique_ptr<CanvasResourceProvider> CreateProvider(
+ base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider,
+ const SkImageInfo& info,
+ const scoped_refptr<StaticBitmapImage>& source_image,
+ bool fallback_to_software) {
+ IntSize size(info.width(), info.height());
+ CanvasColorParams color_params(info);
+
+ if (context_provider) {
+ uint32_t usage_flags =
+ context_provider->ContextProvider()
+ ->SharedImageInterface()
+ ->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);
+ if (resource_provider)
+ return resource_provider;
+
+ if (!fallback_to_software)
+ return nullptr;
+ }
+
+ return CanvasResourceProvider::CreateBitmapProvider(
+ size, kLow_SkFilterQuality, color_params);
+}
+
scoped_refptr<StaticBitmapImage> FlipImageVertically(
scoped_refptr<StaticBitmapImage> input,
const ImageBitmap::ParsedOptions& parsed_options) {
sk_sp<SkImage> image = input->PaintImageForCurrentFrame().GetSkImage();
+ if (!image)
+ return nullptr;
if (ShouldAvoidPremul(parsed_options)) {
// Unpremul code path results in a GPU readback if |input| is texture
@@ -271,34 +294,29 @@ scoped_refptr<StaticBitmapImage> FlipImageVertically(
&writable_pixels[top_last_element],
&writable_pixels[bottom_first_element]);
}
- return StaticBitmapImage::Create(std::move(image_pixels), info);
+ return StaticBitmapImage::Create(std::move(image_pixels), info,
+ input->CurrentFrameOrientation());
}
// Since we are allowed to premul the input image if needed, we can use Skia
// to flip the image by drawing it on a surface. If the image is premul, we
// can use both accelerated and software surfaces. If the image is unpremul,
// we have to use software surfaces.
- sk_sp<SkSurface> surface = nullptr;
- if (image->isTextureBacked() && image->alphaType() == kPremul_SkAlphaType) {
- GrContext* context =
- input->ContextProviderWrapper()->ContextProvider()->GetGrContext();
- if (context) {
- surface = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo,
- GetSkImageInfo(input));
- }
- }
- if (!surface)
- surface = SkSurface::MakeRaster(GetSkImageInfo(input));
- if (!surface)
+ bool use_accelerated =
+ image->isTextureBacked() && image->alphaType() == kPremul_SkAlphaType;
+ auto resource_provider = CreateProvider(
+ use_accelerated ? input->ContextProviderWrapper() : nullptr,
+ GetSkImageInfo(input), input, true /* fallback_to_software */);
+ if (!resource_provider)
return nullptr;
- SkCanvas* canvas = surface->getCanvas();
+
+ auto* canvas = resource_provider->Canvas();
canvas->scale(1, -1);
canvas->translate(0, -input->height());
- SkPaint paint;
+ cc::PaintFlags paint;
paint.setBlendMode(SkBlendMode::kSrc);
- canvas->drawImage(image.get(), 0, 0, &paint);
- return CreateImage(surface->makeImageSnapshot(),
- input->ContextProviderWrapper());
+ canvas->drawImage(input->PaintImageForCurrentFrame(), 0, 0, &paint);
+ return resource_provider->Snapshot(input->CurrentFrameOrientation());
}
scoped_refptr<StaticBitmapImage> GetImageWithAlphaDisposition(
@@ -318,22 +336,17 @@ scoped_refptr<StaticBitmapImage> GetImageWithAlphaDisposition(
// To premul, draw the unpremul image on a surface to avoid GPU read back if
// image is texture backed.
if (alpha_type == kPremul_SkAlphaType) {
- sk_sp<SkSurface> surface = nullptr;
- if (image->IsTextureBacked()) {
- GrContext* context =
- image->ContextProviderWrapper()->ContextProvider()->GetGrContext();
- if (context)
- surface = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info);
- }
- if (!surface)
- surface = SkSurface::MakeRaster(info);
- if (!surface)
+ auto resource_provider = CreateProvider(
+ image->IsTextureBacked() ? image->ContextProviderWrapper() : nullptr,
+ info, image, true /* fallback_to_software */);
+ if (!resource_provider)
return nullptr;
- SkPaint paint;
+
+ cc::PaintFlags paint;
paint.setBlendMode(SkBlendMode::kSrc);
- surface->getCanvas()->drawImage(skia_image.get(), 0, 0, &paint);
- return CreateImage(surface->makeImageSnapshot(),
- image->ContextProviderWrapper());
+ resource_provider->Canvas()->drawImage(image->PaintImageForCurrentFrame(),
+ 0, 0, &paint);
+ return resource_provider->Snapshot(image->CurrentFrameOrientation());
}
// To unpremul, read back the pixels.
@@ -350,7 +363,8 @@ scoped_refptr<StaticBitmapImage> GetImageWithAlphaDisposition(
bool read_successful =
skia_image->readPixels(info, writable_pixels, image_row_bytes, 0, 0);
DCHECK(read_successful);
- return StaticBitmapImage::Create(std::move(dst_pixels), info);
+ return StaticBitmapImage::Create(std::move(dst_pixels), info,
+ image->CurrentFrameOrientation());
}
scoped_refptr<StaticBitmapImage> ScaleImage(
@@ -359,64 +373,62 @@ scoped_refptr<StaticBitmapImage> ScaleImage(
auto sk_image = image->PaintImageForCurrentFrame().GetSkImage();
auto image_info = GetSkImageInfo(image).makeWH(parsed_options.resize_width,
parsed_options.resize_height);
- sk_sp<SkSurface> surface = nullptr;
- sk_sp<SkImage> resized_sk_image = nullptr;
// Try to avoid GPU read back by drawing accelerated premul image on an
// accelerated surface.
if (!ShouldAvoidPremul(parsed_options) && image->IsTextureBacked() &&
sk_image->alphaType() == kPremul_SkAlphaType) {
- GrContext* context =
- image->ContextProviderWrapper()->ContextProvider()->GetGrContext();
- if (context) {
- surface =
- SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, image_info);
- }
- if (surface) {
- SkPaint paint;
+ auto resource_provider =
+ CreateProvider(image->ContextProviderWrapper(), image_info, image,
+ false /* fallback_to_software */);
+ if (resource_provider) {
+ cc::PaintFlags paint;
paint.setFilterQuality(parsed_options.resize_quality);
- surface->getCanvas()->drawImageRect(
- sk_image.get(),
+ resource_provider->Canvas()->drawImageRect(
+ image->PaintImageForCurrentFrame(),
+ SkRect::MakeWH(sk_image->width(), sk_image->height()),
SkRect::MakeWH(parsed_options.resize_width,
parsed_options.resize_height),
- &paint);
- resized_sk_image = surface->makeImageSnapshot();
+ &paint, cc::PaintCanvas::kStrict_SrcRectConstraint);
+ return resource_provider->Snapshot(image->CurrentFrameOrientation());
}
}
- if (!surface) {
- // Avoid sRGB transfer function by setting the color space to nullptr.
- if (image_info.colorSpace()->isSRGB())
- image_info = image_info.makeColorSpace(nullptr);
-
- sk_sp<SkData> image_pixels =
- TryAllocateSkData(image_info.computeMinByteSize());
- if (!image_pixels) {
- return nullptr;
- }
+ // Avoid sRGB transfer function by setting the color space to nullptr.
+ if (image_info.colorSpace()->isSRGB())
+ image_info = image_info.makeColorSpace(nullptr);
- SkPixmap resized_pixmap(image_info, image_pixels->data(),
- image_info.minRowBytes());
- sk_image->scalePixels(resized_pixmap, parsed_options.resize_quality);
- // Tag the resized Pixmap with the correct color space.
- resized_pixmap.setColorSpace(GetSkImageInfo(image).refColorSpace());
-
- resized_sk_image =
- SkImage::MakeRasterData(resized_pixmap.info(), std::move(image_pixels),
- resized_pixmap.rowBytes());
+ sk_sp<SkData> image_pixels =
+ TryAllocateSkData(image_info.computeMinByteSize());
+ if (!image_pixels) {
+ return nullptr;
}
+ SkPixmap resized_pixmap(image_info, image_pixels->data(),
+ image_info.minRowBytes());
+ sk_image->scalePixels(resized_pixmap, parsed_options.resize_quality);
+ // Tag the resized Pixmap with the correct color space.
+ resized_pixmap.setColorSpace(GetSkImageInfo(image).refColorSpace());
+
+ auto resized_sk_image =
+ SkImage::MakeRasterData(resized_pixmap.info(), std::move(image_pixels),
+ resized_pixmap.rowBytes());
if (!resized_sk_image)
return nullptr;
- return CreateImage(resized_sk_image, image->ContextProviderWrapper());
+ return UnacceleratedStaticBitmapImage::Create(
+ resized_sk_image, image->CurrentFrameOrientation());
}
scoped_refptr<StaticBitmapImage> ApplyColorSpaceConversion(
scoped_refptr<StaticBitmapImage>&& image,
ImageBitmap::ParsedOptions& options) {
sk_sp<SkColorSpace> color_space = options.color_params.GetSkColorSpace();
- SkColorType color_type = kN32_SkColorType;
+ SkColorType color_type =
+ image->IsTextureBacked() ? kRGBA_8888_SkColorType : kN32_SkColorType;
sk_sp<SkImage> sk_image = image->PaintImageForCurrentFrame().GetSkImage();
+ if (!sk_image)
+ return nullptr;
+
// If we should preserve color precision, don't lose it in color space
// conversion.
if (options.pixel_format == kImageBitmapPixelFormat_Default &&
@@ -466,9 +478,11 @@ scoped_refptr<StaticBitmapImage> GetImageWithPixelFormat(
}
static scoped_refptr<StaticBitmapImage> CropImageAndApplyColorSpaceConversion(
- scoped_refptr<Image>&& image,
+ scoped_refptr<StaticBitmapImage>&& image,
ImageBitmap::ParsedOptions& parsed_options) {
DCHECK(image);
+ DCHECK(!image->Data());
+
IntRect img_rect(IntPoint(), IntSize(image->width(), image->height()));
const IntRect src_rect = Intersection(img_rect, parsed_options.crop_rect);
@@ -477,44 +491,34 @@ static scoped_refptr<StaticBitmapImage> CropImageAndApplyColorSpaceConversion(
if (src_rect.IsEmpty())
return MakeBlankImage(parsed_options);
- sk_sp<SkImage> skia_image = image->PaintImageForCurrentFrame().GetSkImage();
- // Attempt to get raw unpremultiplied image data, executed only when
- // skia_image is premultiplied.
- if (!skia_image->isOpaque() && image->Data() &&
- skia_image->alphaType() == kPremul_SkAlphaType) {
- const bool data_complete = true;
- std::unique_ptr<ImageDecoder> decoder(ImageDecoder::Create(
- image->Data(), data_complete,
- parsed_options.premultiply_alpha ? ImageDecoder::kAlphaPremultiplied
- : ImageDecoder::kAlphaNotPremultiplied,
- ImageDecoder::kDefaultBitDepth,
- parsed_options.has_color_space_conversion ? ColorBehavior::Tag()
- : ColorBehavior::Ignore()));
- if (!decoder)
- return nullptr;
- skia_image = ImageBitmap::GetSkImageFromDecoder(std::move(decoder));
- if (!skia_image)
- return nullptr;
-
- // In the case where the source image is lazy-decoded, image_ may not be in
- // a decoded state, we trigger it here.
- SkPixmap pixmap;
- if (!skia_image->isTextureBacked() && !skia_image->peekPixels(&pixmap)) {
- sk_sp<SkSurface> surface = SkSurface::MakeRaster(
- GetSkImageInfo(UnacceleratedStaticBitmapImage::Create(skia_image)));
- SkPaint paint;
- paint.setBlendMode(SkBlendMode::kSrc);
- surface->getCanvas()->drawImage(skia_image.get(), 0, 0, &paint);
- skia_image = surface->makeImageSnapshot();
+ scoped_refptr<StaticBitmapImage> result = image;
+ if (src_rect != img_rect) {
+ auto paint_image = result->PaintImageForCurrentFrame();
+ if (result->IsTextureBacked()) {
+ auto image_info = paint_image.GetSkImage()->imageInfo().makeWH(
+ src_rect.Width(), src_rect.Height());
+ auto resource_provider =
+ CreateProvider(image->ContextProviderWrapper(), image_info, result,
+ true /* fallback_to_software*/);
+ if (!resource_provider)
+ return nullptr;
+ cc::PaintFlags paint;
+ resource_provider->Canvas()->drawImageRect(
+ paint_image,
+ 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);
+ result = resource_provider->Snapshot(image->CurrentFrameOrientation());
+ } else {
+ result = UnacceleratedStaticBitmapImage::Create(
+ cc::PaintImageBuilder::WithCopy(std::move(paint_image))
+ .make_subset(src_rect)
+ .TakePaintImage(),
+ image->CurrentFrameOrientation());
}
}
- if (src_rect != img_rect)
- skia_image = skia_image->makeSubset(src_rect);
-
- scoped_refptr<StaticBitmapImage> result =
- CreateImage(skia_image, image->ContextProviderWrapper());
-
// down-scaling has higher priority than other tasks, up-scaling has lower.
bool down_scaling =
parsed_options.should_scale_input &&
@@ -581,6 +585,8 @@ ImageBitmap::ImageBitmap(ImageElementBase* image,
Document* document,
const ImageBitmapOptions* options) {
scoped_refptr<Image> input = image->CachedImage()->GetImage();
+ DCHECK(!input->IsTextureBacked());
+
ParsedOptions parsed_options =
ParseOptions(options, crop_rect, image->BitmapSourceSize());
parsed_options.source_is_unpremul =
@@ -589,8 +595,55 @@ ImageBitmap::ImageBitmap(ImageElementBase* image,
if (DstBufferSizeHasOverflow(parsed_options))
return;
- image_ =
- CropImageAndApplyColorSpaceConversion(std::move(input), parsed_options);
+ cc::PaintImage paint_image = input->PaintImageForCurrentFrame();
+ if (!paint_image)
+ return;
+
+ DCHECK(!paint_image.IsTextureBacked());
+ if (input->IsBitmapImage()) {
+ // A BitmapImage indicates that this is a coded backed image.
+ if (!input->Data())
+ return;
+
+ DCHECK(paint_image.IsLazyGenerated());
+ const bool data_complete = true;
+ std::unique_ptr<ImageDecoder> decoder(ImageDecoder::Create(
+ input->Data(), data_complete,
+ parsed_options.premultiply_alpha ? ImageDecoder::kAlphaPremultiplied
+ : ImageDecoder::kAlphaNotPremultiplied,
+ ImageDecoder::kDefaultBitDepth,
+ parsed_options.has_color_space_conversion ? ColorBehavior::Tag()
+ : ColorBehavior::Ignore(),
+ ImageDecoder::OverrideAllowDecodeToYuv::kDeny));
+ auto skia_image = ImageBitmap::GetSkImageFromDecoder(std::move(decoder));
+ if (!skia_image)
+ return;
+
+ paint_image = PaintImageBuilder::WithDefault()
+ .set_id(paint_image.stable_id())
+ .set_image(std::move(skia_image),
+ paint_image.GetContentIdForFrame(0u))
+ .TakePaintImage();
+ } else if (paint_image.IsLazyGenerated()) {
+ // Other Image types can still produce lazy generated images (for example
+ // SVGs).
+ SkBitmap bitmap;
+ SkImageInfo image_info = GetSkImageInfo(input);
+ bitmap.allocPixels(image_info, image_info.minRowBytes());
+ if (!paint_image.GetSkImage()->readPixels(bitmap.pixmap(), 0, 0))
+ return;
+
+ paint_image = PaintImageBuilder::WithDefault()
+ .set_id(paint_image.stable_id())
+ .set_image(SkImage::MakeFromBitmap(bitmap),
+ paint_image.GetContentIdForFrame(0u))
+ .TakePaintImage();
+ }
+
+ auto static_input = UnacceleratedStaticBitmapImage::Create(
+ std::move(paint_image), input->CurrentFrameOrientation());
+ image_ = CropImageAndApplyColorSpaceConversion(std::move(static_input),
+ parsed_options);
if (!image_)
return;
@@ -609,16 +662,11 @@ ImageBitmap::ImageBitmap(HTMLVideoElement* video,
// TODO(fserb): this shouldn't be software?
std::unique_ptr<CanvasResourceProvider> resource_provider =
- CanvasResourceProvider::Create(
+ CanvasResourceProvider::CreateBitmapProvider(
IntSize(video->videoWidth(), video->videoHeight()),
- CanvasResourceProvider::ResourceUsage::kSoftwareResourceUsage,
- nullptr, // context_provider_wrapper
- 0, // msaa_sample_count
kLow_SkFilterQuality,
- CanvasColorParams(), // TODO: set color space here to avoid clamping
- CanvasResourceProvider::kDefaultPresentationMode,
- nullptr, // canvas_resource_dispatcher
- IsAccelerated()); // is_origin_top_left
+ CanvasColorParams()); // TODO: set color space here to avoid clamping
+
if (!resource_provider)
return;
@@ -627,7 +675,8 @@ ImageBitmap::ImageBitmap(HTMLVideoElement* video,
IntRect(IntPoint(), IntSize(video->videoWidth(), video->videoHeight())),
nullptr);
scoped_refptr<StaticBitmapImage> input = resource_provider->Snapshot();
- image_ = CropImageAndApplyColorSpaceConversion(input, parsed_options);
+ image_ =
+ CropImageAndApplyColorSpaceConversion(std::move(input), parsed_options);
if (!image_)
return;
@@ -643,7 +692,7 @@ ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas,
&status, kPreferAcceleration, FloatSize());
if (status != kNormalSourceImageStatus)
return;
- DCHECK(image_input->IsStaticBitmapImage());
+ DCHECK(IsA<StaticBitmapImage>(image_input.get()));
scoped_refptr<StaticBitmapImage> input =
static_cast<StaticBitmapImage*>(image_input.get());
@@ -667,7 +716,7 @@ ImageBitmap::ImageBitmap(OffscreenCanvas* offscreen_canvas,
SourceImageStatus status;
scoped_refptr<Image> raw_input = offscreen_canvas->GetSourceImageForCanvas(
&status, kPreferNoAcceleration, FloatSize(offscreen_canvas->Size()));
- DCHECK(raw_input->IsStaticBitmapImage());
+ DCHECK(IsA<StaticBitmapImage>(raw_input.get()));
scoped_refptr<StaticBitmapImage> input =
static_cast<StaticBitmapImage*>(raw_input.get());
raw_input = nullptr;
@@ -870,67 +919,6 @@ ImageBitmap::~ImageBitmap() {
-memory_usage_);
}
-ImageBitmap* ImageBitmap::Create(ImageElementBase* image,
- base::Optional<IntRect> crop_rect,
- Document* document,
- const ImageBitmapOptions* options) {
- return MakeGarbageCollected<ImageBitmap>(image, crop_rect, document, options);
-}
-
-ImageBitmap* ImageBitmap::Create(HTMLVideoElement* video,
- base::Optional<IntRect> crop_rect,
- Document* document,
- const ImageBitmapOptions* options) {
- return MakeGarbageCollected<ImageBitmap>(video, crop_rect, document, options);
-}
-
-ImageBitmap* ImageBitmap::Create(HTMLCanvasElement* canvas,
- base::Optional<IntRect> crop_rect,
- const ImageBitmapOptions* options) {
- return MakeGarbageCollected<ImageBitmap>(canvas, crop_rect, options);
-}
-
-ImageBitmap* ImageBitmap::Create(OffscreenCanvas* offscreen_canvas,
- base::Optional<IntRect> crop_rect,
- const ImageBitmapOptions* options) {
- return MakeGarbageCollected<ImageBitmap>(offscreen_canvas, crop_rect,
- options);
-}
-
-ImageBitmap* ImageBitmap::Create(ImageData* data,
- base::Optional<IntRect> crop_rect,
- const ImageBitmapOptions* options) {
- return MakeGarbageCollected<ImageBitmap>(data, crop_rect, options);
-}
-
-ImageBitmap* ImageBitmap::Create(ImageBitmap* bitmap,
- base::Optional<IntRect> crop_rect,
- const ImageBitmapOptions* options) {
- return MakeGarbageCollected<ImageBitmap>(bitmap, crop_rect, options);
-}
-
-ImageBitmap* ImageBitmap::Create(scoped_refptr<StaticBitmapImage> image,
- base::Optional<IntRect> crop_rect,
- const ImageBitmapOptions* options) {
- return MakeGarbageCollected<ImageBitmap>(std::move(image), crop_rect,
- options);
-}
-
-ImageBitmap* ImageBitmap::Create(scoped_refptr<StaticBitmapImage> image) {
- return MakeGarbageCollected<ImageBitmap>(std::move(image));
-}
-
-ImageBitmap* ImageBitmap::Create(const void* pixel_data,
- uint32_t width,
- uint32_t height,
- bool is_image_bitmap_premultiplied,
- bool is_image_bitmap_origin_clean,
- const CanvasColorParams& color_params) {
- return MakeGarbageCollected<ImageBitmap>(
- pixel_data, width, height, is_image_bitmap_premultiplied,
- is_image_bitmap_origin_clean, color_params);
-}
-
void ImageBitmap::ResolvePromiseOnOriginalThread(
ScriptPromiseResolver* resolver,
bool origin_clean,
@@ -1052,7 +1040,7 @@ void ImageBitmap::close() {
// static
ImageBitmap* ImageBitmap::Take(ScriptPromiseResolver*, sk_sp<SkImage> image) {
- return ImageBitmap::Create(
+ return MakeGarbageCollected<ImageBitmap>(
UnacceleratedStaticBitmapImage::Create(std::move(image)));
}
@@ -1094,7 +1082,7 @@ unsigned ImageBitmap::height() const {
}
bool ImageBitmap::IsAccelerated() const {
- return image_ && (image_->IsTextureBacked() || image_->HasMailbox());
+ return image_ && image_->IsTextureBacked();
}
IntSize ImageBitmap::Size() const {
@@ -1105,13 +1093,14 @@ IntSize ImageBitmap::Size() const {
return IntSize(image_->width(), image_->height());
}
-ScriptPromise ImageBitmap::CreateImageBitmap(
- ScriptState* script_state,
- EventTarget& event_target,
- base::Optional<IntRect> crop_rect,
- const ImageBitmapOptions* options) {
+ScriptPromise ImageBitmap::CreateImageBitmap(ScriptState* script_state,
+ EventTarget& event_target,
+ base::Optional<IntRect> crop_rect,
+ const ImageBitmapOptions* options,
+ ExceptionState& exception_state) {
return ImageBitmapSource::FulfillImageBitmap(
- script_state, Create(this, crop_rect, options));
+ script_state, MakeGarbageCollected<ImageBitmap>(this, crop_rect, options),
+ exception_state);
}
scoped_refptr<Image> ImageBitmap::GetSourceImageForCanvas(
@@ -1128,11 +1117,10 @@ scoped_refptr<Image> ImageBitmap::GetSourceImageForCanvas(
return GetImageWithAlphaDisposition(std::move(image_), kPremultiplyAlpha);
}
-void ImageBitmap::AdjustDrawRects(FloatRect* src_rect,
- FloatRect* dst_rect) const {}
-
-FloatSize ImageBitmap::ElementSize(const FloatSize&) const {
- return FloatSize(width(), height());
+FloatSize ImageBitmap::ElementSize(
+ const FloatSize&,
+ const RespectImageOrientationEnum respect_orientation) const {
+ return FloatSize(image_->Size(respect_orientation));
}
} // namespace blink
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 f4fde0b280a..67f62c38edc 100644
--- a/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap.h
+++ b/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap.h
@@ -8,14 +8,15 @@
#include <memory>
#include "base/memory/scoped_refptr.h"
#include "base/sequenced_task_runner.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_image_source.h"
#include "third_party/blink/renderer/core/html/canvas/image_element_base.h"
-#include "third_party/blink/renderer/core/imagebitmap/image_bitmap_options.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap_source.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
+#include "third_party/blink/renderer/platform/graphics/image_orientation.h"
#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -40,48 +41,6 @@ class CORE_EXPORT ImageBitmap final : public ScriptWrappable,
DEFINE_WRAPPERTYPEINFO();
public:
- static ImageBitmap* Create(
- ImageElementBase*,
- base::Optional<IntRect>,
- Document*,
- const ImageBitmapOptions* = ImageBitmapOptions::Create());
- static ImageBitmap* Create(
- HTMLVideoElement*,
- base::Optional<IntRect>,
- Document*,
- const ImageBitmapOptions* = ImageBitmapOptions::Create());
- static ImageBitmap* Create(
- HTMLCanvasElement*,
- base::Optional<IntRect>,
- const ImageBitmapOptions* = ImageBitmapOptions::Create());
- static ImageBitmap* Create(
- OffscreenCanvas*,
- base::Optional<IntRect>,
- const ImageBitmapOptions* = ImageBitmapOptions::Create());
- static ImageBitmap* Create(
- ImageData*,
- base::Optional<IntRect>,
- const ImageBitmapOptions* = ImageBitmapOptions::Create());
- static ImageBitmap* Create(
- ImageBitmap*,
- base::Optional<IntRect>,
- const ImageBitmapOptions* = ImageBitmapOptions::Create());
- static ImageBitmap* Create(scoped_refptr<StaticBitmapImage>);
- static ImageBitmap* Create(
- scoped_refptr<StaticBitmapImage>,
- base::Optional<IntRect>,
- const ImageBitmapOptions* = ImageBitmapOptions::Create());
- // This function is called by structured-cloning an ImageBitmap.
- // isImageBitmapPremultiplied indicates whether the original ImageBitmap is
- // premultiplied or not.
- // isImageBitmapOriginClean indicates whether the original ImageBitmap is
- // origin clean or not.
- static ImageBitmap* Create(const void* pixel_data,
- uint32_t width,
- uint32_t height,
- bool is_image_bitmap_premultiplied,
- bool is_image_bitmap_origin_clean,
- const CanvasColorParams&);
static ScriptPromise CreateAsync(
ImageElementBase*,
base::Optional<IntRect>,
@@ -93,23 +52,32 @@ class CORE_EXPORT ImageBitmap final : public ScriptWrappable,
ImageBitmap(ImageElementBase*,
base::Optional<IntRect>,
Document*,
- const ImageBitmapOptions*);
+ const ImageBitmapOptions* = ImageBitmapOptions::Create());
ImageBitmap(HTMLVideoElement*,
base::Optional<IntRect>,
Document*,
- const ImageBitmapOptions*);
+ const ImageBitmapOptions* = ImageBitmapOptions::Create());
ImageBitmap(HTMLCanvasElement*,
base::Optional<IntRect>,
- const ImageBitmapOptions*);
+ const ImageBitmapOptions* = ImageBitmapOptions::Create());
ImageBitmap(OffscreenCanvas*,
base::Optional<IntRect>,
- const ImageBitmapOptions*);
- ImageBitmap(ImageData*, base::Optional<IntRect>, const ImageBitmapOptions*);
- ImageBitmap(ImageBitmap*, base::Optional<IntRect>, const ImageBitmapOptions*);
+ const ImageBitmapOptions* = ImageBitmapOptions::Create());
+ ImageBitmap(ImageData*,
+ base::Optional<IntRect>,
+ const ImageBitmapOptions* = ImageBitmapOptions::Create());
+ ImageBitmap(ImageBitmap*,
+ base::Optional<IntRect>,
+ const ImageBitmapOptions* = ImageBitmapOptions::Create());
ImageBitmap(scoped_refptr<StaticBitmapImage>);
ImageBitmap(scoped_refptr<StaticBitmapImage>,
base::Optional<IntRect>,
- const ImageBitmapOptions*);
+ const ImageBitmapOptions* = ImageBitmapOptions::Create());
+ // This constructor may called by structured-cloning an ImageBitmap.
+ // isImageBitmapPremultiplied indicates whether the original ImageBitmap is
+ // premultiplied or not.
+ // isImageBitmapOriginClean indicates whether the original ImageBitmap is
+ // origin clean or not.
ImageBitmap(const void* pixel_data,
uint32_t width,
uint32_t height,
@@ -144,8 +112,8 @@ class CORE_EXPORT ImageBitmap final : public ScriptWrappable,
AccelerationHint,
const FloatSize&) override;
bool WouldTaintOrigin() const override { return !image_->OriginClean(); }
- void AdjustDrawRects(FloatRect* src_rect, FloatRect* dst_rect) const override;
- FloatSize ElementSize(const FloatSize&) const override;
+ FloatSize ElementSize(const FloatSize&,
+ const RespectImageOrientationEnum) const override;
bool IsImageBitmap() const override { return true; }
bool IsAccelerated() const override;
@@ -154,7 +122,8 @@ class CORE_EXPORT ImageBitmap final : public ScriptWrappable,
ScriptPromise CreateImageBitmap(ScriptState*,
EventTarget&,
base::Optional<IntRect>,
- const ImageBitmapOptions*) override;
+ const ImageBitmapOptions*,
+ ExceptionState&) override;
struct ParsedOptions {
bool flip_y = false;
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 4379d18467b..7e368e714fe 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
@@ -35,6 +35,7 @@
#include "base/location.h"
#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.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/fileapi/blob.h"
@@ -44,7 +45,6 @@
#include "third_party/blink/renderer/core/html/html_image_element.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
-#include "third_party/blink/renderer/core/imagebitmap/image_bitmap_options.h"
#include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h"
#include "third_party/blink/renderer/core/svg/svg_image_element.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
@@ -144,7 +144,8 @@ ScriptPromise ImageBitmapFactories::CreateImageBitmap(
ScriptState* script_state,
EventTarget& event_target,
const ImageBitmapSourceUnion& bitmap_source,
- const ImageBitmapOptions* options) {
+ const ImageBitmapOptions* options,
+ ExceptionState& exception_state) {
WebFeature feature = WebFeature::kCreateImageBitmap;
UseCounter::Count(ExecutionContext::From(script_state), feature);
ImageBitmapSource* bitmap_source_internal =
@@ -152,7 +153,7 @@ ScriptPromise ImageBitmapFactories::CreateImageBitmap(
if (!bitmap_source_internal)
return ScriptPromise();
return CreateImageBitmap(script_state, event_target, bitmap_source_internal,
- base::Optional<IntRect>(), options);
+ base::Optional<IntRect>(), options, exception_state);
}
ScriptPromise ImageBitmapFactories::CreateImageBitmap(
@@ -163,7 +164,8 @@ ScriptPromise ImageBitmapFactories::CreateImageBitmap(
int sy,
int sw,
int sh,
- const ImageBitmapOptions* options) {
+ const ImageBitmapOptions* options,
+ ExceptionState& exception_state) {
WebFeature feature = WebFeature::kCreateImageBitmap;
UseCounter::Count(ExecutionContext::From(script_state), feature);
ImageBitmapSource* bitmap_source_internal =
@@ -172,7 +174,7 @@ ScriptPromise ImageBitmapFactories::CreateImageBitmap(
return ScriptPromise();
base::Optional<IntRect> crop_rect = IntRect(sx, sy, sw, sh);
return CreateImageBitmap(script_state, event_target, bitmap_source_internal,
- crop_rect, options);
+ crop_rect, options, exception_state);
}
ScriptPromise ImageBitmapFactories::CreateImageBitmap(
@@ -180,14 +182,12 @@ ScriptPromise ImageBitmapFactories::CreateImageBitmap(
EventTarget& event_target,
ImageBitmapSource* bitmap_source,
base::Optional<IntRect> crop_rect,
- const ImageBitmapOptions* options) {
+ const ImageBitmapOptions* options,
+ ExceptionState& exception_state) {
if (crop_rect && (crop_rect->Width() == 0 || crop_rect->Height() == 0)) {
- return ScriptPromise::Reject(
- script_state,
- V8ThrowException::CreateRangeError(
- script_state->GetIsolate(),
- String::Format("The crop rect %s is 0.",
- crop_rect->Width() ? "height" : "width")));
+ exception_state.ThrowRangeError(String::Format(
+ "The crop rect %s is 0.", crop_rect->Width() ? "height" : "width"));
+ return ScriptPromise();
}
if (bitmap_source->IsBlob()) {
@@ -197,18 +197,16 @@ ScriptPromise ImageBitmapFactories::CreateImageBitmap(
if (bitmap_source->BitmapSourceSize().Width() == 0 ||
bitmap_source->BitmapSourceSize().Height() == 0) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- String::Format("The source image %s is 0.",
- bitmap_source->BitmapSourceSize().Width()
- ? "height"
- : "width")));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ String::Format(
+ "The source image %s is 0.",
+ bitmap_source->BitmapSourceSize().Width() ? "height" : "width"));
+ return ScriptPromise();
}
return bitmap_source->CreateImageBitmap(script_state, event_target, crop_rect,
- options);
+ options, exception_state);
}
const char ImageBitmapFactories::kSupplementName[] = "ImageBitmapFactories";
@@ -241,7 +239,7 @@ void ImageBitmapFactories::DidFinishLoading(ImageBitmapLoader* loader) {
pending_loaders_.erase(loader);
}
-void ImageBitmapFactories::Trace(blink::Visitor* visitor) {
+void ImageBitmapFactories::Trace(Visitor* visitor) {
visitor->Trace(pending_loaders_);
Supplement<LocalDOMWindow>::Trace(visitor);
Supplement<WorkerGlobalScope>::Trace(visitor);
@@ -252,7 +250,7 @@ ImageBitmapFactories::ImageBitmapLoader::ImageBitmapLoader(
base::Optional<IntRect> crop_rect,
ScriptState* script_state,
const ImageBitmapOptions* options)
- : ContextLifecycleObserver(ExecutionContext::From(script_state)),
+ : ExecutionContextLifecycleObserver(ExecutionContext::From(script_state)),
loader_(std::make_unique<FileReaderLoader>(
FileReaderLoader::kReadAsArrayBuffer,
this,
@@ -290,8 +288,7 @@ void ImageBitmapFactories::ImageBitmapLoader::RejectPromise(
factory_->DidFinishLoading(this);
}
-void ImageBitmapFactories::ImageBitmapLoader::ContextDestroyed(
- ExecutionContext*) {
+void ImageBitmapFactories::ImageBitmapLoader::ContextDestroyed() {
if (loader_)
factory_->DidFinishLoading(this);
loader_.reset();
@@ -323,7 +320,7 @@ void DecodeImageOnDecoderThread(
SegmentReader::CreateFromSkData(
SkData::MakeWithoutCopy(contents.Data(), contents.DataLength())),
data_complete, alpha_option, ImageDecoder::kDefaultBitDepth,
- color_behavior);
+ color_behavior, ImageDecoder::OverrideAllowDecodeToYuv::kDeny);
sk_sp<SkImage> frame;
if (decoder) {
frame = ImageBitmap::GetSkImageFromDecoder(std::move(decoder));
@@ -369,7 +366,8 @@ void ImageBitmapFactories::ImageBitmapLoader::ResolvePromiseOnOriginalThread(
scoped_refptr<StaticBitmapImage> image =
UnacceleratedStaticBitmapImage::Create(std::move(frame));
image->SetOriginClean(true);
- ImageBitmap* image_bitmap = ImageBitmap::Create(image, crop_rect_, options_);
+ auto* image_bitmap =
+ MakeGarbageCollected<ImageBitmap>(image, crop_rect_, options_);
if (image_bitmap && image_bitmap->BitmapImage()) {
resolver_->Resolve(image_bitmap);
} else {
@@ -379,8 +377,8 @@ void ImageBitmapFactories::ImageBitmapLoader::ResolvePromiseOnOriginalThread(
factory_->DidFinishLoading(this);
}
-void ImageBitmapFactories::ImageBitmapLoader::Trace(blink::Visitor* visitor) {
- ContextLifecycleObserver::Trace(visitor);
+void ImageBitmapFactories::ImageBitmapLoader::Trace(Visitor* visitor) {
+ ExecutionContextLifecycleObserver::Trace(visitor);
visitor->Trace(factory_);
visitor->Trace(resolver_);
visitor->Trace(options_);
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 6413b903ea8..41f6461c7ac 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
@@ -37,12 +37,12 @@
#include "third_party/blink/renderer/bindings/core/v8/image_bitmap_source.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/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/fileapi/file_reader_loader.h"
#include "third_party/blink/renderer/core/fileapi/file_reader_loader_client.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/window_or_worker_global_scope.h"
-#include "third_party/blink/renderer/core/imagebitmap/image_bitmap_options.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
@@ -58,7 +58,6 @@ namespace blink {
class Blob;
class EventTarget;
class ImageBitmapSource;
-class ImageBitmapOptions;
class ImageBitmapFactories final
: public GarbageCollected<ImageBitmapFactories>,
@@ -73,7 +72,8 @@ class ImageBitmapFactories final
static ScriptPromise CreateImageBitmap(ScriptState*,
EventTarget&,
const ImageBitmapSourceUnion&,
- const ImageBitmapOptions*);
+ const ImageBitmapOptions*,
+ ExceptionState&);
static ScriptPromise CreateImageBitmap(ScriptState*,
EventTarget&,
const ImageBitmapSourceUnion&,
@@ -81,12 +81,14 @@ class ImageBitmapFactories final
int sy,
int sw,
int sh,
- const ImageBitmapOptions*);
+ const ImageBitmapOptions*,
+ ExceptionState&);
static ScriptPromise CreateImageBitmap(ScriptState*,
EventTarget&,
ImageBitmapSource*,
base::Optional<IntRect> crop_rect,
- const ImageBitmapOptions*);
+ const ImageBitmapOptions*,
+ ExceptionState&);
static ScriptPromise CreateImageBitmapFromBlob(
ScriptState*,
EventTarget&,
@@ -96,14 +98,14 @@ class ImageBitmapFactories final
virtual ~ImageBitmapFactories() = default;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
const char* NameInHeapSnapshot() const override {
return "ImageBitmapLoader";
}
private:
class ImageBitmapLoader final : public GarbageCollected<ImageBitmapLoader>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public FileReaderLoaderClient {
USING_GARBAGE_COLLECTED_MIXIN(ImageBitmapLoader);
@@ -124,7 +126,7 @@ class ImageBitmapFactories final
void LoadBlobAsync(Blob*);
ScriptPromise Promise() { return resolver_->Promise(); }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
~ImageBitmapLoader() override;
@@ -141,8 +143,8 @@ class ImageBitmapFactories final
void ScheduleAsyncImageBitmapDecoding(ArrayBufferContents);
void ResolvePromiseOnOriginalThread(sk_sp<SkImage>);
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
// FileReaderLoaderClient
void DidStartLoading() override {}
diff --git a/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_source.cc b/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_source.cc
index ff800de4ca6..b6eba7436a2 100644
--- a/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_source.cc
+++ b/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_source.cc
@@ -4,24 +4,28 @@
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap_source.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
-#include "third_party/blink/renderer/core/imagebitmap/image_bitmap_options.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
-ScriptPromise ImageBitmapSource::FulfillImageBitmap(ScriptState* script_state,
- ImageBitmap* image_bitmap) {
- auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
- ScriptPromise promise = resolver->Promise();
- if (image_bitmap && image_bitmap->BitmapImage()) {
- resolver->Resolve(image_bitmap);
- } else {
- resolver->Reject(MakeGarbageCollected<DOMException>(
+ScriptPromise ImageBitmapSource::FulfillImageBitmap(
+ ScriptState* script_state,
+ ImageBitmap* image_bitmap,
+ ExceptionState& exception_state) {
+ if (!image_bitmap || !image_bitmap->BitmapImage()) {
+ exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidStateError,
- "The ImageBitmap could not be allocated."));
+ "The ImageBitmap could not be allocated.");
+ return ScriptPromise();
}
+
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ ScriptPromise promise = resolver->Promise();
+ resolver->Resolve(image_bitmap);
return promise;
}
@@ -29,7 +33,8 @@ ScriptPromise ImageBitmapSource::CreateImageBitmap(
ScriptState* script_state,
EventTarget& event_target,
base::Optional<IntRect> crop_rect,
- const ImageBitmapOptions* options) {
+ const ImageBitmapOptions* options,
+ ExceptionState& exception_state) {
return ScriptPromise();
}
diff --git a/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_source.h b/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_source.h
index 289f08778f7..181d47b4e54 100644
--- a/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_source.h
+++ b/chromium/third_party/blink/renderer/core/imagebitmap/image_bitmap_source.h
@@ -27,11 +27,14 @@ class CORE_EXPORT ImageBitmapSource {
virtual ScriptPromise CreateImageBitmap(ScriptState*,
EventTarget&,
base::Optional<IntRect>,
- const ImageBitmapOptions*);
+ const ImageBitmapOptions*,
+ ExceptionState&);
virtual bool IsBlob() const { return false; }
- static ScriptPromise FulfillImageBitmap(ScriptState*, ImageBitmap*);
+ static ScriptPromise FulfillImageBitmap(ScriptState*,
+ ImageBitmap*,
+ ExceptionState&);
protected:
virtual ~ImageBitmapSource() = default;
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 d7241b0b320..dcc61cb485f 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
@@ -41,12 +41,15 @@
#include "third_party/blink/renderer/core/html/html_image_element.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/core/loader/resource/image_resource_content.h"
+#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h"
+#include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
#include "third_party/blink/renderer/platform/graphics/color_correction_test_utils.h"
#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
#include "third_party/blink/renderer/platform/graphics/test/fake_gles2_interface.h"
#include "third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h"
+#include "third_party/blink/renderer/platform/graphics/test/gpu_test_utils.h"
#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
@@ -79,14 +82,10 @@ class ImageBitmapTest : public testing::Test {
ReplaceMemoryCacheForTesting(MakeGarbageCollected<MemoryCache>(
blink::scheduler::GetSingleThreadTaskRunnerForTesting()));
- auto factory = [](FakeGLES2Interface* gl, bool* gpu_compositing_disabled)
- -> std::unique_ptr<WebGraphicsContext3DProvider> {
- *gpu_compositing_disabled = false;
- return std::make_unique<FakeWebGraphicsContext3DProvider>(gl, nullptr);
- };
- SharedGpuContext::SetContextProviderFactoryForTesting(
- WTF::BindRepeating(factory, WTF::Unretained(&gl_)));
+ test_context_provider_ = viz::TestContextProvider::Create();
+ InitializeSharedGpuContext(test_context_provider_.get());
}
+
void TearDown() override {
// Garbage collection is required prior to switching out the
// test's memory cache; image resources are released, evicting
@@ -99,15 +98,16 @@ class ImageBitmapTest : public testing::Test {
}
protected:
- FakeGLES2Interface gl_;
+ scoped_refptr<viz::TestContextProvider> test_context_provider_;
sk_sp<SkImage> image_, image2_;
Persistent<MemoryCache> global_memory_cache_;
};
TEST_F(ImageBitmapTest, ImageResourceConsistency) {
const ImageBitmapOptions* default_options = ImageBitmapOptions::Create();
+ auto dummy = std::make_unique<DummyPageHolder>(IntSize(800, 600));
auto* image_element =
- MakeGarbageCollected<HTMLImageElement>(*MakeGarbageCollected<Document>());
+ MakeGarbageCollected<HTMLImageElement>(dummy->GetDocument());
sk_sp<SkColorSpace> src_rgb_color_space = SkColorSpace::MakeSRGB();
SkImageInfo raster_image_info =
SkImageInfo::MakeN32Premul(5, 5, src_rgb_color_space);
@@ -120,27 +120,27 @@ TEST_F(ImageBitmapTest, ImageResourceConsistency) {
base::Optional<IntRect> crop_rect =
IntRect(0, 0, image_->width(), image_->height());
- ImageBitmap* image_bitmap_no_crop =
- ImageBitmap::Create(image_element, crop_rect,
- &(image_element->GetDocument()), default_options);
+ auto* image_bitmap_no_crop = MakeGarbageCollected<ImageBitmap>(
+ image_element, crop_rect, &(image_element->GetDocument()),
+ default_options);
ASSERT_TRUE(image_bitmap_no_crop);
crop_rect = IntRect(image_->width() / 2, image_->height() / 2,
image_->width() / 2, image_->height() / 2);
- ImageBitmap* image_bitmap_interior_crop =
- ImageBitmap::Create(image_element, crop_rect,
- &(image_element->GetDocument()), default_options);
+ auto* image_bitmap_interior_crop = MakeGarbageCollected<ImageBitmap>(
+ image_element, crop_rect, &(image_element->GetDocument()),
+ default_options);
ASSERT_TRUE(image_bitmap_interior_crop);
crop_rect = IntRect(-image_->width() / 2, -image_->height() / 2,
image_->width(), image_->height());
- ImageBitmap* image_bitmap_exterior_crop =
- ImageBitmap::Create(image_element, crop_rect,
- &(image_element->GetDocument()), default_options);
+ auto* image_bitmap_exterior_crop = MakeGarbageCollected<ImageBitmap>(
+ image_element, crop_rect, &(image_element->GetDocument()),
+ default_options);
ASSERT_TRUE(image_bitmap_exterior_crop);
crop_rect = IntRect(-image_->width(), -image_->height(), image_->width(),
image_->height());
- ImageBitmap* image_bitmap_outside_crop =
- ImageBitmap::Create(image_element, crop_rect,
- &(image_element->GetDocument()), default_options);
+ auto* image_bitmap_outside_crop = MakeGarbageCollected<ImageBitmap>(
+ image_element, crop_rect, &(image_element->GetDocument()),
+ default_options);
ASSERT_TRUE(image_bitmap_outside_crop);
ASSERT_EQ(image_bitmap_no_crop->BitmapImage()
@@ -177,8 +177,8 @@ TEST_F(ImageBitmapTest, ImageResourceConsistency) {
// Verifies that ImageBitmaps constructed from HTMLImageElements hold a
// reference to the original Image if the HTMLImageElement src is changed.
TEST_F(ImageBitmapTest, ImageBitmapSourceChanged) {
- auto* image =
- MakeGarbageCollected<HTMLImageElement>(*MakeGarbageCollected<Document>());
+ auto dummy = std::make_unique<DummyPageHolder>(IntSize(800, 600));
+ auto* image = MakeGarbageCollected<HTMLImageElement>(dummy->GetDocument());
sk_sp<SkColorSpace> src_rgb_color_space = SkColorSpace::MakeSRGB();
SkImageInfo raster_image_info =
SkImageInfo::MakeN32Premul(5, 5, src_rgb_color_space);
@@ -192,7 +192,7 @@ TEST_F(ImageBitmapTest, ImageBitmapSourceChanged) {
const ImageBitmapOptions* default_options = ImageBitmapOptions::Create();
base::Optional<IntRect> crop_rect =
IntRect(0, 0, image_->width(), image_->height());
- ImageBitmap* image_bitmap = ImageBitmap::Create(
+ auto* image_bitmap = MakeGarbageCollected<ImageBitmap>(
image, crop_rect, &(image->GetDocument()), default_options);
ASSERT_TRUE(image_bitmap);
ASSERT_EQ(
@@ -249,7 +249,7 @@ static void TestImageBitmapTextureBacked(
IntRect& rect,
ImageBitmapOptions* options,
bool is_texture_backed) {
- ImageBitmap* image_bitmap = ImageBitmap::Create(bitmap, rect, options);
+ auto* image_bitmap = MakeGarbageCollected<ImageBitmap>(bitmap, rect, options);
EXPECT_TRUE(image_bitmap);
EXPECT_EQ(image_bitmap->BitmapImage()->IsTextureBacked(), is_texture_backed);
}
@@ -257,18 +257,17 @@ static void TestImageBitmapTextureBacked(
TEST_F(ImageBitmapTest, AvoidGPUReadback) {
base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper =
SharedGpuContext::ContextProviderWrapper();
- GrContext* gr = context_provider_wrapper->ContextProvider()->GetGrContext();
- SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(100, 100);
-
- sk_sp<SkSurface> surface =
- SkSurface::MakeRenderTarget(gr, SkBudgeted::kNo, imageInfo);
- sk_sp<SkImage> image = surface->makeImageSnapshot();
+ 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,
+ 0u /*shared_image_usage_flags*/);
- scoped_refptr<AcceleratedStaticBitmapImage> bitmap =
- AcceleratedStaticBitmapImage::CreateFromSkImage(image,
- context_provider_wrapper);
+ scoped_refptr<StaticBitmapImage> bitmap = resource_provider->Snapshot();
+ ASSERT_TRUE(bitmap->IsTextureBacked());
- ImageBitmap* image_bitmap = ImageBitmap::Create(bitmap);
+ auto* image_bitmap = MakeGarbageCollected<ImageBitmap>(bitmap);
EXPECT_TRUE(image_bitmap);
EXPECT_TRUE(image_bitmap->BitmapImage()->IsTextureBacked());
@@ -315,8 +314,9 @@ TEST_F(ImageBitmapTest, AvoidGPUReadback) {
}
TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionHTMLImageElement) {
+ auto dummy = std::make_unique<DummyPageHolder>(IntSize(800, 600));
auto* image_element =
- MakeGarbageCollected<HTMLImageElement>(*MakeGarbageCollected<Document>());
+ MakeGarbageCollected<HTMLImageElement>(dummy->GetDocument());
SkPaint p;
p.setColor(SK_ColorRED);
@@ -345,7 +345,7 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionHTMLImageElement) {
options->setColorSpaceConversion(
ColorCorrectionTestUtils::ColorSpaceConversionToString(
static_cast<ColorSpaceConversion>(conversion_iterator)));
- ImageBitmap* image_bitmap = ImageBitmap::Create(
+ auto* image_bitmap = MakeGarbageCollected<ImageBitmap>(
image_element, crop_rect, &(image_element->GetDocument()), options);
ASSERT_TRUE(image_bitmap);
sk_sp<SkImage> converted_image =
@@ -404,7 +404,7 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionImageBitmap) {
options->setColorSpaceConversion(
ColorCorrectionTestUtils::ColorSpaceConversionToString(
kColorSpaceConversion_Preserve));
- ImageBitmap* source_image_bitmap = ImageBitmap::Create(
+ auto* source_image_bitmap = MakeGarbageCollected<ImageBitmap>(
UnacceleratedStaticBitmapImage::Create(source_image), crop_rect, options);
ASSERT_TRUE(source_image_bitmap);
@@ -414,8 +414,8 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionImageBitmap) {
options->setColorSpaceConversion(
ColorCorrectionTestUtils::ColorSpaceConversionToString(
static_cast<ColorSpaceConversion>(conversion_iterator)));
- ImageBitmap* image_bitmap =
- ImageBitmap::Create(source_image_bitmap, crop_rect, options);
+ 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();
@@ -477,7 +477,7 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionStaticBitmapImage) {
options->setColorSpaceConversion(
ColorCorrectionTestUtils::ColorSpaceConversionToString(
static_cast<ColorSpaceConversion>(conversion_iterator)));
- ImageBitmap* image_bitmap = ImageBitmap::Create(
+ auto* image_bitmap = MakeGarbageCollected<ImageBitmap>(
UnacceleratedStaticBitmapImage::Create(source_image), crop_rect,
options);
ASSERT_TRUE(image_bitmap);
@@ -520,10 +520,11 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionStaticBitmapImage) {
TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionImageData) {
unsigned char data_buffer[4] = {32, 96, 160, 128};
- DOMUint8ClampedArray* data = DOMUint8ClampedArray::Create(data_buffer, 4);
+ NotShared<DOMUint8ClampedArray> data(
+ DOMUint8ClampedArray::Create(data_buffer, 4));
ImageDataColorSettings* color_settings = ImageDataColorSettings::Create();
- ImageData* image_data = ImageData::Create(
- IntSize(1, 1), NotShared<DOMUint8ClampedArray>(data), color_settings);
+ ImageData* image_data =
+ ImageData::Create(IntSize(1, 1), data, color_settings);
SkImageInfo image_info =
SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kUnpremul_SkAlphaType,
@@ -543,8 +544,8 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionImageData) {
options->setColorSpaceConversion(
ColorCorrectionTestUtils::ColorSpaceConversionToString(
static_cast<ColorSpaceConversion>(conversion_iterator)));
- ImageBitmap* image_bitmap =
- ImageBitmap::Create(image_data, crop_rect, options);
+ auto* image_bitmap =
+ MakeGarbageCollected<ImageBitmap>(image_data, crop_rect, options);
ASSERT_TRUE(image_bitmap);
sk_sp<SkImage> converted_image =
image_bitmap->BitmapImage()->PaintImageForCurrentFrame().GetSkImage();
@@ -591,8 +592,8 @@ TEST_F(ImageBitmapTest, ImageBitmapPixelFormat) {
// source: uint8, bitmap pixel format: default
ImageBitmapOptions* options = ImageBitmapOptions::Create();
- ImageBitmap* image_bitmap =
- ImageBitmap::Create(bitmap_image, bitmap_image->Rect(), options);
+ auto* image_bitmap = MakeGarbageCollected<ImageBitmap>(
+ bitmap_image, bitmap_image->Rect(), options);
ASSERT_TRUE(image_bitmap);
sk_sp<SkImage> sk_image_internal =
@@ -601,8 +602,8 @@ TEST_F(ImageBitmapTest, ImageBitmapPixelFormat) {
// source: uint8, bitmap pixel format: uint8
options->setImagePixelFormat("uint8");
- ImageBitmap* image_bitmap_8888 =
- ImageBitmap::Create(bitmap_image, bitmap_image->Rect(), options);
+ auto* image_bitmap_8888 = MakeGarbageCollected<ImageBitmap>(
+ bitmap_image, bitmap_image->Rect(), options);
ASSERT_TRUE(image_bitmap_8888);
sk_sp<SkImage> sk_image_internal_8888 = image_bitmap_8888->BitmapImage()
->PaintImageForCurrentFrame()
@@ -625,7 +626,7 @@ TEST_F(ImageBitmapTest, ImageBitmapPixelFormat) {
// source: f16, bitmap pixel format: default
ImageBitmapOptions* options_f16 = ImageBitmapOptions::Create();
- ImageBitmap* image_bitmap_f16 = ImageBitmap::Create(
+ auto* image_bitmap_f16 = MakeGarbageCollected<ImageBitmap>(
bitmap_image_f16, bitmap_image_f16->Rect(), options_f16);
ASSERT_TRUE(image_bitmap_f16);
sk_sp<SkImage> sk_image_internal_f16 =
@@ -634,7 +635,7 @@ TEST_F(ImageBitmapTest, ImageBitmapPixelFormat) {
// source: f16, bitmap pixel format: uint8
options_f16->setImagePixelFormat("uint8");
- ImageBitmap* image_bitmap_f16_8888 = ImageBitmap::Create(
+ auto* image_bitmap_f16_8888 = MakeGarbageCollected<ImageBitmap>(
bitmap_image_f16, bitmap_image_f16->Rect(), options_f16);
ASSERT_TRUE(image_bitmap_f16_8888);
sk_sp<SkImage> sk_image_internal_f16_8888 =
@@ -665,7 +666,7 @@ TEST_F(ImageBitmapTest,
options->setColorSpaceConversion(
ColorCorrectionTestUtils::ColorSpaceConversionToString(
kColorSpaceConversion_Default));
- ImageBitmap* image_bitmap = ImageBitmap::Create(
+ 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 c301db4d89b..069a846b7cc 100644
--- a/chromium/third_party/blink/renderer/core/input/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/input/BUILD.gn
@@ -39,7 +39,14 @@ blink_core_sources("input") {
"touch_list.cc",
"touch_list.h",
]
+
+ public_deps = [ "//ui/base/cursor" ]
+
deps = [
+ "//skia",
"//third_party/blink/public:buildflags",
+ "//third_party/blink/renderer/platform",
+ "//third_party/blink/renderer/platform/wtf",
+ "//ui/base/mojom:cursor_type_blink",
]
}
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 39fa47860e4..8ada7d35b31 100644
--- a/chromium/third_party/blink/renderer/core/input/event_handler.cc
+++ b/chromium/third_party/blink/renderer/core/input/event_handler.cc
@@ -32,10 +32,10 @@
#include <utility>
#include "build/build_config.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/mojom/web_feature/web_feature.mojom-blink.h"
#include "third_party/blink/public/platform/task_type.h"
-#include "third_party/blink/public/platform/web_input_event.h"
-#include "third_party/blink/public/platform/web_mouse_wheel_event.h"
#include "third_party/blink/renderer/core/clipboard/data_transfer.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
@@ -69,6 +69,7 @@
#include "third_party/blink/renderer/core/html/html_dialog_element.h"
#include "third_party/blink/renderer/core/html/html_frame_element_base.h"
#include "third_party/blink/renderer/core/html/html_frame_set_element.h"
+#include "third_party/blink/renderer/core/html/portal/html_portal_element.h"
#include "third_party/blink/renderer/core/input/event_handling_util.h"
#include "third_party/blink/renderer/core/input/input_device_capabilities.h"
#include "third_party/blink/renderer/core/input/touch_action_util.h"
@@ -96,10 +97,12 @@
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style/cursor_data.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/cursors.h"
#include "third_party/blink/renderer/platform/geometry/float_point.h"
#include "third_party/blink/renderer/platform/geometry/int_point.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
+#include "third_party/blink/renderer/platform/graphics/image_orientation.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
@@ -107,7 +110,10 @@
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/windows_keyboard_codes.h"
#include "third_party/blink/renderer/platform/wtf/assertions.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/skia/include/core/SkBitmap.h"
+#include "ui/base/mojom/cursor_type.mojom-blink.h"
namespace blink {
@@ -149,6 +155,36 @@ bool ContainsEvenAtEdge(const IntRect& rect, const IntPoint& point) {
point.Y() >= rect.Y() && point.Y() <= rect.MaxY();
}
+IntPoint DetermineHotSpot(const Image& image,
+ bool hot_spot_specified,
+ const IntPoint& specified_hot_spot) {
+ if (image.IsNull())
+ return IntPoint();
+
+ IntRect image_rect = image.Rect();
+
+ // Hot spot must be inside cursor rectangle.
+ if (hot_spot_specified) {
+ if (image_rect.Contains(specified_hot_spot))
+ return specified_hot_spot;
+
+ return IntPoint(clampTo<int>(specified_hot_spot.X(), image_rect.X(),
+ image_rect.MaxX() - 1),
+ clampTo<int>(specified_hot_spot.Y(), image_rect.Y(),
+ image_rect.MaxY() - 1));
+ }
+
+ // If hot spot is not specified externally, it can be extracted from some
+ // image formats (e.g. .cur).
+ IntPoint intrinsic_hot_spot;
+ bool image_has_intrinsic_hot_spot = image.GetHotSpot(intrinsic_hot_spot);
+ if (image_has_intrinsic_hot_spot && image_rect.Contains(intrinsic_hot_spot))
+ return intrinsic_hot_spot;
+
+ // If neither is provided, use a default value of (0, 0).
+ return IntPoint();
+}
+
} // namespace
// The amount of time to wait for a cursor update on style and layout changes
@@ -192,7 +228,8 @@ EventHandler::EventHandler(LocalFrame& frame)
mouse_event_manager_(
MakeGarbageCollected<MouseEventManager>(frame, *scroll_manager_)),
mouse_wheel_event_manager_(
- MakeGarbageCollected<MouseWheelEventManager>(frame)),
+ MakeGarbageCollected<MouseWheelEventManager>(frame,
+ *scroll_manager_)),
keyboard_event_manager_(
MakeGarbageCollected<KeyboardEventManager>(frame, *scroll_manager_)),
pointer_event_manager_(
@@ -214,7 +251,7 @@ EventHandler::EventHandler(LocalFrame& frame)
}
}
-void EventHandler::Trace(blink::Visitor* visitor) {
+void EventHandler::Trace(Visitor* visitor) {
visitor->Trace(frame_);
visitor->Trace(selection_controller_);
visitor->Trace(capturing_mouse_events_element_);
@@ -269,20 +306,10 @@ void EventHandler::StartMiddleClickAutoscroll(LayoutObject* layout_object) {
return;
LayoutBox* scrollable = LayoutBox::FindAutoscrollable(
layout_object, /*is_middle_click_autoscroll*/ true);
- Page* page = frame_->GetPage();
- bool vertical_scroll_offset = false;
- bool horizontal_scroll_offset = false;
- if (page) {
- ScrollOffset maximum_scroll_offset =
- page->GetVisualViewport().MaximumScrollOffset();
- vertical_scroll_offset = maximum_scroll_offset.Height() > 0;
- horizontal_scroll_offset = maximum_scroll_offset.Width() > 0;
- }
controller->StartMiddleClickAutoscroll(
- layout_object->GetFrame(), LastKnownMousePositionInRootFrame(),
- mouse_event_manager_->LastKnownMouseScreenPosition(),
- scrollable->HasScrollableOverflowY() || vertical_scroll_offset,
- scrollable->HasScrollableOverflowX() || horizontal_scroll_offset);
+ layout_object->GetFrame(), scrollable,
+ LastKnownMousePositionInRootFrame(),
+ mouse_event_manager_->LastKnownMouseScreenPosition());
mouse_event_manager_->InvalidateClick();
}
@@ -374,7 +401,7 @@ void EventHandler::StopAutoscroll() {
// TODO(bokan): This should be merged with logicalScroll assuming
// defaultSpaceEventHandler's chaining scroll can be done crossing frames.
-bool EventHandler::BubblingScroll(ScrollDirection direction,
+bool EventHandler::BubblingScroll(mojom::blink::ScrollDirection direction,
ScrollGranularity granularity,
Node* starting_node) {
return scroll_manager_->BubblingScroll(
@@ -434,7 +461,7 @@ void EventHandler::UpdateCursor() {
if (!layout_view)
return;
- frame_->GetDocument()->UpdateStyleAndLayout();
+ frame_->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kInput);
HitTestRequest request(HitTestRequest::kReadOnly |
HitTestRequest::kAllowChildFrameContent);
@@ -444,10 +471,10 @@ void EventHandler::UpdateCursor() {
layout_view->HitTest(location, result);
if (LocalFrame* frame = result.InnerNodeFrame()) {
- EventHandler::OptionalCursor optional_cursor =
+ base::Optional<ui::Cursor> optional_cursor =
frame->GetEventHandler().SelectCursor(location, result);
- if (optional_cursor.IsCursorChange()) {
- view->SetCursor(optional_cursor.GetCursor());
+ if (optional_cursor.has_value()) {
+ view->SetCursor(optional_cursor.value());
}
}
}
@@ -491,17 +518,17 @@ bool EventHandler::ShouldShowIBeamForNode(const Node* node,
return HasEditableStyle(*node);
}
-EventHandler::OptionalCursor EventHandler::SelectCursor(
+base::Optional<ui::Cursor> EventHandler::SelectCursor(
const HitTestLocation& location,
const HitTestResult& result) {
if (scroll_manager_->InResizeMode())
- return kNoCursorChange;
+ return base::nullopt;
Page* page = frame_->GetPage();
if (!page)
- return kNoCursorChange;
+ return base::nullopt;
if (scroll_manager_->MiddleClickAutoscrollInProgress())
- return kNoCursorChange;
+ return base::nullopt;
if (result.GetScrollbar() && !result.GetScrollbar()->IsCustomScrollbar())
return PointerCursor();
@@ -534,14 +561,14 @@ EventHandler::OptionalCursor EventHandler::SelectCursor(
const ComputedStyle* style = layout_object ? layout_object->Style() : nullptr;
if (layout_object) {
- Cursor override_cursor;
+ ui::Cursor override_cursor;
switch (layout_object->GetCursor(result.LocalPoint(), override_cursor)) {
case kSetCursorBasedOnStyle:
break;
case kSetCursor:
return override_cursor;
case kDoNotSetCursor:
- return kNoCursorChange;
+ return base::nullopt;
}
}
@@ -590,12 +617,21 @@ EventHandler::OptionalCursor EventHandler::SelectCursor(
// Convert from logical pixels to physical pixels.
hot_spot.Scale(scale, scale);
- return Cursor(image, hot_spot_specified, hot_spot, scale);
+
+ ui::Cursor cursor(ui::mojom::blink::CursorType::kCustom);
+ cursor.set_custom_bitmap(
+ image ? image->AsSkBitmapForCurrentFrame(kRespectImageOrientation)
+ : SkBitmap());
+ cursor.set_custom_hotspot(
+ DetermineHotSpot(*image, hot_spot_specified, hot_spot));
+ cursor.set_image_scale_factor(scale);
+ return cursor;
}
}
bool horizontal_text = !style || style->IsHorizontalWritingMode();
- const Cursor& i_beam = horizontal_text ? IBeamCursor() : VerticalTextCursor();
+ const ui::Cursor& i_beam =
+ horizontal_text ? IBeamCursor() : VerticalTextCursor();
switch (style ? style->Cursor() : ECursor::kAuto) {
case ECursor::kAuto: {
@@ -675,10 +711,10 @@ EventHandler::OptionalCursor EventHandler::SelectCursor(
return PointerCursor();
}
-EventHandler::OptionalCursor EventHandler::SelectAutoCursor(
+base::Optional<ui::Cursor> EventHandler::SelectAutoCursor(
const HitTestResult& result,
Node* node,
- const Cursor& i_beam) {
+ const ui::Cursor& i_beam) {
if (ShouldShowIBeamForNode(node, result))
return i_beam;
@@ -761,7 +797,9 @@ WebInputEventResult EventHandler::HandleMousePressEvent(
return WebInputEventResult::kHandledSuppressed;
}
- LocalFrame::NotifyUserActivation(frame_, true);
+ LocalFrame::NotifyUserActivation(
+ frame_,
+ RuntimeEnabledFeatures::BrowserVerifiedUserActivationMouseEnabled());
if (RuntimeEnabledFeatures::MiddleClickAutoscrollEnabled()) {
// We store whether middle click autoscroll is in progress before calling
@@ -841,8 +879,6 @@ WebInputEventResult EventHandler::HandleMousePressEvent(
mouse_event_manager_->SetCapturesDragging(false);
}
- // Scrollbars should get events anyway, even disabled controls might be
- // scrollable.
if (PassMousePressEventToScrollbar(mev))
event_result = WebInputEventResult::kHandledSystem;
@@ -873,6 +909,7 @@ WebInputEventResult EventHandler::HandleMouseMoveEvent(
const Vector<WebMouseEvent>& coalesced_events,
const Vector<WebMouseEvent>& predicted_events) {
TRACE_EVENT0("blink", "EventHandler::handleMouseMoveEvent");
+ DCHECK(event.GetType() == WebInputEvent::kMouseMove);
HitTestResult hovered_node_result;
HitTestLocation location;
WebInputEventResult result =
@@ -907,13 +944,13 @@ WebInputEventResult EventHandler::HandleMouseMoveEvent(
void EventHandler::HandleMouseLeaveEvent(const WebMouseEvent& event) {
TRACE_EVENT0("blink", "EventHandler::handleMouseLeaveEvent");
+ DCHECK(event.GetType() == WebInputEvent::kMouseLeave);
Page* page = frame_->GetPage();
if (page)
page->GetChromeClient().ClearToolTip(*frame_);
HandleMouseMoveOrLeaveEvent(event, Vector<WebMouseEvent>(),
- Vector<WebMouseEvent>(), nullptr, nullptr, false,
- true);
+ Vector<WebMouseEvent>());
pointer_event_manager_->RemoveLastMousePosition();
}
@@ -922,17 +959,16 @@ WebInputEventResult EventHandler::HandleMouseMoveOrLeaveEvent(
const Vector<WebMouseEvent>& coalesced_events,
const Vector<WebMouseEvent>& predicted_events,
HitTestResult* hovered_node_result,
- HitTestLocation* hit_test_location,
- bool only_update_scrollbars,
- bool force_leave) {
+ HitTestLocation* hit_test_location) {
DCHECK(frame_);
DCHECK(frame_->View());
+ DCHECK(mouse_event.GetType() == WebInputEvent::kMouseMove ||
+ mouse_event.GetType() == WebInputEvent::kMouseLeave);
mouse_event_manager_->SetLastKnownMousePosition(mouse_event);
hover_timer_.Stop();
cursor_update_timer_.Stop();
- mouse_event_manager_->CancelFakeMouseMoveEvent();
mouse_event_manager_->HandleSvgPanIfNeeded(false);
// Mouse states need to be reset when mouse move with no button down.
@@ -971,31 +1007,27 @@ WebInputEventResult EventHandler::HandleMouseMoveOrLeaveEvent(
HitTestRequest::kMove | HitTestRequest::kRetargetForInert;
if (mouse_event_manager_->MousePressed()) {
hit_type |= HitTestRequest::kActive;
- } else if (only_update_scrollbars) {
- // Mouse events should be treated as "read-only" if we're updating only
- // scrollbars. This means that :hover and :active freeze in the state they
- // were in, rather than updating for nodes the mouse moves while the
- // window is not key (which will be the case if onlyUpdateScrollbars is
- // true).
- hit_type |= HitTestRequest::kReadOnly;
}
// Treat any mouse move events as readonly if the user is currently touching
// the screen.
- if (pointer_event_manager_->IsAnyTouchActive() && !force_leave)
+ if (pointer_event_manager_->IsAnyTouchActive() &&
+ mouse_event.GetType() == WebInputEvent::kMouseMove) {
hit_type |= HitTestRequest::kActive | HitTestRequest::kReadOnly;
+ }
HitTestRequest request(hit_type);
HitTestLocation out_location((PhysicalOffset()));
MouseEventWithHitTestResults mev = MouseEventWithHitTestResults(
mouse_event, out_location, HitTestResult(request, out_location));
- // We don't want to do a hit-test in forceLeave scenarios because there
+ // We don't want to do a hit-test in MouseLeave scenarios because there
// might actually be some other frame above this one at the specified
- // co-ordinate. So we must force the hit-test to fail, while still clearing
- // hover/active state.
- if (force_leave) {
+ // coordinate. So we avoid the hit test but still clear the hover/active
+ // state.
+ if (mouse_event.GetType() == WebInputEvent::kMouseLeave) {
frame_->GetDocument()->UpdateHoverActiveState(request.Active(),
- !request.Move(), nullptr);
+ /*update_active_chain=*/false,
+ nullptr);
} else {
mev = GetMouseEventTarget(request, mouse_event);
}
@@ -1011,32 +1043,35 @@ WebInputEventResult EventHandler::HandleMouseMoveOrLeaveEvent(
if (scroll_manager_->InResizeMode()) {
scroll_manager_->Resize(mev.Event());
} else {
- if (!scrollbar)
- scrollbar = mev.GetScrollbar();
+ scrollbar = mev.GetScrollbar();
UpdateLastScrollbarUnderMouse(scrollbar,
!mouse_event_manager_->MousePressed());
- if (only_update_scrollbars)
- return WebInputEventResult::kHandledSuppressed;
}
WebInputEventResult event_result = WebInputEventResult::kNotHandled;
+ bool is_portal =
+ mev.InnerElement() && IsA<HTMLPortalElement>(*mev.InnerElement());
bool is_remote_frame = false;
- LocalFrame* new_subframe = event_handling_util::GetTargetSubframe(
+ LocalFrame* current_subframe = event_handling_util::GetTargetSubframe(
mev, capturing_mouse_events_element_, &is_remote_frame);
// We want mouseouts to happen first, from the inside out. First send a
// move event to the last subframe so that it will fire mouseouts.
+ // TODO(lanwei): figure out here if we should call HandleMouseLeaveEvent on a
+ // mouse move event.
if (last_mouse_move_event_subframe_ &&
last_mouse_move_event_subframe_->Tree().IsDescendantOf(frame_) &&
- last_mouse_move_event_subframe_ != new_subframe) {
+ last_mouse_move_event_subframe_ != current_subframe) {
+ WebMouseEvent event = mev.Event();
+ event.SetType(WebInputEvent::kMouseLeave);
last_mouse_move_event_subframe_->GetEventHandler().HandleMouseLeaveEvent(
- mev.Event());
+ event);
last_mouse_move_event_subframe_->GetEventHandler()
.mouse_event_manager_->SetLastMousePositionAsUnknown();
}
- if (new_subframe) {
+ if (current_subframe) {
// Update over/out state before passing the event to the subframe.
pointer_event_manager_->SendMouseAndPointerBoundaryEvents(
EffectiveMouseEventTargetElement(mev.InnerElement()),
@@ -1045,10 +1080,10 @@ WebInputEventResult EventHandler::HandleMouseMoveOrLeaveEvent(
// Event dispatch in sendMouseAndPointerBoundaryEvents may have caused the
// subframe of the target node to be detached from its LocalFrameView, in
// which case the event should not be passed.
- if (new_subframe->View()) {
+ if (current_subframe->View()) {
event_result =
PassMouseMoveEventToSubframe(mev, coalesced_events, predicted_events,
- new_subframe, hovered_node_result);
+ current_subframe, hovered_node_result);
}
} else {
if (scrollbar && !mouse_event_manager_->MousePressed()) {
@@ -1057,16 +1092,16 @@ WebInputEventResult EventHandler::HandleMouseMoveOrLeaveEvent(
scrollbar->MouseMoved(mev.Event());
}
LocalFrameView* view = frame_->View();
- if (!is_remote_frame && view) {
- EventHandler::OptionalCursor optional_cursor =
+ if ((!is_remote_frame || is_portal) && view) {
+ base::Optional<ui::Cursor> optional_cursor =
SelectCursor(mev.GetHitTestLocation(), mev.GetHitTestResult());
- if (optional_cursor.IsCursorChange()) {
- view->SetCursor(optional_cursor.GetCursor());
+ if (optional_cursor.has_value()) {
+ view->SetCursor(optional_cursor.value());
}
}
}
- last_mouse_move_event_subframe_ = new_subframe;
+ last_mouse_move_event_subframe_ = current_subframe;
if (event_result != WebInputEventResult::kNotHandled)
return event_result;
@@ -1115,14 +1150,23 @@ WebInputEventResult EventHandler::HandleMouseReleaseEvent(
mouse_event_manager_->SetMousePositionAndDispatchMouseEvent(
EffectiveMouseEventTargetElement(frame_set_being_resized_.Get()),
String(), event_type_names::kMouseup, mouse_event);
- ReleaseMouseCaptureFromLocalRoot();
+ // crbug.com/1053385 release mouse capture only if there are no more mouse
+ // buttons depressed
+ if (MouseEvent::WebInputEventModifiersToButtons(
+ mouse_event.GetModifiers()) == 0)
+ ReleaseMouseCaptureFromLocalRoot();
return result;
}
if (last_scrollbar_under_mouse_) {
mouse_event_manager_->InvalidateClick();
last_scrollbar_under_mouse_->MouseUp(mouse_event);
- ReleaseMouseCaptureFromLocalRoot();
+ // crbug.com/1053385 release mouse capture only if there are no more mouse
+ // buttons depressed
+ if (MouseEvent::WebInputEventModifiersToButtons(
+ mouse_event.GetModifiers()) == 0) {
+ ReleaseMouseCaptureFromLocalRoot();
+ }
return DispatchMousePointerEvent(
WebInputEvent::kPointerUp, mouse_event_manager_->GetElementUnderMouse(),
String(), mouse_event, Vector<WebMouseEvent>(),
@@ -1153,23 +1197,29 @@ WebInputEventResult EventHandler::HandleMouseReleaseEvent(
(GetSelectionController().HasExtendedSelection() &&
IsSelectionOverLink(mev)));
}
-
scroll_manager_->ClearResizeScrollableArea(false);
if (event_result == WebInputEventResult::kNotHandled)
event_result = mouse_event_manager_->HandleMouseReleaseEvent(mev);
mouse_event_manager_->HandleMouseReleaseEventUpdateStates();
- ReleaseMouseCaptureFromLocalRoot();
+
+ // crbug.com/1053385 release mouse capture only if there are no more mouse
+ // buttons depressed
+ if (MouseEvent::WebInputEventModifiersToButtons(mouse_event.GetModifiers()) ==
+ 0)
+ ReleaseMouseCaptureFromLocalRoot();
+
return event_result;
}
static LocalFrame* LocalFrameFromTargetNode(Node* target) {
- if (!IsHTMLFrameElementBase(target))
+ auto* html_frame_base_element = DynamicTo<HTMLFrameElementBase>(target);
+ if (!html_frame_base_element)
return nullptr;
// Cross-process drag and drop is not yet supported.
- return DynamicTo<LocalFrame>(ToHTMLFrameElementBase(target)->ContentFrame());
+ return DynamicTo<LocalFrame>(html_frame_base_element->ContentFrame());
}
WebInputEventResult EventHandler::UpdateDragAndDrop(
@@ -1193,8 +1243,8 @@ WebInputEventResult EventHandler::UpdateDragAndDrop(
if (AutoscrollController* controller =
scroll_manager_->GetAutoscrollController()) {
- controller->UpdateDragAndDrop(new_target, event.PositionInRootFrame(),
- event.TimeStamp());
+ controller->UpdateDragAndDrop(
+ new_target, FloatPoint(event.PositionInRootFrame()), event.TimeStamp());
}
if (drag_target_ != new_target) {
@@ -1906,12 +1956,13 @@ GestureEventWithHitTestResults EventHandler::HitTestResultForGestureEvent(
LocalFrame& root_frame = frame_->LocalFrameRoot();
HitTestResult hit_test_result;
if (hit_rect_size.IsEmpty()) {
- location = HitTestLocation(adjusted_event.PositionInRootFrame());
+ location =
+ HitTestLocation(FloatPoint(adjusted_event.PositionInRootFrame()));
hit_test_result = root_frame.GetEventHandler().HitTestResultAtLocation(
location, hit_type);
} else {
PhysicalOffset top_left = PhysicalOffset::FromFloatPointRound(
- adjusted_event.PositionInRootFrame());
+ FloatPoint(adjusted_event.PositionInRootFrame()));
top_left -= PhysicalOffset(hit_rect_size * 0.5f);
location = HitTestLocation(PhysicalRect(top_left, hit_rect_size));
hit_test_result = root_frame.GetEventHandler().HitTestResultAtLocation(
@@ -1922,7 +1973,7 @@ GestureEventWithHitTestResults EventHandler::HitTestResultForGestureEvent(
// Adjust the location of the gesture to the most likely nearby node, as
// appropriate for the type of event.
ApplyTouchAdjustment(&adjusted_event, location, &hit_test_result);
- // Do a new hit-test at the (adjusted) gesture co-ordinates. This is
+ // Do a new hit-test at the (adjusted) gesture coordinates. This is
// necessary because rect-based hit testing and touch adjustment sometimes
// return a different node than what a point-based hit test would return for
// the same point.
@@ -1931,7 +1982,8 @@ GestureEventWithHitTestResults EventHandler::HitTestResultForGestureEvent(
LocalFrame* hit_frame = hit_test_result.InnerNodeFrame();
if (!hit_frame)
hit_frame = frame_;
- location = HitTestLocation(adjusted_event.PositionInRootFrame());
+ location =
+ HitTestLocation(FloatPoint(adjusted_event.PositionInRootFrame()));
hit_test_result = root_frame.GetEventHandler().HitTestResultAtLocation(
location,
(hit_type | HitTestRequest::kReadOnly) & ~HitTestRequest::kListBased);
@@ -1980,7 +2032,7 @@ void EventHandler::ApplyTouchAdjustment(WebGestureEvent* gesture_event,
DCHECK(location.IsRectBasedTest());
location = hit_test_result->ResolveRectBasedTest(adjusted_node, point);
gesture_event->ApplyTouchAdjustment(
- WebFloatPoint(adjusted_point.X(), adjusted_point.Y()));
+ gfx::PointF(adjusted_point.X(), adjusted_point.Y()));
}
}
@@ -2007,9 +2059,11 @@ WebInputEventResult EventHandler::SendContextMenuEvent(
// Since |Document::performMouseEventHitTest()| modifies layout tree for
// setting hover element, we need to update layout tree for requirement of
// |SelectionController::sendContextMenuEvent()|.
- frame_->GetDocument()->UpdateStyleAndLayout();
+ frame_->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kContextMenu);
- GetSelectionController().SendContextMenuEvent(mev, position_in_contents);
+ GetSelectionController().UpdateSelectionForContextMenuEvent(
+ mev, position_in_contents);
Element* target_element =
override_target_element ? override_target_element : mev.InnerElement();
@@ -2022,7 +2076,8 @@ WebInputEventResult EventHandler::SendContextMenuEvent(
static bool ShouldShowContextMenuAtSelection(const FrameSelection& selection) {
// TODO(editing-dev): The use of UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- selection.GetDocument().UpdateStyleAndLayout();
+ selection.GetDocument().UpdateStyleAndLayout(
+ DocumentUpdateReason::kContextMenu);
const VisibleSelection& visible_selection =
selection.ComputeVisibleSelectionInDOMTree();
@@ -2131,8 +2186,8 @@ WebInputEventResult EventHandler::ShowNonLocatedContextMenu(
WebMouseEvent mouse_event(
event_type,
- WebFloatPoint(location_in_root_frame.X(), location_in_root_frame.Y()),
- WebFloatPoint(global_position.X(), global_position.Y()),
+ gfx::PointF(location_in_root_frame.X(), location_in_root_frame.Y()),
+ gfx::PointF(global_position.X(), global_position.Y()),
WebPointerProperties::Button::kNoButton, /* clickCount */ 0,
WebInputEvent::kNoModifiers, base::TimeTicks::Now(), source_type);
@@ -2164,26 +2219,6 @@ bool EventHandler::CursorUpdatePending() {
return cursor_update_timer_.IsActive();
}
-bool EventHandler::FakeMouseMovePending() const {
- return mouse_event_manager_->FakeMouseMovePending();
-}
-
-void EventHandler::MayUpdateHoverWhenContentUnderMouseChanged(
- MouseEventManager::UpdateHoverReason update_hover_reason) {
- if (update_hover_reason ==
- MouseEventManager::UpdateHoverReason::kScrollOffsetChanged &&
- RuntimeEnabledFeatures::UpdateHoverAtBeginFrameEnabled()) {
- return;
- }
- mouse_event_manager_->MayUpdateHoverWhenContentUnderMouseChanged(
- update_hover_reason);
-}
-
-void EventHandler::MayUpdateHoverAfterScroll(
- const FloatRect& scroller_rect_in_frame) {
- mouse_event_manager_->MayUpdateHoverAfterScroll(scroller_rect_in_frame);
-}
-
void EventHandler::SetResizingFrameSet(HTMLFrameSetElement* frame_set) {
CaptureMouseEventsToWidget(true);
frame_set_being_resized_ = frame_set;
@@ -2289,9 +2324,9 @@ bool EventHandler::HandleTextInputEvent(const String& text,
// Platforms should differentiate real commands like selectAll from text input
// in disguise (like insertNewline), and avoid dispatching text input events
// from keydown default handlers.
- DCHECK(!underlying_event || !underlying_event->IsKeyboardEvent() ||
- ToKeyboardEvent(underlying_event)->type() ==
- event_type_names::kKeypress);
+ auto* keyboard_event = DynamicTo<KeyboardEvent>(underlying_event);
+ DCHECK(!keyboard_event ||
+ keyboard_event->type() == event_type_names::kKeypress);
if (!frame_)
return false;
@@ -2413,7 +2448,7 @@ MouseEventWithHitTestResults EventHandler::GetMouseEventTarget(
const WebMouseEvent& event) {
PhysicalOffset document_point =
event_handling_util::ContentPointFromRootFrame(
- frame_, event.PositionInRootFrame());
+ frame_, FloatPoint(event.PositionInRootFrame()));
// TODO(eirage): This does not handle chorded buttons yet.
if (RuntimeEnabledFeatures::UnifiedPointerCaptureInBlinkEnabled() &&
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 7ff1f80b314..887ec3f9f9c 100644
--- a/chromium/third_party/blink/renderer/core/input/event_handler.h
+++ b/chromium/third_party/blink/renderer/core/input/event_handler.h
@@ -29,9 +29,10 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/optional.h"
-#include "third_party/blink/public/platform/web_input_event.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
+#include "third_party/blink/public/common/input/web_menu_source_type.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
#include "third_party/blink/public/platform/web_input_event_result.h"
-#include "third_party/blink/public/platform/web_menu_source_type.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/events/text_event_input_type.h"
#include "third_party/blink/renderer/core/input/fallback_cursor_event_manager.h"
@@ -46,13 +47,13 @@
#include "third_party/blink/renderer/core/page/event_with_hit_test_results.h"
#include "third_party/blink/renderer/core/scroll/scroll_types.h"
#include "third_party/blink/renderer/core/style/computed_style_constants.h"
-#include "third_party/blink/renderer/platform/cursor.h"
#include "third_party/blink/renderer/platform/geometry/layout_point.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/forward.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/hash_traits.h"
+#include "ui/base/cursor/cursor.h"
namespace blink {
@@ -80,7 +81,7 @@ class WebMouseWheelEvent;
class CORE_EXPORT EventHandler final : public GarbageCollected<EventHandler> {
public:
explicit EventHandler(LocalFrame&);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
void Clear();
@@ -94,10 +95,6 @@ class CORE_EXPORT EventHandler final : public GarbageCollected<EventHandler> {
void StopAutoscroll();
- void MayUpdateHoverWhenContentUnderMouseChanged(
- MouseEventManager::UpdateHoverReason);
- void MayUpdateHoverAfterScroll(const FloatRect&);
-
HitTestResult HitTestResultAtLocation(
const HitTestLocation&,
HitTestRequest::HitTestRequestType hit_type =
@@ -124,10 +121,6 @@ class CORE_EXPORT EventHandler final : public GarbageCollected<EventHandler> {
// testing.
bool CursorUpdatePending();
- // Return whether sending a fake mouse move is currently pending. Used for
- // testing.
- bool FakeMouseMovePending() const;
-
void SetResizingFrameSet(HTMLFrameSetElement*);
void ResizeScrollableAreaDestroyed();
@@ -139,7 +132,7 @@ class CORE_EXPORT EventHandler final : public GarbageCollected<EventHandler> {
// Performs a logical scroll that chains, crossing frames, starting from
// the given node or a reasonable default (focus/last clicked).
- bool BubblingScroll(ScrollDirection,
+ bool BubblingScroll(mojom::blink::ScrollDirection,
ScrollGranularity,
Node* starting_node = nullptr);
@@ -251,23 +244,6 @@ class CORE_EXPORT EventHandler final : public GarbageCollected<EventHandler> {
return *selection_controller_;
}
- // FIXME(nzolghadr): This function is technically a private function of
- // EventHandler class. Making it public temporary to make it possible to
- // move some code around in the refactoring process.
- // Performs a chaining logical scroll, within a *single* frame, starting
- // from either a provided starting node or a default based on the focused or
- // most recently clicked node, falling back to the frame.
- // Returns true if the scroll was consumed.
- // direction - The logical direction to scroll in. This will be converted to
- // a physical direction for each LayoutBox we try to scroll
- // based on that box's writing mode.
- // granularity - The units that the scroll delta parameter is in.
- // startNode - Optional. If provided, start chaining from the given node.
- // If not, use the current focus or last clicked node.
- bool LogicalScroll(ScrollDirection,
- ScrollGranularity,
- Node* start_node = nullptr);
-
bool IsPointerIdActiveOnFrame(PointerId, LocalFrame*) const;
LocalFrame* DetermineActivePointerTrackerFrame(PointerId pointer_id) const;
@@ -295,35 +271,12 @@ class CORE_EXPORT EventHandler final : public GarbageCollected<EventHandler> {
bool LongTapShouldInvokeContextMenu();
private:
- enum NoCursorChangeType { kNoCursorChange };
-
- class OptionalCursor {
- STACK_ALLOCATED();
-
- public:
- OptionalCursor(NoCursorChangeType) : is_cursor_change_(false) {}
- OptionalCursor(const Cursor& cursor)
- : is_cursor_change_(true), cursor_(cursor) {}
-
- bool IsCursorChange() const { return is_cursor_change_; }
- const Cursor& GetCursor() const {
- DCHECK(is_cursor_change_);
- return cursor_;
- }
-
- private:
- bool is_cursor_change_;
- Cursor cursor_;
- };
-
WebInputEventResult HandleMouseMoveOrLeaveEvent(
const WebMouseEvent&,
const Vector<WebMouseEvent>& coalesced_events,
const Vector<WebMouseEvent>& predicted_events,
HitTestResult* hovered_node = nullptr,
- HitTestLocation* hit_test_location = nullptr,
- bool only_update_scrollbars = false,
- bool force_leave = false);
+ HitTestLocation* hit_test_location = nullptr);
// Updates the event, location and result to the adjusted target.
void ApplyTouchAdjustment(WebGestureEvent*, HitTestLocation&, HitTestResult*);
@@ -340,11 +293,11 @@ class CORE_EXPORT EventHandler final : public GarbageCollected<EventHandler> {
bool IsSelectingLink(const HitTestResult&);
bool ShouldShowIBeamForNode(const Node*, const HitTestResult&);
bool ShouldShowResizeForNode(const Node*, const HitTestLocation&);
- OptionalCursor SelectCursor(const HitTestLocation& location,
- const HitTestResult&);
- OptionalCursor SelectAutoCursor(const HitTestResult&,
- Node*,
- const Cursor& i_beam);
+ base::Optional<ui::Cursor> SelectCursor(const HitTestLocation& location,
+ const HitTestResult&);
+ base::Optional<ui::Cursor> SelectAutoCursor(const HitTestResult&,
+ Node*,
+ const ui::Cursor& i_beam);
void HoverTimerFired(TimerBase*);
void CursorUpdateTimerFired(TimerBase*);
@@ -388,7 +341,7 @@ class CORE_EXPORT EventHandler final : public GarbageCollected<EventHandler> {
void DefaultBackspaceEventHandler(KeyboardEvent*);
void DefaultTabEventHandler(KeyboardEvent*);
void DefaultEscapeEventHandler(KeyboardEvent*);
- void DefaultArrowEventHandler(WebFocusType, KeyboardEvent*);
+ void DefaultArrowEventHandler(mojom::blink::FocusType, KeyboardEvent*);
// |last_scrollbar_under_mouse_| is set when the mouse moves off of a
// scrollbar, and used to notify it of MouseUp events to release mouse
@@ -417,6 +370,7 @@ class CORE_EXPORT EventHandler final : public GarbageCollected<EventHandler> {
const Member<SelectionController> selection_controller_;
+ // TODO(lanwei): Remove the below timers for updating hover and cursor.
TaskRunnerTimer<EventHandler> hover_timer_;
// TODO(rbyers): Mouse cursor update is page-wide, not per-frame. Page-wide
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 33a82dce2dd..cca36d91ef5 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
@@ -6,12 +6,14 @@
#include <memory>
+#include "base/optional.h"
#include "base/test/bind_test_util.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/web_keyboard_event.h"
+#include "third_party/blink/public/common/input/web_keyboard_event.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.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/dom_selection.h"
@@ -45,6 +47,8 @@
#include "third_party/blink/renderer/platform/keyboard_codes.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 "ui/base/cursor/cursor.h"
+#include "ui/base/mojom/cursor_type.mojom-blink.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/dom/dom_key.h"
@@ -60,8 +64,8 @@ class EventHandlerTest : public PageTestBase {
class EventHandlerSimTest : public SimTest {
public:
void InitializeMousePositionAndActivateView(float x, float y) {
- WebMouseEvent mouse_move_event(WebMouseEvent::kMouseMove,
- WebFloatPoint(x, y), WebFloatPoint(x, y),
+ WebMouseEvent mouse_move_event(WebMouseEvent::kMouseMove, gfx::PointF(x, y),
+ gfx::PointF(x, y),
WebPointerProperties::Button::kNoButton, 0,
WebInputEvent::Modifiers::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests());
@@ -187,8 +191,7 @@ void EventHandlerTest::SetUp() {
}
void EventHandlerTest::SetHtmlInnerHTML(const char* html_content) {
- GetDocument().documentElement()->SetInnerHTMLFromString(
- String::FromUTF8(html_content));
+ GetDocument().documentElement()->setInnerHTML(String::FromUTF8(html_content));
UpdateAllLifecyclePhasesForTest();
}
@@ -216,11 +219,11 @@ TEST_F(EventHandlerTest, dragSelectionAfterScroll) {
"</div>");
LocalFrameView* frame_view = GetDocument().View();
- frame_view->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 400),
- kProgrammaticScroll);
+ frame_view->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 400), mojom::blink::ScrollType::kProgrammatic);
- WebMouseEvent mouse_down_event(WebInputEvent::kMouseDown, WebFloatPoint(0, 0),
- WebFloatPoint(100, 200),
+ WebMouseEvent mouse_down_event(WebInputEvent::kMouseDown, gfx::PointF(0, 0),
+ gfx::PointF(100, 200),
WebPointerProperties::Button::kLeft, 1,
WebInputEvent::Modifiers::kLeftButtonDown,
WebInputEvent::GetStaticTimeStampForTests());
@@ -234,11 +237,11 @@ TEST_F(EventHandlerTest, dragSelectionAfterScroll) {
.GetSelectionController()
.MouseDownMayStartSelect());
- WebMouseEvent mouse_move_event(
- WebInputEvent::kMouseMove, WebFloatPoint(100, 50),
- WebFloatPoint(200, 250), WebPointerProperties::Button::kLeft, 1,
- WebInputEvent::Modifiers::kLeftButtonDown,
- WebInputEvent::GetStaticTimeStampForTests());
+ WebMouseEvent mouse_move_event(WebInputEvent::kMouseMove,
+ gfx::PointF(100, 50), gfx::PointF(200, 250),
+ WebPointerProperties::Button::kLeft, 1,
+ WebInputEvent::Modifiers::kLeftButtonDown,
+ WebInputEvent::GetStaticTimeStampForTests());
mouse_move_event.SetFrameScale(1);
GetDocument().GetFrame()->GetEventHandler().HandleMouseMoveEvent(
mouse_move_event, Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
@@ -247,7 +250,7 @@ TEST_F(EventHandlerTest, dragSelectionAfterScroll) {
GetPage().Animator().ServiceScriptedAnimations(base::TimeTicks::Now());
WebMouseEvent mouse_up_event(
- WebMouseEvent::kMouseUp, WebFloatPoint(100, 50), WebFloatPoint(200, 250),
+ WebMouseEvent::kMouseUp, gfx::PointF(100, 50), gfx::PointF(200, 250),
WebPointerProperties::Button::kLeft, 1, WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests());
mouse_up_event.SetFrameScale(1);
@@ -349,7 +352,7 @@ TEST_F(EventHandlerTest, draggedInlinePositionTest) {
"<span class='line' draggable='true'>abcd</span>"
"</div>");
WebMouseEvent mouse_down_event(WebMouseEvent::kMouseDown,
- WebFloatPoint(262, 29), WebFloatPoint(329, 67),
+ gfx::PointF(262, 29), gfx::PointF(329, 67),
WebPointerProperties::Button::kLeft, 1,
WebInputEvent::Modifiers::kLeftButtonDown,
WebInputEvent::GetStaticTimeStampForTests());
@@ -357,11 +360,11 @@ TEST_F(EventHandlerTest, draggedInlinePositionTest) {
GetDocument().GetFrame()->GetEventHandler().HandleMousePressEvent(
mouse_down_event);
- WebMouseEvent mouse_move_event(
- WebMouseEvent::kMouseMove, WebFloatPoint(618, 298),
- WebFloatPoint(685, 436), WebPointerProperties::Button::kLeft, 1,
- WebInputEvent::Modifiers::kLeftButtonDown,
- WebInputEvent::GetStaticTimeStampForTests());
+ WebMouseEvent mouse_move_event(WebMouseEvent::kMouseMove,
+ gfx::PointF(618, 298), gfx::PointF(685, 436),
+ WebPointerProperties::Button::kLeft, 1,
+ WebInputEvent::Modifiers::kLeftButtonDown,
+ WebInputEvent::GetStaticTimeStampForTests());
mouse_move_event.SetFrameScale(1);
GetDocument().GetFrame()->GetEventHandler().HandleMouseMoveEvent(
mouse_move_event, Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
@@ -386,20 +389,20 @@ TEST_F(EventHandlerTest, draggedSVGImagePositionTest) {
"draggable='true'/>"
"</svg>"
"</div>");
- WebMouseEvent mouse_down_event(
- WebMouseEvent::kMouseDown, WebFloatPoint(145, 144),
- WebFloatPoint(212, 282), WebPointerProperties::Button::kLeft, 1,
- WebInputEvent::Modifiers::kLeftButtonDown,
- WebInputEvent::GetStaticTimeStampForTests());
+ WebMouseEvent mouse_down_event(WebMouseEvent::kMouseDown,
+ gfx::PointF(145, 144), gfx::PointF(212, 282),
+ WebPointerProperties::Button::kLeft, 1,
+ WebInputEvent::Modifiers::kLeftButtonDown,
+ WebInputEvent::GetStaticTimeStampForTests());
mouse_down_event.SetFrameScale(1);
GetDocument().GetFrame()->GetEventHandler().HandleMousePressEvent(
mouse_down_event);
- WebMouseEvent mouse_move_event(
- WebMouseEvent::kMouseMove, WebFloatPoint(618, 298),
- WebFloatPoint(685, 436), WebPointerProperties::Button::kLeft, 1,
- WebInputEvent::Modifiers::kLeftButtonDown,
- WebInputEvent::GetStaticTimeStampForTests());
+ WebMouseEvent mouse_move_event(WebMouseEvent::kMouseMove,
+ gfx::PointF(618, 298), gfx::PointF(685, 436),
+ WebPointerProperties::Button::kLeft, 1,
+ WebInputEvent::Modifiers::kLeftButtonDown,
+ WebInputEvent::GetStaticTimeStampForTests());
mouse_move_event.SetFrameScale(1);
GetDocument().GetFrame()->GetEventHandler().HandleMouseMoveEvent(
mouse_move_event, Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
@@ -624,9 +627,10 @@ TEST_F(EventHandlerTest, AnchorTextCannotStartSelection) {
.GetFrame()
->GetEventHandler()
.SelectCursor(location, result)
- .GetCursor()
- .GetType(),
- ui::CursorType::kHand); // A hand signals ability to navigate.
+ .value()
+ .type(),
+ ui::mojom::blink::CursorType::kHand); // A hand signals ability to
+ // navigate.
}
TEST_F(EventHandlerTest, EditableAnchorTextCanStartSelection) {
@@ -643,13 +647,14 @@ TEST_F(EventHandlerTest, EditableAnchorTextCanStartSelection) {
EXPECT_TRUE(
GetDocument().GetFrame()->GetEventHandler().ShouldShowIBeamForNode(
text, result));
- EXPECT_EQ(GetDocument()
- .GetFrame()
- ->GetEventHandler()
- .SelectCursor(location, result)
- .GetCursor()
- .GetType(),
- ui::CursorType::kIBeam); // An I-beam signals editability.
+ EXPECT_EQ(
+ GetDocument()
+ .GetFrame()
+ ->GetEventHandler()
+ .SelectCursor(location, result)
+ .value()
+ .type(),
+ ui::mojom::blink::CursorType::kIBeam); // An I-beam signals editability.
}
TEST_F(EventHandlerTest, CursorForVerticalResizableTextArea) {
@@ -666,10 +671,10 @@ TEST_F(EventHandlerTest, CursorForVerticalResizableTextArea) {
.GetFrame()
->GetEventHandler()
.SelectCursor(location, result)
- .GetCursor()
- .GetType(),
+ .value()
+ .type(),
// A north-south resize signals vertical resizability.
- ui::CursorType::kNorthSouthResize);
+ ui::mojom::blink::CursorType::kNorthSouthResize);
}
TEST_F(EventHandlerTest, CursorForHorizontalResizableTextArea) {
@@ -686,10 +691,10 @@ TEST_F(EventHandlerTest, CursorForHorizontalResizableTextArea) {
.GetFrame()
->GetEventHandler()
.SelectCursor(location, result)
- .GetCursor()
- .GetType(),
+ .value()
+ .type(),
// An east-west resize signals horizontal resizability.
- ui::CursorType::kEastWestResize);
+ ui::mojom::blink::CursorType::kEastWestResize);
}
TEST_F(EventHandlerTest, CursorForResizableTextArea) {
@@ -706,11 +711,11 @@ TEST_F(EventHandlerTest, CursorForResizableTextArea) {
.GetFrame()
->GetEventHandler()
.SelectCursor(location, result)
- .GetCursor()
- .GetType(),
+ .value()
+ .type(),
// An south-east resize signals both horizontal and
// vertical resizability.
- ui::CursorType::kSouthEastResize);
+ ui::mojom::blink::CursorType::kSouthEastResize);
}
TEST_F(EventHandlerTest, CursorForRtlResizableTextArea) {
@@ -728,11 +733,11 @@ TEST_F(EventHandlerTest, CursorForRtlResizableTextArea) {
.GetFrame()
->GetEventHandler()
.SelectCursor(location, result)
- .GetCursor()
- .GetType(),
+ .value()
+ .type(),
// An south-west resize signals both horizontal and
// vertical resizability when direction is RTL.
- ui::CursorType::kSouthWestResize);
+ ui::mojom::blink::CursorType::kSouthWestResize);
}
TEST_F(EventHandlerTest, CursorForInlineVerticalWritingMode) {
@@ -752,9 +757,9 @@ TEST_F(EventHandlerTest, CursorForInlineVerticalWritingMode) {
.GetFrame()
->GetEventHandler()
.SelectCursor(location, result)
- .GetCursor()
- .GetType(),
- ui::CursorType::kSouthEastResize);
+ .value()
+ .type(),
+ ui::mojom::blink::CursorType::kSouthEastResize);
}
TEST_F(EventHandlerTest, CursorForBlockVerticalWritingMode) {
@@ -774,9 +779,9 @@ TEST_F(EventHandlerTest, CursorForBlockVerticalWritingMode) {
.GetFrame()
->GetEventHandler()
.SelectCursor(location, result)
- .GetCursor()
- .GetType(),
- ui::CursorType::kSouthEastResize);
+ .value()
+ .type(),
+ ui::mojom::blink::CursorType::kSouthEastResize);
}
TEST_F(EventHandlerTest, implicitSend) {
@@ -803,17 +808,17 @@ TEST_F(EventHandlerTest, sendContextMenuEventWithHover) {
"<div>foo</div>");
GetDocument().GetSettings()->SetScriptEnabled(true);
Element* script = GetDocument().CreateRawElement(html_names::kScriptTag);
- script->SetInnerHTMLFromString(
+ script->setInnerHTML(
"document.addEventListener('contextmenu', event => "
"event.preventDefault());");
GetDocument().body()->AppendChild(script);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
SelectionInDOMTree::Builder()
.Collapse(Position(GetDocument().body(), 0))
.Build());
WebMouseEvent mouse_down_event(
- WebMouseEvent::kMouseDown, WebFloatPoint(0, 0), WebFloatPoint(100, 200),
+ WebMouseEvent::kMouseDown, gfx::PointF(0, 0), gfx::PointF(100, 200),
WebPointerProperties::Button::kRight, 1,
WebInputEvent::Modifiers::kRightButtonDown, base::TimeTicks::Now());
mouse_down_event.SetFrameScale(1);
@@ -970,7 +975,7 @@ TEST_F(EventHandlerTest, dragEndInNewDrag) {
"<a class='box' href=''>Drag me</a>");
WebMouseEvent mouse_down_event(
- WebInputEvent::kMouseDown, WebFloatPoint(50, 50), WebFloatPoint(50, 50),
+ WebInputEvent::kMouseDown, gfx::PointF(50, 50), gfx::PointF(50, 50),
WebPointerProperties::Button::kLeft, 1,
WebInputEvent::Modifiers::kLeftButtonDown, base::TimeTicks::Now());
mouse_down_event.SetFrameScale(1);
@@ -978,7 +983,7 @@ TEST_F(EventHandlerTest, dragEndInNewDrag) {
mouse_down_event);
WebMouseEvent mouse_move_event(
- WebInputEvent::kMouseMove, WebFloatPoint(51, 50), WebFloatPoint(51, 50),
+ WebInputEvent::kMouseMove, gfx::PointF(51, 50), gfx::PointF(51, 50),
WebPointerProperties::Button::kLeft, 1,
WebInputEvent::Modifiers::kLeftButtonDown, base::TimeTicks::Now());
mouse_move_event.SetFrameScale(1);
@@ -992,7 +997,7 @@ TEST_F(EventHandlerTest, dragEndInNewDrag) {
// dragSourceEndedAt() call could occur before a drag operation is started.
WebMouseEvent mouse_up_event(
- WebInputEvent::kMouseUp, WebFloatPoint(100, 50), WebFloatPoint(200, 250),
+ WebInputEvent::kMouseUp, gfx::PointF(100, 50), gfx::PointF(200, 250),
WebPointerProperties::Button::kLeft, 1, WebInputEvent::kNoModifiers,
base::TimeTicks::Now());
mouse_up_event.SetFrameScale(1);
@@ -1015,7 +1020,7 @@ TEST_F(EventHandlerTest, FakeMouseMoveNotStartDrag) {
"<span class='line' draggable='true'>abcd</span>"
"</div>");
WebMouseEvent mouse_down_event(WebMouseEvent::kMouseDown,
- WebFloatPoint(262, 29), WebFloatPoint(329, 67),
+ gfx::PointF(262, 29), gfx::PointF(329, 67),
WebPointerProperties::Button::kLeft, 1,
WebInputEvent::Modifiers::kLeftButtonDown,
WebInputEvent::GetStaticTimeStampForTests());
@@ -1024,8 +1029,8 @@ TEST_F(EventHandlerTest, FakeMouseMoveNotStartDrag) {
mouse_down_event);
WebMouseEvent fake_mouse_move(
- WebMouseEvent::kMouseMove, WebFloatPoint(618, 298),
- WebFloatPoint(685, 436), WebPointerProperties::Button::kLeft, 1,
+ WebMouseEvent::kMouseMove, gfx::PointF(618, 298), gfx::PointF(685, 436),
+ WebPointerProperties::Button::kLeft, 1,
WebInputEvent::Modifiers::kLeftButtonDown |
WebInputEvent::Modifiers::kRelativeMotionEvent,
WebInputEvent::GetStaticTimeStampForTests());
@@ -1082,7 +1087,7 @@ TEST_F(EventHandlerTooltipTest, mouseLeaveClearsTooltip) {
EXPECT_EQ(WTF::String(), LastToolTip());
WebMouseEvent mouse_move_event(
- WebInputEvent::kMouseMove, WebFloatPoint(51, 50), WebFloatPoint(51, 50),
+ WebInputEvent::kMouseMove, gfx::PointF(51, 50), gfx::PointF(51, 50),
WebPointerProperties::Button::kNoButton, 0, WebInputEvent::kNoModifiers,
base::TimeTicks::Now());
mouse_move_event.SetFrameScale(1);
@@ -1092,7 +1097,7 @@ TEST_F(EventHandlerTooltipTest, mouseLeaveClearsTooltip) {
EXPECT_EQ("tooltip", LastToolTip());
WebMouseEvent mouse_leave_event(
- WebInputEvent::kMouseLeave, WebFloatPoint(0, 0), WebFloatPoint(0, 0),
+ WebInputEvent::kMouseLeave, gfx::PointF(0, 0), gfx::PointF(0, 0),
WebPointerProperties::Button::kNoButton, 0, WebInputEvent::kNoModifiers,
base::TimeTicks::Now());
mouse_leave_event.SetFrameScale(1);
@@ -1132,7 +1137,7 @@ class EventHandlerLatencyTest : public PageTestBase {
}
void SetHtmlInnerHTML(const char* html_content) {
- GetDocument().documentElement()->SetInnerHTMLFromString(
+ GetDocument().documentElement()->setInnerHTML(
String::FromUTF8(html_content));
UpdateAllLifecyclePhasesForTest();
}
@@ -1151,7 +1156,7 @@ TEST_F(EventHandlerLatencyTest, NeedsUnbufferedInput) {
ASSERT_FALSE(chrome_client_->ReceivedRequestForUnbufferedInput());
WebMouseEvent mouse_press_event(
- WebInputEvent::kMouseDown, WebFloatPoint(51, 50), WebFloatPoint(51, 50),
+ WebInputEvent::kMouseDown, gfx::PointF(51, 50), gfx::PointF(51, 50),
WebPointerProperties::Button::kLeft, 0, WebInputEvent::kNoModifiers,
base::TimeTicks::Now());
mouse_press_event.SetFrameScale(1);
@@ -1194,7 +1199,7 @@ TEST_F(EventHandlerSimTest, MouseUpOffScrollbarGeneratesScrollEnd) {
bool scrollbar_theme_allows_hit_test =
GetDocument().GetPage()->GetScrollbarTheme().AllowsHitTest();
- const WebFloatPoint scrollbar_forward_track(795, 560);
+ const gfx::PointF scrollbar_forward_track(795, 560);
WebMouseEvent mouse_down(WebInputEvent::kMouseDown, scrollbar_forward_track,
scrollbar_forward_track,
WebPointerProperties::Button::kLeft, 0,
@@ -1213,7 +1218,7 @@ TEST_F(EventHandlerSimTest, MouseUpOffScrollbarGeneratesScrollEnd) {
EXPECT_EQ(WebWidgetClient().GetInjectedScrollGestureData().size(), 0u);
}
- const WebFloatPoint middle_of_page(100, 100);
+ const gfx::PointF middle_of_page(100, 100);
WebMouseEvent mouse_move(WebInputEvent::kMouseMove, middle_of_page,
middle_of_page, WebPointerProperties::Button::kLeft,
0, WebInputEvent::kNoModifiers,
@@ -1263,7 +1268,7 @@ TEST_F(EventHandlerSimTest, MouseUpOnlyOnScrollbar) {
// Validate that we don't inject a ScrollEnd (since no ScrollBegin was
// injected).
- const WebFloatPoint middle_of_page(100, 100);
+ const gfx::PointF middle_of_page(100, 100);
WebMouseEvent mouse_down(WebInputEvent::kMouseDown, middle_of_page,
middle_of_page, WebPointerProperties::Button::kLeft,
0, WebInputEvent::kNoModifiers,
@@ -1274,7 +1279,7 @@ TEST_F(EventHandlerSimTest, MouseUpOnlyOnScrollbar) {
// Mouse down on the page should not generate scroll gestures.
EXPECT_EQ(WebWidgetClient().GetInjectedScrollGestureData().size(), 0u);
- const WebFloatPoint scrollbar_forward_track(795, 560);
+ const gfx::PointF scrollbar_forward_track(795, 560);
WebMouseEvent mouse_move(WebInputEvent::kMouseMove, scrollbar_forward_track,
scrollbar_forward_track,
WebPointerProperties::Button::kLeft, 0,
@@ -1315,7 +1320,7 @@ TEST_F(EventHandlerSimTest, RightClickNoGestures) {
// track, and release the mouse and verify that no gesture events are
// queued up (right click doesn't scroll scrollbars).
- const WebFloatPoint scrollbar_forward_track(795, 560);
+ const gfx::PointF scrollbar_forward_track(795, 560);
WebMouseEvent mouse_down(WebInputEvent::kMouseDown, scrollbar_forward_track,
scrollbar_forward_track,
WebPointerProperties::Button::kRight, 0,
@@ -1393,7 +1398,7 @@ TEST_F(EventHandlerSimTest, MAYBE_GestureTapWithScrollSnaps) {
// kGestureTapDown sets the pressed parts which is a pre-requisite for
// kGestureTap performing a scroll.
- const WebFloatPoint scrollbar_forward_track(495, 450);
+ const FloatPoint scrollbar_forward_track(495, 450);
TapDownEventBuilder tap_down(scrollbar_forward_track);
GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(tap_down);
@@ -1416,8 +1421,8 @@ TEST_F(EventHandlerSimTest, MAYBE_GestureTapWithScrollSnaps) {
WebInputEvent::GetStaticTimeStampForTests()};
gsb.SetFrameScale(1);
gsb.SetSourceDevice(WebGestureDevice::kScrollbar);
- gsb.data.scroll_begin.delta_x_hint = -gsb_data.delta.width;
- gsb.data.scroll_begin.delta_y_hint = -gsb_data.delta.height;
+ 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();
GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(gsb);
@@ -1426,8 +1431,8 @@ TEST_F(EventHandlerSimTest, MAYBE_GestureTapWithScrollSnaps) {
WebInputEvent::GetStaticTimeStampForTests()};
gsu.SetSourceDevice(WebGestureDevice::kScrollbar);
gsu.SetFrameScale(1);
- gsu.data.scroll_update.delta_x = -gsu_data.delta.width;
- gsu.data.scroll_update.delta_y = -gsu_data.delta.height;
+ 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::kGestureScrollEnd,
@@ -1467,7 +1472,7 @@ TEST_F(EventHandlerSimTest, MAYBE_GestureTapWithScrollSnaps) {
TEST_F(EventHandlerTest, MouseLeaveResetsUnknownState) {
SetHtmlInnerHTML("<div></div>");
WebMouseEvent mouse_down_event(WebMouseEvent::kMouseDown,
- WebFloatPoint(262, 29), WebFloatPoint(329, 67),
+ gfx::PointF(262, 29), gfx::PointF(329, 67),
WebPointerProperties::Button::kLeft, 1,
WebInputEvent::Modifiers::kLeftButtonDown,
WebInputEvent::GetStaticTimeStampForTests());
@@ -1477,11 +1482,11 @@ TEST_F(EventHandlerTest, MouseLeaveResetsUnknownState) {
EXPECT_FALSE(
GetDocument().GetFrame()->GetEventHandler().IsMousePositionUnknown());
- WebMouseEvent mouse_leave_event(
- WebMouseEvent::kMouseLeave, WebFloatPoint(262, 29),
- WebFloatPoint(329, 67), WebPointerProperties::Button::kNoButton, 1,
- WebInputEvent::Modifiers::kNoModifiers,
- WebInputEvent::GetStaticTimeStampForTests());
+ WebMouseEvent mouse_leave_event(WebMouseEvent::kMouseLeave,
+ gfx::PointF(262, 29), gfx::PointF(329, 67),
+ WebPointerProperties::Button::kNoButton, 1,
+ WebInputEvent::Modifiers::kNoModifiers,
+ WebInputEvent::GetStaticTimeStampForTests());
mouse_leave_event.SetFrameScale(1);
GetDocument().GetFrame()->GetEventHandler().HandleMouseLeaveEvent(
mouse_leave_event);
@@ -1518,8 +1523,8 @@ TEST_F(EventHandlerSimTest, MouseLeaveIFrameResets) {
frame_resource.Complete("<!DOCTYPE html>");
Compositor().BeginFrame();
WebMouseEvent mouse_move_inside_event(
- WebMouseEvent::kMouseMove, WebFloatPoint(100, 229),
- WebFloatPoint(100, 229), WebPointerProperties::Button::kNoButton, 0,
+ WebMouseEvent::kMouseMove, gfx::PointF(100, 229), gfx::PointF(100, 229),
+ WebPointerProperties::Button::kNoButton, 0,
WebInputEvent::Modifiers::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests());
mouse_move_inside_event.SetFrameScale(1);
@@ -1530,14 +1535,15 @@ TEST_F(EventHandlerSimTest, MouseLeaveIFrameResets) {
GetDocument().GetFrame()->GetEventHandler().IsMousePositionUnknown());
auto* child_frame =
To<HTMLIFrameElement>(GetDocument().getElementById("frame"));
- child_frame->contentDocument()->UpdateStyleAndLayout();
+ child_frame->contentDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(GetDocument().GetFrame()->Tree().FirstChild());
EXPECT_FALSE(To<LocalFrame>(GetDocument().GetFrame()->Tree().FirstChild())
->GetEventHandler()
.IsMousePositionUnknown());
WebMouseEvent mouse_move_outside_event(
- WebMouseEvent::kMouseMove, WebFloatPoint(300, 29), WebFloatPoint(300, 29),
+ WebMouseEvent::kMouseMove, gfx::PointF(300, 29), gfx::PointF(300, 29),
WebPointerProperties::Button::kNoButton, 0,
WebInputEvent::Modifiers::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests());
@@ -1573,7 +1579,7 @@ TEST_F(EventHandlerSimTest, CursorStyleBeforeStartDragging) {
Compositor().BeginFrame();
WebMouseEvent mouse_down_event(WebMouseEvent::kMouseDown,
- WebFloatPoint(150, 50), WebFloatPoint(150, 50),
+ gfx::PointF(150, 50), gfx::PointF(150, 50),
WebPointerProperties::Button::kLeft, 1,
WebInputEvent::Modifiers::kLeftButtonDown,
WebInputEvent::GetStaticTimeStampForTests());
@@ -1582,18 +1588,18 @@ TEST_F(EventHandlerSimTest, CursorStyleBeforeStartDragging) {
mouse_down_event);
WebMouseEvent mouse_move_event(WebMouseEvent::kMouseMove,
- WebFloatPoint(151, 50), WebFloatPoint(151, 50),
+ gfx::PointF(151, 50), gfx::PointF(151, 50),
WebPointerProperties::Button::kLeft, 1,
WebInputEvent::Modifiers::kLeftButtonDown,
WebInputEvent::GetStaticTimeStampForTests());
mouse_move_event.SetFrameScale(1);
GetDocument().GetFrame()->GetEventHandler().HandleMouseMoveEvent(
mouse_move_event, Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
- EXPECT_EQ(ui::CursorType::kHelp, GetDocument()
- .GetFrame()
- ->GetChromeClient()
- .LastSetCursorForTesting()
- .GetType());
+ EXPECT_EQ(ui::mojom::blink::CursorType::kHelp, GetDocument()
+ .GetFrame()
+ ->GetChromeClient()
+ .LastSetCursorForTesting()
+ .type());
}
// Ensure that tap on element in iframe should apply active state.
@@ -1663,7 +1669,6 @@ TEST_F(EventHandlerSimTest, TapActiveInFrame) {
// Test that the hover is updated at the next begin frame after the compositor
// scroll ends.
TEST_F(EventHandlerSimTest, TestUpdateHoverAfterCompositorScrollAtBeginFrame) {
- ScopedUpdateHoverAtBeginFrameForTest scoped_feature(true);
WebView().MainFrameWidget()->Resize(WebSize(800, 600));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
@@ -1713,7 +1718,7 @@ TEST_F(EventHandlerSimTest, TestUpdateHoverAfterCompositorScrollAtBeginFrame) {
// true in WebViewImpl.
LocalFrameView* frame_view = GetDocument().View();
frame_view->LayoutViewport()->DidScroll(FloatPoint(0, 500));
- WebView().MainFrameWidget()->ApplyViewportChanges(
+ WebView().MainFrameWidget()->ApplyViewportChangesForTesting(
{gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, false, 0, 0,
cc::BrowserControlsState::kBoth, true});
ASSERT_EQ(500, frame_view->LayoutViewport()->GetScrollOffset().Height());
@@ -1731,7 +1736,6 @@ TEST_F(EventHandlerSimTest, TestUpdateHoverAfterCompositorScrollAtBeginFrame) {
// Test that the hover is updated at the next begin frame after the main thread
// scroll ends.
TEST_F(EventHandlerSimTest, TestUpdateHoverAfterMainThreadScrollAtBeginFrame) {
- ScopedUpdateHoverAtBeginFrameForTest scoped_feature(true);
WebView().MainFrameWidget()->Resize(WebSize(800, 600));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
@@ -1800,7 +1804,6 @@ TEST_F(EventHandlerSimTest, TestUpdateHoverAfterMainThreadScrollAtBeginFrame) {
// scroll ends in an iframe.
TEST_F(EventHandlerSimTest,
TestUpdateHoverAfterMainThreadScrollInIFrameAtBeginFrame) {
- ScopedUpdateHoverAtBeginFrameForTest scoped_feature(true);
WebView().MainFrameWidget()->Resize(WebSize(800, 600));
SimRequest main_resource("https://example.com/test.html", "text/html");
SimRequest frame_resource("https://example.com/iframe.html", "text/html");
@@ -1871,7 +1874,6 @@ TEST_F(EventHandlerSimTest,
// Test that the hover is updated at the next begin frame after the smooth JS
// scroll ends.
TEST_F(EventHandlerSimTest, TestUpdateHoverAfterJSScrollAtBeginFrame) {
- ScopedUpdateHoverAtBeginFrameForTest scoped_feature(true);
WebView().MainFrameWidget()->Resize(WebSize(800, 500));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
@@ -1904,7 +1906,8 @@ TEST_F(EventHandlerSimTest, TestUpdateHoverAfterJSScrollAtBeginFrame) {
GetDocument().GetLayoutView()->GetScrollableArea();
bool finished = false;
scrollable_area->SetScrollOffset(
- ScrollOffset(0, 1000), kProgrammaticScroll, kScrollBehaviorSmooth,
+ ScrollOffset(0, 1000), mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kSmooth,
ScrollableArea::ScrollCallback(
base::BindOnce([](bool* finished) { *finished = true; }, &finished)));
Compositor().BeginFrame();
@@ -1934,7 +1937,6 @@ TEST_F(EventHandlerSimTest, TestUpdateHoverAfterJSScrollAtBeginFrame) {
// thread scroll snap animation finishes.
TEST_F(EventHandlerSimTest,
TestUpdateHoverAfterMainThreadScrollSnapAtBeginFrame) {
- ScopedUpdateHoverAtBeginFrameForTest scoped_feature(true);
WebView().MainFrameWidget()->Resize(WebSize(800, 600));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
@@ -2017,7 +2019,6 @@ TEST_F(EventHandlerSimTest,
TEST_F(EventHandlerSimTest,
TestUpdateHoverAfterMainThreadScrollAtSnapPointAtBeginFrame) {
- ScopedUpdateHoverAtBeginFrameForTest scoped_feature(true);
WebView().MainFrameWidget()->Resize(WebSize(800, 600));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
@@ -2114,32 +2115,32 @@ TEST_F(EventHandlerSimTest, LargeCustomCursorIntersectsViewport) {
// Move the cursor so no part of it intersects the viewport.
{
WebMouseEvent mouse_move_event(
- WebMouseEvent::kMouseMove, WebFloatPoint(101, 101),
- WebFloatPoint(101, 101), WebPointerProperties::Button::kNoButton, 0, 0,
+ WebMouseEvent::kMouseMove, gfx::PointF(101, 101), gfx::PointF(101, 101),
+ WebPointerProperties::Button::kNoButton, 0, 0,
WebInputEvent::GetStaticTimeStampForTests());
mouse_move_event.SetFrameScale(1);
GetDocument().GetFrame()->GetEventHandler().HandleMouseMoveEvent(
mouse_move_event, Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
- const Cursor& cursor =
+ const ui::Cursor& cursor =
GetDocument().GetFrame()->GetChromeClient().LastSetCursorForTesting();
- EXPECT_EQ(ui::CursorType::kCustom, cursor.GetType());
+ EXPECT_EQ(ui::mojom::blink::CursorType::kCustom, cursor.type());
}
// Now, move the cursor so that it intersects the visual viewport. The cursor
// should be removed.
{
WebMouseEvent mouse_move_event(
- WebMouseEvent::kMouseMove, WebFloatPoint(99, 99), WebFloatPoint(99, 99),
+ WebMouseEvent::kMouseMove, gfx::PointF(99, 99), gfx::PointF(99, 99),
WebPointerProperties::Button::kNoButton, 0, 0,
WebInputEvent::GetStaticTimeStampForTests());
mouse_move_event.SetFrameScale(1);
GetDocument().GetFrame()->GetEventHandler().HandleMouseMoveEvent(
mouse_move_event, Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
- const Cursor& cursor =
+ const ui::Cursor& cursor =
GetDocument().GetFrame()->GetChromeClient().LastSetCursorForTesting();
- EXPECT_EQ(ui::CursorType::kPointer, cursor.GetType());
+ EXPECT_EQ(ui::mojom::blink::CursorType::kPointer, cursor.type());
}
}
@@ -2173,16 +2174,16 @@ TEST_F(EventHandlerSimTest, SmallCustomCursorIntersectsViewport) {
// Move the cursor so no part of it intersects the viewport.
{
WebMouseEvent mouse_move_event(
- WebMouseEvent::kMouseMove, WebFloatPoint(25, 25), WebFloatPoint(25, 25),
+ WebMouseEvent::kMouseMove, gfx::PointF(25, 25), gfx::PointF(25, 25),
WebPointerProperties::Button::kNoButton, 0, 0,
WebInputEvent::GetStaticTimeStampForTests());
mouse_move_event.SetFrameScale(1);
GetDocument().GetFrame()->GetEventHandler().HandleMouseMoveEvent(
mouse_move_event, Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
- const Cursor& cursor =
+ const ui::Cursor& cursor =
GetDocument().GetFrame()->GetChromeClient().LastSetCursorForTesting();
- EXPECT_EQ(ui::CursorType::kCustom, cursor.GetType());
+ EXPECT_EQ(ui::mojom::blink::CursorType::kCustom, cursor.type());
}
// Now, move the cursor so that it intersects the visual viewport. The cursor
@@ -2190,16 +2191,16 @@ TEST_F(EventHandlerSimTest, SmallCustomCursorIntersectsViewport) {
// kMaximumCursorSizeWithoutFallback.
{
WebMouseEvent mouse_move_event(
- WebMouseEvent::kMouseMove, WebFloatPoint(23, 23), WebFloatPoint(23, 23),
+ WebMouseEvent::kMouseMove, gfx::PointF(23, 23), gfx::PointF(23, 23),
WebPointerProperties::Button::kNoButton, 0, 0,
WebInputEvent::GetStaticTimeStampForTests());
mouse_move_event.SetFrameScale(1);
GetDocument().GetFrame()->GetEventHandler().HandleMouseMoveEvent(
mouse_move_event, Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
- const Cursor& cursor =
+ const ui::Cursor& cursor =
GetDocument().GetFrame()->GetChromeClient().LastSetCursorForTesting();
- EXPECT_EQ(ui::CursorType::kCustom, cursor.GetType());
+ EXPECT_EQ(ui::mojom::blink::CursorType::kCustom, cursor.type());
}
}
@@ -2339,7 +2340,8 @@ TEST_F(EventHandlerSimTest, NotExposeKeyboardEvent) {
WebElement input = GetDocument().getElementById("input1");
GetDocument().SetFocusedElement(
input.Unwrap<Element>(),
- FocusParams(SelectionBehaviorOnFocus::kNone, kWebFocusTypeNone, nullptr));
+ FocusParams(SelectionBehaviorOnFocus::kNone,
+ mojom::blink::FocusType::kNone, nullptr));
e.SetType(WebInputEvent::kRawKeyDown);
GetDocument().GetFrame()->GetEventHandler().KeyEvent(e);
@@ -2381,8 +2383,8 @@ TEST_F(EventHandlerSimTest, DoNotScrollWithTouchpadIfOverflowIsHidden) {
WebInputEvent::kGestureScrollBegin, WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
blink::WebGestureDevice::kTouchpad);
- scroll_begin_event.SetPositionInWidget(WebFloatPoint(10, 10));
- scroll_begin_event.SetPositionInScreen(WebFloatPoint(10, 10));
+ scroll_begin_event.SetPositionInWidget(gfx::PointF(10, 10));
+ scroll_begin_event.SetPositionInScreen(gfx::PointF(10, 10));
scroll_begin_event.SetFrameScale(1);
WebGestureEvent scroll_update_event(
@@ -2391,16 +2393,16 @@ TEST_F(EventHandlerSimTest, DoNotScrollWithTouchpadIfOverflowIsHidden) {
blink::WebGestureDevice::kTouchpad);
scroll_update_event.data.scroll_update.delta_x = -100;
scroll_update_event.data.scroll_update.delta_y = -100;
- scroll_update_event.SetPositionInWidget(WebFloatPoint(10, 10));
- scroll_update_event.SetPositionInScreen(WebFloatPoint(10, 10));
+ scroll_update_event.SetPositionInWidget(gfx::PointF(10, 10));
+ scroll_update_event.SetPositionInScreen(gfx::PointF(10, 10));
scroll_update_event.SetFrameScale(1);
WebGestureEvent scroll_end_event(WebInputEvent::kGestureScrollEnd,
WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
blink::WebGestureDevice::kTouchpad);
- scroll_end_event.SetPositionInWidget(WebFloatPoint(10, 10));
- scroll_end_event.SetPositionInScreen(WebFloatPoint(10, 10));
+ scroll_end_event.SetPositionInWidget(gfx::PointF(10, 10));
+ scroll_end_event.SetPositionInScreen(gfx::PointF(10, 10));
WebView().MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(scroll_begin_event));
@@ -2443,8 +2445,8 @@ TEST_F(EventHandlerSimTest, GestureScrollUpdateModifiedScrollChain) {
WebInputEvent::kGestureScrollBegin, WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
blink::WebGestureDevice::kTouchpad);
- scroll_begin_event.SetPositionInWidget(WebFloatPoint(10, 10));
- scroll_begin_event.SetPositionInScreen(WebFloatPoint(10, 10));
+ scroll_begin_event.SetPositionInWidget(gfx::PointF(10, 10));
+ scroll_begin_event.SetPositionInScreen(gfx::PointF(10, 10));
scroll_begin_event.SetFrameScale(1);
WebGestureEvent scroll_update_event(
@@ -2453,16 +2455,16 @@ TEST_F(EventHandlerSimTest, GestureScrollUpdateModifiedScrollChain) {
blink::WebGestureDevice::kTouchpad);
scroll_update_event.data.scroll_update.delta_x = 0;
scroll_update_event.data.scroll_update.delta_y = -100;
- scroll_update_event.SetPositionInWidget(WebFloatPoint(10, 10));
- scroll_update_event.SetPositionInScreen(WebFloatPoint(10, 10));
+ scroll_update_event.SetPositionInWidget(gfx::PointF(10, 10));
+ scroll_update_event.SetPositionInScreen(gfx::PointF(10, 10));
scroll_update_event.SetFrameScale(1);
WebGestureEvent scroll_end_event(WebInputEvent::kGestureScrollEnd,
WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
blink::WebGestureDevice::kTouchpad);
- scroll_end_event.SetPositionInWidget(WebFloatPoint(10, 10));
- scroll_end_event.SetPositionInScreen(WebFloatPoint(10, 10));
+ scroll_end_event.SetPositionInWidget(gfx::PointF(10, 10));
+ scroll_end_event.SetPositionInScreen(gfx::PointF(10, 10));
WebView().MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(scroll_begin_event));
@@ -2561,7 +2563,7 @@ TEST_F(EventHandlerSimTest, ElementTargetedGestureScroll) {
// Remove the scroller, update layout, and ensure the same gestures
// don't crash or scroll the layout viewport.
scroller->remove();
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(
gesture_scroll_begin);
GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(
@@ -2589,8 +2591,8 @@ TEST_F(EventHandlerSimTest, ElementTargetedGestureScrollIFrame) {
)HTML");
Compositor().BeginFrame();
- HTMLFrameElementBase* const iframe =
- ToHTMLFrameElementBase(GetDocument().getElementById("iframe"));
+ auto* const iframe =
+ To<HTMLFrameElementBase>(GetDocument().getElementById("iframe"));
FrameView* child_frame_view =
iframe->GetLayoutEmbeddedContent()->ChildFrameView();
auto* local_child_frame_view = DynamicTo<LocalFrameView>(child_frame_view);
@@ -2697,7 +2699,7 @@ TEST_F(EventHandlerSimTest, SelecteTransformedTextWhenCapturing) {
Compositor().BeginFrame();
WebMouseEvent mouse_down_event(WebInputEvent::kMouseDown,
- WebFloatPoint(100, 20), WebFloatPoint(0, 0),
+ gfx::PointF(100, 20), gfx::PointF(0, 0),
WebPointerProperties::Button::kLeft, 1,
WebInputEvent::Modifiers::kLeftButtonDown,
WebInputEvent::GetStaticTimeStampForTests());
@@ -2716,7 +2718,7 @@ TEST_F(EventHandlerSimTest, SelecteTransformedTextWhenCapturing) {
PointerEventFactory::kMouseId, target);
WebMouseEvent mouse_move_event(WebInputEvent::kMouseMove,
- WebFloatPoint(258, 20), WebFloatPoint(0, 0),
+ gfx::PointF(258, 20), gfx::PointF(0, 0),
WebPointerProperties::Button::kLeft, 1,
WebInputEvent::Modifiers::kLeftButtonDown,
WebInputEvent::GetStaticTimeStampForTests());
@@ -2725,7 +2727,7 @@ TEST_F(EventHandlerSimTest, SelecteTransformedTextWhenCapturing) {
mouse_move_event, Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
WebMouseEvent mouse_up_event(
- WebMouseEvent::kMouseUp, WebFloatPoint(258, 20), WebFloatPoint(0, 0),
+ WebMouseEvent::kMouseUp, gfx::PointF(258, 20), gfx::PointF(0, 0),
WebPointerProperties::Button::kLeft, 1, WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests());
mouse_up_event.SetFrameScale(1);
@@ -2785,7 +2787,7 @@ TEST_F(EventHandlerSimTest, MouseDragWithNoSubframeImplicitCapture) {
Compositor().BeginFrame();
WebMouseEvent mouse_down_inside_event(
- WebMouseEvent::kMouseDown, WebFloatPoint(50, 50), WebFloatPoint(50, 50),
+ WebMouseEvent::kMouseDown, gfx::PointF(50, 50), gfx::PointF(50, 50),
WebPointerProperties::Button::kLeft, 0,
WebInputEvent::Modifiers::kLeftButtonDown,
WebInputEvent::GetStaticTimeStampForTests());
@@ -2794,8 +2796,8 @@ TEST_F(EventHandlerSimTest, MouseDragWithNoSubframeImplicitCapture) {
WebCoalescedInputEvent(mouse_down_inside_event));
WebMouseEvent mouse_move_inside_event(
- WebInputEvent::kMouseMove, WebFloatPoint(100, 100),
- WebFloatPoint(100, 100), WebPointerProperties::Button::kLeft, 1,
+ WebInputEvent::kMouseMove, gfx::PointF(100, 100), gfx::PointF(100, 100),
+ WebPointerProperties::Button::kLeft, 1,
WebInputEvent::Modifiers::kLeftButtonDown,
WebInputEvent::GetStaticTimeStampForTests());
mouse_move_inside_event.SetFrameScale(1);
@@ -2815,8 +2817,8 @@ TEST_F(EventHandlerSimTest, MouseDragWithNoSubframeImplicitCapture) {
// Without capturing, next mouse move will be send to outer frame.
WebMouseEvent mouse_move_outside_event(
- WebInputEvent::kMouseMove, WebFloatPoint(100, 300),
- WebFloatPoint(100, 300), WebPointerProperties::Button::kLeft, 1,
+ WebInputEvent::kMouseMove, gfx::PointF(100, 300), gfx::PointF(100, 300),
+ WebPointerProperties::Button::kLeft, 1,
WebInputEvent::Modifiers::kLeftButtonDown,
WebInputEvent::GetStaticTimeStampForTests());
mouse_move_outside_event.SetFrameScale(1);
@@ -2877,7 +2879,7 @@ TEST_F(EventHandlerSimTest,
Compositor().BeginFrame();
WebMouseEvent mouse_down_inside_event(
- WebMouseEvent::kMouseDown, WebFloatPoint(50, 50), WebFloatPoint(50, 50),
+ WebMouseEvent::kMouseDown, gfx::PointF(50, 50), gfx::PointF(50, 50),
WebPointerProperties::Button::kLeft, 0,
WebInputEvent::Modifiers::kLeftButtonDown,
WebInputEvent::GetStaticTimeStampForTests());
@@ -2896,11 +2898,11 @@ TEST_F(EventHandlerSimTest,
EXPECT_TRUE(target->hasPointerCapture(PointerEventFactory::kMouseId));
// With pointercapture, next mouse move will be send to inner frame.
- WebMouseEvent mouse_move_event(
- WebInputEvent::kMouseMove, WebFloatPoint(100, 300),
- WebFloatPoint(100, 300), WebPointerProperties::Button::kLeft, 1,
- WebInputEvent::Modifiers::kLeftButtonDown,
- WebInputEvent::GetStaticTimeStampForTests());
+ WebMouseEvent mouse_move_event(WebInputEvent::kMouseMove,
+ gfx::PointF(100, 300), gfx::PointF(100, 300),
+ WebPointerProperties::Button::kLeft, 1,
+ WebInputEvent::Modifiers::kLeftButtonDown,
+ WebInputEvent::GetStaticTimeStampForTests());
mouse_move_event.SetFrameScale(1);
WebView().MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(mouse_move_event));
@@ -2954,7 +2956,7 @@ TEST_F(EventHandlerSimTest, MouseRightButtonDownMoveToIFrame) {
frame_resource.Complete("<!DOCTYPE html>");
Compositor().BeginFrame();
WebMouseEvent mouse_down_outside_event(
- WebMouseEvent::kMouseDown, WebFloatPoint(300, 29), WebFloatPoint(300, 29),
+ WebMouseEvent::kMouseDown, gfx::PointF(300, 29), gfx::PointF(300, 29),
WebPointerProperties::Button::kRight, 0,
WebInputEvent::Modifiers::kRightButtonDown,
WebInputEvent::GetStaticTimeStampForTests());
@@ -2963,7 +2965,7 @@ TEST_F(EventHandlerSimTest, MouseRightButtonDownMoveToIFrame) {
WebCoalescedInputEvent(mouse_down_outside_event));
WebMouseEvent mouse_move_outside_event(
- WebMouseEvent::kMouseMove, WebFloatPoint(300, 29), WebFloatPoint(300, 29),
+ WebMouseEvent::kMouseMove, gfx::PointF(300, 29), gfx::PointF(300, 29),
WebPointerProperties::Button::kRight, 0,
WebInputEvent::Modifiers::kRightButtonDown,
WebInputEvent::GetStaticTimeStampForTests());
@@ -2972,8 +2974,8 @@ TEST_F(EventHandlerSimTest, MouseRightButtonDownMoveToIFrame) {
WebCoalescedInputEvent(mouse_move_outside_event));
WebMouseEvent mouse_move_inside_event(
- WebMouseEvent::kMouseMove, WebFloatPoint(100, 229),
- WebFloatPoint(100, 229), WebPointerProperties::Button::kRight, 0,
+ WebMouseEvent::kMouseMove, gfx::PointF(100, 229), gfx::PointF(100, 229),
+ WebPointerProperties::Button::kRight, 0,
WebInputEvent::Modifiers::kRightButtonDown,
WebInputEvent::GetStaticTimeStampForTests());
mouse_move_inside_event.SetFrameScale(1);
@@ -3005,8 +3007,8 @@ TEST_F(EventHandlerSimTest, PenDraggingOnElementActive) {
)HTML");
Compositor().BeginFrame();
- WebMouseEvent pen_down(WebMouseEvent::kMouseDown, WebFloatPoint(100, 100),
- WebFloatPoint(100, 100),
+ WebMouseEvent pen_down(WebMouseEvent::kMouseDown, gfx::PointF(100, 100),
+ gfx::PointF(100, 100),
WebPointerProperties::Button::kLeft, 0,
WebInputEvent::Modifiers::kLeftButtonDown,
WebInputEvent::GetStaticTimeStampForTests());
@@ -3015,8 +3017,8 @@ TEST_F(EventHandlerSimTest, PenDraggingOnElementActive) {
WebView().MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(pen_down));
- WebMouseEvent pen_move(WebMouseEvent::kMouseMove, WebFloatPoint(100, 100),
- WebFloatPoint(100, 100),
+ WebMouseEvent pen_move(WebMouseEvent::kMouseMove, gfx::PointF(100, 100),
+ gfx::PointF(100, 100),
WebPointerProperties::Button::kLeft, 0,
WebInputEvent::Modifiers::kLeftButtonDown,
WebInputEvent::GetStaticTimeStampForTests());
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 a1a56fd0b2c..0e8fe61b1b0 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
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/core/input/event_handling_util.h"
-#include "third_party/blink/public/platform/web_mouse_event.h"
+#include "third_party/blink/public/common/input/web_mouse_event.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_feature.h"
@@ -105,7 +105,8 @@ ContainerNode* ParentForClickEventInteractiveElementSensitive(
const Node& node) {
// IE doesn't dispatch click events for mousedown/mouseup events across form
// controls.
- if (node.IsHTMLElement() && ToHTMLElement(node).IsInteractiveContent())
+ auto* html_element = DynamicTo<HTMLElement>(node);
+ if (html_element && html_element->IsInteractiveContent())
return nullptr;
return FlatTreeTraversal::Parent(node);
@@ -134,15 +135,13 @@ MouseEventWithHitTestResults PerformMouseEventHitTest(
DCHECK(frame->GetDocument());
return frame->GetDocument()->PerformMouseEventHitTest(
- request, ContentPointFromRootFrame(frame, mev.PositionInRootFrame()),
+ request,
+ ContentPointFromRootFrame(frame, FloatPoint(mev.PositionInRootFrame())),
mev);
}
bool ShouldDiscardEventTargetingFrame(const WebInputEvent& event,
const LocalFrame& frame) {
- if (!RuntimeEnabledFeatures::DiscardInputToMovingIframesEnabled())
- return false;
-
// There are two different mechanisms for tracking whether an iframe has moved
// recently, for OOPIF and in-process iframes. For OOPIF's, frame movement is
// tracked in the browser process using hit test data, and it's propagated
@@ -150,7 +149,7 @@ bool ShouldDiscardEventTargetingFrame(const WebInputEvent& event,
// during lifecycle updates, in FrameView::UpdateViewportIntersection, and
// propagated via FrameView::RectInParentIsStable.
bool should_discard = false;
- if (frame.NeedsOcclusionTracking() && frame.IsCrossOriginSubframe()) {
+ if (frame.NeedsOcclusionTracking() && frame.IsCrossOriginToMainFrame()) {
should_discard =
(event.GetModifiers() & WebInputEvent::kTargetFrameMovedRecently) ||
!frame.View()->RectInParentIsStable(event.TimeStamp());
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 a0ceb95901e..b3c987f0c6e 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
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_INPUT_EVENT_HANDLING_UTIL_H_
#include "third_party/blink/public/platform/web_input_event_result.h"
+#include "third_party/blink/renderer/core/core_export.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/layout/geometry/physical_offset.h"
@@ -23,7 +24,7 @@ enum class DispatchEventResult;
namespace event_handling_util {
-HitTestResult HitTestResultInFrame(
+CORE_EXPORT HitTestResult HitTestResultInFrame(
LocalFrame*,
const HitTestLocation&,
HitTestRequest::HitTestRequestType hit_type = HitTestRequest::kReadOnly |
@@ -65,7 +66,7 @@ class PointerEventTarget {
DISALLOW_NEW();
public:
- void Trace(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
visitor->Trace(target_element);
visitor->Trace(target_frame);
}
diff --git a/chromium/third_party/blink/renderer/core/input/fallback_cursor_event_manager.cc b/chromium/third_party/blink/renderer/core/input/fallback_cursor_event_manager.cc
index 7da8a252314..3008ec61847 100644
--- a/chromium/third_party/blink/renderer/core/input/fallback_cursor_event_manager.cc
+++ b/chromium/third_party/blink/renderer/core/input/fallback_cursor_event_manager.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/core/input/fallback_cursor_event_manager.h"
-#include "third_party/blink/public/platform/web_mouse_event.h"
+#include "third_party/blink/public/common/input/web_mouse_event.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
@@ -129,7 +129,7 @@ FallbackCursorEventManager::FallbackCursorEventManager(LocalFrame& root_frame)
ResetCurrentScrollable();
}
-void FallbackCursorEventManager::Trace(blink::Visitor* visitor) {
+void FallbackCursorEventManager::Trace(Visitor* visitor) {
visitor->Trace(root_frame_);
visitor->Trace(current_node_);
}
@@ -355,8 +355,8 @@ void FallbackCursorEventManager::HandleMouseMoveEvent(const WebMouseEvent& e) {
if (!root_frame_->GetDocument() || !root_frame_->GetDocument()->View())
return;
- IntPoint location_in_root_frame{e.PositionInRootFrame().x,
- e.PositionInRootFrame().y};
+ IntPoint location_in_root_frame{e.PositionInRootFrame().x(),
+ e.PositionInRootFrame().y()};
// Make sure we unlock all movement if the cursor is outside our bounds. This
// can happen when the cursor is enabled/disabled (e.g. position: -1,-1).
@@ -388,7 +388,7 @@ void FallbackCursorEventManager::HandleMousePressEvent(const WebMouseEvent& e) {
ResetCurrentScrollable();
// Re hit test since we need a hit test with child frame.
- IntPoint location{e.PositionInRootFrame().x, e.PositionInRootFrame().y};
+ IntPoint location{e.PositionInRootFrame().x(), e.PositionInRootFrame().y()};
HitTestResult hit_test_result =
HitTest(root_frame_->GetDocument()->GetLayoutView(), location);
Node* node = hit_test_result.InnerNode();
diff --git a/chromium/third_party/blink/renderer/core/input/fallback_cursor_event_manager.h b/chromium/third_party/blink/renderer/core/input/fallback_cursor_event_manager.h
index 81a4e4c17b3..7c0bc7a7428 100644
--- a/chromium/third_party/blink/renderer/core/input/fallback_cursor_event_manager.h
+++ b/chromium/third_party/blink/renderer/core/input/fallback_cursor_event_manager.h
@@ -26,7 +26,7 @@ class CORE_EXPORT FallbackCursorEventManager
: public GarbageCollected<FallbackCursorEventManager> {
public:
FallbackCursorEventManager(LocalFrame&);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
void SetIsFallbackCursorModeOn(bool is_on);
diff --git a/chromium/third_party/blink/renderer/core/input/fallback_cursor_event_manager_test.cc b/chromium/third_party/blink/renderer/core/input/fallback_cursor_event_manager_test.cc
index 925a4a56144..ba05ed43673 100644
--- a/chromium/third_party/blink/renderer/core/input/fallback_cursor_event_manager_test.cc
+++ b/chromium/third_party/blink/renderer/core/input/fallback_cursor_event_manager_test.cc
@@ -5,7 +5,7 @@
#include "third_party/blink/renderer/core/input/fallback_cursor_event_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/web_mouse_event.h"
+#include "third_party/blink/public/common/input/web_mouse_event.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/frame/visual_viewport.h"
@@ -82,8 +82,8 @@ class FallbackCursorEventManagerTest : public RenderingTest,
}
void MouseMove(int x, int y, float scale = 1.0f) {
- WebMouseEvent event(WebInputEvent::kMouseMove, WebFloatPoint(x, y),
- WebFloatPoint(x, y),
+ WebMouseEvent event(WebInputEvent::kMouseMove, gfx::PointF(x, y),
+ gfx::PointF(x, y),
WebPointerProperties::Button::kNoButton, 0,
WebInputEvent::kNoModifiers, base::TimeTicks::Now());
event.SetFrameScale(scale);
@@ -110,10 +110,10 @@ class FallbackCursorEventManagerTest : public RenderingTest,
}
void MouseDown(int x, int y) {
- WebMouseEvent event(
- WebInputEvent::kMouseDown, WebFloatPoint(x, y), WebFloatPoint(x, y),
- WebPointerProperties::Button::kLeft, 0,
- WebInputEvent::Modifiers::kLeftButtonDown, base::TimeTicks::Now());
+ WebMouseEvent event(WebInputEvent::kMouseDown, gfx::PointF(x, y),
+ gfx::PointF(x, y), WebPointerProperties::Button::kLeft,
+ 0, WebInputEvent::Modifiers::kLeftButtonDown,
+ base::TimeTicks::Now());
event.SetFrameScale(1);
GetDocument().GetFrame()->GetEventHandler().HandleMousePressEvent(event);
}
@@ -581,7 +581,7 @@ TEST_F(FallbackCursorEventManagerTest, AccountsForOverflowHidden) {
// Fully scroll the layout viewport to the bottom.
GetDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, 100000), kProgrammaticScroll);
+ ScrollOffset(0, 100000), mojom::blink::ScrollType::kProgrammatic);
// Move the mouse to the bottom of the viewport, we shouldn't lock because
// both layout and visual are at the extent.
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 ac1fdd6751d..d28ddfd464f 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(blink::Visitor* visitor) {
+void GestureManager::Trace(Visitor* visitor) {
visitor->Trace(frame_);
visitor->Trace(scroll_manager_);
visitor->Trace(mouse_event_manager_);
@@ -196,7 +196,8 @@ WebInputEventResult GestureManager::HandleGestureTap(
if (current_hit_test.InnerNode()) {
LocalFrame& main_frame = frame_->LocalFrameRoot();
if (!main_frame.View() ||
- !main_frame.View()->UpdateAllLifecyclePhasesExceptPaint())
+ !main_frame.View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kHitTest))
return WebInputEventResult::kNotHandled;
adjusted_point = frame_view->ConvertFromRootFrame(
FlooredIntPoint(gesture_event.PositionInRootFrame()));
@@ -259,7 +260,7 @@ WebInputEventResult GestureManager::HandleGestureTap(
LocalFrame& main_frame = frame_->LocalFrameRoot();
if (main_frame.View()) {
main_frame.View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kOther);
+ DocumentUpdateReason::kHitTest);
}
adjusted_point = frame_view->ConvertFromRootFrame(tapped_position);
current_hit_test = event_handling_util::HitTestResultInFrame(
@@ -486,10 +487,8 @@ void GestureManager::ShowUnhandledTapUIIfNeeded(
// e.g. style->GetFontWeight() to return bold. Need italic, color, etc.
// Notify the Browser.
- WebPoint point(tapped_position_in_viewport.X(),
- tapped_position_in_viewport.Y());
- auto tapped_info =
- mojom::blink::UnhandledTapInfo::New(point, font_size, text_run_length);
+ auto tapped_info = mojom::blink::UnhandledTapInfo::New(
+ tapped_position_in_viewport, font_size, text_run_length);
provider->ShowUnhandledTapUIIfNeeded(std::move(tapped_info));
}
#endif // BUILDFLAG(ENABLE_UNHANDLED_TAP)
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 69a18d787a5..0d5980cf2c5 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(blink::Visitor*);
+ void Trace(Visitor*);
void Clear();
diff --git a/chromium/third_party/blink/renderer/core/input/input_device_capabilities.cc b/chromium/third_party/blink/renderer/core/input/input_device_capabilities.cc
index 076adfba3c6..d590db7e8e8 100644
--- a/chromium/third_party/blink/renderer/core/input/input_device_capabilities.cc
+++ b/chromium/third_party/blink/renderer/core/input/input_device_capabilities.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/core/input/input_device_capabilities.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_input_device_capabilities_init.h"
+
namespace blink {
InputDeviceCapabilities::InputDeviceCapabilities(bool fires_touch_events) {
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 21cf5e4b7a3..922d56b2008 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
@@ -6,11 +6,12 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_INPUT_INPUT_DEVICE_CAPABILITIES_H_
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/input/input_device_capabilities_init.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
namespace blink {
+class InputDeviceCapabilitiesInit;
+
class CORE_EXPORT InputDeviceCapabilities final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
@@ -50,7 +51,7 @@ class InputDeviceCapabilitiesConstants final
// |firesTouchEvents| set to value of |firesTouch|.
InputDeviceCapabilities* FiresTouchEvents(bool fires_touch);
- void Trace(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
visitor->Trace(fires_touch_events_);
visitor->Trace(doesnt_fire_touch_events_);
}
diff --git a/chromium/third_party/blink/renderer/core/input/input_device_capabilities.idl b/chromium/third_party/blink/renderer/core/input/input_device_capabilities.idl
index 16e39ab13a2..341f71ebb80 100644
--- a/chromium/third_party/blink/renderer/core/input/input_device_capabilities.idl
+++ b/chromium/third_party/blink/renderer/core/input/input_device_capabilities.idl
@@ -11,9 +11,8 @@
// https://wicg.github.io/InputDeviceCapabilities/#the-inputdevicecapabilities-interface
-[
- Constructor(optional InputDeviceCapabilitiesInit deviceInitDict)
-] interface InputDeviceCapabilities {
+interface InputDeviceCapabilities {
+ constructor(optional InputDeviceCapabilitiesInit deviceInitDict = {});
// Whether this device dispatches touch events for movement. This is used to detect
// mouse events which represent only an action that has already been handled by
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 f8c8e40a05f..8589587194d 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
@@ -7,8 +7,9 @@
#include <memory>
#include "build/build_config.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_input_event.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
#include "third_party/blink/renderer/core/editing/editor.h"
@@ -47,7 +48,7 @@ const int kVKeySpatNavBack = 233;
bool MapKeyCodeForScroll(int key_code,
WebInputEvent::Modifiers modifiers,
- ScrollDirection* scroll_direction,
+ mojom::blink::ScrollDirection* scroll_direction,
ScrollGranularity* scroll_granularity,
WebFeature* scroll_use_uma) {
if (modifiers & WebInputEvent::kShiftKey ||
@@ -74,42 +75,62 @@ bool MapKeyCodeForScroll(int key_code,
switch (key_code) {
case VKEY_LEFT:
- *scroll_direction = kScrollLeftIgnoringWritingMode;
- *scroll_granularity = ScrollGranularity::kScrollByLine;
+ *scroll_direction =
+ mojom::blink::ScrollDirection::kScrollLeftIgnoringWritingMode;
+ *scroll_granularity =
+ RuntimeEnabledFeatures::PercentBasedScrollingEnabled()
+ ? ScrollGranularity::kScrollByPercentage
+ : ScrollGranularity::kScrollByLine;
*scroll_use_uma = WebFeature::kScrollByKeyboardArrowKeys;
break;
case VKEY_RIGHT:
- *scroll_direction = kScrollRightIgnoringWritingMode;
- *scroll_granularity = ScrollGranularity::kScrollByLine;
+ *scroll_direction =
+ mojom::blink::ScrollDirection::kScrollRightIgnoringWritingMode;
+ *scroll_granularity =
+ RuntimeEnabledFeatures::PercentBasedScrollingEnabled()
+ ? ScrollGranularity::kScrollByPercentage
+ : ScrollGranularity::kScrollByLine;
*scroll_use_uma = WebFeature::kScrollByKeyboardArrowKeys;
break;
case VKEY_UP:
- *scroll_direction = kScrollUpIgnoringWritingMode;
- *scroll_granularity = ScrollGranularity::kScrollByLine;
+ *scroll_direction =
+ mojom::blink::ScrollDirection::kScrollUpIgnoringWritingMode;
+ *scroll_granularity =
+ RuntimeEnabledFeatures::PercentBasedScrollingEnabled()
+ ? ScrollGranularity::kScrollByPercentage
+ : ScrollGranularity::kScrollByLine;
*scroll_use_uma = WebFeature::kScrollByKeyboardArrowKeys;
break;
case VKEY_DOWN:
- *scroll_direction = kScrollDownIgnoringWritingMode;
- *scroll_granularity = ScrollGranularity::kScrollByLine;
+ *scroll_direction =
+ mojom::blink::ScrollDirection::kScrollDownIgnoringWritingMode;
+ *scroll_granularity =
+ RuntimeEnabledFeatures::PercentBasedScrollingEnabled()
+ ? ScrollGranularity::kScrollByPercentage
+ : ScrollGranularity::kScrollByLine;
*scroll_use_uma = WebFeature::kScrollByKeyboardArrowKeys;
break;
case VKEY_HOME:
- *scroll_direction = kScrollUpIgnoringWritingMode;
+ *scroll_direction =
+ mojom::blink::ScrollDirection::kScrollUpIgnoringWritingMode;
*scroll_granularity = ScrollGranularity::kScrollByDocument;
*scroll_use_uma = WebFeature::kScrollByKeyboardHomeEndKeys;
break;
case VKEY_END:
- *scroll_direction = kScrollDownIgnoringWritingMode;
+ *scroll_direction =
+ mojom::blink::ScrollDirection::kScrollDownIgnoringWritingMode;
*scroll_granularity = ScrollGranularity::kScrollByDocument;
*scroll_use_uma = WebFeature::kScrollByKeyboardHomeEndKeys;
break;
case VKEY_PRIOR: // page up
- *scroll_direction = kScrollUpIgnoringWritingMode;
+ *scroll_direction =
+ mojom::blink::ScrollDirection::kScrollUpIgnoringWritingMode;
*scroll_granularity = ScrollGranularity::kScrollByPage;
*scroll_use_uma = WebFeature::kScrollByKeyboardPageUpDownKeys;
break;
case VKEY_NEXT: // page down
- *scroll_direction = kScrollDownIgnoringWritingMode;
+ *scroll_direction =
+ mojom::blink::ScrollDirection::kScrollDownIgnoringWritingMode;
*scroll_granularity = ScrollGranularity::kScrollByPage;
*scroll_use_uma = WebFeature::kScrollByKeyboardPageUpDownKeys;
break;
@@ -126,7 +147,7 @@ KeyboardEventManager::KeyboardEventManager(LocalFrame& frame,
ScrollManager& scroll_manager)
: frame_(frame), scroll_manager_(scroll_manager) {}
-void KeyboardEventManager::Trace(blink::Visitor* visitor) {
+void KeyboardEventManager::Trace(Visitor* visitor) {
visitor->Trace(frame_);
visitor->Trace(scroll_manager_);
}
@@ -147,7 +168,7 @@ bool KeyboardEventManager::HandleAccessKey(const WebKeyboardEvent& evt) {
if (!elem)
return false;
elem->focus(FocusParams(SelectionBehaviorOnFocus::kReset,
- kWebFocusTypeAccessKey, nullptr));
+ mojom::blink::FocusType::kAccessKey, nullptr));
elem->AccessKeyAction(false);
return true;
}
@@ -186,7 +207,9 @@ WebInputEventResult KeyboardEventManager::KeyEvent(
if (!is_modifier && initial_key_event.dom_key != ui::DomKey::ESCAPE &&
(initial_key_event.GetType() == WebInputEvent::kKeyDown ||
initial_key_event.GetType() == WebInputEvent::kRawKeyDown)) {
- LocalFrame::NotifyUserActivation(frame_);
+ LocalFrame::NotifyUserActivation(
+ frame_,
+ RuntimeEnabledFeatures::BrowserVerifiedUserActivationKeyboardEnabled());
}
// In IE, access keys are special, they are handled after default keydown
@@ -325,8 +348,8 @@ WebInputEventResult KeyboardEventManager::KeyEvent(
void KeyboardEventManager::CapsLockStateMayHaveChanged() {
if (Element* element = frame_->GetDocument()->FocusedElement()) {
if (LayoutObject* r = element->GetLayoutObject()) {
- if (r->IsTextField())
- ToLayoutTextControlSingleLine(r)->CapsLockStateMayHaveChanged();
+ if (auto* text_control = DynamicTo<LayoutTextControlSingleLine>(r))
+ text_control->CapsLockStateMayHaveChanged();
}
}
}
@@ -387,8 +410,10 @@ void KeyboardEventManager::DefaultSpaceEventHandler(
if (event->ctrlKey() || event->metaKey() || event->altKey())
return;
- ScrollDirection direction = event->shiftKey() ? kScrollBlockDirectionBackward
- : kScrollBlockDirectionForward;
+ mojom::blink::ScrollDirection direction =
+ event->shiftKey()
+ ? mojom::blink::ScrollDirection::kScrollBlockDirectionBackward
+ : mojom::blink::ScrollDirection::kScrollBlockDirectionForward;
// TODO(bokan): enable scroll customization in this case. See
// crbug.com/410974.
@@ -423,7 +448,7 @@ void KeyboardEventManager::DefaultArrowEventHandler(
if (event->KeyEvent() && event->KeyEvent()->is_system_key)
return;
- ScrollDirection scroll_direction;
+ mojom::blink::ScrollDirection scroll_direction;
ScrollGranularity scroll_granularity;
WebFeature scroll_use_uma;
if (!MapKeyCodeForScroll(event->keyCode(), event->GetModifiers(),
@@ -460,8 +485,9 @@ void KeyboardEventManager::DefaultTabEventHandler(KeyboardEvent* event) {
if (!page->TabKeyCyclesThroughElements())
return;
- WebFocusType focus_type =
- event->shiftKey() ? kWebFocusTypeBackward : kWebFocusTypeForward;
+ mojom::blink::FocusType focus_type = event->shiftKey()
+ ? mojom::blink::FocusType::kBackward
+ : mojom::blink::FocusType::kForward;
// Tabs can be used in design mode editing.
if (frame_->GetDocument()->InDesignMode())
@@ -565,8 +591,8 @@ bool KeyboardEventManager::CurrentCapsLockState() {
}
WebInputEvent::Modifiers KeyboardEventManager::GetCurrentModifierState() {
- unsigned modifiers = 0;
#if defined(OS_MACOSX)
+ unsigned modifiers = 0;
UInt32 current_modifiers = GetCurrentKeyModifiers();
if (current_modifiers & ::shiftKey)
modifiers |= WebInputEvent::kShiftKey;
@@ -576,11 +602,11 @@ WebInputEvent::Modifiers KeyboardEventManager::GetCurrentModifierState() {
modifiers |= WebInputEvent::kAltKey;
if (current_modifiers & ::cmdKey)
modifiers |= WebInputEvent::kMetaKey;
+ return static_cast<WebInputEvent::Modifiers>(modifiers);
#else
// TODO(crbug.com/538289): Implement on other platforms.
return static_cast<WebInputEvent::Modifiers>(0);
#endif
- return static_cast<WebInputEvent::Modifiers>(modifiers);
}
} // namespace blink
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 15d3b7b9f96..c1d28376037 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
@@ -7,8 +7,7 @@
#include "base/macros.h"
#include "build/build_config.h"
-#include "third_party/blink/public/platform/web_focus_type.h"
-#include "third_party/blink/public/platform/web_input_event.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/public/platform/web_input_event_result.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -36,7 +35,7 @@ class CORE_EXPORT KeyboardEventManager final
#endif
KeyboardEventManager(LocalFrame&, ScrollManager&);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
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 dac1b3157d4..b77c990e74f 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
@@ -5,7 +5,11 @@
#include "third_party/blink/renderer/core/input/mouse_event_manager.h"
#include "build/build_config.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#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/v8_drag_event_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_pointer_event_init.h"
#include "third_party/blink/renderer/core/clipboard/data_object.h"
#include "third_party/blink/renderer/core/clipboard/data_transfer.h"
#include "third_party/blink/renderer/core/clipboard/data_transfer_access_policy.h"
@@ -35,6 +39,7 @@
#include "third_party/blink/renderer/core/page/drag_controller.h"
#include "third_party/blink/renderer/core/page/drag_state.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/pointer_lock_controller.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
@@ -86,11 +91,11 @@ void UpdateMouseMovementXY(const WebMouseEvent& mouse_event,
// movementX/Y is type int for now, so we need to truncated the coordinates
// before calculate movement.
initializer->setMovementX(
- base::saturated_cast<int>(mouse_event.PositionInScreen().x *
+ base::saturated_cast<int>(mouse_event.PositionInScreen().x() *
device_scale_factor) -
base::saturated_cast<int>(last_position->X() * device_scale_factor));
initializer->setMovementY(
- base::saturated_cast<int>(mouse_event.PositionInScreen().y *
+ base::saturated_cast<int>(mouse_event.PositionInScreen().y() *
device_scale_factor) -
base::saturated_cast<int>(last_position->Y() * device_scale_factor));
}
@@ -135,16 +140,6 @@ void SetMouseEventAttributes(MouseEventInit* initializer,
: nullptr);
}
-// The amount of time to wait before sending a fake mouse event triggered
-// during a scroll.
-constexpr base::TimeDelta kFakeMouseMoveIntervalDuringScroll =
- base::TimeDelta::FromMilliseconds(100);
-
-// The amount of time to wait before sending a fake mouse event on style and
-// layout changes sets to 50Hz, same as common screen refresh rate.
-constexpr base::TimeDelta kFakeMouseMoveIntervalAfterLayoutChange =
- base::TimeDelta::FromMilliseconds(20);
-
// TODO(crbug.com/653490): Read these values from the OS.
#if defined(OS_MACOSX)
const int kDragThresholdX = 3;
@@ -162,12 +157,7 @@ enum class DragInitiator { kMouse, kTouch };
MouseEventManager::MouseEventManager(LocalFrame& frame,
ScrollManager& scroll_manager)
- : frame_(frame),
- scroll_manager_(scroll_manager),
- fake_mouse_move_event_timer_(
- frame.GetTaskRunner(TaskType::kUserInteraction),
- this,
- &MouseEventManager::FakeMouseMoveEventTimerFired) {
+ : frame_(frame), scroll_manager_(scroll_manager) {
Clear();
}
@@ -190,14 +180,13 @@ void MouseEventManager::Clear() {
svg_pan_ = false;
drag_start_pos_ = PhysicalOffset();
hover_state_dirty_ = false;
- fake_mouse_move_event_timer_.Stop();
ResetDragSource();
ClearDragDataTransfer();
}
MouseEventManager::~MouseEventManager() = default;
-void MouseEventManager::Trace(blink::Visitor* visitor) {
+void MouseEventManager::Trace(Visitor* visitor) {
visitor->Trace(frame_);
visitor->Trace(scroll_manager_);
visitor->Trace(element_under_mouse_);
@@ -438,13 +427,6 @@ WebInputEventResult MouseEventManager::DispatchMouseClickIfNeeded(
return WebInputEventResult::kNotHandled;
}
-void MouseEventManager::FakeMouseMoveEventTimerFired(TimerBase* timer) {
- TRACE_EVENT0("input", "MouseEventManager::fakeMouseMoveEventTimerFired");
- DCHECK(timer == &fake_mouse_move_event_timer_);
-
- RecomputeMouseHoverState();
-}
-
void MouseEventManager::RecomputeMouseHoverStateIfNeeded() {
// |RecomputeMouseHoverState| may set |hover_state_dirty_| to be true.
if (HoverStateDirty()) {
@@ -490,18 +472,12 @@ void MouseEventManager::RecomputeMouseHoverState() {
predicted_events);
}
-void MouseEventManager::CancelFakeMouseMoveEvent() {
- fake_mouse_move_event_timer_.Stop();
-}
-
void MouseEventManager::MarkHoverStateDirty() {
- DCHECK(RuntimeEnabledFeatures::UpdateHoverAtBeginFrameEnabled());
DCHECK(frame_->IsLocalRoot());
hover_state_dirty_ = true;
}
bool MouseEventManager::HoverStateDirty() {
- DCHECK(RuntimeEnabledFeatures::UpdateHoverAtBeginFrameEnabled());
DCHECK(frame_->IsLocalRoot());
return hover_state_dirty_;
}
@@ -588,7 +564,7 @@ WebInputEventResult MouseEventManager::HandleMouseFocus(
}
// The layout needs to be up to date to determine if an element is focusable.
- frame_->GetDocument()->UpdateStyleAndLayout();
+ frame_->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kFocus);
Element* element = element_under_mouse_;
for (; element; element = element->ParentOrShadowHostElement()) {
@@ -638,8 +614,8 @@ WebInputEventResult MouseEventManager::HandleMouseFocus(
// fields before the button click is processed.
if (!page->GetFocusController().SetFocusedElement(
element, frame_,
- FocusParams(SelectionBehaviorOnFocus::kNone, kWebFocusTypeMouse,
- source_capabilities)))
+ FocusParams(SelectionBehaviorOnFocus::kNone,
+ mojom::blink::FocusType::kMouse, source_capabilities)))
return WebInputEventResult::kHandledSystem;
return WebInputEventResult::kNotHandled;
}
@@ -647,10 +623,11 @@ WebInputEventResult MouseEventManager::HandleMouseFocus(
bool MouseEventManager::SlideFocusOnShadowHostIfNecessary(
const Element& element) {
if (Element* delegated_target = element.GetFocusableArea()) {
- // Use WebFocusTypeForward instead of WebFocusTypeMouse here to mean the
+ // Use FocusTypeForward instead of FocusTypeMouse here to mean the
// focus has slided.
delegated_target->focus(FocusParams(SelectionBehaviorOnFocus::kReset,
- kWebFocusTypeForward, nullptr));
+ mojom::blink::FocusType::kForward,
+ nullptr));
return true;
}
return false;
@@ -665,7 +642,6 @@ void MouseEventManager::HandleMouseReleaseEventUpdateStates() {
void MouseEventManager::HandleMousePressEventUpdateStates(
const WebMouseEvent& mouse_event) {
- CancelFakeMouseMoveEvent();
mouse_pressed_ = true;
captures_dragging_ = true;
SetLastKnownMousePosition(mouse_event);
@@ -698,70 +674,21 @@ FloatPoint MouseEventManager::LastKnownMouseScreenPosition() {
void MouseEventManager::SetLastKnownMousePosition(const WebMouseEvent& event) {
is_mouse_position_unknown_ = event.GetType() == WebInputEvent::kMouseLeave;
- last_known_mouse_position_ = event.PositionInWidget();
- last_known_mouse_screen_position_ = event.PositionInScreen();
+ last_known_mouse_position_ = FloatPoint(event.PositionInWidget());
+ last_known_mouse_screen_position_ = FloatPoint(event.PositionInScreen());
}
void MouseEventManager::SetLastMousePositionAsUnknown() {
is_mouse_position_unknown_ = true;
}
-void MouseEventManager::MayUpdateHoverWhenContentUnderMouseChanged(
- MouseEventManager::UpdateHoverReason update_hover_reason) {
- if (RuntimeEnabledFeatures::UpdateHoverAtBeginFrameEnabled() &&
- update_hover_reason ==
- MouseEventManager::UpdateHoverReason::kLayoutOrStyleChanged) {
- return;
- }
-
- if (update_hover_reason ==
- MouseEventManager::UpdateHoverReason::kScrollOffsetChanged &&
- (RuntimeEnabledFeatures::UpdateHoverAtBeginFrameEnabled() ||
- mouse_pressed_)) {
- return;
- }
-
- // TODO(lanwei): When the mouse position is unknown, we do not send the fake
- // mousemove event for now, so we cannot update the hover states and mouse
- // cursor. We should keep the last mouse position somewhere in browser.
- // Please see crbug.com/307375, crbug.com/714378.
- if (is_mouse_position_unknown_)
- return;
-
- // Reschedule the timer, to prevent dispatching mouse move events
- // during a scroll. This avoids a potential source of scroll jank.
- // Or dispatch a fake mouse move to update hover states when the layout
- // changes.
- base::TimeDelta interval =
- update_hover_reason ==
- MouseEventManager::UpdateHoverReason::kScrollOffsetChanged
- ? kFakeMouseMoveIntervalDuringScroll
- : kFakeMouseMoveIntervalAfterLayoutChange;
- fake_mouse_move_event_timer_.StartOneShot(interval, FROM_HERE);
-}
-
-void MouseEventManager::MayUpdateHoverAfterScroll(
- const FloatRect& scroller_rect_in_frame) {
- LocalFrameView* view = frame_->View();
- if (!view)
- return;
-
- if (!scroller_rect_in_frame.Contains(
- view->ViewportToFrame(last_known_mouse_position_)))
- return;
-
- MayUpdateHoverWhenContentUnderMouseChanged(
- MouseEventManager::UpdateHoverReason::kScrollOffsetChanged);
-}
-
WebInputEventResult MouseEventManager::HandleMousePressEvent(
const MouseEventWithHitTestResults& event) {
TRACE_EVENT0("blink", "MouseEventManager::handleMousePressEvent");
ResetDragSource();
- CancelFakeMouseMoveEvent();
- frame_->GetDocument()->UpdateStyleAndLayout();
+ frame_->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kInput);
bool single_click = event.Event().click_count <= 1;
@@ -927,7 +854,7 @@ WebInputEventResult MouseEventManager::HandleMouseDraggedEvent(
return WebInputEventResult::kNotHandled;
layout_object = parent->GetLayoutObject();
- if (!layout_object || !layout_object->IsListBox())
+ if (!layout_object || !IsListBox(layout_object))
return WebInputEventResult::kNotHandled;
}
@@ -947,7 +874,8 @@ WebInputEventResult MouseEventManager::HandleMouseDraggedEvent(
if (AutoscrollController* controller =
scroll_manager_->GetAutoscrollController()) {
// Avoid updating the lifecycle unless it's possible to autoscroll.
- layout_object->GetFrameView()->UpdateAllLifecyclePhasesExceptPaint();
+ layout_object->GetFrameView()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kScroll);
// The lifecycle update above may have invalidated the previous layout.
layout_object = target_node->GetLayoutObject();
@@ -1078,7 +1006,7 @@ bool MouseEventManager::TryStartDrag(
// TODO(editing-dev): The use of
// updateStyleAndLayoutIgnorePendingStylesheets needs to be audited. See
// http://crbug.com/590369 for more details.
- frame_->GetDocument()->UpdateStyleAndLayout();
+ frame_->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kInput);
if (IsInPasswordField(
frame_->Selection().ComputeVisibleSelectionInDOMTree().Start()))
return false;
@@ -1281,7 +1209,7 @@ void MouseEventManager::SetMousePressNode(Node* node) {
}
void MouseEventManager::SetClickElement(Element* element) {
- SetContext(element ? element->ownerDocument() : nullptr);
+ SetDocument(element ? element->ownerDocument() : nullptr);
click_element_ = element;
mouse_down_element_ = element;
}
@@ -1294,8 +1222,4 @@ bool MouseEventManager::MouseDownMayStartDrag() {
return mouse_down_may_start_drag_;
}
-bool MouseEventManager::FakeMouseMovePending() const {
- return fake_mouse_move_event_timer_.IsActive();
-}
-
} // namespace blink
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 161ab34ce59..b237c0660b9 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
@@ -6,8 +6,8 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_INPUT_MOUSE_EVENT_MANAGER_H_
#include "base/macros.h"
+#include "third_party/blink/public/common/input/web_mouse_event.h"
#include "third_party/blink/public/platform/web_input_event_result.h"
-#include "third_party/blink/public/platform/web_mouse_event.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/synchronous_mutation_observer.h"
#include "third_party/blink/renderer/core/input/boundary_event_dispatcher.h"
@@ -39,9 +39,7 @@ class CORE_EXPORT MouseEventManager final
public:
MouseEventManager(LocalFrame&, ScrollManager&);
virtual ~MouseEventManager();
- void Trace(blink::Visitor*) override;
-
- enum class UpdateHoverReason { kScrollOffsetChanged, kLayoutOrStyleChanged };
+ void Trace(Visitor*) override;
WebInputEventResult DispatchMouseEvent(EventTarget*,
const AtomicString&,
@@ -90,13 +88,6 @@ class CORE_EXPORT MouseEventManager final
const HitTestResult&,
InputDeviceCapabilities* source_capabilities);
- void FakeMouseMoveEventTimerFired(TimerBase*);
-
- void CancelFakeMouseMoveEvent();
- void MayUpdateHoverWhenContentUnderMouseChanged(
- MouseEventManager::UpdateHoverReason);
- void MayUpdateHoverAfterScroll(const FloatRect&);
-
void SetLastKnownMousePosition(const WebMouseEvent&);
void SetLastMousePositionAsUnknown();
@@ -155,8 +146,6 @@ class CORE_EXPORT MouseEventManager final
bool MouseDownMayStartDrag();
- bool FakeMouseMovePending() const;
-
void RecomputeMouseHoverStateIfNeeded();
void RecomputeMouseHoverState();
@@ -189,9 +178,9 @@ class CORE_EXPORT MouseEventManager final
const String& canvas_region_id,
const WebMouseEvent&,
bool check_for_listener);
- Member<MouseEventManager> mouse_event_manager_;
+ MouseEventManager* mouse_event_manager_;
const WebMouseEvent* web_mouse_event_;
- Member<EventTarget> exited_target_;
+ EventTarget* exited_target_;
String canvas_region_id_;
DISALLOW_COPY_AND_ASSIGN(MouseEventBoundaryEventDispatcher);
};
@@ -260,8 +249,6 @@ class CORE_EXPORT MouseEventManager final
// update hover when this is true.
bool hover_state_dirty_ = false;
- TaskRunnerTimer<MouseEventManager> fake_mouse_move_event_timer_;
-
DISALLOW_COPY_AND_ASSIGN(MouseEventManager);
};
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 9a3074af898..8b5976c1893 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
@@ -5,7 +5,7 @@
#include "third_party/blink/renderer/core/input/mouse_wheel_event_manager.h"
#include "build/build_config.h"
-#include "third_party/blink/public/platform/web_mouse_wheel_event.h"
+#include "third_party/blink/public/common/input/web_mouse_wheel_event.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/events/wheel_event.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
@@ -15,14 +15,38 @@
#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/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"
+#include "third_party/blink/renderer/platform/wtf/deque.h"
namespace blink {
-MouseWheelEventManager::MouseWheelEventManager(LocalFrame& frame)
- : frame_(frame), wheel_target_(nullptr) {}
-void MouseWheelEventManager::Trace(blink::Visitor* visitor) {
+namespace {
+
+gfx::Vector2dF ResolveMouseWheelPercentToWheelDelta(
+ const WebMouseWheelEvent& event) {
+ DCHECK(event.delta_units == ui::ScrollGranularity::kScrollByPercentage);
+ // TODO (dlibby): OS scroll settings need to be factored into this.
+ // Note that this value is negative because we're converting from wheel
+ // ticks to wheel delta pixel. Wheel ticks are negative for scrolling down,
+ // but the delta must be positive.
+ constexpr float percent_mouse_wheel_ticks_multiplier = -100.f;
+ return gfx::Vector2dF(
+ event.wheel_ticks_x * percent_mouse_wheel_ticks_multiplier,
+ event.wheel_ticks_y * percent_mouse_wheel_ticks_multiplier);
+}
+
+} // namespace
+
+MouseWheelEventManager::MouseWheelEventManager(LocalFrame& frame,
+ ScrollManager& scroll_manager)
+ : frame_(frame), wheel_target_(nullptr), scroll_manager_(scroll_manager) {}
+
+void MouseWheelEventManager::Trace(Visitor* visitor) {
visitor->Trace(frame_);
visitor->Trace(wheel_target_);
+ visitor->Trace(scroll_manager_);
}
void MouseWheelEventManager::Clear() {
@@ -79,7 +103,13 @@ WebInputEventResult MouseWheelEventManager::HandleWheelEvent(
if (wheel_target_) {
WheelEvent* dom_event =
- WheelEvent::Create(event, wheel_target_->GetDocument().domWindow());
+ (event.delta_units == ui::ScrollGranularity::kScrollByPercentage)
+ ? WheelEvent::Create(event,
+ ResolveMouseWheelPercentToWheelDelta(event),
+ wheel_target_->GetDocument().domWindow())
+ : WheelEvent::Create(event,
+ wheel_target_->GetDocument().domWindow());
+
// The event handler might remove |wheel_target_| from DOM so we should get
// this value now (see https://crbug.com/857013).
bool should_enforce_vertical_scroll =
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 80f2fb721b4..57b361ca4b4 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
@@ -7,6 +7,7 @@
#include "base/macros.h"
#include "third_party/blink/public/platform/web_input_event_result.h"
+#include "third_party/blink/renderer/core/input/scroll_manager.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
@@ -21,8 +22,8 @@ class WebMouseWheelEvent;
class MouseWheelEventManager final
: public GarbageCollected<MouseWheelEventManager> {
public:
- explicit MouseWheelEventManager(LocalFrame&);
- void Trace(blink::Visitor*);
+ explicit MouseWheelEventManager(LocalFrame&, ScrollManager&);
+ void Trace(Visitor*);
void Clear();
@@ -37,6 +38,7 @@ class MouseWheelEventManager final
const Member<LocalFrame> frame_;
Member<Node> wheel_target_;
+ Member<ScrollManager> scroll_manager_;
DISALLOW_COPY_AND_ASSIGN(MouseWheelEventManager);
};
diff --git a/chromium/third_party/blink/renderer/core/input/overscroll_behavior_test.cc b/chromium/third_party/blink/renderer/core/input/overscroll_behavior_test.cc
index 06b33633d96..d054a8a497a 100644
--- a/chromium/third_party/blink/renderer/core/input/overscroll_behavior_test.cc
+++ b/chromium/third_party/blink/renderer/core/input/overscroll_behavior_test.cc
@@ -73,8 +73,8 @@ void OverscrollBehaviorTest::ScrollBegin(double hint_x, double hint_y) {
WebGestureEvent event(WebInputEvent::kGestureScrollBegin,
WebInputEvent::kNoModifiers, base::TimeTicks::Now(),
WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(WebFloatPoint(20, 20));
- event.SetPositionInScreen(WebFloatPoint(20, 20));
+ event.SetPositionInWidget(gfx::PointF(20, 20));
+ event.SetPositionInScreen(gfx::PointF(20, 20));
event.data.scroll_begin.delta_x_hint = -hint_x;
event.data.scroll_begin.delta_y_hint = -hint_y;
event.data.scroll_begin.pointer_count = 1;
@@ -86,8 +86,8 @@ void OverscrollBehaviorTest::ScrollUpdate(double delta_x, double delta_y) {
WebGestureEvent event(WebInputEvent::kGestureScrollUpdate,
WebInputEvent::kNoModifiers, base::TimeTicks::Now(),
WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(WebFloatPoint(20, 20));
- event.SetPositionInScreen(WebFloatPoint(20, 20));
+ event.SetPositionInWidget(gfx::PointF(20, 20));
+ event.SetPositionInScreen(gfx::PointF(20, 20));
event.data.scroll_update.delta_x = -delta_x;
event.data.scroll_update.delta_y = -delta_y;
event.SetFrameScale(1);
@@ -98,8 +98,8 @@ void OverscrollBehaviorTest::ScrollEnd() {
WebGestureEvent event(WebInputEvent::kGestureScrollEnd,
WebInputEvent::kNoModifiers, base::TimeTicks::Now(),
WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(WebFloatPoint(20, 20));
- event.SetPositionInScreen(WebFloatPoint(20, 20));
+ event.SetPositionInWidget(gfx::PointF(20, 20));
+ event.SetPositionInScreen(gfx::PointF(20, 20));
GetDocument().GetFrame()->GetEventHandler().HandleGestureScrollEvent(event);
}
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 c6c044bd7c4..6a68b124069 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
@@ -6,7 +6,7 @@
#include "base/auto_reset.h"
#include "base/metrics/field_trial_params.h"
-#include "third_party/blink/public/platform/web_touch_event.h"
+#include "third_party/blink/public/common/input/web_touch_event.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/dom/events/event_path.h"
#include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
@@ -104,7 +104,7 @@ void PointerEventManager::Clear() {
dispatching_pointer_id_ = 0;
}
-void PointerEventManager::Trace(blink::Visitor* visitor) {
+void PointerEventManager::Trace(Visitor* visitor) {
visitor->Trace(frame_);
visitor->Trace(element_under_pointer_);
visitor->Trace(pointer_capture_target_);
@@ -366,8 +366,8 @@ void PointerEventManager::AdjustTouchPointerEvent(
HitTestRequest::kRetargetForInert;
LocalFrame& root_frame = frame_->LocalFrameRoot();
// TODO(szager): Shouldn't this be PositionInScreen() ?
- PhysicalOffset hit_test_point =
- PhysicalOffset::FromFloatPointRound(pointer_event.PositionInWidget());
+ PhysicalOffset hit_test_point = PhysicalOffset::FromFloatPointRound(
+ FloatPoint(pointer_event.PositionInWidget()));
hit_test_point -= PhysicalOffset(hit_rect_size * 0.5f);
HitTestLocation location(PhysicalRect(hit_test_point, hit_rect_size));
HitTestResult hit_test_result =
@@ -381,7 +381,8 @@ void PointerEventManager::AdjustTouchPointerEvent(
pointer_event.SetPositionInWidget(adjusted_point.X(), adjusted_point.Y());
frame_->GetEventHandler().CacheTouchAdjustmentResult(
- pointer_event.unique_touch_event_id, pointer_event.PositionInWidget());
+ pointer_event.unique_touch_event_id,
+ FloatPoint(pointer_event.PositionInWidget()));
}
bool PointerEventManager::ShouldFilterEvent(PointerEvent* pointer_event) {
@@ -424,7 +425,7 @@ PointerEventManager::ComputePointerEventTarget(
HitTestRequest::kActive | HitTestRequest::kRetargetForInert;
HitTestLocation location(frame_->View()->ConvertFromRootFrame(
PhysicalOffset::FromFloatPointRound(
- web_pointer_event.PositionInWidget())));
+ FloatPoint(web_pointer_event.PositionInWidget()))));
HitTestResult hit_test_tesult =
frame_->GetEventHandler().HitTestResultAtLocation(location, hit_type);
Element* target = hit_test_tesult.InnerElement();
@@ -706,8 +707,8 @@ WebInputEventResult PointerEventManager::DirectDispatchMousePointerEvent(
return result;
}
pointer_event_factory_.SetLastPosition(
- pointer_event_factory_.GetPointerEventId(event), event.PositionInScreen(),
- event.GetType());
+ pointer_event_factory_.GetPointerEventId(event),
+ FloatPoint(event.PositionInScreen()), event.GetType());
return WebInputEventResult::kHandledSuppressed;
}
@@ -876,6 +877,9 @@ bool PointerEventManager::GetPointerCaptureState(
PointerId pointer_id,
Element** pointer_capture_target,
Element** pending_pointer_capture_target) {
+ DCHECK(pointer_capture_target);
+ DCHECK(pending_pointer_capture_target);
+
PointerCapturingMap::const_iterator it;
it = pointer_capture_target_.find(pointer_id);
@@ -885,10 +889,8 @@ bool PointerEventManager::GetPointerCaptureState(
Element* pending_pointercapture_target_temp =
(it != pending_pointer_capture_target_.end()) ? it->value : nullptr;
- if (pointer_capture_target)
- *pointer_capture_target = pointer_capture_target_temp;
- if (pending_pointer_capture_target)
- *pending_pointer_capture_target = pending_pointercapture_target_temp;
+ *pointer_capture_target = pointer_capture_target_temp;
+ *pending_pointer_capture_target = pending_pointercapture_target_temp;
return pointer_capture_target_temp != pending_pointercapture_target_temp;
}
@@ -916,8 +918,9 @@ Element* PointerEventManager::ProcessCaptureAndPositionOfPointerEvent(
void PointerEventManager::ProcessPendingPointerCapture(
PointerEvent* pointer_event) {
- Element* pointer_capture_target;
- Element* pending_pointer_capture_target;
+ Element* pointer_capture_target = nullptr;
+ Element* pending_pointer_capture_target = nullptr;
+
const PointerId pointer_id = pointer_event->pointerId();
const bool is_capture_changed = GetPointerCaptureState(
pointer_id, &pointer_capture_target, &pending_pointer_capture_target);
@@ -1084,9 +1087,9 @@ void PointerEventManager::SetLastPointerPositionForFrameBoundary(
pointer_event_factory_.RemoveLastPosition(pointer_id);
} else if (!last_target || new_target->GetDocument().GetFrame() !=
last_target->GetDocument().GetFrame()) {
- pointer_event_factory_.SetLastPosition(pointer_id,
- web_pointer_event.PositionInScreen(),
- web_pointer_event.GetType());
+ pointer_event_factory_.SetLastPosition(
+ pointer_id, FloatPoint(web_pointer_event.PositionInScreen()),
+ web_pointer_event.GetType());
}
}
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 2de86c5e63c..95816c902f1 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
@@ -6,8 +6,8 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_INPUT_POINTER_EVENT_MANAGER_H_
#include "base/macros.h"
+#include "third_party/blink/public/common/input/web_pointer_properties.h"
#include "third_party/blink/public/platform/web_input_event_result.h"
-#include "third_party/blink/public/platform/web_pointer_properties.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/events/pointer_event.h"
#include "third_party/blink/renderer/core/events/pointer_event_factory.h"
@@ -28,7 +28,7 @@ class CORE_EXPORT PointerEventManager final
: public GarbageCollected<PointerEventManager> {
public:
PointerEventManager(LocalFrame&, MouseEventManager&);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
// 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(blink::Visitor* visitor) { visitor->Trace(target); }
+ void Trace(Visitor* visitor) { visitor->Trace(target); }
Member<Element> target;
EventTargetAttributes() : target(nullptr) {}
EventTargetAttributes(Element* target) : target(target) {}
@@ -149,8 +149,8 @@ class CORE_EXPORT PointerEventManager final
EventTarget* related_target,
const AtomicString&,
bool check_for_listener);
- Member<PointerEventManager> pointer_event_manager_;
- Member<PointerEvent> pointer_event_;
+ PointerEventManager* pointer_event_manager_;
+ PointerEvent* pointer_event_;
DISALLOW_COPY_AND_ASSIGN(PointerEventBoundaryEventDispatcher);
};
@@ -248,7 +248,7 @@ class CORE_EXPORT PointerEventManager final
// See "PREVENT MOUSE EVENT flag" in the spec:
// https://w3c.github.io/pointerevents/#compatibility-mapping-with-mouse-events
bool prevent_mouse_event_for_pointer_type_
- [static_cast<size_t>(WebPointerProperties::PointerType::kLastEntry) + 1];
+ [static_cast<size_t>(WebPointerProperties::PointerType::kMaxValue) + 1];
// Set upon scrolling starts when sending a pointercancel, prevents PE
// dispatches for non-hovering pointers until all of them become inactive.
diff --git a/chromium/third_party/blink/renderer/core/input/pointer_event_manager_test.cc b/chromium/third_party/blink/renderer/core/input/pointer_event_manager_test.cc
index c2a164bbbb1..cd7acb67c50 100644
--- a/chromium/third_party/blink/renderer/core/input/pointer_event_manager_test.cc
+++ b/chromium/third_party/blink/renderer/core/input/pointer_event_manager_test.cc
@@ -82,8 +82,8 @@ class PointerEventManagerTest : public SimTest {
WebPointerEvent CreateTestPointerEvent(
WebInputEvent::Type type,
WebPointerProperties::PointerType pointer_type,
- WebFloatPoint position_in_widget = WebFloatPoint(100, 100),
- WebFloatPoint position_in_screen = WebFloatPoint(100, 100),
+ gfx::PointF position_in_widget = gfx::PointF(100, 100),
+ gfx::PointF position_in_screen = gfx::PointF(100, 100),
int movement_x = 0,
int movement_y = 0,
float width = 1,
@@ -97,7 +97,7 @@ class PointerEventManagerTest : public SimTest {
return event;
}
WebMouseEvent CreateTestMouseEvent(WebInputEvent::Type type,
- const WebFloatPoint& coordinates) {
+ const gfx::PointF& coordinates) {
WebMouseEvent event(type, coordinates, coordinates,
WebPointerProperties::Button::kLeft, 0,
WebInputEvent::kLeftButtonDown,
@@ -125,7 +125,7 @@ TEST_F(PointerEventManagerTest, HasPointerCapture) {
ExceptionState exception(nullptr, ExceptionState::kExecutionContext, "", "");
GetEventHandler().HandleMousePressEvent(
- CreateTestMouseEvent(WebInputEvent::kMouseDown, WebFloatPoint(100, 100)));
+ CreateTestMouseEvent(WebInputEvent::kMouseDown, gfx::PointF(100, 100)));
ASSERT_FALSE(
GetDocument().body()->hasPointerCapture(PointerEventFactory::kMouseId));
@@ -136,7 +136,7 @@ TEST_F(PointerEventManagerTest, HasPointerCapture) {
GetDocument().body()->hasPointerCapture(PointerEventFactory::kMouseId));
GetEventHandler().HandleMouseMoveEvent(
- CreateTestMouseEvent(WebInputEvent::kMouseMove, WebFloatPoint(200, 200)),
+ CreateTestMouseEvent(WebInputEvent::kMouseMove, gfx::PointF(200, 200)),
Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
ASSERT_TRUE(
@@ -171,7 +171,7 @@ TEST_F(PointerEventManagerTest, PointerCancelsOfAllTypes) {
{}, {}));
GetEventHandler().HandleMousePressEvent(
- CreateTestMouseEvent(WebInputEvent::kMouseDown, WebFloatPoint(100, 100)));
+ CreateTestMouseEvent(WebInputEvent::kMouseDown, gfx::PointF(100, 100)));
ASSERT_EQ(callback->mouseEventCount(), 0);
ASSERT_EQ(callback->touchEventCount(), 0);
@@ -194,7 +194,7 @@ TEST_F(PointerEventManagerTest, PointerCancelsOfAllTypes) {
ASSERT_EQ(callback->penEventCount(), 1);
GetEventHandler().HandleMouseMoveEvent(
- CreateTestMouseEvent(WebInputEvent::kMouseMove, WebFloatPoint(200, 200)),
+ CreateTestMouseEvent(WebInputEvent::kMouseMove, gfx::PointF(200, 200)),
Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
ASSERT_EQ(callback->mouseEventCount(), 1);
@@ -218,8 +218,8 @@ TEST_F(PointerEventManagerTest, PointerEventCoordinates) {
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::kPointerDown,
WebPointerProperties::PointerType::kTouch,
- WebFloatPoint(150, 200), WebFloatPoint(100, 50),
- 10, 10, 16, 24),
+ gfx::PointF(150, 200), gfx::PointF(100, 50), 10,
+ 10, 16, 24),
{}, {}));
ASSERT_EQ(callback->last_client_x_, 75);
@@ -253,8 +253,8 @@ TEST_F(PointerEventManagerTest, PointerEventMovements) {
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::kPointerMove,
WebPointerProperties::PointerType::kMouse,
- WebFloatPoint(150, 210), WebFloatPoint(100, 50),
- 10, 10),
+ gfx::PointF(150, 210), gfx::PointF(100, 50), 10,
+ 10),
{}, {}));
// The first pointermove event has movement_x/y 0.
ASSERT_EQ(callback->last_screen_x_, 100);
@@ -265,8 +265,8 @@ TEST_F(PointerEventManagerTest, PointerEventMovements) {
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::kPointerMove,
WebPointerProperties::PointerType::kMouse,
- WebFloatPoint(150, 200), WebFloatPoint(132, 29),
- 10, 10),
+ gfx::PointF(150, 200), gfx::PointF(132, 29), 10,
+ 10),
{}, {}));
// pointermove event movement = event.screenX/Y - last_event.screenX/Y.
ASSERT_EQ(callback->last_screen_x_, 132);
@@ -277,8 +277,8 @@ TEST_F(PointerEventManagerTest, PointerEventMovements) {
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::kPointerMove,
WebPointerProperties::PointerType::kMouse,
- WebFloatPoint(150, 210),
- WebFloatPoint(113.8, 32.7), 10, 10),
+ gfx::PointF(150, 210), gfx::PointF(113.8, 32.7),
+ 10, 10),
{}, {}));
// fractional screen coordinates result in fractional movement.
ASSERT_FLOAT_EQ(callback->last_screen_x_, 113.8);
@@ -295,8 +295,8 @@ TEST_F(PointerEventManagerTest, PointerEventMovements) {
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::kPointerMove,
WebPointerProperties::PointerType::kMouse,
- WebFloatPoint(150, 210),
- WebFloatPoint(100, 16.25), 1024, -8765),
+ gfx::PointF(150, 210), gfx::PointF(100, 16.25),
+ 1024, -8765),
{}, {}));
ASSERT_EQ(callback->last_screen_x_, 100);
ASSERT_EQ(callback->last_screen_y_, 16.25);
@@ -323,7 +323,7 @@ TEST_F(PointerEventManagerTest, PointerEventSmallFractionMovements) {
WebPointerEvent pointer_event = CreateTestPointerEvent(
WebInputEvent::kPointerMove, WebPointerProperties::PointerType::kMouse,
- WebFloatPoint(150, 210), WebFloatPoint(113.8, 32.7), 0, 0);
+ gfx::PointF(150, 210), gfx::PointF(113.8, 32.7), 0, 0);
WebView().MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(pointer_event));
ASSERT_FLOAT_EQ(callback->last_movement_x_, 0);
@@ -368,8 +368,8 @@ TEST_F(PointerEventManagerTest, PointerRawUpdateMovements) {
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::kPointerRawUpdate,
WebPointerProperties::PointerType::kMouse,
- WebFloatPoint(150, 210), WebFloatPoint(100, 50),
- 10, 10),
+ gfx::PointF(150, 210), gfx::PointF(100, 50), 10,
+ 10),
{}, {}));
// The first pointerrawupdate event has movement_x/y 0.
ASSERT_EQ(callback->last_screen_x_, 100);
@@ -380,8 +380,8 @@ TEST_F(PointerEventManagerTest, PointerRawUpdateMovements) {
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::kPointerRawUpdate,
WebPointerProperties::PointerType::kMouse,
- WebFloatPoint(150, 200), WebFloatPoint(132, 29),
- 10, 10),
+ gfx::PointF(150, 200), gfx::PointF(132, 29), 10,
+ 10),
{}, {}));
// pointerrawupdate event movement = event.screenX/Y - last_event.screenX/Y.
ASSERT_EQ(callback->last_screen_x_, 132);
@@ -392,8 +392,8 @@ TEST_F(PointerEventManagerTest, PointerRawUpdateMovements) {
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::kPointerMove,
WebPointerProperties::PointerType::kMouse,
- WebFloatPoint(150, 200), WebFloatPoint(144, 30),
- 10, 10),
+ gfx::PointF(150, 200), gfx::PointF(144, 30), 10,
+ 10),
{}, {}));
// First pointermove, have 0 movements.
ASSERT_EQ(callback->last_screen_x_, 144);
@@ -404,8 +404,8 @@ TEST_F(PointerEventManagerTest, PointerRawUpdateMovements) {
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::kPointerRawUpdate,
WebPointerProperties::PointerType::kMouse,
- WebFloatPoint(150, 200), WebFloatPoint(142, 32),
- 10, 10),
+ gfx::PointF(150, 200), gfx::PointF(142, 32), 10,
+ 10),
{}, {}));
// pointerrawupdate event's movement is independent from pointermoves.
ASSERT_EQ(callback->last_screen_x_, 142);
@@ -428,7 +428,7 @@ TEST_F(PointerEventManagerTest, PointerUnadjustedMovement) {
WebPointerEvent event = CreateTestPointerEvent(
WebInputEvent::kPointerMove, WebPointerProperties::PointerType::kMouse,
- WebFloatPoint(150, 210), WebFloatPoint(100, 50), 120, -321);
+ gfx::PointF(150, 210), gfx::PointF(100, 50), 120, -321);
event.is_raw_movement_event = true;
WebView().MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(event, {}, {}));
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 b9945841fef..a887b7dd737 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(blink::Visitor* visitor) {
+void ScrollManager::Trace(Visitor* visitor) {
visitor->Trace(frame_);
visitor->Trace(scroll_gesture_handling_node_);
visitor->Trace(previous_gesture_scrolled_node_);
@@ -205,7 +205,7 @@ bool ScrollManager::CanScroll(const ScrollState& scroll_state,
// so ensure it gets added to the scroll chain. See LTHI::ApplyScroll for the
// equivalent behavior in CC. Node::NativeApplyScroll contains a special
// handler for this case.
- if (current_node.GetLayoutBox()->IsLayoutView() &&
+ if (IsA<LayoutView>(current_node.GetLayoutBox()) &&
current_node.GetDocument().GetFrame()->IsMainFrame()) {
return true;
}
@@ -235,7 +235,7 @@ bool ScrollManager::CanScroll(const ScrollState& scroll_state,
return clamped_offset != current_offset;
}
-bool ScrollManager::LogicalScroll(ScrollDirection direction,
+bool ScrollManager::LogicalScroll(mojom::blink::ScrollDirection direction,
ScrollGranularity granularity,
Node* start_node,
Node* mouse_press_node) {
@@ -256,7 +256,7 @@ bool ScrollManager::LogicalScroll(ScrollDirection direction,
Document& document = node->GetDocument();
- document.UpdateStyleAndLayout();
+ document.UpdateStyleAndLayout(DocumentUpdateReason::kScroll);
Deque<DOMNodeId> scroll_chain;
std::unique_ptr<ScrollStateData> scroll_state_data =
@@ -279,15 +279,20 @@ bool ScrollManager::LogicalScroll(ScrollDirection direction,
ScrollableArea* scrollable_area = ScrollableArea::GetForScrolling(box);
DCHECK(scrollable_area);
- ScrollOffset delta = ToScrollDelta(physical_direction, 1);
+ ScrollOffset delta =
+ ToScrollDelta(physical_direction,
+ ScrollableArea::DirectionBasedScrollDelta(granularity));
delta.Scale(scrollable_area->ScrollStep(granularity, kHorizontalScrollbar),
scrollable_area->ScrollStep(granularity, kVerticalScrollbar));
// Pressing the arrow key is considered as a scroll with intended direction
- // only. Pressing the PgUp/PgDn key is considered as a scroll with intended
- // direction and end position. Pressing the Home/End key is considered as a
- // scroll with intended end position only.
+ // only (this results in kScrollByLine or kScrollByPercentage, depending on
+ // REF::PercentBasedScrollingEnabled). Pressing the PgUp/PgDn key is
+ // considered as a scroll with intended direction and end position. Pressing
+ // the Home/End key is considered as a scroll with intended end position
+ // only.
switch (granularity) {
- case ScrollGranularity::kScrollByLine: {
+ case ScrollGranularity::kScrollByLine:
+ case ScrollGranularity::kScrollByPercentage: {
if (scrollable_area->SnapForDirection(delta))
return true;
break;
@@ -312,18 +317,17 @@ bool ScrollManager::LogicalScroll(ScrollDirection direction,
NOTREACHED();
}
- ScrollableArea::ScrollCallback callback;
- if (RuntimeEnabledFeatures::UpdateHoverAtBeginFrameEnabled() ||
- RuntimeEnabledFeatures::OverscrollCustomizationEnabled()) {
- callback = ScrollableArea::ScrollCallback(WTF::Bind(
- [](WeakPersistent<ScrollableArea> area) {
- if (area)
- area->OnScrollFinished();
- },
- WrapWeakPersistent(scrollable_area)));
- }
+ ScrollableArea::ScrollCallback callback(WTF::Bind(
+ [](WeakPersistent<ScrollableArea> area) {
+ if (area)
+ area->OnScrollFinished();
+ },
+ WrapWeakPersistent(scrollable_area)));
ScrollResult result = scrollable_area->UserScroll(
- granularity, ToScrollDelta(physical_direction, 1), std::move(callback));
+ granularity,
+ ToScrollDelta(physical_direction,
+ ScrollableArea::DirectionBasedScrollDelta(granularity)),
+ std::move(callback));
if (result.DidScroll())
return true;
@@ -334,14 +338,14 @@ bool ScrollManager::LogicalScroll(ScrollDirection direction,
// TODO(bokan): This should be merged with logicalScroll assuming
// defaultSpaceEventHandler's chaining scroll can be done crossing frames.
-bool ScrollManager::BubblingScroll(ScrollDirection direction,
+bool ScrollManager::BubblingScroll(mojom::blink::ScrollDirection direction,
ScrollGranularity granularity,
Node* starting_node,
Node* mouse_press_node) {
// The layout needs to be up to date to determine if we can scroll. We may be
// here because of an onLoad event, in which case the final layout hasn't been
// performed yet.
- frame_->GetDocument()->UpdateStyleAndLayout();
+ frame_->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kScroll);
// FIXME: enable scroll customization in this case. See crbug.com/410974.
if (LogicalScroll(direction, granularity, starting_node, mouse_press_node))
return true;
@@ -359,8 +363,9 @@ void ScrollManager::CustomizedScroll(ScrollState& scroll_state) {
if (scroll_state.FullyConsumed())
return;
- if (scroll_state.deltaX() || scroll_state.deltaY())
- frame_->GetDocument()->UpdateStyleAndLayout();
+ if (scroll_state.deltaX() || scroll_state.deltaY()) {
+ frame_->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kScroll);
+ }
DCHECK(!current_scroll_chain_.IsEmpty());
@@ -508,7 +513,7 @@ WebInputEventResult ScrollManager::HandleGestureScrollBegin(
if (gesture_event.SourceDevice() == WebGestureDevice::kTouchpad &&
gesture_event.data.scroll_begin.delta_hint_units ==
- ui::input_types::ScrollGranularity::kScrollByPrecisePixel) {
+ ui::ScrollGranularity::kScrollByPrecisePixel) {
UseCounter::Count(document, WebFeature::kScrollByPrecisionTouchPad);
} else if (gesture_event.SourceDevice() == WebGestureDevice::kTouchscreen) {
UseCounter::Count(document, WebFeature::kScrollByTouch);
@@ -589,8 +594,7 @@ WebInputEventResult ScrollManager::HandleGestureScrollUpdate(
std::make_unique<ScrollStateData>();
scroll_state_data->delta_x = delta.Width();
scroll_state_data->delta_y = delta.Height();
- scroll_state_data->delta_granularity =
- static_cast<double>(gesture_event.DeltaUnits());
+ scroll_state_data->delta_granularity = gesture_event.DeltaUnits();
scroll_state_data->velocity_x = velocity.Width();
scroll_state_data->velocity_y = velocity.Height();
scroll_state_data->position_x = position.X();
@@ -659,6 +663,8 @@ void ScrollManager::HandleDeferredGestureScrollEnd(
WebInputEventResult ScrollManager::HandleGestureScrollEnd(
const WebGestureEvent& gesture_event) {
TRACE_EVENT0("input", "ScrollManager::handleGestureScrollEnd");
+ GetPage()->GetBrowserControls().ScrollEnd();
+
Node* node = scroll_gesture_handling_node_;
if (node && node->GetLayoutObject()) {
@@ -703,8 +709,7 @@ WebInputEventResult ScrollManager::HandleGestureScrollEnd(
base::ScopedClosureRunner callback(WTF::Bind(
[](WeakPersistent<LocalFrame> local_frame,
WeakPersistent<ScrollManager> scroll_manager) {
- if (RuntimeEnabledFeatures::UpdateHoverAtBeginFrameEnabled() &&
- local_frame) {
+ if (local_frame) {
local_frame->GetEventHandler().MarkHoverStateDirty();
}
@@ -778,7 +783,7 @@ bool ScrollManager::SnapAtGestureScrollEnd(
std::move(on_finish));
}
-bool ScrollManager::GetSnapFlingInfoAndSetSnapTarget(
+bool ScrollManager::GetSnapFlingInfoAndSetAnimatingSnapTarget(
const gfx::Vector2dF& natural_displacement,
gfx::Vector2dF* out_initial_position,
gfx::Vector2dF* out_target_position) const {
@@ -792,7 +797,8 @@ bool ScrollManager::GetSnapFlingInfoAndSetSnapTarget(
std::unique_ptr<cc::SnapSelectionStrategy> strategy =
cc::SnapSelectionStrategy::CreateForEndAndDirection(
gfx::ScrollOffset(*out_initial_position),
- gfx::ScrollOffset(natural_displacement));
+ gfx::ScrollOffset(natural_displacement),
+ RuntimeEnabledFeatures::FractionalScrollOffsetsEnabled());
base::Optional<FloatPoint> snap_end =
scrollable_area->GetSnapPositionAndSetTarget(*strategy);
if (!snap_end.has_value())
@@ -817,7 +823,7 @@ gfx::Vector2dF ScrollManager::ScrollByForSnapFling(
scroll_state_data->is_in_inertial_phase = true;
scroll_state_data->from_user_input = true;
scroll_state_data->delta_granularity =
- static_cast<double>(ScrollGranularity::kScrollByPrecisePixel);
+ ScrollGranularity::kScrollByPrecisePixel;
scroll_state_data->delta_consumed_for_scroll_sequence =
delta_consumed_for_scroll_sequence_;
auto* scroll_state =
@@ -829,7 +835,7 @@ gfx::Vector2dF ScrollManager::ScrollByForSnapFling(
return gfx::Vector2dF(end_position.X(), end_position.Y());
}
-void ScrollManager::ScrollEndForSnapFling() {
+void ScrollManager::ScrollEndForSnapFling(bool did_finish) {
if (RuntimeEnabledFeatures::OverscrollCustomizationEnabled()) {
if (Node* scroll_end_target = GetScrollEventTarget()) {
scroll_end_target->GetDocument().EnqueueScrollEndEventForNode(
@@ -1096,7 +1102,8 @@ bool ScrollManager::HandleScrollGestureOnResizer(
}
} else if (gesture_event.GetType() == WebInputEvent::kGestureScrollUpdate) {
if (resize_scrollable_area_ && resize_scrollable_area_->InResizeMode()) {
- IntPoint pos = RoundedIntPoint(gesture_event.PositionInRootFrame());
+ IntPoint pos =
+ RoundedIntPoint(FloatPoint(gesture_event.PositionInRootFrame()));
pos.Move(gesture_event.DeltaXInRootFrame(),
gesture_event.DeltaYInRootFrame());
resize_scrollable_area_->Resize(pos, offset_from_resize_corner_);
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 238175996fd..12fd76d1222 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(blink::Visitor*);
+ void Trace(Visitor*);
void Clear();
@@ -62,14 +62,14 @@ class CORE_EXPORT ScrollManager : public GarbageCollected<ScrollManager>,
// granularity - The units that the scroll delta parameter is in.
// startNode - Optional. If provided, start chaining from the given node.
// If not, use the current focus or last clicked node.
- bool LogicalScroll(ScrollDirection,
+ bool LogicalScroll(mojom::blink::ScrollDirection,
ScrollGranularity,
Node* start_node,
Node* mouse_press_node);
// Performs a logical scroll that chains, crossing frames, starting from
// the given node or a reasonable default (focus/last clicked).
- bool BubblingScroll(ScrollDirection,
+ bool BubblingScroll(mojom::blink::ScrollDirection,
ScrollGranularity,
Node* starting_node,
Node* mouse_press_node);
@@ -97,12 +97,12 @@ class CORE_EXPORT ScrollManager : public GarbageCollected<ScrollManager>,
void SetResizeScrollableArea(PaintLayer*, IntPoint);
// SnapFlingClient implementation.
- bool GetSnapFlingInfoAndSetSnapTarget(
+ bool GetSnapFlingInfoAndSetAnimatingSnapTarget(
const gfx::Vector2dF& natural_displacement,
gfx::Vector2dF* out_initial_position,
gfx::Vector2dF* out_target_position) const override;
gfx::Vector2dF ScrollByForSnapFling(const gfx::Vector2dF& delta) override;
- void ScrollEndForSnapFling() override;
+ void ScrollEndForSnapFling(bool did_finish) override;
void RequestAnimationForSnapFling() override;
void AnimateSnapFling(base::TimeTicks monotonic_time);
diff --git a/chromium/third_party/blink/renderer/core/input/scroll_snap_test.cc b/chromium/third_party/blink/renderer/core/input/scroll_snap_test.cc
index a27903abb37..fd8b8a5c7fa 100644
--- a/chromium/third_party/blink/renderer/core/input/scroll_snap_test.cc
+++ b/chromium/third_party/blink/renderer/core/input/scroll_snap_test.cc
@@ -93,8 +93,8 @@ void ScrollSnapTest::ScrollBegin(double x,
WebGestureEvent event(WebInputEvent::kGestureScrollBegin,
WebInputEvent::kNoModifiers, base::TimeTicks::Now(),
WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(WebFloatPoint(x, y));
- event.SetPositionInScreen(WebFloatPoint(x, y));
+ event.SetPositionInWidget(gfx::PointF(x, y));
+ event.SetPositionInScreen(gfx::PointF(x, y));
event.data.scroll_begin.delta_x_hint = hint_x;
event.data.scroll_begin.delta_y_hint = hint_y;
event.data.scroll_begin.pointer_count = 1;
@@ -110,8 +110,8 @@ void ScrollSnapTest::ScrollUpdate(double x,
WebGestureEvent event(WebInputEvent::kGestureScrollUpdate,
WebInputEvent::kNoModifiers, base::TimeTicks::Now(),
WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(WebFloatPoint(x, y));
- event.SetPositionInScreen(WebFloatPoint(x, y));
+ event.SetPositionInWidget(gfx::PointF(x, y));
+ event.SetPositionInScreen(gfx::PointF(x, y));
event.data.scroll_update.delta_x = delta_x;
event.data.scroll_update.delta_y = delta_y;
if (is_in_inertial_phase) {
@@ -127,8 +127,8 @@ void ScrollSnapTest::ScrollEnd(double x, double y, bool is_in_inertial_phase) {
WebGestureEvent event(WebInputEvent::kGestureScrollEnd,
WebInputEvent::kNoModifiers, base::TimeTicks::Now(),
WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(WebFloatPoint(x, y));
- event.SetPositionInScreen(WebFloatPoint(x, y));
+ event.SetPositionInWidget(gfx::PointF(x, y));
+ event.SetPositionInScreen(gfx::PointF(x, y));
event.data.scroll_end.inertial_phase =
is_in_inertial_phase ? WebGestureEvent::InertialPhaseState::kMomentum
: WebGestureEvent::InertialPhaseState::kNonMomentum;
@@ -137,8 +137,8 @@ void ScrollSnapTest::ScrollEnd(double x, double y, bool is_in_inertial_phase) {
void ScrollSnapTest::SetInitialScrollOffset(double x, double y) {
Element* scroller = GetDocument().getElementById("scroller");
- scroller->GetScrollableArea()->ScrollToAbsolutePosition(FloatPoint(x, y),
- kScrollBehaviorAuto);
+ scroller->GetScrollableArea()->ScrollToAbsolutePosition(
+ FloatPoint(x, y), mojom::blink::ScrollBehavior::kAuto);
ASSERT_EQ(scroller->scrollLeft(), x);
ASSERT_EQ(scroller->scrollTop(), y);
}
diff --git a/chromium/third_party/blink/renderer/core/input/touch.cc b/chromium/third_party/blink/renderer/core/input/touch.cc
index 4d7a61f6927..7213f1c835e 100644
--- a/chromium/third_party/blink/renderer/core/input/touch.cc
+++ b/chromium/third_party/blink/renderer/core/input/touch.cc
@@ -25,6 +25,7 @@
#include "third_party/blink/renderer/core/input/touch.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_touch_init.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/paint/paint_layer_scrollable_area.h"
@@ -116,7 +117,7 @@ Touch* Touch::CloneWithNewTarget(EventTarget* event_target) const {
rotation_angle_, force_, region_, absolute_location_);
}
-void Touch::Trace(blink::Visitor* visitor) {
+void Touch::Trace(Visitor* visitor) {
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 35e43807ada..2673b89c6f2 100644
--- a/chromium/third_party/blink/renderer/core/input/touch.h
+++ b/chromium/third_party/blink/renderer/core/input/touch.h
@@ -29,7 +29,6 @@
#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/input/touch_init.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/geometry/float_point.h"
#include "third_party/blink/renderer/platform/geometry/float_size.h"
@@ -39,11 +38,26 @@
namespace blink {
class LocalFrame;
+class TouchInit;
class CORE_EXPORT Touch final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
+ static Touch* Create(LocalFrame* frame,
+ EventTarget* target,
+ int identifier,
+ const FloatPoint& screen_pos,
+ const FloatPoint& page_pos,
+ const FloatSize& radius,
+ float rotation_angle,
+ float force,
+ String region) {
+ return MakeGarbageCollected<Touch>(frame, target, identifier, screen_pos,
+ page_pos, radius, rotation_angle, force,
+ region);
+ }
+
static Touch* Create(const Document& document, const TouchInit* initializer) {
return MakeGarbageCollected<Touch>(document.GetFrame(), initializer);
}
@@ -91,7 +105,7 @@ class CORE_EXPORT Touch final : public ScriptWrappable {
const FloatPoint& ScreenLocation() const { return screen_pos_; }
Touch* CloneWithNewTarget(EventTarget*) const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<EventTarget> target_;
diff --git a/chromium/third_party/blink/renderer/core/input/touch.idl b/chromium/third_party/blink/renderer/core/input/touch.idl
index 223edc2c1d3..c9bddf1c571 100644
--- a/chromium/third_party/blink/renderer/core/input/touch.idl
+++ b/chromium/third_party/blink/renderer/core/input/touch.idl
@@ -26,10 +26,9 @@
// https://w3c.github.io/touch-events/#touch-interface
[
- Constructor(TouchInit initDict),
- ConstructorCallWith=Document,
Exposed=Window
] interface Touch {
+ [CallWith=Document] constructor(TouchInit initDict);
readonly attribute long identifier;
readonly attribute EventTarget target;
readonly attribute double screenX;
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 db2f54aa75d..38be891a9e9 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
@@ -29,8 +29,8 @@
*/
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/input/web_touch_event.h"
#include "third_party/blink/public/platform/web_coalesced_input_event.h"
-#include "third_party/blink/public/platform/web_touch_event.h"
#include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_frame.h"
@@ -66,7 +66,7 @@ class TouchActionTrackingWebWidgetClient
: public frame_test_helpers::TestWebWidgetClient {
public:
TouchActionTrackingWebWidgetClient()
- : action_set_count_(0), action_(TouchAction::kTouchActionAuto) {}
+ : action_set_count_(0), action_(TouchAction::kAuto) {}
// WebWidgetClient methods
void SetTouchAction(TouchAction touch_action) override {
@@ -77,7 +77,7 @@ class TouchActionTrackingWebWidgetClient
// Local methods
void Reset() {
action_set_count_ = 0;
- action_ = TouchAction::kTouchActionAuto;
+ action_ = TouchAction::kAuto;
}
int TouchActionSetCount() { return action_set_count_; }
@@ -217,7 +217,7 @@ WebViewImpl* TouchActionTest::SetupTest(
Document* document =
static_cast<Document*>(web_view->MainFrameImpl()->GetDocument());
document->GetFrame()->View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, kScrollOffset), kProgrammaticScroll);
+ ScrollOffset(0, kScrollOffset), mojom::blink::ScrollType::kProgrammatic);
return web_view;
}
@@ -325,7 +325,7 @@ void TouchActionTest::RunTestOnTree(
<< "Unexpected hit test result " << failure_context_pos
<< " Got element: \""
<< result.InnerElement()
- ->OuterHTMLAsString()
+ ->outerHTML()
.StripWhiteSpace()
.Left(80)
.Ascii()
@@ -342,23 +342,22 @@ void TouchActionTest::RunTestOnTree(
EXPECT_EQ(1, client.TouchActionSetCount()) << failure_context_pos;
if (client.TouchActionSetCount()) {
if (expected_action == "auto") {
- EXPECT_EQ(TouchAction::kTouchActionAuto, client.LastTouchAction())
+ EXPECT_EQ(TouchAction::kAuto, client.LastTouchAction())
<< failure_context_pos;
} else if (expected_action == "none") {
- EXPECT_EQ(TouchAction::kTouchActionNone, client.LastTouchAction())
+ EXPECT_EQ(TouchAction::kNone, client.LastTouchAction())
<< failure_context_pos;
} else if (expected_action == "pan-x") {
- EXPECT_EQ(TouchAction::kTouchActionPanX, client.LastTouchAction())
+ EXPECT_EQ(TouchAction::kPanX, client.LastTouchAction())
<< failure_context_pos;
} else if (expected_action == "pan-y") {
- EXPECT_EQ(TouchAction::kTouchActionPanY, client.LastTouchAction())
+ EXPECT_EQ(TouchAction::kPanY, client.LastTouchAction())
<< failure_context_pos;
} else if (expected_action == "pan-x-y") {
- EXPECT_EQ((TouchAction::kTouchActionPan), client.LastTouchAction())
+ EXPECT_EQ((TouchAction::kPan), client.LastTouchAction())
<< failure_context_pos;
} else if (expected_action == "manipulation") {
- EXPECT_EQ((TouchAction::kTouchActionManipulation),
- client.LastTouchAction())
+ EXPECT_EQ((TouchAction::kManipulation), client.LastTouchAction())
<< failure_context_pos;
} else {
FAIL() << "Unrecognized expected-action " << expected_action << " "
@@ -383,8 +382,8 @@ void TouchActionTest::SendTouchEvent(WebView* web_view,
type,
WebPointerProperties(1, WebPointerProperties::PointerType::kTouch,
WebPointerProperties::Button::kLeft,
- WebFloatPoint(client_point.X(), client_point.Y()),
- WebFloatPoint(client_point.X(), client_point.Y())),
+ gfx::PointF(client_point.X(), client_point.Y()),
+ gfx::PointF(client_point.X(), client_point.Y())),
10.0f, 10.0f);
if (type == WebInputEvent::kPointerCancel)
event.dispatch_type = WebInputEvent::kEventNonBlocking;
diff --git a/chromium/third_party/blink/renderer/core/input/touch_action_util.cc b/chromium/third_party/blink/renderer/core/input/touch_action_util.cc
index 7aea46b6d69..b0c40e12501 100644
--- a/chromium/third_party/blink/renderer/core/input/touch_action_util.cc
+++ b/chromium/third_party/blink/renderer/core/input/touch_action_util.cc
@@ -17,7 +17,7 @@ TouchAction ComputeEffectiveTouchAction(const Node& node) {
if (node.GetComputedStyle())
return node.GetComputedStyle()->GetEffectiveTouchAction();
- return TouchAction::kTouchActionAuto;
+ return TouchAction::kAuto;
}
} // namespace touch_action_util
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 4c3c31ea142..917ba947697 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
@@ -5,8 +5,8 @@
#include "third_party/blink/renderer/core/input/touch_event_manager.h"
#include <memory>
+#include "third_party/blink/public/common/input/web_touch_event.h"
#include "third_party/blink/public/platform/web_coalesced_input_event.h"
-#include "third_party/blink/public/platform/web_touch_event.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
#include "third_party/blink/renderer/core/events/touch_event.h"
@@ -20,7 +20,6 @@
#include "third_party/blink/renderer/core/layout/hit_test_canvas_result.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/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -139,7 +138,7 @@ class ChangedTouches final {
public:
// The touches corresponding to the particular change state this struct
// instance represents.
- Member<TouchList> touches_;
+ TouchList* touches_ = nullptr;
using EventTargetSet = HeapHashSet<Member<EventTarget>>;
// Set of targets involved in m_touches.
@@ -157,10 +156,10 @@ void TouchEventManager::Clear() {
touch_attribute_map_.clear();
last_coalesced_touch_event_ = WebTouchEvent();
suppressing_touchmoves_within_slop_ = false;
- current_touch_action_ = TouchAction::kTouchActionAuto;
+ current_touch_action_ = TouchAction::kAuto;
}
-void TouchEventManager::Trace(blink::Visitor* visitor) {
+void TouchEventManager::Trace(Visitor* visitor) {
visitor->Trace(frame_);
visitor->Trace(touch_sequence_document_);
visitor->Trace(touch_attribute_map_);
@@ -207,18 +206,19 @@ Touch* TouchEventManager::CreateDomTouch(
point_attr->event_.WebPointerEventInRootFrame();
float scale_factor = 1.0f / target_frame->PageZoomFactor();
- FloatPoint document_point =
- target_frame->View()
- ->RootFrameToDocument(transformed_event.PositionInWidget())
- .ScaledBy(scale_factor);
+ FloatPoint document_point = target_frame->View()
+ ->RootFrameToDocument(FloatPoint(
+ transformed_event.PositionInWidget()))
+ .ScaledBy(scale_factor);
FloatSize adjusted_radius =
FloatSize(transformed_event.width / 2.f, transformed_event.height / 2.f)
.ScaledBy(scale_factor);
return MakeGarbageCollected<Touch>(
target_frame, touch_node, point_attr->event_.id,
- transformed_event.PositionInScreen(), document_point, adjusted_radius,
- transformed_event.rotation_angle, transformed_event.force, region_id);
+ FloatPoint(transformed_event.PositionInScreen()), document_point,
+ adjusted_radius, transformed_event.rotation_angle,
+ transformed_event.force, region_id);
}
WebCoalescedInputEvent TouchEventManager::GenerateWebCoalescedInputEvent() {
@@ -395,7 +395,7 @@ TouchEventManager::DispatchTouchEventFromAccumulatdTouchPoints() {
}
// Holds the complete set of touches on the screen.
- auto* touches = MakeGarbageCollected<TouchList>();
+ TouchList* touches = TouchList::Create();
// A different view on the 'touches' list above, filtered and grouped by
// event target. Used for the |targetTouches| list in the JS event.
@@ -423,7 +423,7 @@ TouchEventManager::DispatchTouchEventFromAccumulatdTouchPoints() {
TargetTouchesHeapMap::iterator target_touches_iterator =
touches_by_target.find(touch_target);
if (target_touches_iterator == touches_by_target.end()) {
- touches_by_target.Set(touch_target, MakeGarbageCollected<TouchList>());
+ touches_by_target.Set(touch_target, TouchList::Create());
target_touches_iterator = touches_by_target.find(touch_target);
}
@@ -444,10 +444,8 @@ TouchEventManager::DispatchTouchEventFromAccumulatdTouchPoints() {
// for further discussion about the TouchStationary state.
if (!touch_point_attribute->stale_ && known_target) {
size_t event_type_idx = event_type - WebInputEvent::kPointerTypeFirst;
- if (!changed_touches[event_type_idx].touches_) {
- changed_touches[event_type_idx].touches_ =
- MakeGarbageCollected<TouchList>();
- }
+ if (!changed_touches[event_type_idx].touches_)
+ changed_touches[event_type_idx].touches_ = TouchList::Create();
changed_touches[event_type_idx].touches_->Append(touch);
changed_touches[event_type_idx].targets_.insert(touch_target);
}
@@ -474,7 +472,7 @@ TouchEventManager::DispatchTouchEventFromAccumulatdTouchPoints() {
EventTarget* touch_event_target = event_target;
TouchEvent* touch_event = TouchEvent::Create(
coalesced_event, touches, touches_by_target.at(touch_event_target),
- changed_touches[action_idx].touches_.Get(), event_name,
+ changed_touches[action_idx].touches_, event_name,
touch_event_target->ToNode()->GetDocument().domWindow(),
current_touch_action_);
@@ -536,7 +534,7 @@ void TouchEventManager::UpdateTouchAttributeMapsForPointerDown(
if (touch_sequence_document_->GetFrame()) {
HitTestLocation location(PhysicalOffset::FromFloatPointRound(
touch_sequence_document_->GetFrame()->View()->ConvertFromRootFrame(
- event.PositionInWidget())));
+ FloatPoint(event.PositionInWidget()))));
result = event_handling_util::HitTestResultInFrame(
touch_sequence_document_->GetFrame(), location, hit_type);
Node* node = result.InnerNode();
@@ -580,9 +578,9 @@ void TouchEventManager::UpdateTouchAttributeMapsForPointerDown(
if (should_enforce_vertical_scroll_ &&
HasEventHandlerInAncestorPath(
touch_node, EventHandlerRegistry::kTouchStartOrMoveEventBlocking)) {
- delayed_effective_touch_action_ = delayed_effective_touch_action_.value_or(
- TouchAction::kTouchActionAuto) &
- effective_touch_action;
+ delayed_effective_touch_action_ =
+ delayed_effective_touch_action_.value_or(TouchAction::kAuto) &
+ effective_touch_action;
}
if (!delayed_effective_touch_action_) {
frame_->GetPage()->GetChromeClient().SetTouchAction(frame_,
@@ -683,7 +681,7 @@ WebInputEventResult TouchEventManager::FlushEvents() {
void TouchEventManager::AllTouchesReleasedCleanup() {
touch_sequence_document_.Clear();
- current_touch_action_ = TouchAction::kTouchActionAuto;
+ current_touch_action_ = TouchAction::kAuto;
last_coalesced_touch_event_ = WebTouchEvent();
// Ideally, we should have DCHECK(!delayed_effective_touch_action_) but we do
// we do actually get here from HandleTouchPoint(). Supposedly, if there has
@@ -705,7 +703,7 @@ WebInputEventResult TouchEventManager::EnsureVerticalScrollIsPossible(
event_result == WebInputEventResult::kHandledApplication;
if (prevent_defaulted && delayed_effective_touch_action_) {
// Make sure that only vertical scrolling is permitted.
- *delayed_effective_touch_action_ &= TouchAction::kTouchActionPanY;
+ *delayed_effective_touch_action_ &= TouchAction::kPanY;
}
if (delayed_effective_touch_action_) {
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 f55565f273c..693f2d93743 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
@@ -6,10 +6,10 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_INPUT_TOUCH_EVENT_MANAGER_H_
#include "base/macros.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/platform/web_coalesced_input_event.h"
#include "third_party/blink/public/platform/web_input_event_result.h"
-#include "third_party/blink/public/platform/web_pointer_event.h"
-#include "third_party/blink/public/platform/web_touch_event.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/events/pointer_event_factory.h"
#include "third_party/blink/renderer/core/input/event_handling_util.h"
@@ -31,7 +31,7 @@ class CORE_EXPORT TouchEventManager final
public:
explicit TouchEventManager(LocalFrame&);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
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(blink::Visitor* visitor) { visitor->Trace(target_); }
+ void Trace(Visitor* visitor) { visitor->Trace(target_); }
TouchPointAttributes() = default;
explicit TouchPointAttributes(WebPointerEvent event)
diff --git a/chromium/third_party/blink/renderer/core/input/touch_event_manager_test.cc b/chromium/third_party/blink/renderer/core/input/touch_event_manager_test.cc
index f97b5883944..255b908701f 100644
--- a/chromium/third_party/blink/renderer/core/input/touch_event_manager_test.cc
+++ b/chromium/third_party/blink/renderer/core/input/touch_event_manager_test.cc
@@ -28,7 +28,7 @@ class TouchEventManagerTest : public SimTest {
type,
WebPointerProperties(1, WebPointerProperties::PointerType::kTouch,
WebPointerProperties::Button::kLeft,
- WebFloatPoint(100, 100), WebFloatPoint(100, 100)),
+ gfx::PointF(100, 100), gfx::PointF(100, 100)),
1, 1);
event.SetFrameScale(1);
return 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 16eb89ecd6f..68b6002a8b5 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(blink::Visitor* visitor) {
+void TouchList::Trace(Visitor* visitor) {
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 54d05380ec8..602c47f46ca 100644
--- a/chromium/third_party/blink/renderer/core/input/touch_list.h
+++ b/chromium/third_party/blink/renderer/core/input/touch_list.h
@@ -38,6 +38,8 @@ class CORE_EXPORT TouchList final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
+ static TouchList* Create() { return MakeGarbageCollected<TouchList>(); }
+
static TouchList* Create(const HeapVector<Member<Touch>>& touches) {
TouchList* list = MakeGarbageCollected<TouchList>();
list->values_.AppendVector(touches);
@@ -58,7 +60,7 @@ class CORE_EXPORT TouchList final : public ScriptWrappable {
void Append(Touch* touch) { values_.push_back(touch); }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 8ca55e96c4d..a61b241165b 100644
--- a/chromium/third_party/blink/renderer/core/inspector/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/inspector/BUILD.gn
@@ -58,6 +58,10 @@ blink_core_sources("inspector") {
"inspector_history.h",
"inspector_io_agent.cc",
"inspector_io_agent.h",
+ "inspector_issue.cc",
+ "inspector_issue.h",
+ "inspector_issue_storage.cc",
+ "inspector_issue_storage.h",
"inspector_layer_tree_agent.cc",
"inspector_layer_tree_agent.h",
"inspector_log_agent.cc",
@@ -92,6 +96,8 @@ blink_core_sources("inspector") {
"inspector_trace_events.h",
"legacy_dom_snapshot_agent.cc",
"legacy_dom_snapshot_agent.h",
+ "locale_controller.cc",
+ "locale_controller.h",
"main_thread_debugger.cc",
"main_thread_debugger.h",
"network_resources_data.cc",
@@ -187,9 +193,7 @@ inspector_protocol_generate("protocol_sources") {
"inspector/protocol/WebAudio.h",
]
- deps = [
- "//third_party/blink/public/devtools_protocol:protocol_version",
- ]
+ deps = [ "//third_party/blink/public/devtools_protocol:protocol_version" ]
}
# Compiles the sources generated above.
@@ -217,7 +221,5 @@ jumbo_source_set("generated") {
"//v8",
]
- public_deps = [
- "//third_party/inspector_protocol:crdtp",
- ]
+ public_deps = [ "//third_party/inspector_protocol:crdtp" ]
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/DEPS b/chromium/third_party/blink/renderer/core/inspector/DEPS
index cefbff3283e..56e80d50889 100644
--- a/chromium/third_party/blink/renderer/core/inspector/DEPS
+++ b/chromium/third_party/blink/renderer/core/inspector/DEPS
@@ -1,10 +1,13 @@
include_rules = [
+ "+base/i18n/rtl.h",
"+base/time/time_override.h",
- "+base/sampling_heap_profiler/module_cache.h",
+ "+base/profiler/module_cache.h",
"+base/sampling_heap_profiler/poisson_allocation_sampler.h",
"+base/sampling_heap_profiler/sampling_heap_profiler.h",
# for base::GetUniqueIdForProcess
"+base/process/process_handle.h",
"+cc/trees/transform_node.h",
"+third_party/inspector_protocol/crdtp",
+ "+third_party/icu/source/common/unicode/locid.h",
+ "+net/http/http_status_code.h",
]
diff --git a/chromium/third_party/blink/renderer/core/inspector/OWNERS b/chromium/third_party/blink/renderer/core/inspector/OWNERS
index 182cfa9ca81..00f97c75693 100644
--- a/chromium/third_party/blink/renderer/core/inspector/OWNERS
+++ b/chromium/third_party/blink/renderer/core/inspector/OWNERS
@@ -1,7 +1,9 @@
alph@chromium.org
caseq@chromium.org
dgozman@chromium.org
+petermarshall@chromium.org
pfeldman@chromium.org
+sigurds@chromium.org
yangguo@chromium.org
# COMPONENT: Platform>DevTools
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 5c144b89328..52ac9e3ea56 100644
--- a/chromium/third_party/blink/renderer/core/inspector/console_message.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/console_message.cc
@@ -4,85 +4,64 @@
#include "third_party/blink/renderer/core/inspector/console_message.h"
+#include <memory>
+#include <utility>
+
#include "third_party/blink/public/web/web_console_message.h"
-#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/inspector/identifiers_factory.h"
#include "third_party/blink/renderer/core/workers/worker_thread.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
-// static
-ConsoleMessage* ConsoleMessage::CreateForRequest(
- mojom::ConsoleMessageSource source,
- mojom::ConsoleMessageLevel level,
- const String& message,
- const String& url,
- DocumentLoader* loader,
- uint64_t request_identifier) {
- ConsoleMessage* console_message = ConsoleMessage::Create(
- source, level, message, SourceLocation::Capture(url, 0, 0));
- console_message->request_identifier_ =
+ConsoleMessage::ConsoleMessage(mojom::ConsoleMessageSource source,
+ mojom::ConsoleMessageLevel level,
+ const String& message,
+ const String& url,
+ DocumentLoader* loader,
+ uint64_t request_identifier)
+ : ConsoleMessage(source,
+ level,
+ message,
+ SourceLocation::Capture(url, 0, 0)) {
+ request_identifier_ =
IdentifiersFactory::RequestId(loader, request_identifier);
- return console_message;
}
-// static
-ConsoleMessage* ConsoleMessage::Create(
- mojom::ConsoleMessageSource source,
- mojom::ConsoleMessageLevel level,
- const String& message,
- std::unique_ptr<SourceLocation> location) {
- return MakeGarbageCollected<ConsoleMessage>(source, level, message,
- std::move(location));
-}
-
-// static
-ConsoleMessage* ConsoleMessage::Create(mojom::ConsoleMessageSource source,
- mojom::ConsoleMessageLevel level,
- const String& message) {
- return ConsoleMessage::Create(source, level, message,
- SourceLocation::Capture());
-}
-
-// static
-ConsoleMessage* ConsoleMessage::CreateFromWorker(
- mojom::ConsoleMessageLevel level,
- const String& message,
- std::unique_ptr<SourceLocation> location,
- WorkerThread* worker_thread) {
- ConsoleMessage* console_message =
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kWorker, level,
- message, std::move(location));
- console_message->worker_id_ =
+ConsoleMessage::ConsoleMessage(mojom::ConsoleMessageLevel level,
+ const String& message,
+ std::unique_ptr<SourceLocation> location,
+ WorkerThread* worker_thread)
+ : ConsoleMessage(mojom::ConsoleMessageSource::kWorker,
+ level,
+ message,
+ std::move(location)) {
+ worker_id_ =
IdentifiersFactory::IdFromToken(worker_thread->GetDevToolsWorkerToken());
- return console_message;
}
-ConsoleMessage* ConsoleMessage::CreateFromWebConsoleMessage(
- const WebConsoleMessage& message,
- LocalFrame* local_frame) {
- mojom::ConsoleMessageSource message_source =
- message.nodes.empty() ? mojom::ConsoleMessageSource::kOther
- : mojom::ConsoleMessageSource::kRecommendation;
-
- ConsoleMessage* console_message = ConsoleMessage::Create(
- message_source, message.level, message.text,
- std::make_unique<SourceLocation>(message.url, message.line_number,
- message.column_number, nullptr));
-
+ConsoleMessage::ConsoleMessage(const WebConsoleMessage& message,
+ LocalFrame* local_frame)
+ : ConsoleMessage(message.nodes.empty()
+ ? mojom::ConsoleMessageSource::kOther
+ : mojom::ConsoleMessageSource::kRecommendation,
+ message.level,
+ message.text,
+ std::make_unique<SourceLocation>(message.url,
+ message.line_number,
+ message.column_number,
+ nullptr)) {
if (local_frame) {
Vector<DOMNodeId> nodes;
for (const WebNode& web_node : message.nodes)
nodes.push_back(DOMNodeIds::IdForNode(&(*web_node)));
- console_message->SetNodes(local_frame, std::move(nodes));
+ SetNodes(local_frame, std::move(nodes));
}
-
- return console_message;
}
ConsoleMessage::ConsoleMessage(mojom::ConsoleMessageSource source,
@@ -94,7 +73,9 @@ ConsoleMessage::ConsoleMessage(mojom::ConsoleMessageSource source,
message_(message),
location_(std::move(location)),
timestamp_(base::Time::Now().ToDoubleT() * 1000.0),
- frame_(nullptr) {}
+ frame_(nullptr) {
+ DCHECK(location_);
+}
ConsoleMessage::~ConsoleMessage() = default;
@@ -142,7 +123,7 @@ void ConsoleMessage::SetNodes(LocalFrame* frame, Vector<DOMNodeId> nodes) {
nodes_ = std::move(nodes);
}
-void ConsoleMessage::Trace(blink::Visitor* visitor) {
+void ConsoleMessage::Trace(Visitor* visitor) {
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 87abf1e7ec4..e0cbd48922c 100644
--- a/chromium/third_party/blink/renderer/core/inspector/console_message.h
+++ b/chromium/third_party/blink/renderer/core/inspector/console_message.h
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_CONSOLE_MESSAGE_H_
#include "third_party/blink/public/mojom/devtools/console_message.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -23,39 +24,26 @@ struct WebConsoleMessage;
class CORE_EXPORT ConsoleMessage final
: public GarbageCollected<ConsoleMessage> {
public:
- // Location must be non-null.
- static ConsoleMessage* Create(mojom::ConsoleMessageSource,
- mojom::ConsoleMessageLevel,
- const String& message,
- std::unique_ptr<SourceLocation>);
-
- // Shortcut when location is unknown. Captures current location.
- static ConsoleMessage* Create(mojom::ConsoleMessageSource,
- mojom::ConsoleMessageLevel,
- const String& message);
-
- // This method captures current location if available.
- static ConsoleMessage* CreateForRequest(mojom::ConsoleMessageSource,
- mojom::ConsoleMessageLevel,
- const String& message,
- const String& url,
- DocumentLoader*,
- uint64_t request_identifier);
-
- // This creates message from WorkerMessageSource.
- static ConsoleMessage* CreateFromWorker(mojom::ConsoleMessageLevel,
- const String& message,
- std::unique_ptr<SourceLocation>,
- WorkerThread*);
-
+ // This constructor captures current location if available.
+ ConsoleMessage(mojom::ConsoleMessageSource,
+ mojom::ConsoleMessageLevel,
+ const String& message,
+ const String& url,
+ DocumentLoader*,
+ uint64_t request_identifier);
+ // Creates message from WorkerMessageSource.
+ ConsoleMessage(mojom::ConsoleMessageLevel,
+ const String& message,
+ std::unique_ptr<SourceLocation>,
+ WorkerThread*);
// Creates a ConsoleMessage from a similar WebConsoleMessage.
- static ConsoleMessage* CreateFromWebConsoleMessage(const WebConsoleMessage&,
- LocalFrame*);
-
+ ConsoleMessage(const WebConsoleMessage&, LocalFrame*);
+ // If provided, source_location must be non-null.
ConsoleMessage(mojom::ConsoleMessageSource,
mojom::ConsoleMessageLevel,
const String& message,
- std::unique_ptr<SourceLocation>);
+ std::unique_ptr<SourceLocation> source_location =
+ SourceLocation::Capture());
~ConsoleMessage();
SourceLocation* Location() const;
@@ -69,7 +57,7 @@ class CORE_EXPORT ConsoleMessage final
Vector<DOMNodeId>& Nodes();
void SetNodes(LocalFrame*, Vector<DOMNodeId> nodes);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
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 6345f58cb41..12f61d2d6b9 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(blink::Visitor* visitor) {
+void ConsoleMessageStorage::Trace(Visitor* visitor) {
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 d43ec11b9c5..9a4e903043f 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(blink::Visitor*);
+ void Trace(Visitor*);
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 5403152e336..ef5ac5bd4ee 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,9 +106,7 @@ DevToolsEmulator::DevToolsEmulator(WebViewImpl* web_view)
web_view->GetPage()->GetSettings().GetCookieEnabled()),
document_cookie_disabled_(false) {}
-DevToolsEmulator::~DevToolsEmulator() = default;
-
-void DevToolsEmulator::Trace(blink::Visitor* visitor) {}
+void DevToolsEmulator::Trace(Visitor* visitor) {}
void DevToolsEmulator::SetTextAutosizingEnabled(bool enabled) {
embedder_text_autosizing_enabled_ = enabled;
@@ -253,10 +251,10 @@ TransformationMatrix DevToolsEmulator::EnableDeviceEmulation(
if (web_view_->MainFrameImpl()) {
if (Document* document =
web_view_->MainFrameImpl()->GetFrame()->GetDocument())
- document->MediaQueryAffectingValueChanged();
+ document->MediaQueryAffectingValueChanged(MediaValueChange::kOther);
}
- if (params.viewport_offset.x >= 0)
+ if (params.viewport_offset.x() >= 0)
return ForceViewport(params.viewport_offset, params.viewport_scale);
else
return ResetViewport();
@@ -279,7 +277,7 @@ void DevToolsEmulator::DisableDeviceEmulation() {
if (web_view_->MainFrameImpl()) {
if (Document* document =
web_view_->MainFrameImpl()->GetFrame()->GetDocument())
- document->MediaQueryAffectingValueChanged();
+ document->MediaQueryAffectingValueChanged(MediaValueChange::kOther);
}
TransformationMatrix matrix = ResetViewport();
@@ -300,6 +298,7 @@ void DevToolsEmulator::EnableMobileEmulation() {
RuntimeEnabledFeatures::MobileLayoutThemeEnabled();
RuntimeEnabledFeatures::SetMobileLayoutThemeEnabled(true);
ComputedStyle::InvalidateInitialStyle();
+ Page::PlatformColorsChanged();
web_view_->GetPage()->GetSettings().SetForceAndroidOverlayScrollbar(true);
web_view_->GetPage()->GetSettings().SetViewportStyle(
WebViewportStyle::kMobile);
@@ -337,6 +336,7 @@ void DevToolsEmulator::DisableMobileEmulation() {
RuntimeEnabledFeatures::SetMobileLayoutThemeEnabled(
is_mobile_layout_theme_enabled_);
ComputedStyle::InvalidateInitialStyle();
+ Page::PlatformColorsChanged();
web_view_->GetPage()->GetSettings().SetForceAndroidOverlayScrollbar(false);
web_view_->GetPage()->GetSettings().SetViewportEnabled(false);
web_view_->GetPage()->GetSettings().SetViewportMetaEnabled(false);
@@ -363,12 +363,12 @@ void DevToolsEmulator::DisableMobileEmulation() {
}
TransformationMatrix DevToolsEmulator::ForceViewport(
- const WebFloatPoint& position,
+ const gfx::PointF& position,
float scale) {
if (!viewport_override_)
viewport_override_ = ViewportOverride();
- viewport_override_->position = FloatPoint(position.x, position.y);
+ viewport_override_->position = FloatPoint(position);
viewport_override_->scale = scale;
// Move the correct (scaled) content area to show in the top left of the
@@ -402,9 +402,9 @@ void DevToolsEmulator::ApplyViewportOverride(TransformationMatrix* transform) {
web_view_->MainFrame()->IsWebLocalFrame()
? web_view_->MainFrame()->ToWebLocalFrame()->GetScrollOffset()
: WebSize();
- WebFloatPoint visual_offset = web_view_->VisualViewportOffset();
- float scroll_x = scroll_offset.width + visual_offset.x;
- float scroll_y = scroll_offset.height + visual_offset.y;
+ gfx::PointF visual_offset = web_view_->VisualViewportOffset();
+ float scroll_x = scroll_offset.width + visual_offset.x();
+ float scroll_y = scroll_offset.height + visual_offset.y();
transform->Translate(-viewport_override_->position.X() + scroll_x,
-viewport_override_->position.Y() + scroll_y);
@@ -423,15 +423,19 @@ TransformationMatrix DevToolsEmulator::ComputeRootLayerTransform() {
return transform;
}
-void DevToolsEmulator::OverrideVisibleRect(const IntSize& viewport_size,
- IntRect* visible_rect) const {
- if (!viewport_override_)
+void DevToolsEmulator::OverrideVisibleRect(
+ const IntSize& viewport_size,
+ IntRect* visible_rect_in_frame) const {
+ WebLocalFrameImpl* frame = web_view_->MainFrameImpl();
+ if (!viewport_override_ || !frame)
return;
FloatSize scaled_viewport_size(viewport_size);
scaled_viewport_size.Scale(1. / viewport_override_->scale);
- *visible_rect = EnclosingIntRect(
+ IntRect visible_rect_in_document = EnclosingIntRect(
FloatRect(viewport_override_->position, scaled_viewport_size));
+ *visible_rect_in_frame =
+ frame->GetFrameView()->DocumentToFrame(visible_rect_in_document);
}
float DevToolsEmulator::InputEventsScaleForEmulation() {
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 4d7da9b85e8..67aeaa49857 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
@@ -8,7 +8,6 @@
#include <memory>
#include "base/optional.h"
#include "third_party/blink/public/platform/pointer_properties.h"
-#include "third_party/blink/public/platform/web_float_point.h"
#include "third_party/blink/public/platform/web_viewport_style.h"
#include "third_party/blink/public/web/web_device_emulation_params.h"
#include "third_party/blink/renderer/core/core_export.h"
@@ -16,6 +15,10 @@
#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
+namespace gfx {
+class PointF;
+} // namespace gfx
+
namespace blink {
class IntRect;
@@ -25,8 +28,7 @@ class CORE_EXPORT DevToolsEmulator final
: public GarbageCollected<DevToolsEmulator> {
public:
explicit DevToolsEmulator(WebViewImpl*);
- ~DevToolsEmulator();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
// Settings overrides.
void SetTextAutosizingEnabled(bool);
@@ -76,7 +78,7 @@ class CORE_EXPORT DevToolsEmulator final
// device metics.
float InputEventsScaleForEmulation();
- TransformationMatrix ForceViewportForTesting(const WebFloatPoint& position,
+ TransformationMatrix ForceViewportForTesting(const gfx::PointF& position,
float scale) {
return ForceViewport(position, scale);
}
@@ -89,8 +91,7 @@ class CORE_EXPORT DevToolsEmulator final
// Enables viewport override and returns the emulation transform to be used.
// The |position| is in CSS pixels, and |scale| is relative to a page scale of
// 1.0.
- TransformationMatrix ForceViewport(const WebFloatPoint& position,
- float scale);
+ TransformationMatrix ForceViewport(const gfx::PointF& position, float scale);
// Disables viewport override and returns the emulation transform to be used.
TransformationMatrix ResetViewport();
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 0818c266bec..5a0c2c3eb6c 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(devtools_host_);
ContextMenuProvider::Trace(visitor);
}
@@ -109,7 +109,7 @@ DevToolsHost::DevToolsHost(InspectorFrontendClient* client,
DevToolsHost::~DevToolsHost() = default;
-void DevToolsHost::Trace(blink::Visitor* visitor) {
+void DevToolsHost::Trace(Visitor* visitor) {
visitor->Trace(client_);
visitor->Trace(frontend_frame_);
visitor->Trace(menu_provider_);
@@ -156,8 +156,8 @@ float DevToolsHost::zoomFactor() {
}
void DevToolsHost::copyText(const String& text) {
- SystemClipboard::GetInstance().WritePlainText(text);
- SystemClipboard::GetInstance().CommitWrite();
+ frontend_frame_->GetSystemClipboard()->WritePlainText(text);
+ frontend_frame_->GetSystemClipboard()->CommitWrite();
}
static String EscapeUnicodeNonCharacters(const String& str) {
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 276e8120427..f139c8ac9b9 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 99f3b2750f1..32d3f155bf3 100644
--- a/chromium/third_party/blink/renderer/core/inspector/devtools_agent.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/devtools_agent.cc
@@ -7,8 +7,9 @@
#include <v8-inspector.h>
#include <memory>
-#include "third_party/blink/renderer/core/dom/document.h"
+#include "base/bind_helpers.h"
#include "third_party/blink/renderer/core/exported/web_dev_tools_agent_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/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/inspector/devtools_session.h"
@@ -20,8 +21,20 @@
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/core/workers/worker_thread.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+namespace WTF {
+
+using StatePtr = mojo::StructPtr<blink::mojom::blink::DevToolsSessionState>;
+template <>
+struct CrossThreadCopier<StatePtr>
+ : public CrossThreadCopierByValuePassThrough<StatePtr> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+} // namespace WTF
+
namespace blink {
namespace {
@@ -34,8 +47,8 @@ DevToolsAgent* DevToolsAgentFromContext(ExecutionContext* execution_context) {
->GetWorkerInspectorController()
->GetDevToolsAgent();
}
- if (auto* document = DynamicTo<Document>(execution_context)) {
- LocalFrame* frame = document->GetFrame();
+ if (auto* window = DynamicTo<LocalDOMWindow>(execution_context)) {
+ LocalFrame* frame = window->GetFrame();
if (!frame)
return nullptr;
WebLocalFrameImpl* web_frame =
@@ -49,6 +62,75 @@ DevToolsAgent* DevToolsAgentFromContext(ExecutionContext* execution_context) {
} // namespace
+class DevToolsAgent::IOAgent : public mojom::blink::DevToolsAgent {
+ public:
+ IOAgent(scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
+ scoped_refptr<InspectorTaskRunner> inspector_task_runner,
+ CrossThreadWeakPersistent<::blink::DevToolsAgent> agent,
+ mojo::PendingReceiver<mojom::blink::DevToolsAgent> receiver)
+ : io_task_runner_(io_task_runner),
+ inspector_task_runner_(inspector_task_runner),
+ agent_(std::move(agent)) {
+ // Binds on the IO thread and receive messages there too. Messages are
+ // posted to the worker thread in a way that interrupts V8 execution. This
+ // is necessary so that AttachDevToolsSession can be called on a worker
+ // which has already started and is stuck in JS, e.g. polling using
+ // Atomics.wait() which is a common pattern.
+ PostCrossThreadTask(
+ *io_task_runner_, FROM_HERE,
+ CrossThreadBindOnce(&IOAgent::BindInterface,
+ CrossThreadUnretained(this), std::move(receiver)));
+ }
+
+ void BindInterface(
+ mojo::PendingReceiver<mojom::blink::DevToolsAgent> receiver) {
+ receiver_.Bind(std::move(receiver), io_task_runner_);
+ }
+
+ void DeleteSoon() { io_task_runner_->DeleteSoon(FROM_HERE, this); }
+
+ ~IOAgent() override = default;
+
+ // mojom::blink::DevToolsAgent implementation.
+ void AttachDevToolsSession(
+ mojo::PendingAssociatedRemote<mojom::blink::DevToolsSessionHost> host,
+ mojo::PendingAssociatedReceiver<mojom::blink::DevToolsSession>
+ main_session,
+ mojo::PendingReceiver<mojom::blink::DevToolsSession> io_session,
+ mojom::blink::DevToolsSessionStatePtr reattach_session_state,
+ bool client_expects_binary_responses,
+ const WTF::String& session_id) override {
+ DCHECK(receiver_.is_bound());
+ inspector_task_runner_->AppendTask(CrossThreadBindOnce(
+ &::blink::DevToolsAgent::AttachDevToolsSessionImpl, agent_,
+ std::move(host), std::move(main_session), std::move(io_session),
+ std::move(reattach_session_state), client_expects_binary_responses,
+ session_id));
+ }
+
+ void InspectElement(const gfx::Point& point) override {
+ // InspectElement on a worker doesn't make sense.
+ NOTREACHED();
+ }
+
+ void ReportChildWorkers(bool report,
+ bool wait_for_debugger,
+ base::OnceClosure callback) override {
+ DCHECK(receiver_.is_bound());
+ inspector_task_runner_->AppendTask(CrossThreadBindOnce(
+ &::blink::DevToolsAgent::ReportChildWorkersPostCallbackToIO, agent_,
+ report, wait_for_debugger, CrossThreadBindOnce(std::move(callback))));
+ }
+
+ private:
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
+ scoped_refptr<InspectorTaskRunner> inspector_task_runner_;
+ CrossThreadWeakPersistent<::blink::DevToolsAgent> agent_;
+ mojo::Receiver<mojom::blink::DevToolsAgent> receiver_{this};
+
+ DISALLOW_COPY_AND_ASSIGN(IOAgent);
+};
+
DevToolsAgent::DevToolsAgent(
Client* client,
InspectedFrames* inspected_frames,
@@ -63,7 +145,7 @@ DevToolsAgent::DevToolsAgent(
DevToolsAgent::~DevToolsAgent() {}
-void DevToolsAgent::Trace(blink::Visitor* visitor) {
+void DevToolsAgent::Trace(Visitor* visitor) {
visitor->Trace(inspected_frames_);
visitor->Trace(probe_sink_);
visitor->Trace(sessions_);
@@ -76,23 +158,25 @@ void DevToolsAgent::Dispose() {
CleanupConnection();
}
-void DevToolsAgent::BindReceiver(
+void DevToolsAgent::BindReceiverForWorker(
mojo::PendingRemote<mojom::blink::DevToolsAgentHost> host_remote,
mojo::PendingReceiver<mojom::blink::DevToolsAgent> receiver,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- DCHECK(!receiver_.is_bound());
DCHECK(!associated_receiver_.is_bound());
- receiver_.Bind(std::move(receiver), std::move(task_runner));
+
host_remote_.Bind(std::move(host_remote));
host_remote_.set_disconnect_handler(
WTF::Bind(&DevToolsAgent::CleanupConnection, WrapWeakPersistent(this)));
+
+ io_agent_ =
+ new IOAgent(io_task_runner_, inspector_task_runner_,
+ WrapCrossThreadWeakPersistent(this), std::move(receiver));
}
void DevToolsAgent::BindReceiver(
mojo::PendingAssociatedRemote<mojom::blink::DevToolsAgentHost> host_remote,
mojo::PendingAssociatedReceiver<mojom::blink::DevToolsAgent> receiver,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- DCHECK(!receiver_.is_bound());
DCHECK(!associated_receiver_.is_bound());
associated_receiver_.Bind(std::move(receiver), std::move(task_runner));
associated_host_remote_.Bind(std::move(host_remote));
@@ -100,34 +184,82 @@ void DevToolsAgent::BindReceiver(
WTF::Bind(&DevToolsAgent::CleanupConnection, WrapWeakPersistent(this)));
}
-void DevToolsAgent::AttachDevToolsSession(
+void DevToolsAgent::AttachDevToolsSessionImpl(
mojo::PendingAssociatedRemote<mojom::blink::DevToolsSessionHost> host,
mojo::PendingAssociatedReceiver<mojom::blink::DevToolsSession>
session_receiver,
mojo::PendingReceiver<mojom::blink::DevToolsSession> io_session_receiver,
mojom::blink::DevToolsSessionStatePtr reattach_session_state,
- bool client_expects_binary_responses) {
+ bool client_expects_binary_responses,
+ const WTF::String& session_id) {
+ TRACE_EVENT0("devtools", "Agent::AttachDevToolsSessionImpl");
client_->DebuggerTaskStarted();
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);
+ client_expects_binary_responses, session_id);
sessions_.insert(session);
client_->DebuggerTaskFinished();
}
-void DevToolsAgent::InspectElement(const WebPoint& point) {
+void DevToolsAgent::AttachDevToolsSession(
+ mojo::PendingAssociatedRemote<mojom::blink::DevToolsSessionHost> host,
+ mojo::PendingAssociatedReceiver<mojom::blink::DevToolsSession>
+ session_receiver,
+ mojo::PendingReceiver<mojom::blink::DevToolsSession> io_session_receiver,
+ mojom::blink::DevToolsSessionStatePtr reattach_session_state,
+ bool client_expects_binary_responses,
+ const WTF::String& session_id) {
+ TRACE_EVENT0("devtools", "Agent::AttachDevToolsSession");
+ if (associated_receiver_.is_bound()) {
+ AttachDevToolsSessionImpl(std::move(host), std::move(session_receiver),
+ std::move(io_session_receiver),
+ std::move(reattach_session_state),
+ client_expects_binary_responses, session_id);
+ } else {
+ io_agent_->AttachDevToolsSession(
+ std::move(host), std::move(session_receiver),
+ std::move(io_session_receiver), std::move(reattach_session_state),
+ client_expects_binary_responses, session_id);
+ }
+}
+
+void DevToolsAgent::InspectElementImpl(const gfx::Point& point) {
client_->InspectElement(point);
}
+void DevToolsAgent::InspectElement(const gfx::Point& point) {
+ if (associated_receiver_.is_bound()) {
+ client_->InspectElement(point);
+ } else {
+ // InspectElement on a worker doesn't make sense.
+ NOTREACHED();
+ }
+}
+
void DevToolsAgent::FlushProtocolNotifications() {
for (auto& session : sessions_)
session->FlushProtocolNotifications();
}
-void DevToolsAgent::ReportChildWorkers(bool report,
- bool wait_for_debugger,
- base::OnceClosure callback) {
+void DevToolsAgent::ReportChildWorkersPostCallbackToIO(
+ bool report,
+ bool wait_for_debugger,
+ CrossThreadOnceClosure callback) {
+ TRACE_EVENT0("devtools", "Agent::ReportChildWorkersPostCallbackToIO");
+ ReportChildWorkersImpl(report, wait_for_debugger, base::DoNothing());
+ // This message originally came from the IOAgent for a worker which means the
+ // response needs to be sent on the IO thread as well, so we post the callback
+ // task back there to be run. In the non-IO case, this callback would be run
+ // synchronously at the end of ReportChildWorkersImpl, so the ordering between
+ // ReportChildWorkers and running the callback is preserved.
+ PostCrossThreadTask(*io_task_runner_, FROM_HERE, std::move(callback));
+}
+
+void DevToolsAgent::ReportChildWorkersImpl(bool report,
+ bool wait_for_debugger,
+ base::OnceClosure callback) {
+ TRACE_EVENT0("devtools", "Agent::ReportChildWorkersImpl");
report_child_workers_ = report;
pause_child_workers_on_start_ = wait_for_debugger;
if (report_child_workers_) {
@@ -138,6 +270,18 @@ void DevToolsAgent::ReportChildWorkers(bool report,
std::move(callback).Run();
}
+void DevToolsAgent::ReportChildWorkers(bool report,
+ bool wait_for_debugger,
+ base::OnceClosure callback) {
+ TRACE_EVENT0("devtools", "Agent::ReportChildWorkers");
+ if (associated_receiver_.is_bound()) {
+ ReportChildWorkersImpl(report, wait_for_debugger, std::move(callback));
+ } else {
+ io_agent_->ReportChildWorkers(report, wait_for_debugger,
+ std::move(callback));
+ }
+}
+
// static
std::unique_ptr<WorkerDevToolsParams> DevToolsAgent::WorkerThreadCreated(
ExecutionContext* parent_context,
@@ -192,7 +336,10 @@ void DevToolsAgent::ReportChildWorker(std::unique_ptr<WorkerData> data) {
}
void DevToolsAgent::CleanupConnection() {
- receiver_.reset();
+ if (io_agent_) {
+ io_agent_->DeleteSoon();
+ io_agent_ = nullptr;
+ }
associated_receiver_.reset();
host_remote_.reset();
associated_host_remote_.reset();
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 78c07bc2bdb..3d387e9f73e 100644
--- a/chromium/third_party/blink/renderer/core/inspector/devtools_agent.h
+++ b/chromium/third_party/blink/renderer/core/inspector/devtools_agent.h
@@ -37,7 +37,7 @@ class CORE_EXPORT DevToolsAgent : public GarbageCollected<DevToolsAgent>,
virtual ~Client() {}
virtual void AttachSession(DevToolsSession*, bool restore) = 0;
virtual void DetachSession(DevToolsSession*) = 0;
- virtual void InspectElement(const WebPoint&) = 0;
+ virtual void InspectElement(const gfx::Point&) = 0;
virtual void DebuggerTaskStarted() = 0;
virtual void DebuggerTaskFinished() = 0;
};
@@ -59,17 +59,25 @@ class CORE_EXPORT DevToolsAgent : public GarbageCollected<DevToolsAgent>,
void Dispose();
void FlushProtocolNotifications();
- void BindReceiver(mojo::PendingRemote<mojom::blink::DevToolsAgentHost>,
- mojo::PendingReceiver<mojom::blink::DevToolsAgent>,
- scoped_refptr<base::SingleThreadTaskRunner>);
+ // For workers, we use the IO thread similar to DevToolsSession::IOSession to
+ // ensure that we can always interrupt a worker that is stuck in JS. We don't
+ // use an associated channel for workers, meaning we don't have the ordering
+ // constraints related to navigation that the non-worker agents have.
+ void BindReceiverForWorker(
+ mojo::PendingRemote<mojom::blink::DevToolsAgentHost>,
+ mojo::PendingReceiver<mojom::blink::DevToolsAgent>,
+ scoped_refptr<base::SingleThreadTaskRunner>);
+ // Used for non-worker agents. These do not use the IO thread like we do for
+ // workers, and they use associated mojo interfaces.
void BindReceiver(
mojo::PendingAssociatedRemote<mojom::blink::DevToolsAgentHost>,
mojo::PendingAssociatedReceiver<mojom::blink::DevToolsAgent>,
scoped_refptr<base::SingleThreadTaskRunner>);
- virtual void Trace(blink::Visitor*);
+ virtual void Trace(Visitor*);
private:
friend class DevToolsSession;
+ class IOAgent;
// mojom::blink::DevToolsAgent implementation.
void AttachDevToolsSession(
@@ -78,12 +86,17 @@ class CORE_EXPORT DevToolsAgent : public GarbageCollected<DevToolsAgent>,
main_session,
mojo::PendingReceiver<mojom::blink::DevToolsSession> io_session,
mojom::blink::DevToolsSessionStatePtr reattach_session_state,
- bool client_expects_binary_responses) override;
- void InspectElement(const WebPoint& point) override;
+ bool client_expects_binary_responses,
+ const WTF::String& session_id) override;
+ void InspectElement(const gfx::Point& point) override;
void ReportChildWorkers(bool report,
bool wait_for_debugger,
base::OnceClosure callback) override;
+ void ReportChildWorkersPostCallbackToIO(bool report,
+ bool wait_for_debugger,
+ CrossThreadOnceClosure callback);
+
struct WorkerData {
KURL url;
mojo::PendingRemote<mojom::blink::DevToolsAgent> agent_remote;
@@ -96,8 +109,20 @@ class CORE_EXPORT DevToolsAgent : public GarbageCollected<DevToolsAgent>,
void CleanupConnection();
+ void AttachDevToolsSessionImpl(
+ mojo::PendingAssociatedRemote<mojom::blink::DevToolsSessionHost>,
+ mojo::PendingAssociatedReceiver<mojom::blink::DevToolsSession>
+ main_session,
+ mojo::PendingReceiver<mojom::blink::DevToolsSession> io_session,
+ mojom::blink::DevToolsSessionStatePtr reattach_session_state,
+ bool client_expects_binary_responses,
+ const WTF::String& session_id);
+ void InspectElementImpl(const gfx::Point& point);
+ void ReportChildWorkersImpl(bool report,
+ bool wait_for_debugger,
+ base::OnceClosure callback);
+
Client* client_;
- mojo::Receiver<mojom::blink::DevToolsAgent> receiver_{this};
mojo::AssociatedReceiver<mojom::blink::DevToolsAgent> associated_receiver_{
this};
mojo::Remote<mojom::blink::DevToolsAgentHost> host_remote_;
@@ -110,6 +135,7 @@ class CORE_EXPORT DevToolsAgent : public GarbageCollected<DevToolsAgent>,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
HashMap<WorkerThread*, std::unique_ptr<WorkerData>>
unreported_child_worker_threads_;
+ IOAgent* io_agent_{nullptr};
bool report_child_workers_ = false;
bool pause_child_workers_on_start_ = false;
};
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 176aad037ad..4ee6a0ea568 100644
--- a/chromium/third_party/blink/renderer/core/inspector/devtools_session.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/devtools_session.cc
@@ -25,27 +25,19 @@
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
#include "third_party/inspector_protocol/crdtp/cbor.h"
+#include "third_party/inspector_protocol/crdtp/dispatch.h"
#include "third_party/inspector_protocol/crdtp/json.h"
namespace blink {
namespace {
const char kV8StateKey[] = "v8";
-bool ShouldInterruptForMethod(const String& method) {
- return method == "Debugger.pause" || method == "Debugger.setBreakpoint" ||
- method == "Debugger.setBreakpointByUrl" ||
- method == "Debugger.removeBreakpoint" ||
- method == "Debugger.setBreakpointsActive" ||
- method == "Performance.getMetrics" || method == "Page.crash" ||
- method == "Runtime.terminateExecution" ||
- method == "Debugger.getStackTrace" ||
- method == "Emulation.setScriptExecutionDisabled";
-}
+const char kSessionId[] = "sessionId";
-Vector<uint8_t> UnwrapMessage(const mojom::blink::DevToolsMessagePtr& message) {
- Vector<uint8_t> unwrap_message;
- unwrap_message.Append(message->data.data(), message->data.size());
- return unwrap_message;
+bool ShouldInterruptForMethod(const String& method) {
+ return method != "Debugger.evaluateOnCallFrame" &&
+ method != "Runtime.evaluate" && method != "Runtime.callFunctionOn" &&
+ method != "Runtime.runScript";
}
std::vector<uint8_t> Get8BitStringFrom(v8_inspector::StringBuffer* msg) {
@@ -82,10 +74,9 @@ class DevToolsSession::IOSession : public mojom::blink::DevToolsSession {
void DeleteSoon() { io_task_runner_->DeleteSoon(FROM_HERE, this); }
// mojom::blink::DevToolsSession implementation.
- void DispatchProtocolCommand(
- int call_id,
- const String& method,
- mojom::blink::DevToolsMessagePtr message) override {
+ void DispatchProtocolCommand(int call_id,
+ const String& method,
+ base::span<const uint8_t> message) override {
TRACE_EVENT_WITH_FLOW1("devtools", "IOSession::DispatchProtocolCommand",
call_id,
TRACE_EVENT_FLAG_FLOW_OUT | TRACE_EVENT_FLAG_FLOW_IN,
@@ -95,14 +86,16 @@ class DevToolsSession::IOSession : public mojom::blink::DevToolsSession {
CHECK(false);
// Post a task to the worker or main renderer thread that will interrupt V8
// and be run immediately. Only methods that do not run JS code are safe.
+ Vector<uint8_t> message_copy;
+ message_copy.Append(message.data(), message.size());
if (ShouldInterruptForMethod(method)) {
inspector_task_runner_->AppendTask(CrossThreadBindOnce(
&::blink::DevToolsSession::DispatchProtocolCommandImpl, session_,
- call_id, method, UnwrapMessage(message)));
+ call_id, method, std::move(message_copy)));
} else {
inspector_task_runner_->AppendTaskDontInterrupt(CrossThreadBindOnce(
&::blink::DevToolsSession::DispatchProtocolCommandImpl, session_,
- call_id, method, UnwrapMessage(message)));
+ call_id, method, std::move(message_copy)));
}
}
@@ -123,15 +116,16 @@ DevToolsSession::DevToolsSession(
main_receiver,
mojo::PendingReceiver<mojom::blink::DevToolsSession> io_receiver,
mojom::blink::DevToolsSessionStatePtr reattach_session_state,
- bool client_expects_binary_responses)
+ bool client_expects_binary_responses,
+ const String& session_id)
: 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=*/{}) {
+ v8_session_state_cbor_(&v8_session_state_, /*default_value=*/{}),
+ session_id_(session_id) {
io_session_ = new IOSession(
agent_->io_task_runner_, agent_->inspector_task_runner_,
WrapCrossThreadWeakPersistent(this), std::move(io_receiver));
@@ -190,25 +184,22 @@ void DevToolsSession::Detach() {
agent_->client_->DebuggerTaskFinished();
}
-void DevToolsSession::FlushProtocolNotifications() {
- flushProtocolNotifications();
-}
-
void DevToolsSession::DispatchProtocolCommand(
int call_id,
const String& method,
- blink::mojom::blink::DevToolsMessagePtr message_ptr) {
- // TODO(petermarshall): Remove the distinction between DevToolsSession and
- // IOSession as we always use IOSession now.
- NOTREACHED();
+ base::span<const uint8_t> message) {
+ TRACE_EVENT_WITH_FLOW1(
+ "devtools", "DevToolsSession::DispatchProtocolCommand", call_id,
+ TRACE_EVENT_FLAG_FLOW_OUT | TRACE_EVENT_FLAG_FLOW_IN, "call_id", call_id);
+ return DispatchProtocolCommandImpl(call_id, method, message);
}
-void DevToolsSession::DispatchProtocolCommandImpl(int call_id,
- const String& method,
- Vector<uint8_t> data) {
+void DevToolsSession::DispatchProtocolCommandImpl(
+ int call_id,
+ const String& method,
+ base::span<const uint8_t> data) {
DCHECK(crdtp::cbor::IsCBORMessage(
crdtp::span<uint8_t>(data.data(), data.size())));
-
TRACE_EVENT_WITH_FLOW1(
"devtools", "DevToolsSession::DispatchProtocolCommandImpl", call_id,
TRACE_EVENT_FLAG_FLOW_OUT | TRACE_EVENT_FLAG_FLOW_IN, "call_id", call_id);
@@ -232,11 +223,10 @@ void DevToolsSession::DispatchProtocolCommandImpl(int call_id,
v8_session_->dispatchProtocolMessage(
v8_inspector::StringView(data.data(), data.size()));
} else {
- std::unique_ptr<protocol::Value> value =
- protocol::Value::parseBinary(data.data(), data.size());
- // Don't pass protocol message further - there is no passthrough.
- inspector_backend_dispatcher_->dispatch(call_id, method, std::move(value),
- protocol::ProtocolMessage());
+ crdtp::Dispatchable dispatchable(crdtp::SpanFrom(data));
+ // This message has already been checked by content::DevToolsSession.
+ DCHECK(dispatchable.ok());
+ inspector_backend_dispatcher_->Dispatch(dispatchable).Run();
}
agent_->client_->DebuggerTaskFinished();
}
@@ -260,15 +250,32 @@ void DevToolsSession::DidCommitLoad(LocalFrame* frame, DocumentLoader*) {
v8_session_->setSkipAllPauses(false);
}
-void DevToolsSession::sendProtocolResponse(
+void DevToolsSession::PaintTiming(Document* document,
+ const char* name,
+ double timestamp) {
+ if (v8_session_ &&
+ agent_->inspected_frames_->Root()->GetDocument() == document) {
+ v8_session_->triggerPreciseCoverageDeltaUpdate(
+ ToV8InspectorStringView(name));
+ }
+}
+
+void DevToolsSession::DomContentLoadedEventFired(LocalFrame* local_frame) {
+ if (v8_session_ && agent_->inspected_frames_->Root() == local_frame) {
+ v8_session_->triggerPreciseCoverageDeltaUpdate(
+ ToV8InspectorStringView("DomContentLoaded"));
+ }
+}
+
+void DevToolsSession::SendProtocolResponse(
int call_id,
std::unique_ptr<protocol::Serializable> message) {
- SendProtocolResponse(call_id, std::move(*message).TakeSerialized());
+ SendProtocolResponse(call_id, message->Serialize());
}
-void DevToolsSession::fallThrough(int call_id,
- const String& method,
- const protocol::ProtocolMessage& message) {
+void DevToolsSession::FallThrough(int call_id,
+ crdtp::span<uint8_t> method,
+ crdtp::span<uint8_t> message) {
// There's no other layer to handle the command.
NOTREACHED();
}
@@ -298,13 +305,13 @@ void DevToolsSession::SendProtocolResponse(int call_id,
call_id, session_state_.TakeUpdates());
}
-void DevToolsSession::sendProtocolNotification(
+void DevToolsSession::SendProtocolNotification(
std::unique_ptr<protocol::Serializable> notification) {
if (IsDetached())
return;
notification_queue_.push_back(WTF::Bind(
[](std::unique_ptr<protocol::Serializable> notification) {
- return std::move(*notification).TakeSerialized();
+ return notification->Serialize();
},
std::move(notification)));
}
@@ -321,6 +328,10 @@ void DevToolsSession::sendNotification(
}
void DevToolsSession::flushProtocolNotifications() {
+ FlushProtocolNotifications();
+}
+
+void DevToolsSession::FlushProtocolNotifications() {
if (IsDetached())
return;
for (wtf_size_t i = 0; i < agents_.size(); i++)
@@ -337,7 +348,7 @@ void DevToolsSession::flushProtocolNotifications() {
notification_queue_.clear();
}
-void DevToolsSession::Trace(blink::Visitor* visitor) {
+void DevToolsSession::Trace(Visitor* visitor) {
visitor->Trace(agent_);
visitor->Trace(agents_);
}
@@ -345,6 +356,12 @@ void DevToolsSession::Trace(blink::Visitor* visitor) {
blink::mojom::blink::DevToolsMessagePtr DevToolsSession::FinalizeMessage(
std::vector<uint8_t> message) const {
std::vector<uint8_t> message_to_send = std::move(message);
+ if (!session_id_.IsEmpty()) {
+ crdtp::Status status = crdtp::cbor::AppendString8EntryToCBORMap(
+ crdtp::SpanFrom(kSessionId), crdtp::SpanFrom(session_id_.Ascii()),
+ &message_to_send);
+ CHECK(status.ok()) << status.ToASCIIString();
+ }
if (!client_expects_binary_responses_) {
std::vector<uint8_t> json;
crdtp::Status status =
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 2dd23490c71..74e91538ed6 100644
--- a/chromium/third_party/blink/renderer/core/inspector/devtools_session.h
+++ b/chromium/third_party/blink/renderer/core/inspector/devtools_session.h
@@ -26,6 +26,7 @@
namespace blink {
class DevToolsAgent;
+class Document;
class DocumentLoader;
class InspectorAgent;
class LocalFrame;
@@ -43,7 +44,8 @@ class CORE_EXPORT DevToolsSession : public GarbageCollected<DevToolsSession>,
main_receiver,
mojo::PendingReceiver<mojom::blink::DevToolsSession> io_receiver,
mojom::blink::DevToolsSessionStatePtr reattach_session_state,
- bool client_expects_binary_responses);
+ bool client_expects_binary_responses,
+ const String& session_id);
~DevToolsSession() override;
void ConnectToV8(v8_inspector::V8Inspector*, int context_group_id);
@@ -51,36 +53,38 @@ class CORE_EXPORT DevToolsSession : public GarbageCollected<DevToolsSession>,
void Append(InspectorAgent*);
void Detach();
- void FlushProtocolNotifications();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
+
+ // protocol::FrontendChannel implementation.
+ void FlushProtocolNotifications() override;
// Core probes.
void DidStartProvisionalLoad(LocalFrame*);
void DidFailProvisionalLoad(LocalFrame*);
void DidCommitLoad(LocalFrame*, DocumentLoader*);
+ void PaintTiming(Document* document, const char* name, double timestamp);
+ void DomContentLoadedEventFired(LocalFrame*);
private:
class IOSession;
// mojom::blink::DevToolsSession implementation.
- void DispatchProtocolCommand(
- int call_id,
- const String& method,
- mojom::blink::DevToolsMessagePtr message) override;
+ void DispatchProtocolCommand(int call_id,
+ const String& method,
+ base::span<const uint8_t> message) override;
void DispatchProtocolCommandImpl(int call_id,
const String& method,
- Vector<uint8_t> message);
+ base::span<const uint8_t> message);
// protocol::FrontendChannel implementation.
- void sendProtocolResponse(
+ void SendProtocolResponse(
int call_id,
std::unique_ptr<protocol::Serializable> message) override;
- void sendProtocolNotification(
+ void SendProtocolNotification(
std::unique_ptr<protocol::Serializable> message) override;
- void fallThrough(int call_id,
- const String& method,
- const protocol::ProtocolMessage& message) override;
- void flushProtocolNotifications() override;
+ void FallThrough(int call_id,
+ crdtp::span<uint8_t> method,
+ crdtp::span<uint8_t> message) override;
// v8_inspector::V8Inspector::Channel implementation.
void sendResponse(
@@ -88,6 +92,7 @@ class CORE_EXPORT DevToolsSession : public GarbageCollected<DevToolsSession>,
std::unique_ptr<v8_inspector::StringBuffer> message) override;
void sendNotification(
std::unique_ptr<v8_inspector::StringBuffer> message) override;
+ void flushProtocolNotifications() override;
bool IsDetached();
void SendProtocolResponse(int call_id, std::vector<uint8_t> message);
@@ -104,13 +109,14 @@ class CORE_EXPORT DevToolsSession : public GarbageCollected<DevToolsSession>,
std::unique_ptr<protocol::UberDispatcher> inspector_backend_dispatcher_;
InspectorSessionState session_state_;
HeapVector<Member<InspectorAgent>> agents_;
- // Notifications are lazily serialized to shift the overhead we spend away
- // from Javascript code that generates many events (e.g., a loop logging to
- // console on every iteration).
+ // Notifications are lazily serialized to shift the serialization overhead
+ // from performance measurements. We may want to revisit this.
+ // See https://bugs.chromium.org/p/chromium/issues/detail?id=1044989#c8
Vector<base::OnceCallback<std::vector<uint8_t>()>> notification_queue_;
const bool client_expects_binary_responses_;
InspectorAgentState v8_session_state_;
InspectorAgentState::Bytes v8_session_state_cbor_;
+ const String session_id_;
DISALLOW_COPY_AND_ASSIGN(DevToolsSession);
};
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 80f56824c3e..a7951fa37b2 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(element_);
InspectorHistory::Action::Trace(visitor);
}
@@ -203,7 +203,7 @@ class DOMEditor::SetAttributeAction final : public InspectorHistory::Action {
return true;
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(node_);
visitor->Trace(next_sibling_);
visitor->Trace(new_node_);
@@ -294,7 +294,7 @@ class DOMEditor::ReplaceWholeTextAction final
return true;
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(text_node_);
InspectorHistory::Action::Trace(visitor);
}
@@ -331,7 +331,7 @@ class DOMEditor::ReplaceChildNodeAction final
return !exception_state.HadException();
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(node_);
InspectorHistory::Action::Trace(visitor);
}
@@ -457,9 +457,10 @@ static Response ToResponse(ExceptionState& exception_state) {
exception_state.CodeAs<DOMExceptionCode>()) +
" "
: g_empty_string;
- return Response::Error(name_prefix + exception_state.Message());
+ String msg = name_prefix + exception_state.Message();
+ return Response::ServerError(msg.Utf8());
}
- return Response::OK();
+ return Response::Success();
}
Response DOMEditor::InsertBefore(ContainerNode* parent_node,
@@ -504,7 +505,7 @@ Response DOMEditor::ReplaceWholeText(Text* text_node, const String& text) {
return ToResponse(exception_state);
}
-void DOMEditor::Trace(blink::Visitor* visitor) {
+void DOMEditor::Trace(Visitor* visitor) {
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 b5261fc77c0..0331991dcbb 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(blink::Visitor*);
+ void Trace(Visitor*);
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 14cd83f18f8..7dc75ee684b 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
@@ -57,23 +57,24 @@
namespace blink {
DOMPatchSupport::DOMPatchSupport(DOMEditor* dom_editor, Document& document)
- : dom_editor_(dom_editor), document_(document) {}
+ : dom_editor_(dom_editor), document_(&document) {}
void DOMPatchSupport::PatchDocument(const String& markup) {
Document* new_document = nullptr;
- DocumentInit init = DocumentInit::Create();
- if (GetDocument().IsHTMLDocument())
+ DocumentInit init =
+ DocumentInit::Create().WithContextDocument(&GetDocument());
+ if (IsA<HTMLDocument>(GetDocument()))
new_document = MakeGarbageCollected<HTMLDocument>(init);
else if (GetDocument().IsSVGDocument())
new_document = XMLDocument::CreateSVG(init);
else if (GetDocument().IsXHTMLDocument())
new_document = XMLDocument::CreateXHTML(init);
- else if (GetDocument().IsXMLDocument())
+ else if (IsA<XMLDocument>(GetDocument()))
new_document = MakeGarbageCollected<XMLDocument>(init);
DCHECK(new_document);
new_document->SetContextFeatures(GetDocument().GetContextFeatures());
- if (!GetDocument().IsHTMLDocument()) {
+ if (!IsA<HTMLDocument>(GetDocument())) {
DocumentParser* parser =
MakeGarbageCollected<XMLDocumentParser>(*new_document, nullptr);
parser->Append(markup);
@@ -119,7 +120,7 @@ Node* DOMPatchSupport::PatchNode(Node* node,
auto* target_element = To<Element>(target_node);
// FIXME: This code should use one of createFragment* in Serialization.h
- if (GetDocument().IsHTMLDocument())
+ if (IsA<HTMLDocument>(GetDocument()))
fragment->ParseHTML(markup, target_element);
else
fragment->ParseXML(markup, target_element);
@@ -132,7 +133,7 @@ Node* DOMPatchSupport::PatchNode(Node* node,
old_list.push_back(CreateDigest(child, nullptr));
// Compose the new list.
- String markup_copy = markup.DeprecatedLower();
+ String markup_copy = markup.LowerASCII();
HeapVector<Member<Digest>> new_list;
for (Node* child = parent_node->firstChild(); child != node;
child = child->nextSibling())
@@ -532,7 +533,7 @@ void DOMPatchSupport::MarkNodeAsUsed(Digest* digest) {
}
}
-void DOMPatchSupport::Digest::Trace(blink::Visitor* visitor) {
+void DOMPatchSupport::Digest::Trace(Visitor* visitor) {
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 fcfb8c3fc2c..e8b2c51187d 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(blink::Visitor*);
+ void Trace(Visitor*);
String sha1_;
String attrs_sha1_;
@@ -86,8 +86,8 @@ class DOMPatchSupport final {
void MarkNodeAsUsed(Digest*);
Document& GetDocument() const { return *document_; }
- Member<DOMEditor> dom_editor_;
- Member<Document> document_;
+ DOMEditor* dom_editor_;
+ Document* document_;
UnusedNodesMap unused_nodes_map_;
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
index f7bcae8e1cb..2f9157c4a22 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspect_tool_highlight.html
+++ b/chromium/third_party/blink/renderer/core/inspector/inspect_tool_highlight.html
@@ -62,6 +62,7 @@ body {
.tooltip-content {
background-color: white;
padding: 5px 8px;
+ border: 1px solid white;
border-radius: 3px;
box-sizing: border-box;
min-width: 100px;
@@ -216,6 +217,36 @@ body {
background-image: url("data:image/svg+xml;charset=UTF-8, %3csvg xmlns='http://www.w3.org/2000/svg' width='16px' height='16px' viewBox='0 0 48 48' fill='%2300a000'%3e%3cpath d='M0 0h48v48H0z' fill='none'/%3e%3cpath d='M18 32.34L9.66 24l-2.83 2.83L18 38l24-24-2.83-2.83z'/%3e%3c/svg%3e");
}
+@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,
+ .element-info-contrast-row {
+ border-color: Highlight;
+ }
+ .dimensions,
+ .element-info-name,
+ .element-info-value-color,
+ .element-info-value-contrast,
+ .element-info-value-text,
+ .material-tag-name,
+ .material-class-name,
+ .material-node-id {
+ color: CanvasText;
+ }
+}
</style>
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 a0f0465825f..866afa057bf 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspect_tools.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspect_tools.cc
@@ -4,11 +4,11 @@
#include "third_party/blink/renderer/core/inspector/inspect_tools.h"
-#include "third_party/blink/public/platform/web_gesture_event.h"
-#include "third_party/blink/public/platform/web_input_event.h"
+#include "third_party/blink/public/common/input/web_gesture_event.h"
+#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/input/web_pointer_event.h"
#include "third_party/blink/public/platform/web_input_event_result.h"
-#include "third_party/blink/public/platform/web_keyboard_event.h"
-#include "third_party/blink/public/platform/web_pointer_event.h"
#include "third_party/blink/public/resources/grit/blink_resources.h"
#include "third_party/blink/renderer/core/css/css_color_value.h"
#include "third_party/blink/renderer/core/css/css_computed_style_declaration.h"
@@ -26,7 +26,9 @@
#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/platform/cursors.h"
#include "third_party/blink/renderer/platform/keyboard_codes.h"
+#include "third_party/inspector_protocol/crdtp/json.h"
namespace blink {
@@ -73,17 +75,17 @@ Node* HoveredNodeForPoint(LocalFrame* frame,
Node* HoveredNodeForEvent(LocalFrame* frame,
const WebGestureEvent& event,
bool ignore_pointer_events_none) {
- return HoveredNodeForPoint(frame,
- RoundedIntPoint(event.PositionInRootFrame()),
- ignore_pointer_events_none);
+ return HoveredNodeForPoint(
+ frame, RoundedIntPoint(FloatPoint(event.PositionInRootFrame())),
+ ignore_pointer_events_none);
}
Node* HoveredNodeForEvent(LocalFrame* frame,
const WebMouseEvent& event,
bool ignore_pointer_events_none) {
- return HoveredNodeForPoint(frame,
- RoundedIntPoint(event.PositionInRootFrame()),
- ignore_pointer_events_none);
+ return HoveredNodeForPoint(
+ frame, RoundedIntPoint(FloatPoint(event.PositionInRootFrame())),
+ ignore_pointer_events_none);
}
Node* HoveredNodeForEvent(LocalFrame* frame,
@@ -91,7 +93,7 @@ Node* HoveredNodeForEvent(LocalFrame* frame,
bool ignore_pointer_events_none) {
WebPointerEvent transformed_point = event.WebPointerEventInRootFrame();
return HoveredNodeForPoint(
- frame, RoundedIntPoint(transformed_point.PositionInWidget()),
+ frame, RoundedIntPoint(FloatPoint(transformed_point.PositionInWidget())),
ignore_pointer_events_none);
}
@@ -113,7 +115,7 @@ SearchingForNodeTool::SearchingForNodeTool(InspectorDOMAgent* dom_agent,
InspectorOverlayAgent::ToHighlightConfig(highlight_config.get());
}
-void SearchingForNodeTool::Trace(blink::Visitor* visitor) {
+void SearchingForNodeTool::Trace(Visitor* visitor) {
InspectTool::Trace(visitor);
visitor->Trace(dom_agent_);
visitor->Trace(hovered_node_);
@@ -337,7 +339,7 @@ void NodeHighlightTool::DrawMatchingSelector() {
}
}
-void NodeHighlightTool::Trace(blink::Visitor* visitor) {
+void NodeHighlightTool::Trace(Visitor* visitor) {
InspectTool::Trace(visitor);
visitor->Trace(node_);
}
@@ -403,7 +405,7 @@ void NearbyDistanceTool::Draw(float scale) {
overlay_->EvaluateInOverlay("drawDistances", highlight.AsProtocolValue());
}
-void NearbyDistanceTool::Trace(blink::Visitor* visitor) {
+void NearbyDistanceTool::Trace(Visitor* visitor) {
InspectTool::Trace(visitor);
visitor->Trace(hovered_node_);
}
@@ -436,14 +438,27 @@ int ScreenshotTool::GetDataResourceId() {
}
void ScreenshotTool::Dispatch(const String& message) {
+ if (message.IsEmpty())
+ return;
+ std::vector<uint8_t> cbor;
+ if (message.Is8Bit()) {
+ crdtp::json::ConvertJSONToCBOR(
+ crdtp::span<uint8_t>(message.Characters8(), message.length()), &cbor);
+ } else {
+ crdtp::json::ConvertJSONToCBOR(
+ crdtp::span<uint16_t>(
+ reinterpret_cast<const uint16_t*>(message.Characters16()),
+ message.length()),
+ &cbor);
+ }
std::unique_ptr<protocol::Value> value =
- protocol::StringUtil::parseJSON(message);
+ protocol::Value::parseBinary(cbor.data(), cbor.size());
if (!value)
return;
protocol::ErrorSupport errors;
std::unique_ptr<protocol::DOM::Rect> box =
protocol::DOM::Rect::fromValue(value.get(), &errors);
- if (errors.hasErrors())
+ if (!errors.Errors().empty())
return;
float scale = 1.0f;
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 34d440c5fb2..5117ebd7760 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(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
Member<InspectorDOMAgent> dom_agent_;
bool ua_shadow_;
@@ -79,7 +79,7 @@ class NodeHighlightTool : public InspectTool {
void Draw(float scale) override;
void DrawNode();
void DrawMatchingSelector();
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
bool is_locked_ancestor_ = false;
Member<Node> node_;
@@ -102,7 +102,7 @@ class NearbyDistanceTool : public InspectTool {
bool HandleMouseMove(const WebMouseEvent& event) override;
bool HandleMouseUp(const WebMouseEvent& event) override;
void Draw(float scale) override;
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) 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 26606c44467..c795f484df2 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(blink::Visitor* visitor) {
+void InspectedFrames::Trace(Visitor* visitor) {
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 5885c32ff28..b35d35a3b75 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspected_frames.h
+++ b/chromium/third_party/blink/renderer/core/inspector/inspected_frames.h
@@ -32,8 +32,8 @@ class CORE_EXPORT InspectedFrames final
private:
friend class InspectedFrames;
Iterator(LocalFrame* root, LocalFrame* current);
- Member<LocalFrame> root_;
- Member<LocalFrame> current_;
+ LocalFrame* root_;
+ LocalFrame* current_;
};
explicit InspectedFrames(LocalFrame*);
@@ -44,7 +44,7 @@ class CORE_EXPORT InspectedFrames final
Iterator begin();
Iterator end();
- virtual void Trace(blink::Visitor*);
+ virtual void Trace(Visitor*);
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 9e59ad98353..786c300e858 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
@@ -7,17 +7,18 @@
#include <memory>
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_computed_effect_timing.h"
+#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_effect.h"
-#include "third_party/blink/renderer/core/animation/computed_effect_timing.h"
#include "third_party/blink/renderer/core/animation/css/css_animation.h"
#include "third_party/blink/renderer/core/animation/css/css_animations.h"
#include "third_party/blink/renderer/core/animation/css/css_transition.h"
+#include "third_party/blink/renderer/core/animation/document_timeline.h"
#include "third_party/blink/renderer/core/animation/effect_model.h"
#include "third_party/blink/renderer/core/animation/element_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/animation/optional_effect_timing.h"
#include "third_party/blink/renderer/core/animation/string_keyframe.h"
#include "third_party/blink/renderer/core/css/css_keyframe_rule.h"
#include "third_party/blink/renderer/core/css/css_keyframes_rule.h"
@@ -41,10 +42,10 @@ namespace {
String AnimationDisplayName(const Animation& animation) {
if (!animation.id().IsEmpty())
return animation.id();
- else if (animation.IsCSSAnimation())
- return ToCSSAnimation(animation).animationName();
- else if (animation.IsCSSTransition())
- return ToCSSTransition(animation).transitionProperty();
+ else if (auto* css_animation = DynamicTo<CSSAnimation>(animation))
+ return css_animation->animationName();
+ else if (auto* css_transition = DynamicTo<CSSTransition>(animation))
+ return css_transition->transitionProperty();
else
return animation.id();
}
@@ -74,7 +75,7 @@ void InspectorAnimationAgent::Restore() {
Response InspectorAnimationAgent::enable() {
enabled_.Set(true);
instrumenting_agents_->AddInspectorAnimationAgent(this);
- return Response::OK();
+ return Response::Success();
}
Response InspectorAnimationAgent::disable() {
@@ -86,7 +87,7 @@ Response InspectorAnimationAgent::disable() {
id_to_animation_.clear();
id_to_animation_clone_.clear();
cleared_animations_.clear();
- return Response::OK();
+ return Response::Success();
}
void InspectorAnimationAgent::DidCommitLoadForLocalFrame(LocalFrame* frame) {
@@ -116,9 +117,9 @@ BuildObjectForAnimationEffect(KeyframeEffect* effect) {
.setFill(computed_timing->fill())
.setEasing(easing)
.build();
- if (effect->target()) {
+ if (effect->EffectTarget()) {
animation_object->setBackendNodeId(
- IdentifiersFactory::IntIdForNode(effect->target()));
+ IdentifiersFactory::IntIdForNode(effect->EffectTarget()));
}
return animation_object;
}
@@ -151,7 +152,7 @@ BuildObjectForAnimationKeyframes(const KeyframeEffect* effect) {
// Ignore CSS Transitions
if (!keyframe->IsStringKeyframe())
continue;
- const StringKeyframe* string_keyframe = ToStringKeyframe(keyframe);
+ const auto* string_keyframe = To<StringKeyframe>(keyframe);
keyframes->emplace_back(
BuildObjectForStringKeyframe(string_keyframe, computed_offsets.at(i)));
}
@@ -167,16 +168,16 @@ InspectorAnimationAgent::BuildObjectForAnimation(blink::Animation& animation) {
if (animation.effect()) {
animation_effect_object =
- BuildObjectForAnimationEffect(ToKeyframeEffect(animation.effect()));
+ BuildObjectForAnimationEffect(To<KeyframeEffect>(animation.effect()));
- if (animation.IsCSSTransition()) {
+ if (IsA<CSSTransition>(animation)) {
animation_type = AnimationType::CSSTransition;
} else {
animation_effect_object->setKeyframesRule(
BuildObjectForAnimationKeyframes(
- ToKeyframeEffect(animation.effect())));
+ To<KeyframeEffect>(animation.effect())));
- if (animation.IsCSSAnimation())
+ if (IsA<CSSAnimation>(animation))
animation_type = AnimationType::CSSAnimation;
}
}
@@ -189,7 +190,7 @@ InspectorAnimationAgent::BuildObjectForAnimation(blink::Animation& animation) {
.setId(id)
.setName(AnimationDisplayName(animation))
.setPausedState(animation.Paused())
- .setPlayState(animation.playState())
+ .setPlayState(animation.PlayStateString())
.setPlaybackRate(animation.playbackRate())
.setStartTime(NormalizedStartTime(animation))
.setCurrentTime(animation.currentTime())
@@ -204,21 +205,21 @@ InspectorAnimationAgent::BuildObjectForAnimation(blink::Animation& animation) {
Response InspectorAnimationAgent::getPlaybackRate(double* playback_rate) {
*playback_rate = ReferenceTimeline().PlaybackRate();
- return Response::OK();
+ return Response::Success();
}
Response InspectorAnimationAgent::setPlaybackRate(double playback_rate) {
for (LocalFrame* frame : *inspected_frames_)
frame->GetDocument()->Timeline().SetPlaybackRate(playback_rate);
playback_rate_.Set(playback_rate);
- return Response::OK();
+ return Response::Success();
}
Response InspectorAnimationAgent::getCurrentTime(const String& id,
double* current_time) {
blink::Animation* animation = nullptr;
Response response = AssertAnimation(id, animation);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
if (id_to_animation_clone_.at(id))
animation = id_to_animation_clone_.at(id);
@@ -229,12 +230,12 @@ Response InspectorAnimationAgent::getCurrentTime(const String& id,
// Use startTime where possible since currentTime is limited.
base::Optional<double> timeline_time = animation->timeline()->CurrentTime();
// TODO(crbug.com/916117): Handle NaN values for scroll linked animations.
- *current_time = timeline_time
- ? timeline_time.value() -
- animation->startTime().value_or(NullValue())
- : NullValue();
+ *current_time =
+ timeline_time ? timeline_time.value() -
+ animation->startTime().value_or(Timing::NullValue())
+ : Timing::NullValue();
}
- return Response::OK();
+ return Response::Success();
}
Response InspectorAnimationAgent::setPaused(
@@ -243,11 +244,11 @@ Response InspectorAnimationAgent::setPaused(
for (const String& animation_id : *animation_ids) {
blink::Animation* animation = nullptr;
Response response = AssertAnimation(animation_id, animation);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
blink::Animation* clone = AnimationClone(animation);
if (!clone)
- return Response::Error("Failed to clone detached animation");
+ return Response::ServerError("Failed to clone detached animation");
if (paused && !clone->Paused()) {
// Ensure we restore a current time if the animation is limited.
double current_time = 0;
@@ -256,10 +257,10 @@ Response InspectorAnimationAgent::setPaused(
} else {
base::Optional<double> timeline_time = clone->timeline()->CurrentTime();
// TODO(crbug.com/916117): Handle NaN values.
- current_time = timeline_time
- ? timeline_time.value() -
- clone->startTime().value_or(NullValue())
- : NullValue();
+ current_time =
+ timeline_time ? timeline_time.value() -
+ clone->startTime().value_or(Timing::NullValue())
+ : Timing::NullValue();
}
clone->pause();
clone->setCurrentTime(current_time, false);
@@ -267,41 +268,41 @@ Response InspectorAnimationAgent::setPaused(
clone->Unpause();
}
}
- return Response::OK();
+ return Response::Success();
}
blink::Animation* InspectorAnimationAgent::AnimationClone(
blink::Animation* animation) {
const String id = String::Number(animation->SequenceNumber());
if (!id_to_animation_clone_.at(id)) {
- KeyframeEffect* old_effect = ToKeyframeEffect(animation->effect());
+ auto* old_effect = To<KeyframeEffect>(animation->effect());
DCHECK(old_effect->Model()->IsKeyframeEffectModel());
KeyframeEffectModelBase* old_model = old_effect->Model();
KeyframeEffectModelBase* new_model = nullptr;
// Clone EffectModel.
// TODO(samli): Determine if this is an animations bug.
if (old_model->IsStringKeyframeEffectModel()) {
- StringKeyframeEffectModel* old_string_keyframe_model =
- ToStringKeyframeEffectModel(old_model);
+ auto* old_string_keyframe_model =
+ To<StringKeyframeEffectModel>(old_model);
KeyframeVector old_keyframes = old_string_keyframe_model->GetFrames();
StringKeyframeVector new_keyframes;
for (auto& old_keyframe : old_keyframes)
- new_keyframes.push_back(ToStringKeyframe(old_keyframe));
+ new_keyframes.push_back(To<StringKeyframe>(*old_keyframe));
new_model =
MakeGarbageCollected<StringKeyframeEffectModel>(new_keyframes);
} else if (old_model->IsTransitionKeyframeEffectModel()) {
- TransitionKeyframeEffectModel* old_transition_keyframe_model =
- ToTransitionKeyframeEffectModel(old_model);
+ auto* old_transition_keyframe_model =
+ To<TransitionKeyframeEffectModel>(old_model);
KeyframeVector old_keyframes = old_transition_keyframe_model->GetFrames();
TransitionKeyframeVector new_keyframes;
for (auto& old_keyframe : old_keyframes)
- new_keyframes.push_back(ToTransitionKeyframe(old_keyframe));
+ new_keyframes.push_back(To<TransitionKeyframe>(*old_keyframe));
new_model =
MakeGarbageCollected<TransitionKeyframeEffectModel>(new_keyframes);
}
auto* new_effect = MakeGarbageCollected<KeyframeEffect>(
- old_effect->target(), new_model, old_effect->SpecifiedTiming());
+ old_effect->EffectTarget(), new_model, old_effect->SpecifiedTiming());
is_cloning_ = true;
blink::Animation* clone =
blink::Animation::Create(new_effect, animation->timeline());
@@ -309,7 +310,8 @@ blink::Animation* InspectorAnimationAgent::AnimationClone(
id_to_animation_clone_.Set(id, clone);
id_to_animation_.Set(String::Number(clone->SequenceNumber()), clone);
clone->play();
- clone->setStartTime(animation->startTime().value_or(NullValue()), false);
+ clone->setStartTime(animation->startTime().value_or(Timing::NullValue()),
+ false);
animation->SetEffectSuppressed(true);
}
@@ -322,16 +324,16 @@ Response InspectorAnimationAgent::seekAnimations(
for (const String& animation_id : *animation_ids) {
blink::Animation* animation = nullptr;
Response response = AssertAnimation(animation_id, animation);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
blink::Animation* clone = AnimationClone(animation);
if (!clone)
- return Response::Error("Failed to clone a detached animation.");
+ return Response::ServerError("Failed to clone a detached animation.");
if (!clone->Paused())
clone->play();
clone->setCurrentTime(current_time, false);
}
- return Response::OK();
+ return Response::Success();
}
Response InspectorAnimationAgent::releaseAnimations(
@@ -347,7 +349,7 @@ Response InspectorAnimationAgent::releaseAnimations(
id_to_animation_.erase(animation_id);
cleared_animations_.insert(animation_id);
}
- return Response::OK();
+ return Response::Success();
}
Response InspectorAnimationAgent::setTiming(const String& animation_id,
@@ -355,7 +357,7 @@ Response InspectorAnimationAgent::setTiming(const String& animation_id,
double delay) {
blink::Animation* animation = nullptr;
Response response = AssertAnimation(animation_id, animation);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
animation = AnimationClone(animation);
@@ -367,7 +369,7 @@ Response InspectorAnimationAgent::setTiming(const String& animation_id,
timing->setDuration(unrestricted_duration);
timing->setDelay(delay);
animation->effect()->updateTiming(timing, exception_state);
- return Response::OK();
+ return Response::Success();
}
Response InspectorAnimationAgent::resolveAnimation(
@@ -376,17 +378,18 @@ Response InspectorAnimationAgent::resolveAnimation(
result) {
blink::Animation* animation = nullptr;
Response response = AssertAnimation(animation_id, animation);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
if (id_to_animation_clone_.at(animation_id))
animation = id_to_animation_clone_.at(animation_id);
- const Element* element = ToKeyframeEffect(animation->effect())->target();
+ const Element* element =
+ To<KeyframeEffect>(animation->effect())->EffectTarget();
Document* document = element->ownerDocument();
LocalFrame* frame = document ? document->GetFrame() : nullptr;
ScriptState* script_state =
frame ? ToScriptStateForMainWorld(frame) : nullptr;
if (!script_state)
- return Response::Error("Element not associated with a document.");
+ return Response::ServerError("Element not associated with a document.");
ScriptState::Scope scope(script_state);
static const char kAnimationObjectGroup[] = "animation";
@@ -399,8 +402,8 @@ Response InspectorAnimationAgent::resolveAnimation(
ToV8InspectorStringView(kAnimationObjectGroup),
false /* generatePreview */);
if (!*result)
- return Response::Error("Element not associated with a document.");
- return Response::OK();
+ return Response::ServerError("Element not associated with a document.");
+ return Response::Success();
}
String InspectorAnimationAgent::CreateCSSId(blink::Animation& animation) {
@@ -419,25 +422,24 @@ String InspectorAnimationAgent::CreateCSSId(blink::Animation& animation) {
&GetCSSPropertyTransitionTimingFunction(),
};
- KeyframeEffect* effect = ToKeyframeEffect(animation.effect());
+ auto* effect = To<KeyframeEffect>(animation.effect());
Vector<const CSSProperty*> css_properties;
- if (animation.IsCSSAnimation()) {
+ if (IsA<CSSAnimation>(animation)) {
for (const CSSProperty* property : g_animation_properties)
css_properties.push_back(property);
- } else if (animation.IsCSSTransition()) {
+ } else if (auto* css_transition = DynamicTo<CSSTransition>(animation)) {
for (const CSSProperty* property : g_transition_properties)
css_properties.push_back(property);
- css_properties.push_back(
- &ToCSSTransition(animation).TransitionCSSProperty());
+ css_properties.push_back(&css_transition->TransitionCSSProperty());
} else {
NOTREACHED();
}
- Element* element = effect->target();
+ Element* element = effect->EffectTarget();
HeapVector<Member<CSSStyleDeclaration>> styles =
css_agent_->MatchingStyles(element);
Digestor digestor(kHashAlgorithmSha1);
- digestor.UpdateUtf8(animation.IsCSSTransition()
+ digestor.UpdateUtf8(IsA<CSSTransition>(animation)
? AnimationType::CSSTransition
: AnimationType::CSSAnimation);
digestor.UpdateUtf8(animation.id());
@@ -498,8 +500,8 @@ Response InspectorAnimationAgent::AssertAnimation(const String& id,
blink::Animation*& result) {
result = id_to_animation_.at(id);
if (!result)
- return Response::Error("Could not find animation with given id");
- return Response::OK();
+ return Response::ServerError("Could not find animation with given id");
+ return Response::Success();
}
DocumentTimeline& InspectorAnimationAgent::ReferenceTimeline() {
@@ -508,23 +510,24 @@ DocumentTimeline& InspectorAnimationAgent::ReferenceTimeline() {
double InspectorAnimationAgent::NormalizedStartTime(
blink::Animation& animation) {
- double time_ms = animation.startTime().value_or(NullValue());
- if (animation.timeline()->IsDocumentTimeline()) {
+ double time_ms = animation.startTime().value_or(Timing::NullValue());
+ auto* document_timeline = DynamicTo<DocumentTimeline>(animation.timeline());
+ if (document_timeline) {
if (ReferenceTimeline().PlaybackRate() == 0) {
- time_ms += ReferenceTimeline().currentTime() -
- ToDocumentTimeline(animation.timeline())->currentTime();
+ time_ms +=
+ ReferenceTimeline().currentTime() - document_timeline->currentTime();
} else {
- time_ms += (ToDocumentTimeline(animation.timeline())->ZeroTime() -
- ReferenceTimeline().ZeroTime())
- .InMillisecondsF() *
- ReferenceTimeline().PlaybackRate();
+ time_ms +=
+ (document_timeline->ZeroTime() - ReferenceTimeline().ZeroTime())
+ .InMillisecondsF() *
+ ReferenceTimeline().PlaybackRate();
}
}
// Round to the closest microsecond.
return std::round(time_ms * 1000) / 1000;
}
-void InspectorAnimationAgent::Trace(blink::Visitor* visitor) {
+void InspectorAnimationAgent::Trace(Visitor* visitor) {
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 b8044544942..1f1a11309b5 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 82f5a66a076..500adaefe95 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
@@ -57,13 +57,13 @@ void InspectorApplicationCacheAgent::Restore() {
Response InspectorApplicationCacheAgent::enable() {
if (!enabled_.Get())
InnerEnable();
- return Response::OK();
+ return Response::Success();
}
Response InspectorApplicationCacheAgent::disable() {
enabled_.Clear();
instrumenting_agents_->RemoveInspectorApplicationCacheAgent(this);
- return Response::OK();
+ return Response::Success();
}
void InspectorApplicationCacheAgent::UpdateApplicationCacheStatus(
@@ -115,7 +115,7 @@ Response InspectorApplicationCacheAgent::getFramesWithManifests(
(*result)->emplace_back(std::move(value));
}
}
- return Response::OK();
+ return Response::Success();
}
Response InspectorApplicationCacheAgent::AssertFrameWithDocumentLoader(
@@ -124,12 +124,12 @@ Response InspectorApplicationCacheAgent::AssertFrameWithDocumentLoader(
LocalFrame* frame =
IdentifiersFactory::FrameById(inspected_frames_, frame_id);
if (!frame)
- return Response::Error("No frame for given id found");
+ return Response::ServerError("No frame for given id found");
result = frame->Loader().GetDocumentLoader();
if (!result)
- return Response::Error("No documentLoader for given frame found");
- return Response::OK();
+ return Response::ServerError("No documentLoader for given frame found");
+ return Response::Success();
}
Response InspectorApplicationCacheAgent::getManifestForFrame(
@@ -137,13 +137,13 @@ Response InspectorApplicationCacheAgent::getManifestForFrame(
String* manifest_url) {
DocumentLoader* document_loader = nullptr;
Response response = AssertFrameWithDocumentLoader(frame_id, document_loader);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
ApplicationCacheHost::CacheInfo info =
document_loader->GetApplicationCacheHost()->ApplicationCacheInfo();
*manifest_url = info.manifest_.GetString();
- return Response::OK();
+ return Response::Success();
}
Response InspectorApplicationCacheAgent::getApplicationCacheForFrame(
@@ -152,7 +152,7 @@ Response InspectorApplicationCacheAgent::getApplicationCacheForFrame(
application_cache) {
DocumentLoader* document_loader = nullptr;
Response response = AssertFrameWithDocumentLoader(frame_id, document_loader);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
ApplicationCacheHostForFrame* host =
@@ -163,7 +163,7 @@ Response InspectorApplicationCacheAgent::getApplicationCacheForFrame(
host->FillResourceList(&resources);
*application_cache = BuildObjectForApplicationCache(resources, info);
- return Response::OK();
+ return Response::Success();
}
std::unique_ptr<protocol::ApplicationCache::ApplicationCache>
@@ -223,7 +223,7 @@ InspectorApplicationCacheAgent::BuildObjectForApplicationCacheResource(
return value;
}
-void InspectorApplicationCacheAgent::Trace(blink::Visitor* visitor) {
+void InspectorApplicationCacheAgent::Trace(Visitor* visitor) {
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 e4572b85ce6..c8961f23dc4 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
@@ -40,15 +40,9 @@ class InspectedFrames;
class CORE_EXPORT InspectorApplicationCacheAgent final
: public InspectorBaseAgent<protocol::ApplicationCache::Metainfo> {
public:
- static InspectorApplicationCacheAgent* Create(
- InspectedFrames* inspected_frames) {
- return MakeGarbageCollected<InspectorApplicationCacheAgent>(
- inspected_frames);
- }
-
explicit InspectorApplicationCacheAgent(InspectedFrames*);
~InspectorApplicationCacheAgent() override = default;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 21ee35bd19f..7dfae515abc 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
@@ -11,6 +11,9 @@
#include "third_party/blink/renderer/platform/graphics/image_data_buffer.h"
#include "third_party/blink/renderer/platform/wtf/text/base64.h"
+#include "third_party/blink/renderer/core/inspector/inspector_issue.h"
+#include "third_party/blink/renderer/core/inspector/inspector_issue_storage.h"
+
namespace blink {
using protocol::Maybe;
@@ -63,13 +66,17 @@ bool EncodeAsImage(char* body,
} // namespace
-void InspectorAuditsAgent::Trace(blink::Visitor* visitor) {
+void InspectorAuditsAgent::Trace(Visitor* visitor) {
visitor->Trace(network_agent_);
+ visitor->Trace(inspector_issue_storage_);
InspectorBaseAgent::Trace(visitor);
}
-InspectorAuditsAgent::InspectorAuditsAgent(InspectorNetworkAgent* network_agent)
- : network_agent_(network_agent) {}
+InspectorAuditsAgent::InspectorAuditsAgent(InspectorNetworkAgent* network_agent,
+ InspectorIssueStorage* storage)
+ : inspector_issue_storage_(storage),
+ enabled_(&agent_state_, false),
+ network_agent_(network_agent) {}
InspectorAuditsAgent::~InspectorAuditsAgent() = default;
@@ -88,20 +95,20 @@ protocol::Response InspectorAuditsAgent::getEncodedResponse(
bool is_base64_encoded;
Response response =
network_agent_->GetResponseBody(request_id, &body, &is_base64_encoded);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
Vector<char> base64_decoded_buffer;
if (!is_base64_encoded || !Base64Decode(body, base64_decoded_buffer) ||
base64_decoded_buffer.size() == 0) {
- return Response::Error("Failed to decode original image");
+ return Response::ServerError("Failed to decode original image");
}
Vector<unsigned char> encoded_image;
if (!EncodeAsImage(base64_decoded_buffer.data(), base64_decoded_buffer.size(),
encoding, quality.fromMaybe(kDefaultEncodeQuality),
&encoded_image)) {
- return Response::Error("Could not encode image with given settings");
+ return Response::ServerError("Could not encode image with given settings");
}
*out_original_size = static_cast<int>(base64_decoded_buffer.size());
@@ -110,7 +117,176 @@ protocol::Response InspectorAuditsAgent::getEncodedResponse(
if (!size_only.fromMaybe(false)) {
*out_body = protocol::Binary::fromVector(std::move(encoded_image));
}
- return Response::OK();
+ return Response::Success();
+}
+
+Response InspectorAuditsAgent::enable() {
+ if (enabled_.Get()) {
+ return Response::Success();
+ }
+
+ enabled_.Set(true);
+ InnerEnable();
+ return Response::Success();
+}
+
+Response InspectorAuditsAgent::disable() {
+ if (!enabled_.Get()) {
+ return Response::Success();
+ }
+
+ enabled_.Clear();
+ instrumenting_agents_->RemoveInspectorAuditsAgent(this);
+ return Response::Success();
+}
+
+void InspectorAuditsAgent::Restore() {
+ if (!enabled_.Get())
+ return;
+ InnerEnable();
+}
+
+void InspectorAuditsAgent::InnerEnable() {
+ instrumenting_agents_->AddInspectorAuditsAgent(this);
+ for (wtf_size_t i = 0; i < inspector_issue_storage_->size(); ++i)
+ InspectorIssueAdded(inspector_issue_storage_->at(i));
+}
+
+namespace {
+std::unique_ptr<protocol::Array<protocol::Audits::AffectedCookie>> BuildCookies(
+ const WTF::Vector<mojom::blink::AffectedCookiePtr>& cookies) {
+ auto result =
+ std::make_unique<protocol::Array<protocol::Audits::AffectedCookie>>();
+ for (const auto& cookie : cookies) {
+ auto protocol_cookie = std::move(protocol::Audits::AffectedCookie::create()
+ .setName(cookie->name)
+ .setPath(cookie->path)
+ .setDomain(cookie->domain));
+ if (cookie->site_for_cookies) {
+ protocol_cookie.setSiteForCookies(*cookie->site_for_cookies);
+ }
+ result->push_back(protocol_cookie.build());
+ }
+ return result;
+}
+blink::protocol::String InspectorIssueCodeValue(
+ mojom::blink::InspectorIssueCode code) {
+ switch (code) {
+ case mojom::blink::InspectorIssueCode::kSameSiteCookieIssue:
+ return protocol::Audits::InspectorIssueCodeEnum::SameSiteCookieIssue;
+ }
+ NOTREACHED();
+ return "unknown";
+}
+protocol::String BuildCookieExclusionReason(
+ mojom::blink::SameSiteCookieExclusionReason exclusion_reason) {
+ switch (exclusion_reason) {
+ case blink::mojom::blink::SameSiteCookieExclusionReason::
+ ExcludeSameSiteUnspecifiedTreatedAsLax:
+ return protocol::Audits::SameSiteCookieExclusionReasonEnum::
+ ExcludeSameSiteUnspecifiedTreatedAsLax;
+ case blink::mojom::blink::SameSiteCookieExclusionReason::
+ ExcludeSameSiteNoneInsecure:
+ return protocol::Audits::SameSiteCookieExclusionReasonEnum::
+ ExcludeSameSiteNoneInsecure;
+ }
+ NOTREACHED();
+ return "unknown";
+}
+std::unique_ptr<std::vector<blink::protocol::String>>
+BuildCookieExclusionReasons(
+ const WTF::Vector<mojom::blink::SameSiteCookieExclusionReason>&
+ exclusion_reasons) {
+ auto protocol_exclusion_reasons =
+ std::make_unique<std::vector<blink::protocol::String>>();
+ for (const auto& reason : exclusion_reasons) {
+ protocol_exclusion_reasons->push_back(BuildCookieExclusionReason(reason));
+ }
+ return protocol_exclusion_reasons;
+}
+protocol::String BuildCookieWarningReason(
+ mojom::blink::SameSiteCookieWarningReason warning_reason) {
+ switch (warning_reason) {
+ case blink::mojom::blink::SameSiteCookieWarningReason::
+ WarnSameSiteUnspecifiedCrossSiteContext:
+ return protocol::Audits::SameSiteCookieWarningReasonEnum::
+ WarnSameSiteUnspecifiedCrossSiteContext;
+ case blink::mojom::blink::SameSiteCookieWarningReason::
+ WarnSameSiteNoneInsecure:
+ return protocol::Audits::SameSiteCookieWarningReasonEnum::
+ WarnSameSiteNoneInsecure;
+ case blink::mojom::blink::SameSiteCookieWarningReason::
+ WarnSameSiteUnspecifiedLaxAllowUnsafe:
+ return protocol::Audits::SameSiteCookieWarningReasonEnum::
+ WarnSameSiteUnspecifiedLaxAllowUnsafe;
+ case blink::mojom::blink::SameSiteCookieWarningReason::
+ WarnSameSiteCrossSchemeSecureUrlMethodUnsafe:
+ return protocol::Audits::SameSiteCookieWarningReasonEnum::
+ WarnSameSiteCrossSchemeSecureUrlMethodUnsafe;
+ case blink::mojom::blink::SameSiteCookieWarningReason::
+ WarnSameSiteCrossSchemeSecureUrlLax:
+ return protocol::Audits::SameSiteCookieWarningReasonEnum::
+ WarnSameSiteCrossSchemeSecureUrlLax;
+ case blink::mojom::blink::SameSiteCookieWarningReason::
+ WarnSameSiteCrossSchemeSecureUrlStrict:
+ return protocol::Audits::SameSiteCookieWarningReasonEnum::
+ WarnSameSiteCrossSchemeSecureUrlStrict;
+ case blink::mojom::blink::SameSiteCookieWarningReason::
+ WarnSameSiteCrossSchemeInsecureUrlMethodUnsafe:
+ return protocol::Audits::SameSiteCookieWarningReasonEnum::
+ WarnSameSiteCrossSchemeInsecureUrlMethodUnsafe;
+ case blink::mojom::blink::SameSiteCookieWarningReason::
+ WarnSameSiteCrossSchemeInsecureUrlLax:
+ return protocol::Audits::SameSiteCookieWarningReasonEnum::
+ WarnSameSiteCrossSchemeInsecureUrlLax;
+ case blink::mojom::blink::SameSiteCookieWarningReason::
+ WarnSameSiteCrossSchemeInsecureUrlStrict:
+ return protocol::Audits::SameSiteCookieWarningReasonEnum::
+ WarnSameSiteCrossSchemeInsecureUrlStrict;
+ }
+ NOTREACHED();
+ return "unknown";
+}
+std::unique_ptr<std::vector<blink::protocol::String>> BuildCookieWarningReasons(
+ const WTF::Vector<mojom::blink::SameSiteCookieWarningReason>&
+ warning_reasons) {
+ auto protocol_warning_reasons =
+ std::make_unique<std::vector<blink::protocol::String>>();
+ for (const auto& reason : warning_reasons) {
+ protocol_warning_reasons->push_back(BuildCookieWarningReason(reason));
+ }
+ return protocol_warning_reasons;
+}
+} // namespace
+
+void InspectorAuditsAgent::InspectorIssueAdded(InspectorIssue* issue) {
+ auto issueDetails = protocol::Audits::InspectorIssueDetails::create();
+
+ if (issue->Details()->sameSiteCookieIssueDetails) {
+ auto sameSiteCookieDetails =
+ protocol::Audits::SameSiteCookieIssueDetails::create()
+ .setCookieExclusionReasons(BuildCookieExclusionReasons(
+ issue->Details()->sameSiteCookieIssueDetails->exclusionReason))
+ .setCookieWarningReasons(BuildCookieWarningReasons(
+ issue->Details()->sameSiteCookieIssueDetails->warningReason))
+ .build();
+ issueDetails.setSameSiteCookieIssueDetails(
+ std::move(sameSiteCookieDetails));
+ }
+
+ auto affectedResources =
+ protocol::Audits::AffectedResources::create()
+ .setCookies(BuildCookies(issue->Resources()->cookies))
+ .build();
+
+ auto inspector_issue = protocol::Audits::InspectorIssue::create()
+ .setCode(InspectorIssueCodeValue(issue->Code()))
+ .setDetails(issueDetails.build())
+ .setResources(std::move(affectedResources))
+ .build();
+
+ GetFrontend()->issueAdded(std::move(inspector_issue));
+ GetFrontend()->flush();
}
} // namespace blink
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 966524e3e40..d03ee4bc9ee 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
@@ -12,15 +12,25 @@
namespace blink {
+class InspectorIssue;
+class InspectorIssueStorage;
+
class CORE_EXPORT InspectorAuditsAgent final
: public InspectorBaseAgent<protocol::Audits::Metainfo> {
public:
- explicit InspectorAuditsAgent(InspectorNetworkAgent*);
+ explicit InspectorAuditsAgent(InspectorNetworkAgent*, InspectorIssueStorage*);
~InspectorAuditsAgent() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
+
+ void InspectorIssueAdded(InspectorIssue*);
// Protocol methods.
+ protocol::Response enable() override;
+ protocol::Response disable() override;
+
+ void Restore() override;
+
protocol::Response getEncodedResponse(
const String& request_id,
const String& encoding,
@@ -31,6 +41,9 @@ class CORE_EXPORT InspectorAuditsAgent final
int* out_encoded_size) override;
private:
+ void InnerEnable();
+ Member<InspectorIssueStorage> inspector_issue_storage_;
+ InspectorAgentState::Boolean enabled_;
Member<InspectorNetworkAgent> network_agent_;
DISALLOW_COPY_AND_ASSIGN(InspectorAuditsAgent);
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 f91d1e56062..fb5e6fb135e 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(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
virtual void Restore() {}
virtual void DidCommitLoadForLocalFrame(LocalFrame*) {}
@@ -76,7 +76,9 @@ class InspectorBaseAgent : public InspectorAgent,
agent_state_.InitFrom(session_state);
}
- protocol::Response disable() override { return protocol::Response::OK(); }
+ protocol::Response disable() override {
+ return protocol::Response::Success();
+ }
void Dispose() override {
disable();
@@ -84,7 +86,7 @@ class InspectorBaseAgent : public InspectorAgent,
instrumenting_agents_ = nullptr;
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 c3b49c0bef0..b7637eadd7e 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
@@ -64,6 +64,7 @@
#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"
+#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_head_element.h"
#include "third_party/blink/renderer/core/inspector/identifiers_factory.h"
@@ -128,7 +129,7 @@ String CreateShorthandValue(Document* document,
auto* rule = To<CSSStyleRule>(style_sheet->item(0));
CSSStyleDeclaration* style = rule->style();
DummyExceptionStateForTesting exception_state;
- style->setProperty(document, longhand, new_value,
+ style->setProperty(document->GetExecutionContext(), longhand, new_value,
style->getPropertyPriority(longhand), exception_state);
return style->getPropertyValue(shorthand);
}
@@ -162,7 +163,7 @@ HeapVector<Member<Element>> ElementsFromRect(const PhysicalRect& rect,
document.GetFrame()->ContentLayoutObject()->HitTest(location, result);
HeapVector<Member<Element>> elements;
Node* previous_node = nullptr;
- for (const auto hit_test_result_node : result.ListBasedTestResult()) {
+ for (const auto& hit_test_result_node : result.ListBasedTestResult()) {
Node* node = hit_test_result_node.Get();
if (!node || node->IsDocumentNode())
continue;
@@ -417,7 +418,7 @@ class InspectorCSSAgent::SetStyleSheetTextAction final
text_ = other->text_;
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(style_sheet_);
InspectorCSSAgent::StyleSheetAction::Trace(visitor);
}
@@ -515,7 +516,7 @@ class InspectorCSSAgent::ModifyRuleAction final
return nullptr;
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(style_sheet_);
visitor->Trace(css_rule_);
InspectorCSSAgent::StyleSheetAction::Trace(visitor);
@@ -570,7 +571,7 @@ class InspectorCSSAgent::SetElementStyleAction final
return style_sheet_->SetText(text_, exception_state);
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(style_sheet_);
InspectorCSSAgent::StyleSheetAction::Trace(visitor);
}
@@ -633,7 +634,7 @@ class InspectorCSSAgent::AddRuleAction final
return result;
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(style_sheet_);
visitor->Trace(css_rule_);
InspectorCSSAgent::StyleSheetAction::Trace(visitor);
@@ -711,7 +712,7 @@ void InspectorCSSAgent::ResetNonPersistentData() {
void InspectorCSSAgent::enable(std::unique_ptr<EnableCallback> prp_callback) {
if (!dom_agent_->Enabled()) {
prp_callback->sendFailure(
- Response::Error("DOM agent needs to be enabled first."));
+ Response::ServerError("DOM agent needs to be enabled first."));
return;
}
enable_requested_.Set(true);
@@ -746,7 +747,7 @@ Response InspectorCSSAgent::disable() {
resource_content_loader_->Cancel(resource_content_loader_client_id_);
coverage_enabled_.Set(false);
SetCoverageEnabled(false);
- return Response::OK();
+ return Response::Success();
}
void InspectorCSSAgent::DidCommitLoadForLocalFrame(LocalFrame* frame) {
@@ -907,7 +908,7 @@ Response InspectorCSSAgent::getMediaQueries(
CollectMediaQueriesFromRule(rule, medias->get());
}
}
- return Response::OK();
+ return Response::Success();
}
Response InspectorCSSAgent::getMatchedStylesForNode(
@@ -922,12 +923,12 @@ Response InspectorCSSAgent::getMatchedStylesForNode(
Maybe<protocol::Array<protocol::CSS::CSSKeyframesRule>>*
css_keyframes_rules) {
Response response = AssertEnabled();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
Element* element = nullptr;
response = dom_agent_->AssertElement(node_id, element);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
Element* original_element = element;
@@ -935,13 +936,13 @@ Response InspectorCSSAgent::getMatchedStylesForNode(
if (element_pseudo_id) {
element = element->ParentOrShadowHostElement();
if (!element)
- return Response::Error("Pseudo element has no parent");
+ return Response::ServerError("Pseudo element has no parent");
}
Document* owner_document = element->ownerDocument();
// A non-active document has no styles.
if (!owner_document->IsActive())
- return Response::Error("Document is not active");
+ return Response::ServerError("Document is not active");
// FIXME: It's really gross for the inspector to reach in and access
// StyleResolver directly here. We need to provide the Inspector better APIs
@@ -958,7 +959,7 @@ Response InspectorCSSAgent::getMatchedStylesForNode(
// Pseudo elements.
if (element_pseudo_id)
- return Response::OK();
+ return Response::Success();
InspectorStyleSheetForInlineStyle* inline_style_sheet =
AsInspectorStyleSheet(element);
@@ -974,12 +975,11 @@ Response InspectorCSSAgent::getMatchedStylesForNode(
pseudo_id = static_cast<PseudoId>(pseudo_id + 1)) {
RuleIndexList* matched_rules = style_resolver.PseudoCSSRulesForElement(
element, pseudo_id, StyleResolver::kAllCSSRules);
- protocol::DOM::PseudoType pseudo_type;
- if (matched_rules && matched_rules->size() &&
- dom_agent_->GetPseudoElementType(pseudo_id, &pseudo_type)) {
+ if (matched_rules && matched_rules->size()) {
pseudo_id_matches->fromJust()->emplace_back(
protocol::CSS::PseudoElementMatches::create()
- .setPseudoType(pseudo_type)
+ .setPseudoType(
+ InspectorDOMAgent::ProtocolPseudoElementType(pseudo_id))
.setMatches(BuildArrayForMatchedRuleList(matched_rules, element,
pseudo_id))
.build());
@@ -1014,7 +1014,7 @@ Response InspectorCSSAgent::getMatchedStylesForNode(
}
*css_keyframes_rules = AnimationsForNode(element);
- return Response::OK();
+ return Response::Success();
}
template <class CSSRuleCollection>
@@ -1101,21 +1101,21 @@ Response InspectorCSSAgent::getInlineStylesForNode(
Maybe<protocol::CSS::CSSStyle>* inline_style,
Maybe<protocol::CSS::CSSStyle>* attributes_style) {
Response response = AssertEnabled();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
Element* element = nullptr;
response = dom_agent_->AssertElement(node_id, element);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
InspectorStyleSheetForInlineStyle* style_sheet =
AsInspectorStyleSheet(element);
if (!style_sheet)
- return Response::Error("Element is not a style sheet");
+ return Response::ServerError("Element is not a style sheet");
*inline_style = style_sheet->BuildObjectForStyle(element->style());
*attributes_style = BuildObjectForAttributesStyle(element);
- return Response::OK();
+ return Response::Success();
}
Response InspectorCSSAgent::getComputedStyleForNode(
@@ -1123,11 +1123,11 @@ Response InspectorCSSAgent::getComputedStyleForNode(
std::unique_ptr<protocol::Array<protocol::CSS::CSSComputedStyleProperty>>*
style) {
Response response = AssertEnabled();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
Node* node = nullptr;
response = dom_agent_->AssertNode(node_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
auto* computed_style_info =
@@ -1137,8 +1137,8 @@ Response InspectorCSSAgent::getComputedStyleForNode(
for (CSSPropertyID property_id : CSSPropertyIDList()) {
const CSSProperty& property_class =
CSSProperty::Get(resolveCSSPropertyID(property_id));
- if (!property_class.IsWebExposed() || property_class.IsShorthand() ||
- !property_class.IsProperty())
+ if (!property_class.IsWebExposed(node->GetExecutionContext()) ||
+ property_class.IsShorthand() || !property_class.IsProperty())
continue;
(*style)->emplace_back(
protocol::CSS::CSSComputedStyleProperty::create()
@@ -1153,7 +1153,7 @@ Response InspectorCSSAgent::getComputedStyleForNode(
.setValue(it.value->CssText())
.build());
}
- return Response::OK();
+ return Response::Success();
}
void InspectorCSSAgent::CollectPlatformFontsForLayoutObject(
@@ -1189,7 +1189,8 @@ void InspectorCSSAgent::CollectPlatformFontsForLayoutObject(
NGInlineCursor cursor;
cursor.MoveTo(*layout_object);
for (; cursor; cursor.MoveToNextForSameLayoutObject()) {
- const ShapeResultView* shape_result = cursor.CurrentTextShapeResult();
+ const ShapeResultView* shape_result =
+ cursor.Current().TextShapeResult();
if (!shape_result)
continue;
Vector<ShapeResult::RunFontData> run_font_data_list;
@@ -1217,11 +1218,11 @@ Response InspectorCSSAgent::getPlatformFontsForNode(
std::unique_ptr<protocol::Array<protocol::CSS::PlatformFontUsage>>*
platform_fonts) {
Response response = AssertEnabled();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
Node* node = nullptr;
response = dom_agent_->AssertNode(node_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
HashCountedSet<std::pair<int, String>> font_stats;
@@ -1244,7 +1245,7 @@ Response InspectorCSSAgent::getPlatformFontsForNode(
.setGlyphCount(font.value)
.build());
}
- return Response::OK();
+ return Response::Success();
}
Response InspectorCSSAgent::getStyleSheetText(const String& style_sheet_id,
@@ -1252,11 +1253,11 @@ Response InspectorCSSAgent::getStyleSheetText(const String& style_sheet_id,
InspectorStyleSheetBase* inspector_style_sheet = nullptr;
Response response =
AssertStyleSheetForId(style_sheet_id, inspector_style_sheet);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
inspector_style_sheet->GetText(result);
- return Response::OK();
+ return Response::Success();
}
Response InspectorCSSAgent::collectClassNames(
@@ -1265,10 +1266,10 @@ Response InspectorCSSAgent::collectClassNames(
InspectorStyleSheet* inspector_style_sheet = nullptr;
Response response =
AssertInspectorStyleSheetForId(style_sheet_id, inspector_style_sheet);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
*class_names = inspector_style_sheet->CollectClassNames();
- return Response::OK();
+ return Response::Success();
}
Response InspectorCSSAgent::setStyleSheetText(
@@ -1279,7 +1280,7 @@ Response InspectorCSSAgent::setStyleSheetText(
InspectorStyleSheetBase* inspector_style_sheet = nullptr;
Response response =
AssertStyleSheetForId(style_sheet_id, inspector_style_sheet);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
DummyExceptionStateForTesting exception_state;
@@ -1287,25 +1288,33 @@ Response InspectorCSSAgent::setStyleSheetText(
inspector_style_sheet, text),
exception_state);
response = InspectorDOMAgent::ToResponse(exception_state);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
if (!inspector_style_sheet->SourceMapURL().IsEmpty())
*source_map_url = inspector_style_sheet->SourceMapURL();
- return Response::OK();
+ return Response::Success();
}
static Response JsonRangeToSourceRange(
InspectorStyleSheetBase* inspector_style_sheet,
protocol::CSS::SourceRange* range,
SourceRange* source_range) {
- if (range->getStartLine() < 0)
- return Response::Error("range.startLine must be a non-negative integer");
- if (range->getStartColumn() < 0)
- return Response::Error("range.startColumn must be a non-negative integer");
- if (range->getEndLine() < 0)
- return Response::Error("range.endLine must be a non-negative integer");
- if (range->getEndColumn() < 0)
- return Response::Error("range.endColumn must be a non-negative integer");
+ if (range->getStartLine() < 0) {
+ return Response::ServerError(
+ "range.startLine must be a non-negative integer");
+ }
+ if (range->getStartColumn() < 0) {
+ return Response::ServerError(
+ "range.startColumn must be a non-negative integer");
+ }
+ if (range->getEndLine() < 0) {
+ return Response::ServerError(
+ "range.endLine must be a non-negative integer");
+ }
+ if (range->getEndColumn() < 0) {
+ return Response::ServerError(
+ "range.endColumn must be a non-negative integer");
+ }
unsigned start_offset = 0;
unsigned end_offset = 0;
@@ -1315,13 +1324,13 @@ static Response JsonRangeToSourceRange(
inspector_style_sheet->LineNumberAndColumnToOffset(
range->getEndLine(), range->getEndColumn(), &end_offset);
if (!success)
- return Response::Error("Specified range is out of bounds");
+ return Response::ServerError("Specified range is out of bounds");
if (start_offset > end_offset)
- return Response::Error("Range start must not succeed its end");
+ return Response::ServerError("Range start must not succeed its end");
source_range->start = start_offset;
source_range->end = end_offset;
- return Response::OK();
+ return Response::Success();
}
Response InspectorCSSAgent::setRuleSelector(
@@ -1333,12 +1342,12 @@ Response InspectorCSSAgent::setRuleSelector(
InspectorStyleSheet* inspector_style_sheet = nullptr;
Response response =
AssertInspectorStyleSheetForId(style_sheet_id, inspector_style_sheet);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
SourceRange selector_range;
response = JsonRangeToSourceRange(inspector_style_sheet, range.get(),
&selector_range);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
DummyExceptionStateForTesting exception_state;
@@ -1350,8 +1359,10 @@ Response InspectorCSSAgent::setRuleSelector(
CSSStyleRule* rule = InspectorCSSAgent::AsCSSStyleRule(action->TakeRule());
InspectorStyleSheet* inspector_style_sheet =
InspectorStyleSheetForRule(rule);
- if (!inspector_style_sheet)
- return Response::Error("Failed to get inspector style sheet for rule.");
+ if (!inspector_style_sheet) {
+ return Response::ServerError(
+ "Failed to get inspector style sheet for rule.");
+ }
*result = inspector_style_sheet->BuildObjectForSelectorList(rule);
}
return InspectorDOMAgent::ToResponse(exception_state);
@@ -1366,12 +1377,12 @@ Response InspectorCSSAgent::setKeyframeKey(
InspectorStyleSheet* inspector_style_sheet = nullptr;
Response response =
AssertInspectorStyleSheetForId(style_sheet_id, inspector_style_sheet);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
SourceRange key_range;
response =
JsonRangeToSourceRange(inspector_style_sheet, range.get(), &key_range);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
DummyExceptionStateForTesting exception_state;
@@ -1383,9 +1394,10 @@ Response InspectorCSSAgent::setKeyframeKey(
auto* rule = To<CSSKeyframeRule>(action->TakeRule());
InspectorStyleSheet* inspector_style_sheet =
BindStyleSheet(rule->parentStyleSheet());
- if (!inspector_style_sheet)
- return Response::Error("Failed to get inspector style sheet for rule.");
-
+ if (!inspector_style_sheet) {
+ return Response::ServerError(
+ "Failed to get inspector style sheet for rule.");
+ }
CSSRuleSourceData* source_data =
inspector_style_sheet->SourceDataForRule(rule);
*result = protocol::CSS::Value::create()
@@ -1402,22 +1414,23 @@ Response InspectorCSSAgent::MultipleStyleTextsActions(
HeapVector<Member<StyleSheetAction>>* actions) {
size_t n = edits->size();
if (n == 0)
- return Response::Error("Edits should not be empty");
+ return Response::ServerError("Edits should not be empty");
for (size_t i = 0; i < n; ++i) {
protocol::CSS::StyleDeclarationEdit* edit = (*edits)[i].get();
InspectorStyleSheetBase* inspector_style_sheet = nullptr;
Response response =
AssertStyleSheetForId(edit->getStyleSheetId(), inspector_style_sheet);
- if (!response.isSuccess()) {
- return Response::Error(String::Format(
- "StyleSheet not found for edit #%zu of %zu", i + 1, n));
+ if (!response.IsSuccess()) {
+ return Response::ServerError(
+ String::Format("StyleSheet not found for edit #%zu of %zu", i + 1, n)
+ .Utf8());
}
SourceRange range;
response =
JsonRangeToSourceRange(inspector_style_sheet, edit->getRange(), &range);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
if (inspector_style_sheet->IsInlineStyle()) {
@@ -1436,7 +1449,7 @@ Response InspectorCSSAgent::MultipleStyleTextsActions(
actions->push_back(action);
}
}
- return Response::OK();
+ return Response::Success();
}
Response InspectorCSSAgent::setStyleTexts(
@@ -1445,7 +1458,7 @@ Response InspectorCSSAgent::setStyleTexts(
FrontendOperationScope scope;
HeapVector<Member<StyleSheetAction>> actions;
Response response = MultipleStyleTextsActions(std::move(edits), &actions);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
DummyExceptionStateForTesting exception_state;
@@ -1463,9 +1476,9 @@ Response InspectorCSSAgent::setStyleTexts(
revert->Undo(undo_exception_state);
DCHECK(!undo_exception_state.HadException());
}
- return Response::Error(
- String::Format("Failed applying edit #%d: ", i) +
- InspectorDOMAgent::ToResponse(exception_state).errorMessage());
+ return Response::ServerError(
+ String::Format("Failed applying edit #%d: ", i).Utf8() +
+ InspectorDOMAgent::ToResponse(exception_state).Message());
}
serialized_styles->emplace_back(action->TakeSerializedStyle());
}
@@ -1475,7 +1488,7 @@ Response InspectorCSSAgent::setStyleTexts(
dom_agent_->History()->AppendPerformedAction(action);
}
*result = std::move(serialized_styles);
- return Response::OK();
+ return Response::Success();
}
Response InspectorCSSAgent::SetStyleText(
@@ -1492,7 +1505,7 @@ Response InspectorCSSAgent::SetStyleText(
bool success = dom_agent_->History()->Perform(action, exception_state);
if (success) {
result = inline_style_sheet->InlineStyle();
- return Response::OK();
+ return Response::Success();
}
} else {
ModifyRuleAction* action = MakeGarbageCollected<ModifyRuleAction>(
@@ -1503,11 +1516,11 @@ Response InspectorCSSAgent::SetStyleText(
CSSRule* rule = action->TakeRule();
if (auto* style_rule = DynamicTo<CSSStyleRule>(rule)) {
result = style_rule->style();
- return Response::OK();
+ return Response::Success();
}
if (auto* keyframe_rule = DynamicTo<CSSKeyframeRule>(rule)) {
result = keyframe_rule->style();
- return Response::OK();
+ return Response::Success();
}
}
}
@@ -1523,12 +1536,12 @@ Response InspectorCSSAgent::setMediaText(
InspectorStyleSheet* inspector_style_sheet = nullptr;
Response response =
AssertInspectorStyleSheetForId(style_sheet_id, inspector_style_sheet);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
SourceRange text_range;
response =
JsonRangeToSourceRange(inspector_style_sheet, range.get(), &text_range);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
DummyExceptionStateForTesting exception_state;
@@ -1554,20 +1567,20 @@ Response InspectorCSSAgent::createStyleSheet(
LocalFrame* frame =
IdentifiersFactory::FrameById(inspected_frames_, frame_id);
if (!frame)
- return Response::Error("Frame not found");
+ return Response::ServerError("Frame not found");
Document* document = frame->GetDocument();
if (!document)
- return Response::Error("Frame does not have a document");
+ return Response::ServerError("Frame does not have a document");
InspectorStyleSheet* inspector_style_sheet = ViaInspectorStyleSheet(document);
if (!inspector_style_sheet)
- return Response::Error("No target stylesheet found");
+ return Response::ServerError("No target stylesheet found");
UpdateActiveStyleSheets(document);
*out_style_sheet_id = inspector_style_sheet->Id();
- return Response::OK();
+ return Response::Success();
}
Response InspectorCSSAgent::addRule(
@@ -1579,12 +1592,12 @@ Response InspectorCSSAgent::addRule(
InspectorStyleSheet* inspector_style_sheet = nullptr;
Response response =
AssertInspectorStyleSheetForId(style_sheet_id, inspector_style_sheet);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
SourceRange rule_location;
response = JsonRangeToSourceRange(inspector_style_sheet, location.get(),
&rule_location);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
DummyExceptionStateForTesting exception_state;
@@ -1596,18 +1609,18 @@ Response InspectorCSSAgent::addRule(
CSSStyleRule* rule = action->TakeRule();
*result = BuildObjectForRule(rule);
- return Response::OK();
+ return Response::Success();
}
Response InspectorCSSAgent::forcePseudoState(
int node_id,
std::unique_ptr<protocol::Array<String>> forced_pseudo_classes) {
Response response = AssertEnabled();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
Element* element = nullptr;
response = dom_agent_->AssertElement(node_id, element);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
unsigned forced_pseudo_state =
@@ -1618,7 +1631,7 @@ Response InspectorCSSAgent::forcePseudoState(
it == node_id_to_forced_pseudo_state_.end() ? 0 : it->value;
bool need_style_recalc = forced_pseudo_state != current_forced_pseudo_state;
if (!need_style_recalc)
- return Response::OK();
+ return Response::Success();
if (forced_pseudo_state)
node_id_to_forced_pseudo_state_.Set(node_id, forced_pseudo_state);
@@ -1626,7 +1639,7 @@ Response InspectorCSSAgent::forcePseudoState(
node_id_to_forced_pseudo_state_.erase(node_id);
element->ownerDocument()->GetStyleEngine().MarkAllElementsForStyleRecalc(
StyleChangeReasonForTracing::Create(style_change_reason::kInspector));
- return Response::OK();
+ return Response::Success();
}
std::unique_ptr<protocol::CSS::CSSMedia> InspectorCSSAgent::BuildMediaObject(
@@ -1715,9 +1728,11 @@ std::unique_ptr<protocol::CSS::CSSMedia> InspectorCSSAgent::BuildMediaObject(
has_media_query_items = true;
}
+ // The |mediaText()| getter does not require an ExecutionContext as it is
+ // only used for setting/parsing new media queries and features.
std::unique_ptr<protocol::CSS::CSSMedia> media_object =
protocol::CSS::CSSMedia::create()
- .setText(media->mediaText())
+ .setText(media->mediaText(/*execution_context=*/nullptr))
.setSource(source)
.build();
if (has_media_query_items)
@@ -1832,7 +1847,7 @@ InspectorStyleSheetForInlineStyle* InspectorCSSAgent::AsInspectorStyleSheet(
return nullptr;
InspectorStyleSheetForInlineStyle* inspector_style_sheet =
- InspectorStyleSheetForInlineStyle::Create(element, this);
+ MakeGarbageCollected<InspectorStyleSheetForInlineStyle>(element, this);
id_to_inspector_style_sheet_for_inline_style_.Set(inspector_style_sheet->Id(),
inspector_style_sheet);
node_to_inspector_style_sheet_.Set(element, inspector_style_sheet);
@@ -1869,7 +1884,7 @@ InspectorStyleSheet* InspectorCSSAgent::BindStyleSheet(
css_style_sheet_to_inspector_style_sheet_.at(style_sheet);
if (!inspector_style_sheet) {
Document* document = style_sheet->OwnerDocument();
- inspector_style_sheet = InspectorStyleSheet::Create(
+ inspector_style_sheet = MakeGarbageCollected<InspectorStyleSheet>(
network_agent_, style_sheet, DetectOrigin(style_sheet, document),
InspectorDOMAgent::DocumentURLString(document), this,
resource_container_);
@@ -1917,7 +1932,7 @@ InspectorStyleSheet* InspectorCSSAgent::ViaInspectorStyleSheet(
if (!document)
return nullptr;
- if (!document->IsHTMLDocument() && !document->IsSVGDocument())
+ if (!IsA<HTMLDocument>(document) && !document->IsSVGDocument())
return nullptr;
CSSStyleSheet& inspector_sheet =
@@ -1929,22 +1944,22 @@ InspectorStyleSheet* InspectorCSSAgent::ViaInspectorStyleSheet(
}
Response InspectorCSSAgent::AssertEnabled() {
- return enable_completed_ ? Response::OK()
- : Response::Error("CSS agent was not enabled");
+ return enable_completed_ ? Response::Success()
+ : Response::ServerError("CSS agent was not enabled");
}
Response InspectorCSSAgent::AssertInspectorStyleSheetForId(
const String& style_sheet_id,
InspectorStyleSheet*& result) {
Response response = AssertEnabled();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
IdToInspectorStyleSheet::iterator it =
id_to_inspector_style_sheet_.find(style_sheet_id);
if (it == id_to_inspector_style_sheet_.end())
- return Response::Error("No style sheet with given id found");
+ return Response::ServerError("No style sheet with given id found");
result = it->value.Get();
- return Response::OK();
+ return Response::Success();
}
Response InspectorCSSAgent::AssertStyleSheetForId(
@@ -1953,16 +1968,16 @@ Response InspectorCSSAgent::AssertStyleSheetForId(
InspectorStyleSheet* style_sheet = nullptr;
Response response =
AssertInspectorStyleSheetForId(style_sheet_id, style_sheet);
- if (response.isSuccess()) {
+ if (response.IsSuccess()) {
result = style_sheet;
return response;
}
IdToInspectorStyleSheetForInlineStyle::iterator it =
id_to_inspector_style_sheet_for_inline_style_.find(style_sheet_id);
if (it == id_to_inspector_style_sheet_for_inline_style_.end())
- return Response::Error("No style sheet with given id found");
+ return Response::ServerError("No style sheet with given id found");
result = it->value.Get();
- return Response::OK();
+ return Response::Success();
}
protocol::CSS::StyleSheetOrigin InspectorCSSAgent::DetectOrigin(
@@ -2077,7 +2092,9 @@ InspectorCSSAgent::BuildObjectForAttributesStyle(Element* element) {
return nullptr;
InspectorStyle* inspector_style = MakeGarbageCollected<InspectorStyle>(
- mutable_attribute_style->EnsureCSSStyleDeclaration(), nullptr, nullptr);
+ mutable_attribute_style->EnsureCSSStyleDeclaration(
+ element->GetExecutionContext()),
+ nullptr, nullptr);
return inspector_style->BuildObjectForStyle();
}
@@ -2196,25 +2213,28 @@ Response InspectorCSSAgent::setEffectivePropertyValueForNode(
const String& value) {
Element* element = nullptr;
Response response = dom_agent_->AssertElement(node_id, element);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
if (element->GetPseudoId())
- return Response::Error("Elements is pseudo");
+ return Response::ServerError("Elements is pseudo");
- CSSPropertyID property = cssPropertyID(property_name);
- if (!isValidCSSPropertyID(property))
- return Response::Error("Invalid property name");
+ if (!element->ownerDocument()->IsActive()) {
+ return Response::ServerError(
+ "Can't edit a node from a non-active document");
+ }
- Document* owner_document = element->ownerDocument();
- if (!owner_document->IsActive())
- return Response::Error("Can't edit a node from a non-active document");
+ CSSPropertyID property =
+ cssPropertyID(element->GetExecutionContext(), property_name);
+ if (!isValidCSSPropertyID(property))
+ return Response::ServerError("Invalid property name");
- CSSPropertyID property_id = cssPropertyID(property_name);
+ CSSPropertyID property_id =
+ cssPropertyID(element->GetExecutionContext(), property_name);
const CSSProperty& property_class = CSSProperty::Get(property_id);
CSSStyleDeclaration* style =
FindEffectiveDeclaration(property_class, MatchingStyles(element));
if (!style)
- return Response::Error("Can't find a style to edit");
+ return Response::ServerError("Can't find a style to edit");
bool force_important = false;
InspectorStyleSheetBase* inspector_style_sheet = nullptr;
@@ -2233,7 +2253,7 @@ Response InspectorCSSAgent::setEffectivePropertyValueForNode(
}
if (!source_data)
- return Response::Error("Can't find a source to edit");
+ return Response::ServerError("Can't find a source to edit");
Vector<StylePropertyShorthand, 4> shorthands;
getMatchingShorthandsForLonghand(property_id, &shorthands);
@@ -2305,7 +2325,7 @@ Response InspectorCSSAgent::getBackgroundColors(
Maybe<String>* computed_font_weight) {
Element* element = nullptr;
Response response = dom_agent_->AssertElement(node_id, element);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
Vector<Color> bgcolors;
@@ -2324,7 +2344,7 @@ Response InspectorCSSAgent::getBackgroundColors(
*computed_font_size = fs;
if (!fw.IsEmpty())
*computed_font_weight = fw;
- return Response::OK();
+ return Response::Success();
}
// static
@@ -2401,26 +2421,30 @@ Response InspectorCSSAgent::startRuleUsageTracking() {
document->UpdateStyleAndLayoutTree();
}
- return Response::OK();
+ return Response::Success();
}
Response InspectorCSSAgent::stopRuleUsageTracking(
std::unique_ptr<protocol::Array<protocol::CSS::RuleUsage>>* result) {
for (Document* document : dom_agent_->Documents())
document->UpdateStyleAndLayoutTree();
- Response response = takeCoverageDelta(result);
+ double timestamp;
+ Response response = takeCoverageDelta(result, &timestamp);
SetCoverageEnabled(false);
return response;
}
Response InspectorCSSAgent::takeCoverageDelta(
- std::unique_ptr<protocol::Array<protocol::CSS::RuleUsage>>* result) {
+ std::unique_ptr<protocol::Array<protocol::CSS::RuleUsage>>* result,
+ double* out_timestamp) {
if (!tracker_)
- return Response::Error("CSS rule usage tracking is not enabled");
+ return Response::ServerError("CSS rule usage tracking is not enabled");
StyleRuleUsageTracker::RuleListByStyleSheet coverage_delta =
tracker_->TakeDelta();
+ *out_timestamp = base::TimeTicks::Now().since_origin().InSecondsF();
+
*result = std::make_unique<protocol::Array<protocol::CSS::RuleUsage>>();
for (const auto& entry : coverage_delta) {
@@ -2448,10 +2472,10 @@ Response InspectorCSSAgent::takeCoverageDelta(
}
}
- return Response::OK();
+ return Response::Success();
}
-void InspectorCSSAgent::Trace(blink::Visitor* visitor) {
+void InspectorCSSAgent::Trace(Visitor* visitor) {
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 481c6b3531c..5815c86fbdb 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
@@ -89,7 +89,7 @@ class CORE_EXPORT InspectorCSSAgent final
}
private:
- Member<ContentSecurityPolicy> content_security_policy_;
+ ContentSecurityPolicy* content_security_policy_;
};
static CSSStyleRule* AsCSSStyleRule(CSSRule*);
@@ -109,7 +109,7 @@ class CORE_EXPORT InspectorCSSAgent final
InspectorResourceContentLoader*,
InspectorResourceContainer*);
~InspectorCSSAgent() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void ForcePseudoState(Element*, CSSSelector::PseudoType, bool* result);
void DidCommitLoadForLocalFrame(LocalFrame*) override;
@@ -202,8 +202,8 @@ class CORE_EXPORT InspectorCSSAgent final
protocol::Response startRuleUsageTracking() override;
protocol::Response takeCoverageDelta(
- std::unique_ptr<protocol::Array<protocol::CSS::RuleUsage>>* result)
- override;
+ std::unique_ptr<protocol::Array<protocol::CSS::RuleUsage>>* result,
+ double* out_timestamp) override;
protocol::Response stopRuleUsageTracking(
std::unique_ptr<protocol::Array<protocol::CSS::RuleUsage>>* result)
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 793c27538ba..ce49bb82a00 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
@@ -52,11 +52,13 @@
#include "third_party/blink/renderer/core/dom/static_node_list.h"
#include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/dom/v0_insertion_point.h"
+#include "third_party/blink/renderer/core/dom/xml_document.h"
#include "third_party/blink/renderer/core/editing/serializers/serialization.h"
#include "third_party/blink/renderer/core/frame/frame.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/remote_frame.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.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_link_element.h"
#include "third_party/blink/renderer/core/html/html_slot_element.h"
@@ -108,7 +110,7 @@ class InspectorRevalidateDOMTask final
void ScheduleStyleAttrRevalidationFor(Element*);
void Reset() { timer_.Stop(); }
void OnTimer(TimerBase*);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
Member<InspectorDOMAgent> dom_agent_;
@@ -141,7 +143,7 @@ void InspectorRevalidateDOMTask::OnTimer(TimerBase*) {
style_attr_invalidated_elements_.clear();
}
-void InspectorRevalidateDOMTask::Trace(blink::Visitor* visitor) {
+void InspectorRevalidateDOMTask::Trace(Visitor* visitor) {
visitor->Trace(dom_agent_);
visitor->Trace(style_attr_invalidated_elements_);
}
@@ -153,61 +155,51 @@ Response InspectorDOMAgent::ToResponse(ExceptionState& exception_state) {
exception_state.CodeAs<DOMExceptionCode>()) +
" "
: g_empty_string;
- return Response::Error(name_prefix + exception_state.Message());
+ String msg = name_prefix + exception_state.Message();
+ return Response::ServerError(msg.Utf8());
}
- return Response::OK();
+ return Response::Success();
}
-bool InspectorDOMAgent::GetPseudoElementType(PseudoId pseudo_id,
- protocol::DOM::PseudoType* type) {
+protocol::DOM::PseudoType InspectorDOMAgent::ProtocolPseudoElementType(
+ PseudoId pseudo_id) {
switch (pseudo_id) {
case kPseudoIdFirstLine:
- *type = protocol::DOM::PseudoTypeEnum::FirstLine;
- return true;
+ return protocol::DOM::PseudoTypeEnum::FirstLine;
case kPseudoIdFirstLetter:
- *type = protocol::DOM::PseudoTypeEnum::FirstLetter;
- return true;
+ return protocol::DOM::PseudoTypeEnum::FirstLetter;
case kPseudoIdBefore:
- *type = protocol::DOM::PseudoTypeEnum::Before;
- return true;
+ return protocol::DOM::PseudoTypeEnum::Before;
case kPseudoIdAfter:
- *type = protocol::DOM::PseudoTypeEnum::After;
- return true;
+ return protocol::DOM::PseudoTypeEnum::After;
+ case kPseudoIdMarker:
+ return protocol::DOM::PseudoTypeEnum::Marker;
case kPseudoIdBackdrop:
- *type = protocol::DOM::PseudoTypeEnum::Backdrop;
- return true;
+ return protocol::DOM::PseudoTypeEnum::Backdrop;
case kPseudoIdSelection:
- *type = protocol::DOM::PseudoTypeEnum::Selection;
- return true;
+ return protocol::DOM::PseudoTypeEnum::Selection;
case kPseudoIdFirstLineInherited:
- *type = protocol::DOM::PseudoTypeEnum::FirstLineInherited;
- return true;
+ return protocol::DOM::PseudoTypeEnum::FirstLineInherited;
case kPseudoIdScrollbar:
- *type = protocol::DOM::PseudoTypeEnum::Scrollbar;
- return true;
+ return protocol::DOM::PseudoTypeEnum::Scrollbar;
case kPseudoIdScrollbarThumb:
- *type = protocol::DOM::PseudoTypeEnum::ScrollbarThumb;
- return true;
+ return protocol::DOM::PseudoTypeEnum::ScrollbarThumb;
case kPseudoIdScrollbarButton:
- *type = protocol::DOM::PseudoTypeEnum::ScrollbarButton;
- return true;
+ return protocol::DOM::PseudoTypeEnum::ScrollbarButton;
case kPseudoIdScrollbarTrack:
- *type = protocol::DOM::PseudoTypeEnum::ScrollbarTrack;
- return true;
+ return protocol::DOM::PseudoTypeEnum::ScrollbarTrack;
case kPseudoIdScrollbarTrackPiece:
- *type = protocol::DOM::PseudoTypeEnum::ScrollbarTrackPiece;
- return true;
+ return protocol::DOM::PseudoTypeEnum::ScrollbarTrackPiece;
case kPseudoIdScrollbarCorner:
- *type = protocol::DOM::PseudoTypeEnum::ScrollbarCorner;
- return true;
+ return protocol::DOM::PseudoTypeEnum::ScrollbarCorner;
case kPseudoIdResizer:
- *type = protocol::DOM::PseudoTypeEnum::Resizer;
- return true;
+ return protocol::DOM::PseudoTypeEnum::Resizer;
case kPseudoIdInputListButton:
- *type = protocol::DOM::PseudoTypeEnum::InputListButton;
- return true;
- default:
- return false;
+ return protocol::DOM::PseudoTypeEnum::InputListButton;
+ case kAfterLastInternalPseudoId:
+ case kPseudoIdNone:
+ CHECK(false);
+ return "";
}
}
@@ -330,6 +322,8 @@ void InspectorDOMAgent::Unbind(Node* node, NodeToIdMap* nodes_map) {
Unbind(element->GetPseudoElement(kPseudoIdBefore), nodes_map);
if (element->GetPseudoElement(kPseudoIdAfter))
Unbind(element->GetPseudoElement(kPseudoIdAfter), nodes_map);
+ if (element->GetPseudoElement(kPseudoIdMarker))
+ Unbind(element->GetPseudoElement(kPseudoIdMarker), nodes_map);
if (auto* link_element = DynamicTo<HTMLLinkElement>(*element)) {
if (link_element->IsImport() && link_element->import())
@@ -358,8 +352,8 @@ void InspectorDOMAgent::Unbind(Node* node, NodeToIdMap* nodes_map) {
Response InspectorDOMAgent::AssertNode(int node_id, Node*& node) {
node = NodeForId(node_id);
if (!node)
- return Response::Error("Could not find node with given id");
- return Response::OK();
+ return Response::ServerError("Could not find node with given id");
+ return Response::Success();
}
Response InspectorDOMAgent::AssertNode(
@@ -372,27 +366,27 @@ Response InspectorDOMAgent::AssertNode(
if (backend_node_id.isJust()) {
node = DOMNodeIds::NodeForId(backend_node_id.fromJust());
- return !node ? Response::Error("No node found for given backend id")
- : Response::OK();
+ return !node ? Response::ServerError("No node found for given backend id")
+ : Response::Success();
}
if (object_id.isJust())
return NodeForRemoteObjectId(object_id.fromJust(), node);
- return Response::Error(
+ return Response::ServerError(
"Either nodeId, backendNodeId or objectId must be specified");
}
Response InspectorDOMAgent::AssertElement(int node_id, Element*& element) {
Node* node = nullptr;
Response response = AssertNode(node_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
element = DynamicTo<Element>(node);
if (!element)
- return Response::Error("Node is not an Element");
- return Response::OK();
+ return Response::ServerError("Node is not an Element");
+ return Response::Success();
}
// static
@@ -411,45 +405,49 @@ ShadowRoot* InspectorDOMAgent::UserAgentShadowRoot(Node* node) {
Response InspectorDOMAgent::AssertEditableNode(int node_id, Node*& node) {
Response response = AssertNode(node_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
if (node->IsInShadowTree()) {
if (IsA<ShadowRoot>(node))
- return Response::Error("Cannot edit shadow roots");
- if (UserAgentShadowRoot(node))
- return Response::Error("Cannot edit nodes from user-agent shadow trees");
+ return Response::ServerError("Cannot edit shadow roots");
+ if (UserAgentShadowRoot(node)) {
+ return Response::ServerError(
+ "Cannot edit nodes from user-agent shadow trees");
+ }
}
if (node->IsPseudoElement())
- return Response::Error("Cannot edit pseudo elements");
- return Response::OK();
+ return Response::ServerError("Cannot edit pseudo elements");
+ return Response::Success();
}
Response InspectorDOMAgent::AssertEditableChildNode(Element* parent_element,
int node_id,
Node*& node) {
Response response = AssertEditableNode(node_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
- if (node->parentNode() != parent_element)
- return Response::Error("Anchor node must be child of the target element");
- return Response::OK();
+ if (node->parentNode() != parent_element) {
+ return Response::ServerError(
+ "Anchor node must be child of the target element");
+ }
+ return Response::Success();
}
Response InspectorDOMAgent::AssertEditableElement(int node_id,
Element*& element) {
Response response = AssertElement(node_id, element);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
-
- if (element->IsInShadowTree() && UserAgentShadowRoot(element))
- return Response::Error("Cannot edit elements from user-agent shadow trees");
-
+ if (element->IsInShadowTree() && UserAgentShadowRoot(element)) {
+ return Response::ServerError(
+ "Cannot edit elements from user-agent shadow trees");
+ }
if (element->IsPseudoElement())
- return Response::Error("Cannot edit pseudo elements");
+ return Response::ServerError("Cannot edit pseudo elements");
- return Response::OK();
+ return Response::Success();
}
void InspectorDOMAgent::EnableAndReset() {
@@ -463,18 +461,18 @@ void InspectorDOMAgent::EnableAndReset() {
Response InspectorDOMAgent::enable() {
if (!enabled_.Get())
EnableAndReset();
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::disable() {
if (!enabled_.Get())
- return Response::Error("DOM agent hasn't been enabled");
+ return Response::ServerError("DOM agent hasn't been enabled");
enabled_.Clear();
instrumenting_agents_->RemoveInspectorDOMAgent(this);
history_.Clear();
dom_editor_.Clear();
SetDocument(nullptr);
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::getDocument(
@@ -485,7 +483,7 @@ Response InspectorDOMAgent::getDocument(
enable();
if (!document_)
- return Response::Error("Document is not available");
+ return Response::ServerError("Document is not available");
DiscardFrontendBindings();
@@ -496,7 +494,7 @@ Response InspectorDOMAgent::getDocument(
*root = BuildObjectForNode(document_.Get(), sanitized_depth,
pierce.fromMaybe(false),
document_node_to_id_map_.Get());
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::getFlattenedDocument(
@@ -504,10 +502,10 @@ Response InspectorDOMAgent::getFlattenedDocument(
Maybe<bool> pierce,
std::unique_ptr<protocol::Array<protocol::DOM::Node>>* nodes) {
if (!enabled_.Get())
- return Response::Error("DOM agent hasn't been enabled");
+ return Response::ServerError("DOM agent hasn't been enabled");
if (!document_)
- return Response::Error("Document is not available");
+ return Response::ServerError("Document is not available");
DiscardFrontendBindings();
@@ -519,7 +517,7 @@ Response InspectorDOMAgent::getFlattenedDocument(
(*nodes)->emplace_back(BuildObjectForNode(
document_.Get(), sanitized_depth, pierce.fromMaybe(false),
document_node_to_id_map_.Get(), nodes->get()));
- return Response::OK();
+ return Response::Success();
}
void InspectorDOMAgent::PushChildNodesToFrontend(int node_id,
@@ -585,7 +583,7 @@ Response InspectorDOMAgent::collectClassNamesFromSubtree(
auto* parent_element = DynamicTo<Element>(parent_node);
if (!parent_element && !parent_node->IsDocumentNode() &&
!parent_node->IsDocumentFragment())
- return Response::Error("No suitable node with given id found");
+ return Response::ServerError("No suitable node with given id found");
for (Node* node = parent_node; node;
node = FlatTreeTraversal::Next(*node, parent_node)) {
@@ -599,7 +597,7 @@ Response InspectorDOMAgent::collectClassNamesFromSubtree(
}
for (const String& class_name : unique_names)
(*class_names)->emplace_back(class_name);
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::requestChildNodes(
@@ -608,7 +606,7 @@ Response InspectorDOMAgent::requestChildNodes(
Maybe<bool> maybe_taverse_frames) {
int sanitized_depth = depth.fromMaybe(1);
if (sanitized_depth == 0 || sanitized_depth < -1) {
- return Response::Error(
+ return Response::ServerError(
"Please provide a positive integer as a depth or -1 for entire "
"subtree");
}
@@ -617,7 +615,7 @@ Response InspectorDOMAgent::requestChildNodes(
PushChildNodesToFrontend(node_id, sanitized_depth,
maybe_taverse_frames.fromMaybe(false));
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::querySelector(int node_id,
@@ -626,21 +624,21 @@ Response InspectorDOMAgent::querySelector(int node_id,
*element_id = 0;
Node* node = nullptr;
Response response = AssertNode(node_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
auto* container_node = DynamicTo<ContainerNode>(node);
if (!container_node)
- return Response::Error("Not a container node");
+ return Response::ServerError("Not a container node");
DummyExceptionStateForTesting exception_state;
Element* element =
container_node->QuerySelector(AtomicString(selectors), exception_state);
if (exception_state.HadException())
- return Response::Error("DOM Error while querying");
+ return Response::ServerError("DOM Error while querying");
if (element)
*element_id = PushNodePathToFrontend(element);
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::querySelectorAll(
@@ -649,23 +647,23 @@ Response InspectorDOMAgent::querySelectorAll(
std::unique_ptr<protocol::Array<int>>* result) {
Node* node = nullptr;
Response response = AssertNode(node_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
auto* container_node = DynamicTo<ContainerNode>(node);
if (!container_node)
- return Response::Error("Not a container node");
+ return Response::ServerError("Not a container node");
DummyExceptionStateForTesting exception_state;
StaticElementList* elements = container_node->QuerySelectorAll(
AtomicString(selectors), exception_state);
if (exception_state.HadException())
- return Response::Error("DOM Error while querying");
+ return Response::ServerError("DOM Error while querying");
*result = std::make_unique<protocol::Array<int>>();
for (unsigned i = 0; i < elements->length(); ++i)
(*result)->emplace_back(PushNodePathToFrontend(elements->item(i)));
- return Response::OK();
+ return Response::Success();
}
int InspectorDOMAgent::PushNodePathToFrontend(Node* node_to_push,
@@ -736,7 +734,7 @@ Response InspectorDOMAgent::setAttributeValue(int element_id,
const String& value) {
Element* element = nullptr;
Response response = AssertEditableElement(element_id, element);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
return dom_editor_->SetAttribute(element, name, value);
}
@@ -746,14 +744,14 @@ Response InspectorDOMAgent::setAttributesAsText(int element_id,
Maybe<String> name) {
Element* element = nullptr;
Response response = AssertEditableElement(element_id, element);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
String markup = "<span " + text + "></span>";
DocumentFragment* fragment = element->GetDocument().createDocumentFragment();
bool should_ignore_case =
- element->GetDocument().IsHTMLDocument() && element->IsHTMLElement();
+ IsA<HTMLDocument>(element->GetDocument()) && element->IsHTMLElement();
// Not all elements can represent the context (i.e. IFRAME), hence using
// document.body.
if (should_ignore_case && element->GetDocument().body()) {
@@ -768,7 +766,7 @@ Response InspectorDOMAgent::setAttributesAsText(int element_id,
Element* parsed_element = DynamicTo<Element>(fragment->firstChild());
if (!parsed_element)
- return Response::Error("Could not parse value as attributes");
+ return Response::ServerError("Could not parse value as attributes");
String case_adjusted_name = should_ignore_case
? name.fromMaybe("").DeprecatedLower()
@@ -788,7 +786,7 @@ Response InspectorDOMAgent::setAttributesAsText(int element_id,
name.isJust() && attribute_name == case_adjusted_name;
Response response =
dom_editor_->SetAttribute(element, attribute_name, attribute.Value());
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
}
@@ -796,14 +794,14 @@ Response InspectorDOMAgent::setAttributesAsText(int element_id,
!name.fromJust().StripWhiteSpace().IsEmpty()) {
return dom_editor_->RemoveAttribute(element, case_adjusted_name);
}
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::removeAttribute(int element_id,
const String& name) {
Element* element = nullptr;
Response response = AssertEditableElement(element_id, element);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
return dom_editor_->RemoveAttribute(element, name);
@@ -812,12 +810,12 @@ Response InspectorDOMAgent::removeAttribute(int element_id,
Response InspectorDOMAgent::removeNode(int node_id) {
Node* node = nullptr;
Response response = AssertEditableNode(node_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
ContainerNode* parent_node = node->parentNode();
if (!parent_node)
- return Response::Error("Cannot remove detached node");
+ return Response::ServerError("Cannot remove detached node");
return dom_editor_->RemoveChild(parent_node, node);
}
@@ -829,7 +827,7 @@ Response InspectorDOMAgent::setNodeName(int node_id,
Element* old_element = nullptr;
Response response = AssertElement(node_id, old_element);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
DummyExceptionStateForTesting exception_state;
@@ -845,7 +843,7 @@ Response InspectorDOMAgent::setNodeName(int node_id,
for (Node* child = old_element->firstChild(); child;
child = old_element->firstChild()) {
response = dom_editor_->InsertBefore(new_elem, child, nullptr);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
}
@@ -853,16 +851,16 @@ Response InspectorDOMAgent::setNodeName(int node_id,
ContainerNode* parent = old_element->parentNode();
response =
dom_editor_->InsertBefore(parent, new_elem, old_element->nextSibling());
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
response = dom_editor_->RemoveChild(parent, old_element);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
*new_id = PushNodePathToFrontend(new_elem);
if (children_requested_.Contains(node_id))
PushChildNodesToFrontend(*new_id);
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::getOuterHTML(Maybe<int> node_id,
@@ -871,11 +869,11 @@ Response InspectorDOMAgent::getOuterHTML(Maybe<int> node_id,
WTF::String* outer_html) {
Node* node = nullptr;
Response response = AssertNode(node_id, backend_node_id, object_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
*outer_html = CreateMarkup(node);
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::setOuterHTML(int node_id,
@@ -884,27 +882,28 @@ Response InspectorDOMAgent::setOuterHTML(int node_id,
DCHECK(document_);
DOMPatchSupport dom_patch_support(dom_editor_.Get(), *document_.Get());
dom_patch_support.PatchDocument(outer_html);
- return Response::OK();
+ return Response::Success();
}
Node* node = nullptr;
Response response = AssertEditableNode(node_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
Document* document =
IsA<Document>(node) ? To<Document>(node) : node->ownerDocument();
- if (!document || (!document->IsHTMLDocument() && !document->IsXMLDocument()))
- return Response::Error("Not an HTML/XML document");
+ if (!document ||
+ (!IsA<HTMLDocument>(document) && !IsA<XMLDocument>(document)))
+ return Response::ServerError("Not an HTML/XML document");
Node* new_node = nullptr;
response = dom_editor_->SetOuterHTML(node, outer_html, &new_node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
if (!new_node) {
// The only child node has been deleted.
- return Response::OK();
+ return Response::Success();
}
int new_id = PushNodePathToFrontend(new_node);
@@ -912,17 +911,17 @@ Response InspectorDOMAgent::setOuterHTML(int node_id,
bool children_requested = children_requested_.Contains(node_id);
if (children_requested)
PushChildNodesToFrontend(new_id);
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::setNodeValue(int node_id, const String& value) {
Node* node = nullptr;
Response response = AssertEditableNode(node_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
if (node->getNodeType() != Node::kTextNode)
- return Response::Error("Can only set value of text nodes");
+ return Response::ServerError("Can only set value of text nodes");
return dom_editor_->ReplaceWholeText(To<Text>(node), value);
}
@@ -964,7 +963,7 @@ Response InspectorDOMAgent::performSearch(
String* search_id,
int* result_count) {
if (!enabled_.Get())
- return Response::Error("DOM agent is not enabled");
+ return Response::ServerError("DOM agent is not enabled");
// FIXME: Few things are missing here:
// 1) Search works with node granularity - number of matches within node is
@@ -1106,7 +1105,7 @@ Response InspectorDOMAgent::performSearch(
results_it->push_back(result);
*result_count = results_it->size();
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::getSearchResults(
@@ -1116,21 +1115,21 @@ Response InspectorDOMAgent::getSearchResults(
std::unique_ptr<protocol::Array<int>>* node_ids) {
SearchResults::iterator it = search_results_.find(search_id);
if (it == search_results_.end())
- return Response::Error("No search session with given id found");
+ return Response::ServerError("No search session with given id found");
int size = it->value.size();
if (from_index < 0 || to_index > size || from_index >= to_index)
- return Response::Error("Invalid search result range");
+ return Response::ServerError("Invalid search result range");
*node_ids = std::make_unique<protocol::Array<int>>();
for (int i = from_index; i < to_index; ++i)
(*node_ids)->emplace_back(PushNodePathToFrontend((it->value)[i].Get()));
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::discardSearchResults(const String& search_id) {
search_results_.erase(search_id);
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::NodeForRemoteObjectId(const String& object_id,
@@ -1141,15 +1140,15 @@ Response InspectorDOMAgent::NodeForRemoteObjectId(const String& object_id,
std::unique_ptr<v8_inspector::StringBuffer> error;
if (!v8_session_->unwrapObject(&error, ToV8InspectorStringView(object_id),
&value, &context, nullptr))
- return Response::Error(ToCoreString(std::move(error)));
+ return Response::ServerError(ToCoreString(std::move(error)).Utf8());
if (!V8Node::HasInstance(value, isolate_))
- return Response::Error("Object id doesn't reference a Node");
+ return Response::ServerError("Object id doesn't reference a Node");
node = V8Node::ToImpl(v8::Local<v8::Object>::Cast(value));
if (!node) {
- return Response::Error(
+ return Response::ServerError(
"Couldn't convert object with given objectId to Node");
}
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::copyTo(int node_id,
@@ -1158,33 +1157,33 @@ Response InspectorDOMAgent::copyTo(int node_id,
int* new_node_id) {
Node* node = nullptr;
Response response = AssertEditableNode(node_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
Element* target_element = nullptr;
response = AssertEditableElement(target_element_id, target_element);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
Node* anchor_node = nullptr;
if (anchor_node_id.isJust() && anchor_node_id.fromJust()) {
response = AssertEditableChildNode(target_element,
anchor_node_id.fromJust(), anchor_node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
}
// The clone is deep by default.
Node* cloned_node = node->cloneNode(true);
if (!cloned_node)
- return Response::Error("Failed to clone node");
+ return Response::ServerError("Failed to clone node");
response =
dom_editor_->InsertBefore(target_element, cloned_node, anchor_node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
*new_node_id = PushNodePathToFrontend(cloned_node);
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::moveTo(int node_id,
@@ -1193,18 +1192,20 @@ Response InspectorDOMAgent::moveTo(int node_id,
int* new_node_id) {
Node* node = nullptr;
Response response = AssertEditableNode(node_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
Element* target_element = nullptr;
response = AssertEditableElement(target_element_id, target_element);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
Node* current = target_element;
while (current) {
- if (current == node)
- return Response::Error("Unable to move node into self or descendant");
+ if (current == node) {
+ return Response::ServerError(
+ "Unable to move node into self or descendant");
+ }
current = current->parentNode();
}
@@ -1212,21 +1213,21 @@ Response InspectorDOMAgent::moveTo(int node_id,
if (anchor_node_id.isJust() && anchor_node_id.fromJust()) {
response = AssertEditableChildNode(target_element,
anchor_node_id.fromJust(), anchor_node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
}
response = dom_editor_->InsertBefore(target_element, node, anchor_node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
*new_node_id = PushNodePathToFrontend(node);
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::undo() {
if (!enabled_.Get())
- return Response::Error("DOM agent is not enabled");
+ return Response::ServerError("DOM agent is not enabled");
DummyExceptionStateForTesting exception_state;
history_->Undo(exception_state);
return InspectorDOMAgent::ToResponse(exception_state);
@@ -1234,7 +1235,7 @@ Response InspectorDOMAgent::undo() {
Response InspectorDOMAgent::redo() {
if (!enabled_.Get())
- return Response::Error("DOM agent is not enabled");
+ return Response::ServerError("DOM agent is not enabled");
DummyExceptionStateForTesting exception_state;
history_->Redo(exception_state);
return InspectorDOMAgent::ToResponse(exception_state);
@@ -1242,7 +1243,7 @@ Response InspectorDOMAgent::redo() {
Response InspectorDOMAgent::markUndoableState() {
history_->MarkUndoableState();
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::focus(Maybe<int> node_id,
@@ -1250,16 +1251,16 @@ Response InspectorDOMAgent::focus(Maybe<int> node_id,
Maybe<String> object_id) {
Node* node = nullptr;
Response response = AssertNode(node_id, backend_node_id, object_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
auto* element = DynamicTo<Element>(node);
if (!element)
- return Response::Error("Node is not an Element");
- element->GetDocument().UpdateStyleAndLayout();
+ return Response::ServerError("Node is not an Element");
+ element->GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kInspector);
if (!element->IsFocusable())
- return Response::Error("Element is not focusable");
+ return Response::ServerError("Element is not focusable");
element->focus();
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::setFileInputFiles(
@@ -1269,24 +1270,24 @@ Response InspectorDOMAgent::setFileInputFiles(
Maybe<String> object_id) {
Node* node = nullptr;
Response response = AssertNode(node_id, backend_node_id, object_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
auto* html_input_element = DynamicTo<HTMLInputElement>(node);
if (!html_input_element ||
html_input_element->type() != input_type_names::kFile)
- return Response::Error("Node is not a file input element");
+ return Response::ServerError("Node is not a file input element");
Vector<String> paths;
for (const String& file : *files)
paths.push_back(file);
To<HTMLInputElement>(node)->SetFilesFromPaths(paths);
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::setNodeStackTracesEnabled(bool enable) {
capture_node_stack_traces_.Set(enable);
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::getNodeStackTraces(
@@ -1295,7 +1296,7 @@ Response InspectorDOMAgent::getNodeStackTraces(
creation) {
Node* node = nullptr;
Response response = AssertNode(node_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
InspectorSourceLocation* creation_inspector_source_location =
@@ -1305,7 +1306,7 @@ Response InspectorDOMAgent::getNodeStackTraces(
creation_inspector_source_location->GetSourceLocation();
*creation = source_location.BuildInspectorObject();
}
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::getBoxModel(
@@ -1315,13 +1316,13 @@ Response InspectorDOMAgent::getBoxModel(
std::unique_ptr<protocol::DOM::BoxModel>* model) {
Node* node = nullptr;
Response response = AssertNode(node_id, backend_node_id, object_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
bool result = InspectorHighlight::GetBoxModel(node, model, true);
if (!result)
- return Response::Error("Could not compute box model.");
- return Response::OK();
+ return Response::ServerError("Could not compute box model.");
+ return Response::Success();
}
Response InspectorDOMAgent::getContentQuads(
@@ -1331,12 +1332,12 @@ Response InspectorDOMAgent::getContentQuads(
std::unique_ptr<protocol::Array<protocol::Array<double>>>* quads) {
Node* node = nullptr;
Response response = AssertNode(node_id, backend_node_id, object_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
bool result = InspectorHighlight::GetContentQuads(node, quads);
if (!result)
- return Response::Error("Could not compute content quads.");
- return Response::OK();
+ return Response::ServerError("Could not compute content quads.");
+ return Response::Success();
}
Response InspectorDOMAgent::getNodeForLocation(
@@ -1368,7 +1369,7 @@ Response InspectorDOMAgent::getNodeForLocation(
while (node && node->getNodeType() == Node::kTextNode)
node = node->parentNode();
if (!node)
- return Response::Error("No node found at given location");
+ return Response::ServerError("No node found at given location");
*backend_node_id = IdentifiersFactory::IntIdForNode(node);
LocalFrame* frame = node->GetDocument().GetFrame();
*frame_id = IdentifiersFactory::FrameId(frame);
@@ -1376,7 +1377,7 @@ Response InspectorDOMAgent::getNodeForLocation(
document_node_to_id_map_->Contains(document_)) {
*node_id = PushNodePathToFrontend(node);
}
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::resolveNode(
@@ -1389,8 +1390,10 @@ Response InspectorDOMAgent::resolveNode(
String object_group_name = object_group.fromMaybe("");
Node* node = nullptr;
- if (node_id.isJust() == backend_node_id.isJust())
- return Response::Error("Either nodeId or backendNodeId must be specified.");
+ if (node_id.isJust() == backend_node_id.isJust()) {
+ return Response::ServerError(
+ "Either nodeId or backendNodeId must be specified.");
+ }
if (node_id.isJust())
node = NodeForId(node_id.fromJust());
@@ -1398,14 +1401,14 @@ Response InspectorDOMAgent::resolveNode(
node = DOMNodeIds::NodeForId(backend_node_id.fromJust());
if (!node)
- return Response::Error("No node with given id found");
+ return Response::ServerError("No node with given id found");
*result = ResolveNode(v8_session_, node, object_group_name,
std::move(execution_context_id));
if (!*result) {
- return Response::Error(
+ return Response::ServerError(
"Node with given id does not belong to the document");
}
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::getAttributes(
@@ -1413,20 +1416,20 @@ Response InspectorDOMAgent::getAttributes(
std::unique_ptr<protocol::Array<String>>* result) {
Element* element = nullptr;
Response response = AssertElement(node_id, element);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
*result = BuildArrayForElementAttributes(element);
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::requestNode(const String& object_id, int* node_id) {
Node* node = nullptr;
Response response = NodeForRemoteObjectId(object_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
*node_id = PushNodePathToFrontend(node);
- return Response::OK();
+ return Response::Success();
}
// static
@@ -1544,20 +1547,17 @@ std::unique_ptr<protocol::DOM::Node> InspectorDOMAgent::BuildObjectForNode(
}
if (element->GetPseudoId()) {
- protocol::DOM::PseudoType pseudo_type;
- if (InspectorDOMAgent::GetPseudoElementType(element->GetPseudoId(),
- &pseudo_type))
- value->setPseudoType(pseudo_type);
+ value->setPseudoType(ProtocolPseudoElementType(element->GetPseudoId()));
} else {
- std::unique_ptr<protocol::Array<protocol::DOM::Node>> pseudo_elements =
- BuildArrayForPseudoElements(element, nodes_map);
- if (pseudo_elements) {
- value->setPseudoElements(std::move(pseudo_elements));
- force_push_children = true;
- }
if (!element->ownerDocument()->xmlVersion().IsEmpty())
value->setXmlVersion(element->ownerDocument()->xmlVersion());
}
+ std::unique_ptr<protocol::Array<protocol::DOM::Node>> pseudo_elements =
+ BuildArrayForPseudoElements(element, nodes_map);
+ if (pseudo_elements) {
+ value->setPseudoElements(std::move(pseudo_elements));
+ force_push_children = true;
+ }
if (auto* insertion_point = DynamicTo<V0InsertionPoint>(element)) {
value->setDistributedNodes(
@@ -1668,21 +1668,24 @@ InspectorDOMAgent::BuildArrayForContainerChildren(
std::unique_ptr<protocol::Array<protocol::DOM::Node>>
InspectorDOMAgent::BuildArrayForPseudoElements(Element* element,
NodeToIdMap* nodes_map) {
- if (!element->GetPseudoElement(kPseudoIdBefore) &&
- !element->GetPseudoElement(kPseudoIdAfter))
- return nullptr;
-
- auto pseudo_elements =
- std::make_unique<protocol::Array<protocol::DOM::Node>>();
+ protocol::Array<protocol::DOM::Node> pseudo_elements;
if (element->GetPseudoElement(kPseudoIdBefore)) {
- pseudo_elements->emplace_back(BuildObjectForNode(
+ pseudo_elements.emplace_back(BuildObjectForNode(
element->GetPseudoElement(kPseudoIdBefore), 0, false, nodes_map));
}
if (element->GetPseudoElement(kPseudoIdAfter)) {
- pseudo_elements->emplace_back(BuildObjectForNode(
+ pseudo_elements.emplace_back(BuildObjectForNode(
element->GetPseudoElement(kPseudoIdAfter), 0, false, nodes_map));
}
- return pseudo_elements;
+ if (element->GetPseudoElement(kPseudoIdMarker) &&
+ RuntimeEnabledFeatures::CSSMarkerPseudoElementEnabled()) {
+ pseudo_elements.emplace_back(BuildObjectForNode(
+ element->GetPseudoElement(kPseudoIdMarker), 0, false, nodes_map));
+ }
+ if (pseudo_elements.empty())
+ return nullptr;
+ return std::make_unique<protocol::Array<protocol::DOM::Node>>(
+ std::move(pseudo_elements));
}
std::unique_ptr<protocol::Array<protocol::DOM::BackendNode>>
@@ -2089,6 +2092,10 @@ void InspectorDOMAgent::FrameOwnerContentUpdated(
}
void InspectorDOMAgent::PseudoElementCreated(PseudoElement* pseudo_element) {
+ if (pseudo_element->IsMarkerPseudoElement() &&
+ !RuntimeEnabledFeatures::CSSMarkerPseudoElementEnabled()) {
+ return;
+ }
Element* parent = pseudo_element->ParentOrShadowHostElement();
if (!parent)
return;
@@ -2187,19 +2194,19 @@ Node* InspectorDOMAgent::NodeForPath(const String& path) {
Response InspectorDOMAgent::pushNodeByPathToFrontend(const String& path,
int* node_id) {
if (!enabled_.Get())
- return Response::Error("DOM agent is not enabled");
+ return Response::ServerError("DOM agent is not enabled");
if (Node* node = NodeForPath(path))
*node_id = PushNodePathToFrontend(node);
else
- return Response::Error("No node with given path found");
- return Response::OK();
+ return Response::ServerError("No node with given path found");
+ return Response::Success();
}
Response InspectorDOMAgent::pushNodesByBackendIdsToFrontend(
std::unique_ptr<protocol::Array<int>> backend_node_ids,
std::unique_ptr<protocol::Array<int>>* result) {
if (!document_ || !document_node_to_id_map_->Contains(document_))
- return Response::Error("Document needs to be requested first");
+ return Response::ServerError("Document needs to be requested first");
*result = std::make_unique<protocol::Array<int>>();
for (int id : *backend_node_ids) {
@@ -2210,7 +2217,7 @@ Response InspectorDOMAgent::pushNodesByBackendIdsToFrontend(
else
(*result)->emplace_back(0);
}
- return Response::OK();
+ return Response::Success();
}
class InspectableNode final
@@ -2230,10 +2237,10 @@ class InspectableNode final
Response InspectorDOMAgent::setInspectedNode(int node_id) {
Node* node = nullptr;
Response response = AssertNode(node_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
v8_session_->addInspectedObject(std::make_unique<InspectableNode>(node));
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::getRelayoutBoundary(
@@ -2241,11 +2248,11 @@ Response InspectorDOMAgent::getRelayoutBoundary(
int* relayout_boundary_node_id) {
Node* node = nullptr;
Response response = AssertNode(node_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
LayoutObject* layout_object = node->GetLayoutObject();
if (!layout_object) {
- return Response::Error(
+ return Response::ServerError(
"No layout object for node, perhaps orphan or hidden node");
}
while (layout_object && !layout_object->IsDocumentElement() &&
@@ -2254,7 +2261,7 @@ Response InspectorDOMAgent::getRelayoutBoundary(
Node* result_node =
layout_object ? layout_object->GeneratingNode() : node->ownerDocument();
*relayout_boundary_node_id = PushNodePathToFrontend(result_node);
- return Response::OK();
+ return Response::Success();
}
protocol::Response InspectorDOMAgent::describeNode(
@@ -2266,13 +2273,50 @@ protocol::Response InspectorDOMAgent::describeNode(
std::unique_ptr<protocol::DOM::Node>* result) {
Node* node = nullptr;
Response response = AssertNode(node_id, backend_node_id, object_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
if (!node)
- return Response::Error("Node not found");
+ return Response::ServerError("Node not found");
*result = BuildObjectForNode(node, depth.fromMaybe(0),
pierce.fromMaybe(false), nullptr, nullptr);
- return Response::OK();
+ return Response::Success();
+}
+
+protocol::Response InspectorDOMAgent::scrollIntoViewIfNeeded(
+ protocol::Maybe<int> node_id,
+ protocol::Maybe<int> backend_node_id,
+ protocol::Maybe<String> object_id,
+ protocol::Maybe<protocol::DOM::Rect> rect) {
+ Node* node = nullptr;
+ Response response = AssertNode(node_id, backend_node_id, object_id, node);
+ if (!response.IsSuccess())
+ return response;
+ node->GetDocument().EnsurePaintLocationDataValidForNode(
+ node, DocumentUpdateReason::kInspector);
+ if (!node->isConnected())
+ return Response::ServerError("Node is detached from document");
+ LayoutObject* layout_object = node->GetLayoutObject();
+ if (!layout_object)
+ return Response::ServerError("Node does not have a layout object");
+ PhysicalRect rect_to_scroll = PhysicalRect::EnclosingRect(
+ layout_object->AbsoluteBoundingBoxFloatRect());
+ if (rect.isJust()) {
+ rect_to_scroll.SetX(rect_to_scroll.X() +
+ LayoutUnit(rect.fromJust()->getX()));
+ rect_to_scroll.SetY(rect_to_scroll.Y() +
+ LayoutUnit(rect.fromJust()->getY()));
+ rect_to_scroll.SetWidth(LayoutUnit(rect.fromJust()->getWidth()));
+ rect_to_scroll.SetHeight(LayoutUnit(rect.fromJust()->getHeight()));
+ }
+ layout_object->ScrollRectToVisible(
+ rect_to_scroll,
+ ScrollAlignment::CreateScrollIntoViewParams(
+ ScrollAlignment::CenterIfNeeded(), ScrollAlignment::CenterIfNeeded(),
+ mojom::blink::ScrollType::kProgrammatic,
+ true /* make_visible_in_visual_viewport */,
+ mojom::blink::ScrollBehavior::kInstant,
+ true /* is_for_scroll_sequence */, false /* zoom_into_rect */));
+ return Response::Success();
}
protocol::Response InspectorDOMAgent::getFrameOwner(
@@ -2294,10 +2338,10 @@ protocol::Response InspectorDOMAgent::getFrameOwner(
}
}
if (!frame)
- return Response::Error("Frame with the given id was not found.");
+ return Response::ServerError("Frame with the given id was not found.");
auto* frame_owner = DynamicTo<HTMLFrameOwnerElement>(frame->Owner());
if (!frame_owner) {
- return Response::Error(
+ return Response::ServerError(
"Frame with the given id does not belong to the target.");
}
@@ -2307,7 +2351,7 @@ protocol::Response InspectorDOMAgent::getFrameOwner(
document_node_to_id_map_->Contains(document_)) {
*node_id = PushNodePathToFrontend(frame_owner);
}
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMAgent::getFileInfo(const String& object_id, String* path) {
@@ -2317,21 +2361,21 @@ Response InspectorDOMAgent::getFileInfo(const String& object_id, String* path) {
std::unique_ptr<v8_inspector::StringBuffer> error;
if (!v8_session_->unwrapObject(&error, ToV8InspectorStringView(object_id),
&value, &context, nullptr))
- return Response::Error(ToCoreString(std::move(error)));
+ return Response::ServerError(ToCoreString(std::move(error)).Utf8());
if (!V8File::HasInstance(value, isolate_))
- return Response::Error("Object id doesn't reference a File");
+ return Response::ServerError("Object id doesn't reference a File");
File* file = V8File::ToImpl(v8::Local<v8::Object>::Cast(value));
if (!file) {
- return Response::Error(
+ return Response::ServerError(
"Couldn't convert object with given objectId to File");
}
*path = file->GetPath();
- return Response::OK();
+ return Response::Success();
}
-void InspectorDOMAgent::Trace(blink::Visitor* visitor) {
+void InspectorDOMAgent::Trace(Visitor* visitor) {
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 39f63d30265..689a068d888 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,14 +87,14 @@ class CORE_EXPORT InspectorDOMAgent final
: source_location_(std::move(source_location)) {}
SourceLocation& GetSourceLocation() { return *source_location_; }
- virtual void Trace(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
private:
std::unique_ptr<SourceLocation> source_location_;
};
static protocol::Response ToResponse(ExceptionState&);
- static bool GetPseudoElementType(PseudoId, String*);
+ static protocol::DOM::PseudoType ProtocolPseudoElementType(PseudoId);
static protocol::DOM::ShadowRootType GetShadowRootType(ShadowRoot*);
static ShadowRoot* UserAgentShadowRoot(Node*);
static Color ParseColor(protocol::DOM::RGBA*);
@@ -103,7 +103,7 @@ class CORE_EXPORT InspectorDOMAgent final
InspectedFrames*,
v8_inspector::V8InspectorSession*);
~InspectorDOMAgent() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void Restore() override;
@@ -234,6 +234,11 @@ class CORE_EXPORT InspectorDOMAgent final
protocol::Maybe<int> depth,
protocol::Maybe<bool> pierce,
std::unique_ptr<protocol::DOM::Node>*) override;
+ protocol::Response scrollIntoViewIfNeeded(
+ protocol::Maybe<int> node_id,
+ protocol::Maybe<int> backend_node_id,
+ protocol::Maybe<String> object_id,
+ protocol::Maybe<protocol::DOM::Rect> rect) override;
protocol::Response getFrameOwner(const String& frame_id,
int* backend_node_id,
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 d1bbcbcd5fe..1889e2eede6 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
@@ -45,6 +45,10 @@
#include "third_party/blink/renderer/core/inspector/v8_inspector_string.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
+#include "third_party/inspector_protocol/crdtp/json.h"
+
+using crdtp::SpanFrom;
+using crdtp::json::ConvertCBORToJSON;
namespace {
@@ -210,7 +214,7 @@ InspectorDOMDebuggerAgent::InspectorDOMDebuggerAgent(
InspectorDOMDebuggerAgent::~InspectorDOMDebuggerAgent() = default;
-void InspectorDOMDebuggerAgent::Trace(blink::Visitor* visitor) {
+void InspectorDOMDebuggerAgent::Trace(Visitor* visitor) {
visitor->Trace(dom_agent_);
visitor->Trace(dom_breakpoints_);
InspectorBaseAgent::Trace(visitor);
@@ -220,7 +224,7 @@ Response InspectorDOMDebuggerAgent::disable() {
SetEnabled(false);
dom_breakpoints_.clear();
agent_state_.ClearAllFields();
- return Response::OK();
+ return Response::Success();
}
void InspectorDOMDebuggerAgent::Restore() {
@@ -244,11 +248,11 @@ Response InspectorDOMDebuggerAgent::setInstrumentationBreakpoint(
Response InspectorDOMDebuggerAgent::SetBreakpoint(const String& event_name,
const String& target_name) {
if (event_name.IsEmpty())
- return Response::Error("Event name is empty");
+ return Response::ServerError("Event name is empty");
event_listener_breakpoints_.Set(
EventListenerBreakpointKey(event_name, target_name), true);
DidAddBreakpoint();
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMDebuggerAgent::removeEventListenerBreakpoint(
@@ -268,11 +272,11 @@ Response InspectorDOMDebuggerAgent::RemoveBreakpoint(
const String& event_name,
const String& target_name) {
if (event_name.IsEmpty())
- return Response::Error("Event name is empty");
+ return Response::ServerError("Event name is empty");
event_listener_breakpoints_.Clear(
EventListenerBreakpointKey(event_name, target_name));
DidRemoveBreakpoint();
- return Response::OK();
+ return Response::Success();
}
void InspectorDOMDebuggerAgent::DidInvalidateStyleAttr(Node* node) {
@@ -312,17 +316,18 @@ void InspectorDOMDebuggerAgent::DidRemoveDOMNode(Node* node) {
static Response DomTypeForName(const String& type_string, int& type) {
if (type_string == "subtree-modified") {
type = SubtreeModified;
- return Response::OK();
+ return Response::Success();
}
if (type_string == "attribute-modified") {
type = AttributeModified;
- return Response::OK();
+ return Response::Success();
}
if (type_string == "node-removed") {
type = NodeRemoved;
- return Response::OK();
+ return Response::Success();
}
- return Response::Error(String("Unknown DOM breakpoint type: " + type_string));
+ return Response::ServerError(
+ String("Unknown DOM breakpoint type: " + type_string).Utf8());
}
static String DomTypeName(int type) {
@@ -344,12 +349,12 @@ Response InspectorDOMDebuggerAgent::setDOMBreakpoint(
const String& type_string) {
Node* node = nullptr;
Response response = dom_agent_->AssertNode(node_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
int type = -1;
response = DomTypeForName(type_string, type);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
uint32_t root_bit = 1 << type;
@@ -360,7 +365,7 @@ Response InspectorDOMDebuggerAgent::setDOMBreakpoint(
UpdateSubtreeBreakpoints(child, root_bit, true);
}
DidAddBreakpoint();
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMDebuggerAgent::removeDOMBreakpoint(
@@ -368,12 +373,12 @@ Response InspectorDOMDebuggerAgent::removeDOMBreakpoint(
const String& type_string) {
Node* node = nullptr;
Response response = dom_agent_->AssertNode(node_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
int type = -1;
response = DomTypeForName(type_string, type);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
uint32_t root_bit = 1 << type;
@@ -390,7 +395,7 @@ Response InspectorDOMDebuggerAgent::removeDOMBreakpoint(
UpdateSubtreeBreakpoints(child, root_bit, false);
}
DidRemoveBreakpoint();
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMDebuggerAgent::getEventListeners(
@@ -406,7 +411,7 @@ Response InspectorDOMDebuggerAgent::getEventListeners(
std::unique_ptr<v8_inspector::StringBuffer> object_group;
if (!v8_session_->unwrapObject(&error, ToV8InspectorStringView(object_id),
&object, &context, &object_group)) {
- return Response::Error(ToCoreString(std::move(error)));
+ return Response::ServerError(ToCoreString(std::move(error)).Utf8());
}
v8::Context::Scope scope(context);
V8EventListenerInfoList event_information;
@@ -415,7 +420,7 @@ Response InspectorDOMDebuggerAgent::getEventListeners(
pierce.fromMaybe(false), &event_information);
*listeners_array = BuildObjectsForEventListeners(event_information, context,
object_group->string());
- return Response::OK();
+ return Response::Success();
}
std::unique_ptr<protocol::Array<protocol::DOMDebugger::EventListener>>
@@ -539,11 +544,12 @@ void InspectorDOMDebuggerAgent::BreakProgramOnDOMEvent(Node* target,
DCHECK(breakpoint_owner_node_id);
description->setInteger("nodeId", breakpoint_owner_node_id);
description->setString("type", DomTypeName(breakpoint_type));
- String json = description->toJSONString();
+ std::vector<uint8_t> json;
+ ConvertCBORToJSON(SpanFrom(description->Serialize()), &json);
v8_session_->breakProgram(
ToV8InspectorStringView(
v8_inspector::protocol::Debugger::API::Paused::ReasonEnum::DOM),
- ToV8InspectorStringView(json));
+ v8_inspector::StringView(json.data(), json.size()));
}
bool InspectorDOMDebuggerAgent::HasBreakpoint(Node* node, int type) {
@@ -579,17 +585,15 @@ void InspectorDOMDebuggerAgent::PauseOnNativeEventIfNeeded(
bool synchronous) {
if (!event_data)
return;
- String json = event_data->toJSONString();
+ std::vector<uint8_t> json;
+ ConvertCBORToJSON(SpanFrom(event_data->Serialize()), &json);
+ v8_inspector::StringView json_view(json.data(), json.size());
+ auto listener = ToV8InspectorStringView(
+ v8_inspector::protocol::Debugger::API::Paused::ReasonEnum::EventListener);
if (synchronous)
- v8_session_->breakProgram(
- ToV8InspectorStringView(v8_inspector::protocol::Debugger::API::Paused::
- ReasonEnum::EventListener),
- ToV8InspectorStringView(json));
+ v8_session_->breakProgram(listener, json_view);
else
- v8_session_->schedulePauseOnNextStatement(
- ToV8InspectorStringView(v8_inspector::protocol::Debugger::API::Paused::
- ReasonEnum::EventListener),
- ToV8InspectorStringView(json));
+ v8_session_->schedulePauseOnNextStatement(listener, json_view);
}
std::unique_ptr<protocol::DictionaryValue>
@@ -689,7 +693,7 @@ Response InspectorDOMDebuggerAgent::setXHRBreakpoint(const String& url) {
else
xhr_breakpoints_.Set(url, true);
DidAddBreakpoint();
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMDebuggerAgent::removeXHRBreakpoint(const String& url) {
@@ -698,7 +702,7 @@ Response InspectorDOMDebuggerAgent::removeXHRBreakpoint(const String& url) {
else
xhr_breakpoints_.Clear(url);
DidRemoveBreakpoint();
- return Response::OK();
+ return Response::Success();
}
// Returns the breakpoint url if a match is found, or WTF::String().
@@ -722,11 +726,12 @@ void InspectorDOMDebuggerAgent::WillSendXMLHttpOrFetchNetworkRequest(
protocol::DictionaryValue::create();
event_data->setString("breakpointURL", breakpoint_url);
event_data->setString("url", url);
- String json = event_data->toJSONString();
+ std::vector<uint8_t> json;
+ ConvertCBORToJSON(SpanFrom(event_data->Serialize()), &json);
v8_session_->breakProgram(
ToV8InspectorStringView(
v8_inspector::protocol::Debugger::API::Paused::ReasonEnum::XHR),
- ToV8InspectorStringView(json));
+ v8_inspector::StringView(json.data(), json.size()));
}
void InspectorDOMDebuggerAgent::DidCreateCanvasContext() {
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 a1c53b88100..96708618d24 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 56b37830b3a..85e99a901d4 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
@@ -18,6 +18,7 @@
#include "third_party/blink/renderer/core/dom/pseudo_element.h"
#include "third_party/blink/renderer/core/dom/qualified_name.h"
#include "third_party/blink/renderer/core/dom/shadow_root.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/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/forms/html_option_element.h"
@@ -93,6 +94,53 @@ std::unique_ptr<protocol::DOMSnapshot::RareBooleanData> BooleanData() {
.build();
}
+String GetOriginUrlFast(int max_stack_depth) {
+ static const v8::StackTrace::StackTraceOptions stackTraceOptions =
+ static_cast<v8::StackTrace::StackTraceOptions>(v8::StackTrace::kDetailed);
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ DCHECK(isolate);
+
+ v8::Local<v8::StackTrace> v8StackTrace = v8::StackTrace::CurrentStackTrace(
+ isolate, max_stack_depth, stackTraceOptions);
+ if (v8StackTrace.IsEmpty())
+ return String();
+ for (int i = 0, frame_count = v8StackTrace->GetFrameCount(); i < frame_count;
+ ++i) {
+ v8::Local<v8::StackFrame> frame = v8StackTrace->GetFrame(isolate, i);
+ if (frame.IsEmpty())
+ continue;
+ v8::Local<v8::String> script_name = frame->GetScriptNameOrSourceURL();
+ if (script_name.IsEmpty() || !script_name->Length())
+ continue;
+ return ToCoreString(script_name);
+ }
+ return String();
+}
+
+String GetOriginUrl(const Node* node) {
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ ThreadDebugger* debugger = ThreadDebugger::From(isolate);
+ if (!isolate || !isolate->InContext() || !debugger)
+ return String();
+ v8::HandleScope handleScope(isolate);
+ // Try not getting the entire stack first.
+ String url = GetOriginUrlFast(/* maxStackSize=*/5);
+ if (!url.IsEmpty())
+ return url;
+ url = GetOriginUrlFast(/* maxStackSize=*/200);
+ if (!url.IsEmpty())
+ return url;
+ // If we did not get anything from the sync stack, let's try the slow
+ // way that also checks async stacks.
+ auto trace = debugger->GetV8Inspector()->captureStackTrace(true);
+ if (trace)
+ url = ToCoreString(trace->firstNonEmptySourceURL());
+ if (!url.IsEmpty())
+ return url;
+ // Fall back to document url.
+ return node->GetDocument().Url().GetString();
+}
+
} // namespace
// Returns |layout_object|'s bounding box in document coordinates.
@@ -104,7 +152,7 @@ PhysicalRect InspectorDOMSnapshotAgent::RectInDocument(
LocalFrameView* local_frame_view = layout_object->GetFrameView();
// Don't do frame to document coordinate transformation for layout view,
// whose bounding box is not affected by scroll offset.
- if (local_frame_view && !layout_object->IsLayoutView())
+ if (local_frame_view && !IsA<LayoutView>(layout_object))
return local_frame_view->FrameToDocument(rect_in_absolute);
return rect_in_absolute;
}
@@ -132,42 +180,15 @@ InspectorDOMSnapshotAgent::InspectorDOMSnapshotAgent(
InspectorDOMSnapshotAgent::~InspectorDOMSnapshotAgent() = default;
-void InspectorDOMSnapshotAgent::GetOriginUrl(String* origin_url_ptr,
- const Node* node) {
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
- ThreadDebugger* debugger = ThreadDebugger::From(isolate);
- if (!isolate || !isolate->InContext() || !debugger) {
- origin_url_ptr = nullptr;
- return;
- }
- // First try searching in one frame, since grabbing full trace is
- // expensive.
- auto trace = debugger->GetV8Inspector()->captureStackTrace(false);
- if (!trace) {
- origin_url_ptr = nullptr;
- return;
- }
- if (!trace->firstNonEmptySourceURL().length())
- trace = debugger->GetV8Inspector()->captureStackTrace(true);
- String origin_url = ToCoreString(trace->firstNonEmptySourceURL());
- if (origin_url.IsEmpty()) {
- // Fall back to document url.
- origin_url = node->GetDocument().Url().GetString();
- }
- *origin_url_ptr = origin_url;
-}
-
void InspectorDOMSnapshotAgent::CharacterDataModified(
CharacterData* character_data) {
- String origin_url;
- GetOriginUrl(&origin_url, character_data);
+ String origin_url = GetOriginUrl(character_data);
if (origin_url)
origin_url_map_->insert(DOMNodeIds::IdForNode(character_data), origin_url);
}
void InspectorDOMSnapshotAgent::DidInsertDOMNode(Node* node) {
- String origin_url;
- GetOriginUrl(&origin_url, node);
+ String origin_url = GetOriginUrl(node);
if (origin_url)
origin_url_map_->insert(DOMNodeIds::IdForNode(node), origin_url);
}
@@ -186,16 +207,16 @@ void InspectorDOMSnapshotAgent::Restore() {
Response InspectorDOMSnapshotAgent::enable() {
if (!enabled_.Get())
EnableAndReset();
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMSnapshotAgent::disable() {
if (!enabled_.Get())
- return Response::Error("DOM snapshot agent hasn't been enabled.");
+ return Response::ServerError("DOM snapshot agent hasn't been enabled.");
enabled_.Clear();
origin_url_map_.reset();
instrumenting_agents_->RemoveInspectorDOMSnapshotAgent(this);
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMSnapshotAgent::getSnapshot(
@@ -210,7 +231,7 @@ Response InspectorDOMSnapshotAgent::getSnapshot(
computed_styles) {
Document* document = inspected_frames_->Root()->GetDocument();
if (!document)
- return Response::Error("Document is not available");
+ return Response::ServerError("Document is not available");
LegacyDOMSnapshotAgent legacySupport(dom_debugger_agent_,
origin_url_map_.get());
return legacySupport.GetSnapshot(
@@ -226,9 +247,13 @@ protocol::Response InspectorDOMSnapshotAgent::captureSnapshot(
std::unique_ptr<protocol::Array<protocol::DOMSnapshot::DocumentSnapshot>>*
documents,
std::unique_ptr<protocol::Array<String>>* strings) {
- Document* main_document = inspected_frames_->Root()->GetDocument();
- if (!main_document)
- return Response::Error("Document is not available");
+ // This function may kick the layout, but external clients may call this
+ // function outside of the layout phase.
+ FontCachePurgePreventer fontCachePurgePreventer;
+
+ auto* main_window = inspected_frames_->Root()->DomWindow();
+ if (!main_window)
+ return Response::ServerError("Document is not available");
strings_ = std::make_unique<protocol::Array<String>>();
documents_ = std::make_unique<
@@ -237,7 +262,7 @@ protocol::Response InspectorDOMSnapshotAgent::captureSnapshot(
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(entry);
+ CSSPropertyID property_id = cssPropertyID(main_window, entry);
if (property_id == CSSPropertyID::kInvalid)
continue;
css_property_filter_->emplace_back(std::move(entry),
@@ -246,7 +271,7 @@ protocol::Response InspectorDOMSnapshotAgent::captureSnapshot(
if (include_paint_order.fromMaybe(false)) {
paint_order_map_ =
- InspectorDOMSnapshotAgent::BuildPaintLayerTree(main_document);
+ InspectorDOMSnapshotAgent::BuildPaintLayerTree(main_window->document());
}
include_snapshot_dom_rects_ = include_dom_rects.fromMaybe(false);
@@ -268,7 +293,7 @@ protocol::Response InspectorDOMSnapshotAgent::captureSnapshot(
string_table_.clear();
document_order_map_.clear();
documents_.reset();
- return Response::OK();
+ return Response::Success();
}
int InspectorDOMSnapshotAgent::AddString(const String& string) {
@@ -309,12 +334,12 @@ void InspectorDOMSnapshotAgent::SetRare(
}
void InspectorDOMSnapshotAgent::VisitDocument(Document* document) {
- // Update layout tree before traversal of document so that we inspect a
+ // Update layout before traversal of document so that we inspect a
// current and consistent state of all trees. No need to do this if paint
// order was calculated, since layout trees were already updated during
// TraversePaintLayerTree().
if (!paint_order_map_)
- document->UpdateStyleAndLayoutTree();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kInspector);
DocumentType* doc_type = document->doctype();
@@ -471,14 +496,11 @@ int InspectorDOMSnapshotAgent::VisitNode(Node* node, int parent_index) {
}
if (element->GetPseudoId()) {
- protocol::DOM::PseudoType pseudo_type;
- if (InspectorDOMAgent::GetPseudoElementType(element->GetPseudoId(),
- &pseudo_type)) {
- SetRare(nodes->getPseudoType(nullptr), index, pseudo_type);
- }
- } else {
- VisitPseudoElements(element, index);
+ SetRare(
+ nodes->getPseudoType(nullptr), index,
+ InspectorDOMAgent::ProtocolPseudoElementType(element->GetPseudoId()));
}
+ VisitPseudoElements(element, index);
auto* image_element = DynamicTo<HTMLImageElement>(node);
if (image_element) {
@@ -546,8 +568,8 @@ void InspectorDOMSnapshotAgent::VisitContainerChildren(Node* container,
void InspectorDOMSnapshotAgent::VisitPseudoElements(Element* parent,
int parent_index) {
- for (PseudoId pseudo_id :
- {kPseudoIdFirstLetter, kPseudoIdBefore, kPseudoIdAfter}) {
+ for (PseudoId pseudo_id : {kPseudoIdFirstLetter, kPseudoIdBefore,
+ kPseudoIdAfter, kPseudoIdMarker}) {
if (Node* pseudo_node = parent->GetPseudoElement(pseudo_id))
VisitNode(pseudo_node, parent_index);
}
@@ -684,9 +706,9 @@ InspectorDOMSnapshotAgent::BuildPaintLayerTree(Document* document) {
void InspectorDOMSnapshotAgent::TraversePaintLayerTree(
Document* document,
PaintOrderMap* paint_order_map) {
- // Update layout tree before traversal of document so that we inspect a
+ // Update layout before traversal of document so that we inspect a
// current and consistent state of all trees.
- document->UpdateStyleAndLayoutTree();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kInspector);
PaintLayer* root_layer = document->GetLayoutView()->Layer();
// LayoutView requires a PaintLayer.
@@ -716,7 +738,7 @@ void InspectorDOMSnapshotAgent::VisitPaintLayer(
VisitPaintLayer(child_layer, paint_order_map);
}
-void InspectorDOMSnapshotAgent::Trace(blink::Visitor* visitor) {
+void InspectorDOMSnapshotAgent::Trace(Visitor* visitor) {
visitor->Trace(inspected_frames_);
visitor->Trace(dom_debugger_agent_);
visitor->Trace(document_order_map_);
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 ea43902b2a4..8587c6147a9 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
@@ -26,16 +26,9 @@ class PaintLayer;
class CORE_EXPORT InspectorDOMSnapshotAgent final
: public InspectorBaseAgent<protocol::DOMSnapshot::Metainfo> {
public:
- static InspectorDOMSnapshotAgent* Create(
- InspectedFrames* inspected_frames,
- InspectorDOMDebuggerAgent* dom_debugger_agent) {
- return MakeGarbageCollected<InspectorDOMSnapshotAgent>(inspected_frames,
- dom_debugger_agent);
- }
-
InspectorDOMSnapshotAgent(InspectedFrames*, InspectorDOMDebuggerAgent*);
~InspectorDOMSnapshotAgent() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void Restore() override;
@@ -102,8 +95,6 @@ class CORE_EXPORT InspectorDOMSnapshotAgent final
int BuildLayoutTreeNode(LayoutObject*, Node*, int node_index);
std::unique_ptr<protocol::Array<int>> BuildStylesForNode(Node*);
- void GetOriginUrl(String*, const Node*);
-
static void TraversePaintLayerTree(Document*, PaintOrderMap* paint_order_map);
static void VisitPaintLayer(PaintLayer*, PaintOrderMap* paint_order_map);
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 8ac01b3999a..39b3efb5d0f 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
@@ -4,14 +4,15 @@
#include "third_party/blink/renderer/core/inspector/inspector_emulation_agent.h"
+#include "third_party/blink/public/common/input/web_touch_event.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_float_point.h"
-#include "third_party/blink/public/platform/web_touch_event.h"
+#include "third_party/blink/renderer/core/css/vision_deficiency.h"
#include "third_party/blink/renderer/core/exported/web_view_impl.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_local_frame_impl.h"
#include "third_party/blink/renderer/core/inspector/dev_tools_emulator.h"
+#include "third_party/blink/renderer/core/inspector/locale_controller.h"
#include "third_party/blink/renderer/core/inspector/protocol/DOM.h"
#include "third_party/blink/renderer/core/page/focus_controller.h"
#include "third_party/blink/renderer/core/page/page.h"
@@ -39,11 +40,14 @@ InspectorEmulationAgent::InspectorEmulationAgent(
max_touch_points_(&agent_state_, /*default_value=*/1),
emulated_media_(&agent_state_, /*default_value=*/WTF::String()),
emulated_media_features_(&agent_state_, /*default_value=*/WTF::String()),
+ emulated_vision_deficiency_(&agent_state_,
+ /*default_value=*/WTF::String()),
navigator_platform_override_(&agent_state_,
/*default_value=*/WTF::String()),
user_agent_override_(&agent_state_, /*default_value=*/WTF::String()),
accept_language_override_(&agent_state_,
/*default_value=*/WTF::String()),
+ locale_override_(&agent_state_, /*default_value=*/WTF::String()),
virtual_time_budget_(&agent_state_, /*default_value*/ 0.0),
virtual_time_budget_initial_offset_(&agent_state_, /*default_value=*/0.0),
initial_virtual_time_(&agent_state_, /*default_value=*/0.0),
@@ -68,9 +72,7 @@ std::unique_ptr<protocol::DOM::RGBA> ParseRGBA(
return nullptr;
blink::protocol::ErrorSupport errors;
auto rgba = protocol::DOM::RGBA::fromValue(parsed.get(), &errors);
- if (errors.hasErrors())
- return nullptr;
- return rgba;
+ return errors.Errors().empty() ? std::move(rgba) : nullptr;
}
} // namespace
@@ -78,6 +80,8 @@ void InspectorEmulationAgent::Restore() {
setUserAgentOverride(user_agent_override_.Get(),
accept_language_override_.Get(),
navigator_platform_override_.Get());
+ if (!locale_override_.Get().IsEmpty())
+ setLocaleOverride(locale_override_.Get());
if (!web_local_frame_)
return;
@@ -100,6 +104,8 @@ void InspectorEmulationAgent::Restore() {
.build());
}
setEmulatedMedia(emulated_media_.Get(), std::move(features));
+ if (!emulated_vision_deficiency_.Get().IsNull())
+ setEmulatedVisionDeficiency(emulated_vision_deficiency_.Get());
auto rgba = ParseRGBA(default_background_color_override_rgba_.Get());
if (rgba)
setDefaultBackgroundColorOverride(std::move(rgba));
@@ -145,12 +151,16 @@ void InspectorEmulationAgent::Restore() {
}
Response InspectorEmulationAgent::disable() {
- if (enabled_)
+ if (enabled_) {
instrumenting_agents_->RemoveInspectorEmulationAgent(this);
+ enabled_ = false;
+ }
setUserAgentOverride(String(), protocol::Maybe<String>(),
protocol::Maybe<String>());
+ if (!locale_override_.Get().IsEmpty())
+ setLocaleOverride(String());
if (!web_local_frame_)
- return Response::OK();
+ return Response::Success();
setScriptExecutionDisabled(false);
setScrollbarsHidden(false);
setDocumentCookieDisabled(false);
@@ -161,15 +171,17 @@ Response InspectorEmulationAgent::disable() {
// (e.g. if we allowed two different front-ends with the same
// settings to attach to the same page). TODO: support this use case.
setEmulatedMedia(String(), {});
+ if (!emulated_vision_deficiency_.Get().IsNull())
+ setEmulatedVisionDeficiency(String("none"));
setCPUThrottlingRate(1);
setFocusEmulationEnabled(false);
setDefaultBackgroundColorOverride(Maybe<protocol::DOM::RGBA>());
- return Response::OK();
+ return Response::Success();
}
Response InspectorEmulationAgent::resetPageScaleFactor() {
Response response = AssertPage();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
GetWebViewImpl()->ResetScaleStateImmediately();
return response;
@@ -177,7 +189,7 @@ Response InspectorEmulationAgent::resetPageScaleFactor() {
Response InspectorEmulationAgent::setPageScaleFactor(double page_scale_factor) {
Response response = AssertPage();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
GetWebViewImpl()->SetPageScaleFactor(static_cast<float>(page_scale_factor));
return response;
@@ -185,7 +197,7 @@ Response InspectorEmulationAgent::setPageScaleFactor(double page_scale_factor) {
Response InspectorEmulationAgent::setScriptExecutionDisabled(bool value) {
Response response = AssertPage();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
if (script_execution_disabled_.Get() == value)
return response;
@@ -196,7 +208,7 @@ Response InspectorEmulationAgent::setScriptExecutionDisabled(bool value) {
Response InspectorEmulationAgent::setScrollbarsHidden(bool hidden) {
Response response = AssertPage();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
if (scrollbars_hidden_.Get() == hidden)
return response;
@@ -207,7 +219,7 @@ Response InspectorEmulationAgent::setScrollbarsHidden(bool hidden) {
Response InspectorEmulationAgent::setDocumentCookieDisabled(bool disabled) {
Response response = AssertPage();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
if (document_cookie_disabled_.Get() == disabled)
return response;
@@ -220,13 +232,14 @@ Response InspectorEmulationAgent::setTouchEmulationEnabled(
bool enabled,
protocol::Maybe<int> max_touch_points) {
Response response = AssertPage();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
int max_points = max_touch_points.fromMaybe(1);
if (max_points < 1 || max_points > WebTouchEvent::kTouchesLengthCap) {
- return Response::InvalidParams("Touch points must be between 1 and " +
- String::Number(static_cast<uint16_t>(
- WebTouchEvent::kTouchesLengthCap)));
+ String msg =
+ "Touch points must be between 1 and " +
+ String::Number(static_cast<uint16_t>(WebTouchEvent::kTouchesLengthCap));
+ return Response::InvalidParams(msg.Utf8());
}
touch_event_emulation_enabled_.Set(enabled);
max_touch_points_.Set(max_points);
@@ -239,7 +252,7 @@ Response InspectorEmulationAgent::setEmulatedMedia(
Maybe<String> media,
Maybe<protocol::Array<protocol::Emulation::MediaFeature>> features) {
Response response = AssertPage();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
if (media.isJust()) {
auto mediaValue = media.takeJust();
@@ -267,9 +280,38 @@ Response InspectorEmulationAgent::setEmulatedMedia(
return response;
}
+Response InspectorEmulationAgent::setEmulatedVisionDeficiency(
+ const String& type) {
+ Response response = AssertPage();
+ if (!response.IsSuccess())
+ return response;
+
+ VisionDeficiency vision_deficiency;
+ namespace TypeEnum =
+ protocol::Emulation::SetEmulatedVisionDeficiency::TypeEnum;
+ if (type == TypeEnum::None)
+ vision_deficiency = VisionDeficiency::kNoVisionDeficiency;
+ else if (type == TypeEnum::Achromatopsia)
+ vision_deficiency = VisionDeficiency::kAchromatopsia;
+ else if (type == TypeEnum::BlurredVision)
+ vision_deficiency = VisionDeficiency::kBlurredVision;
+ else if (type == TypeEnum::Deuteranopia)
+ vision_deficiency = VisionDeficiency::kDeuteranopia;
+ else if (type == TypeEnum::Protanopia)
+ vision_deficiency = VisionDeficiency::kProtanopia;
+ else if (type == TypeEnum::Tritanopia)
+ vision_deficiency = VisionDeficiency::kTritanopia;
+ else
+ return Response::InvalidParams("Unknown vision deficiency type");
+
+ emulated_vision_deficiency_.Set(type);
+ GetWebViewImpl()->GetPage()->SetVisionDeficiency(vision_deficiency);
+ return response;
+}
+
Response InspectorEmulationAgent::setCPUThrottlingRate(double rate) {
Response response = AssertPage();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
scheduler::ThreadCPUThrottler::GetInstance()->SetThrottlingRate(rate);
return response;
@@ -277,7 +319,7 @@ Response InspectorEmulationAgent::setCPUThrottlingRate(double rate) {
Response InspectorEmulationAgent::setFocusEmulationEnabled(bool enabled) {
Response response = AssertPage();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
emulate_focus_.Set(enabled);
GetWebViewImpl()->GetPage()->GetFocusController().SetFocusEmulationEnabled(
@@ -293,7 +335,7 @@ Response InspectorEmulationAgent::setVirtualTimePolicy(
protocol::Maybe<double> initial_virtual_time,
double* virtual_time_ticks_base_ms) {
Response response = AssertPage();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
virtual_time_policy_.Set(policy);
@@ -373,8 +415,9 @@ void InspectorEmulationAgent::ApplyVirtualTimePolicy(
virtual_time_base_ticks_ =
web_local_frame_->View()->Scheduler()->EnableVirtualTime();
if (new_policy.virtual_time_budget_ms) {
- TRACE_EVENT_ASYNC_BEGIN1("renderer.scheduler", "VirtualTimeBudget", this,
- "budget", *new_policy.virtual_time_budget_ms);
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("renderer.scheduler", "VirtualTimeBudget",
+ TRACE_ID_LOCAL(this), "budget",
+ *new_policy.virtual_time_budget_ms);
base::TimeDelta budget_amount =
base::TimeDelta::FromMillisecondsD(*new_policy.virtual_time_budget_ms);
web_local_frame_->View()->Scheduler()->GrantVirtualTimeBudget(
@@ -413,7 +456,7 @@ void InspectorEmulationAgent::PrepareRequest(
Response InspectorEmulationAgent::setNavigatorOverrides(
const String& platform) {
Response response = AssertPage();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
navigator_platform_override_.Set(platform);
GetWebViewImpl()->GetPage()->GetSettings().SetNavigatorPlatformOverride(
@@ -422,7 +465,8 @@ Response InspectorEmulationAgent::setNavigatorOverrides(
}
void InspectorEmulationAgent::VirtualTimeBudgetExpired() {
- TRACE_EVENT_ASYNC_END0("renderer.scheduler", "VirtualTimeBudget", this);
+ TRACE_EVENT_NESTABLE_ASYNC_END0("renderer.scheduler", "VirtualTimeBudget",
+ TRACE_ID_LOCAL(this));
WebView* view = web_local_frame_->View();
if (!view)
return;
@@ -430,29 +474,31 @@ void InspectorEmulationAgent::VirtualTimeBudgetExpired() {
view->Scheduler()->SetVirtualTimePolicy(
PageScheduler::VirtualTimePolicy::kPause);
virtual_time_policy_.Set(protocol::Emulation::VirtualTimePolicyEnum::Pause);
- GetFrontend()->virtualTimeBudgetExpired();
+ // We could have been detached while VT was still running.
+ // TODO(caseq): should we rather force-pause the time upon Disable()?
+ if (auto* frontend = GetFrontend())
+ frontend->virtualTimeBudgetExpired();
}
Response InspectorEmulationAgent::setDefaultBackgroundColorOverride(
Maybe<protocol::DOM::RGBA> color) {
Response response = AssertPage();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
if (!color.isJust()) {
// Clear the override and state.
GetWebViewImpl()->ClearBaseBackgroundColorOverride();
default_background_color_override_rgba_.Clear();
- return Response::OK();
+ return Response::Success();
}
blink::protocol::DOM::RGBA* rgba = color.fromJust();
- default_background_color_override_rgba_.Set(
- std::move(*rgba).TakeSerialized());
+ default_background_color_override_rgba_.Set(rgba->Serialize());
// Clamping of values is done by Color() constructor.
int alpha = static_cast<int>(lroundf(255.0f * rgba->getA(1.0f)));
GetWebViewImpl()->SetBaseBackgroundColorOverride(
Color(rgba->getR(), rgba->getG(), rgba->getB(), alpha).Rgb());
- return Response::OK();
+ return Response::Success();
}
Response InspectorEmulationAgent::setDeviceMetricsOverride(
@@ -494,7 +540,23 @@ Response InspectorEmulationAgent::setUserAgentOverride(
GetWebViewImpl()->GetPage()->GetSettings().SetNavigatorPlatformOverride(
navigator_platform_override_.Get());
}
- return Response::OK();
+ return Response::Success();
+}
+
+Response InspectorEmulationAgent::setLocaleOverride(
+ protocol::Maybe<String> maybe_locale) {
+ // Only allow resetting overrides set by the same agent.
+ if (locale_override_.Get().IsEmpty() &&
+ LocaleController::instance().has_locale_override()) {
+ return Response::ServerError(
+ "Another locale override is already in effect");
+ }
+ String locale = maybe_locale.fromMaybe(String());
+ String error = LocaleController::instance().SetLocaleOverride(locale);
+ if (!error.IsEmpty())
+ return Response::ServerError(error.Utf8());
+ locale_override_.Set(locale);
+ return Response::Success();
}
Response InspectorEmulationAgent::setTimezoneOverride(
@@ -504,14 +566,15 @@ Response InspectorEmulationAgent::setTimezoneOverride(
timezone_override_ = TimeZoneController::SetTimeZoneOverride(timezone_id);
if (!timezone_override_) {
return TimeZoneController::HasTimeZoneOverride()
- ? Response::Error("Timezone override is already in effect")
+ ? Response::ServerError(
+ "Timezone override is already in effect")
: Response::InvalidParams("Invalid timezone id");
}
}
timezone_id_override_.Set(timezone_id);
- return Response::OK();
+ return Response::Success();
}
void InspectorEmulationAgent::ApplyAcceptLanguageOverride(String* accept_lang) {
@@ -537,10 +600,10 @@ Response InspectorEmulationAgent::AssertPage() {
return Response::InvalidParams(
"Can only enable virtual time for pages, not workers");
}
- return Response::OK();
+ return Response::Success();
}
-void InspectorEmulationAgent::Trace(blink::Visitor* visitor) {
+void InspectorEmulationAgent::Trace(Visitor* visitor) {
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 87a2fd33b52..4c7739644aa 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
@@ -48,6 +48,7 @@ class CORE_EXPORT InspectorEmulationAgent final
protocol::Maybe<String> media,
protocol::Maybe<protocol::Array<protocol::Emulation::MediaFeature>>
features) override;
+ protocol::Response setEmulatedVisionDeficiency(const String&) override;
protocol::Response setCPUThrottlingRate(double) override;
protocol::Response setFocusEmulationEnabled(bool) override;
protocol::Response setVirtualTimePolicy(
@@ -79,6 +80,7 @@ class CORE_EXPORT InspectorEmulationAgent final
const String& user_agent,
protocol::Maybe<String> accept_language,
protocol::Maybe<String> platform) override;
+ protocol::Response setLocaleOverride(protocol::Maybe<String>) override;
// InspectorInstrumentation API
void ApplyAcceptLanguageOverride(String* accept_lang);
@@ -93,7 +95,7 @@ class CORE_EXPORT InspectorEmulationAgent final
protocol::Response disable() override;
void Restore() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
WebViewImpl* GetWebViewImpl();
@@ -126,9 +128,11 @@ class CORE_EXPORT InspectorEmulationAgent final
InspectorAgentState::Integer max_touch_points_;
InspectorAgentState::String emulated_media_;
InspectorAgentState::StringMap emulated_media_features_;
+ InspectorAgentState::String emulated_vision_deficiency_;
InspectorAgentState::String navigator_platform_override_;
InspectorAgentState::String user_agent_override_;
InspectorAgentState::String accept_language_override_;
+ InspectorAgentState::String locale_override_;
InspectorAgentState::Double virtual_time_budget_;
InspectorAgentState::Double virtual_time_budget_initial_offset_;
InspectorAgentState::Double initial_virtual_time_;
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 db0c40dd586..379b7ccf045 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_highlight.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_highlight.cc
@@ -132,7 +132,7 @@ class ShapePathBuilder : public PathBuilder {
}
private:
- Member<LocalFrameView> view_;
+ LocalFrameView* view_;
LayoutObject& layout_object_;
const ShapeOutsideInfo& shape_outside_info_;
};
@@ -278,6 +278,8 @@ std::unique_ptr<protocol::DictionaryValue> BuildElementInfo(Element* element) {
class_names.Append("::before");
else if (pseudo_element->GetPseudoId() == kPseudoIdAfter)
class_names.Append("::after");
+ else if (pseudo_element->GetPseudoId() == kPseudoIdMarker)
+ class_names.Append("::marker");
}
if (!class_names.IsEmpty())
element_info->setString("className", class_names.ToString());
@@ -477,7 +479,8 @@ void InspectorHighlight::AppendDistanceInfo(Node* node) {
boxes_ = std::make_unique<protocol::Array<protocol::Array<double>>>();
computed_style_ = protocol::DictionaryValue::create();
- node->GetDocument().EnsurePaintLocationDataValidForNode(node);
+ node->GetDocument().EnsurePaintLocationDataValidForNode(
+ node, DocumentUpdateReason::kInspector);
LayoutObject* layout_object = node->GetLayoutObject();
if (!layout_object)
return;
@@ -486,7 +489,8 @@ void InspectorHighlight::AppendDistanceInfo(Node* node) {
MakeGarbageCollected<CSSComputedStyleDeclaration>(node, true);
for (size_t i = 0; i < style->length(); ++i) {
AtomicString name(style->item(i));
- const CSSValue* value = style->GetPropertyCSSValue(cssPropertyID(name));
+ const CSSValue* value = style->GetPropertyCSSValue(
+ cssPropertyID(node->GetExecutionContext(), name));
if (!value)
continue;
if (value->IsColorValue()) {
@@ -538,7 +542,7 @@ void InspectorHighlight::VisitAndCollectDistanceInfo(
PseudoId pseudo_id,
LayoutObject* layout_object) {
protocol::DOM::PseudoType pseudo_type;
- if (!InspectorDOMAgent::GetPseudoElementType(pseudo_id, &pseudo_type))
+ if (pseudo_id == kPseudoIdNone)
return;
for (LayoutObject* child = layout_object->SlowFirstChild(); child;
child = child->NextSibling()) {
@@ -705,7 +709,8 @@ bool InspectorHighlight::GetBoxModel(
Node* node,
std::unique_ptr<protocol::DOM::BoxModel>* model,
bool use_absolute_zoom) {
- node->GetDocument().EnsurePaintLocationDataValidForNode(node);
+ node->GetDocument().EnsurePaintLocationDataValidForNode(
+ node, DocumentUpdateReason::kInspector);
LayoutObject* layout_object = node->GetLayoutObject();
LocalFrameView* view = node->GetDocument().View();
if (!layout_object || !view)
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 e83d3053335..8aededb9a81 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(blink::Visitor* visitor) {}
+void InspectorHistory::Action::Trace(Visitor* visitor) {}
String InspectorHistory::Action::ToString() {
return name_;
@@ -143,7 +143,7 @@ void InspectorHistory::Reset() {
history_.clear();
}
-void InspectorHistory::Trace(blink::Visitor* visitor) {
+void InspectorHistory::Trace(Visitor* visitor) {
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 c94ece9dfd6..ef5900cd5c5 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(blink::Visitor*);
+ virtual void Trace(Visitor*);
virtual String ToString();
virtual String MergeId();
@@ -67,7 +67,7 @@ class InspectorHistory final : public GarbageCollected<InspectorHistory> {
};
InspectorHistory();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
bool Perform(Action*, ExceptionState&);
void AppendPerformedAction(Action*);
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_io_agent.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_io_agent.cc
index dc913e60697..3094072852d 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_io_agent.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_io_agent.cc
@@ -25,19 +25,19 @@ Response InspectorIOAgent::resolveBlob(const String& object_id, String* uuid) {
std::unique_ptr<v8_inspector::StringBuffer> error;
if (!v8_session_->unwrapObject(&error, ToV8InspectorStringView(object_id),
&value, &context, nullptr))
- return Response::Error(ToCoreString(std::move(error)));
+ return Response::ServerError(ToCoreString(std::move(error)).Utf8());
if (!V8Blob::HasInstance(value, isolate_))
- return Response::Error("Object id doesn't reference a Blob");
+ return Response::ServerError("Object id doesn't reference a Blob");
Blob* blob = V8Blob::ToImpl(v8::Local<v8::Object>::Cast(value));
if (!blob) {
- return Response::Error(
+ return Response::ServerError(
"Couldn't convert object with given objectId to Blob");
}
*uuid = blob->Uuid();
- return Response::OK();
+ return Response::Success();
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_issue.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_issue.cc
new file mode 100644
index 00000000000..93749ebb4e0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_issue.cc
@@ -0,0 +1,52 @@
+// 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.h"
+
+#include "third_party/blink/renderer/core/inspector/identifiers_factory.h"
+#include "third_party/blink/renderer/core/workers/worker_thread.h"
+#include "third_party/blink/renderer/platform/wtf/assertions.h"
+
+#include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/web_inspector_issue.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace blink {
+
+InspectorIssue::InspectorIssue(mojom::blink::InspectorIssueCode code,
+ mojom::blink::InspectorIssueDetailsPtr details,
+ mojom::blink::AffectedResourcesPtr resources)
+ : code_(code),
+ details_(std::move(details)),
+ resources_(std::move(resources)) {
+ DCHECK(details_);
+ DCHECK(resources_);
+}
+
+InspectorIssue::~InspectorIssue() = default;
+
+InspectorIssue* InspectorIssue::Create(
+ mojom::blink::InspectorIssueInfoPtr info) {
+ DCHECK(info->details);
+ DCHECK(info->resources);
+ return MakeGarbageCollected<InspectorIssue>(
+ info->code, std::move(info->details), std::move(info->resources));
+}
+
+mojom::blink::InspectorIssueCode InspectorIssue::Code() const {
+ return code_;
+}
+
+const mojom::blink::InspectorIssueDetailsPtr& InspectorIssue::Details() const {
+ return details_;
+}
+
+const mojom::blink::AffectedResourcesPtr& InspectorIssue::Resources() const {
+ return resources_;
+}
+
+void InspectorIssue::Trace(blink::Visitor* visitor) {}
+
+} // 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
new file mode 100644
index 00000000000..a97cd2ba467
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_issue.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_INSPECTOR_INSPECTOR_ISSUE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_ISSUE_H_
+
+#include "third_party/blink/public/mojom/devtools/inspector_issue.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/wtf/forward.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+class CORE_EXPORT InspectorIssue final
+ : public GarbageCollected<InspectorIssue> {
+ public:
+ InspectorIssue() = delete;
+ InspectorIssue(mojom::blink::InspectorIssueCode code,
+
+ mojom::blink::InspectorIssueDetailsPtr details,
+ mojom::blink::AffectedResourcesPtr resources);
+ ~InspectorIssue();
+
+ static InspectorIssue* Create(mojom::blink::InspectorIssueInfoPtr info);
+
+ mojom::blink::InspectorIssueCode Code() const;
+ const mojom::blink::InspectorIssueDetailsPtr& Details() const;
+ const mojom::blink::AffectedResourcesPtr& Resources() const;
+
+ void Trace(Visitor*);
+
+ private:
+ mojom::blink::InspectorIssueCode code_;
+ mojom::blink::InspectorIssueDetailsPtr details_;
+ mojom::blink::AffectedResourcesPtr resources_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_ISSUE_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
new file mode 100644
index 00000000000..dd081bbbbe3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_issue_storage.cc
@@ -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.
+
+#include "third_party/blink/renderer/core/inspector/inspector_issue_storage.h"
+
+#include "third_party/blink/renderer/core/inspector/inspector_issue.h"
+#include "third_party/blink/renderer/core/probe/core_probes.h"
+
+namespace blink {
+
+static const unsigned kMaxIssueCount = 1000;
+
+InspectorIssueStorage::InspectorIssueStorage() = default;
+
+void InspectorIssueStorage::AddInspectorIssue(ExecutionContext* context,
+ InspectorIssue* issue) {
+ DCHECK(issues_.size() <= kMaxIssueCount);
+ probe::InspectorIssueAdded(context, issue);
+ if (issues_.size() == kMaxIssueCount) {
+ issues_.pop_front();
+ }
+ issues_.push_back(issue);
+}
+
+void InspectorIssueStorage::Clear() {
+ issues_.clear();
+}
+
+wtf_size_t InspectorIssueStorage::size() const {
+ return issues_.size();
+}
+
+InspectorIssue* InspectorIssueStorage::at(wtf_size_t index) const {
+ return issues_[index].Get();
+}
+
+void InspectorIssueStorage::Trace(Visitor* visitor) {
+ visitor->Trace(issues_);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..d318c96d654
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_issue_storage.h
@@ -0,0 +1,38 @@
+// 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_STORAGE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_ISSUE_STORAGE_H_
+
+#include "base/macros.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/forward.h"
+
+namespace blink {
+
+class InspectorIssue;
+class ExecutionContext;
+
+class CORE_EXPORT InspectorIssueStorage
+ : public GarbageCollected<InspectorIssueStorage> {
+ public:
+ InspectorIssueStorage();
+
+ void AddInspectorIssue(ExecutionContext*, InspectorIssue*);
+ void Clear();
+ wtf_size_t size() const;
+ InspectorIssue* at(wtf_size_t index) const;
+
+ void Trace(Visitor*);
+
+ private:
+ HeapDeque<Member<InspectorIssue>> issues_;
+
+ DISALLOW_COPY_AND_ASSIGN(InspectorIssueStorage);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_ISSUE_STORAGE_H_
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 48af2af46e3..684f6121ecf 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
@@ -36,8 +36,8 @@
#include "base/stl_util.h"
#include "cc/base/region.h"
#include "cc/layers/picture_layer.h"
+#include "cc/trees/layer_tree_host.h"
#include "cc/trees/transform_node.h"
-#include "third_party/blink/public/platform/web_float_point.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -59,6 +59,7 @@
#include "third_party/blink/renderer/platform/transforms/transformation_matrix.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/inspector_protocol/crdtp/json.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "ui/gfx/geometry/rect.h"
@@ -84,6 +85,16 @@ static std::unique_ptr<protocol::DOM::Rect> BuildObjectForRect(
.build();
}
+static std::unique_ptr<protocol::DOM::Rect> BuildObjectForRect(
+ const gfx::RectF& rect) {
+ return protocol::DOM::Rect::create()
+ .setX(rect.x())
+ .setY(rect.y())
+ .setHeight(rect.height())
+ .setWidth(rect.width())
+ .build();
+}
+
static std::unique_ptr<protocol::LayerTree::ScrollRect> BuildScrollRect(
const gfx::Rect& rect,
const String& type) {
@@ -250,7 +261,7 @@ InspectorLayerTreeAgent::InspectorLayerTreeAgent(
InspectorLayerTreeAgent::~InspectorLayerTreeAgent() = default;
-void InspectorLayerTreeAgent::Trace(blink::Visitor* visitor) {
+void InspectorLayerTreeAgent::Trace(Visitor* visitor) {
visitor->Trace(inspected_frames_);
InspectorBaseAgent::Trace(visitor);
}
@@ -265,21 +276,21 @@ Response InspectorLayerTreeAgent::enable() {
instrumenting_agents_->AddInspectorLayerTreeAgent(this);
Document* document = inspected_frames_->Root()->GetDocument();
if (!document)
- return Response::Error("The root frame doesn't have document");
+ return Response::ServerError("The root frame doesn't have document");
inspected_frames_->Root()->View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kOther);
+ DocumentUpdateReason::kInspector);
LayerTreePainted();
LayerTreeDidChange();
- return Response::OK();
+ return Response::Success();
}
Response InspectorLayerTreeAgent::disable() {
instrumenting_agents_->RemoveInspectorLayerTreeAgent(this);
snapshot_by_id_.clear();
- return Response::OK();
+ return Response::Success();
}
void InspectorLayerTreeAgent::LayerTreeDidChange() {
@@ -354,27 +365,36 @@ Response InspectorLayerTreeAgent::LayerById(const String& layer_id,
bool ok;
int id = layer_id.ToInt(&ok);
if (!ok)
- return Response::Error("Invalid layer id");
+ return Response::ServerError("Invalid layer id");
result = FindLayerById(RootLayer(), id);
if (!result)
- return Response::Error("No layer matching given id found");
- return Response::OK();
+ return Response::ServerError("No layer matching given id found");
+ return Response::Success();
}
Response InspectorLayerTreeAgent::compositingReasons(
const String& layer_id,
- std::unique_ptr<Array<String>>* reason_strings) {
+ std::unique_ptr<Array<String>>* compositing_reasons,
+ std::unique_ptr<Array<String>>* compositing_reason_ids) {
const cc::Layer* layer = nullptr;
Response response = LayerById(layer_id, layer);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
- *reason_strings = std::make_unique<protocol::Array<String>>();
+ *compositing_reasons = std::make_unique<protocol::Array<String>>();
+ *compositing_reason_ids = std::make_unique<protocol::Array<String>>();
if (layer->debug_info()) {
- for (const char* name : layer->debug_info()->compositing_reasons)
- (*reason_strings)->emplace_back(name);
+ for (const char* compositing_reason :
+ layer->debug_info()->compositing_reasons) {
+ (*compositing_reasons)->emplace_back(compositing_reason);
+ }
+ for (const char* compositing_reason_id :
+ layer->debug_info()->compositing_reason_ids) {
+ (*compositing_reason_ids)->emplace_back(compositing_reason_id);
+ }
}
- return Response::OK();
+
+ return Response::Success();
}
Response InspectorLayerTreeAgent::makeSnapshot(const String& layer_id,
@@ -388,38 +408,38 @@ Response InspectorLayerTreeAgent::makeSnapshot(const String& layer_id,
->GetDocument()
->Lifecycle()
.LifecyclePostponed())
- return Response::Error("Layer does not draw content");
+ return Response::ServerError("Layer does not draw content");
inspected_frames_->Root()->View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kOther);
+ DocumentUpdateReason::kInspector);
suppress_layer_paint_events_ = false;
const cc::Layer* layer = nullptr;
Response response = LayerById(layer_id, layer);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
if (!layer->DrawsContent())
- return Response::Error("Layer does not draw content");
+ return Response::ServerError("Layer does not draw content");
auto picture = layer->GetPicture();
if (!picture)
- return Response::Error("Layer does not produce picture");
+ return Response::ServerError("Layer does not produce picture");
auto snapshot = base::MakeRefCounted<PictureSnapshot>(std::move(picture));
*snapshot_id = String::Number(++last_snapshot_id_);
bool new_entry = snapshot_by_id_.insert(*snapshot_id, snapshot).is_new_entry;
DCHECK(new_entry);
- return Response::OK();
+ return Response::Success();
}
Response InspectorLayerTreeAgent::loadSnapshot(
std::unique_ptr<Array<protocol::LayerTree::PictureTile>> tiles,
String* snapshot_id) {
if (tiles->empty())
- return Response::Error("Invalid argument, no tiles provided");
+ return Response::ServerError("Invalid argument, no tiles provided");
if (tiles->size() > UINT_MAX)
- return Response::Error("Invalid argument, too many tiles provided");
+ return Response::ServerError("Invalid argument, too many tiles provided");
wtf_size_t tiles_length = static_cast<wtf_size_t>(tiles->size());
Vector<scoped_refptr<PictureSnapshot::TilePictureStream>> decoded_tiles;
decoded_tiles.Grow(tiles_length);
@@ -434,22 +454,22 @@ Response InspectorLayerTreeAgent::loadSnapshot(
scoped_refptr<PictureSnapshot> snapshot =
PictureSnapshot::Load(decoded_tiles);
if (!snapshot)
- return Response::Error("Invalid snapshot format");
+ return Response::ServerError("Invalid snapshot format");
if (snapshot->IsEmpty())
- return Response::Error("Empty snapshot");
+ return Response::ServerError("Empty snapshot");
*snapshot_id = String::Number(++last_snapshot_id_);
bool new_entry = snapshot_by_id_.insert(*snapshot_id, snapshot).is_new_entry;
DCHECK(new_entry);
- return Response::OK();
+ return Response::Success();
}
Response InspectorLayerTreeAgent::releaseSnapshot(const String& snapshot_id) {
SnapshotById::iterator it = snapshot_by_id_.find(snapshot_id);
if (it == snapshot_by_id_.end())
- return Response::Error("Snapshot not found");
+ return Response::ServerError("Snapshot not found");
snapshot_by_id_.erase(it);
- return Response::OK();
+ return Response::Success();
}
Response InspectorLayerTreeAgent::GetSnapshotById(
@@ -457,9 +477,9 @@ Response InspectorLayerTreeAgent::GetSnapshotById(
const PictureSnapshot*& result) {
SnapshotById::iterator it = snapshot_by_id_.find(snapshot_id);
if (it == snapshot_by_id_.end())
- return Response::Error("Snapshot not found");
+ return Response::ServerError("Snapshot not found");
result = it->value.get();
- return Response::OK();
+ return Response::Success();
}
Response InspectorLayerTreeAgent::replaySnapshot(const String& snapshot_id,
@@ -469,14 +489,14 @@ Response InspectorLayerTreeAgent::replaySnapshot(const String& snapshot_id,
String* data_url) {
const PictureSnapshot* snapshot = nullptr;
Response response = GetSnapshotById(snapshot_id, snapshot);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
auto png_data = snapshot->Replay(from_step.fromMaybe(0), to_step.fromMaybe(0),
scale.fromMaybe(1.0));
if (png_data.IsEmpty())
- return Response::Error("Image encoding failed");
+ return Response::ServerError("Image encoding failed");
*data_url = "data:image/png;base64," + Base64Encode(png_data);
- return Response::OK();
+ return Response::Success();
}
static void ParseRect(protocol::DOM::Rect* object, FloatRect* rect) {
@@ -492,7 +512,7 @@ Response InspectorLayerTreeAgent::profileSnapshot(
std::unique_ptr<protocol::Array<protocol::Array<double>>>* out_timings) {
const PictureSnapshot* snapshot = nullptr;
Response response = GetSnapshotById(snapshot_id, snapshot);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
FloatRect rect;
if (clip_rect.isJust())
@@ -508,7 +528,7 @@ Response InspectorLayerTreeAgent::profileSnapshot(
out_row->emplace_back(delta.InSecondsF());
(*out_timings)->emplace_back(std::move(out_row));
}
- return Response::OK();
+ return Response::Success();
}
Response InspectorLayerTreeAgent::snapshotCommandLog(
@@ -516,17 +536,29 @@ Response InspectorLayerTreeAgent::snapshotCommandLog(
std::unique_ptr<Array<protocol::DictionaryValue>>* command_log) {
const PictureSnapshot* snapshot = nullptr;
Response response = GetSnapshotById(snapshot_id, snapshot);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
protocol::ErrorSupport errors;
- std::unique_ptr<protocol::Value> log_value = protocol::StringUtil::parseJSON(
- snapshot->SnapshotCommandLog()->ToJSONString());
+ const String& json = snapshot->SnapshotCommandLog()->ToJSONString();
+ std::vector<uint8_t> cbor;
+ if (json.Is8Bit()) {
+ crdtp::json::ConvertJSONToCBOR(
+ crdtp::span<uint8_t>(json.Characters8(), json.length()), &cbor);
+ } else {
+ crdtp::json::ConvertJSONToCBOR(
+ crdtp::span<uint16_t>(
+ reinterpret_cast<const uint16_t*>(json.Characters16()),
+ json.length()),
+ &cbor);
+ }
+ auto log_value = protocol::Value::parseBinary(cbor.data(), cbor.size());
*command_log = protocol::ValueConversions<
protocol::Array<protocol::DictionaryValue>>::fromValue(log_value.get(),
&errors);
- if (errors.hasErrors())
- return Response::Error(errors.errors());
- return Response::OK();
+ auto err = errors.Errors();
+ if (err.empty())
+ return Response::Success();
+ return Response::ServerError(std::string(err.begin(), err.end()));
}
} // namespace blink
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 8eb4a83cc75..1f06545f9f9 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
@@ -58,7 +58,7 @@ class CORE_EXPORT InspectorLayerTreeAgent final
InspectorLayerTreeAgent(InspectedFrames*, Client*);
~InspectorLayerTreeAgent() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void Restore() override;
@@ -71,7 +71,9 @@ class CORE_EXPORT InspectorLayerTreeAgent final
protocol::Response disable() override;
protocol::Response compositingReasons(
const String& layer_id,
- std::unique_ptr<protocol::Array<String>>* compositing_reasons) override;
+ std::unique_ptr<protocol::Array<String>>* compositing_reasons,
+ std::unique_ptr<protocol::Array<String>>* compositing_reason_ids)
+ override;
protocol::Response makeSnapshot(const String& layer_id,
String* snapshot_id) override;
protocol::Response loadSnapshot(
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 704802d5cd0..e3429abb2e7 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
@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/core/inspector/inspector_dom_agent.h"
#include "third_party/blink/renderer/core/inspector/resolve_node.h"
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
using protocol::Response;
@@ -82,7 +83,7 @@ InspectorLogAgent::InspectorLogAgent(
InspectorLogAgent::~InspectorLogAgent() = default;
-void InspectorLogAgent::Trace(blink::Visitor* visitor) {
+void InspectorLogAgent::Trace(Visitor* visitor) {
visitor->Trace(storage_);
visitor->Trace(performance_monitor_);
InspectorBaseAgent::Trace(visitor);
@@ -182,24 +183,24 @@ void InspectorLogAgent::InnerEnable() {
Response InspectorLogAgent::enable() {
if (enabled_.Get())
- return Response::OK();
+ return Response::Success();
enabled_.Set(true);
InnerEnable();
- return Response::OK();
+ return Response::Success();
}
Response InspectorLogAgent::disable() {
if (!enabled_.Get())
- return Response::OK();
+ return Response::Success();
enabled_.Clear();
stopViolationsReport();
instrumenting_agents_->RemoveInspectorLogAgent(this);
- return Response::OK();
+ return Response::Success();
}
Response InspectorLogAgent::clear() {
storage_->Clear();
- return Response::OK();
+ return Response::Success();
}
static PerformanceMonitor::Violation ParseViolation(const String& name) {
@@ -223,9 +224,11 @@ static PerformanceMonitor::Violation ParseViolation(const String& name) {
Response InspectorLogAgent::startViolationsReport(
std::unique_ptr<protocol::Array<ViolationSetting>> settings) {
if (!enabled_.Get())
- return Response::Error("Log is not enabled");
- if (!performance_monitor_)
- return Response::Error("Violations are not supported for this target");
+ return Response::ServerError("Log is not enabled");
+ if (!performance_monitor_) {
+ return Response::ServerError(
+ "Violations are not supported for this target");
+ }
performance_monitor_->UnsubscribeAll(this);
violation_thresholds_.Clear();
for (const std::unique_ptr<ViolationSetting>& setting : *settings) {
@@ -238,22 +241,24 @@ Response InspectorLogAgent::startViolationsReport(
violation, base::TimeDelta::FromMillisecondsD(threshold), this);
violation_thresholds_.Set(name, threshold);
}
- return Response::OK();
+ return Response::Success();
}
Response InspectorLogAgent::stopViolationsReport() {
violation_thresholds_.Clear();
- if (!performance_monitor_)
- return Response::Error("Violations are not supported for this target");
+ if (!performance_monitor_) {
+ return Response::ServerError(
+ "Violations are not supported for this target");
+ }
performance_monitor_->UnsubscribeAll(this);
- return Response::OK();
+ return Response::Success();
}
void InspectorLogAgent::ReportLongLayout(base::TimeDelta duration) {
String message_text = String::Format(
"Forced reflow while executing JavaScript took %" PRId64 "ms",
duration.InMilliseconds());
- ConsoleMessage* message = ConsoleMessage::Create(
+ auto* message = MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kViolation,
mojom::ConsoleMessageLevel::kVerbose, message_text);
ConsoleMessageAdded(message);
@@ -263,7 +268,7 @@ void InspectorLogAgent::ReportGenericViolation(PerformanceMonitor::Violation,
const String& text,
base::TimeDelta time,
SourceLocation* location) {
- ConsoleMessage* message = ConsoleMessage::Create(
+ auto* message = MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kViolation,
mojom::ConsoleMessageLevel::kVerbose, text, location->Clone());
ConsoleMessageAdded(message);
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 8b46b3181e3..6dbe8f26f0b 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 9b1cdc95b17..16a634f9f44 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
@@ -17,11 +17,11 @@ std::unique_ptr<protocol::Media::PlayerEvent> ConvertInspectorPlayerEvent(
const InspectorPlayerEvent& event) {
protocol::Media::PlayerEventType event_type;
switch (event.type) {
- case InspectorPlayerEvent::PLAYBACK_EVENT:
- event_type = protocol::Media::PlayerEventTypeEnum::PlaybackEvent;
+ case InspectorPlayerEvent::ERROR_EVENT:
+ event_type = protocol::Media::PlayerEventTypeEnum::ErrorEvent;
break;
- case InspectorPlayerEvent::SYSTEM_EVENT:
- event_type = protocol::Media::PlayerEventTypeEnum::SystemEvent;
+ case InspectorPlayerEvent::TRIGGERED_EVENT:
+ event_type = protocol::Media::PlayerEventTypeEnum::TriggeredEvent;
break;
case InspectorPlayerEvent::MESSAGE_EVENT:
event_type = protocol::Media::PlayerEventTypeEnum::MessageEvent;
@@ -72,18 +72,18 @@ void InspectorMediaAgent::RegisterAgent() {
protocol::Response InspectorMediaAgent::enable() {
if (enabled_.Get())
- return protocol::Response::OK();
+ return protocol::Response::Success();
enabled_.Set(true);
RegisterAgent();
- return protocol::Response::OK();
+ return protocol::Response::Success();
}
protocol::Response InspectorMediaAgent::disable() {
if (!enabled_.Get())
- return protocol::Response::OK();
+ return protocol::Response::Success();
enabled_.Clear();
instrumenting_agents_->RemoveInspectorMediaAgent(this);
- return protocol::Response::OK();
+ return protocol::Response::Success();
}
void InspectorMediaAgent::PlayerPropertiesChanged(
@@ -117,7 +117,7 @@ void InspectorMediaAgent::PlayersCreated(const Vector<WebString>& player_ids) {
GetFrontend()->playersCreated(std::move(protocol_players));
}
-void InspectorMediaAgent::Trace(blink::Visitor* visitor) {
+void InspectorMediaAgent::Trace(Visitor* visitor) {
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 493f5d7e30f..e7292fa4c51 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
@@ -36,7 +36,7 @@ class CORE_EXPORT InspectorMediaAgent final
void PlayersCreated(const Vector<WebString>&);
// blink-gc methods.
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 38d03b8995e..445786bfedb 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
@@ -46,7 +46,7 @@ MediaInspectorContextImpl::MediaInspectorContextImpl(LocalFrame& frame)
: Supplement<LocalFrame>(frame) {}
// Garbage collection method.
-void MediaInspectorContextImpl::Trace(blink::Visitor* visitor) {
+void MediaInspectorContextImpl::Trace(Visitor* visitor) {
Supplement<LocalFrame>::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 f863a1ea110..4b6c3eee2ac 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
@@ -22,7 +22,7 @@ class Document;
class HTMLMediaElement;
struct MediaPlayer final : public GarbageCollected<MediaPlayer> {
- void Trace(blink::Visitor*) {}
+ void Trace(Visitor*) {}
WebString player_id;
InspectorPlayerEvents events;
@@ -55,7 +55,7 @@ class CORE_EXPORT MediaInspectorContextImpl final
void SetPlayerProperties(WebString, InspectorPlayerProperties) override;
// GarbageCollected methods.
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
Vector<WebString> GetAllPlayerIds();
std::pair<Vector<InspectorPlayerProperty>, Vector<InspectorPlayerEvent>>
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 23adb49e4e4..b7bbd98f175 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
@@ -33,7 +33,7 @@
#include <cstdio>
#include "base/debug/stack_trace.h"
-#include "base/sampling_heap_profiler/module_cache.h"
+#include "base/profiler/module_cache.h"
#include "base/sampling_heap_profiler/sampling_heap_profiler.h"
#include "build/build_config.h"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
@@ -41,6 +41,7 @@
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
#include "third_party/blink/renderer/platform/instrumentation/instance_counters.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
namespace blink {
@@ -62,7 +63,7 @@ Response InspectorMemoryAgent::getDOMCounters(int* documents,
*nodes = InstanceCounters::CounterValue(InstanceCounters::kNodeCounter);
*js_event_listeners =
InstanceCounters::CounterValue(InstanceCounters::kJSEventListenerCounter);
- return Response::OK();
+ return Response::Success();
}
Response InspectorMemoryAgent::forciblyPurgeJavaScriptMemory() {
@@ -77,10 +78,10 @@ Response InspectorMemoryAgent::forciblyPurgeJavaScriptMemory() {
}
V8PerIsolateData::MainThreadIsolate()->MemoryPressureNotification(
v8::MemoryPressureLevel::kCritical);
- return Response::OK();
+ return Response::Success();
}
-void InspectorMemoryAgent::Trace(blink::Visitor* visitor) {
+void InspectorMemoryAgent::Trace(Visitor* visitor) {
visitor->Trace(frames_);
InspectorBaseAgent::Trace(visitor);
}
@@ -97,33 +98,33 @@ Response InspectorMemoryAgent::startSampling(
int interval =
in_sampling_interval.fromMaybe(kDefaultNativeMemorySamplingInterval);
if (interval <= 0)
- return Response::Error("Invalid sampling rate.");
+ return Response::ServerError("Invalid sampling rate.");
base::SamplingHeapProfiler::Get()->SetSamplingInterval(interval);
sampling_profile_interval_.Set(interval);
if (in_suppressRandomness.fromMaybe(false))
base::PoissonAllocationSampler::Get()->SuppressRandomnessForTest(true);
profile_id_ = base::SamplingHeapProfiler::Get()->Start();
- return Response::OK();
+ return Response::Success();
}
Response InspectorMemoryAgent::stopSampling() {
if (sampling_profile_interval_.Get() == 0)
- return Response::Error("Sampling profiler is not started.");
+ return Response::ServerError("Sampling profiler is not started.");
base::SamplingHeapProfiler::Get()->Stop();
sampling_profile_interval_.Clear();
- return Response::OK();
+ return Response::Success();
}
Response InspectorMemoryAgent::getAllTimeSamplingProfile(
std::unique_ptr<protocol::Memory::SamplingProfile>* out_profile) {
*out_profile = GetSamplingProfileById(0);
- return Response::OK();
+ return Response::Success();
}
Response InspectorMemoryAgent::getSamplingProfile(
std::unique_ptr<protocol::Memory::SamplingProfile>* out_profile) {
*out_profile = GetSamplingProfileById(profile_id_);
- return Response::OK();
+ return Response::Success();
}
std::unique_ptr<protocol::Memory::SamplingProfile>
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 264b9ca18fc..bd83b92b80c 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
@@ -43,13 +43,9 @@ class InspectedFrames;
class CORE_EXPORT InspectorMemoryAgent final
: public InspectorBaseAgent<protocol::Memory::Metainfo> {
public:
- static InspectorMemoryAgent* Create(InspectedFrames* frames) {
- return MakeGarbageCollected<InspectorMemoryAgent>(frames);
- }
-
explicit InspectorMemoryAgent(InspectedFrames*);
~InspectorMemoryAgent() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 11b2fcf9da7..79887e2fc68 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
@@ -37,6 +37,7 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "build/build_config.h"
+#include "net/http/http_status_code.h"
#include "services/network/public/mojom/referrer_policy.mojom-blink.h"
#include "services/network/public/mojom/websocket.mojom-blink.h"
#include "third_party/blink/public/mojom/loader/request_context_frame_type.mojom-blink.h"
@@ -50,6 +51,7 @@
#include "third_party/blink/renderer/core/dom/scriptable_document_parser.h"
#include "third_party/blink/renderer/core/fileapi/file_reader_loader.h"
#include "third_party/blink/renderer/core/fileapi/file_reader_loader_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/html/html_frame_owner_element.h"
#include "third_party/blink/renderer/core/inspector/identifiers_factory.h"
@@ -64,6 +66,7 @@
#include "third_party/blink/renderer/core/xmlhttprequest/xml_http_request.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.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/loader/fetch/fetch_initiator_info.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h"
#include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
@@ -84,6 +87,10 @@
#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"
+#include "third_party/inspector_protocol/crdtp/json.h"
+
+using crdtp::SpanFrom;
+using crdtp::json::ConvertCBORToJSON;
namespace blink {
@@ -166,13 +173,11 @@ class InspectorFileReaderLoaderClient final : public FileReaderLoaderClient {
public:
InspectorFileReaderLoaderClient(
scoped_refptr<BlobDataHandle> blob,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
base::OnceCallback<void(scoped_refptr<SharedBuffer>)> callback)
: blob_(std::move(blob)), callback_(std::move(callback)) {
- // TODO(hajimehoshi): Use a per-ExecutionContext task runner of
- // TaskType::kFileReading
loader_ = std::make_unique<FileReaderLoader>(
- FileReaderLoader::kReadByClient, this,
- ThreadScheduler::Current()->DeprecatedDefaultTaskRunner());
+ FileReaderLoader::kReadByClient, this, std::move(task_runner));
}
~InspectorFileReaderLoaderClient() override = default;
@@ -216,7 +221,7 @@ static void ResponseBodyFileReaderLoaderDone(
std::unique_ptr<GetResponseBodyCallback> callback,
scoped_refptr<SharedBuffer> raw_data) {
if (!raw_data) {
- callback->sendFailure(Response::Error("Couldn't read BLOB"));
+ callback->sendFailure(Response::ServerError("Couldn't read BLOB"));
return;
}
String result;
@@ -225,16 +230,19 @@ static void ResponseBodyFileReaderLoaderDone(
raw_data, mime_type, text_encoding_name, &result, &base64_encoded)) {
callback->sendSuccess(result, base64_encoded);
} else {
- callback->sendFailure(Response::Error("Couldn't encode data"));
+ callback->sendFailure(Response::ServerError("Couldn't encode data"));
}
}
class InspectorPostBodyParser
: public WTF::RefCounted<InspectorPostBodyParser> {
public:
- explicit InspectorPostBodyParser(
- std::unique_ptr<GetRequestPostDataCallback> callback)
- : callback_(std::move(callback)), error_(false) {}
+ InspectorPostBodyParser(
+ std::unique_ptr<GetRequestPostDataCallback> callback,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ : callback_(std::move(callback)),
+ task_runner_(std::move(task_runner)),
+ error_(false) {}
void Parse(EncodedFormData* request_body) {
if (!request_body || request_body->IsEmpty())
@@ -286,13 +294,14 @@ class InspectorPostBodyParser
if (!blob_handle)
return;
auto* reader = new InspectorFileReaderLoaderClient(
- blob_handle,
+ blob_handle, task_runner_,
WTF::Bind(&InspectorPostBodyParser::BlobReadCallback,
WTF::RetainedRef(this), WTF::Unretained(destination)));
reader->Start();
}
std::unique_ptr<GetRequestPostDataCallback> callback_;
+ const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
bool error_;
Vector<String> parts_;
DISALLOW_COPY_AND_ASSIGN(InspectorPostBodyParser);
@@ -355,6 +364,21 @@ String BuildBlockedReason(ResourceRequestBlockedReason reason) {
return protocol::Network::BlockedReasonEnum::Other;
case ResourceRequestBlockedReason::kCollapsedByClient:
return protocol::Network::BlockedReasonEnum::CollapsedByClient;
+ case blink::ResourceRequestBlockedReason::kCoepFrameResourceNeedsCoepHeader:
+ return protocol::Network::BlockedReasonEnum::
+ CoepFrameResourceNeedsCoepHeader;
+ case blink::ResourceRequestBlockedReason::
+ kCoopSandboxedIFrameCannotNavigateToCoopPage:
+ return protocol::Network::BlockedReasonEnum::
+ CoopSandboxedIframeCannotNavigateToCoopPage;
+ case blink::ResourceRequestBlockedReason::kCorpNotSameOrigin:
+ return protocol::Network::BlockedReasonEnum::CorpNotSameOrigin;
+ case blink::ResourceRequestBlockedReason::
+ kCorpNotSameOriginAfterDefaultedToSameOriginByCoep:
+ return protocol::Network::BlockedReasonEnum::
+ CorpNotSameOriginAfterDefaultedToSameOriginByCoep;
+ case blink::ResourceRequestBlockedReason::kCorpNotSameSite:
+ return protocol::Network::BlockedReasonEnum::CorpNotSameSite;
}
NOTREACHED();
return protocol::Network::BlockedReasonEnum::Other;
@@ -408,8 +432,7 @@ String GetReferrerPolicy(network::mojom::ReferrerPolicy policy) {
return protocol::Network::Request::ReferrerPolicyEnum::SameOrigin;
case network::mojom::ReferrerPolicy::kStrictOrigin:
return protocol::Network::Request::ReferrerPolicyEnum::StrictOrigin;
- case network::mojom::ReferrerPolicy::
- kNoReferrerWhenDowngradeOriginWhenCrossOrigin:
+ case network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin:
return protocol::Network::Request::ReferrerPolicyEnum::
StrictOriginWhenCrossOrigin;
}
@@ -490,16 +513,25 @@ static bool FormDataToString(scoped_refptr<EncodedFormData> body,
static std::unique_ptr<protocol::Network::Request>
BuildObjectForResourceRequest(const ResourceRequest& request,
+ scoped_refptr<EncodedFormData> post_data,
size_t max_body_size) {
String postData;
- bool hasPostData =
- FormDataToString(request.HttpBody(), max_body_size, &postData);
+ bool hasPostData = FormDataToString(post_data, max_body_size, &postData);
KURL url = request.Url();
+ // protocol::Network::Request doesn't have a separate referrer string member
+ // like blink::ResourceRequest, so here we add ResourceRequest's referrer
+ // string to the protocol request's headers manually.
+ auto headers = request.HttpHeaderFields();
+
+ // The request's referrer must be generated at this point.
+ DCHECK_NE(request.ReferrerString(), Referrer::ClientReferrerString());
+ headers.Set(http_names::kReferer, AtomicString(request.ReferrerString()));
+
std::unique_ptr<protocol::Network::Request> result =
protocol::Network::Request::create()
.setUrl(UrlWithoutFragment(url).GetString())
.setMethod(request.HttpMethod())
- .setHeaders(BuildObjectForHeaders(request.HttpHeaderFields()))
+ .setHeaders(BuildObjectForHeaders(headers))
.setInitialPriority(ResourcePriorityJSON(request.Priority()))
.setReferrerPolicy(GetReferrerPolicy(request.GetReferrerPolicy()))
.build();
@@ -683,7 +715,7 @@ BuildObjectForResourceResponse(const ResourceResponse& response,
InspectorNetworkAgent::~InspectorNetworkAgent() = default;
-void InspectorNetworkAgent::Trace(blink::Visitor* visitor) {
+void InspectorNetworkAgent::Trace(Visitor* visitor) {
visitor->Trace(inspected_frames_);
visitor->Trace(worker_global_scope_);
visitor->Trace(resources_data_);
@@ -755,12 +787,15 @@ void InspectorNetworkAgent::WillSendRequestInternal(
String request_id = IdentifiersFactory::RequestId(loader, identifier);
NetworkResourcesData::ResourceData const* data =
resources_data_->Data(request_id);
- // Support for POST request redirect
+ // Support for POST request redirect.
scoped_refptr<EncodedFormData> post_data;
- if (data)
+ if (data &&
+ (redirect_response.HttpStatusCode() == net::HTTP_TEMPORARY_REDIRECT ||
+ redirect_response.HttpStatusCode() == net::HTTP_PERMANENT_REDIRECT)) {
post_data = data->PostData();
- else if (request.HttpBody())
+ } else if (request.HttpBody()) {
post_data = request.HttpBody()->DeepCopy();
+ }
resources_data_->ResourceCreated(request_id, loader_id, request.Url(),
post_data);
@@ -783,7 +818,8 @@ void InspectorNetworkAgent::WillSendRequestInternal(
initiator_info, std::numeric_limits<int>::max());
std::unique_ptr<protocol::Network::Request> request_info(
- BuildObjectForResourceRequest(request, max_post_data_size_.Get()));
+ BuildObjectForResourceRequest(request, post_data,
+ max_post_data_size_.Get()));
// |loader| is null while inspecting worker.
// TODO(horo): Refactor MixedContentChecker and set mixed content type even if
@@ -859,13 +895,11 @@ void InspectorNetworkAgent::PrepareRequest(
AtomicString header_name = AtomicString(key);
// When overriding referer, also override referrer policy
// for this request to assure the request will be allowed.
- // TODO(domfarolino): Stop setting the HTTPReferrer header, and instead
- // use ResourceRequest::referrer_. See https://crbug.com/850813. This
- // seems to require storing the referrer info that is currently stored
- // inside state_'s kExtraRequestHeaders, somewhere else.
+ // TODO: Should we store the referrer header somewhere other than
+ // |extra_request_headers_|?
if (header_name.LowerASCII() == http_names::kReferer.LowerASCII()) {
- request.SetHttpReferrer(
- Referrer(value, network::mojom::ReferrerPolicy::kAlways));
+ request.SetReferrerString(value);
+ request.SetReferrerPolicy(network::mojom::ReferrerPolicy::kAlways);
} else {
request.SetHttpHeaderField(header_name, AtomicString(value));
}
@@ -1088,7 +1122,7 @@ void InspectorNetworkAgent::DidFailLoading(uint64_t identifier,
bool canceled = error.IsCancellation();
base::Optional<ResourceRequestBlockedReason> resource_request_blocked_reason =
error.GetResourceRequestBlockedReason();
- blink::protocol::Maybe<String> blocked_reason;
+ protocol::Maybe<String> blocked_reason;
if (resource_request_blocked_reason) {
blocked_reason =
BuildBlockedReason(resource_request_blocked_reason.value());
@@ -1123,13 +1157,12 @@ void InspectorNetworkAgent::WillLoadXHR(ExecutionContext* execution_context,
const AtomicString& method,
const KURL& url,
bool async,
- EncodedFormData* form_data,
const HTTPHeaderMap& headers,
bool include_credentials) {
DCHECK(!pending_request_type_);
- pending_xhr_replay_data_ = XHRReplayData::Create(
+ pending_xhr_replay_data_ = MakeGarbageCollected<XHRReplayData>(
execution_context, method, UrlWithoutFragment(url), async,
- form_data ? form_data->DeepCopy() : nullptr, include_credentials);
+ include_credentials);
for (const auto& header : headers)
pending_xhr_replay_data_->AddHeader(header.key, header.value);
DCHECK(!is_handling_sync_xhr_);
@@ -1175,8 +1208,9 @@ InspectorNetworkAgent::BuildInitiatorObject(
std::unique_ptr<v8_inspector::protocol::Runtime::API::StackTrace>
current_stack_trace =
- SourceLocation::Capture(document)->BuildInspectorObject(
- max_async_depth);
+ SourceLocation::Capture(document ? document->GetExecutionContext()
+ : nullptr)
+ ->BuildInspectorObject(max_async_depth);
if (current_stack_trace) {
std::unique_ptr<protocol::Network::Initiator> initiator_object =
protocol::Network::Initiator::create()
@@ -1351,7 +1385,7 @@ Response InspectorNetworkAgent::enable(Maybe<int> total_buffer_size,
resource_buffer_size.fromMaybe(kDefaultResourceBufferSize));
max_post_data_size_.Set(max_post_data_size.fromMaybe(0));
Enable();
- return Response::OK();
+ return Response::Success();
}
void InspectorNetworkAgent::Enable() {
@@ -1370,7 +1404,7 @@ Response InspectorNetworkAgent::disable() {
instrumenting_agents_->RemoveInspectorNetworkAgent(this);
agent_state_.ClearAllFields();
resources_data_->Clear();
- return Response::OK();
+ return Response::Success();
}
Response InspectorNetworkAgent::setExtraHTTPHeaders(
@@ -1383,7 +1417,7 @@ Response InspectorNetworkAgent::setExtraHTTPHeaders(
if (entry.second && entry.second->asString(&value))
extra_request_headers_.Set(entry.first, value);
}
- return Response::OK();
+ return Response::Success();
}
bool InspectorNetworkAgent::CanGetResponseBodyBlob(const String& request_id) {
@@ -1406,8 +1440,13 @@ void InspectorNetworkAgent::GetResponseBodyBlob(
NetworkResourcesData::ResourceData const* resource_data =
resources_data_->Data(request_id);
BlobDataHandle* blob = resource_data->DownloadedFileBlob();
+ ExecutionContext* context = GetTargetExecutionContext();
+ if (!context) {
+ callback->sendFailure(Response::InternalError());
+ return;
+ }
InspectorFileReaderLoaderClient* client = new InspectorFileReaderLoaderClient(
- blob,
+ blob, context->GetTaskRunner(TaskType::kFileReading),
WTF::Bind(ResponseBodyFileReaderLoaderDone, resource_data->MimeType(),
resource_data->TextEncodingName(),
WTF::Passed(std::move(callback))));
@@ -1425,7 +1464,7 @@ void InspectorNetworkAgent::getResponseBody(
String content;
bool base64_encoded;
Response response = GetResponseBody(request_id, &content, &base64_encoded);
- if (response.isSuccess()) {
+ if (response.IsSuccess()) {
callback->sendSuccess(content, base64_encoded);
} else {
callback->sendFailure(response);
@@ -1437,7 +1476,7 @@ Response InspectorNetworkAgent::setBlockedURLs(
blocked_urls_.Clear();
for (const String& url : *urls)
blocked_urls_.Set(url, true);
- return Response::OK();
+ return Response::Success();
}
Response InspectorNetworkAgent::replayXHR(const String& request_id) {
@@ -1446,12 +1485,12 @@ Response InspectorNetworkAgent::replayXHR(const String& request_id) {
XHRReplayData* xhr_replay_data = resources_data_->XhrReplayData(request_id);
auto* data = resources_data_->Data(request_id);
if (!xhr_replay_data || !data)
- return Response::Error("Given id does not correspond to XHR");
+ return Response::ServerError("Given id does not correspond to XHR");
ExecutionContext* execution_context = xhr_replay_data->GetExecutionContext();
if (!execution_context || execution_context->IsContextDestroyed()) {
resources_data_->SetXHRReplayData(request_id, nullptr);
- return Response::Error("Document is already detached");
+ return Response::ServerError("Document is already detached");
}
XMLHttpRequest* xhr = XMLHttpRequest::Create(execution_context);
@@ -1466,25 +1505,21 @@ Response InspectorNetworkAgent::replayXHR(const String& request_id) {
xhr->setRequestHeader(header.key, header.value,
IGNORE_EXCEPTION_FOR_TESTING);
}
- scoped_refptr<EncodedFormData> post_data;
- if (data)
- post_data = data->PostData();
- if (!post_data)
- post_data = xhr_replay_data->FormData();
- xhr->SendForInspectorXHRReplay(post_data, IGNORE_EXCEPTION_FOR_TESTING);
+ xhr->SendForInspectorXHRReplay(data ? data->PostData() : nullptr,
+ IGNORE_EXCEPTION_FOR_TESTING);
replay_xhrs_.insert(xhr);
- return Response::OK();
+ return Response::Success();
}
Response InspectorNetworkAgent::canClearBrowserCache(bool* result) {
*result = true;
- return Response::OK();
+ return Response::Success();
}
Response InspectorNetworkAgent::canClearBrowserCookies(bool* result) {
*result = true;
- return Response::OK();
+ return Response::Success();
}
Response InspectorNetworkAgent::emulateNetworkConditions(
@@ -1494,13 +1529,13 @@ Response InspectorNetworkAgent::emulateNetworkConditions(
double upload_throughput,
Maybe<String> connection_type) {
if (!IsMainThread())
- return Response::Error("Not supported");
+ return Response::ServerError("Not supported");
WebConnectionType type = kWebConnectionTypeUnknown;
if (connection_type.isJust()) {
type = ToWebConnectionType(connection_type.fromJust());
if (type == kWebConnectionTypeUnknown)
- return Response::Error("Unknown connection type");
+ return Response::ServerError("Unknown connection type");
}
// TODO(dgozman): networkStateNotifier is per-process. It would be nice to
// have per-frame override instead.
@@ -1511,7 +1546,7 @@ Response InspectorNetworkAgent::emulateNetworkConditions(
} else {
GetNetworkStateNotifier().ClearOverride();
}
- return Response::OK();
+ return Response::Success();
}
Response InspectorNetworkAgent::setCacheDisabled(bool cache_disabled) {
@@ -1521,18 +1556,18 @@ Response InspectorNetworkAgent::setCacheDisabled(bool cache_disabled) {
cache_disabled_.Set(cache_disabled);
if (cache_disabled && IsMainThread())
GetMemoryCache()->EvictResources();
- return Response::OK();
+ return Response::Success();
}
Response InspectorNetworkAgent::setBypassServiceWorker(bool bypass) {
bypass_service_worker_.Set(bypass);
- return Response::OK();
+ return Response::Success();
}
Response InspectorNetworkAgent::setDataSizeLimitsForTest(int max_total,
int max_resource) {
resources_data_->SetResourcesDataSizeLimits(max_total, max_resource);
- return Response::OK();
+ return Response::Success();
}
Response InspectorNetworkAgent::getCertificate(
@@ -1551,10 +1586,10 @@ Response InspectorNetworkAgent::getCertificate(
->emplace_back(
Base64Encode(base::as_bytes(base::make_span(cert.Latin1()))));
}
- return Response::OK();
+ return Response::Success();
}
}
- return Response::OK();
+ return Response::Success();
}
void InspectorNetworkAgent::DidCommitLoad(LocalFrame* frame,
@@ -1592,17 +1627,18 @@ Response InspectorNetworkAgent::GetResponseBody(const String& request_id,
NetworkResourcesData::ResourceData const* resource_data =
resources_data_->Data(request_id);
if (!resource_data) {
- return Response::Error("No resource with given identifier found");
+ return Response::ServerError("No resource with given identifier found");
}
if (resource_data->HasContent()) {
*content = resource_data->Content();
*base64_encoded = resource_data->Base64Encoded();
- return Response::OK();
+ return Response::Success();
}
if (resource_data->IsContentEvicted()) {
- return Response::Error("Request content was evicted from inspector cache");
+ return Response::ServerError(
+ "Request content was evicted from inspector cache");
}
if (resource_data->Buffer() && !resource_data->TextEncodingName().IsNull()) {
@@ -1610,16 +1646,17 @@ Response InspectorNetworkAgent::GetResponseBody(const String& request_id,
resource_data->Buffer(), resource_data->MimeType(),
resource_data->TextEncodingName(), content, base64_encoded);
DCHECK(success);
- return Response::OK();
+ return Response::Success();
}
if (resource_data->CachedResource() &&
InspectorPageAgent::CachedResourceContent(resource_data->CachedResource(),
content, base64_encoded)) {
- return Response::OK();
+ return Response::Success();
}
- return Response::Error("No data found for resource with given identifier");
+ return Response::ServerError(
+ "No data found for resource with given identifier");
}
Response InspectorNetworkAgent::searchInResponseBody(
@@ -1633,7 +1670,7 @@ Response InspectorNetworkAgent::searchInResponseBody(
String content;
bool base64_encoded;
Response response = GetResponseBody(request_id, &content, &base64_encoded);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
auto results = v8_session_->searchInTextByLines(
@@ -1642,7 +1679,7 @@ Response InspectorNetworkAgent::searchInResponseBody(
*matches = std::make_unique<
protocol::Array<v8_inspector::protocol::Debugger::API::SearchMatch>>(
std::move(results));
- return Response::OK();
+ return Response::Success();
}
bool InspectorNetworkAgent::FetchResourceContent(Document* document,
@@ -1677,14 +1714,20 @@ String InspectorNetworkAgent::NavigationInitiatorInfo(LocalFrame* frame) {
return String();
auto it =
frame_navigation_initiator_map_.find(IdentifiersFactory::FrameId(frame));
- if (it != frame_navigation_initiator_map_.end())
- return it->value->toJSON();
- // For navigations, we limit async stack trace to depth 1 to avoid the
- // base::Value depth limits with Mojo serialization / parsing.
- // See http://crbug.com/809996.
- return BuildInitiatorObject(frame->GetDocument(), FetchInitiatorInfo(),
- /*max_async_depth=*/1)
- ->toJSON();
+ std::vector<uint8_t> cbor;
+ if (it != frame_navigation_initiator_map_.end()) {
+ it->value->AppendSerialized(&cbor);
+ } else {
+ // For navigations, we limit async stack trace to depth 1 to avoid the
+ // base::Value depth limits with Mojo serialization / parsing.
+ // See http://crbug.com/809996.
+ BuildInitiatorObject(frame->GetDocument(), FetchInitiatorInfo(),
+ /*max_async_depth=*/1)
+ ->AppendSerialized(&cbor);
+ }
+ std::vector<uint8_t> json;
+ ConvertCBORToJSON(SpanFrom(cbor), &json);
+ return String(reinterpret_cast<const char*>(json.data()), json.size());
}
InspectorNetworkAgent::InspectorNetworkAgent(
@@ -1694,8 +1737,9 @@ InspectorNetworkAgent::InspectorNetworkAgent(
: inspected_frames_(inspected_frames),
worker_global_scope_(worker_global_scope),
v8_session_(v8_session),
- resources_data_(NetworkResourcesData::Create(kDefaultTotalBufferSize,
- kDefaultResourceBufferSize)),
+ resources_data_(MakeGarbageCollected<NetworkResourcesData>(
+ kDefaultTotalBufferSize,
+ kDefaultResourceBufferSize)),
devtools_token_(worker_global_scope_
? worker_global_scope_->GetParentDevToolsToken()
: inspected_frames->Root()->GetDevToolsFrameToken()),
@@ -1725,20 +1769,32 @@ void InspectorNetworkAgent::getRequestPostData(
resources_data_->Data(request_id);
if (!resource_data) {
callback->sendFailure(
- Response::Error("No resource with given id was found"));
+ Response::ServerError("No resource with given id was found"));
return;
}
scoped_refptr<EncodedFormData> post_data = resource_data->PostData();
if (!post_data || post_data->IsEmpty()) {
callback->sendFailure(
- Response::Error("No post data available for the request"));
+ Response::ServerError("No post data available for the request"));
+ return;
+ }
+ ExecutionContext* context = GetTargetExecutionContext();
+ if (!context) {
+ callback->sendFailure(Response::InternalError());
return;
}
-
scoped_refptr<InspectorPostBodyParser> parser =
- base::MakeRefCounted<InspectorPostBodyParser>(std::move(callback));
+ base::MakeRefCounted<InspectorPostBodyParser>(
+ std::move(callback), context->GetTaskRunner(TaskType::kFileReading));
// TODO(crbug.com/810554): Extend protocol to fetch body parts separately
parser->Parse(post_data.get());
}
+ExecutionContext* InspectorNetworkAgent::GetTargetExecutionContext() const {
+ if (worker_global_scope_)
+ return worker_global_scope_;
+ DCHECK(inspected_frames_);
+ return inspected_frames_->Root()->DomWindow();
+}
+
} // namespace blink
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 dba8a6d4c3f..9217ce02aae 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void Restore() override;
@@ -150,7 +150,6 @@ class CORE_EXPORT InspectorNetworkAgent final
const AtomicString& method,
const KURL&,
bool async,
- EncodedFormData* form_data,
const HTTPHeaderMap& headers,
bool include_crendentials);
void DidFinishXHR(XMLHttpRequest*);
@@ -257,6 +256,7 @@ class CORE_EXPORT InspectorNetworkAgent final
bool CanGetResponseBodyBlob(const String& request_id);
void GetResponseBodyBlob(const String& request_id,
std::unique_ptr<GetResponseBodyCallback>);
+ ExecutionContext* GetTargetExecutionContext() const;
static std::unique_ptr<protocol::Network::Initiator> BuildInitiatorObject(
Document*,
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 876bf4560e5..ab44f6ddbd3 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
@@ -83,8 +83,12 @@
#include "third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/keyboard_codes.h"
+#include "third_party/inspector_protocol/crdtp/json.h"
#include "v8/include/v8.h"
+using crdtp::SpanFrom;
+using crdtp::json::ConvertCBORToJSON;
+
namespace blink {
using protocol::Maybe;
@@ -196,7 +200,7 @@ bool InspectTool::HideOnHideHighlight() {
return false;
}
-void InspectTool::Trace(blink::Visitor* visitor) {
+void InspectTool::Trace(Visitor* visitor) {
visitor->Trace(overlay_);
}
@@ -233,7 +237,7 @@ class InspectorOverlayAgent::InspectorPageOverlayDelegate final
("InspectorOverlay"));
RecordForeignLayer(graphics_context, debug_name_client,
DisplayItem::kForeignLayerDevToolsOverlay, layer_,
- FloatPoint(), PropertyTreeState::Root());
+ FloatPoint(), &PropertyTreeState::Root());
return;
}
@@ -285,13 +289,13 @@ class InspectorOverlayAgent::InspectorOverlayChromeClient final
InspectorOverlayAgent& overlay)
: client_(&client), overlay_(&overlay) {}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(client_);
visitor->Trace(overlay_);
EmptyChromeClient::Trace(visitor);
}
- void SetCursor(const Cursor& cursor, LocalFrame* local_root) override {
+ void SetCursor(const ui::Cursor& cursor, LocalFrame* local_root) override {
client_->SetCursorOverridden(false);
client_->SetCursor(cursor, overlay_->GetFrame());
client_->SetCursorOverridden(true);
@@ -344,7 +348,7 @@ InspectorOverlayAgent::~InspectorOverlayAgent() {
DCHECK(!overlay_page_);
}
-void InspectorOverlayAgent::Trace(blink::Visitor* visitor) {
+void InspectorOverlayAgent::Trace(Visitor* visitor) {
visitor->Trace(frame_impl_);
visitor->Trace(inspected_frames_);
visitor->Trace(overlay_page_);
@@ -376,7 +380,7 @@ void InspectorOverlayAgent::Dispose() {
Response InspectorOverlayAgent::enable() {
if (!dom_agent_->Enabled())
- return Response::Error("DOM should be enabled first");
+ return Response::ServerError("DOM should be enabled first");
enabled_.Set(true);
if (backend_node_id_to_inspect_) {
GetFrontend()->inspectNodeRequested(
@@ -384,7 +388,7 @@ Response InspectorOverlayAgent::enable() {
}
backend_node_id_to_inspect_ = 0;
SetNeedsUnbufferedInput(true);
- return Response::OK();
+ return Response::Success();
}
Response InspectorOverlayAgent::disable() {
@@ -413,125 +417,151 @@ Response InspectorOverlayAgent::disable() {
frame_resource_name_ = 0;
PickTheRightTool();
SetNeedsUnbufferedInput(false);
- return Response::OK();
+ return Response::Success();
}
Response InspectorOverlayAgent::setShowAdHighlights(bool show) {
show_ad_highlights_.Set(show);
frame_impl_->ViewImpl()->GetPage()->GetSettings().SetHighlightAds(show);
- return Response::OK();
+ return Response::Success();
}
Response InspectorOverlayAgent::setShowDebugBorders(bool show) {
show_debug_borders_.Set(show);
if (show) {
Response response = CompositingEnabled();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
}
WebFrameWidget* widget = frame_impl_->LocalRoot()->FrameWidget();
WebFrameWidgetBase* widget_impl = static_cast<WebFrameWidgetBase*>(widget);
// While a frame is being detached the inspector will shutdown and
// turn off debug overlays, but the WebFrameWidget is already gone.
- if (widget_impl)
- widget_impl->Client()->SetShowDebugBorders(show);
- return Response::OK();
+ if (widget_impl) {
+ cc::LayerTreeDebugState debug_state = widget_impl->GetLayerTreeDebugState();
+ if (show)
+ debug_state.show_debug_borders.set();
+ else
+ debug_state.show_debug_borders.reset();
+ widget_impl->SetLayerTreeDebugState(debug_state);
+ }
+ return Response::Success();
}
Response InspectorOverlayAgent::setShowFPSCounter(bool show) {
show_fps_counter_.Set(show);
if (show) {
Response response = CompositingEnabled();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
}
WebFrameWidget* widget = frame_impl_->LocalRoot()->FrameWidget();
WebFrameWidgetBase* widget_impl = static_cast<WebFrameWidgetBase*>(widget);
// While a frame is being detached the inspector will shutdown and
// turn off debug overlays, but the WebFrameWidget is already gone.
- if (widget_impl)
- widget_impl->Client()->SetShowFPSCounter(show);
- return Response::OK();
+ if (widget_impl) {
+ cc::LayerTreeDebugState debug_state = widget_impl->GetLayerTreeDebugState();
+ debug_state.show_fps_counter = show;
+ widget_impl->SetLayerTreeDebugState(debug_state);
+ }
+ return Response::Success();
}
Response InspectorOverlayAgent::setShowPaintRects(bool show) {
show_paint_rects_.Set(show);
if (show) {
Response response = CompositingEnabled();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
}
WebFrameWidget* widget = frame_impl_->LocalRoot()->FrameWidget();
WebFrameWidgetBase* widget_impl = static_cast<WebFrameWidgetBase*>(widget);
// While a frame is being detached the inspector will shutdown and
// turn off debug overlays, but the WebFrameWidget is already gone.
- if (widget_impl)
- widget_impl->Client()->SetShowPaintRects(show);
+ if (widget_impl) {
+ cc::LayerTreeDebugState debug_state = widget_impl->GetLayerTreeDebugState();
+ debug_state.show_paint_rects = show;
+ widget_impl->SetLayerTreeDebugState(debug_state);
+ }
if (!show && frame_impl_->GetFrameView())
frame_impl_->GetFrameView()->Invalidate();
- return Response::OK();
+ return Response::Success();
}
Response InspectorOverlayAgent::setShowLayoutShiftRegions(bool show) {
show_layout_shift_regions_.Set(show);
if (show) {
Response response = CompositingEnabled();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
}
WebFrameWidget* widget = frame_impl_->LocalRoot()->FrameWidget();
WebFrameWidgetBase* widget_impl = static_cast<WebFrameWidgetBase*>(widget);
// While a frame is being detached the inspector will shutdown and
// turn off debug overlays, but the WebFrameWidget is already gone.
- if (widget_impl)
- widget_impl->Client()->SetShowLayoutShiftRegions(show);
+ if (widget_impl) {
+ cc::LayerTreeDebugState debug_state = widget_impl->GetLayerTreeDebugState();
+ debug_state.show_layout_shift_regions = show;
+ widget_impl->SetLayerTreeDebugState(debug_state);
+ }
+
if (!show && frame_impl_->GetFrameView())
frame_impl_->GetFrameView()->Invalidate();
- return Response::OK();
+ return Response::Success();
}
Response InspectorOverlayAgent::setShowScrollBottleneckRects(bool show) {
show_scroll_bottleneck_rects_.Set(show);
if (show) {
Response response = CompositingEnabled();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
}
WebFrameWidget* widget = frame_impl_->LocalRoot()->FrameWidget();
WebFrameWidgetBase* widget_impl = static_cast<WebFrameWidgetBase*>(widget);
// While a frame is being detached the inspector will shutdown and
// turn off debug overlays, but the WebFrameWidget is already gone.
- if (widget_impl)
- widget_impl->Client()->SetShowScrollBottleneckRects(show);
- return Response::OK();
+ if (widget_impl) {
+ cc::LayerTreeDebugState debug_state = widget_impl->GetLayerTreeDebugState();
+ debug_state.show_touch_event_handler_rects = show;
+ debug_state.show_wheel_event_handler_rects = show;
+ debug_state.show_non_fast_scrollable_rects = show;
+ debug_state.show_main_thread_scrolling_reason_rects = show;
+ widget_impl->SetLayerTreeDebugState(debug_state);
+ }
+
+ return Response::Success();
}
Response InspectorOverlayAgent::setShowHitTestBorders(bool show) {
show_hit_test_borders_.Set(show);
if (show) {
Response response = CompositingEnabled();
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
}
WebFrameWidget* widget = frame_impl_->LocalRoot()->FrameWidget();
WebFrameWidgetBase* widget_impl = static_cast<WebFrameWidgetBase*>(widget);
// While a frame is being detached the inspector will shutdown and
// turn off debug overlays, but the WebFrameWidget is already gone.
- if (widget_impl)
- widget_impl->Client()->SetShowHitTestBorders(show);
- return Response::OK();
+ if (widget_impl) {
+ cc::LayerTreeDebugState debug_state = widget_impl->GetLayerTreeDebugState();
+ debug_state.show_hit_test_borders = show;
+ widget_impl->SetLayerTreeDebugState(debug_state);
+ }
+ return Response::Success();
}
Response InspectorOverlayAgent::setShowViewportSizeOnResize(bool show) {
show_size_on_resize_.Set(show);
- return Response::OK();
+ return Response::Success();
}
Response InspectorOverlayAgent::setPausedInDebuggerMessage(
Maybe<String> message) {
paused_in_debugger_message_.Set(message.fromMaybe(String()));
PickTheRightTool();
- return Response::OK();
+ return Response::Success();
}
Response InspectorOverlayAgent::highlightRect(
@@ -546,7 +576,7 @@ Response InspectorOverlayAgent::highlightRect(
SetInspectTool(MakeGarbageCollected<QuadHighlightTool>(
std::move(quad), InspectorDOMAgent::ParseColor(color.fromMaybe(nullptr)),
InspectorDOMAgent::ParseColor(outline_color.fromMaybe(nullptr))));
- return Response::OK();
+ return Response::Success();
}
Response InspectorOverlayAgent::highlightQuad(
@@ -555,11 +585,11 @@ Response InspectorOverlayAgent::highlightQuad(
Maybe<protocol::DOM::RGBA> outline_color) {
std::unique_ptr<FloatQuad> quad = std::make_unique<FloatQuad>();
if (!ParseQuad(std::move(quad_array), quad.get()))
- return Response::Error("Invalid Quad format");
+ return Response::ServerError("Invalid Quad format");
SetInspectTool(MakeGarbageCollected<QuadHighlightTool>(
std::move(quad), InspectorDOMAgent::ParseColor(color.fromMaybe(nullptr)),
InspectorDOMAgent::ParseColor(outline_color.fromMaybe(nullptr))));
- return Response::OK();
+ return Response::Success();
}
Response InspectorOverlayAgent::highlightNode(
@@ -572,18 +602,18 @@ Response InspectorOverlayAgent::highlightNode(
Node* node = nullptr;
Response response =
dom_agent_->AssertNode(node_id, backend_node_id, object_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
std::unique_ptr<InspectorHighlightConfig> highlight_config;
response = HighlightConfigFromInspectorObject(
std::move(highlight_inspector_object), &highlight_config);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
SetInspectTool(MakeGarbageCollected<NodeHighlightTool>(
node, selector_list.fromMaybe(String()), std::move(highlight_config)));
- return Response::OK();
+ return Response::Success();
}
Response InspectorOverlayAgent::highlightFrame(
@@ -594,7 +624,7 @@ Response InspectorOverlayAgent::highlightFrame(
IdentifiersFactory::FrameById(inspected_frames_, frame_id);
// FIXME: Inspector doesn't currently work cross process.
if (!frame)
- return Response::Error("Invalid frame id");
+ return Response::ServerError("Invalid frame id");
if (frame->DeprecatedLocalOwner()) {
std::unique_ptr<InspectorHighlightConfig> highlight_config =
std::make_unique<InspectorHighlightConfig>();
@@ -609,13 +639,13 @@ Response InspectorOverlayAgent::highlightFrame(
} else {
PickTheRightTool();
}
- return Response::OK();
+ return Response::Success();
}
Response InspectorOverlayAgent::hideHighlight() {
if (inspect_tool_ && inspect_tool_->HideOnHideHighlight())
PickTheRightTool();
- return Response::OK();
+ return Response::Success();
}
Response InspectorOverlayAgent::getHighlightObjectForTest(
@@ -625,7 +655,7 @@ Response InspectorOverlayAgent::getHighlightObjectForTest(
std::unique_ptr<protocol::DictionaryValue>* result) {
Node* node = nullptr;
Response response = dom_agent_->AssertNode(node_id, node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
bool is_locked_ancestor = false;
@@ -644,7 +674,7 @@ Response InspectorOverlayAgent::getHighlightObjectForTest(
include_distance.fromMaybe(false),
is_locked_ancestor);
*result = highlight.AsProtocolValue();
- return Response::OK();
+ return Response::Success();
}
void InspectorOverlayAgent::UpdatePrePaint() {
@@ -689,7 +719,8 @@ WebInputEventResult InspectorOverlayAgent::HandleInputEvent(
if (input_event.GetType() == WebInputEvent::kKeyUp &&
swallow_next_escape_up_) {
- auto keyboard_event = static_cast<const WebKeyboardEvent&>(input_event);
+ const auto& keyboard_event =
+ static_cast<const WebKeyboardEvent&>(input_event);
if (keyboard_event.windows_key_code == VKEY_ESCAPE) {
swallow_next_escape_up_ = false;
return WebInputEventResult::kHandledSuppressed;
@@ -814,7 +845,7 @@ void InspectorOverlayAgent::PaintOverlayPage() {
inspect_tool_->Draw(WindowToViewportScale());
OverlayMainFrame()->View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kOther);
+ DocumentUpdateReason::kInspector);
}
static std::unique_ptr<protocol::DictionaryValue> BuildObjectForSize(
@@ -971,10 +1002,14 @@ void InspectorOverlayAgent::EvaluateInOverlay(const String& method,
std::unique_ptr<protocol::ListValue> command = protocol::ListValue::create();
command->pushValue(protocol::StringValue::create(method));
command->pushValue(protocol::StringValue::create(argument));
+ std::vector<uint8_t> json;
+ ConvertCBORToJSON(SpanFrom(command->Serialize()), &json);
To<LocalFrame>(OverlayMainFrame())
->GetScriptController()
.ExecuteScriptInMainWorld(
- "dispatch(" + command->toJSONString() + ")",
+ "dispatch(" +
+ String(reinterpret_cast<const char*>(json.data()), json.size()) +
+ ")",
ScriptSourceLocationType::kInspector,
ScriptController::kExecuteScriptWhenScriptsDisabled);
}
@@ -986,10 +1021,14 @@ void InspectorOverlayAgent::EvaluateInOverlay(
std::unique_ptr<protocol::ListValue> command = protocol::ListValue::create();
command->pushValue(protocol::StringValue::create(method));
command->pushValue(std::move(argument));
+ std::vector<uint8_t> json;
+ ConvertCBORToJSON(SpanFrom(command->Serialize()), &json);
To<LocalFrame>(OverlayMainFrame())
->GetScriptController()
.ExecuteScriptInMainWorld(
- "dispatch(" + command->toJSONString() + ")",
+ "dispatch(" +
+ String(reinterpret_cast<const char*>(json.data()), json.size()) +
+ ")",
ScriptSourceLocationType::kInspector,
ScriptController::kExecuteScriptWhenScriptsDisabled);
}
@@ -1044,8 +1083,8 @@ Response InspectorOverlayAgent::CompositingEnabled() {
->GetPage()
->GetSettings()
.GetAcceleratedCompositingEnabled())
- return Response::Error("Compositing mode is not supported");
- return Response::OK();
+ return Response::ServerError("Compositing mode is not supported");
+ return Response::Success();
}
bool InspectorOverlayAgent::InSomeInspectMode() {
@@ -1080,8 +1119,8 @@ Response InspectorOverlayAgent::setInspectMode(
mode != protocol::Overlay::InspectModeEnum::SearchForUAShadowDOM &&
mode != protocol::Overlay::InspectModeEnum::CaptureAreaScreenshot &&
mode != protocol::Overlay::InspectModeEnum::ShowDistances) {
- return Response::Error(
- String("Unknown mode \"" + mode + "\" was provided."));
+ return Response::ServerError(
+ String("Unknown mode \"" + mode + "\" was provided.").Utf8());
}
std::vector<uint8_t> serialized_config;
@@ -1091,13 +1130,13 @@ Response InspectorOverlayAgent::setInspectMode(
std::unique_ptr<InspectorHighlightConfig> config;
Response response = HighlightConfigFromInspectorObject(
std::move(highlight_inspector_object), &config);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
inspect_mode_.Set(mode);
inspect_mode_protocol_config_.Set(serialized_config);
PickTheRightTool();
- return Response::OK();
+ return Response::Success();
}
void InspectorOverlayAgent::PickTheRightTool() {
@@ -1157,13 +1196,13 @@ Response InspectorOverlayAgent::HighlightConfigFromInspectorObject(
Maybe<protocol::Overlay::HighlightConfig> highlight_inspector_object,
std::unique_ptr<InspectorHighlightConfig>* out_config) {
if (!highlight_inspector_object.isJust()) {
- return Response::Error(
+ return Response::ServerError(
"Internal error: highlight configuration parameter is missing");
}
protocol::Overlay::HighlightConfig* config =
highlight_inspector_object.fromJust();
*out_config = InspectorOverlayAgent::ToHighlightConfig(config);
- return Response::OK();
+ return Response::Success();
}
// static
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 f03de4b7e99..a81f6463f17 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
@@ -33,7 +33,7 @@
#include <memory>
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/public/platform/web_input_event.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/public/platform/web_input_event_result.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
@@ -92,7 +92,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(blink::Visitor* visitor);
+ virtual void Trace(Visitor* visitor);
virtual void Dispose() {}
virtual bool HideOnHideHighlight();
@@ -115,7 +115,7 @@ class CORE_EXPORT InspectorOverlayAgent final
v8_inspector::V8InspectorSession*,
InspectorDOMAgent*);
~InspectorOverlayAgent() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// protocol::Dispatcher::OverlayCommandHandler implementation.
protocol::Response enable() override;
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 2eedfacd5d4..26942927dbd 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(blink::Visitor* visitor) {
+void InspectorOverlayHost::Trace(Visitor* visitor) {
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 b57c6caa656..96e86efc9d8 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 6167472566e..1ff765e6e0e 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
@@ -42,6 +42,7 @@
#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"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
@@ -91,9 +92,10 @@ using protocol::Response;
namespace {
String ClientNavigationReasonToProtocol(ClientNavigationReason reason) {
- using ReasonEnum =
- protocol::Page::FrameScheduledNavigationNotification::ReasonEnum;
+ namespace ReasonEnum = protocol::Page::ClientNavigationReasonEnum;
switch (reason) {
+ case ClientNavigationReason::kAnchorClick:
+ return ReasonEnum::AnchorClick;
case ClientNavigationReason::kFormSubmissionGet:
return ReasonEnum::FormSubmissionGet;
case ClientNavigationReason::kFormSubmissionPost:
@@ -219,7 +221,7 @@ static std::unique_ptr<TextResourceDecoder> CreateResourceTextDecoder(
options.SetUseLenientXMLDecoding();
return std::make_unique<TextResourceDecoder>(options);
}
- if (DeprecatedEqualIgnoringCase(mime_type, "text/html")) {
+ if (EqualIgnoringASCIICase(mime_type, "text/html")) {
return std::make_unique<TextResourceDecoder>(TextResourceDecoderOptions(
TextResourceDecoderOptions::kHTMLContent, UTF8Encoding()));
}
@@ -520,7 +522,7 @@ void InspectorPageAgent::Restore() {
Response InspectorPageAgent::enable() {
enabled_.Set(true);
instrumenting_agents_->AddInspectorPageAgent(this);
- return Response::OK();
+ return Response::Success();
}
Response InspectorPageAgent::disable() {
@@ -533,7 +535,7 @@ Response InspectorPageAgent::disable() {
stopScreencast();
- return Response::OK();
+ return Response::Success();
}
Response InspectorPageAgent::addScriptToEvaluateOnNewDocument(
@@ -553,16 +555,16 @@ Response InspectorPageAgent::addScriptToEvaluateOnNewDocument(
scripts_to_evaluate_on_load_.Set(*identifier, source);
worlds_to_evaluate_on_load_.Set(*identifier, world_name.fromMaybe(""));
- return Response::OK();
+ return Response::Success();
}
Response InspectorPageAgent::removeScriptToEvaluateOnNewDocument(
const String& identifier) {
if (scripts_to_evaluate_on_load_.Get(identifier).IsNull())
- return Response::Error("Script not found");
+ return Response::ServerError("Script not found");
scripts_to_evaluate_on_load_.Clear(identifier);
worlds_to_evaluate_on_load_.Clear(identifier);
- return Response::OK();
+ return Response::Success();
}
Response InspectorPageAgent::addScriptToEvaluateOnLoad(const String& source,
@@ -579,7 +581,7 @@ Response InspectorPageAgent::removeScriptToEvaluateOnLoad(
Response InspectorPageAgent::setLifecycleEventsEnabled(bool enabled) {
lifecycle_events_enabled_.Set(enabled);
if (!enabled)
- return Response::OK();
+ return Response::Success();
for (LocalFrame* frame : *inspected_frames_) {
Document* document = frame->GetDocument();
@@ -622,11 +624,11 @@ Response InspectorPageAgent::setLifecycleEventsEnabled(bool enabled) {
}
}
- return Response::OK();
+ return Response::Success();
}
Response InspectorPageAgent::setAdBlockingEnabled(bool enable) {
- return Response::OK();
+ return Response::Success();
}
Response InspectorPageAgent::reload(
@@ -635,11 +637,11 @@ Response InspectorPageAgent::reload(
pending_script_to_evaluate_on_load_once_ =
optional_script_to_evaluate_on_load.fromMaybe("");
v8_session_->setSkipAllPauses(true);
- return Response::OK();
+ return Response::Success();
}
Response InspectorPageAgent::stopLoading() {
- return Response::OK();
+ return Response::Success();
}
static void CachedResourcesForDocument(Document* document,
@@ -695,13 +697,13 @@ static HeapVector<Member<Resource>> CachedResourcesForFrame(LocalFrame* frame,
Response InspectorPageAgent::getResourceTree(
std::unique_ptr<protocol::Page::FrameResourceTree>* object) {
*object = BuildObjectForResourceTree(inspected_frames_->Root());
- return Response::OK();
+ return Response::Success();
}
Response InspectorPageAgent::getFrameTree(
std::unique_ptr<protocol::Page::FrameTree>* object) {
*object = BuildObjectForFrameTree(inspected_frames_->Root());
- return Response::OK();
+ return Response::Success();
}
void InspectorPageAgent::GetResourceContentAfterResourcesContentLoaded(
@@ -711,17 +713,19 @@ void InspectorPageAgent::GetResourceContentAfterResourcesContentLoaded(
LocalFrame* frame =
IdentifiersFactory::FrameById(inspected_frames_, frame_id);
if (!frame) {
- callback->sendFailure(Response::Error("No frame for given id found"));
+ callback->sendFailure(Response::ServerError("No frame for given id found"));
return;
}
String content;
bool base64_encoded;
if (InspectorPageAgent::CachedResourceContent(
CachedResource(frame, KURL(url), inspector_resource_content_loader_),
- &content, &base64_encoded))
+ &content, &base64_encoded)) {
callback->sendSuccess(content, base64_encoded);
- else
- callback->sendFailure(Response::Error("No resource with given URL found"));
+ } else {
+ callback->sendFailure(
+ Response::ServerError("No resource with given URL found"));
+ }
}
void InspectorPageAgent::getResourceContent(
@@ -729,7 +733,7 @@ void InspectorPageAgent::getResourceContent(
const String& url,
std::unique_ptr<GetResourceContentCallback> callback) {
if (!enabled_.Get()) {
- callback->sendFailure(Response::Error("Agent is not enabled."));
+ callback->sendFailure(Response::ServerError("Agent is not enabled."));
return;
}
inspector_resource_content_loader_->EnsureResourcesContentLoaded(
@@ -750,7 +754,7 @@ void InspectorPageAgent::SearchContentAfterResourcesContentLoaded(
LocalFrame* frame =
IdentifiersFactory::FrameById(inspected_frames_, frame_id);
if (!frame) {
- callback->sendFailure(Response::Error("No frame for given id found"));
+ callback->sendFailure(Response::ServerError("No frame for given id found"));
return;
}
String content;
@@ -758,7 +762,8 @@ void InspectorPageAgent::SearchContentAfterResourcesContentLoaded(
if (!InspectorPageAgent::CachedResourceContent(
CachedResource(frame, KURL(url), inspector_resource_content_loader_),
&content, &base64_encoded)) {
- callback->sendFailure(Response::Error("No resource with given URL found"));
+ callback->sendFailure(
+ Response::ServerError("No resource with given URL found"));
return;
}
@@ -779,7 +784,7 @@ void InspectorPageAgent::searchInResource(
Maybe<bool> optional_is_regex,
std::unique_ptr<SearchInResourceCallback> callback) {
if (!enabled_.Get()) {
- callback->sendFailure(Response::Error("Agent is not enabled."));
+ callback->sendFailure(Response::ServerError("Agent is not enabled."));
return;
}
inspector_resource_content_loader_->EnsureResourcesContentLoaded(
@@ -795,7 +800,7 @@ Response InspectorPageAgent::setBypassCSP(bool enabled) {
LocalFrame* frame = inspected_frames_->Root();
frame->GetSettings()->SetBypassCSP(enabled);
bypass_csp_enabled_.Set(enabled);
- return Response::OK();
+ return Response::Success();
}
Response InspectorPageAgent::setDocumentContent(const String& frame_id,
@@ -803,13 +808,13 @@ Response InspectorPageAgent::setDocumentContent(const String& frame_id,
LocalFrame* frame =
IdentifiersFactory::FrameById(inspected_frames_, frame_id);
if (!frame)
- return Response::Error("No frame for given id found");
+ return Response::ServerError("No frame for given id found");
Document* document = frame->GetDocument();
if (!document)
- return Response::Error("No Document instance to set HTML for");
+ return Response::ServerError("No Document instance to set HTML for");
document->SetContent(html);
- return Response::OK();
+ return Response::Success();
}
void InspectorPageAgent::DidNavigateWithinDocument(LocalFrame* frame) {
@@ -931,10 +936,12 @@ bool InspectorPageAgent::ScreencastEnabled() {
void InspectorPageAgent::FrameStartedLoading(LocalFrame* frame) {
GetFrontend()->frameStartedLoading(IdentifiersFactory::FrameId(frame));
+ GetFrontend()->flush();
}
void InspectorPageAgent::FrameStoppedLoading(LocalFrame* frame) {
GetFrontend()->frameStoppedLoading(IdentifiersFactory::FrameId(frame));
+ GetFrontend()->flush();
}
void InspectorPageAgent::FrameRequestedNavigation(
@@ -944,6 +951,7 @@ void InspectorPageAgent::FrameRequestedNavigation(
GetFrontend()->frameRequestedNavigation(
IdentifiersFactory::FrameId(target_frame),
ClientNavigationReasonToProtocol(reason), url.GetString());
+ GetFrontend()->flush();
}
void InspectorPageAgent::FrameScheduledNavigation(
@@ -954,11 +962,13 @@ void InspectorPageAgent::FrameScheduledNavigation(
GetFrontend()->frameScheduledNavigation(
IdentifiersFactory::FrameId(frame), delay.InSecondsF(),
ClientNavigationReasonToProtocol(reason), url.GetString());
+ GetFrontend()->flush();
}
void InspectorPageAgent::FrameClearedScheduledNavigation(LocalFrame* frame) {
GetFrontend()->frameClearedScheduledNavigation(
IdentifiersFactory::FrameId(frame));
+ GetFrontend()->flush();
}
void InspectorPageAgent::WillRunJavaScriptDialog() {
@@ -991,6 +1001,7 @@ void InspectorPageAgent::LifecycleEvent(LocalFrame* frame,
GetFrontend()->lifecycleEvent(IdentifiersFactory::FrameId(frame),
IdentifiersFactory::LoaderId(loader), name,
timestamp);
+ GetFrontend()->flush();
}
void InspectorPageAgent::PaintTiming(Document* document,
@@ -1027,6 +1038,7 @@ void InspectorPageAgent::WindowOpen(Document* document,
GetFrontend()->windowOpen(completed_url.GetString(), window_name,
GetEnabledWindowFeatures(window_features),
user_gesture);
+ GetFrontend()->flush();
}
std::unique_ptr<protocol::Page::Frame> InspectorPageAgent::BuildObjectForFrame(
@@ -1150,12 +1162,12 @@ Response InspectorPageAgent::startScreencast(Maybe<String> format,
Maybe<int> max_height,
Maybe<int> every_nth_frame) {
screencast_enabled_.Set(true);
- return Response::OK();
+ return Response::Success();
}
Response InspectorPageAgent::stopScreencast() {
screencast_enabled_.Set(false);
- return Response::OK();
+ return Response::Success();
}
Response InspectorPageAgent::getLayoutMetrics(
@@ -1165,7 +1177,8 @@ Response InspectorPageAgent::getLayoutMetrics(
LocalFrame* main_frame = inspected_frames_->Root();
VisualViewport& visual_viewport = main_frame->GetPage()->GetVisualViewport();
- main_frame->GetDocument()->UpdateStyleAndLayout();
+ main_frame->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kInspector);
IntRect visible_contents =
main_frame->View()->LayoutViewport()->VisibleContentRect();
@@ -1211,7 +1224,7 @@ Response InspectorPageAgent::getLayoutMetrics(
.setScale(scale)
.setZoom(page_zoom_factor)
.build();
- return Response::OK();
+ return Response::Success();
}
protocol::Response InspectorPageAgent::createIsolatedWorld(
@@ -1222,19 +1235,19 @@ protocol::Response InspectorPageAgent::createIsolatedWorld(
LocalFrame* frame =
IdentifiersFactory::FrameById(inspected_frames_, frame_id);
if (!frame)
- return Response::Error("No frame for given id found");
+ return Response::ServerError("No frame for given id found");
scoped_refptr<DOMWrapperWorld> world = EnsureDOMWrapperWorld(
frame, world_name.fromMaybe(""), grant_universal_access.fromMaybe(false));
if (!world)
- return Response::Error("Could not create isolated world");
+ return Response::ServerError("Could not create isolated world");
LocalWindowProxy* isolated_world_window_proxy =
frame->GetScriptController().WindowProxy(*world);
v8::HandleScope handle_scope(V8PerIsolateData::MainThreadIsolate());
*execution_context_id = v8_inspector::V8ContextInfo::executionContextId(
isolated_world_window_proxy->ContextIfInitialized());
- return Response::OK();
+ return Response::Success();
}
Response InspectorPageAgent::setFontFamilies(
@@ -1276,7 +1289,7 @@ Response InspectorPageAgent::setFontFamilies(
settings->NotifyGenericFontFamilyChange();
}
- return Response::OK();
+ return Response::Success();
}
Response InspectorPageAgent::setFontSizes(
@@ -1294,7 +1307,7 @@ Response InspectorPageAgent::setFontSizes(
}
}
- return Response::OK();
+ return Response::Success();
}
void InspectorPageAgent::ConsumeCompilationCache(
@@ -1356,46 +1369,46 @@ void InspectorPageAgent::FileChooserOpened(LocalFrame* frame,
Response InspectorPageAgent::setProduceCompilationCache(bool enabled) {
produce_compilation_cache_.Set(enabled);
- return Response::OK();
+ return Response::Success();
}
Response InspectorPageAgent::addCompilationCache(const String& url,
const protocol::Binary& data) {
compilation_cache_.Set(url, data);
- return Response::OK();
+ return Response::Success();
}
Response InspectorPageAgent::clearCompilationCache() {
compilation_cache_.clear();
- return Response::OK();
+ return Response::Success();
}
Response InspectorPageAgent::waitForDebugger() {
client_->WaitForDebugger();
- return Response::OK();
+ return Response::Success();
}
Response InspectorPageAgent::setInterceptFileChooserDialog(bool enabled) {
intercept_file_chooser_ = enabled;
- return Response::OK();
+ return Response::Success();
}
Response InspectorPageAgent::generateTestReport(const String& message,
Maybe<String> group) {
- Document* document = inspected_frames_->Root()->GetDocument();
+ LocalDOMWindow* window = inspected_frames_->Root()->DomWindow();
// Construct the test report.
TestReportBody* body = MakeGarbageCollected<TestReportBody>(message);
- Report* report =
- MakeGarbageCollected<Report>("test", document->Url().GetString(), body);
+ Report* report = MakeGarbageCollected<Report>(
+ "test", window->document()->Url().GetString(), body);
// Send the test report to any ReportingObservers.
- ReportingContext::From(document)->QueueReport(report);
+ ReportingContext::From(window)->QueueReport(report);
- return Response::OK();
+ return Response::Success();
}
-void InspectorPageAgent::Trace(blink::Visitor* visitor) {
+void InspectorPageAgent::Trace(Visitor* visitor) {
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 1f825f72b55..fa1e022ce6b 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
@@ -217,7 +217,7 @@ class CORE_EXPORT InspectorPageAgent final
void Restore() override;
bool ScreencastEnabled();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 716a15d1698..cff050c6895 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
@@ -20,6 +20,8 @@
namespace blink {
+namespace TimeDomain = protocol::Performance::SetTimeDomain::TimeDomainEnum;
+
using protocol::Response;
namespace {
@@ -57,24 +59,38 @@ void InspectorPerformanceAgent::InnerEnable() {
task_start_ticks_ = base::TimeTicks();
script_start_ticks_ = base::TimeTicks();
v8compile_start_ticks_ = base::TimeTicks();
+ devtools_command_start_ticks_ = base::TimeTicks();
thread_time_origin_ = GetThreadTimeNow();
}
-protocol::Response InspectorPerformanceAgent::enable() {
- if (enabled_.Get())
- return Response::OK();
+protocol::Response InspectorPerformanceAgent::enable(
+ Maybe<String> optional_time_domain) {
+ String time_domain = optional_time_domain.fromMaybe(TimeDomain::TimeTicks);
+ if (enabled_.Get()) {
+ if (!HasTimeDomain(time_domain)) {
+ return Response::ServerError(
+ "Cannot change time domain while performance metrics collection is "
+ "enabled.");
+ }
+ return Response::Success();
+ }
+
+ Response response = InnerSetTimeDomain(time_domain);
+ if (!response.IsSuccess())
+ return response;
+
enabled_.Set(true);
InnerEnable();
- return Response::OK();
+ return Response::Success();
}
protocol::Response InspectorPerformanceAgent::disable() {
if (!enabled_.Get())
- return Response::OK();
+ return Response::Success();
enabled_.Clear();
instrumenting_agents_->RemoveInspectorPerformanceAgent(this);
Thread::Current()->RemoveTaskTimeObserver(this);
- return Response::OK();
+ return Response::Success();
}
namespace {
@@ -88,28 +104,19 @@ void AppendMetric(protocol::Array<protocol::Performance::Metric>* container,
}
} // namespace
+// TODO(crbug.com/1056306): remove this redundant API.
Response InspectorPerformanceAgent::setTimeDomain(const String& time_domain) {
if (enabled_.Get()) {
- return Response::Error(
+ return Response::ServerError(
"Cannot set time domain while performance metrics collection"
" is enabled.");
}
- if (time_domain ==
- protocol::Performance::SetTimeDomain::TimeDomainEnum::TimeTicks) {
- use_thread_ticks_.Clear();
- } else if (time_domain == protocol::Performance::SetTimeDomain::
- TimeDomainEnum::ThreadTicks) {
- if (!base::ThreadTicks::IsSupported()) {
- return Response::Error("Thread time is not supported on this platform.");
- }
- base::ThreadTicks::WaitUntilInitialized();
- use_thread_ticks_.Set(true);
- } else {
- return Response::Error("Invalid time domain specification.");
- }
+ // Prevent this devtools command duration from being collected to avoid
+ // using start and end time from different time domains.
+ devtools_command_start_ticks_ = base::TimeTicks();
- return Response::OK();
+ return InnerSetTimeDomain(time_domain);
}
base::TimeTicks InspectorPerformanceAgent::GetTimeTicksNow() {
@@ -123,13 +130,40 @@ base::TimeTicks InspectorPerformanceAgent::GetThreadTimeNow() {
base::ThreadTicks::Now().since_origin().InMicroseconds());
}
+bool InspectorPerformanceAgent::HasTimeDomain(const String& time_domain) {
+ return use_thread_ticks_.Get() ? time_domain == TimeDomain::ThreadTicks
+ : time_domain == TimeDomain::TimeTicks;
+}
+
+Response InspectorPerformanceAgent::InnerSetTimeDomain(
+ const String& time_domain) {
+ DCHECK(!enabled_.Get());
+
+ if (time_domain == TimeDomain::TimeTicks) {
+ use_thread_ticks_.Clear();
+ return Response::Success();
+ }
+
+ if (time_domain == TimeDomain::ThreadTicks) {
+ if (!base::ThreadTicks::IsSupported()) {
+ return Response::ServerError(
+ "Thread time is not supported on this platform.");
+ }
+ base::ThreadTicks::WaitUntilInitialized();
+ use_thread_ticks_.Set(true);
+ return Response::Success();
+ }
+
+ return Response::ServerError("Invalid time domain specification.");
+}
+
Response InspectorPerformanceAgent::getMetrics(
std::unique_ptr<protocol::Array<protocol::Performance::Metric>>*
out_result) {
if (!enabled_.Get()) {
*out_result =
std::make_unique<protocol::Array<protocol::Performance::Metric>>();
- return Response::OK();
+ return Response::Success();
}
auto result =
@@ -154,6 +188,12 @@ Response InspectorPerformanceAgent::getMetrics(
AppendMetric(result.get(), "RecalcStyleDuration",
recalc_style_duration_.InSecondsF());
+ base::TimeDelta devtools_command_duration = devtools_command_duration_;
+ if (!devtools_command_start_ticks_.is_null())
+ devtools_command_duration += now - devtools_command_start_ticks_;
+ AppendMetric(result.get(), "DevToolsCommandDuration",
+ devtools_command_duration.InSecondsF());
+
base::TimeDelta script_duration = script_duration_;
if (!script_start_ticks_.is_null())
script_duration += now - script_start_ticks_;
@@ -171,9 +211,10 @@ Response InspectorPerformanceAgent::getMetrics(
AppendMetric(result.get(), "TaskDuration", task_duration.InSecondsF());
// Compute task time not accounted for by other metrics.
- base::TimeDelta other_tasks_duration =
- task_duration -
- (script_duration + recalc_style_duration_ + layout_duration_);
+ base::TimeDelta known_tasks_duration =
+ script_duration + v8compile_duration + recalc_style_duration_ +
+ layout_duration_ + devtools_command_duration;
+ base::TimeDelta other_tasks_duration = task_duration - known_tasks_duration;
AppendMetric(result.get(), "TaskOtherDuration",
other_tasks_duration.InSecondsF());
@@ -209,7 +250,7 @@ Response InspectorPerformanceAgent::getMetrics(
}
*out_result = std::move(result);
- return Response::OK();
+ return Response::Success();
}
void InspectorPerformanceAgent::ConsoleTimeStamp(const String& title) {
@@ -228,8 +269,13 @@ void InspectorPerformanceAgent::ScriptStarts() {
void InspectorPerformanceAgent::ScriptEnds() {
if (--script_call_depth_)
return;
- script_duration_ += GetTimeTicksNow() - script_start_ticks_;
+ base::TimeDelta delta = GetTimeTicksNow() - script_start_ticks_;
+ script_duration_ += delta;
script_start_ticks_ = base::TimeTicks();
+
+ // Exclude nested script execution from devtools command duration.
+ if (!devtools_command_start_ticks_.is_null())
+ devtools_command_start_ticks_ += delta;
}
void InspectorPerformanceAgent::Will(const probe::CallFunction& probe) {
@@ -253,16 +299,22 @@ void InspectorPerformanceAgent::Will(const probe::RecalculateStyle& probe) {
}
void InspectorPerformanceAgent::Did(const probe::RecalculateStyle& probe) {
+ if (recalc_style_start_ticks_.is_null())
+ return;
+
base::TimeDelta delta = GetTimeTicksNow() - recalc_style_start_ticks_;
recalc_style_duration_ += delta;
recalc_style_count_++;
recalc_style_start_ticks_ = base::TimeTicks();
- // Exclude nested style re-calculations from script and layout duration.
+ // Exclude nested style re-calculations from script, layout and devtools
+ // command durations.
if (!script_start_ticks_.is_null())
script_start_ticks_ += delta;
if (!layout_start_ticks_.is_null())
layout_start_ticks_ += delta;
+ if (!devtools_command_start_ticks_.is_null())
+ devtools_command_start_ticks_ += delta;
}
void InspectorPerformanceAgent::Will(const probe::UpdateLayout& probe) {
@@ -271,19 +323,22 @@ void InspectorPerformanceAgent::Will(const probe::UpdateLayout& probe) {
}
void InspectorPerformanceAgent::Did(const probe::UpdateLayout& probe) {
- if (--layout_depth_)
+ if (--layout_depth_ || layout_start_ticks_.is_null())
return;
+
base::TimeDelta delta = GetTimeTicksNow() - layout_start_ticks_;
layout_duration_ += delta;
layout_count_++;
layout_start_ticks_ = base::TimeTicks();
- // Exclude nested layout update from script and style re-calculations
- // duration.
+ // Exclude nested layout update from script, style re-calculations and
+ // devtools command durations.
if (!script_start_ticks_.is_null())
script_start_ticks_ += delta;
if (!recalc_style_start_ticks_.is_null())
recalc_style_start_ticks_ += delta;
+ if (!devtools_command_start_ticks_.is_null())
+ devtools_command_start_ticks_ += delta;
}
void InspectorPerformanceAgent::Will(const probe::V8Compile& probe) {
@@ -292,8 +347,29 @@ void InspectorPerformanceAgent::Will(const probe::V8Compile& probe) {
}
void InspectorPerformanceAgent::Did(const probe::V8Compile& probe) {
- v8compile_duration_ += GetTimeTicksNow() - v8compile_start_ticks_;
+ if (v8compile_start_ticks_.is_null())
+ return;
+
+ base::TimeDelta delta = GetTimeTicksNow() - v8compile_start_ticks_;
+ v8compile_duration_ += delta;
v8compile_start_ticks_ = base::TimeTicks();
+
+ // Exclude nested script compilation from devtools command duration.
+ if (!devtools_command_start_ticks_.is_null())
+ devtools_command_start_ticks_ += delta;
+}
+
+void InspectorPerformanceAgent::WillStartDebuggerTask() {
+ devtools_command_start_ticks_ = GetTimeTicksNow();
+}
+
+void InspectorPerformanceAgent::DidFinishDebuggerTask() {
+ if (devtools_command_start_ticks_.is_null())
+ return;
+
+ devtools_command_duration_ +=
+ GetTimeTicksNow() - devtools_command_start_ticks_;
+ devtools_command_start_ticks_ = base::TimeTicks();
}
// Will/DidProcessTask() ignore caller provided times to ensure time domain
@@ -304,12 +380,14 @@ void InspectorPerformanceAgent::WillProcessTask(base::TimeTicks start_time) {
void InspectorPerformanceAgent::DidProcessTask(base::TimeTicks start_time,
base::TimeTicks end_time) {
- if (!task_start_ticks_.is_null())
- task_duration_ += GetTimeTicksNow() - task_start_ticks_;
+ if (task_start_ticks_.is_null())
+ return;
+
+ task_duration_ += GetTimeTicksNow() - task_start_ticks_;
task_start_ticks_ = base::TimeTicks();
}
-void InspectorPerformanceAgent::Trace(blink::Visitor* visitor) {
+void InspectorPerformanceAgent::Trace(Visitor* visitor) {
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 17a34b40579..e8d399c752b 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
@@ -25,11 +25,13 @@ class UpdateLayout;
class V8Compile;
} // namespace probe
+using blink::protocol::Maybe;
+
class CORE_EXPORT InspectorPerformanceAgent final
: public InspectorBaseAgent<protocol::Performance::Metainfo>,
public base::sequence_manager::TaskTimeObserver {
public:
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
explicit InspectorPerformanceAgent(InspectedFrames*);
~InspectorPerformanceAgent() override;
@@ -37,7 +39,7 @@ class CORE_EXPORT InspectorPerformanceAgent final
void Restore() override;
// Performance protocol domain implementation.
- protocol::Response enable() override;
+ protocol::Response enable(Maybe<String> time_domain) override;
protocol::Response disable() override;
protocol::Response setTimeDomain(const String& time_domain) override;
protocol::Response getMetrics(
@@ -56,6 +58,8 @@ class CORE_EXPORT InspectorPerformanceAgent final
void Did(const probe::UpdateLayout&);
void Will(const probe::V8Compile&);
void Did(const probe::V8Compile&);
+ void WillStartDebuggerTask();
+ void DidFinishDebuggerTask();
// TaskTimeObserver implementation.
void WillProcessTask(base::TimeTicks start_time) override;
@@ -68,6 +72,8 @@ class CORE_EXPORT InspectorPerformanceAgent final
void InnerEnable();
base::TimeTicks GetTimeTicksNow();
base::TimeTicks GetThreadTimeNow();
+ bool HasTimeDomain(const String& time_domain);
+ protocol::Response InnerSetTimeDomain(const String& time_domain);
Member<InspectedFrames> inspected_frames_;
base::TimeDelta layout_duration_;
@@ -80,6 +86,8 @@ class CORE_EXPORT InspectorPerformanceAgent final
base::TimeTicks task_start_ticks_;
base::TimeDelta v8compile_duration_;
base::TimeTicks v8compile_start_ticks_;
+ base::TimeDelta devtools_command_duration_;
+ base::TimeTicks devtools_command_start_ticks_;
base::TimeTicks thread_time_origin_;
uint64_t layout_count_ = 0;
uint64_t recalc_style_count_ = 0;
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_protocol_config.json b/chromium/third_party/blink/renderer/core/inspector/inspector_protocol_config.json
index c5945693874..b6ba2f37b0a 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_protocol_config.json
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_protocol_config.json
@@ -74,7 +74,7 @@
{
"domain": "Page",
"exclude": ["getNavigationHistory", "navigateToHistoryEntry", "resetNavigationHistory", "captureScreenshot", "screencastFrameAck", "handleJavaScriptDialog", "setColorPickerEnabled",
- "getAppManifest", "setControlNavigations", "processNavigation", "printToPDF", "bringToFront", "setDownloadBehavior", "navigate", "crash", "close", "setWebLifecycleState", "captureSnapshot", "getInstallabilityErrors"],
+ "getAppManifest", "setControlNavigations", "processNavigation", "printToPDF", "bringToFront", "setDownloadBehavior", "navigate", "crash", "close", "setWebLifecycleState", "captureSnapshot", "getInstallabilityErrors", "getManifestIcons"],
"async": ["getResourceContent", "searchInResource"],
"exclude_events": ["screencastFrame", "screencastVisibilityChanged", "colorPicked", "interstitialShown", "interstitialHidden", "javascriptDialogOpening", "javascriptDialogClosed", "navigationRequested"]
},
@@ -84,8 +84,8 @@
{
"domain": "Emulation",
"include": ["forceViewport", "resetViewport", "resetPageScaleFactor", "setPageScaleFactor", "setScriptExecutionDisabled", "setTouchEmulationEnabled",
- "setEmulatedMedia", "setCPUThrottlingRate", "setVirtualTimePolicy", "setTimezoneOverride", "setNavigatorOverrides", "setDefaultBackgroundColorOverride", "setDeviceMetricsOverride", "clearDeviceMetricsOverride",
- "setUserAgentOverride", "setScrollbarsHidden", "setDocumentCookieDisabled", "setFocusEmulationEnabled"],
+ "setEmulatedMedia", "setEmulatedVisionDeficiency", "setCPUThrottlingRate", "setVirtualTimePolicy", "setTimezoneOverride", "setNavigatorOverrides", "setDefaultBackgroundColorOverride", "setDeviceMetricsOverride", "clearDeviceMetricsOverride",
+ "setUserAgentOverride", "setScrollbarsHidden", "setDocumentCookieDisabled", "setFocusEmulationEnabled", "setLocaleOverride"],
"include_events": ["virtualTimeBudgetExpired", "virtualTimeAdvanced", "virtualTimePaused"]
},
{
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 658fceb2514..c96317ac005 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(blink::Visitor* visitor) {
+void InspectorResourceContainer::Trace(Visitor* visitor) {
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 de3a844e6b6..5c11d438396 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(blink::Visitor*);
+ void Trace(Visitor*);
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 84dfda0888e..1a72eca769a 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
@@ -4,7 +4,6 @@
#include "third_party/blink/renderer/core/inspector/inspector_resource_content_loader.h"
-#include "third_party/blink/public/common/features.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/core/css/css_style_sheet.h"
@@ -37,7 +36,7 @@ class InspectorResourceContentLoader::ResourceClient final
explicit ResourceClient(InspectorResourceContentLoader* loader)
: loader_(loader) {}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(loader_);
RawResourceClient::Trace(visitor);
}
@@ -94,9 +93,7 @@ void InspectorResourceContentLoader::Start() {
}
ResourceFetcher* fetcher = document->Fetcher();
- if (base::FeatureList::IsEnabled(
- features::kHtmlImportsRequestInitiatorLock) &&
- document->ImportsController()) {
+ if (document->ImportsController()) {
// For @imports from HTML imported Documents, we use the
// context document for getting origin and ResourceFetcher to use the
// main Document's origin, while using the element document for
@@ -110,7 +107,7 @@ void InspectorResourceContentLoader::Start() {
urls_to_fetch.insert(resource_request.Url().GetString());
ResourceLoaderOptions options;
options.initiator_info.name = fetch_initiator_type_names::kInternal;
- FetchParameters params(resource_request, options);
+ FetchParameters params(std::move(resource_request), options);
ResourceClient* resource_client =
MakeGarbageCollected<ResourceClient>(this);
// Prevent garbage collection by holding a reference to this resource.
@@ -132,7 +129,7 @@ void InspectorResourceContentLoader::Start() {
resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
ResourceLoaderOptions options;
options.initiator_info.name = fetch_initiator_type_names::kInternal;
- FetchParameters params(resource_request, options);
+ FetchParameters params(std::move(resource_request), options);
ResourceClient* resource_client =
MakeGarbageCollected<ResourceClient>(this);
// Prevent garbage collection by holding a reference to this resource.
@@ -171,7 +168,7 @@ InspectorResourceContentLoader::~InspectorResourceContentLoader() {
DCHECK(resources_.IsEmpty());
}
-void InspectorResourceContentLoader::Trace(blink::Visitor* visitor) {
+void InspectorResourceContentLoader::Trace(Visitor* visitor) {
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 ec8d98c9a30..746406d0152 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(blink::Visitor*);
+ void Trace(Visitor*);
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 2ec520b14f2..7769a1aa17f 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
@@ -155,7 +155,10 @@ class StyleSheetHandler final : public CSSParserObserver {
StyleSheetHandler(const String& parsed_text,
Document* document,
CSSRuleSourceDataList* result)
- : parsed_text_(parsed_text), document_(document), result_(result) {
+ : parsed_text_(parsed_text),
+ document_(document),
+ result_(result),
+ current_rule_data_(nullptr) {
DCHECK(result_);
}
@@ -177,10 +180,10 @@ class StyleSheetHandler final : public CSSParserObserver {
inline void SetRuleHeaderEnd(const CharacterType*, unsigned);
const String& parsed_text_;
- Member<Document> document_;
- Member<CSSRuleSourceDataList> result_;
+ Document* document_;
+ CSSRuleSourceDataList* result_;
CSSRuleSourceDataList current_rule_data_stack_;
- Member<CSSRuleSourceData> current_rule_data_;
+ CSSRuleSourceData* current_rule_data_;
};
void StyleSheetHandler::StartRuleHeader(StyleRule::RuleType type,
@@ -729,8 +732,6 @@ InspectorStyle::InspectorStyle(CSSStyleDeclaration* style,
DCHECK(style_);
}
-InspectorStyle::~InspectorStyle() = default;
-
std::unique_ptr<protocol::CSS::CSSStyle> InspectorStyle::BuildObjectForStyle() {
std::unique_ptr<protocol::CSS::CSSStyle> result = StyleWithProperties();
if (source_data_) {
@@ -897,7 +898,7 @@ String InspectorStyle::ShorthandValue(const String& shorthand_property) {
return builder.ToString();
}
-void InspectorStyle::Trace(blink::Visitor* visitor) {
+void InspectorStyle::Trace(Visitor* visitor) {
visitor->Trace(style_);
visitor->Trace(parent_style_sheet_);
visitor->Trace(source_data_);
@@ -947,18 +948,6 @@ bool InspectorStyleSheetBase::LineNumberAndColumnToOffset(
return true;
}
-InspectorStyleSheet* InspectorStyleSheet::Create(
- InspectorNetworkAgent* network_agent,
- CSSStyleSheet* page_style_sheet,
- const String& origin,
- const String& document_url,
- InspectorStyleSheetBase::Listener* listener,
- InspectorResourceContainer* resource_container) {
- return MakeGarbageCollected<InspectorStyleSheet>(
- network_agent, page_style_sheet, origin, document_url, listener,
- resource_container);
-}
-
InspectorStyleSheet::InspectorStyleSheet(
InspectorNetworkAgent* network_agent,
CSSStyleSheet* page_style_sheet,
@@ -984,7 +973,7 @@ InspectorStyleSheet::InspectorStyleSheet(
InspectorStyleSheet::~InspectorStyleSheet() = default;
-void InspectorStyleSheet::Trace(blink::Visitor* visitor) {
+void InspectorStyleSheet::Trace(Visitor* visitor) {
visitor->Trace(resource_container_);
visitor->Trace(network_agent_);
visitor->Trace(page_style_sheet_);
@@ -1008,8 +997,7 @@ String InspectorStyleSheet::FinalURL() {
bool InspectorStyleSheet::SetText(const String& text,
ExceptionState& exception_state) {
InnerSetText(text, true);
- page_style_sheet_->SetText(text, true /* allow_import_rules */,
- exception_state);
+ page_style_sheet_->SetText(text, true /* allow_import_rules */, nullptr);
OnStyleSheetTextChanged();
return true;
}
@@ -1044,7 +1032,8 @@ CSSStyleRule* InspectorStyleSheet::SetRuleSelector(
}
CSSStyleRule* style_rule = InspectorCSSAgent::AsCSSStyleRule(rule);
- style_rule->setSelectorText(page_style_sheet_->OwnerDocument(), text);
+ style_rule->setSelectorText(
+ page_style_sheet_->OwnerDocument()->GetExecutionContext(), text);
ReplaceText(source_data->rule_header_range, text, new_range, old_text);
OnStyleSheetTextChanged();
@@ -1123,7 +1112,8 @@ CSSRule* InspectorStyleSheet::SetStyleText(const SourceRange& range,
style = style_rule->style();
else
style = To<CSSKeyframeRule>(rule)->style();
- style->setCSSText(page_style_sheet_->OwnerDocument(), text, exception_state);
+ style->setCSSText(page_style_sheet_->OwnerDocument()->GetExecutionContext(),
+ text, exception_state);
ReplaceText(source_data->rule_body_range, text, new_range, old_text);
OnStyleSheetTextChanged();
@@ -1161,7 +1151,8 @@ CSSMediaRule* InspectorStyleSheet::SetMediaRuleText(
}
CSSMediaRule* media_rule = InspectorCSSAgent::AsCSSMediaRule(rule);
- media_rule->media()->setMediaText(text);
+ media_rule->media()->setMediaText(
+ page_style_sheet_->OwnerDocument()->GetExecutionContext(), text);
ReplaceText(source_data->rule_header_range, text, new_range, old_text);
OnStyleSheetTextChanged();
@@ -1217,8 +1208,9 @@ CSSStyleRule* InspectorStyleSheet::InsertCSSOMRuleInMediaRule(
break;
}
- media_rule->insertRule(page_style_sheet_->OwnerDocument(), rule_text, index,
- exception_state);
+ media_rule->insertRule(
+ page_style_sheet_->OwnerDocument()->GetExecutionContext(), rule_text,
+ index, exception_state);
CSSRule* rule = media_rule->Item(index);
CSSStyleRule* style_rule = InspectorCSSAgent::AsCSSStyleRule(rule);
if (!style_rule) {
@@ -1745,6 +1737,11 @@ String InspectorStyleSheet::SourceMapURL() {
return page_style_sheet_->Contents()->SourceMapURL();
}
+const Document* InspectorStyleSheet::GetDocument() {
+ return CSSStyleSheet::SingleOwnerDocument(
+ InspectorStyleSheet::PageStyleSheet());
+}
+
CSSRuleSourceData* InspectorStyleSheet::FindRuleByHeaderRange(
const SourceRange& source_range) {
if (!source_data_)
@@ -1920,13 +1917,6 @@ bool InspectorStyleSheet::InspectorStyleSheetText(String* result) {
return true;
}
-InspectorStyleSheetForInlineStyle* InspectorStyleSheetForInlineStyle::Create(
- Element* element,
- Listener* listener) {
- return MakeGarbageCollected<InspectorStyleSheetForInlineStyle>(element,
- listener);
-}
-
InspectorStyleSheetForInlineStyle::InspectorStyleSheetForInlineStyle(
Element* element,
Listener* listener)
@@ -1950,7 +1940,7 @@ bool InspectorStyleSheetForInlineStyle::SetText(
{
InspectorCSSAgent::InlineStyleOverrideScope override_scope(
- element_->ownerDocument());
+ &element_->ownerDocument()->GetSecurityContext());
element_->setAttribute("style", AtomicString(text), exception_state);
}
if (!exception_state.HadException())
@@ -2001,10 +1991,14 @@ const String& InspectorStyleSheetForInlineStyle::ElementStyleText() {
return element_->getAttribute("style").GetString();
}
-void InspectorStyleSheetForInlineStyle::Trace(blink::Visitor* visitor) {
+void InspectorStyleSheetForInlineStyle::Trace(Visitor* visitor) {
visitor->Trace(element_);
visitor->Trace(inspector_style_);
InspectorStyleSheetBase::Trace(visitor);
}
+const Document* InspectorStyleSheetForInlineStyle::GetDocument() {
+ return &InspectorStyleSheetForInlineStyle::element_->GetDocument();
+}
+
} // namespace blink
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 c59f456f79d..3f7fd47c06b 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
@@ -43,6 +43,7 @@ class CSSMediaRule;
class CSSStyleDeclaration;
class CSSStyleRule;
class CSSStyleSheet;
+class Document;
class Element;
class ExceptionState;
class InspectorNetworkAgent;
@@ -57,14 +58,16 @@ class InspectorStyle final : public GarbageCollected<InspectorStyle> {
InspectorStyle(CSSStyleDeclaration*,
CSSRuleSourceData*,
InspectorStyleSheetBase* parent_style_sheet);
- ~InspectorStyle();
CSSStyleDeclaration* CssStyle() { return style_.Get(); }
+ InspectorStyleSheetBase* InspectorStyleSheet() {
+ return parent_style_sheet_.Get();
+ }
std::unique_ptr<protocol::CSS::CSSStyle> BuildObjectForStyle();
bool StyleText(String* result);
bool TextForRange(const SourceRange&, String* result);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
void PopulateAllProperties(Vector<CSSPropertySourceData>& result);
@@ -86,13 +89,14 @@ class InspectorStyleSheetBase
virtual void StyleSheetChanged(InspectorStyleSheetBase*) = 0;
};
virtual ~InspectorStyleSheetBase() = default;
- virtual void Trace(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
String Id() { return id_; }
virtual bool SetText(const String&, ExceptionState&) = 0;
virtual bool GetText(String* result) = 0;
virtual String SourceMapURL() { return String(); }
+ virtual const Document* GetDocument() = 0;
std::unique_ptr<protocol::CSS::CSSStyle> BuildObjectForStyle(
CSSStyleDeclaration*);
@@ -122,13 +126,6 @@ class InspectorStyleSheetBase
class InspectorStyleSheet : public InspectorStyleSheetBase {
public:
- static InspectorStyleSheet* Create(InspectorNetworkAgent*,
- CSSStyleSheet* page_style_sheet,
- const String& origin,
- const String& document_url,
- InspectorStyleSheetBase::Listener*,
- InspectorResourceContainer*);
-
InspectorStyleSheet(InspectorNetworkAgent*,
CSSStyleSheet* page_style_sheet,
const String& origin,
@@ -136,7 +133,7 @@ class InspectorStyleSheet : public InspectorStyleSheetBase {
InspectorStyleSheetBase::Listener*,
InspectorResourceContainer*);
~InspectorStyleSheet() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
String FinalURL();
bool SetText(const String&, ExceptionState&) override;
@@ -189,6 +186,7 @@ class InspectorStyleSheet : public InspectorStyleSheetBase {
const CSSRuleVector& FlatRules();
CSSRuleSourceData* SourceDataForRule(CSSRule*);
String SourceMapURL() override;
+ const Document* GetDocument() override;
protected:
InspectorStyle* GetInspectorStyle(CSSStyleDeclaration*) override;
@@ -249,8 +247,6 @@ class InspectorStyleSheet : public InspectorStyleSheetBase {
class InspectorStyleSheetForInlineStyle final : public InspectorStyleSheetBase {
public:
- static InspectorStyleSheetForInlineStyle* Create(Element*, Listener*);
-
InspectorStyleSheetForInlineStyle(Element*, Listener*);
void DidModifyElementAttribute();
bool SetText(const String&, ExceptionState&) override;
@@ -258,7 +254,9 @@ class InspectorStyleSheetForInlineStyle final : public InspectorStyleSheetBase {
CSSStyleDeclaration* InlineStyle();
CSSRuleSourceData* RuleSourceData();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
+
+ const Document* GetDocument() override;
protected:
InspectorStyle* GetInspectorStyle(CSSStyleDeclaration*) override;
diff --git a/chromium/third_party/blink/renderer/core/inspector/inspector_task_runner.cc b/chromium/third_party/blink/renderer/core/inspector/inspector_task_runner.cc
index 8df688fdf7b..ec22795232f 100644
--- a/chromium/third_party/blink/renderer/core/inspector/inspector_task_runner.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/inspector_task_runner.cc
@@ -38,8 +38,10 @@ void InspectorTaskRunner::AppendTask(Task task) {
CrossThreadBindOnce(
&InspectorTaskRunner::PerformSingleInterruptingTaskDontWait,
WrapRefCounted(this)));
- if (isolate_)
+ if (isolate_) {
+ AddRef();
isolate_->RequestInterrupt(&V8InterruptCallback, this);
+ }
}
void InspectorTaskRunner::AppendTaskDontInterrupt(Task task) {
@@ -69,6 +71,7 @@ void InspectorTaskRunner::PerformSingleInterruptingTaskDontWait() {
void InspectorTaskRunner::V8InterruptCallback(v8::Isolate*, void* data) {
InspectorTaskRunner* runner = static_cast<InspectorTaskRunner*>(data);
Task task = runner->TakeNextInterruptingTask();
+ runner->Release();
if (!task) {
return;
}
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 d41efcf14a9..212f2427c5b 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
@@ -66,7 +66,6 @@ class CORE_EXPORT InspectorTaskRunner final
Mutex mutex_;
scoped_refptr<base::SingleThreadTaskRunner> isolate_task_runner_;
v8::Isolate* isolate_ GUARDED_BY(mutex_) = nullptr;
- Deque<Task> queue_;
Deque<Task> interrupting_task_queue_;
bool disposed_ GUARDED_BY(mutex_) = false;
DISALLOW_COPY_AND_ASSIGN(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 bf87fbf4058..88dad8dce93 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
@@ -17,6 +17,9 @@
#include "third_party/blink/renderer/core/css/invalidation/invalidation_set.h"
#include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/events/keyboard_event.h"
+#include "third_party/blink/renderer/core/events/wheel_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/local_frame_view.h"
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
@@ -74,6 +77,20 @@ std::unique_ptr<TracedValue> GetNavigationTracingData(Document* document) {
IdentifiersFactory::LoaderId(document->Loader()));
return data;
}
+
+int GetModifierFromEvent(const UIEventWithKeyState& event) {
+ int modifier = 0;
+ if (event.altKey())
+ modifier |= 1;
+ if (event.ctrlKey())
+ modifier |= 2;
+ if (event.metaKey())
+ modifier |= 4;
+ if (event.shiftKey())
+ modifier |= 8;
+ return modifier;
+}
+
} // namespace
String ToHexString(const void* p) {
@@ -346,7 +363,7 @@ const char* PseudoTypeToString(CSSSelector::PseudoType pseudo_type) {
DEFINE_STRING_MAPPING(PseudoHostHasAppearance)
DEFINE_STRING_MAPPING(PseudoVideoPersistent)
DEFINE_STRING_MAPPING(PseudoVideoPersistentAncestor)
- DEFINE_STRING_MAPPING(PseudoXrImmersiveDomOverlay)
+ DEFINE_STRING_MAPPING(PseudoXrOverlay)
#undef DEFINE_STRING_MAPPING
}
@@ -594,6 +611,7 @@ inspector_style_invalidator_invalidate_event::InvalidationList(
std::unique_ptr<TracedValue>
inspector_style_recalc_invalidation_tracking_event::Data(
Node* node,
+ StyleChangeType change_type,
const StyleChangeReasonForTracing& reason) {
DCHECK(node);
@@ -601,6 +619,7 @@ inspector_style_recalc_invalidation_tracking_event::Data(
value->SetString("frame",
IdentifiersFactory::FrameId(node->GetDocument().GetFrame()));
SetNodeInfo(value.get(), node, "nodeId", "nodeName");
+ value->SetBoolean("subtree", change_type == kSubtreeStyleChange);
value->SetString("reason", reason.ReasonString());
value->SetString("extraData", reason.GetExtraData());
SourceLocation::Capture()->ToTracedValue(value.get(), "stackTrace");
@@ -680,6 +699,7 @@ const char kAttributeChanged[] = "Attribute changed";
const char kColumnsChanged[] = "Attribute changed";
const char kChildAnonymousBlockChanged[] = "Child anonymous block changed";
const char kAnonymousBlockChange[] = "Anonymous block change";
+const char kFontsChanged[] = "Fonts changed";
const char kFullscreen[] = "Fullscreen change";
const char kChildChanged[] = "Child changed";
const char kListValueChange[] = "List value change";
@@ -868,8 +888,8 @@ std::unique_ptr<TracedValue> inspector_mark_resource_cached_event::Data(
}
static LocalFrame* FrameForExecutionContext(ExecutionContext* context) {
- if (auto* document = DynamicTo<Document>(context))
- return document->GetFrame();
+ if (auto* window = DynamicTo<LocalDOMWindow>(context))
+ return window->GetFrame();
return nullptr;
}
@@ -913,9 +933,8 @@ std::unique_ptr<TracedValue> inspector_animation_frame_event::Data(
int callback_id) {
auto value = std::make_unique<TracedValue>();
value->SetInteger("id", callback_id);
- if (auto* document = DynamicTo<Document>(context)) {
- value->SetString("frame",
- IdentifiersFactory::FrameId(document->GetFrame()));
+ if (auto* window = DynamicTo<LocalDOMWindow>(context)) {
+ value->SetString("frame", IdentifiersFactory::FrameId(window->GetFrame()));
} else if (auto* scope = DynamicTo<WorkerGlobalScope>(context)) {
value->SetString("worker", ToHexString(scope));
}
@@ -1284,6 +1303,39 @@ std::unique_ptr<TracedValue> inspector_event_dispatch_event::Data(
const Event& event) {
auto value = std::make_unique<TracedValue>();
value->SetString("type", event.type());
+ bool record_input_enabled;
+ TRACE_EVENT_CATEGORY_GROUP_ENABLED(
+ TRACE_DISABLED_BY_DEFAULT("devtools.timeline.inputs"),
+ &record_input_enabled);
+ if (record_input_enabled) {
+ const auto* keyboard_event = DynamicTo<KeyboardEvent>(event);
+ if (keyboard_event) {
+ value->SetInteger("modifier", GetModifierFromEvent(*keyboard_event));
+ value->SetDouble(
+ "timestamp",
+ keyboard_event->PlatformTimeStamp().since_origin().InMicroseconds());
+ value->SetString("code", keyboard_event->code());
+ value->SetString("key", keyboard_event->key());
+ }
+
+ const auto* mouse_event = DynamicTo<MouseEvent>(event);
+ const auto* wheel_event = DynamicTo<WheelEvent>(event);
+ if (mouse_event || wheel_event) {
+ value->SetDouble("x", mouse_event->x());
+ value->SetDouble("y", mouse_event->y());
+ value->SetInteger("modifier", GetModifierFromEvent(*mouse_event));
+ value->SetDouble(
+ "timestamp",
+ mouse_event->PlatformTimeStamp().since_origin().InMicroseconds());
+ value->SetInteger("button", mouse_event->button());
+ value->SetInteger("buttons", mouse_event->buttons());
+ value->SetInteger("clickCount", mouse_event->detail());
+ if (wheel_event) {
+ value->SetDouble("deltaX", wheel_event->deltaX());
+ value->SetDouble("deltaY", wheel_event->deltaY());
+ }
+ }
+ }
SetCallStack(value.get());
return value;
}
@@ -1348,11 +1400,11 @@ std::unique_ptr<TracedValue> inspector_animation_event::Data(
const Animation& animation) {
auto value = std::make_unique<TracedValue>();
value->SetString("id", String::Number(animation.SequenceNumber()));
- value->SetString("state", animation.playState());
+ value->SetString("state", animation.PlayStateString());
if (const AnimationEffect* effect = animation.effect()) {
value->SetString("name", animation.id());
- if (effect->IsKeyframeEffect()) {
- if (Element* target = ToKeyframeEffect(effect)->target())
+ if (auto* frame_effect = DynamicTo<KeyframeEffect>(effect)) {
+ if (Element* target = frame_effect->EffectTarget())
SetNodeInfo(value.get(), target, "nodeId", "nodeName");
}
}
@@ -1362,7 +1414,7 @@ std::unique_ptr<TracedValue> inspector_animation_event::Data(
std::unique_ptr<TracedValue> inspector_animation_state_event::Data(
const Animation& animation) {
auto value = std::make_unique<TracedValue>();
- value->SetString("state", animation.playState());
+ value->SetString("state", animation.PlayStateString());
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 7b1d0d5b6a6..589e587e905 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
@@ -70,6 +70,7 @@ class StyleChangeReasonForTracing;
class StyleImage;
class XMLHttpRequest;
enum class ResourceType : uint8_t;
+enum StyleChangeType : uint32_t;
namespace probe {
class CallFunction;
@@ -126,7 +127,7 @@ class CORE_EXPORT InspectorTraceEvents
void FrameStartedLoading(LocalFrame*);
- void Trace(blink::Visitor*) {}
+ void Trace(Visitor*) {}
private:
DISALLOW_COPY_AND_ASSIGN(InspectorTraceEvents);
@@ -169,7 +170,9 @@ std::unique_ptr<TracedValue> RuleSetInvalidation(ContainerNode&,
(element), (invalidationSet), ##__VA_ARGS__));
namespace inspector_style_recalc_invalidation_tracking_event {
-std::unique_ptr<TracedValue> Data(Node*, const StyleChangeReasonForTracing&);
+std::unique_ptr<TracedValue> Data(Node*,
+ StyleChangeType,
+ const StyleChangeReasonForTracing&);
}
String DescendantInvalidationSetToIdString(const InvalidationSet&);
@@ -225,6 +228,7 @@ extern const char kAttributeChanged[];
extern const char kColumnsChanged[];
extern const char kChildAnonymousBlockChanged[];
extern const char kAnonymousBlockChange[];
+extern const char kFontsChanged[];
extern const char kFullscreen[];
extern const char kChildChanged[];
extern const char kListValueChange[];
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 e2f99df7576..8970aaf5070 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
@@ -124,7 +124,8 @@ Response LegacyDOMSnapshotAgent::GetSnapshot(
// Look up the CSSPropertyIDs for each entry in |style_filter|.
for (const String& entry : *style_filter) {
- CSSPropertyID property_id = cssPropertyID(entry);
+ CSSPropertyID property_id =
+ cssPropertyID(document->GetExecutionContext(), entry);
if (property_id == CSSPropertyID::kInvalid)
continue;
css_property_filter_->emplace_back(entry, property_id);
@@ -144,7 +145,7 @@ Response LegacyDOMSnapshotAgent::GetSnapshot(
computed_styles_map_.reset();
css_property_filter_.reset();
paint_order_map_.reset();
- return Response::OK();
+ return Response::Success();
}
int LegacyDOMSnapshotAgent::VisitNode(Node* node,
@@ -256,16 +257,12 @@ int LegacyDOMSnapshotAgent::VisitNode(Node* node,
value->setOptionSelected(option_element->Selected());
if (element->GetPseudoId()) {
- protocol::DOM::PseudoType pseudo_type;
- if (InspectorDOMAgent::GetPseudoElementType(element->GetPseudoId(),
- &pseudo_type)) {
- value->setPseudoType(pseudo_type);
- }
- } else {
- value->setPseudoElementIndexes(
- VisitPseudoElements(element, index, include_event_listeners,
- include_user_agent_shadow_tree));
+ value->setPseudoType(
+ InspectorDOMAgent::ProtocolPseudoElementType(element->GetPseudoId()));
}
+ value->setPseudoElementIndexes(
+ VisitPseudoElements(element, index, include_event_listeners,
+ include_user_agent_shadow_tree));
auto* image_element = DynamicTo<HTMLImageElement>(node);
if (image_element)
diff --git a/chromium/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.h b/chromium/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.h
index 36c66c9b3ad..245b7845ce0 100644
--- a/chromium/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.h
+++ b/chromium/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.h
@@ -98,7 +98,7 @@ class CORE_EXPORT LegacyDOMSnapshotAgent {
// the corresponding node.
OriginUrlMap* origin_url_map_;
using DocumentOrderMap = HeapHashMap<Member<Document>, int>;
- Member<InspectorDOMDebuggerAgent> dom_debugger_agent_;
+ InspectorDOMDebuggerAgent* dom_debugger_agent_;
DISALLOW_COPY_AND_ASSIGN(LegacyDOMSnapshotAgent);
};
diff --git a/chromium/third_party/blink/renderer/core/inspector/locale_controller.cc b/chromium/third_party/blink/renderer/core/inspector/locale_controller.cc
new file mode 100644
index 00000000000..5e26a092405
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/inspector/locale_controller.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/inspector/locale_controller.h"
+
+#include "base/i18n/rtl.h"
+#include "third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h"
+#include "third_party/blink/renderer/core/workers/worker_thread.h"
+#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
+#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
+#include "third_party/icu/source/common/unicode/locid.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+namespace {
+void UpdateDefaultLocaleInIsolate(v8::Isolate* isolate) {
+ DCHECK(isolate);
+ isolate->LocaleConfigurationChangeNotification();
+ isolate->DateTimeConfigurationChangeNotification();
+}
+
+void NotifyLocaleChangeOnWorkerThread(WorkerThread* worker_thread) {
+ DCHECK(worker_thread->IsCurrentThread());
+ UpdateDefaultLocaleInIsolate(worker_thread->GlobalScope()->GetIsolate());
+}
+
+void UpdateLocale(const String& locale) {
+ WebString web_locale(locale);
+ base::i18n::SetICUDefaultLocale(web_locale.Ascii());
+ UpdateDefaultLocaleInIsolate(V8PerIsolateData::MainThreadIsolate());
+ WorkerThread::CallOnAllWorkerThreads(&NotifyLocaleChangeOnWorkerThread,
+ TaskType::kInternalDefault);
+}
+} // namespace
+
+LocaleController::LocaleController()
+ : embedder_locale_(String(icu::Locale::getDefault().getName())) {}
+
+String LocaleController::SetLocaleOverride(const String& locale) {
+ if (locale_override_ == locale)
+ return String();
+ if (locale.IsEmpty()) {
+ UpdateLocale(embedder_locale_);
+ } else {
+ icu::Locale locale_object(locale.Ascii().data());
+ const char* lang = locale_object.getLanguage();
+ if (!lang || *lang == '\0')
+ return "Invalid locale name";
+ UpdateLocale(locale);
+ }
+ locale_override_ = locale;
+ return String();
+}
+
+bool LocaleController::has_locale_override() const {
+ return !locale_override_.IsEmpty();
+}
+
+// static
+LocaleController& LocaleController::instance() {
+ DEFINE_STATIC_LOCAL(LocaleController, instance, ());
+ return instance;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/inspector/locale_controller.h b/chromium/third_party/blink/renderer/core/inspector/locale_controller.h
new file mode 100644
index 00000000000..a432c7feb78
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/inspector/locale_controller.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_CORE_INSPECTOR_LOCALE_CONTROLLER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_LOCALE_CONTROLLER_H_
+
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+class LocaleController {
+ public:
+ static LocaleController& instance();
+
+ String SetLocaleOverride(const String& locale);
+ bool has_locale_override() const;
+
+ private:
+ LocaleController();
+ ~LocaleController() = default;
+
+ String embedder_locale_;
+ String locale_override_;
+ DISALLOW_COPY_AND_ASSIGN(LocaleController);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_LOCALE_CONTROLLER_H_
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 26c12ec77c2..a7d3ab1ff45 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
@@ -78,8 +78,8 @@ Mutex& CreationMutex() {
LocalFrame* ToFrame(ExecutionContext* context) {
if (!context)
return nullptr;
- if (auto* document = DynamicTo<Document>(context))
- return document->GetFrame();
+ if (auto* window = DynamicTo<LocalDOMWindow>(context))
+ return window->GetFrame();
if (context->IsMainThreadWorkletGlobalScope())
return To<WorkletGlobalScope>(context)->GetFrame();
return nullptr;
@@ -172,8 +172,8 @@ void MainThreadDebugger::ExceptionThrown(ExecutionContext* context,
ErrorEvent* event) {
LocalFrame* frame = nullptr;
ScriptState* script_state = nullptr;
- if (auto* document = DynamicTo<Document>(context)) {
- frame = document->GetFrame();
+ if (auto* window = DynamicTo<LocalDOMWindow>(context)) {
+ frame = window->GetFrame();
if (!frame)
return;
script_state =
@@ -384,9 +384,8 @@ static Node* SecondArgumentAsNode(
if (Node* node = V8Node::ToImplWithTypeCheck(info.GetIsolate(), info[1]))
return node;
}
- ExecutionContext* execution_context =
- ToExecutionContext(info.GetIsolate()->GetCurrentContext());
- return DynamicTo<Document>(execution_context);
+ auto* window = CurrentDOMWindow(info.GetIsolate());
+ return window ? window->document() : nullptr;
}
void MainThreadDebugger::QuerySelectorCallback(
diff --git a/chromium/third_party/blink/renderer/core/inspector/main_thread_debugger_test.cc b/chromium/third_party/blink/renderer/core/inspector/main_thread_debugger_test.cc
index d2b8e76504c..88771122cad 100644
--- a/chromium/third_party/blink/renderer/core/inspector/main_thread_debugger_test.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/main_thread_debugger_test.cc
@@ -23,9 +23,8 @@ TEST_F(MainThreadDebuggerTest, HitBreakPointDuringLifecycle) {
// The following steps would cause either style update or layout, it should
// never crash.
document.View()->ViewportSizeChanged(true, true);
- document.View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
- document.UpdateStyleAndLayout();
+ document.View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
+ document.UpdateStyleAndLayout(DocumentUpdateReason::kTest);
document.UpdateStyleAndLayoutTree();
postponed_transition_scope.reset();
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 12537133b3c..d9753c22e96 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
@@ -41,18 +41,6 @@ static bool IsHTTPErrorStatusCode(int status_code) {
return status_code >= 400;
}
-// static
-XHRReplayData* XHRReplayData::Create(ExecutionContext* execution_context,
- const AtomicString& method,
- const KURL& url,
- bool async,
- scoped_refptr<EncodedFormData> form_data,
- bool include_credentials) {
- return MakeGarbageCollected<XHRReplayData>(execution_context, method, url,
- async, std::move(form_data),
- include_credentials);
-}
-
void XHRReplayData::AddHeader(const AtomicString& key,
const AtomicString& value) {
headers_.Set(key, value);
@@ -62,13 +50,11 @@ XHRReplayData::XHRReplayData(ExecutionContext* execution_context,
const AtomicString& method,
const KURL& url,
bool async,
- scoped_refptr<EncodedFormData> form_data,
bool include_credentials)
: execution_context_(execution_context),
method_(method),
url_(url),
async_(async),
- form_data_(form_data),
include_credentials_(include_credentials) {}
// ResourceData
@@ -89,7 +75,7 @@ NetworkResourcesData::ResourceData::ResourceData(
pending_encoded_data_length_(0),
cached_resource_(nullptr) {}
-void NetworkResourcesData::ResourceData::Trace(blink::Visitor* visitor) {
+void NetworkResourcesData::ResourceData::Trace(Visitor* visitor) {
visitor->Trace(network_resources_data_);
visitor->Trace(xhr_replay_data_);
visitor->template RegisterWeakCallbackMethod<
@@ -124,11 +110,6 @@ size_t NetworkResourcesData::ResourceData::RemoveContent() {
post_data_ = nullptr;
}
- if (xhr_replay_data_ && xhr_replay_data_->FormData()) {
- result += xhr_replay_data_->FormData()->SizeInBytes();
- xhr_replay_data_->DeleteFormData();
- }
-
return result;
}
@@ -175,9 +156,6 @@ uint64_t NetworkResourcesData::ResourceData::DataLength() const {
if (post_data_)
data_length += post_data_->SizeInBytes();
- if (xhr_replay_data_ && xhr_replay_data_->FormData())
- data_length += xhr_replay_data_->FormData()->SizeInBytes();
-
return data_length;
}
@@ -211,7 +189,7 @@ NetworkResourcesData::NetworkResourcesData(size_t total_buffer_size,
NetworkResourcesData::~NetworkResourcesData() = default;
-void NetworkResourcesData::Trace(blink::Visitor* visitor) {
+void NetworkResourcesData::Trace(Visitor* visitor) {
visitor->Trace(request_id_to_resource_data_map_);
}
@@ -337,10 +315,14 @@ void NetworkResourcesData::MaybeDecodeDataToContent(const String& request_id) {
return;
if (!resource_data->HasData())
return;
- content_size_ += resource_data->DecodeDataToContent();
- size_t data_length = resource_data->Content().CharactersSizeInBytes();
+ const size_t data_length_increment = resource_data->DecodeDataToContent();
+ const size_t data_length = resource_data->Content().CharactersSizeInBytes();
+ content_size_ += data_length_increment;
if (data_length > maximum_single_resource_content_size_)
content_size_ -= resource_data->EvictContent();
+ else
+ EnsureFreeSpace(data_length_increment);
+ CHECK_GE(maximum_resources_content_size_, content_size_);
}
void NetworkResourcesData::AddResource(const String& request_id,
@@ -378,15 +360,6 @@ void NetworkResourcesData::SetXHRReplayData(const String& request_id,
if (!resource_data || resource_data->IsContentEvicted())
return;
- if (xhr_replay_data->FormData()) {
- if (!EnsureFreeSpace(xhr_replay_data->FormData()->SizeInBytes())) {
- xhr_replay_data->DeleteFormData();
- } else {
- content_size_ += xhr_replay_data->FormData()->SizeInBytes();
- request_ids_deque_.push_back(request_id);
- }
- }
-
resource_data->SetXHRReplayData(xhr_replay_data);
}
@@ -464,7 +437,7 @@ bool NetworkResourcesData::EnsureFreeSpace(uint64_t size) {
if (size > maximum_resources_content_size_)
return false;
- while (size > maximum_resources_content_size_ - content_size_) {
+ while (content_size_ + size > maximum_resources_content_size_) {
String request_id = request_ids_deque_.TakeFirst();
ResourceData* resource_data = ResourceDataForRequestId(request_id);
if (resource_data)
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 a80765fc07d..1368d3ad52e 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
@@ -50,18 +50,10 @@ class TextResourceDecoder;
class XHRReplayData final : public GarbageCollected<XHRReplayData> {
public:
- static XHRReplayData* Create(ExecutionContext*,
- const AtomicString& method,
- const KURL&,
- bool async,
- scoped_refptr<EncodedFormData>,
- bool include_credentials);
-
XHRReplayData(ExecutionContext*,
const AtomicString& method,
const KURL&,
bool async,
- scoped_refptr<EncodedFormData>,
bool include_credentials);
void AddHeader(const AtomicString& key, const AtomicString& value);
@@ -70,23 +62,16 @@ class XHRReplayData final : public GarbageCollected<XHRReplayData> {
const AtomicString& Method() const { return method_; }
const KURL& Url() const { return url_; }
bool Async() const { return async_; }
- EncodedFormData* FormData() const { return form_data_.get(); }
const HTTPHeaderMap& Headers() const { return headers_; }
bool IncludeCredentials() const { return include_credentials_; }
- virtual void Trace(blink::Visitor* visitor) {
- visitor->Trace(execution_context_);
- }
-
- void DeleteFormData() { form_data_ = nullptr; }
+ virtual void Trace(Visitor* visitor) { visitor->Trace(execution_context_); }
private:
WeakMember<ExecutionContext> execution_context_;
AtomicString method_;
KURL url_;
bool async_;
- // TODO(http://crbug.com/958524): Remove form_data_ after OutOfBlinkCORS is launched.
- scoped_refptr<EncodedFormData> form_data_;
HTTPHeaderMap headers_;
bool include_credentials_;
};
@@ -175,7 +160,7 @@ class NetworkResourcesData final
post_data_ = post_data;
}
EncodedFormData* PostData() const { return post_data_.get(); }
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
bool HasData() const { return data_buffer_.get(); }
@@ -209,12 +194,6 @@ class NetworkResourcesData final
scoped_refptr<EncodedFormData> post_data_;
};
- static NetworkResourcesData* Create(size_t total_buffer_size,
- size_t resource_buffer_size) {
- return MakeGarbageCollected<NetworkResourcesData>(total_buffer_size,
- resource_buffer_size);
- }
-
NetworkResourcesData(size_t total_buffer_size, size_t resource_buffer_size);
~NetworkResourcesData();
@@ -251,7 +230,7 @@ class NetworkResourcesData final
int64_t GetAndClearPendingEncodedDataLength(const String& request_id);
void AddPendingEncodedDataLength(const String& request_id,
size_t encoded_data_length);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
ResourceData* ResourceDataForRequestId(const String& request_id) const;
diff --git a/chromium/third_party/blink/renderer/core/inspector/protocol_parser_test.cc b/chromium/third_party/blink/renderer/core/inspector/protocol_parser_test.cc
index 2f6d31bcff7..8be6ecb2376 100644
--- a/chromium/third_party/blink/renderer/core/inspector/protocol_parser_test.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/protocol_parser_test.cc
@@ -6,6 +6,8 @@
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
+#include "third_party/inspector_protocol/crdtp/json.h"
namespace blink {
@@ -14,7 +16,18 @@ using protocol::ListValue;
using protocol::Value;
static std::unique_ptr<protocol::Value> ParseJSON(const String& string) {
- return protocol::StringUtil::parseJSON(string);
+ std::vector<uint8_t> cbor;
+ if (string.Is8Bit()) {
+ crdtp::json::ConvertJSONToCBOR(
+ crdtp::span<uint8_t>(string.Characters8(), string.length()), &cbor);
+ } else {
+ crdtp::json::ConvertJSONToCBOR(
+ crdtp::span<uint16_t>(
+ reinterpret_cast<const uint16_t*>(string.Characters16()),
+ string.length()),
+ &cbor);
+ }
+ return protocol::Value::parseBinary(cbor.data(), cbor.size());
}
TEST(ProtocolParserTest, Reading) {
@@ -311,44 +324,40 @@ TEST(ProtocolParserTest, Reading) {
ASSERT_TRUE(root.get());
EXPECT_EQ(Value::TypeObject, root->type());
- root = ParseJSON("{\"number\":9.87654321, \"null\":null , \"S\" : \"str\" }");
- ASSERT_TRUE(root.get());
- EXPECT_EQ(Value::TypeObject, root->type());
- DictionaryValue* object_val = DictionaryValue::cast(root.get());
- ASSERT_TRUE(object_val);
- double_val = 0.0;
- EXPECT_TRUE(object_val->getDouble("number", &double_val));
- EXPECT_DOUBLE_EQ(9.87654321, double_val);
- Value* null_val = object_val->get("null");
- ASSERT_TRUE(null_val);
- EXPECT_EQ(Value::TypeNull, null_val->type());
- EXPECT_TRUE(object_val->getString("S", &str_val));
- EXPECT_EQ("str", str_val);
-
- // Test newline equivalence.
- root2 = ParseJSON(
- "{\n"
- " \"number\":9.87654321,\n"
- " \"null\":null,\n"
- " \"S\":\"str\"\n"
- "}\n");
- ASSERT_TRUE(root2.get());
- EXPECT_EQ(root->toJSONString(), root2->toJSONString());
-
- root2 = ParseJSON(
- "{\r\n"
- " \"number\":9.87654321,\r\n"
- " \"null\":null,\r\n"
- " \"S\":\"str\"\r\n"
- "}\r\n");
- ASSERT_TRUE(root2.get());
- EXPECT_EQ(root->toJSONString(), root2->toJSONString());
+ // The three test cases in the loop differ only by their newlines; therefore
+ // the same assertions are valid.
+ for (const char* test :
+ {"{\"number\":9.87654321, \"null\":null , \"S\" : \"str\" }",
+ "{\n"
+ " \"number\":9.87654321,\n"
+ " \"null\":null,\n"
+ " \"S\":\"str\"\n"
+ "}\n",
+ "{\r\n"
+ " \"number\":9.87654321,\r\n"
+ " \"null\":null,\r\n"
+ " \"S\":\"str\"\r\n"
+ "}\r\n"}) {
+ root = ParseJSON(String(test));
+ ASSERT_TRUE(root.get());
+ EXPECT_EQ(Value::TypeObject, root->type());
+ DictionaryValue* object_val = DictionaryValue::cast(root.get());
+ ASSERT_TRUE(object_val);
+ double_val = 0.0;
+ EXPECT_TRUE(object_val->getDouble("number", &double_val));
+ EXPECT_DOUBLE_EQ(9.87654321, double_val);
+ Value* null_val = object_val->get("null");
+ ASSERT_TRUE(null_val);
+ EXPECT_EQ(Value::TypeNull, null_val->type());
+ EXPECT_TRUE(object_val->getString("S", &str_val));
+ EXPECT_EQ("str", str_val);
+ }
// Test nesting
root = ParseJSON("{\"inner\":{\"array\":[true]},\"false\":false,\"d\":{}}");
ASSERT_TRUE(root.get());
EXPECT_EQ(Value::TypeObject, root->type());
- object_val = DictionaryValue::cast(root.get());
+ DictionaryValue* object_val = DictionaryValue::cast(root.get());
ASSERT_TRUE(object_val);
DictionaryValue* inner_object = object_val->getObject("inner");
ASSERT_TRUE(inner_object);
diff --git a/chromium/third_party/blink/renderer/core/inspector/thread_debugger.cc b/chromium/third_party/blink/renderer/core/inspector/thread_debugger.cc
index 6184e545055..ba97400cb64 100644
--- a/chromium/third_party/blink/renderer/core/inspector/thread_debugger.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/thread_debugger.cc
@@ -15,6 +15,7 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_event.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_event_listener.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_event_listener_info.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_event_target.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_html_all_collection.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_html_collection.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_node.h"
@@ -153,9 +154,8 @@ void ThreadDebugger::PromiseRejectionRevoked(v8::Local<v8::Context> context,
// TODO(mustaq): Fix the caller in v8/src.
void ThreadDebugger::beginUserGesture() {
- ExecutionContext* ec = CurrentExecutionContext(isolate_);
- Document* document = DynamicTo<Document>(ec);
- LocalFrame::NotifyUserActivation(document ? document->GetFrame() : nullptr);
+ auto* window = CurrentDOMWindow(isolate_);
+ LocalFrame::NotifyUserActivation(window ? window->GetFrame() : nullptr);
}
// TODO(mustaq): Fix the caller in v8/src.
diff --git a/chromium/third_party/blink/renderer/core/inspector/v8_inspector_string.cc b/chromium/third_party/blink/renderer/core/inspector/v8_inspector_string.cc
index 9a14767c953..8f41883ba48 100644
--- a/chromium/third_party/blink/renderer/core/inspector/v8_inspector_string.cc
+++ b/chromium/third_party/blink/renderer/core/inspector/v8_inspector_string.cc
@@ -7,6 +7,7 @@
#include <utility>
#include "third_party/blink/renderer/core/inspector/protocol/Protocol.h"
#include "third_party/blink/renderer/platform/wtf/text/base64.h"
+#include "third_party/inspector_protocol/crdtp/cbor.h"
namespace blink {
@@ -43,39 +44,6 @@ String ToCoreString(std::unique_ptr<v8_inspector::StringBuffer> buffer) {
}
namespace protocol {
-
-// static
-std::unique_ptr<protocol::Value> StringUtil::parseJSON(const String& string) {
- if (string.IsNull())
- return nullptr;
- if (string.Is8Bit()) {
- return parseJSONCharacters(
- reinterpret_cast<const uint8_t*>(string.Characters8()),
- string.length());
- }
- return parseJSONCharacters(
- reinterpret_cast<const uint16_t*>(string.Characters16()),
- string.length());
-}
-
-// static
-void StringUtil::builderAppendQuotedString(StringBuilder& builder,
- const String& str) {
- builder.Append('"');
- if (!str.IsEmpty()) {
- if (str.Is8Bit()) {
- escapeLatinStringForJSON(
- reinterpret_cast<const uint8_t*>(str.Characters8()), str.length(),
- &builder);
- } else {
- escapeWideStringForJSON(
- reinterpret_cast<const uint16_t*>(str.Characters16()), str.length(),
- &builder);
- }
- }
- builder.Append('"');
-}
-
// static
String StringUtil::fromUTF16LE(const uint16_t* data, size_t length) {
// Chromium doesn't support big endian architectures, so it's OK to cast here.
@@ -125,6 +93,11 @@ class BinaryBasedOnCachedData : public Binary::Impl {
};
} // namespace
+// Implements Serializable.
+void Binary::AppendSerialized(std::vector<uint8_t>* out) const {
+ crdtp::cbor::EncodeBinary(crdtp::span<uint8_t>(data(), size()), out);
+}
+
String Binary::toBase64() const {
return impl_ ? Base64Encode(*impl_) : String();
}
diff --git a/chromium/third_party/blink/renderer/core/inspector/v8_inspector_string.h b/chromium/third_party/blink/renderer/core/inspector/v8_inspector_string.h
index 9d0df48b2a9..e72d470fb5b 100644
--- a/chromium/third_party/blink/renderer/core/inspector/v8_inspector_string.h
+++ b/chromium/third_party/blink/renderer/core/inspector/v8_inspector_string.h
@@ -11,14 +11,14 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
-#include "third_party/blink/renderer/platform/wtf/decimal.h"
#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
-#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
-#include "third_party/blink/renderer/platform/wtf/text/string_to_number.h"
#include "third_party/blink/renderer/platform/wtf/text/string_view.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/inspector_protocol/crdtp/cbor.h"
+#include "third_party/inspector_protocol/crdtp/serializable.h"
+#include "third_party/inspector_protocol/crdtp/serializer_traits.h"
#include "v8/include/v8-inspector.h"
namespace blink {
@@ -33,53 +33,12 @@ CORE_EXPORT String ToCoreString(const v8_inspector::StringView&);
CORE_EXPORT String ToCoreString(std::unique_ptr<v8_inspector::StringBuffer>);
namespace protocol {
-
-class Value;
-
using String = WTF::String;
-using StringBuilder = WTF::StringBuilder;
-using ProtocolMessage = WebVector<uint8_t>;
class CORE_EXPORT StringUtil {
STATIC_ONLY(StringUtil);
public:
- static String substring(const String& s, size_t pos, size_t len) {
- return s.Substring(static_cast<wtf_size_t>(pos),
- static_cast<wtf_size_t>(len));
- }
- static String fromInteger(int64_t number) { return String::Number(number); }
- static String fromDouble(double number) {
- return Decimal::FromDouble(number).ToString();
- }
- static double toDouble(const char* s, size_t len, bool* ok) {
- return WTF::CharactersToDouble(reinterpret_cast<const LChar*>(s), len, ok);
- }
- static size_t find(const String& s, const char* needle) {
- return s.Find(needle);
- }
- static size_t find(const String& s, const String& needle) {
- return s.Find(needle);
- }
- static const size_t kNotFound = WTF::kNotFound;
- static void builderAppend(StringBuilder& builder, const String& s) {
- builder.Append(s);
- }
- static void builderAppend(StringBuilder& builder, UChar c) {
- builder.Append(c);
- }
- static void builderAppend(StringBuilder& builder, const char* s, size_t len) {
- builder.Append(s, static_cast<wtf_size_t>(len));
- }
- static void builderAppendQuotedString(StringBuilder&, const String&);
- static void builderReserve(StringBuilder& builder, uint64_t capacity) {
- builder.ReserveCapacity(static_cast<wtf_size_t>(capacity));
- }
- static String builderToString(StringBuilder& builder) {
- return builder.ToString();
- }
- static std::unique_ptr<protocol::Value> parseJSON(const String&);
-
static String fromUTF8(const uint8_t* data, size_t length) {
return String::FromUTF8(reinterpret_cast<const char*>(data), length);
}
@@ -101,7 +60,7 @@ class CORE_EXPORT StringUtil {
};
// A read-only sequence of uninterpreted bytes with reference-counted storage.
-class CORE_EXPORT Binary {
+class CORE_EXPORT Binary : public crdtp::Serializable {
public:
class Impl : public RefCounted<Impl> {
public:
@@ -113,6 +72,9 @@ class CORE_EXPORT Binary {
Binary() = default;
+ // Implements Serializable.
+ void AppendSerialized(std::vector<uint8_t>* out) const override;
+
const uint8_t* data() const { return impl_ ? impl_->data() : nullptr; }
size_t size() const { return impl_ ? impl_->size() : 0; }
@@ -145,4 +107,28 @@ struct hash<WTF::String> {
};
} // namespace std
+// See third_party/inspector_protocol/crdtp/serializer_traits.h.
+namespace crdtp {
+template <>
+struct SerializerTraits<WTF::String> {
+ static void Serialize(const WTF::String& str, std::vector<uint8_t>* out) {
+ if (str.length() == 0) {
+ cbor::EncodeString8(span<uint8_t>(nullptr, 0), out); // Empty string.
+ return;
+ }
+ if (str.Is8Bit()) {
+ cbor::EncodeFromLatin1(
+ span<uint8_t>(reinterpret_cast<const uint8_t*>(str.Characters8()),
+ str.length()),
+ out);
+ return;
+ }
+ cbor::EncodeFromUTF16(
+ span<uint16_t>(reinterpret_cast<const uint16_t*>(str.Characters16()),
+ str.length()),
+ out);
+ }
+};
+} // namespace crdtp
+
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_V8_INSPECTOR_STRING_H_
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 b1c87944bc0..27331049b52 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
@@ -87,9 +87,10 @@ WorkerInspectorController::WorkerInspectorController(
agent_ = MakeGarbageCollected<DevToolsAgent>(
this, inspected_frames_.Get(), probe_sink_.Get(),
std::move(inspector_task_runner), std::move(io_task_runner));
- agent_->BindReceiver(std::move(devtools_params->agent_host_remote),
- std::move(devtools_params->agent_receiver),
- thread->GetTaskRunner(TaskType::kInternalInspector));
+ agent_->BindReceiverForWorker(
+ std::move(devtools_params->agent_host_remote),
+ std::move(devtools_params->agent_receiver),
+ thread->GetTaskRunner(TaskType::kInternalInspector));
}
trace_event::AddEnabledStateObserver(this);
EmitTraceEvent();
@@ -122,7 +123,7 @@ void WorkerInspectorController::DetachSession(DevToolsSession*) {
thread_->GetWorkerBackingThread().BackingThread().RemoveTaskObserver(this);
}
-void WorkerInspectorController::InspectElement(const WebPoint&) {
+void WorkerInspectorController::InspectElement(const gfx::Point&) {
NOTREACHED();
}
@@ -178,7 +179,7 @@ void WorkerInspectorController::EmitTraceEvent() {
worker_thread_id_));
}
-void WorkerInspectorController::Trace(blink::Visitor* visitor) {
+void WorkerInspectorController::Trace(Visitor* visitor) {
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 75203c505c3..21585d1f3f5 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(blink::Visitor*);
+ void Trace(Visitor*);
CoreProbeSink* GetProbeSink() const { return probe_sink_.Get(); }
DevToolsAgent* GetDevToolsAgent() const { return agent_.Get(); }
@@ -92,7 +92,7 @@ class WorkerInspectorController final
// DevToolsAgent::Client implementation.
void AttachSession(DevToolsSession*, bool restore) override;
void DetachSession(DevToolsSession*) override;
- void InspectElement(const WebPoint&) override;
+ void InspectElement(const gfx::Point&) override;
void DebuggerTaskStarted() override;
void DebuggerTaskFinished() override;
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 856187de40d..7560f2a741c 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
@@ -15,8 +15,8 @@ ElementIntersectionObserverData::ElementIntersectionObserverData() = default;
IntersectionObservation* ElementIntersectionObserverData::GetObservationFor(
IntersectionObserver& observer) {
- auto i = intersection_observations_.find(&observer);
- if (i == intersection_observations_.end())
+ auto i = observations_.find(&observer);
+ if (i == observations_.end())
return nullptr;
return i->value;
}
@@ -24,68 +24,68 @@ IntersectionObservation* ElementIntersectionObserverData::GetObservationFor(
void ElementIntersectionObserverData::AddObservation(
IntersectionObservation& observation) {
DCHECK(observation.Observer());
- intersection_observations_.insert(observation.Observer(), &observation);
+ observations_.insert(observation.Observer(), &observation);
}
void ElementIntersectionObserverData::AddObserver(
IntersectionObserver& observer) {
- intersection_observers_.insert(&observer);
+ observers_.insert(&observer);
}
-bool ElementIntersectionObserverData::IsTargetOfImplicitRootObserver() const {
- for (auto& entry : intersection_observations_) {
- if (entry.key->RootIsImplicit())
- return true;
- }
- return false;
+void ElementIntersectionObserverData::RemoveObservation(
+ IntersectionObservation& observation) {
+ observations_.erase(observation.Observer());
}
-void ElementIntersectionObserverData::RemoveObservation(
+void ElementIntersectionObserverData::RemoveObserver(
IntersectionObserver& observer) {
- intersection_observations_.erase(&observer);
+ observers_.erase(&observer);
+}
+
+void ElementIntersectionObserverData::TrackWithController(
+ IntersectionObserverController& controller) {
+ for (auto& entry : observations_)
+ controller.AddTrackedObservation(*entry.value);
+ for (auto& observer : observers_)
+ controller.AddTrackedObserver(*observer);
+}
+
+void ElementIntersectionObserverData::StopTrackingWithController(
+ IntersectionObserverController& controller) {
+ for (auto& entry : observations_)
+ controller.RemoveTrackedObservation(*entry.value);
+ for (auto& observer : observers_)
+ controller.RemoveTrackedObserver(*observer);
}
bool ElementIntersectionObserverData::ComputeIntersectionsForTarget(
unsigned flags) {
bool needs_occlusion_tracking = false;
- for (auto& entry : intersection_observations_) {
+ for (auto& entry : observations_) {
needs_occlusion_tracking |= entry.key->NeedsOcclusionTracking();
entry.value->ComputeIntersection(flags);
}
return needs_occlusion_tracking;
}
-bool ElementIntersectionObserverData::ComputeIntersectionsForLifecycleUpdate(
- unsigned flags) {
- bool needs_occlusion_tracking = false;
-
- // Process explicit-root observers for which this element is root.
- for (auto& observer : intersection_observers_) {
- needs_occlusion_tracking |= observer->NeedsOcclusionTracking();
- if (flags & IntersectionObservation::kExplicitRootObserversNeedUpdate) {
- observer->ComputeIntersections(flags);
- }
- }
-
- // Process implicit-root observations for which this element is target.
- unsigned implicit_root_flags =
- flags & ~IntersectionObservation::kExplicitRootObserversNeedUpdate;
- needs_occlusion_tracking |=
- ComputeIntersectionsForTarget(implicit_root_flags);
- return needs_occlusion_tracking;
-}
-
bool ElementIntersectionObserverData::NeedsOcclusionTracking() const {
- for (auto& entry : intersection_observations_) {
+ for (auto& entry : observations_) {
if (entry.key->trackVisibility())
return true;
}
return false;
}
-void ElementIntersectionObserverData::Trace(blink::Visitor* visitor) {
- visitor->Trace(intersection_observations_);
- visitor->Trace(intersection_observers_);
+void ElementIntersectionObserverData::InvalidateCachedRects() {
+ for (auto& observer : observers_)
+ observer->InvalidateCachedRects();
+ for (auto& entry : observations_)
+ entry.value->InvalidateCachedRects();
+}
+
+void ElementIntersectionObserverData::Trace(Visitor* visitor) {
+ visitor->Trace(observations_);
+ visitor->Trace(observers_);
}
} // namespace blink
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 488a438fb95..641603fbca3 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
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_INTERSECTION_OBSERVER_ELEMENT_INTERSECTION_OBSERVER_DATA_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_INTERSECTION_OBSERVER_ELEMENT_INTERSECTION_OBSERVER_DATA_H_
+#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/dom_high_res_time_stamp.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -13,31 +14,39 @@ namespace blink {
class IntersectionObservation;
class IntersectionObserver;
+class IntersectionObserverController;
-class ElementIntersectionObserverData final
+class CORE_EXPORT ElementIntersectionObserverData final
: public GarbageCollected<ElementIntersectionObserverData>,
public NameClient {
public:
ElementIntersectionObserverData();
+ // If the argument observer is observing this Element, this method will return
+ // the observation.
IntersectionObservation* GetObservationFor(IntersectionObserver&);
+
+ // Add an implicit-root observation with this element as target.
void AddObservation(IntersectionObservation&);
+ // Add an explicit-root observer with this element as root.
void AddObserver(IntersectionObserver&);
- void RemoveObservation(IntersectionObserver&);
- bool IsTarget() const { return !intersection_observations_.IsEmpty(); }
- bool IsTargetOfImplicitRootObserver() const;
- bool IsRoot() const { return !intersection_observers_.IsEmpty(); }
+ void RemoveObservation(IntersectionObservation&);
+ void RemoveObserver(IntersectionObserver&);
+ bool IsEmpty() const {
+ return observations_.IsEmpty() && observers_.IsEmpty();
+ }
+ void TrackWithController(IntersectionObserverController&);
+ void StopTrackingWithController(IntersectionObserverController&);
+
// Run the IntersectionObserver algorithm for all observations for which this
// element is target.
bool ComputeIntersectionsForTarget(unsigned flags);
- // Run the IntersectionObserver algorithm for all implicit-root observations
- // for which this element is target; and all explicit-root observers for which
- // this element is root. Returns true if any observer needs occlusion
- // tracking.
- bool ComputeIntersectionsForLifecycleUpdate(unsigned flags);
bool NeedsOcclusionTracking() const;
+ // Indicates that geometry information cached during the previous run of the
+ // algorithm is invalid and must be recomputed.
+ void InvalidateCachedRects();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
const char* NameInHeapSnapshot() const override {
return "ElementIntersectionObserverData";
}
@@ -45,11 +54,11 @@ class ElementIntersectionObserverData final
private:
// IntersectionObservations for which the Node owning this data is target.
HeapHashMap<Member<IntersectionObserver>, Member<IntersectionObservation>>
- intersection_observations_;
+ observations_;
// IntersectionObservers for which the Node owning this data is root.
// Weak because once an observer is unreachable from javascript and has no
// active observations, it should be allowed to die.
- HeapHashSet<WeakMember<IntersectionObserver>> intersection_observers_;
+ HeapHashSet<WeakMember<IntersectionObserver>> observers_;
};
} // namespace blink
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 ac40b7c5ef5..586abe8f69a 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
@@ -17,6 +17,7 @@
#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/paint/paint_layer.h"
+#include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h"
namespace blink {
@@ -121,7 +122,8 @@ PhysicalRect InitializeRootRect(const LayoutObject* root,
const Vector<Length>& margin) {
DCHECK(margin.IsEmpty() || margin.size() == 4);
PhysicalRect result;
- if (root->IsLayoutView() && root->GetDocument().IsInMainFrame()) {
+ 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
@@ -130,7 +132,7 @@ PhysicalRect InitializeRootRect(const LayoutObject* root,
// 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 = ToLayoutView(root)->OverflowClipRect(PhysicalOffset());
+ result = layout_view->OverflowClipRect(PhysicalOffset());
} else if (root->IsBox() && root->HasOverflowClip()) {
result = ToLayoutBox(root)->PhysicalContentBoxRect();
} else {
@@ -157,12 +159,21 @@ LayoutObject* GetTargetLayoutObject(const Element& target_element) {
return target;
}
+bool CanUseGeometryMapper(const LayoutObject* object) {
+ // This checks for cases where we didn't just complete a successful lifecycle
+ // update, e.g., if the frame is throttled.
+ LayoutView* layout_view = object->GetDocument().GetLayoutView();
+ return layout_view && !layout_view->NeedsPaintPropertyUpdate() &&
+ !layout_view->DescendantNeedsPaintPropertyUpdate();
+}
+
static const unsigned kConstructorFlagsMask =
IntersectionGeometry::kShouldReportRootBounds |
IntersectionGeometry::kShouldComputeVisibility |
IntersectionGeometry::kShouldTrackFractionOfRoot |
IntersectionGeometry::kShouldUseReplacedContentRect |
- IntersectionGeometry::kShouldConvertToCSSPixels;
+ IntersectionGeometry::kShouldConvertToCSSPixels |
+ IntersectionGeometry::kShouldUseCachedRects;
} // namespace
@@ -178,100 +189,157 @@ IntersectionGeometry::RootGeometry::RootGeometry(const LayoutObject* root,
root_to_document_transform = transform_state.AccumulatedTransform();
}
-// If root_element is non-null, it is treated as the explicit root of an
+// If root_node is non-null, it is treated as the explicit root of an
// IntersectionObserver; if it is valid, its LayoutObject is returned.
//
-// If root_element is null, returns the object to be used as the implicit root
+// If root_node is null, returns the object to be used as the implicit root
// for a given target.
//
// https://w3c.github.io/IntersectionObserver/#dom-intersectionobserver-root
const LayoutObject* IntersectionGeometry::GetRootLayoutObjectForTarget(
- const Element* root_element,
- LayoutObject* target) {
- if (!root_element)
+ const Node* root_node,
+ LayoutObject* target,
+ bool check_containing_block_chain) {
+ if (!root_node)
return target ? LocalRootView(*target) : nullptr;
- if (!root_element->isConnected())
+ if (!root_node->isConnected())
return nullptr;
LayoutObject* root = nullptr;
if (RuntimeEnabledFeatures::
IntersectionObserverDocumentScrollingElementRootEnabled() &&
- root_element == root_element->GetDocument().scrollingElement()) {
- root = root_element->GetDocument().GetLayoutView();
+ root_node->IsDocumentNode()) {
+ root = To<Document>(root_node)->GetLayoutView();
} else {
- root = root_element->GetLayoutObject();
- if (target && !IsContainingBlockChainDescendant(target, root))
+ root = root_node->GetLayoutObject();
+ if (target && check_containing_block_chain &&
+ !IsContainingBlockChainDescendant(target, root)) {
root = nullptr;
+ }
}
return root;
}
-IntersectionGeometry::IntersectionGeometry(const Element* root_element,
+IntersectionGeometry::IntersectionGeometry(const Node* root_node,
const Element& target_element,
const Vector<Length>& root_margin,
const Vector<float>& thresholds,
- unsigned flags)
+ unsigned flags,
+ CachedRects* cached_rects)
: flags_(flags & kConstructorFlagsMask),
intersection_ratio_(0),
threshold_index_(0) {
- if (!root_element)
+ if (cached_rects)
+ cached_rects->valid = false;
+ if (!root_node)
flags_ |= kRootIsImplicit;
LayoutObject* target = GetTargetLayoutObject(target_element);
if (!target)
return;
- const LayoutObject* root = GetRootLayoutObjectForTarget(root_element, target);
+ const LayoutObject* root =
+ GetRootLayoutObjectForTarget(root_node, target, !ShouldUseCachedRects());
if (!root)
return;
RootGeometry root_geometry(root, root_margin);
- ComputeGeometry(root_geometry, root, target, thresholds);
+ ComputeGeometry(root_geometry, root, target, thresholds, cached_rects);
}
IntersectionGeometry::IntersectionGeometry(const RootGeometry& root_geometry,
- const Element& explicit_root,
+ const Node& explicit_root,
const Element& target_element,
const Vector<float>& thresholds,
- unsigned flags)
+ unsigned flags,
+ CachedRects* cached_rects)
: flags_(flags & kConstructorFlagsMask),
intersection_ratio_(0),
threshold_index_(0) {
+ if (cached_rects)
+ cached_rects->valid = false;
LayoutObject* target = GetTargetLayoutObject(target_element);
if (!target)
return;
- const LayoutObject* root =
- GetRootLayoutObjectForTarget(&explicit_root, target);
+ const LayoutObject* root = GetRootLayoutObjectForTarget(
+ &explicit_root, target, !ShouldUseCachedRects());
if (!root)
return;
- ComputeGeometry(root_geometry, root, target, thresholds);
+ ComputeGeometry(root_geometry, root, target, thresholds, cached_rects);
}
-IntersectionGeometry::~IntersectionGeometry() = default;
-
void IntersectionGeometry::ComputeGeometry(const RootGeometry& root_geometry,
const LayoutObject* root,
const LayoutObject* target,
- const Vector<float>& thresholds) {
+ const Vector<float>& thresholds,
+ CachedRects* cached_rects) {
+ DCHECK(cached_rects || !ShouldUseCachedRects());
// Initially:
// target_rect_ is in target's coordinate system
- // intersection_rect_ is in target's coordinate system
// root_rect_ is in root's coordinate system
- target_rect_ = InitializeTargetRect(target, flags_);
- intersection_rect_ = target_rect_;
+ // The coordinate system for unclipped_intersection_rect_ depends on whether
+ // or not we can use previously cached geometry...
+ if (ShouldUseCachedRects()) {
+ target_rect_ = cached_rects->local_target_rect;
+ // The cached intersection rect has already been mapped/clipped up to the
+ // root, except that the root's scroll offset and overflow clip have not
+ // been applied.
+ unclipped_intersection_rect_ =
+ cached_rects->unscrolled_unclipped_intersection_rect;
+ } else {
+ target_rect_ = InitializeTargetRect(target, flags_);
+ // 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.
+ unclipped_intersection_rect_ = target_rect_;
+ }
+ if (cached_rects)
+ cached_rects->local_target_rect = target_rect_;
root_rect_ = root_geometry.local_root_rect;
- // This maps intersection_rect_ up to root's coordinate system
bool does_intersect =
- ClipToRoot(root, target, root_rect_, intersection_rect_);
-
- // Map target_rect_ to absolute coordinates for target's document
- target_rect_ = target->LocalToAncestorRect(target_rect_, nullptr);
+ ClipToRoot(root, target, root_rect_, unclipped_intersection_rect_,
+ intersection_rect_, cached_rects);
+
+ // Map target_rect_ to absolute coordinates for target's document.
+ // GeometryMapper is faster, so we use it when possible; otherwise, fall back
+ // to LocalToAncestorRect.
+ PropertyTreeState container_properties = PropertyTreeState::Uninitialized();
+ const LayoutObject* property_container =
+ CanUseGeometryMapper(target)
+ ? target->GetPropertyContainer(nullptr, &container_properties)
+ : nullptr;
+ if (property_container) {
+ LayoutRect target_layout_rect = target_rect_.ToLayoutRect();
+ target_layout_rect.Move(
+ target->FirstFragment().PaintOffset().ToLayoutSize());
+ GeometryMapper::SourceToDestinationRect(container_properties.Transform(),
+ target->GetDocument()
+ .GetLayoutView()
+ ->FirstFragment()
+ .LocalBorderBoxProperties()
+ .Transform(),
+ target_layout_rect);
+ target_rect_ = PhysicalRect(target_layout_rect);
+ } else {
+ target_rect_ = target->LocalToAncestorRect(target_rect_, nullptr);
+ }
if (does_intersect) {
if (RootIsImplicit()) {
+ // Generate matrix to transform from the space of the implicit root to
+ // the absolute coordinates of the target document.
+ TransformState implicit_root_to_target_document_transform(
+ TransformState::kUnapplyInverseTransformDirection);
+ target->GetDocument().GetLayoutView()->MapAncestorToLocal(
+ nullptr, implicit_root_to_target_document_transform,
+ kTraverseDocumentBoundaries | kApplyRemoteRootFrameOffset);
+ TransformationMatrix matrix =
+ implicit_root_to_target_document_transform.AccumulatedTransform()
+ .Inverse();
+ intersection_rect_ = PhysicalRect::EnclosingRect(
+ matrix.ProjectQuad(FloatRect(intersection_rect_)).BoundingBox());
+ unclipped_intersection_rect_ = PhysicalRect::EnclosingRect(
+ matrix.ProjectQuad(FloatRect(unclipped_intersection_rect_))
+ .BoundingBox());
// intersection_rect_ is in the coordinate system of the implicit root;
// map it down the to absolute coordinates for the target's document.
- intersection_rect_ =
- target->GetDocument().GetLayoutView()->AbsoluteToLocalRect(
- intersection_rect_,
- kTraverseDocumentBoundaries | kApplyRemoteRootFrameOffset);
} else {
// intersection_rect_ is in root's coordinate system; map it up to
// absolute coordinates for target's containing document (which is the
@@ -280,6 +348,10 @@ void IntersectionGeometry::ComputeGeometry(const RootGeometry& root_geometry,
root_geometry.root_to_document_transform
.MapQuad(FloatQuad(FloatRect(intersection_rect_)))
.BoundingBox());
+ unclipped_intersection_rect_ = PhysicalRect::EnclosingRect(
+ root_geometry.root_to_document_transform
+ .MapQuad(FloatQuad(FloatRect(unclipped_intersection_rect_)))
+ .BoundingBox());
}
} else {
intersection_rect_ = PhysicalRect();
@@ -326,8 +398,9 @@ void IntersectionGeometry::ComputeGeometry(const RootGeometry& root_geometry,
threshold_index_ = 0;
}
if (IsIntersecting() && ShouldComputeVisibility() &&
- ComputeIsVisible(target, target_rect_))
+ ComputeIsVisible(target, target_rect_)) {
flags_ |= kIsVisible;
+ }
if (flags_ & kShouldConvertToCSSPixels) {
FloatRect target_float_rect(target_rect_);
@@ -340,49 +413,82 @@ void IntersectionGeometry::ComputeGeometry(const RootGeometry& root_geometry,
AdjustForAbsoluteZoom::AdjustFloatRect(root_float_rect, *root);
root_rect_ = PhysicalRect::EnclosingRect(root_float_rect);
}
+
+ if (cached_rects)
+ cached_rects->valid = true;
}
bool IntersectionGeometry::ClipToRoot(const LayoutObject* root,
const LayoutObject* target,
const PhysicalRect& root_rect,
- PhysicalRect& intersection_rect) {
+ PhysicalRect& unclipped_intersection_rect,
+ PhysicalRect& intersection_rect,
+ CachedRects* cached_rects) {
// Map and clip rect into root element coordinates.
// TODO(szager): the writing mode flipping needs a test.
const LayoutBox* local_ancestor = nullptr;
if (!RootIsImplicit() || root->GetDocument().IsInMainFrame())
local_ancestor = ToLayoutBox(root);
- const LayoutView* layout_view = target->GetDocument().GetLayoutView();
-
- unsigned flags = kDefaultVisualRectFlags | kEdgeInclusive;
- if (!layout_view->NeedsPaintPropertyUpdate() &&
- !layout_view->DescendantNeedsPaintPropertyUpdate()) {
+ unsigned flags = kDefaultVisualRectFlags | kEdgeInclusive |
+ kDontApplyMainFrameOverflowClip;
+ if (CanUseGeometryMapper(target))
flags |= kUseGeometryMapper;
+
+ bool does_intersect;
+ if (ShouldUseCachedRects()) {
+ does_intersect = cached_rects->does_intersect;
+ } else {
+ does_intersect = target->MapToVisualRectInAncestorSpace(
+ local_ancestor, unclipped_intersection_rect,
+ static_cast<VisualRectFlags>(flags));
}
- bool does_intersect = target->MapToVisualRectInAncestorSpace(
- local_ancestor, intersection_rect, static_cast<VisualRectFlags>(flags));
-
- // Note that this early-return for (!local_ancestor) skips clipping to the
- // root_rect. That's ok because the only scenario where local_ancestor is
- // null is an implicit root and running inside an OOPIF, in which case there
- // can't be any root margin applied to root_rect (root margin is disallowed
- // for implicit-root cross-origin observation). So the default behavior of
- // MapToVisualRectInAncestorSpace will have already done the right thing WRT
- // clipping to the implicit root.
- if (!does_intersect || !local_ancestor)
- return does_intersect;
-
- if (local_ancestor->HasOverflowClip()) {
- intersection_rect.Move(
- -PhysicalOffset(LayoutPoint(local_ancestor->ScrollOrigin()) +
- local_ancestor->PixelSnappedScrolledContentOffset()));
+ if (cached_rects) {
+ cached_rects->unscrolled_unclipped_intersection_rect =
+ unclipped_intersection_rect;
+ cached_rects->does_intersect = does_intersect;
}
- LayoutRect root_clip_rect = root_rect.ToLayoutRect();
- // TODO(szager): This flipping seems incorrect because root_rect is already
- // physical.
- local_ancestor->DeprecatedFlipForWritingMode(root_clip_rect);
- return does_intersect &
- intersection_rect.InclusiveIntersect(PhysicalRect(root_clip_rect));
+
+ intersection_rect = PhysicalRect();
+
+ // If the target intersects with the unclipped root, calculate the clipped
+ // intersection.
+ if (does_intersect) {
+ intersection_rect = unclipped_intersection_rect;
+ if (local_ancestor) {
+ if (local_ancestor->HasOverflowClip()) {
+ PhysicalOffset scroll_offset = -PhysicalOffset(
+ LayoutPoint(local_ancestor->ScrollOrigin()) +
+ local_ancestor->PixelSnappedScrolledContentOffset());
+ intersection_rect.Move(scroll_offset);
+ unclipped_intersection_rect.Move(scroll_offset);
+ }
+ LayoutRect root_clip_rect = root_rect.ToLayoutRect();
+ // TODO(szager): This flipping seems incorrect because root_rect is
+ // already physical.
+ local_ancestor->DeprecatedFlipForWritingMode(root_clip_rect);
+ does_intersect &=
+ intersection_rect.InclusiveIntersect(PhysicalRect(root_clip_rect));
+ } else {
+ // Note that we don't clip to root_rect here. That's ok because
+ // (!local_ancestor) implies that the root is implicit and the
+ // main frame is remote, in which case there can't be any root margin
+ // applied to root_rect (root margin is disallowed for implicit-root
+ // cross-origin observation). We still need to apply the remote main
+ // frame's overflow clip here, because the
+ // kDontApplyMainFrameOverflowClip flag above, means it hasn't been
+ // done yet.
+ LocalFrame* local_root_frame = root->GetDocument().GetFrame();
+ IntRect clip_rect(local_root_frame->RemoteViewportIntersection());
+ // Map clip_rect from the coordinate system of the local root frame to
+ // the coordinate system of the remote main frame.
+ clip_rect.MoveBy(IntPoint(local_root_frame->RemoteViewportOffset()));
+ does_intersect &=
+ intersection_rect.InclusiveIntersect(PhysicalRect(clip_rect));
+ }
+ }
+
+ return does_intersect;
}
unsigned IntersectionGeometry::FirstThresholdGreaterThan(
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 e91299541a0..be2d8bc20dc 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
@@ -17,8 +17,9 @@ namespace blink {
class Element;
class LayoutObject;
+class Node;
-// Computes the intersection between an ancestor (root) element and a
+// Computes the intersection between an ancestor (root) node and a
// descendant (target) element, with overflow and CSS clipping applied.
// Optionally also checks whether the target is occluded or has visual
// effects applied.
@@ -34,10 +35,11 @@ class CORE_EXPORT IntersectionGeometry {
kShouldTrackFractionOfRoot = 1 << 2,
kShouldUseReplacedContentRect = 1 << 3,
kShouldConvertToCSSPixels = 1 << 4,
+ kShouldUseCachedRects = 1 << 5,
// These flags will be computed
- kRootIsImplicit = 1 << 5,
- kIsVisible = 1 << 6
+ kRootIsImplicit = 1 << 6,
+ kIsVisible = 1 << 7
};
struct RootGeometry {
@@ -52,24 +54,39 @@ class CORE_EXPORT IntersectionGeometry {
TransformationMatrix root_to_document_transform;
};
+ struct CachedRects {
+ // Target's bounding rect in the target's coordinate space
+ PhysicalRect local_target_rect;
+ // Target rect mapped up to the root's space, with intermediate clips
+ // applied, but without applying the root's clip or scroll offset.
+ PhysicalRect unscrolled_unclipped_intersection_rect;
+ // True iff unscrolled_unclipped_intersection_rect actually intersects the
+ // root, as defined by edge-inclusive intersection rules.
+ bool does_intersect;
+ // Invalidation flag
+ bool valid;
+ };
+
static const LayoutObject* GetRootLayoutObjectForTarget(
- const Element* root_element,
- LayoutObject* target);
+ const Node* root_node,
+ LayoutObject* target,
+ bool check_containing_block_chain);
- IntersectionGeometry(const Element* root,
+ IntersectionGeometry(const Node* root,
const Element& target,
const Vector<Length>& root_margin,
const Vector<float>& thresholds,
- unsigned flags);
+ unsigned flags,
+ CachedRects* cached_rects = nullptr);
IntersectionGeometry(const RootGeometry& root_geometry,
- const Element& explicit_root,
+ const Node& explicit_root,
const Element& target,
const Vector<float>& thresholds,
- unsigned flags);
+ unsigned flags,
+ CachedRects* cached_rects = nullptr);
IntersectionGeometry(const IntersectionGeometry&) = default;
- ~IntersectionGeometry();
bool ShouldReportRootBounds() const {
return flags_ & kShouldReportRootBounds;
@@ -83,6 +100,12 @@ class CORE_EXPORT IntersectionGeometry {
PhysicalRect TargetRect() const { return target_rect_; }
PhysicalRect IntersectionRect() const { return intersection_rect_; }
+
+ // The intersection rect without applying viewport clipping.
+ PhysicalRect UnclippedIntersectionRect() const {
+ return unclipped_intersection_rect_;
+ }
+
PhysicalRect RootRect() const { return root_rect_; }
IntRect IntersectionIntRect() const {
@@ -99,21 +122,26 @@ class CORE_EXPORT IntersectionGeometry {
bool IsVisible() const { return flags_ & kIsVisible; }
private:
+ bool ShouldUseCachedRects() const { return flags_ & kShouldUseCachedRects; }
void ComputeGeometry(const RootGeometry& root_geometry,
const LayoutObject* root,
const LayoutObject* target,
- const Vector<float>& thresholds);
+ const Vector<float>& thresholds,
+ CachedRects* cached_rects);
// Map intersection_rect from the coordinate system of the target to the
// coordinate system of the root, applying intervening clips.
bool ClipToRoot(const LayoutObject* root,
const LayoutObject* target,
const PhysicalRect& root_rect,
- PhysicalRect& intersection_rect);
+ PhysicalRect& unclipped_intersection_rect,
+ PhysicalRect& intersection_rect,
+ CachedRects* cached_rects = nullptr);
unsigned FirstThresholdGreaterThan(float ratio,
const Vector<float>& thresholds) const;
PhysicalRect target_rect_;
PhysicalRect intersection_rect_;
+ PhysicalRect unclipped_intersection_rect_;
PhysicalRect root_rect_;
unsigned flags_;
double intersection_ratio_;
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 ed942cd8408..1e58a306d96 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
@@ -9,8 +9,11 @@
#include "third_party/blink/renderer/core/intersection_observer/intersection_geometry.h"
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer.h"
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.h"
+#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
-#include "third_party/blink/renderer/core/layout/layout_object.h"
+#include "third_party/blink/renderer/core/layout/layout_box.h"
+#include "third_party/blink/renderer/core/layout/layout_view.h"
+#include "third_party/blink/renderer/core/paint/paint_layer.h"
namespace blink {
@@ -33,7 +36,10 @@ IntersectionObservation::IntersectionObservation(IntersectionObserver& observer,
// Note that the spec says the initial value of last_threshold_index_
// should be -1, but since last_threshold_index_ is unsigned, we use a
// different sentinel value.
- last_threshold_index_(kMaxThresholdIndex - 1) {}
+ last_threshold_index_(kMaxThresholdIndex - 1) {
+ if (!observer.RootIsImplicit())
+ cached_rects_ = std::make_unique<IntersectionGeometry::CachedRects>();
+}
void IntersectionObservation::ComputeIntersection(
const IntersectionGeometry::RootGeometry& root_geometry,
@@ -43,7 +49,8 @@ void IntersectionObservation::ComputeIntersection(
DCHECK(observer_->root());
unsigned geometry_flags = GetIntersectionGeometryFlags(compute_flags);
IntersectionGeometry geometry(root_geometry, *observer_->root(), *Target(),
- observer_->thresholds(), geometry_flags);
+ observer_->thresholds(), geometry_flags,
+ cached_rects_.get());
ProcessIntersectionGeometry(geometry);
}
@@ -69,25 +76,24 @@ void IntersectionObservation::Disconnect() {
DCHECK(target_->IntersectionObserverData());
ElementIntersectionObserverData* observer_data =
target_->IntersectionObserverData();
- observer_data->RemoveObservation(*Observer());
- // We track connected elements that are either the root of an explicit root
- // observer, or the target of an implicit root observer. If the target was
- // previously being tracked, but no longer needs to be tracked, then remove
- // it.
- if (target_->isConnected() && Observer()->RootIsImplicit() &&
- !observer_data->IsTargetOfImplicitRootObserver() &&
- !observer_data->IsRoot()) {
+ observer_data->RemoveObservation(*this);
+ if (target_->isConnected()) {
IntersectionObserverController* controller =
target_->GetDocument().GetIntersectionObserverController();
if (controller)
- controller->RemoveTrackedElement(*target_);
+ controller->RemoveTrackedObservation(*this);
}
}
entries_.clear();
observer_.Clear();
}
-void IntersectionObservation::Trace(blink::Visitor* visitor) {
+void IntersectionObservation::InvalidateCachedRects() {
+ if (cached_rects_)
+ cached_rects_->valid = false;
+}
+
+void IntersectionObservation::Trace(Visitor* visitor) {
visitor->Trace(observer_);
visitor->Trace(entries_);
visitor->Trace(target_);
@@ -127,6 +133,47 @@ bool IntersectionObservation::ShouldCompute(unsigned flags) {
return true;
}
+bool IntersectionObservation::CanUseCachedRects() const {
+ if (!cached_rects_ || !cached_rects_->valid ||
+ !observer_->CanUseCachedRects()) {
+ return false;
+ }
+ // Cached rects can only be used if there are no scrollable objects in the
+ // hierarchy between target and root (a scrollable root is ok). The reason is
+ // that a scroll change in an intermediate scroller would change the
+ // intersection geometry, but it would not properly trigger an invalidation of
+ // the cached rects.
+ if (LayoutObject* target = target_->GetLayoutObject()) {
+ PaintLayer* root_layer = target->GetDocument().GetLayoutView()->Layer();
+ if (!root_layer)
+ return false;
+ if (!root_layer->NeedsCompositingInputsUpdate() &&
+ !root_layer->ChildNeedsCompositingInputsUpdate()) {
+ const PaintLayer* painting_layer = target->PaintingLayer();
+ if (!painting_layer)
+ return false;
+ const PaintLayer* scrolling_layer = nullptr;
+ if (&painting_layer->GetLayoutObject() == target) {
+ scrolling_layer = painting_layer->AncestorScrollingLayer();
+ } else if (painting_layer->ScrollsOverflow()) {
+ scrolling_layer = painting_layer;
+ } else {
+ scrolling_layer = painting_layer->AncestorScrollingLayer();
+ }
+ if (scrolling_layer &&
+ scrolling_layer->GetLayoutObject().GetNode() == observer_->root()) {
+ return true;
+ }
+ } else {
+ if (LayoutBox* scroller = target->EnclosingScrollableBox()) {
+ if (scroller->GetNode() == observer_->root())
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
unsigned IntersectionObservation::GetIntersectionGeometryFlags(
unsigned compute_flags) const {
bool report_root_bounds = observer_->AlwaysReportRootBounds() ||
@@ -139,6 +186,8 @@ unsigned IntersectionObservation::GetIntersectionGeometryFlags(
geometry_flags |= IntersectionGeometry::kShouldComputeVisibility;
if (Observer()->trackFractionOfRoot())
geometry_flags |= IntersectionGeometry::kShouldTrackFractionOfRoot;
+ if (CanUseCachedRects())
+ geometry_flags |= IntersectionGeometry::kShouldUseCachedRects;
return geometry_flags;
}
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 8b4a8ebd909..9aeabf8de67 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
@@ -5,20 +5,22 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_INTERSECTION_OBSERVER_INTERSECTION_OBSERVATION_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_INTERSECTION_OBSERVER_INTERSECTION_OBSERVATION_H_
+#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/dom_high_res_time_stamp.h"
-#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.h"
+#include "third_party/blink/renderer/core/intersection_observer/intersection_geometry.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
class Element;
class IntersectionObserver;
+class IntersectionObserverEntry;
// IntersectionObservation represents the result of calling
// IntersectionObserver::observe(target) for some target element; it tracks the
// intersection between a single target element and the IntersectionObserver's
// root. It is an implementation-internal class without any exposed interface.
-class IntersectionObservation final
+class CORE_EXPORT IntersectionObservation final
: public GarbageCollected<IntersectionObservation> {
public:
// Flags that drive the behavior of the ComputeIntersections() method. For an
@@ -38,6 +40,9 @@ class IntersectionObservation final
// the computation will run even if the previous run happened within the
// delay parameter.
kIgnoreDelay = 1 << 3,
+ // If this bit is set, we can skip tracking the sticky frame during
+ // UpdateViewportIntersectionsForSubtree.
+ kCanSkipStickyFrameTracking = 1 << 4,
};
IntersectionObservation(IntersectionObserver&, Element&);
@@ -51,11 +56,15 @@ class IntersectionObservation final
unsigned flags);
void TakeRecords(HeapVector<Member<IntersectionObserverEntry>>&);
void Disconnect();
+ void InvalidateCachedRects();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
+
+ bool CanUseCachedRectsForTesting() const { return CanUseCachedRects(); }
private:
bool ShouldCompute(unsigned flags);
+ bool CanUseCachedRects() const;
unsigned GetIntersectionGeometryFlags(unsigned compute_flags) const;
// Inspect the geometry to see if there has been a transition event; if so,
// generate a notification and schedule it for delivery.
@@ -70,6 +79,8 @@ class IntersectionObservation final
HeapVector<Member<IntersectionObserverEntry>> entries_;
DOMHighResTimeStamp last_run_time_;
+ std::unique_ptr<IntersectionGeometry::CachedRects> cached_rects_;
+
unsigned last_is_visible_ : 1;
unsigned needs_update_ : 1;
unsigned last_threshold_index_ : 30;
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 e13296c8c40..c2a12af4581 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
@@ -12,6 +12,7 @@
#include "third_party/blink/public/mojom/web_feature/web_feature.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_callback.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_delegate.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_init.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_token_range.h"
#include "third_party/blink/renderer/core/css/parser/css_tokenizer.h"
#include "third_party/blink/renderer/core/dom/element.h"
@@ -23,7 +24,7 @@
#include "third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.h"
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.h"
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_delegate.h"
-#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_init.h"
+#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -59,7 +60,7 @@ class IntersectionObserverDelegateImpl final
ExecutionContext* GetExecutionContext() const override { return context_; }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
IntersectionObserverDelegate::Trace(visitor);
visitor->Trace(context_);
}
@@ -159,7 +160,12 @@ IntersectionObserver* IntersectionObserver::Create(
const IntersectionObserverInit* observer_init,
IntersectionObserverDelegate& delegate,
ExceptionState& exception_state) {
- Element* root = observer_init->root();
+ Node* root = nullptr;
+ if (observer_init->root().IsElement()) {
+ root = observer_init->root().GetAsElement();
+ } else if (observer_init->root().IsDocument()) {
+ root = observer_init->root().GetAsDocument();
+ }
DOMHighResTimeStamp delay = 0;
bool track_visibility = false;
@@ -222,7 +228,7 @@ IntersectionObserver* IntersectionObserver::Create(
ExceptionState& exception_state) {
IntersectionObserverDelegateImpl* intersection_observer_delegate =
MakeGarbageCollected<IntersectionObserverDelegateImpl>(
- document, std::move(callback), behavior);
+ document->GetExecutionContext(), std::move(callback), behavior);
return MakeGarbageCollected<IntersectionObserver>(
*intersection_observer_delegate, nullptr, root_margin, thresholds,
semantics, delay, track_visibility, always_report_root_bounds);
@@ -230,24 +236,25 @@ IntersectionObserver* IntersectionObserver::Create(
IntersectionObserver::IntersectionObserver(
IntersectionObserverDelegate& delegate,
- Element* root,
+ Node* root,
const Vector<Length>& root_margin,
const Vector<float>& thresholds,
ThresholdInterpretation semantics,
DOMHighResTimeStamp delay,
bool track_visibility,
bool always_report_root_bounds)
- : ContextClient(delegate.GetExecutionContext()),
+ : ExecutionContextClient(delegate.GetExecutionContext()),
delegate_(&delegate),
root_(root),
thresholds_(thresholds),
delay_(delay),
root_margin_(4, Length::Fixed(0)),
root_is_implicit_(root ? 0 : 1),
- track_visibility_(track_visibility ? 1 : 0),
+ track_visibility_(track_visibility),
track_fraction_of_root_(semantics == kFractionOfRoot),
- always_report_root_bounds_(always_report_root_bounds ? 1 : 0),
- needs_delivery_(0) {
+ always_report_root_bounds_(always_report_root_bounds),
+ needs_delivery_(0),
+ can_use_cached_rects_(0) {
switch (root_margin.size()) {
case 0:
break;
@@ -275,19 +282,24 @@ IntersectionObserver::IntersectionObserver(
break;
}
if (root) {
- root->EnsureIntersectionObserverData().AddObserver(*this);
- root->GetDocument()
- .EnsureIntersectionObserverController()
- .AddTrackedElement(*root, track_visibility);
+ if (root->IsDocumentNode()) {
+ To<Document>(root)
+ ->EnsureDocumentExplicitRootIntersectionObserverData()
+ .AddObserver(*this);
+ } else {
+ DCHECK(root->IsElementNode());
+ To<Element>(root)->EnsureIntersectionObserverData().AddObserver(*this);
+ }
}
}
void IntersectionObserver::ProcessCustomWeakness(const WeakCallbackInfo& info) {
- if (RootIsImplicit() || (root() && info.IsHeapObjectAlive(root())))
- return;
- DummyExceptionStateForTesting exception_state;
- disconnect(exception_state);
- root_ = nullptr;
+ // For explicit-root observers, if the root element disappears for any reason,
+ // any remaining obsevations must be dismantled.
+ if (root() && !info.IsHeapObjectAlive(root()))
+ root_ = nullptr;
+ if (!RootIsImplicit() && !root())
+ disconnect();
}
bool IntersectionObserver::RootIsValid() const {
@@ -313,12 +325,16 @@ void IntersectionObserver::observe(Element* target,
MakeGarbageCollected<IntersectionObservation>(*this, *target);
target->EnsureIntersectionObserverData().AddObservation(*observation);
observations_.insert(observation);
+ if (root() && root()->isConnected()) {
+ root()
+ ->GetDocument()
+ .EnsureIntersectionObserverController()
+ .AddTrackedObserver(*this);
+ }
if (target->isConnected()) {
- if (RootIsImplicit()) {
- target->GetDocument()
- .EnsureIntersectionObserverController()
- .AddTrackedElement(*target, track_visibility_);
- }
+ target->GetDocument()
+ .EnsureIntersectionObserverController()
+ .AddTrackedObservation(*observation);
if (LocalFrameView* frame_view = target_frame->View()) {
// The IntersectionObsever spec requires that at least one observation
// be recorded after observe() is called, even if the frame is throttled.
@@ -347,12 +363,24 @@ void IntersectionObserver::unobserve(Element* target,
observation->Disconnect();
observations_.erase(observation);
+ if (root() && root()->isConnected() && observations_.IsEmpty()) {
+ root()
+ ->GetDocument()
+ .EnsureIntersectionObserverController()
+ .RemoveTrackedObserver(*this);
+ }
}
void IntersectionObserver::disconnect(ExceptionState& exception_state) {
for (auto& observation : observations_)
observation->Disconnect();
observations_.clear();
+ if (root() && root()->isConnected()) {
+ root()
+ ->GetDocument()
+ .EnsureIntersectionObserverController()
+ .RemoveTrackedObserver(*this);
+ }
}
HeapVector<Member<IntersectionObserverEntry>> IntersectionObserver::takeRecords(
@@ -389,11 +417,9 @@ DOMHighResTimeStamp IntersectionObserver::GetEffectiveDelay() const {
}
DOMHighResTimeStamp IntersectionObserver::GetTimeStamp() const {
- if (Document* document = To<Document>(delegate_->GetExecutionContext())) {
- if (LocalDOMWindow* dom_window = document->domWindow())
- return DOMWindowPerformance::performance(*dom_window)->now();
- }
- return -1;
+ return DOMWindowPerformance::performance(
+ *To<LocalDOMWindow>(delegate_->GetExecutionContext()))
+ ->now();
}
bool IntersectionObserver::ComputeIntersections(unsigned flags) {
@@ -401,7 +427,8 @@ bool IntersectionObserver::ComputeIntersections(unsigned flags) {
if (!RootIsValid() || !GetExecutionContext() || observations_.IsEmpty())
return false;
IntersectionGeometry::RootGeometry root_geometry(
- IntersectionGeometry::GetRootLayoutObjectForTarget(root(), nullptr),
+ IntersectionGeometry::GetRootLayoutObjectForTarget(root(), nullptr,
+ false),
root_margin_);
HeapVector<Member<IntersectionObservation>> observations_to_process;
// TODO(szager): Is this copy necessary?
@@ -409,6 +436,7 @@ bool IntersectionObserver::ComputeIntersections(unsigned flags) {
for (auto& observation : observations_to_process) {
observation->ComputeIntersection(root_geometry, flags);
}
+ can_use_cached_rects_ = 1;
return trackVisibility();
}
@@ -416,7 +444,8 @@ void IntersectionObserver::SetNeedsDelivery() {
if (needs_delivery_)
return;
needs_delivery_ = 1;
- To<Document>(GetExecutionContext())
+ To<LocalDOMWindow>(GetExecutionContext())
+ ->document()
->EnsureIntersectionObserverController()
.ScheduleIntersectionObserverForDelivery(*this);
}
@@ -441,13 +470,13 @@ bool IntersectionObserver::HasPendingActivity() const {
return !observations_.IsEmpty();
}
-void IntersectionObserver::Trace(blink::Visitor* visitor) {
+void IntersectionObserver::Trace(Visitor* visitor) {
visitor->template RegisterWeakCallbackMethod<
IntersectionObserver, &IntersectionObserver::ProcessCustomWeakness>(this);
visitor->Trace(delegate_);
visitor->Trace(observations_);
ScriptWrappable::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 44f632cd006..5f6e44ff84e 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
@@ -7,9 +7,8 @@
#include "base/callback.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/intersection_observer/intersection_observation.h"
-#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.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/geometry/length.h"
@@ -23,14 +22,16 @@ class Document;
class Element;
class ExceptionState;
class IntersectionObserverDelegate;
+class IntersectionObserverEntry;
class IntersectionObserverInit;
+class Node;
class ScriptState;
class V8IntersectionObserverCallback;
class CORE_EXPORT IntersectionObserver final
: public ScriptWrappable,
public ActiveScriptWrappable<IntersectionObserver>,
- public ContextClient {
+ public ExecutionContextClient {
USING_GARBAGE_COLLECTED_MIXIN(IntersectionObserver);
DEFINE_WRAPPERTYPEINFO();
@@ -72,20 +73,17 @@ class CORE_EXPORT IntersectionObserver final
static IntersectionObserver* Create(const IntersectionObserverInit*,
IntersectionObserverDelegate&,
- ExceptionState&);
+ ExceptionState& = ASSERT_NO_EXCEPTION);
static IntersectionObserver* Create(ScriptState*,
V8IntersectionObserverCallback*,
const IntersectionObserverInit*,
- ExceptionState&);
+ ExceptionState& = ASSERT_NO_EXCEPTION);
// Creates an IntersectionObserver that monitors changes to the intersection
// between its target element relative to its implicit root and notifies via
// the given |callback|. |thresholds| should be in the range [0,1], and are
// interpreted according to the given |semantics|. |delay| specifies the
// minimum period between change notifications.
- //
- // TODO(crbug.com/915495): The |delay| feature is broken. See comments in
- // intersection_observation.cc.
static IntersectionObserver* Create(
const Vector<Length>& root_margin,
const Vector<float>& thresholds,
@@ -101,7 +99,7 @@ class CORE_EXPORT IntersectionObserver final
static void ResumeSuspendedObservers();
explicit IntersectionObserver(IntersectionObserverDelegate&,
- Element*,
+ Node*,
const Vector<Length>& root_margin,
const Vector<float>& thresholds,
ThresholdInterpretation semantics,
@@ -113,23 +111,25 @@ class CORE_EXPORT IntersectionObserver final
void observe(Element*, ExceptionState& = ASSERT_NO_EXCEPTION);
void unobserve(Element*, ExceptionState& = ASSERT_NO_EXCEPTION);
void disconnect(ExceptionState& = ASSERT_NO_EXCEPTION);
- HeapVector<Member<IntersectionObserverEntry>> takeRecords(ExceptionState&);
+ HeapVector<Member<IntersectionObserverEntry>> takeRecords(
+ ExceptionState& = ASSERT_NO_EXCEPTION);
// API attributes.
- Element* root() const { return root_.Get(); }
+ Node* root() const { return root_.Get(); }
String rootMargin() const;
const Vector<float>& thresholds() const { return thresholds_; }
DOMHighResTimeStamp delay() const { return delay_; }
bool trackVisibility() const { return track_visibility_; }
bool trackFractionOfRoot() const { return track_fraction_of_root_; }
- // An observer can either track intersections with an explicit root Element,
+ // An observer can either track intersections with an explicit root Node,
// or with the the top-level frame's viewport (the "implicit root"). When
// tracking the implicit root, root_ will be null, but because root_ is a
// weak pointer, we cannot surmise that this observer tracks the implicit
// root just because root_ is null. Hence root_is_implicit_.
bool RootIsImplicit() const { return root_is_implicit_; }
+ bool HasObservations() const { return !observations_.IsEmpty(); }
bool AlwaysReportRootBounds() const { return always_report_root_bounds_; }
bool NeedsOcclusionTracking() const {
return trackVisibility() && !observations_.IsEmpty();
@@ -149,14 +149,16 @@ class CORE_EXPORT IntersectionObserver final
DeliveryBehavior GetDeliveryBehavior() const;
void Deliver();
- // Returns false if this observer has an explicit root element which has been
+ // Returns false if this observer has an explicit root node which has been
// deleted; true otherwise.
bool RootIsValid() const;
+ bool CanUseCachedRects() const { return can_use_cached_rects_; }
+ void InvalidateCachedRects() { can_use_cached_rects_ = 0; }
// ScriptWrappable override:
bool HasPendingActivity() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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.
@@ -166,7 +168,7 @@ class CORE_EXPORT IntersectionObserver final
void ProcessCustomWeakness(const WeakCallbackInfo&);
const Member<IntersectionObserverDelegate> delegate_;
- UntracedMember<Element> root_;
+ UntracedMember<Node> root_;
HeapLinkedHashSet<WeakMember<IntersectionObservation>> observations_;
Vector<float> thresholds_;
DOMHighResTimeStamp delay_;
@@ -176,6 +178,7 @@ class CORE_EXPORT IntersectionObserver final
unsigned track_fraction_of_root_ : 1;
unsigned always_report_root_bounds_ : 1;
unsigned needs_delivery_ : 1;
+ unsigned can_use_cached_rects_ : 1;
};
} // namespace blink
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 f96388ff449..f55852bbbd8 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
@@ -8,13 +8,10 @@ callback IntersectionObserverCallback = void (sequence<IntersectionObserverEntry
[
Exposed=Window,
- ActiveScriptWrappable,
- Constructor(IntersectionObserverCallback callback, optional IntersectionObserverInit options),
- ConstructorCallWith=ScriptState,
- MeasureAs=IntersectionObserver_Constructor,
- RaisesException=Constructor
+ ActiveScriptWrappable
] interface IntersectionObserver {
- readonly attribute Element? root;
+ [CallWith=ScriptState, RaisesException, MeasureAs=IntersectionObserver_Constructor] constructor(IntersectionObserverCallback callback, optional IntersectionObserverInit options = {});
+ readonly attribute Node? root;
readonly attribute DOMString rootMargin;
// https://github.com/WICG/IntersectionObserver/issues/114
readonly attribute FrozenArray<double> thresholds;
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 8dd294b9c64..dcdc40da1a6 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
@@ -18,8 +18,8 @@
namespace blink {
IntersectionObserverController::IntersectionObserverController(
- Document* document)
- : ContextClient(document) {}
+ ExecutionContext* context)
+ : ExecutionContextClient(context) {}
IntersectionObserverController::~IntersectionObserverController() = default;
@@ -62,48 +62,90 @@ void IntersectionObserverController::DeliverNotifications(
bool IntersectionObserverController::ComputeIntersections(unsigned flags) {
needs_occlusion_tracking_ = false;
- if (Document* document = To<Document>(GetExecutionContext())) {
+ if (GetExecutionContext()) {
TRACE_EVENT0("blink",
"IntersectionObserverController::"
"computeIntersections");
- HeapVector<Member<Element>> elements_to_process;
- CopyToVector(tracked_elements_, elements_to_process);
- for (auto& element : elements_to_process) {
- needs_occlusion_tracking_ |=
- element->ComputeIntersectionsForLifecycleUpdate(flags);
+ HeapVector<Member<IntersectionObserver>> observers_to_process;
+ CopyToVector(tracked_explicit_root_observers_, observers_to_process);
+ for (auto& observer : observers_to_process) {
+ if (observer->HasObservations())
+ needs_occlusion_tracking_ |= observer->ComputeIntersections(flags);
+ else
+ tracked_explicit_root_observers_.erase(observer);
+ }
+ HeapVector<Member<IntersectionObservation>> observations_to_process;
+ CopyToVector(tracked_implicit_root_observations_, observations_to_process);
+ for (auto& observation : observations_to_process) {
+ observation->ComputeIntersection(flags);
+ needs_occlusion_tracking_ |= observation->Observer()->trackVisibility();
}
}
return needs_occlusion_tracking_;
}
-void IntersectionObserverController::AddTrackedElement(Element& element,
- bool track_occlusion) {
- tracked_elements_.insert(&element);
- if (!track_occlusion)
+void IntersectionObserverController::AddTrackedObserver(
+ IntersectionObserver& observer) {
+ // We only track explicit-root observers that have active observations.
+ if (observer.RootIsImplicit() || !observer.HasObservations())
return;
- needs_occlusion_tracking_ = true;
- if (LocalFrameView* frame_view = element.GetDocument().View()) {
- if (FrameOwner* frame_owner = frame_view->GetFrame().Owner()) {
- // Set this bit as early as possible, rather than waiting for a lifecycle
- // update to recompute it.
- frame_owner->SetNeedsOcclusionTracking(true);
+ tracked_explicit_root_observers_.insert(&observer);
+ if (observer.trackVisibility()) {
+ needs_occlusion_tracking_ = true;
+ if (LocalFrameView* frame_view = observer.root()->GetDocument().View()) {
+ if (FrameOwner* frame_owner = frame_view->GetFrame().Owner()) {
+ // Set this bit as early as possible, rather than waiting for a
+ // lifecycle update to recompute it.
+ frame_owner->SetNeedsOcclusionTracking(true);
+ }
}
}
}
-void IntersectionObserverController::RemoveTrackedElement(Element& target) {
+void IntersectionObserverController::RemoveTrackedObserver(
+ IntersectionObserver& observer) {
+ if (observer.RootIsImplicit())
+ return;
// Note that we don't try to opportunistically turn off the 'needs occlusion
- // tracking' bit here, like the way we turn it on in AddTrackedTarget. The
+ // tracking' bit here, like the way we turn it on in AddTrackedObserver. The
// bit will get recomputed on the next lifecycle update; there's no
- // compelling reason to do it here, so we avoid the iteration through targets
- // and observations here.
- tracked_elements_.erase(&target);
+ // compelling reason to do it here, so we avoid the iteration through
+ // observers and observations here.
+ tracked_explicit_root_observers_.erase(&observer);
+}
+
+void IntersectionObserverController::AddTrackedObservation(
+ IntersectionObservation& observation) {
+ IntersectionObserver* observer = observation.Observer();
+ DCHECK(observer);
+ if (!observer->RootIsImplicit())
+ return;
+ tracked_implicit_root_observations_.insert(&observation);
+ if (observer->trackVisibility()) {
+ needs_occlusion_tracking_ = true;
+ if (LocalFrameView* frame_view =
+ observation.Target()->GetDocument().View()) {
+ if (FrameOwner* frame_owner = frame_view->GetFrame().Owner()) {
+ frame_owner->SetNeedsOcclusionTracking(true);
+ }
+ }
+ }
+}
+
+void IntersectionObserverController::RemoveTrackedObservation(
+ IntersectionObservation& observation) {
+ IntersectionObserver* observer = observation.Observer();
+ DCHECK(observer);
+ if (!observer->RootIsImplicit())
+ return;
+ tracked_implicit_root_observations_.erase(&observation);
}
-void IntersectionObserverController::Trace(blink::Visitor* visitor) {
- visitor->Trace(tracked_elements_);
+void IntersectionObserverController::Trace(Visitor* visitor) {
+ visitor->Trace(tracked_explicit_root_observers_);
+ visitor->Trace(tracked_implicit_root_observations_);
visitor->Trace(pending_intersection_observers_);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 edc08b0ec74..171462f83d5 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
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_INTERSECTION_OBSERVER_INTERSECTION_OBSERVER_CONTROLLER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_INTERSECTION_OBSERVER_INTERSECTION_OBSERVER_CONTROLLER_H_
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -16,16 +16,16 @@
namespace blink {
-class Document;
+class ExecutionContext;
class IntersectionObserverController
: public GarbageCollected<IntersectionObserverController>,
- public ContextClient,
+ public ExecutionContextClient,
public NameClient {
USING_GARBAGE_COLLECTED_MIXIN(IntersectionObserverController);
public:
- explicit IntersectionObserverController(Document*);
+ explicit IntersectionObserverController(ExecutionContext*);
virtual ~IntersectionObserverController();
void ScheduleIntersectionObserverForDelivery(IntersectionObserver&);
@@ -40,31 +40,43 @@ class IntersectionObserverController
// communicates whether observer->trackVisibility() is true for any tracked
// observer.
bool ComputeIntersections(unsigned flags);
+
// The second argument indicates whether the Element is a target of any
// observers for which observer->trackVisibility() is true.
- void AddTrackedElement(Element&, bool);
- void RemoveTrackedElement(Element&);
+ void AddTrackedObserver(IntersectionObserver&);
+ void AddTrackedObservation(IntersectionObservation&);
+ void RemoveTrackedObserver(IntersectionObserver&);
+ void RemoveTrackedObservation(IntersectionObservation&);
+
bool NeedsOcclusionTracking() const { return needs_occlusion_tracking_; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
const char* NameInHeapSnapshot() const override {
return "IntersectionObserverController";
}
- unsigned GetTrackedTargetCountForTesting() const {
- return tracked_elements_.size();
+
+ unsigned GetTrackedObserverCountForTesting() const {
+ return tracked_explicit_root_observers_.size();
+ }
+ unsigned GetTrackedObservationCountForTesting() const {
+ return tracked_implicit_root_observations_.size();
}
private:
void PostTaskToDeliverNotifications();
private:
- // Elements in this document which are the target of an IntersectionObserver
- // with implicit root; or the explicit root of an IntersectionObserver.
- HeapHashSet<WeakMember<Element>> tracked_elements_;
+ // IntersectionObserver's with a connected explicit root in this document.
+ HeapHashSet<WeakMember<IntersectionObserver>>
+ tracked_explicit_root_observers_;
+ // IntersectionObservations with an implicit root and connected target in this
+ // document.
+ HeapHashSet<WeakMember<IntersectionObservation>>
+ tracked_implicit_root_observations_;
// IntersectionObservers for which this is the execution context of the
- // callback.
+ // callback, and with unsent notifications.
HeapHashSet<Member<IntersectionObserver>> pending_intersection_observers_;
- // This is 'true' if any tracked element is the target of an observer for
+ // This is 'true' if any tracked node is the target of an observer for
// which observer->trackVisibility() is true.
bool needs_occlusion_tracking_;
};
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 3ed349b0d37..cd6ccf12097 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(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
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 2506f1ba716..b552a61a1bb 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(blink::Visitor* visitor) {
+void IntersectionObserverEntry::Trace(Visitor* visitor) {
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 c42ea26a85f..7c4883a1d50 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
IntersectionGeometry geometry_;
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 aec7427f539..e83f13dc56b 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
@@ -5,7 +5,7 @@
// https://wicg.github.io/IntersectionObserver/#intersection-observer-init
dictionary IntersectionObserverInit {
- Element? root = null;
+ (Element or Document)? root = null;
DOMString rootMargin = "0px";
(double or sequence<double>) threshold = 0;
[RuntimeEnabled=IntersectionObserverV2] DOMHighResTimeStamp delay = 0;
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 cc24851c44d..fd30925e0fa 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
@@ -6,12 +6,19 @@
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer.h"
+#include "third_party/blink/renderer/bindings/core/v8/sanitize_script_errors.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_init.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/exported/web_view_impl.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
+#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
+#include "third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.h"
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.h"
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_delegate.h"
-#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_init.h"
+#include "third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
@@ -40,10 +47,16 @@ class TestIntersectionObserverDelegate : public IntersectionObserverDelegate {
call_count_++;
entries_.AppendVector(entries);
}
- ExecutionContext* GetExecutionContext() const override { return document_; }
+ ExecutionContext* GetExecutionContext() const override {
+ return document_->GetExecutionContext();
+ }
int CallCount() const { return call_count_; }
int EntryCount() const { return entries_.size(); }
const IntersectionObserverEntry* LastEntry() const { return entries_.back(); }
+ void Clear() {
+ entries_.clear();
+ call_count_ = 0;
+ }
PhysicalRect LastIntersectionRect() const {
if (entries_.IsEmpty())
return PhysicalRect();
@@ -51,7 +64,7 @@ class TestIntersectionObserverDelegate : public IntersectionObserverDelegate {
return geometry.IntersectionRect();
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
IntersectionObserverDelegate::Trace(visitor);
visitor->Trace(document_);
visitor->Trace(entries_);
@@ -122,7 +135,7 @@ TEST_F(IntersectionObserverTest, NotificationSentWhenRootRemoved) {
Element* root = GetDocument().getElementById("root");
ASSERT_TRUE(root);
IntersectionObserverInit* observer_init = IntersectionObserverInit::Create();
- observer_init->setRoot(root);
+ observer_init->setRoot(ElementOrDocument::FromElement(root));
DummyExceptionStateForTesting exception_state;
TestIntersectionObserverDelegate* observer_delegate =
MakeGarbageCollected<TestIntersectionObserverDelegate>(GetDocument());
@@ -149,27 +162,32 @@ TEST_F(IntersectionObserverTest, NotificationSentWhenRootRemoved) {
EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting());
}
-TEST_F(IntersectionObserverTest, ScrollingElementRootClips) {
+TEST_F(IntersectionObserverTest, DocumentRootClips) {
ScopedIntersectionObserverDocumentScrollingElementRootForTest scope(true);
WebView().MainFrameWidget()->Resize(WebSize(800, 600));
SimRequest main_resource("https://example.com/", "text/html");
+ SimRequest iframe_resource("https://example.com/iframe.html", "text/html");
LoadURL("https://example.com/");
main_resource.Complete(R"HTML(
+ <iframe src="iframe.html" style="width:200px; height:100px"></iframe>
+ )HTML");
+ iframe_resource.Complete(R"HTML(
<div id='target'>Hello, world!</div>
<div id='spacer' style='height:2000px'></div>
)HTML");
- Element* root = GetDocument().scrollingElement();
- ASSERT_TRUE(root);
+ Document* iframe_document = To<WebLocalFrameImpl>(MainFrame().FirstChild())
+ ->GetFrame()
+ ->GetDocument();
IntersectionObserverInit* observer_init = IntersectionObserverInit::Create();
- observer_init->setRoot(root);
+ observer_init->setRoot(ElementOrDocument::FromDocument(iframe_document));
DummyExceptionStateForTesting exception_state;
TestIntersectionObserverDelegate* observer_delegate =
MakeGarbageCollected<TestIntersectionObserverDelegate>(GetDocument());
IntersectionObserver* observer = IntersectionObserver::Create(
observer_init, *observer_delegate, exception_state);
ASSERT_FALSE(exception_state.HadException());
- Element* target = GetDocument().getElementById("target");
+ Element* target = iframe_document->getElementById("target");
ASSERT_TRUE(target);
observer->observe(target, exception_state);
@@ -180,8 +198,8 @@ TEST_F(IntersectionObserverTest, ScrollingElementRootClips) {
EXPECT_EQ(observer_delegate->EntryCount(), 1);
EXPECT_TRUE(observer_delegate->LastEntry()->isIntersecting());
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 1000),
- kProgrammaticScroll);
+ iframe_document->View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 1000), mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
EXPECT_EQ(observer_delegate->CallCount(), 2);
@@ -279,8 +297,8 @@ TEST_F(IntersectionObserverTest, ResumePostsTask) {
// When document is not suspended, beginFrame() will generate notifications
// and post a task to deliver them.
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 300),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 300), mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
EXPECT_EQ(observer_delegate->CallCount(), 1);
test::RunPendingTasks();
@@ -290,8 +308,8 @@ TEST_F(IntersectionObserverTest, ResumePostsTask) {
// but it will not be delivered. The notification will, however, be
// available via takeRecords();
WebView().GetPage()->SetPaused(true);
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 0),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 0), mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
EXPECT_EQ(observer_delegate->CallCount(), 2);
test::RunPendingTasks();
@@ -300,8 +318,8 @@ TEST_F(IntersectionObserverTest, ResumePostsTask) {
// Generate a notification while document is suspended; then resume document.
// Notification should happen in a post task.
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 300),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 300), mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
EXPECT_EQ(observer_delegate->CallCount(), 2);
@@ -343,8 +361,8 @@ TEST_F(IntersectionObserverTest, HitTestAfterMutation) {
test::RunPendingTasks();
EXPECT_EQ(observer_delegate->CallCount(), 1);
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 300),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 300), mojom::blink::ScrollType::kProgrammatic);
HitTestLocation location{PhysicalOffset()};
HitTestResult result(
@@ -378,11 +396,11 @@ TEST_F(IntersectionObserverTest, DisconnectClearsNotifications) {
Element* target = GetDocument().getElementById("target");
ASSERT_TRUE(target);
+ IntersectionObserverController& controller =
+ GetDocument().EnsureIntersectionObserverController();
observer->observe(target, exception_state);
- EXPECT_EQ(GetDocument()
- .EnsureIntersectionObserverController()
- .GetTrackedTargetCountForTesting(),
- 1u);
+ EXPECT_EQ(controller.GetTrackedObserverCountForTesting(), 0u);
+ EXPECT_EQ(controller.GetTrackedObservationCountForTesting(), 1u);
Compositor().BeginFrame();
test::RunPendingTasks();
@@ -390,14 +408,12 @@ TEST_F(IntersectionObserverTest, DisconnectClearsNotifications) {
// If disconnect() is called while an observer has unsent notifications,
// those notifications should be discarded.
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 300),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 300), mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
observer->disconnect();
- EXPECT_EQ(GetDocument()
- .EnsureIntersectionObserverController()
- .GetTrackedTargetCountForTesting(),
- 0u);
+ EXPECT_EQ(controller.GetTrackedObserverCountForTesting(), 0u);
+ EXPECT_EQ(controller.GetTrackedObservationCountForTesting(), 0u);
test::RunPendingTasks();
EXPECT_EQ(observer_delegate->CallCount(), 1);
}
@@ -443,8 +459,8 @@ TEST_F(IntersectionObserverTest, RootIntersectionWithForceZeroLayoutHeight) {
ASSERT_EQ(observer_delegate->CallCount(), 1);
EXPECT_TRUE(observer_delegate->LastIntersectionRect().IsEmpty());
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 600),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 600), mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
ASSERT_EQ(observer_delegate->CallCount(), 2);
@@ -452,8 +468,8 @@ TEST_F(IntersectionObserverTest, RootIntersectionWithForceZeroLayoutHeight) {
EXPECT_EQ(PhysicalRect(200, 400, 100, 100),
observer_delegate->LastIntersectionRect());
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 1200),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 1200), mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
test::RunPendingTasks();
ASSERT_EQ(observer_delegate->CallCount(), 3);
@@ -472,29 +488,155 @@ TEST_F(IntersectionObserverTest, TrackedTargetBookkeeping) {
Element* target = GetDocument().getElementById("target");
ASSERT_TRUE(target);
IntersectionObserverInit* observer_init = IntersectionObserverInit::Create();
- DummyExceptionStateForTesting exception_state;
TestIntersectionObserverDelegate* observer_delegate =
MakeGarbageCollected<TestIntersectionObserverDelegate>(GetDocument());
- IntersectionObserver* observer1 = IntersectionObserver::Create(
- observer_init, *observer_delegate, exception_state);
- ASSERT_FALSE(exception_state.HadException());
- observer1->observe(target, exception_state);
- ASSERT_FALSE(exception_state.HadException());
- IntersectionObserver* observer2 = IntersectionObserver::Create(
- observer_init, *observer_delegate, exception_state);
- ASSERT_FALSE(exception_state.HadException());
- observer2->observe(target, exception_state);
- ASSERT_FALSE(exception_state.HadException());
+ IntersectionObserver* observer1 =
+ IntersectionObserver::Create(observer_init, *observer_delegate);
+ observer1->observe(target);
+ IntersectionObserver* observer2 =
+ IntersectionObserver::Create(observer_init, *observer_delegate);
+ observer2->observe(target);
+
+ ElementIntersectionObserverData* target_data =
+ target->IntersectionObserverData();
+ ASSERT_TRUE(target_data);
+ IntersectionObserverController& controller =
+ GetDocument().EnsureIntersectionObserverController();
+ EXPECT_EQ(controller.GetTrackedObservationCountForTesting(), 2u);
+ EXPECT_EQ(controller.GetTrackedObserverCountForTesting(), 0u);
+
+ target->remove();
+ EXPECT_EQ(controller.GetTrackedObservationCountForTesting(), 0u);
+ GetDocument().body()->AppendChild(target);
+ EXPECT_EQ(controller.GetTrackedObservationCountForTesting(), 2u);
+
+ observer1->unobserve(target);
+ EXPECT_EQ(controller.GetTrackedObservationCountForTesting(), 1u);
+
+ observer2->unobserve(target);
+ EXPECT_EQ(controller.GetTrackedObservationCountForTesting(), 0u);
+}
+
+TEST_F(IntersectionObserverTest, TrackedRootBookkeeping) {
+ SimRequest main_resource("https://example.com/", "text/html");
+ LoadURL("https://example.com/");
+ main_resource.Complete(R"HTML(
+ <div id='root'>
+ <div id='target1'></div>
+ <div id='target2'></div>
+ </div>
+ )HTML");
IntersectionObserverController& controller =
GetDocument().EnsureIntersectionObserverController();
- EXPECT_EQ(controller.GetTrackedTargetCountForTesting(), 1u);
- observer1->unobserve(target, exception_state);
- ASSERT_FALSE(exception_state.HadException());
- EXPECT_EQ(controller.GetTrackedTargetCountForTesting(), 1u);
- observer2->unobserve(target, exception_state);
- ASSERT_FALSE(exception_state.HadException());
- EXPECT_EQ(controller.GetTrackedTargetCountForTesting(), 0u);
+ EXPECT_EQ(controller.GetTrackedObserverCountForTesting(), 0u);
+ EXPECT_EQ(controller.GetTrackedObservationCountForTesting(), 0u);
+
+ Persistent<Element> root = GetDocument().getElementById("root");
+ Persistent<Element> target = GetDocument().getElementById("target1");
+ Persistent<IntersectionObserverInit> observer_init =
+ IntersectionObserverInit::Create();
+ observer_init->setRoot(ElementOrDocument::FromElement(root));
+ Persistent<TestIntersectionObserverDelegate> observer_delegate =
+ MakeGarbageCollected<TestIntersectionObserverDelegate>(GetDocument());
+ Persistent<IntersectionObserver> observer =
+ IntersectionObserver::Create(observer_init, *observer_delegate);
+
+ // For an explicit-root observer, the root element is tracked only when it
+ // has observations and is connected. Target elements are not tracked.
+ ElementIntersectionObserverData* root_data = root->IntersectionObserverData();
+ ASSERT_TRUE(root_data);
+ EXPECT_FALSE(root_data->IsEmpty());
+ EXPECT_EQ(controller.GetTrackedObserverCountForTesting(), 0u);
+ EXPECT_EQ(controller.GetTrackedObservationCountForTesting(), 0u);
+
+ observer->observe(target);
+ ElementIntersectionObserverData* target_data =
+ target->IntersectionObserverData();
+ ASSERT_TRUE(target_data);
+ EXPECT_FALSE(target_data->IsEmpty());
+ EXPECT_EQ(controller.GetTrackedObserverCountForTesting(), 1u);
+ EXPECT_EQ(controller.GetTrackedObservationCountForTesting(), 0u);
+
+ // Root should not be tracked if it's not connected.
+ root->remove();
+ EXPECT_EQ(controller.GetTrackedObserverCountForTesting(), 0u);
+ GetDocument().body()->AppendChild(root);
+ EXPECT_EQ(controller.GetTrackedObserverCountForTesting(), 1u);
+
+ // Root should not be tracked if it has no observations.
+ observer->disconnect();
+ EXPECT_EQ(controller.GetTrackedObserverCountForTesting(), 0u);
+ observer->observe(target);
+ EXPECT_EQ(controller.GetTrackedObserverCountForTesting(), 1u);
+ observer->unobserve(target);
+ EXPECT_EQ(controller.GetTrackedObserverCountForTesting(), 0u);
+ observer->observe(target);
+ EXPECT_EQ(controller.GetTrackedObserverCountForTesting(), 1u);
+
+ // The existing observation should keep the observer alive and active.
+ // Flush any pending notifications, which hold a hard reference to the
+ // observer and can prevent it from being gc'ed. The observation will be the
+ // only thing keeping the observer alive.
+ test::RunPendingTasks();
+ observer_delegate->Clear();
+ V8GCController::CollectAllGarbageForTesting(
+ v8::Isolate::GetCurrent(),
+ v8::EmbedderHeapTracer::EmbedderStackState::kEmpty);
+ EXPECT_FALSE(root_data->IsEmpty());
+ EXPECT_FALSE(target_data->IsEmpty());
+ EXPECT_EQ(controller.GetTrackedObserverCountForTesting(), 1u);
+ EXPECT_EQ(controller.GetTrackedObservationCountForTesting(), 0u);
+
+ // When the last observation is disconnected, as a result of the target being
+ // gc'ed, the root element should no longer be tracked after the next
+ // lifecycle update.
+ target->remove();
+ target = nullptr;
+ target_data = nullptr;
+ // Removing the target from the DOM tree forces a notification to be
+ // queued, so flush it out.
+ test::RunPendingTasks();
+ observer_delegate->Clear();
+ V8GCController::CollectAllGarbageForTesting(
+ v8::Isolate::GetCurrent(),
+ v8::EmbedderHeapTracer::EmbedderStackState::kEmpty);
+ Compositor().BeginFrame();
+ EXPECT_EQ(controller.GetTrackedObserverCountForTesting(), 0u);
+ EXPECT_EQ(controller.GetTrackedObservationCountForTesting(), 0u);
+
+ // Removing the last reference to the observer should allow it to be dropeed
+ // from the root's ElementIntersectionObserverData.
+ observer = nullptr;
+ V8GCController::CollectAllGarbageForTesting(
+ v8::Isolate::GetCurrent(),
+ v8::EmbedderHeapTracer::EmbedderStackState::kEmpty);
+ EXPECT_TRUE(root_data->IsEmpty());
+
+ target = GetDocument().getElementById("target2");
+ observer = IntersectionObserver::Create(observer_init, *observer_delegate);
+ observer->observe(target);
+ target_data = target->IntersectionObserverData();
+ ASSERT_TRUE(target_data);
+
+ // If the explicit root of an observer goes away, any existing observations
+ // should be disconnected.
+ target->remove();
+ root->remove();
+ root = nullptr;
+ test::RunPendingTasks();
+ observer_delegate->Clear();
+ observer_delegate = nullptr;
+ observer_init = nullptr;
+ // Removing the target from the tree is not enough to disconnect the
+ // observation.
+ EXPECT_FALSE(target_data->IsEmpty());
+ V8GCController::CollectAllGarbageForTesting(
+ v8::Isolate::GetCurrent(),
+ v8::EmbedderHeapTracer::EmbedderStackState::kEmpty);
+ EXPECT_TRUE(target_data->IsEmpty());
+ EXPECT_EQ(controller.GetTrackedObserverCountForTesting(), 0u);
+ EXPECT_EQ(controller.GetTrackedObservationCountForTesting(), 0u);
}
TEST_F(IntersectionObserverTest, RootMarginDevicePixelRatio) {
@@ -537,6 +679,85 @@ TEST_F(IntersectionObserverTest, RootMarginDevicePixelRatio) {
IntRect(0, 31, 800, 600 - 31));
}
+TEST_F(IntersectionObserverTest, CachedRectsTest) {
+ WebView().MainFrameWidget()->Resize(WebSize(800, 600));
+ SimRequest main_resource("https://example.com/", "text/html");
+ LoadURL("https://example.com/");
+ main_resource.Complete(R"HTML(
+ <style>
+ body { margin: 0; }
+ .spacer { height: 1000px; }
+ .scroller { overflow-y: scroll; height: 100px; }
+ </style>
+ <div id='root' class='scroller'>
+ <div id='target1-container'>
+ <div id='target1'>Hello, world!</div>
+ </div>
+ <div class='scroller'>
+ <div id='target2'>Hello, world!</div>
+ <div class='spacer'></div>
+ </div>
+ <div class='spacer'></div>
+ </div>
+ )HTML");
+
+ Element* root = GetDocument().getElementById("root");
+ Element* target1 = GetDocument().getElementById("target1");
+ Element* target2 = GetDocument().getElementById("target2");
+
+ IntersectionObserverInit* observer_init = IntersectionObserverInit::Create();
+ observer_init->setRoot(ElementOrDocument::FromElement(root));
+ DummyExceptionStateForTesting exception_state;
+ TestIntersectionObserverDelegate* observer_delegate =
+ MakeGarbageCollected<TestIntersectionObserverDelegate>(GetDocument());
+ IntersectionObserver* observer = IntersectionObserver::Create(
+ observer_init, *observer_delegate, exception_state);
+ ASSERT_FALSE(exception_state.HadException());
+ observer->observe(target1, exception_state);
+ ASSERT_FALSE(exception_state.HadException());
+ observer->observe(target2, exception_state);
+ ASSERT_FALSE(exception_state.HadException());
+
+ IntersectionObservation* observation1 =
+ target1->IntersectionObserverData()->GetObservationFor(*observer);
+ EXPECT_FALSE(observation1->CanUseCachedRectsForTesting());
+ IntersectionObservation* observation2 =
+ target2->IntersectionObserverData()->GetObservationFor(*observer);
+ EXPECT_FALSE(observation2->CanUseCachedRectsForTesting());
+
+ // Generate initial notifications and populate cache
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+
+ EXPECT_TRUE(observation1->CanUseCachedRectsForTesting());
+ // observation2 can't use cached rects because the observer's root is not the
+ // target's enclosing scroller.
+ EXPECT_FALSE(observation2->CanUseCachedRectsForTesting());
+
+ // Scrolling the root should not invalidate.
+ PaintLayerScrollableArea* root_scroller = root->GetScrollableArea();
+ root_scroller->SetScrollOffset(ScrollOffset(0, 100),
+ mojom::blink::ScrollType::kProgrammatic);
+ EXPECT_TRUE(observation1->CanUseCachedRectsForTesting());
+
+ // Changing layout between root and target should invalidate.
+ target1->parentElement()->SetInlineStyleProperty(CSSPropertyID::kMarginLeft,
+ "10px");
+ // Invalidation happens during style recalc, so force it here.
+ GetDocument().EnsurePaintLocationDataValidForNode(
+ target1, DocumentUpdateReason::kTest);
+ EXPECT_FALSE(observation1->CanUseCachedRectsForTesting());
+
+ // Moving target2 out from the subscroller should allow it to cache rects.
+ target2->remove();
+ root->appendChild(target2);
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+
+ EXPECT_TRUE(observation1->CanUseCachedRectsForTesting());
+ EXPECT_TRUE(observation2->CanUseCachedRectsForTesting());
+}
+
TEST_F(IntersectionObserverV2Test, TrackVisibilityInit) {
IntersectionObserverInit* observer_init = IntersectionObserverInit::Create();
DummyExceptionStateForTesting exception_state;
diff --git a/chromium/third_party/blink/renderer/core/layout/BUILD.gn b/chromium/third_party/blink/renderer/core/layout/BUILD.gn
index c7a4d88018b..cb2f84ebd46 100644
--- a/chromium/third_party/blink/renderer/core/layout/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/layout/BUILD.gn
@@ -139,16 +139,14 @@ blink_core_sources("layout") {
"layout_image_resource_style_image.h",
"layout_inline.cc",
"layout_inline.h",
- "layout_list_box.cc",
- "layout_list_box.h",
+ "layout_inside_list_marker.cc",
+ "layout_inside_list_marker.h",
"layout_list_item.cc",
"layout_list_item.h",
"layout_list_marker.cc",
"layout_list_marker.h",
"layout_media.cc",
"layout_media.h",
- "layout_menu_list.cc",
- "layout_menu_list.h",
"layout_multi_column_flow_thread.cc",
"layout_multi_column_flow_thread.h",
"layout_multi_column_set.cc",
@@ -162,6 +160,8 @@ blink_core_sources("layout") {
"layout_object_factory.cc",
"layout_object_factory.h",
"layout_object_inlines.h",
+ "layout_outside_list_marker.cc",
+ "layout_outside_list_marker.h",
"layout_progress.cc",
"layout_progress.h",
"layout_quote.cc",
@@ -176,8 +176,6 @@ blink_core_sources("layout") {
"layout_ruby_run.h",
"layout_ruby_text.cc",
"layout_ruby_text.h",
- "layout_search_field.cc",
- "layout_search_field.h",
"layout_shift_region.cc",
"layout_shift_region.h",
"layout_shift_tracker.cc",
@@ -267,14 +265,16 @@ blink_core_sources("layout") {
"list_marker_text.cc",
"list_marker_text.h",
"map_coordinates_flags.h",
- "min_max_size.cc",
- "min_max_size.h",
+ "min_max_sizes.cc",
+ "min_max_sizes.h",
"multi_column_fragmentainer_group.cc",
"multi_column_fragmentainer_group.h",
"ng/custom/css_layout_definition.cc",
"ng/custom/css_layout_definition.h",
"ng/custom/css_layout_worklet.cc",
"ng/custom/css_layout_worklet.h",
+ "ng/custom/custom_intrinsic_sizes.cc",
+ "ng/custom/custom_intrinsic_sizes.h",
"ng/custom/custom_layout_child.cc",
"ng/custom/custom_layout_child.h",
"ng/custom/custom_layout_constraints.cc",
@@ -323,8 +323,6 @@ blink_core_sources("layout") {
"ng/inline/layout_ng_text_fragment.h",
"ng/inline/ng_abstract_inline_text_box.cc",
"ng/inline/ng_abstract_inline_text_box.h",
- "ng/inline/ng_baseline.cc",
- "ng/inline/ng_baseline.h",
"ng/inline/ng_bidi_paragraph.cc",
"ng/inline/ng_bidi_paragraph.h",
"ng/inline/ng_caret_position.cc",
@@ -411,12 +409,24 @@ 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.cc",
- "ng/list/layout_ng_list_marker.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",
+ "ng/mathml/layout_ng_mathml_block.h",
+ "ng/mathml/ng_math_fraction_layout_algorithm.cc",
+ "ng/mathml/ng_math_fraction_layout_algorithm.h",
+ "ng/mathml/ng_math_layout_utils.cc",
+ "ng/mathml/ng_math_layout_utils.h",
+ "ng/mathml/ng_math_row_layout_algorithm.cc",
+ "ng/mathml/ng_math_row_layout_algorithm.h",
+ "ng/mathml/ng_math_space_layout_algorithm.cc",
+ "ng/mathml/ng_math_space_layout_algorithm.h",
"ng/ng_absolute_utils.cc",
"ng/ng_absolute_utils.h",
"ng/ng_block_break_token.cc",
@@ -447,12 +457,16 @@ blink_core_sources("layout") {
"ng/ng_early_break.h",
"ng/ng_fieldset_layout_algorithm.cc",
"ng/ng_fieldset_layout_algorithm.h",
+ "ng/ng_flex_child_iterator.cc",
+ "ng/ng_flex_child_iterator.h",
"ng/ng_flex_layout_algorithm.cc",
"ng/ng_flex_layout_algorithm.h",
"ng/ng_floats_utils.cc",
"ng/ng_floats_utils.h",
"ng/ng_fragment.h",
"ng/ng_fragment_builder.h",
+ "ng/ng_fragment_child_iterator.cc",
+ "ng/ng_fragment_child_iterator.h",
"ng/ng_fragmentation_utils.cc",
"ng/ng_fragmentation_utils.h",
"ng/ng_ink_overflow.cc",
diff --git a/chromium/third_party/blink/renderer/core/layout/DEPS b/chromium/third_party/blink/renderer/core/layout/DEPS
index 3b34fd02b70..98473842d29 100644
--- a/chromium/third_party/blink/renderer/core/layout/DEPS
+++ b/chromium/third_party/blink/renderer/core/layout/DEPS
@@ -1,5 +1,5 @@
specific_include_rules = {
- "layout_theme\.cc": [
+ "layout_theme\.cc|layout_theme_mac\.mm": [
"+ui/native_theme/native_theme.h",
],
}
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 f78350e836f..f5cc4ed4fcd 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
@@ -24,16 +24,7 @@ class LineLayoutListMarker : public LineLayoutBox {
LineLayoutListMarker() = default;
- bool IsInside() const { return ToListMarker()->IsInside(); }
-
- private:
- LayoutListMarker* ToListMarker() {
- return ToLayoutListMarker(GetLayoutObject());
- }
-
- const LayoutListMarker* ToListMarker() const {
- return ToLayoutListMarker(GetLayoutObject());
- }
+ bool IsInside() const { return GetLayoutObject()->IsInsideListMarker(); }
};
} // namespace blink
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 456ffcf24d8..5136d0d40a3 100644
--- a/chromium/third_party/blink/renderer/core/layout/custom_scrollbar.cc
+++ b/chromium/third_party/blink/renderer/core/layout/custom_scrollbar.cc
@@ -36,14 +36,6 @@
namespace blink {
-Scrollbar* CustomScrollbar::CreateCustomScrollbar(
- ScrollableArea* scrollable_area,
- ScrollbarOrientation orientation,
- Element* style_source) {
- return MakeGarbageCollected<CustomScrollbar>(scrollable_area, orientation,
- style_source);
-}
-
CustomScrollbar::CustomScrollbar(ScrollableArea* scrollable_area,
ScrollbarOrientation orientation,
Element* style_source)
@@ -104,7 +96,7 @@ int CustomScrollbar::HypotheticalScrollbarThickness(
enclosing_box.ClientWidth().ToInt(), part_style.get());
}
-void CustomScrollbar::Trace(blink::Visitor* visitor) {
+void CustomScrollbar::Trace(Visitor* visitor) {
Scrollbar::Trace(visitor);
}
@@ -150,14 +142,18 @@ void CustomScrollbar::SetPressedPart(ScrollbarPart part,
UpdateScrollbarPart(kTrackBGPart);
}
-scoped_refptr<ComputedStyle> CustomScrollbar::GetScrollbarPseudoElementStyle(
- ScrollbarPart part_type,
- PseudoId pseudo_id) {
+scoped_refptr<const ComputedStyle>
+CustomScrollbar::GetScrollbarPseudoElementStyle(ScrollbarPart part_type,
+ PseudoId pseudo_id) {
if (!StyleSource()->GetLayoutObject())
return nullptr;
- return StyleSource()->StyleForPseudoElement(
- PseudoElementStyleRequest(pseudo_id, this, part_type),
- StyleSource()->GetLayoutObject()->Style());
+ const ComputedStyle* source_style = StyleSource()->GetLayoutObject()->Style();
+ scoped_refptr<const ComputedStyle> part_style =
+ StyleSource()->StyleForPseudoElement(
+ PseudoElementStyleRequest(pseudo_id, this, part_type), source_style);
+ if (!part_style)
+ return nullptr;
+ return source_style->AddCachedPseudoElementStyle(std::move(part_style));
}
void CustomScrollbar::UpdateScrollbarParts(bool destroy) {
@@ -236,41 +232,28 @@ void CustomScrollbar::UpdateScrollbarPart(ScrollbarPart part_type,
if (part_type == kNoPart)
return;
- scoped_refptr<ComputedStyle> part_style =
+ scoped_refptr<const ComputedStyle> part_style =
!destroy ? GetScrollbarPseudoElementStyle(
part_type, PseudoForScrollbarPart(part_type))
- : scoped_refptr<ComputedStyle>(nullptr);
+ : scoped_refptr<const ComputedStyle>(nullptr);
bool need_layout_object =
!destroy && part_style && part_style->Display() != EDisplay::kNone;
- if (need_layout_object && part_style->Display() != EDisplay::kBlock) {
- // See if we are a button that should not be visible according to OS
- // settings.
- WebScrollbarButtonsPlacement buttons_placement =
- GetTheme().ButtonsPlacement();
+ if (need_layout_object &&
+ // display:block overrides OS settings.
+ part_style->Display() != EDisplay::kBlock) {
+ // If not display:block, visibility of buttons depends on OS settings.
switch (part_type) {
case kBackButtonStartPart:
- need_layout_object =
- (buttons_placement == kWebScrollbarButtonsPlacementSingle ||
- buttons_placement == kWebScrollbarButtonsPlacementDoubleStart ||
- buttons_placement == kWebScrollbarButtonsPlacementDoubleBoth);
- break;
- case kForwardButtonStartPart:
- need_layout_object =
- (buttons_placement == kWebScrollbarButtonsPlacementDoubleStart ||
- buttons_placement == kWebScrollbarButtonsPlacementDoubleBoth);
+ case kForwardButtonEndPart:
+ // Create buttons only if the OS theme has scrollbar buttons.
+ need_layout_object = GetTheme().NativeThemeHasButtons();
break;
case kBackButtonEndPart:
- need_layout_object =
- (buttons_placement == kWebScrollbarButtonsPlacementDoubleEnd ||
- buttons_placement == kWebScrollbarButtonsPlacementDoubleBoth);
- break;
- case kForwardButtonEndPart:
- need_layout_object =
- (buttons_placement == kWebScrollbarButtonsPlacementSingle ||
- buttons_placement == kWebScrollbarButtonsPlacementDoubleEnd ||
- buttons_placement == kWebScrollbarButtonsPlacementDoubleBoth);
+ case kForwardButtonStartPart:
+ // These buttons are not supported by any OS.
+ need_layout_object = false;
break;
default:
break;
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 6f097019e0f..734cb2d7931 100644
--- a/chromium/third_party/blink/renderer/core/layout/custom_scrollbar.h
+++ b/chromium/third_party/blink/renderer/core/layout/custom_scrollbar.h
@@ -45,10 +45,6 @@ class LayoutObject;
// LayoutCustomScrollbarPart.
class CustomScrollbar final : public Scrollbar {
public:
- static Scrollbar* CreateCustomScrollbar(ScrollableArea*,
- ScrollbarOrientation,
- Element*);
-
CustomScrollbar(ScrollableArea*, ScrollbarOrientation, Element*);
~CustomScrollbar() override;
@@ -77,7 +73,7 @@ class CustomScrollbar final : public Scrollbar {
void SetVisualRect(const IntRect&) final;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
friend class Scrollbar;
@@ -94,8 +90,9 @@ class CustomScrollbar final : public Scrollbar {
void UpdateScrollbarParts(bool destroy = false);
- scoped_refptr<ComputedStyle> GetScrollbarPseudoElementStyle(ScrollbarPart,
- PseudoId);
+ scoped_refptr<const ComputedStyle> GetScrollbarPseudoElementStyle(
+ ScrollbarPart,
+ PseudoId);
void UpdateScrollbarPart(ScrollbarPart, bool destroy = false);
HashMap<unsigned, LayoutCustomScrollbarPart*> parts_;
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 e5556b46d71..ebc3d542dff 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
@@ -32,7 +32,8 @@
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/layout_flexible_box.h"
-#include "third_party/blink/renderer/core/layout/min_max_size.h"
+#include "third_party/blink/renderer/core/layout/min_max_sizes.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_box_fragment.h"
namespace blink {
namespace {
@@ -72,77 +73,97 @@ ContentDistributionType BoxPackToContentDistribution(EBoxPack box_pack) {
} // namespace
-FlexItem::FlexItem(LayoutBox* box,
+FlexItem::FlexItem(const FlexLayoutAlgorithm* algorithm,
+ LayoutBox* box,
+ const ComputedStyle& style,
LayoutUnit flex_base_content_size,
- MinMaxSize min_max_sizes,
- base::Optional<MinMaxSize> min_max_cross_axis_sizes,
+ MinMaxSizes min_max_main_sizes,
+ base::Optional<MinMaxSizes> min_max_cross_sizes,
LayoutUnit main_axis_border_padding,
- LayoutUnit main_axis_margin)
- : algorithm(nullptr),
+ LayoutUnit cross_axis_border_padding,
+ NGPhysicalBoxStrut physical_margins)
+ : algorithm(algorithm),
line_number(0),
box(box),
+ style(style),
flex_base_content_size(flex_base_content_size),
- min_max_sizes(min_max_sizes),
- min_max_cross_sizes(min_max_cross_axis_sizes),
+ min_max_main_sizes(min_max_main_sizes),
+ min_max_cross_sizes(min_max_cross_sizes),
hypothetical_main_content_size(
- min_max_sizes.ClampSizeToMinAndMax(flex_base_content_size)),
+ min_max_main_sizes.ClampSizeToMinAndMax(flex_base_content_size)),
main_axis_border_padding(main_axis_border_padding),
- main_axis_margin(main_axis_margin),
+ cross_axis_border_padding(cross_axis_border_padding),
+ physical_margins(physical_margins),
frozen(false),
needs_relayout_for_stretch(false),
ng_input_node(/* LayoutBox* */ nullptr) {
- DCHECK(!box->IsOutOfFlowPositioned());
- DCHECK_GE(min_max_sizes.max_size, LayoutUnit())
+ DCHECK_GE(min_max_main_sizes.max_size, LayoutUnit())
<< "Use LayoutUnit::Max() for no max size";
}
bool FlexItem::MainAxisIsInlineAxis() const {
- return algorithm->IsHorizontalFlow() == box->IsHorizontalWritingMode();
+ return algorithm->IsHorizontalFlow() == style.IsHorizontalWritingMode();
}
LayoutUnit FlexItem::FlowAwareMarginStart() const {
if (algorithm->IsHorizontalFlow()) {
- return algorithm->IsLeftToRightFlow() ? box->MarginLeft()
- : box->MarginRight();
+ return algorithm->IsLeftToRightFlow() ? physical_margins.left
+ : physical_margins.right;
}
- return algorithm->IsLeftToRightFlow() ? box->MarginTop()
- : box->MarginBottom();
+ return algorithm->IsLeftToRightFlow() ? physical_margins.top
+ : physical_margins.bottom;
}
LayoutUnit FlexItem::FlowAwareMarginEnd() const {
if (algorithm->IsHorizontalFlow()) {
- return algorithm->IsLeftToRightFlow() ? box->MarginRight()
- : box->MarginLeft();
+ return algorithm->IsLeftToRightFlow() ? physical_margins.right
+ : physical_margins.left;
}
- return algorithm->IsLeftToRightFlow() ? box->MarginBottom()
- : box->MarginTop();
+ return algorithm->IsLeftToRightFlow() ? physical_margins.bottom
+ : physical_margins.top;
}
LayoutUnit FlexItem::FlowAwareMarginBefore() const {
switch (algorithm->GetTransformedWritingMode()) {
case TransformedWritingMode::kTopToBottomWritingMode:
- return box->MarginTop();
+ return physical_margins.top;
case TransformedWritingMode::kBottomToTopWritingMode:
- return box->MarginBottom();
+ return physical_margins.bottom;
case TransformedWritingMode::kLeftToRightWritingMode:
- return box->MarginLeft();
+ return physical_margins.left;
case TransformedWritingMode::kRightToLeftWritingMode:
- return box->MarginRight();
+ return physical_margins.right;
}
NOTREACHED();
- return box->MarginTop();
+ return LayoutUnit();
+}
+
+LayoutUnit FlexItem::MainAxisMarginExtent() const {
+ return algorithm->IsHorizontalFlow() ? physical_margins.HorizontalSum()
+ : physical_margins.VerticalSum();
}
LayoutUnit FlexItem::CrossAxisMarginExtent() const {
- return algorithm->IsHorizontalFlow() ? box->MarginHeight()
- : box->MarginWidth();
+ return algorithm->IsHorizontalFlow() ? physical_margins.VerticalSum()
+ : physical_margins.HorizontalSum();
}
LayoutUnit FlexItem::MarginBoxAscent() const {
- LayoutUnit ascent(box->FirstLineBoxBaseline());
- if (ascent == -1)
- ascent = cross_axis_size;
- return ascent + FlowAwareMarginBefore();
+ if (box) {
+ LayoutUnit ascent(box->FirstLineBoxBaseline());
+ if (ascent == -1)
+ ascent = cross_axis_size;
+ return ascent + FlowAwareMarginBefore();
+ }
+
+ DCHECK(layout_result);
+ base::Optional<LayoutUnit> baseline =
+ NGBoxFragment(
+ algorithm->StyleRef().GetWritingMode(),
+ algorithm->StyleRef().Direction(),
+ To<NGPhysicalBoxFragment>(layout_result->PhysicalFragment()))
+ .Baseline();
+ return baseline.value_or(cross_axis_size) + FlowAwareMarginBefore();
}
LayoutUnit FlexItem::AvailableAlignmentSpace() const {
@@ -152,64 +173,59 @@ LayoutUnit FlexItem::AvailableAlignmentSpace() const {
bool FlexItem::HasAutoMarginsInCrossAxis() const {
if (algorithm->IsHorizontalFlow()) {
- return box->StyleRef().MarginTop().IsAuto() ||
- box->StyleRef().MarginBottom().IsAuto();
+ return style.MarginTop().IsAuto() || style.MarginBottom().IsAuto();
}
- return box->StyleRef().MarginLeft().IsAuto() ||
- box->StyleRef().MarginRight().IsAuto();
+ return style.MarginLeft().IsAuto() || style.MarginRight().IsAuto();
}
ItemPosition FlexItem::Alignment() const {
- return FlexLayoutAlgorithm::AlignmentForChild(*algorithm->Style(),
- box->StyleRef());
+ return FlexLayoutAlgorithm::AlignmentForChild(*algorithm->Style(), style);
}
void FlexItem::UpdateAutoMarginsInMainAxis(LayoutUnit auto_margin_offset) {
DCHECK_GE(auto_margin_offset, LayoutUnit());
if (algorithm->IsHorizontalFlow()) {
- if (box->StyleRef().MarginLeft().IsAuto())
- box->SetMarginLeft(auto_margin_offset);
- if (box->StyleRef().MarginRight().IsAuto())
- box->SetMarginRight(auto_margin_offset);
+ if (style.MarginLeft().IsAuto())
+ physical_margins.left = auto_margin_offset;
+ if (style.MarginRight().IsAuto())
+ physical_margins.right = auto_margin_offset;
} else {
- if (box->StyleRef().MarginTop().IsAuto())
- box->SetMarginTop(auto_margin_offset);
- if (box->StyleRef().MarginBottom().IsAuto())
- box->SetMarginBottom(auto_margin_offset);
+ if (style.MarginTop().IsAuto())
+ physical_margins.top = auto_margin_offset;
+ if (style.MarginBottom().IsAuto())
+ physical_margins.bottom = auto_margin_offset;
}
}
bool FlexItem::UpdateAutoMarginsInCrossAxis(
LayoutUnit available_alignment_space) {
- DCHECK(!box->IsOutOfFlowPositioned());
DCHECK_GE(available_alignment_space, LayoutUnit());
bool is_horizontal = algorithm->IsHorizontalFlow();
- const Length& top_or_left = is_horizontal ? box->StyleRef().MarginTop()
- : box->StyleRef().MarginLeft();
- const Length& bottom_or_right = is_horizontal ? box->StyleRef().MarginBottom()
- : box->StyleRef().MarginRight();
+ const Length& top_or_left =
+ is_horizontal ? style.MarginTop() : style.MarginLeft();
+ const Length& bottom_or_right =
+ is_horizontal ? style.MarginBottom() : style.MarginRight();
if (top_or_left.IsAuto() && bottom_or_right.IsAuto()) {
desired_location.Move(LayoutUnit(), available_alignment_space / 2);
if (is_horizontal) {
- box->SetMarginTop(available_alignment_space / 2);
- box->SetMarginBottom(available_alignment_space / 2);
+ physical_margins.top = available_alignment_space / 2;
+ physical_margins.bottom = available_alignment_space / 2;
} else {
- box->SetMarginLeft(available_alignment_space / 2);
- box->SetMarginRight(available_alignment_space / 2);
+ physical_margins.left = available_alignment_space / 2;
+ physical_margins.right = available_alignment_space / 2;
}
return true;
}
bool should_adjust_top_or_left = true;
- if (algorithm->IsColumnFlow() && !box->StyleRef().IsLeftToRightDirection()) {
+ if (algorithm->IsColumnFlow() && !style.IsLeftToRightDirection()) {
// For column flows, only make this adjustment if topOrLeft corresponds to
// the "before" margin, so that flipForRightToLeftColumn will do the right
// thing.
should_adjust_top_or_left = false;
}
- if (!algorithm->IsColumnFlow() &&
- box->StyleRef().IsFlippedBlocksWritingMode()) {
+ if (!algorithm->IsColumnFlow() && style.IsFlippedBlocksWritingMode()) {
// If we are a flipped writing mode, we need to adjust the opposite side.
// This is only needed for row flows because this only affects the
// block-direction axis.
@@ -221,9 +237,9 @@ bool FlexItem::UpdateAutoMarginsInCrossAxis(
desired_location.Move(LayoutUnit(), available_alignment_space);
if (is_horizontal)
- box->SetMarginTop(available_alignment_space);
+ physical_margins.top = available_alignment_space;
else
- box->SetMarginLeft(available_alignment_space);
+ physical_margins.left = available_alignment_space;
return true;
}
if (bottom_or_right.IsAuto()) {
@@ -231,9 +247,9 @@ bool FlexItem::UpdateAutoMarginsInCrossAxis(
desired_location.Move(LayoutUnit(), available_alignment_space);
if (is_horizontal)
- box->SetMarginBottom(available_alignment_space);
+ physical_margins.bottom = available_alignment_space;
else
- box->SetMarginRight(available_alignment_space);
+ physical_margins.right = available_alignment_space;
return true;
}
return false;
@@ -241,25 +257,24 @@ bool FlexItem::UpdateAutoMarginsInCrossAxis(
void FlexItem::ComputeStretchedSize() {
DCHECK_EQ(Alignment(), ItemPosition::kStretch);
- if (MainAxisIsInlineAxis() && box->StyleRef().LogicalHeight().IsAuto()) {
- LayoutUnit stretched_logical_height =
- std::max(box->BorderAndPaddingLogicalHeight(),
- Line()->cross_axis_extent - CrossAxisMarginExtent());
- cross_axis_size = box->ConstrainLogicalHeightByMinMax(
- stretched_logical_height, box->IntrinsicContentLogicalHeight());
- } else if (!MainAxisIsInlineAxis() &&
- box->StyleRef().LogicalWidth().IsAuto()) {
- LayoutUnit child_width =
- (Line()->cross_axis_extent - CrossAxisMarginExtent())
- .ClampNegativeToZero();
- if (LayoutFlexibleBox* flexbox = ToLayoutFlexibleBoxOrNull(box->Parent())) {
+ LayoutUnit stretched_size =
+ std::max(cross_axis_border_padding,
+ Line()->cross_axis_extent - CrossAxisMarginExtent());
+ if (box) {
+ if (MainAxisIsInlineAxis() && style.LogicalHeight().IsAuto()) {
+ cross_axis_size = box->ConstrainLogicalHeightByMinMax(
+ stretched_size, box->IntrinsicContentLogicalHeight());
+ } else if (!MainAxisIsInlineAxis() && style.LogicalWidth().IsAuto()) {
+ const LayoutFlexibleBox* flexbox = ToLayoutFlexibleBox(box->Parent());
cross_axis_size = box->ConstrainLogicalWidthByMinMax(
- child_width, flexbox->CrossAxisContentExtent(), flexbox);
- } else {
- DCHECK(box->Parent()->IsLayoutNGFlexibleBox());
- cross_axis_size = min_max_cross_sizes->ClampSizeToMinAndMax(child_width);
+ stretched_size, flexbox->CrossAxisContentExtent(), flexbox);
}
+ return;
}
+
+ if ((MainAxisIsInlineAxis() && style.LogicalHeight().IsAuto()) ||
+ (!MainAxisIsInlineAxis() && style.LogicalWidth().IsAuto()))
+ cross_axis_size = min_max_cross_sizes->ClampSizeToMinAndMax(stretched_size);
}
// static
@@ -314,12 +329,11 @@ void FlexLine::FreezeViolations(ViolationsVector& violations) {
const ComputedStyle& flex_box_style = algorithm->StyleRef();
for (size_t i = 0; i < violations.size(); ++i) {
DCHECK(!violations[i]->frozen) << i;
- LayoutBox* child = violations[i]->box;
+ const ComputedStyle& child_style = violations[i]->style;
LayoutUnit child_size = violations[i]->flexed_content_size;
remaining_free_space -= child_size - violations[i]->flex_base_content_size;
- total_flex_grow -= child->StyleRef().ResolvedFlexGrow(flex_box_style);
- const float flex_shrink =
- child->StyleRef().ResolvedFlexShrink(flex_box_style);
+ total_flex_grow -= child_style.ResolvedFlexGrow(flex_box_style);
+ const float flex_shrink = child_style.ResolvedFlexShrink(flex_box_style);
total_flex_shrink -= flex_shrink;
total_weighted_flex_shrink -=
flex_shrink * violations[i]->flex_base_content_size;
@@ -344,13 +358,11 @@ void FlexLine::FreezeInflexibleItems() {
const ComputedStyle& flex_box_style = algorithm->StyleRef();
for (size_t i = 0; i < line_items.size(); ++i) {
FlexItem& flex_item = line_items[i];
- LayoutBox* child = flex_item.box;
- DCHECK(!flex_item.box->IsOutOfFlowPositioned());
DCHECK(!flex_item.frozen) << i;
float flex_factor =
(flex_sign == kPositiveFlexibility)
- ? child->StyleRef().ResolvedFlexGrow(flex_box_style)
- : child->StyleRef().ResolvedFlexShrink(flex_box_style);
+ ? flex_item.style.ResolvedFlexGrow(flex_box_style)
+ : flex_item.style.ResolvedFlexShrink(flex_box_style);
if (flex_factor == 0 ||
(flex_sign == kPositiveFlexibility &&
flex_item.flex_base_content_size >
@@ -384,7 +396,6 @@ bool FlexLine::ResolveFlexibleLengths() {
const ComputedStyle& flex_box_style = algorithm->StyleRef();
for (size_t i = 0; i < line_items.size(); ++i) {
FlexItem& flex_item = line_items[i];
- LayoutBox* child = flex_item.box;
// This check also covers out-of-flow children.
if (flex_item.frozen)
@@ -395,14 +406,14 @@ bool FlexLine::ResolveFlexibleLengths() {
if (remaining_free_space > 0 && total_flex_grow > 0 &&
flex_sign == kPositiveFlexibility && std::isfinite(total_flex_grow)) {
extra_space = remaining_free_space *
- child->StyleRef().ResolvedFlexGrow(flex_box_style) /
+ flex_item.style.ResolvedFlexGrow(flex_box_style) /
total_flex_grow;
} else if (remaining_free_space < 0 && total_weighted_flex_shrink > 0 &&
flex_sign == kNegativeFlexibility &&
std::isfinite(total_weighted_flex_shrink) &&
- child->StyleRef().ResolvedFlexShrink(flex_box_style)) {
+ flex_item.style.ResolvedFlexShrink(flex_box_style)) {
extra_space = remaining_free_space *
- child->StyleRef().ResolvedFlexShrink(flex_box_style) *
+ flex_item.style.ResolvedFlexShrink(flex_box_style) *
flex_item.flex_base_content_size /
total_weighted_flex_shrink;
}
@@ -438,17 +449,16 @@ LayoutUnit FlexLine::ApplyMainAxisAutoMarginAdjustment() {
int number_of_auto_margins = 0;
bool is_horizontal = algorithm->IsHorizontalFlow();
for (size_t i = 0; i < line_items.size(); ++i) {
- LayoutBox* child = line_items[i].box;
- DCHECK(!child->IsOutOfFlowPositioned());
+ const ComputedStyle& style = line_items[i].style;
if (is_horizontal) {
- if (child->StyleRef().MarginLeft().IsAuto())
+ if (style.MarginLeft().IsAuto())
++number_of_auto_margins;
- if (child->StyleRef().MarginRight().IsAuto())
+ if (style.MarginRight().IsAuto())
++number_of_auto_margins;
} else {
- if (child->StyleRef().MarginTop().IsAuto())
+ if (style.MarginTop().IsAuto())
++number_of_auto_margins;
- if (child->StyleRef().MarginBottom().IsAuto())
+ if (style.MarginBottom().IsAuto())
++number_of_auto_margins;
}
}
@@ -468,11 +478,8 @@ void FlexLine::ComputeLineItemsPosition(LayoutUnit main_axis_start_offset,
// Recalculate the remaining free space. The adjustment for flex factors
// between 0..1 means we can't just use remainingFreeSpace here.
LayoutUnit total_item_size;
- for (size_t i = 0; i < line_items.size(); ++i) {
- FlexItem& flex_item = line_items[i];
- DCHECK(!flex_item.box->IsOutOfFlowPositioned());
- total_item_size += flex_item.FlexedMarginBoxSize();
- }
+ for (size_t i = 0; i < line_items.size(); ++i)
+ total_item_size += line_items[i].FlexedMarginBoxSize();
remaining_free_space = container_main_inner_size - total_item_size;
const StyleContentAlignmentData justify_content =
@@ -516,8 +523,6 @@ void FlexLine::ComputeLineItemsPosition(LayoutUnit main_axis_start_offset,
for (size_t i = 0; i < line_items.size(); ++i) {
FlexItem& flex_item = line_items[i];
- DCHECK(!flex_item.box->IsOutOfFlowPositioned());
-
flex_item.UpdateAutoMarginsInMainAxis(auto_margin_offset);
LayoutUnit child_cross_axis_margin_box_extent;
@@ -590,7 +595,6 @@ FlexLine* FlexLayoutAlgorithm::ComputeNextFlexLine(
for (; next_item_index_ < all_items_.size(); ++next_item_index_) {
FlexItem& flex_item = all_items_[next_item_index_];
- DCHECK(!flex_item.box->IsOutOfFlowPositioned());
if (IsMultiline() &&
sum_hypothetical_main_size +
flex_item.HypotheticalMainAxisMarginBoxSize() >
@@ -600,9 +604,8 @@ FlexLine* FlexLayoutAlgorithm::ComputeNextFlexLine(
}
line_has_in_flow_item = true;
sum_flex_base_size += flex_item.FlexBaseMarginBoxSize();
- total_flex_grow += flex_item.box->StyleRef().ResolvedFlexGrow(StyleRef());
- const float flex_shrink =
- flex_item.box->StyleRef().ResolvedFlexShrink(StyleRef());
+ total_flex_grow += flex_item.style.ResolvedFlexGrow(StyleRef());
+ const float flex_shrink = flex_item.style.ResolvedFlexShrink(StyleRef());
total_flex_shrink += flex_shrink;
total_weighted_flex_shrink +=
flex_shrink * flex_item.flex_base_content_size;
@@ -663,6 +666,8 @@ bool FlexLayoutAlgorithm::ShouldApplyMinSizeAutoForChild(
// css-flexbox section 4.5
const Length& min = IsHorizontalFlow() ? child.StyleRef().MinWidth()
: child.StyleRef().MinHeight();
+ // TODO(dgrogan): min.IsIntrinsic should also get past this check when in the
+ // item's block direction.
if (!min.IsAuto())
return false;
@@ -670,6 +675,8 @@ bool FlexLayoutAlgorithm::ShouldApplyMinSizeAutoForChild(
if (StyleRef().IsDeprecatedWebkitBox())
return false;
+ // TODO(dgrogan): MainAxisOverflowForChild == kClip also qualifies, not just
+ // kVisible.
return !child.ShouldApplySizeContainment() &&
MainAxisOverflowForChild(child) == EOverflow::kVisible;
}
@@ -737,12 +744,9 @@ void FlexLayoutAlgorithm::AlignChildren() {
LayoutUnit max_ascent = line_context.max_ascent;
for (FlexItem& flex_item : line_context.line_items) {
- DCHECK(!flex_item.box->IsOutOfFlowPositioned());
-
if (flex_item.UpdateAutoMarginsInCrossAxis(
- std::max(LayoutUnit(), flex_item.AvailableAlignmentSpace()))) {
+ flex_item.AvailableAlignmentSpace().ClampNegativeToZero()))
continue;
- }
ItemPosition position = flex_item.Alignment();
if (position == ItemPosition::kStretch) {
@@ -980,14 +984,17 @@ void FlexLayoutAlgorithm::LayoutColumnReverse(
child_number < line_context.line_items.size(); ++child_number) {
FlexItem& flex_item = line_context.line_items[child_number];
LayoutUnit item_main_size = flex_item.FlexedBorderBoxSize();
+
+ NGBoxStrut margins = flex_item.physical_margins.ConvertToLogical(
+ Style()->GetWritingMode(), Style()->Direction());
+
// We passed 0 as the initial main_axis offset to ComputeLineItemsPosition
// for ColumnReverse containers so here we have to add the
// border_scrollbar_padding of the container.
flex_item.desired_location.SetX(
main_axis_content_size + border_scrollbar_padding_before -
- flex_item.desired_location.X() - item_main_size -
- flex_item.box->MarginAfter(Style()) +
- flex_item.box->MarginBefore(Style()));
+ flex_item.desired_location.X() - item_main_size - margins.block_end +
+ margins.block_start);
}
}
}
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 8fc05cdab10..19ccd4575f2 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
@@ -33,7 +33,7 @@
#include "base/macros.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/layout/min_max_size.h"
+#include "third_party/blink/renderer/core/layout/min_max_sizes.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h"
#include "third_party/blink/renderer/core/layout/order_iterator.h"
@@ -49,7 +49,7 @@ class FlexItem;
class FlexLine;
class FlexLayoutAlgorithm;
class LayoutBox;
-struct MinMaxSize;
+struct MinMaxSizes;
enum FlexSign {
kPositiveFlexibility,
@@ -113,24 +113,28 @@ class FlexItem {
public:
// Parameters:
// - |flex_base_content_size| includes scrollbar size but not border/padding.
- // - |min_max_sizes| is the resolved min and max size properties in the
+ // - |min_max_main_sizes| is the resolved min and max size properties in the
// main axis direction (not intrinsic widths). It does not include
- // border/scrollbar/padding.
- FlexItem(LayoutBox*,
+ // border/padding.
+ FlexItem(const FlexLayoutAlgorithm*,
+ LayoutBox*,
+ const ComputedStyle& style,
LayoutUnit flex_base_content_size,
- MinMaxSize min_max_main_axis_sizes,
+ MinMaxSizes min_max_main_sizes,
// Ignored for legacy, required for NG:
- base::Optional<MinMaxSize> min_max_cross_axis_sizes,
+ base::Optional<MinMaxSizes> min_max_cross_sizes,
LayoutUnit main_axis_border_padding,
- LayoutUnit main_axis_margin);
+ LayoutUnit cross_axis_border_padding,
+ NGPhysicalBoxStrut physical_margins);
LayoutUnit HypotheticalMainAxisMarginBoxSize() const {
return hypothetical_main_content_size + main_axis_border_padding +
- main_axis_margin;
+ MainAxisMarginExtent();
}
LayoutUnit FlexBaseMarginBoxSize() const {
- return flex_base_content_size + main_axis_border_padding + main_axis_margin;
+ return flex_base_content_size + main_axis_border_padding +
+ MainAxisMarginExtent();
}
LayoutUnit FlexedBorderBoxSize() const {
@@ -138,11 +142,12 @@ class FlexItem {
}
LayoutUnit FlexedMarginBoxSize() const {
- return flexed_content_size + main_axis_border_padding + main_axis_margin;
+ return flexed_content_size + main_axis_border_padding +
+ MainAxisMarginExtent();
}
LayoutUnit ClampSizeToMinAndMax(LayoutUnit size) const {
- return min_max_sizes.ClampSizeToMinAndMax(size);
+ return min_max_main_sizes.ClampSizeToMinAndMax(size);
}
ItemPosition Alignment() const;
@@ -152,6 +157,8 @@ class FlexItem {
LayoutUnit FlowAwareMarginStart() const;
LayoutUnit FlowAwareMarginEnd() const;
LayoutUnit FlowAwareMarginBefore() const;
+
+ LayoutUnit MainAxisMarginExtent() const;
LayoutUnit CrossAxisMarginExtent() const;
LayoutUnit MarginBoxAscent() const;
@@ -178,15 +185,18 @@ class FlexItem {
bool is_wrap_reverse,
bool is_deprecated_webkit_box);
- FlexLayoutAlgorithm* algorithm;
+ const FlexLayoutAlgorithm* algorithm;
wtf_size_t line_number;
LayoutBox* box;
+ const ComputedStyle& style;
const LayoutUnit flex_base_content_size;
- const MinMaxSize min_max_sizes;
- const base::Optional<MinMaxSize> min_max_cross_sizes;
+ const MinMaxSizes min_max_main_sizes;
+ const base::Optional<MinMaxSizes> min_max_cross_sizes;
const LayoutUnit hypothetical_main_content_size;
const LayoutUnit main_axis_border_padding;
- const LayoutUnit main_axis_margin;
+ const LayoutUnit cross_axis_border_padding;
+ NGPhysicalBoxStrut physical_margins;
+
LayoutUnit flexed_content_size;
// When set by the caller, this should be the size pre-stretching.
@@ -327,7 +337,7 @@ class FlexLine {
// https://drafts.csswg.org/css-flexbox/
//
// Expected usage is as follows:
-// FlexLayoutAlgorithm algorithm(Style(), MainAxisLength(), flex_items);
+// FlexLayoutAlgorithm algorithm(Style(), MainAxisLength());
// for (each child) {
// algorithm.emplace_back(...caller must compute these values...)
// }
@@ -353,14 +363,13 @@ class FlexLayoutAlgorithm {
template <typename... Args>
FlexItem& emplace_back(Args&&... args) {
- FlexItem& item = all_items_.emplace_back(std::forward<Args>(args)...);
- item.algorithm = this;
- return item;
+ return all_items_.emplace_back(this, std::forward<Args>(args)...);
}
const ComputedStyle* Style() const { return style_; }
const ComputedStyle& StyleRef() const { return *style_; }
+ const Vector<FlexLine>& FlexLines() const { return flex_lines_; }
Vector<FlexLine>& FlexLines() { return flex_lines_; }
// Computes the next flex line, stores it in FlexLines(), and returns a
diff --git a/chromium/third_party/blink/renderer/core/layout/floating_objects.cc b/chromium/third_party/blink/renderer/core/layout/floating_objects.cc
index 1fe5923973b..d3bc48f940f 100644
--- a/chromium/third_party/blink/renderer/core/layout/floating_objects.cc
+++ b/chromium/third_party/blink/renderer/core/layout/floating_objects.cc
@@ -47,7 +47,7 @@ struct SameSizeAsFloatingObject {
static_assert(sizeof(FloatingObject) == sizeof(SameSizeAsFloatingObject),
"FloatingObject should stay small");
-FloatingObject::FloatingObject(LayoutBox* layout_object, Type type)
+FloatingObject::FloatingObject(PassKey key, LayoutBox* layout_object, Type type)
: layout_object_(layout_object),
originating_line_(nullptr),
type_(type),
@@ -63,7 +63,8 @@ FloatingObject::FloatingObject(LayoutBox* layout_object, Type type)
{
}
-FloatingObject::FloatingObject(LayoutBox* layout_object,
+FloatingObject::FloatingObject(PassKey key,
+ LayoutBox* layout_object,
Type type,
const LayoutRect& frame_rect,
bool should_paint,
@@ -89,7 +90,7 @@ FloatingObject::FloatingObject(LayoutBox* layout_object,
std::unique_ptr<FloatingObject> FloatingObject::Create(LayoutBox* layout_object,
Type type) {
std::unique_ptr<FloatingObject> new_obj =
- base::WrapUnique(new FloatingObject(layout_object, type));
+ base::WrapUnique(new FloatingObject(PassKey(), layout_object, type));
// If a layer exists, the float will paint itself. Otherwise someone else
// will.
@@ -114,14 +115,14 @@ std::unique_ptr<FloatingObject> FloatingObject::CopyToNewContainer(
bool should_paint,
bool is_descendant) const {
return base::WrapUnique(new FloatingObject(
- GetLayoutObject(), GetType(),
+ PassKey(), GetLayoutObject(), GetType(),
LayoutRect(FrameRect().Location() - offset, FrameRect().Size()),
should_paint, is_descendant, IsLowestNonOverhangingFloatInChild()));
}
std::unique_ptr<FloatingObject> FloatingObject::UnsafeClone() const {
std::unique_ptr<FloatingObject> clone_object = base::WrapUnique(
- new FloatingObject(GetLayoutObject(), GetType(), frame_rect_,
+ new FloatingObject(PassKey(), GetLayoutObject(), GetType(), frame_rect_,
should_paint_, is_descendant_, false));
clone_object->is_placed_ = is_placed_;
#if DCHECK_IS_ON()
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 f11a30e3aad..11edc377a8d 100644
--- a/chromium/third_party/blink/renderer/core/layout/floating_objects.h
+++ b/chromium/third_party/blink/renderer/core/layout/floating_objects.h
@@ -27,6 +27,7 @@
#include <memory>
#include "base/macros.h"
+#include "base/util/type_safety/pass_key.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/list_hash_set.h"
@@ -147,15 +148,17 @@ class FloatingObject {
RootInlineBox* OriginatingLine() const { return originating_line_; }
void SetOriginatingLine(RootInlineBox* line) { originating_line_ = line; }
- private:
- FloatingObject(LayoutBox*, Type);
- FloatingObject(LayoutBox*,
+ using PassKey = util::PassKey<FloatingObject>;
+ FloatingObject(PassKey, LayoutBox*, Type);
+ FloatingObject(PassKey,
+ LayoutBox*,
Type,
const LayoutRect&,
bool should_paint,
bool is_descendant,
bool is_lowest_non_overhanging_float_in_child);
+ private:
LayoutBox* layout_object_;
RootInlineBox* originating_line_;
LayoutRect frame_rect_;
diff --git a/chromium/third_party/blink/renderer/core/layout/generated_children.h b/chromium/third_party/blink/renderer/core/layout/generated_children.h
index 52db3958b73..6ed0c9020de 100644
--- a/chromium/third_party/blink/renderer/core/layout/generated_children.h
+++ b/chromium/third_party/blink/renderer/core/layout/generated_children.h
@@ -18,7 +18,7 @@ static bool CanHaveGeneratedChildren(const LayoutObject& layout_object) {
// FIXME: LayoutMedia::layout makes assumptions about what children are
// allowed so we can't support generated content.
if (layout_object.IsMedia() || layout_object.IsTextControl() ||
- layout_object.IsMenuList())
+ IsMenuList(&layout_object))
return false;
// Input elements can't have generated children, but button elements can.
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 f435b7ec3bd..20ddb662d16 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
@@ -96,6 +96,8 @@ struct CORE_EXPORT PhysicalOffset {
: left(point.X()), top(point.Y()) {}
explicit PhysicalOffset(const IntSize& size)
: left(size.Width()), top(size.Height()) {}
+ explicit PhysicalOffset(const gfx::Point& point)
+ : left(point.x()), top(point.y()) {}
static PhysicalOffset FromFloatPointFloor(const FloatPoint& point) {
return {LayoutUnit::FromFloatFloor(point.X()),
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 35436292847..8c8a236c58c 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
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_GEOMETRY_PHYSICAL_RECT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_GEOMETRY_PHYSICAL_RECT_H_
+#include "base/compiler_specific.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/geometry/physical_offset.h"
#include "third_party/blink/renderer/core/layout/geometry/physical_rect.h"
@@ -97,8 +98,8 @@ struct CORE_EXPORT PhysicalRect {
return Contains(point.left, point.top);
}
- bool Intersects(const PhysicalRect&) const;
- bool IntersectsInclusively(const PhysicalRect&) const;
+ WARN_UNUSED_RESULT bool Intersects(const PhysicalRect&) const;
+ WARN_UNUSED_RESULT bool IntersectsInclusively(const PhysicalRect&) const;
// Whether all edges of the rect are at full-pixel boundaries.
// i.e.: EnclosingIntRect(this)) == this
@@ -107,10 +108,6 @@ struct CORE_EXPORT PhysicalRect {
!size.width.HasFraction() && !size.height.HasFraction();
}
- PhysicalRect operator+(const PhysicalOffset&) const {
- return {this->offset + offset, size};
- }
-
void Unite(const PhysicalRect&);
void UniteIfNonZero(const PhysicalRect&);
void UniteEvenIfEmpty(const PhysicalRect&);
diff --git a/chromium/third_party/blink/renderer/core/layout/grid.cc b/chromium/third_party/blink/renderer/core/layout/grid.cc
index f13eca09ca2..d86bcfc238c 100644
--- a/chromium/third_party/blink/renderer/core/layout/grid.cc
+++ b/chromium/third_party/blink/renderer/core/layout/grid.cc
@@ -8,6 +8,7 @@
#include <memory>
#include <utility>
+#include "base/memory/ptr_util.h"
#include "third_party/blink/renderer/core/layout/layout_grid.h"
namespace blink {
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 65bdebf1006..e9779901a9d 100644
--- a/chromium/third_party/blink/renderer/core/layout/grid_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/grid_test.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/layout/grid.h"
#include "third_party/blink/renderer/core/layout/layout_grid.h"
+#include "base/memory/ptr_util.h"
#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
namespace blink {
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 d803cb4052f..9ac29ea0ea3 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
@@ -148,29 +148,47 @@ class DefiniteSizeStrategy final : public GridTrackSizingAlgorithmStrategy {
GridTrackSizingAlgorithmStrategy::~GridTrackSizingAlgorithmStrategy() = default;
-bool GridTrackSizingAlgorithmStrategy::
- ShouldClearOverrideContainingBlockContentSizeForChild(
- const LayoutGrid& grid,
- const LayoutBox& child,
- GridTrackSizingDirection direction) {
+bool GridTrackSizingAlgorithmStrategy::HasRelativeMarginOrPaddingForChild(
+ const LayoutGrid& grid,
+ const LayoutBox& child,
+ GridTrackSizingDirection direction) {
GridTrackSizingDirection child_inline_direction =
GridLayoutUtils::FlowAwareDirectionForChild(grid, child, kForColumns);
if (direction == child_inline_direction) {
- return child.HasRelativeLogicalWidth() ||
- child.StyleRef().LogicalWidth().IsIntrinsicOrAuto() ||
- child.StyleRef().MarginStart().IsPercentOrCalc() ||
+ return child.StyleRef().MarginStart().IsPercentOrCalc() ||
child.StyleRef().MarginEnd().IsPercentOrCalc() ||
child.StyleRef().PaddingStart().IsPercentOrCalc() ||
child.StyleRef().PaddingEnd().IsPercentOrCalc();
}
- return child.HasRelativeLogicalHeight() ||
- child.StyleRef().LogicalHeight().IsIntrinsicOrAuto() ||
- child.StyleRef().MarginBefore().IsPercentOrCalc() ||
+ return child.StyleRef().MarginBefore().IsPercentOrCalc() ||
child.StyleRef().MarginAfter().IsPercentOrCalc() ||
child.StyleRef().PaddingBefore().IsPercentOrCalc() ||
child.StyleRef().PaddingAfter().IsPercentOrCalc();
}
+bool GridTrackSizingAlgorithmStrategy::HasRelativeOrIntrinsicSizeForChild(
+ const LayoutGrid& grid,
+ const LayoutBox& child,
+ GridTrackSizingDirection direction) {
+ GridTrackSizingDirection child_inline_direction =
+ GridLayoutUtils::FlowAwareDirectionForChild(grid, child, kForColumns);
+ if (direction == child_inline_direction) {
+ return child.HasRelativeLogicalWidth() ||
+ child.StyleRef().LogicalWidth().IsIntrinsicOrAuto();
+ }
+ return child.HasRelativeLogicalHeight() ||
+ child.StyleRef().LogicalHeight().IsIntrinsicOrAuto();
+}
+
+bool GridTrackSizingAlgorithmStrategy::
+ ShouldClearOverrideContainingBlockContentSizeForChild(
+ const LayoutGrid& grid,
+ const LayoutBox& child,
+ GridTrackSizingDirection direction) {
+ return HasRelativeOrIntrinsicSizeForChild(grid, child, direction) ||
+ HasRelativeMarginOrPaddingForChild(grid, child, direction);
+}
+
void GridTrackSizingAlgorithmStrategy::
SetOverrideContainingBlockContentSizeForChild(
LayoutBox& child,
@@ -224,7 +242,8 @@ LayoutUnit GridTrackSizingAlgorithm::EstimatedGridAreaBreadthForChild(
kForColumns);
if (grid_area_is_indefinite) {
return direction == child_inline_direction
- ? std::max(child.MaxPreferredLogicalWidth(), grid_area_size)
+ ? std::max(child.PreferredLogicalWidths().max_size,
+ grid_area_size)
: LayoutUnit(-1);
}
return grid_area_size;
@@ -338,7 +357,7 @@ LayoutUnit GridTrackSizingAlgorithmStrategy::MinContentForChild(
// FIXME: It's unclear if we should return the intrinsic width or the
// preferred width.
// See http://lists.w3.org/Archives/Public/www-style/2013Jan/0245.html
- return child.MinPreferredLogicalWidth() +
+ return child.PreferredLogicalWidths().min_size +
GridLayoutUtils::MarginLogicalWidthForChild(*GetLayoutGrid(),
child) +
algorithm_.BaselineOffsetForChild(child,
@@ -362,7 +381,7 @@ LayoutUnit GridTrackSizingAlgorithmStrategy::MaxContentForChild(
// FIXME: It's unclear if we should return the intrinsic width or the
// preferred width.
// See http://lists.w3.org/Archives/Public/www-style/2013Jan/0245.html
- return child.MaxPreferredLogicalWidth() +
+ return child.PreferredLogicalWidths().max_size +
GridLayoutUtils::MarginLogicalWidthForChild(*GetLayoutGrid(),
child) +
algorithm_.BaselineOffsetForChild(child,
@@ -570,8 +589,11 @@ LayoutUnit DefiniteSizeStrategy::MinLogicalSizeForChild(
kForColumns);
LayoutUnit indefinite_size =
Direction() == child_inline_direction ? LayoutUnit() : LayoutUnit(-1);
- if (ShouldClearOverrideContainingBlockContentSizeForChild(
- *GetLayoutGrid(), child, Direction())) {
+ if (HasRelativeMarginOrPaddingForChild(*GetLayoutGrid(), child,
+ Direction()) ||
+ (Direction() != child_inline_direction &&
+ HasRelativeOrIntrinsicSizeForChild(*GetLayoutGrid(), child,
+ Direction()))) {
SetOverrideContainingBlockContentSizeForChild(child, Direction(),
indefinite_size);
}
diff --git a/chromium/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.h b/chromium/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.h
index c2f67decf4f..5472026fedd 100644
--- a/chromium/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.h
+++ b/chromium/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.h
@@ -326,6 +326,12 @@ class GridTrackSizingAlgorithmStrategy {
}
// Helper functions
+ static bool HasRelativeMarginOrPaddingForChild(const LayoutGrid&,
+ const LayoutBox& child,
+ GridTrackSizingDirection);
+ static bool HasRelativeOrIntrinsicSizeForChild(const LayoutGrid&,
+ const LayoutBox& child,
+ GridTrackSizingDirection);
static bool ShouldClearOverrideContainingBlockContentSizeForChild(
const LayoutGrid&,
const LayoutBox& child,
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 2b536141ab6..5a46d3b68cb 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(blink::Visitor* visitor) {
+void HitTestCacheEntry::Trace(Visitor* visitor) {
visitor->Trace(result);
}
@@ -85,7 +85,7 @@ void HitTestCache::Clear() {
items_.clear();
}
-void HitTestCache::Trace(blink::Visitor* visitor) {
+void HitTestCache::Trace(Visitor* visitor) {
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 43f3e253c9d..985e58c1840 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(blink::Visitor*);
+ void Trace(Visitor*);
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(blink::Visitor*);
+ void Trace(Visitor*);
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 8c1f87c84d1..79e9b485d94 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(blink::Visitor* visitor) {
+void HitTestCanvasResult::Trace(Visitor* visitor) {
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 341faf0840b..4dcc8d19cdb 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(blink::Visitor*);
+ void Trace(Visitor*);
private:
String id_;
diff --git a/chromium/third_party/blink/renderer/core/layout/hit_test_location.cc b/chromium/third_party/blink/renderer/core/layout/hit_test_location.cc
index e68cb3bd7dd..bae6bafa322 100644
--- a/chromium/third_party/blink/renderer/core/layout/hit_test_location.cc
+++ b/chromium/third_party/blink/renderer/core/layout/hit_test_location.cc
@@ -88,8 +88,6 @@ HitTestLocation::HitTestLocation(const HitTestLocation& other,
HitTestLocation::HitTestLocation(const HitTestLocation& other) = default;
-HitTestLocation::~HitTestLocation() = default;
-
HitTestLocation& HitTestLocation::operator=(const HitTestLocation& other) =
default;
diff --git a/chromium/third_party/blink/renderer/core/layout/hit_test_location.h b/chromium/third_party/blink/renderer/core/layout/hit_test_location.h
index 08b89056581..016b930ff21 100644
--- a/chromium/third_party/blink/renderer/core/layout/hit_test_location.h
+++ b/chromium/third_party/blink/renderer/core/layout/hit_test_location.h
@@ -62,7 +62,6 @@ class CORE_EXPORT HitTestLocation {
HitTestLocation(const HitTestLocation&, const PhysicalOffset& offset);
HitTestLocation(const HitTestLocation&);
- ~HitTestLocation();
HitTestLocation& operator=(const HitTestLocation&);
const PhysicalOffset& Point() const { return point_; }
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 2138f41923d..68ac6dfdaa8 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
@@ -29,6 +29,7 @@
#include "third_party/blink/renderer/core/editing/position_with_affinity.h"
#include "third_party/blink/renderer/core/editing/visible_units.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/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/html/html_area_element.h"
@@ -38,7 +39,10 @@
#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/core/input_type_names.h"
+#include "third_party/blink/renderer/core/layout/layout_block.h"
#include "third_party/blink/renderer/core/layout/layout_image.h"
+#include "third_party/blink/renderer/core/page/page.h"
+#include "third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.h"
#include "third_party/blink/renderer/core/scroll/scrollbar.h"
#include "third_party/blink/renderer/core/svg/svg_element.h"
#include "third_party/blink/renderer/platform/geometry/region.h"
@@ -124,7 +128,7 @@ void HitTestResult::PopulateFromCachedResult(const HitTestResult& other) {
: nullptr;
}
-void HitTestResult::Trace(blink::Visitor* visitor) {
+void HitTestResult::Trace(Visitor* visitor) {
visitor->Trace(inner_node_);
visitor->Trace(inert_node_);
visitor->Trace(inner_element_);
@@ -174,6 +178,31 @@ void HitTestResult::SetToShadowHostIfInRestrictedShadowRoot() {
SetInnerNode(shadow_host);
}
+CompositorElementId HitTestResult::GetScrollableContainer() const {
+ DCHECK(InnerNode());
+ LayoutBox* cur_box = InnerNode()->GetLayoutObject()->EnclosingBox();
+
+ // Scrolling propagates along the containing block chain and ends at the
+ // RootScroller node. The RootScroller node will have a custom applyScroll
+ // callback that performs scrolling as well as associated "root" actions like
+ // browser control movement and overscroll glow.
+ while (cur_box) {
+ if (cur_box->IsGlobalRootScroller() ||
+ cur_box->NeedsScrollNode(CompositingReason::kNone)) {
+ return CompositorElementIdFromUniqueObjectId(
+ cur_box->UniqueId(), CompositorElementIdNamespace::kScroll);
+ }
+
+ cur_box = cur_box->ContainingBlock();
+ }
+
+ return InnerNode()
+ ->GetDocument()
+ .GetPage()
+ ->GetVisualViewport()
+ .GetScrollElementId();
+}
+
HTMLAreaElement* HitTestResult::ImageAreaForImage() const {
DCHECK(inner_node_);
auto* image_element = DynamicTo<HTMLImageElement>(inner_node_.Get());
@@ -374,9 +403,7 @@ HTMLMediaElement* HitTestResult::MediaElement() const {
inner_node_->GetLayoutObject()->IsMedia()))
return nullptr;
- if (IsHTMLMediaElement(*inner_node_))
- return ToHTMLMediaElement(inner_node_);
- return nullptr;
+ return DynamicTo<HTMLMediaElement>(*inner_node_);
}
KURL HitTestResult::AbsoluteLinkURL() const {
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 c6ea07e53a6..d40ba852d00 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
@@ -27,6 +27,7 @@
#include "third_party/blink/renderer/core/layout/geometry/physical_offset.h"
#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/page/chrome_client.h"
#include "third_party/blink/renderer/platform/geometry/float_quad.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -66,7 +67,7 @@ class CORE_EXPORT HitTestResult {
HitTestResult(const HitTestResult&);
~HitTestResult();
HitTestResult& operator=(const HitTestResult&);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
bool EqualForCacheability(const HitTestResult&) const;
void CacheValues(const HitTestResult& other);
@@ -86,6 +87,7 @@ class CORE_EXPORT HitTestResult {
Node* InnerPossiblyPseudoNode() const {
return inner_possibly_pseudo_node_.Get();
}
+ CompositorElementId GetScrollableContainer() const;
Element* InnerElement() const { return inner_element_.Get(); }
// If innerNode is an image map or image map area, return the associated image
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 228e4a3494e..c17f2501e74 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_block.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_block.cc
@@ -32,7 +32,6 @@
#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/dom/element.h"
-#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/editing/drag_caret.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
@@ -103,7 +102,6 @@ LayoutBlock::LayoutBlock(ContainerNode* node)
: LayoutBox(node),
has_margin_before_quirk_(false),
has_margin_after_quirk_(false),
- being_destroyed_(false),
has_markup_truncation_(false),
width_available_to_children_changed_(false),
height_available_to_children_changed_(false),
@@ -461,6 +459,7 @@ void LayoutBlock::ComputeVisualOverflow(bool) {
AddVisualOverflowFromTheme();
if (VisualOverflowRect() != previous_visual_overflow_rect) {
+ InvalidateIntersectionObserverCachedRects();
SetShouldCheckForPaintInvalidation();
GetFrameView()->SetIntersectionObservationState(LocalFrameView::kDesired);
}
@@ -548,7 +547,7 @@ void LayoutBlock::AddLayoutOverflowFromPositionedObjects() {
// Fixed positioned elements whose containing block is the LayoutView
// don't contribute to layout overflow, since they don't scroll with the
// content.
- if (!IsLayoutView() ||
+ if (!IsA<LayoutView>(this) ||
positioned_object->StyleRef().GetPosition() != EPosition::kFixed) {
AddLayoutOverflowFromChild(*positioned_object,
ToLayoutSize(positioned_object->Location()));
@@ -593,7 +592,8 @@ void LayoutBlock::UpdateBlockChildDirtyBitsBeforeLayout(bool relayout_children,
child.HasRelativeLogicalHeight() ||
(child.IsAnonymous() && HasRelativeLogicalHeight()) ||
child.StretchesToViewport();
- if (relayout_children || (has_relative_logical_height && !IsLayoutView()) ||
+ if (relayout_children ||
+ (has_relative_logical_height && !IsA<LayoutView>(this)) ||
(height_available_to_children_changed_ &&
ChangeInAvailableLogicalHeightAffectsChild(this, child)) ||
(child.IsListMarker() && IsListItem() &&
@@ -719,11 +719,11 @@ void LayoutBlock::MarkFixedPositionObjectForLayoutIfNeeded(
return;
LayoutObject* o = child->Parent();
- while (!o->IsLayoutView() &&
- o->StyleRef().GetPosition() != EPosition::kAbsolute)
+ bool is_layout_view = IsA<LayoutView>(o);
+ while (!is_layout_view && o->StyleRef().GetPosition() != EPosition::kAbsolute)
o = o->Parent();
// The LayoutView is absolute-positioned, but does not move.
- if (o->IsLayoutView())
+ if (is_layout_view)
return;
// We must compute child's width and height, but not update them now.
@@ -1176,7 +1176,7 @@ bool LayoutBlock::IsPointInOverflowControl(
bool LayoutBlock::HitTestOverflowControl(
HitTestResult& result,
const HitTestLocation& hit_test_location,
- const PhysicalOffset& adjusted_location) {
+ const PhysicalOffset& adjusted_location) const {
if (VisibleToHitTestRequest(result.GetHitTestRequest()) &&
IsPointInOverflowControl(result, hit_test_location.Point(),
adjusted_location)) {
@@ -1262,7 +1262,7 @@ static inline bool IsEditingBoundary(const LayoutObject* ancestor,
DCHECK(child);
DCHECK(child.NonPseudoNode());
return !ancestor || !ancestor->Parent() ||
- (ancestor->HasLayer() && ancestor->Parent()->IsLayoutView()) ||
+ (ancestor->HasLayer() && IsA<LayoutView>(ancestor->Parent())) ||
HasEditableStyle(*ancestor->NonPseudoNode()) ==
HasEditableStyle(*child.NonPseudoNode());
}
@@ -1399,10 +1399,9 @@ void LayoutBlock::ScrollbarsChanged(bool horizontal_scrollbar_changed,
height_available_to_children_changed_ |= horizontal_scrollbar_changed;
}
-void LayoutBlock::ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const {
- int scrollbar_width = ScrollbarLogicalWidth();
+MinMaxSizes LayoutBlock::ComputeIntrinsicLogicalWidths() const {
+ MinMaxSizes sizes;
+ sizes += BorderAndPaddingLogicalWidth() + ScrollbarLogicalWidth();
// See if we can early out sooner if the logical width is overridden or we're
// size contained. Note that for multicol containers we need the column gaps.
@@ -1410,50 +1409,56 @@ void LayoutBlock::ComputeIntrinsicLogicalWidths(
const auto* block_flow = DynamicTo<LayoutBlockFlow>(this);
if (!block_flow || !block_flow->MultiColumnFlowThread()) {
if (HasOverrideIntrinsicContentLogicalWidth()) {
- max_logical_width = min_logical_width =
- OverrideIntrinsicContentLogicalWidth() + LayoutUnit(scrollbar_width);
- return;
+ sizes += OverrideIntrinsicContentLogicalWidth();
+ return sizes;
}
- if (ShouldApplySizeContainment()) {
- max_logical_width = min_logical_width = LayoutUnit(scrollbar_width);
- return;
+ LayoutUnit default_inline_size = DefaultIntrinsicContentInlineSize();
+ if (default_inline_size != kIndefiniteSize) {
+ sizes.max_size += default_inline_size;
+ if (!StyleRef().LogicalWidth().IsPercentOrCalc())
+ sizes.min_size = sizes.max_size;
+ return sizes;
}
+ if (ShouldApplySizeContainment())
+ return sizes;
}
+ MinMaxSizes child_sizes;
if (ChildrenInline()) {
// FIXME: Remove this const_cast.
To<LayoutBlockFlow>(const_cast<LayoutBlock*>(this))
- ->ComputeInlinePreferredLogicalWidths(min_logical_width,
- max_logical_width);
+ ->ComputeInlinePreferredLogicalWidths(child_sizes.min_size,
+ child_sizes.max_size);
} else {
- ComputeBlockPreferredLogicalWidths(min_logical_width, max_logical_width);
+ ComputeBlockPreferredLogicalWidths(child_sizes.min_size,
+ child_sizes.max_size);
}
- max_logical_width = std::max(min_logical_width, max_logical_width);
+ child_sizes.max_size = std::max(child_sizes.min_size, child_sizes.max_size);
auto* html_marquee_element = DynamicTo<HTMLMarqueeElement>(GetNode());
if (html_marquee_element && html_marquee_element->IsHorizontal())
- min_logical_width = LayoutUnit();
+ child_sizes.min_size = LayoutUnit();
+ if (UNLIKELY(IsListBox(this) && StyleRef().LogicalWidth().IsPercentOrCalc()))
+ child_sizes.min_size = LayoutUnit();
if (IsTableCell()) {
Length table_cell_width =
ToInterface<LayoutNGTableCellInterface>(this)->StyleOrColLogicalWidth();
- if (table_cell_width.IsFixed() && table_cell_width.Value() > 0)
- max_logical_width = std::max(min_logical_width,
- AdjustContentBoxLogicalWidthForBoxSizing(
- LayoutUnit(table_cell_width.Value())));
+ if (table_cell_width.IsFixed() && table_cell_width.Value() > 0) {
+ child_sizes.max_size = std::max(
+ child_sizes.min_size, AdjustContentBoxLogicalWidthForBoxSizing(
+ LayoutUnit(table_cell_width.Value())));
+ }
}
- max_logical_width += scrollbar_width;
- min_logical_width += scrollbar_width;
+ sizes += child_sizes;
+ return sizes;
}
DISABLE_CFI_PERF
-void LayoutBlock::ComputePreferredLogicalWidths() {
- DCHECK(PreferredLogicalWidthsDirty());
-
- min_preferred_logical_width_ = LayoutUnit();
- max_preferred_logical_width_ = LayoutUnit();
+MinMaxSizes LayoutBlock::PreferredLogicalWidths() const {
+ MinMaxSizes sizes;
// FIXME: The isFixed() calls here should probably be checking for isSpecified
// since you should be able to use percentage, calc or viewport relative
@@ -1462,52 +1467,32 @@ void LayoutBlock::ComputePreferredLogicalWidths() {
if (!IsTableCell() && style_to_use.LogicalWidth().IsFixed() &&
style_to_use.LogicalWidth().Value() >= 0 &&
!(IsFlexItemCommon() && Parent()->StyleRef().IsDeprecatedWebkitBox() &&
- !style_to_use.LogicalWidth().IntValue()))
- min_preferred_logical_width_ = max_preferred_logical_width_ =
- AdjustContentBoxLogicalWidthForBoxSizing(
- LayoutUnit(style_to_use.LogicalWidth().Value()));
- else
- ComputeIntrinsicLogicalWidths(min_preferred_logical_width_,
- max_preferred_logical_width_);
+ !style_to_use.LogicalWidth().IntValue())) {
+ sizes = AdjustBorderBoxLogicalWidthForBoxSizing(
+ LayoutUnit(style_to_use.LogicalWidth().Value()));
+ } else {
+ sizes = IntrinsicLogicalWidths();
+ }
if (style_to_use.LogicalMaxWidth().IsFixed()) {
- max_preferred_logical_width_ =
- std::min(max_preferred_logical_width_,
- AdjustContentBoxLogicalWidthForBoxSizing(
- LayoutUnit(style_to_use.LogicalMaxWidth().Value())));
- min_preferred_logical_width_ =
- std::min(min_preferred_logical_width_,
- AdjustContentBoxLogicalWidthForBoxSizing(
- LayoutUnit(style_to_use.LogicalMaxWidth().Value())));
+ sizes.Constrain(AdjustBorderBoxLogicalWidthForBoxSizing(
+ LayoutUnit(style_to_use.LogicalMaxWidth().Value())));
}
if (style_to_use.LogicalMinWidth().IsFixed() &&
style_to_use.LogicalMinWidth().Value() > 0) {
- max_preferred_logical_width_ =
- std::max(max_preferred_logical_width_,
- AdjustContentBoxLogicalWidthForBoxSizing(
- LayoutUnit(style_to_use.LogicalMinWidth().Value())));
- min_preferred_logical_width_ =
- std::max(min_preferred_logical_width_,
- AdjustContentBoxLogicalWidthForBoxSizing(
- LayoutUnit(style_to_use.LogicalMinWidth().Value())));
+ sizes.Encompass(AdjustBorderBoxLogicalWidthForBoxSizing(
+ LayoutUnit(style_to_use.LogicalMinWidth().Value())));
}
- LayoutUnit border_and_padding = BorderAndPaddingLogicalWidth();
- DCHECK_GE(border_and_padding, LayoutUnit());
- min_preferred_logical_width_ += border_and_padding;
- max_preferred_logical_width_ += border_and_padding;
-
// Table layout uses integers, ceil the preferred widths to ensure that they
// can contain the contents.
if (IsTableCell()) {
- min_preferred_logical_width_ =
- LayoutUnit(min_preferred_logical_width_.Ceil());
- max_preferred_logical_width_ =
- LayoutUnit(max_preferred_logical_width_.Ceil());
+ sizes.min_size = LayoutUnit(sizes.min_size.Ceil());
+ sizes.max_size = LayoutUnit(sizes.max_size.Ceil());
}
- ClearPreferredLogicalWidthsDirty();
+ return sizes;
}
void LayoutBlock::ComputeBlockPreferredLogicalWidths(
@@ -1532,7 +1517,10 @@ void LayoutBlock::ComputeBlockPreferredLogicalWidths(
// We don't really know whether the containing block of this child did
// change or is going to change size. However, this is our only
// opportunity to make sure that it gets its min/max widths calculated.
- child->SetPreferredLogicalWidthsDirty();
+ // This is also an important hook for flow threads; if the container of a
+ // flow thread needs its preferred logical widths recalculated, so does
+ // the flow thread, potentially.
+ child->SetIntrinsicLogicalWidthsDirty();
}
scoped_refptr<const ComputedStyle> child_style = child->Style();
@@ -1648,8 +1636,10 @@ void LayoutBlock::ComputeChildPreferredLogicalWidths(
ToLayoutBox(child).ComputeLogicalHeightWithoutLayout();
return;
}
- min_preferred_logical_width = child.MinPreferredLogicalWidth();
- max_preferred_logical_width = child.MaxPreferredLogicalWidth();
+
+ MinMaxSizes child_preferred_logical_widths = child.PreferredLogicalWidths();
+ min_preferred_logical_width = child_preferred_logical_widths.min_size;
+ max_preferred_logical_width = child_preferred_logical_widths.max_size;
// For non-replaced blocks if the inline size is min|max-content or a definite
// size the min|max-content contribution is that size plus border, padding and
@@ -1664,18 +1654,29 @@ void LayoutBlock::ComputeChildPreferredLogicalWidths(
}
bool LayoutBlock::HasLineIfEmpty() const {
- if (!GetNode())
- return false;
-
- if (IsRootEditableElement(*GetNode()))
- return true;
-
- if (auto* shadow_root = DynamicTo<ShadowRoot>(GetNode())) {
- if (IsA<HTMLInputElement>(shadow_root->host()))
+ if (GetNode()) {
+ if (IsRootEditableElement(*GetNode()))
return true;
}
+ return FirstLineStyleRef().HasLineIfEmpty();
+}
- return false;
+LayoutUnit LayoutBlock::EmptyLineBaseline(
+ LineDirectionMode line_direction) const {
+ if (!HasLineIfEmpty())
+ return LayoutUnit(-1);
+ const SimpleFontData* font_data = FirstLineStyle()->GetFont().PrimaryFont();
+ if (!font_data)
+ return LayoutUnit(-1);
+ const auto& font_metrics = font_data->GetFontMetrics();
+ const LayoutUnit line_height =
+ LineHeight(true, line_direction, kPositionOfInteriorLineBoxes);
+ const LayoutUnit border_padding = line_direction == kHorizontalLine
+ ? BorderTop() + PaddingTop()
+ : BorderRight() + PaddingRight();
+ return LayoutUnit((font_metrics.Ascent() +
+ (line_height - font_metrics.Height()) / 2 + border_padding)
+ .ToInt());
}
LayoutUnit LayoutBlock::LineHeight(bool first_line,
@@ -1816,7 +1817,7 @@ bool LayoutBlock::UseLogicalBottomMarginEdgeForInlineBlockBaseline() const {
// where the block's contents shouldn't be considered when laying out its
// ancestors or siblings.
return (!StyleRef().IsOverflowVisible() &&
- !ShouldIgnoreOverflowPropertyForInlineBlockBaseline()) ||
+ !StyleRef().ShouldIgnoreOverflowPropertyForInlineBlockBaseline()) ||
ShouldApplyLayoutContainment();
}
@@ -1845,18 +1846,8 @@ LayoutUnit LayoutBlock::InlineBlockBaseline(
}
}
}
- const SimpleFontData* font_data = FirstLineStyle()->GetFont().PrimaryFont();
- if (font_data && !have_normal_flow_child && HasLineIfEmpty()) {
- const FontMetrics& font_metrics = font_data->GetFontMetrics();
- return LayoutUnit(
- (font_metrics.Ascent() +
- (LineHeight(true, line_direction, kPositionOfInteriorLineBoxes) -
- font_metrics.Height()) /
- 2 +
- (line_direction == kHorizontalLine ? BorderTop() + PaddingTop()
- : BorderRight() + PaddingRight()))
- .ToInt());
- }
+ if (!have_normal_flow_child)
+ return EmptyLineBaseline(line_direction);
return LayoutUnit(-1);
}
@@ -2320,7 +2311,7 @@ LayoutUnit LayoutBlock::AvailableLogicalHeightForPercentageComputation() const {
available_height = computed_values.extent_ -
BorderAndPaddingLogicalHeight() -
ScrollbarLogicalHeight();
- } else if (IsLayoutView()) {
+ } else if (IsA<LayoutView>(this)) {
available_height = View()->ViewLogicalHeightForPercentages();
}
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 64c3ba8c89a..68f16211d48 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_block.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_block.h
@@ -142,6 +142,10 @@ class CORE_EXPORT LayoutBlock : public LayoutBox {
const char* GetName() const override;
+ virtual const NGPhysicalBoxFragment* CurrentFragment() const {
+ return nullptr;
+ }
+
protected:
// Insert a child correctly into the tree when |beforeDescendant| isn't a
// direct child of |this|. This happens e.g. when there's an anonymous block
@@ -395,6 +399,7 @@ class CORE_EXPORT LayoutBlock : public LayoutBox {
virtual void PaintChildren(const PaintInfo&,
const PhysicalOffset& paint_offset) const;
void UpdateAfterLayout() override;
+ MinMaxSizes PreferredLogicalWidths() const override;
protected:
virtual void AdjustInlineDirectionLineBounds(
@@ -402,10 +407,7 @@ class CORE_EXPORT LayoutBlock : public LayoutBox {
LayoutUnit& /* logicalLeft */,
LayoutUnit& /* logicalWidth */) const {}
- void ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const override;
- void ComputePreferredLogicalWidths() override;
+ MinMaxSizes ComputeIntrinsicLogicalWidths() const override;
void ComputeChildPreferredLogicalWidths(
LayoutObject& child,
LayoutUnit& min_preferred_logical_width,
@@ -414,17 +416,10 @@ class CORE_EXPORT LayoutBlock : public LayoutBox {
LayoutUnit FirstLineBoxBaseline() const override;
LayoutUnit InlineBlockBaseline(LineDirectionMode) const override;
- // This function disables the 'overflow' check in inlineBlockBaseline.
- // For 'inline-block', CSS says that the baseline is the bottom margin edge
- // if 'overflow' is not visible. But some descendant classes want to ignore
- // this condition.
- virtual bool ShouldIgnoreOverflowPropertyForInlineBlockBaseline() const {
- return false;
- }
-
- bool HitTestOverflowControl(HitTestResult&,
- const HitTestLocation&,
- const PhysicalOffset& adjusted_location) override;
+ bool HitTestOverflowControl(
+ HitTestResult&,
+ const HitTestLocation&,
+ const PhysicalOffset& adjusted_location) const override;
bool HitTestChildren(HitTestResult&,
const HitTestLocation&,
const PhysicalOffset& accumulated_offset,
@@ -482,6 +477,8 @@ class CORE_EXPORT LayoutBlock : public LayoutBox {
hit_test_action == kHitTestChildBlockBackground;
}
+ LayoutUnit EmptyLineBaseline(LineDirectionMode line_direction) const;
+
private:
LayoutObjectChildList* VirtualChildren() final { return Children(); }
const LayoutObjectChildList* VirtualChildren() const final {
@@ -558,7 +555,6 @@ class CORE_EXPORT LayoutBlock : public LayoutBox {
// in LayoutBlockRareData since they are
// set too frequently.
unsigned has_margin_after_quirk_ : 1;
- unsigned being_destroyed_ : 1;
unsigned has_markup_truncation_ : 1;
unsigned width_available_to_children_changed_ : 1;
unsigned height_available_to_children_changed_ : 1;
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 596ea315e8a..b0d5df85710 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
@@ -77,7 +77,8 @@ bool LayoutBlockFlow::can_propagate_float_into_sibling_ = false;
struct SameSizeAsLayoutBlockFlow : public LayoutBlock {
LineBoxList line_boxes;
- void* pointers[2];
+ void* pointers[1];
+ Persistent<void*> persistent[1];
};
static_assert(sizeof(LayoutBlockFlow) == sizeof(SameSizeAsLayoutBlockFlow),
@@ -131,7 +132,6 @@ class MarginInfo {
bool has_margin_after_quirk_ : 1;
bool determined_margin_before_quirk_ : 1;
- bool discard_margin_ : 1;
bool last_child_is_self_collapsing_block_with_clearance_ : 1;
// These flags track the previous maximal positive and negative margins.
@@ -155,26 +155,21 @@ class MarginInfo {
determined_margin_before_quirk_ = b;
}
void SetPositiveMargin(LayoutUnit p) {
- DCHECK(!discard_margin_);
positive_margin_ = p;
}
void SetNegativeMargin(LayoutUnit n) {
- DCHECK(!discard_margin_);
negative_margin_ = n;
}
void SetPositiveMarginIfLarger(LayoutUnit p) {
- DCHECK(!discard_margin_);
if (p > positive_margin_)
positive_margin_ = p;
}
void SetNegativeMarginIfLarger(LayoutUnit n) {
- DCHECK(!discard_margin_);
if (n > negative_margin_)
negative_margin_ = n;
}
void SetMargin(LayoutUnit p, LayoutUnit n) {
- DCHECK(!discard_margin_);
positive_margin_ = p;
negative_margin_ = n;
}
@@ -184,7 +179,6 @@ class MarginInfo {
void SetCanCollapseMarginAfterWithLastChild(bool collapse) {
can_collapse_margin_after_with_last_child_ = collapse;
}
- void SetDiscardMargin(bool value) { discard_margin_ = value; }
bool AtBeforeSideOfBlock() const { return at_before_side_of_block_; }
bool CanCollapseWithMarginBefore() const {
@@ -211,7 +205,6 @@ class MarginInfo {
bool HasMarginAfterQuirk() const { return has_margin_after_quirk_; }
LayoutUnit PositiveMargin() const { return positive_margin_; }
LayoutUnit NegativeMargin() const { return negative_margin_; }
- bool DiscardMargin() const { return discard_margin_; }
LayoutUnit Margin() const { return positive_margin_ - negative_margin_; }
void SetLastChildIsSelfCollapsingBlockWithClearance(bool value) {
last_child_is_self_collapsing_block_with_clearance_ = value;
@@ -261,9 +254,16 @@ 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; }
+
private:
MultiColumnLayoutState multi_column_layout_state_;
MarginInfo margin_info_;
+ AtomicString child_page_name_;
LayoutUnit previous_float_logical_bottom_;
EBreakBetween previous_break_after_value_;
bool is_at_first_in_flow_child_;
@@ -387,9 +387,7 @@ bool LayoutBlockFlow::CheckIfIsSelfCollapsingBlock() const {
(element && element->ShadowPseudoId() == "-webkit-input-placeholder"));
if (LogicalHeight() > LayoutUnit() ||
- StyleRef().LogicalMinHeight().IsPositive() ||
- StyleRef().MarginBeforeCollapse() == EMarginCollapse::kSeparate ||
- StyleRef().MarginAfterCollapse() == EMarginCollapse::kSeparate)
+ StyleRef().LogicalMinHeight().IsPositive())
return false;
const Length& logical_height_length = StyleRef().LogicalHeight();
@@ -398,7 +396,7 @@ bool LayoutBlockFlow::CheckIfIsSelfCollapsingBlock() const {
!GetDocument().InQuirksMode()) {
has_auto_height = true;
if (LayoutBlock* cb = ContainingBlock()) {
- if (!cb->IsLayoutView() &&
+ if (!IsA<LayoutView>(cb) &&
(cb->StyleRef().LogicalHeight().IsFixed() || cb->IsTableCell()))
has_auto_height = false;
}
@@ -467,7 +465,7 @@ void LayoutBlockFlow::UpdateBlockLayout(bool relayout_children) {
TextAutosizer::LayoutScope text_autosizer_layout_scope(this, &layout_scope);
bool pagination_state_changed = pagination_state_changed_;
- bool preferred_logical_widths_were_dirty = PreferredLogicalWidthsDirty();
+ bool intrinsic_logical_widths_were_dirty = IntrinsicLogicalWidthsDirty();
// Multiple passes might be required for column based layout.
// The number of passes could be as high as the number of columns.
@@ -484,7 +482,7 @@ void LayoutBlockFlow::UpdateBlockLayout(bool relayout_children) {
LayoutChildren(relayout_children, layout_scope);
- if (!preferred_logical_widths_were_dirty && PreferredLogicalWidthsDirty()) {
+ if (!intrinsic_logical_widths_were_dirty && IntrinsicLogicalWidthsDirty()) {
// The only thing that should dirty preferred widths at this point is the
// addition of overflow:auto scrollbars in a descendant. To avoid a
// potential infinite loop, run layout again with auto scrollbars frozen
@@ -854,6 +852,24 @@ void LayoutBlockFlow::InsertForcedBreakBeforeChildIfNeeded(
// those preceding the break.
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)
+ class_a_break_point_value = EBreakBetween::kPage;
+
if (IsForcedFragmentainerBreakValue(class_a_break_point_value)) {
layout_info.GetMarginInfo().ClearMargin();
LayoutUnit old_logical_top = LogicalHeight();
@@ -862,6 +878,10 @@ 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) {
+ // This was a forced break because of named pages.
+ layout_info.SetChildPageName(child.StyleRef().Page());
+ }
}
}
@@ -898,8 +918,6 @@ void LayoutBlockFlow::LayoutBlockChild(LayoutBox& child,
// Cache if we are at the top of the block right now.
bool at_before_side_of_block = margin_info.AtBeforeSideOfBlock();
bool child_is_self_collapsing = child.IsSelfCollapsingBlock();
- bool child_discard_margin_before = MustDiscardMarginBeforeForChild(child);
- bool child_discard_margin_after = MustDiscardMarginAfterForChild(child);
bool paginated = View()->GetLayoutState()->IsPaginated();
// If there should be a forced break before the child, we need to insert it
@@ -917,15 +935,12 @@ void LayoutBlockFlow::LayoutBlockChild(LayoutBox& child,
// Now determine the correct ypos based off examination of collapsing margin
// values.
LayoutUnit logical_top_before_clear =
- CollapseMargins(child, layout_info, child_is_self_collapsing,
- child_discard_margin_before, child_discard_margin_after);
+ CollapseMargins(child, layout_info, child_is_self_collapsing);
// Now check for clear.
- bool child_discard_margin =
- child_discard_margin_before || child_discard_margin_after;
LayoutUnit new_logical_top = ClearFloatsIfNeeded(
child, margin_info, old_pos_margin_before, old_neg_margin_before,
- logical_top_before_clear, child_is_self_collapsing, child_discard_margin);
+ logical_top_before_clear, child_is_self_collapsing);
// If there's a forced break in front of this child, its final position has
// already been determined. Otherwise, see if there are other reasons for
@@ -982,10 +997,7 @@ void LayoutBlockFlow::LayoutBlockChild(LayoutBox& child,
// Update our height now that the child has been placed in the correct
// position.
SetLogicalHeight(LogicalHeight() + LogicalHeightForChild(child));
- if (MustSeparateMarginAfterForChild(child)) {
- SetLogicalHeight(LogicalHeight() + MarginAfterForChild(child));
- margin_info.ClearMargin();
- }
+
// If the child has overhanging floats that intrude into following siblings
// (or possibly out of this block), then the parent gets notified of the
// floats now.
@@ -1376,8 +1388,9 @@ void LayoutBlockFlow::RebuildFloatsFromIntruding() {
// Inline blocks are covered by the isAtomicInlineLevel() check in the
// avoidFloats method.
- if (CreatesNewFormattingContext() || IsDocumentElement() || IsLayoutView() ||
- IsFloatingOrOutOfFlowPositioned() || IsTableCell()) {
+ if (CreatesNewFormattingContext() || IsDocumentElement() ||
+ IsA<LayoutView>(this) || IsFloatingOrOutOfFlowPositioned() ||
+ IsTableCell()) {
if (floating_objects_) {
floating_objects_->Clear();
}
@@ -1620,17 +1633,15 @@ MarginInfo::MarginInfo(LayoutBlockFlow* block_flow,
has_margin_before_quirk_(false),
has_margin_after_quirk_(false),
determined_margin_before_quirk_(false),
- discard_margin_(false),
last_child_is_self_collapsing_block_with_clearance_(false) {
const ComputedStyle& block_style = block_flow->StyleRef();
- DCHECK(block_flow->IsLayoutView() || block_flow->Parent());
+ DCHECK(IsA<LayoutView>(block_flow) || block_flow->Parent());
can_collapse_with_children_ = !block_flow->CreatesNewFormattingContext() &&
!block_flow->IsLayoutFlowThread() &&
- !block_flow->IsLayoutView();
+ !IsA<LayoutView>(block_flow);
can_collapse_margin_before_with_children_ =
- can_collapse_with_children_ && !before_border_padding &&
- block_style.MarginBeforeCollapse() != EMarginCollapse::kSeparate;
+ can_collapse_with_children_ && !before_border_padding;
// If any height other than auto is specified in CSS, then we don't collapse
// our bottom margins with our children's margins. To do otherwise would be to
@@ -1640,20 +1651,14 @@ MarginInfo::MarginInfo(LayoutBlockFlow* block_flow,
can_collapse_margin_after_with_children_ =
can_collapse_with_children_ && !after_border_padding &&
(block_style.LogicalHeight().IsAuto() &&
- !block_style.LogicalHeight().Value()) &&
- block_style.MarginAfterCollapse() != EMarginCollapse::kSeparate;
+ !block_style.LogicalHeight().Value());
quirk_container_ = block_flow->IsTableCell() || block_flow->IsBody();
- discard_margin_ = can_collapse_margin_before_with_children_ &&
- block_flow->MustDiscardMarginBefore();
-
- positive_margin_ = (can_collapse_margin_before_with_children_ &&
- !block_flow->MustDiscardMarginBefore())
+ positive_margin_ = can_collapse_margin_before_with_children_
? block_flow->MaxPositiveMarginBefore()
: LayoutUnit();
- negative_margin_ = (can_collapse_margin_before_with_children_ &&
- !block_flow->MustDiscardMarginBefore())
+ negative_margin_ = can_collapse_margin_before_with_children_
? block_flow->MaxNegativeMarginBefore()
: LayoutUnit();
}
@@ -1766,17 +1771,9 @@ static LayoutBlockFlow* PreviousBlockFlowInFormattingContext(
LayoutUnit LayoutBlockFlow::CollapseMargins(
LayoutBox& child,
BlockChildrenLayoutInfo& layout_info,
- bool child_is_self_collapsing,
- bool child_discard_margin_before,
- bool child_discard_margin_after) {
+ bool child_is_self_collapsing) {
MarginInfo& margin_info = layout_info.GetMarginInfo();
- // The child discards the before margin when the the after margin has discard
- // in the case of a self collapsing block.
- child_discard_margin_before =
- child_discard_margin_before ||
- (child_discard_margin_after && child_is_self_collapsing);
-
// Get the four margin values for the child and cache them.
const LayoutBlockFlow::MarginValues child_margins =
MarginValuesForChild(child);
@@ -1797,46 +1794,32 @@ LayoutUnit LayoutBlockFlow::CollapseMargins(
bool top_quirk = HasMarginBeforeQuirk(&child);
if (margin_info.CanCollapseWithMarginBefore()) {
- if (!child_discard_margin_before && !margin_info.DiscardMargin()) {
- // This child is collapsing with the top of the
- // block. If it has larger margin values, then we need to update
- // our own maximal values.
- if (!GetDocument().InQuirksMode() || !margin_info.QuirkContainer() ||
- !top_quirk)
- SetMaxMarginBeforeValues(std::max(pos_top, MaxPositiveMarginBefore()),
- std::max(neg_top, MaxNegativeMarginBefore()));
-
- // The minute any of the margins involved isn't a quirk, don't
- // collapse it away, even if the margin is smaller (www.webreference.com
- // has an example of this, a <dt> with 0.8em author-specified inside
- // a <dl> inside a <td>.
- if (!margin_info.DeterminedMarginBeforeQuirk() && !top_quirk &&
- (pos_top - neg_top)) {
- SetHasMarginBeforeQuirk(false);
- margin_info.SetDeterminedMarginBeforeQuirk(true);
- }
+ // This child is collapsing with the top of the block. If it has larger
+ // margin values, then we need to update our own maximal values.
+ if (!GetDocument().InQuirksMode() || !margin_info.QuirkContainer() ||
+ !top_quirk) {
+ SetMaxMarginBeforeValues(std::max(pos_top, MaxPositiveMarginBefore()),
+ std::max(neg_top, MaxNegativeMarginBefore()));
+ }
- if (!margin_info.DeterminedMarginBeforeQuirk() && top_quirk &&
- !MarginBefore()) {
- // We have no top margin and our top child has a quirky margin.
- // We will pick up this quirky margin and pass it through.
- // This deals with the <td><div><p> case.
- // Don't do this for a block that split two inlines though. You do
- // still apply margins in this case.
- SetHasMarginBeforeQuirk(true);
- }
- } else {
- // The before margin of the container will also discard all the margins it
- // is collapsing with.
- SetMustDiscardMarginBefore();
+ // The minute any of the margins involved isn't a quirk, don't collapse it
+ // away, even if the margin is smaller (www.webreference.com has an example
+ // of this, a <dt> with 0.8em author-specified inside a <dl> inside a <td>).
+ if (!margin_info.DeterminedMarginBeforeQuirk() && !top_quirk &&
+ (pos_top - neg_top)) {
+ SetHasMarginBeforeQuirk(false);
+ margin_info.SetDeterminedMarginBeforeQuirk(true);
}
- }
- // Once we find a child with discardMarginBefore all the margins collapsing
- // with us must also discard.
- if (child_discard_margin_before) {
- margin_info.SetDiscardMargin(true);
- margin_info.ClearMargin();
+ if (!margin_info.DeterminedMarginBeforeQuirk() && top_quirk &&
+ !MarginBefore()) {
+ // We have no top margin and our top child has a quirky margin.
+ // We will pick up this quirky margin and pass it through.
+ // This deals with the <td><div><p> case.
+ // Don't do this for a block that split two inlines though. You do still
+ // apply margins in this case.
+ SetHasMarginBeforeQuirk(true);
+ }
}
if (margin_info.QuirkContainer() && margin_info.AtBeforeSideOfBlock() &&
@@ -1866,71 +1849,46 @@ LayoutUnit LayoutBlockFlow::CollapseMargins(
MarginValuesForChild(*previous_block_flow).PositiveMarginBefore());
if (child_is_self_collapsing) {
- // For a self collapsing block both the before and after margins get
- // discarded. The block doesn't contribute anything to the height of the
- // block. Also, the child's top position equals the logical height of the
- // container.
- if (!child_discard_margin_before && !margin_info.DiscardMargin()) {
- // This child has no height. We need to compute our
- // position before we collapse the child's margins together,
- // so that we can get an accurate position for the zero-height block.
- LayoutUnit collapsed_before_pos = std::max(
- margin_info.PositiveMargin(), child_margins.PositiveMarginBefore());
- LayoutUnit collapsed_before_neg = std::max(
- margin_info.NegativeMargin(), child_margins.NegativeMarginBefore());
- margin_info.SetMargin(collapsed_before_pos, collapsed_before_neg);
-
- // Now collapse the child's margins together, which means examining our
- // bottom margin values as well.
- margin_info.SetPositiveMarginIfLarger(
- child_margins.PositiveMarginAfter());
- margin_info.SetNegativeMarginIfLarger(
- child_margins.NegativeMarginAfter());
-
- if (!margin_info.CanCollapseWithMarginBefore()) {
- // We need to make sure that the position of the self-collapsing block
- // is correct, since it could have overflowing content
- // that needs to be positioned correctly (e.g., a block that
- // had a specified height of 0 but that actually had subcontent).
- logical_top =
- LogicalHeight() + collapsed_before_pos - collapsed_before_neg;
- }
+ // The block doesn't contribute anything to the height of the block. Also,
+ // the child's top position equals the logical height of the container.
+
+ // This child has no height. We need to compute our position before we
+ // collapse the child's margins together, so that we can get an accurate
+ // position for the zero-height block.
+ LayoutUnit collapsed_before_pos = std::max(
+ margin_info.PositiveMargin(), child_margins.PositiveMarginBefore());
+ LayoutUnit collapsed_before_neg = std::max(
+ margin_info.NegativeMargin(), child_margins.NegativeMarginBefore());
+ margin_info.SetMargin(collapsed_before_pos, collapsed_before_neg);
+
+ // Now collapse the child's margins together, which means examining our
+ // bottom margin values as well.
+ margin_info.SetPositiveMarginIfLarger(child_margins.PositiveMarginAfter());
+ margin_info.SetNegativeMarginIfLarger(child_margins.NegativeMarginAfter());
+
+ if (!margin_info.CanCollapseWithMarginBefore()) {
+ // We need to make sure that the position of the self-collapsing block is
+ // correct, since it could have overflowing content that needs to be
+ // positioned correctly (e.g., a block that had a specified height of 0
+ // but that actually had subcontent).
+ logical_top =
+ LogicalHeight() + collapsed_before_pos - collapsed_before_neg;
}
} else {
- if (MustSeparateMarginBeforeForChild(child)) {
- DCHECK(!margin_info.DiscardMargin() ||
- (margin_info.DiscardMargin() && !margin_info.Margin()));
- // If we are at the before side of the block and we collapse, ignore the
- // computed margin and just add the child margin to the container height.
- // This will correctly position the child inside the container.
- LayoutUnit separate_margin = !margin_info.CanCollapseWithMarginBefore()
- ? margin_info.Margin()
- : LayoutUnit();
- SetLogicalHeight(LogicalHeight() + separate_margin +
- MarginBeforeForChild(child));
- logical_top = LogicalHeight();
- } else if (!margin_info.DiscardMargin() &&
- (!margin_info.AtBeforeSideOfBlock() ||
- (!margin_info.CanCollapseMarginBeforeWithChildren() &&
- (!GetDocument().InQuirksMode() ||
- !margin_info.QuirkContainer() ||
- !margin_info.HasMarginBeforeQuirk())))) {
- // We're collapsing with a previous sibling's margins and not
- // with the top of the block.
+ if (!margin_info.AtBeforeSideOfBlock() ||
+ (!margin_info.CanCollapseMarginBeforeWithChildren() &&
+ (!GetDocument().InQuirksMode() || !margin_info.QuirkContainer() ||
+ !margin_info.HasMarginBeforeQuirk()))) {
+ // We're collapsing with a previous sibling's margins and not with the
+ // top of the block.
SetLogicalHeight(LogicalHeight() +
std::max(margin_info.PositiveMargin(), pos_top) -
std::max(margin_info.NegativeMargin(), neg_top));
logical_top = LogicalHeight();
}
- margin_info.SetDiscardMargin(child_discard_margin_after);
-
- if (!margin_info.DiscardMargin()) {
- margin_info.SetPositiveMargin(child_margins.PositiveMarginAfter());
- margin_info.SetNegativeMargin(child_margins.NegativeMarginAfter());
- } else {
- margin_info.ClearMargin();
- }
+ margin_info.SetPositiveMargin(child_margins.PositiveMarginAfter());
+ margin_info.SetNegativeMargin(child_margins.NegativeMarginAfter());
if (margin_info.Margin())
margin_info.SetHasMarginAfterQuirk(HasMarginAfterQuirk(&child));
@@ -2016,8 +1974,7 @@ LayoutUnit LayoutBlockFlow::ClearFloatsIfNeeded(LayoutBox& child,
LayoutUnit old_top_pos_margin,
LayoutUnit old_top_neg_margin,
LayoutUnit y_pos,
- bool child_is_self_collapsing,
- bool child_discard_margin) {
+ bool child_is_self_collapsing) {
LayoutUnit height_increase = GetClearDelta(&child, y_pos);
margin_info.SetLastChildIsSelfCollapsingBlockWithClearance(false);
@@ -2026,24 +1983,17 @@ LayoutUnit LayoutBlockFlow::ClearFloatsIfNeeded(LayoutBox& child,
if (child_is_self_collapsing) {
margin_info.SetLastChildIsSelfCollapsingBlockWithClearance(true);
- margin_info.SetDiscardMargin(child_discard_margin);
// For self-collapsing blocks that clear, they can still collapse their
// margins with following siblings. Reset the current margins to represent
// the self-collapsing block's margins only.
- // If DISCARD is specified for -webkit-margin-collapse, reset the margin
- // values.
LayoutBlockFlow::MarginValues child_margins = MarginValuesForChild(child);
- if (!child_discard_margin) {
- margin_info.SetPositiveMargin(
- std::max(child_margins.PositiveMarginBefore(),
- child_margins.PositiveMarginAfter()));
- margin_info.SetNegativeMargin(
- std::max(child_margins.NegativeMarginBefore(),
- child_margins.NegativeMarginAfter()));
- } else {
- margin_info.ClearMargin();
- }
+ margin_info.SetPositiveMargin(
+ std::max(child_margins.PositiveMarginBefore(),
+ child_margins.PositiveMarginAfter()));
+ margin_info.SetNegativeMargin(
+ std::max(child_margins.NegativeMarginBefore(),
+ child_margins.NegativeMarginAfter()));
// CSS2.1 states:
// "If the top and bottom margins of an element with clearance are
@@ -2080,11 +2030,6 @@ LayoutUnit LayoutBlockFlow::ClearFloatsIfNeeded(LayoutBox& child,
// occurred. The empty blocks collapse into the cleared block.
SetMaxMarginBeforeValues(old_top_pos_margin, old_top_neg_margin);
margin_info.SetAtBeforeSideOfBlock(false);
-
- // In case the child discarded the before margin of the block we need to
- // reset the mustDiscardMarginBefore flag to the initial value.
- SetMustDiscardMarginBefore(StyleRef().MarginBeforeCollapse() ==
- EMarginCollapse::kDiscard);
}
return y_pos + height_increase;
@@ -2093,14 +2038,6 @@ LayoutUnit LayoutBlockFlow::ClearFloatsIfNeeded(LayoutBox& child,
void LayoutBlockFlow::SetCollapsedBottomMargin(const MarginInfo& margin_info) {
if (margin_info.CanCollapseWithMarginAfter() &&
!margin_info.CanCollapseWithMarginBefore()) {
- // Update the after side margin of the container to discard if the after
- // margin of the last child also discards and we collapse with it.
- // Don't update the max margin values because we won't need them anyway.
- if (margin_info.DiscardMargin()) {
- SetMustDiscardMarginAfter();
- return;
- }
-
// Update our max pos/neg bottom margins, since we collapsed our bottom
// margins with our children.
SetMaxMarginAfterValues(
@@ -2123,28 +2060,14 @@ DISABLE_CFI_PERF
void LayoutBlockFlow::MarginBeforeEstimateForChild(
LayoutBox& child,
LayoutUnit& positive_margin_before,
- LayoutUnit& negative_margin_before,
- bool& discard_margin_before) const {
+ LayoutUnit& negative_margin_before) const {
// Give up if in quirks mode and we're a body/table cell and the top margin of
// the child box is quirky.
- // Give up if the child specified -webkit-margin-collapse: separate that
- // prevents collapsing.
// FIXME: Use writing mode independent accessor for marginBeforeCollapse.
- if ((GetDocument().InQuirksMode() && HasMarginBeforeQuirk(&child) &&
- (IsTableCell() || IsBody())) ||
- child.StyleRef().MarginBeforeCollapse() == EMarginCollapse::kSeparate)
+ if (GetDocument().InQuirksMode() && HasMarginBeforeQuirk(&child) &&
+ (IsTableCell() || IsBody()))
return;
- // The margins are discarded by a child that specified
- // -webkit-margin-collapse: discard.
- // FIXME: Use writing mode independent accessor for marginBeforeCollapse.
- if (child.StyleRef().MarginBeforeCollapse() == EMarginCollapse::kDiscard) {
- positive_margin_before = LayoutUnit();
- negative_margin_before = LayoutUnit();
- discard_margin_before = true;
- return;
- }
-
LayoutUnit before_child_margin = MarginBeforeForChild(child);
positive_margin_before =
std::max(positive_margin_before, before_child_margin);
@@ -2200,8 +2123,7 @@ void LayoutBlockFlow::MarginBeforeEstimateForChild(
// Collapse the margin of the grandchild box with our own to produce an
// estimate.
child_block_flow->MarginBeforeEstimateForChild(
- *grandchild_box, positive_margin_before, negative_margin_before,
- discard_margin_before);
+ *grandchild_box, positive_margin_before, negative_margin_before);
}
LayoutUnit LayoutBlockFlow::EstimateLogicalTopPosition(
@@ -2215,13 +2137,11 @@ LayoutUnit LayoutBlockFlow::EstimateLogicalTopPosition(
LayoutUnit logical_top_estimate = LogicalHeight();
LayoutUnit positive_margin_before;
LayoutUnit negative_margin_before;
- bool discard_margin_before = false;
if (!margin_info.CanCollapseWithMarginBefore()) {
if (child.SelfNeedsLayout()) {
// Try to do a basic estimation of how the collapse is going to go.
MarginBeforeEstimateForChild(child, positive_margin_before,
- negative_margin_before,
- discard_margin_before);
+ negative_margin_before);
} else {
// Use the cached collapsed margin values from a previous layout. Most of
// the time they will be right.
@@ -2230,14 +2150,12 @@ LayoutUnit LayoutBlockFlow::EstimateLogicalTopPosition(
margin_values.PositiveMarginBefore());
negative_margin_before = std::max(negative_margin_before,
margin_values.NegativeMarginBefore());
- discard_margin_before = MustDiscardMarginBeforeForChild(child);
}
// Collapse the result with our current margins.
- if (!discard_margin_before)
- logical_top_estimate +=
- std::max(margin_info.PositiveMargin(), positive_margin_before) -
- std::max(margin_info.NegativeMargin(), negative_margin_before);
+ logical_top_estimate +=
+ std::max(margin_info.PositiveMargin(), positive_margin_before) -
+ std::max(margin_info.NegativeMargin(), negative_margin_before);
}
LayoutState* layout_state = View()->GetLayoutState();
@@ -2265,9 +2183,7 @@ LayoutUnit LayoutBlockFlow::EstimateLogicalTopPosition(
// Disregard previous margins, since they will collapse with the
// fragmentainer boundary, due to the forced break. Only apply margins
// that have been specified on the child or its descendants.
- if (!discard_margin_before)
- logical_top_estimate +=
- positive_margin_before - negative_margin_before;
+ logical_top_estimate += positive_margin_before - negative_margin_before;
// Clearance may already have taken us past the beginning of the next
// fragmentainer.
@@ -2325,11 +2241,10 @@ void LayoutBlockFlow::HandleAfterSideOfBlock(LayoutBox* last_child,
// If we can't collapse with children then go ahead and add in the bottom
// margin.
- if (!margin_info.DiscardMargin() &&
- (!margin_info.CanCollapseWithMarginAfter() &&
- !margin_info.CanCollapseWithMarginBefore() &&
- (!GetDocument().InQuirksMode() || !margin_info.QuirkContainer() ||
- !margin_info.HasMarginAfterQuirk())))
+ if (!margin_info.CanCollapseWithMarginAfter() &&
+ !margin_info.CanCollapseWithMarginBefore() &&
+ (!GetDocument().InQuirksMode() || !margin_info.QuirkContainer() ||
+ !margin_info.HasMarginAfterQuirk()))
SetLogicalHeight(LogicalHeight() + margin_info.Margin());
// Now add in our bottom border/padding.
@@ -2352,97 +2267,12 @@ void LayoutBlockFlow::HandleAfterSideOfBlock(LayoutBox* last_child,
JoinFragmentainerBreakValues(BreakAfter(), last_child->BreakAfter()));
}
-void LayoutBlockFlow::SetMustDiscardMarginBefore(bool value) {
- if (StyleRef().MarginBeforeCollapse() == EMarginCollapse::kDiscard) {
- DCHECK(value);
- return;
- }
-
- if (!rare_data_ && !value)
- return;
-
- if (!rare_data_)
- rare_data_ = std::make_unique<LayoutBlockFlowRareData>(this);
-
- rare_data_->discard_margin_before_ = value;
-}
-
-void LayoutBlockFlow::SetMustDiscardMarginAfter(bool value) {
- if (StyleRef().MarginAfterCollapse() == EMarginCollapse::kDiscard) {
- DCHECK(value);
- return;
- }
-
- if (!rare_data_ && !value)
- return;
-
- if (!rare_data_)
- rare_data_ = std::make_unique<LayoutBlockFlowRareData>(this);
-
- rare_data_->discard_margin_after_ = value;
-}
-
-bool LayoutBlockFlow::MustDiscardMarginBefore() const {
- return StyleRef().MarginBeforeCollapse() == EMarginCollapse::kDiscard ||
- (rare_data_ && rare_data_->discard_margin_before_);
-}
-
-bool LayoutBlockFlow::MustDiscardMarginAfter() const {
- return StyleRef().MarginAfterCollapse() == EMarginCollapse::kDiscard ||
- (rare_data_ && rare_data_->discard_margin_after_);
-}
-
-bool LayoutBlockFlow::MustDiscardMarginBeforeForChild(
- const LayoutBox& child) const {
- DCHECK(!child.SelfNeedsLayout() ||
- child.LayoutBlockedByDisplayLock(DisplayLockLifecycleTarget::kSelf));
- if (!child.IsWritingModeRoot()) {
- auto* child_layout_block = DynamicTo<LayoutBlockFlow>(&child);
- return child_layout_block ? child_layout_block->MustDiscardMarginBefore()
- : (child.StyleRef().MarginBeforeCollapse() ==
- EMarginCollapse::kDiscard);
- }
- if (child.IsHorizontalWritingMode() == IsHorizontalWritingMode()) {
- auto* child_layout_block = DynamicTo<LayoutBlockFlow>(&child);
- return child_layout_block ? child_layout_block->MustDiscardMarginAfter()
- : (child.StyleRef().MarginAfterCollapse() ==
- EMarginCollapse::kDiscard);
- }
-
- // FIXME: We return false here because the implementation is not geometrically
- // complete. We have values only for before/after, not start/end.
- // In case the boxes are perpendicular we assume the property is not
- // specified.
- return false;
-}
-
-bool LayoutBlockFlow::MustDiscardMarginAfterForChild(
- const LayoutBox& child) const {
- DCHECK(!child.SelfNeedsLayout() ||
- child.LayoutBlockedByDisplayLock(DisplayLockLifecycleTarget::kSelf));
- if (!child.IsWritingModeRoot()) {
- auto* child_layout_block = DynamicTo<LayoutBlockFlow>(&child);
- return child_layout_block ? child_layout_block->MustDiscardMarginAfter()
- : (child.StyleRef().MarginAfterCollapse() ==
- EMarginCollapse::kDiscard);
- }
- if (child.IsHorizontalWritingMode() == IsHorizontalWritingMode()) {
- auto* child_layout_block = DynamicTo<LayoutBlockFlow>(&child);
- return child_layout_block ? child_layout_block->MustDiscardMarginBefore()
- : (child.StyleRef().MarginBeforeCollapse() ==
- EMarginCollapse::kDiscard);
- }
-
- // FIXME: See |mustDiscardMarginBeforeForChild| above.
- return false;
-}
-
void LayoutBlockFlow::SetMaxMarginBeforeValues(LayoutUnit pos, LayoutUnit neg) {
if (!rare_data_) {
if (pos == LayoutBlockFlowRareData::PositiveMarginBeforeDefault(this) &&
neg == LayoutBlockFlowRareData::NegativeMarginBeforeDefault(this))
return;
- rare_data_ = std::make_unique<LayoutBlockFlowRareData>(this);
+ rare_data_ = MakeGarbageCollected<LayoutBlockFlowRareData>(this);
}
rare_data_->margins_.SetPositiveMarginBefore(pos);
rare_data_->margins_.SetNegativeMarginBefore(neg);
@@ -2453,40 +2283,12 @@ void LayoutBlockFlow::SetMaxMarginAfterValues(LayoutUnit pos, LayoutUnit neg) {
if (pos == LayoutBlockFlowRareData::PositiveMarginAfterDefault(this) &&
neg == LayoutBlockFlowRareData::NegativeMarginAfterDefault(this))
return;
- rare_data_ = std::make_unique<LayoutBlockFlowRareData>(this);
+ rare_data_ = MakeGarbageCollected<LayoutBlockFlowRareData>(this);
}
rare_data_->margins_.SetPositiveMarginAfter(pos);
rare_data_->margins_.SetNegativeMarginAfter(neg);
}
-bool LayoutBlockFlow::MustSeparateMarginBeforeForChild(
- const LayoutBox& child) const {
- DCHECK(!child.SelfNeedsLayout() ||
- child.LayoutBlockedByDisplayLock(DisplayLockLifecycleTarget::kSelf));
- const ComputedStyle& child_style = child.StyleRef();
- if (!child.IsWritingModeRoot())
- return child_style.MarginBeforeCollapse() == EMarginCollapse::kSeparate;
- if (child.IsHorizontalWritingMode() == IsHorizontalWritingMode())
- return child_style.MarginAfterCollapse() == EMarginCollapse::kSeparate;
-
- // FIXME: See |mustDiscardMarginBeforeForChild| above.
- return false;
-}
-
-bool LayoutBlockFlow::MustSeparateMarginAfterForChild(
- const LayoutBox& child) const {
- DCHECK(!child.SelfNeedsLayout() ||
- child.LayoutBlockedByDisplayLock(DisplayLockLifecycleTarget::kSelf));
- const ComputedStyle& child_style = child.StyleRef();
- if (!child.IsWritingModeRoot())
- return child_style.MarginAfterCollapse() == EMarginCollapse::kSeparate;
- if (child.IsHorizontalWritingMode() == IsHorizontalWritingMode())
- return child_style.MarginBeforeCollapse() == EMarginCollapse::kSeparate;
-
- // FIXME: See |mustDiscardMarginBeforeForChild| above.
- return false;
-}
-
LayoutUnit LayoutBlockFlow::ApplyForcedBreak(LayoutUnit logical_offset,
EBreakBetween break_value) {
if (!IsForcedFragmentainerBreakValue(break_value))
@@ -2559,6 +2361,27 @@ void LayoutBlockFlow::AddVisualOverflowFromFloats() {
}
}
+void LayoutBlockFlow::AddVisualOverflowFromFloats(
+ const NGPhysicalContainerFragment& fragment) {
+ DCHECK(fragment.HasFloatingDescendantsForPaint());
+ for (const NGLink& child : fragment.Children()) {
+ if (child->HasSelfPaintingLayer())
+ continue;
+
+ if (child->IsFloating()) {
+ AddVisualOverflowFromChild(ToLayoutBox(*child->GetLayoutObject()));
+ continue;
+ }
+
+ if (const NGPhysicalContainerFragment* child_container =
+ DynamicTo<NGPhysicalContainerFragment>(child.get())) {
+ if (child_container->HasFloatingDescendantsForPaint() &&
+ !child_container->IsFormattingContextRoot())
+ AddVisualOverflowFromFloats(*child_container);
+ }
+ }
+}
+
void LayoutBlockFlow::AddLayoutOverflowFromFloats() {
if (!floating_objects_)
return;
@@ -2597,6 +2420,7 @@ void LayoutBlockFlow::ComputeVisualOverflow(
HasSelfPaintingLayer()))
AddVisualOverflowFromFloats();
if (VisualOverflowRect() != previous_visual_overflow_rect) {
+ InvalidateIntersectionObserverCachedRects();
SetShouldCheckForPaintInvalidation();
GetFrameView()->SetIntersectionObservationState(LocalFrameView::kDesired);
}
@@ -2712,15 +2536,13 @@ LayoutUnit LayoutBlockFlow::FirstLineBoxBaseline() const {
NGBoxFragment box_fragment(
StyleRef().GetWritingMode(), StyleRef().Direction(),
To<NGPhysicalBoxFragment>(paint_fragment->PhysicalFragment()));
- NGLineHeightMetrics metrics =
- box_fragment.BaselineMetricsWithoutSynthesize(
- {NGBaselineAlgorithmType::kFirstLine,
- StyleRef().GetFontBaseline()});
- if (!metrics.IsEmpty())
- return metrics.ascent;
+ base::Optional<LayoutUnit> baseline = box_fragment.Baseline();
+ if (baseline)
+ return *baseline;
}
}
- return LayoutUnit(-1);
+ return EmptyLineBaseline(IsHorizontalWritingMode() ? kHorizontalLine
+ : kVerticalLine);
}
LayoutUnit LayoutBlockFlow::InlineBlockBaseline(
@@ -2750,23 +2572,7 @@ LayoutUnit LayoutBlockFlow::InlineBlockBaseline(
return LastLineBox()->LogicalTop() +
font_data->GetFontMetrics().Ascent(LastRootBox()->BaselineType());
}
- if (!HasLineIfEmpty())
- return LayoutUnit(-1);
-
- const SimpleFontData* font_data = FirstLineStyle()->GetFont().PrimaryFont();
- DCHECK(font_data);
- if (!font_data)
- return LayoutUnit(-1);
-
- const FontMetrics& font_metrics = font_data->GetFontMetrics();
- return LayoutUnit(
- (font_metrics.Ascent() +
- (LineHeight(true, line_direction, kPositionOfInteriorLineBoxes) -
- font_metrics.Height()) /
- 2 +
- (line_direction == kHorizontalLine ? BorderTop() + PaddingTop()
- : BorderRight() + PaddingRight()))
- .ToInt());
+ return EmptyLineBaseline(line_direction);
}
void LayoutBlockFlow::RemoveFloatingObjectsFromDescendants() {
@@ -2939,9 +2745,6 @@ void LayoutBlockFlow::CreateFloatingObjects() {
}
void LayoutBlockFlow::WillBeDestroyed() {
- // Mark as being destroyed to avoid trouble with merges in removeChild().
- being_destroyed_ = true;
-
// Make sure to destroy anonymous children first while they are still
// connected to the rest of the tree, so that they will properly dirty line
// boxes that they are removed from. Effects that do :before/:after only on
@@ -3030,7 +2833,7 @@ void LayoutBlockFlow::StyleDidChange(StyleDifference diff,
const FloatingObjectSet& floating_object_set = floating_objects_->Set();
FloatingObjectSetIterator end = floating_object_set.end();
- for (LayoutObject* curr = Parent(); curr && !curr->IsLayoutView();
+ for (LayoutObject* curr = Parent(); !IsA<LayoutView>(curr);
curr = curr->Parent()) {
auto* curr_block = DynamicTo<LayoutBlockFlow>(curr);
if (curr_block) {
@@ -3149,9 +2952,9 @@ void LayoutBlockFlow::AddChild(LayoutObject* new_child,
return;
}
- // LayoutNGListMarker is out-of-flow for the tree building purpose, and that
- // is not inline level, but IsInline().
- if (new_child->IsInline() && !new_child->IsLayoutNGListMarker()) {
+ // LayoutNGOutsideListMarker is out-of-flow for the tree building purpose,
+ // and that is not inline level, but IsInline().
+ if (new_child->IsInline() && !new_child->IsLayoutNGOutsideListMarker()) {
// No suitable existing anonymous box - create a new one.
auto* new_block = To<LayoutBlockFlow>(CreateAnonymousBlock());
LayoutBox::AddChild(new_block, before_child);
@@ -3364,7 +3167,7 @@ void LayoutBlockFlow::CollapseAnonymousBlockChild(LayoutBlockFlow* child) {
// design, so we don't remove them.
if (child->IsRubyRun() || child->IsRubyBase())
return;
- SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kChildAnonymousBlockChanged);
child->MoveAllChildrenTo(this, child->NextSibling(), child->HasLayer());
@@ -3390,7 +3193,7 @@ bool LayoutBlockFlow::MergeSiblingContiguousAnonymousBlock(
!IsMergeableAnonymousBlock(sibling_that_may_be_deleted))
return false;
- SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kAnonymousBlockChange);
// If the inlineness of children of the two block don't match, we'd need
@@ -3510,9 +3313,9 @@ static void GetInlineRun(LayoutObject* start,
// Start by skipping as many non-inlines as we can.
LayoutObject* curr = start;
- // LayoutNGListMarker is out-of-flow for the tree building purpose. Skip here
- // because it's the first child.
- if (curr && curr->IsLayoutNGListMarker())
+ // LayoutNGOutsideListMarker is out-of-flow for the tree building purpose.
+ // Skip here because it's the first child.
+ if (curr && curr->IsLayoutNGOutsideListMarker())
curr = curr->NextSibling();
bool saw_inline;
@@ -3577,7 +3380,7 @@ void LayoutBlockFlow::MakeChildrenNonInline(LayoutObject* insertion_point) {
#if DCHECK_IS_ON()
for (LayoutObject* c = FirstChild(); c; c = c->NextSibling())
- DCHECK(!c->IsInline() || c->IsLayoutNGListMarker());
+ DCHECK(!c->IsInline() || c->IsLayoutNGOutsideListMarker());
#endif
SetShouldDoFullPaintInvalidation();
@@ -4422,7 +4225,7 @@ void LayoutBlockFlow::SetPaginationStrutPropagatedFromChild(LayoutUnit strut) {
if (!rare_data_) {
if (!strut)
return;
- rare_data_ = std::make_unique<LayoutBlockFlowRareData>(this);
+ rare_data_ = MakeGarbageCollected<LayoutBlockFlowRareData>(this);
}
rare_data_->pagination_strut_propagated_from_child_ = strut;
}
@@ -4431,7 +4234,7 @@ void LayoutBlockFlow::SetFirstForcedBreakOffset(LayoutUnit block_offset) {
if (!rare_data_) {
if (!block_offset)
return;
- rare_data_ = std::make_unique<LayoutBlockFlowRareData>(this);
+ rare_data_ = MakeGarbageCollected<LayoutBlockFlowRareData>(this);
}
rare_data_->first_forced_break_offset_ = block_offset;
}
@@ -4450,7 +4253,7 @@ bool LayoutBlockFlow::CreatesNewFormattingContext() const {
if (IsInline() || IsFloatingOrOutOfFlowPositioned() || HasOverflowClip() ||
IsFlexItemIncludingDeprecatedAndNG() || IsCustomItem() ||
IsDocumentElement() || IsGridItem() || IsWritingModeRoot() ||
- StyleRef().Display() == EDisplay::kFlowRoot ||
+ IsMathItem() || StyleRef().Display() == EDisplay::kFlowRoot ||
ShouldApplyPaintContainment() || ShouldApplyLayoutContainment() ||
StyleRef().SpecifiesColumns() ||
StyleRef().GetColumnSpan() == EColumnSpan::kAll) {
@@ -4518,7 +4321,7 @@ void LayoutBlockFlow::CreateOrDestroyMultiColumnFlowThreadIfNeeded(
// Form controls are replaced content, and are therefore not supposed to
// support multicol.
- if (IsFileUploadControl() || IsTextControl() || IsListBox())
+ if (IsFileUploadControl() || IsTextControl() || IsListBox(this))
return;
// We don't allow custom layout and multicol on the same object. This is
@@ -4546,7 +4349,7 @@ LayoutBlockFlow::LayoutBlockFlowRareData& LayoutBlockFlow::EnsureRareData() {
if (rare_data_)
return *rare_data_;
- rare_data_ = std::make_unique<LayoutBlockFlowRareData>(this);
+ rare_data_ = MakeGarbageCollected<LayoutBlockFlowRareData>(this);
return *rare_data_;
}
@@ -4631,10 +4434,9 @@ void LayoutBlockFlow::RecalcInlineChildrenVisualOverflow() {
if (const NGFragmentItems* items = fragment->Items()) {
NGInlineCursor cursor(*items);
NGFragmentItem::RecalcInkOverflowForCursor(&cursor);
- }
-
- if (fragment->HasFloatingDescendantsForPaint())
+ } else if (fragment->HasFloatingDescendantsForPaint()) {
RecalcFloatingDescendantsVisualOverflow(*fragment);
+ }
return;
}
}
@@ -4946,9 +4748,7 @@ LayoutBlockFlow::LayoutBlockFlowRareData::LayoutBlockFlowRareData(
break_before_(static_cast<unsigned>(EBreakBetween::kAuto)),
break_after_(static_cast<unsigned>(EBreakBetween::kAuto)),
line_break_to_avoid_widow_(-1),
- did_break_at_line_to_avoid_widow_(false),
- discard_margin_before_(false),
- discard_margin_after_(false) {}
+ did_break_at_line_to_avoid_widow_(false) {}
LayoutBlockFlow::LayoutBlockFlowRareData::~LayoutBlockFlowRareData() = default;
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 bbe43e33163..e7f1a334a53 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
@@ -105,7 +105,6 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock {
static LayoutBlockFlow* CreateAnonymous(Document*,
scoped_refptr<ComputedStyle>,
LegacyLayout);
- bool BeingDestroyed() const { return being_destroyed_; }
bool IsLayoutBlockFlow() const final { return true; }
@@ -454,6 +453,7 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock {
// These functions are only public so we can call it from NGBlockNode while
// we're still working on LayoutNG.
void AddVisualOverflowFromFloats();
+ void AddVisualOverflowFromFloats(const NGPhysicalContainerFragment& fragment);
void AddLayoutOverflowFromFloats();
virtual NGInlineNodeData* TakeNGInlineNodeData() { return nullptr; }
@@ -464,9 +464,6 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock {
virtual void WillCollectInlines() {}
virtual void SetPaintFragment(const NGBlockBreakToken*,
scoped_refptr<const NGPhysicalFragment>);
- virtual const NGPhysicalBoxFragment* CurrentFragment() const {
- return nullptr;
- }
const NGFragmentItems* FragmentItems() const;
#if DCHECK_IS_ON()
@@ -530,7 +527,6 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock {
const PhysicalOffset& additional_offset,
NGOutlineType) const override;
- bool PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const override;
void InvalidateDisplayItemClients(PaintInvalidationReason) const override;
Node* NodeForHitTest() const final;
@@ -736,9 +732,8 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock {
MarginValues MarginValuesForChild(LayoutBox& child) const;
// Allocated only when some of these fields have non-default values
- struct LayoutBlockFlowRareData {
- USING_FAST_MALLOC(LayoutBlockFlowRareData);
-
+ struct LayoutBlockFlowRareData final
+ : public GarbageCollected<LayoutBlockFlowRareData> {
public:
explicit LayoutBlockFlowRareData(const LayoutBlockFlow* block);
~LayoutBlockFlowRareData();
@@ -758,6 +753,8 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock {
return (-block->MarginAfter()).ClampNegativeToZero();
}
+ void Trace(Visitor*) {}
+
MarginValues margins_;
LayoutUnit pagination_strut_propagated_from_child_;
@@ -775,8 +772,6 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock {
unsigned break_after_ : 4;
int line_break_to_avoid_widow_;
bool did_break_at_line_to_avoid_widow_ : 1;
- bool discard_margin_before_ : 1;
- bool discard_margin_after_ : 1;
DISALLOW_COPY_AND_ASSIGN(LayoutBlockFlowRareData);
};
@@ -823,18 +818,6 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock {
void SetMaxMarginBeforeValues(LayoutUnit pos, LayoutUnit neg);
void SetMaxMarginAfterValues(LayoutUnit pos, LayoutUnit neg);
- void SetMustDiscardMarginBefore(bool = true);
- void SetMustDiscardMarginAfter(bool = true);
-
- bool MustDiscardMarginBefore() const;
- bool MustDiscardMarginAfter() const;
-
- bool MustDiscardMarginBeforeForChild(const LayoutBox&) const;
- bool MustDiscardMarginAfterForChild(const LayoutBox&) const;
-
- bool MustSeparateMarginBeforeForChild(const LayoutBox&) const;
- bool MustSeparateMarginAfterForChild(const LayoutBox&) const;
-
void InitMaxMarginValues() {
if (rare_data_) {
rare_data_->margins_ = MarginValues(
@@ -842,9 +825,6 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock {
LayoutBlockFlowRareData::NegativeMarginBeforeDefault(this),
LayoutBlockFlowRareData::PositiveMarginAfterDefault(this),
LayoutBlockFlowRareData::NegativeMarginAfterDefault(this));
-
- rare_data_->discard_margin_before_ = false;
- rare_data_->discard_margin_after_ = false;
}
}
@@ -866,24 +846,18 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock {
LayoutUnit CollapseMargins(LayoutBox& child,
BlockChildrenLayoutInfo&,
- bool child_is_self_collapsing,
- bool child_discard_margin_before,
- bool child_discard_margin_after);
+ bool child_is_self_collapsing);
LayoutUnit ClearFloatsIfNeeded(LayoutBox& child,
MarginInfo&,
LayoutUnit old_top_pos_margin,
LayoutUnit old_top_neg_margin,
LayoutUnit y_pos,
- bool child_is_self_collapsing,
- bool child_discard_margin);
+ bool child_is_self_collapsing);
LayoutUnit EstimateLogicalTopPosition(
LayoutBox& child,
const BlockChildrenLayoutInfo&,
LayoutUnit& estimate_without_pagination);
- void MarginBeforeEstimateForChild(LayoutBox&,
- LayoutUnit&,
- LayoutUnit&,
- bool&) const;
+ void MarginBeforeEstimateForChild(LayoutBox&, LayoutUnit&, LayoutUnit&) const;
void HandleAfterSideOfBlock(LayoutBox* last_child,
LayoutUnit top,
LayoutUnit bottom,
@@ -937,7 +911,7 @@ class CORE_EXPORT LayoutBlockFlow : public LayoutBlock {
bool CheckIfIsSelfCollapsingBlock() const;
protected:
- std::unique_ptr<LayoutBlockFlowRareData> rare_data_;
+ Persistent<LayoutBlockFlowRareData> rare_data_;
std::unique_ptr<FloatingObjects> floating_objects_;
friend class MarginInfo;
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 ca02eebdb92..96f21e1d24c 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
@@ -38,6 +38,7 @@
#include "third_party/blink/renderer/core/layout/line/word_measurement.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/ng_physical_box_fragment.h"
#include "third_party/blink/renderer/core/layout/svg/line/svg_root_inline_box.h"
#include "third_party/blink/renderer/core/layout/vertical_position_cache.h"
#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
@@ -956,7 +957,7 @@ RootInlineBox* LayoutBlockFlow::CreateLineBoxesFromBidiRuns(
// text selection in RTL boxes would not work as expected.
if (is_svg_root_inline_box) {
DCHECK(IsSVGText());
- ToSVGRootInlineBox(line_box)->ComputePerCharacterLayoutInformation();
+ To<SVGRootInlineBox>(line_box)->ComputePerCharacterLayoutInformation();
}
// Compute our overflow now.
@@ -1179,7 +1180,13 @@ void LayoutBlockFlow::LayoutRunsAndFloatsInRange(
resolver, bidi_runs, end_of_line, override,
layout_state.GetLineInfo().PreviousLineBrokeCleanly(),
is_new_uba_paragraph);
- DCHECK(resolver.GetPosition() == end_of_line);
+ // |resolver| to be at |end_of_line| is critical, because
+ // |SetLineBreakInfo| below copies |end_of_line.current_| to
+ // |RootInlineBox::line_break_obj_|. When the object is destroyed,
+ // |RootInlineBox::ChildRemoved()| clears |line_break_obj_| to avoid
+ // use-after-free, but we cannot find the correct |RootInlineBox| if
+ // |end_of_line| is actually not in this |RootInlineBox|.
+ CHECK(resolver.GetPosition() == end_of_line);
BidiRun* trailing_space_run = resolver.TrailingSpaceRun();
@@ -1690,7 +1697,7 @@ void LayoutBlockFlow::ComputeInlinePreferredLogicalWidths(
// did change or is going to change size. However, this is our only
// opportunity to make sure that it gets its min/max widths
// calculated.
- child->SetPreferredLogicalWidthsDirty();
+ child->SetIntrinsicLogicalWidthsDirty();
}
// Case (1) and (2). Inline replaced and inline flow elements.
@@ -1699,13 +1706,14 @@ void LayoutBlockFlow::ComputeInlinePreferredLogicalWidths(
child_min, child_max);
inline_min += child_min;
inline_max += child_max;
- child->ClearPreferredLogicalWidthsDirty();
+ child->ClearIntrinsicLogicalWidthsDirty();
} else {
AdjustMarginForInlineReplaced(child, child_min, child_max);
}
}
- if (!child->IsLayoutInline() && !child->IsText()) {
+ if (!child->IsLayoutInline() && !child->IsText() &&
+ !child->IsOutsideListMarker()) {
// Case (2). Inline replaced elements and floats.
// Go ahead and terminate the current line as far as
// minwidth is concerned.
@@ -1893,7 +1901,7 @@ void LayoutBlockFlow::ComputeInlinePreferredLogicalWidths(
}
// Ignore spaces after a list marker.
- if (child->IsListMarkerIncludingNG())
+ if (child->IsListMarkerIncludingNGOutside())
strip_front_spaces = true;
} else {
min_logical_width = std::max(min_logical_width, inline_min);
@@ -2394,17 +2402,21 @@ void LayoutBlockFlow::AddVisualOverflowFromInlineChildren() {
AddContentsVisualOverflow(child_rect);
}
}
- } else if (const NGFragmentItems* items = FragmentItems()) {
- for (NGInlineCursor cursor(*items); cursor; cursor.MoveToNextSibling()) {
- const NGFragmentItem* child = cursor.CurrentItem();
- DCHECK(child);
- if (child->HasSelfPaintingLayer())
- continue;
- PhysicalRect child_rect = child->InkOverflow();
- if (!child_rect.IsEmpty()) {
- child_rect.offset += child->Offset();
- AddContentsVisualOverflow(child_rect);
+ } else if (const NGPhysicalBoxFragment* fragment = CurrentFragment()) {
+ if (const NGFragmentItems* items = fragment->Items()) {
+ for (NGInlineCursor cursor(*items); cursor; cursor.MoveToNextSibling()) {
+ const NGFragmentItem* child = cursor.CurrentItem();
+ DCHECK(child);
+ if (child->HasSelfPaintingLayer())
+ continue;
+ PhysicalRect child_rect = child->InkOverflow();
+ if (!child_rect.IsEmpty()) {
+ child_rect.offset += child->OffsetInContainerBlock();
+ AddContentsVisualOverflow(child_rect);
+ }
}
+ } else if (fragment->HasFloatingDescendantsForPaint()) {
+ AddVisualOverflowFromFloats(*fragment);
}
} else {
for (RootInlineBox* curr = FirstRootBox(); curr;
@@ -2744,18 +2756,36 @@ LayoutUnit LayoutBlockFlow::StartAlignedOffsetForLine(
void LayoutBlockFlow::SetShouldDoFullPaintInvalidationForFirstLine() {
DCHECK(ChildrenInline());
- if (RootInlineBox* first_root_box = FirstRootBox())
- first_root_box->SetShouldDoFullPaintInvalidationForFirstLine();
- else if (const NGPaintFragment* paint_fragment = PaintFragment())
+
+ if (const NGPaintFragment* paint_fragment = PaintFragment()) {
paint_fragment->SetShouldDoFullPaintInvalidationForFirstLine();
-}
+ return;
+ }
-bool LayoutBlockFlow::PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const {
- // LayoutBlockFlow is in charge of paint invalidation of the first line.
- if (FirstLineBox())
- return false;
+ if (const NGFragmentItems* fragment_items = FragmentItems()) {
+ NGInlineCursor first_line(*fragment_items);
+ if (first_line) {
+ DCHECK(!FirstRootBox());
+ first_line.MoveToFirstLine();
+ if (first_line && first_line.Current().UsesFirstLineStyle()) {
+ // 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();
+ DCHECK(layout_object);
+ layout_object->StyleRef().ClearCachedPseudoElementStyles();
+ layout_object->SetShouldDoFullPaintInvalidation();
+ }
+ StyleRef().ClearCachedPseudoElementStyles();
+ SetShouldDoFullPaintInvalidation();
+ }
+ }
+ return;
+ }
- return LayoutBlock::PaintedOutputOfObjectHasNoEffectRegardlessOfSize();
+ if (RootInlineBox* first_root_box = FirstRootBox())
+ first_root_box->SetShouldDoFullPaintInvalidationForFirstLine();
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_block_test.cc b/chromium/third_party/blink/renderer/core/layout/layout_block_test.cc
index 98e24416cfd..a08a3b30dc6 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_block_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_block_test.cc
@@ -54,7 +54,8 @@ TEST_F(LayoutBlockTest, WidthAvailableToChildrenChanged) {
150 - list_box->VerticalScrollbarWidth());
DummyExceptionStateForTesting exception_state;
- list_element->style()->setCSSText(&GetDocument(), "width:150px;height:100px;",
+ list_element->style()->setCSSText(GetDocument().GetExecutionContext(),
+ "width:150px;height:100px;",
exception_state);
ASSERT_FALSE(exception_state.HadException());
UpdateAllLifecyclePhasesForTest();
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 e9e3cfdf053..d10c1623fc7 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_box.cc
@@ -30,9 +30,11 @@
#include <algorithm>
#include "cc/input/scroll_snap_data.h"
+#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink.h"
#include "third_party/blink/public/platform/web_rect.h"
-#include "third_party/blink/public/platform/web_scroll_into_view_params.h"
+#include "third_party/blink/public/strings/grit/blink_strings.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/editing/editing_utilities.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -40,10 +42,15 @@
#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_opt_group_element.h"
+#include "third_party/blink/renderer/core/html/forms/html_select_element.h"
+#include "third_party/blink/renderer/core/html/html_div_element.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/html/html_frame_element_base.h"
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
+#include "third_party/blink/renderer/core/input_type_names.h"
#include "third_party/blink/renderer/core/layout/api/line_layout_block_flow.h"
#include "third_party/blink/renderer/core/layout/api/line_layout_box.h"
#include "third_party/blink/renderer/core/layout/box_layout_extra_input.h"
@@ -52,6 +59,7 @@
#include "third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/core/layout/layout_fieldset.h"
+#include "third_party/blink/renderer/core/layout/layout_file_upload_control.h"
#include "third_party/blink/renderer/core/layout/layout_flexible_box.h"
#include "third_party/blink/renderer/core/layout/layout_grid.h"
#include "third_party/blink/renderer/core/layout/layout_inline.h"
@@ -91,6 +99,7 @@
#include "third_party/blink/renderer/platform/geometry/float_rounded_rect.h"
#include "third_party/blink/renderer/platform/geometry/length_functions.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/text/platform_locale.h"
namespace blink {
@@ -107,13 +116,117 @@ struct SameSizeAsLayoutBox : public LayoutBoxModelObject {
LayoutSize previous_size;
LayoutUnit intrinsic_content_logical_height;
LayoutRectOutsets margin_box_outsets;
- LayoutUnit preferred_logical_width[2];
- void* pointers[5];
+ MinMaxSizes intrinsic_logical_widths;
+ LayoutUnit intrinsic_logical_widths_percentage_resolution_block_size;
+ void* pointers[4];
+ Persistent<void*> rare_data;
+ Vector<scoped_refptr<const NGLayoutResult>, 1> layout_results;
};
static_assert(sizeof(LayoutBox) == sizeof(SameSizeAsLayoutBox),
"LayoutBox should stay small");
+namespace {
+
+LayoutUnit FileUploadControlIntrinsicInlineSize(const HTMLInputElement& input,
+ const LayoutBox& box) {
+ // Figure out how big the filename space needs to be for a given number of
+ // characters (using "0" as the nominal character).
+ constexpr int kDefaultWidthNumChars = 34;
+ constexpr UChar kCharacter = '0';
+ const String character_as_string = String(&kCharacter, 1);
+ const Font& font = box.StyleRef().GetFont();
+ const float min_default_label_width =
+ kDefaultWidthNumChars *
+ font.Width(ConstructTextRun(font, character_as_string, box.StyleRef(),
+ TextRun::kAllowTrailingExpansion));
+
+ const String label =
+ input.GetLocale().QueryString(IDS_FORM_FILE_NO_FILE_LABEL);
+ float default_label_width = font.Width(ConstructTextRun(
+ font, label, box.StyleRef(), TextRun::kAllowTrailingExpansion));
+ if (HTMLInputElement* button = input.UploadButton()) {
+ if (LayoutObject* button_layout_object = button->GetLayoutObject()) {
+ default_label_width +=
+ button_layout_object->PreferredLogicalWidths().max_size +
+ LayoutFileUploadControl::kAfterButtonSpacing;
+ }
+ }
+ return LayoutUnit(
+ ceilf(std::max(min_default_label_width, default_label_width)));
+}
+
+LayoutUnit ListBoxDefaultItemHeight(const LayoutBox& box) {
+ constexpr int kDefaultPaddingBottom = 1;
+
+ const SimpleFontData* font_data = box.StyleRef().GetFont().PrimaryFont();
+ if (!font_data)
+ return LayoutUnit();
+ return LayoutUnit(font_data->GetFontMetrics().Height() +
+ kDefaultPaddingBottom);
+}
+
+// TODO(crbug.com/1040826): This function is written in LayoutObject API
+// so that this works in both of the legacy layout and LayoutNG. We
+// should have LayoutNG-specific code.
+LayoutUnit ListBoxItemHeight(const HTMLSelectElement& select,
+ const LayoutBox& box) {
+ const auto& items = select.GetListItems();
+ if (items.IsEmpty() || box.ShouldApplySizeContainment())
+ return ListBoxDefaultItemHeight(box);
+
+ LayoutUnit max_height;
+ for (Element* element : items) {
+ if (auto* optgroup = DynamicTo<HTMLOptGroupElement>(element))
+ element = &optgroup->OptGroupLabelElement();
+ LayoutUnit item_height;
+ if (auto* layout_box = element->GetLayoutBox())
+ item_height = layout_box->Size().Height();
+ else
+ item_height = ListBoxDefaultItemHeight(box);
+ max_height = std::max(max_height, item_height);
+ }
+ return max_height;
+}
+
+LayoutUnit MenuListIntrinsicInlineSize(const HTMLSelectElement& select,
+ const LayoutBox& box) {
+ const ComputedStyle& style = box.StyleRef();
+ float max_option_width = 0;
+ if (!box.ShouldApplySizeContainment()) {
+ for (auto* const option : select.GetOptionList()) {
+ String text = option->TextIndentedToRespectGroupLabel();
+ const ComputedStyle* item_style =
+ option->GetComputedStyle() ? option->GetComputedStyle() : &style;
+ item_style->ApplyTextTransform(&text);
+ // We apply SELECT's style, not OPTION's style because max_option_width is
+ // used to determine intrinsic width of the menulist box.
+ TextRun text_run = ConstructTextRun(style.GetFont(), text, style);
+ max_option_width =
+ std::max(max_option_width, style.GetFont().Width(text_run));
+ }
+ }
+
+ LayoutTheme& theme = LayoutTheme::GetTheme();
+ int paddings = theme.PopupInternalPaddingStart(style) +
+ theme.PopupInternalPaddingEnd(box.GetFrame(), style);
+ return std::max(static_cast<int>(ceilf(max_option_width)),
+ LayoutTheme::GetTheme().MinimumMenuListSize(style)) +
+ LayoutUnit(paddings);
+}
+
+LayoutUnit MenuListIntrinsicBlockSize(const HTMLSelectElement& select,
+ const LayoutBox& box) {
+ if (!box.StyleRef().HasEffectiveAppearance())
+ return kIndefiniteSize;
+ const SimpleFontData* font_data = box.StyleRef().GetFont().PrimaryFont();
+ DCHECK(font_data);
+ return (font_data ? font_data->GetFontMetrics().Height() : 0) +
+ select.InnerElement().GetLayoutBox()->BorderAndPaddingLogicalHeight();
+}
+
+} // anonymous namespace
+
BoxLayoutExtraInput::BoxLayoutExtraInput(LayoutBox& box) : box(box) {
box.SetBoxLayoutExtraInput(this);
}
@@ -135,11 +248,15 @@ LayoutBoxRareData::LayoutBoxRareData()
snap_container_(nullptr),
snap_areas_(nullptr) {}
+void LayoutBoxRareData::Trace(Visitor* visitor) {
+ visitor->Trace(layout_child_);
+}
+
LayoutBox::LayoutBox(ContainerNode* node)
: LayoutBoxModelObject(node),
intrinsic_content_logical_height_(-1),
- min_preferred_logical_width_(-1),
- max_preferred_logical_width_(-1),
+ intrinsic_logical_widths_percentage_resolution_block_size_(
+ LayoutUnit::Min()),
inline_box_wrapper_(nullptr) {
SetIsBox();
if (blink::IsA<HTMLLegendElement>(node))
@@ -181,6 +298,8 @@ void LayoutBox::WillBeDestroyed() {
if (!DocumentBeingDestroyed()) {
if (NGPaintFragment* first_inline_fragment = FirstInlineFragment())
first_inline_fragment->LayoutObjectWillBeDestroyed();
+ for (auto result : layout_results_)
+ result->PhysicalFragment().LayoutObjectWillBeDestroyed();
}
SetSnapContainer(nullptr);
@@ -242,8 +361,7 @@ void LayoutBox::StyleWillChange(StyleDifference diff,
// The background of the root element or the body element could propagate up
// to the canvas. Just dirty the entire canvas when our style changes
// substantially.
- if ((diff.NeedsFullPaintInvalidation() || diff.NeedsLayout()) &&
- GetNode() &&
+ if ((diff.NeedsPaintInvalidation() || diff.NeedsLayout()) && GetNode() &&
(IsDocumentElement() || IsA<HTMLBodyElement>(*GetNode()))) {
View()->SetShouldDoFullPaintInvalidation();
}
@@ -258,7 +376,7 @@ void LayoutBox::StyleWillChange(StyleDifference diff,
// We're about to go out of flow. Before that takes place, we need to
// mark the current containing block chain for preferred widths
// recalculation.
- SetNeedsLayoutAndPrefWidthsRecalc(
+ SetNeedsLayoutAndIntrinsicWidthsRecalc(
layout_invalidation_reason::kStyleChange);
} else {
MarkContainerChainForLayout();
@@ -468,7 +586,6 @@ void LayoutBox::UpdateScrollSnapMappingAfterStyleChange(
const ComputedStyle& old_style) {
DCHECK(Style());
SnapCoordinator& snap_coordinator = GetDocument().GetSnapCoordinator();
-
// scroll-snap-type and scroll-padding invalidate the snap container.
if (old_style.GetScrollSnapType() != StyleRef().GetScrollSnapType() ||
old_style.ScrollPaddingBottom() != StyleRef().ScrollPaddingBottom() ||
@@ -487,6 +604,10 @@ void LayoutBox::UpdateScrollSnapMappingAfterStyleChange(
old_style.ScrollMarginTop() != StyleRef().ScrollMarginTop() ||
old_style.ScrollMarginRight() != StyleRef().ScrollMarginRight())
snap_coordinator.SnapAreaDidChange(*this, StyleRef().GetScrollSnapAlign());
+
+ // Transform invalidates the snap area.
+ if (old_style.Transform() != StyleRef().Transform())
+ snap_coordinator.SnapAreaDidChange(*this, StyleRef().GetScrollSnapAlign());
}
void LayoutBox::AddScrollSnapMapping() {
@@ -647,9 +768,9 @@ int LayoutBox::PixelSnappedScrollHeight() const {
PhysicalRect LayoutBox::ScrollRectToVisibleRecursive(
const PhysicalRect& absolute_rect,
- const WebScrollIntoViewParams& params) {
- DCHECK(params.GetScrollType() == kProgrammaticScroll ||
- params.GetScrollType() == kUserScroll);
+ mojom::blink::ScrollIntoViewParamsPtr params) {
+ DCHECK(params->type == mojom::blink::ScrollType::kProgrammatic ||
+ params->type == mojom::blink::ScrollType::kUser);
if (!GetFrameView())
return absolute_rect;
@@ -659,12 +780,9 @@ PhysicalRect LayoutBox::ScrollRectToVisibleRecursive(
// if the stop_at_main_frame_layout_viewport option is set. We do this so
// that we can allow a smooth "scroll and zoom" animation to do the final
// scroll in cases like scrolling a focused editable box into view.
- if (params.stop_at_main_frame_layout_viewport && IsGlobalRootScroller())
+ if (params->stop_at_main_frame_layout_viewport && IsGlobalRootScroller())
return absolute_rect;
- // Presumably the same issue as in setScrollTop. See crbug.com/343132.
- DisableCompositingQueryAsserts disabler;
-
PhysicalRect absolute_rect_to_scroll = absolute_rect;
if (absolute_rect_to_scroll.Width() <= 0)
absolute_rect_to_scroll.SetWidth(LayoutUnit(1));
@@ -677,11 +795,11 @@ PhysicalRect LayoutBox::ScrollRectToVisibleRecursive(
parent_box = ContainingBlock();
PhysicalRect absolute_rect_for_parent;
- if (!IsLayoutView() && HasOverflowClip()) {
+ if (!IsA<LayoutView>(this) && HasOverflowClip()) {
absolute_rect_for_parent =
GetScrollableArea()->ScrollIntoView(absolute_rect_to_scroll, params);
} else if (!parent_box && CanBeProgramaticallyScrolled()) {
- ScrollableArea* area_to_scroll = params.make_visible_in_visual_viewport
+ ScrollableArea* area_to_scroll = params->make_visible_in_visual_viewport
? GetFrameView()->GetScrollableArea()
: GetFrameView()->LayoutViewport();
absolute_rect_for_parent =
@@ -706,7 +824,7 @@ PhysicalRect LayoutBox::ScrollRectToVisibleRecursive(
// have any effect, so we avoid using the RootFrameViewport and explicitly
// scroll the visual viewport if we can. If not, we're done.
if (StyleRef().GetPosition() == EPosition::kFixed && Container() == View() &&
- params.make_visible_in_visual_viewport) {
+ params->make_visible_in_visual_viewport) {
if (GetFrame()->IsMainFrame()) {
// TODO(donnd): We should continue the recursion if we're in a subframe.
return GetFrame()->GetPage()->GetVisualViewport().ScrollIntoView(
@@ -718,11 +836,11 @@ PhysicalRect LayoutBox::ScrollRectToVisibleRecursive(
if (parent_box) {
return parent_box->ScrollRectToVisibleRecursive(absolute_rect_for_parent,
- params);
+ std::move(params));
} else if (GetFrame()->IsLocalRoot() && !GetFrame()->IsMainFrame()) {
if (AllowedToPropagateRecursiveScrollToParentFrame(params)) {
GetFrameView()->ScrollRectToVisibleInRemoteParent(
- absolute_rect_for_parent, params);
+ absolute_rect_for_parent, std::move(params));
}
}
@@ -767,67 +885,74 @@ void LayoutBox::UpdateAfterLayout() {
// e.g. an OOF-positioned object is laid out by an NG containing block, then
// Legacy, then NG again, NG won't use a stale layout result.
if (IsOutOfFlowPositioned() && !IsLayoutNGObject())
- cached_layout_result_.reset();
+ ClearLayoutResults();
}
bool LayoutBox::HasOverrideIntrinsicContentWidth() const {
- const auto& style = StyleRef();
- const IntrinsicLength& intrinsic_length = style.IntrinsicWidth();
- if (intrinsic_length.IsLegacy())
+ if (!ShouldApplySizeContainment())
return false;
- if (intrinsic_length.IsAuto()) {
- // If we have an overflow that is not 'visible' in this direction, then we
- // override the intrinsic length to be 0. Otherwise, it's the same as
- // legacy, meaning we don't override it.
- // https://drafts.csswg.org/css-sizing-4/#valdef-intrinsic-block-size-auto
- return style.OverflowX() != EOverflow::kVisible;
- }
- return true;
+ const Length& intrinsic_length = StyleRef().ContainIntrinsicSize().Width();
+ return !intrinsic_length.IsAuto();
}
bool LayoutBox::HasOverrideIntrinsicContentHeight() const {
- const auto& style = StyleRef();
- const IntrinsicLength& intrinsic_length = style.IntrinsicHeight();
- if (intrinsic_length.IsLegacy())
+ if (!ShouldApplySizeContainment())
return false;
- if (intrinsic_length.IsAuto()) {
- // If we have an overflow that is not 'visible' in this direction, then we
- // override the intrinsic length to be 0. Otherwise, it's the same as
- // legacy, meaning we don't override it.
- // https://drafts.csswg.org/css-sizing-4/#valdef-intrinsic-block-size-auto
- return style.OverflowY() != EOverflow::kVisible;
- }
- return true;
+ const Length& intrinsic_length = StyleRef().ContainIntrinsicSize().Height();
+ return !intrinsic_length.IsAuto();
}
LayoutUnit LayoutBox::OverrideIntrinsicContentWidth() const {
DCHECK(HasOverrideIntrinsicContentWidth());
const auto& style = StyleRef();
- const IntrinsicLength& intrinsic_length = style.IntrinsicWidth();
- DCHECK(!intrinsic_length.IsLegacy());
- if (intrinsic_length.IsAuto()) {
- DCHECK(style.OverflowX() != EOverflow::kVisible);
- return LayoutUnit();
- }
- DCHECK(intrinsic_length.GetLength().IsFixed());
- DCHECK_GE(intrinsic_length.GetLength().Value(), 0.f);
- return LayoutUnit(intrinsic_length.GetLength().Value());
+ const Length& intrinsic_length = style.ContainIntrinsicSize().Width();
+ DCHECK(!intrinsic_length.IsAuto());
+ DCHECK(intrinsic_length.IsFixed());
+ DCHECK_GE(intrinsic_length.Value(), 0.f);
+ return LayoutUnit(intrinsic_length.Value());
}
LayoutUnit LayoutBox::OverrideIntrinsicContentHeight() const {
DCHECK(HasOverrideIntrinsicContentHeight());
const auto& style = StyleRef();
- const IntrinsicLength& intrinsic_length = style.IntrinsicHeight();
- DCHECK(!intrinsic_length.IsLegacy());
- if (intrinsic_length.IsAuto()) {
- DCHECK(style.OverflowY() != EOverflow::kVisible);
- return LayoutUnit();
+ const Length& intrinsic_length = style.ContainIntrinsicSize().Height();
+ DCHECK(!intrinsic_length.IsAuto());
+ DCHECK(intrinsic_length.IsFixed());
+ DCHECK_GE(intrinsic_length.Value(), 0.f);
+ return LayoutUnit(intrinsic_length.Value());
+}
+
+LayoutUnit LayoutBox::DefaultIntrinsicContentInlineSize() const {
+ // If the intrinsic-inline-size is specified, then we shouldn't ever need to
+ // get here.
+ DCHECK(!HasOverrideIntrinsicContentLogicalWidth());
+
+ auto* select = DynamicTo<HTMLSelectElement>(GetNode());
+ if (UNLIKELY(select && select->UsesMenuList())) {
+ return MenuListIntrinsicInlineSize(*select, *this);
+ }
+ auto* input = DynamicTo<HTMLInputElement>(GetNode());
+ if (UNLIKELY(input && input->type() == input_type_names::kFile))
+ return FileUploadControlIntrinsicInlineSize(*input, *this);
+ return kIndefiniteSize;
+}
+
+LayoutUnit LayoutBox::DefaultIntrinsicContentBlockSize() const {
+ // If the intrinsic-block-size is specified, then we shouldn't ever need to
+ // get here.
+ DCHECK(!HasOverrideIntrinsicContentLogicalHeight());
+
+ if (const auto* select = DynamicTo<HTMLSelectElement>(GetNode())) {
+ if (select->UsesMenuList()) {
+ return MenuListIntrinsicBlockSize(*select, *this);
+ } else {
+ return ListBoxItemHeight(*select, *this) * select->ListBoxSize() -
+ ScrollbarLogicalHeight();
+ }
}
- DCHECK(intrinsic_length.GetLength().IsFixed());
- DCHECK_GE(intrinsic_length.GetLength().Value(), 0.f);
- return LayoutUnit(intrinsic_length.GetLength().Value());
+ return kIndefiniteSize;
}
LayoutUnit LayoutBox::LogicalHeightWithVisibleOverflow() const {
@@ -844,7 +969,7 @@ LayoutUnit LayoutBox::ConstrainLogicalWidthByMinMax(
LayoutUnit available_width,
const LayoutBlock* cb) const {
const ComputedStyle& style_to_use = StyleRef();
- if (!style_to_use.LogicalMaxWidth().IsMaxSizeNone())
+ if (!style_to_use.LogicalMaxWidth().IsNone())
logical_width = std::min(
logical_width,
ComputeLogicalWidthUsing(kMaxSize, style_to_use.LogicalMaxWidth(),
@@ -860,8 +985,7 @@ LayoutUnit LayoutBox::ConstrainLogicalHeightByMinMax(
// Note that the values 'min-content', 'max-content' and 'fit-content' should
// behave as the initial value if specified in the block direction.
const Length& logical_max_height = StyleRef().LogicalMaxHeight();
- if (!logical_max_height.IsMaxSizeNone() &&
- !logical_max_height.IsMinContent() &&
+ if (!logical_max_height.IsNone() && !logical_max_height.IsMinContent() &&
!logical_max_height.IsMaxContent() &&
!logical_max_height.IsFitContent()) {
LayoutUnit max_h = ComputeLogicalHeightUsing(kMaxSize, logical_max_height,
@@ -885,7 +1009,7 @@ LayoutUnit LayoutBox::ConstrainContentBoxLogicalHeightByMinMax(
// advantage of already knowing the current resolved percentage height
// to avoid recursing up through our containing blocks again to determine it.
const ComputedStyle& style_to_use = StyleRef();
- if (!style_to_use.LogicalMaxHeight().IsMaxSizeNone()) {
+ if (!style_to_use.LogicalMaxHeight().IsNone()) {
if (style_to_use.LogicalMaxHeight().IsPercent() &&
style_to_use.LogicalHeight().IsPercent()) {
LayoutUnit available_logical_height(
@@ -1083,9 +1207,9 @@ void LayoutBox::Autoscroll(const PhysicalOffset& position_in_root_frame) {
ScrollRectToVisibleRecursive(
PhysicalRect(absolute_position,
PhysicalSize(LayoutUnit(1), LayoutUnit(1))),
- WebScrollIntoViewParams(ScrollAlignment::kAlignToEdgeIfNeeded,
- ScrollAlignment::kAlignToEdgeIfNeeded,
- kUserScroll));
+ ScrollAlignment::CreateScrollIntoViewParams(
+ ScrollAlignment::ToEdgeIfNeeded(), ScrollAlignment::ToEdgeIfNeeded(),
+ mojom::blink::ScrollType::kUser));
}
bool LayoutBox::CanAutoscroll() const {
@@ -1155,11 +1279,6 @@ LayoutBox* LayoutBox::FindAutoscrollable(LayoutObject* layout_object,
: nullptr;
}
-void LayoutBox::MayUpdateHoverWhenContentUnderMouseChanged(
- EventHandler& event_handler) {
- event_handler.MayUpdateHoverAfterScroll(AbsoluteBoundingBoxFloatRect());
-}
-
void LayoutBox::ScrollByRecursively(const ScrollOffset& delta) {
if (delta.IsZero() || !HasOverflowClip())
return;
@@ -1168,7 +1287,8 @@ void LayoutBox::ScrollByRecursively(const ScrollOffset& delta) {
DCHECK(scrollable_area);
ScrollOffset new_scroll_offset = scrollable_area->GetScrollOffset() + delta;
- scrollable_area->SetScrollOffset(new_scroll_offset, kProgrammaticScroll);
+ scrollable_area->SetScrollOffset(new_scroll_offset,
+ mojom::blink::ScrollType::kProgrammatic);
// If this layer can't do the scroll we ask the next layer up that can
// scroll to try.
@@ -1336,7 +1456,7 @@ bool LayoutBox::MapContentsRectToBoxSpace(
}
bool LayoutBox::ContainedContentsScroll(const LayoutObject& contents) const {
- if (IsLayoutView() &&
+ if (IsA<LayoutView>(this) &&
contents.StyleRef().GetPosition() == EPosition::kFixed) {
return false;
}
@@ -1366,40 +1486,23 @@ bool LayoutBox::ApplyBoxClips(
return does_intersect;
}
-void LayoutBox::ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const {
- min_logical_width =
- MinPreferredLogicalWidth() - BorderAndPaddingLogicalWidth();
- max_logical_width =
- MaxPreferredLogicalWidth() - BorderAndPaddingLogicalWidth();
+MinMaxSizes LayoutBox::PreferredLogicalWidths() const {
+ NOTREACHED();
+ return MinMaxSizes();
}
-LayoutUnit LayoutBox::MinPreferredLogicalWidth() const {
- if (PreferredLogicalWidthsDirty()) {
-#if DCHECK_IS_ON()
- SetLayoutNeededForbiddenScope layout_forbidden_scope(
- const_cast<LayoutBox&>(*this));
-#endif
- const_cast<LayoutBox*>(this)->ComputePreferredLogicalWidths();
- DCHECK(!PreferredLogicalWidthsDirty());
- }
-
- return min_preferred_logical_width_;
-}
+void LayoutBox::UpdateCachedIntrinsicLogicalWidthsIfNeeded() {
+ if (!IntrinsicLogicalWidthsDirty())
+ return;
-DISABLE_CFI_PERF
-LayoutUnit LayoutBox::MaxPreferredLogicalWidth() const {
- if (PreferredLogicalWidthsDirty()) {
#if DCHECK_IS_ON()
- SetLayoutNeededForbiddenScope layout_forbidden_scope(
- const_cast<LayoutBox&>(*this));
+ SetLayoutNeededForbiddenScope layout_forbidden_scope(*this);
#endif
- const_cast<LayoutBox*>(this)->ComputePreferredLogicalWidths();
- DCHECK(!PreferredLogicalWidthsDirty());
- }
- return max_preferred_logical_width_;
+ intrinsic_logical_widths_ = ComputeIntrinsicLogicalWidths();
+ intrinsic_logical_widths_percentage_resolution_block_size_ =
+ LayoutUnit::Min();
+ ClearIntrinsicLogicalWidthsDirty();
}
LayoutUnit LayoutBox::OverrideLogicalWidth() const {
@@ -1771,7 +1874,7 @@ bool LayoutBox::GetBackgroundPaintedExtent(PhysicalRect& painted_extent) const {
// LayoutView is special in the sense that it expands to the whole canvas,
// thus can't be handled by this function.
- DCHECK(!IsLayoutView());
+ DCHECK(!IsA<LayoutView>(this));
PhysicalRect background_rect(PhysicalBorderBoxRect());
@@ -1901,7 +2004,7 @@ bool LayoutBox::ComputeBackgroundIsKnownToBeObscured() const {
if (!StyleRef().HasBackground())
return false;
// Root background painting is special.
- if (IsLayoutView())
+ if (IsA<LayoutView>(this))
return false;
// FIXME: box-shadow is painted while background painting.
if (StyleRef().BoxShadow())
@@ -2020,10 +2123,6 @@ void LayoutBox::SizeChanged() {
// object for paint invalidation.
if (!NeedsLayout())
SetShouldCheckForPaintInvalidation();
-
- if (auto* element = DynamicTo<Element>(GetNode())) {
- element->SetNeedsResizeObserverUpdate();
- }
}
bool LayoutBox::IntersectsVisibleViewport() const {
@@ -2089,12 +2188,33 @@ PhysicalRect LayoutBox::OverflowClipRect(
if (HasOverflowClip())
ExcludeScrollbars(clip_rect, overlay_scrollbar_clip_behavior);
- if (HasControlClip())
- clip_rect.Intersect(ControlClipRect(location));
+ auto* input = DynamicTo<HTMLInputElement>(GetNode());
+ if (UNLIKELY(input)) {
+ // As for LayoutButton, ControlClip is to for not BUTTONs but INPUT
+ // buttons for IE/Firefox compatibility.
+ if (IsTextField() || IsLayoutButton()) {
+ DCHECK(HasControlClip());
+ PhysicalRect control_clip = PhysicalPaddingBoxRect();
+ control_clip.Move(location);
+ clip_rect.Intersect(control_clip);
+ }
+ } else if (UNLIKELY(IsMenuList(this))) {
+ DCHECK(HasControlClip());
+ PhysicalRect control_clip = PhysicalContentBoxRect();
+ control_clip.Move(location);
+ clip_rect.Intersect(control_clip);
+ } else {
+ DCHECK(!HasControlClip());
+ }
return clip_rect;
}
+bool LayoutBox::HasControlClip() const {
+ return UNLIKELY(IsTextField() || IsFileUploadControl() || IsMenuList(this) ||
+ (IsLayoutButton() && IsA<HTMLInputElement>(GetNode())));
+}
+
void LayoutBox::ExcludeScrollbars(
PhysicalRect& rect,
OverlayScrollbarClipBehavior overlay_scrollbar_clip_behavior) const {
@@ -2343,6 +2463,17 @@ void LayoutBox::DirtyLineBoxes(bool full_layout) {
}
}
+bool LayoutBox::HasInlineFragments() const {
+ if (!IsInLayoutNGInlineFormattingContext())
+ return inline_box_wrapper_;
+ if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return first_paint_fragment_;
+ // TODO(yosin): We should use |first_fragment_item_index_|.
+ NGInlineCursor cursor;
+ cursor.MoveTo(*this);
+ return cursor;
+}
+
void LayoutBox::SetFirstInlineFragment(NGPaintFragment* fragment) {
CHECK(IsInLayoutNGInlineFormattingContext()) << *this;
// TODO(yosin): Once we remove |NGPaintFragment|, we should get rid of
@@ -2361,7 +2492,9 @@ void LayoutBox::SetFirstInlineFragmentItemIndex(wtf_size_t index) {
CHECK(IsInLayoutNGInlineFormattingContext()) << *this;
DCHECK(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
DCHECK_NE(index, 0u);
- first_fragment_item_index_ = index;
+ // TDOO(yosin): Once we update all |LayoutObject::FirstInlineFragment()|,
+ // we should enable below.
+ // first_fragment_item_index_ = index;
}
void LayoutBox::InLayoutNGInlineFormattingContextWillChange(bool new_value) {
@@ -2372,33 +2505,76 @@ void LayoutBox::InLayoutNGInlineFormattingContextWillChange(bool new_value) {
DCHECK(new_value ? !first_paint_fragment_ : !inline_box_wrapper_);
}
-void LayoutBox::SetCachedLayoutResult(const NGLayoutResult& layout_result,
- const NGBreakToken* break_token) {
- DCHECK_EQ(layout_result.Status(), NGLayoutResult::kSuccess);
+void LayoutBox::SetCachedLayoutResult(
+ scoped_refptr<const NGLayoutResult> result) {
+ DCHECK(!result->PhysicalFragment().BreakToken());
+ DCHECK(!result->IsSingleUse());
- if (break_token)
- return;
- if (layout_result.PhysicalFragment().BreakToken())
- return;
+ if (result->GetConstraintSpaceForCaching().CacheSlot() ==
+ NGCacheSlot::kMeasure) {
+ if (measure_result_)
+ InvalidateItems(*measure_result_);
+ measure_result_ = result;
+ // When setting the "measure" result we also set the "layout" result.
+ }
- ClearCachedLayoutResult();
- cached_layout_result_ = &layout_result;
+ AddLayoutResult(std::move(result), 0);
}
-void LayoutBox::ClearCachedLayoutResult() {
- if (!cached_layout_result_)
- return;
+void LayoutBox::AddLayoutResult(scoped_refptr<const NGLayoutResult> result,
+ wtf_size_t index) {
+ DCHECK_EQ(result->Status(), NGLayoutResult::kSuccess);
+ if (index != WTF::kNotFound)
+ ShrinkLayoutResults(index);
+ layout_results_.push_back(std::move(result));
+}
+void LayoutBox::ClearLayoutResults() {
+ if (measure_result_)
+ InvalidateItems(*measure_result_);
+ measure_result_ = nullptr;
+
+ ShrinkLayoutResults(0);
+}
+
+void LayoutBox::ShrinkLayoutResults(wtf_size_t results_to_keep) {
+ DCHECK_GE(layout_results_.size(), results_to_keep);
// Invalidate if inline |DisplayItemClient|s will be destroyed.
- if (const auto* box_fragment = DynamicTo<NGPhysicalBoxFragment>(
- &cached_layout_result_->PhysicalFragment())) {
- if (box_fragment->HasItems()) {
- DCHECK_EQ(this, box_fragment->GetLayoutObject());
- ObjectPaintInvalidator(*this).SlowSetPaintingLayerNeedsRepaint();
- }
- }
+ for (wtf_size_t i = results_to_keep; i < layout_results_.size(); i++)
+ InvalidateItems(*layout_results_[i]);
+ layout_results_.Shrink(results_to_keep);
+}
+
+void LayoutBox::InvalidateItems(const NGLayoutResult& result) {
+ // Invalidate if inline |DisplayItemClient|s will be destroyed.
+ const auto& box_fragment =
+ To<NGPhysicalBoxFragment>(result.PhysicalFragment());
+ if (!box_fragment.HasItems())
+ return;
+
+ DCHECK_EQ(this, box_fragment.GetLayoutObject());
+ ObjectPaintInvalidator(*this).SlowSetPaintingLayerNeedsRepaint();
+}
+
+const NGLayoutResult* LayoutBox::GetCachedLayoutResult() const {
+ if (layout_results_.IsEmpty())
+ return nullptr;
+ // Only return re-usable results.
+ const NGLayoutResult* result = layout_results_[0].get();
+ if (result->IsSingleUse())
+ return nullptr;
+ DCHECK_EQ(layout_results_.size(), 1u);
+ return result;
+}
+
+const NGLayoutResult* LayoutBox::GetCachedMeasureResult() const {
+ if (!measure_result_)
+ return nullptr;
+
+ if (measure_result_->IsSingleUse())
+ return nullptr;
- cached_layout_result_ = nullptr;
+ return measure_result_.get();
}
scoped_refptr<const NGLayoutResult> LayoutBox::CachedLayoutResult(
@@ -2409,10 +2585,12 @@ scoped_refptr<const NGLayoutResult> LayoutBox::CachedLayoutResult(
NGLayoutCacheStatus* out_cache_status) {
*out_cache_status = NGLayoutCacheStatus::kNeedsLayout;
- if (!RuntimeEnabledFeatures::LayoutNGFragmentCachingEnabled())
- return nullptr;
+ const NGLayoutResult* cached_layout_result =
+ new_space.CacheSlot() == NGCacheSlot::kLayout &&
+ !layout_results_.IsEmpty()
+ ? GetCachedLayoutResult()
+ : GetCachedMeasureResult();
- const NGLayoutResult* cached_layout_result = GetCachedLayoutResult();
if (!cached_layout_result)
return nullptr;
@@ -2509,8 +2687,7 @@ scoped_refptr<const NGLayoutResult> LayoutBox::CachedLayoutResult(
bool is_exclusion_space_equal =
new_space.ExclusionSpace() == old_space.ExclusionSpace();
- bool is_new_formatting_context =
- physical_fragment.IsBlockFormattingContextRoot();
+ bool is_new_formatting_context = physical_fragment.IsFormattingContextRoot();
// If a node *doesn't* establish a new formatting context it may be affected
// by floats, or clearance.
@@ -2545,7 +2722,7 @@ scoped_refptr<const NGLayoutResult> LayoutBox::CachedLayoutResult(
// "simplified" layout then abort now.
*out_cache_status = cache_status;
if (*out_cache_status == NGLayoutCacheStatus::kNeedsSimplifiedLayout)
- return nullptr;
+ return cached_layout_result;
physical_fragment.CheckType();
@@ -2587,11 +2764,29 @@ scoped_refptr<const NGLayoutResult> LayoutBox::CachedLayoutResult(
bfc_block_offset, block_offset_delta));
if (needs_cached_result_update)
- SetCachedLayoutResult(*new_result, break_token);
+ SetCachedLayoutResult(new_result);
return new_result;
}
+const NGPhysicalBoxFragment* LayoutBox::GetPhysicalFragment(
+ wtf_size_t index) const {
+ return &To<NGPhysicalBoxFragment>(layout_results_[index]->PhysicalFragment());
+}
+
+const FragmentData* LayoutBox::FragmentDataFromPhysicalFragment(
+ const NGPhysicalBoxFragment& physical_fragment) const {
+ const FragmentData* fragment_data = &FirstFragment();
+ for (const auto& result : layout_results_) {
+ if (&result->PhysicalFragment() == &physical_fragment)
+ return fragment_data;
+ DCHECK(fragment_data->NextFragment());
+ fragment_data = fragment_data->NextFragment();
+ }
+ NOTREACHED();
+ return fragment_data;
+}
+
void LayoutBox::PositionLineBox(InlineBox* box) {
if (IsOutOfFlowPositioned()) {
// Cache the x position only if we were an INLINE type originally.
@@ -2772,27 +2967,6 @@ bool LayoutBox::NeedsForcedBreakBefore(
return IsForcedFragmentainerBreakValue(break_value);
}
-bool LayoutBox::PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const {
- if (HasNonCompositedScrollbars() || IsSelected() ||
- HasBoxDecorationBackground() || StyleRef().HasBoxDecorations() ||
- StyleRef().HasVisualOverflowingEffect())
- return false;
-
- // Both mask and clip-path generates drawing display items that depends on
- // the size of the box.
- if (HasMask() || HasClipPath())
- return false;
-
- // If the box paints into its own backing, we can assume that it's painting
- // may have some effect. For example, honoring the border-radius clip on
- // a composited child paints into a mask for an otherwise non-painting
- // element, because children of that element will require the mask.
- if (HasLayer() && Layer()->GetCompositingState() == kPaintsIntoOwnBacking)
- return false;
-
- return true;
-}
-
PhysicalRect LayoutBox::LocalVisualRectIgnoringVisibility() const {
return PhysicalSelfVisualOverflowRect();
}
@@ -2900,10 +3074,10 @@ bool LayoutBox::MapToVisualRectInAncestorSpaceInternal(
return true;
}
- if (container->IsLayoutView()) {
+ if (auto* layout_view = DynamicTo<LayoutView>(container)) {
bool use_fixed_position_adjustment =
position == EPosition::kFixed && container == ancestor;
- return ToLayoutView(container)->MapToVisualRectInAncestorSpaceInternal(
+ return layout_view->MapToVisualRectInAncestorSpaceInternal(
ancestor, transform_state, use_fixed_position_adjustment ? kIsFixed : 0,
visual_rect_flags);
} else {
@@ -2926,7 +3100,7 @@ void LayoutBox::InflateVisualRectForFilter(
static bool ShouldRecalculateMinMaxWidthsAffectedByAncestor(
const LayoutBox* box) {
- if (box->PreferredLogicalWidthsDirty()) {
+ if (box->IntrinsicLogicalWidthsDirty()) {
// If the preferred widths are already dirty at this point (during layout),
// it actually means that we never need to calculate them, since that should
// have been carried out by an ancestor that's sized based on preferred
@@ -2937,7 +3111,7 @@ static bool ShouldRecalculateMinMaxWidthsAffectedByAncestor(
}
if (const LayoutBox* containing_block = box->ContainingBlock()) {
if (containing_block->NeedsPreferredWidthsRecalculation() &&
- !containing_block->PreferredLogicalWidthsDirty()) {
+ !containing_block->IntrinsicLogicalWidthsDirty()) {
// If our containing block also has min/max widths that are affected by
// the ancestry, we have already dealt with this object as well. Avoid
// unnecessary work and O(n^2) time complexity.
@@ -2956,14 +3130,14 @@ void LayoutBox::UpdateLogicalWidth() {
// bottom-up, but that's not always the case), so since the containing
// block size may have changed, we need to recalculate the min/max widths
// of this object, and every child that has the same issue, recursively.
- SetPreferredLogicalWidthsDirty(kMarkOnlyThis);
+ SetIntrinsicLogicalWidthsDirty(kMarkOnlyThis);
// Since all this takes place during actual layout, instead of being part
// of min/max the width calculation machinery, we need to enter said
- // machinery here, to make sure that what was dirtied is actualy
+ // machinery here, to make sure that what was dirtied is actually
// recalculated. Leaving things dirty would mean that any subsequent
// dirtying of descendants would fail.
- ComputePreferredLogicalWidths();
+ UpdateCachedIntrinsicLogicalWidthsIfNeeded();
}
}
@@ -3058,7 +3232,7 @@ void LayoutBox::ComputeLogicalWidth(
if (treat_as_replaced) {
computed_values.extent_ = std::max(
ComputeReplacedLogicalWidth() + BorderAndPaddingLogicalWidth(),
- MinPreferredLogicalWidth());
+ PreferredLogicalWidths().min_size);
}
return;
}
@@ -3163,33 +3337,27 @@ LayoutUnit LayoutBox::FillAvailableMeasure(LayoutUnit available_logical_width,
DISABLE_CFI_PERF
LayoutUnit LayoutBox::ComputeIntrinsicLogicalWidthUsing(
const Length& logical_width_length,
- LayoutUnit available_logical_width,
- LayoutUnit border_and_padding) const {
+ LayoutUnit available_logical_width) const {
if (logical_width_length.IsFillAvailable()) {
if (!IsA<HTMLMarqueeElement>(GetNode())) {
UseCounter::Count(GetDocument(),
WebFeature::kCSSFillAvailableLogicalWidth);
}
- return std::max(border_and_padding,
+ return std::max(BorderAndPaddingLogicalWidth(),
FillAvailableMeasure(available_logical_width));
}
- LayoutUnit min_logical_width;
- LayoutUnit max_logical_width;
- ComputeIntrinsicLogicalWidths(min_logical_width, max_logical_width);
+ MinMaxSizes sizes = IntrinsicLogicalWidths();
if (logical_width_length.IsMinContent())
- return min_logical_width + border_and_padding;
+ return sizes.min_size;
if (logical_width_length.IsMaxContent())
- return max_logical_width + border_and_padding;
+ return sizes.max_size;
if (logical_width_length.IsFitContent()) {
- min_logical_width += border_and_padding;
- max_logical_width += border_and_padding;
- return std::max(min_logical_width,
- std::min(max_logical_width,
- FillAvailableMeasure(available_logical_width)));
+ return sizes.ClampSizeToMinAndMax(
+ FillAvailableMeasure(available_logical_width));
}
NOTREACHED();
@@ -3214,9 +3382,10 @@ LayoutUnit LayoutBox::ComputeLogicalWidthUsing(
ValueForLength(logical_width, available_logical_width));
}
- if (logical_width.IsIntrinsic())
- return ComputeIntrinsicLogicalWidthUsing(
- logical_width, available_logical_width, BorderAndPaddingLogicalWidth());
+ if (logical_width.IsIntrinsic()) {
+ return ComputeIntrinsicLogicalWidthUsing(logical_width,
+ available_logical_width);
+ }
LayoutUnit margin_start;
LayoutUnit margin_end;
@@ -3238,9 +3407,9 @@ LayoutUnit LayoutBox::ComputeLogicalWidthUsing(
// TODO(crbug.com/710026): Remove const_cast
LayoutUnit w = LogicalWidth();
const_cast<LayoutBox*>(this)->SetLogicalWidth(LayoutUnit());
+ MinMaxSizes preferred_logical_widths = PreferredLogicalWidths();
LayoutUnit result =
- std::max(MinPreferredLogicalWidth(),
- std::min(MaxPreferredLogicalWidth(), logical_width_result));
+ preferred_logical_widths.ClampSizeToMinAndMax(logical_width_result);
const_cast<LayoutBox*>(this)->SetLogicalWidth(w);
return result;
}
@@ -3513,10 +3682,16 @@ void LayoutBox::ComputeLogicalHeight(
if (HasOverrideIntrinsicContentLogicalHeight()) {
height = OverrideIntrinsicContentLogicalHeight() +
BorderAndPaddingLogicalHeight() + ScrollbarLogicalHeight();
- } else if (ShouldApplySizeContainment() && !IsLayoutGrid()) {
- height = BorderAndPaddingLogicalHeight() + ScrollbarLogicalHeight();
} else {
- height = LogicalHeight();
+ LayoutUnit default_height = DefaultIntrinsicContentBlockSize();
+ if (default_height != kIndefiniteSize) {
+ height = default_height + BorderAndPaddingLogicalHeight() +
+ ScrollbarLogicalHeight();
+ } else if (ShouldApplySizeContainment() && !IsLayoutGrid()) {
+ height = BorderAndPaddingLogicalHeight() + ScrollbarLogicalHeight();
+ } else {
+ height = LogicalHeight();
+ }
}
ComputeLogicalHeight(height, LogicalTop(), computed_values);
}
@@ -3564,22 +3739,13 @@ void LayoutBox::ComputeLogicalHeight(
return;
}
- // FIXME: Account for writing-mode in flexible boxes.
- // https://bugs.webkit.org/show_bug.cgi?id=46418
- bool in_horizontal_box =
- Parent()->IsDeprecatedFlexibleBox() &&
- Parent()->StyleRef().BoxOrient() == EBoxOrient::kHorizontal;
- bool stretching =
- Parent()->StyleRef().BoxAlign() == EBoxAlignment::kStretch;
- bool treat_as_replaced =
- ShouldComputeSizeAsReplaced() && (!in_horizontal_box || !stretching);
bool check_min_max_height = false;
// The parent box is flexing us, so it has increased or decreased our
// height. We have to grab our cached flexible height.
if (HasOverrideLogicalHeight()) {
h = Length::Fixed(OverrideLogicalHeight());
- } else if (treat_as_replaced) {
+ } else if (ShouldComputeSizeAsReplaced()) {
h = Length::Fixed(ComputeReplacedLogicalHeight() +
BorderAndPaddingLogicalHeight());
} else {
@@ -3587,16 +3753,6 @@ void LayoutBox::ComputeLogicalHeight(
check_min_max_height = true;
}
- // Block children of horizontal flexible boxes fill the height of the box.
- // FIXME: Account for writing-mode in flexible boxes.
- // https://bugs.webkit.org/show_bug.cgi?id=46418
- if (h.IsAuto() && in_horizontal_box &&
- ToLayoutDeprecatedFlexibleBox(Parent())->IsStretchingChildren()) {
- h = Length::Fixed(ParentBox()->ContentLogicalHeight() - MarginBefore() -
- MarginAfter());
- check_min_max_height = false;
- }
-
LayoutUnit height_result;
if (check_min_max_height) {
height_result = ComputeLogicalHeightUsing(
@@ -3793,7 +3949,7 @@ LayoutUnit LayoutBox::ContainingBlockLogicalHeightForPercentageResolution(
const LayoutBox* containing_block_child = this;
bool skipped_auto_height_containing_block = false;
LayoutUnit root_margin_border_padding_height;
- while (!cb->IsLayoutView() &&
+ while (!IsA<LayoutView>(cb) &&
(IsHorizontalWritingMode() == cb->IsHorizontalWritingMode() &&
SkipContainingBlockForPercentHeightCalculation(cb))) {
if ((cb->IsBody() || cb->IsDocumentElement()) &&
@@ -3931,7 +4087,7 @@ LayoutUnit LayoutBox::ComputeReplacedLogicalWidthRespectingMinMaxWidth(
LayoutUnit max_logical_width =
(should_compute_preferred == kComputePreferred &&
StyleRef().LogicalMaxWidth().IsPercentOrCalc()) ||
- StyleRef().LogicalMaxWidth().IsMaxSizeNone()
+ StyleRef().LogicalMaxWidth().IsNone()
? logical_width
: ComputeReplacedLogicalWidthUsing(kMaxSize,
StyleRef().LogicalMaxWidth());
@@ -3955,8 +4111,7 @@ LayoutUnit LayoutBox::ComputeReplacedLogicalWidthUsing(
// MinContent/MaxContent don't need the availableLogicalWidth argument.
LayoutUnit available_logical_width;
return ComputeIntrinsicLogicalWidthUsing(logical_width,
- available_logical_width,
- BorderAndPaddingLogicalWidth()) -
+ available_logical_width) -
BorderAndPaddingLogicalWidth();
}
case Length::kFitContent:
@@ -3978,8 +4133,7 @@ LayoutUnit LayoutBox::ComputeReplacedLogicalWidthUsing(
// FIXME: Handle cases when containing block width is calculated or
// viewport percent. https://bugs.webkit.org/show_bug.cgi?id=91071
if (logical_width.IsIntrinsic())
- return ComputeIntrinsicLogicalWidthUsing(
- logical_width, cw, BorderAndPaddingLogicalWidth()) -
+ return ComputeIntrinsicLogicalWidthUsing(logical_width, cw) -
BorderAndPaddingLogicalWidth();
if (cw > 0 || (!cw && (container_logical_width.IsFixed() ||
container_logical_width.IsPercentOrCalc())))
@@ -3988,7 +4142,7 @@ LayoutUnit LayoutBox::ComputeReplacedLogicalWidthUsing(
return LayoutUnit();
}
case Length::kAuto:
- case Length::kMaxSizeNone:
+ case Length::kNone:
return IntrinsicLogicalWidth();
case Length::kExtendToZoom:
case Length::kDeviceWidth:
@@ -4025,6 +4179,11 @@ bool LayoutBox::LogicalHeightComputesAsNone(SizeType size_type) const {
if (logical_height == initial_logical_height)
return true;
+ if (logical_height.IsPercentOrCalc() &&
+ HasOverrideContainingBlockContentLogicalHeight() &&
+ OverrideContainingBlockContentLogicalHeight() == kIndefiniteSize)
+ return true;
+
// CustomLayout items can resolve their percentages against an available or
// percentage size override.
if (IsCustomItem() && (HasOverrideContainingBlockContentLogicalHeight() ||
@@ -4114,7 +4273,7 @@ LayoutUnit LayoutBox::ComputeReplacedLogicalHeightUsing(
// FIXME: This needs to be made writing-mode-aware. If the cell and
// image are perpendicular writing-modes, this isn't right.
// https://bugs.webkit.org/show_bug.cgi?id=46997
- while (cb && !cb->IsLayoutView() &&
+ while (!IsA<LayoutView>(cb) &&
(cb->StyleRef().LogicalHeight().IsAuto() ||
cb->StyleRef().LogicalHeight().IsPercentOrCalc())) {
if (cb->IsTableCell()) {
@@ -4173,10 +4332,10 @@ LayoutUnit LayoutBox::AvailableLogicalHeight(
LayoutUnit LayoutBox::AvailableLogicalHeightUsing(
const Length& h,
AvailableLogicalHeightType height_type) const {
- if (IsLayoutView()) {
+ if (auto* layout_view = DynamicTo<LayoutView>(this)) {
return LayoutUnit(IsHorizontalWritingMode()
- ? ToLayoutView(this)->GetFrameView()->Size().Height()
- : ToLayoutView(this)->GetFrameView()->Size().Width());
+ ? layout_view->GetFrameView()->Size().Height()
+ : layout_view->GetFrameView()->Size().Width());
}
// We need to stop here, since we don't want to increase the height of the
@@ -4192,10 +4351,17 @@ LayoutUnit LayoutBox::AvailableLogicalHeightUsing(
return LogicalHeight() - BorderAndPaddingLogicalHeight();
}
- if (IsFlexItem()) {
- const LayoutFlexibleBox& flex_box = ToLayoutFlexibleBox(*Parent());
- if (flex_box.UseOverrideLogicalHeightForPerentageResolution(*this))
- return OverrideContentLogicalHeight();
+ if (IsFlexItemIncludingNG()) {
+ if (IsFlexItem()) {
+ const LayoutFlexibleBox& flex_box = ToLayoutFlexibleBox(*Parent());
+ if (flex_box.UseOverrideLogicalHeightForPerentageResolution(*this))
+ return OverrideContentLogicalHeight();
+ } else if (GetCachedLayoutResult()) {
+ const NGConstraintSpace& space =
+ GetCachedLayoutResult()->GetConstraintSpaceForCaching();
+ if (space.IsFixedBlockSize() && !space.IsFixedBlockSizeIndefinite())
+ return space.AvailableSize().block_size;
+ }
}
if (h.IsPercentOrCalc() && IsOutOfFlowPositioned()) {
@@ -4271,9 +4437,9 @@ LayoutUnit LayoutBox::ContainingBlockLogicalWidthForPositioned(
return ContainingBlockLogicalHeightForPositioned(containing_block, false);
// Use viewport as container for top-level fixed-position elements.
- if (StyleRef().GetPosition() == EPosition::kFixed &&
- containing_block->IsLayoutView() && !GetDocument().Printing()) {
- const LayoutView* view = ToLayoutView(containing_block);
+ const auto* view = DynamicTo<LayoutView>(containing_block);
+ if (StyleRef().GetPosition() == EPosition::kFixed && view &&
+ !GetDocument().Printing()) {
if (LocalFrameView* frame_view = view->GetFrameView()) {
// Don't use visibleContentRect since the PaintLayer's size has not been
// set yet.
@@ -4342,9 +4508,9 @@ LayoutUnit LayoutBox::ContainingBlockLogicalHeightForPositioned(
return ContainingBlockLogicalWidthForPositioned(containing_block, false);
// Use viewport as container for top-level fixed-position elements.
- if (StyleRef().GetPosition() == EPosition::kFixed &&
- containing_block->IsLayoutView() && !GetDocument().Printing()) {
- const LayoutView* view = ToLayoutView(containing_block);
+ const auto* view = DynamicTo<LayoutView>(containing_block);
+ if (StyleRef().GetPosition() == EPosition::kFixed && view &&
+ !GetDocument().Printing()) {
if (LocalFrameView* frame_view = view->GetFrameView()) {
// Don't use visibleContentRect since the PaintLayer's size has not been
// set yet.
@@ -4368,7 +4534,7 @@ LayoutUnit LayoutBox::ContainingBlockLogicalHeightForPositioned(
const LayoutInline* flow = ToLayoutInline(containing_block);
// If the containing block is empty, return a height of 0.
- if (flow->IsEmpty())
+ if (!flow->HasInlineFragments())
return LayoutUnit();
LayoutUnit height_result;
@@ -4583,7 +4749,7 @@ void LayoutBox::ComputePositionedLogicalWidth(
margin_logical_right, computed_values);
// Calculate constraint equation values for 'max-width' case.
- if (!StyleRef().LogicalMaxWidth().IsMaxSizeNone()) {
+ if (!StyleRef().LogicalMaxWidth().IsNone()) {
LogicalExtentComputedValues max_values;
ComputePositionedLogicalWidthUsing(
@@ -4653,13 +4819,9 @@ void LayoutBox::ComputeLogicalLeftPositionedOffset(
LayoutUnit LayoutBox::ShrinkToFitLogicalWidth(
LayoutUnit available_logical_width,
LayoutUnit borders_plus_padding) const {
- LayoutUnit preferred_logical_width =
- MaxPreferredLogicalWidth() - borders_plus_padding;
- LayoutUnit preferred_min_logical_width =
- MinPreferredLogicalWidth() - borders_plus_padding;
- return std::min(
- std::max(preferred_min_logical_width, available_logical_width),
- preferred_logical_width);
+ MinMaxSizes sizes = PreferredLogicalWidths();
+ sizes -= borders_plus_padding;
+ return sizes.ShrinkToFit(available_logical_width);
}
void LayoutBox::ComputePositionedLogicalWidthUsing(
@@ -4678,16 +4840,16 @@ void LayoutBox::ComputePositionedLogicalWidthUsing(
DCHECK(width_size_type == kMinSize ||
width_size_type == kMainOrPreferredSize || !logical_width.IsAuto());
- if (width_size_type == kMinSize && logical_width.IsAuto())
+ if (width_size_type == kMinSize && logical_width.IsAuto()) {
logical_width_value = LayoutUnit();
- else if (logical_width.IsIntrinsic())
- logical_width_value =
- ComputeIntrinsicLogicalWidthUsing(
- logical_width, container_logical_width, borders_plus_padding) -
- borders_plus_padding;
- else
+ } else if (logical_width.IsIntrinsic()) {
+ logical_width_value = ComputeIntrinsicLogicalWidthUsing(
+ logical_width, container_logical_width) -
+ borders_plus_padding;
+ } else {
logical_width_value = AdjustContentBoxLogicalWidthForBoxSizing(
ValueForLength(logical_width, container_logical_width));
+ }
// 'left' and 'right' cannot both be 'auto' because one would of been
// converted to the static position already
@@ -4996,8 +5158,7 @@ void LayoutBox::ComputePositionedLogicalHeight(
// Calculate constraint equation values for 'max-height' case.
const Length& logical_max_height = style_to_use.LogicalMaxHeight();
- if (!logical_max_height.IsMaxSizeNone() &&
- !logical_max_height.IsMinContent() &&
+ if (!logical_max_height.IsNone() && !logical_max_height.IsMinContent() &&
!logical_max_height.IsMaxContent() &&
!logical_max_height.IsFitContent()) {
LogicalExtentComputedValues max_values;
@@ -5695,7 +5856,7 @@ void LayoutBox::AddLayoutOverflow(const LayoutRect& rect) {
// For overflow clip objects, we don't want to propagate overflow into
// unreachable areas.
LayoutRect overflow_rect(rect);
- if (HasOverflowClip() || IsLayoutView()) {
+ if (HasOverflowClip() || IsA<LayoutView>(this)) {
// Overflow is in the block's coordinate space and thus is flipped for
// vertical-rl writing
// mode. At this stage that is actually a simplification, since we can
@@ -5813,7 +5974,7 @@ bool LayoutBox::HasUnsplittableScrollingOverflow() const {
// world and is what we used to do in the old model anyway.
return !StyleRef().LogicalHeight().IsIntrinsicOrAuto() ||
(!StyleRef().LogicalMaxHeight().IsIntrinsicOrAuto() &&
- !StyleRef().LogicalMaxHeight().IsMaxSizeNone() &&
+ !StyleRef().LogicalMaxHeight().IsNone() &&
(!StyleRef().LogicalMaxHeight().IsPercentOrCalc() ||
PercentageLogicalHeightIsResolvable())) ||
(!StyleRef().LogicalMinHeight().IsIntrinsicOrAuto() &&
@@ -6029,7 +6190,7 @@ static void MarkBoxForRelayoutAfterSplit(LayoutBox* box) {
ToInterface<LayoutNGTableSectionInterface>(box)->SetNeedsCellRecalc();
}
- box->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ box->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kAnonymousBlockChange);
}
@@ -6336,11 +6497,11 @@ void LayoutBox::ReassignSnapAreas(LayoutBox& new_container) {
}
bool LayoutBox::AllowedToPropagateRecursiveScrollToParentFrame(
- const WebScrollIntoViewParams& params) {
+ const mojom::blink::ScrollIntoViewParamsPtr& params) {
if (!GetFrameView()->SafeToPropagateScrollToParent())
return false;
- if (params.GetScrollType() != kProgrammaticScroll)
+ if (params->type != mojom::blink::ScrollType::kProgrammatic)
return true;
return !GetDocument().IsVerticalScrollEnforced();
@@ -6420,7 +6581,7 @@ TextDirection LayoutBox::ResolvedDirection() const {
NGInlineCursor cursor;
cursor.MoveTo(*this);
if (cursor)
- return cursor.CurrentResolvedDirection();
+ return cursor.Current().ResolvedDirection();
}
if (InlineBoxWrapper())
return InlineBoxWrapper()->Direction();
@@ -6428,4 +6589,15 @@ TextDirection LayoutBox::ResolvedDirection() const {
return StyleRef().Direction();
}
+bool LayoutBox::NeedsScrollNode(
+ CompositingReasons direct_compositing_reasons) const {
+ if (!HasOverflowClip())
+ return false;
+
+ if (direct_compositing_reasons & CompositingReason::kRootScroller)
+ return true;
+
+ return GetScrollableArea()->ScrollsOverflow();
+}
+
} // namespace blink
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 d7c8e1e3355..a9484751df2 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_box.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_box.h
@@ -26,16 +26,16 @@
#include <memory>
#include "base/macros.h"
+#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/layout_box_model_object.h"
-#include "third_party/blink/renderer/core/layout/min_max_size.h"
+#include "third_party/blink/renderer/core/layout/min_max_sizes.h"
#include "third_party/blink/renderer/core/layout/overflow_model.h"
#include "third_party/blink/renderer/platform/graphics/scroll_types.h"
namespace blink {
class CustomLayoutChild;
-class EventHandler;
class LayoutBlockFlow;
class LayoutMultiColumnSpannerPlaceholder;
class NGBoxFragmentBuilder;
@@ -49,7 +49,6 @@ enum class NGLayoutCacheStatus;
class NGLayoutResult;
struct NGPhysicalBoxStrut;
struct PaintInfo;
-struct WebScrollIntoViewParams;
enum SizeType { kMainOrPreferredSize, kMinSize, kMaxSize };
enum AvailableLogicalHeightType {
@@ -66,12 +65,12 @@ enum ShouldComputePreferred { kComputeActual, kComputePreferred };
using SnapAreaSet = HashSet<LayoutBox*>;
-struct LayoutBoxRareData {
- USING_FAST_MALLOC(LayoutBoxRareData);
-
+struct LayoutBoxRareData final : public GarbageCollected<LayoutBoxRareData> {
public:
LayoutBoxRareData();
+ void Trace(Visitor* visitor);
+
// For spanners, the spanner placeholder that lays us out within the multicol
// container.
LayoutMultiColumnSpannerPlaceholder* spanner_placeholder_;
@@ -115,7 +114,7 @@ struct LayoutBoxRareData {
// Used by CSSLayoutDefinition::Instance::Layout. Represents the script
// object for this box that web developers can query style, and perform
// layout upon. Only created if IsCustomItem() is true.
- Persistent<CustomLayoutChild> layout_child_;
+ Member<CustomLayoutChild> layout_child_;
DISALLOW_COPY_AND_ASSIGN(LayoutBoxRareData);
};
@@ -224,6 +223,11 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
virtual bool BackgroundShouldAlwaysBeClipped() const { return false; }
+ // Returns whether this object needs a scroll paint property tree node. These
+ // are a requirement for composited scrolling but are also created for
+ // non-composited scrollers.
+ bool NeedsScrollNode(CompositingReasons direct_compositing_reasons) const;
+
// Use this with caution! No type checking is done!
LayoutBox* FirstChildBox() const;
LayoutBox* FirstInFlowChildBox() const;
@@ -408,16 +412,17 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
ClientHeight());
}
- // TODO(crbu.com/962299): This method is only correct when |offset| is the
- // correct paint offset. It's also incrrect in flipped blocks writing mode.
- IntRect PixelSnappedBorderBoxRect(const PhysicalOffset& offset) const {
- return PixelSnappedBorderBoxRect(offset.ToLayoutSize());
- }
- IntRect PixelSnappedBorderBoxRect(
- const LayoutSize& offset = LayoutSize()) const {
+ // TODO(crbug.com/962299): This method snaps to pixels incorrectly because
+ // Location() is not the correct paint offset. It's also incorrect in flipped
+ // blocks writing mode.
+ IntRect PixelSnappedBorderBoxRect() const {
return IntRect(IntPoint(),
- PixelSnappedIntSize(frame_rect_.Size(),
- frame_rect_.Location() + offset));
+ PixelSnappedBorderBoxSize(PhysicalOffset(Location())));
+ }
+ // TODO(crbug.com/962299): This method is only correct when |offset| is the
+ // correct paint offset.
+ IntSize PixelSnappedBorderBoxSize(const PhysicalOffset& offset) const {
+ return PixelSnappedIntSize(Size(), offset.ToLayoutPoint());
}
IntRect BorderBoundingBox() const final {
return PixelSnappedBorderBoxRect();
@@ -635,6 +640,11 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
: OverrideIntrinsicContentWidth();
}
+ // Returns element-native intrinsic size. Returns kIndefiniteSize if no such
+ // size.
+ LayoutUnit DefaultIntrinsicContentInlineSize() const;
+ LayoutUnit DefaultIntrinsicContentBlockSize() const;
+
// IE extensions. Used to calculate offsetWidth/Height. Overridden by inlines
// (LayoutFlow) to return the remaining width on a given line (and the height
// of a single line).
@@ -718,8 +728,9 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
void ScrollByRecursively(const ScrollOffset& delta);
// If makeVisibleInVisualViewport is set, the visual viewport will be scrolled
// if required to make the rect visible.
- PhysicalRect ScrollRectToVisibleRecursive(const PhysicalRect&,
- const WebScrollIntoViewParams&);
+ PhysicalRect ScrollRectToVisibleRecursive(
+ const PhysicalRect&,
+ mojom::blink::ScrollIntoViewParamsPtr);
LayoutRectOutsets MarginBoxOutsets() const { return margin_box_outsets_; }
LayoutUnit MarginTop() const override { return margin_box_outsets_.Top(); }
@@ -795,8 +806,11 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
const PhysicalOffset& accumulated_offset,
HitTestAction) override;
- LayoutUnit MinPreferredLogicalWidth() const override;
- LayoutUnit MaxPreferredLogicalWidth() const override;
+ // This function calculates the preferred widths for an object.
+ //
+ // See INTRINSIC SIZES / PREFERRED LOGICAL WIDTHS in layout_object.h for more
+ // details about those widths.
+ MinMaxSizes PreferredLogicalWidths() const override;
LayoutUnit OverrideLogicalHeight() const;
LayoutUnit OverrideLogicalWidth() const;
@@ -941,17 +955,27 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
void SetInlineBoxWrapper(InlineBox*);
void DeleteLineBoxWrapper();
+ bool HasInlineFragments() const final;
NGPaintFragment* FirstInlineFragment() const final;
void SetFirstInlineFragment(NGPaintFragment*) final;
wtf_size_t FirstInlineFragmentItemIndex() const final;
void ClearFirstInlineFragmentItemIndex() final;
void SetFirstInlineFragmentItemIndex(wtf_size_t) final;
- void SetCachedLayoutResult(const NGLayoutResult&, const NGBreakToken*);
- void ClearCachedLayoutResult();
- const NGLayoutResult* GetCachedLayoutResult() const {
- return cached_layout_result_.get();
- }
+ void InvalidateItems(const NGLayoutResult&);
+
+ void SetCachedLayoutResult(scoped_refptr<const NGLayoutResult>);
+
+ // Store one layout result (with its physical fragment) at the specified
+ // index, and delete all entries following it.
+ void AddLayoutResult(scoped_refptr<const NGLayoutResult>, wtf_size_t index);
+
+ void ShrinkLayoutResults(wtf_size_t results_to_keep);
+ void ClearLayoutResults();
+
+ const NGLayoutResult* GetCachedLayoutResult() const;
+ const NGLayoutResult* GetCachedMeasureResult() const;
+
// Returns the last layout result for this block flow with the given
// constraint space and break token, or null if it is not up-to-date or
// otherwise unavailable.
@@ -969,6 +993,11 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
base::Optional<NGFragmentGeometry>* initial_fragment_geometry,
NGLayoutCacheStatus* out_cache_status);
+ const NGPhysicalBoxFragment* GetPhysicalFragment(wtf_size_t i) const;
+ const FragmentData* FragmentDataFromPhysicalFragment(
+ const NGPhysicalBoxFragment&) const;
+ wtf_size_t PhysicalFragmentCount() const { return layout_results_.size(); }
+
void SetSpannerPlaceholder(LayoutMultiColumnSpannerPlaceholder&);
void ClearSpannerPlaceholder();
LayoutMultiColumnSpannerPlaceholder* SpannerPlaceholder() const final {
@@ -1018,7 +1047,6 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
// value of the previous in-flow sibling.
bool NeedsForcedBreakBefore(EBreakBetween previous_break_after_value) const;
- bool PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const override;
bool MapToVisualRectInAncestorSpaceInternal(
const LayoutBoxModelObject* ancestor,
TransformState&,
@@ -1076,6 +1104,7 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
LayoutUnit ShrinkLogicalWidthToAvoidFloats(LayoutUnit child_margin_start,
LayoutUnit child_margin_end,
const LayoutBlockFlow* cb) const;
+ bool AutoWidthShouldFitContent() const;
LayoutUnit ComputeLogicalWidthUsing(
SizeType,
@@ -1166,8 +1195,6 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
const FloatPoint& point_in_root_frame) const;
static LayoutBox* FindAutoscrollable(LayoutObject*,
bool is_middle_click_autoscroll);
- virtual void StopAutoscroll() {}
- virtual void MayUpdateHoverWhenContentUnderMouseChanged(EventHandler&);
DISABLE_CFI_PERF bool HasAutoVerticalScrollbar() const {
return HasOverflowClip() && StyleRef().HasAutoVerticalScroll();
@@ -1315,6 +1342,8 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
bool IsGridItem() const { return Parent() && Parent()->IsLayoutGrid(); }
+ bool IsMathItem() const { return Parent() && Parent()->IsMathML(); }
+
LayoutUnit LineHeight(
bool first_line,
LineDirectionMode,
@@ -1501,6 +1530,12 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
const HitTestLocation&,
const PhysicalOffset& border_box_location) const;
+ virtual bool HitTestOverflowControl(HitTestResult&,
+ const HitTestLocation&,
+ const PhysicalOffset&) const {
+ return false;
+ }
+
// Returns true if the box intersects the viewport visible to the user.
bool IntersectsVisibleViewport() const;
@@ -1508,7 +1543,7 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
void EnsureIsReadyForPaintInvalidation() override;
- virtual bool HasControlClip() const { return false; }
+ bool HasControlClip() const;
class MutableForPainting : public LayoutObject::MutableForPainting {
public:
@@ -1553,46 +1588,53 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
: PhysicalRect(PhysicalOffset(), PreviousSize());
}
- // This function calculates the preferred widths for an object.
+ // Calculates the intrinsic logical widths for this layout box.
+ // https://drafts.csswg.org/css-sizing-3/#intrinsic
//
- // This function is only expected to be called if
- // the boolean preferredLogicalWidthsDirty is true. It also MUST clear the
- // boolean before returning.
+ // intrinsicWidth is defined as:
+ // intrinsic size of content (with our border and padding) +
+ // scrollbarWidth.
//
- // See INTRINSIC SIZES / PREFERRED LOGICAL WIDTHS in layout_object.h for more
- // details about those widths.
+ // preferredWidth is defined as:
+ // fixedWidth OR (intrinsicWidth plus border and padding).
+ // Note: fixedWidth includes border and padding and scrollbarWidth.
//
- // This function is public only for use by LayoutNG. Other callers should go
- // through MinPreferredLogicalWidth/MaxPreferredLogicalWidth.
- virtual void ComputePreferredLogicalWidths() {
- ClearPreferredLogicalWidthsDirty();
+ // This is public only for use by LayoutNG. Do not call this elsewhere.
+ virtual MinMaxSizes ComputeIntrinsicLogicalWidths() const = 0;
+
+ // Returns the (maybe cached) intrinsic logical widths for this layout box.
+ MinMaxSizes IntrinsicLogicalWidths() const {
+ const_cast<LayoutBox*>(this)->UpdateCachedIntrinsicLogicalWidthsIfNeeded();
+ return intrinsic_logical_widths_;
}
- // LayoutNG can use this function to update our cache of preferred logical
+ // If |IntrinsicLogicalWidthsDirty()| is true, recalculates the intrinsic
+ // logical widths.
+ void UpdateCachedIntrinsicLogicalWidthsIfNeeded();
+
+ // LayoutNG can use this function to update our cache of intrinsic logical
// widths when the layout object is managed by NG. Should not be called by
// regular code.
- // Also clears the "dirty" flag for preferred widths.
- void SetPreferredLogicalWidthsFromNG(MinMaxSize sizes) {
- min_preferred_logical_width_ = sizes.min_size;
- max_preferred_logical_width_ = sizes.max_size;
- ClearPreferredLogicalWidthsDirty();
+ //
+ // Also clears the "dirty" flag for the intrinsic logical widths.
+ void SetIntrinsicLogicalWidthsFromNG(
+ const MinMaxSizes& sizes,
+ LayoutUnit intrinsic_logical_widths_percentage_resolution_block_size) {
+ intrinsic_logical_widths_ = sizes;
+ intrinsic_logical_widths_percentage_resolution_block_size_ =
+ intrinsic_logical_widths_percentage_resolution_block_size;
+
+ ClearIntrinsicLogicalWidthsDirty();
}
- // Calculates the intrinsic(https://drafts.csswg.org/css-sizing-3/#intrinsic)
- // logical widths for this layout box.
- //
- // intrinsicWidth is defined as:
- // intrinsic size of content (without our border and padding) +
- // scrollbarWidth.
- //
- // preferredWidth is defined as:
- // fixedWidth OR (intrinsicWidth plus border and padding).
- // Note: fixedWidth includes border and padding and scrollbarWidth.
+ // Returns what %-resolution-block-size was used in the intrinsic logical
+ // widths phase.
//
- // This is public only for use by LayoutNG. Do not call this elsewhere.
- virtual void ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const;
+ // For non-LayoutNG code this is always LayoutUnit::Min(), and should not be
+ // used for caching purposes.
+ LayoutUnit IntrinsicLogicalWidthsPercentageResolutionBlockSize() const {
+ return intrinsic_logical_widths_percentage_resolution_block_size_;
+ }
// Make it public.
using LayoutObject::BackgroundIsKnownToBeObscured;
@@ -1601,9 +1643,6 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
~LayoutBox() override;
virtual bool ComputeShouldClipOverflow() const;
- virtual PhysicalRect ControlClipRect(const PhysicalOffset&) const {
- return PhysicalRect();
- }
void WillBeDestroyed() override;
@@ -1636,8 +1675,7 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
LayoutUnit ComputeIntrinsicLogicalWidthUsing(
const Length& logical_width_length,
- LayoutUnit available_logical_width,
- LayoutUnit border_and_padding) const;
+ LayoutUnit available_logical_width) const;
LayoutUnit ComputeIntrinsicLogicalContentHeightUsing(
const Length& logical_height_length,
LayoutUnit intrinsic_content_height,
@@ -1645,11 +1683,6 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
LayoutObject* SplitAnonymousBoxesAroundChild(LayoutObject* before_child);
- virtual bool HitTestOverflowControl(HitTestResult&,
- const HitTestLocation&,
- const PhysicalOffset&) {
- return false;
- }
virtual bool HitTestChildren(HitTestResult&,
const HitTestLocation&,
const PhysicalOffset& accumulated_offset,
@@ -1726,7 +1759,6 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
void ClearScrollSnapMapping();
void AddScrollSnapMapping();
- bool AutoWidthShouldFitContent() const;
LayoutUnit ShrinkToFitLogicalWidth(LayoutUnit available_logical_width,
LayoutUnit borders_plus_padding) const;
@@ -1766,8 +1798,8 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
LayoutBoxRareData& EnsureRareData() {
if (!rare_data_)
- rare_data_ = std::make_unique<LayoutBoxRareData>();
- return *rare_data_.get();
+ rare_data_ = MakeGarbageCollected<LayoutBoxRareData>();
+ return *rare_data_.Get();
}
bool LogicalHeightComputesAsNone(SizeType) const;
@@ -1794,7 +1826,7 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
// Returns true when the current recursive scroll into visible could propagate
// to parent frame.
bool AllowedToPropagateRecursiveScrollToParentFrame(
- const WebScrollIntoViewParams&);
+ const mojom::blink::ScrollIntoViewParamsPtr&);
PhysicalRect DebugRect() const override;
@@ -1845,16 +1877,8 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
mutable LayoutUnit intrinsic_content_logical_height_;
protected:
- // The logical width of the element if it were to break its lines at every
- // possible opportunity.
- //
- // See LayoutObject::minPreferredLogicalWidth() for more details.
- LayoutUnit min_preferred_logical_width_;
-
- // The logical width of the element if it never breaks any lines at all.
- //
- // See LayoutObject::maxPreferredLogicalWidth() for more details.
- LayoutUnit max_preferred_logical_width_;
+ MinMaxSizes intrinsic_logical_widths_;
+ LayoutUnit intrinsic_logical_widths_percentage_resolution_block_size_;
// LayoutBoxUtils is used for the LayoutNG code querying protected methods on
// this class, e.g. determining the static-position of OOF elements.
@@ -1892,8 +1916,9 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
wtf_size_t first_fragment_item_index_;
};
- std::unique_ptr<LayoutBoxRareData> rare_data_;
- scoped_refptr<const NGLayoutResult> cached_layout_result_;
+ Persistent<LayoutBoxRareData> rare_data_;
+ scoped_refptr<const NGLayoutResult> measure_result_;
+ Vector<scoped_refptr<const NGLayoutResult>, 1> layout_results_;
};
DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutBox, IsBox());
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 21782639cd2..e3b20800d32 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
@@ -29,6 +29,7 @@
#include "third_party/blink/renderer/core/dom/node_computed_style.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"
#include "third_party/blink/renderer/core/html/html_body_element.h"
#include "third_party/blink/renderer/core/layout/geometry/transform_state.h"
#include "third_party/blink/renderer/core/layout/layout_block.h"
@@ -36,6 +37,8 @@
#include "third_party/blink/renderer/core/layout/layout_geometry_map.h"
#include "third_party/blink/renderer/core/layout/layout_inline.h"
#include "third_party/blink/renderer/core/layout/layout_view.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/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/object_paint_invalidator.h"
@@ -85,10 +88,6 @@ void LayoutBoxModelObject::ContentChanged(ContentChangeType change_type) {
Layer()->ContentChanged(change_type);
}
-bool LayoutBoxModelObject::HasAcceleratedCompositing() const {
- return View()->Compositor()->HasAcceleratedCompositing();
-}
-
LayoutBoxModelObject::LayoutBoxModelObject(ContainerNode* node)
: LayoutObject(node) {}
@@ -97,9 +96,10 @@ bool LayoutBoxModelObject::UsesCompositedScrolling() const {
Layer()->GetScrollableArea()->UsesCompositedScrolling();
}
-BackgroundPaintLocation LayoutBoxModelObject::GetBackgroundPaintLocation(
+BackgroundPaintLocation
+LayoutBoxModelObject::ComputeBackgroundPaintLocationIfComposited(
uint32_t* main_thread_scrolling_reasons) const {
- bool may_have_scrolling_layers_without_scrolling = IsLayoutView();
+ bool may_have_scrolling_layers_without_scrolling = IsA<LayoutView>(this);
const auto* scrollable_area = GetScrollableArea();
bool scrolls_overflow = scrollable_area && scrollable_area->ScrollsOverflow();
if (!scrolls_overflow && !may_have_scrolling_layers_without_scrolling)
@@ -108,9 +108,8 @@ BackgroundPaintLocation LayoutBoxModelObject::GetBackgroundPaintLocation(
// If we care about LCD text, paint root backgrounds into scrolling contents
// layer even if style suggests otherwise. (For non-root scrollers, we just
// avoid compositing - see PLSA::ComputeNeedsCompositedScrolling.)
- if (IsLayoutView()) {
- DCHECK(Layer()->Compositor());
- if (!Layer()->Compositor()->PreferCompositingToLCDTextEnabled())
+ if (IsA<LayoutView>(this)) {
+ if (!GetDocument().GetSettings()->GetPreferCompositingToLCDTextEnabled())
return kBackgroundPaintInScrollingContents;
}
@@ -283,13 +282,9 @@ void LayoutBoxModelObject::StyleDidChange(StyleDifference diff,
// block/inline position.
// Position changes and other types of display changes are handled elsewhere.
if (old_style && IsOutOfFlowPositioned() && Parent() &&
- (Parent() != ContainingBlock()) &&
(StyleRef().GetPosition() == old_style->GetPosition()) &&
- (StyleRef().OriginalDisplay() != old_style->OriginalDisplay()) &&
- ((StyleRef().OriginalDisplay() == EDisplay::kBlock) ||
- (StyleRef().OriginalDisplay() == EDisplay::kInlineBlock)) &&
- ((old_style->OriginalDisplay() == EDisplay::kBlock) ||
- (old_style->OriginalDisplay() == EDisplay::kInlineBlock)))
+ (StyleRef().IsOriginalDisplayInlineType() !=
+ old_style->IsOriginalDisplayInlineType()))
Parent()->SetNeedsLayout(layout_invalidation_reason::kChildChanged,
kMarkContainerChain);
@@ -320,7 +315,7 @@ void LayoutBoxModelObject::StyleDidChange(StyleDifference diff,
if (EverHadLayout())
SetChildNeedsLayout();
if (had_transform_related_property) {
- SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kStyleChange);
}
if (!NeedsLayout()) {
@@ -444,7 +439,6 @@ void LayoutBoxModelObject::StyleDidChange(StyleDifference diff,
// Remove sticky constraints for this layer.
if (Layer()) {
- DisableCompositingQueryAsserts disabler;
if (const PaintLayer* ancestor_overflow_layer =
Layer()->AncestorOverflowLayer()) {
if (PaintLayerScrollableArea* scrollable_area =
@@ -519,7 +513,6 @@ void LayoutBoxModelObject::InvalidateStickyConstraints() {
// This intentionally uses the stale ancestor overflow layer compositing input
// as if we have saved constraints for this layer they were saved in the
// previous frame.
- DisableCompositingQueryAsserts disabler;
if (const PaintLayer* ancestor_overflow_layer =
enclosing->AncestorOverflowLayer()) {
if (PaintLayerScrollableArea* ancestor_scrollable_area =
@@ -537,6 +530,8 @@ void LayoutBoxModelObject::CreateLayerAfterStyleChange() {
// Creating a layer may affect existence of the LocalBorderBoxProperties, so
// we need to ensure that we update paint properties.
SetNeedsPaintPropertyUpdate();
+ if (GetScrollableArea())
+ GetScrollableArea()->InvalidateScrollTimeline();
}
void LayoutBoxModelObject::DestroyLayer() {
@@ -546,6 +541,7 @@ void LayoutBoxModelObject::DestroyLayer() {
// Removing a layer may affect existence of the LocalBorderBoxProperties, so
// we need to ensure that we update paint properties.
SetNeedsPaintPropertyUpdate();
+ SetBackgroundPaintLocation(kBackgroundPaintInGraphicsLayer);
}
bool LayoutBoxModelObject::HasSelfPaintingLayer() const {
@@ -679,7 +675,7 @@ LayoutBlock* LayoutBoxModelObject::ContainingBlockForAutoHeightDetection(
// Match LayoutBox::availableLogicalHeightUsing by special casing the layout
// view. The available height is taken from the frame.
- if (cb->IsLayoutView())
+ if (IsA<LayoutView>(cb))
return nullptr;
if (IsOutOfFlowPositionedWithImplicitHeight(cb))
@@ -700,10 +696,17 @@ bool LayoutBoxModelObject::HasAutoHeightOrContainingBlockWithAutoHeight(
logical_height_length.IsPercentOrCalc() && cb && IsBox()) {
cb->AddPercentHeightDescendant(const_cast<LayoutBox*>(ToLayoutBox(this)));
}
- if (this_box && this_box->IsFlexItem()) {
- const LayoutFlexibleBox& flex_box = ToLayoutFlexibleBox(*Parent());
- if (flex_box.UseOverrideLogicalHeightForPerentageResolution(*this_box))
- return false;
+ if (this_box && this_box->IsFlexItemIncludingNG()) {
+ if (this_box->IsFlexItem()) {
+ const LayoutFlexibleBox& flex_box = ToLayoutFlexibleBox(*Parent());
+ if (flex_box.UseOverrideLogicalHeightForPerentageResolution(*this_box))
+ return false;
+ } else if (this_box->GetCachedLayoutResult()) {
+ const NGConstraintSpace& space =
+ this_box->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
+ if (space.IsFixedBlockSize() && !space.IsFixedBlockSizeIndefinite())
+ return false;
+ }
}
if (this_box && this_box->IsGridItem() &&
this_box->HasOverrideContainingBlockContentLogicalHeight())
@@ -722,8 +725,14 @@ bool LayoutBoxModelObject::HasAutoHeightOrContainingBlockWithAutoHeight(
// resolve the block-size of the descendant, except when in quirks mode.
// Flexboxes follow strict behavior even in quirks mode, though.
if (!GetDocument().InQuirksMode() ||
- cb->IsFlexibleBoxIncludingDeprecatedAndNG())
+ cb->IsFlexibleBoxIncludingDeprecatedAndNG()) {
+ if (this_box &&
+ this_box->HasOverrideContainingBlockContentLogicalHeight()) {
+ return this_box->OverrideContainingBlockContentLogicalHeight() ==
+ LayoutUnit(-1);
+ }
return !cb->HasDefiniteLogicalHeight();
+ }
}
return false;
@@ -881,7 +890,7 @@ void LayoutBoxModelObject::UpdateStickyPositionConstraints() const {
ToLayoutBox(Layer()->AncestorOverflowLayer()->GetLayoutObject());
LayoutUnit max_container_width =
- containing_block->IsLayoutView()
+ IsA<LayoutView>(containing_block)
? containing_block->LogicalWidth()
: containing_block->ContainingBlockLogicalWidthForContent();
// Sticky positioned element ignore any override logical width on the
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 40b2a33964e..dd19932660c 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
@@ -185,13 +185,13 @@ class CORE_EXPORT LayoutBoxModelObject : public LayoutObject {
bool UsesCompositedScrolling() const;
- // Returns which layers backgrounds should be painted into for overflow
- // scrolling boxes.
+ // Returns which layers backgrounds should be painted into for a overflow
+ // scrolling box if it uses composited scrolling.
// TODO(yigu): PaintLayerScrollableArea::ComputeNeedsCompositedScrolling
// calls this method to obtain main thread scrolling reasons due to
// background paint location. Once the cases get handled on compositor the
// parameter "reasons" could be removed.
- BackgroundPaintLocation GetBackgroundPaintLocation(
+ BackgroundPaintLocation ComputeBackgroundPaintLocationIfComposited(
uint32_t* main_thread_scrolling_reasons = nullptr) const;
// These return the CSS computed padding values.
@@ -415,7 +415,6 @@ class CORE_EXPORT LayoutBoxModelObject : public LayoutObject {
LayoutGeometryMap&) const override;
void ContentChanged(ContentChangeType);
- bool HasAcceleratedCompositing() const;
// Returns true if the background is painted opaque in the given rect.
// The query rect is given in local coordinate system.
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 b4c95094980..990362b2148 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
@@ -423,7 +423,8 @@ TEST_F(LayoutBoxModelObjectTest, StickyPositionConstraintInvalidation) {
.at(sticky->Layer())
.scroll_container_relative_sticky_box_rect.X());
To<HTMLElement>(target->GetNode())->classList().Add("hide");
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
// Layout should invalidate the sticky constraints of the sticky element and
// mark it as needing a compositing inputs update.
EXPECT_FALSE(
@@ -1075,7 +1076,8 @@ TEST_F(LayoutBoxModelObjectTest, InvalidatePaintLayerOnStackedChange) {
EXPECT_NE(parent, original_compositing_container->GetLayoutObject());
target_element->setAttribute(html_names::kClassAttr, "non-stacked");
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
EXPECT_FALSE(target->StyleRef().IsStacked());
EXPECT_TRUE(target->Layer()->SelfNeedsRepaint());
@@ -1085,7 +1087,8 @@ TEST_F(LayoutBoxModelObjectTest, InvalidatePaintLayerOnStackedChange) {
UpdateAllLifecyclePhasesForTest();
target_element->setAttribute(html_names::kClassAttr, "stacked");
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(target->StyleRef().IsStacked());
EXPECT_TRUE(target->Layer()->SelfNeedsRepaint());
@@ -1156,13 +1159,15 @@ TEST_F(LayoutBoxModelObjectTest, BackfaceVisibilityChange) {
target->setAttribute(html_names::kStyleAttr,
base_style + "; backface-visibility: hidden");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(target_layer->SelfNeedsRepaint());
UpdateAllLifecyclePhasesForTest();
EXPECT_FALSE(target_layer->SelfNeedsRepaint());
target->setAttribute(html_names::kStyleAttr, base_style);
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(target_layer->SelfNeedsRepaint());
UpdateAllLifecyclePhasesForTest();
EXPECT_FALSE(target_layer->SelfNeedsRepaint());
@@ -1216,7 +1221,8 @@ TEST_F(LayoutBoxModelObjectTest,
EXPECT_EQ(target->Layer(), target->Layer()->NearestContainedLayoutLayer());
To<HTMLElement>(target->GetNode())->classList().Remove("contained");
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(target->Layer()->NeedsCompositingInputsUpdate());
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 e298eb904a7..99bcb9ca795 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
@@ -392,12 +392,7 @@ TEST_P(LayoutBoxTest, ControlClip) {
EXPECT_TRUE(target->HasControlClip());
EXPECT_TRUE(target->HasClipRelatedProperty());
EXPECT_TRUE(target->ShouldClipOverflow());
-#if defined(OS_MACOSX)
- EXPECT_EQ(PhysicalRect(0, 0, 100, 18),
- target->ClippingRect(PhysicalOffset()));
-#else
EXPECT_EQ(PhysicalRect(2, 2, 96, 46), target->ClippingRect(PhysicalOffset()));
-#endif
}
TEST_P(LayoutBoxTest, LocalVisualRectWithMask) {
@@ -1436,7 +1431,8 @@ TEST_P(LayoutBoxTest, HasNonCollapsedBorderDecoration) {
To<Element>(div->GetNode())
->setAttribute(html_names::kStyleAttr, "border: 1px solid black");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason ::kTest);
EXPECT_TRUE(div->HasNonCollapsedBorderDecoration());
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_button.cc b/chromium/third_party/blink/renderer/core/layout/layout_button.cc
index c743f0cd09a..28d3a96c0a5 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_button.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_button.cc
@@ -73,14 +73,6 @@ void LayoutButton::UpdateAnonymousChildStyle(const LayoutObject* child,
child_style.SetAlignContent(StyleRef().AlignContent());
}
-PhysicalRect LayoutButton::ControlClipRect(
- const PhysicalOffset& additional_offset) const {
- // Clip to the padding box to at least give content the extra padding space.
- PhysicalRect rect(additional_offset, Size());
- rect.Expand(BorderInsets());
- return rect;
-}
-
LayoutUnit LayoutButton::BaselinePosition(
FontBaseline baseline,
bool first_line,
@@ -106,8 +98,4 @@ LayoutUnit LayoutButton::BaselinePosition(
line_position_mode);
}
-// For compatibility with IE/FF we only clip overflow on input elements.
-bool LayoutButton::HasControlClip() const {
- return !IsA<HTMLButtonElement>(GetNode());
-}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_button.h b/chromium/third_party/blink/renderer/core/layout/layout_button.h
index b9aaedc709e..60ce95bc9a4 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_button.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_button.h
@@ -48,9 +48,6 @@ class LayoutButton final : public LayoutFlexibleBox {
void RemoveLeftoverAnonymousBlock(LayoutBlock*) override {}
bool CreatesAnonymousWrapper() const override { return true; }
- bool HasControlClip() const override;
- PhysicalRect ControlClipRect(const PhysicalOffset&) const override;
-
LayoutUnit BaselinePosition(FontBaseline,
bool first_line,
LineDirectionMode,
@@ -60,10 +57,6 @@ class LayoutButton final : public LayoutFlexibleBox {
void UpdateAnonymousChildStyle(const LayoutObject* child,
ComputedStyle& child_style) const override;
- bool HasLineIfEmpty() const override {
- return IsA<HTMLInputElement>(GetNode());
- }
-
LayoutBlock* inner_;
};
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 d7c8f9d0587..d3a3e1359e0 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_counter.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_counter.cc
@@ -474,23 +474,21 @@ void LayoutCounter::WillBeDestroyed() {
scoped_refptr<StringImpl> LayoutCounter::OriginalText() const {
if (!counter_node_) {
- LayoutObject* before_after_container = Parent();
+ LayoutObject* container = Parent();
while (true) {
- if (!before_after_container)
+ if (!container)
return nullptr;
- if (!before_after_container->IsAnonymous() &&
- !before_after_container->IsPseudoElement())
- return nullptr; // LayoutCounters are restricted to before and after
- // pseudo elements
- PseudoId container_style = before_after_container->StyleRef().StyleType();
+ if (!container->IsAnonymous() && !container->IsPseudoElement())
+ return nullptr; // LayoutCounters are restricted to before, after and
+ // marker pseudo elements
+ PseudoId container_style = container->StyleRef().StyleType();
if ((container_style == kPseudoIdBefore) ||
(container_style == kPseudoIdAfter) ||
(container_style == kPseudoIdMarker))
break;
- before_after_container = before_after_container->Parent();
+ container = container->Parent();
}
- MakeCounterNodeIfNeeded(*before_after_container, counter_.Identifier(),
- true)
+ MakeCounterNodeIfNeeded(*container, counter_.Identifier(), true)
->AddLayoutObject(const_cast<LayoutCounter*>(this));
DCHECK(counter_node_);
}
@@ -522,7 +520,7 @@ void LayoutCounter::Invalidate() {
DCHECK(!counter_node_);
if (DocumentBeingDestroyed())
return;
- SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kCountersChanged);
}
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 92de8406cde..e44c69567e7 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
@@ -141,7 +141,7 @@ int LayoutCustomScrollbarPart::ComputeScrollbarWidth(
int min_width = CalcScrollbarThicknessUsing(kMinSize, style->MinWidth(),
visible_size, theme);
int max_width = w;
- if (!style->MaxWidth().IsMaxSizeNone()) {
+ if (!style->MaxWidth().IsNone()) {
max_width = CalcScrollbarThicknessUsing(kMaxSize, style->MaxWidth(),
visible_size, theme);
}
@@ -158,7 +158,7 @@ int LayoutCustomScrollbarPart::ComputeScrollbarHeight(
int min_height = CalcScrollbarThicknessUsing(kMinSize, style->MinHeight(),
visible_size, theme);
int max_height = h;
- if (!style->MaxHeight().IsMaxSizeNone()) {
+ if (!style->MaxHeight().IsNone()) {
max_height = CalcScrollbarThicknessUsing(kMaxSize, style->MaxHeight(),
visible_size, theme);
}
@@ -211,13 +211,8 @@ void LayoutCustomScrollbarPart::UpdateScrollbarHeight() {
.Round()));
}
-void LayoutCustomScrollbarPart::ComputePreferredLogicalWidths() {
- if (!PreferredLogicalWidthsDirty())
- return;
-
- min_preferred_logical_width_ = max_preferred_logical_width_ = LayoutUnit();
-
- ClearPreferredLogicalWidthsDirty();
+MinMaxSizes LayoutCustomScrollbarPart::PreferredLogicalWidths() const {
+ return MinMaxSizes();
}
void LayoutCustomScrollbarPart::StyleWillChange(
@@ -235,7 +230,7 @@ void LayoutCustomScrollbarPart::StyleDidChange(StyleDifference diff,
SetInline(false);
ClearPositionedState();
SetFloating(false);
- if (old_style && (diff.NeedsFullPaintInvalidation() || diff.NeedsLayout()))
+ if (old_style && (diff.NeedsPaintInvalidation() || diff.NeedsLayout()))
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 c6848666b51..dd1f0caf2cd 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
@@ -83,7 +83,7 @@ class LayoutCustomScrollbarPart final : public LayoutBlock {
private:
LayoutCustomScrollbarPart(ScrollableArea*, CustomScrollbar*, ScrollbarPart);
- void ComputePreferredLogicalWidths() override;
+ MinMaxSizes PreferredLogicalWidths() const override;
// Have all padding getters return 0. The important point here is to avoid
// resolving percents against the containing block, since scroll bar corners
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.cc b/chromium/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.cc
index 3dbbe77bdda..8a44c7f8c14 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.cc
@@ -43,11 +43,7 @@ class FlexBoxIterator {
public:
FlexBoxIterator(LayoutDeprecatedFlexibleBox* parent)
: box_(parent), largest_ordinal_(1) {
- if (box_->StyleRef().BoxOrient() == EBoxOrient::kHorizontal &&
- !box_->StyleRef().IsLeftToRightDirection())
- forward_ = box_->StyleRef().BoxDirection() != EBoxDirection::kNormal;
- else
- forward_ = box_->StyleRef().BoxDirection() == EBoxDirection::kNormal;
+ forward_ = box_->StyleRef().BoxDirection() == EBoxDirection::kNormal;
if (!forward_) {
// No choice, since we're going backwards, we have to find out the highest
// ordinal up front.
@@ -271,10 +267,9 @@ static void ClearTruncation(LayoutBlockFlow* block_flow) {
}
}
-LayoutDeprecatedFlexibleBox::LayoutDeprecatedFlexibleBox(Element& element)
- : LayoutBlock(&element) {
+LayoutDeprecatedFlexibleBox::LayoutDeprecatedFlexibleBox(Element* element)
+ : LayoutBlock(element) {
DCHECK(!ChildrenInline());
- stretching_children_ = false;
if (!IsAnonymous()) {
const KURL& url = GetDocument().Url();
if (url.ProtocolIs("chrome")) {
@@ -305,18 +300,6 @@ static LayoutUnit MarginWidthForChild(LayoutBox* child) {
return margin;
}
-static LayoutUnit WidthForChild(LayoutBox* child) {
- if (child->HasOverrideLogicalWidth())
- return child->OverrideLogicalWidth();
- return child->LogicalWidth();
-}
-
-static LayoutUnit ContentWidthForChild(LayoutBox* child) {
- // TODO(rego): Shouldn't we subtract the scrollbar width too?
- return (WidthForChild(child) - child->BorderAndPaddingLogicalWidth())
- .ClampNegativeToZero();
-}
-
static LayoutUnit HeightForChild(LayoutBox* child) {
if (child->HasOverrideLogicalHeight())
return child->OverrideLogicalHeight();
@@ -339,43 +322,27 @@ void LayoutDeprecatedFlexibleBox::StyleWillChange(
LayoutBlock::StyleWillChange(diff, new_style);
}
-void LayoutDeprecatedFlexibleBox::ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const {
- if (IsVertical()) {
- for (LayoutBox* child = FirstChildBox(); child;
- child = child->NextSiblingBox()) {
- if (child->IsOutOfFlowPositioned())
- continue;
-
- LayoutUnit margin = MarginWidthForChild(child);
- LayoutUnit width = child->MinPreferredLogicalWidth() + margin;
- min_logical_width = std::max(width, min_logical_width);
+MinMaxSizes LayoutDeprecatedFlexibleBox::ComputeIntrinsicLogicalWidths() const {
+ MinMaxSizes sizes;
+ for (LayoutBox* child = FirstChildBox(); child;
+ child = child->NextSiblingBox()) {
+ if (child->IsOutOfFlowPositioned())
+ continue;
- width = child->MaxPreferredLogicalWidth() + margin;
- max_logical_width = std::max(width, max_logical_width);
- }
- } else {
- for (LayoutBox* child = FirstChildBox(); child;
- child = child->NextSiblingBox()) {
- if (child->IsOutOfFlowPositioned())
- continue;
+ MinMaxSizes child_sizes = child->PreferredLogicalWidths();
+ child_sizes += MarginWidthForChild(child);
- LayoutUnit margin = MarginWidthForChild(child);
- min_logical_width += child->MinPreferredLogicalWidth() + margin;
- max_logical_width += child->MaxPreferredLogicalWidth() + margin;
- }
+ sizes.Encompass(child_sizes);
}
- max_logical_width = std::max(min_logical_width, max_logical_width);
-
- LayoutUnit scrollbar_width(ScrollbarLogicalWidth());
- max_logical_width += scrollbar_width;
- min_logical_width += scrollbar_width;
+ sizes.max_size = std::max(sizes.min_size, sizes.max_size);
+ sizes += BorderAndPaddingLogicalWidth() + ScrollbarLogicalWidth();
+ return sizes;
}
void LayoutDeprecatedFlexibleBox::UpdateBlockLayout(bool relayout_children) {
DCHECK(NeedsLayout());
+ DCHECK_EQ(StyleRef().BoxOrient(), EBoxOrient::kVertical);
UseCounter::Count(GetDocument(), WebFeature::kWebkitBoxLayout);
@@ -417,23 +384,13 @@ void LayoutDeprecatedFlexibleBox::UpdateBlockLayout(bool relayout_children) {
TextAutosizer::LayoutScope text_autosizer_layout_scope(this);
- if (previous_size != Size() ||
- (Parent()->StyleRef().IsDeprecatedWebkitBox() &&
- Parent()->StyleRef().BoxOrient() == EBoxOrient::kHorizontal &&
- Parent()->StyleRef().BoxAlign() == EBoxAlignment::kStretch))
+ if (previous_size != Size())
relayout_children = true;
SetHeight(LayoutUnit());
- stretching_children_ = false;
-
- if (IsHorizontal()) {
- UseCounter::Count(GetDocument(), WebFeature::kWebkitBoxLayoutHorizontal);
- LayoutHorizontalBox(relayout_children);
- } else {
- UseCounter::Count(GetDocument(), WebFeature::kWebkitBoxLayoutVertical);
- LayoutVerticalBox(relayout_children);
- }
+ UseCounter::Count(GetDocument(), WebFeature::kWebkitBoxLayoutVertical);
+ LayoutVerticalBox(relayout_children);
LayoutUnit old_client_after_edge = ClientLogicalBottom();
UpdateLogicalHeight();
@@ -480,322 +437,6 @@ static void GatherFlexChildrenInfo(FlexBoxIterator& iterator,
}
}
-void LayoutDeprecatedFlexibleBox::LayoutHorizontalBox(bool relayout_children) {
- LayoutUnit to_add =
- BorderBottom() + PaddingBottom() + HorizontalScrollbarHeight();
- LayoutUnit y_pos = BorderTop() + PaddingTop();
- LayoutUnit x_pos = BorderLeft() + PaddingLeft();
- bool height_specified = false;
- bool paginated = View()->GetLayoutState()->IsPaginated();
- LayoutUnit old_height;
-
- LayoutUnit remaining_space;
-
- FlexBoxIterator iterator(this);
- bool have_flex = false, flexing_children = false;
- GatherFlexChildrenInfo(iterator, GetDocument(), relayout_children, have_flex);
-
- PaintLayerScrollableArea::DelayScrollOffsetClampScope delay_clamp_scope;
-
- // We do 2 passes. The first pass is simply to lay everyone out at
- // their preferred widths. The second pass handles flexing the children.
- do {
- // Reset our height.
- SetHeight(y_pos);
-
- x_pos = BorderLeft() + PaddingLeft();
-
- // Our first pass is done without flexing. We simply lay the children
- // out within the box. We have to do a layout first in order to determine
- // our box's intrinsic height.
- LayoutUnit max_ascent;
- LayoutUnit max_descent;
- for (LayoutBox* child = iterator.First(); child; child = iterator.Next()) {
- if (child->IsOutOfFlowPositioned())
- continue;
-
- SubtreeLayoutScope layout_scope(*child);
- // TODO(jchaffraix): It seems incorrect to check isAtomicInlineLevel in
- // this file.
- // We probably want to check if the element is replaced.
- if (relayout_children || (child->IsAtomicInlineLevel() &&
- (child->StyleRef().Width().IsPercentOrCalc() ||
- child->StyleRef().Height().IsPercentOrCalc())))
- layout_scope.SetChildNeedsLayout(child);
-
- // Compute the child's vertical margins.
- child->ComputeAndSetBlockDirectionMargins(this);
-
- if (!child->NeedsLayout())
- MarkChildForPaginationRelayoutIfNeeded(*child, layout_scope);
-
- // Now do the layout.
- child->LayoutIfNeeded();
-
- // Update our height and overflow height.
- if (StyleRef().BoxAlign() == EBoxAlignment::kBaseline) {
- LayoutUnit ascent(child->FirstLineBoxBaseline());
- if (ascent == -1)
- ascent = child->Size().Height() + child->MarginBottom();
- ascent += child->MarginTop();
- LayoutUnit descent =
- (child->Size().Height() + child->MarginHeight()) - ascent;
-
- // Update our maximum ascent.
- max_ascent = std::max(max_ascent, ascent);
-
- // Update our maximum descent.
- max_descent = std::max(max_descent, descent);
-
- // Now update our height.
- SetHeight(std::max(y_pos + max_ascent + max_descent, Size().Height()));
- } else {
- SetHeight(std::max(Size().Height(), y_pos + child->Size().Height() +
- child->MarginHeight()));
- }
-
- if (paginated)
- UpdateFragmentationInfoForChild(*child);
- }
-
- if (!iterator.First() && HasLineIfEmpty()) {
- SetHeight(Size().Height() +
- LineHeight(true,
- StyleRef().IsHorizontalWritingMode()
- ? kHorizontalLine
- : kVerticalLine,
- kPositionOfInteriorLineBoxes));
- }
-
- SetHeight(Size().Height() + to_add);
-
- old_height = Size().Height();
- UpdateLogicalHeight();
-
- relayout_children = false;
- if (old_height != Size().Height())
- height_specified = true;
-
- // Now that our height is actually known, we can place our boxes.
- stretching_children_ = (StyleRef().BoxAlign() == EBoxAlignment::kStretch);
- for (LayoutBox* child = iterator.First(); child; child = iterator.Next()) {
- if (child->IsOutOfFlowPositioned()) {
- child->ContainingBlock()->InsertPositionedObject(child);
- PaintLayer* child_layer = child->Layer();
- child_layer->SetStaticInlinePosition(x_pos);
- if (child_layer->StaticBlockPosition() != y_pos) {
- child_layer->SetStaticBlockPosition(y_pos);
- if (child->StyleRef().HasStaticBlockPosition(
- StyleRef().IsHorizontalWritingMode()))
- child->SetChildNeedsLayout(kMarkOnlyThis);
- }
- continue;
- }
-
- SubtreeLayoutScope layout_scope(*child);
-
- // We need to see if this child's height will change, since we make block
- // elements fill the height of a containing box by default. We cannot
- // actually *set* the new height here, though. Need to do that from
- // within layout, or we won't be able to detect the change and duly
- // notify any positioned descendants that are affected by it.
- LayoutUnit old_child_height = child->LogicalHeight();
- LogicalExtentComputedValues computed_values;
- child->ComputeLogicalHeight(child->LogicalHeight(), child->LogicalTop(),
- computed_values);
- LayoutUnit new_child_height = computed_values.extent_;
- if (old_child_height != new_child_height)
- layout_scope.SetChildNeedsLayout(child);
-
- if (!child->NeedsLayout())
- MarkChildForPaginationRelayoutIfNeeded(*child, layout_scope);
-
- child->LayoutIfNeeded();
-
- // We can place the child now, using our value of box-align.
- x_pos += child->MarginLeft();
- LayoutUnit child_y = y_pos;
- switch (StyleRef().BoxAlign()) {
- case EBoxAlignment::kCenter:
- child_y += child->MarginTop() +
- ((ContentHeight() -
- (child->Size().Height() + child->MarginHeight())) /
- 2)
- .ClampNegativeToZero();
- break;
- case EBoxAlignment::kBaseline: {
- LayoutUnit ascent(child->FirstLineBoxBaseline());
- if (ascent == -1)
- ascent = child->Size().Height() + child->MarginBottom();
- ascent += child->MarginTop();
- child_y += child->MarginTop() + (max_ascent - ascent);
- break;
- }
- case EBoxAlignment::kEnd:
- child_y +=
- ContentHeight() - child->MarginBottom() - child->Size().Height();
- break;
- default: // BSTART
- child_y += child->MarginTop();
- break;
- }
-
- PlaceChild(child, LayoutPoint(x_pos, child_y));
-
- x_pos += child->Size().Width() + child->MarginRight();
- }
-
- remaining_space = Size().Width() - BorderRight() - PaddingRight() -
- VerticalScrollbarWidth() - x_pos;
-
- stretching_children_ = false;
- if (flexing_children) {
- have_flex = false; // We're done.
- } else if (have_flex) {
- // We have some flexible objects. See if we need to grow/shrink them at
- // all.
- if (!remaining_space)
- break;
-
- // Allocate the remaining space among the flexible objects.
- bool expanding = remaining_space > 0;
- do {
- // Flexing consists of multiple passes, since we have to change
- // ratios every time an object hits its max/min-width For a given
- // pass, we always start off by computing the totalFlex of all
- // objects that can grow/shrink at all, and computing the allowed
- // growth before an object hits its min/max width (and thus forces a
- // totalFlex recomputation).
- LayoutUnit remaining_space_at_beginning = remaining_space;
- float total_flex = 0.0f;
- for (LayoutBox* child = iterator.First(); child;
- child = iterator.Next()) {
- if (AllowedChildFlex(child, expanding))
- total_flex += child->StyleRef().BoxFlex();
- }
- LayoutUnit space_available_this_pass = remaining_space;
- for (LayoutBox* child = iterator.First(); child;
- child = iterator.Next()) {
- LayoutUnit allowed_flex = AllowedChildFlex(child, expanding);
- if (allowed_flex) {
- LayoutUnit projected_flex =
- (allowed_flex == LayoutUnit::Max())
- ? allowed_flex
- : LayoutUnit(allowed_flex *
- (total_flex / child->StyleRef().BoxFlex()));
- space_available_this_pass =
- expanding ? std::min(space_available_this_pass, projected_flex)
- : std::max(space_available_this_pass, projected_flex);
- }
- }
-
- // If we can't grow/shrink anymore, break.
- if (!space_available_this_pass || total_flex == 0.0f)
- break;
-
- // Now distribute the space to objects.
- for (LayoutBox* child = iterator.First();
- child && space_available_this_pass && total_flex;
- child = iterator.Next()) {
- if (AllowedChildFlex(child, expanding)) {
- LayoutUnit space_add =
- LayoutUnit(space_available_this_pass *
- (child->StyleRef().BoxFlex() / total_flex));
- if (space_add) {
- child->SetOverrideLogicalWidth(WidthForChild(child) + space_add);
- flexing_children = true;
- relayout_children = true;
- }
-
- space_available_this_pass -= space_add;
- remaining_space -= space_add;
-
- total_flex -= child->StyleRef().BoxFlex();
- }
- }
- if (remaining_space == remaining_space_at_beginning) {
- // This is not advancing, avoid getting stuck by distributing the
- // remaining pixels.
- LayoutUnit space_add = LayoutUnit(remaining_space > 0 ? 1 : -1);
- for (LayoutBox* child = iterator.First(); child && remaining_space;
- child = iterator.Next()) {
- if (AllowedChildFlex(child, expanding)) {
- child->SetOverrideLogicalWidth(WidthForChild(child) + space_add);
- flexing_children = true;
- relayout_children = true;
- remaining_space -= space_add;
- }
- }
- }
- } while (AbsoluteValue(remaining_space) >= 1);
-
- // We didn't find any children that could grow.
- if (have_flex && !flexing_children)
- have_flex = false;
- }
- } while (have_flex);
-
- if (remaining_space > 0 && ((StyleRef().IsLeftToRightDirection() &&
- StyleRef().BoxPack() != EBoxPack::kStart) ||
- (!StyleRef().IsLeftToRightDirection() &&
- StyleRef().BoxPack() != EBoxPack::kEnd))) {
- // Children must be repositioned.
- LayoutUnit offset;
- if (StyleRef().BoxPack() == EBoxPack::kJustify) {
- // Determine the total number of children.
- int total_children = 0;
- for (LayoutBox* child = iterator.First(); child;
- child = iterator.Next()) {
- if (child->IsOutOfFlowPositioned())
- continue;
- ++total_children;
- }
-
- // Iterate over the children and space them out according to the
- // justification level.
- if (total_children > 1) {
- --total_children;
- bool first_child = true;
- for (LayoutBox* child = iterator.First(); child;
- child = iterator.Next()) {
- if (child->IsOutOfFlowPositioned())
- continue;
-
- if (first_child) {
- first_child = false;
- continue;
- }
-
- offset += remaining_space / total_children;
- remaining_space -= (remaining_space / total_children);
- --total_children;
-
- PlaceChild(child,
- child->Location() + LayoutSize(offset, LayoutUnit()));
- }
- }
- } else {
- if (StyleRef().BoxPack() == EBoxPack::kCenter)
- offset += remaining_space / 2;
- else // END for LTR, START for RTL
- offset += remaining_space;
- for (LayoutBox* child = iterator.First(); child;
- child = iterator.Next()) {
- if (child->IsOutOfFlowPositioned())
- continue;
-
- PlaceChild(child, child->Location() + LayoutSize(offset, LayoutUnit()));
- }
- }
- }
-
- // So that the computeLogicalHeight in layoutBlock() knows to relayout
- // positioned objects because of a height change, we revert our height back
- // to the intrinsic height before returning.
- if (height_specified)
- SetHeight(old_height);
-}
-
void LayoutDeprecatedFlexibleBox::LayoutVerticalBox(bool relayout_children) {
LayoutUnit y_pos = BorderTop() + PaddingTop();
LayoutUnit to_add =
@@ -1021,6 +662,8 @@ void LayoutDeprecatedFlexibleBox::LayoutVerticalBox(bool relayout_children) {
// Children must be repositioned.
LayoutUnit offset;
if (StyleRef().BoxPack() == EBoxPack::kJustify) {
+ UseCounter::Count(GetDocument(),
+ WebFeature::kWebkitBoxPackJustifyDoesSomething);
// Determine the total number of children.
int total_children = 0;
for (LayoutBox* child = iterator.First(); child;
@@ -1054,10 +697,15 @@ void LayoutDeprecatedFlexibleBox::LayoutVerticalBox(bool relayout_children) {
}
}
} else {
- if (StyleRef().BoxPack() == EBoxPack::kCenter)
+ if (StyleRef().BoxPack() == EBoxPack::kCenter) {
+ UseCounter::Count(GetDocument(),
+ WebFeature::kWebkitBoxPackCenterDoesSomething);
offset += remaining_space / 2;
- else // END
+ } else { // END
+ UseCounter::Count(GetDocument(),
+ WebFeature::kWebkitBoxPackEndDoesSomething);
offset += remaining_space;
+ }
for (LayoutBox* child = iterator.First(); child;
child = iterator.Next()) {
if (child->IsOutOfFlowPositioned())
@@ -1248,16 +896,6 @@ LayoutUnit LayoutDeprecatedFlexibleBox::AllowedChildFlex(LayoutBox* child,
return LayoutUnit();
if (expanding) {
- if (IsHorizontal()) {
- // FIXME: For now just handle fixed values.
- LayoutUnit max_width = LayoutUnit::Max();
- LayoutUnit width = ContentWidthForChild(child);
- if (child->StyleRef().MaxWidth().IsFixed())
- max_width = LayoutUnit(child->StyleRef().MaxWidth().Value());
- if (max_width == LayoutUnit::Max())
- return max_width;
- return (max_width - width).ClampNegativeToZero();
- }
// FIXME: For now just handle fixed values.
LayoutUnit max_height = LayoutUnit::Max();
LayoutUnit height = ContentHeightForChild(child);
@@ -1269,18 +907,6 @@ LayoutUnit LayoutDeprecatedFlexibleBox::AllowedChildFlex(LayoutBox* child,
}
// FIXME: For now just handle fixed values.
- if (IsHorizontal()) {
- LayoutUnit min_width = child->MinPreferredLogicalWidth();
- LayoutUnit width = ContentWidthForChild(child);
- const Length& min_width_length = child->StyleRef().MinWidth();
- if (min_width_length.IsFixed())
- min_width = LayoutUnit(min_width_length.Value());
- else if (min_width_length.IsAuto())
- min_width = LayoutUnit();
-
- LayoutUnit allowed_shrinkage = (min_width - width).ClampPositiveToZero();
- return allowed_shrinkage;
- }
const Length& min_height_length = child->StyleRef().MinHeight();
if (min_height_length.IsFixed() || min_height_length.IsAuto()) {
LayoutUnit min_height(min_height_length.Value());
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.h b/chromium/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.h
index d05ba26dc16..4ee630f91b7 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.h
@@ -33,7 +33,7 @@ class FlexBoxIterator;
// eventually be replaced by LayoutFlexibleBox.
class LayoutDeprecatedFlexibleBox final : public LayoutBlock {
public:
- LayoutDeprecatedFlexibleBox(Element&);
+ LayoutDeprecatedFlexibleBox(Element* element);
~LayoutDeprecatedFlexibleBox() override;
const char* GetName() const override { return "LayoutDeprecatedFlexibleBox"; }
@@ -42,38 +42,22 @@ class LayoutDeprecatedFlexibleBox final : public LayoutBlock {
const ComputedStyle& new_style) override;
void UpdateBlockLayout(bool relayout_children) override;
- void LayoutHorizontalBox(bool relayout_children);
void LayoutVerticalBox(bool relayout_children);
bool IsDeprecatedFlexibleBox() const override { return true; }
bool IsFlexibleBoxIncludingDeprecatedAndNG() const override { return true; }
- bool IsStretchingChildren() const { return stretching_children_; }
void PlaceChild(LayoutBox* child, const LayoutPoint& location);
private:
- void ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const override;
+ MinMaxSizes ComputeIntrinsicLogicalWidths() const override;
LayoutUnit AllowedChildFlex(LayoutBox* child, bool expanding);
- bool IsVertical() const {
- return StyleRef().BoxOrient() == EBoxOrient::kVertical;
- }
- bool IsHorizontal() const {
- return StyleRef().BoxOrient() == EBoxOrient::kHorizontal;
- }
-
void ApplyLineClamp(FlexBoxIterator&, bool relayout_children);
void ClearLineClamp();
-
- bool stretching_children_;
};
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutDeprecatedFlexibleBox,
- IsDeprecatedFlexibleBox());
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_DEPRECATED_FLEXIBLE_BOX_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_details_marker.h b/chromium/third_party/blink/renderer/core/layout/layout_details_marker.h
index 087b367b199..a2efcbffdfa 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_details_marker.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_details_marker.h
@@ -41,9 +41,6 @@ class LayoutDetailsMarker final : public LayoutBlockFlow {
LayoutBlockFlow::IsOfType(type);
}
void Paint(const PaintInfo&) const override;
- bool PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const override {
- return false;
- }
bool IsOpen() const;
};
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 f768337c124..41b92eaa2eb 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
@@ -24,6 +24,7 @@
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
#include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h"
#include "third_party/blink/renderer/core/frame/embedded_content_view.h"
@@ -68,8 +69,7 @@ void LayoutEmbeddedContent::WillBeDestroyed() {
LayoutReplaced::WillBeDestroyed();
}
-void LayoutEmbeddedContent::Destroy() {
- WillBeDestroyed();
+void LayoutEmbeddedContent::DeleteThis() {
// We call clearNode here because LayoutEmbeddedContent is ref counted. This
// call to destroy may not actually destroy the layout object. We can keep it
// around because of references from the LocalFrameView class. (The actual
@@ -95,7 +95,7 @@ FrameView* LayoutEmbeddedContent::ChildFrameView() const {
WebPluginContainerImpl* LayoutEmbeddedContent::Plugin() const {
EmbeddedContentView* embedded_content_view = GetEmbeddedContentView();
if (embedded_content_view && embedded_content_view->IsPluginView())
- return ToWebPluginContainerImpl(embedded_content_view);
+ return To<WebPluginContainerImpl>(embedded_content_view);
return nullptr;
}
@@ -128,8 +128,15 @@ bool LayoutEmbeddedContent::RequiresAcceleratedCompositing() const {
if (!element)
return false;
- if (element->ContentFrame() && element->ContentFrame()->IsRemoteFrame())
- return true;
+ if (Frame* content_frame = element->ContentFrame()) {
+ if (content_frame->IsRemoteFrame())
+ return true;
+ if (base::FeatureList::IsEnabled(
+ blink::features::kCompositeCrossOriginIframes) &&
+ content_frame->IsCrossOriginToParentFrame()) {
+ return true;
+ }
+ }
if (Document* content_document = element->contentDocument()) {
auto* layout_view = content_document->GetLayoutView();
@@ -302,7 +309,7 @@ void LayoutEmbeddedContent::InvalidatePaint(
}
CursorDirective LayoutEmbeddedContent::GetCursor(const PhysicalOffset& point,
- Cursor& cursor) const {
+ ui::Cursor& cursor) const {
if (Plugin()) {
// A plugin is responsible for setting the cursor when the pointer is over
// it.
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 cde0a2f09aa..ce5d1ef6a97 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
@@ -27,6 +27,10 @@
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
#include "third_party/blink/renderer/core/layout/layout_replaced.h"
+namespace ui {
+class Cursor;
+}
+
namespace blink {
class EmbeddedContentView;
@@ -75,15 +79,16 @@ class CORE_EXPORT LayoutEmbeddedContent : public LayoutReplaced {
void PaintReplaced(const PaintInfo&,
const PhysicalOffset& paint_offset) const override;
void InvalidatePaint(const PaintInvalidatorContext&) const final;
- CursorDirective GetCursor(const PhysicalOffset&, Cursor&) const final;
+ CursorDirective GetCursor(const PhysicalOffset&, ui::Cursor&) const final;
bool CanBeSelectionLeafInternal() const final { return true; }
private:
+ bool CanHaveAdditionalCompositingReasons() const override { return true; }
CompositingReasons AdditionalCompositingReasons() const override;
void WillBeDestroyed() final;
- void Destroy() final;
+ void DeleteThis() final;
bool NodeAtPointOverEmbeddedContentView(
HitTestResult&,
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_fieldset.cc b/chromium/third_party/blink/renderer/core/layout/layout_fieldset.cc
index eaf12e75073..7fba1ae5141 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_fieldset.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_fieldset.cc
@@ -32,14 +32,14 @@ namespace blink {
LayoutFieldset::LayoutFieldset(Element* element) : LayoutBlockFlow(element) {}
-void LayoutFieldset::ComputePreferredLogicalWidths() {
- LayoutBlockFlow::ComputePreferredLogicalWidths();
+MinMaxSizes LayoutFieldset::PreferredLogicalWidths() const {
+ MinMaxSizes sizes = LayoutBlockFlow::PreferredLogicalWidths();
// Size-contained elements don't consider their contents for preferred sizing.
if (ShouldApplySizeContainment())
- return;
+ return sizes;
if (LayoutBox* legend = FindInFlowLegend()) {
- int legend_min_width = legend->MinPreferredLogicalWidth().ToInt();
+ int legend_min_width = legend->PreferredLogicalWidths().min_size.ToInt();
const Length& legend_margin_left = legend->StyleRef().MarginLeft();
const Length& legend_margin_right = legend->StyleRef().MarginRight();
@@ -50,10 +50,11 @@ void LayoutFieldset::ComputePreferredLogicalWidths() {
if (legend_margin_right.IsFixed())
legend_min_width += legend_margin_right.Value();
- min_preferred_logical_width_ =
- max(min_preferred_logical_width_,
- legend_min_width + BorderAndPaddingWidth());
+ sizes.min_size =
+ max(sizes.min_size, legend_min_width + BorderAndPaddingWidth());
}
+
+ return sizes;
}
LayoutObject* LayoutFieldset::LayoutSpecialExcludedChild(bool relayout_children,
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_fieldset.h b/chromium/third_party/blink/renderer/core/layout/layout_fieldset.h
index 16db91bde89..e5edff116ae 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_fieldset.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_fieldset.h
@@ -49,7 +49,7 @@ class LayoutFieldset final : public LayoutBlockFlow {
LayoutObject* LayoutSpecialExcludedChild(bool relayout_children,
SubtreeLayoutScope&) override;
- void ComputePreferredLogicalWidths() override;
+ MinMaxSizes PreferredLogicalWidths() const override;
void PaintBoxDecorationBackground(
const PaintInfo&,
@@ -58,8 +58,6 @@ class LayoutFieldset final : public LayoutBlockFlow {
const PhysicalOffset& paint_offset) const override;
};
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutFieldset, IsFieldset());
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_FIELDSET_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_file_upload_control.cc b/chromium/third_party/blink/renderer/core/layout/layout_file_upload_control.cc
index 737a0bca9c0..589ba9e2cba 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_file_upload_control.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_file_upload_control.cc
@@ -21,47 +21,35 @@
#include "third_party/blink/renderer/core/layout/layout_file_upload_control.h"
#include <math.h>
-#include "third_party/blink/public/strings/grit/blink_strings.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
-#include "third_party/blink/renderer/core/editing/position_with_affinity.h"
#include "third_party/blink/renderer/core/fileapi/file_list.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/input_type_names.h"
#include "third_party/blink/renderer/core/layout/layout_theme.h"
#include "third_party/blink/renderer/core/paint/file_upload_control_painter.h"
#include "third_party/blink/renderer/platform/fonts/font.h"
-#include "third_party/blink/renderer/platform/text/platform_locale.h"
+#include "third_party/blink/renderer/platform/fonts/string_truncator.h"
#include "third_party/blink/renderer/platform/text/text_run.h"
namespace blink {
-const int kDefaultWidthNumChars = 34;
const int kButtonShadowHeight = 2;
-LayoutFileUploadControl::LayoutFileUploadControl(HTMLInputElement* input)
- : LayoutBlockFlow(input),
- can_receive_dropped_files_(input->CanReceiveDroppedFiles()) {}
+LayoutFileUploadControl::LayoutFileUploadControl(Element* input)
+ : LayoutBlockFlow(input) {
+ DCHECK_EQ(To<HTMLInputElement>(input)->type(), input_type_names::kFile);
+}
LayoutFileUploadControl::~LayoutFileUploadControl() = default;
-void LayoutFileUploadControl::UpdateFromElement() {
- auto* input = To<HTMLInputElement>(GetNode());
- DCHECK_EQ(input->type(), input_type_names::kFile);
-
- if (HTMLInputElement* button = UploadButton()) {
- bool new_can_receive_dropped_files_state = input->CanReceiveDroppedFiles();
- if (can_receive_dropped_files_ != new_can_receive_dropped_files_state) {
- can_receive_dropped_files_ = new_can_receive_dropped_files_state;
- button->SetActive(new_can_receive_dropped_files_state);
- }
- }
-
- // This only supports clearing out the files, but that's OK because for
- // security reasons that's the only change the DOM is allowed to make.
- FileList* files = input->files();
- DCHECK(files);
- if (files && files->IsEmpty())
- SetShouldDoFullPaintInvalidation();
+bool LayoutFileUploadControl::IsChildAllowed(LayoutObject* child,
+ const ComputedStyle& style) const {
+ const Node* child_node = child->GetNode();
+ // Reject shadow nodes other than UploadButton.
+ if (child_node && child_node->OwnerShadowHost() == GetNode() &&
+ child_node != UploadButton())
+ return false;
+ return LayoutBlockFlow::IsChildAllowed(child, style);
}
int LayoutFileUploadControl::MaxFilenameWidth() const {
@@ -79,110 +67,27 @@ void LayoutFileUploadControl::PaintObject(
FileUploadControlPainter(*this).PaintObject(paint_info, paint_offset);
}
-void LayoutFileUploadControl::ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const {
- // Figure out how big the filename space needs to be for a given number of
- // characters (using "0" as the nominal character).
- const UChar kCharacter = '0';
- const String character_as_string = String(&kCharacter, 1);
- const Font& font = StyleRef().GetFont();
- float min_default_label_width =
- kDefaultWidthNumChars *
- font.Width(ConstructTextRun(font, character_as_string, StyleRef(),
- TextRun::kAllowTrailingExpansion));
-
- const String label = To<HTMLInputElement>(GetNode())->GetLocale().QueryString(
- IDS_FORM_FILE_NO_FILE_LABEL);
- float default_label_width = font.Width(ConstructTextRun(
- font, label, StyleRef(), TextRun::kAllowTrailingExpansion));
- if (HTMLInputElement* button = UploadButton()) {
- if (LayoutObject* button_layout_object = button->GetLayoutObject())
- default_label_width += button_layout_object->MaxPreferredLogicalWidth() +
- kAfterButtonSpacing;
- }
- max_logical_width =
- LayoutUnit(ceilf(std::max(min_default_label_width, default_label_width)));
-
- if (!StyleRef().Width().IsPercentOrCalc())
- min_logical_width = max_logical_width;
-}
-
-void LayoutFileUploadControl::ComputePreferredLogicalWidths() {
- DCHECK(PreferredLogicalWidthsDirty());
-
- min_preferred_logical_width_ = LayoutUnit();
- max_preferred_logical_width_ = LayoutUnit();
- const ComputedStyle& style_to_use = StyleRef();
-
- if (style_to_use.Width().IsFixed() && style_to_use.Width().Value() > 0)
- min_preferred_logical_width_ = max_preferred_logical_width_ =
- AdjustContentBoxLogicalWidthForBoxSizing(
- LayoutUnit(style_to_use.Width().Value()));
- else
- ComputeIntrinsicLogicalWidths(min_preferred_logical_width_,
- max_preferred_logical_width_);
-
- if (style_to_use.MinWidth().IsFixed() &&
- style_to_use.MinWidth().Value() > 0) {
- max_preferred_logical_width_ =
- std::max(max_preferred_logical_width_,
- AdjustContentBoxLogicalWidthForBoxSizing(
- LayoutUnit(style_to_use.MinWidth().Value())));
- min_preferred_logical_width_ =
- std::max(min_preferred_logical_width_,
- AdjustContentBoxLogicalWidthForBoxSizing(
- LayoutUnit(style_to_use.MinWidth().Value())));
- }
-
- if (style_to_use.MaxWidth().IsFixed()) {
- max_preferred_logical_width_ =
- std::min(max_preferred_logical_width_,
- AdjustContentBoxLogicalWidthForBoxSizing(
- LayoutUnit(style_to_use.MaxWidth().Value())));
- min_preferred_logical_width_ =
- std::min(min_preferred_logical_width_,
- AdjustContentBoxLogicalWidthForBoxSizing(
- LayoutUnit(style_to_use.MaxWidth().Value())));
- }
-
- int to_add = BorderAndPaddingWidth().ToInt();
- min_preferred_logical_width_ += to_add;
- max_preferred_logical_width_ += to_add;
-
- ClearPreferredLogicalWidthsDirty();
-}
-
-PositionWithAffinity LayoutFileUploadControl::PositionForPoint(
- const PhysicalOffset&) const {
- return PositionWithAffinity();
-}
-
HTMLInputElement* LayoutFileUploadControl::UploadButton() const {
- // FIXME: This should be on HTMLInputElement as an API like
- // innerButtonElement().
- auto* input = To<HTMLInputElement>(GetNode());
- return DynamicTo<HTMLInputElement>(
- input->UserAgentShadowRoot()->firstChild());
-}
-
-String LayoutFileUploadControl::ButtonValue() {
- if (HTMLInputElement* button = UploadButton())
- return button->value();
-
- return String();
+ return To<HTMLInputElement>(GetNode())->UploadButton();
}
String LayoutFileUploadControl::FileTextValue() const {
+ int width = MaxFilenameWidth();
+ if (width <= 0)
+ return String();
auto* input = To<HTMLInputElement>(GetNode());
DCHECK(input->files());
- return LayoutTheme::GetTheme().FileListNameForWidth(
- input->GetLocale(), input->files(), StyleRef().GetFont(),
- MaxFilenameWidth());
+ String text = input->FileStatusText();
+ if (input->files()->length() >= 2)
+ return StringTruncator::RightTruncate(text, width, StyleRef().GetFont());
+ return StringTruncator::CenterTruncate(text, width, StyleRef().GetFont());
}
-PhysicalRect LayoutFileUploadControl::ControlClipRect(
- const PhysicalOffset& additional_offset) const {
+// Override to allow effective clip rect to be bigger than the padding box
+// because of kButtonShadowHeight.
+PhysicalRect LayoutFileUploadControl::OverflowClipRect(
+ const PhysicalOffset& additional_offset,
+ OverlayScrollbarClipBehavior) const {
PhysicalRect rect(additional_offset, Size());
rect.Expand(BorderInsets());
rect.offset.top -= LayoutUnit(kButtonShadowHeight);
@@ -190,12 +95,4 @@ PhysicalRect LayoutFileUploadControl::ControlClipRect(
return rect;
}
-// Override to allow effective ControlClipRect to be bigger than the padding
-// box because of kButtonShadowHeight.
-PhysicalRect LayoutFileUploadControl::OverflowClipRect(
- const PhysicalOffset& additional_offset,
- OverlayScrollbarClipBehavior) const {
- return ControlClipRect(additional_offset);
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_file_upload_control.h b/chromium/third_party/blink/renderer/core/layout/layout_file_upload_control.h
index 83aceca59f4..372714a41ef 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_file_upload_control.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_file_upload_control.h
@@ -27,8 +27,6 @@
namespace blink {
-class HTMLInputElement;
-
// Each LayoutFileUploadControl contains a LayoutButton (for opening the file
// chooser), and sufficient space to draw a file icon and filename. The
// LayoutButton has a shadow node associated with it to receive click/hover
@@ -36,7 +34,7 @@ class HTMLInputElement;
class CORE_EXPORT LayoutFileUploadControl final : public LayoutBlockFlow {
public:
- LayoutFileUploadControl(HTMLInputElement*);
+ explicit LayoutFileUploadControl(Element*);
~LayoutFileUploadControl() override;
bool IsOfType(LayoutObjectType type) const override {
@@ -44,39 +42,24 @@ class CORE_EXPORT LayoutFileUploadControl final : public LayoutBlockFlow {
LayoutBlockFlow::IsOfType(type);
}
- String ButtonValue();
String FileTextValue() const;
HTMLInputElement* UploadButton() const;
- int UploadButtonWidth();
- bool HasControlClip() const override { return true; }
- PhysicalRect ControlClipRect(const PhysicalOffset&) const override;
PhysicalRect OverflowClipRect(const PhysicalOffset&,
OverlayScrollbarClipBehavior) const override;
- bool PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const override {
- return false;
- }
-
static const int kAfterButtonSpacing = 4;
const char* GetName() const override { return "LayoutFileUploadControl"; }
private:
- void UpdateFromElement() override;
- void ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const override;
- void ComputePreferredLogicalWidths() override;
+ bool IsChildAllowed(LayoutObject* child,
+ const ComputedStyle& style) const override;
void PaintObject(const PaintInfo&,
const PhysicalOffset& paint_offset) const override;
int MaxFilenameWidth() const;
-
- PositionWithAffinity PositionForPoint(const PhysicalOffset&) const override;
-
- bool can_receive_dropped_files_;
};
DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutFileUploadControl, IsFileUploadControl());
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 97ebd2901a5..0e51f4ec744 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
@@ -33,10 +33,12 @@
#include <limits>
#include "base/auto_reset.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
+#include "third_party/blink/renderer/core/html/forms/html_select_element.h"
#include "third_party/blink/renderer/core/layout/flexible_box_algorithm.h"
#include "third_party/blink/renderer/core/layout/layout_state.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/layout/min_max_size.h"
+#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/text_autosizer.h"
@@ -52,7 +54,7 @@
namespace blink {
static bool HasAspectRatio(const LayoutBox& child) {
- return child.IsImage() || child.IsCanvas() || child.IsVideo();
+ return child.IsImage() || child.IsCanvas() || IsA<LayoutVideo>(child);
}
LayoutFlexibleBox::LayoutFlexibleBox(Element* element)
@@ -66,19 +68,37 @@ LayoutFlexibleBox::LayoutFlexibleBox(Element* element)
LayoutFlexibleBox::~LayoutFlexibleBox() = default;
-void LayoutFlexibleBox::ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const {
- LayoutUnit scrollbar_width(ScrollbarLogicalWidth());
+bool LayoutFlexibleBox::IsChildAllowed(LayoutObject* object,
+ const ComputedStyle& style) const {
+ const auto* select = DynamicTo<HTMLSelectElement>(GetNode());
+ if (UNLIKELY(select && select->UsesMenuList())) {
+ // For a size=1 <select>, we only render the active option label through the
+ // InnerElement. We do not allow adding layout objects for options and
+ // optgroups.
+ return object->GetNode() == &select->InnerElement();
+ }
+ return LayoutBlock::IsChildAllowed(object, style);
+}
+
+MinMaxSizes LayoutFlexibleBox::ComputeIntrinsicLogicalWidths() const {
+ MinMaxSizes sizes;
+ sizes += BorderAndPaddingLogicalWidth() + ScrollbarLogicalWidth();
+
if (HasOverrideIntrinsicContentLogicalWidth()) {
- max_logical_width = min_logical_width =
- OverrideIntrinsicContentLogicalWidth() + scrollbar_width;
- return;
+ sizes += OverrideIntrinsicContentLogicalWidth();
+ return sizes;
}
- if (ShouldApplySizeContainment()) {
- max_logical_width = min_logical_width = scrollbar_width;
- return;
+ LayoutUnit default_inline_size = DefaultIntrinsicContentInlineSize();
+ if (default_inline_size != kIndefiniteSize) {
+ sizes.max_size += default_inline_size;
+ if (!StyleRef().LogicalWidth().IsPercentOrCalc())
+ sizes.min_size = sizes.max_size;
+ return sizes;
}
+ if (ShouldApplySizeContainment())
+ return sizes;
+
+ MinMaxSizes child_sizes;
// FIXME: We're ignoring flex-basis here and we shouldn't. We can't start
// honoring it though until the flex shorthand stops setting it to 0. See
@@ -95,7 +115,7 @@ void LayoutFlexibleBox::ComputeIntrinsicLogicalWidths(
LayoutUnit min_preferred_logical_width;
LayoutUnit max_preferred_logical_width;
if (child->NeedsPreferredWidthsRecalculation())
- child->SetPreferredLogicalWidthsDirty();
+ child->SetIntrinsicLogicalWidthsDirty();
ComputeChildPreferredLogicalWidths(*child, min_preferred_logical_width,
max_preferred_logical_width);
DCHECK_GE(min_preferred_logical_width, LayoutUnit());
@@ -103,35 +123,35 @@ void LayoutFlexibleBox::ComputeIntrinsicLogicalWidths(
min_preferred_logical_width += margin;
max_preferred_logical_width += margin;
if (!IsColumnFlow()) {
- max_logical_width += max_preferred_logical_width;
+ child_sizes.max_size += max_preferred_logical_width;
if (IsMultiline()) {
// For multiline, the min preferred width is if you put a break between
// each item.
- min_logical_width =
- std::max(min_logical_width, min_preferred_logical_width);
+ child_sizes.min_size =
+ std::max(child_sizes.min_size, min_preferred_logical_width);
} else {
- min_logical_width += min_preferred_logical_width;
+ child_sizes.min_size += min_preferred_logical_width;
}
} else {
- min_logical_width =
- std::max(min_preferred_logical_width, min_logical_width);
- max_logical_width =
- std::max(max_preferred_logical_width, max_logical_width);
+ child_sizes.min_size =
+ std::max(min_preferred_logical_width, child_sizes.min_size);
+ child_sizes.max_size =
+ std::max(max_preferred_logical_width, child_sizes.max_size);
}
previous_max_content_flex_fraction = CountIntrinsicSizeForAlgorithmChange(
max_preferred_logical_width, child, previous_max_content_flex_fraction);
}
- max_logical_width = std::max(min_logical_width, max_logical_width);
+ child_sizes.max_size = std::max(child_sizes.min_size, child_sizes.max_size);
// Due to negative margins, it is possible that we calculated a negative
// intrinsic width. Make sure that we never return a negative width.
- min_logical_width = std::max(LayoutUnit(), min_logical_width);
- max_logical_width = std::max(LayoutUnit(), max_logical_width);
+ child_sizes.min_size = std::max(LayoutUnit(), child_sizes.min_size);
+ child_sizes.max_size = std::max(LayoutUnit(), child_sizes.max_size);
- max_logical_width += scrollbar_width;
- min_logical_width += scrollbar_width;
+ sizes += child_sizes;
+ return sizes;
}
float LayoutFlexibleBox::CountIntrinsicSizeForAlgorithmChange(
@@ -622,9 +642,9 @@ LayoutUnit LayoutFlexibleBox::ComputeMainAxisExtentForChild(
// that here. (Compare code in LayoutBlock::computePreferredLogicalWidths)
if (child.StyleRef().LogicalWidth().IsAuto() && !HasAspectRatio(child)) {
if (size.IsMinContent())
- return child.MinPreferredLogicalWidth() - border_and_padding;
+ return child.PreferredLogicalWidths().min_size - border_and_padding;
if (size.IsMaxContent())
- return child.MaxPreferredLogicalWidth() - border_and_padding;
+ return child.PreferredLogicalWidths().max_size - border_and_padding;
}
return child.ComputeLogicalWidthUsing(size_type, size, ContentLogicalWidth(),
this) -
@@ -808,7 +828,7 @@ void LayoutFlexibleBox::CacheChildMainSize(const LayoutBox& child) {
DisplayLockLifecycleTarget::kChildren));
LayoutUnit main_size;
if (MainAxisIsInlineAxis(child)) {
- main_size = child.MaxPreferredLogicalWidth();
+ main_size = child.PreferredLogicalWidths().max_size;
} else {
if (FlexBasisForChild(child).IsPercentOrCalc() &&
!MainAxisLengthIsDefinite(child, FlexBasisForChild(child))) {
@@ -861,7 +881,7 @@ LayoutUnit LayoutFlexibleBox::ComputeInnerFlexBaseSizeForChild(
LayoutBox& child,
LayoutUnit main_axis_border_and_padding,
ChildLayoutType child_layout_type) {
- if (child.IsImage() || child.IsVideo() || child.IsCanvas())
+ if (child.IsImage() || IsA<LayoutVideo>(child) || child.IsCanvas())
UseCounter::Count(GetDocument(), WebFeature::kAspectRatioFlexItem);
Length flex_basis = FlexBasisForChild(child);
@@ -895,7 +915,7 @@ LayoutUnit LayoutFlexibleBox::ComputeInnerFlexBaseSizeForChild(
if (MainAxisIsInlineAxis(child)) {
// We don't need to add ScrollbarLogicalWidth here because the preferred
// width includes the scrollbar, even for overflow: auto.
- main_axis_extent = child.MaxPreferredLogicalWidth();
+ main_axis_extent = child.PreferredLogicalWidths().max_size;
} else {
// The needed value here is the logical height. This value does not include
// the border/scrollbar/padding size, so we have to add the scrollbar.
@@ -1019,28 +1039,20 @@ void LayoutFlexibleBox::PrepareOrderIteratorAndMargins() {
continue;
// Before running the flex algorithm, 'auto' has a margin of 0.
- // Also, if we're not auto sizing, we don't do a layout that computes the
- // start/end margins.
- if (IsHorizontalFlow()) {
- child->SetMarginLeft(
- ComputeChildMarginValue(child->StyleRef().MarginLeft()));
- child->SetMarginRight(
- ComputeChildMarginValue(child->StyleRef().MarginRight()));
- } else {
- child->SetMarginTop(
- ComputeChildMarginValue(child->StyleRef().MarginTop()));
- child->SetMarginBottom(
- ComputeChildMarginValue(child->StyleRef().MarginBottom()));
- }
+ const ComputedStyle& style = child->StyleRef();
+ child->SetMarginTop(ComputeChildMarginValue(style.MarginTop()));
+ child->SetMarginRight(ComputeChildMarginValue(style.MarginRight()));
+ child->SetMarginBottom(ComputeChildMarginValue(style.MarginBottom()));
+ child->SetMarginLeft(ComputeChildMarginValue(style.MarginLeft()));
}
}
DISABLE_CFI_PERF
-MinMaxSize LayoutFlexibleBox::ComputeMinAndMaxSizesForChild(
+MinMaxSizes LayoutFlexibleBox::ComputeMinAndMaxSizesForChild(
const FlexLayoutAlgorithm& algorithm,
const LayoutBox& child,
LayoutUnit border_and_padding) const {
- MinMaxSize sizes{LayoutUnit(), LayoutUnit::Max()};
+ MinMaxSizes sizes{LayoutUnit(), LayoutUnit::Max()};
const Length& max = IsHorizontalFlow() ? child.StyleRef().MaxWidth()
: child.StyleRef().MaxHeight();
@@ -1204,21 +1216,25 @@ void LayoutFlexibleBox::ConstructAndAppendFlexItem(
}
}
- LayoutUnit border_and_padding = IsHorizontalFlow()
- ? child.BorderAndPaddingWidth()
- : child.BorderAndPaddingHeight();
+ LayoutUnit main_axis_border_padding = IsHorizontalFlow()
+ ? child.BorderAndPaddingWidth()
+ : child.BorderAndPaddingHeight();
+ LayoutUnit cross_axis_border_padding = IsHorizontalFlow()
+ ? child.BorderAndPaddingHeight()
+ : child.BorderAndPaddingWidth();
- LayoutUnit child_inner_flex_base_size =
- ComputeInnerFlexBaseSizeForChild(child, border_and_padding, layout_type);
+ LayoutUnit child_inner_flex_base_size = ComputeInnerFlexBaseSizeForChild(
+ child, main_axis_border_padding, layout_type);
- MinMaxSize sizes =
- ComputeMinAndMaxSizesForChild(*algorithm, child, border_and_padding);
+ MinMaxSizes sizes = ComputeMinAndMaxSizesForChild(*algorithm, child,
+ main_axis_border_padding);
- LayoutUnit margin =
- IsHorizontalFlow() ? child.MarginWidth() : child.MarginHeight();
- algorithm->emplace_back(&child, child_inner_flex_base_size, sizes,
- /* cross axis min max sizes */ base::nullopt,
- border_and_padding, margin);
+ NGPhysicalBoxStrut physical_margins(child.MarginTop(), child.MarginRight(),
+ child.MarginBottom(), child.MarginLeft());
+ 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);
}
void LayoutFlexibleBox::SetOverrideMainAxisContentSizeForChild(FlexItem& item) {
@@ -1455,6 +1471,7 @@ void LayoutFlexibleBox::ApplyLineItemsPosition(FlexLine* current_line) {
const FlexItem& flex_item = current_line->line_items[i];
LayoutBox* child = flex_item.box;
SetFlowAwareLocationForChild(*child, flex_item.desired_location);
+ child->SetMargin(flex_item.physical_margins);
if (is_paginated)
UpdateFragmentationInfoForChild(*child);
@@ -1558,6 +1575,7 @@ void LayoutFlexibleBox::AlignChildren(FlexLayoutAlgorithm& algorithm) {
flex_item.needs_relayout_for_stretch = false;
}
ResetAlignmentForChild(*flex_item.box, flex_item.desired_location.Y());
+ flex_item.box->SetMargin(flex_item.physical_margins);
}
}
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_flexible_box.h b/chromium/third_party/blink/renderer/core/layout/layout_flexible_box.h
index 903f746a233..3b3d34ea1ca 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_flexible_box.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_flexible_box.h
@@ -41,7 +41,7 @@ class FlexItem;
class FlexItemVectorView;
class FlexLayoutAlgorithm;
class FlexLine;
-struct MinMaxSize;
+struct MinMaxSizes;
class CORE_EXPORT LayoutFlexibleBox : public LayoutBlock {
public:
@@ -55,6 +55,8 @@ class CORE_EXPORT LayoutFlexibleBox : public LayoutBlock {
bool IsFlexibleBoxIncludingDeprecatedAndNG() const final { return true; }
void UpdateBlockLayout(bool relayout_children) final;
+ bool IsChildAllowed(LayoutObject* object,
+ const ComputedStyle& style) const override;
LayoutUnit BaselinePosition(
FontBaseline,
bool first_line,
@@ -99,9 +101,7 @@ class CORE_EXPORT LayoutFlexibleBox : public LayoutBlock {
LayoutUnit CrossAxisContentExtent() const;
protected:
- void ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const override;
+ MinMaxSizes ComputeIntrinsicLogicalWidths() const override;
bool HitTestChildren(HitTestResult&,
const HitTestLocation&,
@@ -177,9 +177,10 @@ class CORE_EXPORT LayoutFlexibleBox : public LayoutBlock {
LayoutUnit ComputeChildMarginValue(const Length& margin);
void PrepareOrderIteratorAndMargins();
- MinMaxSize ComputeMinAndMaxSizesForChild(const FlexLayoutAlgorithm& algorithm,
- const LayoutBox& child,
- LayoutUnit border_and_padding) const;
+ MinMaxSizes ComputeMinAndMaxSizesForChild(
+ const FlexLayoutAlgorithm& algorithm,
+ const LayoutBox& child,
+ LayoutUnit border_and_padding) const;
LayoutUnit AdjustChildSizeForAspectRatioCrossAxisMinAndMax(
const LayoutBox& child,
LayoutUnit child_size) const;
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_flexible_box_test.cc b/chromium/third_party/blink/renderer/core/layout/layout_flexible_box_test.cc
index 781b9c7e0fb..07853d0ae57 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_flexible_box_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_flexible_box_test.cc
@@ -496,11 +496,12 @@ TEST_P(LayoutFlexibleBoxTest, ResizedFlexChildRequiresVisualOverflowRecalc) {
auto* child1_element = GetElementById("child1");
auto* child2_element = GetElementById("child2");
child2_element->setAttribute(html_names::kStyleAttr, "height: 100px;");
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
auto* child1_box = ToLayoutBox(child1_element->GetLayoutObject());
ASSERT_TRUE(child1_box->HasSelfPaintingLayer());
- EXPECT_TRUE(child1_box->Layer()->NeedsVisualOverflowRecalcForTesting());
+ EXPECT_TRUE(child1_box->Layer()->NeedsVisualOverflowRecalc());
UpdateAllLifecyclePhasesForTest();
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_flow_thread.h b/chromium/third_party/blink/renderer/core/layout/layout_flow_thread.h
index 51130666c56..d43f6eb612d 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_flow_thread.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_flow_thread.h
@@ -105,6 +105,8 @@ class CORE_EXPORT LayoutFlowThread : public LayoutBlockFlow {
// can easily avoid drawing the children directly.
PaintLayerType LayerTypeRequired() const final { return kNormalPaintLayer; }
+ bool NeedsPreferredWidthsRecalculation() const final { return true; }
+
virtual void FlowThreadDescendantWasInserted(LayoutObject*) {}
virtual void FlowThreadDescendantWillBeRemoved(LayoutObject*) {}
virtual void FlowThreadDescendantStyleWillChange(
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_frame_set.cc b/chromium/third_party/blink/renderer/core/layout/layout_frame_set.cc
index 8fe99fd5403..fc00cf0cf40 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_frame_set.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_frame_set.cc
@@ -32,7 +32,7 @@
#include "third_party/blink/renderer/core/layout/layout_frame.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/paint/frame_set_painter.h"
-#include "third_party/blink/renderer/platform/cursor.h"
+#include "third_party/blink/renderer/platform/cursors.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
namespace blink {
@@ -65,12 +65,6 @@ void LayoutFrameSet::Paint(const PaintInfo& paint_info) const {
FrameSetPainter(*this).Paint(paint_info);
}
-void LayoutFrameSet::ComputePreferredLogicalWidths() {
- min_preferred_logical_width_ = LayoutUnit();
- max_preferred_logical_width_ = LayoutUnit();
- ClearPreferredLogicalWidthsDirty();
-}
-
void LayoutFrameSet::GridAxis::Resize(int size) {
sizes_.resize(size);
deltas_.resize(size);
@@ -577,7 +571,7 @@ bool LayoutFrameSet::IsChildAllowed(LayoutObject* child,
}
CursorDirective LayoutFrameSet::GetCursor(const PhysicalOffset& point,
- Cursor& cursor) const {
+ ui::Cursor& cursor) const {
IntPoint rounded_point = RoundedIntPoint(point);
if (CanResizeRow(rounded_point)) {
cursor = RowResizeCursor();
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_frame_set.h b/chromium/third_party/blink/renderer/core/layout/layout_frame_set.h
index 3d193caad5c..6c9aae4e7c9 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_frame_set.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_frame_set.h
@@ -132,9 +132,15 @@ class LayoutFrameSet final : public LayoutBox {
void UpdateLayout() override;
void Paint(const PaintInfo&) const override;
- void ComputePreferredLogicalWidths() override;
+
+ MinMaxSizes PreferredLogicalWidths() const override { return MinMaxSizes(); }
+ MinMaxSizes ComputeIntrinsicLogicalWidths() const final {
+ NOTREACHED();
+ return MinMaxSizes();
+ }
+
bool IsChildAllowed(LayoutObject*, const ComputedStyle&) const override;
- CursorDirective GetCursor(const PhysicalOffset&, Cursor&) const override;
+ CursorDirective GetCursor(const PhysicalOffset&, ui::Cursor&) const override;
void SetIsResizing(bool);
@@ -149,10 +155,6 @@ class LayoutFrameSet final : public LayoutBox {
void StartResizing(GridAxis&, int position);
void ContinueResizing(GridAxis&, int position);
- bool PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const override {
- return false;
- }
-
LayoutObjectChildList children_;
GridAxis rows_;
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_geometry_map.cc b/chromium/third_party/blink/renderer/core/layout/layout_geometry_map.cc
index 8a933f61e59..5333c86d923 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_geometry_map.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_geometry_map.cc
@@ -28,6 +28,7 @@
#include "base/auto_reset.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/layout/geometry/transform_state.h"
+#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#define LAYOUT_GEOMETRY_MAP_LOGGING 0
@@ -105,7 +106,7 @@ void LayoutGeometryMap::MapToAncestor(
}
}
- if (in_fixed && current_step.layout_object_->IsLayoutView()) {
+ if (in_fixed && IsA<LayoutView>(current_step.layout_object_)) {
transform_state.Move(current_step.offset_for_fixed_position_);
in_fixed = false;
}
@@ -119,7 +120,7 @@ void LayoutGeometryMap::MapToAncestor(
const LayoutGeometryMapStep& current_step = mapping_[i];
if (current_step.flags_ & (kContainsFixedPosition | kIsFixedPosition))
break;
- if (current_step.layout_object_->IsLayoutView()) {
+ if (IsA<LayoutView>(current_step.layout_object_)) {
transform_state.Move(current_step.offset_for_fixed_position_);
break;
}
@@ -282,7 +283,7 @@ void LayoutGeometryMap::PushMappingsToAncestor(
// The LayoutView must be pushed first.
if (!mapping_.size()) {
- DCHECK(ancestor_layer->GetLayoutObject().IsLayoutView());
+ DCHECK(IsA<LayoutView>(ancestor_layer->GetLayoutObject()));
PushMappingsToAncestor(&ancestor_layer->GetLayoutObject(), nullptr);
}
@@ -311,9 +312,9 @@ void LayoutGeometryMap::Push(const LayoutObject* layout_object,
#endif
DCHECK_NE(insertion_position_, kNotFound);
- DCHECK(!layout_object->IsLayoutView() || !insertion_position_ ||
+ DCHECK(!IsA<LayoutView>(layout_object) || !insertion_position_ ||
map_coordinates_flags_ & kTraverseDocumentBoundaries);
- DCHECK(offset_for_fixed_position.IsZero() || layout_object->IsLayoutView());
+ DCHECK(offset_for_fixed_position.IsZero() || IsA<LayoutView>(layout_object));
mapping_.insert(insertion_position_,
LayoutGeometryMapStep(layout_object, flags));
@@ -330,9 +331,9 @@ void LayoutGeometryMap::Push(const LayoutObject* layout_object,
GeometryInfoFlags flags,
PhysicalOffset offset_for_fixed_position) {
DCHECK_NE(insertion_position_, kNotFound);
- DCHECK(!layout_object->IsLayoutView() || !insertion_position_ ||
+ DCHECK(!IsA<LayoutView>(layout_object) || !insertion_position_ ||
map_coordinates_flags_ & kTraverseDocumentBoundaries);
- DCHECK(offset_for_fixed_position.IsZero() || layout_object->IsLayoutView());
+ DCHECK(offset_for_fixed_position.IsZero() || IsA<LayoutView>(layout_object));
mapping_.insert(insertion_position_,
LayoutGeometryMapStep(layout_object, flags));
@@ -411,7 +412,7 @@ void LayoutGeometryMap::StepRemoved(const LayoutGeometryMapStep& step) {
#if DCHECK_IS_ON()
bool LayoutGeometryMap::IsTopmostLayoutView(
const LayoutObject* layout_object) const {
- if (!layout_object->IsLayoutView())
+ if (!IsA<LayoutView>(layout_object))
return false;
// If we're not working with multiple LayoutViews, then any view is considered
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_geometry_map_test.cc b/chromium/third_party/blink/renderer/core/layout/layout_geometry_map_test.cc
index e04efaedda7..381b7eb16ad 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_geometry_map_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_geometry_map_test.cc
@@ -144,7 +144,7 @@ class LayoutGeometryMapTest : public testing::Test {
void UpdateAllLifecyclePhases(WebView* web_view) {
web_view->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
}
const std::string base_url_;
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 0d9e5a5dc20..1b03b70feb3 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_grid.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_grid.cc
@@ -194,7 +194,12 @@ bool LayoutGrid::ExplicitGridDidResize(const ComputedStyle& old_style) const {
bool LayoutGrid::NamedGridLinesDefinitionDidChange(
const ComputedStyle& old_style) const {
return old_style.NamedGridRowLines() != StyleRef().NamedGridRowLines() ||
- old_style.NamedGridColumnLines() != StyleRef().NamedGridColumnLines();
+ old_style.NamedGridColumnLines() !=
+ StyleRef().NamedGridColumnLines() ||
+ old_style.ImplicitNamedGridRowLines() !=
+ StyleRef().ImplicitNamedGridRowLines() ||
+ old_style.ImplicitNamedGridColumnLines() !=
+ StyleRef().ImplicitNamedGridColumnLines();
}
void LayoutGrid::ComputeTrackSizesForDefiniteSize(
@@ -246,11 +251,8 @@ void LayoutGrid::RepeatTracksSizingIfNeeded(
void LayoutGrid::UpdateBlockLayout(bool relayout_children) {
DCHECK(NeedsLayout());
- // We cannot perform a simplifiedLayout() on a dirty grid that
- // has positioned items to be laid out.
- if (!relayout_children &&
- (!grid_->NeedsItemsPlacement() || !PosChildNeedsLayout()) &&
- SimplifiedLayout())
+ // We cannot perform a |SimplifiedLayout()| with a dirty grid.
+ if (!relayout_children && !grid_->NeedsItemsPlacement() && SimplifiedLayout())
return;
SubtreeLayoutScope layout_scope(*this);
@@ -502,17 +504,13 @@ LayoutUnit LayoutGrid::GuttersSize(
return gap_accumulator;
}
-void LayoutGrid::ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const {
- LayoutUnit scrollbar_width = LayoutUnit(ScrollbarLogicalWidth());
- min_logical_width = scrollbar_width;
- max_logical_width = scrollbar_width;
+MinMaxSizes LayoutGrid::ComputeIntrinsicLogicalWidths() const {
+ MinMaxSizes sizes;
+ sizes += BorderAndPaddingLogicalWidth() + ScrollbarLogicalWidth();
if (HasOverrideIntrinsicContentLogicalWidth()) {
- min_logical_width += OverrideIntrinsicContentLogicalWidth();
- max_logical_width = min_logical_width;
- return;
+ sizes += OverrideIntrinsicContentLogicalWidth();
+ return sizes;
}
std::unique_ptr<Grid> grid = Grid::Create(this);
@@ -538,8 +536,9 @@ void LayoutGrid::ComputeIntrinsicLogicalWidths(
LayoutUnit total_gutters_size = GuttersSize(
algorithm.GetGrid(), kForColumns, 0, number_of_tracks, base::nullopt);
- min_logical_width += algorithm.MinContentSize() + total_gutters_size;
- max_logical_width += algorithm.MaxContentSize() + total_gutters_size;
+ sizes.min_size += algorithm.MinContentSize() + total_gutters_size;
+ sizes.max_size += algorithm.MaxContentSize() + total_gutters_size;
+ return sizes;
}
void LayoutGrid::ComputeTrackSizesForIndefiniteSize(
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 abfcb38ae67..9b9bb6b31d7 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_grid.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_grid.h
@@ -128,9 +128,7 @@ class LayoutGrid final : public LayoutBlock {
bool IsOfType(LayoutObjectType type) const override {
return type == kLayoutObjectLayoutGrid || LayoutBlock::IsOfType(type);
}
- void ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const override;
+ MinMaxSizes ComputeIntrinsicLogicalWidths() const override;
void AddChild(LayoutObject* new_child,
LayoutObject* before_child = nullptr) override;
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_html_canvas.cc b/chromium/third_party/blink/renderer/core/layout/layout_html_canvas.cc
index 8f8c5d015d4..1023bca17ae 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_html_canvas.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_html_canvas.cc
@@ -61,23 +61,8 @@ void LayoutHTMLCanvas::CanvasSizeChanged() {
if (!Parent())
return;
- if (!PreferredLogicalWidthsDirty())
- SetPreferredLogicalWidthsDirty();
-
- LayoutSize old_size = Size();
- UpdateLogicalWidth();
- UpdateLogicalHeight();
- if (old_size == Size() && !HasOverrideLogicalWidth() &&
- !HasOverrideLogicalHeight()) {
- // If we have an override size, then we're probably a flex item, and the
- // check above is insufficient because updateLogical{Width,Height} just
- // used the override size. We actually have to mark ourselves as needing
- // layout so the flex algorithm can run and compute our size correctly.
- return;
- }
-
- if (!SelfNeedsLayout())
- SetNeedsLayout(layout_invalidation_reason::kSizeChanged);
+ SetIntrinsicLogicalWidthsDirty();
+ SetNeedsLayout(layout_invalidation_reason::kSizeChanged);
}
void LayoutHTMLCanvas::InvalidatePaint(
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_html_canvas.h b/chromium/third_party/blink/renderer/core/layout/layout_html_canvas.h
index 55c979f7e9d..d1b8612e2c7 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_html_canvas.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_html_canvas.h
@@ -56,6 +56,7 @@ class CORE_EXPORT LayoutHTMLCanvas final : public LayoutReplaced {
const PhysicalOffset& paint_offset) const override;
void IntrinsicSizeChanged() override { CanvasSizeChanged(); }
+ bool CanHaveAdditionalCompositingReasons() const override { return true; }
CompositingReasons AdditionalCompositingReasons() const override;
};
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_iframe.h b/chromium/third_party/blink/renderer/core/layout/layout_iframe.h
index eab361c0b9a..5de2e13470c 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_iframe.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_iframe.h
@@ -50,8 +50,6 @@ class LayoutIFrame final : public LayoutEmbeddedContent {
PaintLayerType LayerTypeRequired() const override;
};
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutIFrame, IsLayoutIFrame());
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_IFRAME_H_
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 571e7c8926a..6f2a3ae49ac 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_image.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_image.cc
@@ -35,10 +35,12 @@
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/html/html_area_element.h"
#include "third_party/blink/renderer/core/html/html_image_element.h"
+#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/core/html/media/media_element_parser_helpers.h"
#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/intrinsic_sizing_info.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/loader/resource/image_resource_content.h"
#include "third_party/blink/renderer/core/paint/image_element_timing.h"
@@ -156,6 +158,10 @@ bool LayoutImage::NeedsLayoutOnIntrinsicSizeChange() const {
kDontRegisterPercentageDescendant);
if (!image_size_is_constrained)
return true;
+ // Flex layout algorithm uses the intrinsic image width/height even if
+ // width/height are specified.
+ if (IsFlexItemIncludingNG())
+ return true;
// FIXME: We only need to recompute the containing block's preferred size if
// the containing block's size depends on the image's size (i.e., the
// container uses shrink-to-fit sizing). There's no easy way to detect that
@@ -179,7 +185,7 @@ void LayoutImage::InvalidatePaintAndMarkForLayoutIfNeeded(
return;
if (old_intrinsic_size != new_intrinsic_size) {
- SetPreferredLogicalWidthsDirty();
+ SetIntrinsicLogicalWidthsDirty();
if (NeedsLayoutOnIntrinsicSizeChange()) {
SetNeedsLayoutAndFullPaintInvalidation(
@@ -306,20 +312,19 @@ bool LayoutImage::NodeAtPoint(HitTestResult& result,
return inside;
}
-IntSize LayoutImage::GetOverriddenIntrinsicSize() const {
- if (auto* image_element = DynamicTo<HTMLImageElement>(GetNode())) {
- if (RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled())
- return image_element->GetOverriddenIntrinsicSize();
- }
- return IntSize();
+bool LayoutImage::HasOverriddenIntrinsicSize() const {
+ if (!RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled())
+ return false;
+ auto* image_element = DynamicTo<HTMLImageElement>(GetNode());
+ return image_element && image_element->IsDefaultIntrinsicSize();
}
FloatSize LayoutImage::ImageSizeOverriddenByIntrinsicSize(
float multiplier) const {
- FloatSize overridden_intrinsic_size = FloatSize(GetOverriddenIntrinsicSize());
- if (overridden_intrinsic_size.IsEmpty())
+ if (!HasOverriddenIntrinsicSize())
return image_resource_->ImageSize(multiplier);
+ FloatSize overridden_intrinsic_size(kDefaultWidth, kDefaultHeight);
if (multiplier != 1) {
overridden_intrinsic_size.Scale(multiplier);
if (overridden_intrinsic_size.Width() < 1.0f)
@@ -333,11 +338,11 @@ FloatSize LayoutImage::ImageSizeOverriddenByIntrinsicSize(
bool LayoutImage::OverrideIntrinsicSizingInfo(
IntrinsicSizingInfo& intrinsic_sizing_info) const {
- IntSize overridden_intrinsic_size = GetOverriddenIntrinsicSize();
- if (overridden_intrinsic_size.IsEmpty())
+ if (!HasOverriddenIntrinsicSize())
return false;
- intrinsic_sizing_info.size = FloatSize(overridden_intrinsic_size);
+ FloatSize overridden_intrinsic_size(kDefaultWidth, kDefaultHeight);
+ intrinsic_sizing_info.size = overridden_intrinsic_size;
intrinsic_sizing_info.aspect_ratio = intrinsic_sizing_info.size;
if (!IsHorizontalWritingMode())
intrinsic_sizing_info.Transpose();
@@ -393,7 +398,8 @@ void LayoutImage::ComputeIntrinsicSizingInfo(
// we're painting alt text and/or a broken image.
// Video is excluded from this behavior because video elements have a default
// aspect ratio that a failed poster image load should not override.
- if (image_resource_ && image_resource_->ErrorOccurred() && !IsVideo()) {
+ if (image_resource_ && image_resource_->ErrorOccurred() &&
+ !IsA<LayoutVideo>(this)) {
intrinsic_sizing_info.aspect_ratio = FloatSize(1, 1);
return;
}
@@ -414,15 +420,18 @@ SVGImage* LayoutImage::EmbeddedSVGImage() const {
// https://crbug.com/761026
if (!cached_image || cached_image->IsCacheValidator())
return nullptr;
- return ToSVGImageOrNull(cached_image->GetImage());
+ return DynamicTo<SVGImage>(cached_image->GetImage());
}
void LayoutImage::UpdateAfterLayout() {
LayoutBox::UpdateAfterLayout();
Node* node = GetNode();
if (auto* image_element = DynamicTo<HTMLImageElement>(node)) {
- media_element_parser_helpers::ReportUnsizedMediaViolation(
+ media_element_parser_helpers::CheckUnsizedMediaViolation(
this, image_element->IsDefaultIntrinsicSize());
+ } else if (auto* video_element = DynamicTo<HTMLVideoElement>(node)) {
+ media_element_parser_helpers::CheckUnsizedMediaViolation(
+ this, video_element->IsDefaultIntrinsicSize());
}
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_image.h b/chromium/third_party/blink/renderer/core/layout/layout_image.h
index 43364aaf8d3..3ed38c13197 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_image.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_image.h
@@ -135,8 +135,8 @@ class CORE_EXPORT LayoutImage : public LayoutReplaced {
// Override intrinsic sizing info to default if "unsized-media"
// is disabled and the element has no sizing info.
bool OverrideIntrinsicSizingInfo(IntrinsicSizingInfo&) const;
+ bool HasOverriddenIntrinsicSize() const;
FloatSize ImageSizeOverriddenByIntrinsicSize(float multiplier) const;
- IntSize GetOverriddenIntrinsicSize() const;
// This member wraps the associated decoded image.
//
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_image_resource.cc b/chromium/third_party/blink/renderer/core/layout/layout_image_resource.cc
index 1f260426bcd..57bc7eb48e2 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_image_resource.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_image_resource.cc
@@ -168,7 +168,8 @@ scoped_refptr<Image> LayoutImageResource::GetImage(
layout_object_->StyleRef().EffectiveZoom());
}
- if (!image->IsSVGImage())
+ auto* svg_image = DynamicTo<SVGImage>(image);
+ if (!svg_image)
return image;
KURL url;
@@ -177,8 +178,8 @@ scoped_refptr<Image> LayoutImageResource::GetImage(
url = element->GetDocument().CompleteURL(url_string);
}
return SVGImageForContainer::Create(
- ToSVGImage(image), container_size,
- layout_object_->StyleRef().EffectiveZoom(), url);
+ svg_image, container_size, layout_object_->StyleRef().EffectiveZoom(),
+ url);
}
bool LayoutImageResource::MaybeAnimated() const {
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 af9230cd5f0..808a0958044 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(blink::Visitor* visitor) { visitor->Trace(cached_image_); }
+ virtual void Trace(Visitor* visitor) { 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 77873f52cef..ed8c3dfe576 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
@@ -78,10 +78,11 @@ FloatSize LayoutImageResourceStyleImage::ImageSize(float multiplier) const {
FloatSize LayoutImageResourceStyleImage::ImageSizeWithDefaultSize(
float multiplier,
const LayoutSize& default_size) const {
- return style_image_->ImageSize(layout_object_->GetDocument(), multiplier,
- default_size);
+ return style_image_->ImageSize(
+ layout_object_->GetDocument(), multiplier, default_size,
+ LayoutObject::ShouldRespectImageOrientation(layout_object_));
}
-void LayoutImageResourceStyleImage::Trace(blink::Visitor* visitor) {
+void LayoutImageResourceStyleImage::Trace(Visitor* visitor) {
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 1b2bd849409..108d42d137f 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 a8a84440bd0..a7dd0e57408 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_inline.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_inline.cc
@@ -171,7 +171,20 @@ void LayoutInline::SetFirstInlineFragmentItemIndex(wtf_size_t index) {
CHECK(IsInLayoutNGInlineFormattingContext()) << *this;
DCHECK(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
DCHECK_NE(index, 0u);
- first_fragment_item_index_ = index;
+ // TDOO(yosin): Once we update all |LayoutObject::FirstInlineFragment()|,
+ // we should enable below.
+ // first_fragment_item_index_ = index;
+}
+
+bool LayoutInline::HasInlineFragments() const {
+ if (!IsInLayoutNGInlineFormattingContext())
+ return FirstLineBox();
+ if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return first_paint_fragment_;
+ // TODO(yosin): We should use |first_fragment_item_index_|.
+ NGInlineCursor cursor;
+ cursor.MoveTo(*this);
+ return cursor;
}
void LayoutInline::InLayoutNGInlineFormattingContextWillChange(bool new_value) {
@@ -518,7 +531,7 @@ void LayoutInline::AddChildIgnoringContinuation(LayoutObject* new_child,
LayoutBoxModelObject::AddChild(new_child, before_child);
- new_child->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ new_child->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kChildChanged);
}
@@ -673,7 +686,7 @@ void LayoutInline::SplitFlow(LayoutObject* before_child,
o = no->NextSibling();
pre->Children()->AppendChildNode(
pre, block->Children()->RemoveChildNode(block, no));
- no->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ no->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kAnonymousBlockChange);
}
}
@@ -691,11 +704,11 @@ void LayoutInline::SplitFlow(LayoutObject* before_child,
// wrappers for images) get deleted properly. Because objects moves from the
// pre block into the post block, we want to make new line boxes instead of
// leaving the old line boxes around.
- pre->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ pre->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kAnonymousBlockChange);
- block->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ block->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kAnonymousBlockChange);
- post->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ post->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kAnonymousBlockChange);
}
@@ -790,9 +803,16 @@ void LayoutInline::CollectLineBoxRects(
const auto* box_fragment = ContainingBlockFlowFragmentOf(*this);
if (!box_fragment)
return;
- for (const auto& fragment :
- NGInlineFragmentTraversal::SelfFragmentsOf(*box_fragment, this))
- yield(fragment.RectInContainerBox());
+ if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ for (const auto& fragment :
+ NGInlineFragmentTraversal::SelfFragmentsOf(*box_fragment, this))
+ yield(fragment.RectInContainerBox());
+ return;
+ }
+ NGInlineCursor cursor;
+ cursor.MoveTo(*this);
+ for (; cursor; cursor.MoveToNextForSameLayoutObject())
+ yield(cursor.Current().RectInContainerBlock());
return;
}
if (!AlwaysCreateLineBoxes()) {
@@ -940,7 +960,7 @@ base::Optional<PhysicalOffset> LayoutInline::FirstLineBoxTopLeftInternal()
cursor.MoveTo(*this);
if (!cursor)
return base::nullopt;
- return cursor.CurrentOffset();
+ return cursor.Current().OffsetInContainerBlock();
}
if (const InlineBox* first_box = FirstLineBoxIncludingCulling()) {
LayoutPoint location = first_box->Location();
@@ -1027,21 +1047,41 @@ bool LayoutInline::NodeAtPoint(HitTestResult& result,
HitTestAction hit_test_action) {
if (ContainingNGBlockFlow()) {
// TODO(crbug.com/965976): We should fix the root cause of the missed
- // layout, and then turn this into a DCHECK.
- CHECK(!NeedsLayout()) << this;
+ // layout.
+ if (UNLIKELY(NeedsLayout())) {
+ NOTREACHED();
+ return false;
+ }
// In LayoutNG, we reach here only when called from
// PaintLayer::HitTestContents() without going through any ancestor, in
// which case the element must have self painting layer.
DCHECK(HasSelfPaintingLayer());
- for (const NGPaintFragment* fragment :
- NGPaintFragment::InlineFragmentsFor(this)) {
+ NGInlineCursor cursor;
+ for (cursor.MoveTo(*this); cursor; cursor.MoveToNextForSameLayoutObject()) {
+ if (const NGPaintFragment* paint_fragment =
+ cursor.Current().PaintFragment()) {
+ // NGBoxFragmentPainter::NodeAtPoint() takes an offset that is
+ // accumulated up to the fragment itself. Compute this offset.
+ const PhysicalOffset child_offset =
+ accumulated_offset + paint_fragment->OffsetInContainerBlock();
+ if (NGBoxFragmentPainter(*paint_fragment)
+ .NodeAtPoint(result, hit_test_location, child_offset,
+ hit_test_action))
+ return true;
+ continue;
+ }
+ DCHECK(cursor.Current().Item());
+ const NGFragmentItem& item = *cursor.Current().Item();
+ const NGPhysicalBoxFragment* box_fragment = item.BoxFragment();
+ DCHECK(box_fragment);
// NGBoxFragmentPainter::NodeAtPoint() takes an offset that is accumulated
// up to the fragment itself. Compute this offset.
- PhysicalOffset adjusted_location =
- accumulated_offset + fragment->InlineOffsetToContainerBox();
- if (NGBoxFragmentPainter(*fragment).NodeAtPoint(
- result, hit_test_location, adjusted_location, hit_test_action))
+ const PhysicalOffset child_offset =
+ accumulated_offset + item.OffsetInContainerBlock();
+ if (NGBoxFragmentPainter(cursor, item, *box_fragment)
+ .NodeAtPoint(result, hit_test_location, child_offset,
+ accumulated_offset, hit_test_action))
return true;
}
return false;
@@ -1083,7 +1123,7 @@ bool LayoutInline::HitTestCulledInline(
container_fragment->PhysicalFragment().IsLineBox());
NGInlineCursor cursor(*container_fragment);
for (cursor.MoveTo(*this); cursor; cursor.MoveToNextForSameLayoutObject())
- yield(cursor.CurrentRect());
+ yield(cursor.Current().RectInContainerBlock());
} else {
DCHECK(!ContainingNGBlockFlow());
CollectCulledLineBoxRects(yield);
@@ -1135,7 +1175,7 @@ PhysicalRect LayoutInline::PhysicalLinesBoundingBox() const {
cursor.MoveTo(*this);
PhysicalRect bounding_box;
for (; cursor; cursor.MoveToNextForSameLayoutObject())
- bounding_box.UniteIfNonZero(cursor.CurrentRect());
+ bounding_box.UniteIfNonZero(cursor.Current().RectInContainerBlock());
return bounding_box;
}
@@ -1283,8 +1323,8 @@ PhysicalRect LayoutInline::LinesVisualOverflowBoundingBox() const {
NGInlineCursor cursor;
cursor.MoveTo(*this);
for (; cursor; cursor.MoveToNextForSameLayoutObject()) {
- PhysicalRect child_rect = cursor.CurrentInkOverflow();
- child_rect.offset += cursor.CurrentOffset();
+ PhysicalRect child_rect = cursor.Current().InkOverflow();
+ child_rect.offset += cursor.Current().OffsetInContainerBlock();
result.Unite(child_rect);
}
return result;
@@ -1394,7 +1434,7 @@ PhysicalRect LayoutInline::ReferenceBoxForClipPath() const {
NGInlineCursor cursor;
cursor.MoveTo(*this);
if (cursor)
- return cursor.CurrentRect();
+ return cursor.Current().RectInContainerBlock();
}
if (const InlineFlowBox* flow_box = FirstLineBox())
return FlipForWritingMode(flow_box->FrameRect());
@@ -1736,7 +1776,8 @@ void LayoutInline::InvalidateDisplayItemClients(
PaintInvalidationReason invalidation_reason) const {
ObjectPaintInvalidator paint_invalidator(*this);
- if (RuntimeEnabledFeatures::LayoutNGBlockFragmentationEnabled()) {
+ if (RuntimeEnabledFeatures::LayoutNGBlockFragmentationEnabled() &&
+ !RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
auto fragments = NGPaintFragment::InlineFragmentsFor(this);
if (fragments.IsInLayoutNGInlineFormattingContext()) {
for (NGPaintFragment* fragment : fragments) {
@@ -1748,13 +1789,14 @@ void LayoutInline::InvalidateDisplayItemClients(
}
if (IsInLayoutNGInlineFormattingContext()) {
- if (!ShouldCreateBoxFragment())
+ if (!ShouldCreateBoxFragment() &&
+ !RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
return;
NGInlineCursor cursor;
for (cursor.MoveTo(*this); cursor; cursor.MoveToNextForSameLayoutObject()) {
- DCHECK_EQ(cursor.CurrentLayoutObject(), this);
+ DCHECK_EQ(cursor.Current().GetLayoutObject(), this);
paint_invalidator.InvalidateDisplayItemClient(
- *cursor.CurrentDisplayItemClient(), invalidation_reason);
+ *cursor.Current().GetDisplayItemClient(), invalidation_reason);
}
return;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_inline.h b/chromium/third_party/blink/renderer/core/layout/layout_inline.h
index a6a4fe2a5fa..448bf29cadd 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_inline.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_inline.h
@@ -172,16 +172,13 @@ class CORE_EXPORT LayoutInline : public LayoutBoxModelObject {
return AlwaysCreateLineBoxes() ? LastLineBox() : CulledInlineLastLineBox();
}
+ bool HasInlineFragments() const final;
NGPaintFragment* FirstInlineFragment() const final;
void SetFirstInlineFragment(NGPaintFragment*) final;
wtf_size_t FirstInlineFragmentItemIndex() const final;
void ClearFirstInlineFragmentItemIndex() final;
void SetFirstInlineFragmentItemIndex(wtf_size_t) final;
- // Return true if this inline doesn't occur on any lines, i.e. when it creates
- // no fragments.
- bool IsEmpty() const { return !FirstLineBox() && !FirstInlineFragment(); }
-
LayoutBoxModelObject* VirtualContinuation() const final {
return Continuation();
}
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 7570ca21718..2c8922ef27c 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
@@ -4,9 +4,11 @@
#include "third_party/blink/renderer/core/layout/layout_inline.h"
+#include "build/build_config.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h"
#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
@@ -25,7 +27,9 @@ class ParameterizedLayoutInlineTest : public testing::WithParamInterface<bool>,
ParameterizedLayoutInlineTest() : ScopedLayoutNGForTest(GetParam()) {}
protected:
- bool LayoutNGEnabled() const { return GetParam(); }
+ bool LayoutNGEnabled() const {
+ return RuntimeEnabledFeatures::LayoutNGEnabled();
+ }
};
INSTANTIATE_TEST_SUITE_P(All, ParameterizedLayoutInlineTest, testing::Bool());
@@ -107,6 +111,14 @@ 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);
@@ -676,4 +688,119 @@ TEST_P(ParameterizedLayoutInlineTest, AddAnnotatedRegionsVerticalRL) {
EXPECT_TRUE(regions3.IsEmpty());
}
+TEST_P(ParameterizedLayoutInlineTest, VisualOverflowRecalcLegacyLayout) {
+ // "contenteditable" forces us to use legacy layout, other options could be
+ // using "display: -webkit-box", ruby, etc.
+ LoadAhem();
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ body {
+ margin: 0;
+ font: 20px/20px Ahem;
+ }
+ target {
+ outline: 50px solid red;
+ }
+ </style>
+ <div contenteditable>
+ <span id="span">SPAN1</span>
+ <span id="span2">SPAN2</span>
+ </div>
+ )HTML");
+
+ auto* span = ToLayoutInline(GetLayoutObjectByElementId("span"));
+ auto* span_element = GetDocument().getElementById("span");
+ auto* span2_element = GetDocument().getElementById("span2");
+
+ span_element->setAttribute(html_names::kStyleAttr, "outline: 50px solid red");
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_EQ(PhysicalRect(-50, -50, 200, 120),
+ span->PhysicalVisualOverflowRect());
+
+ span_element->setAttribute(html_names::kStyleAttr, "");
+ span2_element->setAttribute(html_names::kStyleAttr,
+ "outline: 50px solid red");
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_EQ(PhysicalRect(0, 0, 100, 20), span->PhysicalVisualOverflowRect());
+
+ span2_element->setAttribute(html_names::kStyleAttr, "");
+ span_element->setAttribute(html_names::kStyleAttr, "outline: 50px solid red");
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_EQ(PhysicalRect(-50, -50, 200, 120),
+ span->PhysicalVisualOverflowRect());
+
+ span_element->setAttribute(html_names::kStyleAttr, "");
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_EQ(PhysicalRect(0, 0, 100, 20), span->PhysicalVisualOverflowRect());
+}
+
+TEST_P(ParameterizedLayoutInlineTest, VisualOverflowRecalcLayoutNG) {
+ LoadAhem();
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ body {
+ margin: 0;
+ font: 20px/20px Ahem;
+ }
+ target {
+ outline: 50px solid red;
+ }
+ </style>
+ <div>
+ <span id="span">SPAN1</span>
+ <span id="span2">SPAN2</span>
+ </div>
+ )HTML");
+
+ auto* span = ToLayoutInline(GetLayoutObjectByElementId("span"));
+ auto* span_element = GetDocument().getElementById("span");
+ auto* span2_element = GetDocument().getElementById("span2");
+
+ span_element->setAttribute(html_names::kStyleAttr, "outline: 50px solid red");
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_EQ(PhysicalRect(-50, -50, 200, 120),
+ span->PhysicalVisualOverflowRect());
+
+ span_element->setAttribute(html_names::kStyleAttr, "");
+ span2_element->setAttribute(html_names::kStyleAttr,
+ "outline: 50px solid red");
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_EQ(PhysicalRect(0, 0, 100, 20), span->PhysicalVisualOverflowRect());
+
+ span2_element->setAttribute(html_names::kStyleAttr, "");
+ span_element->setAttribute(html_names::kStyleAttr, "outline: 50px solid red");
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_EQ(PhysicalRect(-50, -50, 200, 120),
+ span->PhysicalVisualOverflowRect());
+
+ span_element->setAttribute(html_names::kStyleAttr, "");
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_EQ(PhysicalRect(0, 0, 100, 20), span->PhysicalVisualOverflowRect());
+}
+
+TEST_P(ParameterizedLayoutInlineTest,
+ VisualOverflowRecalcLegacyLayoutPositionRelative) {
+ LoadAhem();
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ body {
+ margin: 0;
+ font: 20px/20px Ahem;
+ }
+ span {
+ position: relative;
+ }
+ </style>
+ <span id="span">SPAN</span>
+ )HTML");
+
+ auto* span = ToLayoutInline(GetLayoutObjectByElementId("span"));
+ auto* span_element = GetDocument().getElementById("span");
+
+ span_element->setAttribute(html_names::kStyleAttr, "outline: 50px solid red");
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_EQ(PhysicalRect(-50, -50, 180, 120),
+ span->PhysicalVisualOverflowRect());
+}
+
} // namespace blink
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
new file mode 100644
index 00000000000..ada7d6b11d0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/layout_inside_list_marker.cc
@@ -0,0 +1,14 @@
+// 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/layout_inside_list_marker.h"
+
+namespace blink {
+
+LayoutInsideListMarker::LayoutInsideListMarker(Element* element)
+ : LayoutListMarker(element) {}
+
+LayoutInsideListMarker::~LayoutInsideListMarker() = default;
+
+} // namespace blink
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
new file mode 100644
index 00000000000..22426dfdec1
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/layout_inside_list_marker.h
@@ -0,0 +1,33 @@
+// 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_INSIDE_LIST_MARKER_H_
+#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"
+
+namespace blink {
+
+// Used to layout the list item's inside marker.
+// The LayoutInsideListMarker always has to be a child of a LayoutListItem.
+class CORE_EXPORT LayoutInsideListMarker final : public LayoutListMarker {
+ public:
+ explicit LayoutInsideListMarker(Element*);
+ ~LayoutInsideListMarker() override;
+
+ const char* GetName() const override { return "LayoutInsideListMarker"; }
+
+ private:
+ bool IsOfType(LayoutObjectType type) const override {
+ return type == kLayoutObjectInsideListMarker ||
+ LayoutListMarker::IsOfType(type);
+ }
+};
+
+DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutInsideListMarker, IsInsideListMarker());
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_INSIDE_LIST_MARKER_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_list_box.cc b/chromium/third_party/blink/renderer/core/layout/layout_list_box.cc
deleted file mode 100644
index 1e9c1061abc..00000000000
--- a/chromium/third_party/blink/renderer/core/layout/layout_list_box.cc
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved.
- * 2009 Torch Mobile Inc. All rights reserved.
- * (http://www.torchmobile.com/)
- *
- * 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.
- */
-
-#include "third_party/blink/renderer/core/layout/layout_list_box.h"
-
-#include "third_party/blink/public/platform/web_scroll_into_view_params.h"
-#include "third_party/blink/renderer/core/dom/element_traversal.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/html_select_element.h"
-#include "third_party/blink/renderer/core/html/html_div_element.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/scroll/scroll_alignment.h"
-#include "third_party/blink/renderer/core/scroll/scroll_types.h"
-
-namespace blink {
-
-// Default size when the multiple attribute is present but size attribute is
-// absent.
-const int kDefaultSize = 4;
-
-const int kDefaultPaddingBottom = 1;
-
-LayoutListBox::LayoutListBox(Element* element) : LayoutBlockFlow(element) {
- DCHECK(element);
- DCHECK(element->IsHTMLElement());
- DCHECK(IsA<HTMLSelectElement>(element));
-}
-
-LayoutListBox::~LayoutListBox() = default;
-
-inline HTMLSelectElement* LayoutListBox::SelectElement() const {
- return To<HTMLSelectElement>(GetNode());
-}
-
-unsigned LayoutListBox::size() const {
- unsigned specified_size = SelectElement()->size();
- if (specified_size >= 1)
- return specified_size;
-
- return kDefaultSize;
-}
-
-LayoutUnit LayoutListBox::DefaultItemHeight() const {
- const SimpleFontData* font_data = StyleRef().GetFont().PrimaryFont();
- if (!font_data)
- return LayoutUnit();
- return LayoutUnit(font_data->GetFontMetrics().Height() +
- kDefaultPaddingBottom);
-}
-
-LayoutUnit LayoutListBox::ItemHeight() const {
- // If the intrinsic-inline-size is specified, then we shouldn't ever need to
- // get the ItemHeight.
- DCHECK(!HasOverrideIntrinsicContentLogicalHeight());
-
- HTMLSelectElement* select = SelectElement();
- if (!select)
- return LayoutUnit();
-
- const auto& items = select->GetListItems();
- if (items.IsEmpty() || ShouldApplySizeContainment())
- return DefaultItemHeight();
-
- LayoutUnit max_height;
- for (Element* element : items) {
- if (auto* optgroup = DynamicTo<HTMLOptGroupElement>(element))
- element = &optgroup->OptGroupLabelElement();
- LayoutObject* layout_object = element->GetLayoutObject();
- LayoutUnit item_height;
- if (layout_object && layout_object->IsBox())
- item_height = ToLayoutBox(layout_object)->Size().Height();
- else
- item_height = DefaultItemHeight();
- max_height = std::max(max_height, item_height);
- }
- return max_height;
-}
-
-void LayoutListBox::ComputeLogicalHeight(
- LayoutUnit,
- LayoutUnit logical_top,
- LogicalExtentComputedValues& computed_values) const {
- LayoutUnit height;
- if (HasOverrideIntrinsicContentLogicalHeight()) {
- height = OverrideIntrinsicContentLogicalHeight();
- } else {
- height = ItemHeight() * size();
- }
-
- // FIXME: The item height should have been added before updateLogicalHeight
- // was called to avoid this hack.
- SetIntrinsicContentLogicalHeight(height);
-
- height += BorderAndPaddingHeight();
-
- LayoutBox::ComputeLogicalHeight(height, logical_top, computed_values);
-}
-
-void LayoutListBox::StopAutoscroll() {
- HTMLSelectElement* select = SelectElement();
- if (select->IsDisabledFormControl())
- return;
- select->HandleMouseRelease();
-}
-
-void LayoutListBox::ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const {
- LayoutBlockFlow::ComputeIntrinsicLogicalWidths(min_logical_width,
- max_logical_width);
- if (StyleRef().Width().IsPercentOrCalc())
- min_logical_width = LayoutUnit();
-}
-
-void LayoutListBox::ScrollToRect(const PhysicalRect& absolute_rect) {
- if (HasOverflowClip()) {
- DCHECK(Layer());
- DCHECK(Layer()->GetScrollableArea());
- Layer()->GetScrollableArea()->ScrollIntoView(
- absolute_rect, WebScrollIntoViewParams(
- ScrollAlignment::kAlignToEdgeIfNeeded,
- ScrollAlignment::kAlignToEdgeIfNeeded,
- kProgrammaticScroll, false, kScrollBehaviorInstant));
- }
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_list_box.h b/chromium/third_party/blink/renderer/core/layout/layout_list_box.h
deleted file mode 100644
index 91e76c1b097..00000000000
--- a/chromium/third_party/blink/renderer/core/layout/layout_list_box.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * This file is part of the select element layoutObject in WebCore.
- *
- * Copyright (C) 2006, 2007, 2009 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.
- * 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.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_LIST_BOX_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_LIST_BOX_H_
-
-#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
-
-namespace blink {
-
-class HTMLSelectElement;
-
-class CORE_EXPORT LayoutListBox final : public LayoutBlockFlow {
- public:
- explicit LayoutListBox(Element*);
- ~LayoutListBox() override;
-
- unsigned size() const;
-
- // Unlike scrollRectToVisible this will not scroll parent boxes.
- void ScrollToRect(const PhysicalRect&);
-
- const char* GetName() const override { return "LayoutListBox"; }
-
- private:
- HTMLSelectElement* SelectElement() const;
-
- bool IsOfType(LayoutObjectType type) const override {
- return type == kLayoutObjectListBox || LayoutBlockFlow::IsOfType(type);
- }
-
- void ComputeLogicalHeight(LayoutUnit logical_height,
- LayoutUnit logical_top,
- LogicalExtentComputedValues&) const override;
- void ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const override;
-
- void StopAutoscroll() override;
-
- LayoutUnit DefaultItemHeight() const;
- LayoutUnit ItemHeight() const;
-};
-
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutListBox, IsListBox());
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_LIST_BOX_H_
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 6f882e11a4a..df0dd904451 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
@@ -36,7 +36,6 @@ namespace blink {
LayoutListItem::LayoutListItem(Element* element)
: LayoutBlockFlow(element),
- marker_(nullptr),
need_block_direction_align_(false) {
SetInline(false);
@@ -51,13 +50,7 @@ void LayoutListItem::StyleDidChange(StyleDifference diff,
StyleImage* current_image = StyleRef().ListStyleImage();
if (StyleRef().ListStyleType() != EListStyleType::kNone ||
(current_image && !current_image->ErrorOccurred())) {
- if (!marker_)
- marker_ = LayoutListMarker::CreateAnonymous(this);
- marker_->ListItemStyleDidChange();
NotifyOfSubtreeChange();
- } else if (marker_) {
- marker_->Destroy();
- marker_ = nullptr;
}
StyleImage* old_image = old_style ? old_style->ListStyleImage() : nullptr;
@@ -70,11 +63,6 @@ void LayoutListItem::StyleDidChange(StyleDifference diff,
}
void LayoutListItem::WillBeDestroyed() {
- if (marker_) {
- marker_->Destroy();
- marker_ = nullptr;
- }
-
LayoutBlockFlow::WillBeDestroyed();
if (Style() && StyleRef().ListStyleImage())
@@ -94,7 +82,8 @@ void LayoutListItem::WillBeRemovedFromTree() {
}
void LayoutListItem::SubtreeDidChange() {
- if (!marker_)
+ LayoutListMarker* marker = Marker();
+ if (!marker)
return;
if (!UpdateMarkerLocation())
@@ -102,8 +91,8 @@ void LayoutListItem::SubtreeDidChange() {
// If the marker is inside we need to redo the preferred width calculations
// as the size of the item now includes the size of the list marker.
- if (marker_->IsInside())
- SetPreferredLogicalWidthsDirty();
+ if (marker->IsInsideListMarker())
+ SetIntrinsicLogicalWidthsDirty();
}
int LayoutListItem::Value() const {
@@ -112,13 +101,12 @@ int LayoutListItem::Value() const {
}
bool LayoutListItem::IsEmpty() const {
- return LastChild() == marker_;
+ return LastChild() == Marker();
}
namespace {
-LayoutObject* GetParentOfFirstLineBox(LayoutBlockFlow* curr,
- LayoutObject* marker) {
+LayoutObject* GetParentOfFirstLineBox(LayoutBlockFlow* curr) {
LayoutObject* first_child = curr->FirstChild();
if (!first_child)
return nullptr;
@@ -126,7 +114,7 @@ LayoutObject* GetParentOfFirstLineBox(LayoutBlockFlow* curr,
bool in_quirks_mode = curr->GetDocument().InQuirksMode();
for (LayoutObject* curr_child = first_child; curr_child;
curr_child = curr_child->NextSibling()) {
- if (curr_child == marker)
+ if (curr_child->IsOutsideListMarker())
continue;
if (curr_child->IsInline() &&
@@ -150,7 +138,7 @@ LayoutObject* GetParentOfFirstLineBox(LayoutBlockFlow* curr,
IsA<HTMLOListElement>(*curr_child->GetNode())))
break;
- LayoutObject* line_box = GetParentOfFirstLineBox(child_block_flow, marker);
+ LayoutObject* line_box = GetParentOfFirstLineBox(child_block_flow);
if (line_box)
return line_box;
}
@@ -186,21 +174,27 @@ void ForceLogicalHeight(LayoutObject& layout_object, const Length& height) {
// marker_container to 0px; else restore it to LogicalHeight of <li>.
bool LayoutListItem::PrepareForBlockDirectionAlign(
const LayoutObject* line_box_parent) {
- LayoutObject* marker_parent = marker_->Parent();
+ LayoutListMarker* marker = Marker();
+ LayoutObject* marker_parent = marker->Parent();
+ bool is_inside = marker->IsInsideListMarker();
// Deal with the situation of layout tree changed.
if (marker_parent && marker_parent->IsAnonymous()) {
+ bool marker_parent_has_lines =
+ line_box_parent && line_box_parent->IsDescendantOf(marker_parent);
// When list-position-style change from outside to inside, we need to
- // restore LogicalHeight to auto. So add IsInside().
- if (marker_->IsInside() || marker_->NextSibling()) {
+ // restore LogicalHeight to auto. So add is_inside.
+ if (is_inside || marker_parent_has_lines) {
// Set marker_container's LogicalHeight to auto.
if (marker_parent->StyleRef().LogicalHeight().IsZero())
ForceLogicalHeight(*marker_parent, Length());
- // If marker_parent isn't the ancestor of line_box_parent, marker might
- // generate a new empty line. We need to remove marker here.E.g:
- // <li><span><div>text<div><span></li>
- if (line_box_parent && !line_box_parent->IsDescendantOf(marker_parent)) {
- marker_->Remove();
+ // If marker_parent_has_lines and the marker is outside, we need to move
+ // the marker into another parent with 'height: 0' to avoid generating a
+ // new empty line in cases like <li><span><div>text<div><span></li>
+ // If the marker is inside and there are inline contents, we want them to
+ // share the same block container to avoid a line break between them.
+ if (is_inside != marker_parent_has_lines) {
+ marker->Remove();
marker_parent = nullptr;
}
} else if (line_box_parent) {
@@ -211,19 +205,18 @@ bool LayoutListItem::PrepareForBlockDirectionAlign(
// Create marker_container, set its height to 0px, and add it to li.
if (!marker_parent) {
LayoutObject* before_child = FirstNonMarkerChild(this);
- if (!marker_->IsInside() && before_child && !before_child->IsInline()) {
+ if (!is_inside && before_child && !before_child->IsInline()) {
// Create marker_container and set its LogicalHeight to 0px.
LayoutBlock* marker_container = CreateAnonymousBlock();
if (line_box_parent)
ForceLogicalHeight(*marker_container, Length::Fixed(0));
- marker_container->AddChild(marker_,
- FirstNonMarkerChild(marker_container));
+ marker_container->AddChild(marker, FirstNonMarkerChild(marker_container));
AddChild(marker_container, before_child);
} else {
- AddChild(marker_, before_child);
+ AddChild(marker, before_child);
}
- marker_->UpdateMarginsAndContent();
+ marker->UpdateMarginsAndContent();
return true;
}
return false;
@@ -241,13 +234,24 @@ static bool IsFirstLeafChild(LayoutObject* container, LayoutObject* child) {
}
bool LayoutListItem::UpdateMarkerLocation() {
- DCHECK(marker_);
+ DCHECK(Marker());
- LayoutObject* marker_parent = marker_->Parent();
+ LayoutListMarker* marker = Marker();
+ LayoutObject* marker_parent = marker->Parent();
LayoutObject* line_box_parent = nullptr;
- if (!marker_->IsInside())
- line_box_parent = GetParentOfFirstLineBox(this, marker_);
+ // Make sure a marker originated by a ::before or ::after precedes the
+ // generated contents.
+ if (IsPseudoElement()) {
+ LayoutObject* first_child = marker_parent->SlowFirstChild();
+ if (marker != first_child) {
+ marker->Remove();
+ AddChild(marker, first_child);
+ }
+ }
+
+ if (marker->IsOutsideListMarker())
+ line_box_parent = GetParentOfFirstLineBox(this);
if (line_box_parent && (line_box_parent->HasOverflowClip() ||
!line_box_parent->IsLayoutBlockFlow() ||
(line_box_parent->IsBox() &&
@@ -277,13 +281,13 @@ bool LayoutListItem::UpdateMarkerLocation() {
if (!marker_parent ||
(marker_parent != line_box_parent && NormalChildNeedsLayout())) {
- marker_->Remove();
- line_box_parent->AddChild(marker_, FirstNonMarkerChild(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
// AddChild, so they are not safe to reference here. Once we have a safe way
// of referencing them delete marker_parent if it is an empty anonymous
// block.
- marker_->UpdateMarginsAndContent();
+ marker->UpdateMarginsAndContent();
return true;
}
@@ -309,6 +313,7 @@ void LayoutListItem::ComputeVisualOverflow(bool recompute_floats) {
AddVisualOverflowFromFloats();
if (VisualOverflowRect() != previous_visual_overflow_rect) {
+ InvalidateIntersectionObserverCachedRects();
SetShouldCheckForPaintInvalidation();
GetFrameView()->SetIntersectionObservationState(LocalFrameView::kDesired);
}
@@ -327,7 +332,8 @@ void LayoutListItem::AlignMarkerInBlockDirection() {
// layout pass. So if there's no line box in line_box_parent make sure it
// back to its original position.
bool back_to_original_baseline = false;
- LayoutObject* line_box_parent = GetParentOfFirstLineBox(this, marker_);
+ LayoutListMarker* marker = Marker();
+ LayoutObject* line_box_parent = GetParentOfFirstLineBox(this);
LayoutBox* line_box_parent_block = nullptr;
if (!line_box_parent || !line_box_parent->IsBox()) {
back_to_original_baseline = true;
@@ -339,12 +345,12 @@ void LayoutListItem::AlignMarkerInBlockDirection() {
back_to_original_baseline = true;
}
- InlineBox* marker_inline_box = marker_->InlineBoxWrapper();
+ InlineBox* marker_inline_box = marker->InlineBoxWrapper();
RootInlineBox& marker_root = marker_inline_box->Root();
auto* line_box_parent_block_flow =
DynamicTo<LayoutBlockFlow>(line_box_parent_block);
if (line_box_parent_block && line_box_parent_block_flow) {
- // If marker_ and line_box_parent_block share a same RootInlineBox, no need
+ // If marker and line_box_parent_block share a same RootInlineBox, no need
// to align marker.
if (line_box_parent_block_flow->FirstRootBox() == &marker_root)
return;
@@ -355,7 +361,7 @@ void LayoutListItem::AlignMarkerInBlockDirection() {
offset = line_box_parent_block->FirstLineBoxBaseline();
if (back_to_original_baseline || offset == -1) {
- line_box_parent_block = marker_->ContainingBlock();
+ line_box_parent_block = marker->ContainingBlock();
offset = line_box_parent_block->FirstLineBoxBaseline();
}
@@ -369,11 +375,11 @@ void LayoutListItem::AlignMarkerInBlockDirection() {
// instead. BaselinePosition is workable when marker is an image.
// However, when marker is text, BaselinePosition contains lineheight
// information. So use marker_font_metrics.Ascent when marker is text.
- if (marker_->IsImage()) {
+ if (marker->IsImage()) {
offset -= marker_inline_box->BaselinePosition(marker_root.BaselineType());
} else {
const SimpleFontData* marker_font_data =
- marker_->Style(true)->GetFont().PrimaryFont();
+ marker->Style(true)->GetFont().PrimaryFont();
if (marker_font_data) {
const FontMetrics& marker_font_metrics =
marker_font_data->GetFontMetrics();
@@ -382,7 +388,7 @@ void LayoutListItem::AlignMarkerInBlockDirection() {
}
offset -= marker_inline_box->LogicalTop();
- for (LayoutBox* o = marker_->ParentBox(); o != this; o = o->ParentBox()) {
+ for (LayoutBox* o = marker->ParentBox(); o != this; o = o->ParentBox()) {
offset -= o->LogicalTop();
}
@@ -392,24 +398,25 @@ void LayoutListItem::AlignMarkerInBlockDirection() {
}
void LayoutListItem::UpdateOverflow() {
- if (!marker_ || !marker_->Parent() || !marker_->Parent()->IsBox() ||
- marker_->IsInside() || !marker_->InlineBoxWrapper())
+ LayoutListMarker* marker = Marker();
+ if (!marker || !marker->Parent() || !marker->Parent()->IsBox() ||
+ marker->IsInsideListMarker() || !marker->InlineBoxWrapper())
return;
if (need_block_direction_align_)
AlignMarkerInBlockDirection();
- LayoutUnit marker_old_logical_left = marker_->LogicalLeft();
+ LayoutUnit marker_old_logical_left = marker->LogicalLeft();
LayoutUnit block_offset;
LayoutUnit line_offset;
- for (LayoutBox* o = marker_->ParentBox(); o != this; o = o->ParentBox()) {
+ for (LayoutBox* o = marker->ParentBox(); o != this; o = o->ParentBox()) {
block_offset += o->LogicalTop();
line_offset += o->LogicalLeft();
}
bool adjust_overflow = false;
LayoutUnit marker_logical_left;
- InlineBox* marker_inline_box = marker_->InlineBoxWrapper();
+ InlineBox* marker_inline_box = marker->InlineBoxWrapper();
RootInlineBox& root = marker_inline_box->Root();
bool hit_self_painting_layer = false;
@@ -427,11 +434,11 @@ void LayoutListItem::UpdateOverflow() {
// FIXME: Need to account for relative positioning in the layout overflow.
if (StyleRef().IsLeftToRightDirection()) {
LayoutUnit marker_line_offset =
- std::min(marker_->LineOffset(),
- LogicalLeftOffsetForLine(marker_->LogicalTop(),
+ std::min(marker->LineOffset(),
+ LogicalLeftOffsetForLine(marker->LogicalTop(),
kDoNotIndentText, LayoutUnit()));
marker_logical_left = marker_line_offset - line_offset - PaddingStart() -
- BorderStart() + marker_->MarginStart();
+ BorderStart() + marker->MarginStart();
marker_inline_box->MoveInInlineDirection(marker_logical_left -
marker_old_logical_left);
@@ -468,11 +475,11 @@ void LayoutListItem::UpdateOverflow() {
}
} else {
LayoutUnit marker_line_offset =
- std::max(marker_->LineOffset(),
- LogicalRightOffsetForLine(marker_->LogicalTop(),
+ std::max(marker->LineOffset(),
+ LogicalRightOffsetForLine(marker->LogicalTop(),
kDoNotIndentText, LayoutUnit()));
marker_logical_left = marker_line_offset - line_offset + PaddingStart() +
- BorderStart() + marker_->MarginEnd();
+ BorderStart() + marker->MarginEnd();
marker_inline_box->MoveInInlineDirection(marker_logical_left -
marker_old_logical_left);
@@ -482,11 +489,11 @@ void LayoutListItem::UpdateOverflow() {
box->AddReplacedChildrenVisualOverflow(line_top, line_bottom);
LayoutRect new_logical_visual_overflow_rect =
box->LogicalVisualOverflowRect(line_top, line_bottom);
- if (marker_logical_left + marker_->LogicalWidth() >
+ if (marker_logical_left + marker->LogicalWidth() >
new_logical_visual_overflow_rect.MaxX() &&
!hit_self_painting_layer) {
new_logical_visual_overflow_rect.SetWidth(
- marker_logical_left + marker_->LogicalWidth() -
+ marker_logical_left + marker->LogicalWidth() -
new_logical_visual_overflow_rect.X());
if (box == root)
adjust_overflow = true;
@@ -498,10 +505,10 @@ void LayoutListItem::UpdateOverflow() {
hit_self_painting_layer = true;
LayoutRect new_logical_layout_overflow_rect =
box->LogicalLayoutOverflowRect(line_top, line_bottom);
- if (marker_logical_left + marker_->LogicalWidth() >
+ if (marker_logical_left + marker->LogicalWidth() >
new_logical_layout_overflow_rect.MaxX()) {
new_logical_layout_overflow_rect.SetWidth(
- marker_logical_left + marker_->LogicalWidth() -
+ marker_logical_left + marker->LogicalWidth() -
new_logical_layout_overflow_rect.X());
if (box == root)
adjust_overflow = true;
@@ -518,10 +525,10 @@ void LayoutListItem::UpdateOverflow() {
LayoutRect marker_rect(
LayoutPoint(marker_logical_left + line_offset,
block_offset + marker_inline_box->LogicalTop()),
- marker_->Size());
+ marker->Size());
if (!StyleRef().IsHorizontalWritingMode())
marker_rect = marker_rect.TransposedRect();
- LayoutBox* object = marker_;
+ LayoutBox* object = marker;
bool found_self_painting_layer = false;
do {
@@ -549,16 +556,16 @@ void LayoutListItem::Paint(const PaintInfo& paint_info) const {
}
const String& LayoutListItem::MarkerText() const {
- if (marker_)
- return marker_->GetText();
+ if (LayoutListMarker* marker = Marker())
+ return marker->GetText();
return g_null_atom.GetString();
}
void LayoutListItem::OrdinalValueChanged() {
- if (!marker_)
- return;
- marker_->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
- layout_invalidation_reason::kListValueChange);
+ if (LayoutListMarker* marker = Marker()) {
+ marker->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
+ layout_invalidation_reason::kListValueChange);
+ }
}
} // namespace blink
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 3984e8ddabc..b324ba8020a 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
@@ -26,11 +26,10 @@
#include "third_party/blink/renderer/core/html/list_item_ordinal.h"
#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
+#include "third_party/blink/renderer/core/layout/layout_list_marker.h"
namespace blink {
-class LayoutListMarker;
-
class LayoutListItem final : public LayoutBlockFlow {
public:
explicit LayoutListItem(Element*);
@@ -41,7 +40,16 @@ class LayoutListItem final : public LayoutBlockFlow {
bool IsEmpty() const;
- LayoutListMarker* Marker() const { return marker_; }
+ LayoutListMarker* Marker() const {
+ Element* list_item = To<Element>(GetNode());
+ if (LayoutObject* marker =
+ list_item->PseudoElementLayoutObject(kPseudoIdMarker)) {
+ if (marker->IsListMarker())
+ return ToLayoutListMarker(marker);
+ NOTREACHED();
+ }
+ return nullptr;
+ }
ListItemOrdinal& Ordinal() { return ordinal_; }
void OrdinalValueChanged();
@@ -80,7 +88,6 @@ class LayoutListItem final : public LayoutBlockFlow {
bool PrepareForBlockDirectionAlign(const LayoutObject*);
ListItemOrdinal ordinal_;
- LayoutListMarker* marker_;
bool need_block_direction_align_;
};
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 7af899cd5b2..0425425e887 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
@@ -41,8 +41,8 @@ const int kCMarkerPaddingPx = 7;
// Recommended UA margin for list markers.
const int kCUAMarkerMarginEm = 1;
-LayoutListMarker::LayoutListMarker(LayoutListItem* item)
- : LayoutBox(nullptr), list_item_(item), line_offset_() {
+LayoutListMarker::LayoutListMarker(Element* element) : LayoutBox(element) {
+ DCHECK(ListItem());
SetInline(true);
SetIsAtomicInlineLevel(true);
}
@@ -55,11 +55,11 @@ void LayoutListMarker::WillBeDestroyed() {
LayoutBox::WillBeDestroyed();
}
-LayoutListMarker* LayoutListMarker::CreateAnonymous(LayoutListItem* item) {
- Document& document = item->GetDocument();
- LayoutListMarker* layout_object = new LayoutListMarker(item);
- layout_object->SetDocumentForAnonymous(&document);
- return layout_object;
+const LayoutListItem* LayoutListMarker::ListItem() const {
+ LayoutObject* list_item = GetNode()->parentNode()->GetLayoutObject();
+ DCHECK(list_item);
+ DCHECK(list_item->IsListItem());
+ return ToLayoutListItem(list_item);
}
LayoutSize LayoutListMarker::ImageBulletSize() const {
@@ -77,7 +77,8 @@ LayoutSize LayoutListMarker::ImageBulletSize() const {
font_data->GetFontMetrics().Ascent() / LayoutUnit(2);
return RoundedLayoutSize(
image_->ImageSize(GetDocument(), StyleRef().EffectiveZoom(),
- LayoutSize(bullet_width, bullet_width)));
+ LayoutSize(bullet_width, bullet_width),
+ LayoutObject::ShouldRespectImageOrientation(this)));
}
void LayoutListMarker::StyleWillChange(StyleDifference diff,
@@ -88,7 +89,7 @@ void LayoutListMarker::StyleWillChange(StyleDifference diff,
(new_style.ListStyleType() == EListStyleType::kString &&
new_style.ListStyleStringValue() !=
StyleRef().ListStyleStringValue()))) {
- SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kStyleChange);
}
@@ -127,14 +128,15 @@ void LayoutListMarker::UpdateLayout() {
LayoutAnalyzer::Scope analyzer(*this);
LayoutUnit block_offset = LogicalTop();
- for (LayoutBox* o = ParentBox(); o && o != ListItem(); o = o->ParentBox()) {
+ const LayoutListItem* list_item = ListItem();
+ for (LayoutBox* o = ParentBox(); o && o != list_item; o = o->ParentBox()) {
block_offset += o->LogicalTop();
}
- if (ListItem()->StyleRef().IsLeftToRightDirection()) {
- line_offset_ = ListItem()->LogicalLeftOffsetForLine(
+ if (list_item->StyleRef().IsLeftToRightDirection()) {
+ line_offset_ = list_item->LogicalLeftOffsetForLine(
block_offset, kDoNotIndentText, LayoutUnit());
} else {
- line_offset_ = ListItem()->LogicalRightOffsetForLine(
+ line_offset_ = list_item->LogicalRightOffsetForLine(
block_offset, kDoNotIndentText, LayoutUnit());
}
if (IsImage()) {
@@ -145,21 +147,11 @@ void LayoutListMarker::UpdateLayout() {
} else {
const SimpleFontData* font_data = StyleRef().GetFont().PrimaryFont();
DCHECK(font_data);
- SetLogicalWidth(MinPreferredLogicalWidth());
+ SetLogicalWidth(PreferredLogicalWidths().min_size);
SetLogicalHeight(
LayoutUnit(font_data ? font_data->GetFontMetrics().Height() : 0));
}
- SetMarginStart(LayoutUnit());
- SetMarginEnd(LayoutUnit());
-
- const Length& start_margin = StyleRef().MarginStart();
- const Length& end_margin = StyleRef().MarginEnd();
- if (start_margin.IsFixed())
- SetMarginStart(LayoutUnit(start_margin.Value()));
- if (end_margin.IsFixed())
- SetMarginEnd(LayoutUnit(end_margin.Value()));
-
ClearNeedsLayout();
}
@@ -171,7 +163,7 @@ void LayoutListMarker::ImageChanged(WrappedImagePtr o, CanDeferInvalidation) {
LayoutSize image_size = IsImage() ? ImageBulletSize() : LayoutSize();
if (Size() != image_size || image_->ErrorOccurred()) {
- SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kImageChanged);
} else {
SetShouldDoFullPaintInvalidation();
@@ -179,14 +171,11 @@ void LayoutListMarker::ImageChanged(WrappedImagePtr o, CanDeferInvalidation) {
}
void LayoutListMarker::UpdateMarginsAndContent() {
- if (PreferredLogicalWidthsDirty())
- ComputePreferredLogicalWidths();
- else
- UpdateMargins();
+ UpdateMargins(PreferredLogicalWidths().min_size);
}
void LayoutListMarker::UpdateContent() {
- DCHECK(PreferredLogicalWidthsDirty());
+ DCHECK(IntrinsicLogicalWidthsDirty());
text_ = "";
@@ -202,7 +191,7 @@ void LayoutListMarker::UpdateContent() {
break;
case ListStyleCategory::kLanguage:
text_ = list_marker_text::GetText(StyleRef().ListStyleType(),
- list_item_->Value());
+ ListItem()->Value());
break;
case ListStyleCategory::kStaticString:
text_ = StyleRef().ListStyleStringValue();
@@ -214,7 +203,7 @@ String LayoutListMarker::TextAlternative() const {
if (GetListStyleCategory() == ListStyleCategory::kStaticString)
return text_;
UChar suffix =
- list_marker_text::Suffix(StyleRef().ListStyleType(), list_item_->Value());
+ list_marker_text::Suffix(StyleRef().ListStyleType(), ListItem()->Value());
// Return suffix after the marker text, even in RTL, reflecting speech order.
return text_ + suffix + ' ';
}
@@ -232,7 +221,7 @@ LayoutUnit LayoutListMarker::GetWidthOfText(ListStyleCategory category) const {
// TODO(wkorman): Look into constructing a text run for both text and suffix
// and painting them together.
UChar suffix[2] = {
- list_marker_text::Suffix(StyleRef().ListStyleType(), list_item_->Value()),
+ list_marker_text::Suffix(StyleRef().ListStyleType(), ListItem()->Value()),
' '};
TextRun run =
ConstructTextRun(font, suffix, 2, StyleRef(), StyleRef().Direction());
@@ -240,40 +229,36 @@ LayoutUnit LayoutListMarker::GetWidthOfText(ListStyleCategory category) const {
return item_width + suffix_space_width;
}
-void LayoutListMarker::ComputePreferredLogicalWidths() {
- DCHECK(PreferredLogicalWidthsDirty());
- UpdateContent();
+MinMaxSizes LayoutListMarker::ComputeIntrinsicLogicalWidths() const {
+ DCHECK(IntrinsicLogicalWidthsDirty());
+ const_cast<LayoutListMarker*>(this)->UpdateContent();
+ MinMaxSizes sizes;
if (IsImage()) {
LayoutSize image_size(ImageBulletSize());
- min_preferred_logical_width_ = max_preferred_logical_width_ =
- StyleRef().IsHorizontalWritingMode() ? image_size.Width()
- : image_size.Height();
- ClearPreferredLogicalWidthsDirty();
- UpdateMargins();
- return;
- }
-
- LayoutUnit logical_width;
- ListStyleCategory category = GetListStyleCategory();
- switch (category) {
- case ListStyleCategory::kNone:
- break;
- case ListStyleCategory::kSymbol:
- logical_width = WidthOfSymbol(StyleRef());
- break;
- case ListStyleCategory::kLanguage:
- case ListStyleCategory::kStaticString:
- logical_width = GetWidthOfText(category);
- break;
+ sizes = StyleRef().IsHorizontalWritingMode() ? image_size.Width()
+ : image_size.Height();
+ } else {
+ ListStyleCategory category = GetListStyleCategory();
+ switch (category) {
+ case ListStyleCategory::kNone:
+ break;
+ case ListStyleCategory::kSymbol:
+ sizes = WidthOfSymbol(StyleRef());
+ break;
+ case ListStyleCategory::kLanguage:
+ case ListStyleCategory::kStaticString:
+ sizes = GetWidthOfText(category);
+ break;
+ }
}
- min_preferred_logical_width_ = logical_width;
- max_preferred_logical_width_ = logical_width;
-
- ClearPreferredLogicalWidthsDirty();
+ const_cast<LayoutListMarker*>(this)->UpdateMargins(sizes.min_size);
+ return sizes;
+}
- UpdateMargins();
+MinMaxSizes LayoutListMarker::PreferredLogicalWidths() const {
+ return IntrinsicLogicalWidths();
}
LayoutUnit LayoutListMarker::WidthOfSymbol(const ComputedStyle& style) {
@@ -285,32 +270,27 @@ LayoutUnit LayoutListMarker::WidthOfSymbol(const ComputedStyle& style) {
return LayoutUnit((font_data->GetFontMetrics().Ascent() * 2 / 3 + 1) / 2 + 2);
}
-void LayoutListMarker::UpdateMargins() {
+void LayoutListMarker::UpdateMargins(LayoutUnit marker_inline_size) {
LayoutUnit margin_start;
LayoutUnit margin_end;
const ComputedStyle& style = StyleRef();
- if (IsInside()) {
+ if (IsInsideListMarker()) {
std::tie(margin_start, margin_end) =
InlineMarginsForInside(style, IsImage());
} else {
std::tie(margin_start, margin_end) =
- InlineMarginsForOutside(style, IsImage(), MinPreferredLogicalWidth());
+ InlineMarginsForOutside(style, IsImage(), marker_inline_size);
}
- Length start_length = Length::Fixed(margin_start);
- Length end_length = Length::Fixed(margin_end);
-
- if (start_length != style.MarginStart() || end_length != style.MarginEnd()) {
- scoped_refptr<ComputedStyle> new_style = ComputedStyle::Clone(style);
- new_style->SetMarginStart(start_length);
- new_style->SetMarginEnd(end_length);
- SetStyleInternal(std::move(new_style));
- }
+ 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())) {
@@ -329,51 +309,31 @@ std::pair<LayoutUnit, LayoutUnit> LayoutListMarker::InlineMarginsForOutside(
LayoutUnit marker_inline_size) {
LayoutUnit margin_start;
LayoutUnit margin_end;
- if (style.IsLeftToRightDirection()) {
- if (is_image) {
- margin_start = -marker_inline_size - 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);
- break;
- }
- default:
- margin_start = -marker_inline_size;
- }
- }
- margin_end = -margin_start - marker_inline_size;
+ if (!style.ContentBehavesAsNormal()) {
+ margin_start = -marker_inline_size;
+ } else if (is_image) {
+ margin_start = -marker_inline_size - kCMarkerPaddingPx;
+ margin_end = LayoutUnit(kCMarkerPaddingPx);
} else {
- if (is_image) {
- 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_end = offset + kCMarkerPaddingPx + 1 - marker_inline_size;
- break;
- }
- default:
- margin_end = LayoutUnit();
+ 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;
}
- margin_start = -margin_end - marker_inline_size;
}
+ DCHECK_EQ(margin_start + margin_end, -marker_inline_size);
return {margin_start, margin_end};
}
@@ -382,7 +342,7 @@ LayoutUnit LayoutListMarker::LineHeight(
LineDirectionMode direction,
LinePositionMode line_position_mode) const {
if (!IsImage())
- return list_item_->LineHeight(first_line, direction,
+ return ListItem()->LineHeight(first_line, direction,
kPositionOfInteriorLineBoxes);
return LayoutBox::LineHeight(first_line, direction, line_position_mode);
}
@@ -394,7 +354,7 @@ LayoutUnit LayoutListMarker::BaselinePosition(
LinePositionMode line_position_mode) const {
DCHECK_EQ(line_position_mode, kPositionOnContainingLine);
if (!IsImage())
- return list_item_->BaselinePosition(baseline_type, first_line, direction,
+ return ListItem()->BaselinePosition(baseline_type, first_line, direction,
kPositionOfInteriorLineBoxes);
return LayoutBox::BaselinePosition(baseline_type, first_line, direction,
line_position_mode);
@@ -475,11 +435,6 @@ LayoutListMarker::ListStyleCategory LayoutListMarker::GetListStyleCategory(
}
}
-bool LayoutListMarker::IsInside() const {
- return list_item_->Ordinal().NotInList() ||
- StyleRef().ListStylePosition() == EListStylePosition::kInside;
-}
-
LayoutRect LayoutListMarker::GetRelativeMarkerRect() const {
if (IsImage())
return LayoutRect(LayoutPoint(), ImageBulletSize());
@@ -535,31 +490,4 @@ LayoutRect LayoutListMarker::RelativeSymbolMarkerRect(
return relative_rect;
}
-void LayoutListMarker::ListItemStyleDidChange() {
- Node* list_item = list_item_->GetNode();
- const ComputedStyle* cached_marker_style =
- list_item->IsPseudoElement()
- ? nullptr
- : ToElement(list_item)->CachedStyleForPseudoElement(kPseudoIdMarker);
- scoped_refptr<ComputedStyle> new_style;
- if (cached_marker_style) {
- new_style = ComputedStyle::Clone(*cached_marker_style);
- } else {
- // The marker always inherits from the list item, regardless of where it
- // might end up (e.g., in some deeply nested line box). See CSS3 spec.
- new_style = ComputedStyle::Create();
- new_style->InheritFrom(list_item_->StyleRef());
- new_style->SetStyleType(kPseudoIdMarker);
- new_style->SetUnicodeBidi(UnicodeBidi::kIsolate);
- new_style->SetFontVariantNumericSpacing(FontVariantNumeric::kTabularNums);
- }
- if (Style()) {
- // Reuse the current margins. Otherwise resetting the margins to initial
- // values would trigger unnecessary layout.
- new_style->SetMarginStart(StyleRef().MarginStart());
- new_style->SetMarginEnd(StyleRef().MarginRight());
- }
- SetStyle(std::move(new_style));
-}
-
} // 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 68d1a290b0f..1fee564ee6e 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
@@ -31,11 +31,10 @@ namespace blink {
class LayoutListItem;
-// Used to layout the list item's marker.
-// The LayoutListMarker always has to be a child of a LayoutListItem.
-class CORE_EXPORT LayoutListMarker final : public LayoutBox {
+// This class holds code shared among legacy classes for list markers.
+class CORE_EXPORT LayoutListMarker : public LayoutBox {
public:
- static LayoutListMarker* CreateAnonymous(LayoutListItem*);
+ explicit LayoutListMarker(Element*);
~LayoutListMarker() override;
// Marker text without suffix, e.g. "1".
@@ -53,8 +52,6 @@ class CORE_EXPORT LayoutListMarker final : public LayoutBox {
ListStyleCategory GetListStyleCategory() const;
static ListStyleCategory GetListStyleCategory(EListStyleType);
- bool IsInside() const;
-
void UpdateMarginsAndContent();
// Compute inline margins for 'list-style-position: inside' and 'outside'.
@@ -72,26 +69,17 @@ class CORE_EXPORT LayoutListMarker final : public LayoutBox {
bool IsImage() const override;
const StyleImage* GetImage() const { return image_.Get(); }
- const LayoutListItem* ListItem() const { return list_item_; }
+ const LayoutListItem* ListItem() const;
LayoutSize ImageBulletSize() const;
- void ListItemStyleDidChange();
-
- const char* GetName() const override { return "LayoutListMarker"; }
-
LayoutUnit LineOffset() const { return line_offset_; }
protected:
void WillBeDestroyed() override;
private:
- LayoutListMarker(LayoutListItem*);
-
- void ComputePreferredLogicalWidths() override;
-
- bool IsOfType(LayoutObjectType type) const override {
- return type == kLayoutObjectListMarker || LayoutBox::IsOfType(type);
- }
+ MinMaxSizes ComputeIntrinsicLogicalWidths() const override;
+ MinMaxSizes PreferredLogicalWidths() const override;
void Paint(const PaintInfo&) const override;
@@ -114,21 +102,15 @@ class CORE_EXPORT LayoutListMarker final : public LayoutBox {
bool IsText() const { return !IsImage(); }
LayoutUnit GetWidthOfText(ListStyleCategory) const;
- void UpdateMargins();
+ void UpdateMargins(LayoutUnit marker_inline_size);
void UpdateContent();
void StyleWillChange(StyleDifference,
const ComputedStyle& new_style) override;
void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
- bool AnonymousHasStylePropagationOverride() override { return true; }
-
- bool PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const override {
- return false;
- }
String text_;
Persistent<StyleImage> image_;
- LayoutListItem* list_item_;
LayoutUnit line_offset_;
};
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_media.cc b/chromium/third_party/blink/renderer/core/layout/layout_media.cc
index 2764e0b773f..359dc680f00 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_media.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_media.cc
@@ -25,6 +25,7 @@
#include "third_party/blink/renderer/core/layout/layout_media.h"
+#include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink.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/html/media/html_media_element.h"
@@ -41,7 +42,7 @@ LayoutMedia::LayoutMedia(HTMLMediaElement* video) : LayoutImage(video) {
LayoutMedia::~LayoutMedia() = default;
HTMLMediaElement* LayoutMedia::MediaElement() const {
- return ToHTMLMediaElement(GetNode());
+ return To<HTMLMediaElement>(GetNode());
}
void LayoutMedia::UpdateLayout() {
@@ -154,9 +155,9 @@ LayoutUnit LayoutMedia::ComputePanelWidth(const LayoutRect& media_rect) const {
// TODO(crbug.com/771379): Once we no longer assume that the video is in the
// main frame for the visibility calculation below, we will only care about
// the video's frame's scrollbar check below.
- ScrollbarMode h_mode, v_mode;
+ mojom::blink::ScrollbarMode h_mode, v_mode;
page_view->GetLayoutView()->CalculateScrollbarModes(h_mode, v_mode);
- if (h_mode != ScrollbarMode::kAlwaysOff)
+ if (h_mode != mojom::blink::ScrollbarMode::kAlwaysOff)
return media_rect.Width();
// If the video's frame (can be different from main frame if video is in an
@@ -165,7 +166,7 @@ LayoutUnit LayoutMedia::ComputePanelWidth(const LayoutRect& media_rect) const {
LocalFrameView* media_page_view = media_frame ? media_frame->View() : nullptr;
if (media_page_view && media_page_view->GetLayoutView()) {
media_page_view->GetLayoutView()->CalculateScrollbarModes(h_mode, v_mode);
- if (h_mode != ScrollbarMode::kAlwaysOff)
+ if (h_mode != mojom::blink::ScrollbarMode::kAlwaysOff)
return media_rect.Width();
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_media.h b/chromium/third_party/blink/renderer/core/layout/layout_media.h
index 98d8a954ffb..d3032678339 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_media.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_media.h
@@ -89,8 +89,6 @@ class LayoutMedia : public LayoutImage {
LayoutObjectChildList children_;
};
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutMedia, IsMedia());
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_MEDIA_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_menu_list.cc b/chromium/third_party/blink/renderer/core/layout/layout_menu_list.cc
deleted file mode 100644
index d10d4e199cd..00000000000
--- a/chromium/third_party/blink/renderer/core/layout/layout_menu_list.cc
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * This file is part of the select element layoutObject in WebCore.
- *
- * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
- * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
- * All rights reserved.
- * (C) 2009 Torch Mobile Inc. All rights reserved.
- * (http://www.torchmobile.com/)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "third_party/blink/renderer/core/layout/layout_menu_list.h"
-
-#include <math.h>
-#include "third_party/blink/public/strings/grit/blink_strings.h"
-#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
-#include "third_party/blink/renderer/core/dom/node_computed_style.h"
-#include "third_party/blink/renderer/core/frame/local_frame_view.h"
-#include "third_party/blink/renderer/core/html/forms/html_option_element.h"
-#include "third_party/blink/renderer/core/html/forms/html_select_element.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/layout_theme.h"
-#include "third_party/blink/renderer/core/paint/paint_layer.h"
-#include "third_party/blink/renderer/platform/text/platform_locale.h"
-
-namespace blink {
-
-LayoutMenuList::LayoutMenuList(Element* element)
- : LayoutFlexibleBox(element),
- button_text_(nullptr),
- inner_block_(nullptr),
- is_empty_(false),
- has_updated_active_option_(false),
- inner_block_height_(LayoutUnit()),
- options_width_(0),
- last_active_index_(-1) {
- DCHECK(IsA<HTMLSelectElement>(element));
-}
-
-LayoutMenuList::~LayoutMenuList() = default;
-
-bool LayoutMenuList::IsChildAllowed(LayoutObject* object,
- const ComputedStyle&) const {
- // For a size=1 <select>, we only render the active option through the
- // anonymous inner_block_ plus button_text_. We do not allow adding layout
- // objects for options or optgroups.
- return object->IsAnonymous();
-}
-
-scoped_refptr<ComputedStyle> LayoutMenuList::CreateInnerStyle() {
- scoped_refptr<ComputedStyle> inner_style =
- ComputedStyle::CreateAnonymousStyleWithDisplay(StyleRef(),
- EDisplay::kBlock);
-
- AdjustInnerStyle(*inner_style);
- return inner_style;
-}
-
-void LayoutMenuList::UpdateInnerStyle() {
- DCHECK(inner_block_);
- scoped_refptr<ComputedStyle> inner_style =
- ComputedStyle::Clone(inner_block_->StyleRef());
- AdjustInnerStyle(*inner_style);
- inner_block_->SetModifiedStyleOutsideStyleRecalc(std::move(inner_style),
- ApplyStyleChanges::kNo);
- // LayoutMenuList::ControlClipRect() depends on inner_block_->ContentsSize().
- SetNeedsPaintPropertyUpdate();
- if (Layer())
- Layer()->SetNeedsCompositingInputsUpdate();
-}
-
-void LayoutMenuList::CreateInnerBlock() {
- if (inner_block_) {
- DCHECK_EQ(FirstChild(), inner_block_);
- DCHECK(!inner_block_->NextSibling());
- return;
- }
-
- // Create an anonymous block.
- LegacyLayout legacy =
- ForceLegacyLayout() ? LegacyLayout::kForce : LegacyLayout::kAuto;
- DCHECK(!FirstChild());
- inner_block_ = LayoutBlockFlow::CreateAnonymous(&GetDocument(),
- CreateInnerStyle(), legacy);
-
- button_text_ =
- LayoutText::CreateEmptyAnonymous(GetDocument(), Style(), legacy);
- // We need to set the text explicitly though it was specified in the
- // constructor because LayoutText doesn't refer to the text
- // specified in the constructor in a case of re-transforming.
- inner_block_->AddChild(button_text_);
- LayoutFlexibleBox::AddChild(inner_block_);
-
- // LayoutMenuList::ControlClipRect() depends on inner_block_->ContentsSize().
- SetNeedsPaintPropertyUpdate();
- if (Layer())
- Layer()->SetNeedsCompositingInputsUpdate();
-}
-
-bool LayoutMenuList::HasOptionStyleChanged(
- const ComputedStyle& inner_style) const {
- return option_style_ &&
- ((option_style_->Direction() != inner_style.Direction() ||
- option_style_->GetUnicodeBidi() != inner_style.GetUnicodeBidi()));
-}
-
-void LayoutMenuList::AdjustInnerStyle(ComputedStyle& inner_style) const {
- inner_style.SetFlexGrow(1);
- inner_style.SetFlexShrink(1);
- // min-width: 0; is needed for correct shrinking.
- inner_style.SetMinWidth(Length::Fixed(0));
-
- // 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
- // center.
- if (StyleRef().AlignItemsPosition() == ItemPosition::kCenter) {
- inner_style.SetMarginTop(Length());
- inner_style.SetMarginBottom(Length());
- inner_style.SetAlignSelfPosition(ItemPosition::kFlexStart);
- }
-
- Length padding_start = Length::Fixed(
- LayoutTheme::GetTheme().PopupInternalPaddingStart(StyleRef()));
- Length padding_end = Length::Fixed(
- LayoutTheme::GetTheme().PopupInternalPaddingEnd(GetFrame(), StyleRef()));
- inner_style.SetPaddingLeft(StyleRef().Direction() == TextDirection::kLtr
- ? padding_start
- : padding_end);
- inner_style.SetPaddingRight(StyleRef().Direction() == TextDirection::kLtr
- ? padding_end
- : padding_start);
- inner_style.SetPaddingTop(Length::Fixed(
- LayoutTheme::GetTheme().PopupInternalPaddingTop(StyleRef())));
- inner_style.SetPaddingBottom(Length::Fixed(
- LayoutTheme::GetTheme().PopupInternalPaddingBottom(StyleRef())));
- inner_style.SetTextAlign(StyleRef().IsLeftToRightDirection()
- ? ETextAlign::kLeft
- : ETextAlign::kRight);
-
- if (HasOptionStyleChanged(inner_style)) {
- inner_block_->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
- layout_invalidation_reason::kStyleChange);
- inner_style.SetDirection(option_style_->Direction());
- inner_style.SetUnicodeBidi(option_style_->GetUnicodeBidi());
- }
-}
-
-HTMLSelectElement* LayoutMenuList::SelectElement() const {
- return To<HTMLSelectElement>(GetNode());
-}
-
-void LayoutMenuList::AddChild(LayoutObject* new_child,
- LayoutObject* before_child) {
- inner_block_->AddChild(new_child, before_child);
- DCHECK_EQ(inner_block_, FirstChild());
-
- if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache())
- cache->ChildrenChanged(this);
-
- // LayoutMenuList::ControlClipRect() depends on inner_block_->ContentsSize().
- SetNeedsPaintPropertyUpdate();
- if (Layer())
- Layer()->SetNeedsCompositingInputsUpdate();
-}
-
-void LayoutMenuList::RemoveChild(LayoutObject* old_child) {
- if (old_child == inner_block_ || !inner_block_) {
- LayoutFlexibleBox::RemoveChild(old_child);
- inner_block_ = nullptr;
- } else {
- inner_block_->RemoveChild(old_child);
- }
-}
-
-void LayoutMenuList::StyleDidChange(StyleDifference diff,
- const ComputedStyle* old_style) {
- LayoutBlock::StyleDidChange(diff, old_style);
-
- if (!inner_block_)
- CreateInnerBlock();
-
- button_text_->SetStyle(Style());
- UpdateInnerStyle();
- UpdateInnerBlockHeight();
-}
-
-void LayoutMenuList::UpdateInnerBlockHeight() {
- const SimpleFontData* font_data = StyleRef().GetFont().PrimaryFont();
- DCHECK(font_data);
- inner_block_height_ = (font_data ? font_data->GetFontMetrics().Height() : 0) +
- inner_block_->BorderAndPaddingHeight();
-}
-
-void LayoutMenuList::UpdateOptionsWidth() const {
- if (ShouldApplySizeContainment()) {
- options_width_ = 0;
- return;
- }
-
- float max_option_width = 0;
-
- for (auto* const option : SelectElement()->GetOptionList()) {
- String text = option->TextIndentedToRespectGroupLabel();
- const ComputedStyle* item_style =
- option->GetComputedStyle() ? option->GetComputedStyle() : Style();
- item_style->ApplyTextTransform(&text);
- // We apply SELECT's style, not OPTION's style because m_optionsWidth is
- // used to determine intrinsic width of the menulist box.
- TextRun text_run = ConstructTextRun(StyleRef().GetFont(), text, *Style());
- max_option_width =
- std::max(max_option_width, StyleRef().GetFont().Width(text_run));
- }
- options_width_ = static_cast<int>(ceilf(max_option_width));
-}
-
-void LayoutMenuList::UpdateFromElement() {
- HTMLSelectElement* select = SelectElement();
- HTMLOptionElement* option = select->OptionToBeShown();
- String text = g_empty_string;
- option_style_ = nullptr;
-
- if (select->IsMultiple()) {
- unsigned selected_count = 0;
- HTMLOptionElement* selected_option_element = nullptr;
- for (auto* const option : select->GetOptionList()) {
- if (option->Selected()) {
- if (++selected_count == 1)
- selected_option_element = option;
- }
- }
-
- if (selected_count == 1) {
- text = selected_option_element->TextIndentedToRespectGroupLabel();
- option_style_ = selected_option_element->GetComputedStyle();
- } else {
- Locale& locale = select->GetLocale();
- String localized_number_string =
- locale.ConvertToLocalizedNumber(String::Number(selected_count));
- text = locale.QueryString(IDS_FORM_SELECT_MENU_LIST_TEXT,
- localized_number_string);
- DCHECK(!option_style_);
- }
- } else {
- if (option) {
- text = option->TextIndentedToRespectGroupLabel();
- option_style_ = option->GetComputedStyle();
- }
- }
-
- SetText(text.StripWhiteSpace());
-
- DidUpdateActiveOption(option);
-
- DCHECK(inner_block_);
- if (HasOptionStyleChanged(inner_block_->StyleRef()))
- UpdateInnerStyle();
-}
-
-void LayoutMenuList::SetText(const String& s) {
- if (s.IsEmpty()) {
- // FIXME: This is a hack. We need the select to have the same baseline
- // positioning as any surrounding text. Wihtout any content, we align the
- // bottom of the select to the bottom of the text. With content (In this
- // case the faked " ") we correctly align the middle of the select to the
- // middle of the text. It should be possible to remove this, just set
- // s.impl() into the text and have things align correctly...
- // crbug.com/485982
- is_empty_ = true;
- button_text_->ForceSetText(StringImpl::Create(" ", 1));
- } else {
- is_empty_ = false;
- button_text_->ForceSetText(s.Impl());
- }
- // LayoutMenuList::ControlClipRect() depends on inner_block_->ContentsSize().
- SetNeedsPaintPropertyUpdate();
- if (Layer())
- Layer()->SetNeedsCompositingInputsUpdate();
-}
-
-String LayoutMenuList::GetText() const {
- return button_text_ && !is_empty_ ? button_text_->GetText() : String();
-}
-
-PhysicalRect LayoutMenuList::ControlClipRect(
- const PhysicalOffset& additional_offset) const {
- // Clip to the intersection of the content box and the content box for the
- // inner box. This will leave room for the arrows which sit in the inner box
- // padding, and if the inner box ever spills out of the outer box, that will
- // get clipped too.
- PhysicalRect outer_box = PhysicalContentBoxRect();
- outer_box.offset += additional_offset;
-
- PhysicalRect inner_box(additional_offset + inner_block_->PhysicalLocation() +
- PhysicalOffset(inner_block_->PaddingLeft(),
- inner_block_->PaddingTop()),
- inner_block_->ContentSize());
-
- return Intersection(outer_box, inner_box);
-}
-
-void LayoutMenuList::ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const {
- UpdateOptionsWidth();
-
- max_logical_width =
- std::max(options_width_,
- LayoutTheme::GetTheme().MinimumMenuListSize(StyleRef())) +
- inner_block_->PaddingLeft() + inner_block_->PaddingRight();
- if (!StyleRef().Width().IsPercentOrCalc())
- min_logical_width = max_logical_width;
- else
- min_logical_width = LayoutUnit();
-}
-
-void LayoutMenuList::ComputeLogicalHeight(
- LayoutUnit logical_height,
- LayoutUnit logical_top,
- LogicalExtentComputedValues& computed_values) const {
- if (StyleRef().HasEffectiveAppearance())
- logical_height = inner_block_height_ + BorderAndPaddingHeight();
- LayoutBox::ComputeLogicalHeight(logical_height, logical_top, computed_values);
-}
-
-void LayoutMenuList::DidSelectOption(HTMLOptionElement* option) {
- DidUpdateActiveOption(option);
-}
-
-void LayoutMenuList::DidUpdateActiveOption(HTMLOptionElement* option) {
- if (!GetDocument().ExistingAXObjectCache())
- return;
-
- int option_index = option ? option->index() : -1;
- if (last_active_index_ == option_index)
- return;
- last_active_index_ = option_index;
-
- // We skip sending accessiblity notifications for the very first option,
- // otherwise we get extra focus and select events that are undesired.
- if (!has_updated_active_option_) {
- has_updated_active_option_ = true;
- return;
- }
-
- GetDocument().ExistingAXObjectCache()->HandleUpdateActiveMenuOption(
- this, option_index);
-}
-
-LayoutUnit LayoutMenuList::ClientPaddingLeft() const {
- return PaddingLeft() + inner_block_->PaddingLeft();
-}
-
-LayoutUnit LayoutMenuList::ClientPaddingRight() const {
- return PaddingRight() + inner_block_->PaddingRight();
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_menu_list.h b/chromium/third_party/blink/renderer/core/layout/layout_menu_list.h
deleted file mode 100644
index ba3a7d5a62d..00000000000
--- a/chromium/third_party/blink/renderer/core/layout/layout_menu_list.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * This file is part of the select element layoutObject in WebCore.
- *
- * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
- * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
- * All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_MENU_LIST_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_MENU_LIST_H_
-
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/layout/layout_flexible_box.h"
-#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
-
-namespace blink {
-
-class HTMLOptionElement;
-class HTMLSelectElement;
-class LayoutText;
-
-class CORE_EXPORT LayoutMenuList final : public LayoutFlexibleBox {
- public:
- explicit LayoutMenuList(Element*);
- ~LayoutMenuList() override;
-
- HTMLSelectElement* SelectElement() const;
- void DidSelectOption(HTMLOptionElement*);
- String GetText() const;
-
- const char* GetName() const override { return "LayoutMenuList"; }
-
- LayoutUnit ClientPaddingLeft() const;
- LayoutUnit ClientPaddingRight() const;
-
- private:
- bool IsOfType(LayoutObjectType type) const override {
- return type == kLayoutObjectMenuList || LayoutFlexibleBox::IsOfType(type);
- }
- bool IsChildAllowed(LayoutObject*, const ComputedStyle&) const override;
-
- void AddChild(LayoutObject* new_child,
- LayoutObject* before_child = nullptr) override;
- void RemoveChild(LayoutObject*) override;
- bool CreatesAnonymousWrapper() const override { return true; }
-
- void UpdateFromElement() override;
-
- PhysicalRect ControlClipRect(const PhysicalOffset&) const override;
- bool HasControlClip() const override { return true; }
-
- void ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const override;
- void ComputeLogicalHeight(LayoutUnit logical_height,
- LayoutUnit logical_top,
- LogicalExtentComputedValues&) const override;
-
- void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
-
- bool HasLineIfEmpty() const override { return true; }
-
- // Flexbox defines baselines differently than regular blocks.
- // For backwards compatibility, menulists need to do the regular block
- // behavior.
- LayoutUnit BaselinePosition(FontBaseline baseline,
- bool first_line,
- LineDirectionMode direction,
- LinePositionMode position) const override {
- return LayoutBlock::BaselinePosition(baseline, first_line, direction,
- position);
- }
- LayoutUnit FirstLineBoxBaseline() const override {
- return LayoutBlock::FirstLineBoxBaseline();
- }
- LayoutUnit InlineBlockBaseline(LineDirectionMode direction) const override {
- return LayoutBlock::InlineBlockBaseline(direction);
- }
-
- void CreateInnerBlock();
- scoped_refptr<ComputedStyle> CreateInnerStyle();
- void UpdateInnerStyle();
- void AdjustInnerStyle(ComputedStyle&) const;
- bool HasOptionStyleChanged(const ComputedStyle& inner_style) const;
- void SetText(const String&);
- void UpdateInnerBlockHeight();
- void UpdateOptionsWidth() const;
- void SetIndexToSelectOnCancel(int list_index);
-
- void DidUpdateActiveOption(HTMLOptionElement*);
-
- LayoutText* button_text_;
- LayoutBlock* inner_block_;
-
- bool is_empty_ : 1;
- bool has_updated_active_option_ : 1;
- LayoutUnit inner_block_height_;
- // m_optionsWidth is calculated and cached on demand.
- // updateOptionsWidth() should be called before reading them.
- mutable int options_width_;
-
- int last_active_index_;
-
- scoped_refptr<const ComputedStyle> option_style_;
-};
-
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutMenuList, IsMenuList());
-
-} // namespace blink
-
-#endif
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 9b7976066aa..2c6e4fc788e 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
@@ -332,7 +332,7 @@ LayoutUnit LayoutMultiColumnFlowThread::MaxColumnLogicalHeight() const {
const LayoutBlockFlow* multicol_block = MultiColumnBlockFlow();
const Length& logical_max_height =
multicol_block->StyleRef().LogicalMaxHeight();
- if (!logical_max_height.IsMaxSizeNone()) {
+ if (!logical_max_height.IsNone()) {
LayoutUnit resolved_logical_max_height =
multicol_block->ComputeContentLogicalHeight(
kMaxSize, logical_max_height, LayoutUnit(-1));
@@ -611,7 +611,7 @@ bool LayoutMultiColumnFlowThread::RemoveSpannerPlaceholderIfNoLongerValid(
// We may have a new containing block, since we're no longer a spanner. Mark
// it for relayout.
spanner_object_in_flow_thread->ContainingBlock()
- ->SetNeedsLayoutAndPrefWidthsRecalc(
+ ->SetNeedsLayoutAndIntrinsicWidthsRecalc(
layout_invalidation_reason::kColumnsChanged);
// Now generate a column set for this ex-spanner, if needed and none is there
@@ -729,7 +729,7 @@ void LayoutMultiColumnFlowThread::CalculateColumnHeightAvailable() {
// have a definite height when they in fact don't.
LayoutBlockFlow* container = MultiColumnBlockFlow();
LayoutUnit column_height;
- if (container->HasDefiniteLogicalHeight() || container->IsLayoutView()) {
+ if (container->HasDefiniteLogicalHeight() || IsA<LayoutView>(container)) {
LogicalExtentComputedValues computed_values;
container->ComputeLogicalHeight(LayoutUnit(), container->LogicalTop(),
computed_values);
@@ -1332,7 +1332,7 @@ void LayoutMultiColumnFlowThread::ToggleSpannersInSubtree(
}
}
-void LayoutMultiColumnFlowThread::ComputePreferredLogicalWidths() {
+MinMaxSizes LayoutMultiColumnFlowThread::PreferredLogicalWidths() const {
// The min/max intrinsic widths calculated really tell how much space elements
// need when laid out inside the columns. In order to eventually end up with
// the desired column width, we need to convert them to values pertaining to
@@ -1343,28 +1343,22 @@ void LayoutMultiColumnFlowThread::ComputePreferredLogicalWidths() {
multicol_style->HasAutoColumnCount() ? 1 : multicol_style->ColumnCount());
LayoutUnit gap_extra((column_count - 1) *
ColumnGap(*multicol_style, LayoutUnit()));
+ MinMaxSizes sizes;
if (flow->HasOverrideIntrinsicContentLogicalWidth()) {
- min_preferred_logical_width_ = max_preferred_logical_width_ =
- flow->OverrideIntrinsicContentLogicalWidth();
- ClearPreferredLogicalWidthsDirty();
+ sizes = flow->OverrideIntrinsicContentLogicalWidth();
} else if (flow->ShouldApplySizeContainment()) {
- min_preferred_logical_width_ = max_preferred_logical_width_ = LayoutUnit();
- ClearPreferredLogicalWidthsDirty();
+ sizes = LayoutUnit();
} else {
- // Calculate and set new min_preferred_logical_width_ and
- // max_preferred_logical_width_.
- LayoutFlowThread::ComputePreferredLogicalWidths();
+ sizes = LayoutFlowThread::PreferredLogicalWidths();
}
LayoutUnit column_width;
if (multicol_style->HasAutoColumnWidth()) {
- min_preferred_logical_width_ =
- min_preferred_logical_width_ * column_count + gap_extra;
+ sizes.min_size = sizes.min_size * column_count + gap_extra;
} else {
column_width = LayoutUnit(multicol_style->ColumnWidth());
- min_preferred_logical_width_ =
- std::min(min_preferred_logical_width_, column_width);
+ sizes.min_size = std::min(sizes.min_size, column_width);
}
// Note that if column-count is auto here, we should resolve it to calculate
// the maximum intrinsic width, instead of pretending that it's 1. The only
@@ -1372,9 +1366,9 @@ void LayoutMultiColumnFlowThread::ComputePreferredLogicalWidths() {
// appropriate time or place for layout. The good news is that if height is
// unconstrained and there are no explicit breaks, the resolved column-count
// really should be 1.
- max_preferred_logical_width_ =
- std::max(max_preferred_logical_width_, column_width) * column_count +
- gap_extra;
+ sizes.max_size =
+ std::max(sizes.max_size, column_width) * column_count + gap_extra;
+ return sizes;
}
void LayoutMultiColumnFlowThread::ComputeLogicalHeight(
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.h b/chromium/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.h
index e0518872994..e09739b2a21 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.h
@@ -317,7 +317,7 @@ class CORE_EXPORT LayoutMultiColumnFlowThread final
StyleDifference,
const ComputedStyle& old_style) override;
void ToggleSpannersInSubtree(LayoutBox*);
- void ComputePreferredLogicalWidths() override;
+ MinMaxSizes PreferredLogicalWidths() const override;
void ComputeLogicalHeight(LayoutUnit logical_height,
LayoutUnit logical_top,
LogicalExtentComputedValues&) const final;
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 924dd0ea1db..05575c71fc9 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
@@ -449,11 +449,8 @@ void LayoutMultiColumnSet::UpdateLayout() {
}
}
-void LayoutMultiColumnSet::ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const {
- min_logical_width = flow_thread_->MinPreferredLogicalWidth();
- max_logical_width = flow_thread_->MaxPreferredLogicalWidth();
+MinMaxSizes LayoutMultiColumnSet::ComputeIntrinsicLogicalWidths() const {
+ return MinMaxSizes();
}
void LayoutMultiColumnSet::ComputeLogicalHeight(
@@ -534,6 +531,7 @@ void LayoutMultiColumnSet::ComputeVisualOverflow(
AddVisualOverflowFromFloats();
if (VisualOverflowRect() != previous_visual_overflow_rect) {
+ InvalidateIntersectionObserverCachedRects();
SetShouldCheckForPaintInvalidation();
GetFrameView()->SetIntersectionObservationState(LocalFrameView::kDesired);
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_multi_column_set.h b/chromium/third_party/blink/renderer/core/layout/layout_multi_column_set.h
index ed5ed54a877..6fdae46ff0c 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_multi_column_set.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_multi_column_set.h
@@ -207,8 +207,7 @@ class CORE_EXPORT LayoutMultiColumnSet final : public LayoutBlockFlow {
void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
void UpdateLayout() override;
- void ComputeIntrinsicLogicalWidths(LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const final;
+ MinMaxSizes ComputeIntrinsicLogicalWidths() const final;
void AttachToFlowThread();
void DetachFromFlowThread();
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.cc b/chromium/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.cc
index d08cd063337..10b19d72df8 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.cc
@@ -72,7 +72,7 @@ void LayoutMultiColumnSpannerPlaceholder::InsertedIntoTree() {
LayoutBox::InsertedIntoTree();
// The object may previously have been laid out as a non-spanner, but since
// it's a spanner now, it needs to be relaid out.
- layout_object_in_flow_thread_->SetNeedsLayoutAndPrefWidthsRecalc(
+ layout_object_in_flow_thread_->SetNeedsLayoutAndIntrinsicWidthsRecalc(
layout_invalidation_reason::kColumnsChanged);
}
@@ -83,7 +83,7 @@ void LayoutMultiColumnSpannerPlaceholder::WillBeRemovedFromTree() {
// Even if the placeholder is going away, the object in the flow thread
// might live on. Since it's not a spanner anymore, it needs to be relaid
// out.
- ex_spanner->SetNeedsLayoutAndPrefWidthsRecalc(
+ ex_spanner->SetNeedsLayoutAndIntrinsicWidthsRecalc(
layout_invalidation_reason::kColumnsChanged);
}
LayoutBox::WillBeRemovedFromTree();
@@ -101,7 +101,7 @@ void LayoutMultiColumnSpannerPlaceholder::RecalcVisualOverflow() {
layout_object_in_flow_thread_->VisualOverflowRect());
}
-LayoutUnit LayoutMultiColumnSpannerPlaceholder::MinPreferredLogicalWidth()
+MinMaxSizes LayoutMultiColumnSpannerPlaceholder::PreferredLogicalWidths()
const {
// There should be no contribution from a spanner if the multicol container is
// size-contained. Normally we'd stop at the object that has contain:size
@@ -111,17 +111,8 @@ LayoutUnit LayoutMultiColumnSpannerPlaceholder::MinPreferredLogicalWidth()
// siblings of the flow thread, we need this check.
// TODO(crbug.com/953919): What should we return for display-locked content?
if (MultiColumnBlockFlow()->ShouldApplySizeContainment())
- return LayoutUnit();
- return layout_object_in_flow_thread_->MinPreferredLogicalWidth();
-}
-
-LayoutUnit LayoutMultiColumnSpannerPlaceholder::MaxPreferredLogicalWidth()
- const {
- // See above.
- // TODO(crbug.com/953919): What should we return for display-locked content?
- if (MultiColumnBlockFlow()->ShouldApplySizeContainment())
- return LayoutUnit();
- return layout_object_in_flow_thread_->MaxPreferredLogicalWidth();
+ return MinMaxSizes();
+ return layout_object_in_flow_thread_->PreferredLogicalWidths();
}
void LayoutMultiColumnSpannerPlaceholder::UpdateLayout() {
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.h b/chromium/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.h
index c4018fbc0ae..a2575a39b8c 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.h
@@ -60,8 +60,7 @@ class LayoutMultiColumnSpannerPlaceholder final : public LayoutBox {
void WillBeRemovedFromTree() override;
bool NeedsPreferredWidthsRecalculation() const override;
void RecalcVisualOverflow() override;
- LayoutUnit MinPreferredLogicalWidth() const override;
- LayoutUnit MaxPreferredLogicalWidth() const override;
+ MinMaxSizes PreferredLogicalWidths() const override;
void UpdateLayout() override;
void ComputeLogicalHeight(LayoutUnit logical_height,
LayoutUnit logical_top,
@@ -75,6 +74,11 @@ class LayoutMultiColumnSpannerPlaceholder final : public LayoutBox {
private:
LayoutMultiColumnSpannerPlaceholder(LayoutBox*);
+ MinMaxSizes ComputeIntrinsicLogicalWidths() const final {
+ NOTREACHED();
+ return MinMaxSizes();
+ }
+
// The actual column-span:all layoutObject inside the flow thread.
LayoutBox* layout_object_in_flow_thread_;
};
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 a8574b15657..9d6d6f718aa 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_object.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_object.cc
@@ -33,7 +33,7 @@
#include <utility>
#include "base/allocator/partition_allocator/partition_alloc.h"
-#include "third_party/blink/public/platform/web_scroll_into_view_params.h"
+#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
#include "third_party/blink/renderer/core/animation/element_animations.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
@@ -55,11 +55,14 @@
#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/html/forms/html_select_element.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/html/html_html_element.h"
#include "third_party/blink/renderer/core/html/html_table_cell_element.h"
#include "third_party/blink/renderer/core/html/html_table_element.h"
+#include "third_party/blink/renderer/core/html/image_document.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
+#include "third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.h"
#include "third_party/blink/renderer/core/layout/geometry/transform_state.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
#include "third_party/blink/renderer/core/layout/layout_counter.h"
@@ -74,6 +77,7 @@
#include "third_party/blink/renderer/core/layout/layout_image_resource_style_image.h"
#include "third_party/blink/renderer/core/layout/layout_inline.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/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"
@@ -237,11 +241,10 @@ LayoutObject* LayoutObject::CreateObject(Element* element,
case EDisplay::kBlock:
case EDisplay::kFlowRoot:
case EDisplay::kInlineBlock:
+ case EDisplay::kListItem:
case EDisplay::kMath:
case EDisplay::kInlineMath:
return LayoutObjectFactory::CreateBlockFlow(*element, style, legacy);
- case EDisplay::kListItem:
- return LayoutObjectFactory::CreateListItem(*element, style, legacy);
case EDisplay::kTable:
case EDisplay::kInlineTable:
return new LayoutTable(element);
@@ -260,9 +263,14 @@ LayoutObject* LayoutObject::CreateObject(Element* element,
return LayoutObjectFactory::CreateTableCaption(*element, style, legacy);
case EDisplay::kWebkitBox:
case EDisplay::kWebkitInlineBox:
+ if (style.IsDeprecatedWebkitBoxWithVerticalLineClamp() &&
+ RuntimeEnabledFeatures::BlockFlowHandlesWebkitLineClampEnabled()) {
+ return LayoutObjectFactory::CreateBlockForLineClamp(*element, style,
+ legacy);
+ }
if (style.IsDeprecatedFlexboxUsingFlexLayout())
return new LayoutFlexibleBox(element);
- return new LayoutDeprecatedFlexibleBox(*element);
+ return new LayoutDeprecatedFlexibleBox(element);
case EDisplay::kFlex:
case EDisplay::kInlineFlex:
UseCounter::Count(element->GetDocument(), WebFeature::kCSSFlexibleBox);
@@ -307,6 +315,7 @@ LayoutObject::LayoutObject(Node* node)
LayoutObject::~LayoutObject() {
#if DCHECK_IS_ON()
DCHECK(!has_ax_object_);
+ DCHECK(BeingDestroyed());
#endif
InstanceCounters::DecrementCounter(InstanceCounters::kLayoutObjectCounter);
}
@@ -361,6 +370,22 @@ bool LayoutObject::RequiresAnonymousTableWrappers(
return false;
}
+#if DCHECK_IS_ON()
+
+void LayoutObject::AssertClearedPaintInvalidationFlags() const {
+ if (!PaintInvalidationStateIsDirty() ||
+ PrePaintBlockedByDisplayLock(DisplayLockLifecycleTarget::kChildren))
+ return;
+ // NG text objects are exempt, as pre-paint walking doesn't visit those with
+ // no paint effects (only white-space, for instance).
+ if (IsText() && IsLayoutNGObject())
+ return;
+ ShowLayoutTreeForThis();
+ NOTREACHED();
+}
+
+#endif // DCHECK_IS_ON()
+
DISABLE_CFI_PERF
void LayoutObject::AddChild(LayoutObject* new_child,
LayoutObject* before_child) {
@@ -467,20 +492,26 @@ LayoutObject* LayoutObject::NextInPreOrder() const {
}
bool LayoutObject::HasClipRelatedProperty() const {
- // TODO(trchen): Refactor / remove this function.
// This function detects a bunch of properties that can potentially affect
- // clip inheritance chain. However such generalization is practially useless
+ // clip inheritance chain. However such generalization is practically useless
// because these properties change clip inheritance in different way that
// needs to be handled explicitly.
// CSS clip applies clip to the current element and all descendants.
- // CSS overflow clip applies only to containg-block descendants.
+ // CSS overflow clip applies only to containing-block descendants.
// CSS contain:paint applies to all descendants by making itself a containing
// block for all descendants.
// CSS clip-path/mask/filter induces a stacking context and applies inherited
// clip to that stacking context, while resetting clip for descendants. This
// special behavior is already handled elsewhere.
- if (HasClip() || HasOverflowClip() || ShouldApplyPaintContainment())
+ if (HasClip() || HasOverflowClip())
+ return true;
+ // Paint containment establishes isolation which creates clip isolation nodes.
+ // Style & Layout containment also establish isolation (see
+ // |NeedsIsolationNodes| in PaintPropertyTreeBuilder).
+ if (ShouldApplyPaintContainment() ||
+ (ShouldApplyStyleContainment() && ShouldApplyLayoutContainment())) {
return true;
+ }
if (IsBox() && ToLayoutBox(this)->HasControlClip())
return true;
return false;
@@ -744,19 +775,18 @@ bool LayoutObject::IsFixedPositionObjectInPagedMedia() const {
PhysicalRect LayoutObject::ScrollRectToVisible(
const PhysicalRect& rect,
- const WebScrollIntoViewParams& params) {
+ mojom::blink::ScrollIntoViewParamsPtr params) {
LayoutBox* enclosing_box = EnclosingBox();
if (!enclosing_box)
return rect;
GetDocument().GetFrame()->GetSmoothScrollSequencer().AbortAnimations();
GetDocument().GetFrame()->GetSmoothScrollSequencer().SetScrollType(
- params.GetScrollType());
- WebScrollIntoViewParams new_params(params);
- new_params.is_for_scroll_sequence |=
- params.GetScrollType() == kProgrammaticScroll;
+ params->type);
+ params->is_for_scroll_sequence |=
+ params->type == mojom::blink::ScrollType::kProgrammatic;
PhysicalRect new_location =
- enclosing_box->ScrollRectToVisibleRecursive(rect, new_params);
+ enclosing_box->ScrollRectToVisibleRecursive(rect, std::move(params));
GetDocument().GetFrame()->GetSmoothScrollSequencer().RunQueuedAnimations();
return new_location;
@@ -855,6 +885,12 @@ static inline bool ObjectIsRelayoutBoundary(const LayoutObject* object) {
// FIXME: In future it may be possible to broaden these conditions in order to
// improve performance.
+ // 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)
+ return false;
+
// LayoutInline can't be relayout roots since LayoutBlockFlow is responsible
// for layouting them.
if (object->IsLayoutInline())
@@ -872,6 +908,17 @@ static inline bool ObjectIsRelayoutBoundary(const LayoutObject* object) {
(style->HasAutoLeftAndRight() || style->HasAutoTopAndBottom()))
return false;
+ if (UNLIKELY(RuntimeEnabledFeatures::LayoutNGFragmentTraversalEnabled() &&
+ object->IsLayoutNGObject())) {
+ // We need to rebuild the entire NG fragment spine all the way from the root
+ // (or at least the nearest self-painting paint layer), since we traverse
+ // the fragments, and not objects. Fragment painting is initiated at
+ // self-painting layers, but we cannot check if it's a self-painting layer
+ // now, because it may cease to be one during layout (an object with clipped
+ // overflow that no longer has content that requires it to clip).
+ return false;
+ }
+
if (object->ShouldApplyLayoutContainment() &&
object->ShouldApplySizeContainment())
return true;
@@ -887,7 +934,7 @@ static inline bool ObjectIsRelayoutBoundary(const LayoutObject* object) {
if (object->IsTextControl())
return true;
- if (object->IsSVGRoot())
+ if (is_svg_root)
return true;
if (!object->HasOverflowClip())
@@ -1016,7 +1063,7 @@ void LayoutObject::MarkContainerChainForLayout(bool schedule_relayout,
// Don't mark the outermost object of an unrooted subtree. That object will
// be marked when the subtree is added to the document.
LayoutObject* container = object->Container();
- if (!container && !object->IsLayoutView())
+ if (!container && !IsA<LayoutView>(object))
return;
if (!last->IsTextOrSVGChild() && last->StyleRef().HasOutOfFlowPosition()) {
object = last->ContainingBlock();
@@ -1112,16 +1159,33 @@ void LayoutObject::CheckBlockPositionedObjectsNeedLayout() {
}
#endif
-void LayoutObject::SetPreferredLogicalWidthsDirty(
+void LayoutObject::SetIntrinsicLogicalWidthsDirty(
MarkingBehavior mark_parents) {
- bitfields_.SetPreferredLogicalWidthsDirty(true);
+ bitfields_.SetIntrinsicLogicalWidthsDirty(true);
if (mark_parents == kMarkContainerChain &&
(IsText() || !StyleRef().HasOutOfFlowPosition()))
- InvalidateContainerPreferredLogicalWidths();
+ InvalidateContainerIntrinsicLogicalWidths();
}
-void LayoutObject::ClearPreferredLogicalWidthsDirty() {
- bitfields_.SetPreferredLogicalWidthsDirty(false);
+void LayoutObject::ClearIntrinsicLogicalWidthsDirty() {
+ bitfields_.SetIntrinsicLogicalWidthsDirty(false);
+}
+
+void LayoutObject::InvalidateSubtreeLayoutForFontUpdates() {
+ SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
+ layout_invalidation_reason::kFontsChanged);
+ for (LayoutObject* child = SlowFirstChild(); child;
+ child = child->NextSibling()) {
+ child->InvalidateSubtreeLayoutForFontUpdates();
+ }
+}
+
+void LayoutObject::InvalidateIntersectionObserverCachedRects() {
+ if (GetNode() && GetNode()->IsElementNode()) {
+ if (auto* data = To<Element>(GetNode())->IntersectionObserverData()) {
+ data->InvalidateCachedRects();
+ }
+ }
}
static inline bool NGKeepInvalidatingBeyond(LayoutObject* o) {
@@ -1131,28 +1195,30 @@ static inline bool NGKeepInvalidatingBeyond(LayoutObject* o) {
// next block container.
// Atomic inlines do not have this problem as they are treated like blocks
// in this context.
+ // There's a similar issue for flow thread objects, as they are invisible to
+ // LayoutNG.
if (!RuntimeEnabledFeatures::LayoutNGEnabled())
return false;
- if (o->IsLayoutInline() || o->IsText())
+ if (o->IsLayoutInline() || o->IsText() || o->IsLayoutFlowThread())
return true;
return false;
}
-inline void LayoutObject::InvalidateContainerPreferredLogicalWidths() {
+inline void LayoutObject::InvalidateContainerIntrinsicLogicalWidths() {
// In order to avoid pathological behavior when inlines are deeply nested, we
// do include them in the chain that we mark dirty (even though they're kind
// of irrelevant).
LayoutObject* o = IsTableCell() ? ContainingBlock() : Container();
while (o &&
- (!o->PreferredLogicalWidthsDirty() || NGKeepInvalidatingBeyond(o))) {
+ (!o->IntrinsicLogicalWidthsDirty() || NGKeepInvalidatingBeyond(o))) {
// Don't invalidate the outermost object of an unrooted subtree. That object
// will be invalidated when the subtree is added to the document.
LayoutObject* container =
o->IsTableCell() ? o->ContainingBlock() : o->Container();
- if (!container && !o->IsLayoutView())
+ if (!container && !IsA<LayoutView>(o))
break;
- o->bitfields_.SetPreferredLogicalWidthsDirty(true);
+ o->bitfields_.SetIntrinsicLogicalWidthsDirty(true);
// A positioned object has no effect on the min/max width of its containing
// block ever. We can optimize this case and not go up any further.
if (o->StyleRef().HasOutOfFlowPosition())
@@ -1187,24 +1253,6 @@ LayoutObject* LayoutObject::ContainerForFixedPosition(
});
}
-LayoutBlock* LayoutObject::FindNonAnonymousContainingBlock(
- LayoutObject* container,
- AncestorSkipInfo* skip_info) {
- // For inlines, we return the nearest non-anonymous enclosing
- // block. We don't try to return the inline itself. This allows us to avoid
- // having a positioned objects list in all LayoutInlines and lets us return a
- // strongly-typed LayoutBlock* result from this method. The
- // LayoutObject::Container() method can actually be used to obtain the inline
- // directly.
- if (container && !container->IsLayoutBlock())
- container = container->ContainingBlock(skip_info);
-
- while (container && container->IsAnonymousBlock())
- container = container->ContainingBlock(skip_info);
-
- return DynamicTo<LayoutBlock>(container);
-}
-
LayoutBlock* LayoutObject::ContainingBlockForAbsolutePosition(
AncestorSkipInfo* skip_info) const {
auto* container = ContainerForAbsolutePosition(skip_info);
@@ -1250,6 +1298,24 @@ LayoutBlock* LayoutObject::ContainingBlock(AncestorSkipInfo* skip_info) const {
return DynamicTo<LayoutBlock>(object);
}
+LayoutBlock* LayoutObject::FindNonAnonymousContainingBlock(
+ LayoutObject* container,
+ AncestorSkipInfo* skip_info) {
+ // For inlines, we return the nearest non-anonymous enclosing
+ // block. We don't try to return the inline itself. This allows us to avoid
+ // having a positioned objects list in all LayoutInlines and lets us return a
+ // strongly-typed LayoutBlock* result from this method. The
+ // LayoutObject::Container() method can actually be used to obtain the inline
+ // directly.
+ if (container && !container->IsLayoutBlock())
+ container = container->ContainingBlock(skip_info);
+
+ while (container && container->IsAnonymousBlock())
+ container = container->ContainingBlock(skip_info);
+
+ return DynamicTo<LayoutBlock>(container);
+}
+
bool LayoutObject::ComputeIsFixedContainer(const ComputedStyle* style) const {
if (!style)
return false;
@@ -1267,7 +1333,7 @@ bool LayoutObject::ComputeIsFixedContainer(const ComputedStyle* style) const {
// select elements inside that are created by user agent shadow DOM, and we
// have (C++) code that assumes that the elements are indeed contained by the
// text control. So just make sure this is the case.
- if (IsLayoutView() || IsSVGForeignObject() || IsTextControl())
+ if (IsA<LayoutView>(this) || IsSVGForeignObject() || IsTextControl())
return true;
// https://www.w3.org/TR/css-transforms-1/#containing-block-for-all-descendants
if (style->HasTransformRelatedProperty()) {
@@ -1334,16 +1400,6 @@ PhysicalRect LayoutObject::AbsoluteBoundingBoxRectForScrollIntoView() const {
return rect;
}
-FloatRect LayoutObject::AbsoluteBoundingBoxRectForRange(
- const EphemeralRange& range) {
- if (range.IsNull() || !range.StartPosition().ComputeContainerNode())
- return FloatRect();
-
- range.GetDocument().UpdateStyleAndLayout();
-
- return ComputeTextFloatRect(range);
-}
-
void LayoutObject::AddAbsoluteRectForLayer(IntRect& result) {
if (HasLayer())
result.Unite(AbsoluteBoundingBoxRect());
@@ -1412,6 +1468,7 @@ void LayoutObject::RecalcNormalFlowChildVisualOverflowIfNeeded() {
}
const LayoutBoxModelObject* LayoutObject::EnclosingCompositedContainer() const {
+ DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
LayoutBoxModelObject* container = nullptr;
// FIXME: CompositingState is not necessarily up to date for many callers of
// this function.
@@ -1495,7 +1552,7 @@ String LayoutObject::DecoratedName() const {
name.Append(" (anonymous)");
// FIXME: Remove the special case for LayoutView here (requires rebaseline of
// all tests).
- if (IsOutOfFlowPositioned() && !IsLayoutView())
+ if (IsOutOfFlowPositioned() && !IsA<LayoutView>(this))
name.Append(" (positioned)");
if (IsRelPositioned())
name.Append(" (relative positioned)");
@@ -1626,14 +1683,12 @@ bool LayoutObject::MapToVisualRectInAncestorSpaceInternalFastPath(
if (ancestor == this)
return true;
- const auto* property_container = this;
AncestorSkipInfo skip_info(ancestor);
- while (!property_container->FirstFragment().HasLocalBorderBoxProperties()) {
- property_container = property_container->Container(&skip_info);
- if (!property_container || skip_info.AncestorSkipped() ||
- property_container->FirstFragment().NextFragment())
- return false;
- }
+ PropertyTreeState container_properties = PropertyTreeState::Uninitialized();
+ const LayoutObject* property_container =
+ GetPropertyContainer(&skip_info, &container_properties);
+ if (!property_container)
+ return false;
// This works because it's not possible to have any intervening clips,
// effects, transforms between |this| and |property_container|, and therefore
@@ -1643,13 +1698,9 @@ bool LayoutObject::MapToVisualRectInAncestorSpaceInternalFastPath(
rect.Move(FirstFragment().PaintOffset());
if (property_container != ancestor) {
FloatClipRect clip_rect((FloatRect(rect)));
- const auto& local_state =
- property_container == this
- ? FirstFragment().LocalBorderBoxProperties()
- : property_container->FirstFragment().ContentsProperties();
intersects = GeometryMapper::LocalToAncestorVisualRect(
- local_state, ancestor->FirstFragment().ContentsProperties(), clip_rect,
- kIgnorePlatformOverlayScrollbarSize,
+ container_properties, ancestor->FirstFragment().ContentsProperties(),
+ clip_rect, kIgnorePlatformOverlayScrollbarSize,
(visual_rect_flags & kEdgeInclusive) ? kInclusiveIntersect
: kNonInclusiveIntersect);
rect = PhysicalRect::EnclosingRect(clip_rect.Rect());
@@ -1707,6 +1758,27 @@ bool LayoutObject::MapToVisualRectInAncestorSpaceInternal(
return true;
}
+const LayoutObject* LayoutObject::GetPropertyContainer(
+ AncestorSkipInfo* skip_info,
+ PropertyTreeState* container_properties) const {
+ const LayoutObject* property_container = this;
+ while (!property_container->FirstFragment().HasLocalBorderBoxProperties()) {
+ property_container = property_container->Container(skip_info);
+ if (!property_container || (skip_info && skip_info->AncestorSkipped()) ||
+ property_container->FirstFragment().NextFragment())
+ return nullptr;
+ }
+ if (container_properties) {
+ if (property_container == this) {
+ *container_properties = FirstFragment().LocalBorderBoxProperties();
+ } else {
+ *container_properties =
+ property_container->FirstFragment().ContentsProperties();
+ }
+ }
+ return property_container;
+}
+
HitTestResult LayoutObject::HitTestForOcclusion(
const PhysicalRect& hit_rect) const {
LocalFrame* frame = GetDocument().GetFrame();
@@ -1893,26 +1965,20 @@ StyleDifference LayoutObject::AdjustStyleDifference(
diff.SetNeedsFullLayout();
}
- // TODO(wangxianzhu): We may avoid subtree paint invalidation on CSS clip
- // change for CAP.
- if (diff.CssClipChanged())
- diff.SetNeedsPaintInvalidationSubtree();
-
// Optimization: for decoration/color property changes, invalidation is only
// needed if we have style or text affected by these properties.
- if (diff.TextDecorationOrColorChanged() &&
- !diff.NeedsFullPaintInvalidation()) {
+ if (diff.TextDecorationOrColorChanged() && !diff.NeedsPaintInvalidation()) {
if (StyleRef().HasBorderColorReferencingCurrentColor() ||
StyleRef().HasOutlineWithCurrentColor() ||
StyleRef().HasBackgroundRelatedColorReferencingCurrentColor() ||
// Skip any text nodes that do not contain text boxes. Whitespace cannot
// be skipped or we will miss invalidating decorations (e.g.,
// underlines).
- (IsText() && !IsBR() && ToLayoutText(this)->HasTextBoxes()) ||
+ (IsText() && !IsBR() && ToLayoutText(this)->HasInlineFragments()) ||
(IsSVG() && StyleRef().SvgStyle().IsFillColorCurrentColor()) ||
(IsSVG() && StyleRef().SvgStyle().IsStrokeColorCurrentColor()) ||
IsListMarker() || IsDetailsMarker())
- diff.SetNeedsPaintInvalidationObject();
+ diff.SetNeedsPaintInvalidation();
}
// The answer to layerTypeRequired() for plugins, iframes, and canvas can
@@ -1956,7 +2022,8 @@ void LayoutObject::SetPseudoElementStyle(
SetStyle(std::move(pseudo_style));
}
-void LayoutObject::MarkContainerChainForOverflowRecalcIfNeeded() {
+void LayoutObject::MarkContainerChainForOverflowRecalcIfNeeded(
+ bool mark_container_chain_layout_overflow_recalc) {
LayoutObject* object = this;
do {
// Cell and row need to propagate the flag to their containing section and
@@ -1966,25 +2033,53 @@ void LayoutObject::MarkContainerChainForOverflowRecalcIfNeeded() {
? object->Parent()
: object->Container();
if (object) {
- object->SetChildNeedsLayoutOverflowRecalc();
- object->MarkSelfPaintingLayerForVisualOverflowRecalc();
+ bool already_needs_layout_overflow_recalc = false;
+ if (mark_container_chain_layout_overflow_recalc) {
+ already_needs_layout_overflow_recalc =
+ object->ChildNeedsLayoutOverflowRecalc();
+ if (!already_needs_layout_overflow_recalc)
+ object->SetChildNeedsLayoutOverflowRecalc();
+ }
+
+ if (object->HasLayer()) {
+ auto* box_model_object = ToLayoutBoxModelObject(object);
+ if (box_model_object->HasSelfPaintingLayer()) {
+ auto* layer = box_model_object->Layer();
+ if (layer->NeedsVisualOverflowRecalc()) {
+ if (already_needs_layout_overflow_recalc)
+ return;
+ } else {
+ layer->SetNeedsVisualOverflowRecalc();
+ }
+ }
+ }
}
} while (object);
}
-void LayoutObject::SetNeedsVisualOverflowAndPaintInvalidation() {
+void LayoutObject::SetNeedsOverflowRecalc(
+ OverflowRecalcType overflow_recalc_type) {
+ bool mark_container_chain_layout_overflow_recalc =
+ !SelfNeedsLayoutOverflowRecalc();
+
+ if (overflow_recalc_type ==
+ OverflowRecalcType::kLayoutAndVisualOverflowRecalc) {
+ SetSelfNeedsLayoutOverflowRecalc();
+ }
+
+ DCHECK(overflow_recalc_type ==
+ OverflowRecalcType::kOnlyVisualOverflowRecalc ||
+ overflow_recalc_type ==
+ OverflowRecalcType::kLayoutAndVisualOverflowRecalc);
SetShouldCheckForPaintInvalidation();
MarkSelfPaintingLayerForVisualOverflowRecalc();
-}
-
-void LayoutObject::SetNeedsOverflowRecalc() {
- bool needed_recalc = SelfNeedsLayoutOverflowRecalc();
- SetSelfNeedsLayoutOverflowRecalc();
- SetNeedsVisualOverflowAndPaintInvalidation();
- if (!needed_recalc)
- MarkContainerChainForOverflowRecalcIfNeeded();
+ if (mark_container_chain_layout_overflow_recalc) {
+ MarkContainerChainForOverflowRecalcIfNeeded(
+ overflow_recalc_type ==
+ OverflowRecalcType::kLayoutAndVisualOverflowRecalc);
+ }
}
DISABLE_CFI_PERF
@@ -2046,7 +2141,7 @@ void LayoutObject::SetStyle(scoped_refptr<const ComputedStyle> style,
if (!diff.NeedsFullLayout()) {
if (updated_diff.NeedsFullLayout()) {
- SetNeedsLayoutAndPrefWidthsRecalc(
+ SetNeedsLayoutAndIntrinsicWidthsRecalc(
layout_invalidation_reason::kStyleChange);
} else if (updated_diff.NeedsPositionedMovementLayout()) {
SetNeedsPositionedMovementLayout();
@@ -2060,32 +2155,34 @@ void LayoutObject::SetStyle(scoped_refptr<const ComputedStyle> style,
container->SetNeedsOverflowRecalc();
}
- if (diff.NeedsRecomputeOverflow() && !NeedsLayout()) {
- // TODO(rhogan): Make inlines capable of recomputing overflow too.
- if (IsLayoutBlock()) {
- SetNeedsOverflowRecalc();
- } else {
- SetNeedsLayoutAndPrefWidthsRecalc(
+ if (diff.NeedsRecomputeVisualOverflow()) {
+ if (!IsLayoutNGObject() && !IsLayoutBlock() && !NeedsLayout()) {
+ // TODO(rego): This is still needed because RecalcVisualOverflow() does
+ // not actually compute the visual overflow for inline elements (legacy
+ // layout). However in LayoutNG RecalcInlineChildrenInkOverflow() is
+ // called and visual overflow is recomputed properly so we don't need this
+ // (see crbug.com/1043927).
+ SetNeedsLayoutAndIntrinsicWidthsRecalc(
layout_invalidation_reason::kStyleChange);
+ } else {
+ PaintingLayer()->SetNeedsVisualOverflowRecalc();
+ SetShouldCheckForPaintInvalidation();
}
}
- if (diff.NeedsPaintInvalidationSubtree() ||
- updated_diff.NeedsPaintInvalidationSubtree()) {
- SetSubtreeShouldDoFullPaintInvalidation();
- } else if (diff.NeedsPaintInvalidationObject() ||
- updated_diff.NeedsPaintInvalidationObject()) {
- // TODO(wangxianzhu): For now LayoutSVGRoot::localVisualRect() depends on
- // several styles. Refactor to avoid this special case.
- if (IsSVGRoot())
+ if (diff.NeedsPaintInvalidation() || updated_diff.NeedsPaintInvalidation()) {
+ if (IsSVGRoot()) {
+ // LayoutSVGRoot::LocalVisualRect() depends on some styles.
SetShouldDoFullPaintInvalidation();
- else
+ } else {
+ // We'll set needing geometry change later if the style change does cause
+ // possible layout change or visual overflow change.
SetShouldDoFullPaintInvalidationWithoutGeometryChange();
+ }
}
- if ((diff.NeedsPaintInvalidationObject() ||
- diff.NeedsPaintInvalidationSubtree()) &&
- old_style && !old_style->ClipPathDataEquivalent(*style_)) {
+ if (diff.NeedsPaintInvalidation() && old_style &&
+ !old_style->ClipPathDataEquivalent(*style_)) {
InvalidateClipPathCache();
PaintingLayer()->SetNeedsCompositingInputsUpdate();
}
@@ -2280,7 +2377,7 @@ void LayoutObject::StyleWillChange(StyleDifference diff,
// Elements may inherit touch action from parent frame, so we need to report
// touchstart handler if the root layout object has non-auto effective touch
// action.
- TouchAction old_touch_action = TouchAction::kTouchActionAuto;
+ TouchAction old_touch_action = TouchAction::kAuto;
bool is_document_element = GetNode() && IsDocumentElement();
if (style_) {
old_touch_action = is_document_element ? style_->GetEffectiveTouchAction()
@@ -2290,11 +2387,11 @@ void LayoutObject::StyleWillChange(StyleDifference diff,
? new_style.GetEffectiveTouchAction()
: new_style.GetTouchAction();
if (GetNode() && !GetNode()->IsTextNode() &&
- (old_touch_action == TouchAction::kTouchActionAuto) !=
- (new_touch_action == TouchAction::kTouchActionAuto)) {
+ (old_touch_action == TouchAction::kAuto) !=
+ (new_touch_action == TouchAction::kAuto)) {
EventHandlerRegistry& registry =
GetDocument().GetFrame()->GetEventHandlerRegistry();
- if (new_touch_action != TouchAction::kTouchActionAuto) {
+ if (new_touch_action != TouchAction::kAuto) {
registry.DidAddEventHandler(*GetNode(),
EventHandlerRegistry::kTouchAction);
} else {
@@ -2342,6 +2439,22 @@ void LayoutObject::SetScrollAnchorDisablingStyleChangedOnAncestor() {
}
}
+static void ClearAncestorScrollAnchors(LayoutObject* layout_object) {
+ PaintLayer* layer = nullptr;
+ if (LayoutObject* parent = layout_object->Parent())
+ layer = parent->EnclosingLayer();
+
+ while (layer) {
+ if (PaintLayerScrollableArea* scrollable_area =
+ layer->GetScrollableArea()) {
+ ScrollAnchor* anchor = scrollable_area->GetScrollAnchor();
+ DCHECK(anchor);
+ anchor->Clear();
+ }
+ layer = layer->Parent();
+ }
+}
+
void LayoutObject::StyleDidChange(StyleDifference diff,
const ComputedStyle* old_style) {
// First assume the outline will be affected. It may be updated when we know
@@ -2372,7 +2485,8 @@ void LayoutObject::StyleDidChange(StyleDifference diff,
MarkContainerChainForLayout();
}
- SetNeedsLayoutAndPrefWidthsRecalc(layout_invalidation_reason::kStyleChange);
+ SetNeedsLayoutAndIntrinsicWidthsRecalc(
+ layout_invalidation_reason::kStyleChange);
} else if (diff.NeedsPositionedMovementLayout()) {
SetNeedsPositionedMovementLayout();
}
@@ -2394,7 +2508,7 @@ void LayoutObject::StyleDidChange(StyleDifference diff,
}
}
- if (diff.NeedsFullPaintInvalidation() && old_style) {
+ if (diff.NeedsPaintInvalidation() && old_style) {
if (ResolveColor(*old_style, GetCSSPropertyBackgroundColor()) !=
ResolveColor(GetCSSPropertyBackgroundColor()) ||
old_style->BackgroundLayers() != StyleRef().BackgroundLayers())
@@ -2409,6 +2523,10 @@ void LayoutObject::StyleDidChange(StyleDifference diff,
AddSubtreePaintPropertyUpdateReason(
SubtreePaintPropertyUpdateReason::kTransformStyleChanged);
}
+
+ if (old_style && old_style->OverflowAnchor() != StyleRef().OverflowAnchor()) {
+ ClearAncestorScrollAnchors(this);
+ }
}
void LayoutObject::ApplyPseudoElementStyleChanges(
@@ -2441,12 +2559,12 @@ void LayoutObject::ApplyFirstLineChanges(const ComputedStyle* old_style) {
}
}
if (!has_diff) {
- diff.SetNeedsPaintInvalidationObject();
+ diff.SetNeedsPaintInvalidation();
diff.SetNeedsFullLayout();
}
- if (BehavesLikeBlockContainer() && (diff.NeedsFullPaintInvalidation() ||
- diff.TextDecorationOrColorChanged())) {
+ if (BehavesLikeBlockContainer() &&
+ (diff.NeedsPaintInvalidation() || diff.TextDecorationOrColorChanged())) {
if (auto* first_line_container =
To<LayoutBlock>(this)->NearestInnerBlockWithFirstLine())
first_line_container->SetShouldDoFullPaintInvalidationForFirstLine();
@@ -2455,7 +2573,8 @@ void LayoutObject::ApplyFirstLineChanges(const ComputedStyle* old_style) {
if (diff.NeedsLayout()) {
if (diff.NeedsFullLayout())
SetNeedsCollectInlines();
- SetNeedsLayoutAndPrefWidthsRecalc(layout_invalidation_reason::kStyleChange);
+ SetNeedsLayoutAndIntrinsicWidthsRecalc(
+ layout_invalidation_reason::kStyleChange);
}
}
@@ -2481,15 +2600,18 @@ void LayoutObject::PropagateStyleToAnonymousChildren() {
child_block_flow->IsAnonymousBlockContinuation())
new_style->SetPosition(child->StyleRef().GetPosition());
- if (child->IsLayoutNGListMarker())
- new_style->SetWhiteSpace(child->StyleRef().WhiteSpace());
-
UpdateAnonymousChildStyle(child, *new_style);
child->SetStyle(std::move(new_style));
}
- if (StyleRef().StyleType() == kPseudoIdNone)
+ PseudoId pseudo_id = StyleRef().StyleType();
+ if (pseudo_id == kPseudoIdNone)
+ return;
+
+ // Don't propagate style from markers with 'content: normal' because it's not
+ // needed and it would be slow.
+ if (pseudo_id == kPseudoIdMarker && StyleRef().ContentBehavesAsNormal())
return;
// Propagate style from pseudo elements to generated content. We skip children
@@ -2681,10 +2803,10 @@ void LayoutObject::MapLocalToAncestor(const LayoutBoxModelObject* ancestor,
: TransformState::kFlattenTransform);
// If the ancestor is fixed, then the rect is already in its coordinates so
// doesn't need viewport-adjusting.
+ auto* layout_view = DynamicTo<LayoutView>(container);
if (ancestor->StyleRef().GetPosition() != EPosition::kFixed &&
- container->IsLayoutView() &&
- StyleRef().GetPosition() == EPosition::kFixed) {
- transform_state.Move(ToLayoutView(container)->OffsetForFixedPosition());
+ layout_view && StyleRef().GetPosition() == EPosition::kFixed) {
+ transform_state.Move(layout_view->OffsetForFixedPosition());
}
return;
}
@@ -2745,10 +2867,10 @@ void LayoutObject::MapAncestorToLocal(const LayoutBoxModelObject* ancestor,
transform_state.Move(-container_offset);
// If the ancestor is fixed, then the rect is already in its coordinates so
// doesn't need viewport-adjusting.
+ auto* layout_view = DynamicTo<LayoutView>(container);
if (ancestor->StyleRef().GetPosition() != EPosition::kFixed &&
- container->IsLayoutView() &&
- StyleRef().GetPosition() == EPosition::kFixed) {
- transform_state.Move(ToLayoutView(container)->OffsetForFixedPosition());
+ layout_view && StyleRef().GetPosition() == EPosition::kFixed) {
+ transform_state.Move(layout_view->OffsetForFixedPosition());
}
}
}
@@ -2931,30 +3053,12 @@ bool LayoutObject::IsRooted() const {
RespectImageOrientationEnum LayoutObject::ShouldRespectImageOrientation(
const LayoutObject* layout_object) {
- if (!layout_object)
- return kDoNotRespectImageOrientation;
-
- // Respect the image's orientation if it's being used as a full-page image or
- // it's an <img> and the setting to respect it everywhere is set or the <img>
- // has image-orientation: from-image style. FIXME: crbug.com/498233
- if (layout_object->GetDocument().IsImageDocument())
- return kRespectImageOrientation;
-
- if (!IsA<HTMLImageElement>(layout_object->GetNode()))
- return kDoNotRespectImageOrientation;
-
- if (layout_object->GetDocument().GetSettings() &&
- layout_object->GetDocument()
- .GetSettings()
- ->GetShouldRespectImageOrientation())
- return kRespectImageOrientation;
-
- if (layout_object->Style() &&
- layout_object->StyleRef().RespectImageOrientation() ==
+ if (layout_object && layout_object->Style() &&
+ layout_object->StyleRef().RespectImageOrientation() !=
kRespectImageOrientation)
- return kRespectImageOrientation;
+ return kDoNotRespectImageOrientation;
- return kDoNotRespectImageOrientation;
+ return kRespectImageOrientation;
}
LayoutObject* LayoutObject::Container(AncestorSkipInfo* skip_info) const {
@@ -2993,7 +3097,7 @@ LayoutObject* LayoutObject::Container(AncestorSkipInfo* skip_info) const {
}
inline LayoutObject* LayoutObject::ParentCrossingFrames() const {
- if (IsLayoutView())
+ if (IsA<LayoutView>(this))
return GetFrame()->OwnerLayoutObject();
return Parent();
}
@@ -3044,7 +3148,7 @@ void LayoutObject::WillBeDestroyed() {
// m_style is null in cases of partial construction. Any handler we added
// previously may have already been removed by the Document independently.
if (GetNode() && !GetNode()->IsTextNode() && style_ &&
- style_->GetTouchAction() != TouchAction::kTouchActionAuto) {
+ style_->GetTouchAction() != TouchAction::kAuto) {
EventHandlerRegistry& registry =
GetDocument().GetFrame()->GetEventHandlerRegistry();
if (registry.EventHandlerTargets(EventHandlerRegistry::kTouchAction)
@@ -3178,6 +3282,11 @@ void LayoutObject::WillBeRemovedFromTree() {
}
void LayoutObject::SetNeedsPaintPropertyUpdate() {
+ SetNeedsPaintPropertyUpdatePreservingCachedRects();
+ InvalidateIntersectionObserverCachedRects();
+}
+
+void LayoutObject::SetNeedsPaintPropertyUpdatePreservingCachedRects() {
if (bitfields_.NeedsPaintPropertyUpdate())
return;
@@ -3287,7 +3396,14 @@ void LayoutObject::DestroyAndCleanupAnonymousWrappers() {
}
void LayoutObject::Destroy() {
+ // Mark as being destroyed to avoid trouble with merges in |RemoveChild()| and
+ // other house keepings.
+ bitfields_.SetBeingDestroyed(true);
WillBeDestroyed();
+ DeleteThis();
+}
+
+void LayoutObject::DeleteThis() {
delete this;
}
@@ -3302,6 +3418,10 @@ CompositingState LayoutObject::GetCompositingState() const {
: kNotComposited;
}
+bool LayoutObject::CanHaveAdditionalCompositingReasons() const {
+ return false;
+}
+
CompositingReasons LayoutObject::AdditionalCompositingReasons() const {
return CompositingReason::kNone;
}
@@ -3343,17 +3463,12 @@ Node* LayoutObject::NodeForHitTest() const {
// If we hit the anonymous layoutObjects inside generated content we should
// actually hit the generated content so walk up to the PseudoElement.
if (const LayoutObject* parent = Parent()) {
- if (parent->IsBeforeOrAfterContent() ||
+ if (parent->IsBeforeOrAfterContent() || parent->IsMarkerContent() ||
parent->StyleRef().StyleType() == kPseudoIdFirstLetter) {
for (; parent; parent = parent->Parent()) {
if (Node* node = parent->GetNode())
return node;
}
- } else if (const LayoutNGListItem* list_item =
- LayoutNGListItem::FromMarkerOrMarkerContent(*this)) {
- // If this is a list marker, or is inside of a list marker, return the
- // list item.
- return list_item->GetNode();
}
}
@@ -3377,9 +3492,8 @@ bool LayoutObject::NodeAtPoint(HitTestResult&,
}
void LayoutObject::ScheduleRelayout() {
- if (IsLayoutView()) {
- LocalFrameView* view = ToLayoutView(this)->GetFrameView();
- if (view)
+ if (auto* layout_view = DynamicTo<LayoutView>(this)) {
+ if (LocalFrameView* view = layout_view->GetFrameView())
view->ScheduleRelayout();
} else {
if (IsRooted()) {
@@ -3605,7 +3719,7 @@ Element* LayoutObject::OffsetParent(const Element* base) const {
break;
if (!IsPositioned() &&
- (IsA<HTMLTableElement>(*node) || IsHTMLTableCellElement(*node)))
+ (IsA<HTMLTableElement>(*node) || IsA<HTMLTableCellElement>(*node)))
break;
// Webkit specific extension where offsetParent stops at zoom level changes.
@@ -3696,11 +3810,12 @@ PositionWithAffinity LayoutObject::CreatePositionWithAffinity(
if (position.IsNotNull())
return PositionWithAffinity(position);
- DCHECK(!GetNode());
+ DCHECK(!NonPseudoNode());
return CreatePositionWithAffinity(0);
}
-CursorDirective LayoutObject::GetCursor(const PhysicalOffset&, Cursor&) const {
+CursorDirective LayoutObject::GetCursor(const PhysicalOffset&,
+ ui::Cursor&) const {
return kSetCursorBasedOnStyle;
}
@@ -4089,6 +4204,15 @@ LayoutUnit LayoutObject::FlipForWritingModeInternal(
->FlipForWritingMode(position, width);
}
+bool LayoutObject::SelfPaintingLayerNeedsVisualOverflowRecalc() const {
+ if (HasLayer()) {
+ auto* box_model_object = ToLayoutBoxModelObject(this);
+ if (box_model_object->HasSelfPaintingLayer())
+ return box_model_object->Layer()->NeedsVisualOverflowRecalc();
+ }
+ return false;
+}
+
void LayoutObject::MarkSelfPaintingLayerForVisualOverflowRecalc() {
if (HasLayer()) {
auto* box_model_object = ToLayoutBoxModelObject(this);
@@ -4097,6 +4221,20 @@ void LayoutObject::MarkSelfPaintingLayerForVisualOverflowRecalc() {
}
}
+bool IsMenuList(const LayoutObject* object) {
+ if (!object)
+ return false;
+ auto* select = DynamicTo<HTMLSelectElement>(object->GetNode());
+ return select && select->UsesMenuList();
+}
+
+bool IsListBox(const LayoutObject* object) {
+ if (!object)
+ return false;
+ auto* select = DynamicTo<HTMLSelectElement>(object->GetNode());
+ return select && !select->UsesMenuList();
+}
+
} // namespace blink
#if DCHECK_IS_ON()
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 28e6a2fec09..714d1246169 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_object.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_object.h
@@ -31,6 +31,7 @@
#include "base/auto_reset.h"
#include "base/macros.h"
+#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/display_lock/display_lock_context.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -45,6 +46,7 @@
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
#include "third_party/blink/renderer/core/layout/layout_object_child_list.h"
#include "third_party/blink/renderer/core/layout/map_coordinates_flags.h"
+#include "third_party/blink/renderer/core/layout/min_max_sizes.h"
#include "third_party/blink/renderer/core/layout/ng/ng_outline_type.h"
#include "third_party/blink/renderer/core/layout/ng/ng_style_variant.h"
#include "third_party/blink/renderer/core/layout/subtree_layout_scope.h"
@@ -64,10 +66,12 @@
#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-namespace blink {
+namespace ui {
+class Cursor;
+}
+namespace blink {
class AffineTransform;
-class Cursor;
class HitTestLocation;
class HitTestRequest;
class InlineBox;
@@ -89,13 +93,15 @@ class PaintLayer;
class PseudoElementStyleRequest;
struct PaintInfo;
struct PaintInvalidatorContext;
-struct WebScrollIntoViewParams;
enum VisualRectFlags {
kDefaultVisualRectFlags = 0,
kEdgeInclusive = 1 << 0,
// Use the GeometryMapper fast-path, if possible.
kUseGeometryMapper = 1 << 1,
+ // When mapping to absolute coordinates and the main frame is remote, don't
+ // apply the main frame root scroller's overflow clip.
+ kDontApplyMainFrameOverflowClip = 1 << 2,
};
enum CursorDirective { kSetCursorBasedOnStyle, kSetCursor, kDoNotSetCursor };
@@ -209,8 +215,8 @@ const int kShowTreeCharacterOffset = 39;
// Those widths are used to determine the final layout logical width, which
// depends on the layout algorithm used and the available logical width.
//
-// LayoutObject only has getters for the widths (MinPreferredLogicalWidth and
-// MaxPreferredLogicalWidth). However the storage for them is in LayoutBox (see
+// LayoutObject only has a getter for the widths (PreferredLogicalWidths).
+// However the storage for them is in LayoutBox (see
// min_preferred_logical_width_ and max_preferred_logical_width_). This is
// because only boxes implementing the full box model have a need for them.
// Because LayoutBlockFlow's intrinsic widths rely on the underlying text
@@ -219,7 +225,7 @@ const int kShowTreeCharacterOffset = 39;
// The 2 widths are computed lazily during layout when the getters are called.
// The computation is done by calling ComputePreferredLogicalWidths() behind the
// scene. The boolean used to control the lazy recomputation is
-// PreferredLogicalWidthsDirty.
+// IntrinsicLogicalWidthsDirty.
//
// See the individual getters below for more details about what each width is.
class CORE_EXPORT LayoutObject : public ImageResourceObserver,
@@ -374,7 +380,7 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
// TODO(nburris): The returned rect is actually in document coordinates, not
// root frame coordinates.
PhysicalRect ScrollRectToVisible(const PhysicalRect&,
- const WebScrollIntoViewParams&);
+ mojom::blink::ScrollIntoViewParamsPtr);
// Convenience function for getting to the nearest enclosing box of a
// LayoutObject.
@@ -439,13 +445,7 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
}
}
- void AssertClearedPaintInvalidationFlags() const {
- if (PaintInvalidationStateIsDirty() &&
- !PrePaintBlockedByDisplayLock(DisplayLockLifecycleTarget::kChildren)) {
- ShowLayoutTreeForThis();
- NOTREACHED();
- }
- }
+ void AssertClearedPaintInvalidationFlags() const;
void AssertSubtreeClearedPaintInvalidationFlags() const {
for (const LayoutObject* layout_object = this; layout_object;
@@ -644,6 +644,9 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
}
bool IsFrame() const { return IsOfType(kLayoutObjectFrame); }
bool IsFrameSet() const { return IsOfType(kLayoutObjectFrameSet); }
+ bool IsInsideListMarker() const {
+ return IsOfType(kLayoutObjectInsideListMarker);
+ }
bool IsLayoutNGBlockFlow() const {
return IsOfType(kLayoutObjectNGBlockFlow);
}
@@ -652,25 +655,27 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
}
bool IsLayoutNGMixin() const { return IsOfType(kLayoutObjectNGMixin); }
bool IsLayoutNGListItem() const { return IsOfType(kLayoutObjectNGListItem); }
- bool IsLayoutNGListMarker() const {
- return IsOfType(kLayoutObjectNGListMarker);
- }
bool IsLayoutNGInsideListMarker() const {
return IsOfType(kLayoutObjectNGInsideListMarker);
}
bool IsLayoutNGListMarkerImage() const {
return IsOfType(kLayoutObjectNGListMarkerImage);
}
+ bool IsLayoutNGOutsideListMarker() const {
+ return IsOfType(kLayoutObjectNGOutsideListMarker);
+ }
bool IsLayoutNGProgress() const { return IsOfType(kLayoutObjectNGProgress); }
bool IsLayoutNGText() const { return IsOfType(kLayoutObjectNGText); }
bool IsLayoutTableCol() const {
return IsOfType(kLayoutObjectLayoutTableCol);
}
- bool IsListBox() const { return IsOfType(kLayoutObjectListBox); }
bool IsListItem() const { return IsOfType(kLayoutObjectListItem); }
- bool IsListMarker() const { return IsOfType(kLayoutObjectListMarker); }
+ bool IsMathML() const { return IsOfType(kLayoutObjectMathML); }
+ bool IsMathMLRoot() const { return IsOfType(kLayoutObjectMathMLRoot); }
bool IsMedia() const { return IsOfType(kLayoutObjectMedia); }
- bool IsMenuList() const { return IsOfType(kLayoutObjectMenuList); }
+ bool IsOutsideListMarker() const {
+ return IsOfType(kLayoutObjectOutsideListMarker);
+ }
bool IsProgress() const { return IsOfType(kLayoutObjectProgress); }
bool IsQuote() const { return IsOfType(kLayoutObjectQuote); }
bool IsLayoutButton() const { return IsOfType(kLayoutObjectLayoutButton); }
@@ -832,11 +837,8 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
bool IsSVGResourceContainer() const {
return IsOfType(kLayoutObjectSVGResourceContainer);
}
- bool IsSVGResourceFilter() const {
- return IsOfType(kLayoutObjectSVGResourceFilter);
- }
- bool IsSVGResourceFilterPrimitive() const {
- return IsOfType(kLayoutObjectSVGResourceFilterPrimitive);
+ bool IsSVGFilterPrimitive() const {
+ return IsOfType(kLayoutObjectSVGFilterPrimitive);
}
// FIXME: Those belong into a SVG specific base-class for all layoutObjects
@@ -1072,14 +1074,14 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
}
bool NeedsCollectInlines() const { return bitfields_.NeedsCollectInlines(); }
- // Return true if the min/max preferred logical widths aren't up-to-date. Note
- // that for objects that *don't* need to calculate preferred logical widths
- // (e.g. if inline-size is a fixed value, and no other inline lengths are
- // intrinsic, and the object isn't a descendant of something that needs
+ // Return true if the min/max intrinsic logical widths aren't up-to-date.
+ // Note that for objects that *don't* need to calculate intrinsic logical
+ // widths (e.g. if inline-size is a fixed value, and no other inline lengths
+ // are intrinsic, and the object isn't a descendant of something that needs
// min/max), this flag will never be cleared (since the values will never be
// calculated).
- bool PreferredLogicalWidthsDirty() const {
- return bitfields_.PreferredLogicalWidthsDirty();
+ bool IntrinsicLogicalWidthsDirty() const {
+ return bitfields_.IntrinsicLogicalWidthsDirty();
}
bool NeedsLayoutOverflowRecalc() const {
@@ -1343,20 +1345,27 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
void SetChildNeedsLayout(MarkingBehavior = kMarkContainerChain,
SubtreeLayoutScope* = nullptr);
void SetNeedsPositionedMovementLayout();
- void SetPreferredLogicalWidthsDirty(MarkingBehavior = kMarkContainerChain);
- void ClearPreferredLogicalWidthsDirty();
+ void SetIntrinsicLogicalWidthsDirty(MarkingBehavior = kMarkContainerChain);
+ void ClearIntrinsicLogicalWidthsDirty();
- void SetNeedsLayoutAndPrefWidthsRecalc(
+ void SetNeedsLayoutAndIntrinsicWidthsRecalc(
LayoutInvalidationReasonForTracing reason) {
SetNeedsLayout(reason);
- SetPreferredLogicalWidthsDirty();
+ SetIntrinsicLogicalWidthsDirty();
}
- void SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ void SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
LayoutInvalidationReasonForTracing reason) {
SetNeedsLayoutAndFullPaintInvalidation(reason);
- SetPreferredLogicalWidthsDirty();
+ SetIntrinsicLogicalWidthsDirty();
}
+ // Traverses subtree, and marks all layout objects as need relayout, repaint
+ // and preferred width recalc. Also invalidates shaping on all text nodes.
+ // TODO(crbug.com/441925): Try to partially invalidate layout on font updates.
+ virtual void InvalidateSubtreeLayoutForFontUpdates();
+
+ void InvalidateIntersectionObserverCachedRects();
+
void SetPositionState(EPosition position) {
DCHECK(
(position != EPosition::kAbsolute && position != EPosition::kFixed) ||
@@ -1368,10 +1377,24 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
void SetFloating(bool is_floating) { bitfields_.SetFloating(is_floating); }
void SetInline(bool is_inline) { bitfields_.SetIsInline(is_inline); }
+ // Return whether we can directly traverse fragments generated for this layout
+ // object, when it comes to painting, hit-testing and other layout read
+ // operations. If false is returned, we need to traverse the layout object
+ // tree instead.
+ //
+ // It is not allowed to call this method on a non-LayoutBox object, unless its
+ // containing block is an NG object (e.g. not allowed to call it on a
+ // LayoutInline that's contained by a legacy LayoutBlockFlow).
+ inline bool CanTraversePhysicalFragments() const;
+
// Returns the associated |NGPaintFragment|. When this is not a |nullptr|,
// this is the root of an inline formatting context, laid out by LayoutNG.
virtual const NGPaintFragment* PaintFragment() const { return nullptr; }
+ // Return true if |this| produces one or more inline fragments, including
+ // whitespace-only text fragments.
+ virtual bool HasInlineFragments() const { return false; }
+
// Paint/Physical fragments are not in sync with LayoutObject tree until it is
// laid out. For inline, it needs to check if the containing block is
// layout-clean. crbug.com/963103
@@ -1479,6 +1502,9 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
virtual void AddAnnotatedRegions(Vector<AnnotatedRegionValue>&);
CompositingState GetCompositingState() const;
+
+ // True for object types which override |AdditionalCompositingReasons|.
+ virtual bool CanHaveAdditionalCompositingReasons() const;
virtual CompositingReasons AdditionalCompositingReasons() const;
// |accumulated_offset| is accumulated physical offset of this object from
@@ -1563,6 +1589,11 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
// See LayoutBlock.h for some extra explanations on containing blocks.
LayoutBlock* ContainingBlock(AncestorSkipInfo* = nullptr) const;
+ // Returns |container|'s containing block.
+ static LayoutBlock* FindNonAnonymousContainingBlock(
+ LayoutObject* container,
+ AncestorSkipInfo* = nullptr);
+
const LayoutBlock* InclusiveContainingBlock() const;
bool CanContainAbsolutePositionObjects() const {
@@ -1725,8 +1756,6 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
virtual void AbsoluteQuads(Vector<FloatQuad>&,
MapCoordinatesFlags mode = 0) const {}
- static FloatRect AbsoluteBoundingBoxRectForRange(const EphemeralRange&);
-
// The bounding box (see: absoluteBoundingBoxRect) including all descendant
// bounding boxes.
IntRect AbsoluteBoundingBoxRectIncludingDescendants() const;
@@ -1736,28 +1765,20 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
// to any ancestor using, e.g., localToAncestorTransform.
virtual FloatRect LocalBoundingBoxRectForAccessibility() const = 0;
- // This function returns the minimal logical width this object can have
- // without overflowing. This means that all the opportunities for wrapping
- // have been taken.
+ // This function returns the:
+ // - Minimal logical width this object can have without overflowing. This
+ // means that all the opportunities for wrapping have been taken.
+ // - Maximal logical width.
//
// See INTRINSIC SIZES / PREFERRED LOGICAL WIDTHS above.
//
- // CSS 2.1 calls this width the "preferred minimum width" (thus this name)
- // and "minimum content width" (for table).
- // However CSS 3 calls it the "min-content inline size".
+ // CSS 2.1 calls this width the "preferred minimum width"/"preferred width"
+ // (thus this name) and "minimum content width" (for table).
+ // However CSS 3 calls it the "min/max-content inline size".
// https://drafts.csswg.org/css-sizing-3/#min-content-inline-size
- // TODO(jchaffraix): We will probably want to rename it to match CSS 3.
- virtual LayoutUnit MinPreferredLogicalWidth() const { return LayoutUnit(); }
-
- // This function returns the maximum logical width this object can have.
- //
- // See INTRINSIC SIZES / PREFERRED LOGICAL WIDTHS above.
- //
- // CSS 2.1 calls this width the "preferred width". However CSS 3 calls it
- // the "max-content inline size".
// https://drafts.csswg.org/css-sizing-3/#max-content-inline-size
// TODO(jchaffraix): We will probably want to rename it to match CSS 3.
- virtual LayoutUnit MaxPreferredLogicalWidth() const { return LayoutUnit(); }
+ virtual MinMaxSizes PreferredLogicalWidths() const { return MinMaxSizes(); }
const ComputedStyle* Style() const { return style_.get(); }
@@ -1791,7 +1812,7 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
return StyleRef().VisitedDependentColor(color_property);
}
- virtual CursorDirective GetCursor(const PhysicalOffset&, Cursor&) const;
+ virtual CursorDirective GetCursor(const PhysicalOffset&, ui::Cursor&) const;
// Return the LayoutBoxModelObject in the container chain which is responsible
// for painting this object. The function crosses frames boundaries so the
@@ -1860,6 +1881,14 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
TransformState&,
VisualRectFlags = kDefaultVisualRectFlags) const;
+ // Returns the nearest ancestor in the containing block chain that
+ // HasLocalBorderBoxProperties. If AncestorSkipInfo* is non-null and the
+ // ancestor was skipped, returns nullptr. If PropertyTreeState* is non-null,
+ // it will be populated with paint property nodes suitable for mapping upward
+ // from the coordinate system of the property container.
+ const LayoutObject* GetPropertyContainer(AncestorSkipInfo*,
+ PropertyTreeState* = nullptr) const;
+
// Do a rect-based hit test with this object as the stop node.
HitTestResult HitTestForOcclusion(const PhysicalRect&) const;
HitTestResult HitTestForOcclusion() const {
@@ -1879,6 +1908,15 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
return (IsFloating() || IsOutOfFlowPositioned());
}
+ // Outside list markers are in-flow but behave kind of out-of-flowish.
+ // We include them here to prevent code like '<li> <ol></ol></li>' from
+ // generating an anonymous block box for the whitespace between the marker
+ // and the <ol>.
+ bool AffectsWhitespaceSiblings() const {
+ return !IsFloatingOrOutOfFlowPositioned() &&
+ !IsLayoutNGOutsideListMarker() && !IsOutsideListMarker();
+ }
+
bool HasReflection() const { return bitfields_.HasReflection(); }
// The current selection state for an object. For blocks, the state refers to
@@ -1932,12 +1970,7 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
void DestroyAndCleanupAnonymousWrappers();
- // While the destroy() method is virtual, this should only be overriden in
- // very rare circumstances.
- // You want to override willBeDestroyed() instead unless you explicitly need
- // to stop this object from being destroyed (for example,
- // LayoutEmbeddedContent overrides destroy() for this purpose).
- virtual void Destroy();
+ void Destroy();
// Virtual function helpers for the deprecated Flexible Box Layout (display:
// -webkit-box).
@@ -1958,14 +1991,14 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
// 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.
- bool IsListMarkerIncludingNG() const {
- return IsListMarker() || IsLayoutNGListMarker();
+ bool IsListMarker() const {
+ return IsOutsideListMarker() || IsInsideListMarker();
}
- bool IsLayoutNGListMarkerIncludingInside() const {
- return IsLayoutNGListMarker() || IsLayoutNGInsideListMarker();
+ bool IsListMarkerIncludingNGOutside() const {
+ return IsListMarker() || IsLayoutNGOutsideListMarker();
}
- bool IsListMarkerIncludingNGInside() const {
- return IsListMarker() || IsLayoutNGListMarkerIncludingInside();
+ bool IsListMarkerIncludingNGOutsideAndInside() const {
+ return IsListMarkerIncludingNGOutside() || IsLayoutNGInsideListMarker();
}
virtual bool IsCombineText() const { return false; }
@@ -2176,8 +2209,12 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
// Returns the bounding box of the visual rects of all fragments.
IntRect FragmentsVisualRectBoundingBox() const;
- void SetNeedsOverflowRecalc();
- void SetNeedsVisualOverflowAndPaintInvalidation();
+ enum OverflowRecalcType {
+ kOnlyVisualOverflowRecalc,
+ kLayoutAndVisualOverflowRecalc,
+ };
+ void SetNeedsOverflowRecalc(
+ OverflowRecalcType = OverflowRecalcType::kLayoutAndVisualOverflowRecalc);
void InvalidateClipPathCache();
@@ -2189,11 +2226,11 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
// (from style) and blocking touch event handlers.
TouchAction EffectiveAllowedTouchAction() const {
if (InsideBlockingTouchEventHandler())
- return TouchAction::kTouchActionNone;
+ return TouchAction::kNone;
return StyleRef().GetEffectiveTouchAction();
}
bool HasEffectiveAllowedTouchAction() const {
- return EffectiveAllowedTouchAction() != TouchAction::kTouchActionAuto;
+ return EffectiveAllowedTouchAction() != TouchAction::kAuto;
}
// Whether this object's Node has a blocking touch event handler on itself
@@ -2239,7 +2276,13 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
}
}
void SetShouldCheckForPaintInvalidation() {
- layout_object_.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
+ // entire containing block chain.
+ DCHECK_EQ(layout_object_.GetDocument().Lifecycle().GetState(),
+ DocumentLifecycle::kInPrePaint);
+ layout_object_.bitfields_.SetNeedsPaintOffsetAndVisualRectUpdate(true);
+ layout_object_.bitfields_.SetShouldCheckForPaintInvalidation(true);
}
void SetShouldDoFullPaintInvalidation(PaintInvalidationReason reason) {
layout_object_.SetShouldDoFullPaintInvalidation(reason);
@@ -2272,9 +2315,10 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
layout_object_.fragment_.SetSelectionVisualRect(r);
}
- void SetPreviousBackgroundPaintLocation(BackgroundPaintLocation location) {
- layout_object_.bitfields_.SetPreviousBackgroundPaintLocation(location);
+ void SetBackgroundPaintLocation(BackgroundPaintLocation location) {
+ layout_object_.SetBackgroundPaintLocation(location);
}
+
void UpdatePreviousOutlineMayBeAffectedByDescendants() {
layout_object_.SetPreviousOutlineMayBeAffectedByDescendants(
layout_object_.OutlineMayBeAffectedByDescendants());
@@ -2303,6 +2347,10 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
layout_object_.UpdateInsideBlockingTouchEventHandler(inside);
}
+ void InvalidateIntersectionObserverCachedRects() {
+ layout_object_.InvalidateIntersectionObserverCachedRects();
+ }
+
#if DCHECK_IS_ON()
// Same as setNeedsPaintPropertyUpdate() but does not mark ancestors as
// having a descendant needing a paint property update.
@@ -2352,6 +2400,7 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
// updated, SetNeedsPaintPropertyUpdate marks all ancestors as having a
// descendant needing a paint property update too.
void SetNeedsPaintPropertyUpdate();
+ void SetNeedsPaintPropertyUpdatePreservingCachedRects();
bool NeedsPaintPropertyUpdate() const {
return bitfields_.NeedsPaintPropertyUpdate();
}
@@ -2387,8 +2436,14 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
bool CompositedScrollsWithRespectTo(
const LayoutBoxModelObject& paint_invalidation_container) const;
- BackgroundPaintLocation PreviousBackgroundPaintLocation() const {
- return bitfields_.PreviousBackgroundPaintLocation();
+ BackgroundPaintLocation GetBackgroundPaintLocation() const {
+ return bitfields_.GetBackgroundPaintLocation();
+ }
+ void SetBackgroundPaintLocation(BackgroundPaintLocation location) {
+ if (GetBackgroundPaintLocation() != location) {
+ SetBackgroundNeedsFullPaintInvalidation();
+ bitfields_.SetBackgroundPaintLocation(location);
+ }
}
bool IsBackgroundAttachmentFixedObject() const {
@@ -2467,8 +2522,10 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
bitfields_.SetHasNonCollapsedBorderDecoration(b);
}
+ bool BeingDestroyed() const { return bitfields_.BeingDestroyed(); }
+
DisplayLockContext* GetDisplayLockContext() const {
- if (!RuntimeEnabledFeatures::DisplayLockingEnabled(&GetDocument()))
+ if (!RuntimeEnabledFeatures::CSSSubtreeVisibilityEnabled())
return nullptr;
auto* element = DynamicTo<Element>(GetNode());
if (!element)
@@ -2487,22 +2544,23 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
kLayoutObjectFileUploadControl,
kLayoutObjectFrame,
kLayoutObjectFrameSet,
+ kLayoutObjectInsideListMarker,
kLayoutObjectLayoutTableCol,
- kLayoutObjectListBox,
kLayoutObjectListItem,
- kLayoutObjectListMarker,
+ kLayoutObjectMathML,
+ kLayoutObjectMathMLRoot,
kLayoutObjectMedia,
- kLayoutObjectMenuList,
kLayoutObjectNGBlockFlow,
kLayoutObjectNGFieldset,
kLayoutObjectNGFlexibleBox,
kLayoutObjectNGMixin,
kLayoutObjectNGListItem,
- kLayoutObjectNGListMarker,
kLayoutObjectNGInsideListMarker,
+ kLayoutObjectNGOutsideListMarker,
kLayoutObjectNGListMarkerImage,
kLayoutObjectNGProgress,
kLayoutObjectNGText,
+ kLayoutObjectOutsideListMarker,
kLayoutObjectProgress,
kLayoutObjectQuote,
kLayoutObjectLayoutButton,
@@ -2549,11 +2607,19 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
kLayoutObjectSVGImage,
kLayoutObjectSVGForeignObject,
kLayoutObjectSVGResourceContainer,
- kLayoutObjectSVGResourceFilter,
- kLayoutObjectSVGResourceFilterPrimitive,
+ kLayoutObjectSVGFilterPrimitive,
};
virtual bool IsOfType(LayoutObjectType type) const { return false; }
+ // While the |DeleteThis()| method is virtual, this should only be overridden
+ // in very rare circumstances.
+ // You want to override |WillBeDestroyed()| instead unless you explicitly need
+ // to stop this object from being destroyed (for example,
+ // |LayoutEmbeddedContent| overrides |DeleteThis()| for this purpose).
+ virtual void DeleteThis();
+
+ void SetBeingDestroyedForTesting() { bitfields_.SetBeingDestroyed(true); }
+
const ComputedStyle& SlowEffectiveStyle(NGStyleVariant style_variant) const;
// Updates only the local style ptr of the object. Does not update the state
@@ -2661,10 +2727,6 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
bitfields_.SetBackgroundIsKnownToBeObscured(b);
}
- // Returns |container|'s containing block.
- static LayoutBlock* FindNonAnonymousContainingBlock(
- LayoutObject* container,
- AncestorSkipInfo* = nullptr);
// Returns ContainerForAbsolutePosition() if it's a LayoutBlock, or the
// containing LayoutBlock of it.
LayoutBlock* ContainingBlockForAbsolutePosition(
@@ -2709,11 +2771,13 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
// scroll anchoring on.
void SetScrollAnchorDisablingStyleChangedOnAncestor();
- inline void MarkContainerChainForOverflowRecalcIfNeeded();
+ bool SelfPaintingLayerNeedsVisualOverflowRecalc() const;
+ inline void MarkContainerChainForOverflowRecalcIfNeeded(
+ bool mark_container_chain_layout_overflow_recalc);
inline void SetNeedsPaintOffsetAndVisualRectUpdate();
- inline void InvalidateContainerPreferredLogicalWidths();
+ inline void InvalidateContainerIntrinsicLogicalWidths();
const LayoutBoxModelObject* EnclosingCompositedContainer() const;
@@ -2810,7 +2874,7 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
needs_simplified_normal_flow_layout_(false),
self_needs_layout_overflow_recalc_(false),
child_needs_layout_overflow_recalc_(false),
- preferred_logical_widths_dirty_(false),
+ intrinsic_logical_widths_dirty_(false),
needs_collect_inlines_(false),
should_check_for_paint_invalidation_(true),
subtree_should_check_for_paint_invalidation_(false),
@@ -2864,11 +2928,12 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
registered_as_first_line_image_observer_(false),
is_html_legend_element_(false),
has_non_collapsed_border_decoration_(false),
+ being_destroyed_(false),
positioned_state_(kIsStaticallyPositioned),
selection_state_(static_cast<unsigned>(SelectionState::kNone)),
subtree_paint_property_update_reasons_(
static_cast<unsigned>(SubtreePaintPropertyUpdateReason::kNone)),
- previous_background_paint_location_(0) {}
+ background_paint_location_(kBackgroundPaintInGraphicsLayer) {}
// Self needs layout for style means that this layout object is marked for a
// full layout. This is the default layout but it is expensive as it
@@ -2918,12 +2983,12 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
ADD_BOOLEAN_BITFIELD(child_needs_layout_overflow_recalc_,
ChildNeedsLayoutOverflowRecalc);
- // This boolean marks preferred logical widths for lazy recomputation.
+ // This boolean marks the intrinsic logical widths for lazy recomputation.
//
// See INTRINSIC SIZES / PREFERRED LOGICAL WIDTHS above about those
// widths.
- ADD_BOOLEAN_BITFIELD(preferred_logical_widths_dirty_,
- PreferredLogicalWidthsDirty);
+ ADD_BOOLEAN_BITFIELD(intrinsic_logical_widths_dirty_,
+ IntrinsicLogicalWidthsDirty);
// This flag is set on inline container boxes that need to run the
// Pre-layout phase in LayoutNG. See NGInlineNode::CollectInlines().
@@ -3124,6 +3189,9 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
ADD_BOOLEAN_BITFIELD(has_non_collapsed_border_decoration_,
HasNonCollapsedBorderDecoration);
+ // True at start of |Destroy()| before calling |WillBeDestroyed()|.
+ ADD_BOOLEAN_BITFIELD(being_destroyed_, BeingDestroyed);
+
private:
// This is the cached 'position' value of this object
// (see ComputedStyle::position).
@@ -3134,8 +3202,9 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
unsigned subtree_paint_property_update_reasons_
: kSubtreePaintPropertyUpdateReasonsBitfieldWidth;
- // BackgroundPaintLocation of previous paint invalidation.
- unsigned previous_background_paint_location_ : 2;
+ // Updated during CompositingUpdate in pre-CompositeAfterPaint, or PrePaint
+ // in CompositeAfterPaint.
+ unsigned background_paint_location_ : 2; // BackgroundPaintLocation.
public:
bool IsOutOfFlowPositioned() const {
@@ -3202,15 +3271,13 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver,
static_cast<unsigned>(SubtreePaintPropertyUpdateReason::kNone);
}
- ALWAYS_INLINE BackgroundPaintLocation
- PreviousBackgroundPaintLocation() const {
- return static_cast<BackgroundPaintLocation>(
- previous_background_paint_location_);
+ ALWAYS_INLINE BackgroundPaintLocation GetBackgroundPaintLocation() const {
+ return static_cast<BackgroundPaintLocation>(background_paint_location_);
}
- ALWAYS_INLINE void SetPreviousBackgroundPaintLocation(
+ ALWAYS_INLINE void SetBackgroundPaintLocation(
BackgroundPaintLocation location) {
- previous_background_paint_location_ = static_cast<unsigned>(location);
- DCHECK_EQ(location, PreviousBackgroundPaintLocation());
+ background_paint_location_ = static_cast<unsigned>(location);
+ DCHECK_EQ(location, GetBackgroundPaintLocation());
}
};
@@ -3290,6 +3357,33 @@ inline bool LayoutObject::IsBeforeOrAfterContent() const {
return IsBeforeContent() || IsAfterContent();
}
+inline bool LayoutObject::CanTraversePhysicalFragments() const {
+ if (LIKELY(!RuntimeEnabledFeatures::LayoutNGFragmentTraversalEnabled()))
+ return false;
+ // Non-NG objects should be painted by legacy.
+ if (!IsLayoutNGObject()) {
+ if (IsBox())
+ return false;
+ // Non-LayoutBox objects (such as LayoutInline) don't necessarily create NG
+ // LayoutObjects. If they are laid out by an NG container, though, we may be
+ // allowed to traverse their fragments. Otherwise, bail now.
+ if (!IsInLayoutNGInlineFormattingContext())
+ return false;
+ }
+ // Bail if we have an NGPaintFragment. NGPaintFragment will be removed, and we
+ // will not attempt to add support for them here.
+ if (PaintFragment())
+ return false;
+ // We don't support fragmentation traversal inside block fragmentation just
+ // yet.
+ if (IsInsideFlowThread())
+ return false;
+ // The NG paint system currently doesn't support table-cells.
+ if (IsTableCell())
+ return false;
+ return true;
+}
+
// setNeedsLayout() won't cause full paint invalidations as
// setNeedsLayoutAndFullPaintInvalidation() does. Otherwise the two methods are
// identical.
@@ -3428,6 +3522,9 @@ CORE_EXPORT std::ostream& operator<<(std::ostream&, const LayoutObject&);
DEFINE_TYPE_CASTS(thisType, LayoutObject, object, object->predicate, \
object.predicate)
+bool IsMenuList(const LayoutObject* object);
+CORE_EXPORT bool IsListBox(const LayoutObject* object);
+
} // namespace blink
#if DCHECK_IS_ON()
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_object_child_list.cc b/chromium/third_party/blink/renderer/core/layout/layout_object_child_list.cc
index fb9db0a519e..8a71bc3a13b 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_object_child_list.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_object_child_list.cc
@@ -58,7 +58,11 @@ void InvalidateInlineItems(LayoutObject* object) {
}
}
- if (NGPaintFragment* fragment = object->FirstInlineFragment()) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ // TODO(yosin): Tells |NGFragmentItem| about they become not to associate
+ // to layout object.
+ object->ClearFirstInlineFragmentItemIndex();
+ } else if (NGPaintFragment* fragment = object->FirstInlineFragment()) {
// This LayoutObject is not technically destroyed, but further access should
// be prohibited when moved to different parent as if it were destroyed.
fragment->LayoutObjectWillBeDestroyed();
@@ -70,20 +74,13 @@ void InvalidateInlineItems(LayoutObject* object) {
} // namespace
void LayoutObjectChildList::DestroyLeftoverChildren() {
- while (FirstChild()) {
- // List markers are owned by their enclosing list and so don't get destroyed
- // by this container.
- if (FirstChild()->IsListMarkerIncludingNG()) {
- FirstChild()->Remove();
- continue;
- }
-
- // Destroy any anonymous children remaining in the layout tree, as well as
- // implicit (shadow) DOM elements like those used in the engine-based text
- // fields.
- if (FirstChild()->GetNode())
- FirstChild()->GetNode()->SetLayoutObject(nullptr);
- FirstChild()->Destroy();
+ // Destroy any anonymous children remaining in the layout tree, as well as
+ // implicit (shadow) DOM elements like those used in the engine-based text
+ // fields.
+ while (LayoutObject* child = FirstChild()) {
+ if (Node* child_node = child->GetNode())
+ child_node->SetLayoutObject(nullptr);
+ child->Destroy();
}
}
@@ -103,7 +100,7 @@ LayoutObject* LayoutObjectChildList::RemoveChildNode(
// issue paint invalidations, so that the area exposed when the child
// disappears gets paint invalidated properly.
if (notify_layout_object && old_child->EverHadLayout()) {
- old_child->SetNeedsLayoutAndPrefWidthsRecalc(
+ old_child->SetNeedsLayoutAndIntrinsicWidthsRecalc(
layout_invalidation_reason::kRemovedFromLayout);
if (old_child->IsOutOfFlowPositioned() &&
RuntimeEnabledFeatures::LayoutNGEnabled())
@@ -129,6 +126,8 @@ LayoutObject* LayoutObjectChildList::RemoveChildNode(
if (old_child->IsInLayoutNGInlineFormattingContext()) {
owner->SetChildNeedsCollectInlines();
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ InvalidateInlineItems(old_child);
}
}
@@ -184,6 +183,12 @@ void LayoutObjectChildList::InsertChildNode(LayoutObject* owner,
return;
}
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled() &&
+ !owner->DocumentBeingDestroyed() &&
+ new_child->IsInLayoutNGInlineFormattingContext()) {
+ InvalidateInlineItems(new_child);
+ }
+
new_child->SetParent(owner);
if (FirstChild() == before_child)
@@ -239,7 +244,7 @@ void LayoutObjectChildList::InsertChildNode(LayoutObject* owner,
// actually happens.
}
- new_child->SetNeedsLayoutAndPrefWidthsRecalc(
+ new_child->SetNeedsLayoutAndIntrinsicWidthsRecalc(
layout_invalidation_reason::kAddedToLayout);
if (new_child->IsOutOfFlowPositioned() &&
RuntimeEnabledFeatures::LayoutNGEnabled())
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 00524e1719a..5ec6031ef59 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
@@ -5,10 +5,15 @@
#include "third_party/blink/renderer/core/layout/layout_object_factory.h"
#include "third_party/blink/renderer/core/dom/element.h"
+#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
+#include "third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.h"
#include "third_party/blink/renderer/core/layout/layout_fieldset.h"
+#include "third_party/blink/renderer/core/layout/layout_file_upload_control.h"
#include "third_party/blink/renderer/core/layout/layout_flexible_box.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_outside_list_marker.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_text.h"
@@ -24,7 +29,7 @@
#include "third_party/blink/renderer/core/layout/ng/layout_ng_table_cell.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_list_marker.h"
+#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -74,9 +79,26 @@ LayoutBlockFlow* LayoutObjectFactory::CreateBlockFlow(
Node& node,
const ComputedStyle& style,
LegacyLayout legacy) {
+ if (style.Display() == EDisplay::kListItem) {
+ // Create a LayoutBlockFlow with a list marker
+ return CreateObject<LayoutBlockFlow, LayoutNGListItem, LayoutListItem>(
+ node, style, legacy);
+ }
+
+ // Create a plain LayoutBlockFlow
return CreateObject<LayoutBlockFlow, LayoutNGBlockFlow>(node, style, legacy);
}
+// static
+LayoutBlock* LayoutObjectFactory::CreateBlockForLineClamp(
+ Node& node,
+ const ComputedStyle& style,
+ LegacyLayout legacy) {
+ DCHECK(RuntimeEnabledFeatures::BlockFlowHandlesWebkitLineClampEnabled());
+ return CreateObject<LayoutBlock, LayoutNGBlockFlow,
+ LayoutDeprecatedFlexibleBox>(node, style, legacy);
+}
+
LayoutBlock* LayoutObjectFactory::CreateFlexibleBox(Node& node,
const ComputedStyle& style,
LegacyLayout legacy) {
@@ -85,28 +107,20 @@ LayoutBlock* LayoutObjectFactory::CreateFlexibleBox(Node& node,
node, style, legacy, disable_ng_for_type);
}
-LayoutBlockFlow* LayoutObjectFactory::CreateListItem(Node& node,
- const ComputedStyle& style,
- LegacyLayout legacy) {
- return CreateObject<LayoutBlockFlow, LayoutNGListItem, LayoutListItem>(
- node, style, legacy);
-}
-
LayoutObject* LayoutObjectFactory::CreateListMarker(Node& node,
const ComputedStyle& style,
LegacyLayout legacy) {
- // TODO(obrufau): allow ::marker pseudo-elements to generate legacy layout.
- if (!RuntimeEnabledFeatures::LayoutNGEnabled() ||
- legacy == LegacyLayout::kForce)
- return nullptr;
- // TODO(obrufau): markers may be forced to be inside despite having
- // `list-style-position: outside`.
- if (style.ListStylePosition() == EListStylePosition::kInside) {
+ const Node* parent = node.parentNode();
+ const ComputedStyle* parent_style = parent->GetComputedStyle();
+ bool is_inside =
+ parent_style->ListStylePosition() == EListStylePosition::kInside ||
+ (IsA<HTMLLIElement>(parent) && !parent_style->IsInsideListElement());
+ if (is_inside) {
return CreateObject<LayoutObject, LayoutNGInsideListMarker,
- LayoutNGInsideListMarker>(node, style, legacy);
+ LayoutInsideListMarker>(node, style, legacy);
}
- return CreateObject<LayoutObject, LayoutNGListMarker, LayoutNGListMarker>(
- node, style, legacy);
+ return CreateObject<LayoutObject, LayoutNGOutsideListMarker,
+ LayoutOutsideListMarker>(node, style, legacy);
}
LayoutTableCaption* LayoutObjectFactory::CreateTableCaption(
@@ -132,6 +146,14 @@ LayoutBlock* LayoutObjectFactory::CreateFieldset(Node& node,
node, style, legacy, disable_ng_for_type);
}
+LayoutBlockFlow* LayoutObjectFactory::CreateFileUploadControl(
+ Node& node,
+ const ComputedStyle& style,
+ LegacyLayout legacy) {
+ return CreateObject<LayoutBlockFlow, LayoutNGBlockFlow,
+ LayoutFileUploadControl>(node, style, legacy);
+}
+
LayoutText* LayoutObjectFactory::CreateText(Node* node,
scoped_refptr<StringImpl> str,
LegacyLayout legacy) {
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 4fc7ac0f5af..37428424c92 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
@@ -38,12 +38,12 @@ class LayoutObjectFactory {
static LayoutBlockFlow* CreateBlockFlow(Node&,
const ComputedStyle&,
LegacyLayout);
+ static LayoutBlock* CreateBlockForLineClamp(Node& node,
+ const ComputedStyle& style,
+ LegacyLayout legacy);
static LayoutBlock* CreateFlexibleBox(Node&,
const ComputedStyle&,
LegacyLayout);
- static LayoutBlockFlow* CreateListItem(Node&,
- const ComputedStyle&,
- LegacyLayout);
static LayoutObject* CreateListMarker(Node&,
const ComputedStyle&,
LegacyLayout);
@@ -54,6 +54,9 @@ class LayoutObjectFactory {
const ComputedStyle&,
LegacyLayout);
static LayoutBlock* CreateFieldset(Node&, const ComputedStyle&, LegacyLayout);
+ static LayoutBlockFlow* CreateFileUploadControl(Node& node,
+ const ComputedStyle& style,
+ LegacyLayout legacy);
static LayoutText* CreateText(Node*, scoped_refptr<StringImpl>, LegacyLayout);
static LayoutTextFragment* CreateTextFragment(Node*,
StringImpl*,
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 bc06001fd8a..d1d45474fa0 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
@@ -530,6 +530,7 @@ TEST_F(LayoutObjectTest, VisualRect) {
class MockLayoutObject : public LayoutObject {
public:
MockLayoutObject() : LayoutObject(nullptr) {}
+ ~MockLayoutObject() override { SetBeingDestroyedForTesting(); }
MOCK_CONST_METHOD0(VisualRectRespectsVisibility, bool());
private:
@@ -856,8 +857,7 @@ TEST_F(LayoutObjectTest, UpdateVisualRectAfterAncestorLayout) {
class LayoutObjectSimTest : public SimTest {
public:
bool DocumentHasTouchActionRegion(const EventHandlerRegistry& registry) {
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
return registry.HasEventHandlers(
EventHandlerRegistry::EventHandlerClass::kTouchAction);
}
@@ -930,8 +930,7 @@ TEST_F(LayoutObjectSimTest, HitTestForOcclusionInIframe) {
<div id='target'>target</div>
)HTML");
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
Element* iframe_element = GetDocument().QuerySelector("iframe");
auto* frame_owner_element = To<HTMLFrameOwnerElement>(iframe_element);
Document* iframe_doc = frame_owner_element->contentDocument();
@@ -941,8 +940,7 @@ TEST_F(LayoutObjectSimTest, HitTestForOcclusionInIframe) {
Element* occluder = GetDocument().getElementById("occluder");
occluder->SetInlineStyleProperty(CSSPropertyID::kMarginTop, "-150px");
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
result = target->GetLayoutObject()->HitTestForOcclusion();
EXPECT_EQ(result.InnerNode(), occluder);
}
@@ -965,8 +963,7 @@ TEST_F(LayoutObjectSimTest, FirstLineBackgroundImage) {
<div>To keep the image alive when target is set display: none</div>
)HTML");
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
auto* target = GetDocument().getElementById("target");
auto* target_object = target->GetLayoutObject();
@@ -998,8 +995,7 @@ TEST_F(LayoutObjectSimTest, FirstLineBackgroundImage) {
EXPECT_FALSE(second_line->SlowFirstChild()->ShouldDoFullPaintInvalidation());
target->setAttribute(html_names::kStyleAttr, "display: none");
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
target_object = target->GetLayoutObject();
EXPECT_EQ(nullptr, target_object);
// The image is still alive because the other div's first line style still
@@ -1064,8 +1060,7 @@ TEST_F(LayoutObjectTest, FirstLineBackgroundImageChangeStyleCrash) {
UpdateAllLifecyclePhasesForTest();
}
-// TODO(rego): Test is failing until we can fix https://crbug.com/941180.
-TEST_F(LayoutObjectTest, DISABLED_NeedsLayoutOverflowRecalc) {
+TEST_F(LayoutObjectTest, NeedsLayoutOverflowRecalc) {
if (!RuntimeEnabledFeatures::LayoutNGEnabled())
return;
@@ -1089,7 +1084,7 @@ TEST_F(LayoutObjectTest, DISABLED_NeedsLayoutOverflowRecalc) {
EXPECT_FALSE(other->NeedsLayoutOverflowRecalc());
auto* target_element = GetDocument().getElementById("target");
- target_element->SetInnerHTMLFromString("baz");
+ target_element->setInnerHTML("baz");
UpdateAllLifecyclePhasesForTest();
EXPECT_FALSE(wrapper->NeedsLayoutOverflowRecalc());
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
new file mode 100644
index 00000000000..41956979cb9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/layout_outside_list_marker.cc
@@ -0,0 +1,14 @@
+// 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/layout_outside_list_marker.h"
+
+namespace blink {
+
+LayoutOutsideListMarker::LayoutOutsideListMarker(Element* element)
+ : LayoutListMarker(element) {}
+
+LayoutOutsideListMarker::~LayoutOutsideListMarker() = default;
+
+} // namespace blink
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
new file mode 100644
index 00000000000..20ff17c14a8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/layout_outside_list_marker.h
@@ -0,0 +1,33 @@
+// 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_OUTSIDE_LIST_MARKER_H_
+#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"
+
+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 {
+ public:
+ explicit LayoutOutsideListMarker(Element*);
+ ~LayoutOutsideListMarker() override;
+
+ const char* GetName() const override { return "LayoutOutsideListMarker"; }
+
+ private:
+ bool IsOfType(LayoutObjectType type) const override {
+ return type == kLayoutObjectOutsideListMarker ||
+ LayoutListMarker::IsOfType(type);
+ }
+};
+
+DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutOutsideListMarker, IsOutsideListMarker());
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_OUTSIDE_LIST_MARKER_H_
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 b74dbbaca8b..e5b86b519aa 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_replaced.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_replaced.cc
@@ -117,7 +117,7 @@ void LayoutReplaced::IntrinsicSizeChanged() {
int scaled_height =
static_cast<int>(kDefaultHeight * StyleRef().EffectiveZoom());
intrinsic_size_ = LayoutSize(scaled_width, scaled_height);
- SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kSizeChanged);
}
@@ -152,7 +152,7 @@ static inline bool LayoutObjectHasAspectRatio(
const LayoutObject* layout_object) {
DCHECK(layout_object);
return layout_object->IsImage() || layout_object->IsCanvas() ||
- layout_object->IsVideo();
+ IsA<LayoutVideo>(layout_object);
}
void LayoutReplaced::RecalcVisualOverflow() {
@@ -724,12 +724,14 @@ void LayoutReplaced::ComputeIntrinsicSizingInfo(
static inline LayoutUnit ResolveWidthForRatio(LayoutUnit height,
const FloatSize& aspect_ratio) {
- return LayoutUnit(height * aspect_ratio.Width() / aspect_ratio.Height());
+ return LayoutUnit(height.ToDouble() * aspect_ratio.Width() /
+ aspect_ratio.Height());
}
static inline LayoutUnit ResolveHeightForRatio(LayoutUnit width,
const FloatSize& aspect_ratio) {
- return LayoutUnit(width * aspect_ratio.Height() / aspect_ratio.Width());
+ return LayoutUnit(width.ToDouble() * aspect_ratio.Height() /
+ aspect_ratio.Width());
}
LayoutUnit LayoutReplaced::ComputeConstrainedLogicalWidth(
@@ -893,60 +895,45 @@ LayoutUnit LayoutReplaced::ComputeReplacedLogicalHeight(
IntrinsicLogicalHeight());
}
-void LayoutReplaced::ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const {
- min_logical_width = max_logical_width = IntrinsicLogicalWidth();
+MinMaxSizes LayoutReplaced::ComputeIntrinsicLogicalWidths() const {
+ MinMaxSizes sizes;
+ sizes += BorderAndPaddingLogicalWidth() + IntrinsicLogicalWidth();
+ return sizes;
}
-void LayoutReplaced::ComputePreferredLogicalWidths() {
- DCHECK(PreferredLogicalWidthsDirty());
+MinMaxSizes LayoutReplaced::PreferredLogicalWidths() const {
+ MinMaxSizes sizes;
// We cannot resolve some logical width here (i.e. percent, fill-available or
// fit-content) as the available logical width may not be set on our
// containing block.
const Length& logical_width = StyleRef().LogicalWidth();
if (logical_width.IsPercentOrCalc() || logical_width.IsFillAvailable() ||
- logical_width.IsFitContent())
- ComputeIntrinsicLogicalWidths(min_preferred_logical_width_,
- max_preferred_logical_width_);
- else
- min_preferred_logical_width_ = max_preferred_logical_width_ =
- ComputeReplacedLogicalWidth(kComputePreferred);
+ logical_width.IsFitContent()) {
+ sizes = IntrinsicLogicalWidths();
+ sizes -= BorderAndPaddingLogicalWidth();
+ } else {
+ sizes = ComputeReplacedLogicalWidth(kComputePreferred);
+ }
const ComputedStyle& style_to_use = StyleRef();
if (style_to_use.LogicalWidth().IsPercentOrCalc() ||
style_to_use.LogicalMaxWidth().IsPercentOrCalc())
- min_preferred_logical_width_ = LayoutUnit();
+ sizes.min_size = LayoutUnit();
if (style_to_use.LogicalMinWidth().IsFixed() &&
style_to_use.LogicalMinWidth().Value() > 0) {
- max_preferred_logical_width_ =
- std::max(max_preferred_logical_width_,
- AdjustContentBoxLogicalWidthForBoxSizing(
- style_to_use.LogicalMinWidth().Value()));
- min_preferred_logical_width_ =
- std::max(min_preferred_logical_width_,
- AdjustContentBoxLogicalWidthForBoxSizing(
- style_to_use.LogicalMinWidth().Value()));
+ sizes.Encompass(AdjustContentBoxLogicalWidthForBoxSizing(
+ style_to_use.LogicalMinWidth().Value()));
}
if (style_to_use.LogicalMaxWidth().IsFixed()) {
- max_preferred_logical_width_ =
- std::min(max_preferred_logical_width_,
- AdjustContentBoxLogicalWidthForBoxSizing(
- style_to_use.LogicalMaxWidth().Value()));
- min_preferred_logical_width_ =
- std::min(min_preferred_logical_width_,
- AdjustContentBoxLogicalWidthForBoxSizing(
- style_to_use.LogicalMaxWidth().Value()));
+ sizes.Constrain(AdjustContentBoxLogicalWidthForBoxSizing(
+ style_to_use.LogicalMaxWidth().Value()));
}
- LayoutUnit border_and_padding = BorderAndPaddingLogicalWidth();
- min_preferred_logical_width_ += border_and_padding;
- max_preferred_logical_width_ += border_and_padding;
-
- ClearPreferredLogicalWidthsDirty();
+ sizes += BorderAndPaddingLogicalWidth();
+ return sizes;
}
static std::pair<LayoutUnit, LayoutUnit> SelectionTopAndBottom(
@@ -975,14 +962,15 @@ static std::pair<LayoutUnit, LayoutUnit> SelectionTopAndBottom(
// Step 2: Return the logical top and bottom of the line box.
// TODO(layout-dev): Use selection top & bottom instead of line's, or decide
// if we still want to distinguish line and selection heights in NG.
- const ComputedStyle& line_style = line_box.CurrentStyle();
+ const ComputedStyle& line_style = line_box.Current().Style();
const WritingMode writing_mode = line_style.GetWritingMode();
const TextDirection text_direction = line_style.Direction();
- const PhysicalOffset line_box_offset = line_box.CurrentOffset();
- const PhysicalSize line_box_size = line_box.CurrentSize();
+ const PhysicalOffset line_box_offset =
+ line_box.Current().OffsetInContainerBlock();
+ const PhysicalSize line_box_size = line_box.Current().Size();
const LogicalOffset logical_offset = line_box_offset.ConvertToLogical(
writing_mode, text_direction, fragmentainer->Size(),
- line_box.CurrentSize());
+ line_box.Current().Size());
const LogicalSize logical_size =
line_box_size.ConvertToLogical(writing_mode);
return {logical_offset.block_offset,
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_replaced.h b/chromium/third_party/blink/renderer/core/layout/layout_replaced.h
index dfb6906f5d1..d501a40eef6 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_replaced.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_replaced.h
@@ -90,11 +90,6 @@ class CORE_EXPORT LayoutReplaced : public LayoutBox {
void Paint(const PaintInfo&) const override;
- // Replaced objects often have contents to paint.
- bool PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const override {
- return false;
- }
-
// This function is public only so we can call it when computing
// intrinsic size in LayoutNG.
virtual void ComputeIntrinsicSizingInfo(IntrinsicSizingInfo&) const;
@@ -136,8 +131,7 @@ class CORE_EXPORT LayoutReplaced : public LayoutBox {
void ComputePositionedLogicalHeight(
LogicalExtentComputedValues&) const override;
- void ComputeIntrinsicLogicalWidths(LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const final;
+ MinMaxSizes ComputeIntrinsicLogicalWidths() const final;
// This function calculates the placement of the replaced contents. It takes
// intrinsic size of the replaced contents, stretch to fit CSS content box
@@ -164,7 +158,7 @@ class CORE_EXPORT LayoutReplaced : public LayoutBox {
}
private:
- void ComputePreferredLogicalWidths() final;
+ MinMaxSizes PreferredLogicalWidths() const final;
void ComputeIntrinsicSizingInfoForReplacedContent(IntrinsicSizingInfo&) const;
FloatSize ConstrainIntrinsicSizeToMinMax(const IntrinsicSizingInfo&) const;
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_replaced_test.cc b/chromium/third_party/blink/renderer/core/layout/layout_replaced_test.cc
index 5b157b6a6c8..138bee7164b 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_replaced_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_replaced_test.cc
@@ -26,7 +26,8 @@ TEST_F(LayoutReplacedTest, InvalidateAfterAddingBorderRadius) {
target_element->setAttribute(html_names::kStyleAttr, "border-radius: 10px");
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(layout_object->NeedsPaintPropertyUpdate());
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_ruby_base.cc b/chromium/third_party/blink/renderer/core/layout/layout_ruby_base.cc
index 9b21b0bf71f..1bb9a9e2685 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_ruby_base.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_ruby_base.cc
@@ -65,9 +65,9 @@ void LayoutRubyBase::MoveChildren(LayoutRubyBase* to_base,
else
MoveBlockChildren(to_base, before_child);
- SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kUnknown);
- to_base->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ to_base->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kUnknown);
}
@@ -152,7 +152,7 @@ void LayoutRubyBase::AdjustInlineDirectionLineBounds(
unsigned expansion_opportunity_count,
LayoutUnit& logical_left,
LayoutUnit& logical_width) const {
- int max_preferred_logical_width = MaxPreferredLogicalWidth().ToInt();
+ int max_preferred_logical_width = PreferredLogicalWidths().max_size.ToInt();
if (max_preferred_logical_width >= logical_width)
return;
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 5990208b8f8..730b2a35e1c 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
@@ -64,7 +64,7 @@ void LayoutRubyText::AdjustInlineDirectionLineBounds(
return LayoutBlockFlow::AdjustInlineDirectionLineBounds(
expansion_opportunity_count, logical_left, logical_width);
- int max_preferred_logical_width = MaxPreferredLogicalWidth().ToInt();
+ int max_preferred_logical_width = PreferredLogicalWidths().max_size.ToInt();
if (max_preferred_logical_width >= logical_width)
return;
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_search_field.cc b/chromium/third_party/blink/renderer/core/layout/layout_search_field.cc
deleted file mode 100644
index 54159e3348f..00000000000
--- a/chromium/third_party/blink/renderer/core/layout/layout_search_field.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * Copyright (C) 2006, 2007, 2010 Apple Inc. All rights reserved.
- * (C) 2008 Torch Mobile Inc. All rights reserved.
- * (http://www.torchmobile.com/)
- * Copyright (C) 2010 Google Inc. All rights reserved.
- * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "third_party/blink/renderer/core/layout/layout_search_field.h"
-
-#include "third_party/blink/renderer/core/dom/shadow_root.h"
-#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
-#include "third_party/blink/renderer/core/html/shadow/shadow_element_names.h"
-#include "third_party/blink/renderer/core/input_type_names.h"
-
-namespace blink {
-
-LayoutSearchField::LayoutSearchField(HTMLInputElement* element)
- : LayoutTextControlSingleLine(element) {
- DCHECK_EQ(element->type(), input_type_names::kSearch);
-}
-
-LayoutSearchField::~LayoutSearchField() = default;
-
-inline Element* LayoutSearchField::SearchDecorationElement() const {
- return InputElement()->UserAgentShadowRoot()->getElementById(
- shadow_element_names::SearchDecoration());
-}
-
-inline Element* LayoutSearchField::CancelButtonElement() const {
- return InputElement()->UserAgentShadowRoot()->getElementById(
- shadow_element_names::ClearButton());
-}
-
-LayoutUnit LayoutSearchField::ComputeControlLogicalHeight(
- LayoutUnit line_height,
- LayoutUnit non_content_height) const {
- Element* search_decoration = SearchDecorationElement();
- if (LayoutBox* decoration_layout_object =
- search_decoration ? search_decoration->GetLayoutBox() : nullptr) {
- decoration_layout_object->UpdateLogicalHeight();
- non_content_height =
- max(non_content_height,
- decoration_layout_object->BorderAndPaddingLogicalHeight() +
- decoration_layout_object->MarginLogicalHeight());
- line_height = max(line_height, decoration_layout_object->LogicalHeight());
- }
- Element* cancel_button = CancelButtonElement();
- if (LayoutBox* cancel_layout_object =
- cancel_button ? cancel_button->GetLayoutBox() : nullptr) {
- cancel_layout_object->UpdateLogicalHeight();
- non_content_height =
- max(non_content_height,
- cancel_layout_object->BorderAndPaddingLogicalHeight() +
- cancel_layout_object->MarginLogicalHeight());
- line_height = max(line_height, cancel_layout_object->LogicalHeight());
- }
-
- return line_height + non_content_height;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_search_field.h b/chromium/third_party/blink/renderer/core/layout/layout_search_field.h
deleted file mode 100644
index f9146cab43b..00000000000
--- a/chromium/third_party/blink/renderer/core/layout/layout_search_field.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Torch Mobile Inc. All rights reserved.
- * (http://www.torchmobile.com/)
- * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_SEARCH_FIELD_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_SEARCH_FIELD_H_
-
-#include "third_party/blink/renderer/core/layout/layout_text_control_single_line.h"
-
-namespace blink {
-
-class HTMLInputElement;
-
-class LayoutSearchField final : public LayoutTextControlSingleLine {
- public:
- LayoutSearchField(HTMLInputElement*);
- ~LayoutSearchField() override;
-
- private:
- LayoutUnit ComputeControlLogicalHeight(
- LayoutUnit line_height,
- LayoutUnit non_content_height) const override;
-
- Element* SearchDecorationElement() const;
- Element* CancelButtonElement() const;
-};
-
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutSearchField, IsTextField());
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_SEARCH_FIELD_H_
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 3ff579f8fe0..20ab99f71b4 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
@@ -6,7 +6,9 @@
#include "cc/layers/heads_up_display_layer.h"
#include "cc/layers/picture_layer.h"
-#include "third_party/blink/public/platform/web_pointer_event.h"
+#include "cc/trees/layer_tree_host.h"
+#include "third_party/blink/public/common/input/web_pointer_event.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"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
@@ -26,12 +28,20 @@
namespace blink {
-static constexpr base::TimeDelta kTimerDelay =
- base::TimeDelta::FromMilliseconds(500);
-static const float kMovementThreshold = 3.0; // CSS pixels.
+using ReattachHook = LayoutShiftTracker::ReattachHook;
-static FloatPoint LogicalStart(const FloatRect& rect,
- const LayoutObject& object) {
+namespace {
+
+ReattachHook& GetReattachHook() {
+ DEFINE_STATIC_LOCAL(Persistent<ReattachHook>, hook,
+ (MakeGarbageCollected<ReattachHook>()));
+ return *hook;
+}
+
+constexpr base::TimeDelta kTimerDelay = base::TimeDelta::FromMilliseconds(500);
+const float kMovementThreshold = 3.0; // CSS pixels.
+
+FloatPoint LogicalStart(const FloatRect& rect, const LayoutObject& object) {
const ComputedStyle* style = object.Style();
DCHECK(style);
auto logical =
@@ -40,59 +50,67 @@ static FloatPoint LogicalStart(const FloatRect& rect,
return FloatPoint(logical.InlineStart(), logical.BlockStart());
}
-static float GetMoveDistance(const FloatRect& old_rect,
- const FloatRect& new_rect,
- const LayoutObject& object) {
+float GetMoveDistance(const FloatRect& old_rect,
+ const FloatRect& new_rect,
+ const LayoutObject& object) {
FloatSize location_delta =
LogicalStart(new_rect, object) - LogicalStart(old_rect, object);
return std::max(fabs(location_delta.Width()), fabs(location_delta.Height()));
}
-static bool EqualWithinMovementThreshold(const FloatPoint& a,
- const FloatPoint& b,
- const LayoutObject& object) {
+bool EqualWithinMovementThreshold(const FloatPoint& a,
+ const FloatPoint& b,
+ const LayoutObject& object) {
float threshold_physical_px =
kMovementThreshold * object.StyleRef().EffectiveZoom();
return fabs(a.X() - b.X()) < threshold_physical_px &&
fabs(a.Y() - b.Y()) < threshold_physical_px;
}
-static bool SmallerThanRegionGranularity(const FloatRect& rect) {
+bool SmallerThanRegionGranularity(const FloatRect& rect) {
// The region uses integer coordinates, so the rects are snapped to
// pixel boundaries. Ignore rects smaller than half a pixel.
return rect.Width() < 0.5 || rect.Height() < 0.5;
}
-static const PropertyTreeState PropertyTreeStateFor(
- const LayoutObject& object) {
+const PropertyTreeState PropertyTreeStateFor(const LayoutObject& object) {
return object.FirstFragment().LocalBorderBoxProperties();
}
-static void RegionToTracedValue(const LayoutShiftRegion& region,
- TracedValue& value) {
+void RectToTracedValue(const IntRect& rect,
+ TracedValue& value,
+ const char* key = nullptr) {
+ if (key)
+ value.BeginArray(key);
+ else
+ value.BeginArray();
+ value.PushInteger(rect.X());
+ value.PushInteger(rect.Y());
+ value.PushInteger(rect.Width());
+ value.PushInteger(rect.Height());
+ value.EndArray();
+}
+
+void RegionToTracedValue(const LayoutShiftRegion& region, TracedValue& value) {
Region blink_region;
for (IntRect rect : region.GetRects())
blink_region.Unite(Region(rect));
value.BeginArray("region_rects");
- for (const IntRect& rect : blink_region.Rects()) {
- value.BeginArray();
- value.PushInteger(rect.X());
- value.PushInteger(rect.Y());
- value.PushInteger(rect.Width());
- value.PushInteger(rect.Height());
- value.EndArray();
- }
+ for (const IntRect& rect : blink_region.Rects())
+ RectToTracedValue(rect, value);
value.EndArray();
}
#if DCHECK_IS_ON()
-static bool ShouldLog(const LocalFrame& frame) {
+bool ShouldLog(const LocalFrame& frame) {
const String& url = frame.GetDocument()->Url().GetString();
- return !url.StartsWith("chrome-devtools:") && !url.StartsWith("devtools:");
+ return !url.StartsWith("devtools:");
}
#endif
+} // namespace
+
LayoutShiftTracker::LayoutShiftTracker(LocalFrameView* frame_view)
: frame_view_(frame_view),
score_(0.0),
@@ -200,6 +218,60 @@ void LayoutShiftTracker::ObjectShifted(
region_.AddRect(visible_old_rect);
region_.AddRect(visible_new_rect);
+
+ if (Node* node = source.GetNode()) {
+ MaybeRecordAttribution(
+ {DOMNodeIds::IdForNode(node), visible_old_rect, visible_new_rect});
+ }
+}
+
+LayoutShiftTracker::Attribution::Attribution() : node_id(kInvalidDOMNodeId) {}
+LayoutShiftTracker::Attribution::Attribution(DOMNodeId node_id_arg,
+ IntRect old_visual_rect_arg,
+ IntRect new_visual_rect_arg)
+ : node_id(node_id_arg),
+ old_visual_rect(old_visual_rect_arg),
+ new_visual_rect(new_visual_rect_arg) {}
+
+LayoutShiftTracker::Attribution::operator bool() const {
+ return node_id != kInvalidDOMNodeId;
+}
+
+bool LayoutShiftTracker::Attribution::Encloses(const Attribution& other) const {
+ return old_visual_rect.Contains(other.old_visual_rect) &&
+ new_visual_rect.Contains(other.new_visual_rect);
+}
+
+int LayoutShiftTracker::Attribution::Area() const {
+ int old_area = old_visual_rect.Width() * old_visual_rect.Height();
+ int new_area = new_visual_rect.Width() * new_visual_rect.Height();
+
+ IntRect intersection = Intersection(old_visual_rect, new_visual_rect);
+ int shared_area = intersection.Width() * intersection.Height();
+ return old_area + new_area - shared_area;
+}
+
+bool LayoutShiftTracker::Attribution::MoreImpactfulThan(
+ const Attribution& other) const {
+ return Area() > other.Area();
+}
+
+void LayoutShiftTracker::MaybeRecordAttribution(
+ const Attribution& attribution) {
+ Attribution* smallest = nullptr;
+ for (auto& slot : attributions_) {
+ if (!slot || attribution.Encloses(slot)) {
+ slot = attribution;
+ return;
+ }
+ if (slot.Encloses(attribution))
+ return;
+ if (!smallest || smallest->MoreImpactfulThan(slot))
+ smallest = &slot;
+ }
+ // No empty slots or redundancies. Replace smallest existing slot if larger.
+ if (attribution.MoreImpactfulThan(*smallest))
+ *smallest = attribution;
}
void LayoutShiftTracker::NotifyObjectPrePaint(
@@ -288,6 +360,7 @@ void LayoutShiftTracker::NotifyPrePaintFinished() {
frame_max_distance_ = 0.0;
frame_scroll_delta_ = ScrollOffset();
+ attributions_.fill(Attribution());
}
void LayoutShiftTracker::ReportShift(double score_delta,
@@ -378,13 +451,14 @@ void LayoutShiftTracker::UpdateInputTimestamp(base::TimeTicks timestamp) {
}
}
-void LayoutShiftTracker::NotifyScroll(ScrollType scroll_type,
+void LayoutShiftTracker::NotifyScroll(mojom::blink::ScrollType scroll_type,
ScrollOffset delta) {
frame_scroll_delta_ += delta;
// Only set observed_input_or_scroll_ for user-initiated scrolls, and not
// other scrolls such as hash fragment navigations.
- if (scroll_type == kUserScroll || scroll_type == kCompositorScroll)
+ if (scroll_type == mojom::blink::ScrollType::kUser ||
+ scroll_type == mojom::blink::ScrollType::kCompositor)
observed_input_or_scroll_ = true;
}
@@ -413,20 +487,39 @@ std::unique_ptr<TracedValue> LayoutShiftTracker::PerFrameTraceData(
RegionToTracedValue(region_, *value);
value->SetBoolean("is_main_frame", frame_view_->GetFrame().IsMainFrame());
value->SetBoolean("had_recent_input", input_detected);
+ AttributionsToTracedValue(*value);
return value;
}
-void LayoutShiftTracker::SetLayoutShiftRects(const Vector<IntRect>& int_rects) {
- // Store the layout shift rects in the HUD layer.
- GraphicsLayer* root_graphics_layer =
- frame_view_->GetLayoutView()->Compositor()->RootGraphicsLayer();
- if (!root_graphics_layer)
+void LayoutShiftTracker::AttributionsToTracedValue(TracedValue& value) const {
+ const Attribution* it = attributions_.begin();
+ if (!*it)
return;
- cc::Layer* cc_layer = root_graphics_layer->CcLayer();
- if (!cc_layer)
- return;
- if (cc_layer->layer_tree_host()) {
+ bool should_include_names;
+ TRACE_EVENT_CATEGORY_GROUP_ENABLED(
+ TRACE_DISABLED_BY_DEFAULT("layout_shift.debug"), &should_include_names);
+
+ value.BeginArray("impacted_nodes");
+ while (it != attributions_.end() && it->node_id != kInvalidDOMNodeId) {
+ value.BeginDictionary();
+ value.SetInteger("node_id", it->node_id);
+ RectToTracedValue(it->old_visual_rect, value, "old_rect");
+ RectToTracedValue(it->new_visual_rect, value, "new_rect");
+ if (should_include_names) {
+ Node* node = DOMNodeIds::NodeForId(it->node_id);
+ value.SetString("debug_name", node ? node->DebugName() : "");
+ }
+ value.EndDictionary();
+ it++;
+ }
+ value.EndArray();
+}
+
+void LayoutShiftTracker::SetLayoutShiftRects(const Vector<IntRect>& int_rects) {
+ // Store the layout shift rects in the HUD layer.
+ auto* cc_layer = frame_view_->RootCcLayer();
+ if (cc_layer && cc_layer->layer_tree_host()) {
if (!cc_layer->layer_tree_host()->GetDebugState().show_layout_shift_regions)
return;
if (cc_layer->layer_tree_host()->hud_layer()) {
@@ -443,4 +536,61 @@ void LayoutShiftTracker::SetLayoutShiftRects(const Vector<IntRect>& int_rects) {
}
}
+ReattachHook::Scope::Scope(const Node& node) : active_(node.GetLayoutObject()) {
+ if (active_) {
+ auto& hook = GetReattachHook();
+ outer_ = hook.scope_;
+ hook.scope_ = this;
+ }
+}
+
+ReattachHook::Scope::~Scope() {
+ if (active_) {
+ auto& hook = GetReattachHook();
+ hook.scope_ = outer_;
+ if (!outer_)
+ hook.visual_rects_.clear();
+ }
+}
+
+void ReattachHook::NotifyDetach(const Node& node) {
+ auto& hook = GetReattachHook();
+ if (!hook.scope_)
+ return;
+ auto* layout_object = node.GetLayoutObject();
+ if (!layout_object)
+ return;
+ auto& map = hook.visual_rects_;
+ auto& fragment = layout_object->GetMutableForPainting().FirstFragment();
+
+ // Save the visual rect for restoration on future reattachment.
+ IntRect visual_rect = fragment.VisualRect();
+ if (visual_rect.IsEmpty())
+ return;
+ map.Set(&node, visual_rect);
+}
+
+void ReattachHook::NotifyAttach(const Node& node) {
+ auto& hook = GetReattachHook();
+ if (!hook.scope_)
+ return;
+ auto* layout_object = node.GetLayoutObject();
+ if (!layout_object)
+ return;
+ auto& map = hook.visual_rects_;
+ auto& fragment = layout_object->GetMutableForPainting().FirstFragment();
+
+ // Restore the visual rect that was saved during detach. Note: this does not
+ // affect paint invalidation; we will fully invalidate the new layout object.
+ auto iter = map.find(&node);
+ if (iter == map.end())
+ return;
+ IntRect visual_rect = iter->value;
+ fragment.SetVisualRect(visual_rect);
+}
+
+void ReattachHook::Trace(Visitor* visitor) {
+ visitor->Trace(visual_rects_);
+}
+
} // namespace blink
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 79185e29907..24bbd221df5 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
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/core/layout/layout_shift_region.h"
#include "third_party/blink/renderer/core/scroll/scroll_types.h"
#include "third_party/blink/renderer/platform/geometry/region.h"
+#include "third_party/blink/renderer/platform/graphics/dom_node_id.h"
#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -48,7 +49,7 @@ class CORE_EXPORT LayoutShiftTracker {
FloatSize paint_offset_delta);
void NotifyPrePaintFinished();
void NotifyInput(const WebInputEvent&);
- void NotifyScroll(ScrollType, ScrollOffset delta);
+ void NotifyScroll(mojom::blink::ScrollType, ScrollOffset delta);
void NotifyViewportSizeChanged();
bool IsActive();
double Score() const { return score_; }
@@ -60,6 +61,31 @@ class CORE_EXPORT LayoutShiftTracker {
return most_recent_input_timestamp_;
}
+ // 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*);
+
+ class Scope {
+ public:
+ Scope(const Node&);
+ ~Scope();
+
+ private:
+ bool active_;
+ Scope* outer_;
+ };
+
+ static void NotifyDetach(const Node&);
+ static void NotifyAttach(const Node&);
+
+ private:
+ Scope* scope_;
+ HeapHashMap<Member<const Node>, IntRect> visual_rects_;
+ };
+
private:
void ObjectShifted(const LayoutObject&,
const PropertyTreeState&,
@@ -70,6 +96,7 @@ class CORE_EXPORT LayoutShiftTracker {
void TimerFired(TimerBase*) {}
std::unique_ptr<TracedValue> PerFrameTraceData(double score_delta,
bool input_detected) const;
+ void AttributionsToTracedValue(TracedValue&) const;
double SubframeWeightingFactor() const;
void SetLayoutShiftRects(const Vector<IntRect>& int_rects);
void UpdateInputTimestamp(base::TimeTicks timestamp);
@@ -132,6 +159,29 @@ class CORE_EXPORT LayoutShiftTracker {
// User input includes window resizing but not scrolling.
base::TimeTicks most_recent_input_timestamp_;
bool most_recent_input_timestamp_initialized_;
+
+ struct Attribution {
+ DOMNodeId node_id;
+ IntRect old_visual_rect;
+ IntRect new_visual_rect;
+
+ Attribution();
+ Attribution(DOMNodeId node_id,
+ IntRect old_visual_rect,
+ IntRect new_visual_rect);
+
+ explicit operator bool() const;
+ bool Encloses(const Attribution&) const;
+ bool MoreImpactfulThan(const Attribution&) const;
+ int Area() const;
+ };
+ static constexpr int kMaxAttributions = 5;
+
+ void MaybeRecordAttribution(const Attribution&);
+
+ // Nodes that have contributed to the impact region for the current frame, for
+ // use in trace event. Only populated while tracing.
+ std::array<Attribution, kMaxAttributions> attributions_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_shift_tracker_test.cc b/chromium/third_party/blink/renderer/core/layout/layout_shift_tracker_test.cc
index 7d60704a20d..4418bcf5202 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_shift_tracker_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_shift_tracker_test.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/core/layout/layout_shift_tracker.h"
-#include "third_party/blink/public/platform/web_mouse_event.h"
+#include "third_party/blink/public/common/input/web_mouse_event.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/svg_names.h"
#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
@@ -30,14 +30,13 @@ class LayoutShiftTrackerTest : public RenderingTest {
void SimulateInput() {
GetLayoutShiftTracker().NotifyInput(WebMouseEvent(
- WebInputEvent::kMouseDown, WebFloatPoint(), WebFloatPoint(),
+ WebInputEvent::kMouseDown, gfx::PointF(), gfx::PointF(),
WebPointerProperties::Button::kLeft, 0,
WebInputEvent::Modifiers::kLeftButtonDown, base::TimeTicks::Now()));
}
void UpdateAllLifecyclePhases() {
- GetFrameView().UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetFrameView().UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
}
};
@@ -81,7 +80,8 @@ TEST_F(LayoutShiftTrackerTest, CompositedShiftBeforeFirstPaint) {
GetDocument().getElementById("B")->setAttribute(html_names::kClassAttr,
AtomicString("tr"));
- GetFrameView().UpdateLifecycleToCompositingCleanPlusScrolling();
+ GetFrameView().UpdateLifecycleToCompositingCleanPlusScrolling(
+ DocumentUpdateReason::kTest);
GetDocument().getElementById("A")->setAttribute(html_names::kClassAttr,
AtomicString("hide"));
UpdateAllLifecyclePhases();
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_slider.cc b/chromium/third_party/blink/renderer/core/layout/layout_slider.cc
index f41bbd8335c..21dcbb6421d 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_slider.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_slider.cc
@@ -19,10 +19,7 @@
#include "third_party/blink/renderer/core/layout/layout_slider.h"
-#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
-#include "third_party/blink/renderer/core/html/forms/slider_thumb_element.h"
-#include "third_party/blink/renderer/core/html/shadow/shadow_element_names.h"
#include "third_party/blink/renderer/core/input_type_names.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
@@ -48,23 +45,14 @@ LayoutUnit LayoutSlider::BaselinePosition(
return Size().Height() + MarginTop();
}
-void LayoutSlider::ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const {
- max_logical_width =
+MinMaxSizes LayoutSlider::ComputeIntrinsicLogicalWidths() const {
+ MinMaxSizes sizes;
+ sizes += BorderAndPaddingLogicalWidth() + ScrollbarLogicalWidth();
+ sizes.max_size +=
LayoutUnit(kDefaultTrackLength * StyleRef().EffectiveZoom());
if (!StyleRef().Width().IsPercentOrCalc())
- min_logical_width = max_logical_width;
-}
-
-inline SliderThumbElement* LayoutSlider::GetSliderThumbElement() const {
- return To<SliderThumbElement>(
- To<Element>(GetNode())->UserAgentShadowRoot()->getElementById(
- shadow_element_names::SliderThumb()));
-}
-
-bool LayoutSlider::InDragMode() const {
- return GetSliderThumbElement()->IsActive();
+ sizes.min_size = sizes.max_size;
+ return sizes;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_slider.h b/chromium/third_party/blink/renderer/core/layout/layout_slider.h
index 09d62822dc7..401f30d251b 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_slider.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_slider.h
@@ -23,11 +23,11 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/layout_flexible_box.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
class HTMLInputElement;
-class SliderThumbElement;
class CORE_EXPORT LayoutSlider final : public LayoutFlexibleBox {
public:
@@ -36,8 +36,6 @@ class CORE_EXPORT LayoutSlider final : public LayoutFlexibleBox {
explicit LayoutSlider(HTMLInputElement*);
~LayoutSlider() override;
- bool InDragMode() const;
-
const char* GetName() const override { return "LayoutSlider"; }
private:
@@ -50,14 +48,15 @@ class CORE_EXPORT LayoutSlider final : public LayoutFlexibleBox {
bool first_line,
LineDirectionMode,
LinePositionMode = kPositionOnContainingLine) const override;
- void ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const override;
-
- SliderThumbElement* GetSliderThumbElement() const;
+ MinMaxSizes ComputeIntrinsicLogicalWidths() const override;
};
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutSlider, IsSlider());
+template <>
+struct DowncastTraits<LayoutSlider> {
+ static bool AllowFrom(const LayoutObject& object) {
+ return object.IsSlider();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_slider_container.cc b/chromium/third_party/blink/renderer/core/layout/layout_slider_container.cc
index b88895afa6f..4df8effbab1 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_slider_container.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_slider_container.cc
@@ -51,22 +51,13 @@ inline static Decimal SliderPosition(HTMLInputElement* element) {
return step_range.ProportionFromValue(step_range.ClampValue(old_value));
}
-inline static bool HasVerticalAppearance(HTMLInputElement* input) {
- DCHECK(input->GetLayoutObject());
- if (!input->GetLayoutObject() || !input->GetLayoutObject()->Style())
- return false;
- const ComputedStyle& slider_style = input->GetLayoutObject()->StyleRef();
- return slider_style.EffectiveAppearance() == kSliderVerticalPart;
-}
-
void LayoutSliderContainer::ComputeLogicalHeight(
LayoutUnit logical_height,
LayoutUnit logical_top,
LogicalExtentComputedValues& computed_values) const {
auto* input = To<HTMLInputElement>(GetNode()->OwnerShadowHost());
- bool is_vertical = HasVerticalAppearance(input);
- if (input->GetLayoutObject()->IsSlider() && !is_vertical && input->list()) {
+ if (input->GetLayoutObject()->IsSlider() && input->list()) {
int offset_from_center =
LayoutTheme::GetTheme().SliderTickOffsetFromTrackCenter();
LayoutUnit track_height;
@@ -87,8 +78,6 @@ void LayoutSliderContainer::ComputeLogicalHeight(
LayoutBox::ComputeLogicalHeight(track_height, logical_top, computed_values);
return;
}
- if (is_vertical)
- logical_height = LayoutUnit(LayoutSlider::kDefaultTrackLength);
// FIXME: The trackHeight should have been added before updateLogicalHeight
// was called to avoid this hack.
@@ -97,9 +86,17 @@ void LayoutSliderContainer::ComputeLogicalHeight(
LayoutBox::ComputeLogicalHeight(logical_height, logical_top, computed_values);
}
+MinMaxSizes LayoutSliderContainer::ComputeIntrinsicLogicalWidths() const {
+ MinMaxSizes sizes;
+ sizes += LayoutUnit(LayoutSlider::kDefaultTrackLength *
+ StyleRef().EffectiveZoom()) +
+ BorderAndPaddingLogicalWidth();
+ return sizes;
+}
+
void LayoutSliderContainer::UpdateLayout() {
auto* input = To<HTMLInputElement>(GetNode()->OwnerShadowHost());
- bool is_vertical = HasVerticalAppearance(input);
+ const bool is_vertical = !StyleRef().IsHorizontalWritingMode();
Element* thumb_element = input->UserAgentShadowRoot()->getElementById(
shadow_element_names::SliderThumb());
@@ -131,8 +128,7 @@ void LayoutSliderContainer::UpdateLayout() {
LayoutUnit offset(percentage_offset * available_extent);
LayoutPoint thumb_location = thumb->Location();
if (is_vertical) {
- thumb_location.SetY(thumb_location.Y() + track->ContentHeight() -
- thumb->Size().Height() - offset);
+ thumb_location.SetY(thumb_location.Y() - offset);
} else if (StyleRef().IsLeftToRightDirection()) {
thumb_location.SetX(thumb_location.X() + offset);
} else {
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_slider_container.h b/chromium/third_party/blink/renderer/core/layout/layout_slider_container.h
index bab81f70c04..9acb550efe3 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_slider_container.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_slider_container.h
@@ -46,6 +46,7 @@ class LayoutSliderContainer final : public LayoutFlexibleBox {
void ComputeLogicalHeight(LayoutUnit logical_height,
LayoutUnit logical_top,
LogicalExtentComputedValues&) const override;
+ MinMaxSizes ComputeIntrinsicLogicalWidths() const override;
private:
void UpdateLayout() override;
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 fbc642e0cb4..c7258a54f38 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_state.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_state.cc
@@ -57,6 +57,11 @@ 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;
+ else
+ page_name_ = next_->page_name_;
+
if (layout_object.IsLayoutFlowThread()) {
// Entering a new pagination context.
pagination_offset_ = LayoutSize();
@@ -105,7 +110,7 @@ LayoutState::LayoutState(LayoutObject& root)
next_(root.View()->GetLayoutState()),
layout_object_(root) {
DCHECK(!next_);
- DCHECK(!root.IsLayoutView());
+ DCHECK(!IsA<LayoutView>(root));
root.View()->PushLayoutState(*this);
}
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 eb1b3ce09db..190e5ba2450 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_state.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_state.h
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/platform/geometry/layout_rect.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/text/atomic_string.h"
namespace blink {
@@ -90,6 +91,8 @@ class LayoutState {
height_offset_for_table_footers_ = offset;
}
+ const AtomicString& PageName() const { return page_name_; }
+
const LayoutSize& PaginationOffset() const { return pagination_offset_; }
bool ContainingBlockLogicalWidthChanged() const {
return containing_block_logical_width_changed_;
@@ -128,6 +131,8 @@ class LayoutState {
// paginated layout.
LayoutUnit height_offset_for_table_footers_;
+ AtomicString 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 33333b6b88e..2b41ff4843e 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_table.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_table.cc
@@ -310,11 +310,10 @@ bool LayoutTable::IsLogicalWidthAuto() const {
void LayoutTable::UpdateLogicalWidth() {
RecalcSectionsIfNeeded();
- // Recalculate preferred logical widths now, rather than relying on them being
- // lazily recalculated, via MinPreferredLogicalWidth() further below. We might
- // not even get there.
- if (PreferredLogicalWidthsDirty())
- ComputePreferredLogicalWidths();
+ // Recalculate the intrinsic logical widths now, rather than relying on them
+ // being lazily recalculated, via PreferredLogicalWidths() further below. We
+ // might not even get there.
+ UpdateCachedIntrinsicLogicalWidthsIfNeeded();
if (IsFlexItemIncludingDeprecatedAndNG() || IsGridItem()) {
// TODO(jfernandez): Investigate whether the grid layout algorithm provides
@@ -344,6 +343,8 @@ void LayoutTable::UpdateLogicalWidth() {
? PerpendicularContainingBlockLogicalHeight()
: available_logical_width;
+ MinMaxSizes preferred_logical_widths = PreferredLogicalWidths();
+
if (!IsLogicalWidthAuto()) {
SetLogicalWidth(ConvertStyleLogicalWidthToComputedWidth(
StyleRef().LogicalWidth(), container_width_in_inline_direction));
@@ -375,11 +376,11 @@ void LayoutTable::UpdateLogicalWidth() {
}
// Ensure we aren't bigger than our available width.
- LayoutUnit max_width = MaxPreferredLogicalWidth();
+ LayoutUnit max_width = preferred_logical_widths.max_size;
// scaledWidthFromPercentColumns depends on m_layoutStruct in
- // TableLayoutAlgorithmAuto, which maxPreferredLogicalWidth fills in. So
- // scaledWidthFromPercentColumns has to be called after
- // maxPreferredLogicalWidth.
+ // TableLayoutAlgorithmAuto, which |PreferredLogicalWidths()| fills in. So
+ // |ScaledWidthFromPercentColumns()| has to be called after
+ // |PreferredLogicalWidths()|.
LayoutUnit scaled_width = table_layout_->ScaledWidthFromPercentColumns() +
BordersPaddingAndSpacingInRowDirection();
max_width = std::max(scaled_width, max_width);
@@ -402,8 +403,8 @@ void LayoutTable::UpdateLogicalWidth() {
// Ensure we aren't smaller than our min preferred width. This MUST be done
// after 'max-width' as we ignore it if it means we wouldn't accommodate our
// content.
- SetLogicalWidth(
- LayoutUnit(std::max(LogicalWidth(), MinPreferredLogicalWidth()).Floor()));
+ SetLogicalWidth(LayoutUnit(
+ std::max(LogicalWidth(), preferred_logical_widths.min_size).Floor()));
// Ensure we aren't smaller than our min-width style.
const Length& style_min_logical_width = StyleRef().LogicalMinWidth();
@@ -431,7 +432,7 @@ void LayoutTable::UpdateLogicalWidth() {
// nor what authors expect.
// FIXME: When we convert to sub-pixel layout for tables we can remove the int
// conversion. http://crbug.com/241198
- DCHECK_GE(LogicalWidth().Floor(), MinPreferredLogicalWidth().Floor());
+ DCHECK_GE(LogicalWidth().Floor(), preferred_logical_widths.min_size.Floor());
}
// This method takes a ComputedStyle's logical width, min-width, or max-width
@@ -439,10 +440,10 @@ void LayoutTable::UpdateLogicalWidth() {
LayoutUnit LayoutTable::ConvertStyleLogicalWidthToComputedWidth(
const Length& style_logical_width,
LayoutUnit available_width) const {
- if (style_logical_width.IsIntrinsic())
- return ComputeIntrinsicLogicalWidthUsing(
- style_logical_width, available_width,
- BordersPaddingAndSpacingInRowDirection());
+ if (style_logical_width.IsIntrinsic()) {
+ return ComputeIntrinsicLogicalWidthUsing(style_logical_width,
+ available_width);
+ }
// HTML tables' width styles already include borders and paddings, but CSS
// tables' width styles do not.
@@ -974,6 +975,7 @@ void LayoutTable::ComputeVisualOverflow(bool) {
AddVisualOverflowFromTheme();
if (VisualOverflowRect() != previous_visual_overflow_rect) {
+ InvalidateIntersectionObserverCachedRects();
SetShouldCheckForPaintInvalidation();
GetFrameView()->SetIntersectionObservationState(LocalFrameView::kDesired);
}
@@ -1088,38 +1090,30 @@ void LayoutTable::PaintMask(const PaintInfo& paint_info,
TablePainter(*this).PaintMask(paint_info, paint_offset);
}
-void LayoutTable::ComputeIntrinsicLogicalWidths(LayoutUnit& min_width,
- LayoutUnit& max_width) const {
+MinMaxSizes LayoutTable::ComputeIntrinsicLogicalWidths() const {
RecalcSectionsIfNeeded();
// FIXME: Restructure the table layout code so that we can make this method
// const.
+ MinMaxSizes sizes;
const_cast<LayoutTable*>(this)->table_layout_->ComputeIntrinsicLogicalWidths(
- min_width, max_width);
+ sizes.min_size, sizes.max_size);
// FIXME: We should include captions widths here like we do in
// computePreferredLogicalWidths.
+ sizes += LayoutUnit(BordersPaddingAndSpacingInRowDirection().ToInt());
+ return sizes;
}
-void LayoutTable::ComputePreferredLogicalWidths() {
- DCHECK(PreferredLogicalWidthsDirty());
-
- ComputeIntrinsicLogicalWidths(min_preferred_logical_width_,
- max_preferred_logical_width_);
-
- int borders_padding_and_spacing =
- BordersPaddingAndSpacingInRowDirection().ToInt();
- min_preferred_logical_width_ += borders_padding_and_spacing;
- max_preferred_logical_width_ += borders_padding_and_spacing;
+MinMaxSizes LayoutTable::PreferredLogicalWidths() const {
+ MinMaxSizes sizes = IntrinsicLogicalWidths();
- table_layout_->ApplyPreferredLogicalWidthQuirks(min_preferred_logical_width_,
- max_preferred_logical_width_);
+ table_layout_->ApplyPreferredLogicalWidthQuirks(sizes.min_size,
+ sizes.max_size);
- for (unsigned i = 0; i < captions_.size(); i++) {
- min_preferred_logical_width_ = std::max(
- min_preferred_logical_width_, captions_[i]->MinPreferredLogicalWidth());
- // Note: using captions' min-width is intentional here:
- max_preferred_logical_width_ = std::max(
- max_preferred_logical_width_, captions_[i]->MinPreferredLogicalWidth());
+ for (const auto* caption : captions_) {
+ LayoutUnit min_preferred_logical_width =
+ caption->PreferredLogicalWidths().min_size;
+ sizes.Encompass(min_preferred_logical_width);
}
const ComputedStyle& style_to_use = StyleRef();
@@ -1127,14 +1121,8 @@ void LayoutTable::ComputePreferredLogicalWidths() {
// able to use percentage or calc values for min-width.
if (style_to_use.LogicalMinWidth().IsFixed() &&
style_to_use.LogicalMinWidth().Value() > 0) {
- max_preferred_logical_width_ =
- std::max(max_preferred_logical_width_,
- AdjustContentBoxLogicalWidthForBoxSizing(
- style_to_use.LogicalMinWidth().Value()));
- min_preferred_logical_width_ =
- std::max(min_preferred_logical_width_,
- AdjustContentBoxLogicalWidthForBoxSizing(
- style_to_use.LogicalMinWidth().Value()));
+ sizes.Encompass(AdjustBorderBoxLogicalWidthForBoxSizing(
+ style_to_use.LogicalMinWidth().Value()));
}
// FIXME: This should probably be checking for isSpecified since you should be
@@ -1142,10 +1130,9 @@ void LayoutTable::ComputePreferredLogicalWidths() {
if (style_to_use.LogicalMaxWidth().IsFixed()) {
// We don't constrain m_minPreferredLogicalWidth as the table should be at
// least the size of its min-content, regardless of 'max-width'.
- max_preferred_logical_width_ =
- std::min(max_preferred_logical_width_,
- AdjustContentBoxLogicalWidthForBoxSizing(
- style_to_use.LogicalMaxWidth().Value()));
+ sizes.max_size =
+ std::min(sizes.max_size, AdjustBorderBoxLogicalWidthForBoxSizing(
+ style_to_use.LogicalMaxWidth().Value()));
}
// 2 cases need this:
@@ -1154,13 +1141,8 @@ void LayoutTable::ComputePreferredLogicalWidths() {
// 2. We buggily calculate min > max for some tables with colspans and
// percent widths. See fast/table/spans-min-greater-than-max-crash.html and
// http://crbug.com/857185
- max_preferred_logical_width_ =
- std::max(min_preferred_logical_width_, max_preferred_logical_width_);
-
- // FIXME: We should be adding borderAndPaddingLogicalWidth here, but
- // m_tableLayout->computePreferredLogicalWidths already does, so a bunch of
- // tests break doing this naively.
- ClearPreferredLogicalWidthsDirty();
+ sizes.max_size = std::max(sizes.min_size, sizes.max_size);
+ return sizes;
}
LayoutTableSection* LayoutTable::TopNonEmptySection() const {
@@ -1865,11 +1847,6 @@ void LayoutTable::UpdateCollapsedOuterBorders() const {
max_border_end - collapsed_outer_border_end_;
}
-bool LayoutTable::PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const {
- return LayoutBlock::PaintedOutputOfObjectHasNoEffectRegardlessOfSize() &&
- !should_paint_all_collapsed_borders_;
-}
-
// LayoutNGTableCellInterface API
bool LayoutTable::IsFirstCell(const LayoutNGTableCellInterface& cell) const {
const LayoutTableCell& layout_cell = *cell.ToLayoutTableCell();
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 1c385155762..53978ca750e 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_table.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_table.h
@@ -427,7 +427,6 @@ class CORE_EXPORT LayoutTable final : public LayoutBlock,
void EnsureIsReadyForPaintInvalidation() override;
void InvalidatePaint(const PaintInvalidatorContext&) const override;
- bool PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const override;
void ColumnStructureChanged();
// LayoutNGTableInterface methods start.
@@ -460,9 +459,8 @@ class CORE_EXPORT LayoutTable final : public LayoutBlock,
void PaintObject(const PaintInfo&,
const PhysicalOffset& paint_offset) const override;
void UpdateLayout() override;
- void ComputeIntrinsicLogicalWidths(LayoutUnit& min_width,
- LayoutUnit& max_width) const override;
- void ComputePreferredLogicalWidths() override;
+ MinMaxSizes ComputeIntrinsicLogicalWidths() const override;
+ MinMaxSizes PreferredLogicalWidths() const override;
bool NodeAtPoint(HitTestResult&,
const HitTestLocation&,
const PhysicalOffset& accumulated_offset,
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_table_caption.h b/chromium/third_party/blink/renderer/core/layout/layout_table_caption.h
index 240de49be66..5ade10c9191 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_table_caption.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_table_caption.h
@@ -62,8 +62,6 @@ class LayoutTableCaption : public LayoutBlockFlow {
LayoutTable* Table() const;
};
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutTableCaption, IsTableCaption());
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_TABLE_CAPTION_H_
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 02b873d3be5..7d041319196 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
@@ -87,12 +87,12 @@ void LayoutTableCell::WillBeRemovedFromTree() {
// remove-cell-with-border-box.html only passes with setNeedsLayout but
// other places use setChildNeedsLayout.
PreviousCell()->SetNeedsLayout(layout_invalidation_reason::kTableChanged);
- PreviousCell()->SetPreferredLogicalWidthsDirty();
+ PreviousCell()->SetIntrinsicLogicalWidthsDirty();
}
if (NextCell()) {
// TODO(dgrogan): Same as above re: setChildNeedsLayout vs setNeedsLayout.
NextCell()->SetNeedsLayout(layout_invalidation_reason::kTableChanged);
- NextCell()->SetPreferredLogicalWidthsDirty();
+ NextCell()->SetIntrinsicLogicalWidthsDirty();
}
}
@@ -100,17 +100,15 @@ unsigned LayoutTableCell::ParseColSpanFromDOM() const {
DCHECK(GetNode());
// TODO(dgrogan): HTMLTableCellElement::colSpan() already clamps to something
// smaller than maxColumnIndex; can we just DCHECK here?
- if (IsHTMLTableCellElement(*GetNode()))
- return std::min<unsigned>(ToHTMLTableCellElement(*GetNode()).colSpan(),
- kMaxColumnIndex);
+ if (auto* cell_element = DynamicTo<HTMLTableCellElement>(GetNode()))
+ return std::min<unsigned>(cell_element->colSpan(), kMaxColumnIndex);
return 1;
}
unsigned LayoutTableCell::ParseRowSpanFromDOM() const {
DCHECK(GetNode());
- if (IsHTMLTableCellElement(*GetNode()))
- return std::min<unsigned>(ToHTMLTableCellElement(*GetNode()).rowSpan(),
- kMaxRowIndex);
+ if (auto* cell_element = DynamicTo<HTMLTableCellElement>(GetNode()))
+ return std::min<unsigned>(cell_element->rowSpan(), kMaxRowIndex);
return 1;
}
@@ -123,11 +121,11 @@ void LayoutTableCell::UpdateColAndRowSpanFlags() {
void LayoutTableCell::ColSpanOrRowSpanChanged() {
DCHECK(GetNode());
- DCHECK(IsHTMLTableCellElement(*GetNode()));
+ DCHECK(IsA<HTMLTableCellElement>(*GetNode()));
UpdateColAndRowSpanFlags();
- SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kAttributeChanged);
if (Parent() && Section()) {
Section()->SetNeedsCellRecalc();
@@ -177,7 +175,7 @@ Length LayoutTableCell::LogicalWidthFromColumns(
return Length::Fixed(col_width_sum);
}
-void LayoutTableCell::ComputePreferredLogicalWidths() {
+MinMaxSizes LayoutTableCell::PreferredLogicalWidths() const {
// The child cells rely on the grids up in the sections to do their
// computePreferredLogicalWidths work. Normally the sections are set up
// early, as table cells are added, but relayout can cause the cells to be
@@ -189,13 +187,14 @@ void LayoutTableCell::ComputePreferredLogicalWidths() {
// notional height on the cell, such as can happen when a percent sized image
// scales up its width to match the available height. Setting a zero override
// height prevents this from happening.
+ auto* mutable_this = const_cast<LayoutTableCell*>(this);
LayoutUnit logical_height =
HasOverrideLogicalHeight() ? OverrideLogicalHeight() : LayoutUnit(-1);
if (logical_height > -1)
- SetOverrideLogicalHeight(LayoutUnit());
- LayoutBlockFlow::ComputePreferredLogicalWidths();
+ mutable_this->SetOverrideLogicalHeight(LayoutUnit());
+ MinMaxSizes sizes = LayoutBlockFlow::PreferredLogicalWidths();
if (logical_height > -1)
- SetOverrideLogicalHeight(logical_height);
+ mutable_this->SetOverrideLogicalHeight(logical_height);
if (GetNode() && StyleRef().AutoWrap()) {
// See if nowrap was set.
@@ -207,10 +206,11 @@ void LayoutTableCell::ComputePreferredLogicalWidths() {
// set on the cell. Even so, it is a WinIE/Moz trait to make the minwidth
// of the cell into the fixed width. They do this even in strict mode, so
// do not make this a quirk. Affected the top of hiptop.com.
- min_preferred_logical_width_ =
- std::max(LayoutUnit(w.Value()), min_preferred_logical_width_);
+ sizes.min_size = std::max(sizes.min_size, LayoutUnit(w.Value()));
}
}
+
+ return sizes;
}
void LayoutTableCell::ComputeIntrinsicPadding(int collapsed_height,
@@ -476,13 +476,13 @@ void LayoutTableCell::StyleDidChange(StyleDifference diff,
// TODO(dgrogan) Add a web test showing that SetChildNeedsLayout is
// needed instead of SetNeedsLayout.
PreviousCell()->SetChildNeedsLayout();
- PreviousCell()->SetPreferredLogicalWidthsDirty(kMarkOnlyThis);
+ PreviousCell()->SetIntrinsicLogicalWidthsDirty(kMarkOnlyThis);
}
if (NextCell()) {
// TODO(dgrogan) Add a web test showing that SetChildNeedsLayout is
// needed instead of SetNeedsLayout.
NextCell()->SetChildNeedsLayout();
- NextCell()->SetPreferredLogicalWidthsDirty(kMarkOnlyThis);
+ NextCell()->SetIntrinsicLogicalWidthsDirty(kMarkOnlyThis);
}
}
}
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 cd9a057af30..b2f2dd196e5 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
@@ -363,9 +363,10 @@ class CORE_EXPORT LayoutTableCell : public LayoutBlockFlow,
// LayoutNGTableCellInterface implementation end.
+ MinMaxSizes PreferredLogicalWidths() const override;
+
protected:
void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
- void ComputePreferredLogicalWidths() override;
void InvalidatePaint(const PaintInvalidatorContext&) const override;
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 77c67634079..0826849fc2e 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
@@ -336,22 +336,26 @@ TEST_F(LayoutTableCellTest, HasNonCollapsedBorderDecoration) {
To<Element>(cell->GetNode())
->setAttribute(html_names::kStyleAttr, "border: 1px solid black");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(cell->HasNonCollapsedBorderDecoration());
To<Element>(cell->Table()->GetNode())
->setAttribute(html_names::kStyleAttr, "border-collapse: collapse");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_FALSE(cell->HasNonCollapsedBorderDecoration());
To<Element>(cell->GetNode())
->setAttribute(html_names::kStyleAttr, "border: 2px solid black");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_FALSE(cell->HasNonCollapsedBorderDecoration());
To<Element>(cell->Table()->GetNode())
->setAttribute(html_names::kStyleAttr, "");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(cell->HasNonCollapsedBorderDecoration());
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_table_col.cc b/chromium/third_party/blink/renderer/core/layout/layout_table_col.cc
index 578d91179f3..e2286b94bfa 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_table_col.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_table_col.cc
@@ -72,15 +72,14 @@ void LayoutTableCol::StyleDidChange(StyleDifference diff,
void LayoutTableCol::UpdateFromElement() {
unsigned old_span = span_;
- Node* n = GetNode();
- if (IsHTMLTableColElement(n)) {
- HTMLTableColElement& tc = ToHTMLTableColElement(*n);
- span_ = tc.span();
+
+ if (auto* tc = DynamicTo<HTMLTableColElement>(GetNode())) {
+ span_ = tc->span();
} else {
span_ = 1;
}
if (span_ != old_span && Style() && Parent()) {
- SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kAttributeChanged);
}
}
@@ -107,17 +106,11 @@ bool LayoutTableCol::CanHaveChildren() const {
return IsTableColumnGroup();
}
-bool LayoutTableCol::PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const {
- // LayoutTableCol paints nothing by itself. Its background is painted by
- // LayoutTableSection.
- return true;
-}
-
-void LayoutTableCol::ClearPreferredLogicalWidthsDirtyBits() {
- ClearPreferredLogicalWidthsDirty();
+void LayoutTableCol::ClearIntrinsicLogicalWidthsDirtyBits() {
+ ClearIntrinsicLogicalWidthsDirty();
for (LayoutObject* child = FirstChild(); child; child = child->NextSibling())
- child->ClearPreferredLogicalWidthsDirty();
+ child->ClearIntrinsicLogicalWidthsDirty();
}
LayoutTable* LayoutTableCol::Table() const {
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_table_col.h b/chromium/third_party/blink/renderer/core/layout/layout_table_col.h
index 56634d3d044..cd905f20d33 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_table_col.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_table_col.h
@@ -60,7 +60,7 @@ class LayoutTableCol final : public LayoutTableBoxComponent {
public:
explicit LayoutTableCol(Element*);
- void ClearPreferredLogicalWidthsDirtyBits();
+ void ClearIntrinsicLogicalWidthsDirtyBits();
// The 'span' attribute in HTML.
// For CSS table columns or colgroups, this is always 1.
@@ -86,7 +86,15 @@ class LayoutTableCol final : public LayoutTableBoxComponent {
return type == kLayoutObjectLayoutTableCol || LayoutBox::IsOfType(type);
}
void UpdateFromElement() override;
- void ComputePreferredLogicalWidths() override { NOTREACHED(); }
+
+ MinMaxSizes PreferredLogicalWidths() const override {
+ NOTREACHED();
+ return MinMaxSizes();
+ }
+ MinMaxSizes ComputeIntrinsicLogicalWidths() const final {
+ NOTREACHED();
+ return MinMaxSizes();
+ }
void InsertedIntoTree() override;
void WillBeRemovedFromTree() override;
@@ -95,8 +103,6 @@ class LayoutTableCol final : public LayoutTableBoxComponent {
bool CanHaveChildren() const override;
PaintLayerType LayerTypeRequired() const override { return kNoPaintLayer; }
- bool PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const final;
-
void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
LayoutTable* Table() const final;
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 001ade422da..8dbea5af6e8 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
@@ -92,7 +92,7 @@ void LayoutTableRow::StyleDidChange(StyleDifference diff,
// TODO(dgrogan) Add a web test showing that SetChildNeedsLayout is
// needed instead of SetNeedsLayout.
child_box->SetChildNeedsLayout();
- child_box->SetPreferredLogicalWidthsDirty(kMarkOnlyThis);
+ child_box->SetIntrinsicLogicalWidthsDirty(kMarkOnlyThis);
}
// Most table componenents can rely on LayoutObject::styleDidChange
// to mark the container chain dirty. But LayoutTableSection seems
@@ -100,7 +100,7 @@ void LayoutTableRow::StyleDidChange(StyleDifference diff,
// anything under LayoutTableSection has to restart the propagation
// at the table.
// TODO(dgrogan): Make LayoutTableSection clear its dirty bit.
- table->SetPreferredLogicalWidthsDirty();
+ table->SetIntrinsicLogicalWidthsDirty();
}
// When a row gets collapsed or uncollapsed, it's necessary to check all the
@@ -178,11 +178,11 @@ void LayoutTableRow::AddChild(LayoutObject* child, LayoutObject* before_child) {
if (enclosing_table && enclosing_table->ShouldCollapseBorders()) {
enclosing_table->InvalidateCollapsedBorders();
if (LayoutTableCell* previous_cell = cell->PreviousCell()) {
- previous_cell->SetNeedsLayoutAndPrefWidthsRecalc(
+ previous_cell->SetNeedsLayoutAndIntrinsicWidthsRecalc(
layout_invalidation_reason::kTableChanged);
}
if (LayoutTableCell* next_cell = cell->NextCell()) {
- next_cell->SetNeedsLayoutAndPrefWidthsRecalc(
+ next_cell->SetNeedsLayoutAndIntrinsicWidthsRecalc(
layout_invalidation_reason::kTableChanged);
}
}
@@ -376,11 +376,4 @@ void LayoutTableRow::AddVisualOverflowFromCell(const LayoutTableCell* cell) {
AddContentsVisualOverflow(cell_visual_overflow_rect);
}
-bool LayoutTableRow::PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const {
- return LayoutTableBoxComponent::
- PaintedOutputOfObjectHasNoEffectRegardlessOfSize() &&
- // Row paints collapsed borders.
- !Table()->HasCollapsedBorders();
-}
-
} // namespace blink
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 7e42e8ef116..82feffcf220 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
@@ -128,8 +128,6 @@ class CORE_EXPORT LayoutTableRow final : public LayoutTableBoxComponent,
bool BackgroundIsKnownToBeOpaqueInRect(const PhysicalRect&) const override {
return false;
}
- bool PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const override;
-
// LayoutNGTableRowInterface methods start.
const LayoutNGTableRowInterface* ToLayoutNGTableRowInterface() const final {
@@ -153,6 +151,11 @@ class CORE_EXPORT LayoutTableRow final : public LayoutTableBoxComponent,
// LayoutNGTableRowInterface methods end.
private:
+ MinMaxSizes ComputeIntrinsicLogicalWidths() const final {
+ NOTREACHED();
+ return MinMaxSizes();
+ }
+
void ComputeVisualOverflow();
void AddLayoutOverflowFromCell(const LayoutTableCell*);
void AddVisualOverflowFromCell(const LayoutTableCell*);
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 f3b49bc2729..e109f213be7 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
@@ -1478,7 +1478,7 @@ void LayoutTableSection::MarkAllCellsWidthsDirtyAndOrNeedsLayout(
for (LayoutTableRow* row = FirstRow(); row; row = row->NextRow()) {
for (LayoutTableCell* cell = row->FirstCell(); cell;
cell = cell->NextCell()) {
- cell->SetPreferredLogicalWidthsDirty();
+ cell->SetIntrinsicLogicalWidthsDirty();
if (what_to_mark == LayoutTable::kMarkDirtyAndNeedsLayout)
cell->SetChildNeedsLayout();
}
@@ -2108,13 +2108,4 @@ bool LayoutTableSection::MapToVisualRectInAncestorSpaceInternal(
ancestor, transform_state, flags);
}
-bool LayoutTableSection::PaintedOutputOfObjectHasNoEffectRegardlessOfSize()
- const {
- // LayoutTableSection paints background from columns.
- if (Table()->HasColElements())
- return false;
- return LayoutTableBoxComponent::
- PaintedOutputOfObjectHasNoEffectRegardlessOfSize();
-}
-
} // namespace blink
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 4bab95705be..2e3495ce6e3 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
@@ -336,6 +336,11 @@ class CORE_EXPORT LayoutTableSection final
HitTestAction) override;
private:
+ MinMaxSizes ComputeIntrinsicLogicalWidths() const final {
+ NOTREACHED();
+ return MinMaxSizes();
+ }
+
void ComputeVisualOverflowFromDescendants();
bool IsOfType(LayoutObjectType type) const override {
@@ -421,8 +426,6 @@ class CORE_EXPORT LayoutTableSection final
// avoid any repeating headers in its table or ancestor tables.
int OffsetForRepeatedHeader() const;
- bool PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const override;
-
bool HeaderGroupShouldRepeat() const {
return Table()->Header() == this && GroupShouldRepeat();
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_table_test.cc b/chromium/third_party/blink/renderer/core/layout/layout_table_test.cc
index 1ea145a99f4..04897e32a31 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_table_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_table_test.cc
@@ -37,8 +37,7 @@ TEST_F(LayoutTableTest, OverflowViaOutline) {
To<Element>(child->GetNode())
->setAttribute(html_names::kStyleAttr, "outline: 2px solid black");
- target->GetFrameView()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ target->GetFrameView()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
EXPECT_EQ(LayoutRect(-2, -2, 104, 204), target->SelfVisualOverflowRect());
EXPECT_EQ(LayoutRect(-2, -2, 104, 204), child->SelfVisualOverflowRect());
@@ -358,8 +357,7 @@ TEST_F(LayoutTableTest, VisualOverflowCleared) {
EXPECT_EQ(LayoutRect(-3, -3, 66, 66), table->SelfVisualOverflowRect());
To<Element>(table->GetNode())
->setAttribute(html_names::kStyleAttr, "box-shadow: initial");
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
EXPECT_EQ(LayoutRect(0, 0, 50, 50), table->SelfVisualOverflowRect());
}
@@ -370,13 +368,15 @@ TEST_F(LayoutTableTest, HasNonCollapsedBorderDecoration) {
To<Element>(table->GetNode())
->setAttribute(html_names::kStyleAttr, "border: 1px solid black");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(table->HasNonCollapsedBorderDecoration());
To<Element>(table->GetNode())
->setAttribute(html_names::kStyleAttr,
"border: 1px solid black; border-collapse: collapse");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_FALSE(table->HasNonCollapsedBorderDecoration());
}
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 f2c80c747a2..b1ccf91480c 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_text.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_text.cc
@@ -29,6 +29,7 @@
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
#include "third_party/blink/renderer/core/content_capture/content_capture_manager.h"
+#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
#include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/editing/ephemeral_range.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
@@ -181,7 +182,8 @@ void LayoutText::StyleDidChange(StyleDifference diff,
// We do have to schedule layouts, though, since a style change can force us
// to need to relayout.
if (diff.NeedsFullLayout()) {
- SetNeedsLayoutAndPrefWidthsRecalc(layout_invalidation_reason::kStyleChange);
+ SetNeedsLayoutAndIntrinsicWidthsRecalc(
+ layout_invalidation_reason::kStyleChange);
known_to_have_no_overflow_and_no_fallback_fonts_ = false;
}
@@ -221,13 +223,20 @@ void LayoutText::RemoveAndDestroyTextBoxes() {
for (InlineTextBox* box : TextBoxes())
box->Remove();
} else {
- if (NGPaintFragment* first_inline_fragment = FirstInlineFragment()) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ if (has_abstract_inline_text_box_)
+ ClearFirstInlineFragmentItemIndex();
+ } else if (NGPaintFragment* first_inline_fragment =
+ FirstInlineFragment()) {
first_inline_fragment->LayoutObjectWillBeDestroyed();
SetFirstInlineFragment(nullptr);
}
if (Parent())
Parent()->DirtyLinesFromChangedChild(this);
}
+ } else if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ if (has_abstract_inline_text_box_)
+ ClearFirstInlineFragmentItemIndex();
} else if (NGPaintFragment* first_inline_fragment = FirstInlineFragment()) {
// Still do this to clear the global hash map in NGAbstractInlineTextBox.
SetFirstInlineFragment(nullptr);
@@ -265,29 +274,42 @@ void LayoutText::RemoveTextBox(InlineTextBox* box) {
void LayoutText::DeleteTextBoxes() {
if (!IsInLayoutNGInlineFormattingContext())
- MutableTextBoxes().DeleteLineBoxes();
+ return MutableTextBoxes().DeleteLineBoxes();
+ DetachAbstractInlineTextBoxesIfNeeded();
}
-void LayoutText::SetFirstInlineFragment(NGPaintFragment* first_fragment) {
- CHECK(IsInLayoutNGInlineFormattingContext());
- // TODO(yosin): Once we remove |NGPaintFragment|, we should get rid of
- // |!fragment|.
- DCHECK(!first_fragment ||
- !RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
+void LayoutText::DetachAbstractInlineTextBoxes() {
// TODO(layout-dev): Because We should call |WillDestroy()| once for
// associated fragments, when you reuse fragments, you should construct
// NGAbstractInlineTextBox for them.
- if (has_abstract_inline_text_box_) {
+ DCHECK(has_abstract_inline_text_box_);
+ has_abstract_inline_text_box_ = false;
+ if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
for (NGPaintFragment* fragment : NGPaintFragment::InlineFragmentsFor(this))
NGAbstractInlineTextBox::WillDestroy(fragment);
- has_abstract_inline_text_box_ = false;
+ return;
}
+ // TODO(yosin): Make sure we call this function within valid containg block
+ // of |this|.
+ NGInlineCursor cursor;
+ for (cursor.MoveTo(*this); cursor; cursor.MoveToNextForSameLayoutObject())
+ NGAbstractInlineTextBox::WillDestroy(cursor);
+}
+
+void LayoutText::SetFirstInlineFragment(NGPaintFragment* first_fragment) {
+ CHECK(IsInLayoutNGInlineFormattingContext());
+ // TODO(yosin): Once we remove |NGPaintFragment|, we should get rid of
+ // |!fragment|.
+ DCHECK(!first_fragment ||
+ !RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
+ DetachAbstractInlineTextBoxesIfNeeded();
first_paint_fragment_ = first_fragment;
}
void LayoutText::ClearFirstInlineFragmentItemIndex() {
CHECK(IsInLayoutNGInlineFormattingContext()) << *this;
DCHECK(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
+ DetachAbstractInlineTextBoxesIfNeeded();
first_fragment_item_index_ = 0u;
}
@@ -296,7 +318,10 @@ void LayoutText::SetFirstInlineFragmentItemIndex(wtf_size_t index) {
// TODO(yosin): Call |NGAbstractInlineTextBox::WillDestroy()|.
DCHECK(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
DCHECK_NE(index, 0u);
- first_fragment_item_index_ = index;
+ DetachAbstractInlineTextBoxesIfNeeded();
+ // TDOO(yosin): Once we update all |LayoutObject::FirstInlineFragment()|,
+ // we should enable below.
+ // first_fragment_item_index_ = index;
}
void LayoutText::InLayoutNGInlineFormattingContextWillChange(bool new_value) {
@@ -305,9 +330,17 @@ void LayoutText::InLayoutNGInlineFormattingContextWillChange(bool new_value) {
// Because |first_paint_fragment_| and |text_boxes_| are union, when one is
// deleted, the other should be initialized to nullptr.
DCHECK(new_value ? !first_paint_fragment_ : !text_boxes_.First());
+
+ // Because there are no inline boxes associated to this text, we should not
+ // have abstract inline text boxes too.
+ DCHECK(!has_abstract_inline_text_box_);
}
Vector<LayoutText::TextBoxInfo> LayoutText::GetTextBoxInfo() const {
+ // This function may kick the layout (e.g., |LocalRect()|), but Inspector may
+ // call this function outside of the layout phase.
+ FontCachePurgePreventer fontCachePurgePreventer;
+
Vector<TextBoxInfo> results;
if (const NGOffsetMapping* mapping = GetNGOffsetMapping()) {
bool in_hidden_for_paint = false;
@@ -317,7 +350,7 @@ Vector<LayoutText::TextBoxInfo> LayoutText::GetTextBoxInfo() const {
// TODO(yosin): We should introduce
// |NGPhysicalTextFragment::IsTruncated()| to skip them instead of using
// |IsHiddenForPaint()| with ordering of fragments.
- if (cursor.IsHiddenForPaint()) {
+ if (cursor.Current().IsHiddenForPaint()) {
in_hidden_for_paint = true;
} else if (in_hidden_for_paint) {
// Because of we finished original fragments (not painted), we should
@@ -326,31 +359,31 @@ Vector<LayoutText::TextBoxInfo> LayoutText::GetTextBoxInfo() const {
}
// We don't put generated texts, e.g. ellipsis, hyphen, etc. not in text
// content, into results. Note: CSS "content" aren't categorized this.
- if (cursor.IsGeneratedTextType())
+ if (cursor.Current().IsGeneratedTextType())
continue;
// When the corresponding DOM range contains collapsed whitespaces, NG
// produces one fragment but legacy produces multiple text boxes broken at
// collapsed whitespaces. We break the fragment at collapsed whitespaces
// to match the legacy output.
+ const NGTextOffset offset = cursor.Current().TextOffset();
for (const NGOffsetMappingUnit& unit :
- mapping->GetMappingUnitsForTextContentOffsetRange(
- cursor.CurrentTextStartOffset(),
- cursor.CurrentTextEndOffset())) {
+ mapping->GetMappingUnitsForTextContentOffsetRange(offset.start,
+ offset.end)) {
DCHECK_EQ(unit.GetLayoutObject(), this);
if (unit.GetType() == NGOffsetMappingUnitType::kCollapsed)
continue;
// [clamped_start, clamped_end] of |fragment| matches a legacy text box.
const unsigned clamped_start =
- std::max(unit.TextContentStart(), cursor.CurrentTextStartOffset());
+ std::max(unit.TextContentStart(), offset.start);
const unsigned clamped_end =
- std::min(unit.TextContentEnd(), cursor.CurrentTextEndOffset());
+ std::min(unit.TextContentEnd(), offset.end);
DCHECK_LT(clamped_start, clamped_end);
const unsigned box_length = clamped_end - clamped_start;
// Compute rect of the legacy text box.
LayoutRect rect =
cursor.CurrentLocalRect(clamped_start, clamped_end).ToLayoutRect();
- rect.MoveBy(cursor.CurrentOffset().ToLayoutPoint());
+ rect.MoveBy(cursor.Current().OffsetInContainerBlock().ToLayoutPoint());
// Compute start of the legacy text box.
if (unit.AssociatedNode()) {
@@ -380,15 +413,13 @@ Vector<LayoutText::TextBoxInfo> LayoutText::GetTextBoxInfo() const {
return results;
}
-bool LayoutText::HasTextBoxes() const {
- if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
- auto fragments = NGPaintFragment::InlineFragmentsFor(this);
- if (fragments.IsInLayoutNGInlineFormattingContext())
- return !(fragments.begin() == fragments.end());
- // When legacy is forced, IsInLayoutNGInlineFormattingContext is false,
- // and we fall back to normal HasTextBox
- return FirstTextBox();
- }
+bool LayoutText::HasInlineFragments() const {
+ if (IsInLayoutNGInlineFormattingContext()) {
+ NGInlineCursor cursor;
+ cursor.MoveTo(*this);
+ return cursor.IsNotNull();
+ }
+
return FirstTextBox();
}
@@ -473,10 +504,10 @@ void LayoutText::CollectLineBoxRects(const PhysicalRectCollector& yield,
for (; cursor; cursor.MoveToNextForSameLayoutObject()) {
if (UNLIKELY(option != ClippingOption::kNoClipping)) {
DCHECK_EQ(option, ClippingOption::kClipToEllipsis);
- if (cursor.IsHiddenForPaint())
+ if (cursor.Current().IsHiddenForPaint())
continue;
}
- yield(cursor.CurrentRect());
+ yield(cursor.Current().RectInContainerBlock());
}
return;
}
@@ -585,13 +616,13 @@ void LayoutText::AbsoluteQuadsForRange(Vector<FloatQuad>& quads,
block_for_flipping = ContainingBlock();
NGInlineCursor cursor;
for (cursor.MoveTo(*this); cursor; cursor.MoveToNextForSameLayoutObject()) {
- const NGTextOffset offset = cursor.CurrentTextOffset();
+ const NGTextOffset offset = cursor.Current().TextOffset();
if (start > offset.end || end < offset.start)
continue;
const unsigned clamped_start = std::max(start, offset.start);
const unsigned clamped_end = std::min(end, offset.end);
PhysicalRect rect = cursor.CurrentLocalRect(clamped_start, clamped_end);
- rect.Move(cursor.CurrentOffset());
+ rect.Move(cursor.Current().OffsetInContainerBlock());
const FloatQuad quad = LocalRectToAbsoluteQuad(rect);
if (clamped_start < clamped_end) {
quads.push_back(quad);
@@ -979,7 +1010,7 @@ void LayoutText::TrimmedPrefWidths(LayoutUnit lead_width_layout_unit,
if (!collapse_white_space)
strip_front_spaces = false;
- if (has_tab_ || PreferredLogicalWidthsDirty())
+ if (has_tab_ || IntrinsicLogicalWidthsDirty())
ComputePreferredLogicalWidths(lead_width);
has_breakable_start = !strip_front_spaces && has_breakable_start_;
@@ -1070,14 +1101,14 @@ void LayoutText::TrimmedPrefWidths(LayoutUnit lead_width_layout_unit,
}
float LayoutText::MinLogicalWidth() const {
- if (PreferredLogicalWidthsDirty())
+ if (IntrinsicLogicalWidthsDirty())
const_cast<LayoutText*>(this)->ComputePreferredLogicalWidths(0);
return min_width_;
}
float LayoutText::MaxLogicalWidth() const {
- if (PreferredLogicalWidthsDirty())
+ if (IntrinsicLogicalWidthsDirty())
const_cast<LayoutText*>(this)->ComputePreferredLogicalWidths(0);
return max_width_;
@@ -1173,7 +1204,7 @@ void LayoutText::ComputePreferredLogicalWidths(
float lead_width,
HashSet<const SimpleFontData*>& fallback_fonts,
FloatRect& glyph_bounds) {
- DCHECK(has_tab_ || PreferredLogicalWidthsDirty() ||
+ DCHECK(has_tab_ || IntrinsicLogicalWidthsDirty() ||
!known_to_have_no_overflow_and_no_fallback_fonts_);
min_width_ = 0;
@@ -1523,7 +1554,7 @@ void LayoutText::ComputePreferredLogicalWidths(
known_to_have_no_overflow_and_no_fallback_fonts_ =
fallback_fonts.IsEmpty() && glyph_overflow.IsApproximatelyZero();
- ClearPreferredLogicalWidthsDirty();
+ ClearIntrinsicLogicalWidthsDirty();
}
bool LayoutText::IsAllCollapsibleWhitespace() const {
@@ -1564,7 +1595,7 @@ UChar32 LayoutText::FirstCharacterAfterWhitespaceCollapsing() const {
NGInlineCursor cursor;
cursor.MoveTo(*this);
if (cursor) {
- const StringView text = cursor.CurrentText();
+ const StringView text = cursor.Current().Text(cursor);
return text.length() ? text.CodepointAt(0) : 0;
}
}
@@ -1580,7 +1611,7 @@ UChar32 LayoutText::LastCharacterAfterWhitespaceCollapsing() const {
NGInlineCursor cursor;
cursor.MoveTo(*this);
if (cursor) {
- const StringView text = cursor.CurrentText();
+ const StringView text = cursor.Current().Text(cursor);
return text.length() ? text.CodepointAt(text.length() - 1) : 0;
}
}
@@ -1588,12 +1619,15 @@ UChar32 LayoutText::LastCharacterAfterWhitespaceCollapsing() const {
}
PhysicalOffset LayoutText::FirstLineBoxTopLeft() const {
- if (const NGPaintFragment* fragment = FirstInlineFragment()) {
+ if (IsInLayoutNGInlineFormattingContext()) {
// TODO(kojii): Some clients call this against dirty-tree, but NG fragments
// are not safe to read for dirty-tree. crbug.com/963103
if (UNLIKELY(!IsFirstInlineFragmentSafe()))
return PhysicalOffset();
- return fragment->InlineOffsetToContainerBox();
+ NGInlineCursor cursor;
+ cursor.MoveTo(*this);
+ return cursor ? cursor.Current().OffsetInContainerBlock()
+ : PhysicalOffset();
}
if (const auto* text_box = FirstTextBox()) {
LayoutPoint location = text_box->Location();
@@ -1798,7 +1832,7 @@ static inline bool IsInlineFlowOrEmptyText(const LayoutObject* o) {
}
OnlyWhitespaceOrNbsp LayoutText::ContainsOnlyWhitespaceOrNbsp() const {
- return PreferredLogicalWidthsDirty() ? OnlyWhitespaceOrNbsp::kUnknown
+ return IntrinsicLogicalWidthsDirty() ? OnlyWhitespaceOrNbsp::kUnknown
: static_cast<OnlyWhitespaceOrNbsp>(
contains_only_whitespace_or_nbsp_);
}
@@ -1889,10 +1923,10 @@ void LayoutText::ForceSetText(scoped_refptr<StringImpl> text) {
void LayoutText::TextDidChange() {
// If preferredLogicalWidthsDirty() of an orphan child is true,
// LayoutObjectChildList::insertChildNode() fails to set true to owner.
- // To avoid that, we call setNeedsLayoutAndPrefWidthsRecalc() only if this
- // LayoutText has parent.
+ // To avoid that, we call SetNeedsLayoutAndIntrinsicWidthsRecalc() only if
+ // this LayoutText has parent.
if (Parent()) {
- SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
+ SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
layout_invalidation_reason::kTextChanged);
}
TextDidChangeWithoutInvalidation();
@@ -1918,6 +1952,14 @@ void LayoutText::TextDidChangeWithoutInvalidation() {
SetNeedsCollectInlines();
}
+void LayoutText::InvalidateSubtreeLayoutForFontUpdates() {
+ known_to_have_no_overflow_and_no_fallback_fonts_ = false;
+ valid_ng_items_ = false;
+ SetNeedsCollectInlines();
+ SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
+ layout_invalidation_reason::kFontsChanged);
+}
+
void LayoutText::DirtyOrDeleteLineBoxesIfNeeded(bool full_layout) {
if (full_layout)
DeleteTextBoxes();
@@ -1999,7 +2041,7 @@ float LayoutText::Width(unsigned from,
if (!StyleRef().PreserveNewline() && !from && len == TextLength()) {
if (fallback_fonts) {
DCHECK(glyph_bounds);
- if (PreferredLogicalWidthsDirty() ||
+ if (IntrinsicLogicalWidthsDirty() ||
!known_to_have_no_overflow_and_no_fallback_fonts_) {
const_cast<LayoutText*>(this)->ComputePreferredLogicalWidths(
0, *fallback_fonts, *glyph_bounds);
@@ -2110,14 +2152,14 @@ PhysicalRect LayoutText::LocalSelectionVisualRect() const {
PhysicalRect rect;
NGInlineCursor cursor(*RootInlineFormattingContext());
for (cursor.MoveTo(*this); cursor; cursor.MoveToNextForSameLayoutObject()) {
- if (cursor.IsHiddenForPaint())
+ if (cursor.Current().IsHiddenForPaint())
continue;
const LayoutSelectionStatus status =
frame_selection.ComputeLayoutSelectionStatus(cursor);
if (status.start == status.end)
continue;
PhysicalRect item_rect = ComputeLocalSelectionRectForText(cursor, status);
- item_rect.offset += cursor.CurrentOffset();
+ item_rect.offset += cursor.Current().OffsetInContainerBlock();
rect.Unite(item_rect);
}
return rect;
@@ -2415,12 +2457,10 @@ void LayoutText::MomentarilyRevealLastTypedCharacter(
}
scoped_refptr<AbstractInlineTextBox> LayoutText::FirstAbstractInlineTextBox() {
- if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
- auto fragments = NGPaintFragment::InlineFragmentsFor(this);
- if (!fragments.IsEmpty() &&
- fragments.IsInLayoutNGInlineFormattingContext()) {
- return NGAbstractInlineTextBox::GetOrCreate(fragments.front());
- }
+ if (IsInLayoutNGInlineFormattingContext()) {
+ NGInlineCursor cursor;
+ cursor.MoveTo(*this);
+ return NGAbstractInlineTextBox::GetOrCreate(cursor);
}
return LegacyAbstractInlineTextBox::GetOrCreate(LineLayoutText(this),
FirstTextBox());
@@ -2430,7 +2470,8 @@ void LayoutText::InvalidateDisplayItemClients(
PaintInvalidationReason invalidation_reason) const {
ObjectPaintInvalidator paint_invalidator(*this);
- if (RuntimeEnabledFeatures::LayoutNGBlockFragmentationEnabled()) {
+ if (RuntimeEnabledFeatures::LayoutNGBlockFragmentationEnabled() &&
+ !RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
auto fragments = NGPaintFragment::InlineFragmentsFor(this);
if (fragments.IsInLayoutNGInlineFormattingContext()) {
for (NGPaintFragment* fragment : fragments) {
@@ -2445,7 +2486,7 @@ void LayoutText::InvalidateDisplayItemClients(
NGInlineCursor cursor;
for (cursor.MoveTo(*this); cursor; cursor.MoveToNextForSameLayoutObject()) {
paint_invalidator.InvalidateDisplayItemClient(
- *cursor.CurrentDisplayItemClient(), invalidation_reason);
+ *cursor.Current().GetDisplayItemClient(), invalidation_reason);
}
return;
}
@@ -2467,8 +2508,11 @@ PhysicalRect LayoutText::DebugRect() const {
DOMNodeId LayoutText::EnsureNodeId() {
if (node_id_ == kInvalidDOMNodeId) {
- if (auto* content_capture_manager = GetContentCaptureManager())
- node_id_ = content_capture_manager->GetNodeId(*GetNode());
+ auto* content_capture_manager = GetContentCaptureManager();
+ if (content_capture_manager) {
+ content_capture_manager->ScheduleTaskIfNeeded();
+ node_id_ = DOMNodeIds::IdForNode(GetNode());
+ }
}
return node_id_;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_text.h b/chromium/third_party/blink/renderer/core/layout/layout_text.h
index 3548afaf77a..17ca490ad20 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_text.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_text.h
@@ -97,6 +97,7 @@ class CORE_EXPORT LayoutText : public LayoutObject {
void AttachTextBox(InlineTextBox*);
void RemoveTextBox(InlineTextBox*);
+ bool HasInlineFragments() const final;
NGPaintFragment* FirstInlineFragment() const final;
void SetFirstInlineFragment(NGPaintFragment*) final;
wtf_size_t FirstInlineFragmentItemIndex() const final;
@@ -218,10 +219,6 @@ class CORE_EXPORT LayoutText : public LayoutObject {
InlineTextBox* FirstTextBox() const { return TextBoxes().First(); }
InlineTextBox* LastTextBox() const { return TextBoxes().Last(); }
- // True if we have inline text box children which implies rendered text (or
- // whitespace) output.
- bool HasTextBoxes() const;
-
// TODO(layoutng) Legacy-only implementation of HasTextBoxes.
// All callers should call HasTextBoxes instead, and take NG into account.
bool HasLegacyTextBoxes() const { return FirstTextBox(); }
@@ -331,6 +328,10 @@ class CORE_EXPORT LayoutText : public LayoutObject {
}
virtual base::span<NGInlineItem>* GetNGInlineItems() { return nullptr; }
+ void InvalidateSubtreeLayoutForFontUpdates() override;
+
+ void DetachAbstractInlineTextBoxesIfNeeded();
+
protected:
void WillBeDestroyed() override;
@@ -439,6 +440,7 @@ class CORE_EXPORT LayoutText : public LayoutObject {
private:
ContentCaptureManager* GetContentCaptureManager();
+ void DetachAbstractInlineTextBoxes();
// Used for LayoutNG with accessibility. True if inline fragments are
// associated to |NGAbstractInlineTextBox|.
@@ -517,6 +519,11 @@ inline float LayoutText::HyphenWidth(const Font& font,
style, direction));
}
+inline void LayoutText::DetachAbstractInlineTextBoxesIfNeeded() {
+ if (UNLIKELY(has_abstract_inline_text_box_))
+ DetachAbstractInlineTextBoxes();
+}
+
DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutText, IsText());
inline LayoutText* Text::GetLayoutObject() const {
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_text_combine.cc b/chromium/third_party/blink/renderer/core/layout/layout_text_combine.cc
index 62c19718366..cb823919580 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_text_combine.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_text_combine.cc
@@ -177,7 +177,7 @@ void LayoutTextCombine::UpdateFontStyleForCombinedText() {
FontSelector* font_selector = style->GetFont().GetFontSelector();
// Need to change font orientation to horizontal.
- bool should_update_font = style->SetFontDescription(description);
+ style->SetFontDescription(description);
if (combined_text_width_ <= em_width) {
scale_x_ = 1.0f;
@@ -187,14 +187,13 @@ void LayoutTextCombine::UpdateFontStyleForCombinedText() {
kQuarterWidth};
for (size_t i = 0; i < base::size(kWidthVariants); ++i) {
description.SetWidthVariant(kWidthVariants[i]);
- Font compressed_font = Font(description);
- compressed_font.Update(font_selector);
+ Font compressed_font(description, font_selector);
float run_width = compressed_font.Width(run);
if (run_width <= em_width) {
combined_text_width_ = run_width;
// Replace my font with the new one.
- should_update_font = style->SetFontDescription(description);
+ style->SetFontDescription(description);
break;
}
}
@@ -209,9 +208,6 @@ void LayoutTextCombine::UpdateFontStyleForCombinedText() {
scale_x_ = 1.0f;
}
}
-
- if (should_update_font)
- style->GetFont().Update(font_selector);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_text_control.cc b/chromium/third_party/blink/renderer/core/layout/layout_text_control.cc
index 966bfa81583..cce0469a265 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_text_control.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_text_control.cc
@@ -208,69 +208,25 @@ float LayoutTextControl::GetAvgCharWidth(const AtomicString& family) const {
return font.Width(text_run);
}
-void LayoutTextControl::ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const {
+MinMaxSizes LayoutTextControl::ComputeIntrinsicLogicalWidths() const {
+ MinMaxSizes sizes;
+ sizes += BorderAndPaddingLogicalWidth();
+
// Use average character width. Matches IE.
AtomicString family =
StyleRef().GetFont().GetFontDescription().Family().Family();
- max_logical_width = PreferredContentLogicalWidth(
+ sizes.max_size += PreferredContentLogicalWidth(
const_cast<LayoutTextControl*>(this)->GetAvgCharWidth(family));
if (InnerEditorElement()) {
if (LayoutBox* inner_editor_layout_box =
- InnerEditorElement()->GetLayoutBox())
- max_logical_width += inner_editor_layout_box->PaddingStart() +
- inner_editor_layout_box->PaddingEnd();
+ InnerEditorElement()->GetLayoutBox()) {
+ sizes.max_size += inner_editor_layout_box->PaddingStart() +
+ inner_editor_layout_box->PaddingEnd();
+ }
}
if (!StyleRef().LogicalWidth().IsPercentOrCalc())
- min_logical_width = max_logical_width;
-}
-
-void LayoutTextControl::ComputePreferredLogicalWidths() {
- DCHECK(PreferredLogicalWidthsDirty());
-
- min_preferred_logical_width_ = LayoutUnit();
- max_preferred_logical_width_ = LayoutUnit();
- const ComputedStyle& style_to_use = StyleRef();
-
- if (style_to_use.LogicalWidth().IsFixed() &&
- style_to_use.LogicalWidth().Value() >= 0)
- min_preferred_logical_width_ = max_preferred_logical_width_ =
- AdjustContentBoxLogicalWidthForBoxSizing(
- style_to_use.LogicalWidth().Value());
- else
- ComputeIntrinsicLogicalWidths(min_preferred_logical_width_,
- max_preferred_logical_width_);
-
- if (style_to_use.LogicalMinWidth().IsFixed() &&
- style_to_use.LogicalMinWidth().Value() > 0) {
- max_preferred_logical_width_ =
- std::max(max_preferred_logical_width_,
- AdjustContentBoxLogicalWidthForBoxSizing(
- style_to_use.LogicalMinWidth().Value()));
- min_preferred_logical_width_ =
- std::max(min_preferred_logical_width_,
- AdjustContentBoxLogicalWidthForBoxSizing(
- style_to_use.LogicalMinWidth().Value()));
- }
-
- if (style_to_use.LogicalMaxWidth().IsFixed()) {
- max_preferred_logical_width_ =
- std::min(max_preferred_logical_width_,
- AdjustContentBoxLogicalWidthForBoxSizing(
- style_to_use.LogicalMaxWidth().Value()));
- min_preferred_logical_width_ =
- std::min(min_preferred_logical_width_,
- AdjustContentBoxLogicalWidthForBoxSizing(
- style_to_use.LogicalMaxWidth().Value()));
- }
-
- LayoutUnit to_add = BorderAndPaddingLogicalWidth();
-
- min_preferred_logical_width_ += to_add;
- max_preferred_logical_width_ += to_add;
-
- ClearPreferredLogicalWidthsDirty();
+ sizes.min_size = sizes.max_size;
+ return sizes;
}
void LayoutTextControl::AddOutlineRects(Vector<PhysicalRect>& rects,
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_text_control.h b/chromium/third_party/blink/renderer/core/layout/layout_text_control.h
index 4c6b2bfb358..b3298fc3835 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_text_control.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_text_control.h
@@ -75,22 +75,13 @@ class CORE_EXPORT LayoutTextControl : public LayoutBlockFlow {
SubtreeLayoutScope&) override;
LayoutUnit FirstLineBoxBaseline() const override;
- // We need to override this function because we don't want overflow:hidden on
- // an <input> to affect the baseline calculation. This is necessary because we
- // are an inline-block element as an implementation detail which would
- // normally be affected by this.
- bool ShouldIgnoreOverflowPropertyForInlineBlockBaseline() const override {
- return true;
- }
bool IsOfType(LayoutObjectType type) const override {
return type == kLayoutObjectTextControl || LayoutBlockFlow::IsOfType(type);
}
private:
- void ComputeIntrinsicLogicalWidths(LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const final;
- void ComputePreferredLogicalWidths() final;
+ MinMaxSizes ComputeIntrinsicLogicalWidths() const final;
void RemoveLeftoverAnonymousBlock(LayoutBlock*) final {}
void AddOutlineRects(Vector<PhysicalRect>&,
@@ -100,33 +91,10 @@ class CORE_EXPORT LayoutTextControl : public LayoutBlockFlow {
bool CanBeProgramaticallyScrolled() const final { return true; }
};
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutTextControl, IsTextControl());
-
-// LayoutObject for our inner container, for <search> and others.
-// We can't use LayoutFlexibleBox directly, because flexboxes have a different
-// baseline definition, and then inputs of different types wouldn't line up
-// anymore.
-class LayoutTextControlInnerContainer final : public LayoutFlexibleBox {
- public:
- explicit LayoutTextControlInnerContainer(Element* element)
- : LayoutFlexibleBox(element) {}
- ~LayoutTextControlInnerContainer() override = default;
-
- LayoutUnit BaselinePosition(FontBaseline baseline,
- bool first_line,
- LineDirectionMode direction,
- LinePositionMode position) const override {
- return LayoutBlock::BaselinePosition(baseline, first_line, direction,
- position);
- }
- LayoutUnit FirstLineBoxBaseline() const override {
- return LayoutBlock::FirstLineBoxBaseline();
- }
- LayoutUnit InlineBlockBaseline(LineDirectionMode direction) const override {
- return LayoutBlock::InlineBlockBaseline(direction);
- }
- bool ShouldIgnoreOverflowPropertyForInlineBlockBaseline() const override {
- return true;
+template <>
+struct DowncastTraits<LayoutTextControl> {
+ static bool AllowFrom(const LayoutObject& object) {
+ return object.IsTextControl();
}
};
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_text_control_multi_line.h b/chromium/third_party/blink/renderer/core/layout/layout_text_control_multi_line.h
index 35fff854e5b..21111aa1a63 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_text_control_multi_line.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_text_control_multi_line.h
@@ -66,8 +66,6 @@ class LayoutTextControlMultiLine final : public LayoutTextControl {
LayoutUnit ScrollHeight() const override;
};
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutTextControlMultiLine, IsTextArea());
-
} // namespace blink
#endif
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc b/chromium/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc
index 6f1f6bc19ae..b2c0cebcab0 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc
@@ -197,17 +197,6 @@ void LayoutTextControlSingleLine::CapsLockStateMayHaveChanged() {
}
}
-bool LayoutTextControlSingleLine::HasControlClip() const {
- return true;
-}
-
-PhysicalRect LayoutTextControlSingleLine::ControlClipRect(
- const PhysicalOffset& additional_offset) const {
- PhysicalRect clip_rect = PhysicalPaddingBoxRect();
- clip_rect.offset += additional_offset;
- return clip_rect;
-}
-
LayoutUnit LayoutTextControlSingleLine::PreferredContentLogicalWidth(
float char_width) const {
int factor;
@@ -249,14 +238,6 @@ LayoutUnit LayoutTextControlSingleLine::ComputeControlLogicalHeight(
return line_height + non_content_height;
}
-void LayoutTextControlSingleLine::Autoscroll(const PhysicalOffset& position) {
- LayoutBox* layout_object = InnerEditorElement()->GetLayoutBox();
- if (!layout_object)
- return;
-
- layout_object->Autoscroll(position);
-}
-
LayoutUnit LayoutTextControlSingleLine::ScrollWidth() const {
// If in preview state, fake the scroll width to prevent that any information
// about the suggested content can be derived from the size.
@@ -309,6 +290,7 @@ void LayoutTextControlSingleLine::ComputeVisualOverflow(
AddVisualOverflowFromFloats();
if (VisualOverflowRect() != previous_visual_overflow_rect) {
+ InvalidateIntersectionObserverCachedRects();
SetShouldCheckForPaintInvalidation();
GetFrameView()->SetIntersectionObservationState(LocalFrameView::kDesired);
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_text_control_single_line.h b/chromium/third_party/blink/renderer/core/layout/layout_text_control_single_line.h
index a49de236a8d..59323298ca3 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_text_control_single_line.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_text_control_single_line.h
@@ -31,6 +31,12 @@ namespace blink {
class HTMLInputElement;
+// LayoutObject for text-field <input>s.
+//
+// This class inherits from LayoutTextControl and LayoutBlockFlow. If we'd like
+// to change the base class, we need to make sure that
+// ShouldIgnoreOverflowPropertyForInlineBlockBaseline flag works with the new
+// base class.
class LayoutTextControlSingleLine : public LayoutTextControl {
public:
LayoutTextControlSingleLine(HTMLInputElement*);
@@ -47,8 +53,6 @@ class LayoutTextControlSingleLine : public LayoutTextControl {
HTMLInputElement* InputElement() const;
private:
- bool HasControlClip() const final;
- PhysicalRect ControlClipRect(const PhysicalOffset&) const final;
bool IsOfType(LayoutObjectType type) const override {
return type == kLayoutObjectTextField || LayoutTextControl::IsOfType(type);
}
@@ -61,8 +65,6 @@ class LayoutTextControlSingleLine : public LayoutTextControl {
const PhysicalOffset& accumulated_offset,
HitTestAction) final;
- void Autoscroll(const PhysicalOffset&) final;
-
// Subclassed to forward to our inner div.
LayoutUnit ScrollWidth() const final;
LayoutUnit ScrollHeight() const final;
@@ -87,16 +89,18 @@ class LayoutTextControlSingleLine : public LayoutTextControl {
bool should_draw_caps_lock_indicator_;
};
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutTextControlSingleLine, IsTextField());
+template <>
+struct DowncastTraits<LayoutTextControlSingleLine> {
+ static bool AllowFrom(const LayoutObject& object) {
+ return object.IsTextField();
+ }
+};
// ----------------------------
class LayoutTextControlInnerEditor : public LayoutBlockFlow {
public:
LayoutTextControlInnerEditor(Element* element) : LayoutBlockFlow(element) {}
- bool ShouldIgnoreOverflowPropertyForInlineBlockBaseline() const override {
- return true;
- }
private:
bool IsIntrinsicallyScrollable(
@@ -105,7 +109,6 @@ class LayoutTextControlInnerEditor : public LayoutBlockFlow {
}
bool ScrollsOverflowX() const override { return HasOverflowClip(); }
bool ScrollsOverflowY() const override { return false; }
- bool HasLineIfEmpty() const override { return true; }
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_text_control_single_line_test.cc b/chromium/third_party/blink/renderer/core/layout/layout_text_control_single_line_test.cc
index a0533fd75c5..a04b29a50f4 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_text_control_single_line_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_text_control_single_line_test.cc
@@ -6,6 +6,7 @@
#include "build/build_config.h"
#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
+#include "ui/base/ui_base_features.h"
namespace blink {
@@ -23,21 +24,28 @@ TEST_F(LayoutTextControlSingleLineTest, VisualOverflowCleared) {
<input id=input type="text"></input.
)HTML");
auto* input =
- ToLayoutTextControlSingleLine(GetLayoutObjectByElementId("input"));
+ To<LayoutTextControlSingleLine>(GetLayoutObjectByElementId("input"));
+ if (::features::IsFormControlsRefreshEnabled()) {
+ EXPECT_EQ(LayoutRect(-3, -3, 74, 72), input->SelfVisualOverflowRect());
+ } else {
#if defined(OS_MACOSX)
- EXPECT_EQ(LayoutRect(-3, -3, 72, 72), input->SelfVisualOverflowRect());
+ EXPECT_EQ(LayoutRect(-3, -3, 72, 72), input->SelfVisualOverflowRect());
#else
- EXPECT_EQ(LayoutRect(-3, -3, 70, 72), input->SelfVisualOverflowRect());
+ EXPECT_EQ(LayoutRect(-3, -3, 70, 72), input->SelfVisualOverflowRect());
#endif
+ }
To<Element>(input->GetNode())
->setAttribute(html_names::kStyleAttr, "box-shadow: initial");
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
+ if (::features::IsFormControlsRefreshEnabled()) {
+ EXPECT_EQ(LayoutRect(0, 0, 58, 56), input->SelfVisualOverflowRect());
+ } else {
#if defined(OS_MACOSX)
- EXPECT_EQ(LayoutRect(0, 0, 56, 56), input->SelfVisualOverflowRect());
+ EXPECT_EQ(LayoutRect(0, 0, 56, 56), input->SelfVisualOverflowRect());
#else
- EXPECT_EQ(LayoutRect(0, 0, 54, 56), input->SelfVisualOverflowRect());
+ EXPECT_EQ(LayoutRect(0, 0, 54, 56), input->SelfVisualOverflowRect());
#endif
+ }
}
} // anonymous namespace
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_text_control_test.cc b/chromium/third_party/blink/renderer/core/layout/layout_text_control_test.cc
index 18d55934be9..b8446166f0c 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_text_control_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_text_control_test.cc
@@ -44,7 +44,8 @@ TEST_F(LayoutTextControlTest,
EXPECT_FALSE(selectedText->ShouldInvalidateSelection());
inputElement->setAttribute(html_names::kClassAttr, "pseudoSelection");
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(selectedText->ShouldInvalidateSelection());
UpdateAllLifecyclePhasesForTest();
@@ -69,7 +70,8 @@ TEST_F(LayoutTextControlTest,
EXPECT_FALSE(selectedText->ShouldInvalidateSelection());
inputElement->setAttribute(html_names::kClassAttr, "pseudoSelection");
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(selectedText->ShouldInvalidateSelection());
UpdateAllLifecyclePhasesForTest();
@@ -94,7 +96,8 @@ TEST_F(LayoutTextControlTest,
EXPECT_FALSE(selectedText->ShouldInvalidateSelection());
inputElement->removeAttribute(html_names::kClassAttr);
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(selectedText->ShouldInvalidateSelection());
UpdateAllLifecyclePhasesForTest();
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_text_fragment_test.cc b/chromium/third_party/blink/renderer/core/layout/layout_text_fragment_test.cc
index e8bacc966f2..3405d85c0ae 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_text_fragment_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_text_fragment_test.cc
@@ -17,7 +17,7 @@ class LayoutTextFragmentTest : public RenderingTest {
protected:
void SetUp() override {
RenderingTest::SetUp();
- GetDocument().head()->SetInnerHTMLFromString(
+ GetDocument().head()->setInnerHTML(
"<style>#target::first-letter{color:red}</style>");
}
@@ -52,7 +52,9 @@ class ParameterizedLayoutTextFragmentTest
ParameterizedLayoutTextFragmentTest() : ScopedLayoutNGForTest(GetParam()) {}
protected:
- bool LayoutNGEnabled() const { return GetParam(); }
+ bool LayoutNGEnabled() const {
+ return RuntimeEnabledFeatures::LayoutNGEnabled();
+ }
};
INSTANTIATE_TEST_SUITE_P(All,
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 ac8fb58a804..ec907acd7fa 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
@@ -78,7 +78,9 @@ class ParameterizedLayoutTextTest : public testing::WithParamInterface<bool>,
ParameterizedLayoutTextTest() : ScopedLayoutNGForTest(GetParam()) {}
protected:
- bool LayoutNGEnabled() const { return GetParam(); }
+ bool LayoutNGEnabled() const {
+ return RuntimeEnabledFeatures::LayoutNGEnabled();
+ }
};
INSTANTIATE_TEST_SUITE_P(All, ParameterizedLayoutTextTest, testing::Bool());
@@ -252,7 +254,7 @@ TEST_P(ParameterizedLayoutTextTest, CharacterAfterWhitespaceCollapsing) {
SetBodyInnerHTML("a <span id=target> </span>b");
layout_text = GetLayoutTextById("target");
- DCHECK(!layout_text->HasTextBoxes());
+ DCHECK(!layout_text->HasInlineFragments());
EXPECT_EQ(0, layout_text->FirstCharacterAfterWhitespaceCollapsing());
EXPECT_EQ(0, layout_text->LastCharacterAfterWhitespaceCollapsing());
@@ -268,7 +270,7 @@ TEST_P(ParameterizedLayoutTextTest, CharacterAfterWhitespaceCollapsing) {
EXPECT_EQ(' ', layout_text->LastCharacterAfterWhitespaceCollapsing());
layout_text =
ToLayoutText(GetLayoutObjectByElementId("target")->NextSibling());
- DCHECK(!layout_text->HasTextBoxes());
+ DCHECK(!layout_text->HasInlineFragments());
EXPECT_EQ(0, layout_text->FirstCharacterAfterWhitespaceCollapsing());
EXPECT_EQ(0, layout_text->LastCharacterAfterWhitespaceCollapsing());
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_theme.cc b/chromium/third_party/blink/renderer/core/layout/layout_theme.cc
index 488f6f7d225..b1cbf5326ba 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_theme.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_theme.cc
@@ -30,7 +30,7 @@
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
-#include "third_party/blink/renderer/core/fileapi/file_list.h"
+#include "third_party/blink/renderer/core/fileapi/file.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/forms/html_data_list_element.h"
@@ -55,12 +55,11 @@
#include "third_party/blink/renderer/core/style/computed_style_initial_values.h"
#include "third_party/blink/renderer/platform/file_metadata.h"
#include "third_party/blink/renderer/platform/fonts/font_selector.h"
-#include "third_party/blink/renderer/platform/fonts/string_truncator.h"
#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/platform_locale.h"
#include "third_party/blink/renderer/platform/web_test_support.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
+#include "ui/base/ui_base_features.h"
#include "ui/native_theme/native_theme.h"
// The methods in this file are shared by all themes on every platform.
@@ -164,9 +163,6 @@ ControlPart LayoutTheme::AdjustAppearanceWithElementType(
const ComputedStyle& style,
const Element* element) {
ControlPart part = style.EffectiveAppearance();
- if (!RuntimeEnabledFeatures::RestrictedWebkitAppearanceEnabled())
- return part;
-
if (!element)
return kNoControlPart;
@@ -186,6 +182,7 @@ ControlPart LayoutTheme::AdjustAppearanceWithElementType(
// Aliases of 'auto'.
// https://drafts.csswg.org/css-ui-4/#typedef-appearance-compat-auto
+ case kAutoPart:
case kCheckboxPart:
case kRadioPart:
case kPushButtonPart:
@@ -262,6 +259,7 @@ void LayoutTheme::AdjustStyle(ComputedStyle& style, Element* e) {
ControlPart part = AdjustAppearanceWithAuthorStyle(
AdjustAppearanceWithElementType(style, e), style);
style.SetEffectiveAppearance(part);
+ DCHECK_NE(part, kAutoPart);
if (part == kNoControlPart)
return;
@@ -297,6 +295,19 @@ void LayoutTheme::AdjustStyle(ComputedStyle& style, Element* e) {
}
String LayoutTheme::ExtraDefaultStyleSheet() {
+ if (RuntimeEnabledFeatures::LayoutNGForControlsEnabled()) {
+ return String(R"CSS(
+input[type="file" i] {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: pre;
+}
+
+input[type="file" i]::-webkit-file-upload-button {
+ margin-inline-end: 4px;
+}
+)CSS");
+ }
return g_empty_string;
}
@@ -612,7 +623,12 @@ void LayoutTheme::AdjustButtonStyle(ComputedStyle& style) const {}
void LayoutTheme::AdjustInnerSpinButtonStyle(ComputedStyle&) const {}
-void LayoutTheme::AdjustMenuListStyle(ComputedStyle&, Element*) const {}
+void LayoutTheme::AdjustMenuListStyle(ComputedStyle& style, Element*) const {
+ // Menulists should have visible overflow
+ // https://bugs.webkit.org/show_bug.cgi?id=21287
+ style.SetOverflowX(EOverflow::kVisible);
+ style.SetOverflowY(EOverflow::kVisible);
+}
base::TimeDelta LayoutTheme::AnimationRepeatIntervalForProgressBar() const {
return base::TimeDelta();
@@ -634,11 +650,15 @@ void LayoutTheme::AdjustSliderContainerStyle(ComputedStyle& style,
if (e && (e->ShadowPseudoId() == "-webkit-media-slider-container" ||
e->ShadowPseudoId() == "-webkit-slider-container")) {
if (style.EffectiveAppearance() == kSliderVerticalPart) {
- style.SetTouchAction(TouchAction::kTouchActionPanX);
+ style.SetTouchAction(TouchAction::kPanX);
style.SetEffectiveAppearance(kNoControlPart);
+ style.SetWritingMode(WritingMode::kVerticalRl);
+ // It's always in RTL because the slider value increases up even in LTR.
+ style.SetDirection(TextDirection::kRtl);
} else {
- style.SetTouchAction(TouchAction::kTouchActionPanY);
+ style.SetTouchAction(TouchAction::kPanY);
style.SetEffectiveAppearance(kNoControlPart);
+ style.SetWritingMode(WritingMode::kHorizontalTb);
}
}
}
@@ -749,7 +769,7 @@ Color LayoutTheme::SystemColor(CSSValueID css_value_id,
case CSSValueID::kButtonshadow:
return 0xFF888888;
case CSSValueID::kButtontext:
- return color_scheme == WebColorScheme::kDark ? 0xFFFFFFFF : 0xFF000000;
+ return color_scheme == WebColorScheme::kDark ? 0xFFAAAAAA : 0xFF000000;
case CSSValueID::kCaptiontext:
return color_scheme == WebColorScheme::kDark ? 0xFFFFFFFF : 0xFF000000;
case CSSValueID::kField:
@@ -855,27 +875,16 @@ Color LayoutTheme::FocusRingColor() const {
: GetTheme().PlatformFocusRingColor();
}
-String LayoutTheme::FileListNameForWidth(Locale& locale,
- const FileList* file_list,
- const Font& font,
- int width) const {
- if (width <= 0)
- return String();
-
- String string;
- if (file_list->IsEmpty()) {
- string = locale.QueryString(IDS_FORM_FILE_NO_FILE_LABEL);
- } else if (file_list->length() == 1) {
- string = file_list->item(0)->name();
- } else {
- return StringTruncator::RightTruncate(
- locale.QueryString(IDS_FORM_FILE_MULTIPLE_UPLOAD,
- locale.ConvertToLocalizedNumber(
- String::Number(file_list->length()))),
- width, font);
- }
+bool LayoutTheme::DelegatesMenuListRendering() const {
+ return delegates_menu_list_rendering_;
+}
+
+void LayoutTheme::SetDelegatesMenuListRenderingForTesting(bool flag) {
+ delegates_menu_list_rendering_ = flag;
+}
- return StringTruncator::CenterTruncate(string, width, font);
+String LayoutTheme::DisplayNameForFile(const File& file) const {
+ return file.name();
}
bool LayoutTheme::ShouldOpenPickerWithF4Key() const {
@@ -884,7 +893,7 @@ bool LayoutTheme::ShouldOpenPickerWithF4Key() const {
bool LayoutTheme::SupportsCalendarPicker(const AtomicString& type) const {
DCHECK(RuntimeEnabledFeatures::InputMultipleFieldsUIEnabled());
- if (RuntimeEnabledFeatures::FormControlsRefreshEnabled() &&
+ if (features::IsFormControlsRefreshEnabled() &&
type == input_type_names::kTime)
return true;
@@ -993,12 +1002,6 @@ void LayoutTheme::AdjustRadioStyleUsingFallbackTheme(
style.ResetBorder();
}
-Color LayoutTheme::RootElementColor(WebColorScheme color_scheme) const {
- if (color_scheme == WebColorScheme::kDark)
- return Color::kWhite;
- return ComputedStyleInitialValues::InitialColor();
-}
-
LengthBox LayoutTheme::ControlPadding(ControlPart part,
const FontDescription&,
const Length& zoomed_box_top,
@@ -1053,4 +1056,12 @@ void LayoutTheme::AdjustControlPartStyle(ComputedStyle& style) {
}
}
+bool LayoutTheme::HasCustomFocusRingColor() const {
+ return has_custom_focus_ring_color_;
+}
+
+Color LayoutTheme::GetCustomFocusRingColor() const {
+ return custom_focus_ring_color_;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_theme.h b/chromium/third_party/blink/renderer/core/layout/layout_theme.h
index 0c92b958f8f..9ffb65caaab 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_theme.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_theme.h
@@ -29,6 +29,7 @@
#include "third_party/blink/renderer/core/scroll/scroll_types.h"
#include "third_party/blink/renderer/platform/fonts/font_description.h"
#include "third_party/blink/renderer/platform/fonts/font_selection_types.h"
+#include "third_party/blink/renderer/platform/geometry/int_rect.h"
#include "third_party/blink/renderer/platform/geometry/layout_unit.h"
#include "third_party/blink/renderer/platform/geometry/length_box.h"
#include "third_party/blink/renderer/platform/geometry/length_size.h"
@@ -42,12 +43,11 @@ namespace blink {
class ComputedStyle;
class Element;
-class FileList;
-class Font;
+class File;
class FontDescription;
class HTMLInputElement;
+class IntRect;
class LengthSize;
-class Locale;
class LocalFrame;
class Node;
class ThemePainter;
@@ -170,22 +170,18 @@ class CORE_EXPORT LayoutTheme : public RefCounted<LayoutTheme> {
WebColorScheme color_scheme) const;
virtual bool IsFocusRingOutset() const;
- Color FocusRingColor() const;
+ virtual Color FocusRingColor() const;
virtual Color PlatformFocusRingColor() const { return Color(0, 0, 0); }
void SetCustomFocusRingColor(const Color&);
static Color TapHighlightColor();
- // Root element text color. It can be different from the initial color in
- // other color schemes than the light theme.
- Color RootElementColor(WebColorScheme) const;
-
virtual Color PlatformTapHighlightColor() const {
return LayoutTheme::kDefaultTapHighlightColor;
}
virtual Color PlatformDefaultCompositionBackgroundColor() const {
return kDefaultCompositionBackgroundColor;
}
- virtual void PlatformColorsDidChange();
+ void PlatformColorsDidChange();
virtual void ColorSchemeDidChange();
void SetCaretBlinkInterval(base::TimeDelta);
@@ -236,16 +232,16 @@ class CORE_EXPORT LayoutTheme : public RefCounted<LayoutTheme> {
virtual bool ShouldHaveSpinButton(HTMLInputElement*) const;
// Functions for <select> elements.
- virtual bool DelegatesMenuListRendering() const { return false; }
+ virtual bool DelegatesMenuListRendering() const;
+ // This function has no effect for LayoutThemeAndroid, of which
+ // DelegatesMenuListRendering() always returns true.
+ void SetDelegatesMenuListRenderingForTesting(bool flag);
virtual bool PopsMenuByArrowKeys() const { return false; }
virtual bool PopsMenuBySpaceKey() const { return false; }
virtual bool PopsMenuByReturnKey() const { return false; }
virtual bool PopsMenuByAltDownUpOrF4Key() const { return false; }
- virtual String FileListNameForWidth(Locale&,
- const FileList*,
- const Font&,
- int width) const;
+ virtual String DisplayNameForFile(const File& file) const;
virtual bool ShouldOpenPickerWithF4Key() const;
@@ -356,6 +352,10 @@ class CORE_EXPORT LayoutTheme : public RefCounted<LayoutTheme> {
static bool IsSpinUpButtonPartHovered(const Node*);
static bool IsReadOnlyControl(const Node*);
+ protected:
+ bool HasCustomFocusRingColor() const;
+ Color GetCustomFocusRingColor() const;
+
private:
// This function is to be implemented in your platform-specific theme
// implementation to hand back the appropriate platform theme.
@@ -372,6 +372,8 @@ class CORE_EXPORT LayoutTheme : public RefCounted<LayoutTheme> {
base::TimeDelta caret_blink_interval_ =
base::TimeDelta::FromMilliseconds(500);
+ bool delegates_menu_list_rendering_ = false;
+
// This color is expected to be drawn on a semi-transparent overlay,
// making it more transparent than its alpha value indicates.
static const RGBA32 kDefaultTapHighlightColor = 0x66000000;
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_theme_default.cc b/chromium/third_party/blink/renderer/core/layout/layout_theme_default.cc
index 8c38b306a47..806f976d723 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_theme_default.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_theme_default.cc
@@ -36,6 +36,7 @@
#include "third_party/blink/renderer/platform/data_resource_helper.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
+#include "ui/base/ui_base_features.h"
namespace blink {
@@ -45,10 +46,16 @@ static const float kDefaultCancelButtonSize = 9;
static const float kMinCancelButtonSize = 5;
static const float kMaxCancelButtonSize = 21;
-LayoutThemeDefault::LayoutThemeDefault()
- : LayoutTheme(),
- caret_blink_interval_(LayoutTheme::CaretBlinkInterval()),
- painter_(*this) {}
+base::TimeDelta LayoutThemeDefault::caret_blink_interval_;
+
+Color LayoutThemeDefault::active_selection_background_color_ = 0xff1e90ff;
+Color LayoutThemeDefault::active_selection_foreground_color_ = Color::kBlack;
+Color LayoutThemeDefault::inactive_selection_background_color_ = 0xffc8c8c8;
+Color LayoutThemeDefault::inactive_selection_foreground_color_ = 0xff323232;
+
+LayoutThemeDefault::LayoutThemeDefault() : LayoutTheme(), painter_(*this) {
+ caret_blink_interval_ = LayoutTheme::CaretBlinkInterval();
+}
LayoutThemeDefault::~LayoutThemeDefault() = default;
@@ -94,7 +101,7 @@ String LayoutThemeDefault::ExtraDefaultStyleSheet() {
String windows_style_sheet =
UncompressResourceAsASCIIString(IDR_UASTYLE_THEME_WIN_CSS);
String controls_refresh_style_sheet =
- RuntimeEnabledFeatures::FormControlsRefreshEnabled()
+ features::IsFormControlsRefreshEnabled()
? UncompressResourceAsASCIIString(
IDR_UASTYLE_THEME_CONTROLS_REFRESH_CSS)
: String();
@@ -154,14 +161,14 @@ Color LayoutThemeDefault::PlatformInactiveSelectionForegroundColor(
}
IntSize LayoutThemeDefault::SliderTickSize() const {
- if (RuntimeEnabledFeatures::FormControlsRefreshEnabled())
+ if (features::IsFormControlsRefreshEnabled())
return IntSize(1, 4);
else
return IntSize(1, 6);
}
int LayoutThemeDefault::SliderTickOffsetFromTrackCenter() const {
- if (RuntimeEnabledFeatures::FormControlsRefreshEnabled())
+ if (features::IsFormControlsRefreshEnabled())
return 7;
else
return -16;
@@ -294,7 +301,8 @@ void LayoutThemeDefault::AdjustSearchFieldCancelButtonStyle(
}
void LayoutThemeDefault::AdjustMenuListStyle(ComputedStyle& style,
- Element*) const {
+ Element* element) const {
+ LayoutTheme::AdjustMenuListStyle(style, element);
// Height is locked to auto on all browsers.
style.SetLineHeight(ComputedStyleInitialValues::InitialLineHeight());
}
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_theme_default.h b/chromium/third_party/blink/renderer/core/layout/layout_theme_default.h
index 397383f420e..50588077553 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_theme_default.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_theme_default.h
@@ -150,12 +150,13 @@ class CORE_EXPORT LayoutThemeDefault : public LayoutTheme {
int MenuListInternalPadding(const ComputedStyle&, int padding) const;
static const RGBA32 kDefaultTapHighlightColor = 0x2e000000; // 18% black.
- base::TimeDelta caret_blink_interval_;
- Color active_selection_background_color_ = 0xff1e90ff;
- Color active_selection_foreground_color_ = Color::kBlack;
- Color inactive_selection_background_color_ = 0xffc8c8c8;
- Color inactive_selection_foreground_color_ = 0xff323232;
+ static base::TimeDelta caret_blink_interval_;
+
+ static Color active_selection_background_color_;
+ static Color active_selection_foreground_color_;
+ static Color inactive_selection_background_color_;
+ static Color inactive_selection_foreground_color_;
ThemePainterDefault painter_;
// Cached values for crbug.com/673754.
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_theme_mac.h b/chromium/third_party/blink/renderer/core/layout/layout_theme_mac.h
index ae22fe65b67..43219d5853f 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_theme_mac.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_theme_mac.h
@@ -29,7 +29,6 @@
#include "base/mac/scoped_nsobject.h"
#import "third_party/blink/renderer/core/layout/layout_theme.h"
#import "third_party/blink/renderer/core/paint/theme_painter_mac.h"
-#import "third_party/blink/renderer/platform/wtf/hash_map.h"
@class BlinkLayoutThemeNotificationObserver;
@@ -67,8 +66,6 @@ class LayoutThemeMac final : public LayoutTheme {
return part == kListboxPart ? kSmallScrollbar : kRegularScrollbar;
}
- void PlatformColorsDidChange() override;
-
// System fonts.
void SystemFont(CSSValueID system_font_id,
FontSelectionValue& font_slope,
@@ -276,10 +273,7 @@ class LayoutThemeMac final : public LayoutTheme {
private:
const int* ProgressBarHeights() const;
const int* ProgressBarMargins(NSControlSize) const;
- String FileListNameForWidth(Locale&,
- const FileList*,
- const Font&,
- int width) const override;
+ String DisplayNameForFile(const File& file) const override;
String ExtraDefaultStyleSheet() override;
bool ThemeDrawsFocusRing(const ComputedStyle&) const override;
@@ -289,8 +283,6 @@ class LayoutThemeMac final : public LayoutTheme {
mutable base::scoped_nsobject<NSSearchFieldCell> search_;
mutable base::scoped_nsobject<NSTextFieldCell> text_field_;
- mutable HashMap<CSSValueID, RGBA32> system_color_cache_;
-
base::scoped_nsobject<BlinkLayoutThemeNotificationObserver>
notification_observer_;
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_theme_mac.mm b/chromium/third_party/blink/renderer/core/layout/layout_theme_mac.mm
index 09eb072a39f..f9912f0c745 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_theme_mac.mm
+++ b/chromium/third_party/blink/renderer/core/layout/layout_theme_mac.mm
@@ -31,21 +31,21 @@
#import "third_party/blink/public/resources/grit/blink_resources.h"
#import "third_party/blink/public/strings/grit/blink_strings.h"
#import "third_party/blink/renderer/core/css_value_keywords.h"
-#import "third_party/blink/renderer/core/fileapi/file_list.h"
+#import "third_party/blink/renderer/core/fileapi/file.h"
#import "third_party/blink/renderer/core/html_names.h"
#import "third_party/blink/renderer/core/layout/layout_progress.h"
#import "third_party/blink/renderer/core/layout/layout_theme_default.h"
#import "third_party/blink/renderer/core/layout/layout_view.h"
#import "third_party/blink/renderer/core/style/shadow_list.h"
#import "third_party/blink/renderer/platform/data_resource_helper.h"
-#import "third_party/blink/renderer/platform/fonts/string_truncator.h"
#import "third_party/blink/renderer/platform/graphics/bitmap_image.h"
#import "third_party/blink/renderer/platform/mac/block_exceptions.h"
#import "third_party/blink/renderer/platform/mac/color_mac.h"
#import "third_party/blink/renderer/platform/mac/web_core_ns_cell_extras.h"
#import "third_party/blink/renderer/platform/runtime_enabled_features.h"
-#import "third_party/blink/renderer/platform/text/platform_locale.h"
#import "third_party/blink/renderer/platform/web_test_support.h"
+#include "ui/base/ui_base_features.h"
+#include "ui/native_theme/native_theme.h"
// This is a view whose sole purpose is to tell AppKit that it's flipped.
@interface BlinkFlippedControl : NSControl
@@ -146,6 +146,27 @@ class LayoutThemeMacRefresh final : public LayoutThemeDefault {
static scoped_refptr<LayoutTheme> Create() {
return base::AdoptRef(new LayoutThemeMacRefresh());
}
+
+ Color PlatformActiveSelectionBackgroundColor(
+ WebColorScheme color_scheme) const override;
+ Color PlatformInactiveSelectionBackgroundColor(
+ WebColorScheme color_scheme) const override;
+ Color PlatformActiveSelectionForegroundColor(
+ WebColorScheme color_scheme) const override;
+ Color PlatformSpellingMarkerUnderlineColor() const override;
+ Color PlatformGrammarMarkerUnderlineColor() const override;
+ Color FocusRingColor() const override;
+ String DisplayNameForFile(const File& file) const override {
+ if (file.GetUserVisibility() == File::kIsUserVisible)
+ return [[NSFileManager defaultManager] displayNameAtPath:file.GetPath()];
+ return file.name();
+ }
+ bool PopsMenuByArrowKeys() const override;
+
+ protected:
+ // Controls color values returned from FocusRingColor().
+ bool UsesTestModeFocusRingColor() const;
+ bool IsAccentColorCustomized(WebColorScheme color_scheme) const;
};
// Inflate an IntRect to account for specific padding around margins.
@@ -162,13 +183,13 @@ bool FontSizeMatchesToControlSize(const ComputedStyle& style) {
return false;
}
-Color GetSystemColor(MacSystemColorID color_id) {
+Color GetSystemColor(MacSystemColorID color_id, WebColorScheme color_scheme) {
// In tests, a WebSandboxSupport may not be set up. Just return a dummy
// color, in this case, black.
auto* sandbox_support = Platform::Current()->GetSandboxSupport();
if (!sandbox_support)
return Color();
- return sandbox_support->GetSystemColor(color_id);
+ return sandbox_support->GetSystemColor(color_id, color_scheme);
}
// Helper functions used by a bunch of different control parts.
@@ -225,12 +246,14 @@ LayoutThemeMac::~LayoutThemeMac() {
Color LayoutThemeMac::PlatformActiveSelectionBackgroundColor(
WebColorScheme color_scheme) const {
- return GetSystemColor(MacSystemColorID::kSelectedTextBackground);
+ return GetSystemColor(MacSystemColorID::kSelectedTextBackground,
+ color_scheme);
}
Color LayoutThemeMac::PlatformInactiveSelectionBackgroundColor(
WebColorScheme color_scheme) const {
- return GetSystemColor(MacSystemColorID::kSecondarySelectedControl);
+ return GetSystemColor(MacSystemColorID::kSecondarySelectedControl,
+ color_scheme);
}
Color LayoutThemeMac::PlatformActiveSelectionForegroundColor(
@@ -240,7 +263,8 @@ Color LayoutThemeMac::PlatformActiveSelectionForegroundColor(
Color LayoutThemeMac::PlatformActiveListBoxSelectionBackgroundColor(
WebColorScheme color_scheme) const {
- return GetSystemColor(MacSystemColorID::kAlternateSelectedControl);
+ return GetSystemColor(MacSystemColorID::kAlternateSelectedControl,
+ color_scheme);
}
Color LayoutThemeMac::PlatformActiveListBoxSelectionForegroundColor(
@@ -276,6 +300,88 @@ Color LayoutThemeMac::PlatformInactiveListBoxSelectionBackgroundColor(
return PlatformInactiveSelectionBackgroundColor(color_scheme);
}
+Color LayoutThemeMacRefresh::PlatformActiveSelectionBackgroundColor(
+ WebColorScheme color_scheme) const {
+ return GetSystemColor(MacSystemColorID::kSelectedTextBackground,
+ color_scheme);
+}
+
+Color LayoutThemeMacRefresh::PlatformInactiveSelectionBackgroundColor(
+ WebColorScheme color_scheme) const {
+ return GetSystemColor(MacSystemColorID::kSecondarySelectedControl,
+ color_scheme);
+}
+
+Color LayoutThemeMacRefresh::PlatformActiveSelectionForegroundColor(
+ WebColorScheme color_scheme) const {
+ return Color::kBlack;
+}
+
+Color LayoutThemeMacRefresh::PlatformSpellingMarkerUnderlineColor() const {
+ return Color(251, 45, 29);
+}
+
+Color LayoutThemeMacRefresh::PlatformGrammarMarkerUnderlineColor() const {
+ return Color(107, 107, 107);
+}
+
+bool LayoutThemeMacRefresh::IsAccentColorCustomized(
+ WebColorScheme color_scheme) const {
+ if (@available(macOS 10.14, *)) {
+ static const Color kControlBlueAccentColor =
+ GetSystemColor(MacSystemColorID::kControlAccentBlueColor, color_scheme);
+ if (kControlBlueAccentColor ==
+ GetSystemColor(MacSystemColorID::kControlAccentColor, color_scheme)) {
+ return false;
+ }
+ } else {
+ if (NSBlueControlTint == [[NSUserDefaults standardUserDefaults]
+ integerForKey:@"AppleAquaColorVariant"]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+Color LayoutThemeMacRefresh::FocusRingColor() const {
+ static const RGBA32 kDefaultFocusRingColor = 0xFF101010;
+ if (UsesTestModeFocusRingColor()) {
+ return HasCustomFocusRingColor() ? GetCustomFocusRingColor()
+ : kDefaultFocusRingColor;
+ }
+
+ if (ui::NativeTheme::GetInstanceForWeb()->UsesHighContrastColors()) {
+ // When high contrast is enabled, #101010 should be used.
+ return Color(0xFF101010);
+ }
+
+ // TODO(crbug.com/929098) Need to pass an appropriate color scheme here.
+ WebColorScheme color_scheme = ComputedStyle::InitialStyle().UsedColorScheme();
+
+ Color keyboard_focus_indicator =
+ GetSystemColor(MacSystemColorID::kKeyboardFocusIndicator, color_scheme);
+ // Take the RGB values from the keyboard_focus_indicator color, but use a
+ // different alpha value to avoid having a color too light.
+ Color focus_ring =
+ Color(keyboard_focus_indicator.Red(), keyboard_focus_indicator.Green(),
+ keyboard_focus_indicator.Blue(), /*alpha=*/166);
+ if (!HasCustomFocusRingColor())
+ return focus_ring;
+ // Use the custom focus ring color when the system accent color wasn't
+ // changed.
+ if (!IsAccentColorCustomized(color_scheme))
+ return GetCustomFocusRingColor();
+ return focus_ring;
+}
+
+bool LayoutThemeMacRefresh::UsesTestModeFocusRingColor() const {
+ return WebTestSupport::IsRunningWebTest();
+}
+
+bool LayoutThemeMacRefresh::PopsMenuByArrowKeys() const {
+ return true;
+}
+
static FontSelectionValue ToFontWeight(NSInteger app_kit_font_weight) {
DCHECK_GT(app_kit_font_weight, 0);
DCHECK_LT(app_kit_font_weight, 15);
@@ -334,138 +440,96 @@ void LayoutThemeMac::SystemFont(CSSValueID system_font_id,
font_family = font_family_names::kSystemUi;
}
-void LayoutThemeMac::PlatformColorsDidChange() {
- system_color_cache_.clear();
- LayoutTheme::PlatformColorsDidChange();
-}
-
Color LayoutThemeMac::SystemColor(CSSValueID css_value_id,
WebColorScheme color_scheme) const {
- {
- HashMap<CSSValueID, RGBA32>::iterator it =
- system_color_cache_.find(css_value_id);
- if (it != system_color_cache_.end())
- return it->value;
- }
+ if (!Platform::Current()->GetSandboxSupport())
+ return LayoutTheme::SystemColor(css_value_id, color_scheme);
- Color color;
- bool needs_fallback = false;
switch (css_value_id) {
case CSSValueID::kActiveborder:
- color = GetSystemColor(MacSystemColorID::kKeyboardFocusIndicator);
- break;
+ return GetSystemColor(MacSystemColorID::kKeyboardFocusIndicator,
+ color_scheme);
case CSSValueID::kActivecaption:
- color = GetSystemColor(MacSystemColorID::kWindowFrameText);
- break;
+ return GetSystemColor(MacSystemColorID::kWindowFrameText, color_scheme);
case CSSValueID::kAppworkspace:
- color = GetSystemColor(MacSystemColorID::kHeader);
- break;
+ return GetSystemColor(MacSystemColorID::kHeader, color_scheme);
case CSSValueID::kBackground:
- // Use theme independent default
- needs_fallback = true;
+ // Use theme independent default.
break;
case CSSValueID::kButtonface:
- color = GetSystemColor(MacSystemColorID::kControlBackground);
- break;
+ return GetSystemColor(MacSystemColorID::kControlBackground, color_scheme);
case CSSValueID::kButtonhighlight:
- color = GetSystemColor(MacSystemColorID::kControlHighlight);
- break;
+ return GetSystemColor(MacSystemColorID::kControlHighlight, color_scheme);
case CSSValueID::kButtonshadow:
- color = GetSystemColor(MacSystemColorID::kControlShadow);
- break;
+ return GetSystemColor(MacSystemColorID::kControlShadow, color_scheme);
case CSSValueID::kButtontext:
- color = GetSystemColor(MacSystemColorID::kControlText);
- break;
+ return GetSystemColor(MacSystemColorID::kControlText, color_scheme);
case CSSValueID::kCaptiontext:
- color = GetSystemColor(MacSystemColorID::kText);
- break;
+ return GetSystemColor(MacSystemColorID::kText, color_scheme);
case CSSValueID::kField:
- color = GetSystemColor(MacSystemColorID::kControlBackground);
- break;
+ return GetSystemColor(MacSystemColorID::kControlBackground, color_scheme);
case CSSValueID::kFieldtext:
- color = GetSystemColor(MacSystemColorID::kText);
- break;
+ return GetSystemColor(MacSystemColorID::kText, color_scheme);
case CSSValueID::kGraytext:
- color = GetSystemColor(MacSystemColorID::kDisabledControlText);
- break;
+ return GetSystemColor(MacSystemColorID::kDisabledControlText,
+ color_scheme);
case CSSValueID::kHighlight:
- color = GetSystemColor(MacSystemColorID::kSelectedTextBackground);
- break;
+ return GetSystemColor(MacSystemColorID::kSelectedTextBackground,
+ color_scheme);
case CSSValueID::kHighlighttext:
- color = GetSystemColor(MacSystemColorID::kSelectedText);
- break;
+ return GetSystemColor(MacSystemColorID::kSelectedText, color_scheme);
case CSSValueID::kInactiveborder:
- color = GetSystemColor(MacSystemColorID::kControlBackground);
- break;
+ return GetSystemColor(MacSystemColorID::kControlBackground, color_scheme);
case CSSValueID::kInactivecaption:
- color = GetSystemColor(MacSystemColorID::kControlBackground);
- break;
+ return GetSystemColor(MacSystemColorID::kControlBackground, color_scheme);
case CSSValueID::kInactivecaptiontext:
- color = GetSystemColor(MacSystemColorID::kText);
- break;
+ return GetSystemColor(MacSystemColorID::kText, color_scheme);
case CSSValueID::kInfobackground:
// There is no corresponding NSColor for this so we use a hard coded
// value.
- color = 0xFFFBFCC5;
- break;
+ return 0xFFFBFCC5;
case CSSValueID::kInfotext:
- color = GetSystemColor(MacSystemColorID::kText);
- break;
+ return GetSystemColor(MacSystemColorID::kText, color_scheme);
case CSSValueID::kMenu:
- color = GetSystemColor(MacSystemColorID::kMenuBackground);
- break;
+ return GetSystemColor(MacSystemColorID::kMenuBackground, color_scheme);
case CSSValueID::kMenutext:
- color = GetSystemColor(MacSystemColorID::kSelectedMenuItemText);
- break;
+ return GetSystemColor(MacSystemColorID::kSelectedMenuItemText,
+ color_scheme);
case CSSValueID::kScrollbar:
- color = GetSystemColor(MacSystemColorID::kScrollBar);
- break;
+ return GetSystemColor(MacSystemColorID::kScrollBar, color_scheme);
case CSSValueID::kText:
- color = GetSystemColor(MacSystemColorID::kText);
- break;
+ return GetSystemColor(MacSystemColorID::kText, color_scheme);
case CSSValueID::kThreeddarkshadow:
- color = GetSystemColor(MacSystemColorID::kControlDarkShadow);
- break;
+ return GetSystemColor(MacSystemColorID::kControlDarkShadow, color_scheme);
case CSSValueID::kThreedshadow:
- color = GetSystemColor(MacSystemColorID::kShadow);
- break;
+ return GetSystemColor(MacSystemColorID::kShadow, color_scheme);
case CSSValueID::kThreedface:
// We use this value instead of NSColor's controlColor to avoid website
// incompatibilities. We may want to change this to use the NSColor in
// future.
- color = 0xFFC0C0C0;
- break;
+ return 0xFFC0C0C0;
case CSSValueID::kThreedhighlight:
- color = GetSystemColor(MacSystemColorID::kHighlight);
- break;
+ return GetSystemColor(MacSystemColorID::kHighlight, color_scheme);
case CSSValueID::kThreedlightshadow:
- color = GetSystemColor(MacSystemColorID::kControlLightHighlight);
- break;
+ return GetSystemColor(MacSystemColorID::kControlLightHighlight,
+ color_scheme);
case CSSValueID::kWebkitFocusRingColor:
- color = GetSystemColor(MacSystemColorID::kKeyboardFocusIndicator);
- break;
+ return GetSystemColor(MacSystemColorID::kKeyboardFocusIndicator,
+ color_scheme);
case CSSValueID::kWindow:
case CSSValueID::kCanvas:
- color = GetSystemColor(MacSystemColorID::kWindowBackground);
- break;
+ return GetSystemColor(MacSystemColorID::kWindowBackground, color_scheme);
case CSSValueID::kWindowframe:
- color = GetSystemColor(MacSystemColorID::kWindowFrame);
- break;
+ return GetSystemColor(MacSystemColorID::kWindowFrame, color_scheme);
case CSSValueID::kWindowtext:
+ return GetSystemColor(MacSystemColorID::kWindowFrameText, color_scheme);
case CSSValueID::kCanvastext:
- color = GetSystemColor(MacSystemColorID::kWindowFrameText);
- break;
+ return GetSystemColor(MacSystemColorID::kText, color_scheme);
default:
- needs_fallback = true;
break;
}
- if (needs_fallback)
- color = LayoutTheme::SystemColor(css_value_id, color_scheme);
-
- system_color_cache_.Set(css_value_id, color.Rgb());
-
- return color;
+ return LayoutTheme::SystemColor(css_value_id, color_scheme);
}
bool LayoutThemeMac::IsControlStyled(ControlPart part,
@@ -656,10 +720,7 @@ void LayoutThemeMac::SetFontFromControlSize(ComputedStyle& style,
// Reset line height.
style.SetLineHeight(ComputedStyleInitialValues::InitialLineHeight());
- // TODO(esprehn): The fontSelector manual management is buggy and error prone.
- FontSelector* font_selector = style.GetFont().GetFontSelector();
- if (style.SetFontDescription(font_description))
- style.GetFont().Update(font_selector);
+ style.SetFontDescription(font_description);
}
NSControlSize LayoutThemeMac::ControlSizeForSystemFont(
@@ -715,6 +776,7 @@ static const IntSize* MenuListButtonSizes() {
void LayoutThemeMac::AdjustMenuListStyle(ComputedStyle& style,
Element* e) const {
+ LayoutTheme::AdjustMenuListStyle(style, e);
NSControlSize control_size = ControlSizeForFont(style);
style.ResetBorder();
@@ -1003,32 +1065,10 @@ NSTextFieldCell* LayoutThemeMac::TextField() const {
return text_field_;
}
-String LayoutThemeMac::FileListNameForWidth(Locale& locale,
- const FileList* file_list,
- const Font& font,
- int width) const {
- if (width <= 0)
- return String();
-
- String str_to_truncate;
- if (file_list->IsEmpty()) {
- str_to_truncate = locale.QueryString(IDS_FORM_FILE_NO_FILE_LABEL);
- } else if (file_list->length() == 1) {
- File* file = file_list->item(0);
- if (file->GetUserVisibility() == File::kIsUserVisible)
- str_to_truncate = [[NSFileManager defaultManager]
- displayNameAtPath:(file_list->item(0)->GetPath())];
- else
- str_to_truncate = file->name();
- } else {
- return StringTruncator::RightTruncate(
- locale.QueryString(IDS_FORM_FILE_MULTIPLE_UPLOAD,
- locale.ConvertToLocalizedNumber(
- String::Number(file_list->length()))),
- width, font);
- }
-
- return StringTruncator::CenterTruncate(str_to_truncate, width, font);
+String LayoutThemeMac::DisplayNameForFile(const File& file) const {
+ if (file.GetUserVisibility() == File::kIsUserVisible)
+ return [[NSFileManager defaultManager] displayNameAtPath:file.GetPath()];
+ return file.name();
}
NSView* FlippedView() {
@@ -1037,7 +1077,7 @@ NSView* FlippedView() {
}
LayoutTheme& LayoutTheme::NativeTheme() {
- if (RuntimeEnabledFeatures::FormControlsRefreshEnabled()) {
+ if (features::IsFormControlsRefreshEnabled()) {
DEFINE_STATIC_REF(LayoutTheme, layout_theme,
(LayoutThemeMacRefresh::Create()));
return *layout_theme;
@@ -1052,7 +1092,8 @@ scoped_refptr<LayoutTheme> LayoutThemeMac::Create() {
}
bool LayoutThemeMac::UsesTestModeFocusRingColor() const {
- return WebTestSupport::IsRunningWebTest();
+ return WebTestSupport::IsRunningWebTest() ||
+ !Platform::Current()->GetSandboxSupport();
}
NSView* LayoutThemeMac::DocumentView() const {
@@ -1475,8 +1516,7 @@ void LayoutThemeMac::AdjustControlPartStyle(ComputedStyle& style) {
style.SetLineHeight(ComputedStyleInitialValues::InitialLineHeight());
// Now update our font.
- if (style.SetFontDescription(control_font))
- style.GetFont().Update(nullptr);
+ style.SetFontDescription(control_font);
}
break;
}
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 ef113db19ff..7461a3457ca 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
@@ -24,15 +24,17 @@
namespace blink {
class LayoutThemeTest : public PageTestBase,
- private ScopedCSSColorSchemeForTest {
+ private ScopedCSSColorSchemeForTest,
+ private ScopedCSSColorSchemeUARenderingForTest {
protected:
- LayoutThemeTest() : ScopedCSSColorSchemeForTest(true) {}
+ LayoutThemeTest()
+ : ScopedCSSColorSchemeForTest(true),
+ ScopedCSSColorSchemeUARenderingForTest(true) {}
void SetHtmlInnerHTML(const char* html_content);
};
void LayoutThemeTest::SetHtmlInnerHTML(const char* html_content) {
- GetDocument().documentElement()->SetInnerHTMLFromString(
- String::FromUTF8(html_content));
+ GetDocument().documentElement()->setInnerHTML(String::FromUTF8(html_content));
UpdateAllLifecyclePhasesForTest();
}
@@ -78,57 +80,8 @@ TEST_F(LayoutThemeTest, ChangeFocusRingColor) {
EXPECT_EQ(custom_color, OutlineColor(span));
}
-TEST_F(LayoutThemeTest, RootElementColor) {
- EXPECT_EQ(Color::kBlack,
- LayoutTheme::GetTheme().RootElementColor(WebColorScheme::kLight));
- EXPECT_EQ(Color::kWhite,
- LayoutTheme::GetTheme().RootElementColor(WebColorScheme::kDark));
-}
-
-TEST_F(LayoutThemeTest, RootElementColorChange) {
- SetHtmlInnerHTML(R"HTML(
- <style>
- :root { color-scheme: light dark }
- #initial { color: initial }
- </style>
- <div id="initial"></div>
- )HTML");
-
- Element* initial = GetDocument().getElementById("initial");
- ASSERT_TRUE(initial);
- ASSERT_TRUE(GetDocument().documentElement());
- const ComputedStyle* document_element_style =
- GetDocument().documentElement()->GetComputedStyle();
- ASSERT_TRUE(document_element_style);
- EXPECT_EQ(Color::kBlack, document_element_style->VisitedDependentColor(
- GetCSSPropertyColor()));
-
- const ComputedStyle* initial_style = initial->GetComputedStyle();
- ASSERT_TRUE(initial_style);
- EXPECT_EQ(Color::kBlack,
- initial_style->VisitedDependentColor(GetCSSPropertyColor()));
-
- // Change color scheme to dark.
- ColorSchemeHelper color_scheme_helper;
- color_scheme_helper.SetPreferredColorScheme(GetDocument(),
- PreferredColorScheme::kDark);
- UpdateAllLifecyclePhasesForTest();
-
- document_element_style = GetDocument().documentElement()->GetComputedStyle();
- ASSERT_TRUE(document_element_style);
- EXPECT_EQ(Color::kWhite, document_element_style->VisitedDependentColor(
- GetCSSPropertyColor()));
-
- initial_style = initial->GetComputedStyle();
- ASSERT_TRUE(initial_style);
- // Theming does not change the initial value for color, only the UA style for
- // the root element.
- EXPECT_EQ(Color::kBlack,
- initial_style->VisitedDependentColor(GetCSSPropertyColor()));
-}
-
-// The expectations are based on LayoutThemeDefault::SystemColor.
-// LayoutThemeMac doesn't use that code path.
+// The expectations in the tests below are relying on LayoutThemeDefault.
+// LayoutThemeMac doesn't inherit from that class.
#if !defined(OS_MACOSX)
TEST_F(LayoutThemeTest, SystemColorWithColorScheme) {
SetHtmlInnerHTML(R"HTML(
@@ -150,9 +103,8 @@ TEST_F(LayoutThemeTest, SystemColorWithColorScheme) {
style->VisitedDependentColor(GetCSSPropertyColor()));
// Change color scheme to dark.
- ColorSchemeHelper color_scheme_helper;
- color_scheme_helper.SetPreferredColorScheme(GetDocument(),
- PreferredColorScheme::kDark);
+ ColorSchemeHelper color_scheme_helper(GetDocument());
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kDark);
UpdateAllLifecyclePhasesForTest();
style = dark_element->GetComputedStyle();
@@ -160,6 +112,32 @@ TEST_F(LayoutThemeTest, SystemColorWithColorScheme) {
EXPECT_EQ(Color(0x44, 0x44, 0x44),
style->VisitedDependentColor(GetCSSPropertyColor()));
}
+
+TEST_F(LayoutThemeTest, SetSelectionColors) {
+ LayoutTheme::GetTheme().SetSelectionColors(Color::kBlack, Color::kBlack,
+ Color::kBlack, Color::kBlack);
+ EXPECT_EQ(Color::kBlack,
+ LayoutTheme::GetTheme().ActiveSelectionForegroundColor(
+ WebColorScheme::kLight));
+ {
+ // Enabling MobileLayoutTheme switches which instance is returned from
+ // LayoutTheme::GetTheme(). Devtools expect SetSelectionColors() to affect
+ // both LayoutTheme instances.
+ ScopedMobileLayoutThemeForTest scope(true);
+ EXPECT_EQ(Color::kBlack,
+ LayoutTheme::GetTheme().ActiveSelectionForegroundColor(
+ WebColorScheme::kLight));
+
+ LayoutTheme::GetTheme().SetSelectionColors(Color::kWhite, Color::kWhite,
+ Color::kWhite, Color::kWhite);
+ EXPECT_EQ(Color::kWhite,
+ LayoutTheme::GetTheme().ActiveSelectionForegroundColor(
+ WebColorScheme::kLight));
+ }
+ EXPECT_EQ(Color::kWhite,
+ LayoutTheme::GetTheme().ActiveSelectionForegroundColor(
+ WebColorScheme::kLight));
+}
#endif // !defined(OS_MACOSX)
} // namespace blink
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 47bdaee8cb0..28cc1cbd7c3 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
@@ -49,7 +49,7 @@
#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/layout_ng_list_item.h"
+#include "third_party/blink/renderer/core/layout/ng/list/list_marker.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"
@@ -487,8 +487,7 @@ static void WriteTextFragment(WTF::TextStream& ts,
const NGTextFragment fragment(paint_fragment->Style().GetWritingMode(),
*physical_text_fragment);
WriteTextFragment(ts, paint_fragment->GetLayoutObject(),
- PhysicalRect(paint_fragment->InlineOffsetToContainerBox(),
- paint_fragment->Size()),
+ paint_fragment->RectInContainerBlock(),
paint_fragment->Style(), physical_text_fragment->Text(),
fragment.InlineSize());
return;
@@ -499,8 +498,8 @@ static void WriteTextFragment(WTF::TextStream& ts,
item.Type() == NGFragmentItem::kGeneratedText);
const LayoutUnit inline_size =
item.IsHorizontal() ? item.Size().width : item.Size().height;
- WriteTextFragment(ts, item.GetLayoutObject(), item.Rect(), item.Style(),
- item.Text(cursor.Items()), inline_size);
+ WriteTextFragment(ts, item.GetLayoutObject(), item.RectInContainerBlock(),
+ item.Style(), item.Text(cursor.Items()), inline_size);
}
static void WritePaintProperties(WTF::TextStream& ts,
@@ -610,7 +609,8 @@ void Write(WTF::TextStream& ts,
FrameView* frame_view = ToLayoutEmbeddedContent(o).ChildFrameView();
if (auto* local_frame_view = DynamicTo<LocalFrameView>(frame_view)) {
if (auto* layout_view = local_frame_view->GetLayoutView()) {
- layout_view->GetDocument().UpdateStyleAndLayout();
+ layout_view->GetDocument().UpdateStyleAndLayout(
+ DocumentUpdateReason::kTest);
if (auto* layer = layout_view->Layer()) {
LayoutTreeAsText::WriteLayers(ts, layer, layer, indent + 1, behavior);
}
@@ -900,7 +900,8 @@ String ExternalRepresentation(LocalFrame* frame,
LayoutAsTextBehavior behavior,
const PaintLayer* marked_layer) {
if (!(behavior & kLayoutAsTextDontUpdateLayout)) {
- bool success = frame->View()->UpdateAllLifecyclePhasesExceptPaint();
+ bool success = frame->View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
DCHECK(success);
};
@@ -931,8 +932,9 @@ String ExternalRepresentation(LocalFrame* frame,
String ExternalRepresentation(Element* element, LayoutAsTextBehavior behavior) {
// Doesn't support printing mode.
DCHECK(!(behavior & kLayoutAsTextPrintingMode));
- if (!(behavior & kLayoutAsTextDontUpdateLayout))
- element->GetDocument().UpdateStyleAndLayout();
+ if (!(behavior & kLayoutAsTextDontUpdateLayout)) {
+ element->GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
+ }
LayoutObject* layout_object = element->GetLayoutObject();
if (!layout_object || !layout_object->IsBox())
@@ -958,11 +960,14 @@ static void WriteCounterValuesFromChildren(WTF::TextStream& stream,
}
String CounterValueForElement(Element* element) {
- element->GetDocument().UpdateStyleAndLayout();
+ element->GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
WTF::TextStream stream;
bool is_first_counter = true;
- // The counter layoutObjects should be children of :before or :after
- // pseudo-elements.
+ // The counter LayoutObjects should be children of ::marker, ::before or
+ // ::after pseudo-elements.
+ if (LayoutObject* marker =
+ element->PseudoElementLayoutObject(kPseudoIdMarker))
+ WriteCounterValuesFromChildren(stream, marker, is_first_counter);
if (LayoutObject* before =
element->PseudoElementLayoutObject(kPseudoIdBefore))
WriteCounterValuesFromChildren(stream, before, is_first_counter);
@@ -972,14 +977,16 @@ String CounterValueForElement(Element* element) {
}
String MarkerTextForListItem(Element* element) {
- element->GetDocument().UpdateStyleAndLayout();
+ element->GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
LayoutObject* layout_object = element->GetLayoutObject();
if (layout_object) {
if (layout_object->IsListItem())
return ToLayoutListItem(layout_object)->MarkerText();
- if (layout_object->IsLayoutNGListItem())
- return ToLayoutNGListItem(layout_object)->MarkerTextWithoutSuffix();
+ if (layout_object->IsLayoutNGListItem()) {
+ if (LayoutObject* marker = ToLayoutNGListItem(layout_object)->Marker())
+ return ListMarker::Get(marker)->MarkerTextWithoutSuffix(*marker);
+ }
}
return String();
}
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 5b910056fbe..5a71ef5b8ce 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_video.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_video.cc
@@ -28,7 +28,6 @@
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
-#include "third_party/blink/renderer/core/html/media/media_element_parser_helpers.h"
#include "third_party/blink/renderer/core/paint/video_painter.h"
namespace blink {
@@ -62,7 +61,7 @@ void LayoutVideo::UpdateIntrinsicSize(bool is_in_layout) {
return;
SetIntrinsicSize(size);
- SetPreferredLogicalWidthsDirty();
+ SetIntrinsicLogicalWidthsDirty();
if (!is_in_layout) {
SetNeedsLayoutAndFullPaintInvalidation(
layout_invalidation_reason::kSizeChanged);
@@ -73,9 +72,10 @@ LayoutSize LayoutVideo::CalculateIntrinsicSize() {
HTMLVideoElement* video = VideoElement();
DCHECK(video);
- if (RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled() &&
- !video->GetOverriddenIntrinsicSize().IsEmpty())
- return LayoutSize(video->GetOverriddenIntrinsicSize());
+ if (RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled()) {
+ if (video->IsDefaultIntrinsicSize())
+ return DefaultSize();
+ }
// Spec text from 4.8.6
//
@@ -91,7 +91,7 @@ LayoutSize LayoutVideo::CalculateIntrinsicSize() {
WebMediaPlayer* web_media_player = MediaElement()->GetWebMediaPlayer();
if (web_media_player &&
video->getReadyState() >= HTMLVideoElement::kHaveMetadata) {
- IntSize size = web_media_player->NaturalSize();
+ IntSize size(web_media_player->NaturalSize());
if (!size.IsEmpty())
return LayoutSize(size);
}
@@ -189,7 +189,7 @@ bool LayoutVideo::SupportsAcceleratedRendering() const {
}
CompositingReasons LayoutVideo::AdditionalCompositingReasons() const {
- HTMLMediaElement* element = ToHTMLMediaElement(GetNode());
+ auto* element = To<HTMLMediaElement>(GetNode());
if (element->IsFullscreen() && element->UsesOverlayFullscreenVideo())
return CompositingReason::kVideo;
@@ -199,13 +199,4 @@ CompositingReasons LayoutVideo::AdditionalCompositingReasons() const {
return CompositingReason::kNone;
}
-void LayoutVideo::UpdateAfterLayout() {
- LayoutBox::UpdateAfterLayout();
- // Report violation of unsized-media policy.
- if (auto* video_element = DynamicTo<HTMLVideoElement>(GetNode())) {
- media_element_parser_helpers::ReportUnsizedMediaViolation(
- this, video_element->IsDefaultIntrinsicSize());
- }
-}
-
} // namespace blink
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 66d2550ef51..ed6ce6aa006 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_video.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_video.h
@@ -27,6 +27,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_VIDEO_H_
#include "third_party/blink/renderer/core/layout/layout_media.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -50,8 +51,6 @@ class LayoutVideo final : public LayoutMedia {
void IntrinsicSizeChanged() override;
- void UpdateAfterLayout() override;
-
bool ComputeShouldClipOverflow() const final { return true; }
private:
@@ -77,6 +76,7 @@ class LayoutVideo final : public LayoutMedia {
LayoutUnit estimated_used_width = LayoutUnit()) const override;
LayoutUnit MinimumReplacedHeight() const override;
+ bool CanHaveAdditionalCompositingReasons() const override { return true; }
CompositingReasons AdditionalCompositingReasons() const override;
void UpdatePlayer(bool is_in_layout);
@@ -84,7 +84,10 @@ class LayoutVideo final : public LayoutMedia {
LayoutSize cached_image_size_;
};
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutVideo, IsVideo());
+template <>
+struct DowncastTraits<LayoutVideo> {
+ static bool AllowFrom(const LayoutObject& object) { return object.IsVideo(); }
+};
} // namespace blink
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 f1af97319ad..65ecfe44e87 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/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"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -34,6 +35,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/html_iframe_element.h"
+#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/layout/geometry/transform_state.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
@@ -96,22 +98,20 @@ LayoutView::LayoutView(Document* document)
: LayoutBlockFlow(document),
frame_view_(document->View()),
layout_state_(nullptr),
- // TODO(pdr): This should be null if CompositeAfterPaintEnabled() is true.
- compositor_(std::make_unique<PaintLayerCompositor>(*this)),
+ compositor_(RuntimeEnabledFeatures::CompositeAfterPaintEnabled()
+ ? nullptr
+ : std::make_unique<PaintLayerCompositor>(*this)),
layout_quote_head_(nullptr),
layout_counter_count_(0),
hit_test_count_(0),
hit_test_cache_hits_(0),
hit_test_cache_(MakeGarbageCollected<HitTestCache>()),
- autosize_h_scrollbar_mode_(ScrollbarMode::kAuto),
- autosize_v_scrollbar_mode_(ScrollbarMode::kAuto) {
+ autosize_h_scrollbar_mode_(mojom::blink::ScrollbarMode::kAuto),
+ autosize_v_scrollbar_mode_(mojom::blink::ScrollbarMode::kAuto) {
// init LayoutObject attributes
SetInline(false);
- min_preferred_logical_width_ = LayoutUnit();
- max_preferred_logical_width_ = LayoutUnit();
-
- SetPreferredLogicalWidthsDirty(kMarkOnlyThis);
+ SetIntrinsicLogicalWidthsDirty(kMarkOnlyThis);
SetPositionState(EPosition::kAbsolute); // to 0,0 :)
@@ -135,7 +135,8 @@ bool LayoutView::HitTest(const HitTestLocation& location,
// Note that if an iframe has its render pipeline throttled, it will not
// update layout here, and it will also not propagate the hit test into the
// iframe's inner document.
- if (!GetFrameView()->UpdateAllLifecyclePhasesExceptPaint())
+ if (!GetFrameView()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kHitTest))
return false;
HitTestLatencyRecorder hit_test_latency_recorder(
result.GetHitTestRequest().AllowsChildFrameContent());
@@ -240,7 +241,8 @@ bool LayoutView::CanHaveChildren() const {
// the PluginDocument's <embed> element to have an EmbeddedContentView, which
// it acquires during LocalFrameView::UpdatePlugins, which operates on the
// <embed> element's layout object (LayoutEmbeddedObject).
- if (GetDocument().IsPluginDocument() || GetDocument().IsForExternalHandler())
+ if (IsA<PluginDocument>(GetDocument()) ||
+ GetDocument().IsForExternalHandler())
return true;
return !owner->IsDisplayNone();
}
@@ -308,8 +310,7 @@ void LayoutView::UpdateLayout() {
SetPageLogicalHeight(LayoutUnit());
if (PageLogicalHeight() && ShouldUsePrintingLayout()) {
- min_preferred_logical_width_ = max_preferred_logical_width_ =
- LogicalWidth();
+ intrinsic_logical_widths_ = LogicalWidth();
if (!fragmentation_context_) {
fragmentation_context_ =
std::make_unique<ViewFragmentationContext>(*this);
@@ -528,7 +529,8 @@ bool LayoutView::MapToVisualRectInAncestorSpaceInternal(
if (!owner) {
PhysicalRect rect = PhysicalRect::EnclosingRect(
transform_state.LastPlanarQuad().BoundingBox());
- bool retval = GetFrameView()->MapToVisualRectInRemoteRootFrame(rect);
+ bool retval = GetFrameView()->MapToVisualRectInRemoteRootFrame(
+ rect, !(visual_rect_flags & kDontApplyMainFrameOverflowClip));
transform_state.SetQuad(FloatQuad(FloatRect(rect)));
return retval;
}
@@ -617,15 +619,17 @@ PhysicalRect LayoutView::OverflowClipRect(
return rect;
}
-void LayoutView::SetAutosizeScrollbarModes(ScrollbarMode h_mode,
- ScrollbarMode v_mode) {
- DCHECK_EQ(v_mode == ScrollbarMode::kAuto, h_mode == ScrollbarMode::kAuto);
+void LayoutView::SetAutosizeScrollbarModes(mojom::blink::ScrollbarMode h_mode,
+ mojom::blink::ScrollbarMode v_mode) {
+ DCHECK_EQ(v_mode == mojom::blink::ScrollbarMode::kAuto,
+ h_mode == mojom::blink::ScrollbarMode::kAuto);
autosize_v_scrollbar_mode_ = v_mode;
autosize_h_scrollbar_mode_ = h_mode;
}
-void LayoutView::CalculateScrollbarModes(ScrollbarMode& h_mode,
- ScrollbarMode& v_mode) const {
+void LayoutView::CalculateScrollbarModes(
+ mojom::blink::ScrollbarMode& h_mode,
+ mojom::blink::ScrollbarMode& v_mode) const {
#define RETURN_SCROLLBAR_MODE(mode) \
{ \
h_mode = v_mode = mode; \
@@ -634,8 +638,8 @@ void LayoutView::CalculateScrollbarModes(ScrollbarMode& h_mode,
// FrameViewAutoSizeInfo manually controls the appearance of the main frame's
// scrollbars so defer to those if we're in AutoSize mode.
- if (AutosizeVerticalScrollbarMode() != ScrollbarMode::kAuto ||
- AutosizeHorizontalScrollbarMode() != ScrollbarMode::kAuto) {
+ if (AutosizeVerticalScrollbarMode() != mojom::blink::ScrollbarMode::kAuto ||
+ AutosizeHorizontalScrollbarMode() != mojom::blink::ScrollbarMode::kAuto) {
h_mode = AutosizeHorizontalScrollbarMode();
v_mode = AutosizeVerticalScrollbarMode();
return;
@@ -643,19 +647,19 @@ void LayoutView::CalculateScrollbarModes(ScrollbarMode& h_mode,
LocalFrame* frame = GetFrame();
if (!frame)
- RETURN_SCROLLBAR_MODE(ScrollbarMode::kAlwaysOff);
+ RETURN_SCROLLBAR_MODE(mojom::blink::ScrollbarMode::kAlwaysOff);
if (FrameOwner* owner = frame->Owner()) {
// Setting scrolling="no" on an iframe element disables scrolling.
- if (owner->ScrollingMode() == ScrollbarMode::kAlwaysOff)
- RETURN_SCROLLBAR_MODE(ScrollbarMode::kAlwaysOff);
+ if (owner->ScrollbarMode() == mojom::blink::ScrollbarMode::kAlwaysOff)
+ RETURN_SCROLLBAR_MODE(mojom::blink::ScrollbarMode::kAlwaysOff);
}
Document& document = GetDocument();
if (Node* body = document.body()) {
// Framesets can't scroll.
if (body->GetLayoutObject() && body->GetLayoutObject()->IsFrameSet())
- RETURN_SCROLLBAR_MODE(ScrollbarMode::kAlwaysOff);
+ RETURN_SCROLLBAR_MODE(mojom::blink::ScrollbarMode::kAlwaysOff);
}
if (document.IsCapturingLayout()) {
@@ -663,40 +667,40 @@ void LayoutView::CalculateScrollbarModes(ScrollbarMode& h_mode,
// displayed.
// TODO(szager): Figure out the right behavior when printing an overflowing
// iframe. https://bugs.chromium.org/p/chromium/issues/detail?id=777528
- RETURN_SCROLLBAR_MODE(ScrollbarMode::kAlwaysOff);
+ RETURN_SCROLLBAR_MODE(mojom::blink::ScrollbarMode::kAlwaysOff);
}
if (LocalFrameView* frameView = GetFrameView()) {
// Scrollbars can be disabled by LocalFrameView::setCanHaveScrollbars.
if (!frameView->CanHaveScrollbars())
- RETURN_SCROLLBAR_MODE(ScrollbarMode::kAlwaysOff);
+ RETURN_SCROLLBAR_MODE(mojom::blink::ScrollbarMode::kAlwaysOff);
}
Element* viewportDefiningElement = document.ViewportDefiningElement();
if (!viewportDefiningElement)
- RETURN_SCROLLBAR_MODE(ScrollbarMode::kAuto);
+ RETURN_SCROLLBAR_MODE(mojom::blink::ScrollbarMode::kAuto);
LayoutObject* viewport = viewportDefiningElement->GetLayoutObject();
if (!viewport)
- RETURN_SCROLLBAR_MODE(ScrollbarMode::kAuto);
+ RETURN_SCROLLBAR_MODE(mojom::blink::ScrollbarMode::kAuto);
const ComputedStyle* style = viewport->Style();
if (!style)
- RETURN_SCROLLBAR_MODE(ScrollbarMode::kAuto);
+ RETURN_SCROLLBAR_MODE(mojom::blink::ScrollbarMode::kAuto);
if (viewport->IsSVGRoot()) {
// Don't allow overflow to affect <img> and css backgrounds
if (ToLayoutSVGRoot(viewport)->IsEmbeddedThroughSVGImage())
- RETURN_SCROLLBAR_MODE(ScrollbarMode::kAuto);
+ RETURN_SCROLLBAR_MODE(mojom::blink::ScrollbarMode::kAuto);
// FIXME: evaluate if we can allow overflow for these cases too.
// Overflow is always hidden when stand-alone SVG documents are embedded.
if (ToLayoutSVGRoot(viewport)
->IsEmbeddedThroughFrameContainingSVGDocument())
- RETURN_SCROLLBAR_MODE(ScrollbarMode::kAlwaysOff);
+ RETURN_SCROLLBAR_MODE(mojom::blink::ScrollbarMode::kAlwaysOff);
}
- h_mode = v_mode = ScrollbarMode::kAuto;
+ h_mode = v_mode = mojom::blink::ScrollbarMode::kAuto;
EOverflow overflow_x = style->OverflowX();
EOverflow overflow_y = style->OverflowY();
@@ -709,25 +713,19 @@ void LayoutView::CalculateScrollbarModes(ScrollbarMode& h_mode,
}
if (!shouldIgnoreOverflowHidden) {
if (overflow_x == EOverflow::kHidden)
- h_mode = ScrollbarMode::kAlwaysOff;
+ h_mode = mojom::blink::ScrollbarMode::kAlwaysOff;
if (overflow_y == EOverflow::kHidden)
- v_mode = ScrollbarMode::kAlwaysOff;
+ v_mode = mojom::blink::ScrollbarMode::kAlwaysOff;
}
if (overflow_x == EOverflow::kScroll)
- h_mode = ScrollbarMode::kAlwaysOn;
+ h_mode = mojom::blink::ScrollbarMode::kAlwaysOn;
if (overflow_y == EOverflow::kScroll)
- v_mode = ScrollbarMode::kAlwaysOn;
+ v_mode = mojom::blink::ScrollbarMode::kAlwaysOn;
#undef RETURN_SCROLLBAR_MODE
}
-void LayoutView::MayUpdateHoverWhenContentUnderMouseChanged(
- EventHandler& event_handler) {
- event_handler.MayUpdateHoverWhenContentUnderMouseChanged(
- MouseEventManager::UpdateHoverReason::kScrollOffsetChanged);
-}
-
PhysicalRect LayoutView::DocumentRect() const {
return FlipForWritingMode(LayoutOverflowRect());
}
@@ -813,7 +811,6 @@ bool LayoutView::UsesCompositing() const {
}
PaintLayerCompositor* LayoutView::Compositor() {
- DCHECK(compositor_);
return compositor_.get();
}
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 38b4e574759..10753eb247a 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_view.h
+++ b/chromium/third_party/blink/renderer/core/layout/layout_view.h
@@ -23,6 +23,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_VIEW_H_
#include <memory>
+#include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/hit_test_cache.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
@@ -31,6 +32,7 @@
#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
#include "third_party/blink/renderer/platform/graphics/scroll_types.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -164,18 +166,17 @@ class CORE_EXPORT LayoutView final : public LayoutBlockFlow {
kIgnorePlatformOverlayScrollbarSize) const override;
// If either direction has a non-auto mode, the other must as well.
- void SetAutosizeScrollbarModes(ScrollbarMode h_mode, ScrollbarMode v_mode);
- ScrollbarMode AutosizeHorizontalScrollbarMode() const {
+ void SetAutosizeScrollbarModes(mojom::blink::ScrollbarMode h_mode,
+ mojom::blink::ScrollbarMode v_mode);
+ mojom::blink::ScrollbarMode AutosizeHorizontalScrollbarMode() const {
return autosize_h_scrollbar_mode_;
}
- ScrollbarMode AutosizeVerticalScrollbarMode() const {
+ mojom::blink::ScrollbarMode AutosizeVerticalScrollbarMode() const {
return autosize_v_scrollbar_mode_;
}
- void CalculateScrollbarModes(ScrollbarMode& h_mode,
- ScrollbarMode& v_mode) const;
-
- void MayUpdateHoverWhenContentUnderMouseChanged(EventHandler&) override;
+ void CalculateScrollbarModes(mojom::blink::ScrollbarMode& h_mode,
+ mojom::blink::ScrollbarMode& v_mode) const;
LayoutState* GetLayoutState() const { return layout_state_; }
@@ -277,6 +278,10 @@ class CORE_EXPORT LayoutView final : public LayoutBlockFlow {
previous_background_rect_ = r;
}
+ void MapAncestorToLocal(const LayoutBoxModelObject*,
+ TransformState&,
+ MapCoordinatesFlags) const override;
+
private:
void MapLocalToAncestor(const LayoutBoxModelObject* ancestor,
TransformState&,
@@ -285,10 +290,6 @@ class CORE_EXPORT LayoutView final : public LayoutBlockFlow {
const LayoutObject* PushMappingToContainer(
const LayoutBoxModelObject* ancestor_to_stop_at,
LayoutGeometryMap&) const override;
- void MapAncestorToLocal(const LayoutBoxModelObject*,
- TransformState&,
- MapCoordinatesFlags) const override;
-
bool CanHaveChildren() const override;
void UpdateBlockLayout(bool relayout_children) override;
@@ -338,15 +339,20 @@ class CORE_EXPORT LayoutView final : public LayoutBlockFlow {
// FrameViewAutoSizeInfo controls scrollbar appearance manually rather than
// relying on layout. These members are used to override the ScrollbarModes
// calculated from style. kScrollbarAuto disables the override.
- ScrollbarMode autosize_h_scrollbar_mode_;
- ScrollbarMode autosize_v_scrollbar_mode_;
+ mojom::blink::ScrollbarMode autosize_h_scrollbar_mode_;
+ mojom::blink::ScrollbarMode autosize_v_scrollbar_mode_;
Vector<IntRect> tickmarks_override_;
mutable PhysicalRect previous_background_rect_;
};
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutView, IsLayoutView());
+template <>
+struct DowncastTraits<LayoutView> {
+ static bool AllowFrom(const LayoutObject& object) {
+ return object.IsLayoutView();
+ }
+};
} // namespace blink
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 1f69fd44cdc..94dbb303112 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
@@ -57,7 +57,7 @@ TEST_F(LayoutViewTest, DisplayNoneFrame) {
EXPECT_FALSE(view->CanHaveChildren());
EXPECT_FALSE(frame_doc->documentElement()->GetComputedStyle());
- frame_doc->body()->SetInnerHTMLFromString(R"HTML(
+ frame_doc->body()->setInnerHTML(R"HTML(
<div id="div"></div>
)HTML");
@@ -74,11 +74,11 @@ class LayoutViewHitTestTest : public testing::WithParamInterface<HitTestConfig>,
public RenderingTest {
public:
LayoutViewHitTestTest()
- : ScopedLayoutNGForTest(LayoutNG()),
+ : ScopedLayoutNGForTest(GetParam().layout_ng),
RenderingTest(MakeGarbageCollected<SingleChildLocalFrameClient>()) {}
protected:
- bool LayoutNG() { return GetParam().layout_ng; }
+ bool LayoutNG() { return RuntimeEnabledFeatures::LayoutNGEnabled(); }
bool IsAndroidOrWindowsEditingBehavior() {
// TODO(crbug.com/971414): For now LayoutNG always uses Android/Windows
// behavior for ShouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom().
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_vtt_cue.cc b/chromium/third_party/blink/renderer/core/layout/layout_vtt_cue.cc
index fa49a3ec625..f882270bd8c 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_vtt_cue.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_vtt_cue.cc
@@ -329,8 +329,7 @@ IntRect LayoutVTTCue::ComputeControlsRect() const {
// the MediaControls.
DCHECK(Parent()->GetNode()->IsTextTrackContainer());
- HTMLMediaElement* media_element =
- ToHTMLMediaElement(Parent()->Parent()->GetNode());
+ auto* media_element = To<HTMLMediaElement>(Parent()->Parent()->GetNode());
DCHECK(media_element);
MediaControls* controls = media_element->GetMediaControls();
diff --git a/chromium/third_party/blink/renderer/core/layout/line/abstract_inline_text_box.cc b/chromium/third_party/blink/renderer/core/layout/line/abstract_inline_text_box.cc
index 1907ede364d..371d92665ef 100644
--- a/chromium/third_party/blink/renderer/core/layout/line/abstract_inline_text_box.cc
+++ b/chromium/third_party/blink/renderer/core/layout/line/abstract_inline_text_box.cc
@@ -305,6 +305,8 @@ bool LegacyAbstractInlineTextBox::IsLineBreak() const {
const NGOffsetMapping* LegacyAbstractInlineTextBox::GetOffsetMapping() const {
const auto* text_node = DynamicTo<Text>(GetNode());
+ if (!text_node)
+ return nullptr;
LayoutBlockFlow& block_flow = *NGOffsetMapping::GetInlineFormattingContextOf(
*text_node->GetLayoutObject());
diff --git a/chromium/third_party/blink/renderer/core/layout/line/abstract_inline_text_box_test.cc b/chromium/third_party/blink/renderer/core/layout/line/abstract_inline_text_box_test.cc
index d63206fe779..5067af15179 100644
--- a/chromium/third_party/blink/renderer/core/layout/line/abstract_inline_text_box_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/line/abstract_inline_text_box_test.cc
@@ -20,7 +20,9 @@ class AbstractInlineTextBoxTest : public testing::WithParamInterface<bool>,
AbstractInlineTextBoxTest() : ScopedLayoutNGForTest(GetParam()) {}
protected:
- bool LayoutNGEnabled() const { return GetParam(); }
+ bool LayoutNGEnabled() const {
+ return RuntimeEnabledFeatures::LayoutNGEnabled();
+ }
};
INSTANTIATE_TEST_SUITE_P(All, AbstractInlineTextBoxTest, testing::Bool());
@@ -116,9 +118,10 @@ TEST_P(AbstractInlineTextBoxTest, GetTextWithLineBreakAtTrailingWhiteSpace) {
TEST_P(AbstractInlineTextBoxTest, GetTextOffsetInContainer) {
// "&#10" is a Line Feed ("\n").
- SetBodyInnerHTML(
- R"HTML(<style>p { white-space: pre-line; }</style>
- <p id="paragraph">First sentence of the &#10; paragraph. Second sentence of &#10; the paragraph.</p>)HTML");
+ SetBodyInnerHTML(R"HTML(
+ <style>p { white-space: pre-line; }</style>
+ <p id="paragraph">First sentence of the &#10; paragraph. Second sentence of &#10; the paragraph. </p>
+ <br id='br'>)HTML");
const Element& paragraph = *GetDocument().getElementById("paragraph");
LayoutText& layout_text =
@@ -145,6 +148,13 @@ TEST_P(AbstractInlineTextBoxTest, GetTextOffsetInContainer) {
inline_text_box = inline_text_box->NextInlineTextBox()->NextInlineTextBox();
EXPECT_EQ("the paragraph.", inline_text_box->GetText());
EXPECT_EQ(52u, inline_text_box->TextOffsetInContainer(0));
+
+ // Ensure that calling TextOffsetInContainer on a br gives the correct result.
+ const Element& br_element = *GetDocument().getElementById("br");
+ LayoutText& br_text = *ToLayoutText(br_element.GetLayoutObject());
+ inline_text_box = br_text.FirstAbstractInlineTextBox();
+ EXPECT_EQ("\n", inline_text_box->GetText());
+ EXPECT_EQ(0u, inline_text_box->TextOffsetInContainer(0));
}
} // namespace blink
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 e9fb4e46810..234f99caab9 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
@@ -20,6 +20,7 @@
#include "third_party/blink/renderer/core/layout/line/inline_box.h"
#include "base/allocator/partition_allocator/partition_alloc.h"
+#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
#include "third_party/blink/renderer/core/layout/api/line_layout_api_shim.h"
#include "third_party/blink/renderer/core/layout/api/line_layout_block_flow.h"
#include "third_party/blink/renderer/core/layout/hit_test_location.h"
@@ -100,6 +101,12 @@ IntRect InlineBox::PartialInvalidationVisualRect() const {
return GetLineLayoutItem().PartialInvalidationVisualRectForInlineBox();
}
+DOMNodeId InlineBox::OwnerNodeId() const {
+ return GetLineLayoutItem().GetNode()
+ ? DOMNodeIds::IdForNode(GetLineLayoutItem().GetNode())
+ : kInvalidDOMNodeId;
+}
+
#if DCHECK_IS_ON()
void InlineBox::ShowTreeForThis() const {
GetLineLayoutItem().ShowTreeForThis();
diff --git a/chromium/third_party/blink/renderer/core/layout/line/inline_box.h b/chromium/third_party/blink/renderer/core/layout/line/inline_box.h
index 2d5dc2026b9..07c06a0bc5c 100644
--- a/chromium/third_party/blink/renderer/core/layout/line/inline_box.h
+++ b/chromium/third_party/blink/renderer/core/layout/line/inline_box.h
@@ -131,6 +131,7 @@ class CORE_EXPORT InlineBox : public DisplayItemClient {
String DebugName() const override;
IntRect VisualRect() const override;
IntRect PartialInvalidationVisualRect() const override;
+ DOMNodeId OwnerNodeId() const override;
bool IsText() const { return bitfields_.IsText(); }
void SetIsText(bool is_text) { bitfields_.SetIsText(is_text); }
diff --git a/chromium/third_party/blink/renderer/core/layout/map_coordinates_test.cc b/chromium/third_party/blink/renderer/core/layout/map_coordinates_test.cc
index ae0b43acf1f..22aefbe8f04 100644
--- a/chromium/third_party/blink/renderer/core/layout/map_coordinates_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/map_coordinates_test.cc
@@ -363,7 +363,7 @@ TEST_F(MapCoordinatesTest, FixedPos) {
LayoutBox* body = container->ParentBox();
LayoutBox* html = body->ParentBox();
LayoutBox* view = html->ParentBox();
- ASSERT_TRUE(view->IsLayoutView());
+ ASSERT_TRUE(IsA<LayoutView>(view));
PhysicalOffset mapped_point =
MapLocalToAncestor(target, view, PhysicalOffset());
@@ -423,7 +423,7 @@ TEST_F(MapCoordinatesTest, FixedPosAuto) {
LayoutBox* body = container->ParentBox();
LayoutBox* html = body->ParentBox();
LayoutBox* view = html->ParentBox();
- ASSERT_TRUE(view->IsLayoutView());
+ ASSERT_TRUE(IsA<LayoutView>(view));
PhysicalOffset mapped_point =
MapLocalToAncestor(target, target->ContainingBlock(), PhysicalOffset());
@@ -489,7 +489,7 @@ TEST_F(MapCoordinatesTest, FixedPosInFixedPos) {
LayoutBox* body = container->ParentBox();
LayoutBox* html = body->ParentBox();
LayoutBox* view = html->ParentBox();
- ASSERT_TRUE(view->IsLayoutView());
+ ASSERT_TRUE(IsA<LayoutView>(view));
PhysicalOffset mapped_point =
MapLocalToAncestor(target, view, PhysicalOffset());
@@ -549,10 +549,10 @@ TEST_F(MapCoordinatesTest, FixedPosInFixedPosScrollView) {
LayoutBox* body = container->ParentBox();
LayoutBox* html = body->ParentBox();
LayoutBox* view = html->ParentBox();
- ASSERT_TRUE(view->IsLayoutView());
+ ASSERT_TRUE(IsA<LayoutView>(view));
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0.0, 50),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0.0, 50), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(50,
GetDocument().View()->LayoutViewport()->ScrollOffsetInt().Height());
@@ -584,10 +584,10 @@ TEST_F(MapCoordinatesTest, FixedPosInAbsolutePosScrollView) {
LayoutBox* body = container->ParentBox();
LayoutBox* html = body->ParentBox();
LayoutBox* view = html->ParentBox();
- ASSERT_TRUE(view->IsLayoutView());
+ ASSERT_TRUE(IsA<LayoutView>(view));
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0.0, 50),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0.0, 50), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(50,
GetDocument().View()->LayoutViewport()->ScrollOffsetInt().Height());
@@ -615,8 +615,8 @@ TEST_F(MapCoordinatesTest, FixedPosInTransform) {
<div class='spacer'></div>
)HTML");
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0.0, 50),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0.0, 50), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(50,
GetDocument().View()->LayoutViewport()->ScrollOffsetInt().Height());
@@ -626,7 +626,7 @@ TEST_F(MapCoordinatesTest, FixedPosInTransform) {
LayoutBox* body = container->ParentBox();
LayoutBox* html = body->ParentBox();
LayoutBox* view = html->ParentBox();
- ASSERT_TRUE(view->IsLayoutView());
+ ASSERT_TRUE(IsA<LayoutView>(view));
PhysicalOffset mapped_point =
MapLocalToAncestor(target, view, PhysicalOffset());
@@ -655,8 +655,8 @@ TEST_F(MapCoordinatesTest, FixedPosInContainPaint) {
<div class='spacer'></div>
)HTML");
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0.0, 50),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0.0, 50), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(50,
GetDocument().View()->LayoutViewport()->ScrollOffsetInt().Height());
@@ -666,7 +666,7 @@ TEST_F(MapCoordinatesTest, FixedPosInContainPaint) {
LayoutBox* body = container->ParentBox();
LayoutBox* html = body->ParentBox();
LayoutBox* view = html->ParentBox();
- ASSERT_TRUE(view->IsLayoutView());
+ ASSERT_TRUE(IsA<LayoutView>(view));
PhysicalOffset mapped_point =
MapLocalToAncestor(target, view, PhysicalOffset());
@@ -700,7 +700,7 @@ TEST_F(MapCoordinatesTest, FixedPosInIFrameWhenMainFrameScrolled) {
"position:fixed}</style><div id=target></div>");
GetDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0.0, 1000), kProgrammaticScroll);
+ ScrollOffset(0.0, 1000), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
Element* target = ChildDocument().getElementById("target");
@@ -731,9 +731,8 @@ TEST_F(MapCoordinatesTest, IFrameTransformed) {
UpdateAllLifecyclePhasesForTest();
ChildDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0.0, 1000), kProgrammaticScroll);
- ChildDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ ScrollOffset(0.0, 1000), mojom::blink::ScrollType::kProgrammatic);
+ ChildDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
Element* target = ChildDocument().getElementById("target");
ASSERT_TRUE(target);
@@ -768,7 +767,7 @@ TEST_F(MapCoordinatesTest, FixedPosInScrolledIFrameWithTransform) {
UpdateAllLifecyclePhasesForTest();
ChildDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0.0, 1000), kProgrammaticScroll);
+ ScrollOffset(0.0, 1000), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
Element* target = ChildDocument().getElementById("target");
diff --git a/chromium/third_party/blink/renderer/core/layout/min_max_size_test.cc b/chromium/third_party/blink/renderer/core/layout/min_max_size_test.cc
index af5cb1e84b0..31171af4b41 100644
--- a/chromium/third_party/blink/renderer/core/layout/min_max_size_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/min_max_size_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/layout/min_max_size.h"
+#include "third_party/blink/renderer/core/layout/min_max_sizes.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -11,7 +11,7 @@ namespace blink {
namespace {
TEST(NGUnitsTest, ShrinkToFit) {
- MinMaxSize sizes;
+ MinMaxSizes sizes;
sizes.min_size = LayoutUnit(100);
sizes.max_size = LayoutUnit(200);
diff --git a/chromium/third_party/blink/renderer/core/layout/min_max_size.cc b/chromium/third_party/blink/renderer/core/layout/min_max_sizes.cc
index e6980104b3c..15f5bf6aca8 100644
--- a/chromium/third_party/blink/renderer/core/layout/min_max_size.cc
+++ b/chromium/third_party/blink/renderer/core/layout/min_max_sizes.cc
@@ -2,13 +2,13 @@
// 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/min_max_size.h"
+#include "third_party/blink/renderer/core/layout/min_max_sizes.h"
#include <algorithm>
namespace blink {
-std::ostream& operator<<(std::ostream& stream, const MinMaxSize& value) {
+std::ostream& operator<<(std::ostream& stream, const MinMaxSizes& value) {
return stream << "(" << value.min_size << ", " << value.max_size << ")";
}
diff --git a/chromium/third_party/blink/renderer/core/layout/min_max_size.h b/chromium/third_party/blink/renderer/core/layout/min_max_sizes.h
index 4233e6c79a1..721ecec1738 100644
--- a/chromium/third_party/blink/renderer/core/layout/min_max_size.h
+++ b/chromium/third_party/blink/renderer/core/layout/min_max_sizes.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_MIN_MAX_SIZE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_MIN_MAX_SIZE_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_MIN_MAX_SIZES_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_MIN_MAX_SIZES_H_
#include <algorithm>
@@ -15,12 +15,12 @@ namespace blink {
// A struct that holds a pair of two sizes, a "min" size and a "max" size.
// Useful for holding a {min,max}-content size pair or a
// {min,max}-{width,height}.
-struct CORE_EXPORT MinMaxSize {
+struct CORE_EXPORT MinMaxSizes {
LayoutUnit min_size;
LayoutUnit max_size;
// Make sure that our min/max sizes are at least as large as |other|.
- void Encompass(const MinMaxSize& other) {
+ void Encompass(const MinMaxSizes& other) {
min_size = std::max(min_size, other.min_size);
max_size = std::max(max_size, other.max_size);
}
@@ -50,30 +50,30 @@ struct CORE_EXPORT MinMaxSize {
return std::max(min_size, std::min(size, max_size));
}
- bool operator==(const MinMaxSize& other) const {
+ bool operator==(const MinMaxSizes& other) const {
return min_size == other.min_size && max_size == other.max_size;
}
void operator=(LayoutUnit value) { min_size = max_size = value; }
- MinMaxSize& operator+=(MinMaxSize extra) {
+ MinMaxSizes& operator+=(MinMaxSizes extra) {
min_size += extra.min_size;
max_size += extra.max_size;
return *this;
}
- MinMaxSize& operator+=(const LayoutUnit length) {
+ MinMaxSizes& operator+=(const LayoutUnit length) {
min_size += length;
max_size += length;
return *this;
}
- MinMaxSize& operator-=(const LayoutUnit length) {
+ MinMaxSizes& operator-=(const LayoutUnit length) {
min_size -= length;
max_size -= length;
return *this;
}
};
-CORE_EXPORT std::ostream& operator<<(std::ostream&, const MinMaxSize&);
+CORE_EXPORT std::ostream& operator<<(std::ostream&, const MinMaxSizes&);
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_MIN_MAX_SIZE_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_MIN_MAX_SIZES_H_
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 3ac1c1fbcb5..b662f819135 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
@@ -13,6 +13,8 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_fragment_result_options.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_function.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_intrinsic_sizes_callback.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_intrinsic_sizes_result_options.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_layout_callback.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_no_argument_constructor.h"
#include "third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.h"
@@ -23,20 +25,41 @@
#include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_edges.h"
#include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_scope.h"
-#include "third_party/blink/renderer/core/layout/ng/custom/fragment_result_options.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_input_node.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/bindings/v8_binding_macros.h"
#include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
+namespace {
+
+void GatherChildren(const NGBlockNode& node,
+ CustomLayoutScope* custom_layout_scope,
+ HeapVector<Member<CustomLayoutChild>>* children) {
+ // TODO(ikilpatrick): Determine if knowing the size of the array ahead of
+ // time improves performance in any noticeable way.
+ for (NGLayoutInputNode child = node.FirstChild(); child;
+ child = child.NextSibling()) {
+ if (child.IsOutOfFlowPositioned())
+ continue;
+
+ CustomLayoutChild* layout_child = child.GetCustomLayoutChild();
+ layout_child->SetCustomLayoutToken(custom_layout_scope->Token());
+ DCHECK(layout_child);
+ children->push_back(layout_child);
+ }
+}
+
+} // anonymous namespace
+
CSSLayoutDefinition::CSSLayoutDefinition(
ScriptState* script_state,
V8NoArgumentConstructor* constructor,
- V8Function* intrinsic_sizes,
+ V8IntrinsicSizesCallback* intrinsic_sizes,
V8LayoutCallback* layout,
const Vector<CSSPropertyID>& native_invalidation_properties,
const Vector<AtomicString>& custom_invalidation_properties,
@@ -44,7 +67,7 @@ CSSLayoutDefinition::CSSLayoutDefinition(
const Vector<AtomicString>& child_custom_invalidation_properties)
: script_state_(script_state),
constructor_(constructor),
- unused_intrinsic_sizes_(intrinsic_sizes),
+ intrinsic_sizes_(intrinsic_sizes),
layout_(layout),
native_invalidation_properties_(native_invalidation_properties),
custom_invalidation_properties_(custom_invalidation_properties),
@@ -66,8 +89,9 @@ bool CSSLayoutDefinition::Instance::Layout(
const NGBlockNode& node,
const LogicalSize& border_box_size,
const NGBoxStrut& border_scrollbar_padding,
+ const LayoutUnit child_percentage_resolution_block_size_for_min_max,
CustomLayoutScope* custom_layout_scope,
- FragmentResultOptions* fragment_result_options,
+ FragmentResultOptions*& fragment_result_options,
scoped_refptr<SerializedScriptValue>* fragment_result_data) {
ScriptState* script_state = definition_->GetScriptState();
v8::Isolate* isolate = script_state->GetIsolate();
@@ -77,19 +101,8 @@ bool CSSLayoutDefinition::Instance::Layout(
ScriptState::Scope scope(script_state);
- // TODO(ikilpatrick): Determine if knowing the size of the array ahead of
- // time improves performance in any noticeable way.
HeapVector<Member<CustomLayoutChild>> children;
- for (NGLayoutInputNode child = node.FirstChild(); child;
- child = child.NextSibling()) {
- if (child.IsOutOfFlowPositioned())
- continue;
-
- CustomLayoutChild* layout_child = child.GetCustomLayoutChild();
- layout_child->SetCustomLayoutToken(custom_layout_scope->Token());
- DCHECK(layout_child);
- children.push_back(layout_child);
- }
+ GatherChildren(node, custom_layout_scope, &children);
CustomLayoutEdges* edges =
MakeGarbageCollected<CustomLayoutEdges>(border_scrollbar_padding);
@@ -121,18 +134,20 @@ bool CSSLayoutDefinition::Instance::Layout(
v8::Local<v8::Value> v8_return_value = return_value.V8Value();
if (v8_return_value.IsEmpty() || !v8_return_value->IsPromise()) {
- execution_context->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kInfo,
- "The layout function must be async or return a "
- "promise, falling back to block layout."));
+ execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kInfo,
+ "The layout function must be async or return a "
+ "promise, falling back to block layout."));
return false;
}
// Run the work queue until exhaustion.
while (!custom_layout_scope->Queue()->IsEmpty()) {
- for (auto& task : *custom_layout_scope->Queue())
- task.Run(space, node.Style());
+ for (auto& task : *custom_layout_scope->Queue()) {
+ task.Run(space, node.Style(),
+ child_percentage_resolution_block_size_for_min_max);
+ }
custom_layout_scope->Queue()->clear();
{
v8::MicrotasksScope microtasks_scope(isolate, microtask_queue,
@@ -149,27 +164,28 @@ bool CSSLayoutDefinition::Instance::Layout(
v8::Local<v8::Promise>::Cast(v8_return_value);
if (v8_result_promise->State() != v8::Promise::kFulfilled) {
- execution_context->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kInfo,
- "The layout function promise must resolve, "
- "falling back to block layout."));
+ execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kInfo,
+ "The layout function promise must resolve, "
+ "falling back to block layout."));
return false;
}
v8::Local<v8::Value> inner_value = v8_result_promise->Result();
// Attempt to convert the result.
- V8FragmentResultOptions::ToImpl(isolate, inner_value, fragment_result_options,
- exception_state);
+ fragment_result_options =
+ NativeValueTraits<FragmentResultOptions>::NativeValue(
+ isolate, inner_value, exception_state);
if (exception_state.HadException()) {
V8ScriptRunner::ReportException(isolate, exception_state.GetException());
exception_state.ClearException();
- execution_context->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kInfo,
- "Unable to parse the layout function "
- "result, falling back to block layout."));
+ execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kInfo,
+ "Unable to parse the layout function "
+ "result, falling back to block layout."));
return false;
}
@@ -188,11 +204,114 @@ bool CSSLayoutDefinition::Instance::Layout(
if (exception_state.HadException()) {
V8ScriptRunner::ReportException(isolate, exception_state.GetException());
exception_state.ClearException();
- execution_context->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kInfo,
- "Unable to serialize the data provided in the "
- "result, falling back to block layout."));
+ execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kInfo,
+ "Unable to serialize the data provided in the "
+ "result, falling back to block layout."));
+ return false;
+ }
+
+ return true;
+}
+
+bool CSSLayoutDefinition::Instance::IntrinsicSizes(
+ const NGConstraintSpace& space,
+ const Document& document,
+ const NGBlockNode& node,
+ const LogicalSize& border_box_size,
+ const NGBoxStrut& border_scrollbar_padding,
+ const LayoutUnit child_percentage_resolution_block_size_for_min_max,
+ CustomLayoutScope* custom_layout_scope,
+ IntrinsicSizesResultOptions*& intrinsic_sizes_result_options) {
+ ScriptState* script_state = definition_->GetScriptState();
+ v8::Isolate* isolate = script_state->GetIsolate();
+
+ if (!script_state->ContextIsValid())
+ return false;
+
+ ScriptState::Scope scope(script_state);
+
+ HeapVector<Member<CustomLayoutChild>> children;
+ GatherChildren(node, custom_layout_scope, &children);
+
+ CustomLayoutEdges* edges =
+ MakeGarbageCollected<CustomLayoutEdges>(border_scrollbar_padding);
+
+ // TODO(ikilpatrick): Instead of creating a new style_map each time here,
+ // store on LayoutCustom, and update when the style changes.
+ StylePropertyMapReadOnly* style_map =
+ MakeGarbageCollected<PrepopulatedComputedStylePropertyMap>(
+ document, node.Style(), definition_->native_invalidation_properties_,
+ definition_->custom_invalidation_properties_);
+
+ ScriptValue return_value;
+ if (!definition_->intrinsic_sizes_
+ ->Invoke(instance_.NewLocal(isolate), children, edges, style_map)
+ .To(&return_value))
+ return false;
+
+ ExecutionContext* execution_context = ExecutionContext::From(script_state);
+ v8::MicrotaskQueue* microtask_queue = ToMicrotaskQueue(execution_context);
+ DCHECK(microtask_queue);
+
+ ExceptionState exception_state(isolate, ExceptionState::kExecutionContext,
+ "CSSLayoutAPI", "IntrinsicSizes");
+
+ v8::Local<v8::Value> v8_return_value = return_value.V8Value();
+ if (v8_return_value.IsEmpty() || !v8_return_value->IsPromise()) {
+ execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kInfo,
+ "The intrinsicSizes function must be async or return a "
+ "promise, falling back to block layout."));
+ return false;
+ }
+
+ // Run the work queue until exhaustion.
+ while (!custom_layout_scope->Queue()->IsEmpty()) {
+ for (auto& task : *custom_layout_scope->Queue()) {
+ task.Run(space, node.Style(),
+ child_percentage_resolution_block_size_for_min_max);
+ }
+ custom_layout_scope->Queue()->clear();
+ {
+ v8::MicrotasksScope microtasks_scope(isolate, microtask_queue,
+ v8::MicrotasksScope::kRunMicrotasks);
+ }
+ }
+
+ if (exception_state.HadException()) {
+ ReportException(&exception_state);
+ return false;
+ }
+
+ v8::Local<v8::Promise> v8_result_promise =
+ v8::Local<v8::Promise>::Cast(v8_return_value);
+
+ if (v8_result_promise->State() != v8::Promise::kFulfilled) {
+ execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kInfo,
+ "The intrinsicSizes function promise must resolve, "
+ "falling back to block layout."));
+ return false;
+ }
+ v8::Local<v8::Value> inner_value = v8_result_promise->Result();
+
+ // Attempt to convert the result.
+ intrinsic_sizes_result_options =
+ NativeValueTraits<IntrinsicSizesResultOptions>::NativeValue(
+ isolate, inner_value, exception_state);
+
+ if (exception_state.HadException()) {
+ V8ScriptRunner::ReportException(isolate, exception_state.GetException());
+ exception_state.ClearException();
+ execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kInfo,
+ "Unable to parse the intrinsicSizes function "
+ "result, falling back to block layout."));
return false;
}
@@ -209,7 +328,7 @@ void CSSLayoutDefinition::Instance::ReportException(
// again (as the callbacks are invoked directly by the UA).
V8ScriptRunner::ReportException(isolate, exception_state->GetException());
exception_state->ClearException();
- execution_context->AddConsoleMessage(ConsoleMessage::Create(
+ execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kInfo,
"The layout function failed, falling back to block layout."));
@@ -234,14 +353,14 @@ CSSLayoutDefinition::Instance* CSSLayoutDefinition::CreateInstance() {
return MakeGarbageCollected<Instance>(this, instance.V8Value());
}
-void CSSLayoutDefinition::Instance::Trace(blink::Visitor* visitor) {
+void CSSLayoutDefinition::Instance::Trace(Visitor* visitor) {
visitor->Trace(definition_);
visitor->Trace(instance_);
}
void CSSLayoutDefinition::Trace(Visitor* visitor) {
visitor->Trace(constructor_);
- visitor->Trace(unused_intrinsic_sizes_);
+ visitor->Trace(intrinsic_sizes_);
visitor->Trace(layout_);
visitor->Trace(script_state_);
}
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 b8690a9e84f..4c1ff77f733 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
@@ -17,13 +17,15 @@ namespace blink {
class CustomLayoutScope;
class FragmentResultOptions;
+class IntrinsicSizesResultOptions;
+class LayoutUnit;
struct LogicalSize;
class NGBlockNode;
struct NGBoxStrut;
class NGConstraintSpace;
class ScriptState;
class SerializedScriptValue;
-class V8Function;
+class V8IntrinsicSizesCallback;
class V8LayoutCallback;
class V8NoArgumentConstructor;
@@ -36,7 +38,7 @@ class CSSLayoutDefinition final : public GarbageCollected<CSSLayoutDefinition>,
CSSLayoutDefinition(
ScriptState*,
V8NoArgumentConstructor* constructor,
- V8Function* intrinsic_sizes,
+ V8IntrinsicSizesCallback* intrinsic_sizes,
V8LayoutCallback* layout,
const Vector<CSSPropertyID>& native_invalidation_properties,
const Vector<AtomicString>& custom_invalidation_properties,
@@ -53,16 +55,30 @@ class CSSLayoutDefinition final : public GarbageCollected<CSSLayoutDefinition>,
// Runs the web developer defined layout, returns true if everything
// succeeded. It populates the FragmentResultOptions dictionary, and
// fragment_result_data.
- bool Layout(const NGConstraintSpace&,
- const Document&,
- const NGBlockNode&,
- const LogicalSize& border_box_size,
- const NGBoxStrut& border_scrollbar_padding,
- CustomLayoutScope*,
- FragmentResultOptions*,
- scoped_refptr<SerializedScriptValue>* fragment_result_data);
-
- void Trace(blink::Visitor*);
+ bool Layout(
+ const NGConstraintSpace&,
+ const Document&,
+ const NGBlockNode&,
+ const LogicalSize& border_box_size,
+ const NGBoxStrut& border_scrollbar_padding,
+ const LayoutUnit child_percentage_resolution_block_size_for_min_max,
+ CustomLayoutScope*,
+ FragmentResultOptions*&,
+ scoped_refptr<SerializedScriptValue>* fragment_result_data);
+
+ // Runs the web developer defined intrinsicSizes, returns true if everything
+ // succeeded. It populates the IntrinsicSizesResultOptions dictionary.
+ bool IntrinsicSizes(
+ const NGConstraintSpace&,
+ const Document&,
+ const NGBlockNode&,
+ const LogicalSize& border_box_size,
+ const NGBoxStrut& border_scrollbar_padding,
+ const LayoutUnit child_percentage_resolution_block_size_for_min_max,
+ CustomLayoutScope*,
+ IntrinsicSizesResultOptions*&);
+
+ void Trace(Visitor*);
private:
void ReportException(ExceptionState*);
@@ -90,7 +106,7 @@ class CSSLayoutDefinition final : public GarbageCollected<CSSLayoutDefinition>,
ScriptState* GetScriptState() const { return script_state_; }
- virtual void Trace(blink::Visitor* visitor);
+ virtual void Trace(Visitor* visitor);
const char* NameInHeapSnapshot() const override {
return "CSSLayoutDefinition";
@@ -103,7 +119,7 @@ class CSSLayoutDefinition final : public GarbageCollected<CSSLayoutDefinition>,
// sizes function, and layout function alive. It participates in wrapper
// tracing as it holds onto V8 wrappers.
Member<V8NoArgumentConstructor> constructor_;
- Member<V8Function> unused_intrinsic_sizes_;
+ Member<V8IntrinsicSizesCallback> intrinsic_sizes_;
Member<V8LayoutCallback> layout_;
// If a constructor call ever fails, we'll refuse to create any more
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
new file mode 100644
index 00000000000..7dd9c992f83
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.cc
@@ -0,0 +1,30 @@
+// 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/layout/ng/custom/custom_intrinsic_sizes.h"
+
+#include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.h"
+
+namespace blink {
+
+CustomIntrinsicSizes::CustomIntrinsicSizes(CustomLayoutChild* child,
+ CustomLayoutToken* token,
+ double min_content_size,
+ double max_content_size)
+ : child_(child),
+ token_(token),
+ min_content_size_(min_content_size),
+ max_content_size_(max_content_size) {}
+
+const NGLayoutInputNode& CustomIntrinsicSizes::GetLayoutNode() const {
+ return child_->GetLayoutNode();
+}
+
+void CustomIntrinsicSizes::Trace(Visitor* visitor) {
+ visitor->Trace(child_);
+ visitor->Trace(token_);
+ ScriptWrappable::Trace(visitor);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..1bfa9cea738
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.h
@@ -0,0 +1,53 @@
+// 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_LAYOUT_NG_CUSTOM_CUSTOM_INTRINSIC_SIZES_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_CUSTOM_CUSTOM_INTRINSIC_SIZES_H_
+
+#include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_scope.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+
+namespace blink {
+
+class NGLayoutInputNode;
+class CustomLayoutChild;
+
+// This represents the result of intrinsicSizes (on a LayoutChild).
+//
+// This should mirror the information in a MinMaxSize, and it has the
+// additional capability that it is exposed to web developers.
+class CustomIntrinsicSizes : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ CustomIntrinsicSizes(CustomLayoutChild*,
+ CustomLayoutToken*,
+ double min_content_size,
+ double max_content_size);
+ ~CustomIntrinsicSizes() override = default;
+
+ CustomIntrinsicSizes(const CustomIntrinsicSizes&) = delete;
+ CustomIntrinsicSizes& operator=(const CustomIntrinsicSizes&) = delete;
+
+ double minContentSize() const { return min_content_size_; }
+ double maxContentSize() const { return max_content_size_; }
+
+ const NGLayoutInputNode& GetLayoutNode() const;
+
+ bool IsValid() const { return token_->IsValid(); }
+
+ void Trace(Visitor*) override;
+
+ private:
+ Member<CustomLayoutChild> child_;
+ Member<CustomLayoutToken> token_;
+
+ // The min and max content sizes on this object should never change.
+ const double min_content_size_;
+ const double max_content_size_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_CUSTOM_CUSTOM_INTRINSIC_SIZES_H_
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 043110aec8f..11a2762ad9d 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
@@ -11,9 +11,14 @@
#include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_scope.h"
#include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
namespace blink {
+namespace {
+const char kInvalidLayoutChild[] = "The LayoutChild is not valid.";
+} // namespace
+
CustomLayoutChild::CustomLayoutChild(const CSSLayoutDefinition& definition,
NGLayoutInputNode node)
: node_(node),
@@ -23,6 +28,24 @@ CustomLayoutChild::CustomLayoutChild(const CSSLayoutDefinition& definition,
definition.ChildNativeInvalidationProperties(),
definition.ChildCustomInvalidationProperties())) {}
+ScriptPromise CustomLayoutChild::intrinsicSizes(
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
+ // A layout child may be invalid if it has been removed from the tree (it is
+ // possible for a web developer to hold onto a LayoutChild object after its
+ // underlying LayoutObject has been destroyed).
+ if (!node_ || !token_->IsValid()) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ kInvalidLayoutChild);
+ return ScriptPromise();
+ }
+
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ CustomLayoutScope::Current()->Queue()->emplace_back(
+ this, token_, resolver, CustomLayoutWorkTask::TaskType::kIntrinsicSizes);
+ return resolver->Promise();
+}
+
ScriptPromise CustomLayoutChild::layoutNextFragment(
ScriptState* script_state,
const CustomLayoutConstraintsOptions* options,
@@ -31,10 +54,9 @@ ScriptPromise CustomLayoutChild::layoutNextFragment(
// possible for a web developer to hold onto a LayoutChild object after its
// underlying LayoutObject has been destroyed).
if (!node_ || !token_->IsValid()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- "The LayoutChild is not valid."));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ kInvalidLayoutChild);
+ return ScriptPromise();
}
// Serialize the provided data if needed.
@@ -54,11 +76,12 @@ ScriptPromise CustomLayoutChild::layoutNextFragment(
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
CustomLayoutScope::Current()->Queue()->emplace_back(
- this, token_, resolver, options, std::move(constraint_data));
+ this, token_, resolver, options, std::move(constraint_data),
+ CustomLayoutWorkTask::TaskType::kLayoutFragment);
return resolver->Promise();
}
-void CustomLayoutChild::Trace(blink::Visitor* visitor) {
+void CustomLayoutChild::Trace(Visitor* visitor) {
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 5b7c1c435f3..7943adc0ac3 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
@@ -16,6 +16,7 @@ namespace blink {
class CSSLayoutDefinition;
class CustomLayoutConstraintsOptions;
class CustomLayoutToken;
+class ExceptionState;
// Represents a "CSS box" for use by a web developer. This is passed into the
// web developer defined layout and intrinsicSizes functions so that they can
@@ -32,6 +33,7 @@ class CustomLayoutChild : public ScriptWrappable {
// LayoutChild.idl
PrepopulatedComputedStylePropertyMap* styleMap() const { return style_map_; }
+ ScriptPromise intrinsicSizes(ScriptState*, ExceptionState&);
ScriptPromise layoutNextFragment(ScriptState*,
const CustomLayoutConstraintsOptions*,
ExceptionState&);
@@ -44,7 +46,7 @@ class CustomLayoutChild : public ScriptWrappable {
void SetCustomLayoutToken(CustomLayoutToken* token) { token_ = token; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 ec4f27e6957..268d0e72343 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
@@ -25,6 +25,13 @@ CustomLayoutConstraints::CustomLayoutConstraints(
CustomLayoutConstraints::~CustomLayoutConstraints() = default;
+base::Optional<double> CustomLayoutConstraints::fixedBlockSize() const {
+ // Check if we've been passed an indefinite block-size.
+ if (fixed_block_size_ < 0.0)
+ return base::nullopt;
+ return fixed_block_size_;
+}
+
double CustomLayoutConstraints::fixedBlockSize(bool& is_null) const {
// Check if we've been passed an indefinite block-size.
if (fixed_block_size_ < 0.0) {
@@ -50,7 +57,7 @@ ScriptValue CustomLayoutConstraints::data(ScriptState* script_state) const {
layout_worklet_world_v8_data_.NewLocal(script_state->GetIsolate()));
}
-void CustomLayoutConstraints::Trace(blink::Visitor* visitor) {
+void CustomLayoutConstraints::Trace(Visitor* visitor) {
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 1c66b7c437f..42ce5a8fa06 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
@@ -29,10 +29,12 @@ class CustomLayoutConstraints : public ScriptWrappable {
// LayoutConstraints.idl
double fixedInlineSize() const { return fixed_inline_size_; }
- double fixedBlockSize(bool& is_null) const;
+ base::Optional<double> fixedBlockSize() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ double fixedBlockSize(bool& is_null) const; // DEPRECATED
ScriptValue data(ScriptState*) const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 1019fd242bb..476d990a0b4 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
@@ -15,12 +15,14 @@ CustomLayoutFragment::CustomLayoutFragment(
CustomLayoutToken* token,
scoped_refptr<const NGLayoutResult> layout_result,
const LogicalSize& size,
+ const base::Optional<LayoutUnit> baseline,
v8::Isolate* isolate)
: child_(child),
token_(token),
layout_result_(std::move(layout_result)),
inline_size_(size.inline_size.ToDouble()),
- block_size_(size.block_size.ToDouble()) {
+ block_size_(size.block_size.ToDouble()),
+ baseline_(baseline) {
// Immediately store the result data, so that it remains immutable between
// layout calls to the child.
if (SerializedScriptValue* data = layout_result_->CustomLayoutData())
@@ -36,6 +38,11 @@ const NGLayoutInputNode& CustomLayoutFragment::GetLayoutNode() const {
return child_->GetLayoutNode();
}
+double CustomLayoutFragment::baseline(bool& is_null) const {
+ is_null = !baseline_.has_value();
+ return baseline_.value_or(0.0);
+}
+
ScriptValue CustomLayoutFragment::data(ScriptState* script_state) const {
// "data" is *only* exposed to the LayoutWorkletGlobalScope, and we are able
// to return the same deserialized object. We don't need to check which world
@@ -51,7 +58,7 @@ ScriptValue CustomLayoutFragment::data(ScriptState* script_state) const {
layout_worklet_world_v8_data_.NewLocal(script_state->GetIsolate()));
}
-void CustomLayoutFragment::Trace(blink::Visitor* visitor) {
+void CustomLayoutFragment::Trace(Visitor* visitor) {
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 bc9cb8ee03e..29adc05f5a9 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
@@ -39,6 +39,7 @@ class CustomLayoutFragment : public ScriptWrappable {
CustomLayoutToken*,
scoped_refptr<const NGLayoutResult>,
const LogicalSize& size,
+ const base::Optional<LayoutUnit> baseline,
v8::Isolate*);
~CustomLayoutFragment() override = default;
@@ -51,6 +52,10 @@ class CustomLayoutFragment : public ScriptWrappable {
void setInlineOffset(double inline_offset) { inline_offset_ = inline_offset; }
void setBlockOffset(double block_offset) { block_offset_ = block_offset; }
+ base::Optional<double> baseline() const { return baseline_; }
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ double baseline(bool& is_null) const; // DEPRECATED
+
ScriptValue data(ScriptState*) const;
const NGLayoutResult& GetLayoutResult() const;
@@ -58,7 +63,7 @@ class CustomLayoutFragment : public ScriptWrappable {
bool IsValid() const { return token_->IsValid(); }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<CustomLayoutChild> child_;
@@ -88,6 +93,9 @@ class CustomLayoutFragment : public ScriptWrappable {
double inline_offset_ = 0;
double block_offset_ = 0;
+ // The first-line baseline.
+ const base::Optional<double> baseline_;
+
TraceWrapperV8Reference<v8::Value> layout_worklet_world_v8_data_;
DISALLOW_COPY_AND_ASSIGN(CustomLayoutFragment);
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 319ea6b778b..3cc70061f06 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
@@ -64,7 +64,7 @@ class CustomLayoutScope {
CustomLayoutScope* prev_scope_;
CustomLayoutWorkQueue queue_;
- Member<CustomLayoutToken> token_;
+ CustomLayoutToken* token_;
};
inline bool CustomLayoutToken::IsValid() const {
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 b23852b8139..3e9dc834b29 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
@@ -5,37 +5,68 @@
#include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
+#include "third_party/blink/renderer/core/layout/ng/custom/custom_intrinsic_sizes.h"
#include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_child.h"
-#include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_constraints_options.h"
#include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_box_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_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/layout/ng/ng_physical_box_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_space_utils.h"
namespace blink {
+CustomLayoutWorkTask::CustomLayoutWorkTask(CustomLayoutChild* child,
+ CustomLayoutToken* token,
+ ScriptPromiseResolver* resolver,
+ const TaskType type)
+ : CustomLayoutWorkTask(child, token, resolver, nullptr, nullptr, type) {}
+
CustomLayoutWorkTask::CustomLayoutWorkTask(
CustomLayoutChild* child,
CustomLayoutToken* token,
ScriptPromiseResolver* resolver,
const CustomLayoutConstraintsOptions* options,
- scoped_refptr<SerializedScriptValue> constraint_data)
+ scoped_refptr<SerializedScriptValue> constraint_data,
+ const TaskType type)
: child_(child),
token_(token),
resolver_(resolver),
options_(options),
- constraint_data_(std::move(constraint_data)) {}
+ constraint_data_(std::move(constraint_data)),
+ type_(type) {}
CustomLayoutWorkTask::~CustomLayoutWorkTask() = default;
-void CustomLayoutWorkTask::Run(const NGConstraintSpace& parent_space,
- const ComputedStyle& parent_style) {
+void CustomLayoutWorkTask::Run(
+ const NGConstraintSpace& parent_space,
+ const ComputedStyle& parent_style,
+ const LayoutUnit child_percentage_resolution_block_size_for_min_max) {
DCHECK(token_->IsValid());
- NGLayoutInputNode node = child_->GetLayoutNode();
- NGConstraintSpaceBuilder builder(parent_space, node.Style().GetWritingMode(),
+ NGLayoutInputNode child = child_->GetLayoutNode();
+
+ if (type_ == CustomLayoutWorkTask::TaskType::kIntrinsicSizes) {
+ RunIntrinsicSizesTask(parent_style,
+ child_percentage_resolution_block_size_for_min_max,
+ child);
+ } else {
+ DCHECK_EQ(type_, CustomLayoutWorkTask::TaskType::kLayoutFragment);
+ RunLayoutFragmentTask(parent_space, parent_style, child);
+ }
+}
+
+void CustomLayoutWorkTask::RunLayoutFragmentTask(
+ const NGConstraintSpace& parent_space,
+ const ComputedStyle& parent_style,
+ NGLayoutInputNode child) {
+ DCHECK_EQ(type_, CustomLayoutWorkTask::TaskType::kLayoutFragment);
+ DCHECK(options_ && resolver_);
+
+ NGConstraintSpaceBuilder builder(parent_space, child.Style().GetWritingMode(),
/* is_new_fc */ true);
- SetOrthogonalFallbackInlineSizeIfNeeded(parent_style, node, &builder);
+ SetOrthogonalFallbackInlineSizeIfNeeded(parent_style, child, &builder);
bool is_fixed_inline_size = false;
bool is_fixed_block_size = false;
@@ -88,24 +119,40 @@ void CustomLayoutWorkTask::Run(const NGConstraintSpace& parent_space,
percentage_size.block_size = kIndefiniteSize;
}
- builder.SetTextDirection(node.Style().Direction());
+ builder.SetTextDirection(child.Style().Direction());
builder.SetAvailableSize(available_size);
builder.SetPercentageResolutionSize(percentage_size);
builder.SetReplacedPercentageResolutionSize(percentage_size);
- builder.SetIsShrinkToFit(node.Style().LogicalWidth().IsAuto());
+ builder.SetIsShrinkToFit(child.Style().LogicalWidth().IsAuto());
builder.SetIsFixedInlineSize(is_fixed_inline_size);
builder.SetIsFixedBlockSize(is_fixed_block_size);
- if (node.IsLayoutNGCustom())
+ builder.SetNeedsBaseline(true);
+ if (child.IsLayoutNGCustom())
builder.SetCustomLayoutData(std::move(constraint_data_));
auto space = builder.ToConstraintSpace();
- auto result = To<NGBlockNode>(node).Layout(space, nullptr /* break_token */);
+ auto result = To<NGBlockNode>(child).Layout(space, nullptr /* break_token */);
- LogicalSize size = result->PhysicalFragment().Size().ConvertToLogical(
- parent_space.GetWritingMode());
+ NGBoxFragment fragment(parent_space.GetWritingMode(),
+ parent_space.Direction(),
+ To<NGPhysicalBoxFragment>(result->PhysicalFragment()));
resolver_->Resolve(MakeGarbageCollected<CustomLayoutFragment>(
- child_, token_, std::move(result), size,
+ child_, token_, std::move(result), fragment.Size(), fragment.Baseline(),
resolver_->GetScriptState()->GetIsolate()));
}
+void CustomLayoutWorkTask::RunIntrinsicSizesTask(
+ const ComputedStyle& parent_style,
+ const LayoutUnit child_percentage_resolution_block_size_for_min_max,
+ NGLayoutInputNode child) {
+ DCHECK_EQ(type_, CustomLayoutWorkTask::TaskType::kIntrinsicSizes);
+ DCHECK(resolver_);
+
+ MinMaxSizesInput input(child_percentage_resolution_block_size_for_min_max);
+ MinMaxSizes sizes =
+ ComputeMinAndMaxContentContribution(parent_style, child, input);
+ resolver_->Resolve(MakeGarbageCollected<CustomIntrinsicSizes>(
+ child_, token_, sizes.min_size, sizes.max_size));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.h b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.h
index 5038048ed31..7aacc7fce5c 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/custom_layout_work_task.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_CUSTOM_CUSTOM_LAYOUT_WORK_TASK_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_CUSTOM_CUSTOM_LAYOUT_WORK_TASK_H_
-#include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_constraints_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_custom_layout_constraints_options.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -14,7 +14,9 @@ namespace blink {
class ComputedStyle;
class CustomLayoutChild;
class CustomLayoutToken;
+class LayoutUnit;
class NGConstraintSpace;
+class NGLayoutInputNode;
class SerializedScriptValue;
class ScriptPromiseResolver;
@@ -22,16 +24,30 @@ class ScriptPromiseResolver;
// intrinsic-sizes.
class CustomLayoutWorkTask {
public:
+ enum TaskType {
+ kLayoutFragment,
+ kIntrinsicSizes,
+ };
+
+ // Used when resolving a promise with intrinsic-sizes.
+ CustomLayoutWorkTask(CustomLayoutChild*,
+ CustomLayoutToken*,
+ ScriptPromiseResolver*,
+ const TaskType type);
+
+ // Used when resolving a promise with a fragment.
CustomLayoutWorkTask(CustomLayoutChild*,
CustomLayoutToken*,
ScriptPromiseResolver*,
const CustomLayoutConstraintsOptions*,
- scoped_refptr<SerializedScriptValue> constraint_data);
+ scoped_refptr<SerializedScriptValue> constraint_data,
+ const TaskType type);
~CustomLayoutWorkTask();
// Runs this work task.
void Run(const NGConstraintSpace& parent_space,
- const ComputedStyle& parent_style);
+ const ComputedStyle& parent_style,
+ const LayoutUnit child_percentage_resolution_block_size_for_min_max);
private:
Persistent<CustomLayoutChild> child_;
@@ -39,6 +55,15 @@ class CustomLayoutWorkTask {
Persistent<ScriptPromiseResolver> resolver_;
Persistent<const CustomLayoutConstraintsOptions> options_;
scoped_refptr<SerializedScriptValue> constraint_data_;
+ TaskType type_;
+
+ void RunLayoutFragmentTask(const NGConstraintSpace& parent_space,
+ const ComputedStyle& parent_style,
+ NGLayoutInputNode child);
+ void RunIntrinsicSizesTask(
+ const ComputedStyle& parent_style,
+ const LayoutUnit child_percentage_resolution_block_size_for_min_max,
+ NGLayoutInputNode child);
};
} // namespace blink
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 3d60b887d1c..c68765b9107 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(blink::Visitor* visitor) {
+void DocumentLayoutDefinition::Trace(Visitor* visitor) {
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 2a8e359b1cf..0c2d8bce246 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(blink::Visitor*);
+ virtual void Trace(Visitor*);
private:
bool IsEqual(const CSSLayoutDefinition&);
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/fragment_result_options.idl b/chromium/third_party/blink/renderer/core/layout/ng/custom/fragment_result_options.idl
index 376cc5be01c..28867d89dc6 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/fragment_result_options.idl
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/fragment_result_options.idl
@@ -6,6 +6,7 @@
dictionary FragmentResultOptions {
double autoBlockSize = 0;
+ double baseline;
sequence<LayoutFragment> childFragments = [];
any data = null;
};
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/intrinsic_sizes.idl b/chromium/third_party/blink/renderer/core/layout/ng/custom/intrinsic_sizes.idl
new file mode 100644
index 00000000000..5864a0720a0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/intrinsic_sizes.idl
@@ -0,0 +1,15 @@
+// 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://drafts.css-houdini.org/css-layout-api/#intrinsicsizes
+
+[
+ Exposed=LayoutWorklet,
+ ImplementedAs=CustomIntrinsicSizes,
+ RuntimeEnabled=CSSLayoutAPI
+]
+interface IntrinsicSizes {
+ readonly attribute double minContentSize;
+ readonly attribute double maxContentSize;
+};
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/intrinsic_sizes_result_options.idl b/chromium/third_party/blink/renderer/core/layout/ng/custom/intrinsic_sizes_result_options.idl
new file mode 100644
index 00000000000..aa3ae7d453b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/intrinsic_sizes_result_options.idl
@@ -0,0 +1,10 @@
+// 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://drafts.css-houdini.org/css-layout-api/#dictdef-intrinsicsizesresultoptions
+
+dictionary IntrinsicSizesResultOptions {
+ double minContentSize = 0;
+ double maxContentSize = 0;
+};
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_child.idl b/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_child.idl
index 3940849802c..76ba3c49d42 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_child.idl
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_child.idl
@@ -12,7 +12,7 @@
interface LayoutChild {
readonly attribute StylePropertyMapReadOnly styleMap;
- // IntrinsicSizesRequest intrinsicSizes();
- [CallWith=ScriptState, RaisesException] Promise<LayoutFragment> layoutNextFragment(optional CustomLayoutConstraintsOptions options);
+ [CallWith=ScriptState, RaisesException] Promise<IntrinsicSizes> intrinsicSizes();
+ [CallWith=ScriptState, RaisesException] Promise<LayoutFragment> layoutNextFragment(optional CustomLayoutConstraintsOptions options = {});
};
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_fragment.idl b/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_fragment.idl
index e142bcd24b3..110744df579 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_fragment.idl
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_fragment.idl
@@ -16,5 +16,7 @@ interface LayoutFragment {
attribute double inlineOffset;
attribute double blockOffset;
+ readonly attribute double? baseline;
+
[CallWith=ScriptState] readonly attribute any data;
};
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_ng_custom.cc b/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_ng_custom.cc
index 254c5354891..b49d3c51ad4 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_ng_custom.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_ng_custom.cc
@@ -15,6 +15,27 @@ LayoutNGCustom::LayoutNGCustom(Element* element)
DCHECK(element);
}
+void LayoutNGCustom::AddChild(LayoutObject* new_child,
+ LayoutObject* before_child) {
+ // Only use the block-flow AddChild logic when we are unloaded, i.e. we
+ // should behave exactly like a block-flow.
+ if (state_ == kUnloaded) {
+ LayoutNGBlockFlow::AddChild(new_child, before_child);
+ return;
+ }
+ LayoutBlock::AddChild(new_child, before_child);
+}
+
+void LayoutNGCustom::RemoveChild(LayoutObject* child) {
+ // Only use the block-flow RemoveChild logic when we are unloaded, i.e. we
+ // should behave exactly like a block-flow.
+ if (state_ == kUnloaded) {
+ LayoutNGBlockFlow::RemoveChild(child);
+ return;
+ }
+ LayoutBlock::RemoveChild(child);
+}
+
void LayoutNGCustom::StyleDidChange(StyleDifference diff,
const ComputedStyle* old_style) {
if (state_ == kUnloaded) {
@@ -35,6 +56,11 @@ void LayoutNGCustom::StyleDidChange(StyleDifference diff,
}
}
+ // Make our children "block-level" before invoking StyleDidChange. As the
+ // current multi-col logic may invoke a call to AddChild, failing a DCHECK.
+ if (state_ != kUnloaded)
+ SetChildrenInline(false);
+
// TODO(ikilpatrick): Investigate reducing the properties which
// LayoutNGBlockFlow::StyleDidChange invalidates upon. (For example margins).
LayoutNGBlockFlow::StyleDidChange(diff, old_style);
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_ng_custom.h b/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_ng_custom.h
index 3b80651d205..95f0f3d0dae 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_ng_custom.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_ng_custom.h
@@ -30,6 +30,9 @@ class LayoutNGCustom final : public LayoutNGBlockFlow {
bool IsLoaded() { return state_ != kUnloaded; }
+ void AddChild(LayoutObject* new_child, LayoutObject* before_child) override;
+ void RemoveChild(LayoutObject* child) override;
+
void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
private:
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 6986d303d97..71e6bb85888 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(blink::Visitor* visitor) {
+void LayoutWorklet::Trace(Visitor* visitor) {
visitor->Trace(document_definition_map_);
visitor->Trace(pending_layout_registry_);
Worklet::Trace(visitor);
@@ -59,8 +59,9 @@ bool LayoutWorklet::NeedsToCreateGlobalScope() {
WorkletGlobalScopeProxy* LayoutWorklet::CreateGlobalScope() {
DCHECK(NeedsToCreateGlobalScope());
return MakeGarbageCollected<LayoutWorkletGlobalScopeProxy>(
- To<Document>(GetExecutionContext())->GetFrame(), ModuleResponsesMap(),
- pending_layout_registry_, GetNumberOfGlobalScopes() + 1);
+ To<LocalDOMWindow>(GetExecutionContext())->GetFrame(),
+ ModuleResponsesMap(), pending_layout_registry_,
+ GetNumberOfGlobalScopes() + 1);
}
} // namespace blink
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 3c433e4920b..19d91dd9a97 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
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/core/layout/ng/custom/pending_layout_registry.h"
#include "third_party/blink/renderer/core/workers/worklet.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/supplementable.h"
namespace blink {
@@ -46,7 +47,7 @@ class CORE_EXPORT LayoutWorklet : public Worklet,
void AddPendingLayout(const AtomicString& name, Node*);
LayoutWorkletGlobalScopeProxy* Proxy();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 a953e2ef0e8..77870594359 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
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_function.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_intrinsic_sizes_callback.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_layout_callback.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_no_argument_constructor.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_object_parser.h"
@@ -36,12 +37,12 @@ LayoutWorkletGlobalScope* LayoutWorkletGlobalScope::Create(
auto* isolate = ToIsolate(frame);
auto microtask_queue =
v8::MicrotaskQueue::New(isolate, v8::MicrotasksPolicy::kScoped);
- auto* agent = Agent::CreateForWorkerOrWorklet(
- isolate,
- creation_params->agent_cluster_id.is_empty()
- ? base::UnguessableToken::Create()
- : creation_params->agent_cluster_id,
- std::move(microtask_queue));
+ auto* agent =
+ MakeGarbageCollected<Agent>(isolate,
+ creation_params->agent_cluster_id.is_empty()
+ ? base::UnguessableToken::Create()
+ : creation_params->agent_cluster_id,
+ std::move(microtask_queue));
auto* global_scope = MakeGarbageCollected<LayoutWorkletGlobalScope>(
frame, std::move(creation_params), reporting_proxy,
pending_layout_registry, agent);
@@ -103,7 +104,8 @@ void LayoutWorkletGlobalScope::registerLayout(
Vector<AtomicString> custom_invalidation_properties;
if (!V8ObjectParser::ParseCSSPropertyList(
- current_context, layout_ctor->CallbackObject(), "inputProperties",
+ current_context, GetFrame()->DomWindow(),
+ layout_ctor->CallbackObject(), "inputProperties",
&native_invalidation_properties, &custom_invalidation_properties,
&exception_state))
return;
@@ -112,8 +114,9 @@ void LayoutWorkletGlobalScope::registerLayout(
Vector<AtomicString> child_custom_invalidation_properties;
if (!V8ObjectParser::ParseCSSPropertyList(
- current_context, layout_ctor->CallbackObject(),
- "childInputProperties", &child_native_invalidation_properties,
+ current_context, GetFrame()->DomWindow(),
+ layout_ctor->CallbackObject(), "childInputProperties",
+ &child_native_invalidation_properties,
&child_custom_invalidation_properties, &exception_state))
return;
@@ -126,7 +129,8 @@ void LayoutWorkletGlobalScope::registerLayout(
retriever.GetMethodOrThrow("intrinsicSizes", exception_state);
if (exception_state.HadException())
return;
- V8Function* intrinsic_sizes = V8Function::Create(v8_intrinsic_sizes);
+ V8IntrinsicSizesCallback* intrinsic_sizes =
+ V8IntrinsicSizesCallback::Create(v8_intrinsic_sizes);
v8::Local<v8::Function> v8_layout =
retriever.GetMethodOrThrow("layout", exception_state);
@@ -141,8 +145,7 @@ void LayoutWorkletGlobalScope::registerLayout(
child_custom_invalidation_properties);
layout_definitions_.Set(name, definition);
- LayoutWorklet* layout_worklet =
- LayoutWorklet::From(*GetFrame()->GetDocument()->domWindow());
+ LayoutWorklet* layout_worklet = LayoutWorklet::From(*GetFrame()->DomWindow());
LayoutWorklet::DocumentDefinitionMap* document_definition_map =
layout_worklet->GetDocumentDefinitionMap();
if (document_definition_map->Contains(name)) {
@@ -177,7 +180,7 @@ CSSLayoutDefinition* LayoutWorkletGlobalScope::FindDefinition(
return layout_definitions_.at(name);
}
-void LayoutWorkletGlobalScope::Trace(blink::Visitor* visitor) {
+void LayoutWorkletGlobalScope::Trace(Visitor* visitor) {
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 642e9af4527..d920e67f8d3 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
@@ -45,7 +45,7 @@ class CORE_EXPORT LayoutWorkletGlobalScope final : public WorkletGlobalScope {
CSSLayoutDefinition* FindDefinition(const AtomicString& name);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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.idl b/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.idl
index 5ce4982e351..63a233f5461 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.idl
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope.idl
@@ -15,3 +15,7 @@
// Blink-specific type for layout function
// https://drafts.css-houdini.org/css-layout-api/#layout-definition-layout-function
callback LayoutCallback = any (sequence<LayoutChild> children, LayoutEdges edges, LayoutConstraints constraints, StylePropertyMapReadOnly styleMap);
+
+// Blink-specific type for intrinsicSizes function
+// https://drafts.css-houdini.org/css-layout-api/#layout-definition-intrinsic-sizes-function
+callback IntrinsicSizesCallback = any (sequence<LayoutChild> children, LayoutEdges edges, StylePropertyMapReadOnly styleMap);
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 781452633d4..b71ceac3b78 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
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
#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/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/loader/worker_fetch_context.h"
@@ -40,15 +41,16 @@ LayoutWorkletGlobalScopeProxy::LayoutWorkletGlobalScopeProxy(
StringView("LayoutWorklet #") + String::Number(global_scope_number);
auto creation_params = std::make_unique<GlobalScopeCreationParams>(
- document->Url(), mojom::ScriptType::kModule,
- OffMainThreadWorkerScriptFetchOption::kEnabled, global_scope_name,
- document->UserAgent(), frame->Client()->CreateWorkerFetchContext(),
+ document->Url(), mojom::blink::ScriptType::kModule, global_scope_name,
+ document->UserAgent(), frame->Client()->UserAgentMetadata(),
+ frame->Client()->CreateWorkerFetchContext(),
document->GetContentSecurityPolicy()->Headers(),
document->GetReferrerPolicy(), document->GetSecurityOrigin(),
document->IsSecureContext(), document->GetHttpsState(),
nullptr /* worker_clients */,
frame->Client()->CreateWorkerContentSettingsClient(),
- document->AddressSpace(), OriginTrialContext::GetTokens(document).get(),
+ document->GetSecurityContext().AddressSpace(),
+ OriginTrialContext::GetTokens(frame->DomWindow()).get(),
base::UnguessableToken::Create(), nullptr /* worker_settings */,
kV8CacheOptionsDefault, module_responses_map,
mojo::NullRemote() /* browser_interface_broker */,
@@ -92,7 +94,7 @@ CSSLayoutDefinition* LayoutWorkletGlobalScopeProxy::FindDefinition(
return global_scope_->FindDefinition(name);
}
-void LayoutWorkletGlobalScopeProxy::Trace(blink::Visitor* visitor) {
+void LayoutWorkletGlobalScopeProxy::Trace(Visitor* visitor) {
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 46837b1ea3a..de993758af3 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 2e7297a2fd7..c763349959b 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
@@ -5,11 +5,12 @@
#include "third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_fragment_result_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_intrinsic_sizes_result_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/layout/ng/custom/custom_layout_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_scope.h"
-#include "third_party/blink/renderer/core/layout/ng/custom/fragment_result_options.h"
#include "third_party/blink/renderer/core/layout/ng/custom/layout_worklet.h"
#include "third_party/blink/renderer/core/layout/ng/custom/layout_worklet_global_scope_proxy.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h"
@@ -30,13 +31,55 @@ NGCustomLayoutAlgorithm::NGCustomLayoutAlgorithm(
container_builder_.SetIsNewFormattingContext(
params.space.IsNewFormattingContext());
container_builder_.SetInitialFragmentGeometry(params.fragment_geometry);
+ const NGConstraintSpace& space = ConstraintSpace();
+ child_percentage_resolution_block_size_for_min_max_ =
+ CalculateChildPercentageBlockSizeForMinMax(
+ space, Node(), border_padding_,
+ space.PercentageResolutionBlockSize());
}
-base::Optional<MinMaxSize> NGCustomLayoutAlgorithm::ComputeMinMaxSize(
- const MinMaxSizeInput& input) const {
- // TODO(ikilpatrick): Invoke the web-developer defined "intrinsicSizes"
- // method.
- return FallbackMinMaxSize(input);
+base::Optional<MinMaxSizes> NGCustomLayoutAlgorithm::ComputeMinMaxSizes(
+ const MinMaxSizesInput& input) const {
+ if (!Node().IsCustomLayoutLoaded())
+ return FallbackMinMaxSizes(input);
+
+ ScriptForbiddenScope::AllowUserAgentScript allow_script;
+ CustomLayoutScope scope;
+
+ const AtomicString& name = Style().DisplayLayoutCustomName();
+ const Document& document = Node().GetDocument();
+ LayoutWorklet* worklet = LayoutWorklet::From(*document.domWindow());
+ CSSLayoutDefinition* definition = worklet->Proxy()->FindDefinition(name);
+
+ // TODO(ikilpatrick): Cache the instance of the layout class.
+ CSSLayoutDefinition::Instance* instance = definition->CreateInstance();
+
+ if (!instance) {
+ // TODO(ikilpatrick): Report this error to the developer.
+ return FallbackMinMaxSizes(input);
+ }
+
+ IntrinsicSizesResultOptions* intrinsic_sizes_result_options = nullptr;
+ if (!instance->IntrinsicSizes(
+ ConstraintSpace(), document, Node(),
+ container_builder_.InitialBorderBoxSize(), border_scrollbar_padding_,
+ child_percentage_resolution_block_size_for_min_max_, &scope,
+ intrinsic_sizes_result_options)) {
+ // TODO(ikilpatrick): Report this error to the developer.
+ return FallbackMinMaxSizes(input);
+ }
+
+ MinMaxSizes sizes;
+ sizes.max_size = LayoutUnit::FromDoubleRound(
+ intrinsic_sizes_result_options->maxContentSize());
+ sizes.min_size = std::min(
+ sizes.max_size, LayoutUnit::FromDoubleRound(
+ intrinsic_sizes_result_options->minContentSize()));
+
+ sizes.min_size.ClampNegativeToZero();
+ sizes.max_size.ClampNegativeToZero();
+
+ return sizes;
}
scoped_refptr<const NGLayoutResult> NGCustomLayoutAlgorithm::Layout() {
@@ -61,13 +104,13 @@ scoped_refptr<const NGLayoutResult> NGCustomLayoutAlgorithm::Layout() {
return FallbackLayout();
}
- FragmentResultOptions* fragment_result_options =
- FragmentResultOptions::Create();
+ FragmentResultOptions* fragment_result_options = nullptr;
scoped_refptr<SerializedScriptValue> fragment_result_data;
- if (!instance->Layout(ConstraintSpace(), document, Node(),
- container_builder_.InitialBorderBoxSize(),
- border_scrollbar_padding_, &scope,
- fragment_result_options, &fragment_result_data)) {
+ if (!instance->Layout(
+ ConstraintSpace(), document, Node(),
+ container_builder_.InitialBorderBoxSize(), border_scrollbar_padding_,
+ child_percentage_resolution_block_size_for_min_max_, &scope,
+ fragment_result_options, &fragment_result_data)) {
// TODO(ikilpatrick): Report this error to the developer.
return FallbackLayout();
}
@@ -123,6 +166,12 @@ scoped_refptr<const NGLayoutResult> NGCustomLayoutAlgorithm::Layout() {
LayoutUnit block_size = ComputeBlockSizeForFragment(
ConstraintSpace(), Style(), border_padding_, auto_block_size);
+ if (fragment_result_options->hasBaseline()) {
+ LayoutUnit baseline =
+ LayoutUnit::FromDoubleRound(fragment_result_options->baseline());
+ container_builder_.SetBaseline(baseline);
+ }
+
container_builder_.SetCustomLayoutData(std::move(fragment_result_data));
container_builder_.SetIntrinsicBlockSize(auto_block_size);
container_builder_.SetBlockSize(block_size);
@@ -151,10 +200,10 @@ void NGCustomLayoutAlgorithm::AddAnyOutOfFlowPositionedChildren(
}
}
-base::Optional<MinMaxSize> NGCustomLayoutAlgorithm::FallbackMinMaxSize(
- const MinMaxSizeInput& input) const {
+base::Optional<MinMaxSizes> NGCustomLayoutAlgorithm::FallbackMinMaxSizes(
+ const MinMaxSizesInput& input) const {
NGBlockLayoutAlgorithm algorithm(params_);
- return algorithm.ComputeMinMaxSize(input);
+ return algorithm.ComputeMinMaxSizes(input);
}
scoped_refptr<const NGLayoutResult> NGCustomLayoutAlgorithm::FallbackLayout() {
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 7725387252a..5a43340b4a0 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
@@ -20,18 +20,20 @@ class CORE_EXPORT NGCustomLayoutAlgorithm
public:
NGCustomLayoutAlgorithm(const NGLayoutAlgorithmParams& params);
- base::Optional<MinMaxSize> ComputeMinMaxSize(
- const MinMaxSizeInput&) const override;
+ base::Optional<MinMaxSizes> ComputeMinMaxSizes(
+ const MinMaxSizesInput&) const override;
scoped_refptr<const NGLayoutResult> Layout() override;
private:
void AddAnyOutOfFlowPositionedChildren(NGLayoutInputNode* child);
- base::Optional<MinMaxSize> FallbackMinMaxSize(const MinMaxSizeInput&) const;
+ base::Optional<MinMaxSizes> FallbackMinMaxSizes(
+ const MinMaxSizesInput&) const;
scoped_refptr<const NGLayoutResult> FallbackLayout();
const NGLayoutAlgorithmParams& params_;
const NGBoxStrut border_padding_;
const NGBoxStrut border_scrollbar_padding_;
+ LayoutUnit child_percentage_resolution_block_size_for_min_max_;
};
} // 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 4239b4da920..644f324ac9c 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(blink::Visitor* visitor) {
+void PendingLayoutRegistry::Trace(Visitor* visitor) {
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 ba74e988d1b..8afe379befd 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(blink::Visitor*);
+ void Trace(Visitor*);
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/exclusions/ng_layout_opportunity.cc b/chromium/third_party/blink/renderer/core/layout/ng/exclusions/ng_layout_opportunity.cc
index 0672d751fc4..250278fdfba 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/exclusions/ng_layout_opportunity.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/exclusions/ng_layout_opportunity.cc
@@ -96,17 +96,6 @@ bool NGLayoutOpportunity::IsBlockDeltaBelowShapes(
return true;
}
-NGLineLayoutOpportunity NGLayoutOpportunity::ComputeLineLayoutOpportunity(
- const NGConstraintSpace& space,
- LayoutUnit line_block_size,
- LayoutUnit block_delta) const {
- return NGLineLayoutOpportunity(
- ComputeLineLeftOffset(space, line_block_size, block_delta),
- ComputeLineRightOffset(space, line_block_size, block_delta),
- rect.LineStartOffset(), rect.LineEndOffset(),
- rect.BlockStartOffset() + block_delta, line_block_size);
-}
-
LayoutUnit NGLayoutOpportunity::ComputeLineLeftOffset(
const NGConstraintSpace& space,
LayoutUnit line_block_size,
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/exclusions/ng_layout_opportunity.h b/chromium/third_party/blink/renderer/core/layout/ng/exclusions/ng_layout_opportunity.h
index abf46f88fff..58734340c0b 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/exclusions/ng_layout_opportunity.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/exclusions/ng_layout_opportunity.h
@@ -47,9 +47,15 @@ struct CORE_EXPORT NGLayoutOpportunity {
// Calculates a line layout opportunity which takes into account any shapes
// which may affect the available inline size for the line breaker.
NGLineLayoutOpportunity ComputeLineLayoutOpportunity(
- const NGConstraintSpace&,
+ const NGConstraintSpace& space,
LayoutUnit line_block_size,
- LayoutUnit block_delta) const;
+ LayoutUnit block_delta) const {
+ return NGLineLayoutOpportunity(
+ ComputeLineLeftOffset(space, line_block_size, block_delta),
+ ComputeLineRightOffset(space, line_block_size, block_delta),
+ rect.LineStartOffset(), rect.LineEndOffset(),
+ rect.BlockStartOffset() + block_delta, line_block_size);
+ }
private:
LayoutUnit ComputeLineLeftOffset(const NGConstraintSpace&,
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h b/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h
index f5c78a92dad..3c01e9f6085 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h
@@ -118,6 +118,10 @@ struct CORE_EXPORT NGLineBoxStrut {
LayoutUnit InlineSum() const { return inline_start + inline_end; }
LayoutUnit BlockSum() const { return line_over + line_under; }
+ bool IsEmpty() const {
+ return !inline_start && !inline_end && !line_over && !line_under;
+ }
+
bool operator==(const NGLineBoxStrut& other) const {
return inline_start == other.inline_start &&
inline_end == other.inline_end && line_over == other.line_over &&
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_margin_strut.h b/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_margin_strut.h
index 8236afa14ee..759d7091b66 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_margin_strut.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/geometry/ng_margin_strut.h
@@ -26,8 +26,7 @@ struct CORE_EXPORT NGMarginStrut {
// See comment inside NGBlockLayoutAlgorithm for when this occurs.
bool is_quirky_container_start = false;
- // If set, we will discard all adjoining margins, which is the
- // effect of -webkit-margin-collapse:discard.
+ // If set, we will discard all adjoining margins.
bool discard_margins = false;
// Appends negative or positive value to the current margin strut.
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 bd55b43700a..da28e31bfcf 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
@@ -47,6 +47,20 @@ class LayoutNGTextTest : public PageTestBase {
}
};
+TEST_F(LayoutNGTextTest, SetTextWithOffsetAppendBidi) {
+ if (!RuntimeEnabledFeatures::LayoutNGEnabled())
+ return;
+
+ SetBodyInnerHTML(u"<div dir=rtl id=target>\u05D0\u05D1\u05BC\u05D2</div>");
+ Text& text = To<Text>(*GetElementById("target")->firstChild());
+ text.appendData(u"\u05D0\u05D1\u05BC\u05D2");
+
+ EXPECT_EQ(String(u"*{'\u05D0\u05D1\u05BC\u05D2\u05D0\u05D1\u05BC\u05D2', "
+ u"ShapeResult=0+8}\n")
+ .Utf8(),
+ GetItemsAsString(*text.GetLayoutObject()));
+}
+
TEST_F(LayoutNGTextTest, SetTextWithOffsetAppendControl) {
if (!RuntimeEnabledFeatures::LayoutNGEnabled())
return;
@@ -136,8 +150,11 @@ TEST_F(LayoutNGTextTest, SetTextWithOffsetDeleteRTL) {
Text& text = To<Text>(*GetElementById("target")->firstChild());
text.deleteData(2, 2, ASSERT_NO_EXCEPTION); // remove "23"
- EXPECT_EQ("*{'0 4', ShapeResult=0+3}\n",
- GetItemsAsString(*text.GetLayoutObject()));
+ EXPECT_EQ(
+ "*{'0', ShapeResult=0+1}\n"
+ "*{' ', ShapeResult=1+1}\n"
+ "*{'4', ShapeResult=2+1}\n",
+ GetItemsAsString(*text.GetLayoutObject()));
}
// http://crbug.com/1000685
@@ -149,7 +166,26 @@ TEST_F(LayoutNGTextTest, SetTextWithOffsetDeleteRTL2) {
Text& text = To<Text>(*GetElementById("target")->firstChild());
text.deleteData(0, 1, ASSERT_NO_EXCEPTION); // remove "0"
- EXPECT_EQ("*{'(xy)5', ShapeResult=0+5}\n",
+ EXPECT_EQ(
+ "*{'(', ShapeResult=0+1}\n"
+ "*{'xy', ShapeResult=1+2}\n"
+ "*{')', ShapeResult=3+1}\n"
+ "*{'5', ShapeResult=4+1}\n",
+ GetItemsAsString(*text.GetLayoutObject()));
+}
+
+// http://crbug.com/1039143
+TEST_F(LayoutNGTextTest, SetTextWithOffsetDeleteWithBidiControl) {
+ if (!RuntimeEnabledFeatures::LayoutNGEnabled())
+ return;
+
+ // In text content, we have bidi control codes:
+ // U+2066 U+2069 \n U+2066 abc U+2066
+ SetBodyInnerHTML(u"<pre><b id=target dir=ltr>\nabc</b></pre>");
+ Text& text = To<Text>(*GetElementById("target")->firstChild());
+ text.deleteData(0, 1, ASSERT_NO_EXCEPTION); // remove "\n"
+
+ EXPECT_EQ("LayoutText has NeedsCollectInlines",
GetItemsAsString(*text.GetLayoutObject()));
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.cc
index 8a5f0a7201d..34643cd55f2 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.cc
@@ -5,7 +5,10 @@
#include "third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.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_break_token.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.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_physical_text_fragment.h"
#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
@@ -16,38 +19,90 @@
namespace blink {
-NGAbstractInlineTextBox::FragmentToNGAbstractInlineTextBoxHashMap*
- NGAbstractInlineTextBox::g_abstract_inline_text_box_map_ = nullptr;
+namespace {
+
+// Mapping from NGFragmentItem/NGPaintFragment to NGAbstractInlineTextBox
+// TODO(yosin): Once we get rid of |NGPaintFragment|, we should not use
+// template class for |NGAbstractInlineTextBoxCache|.
+template <typename Fragment>
+class NGAbstractInlineTextBoxCache final {
+ public:
+ static scoped_refptr<AbstractInlineTextBox> GetOrCreate(
+ const Fragment& fragment) {
+ if (!s_instance_)
+ s_instance_ = new NGAbstractInlineTextBoxCache();
+ return s_instance_->GetOrCreateInternal(fragment);
+ }
+
+ static void WillDestroy(const Fragment* fragment) {
+ if (!s_instance_)
+ return;
+ s_instance_->WillDestroyInternal(fragment);
+ }
+
+ private:
+ scoped_refptr<AbstractInlineTextBox> GetOrCreateInternal(
+ const Fragment& fragment) {
+ const auto it = map_.find(&fragment);
+ LayoutText* const layout_text =
+ ToLayoutText(fragment.GetMutableLayoutObject());
+ if (it != map_.end()) {
+ CHECK(layout_text->HasAbstractInlineTextBox());
+ return it->value;
+ }
+ scoped_refptr<AbstractInlineTextBox> obj = base::AdoptRef(
+ new NGAbstractInlineTextBox(LineLayoutText(layout_text), fragment));
+ map_.Set(&fragment, obj);
+ layout_text->SetHasAbstractInlineTextBox();
+ return obj;
+ }
+
+ void WillDestroyInternal(const Fragment* fragment) {
+ const auto it = map_.find(fragment);
+ if (it == map_.end())
+ return;
+ it->value->Detach();
+ map_.erase(fragment);
+ }
+
+ static NGAbstractInlineTextBoxCache* s_instance_;
+
+ HashMap<const Fragment*, scoped_refptr<AbstractInlineTextBox>> map_;
+};
+
+template <typename Fragment>
+NGAbstractInlineTextBoxCache<Fragment>*
+ NGAbstractInlineTextBoxCache<Fragment>::s_instance_ = nullptr;
+
+} // namespace
scoped_refptr<AbstractInlineTextBox> NGAbstractInlineTextBox::GetOrCreate(
- const NGPaintFragment& fragment) {
- DCHECK(fragment.GetLayoutObject()->IsText()) << fragment.GetLayoutObject();
- if (!g_abstract_inline_text_box_map_) {
- g_abstract_inline_text_box_map_ =
- new FragmentToNGAbstractInlineTextBoxHashMap();
+ const NGInlineCursor& cursor) {
+ if (const NGPaintFragment* paint_fragment = cursor.CurrentPaintFragment()) {
+ return NGAbstractInlineTextBoxCache<NGPaintFragment>::GetOrCreate(
+ *paint_fragment);
}
- const auto it = g_abstract_inline_text_box_map_->find(&fragment);
- LayoutText* const layout_text =
- ToLayoutText(fragment.GetMutableLayoutObject());
- if (it != g_abstract_inline_text_box_map_->end()) {
- CHECK(layout_text->HasAbstractInlineTextBox());
- return it->value;
+ if (const NGFragmentItem* fragment_item = cursor.CurrentItem()) {
+ return NGAbstractInlineTextBoxCache<NGFragmentItem>::GetOrCreate(
+ *fragment_item);
}
- scoped_refptr<AbstractInlineTextBox> obj = base::AdoptRef(
- new NGAbstractInlineTextBox(LineLayoutText(layout_text), fragment));
- g_abstract_inline_text_box_map_->Set(&fragment, obj);
- layout_text->SetHasAbstractInlineTextBox();
- return obj;
+ return nullptr;
}
-void NGAbstractInlineTextBox::WillDestroy(NGPaintFragment* fragment) {
- if (!g_abstract_inline_text_box_map_)
- return;
- const auto it = g_abstract_inline_text_box_map_->find(fragment);
- if (it != g_abstract_inline_text_box_map_->end()) {
- it->value->Detach();
- g_abstract_inline_text_box_map_->erase(fragment);
+void NGAbstractInlineTextBox::WillDestroy(const NGInlineCursor& cursor) {
+ if (const NGPaintFragment* paint_fragment = cursor.CurrentPaintFragment()) {
+ return NGAbstractInlineTextBoxCache<NGPaintFragment>::WillDestroy(
+ paint_fragment);
+ }
+ if (const NGFragmentItem* fragment_item = cursor.CurrentItem()) {
+ return NGAbstractInlineTextBoxCache<NGFragmentItem>::WillDestroy(
+ fragment_item);
}
+ NOTREACHED();
+}
+
+void NGAbstractInlineTextBox::WillDestroy(const NGPaintFragment* fragment) {
+ NGAbstractInlineTextBoxCache<NGPaintFragment>::WillDestroy(fragment);
}
NGAbstractInlineTextBox::NGAbstractInlineTextBox(
@@ -57,6 +112,13 @@ NGAbstractInlineTextBox::NGAbstractInlineTextBox(
DCHECK(fragment_->PhysicalFragment().IsText()) << fragment_;
}
+NGAbstractInlineTextBox::NGAbstractInlineTextBox(
+ LineLayoutText line_layout_item,
+ const NGFragmentItem& fragment_item)
+ : AbstractInlineTextBox(line_layout_item), fragment_item_(&fragment_item) {
+ DCHECK(fragment_item_->IsText()) << fragment_item_;
+}
+
NGAbstractInlineTextBox::~NGAbstractInlineTextBox() {
DCHECK(!fragment_);
}
@@ -70,107 +132,128 @@ void NGAbstractInlineTextBox::Detach() {
fragment_ = nullptr;
}
-const NGPhysicalTextFragment& NGAbstractInlineTextBox::PhysicalTextFragment()
- const {
- return To<NGPhysicalTextFragment>(fragment_->PhysicalFragment());
+NGInlineCursor NGAbstractInlineTextBox::GetCursor() const {
+ if (!fragment_item_)
+ return NGInlineCursor();
+ NGInlineCursor cursor;
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ cursor.MoveTo(*fragment_item_);
+ else
+ cursor.MoveTo(*fragment_);
+ DCHECK(!cursor.Current().GetLayoutObject()->NeedsLayout());
+ return cursor;
+}
+
+NGInlineCursor NGAbstractInlineTextBox::GetCursorOnLine() const {
+ NGInlineCursor current = GetCursor();
+ NGInlineCursor line_box = current;
+ line_box.MoveToContainingLine();
+ NGInlineCursor cursor = line_box.CursorForDescendants();
+ cursor.MoveTo(current);
+ return cursor;
}
-bool NGAbstractInlineTextBox::NeedsLayout() const {
- return fragment_->GetLayoutObject()->NeedsLayout();
+String NGAbstractInlineTextBox::GetTextContent() const {
+ const NGInlineCursor& cursor = GetCursor();
+ if (cursor.Current().IsGeneratedTextType())
+ return cursor.Current().Text(cursor).ToString();
+ if (const NGPaintFragment* paint_fragment = cursor.CurrentPaintFragment()) {
+ return To<NGPhysicalTextFragment>(paint_fragment->PhysicalFragment())
+ .TextContent();
+ }
+ return cursor.Items().Text(cursor.Current().UsesFirstLineStyle());
}
bool NGAbstractInlineTextBox::NeedsTrailingSpace() const {
- if (!fragment_->Style().CollapseWhiteSpace())
+ const NGInlineCursor& cursor = GetCursor();
+ if (!cursor.Current().Style().CollapseWhiteSpace())
return false;
- const NGPaintFragment& line_box = *fragment_->ContainerLineBox();
- if (!To<NGPhysicalLineBoxFragment>(line_box.PhysicalFragment())
- .HasSoftWrapToNextLine())
+ NGInlineCursor line_box = cursor;
+ line_box.MoveToContainingLine();
+ if (!line_box.HasSoftWrapToNextLine())
return false;
- const NGPhysicalTextFragment& text_fragment = PhysicalTextFragment();
- if (text_fragment.EndOffset() >= text_fragment.TextContent().length())
+ const String text_content = GetTextContent();
+ const unsigned end_offset = cursor.Current().TextEndOffset();
+ if (end_offset >= text_content.length())
return false;
- if (text_fragment.TextContent()[text_fragment.EndOffset()] != ' ')
+ if (text_content[end_offset] != ' ')
return false;
- const NGInlineBreakToken& break_token = *To<NGInlineBreakToken>(
- To<NGPhysicalLineBoxFragment>(line_box.PhysicalFragment()).BreakToken());
+ const NGInlineBreakToken* break_token = line_box.Current().InlineBreakToken();
+ DCHECK(break_token);
// TODO(yosin): We should support OOF fragments between |fragment_| and
// break token.
- if (break_token.TextOffset() != text_fragment.EndOffset() + 1)
+ if (break_token->TextOffset() != end_offset + 1)
return false;
// Check a character in text content after |fragment_| comes from same
// layout text of |fragment_|.
- const NGOffsetMapping* mapping =
- NGOffsetMapping::GetFor(fragment_->GetLayoutObject());
+ const LayoutObject* const layout_object = cursor.Current().GetLayoutObject();
+ const NGOffsetMapping* mapping = NGOffsetMapping::GetFor(layout_object);
// TODO(kojii): There's not much we can do for dirty-tree. crbug.com/946004
if (!mapping)
return false;
const base::span<const NGOffsetMappingUnit> mapping_units =
- mapping->GetMappingUnitsForTextContentOffsetRange(
- text_fragment.EndOffset(), text_fragment.EndOffset() + 1);
+ mapping->GetMappingUnitsForTextContentOffsetRange(end_offset,
+ end_offset + 1);
if (mapping_units.begin() == mapping_units.end())
return false;
const NGOffsetMappingUnit& mapping_unit = mapping_units.front();
- return mapping_unit.GetLayoutObject() == fragment_->GetLayoutObject();
-}
-
-const NGPaintFragment*
-NGAbstractInlineTextBox::NextTextFragmentForSameLayoutObject() const {
- const auto fragments =
- NGPaintFragment::InlineFragmentsFor(fragment_->GetLayoutObject());
- const auto it =
- std::find_if(fragments.begin(), fragments.end(),
- [&](const auto& sibling) { return fragment_ == sibling; });
- DCHECK(it != fragments.end());
- const auto next_it = std::next(it);
- return next_it == fragments.end() ? nullptr : *next_it;
+ return mapping_unit.GetLayoutObject() == layout_object;
}
scoped_refptr<AbstractInlineTextBox>
NGAbstractInlineTextBox::NextInlineTextBox() const {
- if (!fragment_)
+ const NGInlineCursor& cursor = GetCursor();
+ if (!cursor)
return nullptr;
- DCHECK(!NeedsLayout());
- const NGPaintFragment* next_fragment = NextTextFragmentForSameLayoutObject();
- if (!next_fragment)
+ NGInlineCursor next;
+ next.MoveTo(*cursor.Current().GetLayoutObject());
+ while (next != cursor)
+ next.MoveToNextForSameLayoutObject();
+ next.MoveToNextForSameLayoutObject();
+ if (!next)
return nullptr;
- return GetOrCreate(*next_fragment);
+ return GetOrCreate(next);
}
LayoutRect NGAbstractInlineTextBox::LocalBounds() const {
- if (!fragment_ || !GetLineLayoutItem())
+ const NGInlineCursor& cursor = GetCursor();
+ if (!cursor)
return LayoutRect();
- return LayoutRect(fragment_->InlineOffsetToContainerBox().ToLayoutPoint(),
- fragment_->Size().ToLayoutSize());
+ return cursor.Current().RectInContainerBlock().ToLayoutRect();
}
unsigned NGAbstractInlineTextBox::Len() const {
- if (!fragment_)
+ const NGInlineCursor& cursor = GetCursor();
+ if (!cursor)
return 0;
if (NeedsTrailingSpace())
- return PhysicalTextFragment().TextLength() + 1;
- return PhysicalTextFragment().TextLength();
+ return cursor.Current().Text(cursor).length() + 1;
+ return cursor.Current().Text(cursor).length();
}
unsigned NGAbstractInlineTextBox::TextOffsetInContainer(unsigned offset) const {
- if (!fragment_)
+ const NGInlineCursor& cursor = GetCursor();
+ if (!cursor)
return 0;
- return PhysicalTextFragment().StartOffset() + offset;
+ return cursor.Current().TextStartOffset() + offset;
}
AbstractInlineTextBox::Direction NGAbstractInlineTextBox::GetDirection() const {
- if (!fragment_ || !GetLineLayoutItem())
+ const NGInlineCursor& cursor = GetCursor();
+ if (!cursor)
return kLeftToRight;
- const TextDirection text_direction =
- PhysicalTextFragment().ResolvedDirection();
+ const TextDirection text_direction = cursor.Current().ResolvedDirection();
if (GetLineLayoutItem().Style()->IsHorizontalWritingMode())
return IsLtr(text_direction) ? kLeftToRight : kRightToLeft;
return IsLtr(text_direction) ? kTopToBottom : kBottomToTop;
}
void NGAbstractInlineTextBox::CharacterWidths(Vector<float>& widths) const {
- if (!fragment_)
+ const NGInlineCursor& cursor = GetCursor();
+ if (!cursor)
return;
- if (!PhysicalTextFragment().TextShapeResult()) {
+ const ShapeResultView* shape_result_view = cursor.Current().TextShapeResult();
+ if (!shape_result_view) {
// When |fragment_| for BR, we don't have shape result.
// "aom-computed-boolean-properties.html" reaches here.
widths.resize(Len());
@@ -178,8 +261,8 @@ void NGAbstractInlineTextBox::CharacterWidths(Vector<float>& widths) const {
}
// TODO(layout-dev): Add support for IndividualCharacterRanges to
// ShapeResultView to avoid the copy below.
- auto shape_result =
- PhysicalTextFragment().TextShapeResult()->CreateShapeResult();
+ scoped_refptr<ShapeResult> shape_result =
+ shape_result_view->CreateShapeResult();
Vector<CharacterRange> ranges;
shape_result->IndividualCharacterRanges(&ranges);
widths.ReserveCapacity(ranges.size());
@@ -193,10 +276,11 @@ void NGAbstractInlineTextBox::CharacterWidths(Vector<float>& widths) const {
}
String NGAbstractInlineTextBox::GetText() const {
- if (!fragment_ || !GetLineLayoutItem())
- return String();
+ const NGInlineCursor& cursor = GetCursor();
+ if (!cursor)
+ return g_empty_string;
- String result = PhysicalTextFragment().Text().ToString();
+ String result = cursor.Current().Text(cursor).ToString();
// For compatibility with |InlineTextBox|, we should have a space character
// for soft line break.
@@ -217,56 +301,51 @@ String NGAbstractInlineTextBox::GetText() const {
}
bool NGAbstractInlineTextBox::IsFirst() const {
- if (!fragment_)
+ const NGInlineCursor& cursor = GetCursor();
+ if (!cursor)
return true;
- DCHECK(!NeedsLayout());
- const auto fragments =
- NGPaintFragment::InlineFragmentsFor(fragment_->GetLayoutObject());
- return fragment_ == &fragments.front();
+ NGInlineCursor first_fragment;
+ first_fragment.MoveTo(*cursor.Current().GetLayoutObject());
+ return cursor == first_fragment;
}
bool NGAbstractInlineTextBox::IsLast() const {
- if (!fragment_)
+ const NGInlineCursor& cursor = GetCursor();
+ if (!cursor)
return true;
- DCHECK(!NeedsLayout());
- const auto fragments =
- NGPaintFragment::InlineFragmentsFor(fragment_->GetLayoutObject());
- return fragment_ == &fragments.back();
+ NGInlineCursor last_fragment;
+ last_fragment.MoveTo(*cursor.Current().GetLayoutObject());
+ last_fragment.MoveToLastForSameLayoutObject();
+ return cursor == last_fragment;
}
scoped_refptr<AbstractInlineTextBox> NGAbstractInlineTextBox::NextOnLine()
const {
- if (!fragment_)
+ NGInlineCursor cursor = GetCursorOnLine();
+ if (!cursor)
return nullptr;
- DCHECK(!NeedsLayout());
- DCHECK(fragment_->ContainerLineBox());
- NGPaintFragmentTraversal cursor(*fragment_->ContainerLineBox(), *fragment_);
- for (cursor.MoveToNext(); !cursor.IsAtEnd(); cursor.MoveToNext()) {
- if (cursor->GetLayoutObject()->IsText())
- return GetOrCreate(*cursor);
+ for (cursor.MoveToNext(); cursor; cursor.MoveToNext()) {
+ if (cursor.Current().GetLayoutObject()->IsText())
+ return GetOrCreate(cursor);
}
return nullptr;
}
scoped_refptr<AbstractInlineTextBox> NGAbstractInlineTextBox::PreviousOnLine()
const {
- if (!fragment_)
+ NGInlineCursor cursor = GetCursorOnLine();
+ if (!cursor)
return nullptr;
- DCHECK(!NeedsLayout());
- DCHECK(fragment_->ContainerLineBox());
- NGPaintFragmentTraversal cursor(*fragment_->ContainerLineBox(), *fragment_);
- for (cursor.MoveToPrevious(); !cursor.IsAtEnd(); cursor.MoveToPrevious()) {
- if (cursor->GetLayoutObject()->IsText())
- return GetOrCreate(*cursor);
+ for (cursor.MoveToPrevious(); cursor; cursor.MoveToPrevious()) {
+ if (cursor.Current().GetLayoutObject()->IsText())
+ return GetOrCreate(cursor);
}
return nullptr;
}
bool NGAbstractInlineTextBox::IsLineBreak() const {
- if (!fragment_)
- return false;
- DCHECK(!NeedsLayout());
- return PhysicalTextFragment().IsLineBreak();
+ const NGInlineCursor& cursor = GetCursor();
+ return cursor && cursor.Current().IsLineBreak();
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.h
index 1f1d57dcef5..85fec4b6631 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.h
@@ -9,34 +9,36 @@
namespace blink {
+class NGFragmentItem;
+class NGInlineCursor;
class NGPaintFragment;
-class NGPhysicalTextFragment;
// The implementation of |AbstractInlineTextBox| for LayoutNG.
// See also |LegacyAbstractInlineTextBox| for legacy layout.
class CORE_EXPORT NGAbstractInlineTextBox final : public AbstractInlineTextBox {
private:
// Returns existing or newly created |NGAbstractInlineTextBox|.
- // * |fragment| should be attached to |NGPhysicalTextFragment|.
+ // * |cursor| should be attached to |NGPhysicalTextFragment|.
static scoped_refptr<AbstractInlineTextBox> GetOrCreate(
- const NGPaintFragment& fragment);
- static void WillDestroy(NGPaintFragment*);
+ const NGInlineCursor& cursor);
+ static void WillDestroy(const NGInlineCursor& cursor);
+ static void WillDestroy(const NGPaintFragment* fragment);
friend class LayoutText;
- friend class NGPaintFragment;
public:
- ~NGAbstractInlineTextBox() final;
-
- private:
NGAbstractInlineTextBox(LineLayoutText line_layout_item,
const NGPaintFragment& fragment);
+ NGAbstractInlineTextBox(LineLayoutText line_layout_item,
+ const NGFragmentItem& fragment);
- const NGPhysicalTextFragment& PhysicalTextFragment() const;
- bool NeedsLayout() const;
+ ~NGAbstractInlineTextBox() final;
+
+ private:
+ NGInlineCursor GetCursor() const;
+ NGInlineCursor GetCursorOnLine() const;
+ String GetTextContent() const;
bool NeedsTrailingSpace() const;
- // Returns next fragment associated to |LayoutText|.
- const NGPaintFragment* NextTextFragmentForSameLayoutObject() const;
// Implementations of AbstractInlineTextBox member functions.
void Detach() final;
@@ -53,12 +55,10 @@ class CORE_EXPORT NGAbstractInlineTextBox final : public AbstractInlineTextBox {
scoped_refptr<AbstractInlineTextBox> PreviousOnLine() const final;
bool IsLineBreak() const final;
- const NGPaintFragment* fragment_;
-
- using FragmentToNGAbstractInlineTextBoxHashMap =
- HashMap<const NGPaintFragment*, scoped_refptr<AbstractInlineTextBox>>;
- static FragmentToNGAbstractInlineTextBoxHashMap*
- g_abstract_inline_text_box_map_;
+ union {
+ const NGPaintFragment* fragment_;
+ const NGFragmentItem* fragment_item_;
+ };
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_baseline.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_baseline.cc
deleted file mode 100644
index f9059f05c5f..00000000000
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_baseline.cc
+++ /dev/null
@@ -1,89 +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/ng/inline/ng_baseline.h"
-
-#include "third_party/blink/renderer/core/layout/layout_block.h"
-#include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
-#include "third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h"
-
-namespace blink {
-
-const unsigned NGBaselineRequest::kTypeIdCount;
-const LayoutUnit NGBaselineList::kEmptyOffset;
-
-bool NGBaselineRequest::operator==(const NGBaselineRequest& other) const {
- return algorithm_type_ == other.algorithm_type_ &&
- baseline_type_ == other.baseline_type_;
-}
-
-bool NGBaselineRequestList::operator==(
- const NGBaselineRequestList& other) const {
- return type_id_mask_ == other.type_id_mask_;
-}
-
-void NGBaselineRequestList::push_back(const NGBaselineRequest& request) {
- type_id_mask_ |= 1 << request.TypeId();
-}
-
-void NGBaselineRequestList::AppendVector(
- const NGBaselineRequestList& requests) {
- type_id_mask_ |= requests.type_id_mask_;
-}
-
-bool NGBaseline::ShouldPropagateBaselines(const NGLayoutInputNode node) {
- if (node.IsInline())
- return true;
-
- return ShouldPropagateBaselines(node.GetLayoutBox());
-}
-
-bool NGBaseline::ShouldPropagateBaselines(LayoutBox* layout_box) {
- // Test if this node should use its own box to synthesize the baseline.
- if (!layout_box->IsLayoutBlock() ||
- layout_box->IsFloatingOrOutOfFlowPositioned() ||
- layout_box->IsWritingModeRoot())
- return false;
-
- // If this node is LayoutBlock that uses old layout, this may be a subclass
- // that overrides baseline functions. Propagate baseline requests so that we
- // call virtual functions.
- if (!NGBlockNode(layout_box).CanUseNewLayout())
- return true;
-
- return true;
-}
-
-NGBaselineList::NGBaselineList() {
- std::fill(std::begin(offsets_), std::end(offsets_), kEmptyOffset);
-}
-
-bool NGBaselineList::IsEmpty() const {
- for (LayoutUnit offset : offsets_) {
- if (offset != kEmptyOffset)
- return false;
- }
- return true;
-}
-
-base::Optional<LayoutUnit> NGBaselineList::Offset(
- const NGBaselineRequest request) const {
- LayoutUnit offset = offsets_[request.TypeId()];
- if (offset != kEmptyOffset)
- return offset;
- return base::nullopt;
-}
-
-void NGBaselineList::emplace_back(NGBaselineRequest request,
- LayoutUnit offset) {
- // Round LayoutUnit::Min() because we use it for an empty value.
- DCHECK_EQ(kEmptyOffset, LayoutUnit::Min())
- << "Change the rounding if kEmptyOffset was changed";
- if (UNLIKELY(offset == LayoutUnit::Min()))
- offset = LayoutUnit::NearlyMin();
- DCHECK_NE(offset, kEmptyOffset);
- offsets_[request.TypeId()] = offset;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_baseline.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_baseline.h
deleted file mode 100644
index 64426201e06..00000000000
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_baseline.h
+++ /dev/null
@@ -1,207 +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_INLINE_NG_BASELINE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_BASELINE_H_
-
-#include "base/optional.h"
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/platform/fonts/font_baseline.h"
-#include "third_party/blink/renderer/platform/geometry/layout_unit.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-
-class LayoutBox;
-class NGLayoutInputNode;
-
-enum class NGBaselineAlgorithmType {
- // Compute baselines for atomic inlines.
- kAtomicInline,
- // Compute baseline of first line box.
- kFirstLine
-};
-
-// Baselines are products of layout.
-// To compute baseline, add requests to NGConstraintSpace and run Layout().
-class CORE_EXPORT NGBaselineRequest {
- DISALLOW_NEW();
-
- public:
- NGBaselineRequest(NGBaselineAlgorithmType algorithm_type,
- FontBaseline baseline_type)
- : algorithm_type_(static_cast<unsigned>(algorithm_type)),
- baseline_type_(static_cast<unsigned>(baseline_type)) {}
-
- NGBaselineAlgorithmType AlgorithmType() const {
- return static_cast<NGBaselineAlgorithmType>(algorithm_type_);
- }
-
- FontBaseline BaselineType() const {
- return static_cast<FontBaseline>(baseline_type_);
- }
-
- bool operator==(const NGBaselineRequest& other) const;
- bool operator!=(const NGBaselineRequest& other) const {
- return !(*this == other);
- }
-
- private:
- // TypeId is an integer that identifies all combinations of
- // |NGBaselineRequest|. Visible only to |NGBaselineRequestList| and
- // |NGBaselineList|.
- static constexpr unsigned kTypeIdCount = 4;
- unsigned TypeId() const { return algorithm_type_ | (baseline_type_ << 1); }
- static NGBaselineRequest FromTypeId(unsigned type_id) {
- DCHECK_LE(type_id, kTypeIdCount);
- return NGBaselineRequest(static_cast<NGBaselineAlgorithmType>(type_id & 1),
- static_cast<FontBaseline>((type_id >> 1) & 1));
- }
- friend class NGBaselineList;
- friend class NGBaselineRequestList;
- friend class NGBaselineTest;
-
- unsigned algorithm_type_ : 1; // NGBaselineAlgorithmType
- unsigned baseline_type_ : 1; // FontBaseline
-};
-
-// A list of |NGBaselineRequest| in a packed format, with similar interface as
-// |Vector|.
-class CORE_EXPORT NGBaselineRequestList {
- DISALLOW_NEW();
-
- public:
- NGBaselineRequestList() = default;
-
- bool IsEmpty() const { return !type_id_mask_; }
-
- bool operator==(const NGBaselineRequestList& other) const;
-
- void push_back(const NGBaselineRequest& request);
- void AppendVector(const NGBaselineRequestList& requests);
-
- class const_iterator {
- DISALLOW_NEW();
-
- public:
- const_iterator() : type_id_(NGBaselineRequest::kTypeIdCount), mask_(0) {}
- explicit const_iterator(unsigned mask) : type_id_(0), mask_(mask) {
- if (!(mask_ & 1))
- ++(*this);
- }
-
- const NGBaselineRequest operator*() const {
- return NGBaselineRequest::FromTypeId(type_id_);
- }
- bool operator!=(const const_iterator& other) const {
- return type_id_ != other.type_id_;
- }
- void operator++() {
- while (type_id_ < NGBaselineRequest::kTypeIdCount) {
- ++type_id_;
- mask_ >>= 1;
- if (mask_ & 1)
- break;
- }
- }
-
- private:
- unsigned type_id_;
- unsigned mask_;
- };
-
- const_iterator begin() const { return const_iterator(type_id_mask_); }
- const_iterator end() const { return const_iterator(); }
-
- private:
- // Serialize/deserialize to a bit fields.
- static constexpr unsigned kSerializedBits = NGBaselineRequest::kTypeIdCount;
- unsigned Serialize() const { return type_id_mask_; }
- explicit NGBaselineRequestList(unsigned serialized)
- : type_id_mask_(serialized) {}
- friend class NGConstraintSpace;
- friend class NGConstraintSpaceBuilder;
-
- unsigned type_id_mask_ = 0;
-};
-
-// Represents a computed baseline position.
-struct CORE_EXPORT NGBaseline {
- NGBaselineRequest request;
- LayoutUnit offset;
-
- // @return if the node needs to propagate baseline requests/results.
- static bool ShouldPropagateBaselines(const NGLayoutInputNode);
- static bool ShouldPropagateBaselines(LayoutBox*);
-};
-
-// A list of |NGBaseline| in a packed format, with similar interface as
-// |Vector|.
-class CORE_EXPORT NGBaselineList {
- DISALLOW_NEW();
-
- public:
- NGBaselineList();
-
- bool IsEmpty() const;
-
- base::Optional<LayoutUnit> Offset(const NGBaselineRequest request) const;
-
- void emplace_back(NGBaselineRequest request, LayoutUnit offset);
-
-#if DCHECK_IS_ON()
- bool operator==(const NGBaselineList& other) const {
- for (wtf_size_t i = 0; i < NGBaselineRequest::kTypeIdCount; ++i) {
- if (offsets_[i] != other.offsets_[i])
- return false;
- }
-
- return true;
- }
-#endif
-
- class const_iterator {
- public:
- explicit const_iterator(unsigned type_id, const LayoutUnit* offset)
- : type_id_(type_id), offset_(offset) {
- DCHECK(offset);
- if (*offset == kEmptyOffset)
- ++(*this);
- }
- const_iterator()
- : type_id_(NGBaselineRequest::kTypeIdCount), offset_(nullptr) {}
-
- const NGBaseline operator*() const {
- return NGBaseline{NGBaselineRequest::FromTypeId(type_id_), *offset_};
- }
- bool operator!=(const const_iterator& other) const {
- return type_id_ != other.type_id_;
- }
- void operator++() {
- while (type_id_ < NGBaselineRequest::kTypeIdCount) {
- ++type_id_;
- ++offset_;
- if (type_id_ < NGBaselineRequest::kTypeIdCount &&
- *offset_ != kEmptyOffset)
- break;
- }
- }
-
- private:
- unsigned type_id_;
- const LayoutUnit* offset_;
- };
-
- const_iterator begin() const { return const_iterator(0, offsets_); }
- const_iterator end() const { return const_iterator(); }
-
- private:
- static constexpr LayoutUnit kEmptyOffset = LayoutUnit::Min();
-
- LayoutUnit offsets_[NGBaselineRequest::kTypeIdCount];
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_BASELINE_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_baseline_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_baseline_test.cc
deleted file mode 100644
index 5278637e097..00000000000
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_baseline_test.cc
+++ /dev/null
@@ -1,76 +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/core/layout/ng/inline/ng_baseline.h"
-
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
-
-namespace blink {
-
-using ::testing::ElementsAre;
-using ::testing::ElementsAreArray;
-
-class NGBaselineTest : public testing::Test {
- public:
- static NGBaselineRequest RequestFromTypeId(unsigned type_id) {
- return NGBaselineRequest::FromTypeId(type_id);
- }
-
- static Vector<NGBaselineRequest> ToList(NGBaselineRequestList requests) {
- Vector<NGBaselineRequest> list;
- for (const NGBaselineRequest request : requests)
- list.push_back(request);
- return list;
- }
-};
-
-struct NGBaselineRequestListTestData {
- unsigned count;
- unsigned type_ids[4];
-} baseline_request_list_test_data[] = {
- {0, {}}, {1, {0}}, {1, {1}}, {1, {2}},
- {1, {3}}, {2, {0, 1}}, {2, {0, 2}}, {2, {1, 3}},
- {3, {0, 1, 2}}, {3, {0, 2, 3}}, {3, {1, 2, 3}}, {4, {0, 1, 2, 3}},
-};
-
-class NGBaselineRequestListDataTest
- : public NGBaselineTest,
- public testing::WithParamInterface<NGBaselineRequestListTestData> {};
-
-INSTANTIATE_TEST_SUITE_P(NGBaselineTest,
- NGBaselineRequestListDataTest,
- testing::ValuesIn(baseline_request_list_test_data));
-
-TEST_P(NGBaselineRequestListDataTest, Data) {
- const auto& data = GetParam();
- NGBaselineRequestList requests;
- Vector<NGBaselineRequest> expected;
- for (unsigned i = 0; i < data.count; i++) {
- NGBaselineRequest request = RequestFromTypeId(data.type_ids[i]);
- requests.push_back(request);
- expected.push_back(request);
- }
-
- EXPECT_EQ(requests.IsEmpty(), !data.count);
-
- Vector<NGBaselineRequest> actual = ToList(requests);
- EXPECT_THAT(actual, expected);
-}
-
-TEST_F(NGBaselineTest, BaselineList) {
- NGBaselineList list;
- EXPECT_TRUE(list.IsEmpty());
-
- NGBaselineRequest request(NGBaselineAlgorithmType::kFirstLine,
- FontBaseline::kAlphabeticBaseline);
- list.emplace_back(request, LayoutUnit(123));
- EXPECT_FALSE(list.IsEmpty());
- EXPECT_EQ(list.Offset(request), LayoutUnit(123));
- EXPECT_FALSE(list.Offset({NGBaselineAlgorithmType::kFirstLine,
- FontBaseline::kIdeographicBaseline}));
-}
-
-} // 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 b01d591bf48..ed88fbe192b 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
@@ -90,11 +90,11 @@ CaretPositionResolution TryResolveCaretPositionInTextFragment(
const NGInlineCursor& cursor,
unsigned offset,
TextAffinity affinity) {
- if (cursor.IsGeneratedText())
+ if (cursor.Current().IsGeneratedText())
return CaretPositionResolution();
const NGOffsetMapping& mapping =
- *NGOffsetMapping::GetFor(cursor.CurrentLayoutObject());
+ *NGOffsetMapping::GetFor(cursor.Current().GetLayoutObject());
// A text fragment natually allows caret placement in offset range
// [StartOffset(), EndOffset()], i.e., from before the first character to
@@ -106,12 +106,13 @@ CaretPositionResolution TryResolveCaretPositionInTextFragment(
// Note that we don't ignore other characters that are not in fragments. For
// example, a trailing space of a line is not in any fragment, but its two
// sides are still different caret positions, so we don't ignore it.
- const unsigned start_offset = cursor.CurrentTextStartOffset();
- const unsigned end_offset = cursor.CurrentTextEndOffset();
+ const NGTextOffset current_offset = cursor.Current().TextOffset();
+ const unsigned start_offset = current_offset.start;
+ const unsigned end_offset = current_offset.end;
if (offset < start_offset &&
!mapping.HasBidiControlCharactersOnly(offset, start_offset))
return CaretPositionResolution();
- if (offset > cursor.CurrentTextEndOffset() &&
+ if (offset > current_offset.end &&
!mapping.HasBidiControlCharactersOnly(end_offset, offset))
return CaretPositionResolution();
@@ -129,7 +130,7 @@ CaretPositionResolution TryResolveCaretPositionInTextFragment(
return {ResolutionType::kResolved, candidate};
}
- if (offset == end_offset && !cursor.IsLineBreak() &&
+ if (offset == end_offset && !cursor.Current().IsLineBreak() &&
CanResolveCaretPositionAfterFragment(cursor, affinity)) {
return {ResolutionType::kResolved, candidate};
}
@@ -157,7 +158,7 @@ CaretPositionResolution TryResolveCaretPositionByBoxFragmentSide(
const NGInlineCursor& cursor,
unsigned offset,
TextAffinity affinity) {
- const Node* const node = cursor.CurrentNode();
+ const Node* const node = cursor.Current().GetNode();
// There is no caret position at a pseudo or generated box side.
if (!node || node->IsPseudoElement()) {
// TODO(xiaochengh): This leads to false negatives for, e.g., RUBY, where an
@@ -192,9 +193,9 @@ CaretPositionResolution TryResolveCaretPositionWithFragment(
const NGInlineCursor& cursor,
unsigned offset,
TextAffinity affinity) {
- if (cursor.IsText())
+ if (cursor.Current().IsText())
return TryResolveCaretPositionInTextFragment(cursor, offset, affinity);
- if (cursor.IsAtomicInline())
+ if (cursor.Current().IsAtomicInline())
return TryResolveCaretPositionByBoxFragmentSide(cursor, offset, affinity);
return CaretPositionResolution();
}
@@ -207,8 +208,9 @@ bool NeedsBidiAdjustment(const NGCaretPosition& caret_position) {
if (caret_position.position_type != NGCaretPositionType::kAtTextOffset)
return true;
DCHECK(caret_position.text_offset.has_value());
- const unsigned start_offset = caret_position.cursor.CurrentTextStartOffset();
- const unsigned end_offset = caret_position.cursor.CurrentTextEndOffset();
+ const NGTextOffset offset = caret_position.cursor.Current().TextOffset();
+ const unsigned start_offset = offset.start;
+ const unsigned end_offset = offset.end;
DCHECK_GE(*caret_position.text_offset, start_offset);
DCHECK_LE(*caret_position.text_offset, end_offset);
// Bidi adjustment is needed only for caret positions at bidi boundaries.
@@ -232,10 +234,10 @@ bool IsUpstreamAfterLineBreak(const NGCaretPosition& caret_position) {
DCHECK(caret_position.cursor.IsNotNull());
DCHECK(caret_position.text_offset.has_value());
- if (!caret_position.cursor.IsLineBreak())
+ if (!caret_position.cursor.Current().IsLineBreak())
return false;
return *caret_position.text_offset ==
- caret_position.cursor.CurrentTextEndOffset();
+ caret_position.cursor.Current().TextEndOffset();
}
NGCaretPosition BetterCandidateBetween(const NGCaretPosition& current,
@@ -320,22 +322,24 @@ PositionWithAffinity NGCaretPosition::ToPositionInDOMTreeWithAffinity() const {
return PositionWithAffinity();
switch (position_type) {
case NGCaretPositionType::kBeforeBox:
- if (cursor.CurrentNode())
+ if (cursor.Current().GetNode())
return PositionWithAffinity();
- return PositionWithAffinity(Position::BeforeNode(*cursor.CurrentNode()),
- TextAffinity::kDownstream);
+ return PositionWithAffinity(
+ Position::BeforeNode(*cursor.Current().GetNode()),
+ TextAffinity::kDownstream);
case NGCaretPositionType::kAfterBox:
- if (cursor.CurrentNode())
+ if (cursor.Current().GetNode())
return PositionWithAffinity();
- return PositionWithAffinity(Position::AfterNode(*cursor.CurrentNode()),
- TextAffinity::kUpstreamIfPossible);
+ return PositionWithAffinity(
+ Position::AfterNode(*cursor.Current().GetNode()),
+ TextAffinity::kUpstreamIfPossible);
case NGCaretPositionType::kAtTextOffset:
- // In case of ::first-letter, |cursor.CurrentNode()| is null.
+ // In case of ::first-letter, |cursor.Current().GetNode()| is null.
DCHECK(text_offset.has_value());
const NGOffsetMapping* mapping =
- NGOffsetMapping::GetFor(cursor.CurrentLayoutObject());
+ NGOffsetMapping::GetFor(cursor.Current().GetLayoutObject());
const TextAffinity affinity =
- *text_offset == cursor.CurrentTextEndOffset()
+ *text_offset == cursor.Current().TextEndOffset()
? TextAffinity::kUpstreamIfPossible
: TextAffinity::kDownstream;
const Position position = affinity == TextAffinity::kDownstream
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 7977e5227cf..bccd83f3551 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
@@ -17,28 +17,29 @@ namespace {
PhysicalRect ComputeLocalCaretRectByBoxSide(const NGInlineCursor& cursor,
NGCaretPositionType position_type) {
- const bool is_horizontal = cursor.CurrentStyle().IsHorizontalWritingMode();
+ const bool is_horizontal = cursor.Current().Style().IsHorizontalWritingMode();
NGInlineCursor line_box(cursor);
line_box.MoveToContainingLine();
DCHECK(line_box);
const PhysicalOffset offset_to_line_box =
- cursor.CurrentOffset() - line_box.CurrentOffset();
- LayoutUnit caret_height = is_horizontal ? line_box.CurrentSize().height
- : line_box.CurrentSize().width;
+ cursor.Current().OffsetInContainerBlock() -
+ line_box.Current().OffsetInContainerBlock();
+ LayoutUnit caret_height = is_horizontal ? line_box.Current().Size().height
+ : line_box.Current().Size().width;
LayoutUnit caret_top =
is_horizontal ? -offset_to_line_box.top : -offset_to_line_box.left;
const LocalFrameView* frame_view =
- cursor.CurrentLayoutObject()->GetDocument().View();
+ cursor.Current().GetLayoutObject()->GetDocument().View();
LayoutUnit caret_width = frame_view->CaretWidth();
- const bool is_ltr = IsLtr(cursor.CurrentResolvedDirection());
+ const bool is_ltr = IsLtr(cursor.Current().ResolvedDirection());
LayoutUnit caret_left;
if (is_ltr != (position_type == NGCaretPositionType::kBeforeBox)) {
if (is_horizontal)
- caret_left = cursor.CurrentSize().width - caret_width;
+ caret_left = cursor.Current().Size().width - caret_width;
else
- caret_left = cursor.CurrentSize().height - caret_width;
+ caret_left = cursor.Current().Size().height - caret_width;
}
if (!is_horizontal) {
@@ -53,22 +54,22 @@ PhysicalRect ComputeLocalCaretRectByBoxSide(const NGInlineCursor& cursor,
PhysicalRect ComputeLocalCaretRectAtTextOffset(const NGInlineCursor& cursor,
unsigned offset) {
- DCHECK(cursor.IsText());
- DCHECK_GE(offset, cursor.CurrentTextStartOffset());
- DCHECK_LE(offset, cursor.CurrentTextEndOffset());
+ DCHECK(cursor.Current().IsText());
+ DCHECK_GE(offset, cursor.Current().TextStartOffset());
+ DCHECK_LE(offset, cursor.Current().TextEndOffset());
const LocalFrameView* frame_view =
- cursor.CurrentLayoutObject()->GetDocument().View();
+ cursor.Current().GetLayoutObject()->GetDocument().View();
LayoutUnit caret_width = frame_view->CaretWidth();
- const bool is_horizontal = cursor.CurrentStyle().IsHorizontalWritingMode();
+ const bool is_horizontal = cursor.Current().Style().IsHorizontalWritingMode();
- LayoutUnit caret_height =
- is_horizontal ? cursor.CurrentSize().height : cursor.CurrentSize().width;
+ LayoutUnit caret_height = is_horizontal ? cursor.Current().Size().height
+ : cursor.Current().Size().width;
LayoutUnit caret_top;
LayoutUnit caret_left = cursor.InlinePositionForOffset(offset);
- if (!cursor.IsLineBreak())
+ if (!cursor.Current().IsLineBreak())
caret_left -= caret_width / 2;
if (!is_horizontal) {
@@ -77,16 +78,17 @@ PhysicalRect ComputeLocalCaretRectAtTextOffset(const NGInlineCursor& cursor,
}
// Adjust the location to be relative to the inline formatting context.
- PhysicalOffset caret_location =
- PhysicalOffset(caret_left, caret_top) + cursor.CurrentOffset();
+ PhysicalOffset caret_location = PhysicalOffset(caret_left, caret_top) +
+ cursor.Current().OffsetInContainerBlock();
const PhysicalSize caret_size(caret_width, caret_height);
const NGPhysicalBoxFragment& fragmentainer =
- *cursor.CurrentLayoutObject()->ContainingBlockFlowFragment();
+ *cursor.Current().GetLayoutObject()->ContainingBlockFlowFragment();
NGInlineCursor line_box(cursor);
line_box.MoveToContainingLine();
- const PhysicalOffset line_box_offset = line_box.CurrentOffset();
- const PhysicalRect line_box_rect(line_box_offset, line_box.CurrentSize());
+ const PhysicalOffset line_box_offset =
+ line_box.Current().OffsetInContainerBlock();
+ const PhysicalRect line_box_rect(line_box_offset, line_box.Current().Size());
// 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
@@ -116,17 +118,17 @@ LocalCaretRect ComputeLocalCaretRect(const NGCaretPosition& caret_position) {
return LocalCaretRect();
const LayoutObject* layout_object =
- caret_position.cursor.CurrentLayoutObject();
+ caret_position.cursor.Current().GetLayoutObject();
switch (caret_position.position_type) {
case NGCaretPositionType::kBeforeBox:
case NGCaretPositionType::kAfterBox: {
- DCHECK(!caret_position.cursor.IsText());
+ DCHECK(!caret_position.cursor.Current().IsText());
const PhysicalRect fragment_local_rect = ComputeLocalCaretRectByBoxSide(
caret_position.cursor, caret_position.position_type);
return {layout_object, fragment_local_rect};
}
case NGCaretPositionType::kAtTextOffset: {
- DCHECK(caret_position.cursor.IsText());
+ DCHECK(caret_position.cursor.Current().IsText());
DCHECK(caret_position.text_offset.has_value());
const PhysicalRect caret_rect = ComputeLocalCaretRectAtTextOffset(
caret_position.cursor, *caret_position.text_offset);
@@ -151,12 +153,12 @@ LocalCaretRect ComputeLocalSelectionRect(
DCHECK(line_box);
PhysicalRect rect = caret_rect.rect;
- if (caret_position.cursor.CurrentStyle().IsHorizontalWritingMode()) {
- rect.SetY(line_box.CurrentOffset().top);
- rect.SetHeight(line_box.CurrentSize().height);
+ if (caret_position.cursor.Current().Style().IsHorizontalWritingMode()) {
+ rect.SetY(line_box.Current().OffsetInContainerBlock().top);
+ rect.SetHeight(line_box.Current().Size().height);
} else {
- rect.SetX(line_box.CurrentOffset().left);
- rect.SetHeight(line_box.CurrentSize().width);
+ rect.SetX(line_box.Current().OffsetInContainerBlock().left);
+ rect.SetHeight(line_box.Current().Size().width);
}
return {caret_rect.layout_object, rect};
}
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 c184209b8f2..63a23dff82b 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
@@ -9,13 +9,14 @@
#include "third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.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_inline_cursor.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
namespace blink {
NGFragmentItem::NGFragmentItem(const NGPhysicalTextFragment& text)
: layout_object_(text.GetLayoutObject()),
- text_({text.TextShapeResult(), text.StartOffset(), text.EndOffset()}),
+ text_({text.TextShapeResult(), text.TextOffset()}),
rect_({PhysicalOffset(), text.Size()}),
type_(kText),
sub_type_(static_cast<unsigned>(text.TextType())),
@@ -23,12 +24,12 @@ NGFragmentItem::NGFragmentItem(const NGPhysicalTextFragment& text)
is_generated_text_(text.IsGeneratedText()),
is_hidden_for_paint_(text.IsHiddenForPaint()),
text_direction_(static_cast<unsigned>(text.ResolvedDirection())),
- ink_overflow_computed_(false) {
- DCHECK_LE(text_.start_offset, text_.end_offset);
+ ink_overflow_computed_(false),
+ is_first_for_node_(text.IsFirstForNode()) {
#if DCHECK_IS_ON()
if (text_.shape_result) {
- DCHECK_EQ(text_.shape_result->StartIndex(), text_.start_offset);
- DCHECK_EQ(text_.shape_result->EndIndex(), text_.end_offset);
+ DCHECK_EQ(text_.shape_result->StartIndex(), StartOffset());
+ DCHECK_EQ(text_.shape_result->EndIndex(), EndOffset());
}
#endif
if (text.TextType() == NGPhysicalTextFragment::kGeneratedText) {
@@ -38,6 +39,7 @@ NGFragmentItem::NGFragmentItem(const NGPhysicalTextFragment& text)
// |generated_text_.text_| instead copying, |generated_text_.text = ...|.
new (&generated_text_.text) String(text.Text().ToString());
}
+ DCHECK(!IsFormattingContextRoot());
}
NGFragmentItem::NGFragmentItem(const NGPhysicalLineBoxFragment& line,
@@ -46,22 +48,45 @@ NGFragmentItem::NGFragmentItem(const NGPhysicalLineBoxFragment& line,
line_({&line, item_count}),
rect_({PhysicalOffset(), line.Size()}),
type_(kLine),
+ sub_type_(static_cast<unsigned>(line.LineBoxType())),
style_variant_(static_cast<unsigned>(line.StyleVariant())),
is_hidden_for_paint_(false),
text_direction_(static_cast<unsigned>(line.BaseDirection())),
- ink_overflow_computed_(false) {}
+ ink_overflow_computed_(false),
+ is_first_for_node_(true) {
+ DCHECK(!IsFormattingContextRoot());
+}
NGFragmentItem::NGFragmentItem(const NGPhysicalBoxFragment& box,
- wtf_size_t item_count,
TextDirection resolved_direction)
: layout_object_(box.GetLayoutObject()),
- box_({&box, item_count}),
+ box_({&box, 1}),
rect_({PhysicalOffset(), box.Size()}),
type_(kBox),
style_variant_(static_cast<unsigned>(box.StyleVariant())),
is_hidden_for_paint_(box.IsHiddenForPaint()),
text_direction_(static_cast<unsigned>(resolved_direction)),
- ink_overflow_computed_(false) {}
+ ink_overflow_computed_(false),
+ is_first_for_node_(box.IsFirstForNode()) {
+ 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_first_for_node_(true) {
+ DCHECK_EQ(inline_item.Type(), NGInlineItem::kOpenTag);
+ DCHECK(layout_object_);
+ DCHECK(layout_object_->IsLayoutInline());
+ DCHECK(!IsFormattingContextRoot());
+}
NGFragmentItem::~NGFragmentItem() {
switch (Type()) {
@@ -80,12 +105,32 @@ NGFragmentItem::~NGFragmentItem() {
}
}
-bool NGFragmentItem::HasSameParent(const NGFragmentItem& other) const {
+bool NGFragmentItem::IsSiblingOf(const NGFragmentItem& other) const {
if (!GetLayoutObject())
return !other.GetLayoutObject();
if (!other.GetLayoutObject())
return false;
- return GetLayoutObject()->Parent() == other.GetLayoutObject()->Parent();
+ if (GetLayoutObject()->Parent() == other.GetLayoutObject()->Parent())
+ return true;
+ // To traverse list marker and line box of <li> with |MoveToNextSibling()|,
+ // we think list marker and <li> are sibling.
+ // See hittesting/culled-inline-crash.html (skip list marker)
+ // See fast/events/onclick-list-marker.html (hit on list marker)
+ if (IsListMarker())
+ return GetLayoutObject()->Parent() == other.GetLayoutObject();
+ if (other.IsListMarker())
+ return other.GetLayoutObject()->Parent() == GetLayoutObject();
+ return false;
+}
+
+bool NGFragmentItem::IsInlineBox() const {
+ if (Type() == kBox) {
+ if (const NGPhysicalBoxFragment* box = BoxFragment())
+ return box->IsInlineBox();
+ DCHECK(GetLayoutObject()->IsLayoutInline());
+ return true;
+ }
+ return false;
}
bool NGFragmentItem::IsAtomicInline() const {
@@ -96,11 +141,16 @@ bool NGFragmentItem::IsAtomicInline() const {
return false;
}
-bool NGFragmentItem::IsEmptyLineBox() const {
- // TODO(yosin): Implement |NGFragmentItem::IsEmptyLineBox()|.
+bool NGFragmentItem::IsFloating() const {
+ if (const NGPhysicalBoxFragment* box = BoxFragment())
+ return box->IsFloating();
return false;
}
+bool NGFragmentItem::IsEmptyLineBox() const {
+ return LineBoxType() == NGLineBoxType::kEmptyLineBox;
+}
+
bool NGFragmentItem::IsGeneratedText() const {
if (Type() == kText || Type() == kGeneratedText)
return is_generated_text_;
@@ -109,8 +159,7 @@ bool NGFragmentItem::IsGeneratedText() const {
}
bool NGFragmentItem::IsListMarker() const {
- // TODO(yosin): Implement |NGFragmentItem::IsListMarker()|.
- return false;
+ return layout_object_ && layout_object_->IsLayoutNGOutsideListMarker();
}
bool NGFragmentItem::HasOverflowClip() const {
@@ -162,11 +211,6 @@ PhysicalRect NGFragmentItem::InkOverflow() const {
return container_ink_overflow.SelfAndContentsInkOverflow();
}
-PositionWithAffinity NGFragmentItem::PositionForPoint(
- const PhysicalOffset&) const {
- return PositionWithAffinity();
-}
-
const ShapeResultView* NGFragmentItem::TextShapeResult() const {
if (Type() == kText)
return text_.shape_result.get();
@@ -176,29 +220,19 @@ const ShapeResultView* NGFragmentItem::TextShapeResult() const {
return nullptr;
}
-unsigned NGFragmentItem::StartOffset() const {
+NGTextOffset NGFragmentItem::TextOffset() const {
if (Type() == kText)
- return text_.start_offset;
+ return text_.text_offset;
if (Type() == kGeneratedText)
- return 0;
+ return {0, generated_text_.text.length()};
NOTREACHED();
- return 0;
-}
-
-unsigned NGFragmentItem::EndOffset() const {
- if (Type() == kText)
- return text_.end_offset;
- if (Type() == kGeneratedText)
- return generated_text_.text.length();
- NOTREACHED();
- return 0;
+ return {};
}
StringView NGFragmentItem::Text(const NGFragmentItems& items) const {
if (Type() == kText) {
- DCHECK_LE(text_.start_offset, text_.end_offset);
- return StringView(items.Text(UsesFirstLineStyle()), text_.start_offset,
- text_.end_offset - text_.start_offset);
+ return StringView(items.Text(UsesFirstLineStyle()), text_.text_offset.start,
+ text_.text_offset.Length());
}
if (Type() == kGeneratedText)
return GeneratedText();
@@ -209,8 +243,8 @@ StringView NGFragmentItem::Text(const NGFragmentItems& items) const {
NGTextFragmentPaintInfo NGFragmentItem::TextPaintInfo(
const NGFragmentItems& items) const {
if (Type() == kText) {
- return {items.Text(UsesFirstLineStyle()), text_.start_offset,
- text_.end_offset, text_.shape_result.get()};
+ return {items.Text(UsesFirstLineStyle()), text_.text_offset.start,
+ text_.text_offset.end, text_.shape_result.get()};
}
if (Type() == kGeneratedText) {
return {generated_text_.text, 0, generated_text_.text.length(),
@@ -231,6 +265,24 @@ TextDirection NGFragmentItem::ResolvedDirection() const {
}
String NGFragmentItem::DebugName() 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|.
+ if (Type() == NGFragmentItem::kBox) {
+ StringBuilder name;
+ name.Append("NGPhysicalBoxFragment ");
+ name.Append(layout_object_->DebugName());
+ return name.ToString();
+ }
+ if (Type() == NGFragmentItem::kText) {
+ StringBuilder name;
+ name.Append("NGPhysicalTextFragment '");
+ name.Append(Text(*layout_object_->ContainingBlockFlowFragment()->Items()));
+ name.Append('\'');
+ return name.ToString();
+ }
+ if (Type() == NGFragmentItem::kLine)
+ return "NGPhysicalLineBoxFragment";
return "NGFragmentItem";
}
@@ -241,17 +293,28 @@ IntRect NGFragmentItem::VisualRect() const {
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());
DCHECK(layout_object.IsInLayoutNGInlineFormattingContext());
PhysicalRect visual_rect;
- for (const NGFragmentItem& item : ItemsFor(layout_object)) {
+ NGInlineCursor cursor;
+ for (cursor.MoveTo(layout_object); cursor;
+ cursor.MoveToNextForSameLayoutObject()) {
+ DCHECK(cursor.Current().Item());
+ const NGFragmentItem& item = *cursor.Current().Item();
if (UNLIKELY(item.IsHiddenForPaint()))
continue;
PhysicalRect child_visual_rect = item.SelfInkOverflow();
- child_visual_rect.offset += item.Offset();
+ child_visual_rect.offset += item.OffsetInContainerBlock();
visual_rect.Unite(child_visual_rect);
}
return visual_rect;
@@ -269,7 +332,7 @@ PhysicalRect NGFragmentItem::RecalcInkOverflowForCursor(
if (item->HasSelfPaintingLayer())
continue;
if (!child_rect.IsEmpty()) {
- child_rect.offset += item->Offset();
+ child_rect.offset += item->OffsetInContainerBlock();
contents_ink_overflow.Unite(child_rect);
}
}
@@ -322,14 +385,22 @@ void NGFragmentItem::RecalcInkOverflow(
cursor->MoveToNextSibling();
PhysicalRect contents_rect = RecalcInkOverflowForCursor(&descendants_cursor);
+ // |contents_rect| is relative to the inline formatting context. Make it
+ // relative to |this|.
+ contents_rect.offset -= OffsetInContainerBlock();
+
// Compute the self ink overflow.
PhysicalRect self_rect;
if (Type() == kLine) {
// Line boxes don't have self overflow. Compute content overflow only.
*self_and_contents_rect_out = contents_rect;
- } else if (const NGPhysicalBoxFragment* box_fragment = BoxFragment()) {
- DCHECK(box_fragment->IsInlineBox());
- self_rect = box_fragment->ComputeSelfInkOverflow();
+ } else if (Type() == kBox) {
+ if (const NGPhysicalBoxFragment* box_fragment = BoxFragment()) {
+ DCHECK(box_fragment->IsInlineBox());
+ self_rect = box_fragment->ComputeSelfInkOverflow();
+ } else {
+ self_rect = LocalRect();
+ }
*self_and_contents_rect_out = UnionRect(self_rect, contents_rect);
} else {
NOTREACHED();
@@ -403,49 +474,6 @@ unsigned NGFragmentItem::TextOffsetForPoint(
return inline_offset <= size.inline_size / 2 ? StartOffset() : EndOffset();
}
-NGFragmentItem::ItemsForLayoutObject NGFragmentItem::ItemsFor(
- const LayoutObject& layout_object) {
- DCHECK(layout_object.IsInLayoutNGInlineFormattingContext());
- DCHECK(layout_object.IsText() || layout_object.IsLayoutInline() ||
- (layout_object.IsBox() && layout_object.IsInline()));
-
- if (const LayoutBlockFlow* block_flow =
- layout_object.RootInlineFormattingContext()) {
- if (const NGPhysicalBoxFragment* fragment = block_flow->CurrentFragment()) {
- if (wtf_size_t index = layout_object.FirstInlineFragmentItemIndex()) {
- const auto& items = fragment->Items()->Items();
- return ItemsForLayoutObject(items, index, items[index].get());
- }
- // TODO(yosin): Once we update all usages of |FirstInlineFragment()|,
- // we should get rid of below code.
- if (const NGFragmentItems* items = fragment->Items()) {
- for (unsigned i = 0; i < items->Items().size(); ++i) {
- const NGFragmentItem* item = items->Items()[i].get();
- if (item->GetLayoutObject() == &layout_object)
- return ItemsForLayoutObject(items->Items(), i, item);
- }
- }
- }
- }
-
- return ItemsForLayoutObject();
-}
-
-NGFragmentItem::ItemsForLayoutObject::Iterator&
-NGFragmentItem::ItemsForLayoutObject::Iterator::operator++() {
- // TODO(kojii): This is a hot function needed by paint and several other
- // operations. Make this fast, by not iterating.
- if (!current_)
- return *this;
- if (!current_->delta_to_next_for_same_layout_object_) {
- current_ = nullptr;
- return *this;
- }
- index_ += current_->delta_to_next_for_same_layout_object_;
- current_ = (*items_)[index_].get();
- return *this;
-}
-
std::ostream& operator<<(std::ostream& ostream, const NGFragmentItem& item) {
ostream << "{";
switch (item.Type()) {
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 112464bdc50..c07af90d3d8 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
@@ -11,6 +11,7 @@
#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_line_height_metrics.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_text_offset.h"
#include "third_party/blink/renderer/core/layout/ng/ng_ink_overflow.h"
#include "third_party/blink/renderer/platform/graphics/paint/display_item_client.h"
@@ -18,6 +19,7 @@ namespace blink {
class NGFragmentItems;
class NGInlineBreakToken;
+class NGInlineItem;
struct NGTextFragmentPaintInfo;
// This class represents a text run or a box in an inline formatting context.
@@ -32,8 +34,7 @@ class CORE_EXPORT NGFragmentItem : public DisplayItemClient {
// TODO(kojii): |start_offset| and |end_offset| should match to the offset
// in |shape_result|. Consider if we should remove them, or if keeping them
// is easier.
- const unsigned start_offset;
- const unsigned end_offset;
+ const NGTextOffset text_offset;
};
// Represents text generated by the layout engine, e.g., hyphen or ellipsis.
struct GeneratedTextItem {
@@ -64,8 +65,8 @@ class CORE_EXPORT NGFragmentItem : public DisplayItemClient {
// TODO(kojii): Should be able to create without once creating fragments.
NGFragmentItem(const NGPhysicalTextFragment& text);
NGFragmentItem(const NGPhysicalBoxFragment& box,
- wtf_size_t item_count,
TextDirection resolved_direction);
+ NGFragmentItem(const NGInlineItem& inline_item, const PhysicalSize& size);
NGFragmentItem(const NGPhysicalLineBoxFragment& line, wtf_size_t item_count);
~NGFragmentItem() final;
@@ -74,11 +75,29 @@ class CORE_EXPORT NGFragmentItem : public DisplayItemClient {
bool IsText() const { return Type() == kText || Type() == kGeneratedText; }
bool IsContainer() const { return Type() == kBox || Type() == kLine; }
+ bool IsInlineBox() const;
bool IsAtomicInline() const;
+ bool IsFloating() const;
bool IsEmptyLineBox() const;
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);
+ DCHECK(!IsInlineBox() || BoxFragment());
+ return is_first_for_node_;
+ }
+
+ // Return true if this is the last fragment generated from a node.
+ bool IsLastForNode() const {
+ // TODO(layout-dev): This doesn't work if the LayoutObject continues in a
+ // next fragmentainer (we get a false negative here then).
+ DCHECK(Type() != kLine);
+ DCHECK(!IsInlineBox() || BoxFragment());
+ return !DeltaToNextForSameLayoutObject();
+ }
+
NGStyleVariant StyleVariant() const {
return static_cast<NGStyleVariant>(style_variant_);
}
@@ -100,15 +119,15 @@ class CORE_EXPORT NGFragmentItem : public DisplayItemClient {
}
Node* GetNode() const { return layout_object_->GetNode(); }
Node* NodeForHitTest() const { return layout_object_->NodeForHitTest(); }
- bool HasSameParent(const NGFragmentItem& other) const;
+ bool IsSiblingOf(const NGFragmentItem& other) const;
wtf_size_t DeltaToNextForSameLayoutObject() const {
return delta_to_next_for_same_layout_object_;
}
void SetDeltaToNextForSameLayoutObject(wtf_size_t delta);
- const PhysicalRect& Rect() const { return rect_; }
- const PhysicalOffset& Offset() const { return rect_.offset; }
+ const PhysicalRect& RectInContainerBlock() const { return rect_; }
+ const PhysicalOffset& OffsetInContainerBlock() const { return rect_.offset; }
const PhysicalSize& Size() const { return rect_.size; }
PhysicalRect LocalRect() const { return {PhysicalOffset(), Size()}; }
void SetOffset(const PhysicalOffset& offset) { rect_.offset = offset; }
@@ -128,6 +147,10 @@ class CORE_EXPORT NGFragmentItem : public DisplayItemClient {
return 0;
}
bool HasChildren() const { return DescendantsCount() > 1; }
+ void SetDescendantsCount(wtf_size_t count) {
+ CHECK_EQ(Type(), kBox);
+ box_.descendants_count = count;
+ }
// Returns |NGPhysicalBoxFragment| if one is associated with this item.
const NGPhysicalBoxFragment* BoxFragment() const {
@@ -158,58 +181,19 @@ class CORE_EXPORT NGFragmentItem : public DisplayItemClient {
return nullptr;
}
- NGTextFragmentPaintInfo TextPaintInfo(const NGFragmentItems& items) const;
+ using NGLineBoxType = NGPhysicalLineBoxFragment::NGLineBoxType;
+ NGLineBoxType LineBoxType() const {
+ if (Type() == kLine)
+ return static_cast<NGLineBoxType>(sub_type_);
+ NOTREACHED() << this;
+ return NGLineBoxType::kNormalLineBox;
+ }
// DisplayItemClient overrides
String DebugName() const override;
IntRect VisualRect() const override;
+ IntRect PartialInvalidationVisualRect() const override;
- // Find |NGFragmentItem|s that are associated with a |LayoutObject|.
- class CORE_EXPORT ItemsForLayoutObject {
- STACK_ALLOCATED();
-
- public:
- ItemsForLayoutObject() = default;
- ItemsForLayoutObject(const Vector<std::unique_ptr<NGFragmentItem>>& items,
- unsigned first_index,
- const NGFragmentItem* first_item)
- : items_(&items), first_item_(first_item), first_index_(first_index) {}
-
- bool IsEmpty() const { return !items_; }
-
- class CORE_EXPORT Iterator {
- public:
- Iterator(const Vector<std::unique_ptr<NGFragmentItem>>* items,
- unsigned index,
- const NGFragmentItem* item)
- : current_(item), items_(items), index_(index) {}
- const NGFragmentItem& operator*() const { return *current_; }
- const NGFragmentItem& operator->() const { return *current_; }
- Iterator& operator++();
- bool operator==(const Iterator& other) const {
- return current_ == other.current_;
- }
- bool operator!=(const Iterator& other) const {
- return current_ != other.current_;
- }
-
- private:
- const NGFragmentItem* current_;
- const Vector<std::unique_ptr<NGFragmentItem>>* items_;
- unsigned index_;
- };
- using iterator = Iterator;
- iterator begin() const {
- return Iterator(items_, first_index_, first_item_);
- }
- iterator end() const { return Iterator(nullptr, 0, nullptr); }
-
- private:
- const Vector<std::unique_ptr<NGFragmentItem>>* items_;
- const NGFragmentItem* first_item_;
- unsigned first_index_;
- };
- static ItemsForLayoutObject ItemsFor(const LayoutObject& layout_object);
static PhysicalRect LocalVisualRectFor(const LayoutObject& layout_object);
// Re-compute the ink overflow for the |cursor| until its end.
@@ -292,16 +276,21 @@ class CORE_EXPORT NGFragmentItem : public DisplayItemClient {
return TextType() == NGTextType::kSymbolMarker;
}
- const ShapeResultView* TextShapeResult() const;
+ bool IsFormattingContextRoot() const {
+ return BoxFragment() && !IsInlineBox();
+ }
- unsigned StartOffset() const;
- unsigned EndOffset() const;
- unsigned TextLength() const { return EndOffset() - StartOffset(); }
+ const ShapeResultView* TextShapeResult() const;
+ NGTextOffset TextOffset() const;
+ unsigned StartOffset() const { return TextOffset().start; }
+ unsigned EndOffset() const { return TextOffset().end; }
+ unsigned TextLength() const { return TextOffset().Length(); }
StringView Text(const NGFragmentItems& items) const;
String GeneratedText() const {
DCHECK_EQ(Type(), kGeneratedText);
return generated_text_.text;
}
+ NGTextFragmentPaintInfo TextPaintInfo(const NGFragmentItems& items) const;
// Compute the inline position from text offset, in logical coordinate
// relative to this fragment.
@@ -338,7 +327,6 @@ class CORE_EXPORT NGFragmentItem : public DisplayItemClient {
// Converts the given point, relative to the fragment itself, into a position
// in DOM tree.
- PositionWithAffinity PositionForPoint(const PhysicalOffset&) const;
PositionWithAffinity PositionForPointInText(
const PhysicalOffset& point,
const NGInlineCursor& cursor) const;
@@ -370,7 +358,7 @@ class CORE_EXPORT NGFragmentItem : public DisplayItemClient {
// Note: We should not add |bidi_level_| because it is used only for layout.
unsigned type_ : 2; // ItemType
- unsigned sub_type_ : 3; // NGTextType
+ unsigned sub_type_ : 3; // NGTextType or NGLineBoxType
unsigned style_variant_ : 2; // NGStyleVariant
// TODO(yosin): We'll remove |is_generated_text_| field when we construct
// |NGFragmentItem| without |NGPhysicalTextFragment| because usage of this
@@ -383,6 +371,8 @@ class CORE_EXPORT NGFragmentItem : public DisplayItemClient {
// Used only when |IsText()| to avoid re-computing ink overflow.
unsigned ink_overflow_computed_ : 1;
+
+ unsigned is_first_for_node_ : 1;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item_test.cc
index bc573b0d0d1..3e8f4853a6b 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item_test.cc
@@ -8,6 +8,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/layout/layout_block_flow.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_layout_test.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
@@ -22,9 +23,12 @@ class NGFragmentItemTest : public NGLayoutTest,
Vector<const NGFragmentItem*> ItemsForAsVector(
const LayoutObject& layout_object) {
- const auto items = NGFragmentItem::ItemsFor(layout_object);
Vector<const NGFragmentItem*> list;
- for (const NGFragmentItem& item : items) {
+ NGInlineCursor cursor;
+ for (cursor.MoveTo(layout_object); cursor;
+ cursor.MoveToNextForSameLayoutObject()) {
+ DCHECK(cursor.Current().Item());
+ const NGFragmentItem& item = *cursor.Current().Item();
EXPECT_EQ(item.GetLayoutObject(), &layout_object);
list.push_back(&item);
}
@@ -67,12 +71,12 @@ TEST_F(NGFragmentItemTest, BasicText) {
const NGFragmentItem& text1 = *items_for_text[0];
EXPECT_EQ(text1.Type(), NGFragmentItem::kText);
EXPECT_EQ(text1.GetLayoutObject(), layout_text);
- EXPECT_EQ(text1.Offset(), PhysicalOffset());
+ EXPECT_EQ(text1.OffsetInContainerBlock(), PhysicalOffset());
const NGFragmentItem& text2 = *items_for_text[1];
EXPECT_EQ(text2.Type(), NGFragmentItem::kText);
EXPECT_EQ(text2.GetLayoutObject(), layout_text);
- EXPECT_EQ(text2.Offset(), PhysicalOffset(0, 10));
+ EXPECT_EQ(text2.OffsetInContainerBlock(), PhysicalOffset(0, 10));
EXPECT_EQ(IntRect(0, 0, 70, 20),
layout_text->FragmentsVisualRectBoundingBox());
@@ -108,7 +112,6 @@ TEST_F(NGFragmentItemTest, BasicInlineBox) {
ASSERT_NE(span1, nullptr);
Vector<const NGFragmentItem*> items_for_span1 = ItemsForAsVector(*span1);
EXPECT_EQ(items_for_span1.size(), 2u);
-
EXPECT_EQ(IntRect(0, 0, 80, 20), span1->FragmentsVisualRectBoundingBox());
// "span2" doesn't wrap, produces only one fragment.
@@ -116,8 +119,52 @@ TEST_F(NGFragmentItemTest, BasicInlineBox) {
ASSERT_NE(span2, nullptr);
Vector<const NGFragmentItem*> items_for_span2 = ItemsForAsVector(*span2);
EXPECT_EQ(items_for_span2.size(), 1u);
+ EXPECT_EQ(IntRect(0, 20, 80, 10), span2->FragmentsVisualRectBoundingBox());
+}
+// Same as |BasicInlineBox| but `<span>`s do not have background.
+// They will not need box fragments, but all operations should work the same.
+TEST_F(NGFragmentItemTest, CulledInlineBox) {
+ LoadAhem();
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ html, body {
+ margin: 0;
+ font-family: Ahem;
+ font-size: 10px;
+ line-height: 1;
+ }
+ #container {
+ width: 10ch;
+ }
+ </style>
+ <div id="container">
+ 000
+ <span id="span1">1234 5678</span>
+ 999
+ <span id="span2">12345678</span>
+ </div>
+ )HTML");
+
+ // "span1" wraps, produces two fragments.
+ const LayoutObject* span1 = GetLayoutObjectByElementId("span1");
+ ASSERT_NE(span1, nullptr);
+ Vector<const NGFragmentItem*> items_for_span1 = ItemsForAsVector(*span1);
+ EXPECT_EQ(items_for_span1.size(), 2u);
+ EXPECT_EQ(IntRect(0, 0, 80, 20), span1->FragmentsVisualRectBoundingBox());
+
+ // "span2" doesn't wrap, produces only one fragment.
+ const LayoutObject* span2 = GetLayoutObjectByElementId("span2");
+ ASSERT_NE(span2, nullptr);
+ Vector<const NGFragmentItem*> items_for_span2 = ItemsForAsVector(*span2);
+ EXPECT_EQ(items_for_span2.size(), 1u);
EXPECT_EQ(IntRect(0, 20, 80, 10), span2->FragmentsVisualRectBoundingBox());
+
+ // Except that they do not produce box fragments.
+ for (const NGFragmentItem* item : items_for_span1)
+ EXPECT_EQ(item->BoxFragment(), nullptr);
+ for (const NGFragmentItem* item : items_for_span2)
+ EXPECT_EQ(item->BoxFragment(), nullptr);
}
} // namespace blink
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 87aba81920f..794995bd7bc 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
@@ -13,4 +13,35 @@ NGFragmentItems::NGFragmentItems(NGFragmentItemsBuilder* builder)
text_content_(std::move(builder->text_content_)),
first_line_text_content_(std::move(builder->first_line_text_content_)) {}
+// static
+void NGFragmentItems::AssociateWithLayoutObject(
+ Vector<std::unique_ptr<NGFragmentItem>>* items) {
+ // items_[0] can be:
+ // - kBox for list marker, e.g. <li>abc</li>
+ // - kLine for line, e.g. <div>abc</div>
+ // Calling get() is necessary below because operator<< in std::unique_ptr is
+ // a C++20 feature.
+ // TODO(https://crbug.com/980914): Drop .get() once we move to C++20.
+ DCHECK(items->IsEmpty() || (*items)[0]->IsContainer()) << (*items)[0].get();
+ HashMap<const LayoutObject*, wtf_size_t> last_fragment_map;
+ for (wtf_size_t index = 1u; index < items->size(); ++index) {
+ const NGFragmentItem& item = *(*items)[index];
+ if (item.Type() == NGFragmentItem::kLine)
+ continue;
+ LayoutObject* const layout_object = item.GetMutableLayoutObject();
+ DCHECK(layout_object->IsInLayoutNGInlineFormattingContext()) << item;
+ auto insert_result = last_fragment_map.insert(layout_object, index);
+ if (insert_result.is_new_entry) {
+ layout_object->SetFirstInlineFragmentItemIndex(index);
+ continue;
+ }
+ 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);
+ (*items)[last_index]->SetDeltaToNextForSameLayoutObject(index - last_index);
+ }
+}
+
} // namespace blink
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 fe62f758e81..76c95f180a5 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
@@ -28,6 +28,9 @@ class CORE_EXPORT NGFragmentItems {
return UNLIKELY(first_line) ? first_line_text_content_ : text_content_;
}
+ static void AssociateWithLayoutObject(
+ Vector<std::unique_ptr<NGFragmentItem>>* items);
+
private:
// TODO(kojii): inline capacity TBD.
Vector<std::unique_ptr<NGFragmentItem>> items_;
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 fd54d34056f..243c9d3622c 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
@@ -30,8 +30,8 @@ void NGFragmentItemsBuilder::SetCurrentLine(
void NGFragmentItemsBuilder::AddLine(const NGPhysicalLineBoxFragment& line,
const LogicalOffset& offset) {
DCHECK_EQ(items_.size(), offsets_.size());
-#if DCHECK_IS_ON()
DCHECK(!is_converted_to_physical_);
+#if DCHECK_IS_ON()
DCHECK_EQ(current_line_fragment_, &line);
#endif
@@ -65,36 +65,40 @@ void NGFragmentItemsBuilder::AddLine(const NGPhysicalLineBoxFragment& line,
void NGFragmentItemsBuilder::AddItems(Child* child_begin, Child* child_end) {
DCHECK_EQ(items_.size(), offsets_.size());
+ DCHECK(!is_converted_to_physical_);
for (Child* child_iter = child_begin; child_iter != child_end;) {
Child& child = *child_iter;
if (const NGPhysicalTextFragment* text = child.fragment.get()) {
items_.push_back(std::make_unique<NGFragmentItem>(*text));
- offsets_.push_back(child.offset);
+ offsets_.push_back(child.rect.offset);
++child_iter;
continue;
}
- if (child.layout_result) {
+ if (child.layout_result || child.inline_item) {
// Create an item if this box has no inline children.
- const NGPhysicalBoxFragment& box =
- To<NGPhysicalBoxFragment>(child.layout_result->PhysicalFragment());
- // Floats are in the fragment tree, not in the fragment item list.
- DCHECK(!box.IsFloating());
+ std::unique_ptr<NGFragmentItem> item;
+ if (child.layout_result) {
+ const NGPhysicalBoxFragment& box =
+ To<NGPhysicalBoxFragment>(child.layout_result->PhysicalFragment());
+ item = std::make_unique<NGFragmentItem>(box, child.ResolvedDirection());
+ } else {
+ DCHECK(child.inline_item);
+ item = std::make_unique<NGFragmentItem>(
+ *child.inline_item,
+ ToPhysicalSize(child.rect.size,
+ child.inline_item->Style()->GetWritingMode()));
+ }
+ // Take the fast path when we know |child| does not have child items.
if (child.children_count <= 1) {
- // Compute |has_floating_descendants_for_paint_| to optimize tree
- // traversal in paint.
- if (!has_floating_descendants_for_paint_ && box.IsFloating())
- has_floating_descendants_for_paint_ = true;
-
- DCHECK(child.HasBidiLevel());
- items_.push_back(std::make_unique<NGFragmentItem>(
- box, 1, DirectionFromLevel(child.bidi_level)));
- offsets_.push_back(child.offset);
+ items_.push_back(std::move(item));
+ offsets_.push_back(child.rect.offset);
++child_iter;
continue;
}
+ DCHECK(!item->IsFloating());
// Children of inline boxes are flattened and added to |items_|, with the
// count of descendant items to preserve the tree structure.
@@ -102,7 +106,7 @@ void NGFragmentItemsBuilder::AddItems(Child* child_begin, Child* child_end) {
// Add an empty item so that the start of the box can be set later.
wtf_size_t box_start_index = items_.size();
items_.Grow(box_start_index + 1);
- offsets_.push_back(child.offset);
+ offsets_.push_back(child.rect.offset);
// Add all children, including their desendants, skipping this item.
CHECK_GE(child.children_count, 1u); // 0 will loop infinitely.
@@ -116,9 +120,8 @@ void NGFragmentItemsBuilder::AddItems(Child* child_begin, Child* child_end) {
wtf_size_t item_count = items_.size() - box_start_index;
// Create an item for the start of the box.
- DCHECK(child.HasBidiLevel());
- items_[box_start_index] = std::make_unique<NGFragmentItem>(
- box, item_count, DirectionFromLevel(child.bidi_level));
+ item->SetDescendantsCount(item_count);
+ items_[box_start_index] = std::move(item);
continue;
}
@@ -132,23 +135,36 @@ void NGFragmentItemsBuilder::AddItems(Child* child_begin, Child* child_end) {
void NGFragmentItemsBuilder::AddListMarker(
const NGPhysicalBoxFragment& marker_fragment,
const LogicalOffset& offset) {
+ DCHECK(!is_converted_to_physical_);
+
// Resolved direction matters only for inline items, and outside list markers
// are not inline.
const TextDirection resolved_direction = TextDirection::kLtr;
items_.push_back(
- std::make_unique<NGFragmentItem>(marker_fragment, 1, resolved_direction));
+ std::make_unique<NGFragmentItem>(marker_fragment, resolved_direction));
offsets_.push_back(offset);
}
+const Vector<std::unique_ptr<NGFragmentItem>>& NGFragmentItemsBuilder::Items(
+ WritingMode writing_mode,
+ TextDirection direction,
+ const PhysicalSize& outer_size) {
+ ConvertToPhysical(writing_mode, direction, 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) {
CHECK_EQ(items_.size(), offsets_.size());
-#if DCHECK_IS_ON()
- DCHECK(!is_converted_to_physical_);
-#endif
+ if (is_converted_to_physical_)
+ return;
+
+ // Children of lines have line-relative offsets. Use line-writing mode to
+ // convert their logical offsets.
+ const WritingMode line_writing_mode = ToLineWritingMode(writing_mode);
std::unique_ptr<NGFragmentItem>* item_iter = items_.begin();
const LogicalOffset* offset = offsets_.begin();
@@ -165,7 +181,7 @@ void NGFragmentItemsBuilder::ConvertToPhysical(WritingMode writing_mode,
unsigned descendants_count = item->DescendantsCount();
DCHECK(descendants_count);
if (descendants_count) {
- const PhysicalRect line_box_bounds = item->Rect();
+ const PhysicalRect line_box_bounds = item->RectInContainerBlock();
while (--descendants_count) {
++offset;
++item_iter;
@@ -175,7 +191,7 @@ void NGFragmentItemsBuilder::ConvertToPhysical(WritingMode writing_mode,
// Use `kLtr` because inline items are after bidi-reoder, and that
// their offset is visual, not logical.
item->SetOffset(
- offset->ConvertToPhysical(writing_mode, TextDirection::kLtr,
+ offset->ConvertToPhysical(line_writing_mode, TextDirection::kLtr,
line_box_bounds.size, item->Size()) +
line_box_bounds.offset);
}
@@ -183,9 +199,17 @@ void NGFragmentItemsBuilder::ConvertToPhysical(WritingMode writing_mode,
}
}
-#if DCHECK_IS_ON()
is_converted_to_physical_ = true;
-#endif
+}
+
+base::Optional<LogicalOffset> NGFragmentItemsBuilder::LogicalOffsetFor(
+ const LayoutObject& layout_object) const {
+ DCHECK_EQ(items_.size(), offsets_.size());
+ for (const std::unique_ptr<NGFragmentItem>& item : items_) {
+ if (item->GetLayoutObject() == &layout_object)
+ return offsets_[&item - items_.begin()];
+ }
+ return base::nullopt;
}
void NGFragmentItemsBuilder::ToFragmentItems(WritingMode writing_mode,
@@ -193,39 +217,8 @@ void NGFragmentItemsBuilder::ToFragmentItems(WritingMode writing_mode,
const PhysicalSize& outer_size,
void* data) {
ConvertToPhysical(writing_mode, direction, outer_size);
- AssociateNextForSameLayoutObject();
+ NGFragmentItems::AssociateWithLayoutObject(&items_);
new (data) NGFragmentItems(this);
}
-void NGFragmentItemsBuilder::AssociateNextForSameLayoutObject() {
- // items_[0] can be:
- // - kBox for list marker, e.g. <li>abc</li>
- // - kLine for line, e.g. <div>abc</div>
- // Calling get() is necessary below because operator<< in std::unique_ptr is
- // a C++20 feature.
- // TODO(https://crbug.com/980914): Drop .get() once we move to C++20.
- DCHECK(items_.IsEmpty() || items_[0]->IsContainer()) << items_[0].get();
- HashMap<const LayoutObject*, wtf_size_t> last_fragment_map;
- for (wtf_size_t index = 1u; index < items_.size(); ++index) {
- const NGFragmentItem& item = *items_[index];
- if (item.Type() == NGFragmentItem::kLine)
- continue;
- LayoutObject* const layout_object = item.GetMutableLayoutObject();
- DCHECK(layout_object->IsInLayoutNGInlineFormattingContext()) << item;
- auto insert_result = last_fragment_map.insert(layout_object, index);
- if (insert_result.is_new_entry) {
- // TDOO(yosin): Once we update all |LayoutObject::FirstInlineFragment()|,
- // we should enable below.
- // layout_object->SetFirstInlineFragmentItemIndex(index);
- continue;
- }
- 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);
- items_[last_index]->SetDeltaToNextForSameLayoutObject(index - last_index);
- }
-}
-
} // namespace blink
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 eef2fc77231..84be85e4132 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
@@ -59,10 +59,21 @@ class CORE_EXPORT NGFragmentItemsBuilder {
void AddListMarker(const NGPhysicalBoxFragment& marker_fragment,
const LogicalOffset& offset);
+ // Find |LogicalOffset| of the first |NGFragmentItem| for |LayoutObject|.
+ base::Optional<LogicalOffset> LogicalOffsetFor(const LayoutObject&) const;
+
+ // Converts the |NGFragmentItem| vector to the physical coordinate space and
+ // returns the result. This should only be used for determining the inline
+ // containing block geometry for OOF-positioned nodes.
+ //
+ // Once this method has been called, new items cannot be added.
+ const Vector<std::unique_ptr<NGFragmentItem>>&
+ Items(WritingMode, TextDirection, const PhysicalSize& outer_size);
+
// Build a |NGFragmentItems|. The builder cannot build twice because data set
// to this builder may be cleared.
- void ToFragmentItems(WritingMode writing_mode,
- TextDirection direction,
+ void ToFragmentItems(WritingMode,
+ TextDirection,
const PhysicalSize& outer_size,
void* data);
@@ -73,8 +84,6 @@ class CORE_EXPORT NGFragmentItemsBuilder {
TextDirection direction,
const PhysicalSize& outer_size);
- void AssociateNextForSameLayoutObject();
-
Vector<std::unique_ptr<NGFragmentItem>> items_;
Vector<LogicalOffset> offsets_;
String text_content_;
@@ -84,10 +93,10 @@ class CORE_EXPORT NGFragmentItemsBuilder {
ChildList current_line_;
bool has_floating_descendants_for_paint_ = false;
+ bool is_converted_to_physical_ = false;
#if DCHECK_IS_ON()
const NGPhysicalLineBoxFragment* current_line_fragment_ = nullptr;
- bool is_converted_to_physical_ = false;
#endif
friend class NGFragmentItems;
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 f2c2f03927e..cc0d8d8d3b4 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
@@ -105,7 +105,8 @@ bool NGInlineBoxState::CanAddTextOfStyle(
NGInlineBoxState* NGInlineLayoutStateStack::OnBeginPlaceItems(
const ComputedStyle& line_style,
FontBaseline baseline_type,
- bool line_height_quirk) {
+ bool line_height_quirk,
+ NGLineBoxFragmentBuilder::ChildList* line_box) {
if (stack_.IsEmpty()) {
// For the first line, push a box state for the line itself.
stack_.resize(1);
@@ -114,7 +115,9 @@ NGInlineBoxState* NGInlineLayoutStateStack::OnBeginPlaceItems(
} else {
// For the following lines, clear states that are not shared across lines.
for (NGInlineBoxState& box : stack_) {
- box.fragment_start = 0;
+ box.fragment_start = line_box->size();
+ if (&box != stack_.begin())
+ AddBoxFragmentPlaceholder(&box, line_box, baseline_type);
if (!line_height_quirk)
box.metrics = box.text_metrics;
else
@@ -133,15 +136,15 @@ NGInlineBoxState* NGInlineLayoutStateStack::OnBeginPlaceItems(
DCHECK(box_data_list_.IsEmpty());
// Initialize the box state for the line box.
- NGInlineBoxState& line_box = LineBoxState();
- if (line_box.style != &line_style) {
- line_box.style = &line_style;
+ NGInlineBoxState& line_box_state = LineBoxState();
+ if (line_box_state.style != &line_style) {
+ line_box_state.style = &line_style;
// Use a "strut" (a zero-width inline box with the element's font and
// line height properties) as the initial metrics for the line box.
// https://drafts.csswg.org/css2/visudet.html#strut
if (!line_height_quirk)
- line_box.ComputeTextMetrics(line_style, baseline_type);
+ line_box_state.ComputeTextMetrics(line_style, baseline_type);
}
return &stack_.back();
@@ -150,31 +153,32 @@ NGInlineBoxState* NGInlineLayoutStateStack::OnBeginPlaceItems(
NGInlineBoxState* NGInlineLayoutStateStack::OnOpenTag(
const NGInlineItem& item,
const NGInlineItemResult& item_result,
- const NGLineBoxFragmentBuilder::ChildList& line_box) {
- DCHECK(item.Style());
- NGInlineBoxState* box = OnOpenTag(*item.Style(), line_box);
- box->item = &item;
-
- if (item.ShouldCreateBoxFragment())
- box->SetNeedsBoxFragment();
-
- // Compute box properties regardless of needs_box_fragment since close tag may
- // also set needs_box_fragment.
- box->has_start_edge = item_result.has_edge;
- box->margin_inline_start = item_result.margins.inline_start;
- box->margin_inline_end = item_result.margins.inline_end;
- box->borders = item_result.borders;
- box->padding = item_result.padding;
+ FontBaseline baseline_type,
+ NGLineBoxFragmentBuilder::ChildList* line_box) {
+ NGInlineBoxState* box =
+ OnOpenTag(item, item_result, baseline_type, *line_box);
+ box->needs_box_fragment = item.ShouldCreateBoxFragment();
+ AddBoxFragmentPlaceholder(box, line_box, baseline_type);
return box;
}
NGInlineBoxState* NGInlineLayoutStateStack::OnOpenTag(
- const ComputedStyle& style,
+ const NGInlineItem& item,
+ const NGInlineItemResult& item_result,
+ FontBaseline baseline_type,
const NGLineBoxFragmentBuilder::ChildList& line_box) {
+ DCHECK(item.Style());
+ const ComputedStyle& style = *item.Style();
stack_.resize(stack_.size() + 1);
NGInlineBoxState* box = &stack_.back();
box->fragment_start = line_box.size();
box->style = &style;
+ box->item = &item;
+ box->has_start_edge = item_result.has_edge;
+ box->margin_inline_start = item_result.margins.inline_start;
+ box->margin_inline_end = item_result.margins.inline_end;
+ box->borders = item_result.borders;
+ box->padding = item_result.padding;
return box;
}
@@ -209,9 +213,9 @@ void NGInlineLayoutStateStack::OnEndPlaceItems(
// Copy the final offset to |box_data_list_|.
for (BoxData& box_data : box_data_list_) {
const NGLineBoxFragmentBuilder::Child& placeholder =
- (*line_box)[box_data.fragment_end];
- DCHECK(!placeholder.HasFragment());
- box_data.offset = placeholder.offset;
+ (*line_box)[box_data.fragment_start];
+ DCHECK(placeholder.IsPlaceholder());
+ box_data.rect.offset = placeholder.rect.offset;
}
}
@@ -219,8 +223,13 @@ void NGInlineLayoutStateStack::EndBoxState(
NGInlineBoxState* box,
NGLineBoxFragmentBuilder::ChildList* line_box,
FontBaseline baseline_type) {
- if (box->needs_box_fragment)
- AddBoxFragmentPlaceholder(box, line_box, baseline_type);
+ if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ if (box->needs_box_fragment)
+ AddBoxData(box, line_box);
+ } else {
+ if (box->has_box_placeholder)
+ AddBoxData(box, line_box);
+ }
PositionPending position_pending =
ApplyBaselineShift(box, line_box, baseline_type);
@@ -237,12 +246,6 @@ void NGInlineLayoutStateStack::EndBoxState(
parent_box.metrics.Unite(box->metrics);
}
-void NGInlineBoxState::SetNeedsBoxFragment() {
- DCHECK(item);
- DCHECK(!needs_box_fragment);
- needs_box_fragment = true;
-}
-
// Crete a placeholder for a box fragment.
// We keep a flat list of fragments because it is more suitable for operations
// such as ApplyBaselineShift. Later, CreateBoxFragments() creates box fragments
@@ -251,12 +254,14 @@ void NGInlineLayoutStateStack::AddBoxFragmentPlaceholder(
NGInlineBoxState* box,
NGLineBoxFragmentBuilder::ChildList* line_box,
FontBaseline baseline_type) {
- DCHECK(box->needs_box_fragment);
+ DCHECK(box != stack_.begin() &&
+ box->item->Type() != NGInlineItem::kAtomicInline);
+ box->has_box_placeholder = true;
DCHECK(box->style);
const ComputedStyle& style = *box->style;
- LogicalOffset offset;
- LogicalSize size;
+ LayoutUnit block_offset;
+ LayoutUnit block_size;
if (!is_empty_line_) {
// The inline box should have the height of the font metrics without the
// line-height property. Compute from style because |box->metrics| includes
@@ -265,63 +270,78 @@ void NGInlineLayoutStateStack::AddBoxFragmentPlaceholder(
// Extend the block direction of the box by borders and paddings. Inline
// direction is already included into positions in NGLineBreaker.
- offset.block_offset =
+ block_offset =
-metrics.ascent - (box->borders.line_over + box->padding.line_over);
- size.block_size = metrics.LineHeight() + box->borders.BlockSum() +
- box->padding.BlockSum();
+ block_size = metrics.LineHeight() + box->borders.BlockSum() +
+ box->padding.BlockSum();
}
+ line_box->AddChild(block_offset, block_size);
+ DCHECK((*line_box)[line_box->size() - 1].IsPlaceholder());
+}
- unsigned fragment_end = line_box->size();
+// 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));
+ DCHECK(box->style);
+ const ComputedStyle& style = *box->style;
+ NGLineBoxFragmentBuilder::Child& 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, size);
- 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);
- }
-
- if (fragment_end > box->fragment_start) {
- // The start is marked only in BoxData, while end is marked
- // in both BoxData and the list itself.
- // With a list of 4 text fragments:
- // | 0 | 1 | 2 | 3 |
- // |text0|text1|text2|text3|
- // By adding a BoxData(2,4) (end is exclusive), it becomes:
- // | 0 | 1 | 2 | 3 | 4 |
- // |text0|text1|text2|text3|null |
- // The "null" is added to the list to compute baseline shift of the box
- // separately from text fragments.
- line_box->AddChild(offset);
+ 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 {
- // Do not defer creating a box fragment if this is an empty inline box.
- // An empty box fragment is still flat that we do not have to defer.
- // Also, placeholders cannot be reordred if empty.
- offset.inline_offset += box_data.margin_line_left;
- LayoutUnit advance = box_data.margin_border_padding_line_left +
- box_data.margin_border_padding_line_right;
- box_data.size.inline_size =
- advance - box_data.margin_line_left - box_data.margin_line_right;
- line_box->AddChild(box_data.CreateBoxFragment(line_box), offset, advance,
- /* bidi_level */ 0);
- box_data_list_.pop_back();
+ DCHECK_EQ(box->margin_inline_start, 0);
+ DCHECK_EQ(box->margin_inline_end, 0);
+ DCHECK(box->padding.IsEmpty());
+ DCHECK(box->borders.IsEmpty());
}
+
+ DCHECK((*line_box)[box->fragment_start].IsPlaceholder());
+ DCHECK_GT(fragment_end, box->fragment_start);
+ if (fragment_end > box->fragment_start + 1)
+ return;
+
+ // Do not defer creating a box fragment if this is an empty inline box.
+ // An empty box fragment is still flat that we do not have to defer.
+ // Also, placeholders cannot be reordred if empty.
+ placeholder.rect.offset.inline_offset += box_data.margin_line_left;
+ LayoutUnit advance = box_data.margin_border_padding_line_left +
+ box_data.margin_border_padding_line_right;
+ box_data.rect.size.inline_size =
+ advance - box_data.margin_line_left - box_data.margin_line_right;
+ placeholder.layout_result = box_data.CreateBoxFragment(line_box);
+ placeholder.inline_size = advance;
+ DCHECK(!placeholder.children_count);
+ box_data_list_.pop_back();
}
void NGInlineLayoutStateStack::ChildInserted(unsigned index) {
@@ -348,20 +368,26 @@ void NGInlineLayoutStateStack::PrepareForReorder(
unsigned box_data_index = 0;
for (const BoxData& box_data : box_data_list_) {
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];
- if (!child.box_data_index)
+ unsigned child_box_data_index = child.box_data_index;
+ if (!child_box_data_index) {
child.box_data_index = box_data_index;
- }
- }
+ continue;
+ }
- // When boxes are nested, placeholders have indexes to which box it should be
- // added. Copy them to BoxData.
- for (BoxData& box_data : box_data_list_) {
- const NGLineBoxFragmentBuilder::Child& placeholder =
- (*line_box)[box_data.fragment_end];
- DCHECK(!placeholder.HasFragment());
- box_data.parent_box_data_index = placeholder.box_data_index;
+ // This |box_data| has child boxes. Set up |parent_box_data_index| to
+ // represent the box nesting structure.
+ while (child_box_data_index != box_data_index) {
+ BoxData* child_box_data = &box_data_list_[child_box_data_index - 1];
+ child_box_data_index = child_box_data->parent_box_data_index;
+ if (!child_box_data_index) {
+ child_box_data->parent_box_data_index = box_data_index;
+ break;
+ }
+ }
+ }
}
}
@@ -491,8 +517,8 @@ LayoutUnit NGInlineLayoutStateStack::ComputeInlinePositions(
// origins at (0, 0). Accumulate inline offset from left to right.
LayoutUnit position;
for (NGLineBoxFragmentBuilder::Child& child : *line_box) {
- child.margin_line_left = child.offset.inline_offset;
- child.offset.inline_offset += position;
+ child.margin_line_left = child.rect.offset.inline_offset;
+ child.rect.offset.inline_offset += position;
// Box margins/boders/paddings will be processed later.
// TODO(kojii): we could optimize this if the reordering did not occur.
if (!child.HasFragment())
@@ -538,7 +564,7 @@ LayoutUnit NGInlineLayoutStateStack::ComputeInlinePositions(
unsigned start = box_data.fragment_start;
NGLineBoxFragmentBuilder::Child& start_child = (*line_box)[start];
LayoutUnit line_left_offset =
- start_child.offset.inline_offset - start_child.margin_line_left;
+ start_child.rect.offset.inline_offset - start_child.margin_line_left;
LinePadding& start_padding = accumulated_padding[start];
start_padding.line_left += box_data.margin_border_padding_line_left;
line_left_offset -= start_padding.line_left - box_data.margin_line_left;
@@ -546,15 +572,15 @@ LayoutUnit NGInlineLayoutStateStack::ComputeInlinePositions(
DCHECK_GT(box_data.fragment_end, start);
unsigned last = box_data.fragment_end - 1;
NGLineBoxFragmentBuilder::Child& last_child = (*line_box)[last];
- LayoutUnit line_right_offset = last_child.offset.inline_offset -
+ LayoutUnit line_right_offset = last_child.rect.offset.inline_offset -
last_child.margin_line_left +
last_child.inline_size;
LinePadding& last_padding = accumulated_padding[last];
last_padding.line_right += box_data.margin_border_padding_line_right;
line_right_offset += last_padding.line_right - box_data.margin_line_right;
- box_data.offset.inline_offset = line_left_offset;
- box_data.size.inline_size = line_right_offset - line_left_offset;
+ box_data.rect.offset.inline_offset = line_left_offset;
+ box_data.rect.size.inline_size = line_right_offset - line_left_offset;
}
return position;
@@ -569,24 +595,38 @@ void NGInlineLayoutStateStack::CreateBoxFragments(
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;
+ }
- scoped_refptr<const NGLayoutResult> box_fragment =
- box_data.CreateBoxFragment(line_box);
- if (!child->HasFragment()) {
- child->layout_result = std::move(box_fragment);
- child->offset = box_data.offset;
- child->children_count = end - start;
- } else {
- // In most cases, |start_child| is moved to the children of the box, and
- // is empty. It's not empty when it's out-of-flow. Insert in such case.
- // TODO(kojii): With |NGFragmentItem|, all cases hit this code. Consider
- // creating an empty item beforehand to avoid inserting.
- line_box->InsertChild(start, std::move(box_fragment), box_data.offset,
- LayoutUnit(), 0);
+ // |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);
- child = &(*line_box)[start];
- child->children_count = end - start + 1;
+ continue;
+ }
+
+ DCHECK(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
+ DCHECK(box_data.item);
+ if (child->IsPlaceholder()) {
+ child->inline_item = box_data.item;
+ 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, *box_data.item, box_data.rect,
+ end - start + 1);
+ ChildInserted(start + 1);
}
box_data_list_.clear();
@@ -600,8 +640,8 @@ NGInlineLayoutStateStack::BoxData::CreateBoxFragment(
const ComputedStyle& style = *item->Style();
NGFragmentGeometry fragment_geometry;
- fragment_geometry.border_box_size = {size.inline_size.ClampNegativeToZero(),
- size.block_size};
+ fragment_geometry.border_box_size = {
+ rect.size.inline_size.ClampNegativeToZero(), rect.size.block_size};
fragment_geometry.padding =
NGBoxStrut(padding, IsFlippedLinesWritingMode(style.GetWritingMode()));
@@ -618,6 +658,8 @@ NGInlineLayoutStateStack::BoxData::CreateBoxFragment(
// supported today.
box.SetBorderEdges({true, has_line_right_edge, true, has_line_left_edge});
+ box.SetIsFirstForNode(has_line_left_edge);
+
for (unsigned i = fragment_start; i < fragment_end; i++) {
NGLineBoxFragmentBuilder::Child& child = (*line_box)[i];
if (child.out_of_flow_positioned_box) {
@@ -627,7 +669,7 @@ NGInlineLayoutStateStack::BoxData::CreateBoxFragment(
// child.offset is the static position wrt. the linebox. As we are adding
// this as a child of an inline level fragment, we adjust the static
// position to be relative to this fragment.
- LogicalOffset static_offset = child.offset - offset;
+ LogicalOffset static_offset = child.rect.offset - rect.offset;
box.AddOutOfFlowInlineChildCandidate(oof_box, static_offset,
child.container_direction);
@@ -636,24 +678,33 @@ NGInlineLayoutStateStack::BoxData::CreateBoxFragment(
}
if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
- // |NGFragmentItems| has a flat list of all descendants, except OOF
- // objects. Still creates |NGPhysicalBoxFragment|, but don't add children
- // to it and keep them in the flat list.
+ // Propagate any OOF-positioned descendants from any atomic-inlines, etc.
+ if (child.layout_result) {
+ box.PropagateChildData(child.layout_result->PhysicalFragment(),
+ child.rect.offset - rect.offset);
+ }
+
+ // |NGFragmentItems| has a flat list of all descendants, except
+ // OOF-positioned descendants.
+ // We still create a |NGPhysicalBoxFragment|, but don't add children to
+ // it and keep them in the flat list.
continue;
}
if (child.layout_result) {
box.AddChild(child.layout_result->PhysicalFragment(),
- child.offset - offset);
+ child.rect.offset - rect.offset);
child.layout_result.reset();
} else if (child.fragment) {
- box.AddChild(std::move(child.fragment), child.offset - offset);
+ box.AddChild(std::move(child.fragment), child.rect.offset - rect.offset);
}
}
- // Inline boxes that produce DisplayItemClient should do full paint
- // invalidations.
- item->GetLayoutObject()->SetShouldDoFullPaintInvalidation();
+ if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ // Inline boxes that produce DisplayItemClient should do full paint
+ // invalidations.
+ item->GetLayoutObject()->SetShouldDoFullPaintInvalidation();
+ }
box.MoveOutOfFlowDescendantCandidatesToDescendants();
return box.ToInlineBoxFragment();
@@ -826,10 +877,12 @@ NGLineHeightMetrics NGInlineLayoutStateStack::MetricsForTopAndBottomAlign(
continue;
// |block_offset| is the top position when the baseline is at 0.
- LayoutUnit box_ascent =
- -line_box[box_data.fragment_end].offset.block_offset;
+ const NGLineBoxFragmentBuilder::Child& placeholder =
+ line_box[box_data.fragment_start];
+ DCHECK(placeholder.IsPlaceholder());
+ LayoutUnit box_ascent = -placeholder.rect.offset.block_offset;
NGLineHeightMetrics box_metrics(box_ascent,
- box_data.size.block_size - box_ascent);
+ box_data.rect.size.block_size - box_ascent);
// The top/bottom of inline boxes should not include their paddings.
box_metrics.ascent -= box_data.padding.line_over;
box_metrics.descent -= box_data.padding.line_under;
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 066225e80ec..2431f010067 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
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_INLINE_BOX_STATE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_INLINE_BOX_STATE_H_
-#include "third_party/blink/renderer/core/layout/geometry/logical_size.h"
+#include "third_party/blink/renderer/core/layout/geometry/logical_rect.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_line_height_metrics.h"
#include "third_party/blink/renderer/core/style/computed_style_constants.h"
@@ -67,6 +67,7 @@ struct NGInlineBoxState {
Vector<NGPendingPositions> pending_descendants;
bool include_used_fonts = false;
+ bool has_box_placeholder = false;
bool needs_box_fragment = false;
// True if this box has a metrics, including pending ones. Pending metrics
@@ -88,9 +89,6 @@ struct NGInlineBoxState {
// 'text-top' offset for 'vertical-align'.
LayoutUnit TextTop(FontBaseline baseline_type) const;
- // Create a box fragment for this box.
- void SetNeedsBoxFragment();
-
// Returns if the text style can be added without open-tag.
// Text with different font or vertical-align needs to be wrapped with an
// inline box.
@@ -116,14 +114,22 @@ 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);
+ NGInlineBoxState* OnBeginPlaceItems(
+ const ComputedStyle&,
+ FontBaseline,
+ bool line_height_quirk,
+ NGLineBoxFragmentBuilder::ChildList* line_box);
// Push a box state stack.
NGInlineBoxState* OnOpenTag(const NGInlineItem&,
const NGInlineItemResult&,
+ FontBaseline baseline_type,
const NGLineBoxFragmentBuilder::ChildList&);
- NGInlineBoxState* OnOpenTag(const ComputedStyle&,
- const NGLineBoxFragmentBuilder::ChildList&);
+ // This variation adds a box placeholder to |line_box|.
+ NGInlineBoxState* OnOpenTag(const NGInlineItem&,
+ const NGInlineItemResult&,
+ FontBaseline baseline_type,
+ NGLineBoxFragmentBuilder::ChildList* line_box);
// Pop a box state stack.
NGInlineBoxState* OnCloseTag(NGLineBoxFragmentBuilder::ChildList*,
@@ -182,6 +188,7 @@ class CORE_EXPORT NGInlineLayoutStateStack {
void AddBoxFragmentPlaceholder(NGInlineBoxState*,
NGLineBoxFragmentBuilder::ChildList*,
FontBaseline);
+ void AddBoxData(NGInlineBoxState*, NGLineBoxFragmentBuilder::ChildList*);
enum PositionPending { kPositionNotPending, kPositionPending };
@@ -208,14 +215,16 @@ class CORE_EXPORT NGInlineLayoutStateStack {
unsigned end,
const NGInlineItem* item,
LogicalSize size)
- : fragment_start(start), fragment_end(end), item(item), size(size) {}
+ : fragment_start(start),
+ fragment_end(end),
+ item(item),
+ rect(LogicalOffset(), size) {}
BoxData(const BoxData& other, unsigned start, unsigned end)
: fragment_start(start),
fragment_end(end),
item(other.item),
- size(other.size),
- offset(other.offset) {}
+ rect(other.rect) {}
void SetFragmentRange(unsigned start_index, unsigned end_index) {
fragment_start = start_index;
@@ -227,7 +236,7 @@ class CORE_EXPORT NGInlineLayoutStateStack {
unsigned fragment_end;
const NGInlineItem* item;
- LogicalSize size;
+ LogicalRect rect;
bool has_line_left_edge = false;
bool has_line_right_edge = false;
@@ -238,7 +247,6 @@ class CORE_EXPORT NGInlineLayoutStateStack {
LayoutUnit margin_border_padding_line_left;
LayoutUnit margin_border_padding_line_right;
- LogicalOffset offset;
unsigned parent_box_data_index = 0;
unsigned fragmented_box_data_index = 0;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc
index 3a9b6f7814d..0485ed7dbb4 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.cc
@@ -22,6 +22,7 @@ static_assert(sizeof(NGInlineBreakToken) ==
} // namespace
NGInlineBreakToken::NGInlineBreakToken(
+ PassKey key,
NGInlineNode node,
const ComputedStyle* style,
unsigned item_index,
@@ -34,7 +35,7 @@ NGInlineBreakToken::NGInlineBreakToken(
flags_ = flags;
}
-NGInlineBreakToken::NGInlineBreakToken(NGLayoutInputNode node)
+NGInlineBreakToken::NGInlineBreakToken(PassKey key, NGLayoutInputNode node)
: NGBreakToken(kInlineBreakToken, kFinished, node),
item_index_(0),
text_offset_(0) {}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h
index fdf2ebdccde..6558270e9cd 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h
@@ -31,13 +31,13 @@ class CORE_EXPORT NGInlineBreakToken final : public NGBreakToken {
unsigned item_index,
unsigned text_offset,
unsigned flags /* NGInlineBreakTokenFlags */) {
- return base::AdoptRef(
- new NGInlineBreakToken(node, style, item_index, text_offset, flags));
+ return base::AdoptRef(new NGInlineBreakToken(
+ PassKey(), node, style, item_index, text_offset, flags));
}
// Creates a break token for a node which cannot produce any more fragments.
static scoped_refptr<NGInlineBreakToken> Create(NGLayoutInputNode node) {
- return base::AdoptRef(new NGInlineBreakToken(node));
+ return base::AdoptRef(new NGInlineBreakToken(PassKey(), node));
}
~NGInlineBreakToken() override;
@@ -69,19 +69,21 @@ class CORE_EXPORT NGInlineBreakToken final : public NGBreakToken {
return flags_ & kIsForcedBreak;
}
-#if DCHECK_IS_ON()
- String ToString() const override;
-#endif
-
- private:
- NGInlineBreakToken(NGInlineNode node,
+ using PassKey = util::PassKey<NGInlineBreakToken>;
+ NGInlineBreakToken(PassKey,
+ NGInlineNode node,
const ComputedStyle*,
unsigned item_index,
unsigned text_offset,
unsigned flags /* NGInlineBreakTokenFlags */);
- explicit NGInlineBreakToken(NGLayoutInputNode node);
+ explicit NGInlineBreakToken(PassKey, NGLayoutInputNode node);
+#if DCHECK_IS_ON()
+ String ToString() const override;
+#endif
+
+ private:
scoped_refptr<const ComputedStyle> style_;
unsigned item_index_;
unsigned text_offset_;
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 df7664e661e..bb39e1b44f1 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
@@ -18,8 +18,8 @@ namespace blink {
void NGInlineCursor::MoveToItem(const ItemsSpan::iterator& iter) {
DCHECK(IsItemCursor());
DCHECK(iter >= items_.begin() && iter <= items_.end());
- item_iter_ = iter;
- current_item_ = iter == items_.end() ? nullptr : iter->get();
+ current_.item_iter_ = iter;
+ current_.item_ = iter == items_.end() ? nullptr : iter->get();
}
void NGInlineCursor::SetRoot(const NGFragmentItems& fragment_items,
@@ -28,6 +28,8 @@ void NGInlineCursor::SetRoot(const NGFragmentItems& fragment_items,
DCHECK(!HasRoot());
fragment_items_ = &fragment_items;
items_ = items;
+ DCHECK(items_.empty() || (items_.data() >= fragment_items_->Items().data() &&
+ items_.data() < fragment_items_->Items().end()));
MoveToItem(items_.begin());
}
@@ -39,7 +41,7 @@ void NGInlineCursor::SetRoot(const NGPaintFragment& root_paint_fragment) {
DCHECK(&root_paint_fragment);
DCHECK(!HasRoot());
root_paint_fragment_ = &root_paint_fragment;
- current_paint_fragment_ = root_paint_fragment.FirstChild();
+ current_.paint_fragment_ = root_paint_fragment.FirstChild();
}
void NGInlineCursor::SetRoot(const LayoutBlockFlow& block_flow) {
@@ -80,28 +82,22 @@ NGInlineCursor::NGInlineCursor(const NGPaintFragment& root_paint_fragment) {
SetRoot(root_paint_fragment);
}
-NGInlineCursor::NGInlineCursor(const NGInlineCursor& other)
- : items_(other.items_),
- item_iter_(other.item_iter_),
- current_item_(other.current_item_),
- fragment_items_(other.fragment_items_),
- root_paint_fragment_(other.root_paint_fragment_),
- current_paint_fragment_(other.current_paint_fragment_),
- layout_inline_(other.layout_inline_) {}
-
-NGInlineCursor::NGInlineCursor() = default;
+NGInlineCursor::NGInlineCursor(const NGInlineBackwardCursor& backward_cursor)
+ : NGInlineCursor(backward_cursor.cursor_) {
+ MoveTo(backward_cursor.Current());
+}
bool NGInlineCursor::operator==(const NGInlineCursor& other) const {
if (root_paint_fragment_) {
return root_paint_fragment_ == other.root_paint_fragment_ &&
- current_paint_fragment_ == other.current_paint_fragment_;
+ current_.paint_fragment_ == other.current_.paint_fragment_;
}
- if (current_item_ != other.current_item_)
+ if (current_.item_ != other.current_.item_)
return false;
DCHECK_EQ(items_.data(), other.items_.data());
DCHECK_EQ(items_.size(), other.items_.size());
DCHECK_EQ(fragment_items_, other.fragment_items_);
- DCHECK(item_iter_ == other.item_iter_);
+ DCHECK(current_.item_iter_ == other.current_.item_iter_);
return true;
}
@@ -122,34 +118,35 @@ const LayoutBlockFlow* NGInlineCursor::GetLayoutBlockFlow() const {
return layout_object->RootInlineFormattingContext();
}
if (IsItemCursor()) {
- for (const auto& item : items_) {
- const LayoutObject* layout_object = item->GetLayoutObject();
- if (layout_object && layout_object->IsInline())
- return layout_object->RootInlineFormattingContext();
- }
+ const NGFragmentItem& item = *fragment_items_->Items().front();
+ const LayoutObject* layout_object = item.GetLayoutObject();
+ if (item.Type() == NGFragmentItem::kLine)
+ return To<LayoutBlockFlow>(layout_object);
+ return layout_object->RootInlineFormattingContext();
}
NOTREACHED();
return nullptr;
}
bool NGInlineCursor::HasChildren() const {
- if (current_paint_fragment_)
- return current_paint_fragment_->FirstChild();
- if (current_item_)
- return current_item_->HasChildren();
+ if (current_.paint_fragment_)
+ return current_.paint_fragment_->FirstChild();
+ if (current_.item_)
+ return current_.item_->HasChildren();
NOTREACHED();
return false;
}
NGInlineCursor NGInlineCursor::CursorForDescendants() const {
- if (current_paint_fragment_)
- return NGInlineCursor(*current_paint_fragment_);
- if (current_item_) {
- unsigned descendants_count = current_item_->DescendantsCount();
+ if (current_.paint_fragment_)
+ return NGInlineCursor(*current_.paint_fragment_);
+ if (current_.item_) {
+ unsigned descendants_count = current_.item_->DescendantsCount();
if (descendants_count > 1) {
DCHECK(fragment_items_);
- return NGInlineCursor(*fragment_items_, ItemsSpan(&*(item_iter_ + 1),
- descendants_count - 1));
+ return NGInlineCursor(
+ *fragment_items_,
+ ItemsSpan(&*(current_.item_iter_ + 1), descendants_count - 1));
}
return NGInlineCursor();
}
@@ -157,96 +154,119 @@ NGInlineCursor NGInlineCursor::CursorForDescendants() const {
return NGInlineCursor();
}
+void NGInlineCursor::ExpandRootToContainingBlock() {
+ if (root_paint_fragment_) {
+ root_paint_fragment_ = root_paint_fragment_->Root();
+ return;
+ }
+ if (fragment_items_) {
+ const unsigned index_diff = items_.data() - fragment_items_->Items().data();
+ DCHECK_LT(index_diff, fragment_items_->Items().size());
+ const unsigned item_index = current_.item_iter_ - items_.begin();
+ items_ = fragment_items_->Items();
+ // Update the iterator to the one for the new span.
+ MoveToItem(items_.begin() + item_index + index_diff);
+ return;
+ }
+ NOTREACHED();
+}
+
bool NGInlineCursor::HasSoftWrapToNextLine() const {
- DCHECK(IsLineBox());
- const NGInlineBreakToken& break_token = CurrentInlineBreakToken();
- return !break_token.IsFinished() && !break_token.IsForcedBreak();
+ DCHECK(Current().IsLineBox());
+ const NGInlineBreakToken* break_token = Current().InlineBreakToken();
+ DCHECK(break_token);
+ return !break_token->IsFinished() && !break_token->IsForcedBreak();
}
-bool NGInlineCursor::IsAtomicInline() const {
- if (current_paint_fragment_)
- return current_paint_fragment_->PhysicalFragment().IsAtomicInline();
- if (current_item_)
- return current_item_->IsAtomicInline();
+bool NGInlineCursorPosition::IsInlineBox() const {
+ if (paint_fragment_)
+ return paint_fragment_->PhysicalFragment().IsInlineBox();
+ if (item_)
+ return item_->IsInlineBox();
NOTREACHED();
return false;
}
-bool NGInlineCursor::IsEllipsis() const {
- if (current_paint_fragment_)
- return current_paint_fragment_->IsEllipsis();
- if (current_item_)
- return current_item_->IsEllipsis();
+bool NGInlineCursorPosition::IsAtomicInline() const {
+ if (paint_fragment_)
+ return paint_fragment_->PhysicalFragment().IsAtomicInline();
+ if (item_)
+ return item_->IsAtomicInline();
NOTREACHED();
return false;
}
-bool NGInlineCursor::IsGeneratedText() const {
- if (current_paint_fragment_) {
+bool NGInlineCursorPosition::IsEllipsis() const {
+ if (paint_fragment_)
+ return paint_fragment_->IsEllipsis();
+ if (item_)
+ return item_->IsEllipsis();
+ NOTREACHED();
+ return false;
+}
+
+bool NGInlineCursorPosition::IsGeneratedText() const {
+ if (paint_fragment_) {
if (auto* text_fragment = DynamicTo<NGPhysicalTextFragment>(
- current_paint_fragment_->PhysicalFragment()))
+ paint_fragment_->PhysicalFragment()))
return text_fragment->IsGeneratedText();
return false;
}
- if (current_item_)
- return current_item_->IsGeneratedText();
+ if (item_)
+ return item_->IsGeneratedText();
NOTREACHED();
return false;
}
-bool NGInlineCursor::IsGeneratedTextType() const {
- if (current_paint_fragment_) {
+bool NGInlineCursorPosition::IsGeneratedTextType() const {
+ if (paint_fragment_) {
if (auto* text_fragment = DynamicTo<NGPhysicalTextFragment>(
- current_paint_fragment_->PhysicalFragment())) {
+ paint_fragment_->PhysicalFragment())) {
return text_fragment->TextType() ==
NGPhysicalTextFragment::kGeneratedText;
}
return false;
}
- if (current_item_)
- return current_item_->Type() == NGFragmentItem::kGeneratedText;
+ if (item_)
+ return item_->Type() == NGFragmentItem::kGeneratedText;
NOTREACHED();
return false;
}
-bool NGInlineCursor::IsHiddenForPaint() const {
- if (current_paint_fragment_)
- return current_paint_fragment_->PhysicalFragment().IsHiddenForPaint();
- if (current_item_)
- return current_item_->IsHiddenForPaint();
+bool NGInlineCursorPosition::IsHiddenForPaint() const {
+ if (paint_fragment_)
+ return paint_fragment_->PhysicalFragment().IsHiddenForPaint();
+ if (item_)
+ return item_->IsHiddenForPaint();
NOTREACHED();
return false;
}
-bool NGInlineCursor::IsHorizontal() const {
- return CurrentStyle().GetWritingMode() == WritingMode::kHorizontalTb;
-}
-
bool NGInlineCursor::IsInlineLeaf() const {
- if (IsHiddenForPaint())
+ if (Current().IsHiddenForPaint())
return false;
- if (IsText())
- return !IsGeneratedTextType();
- if (!IsAtomicInline())
+ if (Current().IsText())
+ return !Current().IsGeneratedTextType();
+ if (!Current().IsAtomicInline())
return false;
- return !IsListMarker();
+ return !Current().IsListMarker();
}
bool NGInlineCursor::IsPartOfCulledInlineBox(
const LayoutInline& layout_inline) const {
- const LayoutObject* const layout_object = CurrentLayoutObject();
+ const LayoutObject* const layout_object = Current().GetLayoutObject();
// We use |IsInline()| to exclude floating and out-of-flow objects.
if (!layout_object || !layout_object->IsInline() ||
layout_object->IsAtomicInlineLevel())
return false;
DCHECK(!layout_object->IsFloatingOrOutOfFlowPositioned());
- DCHECK(!CurrentBoxFragment() ||
- !CurrentBoxFragment()->IsBlockFormattingContextRoot());
+ DCHECK(!Current().BoxFragment() ||
+ !Current().BoxFragment()->IsFormattingContextRoot());
return layout_object->IsDescendantOf(&layout_inline);
}
bool NGInlineCursor::IsLastLineInInlineBlock() const {
- DCHECK(IsLineBox());
+ DCHECK(Current().IsLineBox());
if (!GetLayoutBlockFlow()->IsAtomicInlineLevel())
return false;
NGInlineCursor next_sibling(*this);
@@ -254,45 +274,45 @@ bool NGInlineCursor::IsLastLineInInlineBlock() const {
next_sibling.MoveToNextSibling();
if (!next_sibling)
return true;
- if (next_sibling.IsLineBox())
+ if (next_sibling.Current().IsLineBox())
return false;
// There maybe other top-level objects such as floats, OOF, or list-markers.
}
}
-bool NGInlineCursor::IsLineBreak() const {
- if (current_paint_fragment_) {
+bool NGInlineCursorPosition::IsLineBreak() const {
+ if (paint_fragment_) {
if (auto* text_fragment = DynamicTo<NGPhysicalTextFragment>(
- current_paint_fragment_->PhysicalFragment()))
+ paint_fragment_->PhysicalFragment()))
return text_fragment->IsLineBreak();
return false;
}
- if (current_item_)
- return IsText() && current_item_->IsLineBreak();
+ if (item_)
+ return IsText() && item_->IsLineBreak();
NOTREACHED();
return false;
}
-bool NGInlineCursor::IsListMarker() const {
- if (current_paint_fragment_)
- return current_paint_fragment_->PhysicalFragment().IsListMarker();
- if (current_item_)
- return current_item_->IsListMarker();
+bool NGInlineCursorPosition::IsListMarker() const {
+ if (paint_fragment_)
+ return paint_fragment_->PhysicalFragment().IsListMarker();
+ if (item_)
+ return item_->IsListMarker();
NOTREACHED();
return false;
}
-bool NGInlineCursor::IsText() const {
- if (current_paint_fragment_)
- return current_paint_fragment_->PhysicalFragment().IsText();
- if (current_item_)
- return current_item_->IsText();
+bool NGInlineCursorPosition::IsText() const {
+ if (paint_fragment_)
+ return paint_fragment_->PhysicalFragment().IsText();
+ if (item_)
+ return item_->IsText();
NOTREACHED();
return false;
}
bool NGInlineCursor::IsBeforeSoftLineBreak() const {
- if (IsLineBreak())
+ if (Current().IsLineBreak())
return false;
// Inline block is not be container line box.
// See paint/selection/text-selection-inline-block.html.
@@ -315,57 +335,55 @@ bool NGInlineCursor::IsBeforeSoftLineBreak() const {
// Even If |fragment| is before linebreak, if its direction differs to line
// direction, we don't paint line break. See
// paint/selection/text-selection-newline-mixed-ltr-rtl.html.
- return line.CurrentBaseDirection() == CurrentResolvedDirection();
+ return line.Current().BaseDirection() == Current().ResolvedDirection();
}
bool NGInlineCursor::CanHaveChildren() const {
- if (current_paint_fragment_)
- return current_paint_fragment_->PhysicalFragment().IsContainer();
- if (current_item_) {
- return current_item_->Type() == NGFragmentItem::kLine ||
- (current_item_->Type() == NGFragmentItem::kBox &&
- !current_item_->IsAtomicInline());
+ if (current_.paint_fragment_)
+ return current_.paint_fragment_->PhysicalFragment().IsContainer();
+ if (current_.item_) {
+ return current_.item_->Type() == NGFragmentItem::kLine ||
+ (current_.item_->Type() == NGFragmentItem::kBox &&
+ !current_.item_->IsAtomicInline());
}
NOTREACHED();
return false;
}
-bool NGInlineCursor::IsEmptyLineBox() const {
+bool NGInlineCursorPosition::IsEmptyLineBox() const {
DCHECK(IsLineBox());
- if (current_paint_fragment_) {
- return To<NGPhysicalLineBoxFragment>(
- current_paint_fragment_->PhysicalFragment())
+ if (paint_fragment_) {
+ return To<NGPhysicalLineBoxFragment>(paint_fragment_->PhysicalFragment())
.IsEmptyLineBox();
}
- if (current_item_)
- return current_item_->IsEmptyLineBox();
+ if (item_)
+ return item_->IsEmptyLineBox();
NOTREACHED();
return false;
}
-bool NGInlineCursor::IsLineBox() const {
- if (current_paint_fragment_)
- return current_paint_fragment_->PhysicalFragment().IsLineBox();
- if (current_item_)
- return current_item_->Type() == NGFragmentItem::kLine;
+bool NGInlineCursorPosition::IsLineBox() const {
+ if (paint_fragment_)
+ return paint_fragment_->PhysicalFragment().IsLineBox();
+ if (item_)
+ return item_->Type() == NGFragmentItem::kLine;
NOTREACHED();
return false;
}
-TextDirection NGInlineCursor::CurrentBaseDirection() const {
+TextDirection NGInlineCursorPosition::BaseDirection() const {
DCHECK(IsLineBox());
- if (current_paint_fragment_) {
- return To<NGPhysicalLineBoxFragment>(
- current_paint_fragment_->PhysicalFragment())
+ if (paint_fragment_) {
+ return To<NGPhysicalLineBoxFragment>(paint_fragment_->PhysicalFragment())
.BaseDirection();
}
- if (current_item_)
- return current_item_->BaseDirection();
+ if (item_)
+ return item_->BaseDirection();
NOTREACHED();
return TextDirection::kLtr;
}
-UBiDiLevel NGInlineCursor::CurrentBidiLevel() const {
+UBiDiLevel NGInlineCursorPosition::BidiLevel() const {
if (IsText()) {
if (IsGeneratedTextType()) {
// TODO(yosin): Until we have clients, we don't support bidi-level for
@@ -373,17 +391,18 @@ UBiDiLevel NGInlineCursor::CurrentBidiLevel() const {
NOTREACHED() << this;
return 0;
}
- const LayoutText& layout_text = *ToLayoutText(CurrentLayoutObject());
+ const LayoutText& layout_text = *ToLayoutText(GetLayoutObject());
DCHECK(!layout_text.NeedsLayout()) << this;
const auto* const items = layout_text.GetNGInlineItems();
if (!items || items->size() == 0) {
// In case of <br>, <wbr>, text-combine-upright, etc.
return 0;
}
+ const NGTextOffset offset = TextOffset();
const auto& item = std::find_if(
- items->begin(), items->end(), [this](const NGInlineItem& item) {
- return item.StartOffset() <= CurrentTextStartOffset() &&
- item.EndOffset() >= CurrentTextEndOffset();
+ items->begin(), items->end(), [offset](const NGInlineItem& item) {
+ return item.StartOffset() <= offset.start &&
+ item.EndOffset() >= offset.end;
});
DCHECK(item != items->end()) << this;
return item->BidiLevel();
@@ -391,13 +410,13 @@ UBiDiLevel NGInlineCursor::CurrentBidiLevel() const {
if (IsAtomicInline()) {
const NGPhysicalBoxFragment* fragmentainer =
- CurrentLayoutObject()->ContainingBlockFlowFragment();
+ GetLayoutObject()->ContainingBlockFlowFragment();
DCHECK(fragmentainer);
const LayoutBlockFlow& block_flow =
*To<LayoutBlockFlow>(fragmentainer->GetLayoutObject());
const Vector<NGInlineItem> items =
block_flow.GetNGInlineNodeData()->ItemsData(UsesFirstLineStyle()).items;
- const LayoutObject* const layout_object = CurrentLayoutObject();
+ const LayoutObject* const layout_object = GetLayoutObject();
const auto* const item = std::find_if(
items.begin(), items.end(), [layout_object](const NGInlineItem& item) {
return item.GetLayoutObject() == layout_object;
@@ -410,237 +429,469 @@ UBiDiLevel NGInlineCursor::CurrentBidiLevel() const {
return 0;
}
-const NGPhysicalBoxFragment* NGInlineCursor::CurrentBoxFragment() const {
- if (current_paint_fragment_) {
+const NGPhysicalBoxFragment* NGInlineCursorPosition::BoxFragment() const {
+ if (paint_fragment_) {
return DynamicTo<NGPhysicalBoxFragment>(
- &current_paint_fragment_->PhysicalFragment());
+ &paint_fragment_->PhysicalFragment());
}
- if (current_item_)
- return current_item_->BoxFragment();
+ if (item_)
+ return item_->BoxFragment();
NOTREACHED();
return nullptr;
}
-const DisplayItemClient* NGInlineCursor::CurrentDisplayItemClient() const {
- if (current_paint_fragment_)
- return current_paint_fragment_;
- if (current_item_)
- return current_item_;
+const DisplayItemClient* NGInlineCursorPosition::GetDisplayItemClient() const {
+ if (paint_fragment_)
+ return paint_fragment_;
+ if (item_)
+ return item_;
NOTREACHED();
return nullptr;
}
-const NGInlineBreakToken& NGInlineCursor::CurrentInlineBreakToken() const {
+const NGInlineBreakToken* NGInlineCursorPosition::InlineBreakToken() const {
DCHECK(IsLineBox());
- if (current_paint_fragment_) {
+ if (paint_fragment_) {
return To<NGInlineBreakToken>(
- *To<NGPhysicalLineBoxFragment>(
- current_paint_fragment_->PhysicalFragment())
- .BreakToken());
+ To<NGPhysicalLineBoxFragment>(paint_fragment_->PhysicalFragment())
+ .BreakToken());
}
- DCHECK(current_item_);
- return *current_item_->InlineBreakToken();
+ DCHECK(item_);
+ return item_->InlineBreakToken();
}
-const LayoutObject* NGInlineCursor::CurrentLayoutObject() const {
- if (current_paint_fragment_)
- return current_paint_fragment_->GetLayoutObject();
- if (current_item_)
- return current_item_->GetLayoutObject();
+const LayoutObject* NGInlineCursorPosition::GetLayoutObject() const {
+ if (paint_fragment_)
+ return paint_fragment_->GetLayoutObject();
+ if (item_)
+ return item_->GetLayoutObject();
NOTREACHED();
return nullptr;
}
-LayoutObject* NGInlineCursor::CurrentMutableLayoutObject() const {
- if (current_paint_fragment_)
- return current_paint_fragment_->GetMutableLayoutObject();
- if (current_item_)
- return current_item_->GetMutableLayoutObject();
+LayoutObject* NGInlineCursorPosition::GetMutableLayoutObject() const {
+ if (paint_fragment_)
+ return paint_fragment_->GetMutableLayoutObject();
+ if (item_)
+ return item_->GetMutableLayoutObject();
NOTREACHED();
return nullptr;
}
-Node* NGInlineCursor::CurrentNode() const {
- if (const LayoutObject* layout_object = CurrentLayoutObject())
+const Node* NGInlineCursorPosition::GetNode() const {
+ if (const LayoutObject* layout_object = GetLayoutObject())
return layout_object->GetNode();
return nullptr;
}
-const PhysicalRect NGInlineCursor::CurrentInkOverflow() const {
- if (current_paint_fragment_)
- return current_paint_fragment_->InkOverflow();
- if (current_item_)
- return current_item_->InkOverflow();
+const PhysicalRect NGInlineCursorPosition::InkOverflow() const {
+ if (paint_fragment_)
+ return paint_fragment_->InkOverflow();
+ if (item_)
+ return item_->InkOverflow();
NOTREACHED();
return PhysicalRect();
}
-const PhysicalOffset NGInlineCursor::CurrentOffset() const {
- if (current_paint_fragment_)
- return current_paint_fragment_->InlineOffsetToContainerBox();
- if (current_item_)
- return current_item_->Offset();
+const PhysicalOffset NGInlineCursorPosition::OffsetInContainerBlock() const {
+ if (paint_fragment_)
+ return paint_fragment_->OffsetInContainerBlock();
+ if (item_)
+ return item_->OffsetInContainerBlock();
NOTREACHED();
return PhysicalOffset();
}
-const PhysicalRect NGInlineCursor::CurrentRect() const {
- return PhysicalRect(CurrentOffset(), CurrentSize());
+const PhysicalSize NGInlineCursorPosition::Size() const {
+ if (paint_fragment_)
+ return paint_fragment_->Size();
+ if (item_)
+ return item_->Size();
+ NOTREACHED();
+ return PhysicalSize();
}
-TextDirection NGInlineCursor::CurrentResolvedDirection() const {
- if (current_paint_fragment_)
- return current_paint_fragment_->PhysicalFragment().ResolvedDirection();
- if (current_item_)
- return current_item_->ResolvedDirection();
+const PhysicalRect NGInlineCursorPosition::RectInContainerBlock() const {
+ if (paint_fragment_) {
+ return {paint_fragment_->OffsetInContainerBlock(), paint_fragment_->Size()};
+ }
+ if (item_)
+ return item_->RectInContainerBlock();
NOTREACHED();
- return TextDirection::kLtr;
+ return PhysicalRect();
}
-const PhysicalSize NGInlineCursor::CurrentSize() const {
- if (current_paint_fragment_)
- return current_paint_fragment_->Size();
- if (current_item_)
- return current_item_->Size();
+const PhysicalRect NGInlineCursorPosition::SelfInkOverflow() const {
+ if (paint_fragment_)
+ return paint_fragment_->SelfInkOverflow();
+ if (item_)
+ return item_->SelfInkOverflow();
NOTREACHED();
- return PhysicalSize();
+ return PhysicalRect();
+}
+
+TextDirection NGInlineCursorPosition::ResolvedDirection() const {
+ if (paint_fragment_)
+ return paint_fragment_->PhysicalFragment().ResolvedDirection();
+ if (item_)
+ return item_->ResolvedDirection();
+ NOTREACHED();
+ return TextDirection::kLtr;
}
-const ComputedStyle& NGInlineCursor::CurrentStyle() const {
- if (current_paint_fragment_)
- return current_paint_fragment_->Style();
- return current_item_->Style();
+const ComputedStyle& NGInlineCursorPosition::Style() const {
+ if (paint_fragment_)
+ return paint_fragment_->Style();
+ return item_->Style();
}
-NGStyleVariant NGInlineCursor::CurrentStyleVariant() const {
- if (current_paint_fragment_)
- return current_paint_fragment_->PhysicalFragment().StyleVariant();
- return current_item_->StyleVariant();
+NGStyleVariant NGInlineCursorPosition::StyleVariant() const {
+ if (paint_fragment_)
+ return paint_fragment_->PhysicalFragment().StyleVariant();
+ return item_->StyleVariant();
}
-bool NGInlineCursor::UsesFirstLineStyle() const {
- return CurrentStyleVariant() == NGStyleVariant::kFirstLine;
+bool NGInlineCursorPosition::UsesFirstLineStyle() const {
+ return StyleVariant() == NGStyleVariant::kFirstLine;
}
-NGTextOffset NGInlineCursor::CurrentTextOffset() const {
- if (current_paint_fragment_) {
+NGTextOffset NGInlineCursorPosition::TextOffset() const {
+ if (paint_fragment_) {
const auto& text_fragment =
- To<NGPhysicalTextFragment>(current_paint_fragment_->PhysicalFragment());
- return {text_fragment.StartOffset(), text_fragment.EndOffset()};
+ To<NGPhysicalTextFragment>(paint_fragment_->PhysicalFragment());
+ return text_fragment.TextOffset();
}
- if (current_item_)
- return {current_item_->StartOffset(), current_item_->EndOffset()};
+ if (item_)
+ return item_->TextOffset();
NOTREACHED();
return {};
}
-StringView NGInlineCursor::CurrentText() const {
+StringView NGInlineCursorPosition::Text(const NGInlineCursor& cursor) const {
DCHECK(IsText());
- if (current_paint_fragment_) {
- return To<NGPhysicalTextFragment>(
- current_paint_fragment_->PhysicalFragment())
+ cursor.CheckValid(*this);
+ if (paint_fragment_) {
+ return To<NGPhysicalTextFragment>(paint_fragment_->PhysicalFragment())
.Text();
}
- if (current_item_)
- return current_item_->Text(*fragment_items_);
+ if (item_)
+ return item_->Text(cursor.Items());
NOTREACHED();
return "";
}
-const ShapeResultView* NGInlineCursor::CurrentTextShapeResult() const {
+const ShapeResultView* NGInlineCursorPosition::TextShapeResult() const {
DCHECK(IsText());
- if (current_paint_fragment_) {
- return To<NGPhysicalTextFragment>(
- current_paint_fragment_->PhysicalFragment())
+ if (paint_fragment_) {
+ return To<NGPhysicalTextFragment>(paint_fragment_->PhysicalFragment())
.TextShapeResult();
}
- if (current_item_)
- return current_item_->TextShapeResult();
+ if (item_)
+ return item_->TextShapeResult();
NOTREACHED();
return nullptr;
}
PhysicalRect NGInlineCursor::CurrentLocalRect(unsigned start_offset,
unsigned end_offset) const {
- DCHECK(IsText());
- if (current_paint_fragment_) {
+ DCHECK(Current().IsText());
+ if (current_.paint_fragment_) {
return To<NGPhysicalTextFragment>(
- current_paint_fragment_->PhysicalFragment())
+ current_.paint_fragment_->PhysicalFragment())
.LocalRect(start_offset, end_offset);
}
- if (current_item_) {
- return current_item_->LocalRect(current_item_->Text(*fragment_items_),
- start_offset, end_offset);
+ if (current_.item_) {
+ return current_.item_->LocalRect(current_.item_->Text(*fragment_items_),
+ start_offset, end_offset);
}
NOTREACHED();
return PhysicalRect();
}
LayoutUnit NGInlineCursor::InlinePositionForOffset(unsigned offset) const {
- DCHECK(IsText());
- if (current_paint_fragment_) {
+ DCHECK(Current().IsText());
+ if (current_.paint_fragment_) {
return To<NGPhysicalTextFragment>(
- current_paint_fragment_->PhysicalFragment())
+ current_.paint_fragment_->PhysicalFragment())
.InlinePositionForOffset(offset);
}
- if (current_item_) {
- return current_item_->InlinePositionForOffset(
- current_item_->Text(*fragment_items_), offset);
+ if (current_.item_) {
+ return current_.item_->InlinePositionForOffset(
+ current_.item_->Text(*fragment_items_), offset);
}
NOTREACHED();
return LayoutUnit();
}
PhysicalOffset NGInlineCursor::LineStartPoint() const {
- DCHECK(IsLineBox()) << this;
+ DCHECK(Current().IsLineBox()) << this;
const LogicalOffset logical_start; // (0, 0)
const PhysicalSize pixel_size(LayoutUnit(1), LayoutUnit(1));
- return logical_start.ConvertToPhysical(CurrentStyle().GetWritingMode(),
- CurrentBaseDirection(), CurrentSize(),
- pixel_size);
+ return logical_start.ConvertToPhysical(Current().Style().GetWritingMode(),
+ Current().BaseDirection(),
+ Current().Size(), pixel_size);
}
PhysicalOffset NGInlineCursor::LineEndPoint() const {
- DCHECK(IsLineBox()) << this;
- const LayoutUnit inline_size =
- IsHorizontal() ? CurrentSize().width : CurrentSize().height;
+ DCHECK(Current().IsLineBox()) << this;
+ const WritingMode writing_mode = Current().Style().GetWritingMode();
+ const LayoutUnit inline_size = IsHorizontalWritingMode(writing_mode)
+ ? Current().Size().width
+ : Current().Size().height;
const LogicalOffset logical_end(inline_size, LayoutUnit());
const PhysicalSize pixel_size(LayoutUnit(1), LayoutUnit(1));
- return logical_end.ConvertToPhysical(CurrentStyle().GetWritingMode(),
- CurrentBaseDirection(), CurrentSize(),
- pixel_size);
+ return logical_end.ConvertToPhysical(writing_mode, Current().BaseDirection(),
+ Current().Size(), pixel_size);
}
-PositionWithAffinity NGInlineCursor::PositionForPoint(
- const PhysicalOffset& point) {
- if (root_paint_fragment_)
- return root_paint_fragment_->PositionForPoint(point);
+PositionWithAffinity NGInlineCursor::PositionForPointInInlineFormattingContext(
+ const PhysicalOffset& point,
+ const NGPhysicalBoxFragment& container) {
DCHECK(IsItemCursor());
+ const ComputedStyle& container_style = container.Style();
+ const WritingMode writing_mode = container_style.GetWritingMode();
+ const TextDirection direction = container_style.Direction();
+ const PhysicalSize& container_size = container.Size();
+ const LayoutUnit point_block_offset =
+ point
+ .ConvertToLogical(writing_mode, direction, container_size,
+ // |point| is actually a pixel with size 1x1.
+ PhysicalSize(LayoutUnit(1), LayoutUnit(1)))
+ .block_offset;
+
+ // 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.
+ NGInlineCursorPosition closest_line_before;
+ LayoutUnit closest_line_before_block_offset = LayoutUnit::Min();
+
+ // 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.
+ NGInlineCursorPosition closest_line_after;
+ LayoutUnit closest_line_after_block_offset = LayoutUnit::Max();
+
while (*this) {
- const NGFragmentItem* item = CurrentItem();
- DCHECK(item);
- // TODO(kojii): Do more staff, when the point is not on any item but within
- // line box, etc., see |NGPaintFragment::PositionForPoint|.
- if (!item->Rect().Contains(point)) {
+ const NGFragmentItem* child_item = CurrentItem();
+ DCHECK(child_item);
+ if (child_item->Type() == NGFragmentItem::kLine) {
+ // Try to resolve if |point| falls in a line box in block direction.
+ const LayoutUnit child_block_offset =
+ child_item->OffsetInContainerBlock()
+ .ConvertToLogical(writing_mode, direction, container_size,
+ 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();
+ }
+ MoveToNextItemSkippingChildren();
+ continue;
+ }
+
+ // Hitting on line bottom doesn't count, to match legacy behavior.
+ const LayoutUnit child_block_end_offset =
+ 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();
+ }
+ MoveToNextItemSkippingChildren();
+ continue;
+ }
+
+ if (const PositionWithAffinity child_position =
+ PositionForPointInInlineBox(point))
+ return child_position;
MoveToNextItemSkippingChildren();
continue;
}
- if (item->Type() == NGFragmentItem::kText)
- return item->PositionForPointInText(point, *this);
- MoveToNext();
+ DCHECK_NE(child_item->Type(), NGFragmentItem::kText);
+ MoveToNextItem();
+ }
+
+ if (closest_line_after) {
+ MoveTo(closest_line_after);
+ 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))
+ return child_position;
+ }
+
+ return PositionWithAffinity();
+}
+
+PositionWithAffinity NGInlineCursor::PositionForPointInInlineBox(
+ const PhysicalOffset& point) const {
+ if (const NGPaintFragment* paint_fragment = CurrentPaintFragment()) {
+ DCHECK(paint_fragment->PhysicalFragment().IsLineBox());
+ return paint_fragment->PositionForPoint(point);
+ }
+ const NGFragmentItem* container = CurrentItem();
+ DCHECK(container);
+ DCHECK(container->Type() == NGFragmentItem::kLine ||
+ container->Type() == NGFragmentItem::kBox);
+ const ComputedStyle& container_style = container->Style();
+ const WritingMode writing_mode = container_style.GetWritingMode();
+ const TextDirection direction = container_style.Direction();
+ const PhysicalSize& container_size = container->Size();
+ const LayoutUnit point_inline_offset =
+ point
+ .ConvertToLogical(writing_mode, direction, container_size,
+ // |point| is actually a pixel with size 1x1.
+ PhysicalSize(LayoutUnit(1), LayoutUnit(1)))
+ .inline_offset;
+
+ // Stores the closest child before |point| in the inline direction. Used if we
+ // can't find any child |point| falls in to resolve the position.
+ NGInlineCursorPosition closest_child_before;
+ LayoutUnit closest_child_before_inline_offset = LayoutUnit::Min();
+
+ // Stores the closest child after |point| in the inline direction. Used if we
+ // can't find any child |point| falls in to resolve the position.
+ NGInlineCursorPosition closest_child_after;
+ LayoutUnit closest_child_after_inline_offset = LayoutUnit::Max();
+
+ NGInlineCursor descendants = CursorForDescendants();
+ for (; descendants; descendants.MoveToNext()) {
+ const NGFragmentItem* child_item = descendants.CurrentItem();
+ DCHECK(child_item);
+ if (child_item->Type() == NGFragmentItem::kBox &&
+ !child_item->BoxFragment()) {
+ // Skip virtually "culled" inline box, e.g. <span>foo</span>
+ // "editing/selection/shift-click.html" reaches here.
+ DCHECK(child_item->GetLayoutObject()->IsLayoutInline()) << child_item;
+ continue;
+ }
+ const LayoutUnit child_inline_offset =
+ child_item->OffsetInContainerBlock()
+ .ConvertToLogical(writing_mode, direction, container_size,
+ child_item->Size())
+ .inline_offset;
+ if (point_inline_offset < child_inline_offset) {
+ if (child_inline_offset < closest_child_after_inline_offset) {
+ closest_child_after_inline_offset = child_inline_offset;
+ closest_child_after = descendants.Current();
+ }
+ continue;
+ }
+ const LayoutUnit child_inline_end_offset =
+ child_inline_offset +
+ child_item->Size().ConvertToLogical(writing_mode).inline_size;
+ if (point_inline_offset > child_inline_end_offset) {
+ if (child_inline_end_offset > closest_child_before_inline_offset) {
+ closest_child_before_inline_offset = child_inline_end_offset;
+ closest_child_before = descendants.Current();
+ }
+ continue;
+ }
+
+ if (const PositionWithAffinity child_position =
+ descendants.PositionForPointInChild(point, *child_item))
+ return child_position;
+ }
+
+ if (closest_child_after) {
+ descendants.MoveTo(closest_child_after);
+ if (const PositionWithAffinity child_position =
+ descendants.PositionForPointInChild(point, *closest_child_after))
+ return child_position;
+ // TODO(yosin): we should do like "closest_child_before" once we have a
+ // case.
+ }
+
+ if (closest_child_before) {
+ descendants.MoveTo(closest_child_before);
+ if (const PositionWithAffinity child_position =
+ descendants.PositionForPointInChild(point, *closest_child_before))
+ return child_position;
+ if (closest_child_before->BoxFragment()) {
+ // LayoutViewHitTest.HitTestHorizontal "Top-right corner (outside) of div"
+ // reach here.
+ return descendants.PositionForPointInInlineBox(point);
+ }
+ }
+
+ return PositionWithAffinity();
+}
+
+PositionWithAffinity NGInlineCursor::PositionForPointInChild(
+ const PhysicalOffset& point,
+ const NGFragmentItem& child_item) const {
+ DCHECK_EQ(&child_item, CurrentItem());
+ switch (child_item.Type()) {
+ case NGFragmentItem::kText:
+ return child_item.PositionForPointInText(
+ point - child_item.OffsetInContainerBlock(), *this);
+ case NGFragmentItem::kGeneratedText:
+ break;
+ case NGFragmentItem::kBox:
+ if (const NGPhysicalBoxFragment* box_fragment =
+ child_item.BoxFragment()) {
+ // We must fallback to legacy for old layout roots. We also fallback (to
+ // LayoutNGMixin::PositionForPoint()) for NG block layout, so that we
+ // 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()) {
+ return child_item.GetLayoutObject()->PositionForPoint(
+ point - child_item.OffsetInContainerBlock());
+ }
+ } else {
+ // |LayoutInline| used to be culled.
+ }
+ DCHECK(child_item.GetLayoutObject()->IsLayoutInline()) << child_item;
+ break;
+ case NGFragmentItem::kLine:
+ NOTREACHED();
+ break;
}
return PositionWithAffinity();
}
void NGInlineCursor::MakeNull() {
if (root_paint_fragment_) {
- current_paint_fragment_ = nullptr;
+ current_.paint_fragment_ = nullptr;
return;
}
if (fragment_items_)
return MoveToItem(items_.end());
}
+void NGInlineCursor::MoveTo(const NGInlineCursorPosition& position) {
+ CheckValid(position);
+ current_ = position;
+}
+
+inline unsigned NGInlineCursor::SpanIndexFromItemIndex(unsigned index) const {
+ DCHECK(IsItemCursor());
+ DCHECK_GE(items_.data(), fragment_items_->Items().data());
+ DCHECK_LT(items_.data(), fragment_items_->Items().end());
+ if (items_.data() == fragment_items_->Items().data())
+ return index;
+ unsigned span_index = fragment_items_->Items().data() - items_.data() + index;
+ DCHECK_LT(span_index, items_.size());
+ return span_index;
+}
+
+NGInlineCursor::ItemsSpan::iterator NGInlineCursor::SlowFirstItemIteratorFor(
+ const LayoutObject& layout_object) const {
+ DCHECK(IsItemCursor());
+ for (ItemsSpan::iterator iter = items_.begin(); iter != items_.end();
+ ++iter) {
+ if ((*iter)->GetLayoutObject() == &layout_object)
+ return iter;
+ }
+ return items_.end();
+}
+
void NGInlineCursor::InternalMoveTo(const LayoutObject& layout_object) {
DCHECK(layout_object.IsInLayoutNGInlineFormattingContext());
// If this cursor is rootless, find the root of the inline formatting context.
@@ -662,30 +913,18 @@ void NGInlineCursor::InternalMoveTo(const LayoutObject& layout_object) {
}
}
if (fragment_items_) {
- const wtf_size_t index = layout_object.FirstInlineFragmentItemIndex();
- if (!index) {
+ const wtf_size_t item_index = layout_object.FirstInlineFragmentItemIndex();
+ if (!item_index) {
// TODO(yosin): Once we update all |LayoutObject::FirstInlineFragment()|
// clients, we should replace to |return MakeNull()|
- item_iter_ = items_.begin();
- while (current_item_ && CurrentLayoutObject() != &layout_object)
- MoveToNextItem();
+ MoveToItem(SlowFirstItemIteratorFor(layout_object));
return;
}
- DCHECK_LT(index, items_.size());
- if (!had_root)
- return MoveToItem(items_.begin() + index);
- // Map |index| in |NGFragmentItems| to index of |items_|.
- const LayoutBlockFlow& block_flow =
- *layout_object.RootInlineFormattingContext();
- const auto items =
- ItemsSpan(block_flow.CurrentFragment()->Items()->Items());
- // Note: We use address instead of iterator because we can't compare
- // iterators in different span. See |base::CheckedContiguousIterator<T>|.
- const ptrdiff_t adjusted_index =
- &*(items.begin() + index) - &*items_.begin();
- DCHECK_GE(adjusted_index, 0);
- DCHECK_LT(static_cast<size_t>(adjusted_index), items_.size());
- return MoveToItem(items_.begin() + adjusted_index);
+ const unsigned span_index = SpanIndexFromItemIndex(item_index);
+ DCHECK_EQ(span_index,
+ static_cast<unsigned>(SlowFirstItemIteratorFor(layout_object) -
+ items_.begin()));
+ return MoveToItem(items_.begin() + span_index);
}
if (root_paint_fragment_) {
const auto fragments = NGPaintFragment::InlineFragmentsFor(&layout_object);
@@ -698,13 +937,16 @@ void NGInlineCursor::InternalMoveTo(const LayoutObject& layout_object) {
void NGInlineCursor::MoveTo(const LayoutObject& layout_object) {
DCHECK(layout_object.IsInLayoutNGInlineFormattingContext()) << layout_object;
InternalMoveTo(layout_object);
- if (*this || !HasRoot()) {
+ if (*this || !HasRoot() ||
+ RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
layout_inline_ = nullptr;
return;
}
// This |layout_object| did not produce any fragments.
- //
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
+
// Try to find ancestors if this is a culled inline.
layout_inline_ = ToLayoutInlineOrNull(&layout_object);
if (!layout_inline_)
@@ -715,17 +957,28 @@ void NGInlineCursor::MoveTo(const LayoutObject& layout_object) {
MoveToNext();
}
+void NGInlineCursor::MoveTo(const NGFragmentItem& fragment_item) {
+ DCHECK(!root_paint_fragment_ && !current_.paint_fragment_);
+ MoveTo(*fragment_item.GetLayoutObject());
+ while (IsNotNull()) {
+ if (CurrentItem() == &fragment_item)
+ return;
+ MoveToNext();
+ }
+ NOTREACHED();
+}
+
void NGInlineCursor::MoveTo(const NGInlineCursor& cursor) {
if (const NGPaintFragment* paint_fragment = cursor.CurrentPaintFragment()) {
MoveTo(*paint_fragment);
return;
}
- if (cursor.current_item_) {
+ if (cursor.current_.item_) {
if (!fragment_items_)
SetRoot(*cursor.fragment_items_);
// Note: We use address instead of iterato because we can't compare
// iterators in different span. See |base::CheckedContiguousIterator<T>|.
- const ptrdiff_t index = &*cursor.item_iter_ - &*items_.begin();
+ const ptrdiff_t index = &*cursor.current_.item_iter_ - &*items_.begin();
DCHECK_GE(index, 0);
DCHECK_LT(static_cast<size_t>(index), items_.size());
MoveToItem(items_.begin() + index);
@@ -741,19 +994,26 @@ void NGInlineCursor::MoveTo(const NGPaintFragment& paint_fragment) {
DCHECK(root_paint_fragment_);
DCHECK(paint_fragment.IsDescendantOfNotSelf(*root_paint_fragment_))
<< paint_fragment << " " << root_paint_fragment_;
- current_paint_fragment_ = &paint_fragment;
+ current_.paint_fragment_ = &paint_fragment;
+}
+
+void NGInlineCursor::MoveTo(const NGPaintFragment* paint_fragment) {
+ if (paint_fragment) {
+ MoveTo(*paint_fragment);
+ return;
+ }
+ MakeNull();
}
void NGInlineCursor::MoveToContainingLine() {
- DCHECK(!IsLineBox());
- if (current_paint_fragment_) {
- current_paint_fragment_ = current_paint_fragment_->ContainerLineBox();
+ DCHECK(!Current().IsLineBox());
+ if (current_.paint_fragment_) {
+ current_.paint_fragment_ = current_.paint_fragment_->ContainerLineBox();
return;
}
- if (current_item_) {
- do {
+ if (current_.item_) {
+ while (current_.item_ && !Current().IsLineBox())
MoveToPreviousItem();
- } while (current_item_ && !IsLineBox());
return;
}
NOTREACHED();
@@ -761,7 +1021,7 @@ void NGInlineCursor::MoveToContainingLine() {
void NGInlineCursor::MoveToFirst() {
if (root_paint_fragment_) {
- current_paint_fragment_ = root_paint_fragment_->FirstChild();
+ current_.paint_fragment_ = root_paint_fragment_->FirstChild();
return;
}
if (IsItemCursor()) {
@@ -777,13 +1037,32 @@ void NGInlineCursor::MoveToFirstChild() {
MakeNull();
}
+void NGInlineCursor::MoveToFirstLine() {
+ if (root_paint_fragment_) {
+ MoveTo(root_paint_fragment_->FirstLineBox());
+ return;
+ }
+ if (IsItemCursor()) {
+ auto iter = std::find_if(
+ items_.begin(), items_.end(),
+ [](const auto& item) { return item->Type() == NGFragmentItem::kLine; });
+ if (iter != items_.end()) {
+ MoveToItem(iter);
+ return;
+ }
+ MakeNull();
+ return;
+ }
+ NOTREACHED();
+}
+
void NGInlineCursor::MoveToFirstLogicalLeaf() {
- DCHECK(IsLineBox());
+ DCHECK(Current().IsLineBox());
// TODO(yosin): This isn't correct for mixed Bidi. Fix it. Besides, we
// should compute and store it during layout.
// TODO(yosin): We should check direction of each container instead of line
// box.
- if (IsLtr(CurrentStyle().Direction())) {
+ if (IsLtr(Current().Style().Direction())) {
while (TryToMoveToFirstChild())
continue;
return;
@@ -799,21 +1078,23 @@ void NGInlineCursor::MoveToLastChild() {
}
void NGInlineCursor::MoveToLastForSameLayoutObject() {
- NGInlineCursor last;
- while (IsNotNull()) {
- last = *this;
+ if (!Current())
+ return;
+ NGInlineCursorPosition last;
+ do {
+ last = Current();
MoveToNextForSameLayoutObject();
- }
- *this = last;
+ } while (Current());
+ MoveTo(last);
}
void NGInlineCursor::MoveToLastLogicalLeaf() {
- DCHECK(IsLineBox());
+ DCHECK(Current().IsLineBox());
// TODO(yosin): This isn't correct for mixed Bidi. Fix it. Besides, we
// should compute and store it during layout.
// TODO(yosin): We should check direction of each container instead of line
// box.
- if (IsLtr(CurrentStyle().Direction())) {
+ if (IsLtr(Current().Style().Direction())) {
while (TryToMoveToLastChild())
continue;
return;
@@ -830,15 +1111,16 @@ void NGInlineCursor::MoveToNext() {
void NGInlineCursor::MoveToNextForSameLayoutObject() {
if (layout_inline_) {
+ DCHECK(!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
// Move to next fragment in culled inline box undef |layout_inline_|.
do {
MoveToNext();
} while (IsNotNull() && !IsPartOfCulledInlineBox(*layout_inline_));
return;
}
- if (current_paint_fragment_) {
+ if (current_.paint_fragment_) {
if (auto* paint_fragment =
- current_paint_fragment_->NextForSameLayoutObject()) {
+ 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();
@@ -846,11 +1128,11 @@ void NGInlineCursor::MoveToNextForSameLayoutObject() {
}
return MakeNull();
}
- if (current_item_) {
- const wtf_size_t delta = current_item_->DeltaToNextForSameLayoutObject();
+ if (current_.item_) {
+ const wtf_size_t delta = current_.item_->DeltaToNextForSameLayoutObject();
if (delta == 0u)
return MakeNull();
- return MoveToItem(item_iter_ + delta);
+ return MoveToItem(current_.item_iter_ + delta);
}
}
@@ -864,7 +1146,7 @@ void NGInlineCursor::MoveToNextInlineLeaf() {
void NGInlineCursor::MoveToNextInlineLeafIgnoringLineBreak() {
do {
MoveToNextInlineLeaf();
- } while (IsNotNull() && IsLineBreak());
+ } while (Current() && Current().IsLineBreak());
}
void NGInlineCursor::MoveToNextInlineLeafOnLine() {
@@ -883,23 +1165,23 @@ void NGInlineCursor::MoveToNextInlineLeafOnLine() {
}
void NGInlineCursor::MoveToNextLine() {
- DCHECK(IsLineBox());
- if (current_paint_fragment_) {
- if (auto* paint_fragment = current_paint_fragment_->NextSibling())
+ DCHECK(Current().IsLineBox());
+ if (current_.paint_fragment_) {
+ if (auto* paint_fragment = current_.paint_fragment_->NextSibling())
return MoveTo(*paint_fragment);
return MakeNull();
}
- if (current_item_) {
+ if (current_.item_) {
do {
MoveToNextItem();
- } while (IsNotNull() && !IsLineBox());
+ } while (Current() && !Current().IsLineBox());
return;
}
NOTREACHED();
}
void NGInlineCursor::MoveToNextSibling() {
- if (current_paint_fragment_)
+ if (current_.paint_fragment_)
return MoveToNextSiblingPaintFragment();
return MoveToNextSiblingItem();
}
@@ -926,7 +1208,7 @@ void NGInlineCursor::MoveToPreviousInlineLeaf() {
void NGInlineCursor::MoveToPreviousInlineLeafIgnoringLineBreak() {
do {
MoveToPreviousInlineLeaf();
- } while (IsNotNull() && IsLineBreak());
+ } while (Current() && Current().IsLineBreak());
}
void NGInlineCursor::MoveToPreviousInlineLeafOnLine() {
@@ -945,17 +1227,17 @@ void NGInlineCursor::MoveToPreviousInlineLeafOnLine() {
void NGInlineCursor::MoveToPreviousLine() {
// Note: List marker is sibling of line box.
- DCHECK(IsLineBox());
- if (current_paint_fragment_) {
+ DCHECK(Current().IsLineBox());
+ if (current_.paint_fragment_) {
do {
MoveToPreviousSiblingPaintFragment();
- } while (IsNotNull() && !IsLineBox());
+ } while (Current() && !Current().IsLineBox());
return;
}
- if (current_item_) {
+ if (current_.item_) {
do {
MoveToPreviousItem();
- } while (IsNotNull() && !IsLineBox());
+ } while (Current() && !Current().IsLineBox());
return;
}
NOTREACHED();
@@ -965,10 +1247,10 @@ bool NGInlineCursor::TryToMoveToFirstChild() {
if (!HasChildren())
return false;
if (root_paint_fragment_) {
- MoveTo(*current_paint_fragment_->FirstChild());
+ MoveTo(*current_.paint_fragment_->FirstChild());
return true;
}
- MoveToItem(item_iter_ + 1);
+ MoveToItem(current_.item_iter_ + 1);
return true;
}
@@ -976,14 +1258,14 @@ bool NGInlineCursor::TryToMoveToLastChild() {
if (!HasChildren())
return false;
if (root_paint_fragment_) {
- MoveTo(current_paint_fragment_->Children().back());
+ MoveTo(current_.paint_fragment_->Children().back());
return true;
}
- const auto end = item_iter_ + CurrentItem()->DescendantsCount();
+ const auto end = current_.item_iter_ + CurrentItem()->DescendantsCount();
MoveToNextItem();
DCHECK(!IsNull());
- for (auto it = item_iter_ + 1; it != end; ++it) {
- if (CurrentItem()->HasSameParent(**it))
+ for (auto it = current_.item_iter_ + 1; it != end; ++it) {
+ if (CurrentItem()->IsSiblingOf(**it))
MoveToItem(it);
}
return true;
@@ -991,78 +1273,78 @@ bool NGInlineCursor::TryToMoveToLastChild() {
void NGInlineCursor::MoveToNextItem() {
DCHECK(IsItemCursor());
- if (UNLIKELY(!current_item_))
+ if (UNLIKELY(!current_.item_))
return;
- DCHECK(item_iter_ != items_.end());
- ++item_iter_;
- MoveToItem(item_iter_);
+ DCHECK(current_.item_iter_ != items_.end());
+ ++current_.item_iter_;
+ MoveToItem(current_.item_iter_);
}
void NGInlineCursor::MoveToNextItemSkippingChildren() {
DCHECK(IsItemCursor());
- if (UNLIKELY(!current_item_))
+ if (UNLIKELY(!current_.item_))
return;
// If the current item has |DescendantsCount|, add it to move to the next
// sibling, skipping all children and their descendants.
- if (wtf_size_t descendants_count = current_item_->DescendantsCount())
- return MoveToItem(item_iter_ + descendants_count);
+ if (wtf_size_t descendants_count = current_.item_->DescendantsCount())
+ return MoveToItem(current_.item_iter_ + descendants_count);
return MoveToNextItem();
}
void NGInlineCursor::MoveToNextSiblingItem() {
DCHECK(IsItemCursor());
- if (UNLIKELY(!current_item_))
+ if (UNLIKELY(!current_.item_))
return;
const NGFragmentItem& item = *CurrentItem();
MoveToNextItemSkippingChildren();
- if (IsNull() || item.HasSameParent(*CurrentItem()))
+ if (IsNull() || item.IsSiblingOf(*CurrentItem()))
return;
MakeNull();
}
void NGInlineCursor::MoveToPreviousItem() {
DCHECK(IsItemCursor());
- if (UNLIKELY(!current_item_))
+ if (UNLIKELY(!current_.item_))
return;
- if (item_iter_ == items_.begin())
+ if (current_.item_iter_ == items_.begin())
return MakeNull();
- --item_iter_;
- current_item_ = item_iter_->get();
+ --current_.item_iter_;
+ current_.item_ = current_.item_iter_->get();
}
void NGInlineCursor::MoveToParentPaintFragment() {
- DCHECK(IsPaintFragmentCursor() && current_paint_fragment_);
- const NGPaintFragment* parent = current_paint_fragment_->Parent();
+ DCHECK(IsPaintFragmentCursor() && current_.paint_fragment_);
+ const NGPaintFragment* parent = current_.paint_fragment_->Parent();
if (parent && parent != root_paint_fragment_) {
- current_paint_fragment_ = parent;
+ current_.paint_fragment_ = parent;
return;
}
- current_paint_fragment_ = nullptr;
+ current_.paint_fragment_ = nullptr;
}
void NGInlineCursor::MoveToNextPaintFragment() {
- DCHECK(IsPaintFragmentCursor() && current_paint_fragment_);
- if (const NGPaintFragment* child = current_paint_fragment_->FirstChild()) {
- current_paint_fragment_ = child;
+ DCHECK(IsPaintFragmentCursor() && current_.paint_fragment_);
+ if (const NGPaintFragment* child = current_.paint_fragment_->FirstChild()) {
+ current_.paint_fragment_ = child;
return;
}
MoveToNextPaintFragmentSkippingChildren();
}
void NGInlineCursor::MoveToNextSiblingPaintFragment() {
- DCHECK(IsPaintFragmentCursor() && current_paint_fragment_);
- if (const NGPaintFragment* next = current_paint_fragment_->NextSibling()) {
- current_paint_fragment_ = next;
+ DCHECK(IsPaintFragmentCursor() && current_.paint_fragment_);
+ if (const NGPaintFragment* next = current_.paint_fragment_->NextSibling()) {
+ current_.paint_fragment_ = next;
return;
}
- current_paint_fragment_ = nullptr;
+ current_.paint_fragment_ = nullptr;
}
void NGInlineCursor::MoveToNextPaintFragmentSkippingChildren() {
- DCHECK(IsPaintFragmentCursor() && current_paint_fragment_);
- while (current_paint_fragment_) {
- if (const NGPaintFragment* next = current_paint_fragment_->NextSibling()) {
- current_paint_fragment_ = next;
+ DCHECK(IsPaintFragmentCursor() && current_.paint_fragment_);
+ while (current_.paint_fragment_) {
+ if (const NGPaintFragment* next = current_.paint_fragment_->NextSibling()) {
+ current_.paint_fragment_ = next;
return;
}
MoveToParentPaintFragment();
@@ -1070,25 +1352,25 @@ void NGInlineCursor::MoveToNextPaintFragmentSkippingChildren() {
}
void NGInlineCursor::MoveToPreviousPaintFragment() {
- DCHECK(IsPaintFragmentCursor() && current_paint_fragment_);
- const NGPaintFragment* const parent = current_paint_fragment_->Parent();
+ DCHECK(IsPaintFragmentCursor() && current_.paint_fragment_);
+ const NGPaintFragment* const parent = current_.paint_fragment_->Parent();
MoveToPreviousSiblingPaintFragment();
- if (current_paint_fragment_) {
+ if (current_.paint_fragment_) {
while (TryToMoveToLastChild())
continue;
return;
}
- current_paint_fragment_ = parent == root_paint_fragment_ ? nullptr : parent;
+ current_.paint_fragment_ = parent == root_paint_fragment_ ? nullptr : parent;
}
void NGInlineCursor::MoveToPreviousSiblingPaintFragment() {
- DCHECK(IsPaintFragmentCursor() && current_paint_fragment_);
- const NGPaintFragment* const current = current_paint_fragment_;
- current_paint_fragment_ = nullptr;
+ DCHECK(IsPaintFragmentCursor() && current_.paint_fragment_);
+ const NGPaintFragment* const current = current_.paint_fragment_;
+ current_.paint_fragment_ = nullptr;
for (auto* sibling : current->Parent()->Children()) {
if (sibling == current)
return;
- current_paint_fragment_ = sibling;
+ current_.paint_fragment_ = sibling;
}
NOTREACHED();
}
@@ -1096,28 +1378,35 @@ void NGInlineCursor::MoveToPreviousSiblingPaintFragment() {
NGInlineBackwardCursor::NGInlineBackwardCursor(const NGInlineCursor& cursor)
: cursor_(cursor) {
if (cursor.root_paint_fragment_) {
+ DCHECK(!cursor.CurrentPaintFragment() ||
+ cursor.CurrentPaintFragment()->Parent()->FirstChild() ==
+ cursor.CurrentPaintFragment());
for (NGInlineCursor sibling(cursor); sibling; sibling.MoveToNextSibling())
sibling_paint_fragments_.push_back(sibling.CurrentPaintFragment());
current_index_ = sibling_paint_fragments_.size();
if (current_index_)
- current_paint_fragment_ = sibling_paint_fragments_[--current_index_];
+ current_.paint_fragment_ = sibling_paint_fragments_[--current_index_];
return;
}
if (cursor.IsItemCursor()) {
- for (NGInlineCursor sibling(cursor); sibling; sibling.MoveToNextSibling())
- sibling_item_iterators_.push_back(sibling.item_iter_);
+ DCHECK(!cursor || cursor.items_.begin() == cursor.Current().item_iter_);
+ for (NGInlineCursor sibling(cursor); sibling;
+ sibling.MoveToNextSkippingChildren())
+ sibling_item_iterators_.push_back(sibling.Current().item_iter_);
current_index_ = sibling_item_iterators_.size();
- if (current_index_)
- current_item_ = sibling_item_iterators_[--current_index_]->get();
+ if (current_index_) {
+ current_.item_iter_ = sibling_item_iterators_[--current_index_];
+ current_.item_ = current_.item_iter_->get();
+ }
return;
}
- NOTREACHED();
+ DCHECK(!cursor);
}
NGInlineCursor NGInlineBackwardCursor::CursorForDescendants() const {
- if (const NGPaintFragment* current_paint_fragment = CurrentPaintFragment())
+ if (const NGPaintFragment* current_paint_fragment = Current().PaintFragment())
return NGInlineCursor(*current_paint_fragment);
- if (current_item_) {
+ if (current_.item_) {
NGInlineCursor cursor(cursor_);
cursor.MoveToItem(sibling_item_iterators_[current_index_]);
return cursor.CursorForDescendants();
@@ -1126,38 +1415,21 @@ NGInlineCursor NGInlineBackwardCursor::CursorForDescendants() const {
return NGInlineCursor();
}
-const PhysicalOffset NGInlineBackwardCursor::CurrentOffset() const {
- if (current_paint_fragment_)
- return current_paint_fragment_->InlineOffsetToContainerBox();
- if (current_item_)
- return current_item_->Offset();
- NOTREACHED();
- return PhysicalOffset();
-}
-
-const PhysicalRect NGInlineBackwardCursor::CurrentSelfInkOverflow() const {
- if (current_paint_fragment_)
- return current_paint_fragment_->SelfInkOverflow();
- if (current_item_)
- return current_item_->SelfInkOverflow();
- NOTREACHED();
- return PhysicalRect();
-}
-
void NGInlineBackwardCursor::MoveToPreviousSibling() {
if (current_index_) {
- if (current_paint_fragment_) {
- current_paint_fragment_ = sibling_paint_fragments_[--current_index_];
+ if (current_.paint_fragment_) {
+ current_.paint_fragment_ = sibling_paint_fragments_[--current_index_];
return;
}
- if (current_item_) {
- current_item_ = sibling_item_iterators_[--current_index_]->get();
+ if (current_.item_) {
+ current_.item_iter_ = sibling_item_iterators_[--current_index_];
+ current_.item_ = current_.item_iter_->get();
return;
}
NOTREACHED();
}
- current_paint_fragment_ = nullptr;
- current_item_ = nullptr;
+ current_.paint_fragment_ = nullptr;
+ current_.item_ = nullptr;
}
std::ostream& operator<<(std::ostream& ostream, const NGInlineCursor& cursor) {
@@ -1177,4 +1449,18 @@ std::ostream& operator<<(std::ostream& ostream, const NGInlineCursor* cursor) {
return ostream << *cursor;
}
+#if DCHECK_IS_ON()
+void NGInlineCursor::CheckValid(const NGInlineCursorPosition& position) const {
+ if (position.PaintFragment()) {
+ DCHECK(root_paint_fragment_);
+ DCHECK(
+ position.PaintFragment()->IsDescendantOfNotSelf(*root_paint_fragment_));
+ } else if (position.Item()) {
+ DCHECK(IsItemCursor());
+ const unsigned index = position.item_iter_ - items_.begin();
+ DCHECK_LT(index, items_.size());
+ }
+}
+#endif
+
} // namespace blink
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 9c23ab2daef..c9626d87b5e 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
@@ -25,7 +25,9 @@ class LayoutObject;
class LayoutUnit;
class NGFragmentItem;
class NGFragmentItems;
+class NGInlineBackwardCursor;
class NGInlineBreakToken;
+class NGInlineCursor;
class NGPaintFragment;
class NGPhysicalBoxFragment;
class Node;
@@ -35,6 +37,128 @@ struct PhysicalOffset;
struct PhysicalRect;
struct PhysicalSize;
+// Represents a position of |NGInlineCursor|. This class:
+// 1. Provides properties for the current position.
+// 2. Allows to save |Current()|, and can move back later. Moving to |Position|
+// is faster than moving to |NGFragmentItem|.
+class CORE_EXPORT NGInlineCursorPosition {
+ STACK_ALLOCATED();
+
+ public:
+ using ItemsSpan = base::span<const std::unique_ptr<NGFragmentItem>>;
+
+ const NGPaintFragment* PaintFragment() const { return paint_fragment_; }
+ const NGFragmentItem* Item() const { return item_; }
+ const NGFragmentItem* operator->() const { return item_; }
+ const NGFragmentItem& operator*() const { return *item_; }
+
+ operator bool() const { return paint_fragment_ || item_; }
+
+ bool operator==(const NGInlineCursorPosition& other) const {
+ return paint_fragment_ == other.paint_fragment_ && item_ == other.item_;
+ }
+ bool operator!=(const NGInlineCursorPosition& other) const {
+ return !operator==(other);
+ }
+
+ // True if the current position is a text. It is error to call at end.
+ bool IsText() const;
+
+ // True if the current position is a generatd text. It is error to call at
+ // end.
+ bool IsGeneratedText() const;
+
+ // True if fragment is |NGFragmentItem::kGeneratedText| or
+ // |NGPhysicalTextFragment::kGeneratedText|.
+ // TODO(yosin): We should rename |IsGeneratedTextType()| to another name.
+ bool IsGeneratedTextType() const;
+
+ // True if the current position is a line break. It is error to call at end.
+ bool IsLineBreak() const;
+
+ // True if the current position is an ellipsis. It is error to call at end.
+ bool IsEllipsis() const;
+
+ // True if the current position is a line box. It is error to call at end.
+ bool IsLineBox() const;
+
+ // True if the current position is an empty line box. It is error to call
+ // other then line box.
+ bool IsEmptyLineBox() const;
+
+ // True if the current position is an inline box. It is error to call at end.
+ bool IsInlineBox() const;
+
+ // True if the current position is an atomic inline. It is error to call at
+ // end.
+ bool IsAtomicInline() const;
+
+ // True if the current position is a list marker.
+ bool IsListMarker() const;
+
+ // True if the current position is hidden for paint. It is error to call at
+ // end.
+ bool IsHiddenForPaint() const;
+
+ // |ComputedStyle| and related functions.
+ NGStyleVariant StyleVariant() const;
+ bool UsesFirstLineStyle() const;
+ const ComputedStyle& Style() const;
+
+ // Functions to get corresponding objects for this position.
+ const NGPhysicalBoxFragment* BoxFragment() const;
+ const LayoutObject* GetLayoutObject() const;
+ LayoutObject* GetMutableLayoutObject() const;
+ const Node* GetNode() const;
+ const DisplayItemClient* GetDisplayItemClient() const;
+
+ // Returns break token for line box. It is error to call other than line box.
+ const NGInlineBreakToken* InlineBreakToken() const;
+
+ // The offset relative to the root of the inline formatting context.
+ const PhysicalRect RectInContainerBlock() const;
+ const PhysicalOffset OffsetInContainerBlock() const;
+ const PhysicalSize Size() const;
+
+ // InkOverflow of itself, including contents if they contribute to the ink
+ // overflow of this object (e.g. when not clipped,) in the local coordinate.
+ const PhysicalRect InkOverflow() const;
+ const PhysicalRect SelfInkOverflow() const;
+
+ // Returns start/end of offset in text content of current text fragment.
+ // It is error when this cursor doesn't point to text fragment.
+ NGTextOffset TextOffset() const;
+ unsigned TextStartOffset() const { return TextOffset().start; }
+ unsigned TextEndOffset() const { return TextOffset().end; }
+
+ // Returns text of the current position. It is error to call other than
+ // text.
+ StringView Text(const NGInlineCursor& cursor) const;
+
+ // Returns |ShapeResultView| of the current position. It is error to call
+ // other than text.
+ const ShapeResultView* TextShapeResult() const;
+
+ // Returns bidi level of current position. It is error to call other than
+ // text and atomic inline. It is also error to call |IsGeneratedTextType()|.
+ UBiDiLevel BidiLevel() const;
+ // Returns text direction of current text or atomic inline. It is error to
+ // call at other than text or atomic inline. Note: <span> doesn't have
+ // reserved direction.
+ TextDirection ResolvedDirection() const;
+ // Returns text direction of current line. It is error to call at other than
+ // line.
+ TextDirection BaseDirection() const;
+
+ private:
+ const NGPaintFragment* paint_fragment_ = nullptr;
+ const NGFragmentItem* item_ = nullptr;
+ ItemsSpan::iterator item_iter_;
+
+ friend class NGInlineBackwardCursor;
+ friend class NGInlineCursor;
+};
+
// This class traverses fragments in an inline formatting context.
//
// When constructed, the initial position is empty. Call |MoveToNext()| to move
@@ -53,12 +177,13 @@ class CORE_EXPORT NGInlineCursor {
explicit NGInlineCursor(const NGFragmentItems& fragment_items,
ItemsSpan items);
explicit NGInlineCursor(const NGPaintFragment& root_paint_fragment);
- NGInlineCursor(const NGInlineCursor& other);
+ NGInlineCursor(const NGInlineCursor& other) = default;
+ NGInlineCursor(const NGInlineBackwardCursor& backward_cursor);
// Creates an |NGInlineCursor| without the root. Even when callers don't know
// the root of the inline formatting context, this cursor can |MoveTo()|
// specific |LayoutObject|.
- NGInlineCursor();
+ NGInlineCursor() = default;
bool operator==(const NGInlineCursor& other) const;
bool operator!=(const NGInlineCursor& other) const {
@@ -83,12 +208,13 @@ class CORE_EXPORT NGInlineCursor {
//
// Functions to query the current position.
//
+ const NGInlineCursorPosition& Current() const { return current_; }
// Returns true if cursor is out of fragment tree, e.g. before first fragment
// or after last fragment in tree.
- bool IsNull() const { return !current_item_ && !current_paint_fragment_; }
- bool IsNotNull() const { return !IsNull(); }
- explicit operator bool() const { return !IsNull(); }
+ bool IsNull() const { return !Current(); }
+ bool IsNotNull() const { return Current(); }
+ operator bool() const { return Current(); }
// True if fragment at the current position can have children.
bool CanHaveChildren() const;
@@ -101,104 +227,38 @@ class CORE_EXPORT NGInlineCursor {
// has no children, returns an empty cursor.
NGInlineCursor CursorForDescendants() const;
+ // If |this| is created by |CursorForDescendants()| to traverse parts of an
+ // inline formatting context, expand the traversable range to the containing
+ // |LayoutBlockFlow|. Does nothing if |this| is for an inline formatting
+ // context.
+ void ExpandRootToContainingBlock();
+
// True if current position has soft wrap to next line. It is error to call
// other than line.
bool HasSoftWrapToNextLine() const;
- // True if the current position is a atomic inline. It is error to call at
- // end.
- bool IsAtomicInline() const;
-
// True if the current position is before soft line break. It is error to call
// at end.
bool IsBeforeSoftLineBreak() const;
- // True if the current position is an ellipsis. It is error to call at end.
- bool IsEllipsis() const;
-
- // True if the current position is an empty line box. It is error to call
- // other then line box.
- bool IsEmptyLineBox() const;
-
- // True if the current position is a generatd text. It is error to call at
- // end.
- bool IsGeneratedText() const;
-
- // True if fragment is |NGFragmentItem::kGeneratedText| or
- // |NGPhysicalTextFragment::kGeneratedText|.
- // TODO(yosin): We should rename |IsGeneratedTextType()| to another name.
- bool IsGeneratedTextType() const;
-
- // True if the current position is hidden for paint. It is error to call at
- // end.
- bool IsHiddenForPaint() const;
-
- // True if the current position's writing mode in style is horizontal.
- bool IsHorizontal() const;
-
// 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,
// and line break hyphen.
bool IsInlineLeaf() const;
- // True if the current position is a line box. It is error to call at end.
- bool IsLineBox() const;
-
- // True if the current position is a line break. It is error to call at end.
- bool IsLineBreak() const;
-
- // True if the current position is a list marker.
- bool IsListMarker() const;
-
- // True if the current position is a text. It is error to call at end.
- bool IsText() const;
-
// |Current*| functions return an object for the current position.
- const NGFragmentItem* CurrentItem() const { return current_item_; }
+ const NGFragmentItem* CurrentItem() const { return Current().Item(); }
const NGPaintFragment* CurrentPaintFragment() const {
- return current_paint_fragment_;
+ return Current().PaintFragment();
+ }
+ LayoutObject* CurrentMutableLayoutObject() const {
+ return Current().GetMutableLayoutObject();
}
- // Returns text direction of current line. It is error to call at other than
- // line.
- TextDirection CurrentBaseDirection() const;
- const NGPhysicalBoxFragment* CurrentBoxFragment() const;
- const DisplayItemClient* CurrentDisplayItemClient() const;
- const LayoutObject* CurrentLayoutObject() const;
- LayoutObject* CurrentMutableLayoutObject() const;
- Node* CurrentNode() const;
-
- // Returns bidi level of current position. It is error to call other than
- // text and atomic inline. It is also error to call |IsGeneratedTextType()|.
- UBiDiLevel CurrentBidiLevel() const;
-
- // Returns text direction of current text or atomic inline. It is error to
- // call at other than text or atomic inline. Note: <span> doesn't have
- // reserved direction.
- TextDirection CurrentResolvedDirection() const;
- const ComputedStyle& CurrentStyle() const;
-
- // InkOverflow of itself, including contents if they contribute to the ink
- // overflow of this object (e.g. when not clipped,) in the local coordinate.
- const PhysicalRect CurrentInkOverflow() const;
- // The offset relative to the root of the inline formatting context.
- const PhysicalOffset CurrentOffset() const;
- const PhysicalRect CurrentRect() const;
- const PhysicalSize CurrentSize() const;
-
- // Returns start/end of offset in text content of current text fragment.
- // It is error when this cursor doesn't point to text fragment.
- NGTextOffset CurrentTextOffset() const;
- unsigned CurrentTextStartOffset() const { return CurrentTextOffset().start; }
- unsigned CurrentTextEndOffset() const { return CurrentTextOffset().end; }
// Returns text of the current position. It is error to call other than
// text.
- StringView CurrentText() const;
-
- // Returns |ShapeResultView| of the current position. It is error to call
- // other than text.
- const ShapeResultView* CurrentTextShapeResult() const;
+ StringView CurrentText() const { return Current().Text(*this); }
// The layout box of text in (start, end) range in local coordinate.
// Start and end offsets must be between |CurrentTextStartOffset()| and
@@ -216,12 +276,24 @@ class CORE_EXPORT NGInlineCursor {
PhysicalOffset LineEndPoint() const;
// Converts the given point, relative to the fragment itself, into a position
- // in DOM tree within the range of |this|.
- PositionWithAffinity PositionForPoint(const PhysicalOffset&);
+ // in DOM tree within the range of |this|. This variation ignores the inline
+ // offset, and snaps to the nearest line in the block direction.
+ PositionWithAffinity PositionForPointInInlineFormattingContext(
+ const PhysicalOffset& point,
+ const NGPhysicalBoxFragment& container);
+ // Find the |Position| in the line box |Current()| points to. This variation
+ // ignores the block offset, and snaps to the nearest item in inline
+ // direction.
+ PositionWithAffinity PositionForPointInInlineBox(
+ const PhysicalOffset& point) const;
//
// Functions to move the current position.
//
+ void MoveTo(const NGInlineCursorPosition& position);
+
+ // Move the current position at |fragment_item|.
+ void MoveTo(const NGFragmentItem& fragment_item);
// Move the current position at |cursor|. Unlinke copy constrcutr, this
// function doesn't copy root. Note: The current position in |cursor|
@@ -230,6 +302,7 @@ class CORE_EXPORT NGInlineCursor {
// Move the current posint at |paint_fragment|.
void MoveTo(const NGPaintFragment& paint_fragment);
+ void MoveTo(const NGPaintFragment* paint_fragment);
// Move to first |NGFragmentItem| or |NGPaintFragment| associated to
// |layout_object|. When |layout_object| has no associated fragments, this
@@ -244,6 +317,9 @@ class CORE_EXPORT NGInlineCursor {
// See also |TryToMoveToFirstChild()|.
void MoveToFirstChild();
+ // Move to the first line.
+ void MoveToFirstLine();
+
// Move to first logical leaf of current line box. If current line box has
// no children, curosr becomes null.
void MoveToFirstLogicalLeaf();
@@ -253,6 +329,9 @@ class CORE_EXPORT NGInlineCursor {
// See also |TryToMoveToFirstChild()|.
void MoveToLastChild();
+ // Move the current position to the last fragment on same layout object.
+ void MoveToLastForSameLayoutObject();
+
// Move to last logical leaf of current line box. If current line box has
// no children, curosr becomes null.
void MoveToLastLogicalLeaf();
@@ -269,6 +348,7 @@ class CORE_EXPORT NGInlineCursor {
void MoveToNextLine();
// Move the current position to next sibling fragment.
+ // |MoveToNextSibling()| is deprecated. New code should not be used.
void MoveToNextSibling();
// Same as |MoveToNext| except that this skips children even if they exist.
@@ -304,14 +384,13 @@ class CORE_EXPORT NGInlineCursor {
// TODO(kojii): Add more variations as needed, NextSibling,
// NextSkippingChildren, Previous, etc.
- private:
- // Returns break token for line box. It is error to call other than line box.
- const NGInlineBreakToken& CurrentInlineBreakToken() const;
-
- // Returns style variant of the current position.
- NGStyleVariant CurrentStyleVariant() const;
- bool UsesFirstLineStyle() const;
+#if DCHECK_IS_ON()
+ void CheckValid(const NGInlineCursorPosition& position) const;
+#else
+ void CheckValid(const NGInlineCursorPosition&) const {}
+#endif
+ private:
// True if current position is part of culled inline box |layout_inline|.
bool IsPartOfCulledInlineBox(const LayoutInline& layout_inline) const;
@@ -326,9 +405,6 @@ class CORE_EXPORT NGInlineCursor {
// Move the cursor position to the first fragment in tree.
void MoveToFirst();
- // Move the current position to the last fragment on same layout object.
- void MoveToLastForSameLayoutObject();
-
// Same as |MoveTo()| but not support culled inline.
void InternalMoveTo(const LayoutObject& layout_object);
@@ -350,13 +426,20 @@ class CORE_EXPORT NGInlineCursor {
void MoveToPreviousPaintFragment();
void MoveToPreviousSiblingPaintFragment();
+ ItemsSpan::iterator SlowFirstItemIteratorFor(
+ const LayoutObject& layout_object) const;
+ unsigned SpanIndexFromItemIndex(unsigned index) const;
+
+ PositionWithAffinity PositionForPointInChild(
+ const PhysicalOffset& point,
+ const NGFragmentItem& child_item) const;
+
+ NGInlineCursorPosition current_;
+
ItemsSpan items_;
- ItemsSpan::iterator item_iter_;
- const NGFragmentItem* current_item_ = nullptr;
const NGFragmentItems* fragment_items_ = nullptr;
const NGPaintFragment* root_paint_fragment_ = nullptr;
- const NGPaintFragment* current_paint_fragment_ = nullptr;
// Used in |MoveToNextForSameLayoutObject()| to support culled inline.
const LayoutInline* layout_inline_ = nullptr;
@@ -370,31 +453,25 @@ class CORE_EXPORT NGInlineBackwardCursor {
STACK_ALLOCATED();
public:
+ // |cursor| should be the first child of root or descendants, e.g. the first
+ // item in |NGInlineCursor::items_|.
NGInlineBackwardCursor(const NGInlineCursor& cursor);
- NGInlineCursor CursorForDescendants() const;
-
- explicit operator bool() const {
- return current_paint_fragment_ || current_item_;
- }
-
- const NGFragmentItem* CurrentItem() const { return current_item_; }
- const NGPaintFragment* CurrentPaintFragment() const {
- return current_paint_fragment_;
- }
+ const NGInlineCursorPosition& Current() const { return current_; }
+ operator bool() const { return Current(); }
- const PhysicalOffset CurrentOffset() const;
- const PhysicalRect CurrentSelfInkOverflow() const;
+ NGInlineCursor CursorForDescendants() const;
void MoveToPreviousSibling();
private:
+ NGInlineCursorPosition current_;
const NGInlineCursor& cursor_;
Vector<const NGPaintFragment*, 16> sibling_paint_fragments_;
Vector<NGInlineCursor::ItemsSpan::iterator, 16> sibling_item_iterators_;
- const NGPaintFragment* current_paint_fragment_ = nullptr;
- const NGFragmentItem* current_item_ = nullptr;
wtf_size_t current_index_;
+
+ friend class NGInlineCursor;
};
CORE_EXPORT std::ostream& operator<<(std::ostream&, const NGInlineCursor&);
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 8ded96613d1..8398da81ecb 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
@@ -53,7 +53,7 @@ class NGInlineCursorTest : public NGLayoutTest,
Vector<const NGPaintFragment*> backwards;
for (NGInlineBackwardCursor cursor(start); cursor;
cursor.MoveToPreviousSibling())
- backwards.push_back(cursor.CurrentPaintFragment());
+ backwards.push_back(cursor.Current().PaintFragment());
backwards.Reverse();
EXPECT_THAT(backwards, forwards);
return;
@@ -65,16 +65,16 @@ class NGInlineCursorTest : public NGLayoutTest,
Vector<const NGFragmentItem*> backwards;
for (NGInlineBackwardCursor cursor(start); cursor;
cursor.MoveToPreviousSibling())
- backwards.push_back(cursor.CurrentItem());
+ backwards.push_back(cursor.Current().Item());
backwards.Reverse();
EXPECT_THAT(backwards, forwards);
}
String ToDebugString(const NGInlineCursor& cursor) {
- if (cursor.IsLineBox())
+ if (cursor.Current().IsLineBox())
return "#linebox";
- if (cursor.IsGeneratedTextType()) {
+ if (cursor.Current().IsGeneratedTextType()) {
StringBuilder result;
result.Append("#'");
result.Append(cursor.CurrentText());
@@ -82,10 +82,11 @@ class NGInlineCursorTest : public NGLayoutTest,
return result.ToString();
}
- if (cursor.IsText())
+ if (cursor.Current().IsText())
return cursor.CurrentText().ToString().StripWhiteSpace();
- if (const LayoutObject* layout_object = cursor.CurrentLayoutObject()) {
+ if (const LayoutObject* layout_object =
+ cursor.Current().GetLayoutObject()) {
if (const Element* element =
DynamicTo<Element>(layout_object->GetNode())) {
if (const AtomicString& id = element->GetIdAttribute())
@@ -100,18 +101,22 @@ class NGInlineCursorTest : public NGLayoutTest,
Vector<String> ToDebugStringListWithBidiLevel(const NGInlineCursor& start) {
Vector<String> list;
- for (NGInlineCursor cursor(start); cursor; cursor.MoveToNext())
+ for (NGInlineCursor cursor(start); cursor; cursor.MoveToNext()) {
+ // Inline boxes do not have bidi level.
+ if (cursor.Current().IsInlineBox())
+ continue;
list.push_back(ToDebugStringWithBidiLevel(cursor));
+ }
return list;
}
String ToDebugStringWithBidiLevel(const NGInlineCursor& cursor) {
- if (!cursor.IsText() && !cursor.IsAtomicInline())
+ if (!cursor.Current().IsText() && !cursor.Current().IsAtomicInline())
return ToDebugString(cursor);
StringBuilder result;
result.Append(ToDebugString(cursor));
result.Append(':');
- result.AppendNumber(cursor.CurrentBidiLevel());
+ result.AppendNumber(cursor.Current().BidiLevel());
return result.ToString();
}
};
@@ -126,8 +131,8 @@ TEST_P(NGInlineCursorTest, BidiLevelInlineBoxLTR) {
"<div id=root dir=ltr>"
"abc<b id=def>def</b><bdo dir=rtl><b id=ghi>GHI</b></bdo>jkl</div>");
Vector<String> list = ToDebugStringListWithBidiLevel(cursor);
- EXPECT_THAT(list, ElementsAre("#linebox", "abc:0", "#def:0",
- "LayoutInline BDO", "#ghi:1", "jkl:0"));
+ EXPECT_THAT(list,
+ ElementsAre("#linebox", "abc:0", "#def:0", "#ghi:1", "jkl:0"));
}
TEST_P(NGInlineCursorTest, BidiLevelInlineBoxRTL) {
@@ -136,8 +141,8 @@ TEST_P(NGInlineCursorTest, BidiLevelInlineBoxRTL) {
"<div id=root dir=rtl>"
"abc<b id=def>def</b><bdo dir=rtl><b id=ghi>GHI</b></bdo>jkl</div>");
Vector<String> list = ToDebugStringListWithBidiLevel(cursor);
- EXPECT_THAT(list, ElementsAre("#linebox", "LayoutInline BDO", "#ghi:3",
- "jkl:2", "#def:1", "abc:2"));
+ EXPECT_THAT(list,
+ ElementsAre("#linebox", "#ghi:3", "jkl:2", "#def:1", "abc:2"));
}
TEST_P(NGInlineCursorTest, BidiLevelSimpleLTR) {
@@ -163,7 +168,7 @@ TEST_P(NGInlineCursorTest, BidiLevelSimpleRTL) {
TEST_P(NGInlineCursorTest, GetLayoutBlockFlowWithScopedCursor) {
NGInlineCursor line = SetupCursor("<div id=root>line1<br>line2</div>");
- ASSERT_TRUE(line.IsLineBox()) << line;
+ ASSERT_TRUE(line.Current().IsLineBox()) << line;
NGInlineCursor cursor = line.CursorForDescendants();
EXPECT_EQ(line.GetLayoutBlockFlow(), cursor.GetLayoutBlockFlow());
}
@@ -175,11 +180,11 @@ TEST_P(NGInlineCursorTest, ContainingLine) {
SetupCursor("<div id=root>abc<a id=target>def</a>ghi<br>xyz</div>");
const LayoutBlockFlow& block_flow = *cursor.GetLayoutBlockFlow();
NGInlineCursor line1(cursor);
- ASSERT_TRUE(line1.IsLineBox());
+ ASSERT_TRUE(line1.Current().IsLineBox());
NGInlineCursor line2(line1);
line2.MoveToNextSibling();
- ASSERT_TRUE(line2.IsLineBox());
+ ASSERT_TRUE(line2.Current().IsLineBox());
cursor.MoveTo(*block_flow.FirstChild());
cursor.MoveToContainingLine();
@@ -212,9 +217,14 @@ TEST_P(NGInlineCursorTest, CulledInlineWithAtomicInline) {
list.push_back(ToDebugString(cursor));
cursor.MoveToNextForSameLayoutObject();
}
- EXPECT_THAT(list, ElementsAre("abc", "ABC", "", "XYZ", "xyz"));
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ EXPECT_THAT(list, ElementsAre("#culled", "#culled"));
+ else
+ EXPECT_THAT(list, ElementsAre("abc", "ABC", "", "XYZ", "xyz"));
}
+// We should not have float:right fragment, because it isn't in-flow in
+// an inline formatting context.
// For https://crbug.com/1026022
TEST_P(NGInlineCursorTest, CulledInlineWithFloat) {
SetBodyInnerHTML(
@@ -228,23 +238,27 @@ TEST_P(NGInlineCursorTest, CulledInlineWithFloat) {
list.push_back(ToDebugString(cursor));
cursor.MoveToNextForSameLayoutObject();
}
- EXPECT_THAT(list, ElementsAre("abc", "xyz"))
- << "We should not have float:right fragment, because it isn't in-flow in "
- "an inline formatting context.";
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ EXPECT_THAT(list, ElementsAre("#culled"));
+ else
+ EXPECT_THAT(list, ElementsAre("abc", "xyz"));
}
TEST_P(NGInlineCursorTest, CulledInlineWithRoot) {
- NGInlineCursor cursor =
- SetupCursor("<div id=root><a><b>abc</b><br><i>xyz</i></a></div>");
- const LayoutInline& layout_inline =
- ToLayoutInline(*cursor.GetLayoutBlockFlow()->FirstChild());
- cursor.MoveTo(layout_inline);
+ NGInlineCursor cursor = SetupCursor(R"HTML(
+ <div id="root"><a id="a"><b>abc</b><br><i>xyz</i></a></div>
+ )HTML");
+ const LayoutObject* layout_inline_a = GetLayoutObjectByElementId("a");
+ cursor.MoveTo(*layout_inline_a);
Vector<String> list;
while (cursor) {
list.push_back(ToDebugString(cursor));
cursor.MoveToNextForSameLayoutObject();
}
- EXPECT_THAT(list, ElementsAre("abc", "", "xyz"));
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ EXPECT_THAT(list, ElementsAre("#a", "#a"));
+ else
+ EXPECT_THAT(list, ElementsAre("abc", "", "xyz"));
}
TEST_P(NGInlineCursorTest, CulledInlineWithoutRoot) {
@@ -259,7 +273,10 @@ TEST_P(NGInlineCursorTest, CulledInlineWithoutRoot) {
list.push_back(ToDebugString(cursor));
cursor.MoveToNextForSameLayoutObject();
}
- EXPECT_THAT(list, ElementsAre("abc", "", "xyz"));
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ EXPECT_THAT(list, ElementsAre("#a", "#a"));
+ else
+ EXPECT_THAT(list, ElementsAre("abc", "", "xyz"));
}
TEST_P(NGInlineCursorTest, FirstChild) {
@@ -367,6 +384,17 @@ TEST_P(NGInlineCursorTest, FirstLastLogicalLeafWithImages) {
EXPECT_EQ("#last", ToDebugString(last_logical_leaf));
}
+TEST_P(NGInlineCursorTest, IsEmptyLineBox) {
+ InsertStyleElement("b { margin-bottom: 1px; }");
+ NGInlineCursor cursor = SetupCursor("<div id=root>abc<br><b></b></div>");
+
+ EXPECT_FALSE(cursor.Current().IsEmptyLineBox())
+ << "'abc\\n' is in non-empty line box.";
+ cursor.MoveToNextLine();
+ EXPECT_TRUE(cursor.Current().IsEmptyLineBox())
+ << "<b></b> with margin produces empty line box.";
+}
+
TEST_P(NGInlineCursorTest, LastChild) {
// TDOO(yosin): Remove <style> once NGFragmentItem don't do culled inline.
InsertStyleElement("a, b { background: gray; }");
@@ -431,11 +459,27 @@ TEST_P(NGInlineCursorTest, NextWithEllipsis) {
EXPECT_THAT(list, ElementsAre("#linebox", "abcdefghi", "abcd", u"#'\u2026'"));
}
+TEST_P(NGInlineCursorTest, NextWithEllipsisInlineBoxOnly) {
+ LoadAhem();
+ InsertStyleElement(
+ "#root {"
+ "font: 10px/1 Ahem;"
+ "width: 5ch;"
+ "overflow: hidden;"
+ "text-overflow: ellipsis;"
+ "}"
+ "span { border: solid 10ch blue; }");
+ NGInlineCursor cursor = SetupCursor("<div id=root><span></span></div>");
+ Vector<String> list = ToDebugStringList(cursor);
+ EXPECT_THAT(list, ElementsAre("#linebox", "LayoutInline SPAN"));
+}
+
TEST_P(NGInlineCursorTest, NextWithListItem) {
NGInlineCursor cursor = SetupCursor("<ul><li id=root>abc</li></ul>");
Vector<String> list = ToDebugStringList(cursor);
- EXPECT_THAT(list,
- ElementsAre("LayoutNGListMarker (anonymous)", "#linebox", "abc"));
+ EXPECT_THAT(list, ElementsAre("LayoutNGOutsideListMarker ::marker",
+ "#linebox", "abc"));
+ EXPECT_EQ(GetLayoutObjectByElementId("root"), cursor.GetLayoutBlockFlow());
}
TEST_P(NGInlineCursorTest, NextWithSoftHyphens) {
@@ -546,12 +590,12 @@ TEST_P(NGInlineCursorTest, NextInlineLeafIgnoringLineBreak) {
TEST_P(NGInlineCursorTest, NextLine) {
NGInlineCursor cursor = SetupCursor("<div id=root>abc<br>xyz</div>");
NGInlineCursor line1(cursor);
- while (line1 && !line1.IsLineBox())
+ while (line1 && !line1.Current().IsLineBox())
line1.MoveToNext();
ASSERT_TRUE(line1.IsNotNull());
NGInlineCursor line2(line1);
line2.MoveToNext();
- while (line2 && !line2.IsLineBox())
+ while (line2 && !line2.Current().IsLineBox())
line2.MoveToNext();
ASSERT_NE(line1, line2);
@@ -576,6 +620,10 @@ TEST_P(NGInlineCursorTest, NextWithInlineBox) {
SetupCursor("<div id=root>abc<b id=ib>def</b>xyz</div>");
Vector<String> list = ToDebugStringList(cursor);
EXPECT_THAT(list, ElementsAre("#linebox", "abc", "#ib", "xyz"));
+
+ NGInlineCursor cursor2;
+ cursor2.MoveTo(*GetElementById("ib")->firstChild()->GetLayoutObject());
+ EXPECT_EQ(GetLayoutObjectByElementId("ib"), cursor2.GetLayoutBlockFlow());
}
TEST_P(NGInlineCursorTest, NextForSameLayoutObject) {
@@ -594,10 +642,10 @@ TEST_P(NGInlineCursorTest, Sibling) {
InsertStyleElement("a, b { background: gray; }");
NGInlineCursor cursor =
SetupCursor("<div id=root>abc<a>DEF<b>GHI</b></a>xyz</div>");
+ TestPrevoiusSibling(cursor.CursorForDescendants());
cursor.MoveToFirstChild(); // go to "abc"
Vector<String> list = SiblingsToDebugStringList(cursor);
EXPECT_THAT(list, ElementsAre("abc", "LayoutInline A", "xyz"));
- TestPrevoiusSibling(cursor);
}
TEST_P(NGInlineCursorTest, Sibling2) {
@@ -606,10 +654,10 @@ TEST_P(NGInlineCursorTest, Sibling2) {
NGInlineCursor cursor =
SetupCursor("<div id=root><a>abc<b>def</b>xyz</a></div>");
cursor.MoveToFirstChild(); // go to <a>abc</a>
+ TestPrevoiusSibling(cursor.CursorForDescendants());
cursor.MoveToFirstChild(); // go to "abc"
Vector<String> list = SiblingsToDebugStringList(cursor);
EXPECT_THAT(list, ElementsAre("abc", "LayoutInline B", "xyz"));
- TestPrevoiusSibling(cursor);
}
TEST_P(NGInlineCursorTest, NextSkippingChildren) {
@@ -741,12 +789,12 @@ TEST_P(NGInlineCursorTest, PreviousInlineLeafOnLineFromLayoutText) {
TEST_P(NGInlineCursorTest, PreviousLine) {
NGInlineCursor cursor = SetupCursor("<div id=root>abc<br>xyz</div>");
NGInlineCursor line1(cursor);
- while (line1 && !line1.IsLineBox())
+ while (line1 && !line1.Current().IsLineBox())
line1.MoveToNext();
ASSERT_TRUE(line1.IsNotNull());
NGInlineCursor line2(line1);
line2.MoveToNext();
- while (line2 && !line2.IsLineBox())
+ while (line2 && !line2.Current().IsLineBox())
line2.MoveToNext();
ASSERT_NE(line1, line2);
@@ -784,9 +832,9 @@ TEST_P(NGInlineCursorTest, CursorForDescendants) {
LayoutBlockFlow* block_flow =
To<LayoutBlockFlow>(GetLayoutObjectByElementId("root"));
NGInlineCursor cursor(*block_flow);
- EXPECT_TRUE(cursor.IsLineBox());
+ EXPECT_TRUE(cursor.Current().IsLineBox());
cursor.MoveToNext();
- EXPECT_TRUE(cursor.IsText());
+ EXPECT_TRUE(cursor.Current().IsText());
EXPECT_THAT(ToDebugStringList(cursor.CursorForDescendants()), ElementsAre());
cursor.MoveToNext();
EXPECT_EQ(ToDebugString(cursor), "#span1");
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal.cc
index d9aa540d902..443c9070088 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal.cc
@@ -62,13 +62,13 @@ class NGPhysicalFragmentCollectorBase {
// Traverse descendants unless the fragment is laid out separately from the
// inline layout algorithm.
- if (&fragment != root_fragment_ && fragment.IsBlockFormattingContextRoot())
+ if (&fragment != root_fragment_ && fragment.IsFormattingContextRoot())
return;
DCHECK(fragment.IsContainer());
DCHECK(fragment.IsInline() || fragment.IsLineBox() ||
(fragment.IsBlockFlow() &&
- To<NGPhysicalBoxFragment>(fragment).ChildrenInline()));
+ To<NGPhysicalBoxFragment>(fragment).IsInlineFormattingContext()));
for (const auto& child :
To<NGPhysicalContainerFragment>(fragment).Children()) {
@@ -179,7 +179,7 @@ Vector<Result> NGInlineFragmentTraversal::SelfFragmentsOf(
for (const NGPaintFragment* fragment :
NGPaintFragment::InlineFragmentsFor(layout_object)) {
result.push_back(Result{&fragment->PhysicalFragment(),
- fragment->InlineOffsetToContainerBox()});
+ fragment->OffsetInContainerBlock()});
}
return result;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal_test.cc
index e9ab83060fe..d356f218bbf 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal_test.cc
@@ -50,6 +50,10 @@ class NGInlineFragmentTraversalTest : public NGLayoutTest {
}
TEST_F(NGInlineFragmentTraversalTest, DescendantsOf) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ // NGFragmentItem doesn't use |NGInlineFragmentTraversal|.
+ return;
+ }
SetBodyInnerHTML(
"<style>* { border: 1px solid}</style>"
"<div id=t>foo<b id=b>bar</b><br>baz</div>");
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.cc
index 1e17b432948..bb809f51b2b 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.cc
@@ -60,7 +60,8 @@ bool IsInlineBoxEndEmpty(const ComputedStyle& style,
NGInlineItem::NGInlineItem(NGInlineItemType type,
unsigned start,
unsigned end,
- LayoutObject* layout_object)
+ LayoutObject* layout_object,
+ bool is_first_for_node)
: start_offset_(start),
end_offset_(end),
layout_object_(layout_object),
@@ -74,7 +75,8 @@ NGInlineItem::NGInlineItem(NGInlineItemType type,
end_collapse_type_(kNotCollapsible),
is_end_collapsible_newline_(false),
is_symbol_marker_(false),
- is_generated_for_line_break_(false) {
+ is_generated_for_line_break_(false),
+ is_first_for_node_(is_first_for_node) {
DCHECK_GE(end, start);
ComputeBoxProperties();
}
@@ -97,7 +99,8 @@ NGInlineItem::NGInlineItem(const NGInlineItem& other,
end_collapse_type_(other.end_collapse_type_),
is_end_collapsible_newline_(other.is_end_collapsible_newline_),
is_symbol_marker_(other.is_symbol_marker_),
- is_generated_for_line_break_(other.is_generated_for_line_break_) {
+ is_generated_for_line_break_(other.is_generated_for_line_break_),
+ is_first_for_node_(other.is_first_for_node_) {
DCHECK_GE(end, start);
}
@@ -197,6 +200,7 @@ void NGInlineItem::Split(Vector<NGInlineItem>& items,
items.insert(index + 1, items[index]);
items[index].end_offset_ = offset;
items[index + 1].start_offset_ = offset;
+ items[index + 1].is_first_for_node_ = false;
}
} // namespace blink
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 018e02db8d5..5a8575d3a51 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
@@ -66,7 +66,8 @@ class CORE_EXPORT NGInlineItem {
NGInlineItem(NGInlineItemType type,
unsigned start,
unsigned end,
- LayoutObject* layout_object = nullptr);
+ LayoutObject* layout_object,
+ bool is_first_for_node);
~NGInlineItem();
// Copy constructor adjusting start/end and shape results.
@@ -199,6 +200,11 @@ class CORE_EXPORT NGInlineItem {
static void Split(Vector<NGInlineItem>&, unsigned index, unsigned offset);
+ // Return true if this is the first item created for the node. A node may be
+ // split into multiple inline items due e.g. hard line breaks or bidi
+ // segments.
+ bool IsFirstForNode() const { return is_first_for_node_; }
+
// RunSegmenter properties.
unsigned SegmentData() const { return segment_data_; }
static void SetSegmentData(const RunSegmenter::RunSegmenterRange& range,
@@ -253,6 +259,7 @@ class CORE_EXPORT NGInlineItem {
unsigned is_end_collapsible_newline_ : 1;
unsigned is_symbol_marker_ : 1;
unsigned is_generated_for_line_break_ : 1;
+ unsigned is_first_for_node_ : 1;
friend class NGInlineNode;
friend class NGInlineNodeDataEditor;
};
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 801aaf305c2..b6e4388cefb 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
@@ -220,18 +220,7 @@ LayoutUnit NGLineInfo::ComputeWidth() const {
for (const NGInlineItemResult& item_result : Results())
inline_size += item_result.inline_size;
- if (UNLIKELY(line_end_fragment_)) {
- inline_size += line_end_fragment_->Size()
- .ConvertToLogical(LineStyle().GetWritingMode())
- .inline_size;
- }
-
return inline_size;
}
-void NGLineInfo::SetLineEndFragment(
- scoped_refptr<const NGPhysicalTextFragment> fragment) {
- line_end_fragment_ = std::move(fragment);
-}
-
} // namespace blink
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 c55dfae46de..2015830ed2c 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
@@ -7,7 +7,6 @@
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.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_text_end_effect.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h"
#include "third_party/blink/renderer/core/layout/ng/ng_positioned_float.h"
#include "third_party/blink/renderer/platform/fonts/shaping/shape_result.h"
@@ -37,6 +36,15 @@ struct CORE_EXPORT NGInlineItemResult {
return end_offset - start_offset;
}
+ LayoutUnit HyphenInlineSize() const {
+ return hyphen_shape_result->SnappedWidth().ClampNegativeToZero();
+ }
+
+ void ClearHyphen() {
+ hyphen_string = String();
+ hyphen_shape_result = nullptr;
+ }
+
// The NGInlineItem and its index.
const NGInlineItem* item;
unsigned item_index;
@@ -52,6 +60,10 @@ struct CORE_EXPORT NGInlineItemResult {
// is needed in the line breaker.
scoped_refptr<const ShapeResultView> shape_result;
+ // Hyphen character and its |ShapeResult| if this text is hyphenated.
+ String hyphen_string;
+ scoped_refptr<const ShapeResult> hyphen_shape_result;
+
// NGLayoutResult for atomic inline items.
scoped_refptr<const NGLayoutResult> layout_result;
@@ -112,10 +124,6 @@ struct CORE_EXPORT NGInlineItemResult {
// position) any unpositioned floats.
bool has_unpositioned_floats = false;
- // End effects for text items.
- // The effects are included in |shape_result|, but not in text content.
- NGTextEndEffect text_end_effect = NGTextEndEffect::kNone;
-
NGInlineItemResult();
NGInlineItemResult(const NGInlineItem*,
unsigned index,
@@ -139,7 +147,7 @@ using NGInlineItemResults = Vector<NGInlineItemResult, 32>;
//
// NGLineBreaker produces, and NGInlineLayoutAlgorithm consumes.
class CORE_EXPORT NGLineInfo {
- DISALLOW_NEW();
+ STACK_ALLOCATED();
public:
const NGInlineItemsData& ItemsData() const {
@@ -208,7 +216,7 @@ class CORE_EXPORT NGLineInfo {
// True if this line has overflow, excluding preserved trailing spaces.
bool HasOverflow() const { return has_overflow_; }
- void SetHasOverflow() { has_overflow_ = true; }
+ void SetHasOverflow(bool value = true) { has_overflow_ = value; }
void SetBfcOffset(const NGBfcOffset& bfc_offset) { bfc_offset_ = bfc_offset; }
void SetWidth(LayoutUnit available_width, LayoutUnit width) {
@@ -242,12 +250,6 @@ class CORE_EXPORT NGLineInfo {
// justify alignment.
bool NeedsAccurateEndPosition() const { return needs_accurate_end_position_; }
- // Fragment to append to the line end. Used by 'text-overflow: ellipsis'.
- scoped_refptr<const NGPhysicalTextFragment>& LineEndFragment() {
- return line_end_fragment_;
- }
- void SetLineEndFragment(scoped_refptr<const NGPhysicalTextFragment>);
-
private:
bool ComputeNeedsAccurateEndPosition() const;
@@ -258,7 +260,6 @@ class CORE_EXPORT NGLineInfo {
const NGInlineItemsData* items_data_ = nullptr;
const ComputedStyle* line_style_ = nullptr;
NGInlineItemResults results_;
- scoped_refptr<const NGPhysicalTextFragment> line_end_fragment_;
NGBfcOffset bfc_offset_;
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 744cff0d35a..84d422cbc20 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
@@ -128,8 +128,10 @@ void AppendItem(Vector<NGInlineItem>* items,
NGInlineItem::NGInlineItemType type,
unsigned start,
unsigned end,
- LayoutObject* layout_object = nullptr) {
- items->push_back(NGInlineItem(type, start, end, layout_object));
+ LayoutObject* layout_object,
+ bool is_first_for_node = true) {
+ items->push_back(
+ NGInlineItem(type, start, end, layout_object, is_first_for_node));
}
inline bool ShouldIgnore(UChar c) {
@@ -197,8 +199,8 @@ NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::BoxInfo::BoxInfo(
const NGInlineItem& item)
: item_index(item_index),
should_create_box_fragment(item.ShouldCreateBoxFragment()),
- style(*item.Style()),
- text_metrics(NGLineHeightMetrics(style)) {
+ may_have_margin_(item.Style()->MayHaveMargin()),
+ text_metrics(NGLineHeightMetrics(*item.Style())) {
DCHECK(item.Style());
}
@@ -208,7 +210,7 @@ bool NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::BoxInfo::
ShouldCreateBoxFragmentForChild(const BoxInfo& child) const {
// When a child inline box has margins, the parent has different width/height
// from the union of children.
- if (child.style.MayHaveMargin())
+ if (child.may_have_margin_)
return true;
// Returns true when parent and child boxes have different font metrics, since
@@ -231,21 +233,24 @@ void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::BoxInfo::
template <typename OffsetMappingBuilder>
void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendTextItem(
const StringView string,
- LayoutText* layout_object) {
+ LayoutText* layout_object,
+ bool is_first_for_node) {
DCHECK(layout_object);
- AppendTextItem(NGInlineItem::kText, string, layout_object);
+ AppendTextItem(NGInlineItem::kText, string, layout_object, is_first_for_node);
}
template <typename OffsetMappingBuilder>
void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendTextItem(
NGInlineItem::NGInlineItemType type,
const StringView string,
- LayoutText* layout_object) {
+ LayoutText* layout_object,
+ bool is_first_for_node) {
DCHECK(layout_object);
unsigned start_offset = text_.length();
text_.Append(string);
mapping_builder_.AppendIdentityMapping(string.length());
- AppendItem(items_, type, start_offset, text_.length(), layout_object);
+ AppendItem(items_, type, start_offset, text_.length(), layout_object,
+ is_first_for_node);
DCHECK(!items_->back().IsEmptyItem());
// text item is not empty.
is_empty_inline_ = false;
@@ -501,7 +506,8 @@ template <typename OffsetMappingBuilder>
void NGInlineItemsBuilderTemplate<
OffsetMappingBuilder>::AppendCollapseWhitespace(const StringView string,
const ComputedStyle* style,
- LayoutText* layout_object) {
+ LayoutText* layout_object,
+ bool is_first_for_node) {
DCHECK(!string.IsEmpty());
// This algorithm segments the input string at the collapsible space, and
@@ -528,7 +534,7 @@ void NGInlineItemsBuilderTemplate<
// LayoutBR does not set preserve_newline, but should be preserved.
if (UNLIKELY(space_run_has_newline && string.length() == 1 &&
layout_object && layout_object->IsBR())) {
- AppendForcedBreakCollapseWhitespace(layout_object);
+ AppendForcedBreakCollapseWhitespace(layout_object, is_first_for_node);
return;
}
@@ -685,7 +691,7 @@ void NGInlineItemsBuilderTemplate<
}
AppendItem(items_, NGInlineItem::kText, start_offset, text_.length(),
- layout_object);
+ layout_object, is_first_for_node);
NGInlineItem& item = items_->back();
item.SetEndCollapseType(end_collapse, space_run_has_newline);
DCHECK(!item.IsEmptyItem());
@@ -727,7 +733,8 @@ void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::
do {
++end;
} while (end < string.length() && string[end] == kSpaceCharacter);
- AppendTextItem(StringView(string, *start, end - *start), layout_object);
+ AppendTextItem(StringView(string, *start, end - *start), layout_object,
+ /* is_first_for_node */ false);
AppendGeneratedBreakOpportunity(layout_object);
*start = end;
}
@@ -752,11 +759,12 @@ void NGInlineItemsBuilderTemplate<
unsigned start = 0;
InsertBreakOpportunityAfterLeadingPreservedSpaces(string, *style,
layout_object, &start);
- for (; start < string.length();) {
+ bool is_first_for_node = true;
+ for (; start < string.length(); is_first_for_node = false) {
UChar c = string[start];
if (IsControlItemCharacter(c)) {
if (c == kNewlineCharacter) {
- AppendForcedBreak(layout_object);
+ AppendForcedBreak(layout_object, is_first_for_node);
start++;
// A forced break is not a collapsible space, but following collapsible
// spaces are leading spaces and they need a special code in the line
@@ -771,13 +779,14 @@ void NGInlineItemsBuilderTemplate<
if (end == kNotFound)
end = string.length();
AppendTextItem(NGInlineItem::kControl,
- StringView(string, start, end - start), layout_object);
+ StringView(string, start, end - start), layout_object,
+ is_first_for_node);
start = end;
continue;
}
// ZWNJ splits item, but it should be text.
if (c != kZeroWidthNonJoinerCharacter) {
- Append(NGInlineItem::kControl, c, layout_object);
+ Append(NGInlineItem::kControl, c, layout_object, is_first_for_node);
start++;
continue;
}
@@ -786,7 +795,8 @@ void NGInlineItemsBuilderTemplate<
wtf_size_t end = string.Find(IsControlItemCharacter, start + 1);
if (end == kNotFound)
end = string.length();
- AppendTextItem(StringView(string, start, end - start), layout_object);
+ AppendTextItem(StringView(string, start, end - start), layout_object,
+ is_first_for_node);
start = end;
}
}
@@ -796,9 +806,10 @@ void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendPreserveNewline(
const String& string,
const ComputedStyle* style,
LayoutText* layout_object) {
- for (unsigned start = 0; start < string.length();) {
+ bool is_first_for_node = true;
+ for (unsigned start = 0; start < string.length(); is_first_for_node = false) {
if (string[start] == kNewlineCharacter) {
- AppendForcedBreakCollapseWhitespace(layout_object);
+ AppendForcedBreakCollapseWhitespace(layout_object, is_first_for_node);
start++;
continue;
}
@@ -808,14 +819,15 @@ void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendPreserveNewline(
end = string.length();
DCHECK_GE(end, start);
AppendCollapseWhitespace(StringView(string, start, end - start), style,
- layout_object);
+ layout_object, is_first_for_node);
start = end;
}
}
template <typename OffsetMappingBuilder>
void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendForcedBreak(
- LayoutObject* layout_object) {
+ LayoutObject* layout_object,
+ bool is_first_for_node) {
DCHECK(layout_object);
// At the forced break, add bidi controls to pop all contexts.
// https://drafts.csswg.org/css-writing-modes-3/#bidi-embedding-breaks
@@ -829,7 +841,8 @@ void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendForcedBreak(
}
}
- Append(NGInlineItem::kControl, kNewlineCharacter, layout_object);
+ Append(NGInlineItem::kControl, kNewlineCharacter, layout_object,
+ is_first_for_node);
// A forced break is not a collapsible space, but following collapsible spaces
// are leading spaces and that they should be collapsed.
@@ -849,11 +862,12 @@ void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendForcedBreak(
template <typename OffsetMappingBuilder>
void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::
- AppendForcedBreakCollapseWhitespace(LayoutObject* layout_object) {
+ AppendForcedBreakCollapseWhitespace(LayoutObject* layout_object,
+ bool is_first_for_node) {
// Remove collapsible spaces immediately before a preserved newline.
RemoveTrailingCollapsibleSpaceIfExists();
- AppendForcedBreak(layout_object);
+ AppendForcedBreak(layout_object, is_first_for_node);
}
template <typename OffsetMappingBuilder>
@@ -867,13 +881,15 @@ template <typename OffsetMappingBuilder>
void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::Append(
NGInlineItem::NGInlineItemType type,
UChar character,
- LayoutObject* layout_object) {
+ LayoutObject* layout_object,
+ bool is_first_for_node) {
DCHECK_NE(character, kSpaceCharacter);
text_.Append(character);
mapping_builder_.AppendIdentityMapping(1);
unsigned end_offset = text_.length();
- AppendItem(items_, type, end_offset - 1, end_offset, layout_object);
+ AppendItem(items_, type, end_offset - 1, end_offset, layout_object,
+ is_first_for_node);
is_empty_inline_ &= items_->back().IsEmptyItem();
is_block_level_ &= items_->back().IsBlockLevel();
@@ -887,7 +903,7 @@ void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendAtomicInline(
layout_object);
RestoreTrailingCollapsibleSpaceIfRemoved();
Append(NGInlineItem::kAtomicInline, kObjectReplacementCharacter,
- layout_object);
+ layout_object, /* is_first_for_node */ true);
// Mark dirty lines. Clear if marked, only the first dirty line is relevant.
if (dirty_lines_ &&
@@ -1231,6 +1247,27 @@ void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::Exit(
}
template <typename OffsetMappingBuilder>
+bool NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::MayBeBidiEnabled()
+ const {
+ return !text_.Is8Bit() || HasBidiControls();
+}
+
+template <typename OffsetMappingBuilder>
+void NGInlineItemsBuilderTemplate<
+ OffsetMappingBuilder>::DidFinishCollectInlines(NGInlineNodeData* data) {
+ data->text_content = ToString();
+
+ // Set |is_bidi_enabled_| for all UTF-16 strings for now, because at this
+ // point the string may or may not contain RTL characters.
+ // |SegmentText()| will analyze the text and reset |is_bidi_enabled_| if it
+ // doesn't contain any RTL characters.
+ data->is_bidi_enabled_ = MayBeBidiEnabled();
+ data->is_empty_inline_ = IsEmptyInline();
+ data->is_block_level_ = IsBlockLevel();
+ data->changes_may_affect_earlier_lines_ = ChangesMayAffectEarlierLines();
+}
+
+template <typename OffsetMappingBuilder>
void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::SetIsSymbolMarker(
bool b) {
DCHECK(!items_->IsEmpty());
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 8b0939aa096..eb58909de1d 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
@@ -134,6 +134,9 @@ class NGInlineItemsBuilderTemplate {
void EnterInline(LayoutInline*);
void ExitInline(LayoutObject*);
+ // Set collected inline items data to |data|.
+ void DidFinishCollectInlines(NGInlineNodeData* data);
+
OffsetMappingBuilder& GetOffsetMappingBuilder() { return mapping_builder_; }
void SetIsSymbolMarker(bool b);
@@ -160,9 +163,11 @@ class NGInlineItemsBuilderTemplate {
// Keep track of inline boxes to compute ShouldCreateBoxFragment.
struct BoxInfo {
+ DISALLOW_NEW();
+
unsigned item_index;
bool should_create_box_fragment;
- const ComputedStyle& style;
+ bool may_have_margin_;
NGLineHeightMetrics text_metrics;
BoxInfo(unsigned item_index, const NGInlineItem& item);
@@ -191,18 +196,21 @@ class NGInlineItemsBuilderTemplate {
// LayoutObject.
void Append(NGInlineItem::NGInlineItemType,
UChar,
- LayoutObject*);
+ LayoutObject*,
+ bool is_first_for_node);
void AppendCollapseWhitespace(const StringView,
const ComputedStyle*,
- LayoutText*);
+ LayoutText*,
+ bool is_first_for_node = true);
void AppendPreserveWhitespace(const String&,
const ComputedStyle*,
LayoutText*);
void AppendPreserveNewline(const String&, const ComputedStyle*, LayoutText*);
- void AppendForcedBreakCollapseWhitespace(LayoutObject*);
- void AppendForcedBreak(LayoutObject*);
+ void AppendForcedBreakCollapseWhitespace(LayoutObject*,
+ bool is_first_for_node);
+ void AppendForcedBreak(LayoutObject*, bool is_first_for_node);
void RemoveTrailingCollapsibleSpaceIfExists();
void RemoveTrailingCollapsibleSpace(NGInlineItem*);
@@ -211,16 +219,20 @@ class NGInlineItemsBuilderTemplate {
void RestoreTrailingCollapsibleSpace(NGInlineItem*);
void AppendTextItem(const StringView,
- LayoutText* layout_object);
+ LayoutText* layout_object,
+ bool is_first_for_node);
void AppendTextItem(NGInlineItem::NGInlineItemType type,
const StringView,
- LayoutText* layout_object);
+ LayoutText* layout_object,
+ bool is_first_for_node);
void AppendEmptyTextItem(LayoutText* layout_object);
void AppendGeneratedBreakOpportunity(LayoutObject*);
void Exit(LayoutObject*);
+ bool MayBeBidiEnabled() const;
+
bool ShouldInsertBreakOpportunityAfterLeadingPreservedSpaces(
const String&,
const ComputedStyle&,
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 df95d2fd3f6..77aff76eecc 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
@@ -28,7 +28,6 @@ class NGInlineItemsBuilderTest : public NGLayoutTest {
void SetUp() override {
NGLayoutTest::SetUp();
style_ = ComputedStyle::Create();
- style_->GetFont().Update(nullptr);
}
void TearDown() override {
@@ -448,11 +447,12 @@ TEST_F(NGInlineItemsBuilderTest, BidiBlockOverride) {
builder.ToString());
}
-static std::unique_ptr<LayoutInline> CreateLayoutInline(
+static LayoutInline* CreateLayoutInline(
+ Document* document,
void (*initialize_style)(ComputedStyle*)) {
scoped_refptr<ComputedStyle> style(ComputedStyle::Create());
initialize_style(style.get());
- std::unique_ptr<LayoutInline> node = std::make_unique<LayoutInline>(nullptr);
+ LayoutInline* const node = LayoutInline::CreateAnonymous(document);
node->SetModifiedStyleOutsideStyleRecalc(
std::move(style), LayoutObject::ApplyStyleChanges::kNo);
node->SetIsInLayoutNGInlineFormattingContext(true);
@@ -463,14 +463,14 @@ TEST_F(NGInlineItemsBuilderTest, BidiIsolate) {
Vector<NGInlineItem> items;
NGInlineItemsBuilder builder(&items);
AppendText("Hello ", &builder);
- std::unique_ptr<LayoutInline> isolate_rtl(
- CreateLayoutInline([](ComputedStyle* style) {
+ LayoutInline* const isolate_rtl =
+ CreateLayoutInline(&GetDocument(), [](ComputedStyle* style) {
style->SetUnicodeBidi(UnicodeBidi::kIsolate);
style->SetDirection(TextDirection::kRtl);
- }));
- builder.EnterInline(isolate_rtl.get());
+ });
+ builder.EnterInline(isolate_rtl);
AppendText(u"\u05E2\u05D1\u05E8\u05D9\u05EA", &builder);
- builder.ExitInline(isolate_rtl.get());
+ builder.ExitInline(isolate_rtl);
AppendText(" World", &builder);
// Expected control characters as defined in:
@@ -481,20 +481,21 @@ TEST_F(NGInlineItemsBuilderTest, BidiIsolate) {
u"\u2069"
u" World"),
builder.ToString());
+ isolate_rtl->Destroy();
}
TEST_F(NGInlineItemsBuilderTest, BidiIsolateOverride) {
Vector<NGInlineItem> items;
NGInlineItemsBuilder builder(&items);
AppendText("Hello ", &builder);
- std::unique_ptr<LayoutInline> isolate_override_rtl(
- CreateLayoutInline([](ComputedStyle* style) {
+ LayoutInline* const isolate_override_rtl =
+ CreateLayoutInline(&GetDocument(), [](ComputedStyle* style) {
style->SetUnicodeBidi(UnicodeBidi::kIsolateOverride);
style->SetDirection(TextDirection::kRtl);
- }));
- builder.EnterInline(isolate_override_rtl.get());
+ });
+ builder.EnterInline(isolate_override_rtl);
AppendText(u"\u05E2\u05D1\u05E8\u05D9\u05EA", &builder);
- builder.ExitInline(isolate_override_rtl.get());
+ builder.ExitInline(isolate_override_rtl);
AppendText(" World", &builder);
// Expected control characters as defined in:
@@ -505,6 +506,7 @@ TEST_F(NGInlineItemsBuilderTest, BidiIsolateOverride) {
u"\u202C\u2069"
u" World"),
builder.ToString());
+ isolate_override_rtl->Destroy();
}
} // 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 732b84c0ba2..76a67f7e9eb 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
@@ -6,8 +6,9 @@
#include <memory>
+#include "base/compiler_specific.h"
#include "base/containers/adapters.h"
-#include "third_party/blink/renderer/core/layout/ng/inline/ng_baseline.h"
+#include "third_party/blink/renderer/core/html/forms/html_input_element.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_box_state.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h"
@@ -19,12 +20,13 @@
#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_text_fragment_builder.h"
-#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker.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"
#include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h"
#include "third_party/blink/renderer/core/layout/ng/ng_box_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h"
#include "third_party/blink/renderer/core/layout/ng/ng_floats_utils.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.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/layout/ng/ng_positioned_float.h"
@@ -65,7 +67,9 @@ NGInlineLayoutAlgorithm::NGInlineLayoutAlgorithm(
context_(context),
baseline_type_(container_builder_.Style().GetFontBaseline()),
is_horizontal_writing_mode_(
- blink::IsHorizontalWritingMode(space.GetWritingMode())) {
+ blink::IsHorizontalWritingMode(space.GetWritingMode())),
+ truncate_type_(
+ static_cast<unsigned>(TruncateTypeFromConstraintSpace(space))) {
DCHECK(context);
quirks_mode_ = inline_node.InLineHeightQuirksMode();
}
@@ -77,8 +81,10 @@ NGInlineLayoutAlgorithm::~NGInlineLayoutAlgorithm() = default;
NGInlineBoxState* NGInlineLayoutAlgorithm::HandleOpenTag(
const NGInlineItem& item,
const NGInlineItemResult& item_result,
+ NGLineBoxFragmentBuilder::ChildList* line_box,
NGInlineLayoutStateStack* box_states) const {
- NGInlineBoxState* box = box_states->OnOpenTag(item, item_result, line_box_);
+ NGInlineBoxState* box =
+ box_states->OnOpenTag(item, item_result, baseline_type_, line_box);
// Compute text metrics for all inline boxes since even empty inlines
// influence the line height, except when quirks mode and the box is empty
// for the purpose of empty block calculation.
@@ -103,10 +109,14 @@ NGInlineBoxState* NGInlineLayoutAlgorithm::HandleCloseTag(
box->EnsureTextMetrics(*item.Style(), baseline_type_);
box = box_states_->OnCloseTag(&line_box_, box, baseline_type_,
item.HasEndEdge());
- // Just clear |NeedsLayout| flags. Culled inline boxes do not need paint
- // invalidations. If this object produces box fragments,
- // |NGInlineBoxStateStack| takes care of invalidations.
- item.GetLayoutObject()->ClearNeedsLayoutWithoutPaintInvalidation();
+ if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ // Just clear |NeedsLayout| flags. Culled inline boxes do not need paint
+ // invalidations. If this object produces box fragments,
+ // |NGInlineBoxStateStack| takes care of invalidations.
+ item.GetLayoutObject()->ClearNeedsLayoutWithoutPaintInvalidation();
+ } else {
+ item.GetLayoutObject()->ClearNeedsLayout();
+ }
return box;
}
@@ -160,12 +170,13 @@ void NGInlineLayoutAlgorithm::RebuildBoxStates(
}
// Create box states for tags that are not closed yet.
+ NGLineBoxFragmentBuilder::ChildList line_box;
box_states->OnBeginPlaceItems(line_info.LineStyle(), baseline_type_,
- quirks_mode_);
+ quirks_mode_, &line_box);
for (const NGInlineItem* item : open_items) {
NGInlineItemResult item_result;
NGLineBreaker::ComputeOpenTagResult(*item, ConstraintSpace(), &item_result);
- HandleOpenTag(*item, item_result, box_states);
+ HandleOpenTag(*item, item_result, &line_box, box_states);
}
}
@@ -175,9 +186,9 @@ void NGInlineLayoutAlgorithm::CheckBoxStates(
const NGInlineBreakToken* break_token) const {
NGInlineLayoutStateStack rebuilt;
RebuildBoxStates(line_info, break_token, &rebuilt);
- rebuilt.OnBeginPlaceItems(line_info.LineStyle(), baseline_type_,
- quirks_mode_);
-
+ NGLineBoxFragmentBuilder::ChildList line_box;
+ rebuilt.OnBeginPlaceItems(line_info.LineStyle(), baseline_type_, quirks_mode_,
+ &line_box);
DCHECK(box_states_);
box_states_->CheckSame(rebuilt);
}
@@ -201,8 +212,8 @@ void NGInlineLayoutAlgorithm::CreateLine(
// The baseline is adjusted after the height of the line box is computed.
const ComputedStyle& line_style = line_info->LineStyle();
box_states_->SetIsEmptyLine(line_info->IsEmptyLine());
- NGInlineBoxState* box =
- box_states_->OnBeginPlaceItems(line_style, baseline_type_, quirks_mode_);
+ NGInlineBoxState* box = box_states_->OnBeginPlaceItems(
+ line_style, baseline_type_, quirks_mode_, &line_box_);
#if DCHECK_IS_ON()
if (is_box_states_from_context_)
CheckBoxStates(*line_info, BreakToken());
@@ -227,6 +238,8 @@ void NGInlineLayoutAlgorithm::CreateLine(
item.GetLayoutObject()->IsLayoutNGListItem());
DCHECK(item_result.shape_result);
+ text_builder.SetIsFirstForNode(IsFirstForNode(item, BreakToken()));
+
if (UNLIKELY(quirks_mode_))
box->EnsureTextMetrics(*item.Style(), baseline_type_);
@@ -236,7 +249,7 @@ void NGInlineLayoutAlgorithm::CreateLine(
baseline_type_);
}
- if (item.IsSymbolMarker()) {
+ if (UNLIKELY(item.IsSymbolMarker())) {
text_builder.SetItem(NGPhysicalTextFragment::kSymbolMarker,
line_info->ItemsData(), &item_result,
box->text_height);
@@ -245,14 +258,23 @@ void NGInlineLayoutAlgorithm::CreateLine(
line_info->ItemsData(), &item_result,
box->text_height);
}
- line_box_.AddChild(text_builder.ToTextFragment(), box->text_top,
- item_result.inline_size, item.BidiLevel());
+ if (UNLIKELY(item_result.hyphen_shape_result)) {
+ LayoutUnit hyphen_inline_size = item_result.HyphenInlineSize();
+ line_box_.AddChild(text_builder.ToTextFragment(), box->text_top,
+ item_result.inline_size - hyphen_inline_size,
+ item.BidiLevel());
+ PlaceHyphen(item_result, hyphen_inline_size, box);
+ } else {
+ line_box_.AddChild(text_builder.ToTextFragment(), box->text_top,
+ item_result.inline_size, item.BidiLevel());
+ }
// Text boxes always need full paint invalidations.
item.GetLayoutObject()->ClearNeedsLayoutWithFullPaintInvalidation();
+
} else if (item.Type() == NGInlineItem::kControl) {
PlaceControlItem(item, *line_info, &item_result, box);
} else if (item.Type() == NGInlineItem::kOpenTag) {
- box = HandleOpenTag(item, item_result, box_states_);
+ box = HandleOpenTag(item, item_result, &line_box_, box_states_);
} else if (item.Type() == NGInlineItem::kCloseTag) {
box = HandleCloseTag(item, item_result, box);
} else if (item.Type() == NGInlineItem::kAtomicInline) {
@@ -284,13 +306,6 @@ void NGInlineLayoutAlgorithm::CreateLine(
}
}
- if (line_info->LineEndFragment()) {
- // Add a generated text fragment, hyphen or ellipsis, at the logical end.
- // By using the paragraph bidi_level, it will appear at the visual end.
- PlaceGeneratedContent(std::move(line_info->LineEndFragment()),
- IsLtr(line_info->BaseDirection()) ? 0 : 1, box);
- }
-
box_states_->OnEndPlaceItems(&line_box_, baseline_type_);
if (UNLIKELY(Node().IsBidiEnabled())) {
@@ -308,11 +323,21 @@ void NGInlineLayoutAlgorithm::CreateLine(
}
}
- // Truncate the line if 'text-overflow: ellipsis' is set.
- if (UNLIKELY(inline_size > line_info->AvailableWidth() &&
- node_.GetLayoutBlockFlow()->ShouldTruncateOverflowingText())) {
- inline_size = NGLineTruncator(*line_info)
- .TruncateLine(inline_size, &line_box_, box_states_);
+ // Truncate the line if 'text-overflow: ellipsis' is set, or for line-clamp.
+ if (UNLIKELY((inline_size >
+ line_info->AvailableWidth() - line_info->TextIndent() &&
+ node_.GetLayoutBlockFlow()->ShouldTruncateOverflowingText()) ||
+ ShouldTruncateForLineClamp(*line_info))) {
+ NGLineTruncator truncator(*line_info);
+ auto* input =
+ DynamicTo<HTMLInputElement>(node_.GetLayoutBlockFlow()->GetNode());
+ if (input && input->ShouldApplyMiddleEllipsis()) {
+ inline_size = truncator.TruncateLineInTheMiddle(inline_size, &line_box_,
+ box_states_);
+ } else {
+ inline_size =
+ truncator.TruncateLine(inline_size, &line_box_, box_states_);
+ }
}
// Negative margins can make the position negative, but the inline size is
@@ -421,36 +446,28 @@ void NGInlineLayoutAlgorithm::PlaceControlItem(const NGInlineItem& item,
NGTextFragmentBuilder text_builder(ConstraintSpace().GetWritingMode());
text_builder.SetItem(type, line_info.ItemsData(), item_result,
box->text_height);
+ text_builder.SetIsFirstForNode(IsFirstForNode(item, BreakToken()));
line_box_.AddChild(text_builder.ToTextFragment(), box->text_top,
item_result->inline_size, item.BidiLevel());
}
-// Place a generated content that does not exist in DOM nor in LayoutObject
-// tree.
-void NGInlineLayoutAlgorithm::PlaceGeneratedContent(
- scoped_refptr<const NGPhysicalTextFragment> fragment,
- UBiDiLevel bidi_level,
- NGInlineBoxState* box) {
- LayoutUnit inline_size = IsHorizontalWritingMode() ? fragment->Size().width
- : fragment->Size().height;
- const ComputedStyle& style = fragment->Style();
- if (box->CanAddTextOfStyle(style)) {
- if (UNLIKELY(quirks_mode_))
- box->EnsureTextMetrics(style, baseline_type_);
- DCHECK(!box->text_metrics.IsEmpty());
- line_box_.AddChild(std::move(fragment), box->text_top, inline_size,
- bidi_level);
- } else {
- scoped_refptr<ComputedStyle> text_style =
- ComputedStyle::CreateAnonymousStyleWithDisplay(style,
- EDisplay::kInline);
- NGInlineBoxState* box = box_states_->OnOpenTag(*text_style, line_box_);
- box->ComputeTextMetrics(*text_style, baseline_type_);
- DCHECK(!box->text_metrics.IsEmpty());
- line_box_.AddChild(std::move(fragment), box->text_top, inline_size,
- bidi_level);
- box_states_->OnCloseTag(&line_box_, box, baseline_type_);
- }
+void NGInlineLayoutAlgorithm::PlaceHyphen(const NGInlineItemResult& item_result,
+ LayoutUnit hyphen_inline_size,
+ NGInlineBoxState* box) {
+ DCHECK(item_result.item);
+ DCHECK(item_result.hyphen_string);
+ 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());
}
NGInlineBoxState* NGInlineLayoutAlgorithm::PlaceAtomicInline(
@@ -465,7 +482,8 @@ NGInlineBoxState* NGInlineLayoutAlgorithm::PlaceAtomicInline(
// position += item_result->margins.LineLeft(style.Direction());
item_result->has_edge = true;
- NGInlineBoxState* box = box_states_->OnOpenTag(item, *item_result, line_box_);
+ NGInlineBoxState* box =
+ box_states_->OnOpenTag(item, *item_result, baseline_type_, line_box_);
PlaceLayoutResult(item_result, box, box->margin_inline_start);
return box_states_->OnCloseTag(&line_box_, box, baseline_type_);
}
@@ -478,20 +496,20 @@ void NGInlineLayoutAlgorithm::PlaceLayoutResult(NGInlineItemResult* item_result,
DCHECK(item_result->item);
const NGInlineItem& item = *item_result->item;
DCHECK(item.Style());
- NGBoxFragment fragment(ConstraintSpace().GetWritingMode(),
- ConstraintSpace().Direction(),
- To<NGPhysicalBoxFragment>(
- item_result->layout_result->PhysicalFragment()));
- NGLineHeightMetrics metrics = fragment.BaselineMetrics(
- {NGBaselineAlgorithmType::kAtomicInline, baseline_type_},
- ConstraintSpace());
+ NGLineHeightMetrics metrics =
+ NGBoxFragment(ConstraintSpace().GetWritingMode(),
+ ConstraintSpace().Direction(),
+ To<NGPhysicalBoxFragment>(
+ item_result->layout_result->PhysicalFragment()))
+ .BaselineMetrics(item_result->margins, baseline_type_);
if (box)
box->metrics.Unite(metrics);
LayoutUnit line_top = item_result->margins.line_over - metrics.ascent;
line_box_.AddChild(std::move(item_result->layout_result),
LogicalOffset{inline_offset, line_top},
- item_result->inline_size, item.BidiLevel());
+ item_result->inline_size, /* children_count */ 0,
+ item.BidiLevel());
}
// Place all out-of-flow objects in |line_box_|.
@@ -548,7 +566,7 @@ void NGInlineLayoutAlgorithm::PlaceOutOfFlowObjects(
if (box->StyleRef().IsOriginalDisplayInlineType()) {
// An inline-level OOF element positions itself within the line, at the
// position it would have been if it was in-flow.
- static_offset.inline_offset = child.offset.inline_offset;
+ static_offset.inline_offset = child.rect.offset.inline_offset;
// The static-position of inline-level OOF-positioned nodes depends on
// previous floats (if any).
@@ -572,7 +590,7 @@ void NGInlineLayoutAlgorithm::PlaceOutOfFlowObjects(
}
}
- child.offset = static_offset;
+ child.rect.offset = static_offset;
}
if (UNLIKELY(has_rtl_block_level_out_of_flow_objects)) {
@@ -585,7 +603,7 @@ void NGInlineLayoutAlgorithm::PlaceOutOfFlowObjects(
}
if (has_preceding_inline_level_content &&
!box->StyleRef().IsOriginalDisplayInlineType()) {
- child.offset.block_offset += line_height;
+ child.rect.offset.block_offset += line_height;
}
}
}
@@ -646,8 +664,8 @@ void NGInlineLayoutAlgorithm::PlaceFloatingObjects(
block_offset = -fragment.BlockSize() - block_offset;
}
- child.offset = {child.bfc_offset.line_offset - bfc_line_offset,
- block_offset};
+ child.rect.offset = {child.bfc_offset.line_offset - bfc_line_offset,
+ block_offset};
}
}
@@ -660,8 +678,8 @@ void NGInlineLayoutAlgorithm::PlaceListMarker(const NGInlineItem& item,
baseline_type_);
}
- container_builder_.SetUnpositionedListMarker(
- NGUnpositionedListMarker(ToLayoutNGListMarker(item.GetLayoutObject())));
+ container_builder_.SetUnpositionedListMarker(NGUnpositionedListMarker(
+ ToLayoutNGOutsideListMarker(item.GetLayoutObject())));
}
// Justify the line. This changes the size of items by adding spacing.
@@ -694,8 +712,8 @@ bool NGInlineLayoutAlgorithm::ApplyJustify(LayoutUnit space,
// matches to the |ShapeResult|.
DCHECK(!line_info->Results().IsEmpty());
const NGInlineItemResult& last_item_result = line_info->Results().back();
- if (last_item_result.text_end_effect == NGTextEndEffect::kHyphen)
- line_text_builder.Append(last_item_result.item->Style()->HyphenString());
+ if (last_item_result.hyphen_string)
+ line_text_builder.Append(last_item_result.hyphen_string);
// Compute the spacing to justify.
String line_text = line_text_builder.ToString();
@@ -714,14 +732,14 @@ bool NGInlineLayoutAlgorithm::ApplyJustify(LayoutUnit space,
scoped_refptr<ShapeResult> shape_result =
item_result.shape_result->CreateShapeResult();
DCHECK_GE(item_result.start_offset, line_info->StartOffset());
- // |shape_result| has more characters if it's hyphenated.
- DCHECK(item_result.text_end_effect != NGTextEndEffect::kNone ||
- shape_result->NumCharacters() ==
- item_result.end_offset - item_result.start_offset);
+ DCHECK_EQ(shape_result->NumCharacters(),
+ item_result.end_offset - item_result.start_offset);
shape_result->ApplySpacing(spacing, item_result.start_offset -
line_info->StartOffset() -
shape_result->StartIndex());
item_result.inline_size = shape_result->SnappedWidth();
+ if (UNLIKELY(item_result.hyphen_shape_result))
+ item_result.inline_size += item_result.HyphenInlineSize();
item_result.shape_result = ShapeResultView::Create(shape_result.get());
} else if (item_result.item->Type() == NGInlineItem::kAtomicInline) {
float offset = 0.f;
@@ -823,7 +841,7 @@ scoped_refptr<const NGLayoutResult> NGInlineLayoutAlgorithm::Layout() {
// In order to get the correct list of layout opportunities, we need to
// position any "leading" floats within the exclusion space first.
- NGPositionedFloatVector leading_floats;
+ STACK_UNINITIALIZED NGPositionedFloatVector leading_floats;
unsigned handled_leading_floats_index =
PositionLeadingFloats(&initial_exclusion_space, &leading_floats);
@@ -832,7 +850,7 @@ scoped_refptr<const NGLayoutResult> NGInlineLayoutAlgorithm::Layout() {
// We query all the layout opportunities on the initial exclusion space up
// front, as if the line breaker may add floats and change the opportunities.
- const LayoutOpportunityVector opportunities =
+ const LayoutOpportunityVector& opportunities =
initial_exclusion_space.AllLayoutOpportunities(
{ConstraintSpace().BfcOffset().line_offset,
is_empty_inline ? ConstraintSpace().ExpectedBfcBlockOffset()
@@ -876,7 +894,7 @@ scoped_refptr<const NGLayoutResult> NGInlineLayoutAlgorithm::Layout() {
opportunity.ComputeLineLayoutOpportunity(ConstraintSpace(),
line_block_size, block_delta);
- NGLineInfo line_info;
+ STACK_UNINITIALIZED NGLineInfo line_info;
NGLineBreaker line_breaker(Node(), NGLineBreakerMode::kContent,
ConstraintSpace(), line_opportunity,
leading_floats, handled_leading_floats_index,
@@ -1092,22 +1110,9 @@ void NGInlineLayoutAlgorithm::BidiReorder(TextDirection base_direction) {
// For opaque items, copy bidi levels from adjacent items.
if (has_opaque_items) {
- UBiDiLevel last_level = levels.front();
- if (last_level == kOpaqueBidiLevel) {
- for (const UBiDiLevel level : levels) {
- if (level != kOpaqueBidiLevel) {
- last_level = level;
- break;
- }
- }
- }
- // If all items are opaque, use the base direction.
- if (last_level == kOpaqueBidiLevel) {
- if (IsLtr(base_direction))
- return;
- last_level = 1;
- }
- for (UBiDiLevel& level : levels) {
+ // Use the paragraph level for trailing opaque items.
+ UBiDiLevel last_level = IsLtr(base_direction) ? 0 : 1;
+ for (UBiDiLevel& level : base::Reversed(levels)) {
if (level == kOpaqueBidiLevel)
level = last_level;
else
@@ -1130,4 +1135,22 @@ void NGInlineLayoutAlgorithm::BidiReorder(TextDirection base_direction) {
line_box_ = std::move(visual_items);
}
+// static
+NGInlineLayoutAlgorithm::TruncateType
+NGInlineLayoutAlgorithm::TruncateTypeFromConstraintSpace(
+ const NGConstraintSpace& space) {
+ if (space.LinesUntilClamp() != 1)
+ return TruncateType::kDefault;
+ return space.ForceTruncateAtLineClamp() ? TruncateType::kAlways
+ : TruncateType::kIfNotLastLine;
+}
+
+bool NGInlineLayoutAlgorithm::ShouldTruncateForLineClamp(
+ const NGLineInfo& line_info) const {
+ const TruncateType truncate_type = static_cast<TruncateType>(truncate_type_);
+ return truncate_type == TruncateType::kAlways ||
+ (truncate_type == TruncateType::kIfNotLastLine &&
+ !line_info.IsLastLine());
+}
+
} // namespace blink
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 6fe33fe9220..604eefb4041 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
@@ -52,6 +52,19 @@ class CORE_EXPORT NGInlineLayoutAlgorithm final
scoped_refptr<const NGLayoutResult> Layout() override;
private:
+ enum class TruncateType {
+ // Indicates default behavior. The default truncates if the text doesn't
+ // fit and ShouldTruncateOverflowingText() returns true.
+ kDefault,
+
+ // Truncate if NGLineInfo has more lines.
+ kIfNotLastLine,
+
+ // Forces truncation. This is used when line-clamp is set and there are
+ // blocks after this.
+ kAlways,
+ };
+
unsigned PositionLeadingFloats(NGExclusionSpace*, NGPositionedFloatVector*);
NGPositionedFloat PositionFloat(LayoutUnit origin_block_bfc_offset,
LayoutObject* floating_object,
@@ -69,6 +82,7 @@ class CORE_EXPORT NGInlineLayoutAlgorithm final
NGInlineBoxState* HandleOpenTag(const NGInlineItem&,
const NGInlineItemResult&,
+ NGLineBoxFragmentBuilder::ChildList*,
NGInlineLayoutStateStack*) const;
NGInlineBoxState* HandleCloseTag(const NGInlineItem&,
const NGInlineItemResult&,
@@ -80,9 +94,9 @@ class CORE_EXPORT NGInlineLayoutAlgorithm final
const NGLineInfo&,
NGInlineItemResult*,
NGInlineBoxState*);
- void PlaceGeneratedContent(scoped_refptr<const NGPhysicalTextFragment>,
- UBiDiLevel,
- NGInlineBoxState*);
+ void PlaceHyphen(const NGInlineItemResult&,
+ LayoutUnit hyphen_inline_size,
+ NGInlineBoxState*);
NGInlineBoxState* PlaceAtomicInline(const NGInlineItem&,
const NGLineInfo&,
NGInlineItemResult*);
@@ -105,6 +119,13 @@ class CORE_EXPORT NGInlineLayoutAlgorithm final
const NGExclusionSpace&,
LayoutUnit line_height);
+ static TruncateType TruncateTypeFromConstraintSpace(
+ const NGConstraintSpace& space);
+
+ // Returns true if truncuation should happen as a result of line-clamp for
+ // |line_info|.
+ bool ShouldTruncateForLineClamp(const NGLineInfo& line_info) const;
+
NGLineBoxFragmentBuilder::ChildList line_box_;
NGInlineLayoutStateStack* box_states_;
NGInlineChildLayoutContext* context_;
@@ -113,6 +134,7 @@ class CORE_EXPORT NGInlineLayoutAlgorithm final
unsigned is_horizontal_writing_mode_ : 1;
unsigned quirks_mode_ : 1;
+ unsigned truncate_type_ : 2;
#if DCHECK_IS_ON()
// True if |box_states_| is taken from |context_|, to check the |box_states_|
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 3c1aa36a1bc..fbb4e323541 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
@@ -9,9 +9,11 @@
#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_break_token.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.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/inline/ng_physical_line_box_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.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_result.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
@@ -50,6 +52,14 @@ 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(&container_builder);
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ container_builder.SetItemsBuilder(&items_builder);
+ context.SetItemsBuilder(&items_builder);
+ }
scoped_refptr<const NGLayoutResult> layout_result =
inline_node.Layout(constraint_space, nullptr, &context);
const auto& line1 = layout_result->PhysicalFragment();
@@ -68,95 +78,6 @@ TEST_F(NGInlineLayoutAlgorithmTest, BreakToken) {
EXPECT_TRUE(line3.BreakToken()->IsFinished());
}
-TEST_F(NGInlineLayoutAlgorithmTest, GenerateHyphen) {
- LoadAhem();
- SetBodyInnerHTML(R"HTML(
- <!DOCTYPE html>
- <style>
- html, body { margin: 0; }
- #container {
- font: 10px/1 Ahem;
- width: 5ch;
- }
- </style>
- <div id=container>abc&shy;def</div>
- )HTML");
- scoped_refptr<const NGPhysicalBoxFragment> block =
- GetBoxFragmentByElementId("container");
- EXPECT_EQ(2u, block->Children().size());
- const NGPhysicalLineBoxFragment& line1 =
- To<NGPhysicalLineBoxFragment>(*block->Children()[0].get());
-
- // The hyphen is in its own NGPhysicalTextFragment.
- EXPECT_EQ(2u, line1.Children().size());
- EXPECT_EQ(NGPhysicalFragment::kFragmentText, line1.Children()[1]->Type());
- const auto& hyphen = To<NGPhysicalTextFragment>(*line1.Children()[1].get());
- EXPECT_EQ(String(u"\u2010"), hyphen.Text().ToString());
- // It should have the same LayoutObject as the hyphened word.
- EXPECT_EQ(line1.Children()[0]->GetLayoutObject(), hyphen.GetLayoutObject());
-}
-
-TEST_F(NGInlineLayoutAlgorithmTest, GenerateEllipsis) {
- LoadAhem();
- SetBodyInnerHTML(R"HTML(
- <!DOCTYPE html>
- <style>
- html, body { margin: 0; }
- #container {
- font: 10px/1 Ahem;
- width: 5ch;
- overflow: hidden;
- text-overflow: ellipsis;
- }
- </style>
- <div id=container>123456</div>
- )HTML");
- scoped_refptr<const NGPhysicalBoxFragment> block =
- GetBoxFragmentByElementId("container");
- EXPECT_EQ(1u, block->Children().size());
- const auto& line1 =
- To<NGPhysicalLineBoxFragment>(*block->Children()[0].get());
-
- // The ellipsis is in its own NGPhysicalTextFragment.
- EXPECT_EQ(3u, line1.Children().size());
- const auto& ellipsis = To<NGPhysicalTextFragment>(*line1.Children().back());
- EXPECT_EQ(String(u"\u2026"), ellipsis.Text().ToString());
- // It should have the same LayoutObject as the clipped word.
- EXPECT_EQ(line1.Children()[0]->GetLayoutObject(), ellipsis.GetLayoutObject());
-}
-
-TEST_F(NGInlineLayoutAlgorithmTest, EllipsisInlineBoxOnly) {
- LoadAhem();
- SetBodyInnerHTML(R"HTML(
- <!DOCTYPE html>
- <style>
- html, body { margin: 0; }
- #container {
- font: 10px/1 Ahem;
- width: 5ch;
- overflow: hidden;
- text-overflow: ellipsis;
- }
- span {
- border: solid 10ch blue;
- }
- </style>
- <div id=container><span></span></div>
- )HTML");
- scoped_refptr<const NGPhysicalBoxFragment> block =
- GetBoxFragmentByElementId("container");
- EXPECT_EQ(1u, block->Children().size());
- const auto& line1 =
- To<NGPhysicalLineBoxFragment>(*block->Children()[0].get());
-
- // There should not be ellipsis in this line.
- for (const auto& child : line1.Children()) {
- if (const auto* text = DynamicTo<NGPhysicalTextFragment>(child.get())) {
- EXPECT_FALSE(text->IsEllipsis());
- }
- }
-}
-
// This test ensures box fragments are generated when necessary, even when the
// line is empty. One such case is when the line contains a containing box of an
// out-of-flow object.
@@ -179,7 +100,7 @@ TEST_F(NGInlineLayoutAlgorithmTest,
}
</style>
<div id=container>
- <oof-container>
+ <oof-container id=target>
<oof></oof>
</oof-container>
</div>
@@ -190,15 +111,17 @@ TEST_F(NGInlineLayoutAlgorithmTest,
ASSERT_TRUE(container);
EXPECT_EQ(LayoutUnit(), container->Size().height);
- EXPECT_EQ(2u, container->Children().size());
- const auto& linebox =
- To<NGPhysicalLineBoxFragment>(*container->Children()[0]);
-
- EXPECT_EQ(1u, linebox.Children().size());
- EXPECT_EQ(PhysicalSize(), linebox.Size());
-
- const auto& oof_container = To<NGPhysicalBoxFragment>(*linebox.Children()[0]);
- EXPECT_EQ(PhysicalSize(), oof_container.Size());
+ NGInlineCursor line_box(*block_flow);
+ ASSERT_TRUE(line_box);
+ ASSERT_TRUE(line_box.Current().IsLineBox());
+ EXPECT_EQ(PhysicalSize(), line_box.Current().Size());
+
+ NGInlineCursor off_container(line_box);
+ off_container.MoveToNext();
+ ASSERT_TRUE(off_container);
+ ASSERT_EQ(GetLayoutObjectByElementId("target"),
+ off_container.Current().GetLayoutObject());
+ EXPECT_EQ(PhysicalSize(), off_container.Current().Size());
}
// This test ensures that if an inline box generates (or does not generate) box
@@ -219,21 +142,31 @@ TEST_F(NGInlineLayoutAlgorithmTest, BoxForEndMargin) {
}
</style>
<!-- This line wraps, and only 2nd line has a border. -->
- <div id=container>12 <span>3 45</span> 6</div>
+ <div id=container>12 <span id=span>3 45</span> 6</div>
)HTML");
auto* block_flow =
To<LayoutBlockFlow>(GetLayoutObjectByElementId("container"));
- const NGPhysicalBoxFragment* block_box = block_flow->CurrentFragment();
- ASSERT_TRUE(block_box);
- EXPECT_EQ(2u, block_box->Children().size());
- const auto& line_box1 =
- To<NGPhysicalLineBoxFragment>(*block_box->Children()[0].get());
- EXPECT_EQ(2u, line_box1.Children().size());
+ NGInlineCursor line_box(*block_flow);
+ ASSERT_TRUE(line_box) << "line_box is at start of first line.";
+ ASSERT_TRUE(line_box.Current().IsLineBox());
+ line_box.MoveToNextLine();
+ ASSERT_TRUE(line_box) << "line_box is at start of second line.";
+ NGInlineCursor cursor(line_box);
+ ASSERT_TRUE(line_box.Current().IsLineBox());
+ cursor.MoveToNext();
+ ASSERT_TRUE(cursor);
+ EXPECT_EQ(GetLayoutObjectByElementId("span"),
+ cursor.Current().GetLayoutObject());
// The <span> generates a box fragment for the 2nd line because it has a
// right border. It should also generate a box fragment for the 1st line even
// though there's no borders on the 1st line.
- EXPECT_EQ(NGPhysicalFragment::kFragmentBox, line_box1.Children()[1]->Type());
+ const NGPhysicalBoxFragment* box_fragment = cursor.Current().BoxFragment();
+ ASSERT_TRUE(box_fragment);
+ EXPECT_EQ(NGPhysicalFragment::kFragmentBox, box_fragment->Type());
+
+ line_box.MoveToNextLine();
+ ASSERT_FALSE(line_box) << "block_flow has two lines.";
}
// A block with inline children generates fragment tree as follows:
@@ -257,8 +190,8 @@ TEST_F(NGInlineLayoutAlgorithmTest, ContainerBorderPadding) {
auto* block_flow =
To<LayoutBlockFlow>(GetLayoutObjectByElementId("container"));
NGBlockNode block_node(block_flow);
- NGConstraintSpace space = NGConstraintSpace::CreateFromLayoutObject(
- *block_flow, false /* is_layout_root */);
+ NGConstraintSpace space =
+ NGConstraintSpace::CreateFromLayoutObject(*block_flow);
scoped_refptr<const NGLayoutResult> layout_result = block_node.Layout(space);
EXPECT_TRUE(layout_result->BfcBlockOffset().has_value());
@@ -289,17 +222,13 @@ TEST_F(NGInlineLayoutAlgorithmTest, MAYBE_VerticalAlignBottomReplaced) {
)HTML");
auto* block_flow =
To<LayoutBlockFlow>(GetLayoutObjectByElementId("container"));
- NGInlineNode inline_node(block_flow);
- NGInlineChildLayoutContext context;
- NGConstraintSpace space = NGConstraintSpace::CreateFromLayoutObject(
- *block_flow, false /* is_layout_root */);
- scoped_refptr<const NGLayoutResult> layout_result =
- inline_node.Layout(space, nullptr, &context);
-
- const auto& line = layout_result->PhysicalFragment();
- EXPECT_EQ(LayoutUnit(96), line.Size().height);
- PhysicalOffset img_offset = line.Children()[0].Offset();
- EXPECT_EQ(LayoutUnit(0), img_offset.top);
+ NGInlineCursor cursor(*block_flow);
+ ASSERT_TRUE(cursor);
+ EXPECT_EQ(LayoutUnit(96), cursor.Current().Size().height);
+ cursor.MoveToNext();
+ ASSERT_TRUE(cursor);
+ EXPECT_EQ(LayoutUnit(0), cursor.Current().OffsetInContainerBlock().top)
+ << "Offset top of <img> should be zero.";
}
// Verifies that text can flow correctly around floats that were positioned
@@ -393,7 +322,7 @@ TEST_F(NGInlineLayoutAlgorithmTest, TextFloatsAroundInlineFloatThatFitsOnLine) {
ASSERT_TRUE(block_box);
// Two lines.
- EXPECT_EQ(2u, block_box->Children().size());
+ ASSERT_EQ(2u, block_box->Children().size());
PhysicalOffset first_line_offset = block_box->Children()[1].Offset();
// 30 == narrow-float's width.
@@ -521,20 +450,24 @@ TEST_F(NGInlineLayoutAlgorithmTest, InkOverflow) {
auto* block_flow =
To<LayoutBlockFlow>(GetLayoutObjectByElementId("container"));
const NGPaintFragment* paint_fragment = block_flow->PaintFragment();
- ASSERT_TRUE(paint_fragment);
- const NGPhysicalFragment& box_fragment = paint_fragment->PhysicalFragment();
-
+ const NGPhysicalBoxFragment& box_fragment = *block_flow->CurrentFragment();
+ if (paint_fragment)
+ ASSERT_EQ(&paint_fragment->PhysicalFragment(), &box_fragment);
EXPECT_EQ(LayoutUnit(10), box_fragment.Size().height);
- PhysicalRect ink_overflow = paint_fragment->InkOverflow();
+ NGInlineCursor cursor(*block_flow);
+ PhysicalRect ink_overflow = cursor.Current().InkOverflow();
EXPECT_EQ(LayoutUnit(-5), ink_overflow.offset.top);
EXPECT_EQ(LayoutUnit(20), ink_overflow.size.height);
- // |ContentsInkOverflow| should match to |InkOverflow|, except the width
- // because |<div id=container>| might be wider than the content.
- EXPECT_EQ(ink_overflow.offset, paint_fragment->ContentsInkOverflow().offset);
- EXPECT_EQ(ink_overflow.size.height,
- paint_fragment->ContentsInkOverflow().size.height);
+ if (paint_fragment) {
+ // |ContentsInkOverflow| should match to |InkOverflow|, except the width
+ // because |<div id=container>| might be wider than the content.
+ const PhysicalRect contents_ink_overflow =
+ paint_fragment->ContentsInkOverflow();
+ EXPECT_EQ(ink_overflow.offset, contents_ink_overflow.offset);
+ EXPECT_EQ(ink_overflow.size.height, contents_ink_overflow.size.height);
+ }
}
#undef MAYBE_VerticalAlignBottomReplaced
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 6f83ab768f0..740ab5a243f 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
@@ -24,7 +24,6 @@
#include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h"
#include "third_party/blink/renderer/core/layout/ng/legacy_layout_tree_walking.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_list_marker.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_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h"
@@ -285,7 +284,7 @@ void CollectInlinesInternal(LayoutBlockFlow* block,
builder->ClearInlineFragment(node);
} else if (node->IsAtomicInlineLevel()) {
- if (node->IsListMarkerIncludingNG()) {
+ if (node->IsListMarkerIncludingNGOutside()) {
// LayoutNGListItem produces the 'outside' list marker as an inline
// block. This is an out-of-flow item whose position is computed
// automatically.
@@ -427,13 +426,6 @@ void TruncateOrPadText(String* text, unsigned length) {
}
}
-template <typename OffsetMappingBuilder>
-bool MayBeBidiEnabled(
- const String& text_content,
- const NGInlineItemsBuilderTemplate<OffsetMappingBuilder>& builder) {
- return !text_content.Is8Bit() || builder.HasBidiControls();
-}
-
} // namespace
NGInlineNode::NGInlineNode(LayoutBlockFlow* block)
@@ -528,6 +520,11 @@ class NGInlineNodeDataEditor final {
if (layout_text_.StyleRef().TextSecurity() != ETextSecurity::kNone)
return nullptr;
+ // It is hard to figure differences of bidi control codes before/after
+ // editing. See http://crbug.com/1039143
+ if (layout_text_.HasBidiControlInlineItems())
+ return nullptr;
+
// Note: We should compute offset mapping before calling
// |LayoutBlockFlow::TakeNGInlineNodeData()|
const NGOffsetMapping* const offset_mapping =
@@ -756,6 +753,10 @@ bool NGInlineNode::SetTextWithOffset(LayoutText* layout_text,
if (!previous_data)
return false;
+ // This function runs outside of the layout phase. Prevent purging font cache
+ // while shaping.
+ FontCachePurgePreventer fontCachePurgePreventer;
+
String new_text(std::move(new_text_in));
layout_text->StyleRef().ApplyTextTransform(&new_text,
layout_text->PreviousCharacter());
@@ -769,7 +770,7 @@ bool NGInlineNode::SetTextWithOffset(LayoutText* layout_text,
// inline items.
layout_text->ClearInlineItems();
CollectInlinesInternal(node.GetLayoutBlockFlow(), &builder, previous_data);
- data->text_content = builder.ToString();
+ builder.DidFinishCollectInlines(data);
// Relocates |ShapeResult| in |previous_data| after |offset|+|length|
editor.Run();
node.SegmentText(data);
@@ -877,17 +878,7 @@ void NGInlineNode::CollectInlines(NGInlineNodeData* data,
data->items.ReserveCapacity(EstimateInlineItemsCount(*block));
NGInlineItemsBuilder builder(&data->items, dirty_lines);
CollectInlinesInternal(block, &builder, previous_data);
- data->text_content = builder.ToString();
-
- // Set |is_bidi_enabled_| for all UTF-16 strings for now, because at this
- // point the string may or may not contain RTL characters.
- // |SegmentText()| will analyze the text and reset |is_bidi_enabled_| if it
- // doesn't contain any RTL characters.
- data->is_bidi_enabled_ = MayBeBidiEnabled(data->text_content, builder);
- data->is_empty_inline_ = builder.IsEmptyInline();
- data->is_block_level_ = builder.IsBlockLevel();
- data->changes_may_affect_earlier_lines_ =
- builder.ChangesMayAffectEarlierLines();
+ builder.DidFinishCollectInlines(data);
}
void NGInlineNode::SegmentText(NGInlineNodeData* data) {
@@ -1476,7 +1467,7 @@ String NGInlineNode::TextContentForStickyImagesQuirk(
static LayoutUnit ComputeContentSize(
NGInlineNode node,
WritingMode container_writing_mode,
- const MinMaxSizeInput& input,
+ const MinMaxSizesInput& input,
NGLineBreakerMode mode,
NGLineBreaker::MaxSizeCache* max_size_cache,
base::Optional<LayoutUnit>* max_size_out) {
@@ -1510,7 +1501,7 @@ static LayoutUnit ComputeContentSize(
STACK_ALLOCATED();
public:
- explicit FloatsMaxSize(const MinMaxSizeInput& input)
+ explicit FloatsMaxSize(const MinMaxSizesInput& input)
: floats_inline_size_(input.float_left_inline_size +
input.float_right_inline_size) {
DCHECK_GE(floats_inline_size_, 0);
@@ -1519,7 +1510,7 @@ static LayoutUnit ComputeContentSize(
void AddFloat(const ComputedStyle& float_style,
const ComputedStyle& style,
LayoutUnit float_inline_max_size_with_margin) {
- floating_objects_.push_back(FloatingObject{
+ floating_objects_.push_back(NGInlineNode::FloatingObject{
float_style, style, float_inline_max_size_with_margin});
}
@@ -1561,12 +1552,7 @@ static LayoutUnit ComputeContentSize(
private:
LayoutUnit floats_inline_size_;
- struct FloatingObject {
- const ComputedStyle& float_style;
- const ComputedStyle& style;
- LayoutUnit float_inline_max_size_with_margin;
- };
- Vector<FloatingObject, 4> floating_objects_;
+ HeapVector<NGInlineNode::FloatingObject, 4> floating_objects_;
};
// This struct computes the max size from the line break results for the min
@@ -1711,8 +1697,8 @@ static LayoutUnit ComputeContentSize(
const ComputedStyle& float_style = float_node.Style();
// Floats don't intrude into floats.
- MinMaxSizeInput float_input(input.percentage_resolution_block_size);
- MinMaxSize child_sizes =
+ MinMaxSizesInput float_input(input.percentage_resolution_block_size);
+ MinMaxSizes child_sizes =
ComputeMinAndMaxContentContribution(style, float_node, float_input);
LayoutUnit child_inline_margins =
ComputeMinMaxMargins(style, float_node).InlineSum();
@@ -1751,9 +1737,9 @@ static LayoutUnit ComputeContentSize(
return result;
}
-MinMaxSize NGInlineNode::ComputeMinMaxSize(
+MinMaxSizes NGInlineNode::ComputeMinMaxSizes(
WritingMode container_writing_mode,
- const MinMaxSizeInput& input,
+ const MinMaxSizesInput& input,
const NGConstraintSpace* constraint_space) {
PrepareLayoutIfNeeded();
@@ -1761,7 +1747,7 @@ MinMaxSize NGInlineNode::ComputeMinMaxSize(
// size. This gives the min-content, the width where lines wrap at every
// break opportunity.
NGLineBreaker::MaxSizeCache max_size_cache;
- MinMaxSize sizes;
+ MinMaxSizes sizes;
base::Optional<LayoutUnit> max_size;
sizes.min_size = ComputeContentSize(*this, container_writing_mode, input,
NGLineBreakerMode::kMinContent,
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 ddb8325722d..72a5dd5fa81 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
@@ -22,7 +22,6 @@ class NGInlineChildLayoutContext;
class NGInlineNodeLegacy;
class NGLayoutResult;
class NGOffsetMapping;
-struct MinMaxSize;
struct NGInlineItemsData;
// Represents an anonymous block box to be laid out, that contains consecutive
@@ -55,9 +54,9 @@ class CORE_EXPORT NGInlineNode : public NGLayoutInputNode {
// 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.
- MinMaxSize ComputeMinMaxSize(WritingMode container_writing_mode,
- const MinMaxSizeInput&,
- const NGConstraintSpace* = nullptr);
+ MinMaxSizes ComputeMinMaxSizes(WritingMode container_writing_mode,
+ const MinMaxSizesInput&,
+ const NGConstraintSpace* = nullptr);
// Instruct to re-compute |PrepareLayout| on the next layout.
void InvalidatePrepareLayoutForTest() {
@@ -72,10 +71,19 @@ class CORE_EXPORT NGInlineNode : public NGLayoutInputNode {
return Data().ItemsData(is_first_line);
}
+ // There's a special intrinsic size measure quirk for images that are direct
+ // children of table cells that have auto inline-size: When measuring
+ // intrinsic min/max inline sizes, we pretend that it's not possible to break
+ // between images, or between text and images. Note that this only applies
+ // when measuring. During actual layout, on the other hand, standard breaking
+ // rules are to be followed.
+ // See https://quirks.spec.whatwg.org/#the-table-cell-width-calculation-quirk
+ bool IsStickyImagesQuirkForContentSize() const;
+
// Returns the text content to use for content sizing. This is normally the
// same as |items_data.text_content|, except when sticky images quirk is
// needed.
- String TextContentForContentSize(const NGInlineItemsData& items_data) const;
+ static String TextContentForStickyImagesQuirk(const NGInlineItemsData&);
// Clear associated fragments for LayoutObjects.
// They are associated when NGPaintFragment is constructed, but when clearing,
@@ -121,6 +129,16 @@ class CORE_EXPORT NGInlineNode : public NGLayoutInputNode {
String ToString() const;
+ struct FloatingObject {
+ DISALLOW_NEW();
+
+ void Trace(Visitor* visitor) {}
+
+ const ComputedStyle& float_style;
+ const ComputedStyle& style;
+ LayoutUnit float_inline_max_size_with_margin;
+ };
+
protected:
bool IsPrepareLayoutFinished() const;
@@ -160,8 +178,6 @@ class CORE_EXPORT NGInlineNode : public NGLayoutInputNode {
}
const NGInlineNodeData& EnsureData();
- static String TextContentForStickyImagesQuirk(const NGInlineItemsData&);
-
static void ComputeOffsetMapping(LayoutBlockFlow* layout_block_flow,
NGInlineNodeData* data);
@@ -169,28 +185,14 @@ class CORE_EXPORT NGInlineNode : public NGLayoutInputNode {
friend class NGInlineNodeLegacy;
};
-inline String NGInlineNode::TextContentForContentSize(
- const NGInlineItemsData& items_data) const {
- const String& text_content = items_data.text_content;
- if (UNLIKELY(text_content.IsEmpty()))
- return text_content;
-
- // There's a special intrinsic size measure quirk for images that are direct
- // children of table cells that have auto inline-size: When measuring
- // intrinsic min/max inline sizes, we pretend that it's not possible to break
- // between images, or between text and images. Note that this only applies
- // when measuring. During actual layout, on the other hand, standard breaking
- // rules are to be followed.
- // See https://quirks.spec.whatwg.org/#the-table-cell-width-calculation-quirk
+inline bool NGInlineNode::IsStickyImagesQuirkForContentSize() const {
if (UNLIKELY(GetDocument().InQuirksMode())) {
const ComputedStyle& style = Style();
if (UNLIKELY(style.Display() == EDisplay::kTableCell &&
- style.LogicalWidth().IsIntrinsicOrAuto())) {
- return TextContentForStickyImagesQuirk(items_data);
- }
+ style.LogicalWidth().IsIntrinsicOrAuto()))
+ return true;
}
-
- return text_content;
+ return false;
}
template <>
@@ -202,4 +204,7 @@ struct DowncastTraits<NGInlineNode> {
} // namespace blink
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(
+ blink::NGInlineNode::FloatingObject)
+
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_INLINE_NODE_H_
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 e77f4b569c9..5dda66cc9f2 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
@@ -11,6 +11,9 @@
namespace blink {
+template <typename OffsetMappingBuilder>
+class NGInlineItemsBuilderTemplate;
+
// Data which is required for inline nodes.
struct CORE_EXPORT NGInlineNodeData : NGInlineItemsData {
public:
@@ -40,6 +43,9 @@ struct CORE_EXPORT NGInlineNodeData : NGInlineItemsData {
friend class NGInlineNodeForTest;
friend class NGOffsetMappingTest;
+ template <typename OffsetMappingBuilder>
+ friend class NGInlineItemsBuilderTemplate;
+
// Items to use for the first line, when the node has :first-line rules.
//
// Items have different ComputedStyle, and may also have different
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 819493a0e6e..8d6cc679213 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
@@ -11,6 +11,7 @@
#include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.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_layout_algorithm.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_physical_text_fragment.h"
@@ -48,7 +49,8 @@ class NGInlineNodeForTest : public NGInlineNode {
unsigned start = data->text_content.length();
data->text_content = data->text_content + text;
data->items.push_back(NGInlineItem(NGInlineItem::kText, start,
- start + text.length(), layout_object));
+ start + text.length(), layout_object,
+ /* is_first_for_node */ true));
data->is_empty_inline_ = false;
}
@@ -56,8 +58,9 @@ class NGInlineNodeForTest : public NGInlineNode {
NGInlineNodeData* data = MutableData();
data->text_content = data->text_content + character;
unsigned end = data->text_content.length();
- data->items.push_back(
- NGInlineItem(NGInlineItem::kBidiControl, end - 1, end, nullptr));
+ data->items.push_back(NGInlineItem(NGInlineItem::kBidiControl, end - 1, end,
+ nullptr,
+ /* is_first_for_node */ true));
data->is_bidi_enabled_ = true;
data->is_empty_inline_ = false;
}
@@ -90,7 +93,6 @@ class NGInlineNodeTest : public NGLayoutTest {
void SetUp() override {
NGLayoutTest::SetUp();
style_ = ComputedStyle::Create();
- style_->GetFont().Update(nullptr);
}
void SetupHtml(const char* id, String html) {
@@ -115,31 +117,10 @@ class NGInlineNodeTest : public NGLayoutTest {
return node;
}
- MinMaxSize ComputeMinMaxSize(NGInlineNode node) {
- return node.ComputeMinMaxSize(
+ MinMaxSizes ComputeMinMaxSizes(NGInlineNode node) {
+ return node.ComputeMinMaxSizes(
node.Style().GetWritingMode(),
- MinMaxSizeInput(/* percentage_resolution_block_size */ LayoutUnit()));
- }
-
- void CreateLine(
- NGInlineNode node,
- Vector<scoped_refptr<const NGPhysicalTextFragment>>* fragments_out) {
- NGConstraintSpaceBuilder builder(WritingMode::kHorizontalTb,
- WritingMode::kHorizontalTb,
- /* is_new_fc */ false);
- builder.SetAvailableSize({LayoutUnit::Max(), LayoutUnit(-1)});
- NGConstraintSpace constraint_space = builder.ToConstraintSpace();
- NGInlineChildLayoutContext context;
- scoped_refptr<const NGLayoutResult> result =
- NGInlineLayoutAlgorithm(node, constraint_space,
- nullptr /* break_token */, &context)
- .Layout();
-
- const auto& line =
- To<NGPhysicalLineBoxFragment>(result->PhysicalFragment());
- for (const auto& child : line.Children()) {
- fragments_out->push_back(To<NGPhysicalTextFragment>(child.get()));
- }
+ MinMaxSizesInput(/* percentage_resolution_block_size */ LayoutUnit()));
}
const String& GetText() const {
@@ -177,8 +158,8 @@ class NGInlineNodeTest : public NGLayoutTest {
Vector<unsigned> ToEndOffsetList(
NGInlineItemSegments::const_iterator segments) {
Vector<unsigned> end_offsets;
- for (const NGInlineItemSegment& segment : segments)
- end_offsets.push_back(segment.EndOffset());
+ for (const RunSegmenter::RunSegmenterRange& segment : segments)
+ end_offsets.push_back(segment.end);
return end_offsets;
}
@@ -442,49 +423,27 @@ TEST_F(NGInlineNodeTest, SegmentBidiIsolate) {
TEST_ITEM_OFFSET_DIR(items[8], 22u, 28u, TextDirection::kLtr);
}
-#define TEST_TEXT_FRAGMENT(fragment, start_offset, end_offset) \
- EXPECT_EQ(start_offset, fragment->StartOffset()); \
- EXPECT_EQ(end_offset, fragment->EndOffset());
-
-TEST_F(NGInlineNodeTest, CreateLineBidiIsolate) {
- UseLayoutObjectAndAhem();
- scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
- style->SetLineHeight(Length::Fixed(1));
- style->GetFont().Update(nullptr);
- NGInlineNodeForTest node = CreateInlineNode();
- node = CreateBidiIsolateNode(node, layout_object_);
- node.ShapeText();
- Vector<scoped_refptr<const NGPhysicalTextFragment>> fragments;
- CreateLine(node, &fragments);
- EXPECT_EQ(5u, fragments.size());
- TEST_TEXT_FRAGMENT(fragments[0], 0u, 6u);
- TEST_TEXT_FRAGMENT(fragments[1], 16u, 21u);
- TEST_TEXT_FRAGMENT(fragments[2], 14u, 15u);
- TEST_TEXT_FRAGMENT(fragments[3], 7u, 13u);
- TEST_TEXT_FRAGMENT(fragments[4], 22u, 28u);
-}
-
-TEST_F(NGInlineNodeTest, MinMaxSize) {
+TEST_F(NGInlineNodeTest, MinMaxSizes) {
LoadAhem();
SetupHtml("t", "<div id=t style='font:10px Ahem'>AB CDEF</div>");
NGInlineNodeForTest node = CreateInlineNode();
- MinMaxSize sizes = ComputeMinMaxSize(node);
+ MinMaxSizes sizes = ComputeMinMaxSizes(node);
EXPECT_EQ(40, sizes.min_size);
EXPECT_EQ(70, sizes.max_size);
}
-TEST_F(NGInlineNodeTest, MinMaxSizeElementBoundary) {
+TEST_F(NGInlineNodeTest, MinMaxSizesElementBoundary) {
LoadAhem();
SetupHtml("t", "<div id=t style='font:10px Ahem'>A B<span>C D</span></div>");
NGInlineNodeForTest node = CreateInlineNode();
- MinMaxSize sizes = ComputeMinMaxSize(node);
+ MinMaxSizes sizes = ComputeMinMaxSizes(node);
// |min_content| should be the width of "BC" because there is an element
// boundary between "B" and "C" but no break opportunities.
EXPECT_EQ(20, sizes.min_size);
EXPECT_EQ(60, sizes.max_size);
}
-TEST_F(NGInlineNodeTest, MinMaxSizeFloats) {
+TEST_F(NGInlineNodeTest, MinMaxSizesFloats) {
LoadAhem();
SetupHtml("t", R"HTML(
<style>
@@ -496,13 +455,13 @@ TEST_F(NGInlineNodeTest, MinMaxSizeFloats) {
)HTML");
NGInlineNodeForTest node = CreateInlineNode();
- MinMaxSize sizes = ComputeMinMaxSize(node);
+ MinMaxSizes sizes = ComputeMinMaxSizes(node);
EXPECT_EQ(50, sizes.min_size);
EXPECT_EQ(130, sizes.max_size);
}
-TEST_F(NGInlineNodeTest, MinMaxSizeCloseTagAfterForcedBreak) {
+TEST_F(NGInlineNodeTest, MinMaxSizesCloseTagAfterForcedBreak) {
LoadAhem();
SetupHtml("t", R"HTML(
<style>
@@ -514,14 +473,14 @@ TEST_F(NGInlineNodeTest, MinMaxSizeCloseTagAfterForcedBreak) {
)HTML");
NGInlineNodeForTest node = CreateInlineNode();
- MinMaxSize sizes = ComputeMinMaxSize(node);
+ MinMaxSizes sizes = ComputeMinMaxSizes(node);
// The right border of the `</span>` is included in the line even if it
// appears after `<br>`. crbug.com/991320.
EXPECT_EQ(80, sizes.min_size);
EXPECT_EQ(80, sizes.max_size);
}
-TEST_F(NGInlineNodeTest, MinMaxSizeFloatsClearance) {
+TEST_F(NGInlineNodeTest, MinMaxSizesFloatsClearance) {
LoadAhem();
SetupHtml("t", R"HTML(
<style>
@@ -534,13 +493,13 @@ TEST_F(NGInlineNodeTest, MinMaxSizeFloatsClearance) {
)HTML");
NGInlineNodeForTest node = CreateInlineNode();
- MinMaxSize sizes = ComputeMinMaxSize(node);
+ MinMaxSizes sizes = ComputeMinMaxSizes(node);
EXPECT_EQ(50, sizes.min_size);
EXPECT_EQ(160, sizes.max_size);
}
-TEST_F(NGInlineNodeTest, MinMaxSizeTabulationWithBreakWord) {
+TEST_F(NGInlineNodeTest, MinMaxSizesTabulationWithBreakWord) {
LoadAhem();
SetupHtml("t", R"HTML(
<style>
@@ -554,7 +513,7 @@ TEST_F(NGInlineNodeTest, MinMaxSizeTabulationWithBreakWord) {
)HTML");
NGInlineNodeForTest node = CreateInlineNode();
- MinMaxSize sizes = ComputeMinMaxSize(node);
+ MinMaxSizes sizes = ComputeMinMaxSizes(node);
EXPECT_EQ(160, sizes.min_size);
EXPECT_EQ(170, sizes.max_size);
}
@@ -882,7 +841,12 @@ TEST_F(NGInlineNodeTest, CollectInlinesShouldNotClearFirstInlineFragment) {
// Running |CollectInlines| should not clear |FirstInlineFragment|.
LayoutObject* first_child = container->firstChild()->GetLayoutObject();
- EXPECT_NE(first_child->FirstInlineFragment(), nullptr);
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ // TODO(yosin): We should use |FirstInlineItemFragmentIndex()| once we
+ // implement it.
+ } else {
+ EXPECT_NE(first_child->FirstInlineFragment(), nullptr);
+ }
}
TEST_F(NGInlineNodeTest, InvalidateAddSpan) {
@@ -1371,7 +1335,7 @@ TEST_F(NGInlineNodeTest, MarkLineBoxesDirtyInInlineBlock) {
// Inline block with auto-size calls |ComputeMinMaxSize|, which may call
// |CollectInlines|. Emulate it to ensure it does not let tests to fail.
GetDocument().UpdateStyleAndLayoutTree();
- ComputeMinMaxSize(NGInlineNode(layout_block_flow_));
+ ComputeMinMaxSizes(NGInlineNode(layout_block_flow_));
auto lines = MarkLineBoxesDirty();
// TODO(kojii): Ideally, 0 should be false, or even 1 as well.
@@ -1394,7 +1358,7 @@ TEST_F(NGInlineNodeTest, RemoveInlineNodeDataIfBlockBecomesEmpty2) {
SetupHtml("container", "<div id=container><b><i>foo</i></b></div>");
ASSERT_TRUE(layout_block_flow_->HasNGInlineNodeData());
- GetElementById("container")->SetInnerHTMLFromString("");
+ GetElementById("container")->setInnerHTML("");
UpdateAllLifecyclePhasesForTest();
EXPECT_FALSE(layout_block_flow_->HasNGInlineNodeData());
@@ -1425,9 +1389,9 @@ 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 text_fragment_before_split;
+ text_fragment_before_split.MoveTo(*text->GetLayoutObject());
+ EXPECT_TRUE(text_fragment_before_split);
// Append <div> to <span>. causing SplitFlow().
Element* outer_span = GetElementById("outer_span");
@@ -1435,30 +1399,29 @@ TEST_F(NGInlineNodeTest, ClearFirstInlineFragmentOnSplitFlow) {
outer_span->appendChild(div);
// Update tree but do NOT update layout. At this point, there's no guarantee,
- // but there are some clients (e.g., Schroll Anchor) who try to read
+ // but there are some clients (e.g., Scroll Anchor) who try to read
// associated fragments.
//
// NGPaintFragment is owned by LayoutNGBlockFlow. Because the original owner
// no longer has an inline formatting context, the NGPaintFragment subtree is
// destroyed, and should not be accessible.
GetDocument().UpdateStyleAndLayoutTree();
- scoped_refptr<NGPaintFragment> text_fragment_before_layout =
- text->GetLayoutObject()->FirstInlineFragment();
- EXPECT_EQ(text_fragment_before_layout, nullptr);
+ EXPECT_FALSE(text->GetLayoutObject()->IsInLayoutNGInlineFormattingContext());
// 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 text_fragment_after_layout;
+ text_fragment_after_layout.MoveTo(*text->GetLayoutObject());
+ EXPECT_NE(text_fragment_before_split.Current(),
+ text_fragment_after_layout.Current());
// 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);
+ EXPECT_EQ(anonymous_block, text_fragment_after_layout.Current()
+ .GetLayoutObject()
+ ->ContainingBlock());
}
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 af3b4b14df1..acddeab0eaf 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
@@ -57,14 +57,27 @@ NGLineBoxFragmentBuilder::ChildList::LastInFlowChild() {
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.offset.inline_offset += delta;
+ child.rect.offset.inline_offset += delta;
}
void NGLineBoxFragmentBuilder::ChildList::MoveInInlineDirection(
@@ -72,20 +85,20 @@ void NGLineBoxFragmentBuilder::ChildList::MoveInInlineDirection(
unsigned start,
unsigned end) {
for (unsigned index = start; index < end; index++)
- children_[index].offset.inline_offset += delta;
+ children_[index].rect.offset.inline_offset += delta;
}
void NGLineBoxFragmentBuilder::ChildList::MoveInBlockDirection(
LayoutUnit delta) {
for (auto& child : children_)
- child.offset.block_offset += delta;
+ 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].offset.block_offset += delta;
+ children_[index].rect.offset.block_offset += delta;
}
void NGLineBoxFragmentBuilder::AddChildren(ChildList& children) {
@@ -94,42 +107,39 @@ void NGLineBoxFragmentBuilder::AddChildren(ChildList& children) {
for (auto& child : children) {
if (child.layout_result) {
DCHECK(!child.fragment);
- AddChild(child.layout_result->PhysicalFragment(), child.offset);
+ AddChild(child.layout_result->PhysicalFragment(), child.Offset());
child.layout_result.reset();
} else if (child.fragment) {
- AddChild(std::move(child.fragment), child.offset);
+ AddChild(std::move(child.fragment), child.Offset());
DCHECK(!child.fragment);
} else if (child.out_of_flow_positioned_box) {
AddOutOfFlowInlineChildCandidate(
NGBlockNode(ToLayoutBox(child.out_of_flow_positioned_box)),
- child.offset, child.container_direction);
+ child.Offset(), child.container_direction);
child.out_of_flow_positioned_box = nullptr;
}
}
}
void NGLineBoxFragmentBuilder::PropagateChildrenData(ChildList& children) {
- for (auto& child : children) {
+ for (unsigned index = 0; index < children.size(); ++index) {
+ auto& child = children[index];
if (child.layout_result) {
DCHECK(!child.fragment);
- const NGPhysicalContainerFragment& fragment =
- child.layout_result->PhysicalFragment();
- if (fragment.IsFloating()) {
- // Add positioned floating objects to the fragment tree, not to the
- // fragment item list. Because they are not necessary for inline
- // traversals, and leading floating objects are still in the fragment
- // tree, this helps simplifying painting floats.
- AddChild(fragment, child.offset);
- child.layout_result.reset();
- continue;
- }
- PropagateChildData(child.layout_result->PhysicalFragment(), child.offset);
+ PropagateChildData(child.layout_result->PhysicalFragment(),
+ child.Offset());
+
+ // Skip over any children, the information should have already been
+ // propagated into this layout result.
+ if (child.children_count)
+ index += child.children_count - 1;
+
continue;
}
if (child.out_of_flow_positioned_box) {
AddOutOfFlowInlineChildCandidate(
NGBlockNode(ToLayoutBox(child.out_of_flow_positioned_box)),
- child.offset, child.container_direction);
+ child.Offset(), child.container_direction);
child.out_of_flow_positioned_box = nullptr;
}
}
@@ -148,7 +158,9 @@ NGLineBoxFragmentBuilder::ToLineBoxFragment() {
scoped_refptr<const NGPhysicalLineBoxFragment> fragment =
NGPhysicalLineBoxFragment::Create(this);
- return base::AdoptRef(new NGLayoutResult(std::move(fragment), this));
+ return base::AdoptRef(
+ new NGLayoutResult(NGLayoutResult::NGLineBoxFragmentBuilderPassKey(),
+ std::move(fragment), this));
}
} // namespace blink
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 00807812e98..93550d8b80f 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
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_LINE_BOX_FRAGMENT_BUILDER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_LINE_BOX_FRAGMENT_BUILDER_H_
-#include "third_party/blink/renderer/core/layout/geometry/logical_offset.h"
+#include "third_party/blink/renderer/core/layout/geometry/logical_rect.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_line_height_metrics.h"
@@ -77,11 +77,12 @@ class CORE_EXPORT NGLineBoxFragmentBuilder final
scoped_refptr<const NGLayoutResult> layout_result;
scoped_refptr<const NGPhysicalTextFragment> fragment;
+ const NGInlineItem* inline_item = 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.
- LogicalOffset offset;
+ LogicalRect rect;
// The offset of a positioned float wrt. the root BFC. This should only be
// set for positioned floats.
NGBfcOffset bfc_offset;
@@ -103,18 +104,35 @@ class CORE_EXPORT NGLineBoxFragmentBuilder final
Child() = default;
// Create a placeholder. A placeholder does not have a fragment nor a bidi
// level.
- Child(LogicalOffset offset) : offset(offset) {}
+ 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)),
- offset(offset),
+ rect(offset, LogicalSize()),
inline_size(inline_size),
+ children_count(children_count),
bidi_level(bidi_level) {}
// Create an in-flow |NGPhysicalTextFragment|.
Child(scoped_refptr<const NGPhysicalTextFragment> fragment,
@@ -122,7 +140,7 @@ class CORE_EXPORT NGLineBoxFragmentBuilder final
LayoutUnit inline_size,
UBiDiLevel bidi_level)
: fragment(std::move(fragment)),
- offset(offset),
+ rect(offset, LogicalSize()),
inline_size(inline_size),
bidi_level(bidi_level) {}
Child(scoped_refptr<const NGPhysicalTextFragment> fragment,
@@ -130,7 +148,7 @@ class CORE_EXPORT NGLineBoxFragmentBuilder final
LayoutUnit inline_size,
UBiDiLevel bidi_level)
: fragment(std::move(fragment)),
- offset({LayoutUnit(), block_offset}),
+ rect(LayoutUnit(), block_offset, LayoutUnit(), LayoutUnit()),
inline_size(inline_size),
bidi_level(bidi_level) {}
// Create an out-of-flow positioned object.
@@ -180,11 +198,20 @@ class CORE_EXPORT NGLineBoxFragmentBuilder final
}
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.
@@ -234,11 +261,18 @@ class CORE_EXPORT NGLineBoxFragmentBuilder final
void InsertChild(unsigned index);
void InsertChild(unsigned index,
scoped_refptr<const NGLayoutResult> layout_result,
- const LogicalOffset& offset,
- LayoutUnit inline_size,
- UBiDiLevel bidi_level) {
- children_.insert(index, Child{std::move(layout_result), offset,
- inline_size, bidi_level});
+ 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);
@@ -247,6 +281,8 @@ class CORE_EXPORT NGLineBoxFragmentBuilder final
void MoveInBlockDirection(LayoutUnit, unsigned start, unsigned end);
private:
+ void WillInsertChild(unsigned index);
+
Vector<Child, 16> children_;
};
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 31c45dd7290..494d7ae3167 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
@@ -132,22 +132,16 @@ LayoutUnit ComputeFloatAncestorInlineEndSize(const NGConstraintSpace& space,
return inline_end_size;
}
-scoped_refptr<const NGPhysicalTextFragment> CreateHyphenFragment(
- NGInlineNode node,
- WritingMode writing_mode,
- const NGInlineItem& item) {
+void CreateHyphen(NGInlineNode node,
+ WritingMode writing_mode,
+ const NGInlineItem& item,
+ NGInlineItemResult* item_result) {
DCHECK(item.Style());
const ComputedStyle& style = *item.Style();
TextDirection direction = style.Direction();
- String hyphen_string = style.HyphenString();
- HarfBuzzShaper shaper(hyphen_string);
- scoped_refptr<ShapeResult> hyphen_result =
- shaper.Shape(&style.GetFont(), direction);
- NGTextFragmentBuilder builder(writing_mode);
- builder.SetText(item.GetLayoutObject(), hyphen_string, &style,
- /* is_ellipsis_style */ false,
- ShapeResultView::Create(hyphen_result.get()));
- return builder.ToTextFragment();
+ item_result->hyphen_string = style.HyphenString();
+ HarfBuzzShaper shaper(item_result->hyphen_string);
+ item_result->hyphen_shape_result = shaper.Shape(&style.GetFont(), direction);
}
inline void ClearNeedsLayout(const NGInlineItem& item) {
@@ -183,10 +177,13 @@ NGLineBreaker::NGLineBreaker(NGInlineNode node,
use_first_line_style_(is_first_formatted_line_ &&
node.UseFirstLineStyle()),
in_line_height_quirks_mode_(node.InLineHeightQuirksMode()),
+ sticky_images_quirk_(mode != NGLineBreakerMode::kContent &&
+ node.IsStickyImagesQuirkForContentSize()),
items_data_(node.ItemsData(use_first_line_style_)),
- text_content_(mode == NGLineBreakerMode::kContent
- ? items_data_.text_content
- : node.TextContentForContentSize(items_data_)),
+ text_content_(
+ !sticky_images_quirk_
+ ? items_data_.text_content
+ : NGInlineNode::TextContentForStickyImagesQuirk(items_data_)),
constraint_space_(space),
exclusion_space_(exclusion_space),
break_token_(break_token),
@@ -262,25 +259,6 @@ void NGLineBreaker::SetMaxSizeCache(MaxSizeCache* max_size_cache) {
max_size_cache_ = max_size_cache;
}
-LayoutUnit NGLineBreaker::SetLineEndFragment(
- scoped_refptr<const NGPhysicalTextFragment> fragment,
- NGLineInfo* line_info) {
- LayoutUnit inline_size;
- bool is_horizontal =
- IsHorizontalWritingMode(constraint_space_.GetWritingMode());
- if (line_info->LineEndFragment()) {
- const PhysicalSize& size = line_info->LineEndFragment()->Size();
- inline_size = is_horizontal ? -size.width : -size.height;
- }
- if (fragment) {
- const PhysicalSize& size = fragment->Size();
- inline_size = is_horizontal ? size.width : size.height;
- }
- line_info->SetLineEndFragment(std::move(fragment));
- position_ += inline_size;
- return inline_size;
-}
-
// Compute the base direction for bidi algorithm for this line.
void NGLineBreaker::ComputeBaseDirection() {
// If 'unicode-bidi' is not 'plaintext', use the base direction of the block.
@@ -492,29 +470,15 @@ void NGLineBreaker::ComputeLineLocation(NGLineInfo* line_info) const {
line_info->UpdateTextAlign();
}
-// For Web-compatibility, allow break between an atomic inline and any adjacent
-// U+00A0 NO-BREAK SPACE character.
-// https://www.w3.org/TR/css-text-3/#line-break-details
-bool NGLineBreaker::IsAtomicInlineBeforeNoBreakSpace(
- const NGInlineItemResult& item_result) const {
- DCHECK(auto_wrap_);
- DCHECK_EQ(item_result.item->Type(), NGInlineItem::kAtomicInline);
- const String& text = Text();
- DCHECK_GE(text.length(), item_result.end_offset);
- return text.length() > item_result.end_offset &&
- text[item_result.end_offset] == kNoBreakSpaceCharacter &&
- // Except when sticky images quirk was applied.
- text[item_result.start_offset] != kNoBreakSpaceCharacter;
-}
-
-bool NGLineBreaker::IsAtomicInlineAfterNoBreakSpace(
+// Atomic inlines have break opportunities before and after, even when the
+// adjacent character is U+00A0 NO-BREAK SPACE character.
+bool NGLineBreaker::ShouldForceCanBreakAfter(
const NGInlineItemResult& item_result) const {
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[item_result.end_offset - 1] != kNoBreakSpaceCharacter ||
- text.length() <= item_result.end_offset ||
+ if (text.length() <= item_result.end_offset ||
text[item_result.end_offset] != kObjectReplacementCharacter)
return false;
// This kObjectReplacementCharacter can be any objects, such as a floating or
@@ -598,8 +562,10 @@ void NGLineBreaker::HandleText(const NGInlineItem& item,
}
// Try to break inside of this text item.
- BreakResult break_result = BreakText(item_result, item, shape_result,
- RemainingAvailableWidth(), line_info);
+ const LayoutUnit available_width = RemainingAvailableWidth();
+ BreakResult break_result =
+ BreakText(item_result, item, shape_result, available_width,
+ available_width, line_info);
DCHECK(item_result->shape_result ||
(break_result == kOverflow && break_anywhere_if_overflow_ &&
!override_break_anywhere_));
@@ -677,6 +643,7 @@ NGLineBreaker::BreakResult NGLineBreaker::BreakText(
const NGInlineItem& item,
const ShapeResult& item_shape_result,
LayoutUnit available_width,
+ LayoutUnit available_width_with_hyphens,
NGLineInfo* line_info) {
DCHECK(item.Type() == NGInlineItem::kText ||
(item.Type() == NGInlineItem::kControl &&
@@ -739,7 +706,7 @@ NGLineBreaker::BreakResult NGLineBreaker::BreakText(
// rewinded. Making this item long enough to overflow is enough.
if (!shape_result) {
DCHECK(options & ShapingLineBreaker::kNoResultIfOverflow);
- item_result->inline_size = available_width + 1;
+ item_result->inline_size = available_width_with_hyphens + 1;
item_result->end_offset = item.EndOffset();
return kOverflow;
}
@@ -750,25 +717,27 @@ NGLineBreaker::BreakResult NGLineBreaker::BreakText(
CHECK_GT(result.break_offset, item_result->start_offset);
inline_size = shape_result->SnappedWidth().ClampNegativeToZero();
- item_result->inline_size = inline_size;
if (UNLIKELY(result.is_hyphenated)) {
const WritingMode writing_mode = constraint_space_.GetWritingMode();
- scoped_refptr<const NGPhysicalTextFragment> hyphen_fragment =
- CreateHyphenFragment(node_, writing_mode, item);
- LayoutUnit space_for_hyphen = available_width - inline_size;
- LayoutUnit hyphen_inline_size = IsHorizontalWritingMode(writing_mode)
- ? hyphen_fragment->Size().width
- : hyphen_fragment->Size().height;
+ CreateHyphen(node_, writing_mode, item, item_result);
+ DCHECK(item_result->hyphen_shape_result);
+ DCHECK(item_result->hyphen_string);
+ LayoutUnit hyphen_inline_size = item_result->HyphenInlineSize();
// If the hyphen overflows, retry with the reduced available width.
- if (space_for_hyphen >= 0 && hyphen_inline_size > space_for_hyphen) {
- available_width -= hyphen_inline_size;
- continue;
+ if (!result.is_overflow && inline_size <= available_width) {
+ LayoutUnit space_for_hyphen =
+ available_width_with_hyphens - inline_size;
+ if (space_for_hyphen >= 0 && hyphen_inline_size > space_for_hyphen) {
+ available_width -= hyphen_inline_size;
+ continue;
+ }
}
- inline_size += SetLineEndFragment(std::move(hyphen_fragment), line_info);
- item_result->text_end_effect = NGTextEndEffect::kHyphen;
+ inline_size += hyphen_inline_size;
+ } else if (UNLIKELY(item_result->hyphen_shape_result)) {
+ item_result->hyphen_shape_result = nullptr;
+ item_result->hyphen_string = String();
}
- item_result->inline_size =
- shape_result->SnappedWidth().ClampNegativeToZero();
+ item_result->inline_size = inline_size;
item_result->end_offset = result.break_offset;
item_result->shape_result = std::move(shape_result);
break;
@@ -796,7 +765,7 @@ NGLineBreaker::BreakResult NGLineBreaker::BreakText(
item_result->can_break_after =
break_iterator_.IsBreakable(item_result->end_offset);
if (!item_result->can_break_after && item.Type() == NGInlineItem::kText &&
- IsAtomicInlineAfterNoBreakSpace(*item_result))
+ ShouldForceCanBreakAfter(*item_result))
item_result->can_break_after = true;
trailing_whitespace_ = WhitespaceState::kUnknown;
}
@@ -1344,6 +1313,21 @@ void NGLineBreaker::HandleAtomicInline(
DCHECK(item.Style());
const ComputedStyle& style = *item.Style();
+ const LayoutUnit remaining_width = RemainingAvailableWidth();
+ bool ignore_overflow_if_negative_margin = false;
+ if (state_ == LineBreakState::kContinue && remaining_width < 0) {
+ const unsigned item_index = item_index_;
+ DCHECK_EQ(item_index, static_cast<unsigned>(&item - Items().begin()));
+ DCHECK(!line_info->HasOverflow());
+ HandleOverflow(line_info);
+ if (!line_info->HasOverflow() || item_index != item_index_)
+ return;
+ // Compute margins if this line overflows. Negative margins can put the
+ // position back.
+ DCHECK_NE(state_, LineBreakState::kContinue);
+ ignore_overflow_if_negative_margin = true;
+ }
+
// Compute margins before computing overflow, because even when the current
// position is beyond the end, negative margins can bring this item back to on
// the current line.
@@ -1351,13 +1335,18 @@ void NGLineBreaker::HandleAtomicInline(
item_result->margins =
ComputeLineMarginsForVisualContainer(constraint_space_, style);
LayoutUnit inline_margins = item_result->margins.InlineSum();
- LayoutUnit remaining_width = RemainingAvailableWidth();
- bool is_overflow_before =
- state_ == LineBreakState::kContinue && remaining_width < 0;
- if (UNLIKELY(is_overflow_before && inline_margins > remaining_width)) {
- RemoveLastItem(line_info);
- HandleOverflow(line_info);
- return;
+ if (UNLIKELY(ignore_overflow_if_negative_margin)) {
+ DCHECK_LT(remaining_width, 0);
+ // The margin isn't negative, or the negative margin isn't large enough to
+ // put the position back. Break this line before this item.
+ if (inline_margins >= remaining_width) {
+ RemoveLastItem(line_info);
+ return;
+ }
+ // This line once overflowed, but the negative margin puts the position
+ // back.
+ state_ = LineBreakState::kContinue;
+ line_info->SetHasOverflow(false);
}
// When we're just computing min/max content sizes, we can skip the full
@@ -1369,7 +1358,6 @@ void NGLineBreaker::HandleAtomicInline(
item_result->layout_result =
NGBlockNode(ToLayoutBox(item.GetLayoutObject()))
.LayoutAtomicInline(constraint_space_, node_.Style(),
- line_info->LineStyle().GetFontBaseline(),
line_info->UseFirstLineStyle());
item_result->inline_size =
NGFragment(constraint_space_.GetWritingMode(),
@@ -1382,8 +1370,8 @@ void NGLineBreaker::HandleAtomicInline(
} else {
DCHECK(mode_ == NGLineBreakerMode::kMinContent || !max_size_cache_);
NGBlockNode child(ToLayoutBox(item.GetLayoutObject()));
- MinMaxSizeInput input(percentage_resolution_block_size_for_min_max);
- MinMaxSize sizes =
+ MinMaxSizesInput input(percentage_resolution_block_size_for_min_max);
+ MinMaxSizes sizes =
ComputeMinAndMaxContentContribution(node_.Style(), child, input);
if (mode_ == NGLineBreakerMode::kMinContent) {
item_result->inline_size = sizes.min_size + inline_margins;
@@ -1399,10 +1387,11 @@ void NGLineBreaker::HandleAtomicInline(
}
item_result->should_create_line_box = true;
- ComputeCanBreakAfter(item_result, auto_wrap_, break_iterator_);
- if (!item_result->can_break_after && auto_wrap_ &&
- IsAtomicInlineBeforeNoBreakSpace(*item_result))
- item_result->can_break_after = true;
+ // Atomic inlines have break opportunities before and after, even when the
+ // adjacent character is U+00A0 NO-BREAK SPACE character, except when sticky
+ // images quirk is applied.
+ item_result->can_break_after =
+ auto_wrap_ && !(sticky_images_quirk_ && item.IsImage());
position_ += item_result->inline_size;
trailing_whitespace_ = WhitespaceState::kNone;
@@ -1448,6 +1437,10 @@ void NGLineBreaker::HandleFloat(const NGInlineItem& item,
!leading_floats_.IsEmpty()) {
DCHECK_LT(leading_floats_index_, leading_floats_.size());
item_result->positioned_float = leading_floats_[leading_floats_index_++];
+
+ // Don't break after leading floats if indented.
+ if (position_ != 0)
+ item_result->can_break_after = false;
return;
}
@@ -1654,9 +1647,6 @@ void NGLineBreaker::HandleOverflow(NGLineInfo* line_info) {
LayoutUnit width_to_rewind = position_ - available_width;
DCHECK_GT(width_to_rewind, 0);
- // Indicates positions of items may be changed and need to UpdatePosition().
- bool position_maybe_changed = false;
-
// Keep track of the shortest break opportunity.
unsigned break_before = 0;
@@ -1699,40 +1689,36 @@ void NGLineBreaker::HandleOverflow(NGLineInfo* line_info) {
// If space is available, and if this text is breakable, part of the text
// may fit. Try to break this item.
if (width_to_rewind < 0 && item_result->may_break_inside) {
- LayoutUnit item_available_width = -width_to_rewind;
+ const LayoutUnit item_available_width = -width_to_rewind;
// Make sure the available width is smaller than the current width. The
// break point must not be at the end when e.g., the text fits but its
// right margin does not or following items do not.
const LayoutUnit min_available_width = item_result->inline_size - 1;
- if (item_available_width > min_available_width) {
- item_available_width = min_available_width;
- // If |inline_size| is zero (e.g., `font-size: 0`), |BreakText| cannot
- // make it shorter. Take the previous break opportunity.
- if (UNLIKELY(item_available_width <= 0)) {
- if (BreakTextAtPreviousBreakOpportunity(item_result)) {
- RewindOverflow(i + 1, line_info);
- return;
- }
- continue;
+ // If |inline_size| is zero (e.g., `font-size: 0`), |BreakText| cannot
+ // make it shorter. Take the previous break opportunity.
+ if (UNLIKELY(min_available_width <= 0)) {
+ if (BreakTextAtPreviousBreakOpportunity(item_result)) {
+ RewindOverflow(i + 1, line_info);
+ return;
}
+ continue;
}
- auto was_current_style = current_style_;
+ scoped_refptr<const ComputedStyle> was_current_style = current_style_;
SetCurrentStyle(*item.Style());
- const unsigned end_offset_before = item_result->end_offset;
- BreakResult break_result =
- BreakText(item_result, item, *item.TextShapeResult(),
- item_available_width, line_info);
- DCHECK_LE(item_result->end_offset, end_offset_before);
+ const NGInlineItemResult item_result_before = *item_result;
+ 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);
#if DCHECK_IS_ON()
item_result->CheckConsistency(true);
#endif
+
// If BreakText() changed this item small enough to fit, break here.
- DCHECK_EQ(break_result == kSuccess,
- item_result->inline_size <= item_available_width);
- if (break_result == kSuccess) {
- DCHECK_LE(item_result->inline_size, item_available_width);
+ 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());
- DCHECK(item_result->can_break_after);
// If this is the last item, adjust it to accommodate the change.
const unsigned new_end = i + 1;
@@ -1740,8 +1726,6 @@ void NGLineBreaker::HandleOverflow(NGLineInfo* line_info) {
if (new_end == item_results->size()) {
position_ =
available_width + width_to_rewind + item_result->inline_size;
- if (line_info->LineEndFragment())
- SetLineEndFragment(nullptr, line_info);
DCHECK_EQ(position_, line_info->ComputeWidth());
item_index_ = item_result->item_index;
offset_ = item_result->end_offset;
@@ -1757,8 +1741,10 @@ void NGLineBreaker::HandleOverflow(NGLineInfo* line_info) {
HandleTrailingSpaces(item, line_info);
return;
}
+
+ // Failed to break to fit. Restore to the original state.
+ *item_result = std::move(item_result_before);
SetCurrentStyle(*was_current_style);
- position_maybe_changed = true;
}
}
}
@@ -1786,11 +1772,6 @@ void NGLineBreaker::HandleOverflow(NGLineInfo* line_info) {
return;
}
- if (position_maybe_changed) {
- trailing_whitespace_ = WhitespaceState::kUnknown;
- position_ = line_info->ComputeWidth();
- }
-
if (CanBreakAfterLast(*item_results)) {
state_ = LineBreakState::kTrailing;
return;
@@ -1810,6 +1791,7 @@ void NGLineBreaker::RewindOverflow(unsigned new_end, NGLineInfo* line_info) {
const Vector<NGInlineItem>& items = Items();
const NGInlineItemResults& item_results = line_info->Results();
DCHECK_LT(new_end, item_results.size());
+
unsigned open_tag_count = 0;
const String& text = Text();
for (unsigned index = new_end; index < item_results.size(); index++) {
@@ -1819,16 +1801,20 @@ void NGLineBreaker::RewindOverflow(unsigned new_end, NGLineInfo* line_info) {
if (item.Type() == NGInlineItem::kText) {
// Text items are trailable if they start with trailable spaces.
DCHECK_GT(item_result.Length(), 0u);
- if (item_result.shape_result) {
+ if (item_result.shape_result || // kNoResultIfOverflow if 'break-word'
+ (break_anywhere_if_overflow_ && !override_break_anywhere_)) {
DCHECK(item.Style());
const EWhiteSpace white_space = item.Style()->WhiteSpace();
if (ComputedStyle::AutoWrap(white_space) &&
white_space != EWhiteSpace::kBreakSpaces &&
IsBreakableSpace(text[item_result.start_offset])) {
- // If all characters are trailable spaces, check the next item.
- if (IsAllBreakableSpaces(text, item_result.start_offset + 1,
- item_result.end_offset))
+ // If more items left and all characters are trailable spaces, check
+ // the next item.
+ if (item_result.shape_result && index < item_results.size() - 1 &&
+ IsAllBreakableSpaces(text, item_result.start_offset + 1,
+ item_result.end_offset)) {
continue;
+ }
// If this item starts with spaces followed by non-space characters,
// rewind to before this item. |HandleText()| will include the spaces
// and break there.
@@ -1836,6 +1822,9 @@ void NGLineBreaker::RewindOverflow(unsigned new_end, NGLineInfo* line_info) {
Rewind(index, line_info);
DCHECK_EQ(static_cast<unsigned>(&item - items.begin()), item_index_);
HandleTrailingSpaces(item, line_info);
+#if DCHECK_IS_ON()
+ item_results.back().CheckConsistency(false);
+#endif
return;
}
}
@@ -1962,7 +1951,6 @@ void NGLineBreaker::Rewind(unsigned new_end, NGLineInfo* line_info) {
item_results.Shrink(new_end);
trailing_collapsible_space_.reset();
- SetLineEndFragment(nullptr, line_info);
position_ = line_info->ComputeWidth();
}
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 d19c268bcae..ac8685caad5 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
@@ -99,8 +99,6 @@ class CORE_EXPORT NGLineBreaker {
unsigned end_offset,
NGLineInfo*);
NGInlineItemResult* AddItem(const NGInlineItem&, NGLineInfo*);
- LayoutUnit SetLineEndFragment(scoped_refptr<const NGPhysicalTextFragment>,
- NGLineInfo*);
void BreakLine(LayoutUnit percentage_resolution_block_size_for_min_max,
NGLineInfo*);
@@ -135,6 +133,7 @@ class CORE_EXPORT NGLineBreaker {
const NGInlineItem&,
const ShapeResult&,
LayoutUnit available_width,
+ LayoutUnit available_width_with_hyphens,
NGLineInfo*);
bool BreakTextAtPreviousBreakOpportunity(NGInlineItemResult* item_result);
bool HandleTextForFastMinContent(NGInlineItemResult*,
@@ -166,10 +165,7 @@ class CORE_EXPORT NGLineBreaker {
const NGInlineItem&,
LayoutUnit percentage_resolution_block_size_for_min_max,
NGLineInfo*);
- bool IsAtomicInlineAfterNoBreakSpace(
- const NGInlineItemResult& item_result) const;
- bool IsAtomicInlineBeforeNoBreakSpace(
- const NGInlineItemResult& item_result) const;
+ bool ShouldForceCanBreakAfter(const NGInlineItemResult& item_result) const;
void HandleFloat(const NGInlineItem&,
NGLineInfo*);
void HandleOutOfFlowPositioned(const NGInlineItem&, NGLineInfo*);
@@ -260,6 +256,10 @@ class CORE_EXPORT NGLineBreaker {
// the next line.
bool is_after_forced_break_ = false;
+ // Set in quirks mode when we're not supposed to break inside table cells
+ // between images, and between text and images.
+ bool sticky_images_quirk_ = 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 34eba2935cd..4e53d79afa3 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
@@ -17,6 +17,17 @@
namespace blink {
+String ToString(NGInlineItemResults line, NGInlineNode node) {
+ StringBuilder builder;
+ 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));
+ }
+ return builder.ToString();
+}
+
class NGLineBreakerTest : public NGLayoutTest {
protected:
NGInlineNode CreateInlineNode(const String& html_content) {
@@ -28,8 +39,10 @@ class NGLineBreakerTest : public NGLayoutTest {
}
// Break lines using the specified available width.
- Vector<NGLineInfo> BreakToLineInfo(NGInlineNode node,
- LayoutUnit available_width) {
+ Vector<std::pair<String, unsigned>> BreakLines(
+ NGInlineNode node,
+ LayoutUnit available_width,
+ bool fill_first_space_ = false) {
DCHECK(node);
node.PrepareLayoutIfNeeded();
@@ -42,13 +55,13 @@ class NGLineBreakerTest : public NGLayoutTest {
scoped_refptr<NGInlineBreakToken> break_token;
- Vector<NGLineInfo> line_infos;
+ Vector<std::pair<String, unsigned>> lines;
trailing_whitespaces_.resize(0);
NGExclusionSpace exclusion_space;
NGPositionedFloatVector leading_floats;
NGLineLayoutOpportunity line_opportunity(available_width);
while (!break_token || !break_token->IsFinished()) {
- NGLineInfo& line_info = line_infos.emplace_back();
+ NGLineInfo line_info;
NGLineBreaker line_breaker(node, NGLineBreakerMode::kContent, space,
line_opportunity, leading_floats, 0u,
break_token.get(), &exclusion_space);
@@ -60,36 +73,25 @@ class NGLineBreakerTest : public NGLayoutTest {
break;
break_token = line_breaker.CreateBreakToken(line_info);
+ if (fill_first_space_ && lines.IsEmpty()) {
+ first_should_hang_trailing_space_ =
+ line_info.ShouldHangTrailingSpaces();
+ first_hang_width_ = line_info.HangWidth();
+ }
+ lines.push_back(std::make_pair(ToString(line_info.Results(), node),
+ line_info.Results().back().item_index));
}
- return line_infos;
- }
-
- Vector<NGInlineItemResults> BreakLines(NGInlineNode node,
- LayoutUnit available_width) {
- Vector<NGLineInfo> line_infos = BreakToLineInfo(node, available_width);
- Vector<NGInlineItemResults> lines;
- for (NGLineInfo& line_info : line_infos)
- lines.push_back(std::move(line_info.Results()));
return lines;
}
Vector<NGLineBreaker::WhitespaceState> trailing_whitespaces_;
+ bool first_should_hang_trailing_space_;
+ LayoutUnit first_hang_width_;
};
namespace {
-String ToString(NGInlineItemResults line, NGInlineNode node) {
- StringBuilder builder;
- 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));
- }
- return builder.ToString();
-}
-
TEST_F(NGLineBreakerTest, SingleNode) {
LoadAhem();
NGInlineNode node = CreateInlineNode(R"HTML(
@@ -102,17 +104,17 @@ TEST_F(NGLineBreakerTest, SingleNode) {
<div id=container>123 456 789</div>
)HTML");
- Vector<NGInlineItemResults> lines;
+ Vector<std::pair<String, unsigned>> lines;
lines = BreakLines(node, LayoutUnit(80));
EXPECT_EQ(2u, lines.size());
- EXPECT_EQ("123 456", ToString(lines[0], node));
- EXPECT_EQ("789", ToString(lines[1], node));
+ EXPECT_EQ("123 456", lines[0].first);
+ EXPECT_EQ("789", lines[1].first);
lines = BreakLines(node, LayoutUnit(60));
EXPECT_EQ(3u, lines.size());
- EXPECT_EQ("123", ToString(lines[0], node));
- EXPECT_EQ("456", ToString(lines[1], node));
- EXPECT_EQ("789", ToString(lines[2], node));
+ EXPECT_EQ("123", lines[0].first);
+ EXPECT_EQ("456", lines[1].first);
+ EXPECT_EQ("789", lines[2].first);
}
TEST_F(NGLineBreakerTest, OverflowWord) {
@@ -128,17 +130,17 @@ TEST_F(NGLineBreakerTest, OverflowWord) {
)HTML");
// The first line overflows, but the last line does not.
- Vector<NGInlineItemResults> lines;
+ Vector<std::pair<String, unsigned>> lines;
lines = BreakLines(node, LayoutUnit(40));
EXPECT_EQ(2u, lines.size());
- EXPECT_EQ("12345", ToString(lines[0], node));
- EXPECT_EQ("678", ToString(lines[1], node));
+ EXPECT_EQ("12345", lines[0].first);
+ EXPECT_EQ("678", lines[1].first);
// Both lines overflow.
lines = BreakLines(node, LayoutUnit(20));
EXPECT_EQ(2u, lines.size());
- EXPECT_EQ("12345", ToString(lines[0], node));
- EXPECT_EQ("678", ToString(lines[1], node));
+ EXPECT_EQ("12345", lines[0].first);
+ EXPECT_EQ("678", lines[1].first);
}
TEST_F(NGLineBreakerTest, OverflowTab) {
@@ -156,11 +158,11 @@ TEST_F(NGLineBreakerTest, OverflowTab) {
<div id=container>12345&#9;&#9;678</div>
)HTML");
- Vector<NGInlineItemResults> lines;
+ Vector<std::pair<String, unsigned>> lines;
lines = BreakLines(node, LayoutUnit(100));
EXPECT_EQ(2u, lines.size());
- EXPECT_EQ("12345\t\t", ToString(lines[0], node));
- EXPECT_EQ("678", ToString(lines[1], node));
+ EXPECT_EQ("12345\t\t", lines[0].first);
+ EXPECT_EQ("678", lines[1].first);
}
TEST_F(NGLineBreakerTest, OverflowTabBreakWord) {
@@ -179,11 +181,11 @@ TEST_F(NGLineBreakerTest, OverflowTabBreakWord) {
<div id=container>12345&#9;&#9;678</div>
)HTML");
- Vector<NGInlineItemResults> lines;
+ Vector<std::pair<String, unsigned>> lines;
lines = BreakLines(node, LayoutUnit(100));
EXPECT_EQ(2u, lines.size());
- EXPECT_EQ("12345\t\t", ToString(lines[0], node));
- EXPECT_EQ("678", ToString(lines[1], node));
+ EXPECT_EQ("12345\t\t", lines[0].first);
+ EXPECT_EQ("678", lines[1].first);
}
TEST_F(NGLineBreakerTest, OverflowAtomicInline) {
@@ -203,28 +205,28 @@ TEST_F(NGLineBreakerTest, OverflowAtomicInline) {
<div id=container>12345<span></span>678</div>
)HTML");
- Vector<NGInlineItemResults> lines;
+ Vector<std::pair<String, unsigned>> lines;
lines = BreakLines(node, LayoutUnit(80));
EXPECT_EQ(2u, lines.size());
- EXPECT_EQ(String(u"12345\uFFFC"), ToString(lines[0], node));
- EXPECT_EQ("678", ToString(lines[1], node));
+ EXPECT_EQ(String(u"12345\uFFFC"), lines[0].first);
+ EXPECT_EQ("678", lines[1].first);
lines = BreakLines(node, LayoutUnit(70));
EXPECT_EQ(2u, lines.size());
- EXPECT_EQ("12345", ToString(lines[0], node));
- EXPECT_EQ(String(u"\uFFFC678"), ToString(lines[1], node));
+ EXPECT_EQ("12345", lines[0].first);
+ EXPECT_EQ(String(u"\uFFFC678"), lines[1].first);
lines = BreakLines(node, LayoutUnit(40));
EXPECT_EQ(3u, lines.size());
- EXPECT_EQ("12345", ToString(lines[0], node));
- EXPECT_EQ(String(u"\uFFFC"), ToString(lines[1], node));
- EXPECT_EQ("678", ToString(lines[2], node));
+ EXPECT_EQ("12345", lines[0].first);
+ EXPECT_EQ(String(u"\uFFFC"), lines[1].first);
+ EXPECT_EQ("678", lines[2].first);
lines = BreakLines(node, LayoutUnit(20));
EXPECT_EQ(3u, lines.size());
- EXPECT_EQ("12345", ToString(lines[0], node));
- EXPECT_EQ(String(u"\uFFFC"), ToString(lines[1], node));
- EXPECT_EQ("678", ToString(lines[2], node));
+ EXPECT_EQ("12345", lines[0].first);
+ EXPECT_EQ(String(u"\uFFFC"), lines[1].first);
+ EXPECT_EQ("678", lines[2].first);
}
TEST_F(NGLineBreakerTest, OverflowMargin) {
@@ -246,21 +248,21 @@ TEST_F(NGLineBreakerTest, OverflowMargin) {
// While "123 456" can fit in a line, "456" has a right margin that cannot
// fit. Since "456" and its right margin is not breakable, "456" should be on
// the next line.
- Vector<NGInlineItemResults> lines;
+ Vector<std::pair<String, unsigned>> lines;
lines = BreakLines(node, LayoutUnit(80));
EXPECT_EQ(3u, lines.size());
- EXPECT_EQ("123", ToString(lines[0], node));
- EXPECT_EQ("456", ToString(lines[1], node));
- DCHECK_EQ(NGInlineItem::kCloseTag, items[lines[1].back().item_index].Type());
- EXPECT_EQ("789", ToString(lines[2], node));
+ EXPECT_EQ("123", lines[0].first);
+ EXPECT_EQ("456", lines[1].first);
+ DCHECK_EQ(NGInlineItem::kCloseTag, items[lines[1].second].Type());
+ EXPECT_EQ("789", lines[2].first);
// Same as above, but this time "456" overflows the line because it is 70px.
lines = BreakLines(node, LayoutUnit(60));
EXPECT_EQ(3u, lines.size());
- EXPECT_EQ("123", ToString(lines[0], node));
- EXPECT_EQ("456", ToString(lines[1], node));
- DCHECK_EQ(NGInlineItem::kCloseTag, items[lines[1].back().item_index].Type());
- EXPECT_EQ("789", ToString(lines[2], node));
+ EXPECT_EQ("123", lines[0].first);
+ EXPECT_EQ("456", lines[1].first);
+ DCHECK_EQ(NGInlineItem::kCloseTag, items[lines[1].second].Type());
+ EXPECT_EQ("789", lines[2].first);
}
TEST_F(NGLineBreakerTest, OverflowAfterSpacesAcrossElements) {
@@ -278,12 +280,12 @@ TEST_F(NGLineBreakerTest, OverflowAfterSpacesAcrossElements) {
<div id=container><span>12345 </span> 1234567890123</div>
)HTML");
- Vector<NGInlineItemResults> lines;
+ Vector<std::pair<String, unsigned>> lines;
lines = BreakLines(node, LayoutUnit(100));
EXPECT_EQ(3u, lines.size());
- EXPECT_EQ("12345 ", ToString(lines[0], node));
- EXPECT_EQ("1234567890", ToString(lines[1], node));
- EXPECT_EQ("123", ToString(lines[2], node));
+ EXPECT_EQ("12345 ", lines[0].first);
+ EXPECT_EQ("1234567890", lines[1].first);
+ EXPECT_EQ("123", lines[2].first);
}
// Tests when the last word in a node wraps, and another node continues.
@@ -299,11 +301,11 @@ TEST_F(NGLineBreakerTest, WrapLastWord) {
<div id=container>AAA AAA AAA <span>BB</span> CC</div>
)HTML");
- Vector<NGInlineItemResults> lines;
+ Vector<std::pair<String, unsigned>> lines;
lines = BreakLines(node, LayoutUnit(100));
EXPECT_EQ(2u, lines.size());
- EXPECT_EQ("AAA AAA", ToString(lines[0], node));
- EXPECT_EQ("AAA BB CC", ToString(lines[1], node));
+ EXPECT_EQ("AAA AAA", lines[0].first);
+ EXPECT_EQ("AAA BB CC", lines[1].first);
}
TEST_F(NGLineBreakerTest, WrapLetterSpacing) {
@@ -319,11 +321,11 @@ TEST_F(NGLineBreakerTest, WrapLetterSpacing) {
<div id=container>Star Wars</div>
)HTML");
- Vector<NGInlineItemResults> lines;
+ Vector<std::pair<String, unsigned>> lines;
lines = BreakLines(node, LayoutUnit(100));
EXPECT_EQ(2u, lines.size());
- EXPECT_EQ("Star", ToString(lines[0], node));
- EXPECT_EQ("Wars", ToString(lines[1], node));
+ EXPECT_EQ("Star", lines[0].first);
+ EXPECT_EQ("Wars", lines[1].first);
}
TEST_F(NGLineBreakerTest, BoundaryInWord) {
@@ -340,20 +342,20 @@ TEST_F(NGLineBreakerTest, BoundaryInWord) {
// The element boundary within "456789" should not cause a break.
// Since "789" does not fit, it should go to the next line along with "456".
- Vector<NGInlineItemResults> lines;
+ Vector<std::pair<String, unsigned>> lines;
lines = BreakLines(node, LayoutUnit(80));
EXPECT_EQ(3u, lines.size());
- EXPECT_EQ("123", ToString(lines[0], node));
- EXPECT_EQ("456789", ToString(lines[1], node));
- EXPECT_EQ("abc", ToString(lines[2], node));
+ EXPECT_EQ("123", lines[0].first);
+ EXPECT_EQ("456789", lines[1].first);
+ EXPECT_EQ("abc", lines[2].first);
// Same as above, but this time "456789" overflows the line because it is
// 60px.
lines = BreakLines(node, LayoutUnit(50));
EXPECT_EQ(3u, lines.size());
- EXPECT_EQ("123", ToString(lines[0], node));
- EXPECT_EQ("456789", ToString(lines[1], node));
- EXPECT_EQ("abc", ToString(lines[2], node));
+ EXPECT_EQ("123", lines[0].first);
+ EXPECT_EQ("456789", lines[1].first);
+ EXPECT_EQ("abc", lines[2].first);
}
TEST_F(NGLineBreakerTest, BoundaryInFirstWord) {
@@ -368,21 +370,21 @@ TEST_F(NGLineBreakerTest, BoundaryInFirstWord) {
<div id=container><span>123</span>456 789</div>
)HTML");
- Vector<NGInlineItemResults> lines;
+ Vector<std::pair<String, unsigned>> lines;
lines = BreakLines(node, LayoutUnit(80));
EXPECT_EQ(2u, lines.size());
- EXPECT_EQ("123456", ToString(lines[0], node));
- EXPECT_EQ("789", ToString(lines[1], node));
+ EXPECT_EQ("123456", lines[0].first);
+ EXPECT_EQ("789", lines[1].first);
lines = BreakLines(node, LayoutUnit(50));
EXPECT_EQ(2u, lines.size());
- EXPECT_EQ("123456", ToString(lines[0], node));
- EXPECT_EQ("789", ToString(lines[1], node));
+ EXPECT_EQ("123456", lines[0].first);
+ EXPECT_EQ("789", lines[1].first);
lines = BreakLines(node, LayoutUnit(20));
EXPECT_EQ(2u, lines.size());
- EXPECT_EQ("123456", ToString(lines[0], node));
- EXPECT_EQ("789", ToString(lines[1], node));
+ EXPECT_EQ("123456", lines[0].first);
+ EXPECT_EQ("789", lines[1].first);
}
struct WhitespaceStateTestData {
@@ -451,7 +453,7 @@ TEST_P(NGWhitespaceStateTest, WhitespaceState) {
R"HTML(</div>
)HTML");
- Vector<NGLineInfo> line_infos = BreakToLineInfo(node, LayoutUnit(50));
+ BreakLines(node, LayoutUnit(50));
EXPECT_EQ(trailing_whitespaces_[0], data.expected);
}
@@ -512,13 +514,11 @@ TEST_P(NGTrailingSpaceWidthTest, TrailingSpaceWidth) {
R"HTML(</div>
)HTML");
- Vector<NGLineInfo> line_infos = BreakToLineInfo(node, LayoutUnit(50));
- const NGLineInfo& line_info = line_infos[0];
- if (line_info.ShouldHangTrailingSpaces()) {
- EXPECT_EQ(line_info.HangWidth(),
- LayoutUnit(10) * data.trailing_space_width);
+ BreakLines(node, LayoutUnit(50), true);
+ if (first_should_hang_trailing_space_) {
+ EXPECT_EQ(first_hang_width_, LayoutUnit(10) * data.trailing_space_width);
} else {
- EXPECT_EQ(line_info.HangWidth(), LayoutUnit());
+ EXPECT_EQ(first_hang_width_, LayoutUnit());
}
}
@@ -535,9 +535,9 @@ TEST_F(NGLineBreakerTest, MinMaxWithTrailingSpaces) {
<div id=container>12345 6789 </div>
)HTML");
- auto size = node.ComputeMinMaxSize(
+ auto size = node.ComputeMinMaxSizes(
WritingMode::kHorizontalTb,
- MinMaxSizeInput(/* percentage_resolution_block_size */ (LayoutUnit())));
+ MinMaxSizesInput(/* percentage_resolution_block_size */ (LayoutUnit())));
EXPECT_EQ(size.min_size, LayoutUnit(60));
EXPECT_EQ(size.max_size, LayoutUnit(110));
}
@@ -559,9 +559,9 @@ TEST_F(NGLineBreakerTest, TableCellWidthCalculationQuirkOutOfFlow) {
GetDocument().SetCompatibilityMode(Document::kQuirksMode);
EXPECT_TRUE(node.GetDocument().InQuirksMode());
- node.ComputeMinMaxSize(
+ node.ComputeMinMaxSizes(
WritingMode::kHorizontalTb,
- MinMaxSizeInput(/* percentage_resolution_block_size */ LayoutUnit()));
+ MinMaxSizesInput(/* percentage_resolution_block_size */ LayoutUnit()));
// Pass if |ComputeMinMaxSize| doesn't hit DCHECK failures.
}
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 0014fe382c4..0306094c1f4 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
@@ -14,112 +14,366 @@
namespace blink {
+namespace {
+
+bool IsLeftMostOffset(const ShapeResult& shape_result, unsigned offset) {
+ if (shape_result.Rtl())
+ return offset == shape_result.NumCharacters();
+ return offset == 0;
+}
+
+bool IsRightMostOffset(const ShapeResult& shape_result, unsigned offset) {
+ if (shape_result.Rtl())
+ return offset == 0;
+ return offset == shape_result.NumCharacters();
+}
+
+} // namespace
+
NGLineTruncator::NGLineTruncator(const NGLineInfo& line_info)
: line_style_(&line_info.LineStyle()),
- available_width_(line_info.AvailableWidth()),
+ available_width_(line_info.AvailableWidth() - line_info.TextIndent()),
line_direction_(line_info.BaseDirection()) {}
-LayoutUnit NGLineTruncator::TruncateLine(
- LayoutUnit line_width,
- NGLineBoxFragmentBuilder::ChildList* line_box,
- NGInlineLayoutStateStack* box_states) {
- // Shape the ellipsis and compute its inline size.
+const ComputedStyle& NGLineTruncator::EllipsisStyle() const {
// The ellipsis is styled according to the line style.
// https://drafts.csswg.org/css-ui/#ellipsing-details
- const ComputedStyle* ellipsis_style = line_style_.get();
- const Font& font = ellipsis_style->GetFont();
- const SimpleFontData* font_data = font.PrimaryFont();
- DCHECK(font_data);
- String ellipsis_text =
- font_data && font_data->GlyphForCharacter(kHorizontalEllipsisCharacter)
+ return *line_style_;
+}
+
+void NGLineTruncator::SetupEllipsis() {
+ const Font& font = EllipsisStyle().GetFont();
+ ellipsis_font_data_ = font.PrimaryFont();
+ DCHECK(ellipsis_font_data_);
+ ellipsis_text_ =
+ ellipsis_font_data_ && ellipsis_font_data_->GlyphForCharacter(
+ kHorizontalEllipsisCharacter)
? String(&kHorizontalEllipsisCharacter, 1)
: String(u"...");
- HarfBuzzShaper shaper(ellipsis_text);
- scoped_refptr<ShapeResultView> ellipsis_shape_result =
+ HarfBuzzShaper shaper(ellipsis_text_);
+ ellipsis_shape_result_ =
ShapeResultView::Create(shaper.Shape(&font, line_direction_).get());
- LayoutUnit ellipsis_width = ellipsis_shape_result->SnappedWidth();
+ ellipsis_width_ = ellipsis_shape_result_->SnappedWidth();
+}
+
+LayoutUnit NGLineTruncator::PlaceEllipsisNextTo(
+ NGLineBoxFragmentBuilder::ChildList* line_box,
+ NGLineBoxFragmentBuilder::Child* ellipsized_child) {
+ // Create the ellipsis, associating it with the ellipsized child.
+ DCHECK(ellipsized_child->HasInFlowFragment());
+ LayoutObject* ellipsized_layout_object =
+ ellipsized_child->PhysicalFragment()->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.
+ LayoutUnit ellipsis_inline_offset =
+ IsLtr(line_direction_)
+ ? ellipsized_child->InlineOffset() + ellipsized_child->inline_size
+ : ellipsized_child->InlineOffset() - ellipsis_width_;
+ LayoutUnit ellpisis_ascent;
+ 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;
+ }
+ line_box->AddChild(builder.ToTextFragment(),
+ LogicalOffset{ellipsis_inline_offset, -ellpisis_ascent},
+ ellipsis_width_, 0);
+ return ellipsis_inline_offset;
+}
+
+wtf_size_t NGLineTruncator::AddTruncatedChild(
+ wtf_size_t source_index,
+ bool leave_one_character,
+ LayoutUnit position,
+ TextDirection edge,
+ NGLineBoxFragmentBuilder::ChildList* line_box,
+ NGInlineLayoutStateStack* box_states) {
+ NGLineBoxFragmentBuilder::ChildList& line = *line_box;
+
+ scoped_refptr<ShapeResult> shape_result =
+ line[source_index].fragment->TextShapeResult()->CreateShapeResult();
+ unsigned text_offset = shape_result->OffsetToFit(position, edge);
+ if (IsLtr(edge) ? IsLeftMostOffset(*shape_result, text_offset)
+ : IsRightMostOffset(*shape_result, text_offset)) {
+ if (!leave_one_character)
+ return kDidNotAddChild;
+ text_offset =
+ shape_result->OffsetToFit(shape_result->PositionForOffset(
+ IsRtl(edge) == shape_result->Rtl()
+ ? 1
+ : shape_result->NumCharacters() - 1),
+ 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();
+ 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) {
+ // 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* ellpisized_child = nullptr;
+ NGLineBoxFragmentBuilder::Child* ellipsized_child = nullptr;
scoped_refptr<const NGPhysicalTextFragment> truncated_fragment;
if (IsLtr(line_direction_)) {
NGLineBoxFragmentBuilder::Child* 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,
+ if (EllipsizeChild(line_width, ellipsis_width_, &child == first_child,
&child, &truncated_fragment)) {
- ellpisized_child = &child;
+ ellipsized_child = &child;
break;
}
}
} else {
NGLineBoxFragmentBuilder::Child* first_child = line_box->LastInFlowChild();
for (auto& child : *line_box) {
- if (EllipsizeChild(line_width, ellipsis_width, &child == first_child,
+ if (EllipsizeChild(line_width, ellipsis_width_, &child == first_child,
&child, &truncated_fragment)) {
- ellpisized_child = &child;
+ ellipsized_child = &child;
break;
}
}
}
// Abort if ellipsis could not be placed.
- if (!ellpisized_child)
+ if (!ellipsized_child)
return line_width;
// Truncate the text fragment if needed.
if (truncated_fragment) {
- DCHECK(ellpisized_child->fragment);
+ DCHECK(ellipsized_child->fragment);
// In order to preserve layout information before truncated, hide the
// original fragment and insert a truncated one.
- size_t child_index_to_truncate = ellpisized_child - line_box->begin();
+ size_t child_index_to_truncate = ellipsized_child - line_box->begin();
line_box->InsertChild(child_index_to_truncate + 1);
box_states->ChildInserted(child_index_to_truncate + 1);
NGLineBoxFragmentBuilder::Child* child_to_truncate =
&(*line_box)[child_index_to_truncate];
- ellpisized_child = std::next(child_to_truncate);
- *ellpisized_child = *child_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, ellpisized_child->inline_size);
+ DCHECK_LE(new_inline_size, ellipsized_child->inline_size);
if (UNLIKELY(IsRtl(line_direction_))) {
- ellpisized_child->offset.inline_offset +=
- ellpisized_child->inline_size - new_inline_size;
+ ellipsized_child->rect.offset.inline_offset +=
+ ellipsized_child->inline_size - new_inline_size;
}
- ellpisized_child->inline_size = new_inline_size;
- ellpisized_child->fragment = std::move(truncated_fragment);
+ ellipsized_child->inline_size = new_inline_size;
+ ellipsized_child->fragment = std::move(truncated_fragment);
}
// Create the ellipsis, associating it with the ellipsized child.
- LayoutObject* ellipsized_layout_object =
- ellpisized_child->PhysicalFragment()->GetMutableLayoutObject();
- DCHECK(ellipsized_layout_object && ellipsized_layout_object->IsInline() &&
- (ellipsized_layout_object->IsText() ||
- ellipsized_layout_object->IsAtomicInlineLevel()));
- NGTextFragmentBuilder builder(line_style_->GetWritingMode());
- builder.SetText(ellipsized_layout_object, ellipsis_text, ellipsis_style,
- true /* is_ellipsis_style */,
- std::move(ellipsis_shape_result));
-
- // Now the offset of the ellpisis is determined. Place the ellpisis into the
- // line box.
LayoutUnit ellipsis_inline_offset =
- IsLtr(line_direction_)
- ? ellpisized_child->offset.inline_offset +
- ellpisized_child->inline_size
- : ellpisized_child->offset.inline_offset - ellipsis_width;
- FontBaseline baseline_type = line_style_->GetFontBaseline();
- NGLineHeightMetrics ellipsis_metrics(font_data->GetFontMetrics(),
- baseline_type);
- line_box->AddChild(
- builder.ToTextFragment(),
- LogicalOffset{ellipsis_inline_offset, -ellipsis_metrics.ascent},
- ellipsis_width, 0);
- return std::max(ellipsis_inline_offset + ellipsis_width, line_width);
+ PlaceEllipsisNextTo(line_box, ellipsized_child);
+ return std::max(ellipsis_inline_offset + ellipsis_width_, line_width);
+}
+
+// This function was designed to work only with <input type=file>.
+// We assume the line box contains:
+// (Optional) children without in-flow fragments
+// Children with in-flow fragments, and
+// (Optional) children without in-flow fragments
+// in this order, and the children with in-flow fragments have no padding,
+// no border, and no margin.
+// Children with IsPlaceholder() can appear anywhere.
+LayoutUnit NGLineTruncator::TruncateLineInTheMiddle(
+ LayoutUnit line_width,
+ NGLineBoxFragmentBuilder::ChildList* line_box,
+ NGInlineLayoutStateStack* box_states) {
+ // Shape the ellipsis and compute its inline size.
+ SetupEllipsis();
+
+ NGLineBoxFragmentBuilder::ChildList& 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())
+ continue;
+ if (child.HasOutOfFlowFragment() || !child.fragment ||
+ !child.fragment->TextShapeResult()) {
+ if (initial_index_right != kNotFound)
+ break;
+ continue;
+ }
+ if (initial_index_left == kNotFound)
+ initial_index_left = i;
+ initial_index_right = i;
+ }
+ // There are no truncatable children.
+ if (initial_index_left == kNotFound)
+ return line_width;
+ DCHECK_NE(initial_index_right, kNotFound);
+ DCHECK(line[initial_index_left].HasInFlowFragment());
+ DCHECK(line[initial_index_right].HasInFlowFragment());
+
+ // line[]:
+ // s s s p f f p f f s s
+ // ^ ^
+ // initial_index_left |
+ // initial_index_right
+ // s: child without in-flow fragment
+ // p: placeholder child
+ // f: child with in-flow fragment
+
+ const LayoutUnit static_width_left = line[initial_index_left].InlineOffset();
+ LayoutUnit static_width_right = LayoutUnit(0);
+ for (wtf_size_t i = initial_index_right + 1; i < line.size(); ++i)
+ static_width_right += line[i].inline_size;
+ const LayoutUnit available_width =
+ available_width_ - static_width_left - static_width_right;
+ if (available_width <= ellipsis_width_)
+ return line_width;
+ LayoutUnit available_width_left = (available_width - ellipsis_width_) / 2;
+ LayoutUnit available_width_right = available_width_left;
+
+ // Children for ellipsis and truncated fragments will have index which
+ // is >= new_child_start.
+ const wtf_size_t new_child_start = line.size();
+
+ wtf_size_t index_left = initial_index_left;
+ wtf_size_t index_right = initial_index_right;
+
+ if (IsLtr(line_direction_)) {
+ // Find truncation point at the left, truncate, and add an ellipsis.
+ while (available_width_left >= line[index_left].inline_size)
+ available_width_left -= line[index_left++].inline_size;
+ DCHECK_LE(index_left, index_right);
+ DCHECK(!line[index_left].IsPlaceholder());
+ wtf_size_t new_index = AddTruncatedChild(
+ index_left, index_left == initial_index_left, available_width_left,
+ TextDirection::kLtr, line_box, box_states);
+ if (new_index == kDidNotAddChild) {
+ DCHECK_GT(index_left, initial_index_left);
+ DCHECK_GT(index_left, 0u);
+ wtf_size_t i = index_left;
+ while (!line[--i].HasInFlowFragment())
+ DCHECK(line[i].IsPlaceholder());
+ PlaceEllipsisNextTo(line_box, &line[i]);
+ available_width_right += available_width_left;
+ } else {
+ PlaceEllipsisNextTo(line_box, &line[new_index]);
+ available_width_right +=
+ available_width_left - line[new_index].inline_size;
+ }
+
+ // Find truncation point at the right.
+ while (available_width_right >= line[index_right].inline_size)
+ available_width_right -= line[index_right--].inline_size;
+ LayoutUnit new_modified_right_offset =
+ line[line.size() - 1].InlineOffset() + ellipsis_width_;
+ DCHECK_LE(index_left, index_right);
+ DCHECK(!line[index_right].IsPlaceholder());
+ if (available_width_right > 0) {
+ new_index = AddTruncatedChild(
+ index_right, false,
+ line[index_right].inline_size - available_width_right,
+ TextDirection::kRtl, line_box, box_states);
+ if (new_index != kDidNotAddChild) {
+ line[new_index].rect.offset.inline_offset = new_modified_right_offset;
+ new_modified_right_offset += line[new_index].inline_size;
+ }
+ }
+ // Shift unchanged children at the right of the truncated child.
+ // It's ok to modify existing children's offsets because they are not
+ // web-exposed.
+ LayoutUnit offset_diff = line[index_right].InlineOffset() +
+ line[index_right].inline_size -
+ new_modified_right_offset;
+ for (wtf_size_t i = index_right + 1; i < new_child_start; ++i)
+ line[i].rect.offset.inline_offset -= offset_diff;
+ line_width -= offset_diff;
+
+ } else {
+ // Find truncation point at the right, truncate, and add an ellipsis.
+ while (available_width_right >= line[index_right].inline_size)
+ available_width_right -= line[index_right--].inline_size;
+ DCHECK_LE(index_left, index_right);
+ DCHECK(!line[index_right].IsPlaceholder());
+ wtf_size_t new_index =
+ AddTruncatedChild(index_right, index_right == initial_index_right,
+ line[index_right].inline_size - available_width_right,
+ TextDirection::kRtl, line_box, box_states);
+ if (new_index == kDidNotAddChild) {
+ DCHECK_LT(index_right, initial_index_right);
+ wtf_size_t i = index_right;
+ while (!line[++i].HasInFlowFragment())
+ DCHECK(line[i].IsPlaceholder());
+ PlaceEllipsisNextTo(line_box, &line[i]);
+ available_width_left += available_width_right;
+ } else {
+ line[new_index].rect.offset.inline_offset +=
+ line[index_right].inline_size - line[new_index].inline_size;
+ PlaceEllipsisNextTo(line_box, &line[new_index]);
+ available_width_left +=
+ available_width_right - line[new_index].inline_size;
+ }
+ LayoutUnit ellipsis_offset = line[line.size() - 1].InlineOffset();
+
+ // Find truncation point at the left.
+ while (available_width_left >= line[index_left].inline_size)
+ available_width_left -= line[index_left++].inline_size;
+ DCHECK_LE(index_left, index_right);
+ DCHECK(!line[index_left].IsPlaceholder());
+ if (available_width_left > 0) {
+ new_index = AddTruncatedChild(index_left, false, available_width_left,
+ TextDirection::kLtr, line_box, box_states);
+ if (new_index != kDidNotAddChild) {
+ line[new_index].rect.offset.inline_offset =
+ ellipsis_offset - line[new_index].inline_size;
+ }
+ }
+
+ // Shift unchanged children at the left of the truncated child.
+ // It's ok to modify existing children's offsets because they are not
+ // web-exposed.
+ LayoutUnit offset_diff =
+ line[line.size() - 1].InlineOffset() - line[index_left].InlineOffset();
+ for (wtf_size_t i = index_left; i > 0; --i)
+ line[i - 1].rect.offset.inline_offset += offset_diff;
+ line_width -= offset_diff;
+ }
+ // Hide left/right truncated children and children between them.
+ for (wtf_size_t i = index_left; i <= index_right; ++i) {
+ if (line[i].HasInFlowFragment())
+ HideChild(&line[i]);
+ }
+
+ return line_width;
}
// Hide this child from being painted. Leaves a hidden fragment so that layout
@@ -147,7 +401,7 @@ void NGLineTruncator::HideChild(NGLineBoxFragmentBuilder::Child* child) {
// 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->offset.inline_offset = LayoutUnit::NearlyMax();
+ child->rect.offset.inline_offset = LayoutUnit::NearlyMax();
return;
}
@@ -182,8 +436,8 @@ bool NGLineTruncator::EllipsizeChild(
// Can't place ellipsis if this child is completely outside of the box.
LayoutUnit child_inline_offset =
IsLtr(line_direction_)
- ? child->offset.inline_offset
- : line_width - (child->offset.inline_offset + child->inline_size);
+ ? child->InlineOffset()
+ : line_width - (child->InlineOffset() + child->inline_size);
LayoutUnit space_for_child = available_width_ - child_inline_offset;
if (space_for_child <= 0) {
// This child is outside of the content box, but we still need to hide it.
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 0c507997ad2..c65fa3ce5a4 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
@@ -33,7 +33,40 @@ class CORE_EXPORT NGLineTruncator final {
NGLineBoxFragmentBuilder::ChildList* line_box,
NGInlineLayoutStateStack* box_states);
+ LayoutUnit TruncateLineInTheMiddle(
+ LayoutUnit line_width,
+ NGLineBoxFragmentBuilder::ChildList* line_box,
+ NGInlineLayoutStateStack* box_states);
+
private:
+ const ComputedStyle& EllipsisStyle() const;
+
+ // Initialize four ellipsis_*_ data members.
+ void SetupEllipsis();
+
+ // Add a child for ellipsis next to |ellipsized_child|.
+ LayoutUnit PlaceEllipsisNextTo(
+ NGLineBoxFragmentBuilder::ChildList* line_box,
+ NGLineBoxFragmentBuilder::Child* ellipsized_child);
+
+ static constexpr wtf_size_t kDidNotAddChild = WTF::kNotFound;
+ // Add a child with truncated text of (*line_box)[source_index].
+ // This function returns the index of the new child.
+ // If the truncated text is empty, kDidNotAddChild is returned.
+ //
+ // |leave_one_character| - Force to leave at least one character regardless of
+ // |position|.
+ // |position| and |edge| - Indicate truncation point and direction.
+ // If |edge| is TextDirection::kLtr, the left side of
+ // |position| will be copied to the new child.
+ // Otherwise, the right side of |position| will be
+ // copied.
+ wtf_size_t AddTruncatedChild(wtf_size_t source_index,
+ bool leave_one_character,
+ LayoutUnit position,
+ TextDirection edge,
+ NGLineBoxFragmentBuilder::ChildList* line_box,
+ NGInlineLayoutStateStack* box_states);
bool EllipsizeChild(
LayoutUnit line_width,
LayoutUnit ellipsis_width,
@@ -50,6 +83,15 @@ class CORE_EXPORT NGLineTruncator final {
scoped_refptr<const ComputedStyle> line_style_;
LayoutUnit available_width_;
TextDirection line_direction_;
+
+ // The following 3 data members are available after SetupEllipsis().
+ const SimpleFontData* ellipsis_font_data_;
+ String ellipsis_text_;
+ LayoutUnit ellipsis_width_;
+
+ // This data member is available between SetupEllipsis() and
+ // PlaceEllipsisNextTo().
+ scoped_refptr<ShapeResultView> ellipsis_shape_result_;
};
} // namespace blink
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 9e5ef9dc4aa..a17617b0d31 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
@@ -123,8 +123,6 @@ void NGOffsetMappingUnit::AssertValid() const {
#endif
}
-NGOffsetMappingUnit::~NGOffsetMappingUnit() = default;
-
const Node* NGOffsetMappingUnit::AssociatedNode() const {
if (const auto* text_fragment = ToLayoutTextFragmentOrNull(layout_object_))
return text_fragment->AssociatedTextNode();
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 40ab1e60d63..13b2eb52bbb 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
@@ -47,7 +47,6 @@ class CORE_EXPORT NGOffsetMappingUnit {
unsigned dom_end,
unsigned text_content_start,
unsigned text_content_end);
- ~NGOffsetMappingUnit();
// Returns associated node for this unit or null if this unit is associated
// to generated content.
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 206226f2b87..3e2c8f22e7d 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
@@ -97,7 +97,6 @@ class NGOffsetMappingTest : public NGLayoutTest {
void SetUp() override {
NGLayoutTest::SetUp();
style_ = ComputedStyle::Create();
- style_->GetFont().Update(nullptr);
}
void SetupHtml(const char* id, String html) {
@@ -1496,7 +1495,8 @@ TEST_P(NGOffsetMappingGetterTest, Get) {
// For the purpose of this test, ensure this is laid out by each layout
// engine.
- DCHECK_EQ(layout_block_flow->IsLayoutNGMixin(), GetParam());
+ DCHECK_EQ(layout_block_flow->IsLayoutNGMixin(),
+ RuntimeEnabledFeatures::LayoutNGEnabled());
const NGOffsetMapping* mapping =
NGInlineNode::GetOffsetMapping(layout_block_flow);
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 cab0866ce4c..ac726c4dea4 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
@@ -6,9 +6,11 @@
#include "third_party/blink/renderer/core/editing/editing_utilities.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_cursor.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_fragment_traversal.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_fragment.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_relative_utils.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
@@ -37,11 +39,12 @@ NGPhysicalLineBoxFragment::Create(NGLineBoxFragmentBuilder* builder) {
sizeof(NGPhysicalLineBoxFragment) +
builder->children_.size() * sizeof(NGLink),
::WTF::GetStringWithTypeName<NGPhysicalLineBoxFragment>());
- new (data) NGPhysicalLineBoxFragment(builder);
+ new (data) NGPhysicalLineBoxFragment(PassKey(), builder);
return base::AdoptRef(static_cast<NGPhysicalLineBoxFragment*>(data));
}
NGPhysicalLineBoxFragment::NGPhysicalLineBoxFragment(
+ PassKey key,
NGLineBoxFragmentBuilder* builder)
: NGPhysicalContainerFragment(builder,
builder->GetWritingMode(),
@@ -51,48 +54,51 @@ NGPhysicalLineBoxFragment::NGPhysicalLineBoxFragment(
metrics_(builder->metrics_) {
// A line box must have a metrics unless it's an empty line box.
DCHECK(!metrics_.IsEmpty() || IsEmptyLineBox());
- base_direction_ = static_cast<unsigned>(builder->base_direction_);
+ base_or_resolved_direction_ = static_cast<unsigned>(builder->base_direction_);
has_hanging_ = builder->hang_inline_size_ != 0;
has_propagated_descendants_ = has_floating_descendants_for_paint_ ||
HasOutOfFlowPositionedDescendants() ||
builder->unpositioned_list_marker_;
}
-NGLineHeightMetrics NGPhysicalLineBoxFragment::BaselineMetrics(
- FontBaseline) const {
+NGLineHeightMetrics NGPhysicalLineBoxFragment::BaselineMetrics() const {
// TODO(kojii): Computing other baseline types than the used one is not
// implemented yet.
// TODO(kojii): We might need locale/script to look up OpenType BASE table.
return metrics_;
}
+namespace {
+
+// Include the inline-size of the line-box in the 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))
+ inline_rect.size.width = rect.size.width;
+ else
+ inline_rect.size.height = rect.size.height;
+ overflow->UniteEvenIfEmpty(inline_rect);
+}
+
+} // namespace
+
PhysicalRect NGPhysicalLineBoxFragment::ScrollableOverflow(
- const LayoutObject* container,
- const ComputedStyle* container_style,
- PhysicalSize container_physical_size) const {
- WritingMode container_writing_mode = container_style->GetWritingMode();
- TextDirection container_direction = container_style->Direction();
+ const NGPhysicalBoxFragment& container,
+ const ComputedStyle& container_style) const {
+ const WritingMode container_writing_mode = container_style.GetWritingMode();
+ const TextDirection container_direction = container_style.Direction();
PhysicalRect overflow;
for (const auto& child : Children()) {
PhysicalRect child_scroll_overflow =
child->ScrollableOverflowForPropagation(container);
child_scroll_overflow.offset += child.Offset();
- // Chop the hanging part from scrollable overflow. Children overflow in
- // inline direction should hang, which should not cause scroll.
- // TODO(kojii): Should move to text fragment to make this more accurate.
if (UNLIKELY(has_hanging_ && !child->IsFloatingOrOutOfFlowPositioned())) {
- if (IsHorizontalWritingMode(container_writing_mode)) {
- if (child_scroll_overflow.offset.left < 0)
- child_scroll_overflow.offset.left = LayoutUnit();
- if (child_scroll_overflow.Right() > Size().width)
- child_scroll_overflow.ShiftRightEdgeTo(Size().width);
- } else {
- if (child_scroll_overflow.offset.top < 0)
- child_scroll_overflow.offset.top = LayoutUnit();
- if (child_scroll_overflow.Bottom() > Size().height)
- child_scroll_overflow.ShiftBottomEdgeTo(Size().height);
- }
+ AdjustScrollableOverflowForHanging(LocalRect(), container_writing_mode,
+ &child_scroll_overflow);
}
// For implementation reasons, text nodes inherit computed style from their
@@ -102,18 +108,35 @@ PhysicalRect NGPhysicalLineBoxFragment::ScrollableOverflow(
if (!child->IsText()) {
child_scroll_overflow.offset +=
ComputeRelativeOffset(child->Style(), container_writing_mode,
- container_direction, container_physical_size);
+ container_direction, container.Size());
}
overflow.Unite(child_scroll_overflow);
}
// Make sure we include the inline-size of the line-box in the overflow.
- PhysicalRect rect;
- if (IsHorizontalWritingMode(container_writing_mode))
- rect.size.width = Size().width;
- else
- rect.size.height = Size().height;
- overflow.UniteEvenIfEmpty(rect);
+ AddInlineSizeToOverflow(LocalRect(), container_writing_mode, &overflow);
+
+ return overflow;
+}
+
+PhysicalRect NGPhysicalLineBoxFragment::ScrollableOverflowForLine(
+ const NGPhysicalBoxFragment& container,
+ const ComputedStyle& container_style,
+ const NGFragmentItem& line,
+ const NGInlineCursor& cursor) const {
+ DCHECK(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
+ DCHECK_EQ(&line, cursor.CurrentItem());
+ DCHECK_EQ(line.LineBoxFragment(), this);
+
+ PhysicalRect overflow;
+ AddScrollableOverflowForInlineChild(container, container_style, line,
+ has_hanging_, cursor, &overflow);
+
+ // Make sure we include the inline-size of the line-box in the overflow.
+ // Note, the bottom half-leading should not be included. crbug.com/996847
+ const WritingMode container_writing_mode = container_style.GetWritingMode();
+ AddInlineSizeToOverflow(line.RectInContainerBlock(), container_writing_mode,
+ &overflow);
return overflow;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h
index 6ee0a0a81fb..044007e1cde 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h
@@ -13,6 +13,7 @@
namespace blink {
+class NGFragmentItem;
class NGLineBoxFragmentBuilder;
class CORE_EXPORT NGPhysicalLineBoxFragment final
@@ -31,6 +32,9 @@ class CORE_EXPORT NGPhysicalLineBoxFragment final
static scoped_refptr<const NGPhysicalLineBoxFragment> Create(
NGLineBoxFragmentBuilder* builder);
+ using PassKey = util::PassKey<NGPhysicalLineBoxFragment>;
+ NGPhysicalLineBoxFragment(PassKey, NGLineBoxFragmentBuilder* builder);
+
~NGPhysicalLineBoxFragment() {
for (const NGLink& child : Children())
child.fragment->Release();
@@ -50,19 +54,22 @@ class CORE_EXPORT NGPhysicalLineBoxFragment final
// This may be different from the direction of the container box when
// first-line style is used, or when 'unicode-bidi: plaintext' is used.
TextDirection BaseDirection() const {
- return static_cast<TextDirection>(base_direction_);
+ return static_cast<TextDirection>(base_or_resolved_direction_);
}
- // Compute baseline for the specified baseline type.
- NGLineHeightMetrics BaselineMetrics(FontBaseline) const;
+ // Compute the baseline metrics for this linebox.
+ NGLineHeightMetrics BaselineMetrics() const;
// Scrollable overflow. including contents, in the local coordinate.
// |ScrollableOverflow| is not precomputed/cached because it cannot be
// computed when LineBox is generated because it needs container dimensions
// to resolve relative position of its children.
- PhysicalRect ScrollableOverflow(const LayoutObject* container,
- const ComputedStyle* container_style,
- PhysicalSize container_physical_size) const;
+ PhysicalRect ScrollableOverflow(const NGPhysicalBoxFragment& container,
+ const ComputedStyle& container_style) const;
+ PhysicalRect ScrollableOverflowForLine(const NGPhysicalBoxFragment& container,
+ const ComputedStyle& container_style,
+ const NGFragmentItem& line,
+ const NGInlineCursor& cursor) const;
// Whether the content soft-wraps to the next line.
bool HasSoftWrapToNextLine() const;
@@ -72,8 +79,6 @@ class CORE_EXPORT NGPhysicalLineBoxFragment final
const LayoutObject* ContainerLayoutObject() const { return layout_object_; }
private:
- NGPhysicalLineBoxFragment(NGLineBoxFragmentBuilder* builder);
-
NGLineHeightMetrics metrics_;
NGLink children_[];
};
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 834188b7add..a15a5429402 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
@@ -32,6 +32,7 @@ static_assert(sizeof(NGPhysicalTextFragment) ==
} // anonymous namespace
NGPhysicalTextFragment::NGPhysicalTextFragment(
+ PassKey key,
const NGPhysicalTextFragment& source,
unsigned start_offset,
unsigned end_offset,
@@ -45,25 +46,29 @@ NGPhysicalTextFragment::NGPhysicalTextFragment(
kFragmentText,
source.TextType()),
text_(source.text_),
- start_offset_(start_offset),
- end_offset_(end_offset),
+ text_offset_(start_offset, end_offset),
shape_result_(std::move(shape_result)) {
- DCHECK_GE(start_offset_, source.StartOffset());
- DCHECK_LE(end_offset_, source.EndOffset());
+ DCHECK_GE(text_offset_.start, source.StartOffset());
+ DCHECK_LE(text_offset_.end, source.EndOffset());
DCHECK(shape_result_ || IsFlowControl()) << *this;
- is_generated_text_ = source.is_generated_text_;
+ base_or_resolved_direction_ = source.base_or_resolved_direction_;
+ is_generated_text_or_math_fraction_ =
+ source.is_generated_text_or_math_fraction_;
ink_overflow_computed_ = false;
+ is_first_for_node_ = source.is_first_for_node_;
}
NGPhysicalTextFragment::NGPhysicalTextFragment(NGTextFragmentBuilder* builder)
: NGPhysicalFragment(builder, kFragmentText, builder->text_type_),
text_(builder->text_),
- start_offset_(builder->start_offset_),
- end_offset_(builder->end_offset_),
+ text_offset_({builder->start_offset_, builder->end_offset_}),
shape_result_(std::move(builder->shape_result_)) {
DCHECK(shape_result_ || IsFlowControl()) << *this;
- is_generated_text_ = builder->IsGeneratedText();
+ base_or_resolved_direction_ =
+ static_cast<unsigned>(builder->ResolvedDirection());
+ is_generated_text_or_math_fraction_ = builder->IsGeneratedText();
ink_overflow_computed_ = false;
+ is_first_for_node_ = builder->is_first_for_node_;
}
LayoutUnit NGPhysicalTextFragment::InlinePositionForOffset(
@@ -214,8 +219,9 @@ scoped_refptr<const NGPhysicalTextFragment> NGPhysicalTextFragment::TrimText(
DCHECK_LE(new_end_offset, EndOffset());
scoped_refptr<ShapeResultView> new_shape_result = ShapeResultView::Create(
shape_result_.get(), new_start_offset, new_end_offset);
- return base::AdoptRef(new NGPhysicalTextFragment(
- *this, new_start_offset, new_end_offset, std::move(new_shape_result)));
+ return base::AdoptRef(
+ new NGPhysicalTextFragment(PassKey(), *this, new_start_offset,
+ new_end_offset, std::move(new_shape_result)));
}
unsigned NGPhysicalTextFragment::TextOffsetForPoint(
@@ -263,10 +269,4 @@ UBiDiLevel NGPhysicalTextFragment::BidiLevel() const {
return containing_item->BidiLevel();
}
-TextDirection NGPhysicalTextFragment::ResolvedDirection() const {
- if (TextShapeResult())
- return TextShapeResult()->Direction();
- return DirectionFromLevel(BidiLevel());
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h
index 7d0adc9bfce..dbd1bae97af 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_PHYSICAL_TEXT_FRAGMENT_H_
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/layout/ng/inline/ng_text_end_effect.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_text_offset.h"
#include "third_party/blink/renderer/core/layout/ng/ng_ink_overflow.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h"
#include "third_party/blink/renderer/platform/fonts/ng_text_fragment_paint_info.h"
@@ -45,10 +45,18 @@ class CORE_EXPORT NGPhysicalTextFragment final : public NGPhysicalFragment {
NGPhysicalTextFragment(NGTextFragmentBuilder*);
+ using PassKey = util::PassKey<NGPhysicalTextFragment>;
+ // For use by TrimText only
+ NGPhysicalTextFragment(PassKey,
+ const NGPhysicalTextFragment& source,
+ unsigned start_offset,
+ unsigned end_offset,
+ scoped_refptr<const ShapeResultView> shape_result);
+
NGTextType TextType() const { return static_cast<NGTextType>(sub_type_); }
// Returns true if the text is generated (from, e.g., list marker,
// pseudo-element, ...) instead of from a DOM text node.
- bool IsGeneratedText() const { return is_generated_text_; }
+ bool IsGeneratedText() const { return is_generated_text_or_math_fraction_; }
// True if this is a forced line break.
bool IsLineBreak() const { return TextType() == kForcedLineBreak; }
// True if this is not for painting; i.e., a forced line break, a tabulation,
@@ -63,18 +71,19 @@ class CORE_EXPORT NGPhysicalTextFragment final : public NGPhysicalFragment {
bool IsSymbolMarker() const { return TextType() == kSymbolMarker; }
- unsigned TextLength() const { return end_offset_ - start_offset_; }
- StringView Text() const {
- return StringView(text_, start_offset_, TextLength());
- }
const String& TextContent() const { return text_; }
// ShapeResult may be nullptr if |IsFlowControl()|.
const ShapeResultView* TextShapeResult() const { return shape_result_.get(); }
// Start/end offset to the text of the block container.
- unsigned StartOffset() const { return start_offset_; }
- unsigned EndOffset() const { return end_offset_; }
+ const NGTextOffset& TextOffset() const { return text_offset_; }
+ unsigned StartOffset() const { return text_offset_.start; }
+ unsigned EndOffset() const { return text_offset_.end; }
+ unsigned TextLength() const { return text_offset_.Length(); }
+ StringView Text() const {
+ return StringView(text_, text_offset_.start, TextLength());
+ }
WritingMode GetWritingMode() const { return Style().GetWritingMode(); }
bool IsHorizontal() const {
@@ -113,7 +122,9 @@ class CORE_EXPORT NGPhysicalTextFragment final : public NGPhysicalFragment {
unsigned TextOffsetForPoint(const PhysicalOffset&) const;
UBiDiLevel BidiLevel() const;
- TextDirection ResolvedDirection() const;
+ TextDirection ResolvedDirection() const {
+ return static_cast<TextDirection>(base_or_resolved_direction_);
+ }
// Compute line-relative coordinates for given offsets, this is not
// flow-relative:
@@ -123,12 +134,6 @@ class CORE_EXPORT NGPhysicalTextFragment final : public NGPhysicalFragment {
unsigned end_offset) const;
private:
- // For use by TrimText only
- NGPhysicalTextFragment(const NGPhysicalTextFragment& source,
- unsigned start_offset,
- unsigned end_offset,
- scoped_refptr<const ShapeResultView> shape_result);
-
LayoutUnit InlinePositionForOffset(unsigned offset,
LayoutUnit (*round)(float),
AdjustMidCluster) const;
@@ -140,8 +145,7 @@ class CORE_EXPORT NGPhysicalTextFragment final : public NGPhysicalFragment {
const String text_;
// Start and end offset of the parent block text.
- const unsigned start_offset_;
- const unsigned end_offset_;
+ const NGTextOffset text_offset_;
const scoped_refptr<const ShapeResultView> shape_result_;
// Fragments are immutable but allow certain expensive data, specifically ink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment_test.cc
index 7de65ceb791..ebb2a5abd83 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment_test.cc
@@ -43,6 +43,8 @@ class NGPhysicalTextFragmentTest : public NGLayoutTest {
};
TEST_F(NGPhysicalTextFragmentTest, LocalRect) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
LoadAhem();
SetBodyInnerHTML(R"HTML(
<style>
@@ -59,6 +61,8 @@ TEST_F(NGPhysicalTextFragmentTest, LocalRect) {
}
TEST_F(NGPhysicalTextFragmentTest, LocalRectRTL) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
LoadAhem();
SetBodyInnerHTML(R"HTML(
<style>
@@ -81,6 +85,8 @@ TEST_F(NGPhysicalTextFragmentTest, LocalRectRTL) {
}
TEST_F(NGPhysicalTextFragmentTest, LocalRectVLR) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
LoadAhem();
SetBodyInnerHTML(R"HTML(
<style>
@@ -98,6 +104,8 @@ TEST_F(NGPhysicalTextFragmentTest, LocalRectVLR) {
}
TEST_F(NGPhysicalTextFragmentTest, LocalRectVRL) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
LoadAhem();
SetBodyInnerHTML(R"HTML(
<style>
@@ -115,6 +123,8 @@ TEST_F(NGPhysicalTextFragmentTest, LocalRectVRL) {
}
TEST_F(NGPhysicalTextFragmentTest, NormalTextIsNotAnonymousText) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
SetBodyInnerHTML("<div id=div>text</div>");
auto text_fragments = CollectTextFragmentsInContainer("div");
@@ -125,6 +135,8 @@ TEST_F(NGPhysicalTextFragmentTest, NormalTextIsNotAnonymousText) {
}
TEST_F(NGPhysicalTextFragmentTest, FirstLetterIsNotAnonymousText) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
SetBodyInnerHTML(
"<style>::first-letter {color:red}</style>"
"<div id=div>text</div>");
@@ -139,6 +151,8 @@ TEST_F(NGPhysicalTextFragmentTest, FirstLetterIsNotAnonymousText) {
}
TEST_F(NGPhysicalTextFragmentTest, BeforeAndAfterAreAnonymousText) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
SetBodyInnerHTML(
"<style>::before{content:'x'} ::after{content:'x'}</style>"
"<div id=div>text</div>");
@@ -155,6 +169,8 @@ TEST_F(NGPhysicalTextFragmentTest, BeforeAndAfterAreAnonymousText) {
}
TEST_F(NGPhysicalTextFragmentTest, Ellipsis) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
LoadAhem();
SetBodyInnerHTML(R"HTML(
<style>
@@ -191,6 +207,8 @@ TEST_F(NGPhysicalTextFragmentTest, Ellipsis) {
}
TEST_F(NGPhysicalTextFragmentTest, ListMarkerIsGeneratedText) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
SetBodyInnerHTML(
"<ol style='list-style-position:inside'>"
"<li id=list>text</li>"
@@ -206,6 +224,8 @@ TEST_F(NGPhysicalTextFragmentTest, ListMarkerIsGeneratedText) {
}
TEST_F(NGPhysicalTextFragmentTest, SoftHyphen) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
LoadAhem();
SetBodyInnerHTML(R"HTML(
<style>
@@ -234,6 +254,8 @@ TEST_F(NGPhysicalTextFragmentTest, SoftHyphen) {
}
TEST_F(NGPhysicalTextFragmentTest, QuotationMarksAreAnonymousText) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
SetBodyInnerHTML("<div id=div><q>text</q></div>");
auto text_fragments = CollectTextFragmentsInContainer("div");
@@ -248,6 +270,8 @@ TEST_F(NGPhysicalTextFragmentTest, QuotationMarksAreAnonymousText) {
}
TEST_F(NGPhysicalTextFragmentTest, TextOffsetForPointForTabulation) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
LoadAhem();
SetBodyInnerHTML(R"HTML(
<style>
@@ -270,6 +294,8 @@ TEST_F(NGPhysicalTextFragmentTest, TextOffsetForPointForTabulation) {
}
TEST_F(NGPhysicalTextFragmentTest, TextOffsetForPointForTabulationRtl) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
LoadAhem();
SetBodyInnerHTML(R"HTML(
<style>
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_end_effect.h b/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_end_effect.h
deleted file mode 100644
index 0dbc9f84a77..00000000000
--- a/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_text_end_effect.h
+++ /dev/null
@@ -1,20 +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_INLINE_NG_TEXT_END_EFFECT_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_TEXT_END_EFFECT_H_
-
-namespace blink {
-
-// Effects at the end of text fragments.
-enum class NGTextEndEffect {
- kNone,
- kHyphen,
-
- // When adding new values, ensure NGPhysicalTextFragment has enough bits.
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_TEXT_END_EFFECT_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 ea7efc7acb4..0b85af665ca 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
@@ -36,6 +36,7 @@ void NGTextFragmentBuilder::SetItem(
text_ = items_data.text_content;
start_offset_ = item_result->start_offset;
end_offset_ = item_result->end_offset;
+ resolved_direction_ = item_result->item->Direction();
SetStyle(item_result->item->Style(), item_result->item->StyleVariant());
size_ = {item_result->inline_size, line_height};
shape_result_ = std::move(item_result->shape_result);
@@ -56,6 +57,7 @@ void NGTextFragmentBuilder::SetText(
text_ = text;
start_offset_ = shape_result->StartIndex();
end_offset_ = shape_result->EndIndex();
+ resolved_direction_ = shape_result->Direction();
SetStyle(style, is_ellipsis_style ? NGStyleVariant::kEllipsis
: NGStyleVariant::kStandard);
size_ = {shape_result->SnappedWidth(),
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 422fcd3aa3e..3cb38c1af32 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
@@ -8,7 +8,6 @@
#include "third_party/blink/renderer/core/layout/geometry/logical_size.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_text_fragment.h"
-#include "third_party/blink/renderer/core/layout/ng/inline/ng_text_end_effect.h"
#include "third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -27,6 +26,8 @@ class CORE_EXPORT NGTextFragmentBuilder final : public NGFragmentBuilder {
NGTextFragmentBuilder(const NGPhysicalTextFragment& fragment);
+ TextDirection ResolvedDirection() const { return resolved_direction_; }
+
// NOTE: Takes ownership of the shape result within the item result.
void SetItem(NGPhysicalTextFragment::NGTextType,
const NGInlineItemsData&,
@@ -56,6 +57,9 @@ class CORE_EXPORT NGTextFragmentBuilder final : public NGFragmentBuilder {
NGPhysicalTextFragment::NGTextType text_type_ =
NGPhysicalTextFragment::kNormalText;
+ // Set from |NGInlineItem| by |SetItem()|.
+ TextDirection resolved_direction_ = TextDirection::kLtr;
+
friend class NGPhysicalTextFragment;
};
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 e8132013463..0d6c7251095 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,6 +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 "third_party/blink/renderer/core/core_export.h"
namespace blink {
@@ -13,10 +14,13 @@ namespace blink {
struct CORE_EXPORT NGTextOffset {
NGTextOffset() = default;
NGTextOffset(unsigned start, unsigned end) : start(start), end(end) {
- DCHECK_GE(end, start);
+ AssertValid();
}
- unsigned Length() const { return end - start; }
+ unsigned Length() const {
+ AssertValid();
+ return end - start;
+ }
void AssertValid() const { DCHECK_GE(end, start); }
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 eac09620636..ef990b7ce3f 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
@@ -72,21 +72,6 @@ void LayoutNGBlockFlowMixin<Base>::ClearNGInlineNodeData() {
ng_inline_node_data_.reset();
}
-// The current fragment from the last layout cycle for this box.
-// When pre-NG layout calls functions of this block flow, fragment and/or
-// LayoutResult are required to compute the result.
-// TODO(kojii): Use the cached result for now, we may need to reconsider as the
-// cache evolves.
-template <typename Base>
-const NGPhysicalBoxFragment* LayoutNGBlockFlowMixin<Base>::CurrentFragment()
- const {
- const NGLayoutResult* cached_layout_result = Base::GetCachedLayoutResult();
- if (!cached_layout_result)
- return nullptr;
-
- return &To<NGPhysicalBoxFragment>(cached_layout_result->PhysicalFragment());
-}
-
template <typename Base>
void LayoutNGBlockFlowMixin<Base>::AddLayoutOverflowFromChildren() {
if (Base::LayoutBlockedByDisplayLock(DisplayLockLifecycleTarget::kChildren))
@@ -104,83 +89,15 @@ void LayoutNGBlockFlowMixin<Base>::AddLayoutOverflowFromChildren() {
template <typename Base>
void LayoutNGBlockFlowMixin<Base>::AddScrollingOverflowFromChildren() {
-
const NGPhysicalBoxFragment* physical_fragment = CurrentFragment();
DCHECK(physical_fragment);
- if (physical_fragment->Children().empty())
- return;
-
- const ComputedStyle& style = Base::StyleRef();
- const WritingMode writing_mode = style.GetWritingMode();
- const TextDirection direction = style.Direction();
- const LayoutUnit border_inline_start = LayoutUnit(style.BorderStartWidth());
- const LayoutUnit border_block_start = LayoutUnit(style.BorderBeforeWidth());
- const PhysicalSize& size = physical_fragment->Size();
-
- // End and under padding are added to scroll overflow of inline children.
- // https://github.com/w3c/csswg-drafts/issues/129
- base::Optional<NGPhysicalBoxStrut> padding_strut;
- if (Base::HasOverflowClip()) {
- padding_strut = NGBoxStrut(LayoutUnit(), Base::PaddingEnd(), LayoutUnit(),
- Base::PaddingUnder())
- .ConvertToPhysical(writing_mode, direction);
- }
-
- // Rectangles not reachable by scroll should not be added to overflow.
- auto IsRectReachableByScroll = [&border_inline_start, &border_block_start,
- &writing_mode, &direction,
- &size](const PhysicalRect& rect) {
- LogicalOffset rect_logical_end =
- rect.offset.ConvertToLogical(writing_mode, direction, size, rect.size) +
- rect.size.ConvertToLogical(writing_mode);
- return (rect_logical_end.inline_offset > border_inline_start &&
- rect_logical_end.block_offset > border_block_start);
- };
-
- bool children_inline = Base::ChildrenInline();
- PhysicalRect children_overflow;
- base::Optional<PhysicalRect> lineboxes_enclosing_rect;
- // Only add overflow for fragments NG has not reflected into Legacy.
- // These fragments are:
- // - inline fragments,
- // - out of flow fragments whose css container is inline box.
- // TODO(layout-dev) Transforms also need to be applied to compute overflow
- // correctly. NG is not yet transform-aware. crbug.com/855965
- for (const auto& child : physical_fragment->Children()) {
- PhysicalRect child_scrollable_overflow;
- if (child->IsFloatingOrOutOfFlowPositioned()) {
- child_scrollable_overflow = child->ScrollableOverflowForPropagation(this);
- child_scrollable_overflow.offset +=
- ComputeRelativeOffset(child->Style(), writing_mode, direction, size);
- } else if (children_inline && child->IsLineBox()) {
- DCHECK(child->IsLineBox());
- child_scrollable_overflow =
- To<NGPhysicalLineBoxFragment>(*child).ScrollableOverflow(this, &style,
- size);
- if (padding_strut) {
- PhysicalRect linebox_rect(child.Offset(), child->Size());
- if (lineboxes_enclosing_rect)
- lineboxes_enclosing_rect->Unite(linebox_rect);
- else
- lineboxes_enclosing_rect = linebox_rect;
- }
- } else {
- continue;
- }
- child_scrollable_overflow.offset += child.Offset();
- // Do not add overflow if fragment is not reachable by scrolling.
- if (IsRectReachableByScroll(child_scrollable_overflow))
- children_overflow.Unite(child_scrollable_overflow);
- }
- if (lineboxes_enclosing_rect) {
- lineboxes_enclosing_rect->Expand(*padding_strut);
- if (IsRectReachableByScroll(*lineboxes_enclosing_rect))
- children_overflow.Unite(*lineboxes_enclosing_rect);
- }
+ PhysicalRect children_overflow =
+ physical_fragment->ScrollableOverflowFromChildren();
// LayoutOverflow takes flipped blocks coordinates, adjust as needed.
+ const ComputedStyle& style = physical_fragment->Style();
LayoutRect children_flipped_overflow =
- children_overflow.ToLayoutFlippedRect(style, size);
+ children_overflow.ToLayoutFlippedRect(style, physical_fragment->Size());
Base::AddLayoutOverflow(children_flipped_overflow);
}
@@ -193,60 +110,44 @@ void LayoutNGBlockFlowMixin<Base>::AddOutlineRects(
To<NGPhysicalBoxFragment>(PaintFragment()->PhysicalFragment())
.AddSelfOutlineRects(additional_offset, include_block_overflows,
&rects);
- } else {
- Base::AddOutlineRects(rects, additional_offset, include_block_overflows);
+ return;
}
-}
-
-template <typename Base>
-bool LayoutNGBlockFlowMixin<
- Base>::PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const {
- // LayoutNGBlockFlowMixin is in charge of paint invalidation of the first
- // line.
- if (PaintFragment())
- return false;
- if (Base::StyleRef().HasColumnRule())
- return false;
+ if (const NGPhysicalBoxFragment* fragment = CurrentFragment()) {
+ if (fragment->HasItems()) {
+ fragment->AddSelfOutlineRects(additional_offset, include_block_overflows,
+ &rects);
+ return;
+ }
+ }
- return Base::PaintedOutputOfObjectHasNoEffectRegardlessOfSize();
+ Base::AddOutlineRects(rects, additional_offset, include_block_overflows);
}
// Retrieve NGBaseline from the current fragment.
template <typename Base>
-base::Optional<LayoutUnit> LayoutNGBlockFlowMixin<Base>::FragmentBaseline(
- NGBaselineAlgorithmType type) const {
+base::Optional<LayoutUnit> LayoutNGBlockFlowMixin<Base>::FragmentBaseline()
+ const {
if (Base::ShouldApplyLayoutContainment())
return base::nullopt;
- if (const NGPhysicalFragment* physical_fragment = CurrentFragment()) {
- FontBaseline baseline_type = Base::StyleRef().GetFontBaseline();
- return To<NGPhysicalBoxFragment>(physical_fragment)
- ->Baseline({type, baseline_type});
- }
+ if (const NGPhysicalFragment* physical_fragment = CurrentFragment())
+ return To<NGPhysicalBoxFragment>(physical_fragment)->Baseline();
return base::nullopt;
}
template <typename Base>
LayoutUnit LayoutNGBlockFlowMixin<Base>::FirstLineBoxBaseline() const {
- if (Base::ChildrenInline()) {
- if (base::Optional<LayoutUnit> offset =
- FragmentBaseline(NGBaselineAlgorithmType::kFirstLine)) {
- return *offset;
- }
- }
+ if (base::Optional<LayoutUnit> offset = FragmentBaseline())
+ return *offset;
return Base::FirstLineBoxBaseline();
}
template <typename Base>
LayoutUnit LayoutNGBlockFlowMixin<Base>::InlineBlockBaseline(
LineDirectionMode line_direction) const {
- if (Base::ChildrenInline()) {
- if (base::Optional<LayoutUnit> offset =
- FragmentBaseline(NGBaselineAlgorithmType::kAtomicInline)) {
- return *offset;
- }
- }
+ if (base::Optional<LayoutUnit> offset = FragmentBaseline())
+ return *offset;
return Base::InlineBlockBaseline(line_direction);
}
@@ -300,11 +201,9 @@ void LayoutNGBlockFlowMixin<Base>::Paint(const PaintInfo& paint_info) const {
return;
}
- if (RuntimeEnabledFeatures::LayoutNGFragmentPaintEnabled()) {
- if (const NGPhysicalBoxFragment* fragment = CurrentFragment()) {
- NGBoxFragmentPainter(*fragment).Paint(paint_info);
- return;
- }
+ if (const NGPhysicalBoxFragment* fragment = CurrentFragment()) {
+ NGBoxFragmentPainter(*fragment).Paint(paint_info);
+ return;
}
Base::Paint(paint_info);
@@ -317,7 +216,7 @@ bool LayoutNGBlockFlowMixin<Base>::NodeAtPoint(
const PhysicalOffset& accumulated_offset,
HitTestAction action) {
if (const NGPaintFragment* paint_fragment = PaintFragment()) {
- if (!this->IsEffectiveRootScroller()) {
+ if (!Base::IsEffectiveRootScroller()) {
// Check if we need to do anything at all.
// If we have clipping, then we can't have any spillout.
PhysicalRect overflow_box = Base::HasOverflowClip()
@@ -338,7 +237,11 @@ bool LayoutNGBlockFlowMixin<Base>::NodeAtPoint(
if (UNLIKELY(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())) {
if (const NGPhysicalBoxFragment* fragment = CurrentFragment()) {
- if (fragment->HasItems()) {
+ if (fragment->HasItems() ||
+ // Check descendants of this fragment because floats may be in the
+ // |NGFragmentItems| of the descendants.
+ (action == kHitTestFloat &&
+ fragment->HasFloatingDescendantsForPaint())) {
return NGBoxFragmentPainter(*fragment).NodeAtPoint(
result, hit_test_location, accumulated_offset, action);
}
@@ -370,15 +273,18 @@ PositionWithAffinity LayoutNGBlockFlowMixin<Base>::PositionForPoint(
if (const PositionWithAffinity position =
paint_fragment->PositionForPoint(point_in_contents))
return position;
- } else if (const NGFragmentItems* items = Base::FragmentItems()) {
- // The given offset is relative to this |LayoutBlockFlow|. Convert to the
- // contents offset.
- PhysicalOffset point_in_contents = point;
- Base::OffsetForContents(point_in_contents);
- NGInlineCursor cursor(*items);
- if (const PositionWithAffinity position =
- cursor.PositionForPoint(point_in_contents))
- return position;
+ } else if (const NGPhysicalBoxFragment* fragment = CurrentFragment()) {
+ if (const NGFragmentItems* items = fragment->Items()) {
+ // The given offset is relative to this |LayoutBlockFlow|. Convert to the
+ // contents offset.
+ PhysicalOffset point_in_contents = point;
+ Base::OffsetForContents(point_in_contents);
+ NGInlineCursor cursor(*items);
+ if (const PositionWithAffinity position =
+ cursor.PositionForPointInInlineFormattingContext(
+ point_in_contents, *fragment))
+ return position;
+ }
}
return Base::CreatePositionWithAffinity(0);
@@ -402,26 +308,16 @@ void LayoutNGBlockFlowMixin<Base>::UpdateNGBlockLayout() {
LayoutAnalyzer::BlockScope analyzer(*this);
if (Base::IsOutOfFlowPositioned()) {
- this->UpdateOutOfFlowBlockLayout();
+ LayoutNGMixin<Base>::UpdateOutOfFlowBlockLayout();
return;
}
- NGConstraintSpace constraint_space =
- NGConstraintSpace::CreateFromLayoutObject(
- *this, !Base::View()->GetLayoutState()->Next() /* is_layout_root */);
-
- scoped_refptr<const NGLayoutResult> result =
- NGBlockNode(this).Layout(constraint_space);
-
- for (const auto& descendant :
- result->PhysicalFragment().OutOfFlowPositionedDescendants())
- descendant.node.UseLegacyOutOfFlowPositioning();
- this->UpdateMargins(constraint_space);
+ LayoutNGMixin<Base>::UpdateInFlowBlockLayout();
+ UpdateMargins();
}
template <typename Base>
-void LayoutNGBlockFlowMixin<Base>::UpdateMargins(
- const NGConstraintSpace& space) {
+void LayoutNGBlockFlowMixin<Base>::UpdateMargins() {
const LayoutBlock* containing_block = Base::ContainingBlock();
if (!containing_block || !containing_block->IsLayoutBlockFlow())
return;
@@ -434,13 +330,13 @@ void LayoutNGBlockFlowMixin<Base>::UpdateMargins(
const ComputedStyle& cb_style = containing_block->StyleRef();
const auto writing_mode = cb_style.GetWritingMode();
const auto direction = cb_style.Direction();
- LayoutUnit percentage_resolution_size =
- space.PercentageResolutionInlineSizeForParentWritingMode();
- NGBoxStrut margins = ComputePhysicalMargins(style, percentage_resolution_size)
+ LayoutUnit available_logical_width =
+ LayoutBoxUtils::AvailableLogicalWidth(*this, containing_block);
+ NGBoxStrut margins = ComputePhysicalMargins(style, available_logical_width)
.ConvertToLogical(writing_mode, direction);
- ResolveInlineMargins(style, cb_style, space.AvailableSize().inline_size,
+ ResolveInlineMargins(style, cb_style, available_logical_width,
Base::LogicalWidth(), &margins);
- this->SetMargin(margins.ConvertToPhysical(writing_mode, direction));
+ Base::SetMargin(margins.ConvertToPhysical(writing_mode, direction));
}
template class CORE_TEMPLATE_EXPORT LayoutNGBlockFlowMixin<LayoutBlockFlow>;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.h b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.h
index 6b5d874ce5d..2e808c039bb 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.h
@@ -60,20 +60,18 @@ class LayoutNGBlockFlowMixin : public LayoutNGMixin<Base> {
void SetPaintFragment(const NGBlockBreakToken*,
scoped_refptr<const NGPhysicalFragment>) final;
+ using LayoutNGMixin<Base>::CurrentFragment;
+
protected:
void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
- const NGPhysicalBoxFragment* CurrentFragment() const final;
-
void AddLayoutOverflowFromChildren() final;
void AddOutlineRects(Vector<PhysicalRect>&,
const PhysicalOffset& additional_offset,
NGOutlineType) const final;
- bool PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const final;
-
- base::Optional<LayoutUnit> FragmentBaseline(NGBaselineAlgorithmType) const;
+ base::Optional<LayoutUnit> FragmentBaseline() const;
void DirtyLinesFromChangedChild(LayoutObject* child,
MarkingBehavior marking_behavior) final;
@@ -89,7 +87,7 @@ class LayoutNGBlockFlowMixin : public LayoutNGMixin<Base> {
private:
void AddScrollingOverflowFromChildren();
- void UpdateMargins(const NGConstraintSpace& space);
+ void UpdateMargins();
};
// If you edit these export templates, also update templates in
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_fieldset.cc b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_fieldset.cc
index a39b2b4dee0..907d45bb278 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_fieldset.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_fieldset.cc
@@ -73,17 +73,4 @@ bool LayoutNGFieldset::IsOfType(LayoutObjectType type) const {
return type == kLayoutObjectNGFieldset || LayoutNGBlockFlow::IsOfType(type);
}
-void LayoutNGFieldset::Paint(const PaintInfo& paint_info) const {
- // TODO(crbug.com/988015): This override should not be needed when painting
- // fragment is enabled in parent classes.
- if (!RuntimeEnabledFeatures::LayoutNGFragmentPaintEnabled()) {
- if (const NGPhysicalBoxFragment* fragment = CurrentFragment()) {
- NGBoxFragmentPainter(*fragment, PaintFragment()).Paint(paint_info);
- return;
- }
- }
-
- LayoutNGBlockFlow::Paint(paint_info);
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_fieldset.h b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_fieldset.h
index 4076cdbc70f..5178d12f26d 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_fieldset.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_fieldset.h
@@ -21,14 +21,10 @@ class CORE_EXPORT LayoutNGFieldset final : public LayoutNGBlockFlow {
bool CreatesNewFormattingContext() const final { return true; }
- void Paint(const PaintInfo&) const final;
-
protected:
bool IsOfType(LayoutObjectType) const override;
};
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutNGFieldset, IsLayoutNGFieldset());
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_LAYOUT_NG_FIELDSET_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_flexible_box.cc b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_flexible_box.cc
index dddadee04b5..a74fdfe086d 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_flexible_box.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_flexible_box.cc
@@ -17,6 +17,21 @@ namespace blink {
LayoutNGFlexibleBox::LayoutNGFlexibleBox(Element* element)
: LayoutNGMixin<LayoutBlock>(element) {}
+bool LayoutNGFlexibleBox::HasTopOverflow() const {
+ if (IsHorizontalWritingMode())
+ return StyleRef().ResolvedIsColumnReverseFlexDirection();
+ return StyleRef().IsLeftToRightDirection() ==
+ StyleRef().ResolvedIsRowReverseFlexDirection();
+}
+
+bool LayoutNGFlexibleBox::HasLeftOverflow() const {
+ if (IsHorizontalWritingMode()) {
+ return StyleRef().IsLeftToRightDirection() ==
+ StyleRef().ResolvedIsRowReverseFlexDirection();
+ }
+ return StyleRef().ResolvedIsColumnReverseFlexDirection();
+}
+
void LayoutNGFlexibleBox::UpdateBlockLayout(bool relayout_children) {
LayoutAnalyzer::BlockScope analyzer(*this);
@@ -25,16 +40,34 @@ void LayoutNGFlexibleBox::UpdateBlockLayout(bool relayout_children) {
return;
}
- NGConstraintSpace constraint_space =
- NGConstraintSpace::CreateFromLayoutObject(
- *this, !View()->GetLayoutState()->Next() /* is_layout_root */);
+ UpdateInFlowBlockLayout();
+}
+
+namespace {
+
+void MergeAnonymousFlexItems(LayoutObject* remove_child) {
+ // When we remove a flex item, and the previous and next siblings of the item
+ // are text nodes wrapped in anonymous flex items, the adjacent text nodes
+ // need to be merged into the same flex item.
+ LayoutObject* prev = remove_child->PreviousSibling();
+ if (!prev || !prev->IsAnonymousBlock())
+ return;
+ LayoutObject* next = remove_child->NextSibling();
+ if (!next || !next->IsAnonymousBlock())
+ return;
+ ToLayoutBoxModelObject(next)->MoveAllChildrenTo(ToLayoutBoxModelObject(prev));
+ To<LayoutBlockFlow>(next)->DeleteLineBoxTree();
+ next->Destroy();
+}
+
+} // namespace
- scoped_refptr<const NGLayoutResult> result =
- NGBlockNode(this).Layout(constraint_space);
+void LayoutNGFlexibleBox::RemoveChild(LayoutObject* child) {
+ if (!DocumentBeingDestroyed() &&
+ !StyleRef().IsDeprecatedFlexboxUsingFlexLayout())
+ MergeAnonymousFlexItems(child);
- for (const auto& descendant :
- result->PhysicalFragment().OutOfFlowPositionedDescendants())
- descendant.node.UseLegacyOutOfFlowPositioning();
+ LayoutBlock::RemoveChild(child);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_flexible_box.h b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_flexible_box.h
index c4c0fcfd227..f1a361e1b56 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_flexible_box.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_flexible_box.h
@@ -15,6 +15,9 @@ class CORE_EXPORT LayoutNGFlexibleBox : public LayoutNGMixin<LayoutBlock> {
public:
explicit LayoutNGFlexibleBox(Element*);
+ bool HasTopOverflow() const override;
+ bool HasLeftOverflow() const override;
+
void UpdateBlockLayout(bool relayout_children) override;
bool IsFlexibleBoxIncludingDeprecatedAndNG() const final { return true; }
@@ -22,6 +25,8 @@ class CORE_EXPORT LayoutNGFlexibleBox : public LayoutNGMixin<LayoutBlock> {
const char* GetName() const override { return "LayoutNGFlexibleBox"; }
protected:
+ void RemoveChild(LayoutObject*) override;
+
bool IsOfType(LayoutObjectType type) const override {
return type == kLayoutObjectNGFlexibleBox ||
LayoutNGMixin<LayoutBlock>::IsOfType(type);
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 bc31a16375c..89ad70133c1 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
@@ -11,9 +11,11 @@
#include "third_party/blink/renderer/core/layout/ng/layout_box_utils.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_constraint_space_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/layout/ng/ng_out_of_flow_layout_part.h"
+#include "third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
namespace blink {
@@ -30,27 +32,65 @@ template <typename Base>
LayoutNGMixin<Base>::~LayoutNGMixin() = default;
template <typename Base>
+void LayoutNGMixin<Base>::Paint(const PaintInfo& paint_info) const {
+ // Avoid painting dirty objects because descendants maybe already destroyed.
+ if (UNLIKELY(Base::NeedsLayout() &&
+ !Base::LayoutBlockedByDisplayLock(
+ DisplayLockLifecycleTarget::kChildren))) {
+ NOTREACHED();
+ return;
+ }
+
+ if (const NGPhysicalBoxFragment* fragment = CurrentFragment())
+ NGBoxFragmentPainter(*fragment).Paint(paint_info);
+}
+
+template <typename Base>
+bool LayoutNGMixin<Base>::NodeAtPoint(HitTestResult& result,
+ const HitTestLocation& hit_test_location,
+ const PhysicalOffset& accumulated_offset,
+ HitTestAction action) {
+ if (const NGPhysicalBoxFragment* fragment = CurrentFragment()) {
+ DCHECK_EQ(Base::PhysicalFragmentCount(), 1u);
+ return NGBoxFragmentPainter(*fragment).NodeAtPoint(
+ result, hit_test_location, accumulated_offset, action);
+ }
+
+ return false;
+}
+
+// The current fragment from the last layout cycle for this box.
+// When pre-NG layout calls functions of this block flow, fragment and/or
+// LayoutResult are required to compute the result.
+// TODO(kojii): Use the cached result for now, we may need to reconsider as the
+// cache evolves.
+template <typename Base>
+const NGPhysicalBoxFragment* LayoutNGMixin<Base>::CurrentFragment() const {
+ const NGLayoutResult* cached_layout_result = Base::GetCachedLayoutResult();
+ if (!cached_layout_result)
+ return nullptr;
+
+ return &To<NGPhysicalBoxFragment>(cached_layout_result->PhysicalFragment());
+}
+
+template <typename Base>
bool LayoutNGMixin<Base>::IsOfType(LayoutObject::LayoutObjectType type) const {
return type == LayoutObject::kLayoutObjectNGMixin || Base::IsOfType(type);
}
template <typename Base>
-void LayoutNGMixin<Base>::ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const {
+MinMaxSizes LayoutNGMixin<Base>::ComputeIntrinsicLogicalWidths() const {
NGBlockNode node(const_cast<LayoutNGMixin<Base>*>(this));
- if (!node.CanUseNewLayout()) {
- Base::ComputeIntrinsicLogicalWidths(min_logical_width, max_logical_width);
- return;
- }
+ if (!node.CanUseNewLayout())
+ return Base::ComputeIntrinsicLogicalWidths();
LayoutUnit available_logical_height =
LayoutBoxUtils::AvailableLogicalHeight(*this, Base::ContainingBlock());
- MinMaxSizeInput input(available_logical_height);
- // This function returns content-box plus scrollbar.
- input.size_type = NGMinMaxSizeType::kContentBoxSize;
- MinMaxSize sizes =
- node.ComputeMinMaxSize(node.Style().GetWritingMode(), input);
+
+ NGConstraintSpace space = ConstraintSpaceForMinMaxSizes();
+ MinMaxSizes sizes = node.ComputeMinMaxSizes(
+ node.Style().GetWritingMode(), MinMaxSizesInput(available_logical_height),
+ &space);
if (Base::IsTableCell()) {
// If a table cell, or the column that it belongs to, has a specified fixed
@@ -61,14 +101,34 @@ void LayoutNGMixin<Base>::ComputeIntrinsicLogicalWidths(
Length table_cell_width = cell->StyleOrColLogicalWidth();
if (table_cell_width.IsFixed() && table_cell_width.Value() > 0) {
sizes.max_size = std::max(sizes.min_size,
- Base::AdjustContentBoxLogicalWidthForBoxSizing(
+ Base::AdjustBorderBoxLogicalWidthForBoxSizing(
LayoutUnit(table_cell_width.Value())));
}
}
- sizes += LayoutUnit(Base::ScrollbarLogicalWidth());
- min_logical_width = sizes.min_size;
- max_logical_width = sizes.max_size;
+ return sizes;
+}
+
+template <typename Base>
+NGConstraintSpace LayoutNGMixin<Base>::ConstraintSpaceForMinMaxSizes() const {
+ const ComputedStyle& style = Base::StyleRef();
+ const WritingMode writing_mode = style.GetWritingMode();
+
+ NGConstraintSpaceBuilder builder(writing_mode, writing_mode,
+ /* is_new_fc */ true);
+ builder.SetTextDirection(style.Direction());
+ builder.SetAvailableSize(
+ {Base::ContainingBlockLogicalWidthForContent(), kIndefiniteSize});
+
+ // Table cells borders may be collapsed, we can't calculate these directly
+ // from the style.
+ if (Base::IsTableCell()) {
+ builder.SetIsTableCell(true);
+ builder.SetTableCellBorders({Base::BorderStart(), Base::BorderEnd(),
+ Base::BorderBefore(), Base::BorderAfter()});
+ }
+
+ return builder.ToConstraintSpace();
}
template <typename Base>
@@ -79,8 +139,7 @@ void LayoutNGMixin<Base>::UpdateOutOfFlowBlockLayout() {
: Base::ContainingBlock();
const ComputedStyle* container_style = container->Style();
NGConstraintSpace constraint_space =
- NGConstraintSpace::CreateFromLayoutObject(*this,
- false /* is_layout_root */);
+ NGConstraintSpace::CreateFromLayoutObject(*this);
// As this is part of the Legacy->NG bridge, the container_builder is used
// for indicating the resolved size of the OOF-positioned containing-block
@@ -97,7 +156,7 @@ void LayoutNGMixin<Base>::UpdateOutOfFlowBlockLayout() {
container_node.CreatesNewFormattingContext());
NGFragmentGeometry fragment_geometry;
- fragment_geometry.border = ComputeBorders(constraint_space, container_node);
+ fragment_geometry.border = ComputeBorders(constraint_space, *container_style);
fragment_geometry.scrollbar =
ComputeScrollbars(constraint_space, container_node);
fragment_geometry.padding =
@@ -141,8 +200,9 @@ void LayoutNGMixin<Base>::UpdateOutOfFlowBlockLayout() {
NGBlockNode(this), static_position, ToLayoutInlineOrNull(css_container));
base::Optional<LogicalSize> initial_containing_block_fixed_size;
- if (container->IsLayoutView() && !Base::GetDocument().Printing()) {
- if (LocalFrameView* frame_view = ToLayoutView(container)->GetFrameView()) {
+ auto* layout_view = DynamicTo<LayoutView>(container);
+ if (layout_view && !Base::GetDocument().Printing()) {
+ if (LocalFrameView* frame_view = layout_view->GetFrameView()) {
IntSize size =
frame_view->LayoutViewport()->ExcludeScrollbars(frame_view->Size());
PhysicalSize physical_size(size);
@@ -190,6 +250,29 @@ void LayoutNGMixin<Base>::UpdateOutOfFlowBlockLayout() {
Base::SetIsLegacyInitiatedOutOfFlowLayout(true);
}
+template <typename Base>
+scoped_refptr<const NGLayoutResult>
+LayoutNGMixin<Base>::UpdateInFlowBlockLayout() {
+ const auto* previous_result = Base::GetCachedLayoutResult();
+ bool is_layout_root = !Base::View()->GetLayoutState()->Next();
+
+ // If we are a layout root, use the previous space if available. This will
+ // include any stretched sizes if applicable.
+ NGConstraintSpace constraint_space =
+ is_layout_root && previous_result
+ ? previous_result->GetConstraintSpaceForCaching()
+ : NGConstraintSpace::CreateFromLayoutObject(*this);
+
+ scoped_refptr<const NGLayoutResult> result =
+ NGBlockNode(this).Layout(constraint_space);
+
+ for (const auto& descendant :
+ result->PhysicalFragment().OutOfFlowPositionedDescendants())
+ descendant.node.UseLegacyOutOfFlowPositioning();
+
+ return result;
+}
+
template class CORE_TEMPLATE_EXPORT LayoutNGMixin<LayoutBlock>;
template class CORE_TEMPLATE_EXPORT LayoutNGMixin<LayoutBlockFlow>;
template class CORE_TEMPLATE_EXPORT LayoutNGMixin<LayoutProgress>;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.h b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.h
index e75f321437e..a6194724268 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.h
@@ -23,16 +23,25 @@ class LayoutNGMixin : public Base {
explicit LayoutNGMixin(Element* element);
~LayoutNGMixin() override;
+ void Paint(const PaintInfo&) const override;
+
+ bool NodeAtPoint(HitTestResult&,
+ const HitTestLocation&,
+ const PhysicalOffset& accumulated_offset,
+ HitTestAction) override;
+
bool IsLayoutNGObject() const final { return true; }
+ const NGPhysicalBoxFragment* CurrentFragment() const final;
+
protected:
bool IsOfType(LayoutObject::LayoutObjectType) const override;
- void ComputeIntrinsicLogicalWidths(
- LayoutUnit& min_logical_width,
- LayoutUnit& max_logical_width) const override;
+ MinMaxSizes ComputeIntrinsicLogicalWidths() const override;
+ NGConstraintSpace ConstraintSpaceForMinMaxSizes() const;
void UpdateOutOfFlowBlockLayout();
+ scoped_refptr<const NGLayoutResult> UpdateInFlowBlockLayout();
};
extern template class CORE_EXTERN_TEMPLATE_EXPORT LayoutNGMixin<LayoutBlock>;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_progress.h b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_progress.h
index 7ad4c0c18d7..86d6850fdd5 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_progress.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_progress.h
@@ -25,8 +25,6 @@ class CORE_EXPORT LayoutNGProgress
bool IsOfType(LayoutObjectType type) const override;
};
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutNGProgress, IsLayoutNGProgress());
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_LAYOUT_NG_PROGRESS_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_table_caption.cc b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_table_caption.cc
index 5d5418d2916..2a611c31d3a 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_table_caption.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_table_caption.cc
@@ -57,23 +57,9 @@ void LayoutNGTableCaption::UpdateBlockLayout(bool relayout_children) {
DCHECK(!IsOutOfFlowPositioned()) << "Out of flow captions are blockified.";
- NGConstraintSpace constraint_space =
- NGConstraintSpace::CreateFromLayoutObject(
- *this, !View()->GetLayoutState()->Next() /* is_layout_root */);
-
- scoped_refptr<const NGLayoutResult> result =
- NGBlockNode(this).Layout(constraint_space);
-
- CalculateAndSetMargins(constraint_space, result->PhysicalFragment());
-
- // Tell legacy layout there were abspos descendents we couldn't place. We know
- // we have to pass up to legacy here because this method is legacy's entry
- // point to LayoutNG. If our parent were LayoutNG, it wouldn't have called
- // UpdateBlockLayout, it would have packaged this LayoutObject into
- // NGBlockNode and called Layout on that.
- for (const auto& descendant :
- result->PhysicalFragment().OutOfFlowPositionedDescendants())
- descendant.node.UseLegacyOutOfFlowPositioning();
+ scoped_refptr<const NGLayoutResult> result = UpdateInFlowBlockLayout();
+ CalculateAndSetMargins(result->GetConstraintSpaceForCaching(),
+ result->PhysicalFragment());
// The parent table sometimes changes the caption's position after laying it
// out. So there's no point in setting the fragment's offset here;
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_table_cell.cc b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_table_cell.cc
index da93f774221..87eec6dff43 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_table_cell.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/layout_ng_table_cell.cc
@@ -22,17 +22,7 @@ void LayoutNGTableCell::UpdateBlockLayout(bool relayout_children) {
LayoutAnalyzer::BlockScope analyzer(*this);
SetOverrideLogicalWidth(LogicalWidth());
-
- NGConstraintSpace constraint_space =
- NGConstraintSpace::CreateFromLayoutObject(
- *this, !View()->GetLayoutState()->Next() /* is_layout_root */);
-
- scoped_refptr<const NGLayoutResult> result =
- NGBlockNode(this).Layout(constraint_space);
-
- for (const auto& descendant :
- result->PhysicalFragment().OutOfFlowPositionedDescendants())
- descendant.node.UseLegacyOutOfFlowPositioning();
+ UpdateInFlowBlockLayout();
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/list/README.md b/chromium/third_party/blink/renderer/core/layout/ng/list/README.md
index 9dbe472eaac..b8380c16919 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/list/README.md
+++ b/chromium/third_party/blink/renderer/core/layout/ng/list/README.md
@@ -41,7 +41,7 @@ When the content is inline level and therefore generates line boxes:
generates a box tree of:
- LayoutNGListItem
- - LayoutNGListMarker
+ - LayoutNGOutsideListMarker
- LayoutText (1.)
- LayoutText (sample text)
@@ -56,7 +56,7 @@ When the content is block level:
```
- LayoutNGListItem
- - LayoutNGListMarker
+ - LayoutNGOutsideListMarker
- LayoutText (1.)
- LayoutNGBlockFlow (div)
- LayoutText (sample text)
@@ -74,7 +74,7 @@ When the content is mixed:
```
- LayoutNGListItem
- - LayoutNGListMarker
+ - LayoutNGOutsideListMarker
- LayoutText (1.)
- LayoutNGBlockFlow (anonymous)
- LayoutText (inline text)
@@ -134,7 +134,8 @@ and still easy to implement across implementations.
[marker positioning]: https://drafts.csswg.org/css-lists-3/#positioning
[LayoutNGListItem]: layout_ng_list_item.h
-[LayoutNGListMarker]: layout_ng_list_marker.h
+[LayoutNGInsideListMarker]: layout_ng_inside_list_marker.h
+[LayoutNGOutsideListMarker]: layout_ng_outside_list_marker.h
[NGBlockLayoutAlgorithm]: ../ng_block_layout_algorithm.h
[NGInlineItem]: ../inline/ng_inline_item.h
[NGInlineLayoutAlgorithm]: ../inline/ng_inline_layout_algorithm.h
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_inside_list_marker.cc b/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_inside_list_marker.cc
index 5cdeb8d9124..626ba03e22b 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_inside_list_marker.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_inside_list_marker.cc
@@ -5,20 +5,12 @@
#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_inside_list_marker.h"
#include "third_party/blink/renderer/core/layout/layout_text.h"
-#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h"
namespace blink {
LayoutNGInsideListMarker::LayoutNGInsideListMarker(Element* element)
: LayoutInline(element) {}
-LayoutNGInsideListMarker* LayoutNGInsideListMarker::CreateAnonymous(
- Document* document) {
- LayoutNGInsideListMarker* object = new LayoutNGInsideListMarker(nullptr);
- object->SetDocumentForAnonymous(document);
- return object;
-}
-
bool LayoutNGInsideListMarker::IsOfType(LayoutObjectType type) const {
return type == kLayoutObjectNGInsideListMarker ||
LayoutInline::IsOfType(type);
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 0ce5f756adb..5702a72422c 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,23 +7,24 @@
#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"
namespace blink {
-class Document;
-
// A LayoutObject subclass for inside-positioned list markers in LayoutNG.
class CORE_EXPORT LayoutNGInsideListMarker final : public LayoutInline {
public:
explicit LayoutNGInsideListMarker(Element*);
- static LayoutNGInsideListMarker* CreateAnonymous(Document*);
const char* GetName() const override { return "LayoutNGInsideListMarker"; }
+ const ListMarker& Marker() const { return list_marker_; }
+ ListMarker& Marker() { return list_marker_; }
+
#if DCHECK_IS_ON()
void AddChild(LayoutObject* new_child, LayoutObject* before_child) override {
- // Anonymous list marker should have at most one child.
- DCHECK(GetNode() || !FirstChild());
+ // List markers with 'content: normal' should have at most one child.
+ DCHECK(!StyleRef().ContentBehavesAsNormal() || !FirstChild());
LayoutInline::AddChild(new_child, before_child);
}
#endif
@@ -31,6 +32,8 @@ class CORE_EXPORT LayoutNGInsideListMarker final : public LayoutInline {
private:
bool IsOfType(LayoutObjectType) const override;
PositionWithAffinity PositionForPoint(const PhysicalOffset&) const override;
+
+ ListMarker list_marker_;
};
DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutNGInsideListMarker,
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 826c41c3da0..c3a6d3f0b9f 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,21 +4,12 @@
#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h"
-#include "third_party/blink/renderer/core/layout/layout_image_resource_style_image.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/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.h"
-#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker_image.h"
-#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
+#include "third_party/blink/renderer/core/layout/ng/list/list_marker.h"
namespace blink {
LayoutNGListItem::LayoutNGListItem(Element* element)
- : LayoutNGBlockFlow(element),
- marker_type_(kStatic),
- is_marker_text_updated_(false) {
+ : LayoutNGBlockFlow(element) {
SetInline(false);
SetConsumesSubtreeChangeNotification();
@@ -29,12 +20,6 @@ bool LayoutNGListItem::IsOfType(LayoutObjectType type) const {
return type == kLayoutObjectNGListItem || LayoutNGBlockFlow::IsOfType(type);
}
-void LayoutNGListItem::WillBeDestroyed() {
- DestroyMarker();
-
- LayoutNGBlockFlow::WillBeDestroyed();
-}
-
void LayoutNGListItem::InsertedIntoTree() {
LayoutNGBlockFlow::InsertedIntoTree();
@@ -51,200 +36,52 @@ void LayoutNGListItem::StyleDidChange(StyleDifference diff,
const ComputedStyle* old_style) {
LayoutNGBlockFlow::StyleDidChange(diff, old_style);
- UpdateMarker();
+ LayoutObject* marker = Marker();
+ ListMarker* list_marker = ListMarker::Get(marker);
+ if (!list_marker)
+ return;
+
+ list_marker->UpdateMarkerContentIfNeeded(*marker);
if (old_style && (old_style->ListStyleType() != StyleRef().ListStyleType() ||
(StyleRef().ListStyleType() == EListStyleType::kString &&
old_style->ListStyleStringValue() !=
StyleRef().ListStyleStringValue())))
- ListStyleTypeChanged();
-}
-
-// If the value of ListStyleType changed, we need to the marker text has been
-// updated.
-void LayoutNGListItem::ListStyleTypeChanged() {
- if (!is_marker_text_updated_)
- return;
-
- is_marker_text_updated_ = false;
- if (marker_) {
- marker_->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
- layout_invalidation_reason::kListStyleTypeChange);
- }
+ list_marker->ListStyleTypeChanged(*marker);
}
void LayoutNGListItem::OrdinalValueChanged() {
- if (marker_type_ == kOrdinalValue && is_marker_text_updated_) {
- is_marker_text_updated_ = false;
-
- // |marker_| can be a nullptr, for example, in the case of :after list item
- // elements.
- if (marker_) {
- marker_->SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
- layout_invalidation_reason::kListValueChange);
- }
- }
+ LayoutObject* marker = Marker();
+ if (ListMarker* list_marker = ListMarker::Get(marker))
+ list_marker->OrdinalValueChanged(*marker);
}
void LayoutNGListItem::SubtreeDidChange() {
- if (!marker_)
- return;
-
- if (ordinal_.NotInListChanged()) {
- UpdateMarker();
- ordinal_.SetNotInListChanged(false);
+ LayoutObject* marker = Marker();
+ ListMarker* list_marker = ListMarker::Get(marker);
+ if (!list_marker)
return;
- }
- // Make sure outside marker is the direct child of ListItem.
- if (!IsInside() && marker_->Parent() != this) {
- marker_->Remove();
- AddChild(marker_, FirstChild());
+ // Make sure an outside marker is a direct child of the list item (not nested
+ // inside an anonymous box), and that a marker originated by a ::before or
+ // ::after precedes the generated contents.
+ if ((marker->IsLayoutNGOutsideListMarker() && marker->Parent() != this) ||
+ (IsPseudoElement() && marker != FirstChild())) {
+ marker->Remove();
+ AddChild(marker, FirstChild());
}
- UpdateMarkerContentIfNeeded();
+ list_marker->UpdateMarkerContentIfNeeded(*marker);
}
void LayoutNGListItem::WillCollectInlines() {
UpdateMarkerTextIfNeeded();
}
-// Returns true if this is 'list-style-position: inside', or should be laid out
-// as 'inside'.
-bool LayoutNGListItem::IsInside() const {
- return ordinal_.NotInList() ||
- StyleRef().ListStylePosition() == EListStylePosition::kInside;
-}
-
-// Destroy the list marker objects if exists.
-void LayoutNGListItem::DestroyMarker() {
- if (marker_) {
- marker_->Destroy();
- marker_ = nullptr;
- }
-}
-
-void LayoutNGListItem::UpdateMarkerText(LayoutText* text) {
- DCHECK(text);
- StringBuilder marker_text_builder;
- marker_type_ = MarkerText(&marker_text_builder, kWithSuffix);
- text->SetTextIfNeeded(marker_text_builder.ToString().ReleaseImpl());
- is_marker_text_updated_ = true;
-}
-
-void LayoutNGListItem::UpdateMarkerText() {
- DCHECK(marker_);
- UpdateMarkerText(ToLayoutText(marker_->SlowFirstChild()));
-}
-
-void LayoutNGListItem::UpdateMarker() {
- const ComputedStyle& style = StyleRef();
- if (style.ListStyleType() == EListStyleType::kNone && !IsMarkerImage()) {
- DestroyMarker();
- marker_type_ = kStatic;
- is_marker_text_updated_ = true;
- return;
- }
-
- // Create a marker box if it does not exist yet.
- Node* list_item = GetNode();
- const ComputedStyle* cached_marker_style =
- list_item->IsPseudoElement()
- ? nullptr
- : ToElement(list_item)->CachedStyleForPseudoElement(kPseudoIdMarker);
- if (cached_marker_style && cached_marker_style->GetContentData()) {
- // Don't create an anonymous layout for the marker, it will be generated
- // by the ::marker pseudo-element.
- DestroyMarker();
- marker_type_ = kStatic;
- is_marker_text_updated_ = true;
- return;
- }
- scoped_refptr<ComputedStyle> marker_style;
- if (cached_marker_style) {
- marker_style = ComputedStyle::Clone(*cached_marker_style);
- } else {
- marker_style = ComputedStyle::Create();
- marker_style->InheritFrom(style);
- marker_style->SetStyleType(kPseudoIdMarker);
- marker_style->SetUnicodeBidi(UnicodeBidi::kIsolate);
- marker_style->SetFontVariantNumericSpacing(
- FontVariantNumeric::kTabularNums);
- }
- if (IsInside()) {
- if (marker_ && !marker_->IsLayoutInline())
- DestroyMarker();
- if (!marker_)
- marker_ = LayoutNGInsideListMarker::CreateAnonymous(&GetDocument());
- marker_style->SetDisplay(EDisplay::kInline);
- auto margins =
- LayoutListMarker::InlineMarginsForInside(style, IsMarkerImage());
- marker_style->SetMarginStart(Length::Fixed(margins.first));
- marker_style->SetMarginEnd(Length::Fixed(margins.second));
- } else {
- if (marker_ && !marker_->IsLayoutBlockFlow())
- DestroyMarker();
- if (!marker_)
- marker_ = LayoutNGListMarker::CreateAnonymous(&GetDocument());
- marker_style->SetDisplay(EDisplay::kInlineBlock);
- // Do not break inside the marker, and honor the trailing spaces.
- marker_style->SetWhiteSpace(EWhiteSpace::kPre);
- // Compute margins for 'outside' during layout, because it requires the
- // layout size of the marker.
- // TODO(kojii): absolute position looks more reasonable, and maybe required
- // in some cases, but this is currently blocked by crbug.com/734554
- // marker_style->SetPosition(EPosition::kAbsolute);
- // marker_->SetPositionState(EPosition::kAbsolute);
- }
- marker_->SetStyle(std::move(marker_style));
-
- UpdateMarkerContentIfNeeded();
-
- LayoutObject* first_child = FirstChild();
- if (first_child != marker_) {
- marker_->Remove();
- AddChild(marker_, FirstChild());
- }
-}
-
-LayoutNGListItem* LayoutNGListItem::FromMarker(const LayoutObject& marker) {
- DCHECK(marker.IsLayoutNGListMarkerIncludingInside());
- for (LayoutObject* parent = marker.Parent(); parent;
- parent = parent->Parent()) {
- if (parent->IsLayoutNGListItem()) {
-#if DCHECK_IS_ON()
- LayoutObject* parent_marker = ToLayoutNGListItem(parent)->Marker();
- if (parent_marker) {
- DCHECK(!marker.GetNode());
- DCHECK_EQ(ToLayoutNGListItem(parent)->Marker(), &marker);
- } else {
- DCHECK(marker.GetNode()->IsMarkerPseudoElement());
- DCHECK_EQ(marker.GetNode()->parentElement()->GetLayoutBox(), parent);
- }
-#endif
- return ToLayoutNGListItem(parent);
- }
- // These DCHECKs are not critical but to ensure we cover all cases we know.
- DCHECK(parent->IsAnonymous());
- DCHECK(parent->IsLayoutBlockFlow() || parent->IsLayoutFlowThread());
- }
- return nullptr;
-}
-
-LayoutNGListItem* LayoutNGListItem::FromMarkerOrMarkerContent(
- const LayoutObject& object) {
- DCHECK(object.IsAnonymous());
-
- if (object.IsLayoutNGListMarkerIncludingInside())
- return FromMarker(object);
-
- // Check if this is a marker content.
- if (const LayoutObject* parent = object.Parent()) {
- if (parent->IsLayoutNGListMarkerIncludingInside())
- return FromMarker(*parent);
- }
-
- return nullptr;
+void LayoutNGListItem::UpdateMarkerTextIfNeeded() {
+ LayoutObject* marker = Marker();
+ if (ListMarker* list_marker = ListMarker::Get(marker))
+ list_marker->UpdateMarkerTextIfNeeded(*marker);
}
int LayoutNGListItem::Value() const {
@@ -252,190 +89,16 @@ int LayoutNGListItem::Value() const {
return ordinal_.Value(*GetNode());
}
-LayoutNGListItem::MarkerType LayoutNGListItem::MarkerText(
- StringBuilder* text,
- MarkerTextFormat format) const {
- if (IsMarkerImage()) {
- if (format == kWithSuffix)
- text->Append(' ');
- return kStatic;
- }
-
- const ComputedStyle& style = StyleRef();
- switch (style.ListStyleType()) {
- case EListStyleType::kNone:
- return kStatic;
- case EListStyleType::kString: {
- text->Append(style.ListStyleStringValue());
- return kStatic;
- }
- case EListStyleType::kDisc:
- case EListStyleType::kCircle:
- case EListStyleType::kSquare:
- // 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 = Value();
- text->Append(list_marker_text::GetText(style.ListStyleType(), value));
- if (format == kWithSuffix) {
- text->Append(list_marker_text::Suffix(style.ListStyleType(), value));
- text->Append(' ');
- }
- return kOrdinalValue;
- }
- }
- NOTREACHED();
- return kStatic;
-}
-
-String LayoutNGListItem::MarkerTextWithSuffix() const {
- StringBuilder text;
- MarkerText(&text, kWithSuffix);
- return text.ToString();
-}
-
-String LayoutNGListItem::MarkerTextWithoutSuffix() const {
- StringBuilder text;
- MarkerText(&text, kWithoutSuffix);
- return text.ToString();
-}
-
-String LayoutNGListItem::TextAlternative(const LayoutObject& marker) {
- // For accessibility, return the marker string in the logical order even in
- // RTL, reflecting speech order.
- if (LayoutNGListItem* list_item = FromMarker(marker))
- return list_item->MarkerTextWithSuffix();
- return g_empty_string;
-}
-
-void LayoutNGListItem::UpdateMarkerContentIfNeeded() {
- DCHECK(marker_);
-
- LayoutObject* child = marker_->SlowFirstChild();
- // There should be at most one child.
- DCHECK(!child || !child->SlowFirstChild());
- if (IsMarkerImage()) {
- StyleImage* list_style_image = StyleRef().ListStyleImage();
- if (child) {
- // If the url of `list-style-image` changed, create a new LayoutImage.
- if (!child->IsLayoutImage() ||
- ToLayoutImage(child)->ImageResource()->ImagePtr() !=
- list_style_image->Data()) {
- child->Destroy();
- child = nullptr;
- }
- }
- if (!child) {
- LayoutNGListMarkerImage* image =
- LayoutNGListMarkerImage::CreateAnonymous(&GetDocument());
- scoped_refptr<ComputedStyle> image_style =
- ComputedStyle::CreateAnonymousStyleWithDisplay(marker_->StyleRef(),
- EDisplay::kInline);
- image->SetStyle(image_style);
- image->SetImageResource(
- MakeGarbageCollected<LayoutImageResourceStyleImage>(
- list_style_image));
- image->SetIsGeneratedContent();
- marker_->AddChild(image);
- }
- } else {
- // Create a LayoutText in it.
- LayoutText* text = nullptr;
- // |text_style| should be as same as style propagated in
- // |LayoutObject::PropagateStyleToAnonymousChildren()| to avoid unexpected
- // full layout due by style difference. See http://crbug.com/980399
- scoped_refptr<ComputedStyle> text_style =
- ComputedStyle::CreateAnonymousStyleWithDisplay(
- marker_->StyleRef(), marker_->StyleRef().Display());
- if (child) {
- if (child->IsText()) {
- text = ToLayoutText(child);
- text->SetStyle(text_style);
- } else {
- child->Destroy();
- child = nullptr;
- }
- }
- if (!child) {
- text = LayoutText::CreateEmptyAnonymous(GetDocument(), text_style,
- LegacyLayout::kAuto);
- marker_->AddChild(text);
- is_marker_text_updated_ = false;
- }
- }
-}
-
-LayoutObject* LayoutNGListItem::SymbolMarkerLayoutText() const {
- if (marker_type_ != kSymbolValue)
- return nullptr;
- DCHECK(marker_);
- return marker_->SlowFirstChild();
-}
-
const LayoutObject* LayoutNGListItem::FindSymbolMarkerLayoutText(
const LayoutObject* object) {
if (!object)
return nullptr;
- if (object->IsLayoutNGListItem())
- return ToLayoutNGListItem(object)->SymbolMarkerLayoutText();
+ if (const ListMarker* list_marker = ListMarker::Get(object))
+ return list_marker->SymbolMarkerLayoutText(*object);
- if (object->IsLayoutNGListMarker())
- return ToLayoutNGListMarker(object)->SymbolMarkerLayoutText();
+ if (object->IsLayoutNGListItem())
+ return FindSymbolMarkerLayoutText(ToLayoutNGListItem(object)->Marker());
if (object->IsAnonymousBlock())
return FindSymbolMarkerLayoutText(object->Parent());
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h b/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h
index d6fd7b52ee1..c236130315a 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h
@@ -19,62 +19,30 @@ class CORE_EXPORT LayoutNGListItem final : public LayoutNGBlockFlow {
ListItemOrdinal& Ordinal() { return ordinal_; }
int Value() const;
- String MarkerTextWithSuffix() const;
- String MarkerTextWithoutSuffix() const;
- // Marker text with suffix, e.g. "1. ", for use in accessibility.
- static String TextAlternative(const LayoutObject& marker);
-
- LayoutObject* Marker() const { return marker_; }
- bool IsMarkerImage() const {
- return StyleRef().ListStyleImage() &&
- !StyleRef().ListStyleImage()->ErrorOccurred();
+ LayoutObject* Marker() const {
+ Element* list_item = To<Element>(GetNode());
+ return list_item->PseudoElementLayoutObject(kPseudoIdMarker);
}
- void UpdateMarkerTextIfNeeded() {
- if (marker_ && !is_marker_text_updated_ && !IsMarkerImage())
- UpdateMarkerText();
- }
- void UpdateMarkerContentIfNeeded();
+ void UpdateMarkerTextIfNeeded();
void OrdinalValueChanged();
void WillCollectInlines() override;
- LayoutObject* SymbolMarkerLayoutText() const;
static const LayoutObject* FindSymbolMarkerLayoutText(const LayoutObject*);
- // Find the LayoutNGListItem from a marker.
- static LayoutNGListItem* FromMarker(const LayoutObject& marker);
- static LayoutNGListItem* FromMarkerOrMarkerContent(const LayoutObject&);
-
const char* GetName() const override { return "LayoutNGListItem"; }
private:
bool IsOfType(LayoutObjectType) const override;
- void WillBeDestroyed() override;
void InsertedIntoTree() override;
void WillBeRemovedFromTree() override;
void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
void SubtreeDidChange() final;
- bool IsInside() const;
-
- enum MarkerTextFormat { kWithSuffix, kWithoutSuffix };
- enum MarkerType { kStatic, kOrdinalValue, kSymbolValue };
- MarkerType MarkerText(StringBuilder*, MarkerTextFormat) const;
- void UpdateMarkerText();
- void UpdateMarkerText(LayoutText*);
- void UpdateMarker();
- void DestroyMarker();
-
- void ListStyleTypeChanged();
-
ListItemOrdinal ordinal_;
- LayoutObject* marker_ = nullptr;
-
- unsigned marker_type_ : 2; // MarkerType
- unsigned is_marker_text_updated_ : 1;
};
DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutNGListItem, IsLayoutNGListItem());
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker.cc b/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker.cc
deleted file mode 100644
index a477149ad5d..00000000000
--- a/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker.cc
+++ /dev/null
@@ -1,61 +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/ng/list/layout_ng_list_marker.h"
-
-#include "third_party/blink/renderer/core/layout/layout_text.h"
-#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h"
-
-namespace blink {
-
-LayoutNGListMarker::LayoutNGListMarker(Element* element)
- : LayoutNGBlockFlowMixin<LayoutBlockFlow>(element) {}
-
-LayoutNGListMarker* LayoutNGListMarker::CreateAnonymous(Document* document) {
- LayoutNGListMarker* object = new LayoutNGListMarker(nullptr);
- object->SetDocumentForAnonymous(document);
- return object;
-}
-
-bool LayoutNGListMarker::IsOfType(LayoutObjectType type) const {
- return type == kLayoutObjectNGListMarker ||
- LayoutNGMixin<LayoutBlockFlow>::IsOfType(type);
-}
-
-void LayoutNGListMarker::WillCollectInlines() {
- if (LayoutNGListItem* list_item = LayoutNGListItem::FromMarker(*this))
- list_item->UpdateMarkerTextIfNeeded();
-}
-
-bool LayoutNGListMarker::IsContentImage() const {
- if (LayoutNGListItem* list_item = LayoutNGListItem::FromMarker(*this))
- return list_item->IsMarkerImage();
- return false;
-}
-
-LayoutObject* LayoutNGListMarker::SymbolMarkerLayoutText() const {
- if (LayoutNGListItem* list_item = LayoutNGListItem::FromMarker(*this))
- return list_item->SymbolMarkerLayoutText();
- return nullptr;
-}
-
-bool LayoutNGListMarker::NeedsOccupyWholeLine() const {
- if (!GetDocument().InQuirksMode())
- return false;
-
- LayoutObject* next_sibling = NextSibling();
- if (next_sibling && next_sibling->GetNode() &&
- (IsA<HTMLUListElement>(*next_sibling->GetNode()) ||
- IsA<HTMLOListElement>(*next_sibling->GetNode())))
- return true;
-
- return false;
-}
-
-PositionWithAffinity LayoutNGListMarker::PositionForPoint(
- const PhysicalOffset&) const {
- return CreatePositionWithAffinity(0);
-}
-
-} // 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/ng/list/layout_ng_list_marker_image.cc
index 65a6f555531..0ff22412114 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/ng/list/layout_ng_list_marker_image.cc
@@ -3,7 +3,9 @@
// 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/intrinsic_sizing_info.h"
+#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h"
#include "third_party/blink/renderer/core/svg/graphics/svg_image.h"
namespace blink {
@@ -22,21 +24,6 @@ bool LayoutNGListMarkerImage::IsOfType(LayoutObjectType type) const {
return type == kLayoutObjectNGListMarkerImage || LayoutImage::IsOfType(type);
}
-Node* LayoutNGListMarkerImage::NodeForHitTest() const {
- // In LayoutNG tree, image list marker is structured like this:
- // <li> (LayoutListItem)
- // <anonymous block> (LayoutNGListMarker or LayoutNGInsideListMarker)
- // <anonymous img> (LayoutNGListMarkerImage)
- // Hit testing should return the list-item node.
- DCHECK(!GetNode());
- for (const LayoutObject* parent = Parent(); parent;
- parent = parent->Parent()) {
- if (Node* node = parent->GetNode())
- return node;
- }
- return nullptr;
-}
-
// 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).
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
index 6ebae9a91d7..86bdb5ec592 100644
--- 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
@@ -19,8 +19,6 @@ class CORE_EXPORT LayoutNGListMarkerImage final : public LayoutImage {
bool IsLayoutNGObject() const override { return true; }
- Node* NodeForHitTest() const final;
-
private:
bool IsOfType(LayoutObjectType) const override;
@@ -28,9 +26,6 @@ class CORE_EXPORT LayoutNGListMarkerImage final : public LayoutImage {
void ComputeIntrinsicSizingInfo(IntrinsicSizingInfo&) const final;
};
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutNGListMarkerImage,
- IsLayoutNGListMarkerImage());
-
} // 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.cc b/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.cc
new file mode 100644
index 00000000000..4507904c341
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.cc
@@ -0,0 +1,41 @@
+// 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/list/layout_ng_outside_list_marker.h"
+
+#include "third_party/blink/renderer/core/layout/layout_text.h"
+
+namespace blink {
+
+LayoutNGOutsideListMarker::LayoutNGOutsideListMarker(Element* element)
+ : LayoutNGBlockFlowMixin<LayoutBlockFlow>(element) {}
+
+bool LayoutNGOutsideListMarker::IsOfType(LayoutObjectType type) const {
+ return type == kLayoutObjectNGOutsideListMarker ||
+ LayoutNGMixin<LayoutBlockFlow>::IsOfType(type);
+}
+
+void LayoutNGOutsideListMarker::WillCollectInlines() {
+ list_marker_.UpdateMarkerTextIfNeeded(*this);
+}
+
+bool LayoutNGOutsideListMarker::NeedsOccupyWholeLine() const {
+ if (!GetDocument().InQuirksMode())
+ return false;
+
+ LayoutObject* next_sibling = NextSibling();
+ if (next_sibling && next_sibling->GetNode() &&
+ (IsA<HTMLUListElement>(*next_sibling->GetNode()) ||
+ IsA<HTMLOListElement>(*next_sibling->GetNode())))
+ return true;
+
+ return false;
+}
+
+PositionWithAffinity LayoutNGOutsideListMarker::PositionForPoint(
+ const PhysicalOffset&) const {
+ return CreatePositionWithAffinity(0);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker.h b/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.h
index d317122a3a8..3b30f46349b 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.h
@@ -2,41 +2,41 @@
// 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_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_LIST_LAYOUT_NG_LIST_MARKER_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_LIST_LAYOUT_NG_OUTSIDE_LIST_MARKER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_LIST_LAYOUT_NG_OUTSIDE_LIST_MARKER_H_
#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/ng/layout_ng_block_flow_mixin.h"
+#include "third_party/blink/renderer/core/layout/ng/list/list_marker.h"
namespace blink {
-class Document;
-
// A LayoutObject subclass for outside-positioned list markers in LayoutNG.
-class CORE_EXPORT LayoutNGListMarker final
+class CORE_EXPORT LayoutNGOutsideListMarker final
: public LayoutNGBlockFlowMixin<LayoutBlockFlow> {
public:
- explicit LayoutNGListMarker(Element*);
- static LayoutNGListMarker* CreateAnonymous(Document*);
+ explicit LayoutNGOutsideListMarker(Element*);
void WillCollectInlines() override;
- bool IsContentImage() const;
-
- LayoutObject* SymbolMarkerLayoutText() const;
-
- const char* GetName() const override { return "LayoutNGListMarker"; }
+ const char* GetName() const override { return "LayoutNGOutsideListMarker"; }
bool NeedsOccupyWholeLine() const;
+ const ListMarker& Marker() const { return list_marker_; }
+ ListMarker& Marker() { return list_marker_; }
+
private:
bool IsOfType(LayoutObjectType) const override;
PositionWithAffinity PositionForPoint(const PhysicalOffset&) const override;
+
+ ListMarker list_marker_;
};
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutNGListMarker, IsLayoutNGListMarker());
+DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutNGOutsideListMarker,
+ IsLayoutNGOutsideListMarker());
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_LIST_LAYOUT_NG_LIST_MARKER_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_LIST_LAYOUT_NG_OUTSIDE_LIST_MARKER_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/list/list_marker.cc b/chromium/third_party/blink/renderer/core/layout/ng/list/list_marker.cc
new file mode 100644
index 00000000000..b2533d42d7a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/list/list_marker.cc
@@ -0,0 +1,256 @@
+// 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/list_marker.h"
+
+#include "third_party/blink/renderer/core/layout/layout_image_resource_style_image.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_outside_list_marker.h"
+
+namespace blink {
+
+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();
+ return nullptr;
+}
+
+ListMarker* ListMarker::Get(LayoutObject* object) {
+ return const_cast<ListMarker*>(
+ ListMarker::Get(static_cast<const LayoutObject*>(object)));
+}
+
+// If the value of ListStyleType changed, we need to the marker text has been
+// updated.
+void ListMarker::ListStyleTypeChanged(LayoutObject& marker) {
+ if (marker_text_type_ == kNotText || marker_text_type_ == kUnresolved)
+ return;
+
+ marker_text_type_ = kUnresolved;
+ marker.SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
+ layout_invalidation_reason::kListStyleTypeChange);
+}
+
+void ListMarker::OrdinalValueChanged(LayoutObject& marker) {
+ if (marker_text_type_ == kOrdinalValue) {
+ marker_text_type_ = kUnresolved;
+ marker.SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
+ layout_invalidation_reason::kListValueChange);
+ }
+}
+
+void ListMarker::UpdateMarkerText(LayoutObject& marker, LayoutText* text) {
+ DCHECK(text);
+ DCHECK_EQ(marker_text_type_, kUnresolved);
+ StringBuilder marker_text_builder;
+ marker_text_type_ = MarkerText(marker, &marker_text_builder, kWithSuffix);
+ text->SetTextIfNeeded(marker_text_builder.ToString().ReleaseImpl());
+ DCHECK_NE(marker_text_type_, kNotText);
+ DCHECK_NE(marker_text_type_, kUnresolved);
+}
+
+void ListMarker::UpdateMarkerText(LayoutObject& marker) {
+ 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 {
+ if (IsMarkerImage(marker)) {
+ if (format == kWithSuffix)
+ text->Append(' ');
+ return kNotText;
+ }
+
+ LayoutNGListItem* list_item = ListItem(marker);
+ const ComputedStyle& style = list_item->StyleRef();
+ switch (style.ListStyleType()) {
+ case EListStyleType::kNone:
+ return kNotText;
+ case EListStyleType::kString: {
+ text->Append(style.ListStyleStringValue());
+ return kStatic;
+ }
+ case EListStyleType::kDisc:
+ case EListStyleType::kCircle:
+ case EListStyleType::kSquare:
+ // 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();
+ text->Append(list_marker_text::GetText(style.ListStyleType(), value));
+ if (format == kWithSuffix) {
+ text->Append(list_marker_text::Suffix(style.ListStyleType(), value));
+ text->Append(' ');
+ }
+ return kOrdinalValue;
+ }
+ }
+ NOTREACHED();
+ return kStatic;
+}
+
+String ListMarker::MarkerTextWithSuffix(const LayoutObject& marker) const {
+ StringBuilder text;
+ MarkerText(marker, &text, kWithSuffix);
+ return text.ToString();
+}
+
+String ListMarker::MarkerTextWithoutSuffix(const LayoutObject& marker) const {
+ StringBuilder text;
+ MarkerText(marker, &text, kWithoutSuffix);
+ return text.ToString();
+}
+
+String ListMarker::TextAlternative(const LayoutObject& marker) const {
+ // 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);
+
+ if (!marker.StyleRef().ContentBehavesAsNormal()) {
+ marker_text_type_ = kNotText;
+ return;
+ }
+
+ // There should be at most one child.
+ LayoutObject* child = marker.SlowFirstChild();
+ DCHECK(!child || !child->NextSibling());
+
+ if (IsMarkerImage(marker)) {
+ StyleImage* list_style_image = list_item->StyleRef().ListStyleImage();
+ if (child) {
+ // If the url of `list-style-image` changed, create a new LayoutImage.
+ if (!child->IsLayoutImage() ||
+ ToLayoutImage(child)->ImageResource()->ImagePtr() !=
+ list_style_image->Data()) {
+ child->Destroy();
+ child = nullptr;
+ }
+ }
+ if (!child) {
+ LayoutNGListMarkerImage* image =
+ LayoutNGListMarkerImage::CreateAnonymous(&marker.GetDocument());
+ scoped_refptr<ComputedStyle> image_style =
+ ComputedStyle::CreateAnonymousStyleWithDisplay(marker.StyleRef(),
+ EDisplay::kInline);
+ image->SetStyle(image_style);
+ image->SetImageResource(
+ MakeGarbageCollected<LayoutImageResourceStyleImage>(
+ list_style_image));
+ image->SetIsGeneratedContent();
+ marker.AddChild(image);
+ }
+ marker_text_type_ = kNotText;
+ return;
+ }
+
+ if (list_item->StyleRef().ListStyleType() == EListStyleType::kNone) {
+ marker_text_type_ = kNotText;
+ return;
+ }
+
+ // Create a LayoutText in it.
+ LayoutText* text = nullptr;
+ // |text_style| should be as same as style propagated in
+ // |LayoutObject::PropagateStyleToAnonymousChildren()| to avoid unexpected
+ // full layout due by style difference. See http://crbug.com/980399
+ scoped_refptr<ComputedStyle> text_style =
+ ComputedStyle::CreateAnonymousStyleWithDisplay(
+ marker.StyleRef(), marker.StyleRef().Display());
+ if (child) {
+ if (child->IsText()) {
+ text = ToLayoutText(child);
+ text->SetStyle(text_style);
+ } else {
+ child->Destroy();
+ child = nullptr;
+ }
+ }
+ if (!child) {
+ text = LayoutText::CreateEmptyAnonymous(marker.GetDocument(), text_style,
+ LegacyLayout::kAuto);
+ marker.AddChild(text);
+ marker_text_type_ = kUnresolved;
+ }
+}
+
+LayoutObject* ListMarker::SymbolMarkerLayoutText(
+ const LayoutObject& marker) const {
+ if (marker_text_type_ != kSymbolValue)
+ return nullptr;
+ return marker.SlowFirstChild();
+}
+
+} // 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/ng/list/list_marker.h
new file mode 100644
index 00000000000..0ecf1844689
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/list/list_marker.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_LIST_LIST_MARKER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_LIST_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 CORE_EXPORT ListMarker {
+ friend class LayoutNGListItem;
+
+ public:
+ explicit ListMarker();
+
+ static const ListMarker* Get(const LayoutObject*);
+ static ListMarker* Get(LayoutObject*);
+
+ static LayoutNGListItem* ListItem(const LayoutObject&);
+
+ String MarkerTextWithSuffix(const LayoutObject&) const;
+ String MarkerTextWithoutSuffix(const LayoutObject&) const;
+
+ // 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();
+ }
+
+ void UpdateMarkerTextIfNeeded(LayoutObject& marker) {
+ if (marker_text_type_ == kUnresolved)
+ UpdateMarkerText(marker);
+ }
+ void UpdateMarkerContentIfNeeded(LayoutObject&);
+
+ void OrdinalValueChanged(LayoutObject&);
+
+ LayoutObject* SymbolMarkerLayoutText(const LayoutObject&) const;
+
+ private:
+ enum MarkerTextFormat { kWithSuffix, kWithoutSuffix };
+ enum MarkerTextType {
+ kNotText, // The marker doesn't have a LayoutText, either because it has
+ // not been created yet or because 'list-style-type' is 'none',
+ // 'list-style-image' is not 'none', or 'content' is not
+ // 'normal'.
+ kUnresolved, // The marker has a LayoutText that needs to be updated.
+ kOrdinalValue, // The marker text depends on the ordinal.
+ kStatic, // The marker text doesn't depend on the ordinal.
+ kSymbolValue, // Like kStatic, but the marker is painted as a symbol.
+ };
+ MarkerTextType MarkerText(const LayoutObject&,
+ StringBuilder*,
+ MarkerTextFormat) const;
+ void UpdateMarkerText(LayoutObject&);
+ void UpdateMarkerText(LayoutObject&, LayoutText*);
+
+ void ListStyleTypeChanged(LayoutObject&);
+
+ unsigned marker_text_type_ : 3; // MarkerTextType
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_LIST_LIST_MARKER_H_
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 710824388d4..e0e08726a1f 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
@@ -7,7 +7,7 @@
#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_list_marker.h"
+#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.h"
#include "third_party/blink/renderer/core/layout/ng/ng_box_fragment.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"
@@ -15,16 +15,18 @@
namespace blink {
-NGUnpositionedListMarker::NGUnpositionedListMarker(LayoutNGListMarker* marker)
+NGUnpositionedListMarker::NGUnpositionedListMarker(
+ LayoutNGOutsideListMarker* marker)
: marker_layout_object_(marker) {}
NGUnpositionedListMarker::NGUnpositionedListMarker(const NGBlockNode& node)
- : NGUnpositionedListMarker(ToLayoutNGListMarker(node.GetLayoutBox())) {}
+ : NGUnpositionedListMarker(
+ ToLayoutNGOutsideListMarker(node.GetLayoutBox())) {}
// Returns true if this is an image marker.
bool NGUnpositionedListMarker::IsImage() const {
DCHECK(marker_layout_object_);
- return marker_layout_object_->IsContentImage();
+ return marker_layout_object_->Marker().IsMarkerImage(*marker_layout_object_);
}
// Compute the inline offset of the marker, relative to the list item.
@@ -45,24 +47,21 @@ scoped_refptr<const NGLayoutResult> NGUnpositionedListMarker::Layout(
FontBaseline baseline_type) const {
DCHECK(marker_layout_object_);
NGBlockNode marker_node(marker_layout_object_);
+
+ // We need the first-line baseline from the list-marker, instead of the
+ // typical atomic-inline baseline.
scoped_refptr<const NGLayoutResult> marker_layout_result =
- marker_node.LayoutAtomicInline(parent_space, parent_style, baseline_type,
- parent_space.UseFirstLineStyle());
+ marker_node.LayoutAtomicInline(parent_space, parent_style,
+ parent_space.UseFirstLineStyle(),
+ NGBaselineAlgorithmType::kFirstLine);
DCHECK(marker_layout_result);
return marker_layout_result;
}
-bool NGUnpositionedListMarker::CanAddToBox(
+base::Optional<LayoutUnit> NGUnpositionedListMarker::ContentAlignmentBaseline(
const NGConstraintSpace& space,
FontBaseline baseline_type,
- const NGPhysicalFragment& content,
- NGLineHeightMetrics* content_metrics) const {
- DCHECK(content_metrics);
-
- // Baselines from two different writing-mode cannot be aligned.
- if (UNLIKELY(space.GetWritingMode() != content.Style().GetWritingMode()))
- return false;
-
+ const NGPhysicalFragment& content) const {
// Compute the baseline of the child content.
if (content.IsLineBox()) {
const auto& line_box = To<NGPhysicalLineBoxFragment>(content);
@@ -71,22 +70,17 @@ bool NGUnpositionedListMarker::CanAddToBox(
// with the next non-empty line box produced. (This can occur with floats
// producing empty line-boxes).
if (line_box.IsEmptyLineBox() && !line_box.BreakToken()->IsFinished())
- return false;
+ return base::nullopt;
- *content_metrics = line_box.Metrics();
- } else {
- NGBoxFragment content_fragment(space.GetWritingMode(), space.Direction(),
- To<NGPhysicalBoxFragment>(content));
- *content_metrics = content_fragment.BaselineMetricsWithoutSynthesize(
- {NGBaselineAlgorithmType::kFirstLine, baseline_type});
-
- // If this child content does not have any line boxes, the list marker
- // should be aligned to the first line box of next child.
- // https://github.com/w3c/csswg-drafts/issues/2417
- if (content_metrics->IsEmpty())
- return false;
+ return line_box.Metrics().ascent;
}
- return true;
+
+ // If this child content does not have any line boxes, the list marker
+ // should be aligned to the first line box of next child.
+ // https://github.com/w3c/csswg-drafts/issues/2417
+ return NGBoxFragment(space.GetWritingMode(), space.Direction(),
+ To<NGPhysicalBoxFragment>(content))
+ .FirstBaseline();
}
void NGUnpositionedListMarker::AddToBox(
@@ -94,12 +88,10 @@ void NGUnpositionedListMarker::AddToBox(
FontBaseline baseline_type,
const NGPhysicalFragment& content,
const NGBoxStrut& border_scrollbar_padding,
- const NGLineHeightMetrics& content_metrics,
const NGLayoutResult& marker_layout_result,
+ LayoutUnit content_baseline,
LogicalOffset* content_offset,
NGBoxFragmentBuilder* container_builder) const {
- DCHECK(!content_metrics.IsEmpty());
-
const NGPhysicalBoxFragment& marker_physical_fragment =
To<NGPhysicalBoxFragment>(marker_layout_result.PhysicalFragment());
@@ -111,8 +103,8 @@ void NGUnpositionedListMarker::AddToBox(
// Adjust the block offset to align baselines of the marker and the content.
NGLineHeightMetrics marker_metrics = marker_fragment.BaselineMetrics(
- {NGBaselineAlgorithmType::kAtomicInline, baseline_type}, space);
- LayoutUnit baseline_adjust = content_metrics.ascent - marker_metrics.ascent;
+ /* margins */ NGLineBoxStrut(), baseline_type);
+ LayoutUnit baseline_adjust = content_baseline - marker_metrics.ascent;
if (baseline_adjust >= 0) {
marker_offset.block_offset += baseline_adjust;
} else {
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.h b/chromium/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.h
index 8305cac2cf6..5c5e6e3091f 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.h
@@ -14,7 +14,7 @@
namespace blink {
class ComputedStyle;
-class LayoutNGListMarker;
+class LayoutNGOutsideListMarker;
class LayoutUnit;
class NGBlockNode;
class NGConstraintSpace;
@@ -23,7 +23,6 @@ class NGLayoutResult;
class NGPhysicalFragment;
struct LogicalOffset;
-struct NGLineHeightMetrics;
// Represents an unpositioned list marker.
//
@@ -37,8 +36,8 @@ struct NGLineHeightMetrics;
//
// In order to adjust with the other content of LI, marker will be handled
// after other children.
-// First, try to find the adjusted content_metrics for the marker. See
-// |CanAddToBox()| for details.
+// First, try to find the alignment-baseline for the marker. See
+// |ContentAlignmentBaseline()| for details.
// If found, layout marker, compute the content adjusted offset and float
// intuded offset. See |AddToBox()| for details.
// If not, layout marker and deal with it in |AddToBoxWithoutLineBoxes()|.
@@ -52,25 +51,27 @@ class CORE_EXPORT NGUnpositionedListMarker final {
public:
NGUnpositionedListMarker() : marker_layout_object_(nullptr) {}
- explicit NGUnpositionedListMarker(LayoutNGListMarker*);
+ explicit NGUnpositionedListMarker(LayoutNGOutsideListMarker*);
explicit NGUnpositionedListMarker(const NGBlockNode&);
explicit operator bool() const { return marker_layout_object_; }
- // Returns true if the list marker can be added to box. False indicates
- // that the child content does not have a baseline to align to, and that
- // caller should try next child, or "WithoutLineBoxes" version.
- bool CanAddToBox(const NGConstraintSpace&,
- FontBaseline,
- const NGPhysicalFragment& content,
- NGLineHeightMetrics* content_metrics) const;
+ // Returns the baseline that the list-marker should place itself along.
+ //
+ // |base::nullopt| indicates that the child |content| does not have a baseline
+ // to align to, and that caller should try next child, or use the
+ // |AddToBoxWithoutLineBoxes()| method.
+ base::Optional<LayoutUnit> ContentAlignmentBaseline(
+ const NGConstraintSpace&,
+ FontBaseline,
+ const NGPhysicalFragment& content) const;
// Add a fragment for an outside list marker.
void AddToBox(const NGConstraintSpace&,
FontBaseline,
const NGPhysicalFragment& content,
const NGBoxStrut&,
- const NGLineHeightMetrics& content_metrics,
const NGLayoutResult& marker_layout_result,
+ LayoutUnit content_baseline,
LogicalOffset* content_offset,
NGBoxFragmentBuilder*) const;
@@ -105,7 +106,7 @@ class CORE_EXPORT NGUnpositionedListMarker final {
const NGBoxStrut&,
LayoutUnit) const;
- LayoutNGListMarker* marker_layout_object_;
+ LayoutNGOutsideListMarker* marker_layout_object_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block.cc b/chromium/third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block.cc
new file mode 100644
index 00000000000..161826f1cff
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block.cc
@@ -0,0 +1,46 @@
+// 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/layout/ng/mathml/layout_ng_mathml_block.h"
+
+#include "third_party/blink/renderer/core/layout/layout_analyzer.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h"
+
+namespace blink {
+
+LayoutNGMathMLBlock::LayoutNGMathMLBlock(MathMLElement* element)
+ : LayoutNGMixin<LayoutBlock>(element) {
+ DCHECK(element);
+}
+
+void LayoutNGMathMLBlock::UpdateBlockLayout(bool relayout_children) {
+ LayoutAnalyzer::BlockScope analyzer(*this);
+
+ if (IsOutOfFlowPositioned()) {
+ UpdateOutOfFlowBlockLayout();
+ return;
+ }
+
+ UpdateInFlowBlockLayout();
+}
+
+bool LayoutNGMathMLBlock::IsOfType(LayoutObjectType type) const {
+ return type == kLayoutObjectMathML ||
+ (type == kLayoutObjectMathMLRoot && GetNode() &&
+ GetNode()->HasTagName(mathml_names::kMathTag)) ||
+ LayoutNGMixin<LayoutBlock>::IsOfType(type);
+}
+
+bool LayoutNGMathMLBlock::IsChildAllowed(LayoutObject* child,
+ const ComputedStyle&) const {
+ return child->GetNode() && child->GetNode()->IsMathMLElement();
+}
+
+bool LayoutNGMathMLBlock::CanHaveChildren() const {
+ if (GetNode() && GetNode()->HasTagName(mathml_names::kMspaceTag))
+ return false;
+ return LayoutNGMixin<LayoutBlock>::CanHaveChildren();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block.h b/chromium/third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block.h
new file mode 100644
index 00000000000..bc9dc975643
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block.h
@@ -0,0 +1,29 @@
+// 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_LAYOUT_NG_MATHML_LAYOUT_NG_MATHML_BLOCK_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_LAYOUT_NG_MATHML_BLOCK_H_
+
+#include "third_party/blink/renderer/core/layout/ng/layout_ng_mixin.h"
+#include "third_party/blink/renderer/core/mathml/mathml_element.h"
+
+namespace blink {
+
+class LayoutNGMathMLBlock : public LayoutNGMixin<LayoutBlock> {
+ public:
+ explicit LayoutNGMathMLBlock(MathMLElement*);
+
+ const char* GetName() const override { return "LayoutNGMathMLBlock"; }
+
+ private:
+ void UpdateBlockLayout(bool relayout_children) final;
+
+ bool IsOfType(LayoutObjectType) const final;
+ bool IsChildAllowed(LayoutObject*, const ComputedStyle&) const final;
+ bool CanHaveChildren() const final;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_LAYOUT_NG_MATHML_BLOCK_H_
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
new file mode 100644
index 00000000000..9deb2e3c49f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.cc
@@ -0,0 +1,323 @@
+// 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/mathml/ng_math_fraction_layout_algorithm.h"
+
+#include "third_party/blink/renderer/core/layout/ng/mathml/ng_math_layout_utils.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_box_fragment.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_layout_part.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
+#include "third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.h"
+
+namespace blink {
+namespace {
+
+// Describes the amount to shift the numerator/denominator of the fraction when
+// a fraction bar is present. Data is populated from the OpenType MATH table.
+// If the OpenType MATH table is not present fallback values are used.
+// https://mathml-refresh.github.io/mathml-core/#fraction-with-nonzero-line-thickness
+struct FractionParameters {
+ LayoutUnit numerator_gap_min;
+ LayoutUnit denominator_gap_min;
+ LayoutUnit numerator_min_shift_up;
+ LayoutUnit denominator_min_shift_down;
+};
+
+FractionParameters GetFractionParameters(const ComputedStyle& style) {
+ FractionParameters parameters;
+
+ bool has_display_style = HasDisplayStyle(style);
+
+ // We try and read constants to draw the fraction from the OpenType MATH and
+ // use fallback values otherwise.
+ // The MATH table specification suggests default rule thickness or (in
+ // displaystyle) 3 times default rule thickness for the gaps.
+ parameters.numerator_gap_min = LayoutUnit(
+ MathConstant(
+ style,
+ has_display_style
+ ? OpenTypeMathSupport::MathConstants::
+ kFractionNumDisplayStyleGapMin
+ : OpenTypeMathSupport::MathConstants::kFractionNumeratorGapMin)
+ .value_or((has_display_style ? 3 : 1) *
+ RuleThicknessFallback(style)));
+ parameters.denominator_gap_min = LayoutUnit(
+ MathConstant(
+ style,
+ has_display_style
+ ? OpenTypeMathSupport::MathConstants::
+ kFractionDenomDisplayStyleGapMin
+ : OpenTypeMathSupport::MathConstants::kFractionDenominatorGapMin)
+ .value_or(parameters.numerator_gap_min));
+
+ // TODO(crbug.com/1058369): The MATH table specification does not suggest
+ // any values for shifts, so we leave them at zero for now.
+ parameters.numerator_min_shift_up = LayoutUnit(
+ MathConstant(
+ style,
+ has_display_style
+ ? OpenTypeMathSupport::MathConstants::
+ kFractionNumeratorDisplayStyleShiftUp
+ : OpenTypeMathSupport::MathConstants::kFractionNumeratorShiftUp)
+ .value_or(0));
+ parameters.denominator_min_shift_down = LayoutUnit(
+ MathConstant(style, has_display_style
+ ? OpenTypeMathSupport::MathConstants::
+ kFractionDenominatorDisplayStyleShiftDown
+ : OpenTypeMathSupport::MathConstants::
+ kFractionDenominatorShiftDown)
+ .value_or(0));
+
+ return parameters;
+}
+
+// Describes the amount to shift the numerator/denominator of the fraction when
+// a fraction bar is not present. Data is populated from the OpenType MATH
+// table. If the OpenType MATH table is not present fallback values are used.
+// https://mathml-refresh.github.io/mathml-core/#fraction-with-zero-line-thickness
+struct FractionStackParameters {
+ LayoutUnit gap_min;
+ LayoutUnit top_shift_up;
+ LayoutUnit bottom_shift_down;
+};
+
+FractionStackParameters GetFractionStackParameters(const ComputedStyle& style) {
+ FractionStackParameters parameters;
+
+ bool has_display_style = HasDisplayStyle(style);
+
+ // We try and read constants to draw the stack from the OpenType MATH and use
+ // fallback values otherwise.
+ // We use the fallback values suggested in the MATH table specification.
+ parameters.gap_min = LayoutUnit(
+ MathConstant(
+ style,
+ has_display_style
+ ? OpenTypeMathSupport::MathConstants::kStackDisplayStyleGapMin
+ : OpenTypeMathSupport::MathConstants::kStackGapMin)
+ .value_or((has_display_style ? 7 : 3) *
+ RuleThicknessFallback(style)));
+ // The MATH table specification does not suggest any values for shifts, so
+ // we leave them at zero.
+ parameters.top_shift_up = LayoutUnit(
+ MathConstant(
+ style,
+ has_display_style
+ ? OpenTypeMathSupport::MathConstants::kStackTopDisplayStyleShiftUp
+ : OpenTypeMathSupport::MathConstants::kStackTopShiftUp)
+ .value_or(0));
+ parameters.bottom_shift_down = LayoutUnit(
+ MathConstant(
+ style,
+ has_display_style
+ ? OpenTypeMathSupport::MathConstants::
+ kStackBottomDisplayStyleShiftDown
+ : OpenTypeMathSupport::MathConstants::kStackBottomShiftDown)
+ .value_or(0));
+
+ return parameters;
+}
+
+} // namespace
+
+NGMathFractionLayoutAlgorithm::NGMathFractionLayoutAlgorithm(
+ const NGLayoutAlgorithmParams& params)
+ : NGLayoutAlgorithm(params),
+ border_scrollbar_padding_(params.fragment_geometry.border +
+ params.fragment_geometry.padding +
+ params.fragment_geometry.scrollbar) {
+ DCHECK(params.space.IsNewFormattingContext());
+ container_builder_.SetIsNewFormattingContext(
+ params.space.IsNewFormattingContext());
+ container_builder_.SetInitialFragmentGeometry(params.fragment_geometry);
+ container_builder_.SetIsMathMLFraction();
+}
+
+void NGMathFractionLayoutAlgorithm::GatherChildren(NGBlockNode* numerator,
+ NGBlockNode* denominator) {
+ for (NGLayoutInputNode child = Node().FirstChild(); child;
+ child = child.NextSibling()) {
+ NGBlockNode block_child = To<NGBlockNode>(child);
+ if (child.IsOutOfFlowPositioned()) {
+ container_builder_.AddOutOfFlowChildCandidate(
+ block_child, {border_scrollbar_padding_.inline_start,
+ border_scrollbar_padding_.block_start});
+ continue;
+ }
+ if (!*numerator) {
+ *numerator = block_child;
+ continue;
+ }
+ if (!*denominator) {
+ *denominator = block_child;
+ continue;
+ }
+
+ NOTREACHED();
+ }
+
+ DCHECK(*numerator);
+ DCHECK(*denominator);
+}
+
+scoped_refptr<const NGLayoutResult> NGMathFractionLayoutAlgorithm::Layout() {
+ DCHECK(!BreakToken());
+
+ NGBlockNode numerator = nullptr;
+ 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);
+ 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);
+ scoped_refptr<const NGLayoutResult> denominator_layout_result =
+ denominator.Layout(denominator_space);
+ auto denominator_margins = ComputeMarginsFor(
+ denominator_space, denominator.Style(), ConstraintSpace());
+
+ NGBoxFragment numerator_fragment(
+ ConstraintSpace().GetWritingMode(), ConstraintSpace().Direction(),
+ To<NGPhysicalBoxFragment>(numerator_layout_result->PhysicalFragment()));
+ NGBoxFragment denominator_fragment(
+ ConstraintSpace().GetWritingMode(), ConstraintSpace().Direction(),
+ To<NGPhysicalBoxFragment>(denominator_layout_result->PhysicalFragment()));
+
+ LayoutUnit content_inline_size = std::max(
+ numerator_fragment.InlineSize() + numerator_margins.InlineSum(),
+ denominator_fragment.InlineSize() + denominator_margins.InlineSum());
+
+ LayoutUnit numerator_ascent =
+ numerator_margins.block_start +
+ numerator_fragment.Baseline().value_or(numerator_fragment.BlockSize());
+ LayoutUnit numerator_descent = numerator_fragment.BlockSize() +
+ numerator_margins.BlockSum() -
+ numerator_ascent;
+ LayoutUnit denominator_ascent = denominator_margins.block_start +
+ denominator_fragment.Baseline().value_or(
+ denominator_fragment.BlockSize());
+ LayoutUnit denominator_descent = denominator_fragment.BlockSize() +
+ denominator_margins.BlockSum() -
+ denominator_ascent;
+
+ LayoutUnit numerator_shift, denominator_shift;
+ LayoutUnit thickness = FractionLineThickness(Style());
+ if (thickness) {
+ LayoutUnit axis_height = MathAxisHeight(Style());
+ FractionParameters parameters = GetFractionParameters(Style());
+ numerator_shift =
+ std::max(parameters.numerator_min_shift_up,
+ axis_height + thickness / 2 + parameters.numerator_gap_min +
+ numerator_descent);
+ denominator_shift =
+ std::max(parameters.denominator_min_shift_down,
+ thickness / 2 + parameters.denominator_gap_min +
+ denominator_ascent - axis_height);
+ } else {
+ FractionStackParameters parameters = GetFractionStackParameters(Style());
+ numerator_shift = parameters.top_shift_up;
+ denominator_shift = parameters.bottom_shift_down;
+ LayoutUnit gap = denominator_shift - denominator_ascent + numerator_shift -
+ numerator_descent;
+ if (gap < parameters.gap_min) {
+ LayoutUnit diff = parameters.gap_min - gap;
+ LayoutUnit delta = diff / 2;
+ numerator_shift += delta;
+ denominator_shift += diff - delta;
+ }
+ }
+
+ LayoutUnit fraction_ascent =
+ std::max(numerator_shift + numerator_ascent,
+ -denominator_shift + denominator_ascent);
+ 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;
+ LayoutUnit total_block_size = fraction_ascent + fraction_descent;
+
+ container_builder_.SetBaseline(fraction_ascent);
+
+ LogicalOffset numerator_offset;
+ LogicalOffset denominator_offset;
+ numerator_offset.inline_offset =
+ border_scrollbar_padding_.inline_start + numerator_margins.inline_start +
+ (content_inline_size -
+ (numerator_fragment.InlineSize() + numerator_margins.InlineSum())) /
+ 2;
+ denominator_offset.inline_offset =
+ border_scrollbar_padding_.inline_start +
+ denominator_margins.inline_start +
+ (content_inline_size -
+ (denominator_fragment.InlineSize() + denominator_margins.InlineSum())) /
+ 2;
+
+ numerator_offset.block_offset = numerator_margins.block_start +
+ fraction_ascent - numerator_shift -
+ numerator_ascent;
+ denominator_offset.block_offset = denominator_margins.block_start +
+ fraction_ascent + denominator_shift -
+ denominator_ascent;
+
+ container_builder_.AddChild(numerator_layout_result->PhysicalFragment(),
+ numerator_offset);
+ container_builder_.AddChild(denominator_layout_result->PhysicalFragment(),
+ denominator_offset);
+
+ numerator.StoreMargins(ConstraintSpace(), numerator_margins);
+ denominator.StoreMargins(ConstraintSpace(), denominator_margins);
+
+ LayoutUnit block_size = ComputeBlockSizeForFragment(
+ ConstraintSpace(), Style(), border_scrollbar_padding_, total_block_size);
+
+ container_builder_.SetIntrinsicBlockSize(total_block_size);
+ container_builder_.SetBlockSize(block_size);
+
+ NGOutOfFlowLayoutPart(Node(), ConstraintSpace(), container_builder_.Borders(),
+ &container_builder_)
+ .Run();
+
+ return container_builder_.ToBoxFragment();
+}
+
+base::Optional<MinMaxSizes> NGMathFractionLayoutAlgorithm::ComputeMinMaxSizes(
+ const MinMaxSizesInput& input) const {
+ base::Optional<MinMaxSizes> sizes =
+ CalculateMinMaxSizesIgnoringChildren(Node(), border_scrollbar_padding_);
+ if (sizes)
+ return sizes;
+
+ sizes.emplace();
+ LayoutUnit child_percentage_resolution_block_size =
+ CalculateChildPercentageBlockSizeForMinMax(
+ ConstraintSpace(), Node(), border_scrollbar_padding_,
+ input.percentage_resolution_block_size);
+
+ MinMaxSizesInput child_input(child_percentage_resolution_block_size);
+
+ for (NGLayoutInputNode child = Node().FirstChild(); child;
+ child = child.NextSibling()) {
+ if (child.IsOutOfFlowPositioned())
+ continue;
+ auto child_sizes =
+ ComputeMinAndMaxContentContribution(Style(), child, child_input);
+ NGBoxStrut margins = ComputeMinMaxMargins(Style(), child);
+ child_sizes += margins.InlineSum();
+ sizes->Encompass(child_sizes);
+ }
+
+ *sizes += border_scrollbar_padding_.InlineSum();
+ return sizes;
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..d645439465f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.h
@@ -0,0 +1,31 @@
+// 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_MATH_FRACTION_LAYOUT_ALGORITHM_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_NG_MATH_FRACTION_LAYOUT_ALGORITHM_H_
+
+#include "third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.h"
+
+namespace blink {
+
+class CORE_EXPORT NGMathFractionLayoutAlgorithm
+ : public NGLayoutAlgorithm<NGBlockNode,
+ NGBoxFragmentBuilder,
+ NGBlockBreakToken> {
+ public:
+ explicit NGMathFractionLayoutAlgorithm(const NGLayoutAlgorithmParams& params);
+
+ private:
+ scoped_refptr<const NGLayoutResult> Layout() final;
+
+ base::Optional<MinMaxSizes> ComputeMinMaxSizes(
+ const MinMaxSizesInput&) const final;
+
+ void GatherChildren(NGBlockNode* numerator, NGBlockNode* denominator);
+ const NGBoxStrut border_scrollbar_padding_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_NG_MATH_FRACTION_LAYOUT_ALGORITHM_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_layout_utils.cc b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_layout_utils.cc
new file mode 100644
index 00000000000..44f6ed8d617
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_layout_utils.cc
@@ -0,0 +1,97 @@
+// 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/layout/ng/mathml/ng_math_layout_utils.h"
+
+#include "third_party/blink/renderer/core/layout/layout_box.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/ng_length_utils.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_space_utils.h"
+#include "third_party/blink/renderer/core/mathml/mathml_fraction_element.h"
+
+namespace blink {
+
+NGConstraintSpace CreateConstraintSpaceForMathChild(
+ const NGBlockNode& parent_node,
+ const LogicalSize& child_available_size,
+ const NGConstraintSpace& parent_constraint_space,
+ const NGLayoutInputNode& child) {
+ const ComputedStyle& parent_style = parent_node.Style();
+ const ComputedStyle& child_style = child.Style();
+ DCHECK(child.CreatesNewFormattingContext());
+ NGConstraintSpaceBuilder space_builder(parent_constraint_space,
+ child_style.GetWritingMode(),
+ true /* is_new_fc */);
+ SetOrthogonalFallbackInlineSizeIfNeeded(parent_style, child, &space_builder);
+
+ space_builder.SetAvailableSize(child_available_size);
+ space_builder.SetPercentageResolutionSize(child_available_size);
+ space_builder.SetReplacedPercentageResolutionSize(child_available_size);
+
+ space_builder.SetIsShrinkToFit(child_style.LogicalWidth().IsAuto());
+
+ // TODO(rbuis): add target stretch sizes.
+
+ space_builder.SetTextDirection(child_style.Direction());
+
+ // TODO(rbuis): add ink baselines?
+ space_builder.SetNeedsBaseline(true);
+ return space_builder.ToConstraintSpace();
+}
+
+NGLayoutInputNode FirstChildInFlow(const NGBlockNode& node) {
+ NGLayoutInputNode child = node.FirstChild();
+ while (child && child.IsOutOfFlowPositioned())
+ child = child.NextSibling();
+ return child;
+}
+
+NGLayoutInputNode NextSiblingInFlow(const NGBlockNode& node) {
+ NGLayoutInputNode sibling = node.NextSibling();
+ while (sibling && sibling.IsOutOfFlowPositioned())
+ sibling = sibling.NextSibling();
+ return sibling;
+}
+
+inline bool InFlowChildCountIs(const NGBlockNode& node, unsigned count) {
+ DCHECK(count == 2 || count == 3);
+ auto child = To<NGBlockNode>(FirstChildInFlow(node));
+ while (count && child) {
+ child = To<NGBlockNode>(NextSiblingInFlow(child));
+ count--;
+ }
+ return !count && !child;
+}
+
+bool IsValidMathMLFraction(const NGBlockNode& node) {
+ return InFlowChildCountIs(node, 2);
+}
+
+namespace {
+
+inline LayoutUnit DefaultFractionLineThickness(const ComputedStyle& style) {
+ return LayoutUnit(
+ MathConstant(style,
+ OpenTypeMathSupport::MathConstants::kFractionRuleThickness)
+ .value_or(RuleThicknessFallback(style)));
+}
+
+} // namespace
+
+LayoutUnit MathAxisHeight(const ComputedStyle& style) {
+ return LayoutUnit(
+ MathConstant(style, OpenTypeMathSupport::MathConstants::kAxisHeight)
+ .value_or(style.GetFont().PrimaryFont()->GetFontMetrics().XHeight() /
+ 2));
+}
+
+LayoutUnit FractionLineThickness(const ComputedStyle& style) {
+ return std::max<LayoutUnit>(
+ ValueForLength(style.GetMathFractionBarThickness(),
+ DefaultFractionLineThickness(style)),
+ LayoutUnit());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_layout_utils.h b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_layout_utils.h
new file mode 100644
index 00000000000..366e1a81171
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_layout_utils.h
@@ -0,0 +1,54 @@
+// 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_LAYOUT_NG_MATHML_NG_MATH_LAYOUT_UTILS_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_NG_MATH_LAYOUT_UTILS_H_
+
+#include "third_party/blink/renderer/core/style/computed_style.h"
+#include "third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.h"
+
+namespace blink {
+
+struct LogicalSize;
+class NGBlockNode;
+class NGConstraintSpace;
+class NGLayoutInputNode;
+
+// Creates a new constraint space for the current child.
+NGConstraintSpace CreateConstraintSpaceForMathChild(
+ const NGBlockNode& parent_node,
+ const LogicalSize& child_available_size,
+ const NGConstraintSpace& parent_constraint_space,
+ const NGLayoutInputNode&);
+
+NGLayoutInputNode FirstChildInFlow(const NGBlockNode&);
+NGLayoutInputNode NextSiblingInFlow(const NGBlockNode&);
+
+bool IsValidMathMLFraction(const NGBlockNode&);
+
+inline float RuleThicknessFallback(const ComputedStyle& style) {
+ // This function returns a value for the default rule thickness (TeX's
+ // \xi_8) to be used as a fallback when we lack a MATH table.
+ return 0.05f * style.FontSize();
+}
+
+LayoutUnit MathAxisHeight(const ComputedStyle& style);
+
+inline base::Optional<float> MathConstant(
+ const ComputedStyle& style,
+ OpenTypeMathSupport::MathConstants constant) {
+ return OpenTypeMathSupport::MathConstant(
+ style.GetFont().PrimaryFont()->PlatformData().GetHarfBuzzFace(),
+ constant);
+}
+
+LayoutUnit FractionLineThickness(const ComputedStyle& style);
+
+inline bool HasDisplayStyle(const ComputedStyle& style) {
+ return style.MathStyle() == EMathStyle::kDisplay;
+}
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_NG_MATH_LAYOUT_UTILS_H_
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
new file mode 100644
index 00000000000..6fe8785a1cc
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.cc
@@ -0,0 +1,180 @@
+// 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/layout/ng/mathml/ng_math_row_layout_algorithm.h"
+
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.h"
+#include "third_party/blink/renderer/core/layout/ng/mathml/ng_math_layout_utils.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.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_layout_part.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
+#include "third_party/blink/renderer/core/mathml/mathml_element.h"
+
+namespace blink {
+namespace {
+
+inline LayoutUnit InlineOffsetForDisplayMathCentering(
+ bool is_display_math,
+ LayoutUnit available_inline_size,
+ LayoutUnit max_row_inline_size) {
+ if (is_display_math)
+ return (available_inline_size - max_row_inline_size) / 2;
+ return LayoutUnit();
+}
+
+} // namespace
+
+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) {
+ DCHECK(params.space.IsNewFormattingContext());
+ DCHECK(!ConstraintSpace().HasBlockFragmentation());
+ container_builder_.SetIsNewFormattingContext(
+ params.space.IsNewFormattingContext());
+ container_builder_.SetInitialFragmentGeometry(params.fragment_geometry);
+}
+
+void NGMathRowLayoutAlgorithm::LayoutRowItems(
+ NGContainerFragmentBuilder::ChildrenVector* children,
+ LayoutUnit* max_row_block_baseline,
+ LogicalSize* row_total_size) {
+ LayoutUnit inline_offset, max_row_ascent, max_row_descent;
+ for (NGLayoutInputNode child = Node().FirstChild(); child;
+ child = child.NextSibling()) {
+ if (child.IsOutOfFlowPositioned()) {
+ // TODO(rbuis): OOF should be "where child would have been if not
+ // 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});
+ continue;
+ }
+ const ComputedStyle& child_style = child.Style();
+ NGConstraintSpace child_space = CreateConstraintSpaceForMathChild(
+ Node(), child_available_size_, ConstraintSpace(), child);
+ scoped_refptr<const NGLayoutResult> result =
+ To<NGBlockNode>(child).Layout(child_space, nullptr /* break token */);
+ const NGPhysicalContainerFragment& physical_fragment =
+ result->PhysicalFragment();
+ NGBoxFragment fragment(ConstraintSpace().GetWritingMode(),
+ ConstraintSpace().Direction(),
+ To<NGPhysicalBoxFragment>(physical_fragment));
+
+ NGBoxStrut margins =
+ ComputeMarginsFor(child_space, child_style, ConstraintSpace());
+ inline_offset += margins.inline_start;
+
+ LayoutUnit ascent = margins.block_start +
+ fragment.Baseline().value_or(fragment.BlockSize());
+ *max_row_block_baseline = std::max(*max_row_block_baseline, ascent);
+
+ // TODO(rbuis): Operators can add lspace and rspace.
+
+ children->emplace_back(
+ LogicalOffset{inline_offset, margins.block_start - ascent},
+ &physical_fragment);
+
+ inline_offset += fragment.InlineSize() + margins.inline_end;
+
+ max_row_ascent = std::max(max_row_ascent, ascent + margins.block_start);
+ max_row_descent = std::max(
+ max_row_descent, fragment.BlockSize() + margins.block_end - ascent);
+ row_total_size->inline_size =
+ std::max(row_total_size->inline_size, inline_offset);
+ }
+ row_total_size->block_size = max_row_ascent + max_row_descent;
+}
+
+scoped_refptr<const NGLayoutResult> NGMathRowLayoutAlgorithm::Layout() {
+ DCHECK(!BreakToken());
+
+ bool is_display_math =
+ Node().IsMathRoot() && Style().Display() == EDisplay::kMath;
+
+ LogicalSize max_row_size;
+ 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;
+ LayoutRowItems(&children, &max_row_block_baseline, &max_row_size);
+
+ // Add children taking into account centering, baseline and
+ // border/scrollbar/padding.
+ 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;
+ container_builder_.AddChild(
+ To<NGPhysicalContainerFragment>(*child.fragment), child.offset);
+ }
+
+ container_builder_.SetBaseline(border_scrollbar_padding_.block_start +
+ max_row_block_baseline);
+
+ auto block_size = ComputeBlockSizeForFragment(
+ ConstraintSpace(), Style(), border_padding_,
+ max_row_size.block_size + border_scrollbar_padding_.BlockSum());
+ container_builder_.SetBlockSize(block_size);
+
+ NGOutOfFlowLayoutPart(
+ Node(), ConstraintSpace(),
+ container_builder_.Borders() + container_builder_.Scrollbar(),
+ &container_builder_)
+ .Run();
+
+ return container_builder_.ToBoxFragment();
+}
+
+base::Optional<MinMaxSizes> NGMathRowLayoutAlgorithm::ComputeMinMaxSizes(
+ const MinMaxSizesInput& input) const {
+ base::Optional<MinMaxSizes> sizes =
+ CalculateMinMaxSizesIgnoringChildren(Node(), border_scrollbar_padding_);
+ if (sizes)
+ return sizes;
+
+ sizes.emplace();
+ LayoutUnit child_percentage_resolution_block_size =
+ CalculateChildPercentageBlockSizeForMinMax(
+ ConstraintSpace(), Node(), border_padding_,
+ input.percentage_resolution_block_size);
+
+ MinMaxSizesInput child_input(child_percentage_resolution_block_size);
+
+ for (NGLayoutInputNode child = Node().FirstChild(); child;
+ child = child.NextSibling()) {
+ if (child.IsOutOfFlowPositioned())
+ continue;
+ MinMaxSizes child_min_max_sizes =
+ ComputeMinAndMaxContentContribution(Style(), child, child_input);
+ NGBoxStrut child_margins = ComputeMinMaxMargins(Style(), child);
+ child_min_max_sizes += child_margins.InlineSum();
+ sizes->max_size += child_min_max_sizes.max_size;
+ sizes->min_size += child_min_max_sizes.min_size;
+
+ // TODO(rbuis): Operators can add lspace and rspace.
+ }
+ sizes->max_size = std::max(sizes->max_size, sizes->min_size);
+
+ // 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();
+ return sizes;
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..72b8dd10b40
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.h
@@ -0,0 +1,42 @@
+// 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_LAYOUT_NG_MATHML_NG_MATH_ROW_LAYOUT_ALGORITHM_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_NG_MATH_ROW_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_block_node.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h"
+
+namespace blink {
+
+class LayoutUnit;
+
+class CORE_EXPORT NGMathRowLayoutAlgorithm
+ : public NGLayoutAlgorithm<NGBlockNode,
+ NGBoxFragmentBuilder,
+ NGBlockBreakToken> {
+ public:
+ NGMathRowLayoutAlgorithm(const NGLayoutAlgorithmParams& params);
+
+ protected:
+ void LayoutRowItems(NGContainerFragmentBuilder::ChildrenVector*,
+ LayoutUnit* max_row_block_baseline,
+ LogicalSize* row_total_size);
+
+ private:
+ scoped_refptr<const NGLayoutResult> Layout() final;
+
+ base::Optional<MinMaxSizes> ComputeMinMaxSizes(
+ const MinMaxSizesInput&) const final;
+
+ LogicalSize child_available_size_;
+ const NGBoxStrut border_padding_;
+ const NGBoxStrut border_scrollbar_padding_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_NG_MATH_ROW_LAYOUT_ALGORITHM_H_
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
new file mode 100644
index 00000000000..4abfa765870
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_layout_algorithm.cc
@@ -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.
+
+#include "third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_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_length_utils.h"
+
+namespace blink {
+
+NGMathSpaceLayoutAlgorithm::NGMathSpaceLayoutAlgorithm(
+ const NGLayoutAlgorithmParams& params)
+ : NGLayoutAlgorithm(params),
+ border_padding_(params.fragment_geometry.border +
+ params.fragment_geometry.padding) {
+ DCHECK(params.fragment_geometry.scrollbar.IsEmpty());
+ container_builder_.SetIsNewFormattingContext(true);
+ container_builder_.SetInitialFragmentGeometry(params.fragment_geometry);
+}
+
+scoped_refptr<const NGLayoutResult> NGMathSpaceLayoutAlgorithm::Layout() {
+ DCHECK(!BreakToken());
+
+ LayoutUnit block_size = ComputeBlockSizeForFragment(
+ ConstraintSpace(), Style(), border_padding_, border_padding_.BlockSum());
+
+ container_builder_.SetIntrinsicBlockSize(border_padding_.BlockSum());
+ container_builder_.SetBlockSize(block_size);
+
+ container_builder_.SetBaseline(
+ border_padding_.block_start +
+ ValueForLength(Style().GetMathBaseline(), LayoutUnit()));
+ return container_builder_.ToBoxFragment();
+}
+
+base::Optional<MinMaxSizes> NGMathSpaceLayoutAlgorithm::ComputeMinMaxSizes(
+ const MinMaxSizesInput& input) const {
+ return CalculateMinMaxSizesIgnoringChildren(Node(), border_padding_);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..7b493ef0b17
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_layout_algorithm.h
@@ -0,0 +1,31 @@
+// 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_MATH_SPACE_LAYOUT_ALGORITHM_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_NG_MATH_SPACE_LAYOUT_ALGORITHM_H_
+
+#include "third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h"
+
+namespace blink {
+
+class CORE_EXPORT NGMathSpaceLayoutAlgorithm
+ : public NGLayoutAlgorithm<NGBlockNode,
+ NGBoxFragmentBuilder,
+ NGBlockBreakToken> {
+ public:
+ explicit NGMathSpaceLayoutAlgorithm(const NGLayoutAlgorithmParams& params);
+
+ private:
+ scoped_refptr<const NGLayoutResult> Layout() final;
+
+ base::Optional<MinMaxSizes> ComputeMinMaxSizes(
+ const MinMaxSizesInput&) const final;
+
+ const NGBoxStrut border_padding_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_MATHML_NG_MATH_SPACE_LAYOUT_ALGORITHM_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 d6c66b0b708..fd2180c4c50 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
@@ -31,7 +31,7 @@ bool IsLogicalWidthTreatedAsAuto(const ComputedStyle& style) {
return IsTable(style) || style.LogicalWidth().IsAuto();
}
-bool IsLogicalHeightTreatAsAuto(const ComputedStyle& style) {
+bool IsLogicalHeightTreatedAsAuto(const ComputedStyle& style) {
return IsTable(style) || style.LogicalHeight().IsAuto();
}
@@ -111,11 +111,11 @@ inline LayoutUnit StaticPositionEndInset(StaticPositionEdge edge,
}
LayoutUnit ComputeShrinkToFitSize(
- const base::Optional<MinMaxSize>& child_minmax,
+ const base::Optional<MinMaxSizes>& min_max_sizes,
LayoutUnit computed_available_size,
LayoutUnit margin_start,
LayoutUnit margin_end) {
- return child_minmax->ShrinkToFit(
+ return min_max_sizes->ShrinkToFit(
(computed_available_size - margin_start - margin_end)
.ClampNegativeToZero());
}
@@ -123,10 +123,10 @@ LayoutUnit ComputeShrinkToFitSize(
// Implement the absolute size resolution algorithm.
// https://www.w3.org/TR/css-position-3/#abs-non-replaced-width
// https://www.w3.org/TR/css-position-3/#abs-non-replaced-height
-// |child_minmax| can have no value if an element is replaced, and has no
+// |min_max_sizes| can have no value if an element is replaced, and has no
// intrinsic width or height, but has an aspect ratio.
void ComputeAbsoluteSize(const LayoutUnit border_padding_size,
- const base::Optional<MinMaxSize>& child_minmax,
+ const base::Optional<MinMaxSizes>& min_max_sizes,
const LayoutUnit margin_percentage_resolution_size,
const LayoutUnit available_size,
const Length& margin_start_length,
@@ -199,7 +199,7 @@ void ComputeAbsoluteSize(const LayoutUnit border_padding_size,
computed_available_size = static_position_offset;
break;
}
- size = ComputeShrinkToFitSize(child_minmax, computed_available_size,
+ size = ComputeShrinkToFitSize(min_max_sizes, computed_available_size,
*margin_start, *margin_end);
LayoutUnit margin_size = *size + *margin_start + *margin_end;
if (is_start_dominant) {
@@ -259,7 +259,7 @@ void ComputeAbsoluteSize(const LayoutUnit border_padding_size,
// Rule 1: left/width are unknown.
DCHECK(inset_end.has_value());
LayoutUnit computed_available_size = available_size - *inset_end;
- size = ComputeShrinkToFitSize(child_minmax, computed_available_size,
+ size = ComputeShrinkToFitSize(min_max_sizes, computed_available_size,
*margin_start, *margin_end);
} else if (!inset_start && !inset_end) {
// Rule 2.
@@ -276,7 +276,7 @@ void ComputeAbsoluteSize(const LayoutUnit border_padding_size,
} else if (!size && !inset_end) {
// Rule 3.
LayoutUnit computed_available_size = available_size - *inset_start;
- size = ComputeShrinkToFitSize(child_minmax, computed_available_size,
+ size = ComputeShrinkToFitSize(min_max_sizes, computed_available_size,
*margin_start, *margin_end);
}
@@ -300,7 +300,7 @@ void ComputeAbsoluteSize(const LayoutUnit border_padding_size,
// is safe to recursively call ourselves here because on the second call it
// is guaranteed to be within |min_size| and |max_size|.
ComputeAbsoluteSize(
- border_padding_size, child_minmax, margin_percentage_resolution_size,
+ border_padding_size, min_max_sizes, margin_percentage_resolution_size,
available_size, margin_start_length, margin_end_length,
inset_start_length, inset_end_length, min_size, max_size,
static_position_offset, static_position_edge, is_start_dominant,
@@ -334,7 +334,7 @@ bool AbsoluteNeedsChildBlockSize(const ComputedStyle& style) {
return is_logical_height_intrinsic ||
style.LogicalMinHeight().IsIntrinsic() ||
style.LogicalMaxHeight().IsIntrinsic() ||
- (IsLogicalHeightTreatAsAuto(style) &&
+ (IsLogicalHeightTreatedAsAuto(style) &&
(style.LogicalTop().IsAuto() || style.LogicalBottom().IsAuto()));
}
@@ -382,30 +382,31 @@ base::Optional<LayoutUnit> ComputeAbsoluteDialogYPosition(
return top;
}
-NGLogicalOutOfFlowPosition ComputePartialAbsoluteWithChildInlineSize(
+void ComputeOutOfFlowInlineDimensions(
const NGConstraintSpace& space,
const ComputedStyle& style,
const NGBoxStrut& border_padding,
const NGLogicalStaticPosition& static_position,
- const base::Optional<MinMaxSize>& child_minmax,
+ const base::Optional<MinMaxSizes>& min_max_sizes,
const base::Optional<LogicalSize>& replaced_size,
const WritingMode container_writing_mode,
- const TextDirection container_direction) {
- NGLogicalOutOfFlowPosition position;
+ const TextDirection container_direction,
+ NGLogicalOutOfFlowDimensions* dimensions) {
+ DCHECK(dimensions);
base::Optional<LayoutUnit> inline_size;
if (!IsLogicalWidthTreatedAsAuto(style)) {
inline_size = ResolveMainInlineLength(space, style, border_padding,
- child_minmax, style.LogicalWidth());
+ min_max_sizes, style.LogicalWidth());
} else if (replaced_size.has_value()) {
inline_size = replaced_size->inline_size;
}
LayoutUnit min_inline_size = ResolveMinInlineLength(
- space, style, border_padding, child_minmax, style.LogicalMinWidth(),
+ space, style, border_padding, min_max_sizes, style.LogicalMinWidth(),
LengthResolvePhase::kLayout);
LayoutUnit max_inline_size = ResolveMaxInlineLength(
- space, style, border_padding, child_minmax, style.LogicalMaxWidth(),
+ space, style, border_padding, min_max_sizes, style.LogicalMaxWidth(),
LengthResolvePhase::kLayout);
// Tables use the inline-size as a minimum.
@@ -413,7 +414,7 @@ NGLogicalOutOfFlowPosition ComputePartialAbsoluteWithChildInlineSize(
min_inline_size =
std::max(min_inline_size,
ResolveMainInlineLength(space, style, border_padding,
- child_minmax, style.LogicalWidth()));
+ min_max_sizes, style.LogicalWidth()));
}
bool is_start_dominant;
@@ -428,20 +429,19 @@ NGLogicalOutOfFlowPosition ComputePartialAbsoluteWithChildInlineSize(
}
ComputeAbsoluteSize(
- border_padding.InlineSum(), child_minmax,
+ border_padding.InlineSum(), min_max_sizes,
space.PercentageResolutionInlineSizeForParentWritingMode(),
space.AvailableSize().inline_size, style.MarginStart(), style.MarginEnd(),
style.LogicalInlineStart(), style.LogicalInlineEnd(), min_inline_size,
max_inline_size, static_position.offset.inline_offset,
GetStaticPositionEdge(static_position.inline_edge), is_start_dominant,
- false /* is_block_direction */, inline_size, &position.size.inline_size,
- &position.inset.inline_start, &position.inset.inline_end,
- &position.margins.inline_start, &position.margins.inline_end);
-
- return position;
+ false /* is_block_direction */, inline_size,
+ &dimensions->size.inline_size, &dimensions->inset.inline_start,
+ &dimensions->inset.inline_end, &dimensions->margins.inline_start,
+ &dimensions->margins.inline_end);
}
-void ComputeFullAbsoluteWithChildBlockSize(
+void ComputeOutOfFlowBlockDimensions(
const NGConstraintSpace& space,
const ComputedStyle& style,
const NGBoxStrut& border_padding,
@@ -450,20 +450,20 @@ void ComputeFullAbsoluteWithChildBlockSize(
const base::Optional<LogicalSize>& replaced_size,
const WritingMode container_writing_mode,
const TextDirection container_direction,
- NGLogicalOutOfFlowPosition* position) {
+ NGLogicalOutOfFlowDimensions* dimensions) {
// After partial size has been computed, child block size is either unknown,
// or fully computed, there is no minmax. To express this, a 'fixed' minmax
// is created where min and max are the same.
- base::Optional<MinMaxSize> child_minmax;
+ base::Optional<MinMaxSizes> min_max_sizes;
if (child_block_size.has_value()) {
- child_minmax = MinMaxSize{*child_block_size, *child_block_size};
+ min_max_sizes = MinMaxSizes{*child_block_size, *child_block_size};
}
LayoutUnit child_block_size_or_indefinite =
child_block_size.value_or(kIndefiniteSize);
base::Optional<LayoutUnit> block_size;
- if (!IsLogicalHeightTreatAsAuto(style)) {
+ if (!IsLogicalHeightTreatedAsAuto(style)) {
block_size = ResolveMainBlockLength(
space, style, border_padding, style.LogicalHeight(),
child_block_size_or_indefinite, LengthResolvePhase::kLayout);
@@ -473,10 +473,10 @@ void ComputeFullAbsoluteWithChildBlockSize(
LayoutUnit min_block_size = ResolveMinBlockLength(
space, style, border_padding, style.LogicalMinHeight(),
- child_block_size_or_indefinite, LengthResolvePhase::kLayout);
+ LengthResolvePhase::kLayout);
LayoutUnit max_block_size = ResolveMaxBlockLength(
space, style, border_padding, style.LogicalMaxHeight(),
- child_block_size_or_indefinite, LengthResolvePhase::kLayout);
+ LengthResolvePhase::kLayout);
bool is_start_dominant;
if (style.GetWritingMode() == WritingMode::kHorizontalTb) {
@@ -490,15 +490,15 @@ void ComputeFullAbsoluteWithChildBlockSize(
}
ComputeAbsoluteSize(
- border_padding.BlockSum(), child_minmax,
+ border_padding.BlockSum(), min_max_sizes,
space.PercentageResolutionInlineSizeForParentWritingMode(),
space.AvailableSize().block_size, style.MarginBefore(),
style.MarginAfter(), style.LogicalTop(), style.LogicalBottom(),
min_block_size, max_block_size, static_position.offset.block_offset,
GetStaticPositionEdge(static_position.block_edge), is_start_dominant,
- true /* is_block_direction */, block_size, &position->size.block_size,
- &position->inset.block_start, &position->inset.block_end,
- &position->margins.block_start, &position->margins.block_end);
+ true /* is_block_direction */, block_size, &dimensions->size.block_size,
+ &dimensions->inset.block_start, &dimensions->inset.block_end,
+ &dimensions->margins.block_start, &dimensions->margins.block_end);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h
index bcfa41fc6a7..5c2f3694cb8 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h
@@ -9,7 +9,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/geometry/logical_size.h"
#include "third_party/blink/renderer/core/layout/geometry/physical_size.h"
-#include "third_party/blink/renderer/core/layout/min_max_size.h"
+#include "third_party/blink/renderer/core/layout/min_max_sizes.h"
#include "third_party/blink/renderer/platform/geometry/layout_unit.h"
namespace blink {
@@ -19,7 +19,7 @@ class LayoutObject;
class NGConstraintSpace;
struct NGLogicalStaticPosition;
-struct CORE_EXPORT NGLogicalOutOfFlowPosition {
+struct CORE_EXPORT NGLogicalOutOfFlowDimensions {
NGBoxStrut inset;
LogicalSize size;
NGBoxStrut margins;
@@ -36,43 +36,43 @@ CORE_EXPORT base::Optional<LayoutUnit> ComputeAbsoluteDialogYPosition(
// The following routines implement the absolute size resolution algorithm.
// https://www.w3.org/TR/css-position-3/#abs-non-replaced-width
//
-// The size is computed as |NGLogicalOutOfFlowPosition|.
+// The size is computed as |NGLogicalOutOfFlowDimensions|.
// It needs to be computed in 4 stages:
// 1. If |AbsoluteNeedsChildInlineSize| is true, compute estimated inline_size
-// using |NGBlockNode::MinMaxSize|.
-// 2. Compute part of the |NGLogicalOutOfFlowPosition| which depends on the
-// child inline-size with |ComputePartialAbsoluteWithChildInlineSize|.
+// using |NGBlockNode::ComputeMinMaxSize|.
+// 2. Compute part of the |NGLogicalOutOfFlowDimensions| which depends on the
+// child inline-size with |ComputeOutOfFlowInlineDimensions|.
// 3. If |AbsoluteNeedsChildBlockSize| is true, compute estimated block_size by
// performing layout with the inline_size calculated from (2).
-// 4. Compute the full |NGLogicalOutOfFlowPosition| with
-// |ComputeFullAbsoluteWithChildBlockSize|.
+// 4. Compute the full |NGLogicalOutOfFlowDimensions| with
+// |ComputeOutOfFlowBlockDimensions|.
-// Returns true if |ComputePartialAbsoluteWithChildInlineSize| will need an
-// estimated inline-size.
+// Returns true if |ComputeOutOfFlowInlineDimensions| will need an estimated
+// inline-size.
CORE_EXPORT bool AbsoluteNeedsChildInlineSize(const ComputedStyle&);
-// Returns true if |ComputeFullAbsoluteWithChildBlockSize| will need an
-// estimated block-size.
+// Returns true if |ComputeOutOfFlowBlockDimensions| will need an estimated
+// block-size.
CORE_EXPORT bool AbsoluteNeedsChildBlockSize(const ComputedStyle&);
// Computes part of the absolute position which depends on the child's
// inline-size.
// |replaced_size| should be set if and only if element is replaced element.
// Returns the partially filled position.
-CORE_EXPORT NGLogicalOutOfFlowPosition
-ComputePartialAbsoluteWithChildInlineSize(
+CORE_EXPORT void ComputeOutOfFlowInlineDimensions(
const NGConstraintSpace&,
const ComputedStyle&,
const NGBoxStrut& border_padding,
const NGLogicalStaticPosition&,
- const base::Optional<MinMaxSize>& child_minmax,
+ const base::Optional<MinMaxSizes>& child_minmax,
const base::Optional<LogicalSize>& replaced_size,
const WritingMode container_writing_mode,
- const TextDirection container_direction);
+ const TextDirection container_direction,
+ NGLogicalOutOfFlowDimensions* dimensions);
// Computes the rest of the absolute position which depends on child's
// block-size.
-CORE_EXPORT void ComputeFullAbsoluteWithChildBlockSize(
+CORE_EXPORT void ComputeOutOfFlowBlockDimensions(
const NGConstraintSpace&,
const ComputedStyle&,
const NGBoxStrut& border_padding,
@@ -81,7 +81,7 @@ CORE_EXPORT void ComputeFullAbsoluteWithChildBlockSize(
const base::Optional<LogicalSize>& replaced_size,
const WritingMode container_writing_mode,
const TextDirection container_direction,
- NGLogicalOutOfFlowPosition* position);
+ NGLogicalOutOfFlowDimensions* dimensions);
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_absolute_utils_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_absolute_utils_test.cc
index 86af90137d8..dac7b8f79c4 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_absolute_utils_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_absolute_utils_test.cc
@@ -118,10 +118,10 @@ TEST_F(NGAbsoluteUtilsTest, Horizontal) {
LayoutUnit width =
container_size_.inline_size - left - margin_left - right - margin_right;
- base::Optional<MinMaxSize> estimated_inline;
+ base::Optional<MinMaxSizes> estimated_inline;
base::Optional<LayoutUnit> estimated_block;
- MinMaxSize minmax_60{LayoutUnit(60) + horizontal_border_padding,
- LayoutUnit(60) + horizontal_border_padding};
+ MinMaxSizes min_max_60{LayoutUnit(60) + horizontal_border_padding,
+ LayoutUnit(60) + horizontal_border_padding};
style_->SetBorderLeftWidth(border_left.ToInt());
style_->SetBorderRightWidth(border_right.ToInt());
@@ -154,151 +154,154 @@ TEST_F(NGAbsoluteUtilsTest, Horizontal) {
// Tests.
//
- NGLogicalOutOfFlowPosition p;
+ NGLogicalOutOfFlowDimensions dimensions;
// All auto => width is estimated_inline, left is 0.
SetHorizontalStyle(NGAuto, NGAuto, NGAuto, NGAuto, NGAuto);
EXPECT_EQ(AbsoluteNeedsChildInlineSize(*style_), true);
- estimated_inline = minmax_60;
- p = ComputePartialAbsoluteWithChildInlineSize(
- ltr_space_, *style_, ltr_border_padding, static_position,
- estimated_inline, base::nullopt, WritingMode::kHorizontalTb,
- TextDirection::kLtr);
- EXPECT_EQ(minmax_60.min_size, p.size.inline_size);
- EXPECT_EQ(LayoutUnit(0), p.inset.inline_start);
+ estimated_inline = min_max_60;
+ ComputeOutOfFlowInlineDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, estimated_inline,
+ base::nullopt, WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(min_max_60.min_size, dimensions.size.inline_size);
+ EXPECT_EQ(LayoutUnit(0), dimensions.inset.inline_start);
// All auto => width is estimated_inline, static_position is right
SetHorizontalStyle(NGAuto, NGAuto, NGAuto, NGAuto, NGAuto);
EXPECT_EQ(AbsoluteNeedsChildInlineSize(*style_), true);
- estimated_inline = minmax_60;
- p = ComputePartialAbsoluteWithChildInlineSize(
- ltr_space_, *style_, ltr_border_padding, static_position_inline_end,
- estimated_inline, base::nullopt, WritingMode::kHorizontalTb,
- TextDirection::kLtr);
- EXPECT_EQ(minmax_60.min_size, p.size.inline_size);
- EXPECT_EQ(container_size_.inline_size, p.inset.inline_end);
+ estimated_inline = min_max_60;
+ ComputeOutOfFlowInlineDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position_inline_end, estimated_inline,
+ base::nullopt, WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(min_max_60.min_size, dimensions.size.inline_size);
+ EXPECT_EQ(container_size_.inline_size, dimensions.inset.inline_end);
// All auto + RTL.
- p = ComputePartialAbsoluteWithChildInlineSize(
- rtl_space_, *style_, rtl_border_padding, static_position,
- estimated_inline, base::nullopt, WritingMode::kHorizontalTb,
- TextDirection::kLtr);
- EXPECT_EQ(minmax_60.min_size, p.size.inline_size);
- EXPECT_EQ(container_size_.inline_size - minmax_60.min_size,
- p.inset.inline_end);
+ ComputeOutOfFlowInlineDimensions(rtl_space_, *style_, rtl_border_padding,
+ static_position, estimated_inline,
+ base::nullopt, WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(min_max_60.min_size, dimensions.size.inline_size);
+ EXPECT_EQ(container_size_.inline_size - min_max_60.min_size,
+ dimensions.inset.inline_end);
// left, right, and left are known, compute margins.
SetHorizontalStyle(left, NGAuto, width, NGAuto, right);
EXPECT_EQ(AbsoluteNeedsChildInlineSize(*style_), false);
estimated_inline.reset();
- p = ComputePartialAbsoluteWithChildInlineSize(
- ltr_space_, *style_, ltr_border_padding, static_position,
- estimated_inline, base::nullopt, WritingMode::kHorizontalTb,
- TextDirection::kLtr);
- LayoutUnit margin_space =
- (container_size_.inline_size - left - right - p.size.inline_size) / 2;
- EXPECT_EQ(left + margin_space, p.inset.inline_start);
- EXPECT_EQ(right + margin_space, p.inset.inline_end);
+ ComputeOutOfFlowInlineDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, estimated_inline,
+ base::nullopt, WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ LayoutUnit margin_space = (container_size_.inline_size - left - right -
+ dimensions.size.inline_size) /
+ 2;
+ EXPECT_EQ(left + margin_space, dimensions.inset.inline_start);
+ EXPECT_EQ(right + margin_space, dimensions.inset.inline_end);
// left, right, and left are known, compute margins, writing mode vertical_lr.
SetHorizontalStyle(left, NGAuto, width, NGAuto, right,
WritingMode::kVerticalLr);
EXPECT_EQ(AbsoluteNeedsChildBlockSize(*style_), false);
estimated_inline.reset();
- ComputeFullAbsoluteWithChildBlockSize(
- vlr_space_, *style_, vlr_border_padding, static_position, estimated_block,
- base::nullopt, WritingMode::kHorizontalTb, TextDirection::kLtr, &p);
- EXPECT_EQ(left + margin_space, p.inset.block_start);
- EXPECT_EQ(right + margin_space, p.inset.block_end);
+ ComputeOutOfFlowBlockDimensions(vlr_space_, *style_, vlr_border_padding,
+ static_position, estimated_block,
+ base::nullopt, WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(left + margin_space, dimensions.inset.block_start);
+ EXPECT_EQ(right + margin_space, dimensions.inset.block_end);
// left, right, and left are known, compute margins, writing mode vertical_rl.
SetHorizontalStyle(left, NGAuto, width, NGAuto, right,
WritingMode::kVerticalRl);
EXPECT_EQ(AbsoluteNeedsChildBlockSize(*style_), false);
estimated_inline.reset();
- ComputeFullAbsoluteWithChildBlockSize(
- vrl_space_, *style_, vrl_border_padding, static_position, estimated_block,
- base::nullopt, WritingMode::kHorizontalTb, TextDirection::kLtr, &p);
- EXPECT_EQ(left + margin_space, p.inset.block_end);
- EXPECT_EQ(right + margin_space, p.inset.block_start);
+ ComputeOutOfFlowBlockDimensions(vrl_space_, *style_, vrl_border_padding,
+ static_position, estimated_block,
+ base::nullopt, WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(left + margin_space, dimensions.inset.block_end);
+ EXPECT_EQ(right + margin_space, dimensions.inset.block_start);
// left, right, and width are known, not enough space for margins LTR.
SetHorizontalStyle(left, NGAuto, LayoutUnit(200), NGAuto, right);
estimated_inline.reset();
- p = ComputePartialAbsoluteWithChildInlineSize(
- ltr_space_, *style_, ltr_border_padding, static_position,
- estimated_inline, base::nullopt, WritingMode::kHorizontalTb,
- TextDirection::kLtr);
- EXPECT_EQ(left, p.inset.inline_start);
- EXPECT_EQ(-left, p.inset.inline_end);
+ ComputeOutOfFlowInlineDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, estimated_inline,
+ base::nullopt, WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(left, dimensions.inset.inline_start);
+ EXPECT_EQ(-left, dimensions.inset.inline_end);
// left, right, and left are known, not enough space for margins RTL.
SetHorizontalStyle(left, NGAuto, LayoutUnit(200), NGAuto, right,
WritingMode::kHorizontalTb);
estimated_inline.reset();
- p = ComputePartialAbsoluteWithChildInlineSize(
- rtl_space_, *style_, rtl_border_padding, static_position,
- estimated_inline, base::nullopt, WritingMode::kHorizontalTb,
- TextDirection::kRtl);
- EXPECT_EQ(-right, p.inset.inline_start);
- EXPECT_EQ(right, p.inset.inline_end);
+ ComputeOutOfFlowInlineDimensions(rtl_space_, *style_, rtl_border_padding,
+ static_position, estimated_inline,
+ base::nullopt, WritingMode::kHorizontalTb,
+ TextDirection::kRtl, &dimensions);
+ EXPECT_EQ(-right, dimensions.inset.inline_start);
+ EXPECT_EQ(right, dimensions.inset.inline_end);
// Rule 1 left and width are auto.
SetHorizontalStyle(NGAuto, margin_left, NGAuto, margin_right, right);
EXPECT_EQ(AbsoluteNeedsChildInlineSize(*style_), true);
- estimated_inline = minmax_60;
- p = ComputePartialAbsoluteWithChildInlineSize(
- ltr_space_, *style_, ltr_border_padding, static_position,
- estimated_inline, base::nullopt, WritingMode::kHorizontalTb,
- TextDirection::kLtr);
- EXPECT_EQ(minmax_60.min_size, p.size.inline_size);
+ estimated_inline = min_max_60;
+ ComputeOutOfFlowInlineDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, estimated_inline,
+ base::nullopt, WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(min_max_60.min_size, dimensions.size.inline_size);
// Rule 2 left and right are auto LTR.
SetHorizontalStyle(NGAuto, margin_left, width, margin_right, NGAuto);
EXPECT_EQ(AbsoluteNeedsChildInlineSize(*style_), false);
estimated_inline.reset();
- p = ComputePartialAbsoluteWithChildInlineSize(
- ltr_space_, *style_, ltr_border_padding, static_position,
- estimated_inline, base::nullopt, WritingMode::kHorizontalTb,
- TextDirection::kLtr);
- EXPECT_EQ(margin_left, p.inset.inline_start);
+ ComputeOutOfFlowInlineDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, estimated_inline,
+ base::nullopt, WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(margin_left, dimensions.inset.inline_start);
EXPECT_EQ(container_size_.inline_size - margin_left - width,
- p.inset.inline_end);
+ dimensions.inset.inline_end);
// Rule 2 left and right are auto RTL.
SetHorizontalStyle(NGAuto, margin_left, width, margin_right, NGAuto);
EXPECT_EQ(AbsoluteNeedsChildInlineSize(*style_), false);
estimated_inline.reset();
- p = ComputePartialAbsoluteWithChildInlineSize(
- rtl_space_, *style_, rtl_border_padding, static_position,
- estimated_inline, base::nullopt, WritingMode::kHorizontalTb,
- TextDirection::kLtr);
- EXPECT_EQ(margin_left, p.inset.inline_start);
+ ComputeOutOfFlowInlineDimensions(rtl_space_, *style_, rtl_border_padding,
+ static_position, estimated_inline,
+ base::nullopt, WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(margin_left, dimensions.inset.inline_start);
EXPECT_EQ(container_size_.inline_size - margin_left - width,
- p.inset.inline_end);
+ dimensions.inset.inline_end);
// Rule 3 width and right are auto.
SetHorizontalStyle(left, margin_left, NGAuto, margin_right, NGAuto);
EXPECT_EQ(AbsoluteNeedsChildInlineSize(*style_), true);
- estimated_inline = minmax_60;
- p = ComputePartialAbsoluteWithChildInlineSize(
- ltr_space_, *style_, ltr_border_padding, static_position,
- estimated_inline, base::nullopt, WritingMode::kHorizontalTb,
- TextDirection::kLtr);
+ estimated_inline = min_max_60;
+ ComputeOutOfFlowInlineDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, estimated_inline,
+ base::nullopt, WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
EXPECT_EQ(
- container_size_.inline_size - minmax_60.min_size - left - margin_left,
- p.inset.inline_end);
- EXPECT_EQ(minmax_60.min_size, p.size.inline_size);
+ container_size_.inline_size - min_max_60.min_size - left - margin_left,
+ dimensions.inset.inline_end);
+ EXPECT_EQ(min_max_60.min_size, dimensions.size.inline_size);
// Rule 4: left is auto.
SetHorizontalStyle(NGAuto, margin_left, width, margin_right, right);
EXPECT_EQ(AbsoluteNeedsChildInlineSize(*style_), false);
estimated_inline.reset();
- p = ComputePartialAbsoluteWithChildInlineSize(
- ltr_space_, *style_, ltr_border_padding, static_position,
- estimated_inline, base::nullopt, WritingMode::kHorizontalTb,
- TextDirection::kLtr);
- EXPECT_EQ(left + margin_left, p.inset.inline_start);
+ ComputeOutOfFlowInlineDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, estimated_inline,
+ base::nullopt, WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(left + margin_left, dimensions.inset.inline_start);
// Rule 4: left is auto, EBoxSizing::kContentBox
style_->SetBoxSizing(EBoxSizing::kContentBox);
@@ -307,32 +310,32 @@ TEST_F(NGAbsoluteUtilsTest, Horizontal) {
margin_right, right);
EXPECT_EQ(AbsoluteNeedsChildInlineSize(*style_), false);
estimated_inline.reset();
- p = ComputePartialAbsoluteWithChildInlineSize(
- ltr_space_, *style_, ltr_border_padding, static_position,
- estimated_inline, base::nullopt, WritingMode::kHorizontalTb,
- TextDirection::kLtr);
- EXPECT_EQ(left + margin_left, p.inset.inline_start);
+ ComputeOutOfFlowInlineDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, estimated_inline,
+ base::nullopt, WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(left + margin_left, dimensions.inset.inline_start);
style_->SetBoxSizing(EBoxSizing::kBorderBox);
// Rule 5: right is auto.
SetHorizontalStyle(left, margin_left, width, margin_right, NGAuto);
EXPECT_EQ(AbsoluteNeedsChildInlineSize(*style_), false);
estimated_inline.reset();
- p = ComputePartialAbsoluteWithChildInlineSize(
- ltr_space_, *style_, ltr_border_padding, static_position,
- estimated_inline, base::nullopt, WritingMode::kHorizontalTb,
- TextDirection::kLtr);
- EXPECT_EQ(right + margin_right, p.inset.inline_end);
+ ComputeOutOfFlowInlineDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, estimated_inline,
+ base::nullopt, WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(right + margin_right, dimensions.inset.inline_end);
// Rule 6: width is auto.
SetHorizontalStyle(left, margin_left, NGAuto, margin_right, right);
EXPECT_EQ(AbsoluteNeedsChildInlineSize(*style_), false);
estimated_inline.reset();
- p = ComputePartialAbsoluteWithChildInlineSize(
- ltr_space_, *style_, ltr_border_padding, static_position,
- estimated_inline, base::nullopt, WritingMode::kHorizontalTb,
- TextDirection::kLtr);
- EXPECT_EQ(width, p.size.inline_size);
+ ComputeOutOfFlowInlineDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, estimated_inline,
+ base::nullopt, WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(width, dimensions.size.inline_size);
}
TEST_F(NGAbsoluteUtilsTest, Vertical) {
@@ -365,7 +368,7 @@ TEST_F(NGAbsoluteUtilsTest, Vertical) {
style_->SetBorderRightWidth(0);
base::Optional<LayoutUnit> auto_height;
- MinMaxSize minmax_60{LayoutUnit(60), LayoutUnit(60)};
+ MinMaxSizes min_max_60{LayoutUnit(60), LayoutUnit(60)};
NGBoxStrut ltr_border_padding =
ComputeBordersForTest(*style_) + ComputePadding(ltr_space_, *style_);
@@ -387,133 +390,145 @@ TEST_F(NGAbsoluteUtilsTest, Vertical) {
// Tests
//
- NGLogicalOutOfFlowPosition p;
+ NGLogicalOutOfFlowDimensions dimensions;
// All auto, compute margins.
SetVerticalStyle(NGAuto, NGAuto, NGAuto, NGAuto, NGAuto);
EXPECT_EQ(AbsoluteNeedsChildBlockSize(*style_), true);
auto_height = LayoutUnit(60);
- ComputeFullAbsoluteWithChildBlockSize(
- ltr_space_, *style_, ltr_border_padding, static_position, auto_height,
- base::nullopt, WritingMode::kHorizontalTb, TextDirection::kLtr, &p);
- EXPECT_EQ(*auto_height, p.size.block_size);
- EXPECT_EQ(LayoutUnit(0), p.inset.block_start);
+ ComputeOutOfFlowBlockDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, auto_height, base::nullopt,
+ WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(*auto_height, dimensions.size.block_size);
+ EXPECT_EQ(LayoutUnit(0), dimensions.inset.block_start);
// All auto, static position bottom
- ComputeFullAbsoluteWithChildBlockSize(
- ltr_space_, *style_, ltr_border_padding, static_position_block_end,
- auto_height, base::nullopt, WritingMode::kHorizontalTb,
- TextDirection::kLtr, &p);
- EXPECT_EQ(container_size_.block_size, p.inset.block_end);
+ ComputeOutOfFlowBlockDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position_block_end, auto_height,
+ base::nullopt, WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(container_size_.block_size, dimensions.inset.block_end);
// If top, bottom, and height are known, compute margins.
SetVerticalStyle(top, NGAuto, height, NGAuto, bottom);
EXPECT_EQ(AbsoluteNeedsChildBlockSize(*style_), false);
auto_height.reset();
- ComputeFullAbsoluteWithChildBlockSize(
- ltr_space_, *style_, ltr_border_padding, static_position, auto_height,
- base::nullopt, WritingMode::kHorizontalTb, TextDirection::kLtr, &p);
+ ComputeOutOfFlowBlockDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, auto_height, base::nullopt,
+ WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
LayoutUnit margin_space =
(container_size_.block_size - top - height - bottom) / 2;
- EXPECT_EQ(top + margin_space, p.inset.block_start);
- EXPECT_EQ(bottom + margin_space, p.inset.block_end);
+ EXPECT_EQ(top + margin_space, dimensions.inset.block_start);
+ EXPECT_EQ(bottom + margin_space, dimensions.inset.block_end);
// If top, bottom, and height are known, writing mode vertical_lr.
SetVerticalStyle(top, NGAuto, height, NGAuto, bottom,
WritingMode::kVerticalLr);
EXPECT_EQ(AbsoluteNeedsChildInlineSize(*style_), false);
- p = ComputePartialAbsoluteWithChildInlineSize(
- vlr_space_, *style_, vlr_border_padding, static_position, minmax_60,
- base::nullopt, WritingMode::kHorizontalTb, TextDirection::kLtr);
- EXPECT_EQ(top + margin_space, p.inset.inline_start);
- EXPECT_EQ(bottom + margin_space, p.inset.inline_end);
+ ComputeOutOfFlowInlineDimensions(vlr_space_, *style_, vlr_border_padding,
+ static_position, min_max_60, base::nullopt,
+ WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(top + margin_space, dimensions.inset.inline_start);
+ EXPECT_EQ(bottom + margin_space, dimensions.inset.inline_end);
// If top, bottom, and height are known, writing mode vertical_rl.
SetVerticalStyle(top, NGAuto, height, NGAuto, bottom,
WritingMode::kVerticalRl);
EXPECT_EQ(AbsoluteNeedsChildInlineSize(*style_), false);
- p = ComputePartialAbsoluteWithChildInlineSize(
- vrl_space_, *style_, vrl_border_padding, static_position, minmax_60,
- base::nullopt, WritingMode::kHorizontalTb, TextDirection::kLtr);
- EXPECT_EQ(top + margin_space, p.inset.inline_start);
- EXPECT_EQ(bottom + margin_space, p.inset.inline_end);
+ ComputeOutOfFlowInlineDimensions(vrl_space_, *style_, vrl_border_padding,
+ static_position, min_max_60, base::nullopt,
+ WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(top + margin_space, dimensions.inset.inline_start);
+ EXPECT_EQ(bottom + margin_space, dimensions.inset.inline_end);
// If top, bottom, and height are known, negative auto margins.
LayoutUnit negative_margin_space =
(container_size_.block_size - top - LayoutUnit(300) - bottom) / 2;
SetVerticalStyle(top, NGAuto, LayoutUnit(300), NGAuto, bottom);
EXPECT_EQ(AbsoluteNeedsChildBlockSize(*style_), false);
- ComputeFullAbsoluteWithChildBlockSize(
- ltr_space_, *style_, ltr_border_padding, static_position, auto_height,
- base::nullopt, WritingMode::kHorizontalTb, TextDirection::kLtr, &p);
- EXPECT_EQ(top + negative_margin_space, p.inset.block_start);
- EXPECT_EQ(bottom + negative_margin_space, p.inset.block_end);
+ ComputeOutOfFlowBlockDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, auto_height, base::nullopt,
+ WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(top + negative_margin_space, dimensions.inset.block_start);
+ EXPECT_EQ(bottom + negative_margin_space, dimensions.inset.block_end);
// Rule 1: top and height are unknown.
SetVerticalStyle(NGAuto, margin_top, NGAuto, margin_bottom, bottom);
EXPECT_EQ(AbsoluteNeedsChildBlockSize(*style_), true);
auto_height = LayoutUnit(60);
- ComputeFullAbsoluteWithChildBlockSize(
- ltr_space_, *style_, ltr_border_padding, static_position, auto_height,
- base::nullopt, WritingMode::kHorizontalTb, TextDirection::kLtr, &p);
- EXPECT_EQ(*auto_height, p.size.block_size);
+ ComputeOutOfFlowBlockDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, auto_height, base::nullopt,
+ WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(*auto_height, dimensions.size.block_size);
// Rule 2: top and bottom are unknown.
SetVerticalStyle(NGAuto, margin_top, height, margin_bottom, NGAuto);
EXPECT_EQ(AbsoluteNeedsChildBlockSize(*style_), false);
auto_height.reset();
- ComputeFullAbsoluteWithChildBlockSize(
- ltr_space_, *style_, ltr_border_padding, static_position, auto_height,
- base::nullopt, WritingMode::kHorizontalTb, TextDirection::kLtr, &p);
- EXPECT_EQ(margin_top, p.inset.block_start);
+ ComputeOutOfFlowBlockDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, auto_height, base::nullopt,
+ WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(margin_top, dimensions.inset.block_start);
EXPECT_EQ(container_size_.block_size - margin_top - height,
- p.inset.block_end);
+ dimensions.inset.block_end);
// Rule 3: height and bottom are unknown, auto_height <
// horizontal_border_padding.
SetVerticalStyle(top, margin_top, NGAuto, margin_bottom, NGAuto);
EXPECT_EQ(AbsoluteNeedsChildBlockSize(*style_), true);
auto_height = LayoutUnit(20);
- ComputeFullAbsoluteWithChildBlockSize(
- ltr_space_, *style_, ltr_border_padding, static_position, auto_height,
- base::nullopt, WritingMode::kHorizontalTb, TextDirection::kLtr, &p);
- EXPECT_EQ(horizontal_border_padding, p.size.block_size);
+ ComputeOutOfFlowBlockDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, auto_height, base::nullopt,
+ WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(horizontal_border_padding, dimensions.size.block_size);
// Rule 3: height and bottom are unknown.
SetVerticalStyle(top, margin_top, NGAuto, margin_bottom, NGAuto);
EXPECT_EQ(AbsoluteNeedsChildBlockSize(*style_), true);
auto_height = LayoutUnit(70);
- ComputeFullAbsoluteWithChildBlockSize(
- ltr_space_, *style_, ltr_border_padding, static_position, auto_height,
- base::nullopt, WritingMode::kHorizontalTb, TextDirection::kLtr, &p);
- EXPECT_EQ(*auto_height, p.size.block_size);
+ ComputeOutOfFlowBlockDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, auto_height, base::nullopt,
+ WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(*auto_height, dimensions.size.block_size);
// Rule 4: top is unknown.
SetVerticalStyle(NGAuto, margin_top, height, margin_bottom, bottom);
EXPECT_EQ(AbsoluteNeedsChildBlockSize(*style_), false);
auto_height.reset();
- ComputeFullAbsoluteWithChildBlockSize(
- ltr_space_, *style_, ltr_border_padding, static_position, auto_height,
- base::nullopt, WritingMode::kHorizontalTb, TextDirection::kLtr, &p);
- EXPECT_EQ(top + margin_top, p.inset.block_start);
+ ComputeOutOfFlowBlockDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, auto_height, base::nullopt,
+ WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(top + margin_top, dimensions.inset.block_start);
// Rule 5: bottom is unknown.
SetVerticalStyle(top, margin_top, height, margin_bottom, NGAuto);
EXPECT_EQ(AbsoluteNeedsChildBlockSize(*style_), false);
auto_height.reset();
- ComputeFullAbsoluteWithChildBlockSize(
- ltr_space_, *style_, ltr_border_padding, static_position, auto_height,
- base::nullopt, WritingMode::kHorizontalTb, TextDirection::kLtr, &p);
- EXPECT_EQ(bottom + margin_bottom, p.inset.block_end);
+ ComputeOutOfFlowBlockDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, auto_height, base::nullopt,
+ WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(bottom + margin_bottom, dimensions.inset.block_end);
// Rule 6: height is unknown.
SetVerticalStyle(top, margin_top, NGAuto, margin_bottom, bottom);
EXPECT_EQ(AbsoluteNeedsChildBlockSize(*style_), false);
auto_height.reset();
- ComputeFullAbsoluteWithChildBlockSize(
- ltr_space_, *style_, ltr_border_padding, static_position, auto_height,
- base::nullopt, WritingMode::kHorizontalTb, TextDirection::kLtr, &p);
- EXPECT_EQ(height, p.size.block_size);
+ ComputeOutOfFlowBlockDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, auto_height, base::nullopt,
+ WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(height, dimensions.size.block_size);
}
TEST_F(NGAbsoluteUtilsTest, CenterStaticPosition) {
@@ -529,28 +544,31 @@ TEST_F(NGAbsoluteUtilsTest, CenterStaticPosition) {
EXPECT_EQ(AbsoluteNeedsChildBlockSize(*style_), true);
NGBoxStrut border_padding;
- NGLogicalOutOfFlowPosition p = ComputePartialAbsoluteWithChildInlineSize(
+ NGLogicalOutOfFlowDimensions dimensions;
+
+ ComputeOutOfFlowInlineDimensions(
ltr_space_, *style_, border_padding, static_position,
- MinMaxSize{LayoutUnit(), LayoutUnit(1000)}, base::nullopt,
- WritingMode::kHorizontalTb, TextDirection::kLtr);
- EXPECT_EQ(LayoutUnit(100), p.size.inline_size);
- EXPECT_EQ(LayoutUnit(100), p.inset.inline_start);
- EXPECT_EQ(LayoutUnit(), p.inset.inline_end);
+ MinMaxSizes{LayoutUnit(), LayoutUnit(1000)}, base::nullopt,
+ WritingMode::kHorizontalTb, TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(LayoutUnit(100), dimensions.size.inline_size);
+ EXPECT_EQ(LayoutUnit(100), dimensions.inset.inline_start);
+ EXPECT_EQ(LayoutUnit(), dimensions.inset.inline_end);
- p = ComputePartialAbsoluteWithChildInlineSize(
+ ComputeOutOfFlowInlineDimensions(
ltr_space_, *style_, border_padding, static_position,
- MinMaxSize{LayoutUnit(), LayoutUnit(1000)}, base::nullopt,
- WritingMode::kHorizontalTb, TextDirection::kRtl);
- EXPECT_EQ(LayoutUnit(100), p.size.inline_size);
- EXPECT_EQ(LayoutUnit(100), p.inset.inline_start);
- EXPECT_EQ(LayoutUnit(), p.inset.inline_end);
-
- ComputeFullAbsoluteWithChildBlockSize(
- ltr_space_, *style_, border_padding, static_position, LayoutUnit(150),
- base::nullopt, WritingMode::kHorizontalTb, TextDirection::kLtr, &p);
- EXPECT_EQ(LayoutUnit(150), p.size.block_size);
- EXPECT_EQ(LayoutUnit(125), p.inset.block_start);
- EXPECT_EQ(LayoutUnit(25), p.inset.block_end);
+ MinMaxSizes{LayoutUnit(), LayoutUnit(1000)}, base::nullopt,
+ WritingMode::kHorizontalTb, TextDirection::kRtl, &dimensions);
+ EXPECT_EQ(LayoutUnit(100), dimensions.size.inline_size);
+ EXPECT_EQ(LayoutUnit(100), dimensions.inset.inline_start);
+ EXPECT_EQ(LayoutUnit(), dimensions.inset.inline_end);
+
+ ComputeOutOfFlowBlockDimensions(ltr_space_, *style_, border_padding,
+ static_position, LayoutUnit(150),
+ base::nullopt, WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(LayoutUnit(150), dimensions.size.block_size);
+ EXPECT_EQ(LayoutUnit(125), dimensions.inset.block_start);
+ EXPECT_EQ(LayoutUnit(25), dimensions.inset.block_end);
}
TEST_F(NGAbsoluteUtilsTest, MinMax) {
@@ -569,34 +587,34 @@ TEST_F(NGAbsoluteUtilsTest, MinMax) {
{LayoutUnit(), LayoutUnit()},
NGLogicalStaticPosition::kInlineStart,
NGLogicalStaticPosition::kBlockStart};
- MinMaxSize estimated_inline{LayoutUnit(20), LayoutUnit(20)};
- NGLogicalOutOfFlowPosition p;
+ MinMaxSizes estimated_inline{LayoutUnit(20), LayoutUnit(20)};
+ NGLogicalOutOfFlowDimensions dimensions;
// WIDTH TESTS
// width < min gets set to min.
SetHorizontalStyle(NGAuto, NGAuto, LayoutUnit(5), NGAuto, NGAuto);
- p = ComputePartialAbsoluteWithChildInlineSize(
- ltr_space_, *style_, ltr_border_padding, static_position,
- estimated_inline, base::nullopt, WritingMode::kHorizontalTb,
- TextDirection::kLtr);
- EXPECT_EQ(min, p.size.inline_size);
+ ComputeOutOfFlowInlineDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, estimated_inline,
+ base::nullopt, WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(min, dimensions.size.inline_size);
// width > max gets set to max.
SetHorizontalStyle(NGAuto, NGAuto, LayoutUnit(200), NGAuto, NGAuto);
- p = ComputePartialAbsoluteWithChildInlineSize(
- ltr_space_, *style_, ltr_border_padding, static_position,
- estimated_inline, base::nullopt, WritingMode::kHorizontalTb,
- TextDirection::kLtr);
- EXPECT_EQ(max, p.size.inline_size);
+ ComputeOutOfFlowInlineDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, estimated_inline,
+ base::nullopt, WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(max, dimensions.size.inline_size);
- // Unspecified width becomes minmax, gets clamped to min.
+ // Unspecified width becomes min_max, gets clamped to min.
SetHorizontalStyle(NGAuto, NGAuto, NGAuto, NGAuto, NGAuto);
- p = ComputePartialAbsoluteWithChildInlineSize(
- ltr_space_, *style_, ltr_border_padding, static_position,
- estimated_inline, base::nullopt, WritingMode::kHorizontalTb,
- TextDirection::kLtr);
- EXPECT_EQ(min, p.size.inline_size);
+ ComputeOutOfFlowInlineDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, estimated_inline,
+ base::nullopt, WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(min, dimensions.size.inline_size);
// HEIGHT TESTS
@@ -604,25 +622,28 @@ TEST_F(NGAbsoluteUtilsTest, MinMax) {
// height < min gets set to min.
SetVerticalStyle(NGAuto, NGAuto, LayoutUnit(5), NGAuto, NGAuto);
- ComputeFullAbsoluteWithChildBlockSize(
- ltr_space_, *style_, ltr_border_padding, static_position, auto_height,
- base::nullopt, WritingMode::kHorizontalTb, TextDirection::kLtr, &p);
- EXPECT_EQ(min, p.size.block_size);
+ ComputeOutOfFlowBlockDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, auto_height, base::nullopt,
+ WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(min, dimensions.size.block_size);
// height > max gets set to max.
SetVerticalStyle(NGAuto, NGAuto, LayoutUnit(200), NGAuto, NGAuto);
- ComputeFullAbsoluteWithChildBlockSize(
- ltr_space_, *style_, ltr_border_padding, static_position, auto_height,
- base::nullopt, WritingMode::kHorizontalTb, TextDirection::kLtr, &p);
- EXPECT_EQ(max, p.size.block_size);
+ ComputeOutOfFlowBlockDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, auto_height, base::nullopt,
+ WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(max, dimensions.size.block_size);
// // Unspecified height becomes estimated, gets clamped to min.
SetVerticalStyle(NGAuto, NGAuto, NGAuto, NGAuto, NGAuto);
auto_height = LayoutUnit(20);
- ComputeFullAbsoluteWithChildBlockSize(
- ltr_space_, *style_, ltr_border_padding, static_position, auto_height,
- base::nullopt, WritingMode::kHorizontalTb, TextDirection::kLtr, &p);
- EXPECT_EQ(min, p.size.block_size);
+ ComputeOutOfFlowBlockDimensions(ltr_space_, *style_, ltr_border_padding,
+ static_position, auto_height, base::nullopt,
+ WritingMode::kHorizontalTb,
+ TextDirection::kLtr, &dimensions);
+ EXPECT_EQ(min, dimensions.size.block_size);
}
} // namespace
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.cc
index 7f919d2599f..1ddab49c2b9 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.cc
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h"
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.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/layout/ng/ng_physical_box_fragment.h"
@@ -49,8 +50,8 @@ std::pair<scoped_refptr<const NGPhysicalBoxFragment>, NGConstraintSpace>
NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithmForElement(Element* element) {
auto* block_flow = To<LayoutBlockFlow>(element->GetLayoutObject());
NGBlockNode node(block_flow);
- NGConstraintSpace space = NGConstraintSpace::CreateFromLayoutObject(
- *block_flow, false /* is_layout_root */);
+ NGConstraintSpace space =
+ NGConstraintSpace::CreateFromLayoutObject(*block_flow);
NGFragmentGeometry fragment_geometry =
CalculateInitialFragmentGeometry(space, node);
@@ -61,6 +62,22 @@ NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithmForElement(Element* element) {
}
scoped_refptr<const NGPhysicalBoxFragment>
+NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ NGBlockNode node,
+ const NGConstraintSpace& space,
+ const NGBreakToken* break_token) {
+ NGFragmentGeometry fragment_geometry =
+ CalculateInitialFragmentGeometry(space, node);
+
+ scoped_refptr<const NGLayoutResult> result =
+ NGFieldsetLayoutAlgorithm(
+ {node, fragment_geometry, space, To<NGBlockBreakToken>(break_token)})
+ .Layout();
+
+ return To<NGPhysicalBoxFragment>(&result->PhysicalFragment());
+}
+
+scoped_refptr<const NGPhysicalBoxFragment>
NGBaseLayoutAlgorithmTest::GetBoxFragmentByElementId(const char* id) {
LayoutObject* layout_object = GetLayoutObjectByElementId(id);
CHECK(layout_object && layout_object->IsLayoutNGMixin());
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.h
index 702637ee1bb..9f9fe176151 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.h
@@ -41,6 +41,11 @@ class NGBaseLayoutAlgorithmTest
std::pair<scoped_refptr<const NGPhysicalBoxFragment>, NGConstraintSpace>
RunBlockLayoutAlgorithmForElement(Element* element);
+ scoped_refptr<const NGPhysicalBoxFragment> RunFieldsetLayoutAlgorithm(
+ NGBlockNode node,
+ const NGConstraintSpace& space,
+ const NGBreakToken* break_token = nullptr);
+
scoped_refptr<const NGPhysicalBoxFragment> GetBoxFragmentByElementId(
const char*);
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 6e9781b9bdf..eea8efbb3da 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
@@ -12,7 +12,7 @@ namespace blink {
namespace {
struct SameSizeAsNGBlockBreakToken : NGBreakToken {
- unsigned numbers[2];
+ unsigned numbers[3];
};
static_assert(sizeof(NGBlockBreakToken) == sizeof(SameSizeAsNGBlockBreakToken),
@@ -21,13 +21,16 @@ static_assert(sizeof(NGBlockBreakToken) == sizeof(SameSizeAsNGBlockBreakToken),
} // namespace
NGBlockBreakToken::NGBlockBreakToken(
+ PassKey key,
NGLayoutInputNode node,
LayoutUnit consumed_block_size,
+ unsigned sequence_number,
const NGBreakTokenVector& child_break_tokens,
NGBreakAppeal break_appeal,
bool has_seen_all_children)
: 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;
@@ -37,7 +40,7 @@ NGBlockBreakToken::NGBlockBreakToken(
}
}
-NGBlockBreakToken::NGBlockBreakToken(NGLayoutInputNode node)
+NGBlockBreakToken::NGBlockBreakToken(PassKey key, NGLayoutInputNode node)
: NGBreakToken(kBlockBreakToken, kUnfinished, node), num_children_(0) {}
const NGInlineBreakToken* NGBlockBreakToken::InlineBreakTokenFor(
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 fc5ab4ba485..ee2bcc92fba 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
@@ -27,6 +27,7 @@ class CORE_EXPORT NGBlockBreakToken final : public NGBreakToken {
static scoped_refptr<NGBlockBreakToken> Create(
NGLayoutInputNode node,
LayoutUnit consumed_block_size,
+ unsigned sequence_number,
const NGBreakTokenVector& child_break_tokens,
NGBreakAppeal break_appeal,
bool has_seen_all_children) {
@@ -37,7 +38,8 @@ class CORE_EXPORT NGBlockBreakToken final : public NGBreakToken {
sizeof(NGBlockBreakToken) +
child_break_tokens.size() * sizeof(NGBreakToken*),
::WTF::GetStringWithTypeName<NGBlockBreakToken>());
- new (data) NGBlockBreakToken(node, consumed_block_size, child_break_tokens,
+ new (data) NGBlockBreakToken(PassKey(), node, consumed_block_size,
+ sequence_number, child_break_tokens,
break_appeal, has_seen_all_children);
return base::AdoptRef(static_cast<NGBlockBreakToken*>(data));
}
@@ -48,7 +50,7 @@ class CORE_EXPORT NGBlockBreakToken final : public NGBreakToken {
static scoped_refptr<NGBlockBreakToken> CreateBreakBefore(
NGLayoutInputNode node,
bool is_forced_break) {
- auto* token = new NGBlockBreakToken(node);
+ auto* token = new NGBlockBreakToken(PassKey(), node);
token->is_break_before_ = true;
token->is_forced_break_ = is_forced_break;
return base::AdoptRef(token);
@@ -68,6 +70,17 @@ class CORE_EXPORT NGBlockBreakToken final : public NGBreakToken {
// the fragmentainer is shorter than 50px, for instance).
LayoutUnit ConsumedBlockSize() const { return consumed_block_size_; }
+ // A unique identifier for a fragment that generates a break token. This is
+ // unique within the generating layout input node. The break token of the
+ // first fragment gets 0, then second 1, and so on. Note that we don't "count"
+ // break tokens that aren't associated with a fragment (this happens when we
+ // want a fragmentainer break before laying out the node). What the sequence
+ // number is for such a break token is undefined.
+ unsigned SequenceNumber() const {
+ DCHECK(!IsBreakBefore());
+ return sequence_number_;
+ }
+
// Return true if this is a break token that was produced without any
// "preceding" fragment. This happens when we determine that the first
// fragment for a node needs to be created in a later fragmentainer than the
@@ -102,18 +115,23 @@ class CORE_EXPORT NGBlockBreakToken final : public NGBreakToken {
String ToString() const override;
#endif
- private:
+ using PassKey = util::PassKey<NGBlockBreakToken>;
+
// Must only be called from Create(), because it assumes that enough space
// has been allocated in the flexible array to store the children.
- NGBlockBreakToken(NGLayoutInputNode node,
+ NGBlockBreakToken(PassKey,
+ NGLayoutInputNode node,
LayoutUnit consumed_block_size,
+ unsigned sequence_number,
const NGBreakTokenVector& child_break_tokens,
NGBreakAppeal break_appeal,
bool has_seen_all_children);
- explicit NGBlockBreakToken(NGLayoutInputNode node);
+ explicit NGBlockBreakToken(PassKey, NGLayoutInputNode node);
+ private:
LayoutUnit consumed_block_size_;
+ unsigned sequence_number_ = 0;
wtf_size_t num_children_;
// This must be the last member, because it is a flexible array.
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 917eb7864f5..01b46282762 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
@@ -58,19 +58,19 @@ TEST_F(NGBlockChildIteratorTest, BreakTokens) {
NGBreakTokenVector empty_tokens_list;
scoped_refptr<NGBreakToken> child_token1 = NGBlockBreakToken::Create(
- node1, LayoutUnit(), empty_tokens_list, kBreakAppealPerfect,
+ node1, LayoutUnit(), 0, empty_tokens_list, kBreakAppealPerfect,
/* has_seen_all_children */ false);
scoped_refptr<NGBreakToken> child_token2 = NGBlockBreakToken::Create(
- node2, LayoutUnit(), empty_tokens_list, kBreakAppealPerfect,
+ node2, LayoutUnit(), 0, empty_tokens_list, kBreakAppealPerfect,
/* has_seen_all_children */ false);
scoped_refptr<NGBreakToken> child_token3 = NGBlockBreakToken::Create(
- node3, LayoutUnit(), empty_tokens_list, kBreakAppealPerfect,
+ node3, LayoutUnit(), 0, empty_tokens_list, kBreakAppealPerfect,
/* has_seen_all_children */ false);
NGBreakTokenVector child_break_tokens;
child_break_tokens.push_back(child_token1);
scoped_refptr<NGBlockBreakToken> parent_token = NGBlockBreakToken::Create(
- container, LayoutUnit(), child_break_tokens, kBreakAppealPerfect,
+ container, LayoutUnit(), 0, child_break_tokens, kBreakAppealPerfect,
/* has_seen_all_children */ false);
NGBlockChildIterator iterator(node1, parent_token.get());
@@ -86,7 +86,7 @@ TEST_F(NGBlockChildIteratorTest, BreakTokens) {
child_break_tokens.push_back(child_token1);
child_break_tokens.push_back(child_token2);
parent_token = NGBlockBreakToken::Create(
- container, LayoutUnit(), child_break_tokens, kBreakAppealPerfect,
+ container, LayoutUnit(), 0, child_break_tokens, kBreakAppealPerfect,
/* has_seen_all_children */ false);
iterator = NGBlockChildIterator(node1, parent_token.get());
@@ -103,7 +103,7 @@ TEST_F(NGBlockChildIteratorTest, BreakTokens) {
child_break_tokens.push_back(child_token2);
child_break_tokens.push_back(child_token3);
parent_token = NGBlockBreakToken::Create(
- container, LayoutUnit(), child_break_tokens, kBreakAppealPerfect,
+ container, LayoutUnit(), 0, child_break_tokens, kBreakAppealPerfect,
/* has_seen_all_children */ false);
iterator = NGBlockChildIterator(node1, parent_token.get());
@@ -119,7 +119,7 @@ TEST_F(NGBlockChildIteratorTest, BreakTokens) {
child_break_tokens.push_back(child_token1);
child_break_tokens.push_back(child_token3);
parent_token = NGBlockBreakToken::Create(
- container, LayoutUnit(), child_break_tokens, kBreakAppealPerfect,
+ container, LayoutUnit(), 0, child_break_tokens, kBreakAppealPerfect,
/* has_seen_all_children */ false);
iterator = NGBlockChildIterator(node1, parent_token.get());
@@ -145,13 +145,13 @@ TEST_F(NGBlockChildIteratorTest, SeenAllChildren) {
NGBreakTokenVector empty_tokens_list;
scoped_refptr<NGBreakToken> child_token1 = NGBlockBreakToken::Create(
- node1, LayoutUnit(), empty_tokens_list, kBreakAppealPerfect,
+ node1, LayoutUnit(), 0, empty_tokens_list, kBreakAppealPerfect,
/* has_seen_all_children */ false);
NGBreakTokenVector child_break_tokens;
child_break_tokens.push_back(child_token1);
scoped_refptr<NGBlockBreakToken> parent_token = NGBlockBreakToken::Create(
- container, LayoutUnit(), child_break_tokens, kBreakAppealPerfect,
+ container, LayoutUnit(), 0, child_break_tokens, kBreakAppealPerfect,
/* has_seen_all_children */ true);
// We have a break token for #child1, but have seen all children. This happens
@@ -166,7 +166,7 @@ TEST_F(NGBlockChildIteratorTest, SeenAllChildren) {
child_break_tokens.clear();
parent_token = NGBlockBreakToken::Create(
- container, LayoutUnit(), child_break_tokens, kBreakAppealPerfect,
+ container, LayoutUnit(), 0, child_break_tokens, kBreakAppealPerfect,
/* has_seen_all_children */ true);
// We have no break tokens, but have seen all children. This happens e.g. when
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 ec88e7d665b..9d0e5660942 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
@@ -16,6 +16,7 @@
#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"
+#include "third_party/blink/renderer/core/layout/ng/ng_box_fragment.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_constraint_space_builder.h"
@@ -30,7 +31,6 @@
#include "third_party/blink/renderer/core/layout/ng/ng_positioned_float.h"
#include "third_party/blink/renderer/core/layout/ng/ng_space_utils.h"
#include "third_party/blink/renderer/core/layout/ng/ng_unpositioned_float.h"
-#include "third_party/blink/renderer/core/layout/text_autosizer.h"
#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
@@ -53,7 +53,8 @@ inline scoped_refptr<const NGLayoutResult> LayoutBlockChild(
// child.
DCHECK(early_break_in_child);
}
- return node->Layout(space, break_token, early_break_in_child);
+ return node->Layout(space, To<NGBlockBreakToken>(break_token),
+ early_break_in_child);
}
inline scoped_refptr<const NGLayoutResult> LayoutInflow(
@@ -180,6 +181,8 @@ NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm(
params.fragment_geometry.scrollbar),
is_resuming_(IsResumingLayout(params.break_token)),
exclusion_space_(params.space.ExclusionSpace()),
+ lines_until_clamp_(params.space.LinesUntilClamp()),
+ force_truncate_at_line_clamp_(params.space.ForceTruncateAtLineClamp()),
early_break_(params.early_break) {
AdjustForFragmentation(BreakToken(), &border_scrollbar_padding_);
container_builder_.SetIsNewFormattingContext(
@@ -195,10 +198,10 @@ void NGBlockLayoutAlgorithm::SetBoxType(NGPhysicalFragment::NGBoxType type) {
container_builder_.SetBoxType(type);
}
-base::Optional<MinMaxSize> NGBlockLayoutAlgorithm::ComputeMinMaxSize(
- const MinMaxSizeInput& input) const {
- base::Optional<MinMaxSize> sizes = CalculateMinMaxSizesIgnoringChildren(
- node_, border_scrollbar_padding_, input.size_type);
+base::Optional<MinMaxSizes> NGBlockLayoutAlgorithm::ComputeMinMaxSizes(
+ const MinMaxSizesInput& input) const {
+ base::Optional<MinMaxSizes> sizes =
+ CalculateMinMaxSizesIgnoringChildren(node_, border_scrollbar_padding_);
if (sizes)
return sizes;
@@ -242,13 +245,13 @@ base::Optional<MinMaxSize> NGBlockLayoutAlgorithm::ComputeMinMaxSize(
float_right_inline_size = LayoutUnit();
}
- MinMaxSizeInput child_input(child_percentage_resolution_block_size);
+ MinMaxSizesInput child_input(child_percentage_resolution_block_size);
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;
}
- MinMaxSize child_sizes;
+ MinMaxSizes child_sizes;
if (child.IsInline()) {
// From |NGBlockLayoutAlgorithm| perspective, we can handle |NGInlineNode|
// almost the same as |NGBlockNode|, because an |NGInlineNode| includes
@@ -257,7 +260,7 @@ base::Optional<MinMaxSize> NGBlockLayoutAlgorithm::ComputeMinMaxSize(
// |NextSibling| returns the next block sibling, or nullptr, skipping all
// following inline siblings and descendants.
child_sizes =
- child.ComputeMinMaxSize(Style().GetWritingMode(), child_input);
+ child.ComputeMinMaxSizes(Style().GetWritingMode(), child_input);
} else {
child_sizes =
ComputeMinAndMaxContentContribution(Style(), child, child_input);
@@ -331,8 +334,7 @@ base::Optional<MinMaxSize> NGBlockLayoutAlgorithm::ComputeMinMaxSize(
DCHECK_GE(sizes->min_size, LayoutUnit());
DCHECK_LE(sizes->min_size, sizes->max_size) << Node().ToString();
- if (input.size_type == NGMinMaxSizeType::kBorderBoxSize)
- *sizes += border_scrollbar_padding_.InlineSum();
+ *sizes += border_scrollbar_padding_.InlineSum();
return sizes;
}
@@ -364,7 +366,7 @@ scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
// Inline children require an inline child layout context to be
// passed between siblings. We want to stack-allocate that one, but
// only on demand, as it's quite big.
- if (Node().ChildrenInline())
+ if (Node().IsInlineFormattingContextRoot())
result = LayoutWithInlineChildLayoutContext();
else
result = Layout(nullptr);
@@ -374,6 +376,11 @@ scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
DCHECK(!early_break_);
DCHECK(result->GetEarlyBreak());
return RelayoutAndBreakEarlier(*result->GetEarlyBreak());
+ } else if (UNLIKELY(result->Status() ==
+ NGLayoutResult::
+ kNeedsRelayoutWithNoForcedTruncateAtLineClamp)) {
+ DCHECK(force_truncate_at_line_clamp_);
+ return RelayoutNoForcedTruncateForLineClamp();
}
return result;
}
@@ -417,6 +424,19 @@ NGBlockLayoutAlgorithm::RelayoutAndBreakEarlier(
return algorithm_with_break.Layout();
}
+NOINLINE scoped_refptr<const NGLayoutResult>
+NGBlockLayoutAlgorithm::RelayoutNoForcedTruncateForLineClamp() {
+ NGLayoutAlgorithmParams params(Node(),
+ container_builder_.InitialFragmentGeometry(),
+ ConstraintSpace(), BreakToken(), nullptr);
+ NGBlockLayoutAlgorithm algorithm_with_forced_truncate(params);
+ algorithm_with_forced_truncate.force_truncate_at_line_clamp_ = false;
+ NGBoxFragmentBuilder& new_builder =
+ algorithm_with_forced_truncate.container_builder_;
+ new_builder.SetBoxType(container_builder_.BoxType());
+ return algorithm_with_forced_truncate.Layout();
+}
+
inline scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout(
NGInlineChildLayoutContext* inline_child_layout_context) {
const LogicalSize border_box_size = container_builder_.InitialBorderBoxSize();
@@ -436,6 +456,10 @@ inline scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout(
ConstraintSpace(), Style(), container_builder_.Scrollbar());
}
+ DCHECK_EQ(!!inline_child_layout_context,
+ Node().IsInlineFormattingContextRoot());
+ container_builder_.SetIsInlineFormattingContext(inline_child_layout_context);
+
if (ConstraintSpace().HasBlockFragmentation()) {
container_builder_.SetHasBlockFragmentation();
// The whereabouts of our container's so far best breakpoint is none of our
@@ -463,6 +487,10 @@ inline scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout(
container_builder_.SetAdjoiningObjectTypes(adjoining_object_types);
}
+ if (Style().IsDeprecatedWebkitBoxWithVerticalLineClamp() &&
+ RuntimeEnabledFeatures::BlockFlowHandlesWebkitLineClampEnabled())
+ lines_until_clamp_ = Style().LineClamp();
+
LayoutUnit content_edge = border_scrollbar_padding_.block_start;
NGPreviousInflowPosition previous_inflow_position = {
@@ -480,8 +508,7 @@ inline scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout(
//
// In all those cases we can and must resolve the BFC block offset now.
if (border_scrollbar_padding_.block_start || is_resuming_ ||
- ConstraintSpace().IsNewFormattingContext() ||
- Style().MarginBeforeCollapse() != EMarginCollapse::kCollapse) {
+ ConstraintSpace().IsNewFormattingContext()) {
bool discard_subsequent_margins =
previous_inflow_position.margin_strut.discard_margins &&
!border_scrollbar_padding_.block_start;
@@ -537,12 +564,6 @@ inline scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout(
if (node_.IsQuirkyContainer())
previous_inflow_position.margin_strut.is_quirky_container_start = true;
- // Before we descend into children (but after we have determined our inline
- // size), give the autosizer an opportunity to adjust the font size on the
- // children.
- TextAutosizer::NGLayoutScope text_autosizer_layout_scope(
- Node(), border_box_size.inline_size);
-
// Try to reuse line box fragments from cached fragments if possible.
// When possible, this adds fragments to |container_builder_| and update
// |previous_inflow_position| and |BreakToken()|.
@@ -650,6 +671,18 @@ inline scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout(
}
}
+ if (UNLIKELY(ConstraintSpace().IsNewFormattingContext() &&
+ force_truncate_at_line_clamp_ &&
+ intrinsic_block_size_when_clamped_ && lines_until_clamp_ == 0)) {
+ // Truncation of the last line was forced, but there are no lines after the
+ // truncated line. Rerun layout without forcing truncation. This is only
+ // done if line-clamp was specified on the element as the element containing
+ // the node may have subsequent lines. If there aren't, the containing
+ // element will relayout.
+ return container_builder_.Abort(
+ NGLayoutResult::kNeedsRelayoutWithNoForcedTruncateAtLineClamp);
+ }
+
if (child_iterator.IsAtEnd()) {
// 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
@@ -685,15 +718,22 @@ scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::FinishLayout(
intrinsic_block_size_, exclusion_space_.ClearanceOffset(EClear::kBoth));
}
- // The end margin strut of an in-flow fragment contributes to the size of the
- // current fragment if:
- // - There is block-end border/scrollbar/padding.
- // - There was a self-collapsing child affected by clearance.
- // - We are a new formatting context.
- // Additionally this fragment produces no end margin strut.
- if (border_scrollbar_padding_.block_end ||
- previous_inflow_position->self_collapsing_child_had_clearance ||
- ConstraintSpace().IsNewFormattingContext()) {
+ // If line clamping occurred, the intrinsic block-size comes from the
+ // 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_;
+ end_margin_strut = NGMarginStrut();
+ } else if (border_scrollbar_padding_.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
+ // the current fragment if:
+ // - There is block-end border/scrollbar/padding.
+ // - 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
@@ -741,7 +781,7 @@ scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::FinishLayout(
}
// Save the unconstrained intrinsic size on the builder before clamping it.
- container_builder_.SetUnconstrainedIntrinsicBlockSize(intrinsic_block_size_);
+ container_builder_.SetOverflowBlockSize(intrinsic_block_size_);
intrinsic_block_size_ = ClampIntrinsicBlockSize(
ConstraintSpace(), Node(), border_scrollbar_padding_,
@@ -827,11 +867,14 @@ scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::FinishLayout(
container_builder_.CheckNoBlockFragmentation();
#endif
- PropagateBaselinesFromChildren();
+ // Adjust the position of the final baseline if needed.
+ FinalizeBaseline();
// An exclusion space is confined to nodes within the same formatting context.
- if (!ConstraintSpace().IsNewFormattingContext())
+ if (!ConstraintSpace().IsNewFormattingContext()) {
container_builder_.SetExclusionSpace(std::move(exclusion_space_));
+ container_builder_.SetLinesUntilClamp(lines_until_clamp_);
+ }
if (ConstraintSpace().UseFirstLineStyle())
container_builder_.SetStyleVariant(NGStyleVariant::kFirstLine);
@@ -1016,6 +1059,10 @@ void NGBlockLayoutAlgorithm::HandleFloat(
PositionFloat(&unpositioned_float, &exclusion_space_);
const NGLayoutResult& layout_result = *positioned_float.layout_result;
+
+ // 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()) {
DCHECK(ConstraintSpace().HasBlockFragmentation());
@@ -1230,13 +1277,6 @@ NGLayoutResult::EStatus NGBlockLayoutAlgorithm::HandleNewFormattingContext(
/* abort_if_cleared */ false, &child_bfc_offset);
}
- NGFragment fragment(ConstraintSpace().GetWritingMode(),
- layout_result->PhysicalFragment());
-
- LogicalOffset logical_offset = LogicalFromBfcOffsets(
- child_bfc_offset, ContainerBfcOffset(), fragment.InlineSize(),
- container_builder_.Size().inline_size, ConstraintSpace().Direction());
-
if (ConstraintSpace().HasBlockFragmentation()) {
bool has_container_separation =
has_processed_first_child_ || child_margin_got_separated ||
@@ -1244,20 +1284,32 @@ NGLayoutResult::EStatus NGBlockLayoutAlgorithm::HandleNewFormattingContext(
layout_result->IsPushedByFloats();
NGBreakStatus break_status = BreakBeforeChildIfNeeded(
child, *layout_result, previous_inflow_position,
- logical_offset.block_offset, has_container_separation);
+ child_bfc_offset.block_offset, has_container_separation);
if (break_status == NGBreakStatus::kBrokeBefore)
return NGLayoutResult::kSuccess;
if (break_status == NGBreakStatus::kNeedsEarlierBreak)
return NGLayoutResult::kNeedsEarlierBreak;
+
+ // If the child aborted layout, we cannot continue.
+ DCHECK_EQ(layout_result->Status(), NGLayoutResult::kSuccess);
+
EBreakBetween break_after = JoinFragmentainerBreakValues(
layout_result->FinalBreakAfter(), child.Style().BreakAfter());
container_builder_.SetPreviousBreakAfter(break_after);
}
+ const auto& physical_fragment = layout_result->PhysicalFragment();
+ NGFragment fragment(ConstraintSpace().GetWritingMode(), physical_fragment);
+
+ LogicalOffset logical_offset = LogicalFromBfcOffsets(
+ child_bfc_offset, ContainerBfcOffset(), fragment.InlineSize(),
+ container_builder_.Size().inline_size, ConstraintSpace().Direction());
+
if (!PositionOrPropagateListMarker(*layout_result, &logical_offset,
previous_inflow_position))
return NGLayoutResult::kBfcBlockOffsetResolved;
+ PropagateBaselineFromChild(physical_fragment, logical_offset.block_offset);
container_builder_.AddResult(*layout_result, logical_offset);
// The margins we store will be used by e.g. getComputedStyle().
@@ -1306,7 +1358,7 @@ NGBlockLayoutAlgorithm::LayoutNewFormattingContext(
// fit where it was laid out, and is pushed downwards, we'll lay out over
// again, since a new BFC block offset could result in a new fragment size,
// e.g. when inline size is auto, or if we're block-fragmented.
- for (const auto opportunity : opportunities) {
+ for (const auto& opportunity : opportunities) {
if (abort_if_cleared &&
origin_offset.block_offset < opportunity.rect.BlockStartOffset()) {
// Abort if we got pushed downwards. We need to adjust
@@ -1378,6 +1430,12 @@ NGBlockLayoutAlgorithm::LayoutNewFormattingContext(
// should be returned.
DCHECK(layout_result->ExclusionSpace().IsEmpty());
+ if (layout_result->Status() != NGLayoutResult::kSuccess) {
+ DCHECK_EQ(layout_result->Status(),
+ NGLayoutResult::kOutOfFragmentainerSpace);
+ return layout_result;
+ }
+
NGFragment fragment(writing_mode, layout_result->PhysicalFragment());
// Check if the fragment will fit in this layout opportunity, if not proceed
@@ -1730,7 +1788,8 @@ NGLayoutResult::EStatus NGBlockLayoutAlgorithm::FinishInflow(
LogicalOffset logical_offset = CalculateLogicalOffset(
fragment, layout_result->BfcLineOffset(), child_bfc_block_offset);
- if (ConstraintSpace().HasBlockFragmentation()) {
+ if (ConstraintSpace().HasBlockFragmentation() &&
+ container_builder_.BfcBlockOffset() && child_bfc_block_offset) {
// Floats only cause container separation for the outermost block child that
// gets pushed down (the container and the child may have adjoining
// block-start margins).
@@ -1739,7 +1798,7 @@ NGLayoutResult::EStatus NGBlockLayoutAlgorithm::FinishInflow(
!container_builder_.IsPushedByFloats());
NGBreakStatus break_status = BreakBeforeChildIfNeeded(
child, *layout_result, previous_inflow_position,
- logical_offset.block_offset, has_container_separation);
+ *child_bfc_block_offset, has_container_separation);
if (break_status == NGBreakStatus::kBrokeBefore)
return NGLayoutResult::kSuccess;
if (break_status == NGBreakStatus::kNeedsEarlierBreak)
@@ -1753,6 +1812,7 @@ NGLayoutResult::EStatus NGBlockLayoutAlgorithm::FinishInflow(
previous_inflow_position))
return NGLayoutResult::kBfcBlockOffsetResolved;
+ PropagateBaselineFromChild(physical_fragment, logical_offset.block_offset);
container_builder_.AddResult(*layout_result, logical_offset);
if (auto* block_child = DynamicTo<NGBlockNode>(child)) {
@@ -1795,6 +1855,24 @@ NGLayoutResult::EStatus NGBlockLayoutAlgorithm::FinishInflow(
}
}
+ // Update |lines_until_clamp_| from the LayoutResult.
+ if (lines_until_clamp_) {
+ if (const auto* line_box =
+ DynamicTo<NGPhysicalLineBoxFragment>(physical_fragment)) {
+ if (!line_box->IsEmptyLineBox())
+ lines_until_clamp_ = *lines_until_clamp_ - 1;
+ } else {
+ lines_until_clamp_ = layout_result->LinesUntilClamp();
+ }
+ if (lines_until_clamp_ <= 0 &&
+ !intrinsic_block_size_when_clamped_.has_value()) {
+ // 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;
+ }
+ }
return NGLayoutResult::kSuccess;
}
@@ -1832,32 +1910,9 @@ NGInflowChildData NGBlockLayoutAlgorithm::ComputeChildData(
LayoutUnit logical_block_offset =
previous_inflow_position.logical_block_offset;
- EMarginCollapse margin_before_collapse = child.Style().MarginBeforeCollapse();
- if (margin_before_collapse != EMarginCollapse::kCollapse) {
- // Stop margin collapsing on the block-start side of the child.
- StopMarginCollapsing(child.Style().MarginBeforeCollapse(),
- margins.block_start, &logical_block_offset,
- &margin_strut);
-
- if (margin_before_collapse == EMarginCollapse::kSeparate) {
- UseCounter::Count(Node().GetDocument(),
- WebFeature::kWebkitMarginBeforeCollapseSeparate);
- if (margin_strut != previous_inflow_position.margin_strut ||
- logical_block_offset !=
- previous_inflow_position.logical_block_offset) {
- UseCounter::Count(
- Node().GetDocument(),
- WebFeature::kWebkitMarginBeforeCollapseSeparateMaybeDoesSomething);
- }
- } else if (margin_before_collapse == EMarginCollapse::kDiscard) {
- UseCounter::Count(Node().GetDocument(),
- WebFeature::kWebkitMarginBeforeCollapseDiscard);
- }
- } else {
- margin_strut.Append(margins.block_start,
- child.Style().HasMarginBeforeQuirk());
- SetSubtreeModifiedMarginStrutIfNeeded(&child.Style().MarginBefore());
- }
+ margin_strut.Append(margins.block_start,
+ child.Style().HasMarginBeforeQuirk());
+ SetSubtreeModifiedMarginStrutIfNeeded(&child.Style().MarginBefore());
NGBfcOffset child_bfc_offset = {
ConstraintSpace().BfcOffset().line_offset +
@@ -1945,36 +2000,14 @@ NGPreviousInflowPosition NGBlockLayoutAlgorithm::ComputeInflowPosition(
NGMarginStrut margin_strut = layout_result.EndMarginStrut();
- EMarginCollapse margin_after_collapse = child.Style().MarginAfterCollapse();
- if (margin_after_collapse != EMarginCollapse::kCollapse) {
- LayoutUnit logical_block_offset_copy = logical_block_offset;
- // Stop margin collapsing on the block-end side of the child.
- StopMarginCollapsing(margin_after_collapse, child_data.margins.block_end,
- &logical_block_offset, &margin_strut);
-
- if (margin_after_collapse == EMarginCollapse::kSeparate) {
- UseCounter::Count(Node().GetDocument(),
- WebFeature::kWebkitMarginAfterCollapseSeparate);
- if (margin_strut != layout_result.EndMarginStrut() ||
- logical_block_offset != logical_block_offset_copy) {
- UseCounter::Count(
- Node().GetDocument(),
- WebFeature::kWebkitMarginAfterCollapseSeparateMaybeDoesSomething);
- }
- } else if (margin_after_collapse == EMarginCollapse::kDiscard) {
- UseCounter::Count(Node().GetDocument(),
- WebFeature::kWebkitMarginAfterCollapseDiscard);
- }
- } else {
- // Self collapsing child's end margin can "inherit" quirkiness from its
- // start margin. E.g.
- // <ol style="margin-bottom: 20px"></ol>
- bool is_quirky =
- (is_self_collapsing && child.Style().HasMarginBeforeQuirk()) ||
- child.Style().HasMarginAfterQuirk();
- margin_strut.Append(child_data.margins.block_end, is_quirky);
- SetSubtreeModifiedMarginStrutIfNeeded(&child.Style().MarginAfter());
- }
+ // Self collapsing child's end margin can "inherit" quirkiness from its start
+ // margin. E.g.
+ // <ol style="margin-bottom: 20px"></ol>
+ bool is_quirky =
+ (is_self_collapsing && child.Style().HasMarginBeforeQuirk()) ||
+ child.Style().HasMarginAfterQuirk();
+ margin_strut.Append(child_data.margins.block_end, is_quirky);
+ SetSubtreeModifiedMarginStrutIfNeeded(&child.Style().MarginAfter());
// This flag is subtle, but in order to determine our size correctly we need
// to check if our last child is self-collapsing, and it was affected by
@@ -2044,7 +2077,7 @@ void NGBlockLayoutAlgorithm::SetFragmentainerOutOfSpace(
}
bool NGBlockLayoutAlgorithm::FinalizeForFragmentation() {
- if (Node().ChildrenInline() && !early_break_) {
+ if (Node().IsInlineFormattingContextRoot() && !early_break_) {
if (container_builder_.DidBreak() || first_overflowing_line_) {
if (first_overflowing_line_ &&
first_overflowing_line_ < container_builder_.LineCount()) {
@@ -2112,8 +2145,8 @@ bool NGBlockLayoutAlgorithm::FinalizeForFragmentation() {
}
}
- FinishFragmentation(ConstraintSpace(), block_size, intrinsic_block_size_,
- consumed_block_size, space_left, &container_builder_);
+ FinishFragmentation(ConstraintSpace(), BreakToken(), block_size,
+ intrinsic_block_size_, space_left, &container_builder_);
return true;
}
@@ -2122,14 +2155,13 @@ NGBreakStatus NGBlockLayoutAlgorithm::BreakBeforeChildIfNeeded(
NGLayoutInputNode child,
const NGLayoutResult& layout_result,
NGPreviousInflowPosition* previous_inflow_position,
- LayoutUnit block_offset,
+ LayoutUnit bfc_block_offset,
bool has_container_separation) {
DCHECK(ConstraintSpace().HasBlockFragmentation());
// If the BFC offset is unknown, there's nowhere to break, since there's no
// non-empty child content yet (as that would have resolved the BFC offset).
- if (!container_builder_.BfcBlockOffset())
- return NGBreakStatus::kContinue;
+ DCHECK(container_builder_.BfcBlockOffset());
// If we already know where to insert the break, we already know that it's not
// going to be here, since that's something we check before entering layout of
@@ -2138,8 +2170,7 @@ NGBreakStatus NGBlockLayoutAlgorithm::BreakBeforeChildIfNeeded(
return NGBreakStatus::kContinue;
LayoutUnit fragmentainer_block_offset =
- ConstraintSpace().FragmentainerOffsetAtBfc() +
- *container_builder_.BfcBlockOffset() + block_offset;
+ ConstraintSpace().FragmentainerOffsetAtBfc() + bfc_block_offset;
if (has_container_separation) {
EBreakBetween break_between =
@@ -2315,7 +2346,7 @@ NGBoxStrut NGBlockLayoutAlgorithm::CalculateMargins(
NGConstraintSpace space = builder.ToConstraintSpace();
NGBoxStrut child_border_padding =
- ComputeBorders(space, child) + ComputePadding(space, child.Style());
+ ComputeBorders(space, child_style) + ComputePadding(space, child_style);
LayoutUnit child_inline_size =
ComputeInlineSizeForFragment(space, child, child_border_padding);
@@ -2327,29 +2358,6 @@ NGBoxStrut NGBlockLayoutAlgorithm::CalculateMargins(
return margins;
}
-// Stop margin collapsing on one side of a block when
-// -webkit-margin-{after,before}-collapse is something other than 'collapse'
-// (the initial value)
-void NGBlockLayoutAlgorithm::StopMarginCollapsing(
- EMarginCollapse collapse_value,
- LayoutUnit this_margin,
- LayoutUnit* logical_block_offset,
- NGMarginStrut* margin_strut) {
- DCHECK_NE(collapse_value, EMarginCollapse::kCollapse);
- if (collapse_value == EMarginCollapse::kSeparate) {
- // Separate margins between previously adjoining margins and this margin,
- // AND between this margin and adjoining margins to come.
- *logical_block_offset += margin_strut->Sum() + this_margin;
- *margin_strut = NGMarginStrut();
- return;
- }
- DCHECK_EQ(collapse_value, EMarginCollapse::kDiscard);
- // Discard previously adjoining margins, this margin AND all adjoining margins
- // to come, so that the sum becomes 0.
- margin_strut->discard_margins = true;
- SetSubtreeModifiedMarginStrutIfNeeded();
-}
-
NGConstraintSpace NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild(
const NGLayoutInputNode child,
const NGInflowChildData& child_data,
@@ -2369,6 +2377,9 @@ NGConstraintSpace NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild(
if (!IsParallelWritingMode(ConstraintSpace().GetWritingMode(),
child_writing_mode))
builder.SetIsShrinkToFit(child_style.LogicalWidth().IsAuto());
+ if (child_style.LogicalWidth().IsAuto() &&
+ child.GetLayoutBox()->AutoWidthShouldFitContent())
+ builder.SetIsShrinkToFit(true);
builder.SetAvailableSize(child_available_size);
builder.SetPercentageResolutionSize(child_percentage_size_);
@@ -2387,9 +2398,6 @@ NGConstraintSpace NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild(
builder.SetTableCellChildLayoutMode(mode);
}
- if (NGBaseline::ShouldPropagateBaselines(child))
- builder.AddBaselineRequests(ConstraintSpace().BaselineRequests());
-
bool has_bfc_block_offset = container_builder_.BfcBlockOffset().has_value();
// Propagate the |NGConstraintSpace::ForcedBfcBlockOffset| down to our
@@ -2447,11 +2455,10 @@ NGConstraintSpace NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild(
clearance_offset = std::max(clearance_offset, child_clearance_offset);
builder.SetTextDirection(child_style.Direction());
- // PositionListMarker() requires a first line baseline.
- if (container_builder_.UnpositionedListMarker()) {
- builder.AddBaselineRequest(
- {NGBaselineAlgorithmType::kFirstLine, style.GetFontBaseline()});
- }
+ // |PositionListMarker()| requires a baseline.
+ builder.SetNeedsBaseline(ConstraintSpace().NeedsBaseline() ||
+ container_builder_.UnpositionedListMarker());
+ builder.SetBaselineAlgorithmType(ConstraintSpace().BaselineAlgorithmType());
} else {
builder.SetTextDirection(style.Direction());
}
@@ -2465,6 +2472,8 @@ NGConstraintSpace NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild(
builder.SetAdjoiningObjectTypes(
container_builder_.AdjoiningObjectTypes());
}
+ builder.SetLinesUntilClamp(lines_until_clamp_);
+ builder.SetForceTruncateAtLineClamp(force_truncate_at_line_clamp_);
} else if (child_data.is_resuming_after_break) {
// If the child is being resumed after a break, margins inside the child may
// be adjoining with the fragmentainer boundary, regardless of whether the
@@ -2479,109 +2488,78 @@ NGConstraintSpace NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild(
// fragmentation line.
if (is_new_fc)
fragmentainer_offset_delta = *child_bfc_block_offset;
- SetupFragmentation(ConstraintSpace(), fragmentainer_offset_delta, &builder,
- is_new_fc);
+ SetupFragmentation(ConstraintSpace(), child, fragmentainer_offset_delta,
+ &builder, is_new_fc);
builder.SetEarlyBreakAppeal(container_builder_.BreakAppeal());
}
return builder.ToConstraintSpace();
}
-LayoutUnit NGBlockLayoutAlgorithm::ComputeLineBoxBaselineOffset(
- const NGBaselineRequest& request,
- const NGPhysicalLineBoxFragment& line_box,
- LayoutUnit line_box_block_offset) const {
- NGLineHeightMetrics metrics =
- line_box.BaselineMetrics(request.BaselineType());
- DCHECK(!metrics.IsEmpty());
-
- // NGLineHeightMetrics is line-relative, which matches to the flow-relative
- // unless this box is in flipped-lines writing-mode.
- if (!Style().IsFlippedLinesWritingMode())
- return metrics.ascent + line_box_block_offset;
-
- if (Node().IsInlineLevel()) {
- // If this box is inline-level, since we're in NGBlockLayoutAlgorithm, this
- // is an inline-block.
- DCHECK(Node().IsAtomicInlineLevel());
- // This box will be flipped when the containing line is flipped. Compute the
- // baseline offset from the block-end (right in vertical-lr) content edge.
- line_box_block_offset = container_builder_.Size().block_size -
- (line_box_block_offset + line_box.Size().width);
- return metrics.ascent + line_box_block_offset;
- }
-
- // Otherwise, the baseline is offset by the descent from the block-start
- // content edge.
- return metrics.descent + line_box_block_offset;
-}
+void NGBlockLayoutAlgorithm::PropagateBaselineFromChild(
+ const NGPhysicalContainerFragment& child,
+ LayoutUnit block_offset) {
+ // Check if we've already found an appropriate baseline.
+ if (container_builder_.Baseline() &&
+ ConstraintSpace().BaselineAlgorithmType() ==
+ NGBaselineAlgorithmType::kFirstLine)
+ return;
-// Add a baseline from a child box fragment.
-// @return false if the specified child is not a box or is OOF.
-bool NGBlockLayoutAlgorithm::AddBaseline(const NGBaselineRequest& request,
- const NGPhysicalFragment& child,
- LayoutUnit child_offset) {
if (child.IsLineBox()) {
const auto& line_box = To<NGPhysicalLineBoxFragment>(child);
- // Skip over a line-box which is empty. These don't have any baselines which
- // should be added.
+ // Skip over a line-box which is empty. These don't have any baselines
+ // which should be added.
if (line_box.IsEmptyLineBox())
- return false;
+ return;
- LayoutUnit offset =
- ComputeLineBoxBaselineOffset(request, line_box, child_offset);
- container_builder_.AddBaseline(request, offset);
- return true;
+ NGLineHeightMetrics metrics = line_box.BaselineMetrics();
+ DCHECK(!metrics.IsEmpty());
+ LayoutUnit baseline =
+ block_offset + (Style().IsFlippedLinesWritingMode() ? metrics.descent
+ : metrics.ascent);
+
+ if (!container_builder_.Baseline())
+ container_builder_.SetBaseline(baseline);
+
+ // Set the last baseline only if required.
+ if (ConstraintSpace().BaselineAlgorithmType() !=
+ NGBaselineAlgorithmType::kFirstLine)
+ container_builder_.SetLastBaseline(baseline);
+
+ return;
}
- if (child.IsFloatingOrOutOfFlowPositioned())
- return false;
+ NGBoxFragment fragment(ConstraintSpace().GetWritingMode(),
+ ConstraintSpace().Direction(),
+ To<NGPhysicalBoxFragment>(child));
- if (const auto* box = DynamicTo<NGPhysicalBoxFragment>(child)) {
- if (base::Optional<LayoutUnit> baseline = box->Baseline(request)) {
- container_builder_.AddBaseline(request, *baseline + child_offset);
- return true;
- }
+ if (!container_builder_.Baseline()) {
+ if (auto baseline = fragment.FirstBaseline())
+ container_builder_.SetBaseline(block_offset + *baseline);
}
- return false;
+ // Set the last baseline only if required.
+ if (ConstraintSpace().BaselineAlgorithmType() !=
+ NGBaselineAlgorithmType::kFirstLine) {
+ if (auto last_baseline = fragment.Baseline())
+ container_builder_.SetLastBaseline(block_offset + *last_baseline);
+ }
}
-// Propagate computed baselines from children.
-// Skip children that do not produce baselines (e.g., empty blocks.)
-void NGBlockLayoutAlgorithm::PropagateBaselinesFromChildren() {
- const NGBaselineRequestList requests = ConstraintSpace().BaselineRequests();
- if (requests.IsEmpty())
+void NGBlockLayoutAlgorithm::FinalizeBaseline() {
+ if (ConstraintSpace().BaselineAlgorithmType() !=
+ NGBaselineAlgorithmType::kInlineBlock)
return;
- for (const auto& request : requests) {
- switch (request.AlgorithmType()) {
- case NGBaselineAlgorithmType::kAtomicInline: {
- if (Node().UseLogicalBottomMarginEdgeForInlineBlockBaseline()) {
- LayoutUnit block_end = container_builder_.BlockSize();
- NGBoxStrut margins =
- ComputeMarginsForSelf(ConstraintSpace(), Style());
- container_builder_.AddBaseline(request,
- block_end + margins.block_end);
- break;
- }
+ if (!Node().UseLogicalBottomMarginEdgeForInlineBlockBaseline())
+ return;
- const auto& children = container_builder_.Children();
- for (auto it = children.rbegin(); it != children.rend(); ++it) {
- if (AddBaseline(request, *it->fragment, it->offset.block_offset))
- break;
- }
- break;
- }
- case NGBaselineAlgorithmType::kFirstLine:
- for (const auto& child : container_builder_.Children()) {
- if (AddBaseline(request, *child.fragment, child.offset.block_offset))
- break;
- }
- break;
- }
- }
+ // 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());
+ container_builder_.SetLastBaseline(container_builder_.BlockSize() +
+ margins.block_end);
}
bool NGBlockLayoutAlgorithm::ResolveBfcBlockOffset(
@@ -2687,12 +2665,11 @@ bool NGBlockLayoutAlgorithm::PositionOrPropagateListMarker(
container_builder_.SetUnpositionedListMarker(NGUnpositionedListMarker());
}
- NGLineHeightMetrics content_metrics;
const NGConstraintSpace& space = ConstraintSpace();
const NGPhysicalFragment& content = layout_result.PhysicalFragment();
FontBaseline baseline_type = Style().GetFontBaseline();
- if (list_marker.CanAddToBox(space, baseline_type, content,
- &content_metrics)) {
+ if (auto content_baseline =
+ list_marker.ContentAlignmentBaseline(space, baseline_type, content)) {
// TODO: We are reusing the ConstraintSpace for LI here. It works well for
// now because authors cannot style list-markers currently. If we want to
// support `::marker` pseudo, we need to create ConstraintSpace for marker
@@ -2713,8 +2690,8 @@ bool NGBlockLayoutAlgorithm::PositionOrPropagateListMarker(
}
list_marker.AddToBox(space, baseline_type, content,
- border_scrollbar_padding_, content_metrics,
- *marker_layout_result, content_offset,
+ border_scrollbar_padding_, *marker_layout_result,
+ *content_baseline, content_offset,
&container_builder_);
return true;
}
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 8274b1dc201..644bb031ead 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
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_BLOCK_LAYOUT_ALGORITHM_H_
#include "base/memory/scoped_refptr.h"
+#include "base/optional.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_margin_strut.h"
@@ -17,6 +18,7 @@
#include "third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h"
#include "third_party/blink/renderer/core/layout/ng/ng_unpositioned_float.h"
+#include "third_party/blink/renderer/platform/geometry/layout_unit.h"
namespace blink {
@@ -24,7 +26,6 @@ enum class NGBreakStatus;
class NGConstraintSpace;
class NGEarlyBreak;
class NGFragment;
-class NGPhysicalLineBoxFragment;
// This struct is used for communicating to a child the position of the previous
// inflow child. This will be used to calculate the position of the next child.
@@ -58,8 +59,8 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
void SetBoxType(NGPhysicalFragment::NGBoxType type);
- base::Optional<MinMaxSize> ComputeMinMaxSize(
- const MinMaxSizeInput&) const override;
+ base::Optional<MinMaxSizes> ComputeMinMaxSizes(
+ const MinMaxSizesInput&) const override;
scoped_refptr<const NGLayoutResult> Layout() override;
private:
@@ -75,10 +76,14 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
NOINLINE scoped_refptr<const NGLayoutResult> RelayoutAndBreakEarlier(
const NGEarlyBreak&);
+ NOINLINE scoped_refptr<const NGLayoutResult>
+ RelayoutNoForcedTruncateForLineClamp();
+
inline scoped_refptr<const NGLayoutResult> Layout(
NGInlineChildLayoutContext* inline_child_layout_context);
- scoped_refptr<const NGLayoutResult> FinishLayout(NGPreviousInflowPosition*);
+ scoped_refptr<const NGLayoutResult> FinishLayout(
+ NGPreviousInflowPosition* previous_inflow_position);
// Return the BFC block offset of this block.
LayoutUnit BfcBlockOffset() const {
@@ -102,11 +107,6 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
bool is_new_fc,
bool* margins_fully_resolved);
- void StopMarginCollapsing(EMarginCollapse collapse_value,
- LayoutUnit this_margin,
- LayoutUnit* logical_block_offset,
- NGMarginStrut* margin_strut);
-
// Creates a new constraint space for the current child.
NGConstraintSpace CreateConstraintSpaceForChild(
const NGLayoutInputNode child,
@@ -238,25 +238,19 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
NGBreakStatus BreakBeforeChildIfNeeded(NGLayoutInputNode child,
const NGLayoutResult&,
NGPreviousInflowPosition*,
- LayoutUnit block_offset,
+ LayoutUnit bfc_block_offset,
bool has_container_separation);
// Look for a better breakpoint (than we already have) between lines (i.e. a
// class B breakpoint), and store it.
void UpdateEarlyBreakBetweenLines();
- void PropagateBaselinesFromChildren();
- bool AddBaseline(const NGBaselineRequest&,
- const NGPhysicalFragment&,
- LayoutUnit child_offset);
+ // Propagates the baseline from the given |child| if needed.
+ void PropagateBaselineFromChild(const NGPhysicalContainerFragment& child,
+ LayoutUnit block_offset);
- // Compute the baseline offset of a line box from the content box.
- // Line boxes are in line-relative coordinates. This function returns the
- // offset in flow-relative coordinates.
- LayoutUnit ComputeLineBoxBaselineOffset(
- const NGBaselineRequest&,
- const NGPhysicalLineBoxFragment&,
- LayoutUnit line_box_block_offset) const;
+ // Performs any final baseline adjustments needed.
+ void FinalizeBaseline();
// If still unresolved, resolve the fragment's BFC block offset.
//
@@ -396,6 +390,18 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
NGExclusionSpace exclusion_space_;
+ // If set, this is the number of lines until a clamp. A value of 1 indicates
+ // the current line should be clamped. This may go negative.
+ base::Optional<int> lines_until_clamp_;
+
+ // If true, truncation is forced at the clamped line regardless of whether
+ // there is more text.
+ bool force_truncate_at_line_clamp_ = true;
+
+ // If set, one of the lines was clamped and this is the intrinsic size at the
+ // time of the clamp.
+ base::Optional<LayoutUnit> intrinsic_block_size_when_clamped_;
+
// When set, this will specify where to break before or inside.
const NGEarlyBreak* early_break_ = nullptr;
};
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 1cc8a99f1ed..f07b9dcfcf3 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
@@ -33,7 +33,7 @@ class NGBlockLayoutAlgorithmTest : public NGBaseLayoutAlgorithmTest {
NGBaseLayoutAlgorithmTest::SetUp();
}
- MinMaxSize RunComputeMinAndMax(NGBlockNode node) {
+ MinMaxSizes RunComputeMinMaxSizes(NGBlockNode node) {
// The constraint space is not used for min/max computation, but we need
// it to create the algorithm.
NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
@@ -43,9 +43,9 @@ class NGBlockLayoutAlgorithmTest : public NGBaseLayoutAlgorithmTest {
CalculateInitialMinMaxFragmentGeometry(space, node);
NGBlockLayoutAlgorithm algorithm({node, fragment_geometry, space});
- MinMaxSizeInput input(
+ MinMaxSizesInput input(
/* percentage_resolution_block_size */ (LayoutUnit()));
- auto min_max = algorithm.ComputeMinMaxSize(input);
+ auto min_max = algorithm.ComputeMinMaxSizes(input);
EXPECT_TRUE(min_max.has_value());
return *min_max;
}
@@ -97,10 +97,11 @@ TEST_F(NGBlockLayoutAlgorithmTest, FixedSize) {
}
TEST_F(NGBlockLayoutAlgorithmTest, Caching) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
+ // The inner element exists so that "simplified" layout logic isn't invoked.
SetBodyInnerHTML(R"HTML(
- <div id="box" style="width:30px; height:40%;"></div>
+ <div id="box" style="width:30px; height:40%;">
+ <div style="height: 100%;"></div>
+ </div>
)HTML");
NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
@@ -132,7 +133,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, Caching) {
EXPECT_NE(result.get(), nullptr);
// Test a different constraint space that will actually result in a different
- // size.
+ // sized fragment.
space = ConstructBlockLayoutTestConstraintSpace(
WritingMode::kHorizontalTb, TextDirection::kLtr,
LogicalSize(LayoutUnit(200), LayoutUnit(200)));
@@ -146,8 +147,6 @@ TEST_F(NGBlockLayoutAlgorithmTest, Caching) {
}
TEST_F(NGBlockLayoutAlgorithmTest, MinInlineSizeCaching) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
SetBodyInnerHTML(R"HTML(
<div id="box" style="min-width:30%; width: 10px; height:40px;"></div>
)HTML");
@@ -190,8 +189,6 @@ TEST_F(NGBlockLayoutAlgorithmTest, MinInlineSizeCaching) {
}
TEST_F(NGBlockLayoutAlgorithmTest, PercentageBlockSizeQuirkDescendantsCaching) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
// Quirks mode triggers the interesting parent-child %-resolution behaviour.
GetDocument().SetCompatibilityMode(Document::kQuirksMode);
@@ -237,10 +234,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, PercentageBlockSizeQuirkDescendantsCaching) {
builder.SetAvailableSize(size);
builder.SetPercentageResolutionSize(size);
builder.SetTextDirection(TextDirection::kLtr);
- builder.AddBaselineRequest({NGBaselineAlgorithmType::kAtomicInline,
- FontBaseline::kAlphabeticBaseline});
- builder.AddBaselineRequest({NGBaselineAlgorithmType::kFirstLine,
- FontBaseline::kAlphabeticBaseline});
+ builder.SetNeedsBaseline(true);
return builder.ToConstraintSpace();
};
@@ -298,99 +292,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, PercentageBlockSizeQuirkDescendantsCaching) {
EXPECT_EQ(run_test("box9"), nullptr);
}
-TEST_F(NGBlockLayoutAlgorithmTest, ShrinkToFitCaching) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
- SetBodyInnerHTML(R"HTML(
- <div id="container" style="display: flow-root; width: 300px; height: 100px;">
- <div id="box1" style="float: left;">
- <div style="display: inline-block; width: 150px;"></div>
- <div style="display: inline-block; width: 50px;"></div>
- </div>
- <div id="box2" style="float: left;">
- <div style="display: inline-block; width: 350px;"></div>
- <div style="display: inline-block; width: 250px;"></div>
- </div>
- <div id="box3" style="float: left; min-width: 80%;">
- <div style="display: inline-block; width: 150px;"></div>
- <div style="display: inline-block; width: 250px;"></div>
- </div>
- <div id="box4" style="float: left; margin-left: 75px;">
- <div style="display: inline-block; width: 150px;"></div>
- <div style="display: inline-block; width: 50px;"></div>
- </div>
- </div>
- )HTML");
-
- NGConstraintSpace space100 = ConstructBlockLayoutTestConstraintSpace(
- WritingMode::kHorizontalTb, TextDirection::kLtr,
- LogicalSize(LayoutUnit(100), LayoutUnit(100)),
- /* shrink_to_fit */ true, /* is_new_formatting_context */ true);
- NGConstraintSpace space200 = ConstructBlockLayoutTestConstraintSpace(
- WritingMode::kHorizontalTb, TextDirection::kLtr,
- LogicalSize(LayoutUnit(200), LayoutUnit(100)),
- /* shrink_to_fit */ true, /* is_new_formatting_context */ true);
- NGConstraintSpace space250 = ConstructBlockLayoutTestConstraintSpace(
- WritingMode::kHorizontalTb, TextDirection::kLtr,
- LogicalSize(LayoutUnit(250), LayoutUnit(100)),
- /* shrink_to_fit */ true, /* is_new_formatting_context */ true);
- NGConstraintSpace space300 = ConstructBlockLayoutTestConstraintSpace(
- WritingMode::kHorizontalTb, TextDirection::kLtr,
- LogicalSize(LayoutUnit(300), LayoutUnit(100)),
- /* shrink_to_fit */ true, /* is_new_formatting_context */ true);
- NGConstraintSpace space400 = ConstructBlockLayoutTestConstraintSpace(
- WritingMode::kHorizontalTb, TextDirection::kLtr,
- LogicalSize(LayoutUnit(400), LayoutUnit(100)),
- /* shrink_to_fit */ true, /* is_new_formatting_context */ true);
- scoped_refptr<const NGLayoutResult> result;
-
- auto* box1 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("box1"));
- auto* box2 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("box2"));
- auto* box3 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("box3"));
- auto* box4 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("box4"));
-
- // Ensure we cached the result for box1 in the first layout pass.
- result = RunCachedLayoutResult(space300, NGBlockNode(box1));
- EXPECT_NE(result.get(), nullptr);
-
- // box1 was sized to its max-content size in the first layout pass, passing
- // an available size larger than the fragment should hit the cache.
- result = RunCachedLayoutResult(space400, NGBlockNode(box1));
- EXPECT_NE(result.get(), nullptr);
-
- // Passing an available size smaller than the fragment should miss the cache
- // as the fragment may shrink.
- result = RunCachedLayoutResult(space100, NGBlockNode(box1));
- EXPECT_EQ(result.get(), nullptr);
-
- // Ensure we cached the result for box2 in the first layout pass.
- result = RunCachedLayoutResult(space300, NGBlockNode(box2));
- EXPECT_NE(result.get(), nullptr);
-
- // box2 was sized to its min-content size in the first layout pass, passing
- // an available size smaller than the fragment should hit the cache.
- result = RunCachedLayoutResult(space200, NGBlockNode(box2));
- EXPECT_NE(result.get(), nullptr);
-
- // Passing an available size larger than the fragment should miss the cache
- // as the fragment may shrink.
- result = RunCachedLayoutResult(space400, NGBlockNode(box2));
- EXPECT_EQ(result.get(), nullptr);
-
- // box3 was sized to its min-content size in the first layout pass, however
- // it should miss the cache as it has a %-min-size.
- result = RunCachedLayoutResult(space200, NGBlockNode(box3));
- EXPECT_EQ(result.get(), nullptr);
-
- // box4 was sized to its max-content size in the first layout pass (the same
- // as box1) however it should miss the cache due to its margin.
- result = RunCachedLayoutResult(space250, NGBlockNode(box4));
- EXPECT_EQ(result.get(), nullptr);
-}
-
TEST_F(NGBlockLayoutAlgorithmTest, LineOffsetCaching) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
SetBodyInnerHTML(R"HTML(
<div id="container" style="display: flow-root; width: 300px; height: 100px;">
<div id="box1" style="width: 100px; margin: 0 auto 0 auto;"></div>
@@ -404,10 +306,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, LineOffsetCaching) {
builder.SetAvailableSize(size);
builder.SetPercentageResolutionSize(size);
builder.SetTextDirection(TextDirection::kLtr);
- builder.AddBaselineRequest({NGBaselineAlgorithmType::kAtomicInline,
- FontBaseline::kAlphabeticBaseline});
- builder.AddBaselineRequest({NGBaselineAlgorithmType::kFirstLine,
- FontBaseline::kAlphabeticBaseline});
+ builder.SetNeedsBaseline(true);
builder.SetBfcOffset(bfc_offset);
return builder.ToConstraintSpace();
};
@@ -1645,7 +1544,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, ComputeMinMaxContent) {
NGBlockNode container(ToLayoutBox(GetLayoutObjectByElementId("container")));
- MinMaxSize sizes = RunComputeMinAndMax(container);
+ MinMaxSizes sizes = RunComputeMinMaxSizes(container);
EXPECT_EQ(kSecondChildWidth, sizes.min_size);
EXPECT_EQ(kSecondChildWidth, sizes.max_size);
}
@@ -1666,7 +1565,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, ComputeMinMaxContentFloats) {
NGBlockNode container(ToLayoutBox(GetLayoutObjectByElementId("container")));
- MinMaxSize sizes = RunComputeMinAndMax(container);
+ MinMaxSizes sizes = RunComputeMinMaxSizes(container);
EXPECT_EQ(LayoutUnit(40), sizes.min_size);
EXPECT_EQ(LayoutUnit(90), sizes.max_size);
}
@@ -1687,7 +1586,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, ComputeMinMaxContentFloatsClearance) {
NGBlockNode container(ToLayoutBox(GetLayoutObjectByElementId("container")));
- MinMaxSize sizes = RunComputeMinAndMax(container);
+ MinMaxSizes sizes = RunComputeMinMaxSizes(container);
EXPECT_EQ(LayoutUnit(40), sizes.min_size);
EXPECT_EQ(LayoutUnit(50), sizes.max_size);
}
@@ -1708,7 +1607,7 @@ TEST_F(NGBlockLayoutAlgorithmTest, ComputeMinMaxContentNewFormattingContext) {
NGBlockNode container(ToLayoutBox(GetLayoutObjectByElementId("container")));
- MinMaxSize sizes = RunComputeMinAndMax(container);
+ MinMaxSizes sizes = RunComputeMinMaxSizes(container);
EXPECT_EQ(LayoutUnit(100), sizes.min_size);
EXPECT_EQ(LayoutUnit(100), sizes.max_size);
}
@@ -1730,7 +1629,7 @@ TEST_F(NGBlockLayoutAlgorithmTest,
NGBlockNode container(ToLayoutBox(GetLayoutObjectByElementId("container")));
- MinMaxSize sizes = RunComputeMinAndMax(container);
+ MinMaxSizes sizes = RunComputeMinMaxSizes(container);
EXPECT_EQ(LayoutUnit(30), sizes.min_size);
EXPECT_EQ(LayoutUnit(70), sizes.max_size);
}
@@ -1748,7 +1647,7 @@ TEST_F(NGBlockLayoutAlgorithmTest,
NGBlockNode container(ToLayoutBox(GetLayoutObjectByElementId("container")));
- MinMaxSize sizes = RunComputeMinAndMax(container);
+ MinMaxSizes sizes = RunComputeMinMaxSizes(container);
EXPECT_EQ(LayoutUnit(), sizes.min_size);
EXPECT_EQ(LayoutUnit(), sizes.max_size);
}
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 301d9e9215b..48871b0c4f8 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
@@ -7,8 +7,11 @@
#include <memory>
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
+#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/html_marquee_element.h"
+#include "third_party/blink/renderer/core/input_type_names.h"
#include "third_party/blink/renderer/core/layout/box_layout_extra_input.h"
+#include "third_party/blink/renderer/core/layout/intrinsic_sizing_info.h"
#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
#include "third_party/blink/renderer/core/layout/layout_fieldset.h"
#include "third_party/blink/renderer/core/layout/layout_inline.h"
@@ -17,7 +20,8 @@
#include "third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.h"
#include "third_party/blink/renderer/core/layout/layout_table.h"
#include "third_party/blink/renderer/core/layout/layout_table_cell.h"
-#include "third_party/blink/renderer/core/layout/min_max_size.h"
+#include "third_party/blink/renderer/core/layout/layout_video.h"
+#include "third_party/blink/renderer/core/layout/min_max_sizes.h"
#include "third_party/blink/renderer/core/layout/ng/custom/layout_ng_custom.h"
#include "third_party/blink/renderer/core/layout/ng/custom/ng_custom_layout_algorithm.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_fragment_geometry.h"
@@ -25,6 +29,10 @@
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
#include "third_party/blink/renderer/core/layout/ng/legacy_layout_tree_walking.h"
#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h"
+#include "third_party/blink/renderer/core/layout/ng/mathml/ng_math_fraction_layout_algorithm.h"
+#include "third_party/blink/renderer/core/layout/ng/mathml/ng_math_layout_utils.h"
+#include "third_party/blink/renderer/core/layout/ng/mathml/ng_math_row_layout_algorithm.h"
+#include "third_party/blink/renderer/core/layout/ng/mathml/ng_math_space_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_block_layout_algorithm.h"
#include "third_party/blink/renderer/core/layout/ng/ng_box_fragment.h"
@@ -43,6 +51,10 @@
#include "third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.h"
#include "third_party/blink/renderer/core/layout/ng/ng_space_utils.h"
#include "third_party/blink/renderer/core/layout/shapes/shape_outside_info.h"
+#include "third_party/blink/renderer/core/layout/text_autosizer.h"
+#include "third_party/blink/renderer/core/mathml/mathml_element.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/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/text/writing_mode.h"
@@ -74,6 +86,24 @@ NOINLINE void CreateAlgorithmAndRun(const NGLayoutAlgorithmParams& params,
}
template <typename Callback>
+NOINLINE void DetermineMathMLAlgorithmAndRun(
+ const LayoutBox& box,
+ const NGLayoutAlgorithmParams& params,
+ const Callback& callback) {
+ DCHECK(box.IsMathML());
+ // Currently math layout algorithms can only apply to MathML elements.
+ auto* element = box.GetNode();
+ DCHECK(element);
+ if (IsA<MathMLSpaceElement>(element))
+ CreateAlgorithmAndRun<NGMathSpaceLayoutAlgorithm>(params, callback);
+ else if (IsA<MathMLFractionElement>(element) &&
+ IsValidMathMLFraction(params.node))
+ CreateAlgorithmAndRun<NGMathFractionLayoutAlgorithm>(params, callback);
+ else
+ CreateAlgorithmAndRun<NGMathRowLayoutAlgorithm>(params, callback);
+}
+
+template <typename Callback>
NOINLINE void DetermineAlgorithmAndRun(const NGLayoutAlgorithmParams& params,
const Callback& callback) {
const ComputedStyle& style = params.node.Style();
@@ -82,6 +112,8 @@ NOINLINE void DetermineAlgorithmAndRun(const NGLayoutAlgorithmParams& params,
CreateAlgorithmAndRun<NGFlexLayoutAlgorithm>(params, callback);
} else if (box.IsLayoutNGCustom()) {
CreateAlgorithmAndRun<NGCustomLayoutAlgorithm>(params, callback);
+ } else if (box.IsMathML()) {
+ DetermineMathMLAlgorithmAndRun(box, params, callback);
} else if (box.IsLayoutNGFieldset()) {
CreateAlgorithmAndRun<NGFieldsetLayoutAlgorithm>(params, callback);
// If there's a legacy layout box, we can only do block fragmentation if
@@ -108,15 +140,15 @@ inline scoped_refptr<const NGLayoutResult> LayoutWithAlgorithm(
return result;
}
-inline base::Optional<MinMaxSize> ComputeMinMaxSizeWithAlgorithm(
+inline base::Optional<MinMaxSizes> ComputeMinMaxSizesWithAlgorithm(
const NGLayoutAlgorithmParams& params,
- const MinMaxSizeInput& input) {
- base::Optional<MinMaxSize> minmax;
+ const MinMaxSizesInput& input) {
+ base::Optional<MinMaxSizes> min_max_sizes;
DetermineAlgorithmAndRun(
- params, [&minmax, &input](NGLayoutAlgorithmOperations* algorithm) {
- minmax = algorithm->ComputeMinMaxSize(input);
+ params, [&min_max_sizes, &input](NGLayoutAlgorithmOperations* algorithm) {
+ min_max_sizes = algorithm->ComputeMinMaxSizes(input);
});
- return minmax;
+ return min_max_sizes;
}
void UpdateLegacyMultiColumnFlowThread(
@@ -131,7 +163,7 @@ void UpdateLegacyMultiColumnFlowThread(
// Stitch the columns together.
NGBoxStrut border_scrollbar_padding =
- ComputeBorders(constraint_space, node) +
+ ComputeBorders(constraint_space, node.Style()) +
ComputeScrollbars(constraint_space, node) +
ComputePadding(constraint_space, node.Style());
NGFragment logical_multicol_fragment(writing_mode, fragment);
@@ -171,7 +203,8 @@ void UpdateLegacyMultiColumnFlowThread(
if (!has_processed_first_column_in_flow_thread) {
// The offset of the flow thread should be the same as that of the first
// first column.
- flow_thread->SetLocation(child.Offset().ToLayoutPoint());
+ flow_thread->SetLocationAndUpdateOverflowControlsIfNeeded(
+ child.Offset().ToLayoutPoint());
flow_thread->SetLogicalWidth(logical_column_fragment.InlineSize());
has_processed_first_column_in_flow_thread = true;
}
@@ -267,11 +300,36 @@ void SetupBoxLayoutExtraInput(const NGConstraintSpace& space,
input->override_block_size = space.AvailableSize().block_size;
}
+bool CanUseCachedIntrinsicInlineSizes(const MinMaxSizesInput& input,
+ const LayoutBox& box) {
+ // Obviously can't use the cache if our intrinsic logical widths are dirty.
+ if (box.IntrinsicLogicalWidthsDirty())
+ return false;
+
+ // We don't store the float inline sizes for comparison, always skip the
+ // cache in this case.
+ if (input.float_left_inline_size || input.float_right_inline_size)
+ return false;
+
+ // Check if we have any percentage inline padding.
+ const auto& style = box.StyleRef();
+ if (style.MayHavePadding() && (style.PaddingStart().IsPercentOrCalc() ||
+ style.PaddingEnd().IsPercentOrCalc()))
+ return false;
+
+ // Check if the %-block-size matches.
+ if (input.percentage_resolution_block_size !=
+ box.IntrinsicLogicalWidthsPercentageResolutionBlockSize())
+ return false;
+
+ return true;
+}
+
} // namespace
scoped_refptr<const NGLayoutResult> NGBlockNode::Layout(
const NGConstraintSpace& constraint_space,
- const NGBreakToken* break_token,
+ const NGBlockBreakToken* break_token,
const NGEarlyBreak* early_break) {
// Use the old layout code and synthesize a fragment.
if (!CanUseNewLayout())
@@ -296,8 +354,8 @@ scoped_refptr<const NGLayoutResult> NGBlockNode::Layout(
scoped_refptr<const NGLayoutResult> layout_result =
box_->CachedLayoutResult(constraint_space, break_token, early_break,
&fragment_geometry, &cache_status);
- if (layout_result) {
- DCHECK_EQ(cache_status, NGLayoutCacheStatus::kHit);
+ if (cache_status == NGLayoutCacheStatus::kHit) {
+ DCHECK(layout_result);
// We may have to update the margins on box_; we reuse the layout result
// even if a percentage margin may have changed.
@@ -325,11 +383,13 @@ scoped_refptr<const NGLayoutResult> NGBlockNode::Layout(
CalculateInitialFragmentGeometry(constraint_space, *this);
}
+ TextAutosizer::NGLayoutScope text_autosizer_layout_scope(
+ box_, fragment_geometry->border_box_size.inline_size);
+
PrepareForLayout();
NGLayoutAlgorithmParams params(*this, *fragment_geometry, constraint_space,
- To<NGBlockBreakToken>(break_token),
- early_break);
+ break_token, early_break);
// Try to perform "simplified" layout.
// TODO(crbug.com/992953): Add a simplified layout pass for custom layout.
@@ -339,26 +399,33 @@ scoped_refptr<const NGLayoutResult> NGBlockNode::Layout(
!(block_flow->ChildrenInline() &&
RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) &&
!block_flow->IsLayoutNGCustom()) {
+ DCHECK(layout_result);
+#if DCHECK_IS_ON()
+ scoped_refptr<const NGLayoutResult> previous_result = layout_result;
+#endif
+
// A child may have changed size while performing "simplified" layout (it
// may have gained or removed scrollbars, changing its size). In these
// cases "simplified" layout will return a null layout-result, indicating
// we need to perform a full layout.
- layout_result = RunSimplifiedLayout(params);
+ layout_result = RunSimplifiedLayout(params, *layout_result);
#if DCHECK_IS_ON()
if (layout_result) {
layout_result->CheckSameForSimplifiedLayout(
- *box_->GetCachedLayoutResult(), /* check_same_block_size */ false);
+ *previous_result, /* check_same_block_size */ false);
}
#endif
+ } else {
+ layout_result = nullptr;
}
// Fragment geometry scrollbars are potentially size constrained, and cannot
// be used for comparison with their after layout size.
NGBoxStrut before_layout_scrollbars =
ComputeScrollbars(constraint_space, *this);
- bool before_layout_preferred_logical_widths_dirty =
- box_->PreferredLogicalWidthsDirty();
+ bool before_layout_intrinsic_logical_widths_dirty =
+ box_->IntrinsicLogicalWidthsDirty();
if (!layout_result)
layout_result = LayoutWithAlgorithm(params);
@@ -373,10 +440,15 @@ scoped_refptr<const NGLayoutResult> NGBlockNode::Layout(
// This mirrors legacy code in PaintLayerScrollableArea::UpdateAfterLayout.
if ((before_layout_scrollbars !=
ComputeScrollbars(constraint_space, *this)) ||
- (!before_layout_preferred_logical_widths_dirty &&
- box_->PreferredLogicalWidthsDirty())) {
+ (!before_layout_intrinsic_logical_widths_dirty &&
+ box_->IntrinsicLogicalWidthsDirty())) {
PaintLayerScrollableArea::FreezeScrollbarsScope freeze_scrollbars;
+ // We need to clear any previous results when scrollbars change. For
+ // example - we may have stored a "measure" layout result which will be
+ // incorrect if we try and reuse it.
+ box_->ClearLayoutResults();
+
#if DCHECK_IS_ON()
// Ensure turning on/off scrollbars only once at most, when we call
// |LayoutWithAlgorithm| recursively.
@@ -506,18 +578,32 @@ void NGBlockNode::PrepareForLayout() {
void NGBlockNode::FinishLayout(
LayoutBlockFlow* block_flow,
const NGConstraintSpace& constraint_space,
- const NGBreakToken* break_token,
+ const NGBlockBreakToken* break_token,
scoped_refptr<const NGLayoutResult> layout_result) {
// 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.
if (layout_result->Status() != NGLayoutResult::kSuccess) {
- box_->ClearCachedLayoutResult();
+ box_->ClearLayoutResults();
return;
}
- if (!constraint_space.HasBlockFragmentation())
- box_->SetCachedLayoutResult(*layout_result, break_token);
+ // Add all layout results (and fragments) generated from a node to a list in
+ // the layout object. Some extra care is required to correctly overwrite
+ // intermediate layout results: The sequence number of an incoming break token
+ // corresponds with the fragment index in the layout object (off by 1,
+ // though). When writing back a layout result, we remove any fragments in the
+ // layout box at higher indices than that of the one we're writing back.
+ const auto& physical_fragment =
+ To<NGPhysicalBoxFragment>(layout_result->PhysicalFragment());
+ wtf_size_t fragment_index = 0;
+ if (break_token && !break_token->IsBreakBefore())
+ fragment_index = break_token->SequenceNumber() + 1;
+
+ if (layout_result->IsSingleUse())
+ box_->AddLayoutResult(layout_result, fragment_index);
+ else
+ box_->SetCachedLayoutResult(layout_result);
if (block_flow) {
auto* child = GetLayoutObjectForFirstChildNode(block_flow);
@@ -543,40 +629,28 @@ void NGBlockNode::FinishLayout(
}
if (has_inline_children) {
- const auto& physical_fragment =
- To<NGPhysicalBoxFragment>(layout_result->PhysicalFragment());
if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
CopyFragmentDataToLayoutBoxForInlineChildren(
physical_fragment, physical_fragment.Size().width,
Style().IsFlippedBlocksWritingMode());
- block_flow->SetPaintFragment(To<NGBlockBreakToken>(break_token),
- &physical_fragment);
+ block_flow->SetPaintFragment(break_token, &physical_fragment);
} else {
CopyFragmentDataToLayoutBoxForInlineChildren(physical_fragment);
-
- // Floats are in the fragment tree, not in the item list, and the
- // painter relies on |LayoutBox.Location()|.
- if (physical_fragment.HasFloatingDescendantsForPaint()) {
- CopyFragmentDataToLayoutBoxForInlineChildren(
- physical_fragment, physical_fragment.Size().width,
- Style().IsFlippedBlocksWritingMode());
- }
}
} else {
// We still need to clear paint fragments in case it had inline children,
// and thus had NGPaintFragment.
block_flow->ClearNGInlineNodeData();
- block_flow->SetPaintFragment(To<NGBlockBreakToken>(break_token), nullptr);
+ block_flow->SetPaintFragment(break_token, nullptr);
}
}
- CopyFragmentDataToLayoutBox(constraint_space, *layout_result,
- To<NGBlockBreakToken>(break_token));
+ CopyFragmentDataToLayoutBox(constraint_space, *layout_result, break_token);
}
-MinMaxSize NGBlockNode::ComputeMinMaxSize(
+MinMaxSizes NGBlockNode::ComputeMinMaxSizes(
WritingMode container_writing_mode,
- const MinMaxSizeInput& input,
+ const MinMaxSizesInput& input,
const NGConstraintSpace* constraint_space) {
// TODO(layoutng) Can UpdateMarkerTextIfNeeded call be moved
// somewhere else? List items need up-to-date markers before layout.
@@ -586,13 +660,17 @@ MinMaxSize NGBlockNode::ComputeMinMaxSize(
bool is_orthogonal_flow_root =
!IsParallelWritingMode(container_writing_mode, Style().GetWritingMode());
- MinMaxSize sizes;
+ if (CanUseCachedIntrinsicInlineSizes(input, *box_))
+ return box_->IntrinsicLogicalWidths();
+
+ box_->SetIntrinsicLogicalWidthsDirty();
+
+ MinMaxSizes sizes;
// If we're orthogonal, we have to run layout to compute the sizes. However,
// if we're outside of layout, we can't do that. This can happen on Mac.
if ((!CanUseNewLayout() && !is_orthogonal_flow_root) ||
- (is_orthogonal_flow_root && !box_->GetFrameView()->IsInPerformLayout())) {
- return ComputeMinMaxSizeFromLegacy(input);
- }
+ (is_orthogonal_flow_root && !box_->GetFrameView()->IsInPerformLayout()))
+ return ComputeMinMaxSizesFromLegacy(input);
NGConstraintSpace zero_constraint_space =
CreateConstraintSpaceBuilderForMinMax(*this).ToConstraintSpace();
@@ -614,18 +692,12 @@ MinMaxSize NGBlockNode::ComputeMinMaxSize(
TextDirection::kLtr, // irrelevant here
To<NGPhysicalBoxFragment>(layout_result->PhysicalFragment()));
sizes.min_size = sizes.max_size = fragment.Size().inline_size;
- if (input.size_type == NGMinMaxSizeType::kContentBoxSize) {
- sizes -= fragment.Borders().InlineSum() + fragment.Padding().InlineSum() +
- box_->ScrollbarLogicalWidth();
- DCHECK_GE(sizes.min_size, LayoutUnit());
- DCHECK_GE(sizes.max_size, LayoutUnit());
- }
return sizes;
}
NGFragmentGeometry fragment_geometry =
CalculateInitialMinMaxFragmentGeometry(*constraint_space, *this);
- base::Optional<MinMaxSize> maybe_sizes = ComputeMinMaxSizeWithAlgorithm(
+ base::Optional<MinMaxSizes> maybe_sizes = ComputeMinMaxSizesWithAlgorithm(
NGLayoutAlgorithmParams(*this, fragment_geometry, *constraint_space),
input);
@@ -633,13 +705,21 @@ MinMaxSize NGBlockNode::ComputeMinMaxSize(
auto* html_marquee_element = DynamicTo<HTMLMarqueeElement>(box_->GetNode());
if (UNLIKELY(html_marquee_element && html_marquee_element->IsHorizontal()))
maybe_sizes->min_size = LayoutUnit();
+ else if (UNLIKELY(IsA<HTMLSelectElement>(box_->GetNode()) ||
+ (IsA<HTMLInputElement>(box_->GetNode()) &&
+ To<HTMLInputElement>(box_->GetNode())->type() ==
+ input_type_names::kFile)) &&
+ Style().LogicalWidth().IsPercentOrCalc())
+ maybe_sizes->min_size = LayoutUnit();
+ box_->SetIntrinsicLogicalWidthsFromNG(
+ *maybe_sizes, input.percentage_resolution_block_size);
return *maybe_sizes;
}
if (!box_->GetFrameView()->IsInPerformLayout()) {
// We can't synthesize these using Layout() if we're not in PerformLayout.
// This situation can happen on mac. Fall back to legacy instead.
- return ComputeMinMaxSizeFromLegacy(input);
+ return ComputeMinMaxSizesFromLegacy(input);
}
// Have to synthesize this value.
@@ -662,18 +742,11 @@ MinMaxSize NGBlockNode::ComputeMinMaxSize(
TextDirection::kLtr, // irrelevant here
To<NGPhysicalBoxFragment>(layout_result->PhysicalFragment()));
sizes.max_size = max_fragment.Size().inline_size;
-
- if (input.size_type == NGMinMaxSizeType::kContentBoxSize) {
- sizes -= max_fragment.Borders().InlineSum() +
- max_fragment.Padding().InlineSum() + box_->ScrollbarLogicalWidth();
- DCHECK_GE(sizes.min_size, LayoutUnit());
- DCHECK_GE(sizes.max_size, LayoutUnit());
- }
return sizes;
}
-MinMaxSize NGBlockNode::ComputeMinMaxSizeFromLegacy(
- const MinMaxSizeInput& input) const {
+MinMaxSizes NGBlockNode::ComputeMinMaxSizesFromLegacy(
+ const MinMaxSizesInput& input) const {
bool needs_size_reset = false;
if (!box_->HasOverrideContainingBlockContentLogicalHeight()) {
box_->SetOverrideContainingBlockContentLogicalHeight(
@@ -681,16 +754,13 @@ MinMaxSize NGBlockNode::ComputeMinMaxSizeFromLegacy(
needs_size_reset = true;
}
- MinMaxSize sizes;
- // ComputeIntrinsicLogicalWidths returns content-box + scrollbar.
- box_->ComputeIntrinsicLogicalWidths(sizes.min_size, sizes.max_size);
- if (input.size_type == NGMinMaxSizeType::kContentBoxSize) {
- sizes -= LayoutUnit(box_->ScrollbarLogicalWidth());
- DCHECK_GE(sizes.min_size, LayoutUnit());
- DCHECK_GE(sizes.max_size, LayoutUnit());
- } else {
- sizes += box_->BorderAndPaddingLogicalWidth();
- }
+ // Tables don't calculate their min/max content contribution the same way as
+ // other layout nodes. This is because width/min-width/etc have a different
+ // meaning for tables.
+ //
+ // Due to this the min/max content contribution is their min/max content size.
+ MinMaxSizes sizes = box_->IsTable() ? box_->PreferredLogicalWidths()
+ : box_->IntrinsicLogicalWidths();
if (needs_size_reset)
box_->ClearOverrideContainingBlockContentSize();
@@ -857,10 +927,9 @@ void NGBlockNode::CopyFragmentDataToLayoutBox(
LayoutBlock* block = DynamicTo<LayoutBlock>(box_);
bool needs_full_invalidation = false;
if (LIKELY(block && is_last_fragment)) {
- LayoutUnit intrinsic_block_size =
- layout_result.UnconstrainedIntrinsicBlockSize();
+ LayoutUnit overflow_block_size = layout_result.OverflowBlockSize();
if (UNLIKELY(previous_break_token))
- intrinsic_block_size += previous_break_token->ConsumedBlockSize();
+ overflow_block_size += previous_break_token->ConsumedBlockSize();
#if DCHECK_IS_ON()
block->CheckPositionedObjectsNeedLayout();
@@ -881,10 +950,9 @@ void NGBlockNode::CopyFragmentDataToLayoutBox(
// |ComputeOverflow()| below calls |AddVisualOverflowFromChildren()|, which
// computes visual overflow from |RootInlineBox| if |ChildrenInline()|
- // TODO(rego): This causes that ChildNeedsLayoutOverflowRecalc flags are not
- // cleared after layout (see https://crbug.com/941180).
- block->SetNeedsOverflowRecalc();
- block->ComputeLayoutOverflow(intrinsic_block_size - borders.block_end -
+ block->SetNeedsOverflowRecalc(
+ LayoutObject::OverflowRecalcType::kOnlyVisualOverflowRecalc);
+ block->ComputeLayoutOverflow(overflow_block_size - borders.block_end -
scrollbars.block_end);
}
@@ -915,7 +983,7 @@ void NGBlockNode::PlaceChildrenInLayoutBox(
for (const auto& child_fragment : physical_fragment.Children()) {
// Skip any line-boxes we have as children, this is handled within
// NGInlineNode at the moment.
- if (!child_fragment->IsBox() && !child_fragment->IsRenderedLegend())
+ if (!child_fragment->IsBox())
continue;
const auto& box_fragment = *To<NGPhysicalBoxFragment>(child_fragment.get());
@@ -940,7 +1008,7 @@ void NGBlockNode::PlaceChildrenInLayoutBox(
DCHECK(IsA<HTMLFieldSetElement>(content_wrapper->Parent()->GetNode()));
LayoutPoint location = rendered_legend->Location();
location -= content_wrapper->Location();
- rendered_legend->SetLocation(location);
+ rendered_legend->SetLocationAndUpdateOverflowControlsIfNeeded(location);
}
}
@@ -996,7 +1064,8 @@ void NGBlockNode::CopyChildFragmentPosition(
offset.left += consumed;
}
- layout_box->SetLocation(offset.ToLayoutPoint());
+ layout_box->SetLocationAndUpdateOverflowControlsIfNeeded(
+ offset.ToLayoutPoint());
}
// For inline children, NG painters handles fragments directly, but there are
@@ -1007,6 +1076,7 @@ void NGBlockNode::CopyFragmentDataToLayoutBoxForInlineChildren(
LayoutUnit initial_container_width,
bool initial_container_is_flipped,
PhysicalOffset offset) {
+ DCHECK(!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
for (const auto& child : container.Children()) {
if (child->IsContainer()) {
PhysicalOffset child_offset = offset + child.Offset();
@@ -1022,7 +1092,8 @@ void NGBlockNode::CopyFragmentDataToLayoutBoxForInlineChildren(
child->Size().width -
maybe_flipped_offset.left;
}
- layout_box.SetLocation(maybe_flipped_offset.ToLayoutPoint());
+ layout_box.SetLocationAndUpdateOverflowControlsIfNeeded(
+ maybe_flipped_offset.ToLayoutPoint());
}
// Legacy compatibility. This flag is used in paint layer for
@@ -1038,7 +1109,7 @@ void NGBlockNode::CopyFragmentDataToLayoutBoxForInlineChildren(
// LayoutBlockFlow. If |child| establishes a new block formatting context,
// it also creates another inline formatting context. Do not copy to its
// descendants in this case.
- if (!child->IsBlockFormattingContextRoot()) {
+ if (!child->IsFormattingContextRoot()) {
CopyFragmentDataToLayoutBoxForInlineChildren(
To<NGPhysicalContainerFragment>(*child), initial_container_width,
initial_container_is_flipped, child_offset);
@@ -1055,20 +1126,22 @@ void NGBlockNode::CopyFragmentDataToLayoutBoxForInlineChildren(
return;
bool initial_container_is_flipped = Style().IsFlippedBlocksWritingMode();
for (NGInlineCursor cursor(*items); cursor; cursor.MoveToNext()) {
- if (const NGPhysicalBoxFragment* child = cursor.CurrentBoxFragment()) {
+ if (const NGPhysicalBoxFragment* child = cursor.Current().BoxFragment()) {
// Replaced elements and inline blocks need Location() set relative to
// their block container.
LayoutObject* layout_object = child->GetMutableLayoutObject();
if (!layout_object)
continue;
if (LayoutBox* layout_box = ToLayoutBoxOrNull(layout_object)) {
- PhysicalOffset maybe_flipped_offset = cursor.CurrentOffset();
+ PhysicalOffset maybe_flipped_offset =
+ cursor.Current().OffsetInContainerBlock();
if (initial_container_is_flipped) {
maybe_flipped_offset.left = container.Size().width -
child->Size().width -
maybe_flipped_offset.left;
}
- layout_box->SetLocation(maybe_flipped_offset.ToLayoutPoint());
+ layout_box->SetLocationAndUpdateOverflowControlsIfNeeded(
+ maybe_flipped_offset.ToLayoutPoint());
continue;
}
@@ -1085,9 +1158,9 @@ void NGBlockNode::CopyFragmentDataToLayoutBoxForInlineChildren(
}
}
-bool NGBlockNode::ChildrenInline() const {
+bool NGBlockNode::IsInlineFormattingContextRoot() const {
if (const auto* block = DynamicTo<LayoutBlockFlow>(box_))
- return AreNGBlockFlowChildrenInline(block);
+ return AreNGBlockFlowChildrenInline(block) && FirstChild().IsInline();
return false;
}
@@ -1101,10 +1174,28 @@ bool NGBlockNode::IsAtomicInlineLevel() const {
return GetLayoutBox()->IsAtomicInlineLevel() && GetLayoutBox()->IsInline();
}
-bool NGBlockNode::MayHaveAspectRatio() const {
+bool NGBlockNode::HasAspectRatio() const {
LayoutBox* layout_object = GetLayoutBox();
- return layout_object->IsImage() || layout_object->IsVideo() ||
- layout_object->IsCanvas();
+ if (!layout_object->IsImage() && !IsA<LayoutVideo>(layout_object) &&
+ !layout_object->IsCanvas())
+ return false;
+
+ // Retrieving this and throwing it away is wasteful. We could make this method
+ // return Optional<LogicalSize> that returns the aspect_ratio if there is one.
+ return !GetAspectRatio().IsEmpty();
+}
+
+LogicalSize NGBlockNode::GetAspectRatio() const {
+ base::Optional<LayoutUnit> computed_inline_size;
+ base::Optional<LayoutUnit> computed_block_size;
+ GetOverrideIntrinsicSize(&computed_inline_size, &computed_block_size);
+ if (computed_inline_size && computed_block_size)
+ return LogicalSize(*computed_inline_size, *computed_block_size);
+
+ IntrinsicSizingInfo legacy_sizing_info;
+ ToLayoutReplaced(box_)->ComputeIntrinsicSizingInfo(legacy_sizing_info);
+ return LogicalSize(LayoutUnit(legacy_sizing_info.aspect_ratio.Width()),
+ LayoutUnit(legacy_sizing_info.aspect_ratio.Height()));
}
bool NGBlockNode::UseLogicalBottomMarginEdgeForInlineBlockBaseline() const {
@@ -1121,21 +1212,17 @@ bool NGBlockNode::IsCustomLayoutLoaded() const {
scoped_refptr<const NGLayoutResult> NGBlockNode::LayoutAtomicInline(
const NGConstraintSpace& parent_constraint_space,
const ComputedStyle& parent_style,
- FontBaseline baseline_type,
- bool use_first_line_style) {
+ bool use_first_line_style,
+ NGBaselineAlgorithmType baseline_algorithm_type) {
NGConstraintSpaceBuilder builder(
parent_constraint_space, Style().GetWritingMode(), /* is_new_fc */ true);
SetOrthogonalFallbackInlineSizeIfNeeded(parent_style, *this, &builder);
+ builder.SetIsPaintedAtomically(true);
builder.SetUseFirstLineStyle(use_first_line_style);
- // Request to compute baseline during the layout, except when we know the box
- // would synthesize box-baseline.
- LayoutBox* layout_box = GetLayoutBox();
- if (NGBaseline::ShouldPropagateBaselines(layout_box)) {
- builder.AddBaselineRequest(
- {NGBaselineAlgorithmType::kAtomicInline, baseline_type});
- }
+ builder.SetNeedsBaseline(true);
+ builder.SetBaselineAlgorithmType(baseline_algorithm_type);
builder.SetIsShrinkToFit(Style().LogicalWidth().IsAuto());
builder.SetAvailableSize(parent_constraint_space.AvailableSize());
@@ -1148,7 +1235,7 @@ scoped_refptr<const NGLayoutResult> NGBlockNode::LayoutAtomicInline(
scoped_refptr<const NGLayoutResult> result = Layout(constraint_space);
// TODO(kojii): Investigate why ClearNeedsLayout() isn't called automatically
// when it's being laid out.
- layout_box->ClearNeedsLayout();
+ GetLayoutBox()->ClearNeedsLayout();
return result;
}
@@ -1208,7 +1295,13 @@ scoped_refptr<const NGLayoutResult> NGBlockNode::RunLegacyLayout(
constraint_space.IsNewFormattingContext());
builder.SetInitialFragmentGeometry(fragment_geometry);
builder.SetIsLegacyLayoutRoot();
- builder.SetIntrinsicBlockSize(box_->IntrinsicContentLogicalHeight());
+ if (box_->ShouldComputeSizeAsReplaced()) {
+ builder.SetIntrinsicBlockSize(box_->LogicalHeight());
+ } else {
+ builder.SetIntrinsicBlockSize(box_->IntrinsicContentLogicalHeight() +
+ box_->BorderAndPaddingLogicalHeight() +
+ box_->ScrollbarLogicalHeight());
+ }
// If we're block-fragmented, we can only handle monolithic content, since
// the two block fragmentation machineries (NG and legacy) cannot cooperate.
@@ -1227,7 +1320,7 @@ scoped_refptr<const NGLayoutResult> NGBlockNode::RunLegacyLayout(
CopyBaselinesFromLegacyLayout(constraint_space, &builder);
layout_result = builder.ToBoxFragment();
- box_->SetCachedLayoutResult(*layout_result, /* break_token */ nullptr);
+ box_->SetCachedLayoutResult(layout_result);
// If |SetCachedLayoutResult| did not update cached |LayoutResult|,
// |NeedsLayout()| flag should not be cleared.
@@ -1254,7 +1347,7 @@ scoped_refptr<const NGLayoutResult> NGBlockNode::RunLegacyLayout(
*layout_result, constraint_space, layout_result->EndMarginStrut(),
layout_result->BfcLineOffset(), layout_result->BfcBlockOffset(),
LayoutUnit() /* block_offset_delta */));
- box_->SetCachedLayoutResult(*layout_result, /* break_token */ nullptr);
+ box_->SetCachedLayoutResult(layout_result);
}
}
@@ -1265,42 +1358,40 @@ scoped_refptr<const NGLayoutResult> NGBlockNode::RunLegacyLayout(
}
scoped_refptr<const NGLayoutResult> NGBlockNode::RunSimplifiedLayout(
- const NGLayoutAlgorithmParams& params) const {
- return NGSimplifiedLayoutAlgorithm(params, *box_->GetCachedLayoutResult())
- .Layout();
+ const NGLayoutAlgorithmParams& params,
+ const NGLayoutResult& result) const {
+ return NGSimplifiedLayoutAlgorithm(params, result).Layout();
}
void NGBlockNode::CopyBaselinesFromLegacyLayout(
const NGConstraintSpace& constraint_space,
NGBoxFragmentBuilder* builder) {
- const NGBaselineRequestList requests = constraint_space.BaselineRequests();
- if (requests.IsEmpty())
+ // 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
+ // LayoutNG we should be able to safely remove this flag without a
+ // performance penalty.
+ if (!constraint_space.NeedsBaseline())
return;
- if (UNLIKELY(constraint_space.GetWritingMode() != Style().GetWritingMode()))
- return;
-
- for (const auto& request : requests) {
- switch (request.AlgorithmType()) {
- case NGBaselineAlgorithmType::kAtomicInline: {
- LayoutUnit position =
- AtomicInlineBaselineFromLegacyLayout(request, constraint_space);
- if (position != -1)
- builder->AddBaseline(request, position);
- break;
- }
- case NGBaselineAlgorithmType::kFirstLine: {
- LayoutUnit position = box_->FirstLineBoxBaseline();
- if (position != -1)
- builder->AddBaseline(request, position);
- break;
- }
+ switch (constraint_space.BaselineAlgorithmType()) {
+ case NGBaselineAlgorithmType::kFirstLine: {
+ LayoutUnit position = box_->FirstLineBoxBaseline();
+ if (position != -1)
+ builder->SetBaseline(position);
+ break;
+ }
+ case NGBaselineAlgorithmType::kInlineBlock: {
+ LayoutUnit position =
+ AtomicInlineBaselineFromLegacyLayout(constraint_space);
+ if (position != -1)
+ builder->SetBaseline(position);
+ break;
}
}
}
LayoutUnit NGBlockNode::AtomicInlineBaselineFromLegacyLayout(
- const NGBaselineRequest& request,
const NGConstraintSpace& constraint_space) {
LineDirectionMode line_direction = box_->IsHorizontalWritingMode()
? LineDirectionMode::kHorizontalLine
@@ -1310,7 +1401,7 @@ LayoutUnit NGBlockNode::AtomicInlineBaselineFromLegacyLayout(
// classes override it assuming inline layout calls |BaselinePosition()|.
if (box_->IsInline()) {
LayoutUnit position = LayoutUnit(box_->BaselinePosition(
- request.BaselineType(), constraint_space.UseFirstLineStyle(),
+ box_->Style()->GetFontBaseline(), constraint_space.UseFirstLineStyle(),
line_direction, kPositionOnContainingLine));
// BaselinePosition() uses margin edge for atomic inlines. Subtract
@@ -1318,6 +1409,9 @@ LayoutUnit NGBlockNode::AtomicInlineBaselineFromLegacyLayout(
if (box_->IsAtomicInlineLevel())
position -= box_->MarginOver();
+ if (IsFlippedLinesWritingMode(constraint_space.GetWritingMode()))
+ return box_->Size().Width() - position;
+
return position;
}
@@ -1363,4 +1457,8 @@ void NGBlockNode::StoreMargins(const NGConstraintSpace& constraint_space,
box_->SetMargin(physical_margins);
}
+void NGBlockNode::StoreMargins(const NGPhysicalBoxStrut& physical_margins) {
+ box_->SetMargin(physical_margins);
+}
+
} // namespace blink
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 91b6986774a..7ccb575505f 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
@@ -14,16 +14,14 @@
namespace blink {
class LayoutBox;
-class NGBaselineRequest;
class NGBlockBreakToken;
class NGBoxFragmentBuilder;
-class NGBreakToken;
class NGConstraintSpace;
class NGEarlyBreak;
class NGLayoutResult;
class NGPhysicalBoxFragment;
class NGPhysicalContainerFragment;
-struct MinMaxSize;
+struct MinMaxSizes;
struct NGBoxStrut;
struct NGLayoutAlgorithmParams;
@@ -37,7 +35,7 @@ class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode {
scoped_refptr<const NGLayoutResult> Layout(
const NGConstraintSpace& constraint_space,
- const NGBreakToken* break_token = nullptr,
+ const NGBlockBreakToken* break_token = nullptr,
const NGEarlyBreak* = nullptr);
// This method is just for use within the |NGSimplifiedLayoutAlgorithm|.
@@ -66,7 +64,7 @@ class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode {
// Computes the value of min-content and max-content for this node's border
// box.
- // If the underlying layout algorithm's ComputeMinMaxSize returns
+ // If the underlying layout algorithm's ComputeMinMaxSizes returns
// no value, this function will synthesize these sizes using Layout with
// special constraint spaces -- infinite available size for max content, zero
// available size for min content, and percentage resolution size zero for
@@ -82,21 +80,29 @@ 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.
- MinMaxSize ComputeMinMaxSize(WritingMode container_writing_mode,
- const MinMaxSizeInput&,
- const NGConstraintSpace* = nullptr);
+ MinMaxSizes ComputeMinMaxSizes(WritingMode container_writing_mode,
+ const MinMaxSizesInput&,
+ const NGConstraintSpace* = nullptr);
- MinMaxSize ComputeMinMaxSizeFromLegacy(const MinMaxSizeInput&) const;
+ MinMaxSizes ComputeMinMaxSizesFromLegacy(const MinMaxSizesInput&) const;
NGLayoutInputNode FirstChild() const;
NGBlockNode GetRenderedLegend() const;
NGBlockNode GetFieldsetContent() const;
- bool ChildrenInline() const;
+ // Return true if this block node establishes an inline formatting context.
+ // This will only be the case if there is actual inline content. Empty nodes
+ // or nodes consisting purely of block-level, floats, and/or out-of-flow
+ // positioned children will return false.
+ bool IsInlineFormattingContextRoot() const;
+
bool IsInlineLevel() const;
bool IsAtomicInlineLevel() const;
- bool MayHaveAspectRatio() const;
+ bool HasAspectRatio() const;
+
+ // Returns the aspect ratio of a replaced element.
+ LogicalSize GetAspectRatio() const;
// Returns true if this node should fill the viewport.
// This occurs when we are in quirks-mode and we are *not* OOF-positioned,
@@ -127,8 +133,9 @@ class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode {
scoped_refptr<const NGLayoutResult> LayoutAtomicInline(
const NGConstraintSpace& parent_constraint_space,
const ComputedStyle& parent_style,
- FontBaseline,
- bool use_first_line_style);
+ bool use_first_line_style,
+ NGBaselineAlgorithmType baseline_algorithm_type =
+ NGBaselineAlgorithmType::kInlineBlock);
// Called if this is an out-of-flow block which needs to be
// positioned with legacy layout.
@@ -136,6 +143,7 @@ class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode {
// Write back resolved margins to legacy.
void StoreMargins(const NGConstraintSpace&, const NGBoxStrut& margins);
+ void StoreMargins(const NGPhysicalBoxStrut& margins);
static bool CanUseNewLayout(const LayoutBox&);
bool CanUseNewLayout() const;
@@ -150,13 +158,14 @@ class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode {
scoped_refptr<const NGLayoutResult> RunLegacyLayout(const NGConstraintSpace&);
scoped_refptr<const NGLayoutResult> RunSimplifiedLayout(
- const NGLayoutAlgorithmParams&) const;
+ const NGLayoutAlgorithmParams&,
+ const NGLayoutResult&) const;
// If this node is a LayoutNGMixin, the caller must pass the layout object for
// this node cast to a LayoutBlockFlow as the first argument.
void FinishLayout(LayoutBlockFlow*,
const NGConstraintSpace&,
- const NGBreakToken*,
+ const NGBlockBreakToken*,
scoped_refptr<const NGLayoutResult>);
// After we run the layout algorithm, this function copies back the geometry
@@ -183,8 +192,7 @@ class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode {
void CopyBaselinesFromLegacyLayout(const NGConstraintSpace&,
NGBoxFragmentBuilder*);
- LayoutUnit AtomicInlineBaselineFromLegacyLayout(const NGBaselineRequest&,
- const NGConstraintSpace&);
+ LayoutUnit AtomicInlineBaselineFromLegacyLayout(const NGConstraintSpace&);
void UpdateShapeOutsideInfoIfNeeded(
const NGLayoutResult&,
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 8190b808e58..f42f0ef6ff5 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
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
-#include "third_party/blink/renderer/core/layout/min_max_size.h"
+#include "third_party/blink/renderer/core/layout/min_max_sizes.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_test.h"
namespace blink {
@@ -174,9 +174,9 @@ TEST_F(NGBlockNodeForTest, MinAndMaxContent) {
const int kWidth = 30;
NGBlockNode box(ToLayoutBox(GetLayoutObjectByElementId("box")));
- MinMaxSize sizes = box.ComputeMinMaxSize(
+ MinMaxSizes sizes = box.ComputeMinMaxSizes(
WritingMode::kHorizontalTb,
- MinMaxSizeInput(/* percentage_resolution_block_size */ LayoutUnit()));
+ MinMaxSizesInput(/* percentage_resolution_block_size */ LayoutUnit()));
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.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_box_fragment.cc
index 20aef602f4e..f0b62aff415 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_box_fragment.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_box_fragment.cc
@@ -12,75 +12,46 @@
namespace blink {
-NGLineHeightMetrics NGBoxFragment::BaselineMetricsWithoutSynthesize(
- const NGBaselineRequest& request) const {
+NGLineHeightMetrics NGBoxFragment::BaselineMetrics(
+ const NGLineBoxStrut& margins,
+ FontBaseline baseline_type) const {
+ DCHECK(physical_fragment_.IsAtomicInline() ||
+ physical_fragment_.IsListMarker());
+ const ComputedStyle& style = physical_fragment_.Style();
+
// For "leaf" theme objects, let the theme decide what the baseline position
// is. The theme baseline wins over the propagated baselines.
- const auto& physical_fragment = To<NGPhysicalBoxFragment>(physical_fragment_);
- DCHECK(physical_fragment_.GetLayoutObject());
- const LayoutBox& layout_box =
- ToLayoutBox(*physical_fragment_.GetLayoutObject());
- const ComputedStyle& style = physical_fragment.Style();
if (style.HasEffectiveAppearance() &&
!LayoutTheme::GetTheme().IsControlContainer(
style.EffectiveAppearance())) {
return NGLineHeightMetrics(
- BlockSize() + layout_box.MarginOver() +
+ BlockSize() + margins.line_over +
LayoutTheme::GetTheme().BaselinePositionAdjustment(style),
- layout_box.MarginUnder());
+ margins.line_under);
}
- // Check if we have a propagated baseline.
- if (base::Optional<LayoutUnit> baseline =
- physical_fragment.Baseline(request)) {
- LayoutUnit ascent = *baseline;
- LayoutUnit descent = BlockSize() - ascent;
+ base::Optional<LayoutUnit> baseline = Baseline();
+ if (baseline) {
+ NGLineHeightMetrics metrics =
+ IsFlippedLinesWritingMode(GetWritingMode())
+ ? NGLineHeightMetrics(BlockSize() - *baseline, *baseline)
+ : NGLineHeightMetrics(*baseline, BlockSize() - *baseline);
- // For replaced elements, inline-block elements, and inline-table
- // elements, the height is the height of their margin box.
+ // For replaced elements, inline-block elements, and inline-table elements,
+ // the height is the height of their margin-box.
// https://drafts.csswg.org/css2/visudet.html#line-height
- if (layout_box.IsAtomicInlineLevel()) {
- ascent += layout_box.MarginOver();
- descent += layout_box.MarginUnder();
- }
+ metrics.ascent += margins.line_over;
+ metrics.descent += margins.line_under;
- return NGLineHeightMetrics(ascent, descent);
- }
-
- return NGLineHeightMetrics();
-}
-
-NGLineHeightMetrics NGBoxFragment::BaselineMetrics(
- const NGBaselineRequest& request,
- const NGConstraintSpace& constraint_space) const {
- // Try to compute the baseline if the writing-modes are the same.
- if (constraint_space.GetWritingMode() == GetWritingMode()) {
- NGLineHeightMetrics metrics = BaselineMetricsWithoutSynthesize(request);
- if (!metrics.IsEmpty())
- return metrics;
+ return metrics;
}
// The baseline type was not found. This is either this box should synthesize
// box-baseline without propagating from children, or caller forgot to add
// baseline requests to constraint space when it called Layout().
- LayoutUnit block_size = BlockSize();
-
- // If atomic inline, use the margin box. See above.
- const auto& physical_fragment = To<NGPhysicalBoxFragment>(physical_fragment_);
- DCHECK(physical_fragment_.GetLayoutObject());
- const LayoutBox& layout_box =
- ToLayoutBox(*physical_fragment_.GetLayoutObject());
- if (layout_box.IsAtomicInlineLevel()) {
- bool is_parallel_writing_mode =
- IsParallelWritingMode(constraint_space.GetWritingMode(),
- physical_fragment.Style().GetWritingMode());
- if (is_parallel_writing_mode)
- block_size += layout_box.MarginLogicalHeight();
- else
- block_size += layout_box.MarginLogicalWidth();
- }
+ LayoutUnit block_size = BlockSize() + margins.BlockSum();
- if (request.BaselineType() == kAlphabeticBaseline)
+ if (baseline_type == kAlphabeticBaseline)
return NGLineHeightMetrics(block_size, LayoutUnit());
return NGLineHeightMetrics(block_size - block_size / 2, block_size / 2);
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_box_fragment.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_box_fragment.h
index dbfd474e7c8..f31585b148d 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_box_fragment.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_box_fragment.h
@@ -14,7 +14,6 @@
namespace blink {
-class NGBaselineRequest;
struct NGLineHeightMetrics;
class CORE_EXPORT NGBoxFragment final : public NGFragment {
@@ -24,18 +23,34 @@ class CORE_EXPORT NGBoxFragment final : public NGFragment {
const NGPhysicalBoxFragment& physical_fragment)
: NGFragment(writing_mode, physical_fragment), direction_(direction) {}
+ base::Optional<LayoutUnit> FirstBaseline() const {
+ if (GetWritingMode() != physical_fragment_.Style().GetWritingMode())
+ return base::nullopt;
+
+ return To<NGPhysicalBoxFragment>(physical_fragment_).Baseline();
+ }
+
+ // Returns the baseline for this fragment wrt. the parent writing mode. Will
+ // return a null baseline if:
+ // - The fragment has no baseline.
+ // - The writing modes differ.
+ base::Optional<LayoutUnit> Baseline() const {
+ if (GetWritingMode() != physical_fragment_.Style().GetWritingMode())
+ return base::nullopt;
+
+ if (auto last_baseline =
+ To<NGPhysicalBoxFragment>(physical_fragment_).LastBaseline())
+ return last_baseline;
+
+ return To<NGPhysicalBoxFragment>(physical_fragment_).Baseline();
+ }
+
// Compute baseline metrics (ascent/descent) for this box.
//
- // Baseline requests must be added to constraint space when this fragment was
- // laid out.
- //
- // The "WithoutSynthesize" version returns an empty metrics if this box does
- // not have any baselines, while the other version synthesize the baseline
- // from the box.
- NGLineHeightMetrics BaselineMetricsWithoutSynthesize(
- const NGBaselineRequest&) const;
- NGLineHeightMetrics BaselineMetrics(const NGBaselineRequest&,
- const NGConstraintSpace&) const;
+ // This will synthesize baseline metrics if no baseline is available. See
+ // |Baseline()| for when this may occur.
+ NGLineHeightMetrics BaselineMetrics(const NGLineBoxStrut& margins,
+ FontBaseline) const;
NGBoxStrut Borders() const {
const NGPhysicalBoxFragment& physical_box_fragment =
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 990d5a59d6d..96c7f46d336 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
@@ -77,6 +77,70 @@ void GatherInlineContainerFragmentsFromLinebox(
}
}
+void GatherInlineContainerFragmentsFromItems(
+ const Vector<std::unique_ptr<NGFragmentItem>>& items,
+ const PhysicalOffset& box_offset,
+ NGBoxFragmentBuilder::InlineContainingBlockMap* inline_containing_block_map,
+ HashMap<const LayoutObject*, LineBoxPair>* containing_linebox_map) {
+ const NGPhysicalLineBoxFragment* linebox = nullptr;
+ for (const auto& item : items) {
+ // Track the current linebox.
+ if (const NGPhysicalLineBoxFragment* current_linebox =
+ item->LineBoxFragment()) {
+ linebox = current_linebox;
+ continue;
+ }
+
+ // We only care about inlines which have generated a box fragment.
+ const NGPhysicalBoxFragment* box = item->BoxFragment();
+ if (!box)
+ continue;
+
+ // The key for the inline is the continuation root if it exists.
+ const LayoutObject* key = box->GetLayoutObject();
+ if (key->IsLayoutInline() && key->GetNode())
+ key = key->ContinuationRoot();
+
+ // See if we need the containing block information for this inline.
+ auto it = inline_containing_block_map->find(key);
+ if (it == inline_containing_block_map->end())
+ continue;
+
+ base::Optional<NGBoxFragmentBuilder::InlineContainingBlockGeometry>&
+ containing_block_geometry = it->value;
+ LineBoxPair& containing_lineboxes =
+ containing_linebox_map->insert(key, LineBoxPair{nullptr, nullptr})
+ .stored_value->value;
+ DCHECK(containing_block_geometry.has_value() ||
+ !containing_lineboxes.first);
+
+ PhysicalRect fragment_rect = item->RectInContainerBlock();
+ fragment_rect.offset += box_offset;
+ if (containing_lineboxes.first == linebox) {
+ // Unite the start rect with the fragment's rect.
+ containing_block_geometry->start_fragment_union_rect.Unite(fragment_rect);
+ } else if (!containing_lineboxes.first) {
+ DCHECK(!containing_lineboxes.second);
+ // This is the first linebox we've encountered, initialize the containing
+ // block geometry.
+ containing_lineboxes.first = linebox;
+ containing_lineboxes.second = linebox;
+ containing_block_geometry =
+ NGBoxFragmentBuilder::InlineContainingBlockGeometry{fragment_rect,
+ fragment_rect};
+ }
+
+ if (containing_lineboxes.second == linebox) {
+ // Unite the end rect with the fragment's rect.
+ containing_block_geometry->end_fragment_union_rect.Unite(fragment_rect);
+ } else if (!linebox->IsEmptyLineBox()) {
+ // We've found a new "end" linebox, update the containing block geometry.
+ containing_lineboxes.second = linebox;
+ containing_block_geometry->end_fragment_union_rect = fragment_rect;
+ }
+ }
+}
+
} // namespace
void NGBoxFragmentBuilder::AddBreakBeforeChild(
@@ -121,8 +185,6 @@ void NGBoxFragmentBuilder::AddResult(const NGLayoutResult& child_layout_result,
items_builder_->AddLine(*line, offset);
// TODO(kojii): We probably don't need to AddChild this line, but there
// maybe OOF objects. Investigate how to handle them.
- } else {
- DCHECK(fragment.IsFloating());
}
}
AddChild(fragment, offset, inline_container);
@@ -156,6 +218,8 @@ NGPhysicalFragment::NGBoxType NGBoxFragmentBuilder::BoxType() const {
return NGPhysicalFragment::NGBoxType::kFloating;
if (layout_object_->IsOutOfFlowPositioned())
return NGPhysicalFragment::NGBoxType::kOutOfFlowPositioned;
+ if (layout_object_->IsRenderedLegend())
+ return NGPhysicalFragment::NGBoxType::kRenderedLegend;
if (layout_object_->IsInline()) {
// Check |IsAtomicInlineLevel()| after |IsInline()| because |LayoutReplaced|
// sets |IsAtomicInlineLevel()| even when it's block-level. crbug.com/567964
@@ -171,15 +235,6 @@ NGPhysicalFragment::NGBoxType NGBoxFragmentBuilder::BoxType() const {
return NGPhysicalFragment::NGBoxType::kNormalBox;
}
-void NGBoxFragmentBuilder::AddBaseline(NGBaselineRequest request,
- LayoutUnit offset) {
-#if DCHECK_IS_ON()
- for (const auto& baseline : baselines_)
- DCHECK(baseline.request != request);
-#endif
- baselines_.emplace_back(request, offset);
-}
-
EBreakBetween NGBoxFragmentBuilder::JoinedBreakBetweenValue(
EBreakBetween break_before) const {
return JoinFragmentainerBreakValues(previous_break_after_, break_before);
@@ -226,8 +281,8 @@ scoped_refptr<const NGLayoutResult> NGBoxFragmentBuilder::ToBoxFragment(
}
if (did_break_) {
break_token_ = NGBlockBreakToken::Create(
- node_, consumed_block_size_, child_break_tokens_, break_appeal_,
- has_seen_all_children_);
+ node_, consumed_block_size_, sequence_number_, child_break_tokens_,
+ break_appeal_, has_seen_all_children_);
}
}
@@ -240,18 +295,54 @@ scoped_refptr<const NGLayoutResult> NGBoxFragmentBuilder::ToBoxFragment(
NGPhysicalBoxFragment::Create(this, block_or_line_writing_mode);
fragment->CheckType();
- return base::AdoptRef(new NGLayoutResult(std::move(fragment), this));
+ return base::AdoptRef(
+ new NGLayoutResult(NGLayoutResult::NGBoxFragmentBuilderPassKey(),
+ std::move(fragment), this));
}
scoped_refptr<const NGLayoutResult> NGBoxFragmentBuilder::Abort(
NGLayoutResult::EStatus status) {
- return base::AdoptRef(new NGLayoutResult(status, this));
+ return base::AdoptRef(new NGLayoutResult(
+ NGLayoutResult::NGBoxFragmentBuilderPassKey(), status, this));
+}
+
+LogicalOffset NGBoxFragmentBuilder::GetChildOffset(
+ const LayoutObject* object) const {
+ DCHECK(object);
+
+ if (const NGFragmentItemsBuilder* items_builder = items_builder_) {
+ if (auto offset = items_builder->LogicalOffsetFor(*object))
+ return *offset;
+ NOTREACHED();
+ return LogicalOffset();
+ }
+
+ for (const auto& child : children_) {
+ if (child.fragment->GetLayoutObject() == object)
+ return child.offset;
+
+ // TODO(layout-dev): ikilpatrick thinks we may need to traverse
+ // further than the initial line-box children for a nested inline
+ // container. We could not come up with a testcase, it would be
+ // something with split inlines, and nested oof/fixed descendants maybe.
+ if (child.fragment->IsLineBox()) {
+ const auto& line_box_fragment =
+ To<NGPhysicalLineBoxFragment>(*child.fragment);
+ for (const auto& line_box_child : line_box_fragment.Children()) {
+ if (line_box_child->GetLayoutObject() == object) {
+ return child.offset + line_box_child.Offset().ConvertToLogical(
+ GetWritingMode(), Direction(),
+ line_box_fragment.Size(),
+ line_box_child->Size());
+ }
+ }
+ }
+ }
+ NOTREACHED();
+ return LogicalOffset();
}
-// Computes the geometry required for any inline containing blocks.
-// |inline_containing_block_map| is a map whose keys specify which inline
-// containing block geometry is required.
-void NGBoxFragmentBuilder::ComputeInlineContainerFragments(
+void NGBoxFragmentBuilder::ComputeInlineContainerGeometryFromFragmentTree(
InlineContainingBlockMap* inline_containing_block_map) {
if (inline_containing_block_map->IsEmpty())
return;
@@ -307,6 +398,59 @@ void NGBoxFragmentBuilder::ComputeInlineContainerFragments(
}
}
+void NGBoxFragmentBuilder::ComputeInlineContainerGeometry(
+ InlineContainingBlockMap* inline_containing_block_map) {
+ if (inline_containing_block_map->IsEmpty())
+ return;
+
+ // This function requires that we have the final size of the fragment set
+ // upon the builder.
+ DCHECK_GE(InlineSize(), LayoutUnit());
+ DCHECK_GE(BlockSize(), LayoutUnit());
+
+#if DCHECK_IS_ON()
+ // Make sure all entries are a continuation root.
+ for (const auto& entry : *inline_containing_block_map)
+ DCHECK_EQ(entry.key, entry.key->ContinuationRoot());
+#endif
+
+ HashMap<const LayoutObject*, LineBoxPair> containing_linebox_map;
+
+ if (items_builder_) {
+ // To access the items correctly we need to convert them to the physical
+ // coordinate space.
+ GatherInlineContainerFragmentsFromItems(
+ items_builder_->Items(GetWritingMode(), Direction(),
+ ToPhysicalSize(Size(), GetWritingMode())),
+ PhysicalOffset(), inline_containing_block_map, &containing_linebox_map);
+ return;
+ }
+
+ // If we have children which are anonymous block, we might contain split
+ // inlines, this can occur in the following example:
+ // <div>
+ // Some text <span style="position: relative;">text
+ // <div>block</div>
+ // text </span> text.
+ // </div>
+ for (const auto& child : children_) {
+ if (!child.fragment->IsAnonymousBlock())
+ continue;
+
+ const auto& child_fragment = To<NGPhysicalBoxFragment>(*child.fragment);
+ const auto* items = child_fragment.Items();
+ if (!items)
+ continue;
+
+ const PhysicalOffset child_offset = child.offset.ConvertToPhysical(
+ GetWritingMode(), Direction(), ToPhysicalSize(Size(), GetWritingMode()),
+ child_fragment.Size());
+ GatherInlineContainerFragmentsFromItems(items->Items(), child_offset,
+ inline_containing_block_map,
+ &containing_linebox_map);
+ }
+}
+
#if DCHECK_IS_ON()
void NGBoxFragmentBuilder::CheckNoBlockFragmentation() const {
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 0544b7aa751..288530aeceb 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
@@ -9,7 +9,6 @@
#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"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_fragment_geometry.h"
-#include "third_party/blink/renderer/core/layout/ng/inline/ng_baseline.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items_builder.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"
@@ -38,6 +37,7 @@ class CORE_EXPORT NGBoxFragmentBuilder final
writing_mode,
direction),
box_type_(NGPhysicalFragment::NGBoxType::kNormalBox),
+ is_inline_formatting_context_(node.IsInline()),
did_break_(false) {}
// Build a fragment for LayoutObject without NGLayoutInputNode. LayoutInline
@@ -52,6 +52,7 @@ class CORE_EXPORT NGBoxFragmentBuilder final
writing_mode,
direction),
box_type_(NGPhysicalFragment::NGBoxType::kNormalBox),
+ is_inline_formatting_context_(true),
did_break_(false) {
layout_object_ = layout_object;
}
@@ -68,9 +69,8 @@ class CORE_EXPORT NGBoxFragmentBuilder final
return *initial_fragment_geometry_;
}
- void SetUnconstrainedIntrinsicBlockSize(
- LayoutUnit unconstrained_intrinsic_block_size) {
- unconstrained_intrinsic_block_size_ = unconstrained_intrinsic_block_size;
+ void SetOverflowBlockSize(LayoutUnit overflow_block_size) {
+ overflow_block_size_ = overflow_block_size;
}
void SetIntrinsicBlockSize(LayoutUnit intrinsic_block_size) {
intrinsic_block_size_ = intrinsic_block_size;
@@ -121,6 +121,10 @@ class CORE_EXPORT NGBoxFragmentBuilder final
// building now.
void SetConsumedBlockSize(LayoutUnit size) { consumed_block_size_ = size; }
+ void SetSequenceNumber(unsigned sequence_number) {
+ sequence_number_ = sequence_number;
+ }
+
// Specify that we broke.
//
// This will result in a fragment which has an unfinished break token.
@@ -197,6 +201,10 @@ class CORE_EXPORT NGBoxFragmentBuilder final
void SetColumnSpanner(NGBlockNode spanner) { column_spanner_ = spanner; }
bool FoundColumnSpanner() const { return !!column_spanner_; }
+ void SetLinesUntilClamp(const base::Optional<int>& value) {
+ lines_until_clamp_ = value;
+ }
+
void SetEarlyBreak(scoped_refptr<const NGEarlyBreak> breakpoint,
NGBreakAppeal appeal) {
early_break_ = breakpoint;
@@ -240,6 +248,12 @@ class CORE_EXPORT NGBoxFragmentBuilder final
void SetIsFieldsetContainer() { is_fieldset_container_ = true; }
void SetIsLegacyLayoutRoot() { is_legacy_layout_root_ = true; }
+ void SetIsInlineFormattingContext(bool is_inline_formatting_context) {
+ is_inline_formatting_context_ = is_inline_formatting_context;
+ }
+
+ void SetIsMathMLFraction() { is_math_fraction_ = true; }
+
bool DidBreak() const { return did_break_; }
void SetBorderEdges(NGBorderEdges border_edges) {
@@ -254,15 +268,16 @@ class CORE_EXPORT NGBoxFragmentBuilder final
custom_layout_data_ = std::move(custom_layout_data);
}
- // Layout algorithms should call this function for each baseline request in
- // the constraint space.
- //
- // If a request should use a synthesized baseline from the box rectangle,
- // algorithms can omit the call.
- //
- // This function should be called at most once for a given algorithm/baseline
- // type pair.
- void AddBaseline(NGBaselineRequest, LayoutUnit);
+ // Sets the alignment baseline for this fragment.
+ void SetBaseline(LayoutUnit baseline) { baseline_ = baseline; }
+ base::Optional<LayoutUnit> Baseline() const { return baseline_; }
+
+ // Sets the last baseline for this fragment.
+ void SetLastBaseline(LayoutUnit baseline) {
+ DCHECK_EQ(space_->BaselineAlgorithmType(),
+ NGBaselineAlgorithmType::kInlineBlock);
+ last_baseline_ = baseline;
+ }
// The |NGFragmentItemsBuilder| for the inline formatting context of this box.
NGFragmentItemsBuilder* ItemsBuilder() { return items_builder_; }
@@ -270,8 +285,12 @@ class CORE_EXPORT NGBoxFragmentBuilder final
items_builder_ = builder;
}
- // Inline containing block geometry is defined by two rectangles defined
- // by fragments generated by LayoutInline.
+ // Returns offset for given child. DCHECK if child not found.
+ // Warning: Do not call unless necessary.
+ LogicalOffset GetChildOffset(const LayoutObject* child) const;
+
+ // Inline containing block geometry is defined by two rectangles, generated
+ // by fragments of the LayoutInline.
struct InlineContainingBlockGeometry {
DISALLOW_NEW();
// Union of fragments generated on the first line.
@@ -283,7 +302,13 @@ class CORE_EXPORT NGBoxFragmentBuilder final
using InlineContainingBlockMap =
HashMap<const LayoutObject*,
base::Optional<InlineContainingBlockGeometry>>;
- void ComputeInlineContainerFragments(
+
+ // Computes the geometry required for any inline containing blocks.
+ // |inline_containing_block_map| is a map whose keys specify which inline
+ // containing block geometry is required.
+ void ComputeInlineContainerGeometryFromFragmentTree(
+ InlineContainingBlockMap* inline_containing_block_map);
+ void ComputeInlineContainerGeometry(
InlineContainingBlockMap* inline_containing_block_map);
#if DCHECK_IS_ON()
@@ -304,7 +329,7 @@ class CORE_EXPORT NGBoxFragmentBuilder final
scoped_refptr<const NGLayoutResult> ToBoxFragment(WritingMode);
const NGFragmentGeometry* initial_fragment_geometry_ = nullptr;
- LayoutUnit unconstrained_intrinsic_block_size_ = kIndefiniteSize;
+ LayoutUnit overflow_block_size_ = kIndefiniteSize;
LayoutUnit intrinsic_block_size_;
NGFragmentItemsBuilder* items_builder_ = nullptr;
@@ -314,12 +339,15 @@ class CORE_EXPORT NGBoxFragmentBuilder final
NGPhysicalFragment::NGBoxType box_type_;
bool is_fieldset_container_ = false;
bool is_initial_block_size_indefinite_ = false;
+ bool is_inline_formatting_context_;
bool did_break_;
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;
LayoutUnit consumed_block_size_;
+ unsigned sequence_number_ = 0;
LayoutUnit minimal_space_shortage_ = LayoutUnit::Max();
LayoutUnit tallest_unbreakable_block_size_ = LayoutUnit::Min();
@@ -331,11 +359,12 @@ class CORE_EXPORT NGBoxFragmentBuilder final
// The break-after value of the previous in-flow sibling.
EBreakBetween previous_break_after_ = EBreakBetween::kAuto;
- NGBaselineList baselines_;
-
+ base::Optional<LayoutUnit> baseline_;
+ base::Optional<LayoutUnit> last_baseline_;
NGBorderEdges border_edges_;
scoped_refptr<SerializedScriptValue> custom_layout_data_;
+ base::Optional<int> lines_until_clamp_;
friend class NGPhysicalBoxFragment;
friend class NGLayoutResult;
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 e61e4d42998..f1034c33a1c 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
@@ -8,7 +8,6 @@
#include "third_party/blink/renderer/core/layout/geometry/logical_size.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_fragment_geometry.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_margin_strut.h"
-#include "third_party/blink/renderer/core/layout/ng/inline/ng_baseline.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h"
#include "third_party/blink/renderer/core/layout/ng/ng_box_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h"
@@ -138,10 +137,16 @@ scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::Layout() {
intrinsic_block_size_ = border_scrollbar_padding_.block_start;
- if (!LayoutChildren()) {
+ NGBreakStatus break_status = LayoutChildren();
+ if (break_status == NGBreakStatus::kNeedsEarlierBreak) {
// We need to discard this layout and do it again. We found an earlier break
// point that's more appealing than the one we ran out of space at.
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());
+
+ return container_builder_.Abort(NGLayoutResult::kOutOfFragmentainerSpace);
}
// Figure out how much space we've already been able to process in previous
@@ -166,10 +171,9 @@ scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::Layout() {
if (is_constrained_by_outer_fragmentation_context_) {
// In addition to establishing one, we're nested inside another
// fragmentation context.
- FinishFragmentation(ConstraintSpace(), block_size, intrinsic_block_size_,
- previously_consumed_block_size,
- FragmentainerSpaceAtBfcStart(ConstraintSpace()),
- &container_builder_);
+ FinishFragmentation(
+ ConstraintSpace(), BreakToken(), block_size, intrinsic_block_size_,
+ FragmentainerSpaceAtBfcStart(ConstraintSpace()), &container_builder_);
} else {
container_builder_.SetBlockSize(block_size);
container_builder_.SetIntrinsicBlockSize(intrinsic_block_size_);
@@ -184,19 +188,17 @@ scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::Layout() {
return container_builder_.ToBoxFragment();
}
-base::Optional<MinMaxSize> NGColumnLayoutAlgorithm::ComputeMinMaxSize(
- const MinMaxSizeInput& input) const {
+base::Optional<MinMaxSizes> NGColumnLayoutAlgorithm::ComputeMinMaxSizes(
+ const MinMaxSizesInput& input) const {
// First calculate the min/max sizes of columns.
NGConstraintSpace space = CreateConstraintSpaceForMinMax();
NGFragmentGeometry fragment_geometry =
CalculateInitialMinMaxFragmentGeometry(space, Node());
NGBlockLayoutAlgorithm algorithm({Node(), fragment_geometry, space});
- MinMaxSizeInput child_input(input);
- child_input.size_type = NGMinMaxSizeType::kContentBoxSize;
- base::Optional<MinMaxSize> min_max_sizes =
- algorithm.ComputeMinMaxSize(child_input);
+ base::Optional<MinMaxSizes> min_max_sizes =
+ algorithm.ComputeMinMaxSizes(input);
DCHECK(min_max_sizes.has_value());
- MinMaxSize sizes = *min_max_sizes;
+ MinMaxSizes sizes = *min_max_sizes;
// If column-width is non-auto, pick the larger of that and intrinsic column
// width.
@@ -217,14 +219,11 @@ base::Optional<MinMaxSize> NGColumnLayoutAlgorithm::ComputeMinMaxSize(
// TODO(mstensho): Need to include spanners.
- if (input.size_type == NGMinMaxSizeType::kBorderBoxSize) {
- sizes += border_scrollbar_padding_.InlineSum();
- }
-
+ sizes += border_scrollbar_padding_.InlineSum();
return sizes;
}
-bool NGColumnLayoutAlgorithm::LayoutChildren() {
+NGBreakStatus NGColumnLayoutAlgorithm::LayoutChildren() {
NGMarginStrut margin_strut;
// First extract incoming child break tokens.
@@ -281,7 +280,7 @@ bool NGColumnLayoutAlgorithm::LayoutChildren() {
PushSpannerBreakTokens(std::move(spanner_break_token),
std::move(next_column_token),
&container_builder_);
- return true;
+ return NGBreakStatus::kContinue;
}
} else {
// Breaking before the first element in the fragmentainer isn't allowed,
@@ -291,7 +290,7 @@ bool NGColumnLayoutAlgorithm::LayoutChildren() {
}
if (BreakToken() && BreakToken()->HasSeenAllChildren() && !next_column_token)
- return true;
+ return NGBreakStatus::kContinue;
// Entering the child main loop. Here we'll alternate between laying out
// column content and column spanners, until we're either done, or until
@@ -301,6 +300,26 @@ bool NGColumnLayoutAlgorithm::LayoutChildren() {
do {
scoped_refptr<const NGLayoutResult> result =
LayoutRow(next_column_token.get(), &margin_strut);
+
+ if (!result) {
+ // Not enough outer fragmentainer space to produce any columns at all.
+ container_builder_.SetDidBreak();
+ 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
+ // need to break inside the multicol container. Stop walking the
+ // children, but "continue" layout, so that we produce a fragment. Note
+ // that we normally don't want to break right after initial
+ // border/padding, but will do so as a last resort. It's up to our
+ // containing block to decide what's best.
+ FinishAfterBreakBeforeRow(std::move(next_column_token));
+ return NGBreakStatus::kContinue;
+ }
+ // Otherwise we have nothing here, and need to break before the multicol
+ // container. No fragment will be produced.
+ return NGBreakStatus::kBrokeBefore;
+ }
+
next_column_token =
To<NGBlockBreakToken>(result->PhysicalFragment().BreakToken());
@@ -320,7 +339,7 @@ bool NGColumnLayoutAlgorithm::LayoutChildren() {
container_builder_.AddBreakBeforeChild(
spanner_node, kBreakAppealPerfect, /* is_forced_break */ false);
FinishAfterBreakBeforeSpanner(std::move(next_column_token));
- return true;
+ return NGBreakStatus::kContinue;
}
}
@@ -328,18 +347,18 @@ bool NGColumnLayoutAlgorithm::LayoutChildren() {
NGBreakStatus break_status = LayoutSpanner(
spanner_node, nullptr, &margin_strut, &spanner_break_token);
if (break_status == NGBreakStatus::kNeedsEarlierBreak) {
- return false;
+ return break_status;
} else if (break_status == NGBreakStatus::kBrokeBefore) {
DCHECK(ConstraintSpace().HasBlockFragmentation());
FinishAfterBreakBeforeSpanner(std::move(next_column_token));
- return true;
+ return NGBreakStatus::kContinue;
} else if (spanner_break_token) {
DCHECK_EQ(break_status, NGBreakStatus::kContinue);
// We broke inside the spanner. This may happen if we're nested inside
// another fragmentation context.
PushSpannerBreakTokens(std::move(spanner_break_token),
std::move(next_column_token), &container_builder_);
- return true;
+ return NGBreakStatus::kContinue;
}
} while (next_column_token);
@@ -362,7 +381,7 @@ bool NGColumnLayoutAlgorithm::LayoutChildren() {
intrinsic_block_size_ += margin_strut.Sum();
}
- return true;
+ return NGBreakStatus::kContinue;
}
scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::LayoutRow(
@@ -401,13 +420,23 @@ scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::LayoutRow(
LayoutUnit column_block_offset = intrinsic_block_size_ + margin_strut->Sum();
bool needs_more_fragments_in_outer = false;
+ bool zero_outer_space_left = false;
if (is_constrained_by_outer_fragmentation_context_) {
LayoutUnit available_outer_space =
FragmentainerSpaceAtBfcStart(ConstraintSpace()) - column_block_offset;
- // TODO(mstensho): This should never be negative, or even zero. Turn into a
- // DCHECK when the underlying problem is fixed.
- available_outer_space = available_outer_space.ClampNegativeToZero();
+ if (available_outer_space <= LayoutUnit()) {
+ if (available_outer_space < LayoutUnit()) {
+ // We're past the end of the outer fragmentainer (typically due to a
+ // margin). Nothing will fit here, not even zero-size content.
+ return nullptr;
+ }
+
+ // We are out of space, but we're exactly at the end of the outer
+ // fragmentainer. If none of our contents take up space, we're going to
+ // fit, otherwise not. Lay out and find out.
+ zero_outer_space_left = true;
+ }
// Check if we can fit everything (that's remaining), block-wise, within the
// current outer fragmentainer. If we can't, we need to adjust the block
@@ -498,6 +527,11 @@ scoped_refptr<const NGLayoutResult> NGColumnLayoutAlgorithm::LayoutRow(
if (ConstraintSpace().HasBlockFragmentation() && column_break_token &&
actual_column_count >= used_column_count_ &&
needs_more_fragments_in_outer) {
+ // We cannot keep any of this if we have zero space left. Then we need
+ // to resume in the next outer fragmentainer.
+ if (zero_outer_space_left)
+ return nullptr;
+
container_builder_.SetDidBreak();
container_builder_.SetBreakAppeal(kBreakAppealPerfect);
break;
@@ -626,7 +660,8 @@ NGBreakStatus NGColumnLayoutAlgorithm::LayoutSpanner(
margin_strut->Append(margins.block_start, /* is_quirky */ false);
LayoutUnit block_offset = intrinsic_block_size_ + margin_strut->Sum();
- auto spanner_space = CreateConstraintSpaceForSpanner(block_offset);
+ auto spanner_space =
+ CreateConstraintSpaceForSpanner(spanner_node, block_offset);
const NGEarlyBreak* early_break_in_child = nullptr;
if (early_break_ && early_break_->Type() == NGEarlyBreak::kBlock &&
@@ -764,6 +799,10 @@ LayoutUnit NGColumnLayoutAlgorithm::CalculateBalancedColumnBlockSize(
NGBlockLayoutAlgorithm balancing_algorithm(
{Node(), fragment_geometry, space, break_token.get()});
scoped_refptr<const NGLayoutResult> result = balancing_algorithm.Layout();
+
+ // This algorithm should never abort.
+ DCHECK_EQ(result->Status(), NGLayoutResult::kSuccess);
+
const NGPhysicalBoxFragment& fragment =
To<NGPhysicalBoxFragment>(result->PhysicalFragment());
LayoutUnit column_block_size = CalculateColumnContentBlockSize(
@@ -841,7 +880,7 @@ LayoutUnit NGColumnLayoutAlgorithm::ConstrainColumnBlockSize(
const ComputedStyle& style = Style();
LayoutUnit max = ResolveMaxBlockLength(
- ConstraintSpace(), style, border_padding_, style.LogicalMaxHeight(), size,
+ ConstraintSpace(), style, border_padding_, style.LogicalMaxHeight(),
LengthResolvePhase::kLayout);
LayoutUnit extent = ResolveMainBlockLength(
ConstraintSpace(), style, border_padding_, style.LogicalHeight(), size,
@@ -856,6 +895,20 @@ LayoutUnit NGColumnLayoutAlgorithm::ConstrainColumnBlockSize(
return size - extra;
}
+void NGColumnLayoutAlgorithm::FinishAfterBreakBeforeRow(
+ scoped_refptr<const NGBlockBreakToken> next_column_token) {
+ // We broke before a row for columns. We're done here. Take up the remaining
+ // space in the outer fragmentation context.
+ intrinsic_block_size_ = FragmentainerSpaceAtBfcStart(ConstraintSpace());
+
+ // If we were about to resume column layout after a spanner, add a break token
+ // for this, so that we resume there in the next outer fragmentainer. If
+ // there's no such break token, it means that we're at the start of the
+ // multicol container.
+ if (next_column_token)
+ container_builder_.AddBreakToken(std::move(next_column_token));
+}
+
void NGColumnLayoutAlgorithm::FinishAfterBreakBeforeSpanner(
scoped_refptr<const NGBlockBreakToken> next_column_token) {
// We broke before the spanner. We're done here. Take up the remaining space
@@ -898,9 +951,6 @@ NGConstraintSpace NGColumnLayoutAlgorithm::CreateConstraintSpaceForColumns(
space_builder.SetAvailableSize(column_size);
space_builder.SetPercentageResolutionSize(column_size);
- if (NGBaseline::ShouldPropagateBaselines(Node()))
- space_builder.AddBaselineRequests(ConstraintSpace().BaselineRequests());
-
// To ensure progression, we need something larger than 0 here. The spec
// actually says that fragmentainers have to accept at least 1px of content.
// See https://www.w3.org/TR/css-break-3/#breaking-rules
@@ -939,6 +989,7 @@ NGConstraintSpace NGColumnLayoutAlgorithm::CreateConstraintSpaceForBalancing(
}
NGConstraintSpace NGColumnLayoutAlgorithm::CreateConstraintSpaceForSpanner(
+ const NGBlockNode& spanner,
LayoutUnit block_offset) const {
NGConstraintSpaceBuilder space_builder(
ConstraintSpace(), Style().GetWritingMode(), /* is_new_fc */ true);
@@ -946,7 +997,7 @@ NGConstraintSpace NGColumnLayoutAlgorithm::CreateConstraintSpaceForSpanner(
space_builder.SetPercentageResolutionSize(content_box_size_);
if (ConstraintSpace().HasBlockFragmentation()) {
- SetupFragmentation(ConstraintSpace(), block_offset, &space_builder,
+ SetupFragmentation(ConstraintSpace(), spanner, block_offset, &space_builder,
/* is_new_fc */ true);
}
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 b9108019680..c516f1bafaa 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
@@ -26,17 +26,21 @@ class CORE_EXPORT NGColumnLayoutAlgorithm
scoped_refptr<const NGLayoutResult> Layout() override;
- base::Optional<MinMaxSize> ComputeMinMaxSize(
- const MinMaxSizeInput&) const override;
+ base::Optional<MinMaxSizes> ComputeMinMaxSizes(
+ const MinMaxSizesInput&) const override;
private:
- // Lay out as many children as we can. If false is returned, it means that we
- // ran out of space at an unappealing location, and need to relayout and break
- // earlier (because we have a better breakpoint there).
- bool LayoutChildren();
+ // Lay out as many children as we can. If |kNeedsEarlierBreak| is returned, it
+ // means that we ran out of space at an unappealing location, and need to
+ // relayout and break earlier (because we have a better breakpoint there). If
+ // |kBrokeBefore| is returned, it means that we need to break before the
+ // multicol container, and retry in the next fragmentainer.
+ NGBreakStatus LayoutChildren();
// Lay out one row of columns. The layout result returned is for the last
- // column that was laid out. The rows themselves don't create fragments.
+ // column that was laid out. The rows themselves don't create fragments. If
+ // we're in a nested fragmentation context and completely out of outer
+ // fragmentainer space, nullptr will be returned.
scoped_refptr<const NGLayoutResult> LayoutRow(
const NGBlockBreakToken* next_column_token,
NGMarginStrut*);
@@ -66,6 +70,10 @@ class CORE_EXPORT NGColumnLayoutAlgorithm
return intrinsic_block_size_ - border_scrollbar_padding_.block_start;
}
+ // Finalize layout after breaking before column contents.
+ void FinishAfterBreakBeforeRow(
+ scoped_refptr<const NGBlockBreakToken> next_column_token);
+
// Finalize layout after breaking before a spanner.
void FinishAfterBreakBeforeSpanner(
scoped_refptr<const NGBlockBreakToken> next_column_token);
@@ -83,6 +91,7 @@ class CORE_EXPORT NGColumnLayoutAlgorithm
NGConstraintSpace CreateConstraintSpaceForBalancing(
const LogicalSize& column_size) const;
NGConstraintSpace CreateConstraintSpaceForSpanner(
+ const NGBlockNode& spanner,
LayoutUnit block_offset) const;
NGConstraintSpace CreateConstraintSpaceForMinMax() const;
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 276c9823f0b..b2d3a0825ec 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
@@ -787,7 +787,6 @@ TEST_F(NGColumnLayoutAlgorithmTest, FloatWithLastResortBreak) {
offset:110,0 size:100x100
offset:0,0 size:88x20
offset:0,0 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -1434,14 +1433,10 @@ TEST_F(NGColumnLayoutAlgorithmTest, LinesInMulticolExtraSpace) {
offset:0,0 size:320x50
offset:0,0 size:100x50
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x50
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -1476,14 +1471,10 @@ TEST_F(NGColumnLayoutAlgorithmTest, LinesInMulticolExactFit) {
offset:0,0 size:320x40
offset:0,0 size:100x40
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x40
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -1521,15 +1512,11 @@ TEST_F(NGColumnLayoutAlgorithmTest, LinesInMulticolChildExtraSpace) {
offset:0,0 size:100x50
offset:0,0 size:77x50
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x50
offset:0,0 size:77x40
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -1567,15 +1554,11 @@ TEST_F(NGColumnLayoutAlgorithmTest, LinesInMulticolChildExactFit) {
offset:0,0 size:100x40
offset:0,0 size:77x40
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x40
offset:0,0 size:77x40
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -1615,13 +1598,10 @@ TEST_F(NGColumnLayoutAlgorithmTest, LinesInMulticolChildNoSpaceForFirst) {
offset:110,0 size:100x50
offset:0,0 size:77x50
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:220,0 size:100x50
offset:0,0 size:77x20
offset:0,0 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -1662,13 +1642,10 @@ TEST_F(NGColumnLayoutAlgorithmTest,
offset:110,0 size:100x50
offset:0,0 size:77x50
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:220,0 size:100x50
offset:0,0 size:77x20
offset:0,0 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -1713,7 +1690,6 @@ TEST_F(NGColumnLayoutAlgorithmTest, LineAtColumnBoundaryInFirstBlock) {
offset:110,0 size:100x50
offset:0,0 size:66x20
offset:0,0 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -1752,20 +1728,15 @@ TEST_F(NGColumnLayoutAlgorithmTest, DISABLED_LinesAndFloatsMulticol) {
offset:0,0 size:320x70
offset:0,0 size:100x70
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:10x50
offset:10,20 size:0x20
- offset:0,9 size:0x1
offset:10,40 size:11x30
offset:21,40 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x70
offset:0,0 size:10x70
offset:10,0 size:11x70
offset:21,0 size:0x20
- offset:0,9 size:0x1
offset:21,20 size:0x20
- offset:0,9 size:0x1
offset:220,0 size:100x70
offset:0,0 size:11x20
)DUMP";
@@ -1805,18 +1776,13 @@ TEST_F(NGColumnLayoutAlgorithmTest, DISABLED_FloatBelowLastLineInColumn) {
offset:0,0 size:320x70
offset:0,0 size:100x70
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:0x20
- offset:0,9 size:0x1
offset:0,60 size:11x10
offset:110,0 size:100x70
offset:0,0 size:11x70
offset:11,0 size:0x20
- offset:0,9 size:0x1
offset:11,20 size:0x20
- offset:0,9 size:0x1
offset:220,0 size:100x70
offset:0,0 size:11x40
)DUMP";
@@ -1858,11 +1824,8 @@ TEST_F(NGColumnLayoutAlgorithmTest, Orphans) {
offset:110,0 size:100x90
offset:0,0 size:77x60
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -1899,18 +1862,12 @@ TEST_F(NGColumnLayoutAlgorithmTest, OrphansUnsatisfiable) {
offset:0,0 size:320x90
offset:0,0 size:100x90
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:0x20
- offset:0,9 size:0x1
offset:0,60 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x90
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -1948,20 +1905,13 @@ TEST_F(NGColumnLayoutAlgorithmTest, Widows) {
offset:0,0 size:320x110
offset:0,0 size:100x110
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:0x20
- offset:0,9 size:0x1
offset:0,60 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x110
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -2006,37 +1956,23 @@ TEST_F(NGColumnLayoutAlgorithmTest, WidowsUnsatisfiable) {
offset:0,0 size:320x90
offset:0,0 size:100x90
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x90
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:0x20
- offset:0,9 size:0x1
offset:0,60 size:0x20
- offset:0,9 size:0x1
offset:220,0 size:100x90
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:0x20
- offset:0,9 size:0x1
offset:0,60 size:0x20
- offset:0,9 size:0x1
offset:330,0 size:100x90
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:0x20
- offset:0,9 size:0x1
offset:0,60 size:0x20
- offset:0,9 size:0x1
offset:440,0 size:100x90
offset:0,0 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -2071,14 +2007,10 @@ TEST_F(NGColumnLayoutAlgorithmTest, OrphansAndUnsatisfiableWidows) {
offset:0,0 size:320x70
offset:0,0 size:100x70
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x70
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -2113,14 +2045,10 @@ TEST_F(NGColumnLayoutAlgorithmTest, UnsatisfiableOrphansAndWidows) {
offset:0,0 size:320x70
offset:0,0 size:100x70
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x70
offset:0,0 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -2160,17 +2088,12 @@ TEST_F(NGColumnLayoutAlgorithmTest, WidowsAndAbspos) {
offset:0,0 size:100x70
offset:0,0 size:100x70
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x70
offset:0,0 size:100x60
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:33x33
)DUMP";
EXPECT_EQ(expectation, dump);
@@ -2214,15 +2137,11 @@ TEST_F(NGColumnLayoutAlgorithmTest, BreakBetweenLinesNotBefore) {
offset:0,0 size:44x60
offset:0,60 size:55x40
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x100
offset:0,0 size:55x40
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -2262,11 +2181,9 @@ TEST_F(NGColumnLayoutAlgorithmTest, BreakBetweenLinesNotBefore2) {
offset:0,0 size:44x80
offset:0,80 size:55x20
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x100
offset:0,0 size:55x20
offset:0,0 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -2306,11 +2223,9 @@ TEST_F(NGColumnLayoutAlgorithmTest, BreakBetweenLinesNotBefore3) {
offset:0,0 size:44x80
offset:0,80 size:55x20
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x100
offset:0,0 size:55x20
offset:0,0 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -2351,10 +2266,8 @@ TEST_F(NGColumnLayoutAlgorithmTest, DISABLED_FloatInBlockMovedByOrphans) {
offset:110,0 size:100x70
offset:0,0 size:77x40
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:10x10
offset:10,20 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -2392,17 +2305,12 @@ TEST_F(NGColumnLayoutAlgorithmTest, DISABLED_FloatMovedWithWidows) {
offset:0,0 size:320x90
offset:0,0 size:100x90
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x90
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:10x10
offset:10,40 size:0x20
- offset:0,9 size:0x1
offset:0,60 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -2809,32 +2717,32 @@ TEST_F(NGColumnLayoutAlgorithmTest, MinMax) {
NGFragmentGeometry fragment_geometry =
CalculateInitialFragmentGeometry(space, node);
NGColumnLayoutAlgorithm algorithm({node, fragment_geometry, space});
- base::Optional<MinMaxSize> size;
- MinMaxSizeInput zero_input(
+ base::Optional<MinMaxSizes> sizes;
+ MinMaxSizesInput zero_input(
/* percentage_resolution_block_size */ (LayoutUnit()));
// Both column-count and column-width set.
style->SetColumnCount(3);
style->SetColumnWidth(80);
- size = algorithm.ComputeMinMaxSize(zero_input);
- ASSERT_TRUE(size.has_value());
- EXPECT_EQ(LayoutUnit(260), size->min_size);
- EXPECT_EQ(LayoutUnit(320), size->max_size);
+ sizes = algorithm.ComputeMinMaxSizes(zero_input);
+ ASSERT_TRUE(sizes.has_value());
+ EXPECT_EQ(LayoutUnit(260), sizes->min_size);
+ EXPECT_EQ(LayoutUnit(320), sizes->max_size);
// Only column-count set.
style->SetHasAutoColumnWidth();
- size = algorithm.ComputeMinMaxSize(zero_input);
- ASSERT_TRUE(size.has_value());
- EXPECT_EQ(LayoutUnit(170), size->min_size);
- EXPECT_EQ(LayoutUnit(320), size->max_size);
+ sizes = algorithm.ComputeMinMaxSizes(zero_input);
+ ASSERT_TRUE(sizes.has_value());
+ EXPECT_EQ(LayoutUnit(170), sizes->min_size);
+ EXPECT_EQ(LayoutUnit(320), sizes->max_size);
// Only column-width set.
style->SetColumnWidth(80);
style->SetHasAutoColumnCount();
- size = algorithm.ComputeMinMaxSize(zero_input);
- ASSERT_TRUE(size.has_value());
- EXPECT_EQ(LayoutUnit(80), size->min_size);
- EXPECT_EQ(LayoutUnit(100), size->max_size);
+ sizes = algorithm.ComputeMinMaxSizes(zero_input);
+ ASSERT_TRUE(sizes.has_value());
+ EXPECT_EQ(LayoutUnit(80), sizes->min_size);
+ EXPECT_EQ(LayoutUnit(100), sizes->max_size);
}
TEST_F(NGColumnLayoutAlgorithmTest, ColumnBalancing) {
@@ -3196,7 +3104,6 @@ TEST_F(NGColumnLayoutAlgorithmTest, ColumnBalancingSingleLine) {
offset:0,0 size:320x20
offset:0,0 size:100x20
offset:0,0 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -3228,7 +3135,6 @@ TEST_F(NGColumnLayoutAlgorithmTest, ColumnBalancingSingleLineInNested) {
offset:0,0 size:100x20
offset:0,0 size:45x20
offset:0,0 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -3262,7 +3168,6 @@ TEST_F(NGColumnLayoutAlgorithmTest, ColumnBalancingSingleLineInNestedSpanner) {
offset:0,0 size:100x20
offset:0,0 size:100x20
offset:0,0 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -3327,17 +3232,12 @@ TEST_F(NGColumnLayoutAlgorithmTest, ColumnBalancingLines) {
offset:0,0 size:320x40
offset:0,0 size:100x40
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x40
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:220,0 size:100x40
offset:0,0 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -3375,21 +3275,15 @@ TEST_F(NGColumnLayoutAlgorithmTest, ColumnBalancingLinesOrphans) {
offset:0,0 size:100x60
offset:0,0 size:100x20
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x60
offset:0,0 size:100x60
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:0x20
- offset:0,9 size:0x1
offset:220,0 size:100x60
offset:0,0 size:100x40
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -3427,21 +3321,15 @@ TEST_F(NGColumnLayoutAlgorithmTest, ColumnBalancingLinesForcedBreak) {
offset:0,0 size:100x60
offset:0,0 size:100x20
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x60
offset:0,0 size:100x60
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:0x20
- offset:0,9 size:0x1
offset:220,0 size:100x60
offset:0,0 size:100x40
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -3479,34 +3367,22 @@ TEST_F(NGColumnLayoutAlgorithmTest, ColumnBalancingLinesForcedBreak2) {
offset:0,0 size:100x100
offset:0,0 size:100x100
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:0x20
- offset:0,9 size:0x1
offset:0,60 size:0x20
- offset:0,9 size:0x1
offset:0,80 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x100
offset:0,0 size:100x40
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:220,0 size:100x100
offset:0,0 size:99x0
offset:0,0 size:100x100
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:0x20
- offset:0,9 size:0x1
offset:0,60 size:0x20
- offset:0,9 size:0x1
offset:0,80 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -3548,36 +3424,24 @@ TEST_F(NGColumnLayoutAlgorithmTest, ColumnBalancingLinesForcedBreak3) {
offset:0,0 size:66x100
offset:0,0 size:66x100
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:0x20
- offset:0,9 size:0x1
offset:0,60 size:0x20
- offset:0,9 size:0x1
offset:0,80 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x100
offset:0,0 size:66x100
offset:0,0 size:66x40
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:220,0 size:100x100
offset:0,0 size:66x100
offset:0,0 size:99x0
offset:0,0 size:66x100
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:0x20
- offset:0,9 size:0x1
offset:0,60 size:0x20
- offset:0,9 size:0x1
offset:0,80 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -3615,21 +3479,15 @@ TEST_F(NGColumnLayoutAlgorithmTest, ColumnBalancingLinesAvoidBreakInside) {
offset:0,0 size:100x60
offset:0,0 size:100x20
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x60
offset:0,0 size:100x60
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:0x20
- offset:0,9 size:0x1
offset:220,0 size:100x60
offset:0,0 size:100x40
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -3667,19 +3525,14 @@ TEST_F(NGColumnLayoutAlgorithmTest, ColumnBalancingLinesAvoidBreakInside2) {
offset:0,0 size:100x60
offset:0,0 size:100x20
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x60
offset:0,0 size:100x60
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:0x20
- offset:0,9 size:0x1
offset:220,0 size:100x60
offset:0,0 size:100x20
offset:0,0 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -3978,7 +3831,6 @@ TEST_F(NGColumnLayoutAlgorithmTest, ClassCBreakPointBeforeLine) {
offset:110,0 size:100x100
offset:0,0 size:55x20
offset:0,0 size:33x20
- offset:0,0 size:33x11
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -4313,6 +4165,168 @@ TEST_F(NGColumnLayoutAlgorithmTest, NestedUnbalancedInnerAutoHeight) {
EXPECT_EQ(expectation, dump);
}
+TEST_F(NGColumnLayoutAlgorithmTest, NestedAtOuterBoundary) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ .outer { columns:3; height:100px; width:320px; }
+ .inner { columns:2; height:50px; }
+ .outer, .inner { column-gap:10px; column-fill:auto; }
+ </style>
+ <div id="container">
+ <div class="outer">
+ <div style="width:11px; height:100px;"></div>
+ <div class="inner">
+ <div style="width:22px; height:70px;"></div>
+ </div>
+ </div>
+ </div>
+ )HTML");
+
+ String dump = DumpFragmentTree(GetElementById("container"));
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:1000x100
+ offset:0,0 size:320x100
+ offset:0,0 size:100x100
+ offset:0,0 size:11x100
+ offset:110,0 size:100x100
+ offset:0,0 size:100x50
+ offset:0,0 size:45x50
+ offset:0,0 size:22x50
+ offset:55,0 size:45x50
+ offset:0,0 size:22x20
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+TEST_F(NGColumnLayoutAlgorithmTest, NestedZeroHeightAtOuterBoundary) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ .outer { columns:3; height:100px; width:320px; }
+ .inner { columns:2; }
+ .outer, .inner { column-gap:10px; column-fill:auto; }
+ </style>
+ <div id="container">
+ <div class="outer">
+ <div style="width:11px; height:100px;"></div>
+ <div class="inner">
+ <div style="width:22px;"></div>
+ </div>
+ </div>
+ </div>
+ )HTML");
+
+ String dump = DumpFragmentTree(GetElementById("container"));
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:1000x100
+ offset:0,0 size:320x100
+ offset:0,0 size:100x100
+ offset:0,0 size:11x100
+ offset:0,100 size:100x0
+ offset:0,0 size:45x1
+ offset:0,0 size:22x0
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+TEST_F(NGColumnLayoutAlgorithmTest, NestedWithMarginAtOuterBoundary) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ .outer { columns:3; height:100px; width:320px; }
+ .inner { columns:2; height:50px; margin-top:20px; }
+ .outer, .inner { column-gap:10px; column-fill:auto; }
+ </style>
+ <div id="container">
+ <div class="outer">
+ <div style="width:11px; height:90px;"></div>
+ <div class="inner">
+ <div style="width:22px; height:70px;"></div>
+ </div>
+ </div>
+ </div>
+ )HTML");
+
+ String dump = DumpFragmentTree(GetElementById("container"));
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:1000x100
+ offset:0,0 size:320x100
+ offset:0,0 size:100x100
+ offset:0,0 size:11x90
+ offset:110,0 size:100x100
+ offset:0,0 size:100x50
+ offset:0,0 size:45x50
+ offset:0,0 size:22x50
+ offset:55,0 size:45x50
+ offset:0,0 size:22x20
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+TEST_F(NGColumnLayoutAlgorithmTest, NestedWithTallBorder) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ .outer { columns:3; height:100px; width:320px; }
+ .inner { columns:2; height:50px; border-top:100px solid; }
+ .outer, .inner { column-gap:10px; column-fill:auto; }
+ </style>
+ <div id="container">
+ <div class="outer">
+ <div class="inner">
+ <div style="width:22px; height:70px;"></div>
+ </div>
+ </div>
+ </div>
+ )HTML");
+
+ String dump = DumpFragmentTree(GetElementById("container"));
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:1000x100
+ offset:0,0 size:320x100
+ offset:0,0 size:100x100
+ offset:0,0 size:100x100
+ offset:110,0 size:100x100
+ offset:0,0 size:100x50
+ offset:0,0 size:45x50
+ offset:0,0 size:22x50
+ offset:55,0 size:45x50
+ offset:0,0 size:22x20
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+TEST_F(NGColumnLayoutAlgorithmTest, NestedWithTallSpanner) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ .outer { columns:3; height:100px; width:320px; column-fill:auto; }
+ .inner { columns:2; }
+ .outer, .inner { column-gap:10px; }
+ </style>
+ <div id="container">
+ <div class="outer">
+ <div class="inner">
+ <div style="column-span:all; width:22px; height:100px;"></div>
+ <div style="width:22px; height:70px;"></div>
+ </div>
+ </div>
+ </div>
+ )HTML");
+
+ String dump = DumpFragmentTree(GetElementById("container"));
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:1000x100
+ offset:0,0 size:320x100
+ offset:0,0 size:100x100
+ offset:0,0 size:100x100
+ offset:0,0 size:22x100
+ offset:110,0 size:100x100
+ offset:0,0 size:100x35
+ offset:0,0 size:45x35
+ offset:0,0 size:22x35
+ offset:55,0 size:45x35
+ offset:0,0 size:22x35
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
TEST_F(NGColumnLayoutAlgorithmTest, AbsposFitsInOneColumn) {
SetBodyInnerHTML(R"HTML(
<div id="container">
@@ -5523,14 +5537,11 @@ TEST_F(NGColumnLayoutAlgorithmTest, AvoidSoftBreakBetweenSpanners3) {
offset:0,0 size:100x100
offset:0,0 size:11x100
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x100
offset:0,0 size:100x80
offset:0,0 size:11x20
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:55x60
)DUMP";
EXPECT_EQ(expectation, dump);
@@ -6084,15 +6095,11 @@ TEST_F(NGColumnLayoutAlgorithmTest, AvoidBreakBetweenHonorOrphansWidows) {
offset:0,0 size:100x100
offset:0,0 size:100x100
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x100
offset:0,0 size:100x40
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:100x30
)DUMP";
EXPECT_EQ(expectation, dump);
@@ -6135,9 +6142,7 @@ TEST_F(NGColumnLayoutAlgorithmTest, AvoidBreakBetweenHonorOrphansWidows2) {
offset:110,0 size:100x100
offset:0,0 size:100x40
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:100x30
)DUMP";
EXPECT_EQ(expectation, dump);
@@ -6186,22 +6191,15 @@ TEST_F(NGColumnLayoutAlgorithmTest, AvoidBreakBetweenHonorOrphansWidows3) {
offset:0,0 size:100x100
offset:0,0 size:100x100
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x100
offset:0,0 size:100x40
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:100x60
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:0x20
- offset:0,9 size:0x1
)DUMP";
EXPECT_EQ(expectation, dump);
}
@@ -6243,11 +6241,9 @@ TEST_F(NGColumnLayoutAlgorithmTest, AvoidBreakBetweenIgnoreOrphansWidows) {
offset:0,0 size:100x40
offset:0,40 size:100x60
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:110,0 size:100x100
offset:0,0 size:100x20
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:100x30
)DUMP";
EXPECT_EQ(expectation, dump);
@@ -6296,9 +6292,7 @@ TEST_F(NGColumnLayoutAlgorithmTest, AvoidBreakBetweenLinesInsideBreakAvoid) {
offset:110,0 size:100x100
offset:0,0 size:35x40
offset:0,0 size:0x20
- offset:0,9 size:0x1
offset:0,20 size:0x20
- offset:0,9 size:0x1
offset:0,40 size:36x30
)DUMP";
EXPECT_EQ(expectation, dump);
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space.cc
index c219e2f14f3..e916c433314 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_constraint_space.cc
@@ -35,8 +35,7 @@ static_assert(sizeof(NGConstraintSpace) == sizeof(SameSizeAsNGConstraintSpace),
} // namespace
NGConstraintSpace NGConstraintSpace::CreateFromLayoutObject(
- const LayoutBlock& block,
- bool is_layout_root) {
+ const LayoutBlock& block) {
// We should only ever create a constraint space from legacy layout if the
// object is a new formatting context.
DCHECK(block.CreatesNewFormattingContext());
@@ -77,28 +76,14 @@ NGConstraintSpace NGConstraintSpace::CreateFromLayoutObject(
/* is_new_fc */ true,
!parallel_containing_block);
- auto* previous_result = block.GetCachedLayoutResult();
- if (is_layout_root && previous_result) {
- // Due to layout-roots (starting layout at an arbirary node, instead of the
- // |LayoutView|), we can end up with a situation where we'll miss our cache
- // due to baseline-requests not matching.
- //
- // For the case where we start at a layout-root, the baselines don't
- // particularly matter, so we just request exactly the same as the previous
- // layout.
- builder.AddBaselineRequests(
- previous_result->GetConstraintSpaceForCaching().BaselineRequests());
- } else if (!block.IsWritingModeRoot() || block.IsGridItem()) {
- // Add all types because we don't know which baselines will be requested.
- FontBaseline baseline_type = style.GetFontBaseline();
- bool synthesize_inline_block_baseline =
- block.UseLogicalBottomMarginEdgeForInlineBlockBaseline();
- if (!synthesize_inline_block_baseline) {
- builder.AddBaselineRequest(
- {NGBaselineAlgorithmType::kAtomicInline, baseline_type});
- }
- builder.AddBaselineRequest(
- {NGBaselineAlgorithmType::kFirstLine, baseline_type});
+ if (!block.IsWritingModeRoot() || block.IsGridItem()) {
+ // We don't know if the parent layout will require our baseline, so always
+ // request it.
+ builder.SetNeedsBaseline(true);
+ builder.SetBaselineAlgorithmType(block.IsInline() &&
+ block.IsAtomicInlineLevel()
+ ? NGBaselineAlgorithmType::kInlineBlock
+ : NGBaselineAlgorithmType::kFirstLine);
}
if (block.IsTableCell()) {
@@ -123,6 +108,10 @@ NGConstraintSpace NGConstraintSpace::CreateFromLayoutObject(
table_style.BorderCollapse() == EBorderCollapse::kSeparate);
}
+ if (block.IsAtomicInlineLevel() || block.IsFlexItem() || block.IsGridItem() ||
+ block.IsFloating())
+ builder.SetIsPaintedAtomically(true);
+
builder.SetAvailableSize(available_size);
builder.SetPercentageResolutionSize(percentage_size);
builder.SetIsFixedInlineSize(fixed_inline);
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 91ec55842b2..e409701f6ce 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
@@ -13,7 +13,6 @@
#include "third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_bfc_offset.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_margin_strut.h"
-#include "third_party/blink/renderer/core/layout/ng/inline/ng_baseline.h"
#include "third_party/blink/renderer/core/layout/ng/ng_break_appeal.h"
#include "third_party/blink/renderer/core/layout/ng/ng_floats_utils.h"
#include "third_party/blink/renderer/platform/text/text_direction.h"
@@ -68,6 +67,28 @@ enum NGPercentageStorage {
kRareDataPercentage
};
+// Some layout algorithms (flow, tables) calculate their alignment baseline
+// differently if they are within an atomic-inline context.
+//
+// Other more modern layout algorithms (flex, grid) however ignore this flag
+// and always calculate the alignment baseline in the same way (returning the
+// "first-line").
+enum class NGBaselineAlgorithmType {
+ // Compute the baseline of the first line box.
+ kFirstLine,
+ // Compute the baseline(s) for when we are within an inline-block context. If
+ // the child is block-flow it will produce both the first, and last baselines.
+ kInlineBlock
+};
+
+// Some layout algorithms have multiple layout passes. Between passes they
+// typically have different results which we need to cache separately for
+// performance reasons.
+//
+// This enum gives the caching logic a hint into which cache "slot" it should
+// store a result in.
+enum class NGCacheSlot { kLayout, kMeasure };
+
// The NGConstraintSpace represents a set of constraints and available space
// which a layout algorithm may produce a NGFragment within.
class CORE_EXPORT NGConstraintSpace final {
@@ -134,8 +155,7 @@ class CORE_EXPORT NGConstraintSpace final {
// Creates NGConstraintSpace representing LayoutObject's containing block.
// This should live on NGBlockNode or another layout bridge and probably take
// a root NGConstraintSpace.
- static NGConstraintSpace CreateFromLayoutObject(const LayoutBlock&,
- bool is_layout_root);
+ static NGConstraintSpace CreateFromLayoutObject(const LayoutBlock&);
const NGExclusionSpace& ExclusionSpace() const { return exclusion_space_; }
@@ -239,6 +259,36 @@ class CORE_EXPORT NGConstraintSpace final {
return LayoutUnit();
}
+ // Inline/block target stretch size constraints.
+ // See:
+ // https://mathml-refresh.github.io/mathml-core/#dfn-inline-stretch-size-constraint
+ LayoutUnit TargetStretchInlineSize() const {
+ return HasRareData() ? rare_data_->TargetStretchInlineSize()
+ : kIndefiniteSize;
+ }
+
+ bool HasTargetStretchInlineSize() const {
+ return TargetStretchInlineSize() != kIndefiniteSize;
+ }
+
+ LayoutUnit TargetStretchAscentSize() const {
+ return HasRareData() ? rare_data_->TargetStretchAscentSize()
+ : kIndefiniteSize;
+ }
+
+ bool HasTargetStretchAscentSize() const {
+ return TargetStretchAscentSize() != kIndefiniteSize;
+ }
+
+ LayoutUnit TargetStretchDescentSize() const {
+ return HasRareData() ? rare_data_->TargetStretchDescentSize()
+ : kIndefiniteSize;
+ }
+
+ bool HasTargetStretchDescentSize() const {
+ return TargetStretchDescentSize() != kIndefiniteSize;
+ }
+
// Return the borders which should be used for a table-cell.
NGBoxStrut TableCellBorders() const {
return HasRareData() ? rare_data_->TableCellBorders() : NGBoxStrut();
@@ -322,6 +372,24 @@ class CORE_EXPORT NGConstraintSpace final {
return bitfields_.ancestor_has_clearance_past_adjoining_floats;
}
+ // Returns if the parent layout needs the baseline from this layout.
+ //
+ // This bit is only used for skipping querying baseline information from
+ // legacy layout.
+ bool NeedsBaseline() const { return bitfields_.needs_baseline; }
+
+ // How the baseline for the fragment should be calculated, see documentation
+ // for |NGBaselineAlgorithmType|.
+ NGBaselineAlgorithmType BaselineAlgorithmType() const {
+ return static_cast<NGBaselineAlgorithmType>(
+ bitfields_.baseline_algorithm_type);
+ }
+
+ // Which cache slot the output layout result should be stored in.
+ NGCacheSlot CacheSlot() const {
+ return static_cast<NGCacheSlot>(bitfields_.cache_slot);
+ }
+
// Some layout modes “stretch” their children to a fixed size (e.g. flex,
// grid). These flags represented whether a layout needs to produce a
// fragment that satisfies a fixed constraint in the inline and block
@@ -342,6 +410,8 @@ class CORE_EXPORT NGConstraintSpace final {
// (ie. fit-content). This is used for inline-block, floats, etc.
bool IsShrinkToFit() const { return bitfields_.is_shrink_to_fit; }
+ bool IsPaintedAtomically() const { return bitfields_.is_painted_atomically; }
+
// If specified a layout should produce a Fragment which fragments at the
// blockSize if possible.
NGFragmentationType BlockFragmentationType() const {
@@ -387,7 +457,7 @@ class CORE_EXPORT NGConstraintSpace final {
// Return true if the block size of the table-cell should be considered
// restricted (e.g. height of the cell or its table is non-auto).
bool IsRestrictedBlockSizeTableCell() const {
- return bitfields_.is_restricted_block_size_table_cell;
+ return HasRareData() && rare_data_->is_restricted_block_size_table_cell;
}
NGMarginStrut MarginStrut() const {
@@ -488,8 +558,12 @@ class CORE_EXPORT NGConstraintSpace final {
return HasRareData() ? rare_data_->ClearanceOffset() : LayoutUnit::Min();
}
- const NGBaselineRequestList BaselineRequests() const {
- return NGBaselineRequestList(bitfields_.baseline_requests);
+ bool ForceTruncateAtLineClamp() const {
+ return HasRareData() ? rare_data_->ForceTruncateAtLineClamp() : true;
+ }
+
+ base::Optional<int> LinesUntilClamp() const {
+ return HasRareData() ? rare_data_->LinesUntilClamp() : base::nullopt;
}
// Return true if the two constraint spaces are similar enough that it *may*
@@ -567,9 +641,6 @@ class CORE_EXPORT NGConstraintSpace final {
private:
friend class NGConstraintSpaceBuilder;
- explicit NGConstraintSpace(WritingMode writing_mode)
- : bfc_offset_(), bitfields_(writing_mode) {}
-
// This struct defines all of the inputs to layout which we consider rare.
// Primarily this is:
// - Percentage resolution sizes which differ from the available size or
@@ -577,6 +648,7 @@ class CORE_EXPORT NGConstraintSpace final {
// - The margin strut.
// - Anything to do with floats (the exclusion space, clearance offset, etc).
// - Anything to do with fragmentation.
+ // - Anything to do with stretching of math operators.
//
// This information is kept in a separate in this heap-allocated struct to
// reduce memory usage. Over time this may have to change based on usage data.
@@ -584,9 +656,20 @@ class CORE_EXPORT NGConstraintSpace final {
USING_FAST_MALLOC(RareData);
public:
+ // |RareData| unions different types of data which are mutually exclusive.
+ // They fall into the following categories:
+ enum DataUnionType {
+ kNone,
+ kBlockData, // An inflow block which doesn't establish a new FC.
+ kTableCellData, // A table-cell (display: table-cell).
+ kCustomData, // A custom layout (display: layout(foo)).
+ kStretchData // The target inline/block stretch sizes for MathML.
+ };
+
explicit RareData(const NGBfcOffset bfc_offset)
: bfc_offset(bfc_offset),
data_union_type(static_cast<unsigned>(kNone)),
+ is_restricted_block_size_table_cell(false),
hide_table_cell_if_empty(false),
block_direction_fragmentation_type(
static_cast<unsigned>(kFragmentNone)),
@@ -601,6 +684,8 @@ class CORE_EXPORT NGConstraintSpace final {
fragmentainer_block_size(other.fragmentainer_block_size),
fragmentainer_offset_at_bfc(other.fragmentainer_offset_at_bfc),
data_union_type(other.data_union_type),
+ is_restricted_block_size_table_cell(
+ other.is_restricted_block_size_table_cell),
hide_table_cell_if_empty(other.hide_table_cell_if_empty),
block_direction_fragmentation_type(
other.block_direction_fragmentation_type),
@@ -619,6 +704,9 @@ class CORE_EXPORT NGConstraintSpace final {
case kCustomData:
new (&custom_data_) CustomData(other.custom_data_);
break;
+ case kStretchData:
+ new (&stretch_data_) StretchData(other.stretch_data_);
+ break;
default:
NOTREACHED();
}
@@ -636,38 +724,20 @@ class CORE_EXPORT NGConstraintSpace final {
case kCustomData:
custom_data_.~CustomData();
break;
+ case kStretchData:
+ stretch_data_.~StretchData();
+ break;
default:
NOTREACHED();
}
}
- // |RareData| unions different types of data which are mutually exclusive.
- // They fall into the following categories:
- enum DataUnionType {
- kNone,
- kBlockData, // An inflow block which doesn't establish a new FC.
- kTableCellData, // A table-cell (display: table-cell).
- kCustomData // A custom layout (display: layout(foo)).
- };
-
- LogicalSize percentage_resolution_size;
- LayoutUnit replaced_percentage_resolution_block_size;
- NGBfcOffset bfc_offset;
-
- LayoutUnit fragmentainer_block_size = kIndefiniteSize;
- LayoutUnit fragmentainer_offset_at_bfc;
-
- unsigned data_union_type : 2;
- unsigned hide_table_cell_if_empty : 1;
- unsigned block_direction_fragmentation_type : 2;
- unsigned is_inside_balanced_columns : 1;
- unsigned is_in_column_bfc : 1;
- unsigned early_break_appeal : 2; // NGBreakAppeal
-
bool MaySkipLayout(const RareData& other) const {
if (fragmentainer_block_size != other.fragmentainer_block_size ||
fragmentainer_offset_at_bfc != other.fragmentainer_offset_at_bfc ||
data_union_type != other.data_union_type ||
+ is_restricted_block_size_table_cell !=
+ other.is_restricted_block_size_table_cell ||
hide_table_cell_if_empty != other.hide_table_cell_if_empty ||
block_direction_fragmentation_type !=
other.block_direction_fragmentation_type ||
@@ -680,19 +750,23 @@ class CORE_EXPORT NGConstraintSpace final {
return true;
if (data_union_type == kBlockData)
- return true;
+ return block_data_.MaySkipLayout(other.block_data_);
if (data_union_type == kTableCellData)
return table_cell_data_.MaySkipLayout(other.table_cell_data_);
- DCHECK_EQ(data_union_type, kCustomData);
- return custom_data_.MaySkipLayout(other.custom_data_);
+ if (data_union_type == kCustomData)
+ return custom_data_.MaySkipLayout(other.custom_data_);
+
+ DCHECK_EQ(data_union_type, kStretchData);
+ return stretch_data_.MaySkipLayout(other.stretch_data_);
}
// Must be kept in sync with members checked within |MaySkipLayout|.
bool IsInitialForMaySkipLayout() const {
if (fragmentainer_block_size != kIndefiniteSize ||
- fragmentainer_offset_at_bfc || hide_table_cell_if_empty ||
+ fragmentainer_offset_at_bfc || is_restricted_block_size_table_cell ||
+ hide_table_cell_if_empty ||
block_direction_fragmentation_type != kFragmentNone ||
is_inside_balanced_columns || is_in_column_bfc ||
early_break_appeal != kBreakAppealLastResort)
@@ -702,13 +776,16 @@ class CORE_EXPORT NGConstraintSpace final {
return true;
if (data_union_type == kBlockData)
- return true;
+ return block_data_.IsInitialForMaySkipLayout();
if (data_union_type == kTableCellData)
return table_cell_data_.IsInitialForMaySkipLayout();
- DCHECK_EQ(data_union_type, kCustomData);
- return custom_data_.IsInitialForMaySkipLayout();
+ if (data_union_type == kCustomData)
+ return custom_data_.IsInitialForMaySkipLayout();
+
+ DCHECK_EQ(data_union_type, kStretchData);
+ return stretch_data_.IsInitialForMaySkipLayout();
}
NGMarginStrut MarginStrut() const {
@@ -749,6 +826,25 @@ class CORE_EXPORT NGConstraintSpace final {
EnsureBlockData()->clearance_offset = clearance_offset;
}
+ base::Optional<int> LinesUntilClamp() const {
+ return data_union_type == kBlockData ? block_data_.lines_until_clamp
+ : base::nullopt;
+ }
+
+ void SetLinesUntilClamp(int value) {
+ EnsureBlockData()->lines_until_clamp = value;
+ }
+
+ int ForceTruncateAtLineClamp() const {
+ return data_union_type == kBlockData
+ ? block_data_.force_truncate_at_line_clamp
+ : true;
+ }
+
+ void SetForceTruncateAtLineClamp(bool value) {
+ EnsureBlockData()->force_truncate_at_line_clamp = value;
+ }
+
NGBoxStrut TableCellBorders() const {
return data_union_type == kTableCellData
? table_cell_data_.table_cell_borders
@@ -786,28 +882,78 @@ class CORE_EXPORT NGConstraintSpace final {
EnsureCustomData()->data = std::move(custom_layout_data);
}
+ LayoutUnit TargetStretchInlineSize() const {
+ return data_union_type == kStretchData
+ ? stretch_data_.target_stretch_inline_size
+ : kIndefiniteSize;
+ }
+
+ void SetTargetStretchInlineSize(LayoutUnit target_stretch_inline_size) {
+ EnsureStretchData()->target_stretch_inline_size =
+ target_stretch_inline_size;
+ }
+
+ LayoutUnit TargetStretchAscentSize() const {
+ return data_union_type == kStretchData
+ ? stretch_data_.target_stretch_ascent_size
+ : kIndefiniteSize;
+ }
+
+ void SetTargetStretchAscentSize(LayoutUnit target_stretch_ascent_size) {
+ EnsureStretchData()->target_stretch_ascent_size =
+ target_stretch_ascent_size;
+ }
+
+ LayoutUnit TargetStretchDescentSize() const {
+ return data_union_type == kStretchData
+ ? stretch_data_.target_stretch_descent_size
+ : kIndefiniteSize;
+ }
+
+ void SetTargetStretchDescentSize(LayoutUnit target_stretch_descent_size) {
+ EnsureStretchData()->target_stretch_descent_size =
+ target_stretch_descent_size;
+ }
+
+ LogicalSize percentage_resolution_size;
+ LayoutUnit replaced_percentage_resolution_block_size;
+ NGBfcOffset bfc_offset;
+
+ LayoutUnit fragmentainer_block_size = kIndefiniteSize;
+ LayoutUnit fragmentainer_offset_at_bfc;
+
+ unsigned data_union_type : 3;
+
+ unsigned is_restricted_block_size_table_cell : 1;
+ unsigned hide_table_cell_if_empty : 1;
+
+ unsigned block_direction_fragmentation_type : 2;
+ unsigned is_inside_balanced_columns : 1;
+ unsigned is_in_column_bfc : 1;
+ unsigned early_break_appeal : 2; // NGBreakAppeal
private:
struct BlockData {
+ bool MaySkipLayout(const BlockData& other) const {
+ return lines_until_clamp == other.lines_until_clamp &&
+ force_truncate_at_line_clamp ==
+ other.force_truncate_at_line_clamp;
+ }
+
+ bool IsInitialForMaySkipLayout() const {
+ return !lines_until_clamp.has_value() && force_truncate_at_line_clamp;
+ }
+
NGMarginStrut margin_strut;
base::Optional<LayoutUnit> optimistic_bfc_block_offset;
base::Optional<LayoutUnit> forced_bfc_block_offset;
LayoutUnit clearance_offset = LayoutUnit::Min();
+ base::Optional<int> lines_until_clamp;
+ // If true and |lines_until_clamp| == 1, then the line should be truncated
+ // regardless of whether there is more text that follows on the line.
+ bool force_truncate_at_line_clamp = true;
};
- BlockData* EnsureBlockData() {
- DCHECK(data_union_type == kNone || data_union_type == kBlockData);
- if (data_union_type != kBlockData) {
- data_union_type = kBlockData;
- new (&block_data_) BlockData();
- }
- return &block_data_;
- }
-
struct TableCellData {
- NGBoxStrut table_cell_borders;
- LayoutUnit table_cell_intrinsic_padding_block_start;
- LayoutUnit table_cell_intrinsic_padding_block_end;
-
bool MaySkipLayout(const TableCellData& other) const {
return table_cell_borders == other.table_cell_borders &&
table_cell_intrinsic_padding_block_start ==
@@ -821,16 +967,11 @@ class CORE_EXPORT NGConstraintSpace final {
table_cell_intrinsic_padding_block_start == LayoutUnit() &&
table_cell_intrinsic_padding_block_end == LayoutUnit();
}
- };
- TableCellData* EnsureTableCellData() {
- DCHECK(data_union_type == kNone || data_union_type == kTableCellData);
- if (data_union_type != kTableCellData) {
- data_union_type = kTableCellData;
- new (&table_cell_data_) TableCellData();
- }
- return &table_cell_data_;
- }
+ NGBoxStrut table_cell_borders;
+ LayoutUnit table_cell_intrinsic_padding_block_start;
+ LayoutUnit table_cell_intrinsic_padding_block_end;
+ };
struct CustomData {
scoped_refptr<SerializedScriptValue> data;
@@ -842,6 +983,42 @@ class CORE_EXPORT NGConstraintSpace final {
bool IsInitialForMaySkipLayout() const { return !data; }
};
+ struct StretchData {
+ bool MaySkipLayout(const StretchData& other) const {
+ return target_stretch_inline_size == other.target_stretch_inline_size &&
+ target_stretch_ascent_size == other.target_stretch_ascent_size &&
+ target_stretch_descent_size == other.target_stretch_descent_size;
+ }
+
+ bool IsInitialForMaySkipLayout() const {
+ return target_stretch_inline_size == kIndefiniteSize &&
+ target_stretch_ascent_size == kIndefiniteSize &&
+ target_stretch_descent_size == kIndefiniteSize;
+ }
+
+ LayoutUnit target_stretch_inline_size = kIndefiniteSize;
+ LayoutUnit target_stretch_ascent_size = kIndefiniteSize;
+ LayoutUnit target_stretch_descent_size = kIndefiniteSize;
+ };
+
+ BlockData* EnsureBlockData() {
+ DCHECK(data_union_type == kNone || data_union_type == kBlockData);
+ if (data_union_type != kBlockData) {
+ data_union_type = kBlockData;
+ new (&block_data_) BlockData();
+ }
+ return &block_data_;
+ }
+
+ TableCellData* EnsureTableCellData() {
+ DCHECK(data_union_type == kNone || data_union_type == kTableCellData);
+ if (data_union_type != kTableCellData) {
+ data_union_type = kTableCellData;
+ new (&table_cell_data_) TableCellData();
+ }
+ return &table_cell_data_;
+ }
+
CustomData* EnsureCustomData() {
DCHECK(data_union_type == kNone || data_union_type == kCustomData);
if (data_union_type != kCustomData) {
@@ -851,10 +1028,20 @@ class CORE_EXPORT NGConstraintSpace final {
return &custom_data_;
}
+ StretchData* EnsureStretchData() {
+ DCHECK(data_union_type == kNone || data_union_type == kStretchData);
+ if (data_union_type != kStretchData) {
+ data_union_type = kStretchData;
+ new (&stretch_data_) StretchData();
+ }
+ return &stretch_data_;
+ }
+
union {
BlockData block_data_;
TableCellData table_cell_data_;
CustomData custom_data_;
+ StretchData stretch_data_;
};
};
@@ -876,13 +1063,17 @@ class CORE_EXPORT NGConstraintSpace final {
is_anonymous(false),
is_new_formatting_context(false),
is_orthogonal_writing_mode_root(false),
- is_fixed_block_size_indefinite(false),
- is_restricted_block_size_table_cell(false),
+ is_painted_atomically(false),
use_first_line_style(false),
ancestor_has_clearance_past_adjoining_floats(false),
+ needs_baseline(false),
+ baseline_algorithm_type(
+ static_cast<unsigned>(NGBaselineAlgorithmType::kFirstLine)),
+ cache_slot(static_cast<unsigned>(NGCacheSlot::kLayout)),
is_shrink_to_fit(false),
is_fixed_inline_size(false),
is_fixed_block_size(false),
+ is_fixed_block_size_indefinite(false),
table_cell_child_layout_mode(static_cast<unsigned>(
NGTableCellChildLayoutMode::kNotTableCellChild)),
percentage_inline_storage(kSameAsAvailable),
@@ -898,20 +1089,20 @@ class CORE_EXPORT NGConstraintSpace final {
is_new_formatting_context == other.is_new_formatting_context &&
is_orthogonal_writing_mode_root ==
other.is_orthogonal_writing_mode_root &&
- is_fixed_block_size_indefinite ==
- other.is_fixed_block_size_indefinite &&
- is_restricted_block_size_table_cell ==
- other.is_restricted_block_size_table_cell &&
+ is_painted_atomically == other.is_painted_atomically &&
use_first_line_style == other.use_first_line_style &&
ancestor_has_clearance_past_adjoining_floats ==
other.ancestor_has_clearance_past_adjoining_floats &&
- baseline_requests == other.baseline_requests;
+ needs_baseline == other.needs_baseline &&
+ baseline_algorithm_type == other.baseline_algorithm_type;
}
bool AreSizeConstraintsEqual(const Bitfields& other) const {
return is_shrink_to_fit == other.is_shrink_to_fit &&
is_fixed_inline_size == other.is_fixed_inline_size &&
is_fixed_block_size == other.is_fixed_block_size &&
+ is_fixed_block_size_indefinite ==
+ other.is_fixed_block_size_indefinite &&
table_cell_child_layout_mode == other.table_cell_child_layout_mode;
}
@@ -925,17 +1116,20 @@ class CORE_EXPORT NGConstraintSpace final {
unsigned is_new_formatting_context : 1;
unsigned is_orthogonal_writing_mode_root : 1;
- unsigned is_fixed_block_size_indefinite : 1;
- unsigned is_restricted_block_size_table_cell : 1;
+ unsigned is_painted_atomically : 1;
unsigned use_first_line_style : 1;
unsigned ancestor_has_clearance_past_adjoining_floats : 1;
- unsigned baseline_requests : NGBaselineRequestList::kSerializedBits;
+ unsigned needs_baseline : 1;
+ unsigned baseline_algorithm_type : 1;
+
+ unsigned cache_slot : 1;
// Size constraints.
unsigned is_shrink_to_fit : 1;
unsigned is_fixed_inline_size : 1;
unsigned is_fixed_block_size : 1;
+ unsigned is_fixed_block_size_indefinite : 1;
unsigned table_cell_child_layout_mode : 2; // NGTableCellChildLayoutMode
unsigned percentage_inline_storage : 2; // NGPercentageStorage
@@ -943,6 +1137,9 @@ class CORE_EXPORT NGConstraintSpace final {
unsigned replaced_percentage_block_storage : 2; // NGPercentageStorage
};
+ explicit NGConstraintSpace(WritingMode writing_mode)
+ : bfc_offset_(), bitfields_(writing_mode) {}
+
inline bool HasRareData() const { return bitfields_.has_rare_data; }
RareData* EnsureRareData() {
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 9a1709ec95f..68cc44fc392 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
@@ -145,6 +145,10 @@ class CORE_EXPORT NGConstraintSpaceBuilder final {
void SetIsShrinkToFit(bool b) { space_.bitfields_.is_shrink_to_fit = b; }
+ void SetIsPaintedAtomically(bool b) {
+ space_.bitfields_.is_painted_atomically = b;
+ }
+
void SetFragmentationType(NGFragmentationType fragmentation_type) {
#if DCHECK_IS_ON()
DCHECK(!is_block_direction_fragmentation_type_set_);
@@ -172,13 +176,16 @@ class CORE_EXPORT NGConstraintSpaceBuilder final {
void SetIsRestrictedBlockSizeTableCell(bool b) {
DCHECK(space_.bitfields_.is_table_cell);
- space_.bitfields_.is_restricted_block_size_table_cell = b;
+ if (!b && !space_.rare_data_)
+ return;
+ space_.EnsureRareData()->is_restricted_block_size_table_cell = b;
}
void SetHideTableCellIfEmpty(bool b) {
DCHECK(space_.bitfields_.is_table_cell);
- if (b)
- space_.EnsureRareData()->hide_table_cell_if_empty = b;
+ if (!b && !space_.rare_data_)
+ return;
+ space_.EnsureRareData()->hide_table_cell_if_empty = b;
}
void SetIsAnonymous(bool b) { space_.bitfields_.is_anonymous = b; }
@@ -187,10 +194,6 @@ class CORE_EXPORT NGConstraintSpaceBuilder final {
space_.bitfields_.use_first_line_style = b;
}
- void SetAncestorHasClearancePastAdjoiningFloats() {
- space_.bitfields_.ancestor_has_clearance_past_adjoining_floats = true;
- }
-
void SetAdjoiningObjectTypes(NGAdjoiningObjectTypes adjoining_object_types) {
if (!is_new_fc_) {
space_.bitfields_.adjoining_object_types =
@@ -198,6 +201,20 @@ class CORE_EXPORT NGConstraintSpaceBuilder final {
}
}
+ void SetAncestorHasClearancePastAdjoiningFloats() {
+ space_.bitfields_.ancestor_has_clearance_past_adjoining_floats = true;
+ }
+
+ void SetNeedsBaseline(bool b) { space_.bitfields_.needs_baseline = b; }
+
+ void SetBaselineAlgorithmType(NGBaselineAlgorithmType type) {
+ space_.bitfields_.baseline_algorithm_type = static_cast<unsigned>(type);
+ }
+
+ void SetCacheSlot(NGCacheSlot slot) {
+ space_.bitfields_.cache_slot = static_cast<unsigned>(slot);
+ }
+
void SetMarginStrut(const NGMarginStrut& margin_strut) {
#if DCHECK_IS_ON()
DCHECK(!is_margin_strut_set_);
@@ -301,12 +318,41 @@ class CORE_EXPORT NGConstraintSpaceBuilder final {
}
}
- void AddBaselineRequests(const NGBaselineRequestList requests) {
- DCHECK(baseline_requests_.IsEmpty());
- baseline_requests_.AppendVector(requests);
+ void SetForceTruncateAtLineClamp(bool value) {
+#if DCHECK_IS_ON()
+ DCHECK(!is_force_truncate_at_line_clamp_set_);
+ is_force_truncate_at_line_clamp_set_ = true;
+#endif
+ if (!value)
+ space_.EnsureRareData()->SetForceTruncateAtLineClamp(value);
}
- void AddBaselineRequest(const NGBaselineRequest request) {
- baseline_requests_.push_back(request);
+
+ void SetLinesUntilClamp(const base::Optional<int>& clamp) {
+#if DCHECK_IS_ON()
+ DCHECK(!is_lines_until_clamp_set_);
+ is_lines_until_clamp_set_ = true;
+#endif
+ DCHECK(!is_new_fc_);
+ if (clamp)
+ space_.EnsureRareData()->SetLinesUntilClamp(*clamp);
+ }
+
+ void SetTargetStretchInlineSize(LayoutUnit target_stretch_inline_size) {
+ DCHECK_GE(target_stretch_inline_size, LayoutUnit());
+ space_.EnsureRareData()->SetTargetStretchInlineSize(
+ target_stretch_inline_size);
+ }
+
+ void SetTargetStretchAscentSize(LayoutUnit target_stretch_ascent_size) {
+ DCHECK_GE(target_stretch_ascent_size, LayoutUnit());
+ space_.EnsureRareData()->SetTargetStretchAscentSize(
+ target_stretch_ascent_size);
+ }
+
+ void SetTargetStretchDescentSize(LayoutUnit target_stretch_descent_size) {
+ DCHECK_GE(target_stretch_descent_size, LayoutUnit());
+ space_.EnsureRareData()->SetTargetStretchDescentSize(
+ target_stretch_descent_size);
}
// Creates a new constraint space.
@@ -326,7 +372,6 @@ class CORE_EXPORT NGConstraintSpaceBuilder final {
"simultaneously. Inferred means the constraints are in parent "
"writing mode, forced means they are in child writing mode.";
- space_.bitfields_.baseline_requests = baseline_requests_.Serialize();
return std::move(space_);
}
@@ -355,11 +400,11 @@ class CORE_EXPORT NGConstraintSpaceBuilder final {
bool is_table_cell_borders_set_ = false;
bool is_table_cell_intrinsic_padding_set_ = false;
bool is_custom_layout_data_set_ = false;
+ bool is_lines_until_clamp_set_ = false;
+ bool is_force_truncate_at_line_clamp_set_ = false;
bool to_constraint_space_called_ = false;
#endif
-
- NGBaselineRequestList baseline_requests_;
};
} // namespace blink
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 6e6115501e8..4c26a00648f 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
@@ -101,7 +101,7 @@ void NGContainerFragmentBuilder::PropagateChildData(
// have a child positioned above our block-start edge.
if ((child_offset.block_offset < LayoutUnit() &&
!child.IsOutOfFlowPositioned()) ||
- (!child.IsBlockFormattingContextRoot() && !child.IsLineBox() &&
+ (!child.IsFormattingContextRoot() && !child.IsLineBox() &&
child.MayHaveDescendantAboveBlockStart()))
may_have_descendant_above_block_start_ = true;
@@ -120,7 +120,7 @@ void NGContainerFragmentBuilder::PropagateChildData(
// If a fragment doesn't have any adjoining object descendants, and is
// self-collapsing, it can be "shifted" anywhere.
if (!has_adjoining_object_descendants_) {
- if (!child.IsBlockFormattingContextRoot() &&
+ if (!child.IsFormattingContextRoot() &&
child.HasAdjoiningObjectDescendants())
has_adjoining_object_descendants_ = true;
}
@@ -132,7 +132,6 @@ void NGContainerFragmentBuilder::PropagateChildData(
if (const NGBreakToken* child_break_token = child.BreakToken()) {
switch (child.Type()) {
case NGPhysicalFragment::kFragmentBox:
- case NGPhysicalFragment::kFragmentRenderedLegend:
child_break_tokens_.push_back(child_break_token);
break;
case NGPhysicalFragment::kFragmentLineBox:
@@ -163,33 +162,6 @@ void NGContainerFragmentBuilder::AddChildInternal(
children_.emplace_back(child_offset, std::move(child));
}
-LogicalOffset NGContainerFragmentBuilder::GetChildOffset(
- const LayoutObject* object) const {
- for (const auto& child : children_) {
- if (child.fragment->GetLayoutObject() == object)
- return child.offset;
-
- // TODO(layout-dev): ikilpatrick thinks we may need to traverse
- // further than the initial line-box children for a nested inline
- // container. We could not come up with a testcase, it would be
- // something with split inlines, and nested oof/fixed descendants maybe.
- if (child.fragment->IsLineBox()) {
- const auto& line_box_fragment =
- To<NGPhysicalLineBoxFragment>(*child.fragment);
- for (const auto& line_box_child : line_box_fragment.Children()) {
- if (line_box_child->GetLayoutObject() == object) {
- return child.offset + line_box_child.Offset().ConvertToLogical(
- GetWritingMode(), Direction(),
- line_box_fragment.Size(),
- line_box_child->Size());
- }
- }
- }
- }
- NOTREACHED();
- return LogicalOffset();
-}
-
void NGContainerFragmentBuilder::AddOutOfFlowChildCandidate(
NGBlockNode child,
const LogicalOffset& child_offset,
@@ -197,8 +169,17 @@ void NGContainerFragmentBuilder::AddOutOfFlowChildCandidate(
NGLogicalStaticPosition::BlockEdge block_edge) {
DCHECK(child);
+ // If an OOF-positioned candidate has a static-position which uses a
+ // non-block-start edge, we need to adjust its static-position when the final
+ // block-size is known.
+ bool needs_block_offset_adjustment =
+ block_edge != NGLogicalStaticPosition::BlockEdge::kBlockStart;
+ has_oof_candidate_that_needs_block_offset_adjustment_ |=
+ needs_block_offset_adjustment;
+
oof_positioned_candidates_.emplace_back(
- child, NGLogicalStaticPosition{child_offset, inline_edge, block_edge});
+ child, NGLogicalStaticPosition{child_offset, inline_edge, block_edge},
+ /* inline_container */ nullptr, needs_block_offset_adjustment);
}
void NGContainerFragmentBuilder::AddOutOfFlowInlineChildCandidate(
@@ -226,6 +207,27 @@ void NGContainerFragmentBuilder::SwapOutOfFlowPositionedCandidates(
Vector<NGLogicalOutOfFlowPositionedNode>* candidates) {
DCHECK(candidates->IsEmpty());
std::swap(oof_positioned_candidates_, *candidates);
+
+ if (!has_oof_candidate_that_needs_block_offset_adjustment_)
+ return;
+
+ using BlockEdge = NGLogicalStaticPosition::BlockEdge;
+
+ // We might have an OOF-positioned candidate whose static-position depends on
+ // the final block-size of this fragment.
+ DCHECK_NE(BlockSize(), kIndefiniteSize);
+ for (auto& candidate : *candidates) {
+ if (!candidate.needs_block_offset_adjustment)
+ continue;
+
+ if (candidate.static_position.block_edge == BlockEdge::kBlockCenter)
+ candidate.static_position.offset.block_offset += BlockSize() / 2;
+ else if (candidate.static_position.block_edge == BlockEdge::kBlockEnd)
+ candidate.static_position.offset.block_offset += BlockSize();
+ candidate.needs_block_offset_adjustment = false;
+ }
+
+ has_oof_candidate_that_needs_block_offset_adjustment_ = false;
}
void NGContainerFragmentBuilder::
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 0ca512fee7f..a76a849df0b 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
@@ -88,10 +88,6 @@ class CORE_EXPORT NGContainerFragmentBuilder : public NGFragmentBuilder {
const ChildrenVector& Children() const { return children_; }
- // Returns offset for given child. DCHECK if child not found.
- // Warning: Do not call unless necessary.
- LogicalOffset GetChildOffset(const LayoutObject* child) const;
-
// Builder has non-trivial OOF-positioned methods.
// They are intended to be used by a layout algorithm like this:
//
@@ -183,8 +179,9 @@ class CORE_EXPORT NGContainerFragmentBuilder : public NGFragmentBuilder {
#endif
protected:
- friend class NGPhysicalContainerFragment;
+ friend class NGInlineLayoutStateStack;
friend class NGLayoutResult;
+ friend class NGPhysicalContainerFragment;
NGContainerFragmentBuilder(NGLayoutInputNode node,
scoped_refptr<const ComputedStyle> style,
@@ -240,6 +237,8 @@ class CORE_EXPORT NGContainerFragmentBuilder : public NGFragmentBuilder {
bool has_block_fragmentation_ = false;
bool is_fragmentation_context_root_ = false;
bool may_have_descendant_above_block_start_ = false;
+
+ bool has_oof_candidate_that_needs_block_offset_adjustment_ = false;
};
} // namespace blink
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 79bf0f09f45..02c3b80ed79 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
@@ -10,6 +10,7 @@
#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_fragment.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.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/layout/ng/ng_out_of_flow_layout_part.h"
@@ -21,16 +22,30 @@ namespace blink {
NGFieldsetLayoutAlgorithm::NGFieldsetLayoutAlgorithm(
const NGLayoutAlgorithmParams& params)
: NGLayoutAlgorithm(params),
+ writing_mode_(ConstraintSpace().GetWritingMode()),
border_padding_(params.fragment_geometry.border +
- params.fragment_geometry.padding) {
+ params.fragment_geometry.padding),
+ consumed_block_size_(BreakToken() ? BreakToken()->ConsumedBlockSize()
+ : LayoutUnit()) {
container_builder_.SetIsNewFormattingContext(
params.space.IsNewFormattingContext());
container_builder_.SetInitialFragmentGeometry(params.fragment_geometry);
+
+ borders_ = container_builder_.Borders();
+ padding_ = container_builder_.Padding();
+ border_box_size_ = container_builder_.InitialBorderBoxSize();
+ block_start_padding_edge_ = borders_.block_start;
+
+ // 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_;
+ AdjustForFragmentation(BreakToken(), &adjusted_border_padding_);
}
scoped_refptr<const NGLayoutResult> NGFieldsetLayoutAlgorithm::Layout() {
- // TODO(mstensho): Support block fragmentation.
- DCHECK(!BreakToken());
+ // TODO(almaher): Make sure the border start is handled correctly during
+ // fragmentation.
// 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
@@ -42,87 +57,32 @@ scoped_refptr<const NGLayoutResult> NGFieldsetLayoutAlgorithm::Layout() {
// 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.
- NGBoxStrut borders = container_builder_.Borders();
- NGBoxStrut padding = container_builder_.Padding();
- LogicalSize border_box_size = container_builder_.InitialBorderBoxSize();
- const auto writing_mode = ConstraintSpace().GetWritingMode();
- LayoutUnit block_start_padding_edge =
- container_builder_.Borders().block_start;
-
- // TODO(vmpstr): Skip child (including legend) layout for fieldset elements.
- if (NGBlockNode legend = Node().GetRenderedLegend()) {
- // 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, border_padding_);
- auto legend_space =
- CreateConstraintSpaceForLegend(legend, content_box_size);
- auto result = legend.Layout(legend_space, BreakToken());
- const auto& physical_fragment = result->PhysicalFragment();
- NGBoxStrut legend_margins =
- ComputeMarginsFor(legend_space, legend.Style(), ConstraintSpace());
- // If the margin box of the legend is at least as tall as the fieldset
- // block-start border width, it will start at the block-start border edge of
- // the fieldset. As a paint effect, the block-start border will be pushed so
- // that the center of the border will be flush with the center of the
- // border-box of the legend.
- // TODO(mstensho): inline alignment
- LogicalOffset legend_offset = LogicalOffset(
- border_padding_.inline_start + legend_margins.inline_start,
- legend_margins.block_start);
- LayoutUnit legend_margin_box_block_size =
- NGFragment(writing_mode, physical_fragment).BlockSize() +
- legend_margins.BlockSum();
- LayoutUnit space_left = borders.block_start - legend_margin_box_block_size;
- if (space_left > LayoutUnit()) {
- // If the border is the larger one, though, it will stay put at the
- // border-box block-start edge of the fieldset. Then it's the legend that
- // needs to be pushed. We'll center the margin box in this case, to make
- // sure that both margins remain within the area occupied by the border
- // also after adjustment.
- legend_offset.block_offset += space_left / 2;
- } else {
- // If the legend is larger than the width of the fieldset block-start
- // border, the actual padding edge of the fieldset will be moved
- // accordingly. This will be the block-start offset for the fieldset
- // contents anonymous box.
- block_start_padding_edge = legend_margin_box_block_size;
- }
-
- container_builder_.AddChild(physical_fragment, legend_offset);
- }
- NGBoxStrut borders_with_legend = borders;
- borders_with_legend.block_start = block_start_padding_edge;
- LayoutUnit intrinsic_block_size = borders_with_legend.BlockSum();
+ if (ConstraintSpace().HasBlockFragmentation()) {
+ container_builder_.SetHasBlockFragmentation();
+ // The whereabouts of our container's so far best breakpoint is none of our
+ // business, but we store its appeal, so that we don't look for breakpoints
+ // with lower appeal than that.
+ container_builder_.SetBreakAppeal(ConstraintSpace().EarlyBreakAppeal());
- // Proceed with normal fieldset children (excluding the rendered legend). They
- // all live inside an anonymous child box of the fieldset container.
- if (auto fieldset_content = Node().GetFieldsetContent()) {
- LogicalSize adjusted_padding_box_size =
- ShrinkAvailableSize(border_box_size, borders_with_legend);
- auto child_space =
- CreateConstraintSpaceForFieldsetContent(adjusted_padding_box_size);
- auto result = fieldset_content.Layout(child_space, BreakToken());
- const auto& physical_fragment = result->PhysicalFragment();
- container_builder_.AddChild(physical_fragment,
- borders_with_legend.StartOffset());
+ if (ConstraintSpace().IsInitialColumnBalancingPass())
+ container_builder_.SetIsInitialColumnBalancingPass();
+ }
- intrinsic_block_size +=
- NGFragment(writing_mode, physical_fragment).BlockSize();
- } else {
- // There was no anonymous child to provide the padding, so we have to add it
- // ourselves.
- intrinsic_block_size += padding.BlockSum();
+ NGBreakStatus break_status = LayoutChildren();
+ if (break_status == NGBreakStatus::kNeedsEarlierBreak) {
+ // We need to abort the layout. No fragment will be generated.
+ return container_builder_.Abort(NGLayoutResult::kNeedsEarlierBreak);
}
- intrinsic_block_size = ClampIntrinsicBlockSize(
- ConstraintSpace(), Node(), border_padding_, intrinsic_block_size);
+ intrinsic_block_size_ =
+ ClampIntrinsicBlockSize(ConstraintSpace(), Node(),
+ adjusted_border_padding_, 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_.block_size =
+ ComputeBlockSizeForFragment(ConstraintSpace(), Style(), border_padding_,
+ intrinsic_block_size_ + consumed_block_size_);
// The above computation utility knows nothing about fieldset weirdness. The
// legend may eat from the available content box block size. Make room for
@@ -131,34 +91,291 @@ scoped_refptr<const NGLayoutResult> NGFieldsetLayoutAlgorithm::Layout() {
// contents, with the conjecture being that legend is part of the contents.
// Thus, only do this adjustment if we do not contain size.
if (!Node().ShouldApplySizeContainment()) {
- LayoutUnit minimum_border_box_block_size =
- borders_with_legend.BlockSum() + padding.BlockSum();
- border_box_size.block_size =
- std::max(border_box_size.block_size, minimum_border_box_block_size);
+ // Similar to how we add the consumed block size to the intrinsic
+ // block size when calculating border_box_size_.block_size, we also need to
+ // do so when the fieldset is adjusted to encompass the legend.
+ border_box_size_.block_size =
+ std::max(border_box_size_.block_size,
+ minimum_border_box_block_size_ + consumed_block_size_);
}
+ // 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_;
+
container_builder_.SetIsFieldsetContainer();
- container_builder_.SetIntrinsicBlockSize(intrinsic_block_size);
- container_builder_.SetBlockSize(border_box_size.block_size);
+ if (ConstraintSpace().HasKnownFragmentainerBlockSize()) {
+ FinishFragmentation(
+ ConstraintSpace(), BreakToken(), block_size, intrinsic_block_size_,
+ FragmentainerSpaceAtBfcStart(ConstraintSpace()), &container_builder_);
+ } else {
+ container_builder_.SetIntrinsicBlockSize(intrinsic_block_size_);
+ container_builder_.SetBlockSize(block_size);
+ }
- NGOutOfFlowLayoutPart(Node(), ConstraintSpace(), borders_with_legend,
+ NGOutOfFlowLayoutPart(Node(), ConstraintSpace(), borders_with_legend_,
&container_builder_)
.Run();
return container_builder_.ToBoxFragment();
}
-base::Optional<MinMaxSize> NGFieldsetLayoutAlgorithm::ComputeMinMaxSize(
- const MinMaxSizeInput& input) const {
- MinMaxSize sizes;
+NGBreakStatus NGFieldsetLayoutAlgorithm::LayoutChildren() {
+ scoped_refptr<const NGBlockBreakToken> legend_break_token;
+ scoped_refptr<const NGBlockBreakToken> content_break_token;
+ bool has_seen_all_children = false;
+ if (const auto* token = BreakToken()) {
+ const auto child_tokens = token->ChildBreakTokens();
+ if (wtf_size_t break_token_count = child_tokens.size()) {
+ DCHECK_LE(break_token_count, 2u);
+ for (wtf_size_t break_token_idx = 0; break_token_idx < break_token_count;
+ break_token_idx++) {
+ scoped_refptr<const NGBlockBreakToken> child_token =
+ To<NGBlockBreakToken>(child_tokens[break_token_idx]);
+ if (child_token && child_token->InputNode().IsRenderedLegend()) {
+ DCHECK_EQ(break_token_idx, 0u);
+ legend_break_token = child_token;
+ } else {
+ content_break_token = child_token;
+ }
+ }
+ }
+ if (token->HasSeenAllChildren()) {
+ container_builder_.SetHasSeenAllChildren();
+ has_seen_all_children = true;
+ }
+ }
+
+ NGBlockNode legend = Node().GetRenderedLegend();
+ bool legend_needs_layout =
+ legend && (legend_break_token || !IsResumingLayout(BreakToken()));
- bool apply_size_containment = node_.ShouldApplySizeContainment();
- // TODO(crbug.com/1011842): Need to consider content-size here.
- if (apply_size_containment) {
- if (input.size_type == NGMinMaxSizeType::kContentBoxSize)
- return sizes;
+ if (legend_needs_layout) {
+ NGBreakStatus break_status = LayoutLegend(legend, legend_break_token);
+ if (break_status != NGBreakStatus::kContinue)
+ return break_status;
+ }
+
+ borders_with_legend_ = borders_;
+ borders_with_legend_.block_start = block_start_padding_edge_;
+
+ // The legend may eat from the available content box block size. If the
+ // border_box_size_ is expanded to encompass the legend, then update the
+ // border_box_size_ here, as well, to ensure the fieldset content gets the
+ // correct size.
+ if (!Node().ShouldApplySizeContainment() && legend_needs_layout) {
+ minimum_border_box_block_size_ =
+ borders_with_legend_.BlockSum() + padding_.BlockSum();
+ if (border_box_size_.block_size != kIndefiniteSize) {
+ border_box_size_.block_size =
+ std::max(border_box_size_.block_size, minimum_border_box_block_size_);
+ }
+ }
+
+ LogicalSize adjusted_padding_box_size =
+ ShrinkAvailableSize(border_box_size_, borders_with_legend_);
+
+ // If the legend has been laid out in previous fragments,
+ // adjusted_padding_box_size will need to be adjusted further to account for
+ // block size taken up by the legend.
+ if (legend && adjusted_padding_box_size.block_size != kIndefiniteSize) {
+ LayoutUnit content_consumed_block_size =
+ content_break_token ? content_break_token->ConsumedBlockSize()
+ : LayoutUnit();
+ LayoutUnit legend_block_size =
+ consumed_block_size_ - content_consumed_block_size;
+ adjusted_padding_box_size.block_size =
+ std::max(padding_.BlockSum(),
+ adjusted_padding_box_size.block_size - legend_block_size);
+ }
+
+ if ((IsResumingLayout(content_break_token.get())) ||
+ (!block_start_padding_edge_adjusted_ && IsResumingLayout(BreakToken()))) {
+ borders_with_legend_.block_start = LayoutUnit();
+ }
+ intrinsic_block_size_ = borders_with_legend_.BlockSum();
+
+ // Proceed with normal fieldset children (excluding the rendered legend). They
+ // all live inside an anonymous child box of the fieldset container.
+ auto fieldset_content = Node().GetFieldsetContent();
+ if (fieldset_content && (content_break_token || !has_seen_all_children)) {
+ LayoutUnit fragmentainer_block_offset;
+ if (ConstraintSpace().HasBlockFragmentation()) {
+ fragmentainer_block_offset =
+ ConstraintSpace().FragmentainerOffsetAtBfc() + intrinsic_block_size_;
+ if (legend_broke_ &&
+ IsFragmentainerOutOfSpace(fragmentainer_block_offset))
+ return NGBreakStatus::kContinue;
+ }
+ NGBreakStatus break_status = LayoutFieldsetContent(
+ fieldset_content, content_break_token, adjusted_padding_box_size,
+ fragmentainer_block_offset, !!legend);
+ if (break_status == NGBreakStatus::kNeedsEarlierBreak)
+ return break_status;
+ }
+
+ if (!fieldset_content) {
+ container_builder_.SetHasSeenAllChildren();
+ // There was no anonymous child to provide the padding, so we have to add it
+ // ourselves.
+ intrinsic_block_size_ += padding_.BlockSum();
}
+ return NGBreakStatus::kContinue;
+}
+
+NGBreakStatus NGFieldsetLayoutAlgorithm::LayoutLegend(
+ NGBlockNode& legend,
+ scoped_refptr<const NGBlockBreakToken> legend_break_token) {
+ // 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);
+ NGBoxStrut legend_margins = ComputeMarginsFor(
+ legend.Style(), percentage_size.inline_size,
+ ConstraintSpace().GetWritingMode(), ConstraintSpace().Direction());
+
+ if (legend_break_token)
+ legend_margins.block_start = LayoutUnit();
+
+ LogicalOffset legend_offset;
+ scoped_refptr<const NGLayoutResult> result;
+ scoped_refptr<const NGLayoutResult> previous_result;
+ LayoutUnit block_offset = legend_margins.block_start;
+ do {
+ auto legend_space = CreateConstraintSpaceForLegend(
+ legend, content_box_size, percentage_size, block_offset);
+ result = legend.Layout(legend_space, legend_break_token.get());
+
+ // TODO(layout-dev): Handle abortions caused by block fragmentation.
+ DCHECK_EQ(result->Status(), NGLayoutResult::kSuccess);
+
+ if (ConstraintSpace().HasBlockFragmentation()) {
+ NGBreakStatus break_status = BreakBeforeChildIfNeeded(
+ ConstraintSpace(), legend, *result.get(),
+ ConstraintSpace().FragmentainerOffsetAtBfc() + block_offset,
+ /*has_container_separation*/ false, &container_builder_);
+ if (break_status != NGBreakStatus::kContinue)
+ return break_status;
+ EBreakBetween break_after = JoinFragmentainerBreakValues(
+ result->FinalBreakAfter(), legend.Style().BreakAfter());
+ container_builder_.SetPreviousBreakAfter(break_after);
+ }
+
+ const auto& physical_fragment = result->PhysicalFragment();
+ legend_broke_ = physical_fragment.BreakToken();
+
+ // We have already adjusted the legend block offset, no need to adjust
+ // again.
+ if (block_offset != legend_margins.block_start) {
+ // If adjusting the block_offset caused the legend to break, revert back
+ // to the previous result.
+ if (legend_broke_) {
+ result = std::move(previous_result);
+ block_offset = legend_margins.block_start;
+ }
+ break;
+ }
+
+ LayoutUnit legend_margin_box_block_size =
+ NGFragment(writing_mode_, physical_fragment).BlockSize() +
+ legend_margins.BlockSum();
+ LayoutUnit space_left = borders_.block_start - legend_margin_box_block_size;
+ if (space_left > LayoutUnit()) {
+ // Don't adjust the block_offset if the legend broke.
+ if (legend_break_token || legend_broke_)
+ break;
+
+ // If the border is the larger one, though, it will stay put at the
+ // border-box block-start edge of the fieldset. Then it's the legend
+ // that needs to be pushed. We'll center the margin box in this case, to
+ // make sure that both margins remain within the area occupied by the
+ // border also after adjustment.
+ block_offset += space_left / 2;
+ if (ConstraintSpace().HasBlockFragmentation()) {
+ // Save the previous result in case adjusting the block_offset causes
+ // the legend to break.
+ previous_result = std::move(result);
+ continue;
+ }
+ } else {
+ // If the legend is larger than the width of the fieldset block-start
+ // border, the actual padding edge of the fieldset will be moved
+ // accordingly. This will be the block-start offset for the fieldset
+ // contents anonymous box.
+ block_start_padding_edge_ = legend_margin_box_block_size;
+ block_start_padding_edge_adjusted_ = true;
+ }
+ break;
+ } while (true);
+
+ // If the margin box of the legend is at least as tall as the fieldset
+ // block-start border width, it will start at the block-start border edge
+ // of the fieldset. As a paint effect, the block-start border will be
+ // pushed so that the center of the border will be flush with the center
+ // of the border-box of the legend.
+ // TODO(mstensho): inline alignment
+ legend_offset = LogicalOffset(
+ adjusted_border_padding_.inline_start + legend_margins.inline_start,
+ block_offset);
+
+ container_builder_.AddResult(*result, legend_offset);
+ return NGBreakStatus::kContinue;
+}
+
+NGBreakStatus NGFieldsetLayoutAlgorithm::LayoutFieldsetContent(
+ NGBlockNode& fieldset_content,
+ scoped_refptr<const NGBlockBreakToken> content_break_token,
+ LogicalSize adjusted_padding_box_size,
+ LayoutUnit fragmentainer_block_offset,
+ bool has_legend) {
+ auto child_space = CreateConstraintSpaceForFieldsetContent(
+ fieldset_content, adjusted_padding_box_size,
+ borders_with_legend_.block_start);
+ auto result = fieldset_content.Layout(child_space, content_break_token.get());
+
+ // TODO(layout-dev): Handle abortions caused by block fragmentation.
+ DCHECK_EQ(result->Status(), NGLayoutResult::kSuccess);
+
+ NGBreakStatus break_status = NGBreakStatus::kContinue;
+ if (ConstraintSpace().HasBlockFragmentation()) {
+ // TODO(almaher): The legend should be treated as out-of-flow.
+ break_status = BreakBeforeChildIfNeeded(
+ ConstraintSpace(), fieldset_content, *result.get(),
+ fragmentainer_block_offset,
+ /*has_container_separation*/ has_legend, &container_builder_);
+ EBreakBetween break_after = JoinFragmentainerBreakValues(
+ result->FinalBreakAfter(), fieldset_content.Style().BreakAfter());
+ container_builder_.SetPreviousBreakAfter(break_after);
+ }
+
+ if (break_status == NGBreakStatus::kContinue) {
+ container_builder_.AddResult(*result, borders_with_legend_.StartOffset());
+ intrinsic_block_size_ +=
+ NGFragment(writing_mode_, result->PhysicalFragment()).BlockSize();
+ container_builder_.SetHasSeenAllChildren();
+ }
+
+ return break_status;
+}
+
+bool NGFieldsetLayoutAlgorithm::IsFragmentainerOutOfSpace(
+ LayoutUnit block_offset) const {
+ if (!ConstraintSpace().HasKnownFragmentainerBlockSize())
+ return false;
+ return block_offset >= FragmentainerSpaceAtBfcStart(ConstraintSpace());
+}
+
+base::Optional<MinMaxSizes> NGFieldsetLayoutAlgorithm::ComputeMinMaxSizes(
+ const MinMaxSizesInput& input) const {
+ MinMaxSizes sizes;
+
+ // TODO(crbug.com/1011842): Need to consider content-size here.
+ bool apply_size_containment = Node().ShouldApplySizeContainment();
+
// Size containment does not consider the legend for sizing.
if (!apply_size_containment) {
if (NGBlockNode legend = Node().GetRenderedLegend()) {
@@ -170,42 +387,51 @@ base::Optional<MinMaxSize> NGFieldsetLayoutAlgorithm::ComputeMinMaxSize(
// The fieldset content includes the fieldset padding (and any scrollbars),
// while the legend is a regular child and doesn't. We may have a fieldset
// without any content or legend, so add the padding here, on the outside.
- sizes += ComputePadding(ConstraintSpace(), node_.Style()).InlineSum();
+ sizes += ComputePadding(ConstraintSpace(), Style()).InlineSum();
// Size containment does not consider the content for sizing.
if (!apply_size_containment) {
if (NGBlockNode content = Node().GetFieldsetContent()) {
- MinMaxSize content_minmax =
+ MinMaxSizes content_min_max_sizes =
ComputeMinAndMaxContentContribution(Style(), content, input);
- content_minmax += ComputeMinMaxMargins(Style(), content).InlineSum();
- sizes.Encompass(content_minmax);
+ content_min_max_sizes +=
+ ComputeMinMaxMargins(Style(), content).InlineSum();
+ sizes.Encompass(content_min_max_sizes);
}
}
- sizes += ComputeBorders(ConstraintSpace(), node_).InlineSum();
+ sizes += ComputeBorders(ConstraintSpace(), Style()).InlineSum();
return sizes;
}
const NGConstraintSpace
NGFieldsetLayoutAlgorithm::CreateConstraintSpaceForLegend(
NGBlockNode legend,
- LogicalSize available_size) {
+ LogicalSize available_size,
+ LogicalSize percentage_size,
+ LayoutUnit block_offset) {
NGConstraintSpaceBuilder builder(
ConstraintSpace(), legend.Style().GetWritingMode(), /* is_new_fc */ true);
SetOrthogonalFallbackInlineSizeIfNeeded(Style(), legend, &builder);
builder.SetAvailableSize(available_size);
- LogicalSize percentage_size =
- CalculateChildPercentageSize(ConstraintSpace(), Node(), available_size);
builder.SetPercentageResolutionSize(percentage_size);
builder.SetIsShrinkToFit(legend.Style().LogicalWidth().IsAuto());
builder.SetTextDirection(legend.Style().Direction());
+
+ if (ConstraintSpace().HasBlockFragmentation()) {
+ SetupFragmentation(ConstraintSpace(), legend, block_offset, &builder,
+ /* is_new_fc */ true);
+ builder.SetEarlyBreakAppeal(container_builder_.BreakAppeal());
+ }
return builder.ToConstraintSpace();
}
const NGConstraintSpace
NGFieldsetLayoutAlgorithm::CreateConstraintSpaceForFieldsetContent(
- LogicalSize padding_box_size) {
+ NGBlockNode fieldset_content,
+ LogicalSize padding_box_size,
+ LayoutUnit block_offset) {
NGConstraintSpaceBuilder builder(ConstraintSpace(),
ConstraintSpace().GetWritingMode(),
/* is_new_fc */ true);
@@ -213,6 +439,12 @@ NGFieldsetLayoutAlgorithm::CreateConstraintSpaceForFieldsetContent(
builder.SetPercentageResolutionSize(
ConstraintSpace().PercentageResolutionSize());
builder.SetIsFixedBlockSize(padding_box_size.block_size != kIndefiniteSize);
+
+ if (ConstraintSpace().HasBlockFragmentation()) {
+ SetupFragmentation(ConstraintSpace(), fieldset_content, block_offset,
+ &builder, /* is_new_fc */ true);
+ builder.SetEarlyBreakAppeal(container_builder_.BreakAppeal());
+ }
return builder.ToConstraintSpace();
}
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 df5a8d3538b..c375081737a 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
@@ -12,6 +12,7 @@
namespace blink {
+enum class NGBreakStatus;
class NGBlockBreakToken;
class NGConstraintSpace;
@@ -24,16 +25,63 @@ class CORE_EXPORT NGFieldsetLayoutAlgorithm
scoped_refptr<const NGLayoutResult> Layout() override;
- base::Optional<MinMaxSize> ComputeMinMaxSize(
- const MinMaxSizeInput&) const override;
+ base::Optional<MinMaxSizes> ComputeMinMaxSizes(
+ const MinMaxSizesInput&) const override;
+
+ private:
+ NGBreakStatus LayoutChildren();
+ NGBreakStatus LayoutLegend(
+ NGBlockNode& legend,
+ scoped_refptr<const NGBlockBreakToken> legend_break_token);
+ NGBreakStatus LayoutFieldsetContent(
+ NGBlockNode& fieldset_content,
+ scoped_refptr<const NGBlockBreakToken> content_break_token,
+ LogicalSize adjusted_padding_box_size,
+ LayoutUnit fragmentainer_block_offset,
+ bool has_legend);
const NGConstraintSpace CreateConstraintSpaceForLegend(
NGBlockNode legend,
- LogicalSize available_size);
+ LogicalSize available_size,
+ LogicalSize percentage_size,
+ LayoutUnit block_offset);
const NGConstraintSpace CreateConstraintSpaceForFieldsetContent(
- LogicalSize padding_box_size);
+ NGBlockNode fieldset_content,
+ LogicalSize padding_box_size,
+ LayoutUnit block_offset);
+
+ bool IsFragmentainerOutOfSpace(LayoutUnit block_offset) const;
+
+ const WritingMode writing_mode_;
const NGBoxStrut border_padding_;
+ NGBoxStrut borders_;
+ NGBoxStrut padding_;
+
+ // The border and padding after adjusting to ensure that the leading border
+ // and padding are only applied to the first fragment.
+ NGBoxStrut adjusted_border_padding_;
+
+ // The result of borders_ after positioning the fieldset's legend element.
+ NGBoxStrut borders_with_legend_;
+
+ LayoutUnit block_start_padding_edge_;
+ LayoutUnit intrinsic_block_size_;
+ const LayoutUnit consumed_block_size_;
+ LogicalSize border_box_size_;
+
+ // The legend may eat from the available content box block size. This
+ // represents the minimum block size needed by the border box to encompass
+ // the legend.
+ LayoutUnit minimum_border_box_block_size_;
+
+ // If true, this indicates the block_start_padding_edge_ had changed from its
+ // initial value during the current layout pass.
+ bool block_start_padding_edge_adjusted_ = false;
+
+ // If true, this indicates that the legend broke during the current layout
+ // pass.
+ bool legend_broke_ = 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 ab1718db0e4..36789003311 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
@@ -35,25 +35,26 @@ class NGFieldsetLayoutAlgorithmTest
return NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithm(container, space);
}
- MinMaxSize RunComputeMinAndMax(NGBlockNode node) {
+ MinMaxSizes RunComputeMinMaxSizes(NGBlockNode node) {
NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
WritingMode::kHorizontalTb, TextDirection::kLtr,
- LogicalSize(LayoutUnit(), LayoutUnit()));
+ LogicalSize(LayoutUnit(), LayoutUnit()), false,
+ node.CreatesNewFormattingContext());
NGFragmentGeometry fragment_geometry =
CalculateInitialMinMaxFragmentGeometry(space, node);
NGFieldsetLayoutAlgorithm algorithm({node, fragment_geometry, space});
- MinMaxSizeInput input(
+ MinMaxSizesInput input(
/* percentage_resolution_block_size */ (LayoutUnit()));
- auto min_max = algorithm.ComputeMinMaxSize(input);
+ auto min_max = algorithm.ComputeMinMaxSizes(input);
EXPECT_TRUE(min_max.has_value());
return *min_max;
}
- MinMaxSize RunComputeMinAndMax(const char* element_id) {
+ MinMaxSizes RunComputeMinMaxSizes(const char* element_id) {
Element* element = GetDocument().getElementById(element_id);
NGBlockNode node(ToLayoutBox(element->GetLayoutObject()));
- return RunComputeMinAndMax(node);
+ return RunComputeMinMaxSizes(node);
}
String DumpFragmentTree(const NGPhysicalBoxFragment* fragment) {
@@ -349,7 +350,7 @@ TEST_F(NGFieldsetLayoutAlgorithmTest, ZeroHeight) {
offset:unplaced size:1000x53
offset:0,0 size:126x53
offset:13,0 size:30x30
- offset:3,30 size:120x0
+ offset:3,30 size:120x20
offset:10,10 size:100x200
)DUMP";
EXPECT_EQ(expectation, dump);
@@ -444,6 +445,46 @@ TEST_F(NGFieldsetLayoutAlgorithmTest, LegendPercentHeightQuirks) {
EXPECT_EQ(expectation, dump);
}
+// This test makes sure that the fieldset content handles fieldset padding
+// when the fieldset is expanded to encompass the legend.
+TEST_F(NGFieldsetLayoutAlgorithmTest, FieldsetPaddingWithLegend) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset {
+ border:none; margin:0; padding:10px; width: 150px; height: 100px;
+ }
+ #legend {
+ padding:0px; margin:0; width: 50px; height: 120px;
+ }
+ #child {
+ width: 100px; height: 40px;
+ }
+ </style>
+ <fieldset id="fieldset">
+ <legend id="legend"></legend>
+ <div id="child"></div>
+ </fieldset>
+ )HTML");
+
+ NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("fieldset")));
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(1000), kIndefiniteSize), false,
+ node.CreatesNewFormattingContext());
+
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
+ NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
+
+ String dump = DumpFragmentTree(fragment.get());
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:170x140
+ offset:10,0 size:50x120
+ offset:0,120 size:170x20
+ offset:10,10 size:100x40
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
TEST_F(NGFieldsetLayoutAlgorithmTest, MinMax) {
SetBodyInnerHTML(R"HTML(
<style>
@@ -483,31 +524,1455 @@ TEST_F(NGFieldsetLayoutAlgorithmTest, MinMax) {
</div>
)HTML");
- MinMaxSize size;
+ MinMaxSizes sizes;
+
+ sizes = RunComputeMinMaxSizes("fieldset1");
+ EXPECT_EQ(sizes.min_size, LayoutUnit(26));
+ EXPECT_EQ(sizes.max_size, LayoutUnit(26));
+
+ sizes = RunComputeMinMaxSizes("fieldset2");
+ EXPECT_EQ(sizes.min_size, LayoutUnit(102));
+ EXPECT_EQ(sizes.max_size, LayoutUnit(102));
+
+ sizes = RunComputeMinMaxSizes("fieldset3");
+ EXPECT_EQ(sizes.min_size, LayoutUnit(102));
+ EXPECT_EQ(sizes.max_size, LayoutUnit(126));
+
+ sizes = RunComputeMinMaxSizes("fieldset4");
+ EXPECT_EQ(sizes.min_size, LayoutUnit(152));
+ EXPECT_EQ(sizes.max_size, LayoutUnit(202));
+
+ sizes = RunComputeMinMaxSizes("fieldset5");
+ EXPECT_EQ(sizes.min_size, LayoutUnit(152));
+ EXPECT_EQ(sizes.max_size, LayoutUnit(176));
+
+ sizes = RunComputeMinMaxSizes("fieldset6");
+ EXPECT_EQ(sizes.min_size, LayoutUnit(76));
+ EXPECT_EQ(sizes.max_size, LayoutUnit(126));
+}
+
+// Tests that a fieldset won't fragment if it doesn't reach the fragmentation
+// line.
+TEST_F(NGFieldsetLayoutAlgorithmTest, NoFragmentation) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ fieldset {
+ border:3px solid; margin:0; padding:10px; width: 150px; height: 100px;
+ }
+ </style>
+ <fieldset id="fieldset"></fieldset>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(200);
+
+ NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("fieldset")));
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(1000), kIndefiniteSize), false,
+ node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
+
+ // We should only have one 176x126 fragment with no fragmentation.
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
+ NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
+ EXPECT_EQ(PhysicalSize(176, 126), fragment->Size());
+ ASSERT_FALSE(fragment->BreakToken());
+}
+
+// Tests that a fieldset will fragment if it reaches the fragmentation line.
+TEST_F(NGFieldsetLayoutAlgorithmTest, SimpleFragmentation) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset {
+ border:3px solid; margin:0; padding:10px; width: 150px; height: 500px;
+ }
+ </style>
+ <fieldset id="fieldset"></fieldset>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(200);
+
+ NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("fieldset")));
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(1000), kIndefiniteSize), false,
+ node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
+
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
+ NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
+ EXPECT_EQ(PhysicalSize(176, 200), fragment->Size());
+ ASSERT_TRUE(fragment->BreakToken());
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ EXPECT_EQ(PhysicalSize(176, 200), fragment->Size());
+ ASSERT_TRUE(fragment->BreakToken());
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ EXPECT_EQ(PhysicalSize(176, 126), fragment->Size());
+ ASSERT_FALSE(fragment->BreakToken());
+}
+
+// Tests that a fieldset with no content or padding will fragment if it reaches
+// the fragmentation line.
+TEST_F(NGFieldsetLayoutAlgorithmTest, FragmentationNoPadding) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset { margin:0; border:10px solid; padding:0px; width:100px; }
+ </style>
+ <fieldset id="fieldset"></fieldset>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(10);
+
+ NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("fieldset")));
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(1000), kIndefiniteSize), false,
+ node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
+
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
+ NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
+ ASSERT_TRUE(fragment->BreakToken());
+
+ String dump = DumpFragmentTree(fragment.get());
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:120x10
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_FALSE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:120x10
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+// Tests that a fieldset with auto height will fragment when its content reaches
+// the fragmentation line.
+TEST_F(NGFieldsetLayoutAlgorithmTest, FieldsetContentFragmentationAutoHeight) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset {
+ border:3px solid; margin:0; padding:10px; width: 150px;
+ }
+ #child {
+ margin:0; width: 50px; height: 500px;
+ }
+ </style>
+ <fieldset id="fieldset">
+ <div id="child"></div>
+ </fieldset>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(200);
+
+ NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("fieldset")));
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(1000), kIndefiniteSize), false,
+ node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
+
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
+ NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
+ ASSERT_TRUE(fragment->BreakToken());
+
+ String dump = DumpFragmentTree(fragment.get());
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:176x200
+ offset:3,3 size:170x197
+ offset:10,10 size:50x187
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_TRUE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:176x200
+ offset:3,0 size:170x200
+ offset:10,0 size:50x200
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_FALSE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:176x126
+ offset:3,0 size:170x123
+ offset:10,0 size:50x113
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+// Tests that a fieldset with a set height will fragment when its content
+// reaches the fragmentation line.
+TEST_F(NGFieldsetLayoutAlgorithmTest, FieldsetContentFragmentation) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset {
+ border:3px solid; margin:0; padding:10px; width: 150px; height: 100px;
+ }
+ #child {
+ margin:0; width: 50px; height: 500px;
+ }
+ </style>
+ <fieldset id="fieldset">
+ <div id="child"></div>
+ </fieldset>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(200);
+
+ NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("fieldset")));
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(1000), kIndefiniteSize), false,
+ node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
+
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
+ NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
+ ASSERT_TRUE(fragment->BreakToken());
+
+ String dump = DumpFragmentTree(fragment.get());
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:176x126
+ offset:3,3 size:170x120
+ offset:10,10 size:50x187
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_TRUE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:176x0
+ offset:3,0 size:170x0
+ offset:10,0 size:50x200
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_FALSE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:176x0
+ offset:3,0 size:170x0
+ offset:10,0 size:50x113
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+// Tests that a fieldset with auto height will fragment when its legend reaches
+// the fragmentation line.
+TEST_F(NGFieldsetLayoutAlgorithmTest, LegendFragmentationAutoHeight) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset {
+ border:3px solid; margin:0; padding:10px; width: 150px;
+ }
+ #legend {
+ padding:0px; margin:0; width: 50px; height: 500px;
+ }
+ </style>
+ <fieldset id="fieldset">
+ <legend id="legend"></legend>
+ </fieldset>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(200);
+
+ NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("fieldset")));
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(1000), kIndefiniteSize), false,
+ node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
+
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
+ NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
+ ASSERT_TRUE(fragment->BreakToken());
+
+ String dump = DumpFragmentTree(fragment.get());
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:176x200
+ offset:13,0 size:50x200
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_TRUE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:176x200
+ offset:13,0 size:50x200
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_FALSE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:176x123
+ offset:13,0 size:50x100
+ offset:3,100 size:170x20
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+// Tests that a fieldset with a set height will fragment when its legend
+// reaches the fragmentation line. The used height should also be extended to
+// encompass the legend.
+TEST_F(NGFieldsetLayoutAlgorithmTest, LegendFragmentation) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset {
+ border:3px solid; margin:0; padding:10px; width: 150px; height: 100px;
+ }
+ #legend {
+ padding:0px; margin:0; width: 50px; height: 500px;
+ }
+ </style>
+ <fieldset id="fieldset">
+ <legend id="legend"></legend>
+ </fieldset>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(200);
+
+ NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("fieldset")));
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(1000), kIndefiniteSize), false,
+ node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
+
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
+ NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
+ ASSERT_TRUE(fragment->BreakToken());
+
+ String dump = DumpFragmentTree(fragment.get());
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:176x200
+ offset:13,0 size:50x200
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_TRUE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:176x200
+ offset:13,0 size:50x200
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_FALSE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:176x123
+ offset:13,0 size:50x100
+ offset:3,100 size:170x20
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+// Tests that a fieldset with auto height will fragment when its legend/content
+// reaches the fragmentation line.
+TEST_F(NGFieldsetLayoutAlgorithmTest, LegendAndContentFragmentationAutoHeight) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset {
+ border:3px solid; margin:0; padding:10px; width: 150px;
+ }
+ #legend {
+ padding:0px; margin:0; width: 50px; height: 500px;
+ }
+ #child {
+ margin:0; width: 100px; height: 200px;
+ }
+ </style>
+ <fieldset id="fieldset">
+ <legend id="legend"></legend>
+ <div id="child"></div>
+ </fieldset>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(200);
+
+ NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("fieldset")));
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(1000), kIndefiniteSize), false,
+ node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
+
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
+ NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
+ ASSERT_TRUE(fragment->BreakToken());
+
+ String dump = DumpFragmentTree(fragment.get());
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:176x200
+ offset:13,0 size:50x200
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_TRUE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:176x200
+ offset:13,0 size:50x200
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_TRUE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:176x200
+ offset:13,0 size:50x100
+ offset:3,100 size:170x100
+ offset:10,10 size:100x90
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_FALSE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:176x123
+ offset:3,0 size:170x120
+ offset:10,0 size:100x110
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+// Tests that a fieldset with a set height will fragment when its legend/content
+// reaches the fragmentation line.
+TEST_F(NGFieldsetLayoutAlgorithmTest, LegendAndContentFragmentation) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset {
+ border:3px solid; margin:0; padding:10px; width: 150px; height: 100px;
+ }
+ #legend {
+ padding:0px; margin:0; width: 50px; height: 500px;
+ }
+ #child {
+ margin:0; width: 100px; height: 200px;
+ }
+ </style>
+ <fieldset id="fieldset">
+ <legend id="legend"></legend>
+ <div id="child"></div>
+ </fieldset>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(200);
+
+ NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("fieldset")));
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(1000), kIndefiniteSize), false,
+ node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
+
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
+ NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
+ ASSERT_TRUE(fragment->BreakToken());
+
+ String dump = DumpFragmentTree(fragment.get());
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:176x200
+ offset:13,0 size:50x200
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_TRUE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:176x200
+ offset:13,0 size:50x200
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_TRUE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:176x123
+ offset:13,0 size:50x100
+ offset:3,100 size:170x20
+ offset:10,10 size:100x90
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_FALSE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:176x0
+ offset:3,0 size:170x0
+ offset:10,0 size:100x110
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+// Tests fragmentation when a legend's child content overflows.
+TEST_F(NGFieldsetLayoutAlgorithmTest, LegendFragmentationWithOverflow) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ fieldset, legend { margin:0; border:none; padding:0; }
+ </style>
+ <fieldset id="fieldset">
+ <legend style="height:30px;">
+ <div style="width:55px; height:150px;"></div>
+ </legend>
+ <div style="width:44px; height:150px;"></div>
+ </div>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(100);
+
+ NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("fieldset")));
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(1000), kIndefiniteSize), false,
+ node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
+
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
+ NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
+ ASSERT_TRUE(fragment->BreakToken());
+
+ String dump = DumpFragmentTree(fragment.get());
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:1000x100
+ offset:0,0 size:55x30
+ offset:0,0 size:55x100
+ offset:0,30 size:1000x70
+ offset:0,0 size:44x70
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_FALSE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:1000x80
+ offset:0,0 size:55x0
+ offset:0,0 size:55x50
+ offset:0,0 size:1000x80
+ offset:0,0 size:44x80
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+// Tests that fragmentation works as expected when the fieldset content has a
+// negative margin block start.
+TEST_F(NGFieldsetLayoutAlgorithmTest,
+ LegendAndContentFragmentationNegativeMargin) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset {
+ border:none; margin:0; padding:0px; width: 150px; height: 100px;
+ }
+ #legend {
+ padding:0px; margin:0; width: 50px; height: 100px;
+ }
+ #child {
+ margin-top: -20px; width: 100px; height: 40px;
+ }
+ </style>
+ <fieldset id="fieldset">
+ <legend id="legend"></legend>
+ <div id="child"></div>
+ </fieldset>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(100);
+
+ NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("fieldset")));
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(1000), kIndefiniteSize), false,
+ node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
+
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
+ NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
+ ASSERT_TRUE(fragment->BreakToken());
+
+ String dump = DumpFragmentTree(fragment.get());
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:150x100
+ offset:0,0 size:50x100
+ offset:0,100 size:150x0
+ offset:0,-20 size:100x20
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_FALSE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:150x0
+ offset:0,0 size:150x0
+ offset:0,0 size:100x20
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+TEST_F(NGFieldsetLayoutAlgorithmTest, OverflowedLegend) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset {
+ border:none; margin:0; padding:0px; width: 100px; height: 100px;
+ }
+ #legend {
+ padding:0px; margin:0px;
+ }
+ </style>
+ <fieldset id="fieldset">
+ <legend id="legend" style="width:75%; height:60px;">
+ <div id="grandchild1" style="width:50px; height:120px;"></div>
+ <div id="grandchild2" style="width:40px; height:20px;"></div>
+ </legend>
+ <div id="child" style="width:85%; height:10px;"></div>
+ </fieldset>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(100);
+
+ NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("fieldset")));
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(1000), kIndefiniteSize), false,
+ node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
+
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
+ NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
+ ASSERT_TRUE(fragment->BreakToken());
+
+ String dump = DumpFragmentTree(fragment.get());
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:100x100
+ offset:0,0 size:75x60
+ offset:0,0 size:50x100
+ offset:0,60 size:100x40
+ offset:0,0 size:85x10
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_FALSE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:100x0
+ offset:0,0 size:75x0
+ offset:0,0 size:50x20
+ offset:0,20 size:40x20
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+TEST_F(NGFieldsetLayoutAlgorithmTest, OverflowedFieldsetContent) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset {
+ border:none; margin:0; padding:0px; width: 100px; height: 100px;
+ }
+ #legend {
+ padding:0px; margin:0px;
+ }
+ </style>
+ <fieldset id="fieldset">
+ <legend id="legend" style="width:75%; height:10px;">
+ <div style="width:50px; height:220px;"></div>
+ </legend>
+ <div style="width:85%; height:10px;"></div>
+ <div id="child" style="width:65%; height:10px;">
+ <div style="width:51px; height:220px;"></div>
+ </div>
+ </fieldset>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(100);
+
+ NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("fieldset")));
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(1000), kIndefiniteSize), false,
+ node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
+
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
+ NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
+ ASSERT_TRUE(fragment->BreakToken());
+
+ String dump = DumpFragmentTree(fragment.get());
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:100x100
+ offset:0,0 size:75x10
+ offset:0,0 size:50x100
+ offset:0,10 size:100x90
+ offset:0,0 size:85x10
+ offset:0,10 size:65x10
+ offset:0,0 size:51x80
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_TRUE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:100x0
+ offset:0,0 size:75x0
+ offset:0,0 size:50x100
+ offset:0,0 size:100x0
+ offset:0,0 size:65x0
+ offset:0,0 size:51x100
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_FALSE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:100x0
+ offset:0,0 size:75x0
+ offset:0,0 size:50x20
+ offset:0,0 size:100x0
+ offset:0,0 size:65x0
+ offset:0,0 size:51x40
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+TEST_F(NGFieldsetLayoutAlgorithmTest, BreakInsideAvoid) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset {
+ border:none; margin:0; padding:0px; width: 100px; height: 100px;
+ }
+ #legend {
+ padding:0px; margin:0px;
+ }
+ </style>
+ <fieldset id="fieldset">
+ <legend id="legend" style="width:10px; height:50px;"></legend>
+ <div style="break-inside:avoid; width:20px; height:70px;"></div>
+ </fieldset>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(100);
+
+ NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("fieldset")));
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(1000), kIndefiniteSize), false,
+ node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
+
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
+ NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
+ ASSERT_TRUE(fragment->BreakToken());
+
+ String dump = DumpFragmentTree(fragment.get());
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:100x100
+ offset:0,0 size:10x50
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_FALSE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:100x0
+ offset:0,0 size:100x0
+ offset:0,0 size:20x70
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+TEST_F(NGFieldsetLayoutAlgorithmTest, BreakInsideAvoidTallBlock) {
+ // The block that has break-inside:avoid is too tall to fit in one
+ // fragmentainer. So a break is unavoidable. Let's check that:
+ // 1. The block is still shifted to the start of the next fragmentainer
+ // 2. We give up shifting it any further (would cause infinite an loop)
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset {
+ border:none; margin:0; padding:0px; width: 100px; height: 100px;
+ }
+ #legend {
+ padding:0px; margin:0px;
+ }
+ </style>
+ <fieldset id="fieldset">
+ <legend id="legend" style="width:10px; height:50px;"></legend>
+ <div style="break-inside:avoid; width:20px; height:170px;"></div>
+ </fieldset>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(100);
+
+ NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("fieldset")));
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(1000), kIndefiniteSize), false,
+ node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
+
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
+ NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
+ ASSERT_TRUE(fragment->BreakToken());
+
+ String dump = DumpFragmentTree(fragment.get());
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:100x100
+ offset:0,0 size:10x50
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_TRUE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:100x0
+ offset:0,0 size:100x0
+ offset:0,0 size:20x100
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_FALSE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:100x0
+ offset:0,0 size:100x0
+ offset:0,0 size:20x70
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+TEST_F(NGFieldsetLayoutAlgorithmTest, LegendBreakInsideAvoid) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset {
+ border:none; margin:0; padding:0px; width: 100px; height: 50px;
+ }
+ #legend {
+ padding:0px; margin:0px;
+ }
+ </style>
+ <div id="container">
+ <div style="width:20px; height:50px;"></div>
+ <fieldset id="fieldset">
+ <legend id="legend" style="break-inside:avoid; width:10px; height:60px;">
+ </legend>
+ </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:1000x100
+ offset:0,0 size:20x50
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_FALSE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:1000x60
+ offset:0,0 size:100x60
+ offset:0,0 size:10x60
+ offset:0,60 size:100x0
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+TEST_F(NGFieldsetLayoutAlgorithmTest, BreakBeforeAvoid) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset {
+ border:none; margin:0; padding:0px; width: 100px;
+ }
+ #legend {
+ padding:0px; margin:0px;
+ }
+ </style>
+ <div id="container">
+ <div style="width:20px; height:50px;"></div>
+ <fieldset id="fieldset">
+ <legend id="legend" style="width:10px; height:25px;"></legend>
+ <div style="width:30px; height:25px;"></div>
+ <div style="break-before:avoid; width:15px; height:25px;"></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:1000x75
+ offset:0,0 size:20x50
+ offset:0,50 size:100x25
+ offset:0,0 size:10x25
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_FALSE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:1000x50
+ offset:0,0 size:100x50
+ offset:0,0 size:100x50
+ offset:0,0 size:30x25
+ offset:0,25 size:15x25
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+TEST_F(NGFieldsetLayoutAlgorithmTest, LegendBreakBeforeAvoid) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset {
+ border:10px solid; margin:0; padding:0px; width: 100px;
+ }
+ #legend {
+ padding:0px; margin:10px; width:10px; height:25px;
+ }
+ </style>
+ <div id="container">
+ <div style="width:20px; height:90px;"></div>
+ <fieldset id="fieldset">
+ <legend id="legend" style="break-before:avoid;"></legend>
+ </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:1000x100
+ offset:0,0 size:20x90
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_FALSE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:1000x55
+ offset:0,0 size:120x55
+ offset:20,10 size:10x25
+ offset:10,45 size:100x0
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+TEST_F(NGFieldsetLayoutAlgorithmTest, BreakAfterAvoid) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset {
+ border:none; margin:0; padding:0px; width: 100px;
+ }
+ #legend {
+ padding:0px; margin:0px;
+ }
+ </style>
+ <div id="container">
+ <div style="width:20px; height:50px;"></div>
+ <fieldset id="fieldset">
+ <legend id="legend" style="width:10px; height:25px;"></legend>
+ <div style="break-after:avoid; width:30px; height:25px;"></div>
+ <div style="width:15px; height:25px;"></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:1000x75
+ offset:0,0 size:20x50
+ offset:0,50 size:100x25
+ offset:0,0 size:10x25
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_FALSE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:1000x50
+ offset:0,0 size:100x50
+ offset:0,0 size:100x50
+ offset:0,0 size:30x25
+ offset:0,25 size:15x25
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+TEST_F(NGFieldsetLayoutAlgorithmTest, LegendBreakAfterAvoid) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset {
+ border:0px solid; margin:0; padding:0px; width: 100px;
+ }
+ #legend {
+ padding:0px; margin:0px; width:10px; height:50px;
+ }
+ </style>
+ <div id="container">
+ <div style="width:20px; height:50px;"></div>
+ <fieldset id="fieldset">
+ <legend id="legend" style="break-after:avoid;"></legend>
+ <div style="width:15px; height:25px;"></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:1000x100
+ offset:0,0 size:20x50
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunBlockLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_FALSE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:1000x75
+ offset:0,0 size:100x75
+ offset:0,0 size:10x50
+ offset:0,50 size:100x25
+ offset:0,0 size:15x25
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+TEST_F(NGFieldsetLayoutAlgorithmTest, MarginTopPastEndOfFragmentainer) {
+ // A block whose border box would start past the end of the current
+ // fragmentainer should start exactly at the start of the next fragmentainer,
+ // discarding what's left of the margin.
+ // https://www.w3.org/TR/css-break-3/#break-margins
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset {
+ border:none; margin:0; padding:0px; width: 100px; height: 100px;
+ }
+ #legend {
+ padding:0px; margin:0px;
+ }
+ </style>
+ <fieldset id="fieldset">
+ <legend id="legend" style="margin-top:60px; width:10px; height:20px;"></legend>
+ <div style="width:20px; height:20px;"></div>
+ </fieldset>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(50);
+
+ NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("fieldset")));
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(1000), kIndefiniteSize), false,
+ node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
+
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
+ NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
+ ASSERT_TRUE(fragment->BreakToken());
+
+ String dump = DumpFragmentTree(fragment.get());
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:100x50
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_FALSE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:100x50
+ offset:0,0 size:10x20
+ offset:0,20 size:100x30
+ offset:0,0 size:20x20
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+}
+
+TEST_F(NGFieldsetLayoutAlgorithmTest, MarginBottomPastEndOfFragmentainer) {
+ // A block whose border box would start past the end of the current
+ // fragmentainer should start exactly at the start of the next fragmentainer,
+ // discarding what's left of the margin.
+ // https://www.w3.org/TR/css-break-3/#break-margins
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset {
+ border:none; margin:0; padding:0px; width: 100px; height: 100px;
+ }
+ #legend {
+ padding:0px; margin:0px;
+ }
+ </style>
+ <fieldset id="fieldset">
+ <legend id="legend" style="margin-bottom:20px; height:90px;"></legend>
+ <div style="width:20px; height:20px;"></div>
+ </fieldset>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(100);
+
+ NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("fieldset")));
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(1000), kIndefiniteSize), false,
+ node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
+
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
+ NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
+ ASSERT_TRUE(fragment->BreakToken());
+
+ String dump = DumpFragmentTree(fragment.get());
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:100x100
+ offset:0,0 size:0x90
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_FALSE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:100x0
+ offset:0,0 size:100x0
+ offset:0,0 size:20x20
+)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 is broken across multiple fragments.
+TEST_F(NGFieldsetLayoutAlgorithmTest, SmallLegendLargeBorderFragmentation) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset { margin:0; border:60px solid; padding:0px; width:100px;
+ height:10px; }
+ #legend { padding:0; width:10px; height:50px; }
+ </style>
+ <fieldset id="fieldset">
+ <legend id="legend"></legend>
+ </fieldset>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(40);
+
+ NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("fieldset")));
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(1000), kIndefiniteSize), false,
+ node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
+
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
+ NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
+ ASSERT_TRUE(fragment->BreakToken());
+
+ String dump = DumpFragmentTree(fragment.get());
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:220x40
+ offset:60,0 size:10x40
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_TRUE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:220x40
+ offset:60,0 size:10x10
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_TRUE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:220x40
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ // TODO(almaher): There should be no break token here. In this case the bottom
+ // border never reduces in size, causing fragmentation to continue infinitely.
+ ASSERT_TRUE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:220x10
+)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 adjusted because the
+// legend fits inside the first fragment.
+TEST_F(NGFieldsetLayoutAlgorithmTest, SmallerLegendLargeBorderFragmentation) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset { margin:0; border:60px solid; padding:0px; width:100px;
+ height:10px; }
+ #legend { padding:0; width:10px; height:5px; }
+ </style>
+ <fieldset id="fieldset">
+ <legend id="legend"></legend>
+ </fieldset>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(40);
+
+ NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("fieldset")));
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(1000), kIndefiniteSize), false,
+ node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
+
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
+ NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
+ ASSERT_TRUE(fragment->BreakToken());
+
+ String dump = DumpFragmentTree(fragment.get());
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:220x40
+ offset:60,27.5 size:10x5
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_TRUE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:220x40
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_TRUE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:220x40
+)DUMP";
+ EXPECT_EQ(expectation, dump);
+
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ // TODO(almaher): There should be no break token here. In this case the bottom
+ // border never reduces in size, causing fragmentation to continue infinitely.
+ ASSERT_TRUE(fragment->BreakToken());
+
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:220x10
+)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) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #fieldset { margin:0; border:60px solid; padding:0px; width:100px;
+ height:10px; }
+ #legend { padding:0; width:10px; height:5px; margin-top:16px; }
+ </style>
+ <fieldset id="fieldset">
+ <legend id="legend"></legend>
+ </fieldset>
+ )HTML");
+
+ LayoutUnit kFragmentainerSpaceAvailable(40);
+
+ NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("fieldset")));
+ NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace(
+ WritingMode::kHorizontalTb, TextDirection::kLtr,
+ LogicalSize(LayoutUnit(1000), kIndefiniteSize), false,
+ node.CreatesNewFormattingContext(), kFragmentainerSpaceAvailable);
+
+ scoped_refptr<const NGPhysicalBoxFragment> fragment =
+ NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(node, space);
+ ASSERT_TRUE(fragment->BreakToken());
+
+ String dump = DumpFragmentTree(fragment.get());
+ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:220x40
+ offset:60,16 size:10x5
+)DUMP";
+ EXPECT_EQ(expectation, dump);
- size = RunComputeMinAndMax("fieldset1");
- EXPECT_EQ(size.min_size, LayoutUnit(26));
- EXPECT_EQ(size.max_size, LayoutUnit(26));
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_TRUE(fragment->BreakToken());
- size = RunComputeMinAndMax("fieldset2");
- EXPECT_EQ(size.min_size, LayoutUnit(102));
- EXPECT_EQ(size.max_size, LayoutUnit(102));
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:220x40
+)DUMP";
+ EXPECT_EQ(expectation, dump);
- size = RunComputeMinAndMax("fieldset3");
- EXPECT_EQ(size.min_size, LayoutUnit(102));
- EXPECT_EQ(size.max_size, LayoutUnit(126));
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ ASSERT_TRUE(fragment->BreakToken());
- size = RunComputeMinAndMax("fieldset4");
- EXPECT_EQ(size.min_size, LayoutUnit(152));
- EXPECT_EQ(size.max_size, LayoutUnit(202));
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:220x40
+)DUMP";
+ EXPECT_EQ(expectation, dump);
- size = RunComputeMinAndMax("fieldset5");
- EXPECT_EQ(size.min_size, LayoutUnit(152));
- EXPECT_EQ(size.max_size, LayoutUnit(176));
+ fragment = NGBaseLayoutAlgorithmTest::RunFieldsetLayoutAlgorithm(
+ node, space, fragment->BreakToken());
+ // TODO(almaher): There should be no break token here. In this case the bottom
+ // border never reduces in size, causing fragmentation to continue infinitely.
+ ASSERT_TRUE(fragment->BreakToken());
- size = RunComputeMinAndMax("fieldset6");
- EXPECT_EQ(size.min_size, LayoutUnit(76));
- EXPECT_EQ(size.max_size, LayoutUnit(126));
+ dump = DumpFragmentTree(fragment.get());
+ expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::.
+ offset:unplaced size:220x10
+)DUMP";
+ EXPECT_EQ(expectation, dump);
}
} // anonymous namespace
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_flex_child_iterator.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_flex_child_iterator.cc
new file mode 100644
index 00000000000..350d605af11
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_flex_child_iterator.cc
@@ -0,0 +1,38 @@
+// 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/layout/ng/ng_flex_child_iterator.h"
+
+namespace blink {
+
+NGFlexChildIterator::NGFlexChildIterator(const NGBlockNode node) {
+ bool is_deprecated_webkit_box = node.Style().IsDeprecatedWebkitBox();
+ int initial_order = is_deprecated_webkit_box
+ ? ComputedStyleInitialValues::InitialBoxOrdinalGroup()
+ : ComputedStyleInitialValues::InitialOrder();
+ bool needs_sort = false;
+
+ // Collect all our children, and order them by either their
+ // -webkit-box-ordinal-group/order property.
+ for (NGLayoutInputNode child = node.FirstChild(); child;
+ child = child.NextSibling()) {
+ int order = is_deprecated_webkit_box ? child.Style().BoxOrdinalGroup()
+ : 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
+ // -webkit-box-ordinal-group/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/ng_flex_child_iterator.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_flex_child_iterator.h
new file mode 100644
index 00000000000..609483fc790
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_flex_child_iterator.h
@@ -0,0 +1,53 @@
+// 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_LAYOUT_NG_NG_FLEX_CHILD_ITERATOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_FLEX_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 for flex layout which given the current node will iterate
+// through its children.
+//
+// TODO(layout-dev): Once flex layout 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 NGFlexChildIterator {
+ STACK_ALLOCATED();
+
+ public:
+ NGFlexChildIterator(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;
+ };
+
+ private:
+ Vector<ChildWithOrder, 4> children_;
+ Vector<ChildWithOrder, 4>::const_iterator iterator_;
+};
+
+} // namespace blink
+
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(
+ blink::NGFlexChildIterator::ChildWithOrder)
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_FLEX_CHILD_ITERATOR_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc
index 9bbdcdbedba..21c01f8a5be 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc
@@ -9,12 +9,16 @@
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/layout_flexible_box.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.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_flex_child_iterator.h"
#include "third_party/blink/renderer/core/layout/ng/ng_fragment.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_layout_part.h"
+#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/platform/wtf/vector.h"
namespace blink {
@@ -27,10 +31,18 @@ NGFlexLayoutAlgorithm::NGFlexLayoutAlgorithm(
border_scrollbar_padding_(border_padding_ +
params.fragment_geometry.scrollbar),
is_column_(Style().ResolvedIsColumnFlexDirection()),
- is_horizontal_flow_(FlexLayoutAlgorithm::IsHorizontalFlow(Style())) {
+ is_horizontal_flow_(FlexLayoutAlgorithm::IsHorizontalFlow(Style())),
+ is_cross_size_definite_(IsContainerCrossSizeDefinite()) {
container_builder_.SetIsNewFormattingContext(
params.space.IsNewFormattingContext());
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_);
+ algorithm_.emplace(&Style(), MainAxisContentExtent(LayoutUnit::Max()));
}
bool NGFlexLayoutAlgorithm::MainAxisIsInlineAxis(
@@ -40,26 +52,101 @@ bool NGFlexLayoutAlgorithm::MainAxisIsInlineAxis(
}
LayoutUnit NGFlexLayoutAlgorithm::MainAxisContentExtent(
- LayoutUnit sum_hypothetical_main_size) {
+ LayoutUnit sum_hypothetical_main_size) const {
if (Style().ResolvedIsColumnFlexDirection()) {
return ComputeBlockSizeForFragment(
ConstraintSpace(), Style(), border_padding_,
- sum_hypothetical_main_size + (border_padding_).BlockSum()) -
+ sum_hypothetical_main_size +
+ border_scrollbar_padding_.BlockSum()) -
border_scrollbar_padding_.BlockSum();
}
return content_box_size_.inline_size;
}
+namespace {
+
+enum AxisEdge { kStart, kCenter, kEnd };
+
+// Maps the resolved justify-content value to a static-position edge.
+AxisEdge MainAxisStaticPositionEdge(const ComputedStyle& style,
+ bool is_column) {
+ const StyleContentAlignmentData justify =
+ FlexLayoutAlgorithm::ResolvedJustifyContent(style);
+ const ContentPosition content_position = justify.GetPosition();
+ bool is_reverse_flex = is_column
+ ? style.ResolvedIsColumnReverseFlexDirection()
+ : style.ResolvedIsRowReverseFlexDirection();
+
+ if (content_position == ContentPosition::kFlexEnd)
+ return is_reverse_flex ? AxisEdge::kStart : AxisEdge::kEnd;
+
+ if (content_position == ContentPosition::kCenter ||
+ justify.Distribution() == ContentDistributionType::kSpaceAround ||
+ justify.Distribution() == ContentDistributionType::kSpaceEvenly)
+ return AxisEdge::kCenter;
+
+ return is_reverse_flex ? AxisEdge::kEnd : AxisEdge::kStart;
+}
+
+// Maps the resolved alignment value to a static-position edge.
+AxisEdge CrossAxisStaticPositionEdge(const ComputedStyle& style,
+ const ComputedStyle& child_style) {
+ ItemPosition alignment =
+ FlexLayoutAlgorithm::AlignmentForChild(style, child_style);
+ bool is_wrap_reverse = style.FlexWrap() == EFlexWrap::kWrapReverse;
+
+ if (alignment == ItemPosition::kFlexEnd)
+ return is_wrap_reverse ? AxisEdge::kStart : AxisEdge::kEnd;
+
+ if (alignment == ItemPosition::kCenter)
+ return AxisEdge::kCenter;
+
+ return is_wrap_reverse ? AxisEdge::kEnd : AxisEdge::kStart;
+}
+
+} // namespace
+
void NGFlexLayoutAlgorithm::HandleOutOfFlowPositioned(NGBlockNode child) {
- // TODO(dgrogan): There's stuff from
- // https://www.w3.org/TR/css-flexbox-1/#abspos-items that isn't done here.
- // Specifically, neither rtl nor alignment is handled here, at least.
- // Look at LayoutFlexibleBox::PrepareChildForPositionedLayout and
- // SetStaticPositionForPositionedLayout to see how to statically position
- // this.
- container_builder_.AddOutOfFlowChildCandidate(
- child, {border_scrollbar_padding_.inline_start,
- border_scrollbar_padding_.block_start});
+ AxisEdge main_axis_edge = MainAxisStaticPositionEdge(Style(), is_column_);
+ AxisEdge cross_axis_edge =
+ CrossAxisStaticPositionEdge(Style(), child.Style());
+
+ AxisEdge inline_axis_edge = is_column_ ? cross_axis_edge : main_axis_edge;
+ AxisEdge block_axis_edge = is_column_ ? main_axis_edge : cross_axis_edge;
+
+ using InlineEdge = NGLogicalStaticPosition::InlineEdge;
+ using BlockEdge = NGLogicalStaticPosition::BlockEdge;
+
+ InlineEdge inline_edge;
+ BlockEdge block_edge;
+ LogicalOffset offset(border_scrollbar_padding_.inline_start,
+ border_scrollbar_padding_.block_start);
+
+ // 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;
+ } else {
+ inline_edge = InlineEdge::kInlineEnd;
+ offset.inline_offset += content_box_size_.inline_size;
+ }
+
+ // We may not know the final block-size of the fragment yet. This will be
+ // adjusted within the |NGContainerFragmentBuilder| once set.
+ if (block_axis_edge == AxisEdge::kStart) {
+ block_edge = BlockEdge::kBlockStart;
+ } else if (block_axis_edge == AxisEdge::kCenter) {
+ block_edge = BlockEdge::kBlockCenter;
+ offset.block_offset -= border_scrollbar_padding_.BlockSum() / 2;
+ } else {
+ block_edge = BlockEdge::kBlockEnd;
+ offset.block_offset -= border_scrollbar_padding_.BlockSum();
+ }
+
+ container_builder_.AddOutOfFlowChildCandidate(child, offset, inline_edge,
+ block_edge);
}
bool NGFlexLayoutAlgorithm::IsColumnContainerMainSizeDefinite() const {
@@ -110,13 +197,27 @@ bool NGFlexLayoutAlgorithm::DoesItemStretch(const NGBlockNode& child) const {
ItemPosition::kStretch;
}
+bool NGFlexLayoutAlgorithm::IsItemFlexBasisDefinite(
+ const NGBlockNode& child) const {
+ const Length& flex_basis = child.Style().FlexBasis();
+ DCHECK(!flex_basis.IsAuto())
+ << "This is never called with flex_basis.IsAuto, but it'd be trivial to "
+ "support.";
+ if (!is_column_)
+ return true;
+ return !BlockLengthUnresolvable(BuildSpaceForFlexBasis(child), flex_basis,
+ LengthResolvePhase::kLayout);
+}
+
// This behavior is under discussion: the item's pre-flexing main size
// definiteness may no longer imply post-flexing definiteness.
// TODO(dgrogan): Have https://crbug.com/1003506 and
// https://github.com/w3c/csswg-drafts/issues/4305 been resolved yet?
bool NGFlexLayoutAlgorithm::IsItemMainSizeDefinite(
const NGBlockNode& child) const {
- DCHECK(is_column_);
+ DCHECK(is_column_)
+ << "This method doesn't work with row flexboxes because we assume "
+ "main size is block size when we call BlockLengthUnresolvable.";
// Inline sizes are always definite.
// TODO(dgrogan): The relevant tests, the last two cases in
// css/css-flexbox/percentage-heights-003.html passed even without this, so it
@@ -126,9 +227,8 @@ bool NGFlexLayoutAlgorithm::IsItemMainSizeDefinite(
// We need a constraint space for the child to determine resolvability and the
// space for flex-basis is sufficient, even though it has some unnecessary
// stuff (ShrinkToFit and fixed cross sizes).
- NGConstraintSpace child_space =
- BuildConstraintSpaceForDeterminingFlexBasis(child);
- return !BlockLengthUnresolvable(child_space, child.Style().LogicalHeight(),
+ return !BlockLengthUnresolvable(BuildSpaceForFlexBasis(child),
+ child.Style().LogicalHeight(),
LengthResolvePhase::kLayout);
}
@@ -143,9 +243,8 @@ bool NGFlexLayoutAlgorithm::IsItemCrossAxisLengthDefinite(
if (!MainAxisIsInlineAxis(child))
return true;
// If we get here, cross axis is block axis.
- return !BlockLengthUnresolvable(
- BuildConstraintSpaceForDeterminingFlexBasis(child), length,
- LengthResolvePhase::kLayout);
+ return !BlockLengthUnresolvable(BuildSpaceForFlexBasis(child), length,
+ LengthResolvePhase::kLayout);
}
bool NGFlexLayoutAlgorithm::DoesItemCrossSizeComputeToAuto(
@@ -197,139 +296,157 @@ bool NGFlexLayoutAlgorithm::ShouldItemShrinkToFit(
bool NGFlexLayoutAlgorithm::WillChildCrossSizeBeContainerCrossSize(
const NGBlockNode& child) const {
- return !algorithm_->IsMultiline() && IsContainerCrossSizeDefinite() &&
+ return !algorithm_->IsMultiline() && is_cross_size_definite_ &&
DoesItemStretch(child);
}
-NGConstraintSpace
-NGFlexLayoutAlgorithm::BuildConstraintSpaceForDeterminingFlexBasis(
- const NGBlockNode& flex_item) const {
+double NGFlexLayoutAlgorithm::GetMainOverCrossAspectRatio(
+ const NGBlockNode& child) const {
+ DCHECK(child.HasAspectRatio());
+ LogicalSize aspect_ratio = child.GetAspectRatio();
+
+ DCHECK_GT(aspect_ratio.inline_size, 0);
+ DCHECK_GT(aspect_ratio.block_size, 0);
+
+ double ratio =
+ aspect_ratio.inline_size.ToDouble() / aspect_ratio.block_size.ToDouble();
+ // Multiplying by ratio will take something in the item's block axis and
+ // convert it to the inline axis. We want to convert from cross size to main
+ // size. If block axis and cross axis are the same, then we already have what
+ // we need. Otherwise we need to use the reciprocal.
+ if (!MainAxisIsInlineAxis(child))
+ ratio = 1 / ratio;
+ return ratio;
+}
+
+namespace {
+
+LayoutUnit CalculateFixedCrossSize(LayoutUnit available_size,
+ const MinMaxSizes& cross_axis_min_max,
+ LayoutUnit margin_sum) {
+ return cross_axis_min_max.ClampSizeToMinAndMax(available_size - margin_sum);
+}
+
+} // namespace
+
+NGConstraintSpace NGFlexLayoutAlgorithm::BuildSpaceForIntrinsicBlockSize(
+ const NGBlockNode& flex_item,
+ const NGPhysicalBoxStrut& physical_margins,
+ const MinMaxSizes& cross_axis_min_max) const {
const ComputedStyle& child_style = flex_item.Style();
NGConstraintSpaceBuilder space_builder(ConstraintSpace(),
child_style.GetWritingMode(),
/* is_new_fc */ true);
SetOrthogonalFallbackInlineSizeIfNeeded(Style(), flex_item, &space_builder);
+ space_builder.SetCacheSlot(NGCacheSlot::kMeasure);
+ space_builder.SetIsPaintedAtomically(true);
- if (ShouldItemShrinkToFit(flex_item))
+ NGBoxStrut margins = physical_margins.ConvertToLogical(
+ ConstraintSpace().GetWritingMode(), Style().Direction());
+ LogicalSize child_available_size = content_box_size_;
+ if (ShouldItemShrinkToFit(flex_item)) {
space_builder.SetIsShrinkToFit(true);
- if (WillChildCrossSizeBeContainerCrossSize(flex_item)) {
+ } else if (WillChildCrossSizeBeContainerCrossSize(flex_item)) {
if (is_column_) {
space_builder.SetIsFixedInlineSize(true);
+ child_available_size.inline_size =
+ CalculateFixedCrossSize(child_available_size.inline_size,
+ cross_axis_min_max, margins.InlineSum());
} 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());
}
}
+ space_builder.SetNeedsBaseline(
+ ConstraintSpace().NeedsBaseline() ||
+ FlexLayoutAlgorithm::AlignmentForChild(Style(), child_style) ==
+ ItemPosition::kBaseline);
+
+ // For determining the intrinsic block-size we make %-block-sizes resolve
+ // against an indefinite size.
+ LogicalSize child_percentage_size = child_percentage_size_;
+ if (is_column_)
+ child_percentage_size.block_size = kIndefiniteSize;
+
+ space_builder.SetAvailableSize(child_available_size);
+ space_builder.SetPercentageResolutionSize(child_percentage_size);
+ // TODO(dgrogan): The SetReplacedPercentageResolutionSize calls in this file
+ // may be untested. Write a test or determine why they're unnecessary.
+ space_builder.SetReplacedPercentageResolutionSize(child_percentage_size);
+ space_builder.SetTextDirection(child_style.Direction());
+ return space_builder.ToConstraintSpace();
+}
+
+NGConstraintSpace NGFlexLayoutAlgorithm::BuildSpaceForFlexBasis(
+ const NGBlockNode& flex_item) const {
+ NGConstraintSpaceBuilder space_builder(ConstraintSpace(),
+ flex_item.Style().GetWritingMode(),
+ /* is_new_fc */ true);
+ SetOrthogonalFallbackInlineSizeIfNeeded(Style(), flex_item, &space_builder);
+
+ // 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.SetPercentageResolutionSize(child_percentage_size_);
- space_builder.SetTextDirection(child_style.Direction());
+ space_builder.SetReplacedPercentageResolutionSize(child_percentage_size_);
return space_builder.ToConstraintSpace();
}
void NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() {
- for (NGLayoutInputNode generic_child = Node().FirstChild(); generic_child;
- generic_child = generic_child.NextSibling()) {
- auto child = To<NGBlockNode>(generic_child);
+ NGFlexChildIterator iterator(Node());
+ for (NGBlockNode child = iterator.NextChild(); child;
+ child = iterator.NextChild()) {
if (child.IsOutOfFlowPositioned()) {
HandleOutOfFlowPositioned(child);
continue;
}
const ComputedStyle& child_style = child.Style();
- NGConstraintSpace child_space =
- BuildConstraintSpaceForDeterminingFlexBasis(child);
+ NGConstraintSpace flex_basis_space = BuildSpaceForFlexBasis(child);
+
+ NGPhysicalBoxStrut physical_child_margins =
+ ComputePhysicalMargins(flex_basis_space, child_style);
NGBoxStrut border_padding_in_child_writing_mode =
- ComputeBorders(child_space, child) +
- ComputePadding(child_space, child_style);
- NGBoxStrut border_scrollbar_padding_in_child_writing_mode =
- border_padding_in_child_writing_mode +
- ComputeScrollbars(child_space, child);
+ ComputeBorders(flex_basis_space, child_style) +
+ ComputePadding(flex_basis_space, child_style);
NGPhysicalBoxStrut physical_border_padding(
border_padding_in_child_writing_mode.ConvertToPhysical(
child_style.GetWritingMode(), child_style.Direction()));
- NGPhysicalBoxStrut physical_border_scrollbar_padding(
- border_scrollbar_padding_in_child_writing_mode.ConvertToPhysical(
- child_style.GetWritingMode(), child_style.Direction()));
LayoutUnit main_axis_border_padding =
is_horizontal_flow_ ? physical_border_padding.HorizontalSum()
: physical_border_padding.VerticalSum();
- LayoutUnit main_axis_border_scrollbar_padding =
- is_horizontal_flow_ ? physical_border_scrollbar_padding.HorizontalSum()
- : physical_border_scrollbar_padding.VerticalSum();
-
- // We want the child's min/max size in its writing mode, not ours. We'll
- // only ever use it if the child's inline axis is our main axis.
- MinMaxSizeInput input(
- /* percentage_resolution_block_size */ content_box_size_.block_size);
- MinMaxSize intrinsic_sizes_border_box = child.ComputeMinMaxSize(
- child_style.GetWritingMode(), input, &child_space);
- // TODO(dgrogan): Don't layout every time, just when you need to.
- // Use ChildHasIntrinsicMainAxisSize as a guide.
- scoped_refptr<const NGLayoutResult> layout_result =
- child.Layout(child_space, nullptr /*break token*/);
- NGFragment fragment_in_child_writing_mode(
- child_style.GetWritingMode(), layout_result->PhysicalFragment());
-
- LayoutUnit flex_base_border_box;
- const Length& specified_length_in_main_axis =
- is_horizontal_flow_ ? child_style.Width() : child_style.Height();
- const Length& flex_basis = child_style.FlexBasis();
- // TODO(dgrogan): Generalize IsAuto: See the <'width'> section of
- // https://drafts.csswg.org/css-flexbox/#valdef-flex-flex-basis
- // and https://drafts.csswg.org/css-flexbox/#flex-basis-property, which says
- // that if a flex-basis value would resolve to auto (but not literally auto)
- // we should interpret it as flex-basis:content.
- if (flex_basis.IsAuto() && specified_length_in_main_axis.IsAuto()) {
- if (MainAxisIsInlineAxis(child))
- flex_base_border_box = intrinsic_sizes_border_box.max_size;
- else
- flex_base_border_box = fragment_in_child_writing_mode.BlockSize();
- } else {
- // TODO(dgrogan): Check for definiteness.
- // This block covers case A in
- // https://drafts.csswg.org/css-flexbox/#algo-main-item.
- const Length& length_to_resolve =
- flex_basis.IsAuto() ? specified_length_in_main_axis : flex_basis;
- DCHECK(!length_to_resolve.IsAuto());
-
- if (MainAxisIsInlineAxis(child)) {
- flex_base_border_box = ResolveMainInlineLength(
- child_space, child_style, border_padding_in_child_writing_mode,
- intrinsic_sizes_border_box, length_to_resolve);
- } else {
- // Flex container's main axis is in child's block direction. Child's
- // flex basis is in child's block direction.
- flex_base_border_box = ResolveMainBlockLength(
- child_space, child_style, border_padding_in_child_writing_mode,
- length_to_resolve, fragment_in_child_writing_mode.BlockSize(),
- LengthResolvePhase::kLayout);
+ LayoutUnit cross_axis_border_padding =
+ is_horizontal_flow_ ? physical_border_padding.VerticalSum()
+ : physical_border_padding.HorizontalSum();
+
+ base::Optional<MinMaxSizes> min_max_size;
+ auto MinMaxSizesFunc = [&]() -> MinMaxSizes {
+ if (!min_max_size) {
+ 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(flex_basis_space);
+ }
+ // We want the child's min/max size in its writing mode, not ours.
+ // We'll only ever use it if the child's inline axis is our main axis.
+ min_max_size = child.ComputeMinMaxSizes(
+ child_style.GetWritingMode(),
+ MinMaxSizesInput(content_box_size_.block_size), &flex_basis_space);
}
- }
+ return *min_max_size;
+ };
- // Spec calls this "flex base size"
- // https://www.w3.org/TR/css-flexbox-1/#algo-main-item
- // Blink's FlexibleBoxAlgorithm expects it to be content + scrollbar widths,
- // but no padding or border.
- LayoutUnit flex_base_content_size =
- flex_base_border_box - main_axis_border_padding;
-
- NGPhysicalBoxStrut physical_child_margins =
- ComputePhysicalMargins(child_space, child_style);
- // Set margin because FlexibleBoxAlgorithm reads it from legacy.
- child.GetLayoutBox()->SetMargin(physical_child_margins);
-
- LayoutUnit main_axis_margin = is_horizontal_flow_
- ? physical_child_margins.HorizontalSum()
- : physical_child_margins.VerticalSum();
-
- MinMaxSize min_max_sizes_in_main_axis_direction{LayoutUnit(),
- LayoutUnit::Max()};
- MinMaxSize min_max_sizes_in_cross_axis_direction{LayoutUnit(),
+ MinMaxSizes min_max_sizes_in_main_axis_direction{main_axis_border_padding,
LayoutUnit::Max()};
+ MinMaxSizes min_max_sizes_in_cross_axis_direction{LayoutUnit(),
+ LayoutUnit::Max()};
const Length& max_property_in_main_axis = is_horizontal_flow_
? child.Style().MaxWidth()
: child.Style().MaxHeight();
@@ -341,112 +458,282 @@ void NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() {
: child.Style().MinWidth();
if (MainAxisIsInlineAxis(child)) {
min_max_sizes_in_main_axis_direction.max_size = ResolveMaxInlineLength(
- child_space, child_style, border_padding_in_child_writing_mode,
- intrinsic_sizes_border_box, max_property_in_main_axis,
+ flex_basis_space, child_style, border_padding_in_child_writing_mode,
+ MinMaxSizesFunc, max_property_in_main_axis,
LengthResolvePhase::kLayout);
- min_max_sizes_in_cross_axis_direction.max_size =
- ResolveMaxBlockLength(child_space, child_style,
- border_scrollbar_padding_in_child_writing_mode,
- max_property_in_cross_axis,
- fragment_in_child_writing_mode.BlockSize(),
- LengthResolvePhase::kLayout);
- min_max_sizes_in_cross_axis_direction.min_size =
- ResolveMinBlockLength(child_space, child_style,
- border_scrollbar_padding_in_child_writing_mode,
- min_property_in_cross_axis,
- fragment_in_child_writing_mode.BlockSize(),
- LengthResolvePhase::kLayout);
+ min_max_sizes_in_cross_axis_direction.max_size = ResolveMaxBlockLength(
+ flex_basis_space, child_style, border_padding_in_child_writing_mode,
+ max_property_in_cross_axis, LengthResolvePhase::kLayout);
+ min_max_sizes_in_cross_axis_direction.min_size = ResolveMinBlockLength(
+ flex_basis_space, child_style, border_padding_in_child_writing_mode,
+ min_property_in_cross_axis, LengthResolvePhase::kLayout);
} else {
min_max_sizes_in_main_axis_direction.max_size = ResolveMaxBlockLength(
- child_space, child_style, border_padding_in_child_writing_mode,
- max_property_in_main_axis, fragment_in_child_writing_mode.BlockSize(),
- LengthResolvePhase::kLayout);
+ flex_basis_space, child_style, border_padding_in_child_writing_mode,
+ max_property_in_main_axis, LengthResolvePhase::kLayout);
min_max_sizes_in_cross_axis_direction.max_size = ResolveMaxInlineLength(
- child_space, child_style,
- border_scrollbar_padding_in_child_writing_mode,
- intrinsic_sizes_border_box, max_property_in_cross_axis,
+ flex_basis_space, child_style, border_padding_in_child_writing_mode,
+ MinMaxSizesFunc, max_property_in_cross_axis,
LengthResolvePhase::kLayout);
min_max_sizes_in_cross_axis_direction.min_size = ResolveMinInlineLength(
- child_space, child_style,
- border_scrollbar_padding_in_child_writing_mode,
- intrinsic_sizes_border_box, min_property_in_cross_axis,
+ flex_basis_space, child_style, border_padding_in_child_writing_mode,
+ MinMaxSizesFunc, min_property_in_cross_axis,
LengthResolvePhase::kLayout);
}
+ base::Optional<LayoutUnit> intrinsic_block_size;
+ auto IntrinsicBlockSizeFunc = [&]() -> LayoutUnit {
+ if (!intrinsic_block_size) {
+ NGConstraintSpace child_space = BuildSpaceForIntrinsicBlockSize(
+ child, physical_child_margins,
+ min_max_sizes_in_cross_axis_direction);
+ scoped_refptr<const NGLayoutResult> layout_result =
+ child.Layout(child_space, /* break_token */ nullptr);
+ intrinsic_block_size = layout_result->IntrinsicBlockSize();
+ }
+ return *intrinsic_block_size;
+ };
+
+ // The logic that calculates flex_base_border_box assumes that the used
+ // value of the flex-basis property is either definite or 'content'.
+ LayoutUnit flex_base_border_box;
+ const Length& specified_length_in_main_axis =
+ is_horizontal_flow_ ? child_style.Width() : child_style.Height();
+ const Length& flex_basis = child_style.FlexBasis();
+ Length length_to_resolve = Length::Auto();
+ if (flex_basis.IsAuto()) {
+ if (!is_column_ || IsItemMainSizeDefinite(child))
+ length_to_resolve = specified_length_in_main_axis;
+ } else if (IsItemFlexBasisDefinite(child)) {
+ length_to_resolve = flex_basis;
+ }
+
+ if (length_to_resolve.IsAuto()) {
+ // This block means that the used flex-basis is 'content'. In here we
+ // implement parts B,C,D,E of 9.2.3
+ // 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 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)) {
+ cross_size = ResolveMainBlockLength(
+ flex_basis_space, child_style,
+ border_padding_in_child_writing_mode, cross_axis_length,
+ kIndefiniteSize, LengthResolvePhase::kLayout);
+ } else {
+ cross_size =
+ ResolveMainInlineLength(flex_basis_space, child_style,
+ border_padding_in_child_writing_mode,
+ MinMaxSizesFunc, cross_axis_length);
+ }
+ cross_size = min_max_sizes_in_cross_axis_direction.ClampSizeToMinAndMax(
+ cross_size);
+ flex_base_border_box =
+ LayoutUnit(cross_size * GetMainOverCrossAspectRatio(child));
+ } else if (MainAxisIsInlineAxis(child)) {
+ // We're now in parts C, D, and E for what are usually (horizontal-tb
+ // containers AND children) row flex containers. I _think_ the C and D
+ // cases are correctly handled by this code, which was originally
+ // written for case E.
+ if (child.HasAspectRatio()) {
+ // Legacy uses child.PreferredLogicalWidths() for this case, which
+ // is not exactly correct.
+ // TODO(dgrogan): Replace with a variant of ComputeReplacedSize that
+ // ignores min-width, width, max-width.
+ flex_base_border_box =
+ child.GetLayoutBox()->PreferredLogicalWidths().max_size;
+ } else {
+ flex_base_border_box = MinMaxSizesFunc().max_size;
+ }
+ } else {
+ // Parts C, D, and E for what are usually column flex containers.
+ //
+ // This is the post-layout height for aspect-ratio items, which matches
+ // legacy but isn't always correct.
+ // TODO(dgrogan): Replace with a variant of ComputeReplacedSize that
+ // ignores min-height, height, max-height.
+ flex_base_border_box = IntrinsicBlockSizeFunc();
+ }
+ } else {
+ // Part A of 9.2.3 https://drafts.csswg.org/css-flexbox/#algo-main-item
+ if (MainAxisIsInlineAxis(child)) {
+ flex_base_border_box = ResolveMainInlineLength(
+ flex_basis_space, child_style, border_padding_in_child_writing_mode,
+ MinMaxSizesFunc, length_to_resolve);
+ } else {
+ // Flex container's main axis is in child's block direction. Child's
+ // flex basis is in child's block direction.
+ flex_base_border_box = ResolveMainBlockLength(
+ flex_basis_space, child_style, border_padding_in_child_writing_mode,
+ length_to_resolve, IntrinsicBlockSizeFunc,
+ LengthResolvePhase::kLayout);
+ }
+ }
+
+ // Spec calls this "flex base size"
+ // https://www.w3.org/TR/css-flexbox-1/#algo-main-item
+ // Blink's FlexibleBoxAlgorithm expects it to be content + scrollbar widths,
+ // but no padding or border.
+ // The ClampNegativeToZero is needed for the last canvas element in
+ // flexbox-flex-basis-content-001a.html. It's possibly only needed because
+ // we don't properly account for borders+padding when multiplying by the
+ // aspect ratio.
+ LayoutUnit flex_base_content_size =
+ (flex_base_border_box - main_axis_border_padding).ClampNegativeToZero();
+
const Length& min = is_horizontal_flow_ ? child.Style().MinWidth()
: child.Style().MinHeight();
+ // TODO(dgrogan): min.IsIntrinsic should enter this block when it's in the
+ // item's block direction.
if (min.IsAuto()) {
if (algorithm_->ShouldApplyMinSizeAutoForChild(*child.GetLayoutBox())) {
- // TODO(dgrogan): Do the aspect ratio parts of
- // https://www.w3.org/TR/css-flexbox-1/#min-size-auto
-
- LayoutUnit content_size_suggestion =
- MainAxisIsInlineAxis(child) ? intrinsic_sizes_border_box.min_size
- : layout_result->IntrinsicBlockSize();
- content_size_suggestion =
- std::min(content_size_suggestion,
- min_max_sizes_in_main_axis_direction.max_size);
-
- if (child.MayHaveAspectRatio()) {
- // TODO(dgrogan): We're including borders/padding in both
- // content_size_suggestion and min_max_sizes_in_cross_axis_direction.
- // Maybe we need to multiply the content size by the aspect ratio and
- // then apply the border/padding from the other axis inside the
- // Adjust* function. Test legacy/firefox. Start with
- // https://jsfiddle.net/dgrogan/9uyg3aro/
- content_size_suggestion =
- AdjustChildSizeForAspectRatioCrossAxisMinAndMax(
- child, content_size_suggestion,
- min_max_sizes_in_cross_axis_direction.min_size,
- min_max_sizes_in_cross_axis_direction.max_size);
- }
+ // TODO(dgrogan): This should probably apply to column flexboxes also,
+ // but that's not what legacy does.
+ if (child.IsTable() && !is_column_) {
+ MinMaxSizes table_preferred_widths =
+ ComputeMinAndMaxContentContribution(
+ Style(), child,
+ MinMaxSizesInput(child_percentage_size_.block_size));
+ 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().min_size;
+ } else {
+ LayoutUnit intrinsic_block_size;
+ if (child.HasAspectRatio()) {
+ base::Optional<LayoutUnit> computed_inline_size;
+ base::Optional<LayoutUnit> computed_block_size;
+ child.IntrinsicSize(&computed_inline_size, &computed_block_size);
+
+ // The 150 is for elements that have an aspect ratio but no size,
+ // which SVG can have (maybe others?).
+ intrinsic_block_size =
+ computed_block_size.value_or(LayoutUnit(150));
+ } else {
+ intrinsic_block_size = IntrinsicBlockSizeFunc();
+ }
+ content_size_suggestion = intrinsic_block_size;
+ }
- LayoutUnit specified_size_suggestion(LayoutUnit::Max());
- // If the item’s computed main size property is definite, then the
- // specified size suggestion is that size.
- if (MainAxisIsInlineAxis(child)) {
- if (!specified_length_in_main_axis.IsAuto()) {
- // TODO(dgrogan): Optimization opportunity: we may have already
- // resolved specified_length_in_main_axis in the flex basis
- // calculation. Reuse that if possible.
- specified_size_suggestion = ResolveMainInlineLength(
- child_space, child_style, border_padding_in_child_writing_mode,
- intrinsic_sizes_border_box, specified_length_in_main_axis);
+
+ if (child.HasAspectRatio()) {
+ // TODO(dgrogan): We're including borders/padding in both
+ // content_size_suggestion and
+ // min_max_sizes_in_cross_axis_direction. Maybe we need to multiply
+ // the content size by the aspect ratio and then apply the
+ // border/padding from the other axis inside the Adjust* function.
+ // Test legacy/firefox. Start with
+ // https://jsfiddle.net/dgrogan/9uyg3aro/
+ content_size_suggestion =
+ AdjustChildSizeForAspectRatioCrossAxisMinAndMax(
+ child, content_size_suggestion,
+ min_max_sizes_in_cross_axis_direction.min_size,
+ min_max_sizes_in_cross_axis_direction.max_size);
+ }
+
+ LayoutUnit specified_size_suggestion = LayoutUnit::Max();
+ // If the item’s computed main size property is definite, then the
+ // specified size suggestion is that size.
+ if (MainAxisIsInlineAxis(child)) {
+ if (!specified_length_in_main_axis.IsAuto()) {
+ // TODO(dgrogan): Optimization opportunity: we may have already
+ // resolved specified_length_in_main_axis in the flex basis
+ // calculation. Reuse that if possible.
+ specified_size_suggestion = ResolveMainInlineLength(
+ flex_basis_space, child_style,
+ border_padding_in_child_writing_mode, MinMaxSizesFunc,
+ specified_length_in_main_axis);
+ }
+ } else if (!BlockLengthUnresolvable(flex_basis_space,
+ specified_length_in_main_axis,
+ LengthResolvePhase::kLayout)) {
+ specified_size_suggestion = ResolveMainBlockLength(
+ flex_basis_space, child_style,
+ border_padding_in_child_writing_mode,
+ specified_length_in_main_axis, IntrinsicBlockSizeFunc,
+ LengthResolvePhase::kLayout);
+ DCHECK_NE(specified_size_suggestion, kIndefiniteSize);
}
- } else if (!BlockLengthUnresolvable(child_space,
- specified_length_in_main_axis,
- LengthResolvePhase::kLayout)) {
- specified_size_suggestion = ResolveMainBlockLength(
- child_space, child_style, border_padding_in_child_writing_mode,
- specified_length_in_main_axis,
- layout_result->IntrinsicBlockSize(), LengthResolvePhase::kLayout);
- DCHECK_NE(specified_size_suggestion, kIndefiniteSize);
- }
- // Spec says to clamp specified_size_suggestion by max size but because
- // content_size_suggestion already is, and we take the min of those
- // two, we don't need to clamp specified_size_suggestion.
- // https://github.com/w3c/csswg-drafts/issues/3669
- min_max_sizes_in_main_axis_direction.min_size =
- std::min(specified_size_suggestion, content_size_suggestion);
+ LayoutUnit transferred_size_suggestion = LayoutUnit::Max();
+ if (specified_size_suggestion == LayoutUnit::Max() &&
+ child.HasAspectRatio()) {
+ const Length& cross_axis_length = is_horizontal_flow_
+ ? child_style.Height()
+ : child_style.Width();
+ if (IsItemCrossAxisLengthDefinite(child, cross_axis_length)) {
+ LayoutUnit cross_axis_size;
+ if (MainAxisIsInlineAxis(child)) {
+ cross_axis_size = ResolveMainBlockLength(
+ flex_basis_space, child_style,
+ border_padding_in_child_writing_mode, cross_axis_length,
+ kIndefiniteSize, LengthResolvePhase::kLayout);
+ DCHECK_NE(cross_axis_size, kIndefiniteSize);
+ } else {
+ cross_axis_size = ResolveMainInlineLength(
+ flex_basis_space, child_style,
+ border_padding_in_child_writing_mode, MinMaxSizesFunc,
+ cross_axis_length);
+ }
+ double ratio = GetMainOverCrossAspectRatio(child);
+ transferred_size_suggestion = LayoutUnit(
+ ratio *
+ min_max_sizes_in_cross_axis_direction.ClampSizeToMinAndMax(
+ cross_axis_size));
+ }
+ }
+
+ DCHECK(specified_size_suggestion == LayoutUnit::Max() ||
+ transferred_size_suggestion == LayoutUnit::Max());
+
+ min_max_sizes_in_main_axis_direction.min_size =
+ std::min({specified_size_suggestion, content_size_suggestion,
+ transferred_size_suggestion,
+ min_max_sizes_in_main_axis_direction.max_size});
+ }
}
} else if (MainAxisIsInlineAxis(child)) {
min_max_sizes_in_main_axis_direction.min_size = ResolveMinInlineLength(
- child_space, child_style, border_padding_in_child_writing_mode,
- intrinsic_sizes_border_box, min, LengthResolvePhase::kLayout);
+ flex_basis_space, child_style, border_padding_in_child_writing_mode,
+ MinMaxSizesFunc, min, LengthResolvePhase::kLayout);
} else {
min_max_sizes_in_main_axis_direction.min_size = ResolveMinBlockLength(
- child_space, child_style, border_padding_in_child_writing_mode, min,
- fragment_in_child_writing_mode.BlockSize(),
- LengthResolvePhase::kLayout);
+ flex_basis_space, child_style, border_padding_in_child_writing_mode,
+ min, LengthResolvePhase::kLayout);
}
- // TODO(dgrogan): Should this include scrollbar?
- min_max_sizes_in_main_axis_direction -= main_axis_border_scrollbar_padding;
+ min_max_sizes_in_main_axis_direction -= main_axis_border_padding;
+ DCHECK_GE(min_max_sizes_in_main_axis_direction.min_size, 0);
+ DCHECK_GE(min_max_sizes_in_main_axis_direction.max_size, 0);
+
+ // TODO(dgrogan): Should min_max_sizes_in_cross_axis_direction include
+ // cross_axis_border_padding?
algorithm_
- ->emplace_back(child.GetLayoutBox(), flex_base_content_size,
+ ->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, main_axis_margin)
+ main_axis_border_padding, cross_axis_border_padding,
+ physical_child_margins)
.ng_input_node = child;
}
}
@@ -457,33 +744,16 @@ NGFlexLayoutAlgorithm::AdjustChildSizeForAspectRatioCrossAxisMinAndMax(
LayoutUnit content_suggestion,
LayoutUnit cross_min,
LayoutUnit cross_max) {
- DCHECK(child.MayHaveAspectRatio());
+ DCHECK(child.HasAspectRatio());
+
+ double ratio = GetMainOverCrossAspectRatio(child);
// Clamp content_suggestion by any definite min and max cross size properties
// converted through the aspect ratio.
-
- base::Optional<LayoutUnit> computed_inline_size;
- base::Optional<LayoutUnit> computed_block_size;
- LogicalSize aspect_ratio;
-
- child.IntrinsicSize(&computed_inline_size, &computed_block_size,
- &aspect_ratio);
-
- // TODO(dgrogan): Should we quit here if only the denominator is 0?
- if (aspect_ratio.inline_size == 0 || aspect_ratio.block_size == 0)
- return content_suggestion;
-
- double ratio = aspect_ratio.inline_size / aspect_ratio.block_size;
-
- // Multiplying by ratio will take something in the item's block axis and
- // convert it to the inline axis. We want to convert from cross size to main
- // size. If block axis and cross axis are the same, then we already have what
- // we need. Otherwise we need to use the reciprocal.
- if (!MainAxisIsInlineAxis(child))
- ratio = 1 / ratio;
-
const Length& cross_max_length = is_horizontal_flow_
? child.Style().MaxHeight()
: child.Style().MaxWidth();
+ // TODO(dgrogan): No tests fail if we unconditionally apply max_main_length.
+ // Either add a test that needs it or remove it.
if (IsItemCrossAxisLengthDefinite(child, cross_max_length)) {
LayoutUnit max_main_length = LayoutUnit(cross_max * ratio);
content_suggestion = std::min(max_main_length, content_suggestion);
@@ -492,6 +762,8 @@ NGFlexLayoutAlgorithm::AdjustChildSizeForAspectRatioCrossAxisMinAndMax(
const Length& cross_min_length = is_horizontal_flow_
? child.Style().MinHeight()
: child.Style().MinWidth();
+ // TODO(dgrogan): Same as above with min_main_length here -- it may be
+ // unneeded or untested.
if (IsItemCrossAxisLengthDefinite(child, cross_min_length)) {
LayoutUnit min_main_length = LayoutUnit(cross_min * ratio);
content_suggestion = std::max(min_main_length, content_suggestion);
@@ -500,15 +772,7 @@ NGFlexLayoutAlgorithm::AdjustChildSizeForAspectRatioCrossAxisMinAndMax(
}
scoped_refptr<const NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
- 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_);
-
- const LayoutUnit line_break_length = MainAxisContentExtent(LayoutUnit::Max());
- algorithm_.emplace(&Style(), line_break_length);
-
+ PaintLayerScrollableArea::DelayScrollOffsetClampScope delay_clamp_scope;
ConstructAndAppendFlexItems();
LayoutUnit main_axis_start_offset;
@@ -542,22 +806,29 @@ scoped_refptr<const NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
for (wtf_size_t i = 0; i < line->line_items.size(); ++i) {
FlexItem& flex_item = line->line_items[i];
- WritingMode child_writing_mode =
- flex_item.ng_input_node.Style().GetWritingMode();
+ const ComputedStyle& child_style = flex_item.ng_input_node.Style();
NGConstraintSpaceBuilder space_builder(ConstraintSpace(),
- child_writing_mode,
+ child_style.GetWritingMode(),
/* is_new_fc */ true);
SetOrthogonalFallbackInlineSizeIfNeeded(Style(), flex_item.ng_input_node,
&space_builder);
- space_builder.SetTextDirection(
- flex_item.ng_input_node.Style().Direction());
+ space_builder.SetTextDirection(child_style.Direction());
+ space_builder.SetIsPaintedAtomically(true);
LogicalSize available_size;
+ 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.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());
+ }
// https://drafts.csswg.org/css-flexbox/#definite-sizes
// If the flex container has a definite main size, a flex item's
// post-flexing main size is treated as definite, even though it can
@@ -571,16 +842,22 @@ scoped_refptr<const NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
flex_item.flexed_content_size + flex_item.main_axis_border_padding;
available_size.block_size = content_box_size_.block_size;
space_builder.SetIsFixedInlineSize(true);
- }
- if (WillChildCrossSizeBeContainerCrossSize(flex_item.ng_input_node)) {
- if (is_column_)
- space_builder.SetIsFixedInlineSize(true);
- else
+ 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());
+ }
}
+ space_builder.SetNeedsBaseline(
+ ConstraintSpace().NeedsBaseline() ||
+ FlexLayoutAlgorithm::AlignmentForChild(Style(), child_style) ==
+ ItemPosition::kBaseline);
+
space_builder.SetAvailableSize(available_size);
space_builder.SetPercentageResolutionSize(child_percentage_size_);
+ space_builder.SetReplacedPercentageResolutionSize(child_percentage_size_);
// https://drafts.csswg.org/css-flexbox/#algo-cross-item
// Determine the hypothetical cross size of each item by performing layout
@@ -592,6 +869,10 @@ scoped_refptr<const NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
NGConstraintSpace child_space = space_builder.ToConstraintSpace();
flex_item.layout_result =
flex_item.ng_input_node.Layout(child_space, nullptr /*break token*/);
+
+ // TODO(layout-dev): Handle abortions caused by block fragmentation.
+ DCHECK_EQ(flex_item.layout_result->Status(), NGLayoutResult::kSuccess);
+
flex_item.cross_axis_size =
is_horizontal_flow_
? flex_item.layout_result->PhysicalFragment().Size().height
@@ -627,12 +908,13 @@ scoped_refptr<const NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
}
void NGFlexLayoutAlgorithm::ApplyStretchAlignmentToChild(FlexItem& flex_item) {
- WritingMode child_writing_mode =
- flex_item.ng_input_node.Style().GetWritingMode();
- NGConstraintSpaceBuilder space_builder(ConstraintSpace(), child_writing_mode,
+ const ComputedStyle& child_style = flex_item.ng_input_node.Style();
+ NGConstraintSpaceBuilder space_builder(ConstraintSpace(),
+ child_style.GetWritingMode(),
/* is_new_fc */ true);
SetOrthogonalFallbackInlineSizeIfNeeded(Style(), flex_item.ng_input_node,
&space_builder);
+ space_builder.SetIsPaintedAtomically(true);
LogicalSize available_size(
flex_item.flexed_content_size + flex_item.main_axis_border_padding,
@@ -644,9 +926,16 @@ void NGFlexLayoutAlgorithm::ApplyStretchAlignmentToChild(FlexItem& flex_item) {
space_builder.SetIsFixedBlockSizeIndefinite(true);
}
}
- space_builder.SetTextDirection(flex_item.ng_input_node.Style().Direction());
+
+ space_builder.SetNeedsBaseline(
+ ConstraintSpace().NeedsBaseline() ||
+ FlexLayoutAlgorithm::AlignmentForChild(Style(), child_style) ==
+ ItemPosition::kBaseline);
+
+ space_builder.SetTextDirection(child_style.Direction());
space_builder.SetAvailableSize(available_size);
space_builder.SetPercentageResolutionSize(child_percentage_size_);
+ space_builder.SetReplacedPercentageResolutionSize(child_percentage_size_);
space_builder.SetIsFixedInlineSize(true);
space_builder.SetIsFixedBlockSize(true);
NGConstraintSpace child_space = space_builder.ToConstraintSpace();
@@ -687,6 +976,9 @@ void NGFlexLayoutAlgorithm::GiveLinesAndItemsFinalPositionAndSize() {
border_scrollbar_padding_.block_start);
}
+ base::Optional<LayoutUnit> fallback_baseline;
+
+ LayoutUnit overflow_block_size;
for (FlexLine& line_context : line_contexts) {
for (wtf_size_t child_number = 0;
child_number < line_context.line_items.size(); ++child_number) {
@@ -695,6 +987,9 @@ void NGFlexLayoutAlgorithm::GiveLinesAndItemsFinalPositionAndSize() {
if (DoesItemStretch(flex_item.ng_input_node))
ApplyStretchAlignmentToChild(flex_item);
+ const auto& physical_fragment = To<NGPhysicalBoxFragment>(
+ flex_item.layout_result->PhysicalFragment());
+
// flex_item.desired_location stores the main axis offset in X and the
// cross axis offset in Y. But AddChild wants offset from parent
// rectangle, so we have to transpose for columns. AddChild takes care of
@@ -702,16 +997,70 @@ void NGFlexLayoutAlgorithm::GiveLinesAndItemsFinalPositionAndSize() {
LayoutPoint location = is_column_
? flex_item.desired_location.TransposedPoint()
: flex_item.desired_location;
- container_builder_.AddChild(flex_item.layout_result->PhysicalFragment(),
+
+ NGBoxFragment fragment(ConstraintSpace().GetWritingMode(),
+ ConstraintSpace().Direction(), physical_fragment);
+ // Only propagate baselines from children on the first flex-line.
+ if (&line_context == line_contexts.begin()) {
+ PropagateBaselineFromChild(flex_item, fragment, location.Y(),
+ &fallback_baseline);
+ }
+
+ container_builder_.AddChild(physical_fragment,
{location.X(), location.Y()});
+
+ flex_item.ng_input_node.StoreMargins(flex_item.physical_margins);
+
+ LayoutUnit margin_block_end =
+ flex_item.physical_margins
+ .ConvertToLogical(ConstraintSpace().GetWritingMode(),
+ ConstraintSpace().Direction())
+ .block_end;
+ overflow_block_size =
+ std::max(overflow_block_size,
+ location.Y() + fragment.BlockSize() + margin_block_end);
}
}
+
+ container_builder_.SetOverflowBlockSize(overflow_block_size +
+ border_scrollbar_padding_.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);
+}
+
+void NGFlexLayoutAlgorithm::PropagateBaselineFromChild(
+ const FlexItem& flex_item,
+ const NGBoxFragment& fragment,
+ LayoutUnit block_offset,
+ base::Optional<LayoutUnit>* fallback_baseline) {
+ // Check if we've already found an appropriate baseline.
+ if (container_builder_.Baseline())
+ return;
+
+ LayoutUnit baseline_offset =
+ block_offset + fragment.Baseline().value_or(fragment.BlockSize());
+
+ // We prefer a baseline from a child with baseline alignment, and no
+ // auto-margins in the cross axis (even if we have to synthesize the
+ // baseline).
+ if (FlexLayoutAlgorithm::AlignmentForChild(Style(), flex_item.style) ==
+ ItemPosition::kBaseline &&
+ !flex_item.HasAutoMarginsInCrossAxis()) {
+ container_builder_.SetBaseline(baseline_offset);
+ return;
+ }
+
+ // Set the fallback baseline if it doesn't have a value yet.
+ *fallback_baseline = fallback_baseline->value_or(baseline_offset);
}
-base::Optional<MinMaxSize> NGFlexLayoutAlgorithm::ComputeMinMaxSize(
- const MinMaxSizeInput& input) const {
- base::Optional<MinMaxSize> sizes = CalculateMinMaxSizesIgnoringChildren(
- Node(), border_scrollbar_padding_, input.size_type);
+base::Optional<MinMaxSizes> NGFlexLayoutAlgorithm::ComputeMinMaxSizes(
+ const MinMaxSizesInput& input) const {
+ base::Optional<MinMaxSizes> sizes =
+ CalculateMinMaxSizesIgnoringChildren(Node(), border_scrollbar_padding_);
if (sizes)
return sizes;
@@ -721,21 +1070,15 @@ base::Optional<MinMaxSize> NGFlexLayoutAlgorithm::ComputeMinMaxSize(
ConstraintSpace(), Node(), border_padding_,
input.percentage_resolution_block_size);
- // Use default MinMaxSizeInput:
- // - Children of flexbox ignore any specified float properties, so children
- // never have to take floated siblings into account, and external floats
- // don't make it through the new formatting context that flexbox
- // establishes.
- // - We want the child's border box MinMaxSize, which is the default.
- MinMaxSizeInput child_input(child_percentage_resolution_block_size);
-
- for (NGLayoutInputNode generic_child = Node().FirstChild(); generic_child;
- generic_child = generic_child.NextSibling()) {
- auto child = To<NGBlockNode>(generic_child);
+ MinMaxSizesInput child_input(child_percentage_resolution_block_size);
+
+ NGFlexChildIterator iterator(Node());
+ for (NGBlockNode child = iterator.NextChild(); child;
+ child = iterator.NextChild()) {
if (child.IsOutOfFlowPositioned())
continue;
- MinMaxSize child_min_max_sizes =
+ MinMaxSizes child_min_max_sizes =
ComputeMinAndMaxContentContribution(Style(), child, child_input);
NGBoxStrut child_margins = ComputeMinMaxMargins(Style(), child);
child_min_max_sizes += child_margins.InlineSum();
@@ -744,7 +1087,7 @@ base::Optional<MinMaxSize> NGFlexLayoutAlgorithm::ComputeMinMaxSize(
sizes->max_size = std::max(sizes->max_size, child_min_max_sizes.max_size);
} else {
sizes->max_size += child_min_max_sizes.max_size;
- if (IsMultiline()) {
+ if (algorithm_->IsMultiline()) {
sizes->min_size =
std::max(sizes->min_size, child_min_max_sizes.min_size);
} else {
@@ -757,15 +1100,8 @@ base::Optional<MinMaxSize> NGFlexLayoutAlgorithm::ComputeMinMaxSize(
// 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());
-
- if (input.size_type == NGMinMaxSizeType::kBorderBoxSize)
- *sizes += border_scrollbar_padding_.InlineSum();
-
+ *sizes += border_scrollbar_padding_.InlineSum();
return sizes;
}
-bool NGFlexLayoutAlgorithm::IsMultiline() const {
- return Style().FlexWrap() != EFlexWrap::kNowrap;
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.h b/chromium/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.h
index 16f6aaa02e1..066277e3075 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.h
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.h
@@ -14,6 +14,7 @@ namespace blink {
class NGBlockNode;
class NGBlockBreakToken;
+class NGBoxFragment;
class CORE_EXPORT NGFlexLayoutAlgorithm
: public NGLayoutAlgorithm<NGBlockNode,
@@ -24,15 +25,17 @@ class CORE_EXPORT NGFlexLayoutAlgorithm
scoped_refptr<const NGLayoutResult> Layout() override;
- base::Optional<MinMaxSize> ComputeMinMaxSize(
- const MinMaxSizeInput&) const override;
+ base::Optional<MinMaxSizes> ComputeMinMaxSizes(
+ const MinMaxSizesInput&) const override;
private:
bool DoesItemCrossSizeComputeToAuto(const NGBlockNode& child) const;
+ bool IsItemFlexBasisDefinite(const NGBlockNode& child) const;
bool IsItemMainSizeDefinite(const NGBlockNode& child) const;
bool IsItemCrossAxisLengthDefinite(const NGBlockNode& child,
const Length& length) const;
bool ShouldItemShrinkToFit(const NGBlockNode& child) const;
+ double GetMainOverCrossAspectRatio(const NGBlockNode& child) const;
bool DoesItemStretch(const NGBlockNode& child) const;
// This implements the first of the additional scenarios where a flex item
// has definite sizes when it would not if it weren't a flex item.
@@ -47,8 +50,11 @@ class CORE_EXPORT NGFlexLayoutAlgorithm
bool IsColumnContainerMainSizeDefinite() const;
bool IsContainerCrossSizeDefinite() const;
- NGConstraintSpace BuildConstraintSpaceForDeterminingFlexBasis(
- const NGBlockNode& flex_item) const;
+ NGConstraintSpace BuildSpaceForFlexBasis(const NGBlockNode& flex_item) const;
+ NGConstraintSpace BuildSpaceForIntrinsicBlockSize(
+ const NGBlockNode& flex_item,
+ const NGPhysicalBoxStrut& physical_margins,
+ const MinMaxSizes& cross_axis) const;
void ConstructAndAppendFlexItems();
void ApplyStretchAlignmentToChild(FlexItem& flex_item);
void GiveLinesAndItemsFinalPositionAndSize();
@@ -57,20 +63,22 @@ class CORE_EXPORT NGFlexLayoutAlgorithm
// This is same method as FlexItem but we need that logic before FlexItem is
// constructed.
bool MainAxisIsInlineAxis(const NGBlockNode& child) const;
- LayoutUnit MainAxisContentExtent(LayoutUnit sum_hypothetical_main_size);
+ LayoutUnit MainAxisContentExtent(LayoutUnit sum_hypothetical_main_size) const;
void HandleOutOfFlowPositioned(NGBlockNode child);
- // TODO(dgrogan): This is redundant with FlexLayoutAlgorithm.IsMultiline() but
- // it's needed before the algorithm is instantiated. Figure out how to
- // not reimplement.
- bool IsMultiline() const;
+
+ // Propagates the baseline from the given flex-item if needed.
+ void PropagateBaselineFromChild(
+ const FlexItem&,
+ const NGBoxFragment&,
+ 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_;
- // These are populated at the top of Layout(), so aren't available in
- // ComputeMinMaxSize() or anything it calls.
+ const bool is_cross_size_definite_;
LogicalSize border_box_size_;
LogicalSize content_box_size_;
LogicalSize child_percentage_size_;
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 dccc520c12e..3404db2e94f 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
@@ -6,7 +6,7 @@
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
-#include "third_party/blink/renderer/core/layout/min_max_size.h"
+#include "third_party/blink/renderer/core/layout/min_max_sizes.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"
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h"
@@ -66,13 +66,14 @@ NGConstraintSpace CreateConstraintSpaceForFloat(
/* is_new_fc */ true);
SetOrthogonalFallbackInlineSizeIfNeeded(unpositioned_float.parent_style,
unpositioned_float.node, &builder);
+ builder.SetIsPaintedAtomically(true);
if (origin_block_offset) {
DCHECK(parent_space.HasBlockFragmentation());
DCHECK_EQ(style.GetWritingMode(), parent_space.GetWritingMode());
- SetupFragmentation(parent_space, *origin_block_offset, &builder,
- /* is_new_fc */ true);
+ SetupFragmentation(parent_space, unpositioned_float.node,
+ *origin_block_offset, &builder, /* is_new_fc */ true);
} else {
builder.SetFragmentationType(NGFragmentationType::kFragmentNone);
}
@@ -118,7 +119,7 @@ std::unique_ptr<NGExclusionShapeData> CreateExclusionShapeData(
case CSSBoxType::kContent:
const NGConstraintSpace space =
CreateConstraintSpaceForFloat(unpositioned_float);
- NGBoxStrut strut = ComputeBorders(space, unpositioned_float.node);
+ NGBoxStrut strut = ComputeBorders(space, style);
if (style.ShapeOutside()->CssBox() == CSSBoxType::kContent)
strut += ComputePadding(space, style);
shape_insets =
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..f0bd55d5bc0 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
@@ -47,6 +47,9 @@ class CORE_EXPORT NGFragmentBuilder {
void SetIsHiddenForPaint(bool value) { is_hidden_for_paint_ = value; }
+ // Specify whether this will be the first fragment generated for the node.
+ void SetIsFirstForNode(bool is_first) { is_first_for_node_ = is_first; }
+
const LayoutObject* GetLayoutObject() const { return layout_object_; }
protected:
@@ -80,6 +83,7 @@ class CORE_EXPORT NGFragmentBuilder {
LayoutObject* layout_object_ = nullptr;
scoped_refptr<NGBreakToken> break_token_;
bool is_hidden_for_paint_ = false;
+ bool is_first_for_node_ = true;
friend class NGPhysicalFragment;
};
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
new file mode 100644
index 00000000000..167e14136f6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.cc
@@ -0,0 +1,212 @@
+// 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_fragment_child_iterator.h"
+
+#include "third_party/blink/renderer/core/layout/layout_box.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+
+namespace blink {
+
+NGFragmentChildIterator::NGFragmentChildIterator(
+ const NGPhysicalBoxFragment& parent,
+ const NGBlockBreakToken* parent_break_token)
+ : parent_fragment_(&parent),
+ parent_break_token_(parent_break_token),
+ is_fragmentation_context_root_(parent.IsFragmentationContextRoot()) {
+ DCHECK(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
+ current_.link_.fragment = nullptr;
+ if (parent_break_token)
+ child_break_tokens_ = parent_break_token->ChildBreakTokens();
+ if (parent.HasItems()) {
+ current_.cursor_.emplace(*parent.Items());
+ current_.block_break_token_ = parent_break_token;
+ UpdateSelfFromCursor();
+ } else {
+ UpdateSelfFromFragment();
+ }
+}
+
+NGFragmentChildIterator::NGFragmentChildIterator(
+ const NGInlineCursor& parent,
+ const NGBlockBreakToken* parent_break_token,
+ base::span<const NGBreakToken* const> child_break_tokens)
+ : parent_break_token_(parent_break_token),
+ child_break_tokens_(child_break_tokens) {
+ current_.block_break_token_ = parent_break_token;
+ current_.link_.fragment = nullptr;
+ current_.cursor_ = parent.CursorForDescendants();
+ UpdateSelfFromCursor();
+}
+
+NGFragmentChildIterator NGFragmentChildIterator::Descend() const {
+ if (current_.cursor_) {
+ const NGFragmentItem* item = current_.cursor_->CurrentItem();
+ // Descend using the cursor if the current item doesn't establish a new
+ // formatting context.
+ if (!item->IsFormattingContextRoot()) {
+ return NGFragmentChildIterator(
+ *current_.cursor_,
+ current_.BlockBreakToken() ? parent_break_token_ : nullptr,
+ child_break_tokens_.subspan(child_break_token_idx_));
+ }
+ }
+ DCHECK(current_.BoxFragment());
+ return NGFragmentChildIterator(*current_.BoxFragment(),
+ current_.BlockBreakToken());
+}
+
+bool NGFragmentChildIterator::AdvanceChildFragment() {
+ DCHECK(parent_fragment_);
+ const auto children = parent_fragment_->Children();
+ const NGPhysicalBoxFragment* previous_fragment =
+ To<NGPhysicalBoxFragment>(current_.link_.fragment);
+ DCHECK(previous_fragment);
+ if (child_fragment_idx_ < children.size())
+ child_fragment_idx_++;
+ // There may be line box fragments among the children, and we're not
+ // interested in them (lines will already have been handled by the inline
+ // cursor).
+ SkipToBoxFragment();
+ if (child_fragment_idx_ >= children.size())
+ return false;
+ if (child_break_token_idx_ < child_break_tokens_.size())
+ child_break_token_idx_++;
+ UpdateSelfFromFragment(previous_fragment);
+ return true;
+}
+
+void NGFragmentChildIterator::UpdateSelfFromFragment(
+ const NGPhysicalBoxFragment* previous_fragment) {
+ DCHECK(parent_fragment_);
+ const auto children = parent_fragment_->Children();
+ if (child_fragment_idx_ >= children.size())
+ return;
+ current_.link_ = children[child_fragment_idx_];
+ DCHECK(current_.link_.fragment);
+ SkipToBlockBreakToken();
+ if (child_break_token_idx_ < child_break_tokens_.size()) {
+ 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());
+ current_.break_token_for_fragmentainer_only_ = false;
+ } else if (is_fragmentation_context_root_ && previous_fragment) {
+ if (previous_fragment->IsColumnBox()) {
+ // 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
+ // former column will be ignored by any intervening spanners, and then fed
+ // into the first column that comes after them, as an incoming break
+ // token.
+ current_.block_break_token_ =
+ To<NGBlockBreakToken>(previous_fragment->BreakToken());
+ current_.break_token_for_fragmentainer_only_ = true;
+ } else {
+ // This is a column spanner. 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.
+ DCHECK(
+ NGBlockNode(ToLayoutBox(previous_fragment->GetMutableLayoutObject()))
+ .IsColumnSpanAll());
+
+ // If the previous fragment is a column spanner, it's not expected to have
+ // a break token; if a spanner runs out of space, no columns (or spanners)
+ // would fit after it.
+ DCHECK(!previous_fragment->BreakToken());
+ }
+ } else {
+ current_.block_break_token_ = nullptr;
+ }
+}
+
+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();
+ }
+ UpdateSelfFromCursor();
+ if (current_.cursor_->CurrentItem())
+ return true;
+ // If there are more items, proceed and see if we have box fragment
+ // children. There may be out-of-flow positioned child fragments.
+ if (!parent_fragment_)
+ return false;
+ current_.cursor_.reset();
+ SkipToBoxFragment();
+ UpdateSelfFromFragment();
+ return !IsAtEnd();
+}
+
+void NGFragmentChildIterator::UpdateSelfFromCursor() {
+ DCHECK(current_.cursor_);
+ // For inline items we just use the incoming break token to the containing
+ // block.
+ current_.block_break_token_ = parent_break_token_;
+ const NGFragmentItem* item = current_.cursor_->CurrentItem();
+ if (!item) {
+ current_.link_.fragment = nullptr;
+ 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() {
+ for (const auto children = parent_fragment_->Children();
+ child_fragment_idx_ < children.size(); child_fragment_idx_++) {
+ if (children[child_fragment_idx_].fragment->IsBox())
+ break;
+ }
+}
+
+void NGFragmentChildIterator::SkipToBlockBreakToken() {
+ // There may be inline break tokens here. Ignore them.
+ while (child_break_token_idx_ < child_break_tokens_.size() &&
+ !child_break_tokens_[child_break_token_idx_]->IsBlockType())
+ child_break_token_idx_++;
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..c4927f0acad
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.h
@@ -0,0 +1,141 @@
+// 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_NG_FRAGMENT_CHILD_ITERATOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_FRAGMENT_CHILD_ITERATOR_H_
+
+#include "base/containers/span.h"
+#include "base/optional.h"
+#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_inline_cursor.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_link.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
+
+namespace blink {
+
+class LayoutObject;
+class NGBlockBreakToken;
+
+// Iterator for children of a box fragment. Supports fragment items and break
+// tokens. To advance to the next sibling, call |Advance()|. To descend into
+// children of the current child, call |Descend()|.
+//
+// Using this class requires LayoutNGFragmentItem to be enabled. While fragment
+// items are in a flat list representing the contents of an inline formatting
+// context, the iterator will to a certain extent restore the object hierarchy,
+// so that we can calculate the global offset of children of a relatively
+// positioned inline correctly.
+class CORE_EXPORT NGFragmentChildIterator {
+ STACK_ALLOCATED();
+
+ public:
+ explicit NGFragmentChildIterator(
+ const NGPhysicalBoxFragment& parent,
+ const NGBlockBreakToken* parent_break_token = nullptr);
+
+ // Create a child iterator for the current child.
+ NGFragmentChildIterator Descend() const;
+
+ // Move to the next sibling. Return false if there's no next sibling. Once
+ // false is returned, this object is in an unusable state, with the exception
+ // that calling IsAtEnd() is allowed.
+ bool Advance() {
+ if (current_.cursor_)
+ return AdvanceWithCursor();
+ return AdvanceChildFragment();
+ }
+
+ bool IsAtEnd() {
+ if (current_.cursor_)
+ return !*current_.cursor_;
+ DCHECK(parent_fragment_);
+ const auto children = parent_fragment_->Children();
+ return child_fragment_idx_ >= children.size();
+ }
+
+ class Current {
+ friend class NGFragmentChildIterator;
+
+ public:
+ // Return the current NGLink. Note that its offset is relative to the inline
+ // formatting context root, if the fragment / item participates in one.
+ const NGLink& Link() const { return link_; }
+
+ const NGPhysicalBoxFragment* BoxFragment() const {
+ return To<NGPhysicalBoxFragment>(link_.fragment);
+ }
+ const NGFragmentItem* FragmentItem() const {
+ if (!cursor_)
+ return nullptr;
+ return cursor_->CurrentItem();
+ }
+
+ // Get the incoming break token for the current child, i.e. the context at
+ // which layout of this child's node was resumed. Note that for text and
+ // non-atomic inlines this will be the incoming block break token to the
+ // inline formatting context root. For monolithic content, no break token
+ // will be returned (since such content isn't considered to participate in a
+ // fragmentation context).
+ const NGBlockBreakToken* BlockBreakToken() const {
+ if (LIKELY(!block_break_token_))
+ return nullptr;
+ if (link_.fragment) {
+ // Don't pass the break token into monolithic content.
+ if (link_.fragment->IsMonolithic())
+ return nullptr;
+ // If the break token we've found is from a fragmentainer, it's only to
+ // 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())
+ return nullptr;
+ }
+ return block_break_token_;
+ }
+
+ const LayoutObject* GetLayoutObject() const {
+ if (const NGFragmentItem* item = FragmentItem())
+ return item->GetLayoutObject();
+ return BoxFragment()->GetLayoutObject();
+ }
+
+ private:
+ NGLink link_;
+ base::Optional<NGInlineCursor> cursor_;
+ const NGBlockBreakToken* block_break_token_ = nullptr;
+ bool break_token_for_fragmentainer_only_ = false;
+ };
+
+ const Current& GetCurrent() const { return current_; }
+ const Current& operator*() const { return current_; }
+ const Current* operator->() const { return &current_; }
+
+ private:
+ NGFragmentChildIterator(
+ const NGInlineCursor& parent,
+ const NGBlockBreakToken* parent_break_token,
+ base::span<const NGBreakToken* const> child_break_tokens);
+
+ bool AdvanceChildFragment();
+ void UpdateSelfFromFragment(
+ const NGPhysicalBoxFragment* previous_fragment = nullptr);
+
+ bool AdvanceWithCursor();
+ void UpdateSelfFromCursor();
+ void SkipToBoxFragment();
+ void SkipToBlockBreakToken();
+
+ const NGPhysicalBoxFragment* parent_fragment_ = nullptr;
+ const NGBlockBreakToken* parent_break_token_ = nullptr;
+ Current current_;
+ base::span<const NGBreakToken* const> child_break_tokens_;
+ wtf_size_t child_fragment_idx_ = 0;
+ wtf_size_t child_break_token_idx_ = 0;
+ bool is_fragmentation_context_root_ = false;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_FRAGMENT_CHILD_ITERATOR_H_
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator_test.cc
new file mode 100644
index 00000000000..f0304c056d1
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator_test.cc
@@ -0,0 +1,808 @@
+// 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_fragment_child_iterator.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_base_layout_algorithm_test.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h"
+#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
+
+namespace blink {
+namespace {
+
+class NGFragmentChildIteratorTest
+ : public NGBaseLayoutAlgorithmTest,
+ private ScopedLayoutNGBlockFragmentationForTest,
+ private ScopedLayoutNGFragmentItemForTest {
+ protected:
+ NGFragmentChildIteratorTest()
+ : ScopedLayoutNGBlockFragmentationForTest(true),
+ ScopedLayoutNGFragmentItemForTest(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);
+ }
+};
+
+TEST_F(NGFragmentChildIteratorTest, Basic) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="container">
+ <div id="child1">
+ <div id="grandchild"></div>
+ </div>
+ <div id="child2"></div>
+ </div>
+ )HTML");
+
+ const LayoutObject* child1 = GetLayoutObjectByElementId("child1");
+ const LayoutObject* child2 = GetLayoutObjectByElementId("child2");
+ const LayoutObject* grandchild = GetLayoutObjectByElementId("grandchild");
+
+ scoped_refptr<const NGPhysicalBoxFragment> container =
+ RunBlockLayoutAlgorithm(GetElementById("container"));
+ NGFragmentChildIterator iterator1(*container.get());
+ EXPECT_FALSE(iterator1.IsAtEnd());
+
+ const NGPhysicalBoxFragment* fragment = iterator1->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), child1);
+ EXPECT_FALSE(iterator1.IsAtEnd());
+
+ NGFragmentChildIterator iterator2 = iterator1.Descend();
+ EXPECT_FALSE(iterator2.IsAtEnd());
+ fragment = iterator2->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), grandchild);
+ EXPECT_FALSE(iterator2.IsAtEnd());
+ EXPECT_FALSE(iterator2.Advance());
+ EXPECT_TRUE(iterator2.IsAtEnd());
+
+ EXPECT_TRUE(iterator1.Advance());
+ fragment = iterator1->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), child2);
+ EXPECT_FALSE(iterator1.IsAtEnd());
+
+ // #child2 has no children.
+ EXPECT_TRUE(iterator1.Descend().IsAtEnd());
+
+ // No more children left.
+ EXPECT_FALSE(iterator1.Advance());
+ EXPECT_TRUE(iterator1.IsAtEnd());
+}
+
+TEST_F(NGFragmentChildIteratorTest, BasicInline) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="container">
+ xxx
+ <span id="span1" style="border:solid;">
+ <div id="float1" style="float:left;"></div>
+ xxx
+ </span>
+ xxx
+ </div>
+ )HTML");
+
+ const LayoutObject* span1 = GetLayoutObjectByElementId("span1");
+ const LayoutObject* float1 = GetLayoutObjectByElementId("float1");
+
+ scoped_refptr<const NGPhysicalBoxFragment> container =
+ RunBlockLayoutAlgorithm(GetElementById("container"));
+ NGFragmentChildIterator iterator1(*container.get());
+
+ EXPECT_FALSE(iterator1->BoxFragment());
+ const NGFragmentItem* fragment_item = iterator1->FragmentItem();
+ ASSERT_TRUE(fragment_item);
+ EXPECT_EQ(fragment_item->Type(), NGFragmentItem::kLine);
+
+ // Descend into the line box.
+ NGFragmentChildIterator iterator2 = iterator1.Descend();
+ fragment_item = iterator2->FragmentItem();
+ ASSERT_TRUE(fragment_item);
+ EXPECT_TRUE(fragment_item->IsText());
+
+ EXPECT_TRUE(iterator2.Advance());
+ const NGPhysicalBoxFragment* fragment = iterator2->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), span1);
+
+ // Descend into children of #span1.
+ NGFragmentChildIterator iterator3 = iterator2.Descend();
+ fragment = iterator3->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), float1);
+
+ EXPECT_TRUE(iterator3.Advance());
+ fragment_item = iterator3->FragmentItem();
+ ASSERT_TRUE(fragment_item);
+ EXPECT_TRUE(fragment_item->IsText());
+ EXPECT_FALSE(iterator3.Advance());
+
+ // Continue with siblings of #span1.
+ EXPECT_TRUE(iterator2.Advance());
+ fragment_item = iterator2->FragmentItem();
+ ASSERT_TRUE(fragment_item);
+ EXPECT_TRUE(fragment_item->IsText());
+
+ EXPECT_FALSE(iterator2.Advance());
+ EXPECT_FALSE(iterator1.Advance());
+}
+
+TEST_F(NGFragmentChildIteratorTest, InlineBlock) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="container">
+ xxx
+ <span id="inlineblock">
+ <div id="float1" style="float:left;"></div>
+ </span>
+ xxx
+ </div>
+ )HTML");
+
+ const LayoutObject* inlineblock = GetLayoutObjectByElementId("inlineblock");
+ const LayoutObject* float1 = GetLayoutObjectByElementId("float1");
+
+ scoped_refptr<const NGPhysicalBoxFragment> container =
+ RunBlockLayoutAlgorithm(GetElementById("container"));
+ NGFragmentChildIterator iterator1(*container.get());
+
+ EXPECT_FALSE(iterator1->BoxFragment());
+ const NGFragmentItem* fragment_item = iterator1->FragmentItem();
+ ASSERT_TRUE(fragment_item);
+ EXPECT_EQ(fragment_item->Type(), NGFragmentItem::kLine);
+
+ // Descend into the line box.
+ NGFragmentChildIterator iterator2 = iterator1.Descend();
+ fragment_item = iterator2->FragmentItem();
+ ASSERT_TRUE(fragment_item);
+ EXPECT_TRUE(fragment_item->IsText());
+
+ EXPECT_TRUE(iterator2.Advance());
+ const NGPhysicalBoxFragment* fragment = iterator2->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), inlineblock);
+
+ // Descend into children of #inlineblock.
+ NGFragmentChildIterator iterator3 = iterator2.Descend();
+ fragment = iterator3->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), float1);
+ EXPECT_FALSE(iterator3.Advance());
+
+ // Continue with siblings of #inlineblock.
+ EXPECT_TRUE(iterator2.Advance());
+ fragment_item = iterator2->FragmentItem();
+ ASSERT_TRUE(fragment_item);
+ EXPECT_TRUE(fragment_item->IsText());
+
+ EXPECT_FALSE(iterator2.Advance());
+ EXPECT_FALSE(iterator1.Advance());
+}
+
+TEST_F(NGFragmentChildIteratorTest, FloatsInInline) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="container">
+ <span id="span1" style="border:solid;">
+ <div id="float1" style="float:left;">
+ <div id="child"></div>
+ </div>
+ </span>
+ </div>
+ )HTML");
+
+ const LayoutObject* span1 = GetLayoutObjectByElementId("span1");
+ const LayoutObject* float1 = GetLayoutObjectByElementId("float1");
+ const LayoutObject* child = GetLayoutObjectByElementId("child");
+
+ scoped_refptr<const NGPhysicalBoxFragment> container =
+ RunBlockLayoutAlgorithm(GetElementById("container"));
+ NGFragmentChildIterator iterator1(*container.get());
+
+ const NGPhysicalBoxFragment* fragment = iterator1->BoxFragment();
+ EXPECT_FALSE(fragment);
+ const NGFragmentItem* item = iterator1->FragmentItem();
+ ASSERT_TRUE(item);
+ EXPECT_EQ(item->Type(), NGFragmentItem::kLine);
+
+ // Descend into the line box.
+ NGFragmentChildIterator iterator2 = iterator1.Descend();
+ fragment = iterator2->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), span1);
+
+ // Descend into children of #span1.
+ NGFragmentChildIterator iterator3 = iterator2.Descend();
+ fragment = iterator3->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), float1);
+
+ // Descend into children of #float1.
+ NGFragmentChildIterator iterator4 = iterator3.Descend();
+ fragment = iterator4->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), child);
+
+ EXPECT_FALSE(iterator4.Advance());
+ EXPECT_FALSE(iterator3.Advance());
+ EXPECT_FALSE(iterator2.Advance());
+ EXPECT_FALSE(iterator1.Advance());
+}
+
+TEST_F(NGFragmentChildIteratorTest, AbsposAndLine) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="container" style="position:relative;">
+ <div id="abspos" style="position:absolute;"></div>
+ xxx
+ </div>
+ )HTML");
+
+ const LayoutObject* abspos = GetLayoutObjectByElementId("abspos");
+
+ scoped_refptr<const NGPhysicalBoxFragment> container =
+ RunBlockLayoutAlgorithm(GetElementById("container"));
+ NGFragmentChildIterator iterator1(*container.get());
+
+ const NGPhysicalBoxFragment* fragment = iterator1->BoxFragment();
+ EXPECT_FALSE(fragment);
+ const NGFragmentItem* item = iterator1->FragmentItem();
+ ASSERT_TRUE(item);
+ EXPECT_EQ(item->Type(), NGFragmentItem::kLine);
+
+ // Descend into the line box.
+ NGFragmentChildIterator iterator2 = iterator1.Descend();
+
+ fragment = iterator2->BoxFragment();
+ EXPECT_FALSE(fragment);
+ item = iterator2->FragmentItem();
+ ASSERT_TRUE(item);
+ EXPECT_TRUE(item->IsText());
+ EXPECT_FALSE(iterator2.Advance());
+
+ // The abspos is a sibling of the line box.
+ EXPECT_TRUE(iterator1.Advance());
+ fragment = iterator1->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), abspos);
+ EXPECT_FALSE(iterator1.Advance());
+}
+
+TEST_F(NGFragmentChildIteratorTest, BasicMulticol) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="container">
+ <div id="mc" style="columns:3; padding:2px; column-fill:auto; column-gap:10px; width:320px; height:100px;">
+ <div id="child" style="margin-top:30px; margin-left:4px; height:200px;"></div>
+ </div>
+ </div>
+ )HTML");
+
+ const LayoutObject* mc = GetLayoutObjectByElementId("mc");
+ const LayoutObject* child = GetLayoutObjectByElementId("child");
+
+ scoped_refptr<const NGPhysicalBoxFragment> container =
+ RunBlockLayoutAlgorithm(GetElementById("container"));
+ NGFragmentChildIterator iterator(*container.get());
+
+ const NGPhysicalBoxFragment* fragment = iterator->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), mc);
+
+ // First column.
+ NGFragmentChildIterator child_iterator = iterator.Descend();
+ fragment = child_iterator->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_TRUE(fragment->IsColumnBox());
+ EXPECT_EQ(child_iterator->Link().offset.top, LayoutUnit(2));
+ EXPECT_EQ(child_iterator->Link().offset.left, LayoutUnit(2));
+ EXPECT_EQ(fragment->Size().height, LayoutUnit(100));
+ EXPECT_FALSE(fragment->GetLayoutObject());
+ EXPECT_FALSE(child_iterator->BlockBreakToken());
+
+ NGFragmentChildIterator grandchild_iterator = child_iterator.Descend();
+ fragment = grandchild_iterator->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(grandchild_iterator->Link().offset.top, LayoutUnit(30));
+ EXPECT_EQ(grandchild_iterator->Link().offset.left, LayoutUnit(4));
+ EXPECT_EQ(fragment->Size().height, LayoutUnit(70));
+ EXPECT_EQ(fragment->GetLayoutObject(), child);
+ EXPECT_FALSE(grandchild_iterator.Advance());
+ EXPECT_FALSE(grandchild_iterator->BlockBreakToken());
+
+ // Second column.
+ ASSERT_TRUE(child_iterator.Advance());
+ fragment = child_iterator->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_TRUE(fragment->IsColumnBox());
+ EXPECT_EQ(child_iterator->Link().offset.top, LayoutUnit(2));
+ EXPECT_EQ(child_iterator->Link().offset.left, LayoutUnit(112));
+ EXPECT_EQ(fragment->Size().height, LayoutUnit(100));
+ EXPECT_FALSE(fragment->GetLayoutObject());
+ const auto* break_token = child_iterator->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(100));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc);
+
+ grandchild_iterator = child_iterator.Descend();
+ fragment = grandchild_iterator->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(grandchild_iterator->Link().offset.top, LayoutUnit(0));
+ EXPECT_EQ(grandchild_iterator->Link().offset.left, LayoutUnit(4));
+ EXPECT_EQ(fragment->Size().height, LayoutUnit(100));
+ EXPECT_EQ(fragment->GetLayoutObject(), child);
+ EXPECT_FALSE(grandchild_iterator.Advance());
+ break_token = grandchild_iterator->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(70));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), child);
+
+ // Third column.
+ ASSERT_TRUE(child_iterator.Advance());
+ fragment = child_iterator->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_TRUE(fragment->IsColumnBox());
+ EXPECT_EQ(child_iterator->Link().offset.top, LayoutUnit(2));
+ EXPECT_EQ(child_iterator->Link().offset.left, LayoutUnit(222));
+ EXPECT_EQ(fragment->Size().height, LayoutUnit(100));
+ EXPECT_FALSE(fragment->GetLayoutObject());
+ break_token = child_iterator->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(200));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc);
+
+ grandchild_iterator = child_iterator.Descend();
+ fragment = grandchild_iterator->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(grandchild_iterator->Link().offset.top, LayoutUnit(0));
+ EXPECT_EQ(grandchild_iterator->Link().offset.left, LayoutUnit(4));
+ EXPECT_EQ(fragment->Size().height, LayoutUnit(30));
+ EXPECT_EQ(fragment->GetLayoutObject(), child);
+ EXPECT_FALSE(grandchild_iterator.Advance());
+ break_token = grandchild_iterator->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(170));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), child);
+
+ EXPECT_FALSE(child_iterator.Advance());
+ EXPECT_FALSE(iterator.Advance());
+}
+
+TEST_F(NGFragmentChildIteratorTest, ColumnSpanner) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="container">
+ <div id="mc" style="columns:2;">
+ <div id="child">
+ <div id="grandchild1" style="height:150px;"></div>
+ <div id="spanner" style="column-span:all; height:11px;"></div>
+ <div id="grandchild2" style="height:66px;"></div>
+ </div>
+ </div>
+ </div>
+ )HTML");
+
+ scoped_refptr<const NGPhysicalBoxFragment> container =
+ RunBlockLayoutAlgorithm(GetElementById("container"));
+ NGFragmentChildIterator iterator1(*container.get());
+
+ const LayoutObject* mc = GetLayoutObjectByElementId("mc");
+ const LayoutObject* child = GetLayoutObjectByElementId("child");
+ const LayoutObject* spanner = GetLayoutObjectByElementId("spanner");
+ const LayoutObject* grandchild1 = GetLayoutObjectByElementId("grandchild1");
+ const LayoutObject* grandchild2 = GetLayoutObjectByElementId("grandchild2");
+
+ const NGPhysicalBoxFragment* fragment = iterator1->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), mc);
+
+ // First column before spanner.
+ NGFragmentChildIterator iterator2 = iterator1.Descend();
+ fragment = iterator2->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_TRUE(fragment->IsColumnBox());
+ EXPECT_EQ(fragment->Size().height, LayoutUnit(75));
+ EXPECT_FALSE(fragment->GetLayoutObject());
+ EXPECT_FALSE(iterator2->BlockBreakToken());
+
+ // First fragment for #child.
+ NGFragmentChildIterator iterator3 = iterator2.Descend();
+ fragment = iterator3->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->Size().height, LayoutUnit(75));
+ EXPECT_EQ(fragment->GetLayoutObject(), child);
+ EXPECT_FALSE(iterator3->BlockBreakToken());
+
+ // First fragment for #grandchild1.
+ NGFragmentChildIterator iterator4 = iterator3.Descend();
+ fragment = iterator4->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->Size().height, LayoutUnit(75));
+ EXPECT_EQ(fragment->GetLayoutObject(), grandchild1);
+ EXPECT_FALSE(iterator4->BlockBreakToken());
+ EXPECT_FALSE(iterator4.Advance());
+ EXPECT_FALSE(iterator3.Advance());
+
+ // Second column before spanner.
+ EXPECT_TRUE(iterator2.Advance());
+ fragment = iterator2->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_TRUE(fragment->IsColumnBox());
+ EXPECT_EQ(fragment->Size().height, LayoutUnit(75));
+ EXPECT_FALSE(fragment->GetLayoutObject());
+ const auto* break_token = iterator2->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(75));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc);
+
+ // Second fragment for #child.
+ iterator3 = iterator2.Descend();
+ fragment = iterator3->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->Size().height, LayoutUnit(75));
+ EXPECT_EQ(fragment->GetLayoutObject(), child);
+ break_token = iterator3->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(75));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), child);
+
+ // Second fragment for #grandchild1.
+ iterator4 = iterator3.Descend();
+ fragment = iterator4->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->Size().height, LayoutUnit(75));
+ EXPECT_EQ(fragment->GetLayoutObject(), grandchild1);
+ break_token = iterator4->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(75));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), grandchild1);
+ EXPECT_FALSE(iterator4.Advance());
+ EXPECT_FALSE(iterator3.Advance());
+
+ // The spanner.
+ EXPECT_TRUE(iterator2.Advance());
+ fragment = iterator2->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->Size().height, LayoutUnit(11));
+ EXPECT_EQ(fragment->GetLayoutObject(), spanner);
+ EXPECT_FALSE(iterator2->BlockBreakToken());
+
+ // First column after spanner.
+ EXPECT_TRUE(iterator2.Advance());
+ fragment = iterator2->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_TRUE(fragment->IsColumnBox());
+ EXPECT_EQ(fragment->Size().height, LayoutUnit(33));
+ EXPECT_FALSE(fragment->GetLayoutObject());
+ break_token = iterator2->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(150));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc);
+
+ // Third fragment for #child.
+ iterator3 = iterator2.Descend();
+ fragment = iterator3->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->Size().height, LayoutUnit(33));
+ EXPECT_EQ(fragment->GetLayoutObject(), child);
+ break_token = iterator3->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(150));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), child);
+
+ // First fragment for #grandchild2.
+ iterator4 = iterator3.Descend();
+ fragment = iterator4->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->Size().height, LayoutUnit(33));
+ EXPECT_EQ(fragment->GetLayoutObject(), grandchild2);
+ break_token = iterator4->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_TRUE(break_token->IsBreakBefore());
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), grandchild2);
+ EXPECT_FALSE(iterator4.Advance());
+ EXPECT_FALSE(iterator3.Advance());
+
+ // Second column after spanner.
+ EXPECT_TRUE(iterator2.Advance());
+ fragment = iterator2->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_TRUE(fragment->IsColumnBox());
+ EXPECT_EQ(fragment->Size().height, LayoutUnit(33));
+ EXPECT_FALSE(fragment->GetLayoutObject());
+ break_token = iterator2->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(183));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc);
+
+ // Fourth fragment for #child.
+ iterator3 = iterator2.Descend();
+ fragment = iterator3->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->Size().height, LayoutUnit(33));
+ EXPECT_EQ(fragment->GetLayoutObject(), child);
+ break_token = iterator3->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(183));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), child);
+
+ // Second fragment for #grandchild2.
+ iterator4 = iterator3.Descend();
+ fragment = iterator4->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->Size().height, LayoutUnit(33));
+ EXPECT_EQ(fragment->GetLayoutObject(), grandchild2);
+ break_token = iterator4->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(33));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), grandchild2);
+ EXPECT_FALSE(iterator4.Advance());
+ EXPECT_FALSE(iterator3.Advance());
+
+ EXPECT_FALSE(iterator2.Advance());
+ EXPECT_FALSE(iterator1.Advance());
+}
+
+TEST_F(NGFragmentChildIteratorTest, NestedWithColumnSpanner) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="container">
+ <div id="mc1" style="columns:2; column-fill:auto; height:100px;">
+ <div id="mc2" style="columns:2;">
+ <div id="child1" style="height:150px;"></div>
+ <div id="spanner1" style="column-span:all;">
+ <div id="spanner1child" style="height:55px;"></div>
+ </div>
+ <div id="child2" style="height:50px;"></div>
+ <div id="spanner2" style="column-span:all;">
+ <div id="spanner2child" style="height:20px;"></div>
+ </div>
+ <div id="child3" style="height:20px;"></div>
+ </div>
+ </div>
+ </div>
+ )HTML");
+
+ scoped_refptr<const NGPhysicalBoxFragment> container =
+ RunBlockLayoutAlgorithm(GetElementById("container"));
+ NGFragmentChildIterator iterator1(*container.get());
+
+ const LayoutObject* mc1 = GetLayoutObjectByElementId("mc1");
+ const LayoutObject* mc2 = GetLayoutObjectByElementId("mc2");
+ const LayoutObject* child1 = GetLayoutObjectByElementId("child1");
+ const LayoutObject* child2 = GetLayoutObjectByElementId("child2");
+ const LayoutObject* child3 = GetLayoutObjectByElementId("child3");
+ const LayoutObject* spanner1 = GetLayoutObjectByElementId("spanner1");
+ const LayoutObject* spanner2 = GetLayoutObjectByElementId("spanner2");
+ const LayoutObject* spanner1child =
+ GetLayoutObjectByElementId("spanner1child");
+ const LayoutObject* spanner2child =
+ GetLayoutObjectByElementId("spanner2child");
+
+ const NGPhysicalBoxFragment* fragment = iterator1->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), mc1);
+
+ // First outer column.
+ NGFragmentChildIterator iterator2 = iterator1.Descend();
+ fragment = iterator2->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_TRUE(fragment->IsColumnBox());
+ EXPECT_FALSE(fragment->GetLayoutObject());
+ EXPECT_FALSE(iterator2->BlockBreakToken());
+
+ // First fragment for #mc2.
+ NGFragmentChildIterator iterator3 = iterator2.Descend();
+ fragment = iterator3->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), mc2);
+ EXPECT_FALSE(iterator3->BlockBreakToken());
+
+ // First inner column in first outer column.
+ NGFragmentChildIterator iterator4 = iterator3.Descend();
+ fragment = iterator4->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_TRUE(fragment->IsColumnBox());
+ EXPECT_FALSE(fragment->GetLayoutObject());
+ EXPECT_FALSE(iterator4->BlockBreakToken());
+
+ // First fragment for #child1.
+ NGFragmentChildIterator iterator5 = iterator4.Descend();
+ fragment = iterator5->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), child1);
+ EXPECT_FALSE(iterator5->BlockBreakToken());
+ EXPECT_FALSE(iterator5.Advance());
+
+ // Second inner column in first outer column.
+ EXPECT_TRUE(iterator4.Advance());
+ fragment = iterator4->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_TRUE(fragment->IsColumnBox());
+ EXPECT_FALSE(fragment->GetLayoutObject());
+ const auto* break_token = iterator4->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(75));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc2);
+
+ // Second fragment for #child1.
+ iterator5 = iterator4.Descend();
+ fragment = iterator5->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), child1);
+ break_token = iterator5->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(75));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), child1);
+
+ // First fragment for #spanner1 (it's split into the first and second outer
+ // columns).
+ EXPECT_TRUE(iterator4.Advance());
+ fragment = iterator4->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), spanner1);
+ EXPECT_FALSE(iterator4->BlockBreakToken());
+
+ // First fragment for #spanner1child
+ iterator5 = iterator4.Descend();
+ fragment = iterator5->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), spanner1child);
+ EXPECT_FALSE(iterator5->BlockBreakToken());
+ EXPECT_FALSE(iterator5.Advance());
+ EXPECT_FALSE(iterator4.Advance());
+ EXPECT_FALSE(iterator3.Advance());
+
+ // Second outer column
+ EXPECT_TRUE(iterator2.Advance());
+ fragment = iterator2->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_TRUE(fragment->IsColumnBox());
+ EXPECT_FALSE(fragment->GetLayoutObject());
+ break_token = iterator2->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(100));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc1);
+
+ // Second fragment for #mc2.
+ iterator3 = iterator2.Descend();
+ fragment = iterator3->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), mc2);
+ break_token = iterator3->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(100));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc2);
+
+ // Second fragment for #spanner1 (it's split into the first and second outer
+ // columns).
+ iterator4 = iterator3.Descend();
+ fragment = iterator4->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), spanner1);
+ break_token = iterator4->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(25));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), spanner1);
+
+ // Second fragment for #spanner1child.
+ iterator5 = iterator4.Descend();
+ fragment = iterator5->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), spanner1child);
+ break_token = iterator5->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(25));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), spanner1child);
+ EXPECT_FALSE(iterator5.Advance());
+
+ // First inner column after first spanner in second outer column.
+ EXPECT_TRUE(iterator4.Advance());
+ fragment = iterator4->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_TRUE(fragment->IsColumnBox());
+ EXPECT_FALSE(fragment->GetLayoutObject());
+ break_token = iterator4->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(150));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc2);
+
+ // First fragment for #child2.
+ iterator5 = iterator4.Descend();
+ fragment = iterator5->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), child2);
+ break_token = iterator5->BlockBreakToken();
+ EXPECT_TRUE(break_token);
+ EXPECT_TRUE(break_token->IsBreakBefore());
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), child2);
+ EXPECT_FALSE(iterator5.Advance());
+
+ // Second inner column after first spanner in second outer column.
+ EXPECT_TRUE(iterator4.Advance());
+ fragment = iterator4->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_TRUE(fragment->IsColumnBox());
+ EXPECT_FALSE(fragment->GetLayoutObject());
+ break_token = iterator4->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(175));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc2);
+
+ // Second fragment for #child2.
+ iterator5 = iterator4.Descend();
+ fragment = iterator5->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), child2);
+ break_token = iterator5->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(25));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), child2);
+ EXPECT_FALSE(iterator5.Advance());
+
+ // The only fragment for #spanner2
+ EXPECT_TRUE(iterator4.Advance());
+ fragment = iterator4->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), spanner2);
+ EXPECT_FALSE(iterator4->BlockBreakToken());
+
+ // First fragment for #spanner2child
+ iterator5 = iterator4.Descend();
+ fragment = iterator5->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), spanner2child);
+ EXPECT_FALSE(iterator5->BlockBreakToken());
+ EXPECT_FALSE(iterator5.Advance());
+
+ // First inner column after second spanner in second outer column.
+ EXPECT_TRUE(iterator4.Advance());
+ fragment = iterator4->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_TRUE(fragment->IsColumnBox());
+ EXPECT_FALSE(fragment->GetLayoutObject());
+ break_token = iterator4->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(200));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc2);
+
+ // First fragment for #child3.
+ iterator5 = iterator4.Descend();
+ fragment = iterator5->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), child3);
+ break_token = iterator5->BlockBreakToken();
+ EXPECT_TRUE(break_token);
+ EXPECT_TRUE(break_token->IsBreakBefore());
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), child3);
+ EXPECT_FALSE(iterator5.Advance());
+
+ // Second inner column after second spanner in second outer column.
+ EXPECT_TRUE(iterator4.Advance());
+ fragment = iterator4->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_TRUE(fragment->IsColumnBox());
+ EXPECT_FALSE(fragment->GetLayoutObject());
+ break_token = iterator4->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(210));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), mc2);
+
+ // Second fragment for #child3.
+ iterator5 = iterator4.Descend();
+ fragment = iterator5->BoxFragment();
+ ASSERT_TRUE(fragment);
+ EXPECT_EQ(fragment->GetLayoutObject(), child3);
+ break_token = iterator5->BlockBreakToken();
+ ASSERT_TRUE(break_token);
+ EXPECT_EQ(break_token->ConsumedBlockSize(), LayoutUnit(10));
+ EXPECT_EQ(break_token->InputNode().GetLayoutBox(), child3);
+ EXPECT_FALSE(iterator5.Advance());
+ EXPECT_FALSE(iterator4.Advance());
+ EXPECT_FALSE(iterator3.Advance());
+ EXPECT_FALSE(iterator2.Advance());
+ EXPECT_FALSE(iterator1.Advance());
+}
+
+} // anonymous namespace
+} // namespace blink
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
new file mode 100644
index 00000000000..a0ddc40690f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_fragmentation_test.cc
@@ -0,0 +1,197 @@
+// 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_base_layout_algorithm_test.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.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/platform/testing/runtime_enabled_features_test_helpers.h"
+
+namespace blink {
+namespace {
+
+class NGFragmentationTest : public NGBaseLayoutAlgorithmTest,
+ private ScopedLayoutNGBlockFragmentationForTest {
+ protected:
+ NGFragmentationTest() : 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);
+ }
+};
+
+TEST_F(NGFragmentationTest, MultipleFragments) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="container">
+ <div style="columns:3; width:620px; column-fill:auto; height:100px; column-gap:10px;">
+ <div id="outer1" style="height:150px;">
+ <div id="inner1" style="height:250px;"></div>
+ <div id="inner2" style="height:10px;"></div>
+ </div>
+ <div id="outer2" style="height:90px;"></div>
+ </div>
+ </div>
+ )HTML");
+
+ RunBlockLayoutAlgorithm(GetElementById("container"));
+ const LayoutBox* outer1 = ToLayoutBox(GetLayoutObjectByElementId("outer1"));
+ const LayoutBox* outer2 = ToLayoutBox(GetLayoutObjectByElementId("outer2"));
+ const LayoutBox* inner1 = ToLayoutBox(GetLayoutObjectByElementId("inner1"));
+ const LayoutBox* inner2 = ToLayoutBox(GetLayoutObjectByElementId("inner2"));
+
+ EXPECT_EQ(outer1->PhysicalFragmentCount(), 3u);
+ EXPECT_EQ(outer2->PhysicalFragmentCount(), 2u);
+ EXPECT_EQ(inner1->PhysicalFragmentCount(), 3u);
+ EXPECT_EQ(inner2->PhysicalFragmentCount(), 1u);
+
+ // While the #outer1 box itself only needs two fragments, we need to create a
+ // third fragment to hold the overflowing children in the third column.
+ EXPECT_EQ(outer1->GetPhysicalFragment(0)->Size(), PhysicalSize(200, 100));
+ EXPECT_EQ(outer1->GetPhysicalFragment(1)->Size(), PhysicalSize(200, 50));
+ EXPECT_EQ(outer1->GetPhysicalFragment(2)->Size(), PhysicalSize(200, 0));
+
+ // #inner1 overflows its parent and uses three columns.
+ EXPECT_EQ(inner1->GetPhysicalFragment(0)->Size(), PhysicalSize(200, 100));
+ EXPECT_EQ(inner1->GetPhysicalFragment(1)->Size(), PhysicalSize(200, 100));
+ EXPECT_EQ(inner1->GetPhysicalFragment(2)->Size(), PhysicalSize(200, 50));
+
+ // #inner2 is tiny, and only needs some space in one column (the third one).
+ EXPECT_EQ(inner2->GetPhysicalFragment(0)->Size(), PhysicalSize(200, 10));
+
+ // #outer2 starts in the second column and ends in the third.
+ EXPECT_EQ(outer2->GetPhysicalFragment(0)->Size(), PhysicalSize(200, 50));
+ EXPECT_EQ(outer2->GetPhysicalFragment(1)->Size(), PhysicalSize(200, 40));
+}
+
+TEST_F(NGFragmentationTest, MultipleFragmentsAndColumnSpanner) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="container">
+ <div id="multicol" style="columns:3; width:620px; column-gap:10px; orphans:1; widows:1; line-height:20px;">
+ <div id="outer">
+ <div id="inner1"><br><br><br><br></div>
+ <div id="spanner1" style="column-span:all;"></div>
+ <div id="inner2"><br><br><br><br><br></div>
+ <div id="spanner2" style="column-span:all;"></div>
+ <div id="inner3"><br><br><br><br><br><br><br></div>
+ </div>
+ </div>
+ </div>
+ )HTML");
+
+ RunBlockLayoutAlgorithm(GetElementById("container"));
+ const LayoutBox* multicol =
+ ToLayoutBox(GetLayoutObjectByElementId("multicol"));
+ const LayoutBox* outer = ToLayoutBox(GetLayoutObjectByElementId("outer"));
+ const LayoutBox* inner1 = ToLayoutBox(GetLayoutObjectByElementId("inner1"));
+ const LayoutBox* inner2 = ToLayoutBox(GetLayoutObjectByElementId("inner2"));
+ const LayoutBox* inner3 = ToLayoutBox(GetLayoutObjectByElementId("inner3"));
+ const LayoutBox* spanner1 =
+ ToLayoutBox(GetLayoutObjectByElementId("spanner1"));
+ const LayoutBox* spanner2 =
+ ToLayoutBox(GetLayoutObjectByElementId("spanner2"));
+
+ EXPECT_EQ(multicol->PhysicalFragmentCount(), 1u);
+
+ // #outer will create 8 fragments: 2 for the 2 columns before the first
+ // spanner, 3 for the 3 columns between the two spanners, and 3 for the 3
+ // columns after the last spanner.
+ EXPECT_EQ(outer->PhysicalFragmentCount(), 8u);
+
+ // #inner1 has 4 lines split into 2 columns.
+ EXPECT_EQ(inner1->PhysicalFragmentCount(), 2u);
+
+ // #inner2 has 5 lines split into 3 columns.
+ EXPECT_EQ(inner2->PhysicalFragmentCount(), 3u);
+
+ // #inner3 has 8 lines split into 3 columns.
+ EXPECT_EQ(inner3->PhysicalFragmentCount(), 3u);
+
+ EXPECT_EQ(spanner1->PhysicalFragmentCount(), 1u);
+ EXPECT_EQ(spanner2->PhysicalFragmentCount(), 1u);
+
+ EXPECT_EQ(multicol->GetPhysicalFragment(0)->Size(), PhysicalSize(620, 140));
+ EXPECT_EQ(outer->GetPhysicalFragment(0)->Size(), PhysicalSize(200, 40));
+ EXPECT_EQ(outer->GetPhysicalFragment(1)->Size(), PhysicalSize(200, 40));
+ EXPECT_EQ(outer->GetPhysicalFragment(2)->Size(), PhysicalSize(200, 40));
+ EXPECT_EQ(outer->GetPhysicalFragment(3)->Size(), PhysicalSize(200, 40));
+ EXPECT_EQ(outer->GetPhysicalFragment(4)->Size(), PhysicalSize(200, 20));
+ EXPECT_EQ(outer->GetPhysicalFragment(5)->Size(), PhysicalSize(200, 60));
+ EXPECT_EQ(outer->GetPhysicalFragment(6)->Size(), PhysicalSize(200, 60));
+ EXPECT_EQ(outer->GetPhysicalFragment(7)->Size(), PhysicalSize(200, 20));
+ EXPECT_EQ(inner1->GetPhysicalFragment(0)->Size(), PhysicalSize(200, 40));
+ EXPECT_EQ(inner1->GetPhysicalFragment(1)->Size(), PhysicalSize(200, 40));
+ EXPECT_EQ(inner2->GetPhysicalFragment(0)->Size(), PhysicalSize(200, 40));
+ EXPECT_EQ(inner2->GetPhysicalFragment(1)->Size(), PhysicalSize(200, 40));
+ EXPECT_EQ(inner2->GetPhysicalFragment(2)->Size(), PhysicalSize(200, 20));
+ EXPECT_EQ(inner3->GetPhysicalFragment(0)->Size(), PhysicalSize(200, 60));
+ EXPECT_EQ(inner3->GetPhysicalFragment(1)->Size(), PhysicalSize(200, 60));
+ EXPECT_EQ(inner3->GetPhysicalFragment(2)->Size(), PhysicalSize(200, 20));
+ EXPECT_EQ(spanner1->GetPhysicalFragment(0)->Size(), PhysicalSize(620, 0));
+ EXPECT_EQ(spanner2->GetPhysicalFragment(0)->Size(), PhysicalSize(620, 0));
+}
+
+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="child1" style="width:11px; height:350px;"></div>
+ <div id="child2" style="width:22px; height:350px;"></div>
+ </div>
+ </div>
+ </div>
+ )HTML");
+
+ RunBlockLayoutAlgorithm(GetElementById("container"));
+ const LayoutBox* outer_multicol =
+ ToLayoutBox(GetLayoutObjectByElementId("outer_multicol"));
+ const LayoutBox* inner_multicol =
+ ToLayoutBox(GetLayoutObjectByElementId("inner_multicol"));
+ const LayoutBox* child1 = ToLayoutBox(GetLayoutObjectByElementId("child1"));
+ const LayoutBox* child2 = ToLayoutBox(GetLayoutObjectByElementId("child2"));
+
+ EXPECT_EQ(outer_multicol->PhysicalFragmentCount(), 1u);
+
+ // The content is too tall (350px + 350px, column height 100px, 2*3 columns =
+ // 600px) and will use one more column than we have specified.
+ EXPECT_EQ(inner_multicol->PhysicalFragmentCount(), 4u);
+
+ // 350px tall content with a column height of 100px will require 4 fragments.
+ EXPECT_EQ(child1->PhysicalFragmentCount(), 4u);
+ EXPECT_EQ(child2->PhysicalFragmentCount(), 4u);
+
+ EXPECT_EQ(outer_multicol->GetPhysicalFragment(0)->Size(),
+ PhysicalSize(620, 100));
+
+ EXPECT_EQ(inner_multicol->GetPhysicalFragment(0)->Size(),
+ PhysicalSize(200, 100));
+ EXPECT_EQ(inner_multicol->GetPhysicalFragment(1)->Size(),
+ PhysicalSize(200, 100));
+ EXPECT_EQ(inner_multicol->GetPhysicalFragment(2)->Size(),
+ PhysicalSize(200, 100));
+ EXPECT_EQ(inner_multicol->GetPhysicalFragment(3)->Size(),
+ PhysicalSize(200, 100));
+
+ // #child1 starts at the beginning of a column, so the last fragment will be
+ // shorter than the rest.
+ EXPECT_EQ(child1->GetPhysicalFragment(0)->Size(), PhysicalSize(11, 100));
+ EXPECT_EQ(child1->GetPhysicalFragment(1)->Size(), PhysicalSize(11, 100));
+ EXPECT_EQ(child1->GetPhysicalFragment(2)->Size(), PhysicalSize(11, 100));
+ EXPECT_EQ(child1->GetPhysicalFragment(3)->Size(), PhysicalSize(11, 50));
+
+ // #child2 starts in the middle of a column, so the first fragment will be
+ // shorter than the rest.
+ EXPECT_EQ(child2->GetPhysicalFragment(0)->Size(), PhysicalSize(22, 50));
+ EXPECT_EQ(child2->GetPhysicalFragment(1)->Size(), PhysicalSize(22, 100));
+ EXPECT_EQ(child2->GetPhysicalFragment(2)->Size(), PhysicalSize(22, 100));
+ EXPECT_EQ(child2->GetPhysicalFragment(3)->Size(), PhysicalSize(22, 100));
+}
+
+} // 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 72a107d1f7b..327212ca3a8 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
@@ -164,11 +164,20 @@ NGBreakAppeal CalculateBreakAppealInside(const NGConstraintSpace& space,
}
void SetupFragmentation(const NGConstraintSpace& parent_space,
+ const NGLayoutInputNode& child,
LayoutUnit fragmentainer_offset_delta,
NGConstraintSpaceBuilder* builder,
bool is_new_fc) {
DCHECK(parent_space.HasBlockFragmentation());
+ // If the child is truly unbreakable, it won't participate in block
+ // fragmentation. If it's too tall to fit, it will either overflow the
+ // fragmentainer or get brutally sliced into pieces (without looking for
+ // allowed breakpoints, since there are none, by definition), depending on
+ // fragmentation type (multicol vs. printing).
+ if (child.IsMonolithic())
+ return;
+
builder->SetFragmentainerBlockSize(parent_space.FragmentainerBlockSize());
builder->SetFragmentainerOffsetAtBfc(parent_space.FragmentainerOffsetAtBfc() +
fragmentainer_offset_delta);
@@ -179,11 +188,20 @@ void SetupFragmentation(const NGConstraintSpace& parent_space,
}
void FinishFragmentation(const NGConstraintSpace& space,
+ const NGBlockBreakToken* previous_break_token,
LayoutUnit block_size,
LayoutUnit intrinsic_block_size,
- LayoutUnit previously_consumed_block_size,
LayoutUnit space_left,
NGBoxFragmentBuilder* builder) {
+ LayoutUnit previously_consumed_block_size;
+ unsigned sequence_number = 0;
+ if (previous_break_token && !previous_break_token->IsBreakBefore()) {
+ previously_consumed_block_size = previous_break_token->ConsumedBlockSize();
+ sequence_number = previous_break_token->SequenceNumber() + 1;
+ builder->SetIsFirstForNode(false);
+ }
+ builder->SetSequenceNumber(sequence_number);
+
if (builder->DidBreak()) {
// One of our children broke. Even if we fit within the remaining space, we
// need to prepare a break token.
@@ -271,11 +289,13 @@ void BreakBeforeChild(const NGConstraintSpace& space,
bool is_forced_break,
NGBoxFragmentBuilder* builder) {
#if DCHECK_IS_ON()
- // In order to successfully break before a node, this has to be its first
- // fragment.
- const auto& physical_fragment = layout_result.PhysicalFragment();
- DCHECK(!physical_fragment.IsBox() ||
- To<NGPhysicalBoxFragment>(physical_fragment).IsFirstForNode());
+ if (layout_result.Status() == NGLayoutResult::kSuccess) {
+ // In order to successfully break before a node, this has to be its first
+ // fragment.
+ const auto& physical_fragment = layout_result.PhysicalFragment();
+ DCHECK(!physical_fragment.IsBox() ||
+ To<NGPhysicalBoxFragment>(physical_fragment).IsFirstForNode());
+ }
#endif
// Report space shortage. Note that we're not doing this for line boxes here
@@ -310,7 +330,10 @@ void PropagateSpaceShortage(const NGConstraintSpace& space,
LayoutUnit space_shortage;
if (layout_result.MinimalSpaceShortage() == LayoutUnit::Max()) {
// Calculate space shortage: Figure out how much more space would have been
- // sufficient to make the child fit right here in the current fragment.
+ // sufficient to make the child fragment fit right here in the current
+ // fragmentainer. If layout aborted, though, we can't propagate anything.
+ if (layout_result.Status() != NGLayoutResult::kSuccess)
+ return;
NGFragment fragment(space.GetWritingMode(),
layout_result.PhysicalFragment());
space_shortage = fragmentainer_block_offset + fragment.BlockSize() -
@@ -335,6 +358,13 @@ bool MovePastBreakpoint(const NGConstraintSpace& space,
LayoutUnit fragmentainer_block_offset,
NGBreakAppeal appeal_before,
NGBoxFragmentBuilder* builder) {
+ if (layout_result.Status() != NGLayoutResult::kSuccess) {
+ // Layout aborted - no fragment was produced. There's nothing to move
+ // past. We need to break before.
+ DCHECK_EQ(layout_result.Status(), NGLayoutResult::kOutOfFragmentainerSpace);
+ return false;
+ }
+
const auto& physical_fragment = layout_result.PhysicalFragment();
NGFragment fragment(space.GetWritingMode(), physical_fragment);
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 3f0f844f3a1..48ca63e28a5 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
@@ -6,6 +6,8 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_FRAGMENTATION_UTILS_H_
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.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_item.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
#include "third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h"
@@ -45,6 +47,14 @@ inline bool IsResumingLayout(const NGBlockBreakToken* token) {
return token && !token->IsBreakBefore();
}
+// Return true if the fragment to be generated for the specified item is going
+// to be the first fragment for the node.
+inline bool IsFirstForNode(const NGInlineItem& item,
+ const NGInlineBreakToken* token) {
+ return item.IsFirstForNode() &&
+ (!token || item.StartOffset() >= token->TextOffset());
+}
+
// Calculate the final "break-between" value at a class A or C breakpoint. This
// is the combination of all break-before and break-after values that met at the
// breakpoint.
@@ -93,15 +103,16 @@ inline void AdjustForFragmentation(const NGBlockBreakToken* break_token,
// formatting context starts in a previous fragmentainer; the offset from the
// current fragmentainer block-start.
void SetupFragmentation(const NGConstraintSpace& parent_space,
+ const NGLayoutInputNode& child,
LayoutUnit fragmentainer_offset_delta,
NGConstraintSpaceBuilder*,
bool is_new_fc);
// Write fragmentation information to the fragment builder after layout.
void FinishFragmentation(const NGConstraintSpace&,
+ const NGBlockBreakToken* previous_break_token,
LayoutUnit block_size,
LayoutUnit intrinsic_block_size,
- LayoutUnit previously_consumed_block_size,
LayoutUnit space_left,
NGBoxFragmentBuilder*);
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 2ef8605d97e..b04949398e8 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
@@ -7,7 +7,7 @@
#include "base/optional.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/layout/min_max_size.h"
+#include "third_party/blink/renderer/core/layout/min_max_sizes.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -17,7 +17,7 @@ namespace blink {
class ComputedStyle;
class NGEarlyBreak;
class NGLayoutResult;
-struct MinMaxSizeInput;
+struct MinMaxSizesInput;
// Operations provided by a layout algorithm.
class NGLayoutAlgorithmOperations {
@@ -33,8 +33,8 @@ class NGLayoutAlgorithmOperations {
// account. If the return value is empty, the caller is expected to synthesize
// this value from the overflow rect returned from Layout called with an
// available width of 0 and LayoutUnit::max(), respectively.
- virtual base::Optional<MinMaxSize> ComputeMinMaxSize(
- const MinMaxSizeInput&) const {
+ virtual base::Optional<MinMaxSizes> ComputeMinMaxSizes(
+ const MinMaxSizesInput&) const {
return base::nullopt;
}
};
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 f46d17d48d1..28d5bcce744 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
@@ -8,9 +8,8 @@
#include "third_party/blink/renderer/core/layout/intrinsic_sizing_info.h"
#include "third_party/blink/renderer/core/layout/layout_replaced.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
-#include "third_party/blink/renderer/core/layout/min_max_size.h"
+#include "third_party/blink/renderer/core/layout/min_max_sizes.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_marker.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
@@ -61,39 +60,23 @@ void AppendNodeToString(NGLayoutInputNode node,
} // namespace
-MinMaxSize NGLayoutInputNode::ComputeMinMaxSize(
+MinMaxSizes NGLayoutInputNode::ComputeMinMaxSizes(
WritingMode writing_mode,
- const MinMaxSizeInput& input,
+ const MinMaxSizesInput& input,
const NGConstraintSpace* space) {
if (auto* inline_node = DynamicTo<NGInlineNode>(this))
- return inline_node->ComputeMinMaxSize(writing_mode, input, space);
- return To<NGBlockNode>(*this).ComputeMinMaxSize(writing_mode, input, space);
+ return inline_node->ComputeMinMaxSizes(writing_mode, input, space);
+ return To<NGBlockNode>(*this).ComputeMinMaxSizes(writing_mode, input, space);
}
void NGLayoutInputNode::IntrinsicSize(
base::Optional<LayoutUnit>* computed_inline_size,
- base::Optional<LayoutUnit>* computed_block_size,
- LogicalSize* aspect_ratio) const {
+ base::Optional<LayoutUnit>* computed_block_size) const {
DCHECK(IsReplaced());
- LayoutUnit override_inline_size = OverrideIntrinsicContentInlineSize();
- if (override_inline_size != kIndefiniteSize)
- *computed_inline_size = override_inline_size;
-
- LayoutUnit override_block_size = OverrideIntrinsicContentBlockSize();
- if (override_block_size != kIndefiniteSize)
- *computed_block_size = override_block_size;
-
- if (ShouldApplySizeContainment()) {
- if (!*computed_inline_size)
- *computed_inline_size = LayoutUnit();
- if (!*computed_block_size)
- *computed_block_size = LayoutUnit();
- }
- if (*computed_inline_size && *computed_block_size) {
- *aspect_ratio = LogicalSize(**computed_inline_size, **computed_block_size);
+ GetOverrideIntrinsicSize(computed_inline_size, computed_block_size);
+ if (*computed_inline_size && *computed_block_size)
return;
- }
IntrinsicSizingInfo legacy_sizing_info;
@@ -102,9 +85,6 @@ void NGLayoutInputNode::IntrinsicSize(
*computed_inline_size = LayoutUnit(legacy_sizing_info.size.Width());
if (!*computed_block_size && legacy_sizing_info.has_height)
*computed_block_size = LayoutUnit(legacy_sizing_info.size.Height());
- *aspect_ratio =
- LogicalSize(LayoutUnit(legacy_sizing_info.aspect_ratio.Width()),
- LayoutUnit(legacy_sizing_info.aspect_ratio.Height()));
}
NGLayoutInputNode NGLayoutInputNode::NextSibling() {
@@ -134,8 +114,39 @@ void NGLayoutInputNode::ShowNodeTree() const {
StringBuilder string_builder;
string_builder.Append(".:: LayoutNG Node Tree ::.\n");
AppendNodeToString(*this, &string_builder);
- fprintf(stderr, "%s\n", string_builder.ToString().Utf8().c_str());
+ DLOG(INFO) << "\n" << string_builder.ToString().Utf8();
}
#endif
+void NGLayoutInputNode::GetOverrideIntrinsicSize(
+ base::Optional<LayoutUnit>* computed_inline_size,
+ base::Optional<LayoutUnit>* computed_block_size) const {
+ DCHECK(IsReplaced());
+
+ LayoutUnit override_inline_size = OverrideIntrinsicContentInlineSize();
+ if (override_inline_size != kIndefiniteSize) {
+ *computed_inline_size = override_inline_size;
+ } else {
+ LayoutUnit default_inline_size = DefaultIntrinsicContentInlineSize();
+ if (default_inline_size != kIndefiniteSize)
+ *computed_inline_size = default_inline_size;
+ }
+
+ LayoutUnit override_block_size = OverrideIntrinsicContentBlockSize();
+ if (override_block_size != kIndefiniteSize) {
+ *computed_block_size = override_block_size;
+ } else {
+ LayoutUnit default_block_size = DefaultIntrinsicContentBlockSize();
+ if (default_block_size != kIndefiniteSize)
+ *computed_block_size = default_block_size;
+ }
+
+ if (ShouldApplySizeContainment()) {
+ if (!*computed_inline_size)
+ *computed_inline_size = LayoutUnit();
+ if (!*computed_block_size)
+ *computed_block_size = LayoutUnit();
+ }
+}
+
} // namespace blink
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 c77e16c4310..45acfcb0f7c 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
@@ -11,7 +11,7 @@
#include "third_party/blink/renderer/core/layout/geometry/logical_size.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/ng/layout_box_utils.h"
-#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker.h"
+#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_outside_list_marker.h"
#include "third_party/blink/renderer/platform/geometry/layout_unit.h"
#include "third_party/blink/renderer/platform/text/writing_mode.h"
@@ -24,16 +24,13 @@ class LayoutObject;
class LayoutBox;
class NGConstraintSpace;
class NGPaintFragment;
-struct MinMaxSize;
-struct LogicalSize;
+struct MinMaxSizes;
struct PhysicalSize;
-enum class NGMinMaxSizeType { kContentBoxSize, kBorderBoxSize };
-
// 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.
-struct MinMaxSizeInput {
+struct MinMaxSizesInput {
// The min-max size calculation (un-intuitively) requires a percentage
// resolution size!
// This occurs when a replaced element has an intrinsic size. E.g.
@@ -44,14 +41,11 @@ struct MinMaxSizeInput {
//
// 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 MinMaxSizeInput(LayoutUnit percentage_resolution_block_size)
+ explicit MinMaxSizesInput(LayoutUnit percentage_resolution_block_size)
: percentage_resolution_block_size(percentage_resolution_block_size) {}
LayoutUnit float_left_inline_size;
LayoutUnit float_right_inline_size;
LayoutUnit percentage_resolution_block_size;
-
- // Whether to return the size as a content-box size or border-box size.
- NGMinMaxSizeType size_type = NGMinMaxSizeType::kBorderBoxSize;
};
// Represents the input to a layout algorithm for a given node. The layout
@@ -108,11 +102,11 @@ class CORE_EXPORT NGLayoutInputNode {
}
bool IsListItem() const { return IsBlock() && box_->IsLayoutNGListItem(); }
bool IsListMarker() const {
- return IsBlock() && box_->IsLayoutNGListMarker();
+ return IsBlock() && box_->IsLayoutNGOutsideListMarker();
}
bool ListMarkerOccupiesWholeLine() const {
DCHECK(IsListMarker());
- return ToLayoutNGListMarker(box_)->NeedsOccupyWholeLine();
+ return ToLayoutNGOutsideListMarker(box_)->NeedsOccupyWholeLine();
}
bool IsFieldsetContainer() const {
return IsBlock() && box_->IsLayoutNGFieldset();
@@ -123,6 +117,9 @@ class CORE_EXPORT NGLayoutInputNode {
bool IsRenderedLegend() const {
return IsBlock() && box_->IsRenderedLegend();
}
+ bool IsTable() const { return IsBlock() && box_->IsTable(); }
+
+ bool IsMathRoot() const { return box_->IsMathMLRoot(); }
bool IsAnonymousBlock() const { return box_->IsAnonymousBlock(); }
@@ -159,16 +156,16 @@ class CORE_EXPORT NGLayoutInputNode {
}
// Returns border box.
- MinMaxSize ComputeMinMaxSize(WritingMode,
- const MinMaxSizeInput&,
- const NGConstraintSpace* = nullptr);
+ MinMaxSizes ComputeMinMaxSizes(WritingMode,
+ const MinMaxSizesInput&,
+ const NGConstraintSpace* = nullptr);
// Returns intrinsic sizing information for replaced elements.
// ComputeReplacedSize can use it to compute actual replaced size.
// Corresponds to Legacy's LayoutReplaced::IntrinsicSizingInfo.
+ // Use NGBlockNode::GetAspectRatio to get the aspect ratio.
void IntrinsicSize(base::Optional<LayoutUnit>* computed_inline_size,
- base::Optional<LayoutUnit>* computed_block_size,
- LogicalSize* aspect_ratio) const;
+ base::Optional<LayoutUnit>* computed_block_size) const;
// Returns the next sibling.
NGLayoutInputNode NextSibling();
@@ -201,6 +198,13 @@ class CORE_EXPORT NGLayoutInputNode {
return kIndefiniteSize;
}
+ LayoutUnit DefaultIntrinsicContentInlineSize() const {
+ return box_->DefaultIntrinsicContentInlineSize();
+ }
+ LayoutUnit DefaultIntrinsicContentBlockSize() const {
+ return box_->DefaultIntrinsicContentBlockSize();
+ }
+
// Display locking functionality.
const DisplayLockContext& GetDisplayLockContext() const {
DCHECK(box_->GetDisplayLockContext());
@@ -240,6 +244,10 @@ class CORE_EXPORT NGLayoutInputNode {
NGLayoutInputNode(LayoutBox* box, NGLayoutInputNodeType type)
: box_(box), type_(type) {}
+ void GetOverrideIntrinsicSize(
+ base::Optional<LayoutUnit>* computed_inline_size,
+ base::Optional<LayoutUnit>* computed_block_size) const;
+
LayoutBox* box_;
unsigned type_ : 1; // NGLayoutInputNodeType
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 fac77834d22..6dc8f994eee 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
@@ -39,6 +39,7 @@ static_assert(sizeof(NGLayoutResult) == sizeof(SameSizeAsNGLayoutResult),
} // namespace
NGLayoutResult::NGLayoutResult(
+ NGBoxFragmentBuilderPassKey passkey,
scoped_refptr<const NGPhysicalContainerFragment> physical_fragment,
NGBoxFragmentBuilder* builder)
: NGLayoutResult(std::move(physical_fragment),
@@ -48,6 +49,10 @@ 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);
@@ -62,10 +67,9 @@ NGLayoutResult::NGLayoutResult(
rare_data->has_tallest_unbreakable_block_size = true;
#endif
}
- if (builder->unconstrained_intrinsic_block_size_ != kIndefiniteSize &&
- builder->unconstrained_intrinsic_block_size_ != intrinsic_block_size_) {
- EnsureRareData()->unconstrained_intrinsic_block_size_ =
- builder->unconstrained_intrinsic_block_size_;
+ if (builder->overflow_block_size_ != kIndefiniteSize &&
+ builder->overflow_block_size_ != intrinsic_block_size_) {
+ EnsureRareData()->overflow_block_size_ = builder->overflow_block_size_;
}
if (builder->custom_layout_data_) {
EnsureRareData()->custom_layout_data =
@@ -73,6 +77,8 @@ NGLayoutResult::NGLayoutResult(
}
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 =
@@ -81,15 +87,20 @@ NGLayoutResult::NGLayoutResult(
}
NGLayoutResult::NGLayoutResult(
+ NGLineBoxFragmentBuilderPassKey passkey,
scoped_refptr<const NGPhysicalContainerFragment> physical_fragment,
NGLineBoxFragmentBuilder* builder)
: NGLayoutResult(std::move(physical_fragment),
static_cast<NGContainerFragmentBuilder*>(builder)) {}
-NGLayoutResult::NGLayoutResult(EStatus status, NGBoxFragmentBuilder* builder)
+NGLayoutResult::NGLayoutResult(NGBoxFragmentBuilderPassKey key,
+ EStatus status,
+ NGBoxFragmentBuilder* builder)
: NGLayoutResult(/* physical_fragment */ nullptr,
static_cast<NGContainerFragmentBuilder*>(builder)) {
bitfields_.status = status;
+ if (builder->lines_until_clamp_)
+ EnsureRareData()->lines_until_clamp = *builder->lines_until_clamp_;
DCHECK_NE(status, kSuccess)
<< "Use the other constructor for successful layout";
}
@@ -152,7 +163,7 @@ NGLayoutResult::NGLayoutResult(
#if DCHECK_IS_ON()
if (bitfields_.is_self_collapsing && physical_fragment_) {
// A new formatting-context shouldn't be self-collapsing.
- DCHECK(!physical_fragment_->IsBlockFormattingContextRoot());
+ DCHECK(!physical_fragment_->IsFormattingContextRoot());
// Self-collapsing children must have a block-size of zero.
NGFragment fragment(physical_fragment_->Style().GetWritingMode(),
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 77ff5c5b9b9..3faf3aa43aa 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
@@ -41,6 +41,8 @@ class CORE_EXPORT NGLayoutResult : public RefCounted<NGLayoutResult> {
kSuccess = 0,
kBfcBlockOffsetResolved = 1,
kNeedsEarlierBreak = 2,
+ kOutOfFragmentainerSpace = 3,
+ kNeedsRelayoutWithNoForcedTruncateAtLineClamp = 4,
// When adding new values, make sure the bit size of |Bitfields::status| is
// large enough to store.
};
@@ -62,6 +64,10 @@ class CORE_EXPORT NGLayoutResult : public RefCounted<NGLayoutResult> {
return *physical_fragment_;
}
+ int LinesUntilClamp() const {
+ return HasRareData() ? rare_data_->lines_until_clamp : 0;
+ }
+
LogicalOffset OutOfFlowPositionedOffset() const {
DCHECK(bitfields_.has_oof_positioned_offset);
return HasRareData() ? rare_data_->oof_positioned_offset
@@ -140,16 +146,13 @@ class CORE_EXPORT NGLayoutResult : public RefCounted<NGLayoutResult> {
}
const LayoutUnit IntrinsicBlockSize() const {
- DCHECK(physical_fragment_->Type() == NGPhysicalFragment::kFragmentBox ||
- physical_fragment_->Type() ==
- NGPhysicalFragment::kFragmentRenderedLegend);
+ DCHECK(physical_fragment_->IsBox());
return intrinsic_block_size_;
}
- LayoutUnit UnconstrainedIntrinsicBlockSize() const {
- return HasRareData() && rare_data_->unconstrained_intrinsic_block_size_ !=
- kIndefiniteSize
- ? rare_data_->unconstrained_intrinsic_block_size_
+ LayoutUnit OverflowBlockSize() const {
+ return HasRareData() && rare_data_->overflow_block_size_ != kIndefiniteSize
+ ? rare_data_->overflow_block_size_
: intrinsic_block_size_;
}
@@ -173,6 +176,14 @@ class CORE_EXPORT NGLayoutResult : public RefCounted<NGLayoutResult> {
return rare_data_->tallest_unbreakable_block_size;
}
+ // Return whether this result is single-use only (true), or if it is allowed
+ // to be involved in cache hits in future layout passes (false).
+ // For example, this happens when a block is fragmented, since we don't yet
+ // support caching of block-fragmented results.
+ bool IsSingleUse() const {
+ return HasRareData() && rare_data_->is_single_use;
+ }
+
SerializedScriptValue* CustomLayoutData() const {
return HasRareData() ? rare_data_->custom_layout_data.get() : nullptr;
}
@@ -285,21 +296,24 @@ class CORE_EXPORT NGLayoutResult : public RefCounted<NGLayoutResult> {
bool check_same_block_size = true) const;
#endif
- private:
- friend class NGBoxFragmentBuilder;
- friend class NGLineBoxFragmentBuilder;
- friend class MutableForOutOfFlow;
-
+ using NGBoxFragmentBuilderPassKey = util::PassKey<NGBoxFragmentBuilder>;
+ // This constructor is for a non-success status.
+ NGLayoutResult(NGBoxFragmentBuilderPassKey, EStatus, NGBoxFragmentBuilder*);
// This constructor requires a non-null fragment and sets a success status.
NGLayoutResult(
+ NGBoxFragmentBuilderPassKey,
scoped_refptr<const NGPhysicalContainerFragment> physical_fragment,
NGBoxFragmentBuilder*);
+ using NGLineBoxFragmentBuilderPassKey =
+ util::PassKey<NGLineBoxFragmentBuilder>;
// This constructor requires a non-null fragment and sets a success status.
NGLayoutResult(
+ NGLineBoxFragmentBuilderPassKey,
scoped_refptr<const NGPhysicalContainerFragment> physical_fragment,
NGLineBoxFragmentBuilder*);
- // This constructor is for a non-success status.
- NGLayoutResult(EStatus, NGBoxFragmentBuilder*);
+
+ private:
+ friend class MutableForOutOfFlow;
// We don't need the copy constructor, move constructor, copy
// assigmnment-operator, or move assignment-operator today.
@@ -358,10 +372,12 @@ class CORE_EXPORT NGLayoutResult : public RefCounted<NGLayoutResult> {
};
NGExclusionSpace exclusion_space;
scoped_refptr<SerializedScriptValue> custom_layout_data;
- LayoutUnit unconstrained_intrinsic_block_size_ = kIndefiniteSize;
+ LayoutUnit overflow_block_size_ = kIndefiniteSize;
#if DCHECK_IS_ON()
bool has_tallest_unbreakable_block_size = false;
#endif
+ bool is_single_use = false;
+ int lines_until_clamp = 0;
};
bool HasRareData() const { return bitfields_.has_rare_data; }
@@ -421,7 +437,7 @@ class CORE_EXPORT NGLayoutResult : public RefCounted<NGLayoutResult> {
unsigned initial_break_before : 4; // EBreakBetween
unsigned final_break_after : 4; // EBreakBetween
- unsigned status : 2; // EStatus
+ unsigned status : 3; // EStatus
};
// The constraint space which generated this layout result, may not be valid
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_result_caching_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_result_caching_test.cc
index 107e1cc3dc8..24df10ed942 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_result_caching_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_layout_result_caching_test.cc
@@ -19,8 +19,6 @@ namespace {
class NGLayoutResultCachingTest : public NGLayoutTest {};
TEST_F(NGLayoutResultCachingTest, HitDifferentExclusionSpace) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
// Same BFC offset, different exclusion space.
SetBodyInnerHTML(R"HTML(
<style>
@@ -58,8 +56,6 @@ TEST_F(NGLayoutResultCachingTest, HitDifferentExclusionSpace) {
}
TEST_F(NGLayoutResultCachingTest, HitDifferentBFCOffset) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
// Different BFC offset, same exclusion space.
SetBodyInnerHTML(R"HTML(
<style>
@@ -123,8 +119,6 @@ TEST_F(NGLayoutResultCachingTest, HitDifferentBFCOffset) {
}
TEST_F(NGLayoutResultCachingTest, HitDifferentBFCOffsetSameMarginStrut) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
// Different BFC offset, same margin-strut.
SetBodyInnerHTML(R"HTML(
<style>
@@ -155,8 +149,6 @@ TEST_F(NGLayoutResultCachingTest, HitDifferentBFCOffsetSameMarginStrut) {
}
TEST_F(NGLayoutResultCachingTest, MissDescendantAboveBlockStart1) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
// Same BFC offset, different exclusion space, descendant above
// block start.
SetBodyInnerHTML(R"HTML(
@@ -195,8 +187,6 @@ TEST_F(NGLayoutResultCachingTest, MissDescendantAboveBlockStart1) {
}
TEST_F(NGLayoutResultCachingTest, MissDescendantAboveBlockStart2) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
// Different BFC offset, same exclusion space, descendant above
// block start.
SetBodyInnerHTML(R"HTML(
@@ -235,8 +225,6 @@ TEST_F(NGLayoutResultCachingTest, MissDescendantAboveBlockStart2) {
}
TEST_F(NGLayoutResultCachingTest, HitOOFDescendantAboveBlockStart) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
// Different BFC offset, same exclusion space, OOF-descendant above
// block start.
SetBodyInnerHTML(R"HTML(
@@ -275,8 +263,6 @@ TEST_F(NGLayoutResultCachingTest, HitOOFDescendantAboveBlockStart) {
}
TEST_F(NGLayoutResultCachingTest, HitLineBoxDescendantAboveBlockStart) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
// Different BFC offset, same exclusion space, line-box descendant above
// block start.
SetBodyInnerHTML(R"HTML(
@@ -320,8 +306,6 @@ TEST_F(NGLayoutResultCachingTest, HitLineBoxDescendantAboveBlockStart) {
}
TEST_F(NGLayoutResultCachingTest, MissFloatInitiallyIntruding1) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
// Same BFC offset, different exclusion space, float initially
// intruding.
SetBodyInnerHTML(R"HTML(
@@ -358,8 +342,6 @@ TEST_F(NGLayoutResultCachingTest, MissFloatInitiallyIntruding1) {
}
TEST_F(NGLayoutResultCachingTest, MissFloatInitiallyIntruding2) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
// Different BFC offset, same exclusion space, float initially
// intruding.
SetBodyInnerHTML(R"HTML(
@@ -396,8 +378,6 @@ TEST_F(NGLayoutResultCachingTest, MissFloatInitiallyIntruding2) {
}
TEST_F(NGLayoutResultCachingTest, MissFloatWillIntrude1) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
// Same BFC offset, different exclusion space, float will intrude.
SetBodyInnerHTML(R"HTML(
<style>
@@ -433,8 +413,6 @@ TEST_F(NGLayoutResultCachingTest, MissFloatWillIntrude1) {
}
TEST_F(NGLayoutResultCachingTest, MissFloatWillIntrude2) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
// Different BFC offset, same exclusion space, float will intrude.
SetBodyInnerHTML(R"HTML(
<style>
@@ -470,8 +448,6 @@ TEST_F(NGLayoutResultCachingTest, MissFloatWillIntrude2) {
}
TEST_F(NGLayoutResultCachingTest, HitPushedByFloats1) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
// Same BFC offset, different exclusion space, pushed by floats.
SetBodyInnerHTML(R"HTML(
<style>
@@ -507,8 +483,6 @@ TEST_F(NGLayoutResultCachingTest, HitPushedByFloats1) {
}
TEST_F(NGLayoutResultCachingTest, HitPushedByFloats2) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
// Different BFC offset, same exclusion space, pushed by floats.
SetBodyInnerHTML(R"HTML(
<style>
@@ -544,8 +518,6 @@ TEST_F(NGLayoutResultCachingTest, HitPushedByFloats2) {
}
TEST_F(NGLayoutResultCachingTest, MissPushedByFloats1) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
// Same BFC offset, different exclusion space, pushed by floats.
// Miss due to shrinking offset.
SetBodyInnerHTML(R"HTML(
@@ -582,8 +554,6 @@ TEST_F(NGLayoutResultCachingTest, MissPushedByFloats1) {
}
TEST_F(NGLayoutResultCachingTest, MissPushedByFloats2) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
// Different BFC offset, same exclusion space, pushed by floats.
// Miss due to shrinking offset.
SetBodyInnerHTML(R"HTML(
@@ -620,8 +590,6 @@ TEST_F(NGLayoutResultCachingTest, MissPushedByFloats2) {
}
TEST_F(NGLayoutResultCachingTest, HitDifferentRareData) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
// Same absolute fixed constraints.
SetBodyInnerHTML(R"HTML(
<style>
@@ -651,8 +619,6 @@ TEST_F(NGLayoutResultCachingTest, HitDifferentRareData) {
}
TEST_F(NGLayoutResultCachingTest, HitPercentageMinWidth) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
// min-width calculates to different values, but doesn't change size.
SetBodyInnerHTML(R"HTML(
<style>
@@ -682,8 +648,6 @@ TEST_F(NGLayoutResultCachingTest, HitPercentageMinWidth) {
}
TEST_F(NGLayoutResultCachingTest, HitFixedMinWidth) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
// min-width is always larger than the available size.
SetBodyInnerHTML(R"HTML(
<style>
@@ -712,9 +676,151 @@ TEST_F(NGLayoutResultCachingTest, HitFixedMinWidth) {
EXPECT_NE(result.get(), nullptr);
}
-TEST_F(NGLayoutResultCachingTest, HitShrinkToFitSameIntrinsicSizes) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
+TEST_F(NGLayoutResultCachingTest, HitShrinkToFit) {
+ SetBodyInnerHTML(R"HTML(
+ <div style="display: flow-root; width: 300px; height: 100px;">
+ <div id="test1" style="float: left;">
+ <div style="display: inline-block; width: 150px;"></div>
+ <div style="display: inline-block; width: 50px;"></div>
+ </div>
+ <div id="test2" style="float: left;">
+ <div style="display: inline-block; width: 350px;"></div>
+ <div style="display: inline-block; width: 250px;"></div>
+ </div>
+ </div>
+ <div style="display: flow-root; width: 400px; height: 100px;">
+ <div id="src1" style="float: left;">
+ <div style="display: inline-block; width: 150px;"></div>
+ <div style="display: inline-block; width: 50px;"></div>
+ </div>
+ </div>
+ <div style="display: flow-root; width: 200px; height: 100px;">
+ <div id="src2" style="float: left;">
+ <div style="display: inline-block; width: 350px;"></div>
+ <div style="display: inline-block; width: 250px;"></div>
+ </div>
+ </div>
+ )HTML");
+
+ auto* test1 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("test1"));
+ auto* test2 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("test2"));
+ auto* src1 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("src1"));
+ auto* src2 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("src2"));
+
+ NGLayoutCacheStatus cache_status;
+ base::Optional<NGFragmentGeometry> fragment_geometry;
+ NGConstraintSpace space =
+ src1->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
+ scoped_refptr<const NGLayoutResult> result = test1->CachedLayoutResult(
+ space, nullptr, nullptr, &fragment_geometry, &cache_status);
+ // test1 was sized to its max-content size, passing an available size larger
+ // than the fragment should hit the cache.
+ EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
+ EXPECT_NE(result.get(), nullptr);
+
+ fragment_geometry.reset();
+ space = src2->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
+ result = test2->CachedLayoutResult(space, nullptr, nullptr,
+ &fragment_geometry, &cache_status);
+ // test2 was sized to its min-content size in, passing an available size
+ // smaller than the fragment should hit the cache.
+ EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
+ EXPECT_NE(result.get(), nullptr);
+}
+
+TEST_F(NGLayoutResultCachingTest, MissShrinkToFit) {
+ SetBodyInnerHTML(R"HTML(
+ <div style="display: flow-root; width: 300px; height: 100px;">
+ <div id="test1" style="float: left;">
+ <div style="display: inline-block; width: 150px;"></div>
+ <div style="display: inline-block; width: 50px;"></div>
+ </div>
+ <div id="test2" style="float: left;">
+ <div style="display: inline-block; width: 350px;"></div>
+ <div style="display: inline-block; width: 250px;"></div>
+ </div>
+ <div id="test3" style="float: left; min-width: 80%;">
+ <div style="display: inline-block; width: 150px;"></div>
+ <div style="display: inline-block; width: 250px;"></div>
+ </div>
+ <div id="test4" style="float: left; margin-left: 75px;">
+ <div style="display: inline-block; width: 150px;"></div>
+ <div style="display: inline-block; width: 50px;"></div>
+ </div>
+ </div>
+ <div style="display: flow-root; width: 100px; height: 100px;">
+ <div id="src1" style="float: left;">
+ <div style="display: inline-block; width: 150px;"></div>
+ <div style="display: inline-block; width: 50px;"></div>
+ </div>
+ </div>
+ <div style="display: flow-root; width: 400px; height: 100px;">
+ <div id="src2" style="float: left;">
+ <div style="display: inline-block; width: 350px;"></div>
+ <div style="display: inline-block; width: 250px;"></div>
+ </div>
+ <div id="src3" style="float: left; min-width: 80%;">
+ <div style="display: inline-block; width: 150px;"></div>
+ <div style="display: inline-block; width: 250px;"></div>
+ </div>
+ </div>
+ <div style="display: flow-root; width: 250px; height: 100px;">
+ <div id="src4" style="float: left; margin-left: 75px;">
+ <div style="display: inline-block; width: 150px;"></div>
+ <div style="display: inline-block; width: 50px;"></div>
+ </div>
+ </div>
+ )HTML");
+
+ auto* test1 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("test1"));
+ auto* test2 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("test2"));
+ auto* test3 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("test3"));
+ auto* test4 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("test4"));
+ auto* src1 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("src1"));
+ auto* src2 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("src2"));
+ auto* src3 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("src3"));
+ auto* src4 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("src4"));
+
+ NGLayoutCacheStatus cache_status;
+ base::Optional<NGFragmentGeometry> fragment_geometry;
+ NGConstraintSpace space =
+ src1->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
+ scoped_refptr<const NGLayoutResult> result = test1->CachedLayoutResult(
+ space, nullptr, nullptr, &fragment_geometry, &cache_status);
+ // test1 was sized to its max-content size, passing an available size smaller
+ // than the fragment should miss the cache.
+ EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
+ EXPECT_EQ(result.get(), nullptr);
+
+ fragment_geometry.reset();
+ space = src2->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
+ result = test2->CachedLayoutResult(space, nullptr, nullptr,
+ &fragment_geometry, &cache_status);
+ // test2 was sized to its min-content size, passing an available size
+ // larger than the fragment should miss the cache.
+ EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
+ EXPECT_EQ(result.get(), nullptr);
+
+ fragment_geometry.reset();
+ space = src3->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
+ result = test3->CachedLayoutResult(space, nullptr, nullptr,
+ &fragment_geometry, &cache_status);
+ // test3 was sized to its min-content size, however it should miss the cache
+ // as it has a %-min-size.
+ EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
+ EXPECT_EQ(result.get(), nullptr);
+
+ fragment_geometry.reset();
+ space = src4->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
+ result = test4->CachedLayoutResult(space, nullptr, nullptr,
+ &fragment_geometry, &cache_status);
+ // test4 was sized to its max-content size, however it should miss the cache
+ // due to its margin.
+ EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
+ EXPECT_EQ(result.get(), nullptr);
+}
+TEST_F(NGLayoutResultCachingTest, HitShrinkToFitSameIntrinsicSizes) {
// We have a shrink-to-fit node, with the min, and max intrinsic sizes being
// equal (the available size doesn't affect the final size).
SetBodyInnerHTML(R"HTML(
@@ -750,8 +856,6 @@ TEST_F(NGLayoutResultCachingTest, HitShrinkToFitSameIntrinsicSizes) {
}
TEST_F(NGLayoutResultCachingTest, HitShrinkToFitDifferentParent) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
// The parent "bfc" node changes from shrink-to-fit, to a fixed width. But
// these calculate as the same available space to the "test" element.
SetBodyInnerHTML(R"HTML(
@@ -786,8 +890,6 @@ TEST_F(NGLayoutResultCachingTest, HitShrinkToFitDifferentParent) {
}
TEST_F(NGLayoutResultCachingTest, MissQuirksModePercentageBasedChild) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
// Quirks-mode %-block-size child.
GetDocument().SetCompatibilityMode(Document::kQuirksMode);
SetBodyInnerHTML(R"HTML(
@@ -822,8 +924,6 @@ TEST_F(NGLayoutResultCachingTest, MissQuirksModePercentageBasedChild) {
}
TEST_F(NGLayoutResultCachingTest, HitQuirksModePercentageBasedParentAndChild) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
// Quirks-mode %-block-size parent *and* child. Here we mark the parent as
// depending on %-block-size changes, however itself doesn't change in
// height.
@@ -863,8 +963,6 @@ TEST_F(NGLayoutResultCachingTest, HitQuirksModePercentageBasedParentAndChild) {
}
TEST_F(NGLayoutResultCachingTest, HitStandardsModePercentageBasedChild) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
// Standards-mode %-block-size child.
SetBodyInnerHTML(R"HTML(
<style>
@@ -898,8 +996,6 @@ TEST_F(NGLayoutResultCachingTest, HitStandardsModePercentageBasedChild) {
}
TEST_F(NGLayoutResultCachingTest, ChangeTableCellBlockSizeConstrainedness) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
SetBodyInnerHTML(R"HTML(
<style>
.table { display: table; width: 300px; }
@@ -964,12 +1060,9 @@ TEST_F(NGLayoutResultCachingTest, ChangeTableCellBlockSizeConstrainedness) {
// height or not. We're only going to need simplified layout, though, since no
// children will be affected by its height change.
EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsSimplifiedLayout);
- EXPECT_EQ(result.get(), nullptr);
}
TEST_F(NGLayoutResultCachingTest, OptimisticFloatPlacementNoRelayout) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
SetBodyInnerHTML(R"HTML(
<style>
.root { display: flow-root; width: 300px; }
@@ -994,8 +1087,6 @@ TEST_F(NGLayoutResultCachingTest, OptimisticFloatPlacementNoRelayout) {
}
TEST_F(NGLayoutResultCachingTest, SelfCollapsingShifting) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
SetBodyInnerHTML(R"HTML(
<style>
.bfc { display: flow-root; width: 300px; height: 300px; }
@@ -1080,8 +1171,6 @@ TEST_F(NGLayoutResultCachingTest, SelfCollapsingShifting) {
}
TEST_F(NGLayoutResultCachingTest, ClearancePastAdjoiningFloatsMovement) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
SetBodyInnerHTML(R"HTML(
<style>
.bfc { display: flow-root; width: 300px; height: 300px; }
@@ -1146,8 +1235,6 @@ TEST_F(NGLayoutResultCachingTest, ClearancePastAdjoiningFloatsMovement) {
}
TEST_F(NGLayoutResultCachingTest, MarginStrutMovementSelfCollapsing) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
SetBodyInnerHTML(R"HTML(
<style>
.bfc { display: flow-root; width: 300px; height: 300px; }
@@ -1217,8 +1304,6 @@ TEST_F(NGLayoutResultCachingTest, MarginStrutMovementSelfCollapsing) {
}
TEST_F(NGLayoutResultCachingTest, MarginStrutMovementInFlow) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
SetBodyInnerHTML(R"HTML(
<style>
.bfc { display: flow-root; width: 300px; height: 300px; }
@@ -1315,8 +1400,6 @@ TEST_F(NGLayoutResultCachingTest, MarginStrutMovementInFlow) {
}
TEST_F(NGLayoutResultCachingTest, MarginStrutMovementPercentage) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
SetBodyInnerHTML(R"HTML(
<style>
.bfc { display: flow-root; width: 300px; height: 300px; }
@@ -1354,53 +1437,55 @@ TEST_F(NGLayoutResultCachingTest, MarginStrutMovementPercentage) {
EXPECT_EQ(result.get(), nullptr);
}
-TEST_F(NGLayoutResultCachingTest, MarginStrutMovementDiscard) {
- ScopedLayoutNGFragmentCachingForTest layout_ng_fragment_caching(true);
-
+TEST_F(NGLayoutResultCachingTest, HitIsFixedBlockSizeIndefinite) {
SetBodyInnerHTML(R"HTML(
- <style>
- .bfc { display: flow-root; width: 300px; height: 300px; }
- </style>
- <div class="bfc">
- <div style="margin-top: 10px;">
- <div id="test1">
- <div style="-webkit-margin-top-collapse: discard;">text</div>
- </div>
+ <div style="display: flex; width: 100px; height: 100px;">
+ <div id="test1" style="flex-grow: 1; min-height: 100px;">
+ <div style="height: 50px;">text</div>
</div>
</div>
- <div class="bfc">
- <div style="margin-top: 5px;">
- <div id="src1">
- <div style="-webkit-margin-top-collapse: discard;">text</div>
- </div>
+ <div style="display: flex; width: 100px; height: 100px; align-items: stretch;">
+ <div id="src1" style="flex-grow: 1; min-height: 100px;">
+ <div style="height: 50px;">text</div>
</div>
</div>
- <div class="bfc">
- <div style="margin-top: 10px;">
- <div id="test2">
- <div>
- <div style="-webkit-margin-bottom-collapse: discard;"></div>
- </div>
- <div>text</div>
- </div>
+ )HTML");
+
+ auto* test1 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("test1"));
+ auto* src1 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("src1"));
+
+ NGLayoutCacheStatus cache_status;
+ base::Optional<NGFragmentGeometry> fragment_geometry;
+
+ NGConstraintSpace space =
+ src1->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
+ scoped_refptr<const NGLayoutResult> result = test1->CachedLayoutResult(
+ space, nullptr, nullptr, &fragment_geometry, &cache_status);
+
+ // Even though the "align-items: stretch" will make the final fixed
+ // block-size indefinite, we don't have any %-block-size children, so we can
+ // hit the cache.
+ EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
+ EXPECT_NE(result.get(), nullptr);
+}
+
+TEST_F(NGLayoutResultCachingTest, MissIsFixedBlockSizeIndefinite) {
+ SetBodyInnerHTML(R"HTML(
+ <!DOCTYPE html>
+ <div style="display: flex; width: 100px; height: 100px; align-items: start;">
+ <div id="src1" style="flex-grow: 1; min-height: 100px;">
+ <div style="height: 50%;">text</div>
</div>
</div>
- <div class="bfc">
- <div style="margin-top: 5px;">
- <div id="src2">
- <div>
- <div style="-webkit-margin-bottom-collapse: discard;"></div>
- </div>
- <div>text</div>
- </div>
+ <div style="display: flex; width: 100px; height: 100px; align-items: stretch;">
+ <div id="test1" style="flex-grow: 1; min-height: 100px;">
+ <div style="height: 50%;">text</div>
</div>
</div>
)HTML");
auto* test1 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("test1"));
- auto* test2 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("test2"));
auto* src1 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("src1"));
- auto* src2 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("src2"));
NGLayoutCacheStatus cache_status;
base::Optional<NGFragmentGeometry> fragment_geometry;
@@ -1410,18 +1495,62 @@ TEST_F(NGLayoutResultCachingTest, MarginStrutMovementDiscard) {
scoped_refptr<const NGLayoutResult> result = test1->CachedLayoutResult(
space, nullptr, nullptr, &fragment_geometry, &cache_status);
- // Case 1: We can't re-use this fragment as the sub-tree discards margins.
+ // The "align-items: stretch" will make the final fixed block-size
+ // indefinite, and we have a %-block-size child, so we need to miss the
+ // cache.
EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
EXPECT_EQ(result.get(), nullptr);
+}
- fragment_geometry.reset();
+TEST_F(NGLayoutResultCachingTest, HitFlexBoxMeasureAndLayout) {
+ ScopedLayoutNGFlexBoxForTest layout_ng_flex_box(true);
+
+ SetBodyInnerHTML(R"HTML(
+ <!DOCTYPE html>
+ <div style="display: flex; flex-direction: column; width: 100px; height: 100px;">
+ <div id="src1" style="flex-grow: 0;">
+ <div style="height: 50px;"></div>
+ </div>
+ </div>
+ <div style="display: flex; flex-direction: column; width: 100px; height: 100px;">
+ <div id="src2" style="flex-grow: 1;">
+ <div style="height: 50px;"></div>
+ </div>
+ </div>
+ <div style="display: flex; flex-direction: column; width: 100px; height: 100px;">
+ <div id="test1" style="flex-grow: 2;">
+ <div style="height: 50px;"></div>
+ </div>
+ </div>
+ )HTML");
+
+ auto* test1 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("test1"));
+ auto* src1 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("src1"));
+ auto* src2 = To<LayoutBlockFlow>(GetLayoutObjectByElementId("src2"));
+
+ NGLayoutCacheStatus cache_status;
+ base::Optional<NGFragmentGeometry> fragment_geometry;
+
+ // "src1" only had one "measure" pass performed, and should hit the "measure"
+ // cache-slot for "test1".
+ NGConstraintSpace space =
+ src1->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
+ scoped_refptr<const NGLayoutResult> result = test1->CachedLayoutResult(
+ space, nullptr, nullptr, &fragment_geometry, &cache_status);
+
+ EXPECT_EQ(space.CacheSlot(), NGCacheSlot::kMeasure);
+ EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
+ EXPECT_NE(result.get(), nullptr);
+
+ // "src2" had both a "measure" and "layout" pass performed, and should hit
+ // the "layout" cache-slot for "test1".
space = src2->GetCachedLayoutResult()->GetConstraintSpaceForCaching();
- result = test2->CachedLayoutResult(space, nullptr, nullptr,
+ result = test1->CachedLayoutResult(space, nullptr, nullptr,
&fragment_geometry, &cache_status);
- // Case 2: Also check a self-collapsing block with a block-end discard.
- EXPECT_EQ(cache_status, NGLayoutCacheStatus::kNeedsLayout);
- EXPECT_EQ(result.get(), nullptr);
+ EXPECT_EQ(space.CacheSlot(), NGCacheSlot::kLayout);
+ EXPECT_EQ(cache_status, NGLayoutCacheStatus::kHit);
+ EXPECT_NE(result.get(), nullptr);
}
} // namespace
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 229af34617d..3802930ac23 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
@@ -84,6 +84,8 @@ bool SizeMayChange(const NGBlockNode& node,
DCHECK_EQ(new_space.IsFixedInlineSize(), old_space.IsFixedInlineSize());
DCHECK_EQ(new_space.IsFixedBlockSize(), old_space.IsFixedBlockSize());
+ DCHECK_EQ(new_space.IsFixedBlockSizeIndefinite(),
+ old_space.IsFixedBlockSizeIndefinite());
DCHECK_EQ(new_space.IsShrinkToFit(), old_space.IsShrinkToFit());
DCHECK_EQ(new_space.TableCellChildLayoutMode(),
old_space.TableCellChildLayoutMode());
@@ -180,17 +182,48 @@ NGLayoutCacheStatus CalculateSizeBasedLayoutCacheStatusWithGeometry(
LayoutUnit block_size = fragment_geometry.border_box_size.block_size;
bool is_initial_block_size_indefinite = block_size == kIndefiniteSize;
if (is_initial_block_size_indefinite) {
- // 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.
- //
- // Due to this we can't use cached |NGLayoutResult::IntrinsicBlockSize|
- // value, as the following |block_size| calculation would be incorrect.
- if (node.IsFlexibleBox() && style.ResolvedIsColumnFlexDirection() &&
- layout_result.PhysicalFragment().DependsOnPercentageBlockSize()) {
- if (new_space.PercentageResolutionBlockSize() !=
- old_space.PercentageResolutionBlockSize())
+ if (node.IsFlexibleBox()) {
+ // Flex-boxes can have their children calculate their size based in their
+ // parent's final block-size. E.g.
+ // <div style="display: flex;">
+ // <div style="display: flex;">
+ // <!-- Child will stretch to the parent's fixed block-size -->
+ // <div></div>
+ // </div>
+ // </div>
+ // <div style="display: flex;">
+ // <div style="display: flex; flex-direction: column;">
+ // <!-- Child will grow to the parent's fixed block-size -->
+ // <div style="flex: 1;"></div>
+ // </div>
+ // </div>
+ //
+ // If the previous |layout_result| was produced by a space which had a
+ // fixed block-size we can't use |NGLayoutResult::IntrinsicBlockSize()|,
+ // and need to layout.
+ //
+ // TODO(ikilpatrick): Similar to %-block-size descendants we could store
+ // a bit on the |NGLayoutResult| which indicates if it had a child which
+ // sized itself based on the parent's block-size.
+ // We should consider this optimization if we are missing this cache
+ // often within this branch (and could have re-used the result).
+ // TODO(ikilaptrick): This may occur for other layout modes, e.g.
+ // grid/custom-layout/etc.
+ 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.
+ //
+ // 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()) {
+ if (new_space.PercentageResolutionBlockSize() !=
+ old_space.PercentageResolutionBlockSize())
+ return NGLayoutCacheStatus::kNeedsLayout;
+ }
}
block_size = ComputeBlockSizeForFragment(
@@ -209,7 +242,7 @@ NGLayoutCacheStatus CalculateSizeBasedLayoutCacheStatusWithGeometry(
// If a block (within a formatting-context) changes to/from an empty-block,
// margins may collapse through this node, requiring full layout. We
// approximate this check by checking if the block-size is/was zero.
- if (!physical_fragment.IsBlockFormattingContextRoot() &&
+ if (!physical_fragment.IsFormattingContextRoot() &&
!block_size != !fragment.BlockSize())
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 53a8071828b..e07c07e0d08 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
@@ -90,7 +90,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.IsMaxSizeNone())
+ length.IsFitContent() || length.IsNone())
return true;
if (length.IsPercentOrCalc()) {
if (phase == LengthResolvePhase::kIntrinsic)
@@ -115,7 +115,7 @@ LayoutUnit ResolveInlineLengthInternal(
const NGConstraintSpace& constraint_space,
const ComputedStyle& style,
const NGBoxStrut& border_padding,
- const base::Optional<MinMaxSize>& min_and_max,
+ const base::Optional<MinMaxSizes>& min_max_sizes,
const Length& length) {
DCHECK_GE(constraint_space.AvailableSize().inline_size, LayoutUnit());
DCHECK_GE(constraint_space.PercentageResolutionInlineSize(), LayoutUnit());
@@ -146,20 +146,20 @@ LayoutUnit ResolveInlineLengthInternal(
case Length::kMinContent:
case Length::kMaxContent:
case Length::kFitContent: {
- DCHECK(min_and_max.has_value());
+ DCHECK(min_max_sizes.has_value());
LayoutUnit available_size = constraint_space.AvailableSize().inline_size;
LayoutUnit value;
if (length.IsMinContent()) {
- value = min_and_max->min_size;
+ value = min_max_sizes->min_size;
} else if (length.IsMaxContent() || available_size == LayoutUnit::Max()) {
// If the available space is infinite, fit-content resolves to
// max-content. See css-sizing section 2.1.
- value = min_and_max->max_size;
+ value = min_max_sizes->max_size;
} else {
NGBoxStrut margins = ComputeMarginsForSelf(constraint_space, style);
LayoutUnit fill_available =
std::max(LayoutUnit(), available_size - margins.InlineSum());
- value = min_and_max->ShrinkToFit(fill_available);
+ value = min_max_sizes->ShrinkToFit(fill_available);
}
return value;
}
@@ -168,7 +168,7 @@ LayoutUnit ResolveInlineLengthInternal(
case Length::kExtendToZoom:
NOTREACHED() << "These should only be used for viewport definitions";
FALLTHROUGH;
- case Length::kMaxSizeNone:
+ case Length::kNone:
default:
NOTREACHED();
return border_padding.InlineSum();
@@ -235,18 +235,18 @@ LayoutUnit ResolveBlockLengthInternal(
case Length::kExtendToZoom:
NOTREACHED() << "These should only be used for viewport definitions";
FALLTHROUGH;
- case Length::kMaxSizeNone:
+ case Length::kNone:
default:
NOTREACHED();
return border_padding.BlockSum();
}
}
-MinMaxSize ComputeMinAndMaxContentContribution(
+MinMaxSizes ComputeMinAndMaxContentContribution(
WritingMode parent_writing_mode,
const ComputedStyle& style,
const NGBoxStrut& border_padding,
- const base::Optional<MinMaxSize>& min_and_max) {
+ const base::Optional<MinMaxSizes>& min_max_sizes) {
WritingMode child_writing_mode = style.GetWritingMode();
// Synthesize a zero-sized constraint space for resolving sizes against.
@@ -256,20 +256,20 @@ MinMaxSize ComputeMinAndMaxContentContribution(
.ToConstraintSpace();
LayoutUnit content_size =
- min_and_max ? min_and_max->max_size : kIndefiniteSize;
+ min_max_sizes ? min_max_sizes->max_size : kIndefiniteSize;
- MinMaxSize computed_sizes;
+ MinMaxSizes computed_sizes;
const Length& inline_size = parent_writing_mode == WritingMode::kHorizontalTb
? style.Width()
: style.Height();
if (inline_size.IsAuto() || inline_size.IsPercentOrCalc() ||
inline_size.IsFillAvailable() || inline_size.IsFitContent()) {
- CHECK(min_and_max.has_value());
- computed_sizes = *min_and_max;
+ CHECK(min_max_sizes.has_value());
+ computed_sizes = *min_max_sizes;
} else {
if (IsParallelWritingMode(parent_writing_mode, child_writing_mode)) {
computed_sizes = ResolveMainInlineLength(space, style, border_padding,
- min_and_max, inline_size);
+ min_max_sizes, inline_size);
} else {
computed_sizes =
ResolveMainBlockLength(space, style, border_padding, inline_size,
@@ -282,11 +282,11 @@ MinMaxSize ComputeMinAndMaxContentContribution(
: style.MaxHeight();
LayoutUnit max;
if (IsParallelWritingMode(parent_writing_mode, child_writing_mode)) {
- max = ResolveMaxInlineLength(space, style, border_padding, min_and_max,
+ max = ResolveMaxInlineLength(space, style, border_padding, min_max_sizes,
max_length, LengthResolvePhase::kIntrinsic);
} else {
max = ResolveMaxBlockLength(space, style, border_padding, max_length,
- content_size, LengthResolvePhase::kIntrinsic);
+ LengthResolvePhase::kIntrinsic);
}
computed_sizes.Constrain(max);
@@ -295,59 +295,51 @@ MinMaxSize ComputeMinAndMaxContentContribution(
: style.MinHeight();
LayoutUnit min;
if (IsParallelWritingMode(parent_writing_mode, child_writing_mode)) {
- min = ResolveMinInlineLength(space, style, border_padding, min_and_max,
+ min = ResolveMinInlineLength(space, style, border_padding, min_max_sizes,
min_length, LengthResolvePhase::kIntrinsic);
} else {
min = ResolveMinBlockLength(space, style, border_padding, min_length,
- content_size, LengthResolvePhase::kIntrinsic);
+ LengthResolvePhase::kIntrinsic);
}
computed_sizes.Encompass(min);
return computed_sizes;
}
-MinMaxSize ComputeMinAndMaxContentContribution(
+MinMaxSizes ComputeMinAndMaxContentContribution(
const ComputedStyle& parent_style,
NGLayoutInputNode child,
- const MinMaxSizeInput& input) {
+ const MinMaxSizesInput& input) {
const ComputedStyle& child_style = child.Style();
WritingMode parent_writing_mode = parent_style.GetWritingMode();
WritingMode child_writing_mode = child_style.GetWritingMode();
- LayoutBox* box = child.GetLayoutBox();
-
- if (box->NeedsPreferredWidthsRecalculation()) {
- // Some objects (when there's an intrinsic ratio) have their min/max inline
- // size affected by the block size of their container. We don't really know
- // whether the containing block of this child did change or is going to
- // change size. However, this is our only opportunity to make sure that it
- // gets its min/max widths calculated.
- box->SetPreferredLogicalWidthsDirty();
- }
if (IsParallelWritingMode(parent_writing_mode, child_writing_mode)) {
- if (!box->PreferredLogicalWidthsDirty()) {
- return {box->MinPreferredLogicalWidth(), box->MaxPreferredLogicalWidth()};
- }
// Tables are special; even if a width is specified, they may end up being
// sized different. So we just always let the table code handle this.
+ if (child.IsTable())
+ return child.ComputeMinMaxSizes(parent_writing_mode, input, nullptr);
+
// Replaced elements may size themselves using aspect ratios and block
// sizes, so we pass that on as well.
- if (box->IsTable() || box->IsTablePart() || box->IsLayoutReplaced()) {
+ if (child.IsReplaced()) {
+ LayoutBox* box = child.GetLayoutBox();
bool needs_size_reset = false;
if (!box->HasOverrideContainingBlockContentLogicalHeight()) {
box->SetOverrideContainingBlockContentLogicalHeight(
input.percentage_resolution_block_size);
needs_size_reset = true;
}
- MinMaxSize result{box->MinPreferredLogicalWidth(),
- box->MaxPreferredLogicalWidth()};
+
+ MinMaxSizes result = box->PreferredLogicalWidths();
+
if (needs_size_reset)
box->ClearOverrideContainingBlockContentSize();
return result;
}
}
- base::Optional<MinMaxSize> minmax;
+ base::Optional<MinMaxSizes> min_max_sizes;
if (NeedMinMaxSizeForContentContribution(parent_writing_mode, child_style)) {
// We need to set up a constraint space with correct fallback available
// inline size in case of orthogonal children.
@@ -358,8 +350,8 @@ MinMaxSize ComputeMinAndMaxContentContribution(
CreateIndefiniteConstraintSpaceForChild(parent_style, child);
child_constraint_space = &indefinite_constraint_space;
}
- minmax = child.ComputeMinMaxSize(parent_writing_mode, input,
- child_constraint_space);
+ min_max_sizes = child.ComputeMinMaxSizes(parent_writing_mode, input,
+ child_constraint_space);
}
// Synthesize a zero-sized constraint space for determining the borders, and
// padding.
@@ -368,50 +360,17 @@ MinMaxSize ComputeMinAndMaxContentContribution(
/* is_new_fc */ false)
.ToConstraintSpace();
NGBoxStrut border_padding =
- ComputeBorders(space, child) + ComputePadding(space, child_style);
-
- MinMaxSize sizes = ComputeMinAndMaxContentContribution(
- parent_writing_mode, child_style, border_padding, minmax);
- if (IsParallelWritingMode(parent_writing_mode, child_writing_mode))
- box->SetPreferredLogicalWidthsFromNG(sizes);
- return sizes;
-}
-
-MinMaxSize ComputeMinAndMaxContentSizeForOutOfFlow(
- const NGConstraintSpace& constraint_space,
- NGLayoutInputNode node,
- const NGBoxStrut& border_padding,
- const MinMaxSizeInput& input) {
- LayoutBox* box = node.GetLayoutBox();
- // If we've already populated the legacy preferred logical widths cache for
- // this node at the bottom of this function, use those cached results here.
- // Or, if we're working on a table, use the legacy preferred widths code
- // instead of ComputeMinAndMaxContentContribution below because
- // ComputeMinAndMaxContentContribution assumes that if an element has a
- // specified size, that's its final size, which tables don't follow.
- if ((!box->PreferredLogicalWidthsDirty() &&
- !box->NeedsPreferredWidthsRecalculation()) ||
- box->IsTable()) {
- return MinMaxSize{box->MinPreferredLogicalWidth(),
- box->MaxPreferredLogicalWidth()};
- }
+ ComputeBorders(space, child_style) + ComputePadding(space, child_style);
- // Compute the intrinsic sizes without regard to the specified sizes.
- MinMaxSize result = node.ComputeMinMaxSize(node.Style().GetWritingMode(),
- input, &constraint_space);
- // Apply the specified min, main, max sizes.
- MinMaxSize contribution = ComputeMinAndMaxContentContribution(
- node.Style().GetWritingMode(), node.Style(), border_padding, result);
- // Cache these computed values.
- box->SetPreferredLogicalWidthsFromNG(contribution);
- return result;
+ return ComputeMinAndMaxContentContribution(parent_writing_mode, child_style,
+ border_padding, min_max_sizes);
}
LayoutUnit ComputeInlineSizeForFragment(
const NGConstraintSpace& space,
NGLayoutInputNode node,
const NGBoxStrut& border_padding,
- const MinMaxSize* override_minmax_for_test) {
+ const MinMaxSizes* override_min_max_sizes_for_test) {
if (space.IsFixedInlineSize() || space.IsAnonymous())
return space.AvailableSize().inline_size;
@@ -420,57 +379,24 @@ LayoutUnit ComputeInlineSizeForFragment(
if (logical_width.IsAuto() && space.IsShrinkToFit())
logical_width = Length::FitContent();
- LayoutBox* box = node.GetLayoutBox();
- // If we have usable cached min/max intrinsic sizes, use those if we can. They
- // will normally also be constrained to {min,max}-inline-size, but not if
- // percentages are involved. In such cases we'll have to calculate and apply
- // the constraints on our own. We also need to discard the cached values if
- // the box has certain properties (e.g. percentage padding) that cause the
- // cached values to be affected by extrinsic sizing.
- if (!box->PreferredLogicalWidthsDirty() && !override_minmax_for_test &&
- !style.LogicalMinWidth().IsPercentOrCalc() &&
- !style.LogicalMaxWidth().IsPercentOrCalc() &&
- !box->NeedsPreferredWidthsRecalculation()) {
- if (logical_width.IsFitContent()) {
- // This is not as easy as {min, max}.ShrinkToFit() because we also need
- // to subtract inline margins from the available size. The code in
- // ResolveMainInlineLength knows how to handle that, just call that.
-
- MinMaxSize min_and_max = {box->MinPreferredLogicalWidth(),
- box->MaxPreferredLogicalWidth()};
- return ResolveMainInlineLength(space, style, border_padding, min_and_max,
- logical_width);
- }
- if (logical_width.IsMinContent())
- return box->MinPreferredLogicalWidth();
- if (logical_width.IsMaxContent())
- return box->MaxPreferredLogicalWidth();
- }
+ auto MinMaxSizesFunc = [&]() -> MinMaxSizes {
+ if (override_min_max_sizes_for_test)
+ return *override_min_max_sizes_for_test;
- base::Optional<MinMaxSize> min_and_max;
- if (NeedMinMaxSize(space, style)) {
- if (override_minmax_for_test) {
- min_and_max = *override_minmax_for_test;
- } else {
- min_and_max = node.ComputeMinMaxSize(
- space.GetWritingMode(),
- MinMaxSizeInput(space.PercentageResolutionBlockSize()), &space);
- // Cache these computed values
- MinMaxSize contribution = ComputeMinAndMaxContentContribution(
- style.GetWritingMode(), style, border_padding, min_and_max);
- box->SetPreferredLogicalWidthsFromNG(contribution);
- }
- }
+ return node.ComputeMinMaxSizes(
+ space.GetWritingMode(),
+ MinMaxSizesInput(space.PercentageResolutionBlockSize()), &space);
+ };
LayoutUnit extent = ResolveMainInlineLength(space, style, border_padding,
- min_and_max, logical_width);
-
- LayoutUnit max = ResolveMaxInlineLength(space, style, border_padding,
- min_and_max, style.LogicalMaxWidth(),
- LengthResolvePhase::kLayout);
- LayoutUnit min = ResolveMinInlineLength(space, style, border_padding,
- min_and_max, style.LogicalMinWidth(),
- LengthResolvePhase::kLayout);
+ MinMaxSizesFunc, logical_width);
+
+ LayoutUnit max = ResolveMaxInlineLength(
+ space, style, border_padding, MinMaxSizesFunc, style.LogicalMaxWidth(),
+ LengthResolvePhase::kLayout);
+ LayoutUnit min = ResolveMinInlineLength(
+ space, style, border_padding, MinMaxSizesFunc, style.LogicalMinWidth(),
+ LengthResolvePhase::kLayout);
return ConstrainByMinMax(extent, min, max);
}
@@ -486,7 +412,7 @@ LayoutUnit ComputeBlockSizeForFragmentInternal(
nullptr) {
LayoutUnit min = ResolveMinBlockLength(
constraint_space, style, border_padding, style.LogicalMinHeight(),
- content_size, LengthResolvePhase::kLayout,
+ LengthResolvePhase::kLayout,
opt_percentage_resolution_block_size_for_min_max);
const Length& logical_height = style.LogicalHeight();
// Scrollable percentage-sized children of table cells, in the table
@@ -518,7 +444,7 @@ LayoutUnit ComputeBlockSizeForFragmentInternal(
LayoutUnit max = ResolveMaxBlockLength(
constraint_space, style, border_padding, style.LogicalMaxHeight(),
- content_size, LengthResolvePhase::kLayout,
+ LengthResolvePhase::kLayout,
opt_percentage_resolution_block_size_for_min_max);
return ConstrainByMinMax(extent, min, max);
@@ -546,9 +472,9 @@ LayoutUnit ComputeBlockSizeForFragment(
}
// Computes size for a replaced element.
-void ComputeReplacedSize(const NGLayoutInputNode& node,
+void ComputeReplacedSize(const NGBlockNode& node,
const NGConstraintSpace& space,
- const base::Optional<MinMaxSize>& child_minmax,
+ const base::Optional<MinMaxSizes>& child_min_max_sizes,
base::Optional<LogicalSize>* out_replaced_size,
base::Optional<LogicalSize>* out_aspect_ratio) {
DCHECK(node.IsReplaced());
@@ -558,26 +484,26 @@ void ComputeReplacedSize(const NGLayoutInputNode& node,
const ComputedStyle& style = node.Style();
NGBoxStrut border_padding =
- ComputeBorders(space, node) + ComputePadding(space, style);
+ ComputeBorders(space, style) + ComputePadding(space, style);
LayoutUnit inline_min = ResolveMinInlineLength(
- space, style, border_padding, child_minmax, style.LogicalMinWidth(),
- LengthResolvePhase::kLayout);
+ space, style, border_padding, child_min_max_sizes,
+ style.LogicalMinWidth(), LengthResolvePhase::kLayout);
LayoutUnit inline_max = ResolveMaxInlineLength(
- space, style, border_padding, child_minmax, style.LogicalMaxWidth(),
- LengthResolvePhase::kLayout);
- LayoutUnit block_min = ResolveMinBlockLength(
- space, style, border_padding, style.LogicalMinHeight(),
- border_padding.BlockSum(), LengthResolvePhase::kLayout);
- LayoutUnit block_max = ResolveMaxBlockLength(
- space, style, border_padding, style.LogicalMaxHeight(), LayoutUnit::Max(),
- LengthResolvePhase::kLayout);
+ space, style, border_padding, child_min_max_sizes,
+ style.LogicalMaxWidth(), LengthResolvePhase::kLayout);
+ LayoutUnit block_min = ResolveMinBlockLength(space, style, border_padding,
+ style.LogicalMinHeight(),
+ LengthResolvePhase::kLayout);
+ LayoutUnit block_max = ResolveMaxBlockLength(space, style, border_padding,
+ style.LogicalMaxHeight(),
+ LengthResolvePhase::kLayout);
const Length& inline_length = style.LogicalWidth();
const Length& block_length = style.LogicalHeight();
base::Optional<LayoutUnit> replaced_inline;
if (!inline_length.IsAuto()) {
- replaced_inline = ResolveMainInlineLength(space, style, border_padding,
- child_minmax, inline_length);
+ replaced_inline = ResolveMainInlineLength(
+ space, style, border_padding, child_min_max_sizes, inline_length);
replaced_inline =
ConstrainByMinMax(*replaced_inline, inline_min, inline_max);
}
@@ -595,9 +521,10 @@ void ComputeReplacedSize(const NGLayoutInputNode& node,
base::Optional<LayoutUnit> intrinsic_inline;
base::Optional<LayoutUnit> intrinsic_block;
- LogicalSize aspect_ratio;
+ node.IntrinsicSize(&intrinsic_inline, &intrinsic_block);
+
+ LogicalSize aspect_ratio = node.GetAspectRatio();
- node.IntrinsicSize(&intrinsic_inline, &intrinsic_block, &aspect_ratio);
// Computing intrinsic size is complicated by the fact that
// intrinsic_inline, intrinsic_block, and aspect_ratio can all
// be empty independent of each other.
@@ -850,7 +777,7 @@ NGBoxStrut ComputeBordersInternal(const ComputedStyle& style) {
} // namespace
NGBoxStrut ComputeBorders(const NGConstraintSpace& constraint_space,
- const NGLayoutInputNode node) {
+ const ComputedStyle& style) {
// If we are producing an anonymous fragment (e.g. a column), it has no
// borders, padding or scrollbars. Using the ones from the container can only
// cause trouble.
@@ -862,7 +789,7 @@ NGBoxStrut ComputeBorders(const NGConstraintSpace& constraint_space,
if (constraint_space.IsTableCell())
return constraint_space.TableCellBorders();
- return ComputeBordersInternal(node.Style());
+ return ComputeBordersInternal(style);
}
NGBoxStrut ComputeBordersForInline(const ComputedStyle& style) {
@@ -1058,7 +985,7 @@ NGFragmentGeometry CalculateInitialFragmentGeometry(
const NGBlockNode& node) {
const ComputedStyle& style = node.Style();
- NGBoxStrut border = ComputeBorders(constraint_space, node);
+ NGBoxStrut border = ComputeBorders(constraint_space, style);
NGBoxStrut padding = ComputePadding(constraint_space, style);
NGBoxStrut scrollbar = ComputeScrollbars(constraint_space, node);
NGBoxStrut border_padding = border + padding;
@@ -1096,8 +1023,9 @@ NGFragmentGeometry CalculateInitialFragmentGeometry(
NGFragmentGeometry CalculateInitialMinMaxFragmentGeometry(
const NGConstraintSpace& constraint_space,
const NGBlockNode& node) {
- NGBoxStrut border = ComputeBorders(constraint_space, node);
- NGBoxStrut padding = ComputePadding(constraint_space, node.Style());
+ const ComputedStyle& style = node.Style();
+ NGBoxStrut border = ComputeBorders(constraint_space, style);
+ NGBoxStrut padding = ComputePadding(constraint_space, style);
NGBoxStrut scrollbar = ComputeScrollbars(constraint_space, node);
return {/* border_box_size */ LogicalSize(), border, scrollbar, padding};
@@ -1210,7 +1138,10 @@ LayoutUnit CalculateChildPercentageBlockSizeForMinMax(
const NGBoxStrut& border_padding,
LayoutUnit parent_percentage_block_size) {
// Anonymous block or spaces should pass the percent size straight through.
- if (space.IsAnonymous() || node.IsAnonymousBlock())
+ // If this node is OOF-positioned, our size was pre-calculated and we should
+ // pass this through to our children.
+ if (space.IsAnonymous() || node.IsAnonymousBlock() ||
+ node.IsOutOfFlowPositioned())
return parent_percentage_block_size;
LayoutUnit block_size = ComputeBlockSizeForFragmentInternal(
@@ -1225,8 +1156,7 @@ LayoutUnit CalculateChildPercentageBlockSizeForMinMax(
// For OOF-positioned nodes, use the parent (containing-block) size.
if (child_percentage_block_size == kIndefiniteSize &&
- (node.UseParentPercentageResolutionBlockSizeForChildren() ||
- node.IsOutOfFlowPositioned()))
+ node.UseParentPercentageResolutionBlockSizeForChildren())
child_percentage_block_size = parent_percentage_block_size;
return child_percentage_block_size;
@@ -1255,8 +1185,13 @@ LayoutUnit ClampIntrinsicBlockSize(
// If the intrinsic size was overridden, then use that.
LayoutUnit intrinsic_size_override = node.OverrideIntrinsicContentBlockSize();
- if (intrinsic_size_override != kIndefiniteSize)
+ if (intrinsic_size_override != kIndefiniteSize) {
return intrinsic_size_override + border_scrollbar_padding.BlockSum();
+ } else {
+ LayoutUnit default_intrinsic_size = node.DefaultIntrinsicContentBlockSize();
+ if (default_intrinsic_size != kIndefiniteSize)
+ return default_intrinsic_size + border_scrollbar_padding.BlockSum();
+ }
// If we have size containment, we ignore child contributions to intrinsic
// sizing.
@@ -1265,13 +1200,11 @@ LayoutUnit ClampIntrinsicBlockSize(
return current_intrinsic_block_size;
}
-base::Optional<MinMaxSize> CalculateMinMaxSizesIgnoringChildren(
+base::Optional<MinMaxSizes> CalculateMinMaxSizesIgnoringChildren(
const NGBlockNode& node,
- const NGBoxStrut& border_scrollbar_padding,
- NGMinMaxSizeType type) {
- MinMaxSize sizes;
- if (type == NGMinMaxSizeType::kBorderBoxSize)
- sizes += border_scrollbar_padding.InlineSum();
+ const NGBoxStrut& border_scrollbar_padding) {
+ MinMaxSizes sizes;
+ sizes += border_scrollbar_padding.InlineSum();
// If intrinsic size was overridden, then use that.
const LayoutUnit intrinsic_size_override =
@@ -1279,6 +1212,12 @@ base::Optional<MinMaxSize> CalculateMinMaxSizesIgnoringChildren(
if (intrinsic_size_override != kIndefiniteSize) {
sizes += intrinsic_size_override;
return sizes;
+ } else {
+ LayoutUnit default_inline_size = node.DefaultIntrinsicContentInlineSize();
+ if (default_inline_size != kIndefiniteSize) {
+ sizes += default_inline_size;
+ return sizes;
+ }
}
// Size contained elements don't consider children for intrinsic sizing.
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 525a28b6cec..2a618216acc 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
@@ -9,7 +9,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/geometry/logical_size.h"
#include "third_party/blink/renderer/core/layout/geometry/physical_size.h"
-#include "third_party/blink/renderer/core/layout/min_max_size.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/layout/ng/geometry/ng_fragment_geometry.h"
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h"
@@ -22,7 +22,7 @@
namespace blink {
class ComputedStyle;
class Length;
-struct MinMaxSizeInput;
+struct MinMaxSizesInput;
class NGConstraintSpace;
class NGBlockNode;
class NGLayoutInputNode;
@@ -41,15 +41,6 @@ inline bool NeedMinMaxSize(const ComputedStyle& style) {
style.LogicalMaxWidth().IsIntrinsic();
}
-// Whether the caller needs to compute min-content and max-content sizes to
-// pass them to ResolveMainInlineLength / ComputeInlineSizeForFragment.
-// If this function returns false, it is safe to pass an empty
-// MinMaxSize struct to those functions.
-inline bool NeedMinMaxSize(const NGConstraintSpace& constraint_space,
- const ComputedStyle& style) {
- return constraint_space.IsShrinkToFit() || NeedMinMaxSize(style);
-}
-
// Like NeedMinMaxSize, but for use when calling
// ComputeMinAndMaxContentContribution.
// Because content contributions are commonly needed by a block's parent,
@@ -75,17 +66,17 @@ CORE_EXPORT bool BlockLengthUnresolvable(
// available-size.
// - |ComputedStyle| the style of the node.
// - |border_padding| the resolved border, and padding of the node.
-// - |MinMaxSize| is only used when the length is intrinsic (fit-content).
+// - |MinMaxSizes| is only used when the length is intrinsic (fit-content).
// - |Length| is the length to resolve.
CORE_EXPORT LayoutUnit
ResolveInlineLengthInternal(const NGConstraintSpace&,
const ComputedStyle&,
const NGBoxStrut& border_padding,
- const base::Optional<MinMaxSize>&,
+ const base::Optional<MinMaxSizes>&,
const Length&);
// Same as ResolveInlineLengthInternal, except here |content_size| roughly plays
-// the part of |MinMaxSize|.
+// the part of |MinMaxSizes|.
CORE_EXPORT LayoutUnit ResolveBlockLengthInternal(
const NGConstraintSpace&,
const ComputedStyle&,
@@ -97,44 +88,100 @@ CORE_EXPORT LayoutUnit ResolveBlockLengthInternal(
nullptr);
// Used for resolving min inline lengths, (|ComputedStyle::MinLogicalWidth|).
+template <typename MinMaxSizesFunc>
inline LayoutUnit ResolveMinInlineLength(
const NGConstraintSpace& constraint_space,
const ComputedStyle& style,
const NGBoxStrut& border_padding,
- const base::Optional<MinMaxSize>& min_and_max,
+ const MinMaxSizesFunc& min_max_sizes_func,
+ const Length& length,
+ LengthResolvePhase phase) {
+ if (LIKELY(length.IsAuto() || InlineLengthUnresolvable(length, phase)))
+ return border_padding.InlineSum();
+
+ base::Optional<MinMaxSizes> min_max_sizes;
+ if (length.IsIntrinsic())
+ min_max_sizes = min_max_sizes_func();
+
+ return ResolveInlineLengthInternal(constraint_space, style, border_padding,
+ min_max_sizes, length);
+}
+
+template <>
+inline LayoutUnit ResolveMinInlineLength<base::Optional<MinMaxSizes>>(
+ const NGConstraintSpace& constraint_space,
+ const ComputedStyle& style,
+ const NGBoxStrut& border_padding,
+ const base::Optional<MinMaxSizes>& min_max_sizes,
const Length& length,
LengthResolvePhase phase) {
if (LIKELY(length.IsAuto() || InlineLengthUnresolvable(length, phase)))
return border_padding.InlineSum();
return ResolveInlineLengthInternal(constraint_space, style, border_padding,
- min_and_max, length);
+ min_max_sizes, length);
}
// Used for resolving max inline lengths, (|ComputedStyle::MaxLogicalWidth|).
+template <typename MinMaxSizesFunc>
inline LayoutUnit ResolveMaxInlineLength(
const NGConstraintSpace& constraint_space,
const ComputedStyle& style,
const NGBoxStrut& border_padding,
- const base::Optional<MinMaxSize>& min_and_max,
+ const MinMaxSizesFunc& min_max_sizes_func,
const Length& length,
LengthResolvePhase phase) {
- if (LIKELY(length.IsMaxSizeNone() || InlineLengthUnresolvable(length, phase)))
+ if (LIKELY(length.IsNone() || InlineLengthUnresolvable(length, phase)))
return LayoutUnit::Max();
+ base::Optional<MinMaxSizes> min_max_sizes;
+ if (length.IsIntrinsic())
+ min_max_sizes = min_max_sizes_func();
+
return ResolveInlineLengthInternal(constraint_space, style, border_padding,
- min_and_max, length);
+ min_max_sizes, length);
+}
+
+template <>
+inline LayoutUnit ResolveMaxInlineLength<base::Optional<MinMaxSizes>>(
+ const NGConstraintSpace& constraint_space,
+ const ComputedStyle& style,
+ const NGBoxStrut& border_padding,
+ const base::Optional<MinMaxSizes>& min_max_sizes,
+ const Length& length,
+ LengthResolvePhase phase) {
+ if (LIKELY(length.IsNone() || InlineLengthUnresolvable(length, phase)))
+ return LayoutUnit::Max();
+
+ return ResolveInlineLengthInternal(constraint_space, style, border_padding,
+ min_max_sizes, length);
}
// Used for resolving main inline lengths, (|ComputedStyle::LogicalWidth|).
+template <typename MinMaxSizesFunc>
inline LayoutUnit ResolveMainInlineLength(
const NGConstraintSpace& constraint_space,
const ComputedStyle& style,
const NGBoxStrut& border_padding,
- const base::Optional<MinMaxSize>& min_and_max,
+ 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();
+
+ return ResolveInlineLengthInternal(constraint_space, style, border_padding,
+ min_max_sizes, length);
+}
+
+template <>
+inline LayoutUnit ResolveMainInlineLength<base::Optional<MinMaxSizes>>(
+ const NGConstraintSpace& constraint_space,
+ const ComputedStyle& style,
+ const NGBoxStrut& border_padding,
+ const base::Optional<MinMaxSizes>& min_max_sizes,
const Length& length) {
return ResolveInlineLengthInternal(constraint_space, style, border_padding,
- min_and_max, length);
+ min_max_sizes, length);
}
// Used for resolving min block lengths, (|ComputedStyle::MinLogicalHeight|).
@@ -143,7 +190,6 @@ inline LayoutUnit ResolveMinBlockLength(
const ComputedStyle& style,
const NGBoxStrut& border_padding,
const Length& length,
- LayoutUnit content_size,
LengthResolvePhase phase,
const LayoutUnit* opt_percentage_resolution_block_size_for_min_max =
nullptr) {
@@ -153,7 +199,7 @@ inline LayoutUnit ResolveMinBlockLength(
return border_padding.BlockSum();
return ResolveBlockLengthInternal(
- constraint_space, style, border_padding, length, content_size, phase,
+ constraint_space, style, border_padding, length, kIndefiniteSize, phase,
opt_percentage_resolution_block_size_for_min_max);
}
@@ -163,7 +209,6 @@ inline LayoutUnit ResolveMaxBlockLength(
const ComputedStyle& style,
const NGBoxStrut& border_padding,
const Length& length,
- LayoutUnit content_size,
LengthResolvePhase phase,
const LayoutUnit* opt_percentage_resolution_block_size_for_min_max =
nullptr) {
@@ -173,7 +218,7 @@ inline LayoutUnit ResolveMaxBlockLength(
return LayoutUnit::Max();
return ResolveBlockLengthInternal(
- constraint_space, style, border_padding, length, content_size, phase,
+ constraint_space, style, border_padding, length, kIndefiniteSize, phase,
opt_percentage_resolution_block_size_for_min_max);
}
@@ -198,6 +243,31 @@ inline LayoutUnit ResolveMainBlockLength(
opt_percentage_resolution_block_size_for_min_max);
}
+template <typename IntrinsicBlockSizeFunc>
+inline LayoutUnit ResolveMainBlockLength(
+ const NGConstraintSpace& constraint_space,
+ const ComputedStyle& style,
+ const NGBoxStrut& border_padding,
+ const Length& length,
+ const IntrinsicBlockSizeFunc& intrinsic_block_size_func,
+ LengthResolvePhase phase,
+ const LayoutUnit* opt_percentage_resolution_block_size_for_min_max =
+ nullptr) {
+ if (UNLIKELY((length.IsPercentOrCalc() || length.IsFillAvailable()) &&
+ BlockLengthUnresolvable(
+ constraint_space, length, phase,
+ opt_percentage_resolution_block_size_for_min_max)))
+ return intrinsic_block_size_func();
+
+ LayoutUnit intrinsic_block_size = kIndefiniteSize;
+ if (length.IsIntrinsicOrAuto())
+ intrinsic_block_size = intrinsic_block_size_func();
+
+ return ResolveBlockLengthInternal(
+ constraint_space, style, border_padding, length, intrinsic_block_size,
+ phase, opt_percentage_resolution_block_size_for_min_max);
+}
+
// For the given style and min/max content sizes, computes the min and max
// content contribution (https://drafts.csswg.org/css-sizing/#contributions).
// This is similar to ComputeInlineSizeForFragment except that it does not
@@ -208,11 +278,11 @@ inline LayoutUnit ResolveMainBlockLength(
// Because content contributions are commonly needed by a block's parent,
// we also take a writing mode here so we can compute this in the parent's
// coordinate system.
-CORE_EXPORT MinMaxSize
+CORE_EXPORT MinMaxSizes
ComputeMinAndMaxContentContribution(WritingMode writing_mode,
const ComputedStyle&,
const NGBoxStrut& border_padding,
- const base::Optional<MinMaxSize>&);
+ const base::Optional<MinMaxSizes>&);
// A version of ComputeMinAndMaxContentContribution that does not require you
// to compute the min/max content size of the child. Instead, this function
@@ -222,31 +292,22 @@ ComputeMinAndMaxContentContribution(WritingMode writing_mode,
// parent, we'll still return the inline min/max contribution in the writing
// mode of the parent (i.e. typically something based on the preferred *block*
// size of the child).
-MinMaxSize ComputeMinAndMaxContentContribution(
+MinMaxSizes ComputeMinAndMaxContentContribution(
const ComputedStyle& parent_style,
NGLayoutInputNode child,
- const MinMaxSizeInput&);
-
-// Computes the min/max-content size for an out-of-flow positioned node and
-// returns it, using the cache where possible. ALways computes it in the writing
-// mode of the node itself.
-MinMaxSize ComputeMinAndMaxContentSizeForOutOfFlow(
- const NGConstraintSpace&,
- NGLayoutInputNode,
- const NGBoxStrut& border_padding,
- const MinMaxSizeInput&);
+ const MinMaxSizesInput&);
// Returns inline size of the node's border box by resolving the computed value
// in style.logicalWidth (Length) to a layout unit, adding border and padding,
// then constraining the result by the resolved min logical width and max
// logical width from the ComputedStyle object. Calls Node::ComputeMinMaxSize
// if needed.
-// |override_minmax_for_test| is provided *solely* for use by unit tests.
+// |override_min_max_sizes_for_test| is provided *solely* for use by unit tests.
CORE_EXPORT LayoutUnit ComputeInlineSizeForFragment(
const NGConstraintSpace&,
NGLayoutInputNode,
const NGBoxStrut& border_padding,
- const MinMaxSize* override_minmax_for_test = nullptr);
+ const MinMaxSizes* override_min_max_sizes_for_test = nullptr);
// Same as ComputeInlineSizeForFragment, but uses height instead of width.
CORE_EXPORT LayoutUnit
@@ -265,9 +326,9 @@ ComputeBlockSizeForFragment(const NGConstraintSpace&,
// - neither out_aspect_ratio, nor out_replaced_size
// SVG elements can return any of the three options above.
CORE_EXPORT void ComputeReplacedSize(
- const NGLayoutInputNode&,
+ const NGBlockNode&,
const NGConstraintSpace&,
- const base::Optional<MinMaxSize>&,
+ const base::Optional<MinMaxSizes>&,
base::Optional<LogicalSize>* out_replaced_size,
base::Optional<LogicalSize>* out_aspect_ratio);
@@ -364,7 +425,7 @@ CORE_EXPORT NGBoxStrut ComputeMinMaxMargins(const ComputedStyle& parent_style,
NGLayoutInputNode child);
CORE_EXPORT NGBoxStrut ComputeBorders(const NGConstraintSpace&,
- const NGLayoutInputNode);
+ const ComputedStyle&);
CORE_EXPORT NGBoxStrut ComputeBordersForInline(const ComputedStyle& style);
@@ -480,11 +541,9 @@ LayoutUnit ClampIntrinsicBlockSize(
// without considering children. If so, it returns the calculated size.
// Otherwise, it returns base::nullopt and the caller has to compute the size
// itself.
-base::Optional<MinMaxSize> CalculateMinMaxSizesIgnoringChildren(
+base::Optional<MinMaxSizes> CalculateMinMaxSizesIgnoringChildren(
const NGBlockNode&,
- const NGBoxStrut& border_scrollbar_padding,
- NGMinMaxSizeType);
-
+ const NGBoxStrut& border_scrollbar_padding);
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_length_utils_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_length_utils_test.cc
index 6b63229023f..f374f55a0cb 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_length_utils_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_length_utils_test.cc
@@ -41,7 +41,7 @@ class NGLengthUtilsTest : public testing::Test {
LayoutUnit ResolveMainInlineLength(
const Length& length,
- const base::Optional<MinMaxSize>& sizes = base::nullopt) {
+ const base::Optional<MinMaxSizes>& sizes = base::nullopt) {
NGConstraintSpace constraint_space = ConstructConstraintSpace(200, 300);
NGBoxStrut border_padding = ComputeBordersForTest(*style_) +
ComputePadding(constraint_space, *style_);
@@ -53,7 +53,7 @@ class NGLengthUtilsTest : public testing::Test {
LayoutUnit ResolveMinInlineLength(
const Length& length,
LengthResolvePhase phase = LengthResolvePhase::kLayout,
- const base::Optional<MinMaxSize>& sizes = base::nullopt) {
+ const base::Optional<MinMaxSizes>& sizes = base::nullopt) {
NGConstraintSpace constraint_space = ConstructConstraintSpace(200, 300);
NGBoxStrut border_padding = ComputeBordersForTest(*style_) +
ComputePadding(constraint_space, *style_);
@@ -65,7 +65,7 @@ class NGLengthUtilsTest : public testing::Test {
LayoutUnit ResolveMaxInlineLength(
const Length& length,
LengthResolvePhase phase = LengthResolvePhase::kLayout,
- const base::Optional<MinMaxSize>& sizes = base::nullopt) {
+ const base::Optional<MinMaxSizes>& sizes = base::nullopt) {
NGConstraintSpace constraint_space = ConstructConstraintSpace(200, 300);
NGBoxStrut border_padding = ComputeBordersForTest(*style_) +
ComputePadding(constraint_space, *style_);
@@ -97,10 +97,10 @@ class NGLengthUtilsTestWithNode : public NGLayoutTest {
LayoutUnit ComputeInlineSizeForFragment(
NGConstraintSpace constraint_space = ConstructConstraintSpace(200, 300),
- const MinMaxSize& sizes = MinMaxSize()) {
+ const MinMaxSizes& sizes = MinMaxSizes()) {
LayoutBox* body = ToLayoutBox(GetDocument().body()->GetLayoutObject());
body->SetStyle(style_);
- body->SetPreferredLogicalWidthsDirty();
+ body->SetIntrinsicLogicalWidthsDirty();
NGBlockNode node(body);
NGBoxStrut border_padding = ComputeBordersForTest(*style_) +
@@ -114,7 +114,7 @@ class NGLengthUtilsTestWithNode : public NGLayoutTest {
LayoutUnit content_size = LayoutUnit()) {
LayoutBox* body = ToLayoutBox(GetDocument().body()->GetLayoutObject());
body->SetStyle(style_);
- body->SetPreferredLogicalWidthsDirty();
+ body->SetIntrinsicLogicalWidthsDirty();
NGBoxStrut border_padding = ComputeBordersForTest(*style_) +
ComputePadding(constraint_space, *style_);
@@ -139,7 +139,7 @@ TEST_F(NGLengthUtilsTest, testResolveInlineLength) {
EXPECT_EQ(LayoutUnit::Max(),
ResolveMaxInlineLength(Length::FillAvailable(),
LengthResolvePhase::kIntrinsic));
- MinMaxSize sizes;
+ MinMaxSizes sizes;
sizes.min_size = LayoutUnit(30);
sizes.max_size = LayoutUnit(40);
EXPECT_EQ(LayoutUnit(30),
@@ -168,13 +168,13 @@ TEST_F(NGLengthUtilsTest, testResolveBlockLength) {
}
TEST_F(NGLengthUtilsTest, testComputeContentContribution) {
- MinMaxSize sizes;
+ MinMaxSizes sizes;
sizes.min_size = LayoutUnit(30);
sizes.max_size = LayoutUnit(40);
NGBoxStrut border_padding;
- MinMaxSize expected = sizes;
+ MinMaxSizes expected = sizes;
style_->SetLogicalWidth(Length::Percent(30));
EXPECT_EQ(expected,
ComputeMinAndMaxContentContribution(
@@ -185,7 +185,7 @@ TEST_F(NGLengthUtilsTest, testComputeContentContribution) {
ComputeMinAndMaxContentContribution(
style_->GetWritingMode(), *style_, border_padding, sizes));
- expected = MinMaxSize{LayoutUnit(150), LayoutUnit(150)};
+ expected = MinMaxSizes{LayoutUnit(150), LayoutUnit(150)};
style_->SetLogicalWidth(Length::Fixed(150));
EXPECT_EQ(expected,
ComputeMinAndMaxContentContribution(
@@ -197,7 +197,7 @@ TEST_F(NGLengthUtilsTest, testComputeContentContribution) {
ComputeMinAndMaxContentContribution(
style_->GetWritingMode(), *style_, border_padding, sizes));
- expected = MinMaxSize{LayoutUnit(430), LayoutUnit(440)};
+ expected = MinMaxSizes{LayoutUnit(430), LayoutUnit(440)};
style_->SetPaddingLeft(Length::Fixed(400));
auto sizes_padding400 = sizes;
sizes_padding400 += LayoutUnit(400);
@@ -207,7 +207,7 @@ TEST_F(NGLengthUtilsTest, testComputeContentContribution) {
style_->GetWritingMode(), *style_, border_padding400,
sizes_padding400));
- expected = MinMaxSize{LayoutUnit(30), LayoutUnit(40)};
+ expected = MinMaxSizes{LayoutUnit(30), LayoutUnit(40)};
style_->SetPaddingLeft(Length::Fixed(0));
style_->SetLogicalWidth(Length(CalculationValue::Create(
PixelsAndPercent(100, -10), kValueRangeNonNegative)));
@@ -215,21 +215,21 @@ TEST_F(NGLengthUtilsTest, testComputeContentContribution) {
ComputeMinAndMaxContentContribution(
style_->GetWritingMode(), *style_, border_padding, sizes));
- expected = MinMaxSize{LayoutUnit(30), LayoutUnit(35)};
+ expected = MinMaxSizes{LayoutUnit(30), LayoutUnit(35)};
style_->SetLogicalWidth(Length::Auto());
style_->SetMaxWidth(Length::Fixed(35));
EXPECT_EQ(expected,
ComputeMinAndMaxContentContribution(
style_->GetWritingMode(), *style_, border_padding, sizes));
- expected = MinMaxSize{LayoutUnit(80), LayoutUnit(80)};
+ expected = MinMaxSizes{LayoutUnit(80), LayoutUnit(80)};
style_->SetLogicalWidth(Length::Fixed(50));
style_->SetMinWidth(Length::Fixed(80));
EXPECT_EQ(expected,
ComputeMinAndMaxContentContribution(
style_->GetWritingMode(), *style_, border_padding, sizes));
- expected = MinMaxSize{LayoutUnit(150), LayoutUnit(150)};
+ expected = MinMaxSizes{LayoutUnit(150), LayoutUnit(150)};
style_ = ComputedStyle::Create();
style_->SetLogicalWidth(Length::Fixed(100));
style_->SetPaddingLeft(Length::Fixed(50));
@@ -241,7 +241,7 @@ TEST_F(NGLengthUtilsTest, testComputeContentContribution) {
style_->GetWritingMode(), *style_, border_padding50,
sizes_padding50));
- expected = MinMaxSize{LayoutUnit(100), LayoutUnit(100)};
+ expected = MinMaxSizes{LayoutUnit(100), LayoutUnit(100)};
style_->SetBoxSizing(EBoxSizing::kBorderBox);
EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(
style_->GetWritingMode(), *style_, border_padding50,
@@ -249,7 +249,7 @@ TEST_F(NGLengthUtilsTest, testComputeContentContribution) {
// Content size should never be below zero, even with box-sizing: border-box
// and a large padding...
- expected = MinMaxSize{LayoutUnit(400), LayoutUnit(400)};
+ expected = MinMaxSizes{LayoutUnit(400), LayoutUnit(400)};
style_->SetPaddingLeft(Length::Fixed(400));
EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(
style_->GetWritingMode(), *style_, border_padding400,
@@ -264,11 +264,11 @@ TEST_F(NGLengthUtilsTest, testComputeContentContribution) {
style_->SetMaxWidth(Length::MaxContent());
// Due to padding and box-sizing, width computes to 400px and max-width to
// 440px, so the result is 400.
- expected = MinMaxSize{LayoutUnit(400), LayoutUnit(400)};
+ expected = MinMaxSizes{LayoutUnit(400), LayoutUnit(400)};
EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(
style_->GetWritingMode(), *style_, border_padding400,
sizes_padding400));
- expected = MinMaxSize{LayoutUnit(40), LayoutUnit(40)};
+ expected = MinMaxSizes{LayoutUnit(40), LayoutUnit(40)};
style_->SetPaddingLeft(Length::Fixed(0));
EXPECT_EQ(expected,
ComputeMinAndMaxContentContribution(
@@ -276,7 +276,7 @@ TEST_F(NGLengthUtilsTest, testComputeContentContribution) {
}
TEST_F(NGLengthUtilsTestWithNode, testComputeInlineSizeForFragment) {
- MinMaxSize sizes;
+ MinMaxSizes sizes;
sizes.min_size = LayoutUnit(30);
sizes.max_size = LayoutUnit(40);
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 df903e64148..0df01829351 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
@@ -237,10 +237,8 @@ bool NGOutOfFlowLayoutPart::SweepLegacyCandidates(
// size first.
// We perform a pre-layout to correctly determine the static position.
// Copied from LayoutBlock::LayoutPositionedObject
+ // TODO(layout-dev): Remove this once LayoutFlexibleBox is removed.
LayoutBox* layout_box = ToLayoutBox(legacy_object);
- // TODO(dgrogan): The NG flexbox implementation doesn't have an
- // analogous method yet, so abspos children of NG flexboxes that have a
- // legacy containing block will not be positioned correctly.
if (layout_box->Parent()->IsFlexibleBox()) {
LayoutFlexibleBox* parent = ToLayoutFlexibleBox(layout_box->Parent());
if (parent->SetStaticPositionForPositionedLayout(*layout_box)) {
@@ -293,22 +291,22 @@ void NGOutOfFlowLayoutPart::ComputeInlineContainingBlocks(
inline_geometry);
}
}
- // Fetch start/end fragment info.
- container_builder_->ComputeInlineContainerFragments(
- &inline_container_fragments);
+
+ // Fetch the inline start/end fragment geometry.
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ container_builder_->ComputeInlineContainerGeometry(
+ &inline_container_fragments);
+ } else {
+ container_builder_->ComputeInlineContainerGeometryFromFragmentTree(
+ &inline_container_fragments);
+ }
+
LogicalSize container_builder_size = container_builder_->Size();
PhysicalSize container_builder_physical_size =
ToPhysicalSize(container_builder_size, writing_mode_);
- // Translate start/end fragments into ContainingBlockInfo.
+ // Transform the start/end fragments into a ContainingBlockInfo.
for (auto& block_info : inline_container_fragments) {
- // Variables needed to describe ContainingBlockInfo
- const ComputedStyle* inline_cb_style = block_info.key->Style();
- LogicalSize inline_cb_size;
- LogicalOffset container_offset;
-
DCHECK(block_info.value.has_value());
- DCHECK(inline_cb_style);
- NGBoxStrut inline_cb_borders = ComputeBordersForInline(*inline_cb_style);
// The calculation below determines the size of the inline containing block
// rect.
@@ -362,7 +360,11 @@ void NGOutOfFlowLayoutPart::ComputeInlineContainingBlocks(
//
// Note in cases [2a, 2b] we don't allow a "negative" containing block size,
// we clamp negative sizes to zero.
+ const ComputedStyle* inline_cb_style = block_info.key->Style();
+ DCHECK(inline_cb_style);
+
TextDirection container_direction = default_containing_block_.direction;
+ NGBoxStrut inline_cb_borders = ComputeBordersForInline(*inline_cb_style);
bool is_same_direction =
container_direction == inline_cb_style->Direction();
@@ -403,13 +405,14 @@ void NGOutOfFlowLayoutPart::ComputeInlineContainingBlocks(
// Step 3 - determine the logical rectangle.
// Determine the logical size of the containing block.
- inline_cb_size = {end_offset.inline_offset - start_offset.inline_offset,
- end_offset.block_offset - start_offset.block_offset};
+ LogicalSize inline_cb_size = {
+ end_offset.inline_offset - start_offset.inline_offset,
+ end_offset.block_offset - start_offset.block_offset};
DCHECK_GE(inline_cb_size.inline_size, LayoutUnit());
DCHECK_GE(inline_cb_size.block_size, LayoutUnit());
// Set the container padding-box offset.
- container_offset = start_offset;
+ LogicalOffset container_offset = start_offset;
containing_blocks_map_.insert(
block_info.key,
@@ -525,12 +528,12 @@ scoped_refptr<const NGLayoutResult> NGOutOfFlowLayoutPart::LayoutCandidate(
// Since out-of-flow positioning sets up a constraint space with fixed
// inline-size, the regular layout code (|NGBlockNode::Layout()|) cannot
// re-layout if it discovers that a scrollbar was added or removed. Handle
- // that situation here. The assumption is that if preferred logical widths
- // are dirty after layout, AND its inline-size depends on preferred
+ // that situation here. The assumption is that if intrinsic logical widths
+ // are dirty after layout, AND its inline-size depends on the intrinsic
// logical widths, it means that scrollbars appeared or disappeared. We
// have the same logic in legacy layout in
// |LayoutBlockFlow::UpdateBlockLayout()|.
- if (node.GetLayoutBox()->PreferredLogicalWidthsDirty() &&
+ if (node.GetLayoutBox()->IntrinsicLogicalWidthsDirty() &&
AbsoluteNeedsChildInlineSize(candidate_style)) {
// Freeze the scrollbars for this layout pass. We don't want them to
// change *again*.
@@ -561,12 +564,12 @@ scoped_refptr<const NGLayoutResult> NGOutOfFlowLayoutPart::Layout(
LogicalSize container_content_size_in_candidate_writing_mode =
container_physical_content_size.ConvertToLogical(candidate_writing_mode);
NGBoxStrut border_padding =
- ComputeBorders(candidate_constraint_space, node) +
+ ComputeBorders(candidate_constraint_space, candidate_style) +
ComputePadding(candidate_constraint_space, candidate_style);
// The |block_estimate| is wrt. the candidate's writing mode.
base::Optional<LayoutUnit> block_estimate;
- base::Optional<MinMaxSize> min_max_size;
+ base::Optional<MinMaxSizes> min_max_sizes;
scoped_refptr<const NGLayoutResult> layout_result = nullptr;
// In order to calculate the offsets, we may need to know the size.
@@ -577,45 +580,61 @@ scoped_refptr<const NGLayoutResult> NGOutOfFlowLayoutPart::Layout(
// words, in that case, we may have to lay out, calculate the offset, and
// then lay out again at the correct block-offset.
+ NGLogicalOutOfFlowDimensions node_dimensions;
+ bool has_computed_block_dimensions = false;
bool is_replaced = node.IsReplaced();
bool should_be_considered_as_replaced = node.ShouldBeConsideredAsReplaced();
+ bool absolute_needs_child_block_size =
+ AbsoluteNeedsChildBlockSize(candidate_style);
if (AbsoluteNeedsChildInlineSize(candidate_style) ||
NeedMinMaxSize(candidate_style) || should_be_considered_as_replaced) {
- // This is a new formatting context, so whatever happened on the outside
- // doesn't concern us.
- MinMaxSizeInput input(container_content_size.block_size);
- min_max_size = ComputeMinAndMaxContentSizeForOutOfFlow(
- candidate_constraint_space, node, border_padding, input);
+ MinMaxSizesInput input(kIndefiniteSize);
+ if (is_replaced) {
+ input.percentage_resolution_block_size =
+ container_content_size_in_candidate_writing_mode.block_size;
+ } else if (!absolute_needs_child_block_size) {
+ // If we can determine our block-size ahead of time (it doesn't depend on
+ // our content), we use this for our %-block-size.
+ ComputeOutOfFlowBlockDimensions(
+ candidate_constraint_space, candidate_style, border_padding,
+ candidate_static_position, base::nullopt, base::nullopt,
+ writing_mode_, container_direction, &node_dimensions);
+ has_computed_block_dimensions = true;
+ input.percentage_resolution_block_size = node_dimensions.size.block_size;
+ }
+
+ min_max_sizes = node.ComputeMinMaxSizes(candidate_writing_mode, input,
+ &candidate_constraint_space);
}
base::Optional<LogicalSize> replaced_size;
base::Optional<LogicalSize> replaced_aspect_ratio;
bool is_replaced_with_only_aspect_ratio = false;
if (is_replaced) {
- ComputeReplacedSize(node, candidate_constraint_space, min_max_size,
+ 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();
// If we only have aspect ratio, and no replaced size, intrinsic size
- // defaults to 300x150. min_max_size gets computed from the intrinsic size.
- // We reset the min_max_size because spec says that OOF-positioned 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)
- min_max_size = MinMaxSize{LayoutUnit(), LayoutUnit::NearlyMax()};
+ min_max_sizes = MinMaxSizes{LayoutUnit(), LayoutUnit::NearlyMax()};
} else if (should_be_considered_as_replaced) {
replaced_size =
- LogicalSize{min_max_size->ShrinkToFit(
+ LogicalSize{min_max_sizes->ShrinkToFit(
candidate_constraint_space.AvailableSize().inline_size),
kIndefiniteSize};
}
- NGLogicalOutOfFlowPosition node_position =
- ComputePartialAbsoluteWithChildInlineSize(
- candidate_constraint_space, candidate_style, border_padding,
- candidate_static_position, min_max_size, replaced_size, writing_mode_,
- container_direction);
+
+ ComputeOutOfFlowInlineDimensions(candidate_constraint_space, candidate_style,
+ border_padding, candidate_static_position,
+ min_max_sizes, replaced_size, writing_mode_,
+ container_direction, &node_dimensions);
// |should_be_considered_as_replaced| sets the inline-size.
// It does not set the block-size. This is a compatibility quirk.
@@ -627,16 +646,20 @@ scoped_refptr<const NGLayoutResult> NGOutOfFlowLayoutPart::Layout(
// https://www.w3.org/TR/css-sizing-3/#intrinsic-sizes
if (is_replaced_with_only_aspect_ratio) {
replaced_size = LogicalSize(
- node_position.size.inline_size,
+ node_dimensions.size.inline_size,
(replaced_aspect_ratio->block_size *
- ((node_position.size.inline_size - border_padding.InlineSum()) /
+ ((node_dimensions.size.inline_size - border_padding.InlineSum()) /
replaced_aspect_ratio->inline_size)) +
border_padding.BlockSum());
}
- if (AbsoluteNeedsChildBlockSize(candidate_style)) {
+ if (absolute_needs_child_block_size) {
+ DCHECK(!has_computed_block_dimensions);
layout_result =
GenerateFragment(node, container_content_size_in_candidate_writing_mode,
- block_estimate, node_position);
+ block_estimate, node_dimensions);
+
+ // TODO(layout-dev): Handle abortions caused by block fragmentation.
+ DCHECK(layout_result->Status() != NGLayoutResult::kOutOfFragmentainerSpace);
NGFragment fragment(candidate_writing_mode,
layout_result->PhysicalFragment());
@@ -644,15 +667,18 @@ scoped_refptr<const NGLayoutResult> NGOutOfFlowLayoutPart::Layout(
block_estimate = fragment.BlockSize();
}
- // Calculate the offsets.
-
- ComputeFullAbsoluteWithChildBlockSize(
- candidate_constraint_space, candidate_style, border_padding,
- candidate_static_position, block_estimate, replaced_size, writing_mode_,
- container_direction, &node_position);
+ // We may have already pre-computed our block-dimensions when determining our
+ // |min_max_sizes|, only run if needed.
+ if (!has_computed_block_dimensions) {
+ ComputeOutOfFlowBlockDimensions(
+ candidate_constraint_space, candidate_style, border_padding,
+ candidate_static_position, block_estimate, replaced_size, writing_mode_,
+ container_direction, &node_dimensions);
+ }
+ // Calculate the offsets.
NGBoxStrut inset =
- node_position.inset
+ node_dimensions.inset
.ConvertToPhysical(candidate_writing_mode, candidate_direction)
.ConvertToLogical(writing_mode_, default_direction);
@@ -719,12 +745,15 @@ scoped_refptr<const NGLayoutResult> NGOutOfFlowLayoutPart::Layout(
// Skip this step if we produced a fragment when estimating the block-size.
if (!layout_result) {
- block_estimate = node_position.size.block_size;
+ block_estimate = node_dimensions.size.block_size;
layout_result =
GenerateFragment(node, container_content_size_in_candidate_writing_mode,
- block_estimate, node_position);
+ block_estimate, node_dimensions);
}
+ // TODO(layout-dev): Handle abortions caused by block fragmentation.
+ DCHECK_EQ(layout_result->Status(), NGLayoutResult::kSuccess);
+
// TODO(mstensho): Move the rest of this method back into LayoutCandidate().
if (node.GetLayoutBox()->IsLayoutNGObject()) {
@@ -736,7 +765,7 @@ scoped_refptr<const NGLayoutResult> NGOutOfFlowLayoutPart::Layout(
if (!container_builder_->GetLayoutObject()
->Style()
->IsDisplayFlexibleOrGridBox()) {
- node.GetLayoutBox()->SetMargin(node_position.margins.ConvertToPhysical(
+ node.GetLayoutBox()->SetMargin(node_dimensions.margins.ConvertToPhysical(
candidate_writing_mode, candidate_direction));
}
@@ -785,12 +814,12 @@ scoped_refptr<const NGLayoutResult> NGOutOfFlowLayoutPart::GenerateFragment(
NGBlockNode node,
const LogicalSize& container_content_size_in_candidate_writing_mode,
const base::Optional<LayoutUnit>& block_estimate,
- const NGLogicalOutOfFlowPosition& node_position) {
+ const NGLogicalOutOfFlowDimensions& node_dimensions) {
// As the |block_estimate| is always in the node's writing mode, we build the
// constraint space in the node's writing mode.
WritingMode writing_mode = node.Style().GetWritingMode();
- LayoutUnit inline_size = node_position.size.inline_size;
+ LayoutUnit inline_size = node_dimensions.size.inline_size;
LayoutUnit block_size = block_estimate.value_or(
container_content_size_in_candidate_writing_mode.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 e8d9ad81dbd..777309f62ef 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
@@ -122,7 +122,7 @@ class CORE_EXPORT NGOutOfFlowLayoutPart {
NGBlockNode node,
const LogicalSize& container_content_size_in_child_writing_mode,
const base::Optional<LayoutUnit>& block_estimate,
- const NGLogicalOutOfFlowPosition& node_position);
+ const NGLogicalOutOfFlowDimensions& node_dimensions);
const NGConstraintSpace& container_space_;
NGBoxFragmentBuilder* container_builder_;
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 1037e23bca2..3f9a5127140 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
@@ -54,14 +54,17 @@ struct NGLogicalOutOfFlowPositionedNode {
NGLogicalStaticPosition static_position;
// Continuation root of the optional inline container.
const LayoutInline* inline_container;
+ bool needs_block_offset_adjustment;
NGLogicalOutOfFlowPositionedNode(
NGBlockNode node,
NGLogicalStaticPosition static_position,
- const LayoutInline* inline_container = nullptr)
+ const LayoutInline* inline_container = nullptr,
+ bool needs_block_offset_adjustment = false)
: node(node),
static_position(static_position),
- inline_container(inline_container) {
+ inline_container(inline_container),
+ needs_block_offset_adjustment(needs_block_offset_adjustment) {
DCHECK(!inline_container ||
inline_container == inline_container->ContinuationRoot());
}
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_outline_utils.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_outline_utils.cc
index dece4940984..805794074b6 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_outline_utils.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_outline_utils.cc
@@ -46,7 +46,7 @@ bool NGOutlineUtils::ShouldPaintOutline(
NGInlineCursor cursor;
cursor.MoveTo(*layout_object);
DCHECK(cursor);
- return cursor.CurrentBoxFragment() == &physical_fragment;
+ return cursor.Current().BoxFragment() == &physical_fragment;
}
} // namespace blink
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 21ab11cf7b5..5328304e619 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
@@ -5,7 +5,6 @@
#include "third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.h"
#include <algorithm>
-#include "third_party/blink/renderer/core/layout/ng/inline/ng_baseline.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h"
#include "third_party/blink/renderer/core/layout/ng/ng_box_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h"
@@ -81,13 +80,13 @@ scoped_refptr<const NGLayoutResult> NGPageLayoutAlgorithm::Layout() {
return container_builder_.ToBoxFragment();
}
-base::Optional<MinMaxSize> NGPageLayoutAlgorithm::ComputeMinMaxSize(
- const MinMaxSizeInput& input) const {
+base::Optional<MinMaxSizes> NGPageLayoutAlgorithm::ComputeMinMaxSizes(
+ const MinMaxSizesInput& input) const {
NGFragmentGeometry fragment_geometry =
CalculateInitialMinMaxFragmentGeometry(ConstraintSpace(), Node());
NGBlockLayoutAlgorithm algorithm(
{Node(), fragment_geometry, ConstraintSpace()});
- return algorithm.ComputeMinMaxSize(input);
+ return algorithm.ComputeMinMaxSizes(input);
}
NGConstraintSpace NGPageLayoutAlgorithm::CreateConstraintSpaceForPages(
@@ -97,9 +96,6 @@ NGConstraintSpace NGPageLayoutAlgorithm::CreateConstraintSpaceForPages(
space_builder.SetAvailableSize(page_size);
space_builder.SetPercentageResolutionSize(page_size);
- if (NGBaseline::ShouldPropagateBaselines(Node()))
- space_builder.AddBaselineRequests(ConstraintSpace().BaselineRequests());
-
// TODO(mstensho): Handle auto block size.
space_builder.SetFragmentationType(kFragmentPage);
space_builder.SetFragmentainerBlockSize(page_size.block_size);
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 f05b8a8d717..8797b3ba1ac 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
@@ -25,8 +25,8 @@ class CORE_EXPORT NGPageLayoutAlgorithm
scoped_refptr<const NGLayoutResult> Layout() override;
- base::Optional<MinMaxSize> ComputeMinMaxSize(
- const MinMaxSizeInput&) const override;
+ base::Optional<MinMaxSizes> ComputeMinMaxSizes(
+ const MinMaxSizesInput&) const override;
private:
NGConstraintSpace CreateConstraintSpaceForPages(
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 d550eea7cd0..2092c9bbe84 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
@@ -10,6 +10,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/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_inline_fragment_traversal.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_line_box_fragment.h"
@@ -22,7 +23,8 @@ namespace blink {
namespace {
struct SameSizeAsNGPhysicalBoxFragment : NGPhysicalContainerFragment {
- NGBaselineList baselines;
+ LayoutUnit baseline;
+ LayoutUnit last_baseline;
NGLink children[];
};
@@ -63,25 +65,23 @@ 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(builder, borders, padding,
+ new (data) NGPhysicalBoxFragment(PassKey(), builder, borders, padding,
block_or_line_writing_mode);
return base::AdoptRef(static_cast<NGPhysicalBoxFragment*>(data));
}
NGPhysicalBoxFragment::NGPhysicalBoxFragment(
+ PassKey key,
NGBoxFragmentBuilder* builder,
const NGPhysicalBoxStrut& borders,
const NGPhysicalBoxStrut& padding,
WritingMode block_or_line_writing_mode)
- : NGPhysicalContainerFragment(
- builder,
- block_or_line_writing_mode,
- children_,
- (builder->node_ && builder->node_.IsRenderedLegend())
- ? kFragmentRenderedLegend
- : kFragmentBox,
- builder->BoxType()),
- baselines_(builder->baselines_) {
+ : NGPhysicalContainerFragment(builder,
+ block_or_line_writing_mode,
+ children_,
+ kFragmentBox,
+ builder->BoxType()) {
+ DCHECK(layout_object_);
DCHECK(layout_object_->IsBoxModelObject());
if (NGFragmentItemsBuilder* items_builder = builder->ItemsBuilder()) {
has_fragment_items_ = true;
@@ -98,15 +98,34 @@ NGPhysicalBoxFragment::NGPhysicalBoxFragment(
has_padding_ = !padding.IsZero();
if (has_padding_)
*const_cast<NGPhysicalBoxStrut*>(ComputePaddingAddress()) = padding;
- // consumed_block_size_ is only updated if we're in block
- // fragmentation. Otherwise it will always be 0.
- is_first_for_node_ =
- builder->consumed_block_size_ <= builder->size_.block_size;
+ 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_;
+ is_painted_atomically_ =
+ builder->space_ && builder->space_->IsPaintedAtomically();
border_edge_ = builder->border_edges_.ToPhysical(builder->GetWritingMode());
- children_inline_ =
- builder->layout_object_ && builder->layout_object_->ChildrenInline();
+ is_inline_formatting_context_ = builder->is_inline_formatting_context_;
+ is_generated_text_or_math_fraction_ = builder->is_math_fraction_;
+
+ bool has_layout_containment = layout_object_->ShouldApplyLayoutContainment();
+ if (builder->baseline_.has_value() && !has_layout_containment) {
+ has_baseline_ = true;
+ baseline_ = *builder->baseline_;
+ } else {
+ has_baseline_ = false;
+ baseline_ = LayoutUnit::Min();
+ }
+ if (builder->last_baseline_.has_value() && !has_layout_containment) {
+ has_last_baseline_ = true;
+ last_baseline_ = *builder->last_baseline_;
+ } else {
+ has_last_baseline_ = false;
+ last_baseline_ = LayoutUnit::Min();
+ }
+
+#if DCHECK_IS_ON()
+ CheckIntegrity();
+#endif
}
scoped_refptr<const NGLayoutResult>
@@ -153,7 +172,7 @@ PhysicalRect NGPhysicalBoxFragment::ScrollableOverflow() const {
TextDirection container_direction = Style().Direction();
for (const auto& child_fragment : Children()) {
PhysicalRect child_overflow =
- child_fragment->ScrollableOverflowForPropagation(layout_object);
+ child_fragment->ScrollableOverflowForPropagation(*this);
if (child_fragment->Style() != Style()) {
PhysicalOffset relative_offset = ComputeRelativeOffset(
child_fragment->Style(), container_writing_mode,
@@ -170,6 +189,157 @@ PhysicalRect NGPhysicalBoxFragment::ScrollableOverflow() const {
return PhysicalRect({}, Size());
}
+PhysicalRect NGPhysicalBoxFragment::ScrollableOverflowFromChildren() const {
+ const NGFragmentItems* items = Items();
+ if (Children().empty() && !items)
+ return PhysicalRect();
+
+ // Internal struct to share logic between child fragments and child items.
+ // - Inline children's overflow expands by padding end/after.
+ // - Float / OOF overflow is added as is.
+ // - Children not reachable by scroll overflow do not contribute to it.
+ struct ComputeOverflowContext {
+ ComputeOverflowContext(const NGPhysicalBoxFragment& container)
+ : container(container),
+ style(container.Style()),
+ writing_mode(style.GetWritingMode()),
+ direction(style.Direction()),
+ border_inline_start(LayoutUnit(style.BorderStartWidth())),
+ border_block_start(LayoutUnit(style.BorderBeforeWidth())) {
+ DCHECK_EQ(&style, container.GetLayoutObject()->Style(
+ container.UsesFirstLineStyle()));
+
+ // End and under padding are added to scroll overflow of inline children.
+ // https://github.com/w3c/csswg-drafts/issues/129
+ DCHECK_EQ(container.HasOverflowClip(),
+ container.GetLayoutObject()->HasOverflowClip());
+ if (container.HasOverflowClip()) {
+ const LayoutBox* layout_object =
+ ToLayoutBox(container.GetLayoutObject());
+ padding_strut = NGBoxStrut(LayoutUnit(), layout_object->PaddingEnd(),
+ LayoutUnit(), layout_object->PaddingAfter())
+ .ConvertToPhysical(writing_mode, direction);
+ }
+ }
+
+ // Rectangles not reachable by scroll should not be added to overflow.
+ bool IsRectReachableByScroll(const PhysicalRect& rect) {
+ LogicalOffset rect_logical_end =
+ rect.offset.ConvertToLogical(writing_mode, direction,
+ container.Size(), rect.size) +
+ rect.size.ConvertToLogical(writing_mode);
+ return rect_logical_end.inline_offset > border_inline_start &&
+ rect_logical_end.block_offset > border_block_start;
+ }
+
+ void AddChild(const PhysicalRect& child_scrollable_overflow) {
+ // Do not add overflow if fragment is not reachable by scrolling.
+ if (IsRectReachableByScroll(child_scrollable_overflow))
+ children_overflow.Unite(child_scrollable_overflow);
+ }
+
+ void AddFloatingOrOutOfFlowPositionedChild(
+ const NGPhysicalFragment& child,
+ const PhysicalOffset& child_offset) {
+ DCHECK(child.IsFloatingOrOutOfFlowPositioned());
+ PhysicalRect child_scrollable_overflow =
+ child.ScrollableOverflowForPropagation(container);
+ child_scrollable_overflow.offset += ComputeRelativeOffset(
+ child.Style(), writing_mode, direction, container.Size());
+ child_scrollable_overflow.offset += child_offset;
+ AddChild(child_scrollable_overflow);
+ }
+
+ void AddLineBoxChild(const NGPhysicalLineBoxFragment& child,
+ const PhysicalOffset& child_offset) {
+ if (padding_strut)
+ AddLineBoxRect({child_offset, child.Size()});
+ PhysicalRect child_scrollable_overflow =
+ child.ScrollableOverflow(container, style);
+ child_scrollable_overflow.offset += child_offset;
+ AddChild(child_scrollable_overflow);
+ }
+
+ void AddLineBoxChild(const NGFragmentItem& child,
+ const NGInlineCursor& cursor) {
+ DCHECK_EQ(&child, cursor.CurrentItem());
+ DCHECK_EQ(child.Type(), NGFragmentItem::kLine);
+ if (padding_strut)
+ AddLineBoxRect(child.RectInContainerBlock());
+ const NGPhysicalLineBoxFragment* line_box = child.LineBoxFragment();
+ DCHECK(line_box);
+ PhysicalRect child_scrollable_overflow =
+ line_box->ScrollableOverflowForLine(container, style, child, cursor);
+ AddChild(child_scrollable_overflow);
+ }
+
+ void AddLineBoxRect(const PhysicalRect& linebox_rect) {
+ DCHECK(padding_strut);
+ if (lineboxes_enclosing_rect)
+ lineboxes_enclosing_rect->Unite(linebox_rect);
+ else
+ lineboxes_enclosing_rect = linebox_rect;
+ }
+
+ void AddPaddingToLineBoxChildren() {
+ if (lineboxes_enclosing_rect) {
+ DCHECK(padding_strut);
+ lineboxes_enclosing_rect->Expand(*padding_strut);
+ AddChild(*lineboxes_enclosing_rect);
+ }
+ }
+
+ const NGPhysicalBoxFragment& container;
+ const ComputedStyle& style;
+ const WritingMode writing_mode;
+ const TextDirection direction;
+ const LayoutUnit border_inline_start;
+ const LayoutUnit border_block_start;
+ base::Optional<NGPhysicalBoxStrut> padding_strut;
+ base::Optional<PhysicalRect> lineboxes_enclosing_rect;
+ PhysicalRect children_overflow;
+ } context(*this);
+
+ // Traverse child items.
+ if (items) {
+ for (NGInlineCursor cursor(*items); cursor; cursor.MoveToNextSibling()) {
+ const NGFragmentItem* item = cursor.CurrentItem();
+ if (item->Type() == NGFragmentItem::kLine) {
+ context.AddLineBoxChild(*item, cursor);
+ continue;
+ }
+
+ if (const NGPhysicalBoxFragment* child_box = item->BoxFragment()) {
+ if (child_box->IsFloatingOrOutOfFlowPositioned()) {
+ context.AddFloatingOrOutOfFlowPositionedChild(
+ *child_box, item->OffsetInContainerBlock());
+ }
+ }
+ }
+ }
+
+ // Traverse child fragments.
+ const bool children_inline = IsInlineFormattingContext();
+ // Only add overflow for fragments NG has not reflected into Legacy.
+ // These fragments are:
+ // - inline fragments,
+ // - out of flow fragments whose css container is inline box.
+ // TODO(layout-dev) Transforms also need to be applied to compute overflow
+ // correctly. NG is not yet transform-aware. crbug.com/855965
+ for (const auto& child : Children()) {
+ if (child->IsFloatingOrOutOfFlowPositioned()) {
+ context.AddFloatingOrOutOfFlowPositionedChild(*child, child.Offset());
+ } else if (children_inline && child->IsLineBox()) {
+ context.AddLineBoxChild(To<NGPhysicalLineBoxFragment>(*child),
+ child.Offset());
+ }
+ }
+
+ context.AddPaddingToLineBoxChildren();
+
+ return context.children_overflow;
+}
+
LayoutSize NGPhysicalBoxFragment::PixelSnappedScrolledContentOffset() const {
DCHECK(GetLayoutObject() && GetLayoutObject()->IsBox());
const LayoutBox* box = ToLayoutBox(GetLayoutObject());
@@ -318,9 +488,10 @@ void NGPhysicalBoxFragment::CheckSameForSimplifiedLayout(
DCHECK_EQ(depends_on_percentage_block_size_,
other.depends_on_percentage_block_size_);
- DCHECK_EQ(children_inline_, other.children_inline_);
+ DCHECK_EQ(is_inline_formatting_context_, other.is_inline_formatting_context_);
DCHECK_EQ(is_fieldset_container_, other.is_fieldset_container_);
DCHECK_EQ(is_legacy_layout_root_, other.is_legacy_layout_root_);
+ DCHECK_EQ(is_painted_atomically_, other.is_painted_atomically_);
DCHECK_EQ(border_edge_, other.border_edge_);
// The oof_positioned_descendants_ vector can change during "simplified"
@@ -329,10 +500,63 @@ void NGPhysicalBoxFragment::CheckSameForSimplifiedLayout(
// Legacy layout can (incorrectly) shift baseline position(s) during
// "simplified" layout.
- DCHECK(IsLegacyLayoutRoot() || baselines_ == other.baselines_);
+ DCHECK(IsLegacyLayoutRoot() || Baseline() == other.Baseline());
+ DCHECK(IsLegacyLayoutRoot() || LastBaseline() == other.LastBaseline());
DCHECK(Borders() == other.Borders());
DCHECK(Padding() == other.Padding());
}
+
+// Check our flags represent the actual children correctly.
+void NGPhysicalBoxFragment::CheckIntegrity() const {
+ bool has_inflow_blocks = false;
+ bool has_inlines = false;
+ bool has_line_boxes = false;
+ bool has_floats = false;
+ bool has_list_markers = false;
+
+ for (const NGLink& child : Children()) {
+ if (child->IsFloating())
+ has_floats = true;
+ else if (child->IsOutOfFlowPositioned())
+ ; // OOF can be in the fragment tree regardless of |HasItems|.
+ else if (child->IsLineBox())
+ has_line_boxes = true;
+ else if (child->IsListMarker())
+ has_list_markers = true;
+ else if (child->IsInline())
+ has_inlines = true;
+ else
+ has_inflow_blocks = true;
+ }
+
+ // If we have line boxes, |IsInlineFormattingContext()| is true, but the
+ // reverse is not always true.
+ if (has_line_boxes || has_inlines)
+ DCHECK(IsInlineFormattingContext());
+
+ // If display-locked, we may not have any children.
+ DCHECK(layout_object_);
+ if (layout_object_ && layout_object_->PaintBlockedByDisplayLock(
+ DisplayLockLifecycleTarget::kChildren))
+ return;
+
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ if (RuntimeEnabledFeatures::LayoutNGBlockFragmentationEnabled()) {
+ if (has_line_boxes)
+ DCHECK(HasItems());
+ } else {
+ DCHECK_EQ(HasItems(), has_line_boxes);
+ }
+
+ if (has_line_boxes) {
+ DCHECK(!has_inlines);
+ DCHECK(!has_inflow_blocks);
+ // Following objects should be in the items, not in the tree.
+ DCHECK(!has_floats);
+ DCHECK(!has_list_markers);
+ }
+ }
+}
#endif
} // namespace blink
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 5fdc31c023e..21527728c01 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
@@ -7,7 +7,6 @@
#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_baseline.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.h"
#include "third_party/blink/renderer/platform/graphics/scroll_types.h"
@@ -25,6 +24,13 @@ class CORE_EXPORT NGPhysicalBoxFragment final
NGBoxFragmentBuilder* builder,
WritingMode block_or_line_writing_mode);
+ using PassKey = util::PassKey<NGPhysicalBoxFragment>;
+ NGPhysicalBoxFragment(PassKey,
+ NGBoxFragmentBuilder* builder,
+ const NGPhysicalBoxStrut& borders,
+ const NGPhysicalBoxStrut& padding,
+ WritingMode block_or_line_writing_mode);
+
scoped_refptr<const NGLayoutResult> CloneAsHiddenForPaint() const;
~NGPhysicalBoxFragment() {
@@ -40,8 +46,16 @@ class CORE_EXPORT NGPhysicalBoxFragment final
return has_fragment_items_ ? ComputeItemsAddress() : nullptr;
}
- base::Optional<LayoutUnit> Baseline(const NGBaselineRequest& request) const {
- return baselines_.Offset(request);
+ base::Optional<LayoutUnit> Baseline() const {
+ if (has_baseline_)
+ return baseline_;
+ return base::nullopt;
+ }
+
+ base::Optional<LayoutUnit> LastBaseline() const {
+ if (has_last_baseline_)
+ return last_baseline_;
+ return base::nullopt;
}
const NGPhysicalBoxStrut Borders() const {
@@ -63,9 +77,40 @@ class CORE_EXPORT NGPhysicalBoxFragment final
}
bool HasSelfPaintingLayer() const;
- bool ChildrenInline() const { return children_inline_; }
+
+ // Return true if this is either a container that establishes an inline
+ // formatting context, or if it's non-atomic inline content participating in
+ // one. Empty blocks don't establish an inline formatting context.
+ //
+ // The return value from this method is undefined and irrelevant if the object
+ // establishes a different type of formatting context than block/inline, such
+ // as table or flexbox.
+ //
+ // Example:
+ // <div> <!-- false -->
+ // <div> <!-- true -->
+ // <div style="float:left;"></div> <!-- false -->
+ // <div style="float:left;"> <!-- true -->
+ // xxx <!-- true -->
+ // </div>
+ // <div style="float:left;"> <!-- false -->
+ // <div style="float:left;"></div> <!-- false -->
+ // </div>
+ // <span> <!-- true -->
+ // xxx <!-- true -->
+ // <span style="display:inline-block;"> <!-- false -->
+ // <div></div> <!-- false -->
+ // </span>
+ // <span style="display:inline-block;"> <!-- true -->
+ // xxx <!-- true -->
+ // </span>
+ // <span style="display:inline-flex;"> <!-- N/A -->
+ bool IsInlineFormattingContext() const {
+ return is_inline_formatting_context_;
+ }
PhysicalRect ScrollableOverflow() const;
+ PhysicalRect ScrollableOverflowFromChildren() const;
// TODO(layout-dev): These three methods delegate to legacy layout for now,
// update them to use LayoutNG based overflow information from the fragment
@@ -79,6 +124,14 @@ class CORE_EXPORT NGPhysicalBoxFragment final
// Compute visual overflow of this box in the local coordinate.
PhysicalRect ComputeSelfInkOverflow() const;
+ // Contents ink overflow includes anything that would bleed out of the box and
+ // would be clipped by the overflow clip ('overflow' != visible). This
+ // corresponds to children that overflows their parent.
+ PhysicalRect ContentsInkOverflow() const {
+ // TODO(layout-dev): Implement box fragment overflow.
+ return LocalRect();
+ }
+
// Fragment offset is this fragment's offset from parent.
// Needed to compensate for LayoutInline Legacy code offsets.
void AddSelfOutlineRects(const PhysicalOffset& additional_offset,
@@ -91,20 +144,12 @@ class CORE_EXPORT NGPhysicalBoxFragment final
unsigned BorderEdges() const { return border_edge_; }
NGPixelSnappedPhysicalBoxStrut BorderWidths() const;
- // Return true if this is the first fragment generated from a node.
- bool IsFirstForNode() const { return is_first_for_node_; }
-
#if DCHECK_IS_ON()
void CheckSameForSimplifiedLayout(const NGPhysicalBoxFragment&,
bool check_same_block_size) const;
#endif
private:
- NGPhysicalBoxFragment(NGBoxFragmentBuilder* builder,
- const NGPhysicalBoxStrut& borders,
- const NGPhysicalBoxStrut& padding,
- WritingMode block_or_line_writing_mode);
-
const NGFragmentItems* ComputeItemsAddress() const {
DCHECK(has_fragment_items_ || has_borders_ || has_padding_);
const NGLink* children_end = children_ + Children().size();
@@ -125,7 +170,12 @@ class CORE_EXPORT NGPhysicalBoxFragment final
return has_borders_ ? address + 1 : address;
}
- NGBaselineList baselines_;
+#if DCHECK_IS_ON()
+ void CheckIntegrity() const;
+#endif
+
+ LayoutUnit baseline_;
+ LayoutUnit last_baseline_;
NGLink children_[];
// borders and padding come from after |children_| if they are not zero.
};
@@ -133,8 +183,7 @@ class CORE_EXPORT NGPhysicalBoxFragment final
template <>
struct DowncastTraits<NGPhysicalBoxFragment> {
static bool AllowFrom(const NGPhysicalFragment& fragment) {
- return fragment.Type() == NGPhysicalFragment::kFragmentBox ||
- fragment.Type() == NGPhysicalFragment::kFragmentRenderedLegend;
+ return fragment.Type() == NGPhysicalFragment::kFragmentBox;
}
};
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment_test.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment_test.cc
index 327d158404a..78373f21bb6 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment_test.cc
@@ -122,7 +122,7 @@ TEST_F(NGPhysicalBoxFragmentTest, DISABLED_NormalLegacyLayoutRoot) {
EXPECT_TRUE(fragment->IsBox());
EXPECT_EQ(NGPhysicalFragment::kNormalBox, fragment->BoxType());
EXPECT_TRUE(fragment->IsLegacyLayoutRoot());
- EXPECT_TRUE(fragment->IsBlockFormattingContextRoot());
+ EXPECT_TRUE(fragment->IsFormattingContextRoot());
}
// TODO(editing-dev): Once LayoutNG supports editing, we should change this
@@ -136,7 +136,7 @@ TEST_F(NGPhysicalBoxFragmentTest, DISABLED_FloatLegacyLayoutRoot) {
EXPECT_TRUE(fragment->IsBox());
EXPECT_EQ(NGPhysicalFragment::kFloating, fragment->BoxType());
EXPECT_TRUE(fragment->IsLegacyLayoutRoot());
- EXPECT_TRUE(fragment->IsBlockFormattingContextRoot());
+ EXPECT_TRUE(fragment->IsFormattingContextRoot());
}
// TODO(editing-dev): Once LayoutNG supports editing, we should change this
@@ -152,7 +152,7 @@ TEST_F(NGPhysicalBoxFragmentTest, DISABLED_InlineBlockLegacyLayoutRoot) {
EXPECT_TRUE(fragment->IsBox());
EXPECT_EQ(NGPhysicalFragment::kAtomicInline, fragment->BoxType());
EXPECT_TRUE(fragment->IsLegacyLayoutRoot());
- EXPECT_TRUE(fragment->IsBlockFormattingContextRoot());
+ EXPECT_TRUE(fragment->IsFormattingContextRoot());
}
// TODO(editing-dev): Once LayoutNG supports editing, we should change this
@@ -170,7 +170,7 @@ TEST_F(NGPhysicalBoxFragmentTest,
EXPECT_TRUE(fragment->IsBox());
EXPECT_EQ(NGPhysicalFragment::kOutOfFlowPositioned, fragment->BoxType());
EXPECT_TRUE(fragment->IsLegacyLayoutRoot());
- EXPECT_TRUE(fragment->IsBlockFormattingContextRoot());
+ EXPECT_TRUE(fragment->IsFormattingContextRoot());
}
TEST_F(NGPhysicalBoxFragmentTest, ReplacedBlock) {
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 6e7ac12f47b..82f57612ce4 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
@@ -6,10 +6,12 @@
#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"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_outline_utils.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_relative_utils.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
namespace blink {
@@ -88,6 +90,40 @@ void NGPhysicalContainerFragment::AddOutlineRectsForNormalChildren(
const PhysicalOffset& additional_offset,
NGOutlineType outline_type,
const LayoutBoxModelObject* containing_block) const {
+ if (const auto* box = DynamicTo<NGPhysicalBoxFragment>(this)) {
+ if (const NGFragmentItems* items = box->Items()) {
+ for (NGInlineCursor cursor(*items); cursor; cursor.MoveToNext()) {
+ DCHECK(cursor.Current().Item());
+ const NGFragmentItem& item = *cursor.Current().Item();
+ if (item.Type() == NGFragmentItem::kLine) {
+ AddOutlineRectsForDescendant(
+ {item.LineBoxFragment(), item.OffsetInContainerBlock()},
+ outline_rects, additional_offset, outline_type, containing_block);
+ continue;
+ }
+ if (item.Type() == NGFragmentItem::kBox) {
+ if (const NGPhysicalBoxFragment* child_box = item.BoxFragment()) {
+ DCHECK(!child_box->IsOutOfFlowPositioned());
+ AddOutlineRectsForDescendant(
+ {child_box, item.OffsetInContainerBlock()}, outline_rects,
+ additional_offset, outline_type, containing_block);
+ }
+ continue;
+ }
+ DCHECK(item.IsText());
+ }
+ // Don't add |Children()|. If |this| has |NGFragmentItems|, children are
+ // either line box, which we already handled in items, or OOF, which we
+ // should ignore.
+ DCHECK(std::all_of(PostLayoutChildren().begin(),
+ PostLayoutChildren().end(), [](const NGLink& child) {
+ return child->IsLineBox() ||
+ child->IsOutOfFlowPositioned();
+ }));
+ return;
+ }
+ }
+
for (const auto& child : PostLayoutChildren()) {
// Outlines of out-of-flow positioned descendants are handled in
// NGPhysicalBoxFragment::AddSelfOutlineRects().
@@ -111,6 +147,84 @@ void NGPhysicalContainerFragment::AddOutlineRectsForNormalChildren(
}
}
+void NGPhysicalContainerFragment::AddScrollableOverflowForInlineChild(
+ const NGPhysicalBoxFragment& container,
+ const ComputedStyle& container_style,
+ const NGFragmentItem& line,
+ bool has_hanging,
+ const NGInlineCursor& cursor,
+ PhysicalRect* overflow) const {
+ DCHECK(RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
+ DCHECK(IsLineBox() || IsInlineBox());
+ DCHECK(cursor.Current().Item() &&
+ (cursor.Current().Item()->BoxFragment() == this ||
+ cursor.Current().Item()->LineBoxFragment() == this));
+ const WritingMode container_writing_mode = container_style.GetWritingMode();
+ const TextDirection container_direction = container_style.Direction();
+ for (NGInlineCursor descendants = cursor.CursorForDescendants();
+ descendants;) {
+ const NGFragmentItem* item = descendants.CurrentItem();
+ DCHECK(item);
+ if (item->IsText()) {
+ PhysicalRect child_scroll_overflow = item->RectInContainerBlock();
+ if (UNLIKELY(has_hanging)) {
+ AdjustScrollableOverflowForHanging(line.RectInContainerBlock(),
+ container_writing_mode,
+ &child_scroll_overflow);
+ }
+ overflow->Unite(child_scroll_overflow);
+ descendants.MoveToNextSkippingChildren();
+ continue;
+ }
+
+ if (const NGPhysicalBoxFragment* child_box = item->BoxFragment()) {
+ PhysicalRect child_scroll_overflow = item->RectInContainerBlock();
+ if (child_box->IsInlineBox()) {
+ child_box->AddScrollableOverflowForInlineChild(
+ container, container_style, line, has_hanging, descendants,
+ &child_scroll_overflow);
+ child_box->AdjustScrollableOverflowForPropagation(
+ container, &child_scroll_overflow);
+ } else {
+ child_scroll_overflow =
+ child_box->ScrollableOverflowForPropagation(container);
+ child_scroll_overflow.offset += item->OffsetInContainerBlock();
+ }
+ child_scroll_overflow.offset +=
+ ComputeRelativeOffset(child_box->Style(), container_writing_mode,
+ container_direction, container.Size());
+ overflow->Unite(child_scroll_overflow);
+ descendants.MoveToNextSkippingChildren();
+ continue;
+ }
+
+ // Add all children of a culled inline box; i.e., an inline box without
+ // margin/border/padding etc.
+ DCHECK_EQ(item->Type(), NGFragmentItem::kBox);
+ descendants.MoveToNext();
+ }
+}
+
+// Chop the hanging part from scrollable overflow. Children overflow in inline
+// direction should hang, which should not cause scroll.
+// TODO(kojii): Should move to text fragment to make this more accurate.
+void NGPhysicalContainerFragment::AdjustScrollableOverflowForHanging(
+ const PhysicalRect& rect,
+ const WritingMode container_writing_mode,
+ PhysicalRect* overflow) {
+ if (IsHorizontalWritingMode(container_writing_mode)) {
+ if (overflow->offset.left < rect.offset.left)
+ overflow->offset.left = rect.offset.left;
+ if (overflow->Right() > rect.Right())
+ overflow->ShiftRightEdgeTo(rect.Right());
+ } else {
+ if (overflow->offset.top < rect.offset.top)
+ overflow->offset.top = rect.offset.top;
+ if (overflow->Bottom() > rect.Bottom())
+ overflow->ShiftBottomEdgeTo(rect.Bottom());
+ }
+}
+
// additional_offset must be offset from the containing_block because
// LocalToAncestorRect returns rects wrt containing_block.
void NGPhysicalContainerFragment::AddOutlineRectsForDescendant(
@@ -212,16 +326,23 @@ bool NGPhysicalContainerFragment::DependsOnPercentageBlockSize(
// element if it has a percentage block-size however, but this will return
// the correct result from below.
+ // There are two conditions where we need to know about an (arbitrary)
+ // descendant which depends on a %-block-size.
+ // - In quirks mode, the arbitrary descendant may depend the percentage
+ // resolution block-size given (to this node), and need to relayout if
+ // this size changes.
+ // - A flex-item may have its "definiteness" change, (e.g. if itself is a
+ // flex item which is being stretched). This definiteness change will
+ // affect any %-block-size children.
+ //
+ // NOTE(ikilpatrick): For the flex-item case this is potentially too general.
+ // We only need to know about if this flex-item has a %-block-size child if
+ // the "definiteness" changes, not if the percentage resolution size changes.
if ((builder.has_descendant_that_depends_on_percentage_block_size_ ||
builder.is_legacy_layout_root_) &&
- node.UseParentPercentageResolutionBlockSizeForChildren()) {
- // Quirks mode has different %-block-size behaviour, than standards mode.
- // An arbitrary descendant may depend on the percentage resolution
- // block-size given.
- // If this is also an anonymous block we need to mark ourselves dependent
- // if we have a dependent child.
+ (node.UseParentPercentageResolutionBlockSizeForChildren() ||
+ node.IsFlexItem()))
return true;
- }
const ComputedStyle& style = builder.Style();
if (style.LogicalHeight().IsPercentOrCalc() ||
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 4cf2b93116b..b3c7624f494 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
@@ -17,6 +17,7 @@
namespace blink {
class NGContainerFragmentBuilder;
+class NGFragmentItem;
struct NGPhysicalOutOfFlowPositionedNode;
enum class NGOutlineType;
@@ -149,6 +150,19 @@ class CORE_EXPORT NGPhysicalContainerFragment : public NGPhysicalFragment {
NGFragmentType,
unsigned sub_type);
+ void AddScrollableOverflowForInlineChild(
+ const NGPhysicalBoxFragment& container,
+ const ComputedStyle& container_style,
+ const NGFragmentItem& line,
+ bool has_hanging,
+ const NGInlineCursor& cursor,
+ PhysicalRect* overflow) const;
+
+ static void AdjustScrollableOverflowForHanging(
+ const PhysicalRect& rect,
+ const WritingMode container_writing_mode,
+ PhysicalRect* overflow);
+
void AddOutlineRectsForNormalChildren(
Vector<PhysicalRect>* outline_rects,
const PhysicalOffset& additional_offset,
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 02c51c05535..d5f70584bc9 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
@@ -80,6 +80,9 @@ String StringForBoxType(const NGPhysicalFragment& fragment) {
case NGPhysicalFragment::NGBoxType::kBlockFlowRoot:
result.Append("block-flow-root");
break;
+ case NGPhysicalFragment::NGBoxType::kRenderedLegend:
+ result.Append("rendered-legend");
+ break;
}
if (fragment.IsLegacyLayoutRoot()) {
if (result.length())
@@ -91,18 +94,13 @@ String StringForBoxType(const NGPhysicalFragment& fragment) {
result.Append(" ");
result.Append("block-flow");
}
- if (fragment.IsRenderedLegend()) {
- if (result.length())
- result.Append(" ");
- result.Append("rendered-legend");
- }
if (fragment.IsFieldsetContainer()) {
if (result.length())
result.Append(" ");
result.Append("fieldset-container");
}
if (fragment.IsBox() &&
- static_cast<const NGPhysicalBoxFragment&>(fragment).ChildrenInline()) {
+ To<NGPhysicalBoxFragment>(fragment).IsInlineFormattingContext()) {
if (result.length())
result.Append(" ");
result.Append("children-inline");
@@ -124,10 +122,7 @@ void AppendFragmentToString(const NGPhysicalFragment* fragment,
bool has_content = false;
if (const auto* box = DynamicTo<NGPhysicalBoxFragment>(fragment)) {
if (flags & NGPhysicalFragment::DumpType) {
- if (fragment->IsRenderedLegend())
- builder->Append("RenderedLegend");
- else
- builder->Append("Box");
+ builder->Append("Box");
String box_type = StringForBoxType(*fragment);
has_content = true;
if (!box_type.IsEmpty()) {
@@ -224,9 +219,12 @@ NGPhysicalFragment::NGPhysicalFragment(NGFragmentBuilder* builder,
sub_type_(sub_type),
style_variant_((unsigned)builder->style_variant_),
is_hidden_for_paint_(builder->is_hidden_for_paint_),
+ is_first_for_node_(true),
has_floating_descendants_for_paint_(false),
is_fieldset_container_(false),
- is_legacy_layout_root_(false) {
+ is_legacy_layout_root_(false),
+ is_painted_atomically_(false),
+ has_baseline_(false) {
DCHECK(builder->layout_object_);
}
@@ -243,7 +241,9 @@ NGPhysicalFragment::NGPhysicalFragment(LayoutObject* layout_object,
is_hidden_for_paint_(false),
has_floating_descendants_for_paint_(false),
is_fieldset_container_(false),
- is_legacy_layout_root_(false) {
+ is_legacy_layout_root_(false),
+ is_painted_atomically_(false),
+ has_baseline_(false) {
DCHECK(layout_object);
}
@@ -254,7 +254,6 @@ NGPhysicalFragment::~NGPhysicalFragment() = default;
void NGPhysicalFragment::Destroy() const {
switch (Type()) {
case kFragmentBox:
- case kFragmentRenderedLegend:
delete static_cast<const NGPhysicalBoxFragment*>(this);
break;
case kFragmentText:
@@ -305,6 +304,19 @@ bool NGPhysicalFragment::IsPlacedByLayoutNG() const {
return container->IsLayoutNGMixin();
}
+const FragmentData* NGPhysicalFragment::GetFragmentData() const {
+ DCHECK(CanTraverse());
+ const LayoutObject* layout_object = GetLayoutObject();
+ if (!layout_object)
+ return nullptr;
+ // TODO(mstensho): Actually return the correct FragmentData. For now this
+ // method only behaves if there's just one FragmentData associated with the
+ // LayoutObject.
+ const FragmentData& first_fragment_data = layout_object->FirstFragment();
+ DCHECK(!first_fragment_data.NextFragment());
+ return &first_fragment_data;
+}
+
const NGPhysicalFragment* NGPhysicalFragment::PostLayout() const {
if (IsBox() && !IsInlineBox()) {
if (const auto* block = DynamicTo<LayoutBlockFlow>(GetLayoutObject())) {
@@ -322,7 +334,6 @@ const NGPhysicalFragment* NGPhysicalFragment::PostLayout() const {
void NGPhysicalFragment::CheckType() const {
switch (Type()) {
case kFragmentBox:
- case kFragmentRenderedLegend:
if (IsInlineBox()) {
DCHECK(layout_object_->IsLayoutInline());
} else {
@@ -337,10 +348,10 @@ void NGPhysicalFragment::CheckType() const {
DCHECK(!IsFloating());
DCHECK(!IsOutOfFlowPositioned());
DCHECK(!IsAtomicInline());
- DCHECK(!IsBlockFormattingContextRoot());
+ DCHECK(!IsFormattingContextRoot());
break;
}
- if (layout_object_->IsLayoutNGListMarker()) {
+ if (layout_object_->IsLayoutNGOutsideListMarker()) {
// List marker is an atomic inline if it appears in a line box, or a
// block box.
DCHECK(!IsFloating());
@@ -392,7 +403,6 @@ void NGPhysicalFragment::CheckCanUpdateInkOverflow() const {
PhysicalRect NGPhysicalFragment::ScrollableOverflow() const {
switch (Type()) {
case kFragmentBox:
- case kFragmentRenderedLegend:
return To<NGPhysicalBoxFragment>(*this).ScrollableOverflow();
case kFragmentText:
return {{}, Size()};
@@ -406,18 +416,30 @@ PhysicalRect NGPhysicalFragment::ScrollableOverflow() const {
}
PhysicalRect NGPhysicalFragment::ScrollableOverflowForPropagation(
- const LayoutObject* container) const {
- DCHECK(container);
+ const NGPhysicalBoxFragment& container) const {
PhysicalRect overflow = ScrollableOverflow();
- if (GetLayoutObject() &&
- GetLayoutObject()->ShouldUseTransformFromContainer(container)) {
+ AdjustScrollableOverflowForPropagation(container, &overflow);
+ return overflow;
+}
+
+void NGPhysicalFragment::AdjustScrollableOverflowForPropagation(
+ const NGPhysicalBoxFragment& container,
+ PhysicalRect* overflow) const {
+ DCHECK(!IsLineBox());
+ if (!IsCSSBox())
+ return;
+
+ const LayoutObject* layout_object = GetLayoutObject();
+ DCHECK(layout_object);
+ const LayoutObject* container_layout_object = container.GetLayoutObject();
+ DCHECK(container_layout_object);
+ if (layout_object->ShouldUseTransformFromContainer(container_layout_object)) {
TransformationMatrix transform;
- GetLayoutObject()->GetTransformFromContainer(container, PhysicalOffset(),
- transform);
- overflow =
- PhysicalRect::EnclosingRect(transform.MapRect(FloatRect(overflow)));
+ layout_object->GetTransformFromContainer(container_layout_object,
+ PhysicalOffset(), transform);
+ *overflow =
+ PhysicalRect::EnclosingRect(transform.MapRect(FloatRect(*overflow)));
}
- return overflow;
}
const Vector<NGInlineItem>& NGPhysicalFragment::InlineItemsOfContainingBlock()
@@ -430,6 +452,7 @@ const Vector<NGInlineItem>& NGPhysicalFragment::InlineItemsOfContainingBlock()
// modification. Unify them.
DCHECK(block_flow);
NGBlockNode block_node = NGBlockNode(block_flow);
+ DCHECK(block_node.IsInlineFormattingContextRoot());
DCHECK(block_node.CanUseNewLayout());
NGLayoutInputNode node = block_node.FirstChild();
@@ -447,7 +470,6 @@ UBiDiLevel NGPhysicalFragment::BidiLevel() const {
case kFragmentText:
return To<NGPhysicalTextFragment>(*this).BidiLevel();
case kFragmentBox:
- case kFragmentRenderedLegend:
return To<NGPhysicalBoxFragment>(*this).BidiLevel();
case kFragmentLineBox:
break;
@@ -461,7 +483,6 @@ TextDirection NGPhysicalFragment::ResolvedDirection() const {
case kFragmentText:
return To<NGPhysicalTextFragment>(*this).ResolvedDirection();
case kFragmentBox:
- case kFragmentRenderedLegend:
DCHECK(IsInline() && IsAtomicInline());
// TODO(xiaochengh): Store direction in |base_direction_| flag.
return DirectionFromLevel(BidiLevel());
@@ -494,7 +515,6 @@ String NGPhysicalFragment::ToString() const {
Size().ToString().Ascii().c_str());
switch (Type()) {
case kFragmentBox:
- case kFragmentRenderedLegend:
output.AppendFormat(", BoxType: '%s'",
StringForBoxType(*this).Ascii().c_str());
break;
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 e3b64e26d96..2fcd7049c96 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
@@ -11,7 +11,7 @@
#include "third_party/blink/renderer/core/layout/geometry/physical_offset.h"
#include "third_party/blink/renderer/core/layout/geometry/physical_rect.h"
#include "third_party/blink/renderer/core/layout/geometry/physical_size.h"
-#include "third_party/blink/renderer/core/layout/layout_object.h"
+#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/ng/ng_style_variant.h"
#include "third_party/blink/renderer/platform/graphics/touch_action.h"
#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
@@ -21,6 +21,7 @@
namespace blink {
class ComputedStyle;
+class FragmentData;
class Node;
class NGFragmentBuilder;
class NGInlineItem;
@@ -50,7 +51,6 @@ class CORE_EXPORT NGPhysicalFragment
kFragmentBox = 0,
kFragmentText = 1,
kFragmentLineBox = 2,
- kFragmentRenderedLegend = 3,
// When adding new values, make sure the bit size of |type_| is large
// enough to store.
};
@@ -64,13 +64,14 @@ class CORE_EXPORT NGPhysicalFragment
kFloating,
kOutOfFlowPositioned,
kBlockFlowRoot,
+ kRenderedLegend,
// When adding new values, make sure the bit size of |sub_type_| is large
// enough to store.
- // Also, add after kMinimumBlockFormattingContextRoot if the box type is a
- // block formatting context root, or before otherwise. See
- // IsBlockFormattingContextRoot().
- kMinimumBlockFormattingContextRoot = kAtomicInline
+ // Also, add after kMinimumFormattingContextRoot if the box type is a
+ // formatting context root, or before otherwise. See
+ // IsFormattingContextRoot().
+ kMinimumFormattingContextRoot = kAtomicInline
};
~NGPhysicalFragment();
@@ -78,19 +79,12 @@ class CORE_EXPORT NGPhysicalFragment
NGFragmentType Type() const { return static_cast<NGFragmentType>(type_); }
bool IsContainer() const {
return Type() == NGFragmentType::kFragmentBox ||
- Type() == NGFragmentType::kFragmentLineBox ||
- Type() == NGFragmentType::kFragmentRenderedLegend;
+ Type() == NGFragmentType::kFragmentLineBox;
}
bool IsBox() const { return Type() == NGFragmentType::kFragmentBox; }
bool IsText() const { return Type() == NGFragmentType::kFragmentText; }
bool IsLineBox() const { return Type() == NGFragmentType::kFragmentLineBox; }
- // Return true if this is the legend child of a fieldset that gets special
- // treatment (i.e. placed over the block-start border).
- bool IsRenderedLegend() const {
- return Type() == NGFragmentType::kFragmentRenderedLegend;
- }
-
// Returns the box type of this fragment.
NGBoxType BoxType() const {
DCHECK(IsBox());
@@ -122,6 +116,14 @@ class CORE_EXPORT NGPhysicalFragment
bool IsFloatingOrOutOfFlowPositioned() const {
return IsFloating() || IsOutOfFlowPositioned();
}
+ // Return true if this is the legend child of a fieldset that gets special
+ // treatment (i.e. placed over the block-start border).
+ bool IsRenderedLegend() const {
+ return IsBox() && BoxType() == NGBoxType::kRenderedLegend;
+ }
+ bool IsMathMLFraction() const {
+ return IsBox() && is_generated_text_or_math_fraction_;
+ }
// Return true if this fragment corresponds directly to an entry in the CSS
// box tree [1]. Note that anonymous blocks also exist in the CSS box
@@ -140,7 +142,7 @@ class CORE_EXPORT NGPhysicalFragment
return IsCSSBox() && layout_object_->IsAnonymousBlock();
}
bool IsListMarker() const {
- return IsCSSBox() && layout_object_->IsLayoutNGListMarker();
+ return IsCSSBox() && layout_object_->IsLayoutNGOutsideListMarker();
}
// Return true if this fragment is a container established by a fieldset
@@ -152,9 +154,11 @@ class CORE_EXPORT NGPhysicalFragment
// Returns whether the fragment is legacy layout root.
bool IsLegacyLayoutRoot() const { return is_legacy_layout_root_; }
- bool IsBlockFormattingContextRoot() const {
- return (IsBox() &&
- BoxType() >= NGBoxType::kMinimumBlockFormattingContextRoot) ||
+ // Returns whether the fragment should be atomically painted.
+ bool IsPaintedAtomically() const { return is_painted_atomically_; }
+
+ bool IsFormattingContextRoot() const {
+ return (IsBox() && BoxType() >= NGBoxType::kMinimumFormattingContextRoot) ||
IsLegacyLayoutRoot();
}
@@ -164,6 +168,9 @@ class CORE_EXPORT NGPhysicalFragment
// |LayoutNGBlockFlow::UpdateBlockLayout()| and crbug.com/788590
bool IsPlacedByLayoutNG() const;
+ // Return true if this is the first fragment generated from a node.
+ bool IsFirstForNode() const { return is_first_for_node_; }
+
// The accessors in this class shouldn't be used by layout code directly,
// instead should be accessed by the NGFragmentBase classes. These accessors
// exist for paint, hit-testing, etc.
@@ -206,6 +213,17 @@ class CORE_EXPORT NGPhysicalFragment
// from GetNode() when this fragment is content of a pseudo node.
Node* NodeForHitTest() const { return layout_object_->NodeForHitTest(); }
+ bool IsInSelfHitTestingPhase(HitTestAction action) const {
+ if (const auto* box = ToLayoutBoxOrNull(GetLayoutObject()))
+ return box->IsInSelfHitTestingPhase(action);
+ if (IsInlineBox())
+ return action == kHitTestForeground;
+ // Assuming this is some sort of container, e.g. a fragmentainer (they don't
+ // have a LayoutObject associated).
+ return action == kHitTestBlockBackground ||
+ action == kHitTestChildBlockBackground;
+ }
+
// Whether there is a PaintLayer associated with the fragment.
bool HasLayer() const { return IsCSSBox() && layout_object_->HasLayer(); }
@@ -225,10 +243,31 @@ class CORE_EXPORT NGPhysicalFragment
return IsCSSBox() && layout_object_->ShouldClipOverflow();
}
+ bool IsFragmentationContextRoot() const {
+ return !IsColumnBox() && IsBlockFlow() && Style().SpecifiesColumns();
+ }
+
+ // Return whether we can traverse this fragment and its children directly, for
+ // painting, hit-testing and other layout read operations. If false is
+ // returned, we need to traverse the layout object tree instead.
+ bool CanTraverse() const {
+ return layout_object_->CanTraversePhysicalFragments();
+ }
+
// This fragment is hidden for paint purpose, but exists for querying layout
// information. Used for `text-overflow: ellipsis`.
bool IsHiddenForPaint() const { return is_hidden_for_paint_; }
+ // Return true if this fragment is monolithic, as far as block fragmentation
+ // is concerned.
+ bool IsMonolithic() const {
+ const LayoutObject* layout_object = GetLayoutObject();
+ if (!layout_object || !IsBox() || !layout_object->IsBox())
+ return false;
+ return ToLayoutBox(layout_object)->GetPaginationBreakability() ==
+ LayoutBox::kForbidBreaks;
+ }
+
// GetLayoutObject should only be used when necessary for compatibility
// with LegacyLayout.
//
@@ -244,6 +283,8 @@ class CORE_EXPORT NGPhysicalFragment
return IsCSSBox() ? layout_object_ : nullptr;
}
+ const FragmentData* GetFragmentData() const;
+
// |NGPhysicalFragment| may live longer than the corresponding |LayoutObject|.
// Though |NGPhysicalFragment| is immutable, |layout_object_| is cleared to
// |nullptr| when it was destroyed to avoid reading destroyed objects.
@@ -260,13 +301,21 @@ class CORE_EXPORT NGPhysicalFragment
// check if there were newer generations.
const NGPhysicalFragment* PostLayout() const;
+ PhysicalRect InkOverflow() const {
+ // TODO(layout-dev): Implement box fragment overflow.
+ return LocalRect();
+ }
+
// Scrollable overflow. including contents, in the local coordinate.
PhysicalRect ScrollableOverflow() const;
// ScrollableOverflow(), with transforms applied wrt container if needed.
// This does not include any offsets from the parent (including relpos).
PhysicalRect ScrollableOverflowForPropagation(
- const LayoutObject* container) const;
+ const NGPhysicalBoxFragment& container) const;
+ void AdjustScrollableOverflowForPropagation(
+ const NGPhysicalBoxFragment& container,
+ PhysicalRect* overflow) const;
// The allowed touch action is the union of the effective touch action
// (from style) and blocking touch event handlers.
@@ -336,6 +385,7 @@ class CORE_EXPORT NGPhysicalFragment
const unsigned sub_type_ : 3; // NGBoxType, NGTextType, or NGLineBoxType
const unsigned style_variant_ : 2; // NGStyleVariant
const unsigned is_hidden_for_paint_ : 1;
+ unsigned is_first_for_node_ : 1;
// The following bitfields are only to be used by NGPhysicalContainerFragment
// (it's defined here to save memory, since that class has no bitfields).
@@ -348,28 +398,37 @@ 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;
- unsigned base_direction_ : 1; // TextDirection
+ // 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
// (it's defined here to save memory, since that class has no bitfields).
- unsigned children_inline_ : 1;
+ unsigned is_inline_formatting_context_ : 1;
unsigned has_fragment_items_ : 1;
unsigned border_edge_ : 4; // NGBorderEdges::Physical
unsigned has_borders_ : 1;
unsigned has_padding_ : 1;
- unsigned is_first_for_node_ : 1;
// The following are only used by NGPhysicalBoxFragment but are initialized
// for all types to allow methods using them to be inlined.
unsigned is_fieldset_container_ : 1;
unsigned is_legacy_layout_root_ : 1;
+ unsigned is_painted_atomically_ : 1;
+ unsigned has_baseline_ : 1;
+ unsigned has_last_baseline_ : 1;
+
+ // The following bitfield is shared between NGPhysicalTextFragment and
+ // NGPhysicalBoxFragment.
+ unsigned is_generated_text_or_math_fraction_ : 1;
// The following bitfields are only to be used by NGPhysicalTextFragment
// (it's defined here to save memory, since that class has no bitfields).
- unsigned is_generated_text_ : 1;
mutable unsigned ink_overflow_computed_ : 1;
+ // Note: We've used 32-bit bit field. If you need more bits, please think to
+ // share bit fields.
+
private:
friend struct NGPhysicalFragmentTraits;
void Destroy() const;
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 448c3e00d89..a2bec293a78 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
@@ -36,9 +36,11 @@ NGSimplifiedLayoutAlgorithm::NGSimplifiedLayoutAlgorithm(
const NGPhysicalBoxFragment& physical_fragment =
To<NGPhysicalBoxFragment>(result.PhysicalFragment());
+ container_builder_.SetIsInlineFormattingContext(
+ Node().IsInlineFormattingContextRoot());
container_builder_.SetStyleVariant(physical_fragment.StyleVariant());
container_builder_.SetIsNewFormattingContext(
- physical_fragment.IsBlockFormattingContextRoot());
+ physical_fragment.IsFormattingContextRoot());
container_builder_.SetInitialFragmentGeometry(params.fragment_geometry);
NGExclusionSpace exclusion_space = result.ExclusionSpace();
@@ -65,11 +67,10 @@ NGSimplifiedLayoutAlgorithm::NGSimplifiedLayoutAlgorithm(
container_builder_.SetIsPushedByFloats();
container_builder_.SetAdjoiningObjectTypes(result.AdjoiningObjectTypes());
- for (const auto& request : ConstraintSpace().BaselineRequests()) {
- base::Optional<LayoutUnit> baseline = physical_fragment.Baseline(request);
- if (baseline)
- container_builder_.AddBaseline(request, *baseline);
- }
+ if (physical_fragment.Baseline())
+ container_builder_.SetBaseline(*physical_fragment.Baseline());
+ if (physical_fragment.LastBaseline())
+ container_builder_.SetLastBaseline(*physical_fragment.LastBaseline());
container_builder_.SetBlockSize(ComputeBlockSizeForFragment(
ConstraintSpace(), Style(),
@@ -171,7 +172,7 @@ scoped_refptr<const NGLayoutResult> NGSimplifiedLayoutAlgorithm::Layout() {
// Only take exclusion spaces from children which don't establish their own
// formatting context.
- if (!fragment.IsBlockFormattingContextRoot())
+ if (!fragment.IsFormattingContextRoot())
exclusion_space_ = result->ExclusionSpace();
++it;
}
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 3ae73180868..11eec2a89c9 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
@@ -38,6 +38,7 @@ NGConstraintSpace CreateIndefiniteConstraintSpaceForChild(
builder.SetAvailableSize(indefinite_size);
builder.SetPercentageResolutionSize(indefinite_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_text_decoration_offset.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_text_decoration_offset.cc
index 13a027e0b88..b67b5756cc9 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
@@ -4,7 +4,6 @@
#include "third_party/blink/renderer/core/layout/ng/ng_text_decoration_offset.h"
-#include "third_party/blink/renderer/core/layout/ng/inline/ng_baseline.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
@@ -19,15 +18,8 @@ int NGTextDecorationOffset::ComputeUnderlineOffsetForUnder(
const ComputedStyle& style = text_style_;
FontBaseline baseline_type = style.GetFontBaseline();
- if (decorating_box_) {
- NGBaselineRequest baseline_request = {
- NGBaselineAlgorithmType::kAtomicInline,
- FontBaseline::kIdeographicBaseline};
-
- if (base::Optional<LayoutUnit> baseline =
- decorating_box_->Baseline(baseline_request))
- offset = *baseline;
- }
+ if (decorating_box_)
+ offset = decorating_box_->Baseline().value_or(offset);
if (offset == LayoutUnit::Max()) {
// TODO(layout-dev): How do we compute the baseline offset with a
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 0d86a6fc07c..d796a7f10bb 100644
--- a/chromium/third_party/blink/renderer/core/layout/scroll_anchor.cc
+++ b/chromium/third_party/blink/renderer/core/layout/scroll_anchor.cc
@@ -463,7 +463,8 @@ void ScrollAnchor::Adjust() {
}
scroller_->SetScrollOffset(
- scroller_->GetScrollOffset() + FloatSize(adjustment), kAnchoringScroll);
+ scroller_->GetScrollOffset() + FloatSize(adjustment),
+ mojom::blink::ScrollType::kAnchoring);
// Update UMA metric.
DEFINE_STATIC_LOCAL(EnumerationHistogram, adjusted_offset_histogram,
@@ -538,13 +539,15 @@ bool ScrollAnchor::RestoreAnchor(const SerializedAnchor& serialized_anchor) {
ScrollOffset delta =
ScrollOffset(RoundedIntSize(serialized_anchor.relative_offset));
desired_offset -= delta;
- scroller_->SetScrollOffset(desired_offset, kAnchoringScroll);
+ scroller_->SetScrollOffset(desired_offset,
+ mojom::blink::ScrollType::kAnchoring);
FindAnchor();
// If the above FindAnchor call failed, reset the scroll position and try
// again with the next found element.
if (!anchor_object_) {
- scroller_->SetScrollOffset(current_offset, kAnchoringScroll);
+ scroller_->SetScrollOffset(current_offset,
+ mojom::blink::ScrollType::kAnchoring);
continue;
}
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 56ebdf6a503..c637c9c9e20 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(blink::Visitor* visitor) { visitor->Trace(scroller_); }
+ void Trace(Visitor* visitor) { 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 ae0ac5b2816..e14100e6593 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
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/layout/scroll_anchor.h"
#include "build/build_config.h"
+#include "third_party/blink/public/common/input/web_mouse_event.h"
#include "third_party/blink/renderer/core/dom/static_node_list.h"
#include "third_party/blink/renderer/core/frame/root_frame_viewport.h"
#include "third_party/blink/renderer/core/frame/visual_viewport.h"
@@ -28,6 +29,11 @@ class ScrollAnchorTest : public testing::WithParamInterface<bool>,
ScrollAnchorTest() : ScopedLayoutNGForTest(GetParam()) {}
protected:
+ void SetUp() override {
+ EnableCompositing();
+ RenderingTest::SetUp();
+ }
+
void Update() {
// TODO(skobes): Use SimTest instead of RenderingTest and move into
// Source/web?
@@ -79,6 +85,52 @@ class ScrollAnchorTest : public testing::WithParamInterface<bool>,
GetDocument().QuerySelectorAll(AtomicString(serialized.selector));
EXPECT_EQ(ele_list->length(), 1u);
}
+
+ Scrollbar* VerticalScrollbarForElement(Element* element) {
+ return ToLayoutBox(element->GetLayoutObject())
+ ->GetScrollableArea()
+ ->VerticalScrollbar();
+ }
+
+ void MouseDownOnVerticalScrollbar(Scrollbar* scrollbar) {
+ DCHECK_EQ(true, scrollbar->GetTheme().AllowsHitTest());
+ int thumb_center = scrollbar->GetTheme().ThumbPosition(*scrollbar) +
+ scrollbar->GetTheme().ThumbLength(*scrollbar) / 2;
+ scrollbar_drag_point_ =
+ gfx::PointF(scrollbar->GetScrollableArea()
+ ->ConvertFromScrollbarToContainingEmbeddedContentView(
+ *scrollbar, IntPoint(0, thumb_center)));
+ scrollbar->MouseDown(blink::WebMouseEvent(
+ blink::WebInputEvent::kMouseDown, *scrollbar_drag_point_,
+ *scrollbar_drag_point_, blink::WebPointerProperties::Button::kLeft, 0,
+ blink::WebInputEvent::kNoModifiers, base::TimeTicks::Now()));
+ }
+
+ void MouseDragVerticalScrollbar(Scrollbar* scrollbar, float scroll_delta_y) {
+ DCHECK(scrollbar_drag_point_);
+ ScrollableArea* scroller = scrollbar->GetScrollableArea();
+ scrollbar_drag_point_->Offset(
+ 0, scroll_delta_y *
+ (scrollbar->GetTheme().TrackLength(*scrollbar) -
+ scrollbar->GetTheme().ThumbLength(*scrollbar)) /
+ (scroller->MaximumScrollOffset().Height() -
+ scroller->MinimumScrollOffset().Height()));
+ scrollbar->MouseMoved(blink::WebMouseEvent(
+ blink::WebInputEvent::kMouseMove, *scrollbar_drag_point_,
+ *scrollbar_drag_point_, blink::WebPointerProperties::Button::kLeft, 0,
+ blink::WebInputEvent::kNoModifiers, base::TimeTicks::Now()));
+ }
+
+ void MouseUpOnVerticalScrollbar(Scrollbar* scrollbar) {
+ DCHECK(scrollbar_drag_point_);
+ scrollbar->MouseDown(blink::WebMouseEvent(
+ blink::WebInputEvent::kMouseUp, *scrollbar_drag_point_,
+ *scrollbar_drag_point_, blink::WebPointerProperties::Button::kLeft, 0,
+ blink::WebInputEvent::kNoModifiers, base::TimeTicks::Now()));
+ scrollbar_drag_point_.reset();
+ }
+
+ base::Optional<gfx::PointF> scrollbar_drag_point_;
};
INSTANTIATE_TEST_SUITE_P(All, ScrollAnchorTest, testing::Bool());
@@ -213,7 +265,7 @@ TEST_P(ScrollAnchorTest, ClearScrollAnchorsOnAncestors) {
// Scrolling the nested scroller should clear the anchor on the main frame.
ScrollableArea* scroller =
ScrollerForElement(GetDocument().getElementById("scroller"));
- scroller->ScrollBy(ScrollOffset(0, 100), kUserScroll);
+ scroller->ScrollBy(ScrollOffset(0, 100), mojom::blink::ScrollType::kUser);
EXPECT_EQ(nullptr, GetScrollAnchor(viewport).AnchorObject());
}
@@ -313,7 +365,7 @@ TEST_P(ScrollAnchorTest, AnchorWithLayerInScrollingDiv) {
Element* block1 = GetDocument().getElementById("block1");
Element* block2 = GetDocument().getElementById("block2");
- scroller->ScrollBy(ScrollOffset(0, 150), kUserScroll);
+ scroller->ScrollBy(ScrollOffset(0, 150), mojom::blink::ScrollType::kUser);
// In this layout pass we will anchor to #block2 which has its own PaintLayer.
SetHeight(block1, 200);
@@ -328,6 +380,51 @@ TEST_P(ScrollAnchorTest, AnchorWithLayerInScrollingDiv) {
EXPECT_EQ(250, scroller->ScrollOffsetInt().Height());
}
+TEST_P(ScrollAnchorTest, AnchorWhileDraggingScrollbar) {
+ // Dragging the scrollbar is inherently inaccurate. Allow many pixels slop in
+ // the scroll position.
+ const int kScrollbarDragAccuracy = 10;
+ USE_NON_OVERLAY_SCROLLBARS();
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #scroller { overflow: scroll; width: 500px; height: 400px; }
+ div { height: 100px }
+ #block2 { overflow: hidden }
+ #space { height: 1000px; }
+ </style>
+ <div id='scroller'><div id='space'>
+ <div id='block1'>abc</div>
+ <div id='block2'>def</div>
+ </div></div>
+ )HTML");
+ Element* scroller_element = GetDocument().getElementById("scroller");
+ ScrollableArea* scroller = ScrollerForElement(scroller_element);
+
+ Element* block1 = GetDocument().getElementById("block1");
+ Element* block2 = GetDocument().getElementById("block2");
+
+ Scrollbar* scrollbar = VerticalScrollbarForElement(scroller_element);
+ scroller->MouseEnteredScrollbar(*scrollbar);
+ MouseDownOnVerticalScrollbar(scrollbar);
+ MouseDragVerticalScrollbar(scrollbar, 150);
+ EXPECT_NEAR(150, scroller->GetScrollOffset().Height(),
+ kScrollbarDragAccuracy);
+
+ // In this layout pass we will anchor to #block2 which has its own PaintLayer.
+ SetHeight(block1, 200);
+ EXPECT_NEAR(250, scroller->ScrollOffsetInt().Height(),
+ kScrollbarDragAccuracy);
+ EXPECT_EQ(block2->GetLayoutObject(),
+ GetScrollAnchor(scroller).AnchorObject());
+
+ // If we continue dragging the scroller should scroll from the newly anchored
+ // position.
+ MouseDragVerticalScrollbar(scrollbar, 10);
+ EXPECT_NEAR(260, scroller->ScrollOffsetInt().Height(),
+ kScrollbarDragAccuracy);
+ MouseUpOnVerticalScrollbar(scrollbar);
+}
+
// Verify that a nested scroller with a div that has its own PaintLayer can be
// removed without causing a crash. This test passes if it doesn't crash.
TEST_P(ScrollAnchorTest, RemoveScrollerWithLayerInScrollingDiv) {
@@ -353,7 +450,7 @@ TEST_P(ScrollAnchorTest, RemoveScrollerWithLayerInScrollingDiv) {
Element* changer2 = GetDocument().getElementById("changer2");
Element* anchor = GetDocument().getElementById("anchor");
- scroller->ScrollBy(ScrollOffset(0, 150), kUserScroll);
+ scroller->ScrollBy(ScrollOffset(0, 150), mojom::blink::ScrollType::kUser);
ScrollLayoutViewport(ScrollOffset(0, 50));
// In this layout pass both the inner and outer scroller will anchor to
@@ -949,11 +1046,12 @@ TEST_P(ScrollAnchorTest, ClampAdjustsAnchorAnimation) {
<div class="content" id=three></div>
<div class="content" id=four></div>
)HTML");
- LayoutViewport()->SetScrollOffset(ScrollOffset(0, 2000), kUserScroll);
+ LayoutViewport()->SetScrollOffset(ScrollOffset(0, 2000),
+ mojom::blink::ScrollType::kUser);
Update();
GetDocument().getElementById("hidden")->setAttribute(html_names::kStyleAttr,
"display:block");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
#if !defined(OS_MACOSX)
EXPECT_EQ(IntSize(0, 200), LayoutViewport()
->GetScrollAnimator()
@@ -961,7 +1059,7 @@ TEST_P(ScrollAnchorTest, ClampAdjustsAnchorAnimation) {
#endif
GetDocument().getElementById("hidden")->setAttribute(html_names::kStyleAttr,
"");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
// The clamping scroll after resizing layout overflow to be smaller
// should adjust the animation back to 0.
EXPECT_EQ(IntSize(0, 0), LayoutViewport()
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 174a0472eec..5ffb764ec5e 100644
--- a/chromium/third_party/blink/renderer/core/layout/scrollbars_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/scrollbars_test.cc
@@ -30,6 +30,8 @@
#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 "ui/base/cursor/cursor.h"
+#include "ui/base/mojom/cursor_type.mojom-blink.h"
namespace blink {
@@ -74,19 +76,8 @@ class StubWebThemeEngine : public WebThemeEngine {
return painted_color_scheme_[part];
}
- blink::PreferredColorScheme PreferredColorScheme() const override {
- return preferred_color_scheme_;
- }
-
- void SetPreferredColorScheme(
- const blink::PreferredColorScheme preferred_color_scheme) override {
- preferred_color_scheme_ = preferred_color_scheme;
- }
-
private:
std::array<WebColorScheme, kPartProgressBar + 1> painted_color_scheme_;
- blink::PreferredColorScheme preferred_color_scheme_ =
- blink::PreferredColorScheme::kNoPreference;
};
constexpr int StubWebThemeEngine::kMinimumHorizontalLength;
@@ -136,8 +127,8 @@ class ScrollbarsTest : public SimTest {
}
void HandleMouseMoveEvent(int x, int y) {
- WebMouseEvent event(WebInputEvent::kMouseMove, WebFloatPoint(x, y),
- WebFloatPoint(x, y),
+ WebMouseEvent event(WebInputEvent::kMouseMove, gfx::PointF(x, y),
+ gfx::PointF(x, y),
WebPointerProperties::Button::kNoButton, 0,
WebInputEvent::kNoModifiers, base::TimeTicks::Now());
event.SetFrameScale(1);
@@ -146,17 +137,17 @@ class ScrollbarsTest : public SimTest {
}
void HandleMousePressEvent(int x, int y) {
- WebMouseEvent event(
- WebInputEvent::kMouseDown, WebFloatPoint(x, y), WebFloatPoint(x, y),
- WebPointerProperties::Button::kLeft, 0,
- WebInputEvent::Modifiers::kLeftButtonDown, base::TimeTicks::Now());
+ WebMouseEvent event(WebInputEvent::kMouseDown, gfx::PointF(x, y),
+ gfx::PointF(x, y), WebPointerProperties::Button::kLeft,
+ 0, WebInputEvent::Modifiers::kLeftButtonDown,
+ base::TimeTicks::Now());
event.SetFrameScale(1);
GetEventHandler().HandleMousePressEvent(event);
}
void HandleContextMenuEvent(int x, int y) {
WebMouseEvent event(
- WebInputEvent::kMouseDown, WebFloatPoint(x, y), WebFloatPoint(x, y),
+ WebInputEvent::kMouseDown, gfx::PointF(x, y), gfx::PointF(x, y),
WebPointerProperties::Button::kNoButton, 0,
WebInputEvent::Modifiers::kNoModifiers, base::TimeTicks::Now());
event.SetFrameScale(1);
@@ -164,17 +155,17 @@ class ScrollbarsTest : public SimTest {
}
void HandleMouseReleaseEvent(int x, int y) {
- WebMouseEvent event(
- WebInputEvent::kMouseUp, WebFloatPoint(x, y), WebFloatPoint(x, y),
- WebPointerProperties::Button::kLeft, 0,
- WebInputEvent::Modifiers::kNoModifiers, base::TimeTicks::Now());
+ WebMouseEvent event(WebInputEvent::kMouseUp, gfx::PointF(x, y),
+ gfx::PointF(x, y), WebPointerProperties::Button::kLeft,
+ 0, WebInputEvent::Modifiers::kNoModifiers,
+ base::TimeTicks::Now());
event.SetFrameScale(1);
GetEventHandler().HandleMouseReleaseEvent(event);
}
void HandleMouseMiddlePressEvent(int x, int y) {
WebMouseEvent event(
- WebInputEvent::kMouseDown, WebFloatPoint(x, y), WebFloatPoint(x, y),
+ WebInputEvent::kMouseDown, gfx::PointF(x, y), gfx::PointF(x, y),
WebPointerProperties::Button::kMiddle, 0,
WebInputEvent::Modifiers::kMiddleButtonDown, base::TimeTicks::Now());
event.SetFrameScale(1);
@@ -183,7 +174,7 @@ class ScrollbarsTest : public SimTest {
void HandleMouseMiddleReleaseEvent(int x, int y) {
WebMouseEvent event(
- WebInputEvent::kMouseUp, WebFloatPoint(x, y), WebFloatPoint(x, y),
+ WebInputEvent::kMouseUp, gfx::PointF(x, y), gfx::PointF(x, y),
WebPointerProperties::Button::kMiddle, 0,
WebInputEvent::Modifiers::kMiddleButtonDown, base::TimeTicks::Now());
event.SetFrameScale(1);
@@ -191,10 +182,10 @@ class ScrollbarsTest : public SimTest {
}
void HandleMouseLeaveEvent() {
- WebMouseEvent event(
- WebInputEvent::kMouseMove, WebFloatPoint(1, 1), WebFloatPoint(1, 1),
- WebPointerProperties::Button::kLeft, 0,
- WebInputEvent::Modifiers::kLeftButtonDown, base::TimeTicks::Now());
+ WebMouseEvent event(WebInputEvent::kMouseLeave, gfx::PointF(1, 1),
+ gfx::PointF(1, 1), WebPointerProperties::Button::kLeft,
+ 0, WebInputEvent::Modifiers::kLeftButtonDown,
+ base::TimeTicks::Now());
event.SetFrameScale(1);
GetEventHandler().HandleMouseLeaveEvent(event);
}
@@ -215,12 +206,12 @@ class ScrollbarsTest : public SimTest {
offset);
}
- ui::CursorType CursorType() {
+ ui::mojom::blink::CursorType CursorType() {
return GetDocument()
.GetFrame()
->GetChromeClient()
.LastSetCursorForTesting()
- .GetType();
+ .type();
}
ScrollbarTheme& GetScrollbarTheme() {
@@ -235,7 +226,7 @@ class ScrollbarsTest : public SimTest {
WebGestureEvent event(type, WebInputEvent::kNoModifiers,
base::TimeTicks::Now(), device);
- event.SetPositionInWidget(WebFloatPoint(position.X(), position.Y()));
+ event.SetPositionInWidget(gfx::PointF(position.X(), position.Y()));
if (type == WebInputEvent::kGestureScrollUpdate) {
event.data.scroll_update.delta_x = offset.Width();
@@ -370,7 +361,7 @@ TEST(ScrollbarsTestWithOwnWebViewHelper, ScrollbarSizeForUseZoomDSF) {
"</body>",
base_url);
web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
Document* document =
To<LocalFrame>(web_view_impl->GetPage()->MainFrame())->GetDocument();
@@ -577,6 +568,45 @@ TEST_F(ScrollbarsTest, OverlayScrollbarChangeToDisplayNoneDynamically) {
EXPECT_TRUE(scrollable_root->HorizontalScrollbar()->FrameRect().IsEmpty());
}
+// Ensure that overlay scrollbars are not created, even in overflow:scroll,
+// situations when there's no overflow. Specifically, after style-only changes.
+TEST_F(ScrollbarsTest, OverlayScrolblarNotCreatedInUnscrollableAxis) {
+ // This test is specifically checking the behavior when overlay scrollbars
+ // are enabled.
+ ENABLE_OVERLAY_SCROLLBARS(true);
+
+ 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>
+ #target {
+ width: 100px;
+ height: 100px;
+ overflow-y: scroll;
+ opacity: 0.5;
+ }
+ </style>
+ <div id="target"></div>
+ )HTML");
+
+ Compositor().BeginFrame();
+
+ auto* target = GetDocument().getElementById("target");
+ auto* scrollable_area = target->GetLayoutBox()->GetScrollableArea();
+
+ ASSERT_FALSE(scrollable_area->VerticalScrollbar());
+ ASSERT_FALSE(scrollable_area->HorizontalScrollbar());
+
+ // Mutate the opacity so that we cause a style-only change.
+ target->setAttribute(html_names::kStyleAttr, "opacity: 0.9");
+ Compositor().BeginFrame();
+
+ ASSERT_FALSE(scrollable_area->VerticalScrollbar());
+ ASSERT_FALSE(scrollable_area->HorizontalScrollbar());
+}
+
TEST_F(ScrollbarsTest, scrollbarIsNotHandlingTouchpadScroll) {
WebView().MainFrameWidget()->Resize(WebSize(200, 200));
SimRequest request("https://example.com/test.html", "text/html");
@@ -603,11 +633,11 @@ TEST_F(ScrollbarsTest, scrollbarIsNotHandlingTouchpadScroll) {
WebInputEvent::kGestureScrollBegin, WebInputEvent::kNoModifiers,
base::TimeTicks::Now(), WebGestureDevice::kTouchpad);
scroll_begin.SetPositionInWidget(
- WebFloatPoint(scrollable->OffsetLeft() + scrollable->OffsetWidth() - 2,
- scrollable->OffsetTop()));
+ gfx::PointF(scrollable->OffsetLeft() + scrollable->OffsetWidth() - 2,
+ scrollable->OffsetTop()));
scroll_begin.SetPositionInScreen(
- WebFloatPoint(scrollable->OffsetLeft() + scrollable->OffsetWidth() - 2,
- scrollable->OffsetTop()));
+ gfx::PointF(scrollable->OffsetLeft() + scrollable->OffsetWidth() - 2,
+ scrollable->OffsetTop()));
scroll_begin.data.scroll_begin.delta_x_hint = 0;
scroll_begin.data.scroll_begin.delta_y_hint = 10;
scroll_begin.SetFrameScale(1);
@@ -647,8 +677,8 @@ TEST_F(ScrollbarsTest, HidingScrollbarsOnScrollableAreaDisablesScrollbars) {
ScrollableArea* frame_scroller_area = frame_view->LayoutViewport();
// Scrollbars are hidden at start.
- scroller_area->SetScrollbarsHiddenIfOverlay(true);
- frame_scroller_area->SetScrollbarsHiddenIfOverlay(true);
+ scroller_area->SetScrollbarsHiddenForTesting(true);
+ frame_scroller_area->SetScrollbarsHiddenForTesting(true);
ASSERT_TRUE(scroller_area->HorizontalScrollbar());
ASSERT_TRUE(scroller_area->VerticalScrollbar());
ASSERT_TRUE(frame_scroller_area->HorizontalScrollbar());
@@ -666,23 +696,23 @@ TEST_F(ScrollbarsTest, HidingScrollbarsOnScrollableAreaDisablesScrollbars) {
EXPECT_FALSE(
scroller_area->VerticalScrollbar()->ShouldParticipateInHitTesting());
- frame_scroller_area->SetScrollbarsHiddenIfOverlay(false);
+ frame_scroller_area->SetScrollbarsHiddenForTesting(false);
EXPECT_TRUE(frame_scroller_area->HorizontalScrollbar()
->ShouldParticipateInHitTesting());
EXPECT_TRUE(frame_scroller_area->VerticalScrollbar()
->ShouldParticipateInHitTesting());
- frame_scroller_area->SetScrollbarsHiddenIfOverlay(true);
+ frame_scroller_area->SetScrollbarsHiddenForTesting(true);
EXPECT_FALSE(frame_scroller_area->HorizontalScrollbar()
->ShouldParticipateInHitTesting());
EXPECT_FALSE(frame_scroller_area->VerticalScrollbar()
->ShouldParticipateInHitTesting());
- scroller_area->SetScrollbarsHiddenIfOverlay(false);
+ scroller_area->SetScrollbarsHiddenForTesting(false);
EXPECT_TRUE(
scroller_area->HorizontalScrollbar()->ShouldParticipateInHitTesting());
EXPECT_TRUE(
scroller_area->VerticalScrollbar()->ShouldParticipateInHitTesting());
- scroller_area->SetScrollbarsHiddenIfOverlay(true);
+ scroller_area->SetScrollbarsHiddenForTesting(true);
EXPECT_FALSE(
scroller_area->HorizontalScrollbar()->ShouldParticipateInHitTesting());
EXPECT_FALSE(
@@ -733,7 +763,7 @@ TEST_F(ScrollbarsTest, MouseOverScrollbarInCustomCursorElement) {
HandleMouseMoveEvent(195, 5);
- EXPECT_EQ(ui::CursorType::kPointer, CursorType());
+ EXPECT_EQ(ui::mojom::blink::CursorType::kPointer, CursorType());
}
// Ensure mouse cursor should be override when hovering over the custom
@@ -789,7 +819,7 @@ TEST_F(ScrollbarsTest, MouseOverCustomScrollbarInCustomCursorElement) {
HandleMouseMoveEvent(195, 5);
- EXPECT_EQ(ui::CursorType::kMove, CursorType());
+ EXPECT_EQ(ui::mojom::blink::CursorType::kMove, CursorType());
}
// Makes sure that mouse hover over an overlay scrollbar doesn't activate
@@ -824,7 +854,7 @@ TEST_F(ScrollbarsTest, MouseOverLinkAndOverlayScrollbar) {
.MainFrameImpl()
->GetFrameView()
->LayoutViewport()
- ->SetScrollbarsHiddenIfOverlay(false);
+ ->SetScrollbarsHiddenForTesting(false);
Document& document = GetDocument();
Element* a_tag = document.getElementById("a");
@@ -844,13 +874,13 @@ TEST_F(ScrollbarsTest, MouseOverLinkAndOverlayScrollbar) {
// Mouse over link. Mouse cursor should be hand.
HandleMouseMoveEvent(a_tag->OffsetLeft(), a_tag->OffsetTop());
- EXPECT_EQ(ui::CursorType::kHand, CursorType());
+ EXPECT_EQ(ui::mojom::blink::CursorType::kHand, CursorType());
// Mouse over enabled overlay scrollbar. Mouse cursor should be pointer and no
// active hover element.
HandleMouseMoveEvent(x, y);
- EXPECT_EQ(ui::CursorType::kPointer, CursorType());
+ EXPECT_EQ(ui::mojom::blink::CursorType::kPointer, CursorType());
HandleMousePressEvent(x, y);
@@ -865,7 +895,7 @@ TEST_F(ScrollbarsTest, MouseOverLinkAndOverlayScrollbar) {
.MainFrameImpl()
->GetFrameView()
->LayoutViewport()
- ->SetScrollbarsHiddenIfOverlay(true);
+ ->SetScrollbarsHiddenForTesting(true);
// Ensure hittest only has link
hit_test_result = HitTest(x, y);
@@ -876,7 +906,7 @@ TEST_F(ScrollbarsTest, MouseOverLinkAndOverlayScrollbar) {
HandleMouseMoveEvent(x, y);
- EXPECT_EQ(ui::CursorType::kHand, CursorType());
+ EXPECT_EQ(ui::mojom::blink::CursorType::kHand, CursorType());
HandleMousePressEvent(x, y);
@@ -988,7 +1018,7 @@ TEST_F(ScrollbarsTest, MouseOverScrollbarAndIFrame) {
.MainFrameImpl()
->GetFrameView()
->LayoutViewport()
- ->SetScrollbarsHiddenIfOverlay(false);
+ ->SetScrollbarsHiddenForTesting(false);
frame_resource.Complete("<!DOCTYPE html>");
Compositor().BeginFrame();
@@ -1026,7 +1056,7 @@ TEST_F(ScrollbarsTest, MouseOverScrollbarAndIFrame) {
.MainFrameImpl()
->GetFrameView()
->LayoutViewport()
- ->SetScrollbarsHiddenIfOverlay(true);
+ ->SetScrollbarsHiddenForTesting(true);
// Ensure hittest has IFRAME and no scrollbar.
hit_test_result = HitTest(196, 5);
@@ -1510,8 +1540,9 @@ TEST_F(ScrollbarsTestWithVirtualTimer, TestNonCompositedOverlayScrollbarsFade) {
RunTasksForPeriod(kMockOverlayFadeOutDelay);
EXPECT_TRUE(scrollable_area->ScrollbarsHiddenIfOverlay());
- scrollable_area->SetScrollOffset(ScrollOffset(10, 10), kProgrammaticScroll,
- kScrollBehaviorInstant);
+ scrollable_area->SetScrollOffset(ScrollOffset(10, 10),
+ mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kInstant);
EXPECT_FALSE(scrollable_area->ScrollbarsHiddenIfOverlay());
RunTasksForPeriod(kMockOverlayFadeOutDelay);
@@ -1533,8 +1564,9 @@ TEST_F(ScrollbarsTestWithVirtualTimer, TestNonCompositedOverlayScrollbarsFade) {
// Non-composited scrollbars don't fade out while mouse is over.
EXPECT_TRUE(scrollable_area->VerticalScrollbar());
- scrollable_area->SetScrollOffset(ScrollOffset(20, 20), kProgrammaticScroll,
- kScrollBehaviorInstant);
+ scrollable_area->SetScrollOffset(ScrollOffset(20, 20),
+ mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kInstant);
EXPECT_FALSE(scrollable_area->ScrollbarsHiddenIfOverlay());
scrollable_area->MouseEnteredScrollbar(*scrollable_area->VerticalScrollbar());
RunTasksForPeriod(kMockOverlayFadeOutDelay);
@@ -1693,7 +1725,7 @@ TEST_P(ScrollbarAppearanceTest, HugeScrollingThumbPosition) {
Compositor().BeginFrame();
scrollable_area->SetScrollOffset(ScrollOffset(0, 10000000),
- kProgrammaticScroll);
+ mojom::blink::ScrollType::kProgrammatic);
Compositor().BeginFrame();
@@ -2124,7 +2156,7 @@ TEST_F(ScrollbarsTest,
PaintLayerScrollableArea* scrollable_div =
ToLayoutBox(div->GetLayoutObject())->GetScrollableArea();
- scrollable_div->SetScrollbarsHiddenIfOverlay(false);
+ scrollable_div->SetScrollbarsHiddenForTesting(false);
ASSERT_TRUE(scrollable_div);
ASSERT_TRUE(scrollable_div->GetPageScrollbarTheme().UsesOverlayScrollbars());
ASSERT_TRUE(scrollable_div->VerticalScrollbar());
@@ -2137,7 +2169,7 @@ TEST_F(ScrollbarsTest,
// After paint layer in scrollable dispose, we can still call scrollbar hidden
// just not change scrollbar.
- scrollable_div->SetScrollbarsHiddenIfOverlay(true);
+ scrollable_div->SetScrollbarsHiddenForTesting(true);
EXPECT_FALSE(scrollable_div->ScrollbarsHiddenIfOverlay());
}
@@ -2179,7 +2211,7 @@ TEST_F(ScrollbarsTest, PLSADisposeShouldClearPointerInLayers) {
ASSERT_TRUE(graphics_layer);
div->setAttribute(html_names::kClassAttr, "hide");
- document.UpdateStyleAndLayout();
+ document.UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_FALSE(paint_layer->GetScrollableArea());
}
@@ -2219,7 +2251,7 @@ TEST_F(ScrollbarsTest, OverlayScrollbarHitTest) {
.MainFrameImpl()
->GetFrameView()
->LayoutViewport()
- ->SetScrollbarsHiddenIfOverlay(false);
+ ->SetScrollbarsHiddenForTesting(false);
frame_resource.Complete("<!DOCTYPE html><body style='height: 999px'></body>");
Compositor().BeginFrame();
@@ -2230,7 +2262,7 @@ TEST_F(ScrollbarsTest, OverlayScrollbarHitTest) {
iframe_element->contentDocument()
->View()
->LayoutViewport()
- ->SetScrollbarsHiddenIfOverlay(false);
+ ->SetScrollbarsHiddenForTesting(false);
// Hit test on and off the main frame scrollbar.
HitTestResult hit_test_result = HitTest(295, 5);
@@ -2315,12 +2347,13 @@ TEST_F(ScrollbarsTest, MiddleDownShouldNotAffectScrollbarPress) {
EXPECT_EQ(scrollbar->PressedPart(), ScrollbarPart::kThumbPart);
// Move mouse out of scrollbar with press.
- WebMouseEvent event(WebInputEvent::kMouseMove, WebFloatPoint(5, 5),
- WebFloatPoint(5, 5), WebPointerProperties::Button::kLeft,
- 0, WebInputEvent::Modifiers::kLeftButtonDown,
+ WebMouseEvent event(WebInputEvent::kMouseMove, gfx::PointF(5, 5),
+ gfx::PointF(5, 5), WebPointerProperties::Button::kLeft, 0,
+ WebInputEvent::Modifiers::kLeftButtonDown,
base::TimeTicks::Now());
event.SetFrameScale(1);
- GetEventHandler().HandleMouseLeaveEvent(event);
+ GetEventHandler().HandleMouseMoveEvent(event, Vector<WebMouseEvent>(),
+ Vector<WebMouseEvent>());
EXPECT_EQ(scrollbar->PressedPart(), ScrollbarPart::kThumbPart);
// Middle click should not release scrollbar press state.
@@ -2614,7 +2647,7 @@ TEST_F(ScrollbarsTest, CheckScrollCornerIfThereIsNoScrollbar) {
// Make the container non-scrollable so the scrollbar and corner disappear.
element->setAttribute(html_names::kStyleAttr, "width: 100px;");
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_FALSE(scrollable_container->HasScrollbar());
EXPECT_FALSE(scrollable_container->ScrollCorner());
@@ -2675,8 +2708,9 @@ TEST_F(ScrollbarsTestWithVirtualTimer,
Scrollbar* scrollbar = scrollable_area->VerticalScrollbar();
// Scroll to bottom.
- scrollable_area->SetScrollOffset(ScrollOffset(0, 400), kProgrammaticScroll,
- kScrollBehaviorInstant);
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 400),
+ mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kInstant);
EXPECT_EQ(scrollable_area->ScrollOffsetInt(), IntSize(0, 200));
HandleMouseMoveEvent(195, 195);
@@ -2803,7 +2837,8 @@ INSTANTIATE_TEST_SUITE_P(NonOverlay,
TEST_P(ScrollbarColorSchemeTest, MAYBE_ThemeEnginePaint) {
ScopedTestingPlatformSupport<ScrollbarTestingPlatformSupport> platform;
- ScopedCSSColorSchemeForTest css_feature_scope(true);
+ ScopedCSSColorSchemeForTest color_scheme_scope(true);
+ ScopedCSSColorSchemeUARenderingForTest color_scheme_ua_scope(true);
WebView().MainFrameWidget()->Resize(WebSize(800, 600));
SimRequest request("https://example.com/test.html", "text/html");
@@ -2827,9 +2862,8 @@ TEST_P(ScrollbarColorSchemeTest, MAYBE_ThemeEnginePaint) {
</div>
)HTML");
- ColorSchemeHelper color_scheme_helper;
- color_scheme_helper.SetPreferredColorScheme(GetDocument(),
- PreferredColorScheme::kDark);
+ ColorSchemeHelper color_scheme_helper(GetDocument());
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kDark);
Compositor().BeginFrame();
diff --git a/chromium/third_party/blink/renderer/core/layout/shapes/shape.cc b/chromium/third_party/blink/renderer/core/layout/shapes/shape.cc
index f961184aee3..702e55999e0 100644
--- a/chromium/third_party/blink/renderer/core/layout/shapes/shape.cc
+++ b/chromium/third_party/blink/renderer/core/layout/shapes/shape.cc
@@ -234,7 +234,8 @@ std::unique_ptr<Shape> Shape::CreateEmptyRasterShape(WritingMode writing_mode,
static bool ExtractImageData(Image* image,
const IntSize& image_size,
- ArrayBufferContents& contents) {
+ ArrayBufferContents& contents,
+ RespectImageOrientationEnum respect_orientation) {
if (!image)
return false;
@@ -260,8 +261,8 @@ static bool ExtractImageData(Image* image,
canvas.clear(SK_ColorTRANSPARENT);
image->Draw(&canvas, flags, FloatRect(image_dest_rect), image_source_rect,
- kDoNotRespectImageOrientation,
- Image::kDoNotClampImageToSourceRect, Image::kSyncDecode);
+ respect_orientation, Image::kDoNotClampImageToSourceRect,
+ Image::kSyncDecode);
size_t size_in_bytes;
if (!StaticBitmapImage::GetSizeInBytes(image_dest_rect, color_params)
@@ -332,12 +333,14 @@ static bool IsValidRasterShapeSize(const IntSize& size) {
return size.Area() * 4 < max_image_size_bytes;
}
-std::unique_ptr<Shape> Shape::CreateRasterShape(Image* image,
- float threshold,
- const LayoutRect& image_r,
- const LayoutRect& margin_r,
- WritingMode writing_mode,
- float margin) {
+std::unique_ptr<Shape> Shape::CreateRasterShape(
+ Image* image,
+ float threshold,
+ const LayoutRect& image_r,
+ const LayoutRect& margin_r,
+ WritingMode writing_mode,
+ float margin,
+ RespectImageOrientationEnum respect_orientation) {
IntRect image_rect = PixelSnappedIntRect(image_r);
IntRect margin_rect = PixelSnappedIntRect(margin_r);
@@ -347,8 +350,10 @@ std::unique_ptr<Shape> Shape::CreateRasterShape(Image* image,
}
ArrayBufferContents contents;
- if (!ExtractImageData(image, image_rect.Size(), contents))
+ if (!ExtractImageData(image, image_rect.Size(), contents,
+ respect_orientation)) {
return CreateEmptyRasterShape(writing_mode, margin);
+ }
std::unique_ptr<RasterShapeIntervals> intervals =
ExtractIntervalsFromImageData(contents, threshold, image_rect,
diff --git a/chromium/third_party/blink/renderer/core/layout/shapes/shape.h b/chromium/third_party/blink/renderer/core/layout/shapes/shape.h
index 45be4d014bc..77f7cfacb31 100644
--- a/chromium/third_party/blink/renderer/core/layout/shapes/shape.h
+++ b/chromium/third_party/blink/renderer/core/layout/shapes/shape.h
@@ -35,6 +35,7 @@
#include "third_party/blink/renderer/core/style/basic_shapes.h"
#include "third_party/blink/renderer/core/style/style_image.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
+#include "third_party/blink/renderer/platform/graphics/image_orientation.h"
#include "third_party/blink/renderer/platform/graphics/path.h"
#include "third_party/blink/renderer/platform/text/writing_mode.h"
@@ -84,7 +85,8 @@ class CORE_EXPORT Shape {
const LayoutRect& image_rect,
const LayoutRect& margin_rect,
WritingMode,
- float margin);
+ float margin,
+ RespectImageOrientationEnum);
static std::unique_ptr<Shape> CreateLayoutBoxShape(const FloatRoundedRect&,
WritingMode,
float margin);
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 96cbb7e0912..c9f477b2f0d 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
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/core/layout/shapes/shape_outside_info.h"
#include <memory>
+
#include "base/auto_reset.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
@@ -39,6 +40,7 @@
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/layout_image.h"
#include "third_party/blink/renderer/platform/geometry/length_functions.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
namespace blink {
@@ -152,10 +154,10 @@ static bool CheckShapeImageOrigin(Document& document,
const KURL& url = image_resource.Url();
String url_string = url.IsNull() ? "''" : url.ElidedString();
- document.AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kError,
- "Unsafe attempt to load URL " + url_string + "."));
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kSecurity,
+ mojom::ConsoleMessageLevel::kError,
+ "Unsafe attempt to load URL " + url_string + "."));
return false;
}
@@ -186,7 +188,8 @@ std::unique_ptr<Shape> ShapeOutsideInfo::CreateShapeForImage(
DCHECK(!style_image->IsPendingImage());
const LayoutSize& image_size = RoundedLayoutSize(style_image->ImageSize(
layout_box_.GetDocument(), layout_box_.StyleRef().EffectiveZoom(),
- reference_box_logical_size_));
+ reference_box_logical_size_,
+ LayoutObject::ShouldRespectImageOrientation(&layout_box_)));
const LayoutRect& margin_rect =
GetShapeImageMarginRect(layout_box_, reference_box_logical_size_);
@@ -199,9 +202,9 @@ std::unique_ptr<Shape> ShapeOutsideInfo::CreateShapeForImage(
style_image->GetImage(layout_box_, layout_box_.GetDocument(),
layout_box_.StyleRef(), FloatSize(image_size));
- return Shape::CreateRasterShape(image.get(), shape_image_threshold,
- image_rect, margin_rect, writing_mode,
- margin);
+ return Shape::CreateRasterShape(
+ image.get(), shape_image_threshold, image_rect, margin_rect, writing_mode,
+ margin, LayoutObject::ShouldRespectImageOrientation(&layout_box_));
}
const Shape& ShapeOutsideInfo::ComputedShape() const {
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/BUILD.gn b/chromium/third_party/blink/renderer/core/layout/svg/BUILD.gn
index 3c0d78bbf16..b01361cc458 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/layout/svg/BUILD.gn
@@ -12,6 +12,8 @@ blink_core_sources("svg_layout") {
"layout_svg_container.h",
"layout_svg_ellipse.cc",
"layout_svg_ellipse.h",
+ "layout_svg_filter_primitive.cc",
+ "layout_svg_filter_primitive.h",
"layout_svg_foreign_object.cc",
"layout_svg_foreign_object.h",
"layout_svg_hidden_container.cc",
@@ -34,8 +36,6 @@ blink_core_sources("svg_layout") {
"layout_svg_resource_container.h",
"layout_svg_resource_filter.cc",
"layout_svg_resource_filter.h",
- "layout_svg_resource_filter_primitive.cc",
- "layout_svg_resource_filter_primitive.h",
"layout_svg_resource_gradient.cc",
"layout_svg_resource_gradient.h",
"layout_svg_resource_linear_gradient.cc",
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 8c8dfbfff4a..e95571ca527 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
@@ -82,11 +82,6 @@ class LayoutSVGBlock : public LayoutBlockFlow {
const HitTestLocation&,
const PhysicalOffset& accumulated_offset,
HitTestAction) override;
-
- // The inherited version doesn't check for SVG effects.
- bool PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const override {
- return false;
- }
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_container.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_container.cc
index c9085ba3376..da375b67877 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_container.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_container.cc
@@ -84,7 +84,7 @@ void LayoutSVGContainer::UpdateLayout() {
void LayoutSVGContainer::AddChild(LayoutObject* child,
LayoutObject* before_child) {
LayoutSVGModelObject::AddChild(child, before_child);
- SVGResourcesCache::ClientWasAddedToTree(*child, child->StyleRef());
+ SVGResourcesCache::ClientWasAddedToTree(*child);
bool should_isolate_descendants =
(child->IsBlendingAllowed() && child->StyleRef().HasBlendMode()) ||
@@ -172,7 +172,6 @@ void LayoutSVGContainer::UpdateCachedBoundaries() {
SVGLayoutSupport::ComputeContainerBoundingBoxes(
this, object_bounding_box_, object_bounding_box_valid_,
stroke_bounding_box_, local_visual_rect_);
- GetElement()->SetNeedsResizeObserverUpdate();
}
bool LayoutSVGContainer::NodeAtPoint(HitTestResult& result,
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_container.h b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_container.h
index ba23efa422d..c0ec38b1592 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_container.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_container.h
@@ -24,6 +24,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_LAYOUT_SVG_CONTAINER_H_
#include "third_party/blink/renderer/core/layout/svg/layout_svg_model_object.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -108,7 +109,12 @@ class LayoutSVGContainer : public LayoutSVGModelObject {
mutable bool has_non_isolated_blending_descendants_dirty_ : 1;
};
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutSVGContainer, IsSVGContainer());
+template <>
+struct DowncastTraits<LayoutSVGContainer> {
+ static bool AllowFrom(const LayoutObject& object) {
+ return object.IsSVGContainer();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter_primitive.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_filter_primitive.cc
index bbc7bb39112..7ab539720ab 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter_primitive.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_filter_primitive.cc
@@ -25,12 +25,16 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter_primitive.h"
+#include "third_party/blink/renderer/core/layout/svg/layout_svg_filter_primitive.h"
#include "third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.h"
namespace blink {
+LayoutSVGFilterPrimitive::LayoutSVGFilterPrimitive(
+ SVGFilterPrimitiveStandardAttributes* filter_primitive_element)
+ : LayoutObject(filter_primitive_element) {}
+
static bool CurrentColorChanged(StyleDifference diff, const StyleColor& color) {
return diff.TextDecorationOrColorChanged() && color.IsCurrentColor();
}
@@ -51,15 +55,11 @@ static void CheckForColorChange(SVGFilterPrimitiveStandardAttributes& element,
element.PrimitiveAttributeChanged(attr_name);
}
-void LayoutSVGResourceFilterPrimitive::StyleDidChange(
- StyleDifference diff,
- const ComputedStyle* old_style) {
- LayoutSVGHiddenContainer::StyleDidChange(diff, old_style);
-
+void LayoutSVGFilterPrimitive::StyleDidChange(StyleDifference diff,
+ const ComputedStyle* old_style) {
if (!old_style)
return;
- DCHECK(GetElement());
- auto& element = To<SVGFilterPrimitiveStandardAttributes>(*GetElement());
+ auto& element = To<SVGFilterPrimitiveStandardAttributes>(*GetNode());
const SVGComputedStyle& new_style = StyleRef().SvgStyle();
if (IsA<SVGFEFloodElement>(element) || IsA<SVGFEDropShadowElement>(element)) {
CheckForColorChange(element, svg_names::kFloodColorAttr, diff,
@@ -80,4 +80,8 @@ void LayoutSVGResourceFilterPrimitive::StyleDidChange(
}
}
+void LayoutSVGFilterPrimitive::UpdateLayout() {
+ ClearNeedsLayout();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter_primitive.h b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_filter_primitive.h
index d52bdae9df2..b0e16f447fe 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter_primitive.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_filter_primitive.h
@@ -24,34 +24,42 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_LAYOUT_SVG_RESOURCE_FILTER_PRIMITIVE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_LAYOUT_SVG_RESOURCE_FILTER_PRIMITIVE_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_LAYOUT_SVG_FILTER_PRIMITIVE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_LAYOUT_SVG_FILTER_PRIMITIVE_H_
-#include "third_party/blink/renderer/core/layout/svg/layout_svg_hidden_container.h"
+#include "third_party/blink/renderer/core/layout/layout_object.h"
namespace blink {
-class LayoutSVGResourceFilterPrimitive final : public LayoutSVGHiddenContainer {
+class SVGFilterPrimitiveStandardAttributes;
+
+class LayoutSVGFilterPrimitive final : public LayoutObject {
public:
- explicit LayoutSVGResourceFilterPrimitive(
- SVGElement* filter_primitive_element)
- : LayoutSVGHiddenContainer(filter_primitive_element) {}
+ explicit LayoutSVGFilterPrimitive(SVGFilterPrimitiveStandardAttributes*);
+ private:
bool IsChildAllowed(LayoutObject*, const ComputedStyle&) const override {
return false;
}
void StyleDidChange(StyleDifference, const ComputedStyle*) override;
+ void UpdateLayout() override;
- const char* GetName() const override {
- return "LayoutSVGResourceFilterPrimitive";
- }
+ const char* GetName() const override { return "LayoutSVGFilterPrimitive"; }
bool IsOfType(LayoutObjectType type) const override {
- return type == kLayoutObjectSVGResourceFilterPrimitive ||
- LayoutSVGHiddenContainer::IsOfType(type);
+ return type == kLayoutObjectSVG ||
+ type == kLayoutObjectSVGFilterPrimitive ||
+ LayoutObject::IsOfType(type);
+ }
+ FloatRect ObjectBoundingBox() const override { return FloatRect(); }
+ FloatRect VisualRectInLocalSVGCoordinates() const override {
+ return FloatRect();
+ }
+ FloatRect LocalBoundingBoxRectForAccessibility() const override {
+ return FloatRect();
}
};
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_LAYOUT_SVG_RESOURCE_FILTER_PRIMITIVE_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_LAYOUT_SVG_FILTER_PRIMITIVE_H_
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 838ac43a38f..9d38aab5c10 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
@@ -22,6 +22,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_LAYOUT_SVG_FOREIGN_OBJECT_H_
#include "third_party/blink/renderer/core/layout/svg/layout_svg_block.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -104,7 +105,12 @@ class LayoutSVGForeignObject final : public LayoutSVGBlock {
bool needs_transform_update_;
};
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutSVGForeignObject, IsSVGForeignObject());
+template <>
+struct DowncastTraits<LayoutSVGForeignObject> {
+ static bool AllowFrom(const LayoutObject& object) {
+ return object.IsSVGForeignObject();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_hidden_container.h b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_hidden_container.h
index 6f01462ff3c..06e9e78248a 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_hidden_container.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_hidden_container.h
@@ -45,9 +45,6 @@ class LayoutSVGHiddenContainer : public LayoutSVGContainer {
private:
// LayoutSVGHiddenContainer paints nothing.
void Paint(const PaintInfo&) const final {}
- bool PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const final {
- return true;
- }
PhysicalRect VisualRectInDocument(VisualRectFlags) const final {
return PhysicalRect();
}
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_image.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_image.cc
index df479631785..964f0769a77 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_image.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_image.cc
@@ -27,8 +27,10 @@
#include "third_party/blink/renderer/core/html/media/media_element_parser_helpers.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
+#include "third_party/blink/renderer/core/layout/intrinsic_sizing_info.h"
#include "third_party/blink/renderer/core/layout/layout_analyzer.h"
#include "third_party/blink/renderer/core/layout/layout_image_resource.h"
+#include "third_party/blink/renderer/core/layout/layout_replaced.h"
#include "third_party/blink/renderer/core/layout/pointer_events_hit_rules.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.h"
#include "third_party/blink/renderer/core/layout/svg/svg_layout_support.h"
@@ -38,6 +40,7 @@
#include "third_party/blink/renderer/core/layout/svg/transformed_hit_test_location.h"
#include "third_party/blink/renderer/core/paint/image_element_timing.h"
#include "third_party/blink/renderer/core/paint/svg_image_painter.h"
+#include "third_party/blink/renderer/core/svg/graphics/svg_image.h"
#include "third_party/blink/renderer/core/svg/svg_image_element.h"
#include "third_party/blink/renderer/platform/geometry/length_functions.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_record.h"
@@ -78,37 +81,55 @@ static float ResolveHeightForRatio(float width,
return width * intrinsic_ratio.Height() / intrinsic_ratio.Width();
}
-IntSize LayoutSVGImage::GetOverriddenIntrinsicSize() const {
- if (auto* svg_image = DynamicTo<SVGImageElement>(GetElement())) {
- if (RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled())
- return svg_image->GetOverriddenIntrinsicSize();
- }
- return IntSize();
+bool LayoutSVGImage::HasOverriddenIntrinsicSize() const {
+ if (!RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled())
+ return false;
+ auto* svg_image_element = DynamicTo<SVGImageElement>(GetElement());
+ return svg_image_element && svg_image_element->IsDefaultIntrinsicSize();
}
FloatSize LayoutSVGImage::CalculateObjectSize() const {
- FloatSize intrinsic_size = FloatSize(GetOverriddenIntrinsicSize());
+ FloatSize intrinsic_size;
ImageResourceContent* cached_image = image_resource_->CachedImage();
- if (intrinsic_size.IsEmpty()) {
+ bool has_intrinsic_ratio = true;
+ if (HasOverriddenIntrinsicSize()) {
+ intrinsic_size = FloatSize(LayoutReplaced::kDefaultWidth,
+ LayoutReplaced::kDefaultHeight);
+ } else {
if (!cached_image || cached_image->ErrorOccurred() ||
!cached_image->IsSizeAvailable())
return object_bounding_box_.Size();
- intrinsic_size = FloatSize(cached_image->GetImage()->Size());
+ RespectImageOrientationEnum respect_orientation =
+ LayoutObject::ShouldRespectImageOrientation(this);
+ intrinsic_size = cached_image->GetImage()->SizeAsFloat(respect_orientation);
+ if (auto* svg_image = DynamicTo<SVGImage>(cached_image->GetImage())) {
+ IntrinsicSizingInfo intrinsic_sizing_info;
+ has_intrinsic_ratio &= svg_image->GetIntrinsicSizingInfo(intrinsic_sizing_info);
+ has_intrinsic_ratio &= !intrinsic_sizing_info.aspect_ratio.IsEmpty();
+ }
}
if (StyleRef().Width().IsAuto() && StyleRef().Height().IsAuto())
return intrinsic_size;
- if (StyleRef().Height().IsAuto())
- return FloatSize(
- object_bounding_box_.Width(),
- ResolveHeightForRatio(object_bounding_box_.Width(), intrinsic_size));
+ if (StyleRef().Height().IsAuto()) {
+ if (has_intrinsic_ratio) {
+ return FloatSize(
+ object_bounding_box_.Width(),
+ ResolveHeightForRatio(object_bounding_box_.Width(), intrinsic_size));
+ }
+ return FloatSize(object_bounding_box_.Width(), intrinsic_size.Height());
+ }
DCHECK(StyleRef().Width().IsAuto());
- return FloatSize(
- ResolveWidthForRatio(object_bounding_box_.Height(), intrinsic_size),
- object_bounding_box_.Height());
+ if (has_intrinsic_ratio) {
+ return FloatSize(
+ ResolveWidthForRatio(object_bounding_box_.Height(), intrinsic_size),
+ object_bounding_box_.Height());
+ }
+
+ return FloatSize(intrinsic_size.Width(), object_bounding_box_.Height());
}
bool LayoutSVGImage::UpdateBoundingBox() {
@@ -126,7 +147,6 @@ bool LayoutSVGImage::UpdateBoundingBox() {
object_bounding_box_.SetSize(CalculateObjectSize());
if (old_object_bounding_box != object_bounding_box_) {
- GetElement()->SetNeedsResizeObserverUpdate();
SetShouldDoFullPaintInvalidation(PaintInvalidationReason::kImage);
needs_boundaries_update_ = true;
}
@@ -174,7 +194,7 @@ void LayoutSVGImage::UpdateLayout() {
DCHECK(!needs_transform_update_);
if (auto* svg_image_element = DynamicTo<SVGImageElement>(GetElement())) {
- media_element_parser_helpers::ReportUnsizedMediaViolation(
+ media_element_parser_helpers::CheckUnsizedMediaViolation(
this, svg_image_element->IsDefaultIntrinsicSize());
}
ClearNeedsLayout();
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_image.h b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_image.h
index a56500db2f8..bc8b9227afa 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_image.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_image.h
@@ -80,7 +80,7 @@ class LayoutSVGImage final : public LayoutSVGModelObject {
}
FloatSize CalculateObjectSize() const;
- IntSize GetOverriddenIntrinsicSize() const;
+ bool HasOverriddenIntrinsicSize() const;
bool needs_boundaries_update_ : 1;
bool needs_transform_update_ : 1;
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc
index 78e884af5cf..04b832c1ddf 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc
@@ -60,27 +60,27 @@ InlineFlowBox* LayoutSVGInline::CreateInlineFlowBox() {
}
FloatRect LayoutSVGInline::ObjectBoundingBox() const {
- if (const LayoutSVGText* text_root =
- LayoutSVGText::LocateLayoutSVGTextAncestor(this))
- return text_root->ObjectBoundingBox();
-
- return FloatRect();
+ FloatRect bounds;
+ for (InlineFlowBox* box : *LineBoxes())
+ bounds.Unite(FloatRect(box->FrameRect()));
+ return bounds;
}
FloatRect LayoutSVGInline::StrokeBoundingBox() const {
- if (const LayoutSVGText* text_root =
- LayoutSVGText::LocateLayoutSVGTextAncestor(this))
- return text_root->StrokeBoundingBox();
-
- return FloatRect();
+ if (!FirstLineBox())
+ return FloatRect();
+ return SVGLayoutSupport::ExtendTextBBoxWithStroke(*this, ObjectBoundingBox());
}
FloatRect LayoutSVGInline::VisualRectInLocalSVGCoordinates() const {
- if (const LayoutSVGText* text_root =
- LayoutSVGText::LocateLayoutSVGTextAncestor(this))
- return text_root->VisualRectInLocalSVGCoordinates();
-
- return FloatRect();
+ if (!FirstLineBox())
+ return FloatRect();
+ const LayoutSVGText* text_root =
+ LayoutSVGText::LocateLayoutSVGTextAncestor(this);
+ if (!text_root)
+ return FloatRect();
+ return SVGLayoutSupport::ComputeVisualRectForText(
+ *this, ObjectBoundingBox(), text_root->ObjectBoundingBox());
}
PhysicalRect LayoutSVGInline::VisualRectInDocument(
@@ -103,18 +103,10 @@ const LayoutObject* LayoutSVGInline::PushMappingToContainer(
void LayoutSVGInline::AbsoluteQuads(Vector<FloatQuad>& quads,
MapCoordinatesFlags mode) const {
- const LayoutSVGText* text_root =
- LayoutSVGText::LocateLayoutSVGTextAncestor(this);
- if (!text_root)
- return;
-
- FloatRect text_bounding_box = text_root->StrokeBoundingBox();
for (InlineFlowBox* box : *LineBoxes()) {
+ FloatRect box_rect(box->FrameRect());
quads.push_back(LocalToAbsoluteQuad(
- FloatRect(text_bounding_box.X() + box->X().ToFloat(),
- text_bounding_box.Y() + box->Y().ToFloat(),
- box->Width().ToFloat(), box->Height().ToFloat()),
- mode));
+ SVGLayoutSupport::ExtendTextBBoxWithStroke(*this, box_rect), mode));
}
}
@@ -145,19 +137,15 @@ void LayoutSVGInline::StyleDidChange(StyleDifference diff,
void LayoutSVGInline::AddChild(LayoutObject* child,
LayoutObject* before_child) {
LayoutInline::AddChild(child, before_child);
- SVGResourcesCache::ClientWasAddedToTree(*child, child->StyleRef());
-
- if (LayoutSVGText* text_layout_object =
- LayoutSVGText::LocateLayoutSVGTextAncestor(this))
- text_layout_object->SubtreeChildWasAdded();
+ SVGResourcesCache::ClientWasAddedToTree(*child);
+ LayoutSVGText::NotifySubtreeStructureChanged(
+ this, layout_invalidation_reason::kChildChanged);
}
void LayoutSVGInline::RemoveChild(LayoutObject* child) {
SVGResourcesCache::ClientWillBeRemovedFromTree(*child);
-
- if (LayoutSVGText* text_layout_object =
- LayoutSVGText::LocateLayoutSVGTextAncestor(this))
- text_layout_object->SubtreeChildWillBeRemoved();
+ LayoutSVGText::NotifySubtreeStructureChanged(
+ this, layout_invalidation_reason::kChildChanged);
LayoutInline::RemoveChild(child);
}
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h
index 6322b6218cd..19b362d26fa 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h
@@ -38,11 +38,6 @@ class LayoutSVGInline : public LayoutInline {
bool IsChildAllowed(LayoutObject*, const ComputedStyle&) const override;
- // Chapter 10.4 of the SVG Specification say that we should use the
- // object bounding box of the parent text element.
- // We search for the root text element and take its bounding box.
- // It is also necessary to take the stroke and visual rect of this element,
- // since we need it for filters.
FloatRect ObjectBoundingBox() const final;
FloatRect StrokeBoundingBox() const final;
FloatRect VisualRectInLocalSVGCoordinates() const final;
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.cc
index 5a089322736..4df02e440c4 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_inline_text.cc
@@ -59,9 +59,8 @@ LayoutSVGInlineText::LayoutSVGInlineText(Node* n,
void LayoutSVGInlineText::TextDidChange() {
SetTextInternal(NormalizeWhitespace(GetText().Impl()));
LayoutText::TextDidChange();
- if (LayoutSVGText* text_layout_object =
- LayoutSVGText::LocateLayoutSVGTextAncestor(this))
- text_layout_object->SubtreeTextDidChange();
+ LayoutSVGText::NotifySubtreeStructureChanged(
+ this, layout_invalidation_reason::kTextChanged);
}
void LayoutSVGInlineText::StyleDidChange(StyleDifference diff,
@@ -69,10 +68,9 @@ void LayoutSVGInlineText::StyleDidChange(StyleDifference diff,
LayoutText::StyleDidChange(diff, old_style);
UpdateScaledFont();
- bool new_preserves =
- Style() ? StyleRef().WhiteSpace() == EWhiteSpace::kPre : false;
+ bool new_preserves = StyleRef().WhiteSpace() == EWhiteSpace::kPre;
bool old_preserves =
- old_style ? old_style->WhiteSpace() == EWhiteSpace::kPre : false;
+ old_style && old_style->WhiteSpace() == EWhiteSpace::kPre;
if (old_preserves != new_preserves) {
ForceSetText(OriginalText());
return;
@@ -153,7 +151,7 @@ bool LayoutSVGInlineText::CharacterStartsNewTextChunk(int position) const {
PositionWithAffinity LayoutSVGInlineText::PositionForPoint(
const PhysicalOffset& point) const {
- if (!HasTextBoxes() || !TextLength())
+ if (!HasInlineFragments() || !TextLength())
return CreatePositionWithAffinity(0);
DCHECK(scaling_factor_);
@@ -178,10 +176,10 @@ PositionWithAffinity LayoutSVGInlineText::PositionForPoint(
SVGInlineTextBox* closest_distance_box = nullptr;
for (InlineTextBox* box : TextBoxes()) {
- if (!box->IsSVGInlineTextBox())
+ auto* text_box = DynamicTo<SVGInlineTextBox>(box);
+ if (!text_box)
continue;
- SVGInlineTextBox* text_box = ToSVGInlineTextBox(box);
for (const SVGTextFragment& fragment : text_box->TextFragments()) {
FloatRect fragment_rect = fragment.BoundingBox(baseline);
@@ -416,8 +414,8 @@ void LayoutSVGInlineText::ComputeNewScaledFontForStyle(
FontDescription font_description = unscaled_font_description;
font_description.SetComputedSize(scaled_font_size);
- scaled_font = Font(font_description);
- scaled_font.Update(document.GetStyleEngine().GetFontSelector());
+ scaled_font =
+ Font(font_description, document.GetStyleEngine().GetFontSelector());
}
PhysicalRect LayoutSVGInlineText::VisualRectInDocument(
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_path.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_path.cc
index 61279e3cb9b..9f5bd0a1a6a 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_path.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_path.cc
@@ -56,6 +56,12 @@ void LayoutSVGPath::UpdateShapeFromElement() {
UpdateMarkers();
}
+const StylePath* LayoutSVGPath::GetStylePath() const {
+ if (!IsA<SVGPathElement>(*GetElement()))
+ return nullptr;
+ return StyleRef().SvgStyle().D();
+}
+
void LayoutSVGPath::UpdateMarkers() {
marker_positions_.clear();
@@ -74,12 +80,16 @@ void LayoutSVGPath::UpdateMarkers() {
if (!(marker_start || marker_mid || marker_end))
return;
- SVGMarkerDataBuilder(marker_positions_).Build(GetPath());
+ SVGMarkerDataBuilder builder(marker_positions_);
+ if (const StylePath* style_path = GetStylePath())
+ builder.Build(style_path->ByteStream());
+ else
+ builder.Build(GetPath());
if (marker_positions_.IsEmpty())
return;
- const float stroke_width = StrokeWidth();
+ const float stroke_width = StrokeWidthForMarkerUnits();
FloatRect boundaries;
for (const auto& position : marker_positions_) {
if (LayoutSVGResourceMarker* marker =
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_path.h b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_path.h
index 94cdea0c76c..97b0056bd1b 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_path.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_path.h
@@ -47,6 +47,7 @@ class LayoutSVGPath final : public LayoutSVGShape {
void UpdateShapeFromElement() override;
+ const StylePath* GetStylePath() const;
void UpdateMarkers();
Vector<MarkerPosition> marker_positions_;
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 8778ec876b2..fcfbf011d02 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
@@ -95,8 +95,8 @@ bool ContributesToClip(const SVGElement& element) {
}
Path PathFromElement(const SVGElement& element) {
- if (IsSVGGeometryElement(element))
- return ToSVGGeometryElement(element).ToClipPath();
+ if (auto* geometry_element = DynamicTo<SVGGeometryElement>(element))
+ return geometry_element->ToClipPath();
// Guaranteed by DetermineClipStrategy() above, only <use> element and
// SVGGraphicsElement that has a LayoutSVGShape can reach here.
@@ -106,20 +106,17 @@ Path PathFromElement(const SVGElement& element) {
} // namespace
LayoutSVGResourceClipper::LayoutSVGResourceClipper(SVGClipPathElement* node)
- : LayoutSVGResourceContainer(node), in_clip_expansion_(false) {}
+ : LayoutSVGResourceContainer(node) {}
LayoutSVGResourceClipper::~LayoutSVGResourceClipper() = default;
-void LayoutSVGResourceClipper::RemoveAllClientsFromCache(
- bool mark_for_invalidation) {
+void LayoutSVGResourceClipper::RemoveAllClientsFromCache() {
clip_content_path_validity_ = kClipContentPathUnknown;
clip_content_path_.Clear();
cached_paint_record_.reset();
local_clip_bounds_ = FloatRect();
- MarkAllClientsForInvalidation(
- mark_for_invalidation ? SVGResourceClient::kLayoutInvalidation |
- SVGResourceClient::kBoundariesInvalidation
- : SVGResourceClient::kParentOnlyInvalidation);
+ MarkAllClientsForInvalidation(SVGResourceClient::kLayoutInvalidation |
+ SVGResourceClient::kBoundariesInvalidation);
}
base::Optional<Path> LayoutSVGResourceClipper::AsPath() {
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.h b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.h
index b8f71fbb74e..661f7b0dd95 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.h
@@ -21,6 +21,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_LAYOUT_SVG_RESOURCE_CLIPPER_H_
#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.h"
+#include "third_party/blink/renderer/core/style/reference_clip_path_operation.h"
#include "third_party/blink/renderer/core/svg/svg_unit_types.h"
#include "third_party/skia/include/core/SkRefCnt.h"
@@ -35,7 +36,7 @@ class LayoutSVGResourceClipper final : public LayoutSVGResourceContainer {
const char* GetName() const override { return "LayoutSVGResourceClipper"; }
- void RemoveAllClientsFromCache(bool mark_for_invalidation = true) override;
+ void RemoveAllClientsFromCache() override;
FloatRect ResourceBoundingBox(const FloatRect& reference_box);
@@ -50,16 +51,6 @@ class LayoutSVGResourceClipper final : public LayoutSVGResourceContainer {
base::Optional<Path> AsPath();
sk_sp<const PaintRecord> CreatePaintRecord();
- bool HasCycle() { return in_clip_expansion_; }
- void BeginClipExpansion() {
- DCHECK(!in_clip_expansion_);
- in_clip_expansion_ = true;
- }
- void EndClipExpansion() {
- DCHECK(in_clip_expansion_);
- in_clip_expansion_ = false;
- }
-
protected:
void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
void WillBeDestroyed() override;
@@ -80,14 +71,21 @@ class LayoutSVGResourceClipper final : public LayoutSVGResourceContainer {
sk_sp<const PaintRecord> cached_paint_record_;
FloatRect local_clip_bounds_;
-
- // Reference cycle detection.
- bool in_clip_expansion_;
};
DEFINE_LAYOUT_SVG_RESOURCE_TYPE_CASTS(LayoutSVGResourceClipper,
kClipperResourceType);
+inline LayoutSVGResourceClipper* GetSVGResourceAsType(
+ const ClipPathOperation* clip_path_operation) {
+ const auto* reference_clip =
+ DynamicTo<ReferenceClipPathOperation>(clip_path_operation);
+ if (!reference_clip)
+ return nullptr;
+ return GetSVGResourceAsType<LayoutSVGResourceClipper>(
+ reference_clip->Resource());
+}
+
} // namespace blink
#endif
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.cc
index ce06ebc5c63..da7fd935d74 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.cc
@@ -22,6 +22,7 @@
#include "base/auto_reset.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/svg_resources_cycle_solver.h"
#include "third_party/blink/renderer/core/svg/svg_resource.h"
#include "third_party/blink/renderer/core/svg/svg_tree_scope_resources.h"
@@ -83,12 +84,66 @@ void LayoutSVGResourceContainer::StyleDidChange(
resource->NotifyResourceAttached(*this);
}
+bool LayoutSVGResourceContainer::FindCycle(
+ SVGResourcesCycleSolver& solver) const {
+ if (solver.IsKnownAcyclic(this))
+ return false;
+ SVGResourcesCycleSolver::Scope scope(solver);
+ if (!scope.Enter(this) || FindCycleFromSelf(solver))
+ return true;
+ solver.AddAcyclicSubgraph(this);
+ return false;
+}
+
+bool LayoutSVGResourceContainer::FindCycleInResources(
+ SVGResourcesCycleSolver& solver,
+ const LayoutObject& layout_object) const {
+ SVGResources* resources =
+ SVGResourcesCache::CachedResourcesForLayoutObject(layout_object);
+ if (!resources)
+ return false;
+ // Fetch all the referenced resources.
+ HashSet<LayoutSVGResourceContainer*> local_resources;
+ resources->BuildSetOfResources(local_resources);
+ // This performs a depth-first search for a back-edge in all the
+ // (potentially disjoint) graphs formed by the referenced resources.
+ for (auto* local_resource : local_resources) {
+ if (local_resource->FindCycle(solver))
+ return true;
+ }
+ return false;
+}
+
+bool LayoutSVGResourceContainer::FindCycleFromSelf(
+ SVGResourcesCycleSolver& solver) const {
+ if (FindCycleInResources(solver, *this))
+ return true;
+ return FindCycleInDescendants(solver);
+}
+
+bool LayoutSVGResourceContainer::FindCycleInDescendants(
+ SVGResourcesCycleSolver& solver) const {
+ LayoutObject* node = FirstChild();
+ while (node) {
+ // Skip subtrees which are themselves resources. (They will be
+ // processed - if needed - when they are actually referenced.)
+ if (node->IsSVGResourceContainer()) {
+ node = node->NextInPreOrderAfterChildren(this);
+ continue;
+ }
+ if (FindCycleInResources(solver, *node))
+ return true;
+ node = node->NextInPreOrder(this);
+ }
+ return false;
+}
+
void LayoutSVGResourceContainer::MarkAllClientsForInvalidation(
InvalidationModeMask invalidation_mask) {
if (is_invalidating_)
return;
LocalSVGResource* resource = ResourceForContainer(*this);
- if (!resource || !resource->HasClients())
+ if (!resource)
return;
// Remove modes for which invalidations have already been
// performed. If no modes remain we are done.
@@ -100,8 +155,7 @@ void LayoutSVGResourceContainer::MarkAllClientsForInvalidation(
is_invalidating_ = true;
// Invalidate clients registered via an SVGResource.
- if (resource)
- resource->NotifyContentChanged(invalidation_mask);
+ resource->NotifyContentChanged(invalidation_mask);
is_invalidating_ = false;
}
@@ -154,7 +208,7 @@ static inline void RemoveFromCacheAndInvalidateDependencies(
if (SVGResources* resources =
SVGResourcesCache::CachedResourcesForLayoutObject(object)) {
- SVGResourceClient* client = element->GetSVGResourceClient();
+ SVGElementResourceClient* client = element->GetSVGResourceClient();
if (InvalidationModeMask invalidation_mask =
resources->RemoveClientFromCacheAffectingObjectBounds(*client)) {
LayoutSVGResourceContainer::MarkClientForInvalidation(object,
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.h b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.h
index 56cfe674218..9e5ef616025 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.h
@@ -21,10 +21,14 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_LAYOUT_SVG_RESOURCE_CONTAINER_H_
#include "third_party/blink/renderer/core/layout/svg/layout_svg_hidden_container.h"
+#include "third_party/blink/renderer/core/style/style_svg_resource.h"
+#include "third_party/blink/renderer/core/svg/svg_resource.h"
#include "third_party/blink/renderer/core/svg/svg_resource_client.h"
namespace blink {
+class SVGResourcesCycleSolver;
+
enum LayoutSVGResourceType {
kMaskerResourceType,
kMarkerResourceType,
@@ -40,7 +44,7 @@ class LayoutSVGResourceContainer : public LayoutSVGHiddenContainer {
explicit LayoutSVGResourceContainer(SVGElement*);
~LayoutSVGResourceContainer() override;
- virtual void RemoveAllClientsFromCache(bool mark_for_invalidation = true) = 0;
+ virtual void RemoveAllClientsFromCache() = 0;
// Remove any cached data for the |client|, and return true if so.
virtual bool RemoveClientFromCache(SVGResourceClient&) { return false; }
@@ -64,6 +68,8 @@ class LayoutSVGResourceContainer : public LayoutSVGHiddenContainer {
SubtreeLayoutScope* = nullptr);
void InvalidateCacheAndMarkForLayout(SubtreeLayoutScope* = nullptr);
+ bool FindCycle(SVGResourcesCycleSolver&) const;
+
static void MarkForLayoutAndParentResourceInvalidation(
LayoutObject&,
bool needs_layout = true);
@@ -75,6 +81,11 @@ class LayoutSVGResourceContainer : public LayoutSVGHiddenContainer {
// Used from RemoveAllClientsFromCache methods.
void MarkAllClientsForInvalidation(InvalidationModeMask);
+ bool FindCycleFromSelf(SVGResourcesCycleSolver&) const;
+ bool FindCycleInDescendants(SVGResourcesCycleSolver&) const;
+ bool FindCycleInResources(SVGResourcesCycleSolver&,
+ const LayoutObject&) const;
+
void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
void WillBeDestroyed() override;
@@ -97,6 +108,30 @@ DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutSVGResourceContainer,
resource->ResourceType() == typeName, \
resource.ResourceType() == typeName)
+template <typename ContainerType>
+inline bool IsResourceOfType(const LayoutSVGResourceContainer* container) {
+ return container->ResourceType() == ContainerType::kResourceType;
+}
+
+template <typename ContainerType>
+inline ContainerType* GetSVGResourceAsType(const SVGResource* resource) {
+ if (!resource)
+ return nullptr;
+ if (LayoutSVGResourceContainer* container = resource->ResourceContainer()) {
+ if (IsResourceOfType<ContainerType>(container))
+ return static_cast<ContainerType*>(container);
+ }
+ return nullptr;
+}
+
+template <typename ContainerType>
+inline ContainerType* GetSVGResourceAsType(
+ const StyleSVGResource* style_resource) {
+ if (!style_resource)
+ return nullptr;
+ return GetSVGResourceAsType<ContainerType>(style_resource->Resource());
+}
+
} // namespace blink
#endif
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 9fcc0e045dd..09784e4b5e8 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
@@ -23,66 +23,23 @@
#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.h"
-#include "third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.h"
#include "third_party/blink/renderer/core/svg/svg_filter_element.h"
-#include "third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.h"
-#include "third_party/blink/renderer/core/svg/svg_resource.h"
namespace blink {
-void FilterData::Trace(blink::Visitor* visitor) {
- visitor->Trace(last_effect);
- visitor->Trace(node_map);
-}
-
-void FilterData::Dispose() {
- node_map = nullptr;
- if (last_effect)
- last_effect->DisposeImageFiltersRecursive();
- last_effect = nullptr;
-}
-
LayoutSVGResourceFilter::LayoutSVGResourceFilter(SVGFilterElement* node)
- : LayoutSVGResourceContainer(node),
- filter_(MakeGarbageCollected<FilterMap>()) {}
+ : LayoutSVGResourceContainer(node) {}
LayoutSVGResourceFilter::~LayoutSVGResourceFilter() = default;
-void LayoutSVGResourceFilter::DisposeFilterMap() {
- for (auto& entry : *filter_)
- entry.value->Dispose();
- filter_->clear();
-}
-
-void LayoutSVGResourceFilter::WillBeDestroyed() {
- DisposeFilterMap();
- LayoutSVGResourceContainer::WillBeDestroyed();
-}
-
bool LayoutSVGResourceFilter::IsChildAllowed(LayoutObject* child,
const ComputedStyle&) const {
- return child->IsSVGResourceFilterPrimitive();
-}
-
-void LayoutSVGResourceFilter::RemoveAllClientsFromCache(
- bool mark_for_invalidation) {
- // LayoutSVGResourceFilter::removeClientFromCache will be called for
- // all clients through markAllClientsForInvalidation so no explicit
- // display item invalidation is needed here.
- DisposeFilterMap();
- MarkAllClientsForInvalidation(
- mark_for_invalidation ? SVGResourceClient::kLayoutInvalidation |
- SVGResourceClient::kBoundariesInvalidation
- : SVGResourceClient::kParentOnlyInvalidation);
+ return child->IsSVGFilterPrimitive();
}
-bool LayoutSVGResourceFilter::RemoveClientFromCache(SVGResourceClient& client) {
- auto entry = filter_->find(&client);
- if (entry == filter_->end())
- return false;
- entry->value->Dispose();
- filter_->erase(entry);
- return true;
+void LayoutSVGResourceFilter::RemoveAllClientsFromCache() {
+ MarkAllClientsForInvalidation(SVGResourceClient::kLayoutInvalidation |
+ SVGResourceClient::kBoundariesInvalidation);
}
FloatRect LayoutSVGResourceFilter::ResourceBoundingBox(
@@ -106,32 +63,18 @@ SVGUnitTypes::SVGUnitType LayoutSVGResourceFilter::PrimitiveUnits() const {
->EnumValue();
}
-void LayoutSVGResourceFilter::PrimitiveAttributeChanged(
- SVGFilterPrimitiveStandardAttributes& primitive,
- const QualifiedName& attribute) {
- LayoutObject* object = primitive.GetLayoutObject();
-
- for (auto& filter : *filter_) {
- FilterData* filter_data = filter.value.Get();
- if (filter_data->state_ != FilterData::kReadyToPaint)
- continue;
-
- SVGFilterGraphNodeMap* node_map = filter_data->node_map.Get();
- FilterEffect* effect = node_map->EffectByRenderer(object);
- if (!effect)
- continue;
- // Since all effects shares the same attribute value, all
- // or none of them will be changed.
- if (!primitive.SetFilterEffectAttribute(effect, attribute))
- return;
- node_map->InvalidateDependentEffects(effect);
- }
- if (auto* resource =
- To<SVGFilterElement>(GetElement())->AssociatedResource()) {
- resource->NotifyContentChanged(
- SVGResourceClient::kPaintInvalidation |
- SVGResourceClient::kSkipAncestorInvalidation);
- }
+LayoutSVGResourceFilter* GetFilterResourceForSVG(const ComputedStyle& style) {
+ if (!style.HasFilter())
+ return nullptr;
+ const FilterOperations& operations = style.Filter();
+ if (operations.size() != 1)
+ return nullptr;
+ const auto* reference_filter =
+ DynamicTo<ReferenceFilterOperation>(*operations.at(0));
+ if (!reference_filter)
+ return nullptr;
+ return GetSVGResourceAsType<LayoutSVGResourceFilter>(
+ reference_filter->Resource());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.h b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.h
index 49907fcf609..e1584b2f26c 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.h
@@ -29,39 +29,7 @@
namespace blink {
-class FilterEffect;
class SVGFilterElement;
-class SVGFilterGraphNodeMap;
-class SVGFilterPrimitiveStandardAttributes;
-
-class FilterData final : public GarbageCollected<FilterData> {
- public:
- /*
- * The state transitions should follow the following:
- * Initial->RecordingContent->ReadyToPaint->PaintingFilter->ReadyToPaint
- * | ^ | ^
- * v | v |
- * RecordingContentCycleDetected PaintingFilterCycle
- */
- enum FilterDataState {
- kInitial,
- kRecordingContent,
- kRecordingContentCycleDetected,
- kReadyToPaint,
- kPaintingFilter,
- kPaintingFilterCycleDetected
- };
-
- FilterData() : state_(kInitial) {}
-
- void Dispose();
-
- void Trace(blink::Visitor*);
-
- Member<FilterEffect> last_effect;
- Member<SVGFilterGraphNodeMap> node_map;
- FilterDataState state_;
-};
class LayoutSVGResourceFilter final : public LayoutSVGResourceContainer {
public:
@@ -71,44 +39,24 @@ class LayoutSVGResourceFilter final : public LayoutSVGResourceContainer {
bool IsChildAllowed(LayoutObject*, const ComputedStyle&) const override;
const char* GetName() const override { return "LayoutSVGResourceFilter"; }
- bool IsOfType(LayoutObjectType type) const override {
- return type == kLayoutObjectSVGResourceFilter ||
- LayoutSVGResourceContainer::IsOfType(type);
- }
- void RemoveAllClientsFromCache(bool mark_for_invalidation = true) override;
- bool RemoveClientFromCache(SVGResourceClient&) override;
+ void RemoveAllClientsFromCache() override;
FloatRect ResourceBoundingBox(const FloatRect& reference_box) const;
SVGUnitTypes::SVGUnitType FilterUnits() const;
SVGUnitTypes::SVGUnitType PrimitiveUnits() const;
- void PrimitiveAttributeChanged(SVGFilterPrimitiveStandardAttributes&,
- const QualifiedName&);
-
static const LayoutSVGResourceType kResourceType = kFilterResourceType;
LayoutSVGResourceType ResourceType() const override { return kResourceType; }
-
- FilterData* GetFilterDataForClient(const SVGResourceClient* client) {
- return filter_->at(const_cast<SVGResourceClient*>(client));
- }
- void SetFilterDataForClient(const SVGResourceClient* client,
- FilterData* filter_data) {
- filter_->Set(const_cast<SVGResourceClient*>(client), filter_data);
- }
-
- protected:
- void WillBeDestroyed() override;
-
- private:
- void DisposeFilterMap();
-
- using FilterMap = HeapHashMap<Member<SVGResourceClient>, Member<FilterData>>;
- Persistent<FilterMap> filter_;
};
-DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutSVGResourceFilter, IsSVGResourceFilter());
+// Get the LayoutSVGResourceFilter from the 'filter' property iff the 'filter'
+// is a single url(...) reference.
+LayoutSVGResourceFilter* GetFilterResourceForSVG(const ComputedStyle&);
+
+DEFINE_LAYOUT_SVG_RESOURCE_TYPE_CASTS(LayoutSVGResourceFilter,
+ kFilterResourceType);
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_gradient.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_gradient.cc
index 62d1617857a..2461347012a 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_gradient.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_gradient.cc
@@ -24,21 +24,28 @@
#include <memory>
+#include "third_party/blink/renderer/platform/graphics/gradient.h"
+
namespace blink {
+struct GradientData {
+ USING_FAST_MALLOC(GradientData);
+
+ public:
+ scoped_refptr<Gradient> gradient;
+ AffineTransform userspace_transform;
+};
+
LayoutSVGResourceGradient::LayoutSVGResourceGradient(SVGGradientElement* node)
: LayoutSVGResourcePaintServer(node),
should_collect_gradient_attributes_(true),
gradient_map_(MakeGarbageCollected<GradientMap>()) {}
-void LayoutSVGResourceGradient::RemoveAllClientsFromCache(
- bool mark_for_invalidation) {
+void LayoutSVGResourceGradient::RemoveAllClientsFromCache() {
gradient_map_->clear();
should_collect_gradient_attributes_ = true;
To<SVGGradientElement>(*GetElement()).InvalidateDependentGradients();
- MarkAllClientsForInvalidation(
- mark_for_invalidation ? SVGResourceClient::kPaintInvalidation
- : SVGResourceClient::kParentOnlyInvalidation);
+ MarkAllClientsForInvalidation(SVGResourceClient::kPaintInvalidation);
}
bool LayoutSVGResourceGradient::RemoveClientFromCache(
@@ -50,50 +57,52 @@ bool LayoutSVGResourceGradient::RemoveClientFromCache(
return true;
}
-SVGPaintServer LayoutSVGResourceGradient::PreparePaintServer(
- const SVGResourceClient& client,
+std::unique_ptr<GradientData> LayoutSVGResourceGradient::BuildGradientData(
const FloatRect& object_bounding_box) {
- ClearInvalidationMask();
+ // Create gradient object
+ auto gradient_data = std::make_unique<GradientData>();
// Validate gradient DOM state before building the actual
// gradient. This should avoid tearing down the gradient we're
// currently working on. Preferably the state validation should have
// no side-effects though.
if (should_collect_gradient_attributes_) {
- if (!CollectGradientAttributes())
- return SVGPaintServer::Invalid();
+ CollectGradientAttributes();
should_collect_gradient_attributes_ = false;
}
- // Spec: When the geometry of the applicable element has no width or height
- // and objectBoundingBox is specified, then the given effect (e.g. a gradient
- // or a filter) will be ignored.
- if (GradientUnits() == SVGUnitTypes::kSvgUnitTypeObjectboundingbox &&
- object_bounding_box.IsEmpty())
- return SVGPaintServer::Invalid();
+ // We want the text bounding box applied to the gradient space transform
+ // now, so the gradient shader can use it.
+ if (GradientUnits() == SVGUnitTypes::kSvgUnitTypeObjectboundingbox) {
+ // Spec: When the geometry of the applicable element has no width or height
+ // and objectBoundingBox is specified, then the given effect (e.g. a
+ // gradient or a filter) will be ignored.
+ if (object_bounding_box.IsEmpty())
+ return gradient_data;
+ gradient_data->userspace_transform.Translate(object_bounding_box.X(),
+ object_bounding_box.Y());
+ gradient_data->userspace_transform.ScaleNonUniform(
+ object_bounding_box.Width(), object_bounding_box.Height());
+ }
+
+ // Create gradient object
+ gradient_data->gradient = BuildGradient();
+
+ AffineTransform gradient_transform = CalculateGradientTransform();
+ gradient_data->userspace_transform *= gradient_transform;
+
+ return gradient_data;
+}
+
+SVGPaintServer LayoutSVGResourceGradient::PreparePaintServer(
+ const SVGResourceClient& client,
+ const FloatRect& object_bounding_box) {
+ ClearInvalidationMask();
std::unique_ptr<GradientData>& gradient_data =
gradient_map_->insert(&client, nullptr).stored_value->value;
if (!gradient_data)
- gradient_data = std::make_unique<GradientData>();
-
- // Create gradient object
- if (!gradient_data->gradient) {
- gradient_data->gradient = BuildGradient();
-
- // We want the text bounding box applied to the gradient space transform
- // now, so the gradient shader can use it.
- if (GradientUnits() == SVGUnitTypes::kSvgUnitTypeObjectboundingbox &&
- !object_bounding_box.IsEmpty()) {
- gradient_data->userspace_transform.Translate(object_bounding_box.X(),
- object_bounding_box.Y());
- gradient_data->userspace_transform.ScaleNonUniform(
- object_bounding_box.Width(), object_bounding_box.Height());
- }
-
- AffineTransform gradient_transform = CalculateGradientTransform();
- gradient_data->userspace_transform *= gradient_transform;
- }
+ gradient_data = BuildGradientData(object_bounding_box);
if (!gradient_data->gradient)
return SVGPaintServer::Invalid();
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_gradient.h b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_gradient.h
index 6b974699227..530933fdc0d 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_gradient.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_gradient.h
@@ -25,25 +25,18 @@
#include <memory>
#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_paint_server.h"
#include "third_party/blink/renderer/core/svg/svg_gradient_element.h"
-#include "third_party/blink/renderer/platform/graphics/gradient.h"
#include "third_party/blink/renderer/platform/transforms/affine_transform.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
namespace blink {
-struct GradientData {
- USING_FAST_MALLOC(GradientData);
-
- public:
- scoped_refptr<Gradient> gradient;
- AffineTransform userspace_transform;
-};
+struct GradientData;
class LayoutSVGResourceGradient : public LayoutSVGResourcePaintServer {
public:
explicit LayoutSVGResourceGradient(SVGGradientElement*);
- void RemoveAllClientsFromCache(bool mark_for_invalidation = true) final;
+ void RemoveAllClientsFromCache() final;
bool RemoveClientFromCache(SVGResourceClient&) final;
SVGPaintServer PreparePaintServer(const SVGResourceClient&,
@@ -54,13 +47,16 @@ class LayoutSVGResourceGradient : public LayoutSVGResourcePaintServer {
protected:
virtual SVGUnitTypes::SVGUnitType GradientUnits() const = 0;
virtual AffineTransform CalculateGradientTransform() const = 0;
- virtual bool CollectGradientAttributes() = 0;
+ virtual void CollectGradientAttributes() = 0;
virtual scoped_refptr<Gradient> BuildGradient() const = 0;
static GradientSpreadMethod PlatformSpreadMethodFromSVGType(
SVGSpreadMethodType);
private:
+ std::unique_ptr<GradientData> BuildGradientData(
+ const FloatRect& object_bounding_box);
+
bool should_collect_gradient_attributes_ : 1;
using GradientMap = HeapHashMap<Member<const SVGResourceClient>,
std::unique_ptr<GradientData>>;
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_linear_gradient.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_linear_gradient.cc
index 460a76c10da..8d88444f724 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_linear_gradient.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_linear_gradient.cc
@@ -33,10 +33,10 @@ LayoutSVGResourceLinearGradient::LayoutSVGResourceLinearGradient(
LayoutSVGResourceLinearGradient::~LayoutSVGResourceLinearGradient() = default;
-bool LayoutSVGResourceLinearGradient::CollectGradientAttributes() {
+void LayoutSVGResourceLinearGradient::CollectGradientAttributes() {
DCHECK(GetElement());
attributes_wrapper_->Set(LinearGradientAttributes());
- return To<SVGLinearGradientElement>(GetElement())
+ To<SVGLinearGradientElement>(GetElement())
->CollectGradientAttributes(MutableAttributes());
}
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_linear_gradient.h b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_linear_gradient.h
index bbad601c2c1..48c43d53806 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_linear_gradient.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_linear_gradient.h
@@ -47,7 +47,7 @@ class LayoutSVGResourceLinearGradient final : public LayoutSVGResourceGradient {
AffineTransform CalculateGradientTransform() const override {
return Attributes().GradientTransform();
}
- bool CollectGradientAttributes() override;
+ void CollectGradientAttributes() override;
scoped_refptr<Gradient> BuildGradient() const override;
FloatPoint StartPoint(const LinearGradientAttributes&) const;
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 ba43918adba..491b18a5c92 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
@@ -47,12 +47,9 @@ void LayoutSVGResourceMarker::UpdateLayout() {
ClearInvalidationMask();
}
-void LayoutSVGResourceMarker::RemoveAllClientsFromCache(
- bool mark_for_invalidation) {
- MarkAllClientsForInvalidation(
- mark_for_invalidation ? SVGResourceClient::kLayoutInvalidation |
- SVGResourceClient::kBoundariesInvalidation
- : SVGResourceClient::kParentOnlyInvalidation);
+void LayoutSVGResourceMarker::RemoveAllClientsFromCache() {
+ MarkAllClientsForInvalidation(SVGResourceClient::kLayoutInvalidation |
+ SVGResourceClient::kBoundariesInvalidation);
}
FloatRect LayoutSVGResourceMarker::MarkerBoundaries(
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.h b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.h
index d8596cdafdf..58a23afc549 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.h
@@ -35,7 +35,7 @@ class LayoutSVGResourceMarker final : public LayoutSVGResourceContainer {
const char* GetName() const override { return "LayoutSVGResourceMarker"; }
- void RemoveAllClientsFromCache(bool mark_for_invalidation = true) override;
+ void RemoveAllClientsFromCache() override;
// Calculates marker boundaries, mapped to the target element's coordinate
// space.
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 df8d4817416..b1e201d9a8b 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
@@ -36,14 +36,11 @@ LayoutSVGResourceMasker::LayoutSVGResourceMasker(SVGMaskElement* node)
LayoutSVGResourceMasker::~LayoutSVGResourceMasker() = default;
-void LayoutSVGResourceMasker::RemoveAllClientsFromCache(
- bool mark_for_invalidation) {
+void LayoutSVGResourceMasker::RemoveAllClientsFromCache() {
cached_paint_record_.reset();
mask_content_boundaries_ = FloatRect();
- MarkAllClientsForInvalidation(
- mark_for_invalidation ? SVGResourceClient::kLayoutInvalidation |
- SVGResourceClient::kBoundariesInvalidation
- : SVGResourceClient::kParentOnlyInvalidation);
+ MarkAllClientsForInvalidation(SVGResourceClient::kLayoutInvalidation |
+ SVGResourceClient::kBoundariesInvalidation);
}
sk_sp<const PaintRecord> LayoutSVGResourceMasker::CreatePaintRecord(
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.h b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.h
index 70442a2ddbd..6bb360059c0 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.h
@@ -38,7 +38,7 @@ class LayoutSVGResourceMasker final : public LayoutSVGResourceContainer {
const char* GetName() const override { return "LayoutSVGResourceMasker"; }
- void RemoveAllClientsFromCache(bool mark_for_invalidation = true) override;
+ void RemoveAllClientsFromCache() override;
FloatRect ResourceBoundingBox(const FloatRect& reference_box);
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_paint_server.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_paint_server.cc
index fdc8bc00edd..58231ff80fc 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_paint_server.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_paint_server.cc
@@ -147,7 +147,7 @@ SVGPaintServer SVGPaintServer::RequestForLayoutObject(
return SVGPaintServer(paint_description.color);
SVGPaintServer paint_server = paint_description.resource->PreparePaintServer(
*SVGResources::GetClient(layout_object),
- layout_object.ObjectBoundingBox());
+ SVGResources::ReferenceBoxForEffects(layout_object));
if (paint_server.IsValid())
return paint_server;
if (paint_description.has_fallback)
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_paint_server.h b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_paint_server.h
index fad76f41cb6..9706a786c85 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_paint_server.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_paint_server.h
@@ -114,11 +114,11 @@ class LayoutSVGResourcePaintServer : public LayoutSVGResourceContainer {
LayoutSVGResourceMode);
};
-DEFINE_TYPE_CASTS(LayoutSVGResourcePaintServer,
- LayoutSVGResourceContainer,
- resource,
- resource->IsSVGPaintServer(),
- resource.IsSVGPaintServer());
+template <>
+inline bool IsResourceOfType<LayoutSVGResourcePaintServer>(
+ const LayoutSVGResourceContainer* container) {
+ return container->IsSVGPaintServer();
+}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc
index 754d3cef50d..6944d125c20 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc
@@ -52,13 +52,10 @@ LayoutSVGResourcePattern::LayoutSVGResourcePattern(SVGPatternElement* node)
attributes_wrapper_(MakeGarbageCollected<PatternAttributesWrapper>()),
pattern_map_(MakeGarbageCollected<PatternMap>()) {}
-void LayoutSVGResourcePattern::RemoveAllClientsFromCache(
- bool mark_for_invalidation) {
+void LayoutSVGResourcePattern::RemoveAllClientsFromCache() {
pattern_map_->clear();
should_collect_pattern_attributes_ = true;
- MarkAllClientsForInvalidation(
- mark_for_invalidation ? SVGResourceClient::kPaintInvalidation
- : SVGResourceClient::kParentOnlyInvalidation);
+ MarkAllClientsForInvalidation(SVGResourceClient::kPaintInvalidation);
}
bool LayoutSVGResourcePattern::RemoveClientFromCache(
@@ -70,51 +67,53 @@ bool LayoutSVGResourcePattern::RemoveClientFromCache(
return true;
}
-PatternData* LayoutSVGResourcePattern::PatternForClient(
- const SVGResourceClient& client,
+std::unique_ptr<PatternData> LayoutSVGResourcePattern::BuildPatternData(
const FloatRect& object_bounding_box) {
- DCHECK(!should_collect_pattern_attributes_);
+ auto pattern_data = std::make_unique<PatternData>();
- // FIXME: the double hash lookup is needed to guard against paint-time
- // invalidation (painting animated images may trigger layout invals which
- // delete our map entry). Hopefully that will be addressed at some point, and
- // then we can optimize the lookup.
- if (PatternData* current_data = pattern_map_->at(&client))
- return current_data;
-
- return pattern_map_->Set(&client, BuildPatternData(object_bounding_box))
- .stored_value->value.get();
-}
+ DCHECK(GetElement());
+ // Validate pattern DOM state before building the actual pattern. This should
+ // avoid tearing down the pattern we're currently working on. Preferably the
+ // state validation should have no side-effects though.
+ if (should_collect_pattern_attributes_) {
+ attributes_wrapper_->Set(PatternAttributes());
+ auto* pattern_element = To<SVGPatternElement>(GetElement());
+ pattern_element->CollectPatternAttributes(MutableAttributes());
+ should_collect_pattern_attributes_ = false;
+ }
-std::unique_ptr<PatternData> LayoutSVGResourcePattern::BuildPatternData(
- const FloatRect& object_bounding_box) {
- // If we couldn't determine the pattern content element root, stop here.
const PatternAttributes& attributes = Attributes();
- if (!attributes.PatternContentElement())
- return nullptr;
- // An empty viewBox disables layout.
- if (attributes.HasViewBox() && attributes.ViewBox().IsEmpty())
- return nullptr;
+ // Spec: When the geometry of the applicable element has no width or height
+ // and objectBoundingBox is specified, then the given effect (e.g. a gradient
+ // or a filter) will be ignored.
+ if (attributes.PatternUnits() ==
+ SVGUnitTypes::kSvgUnitTypeObjectboundingbox &&
+ object_bounding_box.IsEmpty())
+ return pattern_data;
+
+ // If there's no content disable rendering of the pattern.
+ if (!attributes.PatternContentElement())
+ return pattern_data;
- DCHECK(GetElement());
// Compute tile metrics.
FloatRect tile_bounds = SVGLengthContext::ResolveRectangle(
GetElement(), attributes.PatternUnits(), object_bounding_box,
*attributes.X(), *attributes.Y(), *attributes.Width(),
*attributes.Height());
if (tile_bounds.IsEmpty())
- return nullptr;
+ return pattern_data;
AffineTransform tile_transform;
if (attributes.HasViewBox()) {
+ // An empty viewBox disables rendering of the pattern.
if (attributes.ViewBox().IsEmpty())
- return nullptr;
+ return pattern_data;
tile_transform = SVGFitToViewBox::ViewBoxToViewTransform(
attributes.ViewBox(), attributes.PreserveAspectRatio(),
tile_bounds.Width(), tile_bounds.Height());
} else {
- // A viewbox overrides patternContentUnits, per spec.
+ // A viewBox overrides patternContentUnits, per spec.
if (attributes.PatternContentUnits() ==
SVGUnitTypes::kSvgUnitTypeObjectboundingbox) {
tile_transform.Scale(object_bounding_box.Width(),
@@ -122,7 +121,6 @@ std::unique_ptr<PatternData> LayoutSVGResourcePattern::BuildPatternData(
}
}
- std::unique_ptr<PatternData> pattern_data = base::WrapUnique(new PatternData);
pattern_data->pattern = Pattern::CreatePaintRecordPattern(
AsPaintRecord(tile_bounds.Size(), tile_transform),
FloatRect(FloatPoint(), tile_bounds.Size()));
@@ -139,27 +137,12 @@ SVGPaintServer LayoutSVGResourcePattern::PreparePaintServer(
const FloatRect& object_bounding_box) {
ClearInvalidationMask();
- // Validate pattern DOM state before building the actual
- // pattern. This should avoid tearing down the pattern we're
- // currently working on. Preferably the state validation should have
- // no side-effects though.
- if (should_collect_pattern_attributes_) {
- attributes_wrapper_->Set(PatternAttributes());
- auto* pattern_element = To<SVGPatternElement>(GetElement());
- pattern_element->CollectPatternAttributes(MutableAttributes());
- should_collect_pattern_attributes_ = false;
- }
-
- // Spec: When the geometry of the applicable element has no width or height
- // and objectBoundingBox is specified, then the given effect (e.g. a gradient
- // or a filter) will be ignored.
- if (Attributes().PatternUnits() ==
- SVGUnitTypes::kSvgUnitTypeObjectboundingbox &&
- object_bounding_box.IsEmpty())
- return SVGPaintServer::Invalid();
+ std::unique_ptr<PatternData>& pattern_data =
+ pattern_map_->insert(&client, nullptr).stored_value->value;
+ if (!pattern_data)
+ pattern_data = BuildPatternData(object_bounding_box);
- PatternData* pattern_data = PatternForClient(client, object_bounding_box);
- if (!pattern_data || !pattern_data->pattern)
+ if (!pattern_data->pattern)
return SVGPaintServer::Invalid();
return SVGPaintServer(pattern_data->pattern, pattern_data->transform);
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.h b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.h
index e293f39d1ba..4630fee0837 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.h
@@ -41,7 +41,7 @@ class LayoutSVGResourcePattern final : public LayoutSVGResourcePaintServer {
const char* GetName() const override { return "LayoutSVGResourcePattern"; }
- void RemoveAllClientsFromCache(bool mark_for_invalidation = true) override;
+ void RemoveAllClientsFromCache() override;
bool RemoveClientFromCache(SVGResourceClient&) override;
SVGPaintServer PreparePaintServer(
@@ -56,8 +56,6 @@ class LayoutSVGResourcePattern final : public LayoutSVGResourcePaintServer {
const FloatRect& object_bounding_box);
sk_sp<PaintRecord> AsPaintRecord(const FloatSize&,
const AffineTransform&) const;
- PatternData* PatternForClient(const SVGResourceClient&,
- const FloatRect& object_bounding_box);
const LayoutSVGResourceContainer* ResolveContentElement() const;
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_radial_gradient.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_radial_gradient.cc
index 9b335862268..bf85cc000e6 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_radial_gradient.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_radial_gradient.cc
@@ -34,10 +34,10 @@ LayoutSVGResourceRadialGradient::LayoutSVGResourceRadialGradient(
LayoutSVGResourceRadialGradient::~LayoutSVGResourceRadialGradient() = default;
-bool LayoutSVGResourceRadialGradient::CollectGradientAttributes() {
+void LayoutSVGResourceRadialGradient::CollectGradientAttributes() {
DCHECK(GetElement());
attributes_wrapper_->Set(RadialGradientAttributes());
- return To<SVGRadialGradientElement>(GetElement())
+ To<SVGRadialGradientElement>(GetElement())
->CollectGradientAttributes(MutableAttributes());
}
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_radial_gradient.h b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_radial_gradient.h
index d6f1b760124..41771233f1f 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_radial_gradient.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_radial_gradient.h
@@ -47,7 +47,7 @@ class LayoutSVGResourceRadialGradient final : public LayoutSVGResourceGradient {
AffineTransform CalculateGradientTransform() const override {
return Attributes().GradientTransform();
}
- bool CollectGradientAttributes() override;
+ void CollectGradientAttributes() override;
scoped_refptr<Gradient> BuildGradient() const override;
FloatPoint CenterPoint(const RadialGradientAttributes&) const;
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 534abb8f071..551f84f910c 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
@@ -130,7 +130,7 @@ LayoutUnit LayoutSVGRoot::ComputeReplacedLogicalWidth(
// (border-image/background-image/<html:img>/...) we're forced to resize to a
// specific size.
if (!container_size_.IsEmpty())
- return LayoutUnit(container_size_.Width());
+ return container_size_.Width();
if (IsEmbeddedThroughFrameContainingSVGDocument())
return ContainingBlock()->AvailableLogicalWidth();
@@ -144,7 +144,7 @@ LayoutUnit LayoutSVGRoot::ComputeReplacedLogicalHeight(
// (border-image/background-image/<html:img>/...) we're forced to resize to a
// specific size.
if (!container_size_.IsEmpty())
- return LayoutUnit(container_size_.Height());
+ return container_size_.Height();
if (IsEmbeddedThroughFrameContainingSVGDocument())
return ContainingBlock()->AvailableLogicalHeight(
@@ -300,7 +300,7 @@ bool LayoutSVGRoot::StyleChangeAffectsIntrinsicSize(
}
void LayoutSVGRoot::IntrinsicSizingInfoChanged() {
- SetPreferredLogicalWidthsDirty();
+ SetIntrinsicLogicalWidthsDirty();
// TODO(fs): Merge with IntrinsicSizeChanged()? (from LayoutReplaced)
// Ignore changes to intrinsic dimensions if the <svg> is not in an SVG
@@ -315,7 +315,7 @@ void LayoutSVGRoot::StyleDidChange(StyleDifference diff,
const ComputedStyle* old_style) {
if (diff.NeedsFullLayout())
SetNeedsBoundariesUpdate();
- if (diff.NeedsFullPaintInvalidation()) {
+ if (diff.NeedsPaintInvalidation()) {
// Box decorations may have appeared/disappeared - recompute status.
has_box_decoration_background_ = StyleRef().HasBoxDecorationBackground();
}
@@ -336,7 +336,7 @@ bool LayoutSVGRoot::IsChildAllowed(LayoutObject* child,
void LayoutSVGRoot::AddChild(LayoutObject* child, LayoutObject* before_child) {
LayoutReplaced::AddChild(child, before_child);
- SVGResourcesCache::ClientWasAddedToTree(*child, child->StyleRef());
+ SVGResourcesCache::ClientWasAddedToTree(*child);
bool should_isolate_descendants =
(child->IsBlendingAllowed() && child->StyleRef().HasBlendMode()) ||
@@ -383,7 +383,7 @@ void LayoutSVGRoot::DescendantIsolationRequirementsChanged(
void LayoutSVGRoot::InsertedIntoTree() {
LayoutReplaced::InsertedIntoTree();
- SVGResourcesCache::ClientWasAddedToTree(*this, StyleRef());
+ SVGResourcesCache::ClientWasAddedToTree(*this);
}
void LayoutSVGRoot::WillBeRemovedFromTree() {
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_root.h b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_root.h
index 3246ac260bf..4bba76f4efb 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_root.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_root.h
@@ -65,8 +65,8 @@ class CORE_EXPORT LayoutSVGRoot final : public LayoutReplaced {
needs_boundaries_or_transform_update_ = true;
}
- IntSize ContainerSize() const { return container_size_; }
- void SetContainerSize(const IntSize& container_size) {
+ LayoutSize ContainerSize() const { return container_size_; }
+ void SetContainerSize(const LayoutSize& container_size) {
// SVGImage::draw() does a view layout prior to painting,
// and we need that layout to know of the new size otherwise
// the layout may be incorrectly using the old size.
@@ -162,7 +162,7 @@ class CORE_EXPORT LayoutSVGRoot final : public LayoutReplaced {
PositionWithAffinity PositionForPoint(const PhysicalOffset&) const final;
LayoutObjectChildList children_;
- IntSize container_size_;
+ LayoutSize container_size_;
FloatRect object_bounding_box_;
bool object_bounding_box_valid_;
FloatRect stroke_bounding_box_;
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_root_test.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_root_test.cc
index cc0f2983d0b..40e7ae0d1b4 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_root_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_root_test.cc
@@ -96,39 +96,6 @@ TEST_F(LayoutSVGRootTest, VisualRectMappingWithViewportClipAndBorder) {
EXPECT_EQ(PhysicalRect(0, 0, 220, 120), root_visual_rect);
}
-TEST_F(LayoutSVGRootTest,
- PaintedOutputOfObjectHasNoEffectRegardlessOfSizeEmpty) {
- SetBodyInnerHTML(R"HTML(
- <svg id="svg" width="100.1%" height="16">
- <rect width="100%" height="16" fill="#fff"></rect>
- </svg>
- )HTML");
-
- const LayoutSVGRoot& root =
- *ToLayoutSVGRoot(GetLayoutObjectByElementId("svg"));
- EXPECT_FALSE(root.PaintedOutputOfObjectHasNoEffectRegardlessOfSize());
-}
-
-TEST_F(LayoutSVGRootTest,
- PaintedOutputOfObjectHasNoEffectRegardlessOfSizeMask) {
- SetBodyInnerHTML(R"HTML(
- <svg id="svg" width="16" height="16" mask="url(#test)">
- <rect width="100%" height="16" fill="#fff"></rect>
- <defs>
- <mask id="test">
- <g>
- <rect width="100%" height="100%" fill="#ffffff" style=""></rect>
- </g>
- </mask>
- </defs>
- </svg>
- )HTML");
-
- const LayoutSVGRoot& root =
- *ToLayoutSVGRoot(GetLayoutObjectByElementId("svg"));
- EXPECT_FALSE(root.PaintedOutputOfObjectHasNoEffectRegardlessOfSize());
-}
-
TEST_F(LayoutSVGRootTest, RectBasedHitTestPartialOverlap) {
SetBodyInnerHTML(R"HTML(
<style>body { margin: 0 }</style>
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_shape.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_shape.cc
index 6286842b095..66bff8d5bd1 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_shape.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_shape.cc
@@ -79,13 +79,13 @@ void LayoutSVGShape::WillBeDestroyed() {
void LayoutSVGShape::CreatePath() {
if (!path_)
path_ = std::make_unique<Path>();
- *path_ = ToSVGGeometryElement(GetElement())->AsPath();
+ *path_ = To<SVGGeometryElement>(GetElement())->AsPath();
}
float LayoutSVGShape::DashScaleFactor() const {
if (StyleRef().SvgStyle().StrokeDashArray()->data.IsEmpty())
return 1;
- return ToSVGGeometryElement(*GetElement()).PathLengthScaleFactor();
+ return To<SVGGeometryElement>(*GetElement()).PathLengthScaleFactor();
}
void LayoutSVGShape::UpdateShapeFromElement() {
@@ -229,7 +229,6 @@ void LayoutSVGShape::UpdateLayout() {
FloatRect old_object_bounding_box = ObjectBoundingBox();
UpdateShapeFromElement();
if (old_object_bounding_box != ObjectBoundingBox()) {
- GetElement()->SetNeedsResizeObserverUpdate();
SetShouldDoFullPaintInvalidation();
bbox_changed = true;
}
@@ -393,6 +392,21 @@ float LayoutSVGShape::StrokeWidth() const {
return length_context.ValueForLength(StyleRef().SvgStyle().StrokeWidth());
}
+float LayoutSVGShape::StrokeWidthForMarkerUnits() const {
+ float stroke_width = StrokeWidth();
+ if (HasNonScalingStroke()) {
+ const auto& non_scaling_transform = NonScalingStrokeTransform();
+ if (!non_scaling_transform.IsInvertible())
+ return 0;
+ float scale_factor =
+ clampTo<float>(sqrt((non_scaling_transform.XScaleSquared() +
+ non_scaling_transform.YScaleSquared()) /
+ 2));
+ stroke_width /= scale_factor;
+ }
+ return stroke_width;
+}
+
LayoutSVGShapeRareData& LayoutSVGShape::EnsureRareData() const {
if (!rare_data_)
rare_data_ = std::make_unique<LayoutSVGShapeRareData>();
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_shape.h b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_shape.h
index 1b11df34d50..803a52ec322 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_shape.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_shape.h
@@ -101,6 +101,7 @@ class LayoutSVGShape : public LayoutSVGModelObject {
}
float StrokeWidth() const;
+ float StrokeWidthForMarkerUnits() const;
virtual ShapeGeometryCodePath GeometryCodePath() const {
return kPathGeometry;
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 34c734ab14f..373e99fb652 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
@@ -111,15 +111,8 @@ static inline void CollectDescendantTextNodes(
}
}
-void LayoutSVGText::InvalidatePositioningValues(
+void LayoutSVGText::SubtreeStructureChanged(
LayoutInvalidationReasonForTracing reason) {
- descendant_text_nodes_.clear();
- SetNeedsPositioningValuesUpdate();
- // TODO(fs): Restore the passing of |reason| here.
- LayoutSVGResourceContainer::MarkForLayoutAndParentResourceInvalidation(*this);
-}
-
-void LayoutSVGText::SubtreeChildWasAdded() {
if (BeingDestroyed() || !EverHadLayout()) {
DCHECK(descendant_text_nodes_.IsEmpty());
return;
@@ -128,37 +121,20 @@ void LayoutSVGText::SubtreeChildWasAdded() {
return;
// The positioning elements cache depends on the size of each text
- // layoutObject in the subtree. If this changes, clear the cache. It will be
+ // LayoutObject in the subtree. If this changes, clear the cache. It will be
// rebuilt on the next layout.
- InvalidatePositioningValues(layout_invalidation_reason::kChildChanged);
- SetNeedsTextMetricsUpdate();
-}
-
-void LayoutSVGText::SubtreeChildWillBeRemoved() {
- if (BeingDestroyed() || !EverHadLayout()) {
- DCHECK(descendant_text_nodes_.IsEmpty());
- return;
- }
-
- // The positioning elements cache depends on the size of each text
- // layoutObject in the subtree. If this changes, clear the cache. It will be
- // rebuilt on the next layout.
- InvalidatePositioningValues(layout_invalidation_reason::kChildChanged);
+ descendant_text_nodes_.clear();
+ SetNeedsPositioningValuesUpdate();
SetNeedsTextMetricsUpdate();
+ // TODO(fs): Restore the passing of |reason| here.
+ LayoutSVGResourceContainer::MarkForLayoutAndParentResourceInvalidation(*this);
}
-void LayoutSVGText::SubtreeTextDidChange() {
- DCHECK(!BeingDestroyed());
- if (!EverHadLayout()) {
- DCHECK(descendant_text_nodes_.IsEmpty());
- return;
- }
-
- // The positioning elements cache depends on the size of each text object in
- // the subtree. If this changes, clear the cache and mark it for rebuilding
- // in the next layout.
- InvalidatePositioningValues(layout_invalidation_reason::kTextChanged);
- SetNeedsTextMetricsUpdate();
+void LayoutSVGText::NotifySubtreeStructureChanged(
+ LayoutObject* object,
+ LayoutInvalidationReasonForTracing reason) {
+ if (LayoutSVGText* layout_text = LocateLayoutSVGTextAncestor(object))
+ layout_text->SubtreeStructureChanged(reason);
}
static inline void UpdateFontAndMetrics(LayoutSVGText& text_root) {
@@ -365,8 +341,8 @@ PositionWithAffinity LayoutSVGText::PositionForPoint(
DCHECK(!root_box->NextRootBox());
DCHECK(ChildrenInline());
- InlineBox* closest_box =
- ToSVGRootInlineBox(root_box)->ClosestLeafChildForPosition(
+ auto* closest_box =
+ To<SVGRootInlineBox>(root_box)->ClosestLeafChildForPosition(
clipped_point_in_contents);
if (!closest_box)
return CreatePositionWithAffinity(0);
@@ -391,27 +367,17 @@ FloatRect LayoutSVGText::ObjectBoundingBox() const {
}
FloatRect LayoutSVGText::StrokeBoundingBox() const {
- FloatRect stroke_boundaries = ObjectBoundingBox();
- const SVGComputedStyle& svg_style = StyleRef().SvgStyle();
- if (!svg_style.HasStroke())
- return stroke_boundaries;
-
- DCHECK(GetElement());
- SVGLengthContext length_context(GetElement());
- stroke_boundaries.Inflate(
- length_context.ValueForLength(svg_style.StrokeWidth()));
- return stroke_boundaries;
+ if (!FirstRootBox())
+ return FloatRect();
+ return SVGLayoutSupport::ExtendTextBBoxWithStroke(*this, ObjectBoundingBox());
}
FloatRect LayoutSVGText::VisualRectInLocalSVGCoordinates() const {
- FloatRect visual_rect = StrokeBoundingBox();
- SVGLayoutSupport::AdjustVisualRectWithResources(*this, ObjectBoundingBox(),
- visual_rect);
-
- if (const ShadowList* text_shadow = StyleRef().TextShadow())
- text_shadow->AdjustRectForShadow(visual_rect);
-
- return visual_rect;
+ if (!FirstRootBox())
+ return FloatRect();
+ const FloatRect object_bounds = ObjectBoundingBox();
+ return SVGLayoutSupport::ComputeVisualRectForText(*this, object_bounds,
+ object_bounds);
}
void LayoutSVGText::AddOutlineRects(Vector<PhysicalRect>& rects,
@@ -428,13 +394,13 @@ bool LayoutSVGText::IsObjectBoundingBoxValid() const {
void LayoutSVGText::AddChild(LayoutObject* child, LayoutObject* before_child) {
LayoutSVGBlock::AddChild(child, before_child);
- SVGResourcesCache::ClientWasAddedToTree(*child, child->StyleRef());
- SubtreeChildWasAdded();
+ SVGResourcesCache::ClientWasAddedToTree(*child);
+ SubtreeStructureChanged(layout_invalidation_reason::kChildChanged);
}
void LayoutSVGText::RemoveChild(LayoutObject* child) {
SVGResourcesCache::ClientWillBeRemovedFromTree(*child);
- SubtreeChildWillBeRemoved();
+ SubtreeStructureChanged(layout_invalidation_reason::kChildChanged);
LayoutSVGBlock::RemoveChild(child);
}
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 2360fe04afd..c5ebeb9f698 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
@@ -53,15 +53,14 @@ class LayoutSVGText final : public LayoutSVGBlock {
static LayoutSVGText* LocateLayoutSVGTextAncestor(LayoutObject*);
static const LayoutSVGText* LocateLayoutSVGTextAncestor(const LayoutObject*);
+ static void NotifySubtreeStructureChanged(LayoutObject*,
+ LayoutInvalidationReasonForTracing);
+
bool NeedsReordering() const { return needs_reordering_; }
const Vector<LayoutSVGInlineText*>& DescendantTextNodes() const {
return descendant_text_nodes_;
}
- void SubtreeChildWasAdded();
- void SubtreeChildWillBeRemoved();
- void SubtreeTextDidChange();
-
void RecalcVisualOverflow() override;
const char* GetName() const override { return "LayoutSVGText"; }
@@ -94,7 +93,7 @@ class LayoutSVGText final : public LayoutSVGBlock {
RootInlineBox* CreateRootInlineBox() override;
- void InvalidatePositioningValues(LayoutInvalidationReasonForTracing);
+ void SubtreeStructureChanged(LayoutInvalidationReasonForTracing);
bool needs_reordering_ : 1;
bool needs_positioning_values_update_ : 1;
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_text_path.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_text_path.cc
index bcf433726ee..1290e22820c 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_text_path.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_text_path.cc
@@ -62,8 +62,7 @@ bool LayoutSVGTextPath::IsChildAllowed(LayoutObject* child,
std::unique_ptr<PathPositionMapper> LayoutSVGTextPath::LayoutPath() const {
const auto& text_path_element = To<SVGTextPathElement>(*GetNode());
Element* target_element = SVGURIReference::TargetElementFromIRIString(
- text_path_element.HrefString(),
- text_path_element.TreeScopeForIdResolution());
+ text_path_element.HrefString(), text_path_element.OriginatingTreeScope());
const auto* path_element = DynamicTo<SVGPathElement>(target_element);
if (!path_element)
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/line/svg_inline_flow_box.h b/chromium/third_party/blink/renderer/core/layout/svg/line/svg_inline_flow_box.h
index b4a32b6a14b..d62be330937 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/line/svg_inline_flow_box.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/line/svg_inline_flow_box.h
@@ -22,6 +22,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_LINE_SVG_INLINE_FLOW_BOX_H_
#include "third_party/blink/renderer/core/layout/line/inline_flow_box.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -42,7 +43,12 @@ class SVGInlineFlowBox final : public InlineFlowBox {
LayoutUnit logical_height_;
};
-DEFINE_INLINE_BOX_TYPE_CASTS(SVGInlineFlowBox);
+template <>
+struct DowncastTraits<SVGInlineFlowBox> {
+ static bool AllowFrom(const InlineBox& box) {
+ return box.IsSVGInlineFlowBox();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/line/svg_inline_text_box.h b/chromium/third_party/blink/renderer/core/layout/svg/line/svg_inline_text_box.h
index 3ce95efaac1..6c19bd6f4ba 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/line/svg_inline_text_box.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/line/svg_inline_text_box.h
@@ -109,7 +109,12 @@ class SVGInlineTextBox final : public InlineTextBox {
Vector<SVGTextFragment> text_fragments_;
};
-DEFINE_INLINE_BOX_TYPE_CASTS(SVGInlineTextBox);
+template <>
+struct DowncastTraits<SVGInlineTextBox> {
+ static bool AllowFrom(const InlineBox& box) {
+ return box.IsSVGInlineTextBox();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/line/svg_root_inline_box.cc b/chromium/third_party/blink/renderer/core/layout/svg/line/svg_root_inline_box.cc
index 240be07bf5c..cf3fffe5517 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/line/svg_root_inline_box.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/line/svg_root_inline_box.cc
@@ -86,8 +86,8 @@ void SVGRootInlineBox::ComputePerCharacterLayoutInformation() {
FloatRect SVGRootInlineBox::LayoutInlineBoxes(InlineBox& box) {
FloatRect rect;
- if (box.IsSVGInlineTextBox()) {
- rect = ToSVGInlineTextBox(box).CalculateBoundaries();
+ if (auto* svg_inline_text_box = DynamicTo<SVGInlineTextBox>(box)) {
+ rect = svg_inline_text_box->CalculateBoundaries();
} else {
for (InlineBox* child = ToInlineFlowBox(box).FirstChild(); child;
child = child->NextOnLine())
@@ -101,12 +101,12 @@ FloatRect SVGRootInlineBox::LayoutInlineBoxes(InlineBox& box) {
box.SetX(logical_rect.X());
box.SetY(logical_rect.Y());
box.SetLogicalWidth(logical_rect.Width());
- if (box.IsSVGInlineTextBox())
- ToSVGInlineTextBox(box).SetLogicalHeight(logical_rect.Height());
- else if (box.IsSVGInlineFlowBox())
- ToSVGInlineFlowBox(box).SetLogicalHeight(logical_rect.Height());
+ if (auto* svg_inline_text_box = DynamicTo<SVGInlineTextBox>(box))
+ svg_inline_text_box->SetLogicalHeight(logical_rect.Height());
+ else if (auto* svg_inline_flow_box = DynamicTo<SVGInlineFlowBox>(box))
+ svg_inline_flow_box->SetLogicalHeight(logical_rect.Height());
else
- ToSVGRootInlineBox(box).SetLogicalHeight(logical_rect.Height());
+ To<SVGRootInlineBox>(box).SetLogicalHeight(logical_rect.Height());
return rect;
}
@@ -170,10 +170,9 @@ static inline void ReverseInlineBoxRangeAndValueListsIfNeeded(
if (first == last || first == --last)
return;
- if ((*last)->IsSVGInlineTextBox() && (*first)->IsSVGInlineTextBox()) {
- SVGInlineTextBox* first_text_box = ToSVGInlineTextBox(*first);
- SVGInlineTextBox* last_text_box = ToSVGInlineTextBox(*last);
-
+ auto* first_text_box = DynamicTo<SVGInlineTextBox>(*first);
+ auto* last_text_box = DynamicTo<SVGInlineTextBox>(*last);
+ if (last_text_box && first_text_box) {
// Reordering is only necessary for BiDi text that is _absolutely_
// positioned.
if (first_text_box->Len() == 1 &&
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/line/svg_root_inline_box.h b/chromium/third_party/blink/renderer/core/layout/svg/line/svg_root_inline_box.h
index 8f741b84c92..3fc347d75a5 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/line/svg_root_inline_box.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/line/svg_root_inline_box.h
@@ -24,6 +24,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_LINE_SVG_ROOT_INLINE_BOX_H_
#include "third_party/blink/renderer/core/layout/line/root_inline_box.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -60,7 +61,12 @@ class SVGRootInlineBox final : public RootInlineBox {
LayoutUnit logical_height_;
};
-DEFINE_INLINE_BOX_TYPE_CASTS(SVGRootInlineBox);
+template <>
+struct DowncastTraits<SVGRootInlineBox> {
+ static bool AllowFrom(const InlineBox& box) {
+ return box.IsSVGRootInlineBox();
+ }
+};
} // namespace blink
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 40000a9c319..14eabbb2fcc 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
@@ -210,10 +210,9 @@ inline void SVGLayoutSupport::UpdateObjectBoundingBox(
bool& object_bounding_box_valid,
LayoutObject* other,
FloatRect other_bounding_box) {
+ auto* svg_container = DynamicTo<LayoutSVGContainer>(other);
bool other_valid =
- other->IsSVGContainer()
- ? ToLayoutSVGContainer(other)->IsObjectBoundingBoxValid()
- : true;
+ svg_container ? svg_container->IsObjectBoundingBoxValid() : true;
if (!other_valid)
return;
@@ -236,8 +235,8 @@ static bool HasValidBoundingBoxForContainer(const LayoutObject* object) {
if (object->IsSVGHiddenContainer())
return false;
- if (object->IsSVGForeignObject())
- return ToLayoutSVGForeignObject(object)->IsObjectBoundingBoxValid();
+ if (auto* foreign_object = DynamicTo<LayoutSVGForeignObject>(object))
+ return foreign_object->IsObjectBoundingBoxValid();
if (object->IsSVGImage())
return ToLayoutSVGImage(object)->IsObjectBoundingBoxValid();
@@ -409,6 +408,34 @@ void SVGLayoutSupport::AdjustVisualRectWithResources(
visual_rect.Intersect(masker->ResourceBoundingBox(object_bounding_box));
}
+FloatRect SVGLayoutSupport::ExtendTextBBoxWithStroke(
+ const LayoutObject& layout_object,
+ const FloatRect& text_bounds) {
+ DCHECK(layout_object.IsSVGText() || layout_object.IsSVGInline());
+ FloatRect bounds = text_bounds;
+ const SVGComputedStyle& svg_style = layout_object.StyleRef().SvgStyle();
+ if (svg_style.HasStroke()) {
+ SVGLengthContext length_context(To<SVGElement>(layout_object.GetNode()));
+ // TODO(fs): This approximation doesn't appear to be conservative enough
+ // since while text (usually?) won't have caps it could have joins and thus
+ // miters.
+ bounds.Inflate(length_context.ValueForLength(svg_style.StrokeWidth()));
+ }
+ return bounds;
+}
+
+FloatRect SVGLayoutSupport::ComputeVisualRectForText(
+ const LayoutObject& layout_object,
+ const FloatRect& text_bounds,
+ const FloatRect& reference_box) {
+ DCHECK(layout_object.IsSVGText() || layout_object.IsSVGInline());
+ FloatRect visual_rect = ExtendTextBBoxWithStroke(layout_object, text_bounds);
+ if (const ShadowList* text_shadow = layout_object.StyleRef().TextShadow())
+ text_shadow->AdjustRectForShadow(visual_rect);
+ AdjustVisualRectWithResources(layout_object, reference_box, visual_rect);
+ return visual_rect;
+}
+
bool SVGLayoutSupport::HasFilterResource(const LayoutObject& object) {
SVGResources* resources =
SVGResourcesCache::CachedResourcesForLayoutObject(object);
@@ -442,8 +469,8 @@ bool SVGLayoutSupport::HitTestChildren(LayoutObject* last_child,
HitTestAction hit_test_action) {
for (LayoutObject* child = last_child; child;
child = child->PreviousSibling()) {
- if (child->IsSVGForeignObject()) {
- if (ToLayoutSVGForeignObject(child)->NodeAtPointFromSVG(
+ if (auto* foreign_object = DynamicTo<LayoutSVGForeignObject>(child)) {
+ if (foreign_object->NodeAtPointFromSVG(
result, location, accumulated_offset, hit_test_action))
return true;
} else {
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/svg_layout_support.h b/chromium/third_party/blink/renderer/core/layout/svg/svg_layout_support.h
index 92b33e48eb6..214bf35707b 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/svg_layout_support.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/svg_layout_support.h
@@ -68,6 +68,15 @@ class CORE_EXPORT SVGLayoutSupport {
const FloatRect& object_bounding_box,
FloatRect&);
+ // Add any contribution from 'stroke' to a text content bounding rect.
+ static FloatRect ExtendTextBBoxWithStroke(const LayoutObject&,
+ const FloatRect& text_bounds);
+
+ // Compute the visual rect for the a text content LayoutObject.
+ static FloatRect ComputeVisualRectForText(const LayoutObject&,
+ const FloatRect& text_bounds,
+ const FloatRect& reference_box);
+
// Determine if the LayoutObject references a filter resource object.
static bool HasFilterResource(const LayoutObject&);
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/svg_layout_tree_as_text.cc b/chromium/third_party/blink/renderer/core/layout/svg/svg_layout_tree_as_text.cc
index 9c5236a6c29..214b062de87 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/svg_layout_tree_as_text.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/svg_layout_tree_as_text.cc
@@ -383,12 +383,10 @@ static WTF::TextStream& operator<<(WTF::TextStream& ts,
WriteNameValuePair(ts, "r",
length_context.ValueForLength(svg_style.R(), style,
SVGLengthMode::kOther));
- } else if (IsSVGPolyElement(*svg_element)) {
- WriteNameAndQuotedValue(ts, "points",
- ToSVGPolyElement(*svg_element)
- .Points()
- ->CurrentValue()
- ->ValueAsString());
+ } else if (auto* svg_poly_element = DynamicTo<SVGPolyElement>(svg_element)) {
+ WriteNameAndQuotedValue(
+ ts, "points",
+ svg_poly_element->Points()->CurrentValue()->ValueAsString());
} else if (IsA<SVGPathElement>(*svg_element)) {
const StylePath& path =
svg_style.D() ? *svg_style.D() : *StylePath::EmptyPath();
@@ -410,7 +408,7 @@ static WTF::TextStream& operator<<(WTF::TextStream& ts,
static void WriteLayoutSVGTextBox(WTF::TextStream& ts,
const LayoutSVGText& text) {
- SVGRootInlineBox* box = ToSVGRootInlineBox(text.FirstRootBox());
+ auto* box = To<SVGRootInlineBox>(text.FirstRootBox());
if (!box)
return;
@@ -495,10 +493,11 @@ static inline void WriteSVGInlineTextBoxes(WTF::TextStream& ts,
const LayoutText& text,
int indent) {
for (InlineTextBox* box : text.TextBoxes()) {
- if (!box->IsSVGInlineTextBox())
+ auto* svg_inline_text_box = DynamicTo<SVGInlineTextBox>(box);
+ if (!svg_inline_text_box)
continue;
- WriteSVGInlineTextBox(ts, ToSVGInlineTextBox(box), indent);
+ WriteSVGInlineTextBox(ts, svg_inline_text_box, indent);
}
}
@@ -648,9 +647,6 @@ void WriteSVGResourceContainer(WTF::TextStream& ts,
void WriteSVGContainer(WTF::TextStream& ts,
const LayoutObject& container,
int indent) {
- // Currently LayoutSVGResourceFilterPrimitive has no meaningful output.
- if (container.IsSVGResourceFilterPrimitive())
- return;
WriteStandardPrefix(ts, container, indent);
WritePositionAndStyle(ts, container);
ts << "\n";
@@ -741,7 +737,7 @@ void WriteResources(WTF::TextStream& ts,
WriteStandardPrefix(ts, *clipper, 0);
ts << " " << clipper->ResourceBoundingBox(reference_box) << "\n";
}
- if (LayoutSVGResourceFilter* filter = resources->Filter()) {
+ if (LayoutSVGResourceFilter* filter = GetFilterResourceForSVG(style)) {
DCHECK(style.HasFilter());
DCHECK_EQ(style.Filter().size(), 1u);
const FilterOperation& filter_operation = *style.Filter().at(0);
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/svg_marker_data.cc b/chromium/third_party/blink/renderer/core/layout/svg/svg_marker_data.cc
index 0892cd34cfd..3673515b7c9 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/svg_marker_data.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/svg_marker_data.cc
@@ -19,6 +19,9 @@
#include "third_party/blink/renderer/core/layout/svg/svg_marker_data.h"
+#include "base/auto_reset.h"
+#include "third_party/blink/renderer/core/svg/svg_path_byte_stream_source.h"
+#include "third_party/blink/renderer/core/svg/svg_path_parser.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
@@ -32,12 +35,7 @@ static double BisectingAngle(double in_angle, double out_angle) {
void SVGMarkerDataBuilder::Build(const Path& path) {
path.Apply(this, SVGMarkerDataBuilder::UpdateFromPathElement);
- if (positions_.IsEmpty())
- return;
- const bool kEndsSubpath = true;
- UpdateAngle(kEndsSubpath);
- // Mark the last marker as 'end'.
- positions_.back().type = kEndMarker;
+ Flush();
}
void SVGMarkerDataBuilder::UpdateFromPathElement(void* info,
@@ -45,6 +43,109 @@ void SVGMarkerDataBuilder::UpdateFromPathElement(void* info,
static_cast<SVGMarkerDataBuilder*>(info)->UpdateFromPathElement(*element);
}
+namespace {
+
+// Path processor that converts an arc segment to a cubic segment with
+// equivalent start/end tangents.
+class MarkerPathSegmentProcessor : public SVGPathNormalizer {
+ STACK_ALLOCATED();
+
+ public:
+ MarkerPathSegmentProcessor(SVGPathConsumer* consumer)
+ : SVGPathNormalizer(consumer) {}
+
+ void EmitSegment(const PathSegmentData&);
+
+ private:
+ Vector<PathSegmentData> DecomposeArc(const PathSegmentData&);
+};
+
+Vector<PathSegmentData> MarkerPathSegmentProcessor::DecomposeArc(
+ const PathSegmentData& segment) {
+ class SegmentCollector : public SVGPathConsumer {
+ STACK_ALLOCATED();
+
+ public:
+ void EmitSegment(const PathSegmentData& segment) override {
+ DCHECK_EQ(segment.command, kPathSegCurveToCubicAbs);
+ segments_.push_back(segment);
+ }
+ Vector<PathSegmentData> ReturnSegments() { return std::move(segments_); }
+
+ private:
+ Vector<PathSegmentData> segments_;
+ } collector;
+ // Temporarily switch to our "collector" to collect the curve segments
+ // emitted by DecomposeArcToCubic(), and then switch back to the actual
+ // consumer.
+ base::AutoReset<SVGPathConsumer*> consumer_scope(&consumer_, &collector);
+ DecomposeArcToCubic(current_point_, segment);
+ return collector.ReturnSegments();
+}
+
+void MarkerPathSegmentProcessor::EmitSegment(
+ const PathSegmentData& original_segment) {
+ PathSegmentData segment = original_segment;
+ // Convert a relative arc to absolute.
+ if (segment.command == kPathSegArcRel) {
+ segment.command = kPathSegArcAbs;
+ segment.target_point += current_point_;
+ }
+ if (segment.command == kPathSegArcAbs) {
+ // Decompose and then pass/emit a synthesized cubic with matching tangents.
+ Vector<PathSegmentData> decomposed_arc_curves = DecomposeArc(segment);
+ if (decomposed_arc_curves.IsEmpty()) {
+ segment.command = kPathSegLineToAbs;
+ } else {
+ // Use the first control point from the first curve and the second and
+ // last control points from the last curve. (If the decomposition only
+ // has one curve then the second line just copies the same point again.)
+ segment = decomposed_arc_curves.back();
+ segment.point1 = decomposed_arc_curves[0].point1;
+ }
+ }
+ // Invoke the base class to normalize and emit to the consumer
+ // (SVGMarkerDataBuilder).
+ SVGPathNormalizer::EmitSegment(segment);
+}
+
+} // namespace
+
+void SVGMarkerDataBuilder::Build(const SVGPathByteStream& stream) {
+ SVGPathByteStreamSource source(stream);
+ MarkerPathSegmentProcessor processor(this);
+ svg_path_parser::ParsePath(source, processor);
+ Flush();
+}
+
+void SVGMarkerDataBuilder::EmitSegment(const PathSegmentData& segment) {
+ PathElement element;
+ FloatPoint points[3];
+ element.points = points;
+ switch (segment.command) {
+ case kPathSegClosePath:
+ element.type = kPathElementCloseSubpath;
+ break;
+ case kPathSegMoveToAbs:
+ element.type = kPathElementMoveToPoint;
+ element.points[0] = segment.target_point;
+ break;
+ case kPathSegLineToAbs:
+ element.type = kPathElementAddLineToPoint;
+ element.points[0] = segment.target_point;
+ break;
+ case kPathSegCurveToCubicAbs:
+ element.type = kPathElementAddCurveToPoint;
+ element.points[0] = segment.point1;
+ element.points[1] = segment.point2;
+ element.points[2] = segment.target_point;
+ break;
+ default:
+ NOTREACHED();
+ }
+ UpdateFromPathElement(element);
+}
+
double SVGMarkerDataBuilder::CurrentAngle(AngleType type) const {
// For details of this calculation, see:
// http://www.w3.org/TR/SVG/single-page.html#painting-MarkerElement
@@ -176,4 +277,13 @@ void SVGMarkerDataBuilder::UpdateFromPathElement(const PathElement& element) {
positions_.push_back(MarkerPosition(marker_type, origin_, 0));
}
+void SVGMarkerDataBuilder::Flush() {
+ if (positions_.IsEmpty())
+ return;
+ const bool kEndsSubpath = true;
+ UpdateAngle(kEndsSubpath);
+ // Mark the last marker as 'end'.
+ positions_.back().type = kEndMarker;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/svg_marker_data.h b/chromium/third_party/blink/renderer/core/layout/svg/svg_marker_data.h
index adbda9ab99c..40d150d0bff 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/svg_marker_data.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/svg_marker_data.h
@@ -20,6 +20,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_SVG_MARKER_DATA_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_SVG_MARKER_DATA_H_
+#include "third_party/blink/renderer/core/svg/svg_path_consumer.h"
#include "third_party/blink/renderer/platform/graphics/path.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
@@ -29,6 +30,7 @@ namespace blink {
enum SVGMarkerType { kStartMarker, kMidMarker, kEndMarker };
class LayoutSVGResourceMarker;
+class SVGPathByteStream;
struct MarkerPosition {
DISALLOW_NEW();
@@ -58,7 +60,7 @@ struct MarkerPosition {
float angle;
};
-class SVGMarkerDataBuilder {
+class SVGMarkerDataBuilder : private SVGPathConsumer {
STACK_ALLOCATED();
public:
@@ -67,9 +69,21 @@ class SVGMarkerDataBuilder {
last_moveto_index_(0),
last_element_type_(kPathElementMoveToPoint) {}
+ // Build marker data for a Path.
void Build(const Path&);
+ // Build marker data for a SVGPathByteStream.
+ //
+ // A SVGPathByteStream is semantically higher-level than a Path, and thus
+ // this allows those higher-level constructs (for example arcs) to be handled
+ // correctly. This should be used in cases where the original path data can
+ // contain such higher-level constructs.
+ void Build(const SVGPathByteStream&);
+
private:
+ // SVGPathConsumer
+ void EmitSegment(const PathSegmentData&) override;
+
static void UpdateFromPathElement(void* info, const PathElement*);
enum AngleType {
@@ -95,6 +109,7 @@ class SVGMarkerDataBuilder {
const FloatPoint& end);
SegmentData ExtractPathElementFeatures(const PathElement&) const;
void UpdateFromPathElement(const PathElement&);
+ void Flush();
Vector<MarkerPosition>& positions_;
unsigned last_moveto_index_;
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 1ff19413ab7..4d1cc23961b 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
@@ -27,15 +27,22 @@
#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_paint_server.h"
+#include "third_party/blink/renderer/core/layout/svg/layout_svg_text.h"
#include "third_party/blink/renderer/core/layout/svg/svg_resources_cache.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style/reference_clip_path_operation.h"
#include "third_party/blink/renderer/core/style/style_svg_resource.h"
+#include "third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.h"
+#include "third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.h"
#include "third_party/blink/renderer/core/svg/svg_pattern_element.h"
#include "third_party/blink/renderer/core/svg/svg_resource.h"
#include "third_party/blink/renderer/core/svg/svg_tree_scope_resources.h"
#include "third_party/blink/renderer/core/svg/svg_uri_reference.h"
#include "third_party/blink/renderer/core/svg_names.h"
+#include "third_party/blink/renderer/platform/graphics/filters/filter.h"
+#include "third_party/blink/renderer/platform/graphics/filters/filter_effect.h"
+#include "third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h"
+#include "third_party/blink/renderer/platform/graphics/filters/source_graphic.h"
#if DCHECK_IS_ON()
#include <stdio.h>
@@ -45,10 +52,32 @@ namespace blink {
SVGResources::SVGResources() : linked_resource_(nullptr) {}
-SVGResourceClient* SVGResources::GetClient(const LayoutObject& object) {
+SVGElementResourceClient* SVGResources::GetClient(const LayoutObject& object) {
return To<SVGElement>(object.GetNode())->GetSVGResourceClient();
}
+FloatRect SVGResources::ReferenceBoxForEffects(
+ const LayoutObject& layout_object) {
+ // For SVG foreign objects, remove the position part of the bounding box. The
+ // position is already baked into the transform, and we don't want to re-apply
+ // the offset when, e.g., using "objectBoundingBox" for clipPathUnits.
+ if (layout_object.IsSVGForeignObject()) {
+ FloatRect rect = layout_object.ObjectBoundingBox();
+ return FloatRect(FloatPoint::Zero(), rect.Size());
+ }
+
+ // Text "sub-elements" (<tspan>, <textpath>, <a>) should use the entire
+ // <text>s object bounding box rather then their own.
+ // https://svgwg.org/svg2-draft/text.html#ObjectBoundingBoxUnitsTextObjects
+ const LayoutObject* obb_layout_object = &layout_object;
+ if (layout_object.IsSVGInline()) {
+ obb_layout_object =
+ LayoutSVGText::LocateLayoutSVGTextAncestor(&layout_object);
+ }
+ DCHECK(obb_layout_object);
+ return obb_layout_object->ObjectBoundingBox();
+}
+
static HashSet<AtomicString>& ClipperFilterMaskerTags() {
DEFINE_STATIC_LOCAL(
HashSet<AtomicString>, tag_list,
@@ -115,37 +144,6 @@ static HashSet<AtomicString>& FillAndStrokeTags() {
return tag_list;
}
-namespace {
-
-template <typename ContainerType>
-bool IsResourceOfType(LayoutSVGResourceContainer* container) {
- return container->ResourceType() == ContainerType::kResourceType;
-}
-
-template <>
-bool IsResourceOfType<LayoutSVGResourcePaintServer>(
- LayoutSVGResourceContainer* container) {
- return container->IsSVGPaintServer();
-}
-
-template <typename ContainerType>
-ContainerType* CastResource(SVGResource* resource) {
- if (!resource)
- return nullptr;
- if (LayoutSVGResourceContainer* container = resource->ResourceContainer()) {
- if (IsResourceOfType<ContainerType>(container))
- return static_cast<ContainerType*>(container);
- }
- return nullptr;
-}
-
-template <typename ContainerType>
-ContainerType* CastResource(StyleSVGResource& style_resource) {
- return CastResource<ContainerType>(style_resource.Resource());
-}
-
-} // namespace
-
bool SVGResources::HasResourceData() const {
return clipper_filter_masker_data_ || marker_data_ || fill_stroke_data_ ||
linked_resource_;
@@ -176,59 +174,51 @@ std::unique_ptr<SVGResources> SVGResources::BuildResources(
std::unique_ptr<SVGResources> resources;
if (ClipperFilterMaskerTags().Contains(tag_name)) {
if (computed_style.ClipPath() && !object.IsSVGRoot()) {
- ClipPathOperation* clip_path_operation = computed_style.ClipPath();
- if (clip_path_operation->GetType() == ClipPathOperation::REFERENCE) {
- const ReferenceClipPathOperation& clip_path_reference =
- To<ReferenceClipPathOperation>(*clip_path_operation);
- EnsureResources(resources).SetClipper(
- CastResource<LayoutSVGResourceClipper>(
- clip_path_reference.Resource()));
+ if (LayoutSVGResourceClipper* clipper =
+ GetSVGResourceAsType(computed_style.ClipPath())) {
+ EnsureResources(resources).SetClipper(clipper);
}
}
if (computed_style.HasFilter() && !object.IsSVGRoot()) {
- const FilterOperations& filter_operations = computed_style.Filter();
- if (filter_operations.size() == 1) {
- const FilterOperation& filter_operation = *filter_operations.at(0);
- if (const auto* reference_filter_operation =
- DynamicTo<ReferenceFilterOperation>(filter_operation)) {
- EnsureResources(resources).SetFilter(
- CastResource<LayoutSVGResourceFilter>(
- reference_filter_operation->Resource()));
- }
+ if (LayoutSVGResourceFilter* filter =
+ GetFilterResourceForSVG(computed_style)) {
+ EnsureResources(resources).SetFilter(filter);
}
}
- if (StyleSVGResource* masker_resource = style.MaskerResource()) {
- EnsureResources(resources).SetMasker(
- CastResource<LayoutSVGResourceMasker>(*masker_resource));
+ if (auto* masker = GetSVGResourceAsType<LayoutSVGResourceMasker>(
+ style.MaskerResource())) {
+ EnsureResources(resources).SetMasker(masker);
}
}
if (style.HasMarkers() && SupportsMarkers(element)) {
- if (StyleSVGResource* marker_start_resource = style.MarkerStartResource()) {
- EnsureResources(resources).SetMarkerStart(
- CastResource<LayoutSVGResourceMarker>(*marker_start_resource));
+ if (auto* marker = GetSVGResourceAsType<LayoutSVGResourceMarker>(
+ style.MarkerStartResource())) {
+ EnsureResources(resources).SetMarkerStart(marker);
}
- if (StyleSVGResource* marker_mid_resource = style.MarkerMidResource()) {
- EnsureResources(resources).SetMarkerMid(
- CastResource<LayoutSVGResourceMarker>(*marker_mid_resource));
+ if (auto* marker = GetSVGResourceAsType<LayoutSVGResourceMarker>(
+ style.MarkerMidResource())) {
+ EnsureResources(resources).SetMarkerMid(marker);
}
- if (StyleSVGResource* marker_end_resource = style.MarkerEndResource()) {
- EnsureResources(resources).SetMarkerEnd(
- CastResource<LayoutSVGResourceMarker>(*marker_end_resource));
+ if (auto* marker = GetSVGResourceAsType<LayoutSVGResourceMarker>(
+ style.MarkerEndResource())) {
+ EnsureResources(resources).SetMarkerEnd(marker);
}
}
if (FillAndStrokeTags().Contains(tag_name)) {
- if (StyleSVGResource* fill_resource = style.FillPaint().Resource()) {
- EnsureResources(resources).SetFill(
- CastResource<LayoutSVGResourcePaintServer>(*fill_resource));
+ if (auto* paint_resource =
+ GetSVGResourceAsType<LayoutSVGResourcePaintServer>(
+ style.FillPaint().Resource())) {
+ EnsureResources(resources).SetFill(paint_resource);
}
- if (StyleSVGResource* stroke_resource = style.StrokePaint().Resource()) {
- EnsureResources(resources).SetStroke(
- CastResource<LayoutSVGResourcePaintServer>(*stroke_resource));
+ if (auto* paint_resource =
+ GetSVGResourceAsType<LayoutSVGResourcePaintServer>(
+ style.StrokePaint().Resource())) {
+ EnsureResources(resources).SetStroke(paint_resource);
}
}
@@ -277,41 +267,28 @@ void SVGResources::LayoutIfNeeded() {
linked_resource_->LayoutIfNeeded();
}
-InvalidationModeMask SVGResources::RemoveClientFromCacheAffectingObjectBounds(
- SVGResourceClient& client) const {
- if (!clipper_filter_masker_data_)
- return 0;
- InvalidationModeMask invalidation_flags = 0;
- if (LayoutSVGResourceClipper* clipper = clipper_filter_masker_data_->clipper)
- clipper->RemoveClientFromCache(client);
- if (LayoutSVGResourceFilter* filter = clipper_filter_masker_data_->filter) {
- if (filter->RemoveClientFromCache(client))
- invalidation_flags |= SVGResourceClient::kPaintInvalidation;
- }
- if (LayoutSVGResourceMasker* masker = clipper_filter_masker_data_->masker)
- masker->RemoveClientFromCache(client);
- return invalidation_flags | SVGResourceClient::kBoundariesInvalidation;
+bool SVGResources::DifferenceNeedsLayout(const SVGResources* a,
+ const SVGResources* b) {
+ bool a_has_bounds_affecting_resource = a && a->clipper_filter_masker_data_;
+ bool b_has_bounds_affecting_resource = b && b->clipper_filter_masker_data_;
+ if (a_has_bounds_affecting_resource != b_has_bounds_affecting_resource)
+ return true;
+ if (!a_has_bounds_affecting_resource)
+ return false;
+ return a->Clipper() != b->Clipper() || a->Filter() != b->Filter() ||
+ a->Masker() != b->Masker();
}
-InvalidationModeMask SVGResources::RemoveClientFromCache(
- SVGResourceClient& client) const {
- if (!HasResourceData())
+InvalidationModeMask SVGResources::RemoveClientFromCacheAffectingObjectBounds(
+ SVGElementResourceClient& client) const {
+ if (!clipper_filter_masker_data_)
return 0;
-
- // We never call this method for the elements where this would be non-null.
- DCHECK(!linked_resource_);
-
InvalidationModeMask invalidation_flags =
- RemoveClientFromCacheAffectingObjectBounds(client);
-
- if (fill_stroke_data_) {
- if (LayoutSVGResourcePaintServer* fill = fill_stroke_data_->fill)
- fill->RemoveClientFromCache(client);
- if (LayoutSVGResourcePaintServer* stroke = fill_stroke_data_->stroke)
- stroke->RemoveClientFromCache(client);
- invalidation_flags |= SVGResourceClient::kPaintInvalidation;
+ SVGResourceClient::kBoundariesInvalidation;
+ if (clipper_filter_masker_data_->filter) {
+ if (client.ClearFilterData())
+ invalidation_flags |= SVGResourceClient::kPaintInvalidation;
}
-
return invalidation_flags;
}
@@ -465,9 +442,7 @@ void SVGResources::BuildSetOfResources(
}
void SVGResources::SetClipper(LayoutSVGResourceClipper* clipper) {
- if (!clipper)
- return;
-
+ DCHECK(clipper);
DCHECK_EQ(clipper->ResourceType(), kClipperResourceType);
if (!clipper_filter_masker_data_)
@@ -477,9 +452,7 @@ void SVGResources::SetClipper(LayoutSVGResourceClipper* clipper) {
}
void SVGResources::SetFilter(LayoutSVGResourceFilter* filter) {
- if (!filter)
- return;
-
+ DCHECK(filter);
DCHECK_EQ(filter->ResourceType(), kFilterResourceType);
if (!clipper_filter_masker_data_)
@@ -489,9 +462,7 @@ void SVGResources::SetFilter(LayoutSVGResourceFilter* filter) {
}
void SVGResources::SetMarkerStart(LayoutSVGResourceMarker* marker_start) {
- if (!marker_start)
- return;
-
+ DCHECK(marker_start);
DCHECK_EQ(marker_start->ResourceType(), kMarkerResourceType);
if (!marker_data_)
@@ -501,9 +472,7 @@ void SVGResources::SetMarkerStart(LayoutSVGResourceMarker* marker_start) {
}
void SVGResources::SetMarkerMid(LayoutSVGResourceMarker* marker_mid) {
- if (!marker_mid)
- return;
-
+ DCHECK(marker_mid);
DCHECK_EQ(marker_mid->ResourceType(), kMarkerResourceType);
if (!marker_data_)
@@ -513,9 +482,7 @@ void SVGResources::SetMarkerMid(LayoutSVGResourceMarker* marker_mid) {
}
void SVGResources::SetMarkerEnd(LayoutSVGResourceMarker* marker_end) {
- if (!marker_end)
- return;
-
+ DCHECK(marker_end);
DCHECK_EQ(marker_end->ResourceType(), kMarkerResourceType);
if (!marker_data_)
@@ -525,9 +492,7 @@ void SVGResources::SetMarkerEnd(LayoutSVGResourceMarker* marker_end) {
}
void SVGResources::SetMasker(LayoutSVGResourceMasker* masker) {
- if (!masker)
- return;
-
+ DCHECK(masker);
DCHECK_EQ(masker->ResourceType(), kMaskerResourceType);
if (!clipper_filter_masker_data_)
@@ -537,8 +502,7 @@ void SVGResources::SetMasker(LayoutSVGResourceMasker* masker) {
}
void SVGResources::SetFill(LayoutSVGResourcePaintServer* fill) {
- if (!fill)
- return;
+ DCHECK(fill);
if (!fill_stroke_data_)
fill_stroke_data_ = std::make_unique<FillStrokeData>();
@@ -547,8 +511,7 @@ void SVGResources::SetFill(LayoutSVGResourcePaintServer* fill) {
}
void SVGResources::SetStroke(LayoutSVGResourcePaintServer* stroke) {
- if (!stroke)
- return;
+ DCHECK(stroke);
if (!fill_stroke_data_)
fill_stroke_data_ = std::make_unique<FillStrokeData>();
@@ -705,6 +668,83 @@ void SVGResources::ClearMarkers(SVGElement& element,
marker_resource->RemoveClient(*client);
}
+bool FilterData::UpdateStateOnFinish() {
+ switch (state_) {
+ // A cycle can occur when an FeImage references a source that
+ // makes use of the FeImage itself. This is the first place we
+ // would hit the cycle so we reset the state and continue.
+ case kGeneratingFilterCycleDetected:
+ state_ = kGeneratingFilter;
+ return false;
+ case kRecordingContentCycleDetected:
+ state_ = kRecordingContent;
+ return false;
+ default:
+ return true;
+ }
+}
+
+void FilterData::UpdateStateOnPrepare() {
+ switch (state_) {
+ case kGeneratingFilter:
+ state_ = kGeneratingFilterCycleDetected;
+ break;
+ case kRecordingContent:
+ state_ = kRecordingContentCycleDetected;
+ break;
+ default:
+ break;
+ }
+}
+
+void FilterData::UpdateContent(sk_sp<PaintRecord> content) {
+ DCHECK_EQ(state_, kRecordingContent);
+ Filter* filter = last_effect_->GetFilter();
+ FloatRect bounds = filter->FilterRegion();
+ DCHECK(filter->GetSourceGraphic());
+ paint_filter_builder::BuildSourceGraphic(filter->GetSourceGraphic(),
+ std::move(content), bounds);
+ state_ = kReadyToPaint;
+}
+
+sk_sp<PaintFilter> FilterData::CreateFilter() {
+ DCHECK_EQ(state_, kReadyToPaint);
+ state_ = kGeneratingFilter;
+ sk_sp<PaintFilter> image_filter =
+ paint_filter_builder::Build(last_effect_, kInterpolationSpaceSRGB);
+ state_ = kReadyToPaint;
+ return image_filter;
+}
+
+FloatRect FilterData::MapRect(const FloatRect& input_rect) const {
+ DCHECK_EQ(state_, kReadyToPaint);
+ return last_effect_->MapRect(input_rect);
+}
+
+bool FilterData::Invalidate(SVGFilterPrimitiveStandardAttributes& primitive,
+ const QualifiedName& attribute) {
+ if (state_ != kReadyToPaint)
+ return true;
+ if (FilterEffect* effect = node_map_->EffectForElement(primitive)) {
+ if (!primitive.SetFilterEffectAttribute(effect, attribute))
+ return false; // No change
+ node_map_->InvalidateDependentEffects(effect);
+ }
+ return true;
+}
+
+void FilterData::Trace(Visitor* visitor) {
+ visitor->Trace(last_effect_);
+ visitor->Trace(node_map_);
+}
+
+void FilterData::Dispose() {
+ node_map_ = nullptr;
+ if (last_effect_)
+ last_effect_->DisposeImageFiltersRecursive();
+ last_effect_ = nullptr;
+}
+
SVGElementResourceClient::SVGElementResourceClient(SVGElement* element)
: element_(element) {}
@@ -713,22 +753,15 @@ void SVGElementResourceClient::ResourceContentChanged(
LayoutObject* layout_object = element_->GetLayoutObject();
if (!layout_object)
return;
- bool mark_for_invalidation =
- invalidation_mask & ~SVGResourceClient::kParentOnlyInvalidation;
if (layout_object->IsSVGResourceContainer()) {
- ToLayoutSVGResourceContainer(layout_object)
- ->RemoveAllClientsFromCache(mark_for_invalidation);
+ ToLayoutSVGResourceContainer(layout_object)->RemoveAllClientsFromCache();
return;
}
- if (mark_for_invalidation) {
- LayoutSVGResourceContainer::MarkClientForInvalidation(*layout_object,
- invalidation_mask);
- }
+ LayoutSVGResourceContainer::MarkClientForInvalidation(*layout_object,
+ invalidation_mask);
- // Special case for filter invalidation.
- if (invalidation_mask & SVGResourceClient::kSkipAncestorInvalidation)
- return;
+ ClearFilterData();
bool needs_layout =
invalidation_mask & SVGResourceClient::kLayoutInvalidation;
@@ -737,8 +770,10 @@ void SVGElementResourceClient::ResourceContentChanged(
}
void SVGElementResourceClient::ResourceElementChanged() {
- if (LayoutObject* layout_object = element_->GetLayoutObject())
+ if (LayoutObject* layout_object = element_->GetLayoutObject()) {
+ ClearFilterData();
SVGResourcesCache::ResourceReferenceChanged(*layout_object);
+ }
}
void SVGElementResourceClient::ResourceDestroyed(
@@ -752,8 +787,32 @@ void SVGElementResourceClient::ResourceDestroyed(
resources->ResourceDestroyed(resource);
}
+void SVGElementResourceClient::FilterPrimitiveChanged(
+ SVGFilterPrimitiveStandardAttributes& primitive,
+ const QualifiedName& attribute) {
+ if (filter_data_ && !filter_data_->Invalidate(primitive, attribute))
+ return; // No change
+ LayoutObject* layout_object = element_->GetLayoutObject();
+ if (!layout_object)
+ return;
+ LayoutSVGResourceContainer::MarkClientForInvalidation(
+ *layout_object, SVGResourceClient::kPaintInvalidation);
+}
+
+void SVGElementResourceClient::SetFilterData(FilterData* filter_data) {
+ filter_data_ = filter_data;
+}
+
+bool SVGElementResourceClient::ClearFilterData() {
+ FilterData* filter_data = filter_data_.Release();
+ if (filter_data)
+ filter_data->Dispose();
+ return !!filter_data;
+}
+
void SVGElementResourceClient::Trace(Visitor* visitor) {
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 5a158e2c60d..96db2ccc575 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
@@ -32,6 +32,7 @@
namespace blink {
class ComputedStyle;
+class FilterEffect;
class LayoutObject;
class LayoutSVGResourceClipper;
class LayoutSVGResourceFilter;
@@ -39,6 +40,8 @@ class LayoutSVGResourceMarker;
class LayoutSVGResourceMasker;
class LayoutSVGResourcePaintServer;
class SVGElement;
+class SVGElementResourceClient;
+class SVGFilterGraphNodeMap;
// Holds a set of resources associated with a LayoutObject
class SVGResources {
@@ -47,7 +50,8 @@ class SVGResources {
public:
SVGResources();
- static SVGResourceClient* GetClient(const LayoutObject&);
+ static SVGElementResourceClient* GetClient(const LayoutObject&);
+ static FloatRect ReferenceBoxForEffects(const LayoutObject&);
static std::unique_ptr<SVGResources> BuildResources(const LayoutObject&,
const ComputedStyle&);
@@ -110,12 +114,13 @@ class SVGResources {
void BuildSetOfResources(HashSet<LayoutSVGResourceContainer*>&);
// Methods operating on all cached resources
- InvalidationModeMask RemoveClientFromCache(SVGResourceClient&) const;
InvalidationModeMask RemoveClientFromCacheAffectingObjectBounds(
- SVGResourceClient&) const;
+ SVGElementResourceClient&) const;
void ResourceDestroyed(LayoutSVGResourceContainer*);
void ClearReferencesTo(LayoutSVGResourceContainer*);
+ static bool DifferenceNeedsLayout(const SVGResources*, const SVGResources*);
+
#if DCHECK_IS_ON()
void Dump(const LayoutObject*);
#endif
@@ -188,6 +193,51 @@ class SVGResources {
DISALLOW_COPY_AND_ASSIGN(SVGResources);
};
+class FilterData final : public GarbageCollected<FilterData> {
+ public:
+ FilterData(FilterEffect* last_effect, SVGFilterGraphNodeMap* node_map)
+ : last_effect_(last_effect),
+ node_map_(node_map),
+ state_(kRecordingContent) {}
+
+ void UpdateStateOnPrepare();
+ bool UpdateStateOnFinish();
+ bool ContentNeedsUpdate() const { return state_ == kRecordingContent; }
+ void UpdateContent(sk_sp<PaintRecord> content);
+ sk_sp<PaintFilter> CreateFilter();
+ FloatRect MapRect(const FloatRect& input_rect) const;
+ // Perform a finegrained invalidation of the filter chain for the
+ // specified filter primitive and attribute. Returns false if no
+ // further invalidation is required, otherwise true.
+ bool Invalidate(SVGFilterPrimitiveStandardAttributes& primitive,
+ const QualifiedName& attribute);
+
+ void Dispose();
+
+ void Trace(Visitor*);
+
+ private:
+ Member<FilterEffect> last_effect_;
+ Member<SVGFilterGraphNodeMap> node_map_;
+
+ /*
+ * The state transitions should follow the following:
+ *
+ * RecordingContent->ReadyToPaint->GeneratingFilter->ReadyToPaint
+ * | ^ | ^
+ * v | v |
+ * RecordingContentCycleDetected GeneratingFilterCycleDetected
+ */
+ enum FilterDataState {
+ kRecordingContent,
+ kRecordingContentCycleDetected,
+ kReadyToPaint,
+ kGeneratingFilter,
+ kGeneratingFilterCycleDetected
+ };
+ FilterDataState state_;
+};
+
class SVGElementResourceClient final
: public GarbageCollected<SVGElementResourceClient>,
public SVGResourceClient {
@@ -200,10 +250,18 @@ class SVGElementResourceClient final
void ResourceElementChanged() override;
void ResourceDestroyed(LayoutSVGResourceContainer*) override;
+ void FilterPrimitiveChanged(SVGFilterPrimitiveStandardAttributes& primitive,
+ const QualifiedName& attribute) override;
+
+ void SetFilterData(FilterData*);
+ bool ClearFilterData();
+ FilterData* GetFilterData() const { return filter_data_; }
+
void Trace(Visitor*) override;
private:
Member<SVGElement> element_;
+ Member<FilterData> filter_data_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/svg_resources_cache.cc b/chromium/third_party/blink/renderer/core/layout/svg/svg_resources_cache.cc
index 30fc8f834a4..61d0dfb9d2a 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/svg_resources_cache.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/svg_resources_cache.cc
@@ -22,6 +22,7 @@
#include <memory>
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.h"
+#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_paint_server.h"
#include "third_party/blink/renderer/core/layout/svg/svg_resources.h"
#include "third_party/blink/renderer/core/layout/svg/svg_resources_cycle_solver.h"
#include "third_party/blink/renderer/core/svg/svg_document_extensions.h"
@@ -32,7 +33,7 @@ SVGResourcesCache::SVGResourcesCache() = default;
SVGResourcesCache::~SVGResourcesCache() = default;
-bool SVGResourcesCache::AddResourcesFromLayoutObject(
+SVGResources* SVGResourcesCache::AddResourcesFromLayoutObject(
LayoutObject& object,
const ComputedStyle& style) {
DCHECK(!cache_.Contains(&object));
@@ -41,7 +42,7 @@ bool SVGResourcesCache::AddResourcesFromLayoutObject(
std::unique_ptr<SVGResources> new_resources =
SVGResources::BuildResources(object, style);
if (!new_resources)
- return false;
+ return nullptr;
// Put object in cache.
SVGResources* resources =
@@ -51,12 +52,12 @@ bool SVGResourcesCache::AddResourcesFromLayoutObject(
HashSet<LayoutSVGResourceContainer*> resource_set;
resources->BuildSetOfResources(resource_set);
- SVGResourcesCycleSolver solver(object);
+ SVGResourcesCycleSolver solver;
for (auto* resource_container : resource_set) {
- if (solver.FindCycle(resource_container))
+ if (resource_container->FindCycle(solver))
resources->ClearReferencesTo(resource_container);
}
- return true;
+ return resources;
}
bool SVGResourcesCache::RemoveResourcesFromLayoutObject(LayoutObject& object) {
@@ -64,12 +65,15 @@ bool SVGResourcesCache::RemoveResourcesFromLayoutObject(LayoutObject& object) {
return !!resources;
}
-bool SVGResourcesCache::UpdateResourcesFromLayoutObject(
+SVGResourcesCache::ResourceUpdateInfo
+SVGResourcesCache::UpdateResourcesFromLayoutObject(
LayoutObject& object,
const ComputedStyle& new_style) {
- bool did_update = RemoveResourcesFromLayoutObject(object);
- did_update |= AddResourcesFromLayoutObject(object, new_style);
- return did_update;
+ std::unique_ptr<SVGResources> old_resources = cache_.Take(&object);
+ SVGResources* new_resources = AddResourcesFromLayoutObject(object, new_style);
+ return {
+ old_resources || new_resources,
+ SVGResources::DifferenceNeedsLayout(old_resources.get(), new_resources)};
}
static inline SVGResourcesCache& ResourcesCache(Document& document) {
@@ -85,14 +89,22 @@ void SVGResourcesCache::ClientLayoutChanged(LayoutObject& object) {
SVGResources* resources = CachedResourcesForLayoutObject(object);
if (!resources)
return;
-
// Invalidate the resources if either the LayoutObject itself changed,
// or we have filter resources, which could depend on the layout of children.
if (!object.SelfNeedsLayout() && !resources->Filter())
return;
- SVGResourceClient* client = SVGResources::GetClient(object);
- if (InvalidationModeMask invalidation_flags =
- resources->RemoveClientFromCache(*client)) {
+ SVGElementResourceClient* client = SVGResources::GetClient(object);
+ InvalidationModeMask invalidation_flags =
+ resources->RemoveClientFromCacheAffectingObjectBounds(*client);
+ if (LayoutSVGResourcePaintServer* fill = resources->Fill()) {
+ fill->RemoveClientFromCache(*client);
+ invalidation_flags |= SVGResourceClient::kPaintInvalidation;
+ }
+ if (LayoutSVGResourcePaintServer* stroke = resources->Stroke()) {
+ stroke->RemoveClientFromCache(*client);
+ invalidation_flags |= SVGResourceClient::kPaintInvalidation;
+ }
+ if (invalidation_flags) {
LayoutSVGResourceContainer::MarkClientForInvalidation(object,
invalidation_flags);
}
@@ -124,28 +136,34 @@ void SVGResourcesCache::ClientStyleChanged(LayoutObject& layout_object,
if (!diff.HasDifference() || !layout_object.Parent())
return;
- // In this case the proper SVGFE*Element will decide whether the modified CSS
- // properties require
- // a relayout or paintInvalidation.
- if (layout_object.IsSVGResourceFilterPrimitive() && !diff.NeedsLayout())
- return;
+ // LayoutObjects for SVGFE*Element should not be calling this function.
+ DCHECK(!layout_object.IsSVGFilterPrimitive());
// Dynamic changes of CSS properties like 'clip-path' may require us to
// recompute the associated resources for a LayoutObject.
// TODO(fs): Avoid passing in a useless StyleDifference, but instead compare
// oldStyle/newStyle to see which resources changed to be able to selectively
// rebuild individual resources, instead of all of them.
+ bool needs_layout = false;
if (LayoutObjectCanHaveResources(layout_object)) {
SVGResourcesCache& cache = ResourcesCache(layout_object.GetDocument());
- if (cache.UpdateResourcesFromLayoutObject(layout_object, new_style))
+ auto update_info =
+ cache.UpdateResourcesFromLayoutObject(layout_object, new_style);
+ if (update_info) {
layout_object.SetNeedsPaintPropertyUpdate();
+ // Since the visual rect has the bounds of the clip-path, mask and filter
+ // baked in, and the visual rect is updated during layout, we need to
+ // trigger layout if the style change could somehow have affected the
+ // bounds that form the visual rect.
+ needs_layout = update_info.needs_layout;
+ }
}
// If this layoutObject is the child of ResourceContainer and it require
// repainting that changes of CSS properties such as 'visibility',
// request repainting.
- bool needs_layout = diff.NeedsFullPaintInvalidation() &&
- IsLayoutObjectOfResourceContainer(layout_object);
+ needs_layout |= diff.NeedsPaintInvalidation() &&
+ IsLayoutObjectOfResourceContainer(layout_object);
LayoutSVGResourceContainer::MarkForLayoutAndParentResourceInvalidation(
layout_object, needs_layout);
@@ -173,8 +191,7 @@ void SVGResourcesCache::ResourceReferenceChanged(LayoutObject& layout_object) {
layout_object, true);
}
-void SVGResourcesCache::ClientWasAddedToTree(LayoutObject& layout_object,
- const ComputedStyle& new_style) {
+void SVGResourcesCache::ClientWasAddedToTree(LayoutObject& layout_object) {
if (!layout_object.GetNode())
return;
LayoutSVGResourceContainer::MarkForLayoutAndParentResourceInvalidation(
@@ -183,7 +200,8 @@ void SVGResourcesCache::ClientWasAddedToTree(LayoutObject& layout_object,
if (!LayoutObjectCanHaveResources(layout_object))
return;
SVGResourcesCache& cache = ResourcesCache(layout_object.GetDocument());
- if (cache.AddResourcesFromLayoutObject(layout_object, new_style))
+ if (cache.AddResourcesFromLayoutObject(layout_object,
+ layout_object.StyleRef()))
layout_object.SetNeedsPaintPropertyUpdate();
}
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/svg_resources_cache.h b/chromium/third_party/blink/renderer/core/layout/svg/svg_resources_cache.h
index c44ec39599f..fe545ef76ba 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/svg_resources_cache.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/svg_resources_cache.h
@@ -42,8 +42,7 @@ class SVGResourcesCache {
static SVGResources* CachedResourcesForLayoutObject(const LayoutObject&);
// Called from all SVG layoutObjects addChild() methods.
- static void ClientWasAddedToTree(LayoutObject&,
- const ComputedStyle& new_style);
+ static void ClientWasAddedToTree(LayoutObject&);
// Called from all SVG layoutObjects removeChild() methods.
static void ClientWillBeRemovedFromTree(LayoutObject&);
@@ -84,9 +83,17 @@ class SVGResourcesCache {
};
private:
- bool AddResourcesFromLayoutObject(LayoutObject&, const ComputedStyle&);
+ struct ResourceUpdateInfo {
+ bool changed;
+ bool needs_layout;
+
+ explicit operator bool() const { return changed; }
+ };
+ SVGResources* AddResourcesFromLayoutObject(LayoutObject&,
+ const ComputedStyle&);
bool RemoveResourcesFromLayoutObject(LayoutObject&);
- bool UpdateResourcesFromLayoutObject(LayoutObject&, const ComputedStyle&);
+ ResourceUpdateInfo UpdateResourcesFromLayoutObject(LayoutObject&,
+ const ComputedStyle&);
typedef HashMap<const LayoutObject*, std::unique_ptr<SVGResources>> CacheMap;
CacheMap cache_;
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/svg_resources_cycle_solver.cc b/chromium/third_party/blink/renderer/core/layout/svg/svg_resources_cycle_solver.cc
index e39121ebe6b..5ede5cc597b 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/svg_resources_cycle_solver.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/svg_resources_cycle_solver.cc
@@ -19,99 +19,30 @@
#include "third_party/blink/renderer/core/layout/svg/svg_resources_cycle_solver.h"
-#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.h"
-#include "third_party/blink/renderer/core/layout/svg/svg_resources.h"
-#include "third_party/blink/renderer/core/layout/svg/svg_resources_cache.h"
-
namespace blink {
-SVGResourcesCycleSolver::SVGResourcesCycleSolver(LayoutObject& layout_object)
- : layout_object_(layout_object) {
- if (layout_object.IsSVGResourceContainer())
- active_resources_.insert(ToLayoutSVGResourceContainer(&layout_object));
-}
+SVGResourcesCycleSolver::SVGResourcesCycleSolver() = default;
SVGResourcesCycleSolver::~SVGResourcesCycleSolver() = default;
-class ScopedTraversalPath {
- public:
- typedef SVGResourcesCycleSolver::ResourceSet ResourceSet;
-
- ScopedTraversalPath(ResourceSet& active_set)
- : active_set_(active_set), resource_(nullptr) {}
- ~ScopedTraversalPath() {
- if (resource_)
- active_set_.erase(resource_);
- }
-
- bool Enter(LayoutSVGResourceContainer* resource) {
- if (!active_set_.insert(resource).is_new_entry)
- return false;
- resource_ = resource;
- return true;
- }
-
- private:
- ResourceSet& active_set_;
- LayoutSVGResourceContainer* resource_;
-};
-
-bool SVGResourcesCycleSolver::TraverseResourceContainer(
- LayoutSVGResourceContainer* resource) {
- // If we've traversed this sub-graph before and no cycles were observed, then
- // reuse that result.
- if (dag_cache_.Contains(resource))
- return false;
-
- ScopedTraversalPath scope(active_resources_);
- if (!scope.Enter(resource))
- return true;
-
- LayoutObject* node = resource;
- while (node) {
- // Skip subtrees which are themselves resources. (They will be
- // processed - if needed - when they are actually referenced.)
- if (node != resource && node->IsSVGResourceContainer()) {
- node = node->NextInPreOrderAfterChildren(resource);
- continue;
- }
- if (TraverseResources(*node))
- return true;
- node = node->NextInPreOrder(resource);
- }
-
- // No cycles found in (or from) this resource. Add it to the "DAG cache".
- dag_cache_.insert(resource);
- return false;
+bool SVGResourcesCycleSolver::IsKnownAcyclic(
+ const LayoutSVGResourceContainer* resource) const {
+ return dag_cache_.Contains(resource);
}
-bool SVGResourcesCycleSolver::TraverseResources(LayoutObject& layout_object) {
- SVGResources* resources =
- SVGResourcesCache::CachedResourcesForLayoutObject(layout_object);
- return resources && TraverseResources(resources);
+void SVGResourcesCycleSolver::AddAcyclicSubgraph(
+ const LayoutSVGResourceContainer* resource) {
+ dag_cache_.insert(resource);
}
-bool SVGResourcesCycleSolver::TraverseResources(SVGResources* resources) {
- // Fetch all the referenced resources.
- ResourceSet local_resources;
- resources->BuildSetOfResources(local_resources);
-
- // This performs a depth-first search for a back-edge in all the
- // (potentially disjoint) graphs formed by the referenced resources.
- for (auto* local_resource : local_resources) {
- if (TraverseResourceContainer(local_resource))
- return true;
- }
- return false;
+bool SVGResourcesCycleSolver::EnterResource(
+ const LayoutSVGResourceContainer* resource) {
+ return active_resources_.insert(resource).is_new_entry;
}
-bool SVGResourcesCycleSolver::FindCycle(
- LayoutSVGResourceContainer* start_node) {
- DCHECK(active_resources_.IsEmpty() ||
- (active_resources_.size() == 1 &&
- active_resources_.Contains(
- ToLayoutSVGResourceContainer(&layout_object_))));
- return TraverseResourceContainer(start_node);
+void SVGResourcesCycleSolver::LeaveResource(
+ const LayoutSVGResourceContainer* resource) {
+ active_resources_.erase(resource);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/svg_resources_cycle_solver.h b/chromium/third_party/blink/renderer/core/layout/svg/svg_resources_cycle_solver.h
index bf44ebdde60..6a9068479c5 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/svg_resources_cycle_solver.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/svg_resources_cycle_solver.h
@@ -21,15 +21,12 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_SVG_RESOURCES_CYCLE_SOLVER_H_
#include "base/macros.h"
+#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
namespace blink {
-class LayoutObject;
-class LayoutSVGResourceContainer;
-class SVGResources;
-
// This class traverses the graph formed by SVGResources of
// LayoutObjects, maintaining the active path as LayoutObjects are
// visited. It also maintains a cache of sub-graphs that has already
@@ -38,22 +35,40 @@ class SVGResourcesCycleSolver {
STACK_ALLOCATED();
public:
- SVGResourcesCycleSolver(LayoutObject&);
+ SVGResourcesCycleSolver();
~SVGResourcesCycleSolver();
- // Traverse the graph starting at the resource container
- // passed. Returns true if a cycle is detected.
- bool FindCycle(LayoutSVGResourceContainer*);
+ bool IsKnownAcyclic(const LayoutSVGResourceContainer*) const;
+ void AddAcyclicSubgraph(const LayoutSVGResourceContainer*);
- typedef HashSet<LayoutSVGResourceContainer*> ResourceSet;
+ class Scope {
+ STACK_ALLOCATED();
- private:
- bool TraverseResourceContainer(LayoutSVGResourceContainer*);
- bool TraverseResources(LayoutObject&);
- bool TraverseResources(SVGResources*);
+ public:
+ Scope(SVGResourcesCycleSolver& solver)
+ : solver_(solver), resource_(nullptr) {}
+ ~Scope() {
+ if (resource_)
+ solver_.LeaveResource(resource_);
+ }
+
+ bool Enter(const LayoutSVGResourceContainer* resource) {
+ if (!solver_.EnterResource(resource))
+ return false;
+ resource_ = resource;
+ return true;
+ }
- LayoutObject& layout_object_;
+ private:
+ SVGResourcesCycleSolver& solver_;
+ const LayoutSVGResourceContainer* resource_;
+ };
+
+ private:
+ bool EnterResource(const LayoutSVGResourceContainer*);
+ void LeaveResource(const LayoutSVGResourceContainer*);
+ using ResourceSet = HashSet<const LayoutSVGResourceContainer*>;
ResourceSet active_resources_;
ResourceSet dag_cache_;
DISALLOW_COPY_AND_ASSIGN(SVGResourcesCycleSolver);
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 5c3e12cf096..94ddd75bcb5 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
@@ -26,8 +26,6 @@
namespace blink {
-namespace {
-
float CalculateTextAnchorShift(const ComputedStyle& style, float length) {
bool is_ltr = style.IsLeftToRightDirection();
switch (style.SvgStyle().TextAnchor()) {
@@ -43,6 +41,8 @@ float CalculateTextAnchorShift(const ComputedStyle& style, float length) {
}
}
+namespace {
+
bool NeedsTextAnchorAdjustment(const ComputedStyle& style) {
bool is_ltr = style.IsLeftToRightDirection();
switch (style.SvgStyle().TextAnchor()) {
@@ -143,10 +143,7 @@ void SVGTextChunkBuilder::ProcessTextChunks(
}
SVGTextPathChunkBuilder::SVGTextPathChunkBuilder()
- : SVGTextChunkBuilder(),
- total_length_(0),
- total_characters_(0),
- total_text_anchor_shift_(0) {}
+ : SVGTextChunkBuilder(), total_length_(0), total_characters_(0) {}
void SVGTextPathChunkBuilder::HandleTextChunk(BoxListConstIterator box_start,
BoxListConstIterator box_end) {
@@ -155,10 +152,6 @@ void SVGTextPathChunkBuilder::HandleTextChunk(BoxListConstIterator box_start,
ChunkLengthAccumulator length_accumulator(!style.IsHorizontalWritingMode());
length_accumulator.ProcessRange(box_start, box_end);
- // Handle text-anchor as additional start offset for text paths.
- total_text_anchor_shift_ +=
- CalculateTextAnchorShift(style, length_accumulator.length());
-
total_length_ += length_accumulator.length();
total_characters_ += length_accumulator.NumCharacters();
}
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/svg_text_chunk_builder.h b/chromium/third_party/blink/renderer/core/layout/svg/svg_text_chunk_builder.h
index 4e8da8976a3..b3ba82fc438 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/svg_text_chunk_builder.h
+++ b/chromium/third_party/blink/renderer/core/layout/svg/svg_text_chunk_builder.h
@@ -26,6 +26,7 @@
namespace blink {
+class ComputedStyle;
class SVGInlineTextBox;
struct SVGTextFragment;
@@ -76,7 +77,6 @@ class SVGTextPathChunkBuilder final : public SVGTextChunkBuilder {
float TotalLength() const { return total_length_; }
unsigned TotalCharacters() const { return total_characters_; }
- float TotalTextAnchorShift() const { return total_text_anchor_shift_; }
private:
void HandleTextChunk(BoxListConstIterator box_start,
@@ -84,11 +84,13 @@ class SVGTextPathChunkBuilder final : public SVGTextChunkBuilder {
float total_length_;
unsigned total_characters_;
- float total_text_anchor_shift_;
DISALLOW_COPY_AND_ASSIGN(SVGTextPathChunkBuilder);
};
+// Compute the "shift" induced by the 'text-anchor' property.
+float CalculateTextAnchorShift(const ComputedStyle&, float length);
+
} // namespace blink
#endif
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 c2c41825bda..6f537e09faf 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
@@ -172,15 +172,15 @@ class AttributeListsIterator {
private:
SVGLengthContext length_context_;
- Member<SVGLengthList> x_list_;
+ SVGLengthList* x_list_;
unsigned x_list_remaining_;
- Member<SVGLengthList> y_list_;
+ SVGLengthList* y_list_;
unsigned y_list_remaining_;
- Member<SVGLengthList> dx_list_;
+ SVGLengthList* dx_list_;
unsigned dx_list_remaining_;
- Member<SVGLengthList> dy_list_;
+ SVGLengthList* dy_list_;
unsigned dy_list_remaining_;
- Member<SVGNumberList> rotate_list_;
+ SVGNumberList* rotate_list_;
unsigned rotate_list_remaining_;
};
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 37d9ed65f2e..956c93cc526 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(blink::Visitor*);
+ void Trace(Visitor*);
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 b4af6bc127a..7628afd5795 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
@@ -178,11 +178,7 @@ void SVGTextLayoutEngine::BeginTextPathLayout(SVGInlineFlowBox* flow_box) {
text_path_chunk_layout_builder.ProcessTextChunks(
line_layout.line_layout_boxes_);
- text_path_start_offset_ +=
- text_path_chunk_layout_builder.TotalTextAnchorShift();
- text_path_current_offset_ = text_path_start_offset_;
-
- // Eventually handle textLength adjustments.
+ // Handle 'textLength' adjustments.
SVGLengthAdjustType length_adjust = kSVGLengthAdjustUnknown;
float desired_text_length = 0;
@@ -199,20 +195,26 @@ void SVGTextLayoutEngine::BeginTextPathLayout(SVGInlineFlowBox* flow_box) {
desired_text_length = 0;
}
- if (!desired_text_length)
- return;
-
- float total_length = text_path_chunk_layout_builder.TotalLength();
- if (length_adjust == kSVGLengthAdjustSpacing) {
- text_path_spacing_ = 0;
- if (text_path_chunk_layout_builder.TotalCharacters() > 1) {
- text_path_spacing_ = desired_text_length - total_length;
- text_path_spacing_ /=
- text_path_chunk_layout_builder.TotalCharacters() - 1;
+ float text_path_content_length = text_path_chunk_layout_builder.TotalLength();
+ if (desired_text_length) {
+ if (length_adjust == kSVGLengthAdjustSpacing) {
+ text_path_spacing_ = 0;
+ if (text_path_chunk_layout_builder.TotalCharacters() > 1) {
+ text_path_spacing_ = desired_text_length - text_path_content_length;
+ text_path_spacing_ /=
+ text_path_chunk_layout_builder.TotalCharacters() - 1;
+ }
+ } else {
+ text_path_scaling_ = desired_text_length / text_path_content_length;
}
- } else {
- text_path_scaling_ = desired_text_length / total_length;
+ text_path_content_length = desired_text_length;
}
+
+ // Perform text-anchor adjustment.
+ float text_anchor_shift =
+ CalculateTextAnchorShift(text_path.StyleRef(), text_path_content_length);
+ text_path_start_offset_ += text_anchor_shift;
+ text_path_current_offset_ = text_path_start_offset_;
}
void SVGTextLayoutEngine::EndTextPathLayout() {
@@ -263,16 +265,16 @@ void SVGTextLayoutEngine::LayoutCharactersInTextBoxes(InlineFlowBox* start) {
for (InlineBox* child = start->FirstChild(); child;
child = child->NextOnLine()) {
- if (child->IsSVGInlineTextBox()) {
+ if (auto* svg_inline_text_box = DynamicTo<SVGInlineTextBox>(child)) {
DCHECK(child->GetLineLayoutItem().IsSVGInlineText());
- LayoutInlineTextBox(ToSVGInlineTextBox(child));
+ LayoutInlineTextBox(svg_inline_text_box);
} else {
// Skip generated content.
Node* node = child->GetLineLayoutItem().GetNode();
if (!node)
continue;
- SVGInlineFlowBox* flow_box = ToSVGInlineFlowBox(child);
+ auto* flow_box = To<SVGInlineFlowBox>(child);
bool is_text_path = IsA<SVGTextPathElement>(*node);
if (is_text_path)
BeginTextPathLayout(flow_box);
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/svg_text_query.cc b/chromium/third_party/blink/renderer/core/layout/svg/svg_text_query.cc
index 93250c14255..45a09e6d0aa 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/svg_text_query.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/svg_text_query.cc
@@ -93,8 +93,8 @@ static void CollectTextBoxesInFlowBox(InlineFlowBox* flow_box,
continue;
}
- if (child->IsSVGInlineTextBox())
- text_boxes.push_back(ToSVGInlineTextBox(child));
+ if (auto* svg_inline_text_box = DynamicTo<SVGInlineTextBox>(child))
+ text_boxes.push_back(svg_inline_text_box);
}
}
@@ -139,7 +139,7 @@ static void CollectTextBoxesInLogicalOrder(
text_boxes.Shrink(0);
for (InlineTextBox* text_box = text_line_layout.FirstTextBox(); text_box;
text_box = text_box->NextForSameLayoutObject())
- text_boxes.push_back(ToSVGInlineTextBox(text_box));
+ text_boxes.push_back(To<SVGInlineTextBox>(text_box));
std::sort(text_boxes.begin(), text_boxes.end(),
InlineTextBox::CompareByStart);
}
diff --git a/chromium/third_party/blink/renderer/core/layout/table_layout_algorithm_auto.cc b/chromium/third_party/blink/renderer/core/layout/table_layout_algorithm_auto.cc
index 11d8591fd6f..1b571da3649 100644
--- a/chromium/third_party/blink/renderer/core/layout/table_layout_algorithm_auto.cc
+++ b/chromium/third_party/blink/renderer/core/layout/table_layout_algorithm_auto.cc
@@ -25,6 +25,7 @@
#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_section.h"
+#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell_interface.h"
#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_interface.h"
#include "third_party/blink/renderer/core/layout/text_autosizer.h"
@@ -53,7 +54,7 @@ void TableLayoutAlgorithmAuto::RecalcColumn(unsigned eff_col) {
// we need to clear their dirty bits so that if we call
// setPreferredWidthsDirty(true) on a col or one of its descendants, we'll
// mark it's ancestors as dirty.
- ToLayoutTableCol(child)->ClearPreferredLogicalWidthsDirtyBits();
+ ToLayoutTableCol(child)->ClearIntrinsicLogicalWidthsDirtyBits();
} else if (child->IsTableSection()) {
LayoutTableSection* section = To<LayoutTableSection>(child);
unsigned num_rows = section->NumRows();
@@ -67,17 +68,20 @@ void TableLayoutAlgorithmAuto::RecalcColumn(unsigned eff_col) {
continue;
column_layout.column_has_no_cells = false;
- if (cell->MaxPreferredLogicalWidth())
+ MinMaxSizes cell_preferred_logical_widths =
+ cell->PreferredLogicalWidths();
+
+ if (cell_preferred_logical_widths.max_size)
column_layout.empty_cells_only = false;
if (cell->ColSpan() == 1) {
column_layout.min_logical_width =
- std::max<int>(cell->MinPreferredLogicalWidth().ToInt(),
+ std::max<int>(cell_preferred_logical_widths.min_size.ToInt(),
column_layout.min_logical_width);
- if (cell->MaxPreferredLogicalWidth() >
+ if (cell_preferred_logical_widths.max_size >
column_layout.max_logical_width) {
column_layout.max_logical_width =
- cell->MaxPreferredLogicalWidth().ToInt();
+ cell_preferred_logical_widths.max_size.ToInt();
max_contributor = cell;
}
@@ -143,7 +147,7 @@ void TableLayoutAlgorithmAuto::RecalcColumn(unsigned eff_col) {
// min/max width of at least 1px for it.
column_layout.min_logical_width =
std::max<int>(column_layout.min_logical_width,
- cell->MaxPreferredLogicalWidth() ? 1 : 0);
+ cell_preferred_logical_widths.max_size ? 1 : 0);
// This spanning cell originates in this column. Insert the cell into
// spanning cells list.
@@ -220,7 +224,7 @@ static bool ShouldScaleColumnsForParent(LayoutTable* table) {
// TODO(layout-dev): We can probably abort before reaching LayoutView in many
// cases. For example, if we find an object with contain:size, or even if we
// find a regular block with fixed logical width.
- while (!cb->IsLayoutView()) {
+ while (!IsA<LayoutView>(cb)) {
// It doesn't matter if our table is auto or fixed: auto means we don't
// scale. Fixed doesn't care if we do or not because it doesn't depend
// on the cell contents' preferred widths.
@@ -262,7 +266,7 @@ static bool ShouldScaleColumnsForSelf(LayoutNGTableInterface* table) {
return true;
LayoutBlock* cb = layout_table->ContainingBlock();
- while (!cb->IsLayoutView() && !cb->IsTableCell() &&
+ while (!IsA<LayoutView>(cb) && !cb->IsTableCell() &&
cb->StyleRef().Width().IsAuto() && !cb->IsOutOfFlowPositioned())
cb = cb->ContainingBlock();
@@ -404,10 +408,13 @@ int TableLayoutAlgorithmAuto::CalcEffectiveLogicalWidth() {
unsigned eff_col =
table_->AbsoluteColumnToEffectiveColumn(cell->AbsoluteColumnIndex());
wtf_size_t last_col = eff_col;
+ MinMaxSizes cell_preferred_logical_widths = cell->PreferredLogicalWidths();
int cell_min_logical_width =
- (cell->MinPreferredLogicalWidth() + spacing_in_row_direction).ToInt();
+ (cell_preferred_logical_widths.min_size + spacing_in_row_direction)
+ .ToInt();
int cell_max_logical_width =
- (cell->MaxPreferredLogicalWidth() + spacing_in_row_direction).ToInt();
+ (cell_preferred_logical_widths.max_size + spacing_in_row_direction)
+ .ToInt();
float total_percent = 0;
int span_min_logical_width = 0;
int span_max_logical_width = 0;
@@ -538,8 +545,11 @@ int TableLayoutAlgorithmAuto::CalcEffectiveLogicalWidth() {
layout_struct_[pos].effective_min_logical_width =
std::max(layout_struct_[pos].effective_min_logical_width,
column_min_logical_width);
+ column_max_logical_width =
+ std::max(column_max_logical_width, column_min_logical_width);
layout_struct_[pos].effective_max_logical_width =
- column_max_logical_width;
+ std::max(layout_struct_[pos].effective_max_logical_width,
+ column_max_logical_width);
allocated_min_logical_width += column_min_logical_width;
allocated_max_logical_width += column_max_logical_width;
}
diff --git a/chromium/third_party/blink/renderer/core/layout/table_layout_algorithm_fixed.cc b/chromium/third_party/blink/renderer/core/layout/table_layout_algorithm_fixed.cc
index f869ceb3a9d..7081480b880 100644
--- a/chromium/third_party/blink/renderer/core/layout/table_layout_algorithm_fixed.cc
+++ b/chromium/third_party/blink/renderer/core/layout/table_layout_algorithm_fixed.cc
@@ -91,9 +91,9 @@ int TableLayoutAlgorithmFixed::CalcWidthArray() {
col = col->NextColumn()) {
// LayoutTableCols don't have the concept of preferred logical width, but we
// need to clear their dirty bits so that if we call
- // setPreferredWidthsDirty(true) on a col or one of its descendants, we'll
+ // SetPreferredWidthsDirty(true) on a col or one of its descendants, we'll
// mark it's ancestors as dirty.
- col->ClearPreferredLogicalWidthsDirtyBits();
+ col->ClearIntrinsicLogicalWidthsDirtyBits();
// Width specified by column-groups that have column child does not affect
// column width in fixed layout tables
@@ -184,12 +184,12 @@ int TableLayoutAlgorithmFixed::CalcWidthArray() {
++current_column;
}
- // TableLayoutAlgorithmFixed doesn't use min/maxPreferredLogicalWidths, but
- // we need to clear the dirty bit on the cell so that we'll correctly mark
- // its ancestors dirty in case we later call
- // setPreferredLogicalWidthsDirty() on it later.
- if (cell->PreferredLogicalWidthsDirty())
- cell->ClearPreferredLogicalWidthsDirty();
+ // TableLayoutAlgorithmFixed doesn't use PreferredLogicalWidths, but we
+ // need to clear the dirty bit on the cell so that we'll correctly mark its
+ // ancestors dirty in case we later call SetIntrinsicLogicalWidthsDirty()
+ // on it later.
+ if (cell->IntrinsicLogicalWidthsDirty())
+ cell->ClearIntrinsicLogicalWidthsDirty();
}
return used_width;
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 400c1ee28e5..f3609dc9801 100644
--- a/chromium/third_party/blink/renderer/core/layout/text_autosizer.cc
+++ b/chromium/third_party/blink/renderer/core/layout/text_autosizer.cc
@@ -52,7 +52,6 @@
#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/ng/list/layout_ng_list_item.h"
-#include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
#include "third_party/blink/renderer/core/layout/style_retain_scope.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
@@ -112,7 +111,7 @@ static bool IsPotentialClusterRoot(const LayoutObject* layout_object) {
// - Must not be normal list items, as items in the same list should look
// consistent, unless they are floating or position:absolute/fixed.
Node* node = layout_object->GeneratingNode();
- if (node && !node->hasChildren() && !layout_object->IsLayoutView())
+ if (node && !node->hasChildren() && !IsA<LayoutView>(layout_object))
return false;
if (!layout_object->IsLayoutBlock())
return false;
@@ -130,7 +129,7 @@ static bool IsIndependentDescendant(const LayoutBlock* layout_object) {
DCHECK(IsPotentialClusterRoot(layout_object));
LayoutBlock* containing_block = layout_object->ContainingBlock();
- return layout_object->IsLayoutView() || layout_object->IsFloating() ||
+ return IsA<LayoutView>(layout_object) || layout_object->IsFloating() ||
layout_object->IsOutOfFlowPositioned() ||
layout_object->IsTableCell() || layout_object->IsTableCaption() ||
layout_object->IsFlexibleBoxIncludingDeprecatedAndNG() ||
@@ -196,7 +195,7 @@ static bool BlockHeightConstrained(const LayoutBlock* block) {
// height:100%, without intending to constrain the height of the content
// within them.
return !block->IsDocumentElement() && !block->IsBody() &&
- !block->IsLayoutView();
+ !IsA<LayoutView>(block);
}
if (block->IsFloating())
return false;
@@ -324,7 +323,7 @@ TextAutosizer::BeginLayoutBehavior TextAutosizer::PrepareForLayout(
if (!first_block_to_begin_layout_) {
first_block_to_begin_layout_ = block;
PrepareClusterStack(block->Parent());
- if (block->IsLayoutView())
+ if (IsA<LayoutView>(block))
CheckSuperclusterConsistency();
} else if (block == CurrentCluster()->root_) {
// Ignore beginLayout on the same block twice.
@@ -359,7 +358,7 @@ void TextAutosizer::BeginLayout(LayoutBlock* block,
if (block->IsRubyRun() || block->IsRubyBase() || block->IsRubyText())
return;
- DCHECK(!cluster_stack_.IsEmpty() || block->IsLayoutView());
+ DCHECK(!cluster_stack_.IsEmpty() || IsA<LayoutView>(block));
if (cluster_stack_.IsEmpty())
did_check_cross_site_use_count_ = false;
@@ -465,11 +464,11 @@ float TextAutosizer::Inflate(LayoutObject* parent,
if (behavior == kDescendToInnerBlocks) {
// The ancestor nodes might be inline-blocks. We should
- // setPreferredLogicalWidthsDirty for ancestor nodes here.
- child->SetPreferredLogicalWidthsDirty();
+ // SetIntrinsicLogicalWidthsDirty for ancestor nodes here.
+ child->SetIntrinsicLogicalWidthsDirty();
} else if (parent->IsLayoutInline()) {
// FIXME: Investigate why MarkOnlyThis is sufficient.
- child->SetPreferredLogicalWidthsDirty(kMarkOnlyThis);
+ child->SetIntrinsicLogicalWidthsDirty(kMarkOnlyThis);
}
} else if (child->IsLayoutInline()) {
multiplier = Inflate(child, layouter, behavior, multiplier);
@@ -509,12 +508,13 @@ float TextAutosizer::Inflate(LayoutObject* parent,
else if (parent->IsLayoutNGListItem())
marker = ToLayoutNGListItem(parent)->Marker();
- // A LayoutNGListMarker has a text child that needs its font multiplier
- // updated. Just mark the entire subtree, to make sure we get to it.
+ // A LayoutNGOutsideListMarker has a text child that needs its font
+ // multiplier updated. Just mark the entire subtree, to make sure we get to
+ // it.
for (LayoutObject* walker = marker; walker;
walker = walker->NextInPreOrder(marker)) {
ApplyMultiplier(walker, multiplier, layouter);
- walker->SetPreferredLogicalWidthsDirty(kMarkOnlyThis);
+ walker->SetIntrinsicLogicalWidthsDirty(kMarkOnlyThis);
}
}
@@ -604,7 +604,7 @@ void TextAutosizer::UpdatePageInfoInAllFrames(Frame* main_frame) {
page_info.shared_info_);
// Remember the RemotePageSettings in the mainframe's renderer so we
// know when they change.
- document->GetPage()->SetTextAutosizePageInfo(page_info.shared_info_);
+ document->GetPage()->SetTextAutosizerPageInfo(page_info.shared_info_);
}
}
}
@@ -881,7 +881,7 @@ TextAutosizer::Cluster* TextAutosizer::MaybeCreateCluster(LayoutBlock* block) {
Cluster* parent_cluster =
cluster_stack_.IsEmpty() ? nullptr : CurrentCluster();
- DCHECK(parent_cluster || block->IsLayoutView());
+ DCHECK(parent_cluster || IsA<LayoutView>(block));
// If a non-independent block would not alter the SUPPRESSING flag, it doesn't
// need to be a cluster.
@@ -1091,7 +1091,7 @@ const LayoutBlock* TextAutosizer::DeepestBlockContainingAllText(
const LayoutBlock* root) const {
// To avoid font-size shaking caused by the change of LayoutView's
// DeepestBlockContainingAllText.
- if (root->IsLayoutView())
+ if (IsA<LayoutView>(root))
return root;
size_t first_depth = 0;
@@ -1171,10 +1171,9 @@ const LayoutObject* TextAutosizer::FindTextLeaf(
}
static bool IsCrossSite(const Frame& frame1, const Frame& frame2) {
- // Cross-site differs from cross-origin (LocalFrame::IsCrossOriginSubframe).
- // For example, http://foo.com and http://sub.foo.com are cross-origin but
- // same-site. Only cross-site text autosizing is impacted by site isolation
- // (crbug.com/393285).
+ // Cross-site differs from cross-origin. For example, http://foo.com and
+ // http://sub.foo.com are cross-origin but same-site. Only cross-site text
+ // autosizing is impacted by site isolation (crbug.com/393285).
const auto* origin1 = frame1.GetSecurityContext()->GetSecurityOrigin();
const auto* origin2 = frame2.GetSecurityContext()->GetSecurityOrigin();
@@ -1441,17 +1440,18 @@ TextAutosizer::DeferUpdatePageInfo::DeferUpdatePageInfo(Page* page)
}
}
-TextAutosizer::NGLayoutScope::NGLayoutScope(const NGBlockNode& node,
+TextAutosizer::NGLayoutScope::NGLayoutScope(LayoutBox* box,
LayoutUnit inline_size)
- : text_autosizer_(node.GetLayoutBox()->GetDocument().GetTextAutosizer()),
- block_(To<LayoutBlockFlow>(node.GetLayoutBox())) {
+ : text_autosizer_(box->GetDocument().GetTextAutosizer()), box_(box) {
+ // Bail if:
+ // - Text autosizing isn't enabled.
+ // - If the chid isn't a LayoutBlock.
+ // - If the child is a LayoutNGOutsideListMarker. (They are super-small
+ // blocks, and using them to determine if we should autosize the text will
+ // typically false, overriding whatever its parent has already correctly
+ // determined).
if (!text_autosizer_ || !text_autosizer_->ShouldHandleLayout() ||
- block_->IsLayoutNGListMarker()) {
- // Bail if text autosizing isn't enabled, but also if this is a
- // IsLayoutNGListMarker. They are super-small blocks, and using them to
- // determine if we should autosize the text will typically always yield
- // false, overriding whatever its parent (typically the list item) has
- // already correctly determined.
+ box_->IsLayoutNGOutsideListMarker() || !box_->IsLayoutBlock()) {
text_autosizer_ = nullptr;
return;
}
@@ -1460,14 +1460,14 @@ TextAutosizer::NGLayoutScope::NGLayoutScope(const NGBlockNode& node,
// know the inline size of the block. So set it. LayoutNG normally writes back
// to the legacy tree *after* layout, but this one must be set before, at
// least if the autosizer is enabled.
- block_->SetLogicalWidth(inline_size);
+ box_->SetLogicalWidth(inline_size);
- text_autosizer_->BeginLayout(block_, nullptr);
+ text_autosizer_->BeginLayout(To<LayoutBlock>(box_), nullptr);
}
TextAutosizer::NGLayoutScope::~NGLayoutScope() {
if (text_autosizer_)
- text_autosizer_->EndLayout(block_);
+ text_autosizer_->EndLayout(To<LayoutBlock>(box_));
}
TextAutosizer::DeferUpdatePageInfo::~DeferUpdatePageInfo() {
@@ -1548,7 +1548,7 @@ void TextAutosizer::CheckSuperclusterConsistency() {
potentially_inconsistent_superclusters.clear();
}
-void TextAutosizer::Trace(blink::Visitor* visitor) {
+void TextAutosizer::Trace(Visitor* visitor) {
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 19111b9123b..7a6390abf7b 100644
--- a/chromium/third_party/blink/renderer/core/layout/text_autosizer.h
+++ b/chromium/third_party/blink/renderer/core/layout/text_autosizer.h
@@ -47,11 +47,11 @@ class Document;
class Frame;
class IntSize;
class LayoutBlock;
+class LayoutBox;
class LayoutNGTableInterface;
class LayoutObject;
class LayoutText;
class LocalFrame;
-class NGBlockNode;
class Page;
class SubtreeLayoutScope;
@@ -80,7 +80,7 @@ class CORE_EXPORT TextAutosizer final : public GarbageCollected<TextAutosizer> {
bool PageNeedsAutosizing() const;
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
class LayoutScope {
STACK_ALLOCATED();
@@ -90,7 +90,7 @@ class CORE_EXPORT TextAutosizer final : public GarbageCollected<TextAutosizer> {
~LayoutScope();
protected:
- Member<TextAutosizer> text_autosizer_;
+ TextAutosizer* text_autosizer_;
LayoutBlock* block_;
};
@@ -105,12 +105,12 @@ class CORE_EXPORT TextAutosizer final : public GarbageCollected<TextAutosizer> {
STACK_ALLOCATED();
public:
- explicit NGLayoutScope(const NGBlockNode& node, LayoutUnit inline_size);
+ explicit NGLayoutScope(LayoutBox*, LayoutUnit inline_size);
~NGLayoutScope();
protected:
- Member<TextAutosizer> text_autosizer_;
- LayoutBlock* block_;
+ TextAutosizer* text_autosizer_;
+ LayoutBox* box_;
};
class CORE_EXPORT DeferUpdatePageInfo {
@@ -121,7 +121,7 @@ class CORE_EXPORT TextAutosizer final : public GarbageCollected<TextAutosizer> {
~DeferUpdatePageInfo();
private:
- Member<LocalFrame> main_frame_;
+ LocalFrame* main_frame_;
};
private:
diff --git a/chromium/third_party/blink/renderer/core/layout/text_autosizer_test.cc b/chromium/third_party/blink/renderer/core/layout/text_autosizer_test.cc
index fcf01c4cbce..dd9ad6e1102 100644
--- a/chromium/third_party/blink/renderer/core/layout/text_autosizer_test.cc
+++ b/chromium/third_party/blink/renderer/core/layout/text_autosizer_test.cc
@@ -579,7 +579,7 @@ TEST_F(TextAutosizerTest, ChangingSuperClusterFirstText) {
UpdateAllLifecyclePhasesForTest();
Element* long_text_element = GetDocument().getElementById("longText");
- long_text_element->SetInnerHTMLFromString(
+ long_text_element->setInnerHTML(
" Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed "
"do eiusmod tempor"
" incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
@@ -624,7 +624,7 @@ TEST_F(TextAutosizerTest, ChangingSuperClusterSecondText) {
UpdateAllLifecyclePhasesForTest();
Element* long_text_element = GetDocument().getElementById("longText");
- long_text_element->SetInnerHTMLFromString(
+ long_text_element->setInnerHTML(
" Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed "
"do eiusmod tempor"
" incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
@@ -669,7 +669,7 @@ TEST_F(TextAutosizerTest, AddingSuperCluster) {
UpdateAllLifecyclePhasesForTest();
Element* container = GetDocument().getElementById("container");
- container->SetInnerHTMLFromString(
+ container->setInnerHTML(
"<div class='supercluster' id='longText'>"
" Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed "
"do eiusmod tempor"
@@ -717,7 +717,7 @@ TEST_F(TextAutosizerTest, ChangingInheritedClusterTextInsideSuperCluster) {
UpdateAllLifecyclePhasesForTest();
Element* long_text_element = GetDocument().getElementById("longText");
- long_text_element->SetInnerHTMLFromString(
+ long_text_element->setInnerHTML(
" Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed "
"do eiusmod tempor"
" incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
@@ -803,7 +803,7 @@ TEST_F(TextAutosizerTest, ResizeAndGlyphOverflowChanged) {
GetDocument().GetSettings()->SetTextAutosizingWindowSizeOverride(
IntSize(360, 640));
Element* html = GetDocument().body()->parentElement();
- html->SetInnerHTMLFromString(
+ html->setInnerHTML(
"<head>"
" <meta name='viewport' content='width=800'>"
" <style>"
@@ -843,7 +843,7 @@ TEST_F(TextAutosizerTest, ResizeAndGlyphOverflowChanged) {
TEST_F(TextAutosizerTest, narrowContentInsideNestedWideBlock) {
Element* html = GetDocument().body()->parentElement();
- html->SetInnerHTMLFromString(
+ html->setInnerHTML(
"<head>"
" <meta name='viewport' content='width=800'>"
" <style>"
@@ -879,7 +879,7 @@ TEST_F(TextAutosizerTest, narrowContentInsideNestedWideBlock) {
TEST_F(TextAutosizerTest, LayoutViewWidthProvider) {
Element* html = GetDocument().body()->parentElement();
- html->SetInnerHTMLFromString(
+ html->setInnerHTML(
"<head>"
" <meta name='viewport' content='width=800'>"
" <style>"
@@ -908,8 +908,8 @@ TEST_F(TextAutosizerTest, LayoutViewWidthProvider) {
EXPECT_FLOAT_EQ(40.f,
content->GetLayoutObject()->StyleRef().ComputedFontSize());
- GetDocument().getElementById("panel")->SetInnerHTMLFromString("insert text");
- content->SetInnerHTMLFromString(content->InnerHTMLAsString());
+ GetDocument().getElementById("panel")->setInnerHTML("insert text");
+ content->setInnerHTML(content->innerHTML());
UpdateAllLifecyclePhasesForTest();
// (specified font-size = 16px) * (viewport width = 800px) /
@@ -920,7 +920,7 @@ TEST_F(TextAutosizerTest, LayoutViewWidthProvider) {
TEST_F(TextAutosizerTest, MultiColumns) {
Element* html = GetDocument().body()->parentElement();
- html->SetInnerHTMLFromString(
+ html->setInnerHTML(
"<head>"
" <meta name='viewport' content='width=800'>"
" <style>"
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 d65144043d6..cd5349c1f8f 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
@@ -287,7 +287,7 @@ TEST_P(VisualRectMappingTest, LayoutView) {
// This case involves clipping: frame height is 50, y-coordinate of result
// rect is 13, so height should be clipped to (50 - 13) == 37.
ChildDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, 47), kProgrammaticScroll);
+ ScrollOffset(0, 47), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
PhysicalRect original_rect(4, 60, 20, 80);
@@ -363,7 +363,7 @@ TEST_P(VisualRectMappingTest, LayoutViewDisplayNone) {
// This part is copied from the LayoutView test, just to ensure that the
// mapped rect is valid before display:none is set on the iframe.
ChildDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, 47), kProgrammaticScroll);
+ ScrollOffset(0, 47), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
PhysicalRect original_rect(4, 60, 20, 80);
@@ -761,7 +761,8 @@ TEST_P(VisualRectMappingTest,
To<LayoutBlock>(GetLayoutObjectByElementId("stacking-context"));
auto* absolute = To<LayoutBlock>(GetLayoutObjectByElementId("absolute"));
auto* container = To<LayoutBlock>(GetLayoutObjectByElementId("container"));
- EXPECT_EQ(absolute->View(), &absolute->ContainerForPaintInvalidation());
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ EXPECT_EQ(absolute->View(), &absolute->ContainerForPaintInvalidation());
EXPECT_EQ(container, absolute->Container());
PhysicalRect absolute_visual_rect = absolute->LocalVisualRect();
@@ -1188,7 +1189,7 @@ TEST_P(VisualRectMappingTest, FixedContentsInIframe) {
root_view, kDefaultVisualRectFlags, true);
ChildDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, 50), kProgrammaticScroll);
+ ScrollOffset(0, 50), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
// The fixed element should not scroll so the mapped visual rect should not
@@ -1221,8 +1222,8 @@ TEST_P(VisualRectMappingTest, FixedContentsWithScrollOffset) {
PhysicalRect(0, -10, 400, 300), fixed,
ancestor, kDefaultVisualRectFlags, true);
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 50),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 50), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
// The fixed element does not scroll but the ancestor does which changes the
@@ -1249,8 +1250,8 @@ TEST_P(VisualRectMappingTest, FixedContentsUnderViewWithScrollOffset) {
PhysicalRect(0, 0, 400, 300), PhysicalRect(0, 0, 400, 300), fixed,
fixed->View(), kDefaultVisualRectFlags, true);
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 50),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 50), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
// Results of mapping to ancestor are in absolute coordinates of the
diff --git a/chromium/third_party/blink/renderer/core/loader/BUILD.gn b/chromium/third_party/blink/renderer/core/loader/BUILD.gn
index 0b517e7463b..286d10f505c 100644
--- a/chromium/third_party/blink/renderer/core/loader/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/loader/BUILD.gn
@@ -20,12 +20,16 @@ blink_core_sources("loader") {
"base_fetch_context.h",
"cookie_jar.cc",
"cookie_jar.h",
+ "cross_thread_resource_timing_info_copier.cc",
+ "cross_thread_resource_timing_info_copier.h",
"document_load_timing.cc",
"document_load_timing.h",
"document_loader.cc",
"document_loader.h",
"empty_clients.cc",
"empty_clients.h",
+ "font_preload_manager.cc",
+ "font_preload_manager.h",
"form_submission.cc",
"form_submission.h",
"frame_fetch_context.cc",
@@ -105,6 +109,7 @@ blink_core_sources("loader") {
"previews_resource_loading_hints.h",
"private/frame_client_hints_preferences_context.cc",
"private/frame_client_hints_preferences_context.h",
+ "private/prerender_client.h",
"private/prerender_handle.cc",
"private/prerender_handle.h",
"progress_tracker.cc",
@@ -158,7 +163,5 @@ blink_core_sources("loader") {
"worker_resource_timing_notifier_impl.h",
]
- public_deps = [
- "//third_party/blink/renderer/platform",
- ]
+ public_deps = [ "//third_party/blink/renderer/platform" ]
}
diff --git a/chromium/third_party/blink/renderer/core/loader/DEPS b/chromium/third_party/blink/renderer/core/loader/DEPS
index 0d1f45e4ad4..528c6cb134d 100644
--- a/chromium/third_party/blink/renderer/core/loader/DEPS
+++ b/chromium/third_party/blink/renderer/core/loader/DEPS
@@ -2,4 +2,7 @@ specific_include_rules = {
"alternate_signed_exchange_resource_info.cc" : [
"+net/http/http_request_headers.h"
],
+ "progress_tracker_test.cc" : [
+ "+base/run_loop.h"
+ ],
}
diff --git a/chromium/third_party/blink/renderer/core/loader/alternate_signed_exchange_resource_info.cc b/chromium/third_party/blink/renderer/core/loader/alternate_signed_exchange_resource_info.cc
index ddc6ee5674f..35ae1b9c22f 100644
--- a/chromium/third_party/blink/renderer/core/loader/alternate_signed_exchange_resource_info.cc
+++ b/chromium/third_party/blink/renderer/core/loader/alternate_signed_exchange_resource_info.cc
@@ -6,7 +6,7 @@
#include "net/http/http_request_headers.h"
#include "third_party/blink/public/common/web_package/signed_exchange_consts.h"
-#include "third_party/blink/public/common/web_package/signed_exchange_request_matcher.h"
+#include "third_party/blink/public/common/web_package/web_package_request_matcher.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource.h"
@@ -22,8 +22,10 @@ namespace {
constexpr char kAlternate[] = "alternate";
constexpr char kAllowedAltSxg[] = "allowed-alt-sxg";
-// These accept header values are also defined in web_url_loader_impl.h and
-// loader_util.h. TODO(horo): Move somewhere and use shared constant value.
+// These accept header values are also defined in
+// blink/renderer/platform/loader/fetch/url_loader/fetch_conversion.cc and
+// services/network/loader_util.h.
+// TODO(horo): Move somewhere and use shared constant value.
const char kDefaultAcceptHeader[] = "*/*";
const char kStylesheetAcceptHeader[] = "text/css,*/*;q=0.1";
const char kImageAcceptHeader[] = "image/webp,image/apng,image/*,*/*;q=0.8";
@@ -175,9 +177,9 @@ AlternateSignedExchangeResourceInfo::FindMatchingEntry(
accept_langs += language.Utf8();
}
net::HttpRequestHeaders request_headers;
- request_headers.SetHeader("accept", accept_header);
+ request_headers.SetHeader(net::HttpRequestHeaders::kAccept, accept_header);
- SignedExchangeRequestMatcher matcher(request_headers, accept_langs);
+ WebPackageRequestMatcher matcher(request_headers, accept_langs);
const auto variant_keys_list_it =
matcher.FindBestMatchingVariantKey(variants, variant_keys_list);
if (variant_keys_list_it == variant_keys_list.end())
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 ec3dd6982d2..f554a26f1f6 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
@@ -30,7 +30,6 @@
#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/hosts_using_features.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/loader/appcache/application_cache_host_for_frame.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
@@ -41,12 +40,14 @@
namespace blink {
ApplicationCache::ApplicationCache(LocalFrame* frame) : DOMWindowClient(frame) {
+ DCHECK(RuntimeEnabledFeatures::AppCacheEnabled(
+ frame->GetDocument()->ToExecutionContext()));
ApplicationCacheHostForFrame* cache_host = GetApplicationCacheHost();
if (cache_host)
cache_host->SetApplicationCache(this);
}
-void ApplicationCache::Trace(blink::Visitor* visitor) {
+void ApplicationCache::Trace(Visitor* visitor) {
EventTargetWithInlineData::Trace(visitor);
DOMWindowClient::Trace(visitor);
}
@@ -119,7 +120,7 @@ const AtomicString& ApplicationCache::InterfaceName() const {
}
ExecutionContext* ApplicationCache::GetExecutionContext() const {
- return GetFrame() ? GetFrame()->GetDocument() : nullptr;
+ return GetFrame() ? GetFrame()->GetDocument()->ToExecutionContext() : nullptr;
}
const AtomicString& ApplicationCache::ToEventType(mojom::AppCacheEventID id) {
@@ -154,16 +155,9 @@ void ApplicationCache::RecordAPIUseType() const {
if (!document)
return;
- if (document->IsSecureContext()) {
- Deprecation::CountDeprecation(document,
- WebFeature::kApplicationCacheAPISecureOrigin);
- } else {
- Deprecation::CountDeprecation(
- document, WebFeature::kApplicationCacheAPIInsecureOrigin);
- HostsUsingFeatures::CountAnyWorld(
- *document,
- HostsUsingFeatures::Feature::kApplicationCacheAPIInsecureHost);
- }
+ CHECK(document->IsSecureContext());
+ Deprecation::CountDeprecation(document,
+ WebFeature::kApplicationCacheAPISecureOrigin);
}
} // namespace blink
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 cc2bb42e4e8..002ab6c55ec 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
@@ -28,7 +28,7 @@
#include "third_party/blink/public/mojom/appcache/appcache.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -68,7 +68,7 @@ class ApplicationCache final : public EventTargetWithInlineData,
static const AtomicString& ToEventType(mojom::AppCacheEventID);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void RecordAPIUseType() const;
diff --git a/chromium/third_party/blink/renderer/core/loader/appcache/application_cache.idl b/chromium/third_party/blink/renderer/core/loader/appcache/application_cache.idl
index a23cef92858..0efa1074910 100644
--- a/chromium/third_party/blink/renderer/core/loader/appcache/application_cache.idl
+++ b/chromium/third_party/blink/renderer/core/loader/appcache/application_cache.idl
@@ -28,6 +28,7 @@
[
Exposed=Window,
DoNotCheckConstants,
+ RuntimeEnabled=AppCache,
SecureContext=RestrictAppCacheToSecureContexts
] interface ApplicationCache : EventTarget {
// update status
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 88409036ad4..69bc7f24209 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
@@ -35,10 +35,8 @@
#include "mojo/public/cpp/bindings/pending_remote.h"
#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/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
-#include "third_party/blink/renderer/core/frame/hosts_using_features.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/inspector/inspector_application_cache_agent.h"
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 2ab5f3b9d6c..78e37fc991c 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
@@ -108,7 +108,7 @@ class CORE_EXPORT ApplicationCacheHost
mojo::PendingRemote<network::mojom::blink::URLLoaderFactory>
url_loader_factory) override {}
- virtual void Trace(blink::Visitor*) {}
+ virtual void Trace(Visitor*) {}
protected:
mojo::Remote<mojom::blink::AppCacheHost> backend_host_;
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 5fc81efa5db..551b8d5f573 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
@@ -16,6 +16,7 @@
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/web_test_support.h"
namespace blink {
@@ -124,17 +125,20 @@ void ApplicationCacheHostForFrame::LogMessage(
// TODO(michaeln): Make app cache host per-frame and correctly report to the
// involved frame.
auto* local_frame = DynamicTo<LocalFrame>(main_frame);
- local_frame->GetDocument()->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kOther, log_level, message));
+ local_frame->GetDocument()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(mojom::ConsoleMessageSource::kOther,
+ log_level, message));
}
void ApplicationCacheHostForFrame::SetSubresourceFactory(
mojo::PendingRemote<network::mojom::blink::URLLoaderFactory>
url_loader_factory) {
auto pending_factories = std::make_unique<PendingURLLoaderFactoryBundle>();
+ // |PassPipe()| invalidates all state, so capture |version()| first.
+ uint32_t version = url_loader_factory.version();
pending_factories->pending_appcache_factory() =
mojo::PendingRemote<network::mojom::URLLoaderFactory>(
- url_loader_factory.PassPipe(), url_loader_factory.version());
+ url_loader_factory.PassPipe(), version);
local_frame_->Client()->UpdateSubresourceFactory(
std::move(pending_factories));
}
@@ -204,21 +208,14 @@ void ApplicationCacheHostForFrame::SelectCacheWithManifest(
const KURL& manifest_url) {
LocalFrame* frame = document_loader_->GetFrame();
Document* document = frame->GetDocument();
- if (document->IsSandboxed(WebSandboxFlags::kOrigin)) {
+ if (document->IsSandboxed(mojom::blink::WebSandboxFlags::kOrigin)) {
// Prevent sandboxes from establishing application caches.
SelectCacheWithoutManifest();
return;
}
- if (document->IsSecureContext()) {
- Deprecation::CountDeprecation(
- document, WebFeature::kApplicationCacheManifestSelectSecureOrigin);
- } else {
- Deprecation::CountDeprecation(
- document, WebFeature::kApplicationCacheManifestSelectInsecureOrigin);
- HostsUsingFeatures::CountAnyWorld(
- *document, HostsUsingFeatures::Feature::
- kApplicationCacheManifestSelectInsecureHost);
- }
+ CHECK(document->IsSecureContext());
+ Deprecation::CountDeprecation(
+ document, WebFeature::kApplicationCacheManifestSelectSecureOrigin);
if (!backend_host_.is_bound())
return;
@@ -288,7 +285,7 @@ void ApplicationCacheHostForFrame::DidReceiveResponseForMainResource(
is_new_master_entry_ = OLD_ENTRY;
}
-void ApplicationCacheHostForFrame::Trace(blink::Visitor* visitor) {
+void ApplicationCacheHostForFrame::Trace(Visitor* visitor) {
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 a43d4f41399..e3a698f7f8b 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 c297d32bf82..566cf11eab0 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
@@ -15,6 +15,7 @@
#include "third_party/blink/renderer/core/loader/private/frame_client_hints_preferences_context.h"
#include "third_party/blink/renderer/core/loader/subresource_filter.h"
#include "third_party/blink/renderer/platform/exported/wrapped_resource_request.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/loader/cors/cors.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource.h"
@@ -31,13 +32,13 @@ base::Optional<ResourceRequestBlockedReason> BaseFetchContext::CanRequest(
const ResourceRequest& resource_request,
const KURL& url,
const ResourceLoaderOptions& options,
- SecurityViolationReportingPolicy reporting_policy,
+ ReportingDisposition reporting_disposition,
ResourceRequest::RedirectStatus redirect_status) const {
base::Optional<ResourceRequestBlockedReason> blocked_reason =
- CanRequestInternal(type, resource_request, url, options, reporting_policy,
- redirect_status);
+ CanRequestInternal(type, resource_request, url, options,
+ reporting_disposition, redirect_status);
if (blocked_reason &&
- reporting_policy == SecurityViolationReportingPolicy::kReport) {
+ reporting_disposition == ReportingDisposition::kReport) {
DispatchDidBlockRequest(resource_request, options.initiator_info,
blocked_reason.value(), type);
}
@@ -55,6 +56,13 @@ bool BaseFetchContext::CalculateIfAdSubresource(const ResourceRequest& request,
filter->IsAdResource(request.Url(), request.GetRequestContext()));
}
+bool BaseFetchContext::SendConversionRequestInsteadOfRedirecting(
+ const KURL& url,
+ ResourceRequest::RedirectStatus redirect_status,
+ ReportingDisposition reporting_disposition) const {
+ return false;
+}
+
void BaseFetchContext::PrintAccessDeniedMessage(const KURL& url) const {
if (url.IsNull())
return;
@@ -72,9 +80,9 @@ void BaseFetchContext::PrintAccessDeniedMessage(const KURL& url) const {
". Domains, protocols and ports must match.\n";
}
- AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kError, message));
+ AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kSecurity,
+ mojom::ConsoleMessageLevel::kError, message));
}
base::Optional<ResourceRequestBlockedReason>
@@ -82,10 +90,10 @@ BaseFetchContext::CheckCSPForRequest(
mojom::RequestContextType request_context,
const KURL& url,
const ResourceLoaderOptions& options,
- SecurityViolationReportingPolicy reporting_policy,
+ ReportingDisposition reporting_disposition,
ResourceRequest::RedirectStatus redirect_status) const {
return CheckCSPForRequestInternal(
- request_context, url, options, reporting_policy, redirect_status,
+ request_context, url, options, reporting_disposition, redirect_status,
ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly);
}
@@ -94,11 +102,12 @@ BaseFetchContext::CheckCSPForRequestInternal(
mojom::RequestContextType request_context,
const KURL& url,
const ResourceLoaderOptions& options,
- SecurityViolationReportingPolicy reporting_policy,
+ ReportingDisposition reporting_disposition,
ResourceRequest::RedirectStatus redirect_status,
ContentSecurityPolicy::CheckHeaderType check_header_type) const {
- if (ShouldBypassMainWorldCSP() || options.content_security_policy_option ==
- kDoNotCheckContentSecurityPolicy) {
+ if (ShouldBypassMainWorldCSP() ||
+ options.content_security_policy_option ==
+ network::mojom::CSPDisposition::DO_NOT_CHECK) {
return base::nullopt;
}
@@ -106,7 +115,7 @@ BaseFetchContext::CheckCSPForRequestInternal(
if (csp && !csp->AllowRequest(
request_context, url, options.content_security_policy_nonce,
options.integrity_metadata, options.parser_disposition,
- redirect_status, reporting_policy, check_header_type)) {
+ redirect_status, reporting_disposition, check_header_type)) {
return ResourceRequestBlockedReason::kCSP;
}
return base::nullopt;
@@ -118,7 +127,7 @@ BaseFetchContext::CanRequestInternal(
const ResourceRequest& resource_request,
const KURL& url,
const ResourceLoaderOptions& options,
- SecurityViolationReportingPolicy reporting_policy,
+ ReportingDisposition reporting_disposition,
ResourceRequest::RedirectStatus redirect_status) const {
if (GetResourceFetcherProperties().IsDetached()) {
if (!resource_request.GetKeepalive() ||
@@ -137,11 +146,11 @@ BaseFetchContext::CanRequestInternal(
// On navigation cases, Context().GetSecurityOrigin() may return nullptr, so
// the request's origin may be nullptr.
// TODO(yhirano): Figure out if it's actually fine.
- DCHECK(network::IsNavigationRequestMode(request_mode) || origin);
- if (!network::IsNavigationRequestMode(request_mode) &&
+ DCHECK(request_mode == network::mojom::RequestMode::kNavigate || origin);
+ if (request_mode != network::mojom::RequestMode::kNavigate &&
!resource_request.CanDisplay(url)) {
- if (reporting_policy == SecurityViolationReportingPolicy::kReport) {
- AddConsoleMessage(ConsoleMessage::Create(
+ if (reporting_disposition == ReportingDisposition::kReport) {
+ AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kError,
"Not allowed to load local resource: " + url.GetString()));
@@ -175,7 +184,7 @@ BaseFetchContext::CanRequestInternal(
// populateResourceRequest). We check the enforced headers here to ensure we
// block things we ought to block.
if (CheckCSPForRequestInternal(
- request_context, url, options, reporting_policy, redirect_status,
+ request_context, url, options, reporting_disposition, redirect_status,
ContentSecurityPolicy::CheckHeaderType::kCheckEnforce) ==
ResourceRequestBlockedReason::kCSP) {
return ResourceRequestBlockedReason::kCSP;
@@ -218,7 +227,7 @@ BaseFetchContext::CanRequestInternal(
// warning instead.
if (ShouldBlockFetchByMixedContentCheck(request_context,
resource_request.GetRedirectStatus(),
- url, reporting_policy))
+ url, reporting_disposition))
return ResourceRequestBlockedReason::kMixedContent;
if (url.PotentiallyDanglingMarkup() && url.ProtocolIsInHTTPFamily()) {
@@ -233,11 +242,16 @@ BaseFetchContext::CanRequestInternal(
return ResourceRequestBlockedReason::kOther;
}
+ if (SendConversionRequestInsteadOfRedirecting(url, redirect_status,
+ reporting_disposition)) {
+ return ResourceRequestBlockedReason::kOther;
+ }
+
// Let the client have the final say into whether or not the load should
// proceed.
if (GetSubresourceFilter() && type != ResourceType::kImportResource) {
if (!GetSubresourceFilter()->AllowLoad(url, request_context,
- reporting_policy)) {
+ reporting_disposition)) {
return ResourceRequestBlockedReason::kSubresourceFilter;
}
}
@@ -245,7 +259,7 @@ BaseFetchContext::CanRequestInternal(
return base::nullopt;
}
-void BaseFetchContext::Trace(blink::Visitor* visitor) {
+void BaseFetchContext::Trace(Visitor* visitor) {
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 317279170ce..7f6c4db5584 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
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_BASE_FETCH_CONTEXT_H_
#include "base/optional.h"
+#include "net/cookies/site_for_cookies.h"
#include "services/network/public/mojom/referrer_policy.mojom-blink-forward.h"
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/renderer/core/core_export.h"
@@ -35,16 +36,16 @@ class CORE_EXPORT BaseFetchContext : public FetchContext {
const ResourceRequest&,
const KURL&,
const ResourceLoaderOptions&,
- SecurityViolationReportingPolicy,
+ ReportingDisposition,
ResourceRequest::RedirectStatus) const override;
base::Optional<ResourceRequestBlockedReason> CheckCSPForRequest(
mojom::RequestContextType,
const KURL&,
const ResourceLoaderOptions&,
- SecurityViolationReportingPolicy,
+ ReportingDisposition,
ResourceRequest::RedirectStatus) const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
const DetachableResourceFetcherProperties& GetResourceFetcherProperties()
const {
@@ -53,7 +54,7 @@ class CORE_EXPORT BaseFetchContext : public FetchContext {
virtual void CountUsage(mojom::WebFeature) const = 0;
virtual void CountDeprecation(mojom::WebFeature) const = 0;
- virtual KURL GetSiteForCookies() const = 0;
+ virtual net::SiteForCookies GetSiteForCookies() const = 0;
// Returns the origin of the top frame in the document.
virtual scoped_refptr<const SecurityOrigin> GetTopFrameOrigin() const = 0;
@@ -68,6 +69,14 @@ class CORE_EXPORT BaseFetchContext : public FetchContext {
bool CalculateIfAdSubresource(const ResourceRequest& resource_request,
ResourceType type) override;
+ // Returns whether a request to |url| is a conversion registration request.
+ // Conversion registration requests are redirects to a well-known conversion
+ // registration endpoint.
+ virtual bool SendConversionRequestInsteadOfRedirecting(
+ const KURL& url,
+ ResourceRequest::RedirectStatus redirect_status,
+ ReportingDisposition reporting_disposition) const;
+
virtual const ContentSecurityPolicy* GetContentSecurityPolicy() const = 0;
protected:
@@ -92,7 +101,7 @@ class CORE_EXPORT BaseFetchContext : public FetchContext {
mojom::RequestContextType,
ResourceRequest::RedirectStatus,
const KURL&,
- SecurityViolationReportingPolicy) const = 0;
+ ReportingDisposition) const = 0;
virtual bool ShouldBlockFetchAsCredentialedSubresource(const ResourceRequest&,
const KURL&) const = 0;
virtual const KURL& Url() const = 0;
@@ -113,14 +122,14 @@ class CORE_EXPORT BaseFetchContext : public FetchContext {
const ResourceRequest&,
const KURL&,
const ResourceLoaderOptions&,
- SecurityViolationReportingPolicy,
+ ReportingDisposition,
ResourceRequest::RedirectStatus) const;
base::Optional<ResourceRequestBlockedReason> CheckCSPForRequestInternal(
mojom::RequestContextType,
const KURL&,
const ResourceLoaderOptions&,
- SecurityViolationReportingPolicy,
+ ReportingDisposition,
ResourceRequest::RedirectStatus,
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 d9b69e509d8..0a9908bb7f9 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
@@ -53,7 +53,9 @@ class MockBaseFetchContext final : public BaseFetchContext {
~MockBaseFetchContext() override = default;
// BaseFetchContext overrides:
- KURL GetSiteForCookies() const override { return KURL(); }
+ net::SiteForCookies GetSiteForCookies() const override {
+ return net::SiteForCookies();
+ }
scoped_refptr<const blink::SecurityOrigin> GetTopFrameOrigin()
const override {
return SecurityOrigin::CreateUniqueOpaque();
@@ -86,7 +88,7 @@ class MockBaseFetchContext final : public BaseFetchContext {
mojom::RequestContextType,
ResourceRequest::RedirectStatus,
const KURL&,
- SecurityViolationReportingPolicy) const override {
+ ReportingDisposition) const override {
return false;
}
bool ShouldBlockFetchAsCredentialedSubresource(const ResourceRequest&,
@@ -103,7 +105,7 @@ class MockBaseFetchContext final : public BaseFetchContext {
}
void AddConsoleMessage(ConsoleMessage*) const override {}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(execution_context_);
visitor->Trace(fetch_client_settings_object_);
BaseFetchContext::Trace(visitor);
@@ -119,7 +121,7 @@ class BaseFetchContextTest : public testing::Test {
void SetUp() override {
execution_context_ = MakeGarbageCollected<NullExecutionContext>();
static_cast<NullExecutionContext*>(execution_context_.Get())
- ->SetUpSecurityContext();
+ ->SetUpSecurityContextForTesting();
resource_fetcher_properties_ =
MakeGarbageCollected<TestResourceFetcherProperties>(
*MakeGarbageCollected<FetchClientSettingsObjectImpl>(
@@ -151,11 +153,11 @@ TEST_F(BaseFetchContextTest, CanRequest) {
ContentSecurityPolicy* policy =
execution_context_->GetContentSecurityPolicy();
policy->DidReceiveHeader("script-src https://foo.test",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ network::mojom::ContentSecurityPolicyType::kEnforce,
+ network::mojom::ContentSecurityPolicySource::kHTTP);
policy->DidReceiveHeader("script-src https://bar.test",
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceHTTP);
+ network::mojom::ContentSecurityPolicyType::kReport,
+ network::mojom::ContentSecurityPolicySource::kHTTP);
KURL url(NullURL(), "http://baz.test");
ResourceRequest resource_request(url);
@@ -167,7 +169,7 @@ TEST_F(BaseFetchContextTest, CanRequest) {
EXPECT_EQ(ResourceRequestBlockedReason::kCSP,
fetch_context_->CanRequest(
ResourceType::kScript, resource_request, url, options,
- SecurityViolationReportingPolicy::kReport,
+ ReportingDisposition::kReport,
ResourceRequest::RedirectStatus::kFollowedRedirect));
EXPECT_EQ(1u, policy->violation_reports_sent_.size());
}
@@ -177,11 +179,11 @@ TEST_F(BaseFetchContextTest, CheckCSPForRequest) {
ContentSecurityPolicy* policy =
execution_context_->GetContentSecurityPolicy();
policy->DidReceiveHeader("script-src https://foo.test",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ network::mojom::ContentSecurityPolicyType::kEnforce,
+ network::mojom::ContentSecurityPolicySource::kHTTP);
policy->DidReceiveHeader("script-src https://bar.test",
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceHTTP);
+ network::mojom::ContentSecurityPolicyType::kReport,
+ network::mojom::ContentSecurityPolicySource::kHTTP);
KURL url(NullURL(), "http://baz.test");
@@ -190,7 +192,7 @@ TEST_F(BaseFetchContextTest, CheckCSPForRequest) {
EXPECT_EQ(base::nullopt,
fetch_context_->CheckCSPForRequest(
mojom::RequestContextType::SCRIPT, url, options,
- SecurityViolationReportingPolicy::kReport,
+ ReportingDisposition::kReport,
ResourceRequest::RedirectStatus::kFollowedRedirect));
EXPECT_EQ(1u, policy->violation_reports_sent_.size());
}
@@ -206,27 +208,26 @@ TEST_F(BaseFetchContextTest, CanRequestWhenDetached) {
EXPECT_EQ(base::nullopt,
fetch_context_->CanRequest(
ResourceType::kRaw, request, url, ResourceLoaderOptions(),
- SecurityViolationReportingPolicy::kSuppressReporting,
+ ReportingDisposition::kSuppressReporting,
ResourceRequest::RedirectStatus::kNoRedirect));
- EXPECT_EQ(
- base::nullopt,
- fetch_context_->CanRequest(
- ResourceType::kRaw, keepalive_request, url, ResourceLoaderOptions(),
- SecurityViolationReportingPolicy::kSuppressReporting,
- ResourceRequest::RedirectStatus::kNoRedirect));
+ EXPECT_EQ(base::nullopt, fetch_context_->CanRequest(
+ ResourceType::kRaw, keepalive_request, url,
+ ResourceLoaderOptions(),
+ ReportingDisposition::kSuppressReporting,
+ ResourceRequest::RedirectStatus::kNoRedirect));
EXPECT_EQ(base::nullopt,
fetch_context_->CanRequest(
ResourceType::kRaw, request, url, ResourceLoaderOptions(),
- SecurityViolationReportingPolicy::kSuppressReporting,
+ ReportingDisposition::kSuppressReporting,
ResourceRequest::RedirectStatus::kFollowedRedirect));
EXPECT_EQ(
base::nullopt,
fetch_context_->CanRequest(
ResourceType::kRaw, keepalive_request, url, ResourceLoaderOptions(),
- SecurityViolationReportingPolicy::kSuppressReporting,
+ ReportingDisposition::kSuppressReporting,
ResourceRequest::RedirectStatus::kFollowedRedirect));
resource_fetcher_->ClearContext();
@@ -234,27 +235,27 @@ TEST_F(BaseFetchContextTest, CanRequestWhenDetached) {
EXPECT_EQ(ResourceRequestBlockedReason::kOther,
fetch_context_->CanRequest(
ResourceType::kRaw, request, url, ResourceLoaderOptions(),
- SecurityViolationReportingPolicy::kSuppressReporting,
+ ReportingDisposition::kSuppressReporting,
ResourceRequest::RedirectStatus::kNoRedirect));
EXPECT_EQ(
ResourceRequestBlockedReason::kOther,
- fetch_context_->CanRequest(
- ResourceType::kRaw, keepalive_request, url, ResourceLoaderOptions(),
- SecurityViolationReportingPolicy::kSuppressReporting,
- ResourceRequest::RedirectStatus::kNoRedirect));
+ fetch_context_->CanRequest(ResourceType::kRaw, keepalive_request, url,
+ ResourceLoaderOptions(),
+ ReportingDisposition::kSuppressReporting,
+ ResourceRequest::RedirectStatus::kNoRedirect));
EXPECT_EQ(ResourceRequestBlockedReason::kOther,
fetch_context_->CanRequest(
ResourceType::kRaw, request, url, ResourceLoaderOptions(),
- SecurityViolationReportingPolicy::kSuppressReporting,
+ ReportingDisposition::kSuppressReporting,
ResourceRequest::RedirectStatus::kFollowedRedirect));
EXPECT_EQ(
base::nullopt,
fetch_context_->CanRequest(
ResourceType::kRaw, keepalive_request, url, ResourceLoaderOptions(),
- SecurityViolationReportingPolicy::kSuppressReporting,
+ ReportingDisposition::kSuppressReporting,
ResourceRequest::RedirectStatus::kFollowedRedirect));
}
@@ -271,19 +272,19 @@ TEST_F(BaseFetchContextTest, UACSSTest) {
EXPECT_EQ(ResourceRequestBlockedReason::kOther,
fetch_context_->CanRequest(
ResourceType::kScript, resource_request, test_url, options,
- SecurityViolationReportingPolicy::kReport,
+ ReportingDisposition::kReport,
ResourceRequest::RedirectStatus::kFollowedRedirect));
EXPECT_EQ(ResourceRequestBlockedReason::kOther,
fetch_context_->CanRequest(
ResourceType::kImage, resource_request, test_url, options,
- SecurityViolationReportingPolicy::kReport,
+ ReportingDisposition::kReport,
ResourceRequest::RedirectStatus::kFollowedRedirect));
EXPECT_EQ(base::nullopt,
fetch_context_->CanRequest(
ResourceType::kImage, resource_request, data_url, options,
- SecurityViolationReportingPolicy::kReport,
+ ReportingDisposition::kReport,
ResourceRequest::RedirectStatus::kFollowedRedirect));
}
@@ -292,8 +293,8 @@ TEST_F(BaseFetchContextTest, UACSSTest_BypassCSP) {
ContentSecurityPolicy* policy =
execution_context_->GetContentSecurityPolicy();
policy->DidReceiveHeader("default-src 'self'",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ network::mojom::ContentSecurityPolicyType::kEnforce,
+ network::mojom::ContentSecurityPolicySource::kHTTP);
KURL data_url("data:image/png;base64,test");
@@ -305,7 +306,7 @@ TEST_F(BaseFetchContextTest, UACSSTest_BypassCSP) {
EXPECT_EQ(base::nullopt,
fetch_context_->CanRequest(
ResourceType::kImage, resource_request, data_url, options,
- SecurityViolationReportingPolicy::kReport,
+ ReportingDisposition::kReport,
ResourceRequest::RedirectStatus::kFollowedRedirect));
}
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 313fcf6e5f5..ca6b5e62eb1 100644
--- a/chromium/third_party/blink/renderer/core/loader/cookie_jar.cc
+++ b/chromium/third_party/blink/renderer/core/loader/cookie_jar.cc
@@ -6,22 +6,26 @@
#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/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
namespace blink {
-CookieJar::CookieJar(blink::Document* document) : document_(document) {}
+CookieJar::CookieJar(blink::Document* document)
+ : backend_(document->ToExecutionContext()), document_(document) {}
CookieJar::~CookieJar() = default;
+void CookieJar::Trace(Visitor* visitor) {
+ visitor->Trace(backend_);
+ visitor->Trace(document_);
+}
+
void CookieJar::SetCookie(const String& value) {
KURL cookie_url = document_->CookieURL();
if (cookie_url.IsEmpty())
return;
RequestRestrictedCookieManagerIfNeeded();
- SCOPED_BLINK_UMA_HISTOGRAM_TIMER("Blink.CookieJar.SyncCookiesSetTime");
backend_->SetCookieFromString(cookie_url, document_->SiteForCookies(),
document_->TopFrameOrigin(), value);
}
@@ -31,7 +35,6 @@ String CookieJar::Cookies() {
if (cookie_url.IsEmpty())
return String();
- SCOPED_BLINK_UMA_HISTOGRAM_TIMER("Blink.CookieJar.SyncCookiesTime");
RequestRestrictedCookieManagerIfNeeded();
String value;
backend_->GetCookiesString(cookie_url, document_->SiteForCookies(),
@@ -55,7 +58,8 @@ void CookieJar::RequestRestrictedCookieManagerIfNeeded() {
if (!backend_.is_bound() || !backend_.is_connected()) {
backend_.reset();
document_->GetBrowserInterfaceBroker().GetInterface(
- backend_.BindNewPipeAndPassReceiver());
+ 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 f1602d134f4..44bb2eb945f 100644
--- a/chromium/third_party/blink/renderer/core/loader/cookie_jar.h
+++ b/chromium/third_party/blink/renderer/core/loader/cookie_jar.h
@@ -7,17 +7,18 @@
#include "services/network/public/mojom/restricted_cookie_manager.mojom-blink.h"
-#include "mojo/public/cpp/bindings/remote.h"
-#include "third_party/blink/renderer/platform/heap/persistent.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/wtf/text/wtf_string.h"
namespace blink {
class Document;
-class CookieJar {
+class CookieJar : public GarbageCollected<CookieJar> {
public:
explicit CookieJar(blink::Document* document);
- ~CookieJar();
+ virtual ~CookieJar();
+ void Trace(Visitor* visitor);
void SetCookie(const String& value);
String Cookies();
@@ -26,8 +27,8 @@ class CookieJar {
private:
void RequestRestrictedCookieManagerIfNeeded();
- mojo::Remote<network::mojom::blink::RestrictedCookieManager> backend_;
- WeakPersistent<blink::Document> document_; // Document owns |this|.
+ HeapMojoRemote<network::mojom::blink::RestrictedCookieManager> backend_;
+ Member<blink::Document> document_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/loader/cross_thread_resource_timing_info_copier.cc b/chromium/third_party/blink/renderer/core/loader/cross_thread_resource_timing_info_copier.cc
new file mode 100644
index 00000000000..e9da877b17c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/loader/cross_thread_resource_timing_info_copier.cc
@@ -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.
+
+#include "third_party/blink/renderer/core/loader/cross_thread_resource_timing_info_copier.h"
+
+#include "third_party/blink/public/mojom/timing/resource_timing.mojom-blink.h"
+
+namespace WTF {
+
+namespace {
+
+Vector<blink::mojom::blink::ServerTimingInfoPtr> CloneServerTimingInfoArray(
+ const Vector<blink::mojom::blink::ServerTimingInfoPtr>& server_timing) {
+ Vector<blink::mojom::blink::ServerTimingInfoPtr> result;
+ for (const auto& entry : server_timing) {
+ result.emplace_back(
+ CrossThreadCopier<blink::mojom::blink::ServerTimingInfoPtr>::Copy(
+ entry));
+ }
+ return result;
+}
+
+} // namespace
+
+CrossThreadCopier<blink::mojom::blink::ResourceTimingInfoPtr>::Type
+CrossThreadCopier<blink::mojom::blink::ResourceTimingInfoPtr>::Copy(
+ const blink::mojom::blink::ResourceTimingInfoPtr& info) {
+ return blink::mojom::blink::ResourceTimingInfo::New(
+ info->name.IsolatedCopy(), info->start_time,
+ info->alpn_negotiated_protocol.IsolatedCopy(),
+ info->connection_info.IsolatedCopy(),
+ info->timing ? info->timing->Clone() : nullptr,
+ info->last_redirect_end_time, info->response_end, info->context_type,
+ info->request_destination, info->transfer_size, info->encoded_body_size,
+ info->decoded_body_size, info->did_reuse_connection,
+ info->is_secure_context, info->allow_timing_details,
+ info->allow_redirect_details, info->allow_negative_values,
+ CloneServerTimingInfoArray(info->server_timing));
+}
+
+CrossThreadCopier<blink::mojom::blink::ServerTimingInfoPtr>::Type
+CrossThreadCopier<blink::mojom::blink::ServerTimingInfoPtr>::Copy(
+ const blink::mojom::blink::ServerTimingInfoPtr& info) {
+ return blink::mojom::blink::ServerTimingInfo::New(
+ info->name.IsolatedCopy(), info->duration,
+ info->description.IsolatedCopy());
+}
+
+} // namespace WTF
diff --git a/chromium/third_party/blink/renderer/core/loader/cross_thread_resource_timing_info_copier.h b/chromium/third_party/blink/renderer/core/loader/cross_thread_resource_timing_info_copier.h
new file mode 100644
index 00000000000..34816336581
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/loader/cross_thread_resource_timing_info_copier.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_CROSS_THREAD_RESOURCE_TIMING_INFO_COPIER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_CROSS_THREAD_RESOURCE_TIMING_INFO_COPIER_H_
+
+#include "third_party/blink/public/mojom/timing/resource_timing.mojom-blink-forward.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h"
+
+namespace WTF {
+
+template <>
+struct CrossThreadCopier<blink::mojom::blink::ServerTimingInfoPtr> {
+ STATIC_ONLY(CrossThreadCopier);
+ using Type = blink::mojom::blink::ServerTimingInfoPtr;
+ static Type Copy(const Type&);
+};
+
+template <>
+struct CrossThreadCopier<blink::mojom::blink::ResourceTimingInfoPtr> {
+ STATIC_ONLY(CrossThreadCopier);
+ using Type = blink::mojom::blink::ResourceTimingInfoPtr;
+ static Type Copy(const Type&);
+};
+
+} // namespace WTF
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_CROSS_THREAD_RESOURCE_TIMING_INFO_COPIER_H_
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 2a5fee87e9b..4c623157ffb 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(blink::Visitor* visitor) {
+void DocumentLoadTiming::Trace(Visitor* visitor) {
visitor->Trace(document_loader_);
}
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 cde9d2eba67..e1e59d2b432 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
@@ -99,7 +99,7 @@ class CORE_EXPORT DocumentLoadTiming final {
return reference_monotonic_time_;
}
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
void SetTickClockForTesting(const base::TickClock* tick_clock);
void SetClockForTesting(const base::Clock* clock);
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 4666a097d26..94d7026e591 100644
--- a/chromium/third_party/blink/renderer/core/loader/document_loader.cc
+++ b/chromium/third_party/blink/renderer/core/loader/document_loader.cc
@@ -31,6 +31,7 @@
#include <memory>
#include <utility>
+
#include "base/auto_reset.h"
#include "base/metrics/histogram_macros.h"
#include "base/time/default_tick_clock.h"
@@ -45,6 +46,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/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"
#include "third_party/blink/renderer/core/frame/frame_console.h"
@@ -53,6 +55,7 @@
#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/settings.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/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
@@ -80,6 +83,7 @@
#include "third_party/blink/renderer/platform/bindings/microtask.h"
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/loader/cors/cors.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h"
@@ -93,7 +97,6 @@
#include "third_party/blink/renderer/platform/loader/static_data_navigation_body_loader.h"
#include "third_party/blink/renderer/platform/mhtml/archive_resource.h"
#include "third_party/blink/renderer/platform/mhtml/mhtml_archive.h"
-#include "third_party/blink/renderer/platform/network/content_security_policy_response_headers.h"
#include "third_party/blink/renderer/platform/network/encoded_form_data.h"
#include "third_party/blink/renderer/platform/network/http_names.h"
#include "third_party/blink/renderer/platform/network/http_parsers.h"
@@ -106,12 +109,14 @@
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
DocumentLoader::DocumentLoader(
LocalFrame* frame,
WebNavigationType navigation_type,
+ ContentSecurityPolicy* content_security_policy,
std::unique_ptr<WebNavigationParams> navigation_params)
: params_(std::move(navigation_params)),
frame_(frame),
@@ -123,6 +128,7 @@ DocumentLoader::DocumentLoader(
document_load_timing_(*this),
service_worker_network_provider_(
std::move(params_->service_worker_network_provider)),
+ was_blocked_by_document_policy_(false),
was_blocked_by_csp_(false),
state_(kNotStarted),
in_commit_data_(false),
@@ -172,7 +178,25 @@ DocumentLoader::DocumentLoader(
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;
+ response_ = params_->response.ToResourceResponse();
+ frame_policy_ = params_->frame_policy.value_or(FramePolicy());
+
+ document_policy_ = CreateDocumentPolicy();
+
+ // If the document is blocked by document policy, there won't be content
+ // in the sub-frametree, thus no need to initialize required_policy for
+ // subtree.
+ if (!was_blocked_by_document_policy_) {
+ // Require-Document-Policy header only affects subtree of current document,
+ // but not the current document.
+ const DocumentPolicy::FeatureState header_required_policy =
+ DocumentPolicyParser::Parse(
+ response_.HttpHeaderField(http_names::kRequireDocumentPolicy))
+ .value_or(DocumentPolicy::ParsedDocumentPolicy{})
+ .feature_state;
+ frame_->SetRequiredDocumentPolicy(DocumentPolicy::MergeFeatureState(
+ frame_policy_.required_document_policy, header_required_policy));
+ }
WebNavigationTimings& timings = params_->navigation_timings;
if (!timings.input_start.is_null())
@@ -211,22 +235,14 @@ DocumentLoader::DocumentLoader(
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_);
- loading_srcdoc_ = url_.IsAboutSrcdocURL();
- if (loading_srcdoc_) {
- // about:srcdoc always inherits CSP from its parent.
- ContentSecurityPolicy* parent_csp = frame_->Tree()
- .Parent()
- ->GetSecurityContext()
- ->GetContentSecurityPolicy();
- content_security_policy_ = MakeGarbageCollected<ContentSecurityPolicy>();
- content_security_policy_->CopyStateFrom(parent_csp);
- content_security_policy_->CopyPluginTypesFrom(parent_csp);
- } else if (!loading_url_as_empty_document_) {
- content_security_policy_ =
- CreateCSP(params_->response.ToResourceResponse(), origin_policy_);
+ if (!loading_url_as_empty_document_) {
+ content_security_policy_ = content_security_policy;
+
+ // The CSP are null when the CSP check done in the FrameLoader failed.
if (!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
@@ -238,25 +254,20 @@ DocumentLoader::DocumentLoader(
// information that is consistent with the final request URL.
// Note: We can't use |url_| for the origin calculation because
// we need to take into account any redirects that may have occurred.
- const auto request_url_origin = blink::SecurityOrigin::Create(
- params_->response.ToResourceResponse().CurrentRequestUrl());
+ const auto request_url_origin =
+ blink::SecurityOrigin::Create(response_.CurrentRequestUrl());
origin_to_commit_ = request_url_origin->DeriveNewOpaqueOrigin();
was_blocked_by_csp_ = true;
- KURL blocked_url = SecurityOrigin::UrlWithUniqueOpaqueOrigin();
- original_url_ = blocked_url;
- url_ = blocked_url;
- params_->url = blocked_url;
- WebNavigationParams::FillStaticResponse(params_.get(), "text/html",
- "UTF-8", "");
}
}
+ if (was_blocked_by_csp_ || was_blocked_by_document_policy_)
+ ReplaceWithEmptyDocument();
+
if (!GetFrameLoader().StateMachine()->CreatingInitialEmptyDocument())
redirect_chain_.push_back(url_);
- response_ = params_->response.ToResourceResponse();
-
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
@@ -277,7 +288,12 @@ DocumentLoader::DocumentLoader(
}
web_bundle_physical_url_ = params_->web_bundle_physical_url;
- base_url_override_for_web_bundle_ = params_->base_url_override_for_web_bundle;
+ 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);
}
FrameLoader& DocumentLoader::GetFrameLoader() const {
@@ -302,7 +318,7 @@ DocumentLoader::~DocumentLoader() {
DCHECK_EQ(state_, kSentDidFinishLoad);
}
-void DocumentLoader::Trace(blink::Visitor* visitor) {
+void DocumentLoader::Trace(Visitor* visitor) {
visitor->Trace(archive_);
visitor->Trace(frame_);
visitor->Trace(history_item_);
@@ -356,7 +372,7 @@ void DocumentLoader::SetServiceWorkerNetworkProvider(
}
void DocumentLoader::DispatchLinkHeaderPreloads(
- const base::Optional<ViewportDescription>& viewport,
+ const ViewportDescription* viewport,
PreloadHelper::MediaPreloadPolicy media_policy) {
DCHECK_GE(state_, kCommitted);
PreloadHelper::LoadLinksFromHeader(
@@ -364,7 +380,7 @@ void DocumentLoader::DispatchLinkHeaderPreloads(
GetResponse().CurrentRequestUrl(), *frame_, frame_->GetDocument(),
PreloadHelper::kOnlyLoadResources, media_policy, viewport,
nullptr /* alternate_resource_info */,
- base::nullopt /* recursive_prefetch_token */);
+ nullptr /* recursive_prefetch_token */);
}
void DocumentLoader::DidChangePerformanceTiming() {
@@ -373,6 +389,11 @@ void DocumentLoader::DidChangePerformanceTiming() {
}
}
+void DocumentLoader::DidObserveInputDelay(base::TimeDelta input_delay) {
+ if (frame_ && state_ >= kCommitted) {
+ GetLocalFrameClient().DidObserveInputDelay(input_delay);
+ }
+}
void DocumentLoader::DidObserveLoadingBehavior(LoadingBehaviorFlag behavior) {
if (frame_) {
DCHECK_GE(state_, kCommitted);
@@ -467,6 +488,7 @@ void DocumentLoader::UpdateForSameDocumentNavigation(
if (is_client_redirect_)
redirect_chain_.push_back(old_url);
redirect_chain_.push_back(new_url);
+ last_same_document_navigation_was_browser_initiated_ = !initiating_document;
SetHistoryItemStateForCommit(
history_item_.Get(), type,
@@ -486,8 +508,10 @@ void DocumentLoader::UpdateForSameDocumentNavigation(
GetLocalFrameClient().DidFinishSameDocumentNavigation(
history_item_.Get(), commit_type, initiating_document);
probe::DidNavigateWithinDocument(frame_);
- if (!was_loading)
+ if (!was_loading) {
GetLocalFrameClient().DidStopLoading();
+ frame_->UpdateFaviconURL();
+ }
}
const KURL& DocumentLoader::UrlForHistory() const {
@@ -522,7 +546,7 @@ void DocumentLoader::SetHistoryItemStateForCommit(
history_item_->SetURL(UrlForHistory());
history_item_->SetReferrer(SecurityPolicy::GenerateReferrer(
referrer_.referrer_policy, history_item_->Url(), referrer_.referrer));
- if (DeprecatedEqualIgnoringCase(http_method_, "POST")) {
+ if (EqualIgnoringASCIICase(http_method_, "POST")) {
// FIXME: Eventually we have to make this smart enough to handle the case
// where we have a stream for the body to handle the "data interspersed with
// files" feature.
@@ -666,6 +690,8 @@ void DocumentLoader::BodyLoadingFinished(
}
void DocumentLoader::LoadFailed(const ResourceError& error) {
+ TRACE_EVENT1("navigation,rail", "DocumentLoader::LoadFailed", "error",
+ error.ErrorCode());
body_loader_.reset();
virtual_time_pauser_.UnpauseVirtualTime();
@@ -733,7 +759,7 @@ void DocumentLoader::FinishedLoading(base::TimeTicks finish_time) {
void DocumentLoader::FinalizeMHTMLArchiveLoad() {
if (!frame_->IsMainFrame()) {
// Only the top-frame can load MHTML.
- frame_->Console().AddMessage(ConsoleMessage::Create(
+ frame_->Console().AddMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kError,
"Attempted to load a multipart archive into an subframe: " +
@@ -744,7 +770,7 @@ void DocumentLoader::FinalizeMHTMLArchiveLoad() {
if (archive_load_result_ != mojom::MHTMLLoadResult::kSuccess) {
archive_.Clear();
// Log if attempting to load an invalid archive resource.
- frame_->Console().AddMessage(ConsoleMessage::Create(
+ frame_->Console().AddMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kError,
"Malformed multipart archive: " + url_.GetString()));
@@ -760,10 +786,10 @@ void DocumentLoader::HandleRedirect(const KURL& current_request_url) {
// (eg: file:///tmp/a.wbn), Chrome internally redirects the navigation to the
// page (eg: https://example.com/page.html) inside the Web Bundle file
// to the file's URL (file:///tmp/a.wbn?https://example.com/page.html). In
- // this case, CanDisplay() returns false, and
- // base_url_override_for_web_bundle must not be null.
+ // this case, CanDisplay() returns false, and web_bundle_claimed_url must not
+ // be null.
CHECK(SecurityOrigin::Create(current_request_url)->CanDisplay(url_) ||
- !params_->base_url_override_for_web_bundle.IsNull());
+ !params_->web_bundle_claimed_url.IsNull());
DCHECK(!GetTiming().FetchStart().is_null());
redirect_chain_.push_back(url_);
@@ -790,69 +816,49 @@ bool DocumentLoader::ShouldReportTimingInfoToParent() {
return true;
}
-ContentSecurityPolicy* DocumentLoader::CreateCSP(
- const ResourceResponse& response,
- const base::Optional<WebOriginPolicy>& origin_policy) {
- auto* csp = MakeGarbageCollected<ContentSecurityPolicy>();
- csp->SetOverrideURLForSelf(response.CurrentRequestUrl());
+void DocumentLoader::ConsoleError(const String& message) {
+ auto* console_message = MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kSecurity,
+ mojom::ConsoleMessageLevel::kError, message,
+ response_.CurrentRequestUrl(), this, MainResourceIdentifier());
+ frame_->GetDocument()->AddConsoleMessage(console_message);
+}
- if (!frame_->GetSettings()->BypassCSP()) {
- csp->DidReceiveHeaders(ContentSecurityPolicyResponseHeaders(response));
+void DocumentLoader::ReplaceWithEmptyDocument() {
+ DCHECK(params_);
+ KURL blocked_url = SecurityOrigin::UrlWithUniqueOpaqueOrigin();
+ original_url_ = blocked_url;
+ url_ = blocked_url;
+ params_->url = blocked_url;
+ WebNavigationParams::FillStaticResponse(params_.get(), "text/html", "UTF-8",
+ "");
+}
- // Handle OriginPolicy. We can skip the entire block if the OP policies have
- // already been passed down.
- if (origin_policy.has_value() &&
- !csp->HasPolicyFromSource(
- kContentSecurityPolicyHeaderSourceOriginPolicy)) {
- for (const auto& policy : origin_policy->content_security_policies) {
- csp->DidReceiveHeader(policy, kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceOriginPolicy);
- }
+DocumentPolicy::ParsedDocumentPolicy DocumentLoader::CreateDocumentPolicy() {
+ // For URLs referring to local content to parent frame, they have no way to
+ // specify the document policy they use. If the parent frame requires a
+ // document policy on them, use the required policy as effective policy.
+ if (url_.IsEmpty() || url_.ProtocolIsAbout() || url_.ProtocolIsData() ||
+ url_.ProtocolIs("blob") || url_.ProtocolIs("filesystem"))
+ return {frame_policy_.required_document_policy, {} /* endpoint_map */};
- for (const auto& policy :
- origin_policy->content_security_policies_report_only) {
- csp->DidReceiveHeader(policy, kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceOriginPolicy);
- }
- }
- }
- if (!base::FeatureList::IsEnabled(
- network::features::kOutOfBlinkFrameAncestors)) {
- if (!csp->AllowAncestors(frame_, response.CurrentRequestUrl()))
- return nullptr;
- }
-
- if (!frame_->GetSettings()->BypassCSP() &&
- !GetFrameLoader().RequiredCSP().IsEmpty()) {
- const SecurityOrigin* parent_security_origin =
- frame_->Tree().Parent()->GetSecurityContext()->GetSecurityOrigin();
- if (ContentSecurityPolicy::ShouldEnforceEmbeddersPolicy(
- response, parent_security_origin)) {
- csp->AddPolicyFromHeaderValue(GetFrameLoader().RequiredCSP(),
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
- } else {
- auto* required_csp = MakeGarbageCollected<ContentSecurityPolicy>();
- required_csp->AddPolicyFromHeaderValue(
- GetFrameLoader().RequiredCSP(),
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
- if (!required_csp->Subsumes(*csp)) {
- String message = "Refused to display '" +
- response.CurrentRequestUrl().ElidedString() +
- "' because it has not opted-into the following policy "
- "required by its embedder: '" +
- GetFrameLoader().RequiredCSP() + "'.";
- ConsoleMessage* console_message = ConsoleMessage::CreateForRequest(
- mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kError, message,
- response.CurrentRequestUrl(), this, MainResourceIdentifier());
- frame_->GetDocument()->AddConsoleMessage(console_message);
- return nullptr;
- }
- }
+ // Assume Document policy feature is enabled so we can check the
+ // Required- headers. Will re-validate when we install the new Document.
+ const auto parsed_policy =
+ DocumentPolicyParser::Parse(
+ response_.HttpHeaderField(http_names::kDocumentPolicy))
+ .value_or(DocumentPolicy::ParsedDocumentPolicy{});
+
+ if (!DocumentPolicy::IsPolicyCompatible(
+ frame_policy_.required_document_policy,
+ parsed_policy.feature_state)) {
+ was_blocked_by_document_policy_ = true;
+ // When header policy is less strict than required policy, use required
+ // policy to initialize document policy for the document.
+ return {frame_policy_.required_document_policy, {} /* endpoint_map */};
}
- return csp;
+
+ return parsed_policy;
}
void DocumentLoader::HandleResponse() {
@@ -884,10 +890,6 @@ void DocumentLoader::HandleResponse() {
void DocumentLoader::CommitNavigation() {
CHECK_GE(state_, kCommitted);
- KURL overriding_url = base_url_override_for_web_bundle_;
- if (loading_mhtml_archive_ && archive_)
- overriding_url = archive_->MainResource()->Url();
-
// Prepare a DocumentInit before clearing the frame, because it may need to
// inherit an aliased security context.
Document* owner_document = nullptr;
@@ -908,8 +910,7 @@ void DocumentLoader::CommitNavigation() {
}
DCHECK(frame_->GetPage());
- InstallNewDocument(Url(), initiator_origin, owner_document, MimeType(),
- overriding_url);
+ InstallNewDocument(Url(), initiator_origin, owner_document, MimeType());
}
void DocumentLoader::CommitData(const char* bytes, size_t length) {
@@ -998,11 +999,10 @@ void DocumentLoader::CommitSameDocumentNavigationInternal(
frame_load_type = WebFrameLoadType::kReplaceCurrentItem;
}
- // If we have a provisional request for a different document, a fragment
+ // If we have a client navigation for a different document, a fragment
// scroll should cancel it.
// Note: see fragment-change-does-not-cancel-pending-navigation, where
// this does not actually happen.
- GetFrameLoader().DetachProvisionalDocumentLoader();
GetFrameLoader().DidFinishNavigation(
FrameLoader::NavigationFinishState::kSuccess);
@@ -1180,7 +1180,8 @@ void DocumentLoader::StartLoadingInternal() {
navigation_timing_info_ = ResourceTimingInfo::Create(
fetch_initiator_type_names::kDocument, GetTiming().NavigationStart(),
- mojom::RequestContextType::IFRAME);
+ mojom::RequestContextType::IFRAME,
+ network::mojom::RequestDestination::kIframe);
navigation_timing_info_->SetInitialURL(url_);
report_timing_info_to_parent_ = ShouldReportTimingInfoToParent();
@@ -1244,9 +1245,8 @@ void DocumentLoader::StartLoadingInternal() {
response_.HttpHeaderField(http_names::kLink),
response_.CurrentRequestUrl(), *GetFrame(), nullptr,
PreloadHelper::kDoNotLoadResources, PreloadHelper::kLoadAll,
- base::nullopt /* viewport_description */,
- nullptr /* alternate_resource_info */,
- base::nullopt /* recursive_prefetch_token */);
+ nullptr /* viewport_description */, nullptr /* alternate_resource_info */,
+ nullptr /* recursive_prefetch_token */);
if (!frame_->IsMainFrame() && response_.HasMajorCertificateErrors()) {
MixedContentChecker::HandleCertificateError(
GetFrame(), response_, mojom::RequestContextType::HYPERLINK);
@@ -1256,14 +1256,12 @@ void DocumentLoader::StartLoadingInternal() {
probe::DidReceiveResourceResponse(probe::ToCoreProbeSink(GetFrame()),
main_resource_identifier_, this, response_,
nullptr /* resource */);
- frame_->Console().ReportResourceResponseReceived(
- this, main_resource_identifier_, response_);
HandleResponse();
loading_mhtml_archive_ =
- DeprecatedEqualIgnoringCase("multipart/related", response_.MimeType()) ||
- DeprecatedEqualIgnoringCase("message/rfc822", response_.MimeType());
+ EqualIgnoringASCIICase("multipart/related", response_.MimeType()) ||
+ EqualIgnoringASCIICase("message/rfc822", response_.MimeType());
if (loading_mhtml_archive_) {
// To commit an mhtml archive synchronously we have to load the whole body
// synchronously and parse it, and it's already loaded in a buffer usually.
@@ -1347,7 +1345,6 @@ void DocumentLoader::StartLoadingResponse() {
}
void DocumentLoader::DidInstallNewDocument(Document* document) {
- document->SetReadyState(Document::kLoading);
if (content_security_policy_)
document->BindContentSecurityPolicy();
@@ -1381,7 +1378,8 @@ void DocumentLoader::DidInstallNewDocument(Document* document) {
response_.HttpHeaderField(http_names::kReferrerPolicy);
if (!referrer_policy_header.IsNull()) {
UseCounter::Count(*document, WebFeature::kReferrerPolicyHeader);
- document->ParseAndSetReferrerPolicy(referrer_policy_header);
+ document->ToExecutionContext()->ParseAndSetReferrerPolicy(
+ referrer_policy_header);
}
if (response_.IsSignedExchangeInnerResponse()) {
@@ -1444,7 +1442,6 @@ void DocumentLoader::DidCommitNavigation() {
probe::DidCommitLoad(frame_, this);
frame_->GetPage()->DidCommitLoad(frame_);
- GetUseCounterHelper().DidCommitLoad(frame_);
// Report legacy TLS versions after Page::DidCommitLoad, because the latter
// clears the console.
@@ -1459,13 +1456,17 @@ void DocumentLoader::DidCommitNavigation() {
// origin policy (if any).
// Headers go first, which means that the per-page headers override the
// origin policy features.
+//
+// TODO(domenic): we want to treat origin policy feature policy as a single
+// feature policy, not a header serialization, so it should be processed
+// differently.
void MergeFeaturesFromOriginPolicy(WTF::StringBuilder& feature_policy,
const WebOriginPolicy& origin_policy) {
- for (const auto& policy : origin_policy.features) {
+ if (!origin_policy.feature_policy.IsNull()) {
if (!feature_policy.IsEmpty()) {
feature_policy.Append(',');
}
- feature_policy.Append(policy);
+ feature_policy.Append(origin_policy.feature_policy);
}
}
@@ -1473,8 +1474,7 @@ void DocumentLoader::InstallNewDocument(
const KURL& url,
const scoped_refptr<const SecurityOrigin> initiator_origin,
Document* owner_document,
- const AtomicString& mime_type,
- const KURL& overriding_url) {
+ const AtomicString& mime_type) {
DCHECK(!frame_->GetDocument() || !frame_->GetDocument()->IsActive());
DCHECK_EQ(frame_->Tree().ChildCount(), 0u);
@@ -1487,10 +1487,23 @@ void DocumentLoader::InstallNewDocument(
MergeFeaturesFromOriginPolicy(feature_policy, origin_policy_.value());
}
+ // Re-validate Document Policy feature before installing the new document.
+ if (!RuntimeEnabledFeatures::DocumentPolicyEnabled(owner_document))
+ document_policy_ = DocumentPolicy::ParsedDocumentPolicy{};
+
+ if (document_policy_.feature_state.contains(
+ mojom::blink::DocumentPolicyFeature::kForceLoadAtTop)) {
+ navigation_scroll_allowed_ = !(
+ document_policy_
+ .feature_state[mojom::blink::DocumentPolicyFeature::kForceLoadAtTop]
+ .BoolValue());
+ }
+
DocumentInit init =
DocumentInit::Create()
.WithDocumentLoader(this)
.WithURL(url)
+ .WithTypeFrom(mime_type)
.WithOwnerDocument(owner_document)
.WithInitiatorOrigin(initiator_origin)
.WithOriginToCommit(origin_to_commit_)
@@ -1501,9 +1514,23 @@ void DocumentLoader::InstallNewDocument(
.WithFramePolicy(frame_policy_)
.WithNewRegistrationContext()
.WithFeaturePolicyHeader(feature_policy.ToString())
+ // TODO(iclelland): Add Feature-Policy-Report-Only to Origin Policy.
+ .WithReportOnlyFeaturePolicyHeader(
+ response_.HttpHeaderField(http_names::kFeaturePolicyReportOnly))
+ .WithDocumentPolicy(document_policy_)
+ // |document_policy_| is parsed in document loader because it is
+ // compared with |frame_policy.required_document_policy| to decide
+ // whether to block the document load or not.
+ // |report_only_document_policy| does not block the page load. Its
+ // initialization is delayed to
+ // SecurityContextInit::InitializeDocumentPolicy(), similar to
+ // |report_only_feature_policy|.
+ .WithReportOnlyDocumentPolicyHeader(
+ response_.HttpHeaderField(http_names::kDocumentPolicyReportOnly))
.WithOriginTrialsHeader(
response_.HttpHeaderField(http_names::kOriginTrial))
- .WithContentSecurityPolicy(content_security_policy_.Get());
+ .WithContentSecurityPolicy(content_security_policy_.Get())
+ .WithWebBundleClaimedUrl(web_bundle_claimed_url_);
// A javascript: url inherits CSP from the document in which it was
// executed.
@@ -1526,6 +1553,9 @@ 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
@@ -1538,28 +1568,35 @@ void DocumentLoader::InstallNewDocument(
if (frame_->GetDocument())
frame_->GetDocument()->RemoveAllEventListenersRecursively();
frame_->SetDOMWindow(MakeGarbageCollected<LocalDOMWindow>(*frame_));
+ if (origin_policy_.has_value()) {
+ // Convert from WebVector<WebString> to WTF::Vector<WTF::String>
+ Vector<String> ids;
+ for (const auto& id : origin_policy_->ids) {
+ ids.push_back(id);
+ }
+
+ frame_->DomWindow()->SetOriginPolicyIds(ids);
+ }
}
if (!loading_url_as_javascript_)
WillCommitNavigation();
- Document* document =
- frame_->DomWindow()->InstallNewDocument(mime_type, init, false);
+ Document* document = frame_->DomWindow()->InstallNewDocument(init, false);
// Clear the user activation state.
// TODO(crbug.com/736415): Clear this bit unconditionally for all frames.
if (frame_->IsMainFrame())
- frame_->ClearActivation();
+ frame_->ClearUserActivation();
// The DocumentLoader was flagged as activated if it needs to notify the frame
// that it was activated before navigation. Update the frame state based on
// the new value.
- if (frame_->HasReceivedUserGestureBeforeNavigation() !=
+ if (frame_->HadStickyUserActivationBeforeNavigation() !=
had_sticky_activation_) {
- frame_->SetDocumentHasReceivedUserGestureBeforeNavigation(
- had_sticky_activation_);
- GetLocalFrameClient().SetHasReceivedUserGestureBeforeNavigation(
- had_sticky_activation_);
+ frame_->SetHadStickyUserActivationBeforeNavigation(had_sticky_activation_);
+ frame_->GetLocalFrameHostRemote()
+ .HadStickyUserActivationBeforeNavigationChanged(had_sticky_activation_);
}
bool should_clear_window_name =
@@ -1576,8 +1613,11 @@ void DocumentLoader::InstallNewDocument(
frame_->Tree().ExperimentalSetNulledName();
}
- if (!overriding_url.IsEmpty())
- document->SetBaseURLOverride(overriding_url);
+ if (loading_mhtml_archive_ && archive_ &&
+ !archive_->MainResource()->Url().IsEmpty()) {
+ document->SetBaseURLOverride(archive_->MainResource()->Url());
+ }
+
DidInstallNewDocument(document);
// This must be called before the document is opened, otherwise HTML parser
@@ -1585,6 +1625,12 @@ void DocumentLoader::InstallNewDocument(
if (!loading_url_as_javascript_)
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());
@@ -1598,10 +1644,41 @@ void DocumentLoader::InstallNewDocument(
// 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_ &&
- document->IsHTMLDocument());
+ IsA<HTMLDocument>(document));
} else {
document->SetDeferredCompositorCommitIsAllowed(false);
}
+
+ if (RuntimeEnabledFeatures::ForceLoadAtTopEnabled(document))
+ CountUse(WebFeature::kForceLoadAtTop);
+
+ // Log if the document was blocked by CSP checks now that the new Document has
+ // been created and console messages will be properly displayed.
+ if (was_blocked_by_csp_) {
+ ConsoleError("Refused to display '" +
+ response_.CurrentRequestUrl().ElidedString() +
+ "' because it has not opted into the following policy "
+ "required by its embedder: '" +
+ GetFrameLoader().RequiredCSP() + "'.");
+ }
+
+ if (was_blocked_by_document_policy_) {
+ // TODO(chenleihu): Add which document policy violated in error string,
+ // instead of just displaying serialized required document policy.
+ ConsoleError(
+ "Refused to display '" + response_.CurrentRequestUrl().ElidedString() +
+ "' because it violates the following document policy "
+ "required by its embedder: '" +
+ DocumentPolicy::Serialize(frame_policy_.required_document_policy)
+ .value_or("[Serialization Error]")
+ .c_str() +
+ "'.");
+ }
+
+ // Report the ResourceResponse now that the new Document has been created and
+ // console messages will be properly displayed.
+ frame_->Console().ReportResourceResponseReceived(
+ this, main_resource_identifier_, response_);
}
void DocumentLoader::CreateParserPostCommit() {
@@ -1618,7 +1695,7 @@ void DocumentLoader::CreateParserPostCommit() {
// Links with media values need more information (like viewport information).
// This happens after the first chunk is parsed in HTMLDocumentParser.
- DispatchLinkHeaderPreloads(base::nullopt /* viewport */,
+ DispatchLinkHeaderPreloads(nullptr /* viewport */,
PreloadHelper::kOnlyLoadNonMedia);
if (!loading_url_as_javascript_ &&
@@ -1629,7 +1706,7 @@ void DocumentLoader::CreateParserPostCommit() {
// Security Policies that have accumulated so far for the new navigation.
frame_->GetSecurityContext()
->GetContentSecurityPolicy()
- ->ReportAccumulatedHeaders(&GetLocalFrameClient());
+ ->ReportAccumulatedHeaders(frame_);
}
// Initializing origin trials might force window proxy initialization,
@@ -1643,6 +1720,10 @@ void DocumentLoader::CreateParserPostCommit() {
OriginTrialFeature::kTouchEventFeatureDetection);
}
+ // Enable any origin trials that have been force enabled for this commit.
+ document->GetOriginTrialContext()->AddForceEnabledTrials(
+ force_enabled_origin_trials_);
+
#if defined(OS_CHROMEOS)
// Enable Auto Picture-in-Picture feature for the built-in Chrome OS Video
// Player app.
@@ -1656,7 +1737,7 @@ void DocumentLoader::CreateParserPostCommit() {
#endif
OriginTrialContext::ActivateNavigationFeaturesFromInitiator(
- document, &initiator_origin_trial_features_);
+ document->ToExecutionContext(), &initiator_origin_trial_features_);
}
ParserSynchronizationPolicy parsing_policy = kAllowAsynchronousParsing;
@@ -1677,12 +1758,7 @@ void DocumentLoader::CreateParserPostCommit() {
// FeaturePolicy is reset in the browser process on commit, so this needs to
// be initialized and replicated to the browser process after commit messages
// are sent in didCommitNavigation().
- document->ApplyPendingFeaturePolicyHeaders();
-
- WTF::String report_only_feature_policy(
- response_.HttpHeaderField(http_names::kFeaturePolicyReportOnly));
- // TODO(iclelland): Add Feature-Policy-Report-Only to Origin Policy.
- document->ApplyReportOnlyFeaturePolicyFromHeader(report_only_feature_policy);
+ document->ApplyPendingFramePolicyHeaders();
GetFrameLoader().DispatchDidClearDocumentOfWindowObject();
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 be87ae25946..31fc5754a02 100644
--- a/chromium/third_party/blink/renderer/core/loader/document_loader.h
+++ b/chromium/third_party/blink/renderer/core/loader/document_loader.h
@@ -111,6 +111,7 @@ class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
public:
DocumentLoader(LocalFrame*,
WebNavigationType navigation_type,
+ ContentSecurityPolicy* content_security_policy,
std::unique_ptr<WebNavigationParams> navigation_params);
~DocumentLoader() override;
@@ -153,6 +154,7 @@ class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
const;
void DidChangePerformanceTiming();
+ void DidObserveInputDelay(base::TimeDelta input_delay);
void DidObserveLoadingBehavior(LoadingBehaviorFlag);
void UpdateForSameDocumentNavigation(const KURL&,
SameDocumentNavigationSource,
@@ -236,7 +238,7 @@ class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
};
InitialScrollState& GetInitialScrollState() { return initial_scroll_state_; }
- void DispatchLinkHeaderPreloads(const base::Optional<ViewportDescription>&,
+ void DispatchLinkHeaderPreloads(const ViewportDescription*,
PreloadHelper::MediaPreloadPolicy);
void SetServiceWorkerNetworkProvider(
@@ -251,7 +253,7 @@ class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
void LoadFailed(const ResourceError&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// For automation driver-initiated navigations over the devtools protocol,
// |devtools_navigation_token_| is used to tag the navigation. This navigation
@@ -316,6 +318,12 @@ class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
const KURL& WebBundlePhysicalUrl() const { return web_bundle_physical_url_; }
+ bool LastSameDocumentNavigationWasBrowserInitiated() const {
+ return last_same_document_navigation_was_browser_initiated_;
+ }
+
+ bool NavigationScrollAllowed() const { return navigation_scroll_allowed_; }
+
protected:
Vector<KURL> redirect_chain_;
@@ -336,8 +344,7 @@ class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
const KURL&,
const scoped_refptr<const SecurityOrigin> initiator_origin,
Document* owner_document,
- const AtomicString& mime_type,
- const KURL& overriding_url);
+ const AtomicString& mime_type);
void DidInstallNewDocument(Document*);
void WillCommitNavigation();
void DidCommitNavigation();
@@ -358,9 +365,14 @@ class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
FrameLoader& GetFrameLoader() const;
LocalFrameClient& GetLocalFrameClient() const;
- ContentSecurityPolicy* CreateCSP(
- const ResourceResponse&,
- const base::Optional<WebOriginPolicy>& origin_policy);
+ void ConsoleError(const String& message);
+
+ // Replace the current document with a empty one and the URL with a unique
+ // opaque origin.
+ void ReplaceWithEmptyDocument();
+
+ DocumentPolicy::ParsedDocumentPolicy CreateDocumentPolicy();
+
void StartLoadingInternal();
void FinishedLoading(base::TimeTicks finish_time);
void CancelLoadAfterCSPDenied(const ResourceResponse&);
@@ -422,7 +434,7 @@ class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
network::mojom::IPAddressSpace::kUnknown;
bool grant_load_local_resources_ = false;
base::Optional<blink::mojom::FetchCacheMode> force_fetch_cache_mode_;
- base::Optional<FramePolicy> frame_policy_;
+ FramePolicy frame_policy_;
// Params are saved in constructor and are cleared after StartLoading().
// TODO(dgozman): remove once StartLoading is merged with constructor.
@@ -469,6 +481,9 @@ class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
std::unique_ptr<WebServiceWorkerNetworkProvider>
service_worker_network_provider_;
+ bool was_blocked_by_document_policy_;
+ DocumentPolicy::ParsedDocumentPolicy document_policy_;
+
Member<ContentSecurityPolicy> content_security_policy_;
ClientHintsPreferences client_hints_preferences_;
InitialScrollState initial_scroll_state_;
@@ -515,7 +530,7 @@ class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
Member<SourceKeyedCachedMetadataHandler> cached_metadata_handler_;
Member<PrefetchedSignedExchangeManager> prefetched_signed_exchange_manager_;
KURL web_bundle_physical_url_;
- KURL base_url_override_for_web_bundle_;
+ 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
@@ -529,6 +544,15 @@ class CORE_EXPORT DocumentLoader : public GarbageCollected<DocumentLoader>,
const base::TickClock* clock_;
Vector<OriginTrialFeature> initiator_origin_trial_features_;
+
+ Vector<String> force_enabled_origin_trials_;
+
+ // Whether this load request is a result of a browser initiated same-document
+ // navigation.
+ bool last_same_document_navigation_was_browser_initiated_ = false;
+
+ // Whether the document can be scrolled on load
+ bool navigation_scroll_allowed_ = true;
};
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 1cf18f95df9..f3673fe84eb 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
@@ -14,6 +14,7 @@
#include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
+#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/testing/scoped_fake_plugin_registry.h"
#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
@@ -253,7 +254,63 @@ TEST_F(DocumentLoaderSimTest, FramePolicyIntegrityOnNavigationCommit) {
auto* child_document = child_frame->GetFrame()->GetDocument();
EXPECT_TRUE(child_document->IsFeatureEnabled(
- blink::mojom::FeaturePolicyFeature::kPayment));
+ blink::mojom::blink::FeaturePolicyFeature::kPayment));
+}
+
+TEST_F(DocumentLoaderSimTest, ReportErrorWhenDocumentPolicyIncompatible) {
+ blink::ScopedDocumentPolicyForTest sdp(true);
+ SimRequest::Params params;
+ params.response_http_headers = {
+ {"Document-Policy", "unoptimized-lossless-images;bpp=1.1"}};
+
+ SimRequest main_resource("https://example.com", "text/html");
+ SimRequest iframe_resource("https://example.com/foo.html", "text/html",
+ params);
+
+ LoadURL("https://example.com");
+ main_resource.Complete(R"(
+ <iframe
+ src="https://example.com/foo.html"
+ policy="unoptimized-lossless-images;bpp=1.0">
+ </iframe>
+ )");
+
+ // When blocked by document policy, the document should be filled in with an
+ // empty response, with Finish called on |navigation_body_loader| already.
+ // If Finish was not called on the loader, because the document was not
+ // blocked, this test will fail by crashing here.
+ iframe_resource.Finish(true /* body_loader_finished */);
+
+ auto* child_frame = To<WebLocalFrameImpl>(MainFrame().FirstChild());
+ auto* child_document = child_frame->GetFrame()->GetDocument();
+
+ // Should console log a error message.
+ auto& console_messages = static_cast<frame_test_helpers::TestWebFrameClient*>(
+ child_frame->Client())
+ ->ConsoleMessages();
+
+ ASSERT_EQ(console_messages.size(), 1u);
+ EXPECT_TRUE(console_messages.front().Contains("document policy"));
+
+ // Should replace the document's origin with an opaque origin.
+ EXPECT_EQ(child_document->Url(), SecurityOrigin::UrlWithUniqueOpaqueOrigin());
+}
+
+// HTTP header Require-Document-Policy should only take effect on subtree of
+// current document, but not on current document.
+TEST_F(DocumentLoaderSimTest,
+ RequireDocumentPolicyHeaderShouldNotAffectCurrentDocument) {
+ blink::ScopedDocumentPolicyForTest sdp(true);
+ SimRequest::Params params;
+ params.response_http_headers = {
+ {"Require-Document-Policy", "unoptimized-lossless-images;bpp=1.0"},
+ {"Document-Policy", "unoptimized-lossless-images;bpp=1.1"}};
+
+ SimRequest main_resource("https://example.com", "text/html", params);
+ LoadURL("https://example.com");
+ // If document is blocked by document policy because of incompatible document
+ // policy, this test will fail by crashing here.
+ main_resource.Finish();
}
TEST_F(DocumentLoaderTest, CommitsDeferredOnSameOriginNavigation) {
diff --git a/chromium/third_party/blink/renderer/core/loader/empty_clients.cc b/chromium/third_party/blink/renderer/core/loader/empty_clients.cc
index cf9c781c221..31d1f0a93bf 100644
--- a/chromium/third_party/blink/renderer/core/loader/empty_clients.cc
+++ b/chromium/third_party/blink/renderer/core/loader/empty_clients.cc
@@ -90,7 +90,7 @@ String EmptyChromeClient::AcceptLanguages() {
void EmptyLocalFrameClient::BeginNavigation(
const ResourceRequest&,
- network::mojom::RequestContextFrameType,
+ mojom::RequestContextFrameType,
Document* origin_document,
DocumentLoader*,
WebNavigationType,
@@ -100,11 +100,12 @@ void EmptyLocalFrameClient::BeginNavigation(
bool,
TriggeringEventInfo,
HTMLFormElement*,
- ContentSecurityPolicyDisposition,
+ network::mojom::CSPDisposition,
mojo::PendingRemote<mojom::blink::BlobURLToken>,
base::TimeTicks,
const String&,
- WebContentSecurityPolicyList,
+ WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr> initiator_csp,
+ network::mojom::blink::CSPSourcePtr initiator_csp_self,
network::mojom::IPAddressSpace,
mojo::PendingRemote<mojom::blink::NavigationInitiator>) {}
@@ -113,10 +114,12 @@ void EmptyLocalFrameClient::DispatchWillSendSubmitEvent(HTMLFormElement*) {}
DocumentLoader* EmptyLocalFrameClient::CreateDocumentLoader(
LocalFrame* frame,
WebNavigationType navigation_type,
+ ContentSecurityPolicy* content_security_policy,
std::unique_ptr<WebNavigationParams> navigation_params,
std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) {
DCHECK(frame);
return MakeGarbageCollected<DocumentLoader>(frame, navigation_type,
+ content_security_policy,
std::move(navigation_params));
}
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 35dfcf4f540..bbfe2870e68 100644
--- a/chromium/third_party/blink/renderer/core/loader/empty_clients.h
+++ b/chromium/third_party/blink/renderer/core/loader/empty_clients.h
@@ -35,11 +35,11 @@
#include "cc/paint/paint_canvas.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
-#include "services/service_manager/public/cpp/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"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_focus_type.h"
-#include "third_party/blink/public/platform/web_menu_source_type.h"
#include "third_party/blink/public/platform/web_screen_info.h"
#include "third_party/blink/public/platform/web_spell_check_panel_host_client.h"
#include "third_party/blink/public/platform/web_url_loader.h"
@@ -48,6 +48,7 @@
#include "third_party/blink/renderer/core/frame/remote_frame_client.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/platform/cursors.h"
#include "third_party/blink/renderer/platform/exported/wrapped_resource_request.h"
#include "third_party/blink/renderer/platform/geometry/float_point.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
@@ -56,6 +57,7 @@
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_error.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
+#include "ui/base/cursor/cursor.h"
#include "v8/include/v8.h"
/*
@@ -74,6 +76,10 @@
Brittle, yes. Unfortunate, yes. Hopefully temporary.
*/
+namespace ui {
+class Cursor;
+}
+
namespace blink {
enum class GlobalObjectReusePolicy;
@@ -81,42 +87,33 @@ enum class GlobalObjectReusePolicy;
class CORE_EXPORT EmptyChromeClient : public ChromeClient {
public:
~EmptyChromeClient() override = default;
- void ChromeDestroyed() override {}
+ // ChromeClient implementation.
WebViewImpl* GetWebView() const override { return nullptr; }
+ void ChromeDestroyed() override {}
void SetWindowRect(const IntRect&, LocalFrame&) override {}
IntRect RootWindowRect(LocalFrame&) override { return IntRect(); }
-
void Focus(LocalFrame*) override {}
-
- bool CanTakeFocus(WebFocusType) override { return false; }
- void TakeFocus(WebFocusType) override {}
-
- void FocusedElementChanged(Element*, Element*) override {}
+ bool CanTakeFocus(mojom::blink::FocusType) override { return false; }
+ void TakeFocus(mojom::blink::FocusType) override {}
void Show(NavigationPolicy) override {}
-
- void DidOverscroll(const FloatSize&,
- const FloatSize&,
- const FloatPoint&,
- const FloatSize&) override {}
+ void DidOverscroll(const gfx::Vector2dF&,
+ const gfx::Vector2dF&,
+ const gfx::PointF&,
+ const gfx::Vector2dF&) override {}
void SetOverscrollBehavior(LocalFrame& frame,
const cc::OverscrollBehavior&) override {}
-
void BeginLifecycleUpdates(LocalFrame& main_frame) override {}
void StartDeferringCommits(LocalFrame& main_frame,
base::TimeDelta timeout) override {}
void StopDeferringCommits(LocalFrame& main_frame,
cc::PaintHoldingCommitTrigger) override {}
-
- bool HadFormInteraction() const override { return false; }
-
void StartDragging(LocalFrame*,
const WebDragData&,
WebDragOperationsMask,
const SkBitmap& drag_image,
const gfx::Point& drag_image_offset) override {}
bool AcceptsLoadDrops() const override { return true; }
-
bool ShouldReportDetailedMessageForSource(LocalFrame&,
const String&) override {
return false;
@@ -128,24 +125,20 @@ class CORE_EXPORT EmptyChromeClient : public ChromeClient {
unsigned,
const String&,
const String&) override {}
-
bool CanOpenBeforeUnloadConfirmPanel() override { return false; }
bool OpenBeforeUnloadConfirmPanelDelegate(LocalFrame*, bool) override {
return true;
}
-
void CloseWindowSoon() override {}
-
Page* CreateWindowDelegate(LocalFrame*,
const FrameLoadRequest&,
const AtomicString&,
const WebWindowFeatures&,
- WebSandboxFlags,
+ mojom::blink::WebSandboxFlags,
const FeaturePolicy::FeatureState&,
const SessionStorageNamespaceId&) override {
return nullptr;
}
-
bool OpenJavaScriptAlertDelegate(LocalFrame*, const String&) override {
return false;
}
@@ -158,7 +151,6 @@ class CORE_EXPORT EmptyChromeClient : public ChromeClient {
String&) override {
return false;
}
-
bool HasOpenedPopup() const override { return false; }
PopupMenu* OpenPopupMenu(LocalFrame&, HTMLSelectElement&) override;
PagePopup* OpenPagePopup(PagePopupClient*) override { return nullptr; }
@@ -170,7 +162,6 @@ class CORE_EXPORT EmptyChromeClient : public ChromeClient {
void InvalidateRect(const IntRect&) override {}
void ScheduleAnimation(const LocalFrameView*,
base::TimeDelta = base::TimeDelta()) override {}
-
IntRect ViewportToScreen(const IntRect& r,
const LocalFrameView*) const override {
return r;
@@ -182,13 +173,9 @@ class CORE_EXPORT EmptyChromeClient : public ChromeClient {
return WebScreenInfo();
}
void ContentsSizeChanged(LocalFrame*, const IntSize&) const override {}
-
void ShowMouseOverURL(const HitTestResult&) override {}
-
void SetToolTip(LocalFrame&, const String&, TextDirection) override {}
-
void PrintDelegate(LocalFrame*) override {}
-
ColorChooser* OpenColorChooser(LocalFrame*,
ColorChooserClient*,
const Color&) override;
@@ -197,16 +184,14 @@ class CORE_EXPORT EmptyChromeClient : public ChromeClient {
DateTimeChooserClient*,
const DateTimeChooserParameters&) override;
void OpenTextDataListChooser(HTMLInputElement&) override;
-
void OpenFileChooser(LocalFrame*, scoped_refptr<FileChooser>) override;
-
- void SetCursor(const Cursor&, LocalFrame* local_root) override {}
+ void SetCursor(const ui::Cursor&, LocalFrame* local_root) override {}
void SetCursorOverridden(bool) override {}
- Cursor LastSetCursorForTesting() const override { return PointerCursor(); }
-
+ ui::Cursor LastSetCursorForTesting() const override {
+ return PointerCursor();
+ }
void AttachRootLayer(scoped_refptr<cc::Layer>,
LocalFrame* local_root) override;
-
void SetEventListenerProperties(LocalFrame*,
cc::EventListenerClass,
cc::EventListenerProperties) override {}
@@ -220,32 +205,23 @@ class CORE_EXPORT EmptyChromeClient : public ChromeClient {
void SetNeedsUnbufferedInputForDebugger(LocalFrame*, bool) override {}
void RequestUnbufferedInputEvents(LocalFrame*) override {}
void SetTouchAction(LocalFrame*, TouchAction) override {}
-
void DidAssociateFormControlsAfterLoad(LocalFrame*) override {}
-
String AcceptLanguages() override;
-
void RegisterPopupOpeningObserver(PopupOpeningObserver*) override {}
void UnregisterPopupOpeningObserver(PopupOpeningObserver*) override {}
void NotifyPopupOpeningObservers() const override {}
-
void FallbackCursorModeLockCursor(LocalFrame* frame,
bool left,
bool right,
bool up,
bool down) override {}
-
void FallbackCursorModeSetCursorVisibility(LocalFrame* frame,
bool visible) override {}
-
void RequestBeginMainFrameNotExpected(LocalFrame& frame,
bool request) override {}
int GetLayerTreeId(LocalFrame& frame) override { return 0; }
-
- void SetCursorForPlugin(const WebCursorInfo&, LocalFrame*) override {}
-
+ void SetCursorForPlugin(const ui::Cursor&, LocalFrame*) override {}
void InstallSupplements(LocalFrame&) override {}
-
void MainFrameScrollOffsetChanged(LocalFrame& main_frame) const override {}
};
@@ -274,9 +250,7 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
const ResourceResponse&) override {}
void DispatchDidHandleOnloadEvents() override {}
- void DispatchDidStartProvisionalLoad(DocumentLoader*) override {}
void DispatchDidReceiveTitle(const String&) override {}
- void DispatchDidChangeIcons(IconType) override {}
void DispatchDidCommitLoad(HistoryItem*,
WebHistoryCommitType,
GlobalObjectReusePolicy) override {}
@@ -287,7 +261,7 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
void BeginNavigation(
const ResourceRequest&,
- network::mojom::RequestContextFrameType,
+ mojom::RequestContextFrameType,
Document* origin_document,
DocumentLoader*,
WebNavigationType,
@@ -297,28 +271,25 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
bool,
TriggeringEventInfo,
HTMLFormElement*,
- ContentSecurityPolicyDisposition,
+ network::mojom::CSPDisposition,
mojo::PendingRemote<mojom::blink::BlobURLToken>,
base::TimeTicks,
const String&,
- WebContentSecurityPolicyList,
+ WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr>
+ initiator_csp,
+ network::mojom::blink::CSPSourcePtr initiator_self_source,
network::mojom::IPAddressSpace,
mojo::PendingRemote<mojom::blink::NavigationInitiator>) override;
void DispatchWillSendSubmitEvent(HTMLFormElement*) override;
void DidStartLoading() override {}
- void ProgressEstimateChanged(double) override {}
void DidStopLoading() override {}
- void ForwardResourceTimingToParent(const WebResourceTimingInfo&) override {}
-
- void DownloadURL(const ResourceRequest&,
- network::mojom::RedirectMode) override {}
-
DocumentLoader* CreateDocumentLoader(
LocalFrame*,
WebNavigationType,
+ ContentSecurityPolicy*,
std::unique_ptr<WebNavigationParams> navigation_params,
std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) override;
void UpdateDocumentLoader(
@@ -326,7 +297,7 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) override {}
String UserAgent() override { return ""; }
- blink::UserAgentMetadata UserAgentMetadata() override {
+ base::Optional<blink::UserAgentMetadata> UserAgentMetadata() override {
return blink::UserAgentMetadata();
}
@@ -360,7 +331,8 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
WebRemotePlaybackClient* CreateWebRemotePlaybackClient(
HTMLMediaElement&) override;
- void DidCreateNewDocument() override {}
+ void DidCreateInitialEmptyDocument() override {}
+ void DidCommitJavascriptUrlNavigation(DocumentLoader*) override {}
void DispatchDidClearWindowObjectInMainWorld() override {}
void DocumentElementAvailable() override {}
void RunScriptsAtDocumentElementAvailable() override {}
@@ -373,10 +345,6 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
int32_t world_id) override {}
bool AllowScriptExtensions() override { return false; }
- service_manager::InterfaceProvider* GetInterfaceProvider() override {
- return &interface_provider_;
- }
-
BrowserInterfaceBrokerProxy& GetBrowserInterfaceBroker() override {
return GetEmptyBrowserInterfaceBroker();
}
@@ -407,10 +375,6 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
return nullptr;
}
- void BubbleLogicalScrollInParentFrame(
- ScrollDirection direction,
- ScrollGranularity granularity) override {}
-
void AnnotatedRegionsChanged() override {}
base::UnguessableToken GetDevToolsFrameToken() const override {
return base::UnguessableToken::Create();
@@ -425,8 +389,6 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
// Not owned
WebTextCheckClient* text_check_client_;
- service_manager::InterfaceProvider interface_provider_;
-
DISALLOW_COPY_AND_ASSIGN(EmptyLocalFrameClient);
};
@@ -451,22 +413,20 @@ class CORE_EXPORT EmptyRemoteFrameClient : public RemoteFrameClient {
void Navigate(const ResourceRequest&,
bool should_replace_current_entry,
bool is_opener_navigation,
- bool prevent_sandboxed_download,
+ bool initiator_frame_has_download_sandbox_flag,
bool initiator_frame_is_ad,
mojo::PendingRemote<mojom::blink::BlobURLToken>) override {}
unsigned BackForwardLength() override { return 0; }
- void CheckCompleted() override {}
- void ForwardPostMessage(MessageEvent*,
- scoped_refptr<const SecurityOrigin> target,
- LocalFrame* source_frame) const override {}
+ 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(WebFocusType, LocalFrame* source) override {}
- void SetIsInert(bool) override {}
- void UpdateRenderThrottlingStatus(bool is_throttled,
- bool subtree_throttled) override {}
+ void AdvanceFocus(mojom::blink::FocusType, LocalFrame* source) override {}
uint32_t Print(const IntRect& rect, cc::PaintCanvas* canvas) const override {
return 0;
}
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
new file mode 100644
index 00000000000..babcddb8903
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/loader/font_preload_manager.cc
@@ -0,0 +1,215 @@
+// 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/loader/font_preload_manager.h"
+
+#include "build/build_config.h"
+#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/common/loader/loading_behavior_flag.h"
+#include "third_party/blink/renderer/core/css/font_face.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/loader/document_loader.h"
+#include "third_party/blink/renderer/core/loader/resource/font_resource.h"
+#include "third_party/blink/renderer/platform/loader/fetch/resource_finish_observer.h"
+
+namespace blink {
+
+namespace {
+
+class FontPreloadFinishObserver final : public ResourceFinishObserver {
+ public:
+ FontPreloadFinishObserver(FontResource& font_resource, Document& document)
+ : font_resource_(font_resource), document_(document) {}
+
+ ~FontPreloadFinishObserver() final = default;
+
+ void Trace(blink::Visitor* visitor) final {
+ visitor->Trace(font_resource_);
+ visitor->Trace(document_);
+ ResourceFinishObserver::Trace(visitor);
+ }
+
+ private:
+ void NotifyFinished() final {
+ document_->GetFontPreloadManager().FontPreloadingFinished(font_resource_,
+ this);
+ }
+
+ String DebugName() const final { return "FontPreloadFinishObserver"; }
+
+ Member<FontResource> font_resource_;
+ Member<Document> document_;
+};
+
+class ImperativeFontLoadFinishedCallback final
+ : public GarbageCollected<ImperativeFontLoadFinishedCallback>,
+ public FontFace::LoadFontCallback {
+ USING_GARBAGE_COLLECTED_MIXIN(ImperativeFontLoadFinishedCallback);
+
+ public:
+ explicit ImperativeFontLoadFinishedCallback(Document& document)
+ : document_(document) {}
+ ~ImperativeFontLoadFinishedCallback() final = default;
+
+ void Trace(Visitor* visitor) final {
+ visitor->Trace(document_);
+ FontFace::LoadFontCallback::Trace(visitor);
+ }
+
+ private:
+ void NotifyLoaded(FontFace*) final {
+ document_->GetFontPreloadManager().ImperativeFontLoadingFinished();
+ }
+
+ void NotifyError(FontFace*) final {
+ document_->GetFontPreloadManager().ImperativeFontLoadingFinished();
+ }
+
+ Member<Document> document_;
+};
+
+} // namespace
+
+FontPreloadManager::FontPreloadManager(Document& document)
+ : document_(document),
+ render_delay_timer_(
+ document.GetTaskRunner(TaskType::kInternalFrameLifecycleControl),
+ this,
+ &FontPreloadManager::FontPreloadingDelaysRenderingTimerFired),
+ render_delay_timeout_(base::TimeDelta::FromMilliseconds(
+ features::kFontPreloadingDelaysRenderingParam.Get())) {}
+
+bool FontPreloadManager::HasPendingRenderBlockingFonts() const {
+ return state_ == State::kLoading;
+}
+
+void FontPreloadManager::FontPreloadingStarted(FontResource* font_resource) {
+ // The font is either already in the memory cache, or has errored out. In
+ // either case, we don't any further processing.
+ if (font_resource->IsLoaded())
+ return;
+
+ if (state_ == State::kUnblocked)
+ return;
+
+ document_->Loader()->DidObserveLoadingBehavior(
+ kLoadingBehaviorFontPreloadStartedBeforeRendering);
+
+ if (!base::FeatureList::IsEnabled(features::kFontPreloadingDelaysRendering))
+ return;
+
+ FontPreloadFinishObserver* observer =
+ MakeGarbageCollected<FontPreloadFinishObserver>(*font_resource,
+ *document_);
+ font_resource->AddFinishObserver(
+ observer, document_->GetTaskRunner(TaskType::kInternalLoading).get());
+ finish_observers_.insert(observer);
+
+ RenderBlockingFontLoadingStarted();
+}
+
+void FontPreloadManager::ImperativeFontLoadingStarted(FontFace* font_face) {
+ if (font_face->LoadStatus() != FontFace::kLoading)
+ return;
+
+ if (state_ == State::kUnblocked)
+ return;
+
+ document_->Loader()->DidObserveLoadingBehavior(
+ kLoadingBehaviorFontPreloadStartedBeforeRendering);
+
+ if (!base::FeatureList::IsEnabled(features::kFontPreloadingDelaysRendering))
+ return;
+
+ ImperativeFontLoadFinishedCallback* callback =
+ MakeGarbageCollected<ImperativeFontLoadFinishedCallback>(*document_);
+ font_face->AddCallback(callback);
+ ++imperative_font_loading_count_;
+
+ RenderBlockingFontLoadingStarted();
+}
+
+void FontPreloadManager::RenderBlockingFontLoadingStarted() {
+ DCHECK(
+ base::FeatureList::IsEnabled(features::kFontPreloadingDelaysRendering));
+ DCHECK_NE(State::kUnblocked, state_);
+ if (state_ == State::kInitial)
+ render_delay_timer_.StartOneShot(render_delay_timeout_, FROM_HERE);
+ state_ = State::kLoading;
+}
+
+void FontPreloadManager::FontPreloadingFinished(
+ FontResource* font_resource,
+ ResourceFinishObserver* observer) {
+ DCHECK(
+ base::FeatureList::IsEnabled(features::kFontPreloadingDelaysRendering));
+ if (state_ == State::kUnblocked) {
+ finish_observers_.clear();
+ return;
+ }
+
+ DCHECK(finish_observers_.Contains(observer));
+ finish_observers_.erase(observer);
+ RenderBlockingFontLoadingFinished();
+}
+
+void FontPreloadManager::ImperativeFontLoadingFinished() {
+ DCHECK(
+ base::FeatureList::IsEnabled(features::kFontPreloadingDelaysRendering));
+ if (state_ == State::kUnblocked) {
+ imperative_font_loading_count_ = 0;
+ return;
+ }
+
+ DCHECK(imperative_font_loading_count_);
+ --imperative_font_loading_count_;
+ RenderBlockingFontLoadingFinished();
+}
+
+void FontPreloadManager::RenderBlockingFontLoadingFinished() {
+ DCHECK(
+ base::FeatureList::IsEnabled(features::kFontPreloadingDelaysRendering));
+ DCHECK_NE(State::kUnblocked, state_);
+ if (!finish_observers_.IsEmpty() || imperative_font_loading_count_)
+ return;
+ state_ = State::kLoaded;
+ document_->FontPreloadingFinishedOrTimedOut();
+}
+
+void FontPreloadManager::WillBeginRendering() {
+ if (state_ == State::kUnblocked)
+ return;
+
+ state_ = State::kUnblocked;
+ finish_observers_.clear();
+ imperative_font_loading_count_ = 0;
+}
+
+void FontPreloadManager::FontPreloadingDelaysRenderingTimerFired(TimerBase*) {
+ if (state_ == State::kUnblocked)
+ return;
+
+ WillBeginRendering();
+ document_->FontPreloadingFinishedOrTimedOut();
+}
+
+void FontPreloadManager::SetRenderDelayTimeoutForTest(base::TimeDelta timeout) {
+ if (render_delay_timer_.IsActive()) {
+ render_delay_timer_.Stop();
+ render_delay_timer_.StartOneShot(timeout, FROM_HERE);
+ }
+ render_delay_timeout_ = timeout;
+}
+
+void FontPreloadManager::DisableTimeoutForTest() {
+ if (render_delay_timer_.IsActive())
+ render_delay_timer_.Stop();
+}
+
+void FontPreloadManager::Trace(Visitor* visitor) {
+ visitor->Trace(finish_observers_);
+ visitor->Trace(document_);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..a7e4871c94e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/loader/font_preload_manager.h
@@ -0,0 +1,89 @@
+// 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_LOADER_FONT_PRELOAD_MANAGER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_FONT_PRELOAD_MANAGER_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/timer.h"
+
+namespace blink {
+
+class Document;
+class FontResource;
+class FontFace;
+class ResourceFinishObserver;
+
+// This class monitors font preloading (via <link rel="preload"> or Font Loading
+// API) and notifies the relevant document, so that it can manage the first
+// rendering timing to work with preloaded fonts.
+// Design doc: https://bit.ly/36E8UKB
+class CORE_EXPORT FontPreloadManager final {
+ DISALLOW_NEW();
+
+ public:
+ explicit FontPreloadManager(Document&);
+ ~FontPreloadManager() = default;
+
+ FontPreloadManager(const FontPreloadManager&) = delete;
+ FontPreloadManager& operator=(const FontPreloadManager&) = delete;
+
+ bool HasPendingRenderBlockingFonts() const;
+ void WillBeginRendering();
+ bool RenderingHasBegun() const { return state_ == State::kUnblocked; }
+
+ void FontPreloadingStarted(FontResource*);
+ void FontPreloadingFinished(FontResource*, ResourceFinishObserver*);
+ void FontPreloadingDelaysRenderingTimerFired(TimerBase*);
+
+ void ImperativeFontLoadingStarted(FontFace*);
+ void ImperativeFontLoadingFinished();
+
+ // Exposed to web tests via internals.
+ void SetRenderDelayTimeoutForTest(base::TimeDelta timeout);
+
+ void Trace(Visitor* visitor);
+
+ private:
+ friend class FontPreloadManagerTest;
+
+ void DisableTimeoutForTest();
+
+ // State of font preloading before lifecycle updates begin
+ enum class State {
+ // Rendering hasn't begun. No font preloading yet.
+ kInitial,
+ // Rendering hasn't begun. There are ongoing font preloadings.
+ kLoading,
+ // Rendering hasn't begun. At least one font has been preloaded,
+ // and all font preloading so far has finished.
+ kLoaded,
+ // Rendering will begin soon or has begun. Font preloading shouldn't block
+ // rendering any more.
+ kUnblocked
+ };
+
+ void RenderBlockingFontLoadingStarted();
+ void RenderBlockingFontLoadingFinished();
+
+ Member<Document> document_;
+
+ // Need to hold strong references here, otherwise they'll be GC-ed immediately
+ // as Resource only holds weak references.
+ HeapHashSet<Member<ResourceFinishObserver>> finish_observers_;
+
+ unsigned imperative_font_loading_count_ = 0;
+
+ TaskRunnerTimer<FontPreloadManager> render_delay_timer_;
+ base::TimeDelta render_delay_timeout_;
+
+ State state_ = State::kInitial;
+
+ // TODO(xiaochengh): Do the same for fonts loaded for other reasons?
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_FONT_PRELOAD_MANAGER_H_
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
new file mode 100644
index 00000000000..8a254066e90
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/loader/font_preload_manager_test.cc
@@ -0,0 +1,486 @@
+// 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/loader/font_preload_manager.h"
+
+#include "base/test/scoped_feature_list.h"
+#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/renderer/core/dom/element.h"
+#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
+#include "third_party/blink/renderer/core/html/html_head_element.h"
+#include "third_party/blink/renderer/core/layout/layout_object.h"
+#include "third_party/blink/renderer/core/style/computed_style.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 {
+
+class FontPreloadManagerTest : public SimTest {
+ public:
+ void SetUp() override {
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kFontPreloadingDelaysRendering);
+ SimTest::SetUp();
+ }
+
+ static Vector<char> ReadAhemWoff2() {
+ return test::ReadFromFile(test::CoreTestDataPath("Ahem.woff2"))
+ ->CopyAs<Vector<char>>();
+ }
+
+ protected:
+ FontPreloadManager& GetFontPreloadManager() {
+ return GetDocument().GetFontPreloadManager();
+ }
+
+ using State = FontPreloadManager::State;
+ State GetState() { return GetFontPreloadManager().state_; }
+
+ void DisableFontPreloadManagerTimeout() {
+ GetFontPreloadManager().DisableTimeoutForTest();
+ }
+
+ Element* GetTarget() { return GetDocument().getElementById("target"); }
+
+ const Font& GetTargetFont() {
+ return GetTarget()->GetLayoutObject()->Style()->GetFont();
+ }
+
+ private:
+ base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+TEST_F(FontPreloadManagerTest, FastFontFinishBeforeBody) {
+ SimRequest main_resource("https://example.com", "text/html");
+ SimRequest font_resource("https://example.com/font.woff", "font/woff2");
+
+ LoadURL("https://example.com");
+ main_resource.Write(R"HTML(
+ <!doctype html>
+ <head>
+ <link rel="preload" as="font" type="font/woff2"
+ href="https://example.com/font.woff">
+ )HTML");
+
+ // Rendering is blocked due to ongoing font preloading.
+ EXPECT_TRUE(Compositor().DeferMainFrameUpdate());
+ EXPECT_TRUE(GetFontPreloadManager().HasPendingRenderBlockingFonts());
+ EXPECT_EQ(State::kLoading, GetState());
+
+ font_resource.Finish();
+ test::RunPendingTasks();
+
+ // Font preloading no longer blocks renderings. However, rendering is still
+ // blocked, as we don't have BODY yet.
+ EXPECT_TRUE(Compositor().DeferMainFrameUpdate());
+ EXPECT_FALSE(GetFontPreloadManager().HasPendingRenderBlockingFonts());
+ EXPECT_EQ(State::kLoaded, GetState());
+
+ main_resource.Complete("</head><body>some text</body>");
+
+ // Rendering starts after BODY has arrived, as the font was loaded earlier.
+ EXPECT_FALSE(Compositor().DeferMainFrameUpdate());
+ EXPECT_FALSE(GetFontPreloadManager().HasPendingRenderBlockingFonts());
+ EXPECT_EQ(State::kUnblocked, GetState());
+}
+
+TEST_F(FontPreloadManagerTest, FastFontFinishAfterBody) {
+ SimRequest main_resource("https://example.com", "text/html");
+ SimRequest font_resource("https://example.com/font.woff", "font/woff2");
+
+ LoadURL("https://example.com");
+ main_resource.Write(R"HTML(
+ <!doctype html>
+ <head>
+ <link rel="preload" as="font" type="font/woff2"
+ href="https://example.com/font.woff">
+ )HTML");
+
+ // Rendering is blocked due to ongoing font preloading.
+ EXPECT_TRUE(Compositor().DeferMainFrameUpdate());
+ EXPECT_TRUE(GetFontPreloadManager().HasPendingRenderBlockingFonts());
+ EXPECT_EQ(State::kLoading, GetState());
+
+ main_resource.Complete("</head><body>some text</body>");
+
+ // Rendering is still blocked by font, even if we already have BODY, because
+ // the font was *not* loaded earlier.
+ EXPECT_TRUE(Compositor().DeferMainFrameUpdate());
+ EXPECT_TRUE(GetFontPreloadManager().HasPendingRenderBlockingFonts());
+ EXPECT_EQ(State::kLoading, GetState());
+
+ font_resource.Finish();
+ test::RunPendingTasks();
+
+ // Rendering starts after font preloading has finished.
+ EXPECT_FALSE(Compositor().DeferMainFrameUpdate());
+ EXPECT_FALSE(GetFontPreloadManager().HasPendingRenderBlockingFonts());
+ EXPECT_EQ(State::kUnblocked, GetState());
+}
+
+TEST_F(FontPreloadManagerTest, SlowFontTimeoutBeforeBody) {
+ SimRequest main_resource("https://example.com", "text/html");
+ SimRequest font_resource("https://example.com/font.woff", "font/woff2");
+
+ LoadURL("https://example.com");
+ main_resource.Write(R"HTML(
+ <!doctype html>
+ <head>
+ <link rel="preload" as="font" type="font/woff2"
+ href="https://example.com/font.woff">
+ )HTML");
+
+ // Rendering is blocked due to ongoing font preloading.
+ EXPECT_TRUE(Compositor().DeferMainFrameUpdate());
+ EXPECT_TRUE(GetFontPreloadManager().HasPendingRenderBlockingFonts());
+ EXPECT_EQ(State::kLoading, GetState());
+
+ GetFontPreloadManager().FontPreloadingDelaysRenderingTimerFired(nullptr);
+
+ // Font preloading no longer blocks renderings after the timeout fires.
+ // However, rendering is still blocked, as we don't have BODY yet.
+ EXPECT_TRUE(Compositor().DeferMainFrameUpdate());
+ EXPECT_FALSE(GetFontPreloadManager().HasPendingRenderBlockingFonts());
+ EXPECT_EQ(State::kUnblocked, GetState());
+
+ main_resource.Complete("</head><body>some text</body>");
+
+ // Rendering starts after BODY has arrived.
+ EXPECT_FALSE(Compositor().DeferMainFrameUpdate());
+ EXPECT_FALSE(GetFontPreloadManager().HasPendingRenderBlockingFonts());
+ EXPECT_EQ(State::kUnblocked, GetState());
+
+ font_resource.Finish();
+}
+
+TEST_F(FontPreloadManagerTest, SlowFontTimeoutAfterBody) {
+ SimRequest main_resource("https://example.com", "text/html");
+ SimRequest font_resource("https://example.com/font.woff", "font/woff2");
+
+ LoadURL("https://example.com");
+ main_resource.Write(R"HTML(
+ <!doctype html>
+ <head>
+ <link rel="preload" as="font" type="font/woff2"
+ href="https://example.com/font.woff">
+ )HTML");
+
+ // Rendering is blocked due to ongoing font preloading.
+ EXPECT_TRUE(Compositor().DeferMainFrameUpdate());
+ EXPECT_TRUE(GetFontPreloadManager().HasPendingRenderBlockingFonts());
+ EXPECT_EQ(State::kLoading, GetState());
+
+ main_resource.Complete("</head><body>some text</body>");
+
+ // Rendering is still blocked by font, even if we already have BODY.
+ EXPECT_TRUE(Compositor().DeferMainFrameUpdate());
+ EXPECT_TRUE(GetFontPreloadManager().HasPendingRenderBlockingFonts());
+ EXPECT_EQ(State::kLoading, GetState());
+
+ GetFontPreloadManager().FontPreloadingDelaysRenderingTimerFired(nullptr);
+
+ // Rendering starts after we've waited for the font preloading long enough.
+ EXPECT_FALSE(Compositor().DeferMainFrameUpdate());
+ EXPECT_FALSE(GetFontPreloadManager().HasPendingRenderBlockingFonts());
+ EXPECT_EQ(State::kUnblocked, GetState());
+
+ font_resource.Finish();
+}
+
+// A trivial test case to verify test setup
+TEST_F(FontPreloadManagerTest, RegularWebFont) {
+ SimRequest main_resource("https://example.com", "text/html");
+ SimRequest 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");
+ }
+ #target {
+ font: 25px/1 custom-font, monospace;
+ }
+ </style>
+ <span id=target style="position:relative">0123456789</span>
+ )HTML");
+
+ // Now rendering has started, as there's no blocking resources.
+ EXPECT_FALSE(Compositor().DeferMainFrameUpdate());
+ EXPECT_EQ(State::kUnblocked, GetState());
+
+ font_resource.Complete(ReadAhemWoff2());
+
+ // Now everything is loaded. The web font should be used in rendering.
+ Compositor().BeginFrame().DrawCount();
+ EXPECT_EQ(250, GetTarget()->OffsetWidth());
+ EXPECT_FALSE(GetTargetFont().ShouldSkipDrawing());
+}
+
+TEST_F(FontPreloadManagerTest, OptionalFontWithoutPreloading) {
+ SimRequest main_resource("https://example.com", "text/html");
+ SimRequest 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-display: optional;
+ }
+ #target {
+ font: 25px/1 custom-font, monospace;
+ }
+ </style>
+ <span id=target>0123456789</span>
+ )HTML");
+
+ // Now rendering has started, as there's no blocking resources.
+ EXPECT_FALSE(Compositor().DeferMainFrameUpdate());
+ EXPECT_EQ(State::kUnblocked, GetState());
+
+ font_resource.Complete(ReadAhemWoff2());
+
+ // The 'optional' web font isn't used, as it didn't finish loading before
+ // rendering started. Text is rendered in visible fallback.
+ Compositor().BeginFrame().Contains(SimCanvas::kText);
+ EXPECT_GT(250, GetTarget()->OffsetWidth());
+ EXPECT_FALSE(GetTargetFont().ShouldSkipDrawing());
+}
+
+TEST_F(FontPreloadManagerTest, OptionalFontRemoveAndReadd) {
+ SimRequest main_resource("https://example.com", "text/html");
+ SimRequest 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-display: optional;
+ }
+ #target {
+ font: 25px/1 custom-font, monospace;
+ }
+ </style>
+ <span id=target>0123456789</span>
+ )HTML");
+
+ // Now rendering has started, as there's no blocking resources.
+ EXPECT_FALSE(Compositor().DeferMainFrameUpdate());
+ EXPECT_EQ(State::kUnblocked, GetState());
+
+ // The 'optional' web font isn't used, as it didn't finish loading before
+ // rendering started. Text is rendered in visible fallback.
+ Compositor().BeginFrame().Contains(SimCanvas::kText);
+ EXPECT_GT(250, GetTarget()->OffsetWidth());
+ EXPECT_FALSE(GetTargetFont().ShouldSkipDrawing());
+
+ font_resource.Complete(ReadAhemWoff2());
+
+ Element* style = GetDocument().QuerySelector("style");
+ style->remove();
+ GetDocument().head()->appendChild(style);
+
+ // After removing and readding the style sheet, we've created a new font face
+ // that got loaded immediately from the memory cache. So it can be used.
+ Compositor().BeginFrame().Contains(SimCanvas::kText);
+ EXPECT_EQ(250, GetTarget()->OffsetWidth());
+ EXPECT_FALSE(GetTargetFont().ShouldSkipDrawing());
+}
+
+TEST_F(FontPreloadManagerTest, OptionalFontSlowPreloading) {
+ SimRequest main_resource("https://example.com", "text/html");
+ SimRequest font_resource("https://example.com/Ahem.woff2", "font/woff2");
+
+ LoadURL("https://example.com");
+ main_resource.Complete(R"HTML(
+ <!doctype html>
+ <link rel="preload" as="font" type="font/woff2"
+ href="https://example.com/Ahem.woff2" crossorigin>
+ <style>
+ @font-face {
+ font-family: custom-font;
+ src: url(https://example.com/Ahem.woff2) format("woff2");
+ font-display: optional;
+ }
+ #target {
+ font: 25px/1 custom-font, monospace;
+ }
+ </style>
+ <span id=target>0123456789</span>
+ )HTML");
+
+ // Rendering is blocked due to font being preloaded.
+ EXPECT_TRUE(Compositor().DeferMainFrameUpdate());
+ EXPECT_TRUE(GetFontPreloadManager().HasPendingRenderBlockingFonts());
+ EXPECT_EQ(State::kLoading, GetState());
+
+ GetFontPreloadManager().FontPreloadingDelaysRenderingTimerFired(nullptr);
+
+ // Rendering is unblocked after the font preloading has timed out.
+ EXPECT_FALSE(Compositor().DeferMainFrameUpdate());
+ EXPECT_FALSE(GetFontPreloadManager().HasPendingRenderBlockingFonts());
+ EXPECT_EQ(State::kUnblocked, GetState());
+
+ // First frame renders text with visible fallback, as the 'optional' web font
+ // isn't loaded yet, and should be treated as in the failure period.
+ Compositor().BeginFrame();
+ EXPECT_GT(250, GetTarget()->OffsetWidth());
+ EXPECT_FALSE(GetTargetFont().ShouldSkipDrawing());
+
+ font_resource.Complete(ReadAhemWoff2());
+
+ // The 'optional' web font should not cause relayout even if it finishes
+ // loading now.
+ Compositor().BeginFrame();
+ EXPECT_GT(250, GetTarget()->OffsetWidth());
+ EXPECT_FALSE(GetTargetFont().ShouldSkipDrawing());
+}
+
+TEST_F(FontPreloadManagerTest, OptionalFontFastPreloading) {
+ SimRequest main_resource("https://example.com", "text/html");
+ SimRequest font_resource("https://example.com/Ahem.woff2", "font/woff2");
+
+ LoadURL("https://example.com");
+ main_resource.Complete(R"HTML(
+ <!doctype html>
+ <link rel="preload" as="font" type="font/woff2"
+ href="https://example.com/Ahem.woff2" crossorigin>
+ <style>
+ @font-face {
+ font-family: custom-font;
+ src: url(https://example.com/Ahem.woff2) format("woff2");
+ font-display: optional;
+ }
+ #target {
+ font: 25px/1 custom-font, monospace;
+ }
+ </style>
+ <span id=target>0123456789</span>
+ )HTML");
+
+ // Rendering is blocked due to font being preloaded.
+ EXPECT_TRUE(Compositor().DeferMainFrameUpdate());
+ EXPECT_TRUE(GetFontPreloadManager().HasPendingRenderBlockingFonts());
+ EXPECT_EQ(State::kLoading, GetState());
+
+ // There are test flakes due to FontPreloadManager timeout firing before the
+ // ResourceFinishObserver gets notified. So we disable the timeout.
+ DisableFontPreloadManagerTimeout();
+
+ font_resource.Complete(ReadAhemWoff2());
+ test::RunPendingTasks();
+
+ // Rendering is unblocked after the font is preloaded.
+ EXPECT_FALSE(Compositor().DeferMainFrameUpdate());
+ EXPECT_FALSE(GetFontPreloadManager().HasPendingRenderBlockingFonts());
+ EXPECT_EQ(State::kUnblocked, GetState());
+
+ // The 'optional' web font should be used in the first paint.
+ Compositor().BeginFrame();
+ EXPECT_EQ(250, GetTarget()->OffsetWidth());
+ EXPECT_FALSE(GetTargetFont().ShouldSkipDrawing());
+}
+
+TEST_F(FontPreloadManagerTest, OptionalFontSlowImperativeLoad) {
+ SimRequest main_resource("https://example.com", "text/html");
+ SimRequest 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-display: optional;
+ }
+ #target {
+ font: 25px/1 custom-font, monospace;
+ }
+ </style>
+ <script>
+ document.fonts.load('25px/1 custom-font');
+ </script>
+ <span id=target>0123456789</span>
+ )HTML");
+
+ // Rendering is blocked due to font being loaded via JavaScript API.
+ EXPECT_TRUE(Compositor().DeferMainFrameUpdate());
+ EXPECT_TRUE(GetFontPreloadManager().HasPendingRenderBlockingFonts());
+ EXPECT_EQ(State::kLoading, GetState());
+
+ GetFontPreloadManager().FontPreloadingDelaysRenderingTimerFired(nullptr);
+
+ // Rendering is unblocked after the font preloading has timed out.
+ EXPECT_FALSE(Compositor().DeferMainFrameUpdate());
+ EXPECT_FALSE(GetFontPreloadManager().HasPendingRenderBlockingFonts());
+ EXPECT_EQ(State::kUnblocked, GetState());
+
+ // First frame renders text with visible fallback, as the 'optional' web font
+ // isn't loaded yet, and should be treated as in the failure period.
+ Compositor().BeginFrame();
+ EXPECT_GT(250, GetTarget()->OffsetWidth());
+ EXPECT_FALSE(GetTargetFont().ShouldSkipDrawing());
+
+ font_resource.Complete(ReadAhemWoff2());
+
+ // The 'optional' web font should not cause relayout even if it finishes
+ // loading now.
+ Compositor().BeginFrame();
+ EXPECT_GT(250, GetTarget()->OffsetWidth());
+ EXPECT_FALSE(GetTargetFont().ShouldSkipDrawing());
+}
+
+TEST_F(FontPreloadManagerTest, OptionalFontFastImperativeLoad) {
+ SimRequest main_resource("https://example.com", "text/html");
+ SimRequest 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-display: optional;
+ }
+ #target {
+ font: 25px/1 custom-font, monospace;
+ }
+ </style>
+ <script>
+ document.fonts.load('25px/1 custom-font');
+ </script>
+ <span id=target>0123456789</span>
+ )HTML");
+
+ // Rendering is blocked due to font being preloaded.
+ EXPECT_TRUE(Compositor().DeferMainFrameUpdate());
+ EXPECT_TRUE(GetFontPreloadManager().HasPendingRenderBlockingFonts());
+ EXPECT_EQ(State::kLoading, GetState());
+
+ font_resource.Complete(ReadAhemWoff2());
+ test::RunPendingTasks();
+
+ // Rendering is unblocked after the font is preloaded.
+ EXPECT_FALSE(Compositor().DeferMainFrameUpdate());
+ EXPECT_FALSE(GetFontPreloadManager().HasPendingRenderBlockingFonts());
+ EXPECT_EQ(State::kUnblocked, GetState());
+
+ // The 'optional' web font should be used in the first paint.
+ Compositor().BeginFrame();
+ EXPECT_EQ(250, GetTarget()->OffsetWidth());
+ EXPECT_FALSE(GetTargetFont().ShouldSkipDrawing());
+}
+
+} // namespace blink
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 663013fcb61..8bd486a40f1 100644
--- a/chromium/third_party/blink/renderer/core/loader/form_submission.cc
+++ b/chromium/third_party/blink/renderer/core/loader/form_submission.cc
@@ -30,7 +30,8 @@
#include "third_party/blink/renderer/core/loader/form_submission.h"
-#include "third_party/blink/public/platform/web_insecure_request_policy.h"
+#include "third_party/blink/public/common/security_context/insecure_request_policy.h"
+#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/events/event.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -65,7 +66,7 @@ static void AppendMailtoPostFormDataToURL(KURL& url,
const String& encoding_type) {
String body = data.FlattenToString();
- if (DeprecatedEqualIgnoringCase(encoding_type, "text/plain")) {
+ if (EqualIgnoringASCIICase(encoding_type, "text/plain")) {
// Convention seems to be to decode, and s/&/\r\n/. Also, spaces are encoded
// as %20.
body = DecodeURLEscapeSequences(
@@ -93,9 +94,9 @@ void FormSubmission::Attributes::ParseAction(const String& action) {
}
AtomicString FormSubmission::Attributes::ParseEncodingType(const String& type) {
- if (DeprecatedEqualIgnoringCase(type, "multipart/form-data"))
+ if (EqualIgnoringASCIICase(type, "multipart/form-data"))
return AtomicString("multipart/form-data");
- if (DeprecatedEqualIgnoringCase(type, "text/plain"))
+ if (EqualIgnoringASCIICase(type, "text/plain"))
return AtomicString("text/plain");
return AtomicString("application/x-www-form-urlencoded");
}
@@ -107,9 +108,9 @@ void FormSubmission::Attributes::UpdateEncodingType(const String& type) {
FormSubmission::SubmitMethod FormSubmission::Attributes::ParseMethodType(
const String& type) {
- if (DeprecatedEqualIgnoringCase(type, "post"))
+ if (EqualIgnoringASCIICase(type, "post"))
return FormSubmission::kPostMethod;
- if (DeprecatedEqualIgnoringCase(type, "dialog"))
+ if (EqualIgnoringASCIICase(type, "dialog"))
return FormSubmission::kDialogMethod;
return FormSubmission::kGetMethod;
}
@@ -141,39 +142,41 @@ void FormSubmission::Attributes::CopyFrom(const Attributes& other) {
accept_charset_ = other.accept_charset_;
}
-inline FormSubmission::FormSubmission(SubmitMethod method,
- const KURL& action,
- const AtomicString& target,
- const AtomicString& content_type,
- HTMLFormElement* form,
- scoped_refptr<EncodedFormData> data,
- const String& boundary,
- Event* event)
+inline FormSubmission::FormSubmission(
+ SubmitMethod method,
+ const KURL& action,
+ const AtomicString& target,
+ const AtomicString& content_type,
+ HTMLFormElement* form,
+ scoped_refptr<EncodedFormData> data,
+ const Event* event,
+ NavigationPolicy navigation_policy,
+ TriggeringEventInfo triggering_event_info,
+ ClientNavigationReason reason,
+ std::unique_ptr<ResourceRequest> resource_request,
+ Frame* target_frame,
+ WebFrameLoadType load_type,
+ Document* origin_document)
: method_(method),
action_(action),
target_(target),
content_type_(content_type),
form_(form),
form_data_(std::move(data)),
- boundary_(boundary) {
- if (event) {
- triggering_event_info_ = event->isTrusted()
- ? TriggeringEventInfo::kFromTrustedEvent
- : TriggeringEventInfo::kFromUntrustedEvent;
- if (event->UnderlyingEvent())
- event = event->UnderlyingEvent();
- } else {
- triggering_event_info_ = TriggeringEventInfo::kNotFromEvent;
- }
- navigation_policy_ = NavigationPolicyFromEvent(event);
-}
+ navigation_policy_(navigation_policy),
+ triggering_event_info_(triggering_event_info),
+ reason_(reason),
+ resource_request_(std::move(resource_request)),
+ target_frame_(target_frame),
+ load_type_(load_type),
+ origin_document_(origin_document) {}
inline FormSubmission::FormSubmission(const String& result)
: method_(kDialogMethod), result_(result) {}
FormSubmission* FormSubmission::Create(HTMLFormElement* form,
const Attributes& attributes,
- Event* event,
+ const Event* event,
HTMLFormControlElement* submit_button) {
DCHECK(form);
@@ -212,7 +215,9 @@ FormSubmission* FormSubmission::Create(HTMLFormElement* form,
? document.Url().GetString()
: copied_attributes.Action());
- if (document.GetInsecureRequestPolicy() & kUpgradeInsecureRequests &&
+ if ((document.GetSecurityContext().GetInsecureRequestPolicy() &
+ mojom::blink::InsecureRequestPolicy::kUpgradeInsecureRequests) !=
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone &&
action_url.ProtocolIs("http") &&
!SecurityOrigin::Create(action_url)->IsPotentiallyTrustworthy()) {
UseCounter::Count(document,
@@ -265,59 +270,89 @@ FormSubmission* FormSubmission::Create(HTMLFormElement* form,
AtomicString target_or_base_target = copied_attributes.Target().IsEmpty()
? document.BaseTarget()
: copied_attributes.Target();
- return MakeGarbageCollected<FormSubmission>(
- copied_attributes.Method(), action_url, target_or_base_target,
- encoding_type, form, std::move(form_data), boundary, event);
-}
-
-void FormSubmission::Trace(blink::Visitor* visitor) {
- visitor->Trace(form_);
-}
-
-KURL FormSubmission::RequestURL() const {
- if (method_ == FormSubmission::kPostMethod ||
- action_.ProtocolIsJavaScript()) {
- return action_;
- }
- KURL request_url(action_);
- request_url.SetQuery(form_data_->FlattenToString());
- return request_url;
-}
-
-void FormSubmission::Navigate() {
- ResourceRequest resource_request(RequestURL());
+ std::unique_ptr<ResourceRequest> resource_request =
+ std::make_unique<ResourceRequest>(action_url);
ClientNavigationReason reason = ClientNavigationReason::kFormSubmissionGet;
- if (method_ == FormSubmission::kPostMethod) {
+ if (copied_attributes.Method() == FormSubmission::kPostMethod) {
reason = ClientNavigationReason::kFormSubmissionPost;
- resource_request.SetHttpMethod(http_names::kPOST);
- resource_request.SetHttpBody(form_data_);
+ resource_request->SetHttpMethod(http_names::kPOST);
+ resource_request->SetHttpBody(form_data);
// construct some user headers if necessary
- if (boundary_.IsEmpty()) {
- resource_request.SetHTTPContentType(content_type_);
+ if (boundary.IsEmpty()) {
+ resource_request->SetHTTPContentType(encoding_type);
} else {
- resource_request.SetHTTPContentType(content_type_ +
- "; boundary=" + boundary_);
+ resource_request->SetHTTPContentType(encoding_type +
+ "; boundary=" + boundary);
}
}
- resource_request.SetHasUserGesture(
- LocalFrame::HasTransientUserActivation(form_->GetDocument().GetFrame()));
+ resource_request->SetHasUserGesture(
+ LocalFrame::HasTransientUserActivation(form->GetDocument().GetFrame()));
- FrameLoadRequest frame_request(&form_->GetDocument(), resource_request);
- frame_request.SetNavigationPolicy(navigation_policy_);
- frame_request.SetClientRedirectReason(reason);
- frame_request.SetForm(form_);
- frame_request.SetTriggeringEventInfo(triggering_event_info_);
+ TriggeringEventInfo triggering_event_info;
+ if (event) {
+ triggering_event_info = event->isTrusted()
+ ? TriggeringEventInfo::kFromTrustedEvent
+ : TriggeringEventInfo::kFromUntrustedEvent;
+ if (event->UnderlyingEvent())
+ event = event->UnderlyingEvent();
+ } else {
+ triggering_event_info = TriggeringEventInfo::kNotFromEvent;
+ }
+ FrameLoadRequest frame_request(&form->GetDocument(), *resource_request);
+ frame_request.SetNavigationPolicy(NavigationPolicyFromEvent(event));
+ frame_request.SetClientRedirectReason(reason);
+ frame_request.SetForm(form);
+ frame_request.SetTriggeringEventInfo(triggering_event_info);
Frame* target_frame =
- form_->GetDocument()
+ form->GetDocument()
.GetFrame()
->Tree()
- .FindOrCreateFrameForNavigation(frame_request, target_)
+ .FindOrCreateFrameForNavigation(frame_request, target_or_base_target)
.frame;
- if (target_frame)
- target_frame->Navigate(frame_request, WebFrameLoadType::kStandard);
+
+ WebFrameLoadType load_type = WebFrameLoadType::kStandard;
+ LocalFrame* target_local_frame = DynamicTo<LocalFrame>(target_frame);
+ if (target_local_frame &&
+ !target_local_frame->GetDocument()->LoadEventFinished() &&
+ !LocalFrame::HasTransientUserActivation(target_local_frame))
+ load_type = WebFrameLoadType::kReplaceCurrentItem;
+
+ return MakeGarbageCollected<FormSubmission>(
+ copied_attributes.Method(), action_url, target_or_base_target,
+ encoding_type, form, std::move(form_data), event,
+ frame_request.GetNavigationPolicy(), triggering_event_info, reason,
+ std::move(resource_request), target_frame, load_type,
+ frame_request.OriginDocument());
+}
+
+void FormSubmission::Trace(Visitor* visitor) {
+ visitor->Trace(form_);
+ visitor->Trace(target_frame_);
+ visitor->Trace(origin_document_);
+}
+
+void FormSubmission::Navigate() {
+ KURL request_url = action_;
+ if (method_ != FormSubmission::kPostMethod &&
+ !action_.ProtocolIsJavaScript()) {
+ request_url.SetQuery(form_data_->FlattenToString());
+ }
+ resource_request_->SetUrl(request_url);
+
+ FrameLoadRequest frame_request(origin_document_.Get(), *resource_request_);
+ frame_request.SetNavigationPolicy(navigation_policy_);
+ frame_request.SetClientRedirectReason(reason_);
+ frame_request.SetForm(form_);
+ frame_request.SetTriggeringEventInfo(triggering_event_info_);
+
+ if (target_frame_ && !target_frame_->GetPage())
+ return;
+
+ if (target_frame_)
+ target_frame_->Navigate(frame_request, load_type_);
}
} // namespace blink
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 7e4465a22cf..0153ff0ba5b 100644
--- a/chromium/third_party/blink/renderer/core/loader/form_submission.h
+++ b/chromium/third_party/blink/renderer/core/loader/form_submission.h
@@ -33,6 +33,7 @@
#include "base/macros.h"
#include "third_party/blink/public/common/navigation/triggering_event_info.h"
+#include "third_party/blink/public/web/web_frame_load_type.h"
#include "third_party/blink/renderer/core/loader/frame_load_request.h"
#include "third_party/blink/renderer/core/loader/navigation_policy.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -44,6 +45,7 @@ namespace blink {
class EncodedFormData;
class Event;
+class Frame;
class HTMLFormControlElement;
class HTMLFormElement;
@@ -95,7 +97,7 @@ class FormSubmission final : public GarbageCollected<FormSubmission> {
static FormSubmission* Create(HTMLFormElement*,
const Attributes&,
- Event*,
+ const Event*,
HTMLFormControlElement* submit_button);
FormSubmission(SubmitMethod,
@@ -104,12 +106,18 @@ class FormSubmission final : public GarbageCollected<FormSubmission> {
const AtomicString& content_type,
HTMLFormElement*,
scoped_refptr<EncodedFormData>,
- const String& boundary,
- Event*);
+ const Event*,
+ NavigationPolicy navigation_policy,
+ TriggeringEventInfo triggering_event_info,
+ ClientNavigationReason reason,
+ std::unique_ptr<ResourceRequest> resource_request,
+ Frame* target_frame,
+ WebFrameLoadType load_type,
+ Document* origin_document);
// FormSubmission for DialogMethod
explicit FormSubmission(const String& result);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
void Navigate();
@@ -122,6 +130,8 @@ class FormSubmission final : public GarbageCollected<FormSubmission> {
const String& Result() const { return result_; }
+ Frame* TargetFrame() const { return target_frame_; }
+
private:
// FIXME: Hold an instance of Attributes instead of individual members.
SubmitMethod method_;
@@ -130,10 +140,14 @@ class FormSubmission final : public GarbageCollected<FormSubmission> {
AtomicString content_type_;
Member<HTMLFormElement> form_;
scoped_refptr<EncodedFormData> form_data_;
- String boundary_;
NavigationPolicy navigation_policy_;
TriggeringEventInfo triggering_event_info_;
String result_;
+ ClientNavigationReason reason_;
+ std::unique_ptr<ResourceRequest> resource_request_;
+ Member<Frame> target_frame_;
+ WebFrameLoadType load_type_;
+ Member<Document> origin_document_;
};
} // namespace blink
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 747a216a644..4da8cf1c591 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
@@ -36,16 +36,19 @@
#include "base/feature_list.h"
#include "base/optional.h"
#include "build/build_config.h"
+#include "mojo/public/cpp/bindings/associated_remote.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/client_hints/client_hints.h"
#include "third_party/blink/public/common/device_memory/approximated_device_memory.h"
+#include "third_party/blink/public/mojom/conversions/conversions.mojom-blink.h"
#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/mojom/loader/request_context_frame_type.mojom-blink.h"
+#include "third_party/blink/public/mojom/web_client_hints/web_client_hints_types.mojom-blink.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h"
#include "third_party/blink/public/platform/scheduler/web_scoped_virtual_time_pauser.h"
#include "third_party/blink/public/platform/web_content_settings_client.h"
#include "third_party/blink/public/platform/web_effective_connection_type.h"
-#include "third_party/blink/public/platform/web_insecure_request_policy.h"
#include "third_party/blink/public/platform/websocket_handshake_throttle.h"
#include "third_party/blink/public/web/web_frame.h"
#include "third_party/blink/public/web/web_local_frame.h"
@@ -87,9 +90,10 @@
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/core/timing/performance.h"
#include "third_party/blink/renderer/core/timing/window_performance.h"
+#include "third_party/blink/renderer/core/url/url_search_params.h"
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
#include "third_party/blink/renderer/platform/exported/wrapped_resource_request.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.h"
@@ -184,6 +188,24 @@ mojom::FetchCacheMode DetermineFrameCacheMode(Frame* frame) {
}
// Simple function to add quotes to make headers strings.
+const AtomicString AddBrandVersionQuotes(const std::string& brand,
+ const std::string& version) {
+ if (brand.empty())
+ return AtomicString("");
+
+ StringBuilder quoted_string;
+ quoted_string.Append("\"");
+ quoted_string.Append(brand.data());
+ quoted_string.Append("\"");
+ if (!version.empty()) {
+ quoted_string.Append(";v=\"");
+ quoted_string.Append(version.data());
+ quoted_string.Append("\"");
+ }
+ return quoted_string.ToAtomicString();
+}
+
+// Simple function to add quotes to make headers strings.
const AtomicString AddQuotes(std::string str) {
if (str.empty())
return AtomicString("");
@@ -201,17 +223,17 @@ struct FrameFetchContext::FrozenState final : GarbageCollected<FrozenState> {
FrozenState(const KURL& url,
scoped_refptr<const SecurityOrigin> parent_security_origin,
const ContentSecurityPolicy* content_security_policy,
- KURL site_for_cookies,
+ net::SiteForCookies site_for_cookies,
scoped_refptr<const SecurityOrigin> top_frame_origin,
const ClientHintsPreferences& client_hints_preferences,
float device_pixel_ratio,
const String& user_agent,
- const UserAgentMetadata& user_agent_metadata,
+ const base::Optional<UserAgentMetadata>& user_agent_metadata,
bool is_svg_image_chrome_client)
: url(url),
parent_security_origin(std::move(parent_security_origin)),
content_security_policy(content_security_policy),
- site_for_cookies(site_for_cookies),
+ site_for_cookies(std::move(site_for_cookies)),
top_frame_origin(std::move(top_frame_origin)),
client_hints_preferences(client_hints_preferences),
device_pixel_ratio(device_pixel_ratio),
@@ -222,17 +244,15 @@ struct FrameFetchContext::FrozenState final : GarbageCollected<FrozenState> {
const KURL url;
const scoped_refptr<const SecurityOrigin> parent_security_origin;
const Member<const ContentSecurityPolicy> content_security_policy;
- const KURL site_for_cookies;
+ const net::SiteForCookies site_for_cookies;
const scoped_refptr<const SecurityOrigin> top_frame_origin;
const ClientHintsPreferences client_hints_preferences;
const float device_pixel_ratio;
const String user_agent;
- const UserAgentMetadata user_agent_metadata;
+ const base::Optional<UserAgentMetadata> user_agent_metadata;
const bool is_svg_image_chrome_client;
- void Trace(blink::Visitor* visitor) {
- visitor->Trace(content_security_policy);
- }
+ void Trace(Visitor* visitor) { visitor->Trace(content_security_policy); }
};
ResourceFetcher* FrameFetchContext::CreateFetcherForCommittedDocument(
@@ -251,8 +271,8 @@ ResourceFetcher* FrameFetchContext::CreateFetcherForCommittedDocument(
frame.GetTaskRunner(TaskType::kNetworking),
MakeGarbageCollected<LoaderFactoryForFrame>(frame_or_imported_document));
init.use_counter = MakeGarbageCollected<DetachableUseCounter>(&document);
- init.console_logger =
- MakeGarbageCollected<DetachableConsoleLogger>(&document);
+ init.console_logger = MakeGarbageCollected<DetachableConsoleLogger>(
+ document.GetExecutionContext());
// Frame loading should normally start with |kTight| throttling, as the
// frame will be in layout-blocking state until the <body> tag is inserted
init.initial_throttling_policy =
@@ -287,7 +307,8 @@ ResourceFetcher* FrameFetchContext::CreateFetcherForImportedDocument(
document->GetTaskRunner(blink::TaskType::kNetworking),
MakeGarbageCollected<LoaderFactoryForFrame>(frame_or_imported_document));
init.use_counter = MakeGarbageCollected<DetachableUseCounter>(document);
- init.console_logger = MakeGarbageCollected<DetachableConsoleLogger>(document);
+ init.console_logger = MakeGarbageCollected<DetachableConsoleLogger>(
+ document->GetExecutionContext());
init.frame_scheduler = frame.GetFrameScheduler();
auto* fetcher = MakeGarbageCollected<ResourceFetcher>(init);
fetcher->SetResourceLoadObserver(
@@ -305,7 +326,7 @@ FrameFetchContext::FrameFetchContext(
GetNetworkStateNotifier().SaveDataEnabled() &&
!GetFrame()->GetSettings()->GetDataSaverHoldbackWebApi()) {}
-KURL FrameFetchContext::GetSiteForCookies() const {
+net::SiteForCookies FrameFetchContext::GetSiteForCookies() const {
if (GetResourceFetcherProperties().IsDetached())
return frozen_state_->site_for_cookies;
return frame_or_imported_document_->GetDocument().SiteForCookies();
@@ -388,11 +409,6 @@ mojom::FetchCacheMode FrameFetchContext::ResourceRequestCachePolicy(
return cache_mode;
}
-DocumentLoader* FrameFetchContext::GetDocumentLoader() const {
- DCHECK(!GetResourceFetcherProperties().IsDetached());
- return frame_or_imported_document_->GetDocumentLoader();
-}
-
inline DocumentLoader* FrameFetchContext::MasterDocumentLoader() const {
DCHECK(!GetResourceFetcherProperties().IsDetached());
return &frame_or_imported_document_->GetMasterDocumentLoader();
@@ -495,7 +511,7 @@ void FrameFetchContext::ModifyRequestForCSP(ResourceRequest& resource_request) {
resource_request,
&GetResourceFetcherProperties().GetFetchClientSettingsObject(),
&frame_or_imported_document_->GetDocument(),
- network::mojom::RequestContextFrameType::kNone);
+ mojom::RequestContextFrameType::kNone);
}
void FrameFetchContext::AddClientHintsIfNecessary(
@@ -518,43 +534,43 @@ void FrameFetchContext::AddClientHintsIfNecessary(
// policy is used to enable hints for all subresources, based on the policy of
// the requesting document, and the origin of the resource.
const FeaturePolicy* policy = nullptr;
- if (frame_or_imported_document_)
- policy = frame_or_imported_document_->GetDocument().GetFeaturePolicy();
- url::Origin resource_origin =
- SecurityOrigin::Create(request.Url())->ToUrlOrigin();
+ if (frame_or_imported_document_) {
+ policy = frame_or_imported_document_->GetDocument()
+ .GetSecurityContext()
+ .GetFeaturePolicy();
+ }
// Sec-CH-UA is special: we always send the header to all origins that are
- // eligible for client hints (e.g. secure transport, JavaScript enabled). We
- // alter the header's value based on whether or not the site has opted into
- // additional detail.
+ // eligible for client hints (e.g. secure transport, JavaScript enabled).
//
// https://github.com/WICG/ua-client-hints
- blink::UserAgentMetadata ua = GetUserAgentMetadata();
- bool use_full_ua =
- (RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() ||
- (policy &&
- policy->IsFeatureEnabledForOrigin(
- mojom::FeaturePolicyFeature::kClientHintUA, resource_origin))) &&
- ShouldSendClientHint(mojom::WebClientHintsType::kUA, hints_preferences,
- enabled_hints);
- if (RuntimeEnabledFeatures::UserAgentClientHintEnabled()) {
- StringBuilder result;
- result.Append(ua.brand.data());
- const auto& version = use_full_ua ? ua.full_version : ua.major_version;
- if (!version.empty()) {
- result.Append(' ');
- result.Append(version.data());
- }
+ //
+ // One exception, however, is that a custom UA is sometimes set without
+ // specifying accomponying client hints, in which case we disable sending
+ // them.
+ base::Optional<UserAgentMetadata> ua = GetUserAgentMetadata();
+ if (RuntimeEnabledFeatures::UserAgentClientHintEnabled() && ua.has_value()) {
request.SetHttpHeaderField(
blink::kClientHintsHeaderMapping[static_cast<size_t>(
- mojom::WebClientHintsType::kUA)],
- AddQuotes(result.ToString().Ascii()));
+ mojom::blink::WebClientHintsType::kUA)],
+ AddBrandVersionQuotes(ua->brand, ua->major_version));
+
+ // We also send Sec-CH-UA-Mobile to all hints. It is a one-bit header
+ // identifying if the browser has opted for a "mobile" experience
+ // Formatted using the "sh-boolean" format from:
+ // https://httpwg.org/http-extensions/draft-ietf-httpbis-header-structure.html#boolean
+ request.SetHttpHeaderField(
+ blink::kClientHintsHeaderMapping[static_cast<size_t>(
+ mojom::blink::WebClientHintsType::kUAMobile)],
+ ua->mobile ? "?1" : "?0");
}
// If the frame is detached, then don't send any hints other than UA.
if (!policy)
return;
+ url::Origin resource_origin =
+ SecurityOrigin::Create(request.Url())->ToUrlOrigin();
bool is_1p_origin = IsFirstPartyOrigin(request.Url());
if (!RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() &&
@@ -570,19 +586,13 @@ void FrameFetchContext::AddClientHintsIfNecessary(
&enabled_hints);
}
- // TODO(iclelland): If feature policy control over client hints ships, remove
- // the runtime flag check for the next four hints. Currently, when the
- // kAllowClientHintsToThirdParty feature is enabled, but the runtime flag is
- // *not* set, the behaviour is that these four hints will be sent on all
- // eligible requests. Feature policy control is intended to change that
- // default.
-
- if ((!RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() ||
- policy->IsFeatureEnabledForOrigin(
- mojom::FeaturePolicyFeature::kClientHintDeviceMemory,
- resource_origin)) &&
- ShouldSendClientHint(mojom::WebClientHintsType::kDeviceMemory,
- hints_preferences, enabled_hints)) {
+ // The next 4 hints should be enabled if we're allowing legacy hints to third
+ // parties, or if FeaturePolicy delegation says they are allowed.
+ if (ShouldSendClientHint(
+ ClientHintsMode::kLegacy, policy, resource_origin, is_1p_origin,
+ mojom::blink::WebClientHintsType::kDeviceMemory,
+ mojom::blink::FeaturePolicyFeature::kClientHintDeviceMemory,
+ hints_preferences, enabled_hints)) {
request.SetHttpHeaderField(
"Device-Memory",
AtomicString(String::Number(
@@ -590,18 +600,28 @@ void FrameFetchContext::AddClientHintsIfNecessary(
}
float dpr = GetDevicePixelRatio();
- if ((!RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() ||
- policy->IsFeatureEnabledForOrigin(
- mojom::FeaturePolicyFeature::kClientHintDPR, resource_origin)) &&
- ShouldSendClientHint(mojom::WebClientHintsType::kDpr, hints_preferences,
- enabled_hints)) {
+ if (ShouldSendClientHint(ClientHintsMode::kLegacy, policy, resource_origin,
+ is_1p_origin, mojom::blink::WebClientHintsType::kDpr,
+ mojom::blink::FeaturePolicyFeature::kClientHintDPR,
+ hints_preferences, enabled_hints)) {
request.SetHttpHeaderField("DPR", AtomicString(String::Number(dpr)));
}
- if ((!RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() ||
- policy->IsFeatureEnabledForOrigin(
- mojom::FeaturePolicyFeature::kClientHintWidth, resource_origin)) &&
- ShouldSendClientHint(mojom::WebClientHintsType::kResourceWidth,
+ if (ShouldSendClientHint(
+ ClientHintsMode::kLegacy, policy, resource_origin, is_1p_origin,
+ mojom::blink::WebClientHintsType::kViewportWidth,
+ mojom::blink::FeaturePolicyFeature::kClientHintViewportWidth,
+ hints_preferences, enabled_hints) &&
+ !GetResourceFetcherProperties().IsDetached() && GetFrame()->View()) {
+ request.SetHttpHeaderField(
+ "Viewport-Width",
+ AtomicString(String::Number(GetFrame()->View()->ViewportWidth())));
+ }
+
+ if (ShouldSendClientHint(ClientHintsMode::kLegacy, policy, resource_origin,
+ is_1p_origin,
+ mojom::blink::WebClientHintsType::kResourceWidth,
+ mojom::blink::FeaturePolicyFeature::kClientHintWidth,
hints_preferences, enabled_hints)) {
if (resource_width.is_set) {
float physical_width = resource_width.width * dpr;
@@ -610,40 +630,10 @@ void FrameFetchContext::AddClientHintsIfNecessary(
}
}
- if ((!RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() ||
- policy->IsFeatureEnabledForOrigin(
- mojom::FeaturePolicyFeature::kClientHintViewportWidth,
- resource_origin)) &&
- ShouldSendClientHint(mojom::WebClientHintsType::kViewportWidth,
- hints_preferences, enabled_hints) &&
- !GetResourceFetcherProperties().IsDetached() && GetFrame()->View()) {
- request.SetHttpHeaderField(
- "Viewport-Width",
- AtomicString(String::Number(GetFrame()->View()->ViewportWidth())));
- }
-
- // TODO(iclelland): If feature policy control over client hints ships, remove
- // the runtime flag check and the 1p origin requirement for the remaining
- // hints. Currently, even when the kAllowClientHintsToThirdParty feature is
- // (and the runtime flag is *not* set,) these hints are only sent for first-
- // party requests. With feature policy control, these can be sent to third
- // parties as well, if correctly delegated.
-
- // Note that if both the kAllowClientHintsToThirdParty feature and the runtime
- // flag are disabled, this code will not be reached.
-
- // True if this is a first-party resource request, and feature policy for
- // client hints is *not* in use.
- bool can_always_send_hints =
- is_1p_origin &&
- !RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled();
-
- if ((can_always_send_hints ||
- (RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() &&
- policy->IsFeatureEnabledForOrigin(
- mojom::FeaturePolicyFeature::kClientHintRTT, resource_origin))) &&
- ShouldSendClientHint(mojom::WebClientHintsType::kRtt, hints_preferences,
- enabled_hints)) {
+ if (ShouldSendClientHint(ClientHintsMode::kStandard, policy, resource_origin,
+ is_1p_origin, mojom::blink::WebClientHintsType::kRtt,
+ mojom::blink::FeaturePolicyFeature::kClientHintRTT,
+ hints_preferences, enabled_hints)) {
base::Optional<base::TimeDelta> http_rtt =
GetNetworkStateNotifier().GetWebHoldbackHttpRtt();
if (!http_rtt) {
@@ -654,17 +644,15 @@ void FrameFetchContext::AddClientHintsIfNecessary(
GetNetworkStateNotifier().RoundRtt(request.Url().Host(), http_rtt);
request.SetHttpHeaderField(
blink::kClientHintsHeaderMapping[static_cast<size_t>(
- mojom::WebClientHintsType::kRtt)],
+ mojom::blink::WebClientHintsType::kRtt)],
AtomicString(String::Number(rtt)));
}
- if ((can_always_send_hints ||
- (RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() &&
- policy->IsFeatureEnabledForOrigin(
- mojom::FeaturePolicyFeature::kClientHintDownlink,
- resource_origin))) &&
- ShouldSendClientHint(mojom::WebClientHintsType::kDownlink,
- hints_preferences, enabled_hints)) {
+ if (ShouldSendClientHint(
+ ClientHintsMode::kStandard, policy, resource_origin, is_1p_origin,
+ mojom::blink::WebClientHintsType::kDownlink,
+ mojom::blink::FeaturePolicyFeature::kClientHintDownlink,
+ hints_preferences, enabled_hints)) {
base::Optional<double> throughput_mbps =
GetNetworkStateNotifier().GetWebHoldbackDownlinkThroughputMbps();
if (!throughput_mbps) {
@@ -675,16 +663,14 @@ void FrameFetchContext::AddClientHintsIfNecessary(
throughput_mbps);
request.SetHttpHeaderField(
blink::kClientHintsHeaderMapping[static_cast<size_t>(
- mojom::WebClientHintsType::kDownlink)],
+ mojom::blink::WebClientHintsType::kDownlink)],
AtomicString(String::Number(mbps)));
}
- if ((can_always_send_hints ||
- (RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() &&
- policy->IsFeatureEnabledForOrigin(
- mojom::FeaturePolicyFeature::kClientHintECT, resource_origin))) &&
- ShouldSendClientHint(mojom::WebClientHintsType::kEct, hints_preferences,
- enabled_hints)) {
+ if (ShouldSendClientHint(ClientHintsMode::kStandard, policy, resource_origin,
+ is_1p_origin, mojom::blink::WebClientHintsType::kEct,
+ mojom::blink::FeaturePolicyFeature::kClientHintECT,
+ hints_preferences, enabled_hints)) {
base::Optional<WebEffectiveConnectionType> holdback_ect =
GetNetworkStateNotifier().GetWebHoldbackEffectiveType();
if (!holdback_ect)
@@ -692,63 +678,71 @@ void FrameFetchContext::AddClientHintsIfNecessary(
request.SetHttpHeaderField(
blink::kClientHintsHeaderMapping[static_cast<size_t>(
- mojom::WebClientHintsType::kEct)],
+ mojom::blink::WebClientHintsType::kEct)],
AtomicString(NetworkStateNotifier::EffectiveConnectionTypeToString(
holdback_ect.value())));
}
- if ((can_always_send_hints ||
- (RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() &&
- policy->IsFeatureEnabledForOrigin(
- mojom::FeaturePolicyFeature::kClientHintLang, resource_origin))) &&
- ShouldSendClientHint(mojom::WebClientHintsType::kLang, hints_preferences,
- enabled_hints)) {
+ if (ShouldSendClientHint(ClientHintsMode::kStandard, policy, resource_origin,
+ is_1p_origin,
+ mojom::blink::WebClientHintsType::kLang,
+ mojom::blink::FeaturePolicyFeature::kClientHintLang,
+ hints_preferences, enabled_hints)) {
request.SetHttpHeaderField(
blink::kClientHintsHeaderMapping[static_cast<size_t>(
- mojom::WebClientHintsType::kLang)],
+ mojom::blink::WebClientHintsType::kLang)],
GetFrame()
->DomWindow()
->navigator()
->SerializeLanguagesForClientHintHeader());
}
- if ((can_always_send_hints ||
- (RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() &&
- policy->IsFeatureEnabledForOrigin(
- mojom::FeaturePolicyFeature::kClientHintUAArch,
- resource_origin))) &&
- ShouldSendClientHint(mojom::WebClientHintsType::kUAArch,
- hints_preferences, enabled_hints)) {
+ if (ua.has_value() &&
+ ShouldSendClientHint(
+ ClientHintsMode::kStandard, policy, resource_origin, is_1p_origin,
+ mojom::blink::WebClientHintsType::kUAArch,
+ mojom::blink::FeaturePolicyFeature::kClientHintUAArch,
+ hints_preferences, enabled_hints)) {
request.SetHttpHeaderField(
blink::kClientHintsHeaderMapping[static_cast<size_t>(
- mojom::WebClientHintsType::kUAArch)],
- AddQuotes(ua.architecture));
+ mojom::blink::WebClientHintsType::kUAArch)],
+ AddQuotes(ua->architecture));
}
- if ((can_always_send_hints ||
- (RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() &&
- policy->IsFeatureEnabledForOrigin(
- mojom::FeaturePolicyFeature::kClientHintUAPlatform,
- resource_origin))) &&
- ShouldSendClientHint(mojom::WebClientHintsType::kUAPlatform,
- hints_preferences, enabled_hints)) {
+ if (ua.has_value() &&
+ ShouldSendClientHint(
+ ClientHintsMode::kStandard, policy, resource_origin, is_1p_origin,
+ mojom::blink::WebClientHintsType::kUAPlatform,
+ mojom::blink::FeaturePolicyFeature::kClientHintUAPlatform,
+ hints_preferences, enabled_hints)) {
request.SetHttpHeaderField(
blink::kClientHintsHeaderMapping[static_cast<size_t>(
- mojom::WebClientHintsType::kUAPlatform)],
- AddQuotes(ua.platform));
+ mojom::blink::WebClientHintsType::kUAPlatform)],
+ AddBrandVersionQuotes(ua->platform, ua->platform_version));
}
- if ((can_always_send_hints ||
- (RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled() &&
- policy->IsFeatureEnabledForOrigin(
- mojom::FeaturePolicyFeature::kClientHintUAModel,
- resource_origin))) &&
- ShouldSendClientHint(mojom::WebClientHintsType::kUAModel,
- hints_preferences, enabled_hints)) {
+ if (ua.has_value() &&
+ ShouldSendClientHint(
+ ClientHintsMode::kStandard, policy, resource_origin, is_1p_origin,
+ mojom::blink::WebClientHintsType::kUAModel,
+ mojom::blink::FeaturePolicyFeature::kClientHintUAModel,
+ hints_preferences, enabled_hints)) {
request.SetHttpHeaderField(
blink::kClientHintsHeaderMapping[static_cast<size_t>(
- mojom::WebClientHintsType::kUAModel)],
- AddQuotes(ua.model));
+ mojom::blink::WebClientHintsType::kUAModel)],
+ AddQuotes(ua->model));
+ }
+
+ if (ua.has_value() &&
+ ShouldSendClientHint(
+ ClientHintsMode::kStandard, policy, resource_origin, is_1p_origin,
+ mojom::blink::WebClientHintsType::kUAFullVersion,
+ mojom::blink::FeaturePolicyFeature::kClientHintUAFullVersion,
+ hints_preferences, enabled_hints)) {
+ request.SetHttpHeaderField(
+ blink::kClientHintsHeaderMapping[static_cast<size_t>(
+ mojom::blink::WebClientHintsType::kUAFullVersion)],
+ AddQuotes(ua->full_version));
}
}
@@ -772,7 +766,7 @@ void FrameFetchContext::SetFirstPartyCookie(ResourceRequest& request) {
// Set the first party for cookies url if it has not been set yet (new
// requests). This value will be updated during redirects, consistent with
// https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00#section-2.1.1?
- if (request.SiteForCookies().IsNull())
+ if (!request.SiteForCookiesSet())
request.SetSiteForCookies(GetSiteForCookies());
}
@@ -831,7 +825,7 @@ bool FrameFetchContext::ShouldBypassMainWorldCSP() const {
return false;
return ContentSecurityPolicy::ShouldBypassMainWorld(
- GetFrame()->GetDocument());
+ GetFrame()->GetDocument()->ToExecutionContext());
}
bool FrameFetchContext::IsSVGImageChromeClient() const {
@@ -882,13 +876,13 @@ bool FrameFetchContext::ShouldBlockFetchByMixedContentCheck(
mojom::RequestContextType request_context,
ResourceRequest::RedirectStatus redirect_status,
const KURL& url,
- SecurityViolationReportingPolicy reporting_policy) const {
+ ReportingDisposition reporting_disposition) const {
if (GetResourceFetcherProperties().IsDetached()) {
// TODO(yhirano): Implement the detached case.
return false;
}
return MixedContentChecker::ShouldBlockFetch(
- GetFrame(), request_context, redirect_status, url, reporting_policy);
+ GetFrame(), request_context, redirect_status, url, reporting_disposition);
}
bool FrameFetchContext::ShouldBlockFetchAsCredentialedSubresource(
@@ -976,7 +970,8 @@ String FrameFetchContext::GetUserAgent() const {
return GetFrame()->Loader().UserAgent();
}
-UserAgentMetadata FrameFetchContext::GetUserAgentMetadata() const {
+base::Optional<UserAgentMetadata> FrameFetchContext::GetUserAgentMetadata()
+ const {
if (GetResourceFetcherProperties().IsDetached())
return frozen_state_->user_agent_metadata;
return GetLocalFrameClient()->UserAgentMetadata();
@@ -997,9 +992,33 @@ float FrameFetchContext::GetDevicePixelRatio() const {
}
bool FrameFetchContext::ShouldSendClientHint(
- mojom::WebClientHintsType type,
+ ClientHintsMode mode,
+ const FeaturePolicy* policy,
+ const url::Origin& resource_origin,
+ bool is_1p_origin,
+ mojom::blink::WebClientHintsType type,
+ mojom::blink::FeaturePolicyFeature feature_policy_feature,
const ClientHintsPreferences& hints_preferences,
const WebEnabledClientHints& enabled_hints) const {
+ bool origin_ok;
+
+ if (mode == ClientHintsMode::kLegacy &&
+ base::FeatureList::IsEnabled(kAllowClientHintsToThirdParty)) {
+ origin_ok = true;
+ } else if (RuntimeEnabledFeatures::FeaturePolicyForClientHintsEnabled()) {
+ origin_ok = (policy && policy->IsFeatureEnabledForOrigin(
+ feature_policy_feature, resource_origin));
+ } else {
+ origin_ok = is_1p_origin;
+ }
+
+ if (!origin_ok)
+ return false;
+
+ // |hints_preferences| is used only in case of the preload scanner;
+ // GetClientHintsPreferences() has things parsed for this document
+ // normally (whether via headers of http-equiv), and |enabled_hints| are
+ // previously persistent settings.
return GetClientHintsPreferences().ShouldSend(type) ||
hints_preferences.ShouldSend(type) || enabled_hints.IsEnabled(type);
}
@@ -1017,7 +1036,7 @@ FetchContext* FrameFetchContext::Detach() {
return this;
}
-void FrameFetchContext::Trace(blink::Visitor* visitor) {
+void FrameFetchContext::Trace(Visitor* visitor) {
visitor->Trace(frame_or_imported_document_);
visitor->Trace(frozen_state_);
BaseFetchContext::Trace(visitor);
@@ -1037,8 +1056,69 @@ bool FrameFetchContext::CalculateIfAdSubresource(
// The AdTracker needs to know about the request as well, and may also mark it
// as an ad.
return GetFrame()->GetAdTracker()->CalculateIfAdSubresource(
- &frame_or_imported_document_->GetDocument(), resource_request, type,
- known_ad);
+ frame_or_imported_document_->GetDocument().ToExecutionContext(),
+ resource_request, type, known_ad);
+}
+
+bool FrameFetchContext::SendConversionRequestInsteadOfRedirecting(
+ const KURL& url,
+ ResourceRequest::RedirectStatus redirect_status,
+ ReportingDisposition reporting_disposition) const {
+ if (!RuntimeEnabledFeatures::ConversionMeasurementEnabled())
+ return false;
+
+ // 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_or_imported_document_ || !GetFrame() ||
+ !GetFrame()->IsMainFrame() ||
+ redirect_status != ResourceRequest::RedirectStatus::kFollowedRedirect) {
+ return false;
+ }
+
+ const char kWellKnownConversionRegsitrationPath[] =
+ "/.well-known/register-conversion";
+ if (url.GetPath() != kWellKnownConversionRegsitrationPath)
+ return false;
+
+ // Only allow conversion registration on secure pages with a secure conversion
+ // redirect.
+ scoped_refptr<const SecurityOrigin> redirect_origin =
+ SecurityOrigin::Create(url);
+ if (!GetFrame()
+ ->GetSecurityContext()
+ ->GetSecurityOrigin()
+ ->IsPotentiallyTrustworthy() ||
+ !redirect_origin->IsPotentiallyTrustworthy()) {
+ return false;
+ }
+
+ // Only report conversions for requests with reporting enabled (i.e. do not
+ // count preload requests). However, return true.
+ if (reporting_disposition == ReportingDisposition::kSuppressReporting)
+ return true;
+
+ mojom::blink::ConversionPtr conversion = mojom::blink::Conversion::New();
+ conversion->reporting_origin = SecurityOrigin::Create(url);
+ conversion->conversion_data = 0UL;
+
+ const char kConversionDataParam[] = "conversion-data";
+ URLSearchParams* search_params = URLSearchParams::Create(url.Query());
+ if (search_params->has(kConversionDataParam)) {
+ bool is_valid_integer = false;
+ uint64_t data = search_params->get(kConversionDataParam)
+ .ToUInt64Strict(&is_valid_integer);
+
+ // Default invalid params to 0.
+ conversion->conversion_data = is_valid_integer ? data : 0UL;
+ }
+
+ mojo::AssociatedRemote<mojom::blink::ConversionHost> conversion_host;
+ GetFrame()->GetRemoteNavigationAssociatedInterfaces()->GetInterface(
+ &conversion_host);
+ conversion_host->RegisterConversion(std::move(conversion));
+ return true;
}
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
@@ -1051,19 +1131,19 @@ base::Optional<ResourceRequestBlockedReason> FrameFetchContext::CanRequest(
const ResourceRequest& resource_request,
const KURL& url,
const ResourceLoaderOptions& options,
- SecurityViolationReportingPolicy reporting_policy,
+ ReportingDisposition reporting_disposition,
ResourceRequest::RedirectStatus redirect_status) const {
if (!GetResourceFetcherProperties().IsDetached() &&
frame_or_imported_document_->GetDocument().IsFreezingInProgress() &&
!resource_request.GetKeepalive()) {
- AddConsoleMessage(ConsoleMessage::Create(
+ AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kError,
"Only fetch keepalive is allowed during onfreeze: " + url.GetString()));
return ResourceRequestBlockedReason::kOther;
}
return BaseFetchContext::CanRequest(type, resource_request, url, options,
- reporting_policy, redirect_status);
+ reporting_disposition, redirect_status);
}
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 0323186e498..9c6d325bce5 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
@@ -35,6 +35,7 @@ n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
#include "base/single_thread_task_runner.h"
#include "third_party/blink/public/common/user_agent/user_agent_metadata.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom-blink-forward.h"
+#include "third_party/blink/public/mojom/web_client_hints/web_client_hints_types.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/loader/base_fetch_context.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -77,7 +78,7 @@ class CORE_EXPORT FrameFetchContext final : public BaseFetchContext {
const ResourceRequest& resource_request,
const KURL& url,
const ResourceLoaderOptions& options,
- SecurityViolationReportingPolicy reporting_policy,
+ ReportingDisposition reporting_disposition,
ResourceRequest::RedirectStatus redirect_status) const override;
mojom::FetchCacheMode ResourceRequestCachePolicy(
const ResourceRequest&,
@@ -104,16 +105,20 @@ class CORE_EXPORT FrameFetchContext final : public BaseFetchContext {
FetchContext* Detach() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
bool CalculateIfAdSubresource(const ResourceRequest& resource_request,
ResourceType type) override;
+ bool SendConversionRequestInsteadOfRedirecting(
+ const KURL& url,
+ ResourceRequest::RedirectStatus redirect_status,
+ ReportingDisposition reporting_disposition) const override;
+
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
TakePendingWorkerTimingReceiver(int request_id) override;
private:
- class FrameConsoleLogger;
friend class FrameFetchContextTest;
struct FrozenState;
@@ -122,13 +127,12 @@ 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* GetDocumentLoader() const;
DocumentLoader* MasterDocumentLoader() const;
LocalFrame* GetFrame() const;
LocalFrameClient* GetLocalFrameClient() const;
// BaseFetchContext overrides:
- KURL GetSiteForCookies() const override;
+ net::SiteForCookies GetSiteForCookies() const override;
scoped_refptr<const SecurityOrigin> GetTopFrameOrigin() const override;
SubresourceFilter* GetSubresourceFilter() const override;
PreviewsResourceLoadingHints* GetPreviewsResourceLoadingHints()
@@ -147,11 +151,10 @@ class CORE_EXPORT FrameFetchContext final : public BaseFetchContext {
bool ShouldBlockWebSocketByMixedContentCheck(const KURL&) const override;
std::unique_ptr<WebSocketHandshakeThrottle> CreateWebSocketHandshakeThrottle()
override;
- bool ShouldBlockFetchByMixedContentCheck(
- mojom::RequestContextType,
- ResourceRequest::RedirectStatus,
- const KURL&,
- SecurityViolationReportingPolicy) const override;
+ bool ShouldBlockFetchByMixedContentCheck(mojom::RequestContextType,
+ ResourceRequest::RedirectStatus,
+ const KURL&,
+ ReportingDisposition) const override;
bool ShouldBlockFetchAsCredentialedSubresource(const ResourceRequest&,
const KURL&) const override;
@@ -163,10 +166,17 @@ class CORE_EXPORT FrameFetchContext final : public BaseFetchContext {
WebContentSettingsClient* GetContentSettingsClient() const;
Settings* GetSettings() const;
String GetUserAgent() const;
- UserAgentMetadata GetUserAgentMetadata() const;
+ base::Optional<UserAgentMetadata> GetUserAgentMetadata() const;
const ClientHintsPreferences GetClientHintsPreferences() const;
float GetDevicePixelRatio() const;
- bool ShouldSendClientHint(mojom::WebClientHintsType,
+
+ enum class ClientHintsMode { kLegacy, kStandard };
+ bool ShouldSendClientHint(ClientHintsMode mode,
+ const FeaturePolicy*,
+ const url::Origin& resource_origin,
+ bool is_1p_origin,
+ mojom::blink::WebClientHintsType,
+ mojom::blink::FeaturePolicyFeature,
const ClientHintsPreferences&,
const WebEnabledClientHints&) const;
void SetFirstPartyCookie(ResourceRequest&);
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 ba9df16bcf6..403758d3604 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
@@ -40,10 +40,10 @@
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/public/mojom/loader/request_context_frame_type.mojom-blink.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
#include "third_party/blink/public/platform/scheduler/web_scoped_virtual_time_pauser.h"
#include "third_party/blink/public/platform/web_client_hints_type.h"
#include "third_party/blink/public/platform/web_document_subresource_filter.h"
-#include "third_party/blink/public/platform/web_insecure_request_policy.h"
#include "third_party/blink/public/platform/web_runtime_features.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/ad_tracker.h"
@@ -73,7 +73,7 @@
#include "third_party/blink/renderer/platform/testing/histogram_tester.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
-#include "third_party/blink/renderer/platform/weborigin/security_violation_reporting_policy.h"
+#include "third_party/blink/renderer/platform/weborigin/reporting_disposition.h"
namespace blink {
@@ -121,6 +121,7 @@ class FrameFetchContextTest : public testing::Test {
void RecreateFetchContext(const KURL& url = KURL(),
const String& feature_policy_header = String()) {
+ dummy_page_holder = nullptr;
dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(500, 500));
dummy_page_holder->GetPage().SetDeviceScaleFactorDeprecated(1.0);
if (url.IsValid()) {
@@ -181,30 +182,31 @@ class FrameFetchContextSubresourceFilterTest : public FrameFetchContextTest {
void SetFilterPolicy(WebDocumentSubresourceFilter::LoadPolicy policy,
bool is_associated_with_ad_subframe = false) {
- document->Loader()->SetSubresourceFilter(SubresourceFilter::Create(
- *document, std::make_unique<FixedPolicySubresourceFilter>(
- policy, &filtered_load_callback_counter_,
- is_associated_with_ad_subframe)));
+ document->Loader()->SetSubresourceFilter(
+ MakeGarbageCollected<SubresourceFilter>(
+ document->ToExecutionContext(),
+ std::make_unique<FixedPolicySubresourceFilter>(
+ policy, &filtered_load_callback_counter_,
+ is_associated_with_ad_subframe)));
}
base::Optional<ResourceRequestBlockedReason> CanRequest() {
- return CanRequestInternal(SecurityViolationReportingPolicy::kReport);
+ return CanRequestInternal(ReportingDisposition::kReport);
}
base::Optional<ResourceRequestBlockedReason> CanRequestKeepAlive() {
- return CanRequestInternal(SecurityViolationReportingPolicy::kReport,
+ return CanRequestInternal(ReportingDisposition::kReport,
true /* keepalive */);
}
base::Optional<ResourceRequestBlockedReason> CanRequestPreload() {
- return CanRequestInternal(
- SecurityViolationReportingPolicy::kSuppressReporting);
+ return CanRequestInternal(ReportingDisposition::kSuppressReporting);
}
base::Optional<ResourceRequestBlockedReason> CanRequestAndVerifyIsAd(
bool expect_is_ad) {
base::Optional<ResourceRequestBlockedReason> reason =
- CanRequestInternal(SecurityViolationReportingPolicy::kReport);
+ CanRequestInternal(ReportingDisposition::kReport);
ResourceRequest request(KURL("http://example.com/"));
EXPECT_EQ(expect_is_ad, GetFetchContext()->CalculateIfAdSubresource(
request, ResourceType::kMock));
@@ -213,18 +215,18 @@ class FrameFetchContextSubresourceFilterTest : public FrameFetchContextTest {
void AppendExecutingScriptToAdTracker(const String& url) {
AdTracker* ad_tracker = document->GetFrame()->GetAdTracker();
- ad_tracker->WillExecuteScript(document, url);
+ ad_tracker->WillExecuteScript(document->ToExecutionContext(), url);
}
void AppendAdScriptToAdTracker(const KURL& ad_script_url) {
AdTracker* ad_tracker = document->GetFrame()->GetAdTracker();
- ad_tracker->AppendToKnownAdScripts(*(document.Get()),
+ ad_tracker->AppendToKnownAdScripts(*document->ToExecutionContext(),
ad_script_url.GetString());
}
private:
base::Optional<ResourceRequestBlockedReason> CanRequestInternal(
- SecurityViolationReportingPolicy reporting_policy,
+ ReportingDisposition reporting_disposition,
bool keepalive = false) {
const KURL input_url("http://example.com/");
ResourceRequest resource_request(input_url);
@@ -236,7 +238,7 @@ class FrameFetchContextSubresourceFilterTest : public FrameFetchContextTest {
ResourceLoaderOptions options;
return GetFetchContext()->CanRequest(
ResourceType::kImage, resource_request, input_url, options,
- reporting_policy, ResourceRequest::RedirectStatus::kNoRedirect);
+ reporting_disposition, ResourceRequest::RedirectStatus::kNoRedirect);
}
int filtered_load_callback_counter_;
@@ -277,7 +279,7 @@ class FrameFetchContextModifyRequestTest : public FrameFetchContextTest {
protected:
void ModifyRequestForCSP(ResourceRequest& resource_request,
- network::mojom::RequestContextFrameType frame_type) {
+ mojom::RequestContextFrameType frame_type) {
document->GetFrame()->Loader().RecordLatestRequiredCSP();
document->GetFrame()->Loader().ModifyRequestForCSP(
resource_request,
@@ -287,12 +289,12 @@ class FrameFetchContextModifyRequestTest : public FrameFetchContextTest {
void ExpectUpgrade(const char* input, const char* expected) {
ExpectUpgrade(input, mojom::RequestContextType::SCRIPT,
- network::mojom::RequestContextFrameType::kNone, expected);
+ mojom::RequestContextFrameType::kNone, expected);
}
void ExpectUpgrade(const char* input,
mojom::RequestContextType request_context,
- network::mojom::RequestContextFrameType frame_type,
+ mojom::RequestContextFrameType frame_type,
const char* expected) {
const KURL input_url(input);
const KURL expected_url(expected);
@@ -312,7 +314,7 @@ class FrameFetchContextModifyRequestTest : public FrameFetchContextTest {
void ExpectUpgradeInsecureRequestHeader(
const char* input,
- network::mojom::RequestContextFrameType frame_type,
+ mojom::RequestContextFrameType frame_type,
bool should_prefer) {
const KURL input_url(input);
@@ -336,25 +338,29 @@ class FrameFetchContextModifyRequestTest : public FrameFetchContextTest {
void ExpectIsAutomaticUpgradeSet(const char* input,
const char* main_frame,
- WebInsecureRequestPolicy policy,
+ mojom::blink::InsecureRequestPolicy policy,
bool expected_value) {
const KURL input_url(input);
const KURL main_frame_url(main_frame);
ResourceRequest resource_request(input_url);
- resource_request.SetRequestContext(mojom::RequestContextType::IMAGE);
+ // TODO(crbug.com/1026464, carlosil): Default behavior currently is to not
+ // autoupgrade images, setting the context to AUDIO to ensure the upgrade
+ // flow runs, this can be switched back to IMAGE once autoupgrades launch
+ // for them.
+ resource_request.SetRequestContext(mojom::RequestContextType::AUDIO);
RecreateFetchContext(main_frame_url);
- document->SetInsecureRequestPolicy(policy);
+ document->GetSecurityContext().SetInsecureRequestPolicy(policy);
ModifyRequestForCSP(resource_request,
- network::mojom::RequestContextFrameType::kNone);
+ mojom::RequestContextFrameType::kNone);
EXPECT_EQ(expected_value, resource_request.IsAutomaticUpgrade());
}
void ExpectSetRequiredCSPRequestHeader(
const char* input,
- network::mojom::RequestContextFrameType frame_type,
+ mojom::RequestContextFrameType frame_type,
const AtomicString& expected_required_csp) {
const KURL input_url(input);
ResourceRequest resource_request(input_url);
@@ -366,11 +372,10 @@ class FrameFetchContextModifyRequestTest : public FrameFetchContextTest {
resource_request.HttpHeaderField(http_names::kSecRequiredCSP));
}
- void SetFrameOwnerBasedOnFrameType(
- network::mojom::RequestContextFrameType frame_type,
- HTMLIFrameElement* iframe,
- const AtomicString& potential_value) {
- if (frame_type != network::mojom::RequestContextFrameType::kNested) {
+ void SetFrameOwnerBasedOnFrameType(mojom::RequestContextFrameType frame_type,
+ HTMLIFrameElement* iframe,
+ const AtomicString& potential_value) {
+ if (frame_type != mojom::RequestContextFrameType::kNested) {
document->GetFrame()->SetOwner(nullptr);
return;
}
@@ -405,48 +410,41 @@ TEST_F(FrameFetchContextModifyRequestTest, UpgradeInsecureResourceRequests) {
"ftp://example.test:1212/image.png"},
};
- document->SetInsecureRequestPolicy(kUpgradeInsecureRequests);
+ document->GetSecurityContext().SetInsecureRequestPolicy(
+ mojom::blink::InsecureRequestPolicy::kUpgradeInsecureRequests);
for (const auto& test : tests) {
- document->ClearInsecureNavigationsToUpgradeForTest();
+ document->GetSecurityContext().ClearInsecureNavigationsToUpgradeForTest();
// We always upgrade for FrameTypeNone.
ExpectUpgrade(test.original, mojom::RequestContextType::SCRIPT,
- network::mojom::RequestContextFrameType::kNone,
- test.upgraded);
+ mojom::RequestContextFrameType::kNone, test.upgraded);
// We never upgrade for FrameTypeNested. This is done on the browser
// process.
ExpectUpgrade(test.original, mojom::RequestContextType::SCRIPT,
- network::mojom::RequestContextFrameType::kNested,
- test.original);
+ mojom::RequestContextFrameType::kNested, test.original);
// We do not upgrade for FrameTypeTopLevel or FrameTypeAuxiliary...
ExpectUpgrade(test.original, mojom::RequestContextType::SCRIPT,
- network::mojom::RequestContextFrameType::kTopLevel,
- test.original);
+ mojom::RequestContextFrameType::kTopLevel, test.original);
ExpectUpgrade(test.original, mojom::RequestContextType::SCRIPT,
- network::mojom::RequestContextFrameType::kAuxiliary,
- test.original);
+ mojom::RequestContextFrameType::kAuxiliary, test.original);
// unless the request context is RequestContextForm.
ExpectUpgrade(test.original, mojom::RequestContextType::FORM,
- network::mojom::RequestContextFrameType::kTopLevel,
- test.upgraded);
+ mojom::RequestContextFrameType::kTopLevel, test.upgraded);
ExpectUpgrade(test.original, mojom::RequestContextType::FORM,
- network::mojom::RequestContextFrameType::kAuxiliary,
- test.upgraded);
+ mojom::RequestContextFrameType::kAuxiliary, test.upgraded);
// Or unless the host of the resource is in the document's
// InsecureNavigationsSet:
- document->AddInsecureNavigationUpgrade(
+ document->GetSecurityContext().AddInsecureNavigationUpgrade(
example_origin->Host().Impl()->GetHash());
ExpectUpgrade(test.original, mojom::RequestContextType::SCRIPT,
- network::mojom::RequestContextFrameType::kTopLevel,
- test.upgraded);
+ mojom::RequestContextFrameType::kTopLevel, test.upgraded);
ExpectUpgrade(test.original, mojom::RequestContextType::SCRIPT,
- network::mojom::RequestContextFrameType::kAuxiliary,
- test.upgraded);
+ mojom::RequestContextFrameType::kAuxiliary, test.upgraded);
}
}
@@ -456,7 +454,8 @@ TEST_F(FrameFetchContextModifyRequestTest,
feature_list.InitAndDisableFeature(blink::features::kMixedContentAutoupgrade);
RecreateFetchContext(KURL("https://secureorigin.test/image.png"));
- document->SetInsecureRequestPolicy(kLeaveInsecureRequestsAlone);
+ document->GetSecurityContext().SetInsecureRequestPolicy(
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone);
ExpectUpgrade("http://example.test/image.png",
"http://example.test/image.png");
@@ -482,70 +481,74 @@ TEST_F(FrameFetchContextModifyRequestTest,
TEST_F(FrameFetchContextModifyRequestTest, IsAutomaticUpgradeSet) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(features::kMixedContentAutoupgrade);
- ExpectIsAutomaticUpgradeSet("http://example.test/image.png",
- "https://example.test",
- kLeaveInsecureRequestsAlone, true);
+ ExpectIsAutomaticUpgradeSet(
+ "http://example.test/image.png", "https://example.test",
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone, true);
}
TEST_F(FrameFetchContextModifyRequestTest, IsAutomaticUpgradeNotSet) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(features::kMixedContentAutoupgrade);
// Upgrade shouldn't happen if the resource is already https.
- ExpectIsAutomaticUpgradeSet("https://example.test/image.png",
- "https://example.test",
- kLeaveInsecureRequestsAlone, false);
+ ExpectIsAutomaticUpgradeSet(
+ "https://example.test/image.png", "https://example.test",
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone, false);
// Upgrade shouldn't happen if the site is http.
- ExpectIsAutomaticUpgradeSet("http://example.test/image.png",
- "http://example.test",
- kLeaveInsecureRequestsAlone, false);
+ ExpectIsAutomaticUpgradeSet(
+ "http://example.test/image.png", "http://example.test",
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone, false);
// Flag shouldn't be set if upgrade was due to upgrade-insecure-requests.
- ExpectIsAutomaticUpgradeSet("http://example.test/image.png",
- "https://example.test", kUpgradeInsecureRequests,
- false);
+ ExpectIsAutomaticUpgradeSet(
+ "http://example.test/image.png", "https://example.test",
+ mojom::blink::InsecureRequestPolicy::kUpgradeInsecureRequests, false);
}
TEST_F(FrameFetchContextModifyRequestTest, SendUpgradeInsecureRequestHeader) {
struct TestCase {
const char* to_request;
- network::mojom::RequestContextFrameType frame_type;
+ mojom::RequestContextFrameType frame_type;
bool should_prefer;
} tests[] = {{"http://example.test/page.html",
- network::mojom::RequestContextFrameType::kAuxiliary, true},
+ mojom::RequestContextFrameType::kAuxiliary, true},
{"http://example.test/page.html",
- network::mojom::RequestContextFrameType::kNested, true},
+ mojom::RequestContextFrameType::kNested, true},
{"http://example.test/page.html",
- network::mojom::RequestContextFrameType::kNone, false},
+ mojom::RequestContextFrameType::kNone, false},
{"http://example.test/page.html",
- network::mojom::RequestContextFrameType::kTopLevel, true},
+ mojom::RequestContextFrameType::kTopLevel, true},
{"https://example.test/page.html",
- network::mojom::RequestContextFrameType::kAuxiliary, true},
+ mojom::RequestContextFrameType::kAuxiliary, true},
{"https://example.test/page.html",
- network::mojom::RequestContextFrameType::kNested, true},
+ mojom::RequestContextFrameType::kNested, true},
{"https://example.test/page.html",
- network::mojom::RequestContextFrameType::kNone, false},
+ mojom::RequestContextFrameType::kNone, false},
{"https://example.test/page.html",
- network::mojom::RequestContextFrameType::kTopLevel, true}};
+ mojom::RequestContextFrameType::kTopLevel, true}};
// This should work correctly both when the FrameFetchContext has a Document,
// and when it doesn't (e.g. during main frame navigations), so run through
// the tests both before and after providing a document to the context.
for (const auto& test : tests) {
- document->SetInsecureRequestPolicy(kLeaveInsecureRequestsAlone);
+ document->GetSecurityContext().SetInsecureRequestPolicy(
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone);
ExpectUpgradeInsecureRequestHeader(test.to_request, test.frame_type,
test.should_prefer);
- document->SetInsecureRequestPolicy(kUpgradeInsecureRequests);
+ document->GetSecurityContext().SetInsecureRequestPolicy(
+ mojom::blink::InsecureRequestPolicy::kUpgradeInsecureRequests);
ExpectUpgradeInsecureRequestHeader(test.to_request, test.frame_type,
test.should_prefer);
}
for (const auto& test : tests) {
- document->SetInsecureRequestPolicy(kLeaveInsecureRequestsAlone);
+ document->GetSecurityContext().SetInsecureRequestPolicy(
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone);
ExpectUpgradeInsecureRequestHeader(test.to_request, test.frame_type,
test.should_prefer);
- document->SetInsecureRequestPolicy(kUpgradeInsecureRequests);
+ document->GetSecurityContext().SetInsecureRequestPolicy(
+ mojom::blink::InsecureRequestPolicy::kUpgradeInsecureRequests);
ExpectUpgradeInsecureRequestHeader(test.to_request, test.frame_type,
test.should_prefer);
}
@@ -554,15 +557,15 @@ TEST_F(FrameFetchContextModifyRequestTest, SendUpgradeInsecureRequestHeader) {
TEST_F(FrameFetchContextModifyRequestTest, SendRequiredCSPHeader) {
struct TestCase {
const char* to_request;
- network::mojom::RequestContextFrameType frame_type;
- } tests[] = {{"https://example.test/page.html",
- network::mojom::RequestContextFrameType::kAuxiliary},
- {"https://example.test/page.html",
- network::mojom::RequestContextFrameType::kNested},
- {"https://example.test/page.html",
- network::mojom::RequestContextFrameType::kNone},
- {"https://example.test/page.html",
- network::mojom::RequestContextFrameType::kTopLevel}};
+ mojom::RequestContextFrameType frame_type;
+ } tests[] = {
+ {"https://example.test/page.html",
+ mojom::RequestContextFrameType::kAuxiliary},
+ {"https://example.test/page.html",
+ mojom::RequestContextFrameType::kNested},
+ {"https://example.test/page.html", mojom::RequestContextFrameType::kNone},
+ {"https://example.test/page.html",
+ mojom::RequestContextFrameType::kTopLevel}};
auto* iframe = MakeGarbageCollected<HTMLIFrameElement>(*document);
const AtomicString& required_csp = AtomicString("default-src 'none'");
@@ -572,7 +575,7 @@ TEST_F(FrameFetchContextModifyRequestTest, SendRequiredCSPHeader) {
SetFrameOwnerBasedOnFrameType(test.frame_type, iframe, required_csp);
ExpectSetRequiredCSPRequestHeader(
test.to_request, test.frame_type,
- test.frame_type == network::mojom::RequestContextFrameType::kNested
+ test.frame_type == mojom::RequestContextFrameType::kNested
? required_csp
: g_null_atom);
@@ -580,7 +583,7 @@ TEST_F(FrameFetchContextModifyRequestTest, SendRequiredCSPHeader) {
another_required_csp);
ExpectSetRequiredCSPRequestHeader(
test.to_request, test.frame_type,
- test.frame_type == network::mojom::RequestContextFrameType::kNested
+ test.frame_type == mojom::RequestContextFrameType::kNested
? another_required_csp
: g_null_atom);
}
@@ -648,8 +651,15 @@ TEST_F(FrameFetchContextHintsTest, MonitorDeviceMemorySecureTransport) {
ExpectHeader("https://www.example.com/1.gif", "Viewport-Width", false, "");
// Without a feature policy header, the client hints should be sent only to
// the first party origins.
+ // Device-memory is a legacy hint that's sent on Android regardless of Feature
+ // Policy delegation.
+#if defined(OS_ANDROID)
+ ExpectHeader("https://www.someother-example.com/1.gif", "Device-Memory", true,
+ "4");
+#else
ExpectHeader("https://www.someother-example.com/1.gif", "Device-Memory",
false, "");
+#endif
}
// Verify that client hints are not attached when the resources do not belong to
@@ -982,15 +992,28 @@ TEST_F(FrameFetchContextHintsTest, MonitorSomeHintsFeaturePolicy) {
// With a feature policy header, the client hints should be sent to the
// declared third party origins.
ExpectHeader("https://www.example.net/1.gif", "Device-Memory", true, "4");
+ // Device-memory is a legacy hint that's sent on Android regardless of Feature
+ // Policy delegation.
+#if defined(OS_ANDROID)
+ ExpectHeader("https://www.someother-example.com/1.gif", "Device-Memory", true,
+ "4");
+#else
ExpectHeader("https://www.someother-example.com/1.gif", "Device-Memory",
false, "");
+#endif
// `Sec-CH-UA` is special.
ExpectHeader("https://www.example.net/1.gif", "Sec-CH-UA", true, "");
// Other hints not declared in the policy are still not attached.
ExpectHeader("https://www.example.net/1.gif", "downlink", false, "");
ExpectHeader("https://www.example.net/1.gif", "ect", false, "");
+ // DPR is a legacy hint that's sent on Android regardless of Feature Policy
+ // delegation.
+#if defined(OS_ANDROID)
+ ExpectHeader("https://www.example.net/1.gif", "DPR", true, "1");
+#else
ExpectHeader("https://www.example.net/1.gif", "DPR", false, "");
+#endif
ExpectHeader("https://www.example.net/1.gif", "Sec-CH-Lang", false, "");
ExpectHeader("https://www.example.net/1.gif", "Sec-CH-UA-Arch", false, "");
ExpectHeader("https://www.example.net/1.gif", "Sec-CH-UA-Platform", false,
@@ -1219,7 +1242,8 @@ TEST_F(FrameFetchContextMockedLocalFrameClientTest,
TEST_F(FrameFetchContextTest, AddResourceTimingWhenDetached) {
scoped_refptr<ResourceTimingInfo> info = ResourceTimingInfo::Create(
"type", base::TimeTicks() + base::TimeDelta::FromSecondsD(0.3),
- mojom::RequestContextType::UNSPECIFIED);
+ mojom::RequestContextType::UNSPECIFIED,
+ network::mojom::RequestDestination::kEmpty);
dummy_page_holder = nullptr;
@@ -1280,8 +1304,8 @@ TEST_F(FrameFetchContextTest, SetFirstPartyCookieWhenDetached) {
SetFirstPartyCookie(request);
- EXPECT_TRUE(
- SecurityOrigin::AreSameOrigin(document_url, request.SiteForCookies()));
+ EXPECT_TRUE(request.SiteForCookies().IsEquivalent(
+ net::SiteForCookies::FromUrl(document_url)));
}
TEST_F(FrameFetchContextTest, TopFrameOrigin) {
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 270ec3c90ff..b4b183842f1 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
@@ -5,7 +5,7 @@
#include "third_party/blink/renderer/core/loader/frame_load_request.h"
#include "third_party/blink/public/common/blob/blob_utils.h"
-#include "third_party/blink/public/platform/web_input_event.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/renderer/core/events/current_input_event.h"
#include "third_party/blink/renderer/core/fileapi/public_url_manager.h"
@@ -36,19 +36,17 @@ static void SetReferrerForRequest(Document* origin_document,
Referrer referrer = SecurityPolicy::GenerateReferrer(
referrer_policy_to_use, request.Url(), referrer_to_use);
- // TODO(domfarolino): Stop storing ResourceRequest's generated referrer as a
- // header and instead use a separate member. See https://crbug.com/850813.
- request.SetHttpReferrer(referrer);
+ request.SetReferrerString(referrer.referrer);
+ request.SetReferrerPolicy(referrer.referrer_policy);
request.SetHTTPOriginToMatchReferrerIfNeeded();
}
FrameLoadRequest::FrameLoadRequest(Document* origin_document,
const ResourceRequest& resource_request)
-
: origin_document_(origin_document),
- resource_request_(resource_request),
should_send_referrer_(kMaybeSendReferrer) {
- // These flags are passed to a service worker which controls the page.
+ resource_request_.CopyHeadFrom(resource_request);
+ resource_request_.SetHttpBody(resource_request.HttpBody());
resource_request_.SetMode(network::mojom::RequestMode::kNavigate);
resource_request_.SetCredentialsMode(
network::mojom::CredentialsMode::kInclude);
@@ -58,10 +56,10 @@ FrameLoadRequest::FrameLoadRequest(Document* origin_document,
SetInputStartTime(input_event->TimeStamp());
should_check_main_world_content_security_policy_ =
- origin_document &&
- ContentSecurityPolicy::ShouldBypassMainWorld(origin_document)
- ? kDoNotCheckContentSecurityPolicy
- : kCheckContentSecurityPolicy;
+ origin_document && ContentSecurityPolicy::ShouldBypassMainWorld(
+ origin_document->ToExecutionContext())
+ ? network::mojom::CSPDisposition::DO_NOT_CHECK
+ : network::mojom::CSPDisposition::CHECK;
if (origin_document) {
DCHECK(!resource_request_.RequestorOrigin());
@@ -79,13 +77,22 @@ FrameLoadRequest::FrameLoadRequest(Document* origin_document,
}
}
+FrameLoadRequest::FrameLoadRequest(
+ Document* origin_document,
+ const ResourceRequestHead& resource_request_head)
+ : FrameLoadRequest(origin_document,
+ ResourceRequest(resource_request_head)) {}
+
ClientRedirectPolicy FrameLoadRequest::ClientRedirect() const {
- // Form submissions have not historically been reported to the extensions API
- // as client redirects.
+ // Form submissions and anchor clicks have not historically been reported
+ // to the extensions API as client redirects.
if (client_navigation_reason_ == ClientNavigationReason::kNone ||
client_navigation_reason_ == ClientNavigationReason::kFormSubmissionGet ||
- client_navigation_reason_ == ClientNavigationReason::kFormSubmissionPost)
+ client_navigation_reason_ ==
+ ClientNavigationReason::kFormSubmissionPost ||
+ client_navigation_reason_ == ClientNavigationReason::kAnchorClick) {
return ClientRedirectPolicy::kNotClientRedirect;
+ }
return ClientRedirectPolicy::kClientRedirect;
}
diff --git a/chromium/third_party/blink/renderer/core/loader/frame_load_request.h b/chromium/third_party/blink/renderer/core/loader/frame_load_request.h
index a68c671de7c..96190d87aef 100644
--- a/chromium/third_party/blink/renderer/core/loader/frame_load_request.h
+++ b/chromium/third_party/blink/renderer/core/loader/frame_load_request.h
@@ -27,6 +27,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_FRAME_LOAD_REQUEST_H_
#include "mojo/public/cpp/bindings/remote.h"
+#include "services/network/public/mojom/referrer_policy.mojom-blink.h"
#include "third_party/blink/public/common/navigation/triggering_event_info.h"
#include "third_party/blink/public/mojom/blob/blob_url_store.mojom-blink.h"
#include "third_party/blink/public/mojom/loader/request_context_frame_type.mojom-blink.h"
@@ -37,6 +38,7 @@
#include "third_party/blink/renderer/core/loader/navigation_policy.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/weborigin/referrer.h"
namespace blink {
@@ -48,13 +50,14 @@ struct CORE_EXPORT FrameLoadRequest {
public:
FrameLoadRequest(Document* origin_document, const ResourceRequest&);
+ FrameLoadRequest(Document* origin_document, const ResourceRequestHead&);
+ FrameLoadRequest(const FrameLoadRequest&) = delete;
+ FrameLoadRequest& operator=(const FrameLoadRequest&) = delete;
- Document* OriginDocument() const { return origin_document_.Get(); }
+ Document* OriginDocument() const { return origin_document_; }
- network::mojom::RequestContextFrameType GetFrameType() const {
- return frame_type_;
- }
- void SetFrameType(network::mojom::RequestContextFrameType frame_type) {
+ mojom::RequestContextFrameType GetFrameType() const { return frame_type_; }
+ void SetFrameType(mojom::RequestContextFrameType frame_type) {
frame_type_ = frame_type;
}
@@ -88,7 +91,7 @@ struct CORE_EXPORT FrameLoadRequest {
triggering_event_info_ = info;
}
- HTMLFormElement* Form() const { return form_.Get(); }
+ HTMLFormElement* Form() const { return form_; }
void SetForm(HTMLFormElement* form) { form_ = form; }
ShouldSendReferrer GetShouldSendReferrer() const {
@@ -100,7 +103,7 @@ struct CORE_EXPORT FrameLoadRequest {
href_translate_ = translate;
}
- ContentSecurityPolicyDisposition ShouldCheckMainWorldContentSecurityPolicy()
+ network::mojom::CSPDisposition ShouldCheckMainWorldContentSecurityPolicy()
const {
return should_check_main_world_content_security_policy_;
}
@@ -136,7 +139,8 @@ struct CORE_EXPORT FrameLoadRequest {
void SetNoOpener() { window_features_.noopener = true; }
void SetNoReferrer() {
should_send_referrer_ = kNeverSendReferrer;
- resource_request_.ClearHTTPReferrer();
+ resource_request_.SetReferrerString(Referrer::NoReferrer());
+ resource_request_.SetReferrerPolicy(network::mojom::ReferrerPolicy::kNever);
resource_request_.ClearHTTPOrigin();
}
@@ -145,7 +149,7 @@ struct CORE_EXPORT FrameLoadRequest {
bool CanDisplay(const KURL&) const;
private:
- Member<Document> origin_document_;
+ Document* origin_document_;
ResourceRequest resource_request_;
AtomicString href_translate_;
ClientNavigationReason client_navigation_reason_ =
@@ -153,15 +157,15 @@ struct CORE_EXPORT FrameLoadRequest {
NavigationPolicy navigation_policy_ = kNavigationPolicyCurrentTab;
TriggeringEventInfo triggering_event_info_ =
TriggeringEventInfo::kNotFromEvent;
- Member<HTMLFormElement> form_;
+ HTMLFormElement* form_ = nullptr;
ShouldSendReferrer should_send_referrer_;
- ContentSecurityPolicyDisposition
+ network::mojom::CSPDisposition
should_check_main_world_content_security_policy_;
scoped_refptr<base::RefCountedData<mojo::Remote<mojom::blink::BlobURLToken>>>
blob_url_token_;
base::TimeTicks input_start_time_;
- network::mojom::RequestContextFrameType frame_type_ =
- network::mojom::RequestContextFrameType::kNone;
+ mojom::RequestContextFrameType frame_type_ =
+ mojom::RequestContextFrameType::kNone;
WebWindowFeatures window_features_;
bool is_window_open_ = false;
};
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 746c175f527..b8f4aa80447 100644
--- a/chromium/third_party/blink/renderer/core/loader/frame_loader.cc
+++ b/chromium/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -45,6 +45,7 @@
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
+#include "services/network/public/cpp/features.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/public/mojom/frame/navigation_initiator.mojom-blink.h"
@@ -65,6 +66,7 @@
#include "third_party/blink/renderer/core/events/page_transition_event.h"
#include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
+#include "third_party/blink/renderer/core/frame/csp/csp_source.h"
#include "third_party/blink/renderer/core/frame/csp/navigation_initiator_impl.h"
#include "third_party/blink/renderer/core/frame/frame_console.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
@@ -103,6 +105,7 @@
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
#include "third_party/blink/renderer/platform/bindings/v8_dom_activity_logger.h"
#include "third_party/blink/renderer/platform/exported/wrapped_resource_request.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/instrumentation/instance_counters.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
@@ -110,6 +113,7 @@
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/mhtml/archive_resource.h"
#include "third_party/blink/renderer/platform/mhtml/mhtml_archive.h"
+#include "third_party/blink/renderer/platform/network/content_security_policy_response_headers.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_utils.h"
@@ -132,7 +136,7 @@ bool IsReloadLoadType(WebFrameLoadType type) {
type == WebFrameLoadType::kReloadBypassingCache;
}
-static bool NeedsHistoryItemRestore(WebFrameLoadType type) {
+bool FrameLoader::NeedsHistoryItemRestore(WebFrameLoadType type) {
return type == WebFrameLoadType::kBackForward || IsReloadLoadType(type);
}
@@ -157,13 +161,13 @@ ResourceRequest FrameLoader::ResourceRequestForReload(
// document. If this reload is a client redirect (e.g., location.reload()), it
// was initiated by something in the current document and should therefore
// show the current document's url as the referrer.
- // TODO(domfarolino): Stop storing ResourceRequest's generated referrer as a
- // header and instead use a separate member. See https://crbug.com/850813.
if (client_redirect_policy == ClientRedirectPolicy::kClientRedirect) {
- request.SetHttpReferrer(SecurityPolicy::GenerateReferrer(
+ Referrer referrer = SecurityPolicy::GenerateReferrer(
frame_->GetDocument()->GetReferrerPolicy(),
frame_->GetDocument()->Url(),
- frame_->GetDocument()->OutgoingReferrer()));
+ frame_->GetDocument()->OutgoingReferrer());
+ request.SetReferrerString(referrer.referrer);
+ request.SetReferrerPolicy(referrer.referrer_policy);
}
request.SetSkipServiceWorker(frame_load_type ==
@@ -174,8 +178,7 @@ ResourceRequest FrameLoader::ResourceRequestForReload(
FrameLoader::FrameLoader(LocalFrame* frame)
: frame_(frame),
progress_tracker_(MakeGarbageCollected<ProgressTracker>(frame)),
- in_restore_scroll_(false),
- forced_sandbox_flags_(WebSandboxFlags::kNone),
+ forced_sandbox_flags_(mojom::blink::WebSandboxFlags::kNone),
dispatching_did_clear_window_object_in_main_world_(false),
detached_(false),
virtual_time_pauser_(
@@ -192,11 +195,10 @@ FrameLoader::~FrameLoader() {
DCHECK(detached_);
}
-void FrameLoader::Trace(blink::Visitor* visitor) {
+void FrameLoader::Trace(Visitor* visitor) {
visitor->Trace(frame_);
visitor->Trace(progress_tracker_);
visitor->Trace(document_loader_);
- visitor->Trace(provisional_document_loader_);
visitor->Trace(last_origin_document_csp_);
}
@@ -209,14 +211,13 @@ void FrameLoader::Init() {
frame_->Owner() ? base::make_optional(frame_->Owner()->GetFramePolicy())
: base::nullopt;
- provisional_document_loader_ = Client()->CreateDocumentLoader(
- frame_, kWebNavigationTypeOther, std::move(navigation_params),
- nullptr /* extra_data */);
- provisional_document_loader_->StartLoading();
+ DocumentLoader* new_document_loader = Client()->CreateDocumentLoader(
+ frame_, kWebNavigationTypeOther,
+ MakeGarbageCollected<ContentSecurityPolicy>(),
+ std::move(navigation_params), nullptr /* extra_data */);
- CommitDocumentLoader(provisional_document_loader_.Release(), base::nullopt,
- false /* dispatch_did_start */, base::DoNothing::Once(),
- false /* dispatch_did_commit */);
+ CommitDocumentLoader(new_document_loader, base::nullopt, nullptr,
+ CommitReason::kInitialization);
frame_->GetDocument()->CancelParsing();
@@ -241,8 +242,6 @@ void FrameLoader::SetDefersLoading(bool defers) {
frame_->GetDocument()->Fetcher()->SetDefersLoading(defers);
if (document_loader_)
document_loader_->SetDefersLoading(defers);
- if (provisional_document_loader_)
- provisional_document_loader_->SetDefersLoading(defers);
}
void FrameLoader::SaveScrollAnchor() {
@@ -266,8 +265,8 @@ void FrameLoader::SaveScrollAnchor() {
if (serialized_anchor.IsValid()) {
history_item->SetScrollAnchorData(
{serialized_anchor.selector,
- WebFloatPoint(serialized_anchor.relative_offset.X(),
- serialized_anchor.relative_offset.Y()),
+ gfx::PointF(serialized_anchor.relative_offset.X(),
+ serialized_anchor.relative_offset.Y()),
serialized_anchor.simhash});
}
}
@@ -342,6 +341,8 @@ void FrameLoader::FinishedParsing() {
progress_tracker_->FinishedParsing();
+ frame_->GetLocalFrameHostRemote().DidFinishDocumentLoad();
+
if (Client()) {
ScriptForbiddenScope forbid_scripts;
Client()->DispatchDidFinishDocumentLoad();
@@ -451,8 +452,7 @@ void FrameLoader::DidFinishSameDocumentNavigation(
: SerializedScriptValue::NullValue());
if (view_state) {
- RestoreScrollPositionAndViewState(frame_load_type,
- true /* is_same_document */, *view_state,
+ RestoreScrollPositionAndViewState(frame_load_type, *view_state,
history_item->ScrollRestorationType());
}
@@ -493,7 +493,7 @@ WebFrameLoadType FrameLoader::DetermineFrameLoadType(
// and that was the about:blank Document created when the browsing context
// was created, then the navigation must be done with replacement enabled."
if ((!state_machine_.CommittedMultipleRealLoads() &&
- DeprecatedEqualIgnoringCase(frame_->GetDocument()->Url(), BlankURL())))
+ EqualIgnoringASCIICase(frame_->GetDocument()->Url(), BlankURL())))
return WebFrameLoadType::kReplaceCurrentItem;
if (url == document_loader_->UrlForHistory()) {
@@ -528,7 +528,7 @@ bool FrameLoader::AllowRequestForThisFrame(const FrameLoadRequest& request) {
// as per https://html.spec.whatwg.org/C/#javascript-protocol.
bool javascript_url_is_allowed =
request.ShouldCheckMainWorldContentSecurityPolicy() ==
- kDoNotCheckContentSecurityPolicy ||
+ network::mojom::CSPDisposition::DO_NOT_CHECK ||
origin_document->GetContentSecurityPolicy()->AllowInline(
ContentSecurityPolicy::InlineType::kNavigation,
frame_->DeprecatedLocalOwner(), url.GetString(),
@@ -538,17 +538,18 @@ bool FrameLoader::AllowRequestForThisFrame(const FrameLoadRequest& request) {
if (!javascript_url_is_allowed)
return false;
- if (frame_->Owner() &&
- ((frame_->Owner()->GetFramePolicy().sandbox_flags &
- WebSandboxFlags::kOrigin) != WebSandboxFlags::kNone))
+ if (frame_->Owner() && ((frame_->Owner()->GetFramePolicy().sandbox_flags &
+ mojom::blink::WebSandboxFlags::kOrigin) !=
+ mojom::blink::WebSandboxFlags::kNone))
return false;
}
if (!request.CanDisplay(url)) {
- request.OriginDocument()->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kError,
- "Not allowed to load local resource: " + url.ElidedString()));
+ request.OriginDocument()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kSecurity,
+ mojom::ConsoleMessageLevel::kError,
+ "Not allowed to load local resource: " + url.ElidedString()));
return false;
}
return true;
@@ -594,16 +595,31 @@ static mojom::RequestContextType DetermineRequestContextFromNavigationType(
return mojom::RequestContextType::HYPERLINK;
}
-void FrameLoader::StartNavigation(const FrameLoadRequest& passed_request,
+static network::mojom::RequestDestination
+DetermineRequestDestinationFromNavigationType(
+ const WebNavigationType navigation_type) {
+ switch (navigation_type) {
+ case kWebNavigationTypeLinkClicked:
+ case kWebNavigationTypeOther:
+ case kWebNavigationTypeFormResubmitted:
+ case kWebNavigationTypeFormSubmitted:
+ return network::mojom::RequestDestination::kDocument;
+ case kWebNavigationTypeBackForward:
+ case kWebNavigationTypeReload:
+ return network::mojom::RequestDestination::kEmpty;
+ }
+ NOTREACHED();
+ return network::mojom::RequestDestination::kDocument;
+}
+
+void FrameLoader::StartNavigation(FrameLoadRequest& request,
WebFrameLoadType frame_load_type) {
CHECK(!IsBackForwardLoadType(frame_load_type));
- DCHECK(passed_request.GetTriggeringEventInfo() !=
- TriggeringEventInfo::kUnknown);
+ DCHECK(request.GetTriggeringEventInfo() != TriggeringEventInfo::kUnknown);
DCHECK(frame_->GetDocument());
if (HTMLFrameOwnerElement* element = frame_->DeprecatedLocalOwner())
element->CancelPendingLazyLoad();
- FrameLoadRequest request(passed_request);
ResourceRequest& resource_request = request.GetResourceRequest();
const KURL& url = resource_request.Url();
Document* origin_document = request.OriginDocument();
@@ -628,11 +644,12 @@ void FrameLoader::StartNavigation(const FrameLoadRequest& passed_request,
(url.ProtocolIs("filesystem") ||
(url.ProtocolIsData() &&
network_utils::IsDataURLMimeTypeSupported(url)))) {
- frame_->GetDocument()->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kError,
- "Not allowed to navigate top frame to " + url.Protocol() +
- " URL: " + url.ElidedString()));
+ frame_->GetDocument()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kSecurity,
+ mojom::ConsoleMessageLevel::kError,
+ "Not allowed to navigate top frame to " + url.Protocol() +
+ " URL: " + url.ElidedString()));
return;
}
@@ -674,16 +691,22 @@ void FrameLoader::StartNavigation(const FrameLoadRequest& passed_request,
request_context_type = mojom::RequestContextType::IFRAME;
}
resource_request.SetRequestContext(request_context_type);
+ resource_request.SetRequestDestination(
+ DetermineRequestDestinationFromNavigationType(navigation_type));
request.SetFrameType(frame_->IsMainFrame()
- ? network::mojom::RequestContextFrameType::kTopLevel
- : network::mojom::RequestContextFrameType::kNested);
+ ? mojom::RequestContextFrameType::kTopLevel
+ : mojom::RequestContextFrameType::kNested);
mojo::PendingRemote<mojom::blink::NavigationInitiator> navigation_initiator;
- WebContentSecurityPolicyList initiator_csp;
+ WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr> initiator_csp;
+ network::mojom::blink::CSPSourcePtr initiator_self_source;
if (origin_document && origin_document->GetContentSecurityPolicy()
->ExperimentalFeaturesEnabled()) {
initiator_csp = origin_document->GetContentSecurityPolicy()
->ExposeForNavigationalChecks();
+ initiator_self_source = origin_document->GetContentSecurityPolicy()
+ ->GetSelfSource()
+ ->ExposeForNavigationalChecks();
origin_document->NavigationInitiator().BindReceiver(
navigation_initiator.InitWithNewPipeAndPassReceiver());
}
@@ -771,7 +794,7 @@ void FrameLoader::StartNavigation(const FrameLoadRequest& passed_request,
}
const network::mojom::IPAddressSpace initiator_address_space =
- origin_document ? origin_document->AddressSpace()
+ origin_document ? origin_document->GetSecurityContext().AddressSpace()
: network::mojom::IPAddressSpace::kUnknown;
Client()->BeginNavigation(
@@ -783,7 +806,8 @@ void FrameLoader::StartNavigation(const FrameLoadRequest& passed_request,
request.ShouldCheckMainWorldContentSecurityPolicy(),
request.GetBlobURLToken(), request.GetInputStartTime(),
request.HrefTranslate().GetString(), std::move(initiator_csp),
- initiator_address_space, std::move(navigation_initiator));
+ std::move(initiator_self_source), initiator_address_space,
+ std::move(navigation_initiator));
}
static void FillStaticResponseIfNeeded(WebNavigationParams* params,
@@ -865,7 +889,6 @@ static bool ShouldNavigate(WebNavigationParams* params, LocalFrame* frame) {
void FrameLoader::CommitNavigation(
std::unique_ptr<WebNavigationParams> navigation_params,
std::unique_ptr<WebDocumentLoader::ExtraData> extra_data,
- base::OnceClosure call_before_attaching_new_document,
bool is_javascript_url) {
DCHECK(frame_->GetDocument());
DCHECK(Client()->HasWebView());
@@ -914,13 +937,6 @@ void FrameLoader::CommitNavigation(
return;
}
- // TODO(dgozman): navigation type should probably be passed by the caller.
- // It seems incorrect to pass |false| for |have_event| and then use
- // determined navigation type to update resource request.
- WebNavigationType navigation_type = DetermineNavigationType(
- navigation_params->frame_load_type,
- !navigation_params->http_body.IsNull(), false /* have_event */);
-
// Keep track of the current Document HistoryItem as the new DocumentLoader
// might need to copy state from it. Note that the current DocumentLoader
// should always exist, as the initial empty document is committed through
@@ -928,50 +944,58 @@ void FrameLoader::CommitNavigation(
DCHECK(!StateMachine()->CreatingInitialEmptyDocument());
HistoryItem* previous_history_item = GetDocumentLoader()->GetHistoryItem();
- base::Optional<Document::UnloadEventTiming> unload_timing;
- scoped_refptr<SecurityOrigin> security_origin =
- SecurityOrigin::Create(navigation_params->url);
-
- // TODO(dgozman): get rid of provisional document loader and most of the code
- // below. We should probably call DocumentLoader::CommitNavigation directly.
- DocumentLoader* provisional_document_loader = Client()->CreateDocumentLoader(
- frame_, navigation_type, std::move(navigation_params),
- std::move(extra_data));
+ bool loading_url_as_empty_document =
+ !navigation_params->is_static_data &&
+ DocumentLoader::WillLoadUrlAsEmpty(navigation_params->url);
+
+ // Check if the CSP of the response allow should block the new document from
+ // committing before unloading the current document. This will allow to report
+ // violations and display console messages properly.
+ ContentSecurityPolicy* content_security_policy;
+ if (!loading_url_as_empty_document) {
+ content_security_policy =
+ CreateCSP(navigation_params->url,
+ navigation_params->response.ToResourceResponse(),
+ navigation_params->origin_policy);
+ }
+ base::Optional<Document::UnloadEventTiming> unload_timing;
FrameSwapScope frame_swap_scope(frame_owner);
-
{
base::AutoReset<bool> scoped_committing(&committing_navigation_, true);
- if (is_javascript_url)
- provisional_document_loader->SetLoadingJavaScriptUrl();
progress_tracker_->ProgressStarted();
- provisional_document_loader_ = provisional_document_loader;
frame_->GetFrameScheduler()->DidStartProvisionalLoad(frame_->IsMainFrame());
probe::DidStartProvisionalLoad(frame_);
- virtual_time_pauser_.PauseVirtualTime();
- provisional_document_loader_->StartLoading();
- virtual_time_pauser_.UnpauseVirtualTime();
DCHECK(Client()->HasWebView());
+ scoped_refptr<SecurityOrigin> security_origin =
+ SecurityOrigin::Create(navigation_params->url);
if (!DetachDocument(security_origin.get(), &unload_timing))
return;
}
tls_version_warning_origins_.clear();
- // Following the call to StartLoading, the provisional DocumentLoader state
- // has taken into account all redirects that happened during navigation. Its
- // HistoryItem can be properly updated for the commit, using the HistoryItem
- // of the previous Document.
- provisional_document_loader_->SetHistoryItemStateForCommit(
- previous_history_item, provisional_document_loader_->LoadType(),
- DocumentLoader::HistoryNavigationType::kDifferentDocument);
+ // TODO(dgozman): navigation type should probably be passed by the caller.
+ // It seems incorrect to pass |false| for |have_event| and then use
+ // determined navigation type to update resource request.
+ WebNavigationType navigation_type = DetermineNavigationType(
+ navigation_params->frame_load_type,
+ !navigation_params->http_body.IsNull(), false /* have_event */);
+
+ // TODO(dgozman): get rid of provisional document loader and most of the code
+ // below. We should probably call DocumentLoader::CommitNavigation directly.
+ DocumentLoader* new_document_loader = Client()->CreateDocumentLoader(
+ frame_, navigation_type, content_security_policy,
+ std::move(navigation_params), std::move(extra_data));
+
+ CommitDocumentLoader(new_document_loader, unload_timing,
+ previous_history_item,
+ is_javascript_url ? CommitReason::kJavascriptUrl
+ : CommitReason::kRegular);
- CommitDocumentLoader(provisional_document_loader_.Release(), unload_timing,
- true /* dispatch_did_start */,
- std::move(call_before_attaching_new_document),
- !is_javascript_url /* dispatch_did_commit */);
+ RestoreScrollPositionAndViewState();
TakeObjectSnapshot();
}
@@ -1013,7 +1037,6 @@ void FrameLoader::StopAllLoaders() {
frame_->GetDocument()->CancelParsing();
if (document_loader_)
document_loader_->StopLoading();
- DetachDocumentLoader(provisional_document_loader_);
CancelClientNavigation();
DidFinishNavigation(FrameLoader::NavigationFinishState::kSuccess);
@@ -1021,12 +1044,12 @@ void FrameLoader::StopAllLoaders() {
}
void FrameLoader::DidAccessInitialDocument() {
- if (frame_->IsMainFrame()) {
+ if (frame_->IsMainFrame() && !has_accessed_initial_document_) {
+ has_accessed_initial_document_ = true;
// Forbid script execution to prevent re-entering V8, since this is called
// from a binding security check.
ScriptForbiddenScope forbid_scripts;
- if (Client())
- Client()->DidAccessInitialDocument();
+ frame_->GetLocalFrameHostRemote().DidAccessInitialDocument();
}
}
@@ -1034,7 +1057,7 @@ bool FrameLoader::DetachDocument(
SecurityOrigin* committing_origin,
base::Optional<Document::UnloadEventTiming>* timing) {
PluginScriptForbiddenScope forbid_plugin_destructor_scripting;
- DocumentLoader* pdl = provisional_document_loader_;
+ ClientNavigationState* client_navigation = client_navigation_.get();
// Don't allow this frame to navigate anymore. This line is needed for
// navigation triggered from children's unload handlers. Blocking navigations
@@ -1060,7 +1083,7 @@ bool FrameLoader::DetachDocument(
if (!frame_->Client())
return false;
// FrameNavigationDisabler should prevent another load from starting.
- DCHECK_EQ(provisional_document_loader_, pdl);
+ DCHECK_EQ(client_navigation_.get(), client_navigation);
// detachFromFrame() will abort XHRs that haven't completed, which can trigger
// event listeners for 'abort'. These event listeners might call
// window.stop(), which will in turn detach the provisional document loader.
@@ -1073,7 +1096,7 @@ bool FrameLoader::DetachDocument(
if (!frame_->Client())
return false;
// FrameNavigationDisabler should prevent another load from starting.
- DCHECK_EQ(provisional_document_loader_, pdl);
+ DCHECK_EQ(client_navigation_.get(), client_navigation);
// No more events will be dispatched so detach the Document.
// TODO(yoav): Should we also be nullifying domWindow's document (or
@@ -1088,12 +1111,28 @@ bool FrameLoader::DetachDocument(
void FrameLoader::CommitDocumentLoader(
DocumentLoader* document_loader,
const base::Optional<Document::UnloadEventTiming>& unload_timing,
- bool dispatch_did_start,
- base::OnceClosure call_before_attaching_new_document,
- bool dispatch_did_commit) {
+ HistoryItem* previous_history_item,
+ CommitReason commit_reason) {
document_loader_ = document_loader;
CHECK(document_loader_);
+ if (commit_reason == CommitReason::kJavascriptUrl)
+ document_loader_->SetLoadingJavaScriptUrl();
+
+ virtual_time_pauser_.PauseVirtualTime();
+ document_loader_->StartLoading();
+ virtual_time_pauser_.UnpauseVirtualTime();
+
+ if (commit_reason != CommitReason::kInitialization) {
+ // Following the call to StartLoading, the DocumentLoader state has taken
+ // into account all redirects that happened during navigation. Its
+ // HistoryItem can be properly updated for the commit, using the HistoryItem
+ // of the previous Document.
+ document_loader_->SetHistoryItemStateForCommit(
+ previous_history_item, document_loader_->LoadType(),
+ DocumentLoader::HistoryNavigationType::kDifferentDocument);
+ }
+
// Update the DocumentLoadTiming with the timings from the previous document
// unload event.
if (unload_timing.has_value()) {
@@ -1114,16 +1153,11 @@ void FrameLoader::CommitDocumentLoader(
{
FrameNavigationDisabler navigation_disabler(*frame_);
- // TODO(https://crbug.com/855189): replace DispatchDidStartProvisionalLoad,
- // call_before_attaching_new_document and DispatchDidCommitLoad with a
- // single call.
- if (dispatch_did_start)
- Client()->DispatchDidStartProvisionalLoad(document_loader_);
- std::move(call_before_attaching_new_document).Run();
- Client()->DidCreateNewDocument();
- if (dispatch_did_commit) {
- // TODO(https://crbug.com/855189): Do not make exceptions
- // for javascript urls.
+ if (commit_reason == CommitReason::kInitialization) {
+ Client()->DidCreateInitialEmptyDocument();
+ } else if (commit_reason == CommitReason::kJavascriptUrl) {
+ Client()->DidCommitJavascriptUrlNavigation(document_loader_);
+ } else {
Client()->DispatchDidCommitLoad(
document_loader_->GetHistoryItem(),
DocumentLoader::LoadTypeToCommitType(document_loader_->LoadType()),
@@ -1132,6 +1166,11 @@ void FrameLoader::CommitDocumentLoader(
// TODO(dgozman): make DidCreateScriptContext notification call currently
// triggered by installing new document happen here, after commit.
}
+ if (commit_reason != CommitReason::kInitialization) {
+ // Note: this must be called after DispatchDidCommitLoad() for
+ // metrics to be correctly sent to the browser process.
+ document_loader_->GetUseCounterHelper().DidCommitLoad(frame_);
+ }
if (document_loader_->LoadType() == WebFrameLoadType::kBackForward) {
if (Page* page = frame_->GetPage())
page->HistoryNavigationVirtualTimePauser().UnpauseVirtualTime();
@@ -1142,22 +1181,21 @@ void FrameLoader::CommitDocumentLoader(
}
void FrameLoader::RestoreScrollPositionAndViewState() {
- if (!frame_->GetPage() || !GetDocumentLoader() ||
+ if (RuntimeEnabledFeatures::ForceLoadAtTopEnabled(frame_->GetDocument()) ||
+ !frame_->GetPage() || !GetDocumentLoader() ||
!GetDocumentLoader()->GetHistoryItem() ||
!GetDocumentLoader()->GetHistoryItem()->GetViewState() ||
- in_restore_scroll_) {
+ !GetDocumentLoader()->NavigationScrollAllowed()) {
return;
}
- base::AutoReset<bool> in_restore_scroll(&in_restore_scroll_, true);
RestoreScrollPositionAndViewState(
- GetDocumentLoader()->LoadType(), false /* is_same_document */,
+ GetDocumentLoader()->LoadType(),
*GetDocumentLoader()->GetHistoryItem()->GetViewState(),
GetDocumentLoader()->GetHistoryItem()->ScrollRestorationType());
}
void FrameLoader::RestoreScrollPositionAndViewState(
WebFrameLoadType load_type,
- bool is_same_document,
const HistoryItem::ViewState& view_state,
HistoryScrollRestorationType scroll_restoration_type) {
LocalFrameView* view = frame_->View();
@@ -1169,81 +1207,12 @@ void FrameLoader::RestoreScrollPositionAndViewState(
if (!NeedsHistoryItemRestore(load_type))
return;
- bool should_restore_scroll =
- scroll_restoration_type != kScrollRestorationManual;
- bool should_restore_scale = view_state.page_scale_factor_;
-
- // This tries to balance:
- // 1. restoring as soon as possible.
- // 2. not overriding user scroll (TODO(majidvp): also respect user scale).
- // 3. detecting clamping to avoid repeatedly popping the scroll position down
- // as the page height increases.
- // 4. forcing a layout if necessary to avoid clamping.
- // 5. ignoring clamp detection if scroll state is not being restored, if load
- // is complete, or if the navigation is same-document (as the new page may
- // be smaller than the previous page).
- bool can_restore_without_clamping =
- view->LayoutViewport()->ClampScrollOffset(view_state.scroll_offset_) ==
- view_state.scroll_offset_;
-
- bool should_force_clamping = !frame_->IsLoading() || is_same_document;
- // Here |can_restore_without_clamping| is false, but layout might be necessary
- // to ensure correct content size.
- if (!can_restore_without_clamping && should_force_clamping)
- frame_->GetDocument()->UpdateStyleAndLayout();
-
- bool can_restore_without_annoying_user =
- !GetDocumentLoader()->GetInitialScrollState().was_scrolled_by_user &&
- (can_restore_without_clamping || should_force_clamping ||
- !should_restore_scroll);
- if (!can_restore_without_annoying_user)
- return;
-
- if (should_restore_scroll) {
- // TODO(pnoland): attempt to restore the anchor in more places than this.
- // Anchor-based restore should allow for earlier restoration.
- bool did_restore = view->LayoutViewport()->RestoreScrollAnchor(
- {view_state.scroll_anchor_data_.selector_,
- LayoutPoint(view_state.scroll_anchor_data_.offset_.x,
- view_state.scroll_anchor_data_.offset_.y),
- view_state.scroll_anchor_data_.simhash_});
- if (!did_restore) {
- view->LayoutViewport()->SetScrollOffset(view_state.scroll_offset_,
- kProgrammaticScroll);
- }
- }
-
- // For main frame restore scale and visual viewport position
- if (frame_->IsMainFrame()) {
- ScrollOffset visual_viewport_offset(
- view_state.visual_viewport_scroll_offset_);
-
- // If the visual viewport's offset is (-1, -1) it means the history item
- // is an old version of HistoryItem so distribute the scroll between
- // the main frame and the visual viewport as best as we can.
- if (visual_viewport_offset.Width() == -1 &&
- visual_viewport_offset.Height() == -1) {
- visual_viewport_offset =
- view_state.scroll_offset_ - view->LayoutViewport()->GetScrollOffset();
- }
-
- VisualViewport& visual_viewport = frame_->GetPage()->GetVisualViewport();
- if (should_restore_scale && should_restore_scroll) {
- visual_viewport.SetScaleAndLocation(
- view_state.page_scale_factor_, visual_viewport.IsPinchGestureActive(),
- FloatPoint(visual_viewport_offset));
- } else if (should_restore_scale) {
- visual_viewport.SetScale(view_state.page_scale_factor_);
- } else if (should_restore_scroll) {
- visual_viewport.SetLocation(FloatPoint(visual_viewport_offset));
- }
-
- if (ScrollingCoordinator* scrolling_coordinator =
- frame_->GetPage()->GetScrollingCoordinator())
- scrolling_coordinator->FrameViewRootLayerDidChange(view);
- }
+ view->LayoutViewport()->SetPendingHistoryRestoreScrollOffset(
+ view_state, scroll_restoration_type != kScrollRestorationManual);
+ view->GetScrollableArea()->SetPendingHistoryRestoreScrollOffset(
+ view_state, scroll_restoration_type != kScrollRestorationManual);
- GetDocumentLoader()->GetInitialScrollState().did_restore_from_history = true;
+ view->ScheduleAnimation();
}
String FrameLoader::UserAgent() const {
@@ -1253,21 +1222,15 @@ String FrameLoader::UserAgent() const {
return user_agent;
}
-blink::UserAgentMetadata FrameLoader::UserAgentMetadata() const {
- // TODO(mkwst): Support overrides.
+base::Optional<blink::UserAgentMetadata> FrameLoader::UserAgentMetadata()
+ const {
+ // TODO(mkwst): Support overrides probes for devtools support.
return Client()->UserAgentMetadata();
}
void FrameLoader::Detach() {
frame_->GetDocument()->CancelParsing();
DetachDocumentLoader(document_loader_);
- if (provisional_document_loader_) {
- // Suppress client notification about failed provisional
- // load - it does not bring any value when the frame is
- // being detached anyway.
- provisional_document_loader_->SetSentDidFinishLoad();
- DetachDocumentLoader(provisional_document_loader_);
- }
ClearClientNavigation();
committing_navigation_ = false;
DidFinishNavigation(FrameLoader::NavigationFinishState::kSuccess);
@@ -1304,10 +1267,6 @@ bool FrameLoader::MaybeRenderFallbackContent() {
return true;
}
-void FrameLoader::DetachProvisionalDocumentLoader() {
- DetachDocumentLoader(provisional_document_loader_);
-}
-
bool FrameLoader::ShouldPerformFragmentNavigation(bool is_form_submission,
const String& http_method,
WebFrameLoadType load_type,
@@ -1315,7 +1274,7 @@ bool FrameLoader::ShouldPerformFragmentNavigation(bool is_form_submission,
// We don't do this if we are submitting a form with method other than "GET",
// explicitly reloading, currently displaying a frameset, or if the URL does
// not have a fragment.
- return DeprecatedEqualIgnoringCase(http_method, http_names::kGET) &&
+ return EqualIgnoringASCIICase(http_method, http_names::kGET) &&
!IsReloadLoadType(load_type) &&
load_type != WebFrameLoadType::kBackForward &&
url.HasFragmentIdentifier() &&
@@ -1351,12 +1310,16 @@ void FrameLoader::ProcessFragment(const KURL& url,
// restoration type is manual, then we should not override it unless this
// is a same document reload.
bool should_scroll_to_fragment =
- (load_start_type == kNavigationWithinSameDocument &&
- !IsBackForwardLoadType(frame_load_type)) ||
- (!GetDocumentLoader()->GetInitialScrollState().did_restore_from_history &&
- !(GetDocumentLoader()->GetHistoryItem() &&
- GetDocumentLoader()->GetHistoryItem()->ScrollRestorationType() ==
- kScrollRestorationManual));
+ !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,
@@ -1442,7 +1405,7 @@ void FrameLoader::DidDropNavigation() {
void FrameLoader::MarkAsLoading() {
// This should only be called for initial history navigation in child frame.
- DCHECK(!provisional_document_loader_ && !client_navigation_);
+ DCHECK(!client_navigation_);
DCHECK(frame_->GetDocument()->IsLoadCompleted());
DCHECK(frame_->GetDocument()->HasFinishedParsing());
progress_tracker_->ProgressStarted();
@@ -1461,10 +1424,11 @@ bool FrameLoader::ShouldReuseDefaultView(
// be considered when deciding whether to reuse it.
// Spec:
// https://html.spec.whatwg.org/C/#initialise-the-document-object
- if ((csp && (csp->GetSandboxMask() & WebSandboxFlags::kOrigin) !=
- WebSandboxFlags::kNone) ||
- ((EffectiveSandboxFlags() & WebSandboxFlags::kOrigin) !=
- WebSandboxFlags::kNone)) {
+ if ((csp &&
+ (csp->GetSandboxMask() & mojom::blink::WebSandboxFlags::kOrigin) !=
+ mojom::blink::WebSandboxFlags::kNone) ||
+ ((EffectiveSandboxFlags() & mojom::blink::WebSandboxFlags::kOrigin) !=
+ mojom::blink::WebSandboxFlags::kNone)) {
return false;
}
@@ -1482,13 +1446,6 @@ bool FrameLoader::CancelProvisionalLoaderForNewNavigation() {
if (!frame_->GetPage())
return false;
- DetachDocumentLoader(provisional_document_loader_);
- // Detaching the provisional DocumentLoader above may leave the frame without
- // any loading DocumentLoader. It can causes the 'load' event to fire, which
- // can be used to detach this frame.
- if (!frame_->GetPage())
- return false;
-
// For client navigations, don't send failure callbacks when simply
// replacing client navigation with a DocumentLoader.
ClearClientNavigation();
@@ -1516,6 +1473,19 @@ void FrameLoader::CancelClientNavigation() {
void FrameLoader::DispatchDocumentElementAvailable() {
ScriptForbiddenScope forbid_scripts;
+
+ // Notify the browser about non-blank documents loading in the top frame.
+ KURL url = frame_->GetDocument()->Url();
+ if (url.IsValid() && !url.IsAboutBlankURL()) {
+ if (frame_->IsMainFrame()) {
+ // For now, don't remember plugin zoom values. We don't want to mix them
+ // with normal web content (i.e. a fixed layout plugin would usually want
+ // them different).
+ frame_->GetLocalFrameHostRemote().DocumentAvailableInMainFrame(
+ frame_->GetDocument()->IsPluginDocument());
+ }
+ }
+
Client()->DocumentElementAvailable();
}
@@ -1561,6 +1531,23 @@ void FrameLoader::DispatchDidClearWindowObjectInMainWorld() {
SandboxFlags FrameLoader::EffectiveSandboxFlags() const {
SandboxFlags flags = forced_sandbox_flags_;
+ if (frame_->Owner()) {
+ // Cannot use flags in frame_owner->GetFramePolicy().sandbox_flags, because
+ // frame_owner's frame policy is volatile and can be changed by javascript
+ // before navigation commits. Uses a snapshot
+ // value(frame_owner_sandbox_flags_) which is set in
+ // DocumentInit::WithFramePolicy instead. crbug.com/1026627
+ DCHECK(frame_owner_sandbox_flags_.has_value());
+ flags |= frame_owner_sandbox_flags_.value();
+ }
+ // Frames need to inherit the sandbox flags of their parent frame.
+ if (Frame* parent_frame = frame_->Tree().Parent())
+ flags |= parent_frame->GetSecurityContext()->GetSandboxFlags();
+ return flags;
+}
+
+SandboxFlags FrameLoader::PendingEffectiveSandboxFlags() const {
+ SandboxFlags flags = forced_sandbox_flags_;
if (FrameOwner* frame_owner = frame_->Owner())
flags |= frame_owner->GetFramePolicy().sandbox_flags;
// Frames need to inherit the sandbox flags of their parent frame.
@@ -1573,7 +1560,7 @@ void FrameLoader::ModifyRequestForCSP(
ResourceRequest& resource_request,
const FetchClientSettingsObject* fetch_client_settings_object,
Document* document_for_logging,
- network::mojom::RequestContextFrameType frame_type) const {
+ mojom::RequestContextFrameType frame_type) const {
if (!RequiredCSP().IsEmpty()) {
DCHECK(
ContentSecurityPolicy::IsValidCSPAttr(RequiredCSP().GetString(), ""));
@@ -1584,7 +1571,7 @@ void FrameLoader::ModifyRequestForCSP(
// Tack an 'Upgrade-Insecure-Requests' header to outgoing navigational
// requests, as described in
// https://w3c.github.io/webappsec-upgrade-insecure-requests/#feature-detect
- if (frame_type != network::mojom::RequestContextFrameType::kNone) {
+ if (frame_type != mojom::RequestContextFrameType::kNone) {
// Early return if the request has already been upgraded.
if (!resource_request.HttpHeaderField(http_names::kUpgradeInsecureRequests)
.IsNull()) {
@@ -1596,7 +1583,9 @@ void FrameLoader::ModifyRequestForCSP(
}
MixedContentChecker::UpgradeInsecureRequest(
- resource_request, fetch_client_settings_object, document_for_logging,
+ resource_request, fetch_client_settings_object,
+ document_for_logging ? document_for_logging->ToExecutionContext()
+ : nullptr,
frame_type, frame_->GetContentSettingsClient());
}
@@ -1664,7 +1653,7 @@ void FrameLoader::ReportLegacyTLSVersion(const KURL& url,
tls_version_warning_origins_.insert(origin);
// To avoid spamming the console, use verbose message level for subframe
// resources, and only use the warning level for main-frame resources.
- frame_->Console().AddMessage(ConsoleMessage::Create(
+ frame_->Console().AddMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
frame_->IsMainFrame() ? mojom::ConsoleMessageLevel::kWarning
: mojom::ConsoleMessageLevel::kVerbose,
@@ -1683,10 +1672,6 @@ std::unique_ptr<TracedValue> FrameLoader::ToTracedValue() const {
traced_value->EndDictionary();
traced_value->SetBoolean("isLoadingMainFrame", frame_->IsMainFrame());
traced_value->SetString("stateMachine", state_machine_.ToString());
- traced_value->SetString("provisionalDocumentLoaderURL",
- provisional_document_loader_
- ? provisional_document_loader_->Url().GetString()
- : String());
traced_value->SetString(
"documentLoaderURL",
document_loader_ ? document_loader_->Url().GetString() : String());
@@ -1707,6 +1692,75 @@ bool FrameLoader::IsClientNavigationInitialHistoryLoad() {
client_navigation_->is_history_navigation_in_new_frame;
}
+ContentSecurityPolicy* FrameLoader::CreateCSP(
+ const KURL& url,
+ const ResourceResponse& response,
+ const base::Optional<WebOriginPolicy>& origin_policy) {
+ auto* csp = MakeGarbageCollected<ContentSecurityPolicy>();
+
+ if (url.IsAboutSrcdocURL()) {
+ // about:srcdoc always inherits CSP from its parent.
+ ContentSecurityPolicy* parent_csp = frame_->Tree()
+ .Parent()
+ ->GetSecurityContext()
+ ->GetContentSecurityPolicy();
+ csp->CopyStateFrom(parent_csp);
+ csp->CopyPluginTypesFrom(parent_csp);
+ return csp;
+ }
+
+ csp->SetOverrideURLForSelf(response.CurrentRequestUrl());
+
+ if (!frame_->GetSettings()->BypassCSP()) {
+ csp->DidReceiveHeaders(ContentSecurityPolicyResponseHeaders(response));
+
+ // Handle OriginPolicy. We can skip the entire block if the OP policies have
+ // already been passed down.
+ if (origin_policy.has_value() &&
+ !csp->HasPolicyFromSource(
+ network::mojom::ContentSecurityPolicySource::kOriginPolicy)) {
+ for (const auto& policy : origin_policy->content_security_policies) {
+ csp->DidReceiveHeader(
+ policy, network::mojom::ContentSecurityPolicyType::kEnforce,
+ network::mojom::ContentSecurityPolicySource::kOriginPolicy);
+ }
+
+ for (const auto& policy :
+ origin_policy->content_security_policies_report_only) {
+ csp->DidReceiveHeader(
+ policy, network::mojom::ContentSecurityPolicyType::kReport,
+ network::mojom::ContentSecurityPolicySource::kOriginPolicy);
+ }
+ }
+ }
+ if (!base::FeatureList::IsEnabled(
+ network::features::kOutOfBlinkFrameAncestors)) {
+ if (!csp->AllowAncestors(frame_, response.CurrentRequestUrl())) {
+ return nullptr;
+ }
+ }
+
+ if (!frame_->GetSettings()->BypassCSP() && !RequiredCSP().IsEmpty()) {
+ const SecurityOrigin* parent_security_origin =
+ frame_->Tree().Parent()->GetSecurityContext()->GetSecurityOrigin();
+ if (parent_security_origin &&
+ ContentSecurityPolicy::ShouldEnforceEmbeddersPolicy(
+ response, parent_security_origin)) {
+ csp->AddPolicyFromHeaderValue(
+ RequiredCSP(), network::mojom::ContentSecurityPolicyType::kEnforce,
+ network::mojom::ContentSecurityPolicySource::kHTTP);
+ } else {
+ auto* required_csp = MakeGarbageCollected<ContentSecurityPolicy>();
+ required_csp->AddPolicyFromHeaderValue(
+ RequiredCSP(), network::mojom::ContentSecurityPolicyType::kEnforce,
+ network::mojom::ContentSecurityPolicySource::kHTTP);
+ if (!required_csp->Subsumes(*csp))
+ return nullptr;
+ }
+ }
+ return csp;
+}
+
STATIC_ASSERT_ENUM(kWebHistoryScrollRestorationManual,
kScrollRestorationManual);
STATIC_ASSERT_ENUM(kWebHistoryScrollRestorationAuto, kScrollRestorationAuto);
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 c16d98c82a5..bda3ebc0635 100644
--- a/chromium/third_party/blink/renderer/core/loader/frame_loader.h
+++ b/chromium/third_party/blink/renderer/core/loader/frame_loader.h
@@ -43,6 +43,7 @@
#include "third_party/blink/public/web/web_document_loader.h"
#include "third_party/blink/public/web/web_frame_load_type.h"
#include "third_party/blink/public/web/web_navigation_type.h"
+#include "third_party/blink/public/web/web_origin_policy.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_types.h"
@@ -92,7 +93,7 @@ class CORE_EXPORT FrameLoader final {
// For reloads, an appropriate WebFrameLoadType should be given. Otherwise,
// kStandard should be used (and the final WebFrameLoadType
// will be computed).
- void StartNavigation(const FrameLoadRequest&,
+ void StartNavigation(FrameLoadRequest&,
WebFrameLoadType = WebFrameLoadType::kStandard);
// Called when the browser process has asked this renderer process to commit
@@ -102,8 +103,6 @@ class CORE_EXPORT FrameLoader final {
void CommitNavigation(
std::unique_ptr<WebNavigationParams> navigation_params,
std::unique_ptr<WebDocumentLoader::ExtraData> extra_data,
- base::OnceClosure call_before_attaching_new_document =
- base::DoNothing::Once(),
bool is_javascript_url = false);
// Called before the browser process is asked to navigate this frame, to mark
@@ -134,7 +133,7 @@ class CORE_EXPORT FrameLoader final {
void DidExplicitOpen();
String UserAgent() const;
- blink::UserAgentMetadata UserAgentMetadata() const;
+ base::Optional<blink::UserAgentMetadata> UserAgentMetadata() const;
void DispatchDidClearWindowObjectInMainWorld();
void DispatchDidClearDocumentOfWindowObject();
@@ -143,14 +142,28 @@ class CORE_EXPORT FrameLoader final {
// The following sandbox flags will be forced, regardless of changes to the
// sandbox attribute of any parent frames.
- void ForceSandboxFlags(WebSandboxFlags flags) {
+ void ForceSandboxFlags(mojom::blink::WebSandboxFlags flags) {
forced_sandbox_flags_ |= flags;
}
+
+ // Set frame_owner's effective sandbox flags, which are sandbox flags value
+ // at the beginning of navigation.
+ void SetFrameOwnerSandboxFlags(mojom::blink::WebSandboxFlags flags) {
+ frame_owner_sandbox_flags_ = flags;
+ }
+
+ // Includes the collection of forced, inherited, and FrameOwner's sandbox
+ // flags, where the FrameOwner's flag is snapshotted from the last committed
+ // navigation. Note: with FeaturePolicyForSandbox the frame owner's sandbox
+ // flags only includes the flags which are *not* implemented as feature
+ // policies already present in the FrameOwner's ContainerPolicy.
+ mojom::blink::WebSandboxFlags EffectiveSandboxFlags() const;
+
// Includes the collection of forced, inherited, and FrameOwner's sandbox
// flags. Note: with FeaturePolicyForSandbox the frame owner's sandbox flags
// only includes the flags which are *not* implemented as feature policies
// already present in the FrameOwner's ContainerPolicy.
- WebSandboxFlags EffectiveSandboxFlags() const;
+ mojom::blink::WebSandboxFlags PendingEffectiveSandboxFlags() const;
// Modifying itself is done based on |fetch_client_settings_object|.
// |document_for_logging| is used only for logging, use counters,
@@ -159,7 +172,7 @@ class CORE_EXPORT FrameLoader final {
ResourceRequest&,
const FetchClientSettingsObject* fetch_client_settings_object,
Document* document_for_logging,
- network::mojom::RequestContextFrameType) const;
+ mojom::RequestContextFrameType) const;
void ReportLegacyTLSVersion(const KURL& url,
bool is_subresource,
bool is_ad_resource);
@@ -216,9 +229,8 @@ class CORE_EXPORT FrameLoader final {
// Like ClearClientNavigation, but also notifies the client to actually cancel
// the navigation.
void CancelClientNavigation();
- void DetachProvisionalDocumentLoader();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
void DidDropNavigation();
void MarkAsLoading();
@@ -231,6 +243,10 @@ class CORE_EXPORT FrameLoader final {
bool IsClientNavigationInitialHistoryLoad();
+ bool HasAccessedInitialDocument() { return has_accessed_initial_document_; }
+
+ static bool NeedsHistoryItemRestore(WebFrameLoadType type);
+
private:
bool AllowRequestForThisFrame(const FrameLoadRequest&);
WebFrameLoadType DetermineFrameLoadType(const KURL& url,
@@ -252,7 +268,6 @@ class CORE_EXPORT FrameLoader final {
void ClearClientNavigation();
void RestoreScrollPositionAndViewState(WebFrameLoadType,
- bool is_same_document,
const HistoryItem::ViewState&,
HistoryScrollRestorationType);
@@ -262,13 +277,26 @@ class CORE_EXPORT FrameLoader final {
std::unique_ptr<TracedValue> ToTracedValue() const;
void TakeObjectSnapshot() const;
+ enum class CommitReason {
+ // Committing initial empty document.
+ kInitialization,
+ // Committing navigation as a result of javascript URL execution.
+ kJavascriptUrl,
+ // All other navigations.
+ kRegular
+ };
// Commits the given |document_loader|.
- void CommitDocumentLoader(
- DocumentLoader* document_loader,
- const base::Optional<Document::UnloadEventTiming>&,
- bool dispatch_did_start,
- base::OnceClosure call_before_attaching_new_document,
- bool dispatch_did_commit);
+ void CommitDocumentLoader(DocumentLoader* document_loader,
+ const base::Optional<Document::UnloadEventTiming>&,
+ HistoryItem* previous_history_item,
+ CommitReason);
+
+ // Creates CSP based on |response| and checks that they allow loading |url|.
+ // Returns nullptr if the check fails.
+ ContentSecurityPolicy* CreateCSP(
+ const KURL& url,
+ const ResourceResponse& response,
+ const base::Optional<WebOriginPolicy>& origin_policy);
LocalFrameClient* Client() const;
@@ -282,13 +310,8 @@ class CORE_EXPORT FrameLoader final {
Member<ProgressTracker> progress_tracker_;
- // Document loaders for the three phases of frame loading. Note that while a
- // new request is being loaded, the old document loader may still be
- // referenced. E.g. while a new request is in the "policy" state, the old
- // document loader may be consulted in particular as it makes sense to imply
- // certain settings on the new loader.
+ // Document loader for frame loading.
Member<DocumentLoader> document_loader_;
- Member<DocumentLoader> provisional_document_loader_;
// This struct holds information about a navigation, which is being
// initiated by the client through the browser process, until the navigation
@@ -299,13 +322,20 @@ class CORE_EXPORT FrameLoader final {
};
std::unique_ptr<ClientNavigationState> client_navigation_;
- bool in_restore_scroll_;
-
- WebSandboxFlags forced_sandbox_flags_;
+ mojom::blink::WebSandboxFlags forced_sandbox_flags_;
+ // A snapshot value of frame_owner's sandbox flags states at the beginning of
+ // navigation. For main frame which does not have a frame owner, the value is
+ // base::nullopt.
+ // The snapshot value is needed because of potential racing conditions on
+ // sandbox attribute on iframe element.
+ // crbug.com/1026627
+ base::Optional<mojom::blink::WebSandboxFlags> frame_owner_sandbox_flags_ =
+ base::nullopt;
bool dispatching_did_clear_window_object_in_main_world_;
bool detached_;
bool committing_navigation_ = false;
+ bool has_accessed_initial_document_ = false;
WebScopedVirtualTimePauser virtual_time_pauser_;
diff --git a/chromium/third_party/blink/renderer/core/loader/frame_loader_types.h b/chromium/third_party/blink/renderer/core/loader/frame_loader_types.h
index fa84bd0dfed..b00161b30f8 100644
--- a/chromium/third_party/blink/renderer/core/loader/frame_loader_types.h
+++ b/chromium/third_party/blink/renderer/core/loader/frame_loader_types.h
@@ -74,6 +74,7 @@ enum SinglePageAppNavigationType {
enum class ClientNavigationReason {
kFormSubmissionGet,
kFormSubmissionPost,
+ kAnchorClick,
kHttpHeaderRefresh,
kFrameNavigation,
kMetaTagRefresh,
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 cc6640d321b..12c1fb1da2b 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
@@ -24,7 +24,7 @@ FrameResourceFetcherProperties::FrameResourceFetcherProperties(
: frame_or_imported_document_(frame_or_imported_document),
fetch_client_settings_object_(
MakeGarbageCollected<FetchClientSettingsObjectImpl>(
- frame_or_imported_document.GetDocument())),
+ *frame_or_imported_document.GetDocument().ToExecutionContext())),
web_bundle_physical_url_(
frame_or_imported_document_->GetMasterDocumentLoader()
.WebBundlePhysicalUrl()) {}
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 a9131543ff6..459e06d9fe3 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(blink::Visitor* visitor) {
+void HistoryItem::Trace(Visitor* visitor) {
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 5d29c48f099..b3d21d3c893 100644
--- a/chromium/third_party/blink/renderer/core/loader/history_item.h
+++ b/chromium/third_party/blink/renderer/core/loader/history_item.h
@@ -50,8 +50,6 @@ enum class FetchCacheMode : int32_t;
class CORE_EXPORT HistoryItem final : public GarbageCollected<HistoryItem> {
public:
- static HistoryItem* Create() { return MakeGarbageCollected<HistoryItem>(); }
-
HistoryItem();
~HistoryItem();
@@ -121,7 +119,7 @@ class CORE_EXPORT HistoryItem final : public GarbageCollected<HistoryItem> {
ResourceRequest GenerateResourceRequest(mojom::FetchCacheMode);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
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 9e41af99e7a..9e8ed4ee4f1 100644
--- a/chromium/third_party/blink/renderer/core/loader/http_equiv.cc
+++ b/chromium/third_party/blink/renderer/core/loader/http_equiv.cc
@@ -16,12 +16,13 @@
#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/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/weborigin/kurl.h"
-#include "third_party/blink/renderer/platform/weborigin/security_violation_reporting_policy.h"
+#include "third_party/blink/renderer/platform/weborigin/reporting_disposition.h"
namespace blink {
@@ -110,7 +111,7 @@ void HttpEquiv::Process(Document& document,
} else if (EqualIgnoringASCIICase(equiv, "x-dns-prefetch-control")) {
document.ParseDNSPrefetchControlHeader(content);
} else if (EqualIgnoringASCIICase(equiv, "x-frame-options")) {
- document.AddConsoleMessage(ConsoleMessage::Create(
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kSecurity,
mojom::ConsoleMessageLevel::kError,
"X-Frame-Options may only be set via an HTTP header sent along with a "
@@ -142,13 +143,13 @@ void HttpEquiv::ProcessHttpEquivContentSecurityPolicy(
return;
if (EqualIgnoringASCIICase(equiv, "content-security-policy")) {
document.GetContentSecurityPolicy()->DidReceiveHeader(
- content, kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceMeta);
+ content, network::mojom::ContentSecurityPolicyType::kEnforce,
+ network::mojom::ContentSecurityPolicySource::kMeta);
} else if (EqualIgnoringASCIICase(equiv,
"content-security-policy-report-only")) {
document.GetContentSecurityPolicy()->DidReceiveHeader(
- content, kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderSourceMeta);
+ content, network::mojom::ContentSecurityPolicyType::kReport,
+ network::mojom::ContentSecurityPolicySource::kMeta);
} else {
NOTREACHED();
}
@@ -195,7 +196,7 @@ void HttpEquiv::ProcessHttpEquivRefresh(Document& document,
if (!document.GetContentSecurityPolicy()->AllowInline(
ContentSecurityPolicy::InlineType::kScript, element, "" /* content */,
"" /* nonce */, NullURL(), OrdinalNumber(),
- SecurityViolationReportingPolicy::kSuppressReporting)) {
+ ReportingDisposition::kSuppressReporting)) {
UseCounter::Count(document,
WebFeature::kMetaRefreshWhenCSPBlocksInlineScript);
}
@@ -206,7 +207,7 @@ void HttpEquiv::ProcessHttpEquivRefresh(Document& document,
void HttpEquiv::ProcessHttpEquivSetCookie(Document& document,
const AtomicString& content,
Element* element) {
- document.AddConsoleMessage(ConsoleMessage::Create(
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kSecurity,
mojom::ConsoleMessageLevel::kError,
String::Format("Blocked setting the `%s` cookie from a `<meta>` tag.",
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 c77f1c1ccf3..eabd1ac445c 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(blink::Visitor* visitor) {
+void HttpRefreshScheduler::Trace(Visitor* visitor) {
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 5381292e363..3eebdd97534 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(blink::Visitor*);
+ void Trace(Visitor*);
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 dd1f4ce89cd..5b910a0a934 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(blink::Visitor* visitor) {
+void IdlenessDetector::Trace(Visitor* visitor) {
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 9325a9d9360..ba49a55c62a 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(blink::Visitor*);
+ void Trace(Visitor*);
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 17d84a4cad7..a5f02639f9b 100644
--- a/chromium/third_party/blink/renderer/core/loader/image_loader.cc
+++ b/chromium/third_party/blink/renderer/core/loader/image_loader.cc
@@ -73,7 +73,7 @@ namespace blink {
namespace {
-bool CheckForUnoptimizedImagePolicy(const Document& document,
+bool CheckForUnoptimizedImagePolicy(Document& document,
ImageResourceContent* new_image) {
if (!new_image)
return false;
@@ -81,8 +81,12 @@ bool CheckForUnoptimizedImagePolicy(const Document& document,
// Render the image as a placeholder image if the image is not sufficiently
// well-compressed, according to the unoptimized image feature policies on
// |document|.
- if (RuntimeEnabledFeatures::UnoptimizedImagePoliciesEnabled(&document) &&
- !new_image->IsAcceptableCompressionRatio(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.ToExecutionContext())) {
return true;
}
@@ -96,7 +100,7 @@ static ImageLoader::BypassMainWorldBehavior ShouldBypassMainWorldCSP(
DCHECK(loader);
DCHECK(loader->GetElement());
if (ContentSecurityPolicy::ShouldBypassMainWorld(
- &loader->GetElement()->GetDocument())) {
+ loader->GetElement()->GetDocument().ToExecutionContext())) {
return ImageLoader::kBypassMainWorldCSP;
}
return ImageLoader::kDoNotBypassMainWorldCSP;
@@ -113,8 +117,9 @@ class ImageLoader::Task {
update_behavior_(update_behavior),
referrer_policy_(referrer_policy),
request_url_(request_url) {
- ExecutionContext& context = loader_->GetElement()->GetDocument();
- probe::AsyncTaskScheduled(&context, "Image", &async_task_id_);
+ ExecutionContext* context =
+ loader_->GetElement()->GetDocument().ToExecutionContext();
+ probe::AsyncTaskScheduled(context, "Image", &async_task_id_);
v8::Isolate* isolate = V8PerIsolateData::MainThreadIsolate();
v8::HandleScope scope(isolate);
// If we're invoked from C++ without a V8 context on the stack, we should
@@ -131,8 +136,9 @@ class ImageLoader::Task {
void Run() {
if (!loader_)
return;
- ExecutionContext& context = loader_->GetElement()->GetDocument();
- probe::AsyncTask async_task(&context, &async_task_id_);
+ ExecutionContext* context =
+ loader_->GetElement()->GetDocument().ToExecutionContext();
+ probe::AsyncTask async_task(context, &async_task_id_);
if (script_state_ && script_state_->ContextIsValid()) {
ScriptState::Scope scope(script_state_);
loader_->DoUpdateFromElement(should_bypass_main_world_csp_,
@@ -167,7 +173,6 @@ class ImageLoader::Task {
ImageLoader::ImageLoader(Element* element)
: element_(element),
image_complete_(true),
- loading_image_document_(false),
suppress_error_events_(false),
was_fully_deferred_(false),
lazy_image_load_state_(LazyImageLoadState::kNone) {
@@ -185,7 +190,7 @@ void ImageLoader::Dispose() {
if (image_content_) {
image_content_->RemoveObserver(this);
image_content_ = nullptr;
- image_resource_for_image_document_ = nullptr;
+ image_content_for_image_document_ = nullptr;
delay_until_image_notify_finished_ = nullptr;
}
}
@@ -264,9 +269,9 @@ void ImageLoader::RejectPendingDecodes(UpdateType update_type) {
}
}
-void ImageLoader::Trace(blink::Visitor* visitor) {
+void ImageLoader::Trace(Visitor* visitor) {
visitor->Trace(image_content_);
- visitor->Trace(image_resource_for_image_document_);
+ visitor->Trace(image_content_for_image_document_);
visitor->Trace(element_);
visitor->Trace(decode_requests_);
}
@@ -302,14 +307,17 @@ bool ImageLoader::ShouldUpdateOnInsertedInto(
}
bool ImageLoader::ImageIsPotentiallyAvailable() const {
+ bool is_lazyload = lazy_image_load_state_ == LazyImageLoadState::kDeferred &&
+ was_fully_deferred_;
+
bool image_has_loaded = image_content_ && !image_content_->IsLoading() &&
!image_content_->ErrorOccurred();
bool image_still_loading = !image_has_loaded && HasPendingActivity() &&
!HasPendingError() &&
!element_->ImageSourceURL().IsEmpty();
bool image_has_image = image_content_ && image_content_->HasImage();
- bool image_is_document = loading_image_document_ && image_content_ &&
- !image_content_->ErrorOccurred();
+ bool image_is_document = element_->GetDocument().IsImageDocument() &&
+ image_content_ && !image_content_->ErrorOccurred();
// Icky special case for deferred images:
// A deferred image is not loading, does have pending activity, does not
@@ -324,27 +332,13 @@ bool ImageLoader::ImageIsPotentiallyAvailable() const {
// ImageResourceContent has non-null image data associated with it, which
// isn't folded into |image_has_loaded| above.
return (image_has_loaded && image_has_image) || image_still_loading ||
- image_is_document;
+ image_is_document || is_lazyload;
}
void ImageLoader::ClearImage() {
SetImageWithoutConsideringPendingLoadEvent(nullptr);
}
-void ImageLoader::SetImageForImageDocument(ImageResource* new_image_resource) {
- DCHECK(loading_image_document_);
- DCHECK(new_image_resource);
- DCHECK(new_image_resource->GetContent());
-
- image_resource_for_image_document_ = new_image_resource;
- SetImageWithoutConsideringPendingLoadEvent(new_image_resource->GetContent());
-
- // |image_complete_| is always true for ImageDocument loading, while the
- // loading is just started.
- // TODO(hiroshige): clean up the behavior of flags. https://crbug.com/719759
- image_complete_ = true;
-}
-
void ImageLoader::SetImageWithoutConsideringPendingLoadEvent(
ImageResourceContent* new_image_content) {
DCHECK(failed_load_url_.IsEmpty());
@@ -372,8 +366,10 @@ static void ConfigureRequest(
ImageLoader::BypassMainWorldBehavior bypass_behavior,
Element& element,
const ClientHintsPreferences& client_hints_preferences) {
- if (bypass_behavior == ImageLoader::kBypassMainWorldCSP)
- params.SetContentSecurityCheck(kDoNotCheckContentSecurityPolicy);
+ if (bypass_behavior == ImageLoader::kBypassMainWorldCSP) {
+ params.SetContentSecurityCheck(
+ network::mojom::CSPDisposition::DO_NOT_CHECK);
+ }
CrossOriginAttributeValue cross_origin = GetCrossOriginAttributeValue(
element.FastGetAttribute(html_names::kCrossoriginAttr));
@@ -435,7 +431,7 @@ inline void ImageLoader::EnqueueImageLoadingMicroTask(
void ImageLoader::UpdateImageState(ImageResourceContent* new_image_content) {
image_content_ = new_image_content;
if (!new_image_content) {
- image_resource_for_image_document_ = nullptr;
+ image_content_for_image_document_ = nullptr;
image_complete_ = true;
if (lazy_image_load_state_ == LazyImageLoadState::kDeferred) {
LazyImageHelper::StopMonitoring(GetElement());
@@ -491,10 +487,16 @@ void ImageLoader::DoUpdateFromElement(
if (IsA<HTMLPictureElement>(GetElement()->parentNode()) ||
!GetElement()->FastGetAttribute(html_names::kSrcsetAttr).IsNull()) {
resource_request.SetRequestContext(mojom::RequestContextType::IMAGE_SET);
+ resource_request.SetRequestDestination(
+ network::mojom::RequestDestination::kImage);
} else if (IsA<HTMLObjectElement>(GetElement())) {
resource_request.SetRequestContext(mojom::RequestContextType::OBJECT);
+ resource_request.SetRequestDestination(
+ network::mojom::RequestDestination::kObject);
} else if (IsA<HTMLEmbedElement>(GetElement())) {
resource_request.SetRequestContext(mojom::RequestContextType::EMBED);
+ resource_request.SetRequestDestination(
+ network::mojom::RequestDestination::kEmbed);
}
bool page_is_being_dismissed =
@@ -516,7 +518,8 @@ void ImageLoader::DoUpdateFromElement(
}
DCHECK(document.GetFrame());
- FetchParameters params(resource_request, resource_loader_options);
+ FetchParameters params(std::move(resource_request),
+ resource_loader_options);
ConfigureRequest(params, bypass_behavior, *element_,
document.GetFrame()->GetClientHintsPreferences());
@@ -569,18 +572,7 @@ void ImageLoader::DoUpdateFromElement(
}
}
- if (lazy_image_load_state_ == LazyImageLoadState::kDeferred &&
- was_fully_deferred_ && !ShouldLoadImmediately(url)) {
- // TODO(rajendrant): Remove this temporary workaround of creating a 1x1
- // placeholder to fix an intersection observer issue not firing with
- // certain styles (https://crbug.com/992765). Instead
- // NoImageResourceToLoad() should be skipped when the image is deferred.
- // https://crbug.com/999209
- new_image_content = ImageResourceContent::CreateLazyImagePlaceholder();
- } else {
- new_image_content =
- ImageResourceContent::Fetch(params, document.Fetcher());
- }
+ new_image_content = ImageResourceContent::Fetch(params, document.Fetcher());
// If this load is starting while navigating away, treat it as an auditing
// keepalive request, and don't report its results back to the element.
@@ -605,11 +597,16 @@ void ImageLoader::DoUpdateFromElement(
new_image_content == old_image_content) {
ToLayoutImage(element_->GetLayoutObject())->IntrinsicSizeChanged();
} else {
+ bool is_lazyload =
+ lazy_image_load_state_ == LazyImageLoadState::kDeferred &&
+ was_fully_deferred_;
+
// Loading didn't start (loading of images was disabled). We show fallback
// contents here, while we don't dispatch an 'error' event etc., because
// spec-wise the image remains in the "Unavailable" state.
if (new_image_content &&
- new_image_content->GetContentStatus() == ResourceStatus::kNotStarted)
+ new_image_content->GetContentStatus() == ResourceStatus::kNotStarted &&
+ !is_lazyload)
NoImageResourceToLoad();
if (pending_load_event_.IsActive())
@@ -657,28 +654,16 @@ void ImageLoader::UpdateFromElement(
if (!failed_load_url_.IsEmpty() && image_source_url == failed_load_url_)
return;
- if (loading_image_document_ && update_behavior == kUpdateForcedReload) {
- // Prepares for reloading ImageDocument.
- // We turn the ImageLoader into non-ImageDocument here, and proceed to
- // reloading just like an ordinary <img> element below.
- loading_image_document_ = false;
- image_resource_for_image_document_ = nullptr;
- ClearImage();
- }
-
- KURL url = ImageSourceToKURL(image_source_url);
-
// Prevent the creation of a ResourceLoader (and therefore a network request)
// for ImageDocument loads. In this case, the image contents have already been
// requested as a main resource and ImageDocumentParser will take care of
- // funneling the main resource bytes into |image_content_|, so just create an
- // ImageResource to be populated later.
- if (loading_image_document_) {
- ResourceRequest request(url);
- request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit);
- ImageResource* image_resource = ImageResource::Create(request);
- image_resource->NotifyStartLoad();
- SetImageForImageDocument(image_resource);
+ // funneling the main resource bytes into |image_content_for_image_document_|,
+ // so just pick up the ImageResourceContent that has been provided.
+ if (image_content_for_image_document_) {
+ DCHECK_NE(update_behavior, kUpdateForcedReload);
+ SetImageWithoutConsideringPendingLoadEvent(
+ image_content_for_image_document_);
+ image_content_for_image_document_ = nullptr;
return;
}
@@ -692,6 +677,8 @@ void ImageLoader::UpdateFromElement(
delay_until_do_update_from_element_ = nullptr;
}
+ KURL url = ImageSourceToKURL(image_source_url);
+
if (ShouldLoadImmediately(url)) {
DoUpdateFromElement(kDoNotBypassMainWorldCSP, update_behavior, url,
referrer_policy, UpdateType::kSync);
@@ -705,7 +692,7 @@ void ImageLoader::UpdateFromElement(
image->RemoveObserver(this);
}
image_content_ = nullptr;
- image_resource_for_image_document_ = nullptr;
+ image_content_for_image_document_ = nullptr;
delay_until_image_notify_finished_ = nullptr;
if (lazy_image_load_state_ != LazyImageLoadState::kNone) {
LazyImageHelper::StopMonitoring(GetElement());
@@ -778,15 +765,7 @@ void ImageLoader::ImageNotifyFinished(ImageResourceContent* resource) {
DCHECK(failed_load_url_.IsEmpty());
DCHECK_EQ(resource, image_content_.Get());
- // |image_complete_| is always true for entire ImageDocument loading for
- // historical reason.
- // DoUpdateFromElement() is not called and SetImageForImageDocument()
- // is called instead for ImageDocument loading.
- // TODO(hiroshige): Turn the CHECK()s to DCHECK()s before going to beta.
- if (loading_image_document_)
- CHECK(image_complete_);
- else
- CHECK(!image_complete_);
+ CHECK(!image_complete_);
if (lazy_image_load_state_ == LazyImageLoadState::kDeferred) {
// LazyImages: if a placeholder is loaded, suppress load events and do not
@@ -813,15 +792,14 @@ void ImageLoader::ImageNotifyFinished(ImageResourceContent* resource) {
if (image_content_ && image_content_->HasImage()) {
Image& image = *image_content_->GetImage();
- if (image.IsSVGImage()) {
- SVGImage& svg_image = ToSVGImage(image);
+ if (auto* svg_image = DynamicTo<SVGImage>(image)) {
// SVG's document should be completely loaded before access control
// checks, which can occur anytime after ImageNotifyFinished()
// (See SVGImage::CurrentFrameHasSingleSecurityOrigin()).
// We check the document is loaded here to catch violation of the
// assumption reliably.
- svg_image.CheckLoaded();
- svg_image.UpdateUseCounters(GetElement()->GetDocument());
+ svg_image->CheckLoaded();
+ svg_image->UpdateUseCounters(GetElement()->GetDocument());
}
}
@@ -838,11 +816,6 @@ void ImageLoader::ImageNotifyFinished(ImageResourceContent* resource) {
if (html_image_element)
LazyImageHelper::RecordMetricsOnLoadFinished(html_image_element);
- if (loading_image_document_) {
- CHECK(!pending_load_event_.IsActive());
- return;
- }
-
if (resource->ErrorOccurred()) {
pending_load_event_.Cancel();
@@ -882,8 +855,8 @@ LayoutImageResource* ImageLoader::GetLayoutImageResource() {
if (layout_object->IsSVGImage())
return ToLayoutSVGImage(layout_object)->ImageResource();
- if (layout_object->IsVideo())
- return ToLayoutVideo(layout_object)->ImageResource();
+ if (auto* layout_video = DynamicTo<LayoutVideo>(layout_object))
+ return layout_video->ImageResource();
return nullptr;
}
@@ -905,7 +878,7 @@ void ImageLoader::UpdateLayoutObject() {
bool ImageLoader::HasPendingEvent() const {
// Regular image loading is in progress.
- if (image_content_ && !image_complete_ && !loading_image_document_)
+ if (image_content_ && !image_complete_)
return true;
if (pending_load_event_.IsActive() || pending_error_event_.IsActive())
@@ -1033,7 +1006,7 @@ void ImageLoader::DecodeRequest::NotifyDecodeDispatched() {
state_ = kDispatched;
}
-void ImageLoader::DecodeRequest::Trace(blink::Visitor* visitor) {
+void ImageLoader::DecodeRequest::Trace(Visitor* visitor) {
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 f60beba5f22..181069a59f9 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(blink::Visitor*);
+ void Trace(Visitor*);
enum UpdateFromElementBehavior {
// This should be the update behavior when the element is attached to a
@@ -109,19 +109,27 @@ class CORE_EXPORT ImageLoader : public GarbageCollected<ImageLoader>,
void SetImageForTest(ImageResourceContent*);
// Image document loading:
- // When |loading_image_document_| is true:
- // Loading via ImageDocument.
- // |image_resource_for_image_document_| points to a ImageResource that is
- // not associated with a ResourceLoader.
- // The corresponding ImageDocument is responsible for supplying the response
- // and data to |image_resource_for_image_document_| and thus
- // |image_content_|.
+ //
+ // Loading via ImageDocument:
+ // ImageDocumentParser creates an ImageResource.
+ // The associated ImageResourceContent is provided to
+ // SetImageDocumentContent and set as
+ // |image_content_for_image_document_|. This ImageResourceContent is not
+ // associated with a ResourceLoader.
+ // When loading is initiated (through the HTMLImageElement that is the
+ // owner of the ImageLoader), |image_content_for_image_document_| is picked
+ // as the ImageResourceContent to use and is then reset to null. Thus
+ // |image_content_for_image_document_| should only be set (and used) when
+ // HTMLImageElement::StartLoadingImageDocument() is in the caller chain to
+ // UpdateFromElement().
+ // The corresponding ImageDocument is responsible for supplying the
+ // response and data via the ImageResourceContent it provided (which is now
+ // set as |image_content_|).
// Otherwise:
// Normal loading via ResourceFetcher/ResourceLoader.
- // |image_resource_for_image_document_| is null.
- void SetLoadingImageDocument() { loading_image_document_ = true; }
- ImageResource* ImageResourceForImageDocument() const {
- return image_resource_for_image_document_;
+ // |image_content_for_image_document_| is null.
+ void SetImageDocumentContent(ImageResourceContent* image_content) {
+ image_content_for_image_document_ = image_content;
}
bool HasPendingActivity() const { return HasPendingEvent() || pending_task_; }
@@ -183,7 +191,6 @@ class CORE_EXPORT ImageLoader : public GarbageCollected<ImageLoader>,
// Note: SetImage.*() are not a simple setter.
// Check the implementation to see what they do.
// TODO(hiroshige): Cleanup these methods.
- void SetImageForImageDocument(ImageResource*);
void SetImageWithoutConsideringPendingLoadEvent(ImageResourceContent*);
void UpdateImageState(ImageResourceContent*);
@@ -213,7 +220,7 @@ class CORE_EXPORT ImageLoader : public GarbageCollected<ImageLoader>,
Member<Element> element_;
Member<ImageResourceContent> image_content_;
- Member<ImageResource> image_resource_for_image_document_;
+ Member<ImageResourceContent> image_content_for_image_document_;
String last_base_element_url_;
network::mojom::ReferrerPolicy last_referrer_policy_ =
@@ -244,7 +251,6 @@ class CORE_EXPORT ImageLoader : public GarbageCollected<ImageLoader>,
TaskHandle pending_error_event_;
bool image_complete_ : 1;
- bool loading_image_document_ : 1;
bool suppress_error_events_ : 1;
bool was_fully_deferred_ : 1; // Used by LazyImageLoad.
@@ -275,7 +281,7 @@ class CORE_EXPORT ImageLoader : public GarbageCollected<ImageLoader>,
DecodeRequest(ImageLoader*, ScriptPromiseResolver*);
~DecodeRequest() = default;
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
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 762e4a0f3ec..8ce504fc1fe 100644
--- a/chromium/third_party/blink/renderer/core/loader/interactive_detector.cc
+++ b/chromium/third_party/blink/renderer/core/loader/interactive_detector.cc
@@ -3,18 +3,37 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/core/loader/interactive_detector.h"
-
+#include "base/metrics/histogram_macros.h"
#include "base/time/default_tick_clock.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
+#include "services/metrics/public/cpp/ukm_recorder.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/events/event.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/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
namespace blink {
+namespace {
+
+// Used to generate a unique id when emitting the "Long Input Delay" trace
+// event.
+int g_num_long_input_events = 0;
+
+// The threshold to emit the "Long Input Delay" trace event is the 99th
+// percentile of the histogram on Windows Stable as of Feb 25, 2020.
+constexpr base::TimeDelta kInputDelayTraceEventThreshold =
+ base::TimeDelta::FromMilliseconds(250);
+
+// The threshold to emit the "Long First Input Delay" trace event is the 99th
+// percentile of the histogram on Windows Stable as of Feb 27, 2020.
+constexpr base::TimeDelta kFirstInputDelayTraceEventThreshold =
+ base::TimeDelta::FromMilliseconds(575);
+
+} // namespace
+
// Required length of main thread and network quiet window for determining
// Time to Interactive.
constexpr auto kTimeToInteractiveWindow = base::TimeDelta::FromSeconds(5);
@@ -48,14 +67,15 @@ InteractiveDetector::InteractiveDetector(
Document& document,
NetworkActivityChecker* network_activity_checker)
: Supplement<Document>(document),
- ContextLifecycleObserver(&document),
+ ExecutionContextLifecycleObserver(&document),
clock_(base::DefaultTickClock::GetInstance()),
network_activity_checker_(network_activity_checker),
time_to_interactive_timer_(
document.GetTaskRunner(TaskType::kInternalDefault),
this,
&InteractiveDetector::TimeToInteractiveTimerFired),
- initially_hidden_(document.hidden()) {}
+ initially_hidden_(document.hidden()),
+ ukm_recorder_(document.UkmRecorder()) {}
void InteractiveDetector::SetNavigationStartTime(
base::TimeTicks navigation_start_time) {
@@ -72,7 +92,6 @@ void InteractiveDetector::SetNavigationStartTime(
base::TimeTicks initial_timer_fire_time =
navigation_start_time + kTimeToInteractiveWindow;
- active_main_thread_quiet_window_start_ = navigation_start_time;
active_network_quiet_window_start_ = navigation_start_time;
StartOrPostponeCITimer(initial_timer_fire_time);
}
@@ -114,37 +133,23 @@ void InteractiveDetector::StartOrPostponeCITimer(
}
}
-base::TimeTicks InteractiveDetector::GetInteractiveTime() const {
- // TODO(crbug.com/808685) Simplify FMP and TTI input invalidation.
- return page_event_times_.first_meaningful_paint_invalidated
- ? base::TimeTicks()
- : interactive_time_;
-}
-
-base::TimeTicks InteractiveDetector::GetInteractiveDetectionTime() const {
- // TODO(crbug.com/808685) Simplify FMP and TTI input invalidation.
- return page_event_times_.first_meaningful_paint_invalidated
- ? base::TimeTicks()
- : interactive_detection_time_;
-}
-
-base::TimeTicks InteractiveDetector::GetFirstInvalidatingInputTime() const {
- return page_event_times_.first_invalidating_input;
-}
-
-base::TimeDelta InteractiveDetector::GetFirstInputDelay() const {
+base::Optional<base::TimeDelta> InteractiveDetector::GetFirstInputDelay()
+ const {
return page_event_times_.first_input_delay;
}
-base::TimeTicks InteractiveDetector::GetFirstInputTimestamp() const {
+base::Optional<base::TimeTicks> InteractiveDetector::GetFirstInputTimestamp()
+ const {
return page_event_times_.first_input_timestamp;
}
-base::TimeDelta InteractiveDetector::GetLongestInputDelay() const {
+base::Optional<base::TimeDelta> InteractiveDetector::GetLongestInputDelay()
+ const {
return page_event_times_.longest_input_delay;
}
-base::TimeTicks InteractiveDetector::GetLongestInputTimestamp() const {
+base::Optional<base::TimeTicks> InteractiveDetector::GetLongestInputTimestamp()
+ const {
return page_event_times_.longest_input_timestamp;
}
@@ -220,12 +225,43 @@ void InteractiveDetector::HandleForInputDelay(
pending_pointerdown_delay_ = base::TimeDelta();
pending_pointerdown_timestamp_ = base::TimeTicks();
- bool input_delay_metrics_changed = false;
+ bool interactive_timing_metrics_changed = false;
- if (page_event_times_.first_input_delay.is_zero()) {
+ if (!page_event_times_.first_input_delay.has_value()) {
page_event_times_.first_input_delay = delay;
page_event_times_.first_input_timestamp = event_timestamp;
- input_delay_metrics_changed = true;
+ interactive_timing_metrics_changed = true;
+
+ if (delay > kFirstInputDelayTraceEventThreshold) {
+ // Emit a trace event to highlight long first input delays.
+ TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0(
+ "latency", "Long First Input Delay",
+ TRACE_ID_LOCAL(g_num_long_input_events), event_timestamp);
+ TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0(
+ "latency", "Long First Input Delay",
+ TRACE_ID_LOCAL(g_num_long_input_events), event_timestamp + delay);
+ g_num_long_input_events++;
+ }
+ } else if (delay > kInputDelayTraceEventThreshold) {
+ // Emit a trace event to highlight long input delays from second input and
+ // onwards.
+ TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0(
+ "latency", "Long Input Delay", TRACE_ID_LOCAL(g_num_long_input_events),
+ event_timestamp);
+ TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0(
+ "latency", "Long Input Delay", TRACE_ID_LOCAL(g_num_long_input_events),
+ event_timestamp + delay);
+ 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());
+ if (GetSupplementable()->Loader()) {
+ GetSupplementable()->Loader()->DidObserveInputDelay(delay);
}
UMA_HISTOGRAM_CUSTOM_TIMES(kHistogramInputDelay, delay,
@@ -238,15 +274,17 @@ void InteractiveDetector::HandleForInputDelay(
// Only update longest input delay if page was not backgrounded while the
// input was queued.
- if (delay > page_event_times_.longest_input_delay &&
+ if ((!page_event_times_.longest_input_delay.has_value() ||
+ delay > *page_event_times_.longest_input_delay) &&
!PageWasBackgroundedSinceEvent(event_timestamp)) {
page_event_times_.longest_input_delay = delay;
page_event_times_.longest_input_timestamp = event_timestamp;
- input_delay_metrics_changed = true;
+ interactive_timing_metrics_changed = true;
}
- if (GetSupplementable()->Loader() && input_delay_metrics_changed)
+ if (GetSupplementable()->Loader() && interactive_timing_metrics_changed) {
GetSupplementable()->Loader()->DidChangePerformanceTiming();
+ }
}
void InteractiveDetector::BeginNetworkQuietPeriod(
@@ -316,29 +354,20 @@ void InteractiveDetector::OnLongTaskDetected(base::TimeTicks start_time,
// We should not be receiving long task notifications after Time to
// Interactive has already been reached.
DCHECK(interactive_time_.is_null());
- base::TimeDelta quiet_window_length =
- start_time - active_main_thread_quiet_window_start_;
- if (quiet_window_length >= kTimeToInteractiveWindow) {
- main_thread_quiet_windows_.emplace_back(
- active_main_thread_quiet_window_start_, start_time);
- }
- active_main_thread_quiet_window_start_ = end_time;
+ long_tasks_.emplace_back(start_time, end_time);
StartOrPostponeCITimer(end_time + kTimeToInteractiveWindow);
}
-void InteractiveDetector::OnFirstMeaningfulPaintDetected(
- base::TimeTicks fmp_time,
- FirstMeaningfulPaintDetector::HadUserInput user_input_before_fmp) {
- DCHECK(page_event_times_.first_meaningful_paint
- .is_null()); // Should not set FMP twice.
- page_event_times_.first_meaningful_paint = fmp_time;
- page_event_times_.first_meaningful_paint_invalidated =
- user_input_before_fmp == FirstMeaningfulPaintDetector::kHadUserInput;
- if (clock_->NowTicks() - fmp_time >= kTimeToInteractiveWindow) {
- // We may have reached TTCI already. Check right away.
+void InteractiveDetector::OnFirstContentfulPaint(
+ base::TimeTicks first_contentful_paint) {
+ // Should not set FCP twice.
+ DCHECK(page_event_times_.first_contentful_paint.is_null());
+ page_event_times_.first_contentful_paint = first_contentful_paint;
+ if (clock_->NowTicks() - first_contentful_paint >= kTimeToInteractiveWindow) {
+ // We may have reached TTI already. Check right away.
CheckTimeToInteractiveReached();
} else {
- StartOrPostponeCITimer(page_event_times_.first_meaningful_paint +
+ StartOrPostponeCITimer(page_event_times_.first_contentful_paint +
kTimeToInteractiveWindow);
}
}
@@ -380,7 +409,7 @@ void InteractiveDetector::TimeToInteractiveTimerFired(TimerBase*) {
CheckTimeToInteractiveReached();
}
-void InteractiveDetector::AddCurrentlyActiveQuietIntervals(
+void InteractiveDetector::AddCurrentlyActiveNetworkQuietInterval(
base::TimeTicks current_time) {
// Network is currently quiet.
if (!active_network_quiet_window_start_.is_null()) {
@@ -390,78 +419,81 @@ void InteractiveDetector::AddCurrentlyActiveQuietIntervals(
current_time);
}
}
-
- // Since this code executes on the main thread, we know that no task is
- // currently running on the main thread. We can therefore skip checking.
- // main_thread_quiet_window_being != 0.0.
- if (current_time - active_main_thread_quiet_window_start_ >=
- kTimeToInteractiveWindow) {
- main_thread_quiet_windows_.emplace_back(
- active_main_thread_quiet_window_start_, current_time);
- }
}
-void InteractiveDetector::RemoveCurrentlyActiveQuietIntervals() {
+void InteractiveDetector::RemoveCurrentlyActiveNetworkQuietInterval() {
if (!network_quiet_windows_.IsEmpty() &&
network_quiet_windows_.back().Low() ==
active_network_quiet_window_start_) {
network_quiet_windows_.pop_back();
}
-
- if (!main_thread_quiet_windows_.IsEmpty() &&
- main_thread_quiet_windows_.back().Low() ==
- active_main_thread_quiet_window_start_) {
- main_thread_quiet_windows_.pop_back();
- }
}
base::TimeTicks InteractiveDetector::FindInteractiveCandidate(
- base::TimeTicks lower_bound) {
- // Main thread iterator.
- auto* it_mt = main_thread_quiet_windows_.begin();
+ base::TimeTicks lower_bound,
+ base::TimeTicks current_time) {
// Network iterator.
auto* it_net = network_quiet_windows_.begin();
+ // Long tasks iterator.
+ auto* it_lt = long_tasks_.begin();
- while (it_mt < main_thread_quiet_windows_.end() &&
+ base::TimeTicks main_quiet_start = page_event_times_.nav_start;
+
+ while (main_quiet_start < current_time &&
it_net < network_quiet_windows_.end()) {
- if (it_mt->High() <= lower_bound) {
- it_mt++;
+ base::TimeTicks main_quiet_end =
+ it_lt == long_tasks_.end() ? current_time : it_lt->Low();
+ base::TimeTicks next_main_quiet_start =
+ it_lt == long_tasks_.end() ? current_time : it_lt->High();
+ if (main_quiet_end - main_quiet_start < kTimeToInteractiveWindow) {
+ // The main thread quiet window is too short.
+ ++it_lt;
+ main_quiet_start = next_main_quiet_start;
+ continue;
+ }
+ if (main_quiet_end <= lower_bound) {
+ // The main thread quiet window is before |lower_bound|.
+ ++it_lt;
+ main_quiet_start = next_main_quiet_start;
continue;
}
if (it_net->High() <= lower_bound) {
- it_net++;
+ // The network quiet window is before |lower_bound|.
+ ++it_net;
continue;
}
// First handling the no overlap cases.
// [ main thread interval ]
// [ network interval ]
- if (it_mt->High() <= it_net->Low()) {
- it_mt++;
+ if (main_quiet_end <= it_net->Low()) {
+ ++it_lt;
+ main_quiet_start = next_main_quiet_start;
continue;
}
// [ main thread interval ]
// [ network interval ]
- if (it_net->High() <= it_mt->Low()) {
- it_net++;
+ if (it_net->High() <= main_quiet_start) {
+ ++it_net;
continue;
}
// At this point we know we have a non-empty overlap after lower_bound.
base::TimeTicks overlap_start =
- std::max({it_mt->Low(), it_net->Low(), lower_bound});
- base::TimeTicks overlap_end = std::min(it_mt->High(), it_net->High());
+ std::max({main_quiet_start, it_net->Low(), lower_bound});
+ base::TimeTicks overlap_end = std::min(main_quiet_end, it_net->High());
base::TimeDelta overlap_duration = overlap_end - overlap_start;
if (overlap_duration >= kTimeToInteractiveWindow) {
- return std::max(lower_bound, it_mt->Low());
+ return std::max(lower_bound, main_quiet_start);
}
// The interval with earlier end time will not produce any more overlap, so
// we move on from it.
- if (it_mt->High() <= it_net->High()) {
- it_mt++;
+ if (main_quiet_end <= it_net->High()) {
+ ++it_lt;
+ main_quiet_start = next_main_quiet_start;
} else {
- it_net++;
+ ++it_net;
}
}
@@ -474,22 +506,22 @@ void InteractiveDetector::CheckTimeToInteractiveReached() {
if (!interactive_time_.is_null())
return;
- // FMP and DCL have not been detected yet.
- if (page_event_times_.first_meaningful_paint.is_null() ||
+ // FCP and DCL have not been detected yet.
+ if (page_event_times_.first_contentful_paint.is_null() ||
page_event_times_.dom_content_loaded_end.is_null())
return;
const base::TimeTicks current_time = clock_->NowTicks();
- if (current_time - page_event_times_.first_meaningful_paint <
+ if (current_time - page_event_times_.first_contentful_paint <
kTimeToInteractiveWindow) {
- // Too close to FMP to determine Time to Interactive.
+ // Too close to FCP to determine Time to Interactive.
return;
}
- AddCurrentlyActiveQuietIntervals(current_time);
- const base::TimeTicks interactive_candidate =
- FindInteractiveCandidate(page_event_times_.first_meaningful_paint);
- RemoveCurrentlyActiveQuietIntervals();
+ AddCurrentlyActiveNetworkQuietInterval(current_time);
+ const base::TimeTicks interactive_candidate = FindInteractiveCandidate(
+ page_event_times_.first_contentful_paint, current_time);
+ RemoveCurrentlyActiveNetworkQuietInterval();
// No Interactive Candidate found.
if (interactive_candidate.is_null())
@@ -503,36 +535,56 @@ void InteractiveDetector::CheckTimeToInteractiveReached() {
void InteractiveDetector::OnTimeToInteractiveDetected() {
LongTaskDetector::Instance().UnregisterObserver(this);
- main_thread_quiet_windows_.clear();
network_quiet_windows_.clear();
+ TRACE_EVENT_MARK_WITH_TIMESTAMP2(
+ "loading,rail", "InteractiveTime", interactive_time_, "frame",
+ ToTraceValue(GetSupplementable()->GetFrame()), "args",
+ ComputeTimeToInteractiveTraceArgs());
+
+ long_tasks_.clear();
+}
+
+std::unique_ptr<TracedValue>
+InteractiveDetector::ComputeTimeToInteractiveTraceArgs() {
+ // We log the trace event even if there is user input, but annotate the event
+ // with whether that happened.
bool had_user_input_before_interactive =
!page_event_times_.first_invalidating_input.is_null() &&
page_event_times_.first_invalidating_input < interactive_time_;
- // We log the trace event even if there is user input, but annotate the event
- // with whether that happened.
- TRACE_EVENT_MARK_WITH_TIMESTAMP2(
- "loading,rail", "InteractiveTime", interactive_time_, "frame",
- ToTraceValue(GetSupplementable()->GetFrame()),
- "had_user_input_before_interactive", had_user_input_before_interactive);
-
- // We only send TTI to Performance Timing Observers if FMP was not invalidated
- // by input.
- // TODO(crbug.com/808685) Simplify FMP and TTI input invalidation.
- if (!page_event_times_.first_meaningful_paint_invalidated) {
- if (GetSupplementable()->Loader())
- GetSupplementable()->Loader()->DidChangePerformanceTiming();
+ auto dict = std::make_unique<TracedValue>();
+ dict->SetBoolean("had_user_input_before_interactive",
+ had_user_input_before_interactive);
+ dict->SetDouble("total_blocking_time_ms",
+ ComputeTotalBlockingTime().InMillisecondsF());
+ return dict;
+}
+
+base::TimeDelta InteractiveDetector::ComputeTotalBlockingTime() {
+ // We follow the same logic as the lighthouse computation in
+ // https://github.com/GoogleChrome/lighthouse/blob/f150573b5970cc90c8d0c2214f5738df5cde8a31/lighthouse-core/computed/metrics/total-blocking-time.js#L60-L74.
+ // In particular, tasks are clipped [FCP, TTI], and then all positive values
+ // of (task_length - 50) are added to the blocking time.
+ base::TimeDelta total_blocking_time;
+ for (const auto& long_task : long_tasks_) {
+ base::TimeTicks clipped_start =
+ std::max(long_task.Low(), page_event_times_.first_contentful_paint);
+ base::TimeTicks clipped_end = std::min(long_task.High(), interactive_time_);
+ total_blocking_time +=
+ std::max(base::TimeDelta(), clipped_end - clipped_start -
+ base::TimeDelta::FromMilliseconds(50));
}
+ return total_blocking_time;
}
-void InteractiveDetector::ContextDestroyed(ExecutionContext*) {
+void InteractiveDetector::ContextDestroyed() {
LongTaskDetector::Instance().UnregisterObserver(this);
}
void InteractiveDetector::Trace(Visitor* visitor) {
Supplement<Document>::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
void InteractiveDetector::SetTickClockForTesting(const base::TickClock* clock) {
@@ -544,4 +596,12 @@ void InteractiveDetector::SetTaskRunnerForTesting(
time_to_interactive_timer_.MoveToNewTaskRunner(task_runner_for_testing);
}
+ukm::UkmRecorder* InteractiveDetector::GetUkmRecorder() const {
+ return ukm_recorder_;
+}
+
+void InteractiveDetector::SetUkmRecorderForTesting(
+ ukm::UkmRecorder* test_ukm_recorder) {
+ ukm_recorder_ = test_ukm_recorder;
+}
} // 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 a7c7cdd1e32..09e8622eb06 100644
--- a/chromium/third_party/blink/renderer/core/loader/interactive_detector.h
+++ b/chromium/third_party/blink/renderer/core/loader/interactive_detector.h
@@ -9,12 +9,12 @@
#include "base/optional.h"
#include "base/time/time.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/loader/long_task_detector.h"
#include "third_party/blink/renderer/core/page/page_hidden_state.h"
-#include "third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h"
#include "third_party/blink/renderer/platform/supplementable.h"
#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/wtf/pod_interval.h"
@@ -24,6 +24,10 @@ namespace base {
class TickClock;
} // namespace base
+namespace ukm {
+class UkmRecorder;
+} // namespace ukm
+
namespace blink {
class Document;
@@ -37,7 +41,7 @@ class Event;
class CORE_EXPORT InteractiveDetector
: public GarbageCollected<InteractiveDetector>,
public Supplement<Document>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public LongTaskObserver {
USING_GARBAGE_COLLECTED_MIXIN(InteractiveDetector);
@@ -74,41 +78,27 @@ class CORE_EXPORT InteractiveDetector
void OnResourceLoadEnd(base::Optional<base::TimeTicks> load_finish_time);
void SetNavigationStartTime(base::TimeTicks navigation_start_time);
- void OnFirstMeaningfulPaintDetected(
- base::TimeTicks fmp_time,
- FirstMeaningfulPaintDetector::HadUserInput user_input_before_fmp);
+ void OnFirstContentfulPaint(base::TimeTicks first_contentful_paint);
void OnDomContentLoadedEnd(base::TimeTicks dcl_time);
void OnInvalidatingInputEvent(base::TimeTicks invalidation_time);
void OnPageHiddenChanged(bool is_hidden);
- // Returns Interactive Time if already detected, or 0.0 otherwise.
- base::TimeTicks GetInteractiveTime() const;
-
- // Returns the time when page interactive was detected. The detection time can
- // be useful to make decisions about metric invalidation in scenarios like tab
- // backgrounding.
- base::TimeTicks GetInteractiveDetectionTime() const;
-
- // Returns the first time interactive detector received a significant input
- // that may cause observers to discard the interactive time value.
- base::TimeTicks GetFirstInvalidatingInputTime() const;
-
// The duration between the hardware timestamp and being queued on the main
// thread for the first click, tap, key press, cancelable touchstart, or
// pointer down followed by a pointer up.
- base::TimeDelta GetFirstInputDelay() const;
+ base::Optional<base::TimeDelta> GetFirstInputDelay() const;
// The timestamp of the event whose delay is reported by GetFirstInputDelay().
- base::TimeTicks GetFirstInputTimestamp() const;
+ base::Optional<base::TimeTicks> GetFirstInputTimestamp() const;
// Queueing Time of the meaningful input event with longest delay. Meaningful
// input events are click, tap, key press, cancellable touchstart, or pointer
// down followed by a pointer up.
- base::TimeDelta GetLongestInputDelay() const;
+ base::Optional<base::TimeDelta> GetLongestInputDelay() const;
// The timestamp of the event whose delay is reported by
// GetLongestInputDelay().
- base::TimeTicks GetLongestInputTimestamp() const;
+ base::Optional<base::TimeTicks> GetLongestInputTimestamp() const;
// Process an input event, updating first_input_delay and
// first_input_timestamp if needed.
@@ -116,8 +106,8 @@ class CORE_EXPORT InteractiveDetector
base::TimeTicks event_platform_timestamp,
base::TimeTicks processing_start);
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
void Trace(Visitor*) override;
@@ -126,6 +116,10 @@ class CORE_EXPORT InteractiveDetector
// The caller owns the |clock| which must outlive the InteractiveDetector.
void SetTickClockForTesting(const base::TickClock* clock);
+ ukm::UkmRecorder* GetUkmRecorder() const;
+
+ void SetUkmRecorderForTesting(ukm::UkmRecorder* test_ukm_recorder);
+
private:
friend class InteractiveDetectorTest;
@@ -137,15 +131,17 @@ class CORE_EXPORT InteractiveDetector
// Page event times that Interactive Detector depends on.
// Null base::TimeTicks values indicate the event has not been detected yet.
struct {
- base::TimeTicks first_meaningful_paint;
+ base::TimeTicks first_contentful_paint;
base::TimeTicks dom_content_loaded_end;
base::TimeTicks nav_start;
+ // The timestamp of the first input that would invalidate a Time to
+ // Interactive computation. This is used when reporting Time To Interactive
+ // on a trace event.
base::TimeTicks first_invalidating_input;
- base::TimeDelta first_input_delay;
- base::TimeDelta longest_input_delay;
- base::TimeTicks first_input_timestamp;
- base::TimeTicks longest_input_timestamp;
- bool first_meaningful_paint_invalidated = false;
+ base::Optional<base::TimeDelta> first_input_delay;
+ base::Optional<base::TimeDelta> longest_input_delay;
+ base::Optional<base::TimeTicks> first_input_timestamp;
+ base::Optional<base::TimeTicks> longest_input_timestamp;
} page_event_times_;
struct VisibilityChangeEvent {
@@ -153,22 +149,22 @@ class CORE_EXPORT InteractiveDetector
bool was_hidden;
};
- // Stores sufficiently long quiet windows on main thread and network.
- Vector<WTF::PODInterval<base::TimeTicks>> main_thread_quiet_windows_;
+ // Stores sufficiently long quiet windows on the network.
Vector<WTF::PODInterval<base::TimeTicks>> network_quiet_windows_;
- // Start times of currently active main thread and network quiet windows.
- // Null base::TimeTicks values indicate main thread or network is not quiet at
- // the moment.
- base::TimeTicks active_main_thread_quiet_window_start_;
+ // Stores long tasks in order to compute Total Blocking Time (TBT) once Time
+ // To Interactive (TTI) is known.
+ Vector<WTF::PODInterval<base::TimeTicks>> long_tasks_;
+
+ // Start time of currently active network quiet windows.
+ // Null base::TimeTicks values indicate network is not quiet at the moment.
base::TimeTicks active_network_quiet_window_start_;
- // Adds currently active quiet main thread and network quiet windows to the
- // vectors. Should be called before calling
- // FindInteractiveCandidate.
- void AddCurrentlyActiveQuietIntervals(base::TimeTicks current_time);
- // Undoes AddCurrentlyActiveQuietIntervals.
- void RemoveCurrentlyActiveQuietIntervals();
+ // Adds currently active quiet network quiet window to the
+ // vector. Should be called before calling FindInteractiveCandidate.
+ void AddCurrentlyActiveNetworkQuietInterval(base::TimeTicks current_time);
+ // Undoes AddCurrentlyActiveNetworkQuietInterval.
+ void RemoveCurrentlyActiveNetworkQuietInterval();
std::unique_ptr<NetworkActivityChecker> network_activity_checker_;
int ActiveConnections();
@@ -185,6 +181,8 @@ class CORE_EXPORT InteractiveDetector
void TimeToInteractiveTimerFired(TimerBase*);
void CheckTimeToInteractiveReached();
void OnTimeToInteractiveDetected();
+ std::unique_ptr<TracedValue> ComputeTimeToInteractiveTraceArgs();
+ base::TimeDelta ComputeTotalBlockingTime();
Vector<VisibilityChangeEvent> visibility_change_events_;
bool initially_hidden_;
@@ -197,7 +195,8 @@ class CORE_EXPORT InteractiveDetector
// long task before that quiet window, or lower_bound, whichever is bigger -
// this is called the Interactive Candidate. Returns 0.0 if no such quiet
// window is found.
- base::TimeTicks FindInteractiveCandidate(base::TimeTicks lower_bound);
+ base::TimeTicks FindInteractiveCandidate(base::TimeTicks lower_bound,
+ base::TimeTicks current_time);
// LongTaskObserver implementation
void OnLongTaskDetected(base::TimeTicks start_time,
@@ -211,6 +210,8 @@ class CORE_EXPORT InteractiveDetector
// pending_pointerdown_delay_.
base::TimeTicks pending_pointerdown_timestamp_;
+ ukm::UkmRecorder* ukm_recorder_;
+
DISALLOW_COPY_AND_ASSIGN(InteractiveDetector);
};
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 223efec74e6..4bfb1c4ce00 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
@@ -1,14 +1,18 @@
// 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 "components/ukm/test_ukm_recorder.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
+#include "base/bind_helpers.h"
#include "third_party/blink/renderer/core/loader/interactive_detector.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h"
+#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
+#include "third_party/blink/renderer/core/testing/scoped_mock_overlay_scrollbars.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
@@ -16,6 +20,8 @@
namespace blink {
+using InputEvent = ukm::builders::InputEvent;
+
class NetworkActivityCheckerForTest
: public InteractiveDetector::NetworkActivityChecker {
public:
@@ -35,7 +41,8 @@ int NetworkActivityCheckerForTest::GetActiveConnections() {
return active_connections_;
}
-class InteractiveDetectorTest : public testing::Test {
+class InteractiveDetectorTest : public testing::Test,
+ public ScopedMockOverlayScrollbars {
public:
InteractiveDetectorTest() {
platform_->AdvanceClockSeconds(1);
@@ -46,7 +53,6 @@ class InteractiveDetectorTest : public testing::Test {
IntSize(), nullptr, nullptr, base::NullCallback(), tick_clock);
Document* document = &dummy_page_holder_->GetDocument();
-
detector_ = MakeGarbageCollected<InteractiveDetector>(
*document, new NetworkActivityCheckerForTest(document));
detector_->SetTaskRunnerForTesting(test_task_runner);
@@ -95,11 +101,10 @@ class InteractiveDetectorTest : public testing::Test {
detector_->OnDomContentLoadedEnd(dcl_time);
}
- void SimulateFMPDetected(base::TimeTicks fmp_time,
+ void SimulateFCPDetected(base::TimeTicks fcp_time,
base::TimeTicks detection_time) {
RunTillTimestamp(detection_time);
- detector_->OnFirstMeaningfulPaintDetected(
- fmp_time, FirstMeaningfulPaintDetector::kNoUserInput);
+ detector_->OnFirstContentfulPaint(fcp_time);
}
void SimulateInteractiveInvalidatingInput(base::TimeTicks timestamp) {
@@ -137,8 +142,14 @@ class InteractiveDetectorTest : public testing::Test {
base::TimeTicks Now() { return platform_->test_task_runner()->NowTicks(); }
- base::TimeTicks GetInteractiveTime() {
- return detector_->GetInteractiveTime();
+ base::TimeTicks GetInteractiveTime() { return detector_->interactive_time_; }
+
+ void SetTimeToInteractive(base::TimeTicks interactive_time) {
+ detector_->interactive_time_ = interactive_time;
+ }
+
+ base::TimeDelta GetTotalBlockingTime() {
+ return detector_->ComputeTotalBlockingTime();
}
ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
@@ -156,60 +167,60 @@ class InteractiveDetectorTest : public testing::Test {
// Note: Some of the tests are named W_X_Y_Z, where W, X, Y, Z can any of the
// following events:
-// FMP: First Meaningful Paint
+// FCP: First Contentful Paint
// DCL: DomContentLoadedEnd
-// FmpDetect: Detection of FMP. FMP is not detected in realtime.
+// FcpDetect: Detection of FCP. FCP is a presentation timestamp.
// LT: Long Task
// The name shows the ordering of these events in the test.
-TEST_F(InteractiveDetectorTest, FMP_DCL_FmpDetect) {
+TEST_F(InteractiveDetectorTest, FCP_DCL_FcpDetect) {
base::TimeTicks t0 = Now();
SimulateNavigationStart(t0);
// Network is forever quiet for this test.
SetActiveConnections(1);
SimulateDOMContentLoadedEnd(t0 + base::TimeDelta::FromSeconds(3));
- SimulateFMPDetected(
- /* fmp_time */ t0 + base::TimeDelta::FromSeconds(5),
+ SimulateFCPDetected(
+ /* fcp_time */ t0 + base::TimeDelta::FromSeconds(5),
/* detection_time */ t0 + base::TimeDelta::FromSeconds(7));
- // Run until 5 seconds after FMP.
+ // Run until 5 seconds after FCP.
RunTillTimestamp((t0 + base::TimeDelta::FromSeconds(5)) +
base::TimeDelta::FromSecondsD(5.0 + 0.1));
- // Reached TTI at FMP.
+ // Reached TTI at FCP.
EXPECT_EQ(GetInteractiveTime(), t0 + base::TimeDelta::FromSeconds(5));
}
-TEST_F(InteractiveDetectorTest, DCL_FMP_FmpDetect) {
+TEST_F(InteractiveDetectorTest, DCL_FCP_FcpDetect) {
base::TimeTicks t0 = Now();
SimulateNavigationStart(t0);
// Network is forever quiet for this test.
SetActiveConnections(1);
SimulateDOMContentLoadedEnd(t0 + base::TimeDelta::FromSeconds(5));
- SimulateFMPDetected(
- /* fmp_time */ t0 + base::TimeDelta::FromSeconds(3),
+ SimulateFCPDetected(
+ /* fcp_time */ t0 + base::TimeDelta::FromSeconds(3),
/* detection_time */ t0 + base::TimeDelta::FromSeconds(7));
- // Run until 5 seconds after FMP.
+ // Run until 5 seconds after FCP.
RunTillTimestamp((t0 + base::TimeDelta::FromSeconds(3)) +
base::TimeDelta::FromSecondsD(5.0 + 0.1));
// Reached TTI at DCL.
EXPECT_EQ(GetInteractiveTime(), t0 + base::TimeDelta::FromSeconds(5));
}
-TEST_F(InteractiveDetectorTest, InstantDetectionAtFmpDetectIfPossible) {
+TEST_F(InteractiveDetectorTest, InstantDetectionAtFcpDetectIfPossible) {
base::TimeTicks t0 = Now();
SimulateNavigationStart(t0);
// Network is forever quiet for this test.
SetActiveConnections(1);
SimulateDOMContentLoadedEnd(t0 + base::TimeDelta::FromSeconds(5));
- SimulateFMPDetected(
- /* fmp_time */ t0 + base::TimeDelta::FromSeconds(3),
+ SimulateFCPDetected(
+ /* fcp_time */ t0 + base::TimeDelta::FromSeconds(3),
/* detection_time */ t0 + base::TimeDelta::FromSeconds(10));
- // Although we just detected FMP, the FMP timestamp is more than
+ // Although we just detected FCP, the FCP timestamp is more than
// kTimeToInteractiveWindowSeconds earlier. We should instantaneously
// detect that we reached TTI at DCL.
EXPECT_EQ(GetInteractiveTime(), t0 + base::TimeDelta::FromSeconds(5));
}
-TEST_F(InteractiveDetectorTest, FmpDetectFiresAfterLateLongTask) {
+TEST_F(InteractiveDetectorTest, FcpDetectFiresAfterLateLongTask) {
base::TimeTicks t0 = Now();
SimulateNavigationStart(t0);
// Network is forever quiet for this test.
@@ -217,28 +228,28 @@ TEST_F(InteractiveDetectorTest, FmpDetectFiresAfterLateLongTask) {
SimulateDOMContentLoadedEnd(t0 + base::TimeDelta::FromSeconds(3));
SimulateLongTask(t0 + base::TimeDelta::FromSeconds(9),
t0 + base::TimeDelta::FromSecondsD(9.1));
- SimulateFMPDetected(
- /* fmp_time */ t0 + base::TimeDelta::FromSeconds(3),
+ SimulateFCPDetected(
+ /* fcp_time */ t0 + base::TimeDelta::FromSeconds(3),
/* detection_time */ t0 + base::TimeDelta::FromSeconds(10));
- // There is a 5 second quiet window after fmp_time - the long task is 6s
- // seconds after fmp_time. We should instantly detect we reached TTI at FMP.
+ // There is a 5 second quiet window after fcp_time - the long task is 6s
+ // seconds after fcp_time. We should instantly detect we reached TTI at FCP.
EXPECT_EQ(GetInteractiveTime(), t0 + base::TimeDelta::FromSeconds(3));
}
-TEST_F(InteractiveDetectorTest, FMP_FmpDetect_DCL) {
+TEST_F(InteractiveDetectorTest, FCP_FcpDetect_DCL) {
base::TimeTicks t0 = Now();
SimulateNavigationStart(t0);
// Network is forever quiet for this test.
SetActiveConnections(1);
- SimulateFMPDetected(
- /* fmp_time */ t0 + base::TimeDelta::FromSeconds(3),
+ SimulateFCPDetected(
+ /* fcp_time */ t0 + base::TimeDelta::FromSeconds(3),
/* detection_time */ t0 + base::TimeDelta::FromSeconds(5));
SimulateDOMContentLoadedEnd(t0 + base::TimeDelta::FromSeconds(9));
// TTI reached at DCL.
EXPECT_EQ(GetInteractiveTime(), t0 + base::TimeDelta::FromSeconds(9));
}
-TEST_F(InteractiveDetectorTest, LongTaskBeforeFMPDoesNotAffectTTI) {
+TEST_F(InteractiveDetectorTest, LongTaskBeforeFCPDoesNotAffectTTI) {
base::TimeTicks t0 = Now();
SimulateNavigationStart(t0);
// Network is forever quiet for this test.
@@ -246,13 +257,13 @@ TEST_F(InteractiveDetectorTest, LongTaskBeforeFMPDoesNotAffectTTI) {
SimulateDOMContentLoadedEnd(t0 + base::TimeDelta::FromSeconds(3));
SimulateLongTask(t0 + base::TimeDelta::FromSecondsD(5.1),
t0 + base::TimeDelta::FromSecondsD(5.2));
- SimulateFMPDetected(
- /* fmp_time */ t0 + base::TimeDelta::FromSeconds(8),
+ SimulateFCPDetected(
+ /* fcp_time */ t0 + base::TimeDelta::FromSeconds(8),
/* detection_time */ t0 + base::TimeDelta::FromSeconds(9));
- // Run till 5 seconds after FMP.
+ // Run till 5 seconds after FCP.
RunTillTimestamp((t0 + base::TimeDelta::FromSeconds(8)) +
base::TimeDelta::FromSecondsD(5.0 + 0.1));
- // TTI reached at FMP.
+ // TTI reached at FCP.
EXPECT_EQ(GetInteractiveTime(), t0 + base::TimeDelta::FromSeconds(8));
}
@@ -261,8 +272,8 @@ TEST_F(InteractiveDetectorTest, DCLDoesNotResetTimer) {
SimulateNavigationStart(t0);
// Network is forever quiet for this test.
SetActiveConnections(1);
- SimulateFMPDetected(
- /* fmp_time */ t0 + base::TimeDelta::FromSeconds(3),
+ SimulateFCPDetected(
+ /* fcp_time */ t0 + base::TimeDelta::FromSeconds(3),
/* detection_time */ t0 + base::TimeDelta::FromSeconds(4));
SimulateLongTask(t0 + base::TimeDelta::FromSeconds(5),
t0 + base::TimeDelta::FromSecondsD(5.1));
@@ -274,14 +285,14 @@ TEST_F(InteractiveDetectorTest, DCLDoesNotResetTimer) {
EXPECT_EQ(GetInteractiveTime(), t0 + base::TimeDelta::FromSeconds(8));
}
-TEST_F(InteractiveDetectorTest, DCL_FMP_FmpDetect_LT) {
+TEST_F(InteractiveDetectorTest, DCL_FCP_FcpDetect_LT) {
base::TimeTicks t0 = Now();
SimulateNavigationStart(t0);
// Network is forever quiet for this test.
SetActiveConnections(1);
SimulateDOMContentLoadedEnd(t0 + base::TimeDelta::FromSeconds(3));
- SimulateFMPDetected(
- /* fmp_time */ t0 + base::TimeDelta::FromSeconds(4),
+ SimulateFCPDetected(
+ /* fcp_time */ t0 + base::TimeDelta::FromSeconds(4),
/* detection_time */ t0 + base::TimeDelta::FromSeconds(5));
SimulateLongTask(t0 + base::TimeDelta::FromSeconds(7),
t0 + base::TimeDelta::FromSecondsD(7.1));
@@ -292,7 +303,7 @@ TEST_F(InteractiveDetectorTest, DCL_FMP_FmpDetect_LT) {
EXPECT_EQ(GetInteractiveTime(), t0 + base::TimeDelta::FromSecondsD(7.1));
}
-TEST_F(InteractiveDetectorTest, DCL_FMP_LT_FmpDetect) {
+TEST_F(InteractiveDetectorTest, DCL_FCP_LT_FcpDetect) {
base::TimeTicks t0 = Now();
SimulateNavigationStart(t0);
// Network is forever quiet for this test.
@@ -300,8 +311,8 @@ TEST_F(InteractiveDetectorTest, DCL_FMP_LT_FmpDetect) {
SimulateDOMContentLoadedEnd(t0 + base::TimeDelta::FromSeconds(3));
SimulateLongTask(t0 + base::TimeDelta::FromSeconds(7),
t0 + base::TimeDelta::FromSecondsD(7.1));
- SimulateFMPDetected(
- /* fmp_time */ t0 + base::TimeDelta::FromSeconds(3),
+ SimulateFCPDetected(
+ /* fcp_time */ t0 + base::TimeDelta::FromSeconds(3),
/* detection_time */ t0 + base::TimeDelta::FromSeconds(5));
// Run till 5 seconds after long task end.
RunTillTimestamp((t0 + base::TimeDelta::FromSecondsD(7.1)) +
@@ -310,13 +321,13 @@ TEST_F(InteractiveDetectorTest, DCL_FMP_LT_FmpDetect) {
EXPECT_EQ(GetInteractiveTime(), t0 + base::TimeDelta::FromSecondsD(7.1));
}
-TEST_F(InteractiveDetectorTest, FMP_FmpDetect_LT_DCL) {
+TEST_F(InteractiveDetectorTest, FCP_FcpDetect_LT_DCL) {
base::TimeTicks t0 = Now();
SimulateNavigationStart(t0);
// Network is forever quiet for this test.
SetActiveConnections(1);
- SimulateFMPDetected(
- /* fmp_time */ t0 + base::TimeDelta::FromSeconds(3),
+ SimulateFCPDetected(
+ /* fcp_time */ t0 + base::TimeDelta::FromSeconds(3),
/* detection_time */ t0 + base::TimeDelta::FromSeconds(4));
SimulateLongTask(t0 + base::TimeDelta::FromSeconds(7),
t0 + base::TimeDelta::FromSecondsD(7.1));
@@ -328,13 +339,13 @@ TEST_F(InteractiveDetectorTest, FMP_FmpDetect_LT_DCL) {
EXPECT_EQ(GetInteractiveTime(), t0 + base::TimeDelta::FromSeconds(8));
}
-TEST_F(InteractiveDetectorTest, DclIsMoreThan5sAfterFMP) {
+TEST_F(InteractiveDetectorTest, DclIsMoreThan5sAfterFCP) {
base::TimeTicks t0 = Now();
SimulateNavigationStart(t0);
// Network is forever quiet for this test.
SetActiveConnections(1);
- SimulateFMPDetected(
- /* fmp_time */ t0 + base::TimeDelta::FromSeconds(3),
+ SimulateFCPDetected(
+ /* fcp_time */ t0 + base::TimeDelta::FromSeconds(3),
/* detection_time */ t0 + base::TimeDelta::FromSeconds(4));
SimulateLongTask(t0 + base::TimeDelta::FromSeconds(7),
t0 + base::TimeDelta::FromSecondsD(7.1)); // Long task 1.
@@ -359,8 +370,8 @@ TEST_F(InteractiveDetectorTest, NetworkBusyBlocksTTIEvenWhenMainThreadQuiet) {
t0 + base::TimeDelta::FromSecondsD(3.4)); // Request 2 start.
SimulateResourceLoadBegin(t0 + base::TimeDelta::FromSecondsD(
3.5)); // Request 3 start. Network busy.
- SimulateFMPDetected(
- /* fmp_time */ t0 + base::TimeDelta::FromSeconds(3),
+ SimulateFCPDetected(
+ /* fcp_time */ t0 + base::TimeDelta::FromSeconds(3),
/* detection_time */ t0 + base::TimeDelta::FromSeconds(4));
SimulateLongTask(t0 + base::TimeDelta::FromSeconds(7),
t0 + base::TimeDelta::FromSecondsD(7.1)); // Long task 1.
@@ -376,7 +387,11 @@ TEST_F(InteractiveDetectorTest, NetworkBusyBlocksTTIEvenWhenMainThreadQuiet) {
EXPECT_EQ(GetInteractiveTime(), (t0 + base::TimeDelta::FromSecondsD(13.1)));
}
-TEST_F(InteractiveDetectorTest, LongEnoughQuietWindowBetweenFMPAndFmpDetect) {
+// FCP is a presentation timestamp, which is computed by another process and
+// thus received asynchronously by the renderer process. Therefore, there can be
+// some delay between the time in which FCP occurs and the time in which FCP is
+// detected by the renderer.
+TEST_F(InteractiveDetectorTest, LongEnoughQuietWindowBetweenFCPAndFcpDetect) {
base::TimeTicks t0 = Now();
SimulateNavigationStart(t0);
SetActiveConnections(1);
@@ -389,12 +404,12 @@ TEST_F(InteractiveDetectorTest, LongEnoughQuietWindowBetweenFMPAndFmpDetect) {
t0 + base::TimeDelta::FromSecondsD(8.4)); // Request 2 start.
SimulateResourceLoadBegin(t0 + base::TimeDelta::FromSecondsD(
8.5)); // Request 3 start. Network busy.
- SimulateFMPDetected(
- /* fmp_time */ t0 + base::TimeDelta::FromSeconds(3),
+ SimulateFCPDetected(
+ /* fcp_time */ t0 + base::TimeDelta::FromSeconds(3),
/* detection_time */ t0 + base::TimeDelta::FromSeconds(10));
// Even though network is currently busy and we have long task finishing
// recently, we should be able to detect that the page already achieved TTI at
- // FMP.
+ // FCP.
EXPECT_EQ(GetInteractiveTime(), t0 + base::TimeDelta::FromSeconds(3));
}
@@ -407,8 +422,8 @@ TEST_F(InteractiveDetectorTest, NetworkBusyEndIsNotTTI) {
t0 + base::TimeDelta::FromSecondsD(3.4)); // Request 2 start.
SimulateResourceLoadBegin(t0 + base::TimeDelta::FromSecondsD(
3.5)); // Request 3 start. Network busy.
- SimulateFMPDetected(
- /* fmp_time */ t0 + base::TimeDelta::FromSeconds(3),
+ SimulateFCPDetected(
+ /* fcp_time */ t0 + base::TimeDelta::FromSeconds(3),
/* detection_time */ t0 + base::TimeDelta::FromSeconds(4));
SimulateLongTask(t0 + base::TimeDelta::FromSeconds(7),
t0 + base::TimeDelta::FromSecondsD(7.1)); // Long task 1.
@@ -423,7 +438,7 @@ TEST_F(InteractiveDetectorTest, NetworkBusyEndIsNotTTI) {
EXPECT_EQ(GetInteractiveTime(), t0 + base::TimeDelta::FromSecondsD(13.1));
}
-TEST_F(InteractiveDetectorTest, LateLongTaskWithLateFMPDetection) {
+TEST_F(InteractiveDetectorTest, LateLongTaskWithLateFCPDetection) {
base::TimeTicks t0 = Now();
SimulateNavigationStart(t0);
SetActiveConnections(1);
@@ -438,8 +453,8 @@ TEST_F(InteractiveDetectorTest, LateLongTaskWithLateFMPDetection) {
base::TimeDelta::FromSeconds(8)); // Network quiet.
SimulateLongTask(t0 + base::TimeDelta::FromSeconds(14),
t0 + base::TimeDelta::FromSecondsD(14.1)); // Long task 2.
- SimulateFMPDetected(
- /* fmp_time */ t0 + base::TimeDelta::FromSeconds(3),
+ SimulateFCPDetected(
+ /* fcp_time */ t0 + base::TimeDelta::FromSeconds(3),
/* detection_time */ t0 + base::TimeDelta::FromSeconds(20));
// TTI reached at long task 1 end, NOT at long task 2 end.
EXPECT_EQ(GetInteractiveTime(), t0 + base::TimeDelta::FromSecondsD(7.1));
@@ -450,8 +465,8 @@ TEST_F(InteractiveDetectorTest, IntermittentNetworkBusyBlocksTTI) {
SimulateNavigationStart(t0);
SetActiveConnections(1);
SimulateDOMContentLoadedEnd(t0 + base::TimeDelta::FromSeconds(2));
- SimulateFMPDetected(
- /* fmp_time */ t0 + base::TimeDelta::FromSeconds(3),
+ SimulateFCPDetected(
+ /* fcp_time */ t0 + base::TimeDelta::FromSeconds(3),
/* detection_time */ t0 + base::TimeDelta::FromSeconds(4));
SimulateLongTask(t0 + base::TimeDelta::FromSeconds(7),
t0 + base::TimeDelta::FromSecondsD(7.1)); // Long task 1.
@@ -484,8 +499,8 @@ TEST_F(InteractiveDetectorTest, InvalidatingUserInput) {
// Network is forever quiet for this test.
SetActiveConnections(1);
SimulateDOMContentLoadedEnd(t0 + base::TimeDelta::FromSeconds(2));
- SimulateFMPDetected(
- /* fmp_time */ t0 + base::TimeDelta::FromSeconds(3),
+ SimulateFCPDetected(
+ /* fcp_time */ t0 + base::TimeDelta::FromSeconds(3),
/* detection_time */ t0 + base::TimeDelta::FromSeconds(4));
SimulateInteractiveInvalidatingInput(t0 + base::TimeDelta::FromSeconds(5));
SimulateLongTask(t0 + base::TimeDelta::FromSeconds(7),
@@ -497,53 +512,6 @@ TEST_F(InteractiveDetectorTest, InvalidatingUserInput) {
// invalidating user input. Page Load Metrics filters out this value in the
// browser process for UMA reporting.
EXPECT_EQ(GetInteractiveTime(), t0 + base::TimeDelta::FromSecondsD(7.1));
- EXPECT_EQ(GetDetector()->GetFirstInvalidatingInputTime(),
- t0 + base::TimeDelta::FromSeconds(5));
-}
-
-TEST_F(InteractiveDetectorTest, InvalidatingUserInputClampedAtNavStart) {
- base::TimeTicks t0 = Now();
- SimulateNavigationStart(t0);
- // Network is forever quiet for this test.
- SetActiveConnections(1);
- SimulateDOMContentLoadedEnd(t0 + base::TimeDelta::FromSeconds(2));
- SimulateFMPDetected(
- /* fmp_time */ t0 + base::TimeDelta::FromSeconds(3),
- /* detection_time */ t0 + base::TimeDelta::FromSeconds(4));
- // Invalidating input timestamp is earlier than navigation start.
- SimulateInteractiveInvalidatingInput(t0 - base::TimeDelta::FromSeconds(10));
- // Run till 5 seconds after FMP.
- RunTillTimestamp((t0 + base::TimeDelta::FromSecondsD(7.1)) +
- base::TimeDelta::FromSecondsD(5.0 + 0.1));
- EXPECT_EQ(GetInteractiveTime(),
- t0 + base::TimeDelta::FromSeconds(3)); // TTI at FMP.
- // Invalidating input timestamp is clamped at navigation start.
- EXPECT_EQ(GetDetector()->GetFirstInvalidatingInputTime(), t0);
-}
-
-TEST_F(InteractiveDetectorTest, InvalidatedFMP) {
- base::TimeTicks t0 = Now();
- SimulateNavigationStart(t0);
- // Network is forever quiet for this test.
- SetActiveConnections(1);
- SimulateInteractiveInvalidatingInput(t0 + base::TimeDelta::FromSeconds(1));
- SimulateDOMContentLoadedEnd(t0 + base::TimeDelta::FromSeconds(2));
- RunTillTimestamp(t0 +
- base::TimeDelta::FromSeconds(4)); // FMP Detection time.
- GetDetector()->OnFirstMeaningfulPaintDetected(
- t0 + base::TimeDelta::FromSeconds(3),
- FirstMeaningfulPaintDetector::kHadUserInput);
- // Run till 5 seconds after FMP.
- RunTillTimestamp((t0 + base::TimeDelta::FromSeconds(3)) +
- base::TimeDelta::FromSecondsD(5.0 + 0.1));
- // Since FMP was invalidated, we do not have TTI or TTI Detection Time.
- EXPECT_EQ(GetInteractiveTime(), base::TimeTicks());
- EXPECT_EQ(
- GetDetector()->GetInteractiveDetectionTime().since_origin().InSecondsF(),
- 0.0);
- // Invalidating input timestamp is available.
- EXPECT_EQ(GetDetector()->GetFirstInvalidatingInputTime(),
- t0 + base::TimeDelta::FromSeconds(1));
}
TEST_F(InteractiveDetectorTest, TaskLongerThan5sBlocksTTI) {
@@ -551,7 +519,7 @@ TEST_F(InteractiveDetectorTest, TaskLongerThan5sBlocksTTI) {
GetDetector()->SetNavigationStartTime(t0);
SimulateDOMContentLoadedEnd(t0 + base::TimeDelta::FromSeconds(2));
- SimulateFMPDetected(t0 + base::TimeDelta::FromSeconds(3),
+ SimulateFCPDetected(t0 + base::TimeDelta::FromSeconds(3),
t0 + base::TimeDelta::FromSeconds(4));
// Post a task with 6 seconds duration.
@@ -563,7 +531,7 @@ TEST_F(InteractiveDetectorTest, TaskLongerThan5sBlocksTTI) {
// We should be able to detect TTI 5s after the end of long task.
platform_->RunForPeriodSeconds(5.1);
- EXPECT_EQ(GetDetector()->GetInteractiveTime(), GetDummyTaskEndTime());
+ EXPECT_EQ(GetInteractiveTime(), GetDummyTaskEndTime());
}
TEST_F(InteractiveDetectorTest, LongTaskAfterTTIDoesNothing) {
@@ -571,7 +539,7 @@ TEST_F(InteractiveDetectorTest, LongTaskAfterTTIDoesNothing) {
GetDetector()->SetNavigationStartTime(t0);
SimulateDOMContentLoadedEnd(t0 + base::TimeDelta::FromSeconds(2));
- SimulateFMPDetected(t0 + base::TimeDelta::FromSeconds(3),
+ SimulateFCPDetected(t0 + base::TimeDelta::FromSeconds(3),
t0 + base::TimeDelta::FromSeconds(4));
// Long task 1.
@@ -584,7 +552,7 @@ TEST_F(InteractiveDetectorTest, LongTaskAfterTTIDoesNothing) {
base::TimeTicks long_task_1_end_time = GetDummyTaskEndTime();
// We should be able to detect TTI 5s after the end of long task.
platform_->RunForPeriodSeconds(5.1);
- EXPECT_EQ(GetDetector()->GetInteractiveTime(), long_task_1_end_time);
+ EXPECT_EQ(GetInteractiveTime(), long_task_1_end_time);
// Long task 2.
Thread::Current()->GetTaskRunner()->PostTask(
@@ -595,7 +563,101 @@ TEST_F(InteractiveDetectorTest, LongTaskAfterTTIDoesNothing) {
// Wait 5 seconds to see if TTI time changes.
platform_->RunForPeriodSeconds(5.1);
// TTI time should not change.
- EXPECT_EQ(GetDetector()->GetInteractiveTime(), long_task_1_end_time);
+ EXPECT_EQ(GetInteractiveTime(), long_task_1_end_time);
+}
+
+TEST_F(InteractiveDetectorTest, RecordInputDelayUKM) {
+ base::TimeDelta delay = 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();
+
+ ukm::TestAutoSetUkmRecorder test_ukm_recorder;
+ GetDetector()->SetUkmRecorderForTesting(&test_ukm_recorder);
+ GetDetector()->HandleForInputDelay(event, event_platform_timestamp,
+ processing_start);
+ 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());
+}
+
+// In tests for Total Blocking Time (TBT) we call SetTimeToInteractive() instead
+// of allowing TimeToInteractive to occur because the computation is gated
+// behind tracing being enabled, which means that they won't run by default. In
+// addition, further complication stems from the fact that the vector of
+// longtasks is cleared at the end of OnTimeToInteractiveDetected(). Therefore,
+// the simplest solution is to manually set all of the relevant variables and
+// check the correctness of the method ComputeTotalBlockingTime(). This can be
+// revisited if we move TBT computations to occur outside of the trace event.
+TEST_F(InteractiveDetectorTest, TotalBlockingTimeZero) {
+ base::TimeTicks t0 = Now();
+ SimulateNavigationStart(t0);
+ // Set a high number of active connections, so that
+ // OnTimeToInteractiveDetected() is not called by accident.
+ SetActiveConnections(5);
+ SimulateFCPDetected(
+ /* fcp_time */ t0 + base::TimeDelta::FromMilliseconds(100),
+ /* detection_time */ t0 + base::TimeDelta::FromMilliseconds(100));
+
+ // Longtask of duration 51ms, but only 50ms occur after FCP.
+ SimulateLongTask(t0 + base::TimeDelta::FromMilliseconds(99),
+ t0 + base::TimeDelta::FromMilliseconds(150));
+ // Longtask of duration 59ms, but only 49ms occur before TTI.
+ SimulateLongTask(t0 + base::TimeDelta::FromMilliseconds(201),
+ t0 + base::TimeDelta::FromMilliseconds(260));
+ SetTimeToInteractive(t0 + base::TimeDelta::FromMilliseconds(250));
+ EXPECT_EQ(GetTotalBlockingTime(), base::TimeDelta());
+}
+
+TEST_F(InteractiveDetectorTest, TotalBlockingTimeNonZero) {
+ base::TimeTicks t0 = Now();
+ SimulateNavigationStart(t0);
+ // Set a high number of active connections, so that
+ // OnTimeToInteractiveDetected() is not called by accident.
+ SetActiveConnections(5);
+ SimulateFCPDetected(
+ /* fcp_time */ t0 + base::TimeDelta::FromMilliseconds(100),
+ /* detection_time */ t0 + base::TimeDelta::FromMilliseconds(100));
+
+ // Longtask fully before FCP.
+ SimulateLongTask(t0 + base::TimeDelta::FromMilliseconds(30),
+ t0 + base::TimeDelta::FromMilliseconds(89));
+ // Longtask of duration 70ms, 60 ms of which occur after FCP. +10ms to TBT.
+ SimulateLongTask(t0 + base::TimeDelta::FromMilliseconds(90),
+ t0 + base::TimeDelta::FromMilliseconds(160));
+ // Longtask of duration 80ms between FCP and TTI. +30ms to TBT.
+ SimulateLongTask(t0 + base::TimeDelta::FromMilliseconds(200),
+ t0 + base::TimeDelta::FromMilliseconds(280));
+ // Longtask of duration 90ms, 70ms of which occur before TTI. +20ms to TBT.
+ SimulateLongTask(t0 + base::TimeDelta::FromMilliseconds(300),
+ t0 + base::TimeDelta::FromMilliseconds(390));
+ // Longtask fully after TTI.
+ SimulateLongTask(t0 + base::TimeDelta::FromMilliseconds(371),
+ t0 + base::TimeDelta::FromMilliseconds(472));
+ SetTimeToInteractive(t0 + base::TimeDelta::FromMilliseconds(370));
+ EXPECT_EQ(GetTotalBlockingTime(), base::TimeDelta::FromMilliseconds(60));
+}
+
+TEST_F(InteractiveDetectorTest, TotalBlockingSingleTask) {
+ base::TimeTicks t0 = Now();
+ SimulateNavigationStart(t0);
+ // Set a high number of active connections, so that
+ // OnTimeToInteractiveDetected() is not called by accident.
+ SetActiveConnections(5);
+ SimulateFCPDetected(
+ /* fcp_time */ t0 + base::TimeDelta::FromMilliseconds(100),
+ /* detection_time */ t0 + base::TimeDelta::FromMilliseconds(100));
+
+ // Longtask of duration 1s, from navigation start.
+ SimulateLongTask(t0, t0 + base::TimeDelta::FromSeconds(1));
+ SetTimeToInteractive(t0 + base::TimeDelta::FromMilliseconds(500));
+ // Truncated longtask is of length 400. So TBT is 400 - 50 = 350
+ EXPECT_EQ(GetTotalBlockingTime(), base::TimeDelta::FromMilliseconds(350));
}
} // namespace blink
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 23424d19da3..0624d7cfffd 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
@@ -6,6 +6,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/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/frame_owner.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
@@ -110,6 +111,11 @@ LazyImageHelper::DetermineEligibilityAndTrackVisibilityMetrics(
if (!url.ProtocolIsInHTTPFamily())
return LazyImageHelper::Eligibility::kDisabled;
+ // Do not lazyload image elements when JavaScript is disabled, regardless of
+ // the `loading` attribute.
+ if (!frame.GetDocument()->CanExecuteScripts(kNotAboutToExecuteScript))
+ return LazyImageHelper::Eligibility::kDisabled;
+
const auto lazy_load_image_setting = frame.GetLazyLoadImageSetting();
LoadingAttrValue loading_attr = GetLoadingAttrValue(*html_image);
bool is_fully_loadable =
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 44d6cdee3df..755214834da 100644
--- a/chromium/third_party/blink/renderer/core/loader/link_loader.cc
+++ b/chromium/third_party/blink/renderer/core/loader/link_loader.cc
@@ -31,7 +31,6 @@
#include "third_party/blink/renderer/core/loader/link_loader.h"
-#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/prerender/prerender_rel_type.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -49,7 +48,6 @@
#include "third_party/blink/renderer/platform/loader/fetch/resource_finish_observer.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
#include "third_party/blink/renderer/platform/loader/subresource_integrity.h"
-#include "third_party/blink/renderer/platform/prerender.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
@@ -76,15 +74,7 @@ unsigned PrerenderRelTypesFromRelAttribute(
} // namespace
-LinkLoader* LinkLoader::Create(LinkLoaderClient* client) {
- return MakeGarbageCollected<LinkLoader>(client,
- client->GetLoadingTaskRunner());
-}
-
-class LinkLoader::FinishObserver final
- : public GarbageCollected<LinkLoader::FinishObserver>,
- public ResourceFinishObserver {
- USING_GARBAGE_COLLECTED_MIXIN(FinishObserver);
+class LinkLoader::FinishObserver final : public ResourceFinishObserver {
USING_PRE_FINALIZER(FinishObserver, ClearResource);
public:
@@ -113,7 +103,7 @@ class LinkLoader::FinishObserver final
resource_ = nullptr;
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(loader_);
visitor->Trace(resource_);
blink::ResourceFinishObserver::Trace(visitor);
@@ -192,7 +182,7 @@ bool LinkLoader::LoadLink(const LinkLoadParameters& params,
Resource* resource = PreloadHelper::PreloadIfNeeded(
params, document, NullURL(), PreloadHelper::kLinkCalledFromMarkup,
- base::nullopt /* viewport_description */,
+ nullptr /* viewport_description */,
client_->IsLinkCreatedByParser() ? kParserInserted : kNotParserInserted);
if (!resource) {
resource = PreloadHelper::PrefetchIfNeeded(params, document);
@@ -201,7 +191,7 @@ bool LinkLoader::LoadLink(const LinkLoadParameters& params,
finish_observer_ = MakeGarbageCollected<FinishObserver>(this, resource);
PreloadHelper::ModulePreloadIfNeeded(
- params, document, base::nullopt /* viewport_description */, this);
+ params, document, nullptr /* viewport_description */, this);
if (const unsigned prerender_rel_types =
PrerenderRelTypesFromRelAttribute(params.rel, document)) {
@@ -228,9 +218,7 @@ void LinkLoader::LoadStylesheet(const LinkLoadParameters& params,
Document& document,
ResourceClient* link_client) {
Document* document_for_origin = &document;
- if (base::FeatureList::IsEnabled(
- features::kHtmlImportsRequestInitiatorLock) &&
- document.ImportsController()) {
+ if (document.ImportsController()) {
// For stylesheets loaded from HTML imported Documents, we use
// context document for getting origin and ResourceFetcher to use the main
// Document's origin, while using element document for CompleteURL() to use
@@ -251,7 +239,7 @@ void LinkLoader::LoadStylesheet(const LinkLoadParameters& params,
ResourceLoaderOptions options;
options.initiator_info.name = local_name;
- FetchParameters link_fetch_params(resource_request, options);
+ FetchParameters link_fetch_params(std::move(resource_request), options);
link_fetch_params.SetCharset(charset);
link_fetch_params.SetDefer(defer_option);
@@ -268,7 +256,8 @@ void LinkLoader::LoadStylesheet(const LinkLoadParameters& params,
if (!integrity_attr.IsEmpty()) {
IntegrityMetadataSet metadata_set;
SubresourceIntegrity::ParseIntegrityAttribute(
- integrity_attr, SubresourceIntegrityHelper::GetFeatures(&document),
+ integrity_attr,
+ SubresourceIntegrityHelper::GetFeatures(document.ToExecutionContext()),
metadata_set);
link_fetch_params.SetIntegrityMetadata(metadata_set);
link_fetch_params.MutableResourceRequest().SetFetchIntegrity(
@@ -290,7 +279,7 @@ void LinkLoader::Abort() {
}
}
-void LinkLoader::Trace(blink::Visitor* visitor) {
+void LinkLoader::Trace(Visitor* visitor) {
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 10d0724c02f..925ba7787c3 100644
--- a/chromium/third_party/blink/renderer/core/loader/link_loader.h
+++ b/chromium/third_party/blink/renderer/core/loader/link_loader.h
@@ -34,9 +34,9 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/loader/link_load_parameters.h"
+#include "third_party/blink/renderer/core/loader/private/prerender_client.h"
#include "third_party/blink/renderer/core/script/modulator.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h"
-#include "third_party/blink/renderer/platform/prerender_client.h"
namespace blink {
@@ -53,8 +53,6 @@ class CORE_EXPORT LinkLoader final : public SingleModuleClient,
USING_GARBAGE_COLLECTED_MIXIN(LinkLoader);
public:
- static LinkLoader* Create(LinkLoaderClient*);
-
LinkLoader(LinkLoaderClient*, scoped_refptr<base::SingleThreadTaskRunner>);
~LinkLoader() override;
@@ -75,7 +73,7 @@ class CORE_EXPORT LinkLoader final : public SingleModuleClient,
Resource* GetResourceForTesting();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 28e042239dd..3b47304175d 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(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) 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 e7233d67a19..fa6fc74d28b 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
@@ -21,9 +21,12 @@
#include "third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h"
#include "third_party/blink/renderer/core/testing/dummy_modulator.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
+#include "third_party/blink/renderer/core/testing/scoped_mock_overlay_scrollbars.h"
+#include "third_party/blink/renderer/platform/heap/heap.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/loader/fetch/resource_load_priority.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
@@ -39,9 +42,7 @@ class MockLinkLoaderClient final
public:
explicit MockLinkLoaderClient(bool should_load) : should_load_(should_load) {}
- void Trace(blink::Visitor* visitor) override {
- LinkLoaderClient::Trace(visitor);
- }
+ void Trace(Visitor* visitor) override { LinkLoaderClient::Trace(visitor); }
bool ShouldLoadLink() override { return should_load_; }
bool IsLinkCreatedByParser() override { return true; }
@@ -86,7 +87,8 @@ class NetworkHintsMock : public WebPrescientNetworking {
mutable bool allow_credentials_ = false;
};
-class LinkLoaderPreloadTestBase : public testing::Test {
+class LinkLoaderPreloadTestBase : public testing::Test,
+ private ScopedMockOverlayScrollbars {
public:
struct Expectations {
ResourceLoadPriority priority;
@@ -113,7 +115,8 @@ class LinkLoaderPreloadTestBase : public testing::Test {
Persistent<MockLinkLoaderClient> loader_client =
MakeGarbageCollected<MockLinkLoaderClient>(
expected.link_loader_should_load_value);
- LinkLoader* loader = LinkLoader::Create(loader_client.Get());
+ auto* loader = MakeGarbageCollected<LinkLoader>(
+ loader_client.Get(), loader_client.Get()->GetLoadingTaskRunner());
// TODO(crbug.com/751425): We should use the mock functionality
// via |dummy_page_holder_|.
url_test_helpers::RegisterMockedErrorURLLoad(params.href);
@@ -324,8 +327,7 @@ constexpr network::mojom::ReferrerPolicy kPreloadReferrerPolicyTestParams[] = {
network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin,
network::mojom::ReferrerPolicy::kSameOrigin,
network::mojom::ReferrerPolicy::kStrictOrigin,
- network::mojom::ReferrerPolicy::
- kNoReferrerWhenDowngradeOriginWhenCrossOrigin,
+ network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin,
network::mojom::ReferrerPolicy::kNever};
class LinkLoaderPreloadReferrerPolicyTest
@@ -369,8 +371,8 @@ TEST_P(LinkLoaderPreloadNonceTest, Preload) {
dummy_page_holder_->GetDocument()
.GetContentSecurityPolicy()
->DidReceiveHeader(test_case.content_security_policy,
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ network::mojom::ContentSecurityPolicyType::kEnforce,
+ network::mojom::ContentSecurityPolicySource::kHTTP);
LinkLoadParameters params(
LinkRelAttribute("preload"), kCrossOriginAttributeNotSet, String(),
"script", String(), test_case.nonce, String(), String(),
@@ -468,7 +470,8 @@ constexpr ModulePreloadTestParams kModulePreloadTestParams[] = {
true, network::mojom::CredentialsMode::kSameOrigin}};
class LinkLoaderModulePreloadTest
- : public testing::TestWithParam<ModulePreloadTestParams> {};
+ : public testing::TestWithParam<ModulePreloadTestParams>,
+ private ScopedMockOverlayScrollbars {};
class ModulePreloadTestModulator final : public DummyModulator {
public:
@@ -511,7 +514,8 @@ TEST_P(LinkLoaderModulePreloadTest, ModulePreload) {
modulator);
Persistent<MockLinkLoaderClient> loader_client =
MakeGarbageCollected<MockLinkLoaderClient>(true);
- LinkLoader* loader = LinkLoader::Create(loader_client.Get());
+ auto* loader = MakeGarbageCollected<LinkLoader>(
+ loader_client.Get(), loader_client.Get()->GetLoadingTaskRunner());
KURL href_url = KURL(NullURL(), test_case.href);
LinkLoadParameters params(
LinkRelAttribute("modulepreload"), test_case.cross_origin,
@@ -528,7 +532,8 @@ INSTANTIATE_TEST_SUITE_P(LinkLoaderModulePreloadTest,
class LinkLoaderTestPrefetchPrivacyChanges
: public testing::Test,
- public testing::WithParamInterface<bool> {
+ public testing::WithParamInterface<bool>,
+ private ScopedMockOverlayScrollbars {
public:
LinkLoaderTestPrefetchPrivacyChanges()
: privacy_changes_enabled_(GetParam()) {}
@@ -560,7 +565,8 @@ TEST_P(LinkLoaderTestPrefetchPrivacyChanges, PrefetchPrivacyChanges) {
dummy_page_holder->GetFrame().GetSettings()->SetScriptEnabled(true);
Persistent<MockLinkLoaderClient> loader_client =
MakeGarbageCollected<MockLinkLoaderClient>(true);
- LinkLoader* loader = LinkLoader::Create(loader_client.Get());
+ auto* loader = MakeGarbageCollected<LinkLoader>(
+ loader_client.Get(), loader_client.Get()->GetLoadingTaskRunner());
KURL href_url = KURL(NullURL(), "http://example.test/cat.jpg");
// TODO(crbug.com/751425): We should use the mock functionality
// via |dummy_page_holder|.
@@ -583,13 +589,16 @@ TEST_P(LinkLoaderTestPrefetchPrivacyChanges, PrefetchPrivacyChanges) {
EXPECT_EQ(resource->GetResourceRequest().GetRedirectMode(),
network::mojom::RedirectMode::kFollow);
EXPECT_EQ(resource->GetResourceRequest().GetReferrerPolicy(),
- network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade);
+ RuntimeEnabledFeatures::ReducedReferrerGranularityEnabled()
+ ? network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin
+ : network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade);
}
platform_->GetURLLoaderMockFactory()->UnregisterAllURLsAndClearMemoryCache();
}
-class LinkLoaderTest : public testing::Test {
+class LinkLoaderTest : public testing::Test,
+ private ScopedMockOverlayScrollbars {
protected:
ScopedTestingPlatformSupport<TestingPlatformSupport> platform_;
};
@@ -625,7 +634,8 @@ TEST_F(LinkLoaderTest, Prefetch) {
Persistent<MockLinkLoaderClient> loader_client =
MakeGarbageCollected<MockLinkLoaderClient>(
test_case.link_loader_should_load_value);
- LinkLoader* loader = LinkLoader::Create(loader_client.Get());
+ auto* loader = MakeGarbageCollected<LinkLoader>(
+ loader_client.Get(), loader_client.Get()->GetLoadingTaskRunner());
KURL href_url = KURL(NullURL(), test_case.href);
// TODO(crbug.com/751425): We should use the mock functionality
// via |dummy_page_holder|.
@@ -678,7 +688,8 @@ TEST_F(LinkLoaderTest, DNSPrefetch) {
dummy_page_holder->GetFrame().PrescientNetworking());
Persistent<MockLinkLoaderClient> loader_client =
MakeGarbageCollected<MockLinkLoaderClient>(test_case.should_load);
- LinkLoader* loader = LinkLoader::Create(loader_client.Get());
+ auto* loader = MakeGarbageCollected<LinkLoader>(
+ loader_client.Get(), loader_client.Get()->GetLoadingTaskRunner());
KURL href_url = KURL(KURL(String("http://example.com")), test_case.href);
LinkLoadParameters params(
LinkRelAttribute("dns-prefetch"), kCrossOriginAttributeNotSet, String(),
@@ -717,7 +728,8 @@ TEST_F(LinkLoaderTest, Preconnect) {
dummy_page_holder->GetFrame().PrescientNetworking());
Persistent<MockLinkLoaderClient> loader_client =
MakeGarbageCollected<MockLinkLoaderClient>(test_case.should_load);
- LinkLoader* loader = LinkLoader::Create(loader_client.Get());
+ auto* loader = MakeGarbageCollected<LinkLoader>(
+ loader_client.Get(), loader_client.Get()->GetLoadingTaskRunner());
KURL href_url = KURL(KURL(String("http://example.com")), test_case.href);
LinkLoadParameters params(
LinkRelAttribute("preconnect"), test_case.cross_origin, String(),
@@ -744,7 +756,8 @@ TEST_F(LinkLoaderTest, PreloadAndPrefetch) {
dummy_page_holder->GetFrame().GetSettings()->SetScriptEnabled(true);
Persistent<MockLinkLoaderClient> loader_client =
MakeGarbageCollected<MockLinkLoaderClient>(true);
- LinkLoader* loader = LinkLoader::Create(loader_client.Get());
+ auto* loader = MakeGarbageCollected<LinkLoader>(
+ loader_client.Get(), loader_client.Get()->GetLoadingTaskRunner());
KURL href_url = KURL(KURL(), "https://www.example.com/");
// TODO(crbug.com/751425): We should use the mock functionality
// via |dummy_page_holder|.
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 a78063e2fd5..488eb143003 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(blink::Visitor* visitor) {
+void LongTaskDetector::Trace(Visitor* visitor) {
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 efb1675d751..b32e9165efb 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(blink::Visitor*);
+ void Trace(Visitor*);
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 cc47ffb5550..76cf757241c 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
@@ -32,9 +32,10 @@
#include "base/metrics/field_trial_params.h"
#include "services/network/public/mojom/ip_address_space.mojom-blink.h"
#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/common/security_context/insecure_request_policy.h"
#include "third_party/blink/public/mojom/loader/request_context_frame_type.mojom-blink.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
#include "third_party/blink/public/platform/web_content_settings_client.h"
-#include "third_party/blink/public/platform/web_insecure_request_policy.h"
#include "third_party/blink/public/platform/web_mixed_content.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/platform/web_worker_fetch_context.h"
@@ -50,6 +51,7 @@
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h"
#include "third_party/blink/renderer/core/workers/worker_settings.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/resource_fetcher_properties.h"
#include "third_party/blink/renderer/platform/network/network_utils.h"
@@ -157,7 +159,7 @@ const char* RequestContextName(mojom::RequestContextType context) {
// TODO(hiroshige): Consider merging them once FetchClientSettingsObject
// becomes the source of CSP/InsecureRequestPolicy also in frames.
bool IsWebSocketAllowedInFrame(const BaseFetchContext& fetch_context,
- SecurityContext* security_context,
+ const SecurityContext* security_context,
Settings* settings,
const KURL& url) {
fetch_context.CountUsage(WebFeature::kMixedContentPresent);
@@ -172,7 +174,9 @@ bool IsWebSocketAllowedInFrame(const BaseFetchContext& fetch_context,
// intentionally skip the client checks in order to prevent degrading the
// site's security UI.
bool strict_mode =
- security_context->GetInsecureRequestPolicy() & kBlockAllMixedContent ||
+ (security_context->GetInsecureRequestPolicy() &
+ mojom::blink::InsecureRequestPolicy::kBlockAllMixedContent) !=
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone ||
settings->GetStrictMixedContentChecking();
if (strict_mode)
return false;
@@ -193,11 +197,13 @@ bool IsWebSocketAllowedInWorker(const BaseFetchContext& fetch_context,
// If we're in strict mode, we'll automagically fail everything, and
// intentionally skip the client checks in order to prevent degrading the
// site's security UI.
- bool strict_mode = fetch_context.GetResourceFetcherProperties()
- .GetFetchClientSettingsObject()
- .GetInsecureRequestsPolicy() &
- kBlockAllMixedContent ||
- settings->GetStrictMixedContentChecking();
+ bool strict_mode =
+ (fetch_context.GetResourceFetcherProperties()
+ .GetFetchClientSettingsObject()
+ .GetInsecureRequestsPolicy() &
+ mojom::blink::InsecureRequestPolicy::kBlockAllMixedContent) !=
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone ||
+ settings->GetStrictMixedContentChecking();
if (strict_mode)
return false;
return settings && settings->GetAllowRunningOfInsecureContent();
@@ -308,12 +314,12 @@ ConsoleMessage* MixedContentChecker::CreateConsoleMessageAboutFetch(
allowed ? mojom::ConsoleMessageLevel::kWarning
: mojom::ConsoleMessageLevel::kError;
if (source_location) {
- return ConsoleMessage::Create(mojom::ConsoleMessageSource::kSecurity,
- message_level, message,
- std::move(source_location));
+ return MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kSecurity, message_level, message,
+ std::move(source_location));
}
- return ConsoleMessage::Create(mojom::ConsoleMessageSource::kSecurity,
- message_level, message);
+ return MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kSecurity, message_level, message);
}
// static
@@ -375,7 +381,7 @@ bool MixedContentChecker::ShouldBlockFetch(
mojom::RequestContextType request_context,
ResourceRequest::RedirectStatus redirect_status,
const KURL& url,
- SecurityViolationReportingPolicy reporting_policy) {
+ ReportingDisposition reporting_disposition) {
Frame* mixed_frame = InWhichFrameIsContentMixed(frame, url);
if (!mixed_frame)
return false;
@@ -419,8 +425,9 @@ bool MixedContentChecker::ShouldBlockFetch(
// intentionally skip the client checks in order to prevent degrading the
// site's security UI.
bool strict_mode =
- mixed_frame->GetSecurityContext()->GetInsecureRequestPolicy() &
- kBlockAllMixedContent ||
+ (mixed_frame->GetSecurityContext()->GetInsecureRequestPolicy() &
+ mojom::blink::InsecureRequestPolicy::kBlockAllMixedContent) !=
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone ||
settings->GetStrictMixedContentChecking();
WebMixedContentContextType context_type =
@@ -484,7 +491,7 @@ bool MixedContentChecker::ShouldBlockFetch(
break;
};
- if (reporting_policy == SecurityViolationReportingPolicy::kReport) {
+ if (reporting_disposition == ReportingDisposition::kReport) {
frame->GetDocument()->AddConsoleMessage(
CreateConsoleMessageAboutFetch(MainResourceUrlForFrame(mixed_frame),
url, request_context, allowed, nullptr));
@@ -498,7 +505,7 @@ bool MixedContentChecker::ShouldBlockFetchOnWorker(
mojom::RequestContextType request_context,
ResourceRequest::RedirectStatus redirect_status,
const KURL& url,
- SecurityViolationReportingPolicy reporting_policy,
+ ReportingDisposition reporting_disposition,
bool is_worklet_global_scope) {
const FetchClientSettingsObject& fetch_client_settings_object =
worker_fetch_context.GetResourceFetcherProperties()
@@ -529,8 +536,9 @@ bool MixedContentChecker::ShouldBlockFetchOnWorker(
allowed = false;
} else {
bool strict_mode =
- fetch_client_settings_object.GetInsecureRequestsPolicy() &
- kBlockAllMixedContent ||
+ (fetch_client_settings_object.GetInsecureRequestsPolicy() &
+ mojom::blink::InsecureRequestPolicy::kBlockAllMixedContent) !=
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone ||
settings->GetStrictMixedContentChecking();
bool should_ask_embedder =
!strict_mode && (!settings->GetStrictlyBlockBlockableMixedContent() ||
@@ -547,7 +555,7 @@ bool MixedContentChecker::ShouldBlockFetchOnWorker(
}
}
- if (reporting_policy == SecurityViolationReportingPolicy::kReport) {
+ if (reporting_disposition == ReportingDisposition::kReport) {
worker_fetch_context.AddConsoleMessage(CreateConsoleMessageAboutFetch(
worker_fetch_context.Url(), url, request_context, allowed, nullptr));
}
@@ -571,8 +579,8 @@ ConsoleMessage* MixedContentChecker::CreateConsoleMessageAboutWebSocket(
mojom::ConsoleMessageLevel message_level =
allowed ? mojom::ConsoleMessageLevel::kWarning
: mojom::ConsoleMessageLevel::kError;
- return ConsoleMessage::Create(mojom::ConsoleMessageSource::kSecurity,
- message_level, message);
+ return MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kSecurity, message_level, message);
}
// static
@@ -589,7 +597,7 @@ bool MixedContentChecker::IsWebSocketAllowed(
// mixed content signals from different frames on the same page.
WebContentSettingsClient* content_settings_client =
frame->GetContentSettingsClient();
- SecurityContext* security_context = mixed_frame->GetSecurityContext();
+ const SecurityContext* security_context = mixed_frame->GetSecurityContext();
const SecurityOrigin* security_origin = security_context->GetSecurityOrigin();
bool allowed = IsWebSocketAllowedInFrame(frame_fetch_context,
@@ -641,7 +649,7 @@ bool MixedContentChecker::IsWebSocketAllowed(
bool MixedContentChecker::IsMixedFormAction(
LocalFrame* frame,
const KURL& url,
- SecurityViolationReportingPolicy reporting_policy) {
+ ReportingDisposition reporting_disposition) {
// For whatever reason, some folks handle forms via JavaScript, and submit to
// `javascript:void(0)` rather than calling `preventDefault()`. We
// special-case `javascript:` URLs here, as they don't introduce MixedContent
@@ -659,7 +667,7 @@ bool MixedContentChecker::IsMixedFormAction(
// mixed content signals from different frames on the same page.
frame->GetLocalFrameHostRemote().DidContainInsecureFormAction();
- if (reporting_policy == SecurityViolationReportingPolicy::kReport) {
+ if (reporting_disposition == ReportingDisposition::kReport) {
String message = String::Format(
"Mixed Content: The page at '%s' was loaded over a secure connection, "
"but contains a form that targets an insecure endpoint '%s'. This "
@@ -667,8 +675,9 @@ bool MixedContentChecker::IsMixedFormAction(
MainResourceUrlForFrame(mixed_frame).ElidedString().Utf8().c_str(),
url.ElidedString().Utf8().c_str());
frame->GetDocument()->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kWarning, message));
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kSecurity,
+ mojom::ConsoleMessageLevel::kWarning, message));
}
return true;
@@ -697,12 +706,12 @@ bool MixedContentChecker::ShouldAutoupgrade(
blink::features::kMixedContentAutoupgradeModeParamName);
if (autoupgrade_mode ==
- blink::features::kMixedContentAutoupgradeModeNoImages) {
- return type != mojom::RequestContextType::IMAGE;
+ blink::features::kMixedContentAutoupgradeModeAllPassive) {
+ return true;
}
- // Otherwise we default to autoupgrading all mixed content.
- return true;
+ // Otherwise we default to excluding images.
+ return type != mojom::RequestContextType::IMAGE;
}
void MixedContentChecker::CheckMixedPrivatePublic(
@@ -713,7 +722,7 @@ void MixedContentChecker::CheckMixedPrivatePublic(
// Just count these for the moment, don't block them.
if (network_utils::IsReservedIPAddress(resource_ip_address) &&
- frame->GetDocument()->AddressSpace() ==
+ frame->GetDocument()->GetSecurityContext().AddressSpace() ==
network::mojom::IPAddressSpace::kPublic) {
UseCounter::Count(frame->GetDocument(),
WebFeature::kMixedContentPrivateHostnameInPublicHostname);
@@ -789,8 +798,9 @@ ConsoleMessage* MixedContentChecker::CreateConsoleMessageAboutFetchAutoupgrade(
"no-more-mixed-messages-about-https.html",
main_resource_url.ElidedString().Utf8().c_str(),
mixed_content_url.ElidedString().Utf8().c_str());
- return ConsoleMessage::Create(mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kWarning, message);
+ return MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kSecurity,
+ mojom::ConsoleMessageLevel::kWarning, message);
}
WebMixedContentContextType MixedContentChecker::ContextTypeForInspector(
@@ -812,7 +822,7 @@ void MixedContentChecker::UpgradeInsecureRequest(
ResourceRequest& resource_request,
const FetchClientSettingsObject* fetch_client_settings_object,
ExecutionContext* execution_context_for_logging,
- network::mojom::RequestContextFrameType frame_type,
+ mojom::RequestContextFrameType frame_type,
WebContentSettingsClient* settings_client) {
// We always upgrade requests that meet any of the following criteria:
// 1. Are for subresources.
@@ -830,17 +840,22 @@ void MixedContentChecker::UpgradeInsecureRequest(
DCHECK(fetch_client_settings_object);
- if (!(fetch_client_settings_object->GetInsecureRequestsPolicy() &
- kUpgradeInsecureRequests)) {
+ if ((fetch_client_settings_object->GetInsecureRequestsPolicy() &
+ mojom::blink::InsecureRequestPolicy::kUpgradeInsecureRequests) ==
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone) {
mojom::RequestContextType context = resource_request.GetRequestContext();
- if (context != mojom::RequestContextType::UNSPECIFIED &&
- resource_request.Url().ProtocolIs("http") &&
- MixedContentChecker::ShouldAutoupgrade(
+ if (context == mojom::RequestContextType::UNSPECIFIED ||
+ !MixedContentChecker::ShouldAutoupgrade(
fetch_client_settings_object->GetHttpsState(), context,
settings_client, fetch_client_settings_object->GlobalObjectUrl())) {
+ return;
+ }
+ // We set the upgrade if insecure flag regardless of whether we autoupgrade
+ // due to scheme not being http, so any redirects get upgraded.
+ resource_request.SetUpgradeIfInsecure(true);
+ if (resource_request.Url().ProtocolIs("http")) {
if (execution_context_for_logging->IsDocument()) {
- Document* document =
- static_cast<Document*>(execution_context_for_logging);
+ Document* document = Document::From(execution_context_for_logging);
document->AddConsoleMessage(
MixedContentChecker::CreateConsoleMessageAboutFetchAutoupgrade(
fetch_client_settings_object->GlobalObjectUrl(),
@@ -854,7 +869,7 @@ void MixedContentChecker::UpgradeInsecureRequest(
}
// Nested frames are always upgraded on the browser process.
- if (frame_type == network::mojom::RequestContextFrameType::kNested)
+ if (frame_type == mojom::RequestContextFrameType::kNested)
return;
// We set the UpgradeIfInsecure flag even if the current request wasn't
@@ -869,7 +884,7 @@ void MixedContentChecker::UpgradeInsecureRequest(
return;
}
- if (frame_type == network::mojom::RequestContextFrameType::kNone ||
+ if (frame_type == mojom::RequestContextFrameType::kNone ||
resource_request.GetRequestContext() == mojom::RequestContextType::FORM ||
(!url.Host().IsNull() &&
fetch_client_settings_object->GetUpgradeInsecureNavigationsSet()
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 43ff2693a5f..66b5f126416 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
@@ -39,7 +39,7 @@
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/loader/fetch/https_state.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
-#include "third_party/blink/renderer/platform/weborigin/security_violation_reporting_policy.h"
+#include "third_party/blink/renderer/platform/weborigin/reporting_disposition.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -69,18 +69,18 @@ class CORE_EXPORT MixedContentChecker final {
DISALLOW_NEW();
public:
- static bool ShouldBlockFetch(LocalFrame*,
- mojom::RequestContextType,
- ResourceRequest::RedirectStatus,
- const KURL&,
- SecurityViolationReportingPolicy =
- SecurityViolationReportingPolicy::kReport);
+ static bool ShouldBlockFetch(
+ LocalFrame*,
+ mojom::RequestContextType,
+ ResourceRequest::RedirectStatus,
+ const KURL&,
+ ReportingDisposition = ReportingDisposition::kReport);
static bool ShouldBlockFetchOnWorker(const WorkerFetchContext&,
mojom::RequestContextType,
ResourceRequest::RedirectStatus,
const KURL&,
- SecurityViolationReportingPolicy,
+ ReportingDisposition,
bool is_worklet_global_scope);
static bool IsWebSocketAllowed(const FrameFetchContext&,
@@ -90,10 +90,10 @@ class CORE_EXPORT MixedContentChecker final {
static bool IsMixedContent(const SecurityOrigin*, const KURL&);
static bool IsMixedContent(const FetchClientSettingsObject&, const KURL&);
- static bool IsMixedFormAction(LocalFrame*,
- const KURL&,
- SecurityViolationReportingPolicy =
- SecurityViolationReportingPolicy::kReport);
+ static bool IsMixedFormAction(
+ LocalFrame*,
+ const KURL&,
+ ReportingDisposition = ReportingDisposition::kReport);
static bool ShouldAutoupgrade(HttpsState context_https_state,
mojom::RequestContextType type,
@@ -133,7 +133,7 @@ class CORE_EXPORT MixedContentChecker final {
ResourceRequest&,
const FetchClientSettingsObject* fetch_client_settings_object,
ExecutionContext* execution_context_for_logging,
- network::mojom::RequestContextFrameType,
+ mojom::RequestContextFrameType,
WebContentSettingsClient* settings_client);
private:
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 ca4ec7f057d..2ce38372705 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
@@ -15,6 +15,7 @@
#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/dummy_page_holder.h"
+#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -40,15 +41,15 @@ TEST(MixedContentCheckerTest, IsMixedContent) {
{"https://example.com/foo", "https://example.com/foo", false},
{"https://example.com/foo", "wss://example.com/foo", false},
{"https://example.com/foo", "data:text/html,<p>Hi!</p>", false},
- {"https://example.com/foo", "http://127.0.0.1/", false},
- {"https://example.com/foo", "http://[::1]/", false},
{"https://example.com/foo", "blob:https://example.com/foo", false},
{"https://example.com/foo", "blob:http://example.com/foo", false},
{"https://example.com/foo", "blob:null/foo", false},
{"https://example.com/foo", "filesystem:https://example.com/foo", false},
{"https://example.com/foo", "filesystem:http://example.com/foo", false},
- {"https://example.com/foo", "http://localhost/", false},
+ {"https://example.com/foo", "http://127.0.0.1/", false},
+ {"https://example.com/foo", "http://[::1]/", false},
{"https://example.com/foo", "http://a.localhost/", false},
+ {"https://example.com/foo", "http://localhost/", false},
{"https://example.com/foo", "http://example.com/foo", true},
{"https://example.com/foo", "http://google.com/foo", true},
@@ -172,16 +173,16 @@ TEST(MixedContentCheckerTest, DetectMixedForm) {
EXPECT_TRUE(MixedContentChecker::IsMixedFormAction(
&dummy_page_holder->GetFrame(), http_form_action_url,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(MixedContentChecker::IsMixedFormAction(
&dummy_page_holder->GetFrame(), https_form_action_url,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_FALSE(MixedContentChecker::IsMixedFormAction(
&dummy_page_holder->GetFrame(), javascript_form_action_url,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
EXPECT_TRUE(MixedContentChecker::IsMixedFormAction(
&dummy_page_holder->GetFrame(), mailto_form_action_url,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
}
TEST(MixedContentCheckerTest, DetectMixedFavicon) {
@@ -205,13 +206,80 @@ TEST(MixedContentCheckerTest, DetectMixedFavicon) {
EXPECT_TRUE(MixedContentChecker::ShouldBlockFetch(
&dummy_page_holder->GetFrame(), mojom::RequestContextType::FAVICON,
ResourceRequest::RedirectStatus::kNoRedirect, http_favicon_url,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ 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,
- SecurityViolationReportingPolicy::kSuppressReporting));
+ ReportingDisposition::kSuppressReporting));
+}
+
+class TestFetchClientSettingsObject : public FetchClientSettingsObject {
+ public:
+ const KURL& GlobalObjectUrl() const override { return url; }
+ HttpsState GetHttpsState() const override { return HttpsState::kModern; }
+ mojom::blink::InsecureRequestPolicy GetInsecureRequestsPolicy()
+ const override {
+ return mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone;
+ }
+
+ // These are not used in test, but need to be implemented since they are pure
+ // virtual.
+ const KURL& BaseUrl() const override { return url; }
+ const SecurityOrigin* GetSecurityOrigin() const override { return nullptr; }
+ network::mojom::ReferrerPolicy GetReferrerPolicy() const override {
+ return network::mojom::ReferrerPolicy::kAlways;
+ }
+ const String GetOutgoingReferrer() const override { return ""; }
+ AllowedByNosniff::MimeTypeCheck MimeTypeCheckForClassicWorkerScript()
+ const override {
+ return AllowedByNosniff::MimeTypeCheck::kStrict;
+ }
+ network::mojom::IPAddressSpace GetAddressSpace() const override {
+ return network::mojom::IPAddressSpace::kLocal;
+ }
+ const InsecureNavigationsSet& GetUpgradeInsecureNavigationsSet()
+ const override {
+ return set;
+ }
+
+ private:
+ const KURL url = KURL("https://example.test");
+ const InsecureNavigationsSet set;
+};
+
+TEST(MixedContentCheckerTest,
+ NotAutoupgradedMixedContentHasUpgradeIfInsecureSet) {
+ ResourceRequest request;
+ request.SetUrl(KURL("https://example.test"));
+ request.SetRequestContext(mojom::RequestContextType::AUDIO);
+ TestFetchClientSettingsObject settings;
+ // Used to get a non-null document.
+ DummyPageHolder holder;
+
+ MixedContentChecker::UpgradeInsecureRequest(
+ request, &settings, holder.GetDocument().GetExecutionContext(),
+ mojom::RequestContextFrameType::kTopLevel, nullptr);
+
+ EXPECT_FALSE(request.IsAutomaticUpgrade());
+ EXPECT_TRUE(request.UpgradeIfInsecure());
+}
+
+TEST(MixedContentCheckerTest, AutoupgradedMixedContentHasUpgradeIfInsecureSet) {
+ ResourceRequest request;
+ request.SetUrl(KURL("http://example.test"));
+ request.SetRequestContext(mojom::RequestContextType::AUDIO);
+ TestFetchClientSettingsObject settings;
+ // Used to get a non-null document.
+ DummyPageHolder holder;
+
+ MixedContentChecker::UpgradeInsecureRequest(
+ request, &settings, holder.GetDocument().GetExecutionContext(),
+ mojom::RequestContextFrameType::kTopLevel, nullptr);
+
+ EXPECT_TRUE(request.IsAutomaticUpgrade());
+ EXPECT_TRUE(request.UpgradeIfInsecure());
}
} // namespace blink
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 e78233e41d3..29765436437 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
@@ -5,26 +5,25 @@
#include "third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
-#include "third_party/blink/renderer/core/script/layered_api.h"
#include "third_party/blink/renderer/platform/bindings/parkable_string.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
+DocumentModuleScriptFetcher::DocumentModuleScriptFetcher(
+ util::PassKey<ModuleScriptLoader> pass_key)
+ : ModuleScriptFetcher(pass_key) {}
+
void DocumentModuleScriptFetcher::Fetch(
FetchParameters& fetch_params,
ResourceFetcher* fetch_client_settings_object_fetcher,
- const Modulator* modulator_for_built_in_modules,
ModuleGraphLevel level,
ModuleScriptFetcher::Client* client) {
DCHECK(fetch_client_settings_object_fetcher);
DCHECK(!client_);
client_ = client;
- if (modulator_for_built_in_modules &&
- FetchIfLayeredAPI(*modulator_for_built_in_modules, fetch_params))
- return;
-
ScriptResource::Fetch(fetch_params, fetch_client_settings_object_fetcher,
this, ScriptResource::kNoStreaming);
}
@@ -49,44 +48,10 @@ void DocumentModuleScriptFetcher::NotifyFinished(Resource* resource) {
client_->NotifyFetchFinished(params, error_messages);
}
-void DocumentModuleScriptFetcher::Trace(blink::Visitor* visitor) {
+void DocumentModuleScriptFetcher::Trace(Visitor* visitor) {
+ ModuleScriptFetcher::Trace(visitor);
visitor->Trace(client_);
ResourceClient::Trace(visitor);
}
-bool DocumentModuleScriptFetcher::FetchIfLayeredAPI(
- const Modulator& modulator_for_built_in_modules,
- FetchParameters& fetch_params) {
- if (!modulator_for_built_in_modules.BuiltInModuleInfraEnabled())
- return false;
-
- KURL layered_api_url = blink::layered_api::GetInternalURL(fetch_params.Url());
-
- if (layered_api_url.IsNull())
- return false;
-
- String source_text = blink::layered_api::GetSourceText(
- modulator_for_built_in_modules, layered_api_url);
-
- if (source_text.IsNull()) {
- HeapVector<Member<ConsoleMessage>> error_messages;
- error_messages.push_back(ConsoleMessage::CreateForRequest(
- mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kError, "Unexpected data error",
- fetch_params.Url().GetString(), nullptr, 0));
- client_->NotifyFetchFinished(base::nullopt, error_messages);
- return true;
- }
-
- // TODO(hiroshige): Support V8 Code Cache for Layered API.
- // TODO(sasebree). Support Non-JS Modules for Layered API.
- ModuleScriptCreationParams params(
- layered_api_url,
- ModuleScriptCreationParams::ModuleType::kJavaScriptModule,
- ParkableString(source_text.ReleaseImpl()), nullptr /* cache_handler */,
- fetch_params.GetResourceRequest().GetCredentialsMode());
- client_->NotifyFetchFinished(params, HeapVector<Member<ConsoleMessage>>());
- return true;
-}
-
} // namespace blink
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 35ee3d74587..4ac35597297 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
@@ -21,13 +21,11 @@ class CORE_EXPORT DocumentModuleScriptFetcher final
USING_GARBAGE_COLLECTED_MIXIN(DocumentModuleScriptFetcher);
public:
- DocumentModuleScriptFetcher() = default;
- ~DocumentModuleScriptFetcher() override = default;
+ explicit DocumentModuleScriptFetcher(util::PassKey<ModuleScriptLoader>);
// Implements ModuleScriptFetcher.
void Fetch(FetchParameters&,
ResourceFetcher*,
- const Modulator* modulator_for_built_in_modules,
ModuleGraphLevel,
Client*) override;
@@ -35,12 +33,9 @@ class CORE_EXPORT DocumentModuleScriptFetcher final
void NotifyFinished(Resource*) override;
String DebugName() const override { return "DocumentModuleScriptFetcher"; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
- bool FetchIfLayeredAPI(const Modulator& modulator_for_built_in_modules,
- FetchParameters&);
-
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 d1976649db4..1862a248eb4 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
@@ -4,25 +4,30 @@
#include "third_party/blink/renderer/core/loader/modulescript/installed_service_worker_module_script_fetcher.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/appcache/appcache.mojom-blink.h"
+#include "third_party/blink/renderer/core/dom/dom_implementation.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/workers/installed_scripts_manager.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/core/workers/worker_thread.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
namespace blink {
InstalledServiceWorkerModuleScriptFetcher::
- InstalledServiceWorkerModuleScriptFetcher(WorkerGlobalScope* global_scope)
- : global_scope_(global_scope) {
+ InstalledServiceWorkerModuleScriptFetcher(
+ WorkerGlobalScope* global_scope,
+ util::PassKey<ModuleScriptLoader> pass_key)
+ : ModuleScriptFetcher(pass_key), global_scope_(global_scope) {
DCHECK(global_scope_->IsServiceWorkerGlobalScope());
}
void InstalledServiceWorkerModuleScriptFetcher::Fetch(
FetchParameters& fetch_params,
ResourceFetcher*,
- const Modulator* modulator_for_built_in_modules,
ModuleGraphLevel level,
ModuleScriptFetcher::Client* client) {
DCHECK(global_scope_->IsContextThread());
@@ -35,7 +40,7 @@ void InstalledServiceWorkerModuleScriptFetcher::Fetch(
if (!script_data) {
HeapVector<Member<ConsoleMessage>> error_messages;
- error_messages.push_back(ConsoleMessage::CreateForRequest(
+ error_messages.push_back(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kError,
"Failed to load the script unexpectedly",
@@ -72,21 +77,40 @@ void InstalledServiceWorkerModuleScriptFetcher::Fetch(
mojom::blink::kAppCacheNoCacheId);
}
- // TODO(sasebree). Figure out how to get the correct mime type for the
- // ModuleScriptCreationParams here. Hard-coding application/javascript will
- // cause JSON modules to break for service workers. We need to store the mime
- // type of the service worker scripts in ServiceWorkerStorage, and pass it up
- // to here via InstalledScriptManager.
+ ModuleScriptCreationParams::ModuleType module_type;
+
+ // TODO(sasebree) De-duplicate similar logic that lives in
+ // ModuleScriptFetcher::WasModuleLoadSuccessful
+ if (MIMETypeRegistry::IsSupportedJavaScriptMIMEType(
+ script_data->GetHttpContentType())) {
+ module_type = ModuleScriptCreationParams::ModuleType::kJavaScriptModule;
+ } else if (base::FeatureList::IsEnabled(blink::features::kJSONModules) &&
+ MIMETypeRegistry::IsJSONMimeType(
+ script_data->GetHttpContentType())) {
+ module_type = ModuleScriptCreationParams::ModuleType::kJSONModule;
+ } else {
+ // This should never happen.
+ // If we reach here, we know we received an incompatible mime type from the
+ // network
+ HeapVector<Member<ConsoleMessage>> error_messages;
+ error_messages.push_back(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kError,
+ "Failed to load the script unexpectedly",
+ fetch_params.Url().GetString(), nullptr, 0));
+ client->NotifyFetchFinished(base::nullopt, error_messages);
+ return;
+ }
+
ModuleScriptCreationParams params(
- fetch_params.Url(),
- ModuleScriptCreationParams::ModuleType::kJavaScriptModule,
+ fetch_params.Url(), module_type,
ParkableString(script_data->TakeSourceText().Impl()),
nullptr /* cache_handler */,
fetch_params.GetResourceRequest().GetCredentialsMode());
client->NotifyFetchFinished(params, HeapVector<Member<ConsoleMessage>>());
}
-void InstalledServiceWorkerModuleScriptFetcher::Trace(blink::Visitor* visitor) {
+void InstalledServiceWorkerModuleScriptFetcher::Trace(Visitor* visitor) {
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 b03fe39bc5c..e68a730dfec 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
@@ -20,16 +20,16 @@ class CORE_EXPORT InstalledServiceWorkerModuleScriptFetcher final
USING_GARBAGE_COLLECTED_MIXIN(InstalledServiceWorkerModuleScriptFetcher);
public:
- explicit InstalledServiceWorkerModuleScriptFetcher(WorkerGlobalScope*);
+ InstalledServiceWorkerModuleScriptFetcher(WorkerGlobalScope*,
+ util::PassKey<ModuleScriptLoader>);
// Implements ModuleScriptFetcher.
void Fetch(FetchParameters&,
ResourceFetcher*,
- const Modulator* modulator_for_built_in_modules,
ModuleGraphLevel,
ModuleScriptFetcher::Client*) override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
String DebugName() const override {
diff --git a/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_creation_params.h b/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_creation_params.h
index 6acd69c5177..5f16296c974 100644
--- a/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_creation_params.h
+++ b/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_creation_params.h
@@ -20,7 +20,7 @@ namespace blink {
class ModuleScriptCreationParams {
DISALLOW_NEW();
- enum class ModuleType { kJavaScriptModule, kJSONModule };
+ enum class ModuleType { kJavaScriptModule, kJSONModule, kCSSModule };
public:
ModuleScriptCreationParams(
diff --git a/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h b/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h
index 57272881322..e746bc0c749 100644
--- a/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h
+++ b/chromium/third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h
@@ -22,11 +22,13 @@ class ModuleScriptFetchRequest final {
// Referrer is set only for internal module script fetch algorithms triggered
// from ModuleTreeLinker to fetch descendant module scripts.
ModuleScriptFetchRequest(const KURL& url,
- mojom::RequestContextType destination,
+ mojom::RequestContextType context_type,
+ network::mojom::RequestDestination destination,
const ScriptFetchOptions& options,
const String& referrer_string,
const TextPosition& referrer_position)
: url_(url),
+ context_type_(context_type),
destination_(destination),
options_(options),
referrer_string_(referrer_string),
@@ -34,20 +36,25 @@ class ModuleScriptFetchRequest final {
static ModuleScriptFetchRequest CreateForTest(const KURL& url) {
return ModuleScriptFetchRequest(
- url, mojom::RequestContextType::SCRIPT, ScriptFetchOptions(),
+ url, mojom::RequestContextType::SCRIPT,
+ network::mojom::RequestDestination::kScript, ScriptFetchOptions(),
Referrer::ClientReferrerString(), TextPosition::MinimumPosition());
}
~ModuleScriptFetchRequest() = default;
const KURL& Url() const { return url_; }
- mojom::RequestContextType Destination() const { return destination_; }
+ mojom::RequestContextType ContextType() const { return context_type_; }
+ network::mojom::RequestDestination Destination() const {
+ return destination_;
+ }
const ScriptFetchOptions& Options() const { return options_; }
const String& ReferrerString() const { return referrer_string_; }
const TextPosition& GetReferrerPosition() const { return referrer_position_; }
private:
const KURL url_;
- const mojom::RequestContextType destination_;
+ const mojom::RequestContextType context_type_;
+ const network::mojom::RequestDestination destination_;
const ScriptFetchOptions options_;
const String referrer_string_;
const TextPosition referrer_position_;
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 3d50b539c3c..af7f699107c 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
@@ -4,9 +4,11 @@
#include "third_party/blink/renderer/core/loader/modulescript/module_script_fetcher.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/core/dom/dom_implementation.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/loader/subresource_integrity_helper.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/loader/cors/cors.h"
#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -14,6 +16,9 @@
namespace blink {
+ModuleScriptFetcher::ModuleScriptFetcher(
+ util::PassKey<ModuleScriptLoader> pass_key) {}
+
void ModuleScriptFetcher::Client::OnFetched(
const base::Optional<ModuleScriptCreationParams>& params) {
NotifyFetchFinished(params, HeapVector<Member<ConsoleMessage>>());
@@ -23,6 +28,10 @@ void ModuleScriptFetcher::Client::OnFailed() {
NotifyFetchFinished(base::nullopt, HeapVector<Member<ConsoleMessage>>());
}
+void ModuleScriptFetcher::Trace(Visitor* visitor) {
+ ResourceClient::Trace(visitor);
+}
+
// <specdef href="https://html.spec.whatwg.org/C/#fetch-a-single-module-script">
bool ModuleScriptFetcher::WasModuleLoadSuccessful(
Resource* resource,
@@ -64,21 +73,33 @@ bool ModuleScriptFetcher::WasModuleLoadSuccessful(
return true;
}
// <spec step="13">If type is a JSON MIME type, then:</spec>
- if (RuntimeEnabledFeatures::JSONModulesEnabled() &&
+ if (base::FeatureList::IsEnabled(blink::features::kJSONModules) &&
MIMETypeRegistry::IsJSONMimeType(response.HttpContentType())) {
*module_type = ModuleScriptCreationParams::ModuleType::kJSONModule;
return true;
}
- String required_response_type = RuntimeEnabledFeatures::JSONModulesEnabled()
- ? "JavaScript or JSON"
- : "JavaScript";
+
+ if (RuntimeEnabledFeatures::CSSModulesEnabled() &&
+ MIMETypeRegistry::IsSupportedStyleSheetMIMEType(
+ response.HttpContentType())) {
+ *module_type = ModuleScriptCreationParams::ModuleType::kCSSModule;
+ return true;
+ }
+ String required_response_type = "JavaScript";
+ if (base::FeatureList::IsEnabled(blink::features::kJSONModules)) {
+ required_response_type = required_response_type + ", JSON";
+ }
+ if (RuntimeEnabledFeatures::CSSModulesEnabled()) {
+ required_response_type = required_response_type + ", CSS";
+ }
+
String message =
"Failed to load module script: The server responded with a non-" +
required_response_type + " MIME type of \"" +
resource->GetResponse().HttpContentType() +
"\". Strict MIME type checking is enforced for module scripts per HTML "
"spec.";
- error_messages->push_back(ConsoleMessage::CreateForRequest(
+ error_messages->push_back(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kError, message,
response.CurrentRequestUrl().GetString(), /*loader=*/nullptr,
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 c5081a0153a..9b034af0c37 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
@@ -12,17 +12,21 @@
#include "third_party/blink/renderer/core/script/modulator.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.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 {
class ConsoleMessage;
-class ResourceFetcher;
+class ModuleScriptLoader;
// ModuleScriptFetcher is an abstract class to fetch module scripts. Derived
// classes are expected to fetch a module script for the given FetchParameters
// and return its client a fetched resource as ModuleScriptCreationParams.
class CORE_EXPORT ModuleScriptFetcher : public ResourceClient {
public:
+ // ModuleScriptFetcher should only be called from ModuleScriptLoader.
+ explicit ModuleScriptFetcher(util::PassKey<ModuleScriptLoader>);
+
class CORE_EXPORT Client : public GarbageCollectedMixin {
public:
virtual void NotifyFetchFinished(
@@ -35,20 +39,18 @@ class CORE_EXPORT ModuleScriptFetcher : public ResourceClient {
void OnFailed();
};
+ // Fetch() must be called right after ModuleScriptFetcher is constructed.
+ // Fetch() must not be called more than once.
+ //
// Takes a non-const reference to FetchParameters because
// ScriptResource::Fetch() requires it.
- //
- // Do not use |modulator_for_built_in_modules| other than for built-in
- // modules. Fetching should depend sorely on the ResourceFetcher that
- // represents fetch client settings object. https://crbug.com/928435
- // |modulator_for_built_in_modules| can be nullptr in unit tests, and
- // in such cases built-in modules are not loaded at all.
virtual void Fetch(FetchParameters&,
ResourceFetcher*,
- const Modulator* modulator_for_built_in_modules,
ModuleGraphLevel,
Client*) = 0;
+ void Trace(Visitor*) override;
+
protected:
static bool WasModuleLoadSuccessful(
Resource* resource,
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 8f2dfc16cbd..0296fc6c786 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
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/loader/modulescript/module_script_loader.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/core/dom/dom_implementation.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
@@ -116,7 +117,8 @@ void ModuleScriptLoader::FetchInternal(
#endif
// <spec step="5">... destination is destination, ...</spec>
- resource_request.SetRequestContext(module_request.Destination());
+ resource_request.SetRequestContext(module_request.ContextType());
+ resource_request.SetRequestDestination(module_request.Destination());
ResourceLoaderOptions options;
@@ -141,6 +143,9 @@ void ModuleScriptLoader::FetchInternal(
// https://fetch.spec.whatwg.org/#concept-request-initiator
options.initiator_info.name = g_empty_atom;
+ // TODO(crbug.com/1064920): Remove this once PlzDedicatedWorker ships.
+ options.reject_coep_unsafe_none = options_.GetRejectCoepUnsafeNone();
+
if (level == ModuleGraphLevel::kDependentModuleFetch) {
options.initiator_info.imported_module_referrer =
module_request.ReferrerString();
@@ -148,7 +153,7 @@ void ModuleScriptLoader::FetchInternal(
}
// Note: |options| should not be modified after here.
- FetchParameters fetch_params(resource_request, options);
+ FetchParameters fetch_params(std::move(resource_request), options);
// <spec label="SMSR">... its integrity metadata to options's integrity
// metadata, ...</spec>
@@ -211,9 +216,10 @@ void ModuleScriptLoader::FetchInternal(
// steps. Otherwise, fetch request. Return from this algorithm, and run the
// remaining steps as part of the fetch's process response for the response
// response.</spec>
- module_fetcher_ = modulator_->CreateModuleScriptFetcher(custom_fetch_type);
+ module_fetcher_ =
+ modulator_->CreateModuleScriptFetcher(custom_fetch_type, PassKey());
module_fetcher_->Fetch(fetch_params, fetch_client_settings_object_fetcher,
- modulator_, level, this);
+ level, this);
}
// <specdef href="https://html.spec.whatwg.org/C/#fetch-a-single-module-script">
@@ -248,10 +254,15 @@ void ModuleScriptLoader::NotifyFetchFinished(
// url, and options.</spec>
switch (params->GetModuleType()) {
case ModuleScriptCreationParams::ModuleType::kJSONModule:
- DCHECK(RuntimeEnabledFeatures::JSONModulesEnabled());
+ DCHECK(base::FeatureList::IsEnabled(blink::features::kJSONModules));
module_script_ = ValueWrapperSyntheticModuleScript::
CreateJSONWrapperSyntheticModuleScript(params, modulator_);
break;
+ case ModuleScriptCreationParams::ModuleType::kCSSModule:
+ DCHECK(RuntimeEnabledFeatures::CSSModulesEnabled());
+ module_script_ = ValueWrapperSyntheticModuleScript::
+ CreateCSSWrapperSyntheticModuleScript(params, modulator_);
+ break;
case ModuleScriptCreationParams::ModuleType::kJavaScriptModule:
// Step 9. "Let source text be the result of UTF-8 decoding response's
// body." [spec text]
@@ -268,7 +279,7 @@ void ModuleScriptLoader::NotifyFetchFinished(
AdvanceState(State::kFinished);
}
-void ModuleScriptLoader::Trace(blink::Visitor* visitor) {
+void ModuleScriptLoader::Trace(Visitor* visitor) {
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 7541555d508..1874e4cfb89 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,9 @@ class CORE_EXPORT ModuleScriptLoader final
bool IsInitialState() const { return state_ == State::kInitial; }
bool HasFinished() const { return state_ == State::kFinished; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
+
+ friend class WorkletModuleResponsesMapTest;
private:
void FetchInternal(const ModuleScriptFetchRequest&,
@@ -76,6 +78,14 @@ class CORE_EXPORT ModuleScriptLoader final
ModuleScriptCustomFetchType);
void AdvanceState(State new_state);
+
+ using PassKey = util::PassKey<ModuleScriptLoader>;
+ // PassKey should be private and cannot be accessed from outside, but allow
+ // accessing only from friend classes for testing.
+ static util::PassKey<ModuleScriptLoader> CreatePassKeyForTests() {
+ return PassKey();
+ }
+
#if DCHECK_IS_ON()
static const char* StateToString(State);
#endif
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 d52e6549707..9f250d20293 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(blink::Visitor* visitor) {
+void ModuleScriptLoaderRegistry::Trace(Visitor* visitor) {
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 bd037ef9200..af8cb737342 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(blink::Visitor*);
+ void Trace(Visitor*);
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 3800534be20..42631bf83d8 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
@@ -4,8 +4,10 @@
#include "third_party/blink/renderer/core/loader/modulescript/module_script_loader.h"
+#include "base/test/scoped_feature_list.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/platform.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
@@ -51,9 +53,7 @@ class TestModuleScriptLoaderClient final
TestModuleScriptLoaderClient() = default;
~TestModuleScriptLoaderClient() override = default;
- void Trace(blink::Visitor* visitor) override {
- visitor->Trace(module_script_);
- }
+ void Trace(Visitor* visitor) override { visitor->Trace(module_script_); }
void NotifyNewSingleModuleFinished(ModuleScript* module_script) override {
was_notify_finished_ = true;
@@ -95,34 +95,34 @@ class ModuleScriptLoaderTestModulator final : public DummyModulator {
}
ModuleScriptFetcher* CreateModuleScriptFetcher(
- ModuleScriptCustomFetchType custom_fetch_type) override {
+ ModuleScriptCustomFetchType custom_fetch_type,
+ util::PassKey<ModuleScriptLoader> pass_key) override {
auto* execution_context = ExecutionContext::From(script_state_);
if (auto* scope = DynamicTo<WorkletGlobalScope>(execution_context)) {
EXPECT_EQ(ModuleScriptCustomFetchType::kWorkletAddModule,
custom_fetch_type);
return MakeGarbageCollected<WorkletModuleScriptFetcher>(
- scope->GetModuleResponsesMap());
+ scope->GetModuleResponsesMap(), pass_key);
}
EXPECT_EQ(ModuleScriptCustomFetchType::kNone, custom_fetch_type);
- return MakeGarbageCollected<DocumentModuleScriptFetcher>();
+ return MakeGarbageCollected<DocumentModuleScriptFetcher>(pass_key);
}
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<ScriptState> script_state_;
Vector<ModuleRequest> requests_;
};
-void ModuleScriptLoaderTestModulator::Trace(blink::Visitor* visitor) {
+void ModuleScriptLoaderTestModulator::Trace(Visitor* visitor) {
visitor->Trace(script_state_);
DummyModulator::Trace(visitor);
}
} // namespace
-class ModuleScriptLoaderTest : public PageTestBase,
- private ScopedJSONModulesForTest {
+class ModuleScriptLoaderTest : public PageTestBase {
DISALLOW_COPY_AND_ASSIGN(ModuleScriptLoaderTest);
public:
@@ -156,6 +156,7 @@ class ModuleScriptLoaderTest : public PageTestBase,
const base::TickClock* GetTickClock() override {
return platform_->test_task_runner()->GetMockTickClock();
}
+ base::test::ScopedFeatureList scoped_feature_list_;
protected:
const KURL url_;
@@ -174,9 +175,9 @@ void ModuleScriptLoaderTest::SetUp() {
}
ModuleScriptLoaderTest::ModuleScriptLoaderTest()
- : ScopedJSONModulesForTest(true),
- url_("https://example.test"),
+ : url_("https://example.test"),
security_origin_(SecurityOrigin::Create(url_)) {
+ scoped_feature_list_.InitAndEnableFeature(blink::features::kJSONModules);
platform_->AdvanceClockSeconds(1.); // For non-zero DocumentParserTimings
}
@@ -202,9 +203,8 @@ void ModuleScriptLoaderTest::InitializeForWorklet() {
MakeGarbageCollected<TestLoaderFactory>()));
reporting_proxy_ = std::make_unique<MockWorkerReportingProxy>();
auto creation_params = std::make_unique<GlobalScopeCreationParams>(
- url_, mojom::ScriptType::kModule,
- OffMainThreadWorkerScriptFetchOption::kEnabled, "GlobalScopeName",
- "UserAgent", nullptr /* web_worker_fetch_context */,
+ url_, mojom::blink::ScriptType::kModule, "GlobalScopeName", "UserAgent",
+ UserAgentMetadata(), nullptr /* web_worker_fetch_context */,
Vector<CSPHeaderAndType>(), network::mojom::ReferrerPolicy::kDefault,
security_origin_.get(), true /* is_secure_context */, HttpsState::kModern,
nullptr /* worker_clients */, nullptr /* content_settings_client */,
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 e2c000bcd97..5e710b04a5b 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
@@ -7,7 +7,6 @@
#include "third_party/blink/renderer/bindings/core/v8/module_record.h"
#include "third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h"
#include "third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.h"
-#include "third_party/blink/renderer/core/script/layered_api.h"
#include "third_party/blink/renderer/core/script/module_script.h"
#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
@@ -34,15 +33,16 @@ namespace blink {
void ModuleTreeLinker::Fetch(
const KURL& url,
ResourceFetcher* fetch_client_settings_object_fetcher,
- mojom::RequestContextType destination,
+ mojom::RequestContextType context_type,
+ network::mojom::RequestDestination destination,
const ScriptFetchOptions& options,
Modulator* modulator,
ModuleScriptCustomFetchType custom_fetch_type,
ModuleTreeLinkerRegistry* registry,
ModuleTreeClient* client) {
ModuleTreeLinker* fetcher = MakeGarbageCollected<ModuleTreeLinker>(
- fetch_client_settings_object_fetcher, destination, modulator,
- custom_fetch_type, registry, client);
+ fetch_client_settings_object_fetcher, context_type, destination,
+ modulator, custom_fetch_type, registry, client);
registry->AddFetcher(fetcher);
fetcher->FetchRoot(url, options);
DCHECK(fetcher->IsFetching());
@@ -51,15 +51,16 @@ void ModuleTreeLinker::Fetch(
void ModuleTreeLinker::FetchDescendantsForInlineScript(
ModuleScript* module_script,
ResourceFetcher* fetch_client_settings_object_fetcher,
- mojom::RequestContextType destination,
+ mojom::RequestContextType context_type,
+ network::mojom::RequestDestination destination,
Modulator* modulator,
ModuleScriptCustomFetchType custom_fetch_type,
ModuleTreeLinkerRegistry* registry,
ModuleTreeClient* client) {
DCHECK(module_script);
ModuleTreeLinker* fetcher = MakeGarbageCollected<ModuleTreeLinker>(
- fetch_client_settings_object_fetcher, destination, modulator,
- custom_fetch_type, registry, client);
+ fetch_client_settings_object_fetcher, context_type, destination,
+ modulator, custom_fetch_type, registry, client);
registry->AddFetcher(fetcher);
fetcher->FetchRootInline(module_script);
DCHECK(fetcher->IsFetching());
@@ -67,13 +68,15 @@ void ModuleTreeLinker::FetchDescendantsForInlineScript(
ModuleTreeLinker::ModuleTreeLinker(
ResourceFetcher* fetch_client_settings_object_fetcher,
- mojom::RequestContextType destination,
+ mojom::RequestContextType context_type,
+ network::mojom::RequestDestination destination,
Modulator* modulator,
ModuleScriptCustomFetchType custom_fetch_type,
ModuleTreeLinkerRegistry* registry,
ModuleTreeClient* client)
: fetch_client_settings_object_fetcher_(
fetch_client_settings_object_fetcher),
+ context_type_(context_type),
destination_(destination),
modulator_(modulator),
custom_fetch_type_(custom_fetch_type),
@@ -84,7 +87,7 @@ ModuleTreeLinker::ModuleTreeLinker(
CHECK(client);
}
-void ModuleTreeLinker::Trace(blink::Visitor* visitor) {
+void ModuleTreeLinker::Trace(Visitor* visitor) {
visitor->Trace(fetch_client_settings_object_fetcher_);
visitor->Trace(modulator_);
visitor->Trace(registry_);
@@ -177,12 +180,6 @@ void ModuleTreeLinker::FetchRoot(const KURL& original_url,
AdvanceState(State::kFetchingSelf);
KURL url = original_url;
- // <spec
- // href="https://github.com/drufball/layered-apis/blob/master/spec.md#fetch-a-module-script-graph"
- // step="1">Set url to the layered API fetching URL given url and the current
- // settings object's API base URL.</spec>
- if (modulator_->BuiltInModuleInfraEnabled())
- url = blink::layered_api::ResolveFetchingURL(*modulator_, url);
#if DCHECK_IS_ON()
url_ = url;
@@ -229,7 +226,7 @@ void ModuleTreeLinker::FetchRoot(const KURL& original_url,
// module script given url, fetch client settings object, destination,
// options, module map settings object, "client", and with the top-level
// module fetch flag set. ...</spec>
- ModuleScriptFetchRequest request(url, destination_, options,
+ ModuleScriptFetchRequest request(url, context_type_, destination_, options,
Referrer::ClientReferrerString(),
TextPosition::MinimumPosition());
++num_incomplete_fetches_;
@@ -448,9 +445,9 @@ void ModuleTreeLinker::FetchDescendants(const ModuleScript* module_script) {
// procedure given url, fetch client settings object, destination, options,
// module script's settings object, visited set, and module script's base
// URL. ...</spec>
- ModuleScriptFetchRequest request(urls[i], destination_, options,
- module_script->BaseURL().GetString(),
- positions[i]);
+ ModuleScriptFetchRequest request(
+ urls[i], context_type_, destination_, options,
+ module_script->BaseURL().GetString(), positions[i]);
// <spec label="IMSGF" step="1">Assert: visited set contains url.</spec>
DCHECK(visited_set_.Contains(request.Url()));
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 aaa95665fa5..c4a664b1987 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
@@ -33,7 +33,8 @@ class CORE_EXPORT ModuleTreeLinker final : public SingleModuleClient {
// https://html.spec.whatwg.org/C/#fetch-an-import()-module-script-graph
static void Fetch(const KURL&,
ResourceFetcher* fetch_client_settings_object_fetcher,
- mojom::RequestContextType destination,
+ mojom::RequestContextType context_type,
+ network::mojom::RequestDestination destination,
const ScriptFetchOptions&,
Modulator*,
ModuleScriptCustomFetchType,
@@ -44,20 +45,22 @@ class CORE_EXPORT ModuleTreeLinker final : public SingleModuleClient {
static void FetchDescendantsForInlineScript(
ModuleScript*,
ResourceFetcher* fetch_client_settings_object_fetcher,
- mojom::RequestContextType destination,
+ mojom::RequestContextType context_type,
+ network::mojom::RequestDestination destination,
Modulator*,
ModuleScriptCustomFetchType,
ModuleTreeLinkerRegistry*,
ModuleTreeClient*);
ModuleTreeLinker(ResourceFetcher* fetch_client_settings_object_fetcher,
- mojom::RequestContextType destination,
+ mojom::RequestContextType context_type,
+ network::mojom::RequestDestination destination,
Modulator*,
ModuleScriptCustomFetchType,
ModuleTreeLinkerRegistry*,
ModuleTreeClient*);
~ModuleTreeLinker() override = default;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
bool IsFetching() const {
return State::kFetchingSelf <= state_ && state_ < State::kFinished;
@@ -99,7 +102,8 @@ class CORE_EXPORT ModuleTreeLinker final : public SingleModuleClient {
const Member<ResourceFetcher> fetch_client_settings_object_fetcher_;
- const mojom::RequestContextType destination_;
+ const mojom::RequestContextType context_type_;
+ const network::mojom::RequestDestination destination_;
const Member<Modulator> modulator_;
const ModuleScriptCustomFetchType custom_fetch_type_;
HashSet<KURL> visited_set_;
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 b4f7075f199..152aace03c0 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(blink::Visitor* visitor) {
+void ModuleTreeLinkerRegistry::Trace(Visitor* visitor) {
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 ab2c73a1e24..9bfb1121d9e 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(blink::Visitor*);
+ void Trace(Visitor*);
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 bc618489efd..ce6ccc0ef19 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
enum class ResolveResult { kFailure, kSuccess };
@@ -182,7 +182,7 @@ class ModuleTreeLinkerTestModulator final : public DummyModulator {
bool instantiate_should_fail_ = false;
};
-void ModuleTreeLinkerTestModulator::Trace(blink::Visitor* visitor) {
+void ModuleTreeLinkerTestModulator::Trace(Visitor* visitor) {
visitor->Trace(script_state_);
visitor->Trace(pending_clients_);
visitor->Trace(module_map_);
@@ -215,10 +215,10 @@ TEST_F(ModuleTreeLinkerTest, FetchTreeNoDeps) {
KURL url("http://example.com/root.js");
TestModuleTreeClient* client = MakeGarbageCollected<TestModuleTreeClient>();
- ModuleTreeLinker::Fetch(url, GetDocument().Fetcher(),
- mojom::RequestContextType::SCRIPT,
- ScriptFetchOptions(), GetModulator(),
- ModuleScriptCustomFetchType::kNone, registry, client);
+ ModuleTreeLinker::Fetch(
+ url, GetDocument().Fetcher(), mojom::RequestContextType::SCRIPT,
+ network::mojom::RequestDestination::kScript, ScriptFetchOptions(),
+ GetModulator(), ModuleScriptCustomFetchType::kNone, registry, client);
EXPECT_FALSE(client->WasNotifyFinished())
<< "ModuleTreeLinker should always finish asynchronously.";
@@ -238,10 +238,10 @@ TEST_F(ModuleTreeLinkerTest, FetchTreeInstantiationFailure) {
KURL url("http://example.com/root.js");
TestModuleTreeClient* client = MakeGarbageCollected<TestModuleTreeClient>();
- ModuleTreeLinker::Fetch(url, GetDocument().Fetcher(),
- mojom::RequestContextType::SCRIPT,
- ScriptFetchOptions(), GetModulator(),
- ModuleScriptCustomFetchType::kNone, registry, client);
+ ModuleTreeLinker::Fetch(
+ url, GetDocument().Fetcher(), mojom::RequestContextType::SCRIPT,
+ network::mojom::RequestDestination::kScript, ScriptFetchOptions(),
+ GetModulator(), ModuleScriptCustomFetchType::kNone, registry, client);
EXPECT_FALSE(client->WasNotifyFinished())
<< "ModuleTreeLinker should always finish asynchronously.";
@@ -265,10 +265,10 @@ TEST_F(ModuleTreeLinkerTest, FetchTreeWithSingleDependency) {
KURL url("http://example.com/root.js");
TestModuleTreeClient* client = MakeGarbageCollected<TestModuleTreeClient>();
- ModuleTreeLinker::Fetch(url, GetDocument().Fetcher(),
- mojom::RequestContextType::SCRIPT,
- ScriptFetchOptions(), GetModulator(),
- ModuleScriptCustomFetchType::kNone, registry, client);
+ ModuleTreeLinker::Fetch(
+ url, GetDocument().Fetcher(), mojom::RequestContextType::SCRIPT,
+ network::mojom::RequestDestination::kScript, ScriptFetchOptions(),
+ GetModulator(), ModuleScriptCustomFetchType::kNone, registry, client);
EXPECT_FALSE(client->WasNotifyFinished())
<< "ModuleTreeLinker should always finish asynchronously.";
@@ -293,10 +293,10 @@ TEST_F(ModuleTreeLinkerTest, FetchTreeWith3Deps) {
KURL url("http://example.com/root.js");
TestModuleTreeClient* client = MakeGarbageCollected<TestModuleTreeClient>();
- ModuleTreeLinker::Fetch(url, GetDocument().Fetcher(),
- mojom::RequestContextType::SCRIPT,
- ScriptFetchOptions(), GetModulator(),
- ModuleScriptCustomFetchType::kNone, registry, client);
+ ModuleTreeLinker::Fetch(
+ url, GetDocument().Fetcher(), mojom::RequestContextType::SCRIPT,
+ network::mojom::RequestDestination::kScript, ScriptFetchOptions(),
+ GetModulator(), ModuleScriptCustomFetchType::kNone, registry, client);
EXPECT_FALSE(client->WasNotifyFinished())
<< "ModuleTreeLinker should always finish asynchronously.";
@@ -334,10 +334,10 @@ TEST_F(ModuleTreeLinkerTest, FetchTreeWith3Deps1Fail) {
KURL url("http://example.com/root.js");
TestModuleTreeClient* client = MakeGarbageCollected<TestModuleTreeClient>();
- ModuleTreeLinker::Fetch(url, GetDocument().Fetcher(),
- mojom::RequestContextType::SCRIPT,
- ScriptFetchOptions(), GetModulator(),
- ModuleScriptCustomFetchType::kNone, registry, client);
+ ModuleTreeLinker::Fetch(
+ url, GetDocument().Fetcher(), mojom::RequestContextType::SCRIPT,
+ network::mojom::RequestDestination::kScript, ScriptFetchOptions(),
+ GetModulator(), ModuleScriptCustomFetchType::kNone, registry, client);
EXPECT_FALSE(client->WasNotifyFinished())
<< "ModuleTreeLinker should always finish asynchronously.";
@@ -394,10 +394,10 @@ TEST_F(ModuleTreeLinkerTest, FetchDependencyTree) {
KURL url("http://example.com/depth1.js");
TestModuleTreeClient* client = MakeGarbageCollected<TestModuleTreeClient>();
- ModuleTreeLinker::Fetch(url, GetDocument().Fetcher(),
- mojom::RequestContextType::SCRIPT,
- ScriptFetchOptions(), GetModulator(),
- ModuleScriptCustomFetchType::kNone, registry, client);
+ ModuleTreeLinker::Fetch(
+ url, GetDocument().Fetcher(), mojom::RequestContextType::SCRIPT,
+ network::mojom::RequestDestination::kScript, ScriptFetchOptions(),
+ GetModulator(), ModuleScriptCustomFetchType::kNone, registry, client);
EXPECT_FALSE(client->WasNotifyFinished())
<< "ModuleTreeLinker should always finish asynchronously.";
@@ -421,10 +421,10 @@ TEST_F(ModuleTreeLinkerTest, FetchDependencyOfCyclicGraph) {
KURL url("http://example.com/a.js");
TestModuleTreeClient* client = MakeGarbageCollected<TestModuleTreeClient>();
- ModuleTreeLinker::Fetch(url, GetDocument().Fetcher(),
- mojom::RequestContextType::SCRIPT,
- ScriptFetchOptions(), GetModulator(),
- ModuleScriptCustomFetchType::kNone, registry, client);
+ ModuleTreeLinker::Fetch(
+ url, GetDocument().Fetcher(), mojom::RequestContextType::SCRIPT,
+ network::mojom::RequestDestination::kScript, ScriptFetchOptions(),
+ GetModulator(), ModuleScriptCustomFetchType::kNone, registry, client);
EXPECT_FALSE(client->WasNotifyFinished())
<< "ModuleTreeLinker should always finish asynchronously.";
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 8aeea99a2c8..2b00996a03a 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
@@ -9,7 +9,10 @@
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object.h"
#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/network/content_security_policy_response_headers.h"
#include "third_party/blink/renderer/platform/network/http_names.h"
#include "third_party/blink/renderer/platform/network/network_utils.h"
@@ -18,17 +21,19 @@
namespace blink {
WorkerModuleScriptFetcher::WorkerModuleScriptFetcher(
- WorkerGlobalScope* global_scope)
- : global_scope_(global_scope) {}
+ WorkerGlobalScope* global_scope,
+ util::PassKey<ModuleScriptLoader> pass_key)
+ : ModuleScriptFetcher(pass_key), global_scope_(global_scope) {}
// <specdef href="https://html.spec.whatwg.org/C/#run-a-worker">
void WorkerModuleScriptFetcher::Fetch(
FetchParameters& fetch_params,
ResourceFetcher* fetch_client_settings_object_fetcher,
- const Modulator* modulator_for_built_in_modules,
ModuleGraphLevel level,
ModuleScriptFetcher::Client* client) {
DCHECK(global_scope_->IsContextThread());
+ DCHECK(!fetch_client_settings_object_fetcher_);
+ fetch_client_settings_object_fetcher_ = fetch_client_settings_object_fetcher;
client_ = client;
level_ = level;
@@ -46,10 +51,11 @@ void WorkerModuleScriptFetcher::Fetch(
this, ScriptResource::kNoStreaming);
}
-void WorkerModuleScriptFetcher::Trace(blink::Visitor* visitor) {
+void WorkerModuleScriptFetcher::Trace(Visitor* visitor) {
ModuleScriptFetcher::Trace(visitor);
visitor->Trace(client_);
visitor->Trace(global_scope_);
+ visitor->Trace(fetch_client_settings_object_fetcher_);
}
// https://html.spec.whatwg.org/C/#worker-processing-model
@@ -70,17 +76,35 @@ void WorkerModuleScriptFetcher::NotifyFinished(Resource* resource) {
// TODO(nhiroki, hiroshige): Access to WorkerGlobalScope in module loaders
// is a layering violation. Also, updating WorkerGlobalScope ('module map
// settigns object') in flight can be dangerous because module loaders may
- // refers to it. We should move these steps out of core/loader/modulescript/
+ // refer to it. We should move these steps out of core/loader/modulescript/
// and run them after module loading. This may require the spec change.
// (https://crbug.com/845285)
// Ensure redirects don't affect SecurityOrigin.
const KURL request_url = resource->Url();
const KURL response_url = resource->GetResponse().CurrentRequestUrl();
- if (request_url != response_url &&
- !global_scope_->GetSecurityOrigin()->IsSameOriginWith(
- SecurityOrigin::Create(response_url).get())) {
- error_messages.push_back(ConsoleMessage::Create(
+ DCHECK(fetch_client_settings_object_fetcher_->GetProperties()
+ .GetFetchClientSettingsObject()
+ .GetSecurityOrigin()
+ ->CanReadContent(request_url))
+ << "Top-level worker script request url must be same-origin with "
+ "outside settings constructor origin or permitted by the parent "
+ "chrome-extension.";
+
+ // |response_url| must be same-origin with request origin or its url's
+ // scheme must be "data".
+ //
+ // https://fetch.spec.whatwg.org/#concept-main-fetch
+ // Step 5:
+ // - request’s current URL’s origin is same origin with request’s
+ // origin (request's current URL indicates |response_url|)
+ // - request’s current URL’s scheme is "data"
+ // ---> Return the result of performing a scheme fetch using request.
+ // - request’s mode is "same-origin"
+ // ---> Return a network error. [spec text]
+ if (!SecurityOrigin::AreSameOrigin(request_url, response_url) &&
+ !response_url.ProtocolIsData()) {
+ error_messages.push_back(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kSecurity,
mojom::ConsoleMessageLevel::kError,
"Refused to cross-origin redirects of the top-level worker script."));
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 36710fdbcf3..9453005523a 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
@@ -22,16 +22,16 @@ class CORE_EXPORT WorkerModuleScriptFetcher final
USING_GARBAGE_COLLECTED_MIXIN(WorkerModuleScriptFetcher);
public:
- explicit WorkerModuleScriptFetcher(WorkerGlobalScope*);
+ WorkerModuleScriptFetcher(WorkerGlobalScope*,
+ util::PassKey<ModuleScriptLoader>);
// Implements ModuleScriptFetcher.
void Fetch(FetchParameters&,
ResourceFetcher*,
- const Modulator* modulator_for_built_in_modules,
ModuleGraphLevel,
ModuleScriptFetcher::Client*) override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
// Implements ResourceClient
@@ -40,6 +40,7 @@ class CORE_EXPORT WorkerModuleScriptFetcher final
const Member<WorkerGlobalScope> global_scope_;
+ Member<ResourceFetcher> fetch_client_settings_object_fetcher_;
Member<Client> client_;
ModuleGraphLevel level_;
};
diff --git a/chromium/third_party/blink/renderer/core/loader/modulescript/worklet_module_script_fetcher.cc b/chromium/third_party/blink/renderer/core/loader/modulescript/worklet_module_script_fetcher.cc
index 942c9a07569..43bb0c89006 100644
--- a/chromium/third_party/blink/renderer/core/loader/modulescript/worklet_module_script_fetcher.cc
+++ b/chromium/third_party/blink/renderer/core/loader/modulescript/worklet_module_script_fetcher.cc
@@ -9,13 +9,14 @@
namespace blink {
WorkletModuleScriptFetcher::WorkletModuleScriptFetcher(
- WorkletModuleResponsesMap* module_responses_map)
- : module_responses_map_(module_responses_map) {}
+ WorkletModuleResponsesMap* module_responses_map,
+ util::PassKey<ModuleScriptLoader> pass_key)
+ : ModuleScriptFetcher(pass_key),
+ module_responses_map_(module_responses_map) {}
void WorkletModuleScriptFetcher::Fetch(
FetchParameters& fetch_params,
ResourceFetcher* fetch_client_settings_object_fetcher,
- const Modulator* modulator_for_built_in_modules,
ModuleGraphLevel level,
ModuleScriptFetcher::Client* client) {
if (module_responses_map_->GetEntry(
diff --git a/chromium/third_party/blink/renderer/core/loader/modulescript/worklet_module_script_fetcher.h b/chromium/third_party/blink/renderer/core/loader/modulescript/worklet_module_script_fetcher.h
index 4bc3312d663..2a5901a95f1 100644
--- a/chromium/third_party/blink/renderer/core/loader/modulescript/worklet_module_script_fetcher.h
+++ b/chromium/third_party/blink/renderer/core/loader/modulescript/worklet_module_script_fetcher.h
@@ -28,12 +28,12 @@ class CORE_EXPORT WorkletModuleScriptFetcher final
USING_GARBAGE_COLLECTED_MIXIN(WorkletModuleScriptFetcher);
public:
- explicit WorkletModuleScriptFetcher(WorkletModuleResponsesMap*);
+ WorkletModuleScriptFetcher(WorkletModuleResponsesMap*,
+ util::PassKey<ModuleScriptLoader>);
// Implements ModuleScriptFetcher.
void Fetch(FetchParameters&,
ResourceFetcher*,
- const Modulator* modulator_for_built_in_modules,
ModuleGraphLevel,
ModuleScriptFetcher::Client*) override;
diff --git a/chromium/third_party/blink/renderer/core/loader/navigation_policy.cc b/chromium/third_party/blink/renderer/core/loader/navigation_policy.cc
index 490eb5bc599..7184c533596 100644
--- a/chromium/third_party/blink/renderer/core/loader/navigation_policy.cc
+++ b/chromium/third_party/blink/renderer/core/loader/navigation_policy.cc
@@ -31,8 +31,8 @@
#include "third_party/blink/renderer/core/loader/navigation_policy.h"
#include "build/build_config.h"
-#include "third_party/blink/public/platform/web_keyboard_event.h"
-#include "third_party/blink/public/platform/web_mouse_event.h"
+#include "third_party/blink/public/common/input/web_keyboard_event.h"
+#include "third_party/blink/public/common/input/web_mouse_event.h"
#include "third_party/blink/public/web/web_navigation_policy.h"
#include "third_party/blink/public/web/web_window_features.h"
#include "third_party/blink/renderer/core/events/current_input_event.h"
@@ -74,24 +74,21 @@ NavigationPolicy NavigationPolicyFromEventModifiers(int16_t button,
return kNavigationPolicyCurrentTab;
}
-NavigationPolicy NavigationPolicyFromEventInternal(Event* event) {
+NavigationPolicy NavigationPolicyFromEventInternal(const Event* event) {
if (!event)
return kNavigationPolicyCurrentTab;
- if (event->IsMouseEvent()) {
- MouseEvent* mouse_event = ToMouseEvent(event);
+ if (const auto* mouse_event = DynamicTo<MouseEvent>(event)) {
return NavigationPolicyFromEventModifiers(
mouse_event->button(), mouse_event->ctrlKey(), mouse_event->shiftKey(),
mouse_event->altKey(), mouse_event->metaKey());
- } else if (event->IsKeyboardEvent()) {
+ } else if (const KeyboardEvent* key_event = DynamicTo<KeyboardEvent>(event)) {
// The click is simulated when triggering the keypress event.
- KeyboardEvent* key_event = ToKeyboardEvent(event);
return NavigationPolicyFromEventModifiers(
0, key_event->ctrlKey(), key_event->shiftKey(), key_event->altKey(),
key_event->metaKey());
- } else if (event->IsGestureEvent()) {
+ } else if (const auto* gesture_event = DynamicTo<GestureEvent>(event)) {
// The click is simulated when triggering the gesture-tap event
- GestureEvent* gesture_event = ToGestureEvent(event);
return NavigationPolicyFromEventModifiers(
0, gesture_event->ctrlKey(), gesture_event->shiftKey(),
gesture_event->altKey(), gesture_event->metaKey());
@@ -140,7 +137,7 @@ NavigationPolicy NavigationPolicyFromCurrentEvent() {
} // namespace
-NavigationPolicy NavigationPolicyFromEvent(Event* event) {
+NavigationPolicy NavigationPolicyFromEvent(const Event* event) {
NavigationPolicy event_policy = NavigationPolicyFromEventInternal(event);
NavigationPolicy input_policy = NavigationPolicyFromCurrentEvent();
diff --git a/chromium/third_party/blink/renderer/core/loader/navigation_policy.h b/chromium/third_party/blink/renderer/core/loader/navigation_policy.h
index 402caf760c1..01cc6be73d3 100644
--- a/chromium/third_party/blink/renderer/core/loader/navigation_policy.h
+++ b/chromium/third_party/blink/renderer/core/loader/navigation_policy.h
@@ -51,7 +51,7 @@ enum NavigationPolicy {
// based on the Event. This function takes care of some security checks,
// ensuring that synthesized events cannot trigger arbitrary downloads
// or new tabs without user intention coming from a real input event.
-CORE_EXPORT NavigationPolicy NavigationPolicyFromEvent(Event*);
+CORE_EXPORT NavigationPolicy NavigationPolicyFromEvent(const Event*);
// Returns a NavigationPolicy to use for navigating a new window.
// This function respects user intention coming from a real input event,
diff --git a/chromium/third_party/blink/renderer/core/loader/navigation_policy_test.cc b/chromium/third_party/blink/renderer/core/loader/navigation_policy_test.cc
index d28c630f6d2..44f91a9568c 100644
--- a/chromium/third_party/blink/renderer/core/loader/navigation_policy_test.cc
+++ b/chromium/third_party/blink/renderer/core/loader/navigation_policy_test.cc
@@ -29,12 +29,14 @@
*/
#include "third_party/blink/renderer/core/loader/navigation_policy.h"
+
#include "base/auto_reset.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/web_input_event.h"
-#include "third_party/blink/public/platform/web_mouse_event.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
+#include "third_party/blink/public/common/input/web_mouse_event.h"
#include "third_party/blink/public/web/web_window_features.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mouse_event_init.h"
#include "third_party/blink/renderer/core/events/current_input_event.h"
#include "third_party/blink/renderer/core/events/mouse_event.h"
#include "third_party/blink/renderer/core/page/create_window.h"
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 242fe044140..181b50c9f92 100644
--- a/chromium/third_party/blink/renderer/core/loader/ping_loader.cc
+++ b/chromium/third_party/blink/renderer/core/loader/ping_loader.cc
@@ -31,6 +31,8 @@
#include "third_party/blink/renderer/core/loader/ping_loader.h"
+#include "base/feature_list.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/fileapi/file.h"
@@ -39,6 +41,7 @@
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/html/forms/form_data.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h"
+#include "third_party/blink/renderer/platform/loader/cors/cors.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_context.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_utils.h"
@@ -101,21 +104,27 @@ class BeaconBlob final : public Beacon {
DCHECK(data_);
scoped_refptr<EncodedFormData> entity_body = EncodedFormData::Create();
- if (data_->HasBackingFile())
- entity_body->AppendFile(To<File>(data_.Get())->GetPath());
- else
+ if (data_->HasBackingFile()) {
+ entity_body->AppendFile(To<File>(data_)->GetPath(),
+ To<File>(data_)->LastModifiedTime());
+ } else {
entity_body->AppendBlob(data_->Uuid(), data_->GetBlobDataHandle());
+ }
request.SetHttpBody(std::move(entity_body));
- if (!content_type_.IsEmpty())
+ if (!content_type_.IsEmpty()) {
+ if (!cors::IsCorsSafelistedContentType(content_type_)) {
+ request.SetMode(network::mojom::blink::RequestMode::kCors);
+ }
request.SetHTTPContentType(content_type_);
+ }
}
const AtomicString GetContentType() const override { return content_type_; }
private:
- const Member<Blob> data_;
+ Blob* const data_;
AtomicString content_type_;
};
@@ -136,15 +145,18 @@ class BeaconDOMArrayBufferView final : public Beacon {
base::checked_cast<wtf_size_t>(data_->byteLengthAsSizeT()));
request.SetHttpBody(std::move(entity_body));
- // FIXME: a reasonable choice, but not in the spec; should it give a
- // default?
- request.SetHTTPContentType(AtomicString("application/octet-stream"));
+ if (!base::FeatureList::IsEnabled(
+ features::kSuppressContentTypeForBeaconMadeWithArrayBufferView)) {
+ // FIXME: a reasonable choice, but not in the spec; should it give a
+ // default?
+ request.SetHTTPContentType(AtomicString("application/octet-stream"));
+ }
}
const AtomicString GetContentType() const override { return g_null_atom; }
private:
- const Member<DOMArrayBufferView> data_;
+ DOMArrayBufferView* const data_;
};
class BeaconFormData final : public Beacon {
@@ -165,7 +177,7 @@ class BeaconFormData final : public Beacon {
const AtomicString GetContentType() const override { return content_type_; }
private:
- const Member<FormData> data_;
+ FormData* const data_;
scoped_refptr<EncodedFormData> entity_body_;
AtomicString content_type_;
};
@@ -188,7 +200,7 @@ bool SendBeaconCommon(LocalFrame* frame,
request.SetKeepalive(true);
request.SetRequestContext(mojom::RequestContextType::BEACON);
beacon.Serialize(request);
- FetchParameters params(request);
+ FetchParameters params(std::move(request));
// The spec says:
// - If mimeType is not null:
// - If mimeType value is a CORS-safelisted request-header value for the
@@ -230,16 +242,14 @@ void PingLoader::SendLinkAuditPing(LocalFrame* frame,
}
request.SetKeepalive(true);
- // TODO(domfarolino): Add WPTs ensuring that pings do not have a referrer
- // header.
request.SetReferrerString(Referrer::NoReferrer());
request.SetReferrerPolicy(network::mojom::ReferrerPolicy::kNever);
request.SetRequestContext(mojom::RequestContextType::PING);
- FetchParameters params(request);
+ FetchParameters params(std::move(request));
params.MutableOptions().initiator_info.name =
fetch_initiator_type_names::kPing;
- frame->Client()->DidDispatchPingLoader(request.Url());
+ frame->Client()->DidDispatchPingLoader(ping_url);
RawResource::Fetch(params, frame->GetDocument()->Fetcher(), nullptr);
}
@@ -253,13 +263,14 @@ void PingLoader::SendViolationReport(LocalFrame* frame,
request.SetHttpBody(std::move(report));
request.SetCredentialsMode(network::mojom::CredentialsMode::kSameOrigin);
request.SetRequestContext(mojom::RequestContextType::CSP_REPORT);
+ request.SetRequestDestination(network::mojom::RequestDestination::kReport);
request.SetRequestorOrigin(frame->GetDocument()->GetSecurityOrigin());
request.SetRedirectMode(network::mojom::RedirectMode::kError);
- FetchParameters params(request);
+ FetchParameters params(std::move(request));
params.MutableOptions().initiator_info.name =
fetch_initiator_type_names::kViolationreport;
- frame->Client()->DidDispatchPingLoader(request.Url());
+ frame->Client()->DidDispatchPingLoader(report_url);
RawResource::Fetch(params, frame->GetDocument()->Fetcher(), nullptr);
}
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 ac71a793058..86454344997 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
@@ -19,6 +19,27 @@ namespace blink {
namespace {
+class PartialResourceRequest {
+ public:
+ PartialResourceRequest() : PartialResourceRequest(ResourceRequest()) {}
+ PartialResourceRequest(const ResourceRequest& request)
+ : url_(request.Url()), priority_(request.Priority()) {
+ http_header_fields_.Adopt(request.HttpHeaderFields().CopyData());
+ }
+
+ bool IsNull() const { return url_.IsNull(); }
+ const KURL& Url() const { return url_; }
+ const AtomicString& HttpHeaderField(const AtomicString& name) const {
+ return http_header_fields_.Get(name);
+ }
+ ResourceLoadPriority Priority() const { return priority_; }
+
+ private:
+ KURL url_;
+ HTTPHeaderMap http_header_fields_;
+ ResourceLoadPriority priority_;
+};
+
class PingLocalFrameClient : public EmptyLocalFrameClient {
public:
std::unique_ptr<WebURLLoaderFactory> CreateURLLoaderFactory() override {
@@ -27,13 +48,13 @@ class PingLocalFrameClient : public EmptyLocalFrameClient {
void DispatchWillSendRequest(ResourceRequest& request) override {
if (request.GetKeepalive())
- ping_request_ = request;
+ ping_request_ = PartialResourceRequest(request);
}
- const ResourceRequest& PingRequest() const { return ping_request_; }
+ const PartialResourceRequest& PingRequest() const { return ping_request_; }
private:
- ResourceRequest ping_request_;
+ PartialResourceRequest ping_request_;
};
class PingLoaderTest : public PageTestBase {
@@ -55,14 +76,14 @@ class PingLoaderTest : public PageTestBase {
ASSERT_EQ(url.GetString(), GetDocument().Url().GetString());
}
- const ResourceRequest& PingAndGetRequest(const KURL& ping_url) {
+ const PartialResourceRequest& PingAndGetRequest(const KURL& ping_url) {
KURL destination_url("http://navigation.destination");
// TODO(crbug.com/751425): We should use the mock functionality
// via |PageTestBase::dummy_page_holder_|.
url_test_helpers::RegisterMockedURLLoad(
ping_url, test::CoreTestDataPath("bar.html"), "text/html");
PingLoader::SendLinkAuditPing(&GetFrame(), ping_url, destination_url);
- const ResourceRequest& ping_request = client_->PingRequest();
+ const PartialResourceRequest& ping_request = client_->PingRequest();
if (!ping_request.IsNull()) {
EXPECT_EQ(destination_url.GetString(),
ping_request.HttpHeaderField("Ping-To"));
@@ -80,7 +101,7 @@ class PingLoaderTest : public PageTestBase {
TEST_F(PingLoaderTest, HTTPSToHTTPS) {
KURL ping_url("https://localhost/bar.html");
SetDocumentURL(KURL("https://127.0.0.1:8000/foo.html"));
- const ResourceRequest& ping_request = PingAndGetRequest(ping_url);
+ const PartialResourceRequest& ping_request = PingAndGetRequest(ping_url);
ASSERT_FALSE(ping_request.IsNull());
EXPECT_EQ(ping_url, ping_request.Url());
EXPECT_EQ(String(), ping_request.HttpHeaderField("Ping-From"));
@@ -90,7 +111,7 @@ TEST_F(PingLoaderTest, HTTPToHTTPS) {
KURL document_url("http://127.0.0.1:8000/foo.html");
KURL ping_url("https://localhost/bar.html");
SetDocumentURL(document_url);
- const ResourceRequest& ping_request = PingAndGetRequest(ping_url);
+ const PartialResourceRequest& ping_request = PingAndGetRequest(ping_url);
ASSERT_FALSE(ping_request.IsNull());
EXPECT_EQ(ping_url, ping_request.Url());
EXPECT_EQ(document_url.GetString(),
@@ -99,7 +120,7 @@ TEST_F(PingLoaderTest, HTTPToHTTPS) {
TEST_F(PingLoaderTest, NonHTTPPingTarget) {
SetDocumentURL(KURL("http://127.0.0.1:8000/foo.html"));
- const ResourceRequest& ping_request =
+ const PartialResourceRequest& ping_request =
PingAndGetRequest(KURL("ftp://localhost/bar.html"));
ASSERT_TRUE(ping_request.IsNull());
}
@@ -115,7 +136,7 @@ TEST_F(PingLoaderTest, LinkAuditPingPriority) {
ping_url, test::CoreTestDataPath("bar.html"), "text/html");
PingLoader::SendLinkAuditPing(&GetFrame(), ping_url, destination_url);
url_test_helpers::ServeAsynchronousRequests();
- const ResourceRequest& request = client_->PingRequest();
+ const PartialResourceRequest& request = client_->PingRequest();
ASSERT_FALSE(request.IsNull());
ASSERT_EQ(request.Url(), ping_url);
EXPECT_EQ(ResourceLoadPriority::kVeryLow, request.Priority());
@@ -132,7 +153,7 @@ TEST_F(PingLoaderTest, ViolationPriority) {
PingLoader::SendViolationReport(&GetFrame(), ping_url,
EncodedFormData::Create());
url_test_helpers::ServeAsynchronousRequests();
- const ResourceRequest& request = client_->PingRequest();
+ const PartialResourceRequest& request = client_->PingRequest();
ASSERT_FALSE(request.IsNull());
ASSERT_EQ(request.Url(), ping_url);
EXPECT_EQ(ResourceLoadPriority::kVeryLow, request.Priority());
@@ -148,7 +169,7 @@ TEST_F(PingLoaderTest, BeaconPriority) {
ping_url, test::CoreTestDataPath("bar.html"), "text/html");
PingLoader::SendBeacon(&GetFrame(), ping_url, "hello");
url_test_helpers::ServeAsynchronousRequests();
- const ResourceRequest& request = client_->PingRequest();
+ const PartialResourceRequest& request = client_->PingRequest();
ASSERT_FALSE(request.IsNull());
ASSERT_EQ(request.Url(), ping_url);
EXPECT_EQ(ResourceLoadPriority::kVeryLow, request.Priority());
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 f5752cbbaab..0215b9965b1 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
@@ -12,7 +12,6 @@
#include "third_party/blink/public/mojom/devtools/console_message.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_url_load_timing.h"
#include "third_party/blink/public/platform/web_url_loader.h"
#include "third_party/blink/public/platform/web_url_loader_client.h"
#include "third_party/blink/public/platform/web_url_loader_factory.h"
@@ -23,6 +22,7 @@
#include "third_party/blink/renderer/core/frame/navigator.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/loader/alternate_signed_exchange_resource_info.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/loader/link_header.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
@@ -43,7 +43,9 @@ class PrefetchedSignedExchangeManager::PrefetchedSignedExchangeLoader
PrefetchedSignedExchangeLoader(
const WebURLRequest& request,
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : request_(request), task_runner_(std::move(task_runner)) {}
+ : task_runner_(std::move(task_runner)) {
+ request_.CopyFrom(request);
+ }
~PrefetchedSignedExchangeLoader() override {}
@@ -60,28 +62,44 @@ class PrefetchedSignedExchangeManager::PrefetchedSignedExchangeLoader
const WebURLRequest& request() const { return request_; }
// WebURLLoader methods:
- void LoadSynchronously(const WebURLRequest& request,
- WebURLLoaderClient* client,
- WebURLResponse& response,
- base::Optional<WebURLError>& error,
- WebData& data,
- int64_t& encoded_data_length,
- int64_t& encoded_body_length,
- WebBlobInfo& downloaded_blob) override {
+ void LoadSynchronously(
+ std::unique_ptr<network::ResourceRequest> request,
+ scoped_refptr<WebURLRequest::ExtraData> request_extra_data,
+ int requestor_id,
+ bool download_to_network_cache_only,
+ bool pass_response_pipe_to_client,
+ bool no_mime_sniffing,
+ base::TimeDelta timeout_interval,
+ WebURLLoaderClient* client,
+ WebURLResponse& response,
+ base::Optional<WebURLError>& error,
+ WebData& data,
+ int64_t& encoded_data_length,
+ int64_t& encoded_body_length,
+ WebBlobInfo& downloaded_blob) override {
NOTREACHED();
}
- void LoadAsynchronously(const WebURLRequest& request,
- WebURLLoaderClient* client) override {
+ void LoadAsynchronously(
+ std::unique_ptr<network::ResourceRequest> request,
+ scoped_refptr<WebURLRequest::ExtraData> request_extra_data,
+ int requestor_id,
+ bool download_to_network_cache_only,
+ bool no_mime_sniffing,
+ WebURLLoaderClient* client) override {
if (url_loader_) {
- url_loader_->LoadAsynchronously(request, client);
+ url_loader_->LoadAsynchronously(
+ std::move(request), std::move(request_extra_data), requestor_id,
+ download_to_network_cache_only, no_mime_sniffing, client);
return;
}
// It is safe to use Unretained(client), because |client| is a
// ResourceLoader which owns |this|, and we are binding with weak ptr of
// |this| here.
- pending_method_calls_.push(
- WTF::Bind(&PrefetchedSignedExchangeLoader::LoadAsynchronously,
- GetWeakPtr(), request, WTF::Unretained(client)));
+ pending_method_calls_.push(WTF::Bind(
+ &PrefetchedSignedExchangeLoader::LoadAsynchronously, GetWeakPtr(),
+ std::move(request), std::move(request_extra_data), requestor_id,
+ download_to_network_cache_only, no_mime_sniffing,
+ WTF::Unretained(client)));
}
void SetDefersLoading(bool value) override {
if (url_loader_) {
@@ -116,7 +134,7 @@ class PrefetchedSignedExchangeManager::PrefetchedSignedExchangeLoader
}
}
- const WebURLRequest request_;
+ WebURLRequest request_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
std::unique_ptr<WebURLLoader> url_loader_;
std::queue<base::OnceClosure> pending_method_calls_;
@@ -168,7 +186,7 @@ PrefetchedSignedExchangeManager::PrefetchedSignedExchangeManager(
PrefetchedSignedExchangeManager::~PrefetchedSignedExchangeManager() {}
-void PrefetchedSignedExchangeManager::Trace(blink::Visitor* visitor) {
+void PrefetchedSignedExchangeManager::Trace(Visitor* visitor) {
visitor->Trace(frame_);
}
@@ -266,8 +284,9 @@ void PrefetchedSignedExchangeManager::TriggerLoad() {
"Requesting the all original resources ignoreing all alternative signed"
" exchange responses.";
frame_->GetDocument()->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kNetwork,
- mojom::ConsoleMessageLevel::kError, message));
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kNetwork,
+ mojom::ConsoleMessageLevel::kError, message));
for (auto loader : loaders_) {
if (!loader)
continue;
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 40dfc6f5aa4..2b3b35bc8b7 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(blink::Visitor* visitor);
+ void Trace(Visitor* visitor);
// 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 96fe8650bf3..7ad53e5e884 100644
--- a/chromium/third_party/blink/renderer/core/loader/preload_helper.cc
+++ b/chromium/third_party/blink/renderer/core/loader/preload_helper.cc
@@ -33,8 +33,10 @@
#include "third_party/blink/renderer/core/loader/resource/link_fetch_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"
#include "third_party/blink/renderer/core/script/modulator.h"
#include "third_party/blink/renderer/core/script/script_loader.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/fetch_initiator_type_names.h"
#include "third_party/blink/renderer/platform/loader/fetch/raw_resource.h"
@@ -90,10 +92,10 @@ bool IsSupportedType(ResourceType resource_type, const String& mime_type) {
MediaValues* CreateMediaValues(
Document& document,
- const base::Optional<ViewportDescription>& viewport_description) {
+ const ViewportDescription* viewport_description) {
MediaValues* media_values =
MediaValues::CreateDynamicIfFrameExists(document.GetFrame());
- if (viewport_description.has_value()) {
+ if (viewport_description) {
FloatSize initial_viewport(media_values->DeviceWidth(),
media_values->DeviceHeight());
PageScaleConstraints constraints = viewport_description->Resolve(
@@ -104,8 +106,11 @@ MediaValues* CreateMediaValues(
return media_values;
}
-bool MediaMatches(const String& media, MediaValues* media_values) {
- scoped_refptr<MediaQuerySet> media_queries = MediaQuerySet::Create(media);
+bool MediaMatches(const String& media,
+ MediaValues* media_values,
+ const ExecutionContext* execution_context) {
+ scoped_refptr<MediaQuerySet> media_queries =
+ MediaQuerySet::Create(media, execution_context);
MediaQueryEvaluator evaluator(*media_values);
return evaluator.Eval(*media_queries);
}
@@ -116,13 +121,26 @@ KURL GetBestFitImageURL(const Document& document,
const KURL& href,
const String& image_srcset,
const String& image_sizes) {
- float source_size = SizesAttributeParser(media_values, image_sizes).length();
+ float source_size = SizesAttributeParser(media_values, image_sizes,
+ document.ToExecutionContext())
+ .length();
ImageCandidate candidate = BestFitSourceForImageAttributes(
media_values->DevicePixelRatio(), source_size, href, image_srcset);
return base_url.IsNull() ? document.CompleteURL(candidate.ToString())
: KURL(base_url, candidate.ToString());
}
+// Check whether the `as` attribute is valid according to the spec, even if we
+// don't currently support it yet.
+bool IsValidButUnsupportedAsAttribute(const String& as) {
+ DCHECK(as != "fetch" && as != "image" && as != "font" && as != "script" &&
+ as != "style" && as != "track");
+ return as == "audio" || as == "audioworklet" || as == "document" ||
+ as == "embed" || as == "manifest" || as == "object" ||
+ as == "paintworklet" || as == "report" || as == "sharedworker" ||
+ as == "video" || as == "worker" || as == "xslt";
+}
+
} // namespace
void PreloadHelper::DnsPrefetchIfNeeded(
@@ -142,7 +160,7 @@ void PreloadHelper::DnsPrefetchIfNeeded(
params.href.IsValid() && !params.href.IsEmpty()) {
if (settings->GetLogDnsPrefetchAndPreconnect()) {
SendMessageToConsoleForPossiblyNullDocument(
- ConsoleMessage::Create(
+ MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kVerbose,
String("DNS prefetch triggered for " + params.href.Host())),
@@ -170,20 +188,21 @@ void PreloadHelper::PreconnectIfNeeded(
Settings* settings = frame ? frame->GetSettings() : nullptr;
if (settings && settings->GetLogDnsPrefetchAndPreconnect()) {
SendMessageToConsoleForPossiblyNullDocument(
- ConsoleMessage::Create(
+ MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kVerbose,
String("Preconnect triggered for ") + params.href.GetString()),
document, frame);
if (params.cross_origin != kCrossOriginAttributeNotSet) {
SendMessageToConsoleForPossiblyNullDocument(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kOther,
- mojom::ConsoleMessageLevel::kVerbose,
- String("Preconnect CORS setting is ") +
- String((params.cross_origin ==
- kCrossOriginAttributeAnonymous)
- ? "anonymous"
- : "use-credentials")),
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kOther,
+ mojom::ConsoleMessageLevel::kVerbose,
+ String("Preconnect CORS setting is ") +
+ String(
+ (params.cross_origin == kCrossOriginAttributeAnonymous)
+ ? "anonymous"
+ : "use-credentials")),
document, frame);
}
}
@@ -228,7 +247,7 @@ Resource* PreloadHelper::PreloadIfNeeded(
Document& document,
const KURL& base_url,
LinkCaller caller,
- const base::Optional<ViewportDescription>& viewport_description,
+ const ViewportDescription* viewport_description,
ParserDisposition parser_disposition) {
if (!document.Loader() || !params.rel.IsLinkPreload())
return nullptr;
@@ -249,7 +268,7 @@ Resource* PreloadHelper::PreloadIfNeeded(
UseCounter::Count(document, WebFeature::kLinkRelPreload);
if (!url.IsValid() || url.IsEmpty()) {
- document.AddConsoleMessage(ConsoleMessage::Create(
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kWarning,
String("<link rel=preload> has an invalid `href` value")));
@@ -260,22 +279,27 @@ Resource* PreloadHelper::PreloadIfNeeded(
if (!params.media.IsEmpty()) {
if (!media_values)
media_values = CreateMediaValues(document, viewport_description);
- if (!MediaMatches(params.media, media_values))
+ if (!MediaMatches(params.media, media_values,
+ document.ToExecutionContext()))
return nullptr;
}
if (caller == kLinkCalledFromHeader)
UseCounter::Count(document, WebFeature::kLinkHeaderPreload);
if (resource_type == base::nullopt) {
- document.AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kOther,
- mojom::ConsoleMessageLevel::kWarning,
- String("<link rel=preload> must have a valid `as` value")));
+ String message;
+ if (IsValidButUnsupportedAsAttribute(params.as)) {
+ message = String("<link rel=preload> uses an unsupported `as` value");
+ } else {
+ message = String("<link rel=preload> must have a valid `as` value");
+ }
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kOther,
+ mojom::blink::ConsoleMessageLevel::kWarning, message));
return nullptr;
}
-
if (!IsSupportedType(resource_type.value(), params.type)) {
- document.AddConsoleMessage(ConsoleMessage::Create(
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kWarning,
String("<link rel=preload> has an unsupported `type` value")));
@@ -284,6 +308,8 @@ Resource* PreloadHelper::PreloadIfNeeded(
ResourceRequest resource_request(url);
resource_request.SetRequestContext(ResourceFetcher::DetermineRequestContext(
resource_type.value(), ResourceFetcher::kImageNotImageSet));
+ resource_request.SetRequestDestination(
+ ResourceFetcher::DetermineRequestDestination(resource_type.value()));
resource_request.SetReferrerPolicy(params.referrer_policy);
@@ -293,7 +319,7 @@ Resource* PreloadHelper::PreloadIfNeeded(
ResourceLoaderOptions options;
options.initiator_info.name = fetch_initiator_type_names::kLink;
options.parser_disposition = parser_disposition;
- FetchParameters link_fetch_params(resource_request, options);
+ FetchParameters link_fetch_params(std::move(resource_request), options);
link_fetch_params.SetCharset(document.Encoding());
if (params.cross_origin != kCrossOriginAttributeNotSet) {
@@ -310,7 +336,9 @@ Resource* PreloadHelper::PreloadIfNeeded(
if (!integrity_attr.IsEmpty()) {
IntegrityMetadataSet metadata_set;
SubresourceIntegrity::ParseIntegrityAttribute(
- integrity_attr, SubresourceIntegrityHelper::GetFeatures(&document),
+ integrity_attr,
+ SubresourceIntegrityHelper::GetFeatures(
+ document.ToExecutionContext()),
metadata_set);
link_fetch_params.SetIntegrityMetadata(metadata_set);
link_fetch_params.MutableResourceRequest().SetFetchIntegrity(
@@ -318,7 +346,7 @@ Resource* PreloadHelper::PreloadIfNeeded(
}
} else {
if (!integrity_attr.IsEmpty()) {
- document.AddConsoleMessage(ConsoleMessage::Create(
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kWarning,
String("The `integrity` attribute is currently ignored for preload "
@@ -330,21 +358,21 @@ Resource* PreloadHelper::PreloadIfNeeded(
link_fetch_params.SetContentSecurityPolicyNonce(params.nonce);
Settings* settings = document.GetSettings();
if (settings && settings->GetLogPreload()) {
- document.AddConsoleMessage(ConsoleMessage::Create(
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kVerbose,
String("Preload triggered for " + url.Host() + url.GetPath())));
}
link_fetch_params.SetLinkPreload(true);
return PreloadHelper::StartPreload(resource_type.value(), link_fetch_params,
- document.Fetcher());
+ document);
}
// https://html.spec.whatwg.org/C/#link-type-modulepreload
void PreloadHelper::ModulePreloadIfNeeded(
const LinkLoadParameters& params,
Document& document,
- const base::Optional<ViewportDescription>& viewport_description,
+ const ViewportDescription* viewport_description,
SingleModuleClient* client) {
if (!document.Loader() || !params.rel.IsModulePreload())
return;
@@ -354,10 +382,10 @@ void PreloadHelper::ModulePreloadIfNeeded(
// Step 1. "If the href attribute's value is the empty string, then return."
// [spec text]
if (params.href.IsEmpty()) {
- document.AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kOther,
- mojom::ConsoleMessageLevel::kWarning,
- "<link rel=modulepreload> has no `href` value"));
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kOther,
+ mojom::ConsoleMessageLevel::kWarning,
+ "<link rel=modulepreload> has no `href` value"));
return;
}
@@ -379,7 +407,7 @@ void PreloadHelper::ModulePreloadIfNeeded(
// and return." [spec text]
// Currently we only support as="script".
if (!params.as.IsEmpty() && params.as != "script") {
- document.AddConsoleMessage(ConsoleMessage::Create(
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kWarning,
String("<link rel=modulepreload> has an invalid `as` value " +
@@ -393,14 +421,16 @@ void PreloadHelper::ModulePreloadIfNeeded(
}
return;
}
- mojom::RequestContextType destination = mojom::RequestContextType::SCRIPT;
+ mojom::RequestContextType context_type = mojom::RequestContextType::SCRIPT;
+ network::mojom::RequestDestination destination =
+ network::mojom::RequestDestination::kScript;
// Step 4. "Parse the URL given by the href attribute, relative to the
// element's node document. If that fails, then return. Otherwise, let url be
// the resulting URL record." [spec text]
// |href| is already resolved in caller side.
if (!params.href.IsValid()) {
- document.AddConsoleMessage(ConsoleMessage::Create(
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kWarning,
"<link rel=modulepreload> has an invalid `href` value " +
@@ -413,7 +443,8 @@ void PreloadHelper::ModulePreloadIfNeeded(
if (!params.media.IsEmpty()) {
MediaValues* media_values =
CreateMediaValues(document, viewport_description);
- if (!MediaMatches(params.media, media_values))
+ if (!MediaMatches(params.media, media_values,
+ document.ToExecutionContext()))
return;
}
@@ -431,11 +462,12 @@ void PreloadHelper::ModulePreloadIfNeeded(
IntegrityMetadataSet integrity_metadata;
if (!params.integrity.IsEmpty()) {
SubresourceIntegrity::IntegrityFeatures integrity_features =
- SubresourceIntegrityHelper::GetFeatures(&document);
+ SubresourceIntegrityHelper::GetFeatures(document.ToExecutionContext());
SubresourceIntegrity::ReportInfo report_info;
SubresourceIntegrity::ParseIntegrityAttribute(
params.integrity, integrity_features, integrity_metadata, &report_info);
- SubresourceIntegrityHelper::DoReport(document, report_info);
+ SubresourceIntegrityHelper::DoReport(*document.ToExecutionContext(),
+ report_info);
}
// Step 9. "Let referrer policy be the current state of the element's
@@ -447,7 +479,7 @@ void PreloadHelper::ModulePreloadIfNeeded(
// metadata is "not-parser-inserted", credentials mode is credentials mode,
// and referrer policy is referrer policy." [spec text]
ModuleScriptFetchRequest request(
- params.href, destination,
+ params.href, context_type, destination,
ScriptFetchOptions(params.nonce, integrity_metadata, params.integrity,
kNotParserInserted, credentials_mode,
params.referrer_policy,
@@ -464,11 +496,11 @@ void PreloadHelper::ModulePreloadIfNeeded(
Settings* settings = document.GetSettings();
if (settings && settings->GetLogPreload()) {
- document.AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kOther,
- mojom::ConsoleMessageLevel::kVerbose,
- "Module preload triggered for " +
- params.href.Host() + params.href.GetPath()));
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kOther,
+ mojom::ConsoleMessageLevel::kVerbose,
+ "Module preload triggered for " + params.href.Host() +
+ params.href.GetPath()));
}
// Asynchronously continue processing after
@@ -510,7 +542,7 @@ Resource* PreloadHelper::PrefetchIfNeeded(const LinkLoadParameters& params,
ResourceLoaderOptions options;
options.initiator_info.name = fetch_initiator_type_names::kLink;
- FetchParameters link_fetch_params(resource_request, options);
+ FetchParameters link_fetch_params(std::move(resource_request), options);
if (params.cross_origin != kCrossOriginAttributeNotSet) {
link_fetch_params.SetCrossOriginAccessControl(
document.GetSecurityOrigin(), params.cross_origin);
@@ -533,10 +565,10 @@ void PreloadHelper::LoadLinksFromHeader(
Document* document,
CanLoadResources can_load_resources,
MediaPreloadPolicy media_policy,
- const base::Optional<ViewportDescription>& viewport_description,
+ const ViewportDescription* viewport_description,
std::unique_ptr<AlternateSignedExchangeResourceInfo>
alternate_resource_info,
- base::Optional<base::UnguessableToken> recursive_prefetch_token) {
+ const base::UnguessableToken* recursive_prefetch_token) {
if (header_value.IsEmpty())
return;
LinkHeaderSet header_set(header_value);
@@ -550,12 +582,14 @@ void PreloadHelper::LoadLinksFromHeader(
continue;
LinkLoadParameters params(header, base_url);
+ bool change_rel_to_prefetch = false;
+
if (params.rel.IsLinkPreload() && recursive_prefetch_token) {
// Only preload headers are expected to have a recursive prefetch token
// In response to that token's existence, we treat the request as a
// prefetch.
- params.recursive_prefetch_token = recursive_prefetch_token;
- params.rel = LinkRelAttribute("prefetch");
+ params.recursive_prefetch_token = *recursive_prefetch_token;
+ change_rel_to_prefetch = true;
}
if (alternate_resource_info && params.rel.IsLinkPreload()) {
@@ -598,9 +632,13 @@ void PreloadHelper::LoadLinksFromHeader(
// navigation, but can only populate things in the cache that can be
// used by the next navigation only when they requested the same URL
// with the same association mapping.
- params.rel = LinkRelAttribute("prefetch");
+ change_rel_to_prefetch = true;
}
}
+
+ if (change_rel_to_prefetch)
+ params.rel = LinkRelAttribute("prefetch");
+
// Sanity check to avoid re-entrancy here.
if (params.href == base_url)
continue;
@@ -625,7 +663,8 @@ void PreloadHelper::LoadLinksFromHeader(
Resource* PreloadHelper::StartPreload(ResourceType type,
FetchParameters& params,
- ResourceFetcher* resource_fetcher) {
+ Document& document) {
+ ResourceFetcher* resource_fetcher = document.Fetcher();
Resource* resource = nullptr;
switch (type) {
case ResourceType::kImage:
@@ -633,6 +672,7 @@ Resource* PreloadHelper::StartPreload(ResourceType type,
break;
case ResourceType::kScript:
params.SetRequestContext(mojom::RequestContextType::SCRIPT);
+ params.SetRequestDestination(network::mojom::RequestDestination::kScript);
resource = ScriptResource::Fetch(params, resource_fetcher, nullptr,
ScriptResource::kAllowStreaming);
break;
@@ -642,6 +682,8 @@ Resource* PreloadHelper::StartPreload(ResourceType type,
break;
case ResourceType::kFont:
resource = FontResource::Fetch(params, resource_fetcher, nullptr);
+ document.GetFontPreloadManager().FontPreloadingStarted(
+ ToFontResource(resource));
break;
case ResourceType::kAudio:
case ResourceType::kVideo:
diff --git a/chromium/third_party/blink/renderer/core/loader/preload_helper.h b/chromium/third_party/blink/renderer/core/loader/preload_helper.h
index 79522b5f6fc..d06899c602f 100644
--- a/chromium/third_party/blink/renderer/core/loader/preload_helper.h
+++ b/chromium/third_party/blink/renderer/core/loader/preload_helper.h
@@ -6,7 +6,6 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_PRELOAD_HELPER_H_
#include "base/optional.h"
-#include "third_party/blink/renderer/core/page/viewport_description.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource.h"
namespace blink {
@@ -16,6 +15,7 @@ class Document;
class LocalFrame;
class SingleModuleClient;
struct LinkLoadParameters;
+struct ViewportDescription;
// PreloadHelper is a helper class for preload, module preload, prefetch,
// DNS prefetch, and preconnect triggered by <link> elements and "Link" HTTP
@@ -41,12 +41,10 @@ class PreloadHelper final {
Document*, // can be nullptr
CanLoadResources,
MediaPreloadPolicy,
- const base::Optional<ViewportDescription>&,
+ const ViewportDescription*, // can be nullptr
std::unique_ptr<AlternateSignedExchangeResourceInfo>,
- base::Optional<base::UnguessableToken>);
- static Resource* StartPreload(ResourceType,
- FetchParameters&,
- ResourceFetcher*);
+ const base::UnguessableToken* /* can be nullptr */);
+ static Resource* StartPreload(ResourceType, FetchParameters&, Document&);
// Currently only used for UseCounter.
enum LinkCaller {
@@ -67,11 +65,11 @@ class PreloadHelper final {
Document&,
const KURL& base_url,
LinkCaller,
- const base::Optional<ViewportDescription>&,
+ const ViewportDescription*,
ParserDisposition);
static void ModulePreloadIfNeeded(const LinkLoadParameters&,
Document&,
- const base::Optional<ViewportDescription>&,
+ const ViewportDescription*,
SingleModuleClient*);
static base::Optional<ResourceType> GetResourceTypeFromAsAttribute(
diff --git a/chromium/third_party/blink/renderer/core/loader/prerenderer_client.cc b/chromium/third_party/blink/renderer/core/loader/prerenderer_client.cc
index f8451b829d7..6e194ca6a51 100644
--- a/chromium/third_party/blink/renderer/core/loader/prerenderer_client.cc
+++ b/chromium/third_party/blink/renderer/core/loader/prerenderer_client.cc
@@ -31,11 +31,8 @@
#include "third_party/blink/renderer/core/loader/prerenderer_client.h"
-#include "third_party/blink/public/platform/web_prerender.h"
#include "third_party/blink/public/web/web_prerenderer_client.h"
-#include "third_party/blink/renderer/core/exported/web_view_impl.h"
#include "third_party/blink/renderer/core/page/page.h"
-#include "third_party/blink/renderer/platform/prerender.h"
namespace blink {
@@ -50,13 +47,6 @@ PrerendererClient* PrerendererClient::From(Page* page) {
PrerendererClient::PrerendererClient(Page& page, WebPrerendererClient* client)
: Supplement<Page>(page), client_(client) {}
-void PrerendererClient::WillAddPrerender(Prerender* prerender) {
- if (!client_)
- return;
- WebPrerender web_prerender(prerender);
- client_->WillAddPrerender(&web_prerender);
-}
-
bool PrerendererClient::IsPrefetchOnly() {
return client_ && client_->IsPrefetchOnly();
}
diff --git a/chromium/third_party/blink/renderer/core/loader/prerenderer_client.h b/chromium/third_party/blink/renderer/core/loader/prerenderer_client.h
index ea613dade39..1e027b7c834 100644
--- a/chromium/third_party/blink/renderer/core/loader/prerenderer_client.h
+++ b/chromium/third_party/blink/renderer/core/loader/prerenderer_client.h
@@ -40,7 +40,6 @@
namespace blink {
class Page;
-class Prerender;
class WebPrerendererClient;
class CORE_EXPORT PrerendererClient
@@ -53,7 +52,6 @@ class CORE_EXPORT PrerendererClient
PrerendererClient(Page&, WebPrerendererClient*);
- virtual void WillAddPrerender(Prerender*);
virtual bool IsPrefetchOnly();
static PrerendererClient* From(Page*);
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 620197da5e3..79e250203ee 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
@@ -14,6 +14,7 @@
#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/core/loader/document_loader.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -79,6 +80,7 @@ PreviewsResourceLoadingHints::PreviewsResourceLoadingHints(
block_resource_type_[static_cast<int>(ResourceType::kCSSStyleSheet)] = true;
block_resource_type_[static_cast<int>(ResourceType::kScript)] = true;
block_resource_type_[static_cast<int>(ResourceType::kRaw)] = true;
+ block_resource_type_[static_cast<int>(ResourceType::kFont)] = true;
for (int i = 0; i < static_cast<int>(ResourceType::kMaxValue) + 1; ++i) {
// Parameter names are of format: "block_resource_type_%d". The value
// should be either "true" or "false".
@@ -114,8 +116,7 @@ bool PreviewsResourceLoadingHints::AllowLoad(
bool allow_load = true;
int pattern_index = 0;
- for (const WTF::String& subresource_pattern :
- subresource_patterns_to_block_) {
+ for (const WebString& subresource_pattern : subresource_patterns_to_block_) {
// TODO(tbansal): https://crbug.com/856247. Add support for wildcard
// matching.
if (resource_url_string.Find(subresource_pattern) != kNotFound) {
@@ -149,12 +150,12 @@ bool PreviewsResourceLoadingHints::AllowLoad(
void PreviewsResourceLoadingHints::ReportBlockedLoading(
const KURL& resource_url) const {
- execution_context_->AddConsoleMessage(ConsoleMessage::Create(
+ execution_context_->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther, mojom::ConsoleMessageLevel::kWarning,
GetConsoleLogStringForBlockedLoad(resource_url)));
}
-void PreviewsResourceLoadingHints::Trace(blink::Visitor* visitor) {
+void PreviewsResourceLoadingHints::Trace(Visitor* visitor) {
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 5033635a421..edd00fe6753 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(blink::Visitor*);
+ virtual void Trace(Visitor*);
// 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/previews_resource_loading_hints_test.cc b/chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints_test.cc
index 17784531c31..87db913bd4b 100644
--- a/chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints_test.cc
+++ b/chromium/third_party/blink/renderer/core/loader/previews_resource_loading_hints_test.cc
@@ -42,8 +42,8 @@ TEST_F(PreviewsResourceLoadingHintsTest, NoPatterns) {
Vector<WTF::String> subresources_to_block;
PreviewsResourceLoadingHints* hints = PreviewsResourceLoadingHints::Create(
- dummy_page_holder_->GetDocument(), ukm::UkmRecorder::GetNewSourceID(),
- subresources_to_block);
+ *dummy_page_holder_->GetDocument().ToExecutionContext(),
+ ukm::UkmRecorder::GetNewSourceID(), subresources_to_block);
EXPECT_TRUE(hints->AllowLoad(ResourceType::kScript,
KURL("https://www.example.com/"),
ResourceLoadPriority::kHighest));
@@ -54,8 +54,8 @@ TEST_F(PreviewsResourceLoadingHintsTest, OnePattern) {
subresources_to_block.push_back("foo.jpg");
PreviewsResourceLoadingHints* hints = PreviewsResourceLoadingHints::Create(
- dummy_page_holder_->GetDocument(), ukm::UkmRecorder::GetNewSourceID(),
- subresources_to_block);
+ *dummy_page_holder_->GetDocument().ToExecutionContext(),
+ ukm::UkmRecorder::GetNewSourceID(), subresources_to_block);
const struct {
KURL url;
@@ -117,8 +117,8 @@ TEST_F(PreviewsResourceLoadingHintsTest, MultiplePatterns) {
subresources_to_block.push_back(".example2.com/baz.jpg");
PreviewsResourceLoadingHints* hints = PreviewsResourceLoadingHints::Create(
- dummy_page_holder_->GetDocument(), ukm::UkmRecorder::GetNewSourceID(),
- subresources_to_block);
+ *dummy_page_holder_->GetDocument().ToExecutionContext(),
+ ukm::UkmRecorder::GetNewSourceID(), subresources_to_block);
const struct {
KURL url;
@@ -149,8 +149,8 @@ TEST_F(PreviewsResourceLoadingHintsTest, OnePatternHistogramChecker) {
subresources_to_block.push_back("foo.jpg");
PreviewsResourceLoadingHints* hints = PreviewsResourceLoadingHints::Create(
- dummy_page_holder_->GetDocument(), ukm::UkmRecorder::GetNewSourceID(),
- subresources_to_block);
+ *dummy_page_holder_->GetDocument().ToExecutionContext(),
+ ukm::UkmRecorder::GetNewSourceID(), subresources_to_block);
const struct {
KURL url;
@@ -210,8 +210,8 @@ TEST_F(PreviewsResourceLoadingHintsTest, MultiplePatternUKMChecker) {
subresources_to_block.push_back(".example3.com/very_low_2_and_medium_3.jpg");
PreviewsResourceLoadingHints* hints = PreviewsResourceLoadingHints::Create(
- dummy_page_holder_->GetDocument(), ukm::UkmRecorder::GetNewSourceID(),
- subresources_to_block);
+ *dummy_page_holder_->GetDocument().ToExecutionContext(),
+ ukm::UkmRecorder::GetNewSourceID(), subresources_to_block);
const struct {
KURL url;
@@ -301,8 +301,8 @@ TEST_F(PreviewsResourceLoadingHintsTestBlockImages,
subresources_to_block.push_back("foo.jpg");
PreviewsResourceLoadingHints* hints = PreviewsResourceLoadingHints::Create(
- dummy_page_holder_->GetDocument(), ukm::UkmRecorder::GetNewSourceID(),
- subresources_to_block);
+ *dummy_page_holder_->GetDocument().ToExecutionContext(),
+ ukm::UkmRecorder::GetNewSourceID(), subresources_to_block);
const struct {
KURL url;
@@ -321,8 +321,8 @@ TEST_F(PreviewsResourceLoadingHintsTestBlockImages,
};
for (const auto& test : tests) {
- // By default, resource blocking hints do not apply to fonts.
- EXPECT_TRUE(hints->AllowLoad(ResourceType::kFont, test.url,
+ // By default, resource blocking hints do not apply to SVG documents.
+ EXPECT_TRUE(hints->AllowLoad(ResourceType::kSVGDocument, test.url,
ResourceLoadPriority::kHighest));
// Feature override should cause resource blocking hints to apply to images.
EXPECT_EQ(test.allow_load_expected,
@@ -357,8 +357,8 @@ TEST_F(PreviewsResourceLoadingHintsTestAllowCSS,
subresources_to_block.push_back("foo.jpg");
PreviewsResourceLoadingHints* hints = PreviewsResourceLoadingHints::Create(
- dummy_page_holder_->GetDocument(), ukm::UkmRecorder::GetNewSourceID(),
- subresources_to_block);
+ *dummy_page_holder_->GetDocument().ToExecutionContext(),
+ ukm::UkmRecorder::GetNewSourceID(), subresources_to_block);
const struct {
KURL url;
@@ -378,9 +378,7 @@ TEST_F(PreviewsResourceLoadingHintsTestAllowCSS,
for (const auto& test : tests) {
// Feature override should cause resource blocking hints to apply to only
- // scripts.
- EXPECT_TRUE(hints->AllowLoad(ResourceType::kFont, test.url,
- ResourceLoadPriority::kHighest));
+ // scripts and fonts.
EXPECT_TRUE(hints->AllowLoad(ResourceType::kImage, test.url,
ResourceLoadPriority::kHighest));
EXPECT_TRUE(hints->AllowLoad(ResourceType::kCSSStyleSheet, test.url,
@@ -388,6 +386,9 @@ TEST_F(PreviewsResourceLoadingHintsTestAllowCSS,
EXPECT_EQ(test.allow_load_expected,
hints->AllowLoad(ResourceType::kScript, test.url,
ResourceLoadPriority::kHighest));
+ EXPECT_EQ(test.allow_load_expected,
+ hints->AllowLoad(ResourceType::kFont, test.url,
+ ResourceLoadPriority::kHighest));
}
}
diff --git a/chromium/third_party/blink/renderer/core/loader/private/frame_client_hints_preferences_context.cc b/chromium/third_party/blink/renderer/core/loader/private/frame_client_hints_preferences_context.cc
index a09b4e4d8ff..a8701e6cb7e 100644
--- a/chromium/third_party/blink/renderer/core/loader/private/frame_client_hints_preferences_context.cc
+++ b/chromium/third_party/blink/renderer/core/loader/private/frame_client_hints_preferences_context.cc
@@ -28,6 +28,8 @@ static constexpr WebFeature kWebFeatureMapping[] = {
WebFeature::kClientHintsUAArch,
WebFeature::kClientHintsUAPlatform,
WebFeature::kClientHintsUAModel,
+ WebFeature::kClientHintsUAMobile,
+ WebFeature::kClientHintsUAFullVersion,
};
static_assert(static_cast<int>(mojom::WebClientHintsType::kMaxValue) + 1 ==
diff --git a/chromium/third_party/blink/renderer/core/loader/private/frame_client_hints_preferences_context.h b/chromium/third_party/blink/renderer/core/loader/private/frame_client_hints_preferences_context.h
index ebbebd507bb..b1d439d660e 100644
--- a/chromium/third_party/blink/renderer/core/loader/private/frame_client_hints_preferences_context.h
+++ b/chromium/third_party/blink/renderer/core/loader/private/frame_client_hints_preferences_context.h
@@ -23,7 +23,7 @@ class FrameClientHintsPreferencesContext final
void CountPersistentClientHintHeaders() override;
private:
- Member<LocalFrame> frame_;
+ LocalFrame* frame_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/prerender_client.h b/chromium/third_party/blink/renderer/core/loader/private/prerender_client.h
index 0d56cf628c9..cc62574b54c 100644
--- a/chromium/third_party/blink/renderer/platform/prerender_client.h
+++ b/chromium/third_party/blink/renderer/core/loader/private/prerender_client.h
@@ -29,8 +29,8 @@
*
*/
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_PRERENDER_CLIENT_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PRERENDER_CLIENT_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_PRIVATE_PRERENDER_CLIENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_PRIVATE_PRERENDER_CLIENT_H_
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/platform_export.h"
@@ -46,9 +46,9 @@ class PLATFORM_EXPORT PrerenderClient : public GarbageCollectedMixin {
virtual void DidSendLoadForPrerender() = 0;
virtual void DidSendDOMContentLoadedForPrerender() = 0;
- void Trace(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) override {}
};
} // namespace blink
-#endif
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_PRIVATE_PRERENDER_CLIENT_H_
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 01aaa2809ba..97fc5fd0bbd 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
@@ -31,12 +31,12 @@
#include "third_party/blink/renderer/core/loader/private/prerender_handle.h"
#include "services/network/public/mojom/referrer_policy.mojom-blink.h"
+#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/core/loader/frame_loader.h"
-#include "third_party/blink/renderer/core/loader/prerenderer_client.h"
+#include "third_party/blink/renderer/core/frame/local_frame_client.h"
+#include "third_party/blink/renderer/core/loader/private/prerender_client.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/prerender.h"
#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
namespace blink {
@@ -48,70 +48,112 @@ PrerenderHandle* PrerenderHandle::Create(Document& document,
const unsigned prerender_rel_types) {
// Prerenders are unlike requests in most ways (for instance, they pass down
// fragments, and they don't return data), but they do have referrers.
+
if (!document.GetFrame())
return nullptr;
- auto* prerender = MakeGarbageCollected<Prerender>(
- client, url, prerender_rel_types,
- SecurityPolicy::GenerateReferrer(document.GetReferrerPolicy(), url,
- document.OutgoingReferrer()),
- document.GetSecurityOrigin());
-
- PrerendererClient* prerenderer_client =
- PrerendererClient::From(document.GetPage());
- if (prerenderer_client)
- prerenderer_client->WillAddPrerender(prerender);
- prerender->Add();
-
- return MakeGarbageCollected<PrerenderHandle>(document, prerender);
+ Referrer referrer = SecurityPolicy::GenerateReferrer(
+ document.GetReferrerPolicy(), url, document.OutgoingReferrer());
+
+ mojom::blink::PrerenderAttributesPtr attributes =
+ mojom::blink::PrerenderAttributes::New();
+ attributes->url = url;
+ 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->view_size =
+ gfx::Size(document.GetFrame()->GetMainFrameViewportSize());
+
+ mojo::Remote<mojom::blink::PrerenderProcessor> prerender_processor;
+ document.GetFrame()->Client()->GetBrowserInterfaceBroker().GetInterface(
+ prerender_processor.BindNewPipeAndPassReceiver());
+
+ mojo::PendingRemote<mojom::blink::PrerenderHandleClient>
+ prerender_handle_client;
+ auto receiver = prerender_handle_client.InitWithNewPipeAndPassReceiver();
+
+ mojo::Remote<mojom::blink::PrerenderHandle> remote_handle;
+ prerender_processor->AddPrerender(std::move(attributes),
+ std::move(prerender_handle_client),
+ remote_handle.BindNewPipeAndPassReceiver());
+
+ return MakeGarbageCollected<PrerenderHandle>(PassKey(), document, client, url,
+ std::move(remote_handle),
+ std::move(receiver));
}
-PrerenderHandle::PrerenderHandle(Document& document, Prerender* prerender)
- : ContextLifecycleObserver(&document), prerender_(prerender) {}
+PrerenderHandle::PrerenderHandle(
+ PassKey pass_key,
+ Document& document,
+ PrerenderClient* client,
+ const KURL& url,
+ mojo::Remote<mojom::blink::PrerenderHandle> remote_handle,
+ mojo::PendingReceiver<mojom::blink::PrerenderHandleClient> receiver)
+ : ExecutionContextLifecycleObserver(&document),
+ url_(url),
+ client_(client),
+ remote_handle_(std::move(remote_handle)),
+ receiver_(this, std::move(receiver)) {}
PrerenderHandle::~PrerenderHandle() = default;
void PrerenderHandle::Dispose() {
- if (prerender_) {
- prerender_->Abandon();
- Detach();
- }
+ if (remote_handle_)
+ remote_handle_->Abandon();
+ Detach();
}
void PrerenderHandle::Cancel() {
// Avoid both abandoning and canceling the same prerender. In the abandon
// case, the LinkLoader cancels the PrerenderHandle as the Document is
- // destroyed, even through the ContextLifecycleObserver has already abandoned
- // it.
- if (!prerender_)
- return;
- prerender_->Cancel();
+ // destroyed, even through the ExecutionContextLifecycleObserver has already
+ // abandoned it.
+ if (remote_handle_)
+ remote_handle_->Cancel();
Detach();
}
const KURL& PrerenderHandle::Url() const {
- return prerender_->Url();
+ return url_;
}
-void PrerenderHandle::ContextDestroyed(ExecutionContext*) {
+void PrerenderHandle::ContextDestroyed() {
// A PrerenderHandle is not removed from LifecycleNotifier::m_observers until
// the next GC runs. Thus contextDestroyed() can be called for a
// PrerenderHandle that is already cancelled (and thus detached). In that
// case, we should not detach the PrerenderHandle again.
- if (!prerender_)
- return;
- prerender_->Abandon();
- Detach();
+ Dispose();
}
-void PrerenderHandle::Detach() {
- prerender_->Dispose();
- prerender_.Clear();
+void PrerenderHandle::OnPrerenderStart() {
+ if (client_)
+ client_->DidStartPrerender();
+}
+
+void PrerenderHandle::OnPrerenderStopLoading() {
+ if (client_)
+ client_->DidSendLoadForPrerender();
}
-void PrerenderHandle::Trace(blink::Visitor* visitor) {
- visitor->Trace(prerender_);
- ContextLifecycleObserver::Trace(visitor);
+void PrerenderHandle::OnPrerenderDomContentLoaded() {
+ if (client_)
+ client_->DidSendDOMContentLoadedForPrerender();
+}
+
+void PrerenderHandle::OnPrerenderStop() {
+ if (client_)
+ client_->DidStopPrerender();
+}
+
+void PrerenderHandle::Trace(Visitor* visitor) {
+ visitor->Trace(client_);
+ ExecutionContextLifecycleObserver::Trace(visitor);
+}
+
+void PrerenderHandle::Detach() {
+ remote_handle_.reset();
+ receiver_.reset();
}
} // namespace blink
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 b9d4a97460a..18df853e178 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
@@ -33,18 +33,21 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "base/util/type_safety/pass_key.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/blink/public/mojom/prerender/prerender.mojom-blink.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
namespace blink {
class Document;
-class Prerender;
class PrerenderClient;
class PrerenderHandle final : public GarbageCollected<PrerenderHandle>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver,
+ public mojom::blink::PrerenderHandleClient {
USING_GARBAGE_COLLECTED_MIXIN(PrerenderHandle);
USING_PRE_FINALIZER(PrerenderHandle, Dispose);
@@ -54,22 +57,37 @@ class PrerenderHandle final : public GarbageCollected<PrerenderHandle>,
const KURL&,
unsigned prerender_rel_types);
- PrerenderHandle(Document&, Prerender*);
- virtual ~PrerenderHandle();
+ using PassKey = util::PassKey<PrerenderHandle>;
+ PrerenderHandle(PassKey,
+ Document&,
+ PrerenderClient*,
+ const KURL&,
+ mojo::Remote<mojom::blink::PrerenderHandle>,
+ mojo::PendingReceiver<mojom::blink::PrerenderHandleClient>);
+ ~PrerenderHandle() override;
void Dispose();
void Cancel();
const KURL& Url() const;
- // ContextLifecycleObserver:
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver:
+ void ContextDestroyed() override;
- void Trace(blink::Visitor*) override;
+ // mojom::blink::PrerenderHandleClient:
+ void OnPrerenderStart() override;
+ void OnPrerenderStopLoading() override;
+ void OnPrerenderDomContentLoaded() override;
+ void OnPrerenderStop() override;
+
+ void Trace(Visitor*) override;
private:
void Detach();
- Member<Prerender> prerender_;
+ KURL url_;
+ WeakMember<PrerenderClient> client_;
+ mojo::Remote<mojom::blink::PrerenderHandle> remote_handle_;
+ mojo::Receiver<mojom::blink::PrerenderHandleClient> receiver_;
DISALLOW_COPY_AND_ASSIGN(PrerenderHandle);
};
diff --git a/chromium/third_party/blink/renderer/core/loader/programmatic_scroll_test.cc b/chromium/third_party/blink/renderer/core/loader/programmatic_scroll_test.cc
index 9d1f678ddff..cdc86f8057a 100644
--- a/chromium/third_party/blink/renderer/core/loader/programmatic_scroll_test.cc
+++ b/chromium/third_party/blink/renderer/core/loader/programmatic_scroll_test.cc
@@ -3,7 +3,7 @@
// found in the LICENSE file.
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/web_input_event.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
#include "third_party/blink/public/web/web_frame.h"
#include "third_party/blink/public/web/web_history_item.h"
@@ -52,7 +52,7 @@ TEST_F(ProgrammaticScrollTest, RestoreScrollPositionAndViewStateWithScale) {
web_view_helper.InitializeAndLoad(base_url_.Utf8() + "long_scroll.html");
web_view->MainFrameWidget()->Resize(WebSize(1000, 1000));
web_view->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
FrameLoader& loader = web_view->MainFrameImpl()->GetFrame()->Loader();
loader.GetDocumentLoader()->SetLoadType(WebFrameLoadType::kBackForward);
@@ -71,6 +71,8 @@ TEST_F(ProgrammaticScrollTest, RestoreScrollPositionAndViewStateWithScale) {
loader.GetDocumentLoader()->GetInitialScrollState().was_scrolled_by_user =
false;
loader.RestoreScrollPositionAndViewState();
+ web_view->MainFrameWidget()->UpdateAllLifecyclePhases(
+ DocumentUpdateReason::kTest);
// Expect that both scroll and scale were restored.
EXPECT_EQ(2.0f, web_view->PageScaleFactor());
@@ -85,7 +87,7 @@ TEST_F(ProgrammaticScrollTest, RestoreScrollPositionAndViewStateWithoutScale) {
web_view_helper.InitializeAndLoad(base_url_.Utf8() + "long_scroll.html");
web_view->MainFrameWidget()->Resize(WebSize(1000, 1000));
web_view->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
FrameLoader& loader = web_view->MainFrameImpl()->GetFrame()->Loader();
loader.GetDocumentLoader()->SetLoadType(WebFrameLoadType::kBackForward);
@@ -101,6 +103,8 @@ TEST_F(ProgrammaticScrollTest, RestoreScrollPositionAndViewStateWithoutScale) {
// FrameLoader::restoreScrollPositionAndViewState flows differently if scale
// is zero.
loader.RestoreScrollPositionAndViewState();
+ web_view->MainFrameWidget()->UpdateAllLifecyclePhases(
+ DocumentUpdateReason::kTest);
// Expect that only the scroll position was restored.
EXPECT_EQ(3.0f, web_view->PageScaleFactor());
@@ -115,7 +119,7 @@ TEST_F(ProgrammaticScrollTest, SaveScrollStateClearsAnchor) {
web_view_helper.InitializeAndLoad(base_url_.Utf8() + "long_scroll.html");
web_view->MainFrameWidget()->Resize(WebSize(1000, 1000));
web_view->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
FrameLoader& loader = web_view->MainFrameImpl()->GetFrame()->Loader();
loader.GetDocumentLoader()->SetLoadType(WebFrameLoadType::kBackForward);
@@ -166,11 +170,11 @@ TEST_F(ProgrammaticScrollSimTest, NavigateToHash) {
)HTML");
main_resource.Finish();
css_resource.Complete();
- Compositor().BeginFrame();
// Run pending tasks to fire the load event and close the document. This
// should cause the document to scroll to the hash.
test::RunPendingTasks();
+ Compositor().BeginFrame();
ScrollableArea* layout_viewport = GetDocument().View()->LayoutViewport();
EXPECT_EQ(3000, layout_viewport->GetScrollOffset().Height());
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 daa9acd81f6..13bf10794fe 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(blink::Visitor* visitor) {
+void ProgressTracker::Trace(Visitor* visitor) {
visitor->Trace(frame_);
}
@@ -112,6 +112,7 @@ void ProgressTracker::ProgressCompleted() {
SendFinalProgress();
Reset();
GetLocalFrameClient()->DidStopLoading();
+ frame_->UpdateFaviconURL();
probe::FrameStoppedLoading(frame_);
}
@@ -129,7 +130,7 @@ void ProgressTracker::SendFinalProgress() {
if (progress_value_ == 1)
return;
progress_value_ = 1;
- GetLocalFrameClient()->ProgressEstimateChanged(progress_value_);
+ frame_->GetLocalFrameHostRemote().DidChangeLoadProgress(progress_value_);
}
void ProgressTracker::WillStartLoading(uint64_t identifier,
@@ -223,7 +224,7 @@ void ProgressTracker::MaybeSendProgress() {
progress_value_ - last_notified_progress_value_;
if (notification_progress_delta >= kProgressNotificationInterval ||
notified_progress_time_delta >= kProgressNotificationTimeInterval) {
- GetLocalFrameClient()->ProgressEstimateChanged(progress_value_);
+ frame_->GetLocalFrameHostRemote().DidChangeLoadProgress(progress_value_);
last_notified_progress_value_ = progress_value_;
last_notified_progress_time_ = now;
}
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 36e97827799..09d9b696b02 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(blink::Visitor*);
+ void Trace(Visitor*);
void Dispose();
double EstimatedProgress() const;
diff --git a/chromium/third_party/blink/renderer/core/loader/progress_tracker_test.cc b/chromium/third_party/blink/renderer/core/loader/progress_tracker_test.cc
index cb9ca792929..34d8a7086e6 100644
--- a/chromium/third_party/blink/renderer/core/loader/progress_tracker_test.cc
+++ b/chromium/third_party/blink/renderer/core/loader/progress_tracker_test.cc
@@ -4,42 +4,49 @@
#include "third_party/blink/renderer/core/loader/progress_tracker.h"
+#include "base/auto_reset.h"
+#include "base/run_loop.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/settings.h"
-#include "third_party/blink/renderer/core/loader/empty_clients.h"
-#include "third_party/blink/renderer/core/testing/page_test_base.h"
+#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
+#include "third_party/blink/renderer/core/testing/fake_local_frame_host.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
+#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
namespace blink {
-class ProgressClient : public EmptyLocalFrameClient {
+class ProgressTrackerTest : public testing::Test, public FakeLocalFrameHost {
public:
- ProgressClient() : last_progress_(0.0) {}
-
- void ProgressEstimateChanged(double progress_estimate) override {
- last_progress_ = progress_estimate;
- }
-
- double LastProgress() const { return last_progress_; }
-
- private:
- double last_progress_;
-};
-
-class ProgressTrackerTest : public PageTestBase {
- public:
- ProgressTrackerTest() : response_(KURL("http://example.com")) {
+ ProgressTrackerTest()
+ : response_(KURL("http://example.com")), last_progress_(0.0) {
response_.SetMimeType("text/html");
response_.SetExpectedContentLength(1024);
}
void SetUp() override {
- client_ = MakeGarbageCollected<ProgressClient>();
- PageTestBase::SetupPageWithClients(nullptr, client_.Get());
+ FakeLocalFrameHost::Init(
+ web_frame_client_.GetRemoteNavigationAssociatedInterfaces());
+ web_view_helper_.Initialize(&web_frame_client_);
}
- ProgressTracker& Progress() const { return GetFrame().Loader().Progress(); }
- double LastProgress() const { return client_->LastProgress(); }
+ void TearDown() override {
+ // The WebViewHelper will crash when being reset if the TestWebFrameClient
+ // is still reporting that some loads are in progress, so let's make sure
+ // that's not the case via a call to ProgressTracker::ProgressCompleted().
+ if (web_frame_client_.IsLoading())
+ Progress().ProgressCompleted();
+ web_view_helper_.Reset();
+ }
+
+ LocalFrame* GetFrame() const {
+ return web_view_helper_.GetWebView()->MainFrameImpl()->GetFrame();
+ }
+
+ ProgressTracker& Progress() const { return GetFrame()->Loader().Progress(); }
+
+ double LastProgress() const { return last_progress_; }
+
const ResourceResponse& ResponseHeaders() const { return response_; }
// Reports a 1024-byte "main resource" (VeryHigh priority) request/response
@@ -53,16 +60,32 @@ class ProgressTrackerTest : public PageTestBase {
EXPECT_EQ(0.0, LastProgress());
}
+ double WaitForNextProgressChange() const {
+ base::RunLoop run_loop;
+ base::AutoReset<base::RunLoop*> current_loop(&current_run_loop_, &run_loop);
+ run_loop.Run();
+ return last_progress_;
+ }
+
+ // FakeLocalFrameHost:
+ void DidChangeLoadProgress(double progress) override {
+ last_progress_ = progress;
+ current_run_loop_->Quit();
+ }
+
private:
- Persistent<ProgressClient> client_;
+ mutable base::RunLoop* current_run_loop_ = nullptr;
+ frame_test_helpers::TestWebFrameClient web_frame_client_;
+ frame_test_helpers::WebViewHelper web_view_helper_;
ResourceResponse response_;
+ double last_progress_;
};
TEST_F(ProgressTrackerTest, Static) {
Progress().ProgressStarted();
EXPECT_EQ(0.0, LastProgress());
Progress().ProgressCompleted();
- EXPECT_EQ(1.0, LastProgress());
+ EXPECT_EQ(1.0, WaitForNextProgressChange());
}
TEST_F(ProgressTrackerTest, MainResourceOnly) {
@@ -70,15 +93,17 @@ TEST_F(ProgressTrackerTest, MainResourceOnly) {
// .2 for committing, .25 out of .5 possible for bytes received.
Progress().IncrementProgress(1ul, 512);
- EXPECT_EQ(0.45, LastProgress());
+ EXPECT_EQ(0.45, WaitForNextProgressChange());
// .2 for committing, .5 for all bytes received.
Progress().CompleteProgress(1ul);
- EXPECT_EQ(0.7, LastProgress());
+ EXPECT_EQ(0.7, WaitForNextProgressChange());
Progress().FinishedParsing();
+ EXPECT_EQ(0.8, WaitForNextProgressChange());
+
Progress().DidFirstContentfulPaint();
- EXPECT_EQ(1.0, LastProgress());
+ EXPECT_EQ(1.0, WaitForNextProgressChange());
}
TEST_F(ProgressTrackerTest, WithHighPriorirySubresource) {
@@ -91,16 +116,18 @@ TEST_F(ProgressTrackerTest, WithHighPriorirySubresource) {
// .2 for committing, .25 out of .5 possible for bytes received.
Progress().IncrementProgress(1ul, 1024);
Progress().CompleteProgress(1ul);
- EXPECT_EQ(0.45, LastProgress());
+ EXPECT_EQ(0.45, WaitForNextProgressChange());
// .4 for finishing parsing/painting,
// .25 out of .5 possible for bytes received.
Progress().FinishedParsing();
+ EXPECT_EQ(0.55, WaitForNextProgressChange());
+
Progress().DidFirstContentfulPaint();
- EXPECT_EQ(0.65, LastProgress());
+ EXPECT_EQ(0.65, WaitForNextProgressChange());
Progress().CompleteProgress(2ul);
- EXPECT_EQ(1.0, LastProgress());
+ EXPECT_EQ(1.0, WaitForNextProgressChange());
}
TEST_F(ProgressTrackerTest, WithMediumPrioritySubresource) {
@@ -113,11 +140,13 @@ TEST_F(ProgressTrackerTest, WithMediumPrioritySubresource) {
// .2 for committing, .5 for all bytes received.
// Medium priority resource is ignored.
Progress().CompleteProgress(1ul);
- EXPECT_EQ(0.7, LastProgress());
+ EXPECT_EQ(0.7, WaitForNextProgressChange());
Progress().FinishedParsing();
+ EXPECT_EQ(0.8, WaitForNextProgressChange());
+
Progress().DidFirstContentfulPaint();
- EXPECT_EQ(1.0, LastProgress());
+ EXPECT_EQ(1.0, WaitForNextProgressChange());
}
TEST_F(ProgressTrackerTest, FinishParsingBeforeContentfulPaint) {
@@ -125,13 +154,13 @@ TEST_F(ProgressTrackerTest, FinishParsingBeforeContentfulPaint) {
// .2 for committing, .5 for all bytes received.
Progress().CompleteProgress(1ul);
- EXPECT_EQ(0.7, LastProgress());
+ EXPECT_EQ(0.7, WaitForNextProgressChange());
Progress().FinishedParsing();
- EXPECT_EQ(0.8, LastProgress());
+ EXPECT_EQ(0.8, WaitForNextProgressChange());
Progress().DidFirstContentfulPaint();
- EXPECT_EQ(1.0, LastProgress());
+ EXPECT_EQ(1.0, WaitForNextProgressChange());
}
TEST_F(ProgressTrackerTest, ContentfulPaintBeforeFinishParsing) {
@@ -139,13 +168,13 @@ TEST_F(ProgressTrackerTest, ContentfulPaintBeforeFinishParsing) {
// .2 for committing, .5 for all bytes received.
Progress().CompleteProgress(1ul);
- EXPECT_EQ(0.7, LastProgress());
+ EXPECT_EQ(0.7, WaitForNextProgressChange());
Progress().DidFirstContentfulPaint();
- EXPECT_EQ(0.8, LastProgress());
+ EXPECT_EQ(0.8, WaitForNextProgressChange());
Progress().FinishedParsing();
- EXPECT_EQ(1.0, LastProgress());
+ EXPECT_EQ(1.0, WaitForNextProgressChange());
}
} // namespace blink
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 79733761842..9a89f9b5747 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
@@ -47,6 +47,7 @@ CSSStyleSheetResource* CSSStyleSheetResource::Fetch(FetchParameters& params,
ResourceFetcher* fetcher,
ResourceClient* client) {
params.SetRequestContext(mojom::RequestContextType::STYLE);
+ params.SetRequestDestination(network::mojom::RequestDestination::kStyle);
CSSStyleSheetResource* resource = ToCSSStyleSheetResource(
fetcher->RequestResource(params, CSSStyleSheetResourceFactory(), client));
return resource;
@@ -87,7 +88,7 @@ void CSSStyleSheetResource::SetParsedStyleSheetCache(
UpdateDecodedSize();
}
-void CSSStyleSheetResource::Trace(blink::Visitor* visitor) {
+void CSSStyleSheetResource::Trace(Visitor* visitor) {
visitor->Trace(parsed_style_sheet_cache_);
TextResource::Trace(visitor);
}
@@ -206,9 +207,9 @@ bool CSSStyleSheetResource::CanUseSheet(const CSSParserContext* parser_context,
return true;
AtomicString content_type = HttpContentType();
return content_type.IsEmpty() ||
- DeprecatedEqualIgnoringCase(content_type, "text/css") ||
- DeprecatedEqualIgnoringCase(content_type,
- "application/x-unknown-content-type");
+ EqualIgnoringASCIICase(content_type, "text/css") ||
+ EqualIgnoringASCIICase(content_type,
+ "application/x-unknown-content-type");
}
StyleSheetContents* CSSStyleSheetResource::CreateParsedStyleSheetFromCache(
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 0253711b206..c863f63f94b 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void OnMemoryDump(WebMemoryDumpLevelOfDetail,
WebProcessMemoryDump*) const override;
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/document_resource.cc b/chromium/third_party/blink/renderer/core/loader/resource/document_resource.cc
index b1d14480dcf..ea05b85bb25 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource/document_resource.cc
+++ b/chromium/third_party/blink/renderer/core/loader/resource/document_resource.cc
@@ -34,14 +34,20 @@
namespace blink {
-DocumentResource* DocumentResource::FetchSVGDocument(FetchParameters& params,
- ResourceFetcher* fetcher,
- ResourceClient* client) {
+DocumentResource* DocumentResource::FetchSVGDocument(
+ FetchParameters& params,
+ const Document& context_document,
+ ResourceClient* client) {
DCHECK_EQ(params.GetResourceRequest().GetMode(),
network::mojom::RequestMode::kSameOrigin);
params.SetRequestContext(mojom::RequestContextType::IMAGE);
- return ToDocumentResource(
- fetcher->RequestResource(params, SVGDocumentResourceFactory(), client));
+ params.SetRequestDestination(network::mojom::RequestDestination::kImage);
+ auto* resource =
+ To<DocumentResource>(context_document.Fetcher()->RequestResource(
+ params, SVGDocumentResourceFactory(), client));
+ if (!resource->document_ && !resource->context_document_)
+ resource->context_document_ = const_cast<Document*>(&context_document);
+ return resource;
}
DocumentResource::DocumentResource(
@@ -56,8 +62,9 @@ DocumentResource::DocumentResource(
DocumentResource::~DocumentResource() = default;
-void DocumentResource::Trace(blink::Visitor* visitor) {
+void DocumentResource::Trace(Visitor* visitor) {
visitor->Trace(document_);
+ visitor->Trace(context_document_);
Resource::Trace(visitor);
}
@@ -83,7 +90,9 @@ bool DocumentResource::MimeTypeAllowed() const {
Document* DocumentResource::CreateDocument(const KURL& url) {
switch (GetType()) {
case ResourceType::kSVGDocument:
- return XMLDocument::CreateSVG(DocumentInit::Create().WithURL(url));
+ return XMLDocument::CreateSVG(
+ DocumentInit::Create().WithURL(url).WithContextDocument(
+ context_document_));
default:
// FIXME: We'll add more types to support HTMLImports.
NOTREACHED();
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/document_resource.h b/chromium/third_party/blink/renderer/core/loader/resource/document_resource.h
index bee1015ed8f..a468525c68f 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource/document_resource.h
+++ b/chromium/third_party/blink/renderer/core/loader/resource/document_resource.h
@@ -29,17 +29,17 @@
#include "third_party/blink/renderer/platform/loader/fetch/resource.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_client.h"
#include "third_party/blink/renderer/platform/loader/fetch/text_resource_decoder_options.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
class Document;
class FetchParameters;
-class ResourceFetcher;
class CORE_EXPORT DocumentResource final : public TextResource {
public:
static DocumentResource* FetchSVGDocument(FetchParameters&,
- ResourceFetcher*,
+ const Document& context_document,
ResourceClient*);
DocumentResource(const ResourceRequest&,
@@ -47,7 +47,7 @@ class CORE_EXPORT DocumentResource final : public TextResource {
const ResourceLoaderOptions&,
const TextResourceDecoderOptions&);
~DocumentResource() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
Document* GetDocument() const { return document_.Get(); }
@@ -73,13 +73,15 @@ class CORE_EXPORT DocumentResource final : public TextResource {
Document* CreateDocument(const KURL&);
Member<Document> document_;
+ WeakMember<Document> context_document_;
};
-DEFINE_TYPE_CASTS(DocumentResource,
- Resource,
- resource,
- resource->GetType() == ResourceType::kSVGDocument,
- resource.GetType() == ResourceType::kSVGDocument);
+template <>
+struct DowncastTraits<DocumentResource> {
+ static bool AllowFrom(const Resource& resource) {
+ return resource.GetType() == ResourceType::kSVGDocument;
+ }
+};
} // namespace blink
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 e5bc075c229..794161c5fa6 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
@@ -26,11 +26,11 @@
#include "third_party/blink/renderer/core/loader/resource/font_resource.h"
+#include "base/metrics/histogram_functions.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/public/mojom/loader/request_context_frame_type.mojom-blink.h"
#include "third_party/blink/renderer/platform/fonts/font_custom_platform_data.h"
#include "third_party/blink/renderer/platform/fonts/font_platform_data.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_client_walker.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
@@ -49,39 +49,11 @@ constexpr base::TimeDelta kFontLoadWaitShort =
constexpr base::TimeDelta kFontLoadWaitLong =
base::TimeDelta::FromMilliseconds(3000);
-enum FontPackageFormat {
- kPackageFormatUnknown,
- kPackageFormatSFNT,
- kPackageFormatWOFF,
- kPackageFormatWOFF2,
- kPackageFormatSVG,
- kPackageFormatEnumMax
-};
-
-static FontPackageFormat PackageFormatOf(SharedBuffer* buffer) {
- static constexpr size_t kMaxHeaderSize = 4;
- char data[kMaxHeaderSize];
- if (!buffer->GetBytes(data, kMaxHeaderSize))
- return kPackageFormatUnknown;
-
- if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == 'F')
- return kPackageFormatWOFF;
- if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == '2')
- return kPackageFormatWOFF2;
- return kPackageFormatSFNT;
-}
-
-static void RecordPackageFormatHistogram(FontPackageFormat format) {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- EnumerationHistogram, package_format_histogram,
- ("WebFont.PackageFormat", kPackageFormatEnumMax));
- package_format_histogram.Count(format);
-}
-
FontResource* FontResource::Fetch(FetchParameters& params,
ResourceFetcher* fetcher,
FontResourceClient* client) {
params.SetRequestContext(mojom::RequestContextType::FONT);
+ params.SetRequestDestination(network::mojom::RequestDestination::kFont);
return ToFontResource(
fetcher->RequestResource(params, FontResourceFactory(), client));
}
@@ -89,7 +61,7 @@ FontResource* FontResource::Fetch(FetchParameters& params,
FontResource::FontResource(const ResourceRequest& resource_request,
const ResourceLoaderOptions& options)
: Resource(resource_request, ResourceType::kFont, options),
- load_limit_state_(kLoadNotStarted),
+ load_limit_state_(LoadLimitState::kLoadNotStarted),
cors_failed_(false) {}
FontResource::~FontResource() = default;
@@ -103,30 +75,30 @@ void FontResource::DidAddClient(ResourceClient* c) {
return;
ProhibitAddRemoveClientInScope prohibit_add_remove_client(this);
- if (load_limit_state_ == kShortLimitExceeded ||
- load_limit_state_ == kLongLimitExceeded)
+ if (load_limit_state_ == LoadLimitState::kShortLimitExceeded ||
+ load_limit_state_ == LoadLimitState::kLongLimitExceeded)
static_cast<FontResourceClient*>(c)->FontLoadShortLimitExceeded(this);
- if (load_limit_state_ == kLongLimitExceeded)
+ if (load_limit_state_ == LoadLimitState::kLongLimitExceeded)
static_cast<FontResourceClient*>(c)->FontLoadLongLimitExceeded(this);
}
-void FontResource::SetRevalidatingRequest(const ResourceRequest& request) {
+void FontResource::SetRevalidatingRequest(const ResourceRequestHead& request) {
// Reload will use the same object, and needs to reset |m_loadLimitState|
// before any didAddClient() is called again.
DCHECK(IsLoaded());
DCHECK(!font_load_short_limit_.IsActive());
DCHECK(!font_load_long_limit_.IsActive());
- load_limit_state_ = kLoadNotStarted;
+ load_limit_state_ = LoadLimitState::kLoadNotStarted;
Resource::SetRevalidatingRequest(request);
}
void FontResource::StartLoadLimitTimersIfNecessary(
base::SingleThreadTaskRunner* task_runner) {
- if (!IsLoading() || load_limit_state_ != kLoadNotStarted)
+ if (!IsLoading() || load_limit_state_ != LoadLimitState::kLoadNotStarted)
return;
DCHECK(!font_load_short_limit_.IsActive());
DCHECK(!font_load_long_limit_.IsActive());
- load_limit_state_ = kUnderLimit;
+ load_limit_state_ = LoadLimitState::kUnderLimit;
font_load_short_limit_ = PostDelayedCancellableTask(
*task_runner, FROM_HERE,
@@ -145,12 +117,8 @@ scoped_refptr<FontCustomPlatformData> FontResource::GetCustomFontData() {
if (Data())
font_data_ = FontCustomPlatformData::Create(Data(), ots_parsing_message_);
- if (font_data_) {
- RecordPackageFormatHistogram(PackageFormatOf(Data()));
- } else {
+ if (!font_data_)
SetStatus(ResourceStatus::kDecodeError);
- RecordPackageFormatHistogram(kPackageFormatUnknown);
- }
}
return font_data_;
}
@@ -158,23 +126,21 @@ scoped_refptr<FontCustomPlatformData> FontResource::GetCustomFontData() {
void FontResource::WillReloadAfterDiskCacheMiss() {
DCHECK(IsLoading());
DCHECK(Loader()->IsCacheAwareLoadingActivated());
- if (load_limit_state_ == kShortLimitExceeded ||
- load_limit_state_ == kLongLimitExceeded) {
+ if (load_limit_state_ == LoadLimitState::kShortLimitExceeded ||
+ load_limit_state_ == LoadLimitState::kLongLimitExceeded) {
NotifyClientsShortLimitExceeded();
}
- if (load_limit_state_ == kLongLimitExceeded)
+ if (load_limit_state_ == LoadLimitState::kLongLimitExceeded)
NotifyClientsLongLimitExceeded();
- DEFINE_STATIC_LOCAL(
- EnumerationHistogram, load_limit_histogram,
- ("WebFont.LoadLimitOnDiskCacheMiss", kLoadLimitStateEnumMax));
- load_limit_histogram.Count(load_limit_state_);
+ base::UmaHistogramEnumeration("WebFont.LoadLimitOnDiskCacheMiss",
+ load_limit_state_);
}
void FontResource::FontLoadShortLimitCallback() {
DCHECK(IsLoading());
- DCHECK_EQ(load_limit_state_, kUnderLimit);
- load_limit_state_ = kShortLimitExceeded;
+ DCHECK_EQ(load_limit_state_, LoadLimitState::kUnderLimit);
+ load_limit_state_ = LoadLimitState::kShortLimitExceeded;
// Block client callbacks if currently loading from cache.
if (Loader()->IsCacheAwareLoadingActivated())
@@ -184,8 +150,8 @@ void FontResource::FontLoadShortLimitCallback() {
void FontResource::FontLoadLongLimitCallback() {
DCHECK(IsLoading());
- DCHECK_EQ(load_limit_state_, kShortLimitExceeded);
- load_limit_state_ = kLongLimitExceeded;
+ DCHECK_EQ(load_limit_state_, LoadLimitState::kShortLimitExceeded);
+ load_limit_state_ = LoadLimitState::kLongLimitExceeded;
// Block client callbacks if currently loading from cache.
if (Loader()->IsCacheAwareLoadingActivated())
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 d07e8567953..d31b28d8ba3 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
@@ -53,7 +53,7 @@ class CORE_EXPORT FontResource final : public Resource {
void DidAddClient(ResourceClient*) override;
- void SetRevalidatingRequest(const ResourceRequest&) override;
+ void SetRevalidatingRequest(const ResourceRequestHead&) override;
void AllClientsAndObserversRemoved() override;
void StartLoadLimitTimersIfNecessary(base::SingleThreadTaskRunner*);
@@ -90,12 +90,12 @@ class CORE_EXPORT FontResource final : public Resource {
void NotifyClientsLongLimitExceeded();
// This is used in UMA histograms, should not change order.
- enum LoadLimitState {
+ enum class LoadLimitState {
kLoadNotStarted,
kUnderLimit,
kShortLimitExceeded,
kLongLimitExceeded,
- kLoadLimitStateEnumMax
+ kMaxValue = kLongLimitExceeded,
};
scoped_refptr<FontCustomPlatformData> font_data_;
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/font_resource_test.cc b/chromium/third_party/blink/renderer/core/loader/resource/font_resource_test.cc
index 7a5e062b7f7..d67532f2701 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource/font_resource_test.cc
+++ b/chromium/third_party/blink/renderer/core/loader/resource/font_resource_test.cc
@@ -71,7 +71,7 @@ TEST_F(FontResourceTest,
// Fetch to cache a resource.
ResourceRequest request1(url);
- FetchParameters fetch_params1(request1);
+ FetchParameters fetch_params1(std::move(request1));
Resource* resource1 = FontResource::Fetch(fetch_params1, fetcher, nullptr);
ASSERT_FALSE(resource1->ErrorOccurred());
fetcher->StartLoad(resource1);
@@ -85,7 +85,7 @@ TEST_F(FontResourceTest,
// Revalidate the resource.
ResourceRequest request2(url);
request2.SetCacheMode(mojom::FetchCacheMode::kValidateCache);
- FetchParameters fetch_params2(request2);
+ FetchParameters fetch_params2(std::move(request2));
Resource* resource2 = FontResource::Fetch(fetch_params2, fetcher, nullptr);
ASSERT_FALSE(resource2->ErrorOccurred());
EXPECT_EQ(resource1, resource2);
@@ -95,7 +95,7 @@ TEST_F(FontResourceTest,
// Fetch the same resource again before actual load operation starts.
ResourceRequest request3(url);
request3.SetCacheMode(mojom::FetchCacheMode::kValidateCache);
- FetchParameters fetch_params3(request3);
+ FetchParameters fetch_params3(std::move(request3));
Resource* resource3 = FontResource::Fetch(fetch_params3, fetcher, nullptr);
ASSERT_FALSE(resource3->ErrorOccurred());
EXPECT_EQ(resource2, resource3);
@@ -130,7 +130,7 @@ TEST_F(CacheAwareFontResourceTest, CacheAwareFontLoading) {
CSSFontFaceSrcValue* src_value = CSSFontFaceSrcValue::Create(
url.GetString(), url.GetString(),
Referrer(document.Url(), document.GetReferrerPolicy()),
- kDoNotCheckContentSecurityPolicy, OriginClean::kTrue);
+ network::mojom::CSPDisposition::DO_NOT_CHECK, OriginClean::kTrue);
// Route font requests in this test through CSSFontFaceSrcValue::Fetch
// instead of calling FontResource::Fetch directly. CSSFontFaceSrcValue
@@ -140,11 +140,12 @@ TEST_F(CacheAwareFontResourceTest, CacheAwareFontLoading) {
// a "cache hit" in ResourceFetcher's view.
Persistent<MockFontResourceClient> client =
MakeGarbageCollected<MockFontResourceClient>();
- FontResource& resource = src_value->Fetch(&document, client);
+ FontResource& resource =
+ src_value->Fetch(document.ToExecutionContext(), client);
fetcher->StartLoad(&resource);
EXPECT_TRUE(resource.Loader()->IsCacheAwareLoadingActivated());
- resource.load_limit_state_ = FontResource::kUnderLimit;
+ resource.load_limit_state_ = FontResource::LoadLimitState::kUnderLimit;
// FontResource callbacks should be blocked during cache-aware loading.
resource.FontLoadShortLimitCallback();
@@ -162,7 +163,8 @@ TEST_F(CacheAwareFontResourceTest, CacheAwareFontLoading) {
// Add client now, FontLoadShortLimitExceeded() should be called.
Persistent<MockFontResourceClient> client2 =
MakeGarbageCollected<MockFontResourceClient>();
- FontResource& resource2 = src_value->Fetch(&document, client2);
+ FontResource& resource2 =
+ src_value->Fetch(document.ToExecutionContext(), client2);
EXPECT_EQ(&resource, &resource2);
EXPECT_TRUE(client2->FontLoadShortLimitExceededCalled());
EXPECT_FALSE(client2->FontLoadLongLimitExceededCalled());
@@ -174,7 +176,8 @@ TEST_F(CacheAwareFontResourceTest, CacheAwareFontLoading) {
// Add client now, both callbacks should be called.
Persistent<MockFontResourceClient> client3 =
MakeGarbageCollected<MockFontResourceClient>();
- FontResource& resource3 = src_value->Fetch(&document, client3);
+ FontResource& resource3 =
+ src_value->Fetch(document.ToExecutionContext(), client3);
EXPECT_EQ(&resource, &resource3);
EXPECT_TRUE(client3->FontLoadShortLimitExceededCalled());
EXPECT_TRUE(client3->FontLoadLongLimitExceededCalled());
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 47f73bf1fb4..eefacdf9ba1 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
@@ -28,12 +28,12 @@
#include <memory>
#include <utility>
+#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/core/loader/resource/image_resource_content.h"
#include "third_party/blink/renderer/core/loader/resource/image_resource_info.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/instance_counters.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h"
@@ -49,7 +49,8 @@
#include "third_party/blink/renderer/platform/network/network_utils.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_violation_reporting_policy.h"
+#include "third_party/blink/renderer/platform/weborigin/reporting_disposition.h"
+#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
@@ -77,7 +78,7 @@ class ImageResource::ImageResourceInfoImpl final
: resource_(resource) {
DCHECK(resource_);
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(resource_);
ImageResourceInfo::Trace(visitor);
}
@@ -133,7 +134,8 @@ class ImageResource::ImageResourceInfoImpl final
const KURL& url,
const AtomicString& initiator_name) override {
fetcher->EmulateLoadStartedForInspector(
- resource_.Get(), url, mojom::RequestContextType::IMAGE, initiator_name);
+ resource_.Get(), url, mojom::RequestContextType::IMAGE,
+ network::mojom::RequestDestination::kImage, initiator_name);
}
void LoadDeferredImage(ResourceFetcher* fetcher) override {
@@ -144,6 +146,10 @@ class ImageResource::ImageResourceInfoImpl final
}
}
+ bool IsAdResource() const override {
+ return resource_->GetResourceRequest().IsAdResource();
+ }
+
const Member<ImageResource> resource_;
};
@@ -173,6 +179,7 @@ ImageResource* ImageResource::Fetch(FetchParameters& params,
if (params.GetResourceRequest().GetRequestContext() ==
mojom::RequestContextType::UNSPECIFIED) {
params.SetRequestContext(mojom::RequestContextType::IMAGE);
+ params.SetRequestDestination(network::mojom::RequestDestination::kImage);
}
ImageResource* resource = ToImageResource(
@@ -218,6 +225,13 @@ ImageResource* ImageResource::Create(const ResourceRequest& request) {
ImageResource* ImageResource::CreateForTest(const KURL& url) {
ResourceRequest request(url);
request.SetInspectorId(CreateUniqueIdentifier());
+ // These are needed because some unittests don't go through the usual
+ // request setting path in ResourceFetcher.
+ request.SetRequestorOrigin(SecurityOrigin::CreateUniqueOpaque());
+ request.SetReferrerPolicy(
+ ReferrerPolicyResolveDefault(request.GetReferrerPolicy()));
+ request.SetPriority(WebURLRequest::Priority::kLow);
+
return Create(request);
}
@@ -254,7 +268,7 @@ void ImageResource::OnMemoryDump(WebMemoryDumpLevelOfDetail level_of_detail,
dump->AddScalar("size", "bytes", content_->GetImage()->Data()->size());
}
-void ImageResource::Trace(blink::Visitor* visitor) {
+void ImageResource::Trace(Visitor* visitor) {
visitor->Trace(multipart_parser_);
visitor->Trace(content_);
Resource::Trace(visitor);
@@ -564,10 +578,10 @@ void ImageResource::ReloadIfLoFiOrPlaceholderImage(
SetPreviewsState(previews_state_for_reload);
- if (placeholder_option_ != PlaceholderOption::kDoNotReloadPlaceholder)
+ if (placeholder_option_ != PlaceholderOption::kDoNotReloadPlaceholder) {
ClearRangeRequestHeader();
-
placeholder_option_ = PlaceholderOption::kDoNotReloadPlaceholder;
+ }
if (IsLoading()) {
Loader()->Cancel();
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 e25bcdec228..129be3d3b19 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
@@ -110,7 +110,7 @@ class CORE_EXPORT ImageResource final
void OnMemoryDump(WebMemoryDumpLevelOfDetail,
WebProcessMemoryDump*) const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 6247d3f5e82..854baaa5e41 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
@@ -6,9 +6,10 @@
#include <memory>
+#include "base/metrics/histogram_macros.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink.h"
#include "third_party/blink/public/mojom/feature_policy/policy_value.mojom-blink.h"
-#include "third_party/blink/renderer/core/execution_context/security_context.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/loader/resource/image_resource.h"
#include "third_party/blink/renderer/core/loader/resource/image_resource_info.h"
#include "third_party/blink/renderer/core/loader/resource/image_resource_observer.h"
@@ -16,7 +17,6 @@
#include "third_party/blink/renderer/platform/geometry/int_size.h"
#include "third_party/blink/renderer/platform/graphics/bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/placeholder_image.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/network/http_parsers.h"
#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
@@ -37,9 +37,7 @@ class NullImageResourceInfo final
public:
NullImageResourceInfo() = default;
- void Trace(blink::Visitor* visitor) override {
- ImageResourceInfo::Trace(visitor);
- }
+ void Trace(Visitor* visitor) override { ImageResourceInfo::Trace(visitor); }
private:
const KURL& Url() const override { return url_; }
@@ -71,6 +69,8 @@ class NullImageResourceInfo final
void LoadDeferredImage(ResourceFetcher* fetcher) override {}
+ bool IsAdResource() const override { return false; }
+
const KURL url_;
const ResourceResponse response_;
};
@@ -143,7 +143,7 @@ void ImageResourceContent::SetImageResourceInfo(ImageResourceInfo* info) {
info_ = info;
}
-void ImageResourceContent::Trace(blink::Visitor* visitor) {
+void ImageResourceContent::Trace(Visitor* visitor) {
visitor->Trace(info_);
ImageObserver::Trace(visitor);
}
@@ -195,7 +195,8 @@ void ImageResourceContent::RemoveObserver(ImageResourceObserver* observer) {
auto it = observers_.find(observer);
bool fully_erased;
if (it != observers_.end()) {
- fully_erased = observers_.erase(it);
+ fully_erased = observers_.erase(it) && finished_observers_.find(observer) ==
+ finished_observers_.end();
} else {
it = finished_observers_.find(observer);
DCHECK(it != finished_observers_.end());
@@ -265,10 +266,7 @@ IntSize ImageResourceContent::IntrinsicSize(
RespectImageOrientationEnum should_respect_image_orientation) const {
if (!image_)
return IntSize();
- if (should_respect_image_orientation == kRespectImageOrientation &&
- image_->IsBitmapImage())
- return ToBitmapImage(image_.get())->SizeRespectingOrientation();
- return image_->Size();
+ return image_->Size(should_respect_image_orientation);
}
void ImageResourceContent::NotifyObservers(
@@ -471,7 +469,7 @@ ImageResourceContent::UpdateImageResult ImageResourceContent::UpdateImage(
// consider such an image as DecodeError.
// https://www.w3.org/TR/SVG/struct.html#SVGElementWidthAttribute
if (!image_ ||
- (image_->IsNull() && (!image_->IsSVGImage() ||
+ (image_->IsNull() && (!IsA<SVGImage>(image_.get()) ||
size_available_ == Image::kSizeUnavailable))) {
ClearImage();
return UpdateImageResult::kShouldDecodeError;
@@ -513,11 +511,11 @@ ImageDecoder::CompressionFormat ImageResourceContent::GetCompressionFormat()
}
bool ImageResourceContent::IsAcceptableCompressionRatio(
- const SecurityContext& context) {
+ ExecutionContext& context) {
if (!image_)
return true;
- uint64_t pixels = IntrinsicSize(kDoNotRespectImageOrientation).Area();
+ uint64_t pixels = image_->Size().Area();
if (!pixels)
return true;
@@ -535,22 +533,6 @@ bool ImageResourceContent::IsAcceptableCompressionRatio(
double compression_ratio_10k = (resource_length - 10240) / pixels;
ImageDecoder::CompressionFormat compression_format = GetCompressionFormat();
- const auto max_value =
- PolicyValue::CreateMaxPolicyValue(mojom::PolicyValueType::kDecDouble);
- // If an unoptimized-*-images policy is specified, the specified compression
- // ratio will be less than the max value.
- bool is_policy_specified =
- !context.IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kUnoptimizedLossyImages, max_value) ||
- !context.IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kUnoptimizedLosslessImagesStrict,
- max_value) ||
- !context.IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kUnoptimizedLosslessImages, max_value);
- if (is_policy_specified) {
- UMA_HISTOGRAM_ENUMERATION("Blink.UseCounter.FeaturePolicy.ImageFormats",
- compression_format);
- }
// Pass image url to reporting API.
const String& image_url = Url().GetString();
@@ -558,18 +540,18 @@ bool ImageResourceContent::IsAcceptableCompressionRatio(
if (compression_format == ImageDecoder::kLossyFormat) {
// Enforce the lossy image policy.
return context.IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kUnoptimizedLossyImages,
+ mojom::blink::DocumentPolicyFeature::kUnoptimizedLossyImages,
PolicyValue(compression_ratio_1k), ReportOptions::kReportOnFailure,
g_empty_string, image_url);
}
if (compression_format == ImageDecoder::kLosslessFormat) {
// Enforce the lossless image policy.
bool enabled_by_10k_policy = context.IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kUnoptimizedLosslessImages,
+ mojom::blink::DocumentPolicyFeature::kUnoptimizedLosslessImages,
PolicyValue(compression_ratio_10k), ReportOptions::kReportOnFailure,
g_empty_string, image_url);
bool enabled_by_1k_policy = context.IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kUnoptimizedLosslessImagesStrict,
+ mojom::blink::DocumentPolicyFeature::kUnoptimizedLosslessImagesStrict,
PolicyValue(compression_ratio_1k), ReportOptions::kReportOnFailure,
g_empty_string, image_url);
return enabled_by_10k_policy && enabled_by_1k_policy;
@@ -705,4 +687,8 @@ void ImageResourceContent::LoadDeferredImage(ResourceFetcher* fetcher) {
info_->LoadDeferredImage(fetcher);
}
+bool ImageResourceContent::IsAdResource() const {
+ return info_->IsAdResource();
+}
+
} // namespace blink
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 21d16460d63..9e9fe6c6d22 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
@@ -23,13 +23,13 @@
namespace blink {
+class ExecutionContext;
class FetchParameters;
class ImageResourceInfo;
class ImageResourceObserver;
class ResourceError;
class ResourceFetcher;
class ResourceResponse;
-class SecurityContext;
// ImageResourceContent is a container that holds fetch result of
// an ImageResource in a decoded form.
@@ -86,7 +86,7 @@ class CORE_EXPORT ImageResourceContent final
return size_available_ != Image::kSizeUnavailable;
}
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// Content status and deriving predicates.
// https://docs.google.com/document/d/1O-fB83mrE0B_V8gzXNqHgmRLCvstTB4MMi3RnVLr8bE/edit#heading=h.6cyqmir0f30h
@@ -182,10 +182,13 @@ class CORE_EXPORT ImageResourceContent final
// extraneous metadata). "well-compressed" is determined by comparing the
// image's compression ratio against a specific value that is defined by an
// unoptimized image feature policy on |context|.
- bool IsAcceptableCompressionRatio(const SecurityContext& context);
+ bool IsAcceptableCompressionRatio(ExecutionContext& context);
void LoadDeferredImage(ResourceFetcher* fetcher);
+ // Returns whether the resource request has been tagged as an ad.
+ bool IsAdResource() const;
+
private:
using CanDeferInvalidation = ImageResourceObserver::CanDeferInvalidation;
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 1a8a9ec6c3c..f459616c35e 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
@@ -60,7 +60,9 @@ class CORE_EXPORT ImageResourceInfo : public GarbageCollectedMixin {
virtual void LoadDeferredImage(ResourceFetcher* fetcher) = 0;
- void Trace(blink::Visitor* visitor) override {}
+ virtual bool IsAdResource() const = 0;
+
+ void Trace(Visitor* visitor) 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 5bab2d34365..5abd3cc3903 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
@@ -40,7 +40,9 @@
#include "third_party/blink/public/platform/web_url_response.h"
#include "third_party/blink/renderer/core/loader/empty_clients.h"
#include "third_party/blink/renderer/core/loader/resource/mock_image_resource_observer.h"
+#include "third_party/blink/renderer/core/svg/graphics/svg_image.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
+#include "third_party/blink/renderer/core/testing/scoped_mock_overlay_scrollbars.h"
#include "third_party/blink/renderer/platform/exported/wrapped_resource_response.h"
#include "third_party/blink/renderer/platform/graphics/bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
@@ -66,6 +68,7 @@
#include "third_party/blink/renderer/platform/testing/scoped_mocked_url.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
#include "third_party/blink/renderer/platform/wtf/text/base64.h"
@@ -111,17 +114,20 @@ constexpr size_t kJpegImageSubrangeWithDimensionsLength =
sizeof(kJpegImage) - 1;
constexpr size_t kJpegImageSubrangeWithoutDimensionsLength = 3;
+class ImageResourceTest : public testing::Test,
+ private ScopedMockOverlayScrollbars {};
+
// Ensure that the image decoder can determine the dimensions of kJpegImage from
// just the first kJpegImageSubrangeWithDimensionsLength bytes. If this test
// fails, then the test data here probably needs to be updated.
-TEST(ImageResourceTest, DimensionsDecodableFromPartialTestImage) {
+TEST_F(ImageResourceTest, DimensionsDecodableFromPartialTestImage) {
scoped_refptr<Image> image = BitmapImage::Create();
EXPECT_EQ(
Image::kSizeAvailable,
image->SetData(SharedBuffer::Create(
kJpegImage, kJpegImageSubrangeWithDimensionsLength),
true));
- EXPECT_TRUE(image->IsBitmapImage());
+ EXPECT_TRUE(IsA<BitmapImage>(image.get()));
EXPECT_EQ(1, image->width());
EXPECT_EQ(1, image->height());
}
@@ -308,8 +314,8 @@ void TestThatIsPlaceholderRequestAndServeResponse(
// A placeholder image.
EXPECT_TRUE(image_resource->ShouldShowPlaceholder());
- EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsBitmapImage());
- EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsSVGImage());
+ EXPECT_FALSE(IsA<BitmapImage>(image_resource->GetContent()->GetImage()));
+ EXPECT_FALSE(IsA<SVGImage>(image_resource->GetContent()->GetImage()));
}
void TestThatIsNotPlaceholderRequestAndServeResponse(
@@ -350,8 +356,8 @@ void TestThatIsNotPlaceholderRequestAndServeResponse(
// A non-placeholder bitmap image.
EXPECT_FALSE(image_resource->ShouldShowPlaceholder());
- EXPECT_TRUE(image_resource->GetContent()->GetImage()->IsBitmapImage());
- EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsSVGImage());
+ EXPECT_TRUE(IsA<BitmapImage>(image_resource->GetContent()->GetImage()));
+ EXPECT_FALSE(IsA<SVGImage>(image_resource->GetContent()->GetImage()));
}
ResourceFetcher* CreateFetcher() {
@@ -362,7 +368,7 @@ ResourceFetcher* CreateFetcher() {
MakeGarbageCollected<TestLoaderFactory>()));
}
-TEST(ImageResourceTest, MultipartImage) {
+TEST_F(ImageResourceTest, MultipartImage) {
ResourceFetcher* fetcher = CreateFetcher();
KURL test_url(kTestURL);
ScopedMockedURLLoad scoped_mocked_url_load(test_url, GetTestFilePath());
@@ -437,7 +443,7 @@ TEST(ImageResourceTest, MultipartImage) {
EXPECT_EQ(kJpegImageWidth, image_resource->GetContent()->GetImage()->width());
EXPECT_EQ(kJpegImageHeight,
image_resource->GetContent()->GetImage()->height());
- EXPECT_TRUE(image_resource->GetContent()->GetImage()->IsSVGImage());
+ EXPECT_TRUE(IsA<SVGImage>(image_resource->GetContent()->GetImage()));
EXPECT_TRUE(image_resource->GetContent()
->GetImage()
->PaintImageForCurrentFrame()
@@ -449,12 +455,16 @@ TEST(ImageResourceTest, MultipartImage) {
EXPECT_TRUE(observer2->ImageNotifyFinishedCalled());
}
-TEST(ImageResourceTest, BitmapMultipartImage) {
+TEST_F(ImageResourceTest, BitmapMultipartImage) {
ResourceFetcher* fetcher = CreateFetcher();
KURL test_url(kTestURL);
ScopedMockedURLLoad scoped_mocked_url_load(test_url, GetTestFilePath());
ResourceRequest resource_request(test_url);
resource_request.SetInspectorId(CreateUniqueIdentifier());
+ resource_request.SetRequestorOrigin(SecurityOrigin::CreateUniqueOpaque());
+ resource_request.SetReferrerPolicy(
+ ReferrerPolicyResolveDefault(resource_request.GetReferrerPolicy()));
+ resource_request.SetPriority(WebURLRequest::Priority::kLow);
ImageResource* image_resource = ImageResource::Create(resource_request);
fetcher->StartLoad(image_resource);
@@ -475,14 +485,14 @@ TEST(ImageResourceTest, BitmapMultipartImage) {
image_resource->AppendData(kBoundary, strlen(kBoundary));
image_resource->Loader()->DidFinishLoading(base::TimeTicks(), 0, 0, 0, false);
EXPECT_TRUE(image_resource->GetContent()->HasImage());
- EXPECT_TRUE(image_resource->GetContent()->GetImage()->IsBitmapImage());
+ EXPECT_TRUE(IsA<BitmapImage>(image_resource->GetContent()->GetImage()));
EXPECT_TRUE(image_resource->GetContent()
->GetImage()
->PaintImageForCurrentFrame()
.is_multipart());
}
-TEST(ImageResourceTest, CancelOnRemoveObserver) {
+TEST_F(ImageResourceTest, CancelOnRemoveObserver) {
KURL test_url(kTestURL);
ScopedMockedURLLoad scoped_mocked_url_load(test_url, GetTestFilePath());
@@ -514,20 +524,15 @@ TEST(ImageResourceTest, CancelOnRemoveObserver) {
EXPECT_FALSE(GetMemoryCache()->ResourceForURL(test_url));
}
-class MockFinishObserver : public GarbageCollected<MockFinishObserver>,
- public ResourceFinishObserver {
- USING_GARBAGE_COLLECTED_MIXIN(MockFinishObserver);
-
+class MockFinishObserver : public ResourceFinishObserver {
public:
static MockFinishObserver* Create() {
- return
-
- MakeGarbageCollected<testing::StrictMock<MockFinishObserver>>();
+ return MakeGarbageCollected<testing::StrictMock<MockFinishObserver>>();
}
MOCK_METHOD0(NotifyFinished, void());
String DebugName() const override { return "MockFinishObserver"; }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
blink::ResourceFinishObserver::Trace(visitor);
}
@@ -535,7 +540,7 @@ class MockFinishObserver : public GarbageCollected<MockFinishObserver>,
MockFinishObserver() = default;
};
-TEST(ImageResourceTest, CancelWithImageAndFinishObserver) {
+TEST_F(ImageResourceTest, CancelWithImageAndFinishObserver) {
KURL test_url(kTestURL);
ScopedMockedURLLoad scoped_mocked_url_load(test_url, GetTestFilePath());
@@ -572,7 +577,7 @@ TEST(ImageResourceTest, CancelWithImageAndFinishObserver) {
blink::test::RunPendingTasks();
}
-TEST(ImageResourceTest, DecodedDataRemainsWhileHasClients) {
+TEST_F(ImageResourceTest, DecodedDataRemainsWhileHasClients) {
ImageResource* image_resource = ImageResource::CreateForTest(NullURL());
image_resource->NotifyStartLoad();
@@ -614,7 +619,7 @@ TEST(ImageResourceTest, DecodedDataRemainsWhileHasClients) {
// data.
}
-TEST(ImageResourceTest, UpdateBitmapImages) {
+TEST_F(ImageResourceTest, UpdateBitmapImages) {
ImageResource* image_resource = ImageResource::CreateForTest(NullURL());
image_resource->NotifyStartLoad();
@@ -635,10 +640,13 @@ TEST(ImageResourceTest, UpdateBitmapImages) {
EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsNull());
EXPECT_EQ(2, observer->ImageChangedCount());
EXPECT_TRUE(observer->ImageNotifyFinishedCalled());
- EXPECT_TRUE(image_resource->GetContent()->GetImage()->IsBitmapImage());
+ EXPECT_TRUE(IsA<BitmapImage>(image_resource->GetContent()->GetImage()));
}
-TEST(ImageResourceReloadTest, ReloadIfLoFiOrPlaceholderForPlaceholder) {
+class ImageResourceReloadTest : public testing::Test,
+ private ScopedMockOverlayScrollbars {};
+
+TEST_F(ImageResourceReloadTest, ReloadIfLoFiOrPlaceholderForPlaceholder) {
KURL test_url(kTestURL);
ScopedMockedURLLoad scoped_mocked_url_load(test_url, GetTestFilePath());
@@ -662,7 +670,7 @@ TEST(ImageResourceReloadTest, ReloadIfLoFiOrPlaceholderForPlaceholder) {
observer.get(), false);
}
-TEST(ImageResourceTest, SVGImage) {
+TEST_F(ImageResourceTest, SVGImage) {
KURL url("http://127.0.0.1:8000/foo");
ImageResource* image_resource = ImageResource::CreateForTest(url);
auto observer =
@@ -676,10 +684,10 @@ TEST(ImageResourceTest, SVGImage) {
EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsNull());
EXPECT_EQ(1, observer->ImageChangedCount());
EXPECT_TRUE(observer->ImageNotifyFinishedCalled());
- EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsBitmapImage());
+ EXPECT_FALSE(IsA<BitmapImage>(image_resource->GetContent()->GetImage()));
}
-TEST(ImageResourceTest, SVGImageWithSubresource) {
+TEST_F(ImageResourceTest, SVGImageWithSubresource) {
KURL url("http://127.0.0.1:8000/foo");
ImageResource* image_resource = ImageResource::CreateForTest(url);
auto observer =
@@ -691,7 +699,7 @@ TEST(ImageResourceTest, SVGImageWithSubresource) {
EXPECT_FALSE(image_resource->ErrorOccurred());
ASSERT_TRUE(image_resource->GetContent()->HasImage());
EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsNull());
- EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsBitmapImage());
+ EXPECT_FALSE(IsA<BitmapImage>(image_resource->GetContent()->GetImage()));
// At this point, image is (mostly) available but the loading is not yet
// finished because of SVG's subresources, and thus ImageChanged() or
@@ -724,7 +732,7 @@ TEST(ImageResourceTest, SVGImageWithSubresource) {
GetMemoryCache()->EvictResources();
}
-TEST(ImageResourceTest, SuccessfulRevalidationJpeg) {
+TEST_F(ImageResourceTest, SuccessfulRevalidationJpeg) {
KURL url("http://127.0.0.1:8000/foo");
ImageResource* image_resource = ImageResource::CreateForTest(url);
auto observer =
@@ -739,7 +747,7 @@ TEST(ImageResourceTest, SuccessfulRevalidationJpeg) {
EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsNull());
EXPECT_EQ(2, observer->ImageChangedCount());
EXPECT_TRUE(observer->ImageNotifyFinishedCalled());
- EXPECT_TRUE(image_resource->GetContent()->GetImage()->IsBitmapImage());
+ EXPECT_TRUE(IsA<BitmapImage>(image_resource->GetContent()->GetImage()));
EXPECT_EQ(kJpegImageWidth, image_resource->GetContent()->GetImage()->width());
EXPECT_EQ(kJpegImageHeight,
image_resource->GetContent()->GetImage()->height());
@@ -755,13 +763,13 @@ TEST(ImageResourceTest, SuccessfulRevalidationJpeg) {
EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsNull());
EXPECT_EQ(2, observer->ImageChangedCount());
EXPECT_TRUE(observer->ImageNotifyFinishedCalled());
- EXPECT_TRUE(image_resource->GetContent()->GetImage()->IsBitmapImage());
+ EXPECT_TRUE(IsA<BitmapImage>(image_resource->GetContent()->GetImage()));
EXPECT_EQ(kJpegImageWidth, image_resource->GetContent()->GetImage()->width());
EXPECT_EQ(kJpegImageHeight,
image_resource->GetContent()->GetImage()->height());
}
-TEST(ImageResourceTest, SuccessfulRevalidationSvg) {
+TEST_F(ImageResourceTest, SuccessfulRevalidationSvg) {
KURL url("http://127.0.0.1:8000/foo");
ImageResource* image_resource = ImageResource::CreateForTest(url);
auto observer =
@@ -775,7 +783,7 @@ TEST(ImageResourceTest, SuccessfulRevalidationSvg) {
EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsNull());
EXPECT_EQ(1, observer->ImageChangedCount());
EXPECT_TRUE(observer->ImageNotifyFinishedCalled());
- EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsBitmapImage());
+ EXPECT_FALSE(IsA<BitmapImage>(image_resource->GetContent()->GetImage()));
EXPECT_EQ(200, image_resource->GetContent()->GetImage()->width());
EXPECT_EQ(200, image_resource->GetContent()->GetImage()->height());
@@ -789,12 +797,12 @@ TEST(ImageResourceTest, SuccessfulRevalidationSvg) {
EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsNull());
EXPECT_EQ(1, observer->ImageChangedCount());
EXPECT_TRUE(observer->ImageNotifyFinishedCalled());
- EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsBitmapImage());
+ EXPECT_FALSE(IsA<BitmapImage>(image_resource->GetContent()->GetImage()));
EXPECT_EQ(200, image_resource->GetContent()->GetImage()->width());
EXPECT_EQ(200, image_resource->GetContent()->GetImage()->height());
}
-TEST(ImageResourceTest, FailedRevalidationJpegToJpeg) {
+TEST_F(ImageResourceTest, FailedRevalidationJpegToJpeg) {
KURL url("http://127.0.0.1:8000/foo");
ImageResource* image_resource = ImageResource::CreateForTest(url);
auto observer =
@@ -809,7 +817,7 @@ TEST(ImageResourceTest, FailedRevalidationJpegToJpeg) {
EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsNull());
EXPECT_EQ(2, observer->ImageChangedCount());
EXPECT_TRUE(observer->ImageNotifyFinishedCalled());
- EXPECT_TRUE(image_resource->GetContent()->GetImage()->IsBitmapImage());
+ EXPECT_TRUE(IsA<BitmapImage>(image_resource->GetContent()->GetImage()));
EXPECT_EQ(kJpegImageWidth, image_resource->GetContent()->GetImage()->width());
EXPECT_EQ(kJpegImageHeight,
image_resource->GetContent()->GetImage()->height());
@@ -824,12 +832,12 @@ TEST(ImageResourceTest, FailedRevalidationJpegToJpeg) {
EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsNull());
EXPECT_EQ(4, observer->ImageChangedCount());
EXPECT_TRUE(observer->ImageNotifyFinishedCalled());
- EXPECT_TRUE(image_resource->GetContent()->GetImage()->IsBitmapImage());
+ EXPECT_TRUE(IsA<BitmapImage>(image_resource->GetContent()->GetImage()));
EXPECT_EQ(50, image_resource->GetContent()->GetImage()->width());
EXPECT_EQ(50, image_resource->GetContent()->GetImage()->height());
}
-TEST(ImageResourceTest, FailedRevalidationJpegToSvg) {
+TEST_F(ImageResourceTest, FailedRevalidationJpegToSvg) {
KURL url("http://127.0.0.1:8000/foo");
ImageResource* image_resource = ImageResource::CreateForTest(url);
auto observer =
@@ -844,7 +852,7 @@ TEST(ImageResourceTest, FailedRevalidationJpegToSvg) {
EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsNull());
EXPECT_EQ(2, observer->ImageChangedCount());
EXPECT_TRUE(observer->ImageNotifyFinishedCalled());
- EXPECT_TRUE(image_resource->GetContent()->GetImage()->IsBitmapImage());
+ EXPECT_TRUE(IsA<BitmapImage>(image_resource->GetContent()->GetImage()));
EXPECT_EQ(kJpegImageWidth, image_resource->GetContent()->GetImage()->width());
EXPECT_EQ(kJpegImageHeight,
image_resource->GetContent()->GetImage()->height());
@@ -858,12 +866,12 @@ TEST(ImageResourceTest, FailedRevalidationJpegToSvg) {
EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsNull());
EXPECT_EQ(3, observer->ImageChangedCount());
EXPECT_TRUE(observer->ImageNotifyFinishedCalled());
- EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsBitmapImage());
+ EXPECT_FALSE(IsA<BitmapImage>(image_resource->GetContent()->GetImage()));
EXPECT_EQ(200, image_resource->GetContent()->GetImage()->width());
EXPECT_EQ(200, image_resource->GetContent()->GetImage()->height());
}
-TEST(ImageResourceTest, FailedRevalidationSvgToJpeg) {
+TEST_F(ImageResourceTest, FailedRevalidationSvgToJpeg) {
KURL url("http://127.0.0.1:8000/foo");
ImageResource* image_resource = ImageResource::CreateForTest(url);
auto observer =
@@ -877,7 +885,7 @@ TEST(ImageResourceTest, FailedRevalidationSvgToJpeg) {
EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsNull());
EXPECT_EQ(1, observer->ImageChangedCount());
EXPECT_TRUE(observer->ImageNotifyFinishedCalled());
- EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsBitmapImage());
+ EXPECT_FALSE(IsA<BitmapImage>(image_resource->GetContent()->GetImage()));
EXPECT_EQ(200, image_resource->GetContent()->GetImage()->width());
EXPECT_EQ(200, image_resource->GetContent()->GetImage()->height());
@@ -891,13 +899,13 @@ TEST(ImageResourceTest, FailedRevalidationSvgToJpeg) {
EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsNull());
EXPECT_EQ(3, observer->ImageChangedCount());
EXPECT_TRUE(observer->ImageNotifyFinishedCalled());
- EXPECT_TRUE(image_resource->GetContent()->GetImage()->IsBitmapImage());
+ EXPECT_TRUE(IsA<BitmapImage>(image_resource->GetContent()->GetImage()));
EXPECT_EQ(kJpegImageWidth, image_resource->GetContent()->GetImage()->width());
EXPECT_EQ(kJpegImageHeight,
image_resource->GetContent()->GetImage()->height());
}
-TEST(ImageResourceTest, FailedRevalidationSvgToSvg) {
+TEST_F(ImageResourceTest, FailedRevalidationSvgToSvg) {
KURL url("http://127.0.0.1:8000/foo");
ImageResource* image_resource = ImageResource::CreateForTest(url);
auto observer =
@@ -911,7 +919,7 @@ TEST(ImageResourceTest, FailedRevalidationSvgToSvg) {
EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsNull());
EXPECT_EQ(1, observer->ImageChangedCount());
EXPECT_TRUE(observer->ImageNotifyFinishedCalled());
- EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsBitmapImage());
+ EXPECT_FALSE(IsA<BitmapImage>(image_resource->GetContent()->GetImage()));
EXPECT_EQ(200, image_resource->GetContent()->GetImage()->width());
EXPECT_EQ(200, image_resource->GetContent()->GetImage()->height());
@@ -924,14 +932,14 @@ TEST(ImageResourceTest, FailedRevalidationSvgToSvg) {
EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsNull());
EXPECT_EQ(2, observer->ImageChangedCount());
EXPECT_TRUE(observer->ImageNotifyFinishedCalled());
- EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsBitmapImage());
+ EXPECT_FALSE(IsA<BitmapImage>(image_resource->GetContent()->GetImage()));
EXPECT_EQ(300, image_resource->GetContent()->GetImage()->width());
EXPECT_EQ(300, image_resource->GetContent()->GetImage()->height());
}
// Tests for pruning.
-TEST(ImageResourceTest, Prune) {
+TEST_F(ImageResourceTest, Prune) {
KURL url("http://127.0.0.1:8000/foo");
ImageResource* image_resource = ImageResource::CreateForTest(url);
@@ -960,7 +968,7 @@ TEST(ImageResourceTest, Prune) {
image_resource->GetContent()->GetImage()->height());
}
-TEST(ImageResourceTest, CancelOnDecodeError) {
+TEST_F(ImageResourceTest, CancelOnDecodeError) {
KURL test_url(kTestURL);
ScopedMockedURLLoad scoped_mocked_url_load(test_url, GetTestFilePath());
@@ -988,7 +996,7 @@ TEST(ImageResourceTest, CancelOnDecodeError) {
EXPECT_FALSE(image_resource->IsLoading());
}
-TEST(ImageResourceTest, DecodeErrorWithEmptyBody) {
+TEST_F(ImageResourceTest, DecodeErrorWithEmptyBody) {
KURL test_url(kTestURL);
ScopedMockedURLLoad scoped_mocked_url_load(test_url, GetTestFilePath());
@@ -1019,13 +1027,13 @@ TEST(ImageResourceTest, DecodeErrorWithEmptyBody) {
// Testing DecodeError that occurs in didFinishLoading().
// This is similar to DecodeErrorWithEmptyBody, but with non-empty body.
-TEST(ImageResourceTest, PartialContentWithoutDimensions) {
+TEST_F(ImageResourceTest, PartialContentWithoutDimensions) {
KURL test_url(kTestURL);
ScopedMockedURLLoad scoped_mocked_url_load(test_url, GetTestFilePath());
ResourceRequest resource_request(test_url);
resource_request.SetHttpHeaderField("range", "bytes=0-2");
- FetchParameters params(resource_request);
+ FetchParameters params(std::move(resource_request));
ResourceFetcher* fetcher = CreateFetcher();
ImageResource* image_resource = ImageResource::Fetch(params, fetcher);
auto observer =
@@ -1064,7 +1072,7 @@ TEST(ImageResourceTest, PartialContentWithoutDimensions) {
EXPECT_FALSE(image_resource->IsLoading());
}
-TEST(ImageResourceTest, FetchDisallowPlaceholder) {
+TEST_F(ImageResourceTest, FetchDisallowPlaceholder) {
KURL test_url(kTestURL);
ScopedMockedURLLoad scoped_mocked_url_load(test_url, GetTestFilePath());
@@ -1078,7 +1086,7 @@ TEST(ImageResourceTest, FetchDisallowPlaceholder) {
observer.get());
}
-TEST(ImageResourceTest, FetchAllowPlaceholderDataURL) {
+TEST_F(ImageResourceTest, FetchAllowPlaceholderDataURL) {
KURL test_url("data:image/jpeg;base64," + Base64Encode(kJpegImage));
FetchParameters params{ResourceRequest(test_url)};
params.SetAllowImagePlaceholder();
@@ -1089,12 +1097,12 @@ TEST(ImageResourceTest, FetchAllowPlaceholderDataURL) {
EXPECT_FALSE(image_resource->ShouldShowPlaceholder());
}
-TEST(ImageResourceTest, FetchAllowPlaceholderPostRequest) {
+TEST_F(ImageResourceTest, FetchAllowPlaceholderPostRequest) {
KURL test_url(kTestURL);
ScopedMockedURLLoad scoped_mocked_url_load(test_url, GetTestFilePath());
ResourceRequest resource_request(test_url);
resource_request.SetHttpMethod(http_names::kPOST);
- FetchParameters params(resource_request);
+ FetchParameters params(std::move(resource_request));
params.SetAllowImagePlaceholder();
ImageResource* image_resource = ImageResource::Fetch(params, CreateFetcher());
EXPECT_EQ(FetchParameters::kNone, params.GetImageRequestOptimization());
@@ -1105,12 +1113,12 @@ TEST(ImageResourceTest, FetchAllowPlaceholderPostRequest) {
image_resource->Loader()->Cancel();
}
-TEST(ImageResourceTest, FetchAllowPlaceholderExistingRangeHeader) {
+TEST_F(ImageResourceTest, FetchAllowPlaceholderExistingRangeHeader) {
KURL test_url(kTestURL);
ScopedMockedURLLoad scoped_mocked_url_load(test_url, GetTestFilePath());
ResourceRequest resource_request(test_url);
resource_request.SetHttpHeaderField("range", "bytes=128-255");
- FetchParameters params(resource_request);
+ FetchParameters params(std::move(resource_request));
params.SetAllowImagePlaceholder();
ImageResource* image_resource = ImageResource::Fetch(params, CreateFetcher());
EXPECT_EQ(FetchParameters::kNone, params.GetImageRequestOptimization());
@@ -1121,7 +1129,7 @@ TEST(ImageResourceTest, FetchAllowPlaceholderExistingRangeHeader) {
image_resource->Loader()->Cancel();
}
-TEST(ImageResourceTest, FetchAllowPlaceholderSuccessful) {
+TEST_F(ImageResourceTest, FetchAllowPlaceholderSuccessful) {
KURL test_url(kTestURL);
ScopedMockedURLLoad scoped_mocked_url_load(test_url, GetTestFilePath());
@@ -1137,7 +1145,7 @@ TEST(ImageResourceTest, FetchAllowPlaceholderSuccessful) {
observer.get());
}
-TEST(ImageResourceTest, FetchAllowPlaceholderUnsuccessful) {
+TEST_F(ImageResourceTest, FetchAllowPlaceholderUnsuccessful) {
KURL test_url(kTestURL);
ScopedMockedURLLoad scoped_mocked_url_load(test_url, GetTestFilePath());
@@ -1179,7 +1187,7 @@ TEST(ImageResourceTest, FetchAllowPlaceholderUnsuccessful) {
observer.get(), false);
}
-TEST(ImageResourceTest, FetchAllowPlaceholderPartialContentWithoutDimensions) {
+TEST_F(ImageResourceTest, FetchAllowPlaceholderPartialContentWithoutDimensions) {
const struct {
WebURLRequest::PreviewsState initial_previews_state;
WebURLRequest::PreviewsState expected_reload_previews_state;
@@ -1196,7 +1204,7 @@ TEST(ImageResourceTest, FetchAllowPlaceholderPartialContentWithoutDimensions) {
ResourceRequest resource_request(test_url);
resource_request.SetPreviewsState(test.initial_previews_state);
- FetchParameters params(resource_request);
+ FetchParameters params(std::move(resource_request));
params.SetAllowImagePlaceholder();
ImageResource* image_resource =
@@ -1246,7 +1254,7 @@ TEST(ImageResourceTest, FetchAllowPlaceholderPartialContentWithoutDimensions) {
}
}
-TEST(ImageResourceTest, FetchAllowPlaceholderThenDisallowPlaceholder) {
+TEST_F(ImageResourceTest, FetchAllowPlaceholderThenDisallowPlaceholder) {
KURL test_url(kTestURL);
ScopedMockedURLLoad scoped_mocked_url_load(test_url, GetTestFilePath());
@@ -1293,10 +1301,10 @@ TEST(ImageResourceTest, FetchAllowPlaceholderThenDisallowPlaceholder) {
// |imageResource2| is still a non-placeholder image.
EXPECT_FALSE(image_resource2->ShouldShowPlaceholder());
- EXPECT_TRUE(image_resource2->GetContent()->GetImage()->IsBitmapImage());
+ EXPECT_TRUE(IsA<BitmapImage>(image_resource2->GetContent()->GetImage()));
}
-TEST(ImageResourceTest,
+TEST_F(ImageResourceTest,
FetchAllowPlaceholderThenDisallowPlaceholderAfterLoaded) {
KURL test_url(kTestURL);
ScopedMockedURLLoad scoped_mocked_url_load(test_url, GetTestFilePath());
@@ -1336,7 +1344,7 @@ TEST(ImageResourceTest,
EXPECT_TRUE(observer3->ImageNotifyFinishedCalled());
}
-TEST(ImageResourceTest, FetchAllowPlaceholderFullResponseDecodeSuccess) {
+TEST_F(ImageResourceTest, FetchAllowPlaceholderFullResponseDecodeSuccess) {
const struct {
int status_code;
AtomicString content_range;
@@ -1388,11 +1396,11 @@ TEST(ImageResourceTest, FetchAllowPlaceholderFullResponseDecodeSuccess) {
image_resource->GetContent()->GetImage()->width());
EXPECT_EQ(kJpegImageHeight,
image_resource->GetContent()->GetImage()->height());
- EXPECT_TRUE(image_resource->GetContent()->GetImage()->IsBitmapImage());
+ EXPECT_TRUE(IsA<BitmapImage>(image_resource->GetContent()->GetImage()));
}
}
-TEST(ImageResourceTest,
+TEST_F(ImageResourceTest,
FetchAllowPlaceholderFullResponseDecodeFailureNoReload) {
static const char kBadImageData[] = "bad image data";
@@ -1437,7 +1445,7 @@ TEST(ImageResourceTest,
}
}
-TEST(ImageResourceTest,
+TEST_F(ImageResourceTest,
FetchAllowPlaceholderFullResponseDecodeFailureWithReload) {
const int kStatusCodes[] = {404, 500};
for (int status_code : kStatusCodes) {
@@ -1477,7 +1485,7 @@ TEST(ImageResourceTest,
}
}
-TEST(ImageResourceTest, PeriodicFlushTest) {
+TEST_F(ImageResourceTest, PeriodicFlushTest) {
ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
platform;
@@ -1583,12 +1591,12 @@ TEST(ImageResourceTest, PeriodicFlushTest) {
EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsNull());
EXPECT_EQ(5, observer->ImageChangedCount());
EXPECT_TRUE(observer->ImageNotifyFinishedCalled());
- EXPECT_TRUE(image_resource->GetContent()->GetImage()->IsBitmapImage());
+ EXPECT_TRUE(IsA<BitmapImage>(image_resource->GetContent()->GetImage()));
EXPECT_EQ(50, image_resource->GetContent()->GetImage()->width());
EXPECT_EQ(50, image_resource->GetContent()->GetImage()->height());
}
-TEST(ImageResourceTest, DeferredInvalidation) {
+TEST_F(ImageResourceTest, DeferredInvalidation) {
ImageResource* image_resource = ImageResource::CreateForTest(NullURL());
std::unique_ptr<MockImageResourceObserver> obs =
std::make_unique<MockImageResourceObserver>(image_resource->GetContent());
@@ -1637,7 +1645,7 @@ constexpr unsigned char kExtendedWebPImage[] = {
0xC8, 0x70, 0x88, 0x0B, 0x6C, 0x54, 0x7A, 0xFB, 0xCA, 0x1D, 0x89, 0x90,
0xDD, 0x27, 0xEA, 0x7F, 0x28, 0x00, 0x00, 0x00};
-TEST(ImageResourceTest, WebPSniffing) {
+TEST_F(ImageResourceTest, WebPSniffing) {
KURL test_url(kTestURL);
// Test lossy WebP image.
@@ -1674,7 +1682,7 @@ class ImageResourceCounterTest : public testing::Test {
ResourceFetcher* fetcher = CreateFetcher();
KURL test_url(url);
ResourceRequest request = ResourceRequest(test_url);
- FetchParameters fetch_params(request);
+ FetchParameters fetch_params(std::move(request));
scheduler::FakeTaskRunner* task_runner =
static_cast<scheduler::FakeTaskRunner*>(fetcher->GetTaskRunner().get());
task_runner->SetTime(1);
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 0e7958d8551..385afece9ba 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(blink::Visitor* visitor) {
+void MultipartImageResourceParser::Trace(Visitor* visitor) {
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 9fc6648bff1..b41f34b18c3 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(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) override {}
};
MultipartImageResourceParser(const ResourceResponse&,
@@ -68,7 +68,7 @@ class CORE_EXPORT MultipartImageResourceParser final
void Finish();
void Cancel() { is_cancelled_ = true; }
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
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 1e8c9059808..a7a69c2617a 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
@@ -58,13 +58,12 @@ namespace {
// defined in the Fetch spec:
// https://fetch.spec.whatwg.org/#request-destination-script-like
bool IsRequestContextSupported(mojom::RequestContextType request_context) {
- // TODO(nhiroki): Support |kRequestContextSharedWorker| for module loading for
- // shared workers (https://crbug.com/824646).
// TODO(nhiroki): Support "audioworklet" and "paintworklet" destinations.
switch (request_context) {
case mojom::RequestContextType::SCRIPT:
case mojom::RequestContextType::WORKER:
case mojom::RequestContextType::SERVICE_WORKER:
+ case mojom::RequestContextType::SHARED_WORKER:
return true;
default:
break;
@@ -140,7 +139,7 @@ void ScriptResource::Prefinalize() {
watcher_.reset();
}
-void ScriptResource::Trace(blink::Visitor* visitor) {
+void ScriptResource::Trace(Visitor* visitor) {
visitor->Trace(streamer_);
visitor->Trace(response_body_loader_client_);
TextResource::Trace(visitor);
@@ -232,7 +231,8 @@ void ScriptResource::DestroyDecodedDataForFailedRevalidation() {
SetDecodedSize(0);
}
-void ScriptResource::SetRevalidatingRequest(const ResourceRequest& request) {
+void ScriptResource::SetRevalidatingRequest(
+ const ResourceRequestHead& request) {
CHECK_EQ(streaming_state_, StreamingState::kFinishedNotificationSent);
if (streamer_) {
CHECK(streamer_->IsStreamingFinished());
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 010d12222b0..791b32f9ac2 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
@@ -93,7 +93,7 @@ class CORE_EXPORT ScriptResource final : public TextResource {
ResponseBodyLoaderDrainableInterface& body_loader,
scoped_refptr<base::SingleThreadTaskRunner> loader_task_runner) override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void OnMemoryDump(WebMemoryDumpLevelOfDetail,
WebProcessMemoryDump*) const override;
@@ -150,7 +150,7 @@ class CORE_EXPORT ScriptResource final : public TextResource {
bool HasFinishedStreamer() { return streamer_ && streamer_->IsFinished(); }
// Visible for tests.
- void SetRevalidatingRequest(const ResourceRequest&) override;
+ void SetRevalidatingRequest(const ResourceRequestHead&) override;
protected:
CachedMetadataHandler* CreateCachedMetadataHandler(
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/xsl_style_sheet_resource.cc b/chromium/third_party/blink/renderer/core/loader/resource/xsl_style_sheet_resource.cc
index ce39f0ac1ad..3620d86eaef 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource/xsl_style_sheet_resource.cc
+++ b/chromium/third_party/blink/renderer/core/loader/resource/xsl_style_sheet_resource.cc
@@ -36,6 +36,7 @@ namespace blink {
static void ApplyXSLRequestProperties(FetchParameters& params) {
params.SetRequestContext(mojom::RequestContextType::XSLT);
+ params.SetRequestDestination(network::mojom::RequestDestination::kXslt);
// TODO(japhet): Accept: headers can be set manually on XHRs from script, in
// the browser process, and... here. The browser process can't tell the
// difference between an XSL stylesheet and a CSS stylesheet, so it assumes
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 01feb648342..6d296c859f8 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
@@ -133,7 +133,7 @@ void ResourceLoadObserverForFrame::DidReceiveResponse(
if (response_source == ResponseSource::kFromMemoryCache) {
frame_client->DispatchDidLoadResourceFromMemoryCache(
- resource->GetResourceRequest(), response);
+ ResourceRequest(resource->GetResourceRequest()), response);
// Note: probe::WillSendRequest needs to precede before this probe method.
probe::MarkResourceAsCached(&frame, &document_loader, identifier);
@@ -172,8 +172,8 @@ void ResourceLoadObserverForFrame::DidReceiveResponse(
response.HttpHeaderField(http_names::kLink), response.CurrentRequestUrl(),
frame, &frame_or_imported_document_->GetDocument(),
resource_loading_policy, PreloadHelper::kLoadAll,
- base::nullopt /* viewport_description */,
- std::move(alternate_resource_info), response.RecursivePrefetchToken());
+ nullptr /* viewport_description */, std::move(alternate_resource_info),
+ base::OptionalOrNullptr(response.RecursivePrefetchToken()));
if (response.HasMajorCertificateErrors()) {
MixedContentChecker::HandleCertificateError(&frame, response,
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 5b9982fb00f..f82f2ffd50d 100644
--- a/chromium/third_party/blink/renderer/core/loader/subresource_filter.cc
+++ b/chromium/third_party/blink/renderer/core/loader/subresource_filter.cc
@@ -13,6 +13,7 @@
#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/core/loader/document_loader.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
@@ -34,14 +35,6 @@ String GetErrorStringForDisallowedLoad(const KURL& url) {
} // namespace
-// static
-SubresourceFilter* SubresourceFilter::Create(
- ExecutionContext& execution_context,
- std::unique_ptr<WebDocumentSubresourceFilter> filter) {
- return MakeGarbageCollected<SubresourceFilter>(&execution_context,
- std::move(filter));
-}
-
SubresourceFilter::SubresourceFilter(
ExecutionContext* execution_context,
std::unique_ptr<WebDocumentSubresourceFilter> subresource_filter)
@@ -50,7 +43,7 @@ SubresourceFilter::SubresourceFilter(
DCHECK(subresource_filter_);
// Report the main resource as an ad if the subresource filter is
// associated with an ad subframe.
- if (auto* document = DynamicTo<Document>(execution_context_.Get())) {
+ if (auto* document = Document::DynamicFrom(execution_context_.Get())) {
auto* loader = document->Loader();
if (document->GetFrame()->IsAdSubframe()) {
ReportAdRequestId(loader->GetResponse().RequestId());
@@ -60,16 +53,15 @@ SubresourceFilter::SubresourceFilter(
SubresourceFilter::~SubresourceFilter() = default;
-bool SubresourceFilter::AllowLoad(
- const KURL& resource_url,
- mojom::RequestContextType request_context,
- SecurityViolationReportingPolicy reporting_policy) {
+bool SubresourceFilter::AllowLoad(const KURL& resource_url,
+ mojom::RequestContextType request_context,
+ ReportingDisposition reporting_disposition) {
// TODO(csharrison): Implement a caching layer here which is a HashMap of
// Pair<url string, context> -> LoadPolicy.
WebDocumentSubresourceFilter::LoadPolicy load_policy =
subresource_filter_->GetLoadPolicy(resource_url, request_context);
- if (reporting_policy == SecurityViolationReportingPolicy::kReport)
+ if (reporting_disposition == ReportingDisposition::kReport)
ReportLoad(resource_url, load_policy);
last_resource_check_result_ = std::make_pair(
@@ -129,17 +121,18 @@ void SubresourceFilter::ReportLoad(
// TODO: Consider logging this as a kIntervention for showing
// warning in Lighthouse.
if (subresource_filter_->ShouldLogToConsole()) {
- execution_context_->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kOther,
- mojom::ConsoleMessageLevel::kError,
- GetErrorStringForDisallowedLoad(resource_url)));
+ execution_context_->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kOther,
+ mojom::ConsoleMessageLevel::kError,
+ GetErrorStringForDisallowedLoad(resource_url)));
}
FALLTHROUGH;
case WebDocumentSubresourceFilter::kWouldDisallow:
// TODO(csharrison): Consider posting a task to the main thread from
// worker thread, or adding support for DidObserveLoadingBehavior to
// ExecutionContext.
- if (auto* document = DynamicTo<Document>(execution_context_.Get())) {
+ if (auto* document = Document::DynamicFrom(execution_context_.Get())) {
if (DocumentLoader* loader = document->Loader()) {
loader->DidObserveLoadingBehavior(
kLoadingBehaviorSubresourceFilterMatch);
@@ -149,7 +142,7 @@ void SubresourceFilter::ReportLoad(
}
}
-void SubresourceFilter::Trace(blink::Visitor* visitor) {
+void SubresourceFilter::Trace(Visitor* visitor) {
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 d8c9a2ce833..4b11327cbe8 100644
--- a/chromium/third_party/blink/renderer/core/loader/subresource_filter.h
+++ b/chromium/third_party/blink/renderer/core/loader/subresource_filter.h
@@ -13,7 +13,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
-#include "third_party/blink/renderer/platform/weborigin/security_violation_reporting_policy.h"
+#include "third_party/blink/renderer/platform/weborigin/reporting_disposition.h"
namespace blink {
@@ -26,17 +26,13 @@ class KURL;
class CORE_EXPORT SubresourceFilter final
: public GarbageCollected<SubresourceFilter> {
public:
- static SubresourceFilter* Create(
- ExecutionContext&,
- std::unique_ptr<WebDocumentSubresourceFilter>);
-
SubresourceFilter(ExecutionContext*,
std::unique_ptr<WebDocumentSubresourceFilter>);
~SubresourceFilter();
bool AllowLoad(const KURL& resource_url,
mojom::RequestContextType,
- SecurityViolationReportingPolicy);
+ ReportingDisposition);
bool AllowWebSocketConnection(const KURL&);
// Returns if |resource_url| is an ad resource.
@@ -44,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(blink::Visitor*);
+ virtual void Trace(Visitor*);
private:
void ReportLoad(const KURL& resource_url,
diff --git a/chromium/third_party/blink/renderer/core/loader/subresource_integrity_helper.cc b/chromium/third_party/blink/renderer/core/loader/subresource_integrity_helper.cc
index 21a2972ae07..56ab9298e38 100644
--- a/chromium/third_party/blink/renderer/core/loader/subresource_integrity_helper.cc
+++ b/chromium/third_party/blink/renderer/core/loader/subresource_integrity_helper.cc
@@ -7,6 +7,7 @@
#include "third_party/blink/public/mojom/devtools/console_message.mojom-blink.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/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -56,9 +57,9 @@ void SubresourceIntegrityHelper::GetConsoleMessages(
HeapVector<Member<ConsoleMessage>>* messages) {
DCHECK(messages);
for (const auto& message : report_info.ConsoleErrorMessages()) {
- messages->push_back(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kError, message));
+ messages->push_back(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kSecurity,
+ mojom::ConsoleMessageLevel::kError, message));
}
}
diff --git a/chromium/third_party/blink/renderer/core/loader/text_resource_decoder_builder.cc b/chromium/third_party/blink/renderer/core/loader/text_resource_decoder_builder.cc
index 861656d8a6c..fb2d66ec459 100644
--- a/chromium/third_party/blink/renderer/core/loader/text_resource_decoder_builder.cc
+++ b/chromium/third_party/blink/renderer/core/loader/text_resource_decoder_builder.cc
@@ -91,9 +91,9 @@ static const WTF::TextEncoding GetEncodingFromDomain(const KURL& url) {
TextResourceDecoderOptions::ContentType DetermineContentType(
const String& mime_type) {
- if (DeprecatedEqualIgnoringCase(mime_type, "text/css"))
+ if (EqualIgnoringASCIICase(mime_type, "text/css"))
return TextResourceDecoderOptions::kCSSContent;
- if (DeprecatedEqualIgnoringCase(mime_type, "text/html"))
+ if (EqualIgnoringASCIICase(mime_type, "text/html"))
return TextResourceDecoderOptions::kHTMLContent;
if (DOMImplementation::IsXMLMIMEType(mime_type))
return TextResourceDecoderOptions::kXMLContent;
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 3fb26f885cd..f932278a1d4 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(blink::Visitor* visitor) {
+void TextTrackLoader::Trace(Visitor* visitor) {
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 2621d7fee27..4338729ca99 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 2370628f300..2eabb5f8cf7 100644
--- a/chromium/third_party/blink/renderer/core/loader/threadable_loader.cc
+++ b/chromium/third_party/blink/renderer/core/loader/threadable_loader.cc
@@ -32,6 +32,7 @@
#include "third_party/blink/renderer/core/loader/threadable_loader.h"
#include <memory>
+
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "services/network/public/cpp/cors/cors_error_status.h"
@@ -56,6 +57,7 @@
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/platform/exported/wrapped_resource_request.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/self_keep_alive.h"
#include "third_party/blink/renderer/platform/loader/cors/cors.h"
#include "third_party/blink/renderer/platform/loader/cors/cors_error_string.h"
@@ -72,6 +74,7 @@
#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
namespace blink {
@@ -230,7 +233,8 @@ ThreadableLoader::ThreadableLoader(
void ThreadableLoader::Start(const ResourceRequest& request) {
original_security_origin_ = security_origin_ = request.RequestorOrigin();
// Setting an outgoing referer is only supported in the async code path.
- DCHECK(async_ || request.HttpReferrer().IsEmpty());
+ DCHECK(async_ ||
+ request.ReferrerString() == Referrer::ClientReferrerString());
bool cors_enabled = cors::IsCorsEnabledRequestMode(request.GetMode());
@@ -273,7 +277,8 @@ void ThreadableLoader::Start(const ResourceRequest& request) {
request_headers_ = request.HttpHeaderFields();
report_upload_progress_ = request.ReportUploadProgress();
- ResourceRequest new_request(request);
+ ResourceRequest new_request;
+ new_request.CopyFrom(request);
// Set the service worker mode to none if "bypass for network" in DevTools is
// enabled.
@@ -318,7 +323,7 @@ void ThreadableLoader::Start(const ResourceRequest& request) {
// Save the request to fallback_request_for_service_worker to use when the
// service worker doesn't handle (call respondWith()) a CORS enabled
// request.
- fallback_request_for_service_worker_ = ResourceRequest(request);
+ fallback_request_for_service_worker_.CopyFrom(request);
// Skip the service worker for the fallback request.
fallback_request_for_service_worker_.SetSkipServiceWorker(true);
}
@@ -355,7 +360,7 @@ void ThreadableLoader::LoadPreflightRequest(
std::unique_ptr<ResourceRequest> preflight_request =
CreateAccessControlPreflightRequest(actual_request, GetSecurityOrigin());
- actual_request_ = actual_request;
+ actual_request_.CopyFrom(actual_request);
actual_options_ = actual_options;
// Explicitly set |skip_service_worker| to true here. Although the page is
@@ -404,7 +409,8 @@ void ThreadableLoader::MakeCrossOriginAccessRequest(
return;
}
- ResourceRequest cross_origin_request(request);
+ ResourceRequest cross_origin_request;
+ cross_origin_request.CopyFrom(request);
ResourceLoaderOptions cross_origin_options(resource_loader_options_);
cross_origin_request.RemoveUserAndPassFromURL();
@@ -569,8 +575,7 @@ bool ThreadableLoader::RedirectReceived(
if (cors_flag_) {
if (const auto error_status = cors::CheckAccess(
- original_url, redirect_response.HttpStatusCode(),
- redirect_response.HttpHeaderFields(),
+ original_url, redirect_response.HttpHeaderFields(),
new_request.GetCredentialsMode(), *GetSecurityOrigin())) {
DispatchDidFail(ResourceError(original_url, *error_status));
return false;
@@ -598,7 +603,7 @@ bool ThreadableLoader::RedirectReceived(
if (redirect_limit_ <= 0) {
ThreadableLoaderClient* client = client_;
Clear();
- ConsoleMessage* message = ConsoleMessage::Create(
+ auto* message = MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kNetwork,
mojom::ConsoleMessageLevel::kError,
"Failed to load resource: net::ERR_TOO_MANY_REDIRECTS",
@@ -672,20 +677,21 @@ bool ThreadableLoader::RedirectReceived(
// Save the referrer to use when following the redirect.
override_referrer_ = true;
- // TODO(domfarolino): Use ReferrerString() once https://crbug.com/850813 is
- // closed and we stop storing the referrer string as a `Referer` header.
referrer_after_redirect_ =
- Referrer(new_request.HttpReferrer(), new_request.GetReferrerPolicy());
+ Referrer(new_request.ReferrerString(), new_request.GetReferrerPolicy());
}
// We're initiating a new request (for redirect), so update
// |last_request_url_| by destroying |assign_on_scope_exit|.
- ResourceRequest cross_origin_request(new_request);
+ 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.
- cross_origin_request.ClearHTTPReferrer();
+ cross_origin_request.SetReferrerString(Referrer::NoReferrer());
+ cross_origin_request.SetReferrerPolicy(
+ network::mojom::ReferrerPolicy::kDefault);
cross_origin_request.ClearHTTPOrigin();
cross_origin_request.ClearHTTPUserAgent();
// Add any request headers which we previously saved from the
@@ -750,14 +756,6 @@ void ThreadableLoader::HandlePreflightResponse(
return;
}
- base::Optional<network::mojom::CorsError> preflight_error =
- cors::CheckPreflight(response.HttpStatusCode());
- if (preflight_error) {
- HandlePreflightFailure(response.CurrentRequestUrl(),
- network::CorsErrorStatus(*preflight_error));
- return;
- }
-
base::Optional<network::CorsErrorStatus> error_status;
if (actual_request_.IsExternalRequest()) {
error_status = cors::CheckExternalPreflight(response.HttpHeaderFields());
@@ -847,7 +845,7 @@ void ThreadableLoader::ResponseReceived(Resource* resource,
// Even if the request met the conditions to get handled by a Service Worker
// in the constructor of this class (and therefore
- // |m_fallbackRequestForServiceWorker| is set), the Service Worker may skip
+ // |fallback_request_for_service_worker_| is set), the Service Worker may skip
// processing the request. Only if the request is same origin, the skipped
// response may come here (wasFetchedViaServiceWorker() returns false) since
// such a request doesn't have to go through the CORS algorithm by calling
@@ -859,8 +857,8 @@ void ThreadableLoader::ResponseReceived(Resource* resource,
if (cors_flag_) {
base::Optional<network::CorsErrorStatus> access_error = cors::CheckAccess(
- response.CurrentRequestUrl(), response.HttpStatusCode(),
- response.HttpHeaderFields(), credentials_mode_, *GetSecurityOrigin());
+ response.CurrentRequestUrl(), response.HttpHeaderFields(),
+ credentials_mode_, *GetSecurityOrigin());
if (access_error) {
ReportResponseReceived(resource->InspectorId(), response);
DispatchDidFail(
@@ -942,12 +940,12 @@ void ThreadableLoader::DidTimeout(TimerBase* timer) {
DCHECK(async_);
DCHECK_EQ(timer, &timeout_timer_);
// clearResource() may be called in clear() and some other places. clear()
- // calls stop() on |m_timeoutTimer|. In the other places, the resource is set
+ // calls stop() on |timeout_|. In the other places, the resource is set
// again. If the creation fails, clear() is called. So, here, resource() is
// always non-nullptr.
DCHECK(GetResource());
- // When |m_client| is set to nullptr only in clear() where |m_timeoutTimer|
- // is stopped. So, |m_client| is always non-nullptr here.
+ // When |client_| is set to nullptr only in clear() where |timeout_|
+ // is stopped. So, |client_| is always non-nullptr here.
DCHECK(client_);
DispatchDidFail(ResourceError::TimeoutError(GetResource()->Url()));
@@ -957,15 +955,17 @@ void ThreadableLoader::LoadFallbackRequestForServiceWorker() {
if (GetResource())
checker_.WillRemoveClient();
ClearResource();
- ResourceRequest fallback_request(fallback_request_for_service_worker_);
- fallback_request_for_service_worker_ = ResourceRequest();
+ ResourceRequest fallback_request;
+ fallback_request.CopyFrom(fallback_request_for_service_worker_);
+ fallback_request_for_service_worker_.CopyFrom(ResourceRequest());
DispatchInitialRequest(fallback_request);
}
void ThreadableLoader::LoadActualRequest() {
- ResourceRequest actual_request = actual_request_;
+ ResourceRequest actual_request;
+ actual_request.CopyFrom(actual_request_);
ResourceLoaderOptions actual_options = actual_options_;
- actual_request_ = ResourceRequest();
+ actual_request_.CopyFrom(ResourceRequest());
actual_options_ = ResourceLoaderOptions();
if (GetResource())
@@ -991,7 +991,7 @@ void ThreadableLoader::DispatchDidFail(const ResourceError& error) {
*error.CorsErrorStatus(), initial_request_url_, last_request_url_,
*GetSecurityOrigin(), ResourceType::kRaw,
resource_loader_options_.initiator_info.name);
- execution_context_->AddConsoleMessage(ConsoleMessage::Create(
+ execution_context_->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kError, std::move(message)));
}
@@ -1043,7 +1043,7 @@ void ThreadableLoader::LoadRequest(
}
}
- FetchParameters new_params(request, resource_loader_options);
+ FetchParameters new_params(std::move(request), resource_loader_options);
DCHECK(!GetResource());
checker_.WillAddClient();
@@ -1070,10 +1070,10 @@ const SecurityOrigin* ThreadableLoader::GetSecurityOrigin() const {
}
Document* ThreadableLoader::GetDocument() const {
- return DynamicTo<Document>(execution_context_.Get());
+ return Document::DynamicFrom(execution_context_.Get());
}
-void ThreadableLoader::Trace(blink::Visitor* visitor) {
+void ThreadableLoader::Trace(Visitor* visitor) {
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 3bc9d5e11c2..79105495732 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(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
class AssignOnScopeExit;
diff --git a/chromium/third_party/blink/renderer/core/loader/threadable_loader_test.cc b/chromium/third_party/blink/renderer/core/loader/threadable_loader_test.cc
index eacb01a2f14..a73c99e7132 100644
--- a/chromium/third_party/blink/renderer/core/loader/threadable_loader_test.cc
+++ b/chromium/third_party/blink/renderer/core/loader/threadable_loader_test.cc
@@ -8,10 +8,10 @@
#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
+#include "services/network/public/mojom/load_timing_info.mojom.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/task_type.h"
-#include "third_party/blink/public/platform/web_url_load_timing.h"
#include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/public/platform/web_url_response.h"
@@ -105,13 +105,13 @@ void SetUpErrorURL() {
void SetUpRedirectURL() {
KURL url = RedirectURL();
- WebURLLoadTiming timing;
- timing.Initialize();
+ network::mojom::LoadTimingInfoPtr timing =
+ network::mojom::LoadTimingInfo::New();
WebURLResponse response;
response.SetCurrentRequestUrl(url);
response.SetHttpStatusCode(301);
- response.SetLoadTiming(timing);
+ response.SetLoadTiming(*timing);
response.AddHttpHeaderField("Location", SuccessURL().GetString());
response.AddHttpHeaderField("Access-Control-Allow-Origin", "http://fake.url");
@@ -124,13 +124,13 @@ void SetUpRedirectURL() {
void SetUpRedirectLoopURL() {
KURL url = RedirectLoopURL();
- WebURLLoadTiming timing;
- timing.Initialize();
+ network::mojom::LoadTimingInfoPtr timing =
+ network::mojom::LoadTimingInfo::New();
WebURLResponse response;
response.SetCurrentRequestUrl(url);
response.SetHttpStatusCode(301);
- response.SetLoadTiming(timing);
+ response.SetLoadTiming(*timing);
response.AddHttpHeaderField("Location", RedirectLoopURL().GetString());
response.AddHttpHeaderField("Access-Control-Allow-Origin", "http://fake.url");
@@ -165,8 +165,8 @@ class ThreadableLoaderTestHelper final {
void CreateLoader(ThreadableLoaderClient* client) {
ResourceLoaderOptions resource_loader_options;
- loader_ = MakeGarbageCollected<ThreadableLoader>(GetDocument(), client,
- resource_loader_options);
+ loader_ = MakeGarbageCollected<ThreadableLoader>(
+ *GetDocument().ToExecutionContext(), client, resource_loader_options);
}
void StartLoader(const ResourceRequest& request) { loader_->Start(request); }
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 355a5542de2..6b05fdda7d0 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
@@ -32,10 +32,11 @@ int ClampToRange(const int value, const int min, const int max) {
} // namespace
-void ThreadedIconLoader::Start(ExecutionContext* execution_context,
- const ResourceRequest& resource_request,
- const base::Optional<WebSize>& resize_dimensions,
- IconCallback callback) {
+void ThreadedIconLoader::Start(
+ ExecutionContext* execution_context,
+ const ResourceRequest& resource_request,
+ const base::Optional<gfx::Size>& resize_dimensions,
+ IconCallback callback) {
DCHECK(!stopped_);
DCHECK(resource_request.Url().IsValid());
DCHECK_EQ(resource_request.GetRequestContext(),
@@ -110,7 +111,8 @@ void ThreadedIconLoader::DecodeAndResizeImageOnBackgroundThread(
std::unique_ptr<ImageDecoder> decoder = ImageDecoder::Create(
std::move(data), /* data_complete= */ true,
ImageDecoder::kAlphaPremultiplied, ImageDecoder::kDefaultBitDepth,
- ColorBehavior::TransformToSRGB());
+ ColorBehavior::TransformToSRGB(),
+ ImageDecoder::OverrideAllowDecodeToYuv::kDeny);
if (!decoder) {
notify_complete(-1.0);
@@ -134,8 +136,9 @@ void ThreadedIconLoader::DecodeAndResizeImageOnBackgroundThread(
// it as well. This can be done synchronously given that we're on a
// background thread already.
double scale = std::min(
- static_cast<double>(resize_dimensions_->width) / decoded_icon_.width(),
- static_cast<double>(resize_dimensions_->height) / decoded_icon_.height());
+ static_cast<double>(resize_dimensions_->width()) / decoded_icon_.width(),
+ static_cast<double>(resize_dimensions_->height()) /
+ decoded_icon_.height());
if (scale >= 1.0) {
notify_complete(1.0);
@@ -144,10 +147,10 @@ void ThreadedIconLoader::DecodeAndResizeImageOnBackgroundThread(
int resized_width =
ClampToRange(static_cast<int>(scale * decoded_icon_.width()), 1,
- resize_dimensions_->width);
+ resize_dimensions_->width());
int resized_height =
ClampToRange(static_cast<int>(scale * decoded_icon_.height()), 1,
- resize_dimensions_->height);
+ resize_dimensions_->height());
// Use the RESIZE_GOOD quality allowing the implementation to pick an
// appropriate method for the resize. Can be increased to RESIZE_BETTER
@@ -183,7 +186,7 @@ void ThreadedIconLoader::DidFailRedirectCheck() {
std::move(icon_callback_).Run(SkBitmap(), -1);
}
-void ThreadedIconLoader::Trace(blink::Visitor* visitor) {
+void ThreadedIconLoader::Trace(Visitor* visitor) {
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 4384d7b8bd6..76697561842 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
@@ -38,7 +38,7 @@ class CORE_EXPORT ThreadedIconLoader final
// those dimensions.
void Start(ExecutionContext* execution_context,
const ResourceRequest& resource_request,
- const base::Optional<WebSize>& resize_dimensions,
+ const base::Optional<gfx::Size>& resize_dimensions,
IconCallback callback);
// Stops the background task. The provided callback will not be run if
@@ -51,7 +51,7 @@ class CORE_EXPORT ThreadedIconLoader final
void DidFail(const ResourceError& error) override;
void DidFailRedirectCheck() override;
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
void DecodeAndResizeImageOnBackgroundThread(
@@ -67,7 +67,7 @@ class CORE_EXPORT ThreadedIconLoader final
scoped_refptr<SharedBuffer> data_;
// Accessed from main thread and background thread.
- base::Optional<WebSize> resize_dimensions_;
+ base::Optional<gfx::Size> resize_dimensions_;
SkBitmap decoded_icon_;
IconCallback icon_callback_;
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 d515b09f4d1..3963b6e9cbb 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
@@ -49,7 +49,7 @@ class ThreadedIconLoaderTest : public PageTestBase {
std::pair<SkBitmap, double> LoadIcon(
const KURL& url,
- base::Optional<WebSize> resize_dimensions = base::nullopt) {
+ base::Optional<gfx::Size> resize_dimensions = base::nullopt) {
auto* icon_loader = MakeGarbageCollected<ThreadedIconLoader>();
ResourceRequest resource_request(url);
@@ -60,7 +60,7 @@ class ThreadedIconLoaderTest : public PageTestBase {
double resize_scale;
base::RunLoop run_loop;
icon_loader->Start(
- &GetDocument(), resource_request, resize_dimensions,
+ GetDocument().ToExecutionContext(), resource_request, resize_dimensions,
WTF::Bind(&ThreadedIconLoaderTest::DidGetIcon, WTF::Unretained(this),
run_loop.QuitClosure(), WTF::Unretained(&icon),
WTF::Unretained(&resize_scale)));
@@ -97,7 +97,7 @@ TEST_F(ThreadedIconLoaderTest, LoadIcon) {
}
TEST_F(ThreadedIconLoaderTest, LoadAndDownscaleIcon) {
- WebSize dimensions = {50, 50};
+ gfx::Size dimensions = {50, 50};
auto result = LoadIcon(RegisterMockedURL(kIconLoaderIcon100x100), dimensions);
const SkBitmap& icon = result.first;
double resize_scale = result.second;
@@ -110,7 +110,7 @@ TEST_F(ThreadedIconLoaderTest, LoadAndDownscaleIcon) {
}
TEST_F(ThreadedIconLoaderTest, LoadIconAndUpscaleIgnored) {
- WebSize dimensions = {500, 500};
+ gfx::Size dimensions = {500, 500};
auto result = LoadIcon(RegisterMockedURL(kIconLoaderIcon100x100), dimensions);
const SkBitmap& icon = result.first;
double resize_scale = result.second;
@@ -138,7 +138,7 @@ TEST_F(ThreadedIconLoaderTest, LoadTimeRecordedByUMA) {
}
TEST_F(ThreadedIconLoaderTest, ResizeFailed) {
- WebSize dimensions = {25, 0};
+ gfx::Size dimensions = {25, 0};
auto result = LoadIcon(RegisterMockedURL(kIconLoaderIcon100x100), dimensions);
const SkBitmap& icon = result.first;
double resize_scale = result.second;
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 13b5e510efb..bf9f746de74 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
@@ -37,6 +37,7 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/optional.h"
+#include "services/network/public/cpp/request_destination.h"
#include "services/network/public/cpp/request_mode.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
@@ -48,7 +49,7 @@
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/public/web/web_associated_url_loader_client.h"
#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/loader/threadable_loader.h"
#include "third_party/blink/renderer/core/loader/threadable_loader_client.h"
#include "third_party/blink/renderer/platform/exported/wrapped_resource_request.h"
@@ -61,6 +62,7 @@
#include "third_party/blink/renderer/platform/network/http_parsers.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/blink/renderer/platform/timer.h"
+#include "third_party/blink/renderer/platform/weborigin/referrer.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -214,9 +216,9 @@ void WebAssociatedURLLoaderImpl::ClientAdapter::DidReceiveResponse(
return;
}
- WebHTTPHeaderSet exposed_headers =
+ HTTPHeaderSet exposed_headers =
cors::ExtractCorsExposedHeaderNamesList(credentials_mode_, response);
- WebHTTPHeaderSet blocked_headers;
+ HTTPHeaderSet blocked_headers;
for (const auto& header : response.HttpHeaderFields()) {
if (FetchUtils::IsForbiddenResponseHeaderName(header.key) ||
(!cors::IsCorsSafelistedResponseHeader(header.key) &&
@@ -314,25 +316,31 @@ void WebAssociatedURLLoaderImpl::ClientAdapter::NotifyError(TimerBase* timer) {
class WebAssociatedURLLoaderImpl::Observer final
: public GarbageCollected<Observer>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(Observer);
public:
Observer(WebAssociatedURLLoaderImpl* parent, Document* document)
- : ContextLifecycleObserver(document), parent_(parent) {}
+ : ExecutionContextLifecycleObserver(document), parent_(parent) {}
void Dispose() {
parent_ = nullptr;
- ClearContext();
+ // TODO(keishi): Remove IsIteratingOverObservers() check when
+ // HeapObserverList() supports removal while iterating.
+ if (!GetExecutionContext()
+ ->ContextLifecycleObserverList()
+ .IsIteratingOverObservers()) {
+ SetExecutionContext(nullptr);
+ }
}
- void ContextDestroyed(ExecutionContext*) override {
+ void ContextDestroyed() override {
if (parent_)
parent_->DocumentDestroyed();
}
- void Trace(blink::Visitor* visitor) override {
- ContextLifecycleObserver::Trace(visitor);
+ void Trace(Visitor* visitor) override {
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
WebAssociatedURLLoaderImpl* parent_;
@@ -359,7 +367,8 @@ void WebAssociatedURLLoaderImpl::LoadAsynchronously(
DCHECK(client);
bool allow_load = true;
- WebURLRequest new_request(request);
+ WebURLRequest new_request;
+ new_request.CopyFrom(request);
if (options_.untrusted_http) {
WebString method = new_request.HttpMethod();
allow_load = observer_ && IsValidHTTPToken(method) &&
@@ -368,7 +377,18 @@ void WebAssociatedURLLoaderImpl::LoadAsynchronously(
new_request.SetHttpMethod(FetchUtils::NormalizeMethod(method));
HTTPRequestHeaderValidator validator;
new_request.VisitHttpHeaderFields(&validator);
- allow_load = validator.IsSafe();
+
+ // The request's referrer string is not stored as a header, so we must
+ // consult it separately, if set.
+ if (request.ReferrerString() !=
+ blink::WebString(Referrer::ClientReferrerString())) {
+ DCHECK(cors::IsForbiddenHeaderName("Referer"));
+ // `Referer` is a forbidden header name, so we must disallow this to
+ // load.
+ allow_load = false;
+ }
+
+ allow_load = allow_load && validator.IsSafe();
}
}
new_request.ToMutableResourceRequest().SetCorsPreflightPolicy(
@@ -379,7 +399,7 @@ void WebAssociatedURLLoaderImpl::LoadAsynchronously(
// ClientAdapterDone gets called between creating the loader and
// calling LoadAsynchronously.
if (observer_) {
- task_runner = To<Document>(observer_->LifecycleContext())
+ task_runner = Document::From(observer_->GetExecutionContext())
->GetTaskRunner(TaskType::kInternalLoading);
} else {
task_runner = Thread::Current()->GetTaskRunner();
@@ -396,7 +416,7 @@ void WebAssociatedURLLoaderImpl::LoadAsynchronously(
if (options_.grant_universal_access) {
const auto request_mode = new_request.GetMode();
DCHECK(request_mode == network::mojom::RequestMode::kNoCors ||
- network::IsNavigationRequestMode(request_mode));
+ request_mode == network::mojom::RequestMode::kNavigate);
// Some callers, notablly flash, with |grant_universal_access| want to
// have an origin matching with referrer.
KURL referrer(request.ToResourceRequest().ReferrerString());
@@ -413,6 +433,8 @@ void WebAssociatedURLLoaderImpl::LoadAsynchronously(
// (P2PPortAllocatorSession::AllocateLegacyRelaySession, for example).
// Remove this once those places are patched up.
new_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
+ new_request.SetRequestDestination(
+ network::mojom::RequestDestination::kEmpty);
} else if (context == mojom::RequestContextType::VIDEO) {
resource_loader_options.initiator_info.name =
fetch_initiator_type_names::kVideo;
@@ -422,9 +444,10 @@ void WebAssociatedURLLoaderImpl::LoadAsynchronously(
}
if (observer_) {
- Document& document = To<Document>(*observer_->LifecycleContext());
+ Document& document = Document::From(*observer_->GetExecutionContext());
loader_ = MakeGarbageCollected<ThreadableLoader>(
- document, client_adapter_, resource_loader_options);
+ *document.ToExecutionContext(), client_adapter_,
+ resource_loader_options);
loader_->Start(webcore_request);
}
}
diff --git a/chromium/third_party/blink/renderer/core/loader/web_associated_url_loader_impl.h b/chromium/third_party/blink/renderer/core/loader/web_associated_url_loader_impl.h
index 2c8ccfc2669..35b3e1183fe 100644
--- a/chromium/third_party/blink/renderer/core/loader/web_associated_url_loader_impl.h
+++ b/chromium/third_party/blink/renderer/core/loader/web_associated_url_loader_impl.h
@@ -64,8 +64,8 @@ class CORE_EXPORT WebAssociatedURLLoaderImpl final
Persistent<ClientAdapter> client_adapter_;
Persistent<ThreadableLoader> loader_;
- // A ContextLifecycleObserver for cancelling |loader_| when the Document is
- // detached.
+ // A ExecutionContextLifecycleObserver for cancelling |loader_| when the
+ // Document is detached.
Persistent<Observer> observer_;
DISALLOW_COPY_AND_ASSIGN(WebAssociatedURLLoaderImpl);
diff --git a/chromium/third_party/blink/renderer/core/loader/web_associated_url_loader_impl_test.cc b/chromium/third_party/blink/renderer/core/loader/web_associated_url_loader_impl_test.cc
index be5939bad5c..551498eb024 100644
--- a/chromium/third_party/blink/renderer/core/loader/web_associated_url_loader_impl_test.cc
+++ b/chromium/third_party/blink/renderer/core/loader/web_associated_url_loader_impl_test.cc
@@ -185,8 +185,8 @@ class WebAssociatedURLLoaderTest : public testing::Test,
request.SetMode(network::mojom::RequestMode::kSameOrigin);
request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit);
if (EqualIgnoringASCIICase(WebString::FromUTF8(header_field), "referer")) {
- request.SetHttpReferrer(WebString::FromUTF8(header_value),
- network::mojom::ReferrerPolicy::kDefault);
+ request.SetReferrerString(WebString::FromUTF8(header_value));
+ request.SetReferrerPolicy(network::mojom::ReferrerPolicy::kDefault);
} else {
request.SetHttpHeaderField(WebString::FromUTF8(header_field),
WebString::FromUTF8(header_value));
@@ -387,36 +387,6 @@ TEST_F(WebAssociatedURLLoaderTest, CrossOriginWithAccessControlFailure) {
EXPECT_FALSE(did_receive_response_);
}
-// Test an unsuccessful cross-origin load using CORS.
-TEST_F(WebAssociatedURLLoaderTest,
- CrossOriginWithAccessControlFailureBadStatusCode) {
- // This is cross-origin since the frame was loaded from www.test.com.
- KURL url =
- ToKURL("http://www.other.com/CrossOriginWithAccessControlFailure.html");
- WebURLRequest request(url);
- request.SetMode(network::mojom::RequestMode::kCors);
- request.SetCredentialsMode(network::mojom::CredentialsMode::kOmit);
-
- expected_response_ = WebURLResponse();
- expected_response_.SetMimeType("text/html");
- expected_response_.SetHttpStatusCode(0);
- expected_response_.AddHttpHeaderField("access-control-allow-origin", "*");
- RegisterMockedURLLoadWithCustomResponse(url, expected_response_,
- frame_file_path_);
-
- WebAssociatedURLLoaderOptions options;
- expected_loader_ = CreateAssociatedURLLoader(options);
- EXPECT_TRUE(expected_loader_);
- expected_loader_->LoadAsynchronously(request, this);
-
- // Failure should not be reported synchronously.
- EXPECT_FALSE(did_fail_);
- // The loader needs to receive the response, before doing the CORS check.
- ServeRequests();
- EXPECT_TRUE(did_fail_);
- EXPECT_FALSE(did_receive_response_);
-}
-
// Test a same-origin URL redirect and load.
TEST_F(WebAssociatedURLLoaderTest, RedirectSuccess) {
KURL url = ToKURL("http://www.test.com/RedirectSuccess.html");
@@ -617,6 +587,7 @@ TEST_F(WebAssociatedURLLoaderTest, MAYBE_UntrustedCheckHeaders) {
CheckHeaderFails("keep-alive");
CheckHeaderFails("origin");
CheckHeaderFails("referer", "http://example.com/");
+ CheckHeaderFails("referer", ""); // no-referrer.
CheckHeaderFails("te");
CheckHeaderFails("trailer");
CheckHeaderFails("transfer-encoding");
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 67b260827a3..afa9b00db12 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
@@ -51,7 +51,7 @@ WorkerFetchContext::WorkerFetchContext(
DCHECK(web_context_);
}
-KURL WorkerFetchContext::GetSiteForCookies() const {
+net::SiteForCookies WorkerFetchContext::GetSiteForCookies() const {
return web_context_->SiteForCookies();
}
@@ -144,9 +144,9 @@ bool WorkerFetchContext::ShouldBlockFetchByMixedContentCheck(
mojom::RequestContextType request_context,
ResourceRequest::RedirectStatus redirect_status,
const KURL& url,
- SecurityViolationReportingPolicy reporting_policy) const {
+ ReportingDisposition reporting_disposition) const {
return MixedContentChecker::ShouldBlockFetchOnWorker(
- *this, request_context, redirect_status, url, reporting_policy,
+ *this, request_context, redirect_status, url, reporting_disposition,
global_scope_->IsWorkletGlobalScope());
}
@@ -226,12 +226,14 @@ void WorkerFetchContext::AddResourceTiming(const ResourceTimingInfo& info) {
const SecurityOrigin* security_origin = GetResourceFetcherProperties()
.GetFetchClientSettingsObject()
.GetSecurityOrigin();
- WebResourceTimingInfo web_info = Performance::GenerateResourceTiming(
- *security_origin, info, *global_scope_);
+ mojom::blink::ResourceTimingInfoPtr mojo_info =
+ Performance::GenerateResourceTiming(*security_origin, info,
+ *global_scope_);
// |info| is taken const-ref but this can make destructive changes to
// WorkerTimingContainer on |info| when a page is controlled by a service
// worker.
- resource_timing_notifier_->AddResourceTiming(web_info, info.InitiatorType(),
+ resource_timing_notifier_->AddResourceTiming(std::move(mojo_info),
+ info.InitiatorType(),
info.TakeWorkerTimingReceiver());
}
@@ -243,7 +245,7 @@ void WorkerFetchContext::PopulateResourceRequest(
MixedContentChecker::UpgradeInsecureRequest(
out_request,
&GetResourceFetcherProperties().GetFetchClientSettingsObject(),
- global_scope_, network::mojom::RequestContextFrameType::kNone,
+ global_scope_, mojom::RequestContextFrameType::kNone,
global_scope_->ContentSettingsClient());
SetFirstPartyCookie(out_request);
if (!out_request.TopFrameOrigin())
@@ -277,7 +279,7 @@ bool WorkerFetchContext::AllowRunningInsecureContent(
enabled_per_settings, url);
}
-void WorkerFetchContext::Trace(blink::Visitor* visitor) {
+void WorkerFetchContext::Trace(Visitor* visitor) {
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 bd47ca130af..f7f18854f7c 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
@@ -40,7 +40,7 @@ class WorkerFetchContext final : public BaseFetchContext {
~WorkerFetchContext() override;
// BaseFetchContext implementation:
- KURL GetSiteForCookies() const override;
+ net::SiteForCookies GetSiteForCookies() const override;
scoped_refptr<const SecurityOrigin> GetTopFrameOrigin() const override;
SubresourceFilter* GetSubresourceFilter() const override;
@@ -59,11 +59,10 @@ class WorkerFetchContext final : public BaseFetchContext {
bool ShouldBlockWebSocketByMixedContentCheck(const KURL&) const override;
std::unique_ptr<WebSocketHandshakeThrottle> CreateWebSocketHandshakeThrottle()
override;
- bool ShouldBlockFetchByMixedContentCheck(
- mojom::RequestContextType,
- ResourceRequest::RedirectStatus,
- const KURL&,
- SecurityViolationReportingPolicy) const override;
+ bool ShouldBlockFetchByMixedContentCheck(mojom::RequestContextType,
+ ResourceRequest::RedirectStatus,
+ const KURL&,
+ ReportingDisposition) const override;
bool ShouldBlockFetchAsCredentialedSubresource(const ResourceRequest&,
const KURL&) const override;
const KURL& Url() const override;
@@ -93,7 +92,7 @@ class WorkerFetchContext final : public BaseFetchContext {
bool AllowRunningInsecureContent(bool enabled_per_settings,
const KURL& url) const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void SetFirstPartyCookie(ResourceRequest&);
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 a9f4eb5eebc..b78c173ef0e 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
@@ -5,7 +5,7 @@
#include "third_party/blink/renderer/core/loader/worker_resource_timing_notifier_impl.h"
#include <memory>
-#include "third_party/blink/public/platform/web_resource_timing_info.h"
+#include "third_party/blink/renderer/core/loader/cross_thread_resource_timing_info_copier.h"
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/core/timing/performance.h"
#include "third_party/blink/renderer/core/timing/worker_global_scope_performance.h"
@@ -63,7 +63,7 @@ WorkerResourceTimingNotifierImpl::WorkerResourceTimingNotifierImpl(
}
void WorkerResourceTimingNotifierImpl::AddResourceTiming(
- const WebResourceTimingInfo& info,
+ mojom::blink::ResourceTimingInfoPtr info,
const AtomicString& initiator_type,
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
worker_timing_receiver) {
@@ -73,20 +73,20 @@ void WorkerResourceTimingNotifierImpl::AddResourceTiming(
return;
DCHECK(inside_execution_context_->IsContextThread());
GetPerformance(*inside_execution_context_)
- ->AddResourceTiming(info, initiator_type,
+ ->AddResourceTiming(std::move(info), initiator_type,
std::move(worker_timing_receiver));
} else {
PostCrossThreadTask(
*task_runner_, FROM_HERE,
CrossThreadBindOnce(
&WorkerResourceTimingNotifierImpl::AddCrossThreadResourceTiming,
- WrapCrossThreadWeakPersistent(this), info,
+ WrapCrossThreadWeakPersistent(this), std::move(info),
initiator_type.GetString(), std::move(worker_timing_receiver)));
}
}
void WorkerResourceTimingNotifierImpl::AddCrossThreadResourceTiming(
- const WebResourceTimingInfo& info,
+ mojom::blink::ResourceTimingInfoPtr info,
const String& initiator_type,
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
worker_timing_receiver) {
@@ -96,7 +96,7 @@ void WorkerResourceTimingNotifierImpl::AddCrossThreadResourceTiming(
return;
DCHECK(outside_execution_context_->IsContextThread());
GetPerformance(*outside_execution_context_)
- ->AddResourceTiming(info, AtomicString(initiator_type),
+ ->AddResourceTiming(std::move(info), AtomicString(initiator_type),
std::move(worker_timing_receiver));
}
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 8ab07a20180..25dace026bc 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
@@ -7,6 +7,7 @@
#include "base/memory/scoped_refptr.h"
#include "base/single_thread_task_runner.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/core_export.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -39,7 +40,7 @@ class CORE_EXPORT WorkerResourceTimingNotifierImpl final
~WorkerResourceTimingNotifierImpl() override = default;
void AddResourceTiming(
- const WebResourceTimingInfo&,
+ mojom::blink::ResourceTimingInfoPtr,
const AtomicString& initiator_type,
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
worker_timing_receiver) override;
@@ -48,7 +49,7 @@ class CORE_EXPORT WorkerResourceTimingNotifierImpl final
private:
void AddCrossThreadResourceTiming(
- const WebResourceTimingInfo&,
+ mojom::blink::ResourceTimingInfoPtr,
const String& initiator_type,
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
worker_timing_receiver);
@@ -80,7 +81,7 @@ class CORE_EXPORT NullWorkerResourceTimingNotifier final
~NullWorkerResourceTimingNotifier() override = default;
void AddResourceTiming(
- const WebResourceTimingInfo&,
+ mojom::blink::ResourceTimingInfoPtr,
const AtomicString& initiator_type,
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
worker_timing_receiver) override {}
diff --git a/chromium/third_party/blink/renderer/core/mathml/BUILD.gn b/chromium/third_party/blink/renderer/core/mathml/BUILD.gn
index be46256d435..2204ea93ce5 100644
--- a/chromium/third_party/blink/renderer/core/mathml/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/mathml/BUILD.gn
@@ -8,5 +8,11 @@ blink_core_sources("mathml") {
sources = [
"mathml_element.cc",
"mathml_element.h",
+ "mathml_fraction_element.cc",
+ "mathml_fraction_element.h",
+ "mathml_row_element.cc",
+ "mathml_row_element.h",
+ "mathml_space_element.cc",
+ "mathml_space_element.h",
]
}
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 7e4430d542f..8d4a66622db 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
@@ -8,9 +8,15 @@
data: [
"definitionURL",
+ "depth",
+ "display",
+ "displaystyle",
"encoding",
+ "height",
+ "linethickness",
"mathbackground",
"mathcolor",
"mathsize",
+ "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 52bb3e3f390..9e1a4254d27 100644
--- a/chromium/third_party/blink/renderer/core/mathml/mathml_element.cc
+++ b/chromium/third_party/blink/renderer/core/mathml/mathml_element.cc
@@ -6,6 +6,7 @@
#include "third_party/blink/renderer/bindings/core/v8/script_event_listener.h"
#include "third_party/blink/renderer/core/css/css_property_name.h"
+#include "third_party/blink/renderer/core/css/parser/css_parser.h"
#include "third_party/blink/renderer/core/css_value_keywords.h"
#include "third_party/blink/renderer/core/html/html_element.h"
@@ -19,25 +20,26 @@ MathMLElement::MathMLElement(const QualifiedName& tagName,
MathMLElement::~MathMLElement() {}
static inline bool IsValidDirAttribute(const AtomicString& value) {
- return DeprecatedEqualIgnoringCase(value, "ltr") ||
- DeprecatedEqualIgnoringCase(value, "rtl");
+ return EqualIgnoringASCIICase(value, "ltr") ||
+ EqualIgnoringASCIICase(value, "rtl");
}
// Keywords from MathML3 and CSS font-size are skipped.
static inline bool IsDisallowedMathSizeAttribute(const AtomicString& value) {
- return DeprecatedEqualIgnoringCase(value, "medium") ||
+ return EqualIgnoringASCIICase(value, "medium") ||
value.EndsWith("large", kTextCaseASCIIInsensitive) ||
value.EndsWith("small", kTextCaseASCIIInsensitive) ||
- DeprecatedEqualIgnoringCase(value, "smaller") ||
- DeprecatedEqualIgnoringCase(value, "larger");
+ EqualIgnoringASCIICase(value, "smaller") ||
+ EqualIgnoringASCIICase(value, "larger");
}
bool MathMLElement::IsPresentationAttribute(const QualifiedName& name) const {
- // TODO(crbug.com/1023292, crbug.com/1023296): add support for display,
- // displaystyle and scriptlevel.
+ // 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)
+ name == mathml_names::kMathbackgroundAttr ||
+ name == mathml_names::kDisplayAttr ||
+ name == mathml_names::kDisplaystyleAttr)
return true;
return Element::IsPresentationAttribute(name);
}
@@ -64,6 +66,27 @@ void MathMLElement::CollectStyleForPresentationAttribute(
} else if (name == mathml_names::kMathcolorAttr) {
AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kColor,
value);
+ } else if (name == mathml_names::kDisplayAttr &&
+ HasTagName(mathml_names::kMathTag)) {
+ if (EqualIgnoringASCIICase(value, "inline")) {
+ AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kDisplay,
+ CSSValueID::kInlineMath);
+ AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kMathStyle,
+ CSSValueID::kInline);
+ } else if (EqualIgnoringASCIICase(value, "block")) {
+ AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kDisplay,
+ CSSValueID::kMath);
+ AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kMathStyle,
+ CSSValueID::kDisplay);
+ }
+ } else if (name == mathml_names::kDisplaystyleAttr) {
+ if (EqualIgnoringASCIICase(value, "false")) {
+ AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kMathStyle,
+ CSSValueID::kInline);
+ } else if (EqualIgnoringASCIICase(value, "true")) {
+ AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kMathStyle,
+ CSSValueID::kDisplay);
+ }
} else {
Element::CollectStyleForPresentationAttribute(name, value, style);
}
@@ -82,4 +105,18 @@ void MathMLElement::ParseAttribute(const AttributeModificationParams& param) {
Element::ParseAttribute(param);
}
+base::Optional<Length> MathMLElement::AddMathLengthToComputedStyle(
+ ComputedStyle& style,
+ const CSSToLengthConversionData& conversion_data,
+ const QualifiedName& attr_name) {
+ if (!FastHasAttribute(attr_name))
+ return base::nullopt;
+ auto value = FastGetAttribute(attr_name);
+ const CSSPrimitiveValue* parsed_value = CSSParser::ParseLengthPercentage(
+ value, StrictCSSParserContext(GetDocument().GetSecureContextMode()));
+ if (!parsed_value || parsed_value->IsCalculated())
+ return base::nullopt;
+ return parsed_value->ConvertToLength(conversion_data);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/mathml/mathml_element.h b/chromium/third_party/blink/renderer/core/mathml/mathml_element.h
index 62d629010a7..a83de751a16 100644
--- a/chromium/third_party/blink/renderer/core/mathml/mathml_element.h
+++ b/chromium/third_party/blink/renderer/core/mathml/mathml_element.h
@@ -5,13 +5,18 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_MATHML_MATHML_ELEMENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_MATHML_MATHML_ELEMENT_H_
+#include "base/optional.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/mathml_names.h"
+#include "third_party/blink/renderer/platform/geometry/length.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
+class CSSToLengthConversionData;
+class QualifiedName;
+
class CORE_EXPORT MathMLElement : public Element {
DEFINE_WRAPPERTYPEINFO();
@@ -25,61 +30,45 @@ class CORE_EXPORT MathMLElement : public Element {
return HasLocalName(name.LocalName());
}
- private:
- bool IsPresentationAttribute(const QualifiedName&) const final;
- void CollectStyleForPresentationAttribute(const QualifiedName&,
- const AtomicString&,
- MutableCSSPropertyValueSet*) final;
+ protected:
+ bool IsPresentationAttribute(const QualifiedName&) const override;
+ void CollectStyleForPresentationAttribute(
+ const QualifiedName&,
+ const AtomicString&,
+ MutableCSSPropertyValueSet*) override;
+
+ base::Optional<Length> AddMathLengthToComputedStyle(
+ ComputedStyle&,
+ const CSSToLengthConversionData&,
+ const QualifiedName&);
+ private:
void ParseAttribute(const AttributeModificationParams&) final;
bool IsMathMLElement() const =
delete; // This will catch anyone doing an unnecessary check.
};
-DEFINE_ELEMENT_TYPE_CASTS(MathMLElement, IsMathMLElement());
-
-template <>
-struct DowncastTraits<MathMLElement> {
- static bool AllowFrom(const Node& node) { return node.IsMathMLElement(); }
-};
-
template <typename T>
bool IsElementOfType(const MathMLElement&);
template <>
inline bool IsElementOfType<const MathMLElement>(const MathMLElement&) {
return true;
}
+template <>
+inline bool IsElementOfType<const MathMLElement>(const Node& node) {
+ return IsA<MathMLElement>(node);
+}
+template <>
+struct DowncastTraits<MathMLElement> {
+ static bool AllowFrom(const Node& node) { return node.IsMathMLElement(); }
+};
inline bool Node::HasTagName(const MathMLQualifiedName& name) const {
auto* mathml_element = DynamicTo<MathMLElement>(this);
return mathml_element && mathml_element->HasTagName(name);
}
-// This requires IsMathML*Element(const MathMLElement&).
-#define DEFINE_MATHMLELEMENT_TYPE_CASTS_WITH_FUNCTION(thisType) \
- inline bool Is##thisType(const thisType* element); \
- inline bool Is##thisType(const thisType& element); \
- inline bool Is##thisType(const MathMLElement* element) { \
- return element && Is##thisType(*element); \
- } \
- inline bool Is##thisType(const Node& node) { \
- auto* mathml_element = DynamicTo<MathMLElement>(node); \
- return mathml_element && Is##thisType(mathml_element); \
- } \
- inline bool Is##thisType(const Node* node) { \
- return node && Is##thisType(*node); \
- } \
- template <typename T> \
- inline bool Is##thisType(const Member<T>& node) { \
- return Is##thisType(node.Get()); \
- } \
- template <> \
- inline bool IsElementOfType<const thisType>(const MathMLElement& element) { \
- return Is##thisType(element); \
- } \
- DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(thisType)
-
} // namespace blink
#include "third_party/blink/renderer/core/mathml_element_type_helpers.h"
diff --git a/chromium/third_party/blink/renderer/core/mathml/mathml_fraction_element.cc b/chromium/third_party/blink/renderer/core/mathml/mathml_fraction_element.cc
new file mode 100644
index 00000000000..ad316cdd671
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/mathml/mathml_fraction_element.cc
@@ -0,0 +1,32 @@
+// 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/mathml/mathml_fraction_element.h"
+
+#include "third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+
+namespace blink {
+
+MathMLFractionElement::MathMLFractionElement(Document& doc)
+ : MathMLElement(mathml_names::kMfracTag, doc) {}
+
+void MathMLFractionElement::AddMathFractionBarThicknessIfNeeded(
+ ComputedStyle& style,
+ const CSSToLengthConversionData& conversion_data) {
+ if (auto length_or_percentage_value = AddMathLengthToComputedStyle(
+ style, conversion_data, mathml_names::kLinethicknessAttr))
+ style.SetMathFractionBarThickness(std::move(*length_or_percentage_value));
+}
+
+LayoutObject* MathMLFractionElement::CreateLayoutObject(
+ const ComputedStyle& style,
+ LegacyLayout legacy) {
+ if (!RuntimeEnabledFeatures::MathMLCoreEnabled() ||
+ !style.IsDisplayMathType() || legacy == LegacyLayout::kForce)
+ return MathMLElement::CreateLayoutObject(style, legacy);
+ return new LayoutNGMathMLBlock(this);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/mathml/mathml_fraction_element.h b/chromium/third_party/blink/renderer/core/mathml/mathml_fraction_element.h
new file mode 100644
index 00000000000..eac9e4e5d95
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/mathml/mathml_fraction_element.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_CORE_MATHML_MATHML_FRACTION_ELEMENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_MATHML_MATHML_FRACTION_ELEMENT_H_
+
+#include "third_party/blink/renderer/core/mathml/mathml_element.h"
+
+namespace blink {
+
+class ComputedStyle;
+class CSSToLengthConversionData;
+class LayoutObject;
+
+class MathMLFractionElement final : public MathMLElement {
+ public:
+ explicit MathMLFractionElement(Document&);
+
+ void AddMathFractionBarThicknessIfNeeded(ComputedStyle&,
+ const CSSToLengthConversionData&);
+
+ private:
+ LayoutObject* CreateLayoutObject(const ComputedStyle&,
+ LegacyLayout legacy) final;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_MATHML_MATHML_FRACTION_ELEMENT_H_
diff --git a/chromium/third_party/blink/renderer/core/mathml/mathml_row_element.cc b/chromium/third_party/blink/renderer/core/mathml/mathml_row_element.cc
new file mode 100644
index 00000000000..db1206b6de1
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/mathml/mathml_row_element.cc
@@ -0,0 +1,26 @@
+// 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/mathml/mathml_row_element.h"
+
+#include "third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+
+namespace blink {
+
+MathMLRowElement::MathMLRowElement(const QualifiedName& tagName,
+ Document& document)
+ : MathMLElement(tagName, document) {}
+
+LayoutObject* MathMLRowElement::CreateLayoutObject(const ComputedStyle& style,
+ LegacyLayout legacy) {
+ // TODO(rbuis): legacy check should be removed.
+ if (!RuntimeEnabledFeatures::MathMLCoreEnabled() ||
+ legacy == LegacyLayout::kForce ||
+ (!style.IsDisplayMathType() && !HasTagName(mathml_names::kMathTag)))
+ return MathMLElement::CreateLayoutObject(style, legacy);
+ return new LayoutNGMathMLBlock(this);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/mathml/mathml_row_element.h b/chromium/third_party/blink/renderer/core/mathml/mathml_row_element.h
new file mode 100644
index 00000000000..5e0a53c0bdb
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/mathml/mathml_row_element.h
@@ -0,0 +1,25 @@
+// 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_MATHML_MATHML_ROW_ELEMENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_MATHML_MATHML_ROW_ELEMENT_H_
+
+#include "third_party/blink/renderer/core/mathml/mathml_element.h"
+
+namespace blink {
+
+class ComputedStyle;
+class Document;
+
+class CORE_EXPORT MathMLRowElement : public MathMLElement {
+ public:
+ explicit MathMLRowElement(const QualifiedName&, Document&);
+
+ private:
+ LayoutObject* CreateLayoutObject(const ComputedStyle&,
+ LegacyLayout legacy) final;
+};
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_MATHML_MATHML_ROW_ELEMENT_H_
diff --git a/chromium/third_party/blink/renderer/core/mathml/mathml_space_element.cc b/chromium/third_party/blink/renderer/core/mathml/mathml_space_element.cc
new file mode 100644
index 00000000000..716fe389fb9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/mathml/mathml_space_element.cc
@@ -0,0 +1,65 @@
+// 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/mathml/mathml_space_element.h"
+
+#include "third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+
+namespace blink {
+
+MathMLSpaceElement::MathMLSpaceElement(Document& doc)
+ : MathMLElement(mathml_names::kMspaceTag, doc) {}
+
+void MathMLSpaceElement::AddMathBaselineIfNeeded(
+ ComputedStyle& style,
+ const CSSToLengthConversionData& conversion_data) {
+ if (auto length_or_percentage_value = AddMathLengthToComputedStyle(
+ style, conversion_data, mathml_names::kHeightAttr))
+ style.SetMathBaseline(std::move(*length_or_percentage_value));
+}
+
+bool MathMLSpaceElement::IsPresentationAttribute(
+ const QualifiedName& name) const {
+ if (name == mathml_names::kWidthAttr || name == mathml_names::kHeightAttr ||
+ name == mathml_names::kDepthAttr)
+ return true;
+ return MathMLElement::IsPresentationAttribute(name);
+}
+
+void MathMLSpaceElement::CollectStyleForPresentationAttribute(
+ const QualifiedName& name,
+ const AtomicString& value,
+ MutableCSSPropertyValueSet* style) {
+ if (name == mathml_names::kWidthAttr) {
+ AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kWidth,
+ value);
+ } else if (name == mathml_names::kHeightAttr ||
+ name == mathml_names::kDepthAttr) {
+ // TODO(rbuis): this can be simplified once attr() is supported for
+ // width/height.
+ String height = FastGetAttribute(mathml_names::kHeightAttr);
+ String depth = FastGetAttribute(mathml_names::kDepthAttr);
+ if (!height.IsEmpty() && !depth.IsEmpty()) {
+ AddPropertyToPresentationAttributeStyle(
+ style, CSSPropertyID::kHeight,
+ "calc(" + height + " + " + depth + ")");
+ } else {
+ AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kHeight,
+ value);
+ }
+ } else {
+ MathMLElement::CollectStyleForPresentationAttribute(name, value, style);
+ }
+}
+
+LayoutObject* MathMLSpaceElement::CreateLayoutObject(const ComputedStyle& style,
+ LegacyLayout legacy) {
+ if (!RuntimeEnabledFeatures::MathMLCoreEnabled() ||
+ !style.IsDisplayMathType() || legacy == LegacyLayout::kForce)
+ return MathMLElement::CreateLayoutObject(style, legacy);
+ return new LayoutNGMathMLBlock(this);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/mathml/mathml_space_element.h b/chromium/third_party/blink/renderer/core/mathml/mathml_space_element.h
new file mode 100644
index 00000000000..719e497324c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/mathml/mathml_space_element.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_CORE_MATHML_MATHML_SPACE_ELEMENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_MATHML_MATHML_SPACE_ELEMENT_H_
+
+#include "third_party/blink/renderer/core/mathml/mathml_element.h"
+
+namespace blink {
+
+class LayoutObject;
+class ComputedStyle;
+class CSSToLengthConversionData;
+
+class MathMLSpaceElement final : public MathMLElement {
+ public:
+ explicit MathMLSpaceElement(Document&);
+
+ void AddMathBaselineIfNeeded(ComputedStyle&,
+ const CSSToLengthConversionData&);
+
+ private:
+ LayoutObject* CreateLayoutObject(const ComputedStyle&,
+ LegacyLayout legacy) override;
+ bool IsPresentationAttribute(const QualifiedName&) const override;
+ void CollectStyleForPresentationAttribute(
+ const QualifiedName&,
+ const AtomicString&,
+ MutableCSSPropertyValueSet*) override;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_MATHML_MATHML_SPACE_ELEMENT_H_
diff --git a/chromium/third_party/blink/renderer/core/mathml/mathml_tag_names.json5 b/chromium/third_party/blink/renderer/core/mathml/mathml_tag_names.json5
index af9f5dd80a1..17fd2a6452f 100644
--- a/chromium/third_party/blink/renderer/core/mathml/mathml_tag_names.json5
+++ b/chromium/third_party/blink/renderer/core/mathml/mathml_tag_names.json5
@@ -2,13 +2,41 @@
metadata: {
namespace: "MathML",
namespaceURI: "http://www.w3.org/1998/Math/MathML",
- fallbackInterfaceName: "MathMLElement",
+ fallbackInterfaceName: "MathMLRowElement",
fallbackJSInterfaceName: "MathMLElement",
export: "CORE_EXPORT",
},
data: [
{
+ name: "annotation",
+ interfaceName: "MathMLElement",
+ },
+ {
+ name: "annotation-xml",
+ interfaceName: "MathMLElement",
+ },
+ {
+ name: "maction",
+ interfaceName: "MathMLRowElement",
+ },
+ {
+ name: "malignmark",
+ interfaceName: "MathMLElement",
+ },
+ {
name: "math",
+ interfaceName: "MathMLRowElement",
+ },
+ {
+ name: "merror",
+ interfaceName: "MathMLRowElement",
+ },
+ {
+ name: "mfrac",
+ interfaceName: "MathMLFractionElement",
+ },
+ {
+ name: "mglyph",
interfaceName: "MathMLElement",
},
{
@@ -24,32 +52,32 @@
interfaceName: "MathMLElement",
},
{
- name: "mtext",
- interfaceName: "MathMLElement",
+ name: "mphantom",
+ interfaceName: "MathMLRowElement",
},
{
- name: "ms",
- interfaceName: "MathMLElement",
+ name: "mrow",
+ interfaceName: "MathMLRowElement",
},
{
- name: "mglyph",
+ name: "ms",
interfaceName: "MathMLElement",
},
{
- name: "malignmark",
- interfaceName: "MathMLElement",
+ name: "mspace",
+ interfaceName: "MathMLSpaceElement",
},
{
- name: "annotation",
- interfaceName: "MathMLElement",
+ name: "mstyle",
+ interfaceName: "MathMLRowElement",
},
{
- name: "annotation-xml",
+ name: "mtext",
interfaceName: "MathMLElement",
},
{
name: "semantics",
- interfaceName: "MathMLElement",
+ interfaceName: "MathMLRowElement",
},
]
}
diff --git a/chromium/third_party/blink/renderer/core/messaging/BUILD.gn b/chromium/third_party/blink/renderer/core/messaging/BUILD.gn
index ec799e5296f..a523a06df0d 100644
--- a/chromium/third_party/blink/renderer/core/messaging/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/messaging/BUILD.gn
@@ -20,7 +20,5 @@ blink_core_sources("messaging") {
"message_port.h",
]
- public_deps = [
- "//third_party/blink/public/mojom:mojom_core_blink",
- ]
+ public_deps = [ "//third_party/blink/public/mojom:mojom_core_blink" ]
}
diff --git a/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits_test.cc b/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits_test.cc
index b29bbeae424..f92ff31a947 100644
--- a/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits_test.cc
+++ b/chromium/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits_test.cc
@@ -20,6 +20,7 @@
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/skia/include/core/SkBitmap.h"
namespace blink {
@@ -122,7 +123,7 @@ TEST(BlinkTransferableMessageStructTraitsTest,
ImageBitmap* CreateBitmap() {
sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(8, 4);
surface->getCanvas()->clear(SK_ColorRED);
- return ImageBitmap::Create(
+ return MakeGarbageCollected<ImageBitmap>(
UnacceleratedStaticBitmapImage::Create(surface->makeImageSnapshot()));
}
@@ -178,8 +179,8 @@ TEST(BlinkTransferableMessageStructTraitsTest,
ASSERT_EQ(out.message->GetImageBitmapContentsArray().size(), 1U);
scoped_refptr<blink::StaticBitmapImage> deserialized_bitmap_contents =
out.message->GetImageBitmapContentsArray()[0];
- ImageBitmap* deserialized_bitmap =
- ImageBitmap::Create(std::move(deserialized_bitmap_contents));
+ auto* deserialized_bitmap = MakeGarbageCollected<ImageBitmap>(
+ std::move(deserialized_bitmap_contents));
ASSERT_EQ(deserialized_bitmap->height(), original_bitmap_height);
ASSERT_EQ(deserialized_bitmap->width(), original_bitmap_width);
// When using WrapAsMessage, the deserialized bitmap should own
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 b8f69fe9cc8..cc86ff2c95d 100644
--- a/chromium/third_party/blink/renderer/core/messaging/message_channel.cc
+++ b/chromium/third_party/blink/renderer/core/messaging/message_channel.cc
@@ -39,7 +39,7 @@ MessageChannel::MessageChannel(ExecutionContext* context)
port2_->Entangle(std::move(pipe.handle1));
}
-void MessageChannel::Trace(blink::Visitor* visitor) {
+void MessageChannel::Trace(Visitor* visitor) {
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 45fea2f4f92..59f7132f1cb 100644
--- a/chromium/third_party/blink/renderer/core/messaging/message_channel.h
+++ b/chromium/third_party/blink/renderer/core/messaging/message_channel.h
@@ -40,12 +40,16 @@ class CORE_EXPORT MessageChannel final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
+ static MessageChannel* Create(ExecutionContext* execution_context) {
+ return MakeGarbageCollected<MessageChannel>(execution_context);
+ }
+
explicit MessageChannel(ExecutionContext*);
MessagePort* port1() const { return port1_; }
MessagePort* port2() const { return port2_; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<MessagePort> port1_;
diff --git a/chromium/third_party/blink/renderer/core/messaging/message_channel.idl b/chromium/third_party/blink/renderer/core/messaging/message_channel.idl
index 7377c571b20..39907689b58 100644
--- a/chromium/third_party/blink/renderer/core/messaging/message_channel.idl
+++ b/chromium/third_party/blink/renderer/core/messaging/message_channel.idl
@@ -27,10 +27,9 @@
// https://html.spec.whatwg.org/C/#message-channels
[
- CustomConstructor,
- Exposed=(Window,Worker),
- Measure
+ Exposed=(Window, Worker)
] interface MessageChannel {
+ [CallWith=ExecutionContext, Measure] constructor();
readonly attribute MessagePort port1;
readonly attribute MessagePort port2;
};
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 a82a85280e9..3e71122bfbc 100644
--- a/chromium/third_party/blink/renderer/core/messaging/message_port.cc
+++ b/chromium/third_party/blink/renderer/core/messaging/message_port.cc
@@ -32,13 +32,13 @@
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_post_message_options.h"
#include "third_party/blink/renderer/core/events/message_event.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/user_activation.h"
#include "third_party/blink/renderer/core/inspector/thread_debugger.h"
#include "third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.h"
-#include "third_party/blink/renderer/core/messaging/post_message_options.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
@@ -48,15 +48,8 @@
namespace blink {
-// TODO(altimin): Remove these after per-task mojo dispatching.
-// The maximum number of MessageEvents to dispatch from one task.
-constexpr int kMaximumMessagesPerTask = 200;
-// The threshold to stop processing new tasks.
-constexpr base::TimeDelta kYieldThreshold =
- base::TimeDelta::FromMilliseconds(50);
-
MessagePort::MessagePort(ExecutionContext& execution_context)
- : ContextLifecycleObserver(&execution_context),
+ : ExecutionContextLifecycleObserver(&execution_context),
task_runner_(execution_context.GetTaskRunner(TaskType::kPostedMessage)) {}
MessagePort::~MessagePort() {
@@ -258,29 +251,14 @@ MessagePortArray* MessagePort::EntanglePorts(
return connector_->handle().value();
}
-void MessagePort::Trace(blink::Visitor* visitor) {
- ContextLifecycleObserver::Trace(visitor);
+void MessagePort::Trace(Visitor* visitor) {
+ ExecutionContextLifecycleObserver::Trace(visitor);
EventTargetWithInlineData::Trace(visitor);
}
bool MessagePort::Accept(mojo::Message* mojo_message) {
TRACE_EVENT0("blink", "MessagePort::Accept");
- // Connector repeatedly calls Accept as long as any messages are available. To
- // avoid completely starving the event loop and give some time for other tasks
- // the connector is temporarily paused after |kMaximumMessagesPerTask| have
- // been received without other tasks having had a chance to run (in particular
- // the ResetMessageCount task posted here).
- // TODO(altimin): Remove this after per-task mojo dispatching lands[1].
- // [1] https://chromium-review.googlesource.com/c/chromium/src/+/1145692
- if (messages_in_current_task_ == 0) {
- task_runner_->PostTask(FROM_HERE, WTF::Bind(&MessagePort::ResetMessageCount,
- WrapWeakPersistent(this)));
- }
- if (ShouldYieldAfterNewMessage()) {
- connector_->PauseIncomingMethodCallProcessing();
- }
-
BlinkTransferableMessage message;
if (!mojom::blink::TransferableMessage::DeserializeFromMessage(
std::move(*mojo_message), &message)) {
@@ -348,23 +326,4 @@ Event* MessagePort::CreateMessageEvent(BlinkTransferableMessage& message) {
user_activation);
}
-void MessagePort::ResetMessageCount() {
- DCHECK_GT(messages_in_current_task_, 0);
- messages_in_current_task_ = 0;
- task_start_time_ = base::nullopt;
- // No-op if not paused already.
- if (connector_)
- connector_->ResumeIncomingMethodCallProcessing();
-}
-
-bool MessagePort::ShouldYieldAfterNewMessage() {
- ++messages_in_current_task_;
- if (messages_in_current_task_ > kMaximumMessagesPerTask)
- return true;
- base::TimeTicks now = base::TimeTicks::Now();
- if (!task_start_time_)
- task_start_time_ = now;
- return now - task_start_time_.value() > kYieldThreshold;
-}
-
} // namespace blink
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 2a08335398b..d2480449994 100644
--- a/chromium/third_party/blink/renderer/core/messaging/message_port.h
+++ b/chromium/third_party/blink/renderer/core/messaging/message_port.h
@@ -39,7 +39,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/events/event_listener.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
@@ -53,7 +53,7 @@ class ScriptState;
class CORE_EXPORT MessagePort : public EventTargetWithInlineData,
public mojo::MessageReceiver,
public ActiveScriptWrappable<MessagePort>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(MessagePort);
@@ -93,15 +93,15 @@ class CORE_EXPORT MessagePort : public EventTargetWithInlineData,
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
MessagePort* ToMessagePort() override { return this; }
// ScriptWrappable implementation.
bool HasPendingActivity() const final;
- // ContextLifecycleObserver implementation.
- void ContextDestroyed(ExecutionContext*) override { close(); }
+ // ExecutionContextLifecycleObserver implementation.
+ void ContextDestroyed() override { close(); }
void setOnmessage(EventListener* listener) {
SetAttributeEventListener(event_type_names::kMessage, listener);
@@ -130,23 +130,18 @@ class CORE_EXPORT MessagePort : public EventTargetWithInlineData,
// For testing only: allows inspection of the entangled channel.
::MojoHandle EntangledHandleForTesting() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
// mojo::MessageReceiver implementation.
bool Accept(mojo::Message*) override;
- void ResetMessageCount();
- bool ShouldYieldAfterNewMessage();
Event* CreateMessageEvent(BlinkTransferableMessage& message);
std::unique_ptr<mojo::Connector> connector_;
- int messages_in_current_task_ = 0;
bool started_ = false;
bool closed_ = false;
- base::Optional<base::TimeTicks> task_start_time_;
-
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
};
diff --git a/chromium/third_party/blink/renderer/core/messaging/message_port.idl b/chromium/third_party/blink/renderer/core/messaging/message_port.idl
index 554b822687e..6fab27fcdf1 100644
--- a/chromium/third_party/blink/renderer/core/messaging/message_port.idl
+++ b/chromium/third_party/blink/renderer/core/messaging/message_port.idl
@@ -33,7 +33,7 @@
Transferable
] interface MessagePort : EventTarget {
[CallWith=ScriptState, RaisesException, Measure] void postMessage(any message, sequence<object> transfer);
- [CallWith=ScriptState, RaisesException, Measure] void postMessage(any message, optional PostMessageOptions options);
+ [CallWith=ScriptState, RaisesException, Measure] void postMessage(any message, optional PostMessageOptions options = {});
[Measure] void start();
[Measure] void close();
diff --git a/chromium/third_party/blink/renderer/core/mojo/BUILD.gn b/chromium/third_party/blink/renderer/core/mojo/BUILD.gn
index eb1f27925c4..537be921093 100644
--- a/chromium/third_party/blink/renderer/core/mojo/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/mojo/BUILD.gn
@@ -28,13 +28,9 @@ blink_core_sources("mojo") {
jumbo_source_set("unit_tests") {
testonly = true
- sources = [
- "tests/js_to_cpp_test.cc",
- ]
+ sources = [ "tests/js_to_cpp_test.cc" ]
- data = [
- "tests/JsToCppTest.js",
- ]
+ data = [ "tests/JsToCppTest.js" ]
configs += [
"//third_party/blink/renderer/core:blink_core_pch",
@@ -57,7 +53,5 @@ jumbo_source_set("unit_tests") {
}
mojom("test_bindings") {
- sources = [
- "tests/js_to_cpp.mojom",
- ]
+ sources = [ "tests/js_to_cpp.mojom" ]
}
diff --git a/chromium/third_party/blink/renderer/core/mojo/mojo.cc b/chromium/third_party/blink/renderer/core/mojo/mojo.cc
index aab3fa5cd51..28de5f1938d 100644
--- a/chromium/third_party/blink/renderer/core/mojo/mojo.cc
+++ b/chromium/third_party/blink/renderer/core/mojo/mojo.cc
@@ -8,16 +8,15 @@
#include <utility>
#include "mojo/public/cpp/system/message_pipe.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
-#include "third_party/blink/public/platform/interface_provider.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/renderer/bindings/core/v8/v8_mojo_create_data_pipe_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mojo_create_data_pipe_result.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mojo_create_message_pipe_result.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mojo_create_shared_buffer_result.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/frame/local_frame_client.h"
-#include "third_party/blink/renderer/core/mojo/mojo_create_data_pipe_options.h"
-#include "third_party/blink/renderer/core/mojo/mojo_create_data_pipe_result.h"
-#include "third_party/blink/renderer/core/mojo/mojo_create_message_pipe_result.h"
-#include "third_party/blink/renderer/core/mojo/mojo_create_shared_buffer_result.h"
#include "third_party/blink/renderer/core/mojo/mojo_handle.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/core/workers/worker_thread.h"
@@ -98,33 +97,20 @@ MojoCreateSharedBufferResult* Mojo::createSharedBuffer(unsigned num_bytes) {
void Mojo::bindInterface(ScriptState* script_state,
const String& interface_name,
MojoHandle* request_handle,
- const String& scope,
- bool use_browser_interface_broker) {
+ const String& scope) {
std::string name = interface_name.Utf8();
auto handle =
mojo::ScopedMessagePipeHandle::From(request_handle->TakeHandle());
if (scope == "process") {
- Platform::Current()->GetInterfaceProvider()->GetInterface(
- name.c_str(), std::move(handle));
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
+ mojo::GenericPendingReceiver(name, std::move(handle)));
return;
}
- // This should replace InterfaceProvider usage below when all
- // InterfaceProvider clients are converted to use BrowserInterfaceBroker. See
- // crbug.com/936482.
- if (use_browser_interface_broker) {
- ExecutionContext::From(script_state)
- ->GetBrowserInterfaceBroker()
- .GetInterface(name, std::move(handle));
- return;
- }
-
- // TODO(crbug.com/995556): remove when no longer used.
- if (auto* interface_provider =
- ExecutionContext::From(script_state)->GetInterfaceProvider()) {
- interface_provider->GetInterfaceByName(name, std::move(handle));
- }
+ ExecutionContext::From(script_state)
+ ->GetBrowserInterfaceBroker()
+ .GetInterface(name, std::move(handle));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/mojo/mojo.h b/chromium/third_party/blink/renderer/core/mojo/mojo.h
index b0e8b78d35f..a81831c93b0 100644
--- a/chromium/third_party/blink/renderer/core/mojo/mojo.h
+++ b/chromium/third_party/blink/renderer/core/mojo/mojo.h
@@ -54,8 +54,7 @@ class Mojo final : public ScriptWrappable {
static void bindInterface(ScriptState*,
const String& interface_name,
MojoHandle*,
- const String& scope,
- bool use_browser_interface_broker);
+ const String& scope);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/mojo/mojo.idl b/chromium/third_party/blink/renderer/core/mojo/mojo.idl
index 9bfcfc67066..d407172039f 100644
--- a/chromium/third_party/blink/renderer/core/mojo/mojo.idl
+++ b/chromium/third_party/blink/renderer/core/mojo/mojo.idl
@@ -7,14 +7,14 @@
typedef unsigned long MojoResult;
enum MojoScope {
- // Refers to the InterfaceProvider associated with the current execution
+ // Refers to the BrowserInterfaceBroker associated with the current execution
// context. Either a Document or WorkerGlobalScope.
"context",
- // Refers to the InterfaceProvider of the current process.
+ // Refers to the BrowserInterfaceBroker of the current process.
//
// Note: A "process" is not a web concept. In some cases the browser process
// concept of a "site instance" may be useful however there is currently no
- // InterfaceProvider per site instance.
+ // BrowserInterfaceBroker per site instance.
"process",
};
@@ -46,5 +46,5 @@ enum MojoScope {
static MojoCreateDataPipeResult createDataPipe(MojoCreateDataPipeOptions options);
static MojoCreateSharedBufferResult createSharedBuffer(unsigned long numBytes);
- [CallWith=ScriptState] static void bindInterface(DOMString interfaceName, MojoHandle request_handle, optional MojoScope scope = "context", optional boolean useBrowserInterfaceBroker = false);
+ [CallWith=ScriptState] static void bindInterface(DOMString interfaceName, MojoHandle request_handle, optional MojoScope scope = "context");
};
diff --git a/chromium/third_party/blink/renderer/core/mojo/mojo_handle.cc b/chromium/third_party/blink/renderer/core/mojo/mojo_handle.cc
index a7c22b55bc0..5f1aafc57b1 100644
--- a/chromium/third_party/blink/renderer/core/mojo/mojo_handle.cc
+++ b/chromium/third_party/blink/renderer/core/mojo/mojo_handle.cc
@@ -9,18 +9,18 @@
#include "mojo/public/cpp/bindings/message.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mojo_create_shared_buffer_result.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mojo_discard_data_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mojo_duplicate_buffer_handle_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mojo_map_buffer_result.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mojo_read_data_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mojo_read_data_result.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mojo_read_message_flags.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mojo_read_message_result.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mojo_write_data_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mojo_write_data_result.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
-#include "third_party/blink/renderer/core/mojo/mojo_create_shared_buffer_result.h"
-#include "third_party/blink/renderer/core/mojo/mojo_discard_data_options.h"
-#include "third_party/blink/renderer/core/mojo/mojo_duplicate_buffer_handle_options.h"
-#include "third_party/blink/renderer/core/mojo/mojo_map_buffer_result.h"
-#include "third_party/blink/renderer/core/mojo/mojo_read_data_options.h"
-#include "third_party/blink/renderer/core/mojo/mojo_read_data_result.h"
-#include "third_party/blink/renderer/core/mojo/mojo_read_message_flags.h"
-#include "third_party/blink/renderer/core/mojo/mojo_read_message_result.h"
#include "third_party/blink/renderer/core/mojo/mojo_watcher.h"
-#include "third_party/blink/renderer/core/mojo/mojo_write_data_options.h"
-#include "third_party/blink/renderer/core/mojo/mojo_write_data_result.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/platform/bindings/script_state.h"
diff --git a/chromium/third_party/blink/renderer/core/mojo/mojo_handle.idl b/chromium/third_party/blink/renderer/core/mojo/mojo_handle.idl
index 4fe2ab28ad1..428236f88a8 100644
--- a/chromium/third_party/blink/renderer/core/mojo/mojo_handle.idl
+++ b/chromium/third_party/blink/renderer/core/mojo/mojo_handle.idl
@@ -15,17 +15,17 @@ callback MojoWatchCallback = void (MojoResult result);
// TODO(alokp): Create MojoMessagePipeHandle, a subclass of MojoHandle
// and move the following member functions.
MojoResult writeMessage(BufferSource buffer, sequence<MojoHandle> handles);
- MojoReadMessageResult readMessage(optional MojoReadMessageFlags flags);
+ MojoReadMessageResult readMessage(optional MojoReadMessageFlags flags = {});
// TODO(alokp): Create MojoDataPipeProducerHandle and MojoDataPipeConsumerHandle,
// subclasses of MojoHandle and move the following member functions.
- MojoWriteDataResult writeData(BufferSource buffer, optional MojoWriteDataOptions options);
+ MojoWriteDataResult writeData(BufferSource buffer, optional MojoWriteDataOptions options = {});
MojoReadDataResult queryData();
- MojoReadDataResult discardData(unsigned long numBytes, optional MojoDiscardDataOptions options);
- MojoReadDataResult readData(BufferSource buffer, optional MojoReadDataOptions options);
+ MojoReadDataResult discardData(unsigned long numBytes, optional MojoDiscardDataOptions options = {});
+ MojoReadDataResult readData(BufferSource buffer, optional MojoReadDataOptions options = {});
// TODO(alokp): Create MojoSharedBufferHandle, a subclass of MojoHandle
// and move the following member functions.
MojoMapBufferResult mapBuffer(unsigned long offset, unsigned long numBytes);
- MojoCreateSharedBufferResult duplicateBufferHandle(optional MojoDuplicateBufferHandleOptions options);
+ MojoCreateSharedBufferResult duplicateBufferHandle(optional MojoDuplicateBufferHandleOptions options = {});
};
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 3f0ec6ee1f0..b9f8e2bdcc2 100644
--- a/chromium/third_party/blink/renderer/core/mojo/mojo_watcher.cc
+++ b/chromium/third_party/blink/renderer/core/mojo/mojo_watcher.cc
@@ -6,9 +6,9 @@
#include "base/single_thread_task_runner.h"
#include "third_party/blink/public/platform/task_type.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mojo_handle_signals.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_mojo_watch_callback.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
-#include "third_party/blink/renderer/core/mojo/mojo_handle_signals.h"
#include "third_party/blink/renderer/platform/bindings/script_state.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"
@@ -49,23 +49,23 @@ MojoResult MojoWatcher::cancel() {
return MOJO_RESULT_OK;
}
-void MojoWatcher::Trace(blink::Visitor* visitor) {
+void MojoWatcher::Trace(Visitor* visitor) {
visitor->Trace(callback_);
ScriptWrappable::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
bool MojoWatcher::HasPendingActivity() const {
return handle_.is_valid();
}
-void MojoWatcher::ContextDestroyed(ExecutionContext*) {
+void MojoWatcher::ContextDestroyed() {
cancel();
}
MojoWatcher::MojoWatcher(ExecutionContext* context,
V8MojoWatchCallback* callback)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
task_runner_(context->GetTaskRunner(TaskType::kInternalDefault)),
callback_(callback) {}
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 8fc307a6aa4..1de31f7482e 100644
--- a/chromium/third_party/blink/renderer/core/mojo/mojo_watcher.h
+++ b/chromium/third_party/blink/renderer/core/mojo/mojo_watcher.h
@@ -8,7 +8,7 @@
#include "mojo/public/cpp/system/handle.h"
#include "mojo/public/cpp/system/trap.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
namespace blink {
@@ -19,7 +19,7 @@ class V8MojoWatchCallback;
class MojoWatcher final : public ScriptWrappable,
public ActiveScriptWrappable<MojoWatcher>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(MojoWatcher);
@@ -34,13 +34,13 @@ class MojoWatcher final : public ScriptWrappable,
MojoResult cancel();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// ActiveScriptWrappable
bool HasPendingActivity() const final;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) final;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() final;
private:
friend class V8MojoWatcher;
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 473044dbfb9..2251830a146 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
@@ -4,7 +4,6 @@
#include "third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/platform/platform.h"
@@ -29,7 +28,6 @@ MojoInterfaceInterceptor* MojoInterfaceInterceptor::Create(
ExecutionContext* context,
const String& interface_name,
const String& scope,
- bool use_browser_interface_broker,
ExceptionState& exception_state) {
bool process_scope = scope == "process";
if (process_scope && !context->IsDocument()) {
@@ -39,9 +37,8 @@ MojoInterfaceInterceptor* MojoInterfaceInterceptor::Create(
return nullptr;
}
- return MakeGarbageCollected<MojoInterfaceInterceptor>(
- context, interface_name, process_scope,
- UseBrowserInterfaceBroker(use_browser_interface_broker));
+ return MakeGarbageCollected<MojoInterfaceInterceptor>(context, interface_name,
+ process_scope);
}
MojoInterfaceInterceptor::~MojoInterfaceInterceptor() = default;
@@ -68,48 +65,21 @@ void MojoInterfaceInterceptor::start(ExceptionState& exception_state) {
return;
}
- if (use_browser_interface_broker_) {
- ExecutionContext* context = GetExecutionContext();
-
- if (!context)
- return;
-
- started_ = true;
- if (!context->GetBrowserInterfaceBroker().SetBinderForTesting(
- interface_name,
- WTF::BindRepeating(&MojoInterfaceInterceptor::OnInterfaceRequest,
- WrapWeakPersistent(this)))) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kInvalidModificationError,
- "Interface " + interface_name_ +
- " is already intercepted by another MojoInterfaceInterceptor.");
- }
- return;
- }
+ ExecutionContext* context = GetExecutionContext();
- // TODO(crbug.com/994843): remove when no longer used.
- service_manager::InterfaceProvider* interface_provider =
- GetInterfaceProvider();
- if (!interface_provider) {
- exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
- "The interface provider is unavailable.");
+ if (!context)
return;
- }
- service_manager::InterfaceProvider::TestApi test_api(interface_provider);
- if (test_api.HasBinderForName(interface_name)) {
+ started_ = true;
+ if (!context->GetBrowserInterfaceBroker().SetBinderForTesting(
+ interface_name,
+ WTF::BindRepeating(&MojoInterfaceInterceptor::OnInterfaceRequest,
+ WrapWeakPersistent(this)))) {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidModificationError,
"Interface " + interface_name_ +
" is already intercepted by another MojoInterfaceInterceptor.");
- return;
}
-
- started_ = true;
- test_api.SetBinderForName(
- interface_name,
- WTF::BindRepeating(&MojoInterfaceInterceptor::OnInterfaceRequest,
- WrapWeakPersistent(this)));
}
void MojoInterfaceInterceptor::stop() {
@@ -125,25 +95,14 @@ void MojoInterfaceInterceptor::stop() {
return;
}
- if (use_browser_interface_broker_) {
- ExecutionContext* context = GetExecutionContext();
- DCHECK(context);
- context->GetBrowserInterfaceBroker().SetBinderForTesting(interface_name,
- {});
- return;
- }
-
- // TODO(crbug.com/994843): remove when no longer used.
- // GetInterfaceProvider() is guaranteed not to return nullptr because this
- // method is called when the context is destroyed.
- service_manager::InterfaceProvider::TestApi test_api(GetInterfaceProvider());
- DCHECK(test_api.HasBinderForName(interface_name));
- test_api.ClearBinderForName(interface_name);
+ ExecutionContext* context = GetExecutionContext();
+ DCHECK(context);
+ context->GetBrowserInterfaceBroker().SetBinderForTesting(interface_name, {});
}
-void MojoInterfaceInterceptor::Trace(blink::Visitor* visitor) {
+void MojoInterfaceInterceptor::Trace(Visitor* visitor) {
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
const AtomicString& MojoInterfaceInterceptor::InterfaceName() const {
@@ -151,40 +110,28 @@ const AtomicString& MojoInterfaceInterceptor::InterfaceName() const {
}
ExecutionContext* MojoInterfaceInterceptor::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
bool MojoInterfaceInterceptor::HasPendingActivity() const {
return started_;
}
-void MojoInterfaceInterceptor::ContextDestroyed(ExecutionContext*) {
+void MojoInterfaceInterceptor::ContextDestroyed() {
stop();
}
-MojoInterfaceInterceptor::MojoInterfaceInterceptor(
- ExecutionContext* context,
- const String& interface_name,
- bool process_scope,
- UseBrowserInterfaceBroker use_browser_interface_broker)
- : ContextLifecycleObserver(context),
+MojoInterfaceInterceptor::MojoInterfaceInterceptor(ExecutionContext* context,
+ const String& interface_name,
+ bool process_scope)
+ : ExecutionContextLifecycleObserver(context),
interface_name_(interface_name),
- process_scope_(process_scope),
- use_browser_interface_broker_(use_browser_interface_broker) {}
-
-service_manager::InterfaceProvider*
-MojoInterfaceInterceptor::GetInterfaceProvider() const {
- ExecutionContext* context = GetExecutionContext();
- if (!context)
- return nullptr;
-
- return context->GetInterfaceProvider();
-}
+ process_scope_(process_scope) {}
void MojoInterfaceInterceptor::OnInterfaceRequest(
mojo::ScopedMessagePipeHandle handle) {
// Execution of JavaScript may be forbidden in this context as this method is
- // called synchronously by the InterfaceProvider. Dispatching of the
+ // called synchronously by the BrowserInterfaceBroker. Dispatching of the
// 'interfacerequest' event is therefore scheduled to take place in the next
// microtask. This also more closely mirrors the behavior when an interface
// request is being satisfied by another process.
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 010d146b816..c45bfdcc387 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
@@ -10,14 +10,10 @@
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/core/dom/events/event_listener.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-namespace service_manager {
-class InterfaceProvider;
-}
-
namespace blink {
class ExceptionState;
@@ -32,7 +28,7 @@ class ExecutionContext;
class MojoInterfaceInterceptor final
: public EventTargetWithInlineData,
public ActiveScriptWrappable<MojoInterfaceInterceptor>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(MojoInterfaceInterceptor);
@@ -40,16 +36,11 @@ class MojoInterfaceInterceptor final
static MojoInterfaceInterceptor* Create(ExecutionContext*,
const String& interface_name,
const String& scope,
- bool use_browser_interface_broker,
ExceptionState&);
- using UseBrowserInterfaceBroker =
- util::StrongAlias<class UseBrowserInterfaceBrokerTag, bool>;
- MojoInterfaceInterceptor(
- ExecutionContext*,
- const String& interface_name,
- bool process_scope,
- UseBrowserInterfaceBroker use_browser_interface_broker);
+ MojoInterfaceInterceptor(ExecutionContext*,
+ const String& interface_name,
+ bool process_scope);
~MojoInterfaceInterceptor() override;
void start(ExceptionState&);
@@ -57,7 +48,7 @@ class MojoInterfaceInterceptor final
DEFINE_ATTRIBUTE_EVENT_LISTENER(interfacerequest, kInterfacerequest)
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// EventTargetWithInlineData
const AtomicString& InterfaceName() const override;
@@ -66,18 +57,16 @@ class MojoInterfaceInterceptor final
// ActiveScriptWrappable
bool HasPendingActivity() const final;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) final;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() final;
private:
- service_manager::InterfaceProvider* GetInterfaceProvider() const;
void OnInterfaceRequest(mojo::ScopedMessagePipeHandle);
void DispatchInterfaceRequestEvent(mojo::ScopedMessagePipeHandle);
const String interface_name_;
bool started_ = false;
bool process_scope_ = false;
- bool use_browser_interface_broker_ = false;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.idl b/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.idl
index e50fcf3aee9..075783322e9 100644
--- a/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.idl
+++ b/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.idl
@@ -4,13 +4,10 @@
[
ActiveScriptWrappable,
- Constructor(DOMString interfaceName, optional MojoScope scope = "context",
- optional boolean useBrowserInterfaceBroker = false),
- ConstructorCallWith=ExecutionContext,
Exposed=(Window,Worker),
- RaisesException=Constructor,
RuntimeEnabled=MojoJSTest
] interface MojoInterfaceInterceptor : EventTarget {
+ [CallWith=ExecutionContext, RaisesException] constructor(DOMString interfaceName, optional MojoScope scope = "context");
[RaisesException] void start();
void stop();
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 70587940e03..1356522ce63 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
@@ -4,15 +4,15 @@
#include "third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mojo_interface_request_event_init.h"
#include "third_party/blink/renderer/core/event_type_names.h"
#include "third_party/blink/renderer/core/mojo/mojo_handle.h"
-#include "third_party/blink/renderer/core/mojo/test/mojo_interface_request_event_init.h"
namespace blink {
MojoInterfaceRequestEvent::~MojoInterfaceRequestEvent() = default;
-void MojoInterfaceRequestEvent::Trace(blink::Visitor* visitor) {
+void MojoInterfaceRequestEvent::Trace(Visitor* visitor) {
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 c67cf9af86a..7427b07786d 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<MojoHandle> handle_;
diff --git a/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.idl b/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.idl
index 9d96d25693f..3a0ceac0954 100644
--- a/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.idl
+++ b/chromium/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.idl
@@ -3,9 +3,9 @@
// found in the LICENSE file.
[
- Constructor(DOMString type, optional MojoInterfaceRequestEventInit eventInitDict),
Exposed=(Window,Worker),
RuntimeEnabled=MojoJSTest
] interface MojoInterfaceRequestEvent : Event {
+ constructor(DOMString type, optional MojoInterfaceRequestEventInit eventInitDict = {});
readonly attribute 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 7a309ade4e1..cbef632e65e 100644
--- a/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc
+++ b/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc
@@ -7,12 +7,15 @@
#include <memory>
#include <utility>
+#include "base/metrics/histogram_functions.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/core/css/css_font_selector.h"
#include "third_party/blink/renderer/core/css/offscreen_font_selector.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/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.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"
@@ -42,6 +45,27 @@ OffscreenCanvas::OffscreenCanvas(ExecutionContext* context, const IntSize& size)
CanvasRenderingContextHost::HostType::kOffscreenCanvasHost),
execution_context_(context),
size_(size) {
+ // Other code in Blink watches for destruction of the context; be
+ // robust here as well.
+ if (!context->IsContextDestroyed()) {
+ if (context->IsDocument()) {
+ // If this OffscreenCanvas is being created in the context of a
+ // cross-origin iframe, it should prefer to use the low-power GPU.
+ LocalFrame* frame = Document::From(context)->GetFrame();
+ if (!(frame && frame->IsCrossOriginToMainFrame())) {
+ AllowHighPerformancePowerPreference();
+ }
+ } else if (context->IsDedicatedWorkerGlobalScope()) {
+ // Per spec, dedicated workers can only load same-origin top-level
+ // scripts, so grant them access to the high-performance GPU.
+ //
+ // TODO(crbug.com/1050739): refine this logic. If the worker was
+ // spawned from an iframe, keep track of whether that iframe was
+ // itself cross-origin.
+ AllowHighPerformancePowerPreference();
+ }
+ }
+
UpdateMemoryUsage();
}
@@ -220,12 +244,16 @@ ScriptPromise OffscreenCanvas::CreateImageBitmap(
ScriptState* script_state,
EventTarget&,
base::Optional<IntRect> crop_rect,
- const ImageBitmapOptions* options) {
+ const ImageBitmapOptions* options,
+ ExceptionState& exception_state) {
if (context_)
context_->FinalizeFrame();
return ImageBitmapSource::FulfillImageBitmap(
script_state,
- IsPaintable() ? ImageBitmap::Create(this, crop_rect, options) : nullptr);
+ IsPaintable()
+ ? MakeGarbageCollected<ImageBitmap>(this, crop_rect, options)
+ : nullptr,
+ exception_state);
}
bool OffscreenCanvas::IsOpaque() const {
@@ -349,38 +377,56 @@ CanvasResourceProvider* OffscreenCanvas::GetOrCreateResourceProvider() {
}
IntSize surface_size(width(), height());
- CanvasResourceProvider::ResourceUsage usage;
- if (can_use_gpu) {
- if (HasPlaceholderCanvas()) {
- usage = CanvasResourceProvider::ResourceUsage::
- kAcceleratedCompositedResourceUsage;
- } else {
- usage =
- CanvasResourceProvider::ResourceUsage::kAcceleratedResourceUsage;
- }
- } else {
- if (HasPlaceholderCanvas()) {
- usage = CanvasResourceProvider::ResourceUsage::
- kSoftwareCompositedResourceUsage;
- } else {
- usage = CanvasResourceProvider::ResourceUsage::kSoftwareResourceUsage;
- }
- }
-
base::WeakPtr<CanvasResourceDispatcher> dispatcher_weakptr =
HasPlaceholderCanvas() ? GetOrCreateResourceDispatcher()->GetWeakPtr()
: nullptr;
+ std::unique_ptr<CanvasResourceProvider> provider;
+ // kAcceleratedCompositedResourceUsage and kSoftwareCompositedResourceUsage
+ // still need to use the Create method for CanvasResourceProvider.
+ // The former kAcceleratedResourceUsage and kSoftwareResourceUsage have been
+ // replaced by two different constructors (one of sharedImage witt the
+ // fallback to bitmap, and the other one to bitmap)
+ // This is still WIP and more changes will come in upcoming CLs.
+ if (can_use_gpu && HasPlaceholderCanvas()) {
+ provider = CanvasResourceProvider::Create(
+ surface_size,
+ CanvasResourceProvider::ResourceUsage::
+ kAcceleratedCompositedResourceUsage,
+ SharedGpuContext::ContextProviderWrapper(), 0, FilterQuality(),
+ context_->ColorParams(), presentation_mode,
+ std::move(dispatcher_weakptr), false /*is_origin_top_left*/);
+ } else if (!can_use_gpu && HasPlaceholderCanvas()) {
+ provider = CanvasResourceProvider::Create(
+ surface_size,
+ CanvasResourceProvider::ResourceUsage::
+ kSoftwareCompositedResourceUsage,
+ SharedGpuContext::ContextProviderWrapper(), 0, FilterQuality(),
+ context_->ColorParams(), presentation_mode,
+ std::move(dispatcher_weakptr), false /*is_origin_top_left=*/);
+ } else if (can_use_gpu) {
+ provider = CanvasResourceProvider::CreateSharedImageProvider(
+ surface_size, SharedGpuContext::ContextProviderWrapper(),
+ FilterQuality(), context_->ColorParams(),
+ false /*is_origin_top_left*/,
+ CanvasResourceProvider::RasterMode::kGPU,
+ 0u /*shared_image_usage_flags*/);
+
+ } // else will try the BitmapProvider
+
+ if (!provider) {
+ provider = CanvasResourceProvider::CreateBitmapProvider(
+ surface_size, FilterQuality(), context_->ColorParams());
+ }
- ReplaceResourceProvider(CanvasResourceProvider::CreateForCanvas(
- surface_size, usage, SharedGpuContext::ContextProviderWrapper(), 0,
- FilterQuality(), context_->ColorParams(), presentation_mode,
- std::move(dispatcher_weakptr), false /* is_origin_top_left */));
+ ReplaceResourceProvider(std::move(provider));
if (ResourceProvider() && ResourceProvider()->IsValid()) {
+ base::UmaHistogramBoolean("Blink.Canvas.ResourceProviderIsAccelerated",
+ ResourceProvider()->IsAccelerated());
+ base::UmaHistogramEnumeration("Blink.Canvas.ResourceProviderType",
+ ResourceProvider()->GetType());
ResourceProvider()->Clear();
- // Always save an initial frame, to support resetting the top level matrix
- // and clip.
- ResourceProvider()->Canvas()->save();
+ DidDraw();
if (needs_matrix_clip_restore_) {
needs_matrix_clip_restore_ = false;
@@ -454,7 +500,7 @@ bool OffscreenCanvas::ShouldAccelerate2dContext() const {
}
FontSelector* OffscreenCanvas::GetFontSelector() {
- if (auto* document = DynamicTo<Document>(GetExecutionContext())) {
+ if (auto* document = Document::DynamicFrom(GetExecutionContext())) {
return document->GetStyleEngine().GetFontSelector();
}
return To<WorkerGlobalScope>(GetExecutionContext())->GetFontSelector();
@@ -474,7 +520,7 @@ void OffscreenCanvas::UpdateMemoryUsage() {
memory_usage_ = new_memory_usage;
}
-void OffscreenCanvas::Trace(blink::Visitor* visitor) {
+void OffscreenCanvas::Trace(Visitor* visitor) {
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 3fa1bec8da5..1f0b8a53b59 100644
--- a/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h
+++ b/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h
@@ -6,12 +6,12 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_OFFSCREENCANVAS_OFFSCREEN_CANVAS_H_
#include <memory>
+
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h"
#include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
-#include "third_party/blink/renderer/core/html/canvas/image_encode_options.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap_source.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -155,14 +155,16 @@ class CORE_EXPORT OffscreenCanvas final
ScriptPromise CreateImageBitmap(ScriptState*,
EventTarget&,
base::Optional<IntRect>,
- const ImageBitmapOptions*) final;
+ const ImageBitmapOptions*,
+ ExceptionState&) 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) const final {
+ FloatSize ElementSize(const FloatSize& default_object_size,
+ const RespectImageOrientationEnum) const final {
return FloatSize(width(), height());
}
bool IsOpaque() const final;
@@ -178,7 +180,7 @@ class CORE_EXPORT OffscreenCanvas final
FontSelector* GetFontSelector() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
class ScopedInsideWorkerRAF {
STACK_ALLOCATED();
diff --git a/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.idl b/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.idl
index 0890b3be942..5dcd665caa4 100644
--- a/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.idl
+++ b/chromium/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.idl
@@ -5,16 +5,14 @@
// https://html.spec.whatwg.org/C/#the-offscreencanvas-interface
[
- Constructor([EnforceRange] unsigned long width, [EnforceRange] unsigned long height),
Exposed=(Window,Worker),
Transferable,
- ConstructorCallWith=ExecutionContext,
- MeasureAs=OffscreenCanvas,
RuntimeEnabled=SurfaceEmbeddingFeatures
] interface OffscreenCanvas : EventTarget {
+ [CallWith=ExecutionContext, MeasureAs=OffscreenCanvas] constructor([EnforceRange] unsigned long width, [EnforceRange] unsigned long height);
attribute [EnforceRange] unsigned long width;
attribute [EnforceRange] unsigned long height;
[CallWith=ScriptState, HighEntropy, MeasureAs=OffscreenCanvasTransferToImageBitmap, RaisesException] ImageBitmap transferToImageBitmap();
- [CallWith=ScriptState, HighEntropy, MeasureAs=OffscreenCanvasConvertToBlob, RaisesException] Promise<Blob> convertToBlob(optional ImageEncodeOptions options);
+ [CallWith=ScriptState, HighEntropy, MeasureAs=OffscreenCanvasConvertToBlob, RaisesException] Promise<Blob> convertToBlob(optional ImageEncodeOptions options = {});
};
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 95aaf0f19a2..37f0b2c2cfb 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,7 +4,9 @@
#include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h"
+#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/origin_trials/trial_token.h"
#include "third_party/blink/public/common/origin_trials/trial_token_validator.h"
#include "third_party/blink/public/platform/platform.h"
@@ -15,10 +17,12 @@
#include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.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/origin_trials/origin_trials.h"
#include "third_party/blink/renderer/core/workers/worklet_global_scope.h"
#include "third_party/blink/renderer/platform/bindings/origin_trial_features.h"
+#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -31,12 +35,8 @@ namespace blink {
namespace {
-static EnumerationHistogram& TokenValidationResultHistogram() {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- EnumerationHistogram, histogram,
- ("OriginTrials.ValidationResult",
- static_cast<int>(OriginTrialTokenStatus::kLast)));
- return histogram;
+void RecordTokenValidationResultHistogram(OriginTrialTokenStatus status) {
+ UMA_HISTOGRAM_ENUMERATION("OriginTrials.ValidationResult", status);
}
bool IsWhitespace(UChar chr) {
@@ -238,7 +238,7 @@ void OriginTrialContext::ActivateNavigationFeaturesFromInitiator(
void OriginTrialContext::InitializePendingFeatures() {
if (!enabled_features_.size() && !navigation_activated_features_.size())
return;
- auto* document = DynamicTo<Document>(context_.Get());
+ auto* document = Document::DynamicFrom(context_.Get());
if (!document)
return;
LocalFrame* frame = document->GetFrame();
@@ -283,7 +283,8 @@ bool OriginTrialContext::IsFeatureEnabled(OriginTrialFeature feature) const {
// 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.
- auto* document = DynamicTo<Document>(context_.Get());
+ auto* window = DynamicTo<LocalDOMWindow>(context_.Get());
+ auto* document = window ? window->document() : nullptr;
if (!document || !document->IsHTMLImport())
return false;
@@ -294,28 +295,95 @@ bool OriginTrialContext::IsFeatureEnabled(OriginTrialFeature feature) const {
return context->IsFeatureEnabled(feature);
}
+base::Time OriginTrialContext::GetFeatureExpiry(OriginTrialFeature feature) {
+ if (!IsFeatureEnabled(feature))
+ return base::Time();
+
+ auto it = feature_expiry_times_.find(feature);
+ if (it == feature_expiry_times_.end())
+ return base::Time();
+
+ return it->value;
+}
+
bool OriginTrialContext::IsNavigationFeatureActivated(
OriginTrialFeature feature) const {
return navigation_activated_features_.Contains(feature);
}
+void OriginTrialContext::AddForceEnabledTrials(
+ const Vector<String>& trial_names) {
+ bool is_valid = false;
+ for (const auto& trial_name : trial_names) {
+ DCHECK(origin_trials::IsTrialValid(trial_name));
+ is_valid |=
+ EnableTrialFromName(trial_name, /*expiry_time=*/base::Time::Max());
+ }
+
+ if (is_valid) {
+ // Only install pending features if at least one trial is valid. Otherwise
+ // there was no change to the list of enabled features.
+ InitializePendingFeatures();
+ }
+}
+
+bool OriginTrialContext::CanEnableTrialFromName(const StringView& trial_name) {
+ if (trial_name == "Portals" &&
+ !base::FeatureList::IsEnabled(features::kPortals)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool OriginTrialContext::EnableTrialFromName(const String& trial_name,
+ base::Time expiry_time) {
+ bool did_enable_feature = false;
+ for (OriginTrialFeature feature :
+ origin_trials::FeaturesForTrial(trial_name)) {
+ if (!origin_trials::FeatureEnabledForOS(feature))
+ continue;
+
+ if (!CanEnableTrialFromName(trial_name))
+ continue;
+
+ did_enable_feature = true;
+ enabled_features_.insert(feature);
+
+ // Use the latest expiry time for the feature.
+ if (GetFeatureExpiry(feature) < expiry_time)
+ feature_expiry_times_.Set(feature, expiry_time);
+
+ // Also enable any features implied by this feature.
+ for (OriginTrialFeature implied_feature :
+ origin_trials::GetImpliedFeatures(feature)) {
+ enabled_features_.insert(implied_feature);
+
+ // Use the latest expiry time for the implied feature.
+ if (GetFeatureExpiry(implied_feature) < expiry_time)
+ feature_expiry_times_.Set(implied_feature, expiry_time);
+ }
+ }
+ return did_enable_feature;
+}
+
bool OriginTrialContext::EnableTrialFromToken(const SecurityOrigin* origin,
bool is_secure,
const String& token) {
DCHECK(!token.IsEmpty());
if (!trial_token_validator_) {
- TokenValidationResultHistogram().Count(
- static_cast<int>(OriginTrialTokenStatus::kNotSupported));
+ RecordTokenValidationResultHistogram(OriginTrialTokenStatus::kNotSupported);
return false;
}
bool valid = false;
StringUTF8Adaptor token_string(token);
std::string trial_name_str;
+ base::Time expiry_time;
OriginTrialTokenStatus token_result = trial_token_validator_->ValidateToken(
- token_string.AsStringPiece(), origin->ToUrlOrigin(), &trial_name_str,
- base::Time::Now());
+ token_string.AsStringPiece(), origin->ToUrlOrigin(), base::Time::Now(),
+ &trial_name_str, &expiry_time);
if (token_result == OriginTrialTokenStatus::kSuccess) {
String trial_name =
String::FromUTF8(trial_name_str.data(), trial_name_str.size());
@@ -324,18 +392,7 @@ bool OriginTrialContext::EnableTrialFromToken(const SecurityOrigin* origin,
// is for deprecation trials.
if (is_secure ||
origin_trials::IsTrialEnabledForInsecureContext(trial_name)) {
- for (OriginTrialFeature feature :
- origin_trials::FeaturesForTrial(trial_name)) {
- if (origin_trials::FeatureEnabledForOS(feature)) {
- valid = true;
- enabled_features_.insert(feature);
- // Also enable any features implied by this feature.
- for (OriginTrialFeature implied_feature :
- origin_trials::GetImpliedFeatures(feature)) {
- enabled_features_.insert(implied_feature);
- }
- }
- }
+ valid = EnableTrialFromName(trial_name, expiry_time);
} else {
// Insecure origin and trial is restricted to secure origins.
token_result = OriginTrialTokenStatus::kInsecure;
@@ -343,11 +400,11 @@ bool OriginTrialContext::EnableTrialFromToken(const SecurityOrigin* origin,
}
}
- TokenValidationResultHistogram().Count(static_cast<int>(token_result));
+ RecordTokenValidationResultHistogram(token_result);
return valid;
}
-void OriginTrialContext::Trace(blink::Visitor* visitor) {
+void OriginTrialContext::Trace(Visitor* visitor) {
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 ecf41cc05ec..c4b6352fa64 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
@@ -17,6 +17,7 @@
namespace blink {
class ExecutionContext;
+class ScriptState;
// The Origin Trials Framework provides limited access to experimental features,
// on a per-origin basis (origin trials). This class provides the implementation
@@ -84,10 +85,20 @@ class CORE_EXPORT OriginTrialContext final
// and immediately adds required bindings to already initialized JS contexts.
void AddFeature(OriginTrialFeature feature);
+ // Forces given trials to be enabled in this context and immediately adds
+ // required bindings to already initialized JS contexts.
+ void AddForceEnabledTrials(const Vector<String>& trial_names);
+
// Returns true if the feature should be considered enabled for the current
// execution context.
bool IsFeatureEnabled(OriginTrialFeature feature) const;
+ // Gets the latest expiry time of all valid tokens that enable |feature|. If
+ // there are no valid tokens enabling the feature, this will return the null
+ // time (base::Time()). Note: This will only find expiry times for features
+ // backed by a token, so will not work for features enabled via |AddFeature|.
+ base::Time GetFeatureExpiry(OriginTrialFeature feature);
+
std::unique_ptr<Vector<OriginTrialFeature>> GetEnabledNavigationFeatures()
const;
@@ -109,9 +120,17 @@ class CORE_EXPORT OriginTrialContext final
// enabled.
void InitializePendingFeatures();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
+ // 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);
+
+ // Enable features by trial name. Returns true or false to indicate whether
+ // some features are enabled as the result.
+ bool EnableTrialFromName(const String& trial_name, base::Time expiry_time);
+
// Validate the trial token. If valid, the trial named in the token is
// added to the list of enabled trials. Returns true or false to indicate if
// the token is valid.
@@ -130,6 +149,7 @@ class CORE_EXPORT OriginTrialContext final
HashSet<OriginTrialFeature> enabled_features_;
HashSet<OriginTrialFeature> installed_features_;
HashSet<OriginTrialFeature> navigation_activated_features_;
+ WTF::HashMap<OriginTrialFeature, base::Time> feature_expiry_times_;
std::unique_ptr<TrialTokenValidator> trial_token_validator_;
Member<ExecutionContext> context_;
};
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 80f6df182ea..64061494a4b 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
@@ -48,24 +48,30 @@ class MockTokenValidator : public TrialTokenValidator {
// blink::WebTrialTokenValidator implementation
OriginTrialTokenStatus ValidateToken(base::StringPiece token,
const url::Origin& origin,
+ base::Time current_time,
std::string* feature_name,
- base::Time current_time) const override {
+ base::Time* expiry_time) const override {
call_count_++;
*feature_name = feature_;
+ *expiry_time = expiry_;
return response_;
}
// Useful methods for controlling the validator
void SetResponse(OriginTrialTokenStatus response,
- const std::string& feature) {
+ const std::string& feature,
+ base::Time expiry = base::Time()) {
response_ = response;
feature_ = feature;
+ expiry_ = expiry;
}
int CallCount() { return call_count_; }
private:
OriginTrialTokenStatus response_;
std::string feature_;
+ base::Time expiry_;
+
mutable int call_count_;
DISALLOW_COPY_AND_ASSIGN(MockTokenValidator);
@@ -88,18 +94,30 @@ class OriginTrialContextTest : public testing::Test {
KURL page_url(origin);
scoped_refptr<SecurityOrigin> page_origin =
SecurityOrigin::Create(page_url);
- execution_context_->SetSecurityOrigin(page_origin);
- execution_context_->SetIsSecureContext(SecurityOrigin::IsSecure(page_url));
+ execution_context_->GetSecurityContext().SetSecurityOrigin(page_origin);
+ execution_context_->GetSecurityContext().SetSecureContextModeForTesting(
+ SecurityOrigin::IsSecure(page_url)
+ ? SecureContextMode::kSecureContext
+ : SecureContextMode::kInsecureContext);
}
bool IsFeatureEnabled(const String& origin, OriginTrialFeature feature) {
UpdateSecurityOrigin(origin);
+ return IsFeatureEnabled(feature);
+ }
+
+ bool IsFeatureEnabled(OriginTrialFeature feature) {
// Need at least one token to ensure the token validator is called.
execution_context_->GetOriginTrialContext()->AddToken(kTokenPlaceholder);
return execution_context_->GetOriginTrialContext()->IsFeatureEnabled(
feature);
}
+ base::Time GetFeatureExpiry(OriginTrialFeature feature) {
+ return execution_context_->GetOriginTrialContext()->GetFeatureExpiry(
+ feature);
+ }
+
std::unique_ptr<Vector<OriginTrialFeature>> GetEnabledNavigationFeatures() {
return execution_context_->GetOriginTrialContext()
->GetEnabledNavigationFeatures();
@@ -298,7 +316,7 @@ TEST_F(OriginTrialContextTest, FeaturePolicy) {
// Make a mock feature name map with "frobulate".
FeatureNameMap feature_map;
- feature_map.Set("frobulate", mojom::FeaturePolicyFeature::kFrobulate);
+ feature_map.Set("frobulate", mojom::blink::FeaturePolicyFeature::kFrobulate);
// Attempt to parse the "frobulate" feature policy. This will only work if the
// feature policy is successfully enabled via the origin trial.
@@ -310,7 +328,7 @@ TEST_F(OriginTrialContextTest, FeaturePolicy) {
&messages, feature_map, document);
EXPECT_TRUE(messages.IsEmpty());
ASSERT_EQ(1u, result.size());
- EXPECT_EQ(mojom::FeaturePolicyFeature::kFrobulate, result[0].feature);
+ EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFrobulate, result[0].feature);
}
TEST_F(OriginTrialContextTest, GetEnabledNavigationFeatures) {
@@ -334,4 +352,71 @@ TEST_F(OriginTrialContextTest, ActivateNavigationFeature) {
ActivateNavigationFeature(OriginTrialFeature::kOriginTrialsSampleAPI));
}
+TEST_F(OriginTrialContextTest, GetTokenExpiryTimeIgnoresIrrelevantTokens) {
+ UpdateSecurityOrigin(kFrobulateEnabledOrigin);
+
+ base::Time nowish = base::Time::Now();
+ // A non-success response shouldn't affect Frobulate's expiry time.
+ TokenValidator()->SetResponse(OriginTrialTokenStatus::kMalformed,
+ kFrobulateTrialName,
+ nowish + base::TimeDelta::FromDays(2));
+ EXPECT_FALSE(IsFeatureEnabled(OriginTrialFeature::kOriginTrialsSampleAPI));
+ EXPECT_EQ(base::Time(),
+ GetFeatureExpiry(OriginTrialFeature::kOriginTrialsSampleAPI));
+
+ // A different trial shouldn't affect Frobulate's expiry time.
+ TokenValidator()->SetResponse(OriginTrialTokenStatus::kSuccess,
+ kFrobulateDeprecationTrialName,
+ nowish + base::TimeDelta::FromDays(3));
+ EXPECT_TRUE(
+ IsFeatureEnabled(OriginTrialFeature::kOriginTrialsSampleAPIDeprecation));
+ EXPECT_EQ(base::Time(),
+ GetFeatureExpiry(OriginTrialFeature::kOriginTrialsSampleAPI));
+
+ // A valid trial should update the expiry time.
+ base::Time expected_expiry = nowish + base::TimeDelta::FromDays(1);
+ TokenValidator()->SetResponse(OriginTrialTokenStatus::kSuccess,
+ kFrobulateTrialName, expected_expiry);
+ EXPECT_TRUE(IsFeatureEnabled(OriginTrialFeature::kOriginTrialsSampleAPI));
+ EXPECT_EQ(expected_expiry,
+ GetFeatureExpiry(OriginTrialFeature::kOriginTrialsSampleAPI));
+}
+
+TEST_F(OriginTrialContextTest, LastExpiryForFeatureIsUsed) {
+ UpdateSecurityOrigin(kFrobulateEnabledOrigin);
+
+ base::Time plusone = base::Time::Now() + base::TimeDelta::FromDays(1);
+ base::Time plustwo = plusone + base::TimeDelta::FromDays(1);
+ base::Time plusthree = plustwo + base::TimeDelta::FromDays(1);
+
+ TokenValidator()->SetResponse(OriginTrialTokenStatus::kSuccess,
+ kFrobulateTrialName, plusone);
+ EXPECT_TRUE(IsFeatureEnabled(OriginTrialFeature::kOriginTrialsSampleAPI));
+ EXPECT_EQ(plusone,
+ GetFeatureExpiry(OriginTrialFeature::kOriginTrialsSampleAPI));
+
+ TokenValidator()->SetResponse(OriginTrialTokenStatus::kSuccess,
+ kFrobulateTrialName, plusthree);
+ EXPECT_TRUE(IsFeatureEnabled(OriginTrialFeature::kOriginTrialsSampleAPI));
+ EXPECT_EQ(plusthree,
+ GetFeatureExpiry(OriginTrialFeature::kOriginTrialsSampleAPI));
+
+ TokenValidator()->SetResponse(OriginTrialTokenStatus::kSuccess,
+ kFrobulateTrialName, plustwo);
+ EXPECT_TRUE(IsFeatureEnabled(OriginTrialFeature::kOriginTrialsSampleAPI));
+ EXPECT_EQ(plusthree,
+ GetFeatureExpiry(OriginTrialFeature::kOriginTrialsSampleAPI));
+}
+
+TEST_F(OriginTrialContextTest, ImpliedFeatureExpiryTimesAreUpdated) {
+ UpdateSecurityOrigin(kFrobulateEnabledOrigin);
+
+ base::Time tomorrow = base::Time::Now() + base::TimeDelta::FromDays(1);
+ TokenValidator()->SetResponse(OriginTrialTokenStatus::kSuccess,
+ kFrobulateTrialName, tomorrow);
+ EXPECT_TRUE(IsFeatureEnabled(OriginTrialFeature::kOriginTrialsSampleAPI));
+ EXPECT_EQ(tomorrow, GetFeatureExpiry(
+ OriginTrialFeature::kOriginTrialsSampleAPIImplied));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/origin_trials/origin_trials.h b/chromium/third_party/blink/renderer/core/origin_trials/origin_trials.h
index 2ea45657f01..a2973300261 100644
--- a/chromium/third_party/blink/renderer/core/origin_trials/origin_trials.h
+++ b/chromium/third_party/blink/renderer/core/origin_trials/origin_trials.h
@@ -7,10 +7,11 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ORIGIN_TRIALS_ORIGIN_TRIALS_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_ORIGIN_TRIALS_ORIGIN_TRIALS_H_
+#include "base/containers/span.h"
#include "third_party/blink/renderer/core/core_export.h"
#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/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_view.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
@@ -22,10 +23,10 @@ enum class OriginTrialType { kDefault = 0, kDeprecation, kIntervention };
namespace origin_trials {
// Return true if there is a feature with the passed |trial_name|.
-CORE_EXPORT bool IsTrialValid(const String& trial_name);
+CORE_EXPORT bool IsTrialValid(const StringView& trial_name);
// Return true if |trial_name| can be enabled in an insecure context.
-CORE_EXPORT bool IsTrialEnabledForInsecureContext(const String& trial_name);
+CORE_EXPORT bool IsTrialEnabledForInsecureContext(const StringView& trial_name);
// Returns the trial type of the given |feature|.
CORE_EXPORT OriginTrialType GetTrialType(OriginTrialFeature feature);
@@ -33,12 +34,13 @@ CORE_EXPORT OriginTrialType GetTrialType(OriginTrialFeature feature);
// Return origin trials features that are enabled by the passed |trial_name|.
// The trial name MUST be valid (call IsTrialValid() before calling this
// function).
-CORE_EXPORT const Vector<OriginTrialFeature>& FeaturesForTrial(
- const String& trial_name);
+CORE_EXPORT base::span<const OriginTrialFeature> FeaturesForTrial(
+ const StringView& trial_name);
// Return the list of features which will also be enabled if the given
// |feature| is enabled.
-Vector<OriginTrialFeature> GetImpliedFeatures(OriginTrialFeature feature);
+base::span<const OriginTrialFeature> GetImpliedFeatures(
+ OriginTrialFeature feature);
bool FeatureEnabledForOS(OriginTrialFeature feature);
diff --git a/chromium/third_party/blink/renderer/core/page/BUILD.gn b/chromium/third_party/blink/renderer/core/page/BUILD.gn
index 9c440eeb656..b5c6f949729 100644
--- a/chromium/third_party/blink/renderer/core/page/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/page/BUILD.gn
@@ -12,6 +12,8 @@ blink_core_sources("page") {
"chrome_client.h",
"chrome_client_impl.cc",
"chrome_client_impl.h",
+ "color_page_popup_controller.cc",
+ "color_page_popup_controller.h",
"context_menu_controller.cc",
"context_menu_controller.h",
"context_menu_provider.h",
@@ -47,8 +49,7 @@ blink_core_sources("page") {
"page_popup_controller.h",
"page_popup_supplement.cc",
"page_popup_supplement.h",
- "page_visibility_notifier.cc",
- "page_visibility_notifier.h",
+ "page_visibility_observer.cc",
"page_visibility_observer.h",
"page_widget_delegate.cc",
"page_widget_delegate.h",
@@ -81,7 +82,6 @@ blink_core_sources("page") {
"scrolling/scroll_state_callback.h",
"scrolling/scrolling_coordinator.cc",
"scrolling/scrolling_coordinator.h",
- "scrolling/scrolling_coordinator_context.cc",
"scrolling/scrolling_coordinator_context.h",
"scrolling/snap_coordinator.cc",
"scrolling/snap_coordinator.h",
@@ -115,4 +115,6 @@ blink_core_sources("page") {
"viewport_description.cc",
"viewport_description.h",
]
+
+ public_deps = [ "//ui/base/cursor" ]
}
diff --git a/chromium/third_party/blink/renderer/core/page/DEPS b/chromium/third_party/blink/renderer/core/page/DEPS
index a45c5f7cb81..3799876c3c8 100644
--- a/chromium/third_party/blink/renderer/core/page/DEPS
+++ b/chromium/third_party/blink/renderer/core/page/DEPS
@@ -2,3 +2,9 @@ include_rules = [
# For validation_message_overlay_delegate_test.cc
"+base/strings/utf_string_conversions.h",
]
+
+specific_include_rules = {
+ "chrome_client_impl_test\.cc": [
+ "+base/run_loop.h",
+ ],
+}
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 633a65bc631..aee12d467d5 100644
--- a/chromium/third_party/blink/renderer/core/page/autoscroll_controller.cc
+++ b/chromium/third_party/blink/renderer/core/page/autoscroll_controller.cc
@@ -31,13 +31,16 @@
#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/html/html_frame_owner_element.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
-#include "third_party/blink/renderer/core/layout/layout_list_box.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/scroll/scroll_types.h"
+#include "third_party/blink/renderer/platform/cursors.h"
+#include "ui/base/cursor/cursor.h"
namespace blink {
@@ -47,15 +50,16 @@ constexpr base::TimeDelta kAutoscrollDelay = base::TimeDelta::FromSecondsD(0.2);
static const int kNoMiddleClickAutoscrollRadius = 15;
-static const Cursor& MiddleClickAutoscrollCursor(const FloatSize& velocity,
- bool scroll_vert,
- bool scroll_horiz) {
+static const ui::Cursor& MiddleClickAutoscrollCursor(
+ const gfx::Vector2dF& velocity,
+ bool scroll_vert,
+ bool scroll_horiz) {
// At the original click location we draw a 4 arrowed icon. Over this icon
// there won't be any scroll, So don't change the cursor over this area.
- bool east = velocity.Width() < 0;
- bool west = velocity.Width() > 0;
- bool north = velocity.Height() > 0;
- bool south = velocity.Height() < 0;
+ bool east = velocity.x() < 0;
+ bool west = velocity.x() > 0;
+ bool north = velocity.y() > 0;
+ bool south = velocity.y() < 0;
if (north && scroll_vert) {
if (scroll_horiz) {
@@ -88,7 +92,7 @@ static const Cursor& MiddleClickAutoscrollCursor(const FloatSize& velocity,
AutoscrollController::AutoscrollController(Page& page) : page_(&page) {}
-void AutoscrollController::Trace(blink::Visitor* visitor) {
+void AutoscrollController::Trace(Visitor* visitor) {
visitor->Trace(page_);
}
@@ -113,9 +117,9 @@ void AutoscrollController::StartAutoscrollForSelection(
return;
LayoutBox* scrollable = LayoutBox::FindAutoscrollable(
layout_object, /*is_middle_click_autoscroll*/ false);
- if (!scrollable)
- scrollable =
- layout_object->IsListBox() ? ToLayoutListBox(layout_object) : nullptr;
+ if (!scrollable && layout_object->GetNode()) {
+ scrollable = layout_object->GetNode()->AutoscrollBox();
+ }
if (!scrollable)
return;
@@ -129,7 +133,8 @@ void AutoscrollController::StartAutoscrollForSelection(
void AutoscrollController::StopAutoscroll() {
if (pressed_layout_object_) {
- pressed_layout_object_->StopAutoscroll();
+ if (pressed_layout_object_->GetNode())
+ pressed_layout_object_->GetNode()->StopAutoscroll();
pressed_layout_object_ = nullptr;
}
autoscroll_layout_object_ = nullptr;
@@ -179,7 +184,7 @@ void AutoscrollController::UpdateDragAndDrop(Node* drop_target_node,
drop_target_node->GetLayoutObject()
->GetFrameView()
- ->UpdateAllLifecyclePhasesExceptPaint();
+ ->UpdateAllLifecyclePhasesExceptPaint(DocumentUpdateReason::kScroll);
LayoutBox* scrollable =
LayoutBox::FindAutoscrollable(drop_target_node->GetLayoutObject(),
@@ -219,6 +224,30 @@ void AutoscrollController::UpdateDragAndDrop(Node* drop_target_node,
}
}
+bool CanScrollDirection(LayoutBox* layout_box,
+ Page* page,
+ ScrollOrientation orientation) {
+ DCHECK(layout_box);
+
+ bool can_scroll = orientation == ScrollOrientation::kHorizontalScroll
+ ? layout_box->HasScrollableOverflowX()
+ : layout_box->HasScrollableOverflowY();
+
+ if (page) {
+ // TODO: Consider only doing this when the layout_box is the document to
+ // correctly handle autoscrolling a DIV when pinch-zoomed.
+ // See comments on crrev.com/c/2109286
+ ScrollOffset maximum_scroll_offset =
+ page->GetVisualViewport().MaximumScrollOffset();
+ can_scroll =
+ can_scroll || (orientation == ScrollOrientation::kHorizontalScroll
+ ? maximum_scroll_offset.Width() > 0
+ : maximum_scroll_offset.Height() > 0);
+ }
+
+ return can_scroll;
+}
+
void AutoscrollController::HandleMouseMoveForMiddleClickAutoscroll(
LocalFrame* frame,
const FloatPoint& position_global,
@@ -226,6 +255,11 @@ void AutoscrollController::HandleMouseMoveForMiddleClickAutoscroll(
if (!MiddleClickAutoscrollInProgress())
return;
+ if (!autoscroll_layout_object_->CanBeScrolledAndHasScrollableArea()) {
+ StopMiddleClickAutoscroll(frame);
+ return;
+ }
+
LocalFrameView* view = frame->View();
if (!view)
return;
@@ -243,17 +277,24 @@ void AutoscrollController::HandleMouseMoveForMiddleClickAutoscroll(
const float kMultiplier = -0.000008f;
const int x_signum = (distance.Width() < 0) ? -1 : (distance.Width() > 0);
const int y_signum = (distance.Height() < 0) ? -1 : (distance.Height() > 0);
- FloatSize velocity(
+ gfx::Vector2dF velocity(
pow(fabs(distance.Width()), kExponent) * kMultiplier * x_signum,
pow(fabs(distance.Height()), kExponent) * kMultiplier * y_signum);
+ bool can_scroll_vertically =
+ CanScrollDirection(autoscroll_layout_object_, frame->GetPage(),
+ ScrollOrientation::kVerticalScroll);
+ bool can_scroll_horizontally =
+ CanScrollDirection(autoscroll_layout_object_, frame->GetPage(),
+ ScrollOrientation::kHorizontalScroll);
+
if (velocity != last_velocity_) {
last_velocity_ = velocity;
if (middle_click_mode_ == kMiddleClickInitial)
middle_click_mode_ = kMiddleClickHolding;
page_->GetChromeClient().SetCursorOverridden(false);
- view->SetCursor(MiddleClickAutoscrollCursor(
- velocity, can_scroll_vertically_, can_scroll_horizontally_));
+ view->SetCursor(MiddleClickAutoscrollCursor(velocity, can_scroll_vertically,
+ can_scroll_horizontally));
page_->GetChromeClient().SetCursorOverridden(true);
page_->GetChromeClient().AutoscrollFling(velocity, frame);
}
@@ -283,6 +324,7 @@ void AutoscrollController::StopMiddleClickAutoscroll(LocalFrame* frame) {
autoscroll_type_ = kNoAutoscroll;
page_->GetChromeClient().SetCursorOverridden(false);
frame->LocalFrameRoot().GetEventHandler().ScheduleCursorUpdate();
+ autoscroll_layout_object_ = nullptr;
}
bool AutoscrollController::MiddleClickAutoscrollInProgress() const {
@@ -291,30 +333,36 @@ bool AutoscrollController::MiddleClickAutoscrollInProgress() const {
void AutoscrollController::StartMiddleClickAutoscroll(
LocalFrame* frame,
+ LayoutBox* scrollable,
const FloatPoint& position,
- const FloatPoint& position_global,
- bool scroll_vert,
- bool scroll_horiz) {
+ const FloatPoint& position_global) {
DCHECK(RuntimeEnabledFeatures::MiddleClickAutoscrollEnabled());
+ DCHECK(scrollable);
// We don't want to trigger the autoscroll or the middleClickAutoscroll if
// it's already active.
if (autoscroll_type_ != kNoAutoscroll)
return;
+ autoscroll_layout_object_ = scrollable;
autoscroll_type_ = kAutoscrollForMiddleClick;
middle_click_mode_ = kMiddleClickInitial;
middle_click_autoscroll_start_pos_global_ = position_global;
- can_scroll_vertically_ = scroll_vert;
- can_scroll_horizontally_ = scroll_horiz;
+
+ bool can_scroll_vertically =
+ CanScrollDirection(autoscroll_layout_object_, frame->GetPage(),
+ ScrollOrientation::kVerticalScroll);
+ bool can_scroll_horizontally =
+ CanScrollDirection(autoscroll_layout_object_, frame->GetPage(),
+ ScrollOrientation::kHorizontalScroll);
UseCounter::Count(frame->GetDocument(),
WebFeature::kMiddleClickAutoscrollStart);
- last_velocity_ = FloatSize();
+ last_velocity_ = gfx::Vector2dF();
if (LocalFrameView* view = frame->View()) {
view->SetCursor(MiddleClickAutoscrollCursor(
- last_velocity_, can_scroll_vertically_, can_scroll_horizontally_));
+ last_velocity_, can_scroll_vertically, can_scroll_horizontally));
}
page_->GetChromeClient().SetCursorOverridden(true);
page_->GetChromeClient().AutoscrollStart(
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 88edd833c94..4a6f4edad3a 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(blink::Visitor*);
+ void Trace(Visitor*);
// Selection and drag-and-drop autoscroll.
void Animate();
@@ -84,10 +84,9 @@ class CORE_EXPORT AutoscrollController final
// Middle-click autoscroll.
void StartMiddleClickAutoscroll(LocalFrame*,
+ LayoutBox*,
const FloatPoint& position,
- const FloatPoint& position_global,
- bool scroll_vert,
- bool scroll_horiz);
+ const FloatPoint& position_global);
void HandleMouseMoveForMiddleClickAutoscroll(
LocalFrame*,
const FloatPoint& position_global,
@@ -103,25 +102,24 @@ class CORE_EXPORT AutoscrollController final
Member<Page> page_;
AutoscrollType autoscroll_type_ = kNoAutoscroll;
+ LayoutBox* autoscroll_layout_object_ = nullptr;
// Selection and drag-and-drop autoscroll.
void ScheduleMainThreadAnimation();
- LayoutBox* autoscroll_layout_object_ = nullptr;
LayoutBox* pressed_layout_object_ = nullptr;
PhysicalOffset drag_and_drop_autoscroll_reference_position_;
base::TimeTicks drag_and_drop_autoscroll_start_time_;
// Middle-click autoscroll.
FloatPoint middle_click_autoscroll_start_pos_global_;
- FloatSize last_velocity_;
+ gfx::Vector2dF last_velocity_;
MiddleClickMode middle_click_mode_ = kMiddleClickInitial;
- bool can_scroll_vertically_ = false;
- bool can_scroll_horizontally_ = false;
FRIEND_TEST_ALL_PREFIXES(AutoscrollControllerTest,
CrashWhenLayoutStopAnimationBeforeScheduleAnimation);
FRIEND_TEST_ALL_PREFIXES(AutoscrollControllerTest,
ContinueAutoscrollAfterMouseLeaveEvent);
+ FRIEND_TEST_ALL_PREFIXES(AutoscrollControllerTest, StopAutoscrollOnResize);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/autoscroll_controller_test.cc b/chromium/third_party/blink/renderer/core/page/autoscroll_controller_test.cc
index 33593bf890e..db8e230026a 100644
--- a/chromium/third_party/blink/renderer/core/page/autoscroll_controller_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/autoscroll_controller_test.cc
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/css_value_keywords.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/input/event_handler.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/testing/sim/sim_request.h"
#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
@@ -58,9 +59,9 @@ TEST_F(AutoscrollControllerTest,
DCHECK(scrollable);
DCHECK(scrollable->GetLayoutObject());
- WebMouseEvent event(WebInputEvent::kMouseDown, WebFloatPoint(5, 5),
- WebFloatPoint(5, 5), WebPointerProperties::Button::kLeft,
- 0, WebInputEvent::Modifiers::kLeftButtonDown,
+ WebMouseEvent event(WebInputEvent::kMouseDown, gfx::PointF(5, 5),
+ gfx::PointF(5, 5), WebPointerProperties::Button::kLeft, 0,
+ WebInputEvent::Modifiers::kLeftButtonDown,
base::TimeTicks::Now());
event.SetFrameScale(1);
@@ -82,13 +83,31 @@ TEST_F(AutoscrollControllerTest,
// Ensure that autoscrolling continues when the MouseLeave event is fired.
TEST_F(AutoscrollControllerTest, ContinueAutoscrollAfterMouseLeaveEvent) {
+ 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>
+ #scrollable {
+ width: 820px;
+ height: 620px;
+ }
+ </style>
+ <div id='scrollable'></div>
+ )HTML");
+
+ Compositor().BeginFrame();
+
AutoscrollController& controller = GetAutoscrollController();
- LocalFrame* frame = GetDocument().GetFrame();
EXPECT_FALSE(controller.IsAutoscrolling());
- controller.StartMiddleClickAutoscroll(frame, FloatPoint(), FloatPoint(),
- false, false);
+ LocalFrame* frame = GetDocument().GetFrame();
+ Node* document_node = GetDocument().documentElement();
+ controller.StartMiddleClickAutoscroll(
+ frame, document_node->parentNode()->GetLayoutBox(), FloatPoint(),
+ FloatPoint());
EXPECT_TRUE(controller.IsAutoscrolling());
@@ -102,4 +121,65 @@ TEST_F(AutoscrollControllerTest, ContinueAutoscrollAfterMouseLeaveEvent) {
EXPECT_TRUE(controller.IsAutoscrolling());
}
+// Ensure that autoscrolling stops when scrolling is no longer available.
+TEST_F(AutoscrollControllerTest, StopAutoscrollOnResize) {
+ 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>
+ #scrollable {
+ width: 820px;
+ height: 620px;
+ }
+ </style>
+ <div id='scrollable'></div>
+ )HTML");
+
+ Compositor().BeginFrame();
+
+ AutoscrollController& controller = GetAutoscrollController();
+
+ EXPECT_FALSE(controller.IsAutoscrolling());
+
+ LocalFrame* frame = GetDocument().GetFrame();
+ controller.StartMiddleClickAutoscroll(frame, GetDocument().GetLayoutView(),
+ FloatPoint(), FloatPoint());
+
+ EXPECT_TRUE(controller.IsAutoscrolling());
+
+ // Confirm that it correctly stops autoscrolling when scrolling is no longer
+ // possible
+ WebView().MainFrameWidget()->Resize(WebSize(840, 640));
+
+ WebMouseEvent mouse_move_event(WebInputEvent::kMouseMove,
+ WebInputEvent::kNoModifiers,
+ base::TimeTicks::Now());
+
+ frame->GetEventHandler().HandleMouseMoveEvent(
+ mouse_move_event, Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
+
+ EXPECT_FALSE(controller.IsAutoscrolling());
+
+ // Confirm that autoscrolling doesn't restart when scrolling is available
+ // again
+ WebView().MainFrameWidget()->Resize(WebSize(800, 600));
+
+ WebMouseEvent mouse_move_event2(WebInputEvent::kMouseMove,
+ WebInputEvent::kNoModifiers,
+ base::TimeTicks::Now());
+
+ frame->GetEventHandler().HandleMouseMoveEvent(
+ mouse_move_event2, Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
+
+ EXPECT_FALSE(controller.IsAutoscrolling());
+
+ // And finally confirm that autoscrolling can start again.
+ controller.StartMiddleClickAutoscroll(frame, GetDocument().GetLayoutView(),
+ FloatPoint(), FloatPoint());
+
+ EXPECT_TRUE(controller.IsAutoscrolling());
+}
+
} // namespace blink
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 b2d64151f72..a7c3341161e 100644
--- a/chromium/third_party/blink/renderer/core/page/chrome_client.cc
+++ b/chromium/third_party/blink/renderer/core/page/chrome_client.cc
@@ -22,6 +22,7 @@
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include <algorithm>
+
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_prescient_networking.h"
#include "third_party/blink/public/platform/web_screen_info.h"
@@ -37,11 +38,12 @@
#include "third_party/blink/renderer/core/page/scoped_page_pauser.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
-void ChromeClient::Trace(blink::Visitor* visitor) {
+void ChromeClient::Trace(Visitor* visitor) {
visitor->Trace(last_mouse_over_node_);
}
@@ -124,7 +126,7 @@ Page* ChromeClient::CreateWindow(
const FrameLoadRequest& r,
const AtomicString& frame_name,
const WebWindowFeatures& features,
- WebSandboxFlags sandbox_flags,
+ mojom::blink::WebSandboxFlags sandbox_flags,
const FeaturePolicy::FeatureState& opener_feature_state,
const SessionStorageNamespaceId& session_storage_namespace_id) {
if (!CanOpenUIElementIfDuringPageDismissal(
@@ -275,10 +277,11 @@ bool ChromeClient::Print(LocalFrame* frame) {
return false;
}
- if (frame->GetDocument()->IsSandboxed(WebSandboxFlags::kModals)) {
+ if (frame->GetDocument()->IsSandboxed(
+ mojom::blink::WebSandboxFlags::kModals)) {
UseCounter::Count(frame->GetDocument(),
WebFeature::kDialogInSandboxedContext);
- frame->Console().AddMessage(ConsoleMessage::Create(
+ frame->Console().AddMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kSecurity,
mojom::ConsoleMessageLevel::kError,
"Ignored call to 'print()'. The document is sandboxed, and the "
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 7ab1fb76dc3..e027493c721 100644
--- a/chromium/third_party/blink/renderer/core/page/chrome_client.h
+++ b/chromium/third_party/blink/renderer/core/page/chrome_client.h
@@ -28,14 +28,19 @@
#include "base/gtest_prod_util.h"
#include "base/optional.h"
#include "cc/input/event_listener_properties.h"
+#include "cc/input/layer_selection_bound.h"
#include "cc/input/overscroll_behavior.h"
+#include "cc/paint/paint_image.h"
#include "cc/trees/paint_holding_commit_trigger.h"
+#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/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_focus_type.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"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
#include "third_party/blink/renderer/core/core_export.h"
@@ -47,7 +52,6 @@
#include "third_party/blink/renderer/core/loader/navigation_policy.h"
#include "third_party/blink/renderer/core/scroll/scroll_types.h"
#include "third_party/blink/renderer/core/style/computed_style_constants.h"
-#include "third_party/blink/renderer/platform/cursor.h"
#include "third_party/blink/renderer/platform/graphics/touch_action.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/text/text_direction.h"
@@ -64,6 +68,10 @@ class Layer;
struct OverscrollBehavior;
}
+namespace ui {
+class Cursor;
+}
+
namespace blink {
class ColorChooser;
@@ -73,7 +81,6 @@ class DateTimeChooser;
class DateTimeChooserClient;
class Element;
class FileChooser;
-class FloatPoint;
class Frame;
class FullscreenOptions;
class HTMLFormControlElement;
@@ -97,9 +104,9 @@ struct DateTimeChooserParameters;
struct FrameLoadRequest;
struct WebTextAutosizerPageInfo;
struct ViewportDescription;
-struct WebCursorInfo;
struct WebScreenInfo;
struct WebWindowFeatures;
+struct WebRect;
using CompositorElementId = cc::ElementId;
@@ -109,10 +116,16 @@ class CORE_EXPORT ChromeClient : public GarbageCollected<ChromeClient> {
public:
virtual ~ChromeClient() = default;
+ virtual WebViewImpl* GetWebView() const = 0;
+
// Converts the scalar value from window coordinates to viewport scale.
virtual float WindowToViewportScalar(LocalFrame*,
const float value) const = 0;
+ // Converts the scalar value from window coordinates to viewport rectangle.
+ virtual void WindowToViewportRect(LocalFrame& frame,
+ WebFloatRect* viewport_rect) const {}
+
virtual bool IsPopup() { return false; }
virtual void ChromeDestroyed() = 0;
@@ -138,12 +151,10 @@ class CORE_EXPORT ChromeClient : public GarbageCollected<ChromeClient> {
virtual void Focus(LocalFrame*) = 0;
- virtual bool CanTakeFocus(WebFocusType) = 0;
- virtual void TakeFocus(WebFocusType) = 0;
-
- virtual void FocusedElementChanged(Element*, Element*) = 0;
+ virtual bool CanTakeFocus(mojom::blink::FocusType) = 0;
+ virtual void TakeFocus(mojom::blink::FocusType) = 0;
- virtual bool HadFormInteraction() const = 0;
+ virtual void SetKeyboardFocusURL(Element*) {}
// Allow document lifecycle updates to be run in order to produce composited
// outputs. Updates are blocked from occurring during loading navigation in
@@ -190,7 +201,7 @@ class CORE_EXPORT ChromeClient : public GarbageCollected<ChromeClient> {
const FrameLoadRequest&,
const AtomicString& frame_name,
const WebWindowFeatures&,
- WebSandboxFlags,
+ mojom::blink::WebSandboxFlags,
const FeaturePolicy::FeatureState&,
const SessionStorageNamespaceId&);
virtual void Show(NavigationPolicy) = 0;
@@ -199,10 +210,10 @@ class CORE_EXPORT ChromeClient : public GarbageCollected<ChromeClient> {
// scrolls by 10 px, but due to a 2X page scale we apply a 5px scroll to the
// root frame, all of which is handled as overscroll, we should return 10px
// as the |overscroll_delta|.
- virtual void DidOverscroll(const FloatSize& overscroll_delta,
- const FloatSize& accumulated_overscroll,
- const FloatPoint& position_in_viewport,
- const FloatSize& velocity_in_viewport) = 0;
+ virtual void DidOverscroll(const gfx::Vector2dF& overscroll_delta,
+ const gfx::Vector2dF& accumulated_overscroll,
+ const gfx::PointF& position_in_viewport,
+ const gfx::Vector2dF& velocity_in_viewport) = 0;
// Causes a gesture event of |injected_type| to be dispatched at a later
// point in time. |injected_type| is required to be one of
@@ -216,7 +227,7 @@ class CORE_EXPORT ChromeClient : public GarbageCollected<ChromeClient> {
virtual void InjectGestureScrollEvent(
LocalFrame& local_frame,
WebGestureDevice device,
- const WebFloatSize& delta,
+ const gfx::Vector2dF& delta,
ScrollGranularity granularity,
CompositorElementId scrollable_area_element_id,
WebInputEvent::Type injected_type) {}
@@ -254,23 +265,21 @@ class CORE_EXPORT ChromeClient : public GarbageCollected<ChromeClient> {
String& result);
virtual bool TabsToLinks() = 0;
- virtual WebViewImpl* GetWebView() const = 0;
-
virtual WebScreenInfo GetScreenInfo(LocalFrame& frame) const = 0;
- virtual void SetCursor(const Cursor&, LocalFrame* local_root) = 0;
+ virtual void SetCursor(const ui::Cursor&, LocalFrame* local_root) = 0;
virtual void SetCursorOverridden(bool) = 0;
- virtual void AutoscrollStart(WebFloatPoint position, LocalFrame*) {}
- virtual void AutoscrollFling(WebFloatSize velocity, LocalFrame*) {}
+ virtual void AutoscrollStart(const gfx::PointF& position, LocalFrame*) {}
+ virtual void AutoscrollFling(const gfx::Vector2dF& velocity, LocalFrame*) {}
virtual void AutoscrollEnd(LocalFrame*) {}
- virtual Cursor LastSetCursorForTesting() const = 0;
+ virtual ui::Cursor LastSetCursorForTesting() const = 0;
Node* LastSetTooltipNodeForTesting() const {
return last_mouse_over_node_.Get();
}
- virtual void SetCursorForPlugin(const WebCursorInfo&, LocalFrame*) = 0;
+ virtual void SetCursorForPlugin(const ui::Cursor&, LocalFrame*) = 0;
// Returns a custom visible rect if a viewport override is active. Requires
// the |frame| being painted, but only supports being used for the main frame.
@@ -286,6 +295,10 @@ class CORE_EXPORT ChromeClient : public GarbageCollected<ChromeClient> {
virtual bool DoubleTapToZoomEnabled() const { return false; }
+ virtual void EnablePreferredSizeChangedMode() {}
+
+ virtual void ZoomToFindInPageRect(const WebRect&) {}
+
virtual void ContentsSizeChanged(LocalFrame*, const IntSize&) const = 0;
// Call during pinch gestures, or when page-scale changes on main-frame load.
virtual void PageScaleFactorChanged() const {}
@@ -344,11 +357,16 @@ class CORE_EXPORT ChromeClient : public GarbageCollected<ChromeClient> {
virtual void DetachCompositorAnimationTimeline(CompositorAnimationTimeline*,
LocalFrame* local_root) {}
- virtual void EnterFullscreen(LocalFrame&, const FullscreenOptions*) {}
+ virtual void EnterFullscreen(LocalFrame&,
+ const FullscreenOptions*,
+ bool for_cross_process_descendant) {}
virtual void ExitFullscreen(LocalFrame&) {}
virtual void FullscreenElementChanged(Element* old_element,
Element* new_element) {}
+ virtual void AnimateDoubleTapZoom(const gfx::Point& point,
+ const gfx::Rect& rect) {}
+
virtual void ClearLayerSelection(LocalFrame*) {}
virtual void UpdateLayerSelection(LocalFrame*, const cc::LayerSelection&) {}
@@ -402,9 +420,18 @@ class CORE_EXPORT ChromeClient : public GarbageCollected<ChromeClient> {
virtual bool IsSVGImageChromeClient() const { return false; }
virtual bool RequestPointerLock(LocalFrame*,
+ WebWidgetClient::PointerLockCallback callback,
bool request_unadjusted_movement) {
return false;
}
+
+ virtual bool RequestPointerLockChange(
+ LocalFrame*,
+ WebWidgetClient::PointerLockCallback callback,
+ bool request_unadjusted_movement) {
+ return false;
+ }
+
virtual void RequestPointerUnlock(LocalFrame*) {}
virtual IntSize MinimumWindowSize() const { return IntSize(100, 100); }
@@ -445,7 +472,7 @@ class CORE_EXPORT ChromeClient : public GarbageCollected<ChromeClient> {
}
virtual void RequestDecode(LocalFrame*,
- const PaintImage& image,
+ const cc::PaintImage& image,
base::OnceCallback<void(bool)> callback) {
std::move(callback).Run(false);
}
@@ -454,8 +481,7 @@ class CORE_EXPORT ChromeClient : public GarbageCollected<ChromeClient> {
// |frame| is submitted (still called "swapped") to the display compositor
// (either with DidSwap or DidNotSwap).
using ReportTimeCallback =
- WTF::CrossThreadOnceFunction<void(WebWidgetClient::SwapResult,
- base::TimeTicks)>;
+ WTF::CrossThreadOnceFunction<void(WebSwapResult, base::TimeTicks)>;
virtual void NotifySwapTime(LocalFrame& frame, ReportTimeCallback callback) {}
virtual void FallbackCursorModeLockCursor(LocalFrame* frame,
@@ -477,7 +503,7 @@ class CORE_EXPORT ChromeClient : public GarbageCollected<ChromeClient> {
// tracing/debugging purposes.
virtual int GetLayerTreeId(LocalFrame& frame) = 0;
- virtual void Trace(blink::Visitor*);
+ virtual void Trace(Visitor*);
virtual void DidUpdateTextAutosizerPageInfo(const WebTextAutosizerPageInfo&) {
}
@@ -502,7 +528,7 @@ class CORE_EXPORT ChromeClient : public GarbageCollected<ChromeClient> {
const FrameLoadRequest&,
const AtomicString& frame_name,
const WebWindowFeatures&,
- WebSandboxFlags,
+ mojom::blink::WebSandboxFlags,
const FeaturePolicy::FeatureState&,
const SessionStorageNamespaceId&) = 0;
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 67e9cb90c33..1b430137301 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
@@ -39,7 +39,7 @@
#include "build/build_config.h"
#include "cc/animation/animation_host.h"
#include "cc/layers/picture_layer.h"
-#include "third_party/blink/public/platform/web_cursor_info.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/public/platform/web_float_rect.h"
#include "third_party/blink/public/platform/web_rect.h"
#include "third_party/blink/public/platform/web_text_autosizer_page_info.h"
@@ -53,13 +53,13 @@
#include "third_party/blink/public/web/web_plugin.h"
#include "third_party/blink/public/web/web_popup_menu_info.h"
#include "third_party/blink/public/web/web_settings.h"
-#include "third_party/blink/public/web/web_text_direction.h"
#include "third_party/blink/public/web/web_view_client.h"
#include "third_party/blink/public/web/web_window_features.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/dom/node.h"
#include "third_party/blink/renderer/core/events/web_input_event_conversion.h"
+#include "third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.h"
#include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h"
#include "third_party/blink/renderer/core/exported/web_remote_frame_impl.h"
#include "third_party/blink/renderer/core/exported/web_settings_impl.h"
@@ -94,7 +94,6 @@
#include "third_party/blink/renderer/core/page/popup_opening_observer.h"
#include "third_party/blink/renderer/core/page/validation_message_client.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.h"
-#include "third_party/blink/renderer/platform/cursor.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/graphics/compositor_element_id.h"
@@ -102,10 +101,13 @@
#include "third_party/blink/renderer/platform/graphics/touch_action.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/instrumentation/resource_coordinator/document_resource_coordinator.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/text/text_direction.h"
#include "third_party/blink/renderer/platform/web_test_support.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/text/character_names.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/string_concatenate.h"
@@ -148,6 +150,15 @@ const char* DismissalTypeToString(Document::PageDismissalType dismissal_type) {
return "";
}
+String TruncateDialogMessage(const String& message) {
+ if (message.IsNull())
+ return g_empty_string;
+
+ // 10k ought to be enough for anyone.
+ const wtf_size_t kMaxMessageSize = 10 * 1024;
+ return message.Substring(0, kMaxMessageSize);
+}
+
} // namespace
class CompositorAnimationTimeline;
@@ -177,8 +188,7 @@ void ChromeClientImpl::ChromeDestroyed() {
void ChromeClientImpl::SetWindowRect(const IntRect& r, LocalFrame& frame) {
DCHECK_EQ(&frame, web_view_->MainFrameImpl()->GetFrame());
- WebWidgetClient* client =
- WebLocalFrameImpl::FromFrame(frame)->FrameWidgetImpl()->Client();
+ WebWidgetClient* client = frame.GetWidgetForLocalRoot()->Client();
client->SetWindowRect(r);
}
@@ -186,9 +196,7 @@ IntRect ChromeClientImpl::RootWindowRect(LocalFrame& frame) {
// The WindowRect() for each WebWidgetClient will be the same rect of the top
// level window. Since there is not always a WebWidgetClient attached to the
// WebView, we ask the WebWidget associated with the |frame|'s local root.
- LocalFrame& local_root = frame.LocalFrameRoot();
- WebWidgetClient* client =
- WebLocalFrameImpl::FromFrame(local_root)->FrameWidgetImpl()->Client();
+ WebWidgetClient* client = frame.GetWidgetForLocalRoot()->Client();
return IntRect(client->WindowRect());
}
@@ -199,44 +207,29 @@ void ChromeClientImpl::Focus(LocalFrame* calling_frame) {
}
}
-bool ChromeClientImpl::CanTakeFocus(WebFocusType) {
+bool ChromeClientImpl::CanTakeFocus(mojom::blink::FocusType) {
// For now the browser can always take focus if we're not running layout
// tests.
return !WebTestSupport::IsRunningWebTest();
}
-void ChromeClientImpl::TakeFocus(WebFocusType type) {
+void ChromeClientImpl::TakeFocus(mojom::blink::FocusType type) {
if (!web_view_->Client())
return;
- if (type == kWebFocusTypeBackward)
+ if (type == mojom::blink::FocusType::kBackward)
web_view_->Client()->FocusPrevious();
else
web_view_->Client()->FocusNext();
}
-void ChromeClientImpl::FocusedElementChanged(Element* from_element,
- Element* to_element) {
- web_view_->GetPage()->GetValidationMessageClient().DidChangeFocusTo(
- to_element);
-
- if (!web_view_->Client())
- return;
-
- web_view_->Client()->FocusedElementChanged(WebElement(from_element),
- WebElement(to_element));
-
+void ChromeClientImpl::SetKeyboardFocusURL(Element* new_focus_element) {
WebURL focus_url;
- if (to_element && to_element->IsLiveLink() &&
- to_element->ShouldHaveFocusAppearance())
- focus_url = to_element->HrefURL();
+ if (new_focus_element && new_focus_element->IsLiveLink() &&
+ new_focus_element->ShouldHaveFocusAppearance())
+ focus_url = new_focus_element->HrefURL();
web_view_->Client()->SetKeyboardFocusURL(focus_url);
}
-bool ChromeClientImpl::HadFormInteraction() const {
- return web_view_->PageImportanceSignals() &&
- web_view_->PageImportanceSignals()->HadFormInteraction();
-}
-
void ChromeClientImpl::StartDragging(LocalFrame* frame,
const WebDragData& drag_data,
WebDragOperationsMask mask,
@@ -258,7 +251,7 @@ Page* ChromeClientImpl::CreateWindowDelegate(
const FrameLoadRequest& r,
const AtomicString& name,
const WebWindowFeatures& features,
- WebSandboxFlags sandbox_flags,
+ mojom::blink::WebSandboxFlags sandbox_flags,
const FeaturePolicy::FeatureState& opener_feature_state,
const SessionStorageNamespaceId& session_storage_namespace_id) {
if (!web_view_->Client())
@@ -275,20 +268,22 @@ Page* ChromeClientImpl::CreateWindowDelegate(
WebLocalFrameImpl::FromFrame(frame),
WrappedResourceRequest(r.GetResourceRequest()), features, frame_name,
static_cast<WebNavigationPolicy>(r.GetNavigationPolicy()),
- static_cast<WebSandboxFlags>(sandbox_flags), opener_feature_state,
- session_storage_namespace_id));
+ static_cast<mojom::blink::WebSandboxFlags>(sandbox_flags),
+ opener_feature_state, session_storage_namespace_id));
if (!new_view)
return nullptr;
return new_view->GetPage();
}
-void ChromeClientImpl::DidOverscroll(const FloatSize& overscroll_delta,
- const FloatSize& accumulated_overscroll,
- const FloatPoint& position_in_viewport,
- const FloatSize& velocity_in_viewport) {
+void ChromeClientImpl::DidOverscroll(
+ const gfx::Vector2dF& overscroll_delta,
+ const gfx::Vector2dF& accumulated_overscroll,
+ const gfx::PointF& position_in_viewport,
+ const gfx::Vector2dF& velocity_in_viewport) {
+ // WebWidgetClient can be null when not compositing, and this behaviour only
+ // applies when compositing is enabled.
if (!web_view_->does_composite())
return;
-
// TODO(darin): Change caller to pass LocalFrame.
DCHECK(web_view_->MainFrameImpl());
web_view_->MainFrameImpl()->FrameWidgetImpl()->Client()->DidOverscroll(
@@ -299,32 +294,30 @@ void ChromeClientImpl::DidOverscroll(const FloatSize& overscroll_delta,
void ChromeClientImpl::InjectGestureScrollEvent(
LocalFrame& local_frame,
WebGestureDevice device,
- const WebFloatSize& delta,
+ const gfx::Vector2dF& delta,
ScrollGranularity granularity,
CompositorElementId scrollable_area_element_id,
WebInputEvent::Type injected_type) {
- WebFrameWidgetBase* widget =
- WebLocalFrameImpl::FromFrame(&local_frame)->LocalRootFrameWidget();
- widget->Client()->InjectGestureScrollEvent(
- device, delta, granularity, scrollable_area_element_id, injected_type);
+ WebWidgetClient* client = local_frame.GetWidgetForLocalRoot()->Client();
+ client->InjectGestureScrollEvent(device, delta, granularity,
+ scrollable_area_element_id, injected_type);
}
void ChromeClientImpl::SetOverscrollBehavior(
LocalFrame& main_frame,
const cc::OverscrollBehavior& overscroll_behavior) {
DCHECK(main_frame.IsMainFrame());
- if (!web_view_->does_composite())
- return;
- WebWidgetClient* client =
- WebLocalFrameImpl::FromFrame(main_frame)->FrameWidgetImpl()->Client();
- client->SetOverscrollBehavior(overscroll_behavior);
+ main_frame.GetWidgetForLocalRoot()->SetOverscrollBehavior(
+ overscroll_behavior);
}
void ChromeClientImpl::Show(NavigationPolicy navigation_policy) {
// TODO(darin): Change caller to pass LocalFrame.
- DCHECK(web_view_->MainFrameImpl());
- web_view_->MainFrameImpl()->FrameWidgetImpl()->Client()->Show(
+ WebLocalFrameImpl* main_frame = web_view_->MainFrameImpl();
+ DCHECK(main_frame);
+ main_frame->FrameWidgetImpl()->Client()->Show(
static_cast<WebNavigationPolicy>(navigation_policy));
+ main_frame->DevToolsAgentImpl()->DidShowNewWindow();
}
bool ChromeClientImpl::ShouldReportDetailedMessageForSource(
@@ -359,9 +352,10 @@ bool ChromeClientImpl::CanOpenBeforeUnloadConfirmPanel() {
bool ChromeClientImpl::OpenBeforeUnloadConfirmPanelDelegate(LocalFrame* frame,
bool is_reload) {
NotifyPopupOpeningObservers();
- WebLocalFrameImpl* webframe = WebLocalFrameImpl::FromFrame(frame);
- return webframe->Client() &&
- webframe->Client()->RunModalBeforeUnloadDialog(is_reload);
+ bool success = false;
+ // Synchronous mojo call.
+ frame->GetLocalFrameHostRemote().RunBeforeUnloadConfirm(is_reload, &success);
+ return success;
}
void ChromeClientImpl::CloseWindowSoon() {
@@ -372,22 +366,20 @@ void ChromeClientImpl::CloseWindowSoon() {
bool ChromeClientImpl::OpenJavaScriptAlertDelegate(LocalFrame* frame,
const String& message) {
NotifyPopupOpeningObservers();
- WebLocalFrameImpl* webframe = WebLocalFrameImpl::FromFrame(frame);
- if (webframe->Client()) {
- webframe->Client()->RunModalAlertDialog(message);
- return true;
- }
- return false;
+ // Synchronous mojo call.
+ frame->GetLocalFrameHostRemote().RunModalAlertDialog(
+ TruncateDialogMessage(message));
+ return true;
}
bool ChromeClientImpl::OpenJavaScriptConfirmDelegate(LocalFrame* frame,
const String& message) {
NotifyPopupOpeningObservers();
- WebLocalFrameImpl* webframe = WebLocalFrameImpl::FromFrame(frame);
- if (webframe->Client()) {
- return webframe->Client()->RunModalConfirmDialog(message);
- }
- return false;
+ bool success = false;
+ // Synchronous mojo call.
+ frame->GetLocalFrameHostRemote().RunModalConfirmDialog(
+ TruncateDialogMessage(message), &success);
+ return success;
}
bool ChromeClientImpl::OpenJavaScriptPromptDelegate(LocalFrame* frame,
@@ -395,16 +387,13 @@ bool ChromeClientImpl::OpenJavaScriptPromptDelegate(LocalFrame* frame,
const String& default_value,
String& result) {
NotifyPopupOpeningObservers();
- WebLocalFrameImpl* webframe = WebLocalFrameImpl::FromFrame(frame);
- if (webframe->Client()) {
- WebString actual_value;
- bool ok = webframe->Client()->RunModalPromptDialog(message, default_value,
- &actual_value);
- if (ok)
- result = actual_value;
- return ok;
- }
- return false;
+ bool success = false;
+ // Synchronous mojo call.
+ frame->GetLocalFrameHostRemote().RunModalPromptDialog(
+ TruncateDialogMessage(message),
+ default_value.IsNull() ? g_empty_string : default_value, &success,
+ &result);
+ return success;
}
bool ChromeClientImpl::TabsToLinks() {
return web_view_->TabsToLinks();
@@ -418,14 +407,12 @@ void ChromeClientImpl::InvalidateRect(const IntRect& update_rect) {
void ChromeClientImpl::ScheduleAnimation(const LocalFrameView* frame_view,
base::TimeDelta delay) {
LocalFrame& frame = frame_view->GetFrame();
- WebLocalFrameImpl* web_frame = WebLocalFrameImpl::FromFrame(frame);
- DCHECK(web_frame);
// If the frame is still being created, it might not yet have a WebWidget.
// TODO(dcheng): Is this the right thing to do? Is there a way to avoid having
// a local frame root that doesn't have a WebWidget? During initialization
// there is no content to draw so this call serves no purpose. Maybe the
// WebFrameWidget needs to be initialized before initializing the core frame?
- WebFrameWidgetBase* widget = web_frame->LocalRootFrameWidget();
+ FrameWidget* widget = frame.GetWidgetForLocalRoot();
if (widget) {
if (delay.is_zero()) {
// LocalRootFrameWidget() is a WebWidget, its client is the embedder.
@@ -444,9 +431,7 @@ IntRect ChromeClientImpl::ViewportToScreen(
LocalFrame& frame = frame_view->GetFrame();
- WebWidgetClient* client =
- WebLocalFrameImpl::FromFrame(frame)->LocalRootFrameWidget()->Client();
-
+ WebWidgetClient* client = frame.GetWidgetForLocalRoot()->Client();
// TODO(dcheng): Is this null check needed?
if (client) {
client->ConvertViewportToWindow(&screen_rect);
@@ -470,16 +455,19 @@ float ChromeClientImpl::WindowToViewportScalar(LocalFrame* frame,
}
WebFloatRect viewport_rect(0, 0, scalar_value, 0);
- WebLocalFrameImpl::FromFrame(frame)
- ->LocalRootFrameWidget()
- ->Client()
- ->ConvertWindowToViewport(&viewport_rect);
+ frame->GetWidgetForLocalRoot()->Client()->ConvertWindowToViewport(
+ &viewport_rect);
return viewport_rect.width;
}
+void ChromeClientImpl::WindowToViewportRect(LocalFrame& frame,
+ WebFloatRect* viewport_rect) const {
+ frame.GetWidgetForLocalRoot()->Client()->ConvertWindowToViewport(
+ viewport_rect);
+}
+
WebScreenInfo ChromeClientImpl::GetScreenInfo(LocalFrame& frame) const {
- WebWidgetClient* client =
- WebLocalFrameImpl::FromFrame(frame)->LocalRootFrameWidget()->Client();
+ WebWidgetClient* client = frame.GetWidgetForLocalRoot()->Client();
DCHECK(client);
return client->GetScreenInfo();
}
@@ -488,8 +476,7 @@ void ChromeClientImpl::OverrideVisibleRectForMainFrame(
LocalFrame& frame,
IntRect* visible_rect) const {
DCHECK(frame.IsMainFrame());
- WebWidgetClient* client =
- WebLocalFrameImpl::FromFrame(frame)->FrameWidgetImpl()->Client();
+ WebWidgetClient* client = frame.GetWidgetForLocalRoot()->Client();
return web_view_->GetDevToolsEmulator()->OverrideVisibleRect(
IntRect(client->ViewRect()).Size(), visible_rect);
}
@@ -510,6 +497,14 @@ bool ChromeClientImpl::DoubleTapToZoomEnabled() const {
return web_view_->SettingsImpl()->DoubleTapToZoomEnabled();
}
+void ChromeClientImpl::EnablePreferredSizeChangedMode() {
+ web_view_->EnablePreferredSizeChangedMode();
+}
+
+void ChromeClientImpl::ZoomToFindInPageRect(const WebRect& rect_in_root_frame) {
+ web_view_->ZoomToFindInPageRect(rect_in_root_frame);
+}
+
void ChromeClientImpl::PageScaleFactorChanged() const {
web_view_->PageScaleFactorChanged();
}
@@ -569,13 +564,13 @@ void ChromeClientImpl::SetToolTip(LocalFrame& frame,
WebLocalFrameImpl* web_frame = WebLocalFrameImpl::FromFrame(frame);
if (!tooltip_text.IsEmpty()) {
web_frame->LocalRootFrameWidget()->Client()->SetToolTipText(
- tooltip_text, ToWebTextDirection(dir));
+ tooltip_text, ToBaseTextDirection(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, ToWebTextDirection(dir));
+ tooltip_text, ToBaseTextDirection(dir));
did_request_non_empty_tool_tip_ = false;
}
}
@@ -635,7 +630,8 @@ DateTimeChooser* ChromeClientImpl::OpenDateTimeChooser(
external_date_time_chooser_->IsShowingDateTimeChooserUI())
return nullptr;
- external_date_time_chooser_ = ExternalDateTimeChooser::Create(picker_client);
+ external_date_time_chooser_ =
+ MakeGarbageCollected<ExternalDateTimeChooser>(picker_client);
external_date_time_chooser_->OpenDateTimeChooser(frame, parameters);
return external_date_time_chooser_;
}
@@ -693,18 +689,18 @@ void ChromeClientImpl::DidCompleteFileChooser(FileChooser& chooser) {
DidCompleteFileChooser(*next_chooser);
}
-Cursor ChromeClientImpl::LastSetCursorForTesting() const {
+ui::Cursor ChromeClientImpl::LastSetCursorForTesting() const {
return last_set_mouse_cursor_for_testing_;
}
-void ChromeClientImpl::SetCursor(const Cursor& cursor,
+void ChromeClientImpl::SetCursor(const ui::Cursor& cursor,
LocalFrame* local_frame) {
last_set_mouse_cursor_for_testing_ = cursor;
- SetCursor(WebCursorInfo(cursor), local_frame);
+ SetCursorInternal(cursor, local_frame);
}
-void ChromeClientImpl::SetCursor(const WebCursorInfo& cursor,
- LocalFrame* local_frame) {
+void ChromeClientImpl::SetCursorInternal(const ui::Cursor& cursor,
+ LocalFrame* local_frame) {
if (cursor_overridden_)
return;
@@ -716,37 +712,36 @@ void ChromeClientImpl::SetCursor(const WebCursorInfo& cursor,
#endif
// TODO(dcheng): Why is this null check necessary?
- if (WebFrameWidgetBase* widget =
- WebLocalFrameImpl::FromFrame(local_frame)->LocalRootFrameWidget())
+ if (FrameWidget* widget = local_frame->GetWidgetForLocalRoot())
widget->Client()->DidChangeCursor(cursor);
}
-void ChromeClientImpl::SetCursorForPlugin(const WebCursorInfo& cursor,
+void ChromeClientImpl::SetCursorForPlugin(const ui::Cursor& cursor,
LocalFrame* local_frame) {
- SetCursor(cursor, local_frame);
+ SetCursorInternal(cursor, local_frame);
}
void ChromeClientImpl::SetCursorOverridden(bool overridden) {
cursor_overridden_ = overridden;
}
-void ChromeClientImpl::AutoscrollStart(WebFloatPoint viewport_point,
+void ChromeClientImpl::AutoscrollStart(const gfx::PointF& viewport_point,
LocalFrame* local_frame) {
- if (WebFrameWidgetBase* widget =
- WebLocalFrameImpl::FromFrame(local_frame)->LocalRootFrameWidget())
+ // TODO(dcheng): Why is this null check necessary?
+ if (FrameWidget* widget = local_frame->GetWidgetForLocalRoot())
widget->Client()->AutoscrollStart(viewport_point);
}
-void ChromeClientImpl::AutoscrollFling(WebFloatSize velocity,
+void ChromeClientImpl::AutoscrollFling(const gfx::Vector2dF& velocity,
LocalFrame* local_frame) {
- if (WebFrameWidgetBase* widget =
- WebLocalFrameImpl::FromFrame(local_frame)->LocalRootFrameWidget())
+ // TODO(dcheng): Why is this null check necessary?
+ if (FrameWidget* widget = local_frame->GetWidgetForLocalRoot())
widget->Client()->AutoscrollFling(velocity);
}
void ChromeClientImpl::AutoscrollEnd(LocalFrame* local_frame) {
- if (WebFrameWidgetBase* widget =
- WebLocalFrameImpl::FromFrame(local_frame)->LocalRootFrameWidget())
+ // TODO(dcheng): Why is this null check necessary?
+ if (FrameWidget* widget = local_frame->GetWidgetForLocalRoot())
widget->Client()->AutoscrollEnd();
}
@@ -756,29 +751,23 @@ String ChromeClientImpl::AcceptLanguages() {
void ChromeClientImpl::AttachRootLayer(scoped_refptr<cc::Layer> root_layer,
LocalFrame* local_frame) {
- // TODO(dcheng): This seems wrong. Non-local roots shouldn't be calling this
- // function.
- WebLocalFrameImpl* web_frame =
- WebLocalFrameImpl::FromFrame(local_frame)->LocalRoot();
- DCHECK(WebLocalFrameImpl::FromFrame(local_frame) == web_frame);
+ DCHECK(local_frame->IsLocalRoot());
- // This method can be called while the frame is being detached. In that
- // case, the rootLayer is null, and the widget is already destroyed.
- // TODO(dcheng): This should be called before the widget is gone...
- DCHECK(web_frame->FrameWidget() || !root_layer);
- if (web_frame->FrameWidgetImpl())
- web_frame->FrameWidgetImpl()->SetRootLayer(std::move(root_layer));
+ // This method is called during Document::Shutdown with a null |root_layer|,
+ // but a widget may have never been created in some tests, so it would also
+ // be null (we don't call here with a valid |root_layer| in those tests).
+ FrameWidget* widget = local_frame->GetWidgetForLocalRoot();
+ DCHECK(widget || !root_layer);
+ if (widget)
+ widget->SetRootLayer(std::move(root_layer));
}
void ChromeClientImpl::AttachCompositorAnimationTimeline(
CompositorAnimationTimeline* compositor_timeline,
LocalFrame* local_frame) {
DCHECK(Platform::Current()->IsThreadedAnimationEnabled());
- WebLocalFrameImpl* web_frame = WebLocalFrameImpl::FromFrame(local_frame);
- WebFrameWidgetBase* widget = web_frame->LocalRootFrameWidget();
- // TODO(crbug.com/912193): This is called while a frame is attached so widget
- // is never null, right?
- CHECK(widget);
+ FrameWidget* widget = local_frame->GetWidgetForLocalRoot();
+ DCHECK(widget);
widget->AnimationHost()->AddAnimationTimeline(
compositor_timeline->GetAnimationTimeline());
}
@@ -787,18 +776,16 @@ void ChromeClientImpl::DetachCompositorAnimationTimeline(
CompositorAnimationTimeline* compositor_timeline,
LocalFrame* local_frame) {
DCHECK(Platform::Current()->IsThreadedAnimationEnabled());
- WebLocalFrameImpl* web_frame = WebLocalFrameImpl::FromFrame(local_frame);
- WebFrameWidgetBase* widget = web_frame->LocalRootFrameWidget();
- // TODO(crbug.com/912193): This should not be called after Document::Shutdown,
- // so widget is never null, right?
- CHECK(widget);
+ FrameWidget* widget = local_frame->GetWidgetForLocalRoot();
+ DCHECK(widget);
widget->AnimationHost()->RemoveAnimationTimeline(
compositor_timeline->GetAnimationTimeline());
}
void ChromeClientImpl::EnterFullscreen(LocalFrame& frame,
- const FullscreenOptions* options) {
- web_view_->EnterFullscreen(frame, options);
+ const FullscreenOptions* options,
+ bool for_cross_process_descendant) {
+ web_view_->EnterFullscreen(frame, options, for_cross_process_descendant);
}
void ChromeClientImpl::ExitFullscreen(LocalFrame& frame) {
@@ -810,24 +797,19 @@ void ChromeClientImpl::FullscreenElementChanged(Element* old_element,
web_view_->FullscreenElementChanged(old_element, new_element);
}
+void ChromeClientImpl::AnimateDoubleTapZoom(const gfx::Point& point,
+ const gfx::Rect& rect) {
+ web_view_->AnimateDoubleTapZoom(point, WebRect(rect));
+}
+
void ChromeClientImpl::ClearLayerSelection(LocalFrame* frame) {
- WebFrameWidgetBase* widget =
- WebLocalFrameImpl::FromFrame(frame)->LocalRootFrameWidget();
- WebWidgetClient* client = widget->Client();
- // TODO(dcheng): This shouldn't be called on detached frames?
- if (client)
- client->RegisterSelection(cc::LayerSelection());
+ frame->GetWidgetForLocalRoot()->RegisterSelection(cc::LayerSelection());
}
void ChromeClientImpl::UpdateLayerSelection(
LocalFrame* frame,
const cc::LayerSelection& selection) {
- WebFrameWidgetBase* widget =
- WebLocalFrameImpl::FromFrame(frame)->LocalRootFrameWidget();
- WebWidgetClient* client = widget->Client();
- // TODO(dcheng): This shouldn't be called on detached frames?
- if (client)
- client->RegisterSelection(selection);
+ frame->GetWidgetForLocalRoot()->RegisterSelection(selection);
}
bool ChromeClientImpl::HasOpenedPopup() const {
@@ -878,7 +860,7 @@ bool ChromeClientImpl::ShouldOpenUIElementDuringPageDismissal(
UIElementType ui_element_type,
const String& dialog_message,
Document::PageDismissalType dismissal_type) const {
- // TODO(https://crbug.com/937569): Remove this in Chrome 82.
+ // TODO(https://crbug.com/937569): Remove this in Chrome 88.
if (ui_element_type == ChromeClient::UIElementType::kPopup &&
web_view_->Client() &&
web_view_->Client()->AllowPopupsDuringPageUnload()) {
@@ -904,27 +886,24 @@ bool ChromeClientImpl::ShouldOpenUIElementDuringPageDismissal(
}
viz::FrameSinkId ChromeClientImpl::GetFrameSinkId(LocalFrame* frame) {
- WebFrameWidgetBase* widget =
- WebLocalFrameImpl::FromFrame(frame)->LocalRootFrameWidget();
- WebWidgetClient* client = widget->Client();
+ WebWidgetClient* client = frame->GetWidgetForLocalRoot()->Client();
return client->GetFrameSinkId();
}
void ChromeClientImpl::RequestDecode(LocalFrame* frame,
const PaintImage& image,
base::OnceCallback<void(bool)> callback) {
- WebLocalFrameImpl* web_frame = WebLocalFrameImpl::FromFrame(frame);
- web_frame->LocalRootFrameWidget()->RequestDecode(image, std::move(callback));
+ FrameWidget* widget = frame->GetWidgetForLocalRoot();
+ widget->RequestDecode(image, std::move(callback));
}
void ChromeClientImpl::NotifySwapTime(LocalFrame& frame,
ReportTimeCallback callback) {
- WebLocalFrameImpl* web_frame = WebLocalFrameImpl::FromFrame(frame);
- WebFrameWidgetBase* widget = web_frame->LocalRootFrameWidget();
+ FrameWidget* widget = frame.GetWidgetForLocalRoot();
if (!widget)
return;
- WebWidgetClient* client = widget->Client();
- client->NotifySwapTime(ConvertToBaseOnceCallback(std::move(callback)));
+ widget->NotifySwapAndPresentationTimeInBlink(
+ base::NullCallback(), ConvertToBaseOnceCallback(std::move(callback)));
}
void ChromeClientImpl::FallbackCursorModeLockCursor(LocalFrame* frame,
@@ -932,53 +911,39 @@ void ChromeClientImpl::FallbackCursorModeLockCursor(LocalFrame* frame,
bool right,
bool up,
bool down) {
- DCHECK(frame);
- WebLocalFrameImpl* web_frame = WebLocalFrameImpl::FromFrame(frame);
- WebFrameWidgetBase* widget = web_frame->LocalRootFrameWidget();
+ FrameWidget* widget = frame->GetWidgetForLocalRoot();
if (!widget)
return;
-
if (WebWidgetClient* client = widget->Client())
client->FallbackCursorModeLockCursor(left, right, up, down);
}
void ChromeClientImpl::FallbackCursorModeSetCursorVisibility(LocalFrame* frame,
bool visible) {
- DCHECK(frame);
- WebLocalFrameImpl* web_frame = WebLocalFrameImpl::FromFrame(frame);
- WebFrameWidgetBase* widget = web_frame->LocalRootFrameWidget();
+ FrameWidget* widget = frame->GetWidgetForLocalRoot();
if (!widget)
return;
-
if (WebWidgetClient* client = widget->Client())
client->FallbackCursorModeSetCursorVisibility(visible);
}
void ChromeClientImpl::RequestBeginMainFrameNotExpected(LocalFrame& frame,
bool request) {
- // WebWidgetClient can be null when not compositing, and this behaviour only
- // applies when compositing is enabled.
- if (!web_view_->does_composite())
- return;
- WebWidgetClient* client =
- WebLocalFrameImpl::FromFrame(frame)->LocalRootFrameWidget()->Client();
- client->RequestBeginMainFrameNotExpected(request);
+ frame.GetWidgetForLocalRoot()->RequestBeginMainFrameNotExpected(request);
}
int ChromeClientImpl::GetLayerTreeId(LocalFrame& frame) {
- // WebWidgetClient can be null when not compositing, and this method is only
- // useful when compositing is enabled.
- if (!web_view_->does_composite())
- return 0;
- WebWidgetClient* client =
- WebLocalFrameImpl::FromFrame(frame)->LocalRootFrameWidget()->Client();
- return client->GetLayerTreeId();
+ return frame.GetWidgetForLocalRoot()->GetLayerTreeId();
}
void ChromeClientImpl::SetEventListenerProperties(
LocalFrame* frame,
cc::EventListenerClass event_class,
cc::EventListenerProperties properties) {
+ // This method is only useful when compositing is enabled.
+ if (!web_view_->does_composite())
+ return;
+
// |frame| might be null if called via TreeScopeAdopter::
// moveNodeToNewDocument() and the new document has no frame attached.
// Since a document without a frame cannot attach one later, it is safe to
@@ -986,12 +951,12 @@ void ChromeClientImpl::SetEventListenerProperties(
if (!frame)
return;
- WebLocalFrameImpl* web_frame = WebLocalFrameImpl::FromFrame(frame);
- WebFrameWidgetBase* widget = web_frame->LocalRootFrameWidget();
+ FrameWidget* widget = frame->GetWidgetForLocalRoot();
// TODO(https://crbug.com/820787): When creating a local root, the widget
// won't be set yet. While notifications in this case are technically
// redundant, it adds an awkward special case.
if (!widget) {
+ WebLocalFrameImpl* web_frame = WebLocalFrameImpl::FromFrame(frame);
if (web_frame->IsProvisional()) {
// If we hit a provisional frame, we expect it to be during initialization
// in which case the |properties| should be 'nothing'.
@@ -1000,17 +965,16 @@ void ChromeClientImpl::SetEventListenerProperties(
return;
}
- WebWidgetClient* client = widget->Client();
-
- client->SetEventListenerProperties(event_class, properties);
+ widget->SetEventListenerProperties(event_class, properties);
+ WebWidgetClient* client = widget->Client();
if (event_class == cc::EventListenerClass::kTouchStartOrMove ||
event_class == cc::EventListenerClass::kTouchEndOrCancel) {
client->SetHasTouchEventHandlers(
- client->EventListenerProperties(
+ widget->EventListenerProperties(
cc::EventListenerClass::kTouchStartOrMove) !=
cc::EventListenerProperties::kNone ||
- client->EventListenerProperties(
+ widget->EventListenerProperties(
cc::EventListenerClass::kTouchEndOrCancel) !=
cc::EventListenerProperties::kNone);
} else if (event_class == cc::EventListenerClass::kPointerRawUpdate) {
@@ -1029,8 +993,7 @@ cc::EventListenerProperties ChromeClientImpl::EventListenerProperties(
WebLocalFrameImpl::FromFrame(frame)->LocalRootFrameWidget();
if (!widget)
return cc::EventListenerProperties::kNone;
- WebWidgetClient* client = widget->Client();
- return client->EventListenerProperties(event_class);
+ return widget->EventListenerProperties(event_class);
}
void ChromeClientImpl::BeginLifecycleUpdates(LocalFrame& main_frame) {
@@ -1041,26 +1004,18 @@ void ChromeClientImpl::BeginLifecycleUpdates(LocalFrame& main_frame) {
void ChromeClientImpl::StartDeferringCommits(LocalFrame& main_frame,
base::TimeDelta timeout) {
DCHECK(main_frame.IsMainFrame());
- // WebWidgetClient can be null when not compositing, and deferring commits
- // only applies with a compositor.
- if (!web_view_->does_composite())
- return;
- WebWidgetClient* client =
- WebLocalFrameImpl::FromFrame(main_frame)->FrameWidgetImpl()->Client();
- client->StartDeferringCommits(timeout);
+ WebLocalFrameImpl::FromFrame(main_frame)
+ ->FrameWidgetImpl()
+ ->StartDeferringCommits(timeout);
}
void ChromeClientImpl::StopDeferringCommits(
LocalFrame& main_frame,
cc::PaintHoldingCommitTrigger trigger) {
DCHECK(main_frame.IsMainFrame());
- // WebWidgetClient can be null when not compositing, and deferring commits
- // only applies with a compositor.
- if (!web_view_->does_composite())
- return;
- WebWidgetClient* client =
- WebLocalFrameImpl::FromFrame(main_frame)->FrameWidgetImpl()->Client();
- client->StopDeferringCommits(trigger);
+ WebLocalFrameImpl::FromFrame(main_frame)
+ ->FrameWidgetImpl()
+ ->StopDeferringCommits(trigger);
}
void ChromeClientImpl::SetHasScrollEventHandlers(LocalFrame* frame,
@@ -1072,9 +1027,9 @@ void ChromeClientImpl::SetHasScrollEventHandlers(LocalFrame* frame,
if (!frame)
return;
- WebWidgetClient* client =
- WebLocalFrameImpl::FromFrame(frame)->LocalRootFrameWidget()->Client();
- client->SetHaveScrollEventHandlers(has_event_handlers);
+ WebLocalFrameImpl::FromFrame(frame)
+ ->LocalRootFrameWidget()
+ ->SetHaveScrollEventHandlers(has_event_handlers);
}
void ChromeClientImpl::SetNeedsLowLatencyInput(LocalFrame* frame,
@@ -1124,13 +1079,27 @@ void ChromeClientImpl::SetTouchAction(LocalFrame* frame,
client->SetTouchAction(static_cast<TouchAction>(touch_action));
}
-bool ChromeClientImpl::RequestPointerLock(LocalFrame* frame,
- bool request_unadjusted_movement) {
+bool ChromeClientImpl::RequestPointerLock(
+ LocalFrame* frame,
+ WebWidgetClient::PointerLockCallback callback,
+ bool request_unadjusted_movement) {
return WebLocalFrameImpl::FromFrame(frame)
->LocalRootFrameWidget()
->Client()
->RequestPointerLock(WebLocalFrameImpl::FromFrame(frame),
- request_unadjusted_movement);
+ std::move(callback), request_unadjusted_movement);
+}
+
+bool ChromeClientImpl::RequestPointerLockChange(
+ LocalFrame* frame,
+ WebWidgetClient::PointerLockCallback callback,
+ bool request_unadjusted_movement) {
+ return WebLocalFrameImpl::FromFrame(frame)
+ ->LocalRootFrameWidget()
+ ->Client()
+ ->RequestPointerLockChange(WebLocalFrameImpl::FromFrame(frame),
+ std::move(callback),
+ request_unadjusted_movement);
}
void ChromeClientImpl::RequestPointerUnlock(LocalFrame* frame) {
@@ -1183,7 +1152,9 @@ void ChromeClientImpl::DidChangeValueInTextField(
? WebFeature::kFieldEditInSecureContext
: WebFeature::kFieldEditInNonSecureContext);
doc.MaybeQueueSendDidEditFieldInInsecureContext();
- web_view_->PageImportanceSignals()->SetHadFormInteraction();
+ // The resource coordinator is not available in some tests.
+ if (auto* rc = doc.GetResourceCoordinator())
+ rc->SetHadFormInteraction();
}
}
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 9d9b15296ae..ec816f101ca 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
@@ -35,11 +35,18 @@
#include <memory>
#include "cc/input/overscroll_behavior.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
#include "third_party/blink/public/web/web_navigation_policy.h"
+#include "third_party/blink/public/web/web_widget_client.h"
#include "third_party/blink/public/web/web_window_features.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/platform/graphics/touch_action.h"
+#include "ui/base/cursor/cursor.h"
+
+namespace ui {
+class Cursor;
+}
namespace blink {
@@ -47,7 +54,7 @@ class PagePopup;
class PagePopupClient;
class WebAutofillClient;
class WebViewImpl;
-struct WebCursorInfo;
+struct WebRect;
// Handles window-level notifications from core on behalf of a WebView.
class CORE_EXPORT ChromeClientImpl final : public ChromeClient {
@@ -56,22 +63,20 @@ class CORE_EXPORT ChromeClientImpl final : public ChromeClient {
~ChromeClientImpl() override;
void Trace(Visitor* visitor) override;
- WebViewImpl* GetWebView() 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;
- bool CanTakeFocus(WebFocusType) override;
- void TakeFocus(WebFocusType) override;
- void FocusedElementChanged(Element* from_node, Element* to_node) override;
+ bool CanTakeFocus(mojom::blink::FocusType) override;
+ void TakeFocus(mojom::blink::FocusType) override;
+ void SetKeyboardFocusURL(Element* new_focus_element) override;
void BeginLifecycleUpdates(LocalFrame& main_frame) override;
void StartDeferringCommits(LocalFrame& main_frame,
base::TimeDelta timeout) override;
void StopDeferringCommits(LocalFrame& main_frame,
cc::PaintHoldingCommitTrigger) override;
- bool HadFormInteraction() const override;
void StartDragging(LocalFrame*,
const WebDragData&,
WebDragOperationsMask,
@@ -82,19 +87,19 @@ class CORE_EXPORT ChromeClientImpl final : public ChromeClient {
const FrameLoadRequest&,
const AtomicString& name,
const WebWindowFeatures&,
- WebSandboxFlags,
+ mojom::blink::WebSandboxFlags,
const FeaturePolicy::FeatureState&,
const SessionStorageNamespaceId&) override;
void Show(NavigationPolicy) override;
- void DidOverscroll(const FloatSize& overscroll_delta,
- const FloatSize& accumulated_overscroll,
- const FloatPoint& position_in_viewport,
- const FloatSize& velocity_in_viewport) override;
+ void DidOverscroll(const gfx::Vector2dF& overscroll_delta,
+ const gfx::Vector2dF& accumulated_overscroll,
+ const gfx::PointF& position_in_viewport,
+ const gfx::Vector2dF& velocity_in_viewport) override;
void SetOverscrollBehavior(LocalFrame& main_frame,
const cc::OverscrollBehavior&) override;
void InjectGestureScrollEvent(LocalFrame& local_frame,
WebGestureDevice device,
- const WebFloatSize& delta,
+ const gfx::Vector2dF& delta,
ScrollGranularity granularity,
CompositorElementId scrollable_area_element_id,
WebInputEvent::Type injected_type) override;
@@ -124,12 +129,16 @@ class CORE_EXPORT ChromeClientImpl final : public ChromeClient {
IntRect ViewportToScreen(const IntRect&,
const LocalFrameView*) const override;
float WindowToViewportScalar(LocalFrame*, const float) const override;
+ void WindowToViewportRect(LocalFrame& frame,
+ WebFloatRect* viewport_rect) const override;
WebScreenInfo GetScreenInfo(LocalFrame&) const override;
void OverrideVisibleRectForMainFrame(LocalFrame& frame,
IntRect* paint_rect) const override;
float InputEventsScaleForEmulation() const override;
void ContentsSizeChanged(LocalFrame*, const IntSize&) const override;
bool DoubleTapToZoomEnabled() const override;
+ void EnablePreferredSizeChangedMode() override;
+ void ZoomToFindInPageRect(const WebRect& rect_in_root_frame) override;
void PageScaleFactorChanged() const override;
float ClampPageScaleFactorToLimits(float scale) const override;
void MainFrameScrollOffsetChanged(LocalFrame& main_frame) const override;
@@ -149,9 +158,9 @@ class CORE_EXPORT ChromeClientImpl final : public ChromeClient {
const DateTimeChooserParameters&) override;
ExternalDateTimeChooser* GetExternalDateTimeChooserForTesting() override;
void OpenFileChooser(LocalFrame*, scoped_refptr<FileChooser>) override;
- void SetCursor(const Cursor&, LocalFrame*) override;
+ void SetCursor(const ui::Cursor&, LocalFrame*) override;
void SetCursorOverridden(bool) override;
- Cursor LastSetCursorForTesting() const override;
+ ui::Cursor LastSetCursorForTesting() const override;
void SetEventListenerProperties(LocalFrame*,
cc::EventListenerClass,
cc::EventListenerProperties) override;
@@ -174,17 +183,22 @@ class CORE_EXPORT ChromeClientImpl final : public ChromeClient {
void DetachCompositorAnimationTimeline(CompositorAnimationTimeline*,
LocalFrame*) override;
- void EnterFullscreen(LocalFrame&, const FullscreenOptions*) override;
+ void EnterFullscreen(LocalFrame&,
+ const FullscreenOptions*,
+ bool for_cross_process_descendant) override;
void ExitFullscreen(LocalFrame&) override;
void FullscreenElementChanged(Element* old_element,
Element* new_element) override;
+ void AnimateDoubleTapZoom(const gfx::Point& point,
+ const gfx::Rect& rect) override;
+
void ClearLayerSelection(LocalFrame*) override;
void UpdateLayerSelection(LocalFrame*, const cc::LayerSelection&) override;
// ChromeClient methods:
String AcceptLanguages() override;
- void SetCursorForPlugin(const WebCursorInfo&, LocalFrame*) override;
+ void SetCursorForPlugin(const ui::Cursor&, LocalFrame*) override;
// ChromeClientImpl:
void SetNewWindowNavigationPolicy(WebNavigationPolicy);
@@ -193,8 +207,8 @@ class CORE_EXPORT ChromeClientImpl final : public ChromeClient {
// requests.
void DidCompleteFileChooser(FileChooser& file_chooser);
- void AutoscrollStart(WebFloatPoint viewport_point, LocalFrame*) override;
- void AutoscrollFling(WebFloatSize velocity, LocalFrame*) override;
+ void AutoscrollStart(const gfx::PointF& viewport_point, LocalFrame*) override;
+ void AutoscrollFling(const gfx::Vector2dF& velocity, LocalFrame*) override;
void AutoscrollEnd(LocalFrame*) override;
bool HasOpenedPopup() const override;
@@ -215,7 +229,12 @@ class CORE_EXPORT ChromeClientImpl final : public ChromeClient {
const String& dialog_message,
Document::PageDismissalType) const override;
- bool RequestPointerLock(LocalFrame*, bool) override;
+ bool RequestPointerLock(LocalFrame*,
+ WebWidgetClient::PointerLockCallback,
+ bool) override;
+ bool RequestPointerLockChange(LocalFrame*,
+ WebWidgetClient::PointerLockCallback,
+ bool) override;
void RequestPointerUnlock(LocalFrame*) override;
// AutofillClient pass throughs:
@@ -246,7 +265,7 @@ class CORE_EXPORT ChromeClientImpl final : public ChromeClient {
viz::FrameSinkId GetFrameSinkId(LocalFrame*) override;
void RequestDecode(LocalFrame*,
- const PaintImage&,
+ const cc::PaintImage&,
base::OnceCallback<void(bool)>) override;
void NotifySwapTime(LocalFrame& frame, ReportTimeCallback callback) override;
@@ -272,7 +291,7 @@ class CORE_EXPORT ChromeClientImpl final : public ChromeClient {
private:
bool IsChromeClientImpl() const override { return true; }
- void SetCursor(const WebCursorInfo&, LocalFrame*);
+ void SetCursorInternal(const ui::Cursor&, LocalFrame*);
// Returns WebAutofillClient associated with the WebLocalFrame. This takes and
// returns nullable.
@@ -281,7 +300,7 @@ class CORE_EXPORT ChromeClientImpl final : public ChromeClient {
WebViewImpl* web_view_; // Weak pointer.
HeapHashSet<WeakMember<PopupOpeningObserver>> popup_opening_observers_;
Vector<scoped_refptr<FileChooser>> file_chooser_queue_;
- Cursor last_set_mouse_cursor_for_testing_;
+ ui::Cursor last_set_mouse_cursor_for_testing_;
bool cursor_overridden_;
Member<ExternalDateTimeChooser> external_date_time_chooser_;
bool did_request_non_empty_tool_tip_;
@@ -289,11 +308,12 @@ class CORE_EXPORT ChromeClientImpl final : public ChromeClient {
FRIEND_TEST_ALL_PREFIXES(FileChooserQueueTest, DerefQueuedChooser);
};
-DEFINE_TYPE_CASTS(ChromeClientImpl,
- ChromeClient,
- client,
- client->IsChromeClientImpl(),
- client.IsChromeClientImpl());
+template <>
+struct DowncastTraits<ChromeClientImpl> {
+ static bool AllowFrom(const ChromeClient& client) {
+ return client.IsChromeClientImpl();
+ }
+};
} // namespace blink
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 75815d37999..5eedac92db9 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
@@ -29,11 +29,12 @@
*/
#include "third_party/blink/renderer/core/page/chrome_client_impl.h"
+#include "base/run_loop.h"
#include "cc/trees/layer_tree_host.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/public/mojom/choosers/color_chooser.mojom-blink.h"
-#include "third_party/blink/public/platform/web_input_event.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_view.h"
@@ -62,7 +63,7 @@ class ViewCreatingClient : public frame_test_helpers::TestWebViewClient {
const WebWindowFeatures&,
const WebString& name,
WebNavigationPolicy,
- WebSandboxFlags,
+ mojom::blink::WebSandboxFlags,
const FeaturePolicy::FeatureState&,
const SessionStorageNamespaceId&) override {
return web_view_helper_.InitializeWithOpener(opener);
@@ -78,7 +79,7 @@ class CreateWindowTest : public testing::Test {
web_view_ = helper_.Initialize(nullptr, &web_view_client_);
main_frame_ = helper_.LocalMainFrame();
chrome_client_impl_ =
- ToChromeClientImpl(&web_view_->GetPage()->GetChromeClient());
+ To<ChromeClientImpl>(&web_view_->GetPage()->GetChromeClient());
}
ViewCreatingClient web_view_client_;
@@ -95,7 +96,8 @@ TEST_F(CreateWindowTest, CreateWindowFromPausedPage) {
request.SetNavigationPolicy(kNavigationPolicyNewForegroundTab);
WebWindowFeatures features;
EXPECT_EQ(nullptr, chrome_client_impl_->CreateWindow(
- frame, request, "", features, WebSandboxFlags::kNone,
+ frame, request, "", features,
+ mojom::blink::WebSandboxFlags::kNone,
FeaturePolicy::FeatureState(), ""));
}
@@ -106,7 +108,7 @@ class FakeColorChooserClient : public GarbageCollected<FakeColorChooserClient>,
: owner_element_(owner_element) {}
~FakeColorChooserClient() override = default;
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(owner_element_);
ColorChooserClient::Trace(visitor);
}
@@ -136,7 +138,7 @@ class FakeDateTimeChooserClient
: owner_element_(owner_element) {}
~FakeDateTimeChooserClient() override = default;
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(owner_element_);
DateTimeChooserClient::Trace(visitor);
}
@@ -185,7 +187,7 @@ class PagePopupSuppressionTest : public testing::Test {
web_view_ = helper_.Initialize();
main_frame_ = helper_.LocalMainFrame();
chrome_client_impl_ =
- ToChromeClientImpl(&web_view_->GetPage()->GetChromeClient());
+ To<ChromeClientImpl>(&web_view_->GetPage()->GetChromeClient());
LocalFrame* frame = helper_.LocalMainFrame()->GetFrame();
color_chooser_client_ = MakeGarbageCollected<FakeColorChooserClient>(
frame->GetDocument()->documentElement());
@@ -257,7 +259,7 @@ class FileChooserQueueTest : public testing::Test {
void SetUp() override {
web_view_ = helper_.Initialize();
chrome_client_impl_ =
- ToChromeClientImpl(&web_view_->GetPage()->GetChromeClient());
+ To<ChromeClientImpl>(&web_view_->GetPage()->GetChromeClient());
}
frame_test_helpers::WebViewHelper helper_;
diff --git a/chromium/third_party/blink/renderer/core/page/color_page_popup_controller.cc b/chromium/third_party/blink/renderer/core/page/color_page_popup_controller.cc
new file mode 100644
index 00000000000..13d064d6b8a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/page/color_page_popup_controller.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/page/color_page_popup_controller.h"
+
+#include "third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.h"
+#include "third_party/blink/renderer/core/page/page_popup.h"
+#include "third_party/blink/renderer/core/page/page_popup_client.h"
+#include "third_party/blink/renderer/core/page/page_popup_controller.h"
+
+namespace blink {
+
+ColorPagePopupController::ColorPagePopupController(
+ PagePopup& popup,
+ ColorChooserPopupUIController* client)
+ : PagePopupController(popup, client) {}
+
+void ColorPagePopupController::openEyeDropper() {
+ if (popup_client_) {
+ static_cast<ColorChooserPopupUIController*>(popup_client_)
+ ->OpenEyeDropper();
+ }
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/color_page_popup_controller.h b/chromium/third_party/blink/renderer/core/page/color_page_popup_controller.h
new file mode 100644
index 00000000000..369d5e8f732
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/page/color_page_popup_controller.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_COLOR_PAGE_POPUP_CONTROLLER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_COLOR_PAGE_POPUP_CONTROLLER_H_
+
+#include "third_party/blink/renderer/core/page/page_popup_controller.h"
+
+namespace blink {
+
+class ColorChooserPopupUIController;
+class PagePopup;
+
+class ColorPagePopupController final : public PagePopupController {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ ColorPagePopupController(PagePopup&, ColorChooserPopupUIController*);
+
+ void openEyeDropper();
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_COLOR_PAGE_POPUP_CONTROLLER_H_
diff --git a/chromium/third_party/blink/renderer/core/page/color_page_popup_controller.idl b/chromium/third_party/blink/renderer/core/page/color_page_popup_controller.idl
new file mode 100644
index 00000000000..414ab01c5ed
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/page/color_page_popup_controller.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.
+
+// ColorPagePopupController provides functions used by color control popup
+// implementation and it's not exposed to the Web. WebPagePopupImpl class
+// enables this interface by provideContextFeaturesTo().
+[
+ NoInterfaceObject,
+ RuntimeEnabled=PagePopup
+] interface ColorPagePopupController : PagePopupController {
+ void openEyeDropper();
+};
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 19401a4f0d8..27aa332df8a 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
@@ -31,7 +31,7 @@
#include <utility>
#include "third_party/blink/public/common/context_menu_data/edit_flags.h"
-#include "third_party/blink/public/platform/web_menu_source_type.h"
+#include "third_party/blink/public/common/input/web_menu_source_type.h"
#include "third_party/blink/public/web/web_context_menu_data.h"
#include "third_party/blink/public/web/web_local_frame_client.h"
#include "third_party/blink/public/web/web_plugin.h"
@@ -53,6 +53,7 @@
#include "third_party/blink/renderer/core/html/forms/html_form_element.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/html_anchor_element.h"
+#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html/html_frame_element_base.h"
#include "third_party/blink/renderer/core/html/html_image_element.h"
#include "third_party/blink/renderer/core/html/html_plugin_element.h"
@@ -73,7 +74,7 @@ ContextMenuController::ContextMenuController(Page* page) : page_(page) {}
ContextMenuController::~ContextMenuController() = default;
-void ContextMenuController::Trace(blink::Visitor* visitor) {
+void ContextMenuController::Trace(Visitor* visitor) {
visitor->Trace(page_);
visitor->Trace(menu_provider_);
visitor->Trace(hit_test_result_);
@@ -127,16 +128,6 @@ Node* ContextMenuController::ContextMenuNodeForFrame(LocalFrame* frame) {
: nullptr;
}
-// Figure out the URL of a page or subframe.
-static KURL UrlFromFrame(LocalFrame* frame) {
- if (frame) {
- DocumentLoader* document_loader = frame->Loader().GetDocumentLoader();
- if (document_loader)
- return document_loader->UrlForHistory();
- }
- return KURL();
-}
-
static int ComputeEditFlags(Document& selected_document, Editor& editor) {
int edit_flags = ContextMenuDataEditFlags::kCanDoNone;
if (editor.CanUndo())
@@ -153,7 +144,7 @@ static int ComputeEditFlags(Document& selected_document, Editor& editor) {
edit_flags |= ContextMenuDataEditFlags::kCanDelete;
if (editor.CanEditRichly())
edit_flags |= ContextMenuDataEditFlags::kCanEditRichly;
- if (selected_document.IsHTMLDocument() ||
+ if (IsA<HTMLDocument>(selected_document) ||
selected_document.IsXHTMLDocument()) {
edit_flags |= ContextMenuDataEditFlags::kCanTranslate;
if (selected_document.queryCommandEnabled("selectAll", ASSERT_NO_EXCEPTION))
@@ -278,7 +269,7 @@ bool ContextMenuController::ShowContextMenu(LocalFrame* frame,
// We know that if absoluteMediaURL() is not empty or element has a media
// stream descriptor, then this is a media element.
- HTMLMediaElement* media_element = ToHTMLMediaElement(result.InnerNode());
+ auto* media_element = To<HTMLMediaElement>(result.InnerNode());
if (IsA<HTMLVideoElement>(*media_element)) {
// A video element should be presented as an audio element when it has an
// audio track but no video track.
@@ -332,8 +323,7 @@ bool ContextMenuController::ShowContextMenu(LocalFrame* frame,
WebPlugin* plugin = plugin_view->Plugin();
data.link_url = plugin->LinkAtPosition(data.mouse_position);
- HTMLPlugInElement* plugin_element =
- ToHTMLPlugInElement(result.InnerNode());
+ auto* plugin_element = To<HTMLPlugInElement>(result.InnerNode());
data.src_url =
plugin_element->GetDocument().CompleteURL(plugin_element->Url());
@@ -380,25 +370,6 @@ bool ContextMenuController::ShowContextMenu(LocalFrame* frame,
if (selected_frame->GetDocument()->Loader())
data.frame_encoding = selected_frame->GetDocument()->EncodingName();
- // Send the frame and page URLs in any case.
- auto* main_local_frame = DynamicTo<LocalFrame>(page_->MainFrame());
- if (!main_local_frame) {
- // TODO(kenrb): This works around the problem of URLs not being
- // available for top-level frames that are in a different process.
- // It mostly works to convert the security origin to a URL, but
- // extensions accessing that property will not get the correct value
- // in that case. See https://crbug.com/534561
- const SecurityOrigin* origin =
- page_->MainFrame()->GetSecurityContext()->GetSecurityOrigin();
- if (origin)
- data.page_url = KURL(origin->ToString());
- } else {
- data.page_url = WebURL(UrlFromFrame(main_local_frame));
- }
-
- if (selected_frame != page_->MainFrame())
- data.frame_url = WebURL(UrlFromFrame(selected_frame));
-
data.selection_start_offset = 0;
// HitTestResult::isSelected() ensures clean layout by performing a hit test.
// If source_type is |kMenuSourceAdjustSelection| or
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 8aef3cb9f85..27492a41cdf 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
@@ -29,7 +29,7 @@
#include <memory>
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/public/platform/web_menu_source_type.h"
+#include "third_party/blink/public/common/input/web_menu_source_type.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -48,7 +48,7 @@ class CORE_EXPORT ContextMenuController final
public:
explicit ContextMenuController(Page*);
~ContextMenuController();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
void ClearContextMenu();
diff --git a/chromium/third_party/blink/renderer/core/page/context_menu_controller_test.cc b/chromium/third_party/blink/renderer/core/page/context_menu_controller_test.cc
index 894def7441f..31f1dfab525 100644
--- a/chromium/third_party/blink/renderer/core/page/context_menu_controller_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/context_menu_controller_test.cc
@@ -6,15 +6,17 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/context_menu_data/edit_flags.h"
+#include "third_party/blink/public/common/input/web_menu_source_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/platform/web_menu_source_type.h"
#include "third_party/blink/public/platform/web_rect.h"
#include "third_party/blink/public/web/web_context_menu_data.h"
+#include "third_party/blink/renderer/core/dom/xml_document.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/geometry/dom_rect.h"
+#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/core/input/context_menu_allowed_scope.h"
#include "third_party/blink/renderer/core/page/context_menu_controller.h"
@@ -22,6 +24,7 @@
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/testing/empty_web_media_player.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
using testing::Return;
@@ -73,7 +76,7 @@ class ContextMenuControllerTest : public testing::Test {
WebLocalFrameImpl* local_main_frame = web_view_helper_.LocalMainFrame();
local_main_frame->ViewImpl()->MainFrameWidget()->Resize(WebSize(640, 480));
local_main_frame->ViewImpl()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
}
bool ShowContextMenu(const PhysicalOffset& location,
@@ -493,7 +496,7 @@ TEST_F(ContextMenuControllerTest, EditingActionsEnabledInSVGDocument) {
ASSERT_TRUE(document->IsSVGDocument());
Element* text_element = document->getElementById("t");
- document->UpdateStyleAndLayout();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kTest);
FrameSelection& selection = document->GetFrame()->Selection();
// <text> element
@@ -532,11 +535,11 @@ TEST_F(ContextMenuControllerTest, EditingActionsEnabledInXMLDocument) {
)XML");
Document* document = GetDocument();
- ASSERT_TRUE(document->IsXMLDocument());
- ASSERT_FALSE(document->IsHTMLDocument());
+ ASSERT_TRUE(IsA<XMLDocument>(document));
+ ASSERT_FALSE(IsA<HTMLDocument>(document));
Element* text_element = document->getElementById("t");
- document->UpdateStyleAndLayout();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kTest);
FrameSelection& selection = document->GetFrame()->Selection();
selection.SelectAll();
@@ -550,19 +553,19 @@ TEST_F(ContextMenuControllerTest, EditingActionsEnabledInXMLDocument) {
}
TEST_F(ContextMenuControllerTest, ShowNonLocatedContextMenuEvent) {
- GetDocument()->documentElement()->SetInnerHTMLFromString(
+ GetDocument()->documentElement()->setInnerHTML(
"<input id='sample' type='text' size='5' value='Sample Input Text'>");
Document* document = GetDocument();
Element* input_element = document->getElementById("sample");
- document->UpdateStyleAndLayout();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kTest);
// Select the 'Sample' of |input|.
DOMRect* rect = input_element->getBoundingClientRect();
WebGestureEvent gesture_event(
WebInputEvent::kGestureLongPress, WebInputEvent::kNoModifiers,
base::TimeTicks::Now(), WebGestureDevice::kTouchscreen);
- gesture_event.SetPositionInWidget(WebFloatPoint(rect->left(), rect->top()));
+ gesture_event.SetPositionInWidget(gfx::PointF(rect->left(), rect->top()));
GetWebView()->MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(gesture_event));
@@ -574,7 +577,7 @@ TEST_F(ContextMenuControllerTest, ShowNonLocatedContextMenuEvent) {
LayoutPoint middle_point((rect->left() + rect->right()) / 2,
(rect->top() + rect->bottom()) / 2);
LocalMainFrame()->MoveRangeSelectionExtent(
- WebPoint(middle_point.X().ToInt(), middle_point.Y().ToInt()));
+ gfx::Point(middle_point.X().ToInt(), middle_point.Y().ToInt()));
GetWebView()->MainFrameWidget()->ShowContextMenu(kMenuSourceTouchHandle);
context_menu_data = GetWebFrameClient().GetContextMenuData();
@@ -586,7 +589,7 @@ TEST_F(ContextMenuControllerTest, ShowNonLocatedContextMenuEvent) {
// Select all the value of |input| to ensure the start of selection is
// invisible.
LocalMainFrame()->MoveRangeSelectionExtent(
- WebPoint(rect->right(), rect->bottom()));
+ gfx::Point(rect->right(), rect->bottom()));
GetWebView()->MainFrameWidget()->ShowContextMenu(kMenuSourceTouchHandle);
context_menu_data = GetWebFrameClient().GetContextMenuData();
@@ -594,12 +597,12 @@ TEST_F(ContextMenuControllerTest, ShowNonLocatedContextMenuEvent) {
}
TEST_F(ContextMenuControllerTest, SelectionRectClipped) {
- GetDocument()->documentElement()->SetInnerHTMLFromString(
+ GetDocument()->documentElement()->setInnerHTML(
"<textarea id='text-area' cols=6 rows=2>Sample editable text</textarea>");
Document* document = GetDocument();
Element* editable_element = document->getElementById("text-area");
- document->UpdateStyleAndLayout();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kTest);
FrameSelection& selection = document->GetFrame()->Selection();
// Select the 'Sample' of |textarea|.
@@ -607,7 +610,7 @@ TEST_F(ContextMenuControllerTest, SelectionRectClipped) {
WebGestureEvent gesture_event(
WebInputEvent::kGestureLongPress, WebInputEvent::kNoModifiers,
base::TimeTicks::Now(), WebGestureDevice::kTouchscreen);
- gesture_event.SetPositionInWidget(WebFloatPoint(rect->left(), rect->top()));
+ gesture_event.SetPositionInWidget(gfx::PointF(rect->left(), rect->top()));
GetWebView()->MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(gesture_event));
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 b712a07bca1..d4051b9068e 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(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
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 e53ab2877f0..79b3084588f 100644
--- a/chromium/third_party/blink/renderer/core/page/create_window.cc
+++ b/chromium/third_party/blink/renderer/core/page/create_window.cc
@@ -48,6 +48,7 @@
#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/probe/core_probes.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/text/number_parsing_options.h"
@@ -202,7 +203,8 @@ static void MaybeLogWindowOpen(LocalFrame& opener_frame) {
return;
bool is_ad_subframe = opener_frame.IsAdSubframe();
- bool is_ad_script_in_stack = ad_tracker->IsAdScriptInStack();
+ bool is_ad_script_in_stack =
+ ad_tracker->IsAdScriptInStack(AdTracker::StackType::kBottomAndTop);
FromAdState state =
blink::GetFromAdState(is_ad_subframe, is_ad_script_in_stack);
@@ -228,7 +230,7 @@ Frame* CreateNewWindow(LocalFrame& opener_frame,
DCHECK_EQ(kNavigationPolicyCurrentTab, request.GetNavigationPolicy());
// Exempting window.open() from this check here is necessary to support a
- // special policy that will be removed in Chrome 82.
+ // special policy that will be removed in Chrome 88.
// See https://crbug.com/937569
if (!request.IsWindowOpen() &&
opener_frame.GetDocument()->PageDismissalEventBeingDispatched() !=
@@ -236,13 +238,13 @@ Frame* CreateNewWindow(LocalFrame& opener_frame,
return nullptr;
}
- request.SetFrameType(network::mojom::RequestContextFrameType::kAuxiliary);
+ request.SetFrameType(mojom::RequestContextFrameType::kAuxiliary);
const KURL& url = request.GetResourceRequest().Url();
if (url.ProtocolIsJavaScript() &&
opener_frame.GetDocument()->GetContentSecurityPolicy() &&
!ContentSecurityPolicy::ShouldBypassMainWorld(
- opener_frame.GetDocument())) {
+ opener_frame.GetDocument()->ToExecutionContext())) {
String script_source = DecodeURLEscapeSequences(
url.GetString(), DecodeURLMode::kUTF8OrIsomorphic);
@@ -255,10 +257,11 @@ Frame* CreateNewWindow(LocalFrame& opener_frame,
}
if (!opener_frame.GetDocument()->GetSecurityOrigin()->CanDisplay(url)) {
- opener_frame.GetDocument()->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kError,
- "Not allowed to load local resource: " + url.ElidedString()));
+ opener_frame.GetDocument()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kSecurity,
+ mojom::ConsoleMessageLevel::kError,
+ "Not allowed to load local resource: " + url.ElidedString()));
return nullptr;
}
@@ -268,29 +271,32 @@ Frame* CreateNewWindow(LocalFrame& opener_frame,
LocalFrame::HasTransientUserActivation(&opener_frame));
// Sandboxed frames cannot open new auxiliary browsing contexts.
- if (opener_frame.GetDocument()->IsSandboxed(WebSandboxFlags::kPopups)) {
+ if (opener_frame.GetDocument()->IsSandboxed(
+ mojom::blink::WebSandboxFlags::kPopups)) {
// FIXME: This message should be moved off the console once a solution to
// https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
- opener_frame.GetDocument()->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kError,
- "Blocked opening '" + url.ElidedString() +
- "' in a new window because the request was made in a sandboxed "
- "frame whose 'allow-popups' permission is not set."));
+ opener_frame.GetDocument()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kSecurity,
+ mojom::ConsoleMessageLevel::kError,
+ "Blocked opening '" + url.ElidedString() +
+ "' in a new window because the request was made in a sandboxed "
+ "frame whose 'allow-popups' permission is not set."));
return nullptr;
}
bool propagate_sandbox = opener_frame.GetDocument()->IsSandboxed(
- WebSandboxFlags::kPropagatesToAuxiliaryBrowsingContexts);
+ mojom::blink::WebSandboxFlags::kPropagatesToAuxiliaryBrowsingContexts);
const SandboxFlags sandbox_flags =
propagate_sandbox ? opener_frame.GetDocument()->GetSandboxFlags()
- : WebSandboxFlags::kNone;
- bool not_sandboxed =
- opener_frame.GetDocument()->GetSandboxFlags() == WebSandboxFlags::kNone;
+ : mojom::blink::WebSandboxFlags::kNone;
+ bool not_sandboxed = opener_frame.GetDocument()->GetSandboxFlags() ==
+ mojom::blink::WebSandboxFlags::kNone;
FeaturePolicy::FeatureState opener_feature_state =
- (not_sandboxed || propagate_sandbox)
- ? opener_frame.GetDocument()->GetFeaturePolicy()->GetFeatureState()
- : FeaturePolicy::FeatureState();
+ (not_sandboxed || propagate_sandbox) ? opener_frame.GetSecurityContext()
+ ->GetFeaturePolicy()
+ ->GetFeatureState()
+ : FeaturePolicy::FeatureState();
SessionStorageNamespaceId new_namespace_id =
AllocateSessionStorageNamespaceId();
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 72a7420ce18..8d49321e25e 100644
--- a/chromium/third_party/blink/renderer/core/page/drag_controller.cc
+++ b/chromium/third_party/blink/renderer/core/page/drag_controller.cc
@@ -33,7 +33,6 @@
#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_point.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"
@@ -63,6 +62,7 @@
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/html_anchor_element.h"
#include "third_party/blink/renderer/core/html/html_plugin_element.h"
+#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/input_type_names.h"
#include "third_party/blink/renderer/core/layout/hit_test_request.h"
@@ -139,7 +139,8 @@ static DataTransfer* CreateDraggingDataTransfer(DataTransferAccessPolicy policy,
}
DragController::DragController(Page* page)
- : ContextLifecycleObserver(nullptr),
+ : ExecutionContextLifecycleObserver(
+ static_cast<ExecutionContext*>(nullptr)),
page_(page),
document_under_mouse_(nullptr),
drag_initiator_(nullptr),
@@ -259,9 +260,10 @@ void DragController::PerformDrag(DragData* drag_data, LocalFrame& local_root) {
PhysicalOffset::FromFloatPointRound(drag_data->ClientPosition())));
const HitTestResult result =
event_handler.HitTestResultAtLocation(location);
+ auto* html_plugin_element =
+ DynamicTo<HTMLPlugInElement>(result.InnerNode());
prevented_default |=
- IsHTMLPlugInElement(*result.InnerNode()) &&
- ToHTMLPlugInElement(result.InnerNode())->CanProcessDrag();
+ html_plugin_element && html_plugin_element->CanProcessDrag();
}
// Invalidate clipboard here for security.
@@ -298,8 +300,8 @@ void DragController::PerformDrag(DragData* drag_data, LocalFrame& local_root) {
// the drag as the initiator of the navigation below.
resource_request.SetRequestorOrigin(SecurityOrigin::CreateUniqueOpaque());
- page_->MainFrame()->Navigate(FrameLoadRequest(nullptr, resource_request),
- WebFrameLoadType::kStandard);
+ FrameLoadRequest request(nullptr, resource_request);
+ page_->MainFrame()->Navigate(request, WebFrameLoadType::kStandard);
}
// TODO(bokan): This case happens when we end a URL drag inside a guest
@@ -466,8 +468,8 @@ DragOperation DragController::OperationForLoad(DragData* drag_data,
Document* doc = local_root.DocumentAtPoint(
PhysicalOffset::FromFloatPointRound(drag_data->ClientPosition()));
- if (doc &&
- (did_initiate_drag_ || doc->IsPluginDocument() || HasEditableStyle(*doc)))
+ if (doc && (did_initiate_drag_ || IsA<PluginDocument>(doc) ||
+ HasEditableStyle(*doc)))
return kDragOperationNone;
return GetDragOperation(drag_data);
}
@@ -483,7 +485,7 @@ static bool SetSelectionToDragCaret(LocalFrame* frame,
// TODO(editing-dev): The use of
// UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- frame->GetDocument()->UpdateStyleAndLayout();
+ frame->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
if (!frame->Selection().ComputeVisibleSelectionInDOMTree().IsNone()) {
return frame->Selection()
.ComputeVisibleSelectionInDOMTree()
@@ -499,7 +501,7 @@ static bool SetSelectionToDragCaret(LocalFrame* frame,
// TODO(editing-dev): The use of
// UpdateStyleAndLayout
// needs to be audited. See http://crbug.com/590369 for more details.
- frame->GetDocument()->UpdateStyleAndLayout();
+ frame->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
const VisibleSelection& visible_selection =
frame->Selection().ComputeVisibleSelectionInDOMTree();
range = CreateRange(visible_selection.ToNormalizedEphemeralRange());
@@ -576,7 +578,7 @@ bool DragController::ConcludeEditDrag(DragData* drag_data) {
.CaretPosition()
.GetPosition()
.GetDocument()
- ->UpdateStyleAndLayout();
+ ->UpdateStyleAndLayout(DocumentUpdateReason::kEditing);
}
const PositionWithAffinity& caret_position =
@@ -718,8 +720,7 @@ bool DragController::CanProcessDrag(DragData* drag_data,
if (drag_data->ContainsFiles() && AsFileInput(result.InnerNode()))
return true;
- if (IsHTMLPlugInElement(*result.InnerNode())) {
- HTMLPlugInElement* plugin = ToHTMLPlugInElement(result.InnerNode());
+ if (auto* plugin = DynamicTo<HTMLPlugInElement>(result.InnerNode())) {
if (!plugin->CanProcessDrag() && !HasEditableStyle(*result.InnerNode()))
return false;
} else if (!HasEditableStyle(*result.InnerNode())) {
@@ -995,7 +996,7 @@ bool DragController::PopulateDragDataTransfer(LocalFrame* src,
// Observe context related to source to allow dropping drag_state_ when the
// Document goes away.
- SetContext(src->GetDocument());
+ SetExecutionContext(src->GetDocument()->ToExecutionContext());
return true;
}
@@ -1059,10 +1060,10 @@ static std::unique_ptr<DragImage> DragImageForImage(
// Substitute an appropriately-sized SVGImageForContainer, to ensure dragged
// SVG images scale seamlessly.
scoped_refptr<SVGImageForContainer> svg_image;
- if (image->IsSVGImage()) {
+ if (auto* svg_img = DynamicTo<SVGImage>(image)) {
KURL url = element->GetDocument().CompleteURL(element->ImageSourceURL());
svg_image = SVGImageForContainer::Create(
- ToSVGImage(image), FloatSize(image_element_size_in_pixels), 1, url);
+ svg_img, FloatSize(image_element_size_in_pixels), 1, url);
image = svg_image.get();
}
@@ -1072,25 +1073,17 @@ static std::unique_ptr<DragImage> DragImageForImage(
interpolation_quality = kInterpolationNone;
}
- RespectImageOrientationEnum should_respect_image_orientation =
+ RespectImageOrientationEnum respect_image_orientation =
LayoutObject::ShouldRespectImageOrientation(element->GetLayoutObject());
- ImageOrientation orientation;
-
- if (should_respect_image_orientation == kRespectImageOrientation &&
- image->IsBitmapImage())
- orientation = ToBitmapImage(image)->CurrentFrameOrientation();
-
- IntSize image_size = orientation.UsesWidthAsHeight()
- ? image->Size().TransposedSize()
- : image->Size();
+ IntSize image_size = image->Size(respect_image_orientation);
FloatSize image_scale =
DragImage::ClampedImageScale(image_size, image_element_size_in_pixels,
MaxDragImageSize(device_scale_factor));
if (image_size.Area() <= kMaxOriginalImageArea &&
(drag_image = DragImage::Create(
- image, should_respect_image_orientation, device_scale_factor,
+ image, respect_image_orientation, device_scale_factor,
interpolation_quality, kDragImageAlpha, image_scale))) {
IntSize original_size = image_element_size_in_pixels;
origin = image_element_location;
@@ -1149,12 +1142,13 @@ std::unique_ptr<DragImage> DragController::DragImageForSelection(
if (!frame.Selection().ComputeVisibleSelectionInDOMTreeDeprecated().IsRange())
return nullptr;
- frame.View()->UpdateAllLifecyclePhasesExceptPaint();
+ frame.View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kDragImage);
DCHECK(frame.GetDocument()->IsActive());
FloatRect painting_rect = ClippedSelection(frame);
GlobalPaintFlags paint_flags =
- kGlobalPaintSelectionOnly | kGlobalPaintFlattenCompositingLayers;
+ kGlobalPaintSelectionDragImageOnly | kGlobalPaintFlattenCompositingLayers;
PaintRecordBuilder builder;
frame.View()->PaintContentsOutsideOfLifecycle(
@@ -1164,7 +1158,7 @@ std::unique_ptr<DragImage> DragController::DragImageForSelection(
PropertyTreeState property_tree_state =
frame.View()->GetLayoutView()->FirstFragment().LocalBorderBoxProperties();
return DataTransfer::CreateDragImageForFrame(
- frame, opacity, kDoNotRespectImageOrientation, painting_rect.Size(),
+ frame, opacity, kRespectImageOrientation, painting_rect.Size(),
painting_rect.Location(), builder, property_tree_state);
}
@@ -1307,7 +1301,7 @@ void DragController::DoSystemDrag(DragImage* image,
bool for_link) {
did_initiate_drag_ = true;
drag_initiator_ = frame->GetDocument();
- SetContext(drag_initiator_);
+ SetExecutionContext(drag_initiator_->ToExecutionContext());
// TODO(pdr): |drag_location| and |event_pos| should be passed in as
// FloatPoints and we should calculate these adjusted values in floating
@@ -1364,17 +1358,17 @@ DragState& DragController::GetDragState() {
return *drag_state_;
}
-void DragController::ContextDestroyed(ExecutionContext*) {
+void DragController::ContextDestroyed() {
drag_state_ = nullptr;
}
-void DragController::Trace(blink::Visitor* visitor) {
+void DragController::Trace(Visitor* visitor) {
visitor->Trace(page_);
visitor->Trace(document_under_mouse_);
visitor->Trace(drag_initiator_);
visitor->Trace(drag_state_);
visitor->Trace(file_input_element_under_mouse_);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 daeed24b63d..f6b18181e61 100644
--- a/chromium/third_party/blink/renderer/core/page/drag_controller.h
+++ b/chromium/third_party/blink/renderer/core/page/drag_controller.h
@@ -29,7 +29,7 @@
#include "base/macros.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/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/page/drag_actions.h"
#include "third_party/blink/renderer/platform/geometry/int_point.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -53,7 +53,7 @@ class WebMouseEvent;
class CORE_EXPORT DragController final
: public GarbageCollected<DragController>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(DragController);
public:
@@ -90,10 +90,10 @@ class CORE_EXPORT DragController final
// to the visual viewport.
static FloatRect ClippedSelection(const LocalFrame&);
- // ContextLifecycleObserver.
- void ContextDestroyed(ExecutionContext*) final;
+ // ExecutionContextLifecycleObserver.
+ void ContextDestroyed() final;
- void Trace(blink::Visitor*) final;
+ void Trace(Visitor*) final;
private:
DispatchEventResult DispatchTextInputEventFor(LocalFrame*, DragData*);
diff --git a/chromium/third_party/blink/renderer/core/page/drag_controller_test.cc b/chromium/third_party/blink/renderer/core/page/drag_controller_test.cc
index 84135c591b7..0339a64e275 100644
--- a/chromium/third_party/blink/renderer/core/page/drag_controller_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/drag_controller_test.cc
@@ -203,8 +203,8 @@ TEST_F(DragControllerTest, DragImageForSelectionClipsToViewport) {
// the entire viewport.
int scroll_offset = 500;
LocalFrameView* frame_view = GetDocument().View();
- frame_view->LayoutViewport()->SetScrollOffset(ScrollOffset(0, scroll_offset),
- kProgrammaticScroll);
+ frame_view->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, scroll_offset), mojom::blink::ScrollType::kProgrammatic);
expected_selection = FloatRect(0, 0, node_width, viewport_height_css);
EXPECT_EQ(expected_selection, DragController::ClippedSelection(GetFrame()));
selection_image = DragController::DragImageForSelection(GetFrame(), 1);
@@ -215,8 +215,8 @@ TEST_F(DragControllerTest, DragImageForSelectionClipsToViewport) {
// Scroll 800 css px down so the top of the node is outside the viewport and
// the bottom of the node is now visible.
scroll_offset = 800;
- frame_view->LayoutViewport()->SetScrollOffset(ScrollOffset(0, scroll_offset),
- kProgrammaticScroll);
+ frame_view->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, scroll_offset), mojom::blink::ScrollType::kProgrammatic);
expected_selection = FloatRect(0, 0, node_width,
node_height + node_margin_top - scroll_offset);
EXPECT_EQ(expected_selection, DragController::ClippedSelection(GetFrame()));
@@ -271,8 +271,8 @@ TEST_F(DragControllerTest, DragImageForSelectionClipsChildFrameToViewport) {
// not include scroll offset.
int scroll_offset = 50;
LocalFrameView* frame_view = GetDocument().View();
- frame_view->LayoutViewport()->SetScrollOffset(ScrollOffset(0, scroll_offset),
- kProgrammaticScroll);
+ frame_view->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, scroll_offset), mojom::blink::ScrollType::kProgrammatic);
expected_selection = FloatRect(0, 5, 30, 20);
EXPECT_EQ(expected_selection, DragController::ClippedSelection(child_frame));
selection_image = DragController::DragImageForSelection(child_frame, 1);
@@ -283,8 +283,8 @@ TEST_F(DragControllerTest, DragImageForSelectionClipsChildFrameToViewport) {
// be shifted which should cause the iframe's selection rect to be clipped by
// the visual viewport.
scroll_offset = 210;
- frame_view->LayoutViewport()->SetScrollOffset(ScrollOffset(0, scroll_offset),
- kProgrammaticScroll);
+ frame_view->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, scroll_offset), mojom::blink::ScrollType::kProgrammatic);
expected_selection = FloatRect(0, 10, 30, 15);
EXPECT_EQ(expected_selection, DragController::ClippedSelection(child_frame));
selection_image = DragController::DragImageForSelection(child_frame, 1);
@@ -295,7 +295,8 @@ TEST_F(DragControllerTest, DragImageForSelectionClipsChildFrameToViewport) {
// visual viewport clip.
int iframe_scroll_offset = 7;
child_frame.View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, iframe_scroll_offset), kProgrammaticScroll);
+ ScrollOffset(0, iframe_scroll_offset),
+ mojom::blink::ScrollType::kProgrammatic);
expected_selection = FloatRect(0, 10, 30, 8);
EXPECT_EQ(expected_selection, DragController::ClippedSelection(child_frame));
selection_image = DragController::DragImageForSelection(child_frame, 1);
@@ -352,8 +353,8 @@ TEST_F(DragControllerTest,
// not include the parent frame's scroll offset.
int scroll_offset = 50;
LocalFrameView* frame_view = GetDocument().View();
- frame_view->LayoutViewport()->SetScrollOffset(ScrollOffset(0, scroll_offset),
- kProgrammaticScroll);
+ frame_view->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, scroll_offset), mojom::blink::ScrollType::kProgrammatic);
expected_selection = FloatRect(0, 5, 30, 20);
EXPECT_EQ(expected_selection, DragController::ClippedSelection(child_frame));
selection_image = DragController::DragImageForSelection(child_frame, 1);
@@ -365,8 +366,8 @@ TEST_F(DragControllerTest,
// be shifted which should cause the iframe's selection rect to be clipped by
// the visual viewport.
scroll_offset = 210;
- frame_view->LayoutViewport()->SetScrollOffset(ScrollOffset(0, scroll_offset),
- kProgrammaticScroll);
+ frame_view->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, scroll_offset), mojom::blink::ScrollType::kProgrammatic);
expected_selection = FloatRect(0, 10, 30, 15);
EXPECT_EQ(expected_selection, DragController::ClippedSelection(child_frame));
selection_image = DragController::DragImageForSelection(child_frame, 1);
@@ -378,7 +379,8 @@ TEST_F(DragControllerTest,
// visual viewport clip.
int iframe_scroll_offset = 7;
child_frame.View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, iframe_scroll_offset), kProgrammaticScroll);
+ ScrollOffset(0, iframe_scroll_offset),
+ mojom::blink::ScrollType::kProgrammatic);
expected_selection = FloatRect(0, 10, 30, 8);
EXPECT_EQ(expected_selection, DragController::ClippedSelection(child_frame));
selection_image = DragController::DragImageForSelection(child_frame, 1);
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 24368fea45b..e59749135cf 100644
--- a/chromium/third_party/blink/renderer/core/page/drag_data.h
+++ b/chromium/third_party/blink/renderer/core/page/drag_data.h
@@ -87,7 +87,7 @@ class CORE_EXPORT DragData {
private:
const FloatPoint client_position_;
const FloatPoint global_position_;
- const Member<DataObject> platform_drag_data_;
+ DataObject* const platform_drag_data_;
const DragOperation dragging_source_operation_mask_;
const DragApplicationFlags application_flags_;
diff --git a/chromium/third_party/blink/renderer/core/page/drag_image.cc b/chromium/third_party/blink/renderer/core/page/drag_image.cc
index 73227022bbb..8b62fc5415f 100644
--- a/chromium/third_party/blink/renderer/core/page/drag_image.cc
+++ b/chromium/third_party/blink/renderer/core/page/drag_image.cc
@@ -109,9 +109,10 @@ std::unique_ptr<DragImage> DragImage::Create(
return nullptr;
ImageOrientation orientation;
+ auto* bitmap_image = DynamicTo<BitmapImage>(image);
if (should_respect_image_orientation == kRespectImageOrientation &&
- image->IsBitmapImage())
- orientation = ToBitmapImage(image)->CurrentFrameOrientation();
+ bitmap_image)
+ orientation = bitmap_image->CurrentFrameOrientation();
SkBitmap bm;
paint_image = Image::ResizeAndOrientImage(
@@ -131,7 +132,6 @@ static Font DeriveDragLabelFont(int size,
description.SetSpecifiedSize(size);
description.SetComputedSize(size);
Font result(description);
- result.Update(nullptr);
return result;
}
@@ -203,14 +203,8 @@ std::unique_ptr<DragImage> DragImage::Create(const KURL& url,
scaled_image_size.Scale(device_scale_factor);
// TODO(fserb): are we sure this should be software?
std::unique_ptr<CanvasResourceProvider> resource_provider(
- CanvasResourceProvider::Create(
- scaled_image_size,
- CanvasResourceProvider::ResourceUsage::kSoftwareResourceUsage,
- nullptr, // context_provider_wrapper
- 0, // msaa_sample_count
- kLow_SkFilterQuality, CanvasColorParams(),
- CanvasResourceProvider::kDefaultPresentationMode,
- nullptr)); // canvas_resource_dispatcher
+ CanvasResourceProvider::CreateBitmapProvider(
+ scaled_image_size, kLow_SkFilterQuality, CanvasColorParams()));
if (!resource_provider)
return nullptr;
@@ -265,7 +259,7 @@ std::unique_ptr<DragImage> DragImage::Create(const KURL& url,
text_paint);
scoped_refptr<StaticBitmapImage> image = resource_provider->Snapshot();
- return DragImage::Create(image.get(), kDoNotRespectImageOrientation,
+ return DragImage::Create(image.get(), kRespectImageOrientation,
device_scale_factor);
}
diff --git a/chromium/third_party/blink/renderer/core/page/drag_image.h b/chromium/third_party/blink/renderer/core/page/drag_image.h
index 5a8fd1bd4c3..11d947d8387 100644
--- a/chromium/third_party/blink/renderer/core/page/drag_image.h
+++ b/chromium/third_party/blink/renderer/core/page/drag_image.h
@@ -52,7 +52,7 @@ class CORE_EXPORT DragImage {
public:
static std::unique_ptr<DragImage> Create(
Image*,
- RespectImageOrientationEnum = kDoNotRespectImageOrientation,
+ RespectImageOrientationEnum = kRespectImageOrientation,
float device_scale_factor = 1,
InterpolationQuality = kInterpolationDefault,
float opacity = 1,
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 a14478b2810..ffed0154fca 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
@@ -168,7 +168,7 @@ TEST(DragImageTest, InterpolationNone) {
scoped_refptr<TestImage> test_image =
TestImage::Create(SkImage::MakeFromBitmap(test_bitmap));
std::unique_ptr<DragImage> drag_image = DragImage::Create(
- test_image.get(), kDoNotRespectImageOrientation, 1, kInterpolationNone);
+ test_image.get(), kRespectImageOrientation, 1, kInterpolationNone);
ASSERT_TRUE(drag_image);
drag_image->Scale(2, 2);
const SkBitmap& drag_bitmap = drag_image->Bitmap();
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 9f6c405a858..b886c94d278 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(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
visitor->Trace(drag_src_);
visitor->Trace(drag_data_transfer_);
}
diff --git a/chromium/third_party/blink/renderer/core/page/event_with_hit_test_results.h b/chromium/third_party/blink/renderer/core/page/event_with_hit_test_results.h
index 839dbd901d8..a5a63f2b928 100644
--- a/chromium/third_party/blink/renderer/core/page/event_with_hit_test_results.h
+++ b/chromium/third_party/blink/renderer/core/page/event_with_hit_test_results.h
@@ -21,8 +21,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_EVENT_WITH_HIT_TEST_RESULTS_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_EVENT_WITH_HIT_TEST_RESULTS_H_
-#include "third_party/blink/public/platform/web_gesture_event.h"
-#include "third_party/blink/public/platform/web_mouse_event.h"
+#include "third_party/blink/public/common/input/web_gesture_event.h"
+#include "third_party/blink/public/common/input/web_mouse_event.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
namespace blink {
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 03eef54ac1e..225ff4339c3 100644
--- a/chromium/third_party/blink/renderer/core/page/focus_controller.cc
+++ b/chromium/third_party/blink/renderer/core/page/focus_controller.cc
@@ -28,6 +28,7 @@
#include <limits>
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
#include "third_party/blink/renderer/core/dom/container_node.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -49,6 +50,7 @@
#include "third_party/blink/renderer/core/html/forms/text_control_element.h"
#include "third_party/blink/renderer/core/html/html_plugin_element.h"
#include "third_party/blink/renderer/core/html/html_slot_element.h"
+#include "third_party/blink/renderer/core/html/portal/html_portal_element.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
@@ -111,7 +113,7 @@ class FocusNavigation : public GarbageCollected<FocusNavigation> {
return FindOwner(*root_);
}
- void Trace(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
visitor->Trace(root_);
visitor->Trace(slot_);
}
@@ -175,14 +177,13 @@ class ScopedFocusNavigation {
// [1]
// https://html.spec.whatwg.org/C/#sequential-focus-navigation
// [2] https://w3c.github.io/webcomponents/spec/shadow/#focus-navigation
- Element* FindFocusableElement(WebFocusType type) {
- return (type == kWebFocusTypeForward) ? NextFocusableElement()
- : PreviousFocusableElement();
+ Element* FindFocusableElement(mojom::blink::FocusType type) {
+ return (type == mojom::blink::FocusType::kForward)
+ ? NextFocusableElement()
+ : PreviousFocusableElement();
}
- Element* CurrentElement() const {
- return const_cast<Element*>(current_.Get());
- }
+ Element* CurrentElement() const { return const_cast<Element*>(current_); }
Element* Owner() const;
static ScopedFocusNavigation CreateFor(const Element&,
@@ -209,7 +210,7 @@ class ScopedFocusNavigation {
const Element* current,
FocusController::OwnerMap&);
- Element* FindElementWithExactTabIndex(int tab_index, WebFocusType);
+ Element* FindElementWithExactTabIndex(int tab_index, mojom::blink::FocusType);
Element* NextElementWithGreaterTabIndex(int tab_index);
Element* PreviousElementWithLowerTabIndex(int tab_index);
Element* NextFocusableElement();
@@ -221,8 +222,8 @@ class ScopedFocusNavigation {
void MoveToFirst();
void MoveToLast();
- Member<const Element> current_;
- Member<FocusNavigation> navigation_;
+ const Element* current_;
+ FocusNavigation* navigation_;
};
ScopedFocusNavigation::ScopedFocusNavigation(
@@ -354,7 +355,7 @@ bool ScopedFocusNavigation::IsSlotFallbackScopedForThisSlot(
inline void DispatchBlurEvent(const Document& document,
Element& focused_element) {
- focused_element.DispatchBlurEvent(nullptr, kWebFocusTypePage);
+ focused_element.DispatchBlurEvent(nullptr, mojom::blink::FocusType::kPage);
if (focused_element == document.FocusedElement()) {
focused_element.DispatchFocusOutEvent(event_type_names::kFocusout, nullptr);
if (focused_element == document.FocusedElement())
@@ -365,13 +366,14 @@ inline void DispatchBlurEvent(const Document& document,
inline void DispatchFocusEvent(const Document& document,
Element& focused_element) {
- focused_element.DispatchFocusEvent(nullptr, kWebFocusTypePage);
+ focused_element.DispatchFocusEvent(nullptr, mojom::blink::FocusType::kPage);
if (focused_element == document.FocusedElement()) {
focused_element.DispatchFocusInEvent(event_type_names::kFocusin, nullptr,
- kWebFocusTypePage);
+ mojom::blink::FocusType::kPage);
if (focused_element == document.FocusedElement()) {
focused_element.DispatchFocusInEvent(event_type_names::kDOMFocusIn,
- nullptr, kWebFocusTypePage);
+ nullptr,
+ mojom::blink::FocusType::kPage);
}
}
}
@@ -392,8 +394,9 @@ inline void DispatchEventsOnWindowAndFocusedElement(Document* document,
if (!focused && document->FocusedElement()) {
Element* focused_element = document->FocusedElement();
- // Use focus_type kWebFocusTypePage, same as used in DispatchBlurEvent.
- focused_element->SetFocused(false, kWebFocusTypePage);
+ // Use focus_type mojom::blink::FocusType::kPage, same as used in
+ // DispatchBlurEvent.
+ focused_element->SetFocused(false, mojom::blink::FocusType::kPage);
focused_element->SetHasFocusWithinUpToAncestor(false, nullptr);
DispatchBlurEvent(*document, *focused_element);
}
@@ -404,8 +407,9 @@ inline void DispatchEventsOnWindowAndFocusedElement(Document* document,
}
if (focused && document->FocusedElement()) {
Element* focused_element(document->FocusedElement());
- // Use focus_type kWebFocusTypePage, same as used in DispatchFocusEvent.
- focused_element->SetFocused(true, kWebFocusTypePage);
+ // Use focus_type mojom::blink::FocusType::kPage, same as used in
+ // DispatchFocusEvent.
+ focused_element->SetFocused(true, mojom::blink::FocusType::kPage);
focused_element->SetHasFocusWithinUpToAncestor(true, nullptr);
DispatchFocusEvent(*document, *focused_element);
}
@@ -460,10 +464,11 @@ inline bool ShouldVisit(Element& element) {
Element* ScopedFocusNavigation::FindElementWithExactTabIndex(
int tab_index,
- WebFocusType type) {
+ mojom::blink::FocusType type) {
// Search is inclusive of start
- for (; CurrentElement();
- type == kWebFocusTypeForward ? MoveToNext() : MoveToPrevious()) {
+ for (; CurrentElement(); type == mojom::blink::FocusType::kForward
+ ? MoveToNext()
+ : MoveToPrevious()) {
Element* current = CurrentElement();
if (ShouldVisit(*current) && AdjustedTabIndex(*current) == tab_index)
return current;
@@ -523,8 +528,8 @@ Element* ScopedFocusNavigation::NextFocusableElement() {
// First try to find an element with the same tabindex as start that comes
// after start in the scope.
MoveToNext();
- if (Element* winner =
- FindElementWithExactTabIndex(tab_index, kWebFocusTypeForward))
+ if (Element* winner = FindElementWithExactTabIndex(
+ tab_index, mojom::blink::FocusType::kForward))
return winner;
}
if (!tab_index) {
@@ -547,7 +552,7 @@ Element* ScopedFocusNavigation::NextFocusableElement() {
// There are no elements with a tabindex greater than start's tabindex,
// so find the first element with a tabindex of 0.
MoveToFirst();
- return FindElementWithExactTabIndex(0, kWebFocusTypeForward);
+ return FindElementWithExactTabIndex(0, mojom::blink::FocusType::kForward);
}
Element* ScopedFocusNavigation::PreviousFocusableElement() {
@@ -573,8 +578,8 @@ Element* ScopedFocusNavigation::PreviousFocusableElement() {
return current;
}
} else {
- if (Element* winner =
- FindElementWithExactTabIndex(tab_index, kWebFocusTypeBackward))
+ if (Element* winner = FindElementWithExactTabIndex(
+ tab_index, mojom::blink::FocusType::kBackward))
return winner;
}
@@ -593,7 +598,8 @@ Element* FindFocusableElementRecursivelyForward(
ScopedFocusNavigation& scope,
FocusController::OwnerMap& owner_map) {
// Starting element is exclusive.
- while (Element* found = scope.FindFocusableElement(kWebFocusTypeForward)) {
+ while (Element* found =
+ scope.FindFocusableElement(mojom::blink::FocusType::kForward)) {
if (found->DelegatesFocus()) {
// If tabindex is positive, invalid, or missing, find focusable element
// inside its shadow tree.
@@ -628,7 +634,8 @@ Element* FindFocusableElementRecursivelyBackward(
ScopedFocusNavigation& scope,
FocusController::OwnerMap& owner_map) {
// Starting element is exclusive.
- while (Element* found = scope.FindFocusableElement(kWebFocusTypeBackward)) {
+ while (Element* found =
+ scope.FindFocusableElement(mojom::blink::FocusType::kBackward)) {
// Now |found| is on a focusable shadow host.
// Find inside shadow backwards. If any focusable element is found, return
// it, otherwise return the host itself.
@@ -667,16 +674,16 @@ Element* FindFocusableElementRecursivelyBackward(
return nullptr;
}
-Element* FindFocusableElementRecursively(WebFocusType type,
+Element* FindFocusableElementRecursively(mojom::blink::FocusType type,
ScopedFocusNavigation& scope,
FocusController::OwnerMap& owner_map) {
- return (type == kWebFocusTypeForward)
+ return (type == mojom::blink::FocusType::kForward)
? FindFocusableElementRecursivelyForward(scope, owner_map)
: FindFocusableElementRecursivelyBackward(scope, owner_map);
}
Element* FindFocusableElementDescendingDownIntoFrameDocument(
- WebFocusType type,
+ mojom::blink::FocusType type,
Element* element,
FocusController::OwnerMap& owner_map) {
// The element we found might be a HTMLFrameOwnerElement, so descend down the
@@ -688,7 +695,8 @@ Element* FindFocusableElementDescendingDownIntoFrameDocument(
auto* container_local_frame = DynamicTo<LocalFrame>(owner.ContentFrame());
if (!container_local_frame)
break;
- container_local_frame->GetDocument()->UpdateStyleAndLayout();
+ container_local_frame->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kFocus);
ScopedFocusNavigation scope =
ScopedFocusNavigation::OwnedByIFrame(owner, owner_map);
Element* found_element =
@@ -729,7 +737,7 @@ Element* FindFocusableElementAcrossFocusScopesForward(
found = FindFocusableElementRecursivelyForward(current_scope, owner_map);
}
return FindFocusableElementDescendingDownIntoFrameDocument(
- kWebFocusTypeForward, found, owner_map);
+ mojom::blink::FocusType::kForward, found, owner_map);
}
Element* FindFocusableElementAcrossFocusScopesBackward(
@@ -752,14 +760,14 @@ Element* FindFocusableElementAcrossFocusScopesBackward(
found = FindFocusableElementRecursivelyBackward(current_scope, owner_map);
}
return FindFocusableElementDescendingDownIntoFrameDocument(
- kWebFocusTypeBackward, found, owner_map);
+ mojom::blink::FocusType::kBackward, found, owner_map);
}
Element* FindFocusableElementAcrossFocusScopes(
- WebFocusType type,
+ mojom::blink::FocusType type,
ScopedFocusNavigation& scope,
FocusController::OwnerMap& owner_map) {
- return (type == kWebFocusTypeForward)
+ return (type == mojom::blink::FocusType::kForward)
? FindFocusableElementAcrossFocusScopesForward(scope, owner_map)
: FindFocusableElementAcrossFocusScopesBackward(scope, owner_map);
}
@@ -931,7 +939,7 @@ void FocusController::SetFocusEmulationEnabled(bool emulate_focus) {
FocusHasChanged();
}
-bool FocusController::SetInitialFocus(WebFocusType type) {
+bool FocusController::SetInitialFocus(mojom::blink::FocusType type) {
bool did_advance_focus = AdvanceFocus(type, true);
// If focus is being set initially, accessibility needs to be informed that
@@ -950,12 +958,12 @@ bool FocusController::SetInitialFocus(WebFocusType type) {
}
bool FocusController::AdvanceFocus(
- WebFocusType type,
+ mojom::blink::FocusType type,
bool initial_focus,
InputDeviceCapabilities* source_capabilities) {
switch (type) {
- case kWebFocusTypeForward:
- case kWebFocusTypeBackward: {
+ case mojom::blink::FocusType::kForward:
+ case mojom::blink::FocusType::kBackward: {
// We should never hit this when a RemoteFrame is focused, since the key
// event that initiated focus advancement should've been routed to that
// frame's process from the beginning.
@@ -963,7 +971,7 @@ bool FocusController::AdvanceFocus(
return AdvanceFocusInDocumentOrder(starting_frame, nullptr, type,
initial_focus, source_capabilities);
}
- case kWebFocusTypeSpatialNavigation:
+ case mojom::blink::FocusType::kSpatialNavigation:
// Fallthrough - SpatialNavigation should use
// SpatialNavigationController.
default:
@@ -974,7 +982,7 @@ bool FocusController::AdvanceFocus(
}
bool FocusController::AdvanceFocusAcrossFrames(
- WebFocusType type,
+ mojom::blink::FocusType type,
RemoteFrame* from,
LocalFrame* to,
InputDeviceCapabilities* source_capabilities) {
@@ -1005,7 +1013,7 @@ inline bool IsNonFocusableShadowHost(const Element& element) {
bool FocusController::AdvanceFocusInDocumentOrder(
LocalFrame* frame,
Element* start,
- WebFocusType type,
+ mojom::blink::FocusType type,
bool initial_focus,
InputDeviceCapabilities* source_capabilities) {
DCHECK(frame);
@@ -1020,7 +1028,7 @@ bool FocusController::AdvanceFocusInDocumentOrder(
if (!current && !initial_focus)
current = document->SequentialFocusNavigationStartingPoint(type);
- document->UpdateStyleAndLayout();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kFocus);
ScopedFocusNavigation scope =
current ? ScopedFocusNavigation::CreateFor(*current, owner_map)
: ScopedFocusNavigation::CreateForDocument(*document, owner_map);
@@ -1077,8 +1085,12 @@ bool FocusController::AdvanceFocusInDocumentOrder(
auto* owner = DynamicTo<HTMLFrameOwnerElement>(element);
bool has_remote_frame =
owner && owner->ContentFrame() && owner->ContentFrame()->IsRemoteFrame();
- if (owner && (has_remote_frame || !IsHTMLPlugInElement(*element) ||
- !element->IsKeyboardFocusable())) {
+ // Portals do not currently allow input events, so we block focus from
+ // advancing into the portal's content frame.
+ bool is_portal = IsA<HTMLPortalElement>(owner);
+ if (owner && !is_portal &&
+ (has_remote_frame || !IsA<HTMLPlugInElement>(*element) ||
+ !element->IsKeyboardFocusable())) {
// FIXME: We should not focus frames that have no scrollbars, as focusing
// them isn't useful to the user.
if (!owner->ContentFrame())
@@ -1120,23 +1132,25 @@ bool FocusController::AdvanceFocusInDocumentOrder(
return true;
}
-Element* FocusController::FindFocusableElement(WebFocusType type,
+Element* FocusController::FindFocusableElement(mojom::blink::FocusType type,
Element& element,
OwnerMap& owner_map) {
// FIXME: No spacial navigation code yet.
- DCHECK(type == kWebFocusTypeForward || type == kWebFocusTypeBackward);
+ DCHECK(type == mojom::blink::FocusType::kForward ||
+ type == mojom::blink::FocusType::kBackward);
ScopedFocusNavigation scope =
ScopedFocusNavigation::CreateFor(element, owner_map);
return FindFocusableElementAcrossFocusScopes(type, scope, owner_map);
}
-Element* FocusController::NextFocusableElementInForm(Element* element,
- WebFocusType focus_type) {
+Element* FocusController::NextFocusableElementInForm(
+ Element* element,
+ mojom::blink::FocusType focus_type) {
// TODO(ajith.v) Due to crbug.com/781026 when next/previous element is far
// from current element in terms of tabindex, then it's signalling CPU load.
// Will nvestigate further for a proper solution later.
static const int kFocusTraversalThreshold = 50;
- element->GetDocument().UpdateStyleAndLayout();
+ element->GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kFocus);
auto* html_element = DynamicTo<HTMLElement>(element);
if (!html_element)
return nullptr;
@@ -1191,42 +1205,36 @@ Element* FocusController::NextFocusableElementInForm(Element* element,
return nullptr;
}
+// This is an implementation of step 2 of the "shadow host" branch of
+// https://html.spec.whatwg.org/C/#get-the-focusable-area
Element* FocusController::FindFocusableElementInShadowHost(
const Element& shadow_host) {
DCHECK(shadow_host.AuthorShadowRoot());
- OwnerMap owner_map;
- ScopedFocusNavigation scope =
- ScopedFocusNavigation::OwnedByShadowHost(shadow_host, owner_map);
- Element* result = FindFocusableElementAcrossFocusScopes(kWebFocusTypeForward,
- scope, owner_map);
- if (!result)
- return nullptr;
- // Check if |found| is the first focusable element under |element|, and count
- // if it's not.
- const Node* current = &shadow_host;
- while ((current = FlatTreeTraversal::Next(*current))) {
- if (!current->IsElementNode())
- continue;
- if (current == result) {
- // We've reached |found|, which means |found| is the first focusable
- // element so we don't count this.
- break;
- }
- if (ToElement(current)->IsFocusable()) {
- UseCounter::Count(shadow_host.GetDocument(),
- WebFeature::kDelegateFocusNotFirstInFlatTree);
- break;
+ // We have no behavior difference by focus trigger. Skip step 2.1.
+
+ // 2.2. Otherwise, let possible focus delegates be the list of all
+ // focusable areas whose DOM anchor is a descendant of focus target
+ // in the flat tree.
+ // 2.3. Return the first focusable area in tree order of their DOM
+ // anchors in possible focus delegates, or null if possible focus
+ // delegates is empty.
+ Node* current = const_cast<Element*>(&shadow_host);
+ while ((current = FlatTreeTraversal::Next(*current, &shadow_host))) {
+ if (auto* current_element = DynamicTo<Element>(current)) {
+ if (current_element->IsFocusable())
+ return current_element;
}
}
-
- return result;
+ return nullptr;
}
-Element* FocusController::FindFocusableElementAfter(Element& element,
- WebFocusType type) {
- if (type != kWebFocusTypeForward && type != kWebFocusTypeBackward)
+Element* FocusController::FindFocusableElementAfter(
+ Element& element,
+ mojom::blink::FocusType type) {
+ if (type != mojom::blink::FocusType::kForward &&
+ type != mojom::blink::FocusType::kBackward)
return nullptr;
- element.GetDocument().UpdateStyleAndLayout();
+ element.GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kFocus);
OwnerMap owner_map;
return FindFocusableElement(type, element, owner_map);
@@ -1241,7 +1249,8 @@ bool FocusController::SetFocusedElement(Element* element,
Frame* new_focused_frame) {
return SetFocusedElement(
element, new_focused_frame,
- FocusParams(SelectionBehaviorOnFocus::kNone, kWebFocusTypeNone, nullptr));
+ FocusParams(SelectionBehaviorOnFocus::kNone,
+ mojom::blink::FocusType::kNone, nullptr));
}
bool FocusController::SetFocusedElement(Element* element,
@@ -1330,7 +1339,7 @@ void FocusController::NotifyFocusChangedObservers() const {
it->FocusedFrameChanged();
}
-void FocusController::Trace(blink::Visitor* visitor) {
+void FocusController::Trace(Visitor* visitor) {
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 22c60670ac5..b22ebd992f4 100644
--- a/chromium/third_party/blink/renderer/core/page/focus_controller.h
+++ b/chromium/third_party/blink/renderer/core/page/focus_controller.h
@@ -28,7 +28,7 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/public/platform/web_focus_type.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -73,23 +73,23 @@ class CORE_EXPORT FocusController final
// http://www.w3.org/TR/html5/editing.html#dom-document-hasfocus
bool IsDocumentFocused(const Document&) const;
- bool SetInitialFocus(WebFocusType);
- bool AdvanceFocus(WebFocusType type,
+ bool SetInitialFocus(mojom::blink::FocusType);
+ bool AdvanceFocus(mojom::blink::FocusType type,
InputDeviceCapabilities* source_capabilities = nullptr) {
return AdvanceFocus(type, false, source_capabilities);
}
bool AdvanceFocusAcrossFrames(
- WebFocusType,
+ mojom::blink::FocusType,
RemoteFrame* from,
LocalFrame* to,
InputDeviceCapabilities* source_capabilities = nullptr);
- Element* FindFocusableElementInShadowHost(const Element& shadow_host);
- Element* NextFocusableElementInForm(Element*, WebFocusType);
- Element* FindFocusableElementAfter(Element& element, WebFocusType);
+ static Element* FindFocusableElementInShadowHost(const Element& shadow_host);
+ Element* NextFocusableElementInForm(Element*, mojom::blink::FocusType);
+ Element* FindFocusableElementAfter(Element& element, mojom::blink::FocusType);
bool SetFocusedElement(Element*, Frame*, const FocusParams&);
// |setFocusedElement| variant with SelectionBehaviorOnFocus::None,
- // |WebFocusTypeNone, and null InputDeviceCapabilities.
+ // |kFocusTypeNone, and null InputDeviceCapabilities.
bool SetFocusedElement(Element*, Frame*);
void SetActive(bool);
@@ -102,19 +102,18 @@ class CORE_EXPORT FocusController final
void RegisterFocusChangedObserver(FocusChangedObserver*);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
+ Element* FindFocusableElement(mojom::blink::FocusType, Element&, OwnerMap&);
- Element* FindFocusableElement(WebFocusType, Element&, OwnerMap&);
-
- bool AdvanceFocus(WebFocusType,
+ bool AdvanceFocus(mojom::blink::FocusType,
bool initial_focus,
InputDeviceCapabilities* source_capabilities = nullptr);
bool AdvanceFocusInDocumentOrder(
LocalFrame*,
Element* start,
- WebFocusType,
+ mojom::blink::FocusType,
bool initial_focus,
InputDeviceCapabilities* source_capabilities);
diff --git a/chromium/third_party/blink/renderer/core/page/focus_controller_test.cc b/chromium/third_party/blink/renderer/core/page/focus_controller_test.cc
index b597c0466a6..be6f4890c27 100644
--- a/chromium/third_party/blink/renderer/core/page/focus_controller_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/focus_controller_test.cc
@@ -6,6 +6,7 @@
#include <memory>
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/html/html_element.h"
@@ -19,19 +20,19 @@ class FocusControllerTest : public PageTestBase {
};
TEST_F(FocusControllerTest, SetInitialFocus) {
- GetDocument().body()->SetInnerHTMLFromString("<input><textarea>");
+ GetDocument().body()->setInnerHTML("<input><textarea>");
auto* input = To<Element>(GetDocument().body()->firstChild());
// Set sequential focus navigation point before the initial focus.
input->focus();
input->blur();
- GetFocusController().SetInitialFocus(kWebFocusTypeForward);
+ GetFocusController().SetInitialFocus(mojom::blink::FocusType::kForward);
EXPECT_EQ(input, GetDocument().FocusedElement())
<< "We should ignore sequential focus navigation starting point in "
"setInitialFocus().";
}
TEST_F(FocusControllerTest, DoNotCrash1) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<div id='host'></div>This test is for crbug.com/609012<p id='target' "
"tabindex='0'></p>");
// <div> with shadow root
@@ -45,13 +46,13 @@ TEST_F(FocusControllerTest, DoNotCrash1) {
// Set sequential focus navigation point at text node.
GetDocument().SetSequentialFocusNavigationStartingPoint(text);
- GetFocusController().AdvanceFocus(kWebFocusTypeForward);
+ GetFocusController().AdvanceFocus(mojom::blink::FocusType::kForward);
EXPECT_EQ(target, GetDocument().FocusedElement())
<< "This should not hit assertion and finish properly.";
}
TEST_F(FocusControllerTest, DoNotCrash2) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<p id='target' tabindex='0'></p>This test is for crbug.com/609012<div "
"id='host'></div>");
// <p>
@@ -65,7 +66,7 @@ TEST_F(FocusControllerTest, DoNotCrash2) {
// Set sequential focus navigation point at text node.
GetDocument().SetSequentialFocusNavigationStartingPoint(text);
- GetFocusController().AdvanceFocus(kWebFocusTypeBackward);
+ GetFocusController().AdvanceFocus(mojom::blink::FocusType::kBackward);
EXPECT_EQ(target, GetDocument().FocusedElement())
<< "This should not hit assertion and finish properly.";
}
@@ -81,7 +82,7 @@ TEST_F(FocusControllerTest, SetActiveOnInactiveDocument) {
// This test is for crbug.com/733218
TEST_F(FocusControllerTest, SVGFocusableElementInForm) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<form>"
"<input id='first'>"
"<svg width='100px' height='100px' tabindex='0'>"
@@ -95,18 +96,18 @@ TEST_F(FocusControllerTest, SVGFocusableElementInForm) {
auto* last = To<Element>(form->lastChild());
Element* next = GetFocusController().NextFocusableElementInForm(
- first, kWebFocusTypeForward);
+ first, mojom::blink::FocusType::kForward);
EXPECT_EQ(next, last)
<< "SVG Element should be skipped even when focusable in form.";
Element* prev = GetFocusController().NextFocusableElementInForm(
- next, kWebFocusTypeBackward);
+ next, mojom::blink::FocusType::kBackward);
EXPECT_EQ(prev, first)
<< "SVG Element should be skipped even when focusable in form.";
}
TEST_F(FocusControllerTest, FindFocusableAfterElement) {
- GetDocument().body()->SetInnerHTMLFromString(
+ GetDocument().body()->setInnerHTML(
"<input id='first'><div id='second'></div><input id='third'><div "
"id='fourth' tabindex='0'></div>");
Element* first = GetElementById("first");
@@ -114,25 +115,25 @@ TEST_F(FocusControllerTest, FindFocusableAfterElement) {
Element* third = GetElementById("third");
Element* fourth = GetElementById("fourth");
EXPECT_EQ(third, GetFocusController().FindFocusableElementAfter(
- *first, kWebFocusTypeForward));
+ *first, mojom::blink::FocusType::kForward));
EXPECT_EQ(third, GetFocusController().FindFocusableElementAfter(
- *second, kWebFocusTypeForward));
+ *second, mojom::blink::FocusType::kForward));
EXPECT_EQ(fourth, GetFocusController().FindFocusableElementAfter(
- *third, kWebFocusTypeForward));
+ *third, mojom::blink::FocusType::kForward));
EXPECT_EQ(nullptr, GetFocusController().FindFocusableElementAfter(
- *fourth, kWebFocusTypeForward));
+ *fourth, mojom::blink::FocusType::kForward));
EXPECT_EQ(nullptr, GetFocusController().FindFocusableElementAfter(
- *first, kWebFocusTypeBackward));
+ *first, mojom::blink::FocusType::kBackward));
EXPECT_EQ(first, GetFocusController().FindFocusableElementAfter(
- *second, kWebFocusTypeBackward));
+ *second, mojom::blink::FocusType::kBackward));
EXPECT_EQ(first, GetFocusController().FindFocusableElementAfter(
- *third, kWebFocusTypeBackward));
+ *third, mojom::blink::FocusType::kBackward));
EXPECT_EQ(third, GetFocusController().FindFocusableElementAfter(
- *fourth, kWebFocusTypeBackward));
+ *fourth, mojom::blink::FocusType::kBackward));
EXPECT_EQ(nullptr, GetFocusController().FindFocusableElementAfter(
- *first, kWebFocusTypeNone));
+ *first, mojom::blink::FocusType::kNone));
}
} // namespace blink
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 aa41f8357f2..3c3ef06af37 100644
--- a/chromium/third_party/blink/renderer/core/page/frame_tree.cc
+++ b/chromium/third_party/blink/renderer/core/page/frame_tree.cc
@@ -349,7 +349,7 @@ Frame* FrameTree::TraverseNext(const Frame* stay_within) const {
return nullptr;
}
-void FrameTree::Trace(blink::Visitor* visitor) {
+void FrameTree::Trace(Visitor* visitor) {
visitor->Trace(this_frame_);
}
@@ -384,7 +384,7 @@ static void printFrames(const blink::Frame* frame,
printf(" document=%p\n", local_frame ? local_frame->GetDocument() : nullptr);
printIndent(indent);
printf(" uri=%s\n\n",
- local_frame
+ local_frame && local_frame->GetDocument()
? local_frame->GetDocument()->Url().GetString().Utf8().c_str()
: nullptr);
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 2b43291ff02..8bfb2cd5898 100644
--- a/chromium/third_party/blink/renderer/core/page/frame_tree.h
+++ b/chromium/third_party/blink/renderer/core/page/frame_tree.h
@@ -69,7 +69,7 @@ class CORE_EXPORT FrameTree final {
public:
FindResult(Frame* f, bool is_new) : frame(f), new_window(is_new) {}
- Member<Frame> frame;
+ Frame* frame;
bool new_window;
};
FindResult FindOrCreateFrameForNavigation(FrameLoadRequest&,
@@ -87,7 +87,7 @@ class CORE_EXPORT FrameTree final {
unsigned ScopedChildCount() const;
void InvalidateScopedChildCount();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
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 6c4945fb795..2bf0e6a56f4 100644
--- a/chromium/third_party/blink/renderer/core/page/link_highlight.cc
+++ b/chromium/third_party/blink/renderer/core/page/link_highlight.cc
@@ -25,19 +25,16 @@ LinkHighlight::~LinkHighlight() {
RemoveHighlight();
}
-void LinkHighlight::Trace(blink::Visitor* visitor) {
+void LinkHighlight::Trace(Visitor* visitor) {
visitor->Trace(page_);
}
void LinkHighlight::RemoveHighlight() {
- if (impl_) {
- if (timeline_)
- timeline_->AnimationDestroyed(*impl_);
- if (auto* node = impl_->GetNode()) {
- if (auto* layout_object = node->GetLayoutObject())
- layout_object->SetNeedsPaintPropertyUpdate();
- }
- }
+ if (!impl_)
+ return;
+
+ if (timeline_)
+ timeline_->AnimationDestroyed(*impl_);
impl_.reset();
}
@@ -50,9 +47,12 @@ void LinkHighlight::SetTapHighlight(Node* node) {
// don't get a new target to highlight.
RemoveHighlight();
- if (!node || !node->GetLayoutObject())
+ if (!node)
return;
+ DCHECK(node->GetLayoutObject());
+ DCHECK(!node->IsTextNode());
+
Color highlight_color =
node->GetLayoutObject()->StyleRef().TapHighlightColor();
// Safari documentation for -webkit-tap-highlight-color says if the
@@ -64,7 +64,6 @@ void LinkHighlight::SetTapHighlight(Node* node) {
impl_ = std::make_unique<LinkHighlightImpl>(node);
if (timeline_)
timeline_->AnimationAttached(*impl_);
- node->GetLayoutObject()->SetNeedsPaintPropertyUpdate();
}
LocalFrame* LinkHighlight::MainFrame() const {
@@ -102,9 +101,7 @@ void LinkHighlight::WillCloseAnimationHost() {
bool LinkHighlight::NeedsHighlightEffectInternal(
const LayoutObject& object) const {
DCHECK(impl_);
- if (auto* node = impl_->GetNode())
- return node->GetLayoutObject() == &object;
- return false;
+ return &object == impl_->GetLayoutObject();
}
void LinkHighlight::UpdateBeforePrePaint() {
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 b1df87c73f1..9e793ff77b3 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(blink::Visitor*);
+ virtual void Trace(Visitor*);
void ResetForPageNavigation();
diff --git a/chromium/third_party/blink/renderer/core/page/page.cc b/chromium/third_party/blink/renderer/core/page/page.cc
index 90c4ea4fe9c..50e76a0e0a6 100644
--- a/chromium/third_party/blink/renderer/core/page/page.cc
+++ b/chromium/third_party/blink/renderer/core/page/page.cc
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/core/css/media_feature_overrides.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/vision_deficiency.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/visited_link_state.h"
#include "third_party/blink/renderer/core/editing/drag_caret.h"
@@ -53,6 +54,8 @@
#include "third_party/blink/renderer/core/html/media/html_media_element.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.h"
+#include "third_party/blink/renderer/core/inspector/inspector_issue_storage.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/layout/text_autosizer.h"
#include "third_party/blink/renderer/core/loader/idleness_detector.h"
@@ -80,6 +83,7 @@
#include "third_party/blink/renderer/core/svg/graphics/svg_image_chrome_client.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.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/frame_scheduler.h"
#include "third_party/skia/include/core/SkColor.h"
@@ -157,11 +161,6 @@ Page* Page::CreateOrdinary(PageClients& page_clients, Page* opener) {
page->prev_related_page_ = opener;
page->next_related_page_ = next;
next->prev_related_page_ = page;
-
- // No need to update |prev| here as if |next| != |prev|, |prev| was already
- // marked as having related pages.
- next->UpdateHasRelatedPages();
- page->UpdateHasRelatedPages();
}
OrdinaryPages().insert(page);
@@ -187,6 +186,7 @@ Page::Page(PageClients& page_clients)
MakeGarbageCollected<PointerLockController>(this)),
browser_controls_(MakeGarbageCollected<BrowserControls>(*this)),
console_message_storage_(MakeGarbageCollected<ConsoleMessageStorage>()),
+ inspector_issue_storage_(MakeGarbageCollected<InspectorIssueStorage>()),
global_root_scroller_controller_(
MakeGarbageCollected<TopDocumentRootScrollerController>(*this)),
visual_viewport_(MakeGarbageCollected<VisualViewport>(*this)),
@@ -213,6 +213,13 @@ Page::Page(PageClients& page_clients)
web_text_autosizer_page_info_({0, 0, 1.f}) {
DCHECK(!AllPages().Contains(this));
AllPages().insert(this);
+
+ // Try to dereference the scrollbar theme. This is here to ensure tests are
+ // correctly setting up their platform theme or mocking scrollbars. On
+ // Android, unit tests run without a ThemeEngine and thus must set a mock
+ // ScrollbarTheme, if they don't this call will crash. To set a mock theme,
+ // see ScopedMockOverlayScrollbars or WebScopedMockScrollbars.
+ DCHECK(&GetScrollbarTheme());
}
Page::~Page() {
@@ -272,6 +279,14 @@ const ConsoleMessageStorage& Page::GetConsoleMessageStorage() const {
return *console_message_storage_;
}
+InspectorIssueStorage& Page::GetInspectorIssueStorage() {
+ return *inspector_issue_storage_;
+}
+
+const InspectorIssueStorage& Page::GetInspectorIssueStorage() const {
+ return *inspector_issue_storage_;
+}
+
TopDocumentRootScrollerController& Page::GlobalRootScrollerController() const {
return *global_root_scroller_controller_;
}
@@ -302,9 +317,6 @@ void Page::SetMainFrame(Frame* main_frame) {
main_frame_ = main_frame;
page_scheduler_->SetIsMainFrameLocal(main_frame->IsLocalFrame());
- // |has_related_pages_| is only reported when the main frame is local, so make
- // sure it's updated after the main frame changes.
- UpdateHasRelatedPages();
}
LocalFrame* Page::DeprecatedLocalMainFrame() const {
@@ -316,7 +328,6 @@ void Page::DocumentDetached(Document* document) {
context_menu_controller_->DocumentDetached(document);
if (validation_message_client_)
validation_message_client_->DocumentDetached(*document);
- hosts_using_features_.DocumentDetached(*document);
if (agent_metrics_collector_)
agent_metrics_collector_->DidDetachDocument(*document);
@@ -391,7 +402,7 @@ void Page::ResetPluginData() {
static void RestoreSVGImageAnimations() {
for (const Page* page : AllPages()) {
if (auto* svg_image_chrome_client =
- ToSVGImageChromeClientOrNull(page->GetChromeClient()))
+ DynamicTo<SVGImageChromeClient>(page->GetChromeClient()))
svg_image_chrome_client->RestoreAnimationIfNeeded();
}
}
@@ -509,7 +520,11 @@ void Page::SetVisibilityState(PageVisibilityState visibility_state,
if (is_initial_state)
return;
- NotifyPageVisibilityChanged();
+ page_visibility_observer_list_.ForEachObserver(
+ [](PageVisibilityObserver* observer) {
+ observer->PageVisibilityChanged();
+ });
+
if (main_frame_) {
if (visibility_state_ == PageVisibilityState::kVisible)
RestoreSVGImageAnimations();
@@ -649,8 +664,10 @@ void Page::SettingsChanged(SettingsDelegate::ChangeType change_type) {
case SettingsDelegate::kMediaQueryChange:
for (Frame* frame = MainFrame(); frame;
frame = frame->Tree().TraverseNext()) {
- if (auto* local_frame = DynamicTo<LocalFrame>(frame))
- local_frame->GetDocument()->MediaQueryAffectingValueChanged();
+ if (auto* local_frame = DynamicTo<LocalFrame>(frame)) {
+ local_frame->GetDocument()->MediaQueryAffectingValueChanged(
+ MediaValueChange::kOther);
+ }
}
break;
case SettingsDelegate::kAccessibilityStateChange:
@@ -721,14 +738,7 @@ void Page::SettingsChanged(SettingsDelegate::ChangeType change_type) {
break;
}
case SettingsDelegate::kPaintChange: {
- for (Frame* frame = MainFrame(); frame;
- frame = frame->Tree().TraverseNext()) {
- auto* local_frame = DynamicTo<LocalFrame>(frame);
- if (!local_frame)
- continue;
- if (LayoutView* view = local_frame->ContentLayoutObject())
- view->InvalidatePaintForViewAndCompositedLayers();
- }
+ InvalidatePaint();
break;
}
case SettingsDelegate::kScrollbarLayoutChange: {
@@ -755,11 +765,7 @@ void Page::SettingsChanged(SettingsDelegate::ChangeType change_type) {
break;
}
case SettingsDelegate::kColorSchemeChange:
- for (Frame* frame = MainFrame(); frame;
- frame = frame->Tree().TraverseNext()) {
- if (auto* local_frame = DynamicTo<LocalFrame>(frame))
- local_frame->GetDocument()->ColorSchemeChanged();
- }
+ InvalidateColorScheme();
break;
case SettingsDelegate::kSpatialNavigationChange:
if (spatial_navigation_controller_ ||
@@ -783,6 +789,34 @@ void Page::SettingsChanged(SettingsDelegate::ChangeType change_type) {
}
break;
}
+ case SettingsDelegate::kVisionDeficiencyChange: {
+ if (auto* main_local_frame = DynamicTo<LocalFrame>(MainFrame()))
+ main_local_frame->GetDocument()->VisionDeficiencyChanged();
+ break;
+ }
+ case SettingsDelegate::kForceDarkChange:
+ InvalidateColorScheme();
+ InvalidatePaint();
+ break;
+ }
+}
+
+void Page::InvalidateColorScheme() {
+ for (Frame* frame = MainFrame(); frame;
+ frame = frame->Tree().TraverseNext()) {
+ if (auto* local_frame = DynamicTo<LocalFrame>(frame))
+ local_frame->GetDocument()->ColorSchemeChanged();
+ }
+}
+
+void Page::InvalidatePaint() {
+ for (Frame* frame = MainFrame(); frame;
+ frame = frame->Tree().TraverseNext()) {
+ auto* local_frame = DynamicTo<LocalFrame>(frame);
+ if (!local_frame)
+ continue;
+ if (LayoutView* view = local_frame->ContentLayoutObject())
+ view->InvalidatePaintForViewAndCompositedLayers();
}
}
@@ -800,7 +834,20 @@ void Page::UpdateAcceleratedCompositingSettings() {
if (!local_frame)
continue;
LayoutView* layout_view = local_frame->ContentLayoutObject();
- layout_view->Compositor()->UpdateAcceleratedCompositingSettings();
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ layout_view->Compositor()->UpdateAcceleratedCompositingSettings();
+ } else {
+ // Mark all scrollable areas as needing a paint property update because
+ // the compositing reasons may have changed.
+ if (const auto* areas = local_frame->View()->ScrollableAreas()) {
+ for (const auto& scrollable_area : *areas) {
+ if (scrollable_area->ScrollsOverflow()) {
+ if (auto* layout_box = scrollable_area->GetLayoutBox())
+ layout_box->SetNeedsPaintPropertyUpdate();
+ }
+ }
+ }
+ }
}
}
@@ -815,12 +862,10 @@ void Page::DidCommitLoad(LocalFrame* frame) {
// would update the previous history item, Page::didCommitLoad is called
// after a new history item is created in FrameLoader.
// See crbug.com/642279
- GetVisualViewport().SetScrollOffset(ScrollOffset(), kProgrammaticScroll,
- kScrollBehaviorInstant,
+ GetVisualViewport().SetScrollOffset(ScrollOffset(),
+ mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kInstant,
ScrollableArea::ScrollCallback());
- hosts_using_features_.UpdateMeasurementsAndClear();
- // Update |has_related_pages_| as features are reset after navigation.
- UpdateHasRelatedPages();
}
GetLinkHighlight().ResetForPageNavigation();
}
@@ -840,7 +885,7 @@ void Page::AcceptLanguagesChanged() {
frames[i]->DomWindow()->AcceptLanguagesChanged();
}
-void Page::Trace(blink::Visitor* visitor) {
+void Page::Trace(Visitor* visitor) {
visitor->Trace(animator_);
visitor->Trace(autoscroll_controller_);
visitor->Trace(chrome_client_);
@@ -849,10 +894,12 @@ void Page::Trace(blink::Visitor* visitor) {
visitor->Trace(focus_controller_);
visitor->Trace(context_menu_controller_);
visitor->Trace(page_scale_constraints_set_);
+ visitor->Trace(page_visibility_observer_list_);
visitor->Trace(pointer_lock_controller_);
visitor->Trace(scrolling_coordinator_);
visitor->Trace(browser_controls_);
visitor->Trace(console_message_storage_);
+ visitor->Trace(inspector_issue_storage_);
visitor->Trace(global_root_scroller_controller_);
visitor->Trace(visual_viewport_);
visitor->Trace(overscroll_controller_);
@@ -866,7 +913,6 @@ void Page::Trace(blink::Visitor* visitor) {
visitor->Trace(next_related_page_);
visitor->Trace(prev_related_page_);
Supplementable<Page>::Trace(visitor);
- PageVisibilityNotifier::Trace(visitor);
}
void Page::AnimationHostInitialized(cc::AnimationHost& animation_host,
@@ -902,10 +948,6 @@ void Page::WillBeDestroyed() {
prev->next_related_page_ = next;
this->prev_related_page_ = nullptr;
this->next_related_page_ = nullptr;
- if (prev != this)
- prev->UpdateHasRelatedPages();
- if (next != this)
- next->UpdateHasRelatedPages();
}
if (scrolling_coordinator_)
@@ -919,7 +961,11 @@ void Page::WillBeDestroyed() {
if (agent_metrics_collector_)
agent_metrics_collector_->ReportMetrics();
- PageVisibilityNotifier::NotifyContextDestroyed();
+ page_visibility_observer_list_.ForEachObserver(
+ [](PageVisibilityObserver* observer) {
+ observer->ObserverListWillBeCleared();
+ });
+ page_visibility_observer_list_.Clear();
page_scheduler_.reset();
}
@@ -954,7 +1000,7 @@ bool Page::IsOrdinary() const {
void Page::ReportIntervention(const String& text) {
if (LocalFrame* local_frame = DeprecatedLocalMainFrame()) {
- ConsoleMessage* message = ConsoleMessage::Create(
+ auto* message = MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kWarning, text,
std::make_unique<SourceLocation>(String(), 0, 0, nullptr));
@@ -998,22 +1044,6 @@ bool Page::InsidePortal() const {
return inside_portal_;
}
-void Page::UpdateHasRelatedPages() {
- bool has_related_pages = next_related_page_ != this;
- if (!has_related_pages) {
- has_related_pages_.reset();
- } else {
- LocalFrame* local_main_frame = DynamicTo<LocalFrame>(main_frame_.Get());
- // We want to record this only for the pages which have local main frame,
- // which is fine as we are aggregating results across all processes.
- if (!local_main_frame || !local_main_frame->IsAttached())
- return;
- has_related_pages_ = local_main_frame->GetFrameScheduler()->RegisterFeature(
- SchedulingPolicy::Feature::kHasScriptableFramesInMultipleTabs,
- {SchedulingPolicy::RecordMetricsForBackForwardCache()});
- }
-}
-
void Page::SetMediaFeatureOverride(const AtomicString& media_feature,
const String& value) {
if (!media_feature_overrides_) {
@@ -1034,9 +1064,14 @@ void Page::ClearMediaFeatureOverrides() {
SettingsChanged(SettingsDelegate::kColorSchemeChange);
}
-Page::PageClients::PageClients() : chrome_client(nullptr) {}
+void Page::SetVisionDeficiency(VisionDeficiency new_vision_deficiency) {
+ if (new_vision_deficiency != vision_deficiency_) {
+ vision_deficiency_ = new_vision_deficiency;
+ SettingsChanged(SettingsDelegate::kVisionDeficiencyChange);
+ }
+}
-Page::PageClients::~PageClients() = default;
+Page::PageClients::PageClients() : chrome_client(nullptr) {}
template class CORE_TEMPLATE_EXPORT Supplement<Page>;
diff --git a/chromium/third_party/blink/renderer/core/page/page.h b/chromium/third_party/blink/renderer/core/page/page.h
index e968b10542e..1074204dbfb 100644
--- a/chromium/third_party/blink/renderer/core/page/page.h
+++ b/chromium/third_party/blink/renderer/core/page/page.h
@@ -31,15 +31,15 @@
#include "third_party/blink/public/platform/web_text_autosizer_page_info.h"
#include "third_party/blink/public/web/web_window_features.h"
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/css/vision_deficiency.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
-#include "third_party/blink/renderer/core/frame/hosts_using_features.h"
#include "third_party/blink/renderer/core/frame/settings_delegate.h"
#include "third_party/blink/renderer/core/page/page_animator.h"
-#include "third_party/blink/renderer/core/page/page_visibility_notifier.h"
#include "third_party/blink/renderer/core/page/page_visibility_observer.h"
#include "third_party/blink/renderer/core/page/viewport_description.h"
#include "third_party/blink/renderer/platform/heap/handle.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/scheduler/public/page_lifecycle_state.h"
#include "third_party/blink/renderer/platform/scheduler/public/page_scheduler.h"
#include "third_party/blink/renderer/platform/supplementable.h"
@@ -57,6 +57,7 @@ class AutoscrollController;
class BrowserControls;
class ChromeClient;
class ConsoleMessageStorage;
+class InspectorIssueStorage;
class ContextMenuController;
class Document;
class DragCaret;
@@ -89,7 +90,6 @@ float DeviceScaleFactorDeprecated(LocalFrame*);
class CORE_EXPORT Page final : public GarbageCollected<Page>,
public Supplementable<Page>,
- public PageVisibilityNotifier,
public SettingsDelegate,
public PageScheduler::Delegate {
USING_GARBAGE_COLLECTED_MIXIN(Page);
@@ -103,9 +103,8 @@ class CORE_EXPORT Page final : public GarbageCollected<Page>,
public:
PageClients();
- ~PageClients();
- Member<ChromeClient> chrome_client;
+ ChromeClient* chrome_client;
DISALLOW_COPY_AND_ASSIGN(PageClients);
};
@@ -199,7 +198,6 @@ class CORE_EXPORT Page final : public GarbageCollected<Page>,
Settings& GetSettings() const { return *settings_; }
Deprecation& GetDeprecation() { return deprecation_; }
- HostsUsingFeatures& GetHostsUsingFeatures() { return hosts_using_features_; }
void SetWindowFeatures(const WebWindowFeatures& features) {
window_features_ = features;
@@ -217,6 +215,9 @@ class CORE_EXPORT Page final : public GarbageCollected<Page>,
ConsoleMessageStorage& GetConsoleMessageStorage();
const ConsoleMessageStorage& GetConsoleMessageStorage() const;
+ InspectorIssueStorage& GetInspectorIssueStorage();
+ const InspectorIssueStorage& GetInspectorIssueStorage() const;
+
TopDocumentRootScrollerController& GlobalRootScrollerController() const;
VisualViewport& GetVisualViewport();
@@ -298,7 +299,7 @@ class CORE_EXPORT Page final : public GarbageCollected<Page>,
void AcceptLanguagesChanged();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void AnimationHostInitialized(cc::AnimationHost&, LocalFrameView*);
void WillCloseAnimationHost(LocalFrameView*);
@@ -326,7 +327,7 @@ class CORE_EXPORT Page final : public GarbageCollected<Page>,
void SetInsidePortal(bool inside_portal);
bool InsidePortal() const;
- void SetTextAutosizePageInfo(const WebTextAutosizerPageInfo& page_info) {
+ void SetTextAutosizerPageInfo(const WebTextAutosizerPageInfo& page_info) {
web_text_autosizer_page_info_ = page_info;
}
const WebTextAutosizerPageInfo& TextAutosizerPageInfo() const {
@@ -340,10 +341,17 @@ class CORE_EXPORT Page final : public GarbageCollected<Page>,
}
void ClearMediaFeatureOverrides();
+ void SetVisionDeficiency(VisionDeficiency new_vision_deficiency);
+ VisionDeficiency GetVisionDeficiency() const { return vision_deficiency_; }
+
WebScopedVirtualTimePauser& HistoryNavigationVirtualTimePauser() {
return history_navigation_virtual_time_pauser_;
}
+ HeapObserverList<PageVisibilityObserver>& PageVisibilityObserverList() {
+ return page_visibility_observer_list_;
+ }
+
static void PrepareForLeakDetection();
private:
@@ -359,8 +367,8 @@ class CORE_EXPORT Page final : public GarbageCollected<Page>,
void SetPageScheduler(std::unique_ptr<PageScheduler>);
- void UpdateHasRelatedPages();
-
+ void InvalidateColorScheme();
+ void InvalidatePaint();
// Typically, the main frame and Page should both be owned by the embedder,
// which must call Page::willBeDestroyed() prior to destroying Page. This
// call detaches the main frame and clears this pointer, thus ensuring that
@@ -383,10 +391,12 @@ class CORE_EXPORT Page final : public GarbageCollected<Page>,
const Member<FocusController> focus_controller_;
const Member<ContextMenuController> context_menu_controller_;
const Member<PageScaleConstraintsSet> page_scale_constraints_set_;
+ HeapObserverList<PageVisibilityObserver> page_visibility_observer_list_;
const Member<PointerLockController> pointer_lock_controller_;
Member<ScrollingCoordinator> scrolling_coordinator_;
const Member<BrowserControls> browser_controls_;
const Member<ConsoleMessageStorage> console_message_storage_;
+ const Member<InspectorIssueStorage> inspector_issue_storage_;
const Member<TopDocumentRootScrollerController>
global_root_scroller_controller_;
const Member<VisualViewport> visual_viewport_;
@@ -403,7 +413,6 @@ class CORE_EXPORT Page final : public GarbageCollected<Page>,
Member<AgentMetricsCollector> agent_metrics_collector_;
Deprecation deprecation_;
- HostsUsingFeatures hosts_using_features_;
WebWindowFeatures window_features_;
bool opened_by_dom_;
@@ -446,9 +455,12 @@ class CORE_EXPORT Page final : public GarbageCollected<Page>,
std::unique_ptr<PageScheduler> page_scheduler_;
- // Overrides for various media features set from the devtools.
+ // Overrides for various media features, set from DevTools.
std::unique_ptr<MediaFeatureOverrides> media_feature_overrides_;
+ // Emulated vision deficiency, set from DevTools.
+ VisionDeficiency vision_deficiency_ = VisionDeficiency::kNoVisionDeficiency;
+
int32_t autoplay_flags_;
// Accessed by frames to determine whether to expose the PortalHost object.
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 4a16ce2d429..ec13847be9d 100644
--- a/chromium/third_party/blink/renderer/core/page/page_animator.cc
+++ b/chromium/third_party/blink/renderer/core/page/page_animator.cc
@@ -18,12 +18,28 @@
namespace blink {
+namespace {
+
+typedef HeapVector<Member<Document>, 32> DocumentsVector;
+
+// We walk through all the frames in DOM tree order and get all the documents
+DocumentsVector GetAllDocuments(Frame* main_frame) {
+ DocumentsVector documents;
+ for (Frame* frame = main_frame; frame; frame = frame->Tree().TraverseNext()) {
+ if (auto* local_frame = DynamicTo<LocalFrame>(frame))
+ documents.push_back(local_frame->GetDocument());
+ }
+ return documents;
+}
+
+} // namespace
+
PageAnimator::PageAnimator(Page& page)
: page_(page),
servicing_animations_(false),
updating_layout_and_style_for_painting_(false) {}
-void PageAnimator::Trace(blink::Visitor* visitor) {
+void PageAnimator::Trace(Visitor* visitor) {
visitor->Trace(page_);
}
@@ -36,17 +52,12 @@ void PageAnimator::ServiceScriptedAnimations(
Clock().SetAllowedToDynamicallyUpdateTime(false);
Clock().UpdateTime(monotonic_animation_start_time);
- HeapVector<Member<Document>, 32> documents;
- for (Frame* frame = page_->MainFrame(); frame;
- frame = frame->Tree().TraverseNext()) {
- if (auto* local_frame = DynamicTo<LocalFrame>(frame))
- documents.push_back(local_frame->GetDocument());
- }
+ DocumentsVector documents = GetAllDocuments(page_->MainFrame());
for (auto& document : documents) {
ScopedFrameBlamer frame_blamer(document->GetFrame());
TRACE_EVENT0("blink,rail", "PageAnimator::serviceScriptedAnimations");
- DocumentAnimations::UpdateAnimationTimingForAnimationFrame(*document);
+ document->GetDocumentAnimations().UpdateAnimationTimingForAnimationFrame();
if (document->View()) {
if (document->View()->ShouldThrottleRendering()) {
document->SetCurrentFrameIsThrottled(true);
@@ -89,7 +100,7 @@ void PageAnimator::ServiceScriptedAnimations(
}
void PageAnimator::PostAnimate() {
- HeapVector<Member<Document>, 32> documents;
+ DocumentsVector documents;
for (Frame* frame = page_->MainFrame(); frame;
frame = frame->Tree().TraverseNext()) {
if (frame->IsLocalFrame())
@@ -131,27 +142,40 @@ void PageAnimator::ScheduleVisualUpdate(LocalFrame* frame) {
page_->GetChromeClient().ScheduleAnimation(frame->View());
}
-void PageAnimator::UpdateAllLifecyclePhases(
- LocalFrame& root_frame,
- DocumentLifecycle::LifecycleUpdateReason reason) {
+void PageAnimator::UpdateAllLifecyclePhases(LocalFrame& root_frame,
+ DocumentUpdateReason reason) {
LocalFrameView* view = root_frame.View();
base::AutoReset<bool> servicing(&updating_layout_and_style_for_painting_,
true);
view->UpdateAllLifecyclePhases(reason);
}
-void PageAnimator::UpdateAllLifecyclePhasesExceptPaint(LocalFrame& root_frame) {
+void PageAnimator::UpdateAllLifecyclePhasesExceptPaint(
+ LocalFrame& root_frame,
+ DocumentUpdateReason reason) {
LocalFrameView* view = root_frame.View();
base::AutoReset<bool> servicing(&updating_layout_and_style_for_painting_,
true);
- view->UpdateAllLifecyclePhasesExceptPaint();
+ view->UpdateAllLifecyclePhasesExceptPaint(reason);
}
-void PageAnimator::UpdateLifecycleToLayoutClean(LocalFrame& root_frame) {
+void PageAnimator::UpdateLifecycleToLayoutClean(LocalFrame& root_frame,
+ DocumentUpdateReason reason) {
LocalFrameView* view = root_frame.View();
base::AutoReset<bool> servicing(&updating_layout_and_style_for_painting_,
true);
- view->UpdateLifecycleToLayoutClean();
+ view->UpdateLifecycleToLayoutClean(reason);
+}
+
+HeapVector<Member<Animation>> PageAnimator::GetAnimations(
+ const TreeScope& tree_scope) {
+ HeapVector<Member<Animation>> animations;
+ DocumentsVector documents = GetAllDocuments(page_->MainFrame());
+ for (auto& document : documents) {
+ document->GetDocumentAnimations().GetAnimationsTargetingTreeScope(
+ animations, tree_scope);
+ }
+ return animations;
}
} // namespace blink
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 84701414048..181a6e5f37a 100644
--- a/chromium/third_party/blink/renderer/core/page/page_animator.h
+++ b/chromium/third_party/blink/renderer/core/page/page_animator.h
@@ -5,21 +5,25 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_PAGE_ANIMATOR_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_PAGE_ANIMATOR_H_
+#include "third_party/blink/public/common/metrics/document_update_reason.h"
+#include "third_party/blink/renderer/core/animation/animation.h"
#include "third_party/blink/renderer/core/animation/animation_clock.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/document_lifecycle.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
class LocalFrame;
class Page;
+class TreeScope;
class CORE_EXPORT PageAnimator final : public GarbageCollected<PageAnimator> {
public:
explicit PageAnimator(Page&);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
void ScheduleVisualUpdate(LocalFrame*);
void ServiceScriptedAnimations(
base::TimeTicks monotonic_animation_start_time);
@@ -34,12 +38,14 @@ class CORE_EXPORT PageAnimator final : public GarbageCollected<PageAnimator> {
void SetSuppressFrameRequestsWorkaroundFor704763Only(bool);
// See documents of methods with the same names in LocalFrameView class.
- void UpdateAllLifecyclePhases(
- LocalFrame& root_frame,
- DocumentLifecycle::LifecycleUpdateReason reason);
- void UpdateAllLifecyclePhasesExceptPaint(LocalFrame& root_frame);
- void UpdateLifecycleToLayoutClean(LocalFrame& root_frame);
+ void UpdateAllLifecyclePhases(LocalFrame& root_frame,
+ DocumentUpdateReason reason);
+ void UpdateAllLifecyclePhasesExceptPaint(LocalFrame& root_frame,
+ DocumentUpdateReason reason);
+ void UpdateLifecycleToLayoutClean(LocalFrame& root_frame,
+ DocumentUpdateReason reason);
AnimationClock& Clock() { return animation_clock_; }
+ HeapVector<Member<Animation>> GetAnimations(const TreeScope&);
private:
Member<Page> page_;
diff --git a/chromium/third_party/blink/renderer/core/page/page_popup_client.cc b/chromium/third_party/blink/renderer/core/page/page_popup_client.cc
index b600100e0cc..da21fc48bbc 100644
--- a/chromium/third_party/blink/renderer/core/page/page_popup_client.cc
+++ b/chromium/third_party/blink/renderer/core/page/page_popup_client.cc
@@ -30,9 +30,11 @@
#include "third_party/blink/renderer/core/page/page_popup_client.h"
+#include "third_party/blink/renderer/core/css/css_font_selector.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.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_popup_controller.h"
#include "third_party/blink/renderer/platform/wtf/text/character_names.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
@@ -155,4 +157,14 @@ void PagePopupClient::AddProperty(const char* name,
addLiteral("},\n", data);
}
+CSSFontSelector* PagePopupClient::CreateCSSFontSelector(
+ Document& popup_document) {
+ return MakeGarbageCollected<CSSFontSelector>(&popup_document);
+}
+
+PagePopupController* PagePopupClient::CreatePagePopupController(
+ PagePopup& popup) {
+ return MakeGarbageCollected<PagePopupController>(popup, this);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/page_popup_client.h b/chromium/third_party/blink/renderer/core/page/page_popup_client.h
index fe542ea5640..7f36805face 100644
--- a/chromium/third_party/blink/renderer/core/page/page_popup_client.h
+++ b/chromium/third_party/blink/renderer/core/page/page_popup_client.h
@@ -39,10 +39,13 @@
namespace blink {
+class CSSFontSelector;
class ChromeClient;
class Document;
class Element;
class Locale;
+class PagePopup;
+class PagePopupController;
class CORE_EXPORT PagePopupClient {
public:
@@ -53,13 +56,14 @@ class CORE_EXPORT PagePopupClient {
// - window.setValueAndClosePopup(number, string).
virtual void WriteDocument(SharedBuffer*) = 0;
- // This is called after the document is ready to do additionary setup.
- virtual void SelectFontsFromOwnerDocument(Document&) = 0;
-
virtual Element& OwnerElement() = 0;
virtual ChromeClient& GetChromeClient() = 0;
+ virtual CSSFontSelector* CreateCSSFontSelector(Document& popup_document);
+
+ virtual PagePopupController* CreatePagePopupController(PagePopup&);
+
// Returns effective zoom factor of ownerElement, or the page zoom factor if
// the effective zoom factor is not available.
virtual float ZoomFactor();
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 8a56d320cea..82bc0cbb1e8 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
@@ -34,6 +34,7 @@
#include "third_party/blink/public/strings/grit/blink_strings.h"
#include "third_party/blink/renderer/core/page/page_popup.h"
#include "third_party/blink/renderer/core/page/page_popup_client.h"
+#include "third_party/blink/renderer/core/page/page_popup_supplement.h"
#include "third_party/blink/renderer/platform/text/platform_locale.h"
namespace blink {
@@ -60,13 +61,6 @@ void PagePopupController::closePopup() {
popup_client_->CancelPopup();
}
-void PagePopupController::selectFontsFromOwnerDocument(
- Document* target_document) {
- DCHECK(target_document);
- if (popup_client_)
- popup_client_->SelectFontsFromOwnerDocument(*target_document);
-}
-
String PagePopupController::localizeNumberString(const String& number_string) {
if (popup_client_)
return popup_client_->GetLocale().ConvertToLocalizedNumber(number_string);
@@ -112,4 +106,17 @@ void PagePopupController::setWindowRect(int x, int y, int width, int height) {
popup_.SetWindowRect(IntRect(x, y, width, height));
}
+// static
+CSSFontSelector* PagePopupController::CreateCSSFontSelector(
+ Document& popup_document) {
+ LocalFrame* frame = popup_document.GetFrame();
+ DCHECK(frame);
+ DCHECK(frame->PagePopupOwner());
+
+ auto* controller = PagePopupSupplement::From(*frame).GetPagePopupController();
+
+ DCHECK(controller->popup_client_);
+ return controller->popup_client_->CreateCSSFontSelector(popup_document);
+}
+
} // namespace blink
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 005541c6fc8..a08566a2dc4 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
@@ -37,11 +37,12 @@
namespace blink {
+class CSSFontSelector;
class Document;
class PagePopup;
class PagePopupClient;
-class PagePopupController final : public ScriptWrappable {
+class PagePopupController : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
@@ -50,7 +51,6 @@ class PagePopupController final : public ScriptWrappable {
void setValueAndClosePopup(int num_value, const String& string_value);
void setValue(const String&);
void closePopup();
- void selectFontsFromOwnerDocument(Document* target_document);
String localizeNumberString(const String&);
String formatMonth(int year, int zero_base_month);
String formatShortMonth(int year, int zero_base_month);
@@ -60,8 +60,12 @@ class PagePopupController final : public ScriptWrappable {
void ClearPagePopupClient();
void setWindowRect(int x, int y, int width, int height);
+ static CSSFontSelector* CreateCSSFontSelector(Document& popup_document);
+
private:
PagePopup& popup_;
+
+ protected:
PagePopupClient* popup_client_;
};
diff --git a/chromium/third_party/blink/renderer/core/page/page_popup_controller.idl b/chromium/third_party/blink/renderer/core/page/page_popup_controller.idl
index 26668d71fc8..5d7bc223559 100644
--- a/chromium/third_party/blink/renderer/core/page/page_popup_controller.idl
+++ b/chromium/third_party/blink/renderer/core/page/page_popup_controller.idl
@@ -38,7 +38,6 @@
void setValueAndClosePopup(long numberValue, DOMString stringValue);
void setValue(DOMString value);
void closePopup();
- void selectFontsFromOwnerDocument(Document targetDocument);
DOMString localizeNumberString(DOMString numberString);
DOMString formatMonth(long year, long zeroBaseMonth);
DOMString formatShortMonth(long year, long zeroBaseMonth);
diff --git a/chromium/third_party/blink/renderer/core/page/page_popup_supplement.cc b/chromium/third_party/blink/renderer/core/page/page_popup_supplement.cc
index 44d132e31dd..e0f3a51af5a 100644
--- a/chromium/third_party/blink/renderer/core/page/page_popup_supplement.cc
+++ b/chromium/third_party/blink/renderer/core/page/page_popup_supplement.cc
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/core/page/page_popup_supplement.h"
+#include "third_party/blink/renderer/core/page/page_popup_client.h"
#include "third_party/blink/renderer/core/page/page_popup_controller.h"
namespace blink {
@@ -38,8 +39,7 @@ PagePopupSupplement::PagePopupSupplement(LocalFrame& frame,
PagePopup& popup,
PagePopupClient* popup_client)
: Supplement<LocalFrame>(frame),
- controller_(
- MakeGarbageCollected<PagePopupController>(popup, popup_client)) {
+ controller_(popup_client->CreatePagePopupController(popup)) {
DCHECK(popup_client);
}
@@ -73,7 +73,7 @@ void PagePopupSupplement::Uninstall(LocalFrame& frame) {
frame.RemoveSupplement<PagePopupSupplement>();
}
-void PagePopupSupplement::Trace(blink::Visitor* visitor) {
+void PagePopupSupplement::Trace(Visitor* visitor) {
visitor->Trace(controller_);
Supplement<LocalFrame>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/page/page_popup_supplement.h b/chromium/third_party/blink/renderer/core/page/page_popup_supplement.h
index c1511cbc6c7..4dafb45f1c6 100644
--- a/chromium/third_party/blink/renderer/core/page/page_popup_supplement.h
+++ b/chromium/third_party/blink/renderer/core/page/page_popup_supplement.h
@@ -58,7 +58,7 @@ class CORE_EXPORT PagePopupSupplement final
PagePopupSupplement(LocalFrame&, PagePopup&, PagePopupClient*);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void Dispose();
diff --git a/chromium/third_party/blink/renderer/core/page/page_visibility_notifier.cc b/chromium/third_party/blink/renderer/core/page/page_visibility_notifier.cc
deleted file mode 100644
index b497d34753a..00000000000
--- a/chromium/third_party/blink/renderer/core/page/page_visibility_notifier.cc
+++ /dev/null
@@ -1,39 +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:
- * 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/page/page_visibility_notifier.h"
-
-#include "base/auto_reset.h"
-#include "third_party/blink/renderer/core/page/page_visibility_observer.h"
-
-namespace blink {
-
-void PageVisibilityNotifier::NotifyPageVisibilityChanged() {
- ForEachObserver([](PageVisibilityObserver* observer) {
- observer->PageVisibilityChanged();
- });
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/page_visibility_notifier.h b/chromium/third_party/blink/renderer/core/page/page_visibility_notifier.h
deleted file mode 100644
index 97e6dbaea76..00000000000
--- a/chromium/third_party/blink/renderer/core/page/page_visibility_notifier.h
+++ /dev/null
@@ -1,45 +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:
- * 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_PAGE_PAGE_VISIBILITY_NOTIFIER_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_PAGE_VISIBILITY_NOTIFIER_H_
-
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/platform/lifecycle_notifier.h"
-
-namespace blink {
-
-class Page;
-class PageVisibilityObserver;
-
-class CORE_EXPORT PageVisibilityNotifier
- : public LifecycleNotifier<Page, PageVisibilityObserver> {
- public:
- void NotifyPageVisibilityChanged();
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_PAGE_VISIBILITY_NOTIFIER_H_
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
new file mode 100644
index 00000000000..2cab0c51ea9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/page/page_visibility_observer.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/page/page_visibility_observer.h"
+
+#include "third_party/blink/renderer/core/page/page.h"
+
+namespace blink {
+
+PageVisibilityObserver::PageVisibilityObserver(Page* page) {
+ SetPage(page);
+}
+
+void PageVisibilityObserver::ObserverListWillBeCleared() {
+ page_ = nullptr;
+}
+
+void PageVisibilityObserver::SetPage(Page* page) {
+ if (page == page_)
+ return;
+
+ if (page_)
+ page_->PageVisibilityObserverList().RemoveObserver(this);
+
+ page_ = page;
+
+ if (page_)
+ page_->PageVisibilityObserverList().AddObserver(this);
+}
+
+void PageVisibilityObserver::Trace(Visitor* visitor) {
+ visitor->Trace(page_);
+}
+
+} // namespace blink
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 2c57411b245..29e0b32773e 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
@@ -28,20 +28,29 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_PAGE_VISIBILITY_OBSERVER_H_
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/page/page.h"
-#include "third_party/blink/renderer/platform/lifecycle_observer.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
-class CORE_EXPORT PageVisibilityObserver
- : public LifecycleObserver<Page, PageVisibilityObserver> {
+class Page;
+
+class CORE_EXPORT PageVisibilityObserver : public GarbageCollectedMixin {
public:
- virtual void PageVisibilityChanged() {}
+ virtual void PageVisibilityChanged() = 0;
+
+ // Call before clearing an observer list.
+ void ObserverListWillBeCleared();
- Page* GetPage() const { return LifecycleContext(); }
+ Page* GetPage() const { return page_; }
+ void SetPage(Page*);
+
+ void Trace(Visitor* visitor) override;
protected:
- explicit PageVisibilityObserver(Page* page) : LifecycleObserver(page) {}
+ explicit PageVisibilityObserver(Page*);
+
+ private:
+ WeakMember<Page> page_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/page_widget_delegate.cc b/chromium/third_party/blink/renderer/core/page/page_widget_delegate.cc
index 6a25df5fb9b..4c9a4a84ee6 100644
--- a/chromium/third_party/blink/renderer/core/page/page_widget_delegate.cc
+++ b/chromium/third_party/blink/renderer/core/page/page_widget_delegate.cc
@@ -30,7 +30,7 @@
#include "third_party/blink/renderer/core/page/page_widget_delegate.h"
-#include "third_party/blink/public/platform/web_input_event.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
#include "third_party/blink/renderer/core/events/web_input_event_conversion.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -60,18 +60,16 @@ void PageWidgetDelegate::PostAnimate(Page& page) {
page.Animator().PostAnimate();
}
-void PageWidgetDelegate::UpdateLifecycle(
- Page& page,
- LocalFrame& root,
- WebWidget::LifecycleUpdate requested_update,
- WebWidget::LifecycleUpdateReason reason) {
- if (requested_update == WebWidget::LifecycleUpdate::kLayout) {
- page.Animator().UpdateLifecycleToLayoutClean(root);
- } else if (requested_update == WebWidget::LifecycleUpdate::kPrePaint) {
- page.Animator().UpdateAllLifecyclePhasesExceptPaint(root);
+void PageWidgetDelegate::UpdateLifecycle(Page& page,
+ LocalFrame& root,
+ WebLifecycleUpdate requested_update,
+ DocumentUpdateReason reason) {
+ if (requested_update == WebLifecycleUpdate::kLayout) {
+ page.Animator().UpdateLifecycleToLayoutClean(root, reason);
+ } else if (requested_update == WebLifecycleUpdate::kPrePaint) {
+ page.Animator().UpdateAllLifecyclePhasesExceptPaint(root, reason);
} else {
- page.Animator().UpdateAllLifecyclePhases(
- root, static_cast<DocumentLifecycle::LifecycleUpdateReason>(reason));
+ page.Animator().UpdateAllLifecyclePhases(root, reason);
}
}
diff --git a/chromium/third_party/blink/renderer/core/page/page_widget_delegate.h b/chromium/third_party/blink/renderer/core/page/page_widget_delegate.h
index 996e0dcd785..bfe965ffaa8 100644
--- a/chromium/third_party/blink/renderer/core/page/page_widget_delegate.h
+++ b/chromium/third_party/blink/renderer/core/page/page_widget_delegate.h
@@ -83,8 +83,8 @@ class CORE_EXPORT PageWidgetDelegate {
// See comment of WebWidget::UpdateLifecycle.
static void UpdateLifecycle(Page&,
LocalFrame& root,
- WebWidget::LifecycleUpdate requested_update,
- WebWidget::LifecycleUpdateReason reason);
+ WebLifecycleUpdate requested_update,
+ DocumentUpdateReason reason);
// See comment of WebWidget::DidBeginFrame.
static void DidBeginFrame(LocalFrame& root);
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 7ea0e09e47a..9b6a945105c 100644
--- a/chromium/third_party/blink/renderer/core/page/plugin_data.cc
+++ b/chromium/third_party/blink/renderer/core/page/plugin_data.cc
@@ -24,16 +24,16 @@
#include "third_party/blink/renderer/core/page/plugin_data.h"
#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/plugins/plugin_registry.mojom-blink.h"
#include "third_party/blink/public/platform/file_path_conversion.h"
-#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
namespace blink {
-void MimeClassInfo::Trace(blink::Visitor* visitor) {
+void MimeClassInfo::Trace(Visitor* visitor) {
visitor->Trace(plugin_);
}
@@ -42,7 +42,7 @@ MimeClassInfo::MimeClassInfo(const String& type,
PluginInfo& plugin)
: type_(type), description_(description), plugin_(&plugin) {}
-void PluginInfo::Trace(blink::Visitor* visitor) {
+void PluginInfo::Trace(Visitor* visitor) {
visitor->Trace(mimes_);
}
@@ -80,7 +80,7 @@ wtf_size_t PluginInfo::GetMimeClassInfoSize() const {
return mimes_.size();
}
-void PluginData::Trace(blink::Visitor* visitor) {
+void PluginData::Trace(Visitor* visitor) {
visitor->Trace(plugins_);
visitor->Trace(mimes_);
}
@@ -88,7 +88,7 @@ void PluginData::Trace(blink::Visitor* visitor) {
// static
void PluginData::RefreshBrowserSidePluginCache() {
mojo::Remote<mojom::blink::PluginRegistry> registry;
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
registry.BindNewPipeAndPassReceiver());
Vector<mojom::blink::PluginInfoPtr> plugins;
registry->GetPlugins(true, SecurityOrigin::CreateUniqueOpaque(), &plugins);
@@ -99,7 +99,7 @@ void PluginData::UpdatePluginList(const SecurityOrigin* main_frame_origin) {
main_frame_origin_ = main_frame_origin;
mojo::Remote<mojom::blink::PluginRegistry> registry;
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
registry.BindNewPipeAndPassReceiver());
Vector<mojom::blink::PluginInfoPtr> plugins;
registry->GetPlugins(false, main_frame_origin_, &plugins);
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 efd11fb5b5e..d0260f9f6b1 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(blink::Visitor*);
+ void Trace(Visitor*);
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(blink::Visitor*);
+ void Trace(Visitor*);
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(blink::Visitor*);
+ void Trace(Visitor*);
PluginData() = default;
diff --git a/chromium/third_party/blink/renderer/core/page/plugin_data_test.cc b/chromium/third_party/blink/renderer/core/page/plugin_data_test.cc
index e522955ef65..9114eac609a 100644
--- a/chromium/third_party/blink/renderer/core/page/plugin_data_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/plugin_data_test.cc
@@ -37,6 +37,7 @@ class MockPluginRegistry : public mojom::blink::PluginRegistry {
TEST(PluginDataTest, NonStandardUrlSchemeRequestsPluginsWithUniqueOrigin) {
ScopedTestingPlatformSupport<TestingPlatformSupport> support;
// Create a scheme that's local but nonstandard, as in bug 862282.
+ url::ScopedSchemeRegistryForTests scoped_registry;
url::AddLocalScheme("nonstandard-862282");
SchemeRegistry::RegisterURLSchemeAsLocal("nonstandard-862282");
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 e3f22d33f0c..8b72cb38083 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
@@ -25,28 +25,38 @@
#include "third_party/blink/renderer/core/page/pointer_lock_controller.h"
-#include "third_party/blink/public/platform/web_mouse_event.h"
+#include "third_party/blink/public/common/input/web_mouse_event.h"
+#include "third_party/blink/public/mojom/input/pointer_lock_result.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_pointer_lock_options.h"
+#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
-#include "third_party/blink/renderer/core/dom/pointer_lock_options.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.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/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
PointerLockController::PointerLockController(Page* page)
: page_(page), lock_pending_(false) {}
-void PointerLockController::RequestPointerLock(
+ScriptPromise PointerLockController::RequestPointerLock(
+ ScriptPromiseResolver* resolver,
Element* target,
+ ExceptionState& exception_state,
const PointerLockOptions* options) {
+ ScriptPromise promise = resolver->Promise();
+
if (!target || !target->isConnected() ||
document_of_removed_element_while_waiting_for_unlock_) {
EnqueueEvent(event_type_names::kPointerlockerror, target);
- return;
+ exception_state.ThrowDOMException(DOMExceptionCode::kWrongDocumentError,
+ "Target Element removed from DOM");
+ return promise;
}
target->GetDocument().CountUseOnlyInCrossOriginIframe(
@@ -60,32 +70,141 @@ void PointerLockController::RequestPointerLock(
WebFeature::kPointerLockUnadjustedMovement);
}
- if (target->GetDocument().IsSandboxed(WebSandboxFlags::kPointerLock)) {
+ if (target->GetDocument().IsSandboxed(
+ 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(ConsoleMessage::Create(
- 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."));
+ 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."));
EnqueueEvent(event_type_names::kPointerlockerror, target);
- return;
+ exception_state.ThrowSecurityError(
+ "Blocked pointer lock on an element because the element's frame is "
+ "sandboxed and the 'allow-pointer-lock' permission is not set.",
+ "");
+ return promise;
}
+ bool unadjusted_movement_requested =
+ options ? options->unadjustedMovement() : false;
if (element_) {
if (element_->GetDocument() != target->GetDocument()) {
EnqueueEvent(event_type_names::kPointerlockerror, target);
- return;
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kWrongDocumentError,
+ "The new element is not in the same shadow-root document as the "
+ "element that currently holds the lock.");
+ return promise;
}
+
+ // Attempt to change options if necessary.
+ if (unadjusted_movement_requested != current_unadjusted_movement_setting_) {
+ if (!page_->GetChromeClient().RequestPointerLockChange(
+ target->GetDocument().GetFrame(),
+ WTF::Bind(&PointerLockController::ChangeLockRequestCallback,
+ WrapWeakPersistent(this), WrapWeakPersistent(target),
+ WrapPersistent(resolver)),
+ unadjusted_movement_requested)) {
+ EnqueueEvent(event_type_names::kPointerlockerror, target);
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInUseAttributeError, "Pointer lock pending.");
+ }
+ return promise;
+ }
+
EnqueueEvent(event_type_names::kPointerlockchange, target);
element_ = target;
+ resolver->Resolve();
+
+ // Subsequent steps are handled in the browser process.
} else if (page_->GetChromeClient().RequestPointerLock(
target->GetDocument().GetFrame(),
- (options ? options->unadjustedMovement() : false))) {
+ WTF::Bind(&PointerLockController::LockRequestCallback,
+ WrapWeakPersistent(this), WrapPersistent(resolver)),
+ unadjusted_movement_requested)) {
lock_pending_ = true;
element_ = target;
+ current_unadjusted_movement_setting_ =
+ options ? options->unadjustedMovement() : false;
} else {
EnqueueEvent(event_type_names::kPointerlockerror, target);
+ exception_state.ThrowDOMException(DOMExceptionCode::kInUseAttributeError,
+ "Pointer lock pending.");
+ }
+
+ return promise;
+}
+
+void PointerLockController::ChangeLockRequestCallback(
+ Element* target,
+ ScriptPromiseResolver* resolver,
+ mojom::blink::PointerLockResult result) {
+ if (result == mojom::blink::PointerLockResult::kSuccess)
+ element_ = target;
+
+ LockRequestCallback(resolver, result);
+}
+
+void PointerLockController::LockRequestCallback(
+ ScriptPromiseResolver* resolver,
+ mojom::blink::PointerLockResult result) {
+ if (result == mojom::blink::PointerLockResult::kSuccess) {
+ resolver->Resolve();
+ return;
+ }
+ DOMException* exception = ConvertResultToException(result);
+ RejectIfPromiseEnabled(resolver, exception);
+}
+
+DOMException* PointerLockController::ConvertResultToException(
+ mojom::blink::PointerLockResult result) {
+ switch (result) {
+ case mojom::blink::PointerLockResult::kUnsupportedOptions:
+ return MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kNotSupportedError,
+ "The options asked for in this request are not supported on this "
+ "platform.");
+ case mojom::blink::PointerLockResult::kRequiresUserGesture:
+ return MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kNotAllowedError,
+ "A user gesture is required to request Pointer Lock.");
+ case mojom::blink::PointerLockResult::kAlreadyLocked:
+ return MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kInUseAttributeError, "Pointer is already locked.");
+ case mojom::blink::PointerLockResult::kWrongDocument:
+ return MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kWrongDocumentError,
+ "The root document of this element is not valid for pointer lock.");
+ case mojom::blink::PointerLockResult::kPermissionDenied:
+ return MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kSecurityError,
+ "The root document of this element is not valid for pointer lock.");
+ case mojom::blink::PointerLockResult::kElementDestroyed:
+ return MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kWrongDocumentError,
+ "The element has been destroyed while making this request.");
+ case mojom::blink::PointerLockResult::kUserRejected:
+ return MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kSecurityError,
+ "The user has exited the lock before this request was completed.");
+ case mojom::blink::PointerLockResult::kSuccess:
+ case mojom::blink::PointerLockResult::kUnknownError:
+ return MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kUnknownError,
+ "If you see this error we have a bug. Please report this bug to "
+ "chromium.");
+ }
+}
+
+void PointerLockController::RejectIfPromiseEnabled(
+ ScriptPromiseResolver* resolver,
+ DOMException* exception) {
+ if (RuntimeEnabledFeatures::PointerLockOptionsEnabled(
+ resolver->GetExecutionContext())) {
+ resolver->Reject(exception);
}
}
@@ -211,7 +330,7 @@ void PointerLockController::EnqueueEvent(const AtomicString& type,
}
}
-void PointerLockController::Trace(blink::Visitor* visitor) {
+void PointerLockController::Trace(Visitor* visitor) {
visitor->Trace(page_);
visitor->Trace(element_);
visitor->Trace(document_of_removed_element_while_waiting_for_unlock_);
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 293d476a0ad..fd8aeaafcfd 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
@@ -28,7 +28,11 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
+#include "third_party/blink/public/mojom/input/pointer_lock_result.mojom-blink-forward.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/core_export.h"
+#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/geometry/float_point.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
@@ -48,8 +52,10 @@ class CORE_EXPORT PointerLockController final
public:
explicit PointerLockController(Page*);
- void RequestPointerLock(Element* target,
- const PointerLockOptions* options = nullptr);
+ ScriptPromise RequestPointerLock(ScriptPromiseResolver* resolver,
+ Element* target,
+ ExceptionState& exception_state,
+ const PointerLockOptions* options = nullptr);
void RequestPointerUnlock();
void ElementRemoved(Element*);
void DocumentDetached(Document*);
@@ -68,12 +74,21 @@ class CORE_EXPORT PointerLockController final
// changed if pointer is not locked.
void GetPointerLockPosition(FloatPoint* lock_position,
FloatPoint* lock_screen_position);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
void ClearElement();
void EnqueueEvent(const AtomicString& type, Element*);
void EnqueueEvent(const AtomicString& type, Document*);
+ void ChangeLockRequestCallback(Element* target,
+ ScriptPromiseResolver* resolver,
+ mojom::blink::PointerLockResult result);
+ void LockRequestCallback(ScriptPromiseResolver* resolver,
+ mojom::blink::PointerLockResult result);
+ DOMException* ConvertResultToException(
+ mojom::blink::PointerLockResult result);
+ void RejectIfPromiseEnabled(ScriptPromiseResolver* resolver,
+ DOMException* exception);
Member<Page> page_;
bool lock_pending_;
@@ -85,6 +100,8 @@ class CORE_EXPORT PointerLockController final
FloatPoint pointer_lock_position_;
FloatPoint pointer_lock_screen_position_;
+ bool current_unadjusted_movement_setting_ = false;
+
DISALLOW_COPY_AND_ASSIGN(PointerLockController);
};
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 d87dad4e1b0..f7f90dba8a4 100644
--- a/chromium/third_party/blink/renderer/core/page/print_context.cc
+++ b/chromium/third_party/blink/renderer/core/page/print_context.cc
@@ -173,7 +173,7 @@ void PrintContext::EndPrintMode() {
// static
int PrintContext::PageNumberForElement(Element* element,
const FloatSize& page_size_in_pixels) {
- element->GetDocument().UpdateStyleAndLayout();
+ element->GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kPrinting);
LocalFrame* frame = element->GetDocument().GetFrame();
FloatRect page_rect(FloatPoint(0, 0), page_size_in_pixels);
@@ -300,7 +300,7 @@ String PrintContext::PageSizeAndMarginsInPixels(LocalFrame* frame,
// static
int PrintContext::NumberOfPages(LocalFrame* frame,
const FloatSize& page_size_in_pixels) {
- frame->GetDocument()->UpdateStyleAndLayout();
+ frame->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kPrinting);
FloatRect page_rect(FloatPoint(0, 0), page_size_in_pixels);
ScopedPrintContext print_context(frame);
@@ -319,7 +319,7 @@ bool PrintContext::IsFrameValid() const {
frame_->GetDocument()->GetLayoutView();
}
-void PrintContext::Trace(blink::Visitor* visitor) {
+void PrintContext::Trace(Visitor* visitor) {
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 18270df3f9a..9bcde62284b 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(blink::Visitor*);
+ virtual void Trace(Visitor*);
bool use_printing_layout() const;
@@ -139,10 +139,10 @@ class ScopedPrintContext {
explicit ScopedPrintContext(LocalFrame*);
~ScopedPrintContext();
- PrintContext* operator->() const { return context_.Get(); }
+ PrintContext* operator->() const { return context_; }
private:
- Member<PrintContext> context_;
+ PrintContext* context_;
DISALLOW_COPY_AND_ASSIGN(ScopedPrintContext);
};
diff --git a/chromium/third_party/blink/renderer/core/page/print_context_test.cc b/chromium/third_party/blink/renderer/core/page/print_context_test.cc
index cd38040c55b..94644e6cecd 100644
--- a/chromium/third_party/blink/renderer/core/page/print_context_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/print_context_test.cc
@@ -48,6 +48,10 @@ class MockPageContextCanvas : public SkCanvas {
void onDrawAnnotation(const SkRect& rect,
const char key[],
SkData* value) override {
+ // Ignore PDF node key annotations, defined in SkPDFDocument.cpp.
+ if (0 == strcmp(key, "PDF_Node_Key"))
+ return;
+
if (rect.width() == 0 && rect.height() == 0) {
SkPoint point = getTotalMatrix().mapXY(rect.x(), rect.y());
Operation operation = {kDrawPoint,
@@ -101,7 +105,7 @@ class PrintContextTest : public PaintTestConfigurations, public RenderingTest {
void SetBodyInnerHTML(String body_content) {
GetDocument().body()->setAttribute(html_names::kStyleAttr, "margin: 0");
- GetDocument().body()->SetInnerHTMLFromString(body_content);
+ GetDocument().body()->setInnerHTML(body_content);
}
void PrintSinglePage(SkCanvas& canvas) {
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/DEPS b/chromium/third_party/blink/renderer/core/page/scrolling/DEPS
index 463d864cd91..ad855a9b1a9 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/DEPS
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/DEPS
@@ -3,3 +3,9 @@ include_rules = [
"+cc/layers/painted_scrollbar_layer.h",
"+cc/layers/solid_color_scrollbar_layer.h",
]
+
+specific_include_rules = {
+ "scrolling_test.cc": [
+ "+third_party/blink/renderer/core/exported/web_plugin_container_impl.h"
+ ]
+}
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 73dc75a7693..6106f6d7784 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
@@ -4,13 +4,13 @@
#include "third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_scroll_into_view_options.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
#include "third_party/blink/renderer/core/display_lock/display_lock_context.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/dom/node.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
-#include "third_party/blink/renderer/core/frame/scroll_into_view_options.h"
#include "third_party/blink/renderer/core/svg/svg_svg_element.h"
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -25,7 +25,7 @@ Node* FindAnchorFromFragment(const String& fragment, Document& doc) {
// Implement the rule that "" and "top" both mean top of page as in other
// browsers.
if (!anchor_node &&
- (fragment.IsEmpty() || DeprecatedEqualIgnoringCase(fragment, "top")))
+ (fragment.IsEmpty() || EqualIgnoringASCIICase(fragment, "top")))
return &doc;
return anchor_node;
@@ -157,7 +157,7 @@ void ElementFragmentAnchor::Installed() {
needs_invoke_ = true;
}
-void ElementFragmentAnchor::DidScroll(ScrollType type) {
+void ElementFragmentAnchor::DidScroll(mojom::blink::ScrollType type) {
if (!IsExplicitScrollType(type))
return;
@@ -168,17 +168,7 @@ void ElementFragmentAnchor::DidScroll(ScrollType type) {
needs_invoke_ = false;
}
-void ElementFragmentAnchor::DidCompleteLoad() {
- DCHECK(frame_);
- DCHECK(frame_->View());
-
- // If there is a pending layout, the fragment anchor will be cleared when it
- // finishes.
- if (!frame_->View()->NeedsLayout())
- needs_invoke_ = false;
-}
-
-void ElementFragmentAnchor::Trace(blink::Visitor* visitor) {
+void ElementFragmentAnchor::Trace(Visitor* visitor) {
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 f51ce60afd2..56998427d8f 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
@@ -45,20 +45,17 @@ class CORE_EXPORT ElementFragmentAnchor final : public FragmentAnchor {
// Used to let the anchor know the frame's been scrolled and so we should
// abort keeping the fragment target in view to avoid fighting with user
// scrolls.
- void DidScroll(ScrollType type) override;
+ void DidScroll(mojom::blink::ScrollType type) override;
// Attempts to focus the anchor if we couldn't focus right after install
// (because rendering was blocked at the time). This can cause script to run
// so we can't do it in Invoke.
void PerformPreRafActions() override;
- // We can dispose of the fragment once load has been completed.
- void DidCompleteLoad() override;
-
// Does nothing as an element anchor does not have any dismissal work.
bool Dismiss() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
FRIEND_TEST_ALL_PREFIXES(ElementFragmentAnchorTest,
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor_test.cc b/chromium/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor_test.cc
index e569efda565..2498f8a924f 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor_test.cc
@@ -53,43 +53,54 @@ TEST_F(ElementFragmentAnchorTest, FocusHandlerRunBeforeRaf) {
background-color: red;
}
</style>
- <link rel="stylesheet" type="text/css" href="sheet.css">
<a id="anchorlink" href="#bottom">Link to bottom of the page</a>
<div style="height: 1000px;"></div>
+ <link rel="stylesheet" type="text/css" href="sheet.css">
<input id="bottom">Bottom of the page</input>
- )HTML");
-
- MainFrame().ExecuteScript(WebScriptSource(R"HTML(
- document.getElementById("bottom").addEventListener('focus', () => {
- requestAnimationFrame(() => {
- document.body.style.backgroundColor = '#00FF00';
+ <script>
+ document.getElementById("bottom").addEventListener('focus', () => {
+ requestAnimationFrame(() => {
+ document.body.style.backgroundColor = '#00FF00';
+ });
});
- });
- )HTML"));
+ </script>
+ )HTML");
// We're still waiting on the stylesheet to load so the load event shouldn't
- // yet dispatch and rendering is deferred.
- ASSERT_FALSE(GetDocument().HaveRenderBlockingResourcesLoaded());
+ // yet dispatch.
ASSERT_FALSE(GetDocument().IsLoadCompleted());
// Click on the anchor element. This will cause a synchronous same-document
- // navigation.
+ // navigation. The fragment shouldn't activate yet as parsing will be blocked
+ // due to the unloaded stylesheet.
auto* anchor =
To<HTMLAnchorElement>(GetDocument().getElementById("anchorlink"));
anchor->click();
ASSERT_EQ(GetDocument().body(), GetDocument().ActiveElement())
<< "Active element changed while rendering is blocked";
- // Complete the CSS stylesheet load so the document can finish loading. The
- // fragment should be activated at that point.
+ // Complete the CSS stylesheet load so the document can finish parsing.
css_resource.Complete("");
- Compositor().BeginFrame();
+ test::RunPendingTasks();
- ASSERT_FALSE(GetDocument().IsLoadCompleted());
- ASSERT_TRUE(GetDocument().HaveRenderBlockingResourcesLoaded());
+ // Now that the document has fully parsed the anchor should invoke at this
+ // point.
ASSERT_EQ(GetDocument().getElementById("bottom"),
- GetDocument().ActiveElement())
- << "Active element wasn't changed after rendering was unblocked.";
+ GetDocument().ActiveElement());
+
+ // The background color shouldn't yet be updated.
+ ASSERT_EQ(GetDocument()
+ .body()
+ ->GetLayoutObject()
+ ->Style()
+ ->VisitedDependentColor(GetCSSPropertyBackgroundColor())
+ .NameForLayoutTreeAsText(),
+ Color(255, 0, 0).NameForLayoutTreeAsText());
+
+ Compositor().BeginFrame();
+
+ // Make sure the background color is updated from the rAF without requiring a
+ // second BeginFrame.
EXPECT_EQ(GetDocument()
.body()
->GetLayoutObject()
@@ -220,23 +231,34 @@ TEST_F(ElementFragmentAnchorTest, AnchorRemovedBeforeBeginFrameCrash) {
"text/css");
LoadURL("https://example.com/test.html#anchor");
- main_resource.Complete(R"HTML(
- <!DOCTYPE html>
- <link rel="stylesheet" type="text/css" href="sheet.css">
- <div style="height: 1000px;"></div>
- <input id="anchor">Bottom of the page</input>
- )HTML");
-
- // We're still waiting on the stylesheet to load so the load event shouldn't
- // yet dispatch and rendering is deferred. This will avoid invoking or
- // focusing the fragment when it's first installed.
- ASSERT_FALSE(GetDocument().HaveRenderBlockingResourcesLoaded());
- ASSERT_FALSE(GetDocument().IsLoadCompleted());
-
- ASSERT_TRUE(GetDocument().View()->GetFragmentAnchor());
- ASSERT_TRUE(static_cast<ElementFragmentAnchor*>(
- GetDocument().View()->GetFragmentAnchor())
- ->anchor_node_);
+ if (!RuntimeEnabledFeatures::BlockHTMLParserOnStyleSheetsEnabled()) {
+ main_resource.Complete(R"HTML(
+ <!DOCTYPE html>
+ <link rel="stylesheet" type="text/css" href="sheet.css">
+ <div style="height: 1000px;"></div>
+ <input id="anchor">Bottom of the page</input>
+ )HTML");
+
+ // We're still waiting on the stylesheet to load so the load event shouldn't
+ // yet dispatch and parsing is deferred. This will install the anchor.
+ ASSERT_FALSE(GetDocument().IsLoadCompleted());
+ ASSERT_TRUE(GetDocument().View()->GetFragmentAnchor());
+ ASSERT_TRUE(static_cast<ElementFragmentAnchor*>(
+ GetDocument().View()->GetFragmentAnchor())
+ ->anchor_node_);
+ } else {
+ main_resource.Complete(R"HTML(
+ <!DOCTYPE html>
+ <div style="height: 1000px;"></div>
+ <input id="anchor">Bottom of the page</input>
+ <link rel="stylesheet" type="text/css" href="sheet.css">
+ )HTML");
+
+ // We're still waiting on the stylesheet to load so the load event shouldn't
+ // yet dispatch and parsing is deferred. This will install the anchor.
+ ASSERT_FALSE(GetDocument().IsLoadCompleted());
+ ASSERT_FALSE(GetDocument().View()->GetFragmentAnchor());
+ }
// Remove the fragment anchor from the DOM and perform GC.
GetDocument().getElementById("anchor")->remove();
@@ -244,18 +266,23 @@ TEST_F(ElementFragmentAnchorTest, AnchorRemovedBeforeBeginFrameCrash) {
isolate->RequestGarbageCollectionForTesting(
v8::Isolate::kFullGarbageCollection);
- // Now that the element has been removed and GC'd, unblock rendering so we can
- // produce a frame.
+ // Now that the element has been removed and GC'd, unblock parsing. The
+ // anchor should be installed at this point.
css_resource.Complete("");
-
- ASSERT_TRUE(GetDocument().HaveRenderBlockingResourcesLoaded());
-
- // We should still have a fragment anchor but its node pointer shoulld be
- // gone since it's a WeakMember.
- ASSERT_TRUE(GetDocument().View()->GetFragmentAnchor());
- ASSERT_FALSE(static_cast<ElementFragmentAnchor*>(
- GetDocument().View()->GetFragmentAnchor())
- ->anchor_node_);
+ test::RunPendingTasks();
+
+ if (!RuntimeEnabledFeatures::BlockHTMLParserOnStyleSheetsEnabled()) {
+ // We should still have a fragment anchor but its node pointer should be
+ // gone since it's a WeakMember.
+ ASSERT_TRUE(GetDocument().View()->GetFragmentAnchor());
+ ASSERT_FALSE(static_cast<ElementFragmentAnchor*>(
+ GetDocument().View()->GetFragmentAnchor())
+ ->anchor_node_);
+ } else {
+ // The fragment shouldn't have installed since the targeted element was
+ // removed.
+ ASSERT_FALSE(GetDocument().View()->GetFragmentAnchor());
+ }
// We'd normally focus the fragment during BeginFrame. Make sure we don't
// crash since it's been GC'd.
@@ -291,7 +318,7 @@ TEST_F(ElementFragmentAnchorTest, SVGDocumentDoesntCreateFragment) {
)SVG");
auto* img = To<HTMLImageElement>(GetDocument().getElementById("image"));
- SVGImage* svg = ToSVGImage(img->CachedImage()->GetImage());
+ auto* svg = To<SVGImage>(img->CachedImage()->GetImage());
auto* view =
DynamicTo<LocalFrameView>(svg->GetPageForTesting()->MainFrame()->View());
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 db3ebbc7839..0d8e0886b96 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
@@ -7,6 +7,7 @@
#include "base/metrics/histogram_macros.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"
#include "third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.h"
#include "third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -68,7 +69,7 @@ FragmentAnchor* FragmentAnchor::TryCreate(const KURL& url,
// Track how often we have a element fragment that we can't find. Only track
// if we didn't match a text fragment since we expect those would inflate the
// "failed" case.
- if (frame.GetDocument()->IsHTMLDocument() && url.HasFragmentIdentifier() &&
+ if (IsA<HTMLDocument>(frame.GetDocument()) && url.HasFragmentIdentifier() &&
!text_fragment_anchor_created) {
UMA_HISTOGRAM_BOOLEAN("TextFragmentAnchor.ElementIdFragmentFound",
element_id_anchor_found);
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 7550d5674a9..e8d1eddcff1 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
@@ -49,16 +49,15 @@ class CORE_EXPORT FragmentAnchor : public GarbageCollected<FragmentAnchor> {
// anchor to perform some initialization.
virtual void Installed() = 0;
- virtual void DidScroll(ScrollType type) = 0;
+ virtual void DidScroll(mojom::blink::ScrollType type) = 0;
virtual void PerformPreRafActions() = 0;
- virtual void DidCompleteLoad() = 0;
// Dismissing the fragment anchor removes indicators of the anchor, such as
// text highlighting on a text fragment anchor. If true, the anchor has been
// dismissed and can be disposed.
virtual bool Dismiss() = 0;
- virtual void Trace(blink::Visitor*) {}
+ virtual void Trace(Visitor*) {}
};
} // 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 182c2d6ef5d..c0148282498 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
@@ -32,7 +32,7 @@ class MainThreadScrollingReasonsTest : public testing::Test {
helper_.InitializeWithSettings(&ConfigureSettings);
GetWebView()->MainFrameWidget()->Resize(IntSize(320, 240));
GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
}
~MainThreadScrollingReasonsTest() override {
@@ -51,7 +51,7 @@ class MainThreadScrollingReasonsTest : public testing::Test {
void ForceFullCompositingUpdate() {
GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
}
void RegisterMockedHttpURLLoad(const String& file_name) {
@@ -61,11 +61,18 @@ class MainThreadScrollingReasonsTest : public testing::Test {
WebString(base_url_), test::CoreTestDataPath(), WebString(file_name));
}
- uint32_t GetMainThreadScrollingReasons(const cc::Layer* layer) const {
+ const cc::ScrollNode* GetScrollNode(const cc::Layer* layer) const {
return layer->layer_tree_host()
->property_trees()
- ->scroll_tree.Node(layer->scroll_tree_index())
- ->main_thread_scrolling_reasons;
+ ->scroll_tree.FindNodeFromElementId(layer->element_id());
+ }
+
+ bool IsScrollable(const cc::Layer* layer) const {
+ return GetScrollNode(layer)->scrollable;
+ }
+
+ uint32_t GetMainThreadScrollingReasons(const cc::Layer* layer) const {
+ return GetScrollNode(layer)->main_thread_scrolling_reasons;
}
uint32_t GetViewMainThreadScrollingReasons() const {
@@ -126,7 +133,7 @@ TEST_F(MainThreadScrollingReasonsTest,
cc::Layer* cc_scroll_layer =
inner_frame_view->LayoutViewport()->LayerForScrolling();
ASSERT_TRUE(cc_scroll_layer);
- ASSERT_TRUE(cc_scroll_layer->scrollable());
+ ASSERT_TRUE(IsScrollable(cc_scroll_layer));
ASSERT_TRUE(
GetMainThreadScrollingReasons(cc_scroll_layer) &
cc::MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects);
@@ -146,7 +153,7 @@ TEST_F(MainThreadScrollingReasonsTest,
cc_scroll_layer =
layout_object->GetFrameView()->LayoutViewport()->LayerForScrolling();
ASSERT_TRUE(cc_scroll_layer);
- ASSERT_TRUE(cc_scroll_layer->scrollable());
+ ASSERT_TRUE(IsScrollable(cc_scroll_layer));
ASSERT_FALSE(
GetMainThreadScrollingReasons(cc_scroll_layer) &
cc::MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects);
@@ -167,7 +174,7 @@ TEST_F(MainThreadScrollingReasonsTest,
cc_scroll_layer =
layout_object->GetFrameView()->LayoutViewport()->LayerForScrolling();
ASSERT_TRUE(cc_scroll_layer);
- ASSERT_TRUE(cc_scroll_layer->scrollable());
+ ASSERT_TRUE(IsScrollable(cc_scroll_layer));
ASSERT_TRUE(
GetMainThreadScrollingReasons(cc_scroll_layer) &
cc::MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects);
@@ -219,7 +226,7 @@ TEST_F(MainThreadScrollingReasonsTest, FastScrollingCanBeDisabledWithSetting) {
// Main scrolling should also propagate to inner viewport layer.
const cc::Layer* visual_viewport_scroll_layer =
GetFrame()->GetPage()->GetVisualViewport().LayerForScrolling();
- ASSERT_TRUE(visual_viewport_scroll_layer->scrollable());
+ ASSERT_TRUE(IsScrollable(visual_viewport_scroll_layer));
EXPECT_TRUE(GetMainThreadScrollingReasons(visual_viewport_scroll_layer));
}
@@ -251,7 +258,7 @@ TEST_F(MainThreadScrollingReasonsTest, FastScrollingByDefault) {
const cc::Layer* visual_viewport_scroll_layer =
GetFrame()->GetPage()->GetVisualViewport().LayerForScrolling();
- ASSERT_TRUE(visual_viewport_scroll_layer->scrollable());
+ ASSERT_TRUE(IsScrollable(visual_viewport_scroll_layer));
EXPECT_FALSE(GetMainThreadScrollingReasons(visual_viewport_scroll_layer));
}
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 8fe00af74d2..d75c02219ed 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
@@ -20,12 +20,12 @@ namespace {
// to maintain consistency as done in the compositor.
const float kMinimumOverscrollDelta = 0.1;
-void AdjustOverscroll(FloatSize* unused_delta) {
+void AdjustOverscroll(gfx::Vector2dF* unused_delta) {
DCHECK(unused_delta);
- if (std::abs(unused_delta->Width()) < kMinimumOverscrollDelta)
- unused_delta->SetWidth(0);
- if (std::abs(unused_delta->Height()) < kMinimumOverscrollDelta)
- unused_delta->SetHeight(0);
+ if (std::abs(unused_delta->x()) < kMinimumOverscrollDelta)
+ unused_delta->set_x(0);
+ if (std::abs(unused_delta->y()) < kMinimumOverscrollDelta)
+ unused_delta->set_y(0);
}
} // namespace
@@ -35,16 +35,16 @@ OverscrollController::OverscrollController(
ChromeClient& chrome_client)
: visual_viewport_(&visual_viewport), chrome_client_(&chrome_client) {}
-void OverscrollController::Trace(blink::Visitor* visitor) {
+void OverscrollController::Trace(Visitor* visitor) {
visitor->Trace(visual_viewport_);
visitor->Trace(chrome_client_);
}
void OverscrollController::ResetAccumulated(bool reset_x, bool reset_y) {
if (reset_x)
- accumulated_root_overscroll_.SetWidth(0);
+ accumulated_root_overscroll_.set_x(0);
if (reset_y)
- accumulated_root_overscroll_.SetHeight(0);
+ accumulated_root_overscroll_.set_y(0);
}
void OverscrollController::HandleOverscroll(
@@ -54,20 +54,20 @@ void OverscrollController::HandleOverscroll(
DCHECK(visual_viewport_);
DCHECK(chrome_client_);
- FloatSize unused_delta(scroll_result.unused_scroll_delta_x,
- scroll_result.unused_scroll_delta_y);
+ gfx::Vector2dF unused_delta(scroll_result.unused_scroll_delta_x,
+ scroll_result.unused_scroll_delta_y);
AdjustOverscroll(&unused_delta);
- FloatSize delta_in_viewport =
- unused_delta.ScaledBy(visual_viewport_->Scale());
- FloatSize velocity_in_viewport =
- velocity_in_root_frame.ScaledBy(visual_viewport_->Scale());
- FloatPoint position_in_viewport =
+ gfx::Vector2dF delta_in_viewport =
+ gfx::ScaleVector2d(unused_delta, visual_viewport_->Scale());
+ gfx::Vector2dF velocity_in_viewport = gfx::ScaleVector2d(
+ gfx::Vector2dF(velocity_in_root_frame), visual_viewport_->Scale());
+ gfx::PointF position_in_viewport =
visual_viewport_->RootFrameToViewport(position_in_root_frame);
ResetAccumulated(scroll_result.did_scroll_x, scroll_result.did_scroll_y);
- if (delta_in_viewport != FloatSize()) {
+ if (!delta_in_viewport.IsZero()) {
accumulated_root_overscroll_ += delta_in_viewport;
chrome_client_->DidOverscroll(delta_in_viewport,
accumulated_root_overscroll_,
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 6ca1edd3c55..23b7a4b4dba 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,13 +36,13 @@ class OverscrollController : public GarbageCollected<OverscrollController> {
const FloatPoint& position_in_root_frame,
const FloatSize& velocity_in_root_frame);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
WeakMember<const VisualViewport> visual_viewport_;
WeakMember<ChromeClient> chrome_client_;
- FloatSize accumulated_root_overscroll_;
+ gfx::Vector2dF accumulated_root_overscroll_;
};
} // namespace blink
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 732536e29f2..c235d4199aa 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(blink::Visitor* visitor) {
+void RootScrollerController::Trace(Visitor* visitor) {
visitor->Trace(document_);
visitor->Trace(root_scroller_);
visitor->Trace(effective_root_scroller_);
@@ -312,7 +312,7 @@ bool RootScrollerController::IsValidImplicit(const Element& element) const {
// The LayoutView is allowed to have a clip (since its clip is resized by
// the URL bar movement). Test it for scrolling so that we only promote if
// we know we won't block scrolling the main document.
- if (ancestor->IsLayoutView()) {
+ if (IsA<LayoutView>(ancestor)) {
const ComputedStyle* ancestor_style = ancestor->Style();
DCHECK(ancestor_style);
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 834957baf45..26c95b6fb1d 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(blink::Visitor*);
+ void Trace(Visitor*);
// 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 f67f9f5409e..4f8f3b4d58a 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
@@ -26,6 +26,7 @@
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
+#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h"
#include "third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.h"
@@ -113,7 +114,7 @@ class RootScrollerTest : public testing::Test,
void ExecuteScript(const WebString& code, WebLocalFrame& frame) {
frame.ExecuteScript(WebScriptSource(code));
frame.View()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
RunPendingTasks();
}
@@ -164,7 +165,7 @@ class RootScrollerTest : public testing::Test,
int delta_y) {
WebGestureEvent event(type, WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(), device);
- event.SetPositionInWidget(WebFloatPoint(100, 100));
+ event.SetPositionInWidget(gfx::PointF(100, 100));
if (type == WebInputEvent::kGestureScrollUpdate) {
event.data.scroll_update.delta_x = delta_x;
event.data.scroll_update.delta_y = delta_y;
@@ -191,8 +192,7 @@ class RootScrollerTest : public testing::Test,
}
void UpdateAllLifecyclePhases(LocalFrameView* view) {
- view->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ view->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
}
String base_url_;
@@ -239,10 +239,10 @@ class OverscrollTestWebWidgetClient
: public frame_test_helpers::TestWebWidgetClient {
public:
MOCK_METHOD4(DidOverscroll,
- void(const WebFloatSize&,
- const WebFloatSize&,
- const WebFloatPoint&,
- const WebFloatSize&));
+ void(const gfx::Vector2dF&,
+ const gfx::Vector2dF&,
+ const gfx::PointF&,
+ const gfx::Vector2dF&));
};
// Tests that setting an element as the root scroller causes it to control url
@@ -286,8 +286,9 @@ TEST_F(RootScrollerTest, TestSetRootScroller) {
{
// Scroll 50 pixels past the end. Ensure we report the 50 pixels as
// overscroll.
- EXPECT_CALL(client, DidOverscroll(WebFloatSize(0, 50), WebFloatSize(0, 50),
- WebFloatPoint(100, 100), WebFloatSize()));
+ EXPECT_CALL(client,
+ DidOverscroll(gfx::Vector2dF(0, 50), gfx::Vector2dF(0, 50),
+ gfx::PointF(100, 100), gfx::Vector2dF()));
GetWebView()->MainFrameWidget()->HandleInputEvent(GenerateTouchGestureEvent(
WebInputEvent::kGestureScrollUpdate, 0, -500));
EXPECT_FLOAT_EQ(maximum_scroll, container->scrollTop());
@@ -298,8 +299,9 @@ TEST_F(RootScrollerTest, TestSetRootScroller) {
{
// Continue the gesture overscroll.
- EXPECT_CALL(client, DidOverscroll(WebFloatSize(0, 20), WebFloatSize(0, 70),
- WebFloatPoint(100, 100), WebFloatSize()));
+ EXPECT_CALL(client,
+ DidOverscroll(gfx::Vector2dF(0, 20), gfx::Vector2dF(0, 70),
+ gfx::PointF(100, 100), gfx::Vector2dF()));
GetWebView()->MainFrameWidget()->HandleInputEvent(
GenerateTouchGestureEvent(WebInputEvent::kGestureScrollUpdate, 0, -20));
EXPECT_FLOAT_EQ(maximum_scroll, container->scrollTop());
@@ -317,8 +319,9 @@ TEST_F(RootScrollerTest, TestSetRootScroller) {
GetWebView()->MainFrameWidget()->HandleInputEvent(
GenerateTouchGestureEvent(WebInputEvent::kGestureScrollBegin));
- EXPECT_CALL(client, DidOverscroll(WebFloatSize(0, 30), WebFloatSize(0, 30),
- WebFloatPoint(100, 100), WebFloatSize()));
+ EXPECT_CALL(client,
+ DidOverscroll(gfx::Vector2dF(0, 30), gfx::Vector2dF(0, 30),
+ gfx::PointF(100, 100), gfx::Vector2dF()));
GetWebView()->MainFrameWidget()->HandleInputEvent(
GenerateTouchGestureEvent(WebInputEvent::kGestureScrollUpdate, 0, -30));
EXPECT_FLOAT_EQ(maximum_scroll, container->scrollTop());
@@ -875,7 +878,8 @@ TEST_F(RootScrollerTest, NonMainLocalRootLifecycle) {
// 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();
+ helper_.LocalMainFrame()->GetFrameView()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
UpdateAllLifecyclePhases(non_main_local_root->GetFrameView());
UpdateAllLifecyclePhases(helper_.LocalMainFrame()->GetFrameView());
@@ -902,7 +906,7 @@ TEST_F(RootScrollerTest, RemoveRootScrollerFromDom) {
ASSERT_EQ(inner_container,
EffectiveRootScroller(iframe->contentDocument()));
- iframe->contentDocument()->body()->SetInnerHTMLFromString("");
+ iframe->contentDocument()->body()->setInnerHTML("");
// If the root scroller wasn't updated by the DOM removal above, this
// will touch the disposed root scroller's ScrollableArea.
@@ -1299,8 +1303,8 @@ TEST_F(RootScrollerSimTest, NonLifecycleLayoutDoesntCauseReselection) {
ASSERT_EQ(container,
GetDocument().GetRootScrollerController().EffectiveRootScroller());
- container->style()->setProperty(&GetDocument(), "width", "95%", String(),
- ASSERT_NO_EXCEPTION);
+ container->style()->setProperty(GetDocument().ToExecutionContext(), "width",
+ "95%", String(), ASSERT_NO_EXCEPTION);
ASSERT_TRUE(Compositor().NeedsBeginFrame());
@@ -1619,15 +1623,16 @@ TEST_F(ImplicitRootScrollerSimTest, ImplicitRootScroller) {
String& style_val = std::get<1>(test_case);
Node* expected_root_scroller = std::get<2>(test_case);
- container->style()->setProperty(&GetDocument(), style, style_val, String(),
- ASSERT_NO_EXCEPTION);
+ container->style()->setProperty(GetDocument().ToExecutionContext(), style,
+ style_val, String(), ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
ASSERT_EQ(expected_root_scroller,
GetDocument().GetRootScrollerController().EffectiveRootScroller())
<< "Failed to set rootScroller after setting " << std::get<0>(test_case)
<< ": " << std::get<1>(test_case);
- container->style()->setProperty(&GetDocument(), std::get<0>(test_case),
- String(), String(), ASSERT_NO_EXCEPTION);
+ container->style()->setProperty(GetDocument().ToExecutionContext(),
+ std::get<0>(test_case), String(), String(),
+ ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
ASSERT_EQ(&GetDocument(),
GetDocument().GetRootScrollerController().EffectiveRootScroller())
@@ -1646,16 +1651,17 @@ TEST_F(ImplicitRootScrollerSimTest, ImplicitRootScroller) {
String& style_val = std::get<1>(test_case);
Node* expected_root_scroller = &GetDocument();
- container->style()->setProperty(&GetDocument(), style, style_val, String(),
- ASSERT_NO_EXCEPTION);
+ container->style()->setProperty(GetDocument().ToExecutionContext(), style,
+ style_val, String(), ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
ASSERT_EQ(expected_root_scroller,
GetDocument().GetRootScrollerController().EffectiveRootScroller())
<< "Failed to set rootScroller after setting " << std::get<0>(test_case)
<< ": " << std::get<1>(test_case);
- container->style()->setProperty(&GetDocument(), std::get<0>(test_case),
- String(), String(), ASSERT_NO_EXCEPTION);
+ container->style()->setProperty(GetDocument().ToExecutionContext(),
+ std::get<0>(test_case), String(), String(),
+ ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
ASSERT_EQ(&GetDocument(),
GetDocument().GetRootScrollerController().EffectiveRootScroller())
@@ -1699,10 +1705,10 @@ TEST_F(ImplicitRootScrollerSimTest, ImplicitRootScrollerAddOverflow) {
<< "Shouldn't promote 'container' since it has no overflow.";
Element* spacer = GetDocument().getElementById("spacer");
- spacer->style()->setProperty(&GetDocument(), "height", "2000px", String(),
- ASSERT_NO_EXCEPTION);
- spacer->style()->setProperty(&GetDocument(), "width", "2000px", String(),
- ASSERT_NO_EXCEPTION);
+ spacer->style()->setProperty(GetDocument().ToExecutionContext(), "height",
+ "2000px", String(), ASSERT_NO_EXCEPTION);
+ spacer->style()->setProperty(GetDocument().ToExecutionContext(), "width",
+ "2000px", String(), ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
Element* container = GetDocument().getElementById("container");
EXPECT_EQ(container,
@@ -1811,10 +1817,10 @@ TEST_F(ImplicitRootScrollerSimTest,
GetDocument().GetRootScrollerController().EffectiveRootScroller());
Element* overflow = GetDocument().getElementById("overflow");
- overflow->style()->setProperty(&GetDocument(), "height", "10px", String(),
- ASSERT_NO_EXCEPTION);
- overflow->style()->setProperty(&GetDocument(), "width", "10px", String(),
- ASSERT_NO_EXCEPTION);
+ overflow->style()->setProperty(GetDocument().ToExecutionContext(), "height",
+ "10px", String(), ASSERT_NO_EXCEPTION);
+ overflow->style()->setProperty(GetDocument().ToExecutionContext(), "width",
+ "10px", String(), ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
EXPECT_EQ(&GetDocument(),
GetDocument().GetRootScrollerController().EffectiveRootScroller())
@@ -1864,36 +1870,39 @@ TEST_F(ImplicitRootScrollerSimTest, ImplicitRootScrollerVisibilityCondition) {
ASSERT_EQ(container,
GetDocument().GetRootScrollerController().EffectiveRootScroller());
- container->style()->setProperty(&GetDocument(), "opacity", "0.5", String(),
- ASSERT_NO_EXCEPTION);
+ container->style()->setProperty(GetDocument().ToExecutionContext(), "opacity",
+ "0.5", String(), ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
EXPECT_EQ(&GetDocument(),
GetDocument().GetRootScrollerController().EffectiveRootScroller())
<< "Adding opacity to 'container' causes it to be demoted.";
- container->style()->setProperty(&GetDocument(), "opacity", "", String(),
- ASSERT_NO_EXCEPTION);
+ container->style()->setProperty(GetDocument().ToExecutionContext(), "opacity",
+ "", String(), ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
EXPECT_EQ(container,
GetDocument().GetRootScrollerController().EffectiveRootScroller())
<< "Removing opacity from 'container' causes it to be promoted.";
- container->style()->setProperty(&GetDocument(), "visibility", "hidden",
- String(), ASSERT_NO_EXCEPTION);
+ container->style()->setProperty(GetDocument().ToExecutionContext(),
+ "visibility", "hidden", String(),
+ ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
EXPECT_EQ(&GetDocument(),
GetDocument().GetRootScrollerController().EffectiveRootScroller())
<< "visibility:hidden causes 'container' to be demoted.";
- container->style()->setProperty(&GetDocument(), "visibility", "collapse",
- String(), ASSERT_NO_EXCEPTION);
+ container->style()->setProperty(GetDocument().ToExecutionContext(),
+ "visibility", "collapse", String(),
+ ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
EXPECT_EQ(&GetDocument(),
GetDocument().GetRootScrollerController().EffectiveRootScroller())
<< "visibility:collapse doesn't cause 'container' to be promoted.";
- container->style()->setProperty(&GetDocument(), "visibility", "visible",
- String(), ASSERT_NO_EXCEPTION);
+ container->style()->setProperty(GetDocument().ToExecutionContext(),
+ "visibility", "visible", String(),
+ ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
EXPECT_EQ(container,
GetDocument().GetRootScrollerController().EffectiveRootScroller())
@@ -1935,8 +1944,8 @@ TEST_F(ImplicitRootScrollerSimTest, ImplicitRootScrollerIframe) {
ASSERT_EQ(container,
GetDocument().GetRootScrollerController().EffectiveRootScroller());
- container->style()->setProperty(&GetDocument(), "height", "95%", String(),
- ASSERT_NO_EXCEPTION);
+ container->style()->setProperty(GetDocument().ToExecutionContext(), "height",
+ "95%", String(), ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
ASSERT_EQ(&GetDocument(),
@@ -1977,8 +1986,8 @@ TEST_F(ImplicitRootScrollerSimTest, UseCounterNegative) {
EXPECT_FALSE(
GetDocument().IsUseCounted(WebFeature::kActivatedImplicitRootScroller));
- container->style()->setProperty(&GetDocument(), "height", "150%", String(),
- ASSERT_NO_EXCEPTION);
+ container->style()->setProperty(GetDocument().ToExecutionContext(), "height",
+ "150%", String(), ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
EXPECT_FALSE(
@@ -2025,8 +2034,8 @@ TEST_F(ImplicitRootScrollerSimTest, UseCounterPositive) {
EXPECT_TRUE(
GetDocument().IsUseCounted(WebFeature::kActivatedImplicitRootScroller));
- container->style()->setProperty(&GetDocument(), "height", "150%", String(),
- ASSERT_NO_EXCEPTION);
+ container->style()->setProperty(GetDocument().ToExecutionContext(), "height",
+ "150%", String(), ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
ASSERT_NE(container,
@@ -2076,8 +2085,8 @@ TEST_F(ImplicitRootScrollerSimTest, UseCounterPositiveAfterLoad) {
EXPECT_FALSE(
GetDocument().IsUseCounted(WebFeature::kActivatedImplicitRootScroller));
- container->style()->setProperty(&GetDocument(), "height", "100%", String(),
- ASSERT_NO_EXCEPTION);
+ container->style()->setProperty(GetDocument().ToExecutionContext(), "height",
+ "100%", String(), ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
ASSERT_EQ(container,
@@ -2178,8 +2187,8 @@ TEST_F(ImplicitRootScrollerSimTest, DontPromoteWhenMultipleAreValid) {
// Now make the second one invalid, that should cause the first to be
// promoted.
Element* container2 = GetDocument().getElementById("container2");
- container2->style()->setProperty(&GetDocument(), "height", "95%", String(),
- ASSERT_NO_EXCEPTION);
+ container2->style()->setProperty(GetDocument().ToExecutionContext(), "height",
+ "95%", String(), ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
Element* container = GetDocument().getElementById("container");
@@ -2311,6 +2320,74 @@ TEST_F(ImplicitRootScrollerSimTest, NavigateToValidRemainsRootScroller) {
<< "Once loaded, the iframe should be promoted again.";
}
+// Ensure that scroll restoration logic in the document does not apply
+// to the implicit root scroller, but rather to the document's LayoutViewport.
+TEST_F(ImplicitRootScrollerSimTest, ScrollRestorationIgnoresImplicit) {
+ WebView().MainFrameWidget()->Resize(WebSize(800, 600));
+ 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");
+ child_request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ body {
+ height: 1000px;
+ }
+ </style>
+ )HTML");
+ Compositor().BeginFrame();
+ ASSERT_EQ(GetDocument().getElementById("container"),
+ GetDocument().GetRootScrollerController().EffectiveRootScroller());
+
+ HistoryItem::ViewState view_state;
+ view_state.scroll_offset_ = ScrollOffset(10, 20);
+
+ GetDocument()
+ .View()
+ ->GetScrollableArea()
+ ->SetPendingHistoryRestoreScrollOffset(view_state, true);
+ GetDocument().View()->LayoutViewport()->SetPendingHistoryRestoreScrollOffset(
+ view_state, true);
+ GetDocument().View()->ScheduleAnimation();
+
+ Compositor().BeginFrame();
+ EXPECT_EQ(ScrollOffset(0, 0),
+ GetDocument().View()->GetScrollableArea()->GetScrollOffset());
+
+ GetDocument().domWindow()->scrollTo(0, 20);
+ GetDocument().View()->ScheduleAnimation();
+ // Check that an implicit scroll offset is not saved.
+ // TODO(chrishtr): probably it should?
+ Compositor().BeginFrame();
+ EXPECT_FALSE(GetDocument()
+ .GetFrame()
+ ->Loader()
+ .GetDocumentLoader()
+ ->GetHistoryItem()
+ ->GetViewState());
+}
+
// Test that a root scroller is considered to fill the viewport at both the URL
// bar shown and URL bar hidden height.
TEST_F(ImplicitRootScrollerSimTest,
@@ -2372,16 +2449,16 @@ TEST_F(ImplicitRootScrollerSimTest,
// Set the height explicitly to a new value in-between. The root scroller
// should be demoted.
- container->style()->setProperty(&GetDocument(), "height", "601px", String(),
- ASSERT_NO_EXCEPTION);
+ container->style()->setProperty(GetDocument().ToExecutionContext(), "height",
+ "601px", String(), ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
EXPECT_EQ(GetDocument(),
GetDocument().GetRootScrollerController().EffectiveRootScroller());
// Reset back to valid and hide the top controls. Zoom to 2x. Ensure we're
// still considered valid.
- container->style()->setProperty(&GetDocument(), "height", "", String(),
- ASSERT_NO_EXCEPTION);
+ container->style()->setProperty(GetDocument().ToExecutionContext(), "height",
+ "", String(), ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
EXPECT_EQ(container,
GetDocument().GetRootScrollerController().EffectiveRootScroller());
@@ -2442,37 +2519,40 @@ TEST_F(ImplicitRootScrollerSimTest, ContinuallyReevaluateImplicitPromotion) {
GetDocument().GetRootScrollerController().EffectiveRootScroller());
// The container now has overflow but still doesn't scroll.
- spacer->style()->setProperty(&GetDocument(), "height", "2000px", String(),
- ASSERT_NO_EXCEPTION);
+ spacer->style()->setProperty(GetDocument().ToExecutionContext(), "height",
+ "2000px", String(), ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
EXPECT_EQ(GetDocument(),
GetDocument().GetRootScrollerController().EffectiveRootScroller());
// The container is now scrollable and should be promoted.
- container->style()->setProperty(&GetDocument(), "overflow", "auto", String(),
+ container->style()->setProperty(GetDocument().ToExecutionContext(),
+ "overflow", "auto", String(),
ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
EXPECT_EQ(container,
GetDocument().GetRootScrollerController().EffectiveRootScroller());
// The container is now not viewport-filling so it should be demoted.
- container->style()->setProperty(&GetDocument(), "transform",
- "translateX(-50px)", String(),
+ container->style()->setProperty(GetDocument().ToExecutionContext(),
+ "transform", "translateX(-50px)", String(),
ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
EXPECT_EQ(GetDocument(),
GetDocument().GetRootScrollerController().EffectiveRootScroller());
// The container is viewport-filling again so it should be promoted.
- parent->style()->setProperty(&GetDocument(), "transform", "translateX(50px)",
- String(), ASSERT_NO_EXCEPTION);
+ parent->style()->setProperty(GetDocument().ToExecutionContext(), "transform",
+ "translateX(50px)", String(),
+ ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
EXPECT_EQ(container,
GetDocument().GetRootScrollerController().EffectiveRootScroller());
// No longer scrollable so demote.
- container->style()->setProperty(&GetDocument(), "overflow", "hidden",
- String(), ASSERT_NO_EXCEPTION);
+ container->style()->setProperty(GetDocument().ToExecutionContext(),
+ "overflow", "hidden", String(),
+ ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
EXPECT_EQ(GetDocument(),
GetDocument().GetRootScrollerController().EffectiveRootScroller());
@@ -2520,17 +2600,17 @@ TEST_F(ImplicitRootScrollerSimTest, IframeScrollingAffectsPromotion) {
GetDocument().GetRootScrollerController().EffectiveRootScroller());
// Allows scrolling now so promote.
- inner_html_element->style()->setProperty(container->contentDocument(),
- "overflow", "auto", String(),
- ASSERT_NO_EXCEPTION);
+ inner_html_element->style()->setProperty(
+ container->contentDocument()->ToExecutionContext(), "overflow", "auto",
+ String(), ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
EXPECT_EQ(container,
GetDocument().GetRootScrollerController().EffectiveRootScroller());
// Demote again.
- inner_html_element->style()->setProperty(container->contentDocument(),
- "overflow", "hidden", String(),
- ASSERT_NO_EXCEPTION);
+ inner_html_element->style()->setProperty(
+ container->contentDocument()->ToExecutionContext(), "overflow", "hidden",
+ String(), ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
EXPECT_EQ(GetDocument(),
GetDocument().GetRootScrollerController().EffectiveRootScroller());
@@ -2832,8 +2912,8 @@ TEST_F(ImplicitRootScrollerSimTest, OverflowInMainDocumentRestrictsImplicit) {
<< "iframe shouldn't be promoted due to overflow in the main document.";
Element* spacer = GetDocument().getElementById("spacer");
- spacer->style()->setProperty(&GetDocument(), "height", "100%", String(),
- ASSERT_NO_EXCEPTION);
+ spacer->style()->setProperty(GetDocument().ToExecutionContext(), "height",
+ "100%", String(), ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
EXPECT_EQ(GetDocument().getElementById("container"),
@@ -2895,16 +2975,16 @@ TEST_F(ImplicitRootScrollerSimTest, OverflowHiddenDoesntRestrictImplicit) {
<< "iframe should be promoted since document's overflow is hidden.";
Element* html = GetDocument().documentElement();
- html->style()->setProperty(&GetDocument(), "overflow", "auto", String(),
- ASSERT_NO_EXCEPTION);
+ html->style()->setProperty(GetDocument().ToExecutionContext(), "overflow",
+ "auto", String(), ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
EXPECT_EQ(GetDocument(),
GetDocument().GetRootScrollerController().EffectiveRootScroller())
<< "iframe should now be demoted since main document scrolls overflow.";
- html->style()->setProperty(&GetDocument(), "overflow", "visible", String(),
- ASSERT_NO_EXCEPTION);
+ html->style()->setProperty(GetDocument().ToExecutionContext(), "overflow",
+ "visible", String(), ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
EXPECT_EQ(GetDocument(),
@@ -2988,8 +3068,8 @@ TEST_F(ImplicitRootScrollerSimTest, ClippingAncestorPreventsPromotion) {
GetDocument().GetRootScrollerController().EffectiveRootScroller())
<< "iframe should start off promoted.";
- ancestor->style()->setProperty(&GetDocument(), style, style_val, String(),
- ASSERT_NO_EXCEPTION);
+ ancestor->style()->setProperty(GetDocument().ToExecutionContext(), style,
+ style_val, String(), ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
EXPECT_EQ(GetDocument(),
@@ -2997,8 +3077,8 @@ TEST_F(ImplicitRootScrollerSimTest, ClippingAncestorPreventsPromotion) {
<< "iframe should be demoted since ancestor has " << style << ": "
<< style_val;
- ancestor->style()->setProperty(&GetDocument(), style, String(), String(),
- ASSERT_NO_EXCEPTION);
+ ancestor->style()->setProperty(GetDocument().ToExecutionContext(), style,
+ String(), String(), ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
ASSERT_EQ(iframe,
GetDocument().GetRootScrollerController().EffectiveRootScroller())
@@ -3102,7 +3182,7 @@ class RootScrollerHitTest : public RootScrollerSimTest {
// to the bottom.
ASSERT_EQ(1, GetBrowserControls().TopShownRatio());
ASSERT_EQ(1, GetBrowserControls().BottomShownRatio());
- WebView().MainFrameWidget()->ApplyViewportChanges(
+ WebView().MainFrameWidget()->ApplyViewportChangesForTesting(
{gfx::ScrollOffset(), gfx::Vector2dF(), 1, false, -1, -1,
cc::BrowserControlsState::kBoth});
ASSERT_EQ(0, GetBrowserControls().TopShownRatio());
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 ad7ee18b583..b7cb6767780 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(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
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_into_view_test.cc b/chromium/third_party/blink/renderer/core/page/scrolling/scroll_into_view_test.cc
index 443254b2e0d..253e54e6318 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/scroll_into_view_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/scroll_into_view_test.cc
@@ -4,21 +4,22 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/frame/find_in_page.mojom-blink.h"
-#include "third_party/blink/public/platform/web_scroll_into_view_params.h"
+#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink.h"
#include "third_party/blink/public/web/web_script_source.h"
#include "third_party/blink/renderer/bindings/core/v8/scroll_into_view_options_or_boolean.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_scroll_into_view_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_scroll_to_options.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/frame/find_in_page.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/root_frame_viewport.h"
-#include "third_party/blink/renderer/core/frame/scroll_into_view_options.h"
-#include "third_party/blink/renderer/core/frame/scroll_to_options.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/html/html_element.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/page/scrolling/top_document_root_scroller_controller.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
+#include "third_party/blink/renderer/core/scroll/scroll_alignment.h"
#include "third_party/blink/renderer/core/testing/sim/sim_compositor.h"
#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
@@ -588,12 +589,13 @@ TEST_F(ScrollIntoViewTest, StopAtLayoutViewportOption) {
// stop_at_main_frame_layout_viewport.
LayoutObject* target =
GetDocument().getElementById("target")->GetLayoutObject();
- WebScrollIntoViewParams params(
- ScrollAlignment::kAlignLeftAlways, ScrollAlignment::kAlignTopAlways,
- kProgrammaticScroll, false, kScrollBehaviorInstant);
- params.stop_at_main_frame_layout_viewport = true;
+ auto params = ScrollAlignment::CreateScrollIntoViewParams(
+ ScrollAlignment::LeftAlways(), ScrollAlignment::TopAlways(),
+ mojom::blink::ScrollType::kProgrammatic, false,
+ mojom::blink::ScrollBehavior::kInstant);
+ params->stop_at_main_frame_layout_viewport = true;
target->ScrollRectToVisible(PhysicalRect(target->AbsoluteBoundingBoxRect()),
- params);
+ std::move(params));
ScrollableArea* root_scroller =
ToLayoutBox(root->GetLayoutObject())->GetScrollableArea();
@@ -683,8 +685,10 @@ TEST_F(ScrollIntoViewTest, SmoothUserScrollNotAbortedByProgrammaticScrolls) {
Element* content = GetDocument().getElementById("content");
content->GetLayoutObject()->ScrollRectToVisible(
content->BoundingBoxForScrollIntoView(),
- {ScrollAlignment::kAlignToEdgeIfNeeded, ScrollAlignment::kAlignTopAlways,
- kUserScroll, false, kScrollBehaviorSmooth, true});
+ ScrollAlignment::CreateScrollIntoViewParams(
+ ScrollAlignment::ToEdgeIfNeeded(), ScrollAlignment::TopAlways(),
+ mojom::blink::ScrollType::kUser, false,
+ mojom::blink::ScrollBehavior::kSmooth, true));
// Animating the container
Compositor().BeginFrame(); // update run_state_.
@@ -725,10 +729,10 @@ TEST_F(ScrollIntoViewTest, LongDistanceSmoothScrollFinishedInThreeSeconds) {
Compositor().BeginFrame(); // update run_state_.
Compositor().BeginFrame(); // Set start_time = now.
Compositor().BeginFrame(0.2);
- ASSERT_NEAR(Window().scrollY(), 864, 1);
+ ASSERT_NEAR(Window().scrollY(), 16971, 1);
// Finish scrolling the container
- Compositor().BeginFrame(2.8);
+ Compositor().BeginFrame(0.5);
ASSERT_EQ(Window().scrollY(), target->OffsetTop());
}
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 8cd487ec503..dc00e7d8401 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
@@ -42,8 +42,7 @@ class ScrollMetricsTest : public SimTest {
void SetUpHtml(const char*);
void Scroll(Element*, const WebGestureDevice);
void UpdateAllLifecyclePhases() {
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
}
};
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state.cc b/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state.cc
index 7a01628b23a..728e964d684 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state.cc
@@ -5,6 +5,8 @@
#include "third_party/blink/renderer/core/page/scrolling/scroll_state.h"
#include <memory>
+
+#include "third_party/blink/renderer/bindings/core/v8/v8_scroll_state_init.h"
#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
@@ -13,11 +15,13 @@
namespace blink {
namespace {
+
Node* NodeForId(DOMNodeId node_id) {
Node* node = DOMNodeIds::NodeForId(node_id);
DCHECK(node);
return node;
}
+
} // namespace
ScrollState* ScrollState::Create(ScrollStateInit* init) {
@@ -36,7 +40,8 @@ ScrollState* ScrollState::Create(ScrollStateInit* init) {
scroll_state_data->is_ending = init->isEnding();
scroll_state_data->from_user_input = init->fromUserInput();
scroll_state_data->is_direct_manipulation = init->isDirectManipulation();
- scroll_state_data->delta_granularity = init->deltaGranularity();
+ scroll_state_data->delta_granularity =
+ static_cast<ScrollGranularity>(init->deltaGranularity());
ScrollState* scroll_state =
MakeGarbageCollected<ScrollState>(std::move(scroll_state_data));
return scroll_state;
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 3c23564f002..040650db2ee 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
@@ -9,7 +9,6 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
#include "third_party/blink/renderer/core/dom/node.h"
-#include "third_party/blink/renderer/core/page/scrolling/scroll_state_init.h"
#include "third_party/blink/renderer/core/scroll/scroll_state_data.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -18,6 +17,8 @@
namespace blink {
+class ScrollStateInit;
+
class CORE_EXPORT ScrollState final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
@@ -45,8 +46,14 @@ class CORE_EXPORT ScrollState final : public ScriptWrappable {
// Positive when scrolling down.
double deltaYHint() const { return data_->delta_y_hint; }
// Indicates the smallest delta the input device can produce. 0 for
- // unquantized inputs.
- double deltaGranularity() const { return data_->delta_granularity; }
+ // unquantized inputs. Deprecated, only exists for script binding
+ // compatibility. Use delta_granularity instead for usage within Blink.
+ double deltaGranularity() const {
+ return static_cast<double>(data_->delta_granularity);
+ }
+ ui::ScrollGranularity delta_granularity() const {
+ return data_->delta_granularity;
+ }
// Positive if moving right.
double velocityX() const { return data_->velocity_x; }
// Positive if moving down.
@@ -87,7 +94,7 @@ class CORE_EXPORT ScrollState final : public ScriptWrappable {
ScrollStateData* Data() const { return data_.get(); }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(node_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state.idl b/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state.idl
index e1a9006bbae..515a5d6a634 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state.idl
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/scroll_state.idl
@@ -5,10 +5,10 @@
// https://docs.google.com/document/d/1VnvAqeWFG9JFZfgG5evBqrLGDZYRE5w6G5jEDORekPY
[
- Constructor(optional ScrollStateInit scrollStateInit),
RuntimeEnabled = ScrollCustomization
] interface ScrollState
{
+ constructor(optional ScrollStateInit scrollStateInit = {});
readonly attribute double deltaX;
readonly attribute double deltaY;
readonly attribute long positionX;
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 8c1069e6ce3..1d5cae38d2b 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(blink::Visitor* visitor) {
+void ScrollStateCallbackV8Impl::Trace(Visitor* visitor) {
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 e9342fe6f43..29273973a58 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(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
virtual void Invoke(ScrollState*) = 0;
@@ -56,7 +56,7 @@ class ScrollStateCallbackV8Impl : public ScrollStateCallback {
: ScrollStateCallback(native_scroll_behavior), callback_(callback) {}
~ScrollStateCallbackV8Impl() override = default;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void Invoke(ScrollState*) override;
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 ddc5aa48a08..6140bf3849a 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
@@ -67,7 +67,7 @@ ScrollingCoordinator::~ScrollingCoordinator() {
DCHECK(!page_);
}
-void ScrollingCoordinator::Trace(blink::Visitor* visitor) {
+void ScrollingCoordinator::Trace(Visitor* visitor) {
visitor->Trace(page_);
visitor->Trace(horizontal_scrollbars_);
visitor->Trace(vertical_scrollbars_);
@@ -76,7 +76,6 @@ void ScrollingCoordinator::Trace(blink::Visitor* visitor) {
void ScrollingCoordinator::NotifyGeometryChanged(LocalFrameView* frame_view) {
frame_view->GetScrollingContext()->SetScrollGestureRegionIsDirty(true);
frame_view->GetScrollingContext()->SetTouchEventTargetRectsAreDirty(true);
- frame_view->GetScrollingContext()->SetShouldScrollOnMainThreadIsDirty(true);
}
ScrollableArea*
@@ -123,11 +122,18 @@ void ScrollingCoordinator::DidChangeScrollbarsHidden(
// See the above function for the case of null scrollable area.
if (auto* scrollable =
ScrollableAreaWithElementIdInAllLocalFrames(element_id)) {
- scrollable->SetScrollbarsHiddenIfOverlay(hidden);
+ // On Mac, we'll only receive these visibility changes if device emulation
+ // is enabled and we're using the Android ScrollbarController. Make sure we
+ // stop listening when device emulation is turned off since we might still
+ // get a lagging message from the compositor before it finds out.
+ if (scrollable->GetPageScrollbarTheme().BlinkControlsOverlayVisibility())
+ scrollable->SetScrollbarsHiddenIfOverlay(hidden);
}
}
void ScrollingCoordinator::UpdateAfterPaint(LocalFrameView* frame_view) {
+ DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
+
LocalFrame* frame = &frame_view->GetFrame();
DCHECK(frame->IsLocalRoot());
@@ -135,14 +141,9 @@ void ScrollingCoordinator::UpdateAfterPaint(LocalFrameView* frame_view) {
frame_view->GetScrollingContext()->ScrollGestureRegionIsDirty();
bool touch_event_rects_dirty =
frame_view->GetScrollingContext()->TouchEventTargetRectsAreDirty();
- bool should_scroll_on_main_thread_dirty =
- frame_view->GetScrollingContext()->ShouldScrollOnMainThreadIsDirty();
- bool frame_scroller_dirty = FrameScrollerIsDirty(frame_view);
- if (!(scroll_gesture_region_dirty || touch_event_rects_dirty ||
- should_scroll_on_main_thread_dirty || frame_scroller_dirty)) {
+ if (!scroll_gesture_region_dirty && !touch_event_rects_dirty)
return;
- }
SCOPED_UMA_AND_UKM_TIMER(frame_view->EnsureUkmAggregator(),
LocalFrameUkmAggregator::kScrollingCoordinator);
@@ -153,24 +154,10 @@ void ScrollingCoordinator::UpdateAfterPaint(LocalFrameView* frame_view) {
frame_view->GetScrollingContext()->SetScrollGestureRegionIsDirty(false);
}
- if (!(touch_event_rects_dirty || should_scroll_on_main_thread_dirty ||
- frame_scroller_dirty)) {
- return;
- }
-
if (touch_event_rects_dirty) {
UpdateTouchEventTargetRectsIfNeeded(frame);
frame_view->GetScrollingContext()->SetTouchEventTargetRectsAreDirty(false);
}
-
- if (should_scroll_on_main_thread_dirty ||
- frame_view->FrameIsScrollableDidChange()) {
- // TODO(pdr): Now that BlinkGenPropertyTrees has launched, we should remove
- // FrameIsScrollableDidChange.
- frame_view->GetScrollingContext()->SetShouldScrollOnMainThreadIsDirty(
- false);
- }
- frame_view->ClearFrameIsScrollableDidChange();
}
template <typename Function>
@@ -253,10 +240,7 @@ void ScrollingCoordinator::RemoveScrollbarLayer(
ScrollbarMap& scrollbars = orientation == kHorizontalScrollbar
? horizontal_scrollbars_
: vertical_scrollbars_;
- if (scoped_refptr<cc::ScrollbarLayerBase> scrollbar_layer =
- scrollbars.Take(scrollable_area)) {
- GraphicsLayer::UnregisterContentsLayer(scrollbar_layer.get());
- }
+ scrollbars.erase(scrollable_area);
}
static scoped_refptr<cc::ScrollbarLayerBase> CreateScrollbarLayer(
@@ -274,7 +258,6 @@ static scoped_refptr<cc::ScrollbarLayerBase> CreateScrollbarLayer(
cc::PaintedScrollbarLayer::Create(std::move(scrollbar_delegate));
}
scrollbar_layer->SetElementId(scrollbar.GetElementId());
- GraphicsLayer::RegisterContentsLayer(scrollbar_layer.get());
return scrollbar_layer;
}
@@ -291,7 +274,6 @@ ScrollingCoordinator::CreateSolidColorScrollbarLayer(
cc_orientation, thumb_thickness, track_start,
is_left_side_vertical_scrollbar);
scrollbar_layer->SetElementId(element_id);
- GraphicsLayer::RegisterContentsLayer(scrollbar_layer.get());
return scrollbar_layer;
}
@@ -363,7 +345,9 @@ void ScrollingCoordinator::ScrollableAreaScrollbarLayerDidChange(
cc::ScrollbarLayerBase* scrollbar_layer =
GetScrollbarLayer(scrollable_area, orientation);
- if (!scrollbar_layer) {
+ if (!scrollbar_layer ||
+ scrollbar_layer->is_left_side_vertical_scrollbar() !=
+ scrollable_area->ShouldPlaceVerticalScrollbarOnLeft()) {
scoped_refptr<cc::ScrollbarLayerBase> new_scrollbar_layer;
if (scrollbar.IsSolidColor()) {
DCHECK(scrollbar.IsOverlayScrollbar());
@@ -396,12 +380,15 @@ void ScrollingCoordinator::ScrollableAreaScrollbarLayerDidChange(
}
}
-bool ScrollingCoordinator::UpdateCompositedScrollOffset(
- ScrollableArea* scrollable_area) {
- cc::Layer* scroll_layer = scrollable_area->LayerForScrolling();
- scroll_layer->SetScrollOffset(
- static_cast<gfx::ScrollOffset>(scrollable_area->ScrollPosition()));
- return true;
+bool ScrollingCoordinator::UpdateCompositorScrollOffset(
+ const LocalFrame& frame,
+ const ScrollableArea& scrollable_area) {
+ auto* paint_artifact_compositor =
+ frame.LocalFrameRoot().View()->GetPaintArtifactCompositor();
+ if (!paint_artifact_compositor)
+ return false;
+ return paint_artifact_compositor->DirectlySetScrollOffset(
+ scrollable_area.GetScrollElementId(), scrollable_area.ScrollPosition());
}
void ScrollingCoordinator::ScrollableAreaScrollLayerDidChange(
@@ -424,14 +411,12 @@ void ScrollingCoordinator::ScrollableAreaScrollLayerDidChange(
IntSize scroll_contents_size =
PhysicalRect(subpixel_accumulation, contents_size).PixelSnappedSize();
- IntSize container_size = scrollable_area->VisibleContentRect().Size();
- cc_layer->SetScrollable(gfx::Size(container_size));
-
// The scrolling contents layer must be at least as large as its clip.
// The visual viewport is special because the size of its scrolling
// content depends on the page scale factor. Its scrollable content is
// the layout viewport which is sized based on the minimum allowed page
// scale so it actually can be smaller than its clip.
+ IntSize container_size = scrollable_area->VisibleContentRect().Size();
scroll_contents_size = scroll_contents_size.ExpandedTo(container_size);
// This call has to go through the GraphicsLayer method to preserve
@@ -471,14 +456,8 @@ void ScrollingCoordinator::UpdateTouchEventTargetRectsIfNeeded(
}
void ScrollingCoordinator::Reset(LocalFrame* frame) {
- for (const auto& scrollbar : horizontal_scrollbars_)
- GraphicsLayer::UnregisterContentsLayer(scrollbar.value.get());
- for (const auto& scrollbar : vertical_scrollbars_)
- GraphicsLayer::UnregisterContentsLayer(scrollbar.value.get());
-
horizontal_scrollbars_.clear();
vertical_scrollbars_.clear();
- frame->View()->ClearFrameIsScrollableDidChange();
}
void ScrollingCoordinator::TouchEventTargetRectsDidChange(LocalFrame* frame) {
@@ -546,12 +525,7 @@ void ScrollingCoordinator::WillCloseAnimationHost(LocalFrameView* view) {
void ScrollingCoordinator::WillBeDestroyed() {
DCHECK(page_);
-
page_ = nullptr;
- for (const auto& scrollbar : horizontal_scrollbars_)
- GraphicsLayer::UnregisterContentsLayer(scrollbar.value.get());
- for (const auto& scrollbar : vertical_scrollbars_)
- GraphicsLayer::UnregisterContentsLayer(scrollbar.value.get());
}
bool ScrollingCoordinator::CoordinatesScrollingForFrameView(
@@ -565,29 +539,6 @@ bool ScrollingCoordinator::CoordinatesScrollingForFrameView(
return layout_view->UsesCompositing();
}
-void ScrollingCoordinator::
- FrameViewHasBackgroundAttachmentFixedObjectsDidChange(
- LocalFrameView* frame_view) {
- DCHECK(IsMainThread());
- DCHECK(frame_view);
-
- if (!CoordinatesScrollingForFrameView(frame_view))
- return;
-
- frame_view->GetScrollingContext()->SetShouldScrollOnMainThreadIsDirty(true);
-}
-
-void ScrollingCoordinator::FrameViewFixedObjectsDidChange(
- LocalFrameView* frame_view) {
- DCHECK(IsMainThread());
- DCHECK(frame_view);
-
- if (!CoordinatesScrollingForFrameView(frame_view))
- return;
-
- frame_view->GetScrollingContext()->SetShouldScrollOnMainThreadIsDirty(true);
-}
-
bool ScrollingCoordinator::IsForMainFrame(
ScrollableArea* scrollable_area) const {
if (!IsA<LocalFrame>(page_->MainFrame()))
@@ -609,21 +560,4 @@ void ScrollingCoordinator::FrameViewRootLayerDidChange(
NotifyGeometryChanged(frame_view);
}
-bool ScrollingCoordinator::FrameScrollerIsDirty(
- LocalFrameView* frame_view) const {
- DCHECK(frame_view);
- // TODO(bokan): This should probably be checking the root scroller in the
- // FrameView, rather than the frame_view.
- if (frame_view->FrameIsScrollableDidChange())
- return true;
-
- if (cc::Layer* scroll_layer =
- frame_view->LayoutViewport()->LayerForScrolling()) {
- return static_cast<gfx::Size>(
- frame_view->LayoutViewport()->ContentsSize()) !=
- scroll_layer->bounds();
- }
- return false;
-}
-
} // namespace blink
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 ebc8693e915..6f82275e0e8 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(blink::Visitor*);
+ void Trace(Visitor*);
// The LocalFrameView argument is optional, nullptr causes the the scrolling
// animation host and timeline to be owned by the ScrollingCoordinator. When
@@ -84,18 +84,10 @@ class CORE_EXPORT ScrollingCoordinator final
// Called when any frame has done its layout or compositing has changed.
void NotifyGeometryChanged(LocalFrameView*);
- // Update non-fast scrollable regions, touch event target rects, main thread
- // scrolling reasons, and whether the visual viewport is user scrollable.
+ // Update non-fast scrollable regions and touch event target rects.
// TODO(pdr): Refactor this out of ScrollingCoordinator.
void UpdateAfterPaint(LocalFrameView*);
- // Should be called whenever the slow repaint objects counter changes between
- // zero and one.
- void FrameViewHasBackgroundAttachmentFixedObjectsDidChange(LocalFrameView*);
-
- // Should be called whenever the set of fixed objects changes.
- void FrameViewFixedObjectsDidChange(LocalFrameView*);
-
// Should be called whenever the root layer for the given frame view changes.
void FrameViewRootLayerDidChange(LocalFrameView*);
@@ -108,9 +100,14 @@ class CORE_EXPORT ScrollingCoordinator final
void WillDestroyScrollableArea(ScrollableArea*);
- // Updates scroll offset, if the appropriate composited layers exist,
- // and if successful, returns true. Otherwise returns false.
- bool UpdateCompositedScrollOffset(ScrollableArea* scrollable_area);
+ // Updates scroll offset in cc scroll tree immediately. We don't wait for
+ // a full document lifecycle update to propagate the scroll offset from blink
+ // paint properties to cc paint properties because cc needs the scroll offset
+ // to apply the impl-side scroll delta correctly at the beginning of the next
+ // frame. The scroll offset in the transform node will still be updated
+ // in normal document lifecycle update instead of here.
+ // Returns whether the update is successful.
+ bool UpdateCompositorScrollOffset(const LocalFrame&, const ScrollableArea&);
// Updates composited layers after changes to scrollable area properties
// like content and container sizes, scrollbar existence, scrollability, etc.
@@ -172,8 +169,6 @@ class CORE_EXPORT ScrollingCoordinator final
ScrollbarOrientation);
void RemoveScrollbarLayer(ScrollableArea*, ScrollbarOrientation);
- bool FrameScrollerIsDirty(LocalFrameView*) const;
-
cc::AnimationHost* animation_host_ = nullptr;
std::unique_ptr<CompositorAnimationTimeline>
programmatic_scroll_animator_timeline_;
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_context.cc b/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_context.cc
deleted file mode 100644
index 98f48f78ef5..00000000000
--- a/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_context.cc
+++ /dev/null
@@ -1,60 +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/core/page/scrolling/scrolling_coordinator_context.h"
-
-namespace blink {
-
-void ScrollingCoordinatorContext::SetAnimationTimeline(
- std::unique_ptr<CompositorAnimationTimeline> timeline) {
- animation_timeline_ = std::move(timeline);
-}
-
-void ScrollingCoordinatorContext::SetAnimationHost(cc::AnimationHost* host) {
- animation_host_ = host;
-}
-
-CompositorAnimationTimeline*
-ScrollingCoordinatorContext::GetCompositorAnimationTimeline() {
- return animation_timeline_.get();
-}
-
-cc::AnimationHost* ScrollingCoordinatorContext::GetCompositorAnimationHost() {
- return animation_host_;
-}
-
-bool ScrollingCoordinatorContext::ScrollGestureRegionIsDirty() const {
- return scroll_gesture_region_is_dirty_;
-}
-
-bool ScrollingCoordinatorContext::TouchEventTargetRectsAreDirty() const {
- return touch_event_target_rects_are_dirty_;
-}
-
-bool ScrollingCoordinatorContext::ShouldScrollOnMainThreadIsDirty() const {
- return should_scroll_on_main_thread_is_dirty_;
-}
-
-bool ScrollingCoordinatorContext::WasScrollable() const {
- return was_scrollable_;
-}
-
-void ScrollingCoordinatorContext::SetScrollGestureRegionIsDirty(bool dirty) {
- scroll_gesture_region_is_dirty_ = dirty;
-}
-
-void ScrollingCoordinatorContext::SetTouchEventTargetRectsAreDirty(bool dirty) {
- touch_event_target_rects_are_dirty_ = dirty;
-}
-
-void ScrollingCoordinatorContext::SetShouldScrollOnMainThreadIsDirty(
- bool dirty) {
- should_scroll_on_main_thread_is_dirty_ = dirty;
-}
-
-void ScrollingCoordinatorContext::SetWasScrollable(bool was_scrollable) {
- was_scrollable_ = was_scrollable;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_context.h b/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_context.h
index df16b878e95..8a90cb0383d 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_context.h
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_context.h
@@ -25,27 +25,33 @@ class CORE_EXPORT ScrollingCoordinatorContext final {
ScrollingCoordinatorContext() {}
virtual ~ScrollingCoordinatorContext() {}
- void SetAnimationTimeline(std::unique_ptr<CompositorAnimationTimeline>);
- void SetAnimationHost(cc::AnimationHost*);
+ void SetAnimationTimeline(
+ std::unique_ptr<CompositorAnimationTimeline> timeline) {
+ animation_timeline_ = std::move(timeline);
+ }
+ void SetAnimationHost(cc::AnimationHost* host) { animation_host_ = host; }
- CompositorAnimationTimeline* GetCompositorAnimationTimeline();
- cc::AnimationHost* GetCompositorAnimationHost();
+ CompositorAnimationTimeline* GetCompositorAnimationTimeline() {
+ return animation_timeline_.get();
+ }
+ cc::AnimationHost* GetCompositorAnimationHost() { return animation_host_; }
// Non-fast scrollable regions need updating by ScrollingCoordinator.
- bool ScrollGestureRegionIsDirty() const;
+ bool ScrollGestureRegionIsDirty() const {
+ return scroll_gesture_region_is_dirty_;
+ }
// Touch event target rects need updating by ScrollingCoordinator.
- bool TouchEventTargetRectsAreDirty() const;
- // ScrollingCoordinator should update whether or not scrolling for this
- // subtree has to happen on the main thread.
- bool ShouldScrollOnMainThreadIsDirty() const;
- bool WasScrollable() const;
+ bool TouchEventTargetRectsAreDirty() const {
+ return touch_event_target_rects_are_dirty_;
+ }
// Only ScrollingCoordinator should ever set |dirty| to |false|.
- void SetScrollGestureRegionIsDirty(bool dirty);
- void SetTouchEventTargetRectsAreDirty(bool dirty);
- void SetShouldScrollOnMainThreadIsDirty(bool dirty);
-
- void SetWasScrollable(bool was_scrollable);
+ void SetScrollGestureRegionIsDirty(bool dirty) {
+ scroll_gesture_region_is_dirty_ = dirty;
+ }
+ void SetTouchEventTargetRectsAreDirty(bool dirty) {
+ touch_event_target_rects_are_dirty_ = dirty;
+ }
private:
std::unique_ptr<CompositorAnimationTimeline> animation_timeline_;
@@ -53,8 +59,6 @@ class CORE_EXPORT ScrollingCoordinatorContext final {
bool scroll_gesture_region_is_dirty_ = false;
bool touch_event_target_rects_are_dirty_ = false;
- bool should_scroll_on_main_thread_is_dirty_ = false;
- bool was_scrollable_ = false;
DISALLOW_COPY_AND_ASSIGN(ScrollingCoordinatorContext);
};
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc b/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc
index 355b3db41d0..aad1e1eb78c 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc
@@ -22,8 +22,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h"
-
#include "build/build_config.h"
#include "cc/layers/scrollbar_layer_base.h"
#include "cc/trees/property_tree.h"
@@ -38,9 +36,9 @@
#include "third_party/blink/public/web/web_view_client.h"
#include "third_party/blink/renderer/core/css/css_style_sheet.h"
#include "third_party/blink/renderer/core/css/style_sheet_list.h"
+#include "third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.h"
#include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
#include "third_party/blink/renderer/core/exported/web_plugin_container_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_view.h"
@@ -52,6 +50,7 @@
#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/page/page.h"
+#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h"
#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_context.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"
@@ -71,17 +70,16 @@
namespace blink {
-class ScrollingCoordinatorTest : public testing::Test,
- public PaintTestConfigurations {
+class ScrollingTest : public testing::Test, public PaintTestConfigurations {
public:
- ScrollingCoordinatorTest() : base_url_("http://www.test.com/") {
+ ScrollingTest() : base_url_("http://www.test.com/") {
helper_.Initialize(nullptr, nullptr, nullptr, &ConfigureSettings);
- GetWebView()->MainFrameWidget()->Resize(IntSize(320, 240));
- GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ GetWebView()->MainFrameWidgetBase()->Resize(IntSize(320, 240));
+ GetWebView()->MainFrameWidgetBase()->UpdateAllLifecyclePhases(
+ DocumentUpdateReason::kTest);
}
- ~ScrollingCoordinatorTest() override {
+ ~ScrollingTest() override {
url_test_helpers::UnregisterAllURLsAndClearMemoryCache();
}
@@ -95,8 +93,8 @@ class ScrollingCoordinatorTest : public testing::Test,
}
void ForceFullCompositingUpdate() {
- GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ GetWebView()->MainFrameWidgetBase()->UpdateAllLifecyclePhases(
+ DocumentUpdateReason::kTest);
}
void RegisterMockedHttpURLLoad(const std::string& file_name) {
@@ -131,12 +129,16 @@ class ScrollingCoordinatorTest : public testing::Test,
GetFrame()->GetDocument()->getElementById(dom_id)->GetScrollableArea());
}
- gfx::ScrollOffset CurrentScrollOffset(
- const cc::ScrollNode* scroll_node) const {
+ gfx::ScrollOffset CurrentScrollOffset(cc::ElementId element_id) const {
return RootCcLayer()
->layer_tree_host()
->property_trees()
- ->scroll_tree.current_scroll_offset(scroll_node->element_id);
+ ->scroll_tree.current_scroll_offset(element_id);
+ }
+
+ gfx::ScrollOffset CurrentScrollOffset(
+ const cc::ScrollNode* scroll_node) const {
+ return CurrentScrollOffset(scroll_node->element_id);
}
const cc::ScrollbarLayerBase* ScrollbarLayerForScrollNode(
@@ -150,6 +152,10 @@ class ScrollingCoordinatorTest : public testing::Test,
return GetFrame()->View()->RootCcLayer();
}
+ cc::LayerTreeHost* LayerTreeHost() const {
+ return helper_.GetLayerTreeHost();
+ }
+
const cc::Layer* FrameScrollingContentsLayer(const LocalFrame& frame) const {
return ScrollingContentsCcLayerByScrollElementId(
RootCcLayer(), frame.View()->LayoutViewport()->GetScrollElementId());
@@ -184,10 +190,10 @@ class ScrollingCoordinatorTest : public testing::Test,
frame_test_helpers::WebViewHelper helper_;
};
-INSTANTIATE_PAINT_TEST_SUITE_P(ScrollingCoordinatorTest);
+INSTANTIATE_PAINT_TEST_SUITE_P(ScrollingTest);
-TEST_P(ScrollingCoordinatorTest, fastScrollingByDefault) {
- GetWebView()->MainFrameWidget()->Resize(WebSize(800, 600));
+TEST_P(ScrollingTest, fastScrollingByDefault) {
+ GetWebView()->MainFrameWidgetBase()->Resize(WebSize(800, 600));
LoadHTML("<div id='spacer' style='height: 1000px'></div>");
ForceFullCompositingUpdate();
@@ -195,8 +201,11 @@ TEST_P(ScrollingCoordinatorTest, fastScrollingByDefault) {
LocalFrameView* frame_view = GetFrame()->View();
Page* page = GetFrame()->GetPage();
ASSERT_TRUE(page->GetScrollingCoordinator());
- ASSERT_TRUE(page->GetScrollingCoordinator()->CoordinatesScrollingForFrameView(
- frame_view));
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ ASSERT_TRUE(
+ page->GetScrollingCoordinator()->CoordinatesScrollingForFrameView(
+ frame_view));
+ }
// Fast scrolling should be enabled by default.
const auto* outer_scroll_node =
@@ -205,10 +214,10 @@ TEST_P(ScrollingCoordinatorTest, fastScrollingByDefault) {
EXPECT_FALSE(outer_scroll_node->main_thread_scrolling_reasons);
ASSERT_EQ(cc::EventListenerProperties::kNone,
- GetWidgetClient()->EventListenerProperties(
+ LayerTreeHost()->event_listener_properties(
cc::EventListenerClass::kTouchStartOrMove));
ASSERT_EQ(cc::EventListenerProperties::kNone,
- GetWidgetClient()->EventListenerProperties(
+ LayerTreeHost()->event_listener_properties(
cc::EventListenerClass::kMouseWheel));
const auto* inner_scroll_node =
@@ -217,7 +226,7 @@ TEST_P(ScrollingCoordinatorTest, fastScrollingByDefault) {
EXPECT_FALSE(inner_scroll_node->main_thread_scrolling_reasons);
}
-TEST_P(ScrollingCoordinatorTest, fastFractionalScrollingDiv) {
+TEST_P(ScrollingTest, fastFractionalScrollingDiv) {
RegisterMockedHttpURLLoad("fractional-scroll-div.html");
NavigateTo(base_url_ + "fractional-scroll-div.html");
ForceFullCompositingUpdate();
@@ -242,7 +251,7 @@ TEST_P(ScrollingCoordinatorTest, fastFractionalScrollingDiv) {
ASSERT_NEAR(1.2f, CurrentScrollOffset(scroll_node).y(), 0.01f);
}
-TEST_P(ScrollingCoordinatorTest, fastScrollingForFixedPosition) {
+TEST_P(ScrollingTest, fastScrollingForFixedPosition) {
RegisterMockedHttpURLLoad("fixed-position.html");
NavigateTo(base_url_ + "fixed-position.html");
ForceFullCompositingUpdate();
@@ -261,7 +270,7 @@ static cc::StickyPositionConstraint GetStickyConstraint(Element* element) {
return *properties->StickyTranslation()->GetStickyConstraint();
}
-TEST_P(ScrollingCoordinatorTest, fastScrollingForStickyPosition) {
+TEST_P(ScrollingTest, fastScrollingForStickyPosition) {
RegisterMockedHttpURLLoad("sticky-position.html");
NavigateTo(base_url_ + "sticky-position.html");
ForceFullCompositingUpdate();
@@ -281,9 +290,9 @@ TEST_P(ScrollingCoordinatorTest, fastScrollingForStickyPosition) {
!constraint.is_anchored_bottom);
EXPECT_EQ(1.f, constraint.top_offset);
EXPECT_EQ(1.f, constraint.left_offset);
- EXPECT_EQ(gfx::Rect(100, 100, 10, 10),
+ EXPECT_EQ(gfx::RectF(100, 100, 10, 10),
constraint.scroll_container_relative_sticky_box_rect);
- EXPECT_EQ(gfx::Rect(100, 100, 200, 200),
+ EXPECT_EQ(gfx::RectF(100, 100, 200, 200),
constraint.scroll_container_relative_containing_block_rect);
}
{
@@ -325,14 +334,14 @@ TEST_P(ScrollingCoordinatorTest, fastScrollingForStickyPosition) {
Element* element = document->getElementById("composited-top");
auto constraint = GetStickyConstraint(element);
EXPECT_TRUE(constraint.is_anchored_top);
- EXPECT_EQ(gfx::Rect(100, 110, 10, 10),
+ EXPECT_EQ(gfx::RectF(100, 110, 10, 10),
constraint.scroll_container_relative_sticky_box_rect);
- EXPECT_EQ(gfx::Rect(100, 100, 200, 200),
+ EXPECT_EQ(gfx::RectF(100, 100, 200, 200),
constraint.scroll_container_relative_containing_block_rect);
}
}
-TEST_P(ScrollingCoordinatorTest, elementPointerEventHandler) {
+TEST_P(ScrollingTest, elementPointerEventHandler) {
LoadHTML(R"HTML(
<div id="pointer" style="width: 100px; height: 100px;"></div>
<script>
@@ -346,21 +355,21 @@ TEST_P(ScrollingCoordinatorTest, elementPointerEventHandler) {
// Pointer event handlers should not generate blocking touch action regions.
cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionNone);
+ TouchAction::kNone);
EXPECT_TRUE(region.IsEmpty());
}
-TEST_P(ScrollingCoordinatorTest, touchEventHandler) {
+TEST_P(ScrollingTest, touchEventHandler) {
RegisterMockedHttpURLLoad("touch-event-handler.html");
NavigateTo(base_url_ + "touch-event-handler.html");
ForceFullCompositingUpdate();
ASSERT_EQ(cc::EventListenerProperties::kBlocking,
- GetWidgetClient()->EventListenerProperties(
+ LayerTreeHost()->event_listener_properties(
cc::EventListenerClass::kTouchStartOrMove));
}
-TEST_P(ScrollingCoordinatorTest, elementBlockingTouchEventHandler) {
+TEST_P(ScrollingTest, elementBlockingTouchEventHandler) {
LoadHTML(R"HTML(
<div id="blocking" style="width: 100px; height: 100px;"></div>
<script>
@@ -372,21 +381,21 @@ TEST_P(ScrollingCoordinatorTest, elementBlockingTouchEventHandler) {
const auto* cc_layer = MainFrameScrollingContentsLayer();
cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionNone);
+ TouchAction::kNone);
EXPECT_EQ(region.bounds(), gfx::Rect(8, 8, 100, 100));
}
-TEST_P(ScrollingCoordinatorTest, touchEventHandlerPassive) {
+TEST_P(ScrollingTest, touchEventHandlerPassive) {
RegisterMockedHttpURLLoad("touch-event-handler-passive.html");
NavigateTo(base_url_ + "touch-event-handler-passive.html");
ForceFullCompositingUpdate();
ASSERT_EQ(cc::EventListenerProperties::kPassive,
- GetWidgetClient()->EventListenerProperties(
+ LayerTreeHost()->event_listener_properties(
cc::EventListenerClass::kTouchStartOrMove));
}
-TEST_P(ScrollingCoordinatorTest, elementTouchEventHandlerPassive) {
+TEST_P(ScrollingTest, elementTouchEventHandlerPassive) {
LoadHTML(R"HTML(
<div id="passive" style="width: 100px; height: 100px;"></div>
<script>
@@ -400,11 +409,11 @@ TEST_P(ScrollingCoordinatorTest, elementTouchEventHandlerPassive) {
// Passive event handlers should not generate blocking touch action regions.
cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionNone);
+ TouchAction::kNone);
EXPECT_TRUE(region.IsEmpty());
}
-TEST_P(ScrollingCoordinatorTest, TouchActionRectsOnImage) {
+TEST_P(ScrollingTest, TouchActionRectsOnImage) {
LoadHTML(R"HTML(
<img id="image" style="width: 100px; height: 100px; touch-action: none;">
)HTML");
@@ -412,51 +421,51 @@ TEST_P(ScrollingCoordinatorTest, TouchActionRectsOnImage) {
const auto* cc_layer = MainFrameScrollingContentsLayer();
cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionNone);
+ TouchAction::kNone);
EXPECT_EQ(region.bounds(), gfx::Rect(8, 8, 100, 100));
}
-TEST_P(ScrollingCoordinatorTest, touchEventHandlerBoth) {
+TEST_P(ScrollingTest, touchEventHandlerBoth) {
RegisterMockedHttpURLLoad("touch-event-handler-both.html");
NavigateTo(base_url_ + "touch-event-handler-both.html");
ForceFullCompositingUpdate();
ASSERT_EQ(cc::EventListenerProperties::kBlockingAndPassive,
- GetWidgetClient()->EventListenerProperties(
+ LayerTreeHost()->event_listener_properties(
cc::EventListenerClass::kTouchStartOrMove));
}
-TEST_P(ScrollingCoordinatorTest, wheelEventHandler) {
+TEST_P(ScrollingTest, wheelEventHandler) {
RegisterMockedHttpURLLoad("wheel-event-handler.html");
NavigateTo(base_url_ + "wheel-event-handler.html");
ForceFullCompositingUpdate();
ASSERT_EQ(cc::EventListenerProperties::kBlocking,
- GetWidgetClient()->EventListenerProperties(
+ LayerTreeHost()->event_listener_properties(
cc::EventListenerClass::kMouseWheel));
}
-TEST_P(ScrollingCoordinatorTest, wheelEventHandlerPassive) {
+TEST_P(ScrollingTest, wheelEventHandlerPassive) {
RegisterMockedHttpURLLoad("wheel-event-handler-passive.html");
NavigateTo(base_url_ + "wheel-event-handler-passive.html");
ForceFullCompositingUpdate();
ASSERT_EQ(cc::EventListenerProperties::kPassive,
- GetWidgetClient()->EventListenerProperties(
+ LayerTreeHost()->event_listener_properties(
cc::EventListenerClass::kMouseWheel));
}
-TEST_P(ScrollingCoordinatorTest, wheelEventHandlerBoth) {
+TEST_P(ScrollingTest, wheelEventHandlerBoth) {
RegisterMockedHttpURLLoad("wheel-event-handler-both.html");
NavigateTo(base_url_ + "wheel-event-handler-both.html");
ForceFullCompositingUpdate();
ASSERT_EQ(cc::EventListenerProperties::kBlockingAndPassive,
- GetWidgetClient()->EventListenerProperties(
+ LayerTreeHost()->event_listener_properties(
cc::EventListenerClass::kMouseWheel));
}
-TEST_P(ScrollingCoordinatorTest, scrollEventHandler) {
+TEST_P(ScrollingTest, scrollEventHandler) {
RegisterMockedHttpURLLoad("scroll-event-handler.html");
NavigateTo(base_url_ + "scroll-event-handler.html");
ForceFullCompositingUpdate();
@@ -464,7 +473,7 @@ TEST_P(ScrollingCoordinatorTest, scrollEventHandler) {
ASSERT_TRUE(GetWidgetClient()->HaveScrollEventHandlers());
}
-TEST_P(ScrollingCoordinatorTest, updateEventHandlersDuringTeardown) {
+TEST_P(ScrollingTest, updateEventHandlersDuringTeardown) {
RegisterMockedHttpURLLoad("scroll-event-handler-window.html");
NavigateTo(base_url_ + "scroll-event-handler-window.html");
ForceFullCompositingUpdate();
@@ -474,7 +483,7 @@ TEST_P(ScrollingCoordinatorTest, updateEventHandlersDuringTeardown) {
GetFrame()->GetDocument()->Shutdown();
}
-TEST_P(ScrollingCoordinatorTest, clippedBodyTest) {
+TEST_P(ScrollingTest, clippedBodyTest) {
RegisterMockedHttpURLLoad("clipped-body.html");
NavigateTo(base_url_ + "clipped-body.html");
ForceFullCompositingUpdate();
@@ -483,19 +492,19 @@ TEST_P(ScrollingCoordinatorTest, clippedBodyTest) {
EXPECT_TRUE(root_scroll_layer->non_fast_scrollable_region().IsEmpty());
}
-TEST_P(ScrollingCoordinatorTest, touchAction) {
+TEST_P(ScrollingTest, touchAction) {
RegisterMockedHttpURLLoad("touch-action.html");
NavigateTo(base_url_ + "touch-action.html");
ForceFullCompositingUpdate();
const auto* cc_layer = ScrollingContentsLayerByDOMElementId("scrollable");
cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionPanX | TouchAction::kTouchActionPanDown);
+ TouchAction::kPanX | TouchAction::kPanDown);
EXPECT_EQ(region.GetRegionComplexity(), 1);
EXPECT_EQ(region.bounds(), gfx::Rect(0, 0, 1000, 1000));
}
-TEST_P(ScrollingCoordinatorTest, touchActionRegions) {
+TEST_P(ScrollingTest, touchActionRegions) {
RegisterMockedHttpURLLoad("touch-action-regions.html");
NavigateTo(base_url_ + "touch-action-regions.html");
ForceFullCompositingUpdate();
@@ -503,22 +512,22 @@ TEST_P(ScrollingCoordinatorTest, touchActionRegions) {
const auto* cc_layer = ScrollingContentsLayerByDOMElementId("scrollable");
cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionPanDown | TouchAction::kTouchActionPanX);
+ TouchAction::kPanDown | TouchAction::kPanX);
EXPECT_EQ(region.GetRegionComplexity(), 1);
EXPECT_EQ(region.bounds(), gfx::Rect(0, 0, 100, 100));
region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionPanDown | TouchAction::kTouchActionPanRight);
+ TouchAction::kPanDown | TouchAction::kPanRight);
EXPECT_EQ(region.GetRegionComplexity(), 1);
EXPECT_EQ(region.bounds(), gfx::Rect(0, 0, 50, 50));
region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionPanDown);
+ TouchAction::kPanDown);
EXPECT_EQ(region.GetRegionComplexity(), 1);
EXPECT_EQ(region.bounds(), gfx::Rect(0, 100, 100, 100));
}
-TEST_P(ScrollingCoordinatorTest, touchActionNesting) {
+TEST_P(ScrollingTest, touchActionNesting) {
LoadHTML(R"HTML(
<style>
#scrollable {
@@ -550,12 +559,12 @@ TEST_P(ScrollingCoordinatorTest, touchActionNesting) {
const auto* cc_layer = ScrollingContentsLayerByDOMElementId("scrollable");
cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionPanX);
+ TouchAction::kPanX);
EXPECT_EQ(region.GetRegionComplexity(), 2);
EXPECT_EQ(region.bounds(), gfx::Rect(5, 5, 150, 100));
}
-TEST_P(ScrollingCoordinatorTest, nestedTouchActionInvalidation) {
+TEST_P(ScrollingTest, nestedTouchActionInvalidation) {
LoadHTML(R"HTML(
<style>
#scrollable {
@@ -587,7 +596,7 @@ TEST_P(ScrollingCoordinatorTest, nestedTouchActionInvalidation) {
const auto* cc_layer = ScrollingContentsLayerByDOMElementId("scrollable");
cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionPanX);
+ TouchAction::kPanX);
EXPECT_EQ(region.GetRegionComplexity(), 2);
EXPECT_EQ(region.bounds(), gfx::Rect(5, 5, 150, 100));
@@ -595,14 +604,14 @@ TEST_P(ScrollingCoordinatorTest, nestedTouchActionInvalidation) {
scrollable->setAttribute("style", "touch-action: none", ASSERT_NO_EXCEPTION);
ForceFullCompositingUpdate();
region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionPanX);
+ TouchAction::kPanX);
EXPECT_TRUE(region.IsEmpty());
}
// Similar to nestedTouchActionInvalidation but tests that an ancestor with
// touch-action: pan-x and a descendant with touch-action: pan-y results in a
// touch-action rect of none for the descendant.
-TEST_P(ScrollingCoordinatorTest, nestedTouchActionChangesUnion) {
+TEST_P(ScrollingTest, nestedTouchActionChangesUnion) {
LoadHTML(R"HTML(
<style>
#ancestor {
@@ -624,10 +633,10 @@ TEST_P(ScrollingCoordinatorTest, nestedTouchActionChangesUnion) {
const auto* cc_layer = MainFrameScrollingContentsLayer();
cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionPanX);
+ TouchAction::kPanX);
EXPECT_EQ(region.bounds(), gfx::Rect(8, 8, 150, 50));
region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionNone);
+ TouchAction::kNone);
EXPECT_TRUE(region.IsEmpty());
Element* ancestor = GetFrame()->GetDocument()->getElementById("ancestor");
@@ -635,18 +644,18 @@ TEST_P(ScrollingCoordinatorTest, nestedTouchActionChangesUnion) {
ForceFullCompositingUpdate();
region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionPanY);
+ TouchAction::kPanY);
EXPECT_EQ(region.bounds(), gfx::Rect(8, 8, 100, 100));
region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionPanX);
+ TouchAction::kPanX);
EXPECT_TRUE(region.IsEmpty());
region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionNone);
+ TouchAction::kNone);
EXPECT_EQ(region.bounds(), gfx::Rect(8, 8, 150, 50));
}
// Box shadow is not hit testable and should not be included in touch action.
-TEST_P(ScrollingCoordinatorTest, touchActionExcludesBoxShadow) {
+TEST_P(ScrollingTest, touchActionExcludesBoxShadow) {
LoadHTML(R"HTML(
<style>
#shadow {
@@ -663,11 +672,11 @@ TEST_P(ScrollingCoordinatorTest, touchActionExcludesBoxShadow) {
const auto* cc_layer = MainFrameScrollingContentsLayer();
cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionNone);
+ TouchAction::kNone);
EXPECT_EQ(region.bounds(), gfx::Rect(8, 8, 100, 100));
}
-TEST_P(ScrollingCoordinatorTest, touchActionOnInline) {
+TEST_P(ScrollingTest, touchActionOnInline) {
RegisterMockedHttpURLLoad("touch-action-on-inline.html");
NavigateTo(base_url_ + "touch-action-on-inline.html");
LoadAhem();
@@ -676,11 +685,24 @@ TEST_P(ScrollingCoordinatorTest, touchActionOnInline) {
const auto* cc_layer = MainFrameScrollingContentsLayer();
cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionNone);
- EXPECT_EQ(region.bounds(), gfx::Rect(8, 8, 80, 50));
+ TouchAction::kNone);
+ EXPECT_EQ(region.bounds(), gfx::Rect(8, 8, 120, 50));
+}
+
+TEST_P(ScrollingTest, touchActionOnText) {
+ RegisterMockedHttpURLLoad("touch-action-on-text.html");
+ NavigateTo(base_url_ + "touch-action-on-text.html");
+ LoadAhem();
+ ForceFullCompositingUpdate();
+
+ const auto* cc_layer = MainFrameScrollingContentsLayer();
+
+ cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
+ TouchAction::kNone);
+ EXPECT_EQ(region.bounds(), gfx::Rect(8, 8, 160, 30));
}
-TEST_P(ScrollingCoordinatorTest, touchActionWithVerticalRLWritingMode) {
+TEST_P(ScrollingTest, touchActionWithVerticalRLWritingMode) {
RegisterMockedHttpURLLoad("touch-action-with-vertical-rl-writing-mode.html");
NavigateTo(base_url_ + "touch-action-with-vertical-rl-writing-mode.html");
LoadAhem();
@@ -689,11 +711,11 @@ TEST_P(ScrollingCoordinatorTest, touchActionWithVerticalRLWritingMode) {
const auto* cc_layer = MainFrameScrollingContentsLayer();
cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionNone);
+ TouchAction::kNone);
EXPECT_EQ(region.bounds(), gfx::Rect(292, 8, 20, 80));
}
-TEST_P(ScrollingCoordinatorTest, touchActionBlockingHandler) {
+TEST_P(ScrollingTest, touchActionBlockingHandler) {
RegisterMockedHttpURLLoad("touch-action-blocking-handler.html");
NavigateTo(base_url_ + "touch-action-blocking-handler.html");
ForceFullCompositingUpdate();
@@ -701,17 +723,17 @@ TEST_P(ScrollingCoordinatorTest, touchActionBlockingHandler) {
const auto* cc_layer = ScrollingContentsLayerByDOMElementId("scrollable");
cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionNone);
+ TouchAction::kNone);
EXPECT_EQ(region.GetRegionComplexity(), 1);
EXPECT_EQ(region.bounds(), gfx::Rect(0, 0, 100, 100));
region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionPanY);
+ TouchAction::kPanY);
EXPECT_EQ(region.GetRegionComplexity(), 2);
EXPECT_EQ(region.bounds(), gfx::Rect(0, 0, 1000, 1000));
}
-TEST_P(ScrollingCoordinatorTest, touchActionOnScrollingElement) {
+TEST_P(ScrollingTest, touchActionOnScrollingElement) {
LoadHTML(R"HTML(
<style>
#scrollable {
@@ -738,7 +760,7 @@ TEST_P(ScrollingCoordinatorTest, touchActionOnScrollingElement) {
ScrollingContentsLayerByDOMElementId("scrollable");
cc::Region region =
scrolling_contents_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionPanY);
+ TouchAction::kPanY);
EXPECT_EQ(region.bounds(), gfx::Rect(0, 0, 50, 150));
const auto* container_layer =
@@ -746,14 +768,14 @@ TEST_P(ScrollingCoordinatorTest, touchActionOnScrollingElement) {
? MainFrameScrollingContentsLayer()
: LayerByDOMElementId("scrollable");
region = container_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionPanY);
+ TouchAction::kPanY);
EXPECT_EQ(region.bounds(),
RuntimeEnabledFeatures::CompositeAfterPaintEnabled()
? gfx::Rect(8, 8, 100, 100)
: gfx::Rect(0, 0, 100, 100));
}
-TEST_P(ScrollingCoordinatorTest, IframeWindowTouchHandler) {
+TEST_P(ScrollingTest, IframeWindowTouchHandler) {
LoadHTML(R"HTML(
<iframe style="width: 275px; height: 250px; will-change: transform">
</iframe>
@@ -775,11 +797,11 @@ TEST_P(ScrollingCoordinatorTest, IframeWindowTouchHandler) {
FrameScrollingContentsLayer(*child_frame->GetFrame());
cc::Region region_child_frame =
child_cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionNone);
+ TouchAction::kNone);
cc::Region region_main_frame =
MainFrameScrollingContentsLayer()
->touch_action_region()
- .GetRegionForTouchAction(TouchAction::kTouchActionNone);
+ .GetRegionForTouchAction(TouchAction::kNone);
EXPECT_TRUE(region_main_frame.bounds().IsEmpty());
EXPECT_FALSE(region_child_frame.bounds().IsEmpty());
// We only check for the content size for verification as the offset is 0x0
@@ -790,7 +812,7 @@ TEST_P(ScrollingCoordinatorTest, IframeWindowTouchHandler) {
EXPECT_EQ(gfx::Rect(child_cc_layer->bounds()), region_child_frame.bounds());
}
-TEST_P(ScrollingCoordinatorTest, WindowTouchEventHandler) {
+TEST_P(ScrollingTest, WindowTouchEventHandler) {
LoadHTML(R"HTML(
<style>
html { width: 200px; height: 200px; }
@@ -809,18 +831,18 @@ TEST_P(ScrollingCoordinatorTest, WindowTouchEventHandler) {
// The touch action region should include the entire frame, even though the
// document is smaller than the frame.
cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionNone);
+ TouchAction::kNone);
EXPECT_EQ(region.bounds(), gfx::Rect(0, 0, 320, 240));
}
namespace {
-class ScrollingCoordinatorMockEventListener final : public NativeEventListener {
+class ScrollingTestMockEventListener final : public NativeEventListener {
public:
void Invoke(ExecutionContext*, Event*) override {}
};
} // namespace
-TEST_P(ScrollingCoordinatorTest, WindowTouchEventHandlerInvalidation) {
+TEST_P(ScrollingTest, WindowTouchEventHandlerInvalidation) {
LoadHTML("");
ForceFullCompositingUpdate();
@@ -828,12 +850,11 @@ TEST_P(ScrollingCoordinatorTest, WindowTouchEventHandlerInvalidation) {
// Initially there are no touch action regions.
auto region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionNone);
+ TouchAction::kNone);
EXPECT_TRUE(region.IsEmpty());
// Adding a blocking window event handler should create a touch action region.
- auto* listener =
- MakeGarbageCollected<ScrollingCoordinatorMockEventListener>();
+ auto* listener = MakeGarbageCollected<ScrollingTestMockEventListener>();
auto* resolved_options =
MakeGarbageCollected<AddEventListenerOptionsResolved>();
resolved_options->setPassive(false);
@@ -841,7 +862,7 @@ TEST_P(ScrollingCoordinatorTest, WindowTouchEventHandlerInvalidation) {
listener, resolved_options);
ForceFullCompositingUpdate();
region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionNone);
+ TouchAction::kNone);
EXPECT_FALSE(region.IsEmpty());
// Removing the window event handler also removes the blocking touch action
@@ -849,12 +870,12 @@ TEST_P(ScrollingCoordinatorTest, WindowTouchEventHandlerInvalidation) {
GetFrame()->DomWindow()->RemoveAllEventListeners();
ForceFullCompositingUpdate();
region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionNone);
+ TouchAction::kNone);
EXPECT_TRUE(region.IsEmpty());
}
// Ensure we don't crash when a plugin becomes a LayoutInline
-TEST_P(ScrollingCoordinatorTest, PluginBecomesLayoutInline) {
+TEST_P(ScrollingTest, PluginBecomesLayoutInline) {
LoadHTML(R"HTML(
<style>
body {
@@ -880,7 +901,7 @@ TEST_P(ScrollingCoordinatorTest, PluginBecomesLayoutInline) {
// Ensure NonFastScrollableRegions are correctly generated for both fixed and
// in-flow plugins that need them.
-TEST_P(ScrollingCoordinatorTest, NonFastScrollableRegionsForPlugins) {
+TEST_P(ScrollingTest, NonFastScrollableRegionsForPlugins) {
LoadHTML(R"HTML(
<style>
body {
@@ -925,14 +946,12 @@ TEST_P(ScrollingCoordinatorTest, NonFastScrollableRegionsForPlugins) {
// The fixed plugin should create a non-fast scrollable region in a fixed
// cc::Layer.
- auto* fixed_layer = LayerByDOMElementId(
- RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ? "pluginfixed"
- : "fixed");
+ auto* fixed_layer = LayerByDOMElementId("fixed");
EXPECT_EQ(fixed_layer->non_fast_scrollable_region().bounds(),
gfx::Rect(0, 0, 200, 200));
}
-TEST_P(ScrollingCoordinatorTest, NonFastScrollableRegionWithBorder) {
+TEST_P(ScrollingTest, NonFastScrollableRegionWithBorder) {
GetWebView()->GetPage()->GetSettings().SetPreferCompositingToLCDTextEnabled(
false);
LoadHTML(R"HTML(
@@ -957,7 +976,7 @@ TEST_P(ScrollingCoordinatorTest, NonFastScrollableRegionWithBorder) {
gfx::Rect(0, 0, 120, 120));
}
-TEST_P(ScrollingCoordinatorTest, overflowScrolling) {
+TEST_P(ScrollingTest, overflowScrolling) {
RegisterMockedHttpURLLoad("overflow-scrolling.html");
NavigateTo(base_url_ + "overflow-scrolling.html");
ForceFullCompositingUpdate();
@@ -972,7 +991,7 @@ TEST_P(ScrollingCoordinatorTest, overflowScrolling) {
EXPECT_TRUE(ScrollbarLayerForScrollNode(scroll_node, cc::VERTICAL));
}
-TEST_P(ScrollingCoordinatorTest, overflowHidden) {
+TEST_P(ScrollingTest, overflowHidden) {
RegisterMockedHttpURLLoad("overflow-hidden.html");
NavigateTo(base_url_ + "overflow-hidden.html");
ForceFullCompositingUpdate();
@@ -989,7 +1008,7 @@ TEST_P(ScrollingCoordinatorTest, overflowHidden) {
EXPECT_TRUE(scroll_node->user_scrollable_vertical);
}
-TEST_P(ScrollingCoordinatorTest, iframeScrolling) {
+TEST_P(ScrollingTest, iframeScrolling) {
RegisterMockedHttpURLLoad("iframe-scrolling.html");
RegisterMockedHttpURLLoad("iframe-scrolling-inner.html");
NavigateTo(base_url_ + "iframe-scrolling.html");
@@ -1019,7 +1038,7 @@ TEST_P(ScrollingCoordinatorTest, iframeScrolling) {
EXPECT_TRUE(ScrollbarLayerForScrollNode(scroll_node, cc::VERTICAL));
}
-TEST_P(ScrollingCoordinatorTest, rtlIframe) {
+TEST_P(ScrollingTest, rtlIframe) {
RegisterMockedHttpURLLoad("rtl-iframe.html");
RegisterMockedHttpURLLoad("rtl-iframe-inner.html");
NavigateTo(base_url_ + "rtl-iframe.html");
@@ -1054,7 +1073,7 @@ TEST_P(ScrollingCoordinatorTest, rtlIframe) {
ASSERT_EQ(expected_scroll_position, CurrentScrollOffset(scroll_node).x());
}
-TEST_P(ScrollingCoordinatorTest, setupScrollbarLayerShouldNotCrash) {
+TEST_P(ScrollingTest, setupScrollbarLayerShouldNotCrash) {
RegisterMockedHttpURLLoad("setup_scrollbar_layer_crash.html");
NavigateTo(base_url_ + "setup_scrollbar_layer_crash.html");
ForceFullCompositingUpdate();
@@ -1063,10 +1082,9 @@ TEST_P(ScrollingCoordinatorTest, setupScrollbarLayerShouldNotCrash) {
}
#if defined(OS_MACOSX) || defined(OS_ANDROID)
-TEST_P(ScrollingCoordinatorTest,
- DISABLED_setupScrollbarLayerShouldSetScrollLayerOpaque)
+TEST_P(ScrollingTest, DISABLED_setupScrollbarLayerShouldSetScrollLayerOpaque)
#else
-TEST_P(ScrollingCoordinatorTest, setupScrollbarLayerShouldSetScrollLayerOpaque)
+TEST_P(ScrollingTest, setupScrollbarLayerShouldSetScrollLayerOpaque)
#endif
{
ScopedMockOverlayScrollbars mock_overlay_scrollbar(false);
@@ -1096,7 +1114,7 @@ TEST_P(ScrollingCoordinatorTest, setupScrollbarLayerShouldSetScrollLayerOpaque)
EXPECT_FALSE(ScrollbarLayerForScrollNode(scroll_node, cc::VERTICAL));
}
-TEST_P(ScrollingCoordinatorTest, NestedIFramesMainThreadScrollingRegion) {
+TEST_P(ScrollingTest, NestedIFramesMainThreadScrollingRegion) {
// This page has an absolute IFRAME. It contains a scrollable child DIV
// that's nested within an intermediate IFRAME.
GetWebView()->GetPage()->GetSettings().SetPreferCompositingToLCDTextEnabled(
@@ -1148,7 +1166,7 @@ TEST_P(ScrollingCoordinatorTest, NestedIFramesMainThreadScrollingRegion) {
// Scroll the frame to ensure the rect is in the correct coordinate space.
GetFrame()->GetDocument()->View()->GetScrollableArea()->SetScrollOffset(
- ScrollOffset(0, 1000), kProgrammaticScroll);
+ ScrollOffset(0, 1000), mojom::blink::ScrollType::kProgrammatic);
ForceFullCompositingUpdate();
@@ -1159,7 +1177,7 @@ TEST_P(ScrollingCoordinatorTest, NestedIFramesMainThreadScrollingRegion) {
// Same as above but test that the rect is correctly calculated into the fixed
// region when the containing iframe is position: fixed.
-TEST_P(ScrollingCoordinatorTest, NestedFixedIFramesMainThreadScrollingRegion) {
+TEST_P(ScrollingTest, NestedFixedIFramesMainThreadScrollingRegion) {
// This page has a fixed IFRAME. It contains a scrollable child DIV that's
// nested within an intermediate IFRAME.
GetWebView()->GetPage()->GetSettings().SetPreferCompositingToLCDTextEnabled(
@@ -1211,7 +1229,7 @@ TEST_P(ScrollingCoordinatorTest, NestedFixedIFramesMainThreadScrollingRegion) {
// Scroll the frame to ensure the rect is in the correct coordinate space.
GetFrame()->GetDocument()->View()->GetScrollableArea()->SetScrollOffset(
- ScrollOffset(0, 1000), kProgrammaticScroll);
+ ScrollOffset(0, 1000), mojom::blink::ScrollType::kProgrammatic);
ForceFullCompositingUpdate();
auto* non_fast_layer = LayerByDOMElementId("iframe");
@@ -1219,7 +1237,7 @@ TEST_P(ScrollingCoordinatorTest, NestedFixedIFramesMainThreadScrollingRegion) {
gfx::Rect(20, 20, 75, 75));
}
-TEST_P(ScrollingCoordinatorTest, IframeCompositedScrollingHideAndShow) {
+TEST_P(ScrollingTest, IframeCompositedScrollingHideAndShow) {
GetWebView()->GetPage()->GetSettings().SetPreferCompositingToLCDTextEnabled(
false);
LoadHTML(R"HTML(
@@ -1263,8 +1281,7 @@ TEST_P(ScrollingCoordinatorTest, IframeCompositedScrollingHideAndShow) {
// Same as above but the main frame is scrollable. This should cause the non
// fast scrollable regions to go on the outer viewport's scroll layer.
-TEST_P(ScrollingCoordinatorTest,
- IframeCompositedScrollingHideAndShowScrollable) {
+TEST_P(ScrollingTest, IframeCompositedScrollingHideAndShowScrollable) {
GetWebView()->GetPage()->GetSettings().SetPreferCompositingToLCDTextEnabled(
false);
LoadHTML(R"HTML(
@@ -1321,7 +1338,7 @@ TEST_P(ScrollingCoordinatorTest,
.IsEmpty());
}
-TEST_P(ScrollingCoordinatorTest, ScrollOffsetClobberedBeforeCompositingUpdate) {
+TEST_P(ScrollingTest, ScrollOffsetClobberedBeforeCompositingUpdate) {
LoadHTML(R"HTML(
<!DOCTYPE html>
<style>
@@ -1354,14 +1371,15 @@ TEST_P(ScrollingCoordinatorTest, ScrollOffsetClobberedBeforeCompositingUpdate) {
scroll_and_scale_set.scrolls.push_back(
{scrollable_area->GetScrollElementId(), compositor_delta, base::nullopt});
RootCcLayer()->layer_tree_host()->ApplyScrollAndScale(&scroll_and_scale_set);
- // The compositor offset is reflected in blink.
- EXPECT_EQ(compositor_delta.y(), scrollable_area->GetScrollOffset().Height());
- // But not in cc scroll node before updating the lifecycle.
- EXPECT_EQ(gfx::ScrollOffset(), CurrentScrollOffset(scroll_node));
+ // The compositor offset is reflected in blink and cc scroll tree.
+ EXPECT_EQ(compositor_delta,
+ gfx::ScrollOffset(scrollable_area->ScrollPosition()));
+ EXPECT_EQ(compositor_delta, CurrentScrollOffset(scroll_node));
// Before updating the lifecycle, set the scroll offset back to what it was
// before the commit from the main thread.
- scrollable_area->SetScrollOffset(ScrollOffset(0, 0), kProgrammaticScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 0),
+ mojom::blink::ScrollType::kProgrammatic);
// Ensure the offset is up-to-date on the cc::Layer even though, as far as
// the main thread is concerned, it was unchanged since the last time we
@@ -1370,7 +1388,7 @@ TEST_P(ScrollingCoordinatorTest, ScrollOffsetClobberedBeforeCompositingUpdate) {
EXPECT_EQ(gfx::ScrollOffset(), CurrentScrollOffset(scroll_node));
}
-TEST_P(ScrollingCoordinatorTest, UpdateVisualViewportScrollLayer) {
+TEST_P(ScrollingTest, UpdateVisualViewportScrollLayer) {
LoadHTML(R"HTML(
<!DOCTYPE html>
<style>
@@ -1396,14 +1414,11 @@ TEST_P(ScrollingCoordinatorTest, UpdateVisualViewportScrollLayer) {
page->GetVisualViewport().SetLocation(FloatPoint(10, 20));
ForceFullCompositingUpdate();
- // TODO(crbug.com/953322): Make this work for CAP.
- if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
- EXPECT_EQ(gfx::ScrollOffset(10, 20),
- CurrentScrollOffset(inner_viewport_scroll_node));
- }
+ EXPECT_EQ(gfx::ScrollOffset(10, 20),
+ CurrentScrollOffset(inner_viewport_scroll_node));
}
-TEST_P(ScrollingCoordinatorTest, UpdateUMAMetricUpdated) {
+TEST_P(ScrollingTest, UpdateUMAMetricUpdated) {
// The metrics are recorced in ScrollingCoordinator::UpdateAfterPaint() which
// is not called in CompositeAfterPaint.
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
@@ -1428,7 +1443,10 @@ TEST_P(ScrollingCoordinatorTest, UpdateUMAMetricUpdated) {
// After an initial compositing update, we should have one scrolling update
// recorded as PreFCP.
+ GetWebView()->MainFrameWidgetBase()->RecordStartOfFrameMetrics();
ForceFullCompositingUpdate();
+ GetWebView()->MainFrameWidgetBase()->RecordEndOfFrameMetrics(
+ base::TimeTicks(), 0);
histogram_tester.ExpectTotalCount("Blink.ScrollingCoordinator.UpdateTime", 1);
histogram_tester.ExpectTotalCount(
"Blink.ScrollingCoordinator.UpdateTime.PreFCP", 1);
@@ -1438,7 +1456,10 @@ TEST_P(ScrollingCoordinatorTest, UpdateUMAMetricUpdated) {
"Blink.ScrollingCoordinator.UpdateTime.AggregatedPreFCP", 0);
// An update with no scrolling changes should not cause a scrolling update.
+ GetWebView()->MainFrameWidgetBase()->RecordStartOfFrameMetrics();
ForceFullCompositingUpdate();
+ GetWebView()->MainFrameWidgetBase()->RecordEndOfFrameMetrics(
+ base::TimeTicks(), 0);
histogram_tester.ExpectTotalCount("Blink.ScrollingCoordinator.UpdateTime", 1);
histogram_tester.ExpectTotalCount(
"Blink.ScrollingCoordinator.UpdateTime.PreFCP", 1);
@@ -1448,34 +1469,41 @@ TEST_P(ScrollingCoordinatorTest, UpdateUMAMetricUpdated) {
"Blink.ScrollingCoordinator.UpdateTime.AggregatedPreFCP", 0);
// A change to background color does not need to cause a scrolling update but,
- // because hit test display items paint, we also cause a scrolling coordinator
+ // because we record hit test data, we also cause a scrolling coordinator
// update when the background paints. Also render some text to get past FCP.
+ // Note that this frame is still considered pre-FCP.
auto* background = GetFrame()->GetDocument()->getElementById("bg");
background->removeAttribute(html_names::kStyleAttr);
- background->SetInnerHTMLFromString("Some Text");
+ background->setInnerHTML("Some Text");
+ GetWebView()->MainFrameWidgetBase()->RecordStartOfFrameMetrics();
ForceFullCompositingUpdate();
+ GetWebView()->MainFrameWidgetBase()->RecordEndOfFrameMetrics(
+ base::TimeTicks(), 0);
histogram_tester.ExpectTotalCount("Blink.ScrollingCoordinator.UpdateTime", 2);
histogram_tester.ExpectTotalCount(
- "Blink.ScrollingCoordinator.UpdateTime.PreFCP", 1);
+ "Blink.ScrollingCoordinator.UpdateTime.PreFCP", 2);
histogram_tester.ExpectTotalCount(
- "Blink.ScrollingCoordinator.UpdateTime.PostFCP", 1);
+ "Blink.ScrollingCoordinator.UpdateTime.PostFCP", 0);
histogram_tester.ExpectTotalCount(
"Blink.ScrollingCoordinator.UpdateTime.AggregatedPreFCP", 1);
// Removing a scrollable area should cause a scrolling update.
auto* scroller = GetFrame()->GetDocument()->getElementById("scroller");
scroller->removeAttribute(html_names::kStyleAttr);
+ GetWebView()->MainFrameWidgetBase()->RecordStartOfFrameMetrics();
ForceFullCompositingUpdate();
+ GetWebView()->MainFrameWidgetBase()->RecordEndOfFrameMetrics(
+ base::TimeTicks(), 0);
histogram_tester.ExpectTotalCount("Blink.ScrollingCoordinator.UpdateTime", 3);
histogram_tester.ExpectTotalCount(
- "Blink.ScrollingCoordinator.UpdateTime.PreFCP", 1);
+ "Blink.ScrollingCoordinator.UpdateTime.PreFCP", 2);
histogram_tester.ExpectTotalCount(
- "Blink.ScrollingCoordinator.UpdateTime.PostFCP", 2);
+ "Blink.ScrollingCoordinator.UpdateTime.PostFCP", 1);
histogram_tester.ExpectTotalCount(
"Blink.ScrollingCoordinator.UpdateTime.AggregatedPreFCP", 1);
}
-TEST_P(ScrollingCoordinatorTest, NonCompositedNonFastScrollableRegion) {
+TEST_P(ScrollingTest, NonCompositedNonFastScrollableRegion) {
GetWebView()->GetPage()->GetSettings().SetPreferCompositingToLCDTextEnabled(
false);
LoadHTML(R"HTML(
@@ -1507,7 +1535,7 @@ TEST_P(ScrollingCoordinatorTest, NonCompositedNonFastScrollableRegion) {
EXPECT_EQ(region.bounds(), gfx::Rect(20, 20, 200, 200));
}
-TEST_P(ScrollingCoordinatorTest, NonCompositedResizerNonFastScrollableRegion) {
+TEST_P(ScrollingTest, NonCompositedResizerNonFastScrollableRegion) {
GetWebView()->GetPage()->GetSettings().SetPreferCompositingToLCDTextEnabled(
false);
LoadHTML(R"HTML(
@@ -1538,7 +1566,7 @@ TEST_P(ScrollingCoordinatorTest, NonCompositedResizerNonFastScrollableRegion) {
EXPECT_EQ(region.bounds(), gfx::Rect(86, 121, 14, 14));
}
-TEST_P(ScrollingCoordinatorTest, CompositedResizerNonFastScrollableRegion) {
+TEST_P(ScrollingTest, CompositedResizerNonFastScrollableRegion) {
LoadHTML(R"HTML(
<style>
#container { will-change: transform; }
@@ -1561,7 +1589,7 @@ TEST_P(ScrollingCoordinatorTest, CompositedResizerNonFastScrollableRegion) {
EXPECT_EQ(region.bounds(), gfx::Rect(66, 66, 14, 14));
}
-TEST_P(ScrollingCoordinatorTest, TouchActionUpdatesOutsideInterestRect) {
+TEST_P(ScrollingTest, TouchActionUpdatesOutsideInterestRect) {
LoadHTML(R"HTML(
<!DOCTYPE html>
<style>
@@ -1598,23 +1626,47 @@ TEST_P(ScrollingCoordinatorTest, TouchActionUpdatesOutsideInterestRect) {
ForceFullCompositingUpdate();
auto* scroller = GetFrame()->GetDocument()->getElementById("scroller");
- scroller->GetScrollableArea()->SetScrollOffset(ScrollOffset(0, 5100),
- kProgrammaticScroll);
+ scroller->GetScrollableArea()->SetScrollOffset(
+ ScrollOffset(0, 5100), mojom::blink::ScrollType::kProgrammatic);
ForceFullCompositingUpdate();
auto* cc_layer = ScrollingContentsLayerByDOMElementId("scroller");
cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionNone);
+ TouchAction::kNone);
EXPECT_EQ(region.bounds(), gfx::Rect(0, 5000, 200, 100));
}
-class ScrollingCoordinatorTestWithAcceleratedContext
- : public ScrollingCoordinatorTest {
- public:
- ScrollingCoordinatorTestWithAcceleratedContext()
- : ScrollingCoordinatorTest() {}
+TEST_P(ScrollingTest, MainThreadScrollAndDeltaFromImplSide) {
+ LoadHTML(R"HTML(
+ <div id='scroller' style='overflow: scroll; width: 100px; height: 100px'>
+ <div style='height: 1000px'></div>
+ </div>
+ )HTML");
+ ForceFullCompositingUpdate();
+
+ auto* scroller = GetFrame()->GetDocument()->getElementById("scroller");
+ auto* scrollable_area = scroller->GetLayoutBox()->GetScrollableArea();
+ auto element_id = scrollable_area->GetScrollElementId();
+
+ EXPECT_EQ(gfx::ScrollOffset(), CurrentScrollOffset(element_id));
+
+ // Simulate a direct scroll update out of document lifecycle update.
+ scroller->scrollTo(0, 200);
+ EXPECT_EQ(FloatPoint(0, 200), scrollable_area->ScrollPosition());
+ EXPECT_EQ(gfx::ScrollOffset(0, 200), CurrentScrollOffset(element_id));
+
+ // Simulate the scroll update with scroll delta from impl-side at the
+ // beginning of BeginMainFrame.
+ cc::ScrollAndScaleSet scroll_and_scale;
+ scroll_and_scale.scrolls.push_back(cc::ScrollAndScaleSet::ScrollUpdateInfo(
+ element_id, gfx::ScrollOffset(0, 10), base::nullopt));
+ RootCcLayer()->layer_tree_host()->ApplyScrollAndScale(&scroll_and_scale);
+ EXPECT_EQ(FloatPoint(0, 210), scrollable_area->ScrollPosition());
+ EXPECT_EQ(gfx::ScrollOffset(0, 210), CurrentScrollOffset(element_id));
+}
+class ScrollingTestWithAcceleratedContext : public ScrollingTest {
protected:
void SetUp() override {
auto factory = [](FakeGLES2Interface* gl, bool* gpu_compositing_disabled)
@@ -1625,21 +1677,21 @@ class ScrollingCoordinatorTestWithAcceleratedContext
};
SharedGpuContext::SetContextProviderFactoryForTesting(
WTF::BindRepeating(factory, WTF::Unretained(&gl_)));
- ScrollingCoordinatorTest::SetUp();
+ ScrollingTest::SetUp();
}
void TearDown() override {
SharedGpuContext::ResetForTesting();
- ScrollingCoordinatorTest::TearDown();
+ ScrollingTest::TearDown();
}
private:
FakeGLES2Interface gl_;
};
-INSTANTIATE_PAINT_TEST_SUITE_P(ScrollingCoordinatorTestWithAcceleratedContext);
+INSTANTIATE_PAINT_TEST_SUITE_P(ScrollingTestWithAcceleratedContext);
-TEST_P(ScrollingCoordinatorTestWithAcceleratedContext, CanvasTouchActionRects) {
+TEST_P(ScrollingTestWithAcceleratedContext, CanvasTouchActionRects) {
LoadHTML(R"HTML(
<canvas id="canvas" style="touch-action: none; will-change: transform;">
<script>
@@ -1655,7 +1707,7 @@ TEST_P(ScrollingCoordinatorTestWithAcceleratedContext, CanvasTouchActionRects) {
const auto* cc_layer = LayerByDOMElementId("canvas");
cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
- TouchAction::kTouchActionNone);
+ TouchAction::kNone);
EXPECT_EQ(region.bounds(), gfx::Rect(0, 0, 400, 400));
}
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc b/chromium/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc
index 7b510bc8739..ed26bffc6ba 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc
@@ -37,7 +37,7 @@ LayoutBox* FindSnapContainer(const LayoutBox& origin_box) {
// containing block chain) scroll container".
Element* document_element = origin_box.GetDocument().documentElement();
LayoutBox* box = origin_box.ContainingBlock();
- while (box && !box->HasOverflowClip() && !box->IsLayoutView() &&
+ while (box && !box->HasOverflowClip() && !IsA<LayoutView>(box) &&
box->GetNode() != document_element) {
box = box->ContainingBlock();
}
@@ -84,8 +84,6 @@ cc::ScrollSnapType GetPhysicalSnapType(const LayoutBox& snap_container) {
// A1 A2 A3 +---+ A3
// | |
// A1 A2
-// The snap container data does not need to be updated because it will be
-// updated at the end of the layout.
void SnapCoordinator::AddSnapContainer(LayoutBox& snap_container) {
snap_containers_.insert(&snap_container);
@@ -107,6 +105,15 @@ void SnapCoordinator::AddSnapContainer(LayoutBox& snap_container) {
}
for (auto* snap_area : snap_areas_to_reassign)
snap_area->SetSnapContainer(&snap_container);
+
+ // The new snap container will not have attached its ScrollableArea yet, so we
+ // cannot invalidate the snap container data at this point. However, the snap
+ // container data is set to needing an update by default, so we only need to
+ // update the flag for the ancestor.
+ if (snap_areas_to_reassign.size()) {
+ ancestor_snap_container->GetScrollableArea()
+ ->SetSnapContainerDataNeedsUpdate(true);
+ }
}
void SnapCoordinator::RemoveSnapContainer(LayoutBox& snap_container) {
@@ -119,8 +126,8 @@ void SnapCoordinator::RemoveSnapContainer(LayoutBox& snap_container) {
// - If it is detached, then we simply clear its snap areas since they will be
// detached as well.
if (ancestor_snap_container) {
- // No need to update the ancestor's snap container data because it will be
- // updated at the end of the layout.
+ ancestor_snap_container->GetScrollableArea()
+ ->SetSnapContainerDataNeedsUpdate(true);
snap_container.ReassignSnapAreas(*ancestor_snap_container);
} else {
DCHECK(!snap_container.Parent());
@@ -141,12 +148,14 @@ void SnapCoordinator::SnapContainerDidChange(LayoutBox& snap_container) {
snap_container.GetDocument().documentElement())
return;
+ PaintLayerScrollableArea* scrollable_area =
+ snap_container.GetScrollableArea();
// Per specification snap positions only affect *scroll containers* [1]. So if
// the layout box is not a scroll container we ignore it here even if it has
// non-none scroll-snap-type. Note that in blink, existence of scrollable area
// directly maps to being a scroll container in the specification. [1]
// https://drafts.csswg.org/css-scroll-snap/#overview
- if (!snap_container.GetScrollableArea()) {
+ if (!scrollable_area) {
DCHECK(!snap_containers_.Contains(&snap_container));
return;
}
@@ -157,9 +166,7 @@ void SnapCoordinator::SnapContainerDidChange(LayoutBox& snap_container) {
// subtree for whom it is the nearest ancestor scroll container per spec [1].
//
// [1] https://drafts.csswg.org/css-scroll-snap/#overview
-
- // TODO(sunyunjia): Only update when the localframe doesn't need layout.
- UpdateSnapContainerData(snap_container);
+ scrollable_area->SetSnapContainerDataNeedsUpdate(true);
}
void SnapCoordinator::SnapAreaDidChange(LayoutBox& snap_area,
@@ -169,7 +176,7 @@ void SnapCoordinator::SnapAreaDidChange(LayoutBox& snap_area,
scroll_snap_align.alignment_block == cc::SnapAlignment::kNone) {
snap_area.SetSnapContainer(nullptr);
if (old_container)
- UpdateSnapContainerData(*old_container);
+ old_container->GetScrollableArea()->SetSnapContainerDataNeedsUpdate(true);
return;
}
@@ -181,18 +188,21 @@ void SnapCoordinator::SnapAreaDidChange(LayoutBox& snap_area,
snap_area.SetSnapContainer(new_container);
// TODO(sunyunjia): consider keep the SnapAreas in a map so it is
// easier to update.
- // TODO(sunyunjia): Only update when the localframe doesn't need layout.
- UpdateSnapContainerData(*new_container);
+ new_container->GetScrollableArea()->SetSnapContainerDataNeedsUpdate(true);
if (old_container && old_container != new_container)
- UpdateSnapContainerData(*old_container);
+ old_container->GetScrollableArea()->SetSnapContainerDataNeedsUpdate(true);
}
}
-void SnapCoordinator::ReSnapAllContainers() {
+void SnapCoordinator::ResnapAllContainersIfNeeded() {
for (const auto* container : snap_containers_) {
+ if (!container->GetScrollableArea()->NeedsResnap())
+ continue;
+
auto* scrollable_area = ScrollableArea::GetForScrolling(container);
ScrollOffset initial_offset = scrollable_area->GetScrollOffset();
scrollable_area->SnapAfterLayout();
+ container->GetScrollableArea()->SetNeedsResnap(false);
// If this is the first time resnapping all containers then this means this
// is the initial layout. We record whenever the initial scroll offset
@@ -209,9 +219,12 @@ void SnapCoordinator::ReSnapAllContainers() {
did_first_resnap_all_containers_ = true;
}
-void SnapCoordinator::UpdateAllSnapContainerData() {
- for (auto* container : snap_containers_)
- UpdateSnapContainerData(*container);
+void SnapCoordinator::UpdateAllSnapContainerDataIfNeeded() {
+ for (auto* container : snap_containers_) {
+ if (container->GetScrollableArea()->SnapContainerDataNeedsUpdate())
+ UpdateSnapContainerData(*container);
+ }
+ SetAnySnapContainerDataNeedsUpdate(false);
}
void SnapCoordinator::UpdateSnapContainerData(LayoutBox& snap_container) {
@@ -219,6 +232,7 @@ void SnapCoordinator::UpdateSnapContainerData(LayoutBox& snap_container) {
ScrollableArea::GetForScrolling(&snap_container);
const auto* old_snap_container_data = scrollable_area->GetSnapContainerData();
auto snap_type = GetPhysicalSnapType(snap_container);
+ scrollable_area->SetSnapContainerDataNeedsUpdate(false);
// Scrollers that don't have any snap areas assigned to them and don't snap
// require no further processing. These are the most common types and thus
@@ -228,7 +242,6 @@ void SnapCoordinator::UpdateSnapContainerData(LayoutBox& snap_container) {
cc::SnapContainerData snap_container_data(snap_type);
- DCHECK(scrollable_area);
DCHECK(snap_containers_.Contains(&snap_container));
// When snap type is 'none' we don't perform any snapping so there is no need
@@ -306,11 +319,12 @@ void SnapCoordinator::UpdateSnapContainerData(LayoutBox& snap_container) {
}
snap_container_data.SetTargetSnapAreaElementIds(new_target_ids);
}
-
if (!old_snap_container_data ||
*old_snap_container_data != snap_container_data) {
snap_container.SetNeedsPaintPropertyUpdate();
scrollable_area->SetSnapContainerData(snap_container_data);
+ // If the snap container data changed then we need to resnap.
+ scrollable_area->SetNeedsResnap(true);
}
}
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 dd73625f2a4..dd591a27b95 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(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
void AddSnapContainer(LayoutBox& snap_container);
void RemoveSnapContainer(LayoutBox& snap_container);
@@ -49,15 +49,23 @@ class CORE_EXPORT SnapCoordinator final
cc::SnapAreaData CalculateSnapAreaData(const LayoutBox& snap_area,
const LayoutBox& snap_container);
- // Called by LocalFrameView::PerformPostLayoutTasks(), so that the snap data
- // are updated whenever a layout happens.
- void UpdateAllSnapContainerData();
- void UpdateSnapContainerData(LayoutBox&);
+ bool AnySnapContainerDataNeedsUpdate() const {
+ return any_snap_container_data_needs_update_;
+ }
+ void SetAnySnapContainerDataNeedsUpdate(bool needs_update) {
+ any_snap_container_data_needs_update_ = needs_update;
+ }
+ // Called by Document::PerformScrollSnappingTasks() whenever a style or layout
+ // change happens. This will update all snap container data that was affected
+ // by the style/layout change.
+ void UpdateAllSnapContainerDataIfNeeded();
// Resnaps all snap containers to their current snap target, or to the
// closest snap point if there is no target (e.g. on the initial layout or if
// the previous snapped target was removed).
- void ReSnapAllContainers();
+ void ResnapAllContainersIfNeeded();
+
+ void UpdateSnapContainerData(LayoutBox&);
#ifndef NDEBUG
void ShowSnapAreaMap();
@@ -69,10 +77,11 @@ class CORE_EXPORT SnapCoordinator final
friend class SnapCoordinatorTest;
HashSet<LayoutBox*> snap_containers_;
+ bool any_snap_container_data_needs_update_ = true;
// Used for reporting to UMA when snapping on the initial layout affects the
// initial scroll position.
- bool did_first_resnap_all_containers_{false};
+ bool did_first_resnap_all_containers_ = false;
DISALLOW_COPY_AND_ASSIGN(SnapCoordinator);
};
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/snap_coordinator_test.cc b/chromium/third_party/blink/renderer/core/page/scrolling/snap_coordinator_test.cc
index e6308c80428..b69b4af61b2 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/snap_coordinator_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/snap_coordinator_test.cc
@@ -68,7 +68,7 @@ class SnapCoordinatorTest : public testing::Test,
Document& GetDocument() { return page_holder_->GetDocument(); }
void SetHTML(const char* html_content) {
- GetDocument().documentElement()->SetInnerHTMLFromString(html_content);
+ GetDocument().documentElement()->setInnerHTML(html_content);
}
Element& SnapContainer() {
@@ -117,8 +117,7 @@ class SnapCoordinatorTest : public testing::Test,
}
void UpdateAllLifecyclePhasesForTest() {
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
GetDocument().View()->RunPostLifecycleSteps();
}
@@ -209,7 +208,7 @@ TEST_F(SnapCoordinatorTest, UpdateStyleForSnapElement) {
// Add a new snap element
Element& container = *GetDocument().getElementById("snap-container");
- container.SetInnerHTMLFromString(R"HTML(
+ container.setInnerHTML(R"HTML(
<div style='scroll-snap-align: start;'>
<div style='width:2000px; height:2000px;'></div>
</div>
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 d26d801edb3..ebdb5b14f8a 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
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.h"
-#include "third_party/blink/public/platform/web_scroll_into_view_params.h"
+#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.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/editing/editor.h"
@@ -33,7 +33,10 @@ bool ParseTextDirective(const String& fragment,
size_t end_pos = 0;
while (end_pos != kNotFound) {
if (fragment.Find(kTextFragmentIdentifierPrefix, start_pos) != start_pos) {
- return false;
+ // If this is not a text directive, continue to the next directive
+ end_pos = fragment.find('&', start_pos + 1);
+ start_pos = end_pos + 1;
+ continue;
}
start_pos += kTextFragmentIdentifierPrefixStringLength;
@@ -46,10 +49,13 @@ bool ParseTextDirective(const String& fragment,
target_text = fragment.Substring(start_pos, end_pos - start_pos);
start_pos = end_pos + 1;
}
- out_selectors->push_back(TextFragmentSelector::Create(target_text));
+
+ TextFragmentSelector selector = TextFragmentSelector::Create(target_text);
+ if (selector.Type() != TextFragmentSelector::kInvalid)
+ out_selectors->push_back(selector);
}
- return true;
+ return out_selectors->size() > 0;
}
bool CheckSecurityRestrictions(LocalFrame& frame,
@@ -64,11 +70,13 @@ bool CheckSecurityRestrictions(LocalFrame& frame,
return false;
}
- // We only allow text fragment anchors on a full navigation.
- // TODO(crbug.com/1023640): Explore allowing scroll to text navigations from
- // same-page bookmarks.
- if (same_document_navigation)
- return false;
+ // Allow same-document navigations only if they are browser initiated, e.g.
+ // same-document bookmarks.
+ if (same_document_navigation) {
+ return frame.Loader()
+ .GetDocumentLoader()
+ ->LastSameDocumentNavigationWasBrowserInitiated();
+ }
// Allow text fragments on same-origin initiated navigations.
if (frame.Loader().GetDocumentLoader()->IsSameOriginNavigation())
@@ -146,6 +154,10 @@ bool TextFragmentAnchor::Invoke() {
frame_->GetDocument()->Markers().RemoveMarkersOfTypes(
DocumentMarker::MarkerTypes::TextFragment());
+ // TODO(bokan): Once BlockHTMLParserOnStyleSheets is launched, there won't be
+ // a way for the user to scroll before we invoke and scroll the anchor. We
+ // should confirm if we can remove tracking this after that point or if we
+ // need a replacement metric.
if (user_scrolled_ && !did_scroll_into_view_)
metrics_->ScrollCancelled();
@@ -171,7 +183,7 @@ bool TextFragmentAnchor::Invoke() {
void TextFragmentAnchor::Installed() {}
-void TextFragmentAnchor::DidScroll(ScrollType type) {
+void TextFragmentAnchor::DidScroll(mojom::blink::ScrollType type) {
if (!IsExplicitScrollType(type))
return;
@@ -187,16 +199,7 @@ void TextFragmentAnchor::PerformPreRafActions() {
}
}
-void TextFragmentAnchor::DidCompleteLoad() {
- if (search_finished_)
- return;
-
- // If there is a pending layout we'll finish the search from Invoke.
- if (!frame_->View()->NeedsLayout())
- DidFinishSearch();
-}
-
-void TextFragmentAnchor::Trace(blink::Visitor* visitor) {
+void TextFragmentAnchor::Trace(Visitor* visitor) {
visitor->Trace(frame_);
visitor->Trace(element_fragment_anchor_);
visitor->Trace(metrics_);
@@ -219,6 +222,31 @@ void TextFragmentAnchor::DidFindMatch(const EphemeralRangeInFlatTree& range) {
return;
}
+ bool needs_style_and_layout = false;
+
+ // Apply :target to the first match
+ if (!did_find_match_) {
+ ApplyTargetToCommonAncestor(range);
+ needs_style_and_layout = true;
+ }
+
+ // Activate any find-in-page activatable display-locks in the ancestor
+ // chain.
+ if (DisplayLockUtilities::ActivateFindInPageMatchRangeIfNeeded(range)) {
+ // Since activating a lock dirties layout, we need to make sure it's clean
+ // before computing the text rect below.
+ needs_style_and_layout = true;
+ // TODO(crbug.com/1041942): It is possible and likely that activation
+ // signal causes script to resize something on the page. This code here
+ // should really yield until the next frame to give script an opportunity
+ // to run.
+ }
+
+ if (needs_style_and_layout) {
+ frame_->GetDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kFindInPage);
+ }
+
metrics_->DidFindMatch(PlainText(range));
did_find_match_ = true;
@@ -239,11 +267,15 @@ void TextFragmentAnchor::DidFindMatch(const EphemeralRangeInFlatTree& range) {
PhysicalRect scrolled_bounding_box =
node.GetLayoutObject()->ScrollRectToVisible(
- bounding_box,
- WebScrollIntoViewParams(ScrollAlignment::kAlignCenterAlways,
- ScrollAlignment::kAlignCenterAlways,
- kProgrammaticScroll));
+ bounding_box, ScrollAlignment::CreateScrollIntoViewParams(
+ ScrollAlignment::CenterAlways(),
+ ScrollAlignment::CenterAlways(),
+ mojom::blink::ScrollType::kProgrammatic));
did_scroll_into_view_ = true;
+
+ if (AXObjectCache* cache = frame_->GetDocument()->ExistingAXObjectCache())
+ cache->HandleScrolledToAnchor(&node);
+
metrics_->DidScroll();
// We scrolled the text into view if the main document scrolled or the text
@@ -309,4 +341,18 @@ bool TextFragmentAnchor::Dismiss() {
return dismissed_;
}
+void TextFragmentAnchor::ApplyTargetToCommonAncestor(
+ const EphemeralRangeInFlatTree& range) {
+ Node* common_node = range.CommonAncestorContainer();
+ while (common_node && common_node->getNodeType() != Node::kElementNode) {
+ common_node = common_node->parentNode();
+ }
+
+ DCHECK(common_node);
+ if (common_node) {
+ auto* target = DynamicTo<Element>(common_node);
+ frame_->GetDocument()->SetCSSTarget(target);
+ }
+}
+
} // 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 27d3da57a9a..a1384171292 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
@@ -49,16 +49,14 @@ class CORE_EXPORT TextFragmentAnchor final : public FragmentAnchor,
void Installed() override;
- void DidScroll(ScrollType type) override;
+ void DidScroll(mojom::blink::ScrollType type) override;
void PerformPreRafActions() override;
- void DidCompleteLoad() override;
-
// Removes text match highlights if any highlight is in view.
bool Dismiss() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// TextFragmentFinder::Client interface
void DidFindMatch(const EphemeralRangeInFlatTree& range) override;
@@ -69,6 +67,8 @@ class CORE_EXPORT TextFragmentAnchor final : public FragmentAnchor,
// element fragment anchor if we didn't find a match.
void DidFinishSearch();
+ void ApplyTargetToCommonAncestor(const EphemeralRangeInFlatTree& range);
+
Vector<TextFragmentFinder> text_fragment_finders_;
Member<LocalFrame> frame_;
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 ad8286e2ef0..fd8b4c20e61 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
@@ -122,7 +122,7 @@ void TextFragmentAnchorMetrics::Dismissed() {
TRACE_EVENT_SCOPE_THREAD);
}
-void TextFragmentAnchorMetrics::Trace(blink::Visitor* visitor) {
+void TextFragmentAnchorMetrics::Trace(Visitor* visitor) {
visitor->Trace(document_);
}
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 31af760438c..64d114dcca2 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
@@ -34,7 +34,7 @@ class CORE_EXPORT TextFragmentAnchorMetrics final
void Dismissed();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
Member<Document> document_;
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 6a68f12dbda..e81c97008b6 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
@@ -35,10 +35,10 @@ class TextFragmentAnchorMetricsTest : public SimTest {
}
void SimulateClick(int x, int y) {
- WebMouseEvent event(
- WebInputEvent::kMouseDown, WebFloatPoint(x, y), WebFloatPoint(x, y),
- WebPointerProperties::Button::kLeft, 0,
- WebInputEvent::Modifiers::kLeftButtonDown, base::TimeTicks::Now());
+ WebMouseEvent event(WebInputEvent::kMouseDown, gfx::PointF(x, y),
+ gfx::PointF(x, y), WebPointerProperties::Button::kLeft,
+ 0, WebInputEvent::Modifiers::kLeftButtonDown,
+ base::TimeTicks::Now());
event.SetFrameScale(1);
GetDocument().GetFrame()->GetEventHandler().HandleMousePressEvent(event);
}
@@ -65,10 +65,10 @@ TEST_F(TextFragmentAnchorMetricsTest, UMAMetricsCollected) {
<p>This is a test page</p>
<p>With ambiguous test content</p>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
histogram_tester_.ExpectTotalCount("TextFragmentAnchor.SelectorCount", 1);
histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.SelectorCount", 2,
1);
@@ -109,10 +109,10 @@ TEST_F(TextFragmentAnchorMetricsTest, NoMatchFound) {
</style>
<p>This is a test page</p>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
histogram_tester_.ExpectTotalCount("TextFragmentAnchor.SelectorCount", 1);
histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.SelectorCount", 1,
1);
@@ -169,10 +169,10 @@ TEST_F(TextFragmentAnchorMetricsTest, MatchFoundNoScroll) {
<!DOCTYPE html>
<p>This is a test page</p>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
histogram_tester_.ExpectTotalCount("TextFragmentAnchor.SelectorCount", 1);
histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.SelectorCount", 1,
1);
@@ -199,6 +199,12 @@ TEST_F(TextFragmentAnchorMetricsTest, MatchFoundNoScroll) {
// Test that the ScrollCancelled metric gets reported when a user scroll cancels
// the scroll into view.
TEST_F(TextFragmentAnchorMetricsTest, 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
+ // before this point.
+ ScopedBlockHTMLParserOnStyleSheetsForTest block_parser(false);
+
SimRequest request("https://example.com/test.html#:~:text=test", "text/html");
SimSubresourceRequest css_request("https://example.com/test.css", "text/css");
LoadURL("https://example.com/test.html#:~:text=test");
@@ -219,15 +225,15 @@ TEST_F(TextFragmentAnchorMetricsTest, ScrollCancelled) {
)HTML");
Compositor().PaintFrame();
- GetDocument().View()->LayoutViewport()->ScrollBy(ScrollOffset(0, 100),
- kUserScroll);
+ GetDocument().View()->LayoutViewport()->ScrollBy(
+ ScrollOffset(0, 100), mojom::blink::ScrollType::kUser);
// Set the target text to visible and change its position to cause a layout
// and invoke the fragment anchor.
css_request.Complete("p { visibility: visible; top: 1001px; }");
+ RunAsyncMatchingTasks();
Compositor().BeginFrame();
- RunAsyncMatchingTasks();
histogram_tester_.ExpectTotalCount("TextFragmentAnchor.SelectorCount", 1);
histogram_tester_.ExpectUniqueSample("TextFragmentAnchor.SelectorCount", 1,
@@ -269,9 +275,10 @@ TEST_F(TextFragmentAnchorMetricsTest, TapToDismiss) {
</style>
<p>This is a test page</p>
)HTML");
- Compositor().BeginFrame();
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
EXPECT_TRUE(GetDocument().IsUseCounted(WebFeature::kTextFragmentAnchor));
EXPECT_TRUE(
GetDocument().IsUseCounted(WebFeature::kTextFragmentAnchorMatchFound));
@@ -298,7 +305,7 @@ TEST_F(TextFragmentAnchorMetricsTest, InvalidFragmentDirective) {
{"#foo:~:bar", kCounted},
{"#:~:utext=foo", kCounted},
{"#:~:text=foo", kUncounted},
- {"#:~:text=foo&invalid", kCounted},
+ {"#:~:text=foo&invalid", kUncounted},
{"#foo:~:text=foo", kUncounted}};
for (auto test_case : test_cases) {
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 aa00bcf0607..c8c87c95319 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
@@ -56,10 +56,10 @@ class TextFragmentAnchorTest : public SimTest {
}
void SimulateClick(int x, int y) {
- WebMouseEvent event(
- WebInputEvent::kMouseDown, WebFloatPoint(x, y), WebFloatPoint(x, y),
- WebPointerProperties::Button::kLeft, 0,
- WebInputEvent::Modifiers::kLeftButtonDown, base::TimeTicks::Now());
+ WebMouseEvent event(WebInputEvent::kMouseDown, gfx::PointF(x, y),
+ gfx::PointF(x, y), WebPointerProperties::Button::kLeft,
+ 0, WebInputEvent::Modifiers::kLeftButtonDown,
+ base::TimeTicks::Now());
event.SetFrameScale(1);
GetDocument().GetFrame()->GetEventHandler().HandleMousePressEvent(event);
}
@@ -68,8 +68,8 @@ class TextFragmentAnchorTest : public SimTest {
WebGestureEvent event(WebInputEvent::kGestureTap,
WebInputEvent::kNoModifiers, base::TimeTicks::Now(),
WebGestureDevice::kTouchscreen);
- event.SetPositionInWidget(FloatPoint(x, y));
- event.SetPositionInScreen(FloatPoint(x, y));
+ event.SetPositionInWidget(gfx::PointF(x, y));
+ event.SetPositionInScreen(gfx::PointF(x, y));
event.SetFrameScale(1);
GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(event);
}
@@ -92,12 +92,13 @@ TEST_F(TextFragmentAnchorTest, BasicSmokeTest) {
</style>
<p id="text">This is a test page</p>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
Element& p = *GetDocument().getElementById("text");
+ EXPECT_EQ(p, *GetDocument().CssTarget());
EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(p)))
<< "<p> Element wasn't scrolled into view, viewport's scroll offset: "
<< LayoutViewport()->GetScrollOffset().ToString();
@@ -122,15 +123,17 @@ TEST_F(TextFragmentAnchorTest, NonMatchingString) {
</style>
<p id="text">This is a test page</p>
)HTML");
- Compositor().BeginFrame();
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
EXPECT_EQ(ScrollOffset(), LayoutViewport()->GetScrollOffset());
// Force a layout
GetDocument().body()->setAttribute(html_names::kStyleAttr, "height: 1300px");
Compositor().BeginFrame();
+ EXPECT_EQ(nullptr, GetDocument().CssTarget());
EXPECT_FALSE(GetDocument().View()->GetFragmentAnchor());
EXPECT_TRUE(GetDocument().Markers().Markers().IsEmpty());
}
@@ -157,12 +160,13 @@ TEST_F(TextFragmentAnchorTest, MultipleMatches) {
<p id="first">This is a test page</p>
<p id="second">This is a test page</p>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
Element& first = *GetDocument().getElementById("first");
+ EXPECT_EQ(first, *GetDocument().CssTarget());
EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(first)))
<< "First <p> wasn't scrolled into view, viewport's scroll offset: "
<< LayoutViewport()->GetScrollOffset().ToString();
@@ -191,12 +195,13 @@ TEST_F(TextFragmentAnchorTest, NestedBlocks) {
</div>
</body>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
Element& match = *GetDocument().getElementById("match");
+ EXPECT_EQ(match, *GetDocument().CssTarget());
EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(match)))
<< "<p> wasn't scrolled into view, viewport's scroll offset: "
<< LayoutViewport()->GetScrollOffset().ToString();
@@ -226,12 +231,13 @@ TEST_F(TextFragmentAnchorTest, MultipleTextFragments) {
<p id="first">This is a test page</p>
<p id="second">This is some more text</p>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
Element& first = *GetDocument().getElementById("first");
+ EXPECT_EQ(first, *GetDocument().CssTarget());
EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(first)))
<< "First <p> wasn't scrolled into view, viewport's scroll offset: "
<< LayoutViewport()->GetScrollOffset().ToString();
@@ -262,12 +268,13 @@ TEST_F(TextFragmentAnchorTest, FirstTextFragmentNotFound) {
<p id="first">This is a page</p>
<p id="second">This is some more text</p>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
Element& second = *GetDocument().getElementById("second");
+ EXPECT_EQ(second, *GetDocument().CssTarget());
EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(second)))
<< "Second <p> wasn't scrolled into view, viewport's scroll offset: "
<< LayoutViewport()->GetScrollOffset().ToString();
@@ -294,12 +301,13 @@ TEST_F(TextFragmentAnchorTest, OnlyFirstTextFragmentFound) {
</style>
<p id="text">This is a test page</p>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
Element& p = *GetDocument().getElementById("text");
+ EXPECT_EQ(p, *GetDocument().CssTarget());
EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(p)))
<< "<p> Element wasn't scrolled into view, viewport's scroll offset: "
<< LayoutViewport()->GetScrollOffset().ToString();
@@ -330,15 +338,17 @@ TEST_F(TextFragmentAnchorTest, MultipleNonMatchingStrings) {
</style>
<p id="text">This is a test page</p>
)HTML");
- Compositor().BeginFrame();
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
EXPECT_EQ(ScrollOffset(), LayoutViewport()->GetScrollOffset());
// Force a layout
GetDocument().body()->setAttribute(html_names::kStyleAttr, "height: 1300px");
Compositor().BeginFrame();
+ EXPECT_EQ(nullptr, GetDocument().CssTarget());
EXPECT_FALSE(GetDocument().View()->GetFragmentAnchor());
EXPECT_TRUE(GetDocument().Markers().Markers().IsEmpty());
}
@@ -361,10 +371,11 @@ TEST_F(TextFragmentAnchorTest, SameElementTextRange) {
</style>
<p id="text">This is a test page</p>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
+ EXPECT_EQ(*GetDocument().getElementById("text"), *GetDocument().CssTarget());
EXPECT_EQ(1u, GetDocument().Markers().Markers().size());
// Expect marker on "This is a test page".
@@ -395,10 +406,11 @@ TEST_F(TextFragmentAnchorTest, NeighboringElementTextRange) {
<p id="text1">This is a test page</p>
<p id="text2">with another paragraph of text</p>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
+ EXPECT_EQ(*GetDocument().body(), *GetDocument().CssTarget());
EXPECT_EQ(2u, GetDocument().Markers().Markers().size());
// Expect marker on "test page"
@@ -439,10 +451,11 @@ TEST_F(TextFragmentAnchorTest, DifferentDepthElementTextRange) {
<p id="text2">with another paragraph of text</p>
</div>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
+ EXPECT_EQ(*GetDocument().body(), *GetDocument().CssTarget());
EXPECT_EQ(2u, GetDocument().Markers().Markers().size());
// Expect marker on "test page"
@@ -480,10 +493,9 @@ TEST_F(TextFragmentAnchorTest, TextRangeEndTextNotFound) {
</style>
<p id="text">This is a test page</p>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ EXPECT_EQ(nullptr, GetDocument().CssTarget());
EXPECT_EQ(0u, GetDocument().Markers().Markers().size());
EXPECT_EQ(ScrollOffset(), LayoutViewport()->GetScrollOffset());
}
@@ -513,10 +525,11 @@ TEST_F(TextFragmentAnchorTest, MultipleTextRanges) {
<p id="text2">with another paragraph of text</p>
</div>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
+ EXPECT_EQ(*GetDocument().body(), *GetDocument().CssTarget());
EXPECT_EQ(3u, GetDocument().Markers().Markers().size());
// Expect marker on "test page"
@@ -553,10 +566,10 @@ TEST_F(TextFragmentAnchorTest, DistantElementTextRange) {
<p id="text">This is a test page</p>
<p>with another paragraph of text</p>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
Element& p = *GetDocument().getElementById("text");
EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(p)))
<< "<p> Element wasn't scrolled into view, viewport's scroll offset: "
@@ -573,10 +586,11 @@ TEST_F(TextFragmentAnchorTest, TextRangeWithContext) {
<!DOCTYPE html>
<p id="text">This is a test page</p>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
+ EXPECT_EQ(*GetDocument().getElementById("text"), *GetDocument().CssTarget());
EXPECT_EQ(1u, GetDocument().Markers().Markers().size());
// Expect marker on "is a test".
@@ -602,6 +616,7 @@ TEST_F(TextFragmentAnchorTest, PrefixNotFound) {
RunAsyncMatchingTasks();
+ EXPECT_EQ(nullptr, GetDocument().CssTarget());
EXPECT_EQ(0u, GetDocument().Markers().Markers().size());
}
@@ -615,10 +630,9 @@ TEST_F(TextFragmentAnchorTest, SuffixNotFound) {
<!DOCTYPE html>
<p id="text">This is a test page</p>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ EXPECT_EQ(nullptr, GetDocument().CssTarget());
EXPECT_EQ(0u, GetDocument().Markers().Markers().size());
}
@@ -642,10 +656,12 @@ TEST_F(TextFragmentAnchorTest, TextRangeWithCrossElementContext) {
<p>A string of text</p>
<p>Footer 2</p>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
+ EXPECT_EQ(*GetDocument().getElementById("expected"),
+ *GetDocument().CssTarget());
EXPECT_EQ(1u, GetDocument().Markers().Markers().size());
// Expect marker on the expected "A string of text".
@@ -684,10 +700,12 @@ TEST_F(TextFragmentAnchorTest, CrossElementAndWhitespaceContext) {
<p>&nbsp;Bad cat</p>
</div>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
+ EXPECT_EQ(*GetDocument().getElementById("expected"),
+ *GetDocument().CssTarget());
EXPECT_EQ(1u, GetDocument().Markers().Markers().size());
// Expect marker on the expected "cat".
@@ -720,10 +738,12 @@ TEST_F(TextFragmentAnchorTest, CrossEmptySiblingAndParentElementContext) {
<p>suffix</p>
<div>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
+ EXPECT_EQ(*GetDocument().getElementById("expected"),
+ *GetDocument().CssTarget());
EXPECT_EQ(1u, GetDocument().Markers().Markers().size());
// Expect marker on "match".
@@ -753,10 +773,10 @@ TEST_F(TextFragmentAnchorTest, DistantElementContext) {
<p id="text">Cats</p>
<p>Suffix</p>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
Element& p = *GetDocument().getElementById("text");
EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(p)))
<< "<p> Element wasn't scrolled into view, viewport's scroll offset: "
@@ -778,9 +798,11 @@ TEST_F(TextFragmentAnchorTest, OneContextTerm) {
<p id="text1">This is a test page</p>
<p id="text2">Not a page with real content</p>
)HTML");
+ RunAsyncMatchingTasks();
+
Compositor().BeginFrame();
- RunAsyncMatchingTasks();
+ EXPECT_EQ(*GetDocument().getElementById("text1"), *GetDocument().CssTarget());
// Expect marker on the first "page"
auto* text1 = To<Text>(GetDocument().getElementById("text1")->firstChild());
@@ -803,6 +825,8 @@ TEST_F(TextFragmentAnchorTest, OneContextTerm) {
TEST_F(TextFragmentAnchorTest, 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",
+ "image/png");
LoadURL("https://example.com/test.html#:~:text=test");
request.Complete(R"HTML(
<!DOCTYPE html>
@@ -818,22 +842,49 @@ TEST_F(TextFragmentAnchorTest, ScrollCancelled) {
</style>
<link rel=stylesheet href=test.css>
<p id="text">This is a test page</p>
+ <img src="test.png">
)HTML");
Compositor().PaintFrame();
- GetDocument().View()->LayoutViewport()->ScrollBy(ScrollOffset(0, 100),
- kUserScroll);
+ if (!RuntimeEnabledFeatures::BlockHTMLParserOnStyleSheetsEnabled()) {
+ GetDocument().View()->LayoutViewport()->ScrollBy(
+ ScrollOffset(0, 100), mojom::blink::ScrollType::kUser);
+ // 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; }");
+ img_request.Complete("");
+ } else {
+ // 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; }");
+ RunPendingTasks();
+ Compositor().BeginFrame();
+ Element& p = *GetDocument().getElementById("text");
- // Set the target text to visible and change its position to cause a layout
- // and invoke the fragment anchor.
- css_request.Complete("p { visibility: visible; top: 1001px; }");
+ // We should have invoked the fragment and scrolled the <p> into view, but
+ // load should not yet be complete due to the image.
+ EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(p)));
+ ASSERT_FALSE(GetDocument().IsLoadCompleted());
+
+ // 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);
+ ASSERT_FALSE(ViewportRect().Contains(BoundingRectInFrame(p)));
+
+ img_request.Complete("");
+ RunPendingTasks();
+ ASSERT_TRUE(GetDocument().IsLoadCompleted());
+ }
- Compositor().BeginFrame();
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
Element& p = *GetDocument().getElementById("text");
EXPECT_FALSE(ViewportRect().Contains(BoundingRectInFrame(p)));
+ EXPECT_EQ(p, *GetDocument().CssTarget());
EXPECT_EQ(1u, GetDocument().Markers().Markers().size());
// Expect marker on "test"
@@ -868,14 +919,15 @@ TEST_F(TextFragmentAnchorTest, DisabledInIframes) {
test
</p>
)HTML");
+ RunAsyncMatchingTasks();
Compositor().BeginFrame();
- RunAsyncMatchingTasks();
Element* iframe = GetDocument().getElementById("iframe");
auto* child_frame =
To<LocalFrame>(To<HTMLFrameOwnerElement>(iframe)->ContentFrame());
+ EXPECT_EQ(nullptr, GetDocument().CssTarget());
EXPECT_EQ(ScrollOffset(),
child_frame->View()->GetScrollableArea()->GetScrollOffset());
}
@@ -918,11 +970,13 @@ TEST_F(TextFragmentAnchorTest, DisabledInWindowOpen) {
RunAsyncMatchingTasks();
+ EXPECT_EQ(nullptr, child_window->document()->CssTarget());
+
LocalFrameView* child_view = child_window->GetFrame()->View();
EXPECT_EQ(ScrollOffset(), child_view->GetScrollableArea()->GetScrollOffset());
}
-// Ensure that the text fragment anchor is only allowed in full (non-same-page)
+// Ensure that the text fragment anchor is not activated by same-document script
// navigations.
TEST_F(TextFragmentAnchorTest, DisabledInSamePageNavigation) {
SimRequest main_request("https://example.com/test.html", "text/html");
@@ -938,9 +992,9 @@ TEST_F(TextFragmentAnchorTest, DisabledInSamePageNavigation) {
test
</p>
)HTML");
+ RunAsyncMatchingTasks();
Compositor().BeginFrame();
- RunAsyncMatchingTasks();
ASSERT_EQ(ScrollOffset(),
GetDocument().View()->GetScrollableArea()->GetScrollOffset());
@@ -949,9 +1003,10 @@ TEST_F(TextFragmentAnchorTest, DisabledInSamePageNavigation) {
ToScriptStateForMainWorld(GetDocument().GetFrame());
ScriptState::Scope entered_context_scope(script_state);
GetDocument().GetFrame()->DomWindow()->location()->setHash(
- script_state->GetIsolate(), "text=test", ASSERT_NO_EXCEPTION);
+ script_state->GetIsolate(), ":~:text=test", ASSERT_NO_EXCEPTION);
RunAsyncMatchingTasks();
+ EXPECT_EQ(nullptr, GetDocument().CssTarget());
EXPECT_EQ(ScrollOffset(), LayoutViewport()->GetScrollOffset());
}
@@ -972,9 +1027,10 @@ TEST_F(TextFragmentAnchorTest, CaseInsensitive) {
</style>
<p id="text">test</p>
)HTML");
- Compositor().BeginFrame();
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
Element& p = *GetDocument().getElementById("text");
EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(p)))
@@ -1000,9 +1056,10 @@ TEST_F(TextFragmentAnchorTest, TargetStaysInView) {
<img src="image.svg">
<p id="text">test</p>
)HTML");
- Compositor().PaintFrame();
RunAsyncMatchingTasks();
+ Compositor().PaintFrame();
+
ScrollOffset first_scroll_offset = LayoutViewport()->GetScrollOffset();
ASSERT_NE(ScrollOffset(), first_scroll_offset);
@@ -1016,8 +1073,8 @@ TEST_F(TextFragmentAnchorTest, TargetStaysInView) {
<rect fill="green" width="200" height="2000"/>
</svg>
)SVG");
- Compositor().BeginFrame();
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
// Ensure the target text is still in view and stayed centered
ASSERT_NE(first_scroll_offset, LayoutViewport()->GetScrollOffset());
@@ -1046,10 +1103,10 @@ TEST_F(TextFragmentAnchorTest, OverlappingTextRanges) {
</style>
<p id="text">This is a test page</p>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
EXPECT_EQ(1u, GetDocument().Markers().Markers().size());
// Expect marker on "This is a test".
@@ -1079,10 +1136,10 @@ TEST_F(TextFragmentAnchorTest, SpaceMatchesNbsp) {
</style>
<p id="text">This is a test&nbsp;page</p>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
Element& p = *GetDocument().getElementById("text");
EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(p)))
@@ -1111,10 +1168,10 @@ TEST_F(TextFragmentAnchorTest, CSSTextTransform) {
</style>
<p id="text">This is a test page</p>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
Element& p = *GetDocument().getElementById("text");
EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(p)))
@@ -1147,9 +1204,10 @@ TEST_F(TextFragmentAnchorTest, NoMatchFoundFallsBackToElementFragment) {
<p>This is a test page</p>
<div id="element">Some text</div>
)HTML");
- Compositor().BeginFrame();
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
// The TextFragmentAnchor needs another frame to invoke the element anchor
Compositor().BeginFrame();
RunAsyncMatchingTasks();
@@ -1158,6 +1216,7 @@ TEST_F(TextFragmentAnchorTest, NoMatchFoundFallsBackToElementFragment) {
Element& p = *GetDocument().getElementById("element");
+ EXPECT_EQ(p, *GetDocument().CssTarget());
EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(p)))
<< "<p> Element wasn't scrolled into view, viewport's scroll offset: "
<< LayoutViewport()->GetScrollOffset().ToString();
@@ -1185,9 +1244,9 @@ TEST_F(TextFragmentAnchorTest, CheckForWordBoundary) {
</style>
<p id="text">This is a test page</p>
)HTML");
- Compositor().BeginFrame();
RunAsyncMatchingTasks();
+ EXPECT_EQ(nullptr, GetDocument().CssTarget());
EXPECT_EQ(ScrollOffset(), LayoutViewport()->GetScrollOffset());
EXPECT_TRUE(GetDocument().Markers().Markers().IsEmpty());
}
@@ -1210,9 +1269,9 @@ TEST_F(TextFragmentAnchorTest, CheckForWordBoundaryWithContext) {
</style>
<p id="text">This is a test page</p>
)HTML");
- Compositor().BeginFrame();
RunAsyncMatchingTasks();
+ EXPECT_EQ(nullptr, GetDocument().CssTarget());
EXPECT_EQ(ScrollOffset(), LayoutViewport()->GetScrollOffset());
EXPECT_TRUE(GetDocument().Markers().Markers().IsEmpty());
}
@@ -1241,11 +1300,13 @@ TEST_F(TextFragmentAnchorTest, CheckForWordBoundaryWithPartialWord) {
<p id="first">This is a test page</p>
<p id="second">This is a tes age</p>
)HTML");
- Compositor().BeginFrame();
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
Element& p = *GetDocument().getElementById("second");
+ EXPECT_EQ(p, *GetDocument().CssTarget());
EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(p)))
<< "Should have scrolled <p> into view but didn't, scroll offset: "
<< LayoutViewport()->GetScrollOffset().ToString();
@@ -1286,9 +1347,10 @@ TEST_F(TextFragmentAnchorTest, DismissTextHighlightWithClick) {
<p id="first">This is a test page</p>
<p id="second">With some more text</p>
)HTML");
- Compositor().BeginFrame();
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
EXPECT_EQ(2u, GetDocument().Markers().Markers().size());
SimulateClick(100, 100);
@@ -1326,9 +1388,10 @@ TEST_F(TextFragmentAnchorTest, DismissTextHighlightWithTap) {
<p id="first">This is a test page</p>
<p id="second">With some more text</p>
)HTML");
- Compositor().BeginFrame();
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
EXPECT_EQ(2u, GetDocument().Markers().Markers().size());
SimulateTap(100, 100);
@@ -1367,9 +1430,9 @@ TEST_F(TextFragmentAnchorTest, DismissTextHighlightOutOfView) {
// Set the target text to visible and change its position to cause a layout
// and invoke the fragment anchor.
css_request.Complete("p { visibility: visible; top: 1001px; }");
+ RunAsyncMatchingTasks();
Compositor().BeginFrame();
- RunAsyncMatchingTasks();
EXPECT_EQ(1u, GetDocument().Markers().Markers().size());
@@ -1401,9 +1464,10 @@ TEST_F(TextFragmentAnchorTest, DismissTextHighlightInView) {
</style>
<p>This is a test page</p>
)HTML");
- Compositor().BeginFrame();
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
EXPECT_EQ(ScrollOffset(), LayoutViewport()->GetScrollOffset());
EXPECT_EQ(1u, GetDocument().Markers().Markers().size());
@@ -1433,10 +1497,10 @@ TEST_F(TextFragmentAnchorTest, FragmentDirectiveDelimiter) {
</style>
<p id="text">This is a test page</p>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
EXPECT_EQ(1u, GetDocument().Markers().Markers().size());
EXPECT_EQ(GetDocument().Url(), "https://example.com/test.html");
@@ -1466,14 +1530,15 @@ TEST_F(TextFragmentAnchorTest, FragmentDirectiveDelimiterWithElementFragment) {
<p id="text">This is a test page</p>
<div id="element">Some text</div>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
EXPECT_EQ(GetDocument().Url(), "https://example.com/test.html#element");
Element& p = *GetDocument().getElementById("text");
+ EXPECT_EQ(p, *GetDocument().CssTarget());
EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(p)))
<< "<p> Element wasn't scrolled into view, viewport's scroll offset: "
<< LayoutViewport()->GetScrollOffset().ToString();
@@ -1502,13 +1567,14 @@ TEST_F(TextFragmentAnchorTest, IdFragmentWithFragmentDirective) {
<p id="element">This is a test page</p>
<div id="element:~:id">Some text</div>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
- Element& div = *GetDocument().getElementById("element");
+ Compositor().BeginFrame();
+
+ Element& p = *GetDocument().getElementById("element");
- EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(div)))
+ EXPECT_EQ(p, *GetDocument().CssTarget());
+ EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(p)))
<< "Should have scrolled <div> into view but didn't, scroll offset: "
<< LayoutViewport()->GetScrollOffset().ToString();
}
@@ -1530,12 +1596,13 @@ TEST_F(TextFragmentAnchorTest, TextDirectiveInSvg) {
</style>
<svg><text id="text" x="0" y="15">This is a test page</text></svg>
)HTML");
- Compositor().BeginFrame();
-
RunAsyncMatchingTasks();
+ Compositor().BeginFrame();
+
Element& text = *GetDocument().getElementById("text");
+ EXPECT_EQ(text, *GetDocument().CssTarget());
EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(text)))
<< "<text> Element wasn't scrolled into view, viewport's scroll offset: "
<< LayoutViewport()->GetScrollOffset().ToString();
@@ -1561,9 +1628,9 @@ TEST_F(TextFragmentAnchorTest, HighlightOnReload) {
<p id="text">This is a test page</p>
)HTML";
request.Complete(html);
+ RunAsyncMatchingTasks();
Compositor().BeginFrame();
- RunAsyncMatchingTasks();
EXPECT_EQ(1u, GetDocument().Markers().Markers().size());
@@ -1580,6 +1647,100 @@ TEST_F(TextFragmentAnchorTest, HighlightOnReload) {
Compositor().BeginFrame();
RunAsyncMatchingTasks();
+ EXPECT_EQ(*GetDocument().getElementById("text"), *GetDocument().CssTarget());
+ EXPECT_EQ(1u, GetDocument().Markers().Markers().size());
+}
+
+// Ensure that we can have text directives combined with non-text directives
+TEST_F(TextFragmentAnchorTest, NonTextDirectives) {
+ SimRequest request(
+ "https://example.com/test.html#:~:text=test&directive&text=more",
+ "text/html");
+ LoadURL("https://example.com/test.html#:~:text=test&directive&text=more");
+ 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">This is some more text</p>
+ )HTML");
+ Compositor().BeginFrame();
+
+ RunAsyncMatchingTasks();
+
+ Element& first = *GetDocument().getElementById("first");
+
+ EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(first)))
+ << "First <p> wasn't scrolled into view, viewport's scroll offset: "
+ << LayoutViewport()->GetScrollOffset().ToString();
+
+ EXPECT_EQ(2u, GetDocument().Markers().Markers().size());
+}
+
+// Test that the text directive applies :target styling
+TEST_F(TextFragmentAnchorTest, CssTarget) {
+ SimRequest main_request("https://example.com/test.html#:~:text=test",
+ "text/html");
+ SimRequest css_request("https://example.com/test.css", "text/css");
+ LoadURL("https://example.com/test.html#:~:text=test");
+ main_request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ p {
+ margin-top: 1000px;
+ }
+ </style>
+ <link rel="stylesheet" href="test.css">
+ <p id="text">test</p>
+ )HTML");
+
+ // With BlockHTMLParserOnStyleSheetsEnabled, the text fragment anchor won't be
+ // invoked until the CSS is loaded. Otherwise, we test the behavior where the
+ // text fragment anchor is invoked before and after the stylesheet is applied.
+ if (!RuntimeEnabledFeatures::BlockHTMLParserOnStyleSheetsEnabled()) {
+ Compositor().PaintFrame();
+ ScrollOffset first_scroll_offset = LayoutViewport()->GetScrollOffset();
+ ASSERT_NE(ScrollOffset(), first_scroll_offset);
+
+ Element& p = *GetDocument().getElementById("text");
+ IntRect first_bounding_rect = BoundingRectInFrame(p);
+ EXPECT_TRUE(ViewportRect().Contains(first_bounding_rect));
+
+ // Load CSS that has target styling that moves the text out of view
+ css_request.Complete(R"CSS(
+ :target {
+ margin-top: 2000px;
+ }
+ )CSS");
+ RunPendingTasks();
+ Compositor().BeginFrame();
+
+ // Ensure the target text is still in view and stayed centered
+ ASSERT_NE(first_scroll_offset, LayoutViewport()->GetScrollOffset());
+ EXPECT_EQ(first_bounding_rect, BoundingRectInFrame(p));
+ } else {
+ css_request.Complete(R"CSS(
+ :target {
+ margin-top: 2000px;
+ }
+ )CSS");
+ RunPendingTasks();
+ Compositor().BeginFrame();
+ }
+
+ Element& p = *GetDocument().getElementById("text");
+ EXPECT_TRUE(ViewportRect().Contains(BoundingRectInFrame(p)));
EXPECT_EQ(1u, GetDocument().Markers().Markers().size());
}
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 f4039a47207..589f375e3a6 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
@@ -148,13 +148,15 @@ EphemeralRangeInFlatTree FindMatchInRangeWithContext(
// No search_text match in remaining range
if (potential_match.IsNull())
return EphemeralRangeInFlatTree();
+
+ search_start = potential_match.EndPosition();
}
+ PositionInFlatTree suffix_start = potential_match.EndPosition();
DCHECK(potential_match.IsNotNull());
- search_start = potential_match.EndPosition();
if (!suffix.IsEmpty()) {
EphemeralRangeInFlatTree suffix_match =
- FindImmediateMatch(suffix, search_start, search_end);
+ FindImmediateMatch(suffix, suffix_start, search_end);
// No suffix match after current potential_match
if (suffix_match.IsNull())
@@ -180,6 +182,9 @@ void TextFragmentFinder::FindMatch(Document& document) {
PositionInFlatTree search_start =
PositionInFlatTree::FirstPositionInNode(document);
+ auto forced_lock_scope = document.GetScopedForceActivatableLocks();
+ document.UpdateStyleAndLayout(DocumentUpdateReason::kFindInPage);
+
EphemeralRangeInFlatTree match =
FindMatchFromPosition(document, search_start);
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector.cc b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector.cc
index 57f61aeaa1d..42c93d9d571 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector.cc
@@ -50,6 +50,11 @@ TextFragmentSelector TextFragmentSelector::Create(String target_text) {
size_t comma_pos = target_text.find(',');
+ // If there are more commas, this is an invalid text fragment selector.
+ size_t next_comma_pos = target_text.find(',', comma_pos + 1);
+ if (next_comma_pos != kNotFound)
+ return TextFragmentSelector(kInvalid);
+
if (comma_pos == kNotFound) {
type = kExact;
start = target_text;
@@ -74,4 +79,6 @@ TextFragmentSelector::TextFragmentSelector(SelectorType type,
const String& suffix)
: type_(type), start_(start), end_(end), prefix_(prefix), suffix_(suffix) {}
+TextFragmentSelector::TextFragmentSelector(SelectorType type) : type_(type) {}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector.h b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector.h
index d0f16a67b87..536cdb59b89 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector.h
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector.h
@@ -17,6 +17,8 @@ class CORE_EXPORT TextFragmentSelector final {
static TextFragmentSelector Create(String target_text);
enum SelectorType {
+ // An invalid text selector.
+ kInvalid,
// An exact selector on the string start_.
kExact,
// A range selector on a text range start_ to end_.
@@ -28,6 +30,7 @@ class CORE_EXPORT TextFragmentSelector final {
const String& end,
const String& prefix,
const String& suffix);
+ TextFragmentSelector(SelectorType type);
~TextFragmentSelector() = default;
SelectorType Type() const { return type_; }
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_test.cc b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_test.cc
new file mode 100644
index 00000000000..3cf54d1a9ea
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/text_fragment_selector_test.cc
@@ -0,0 +1,95 @@
+// 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/page/scrolling/text_fragment_selector.h"
+
+#include <gtest/gtest.h>
+
+namespace blink {
+
+class TextFragmentSelectorTest : public testing::Test {
+ protected:
+ bool Equals(TextFragmentSelector a, TextFragmentSelector b) {
+ return a.Type() == b.Type() && a.Start() == b.Start() &&
+ a.End() == b.End() && a.Prefix() == b.Prefix() &&
+ a.Suffix() == b.Suffix();
+ }
+};
+
+TEST_F(TextFragmentSelectorTest, ExactText) {
+ TextFragmentSelector selector = TextFragmentSelector::Create("test");
+ TextFragmentSelector expected(TextFragmentSelector::kExact, "test", "", "",
+ "");
+ EXPECT_TRUE(Equals(selector, expected));
+}
+
+TEST_F(TextFragmentSelectorTest, ExactTextWithPrefix) {
+ TextFragmentSelector selector = TextFragmentSelector::Create("prefix-,test");
+ TextFragmentSelector expected(TextFragmentSelector::kExact, "test", "",
+ "prefix", "");
+ EXPECT_TRUE(Equals(selector, expected));
+}
+
+TEST_F(TextFragmentSelectorTest, ExactTextWithSuffix) {
+ TextFragmentSelector selector = TextFragmentSelector::Create("test,-suffix");
+ TextFragmentSelector expected(TextFragmentSelector::kExact, "test", "", "",
+ "suffix");
+ EXPECT_TRUE(Equals(selector, expected));
+}
+
+TEST_F(TextFragmentSelectorTest, ExactTextWithContext) {
+ TextFragmentSelector selector =
+ TextFragmentSelector::Create("prefix-,test,-suffix");
+ TextFragmentSelector expected(TextFragmentSelector::kExact, "test", "",
+ "prefix", "suffix");
+ EXPECT_TRUE(Equals(selector, expected));
+}
+
+TEST_F(TextFragmentSelectorTest, TextRange) {
+ TextFragmentSelector selector = TextFragmentSelector::Create("test,page");
+ TextFragmentSelector expected(TextFragmentSelector::kRange, "test", "page",
+ "", "");
+ EXPECT_TRUE(Equals(selector, expected));
+}
+
+TEST_F(TextFragmentSelectorTest, TextRangeWithPrefix) {
+ TextFragmentSelector selector =
+ TextFragmentSelector::Create("prefix-,test,page");
+ TextFragmentSelector expected(TextFragmentSelector::kRange, "test", "page",
+ "prefix", "");
+ EXPECT_TRUE(Equals(selector, expected));
+}
+
+TEST_F(TextFragmentSelectorTest, TextRangeWithSuffix) {
+ TextFragmentSelector selector =
+ TextFragmentSelector::Create("test,page,-suffix");
+ TextFragmentSelector expected(TextFragmentSelector::kRange, "test", "page",
+ "", "suffix");
+ EXPECT_TRUE(Equals(selector, expected));
+}
+
+TEST_F(TextFragmentSelectorTest, TextRangeWithContext) {
+ TextFragmentSelector selector =
+ TextFragmentSelector::Create("prefix-,test,page,-suffix");
+ TextFragmentSelector expected(TextFragmentSelector::kRange, "test", "page",
+ "prefix", "suffix");
+ EXPECT_TRUE(Equals(selector, expected));
+}
+
+TEST_F(TextFragmentSelectorTest, InvalidContext) {
+ TextFragmentSelector selector =
+ TextFragmentSelector::Create("prefix,test,page,suffix");
+ TextFragmentSelector expected(TextFragmentSelector::kInvalid);
+ EXPECT_TRUE(Equals(selector, expected));
+}
+
+TEST_F(TextFragmentSelectorTest, TooManyParameters) {
+ TextFragmentSelector selector = TextFragmentSelector::Create(
+ "prefix-,exact text, that has commas, which are not percent "
+ "encoded,-suffix");
+ TextFragmentSelector expected(TextFragmentSelector::kInvalid);
+ EXPECT_TRUE(Equals(selector, expected));
+}
+
+} // namespace blink
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 7852b2cab20..965191f2609 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(blink::Visitor* visitor) {
+void TopDocumentRootScrollerController::Trace(Visitor* visitor) {
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 917d52f2c08..e44a32a8c60 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(blink::Visitor*);
+ void Trace(Visitor*);
// 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 ecbb10eb338..89a5d9ad278 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(blink::Visitor* visitor) {
+void ViewportScrollCallback::Trace(Visitor* visitor) {
visitor->Trace(browser_controls_);
visitor->Trace(overscroll_controller_);
visitor->Trace(root_frame_viewport_);
@@ -59,8 +59,7 @@ bool ViewportScrollCallback::ScrollBrowserControls(ScrollState& state) {
browser_controls_->ScrollBegin();
FloatSize delta(state.deltaX(), state.deltaY());
- ScrollGranularity granularity =
- ScrollGranularity(static_cast<int>(state.deltaGranularity()));
+ ScrollGranularity granularity = state.delta_granularity();
if (ShouldScrollBrowserControls(delta, granularity)) {
FloatSize remaining_delta = browser_controls_->ScrollBy(delta);
FloatSize consumed = delta - remaining_delta;
@@ -101,8 +100,7 @@ ScrollResult ViewportScrollCallback::PerformNativeScroll(ScrollState& state) {
DCHECK(root_frame_viewport_);
FloatSize delta(state.deltaX(), state.deltaY());
- ScrollGranularity granularity =
- ScrollGranularity(static_cast<int>(state.deltaGranularity()));
+ ScrollGranularity granularity = state.delta_granularity();
ScrollResult result = root_frame_viewport_->UserScroll(
granularity, delta, ScrollableArea::ScrollCallback());
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 6d01df7f7e1..081f04da55d 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
bool ShouldScrollBrowserControls(const ScrollOffset&,
diff --git a/chromium/third_party/blink/renderer/core/page/slot_scoped_traversal_test.cc b/chromium/third_party/blink/renderer/core/page/slot_scoped_traversal_test.cc
index e711cfd709f..465990a5f20 100644
--- a/chromium/third_party/blink/renderer/core/page/slot_scoped_traversal_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/slot_scoped_traversal_test.cc
@@ -52,7 +52,7 @@ void SlotScopedTraversalTest::SetupSampleHTML(const char* main_html,
const char* shadow_html,
unsigned index) {
Element* body = GetDocument().body();
- body->SetInnerHTMLFromString(String::FromUTF8(main_html));
+ body->setInnerHTML(String::FromUTF8(main_html));
if (shadow_html) {
auto* shadow_host = To<Element>(NodeTraversal::ChildAt(*body, index));
AttachOpenShadowRoot(*shadow_host, shadow_html);
@@ -64,7 +64,7 @@ void SlotScopedTraversalTest::AttachOpenShadowRoot(
const char* shadow_inner_html) {
ShadowRoot& shadow_root =
shadow_host.AttachShadowRootInternal(ShadowRootType::kOpen);
- shadow_root.SetInnerHTMLFromString(String::FromUTF8(shadow_inner_html));
+ shadow_root.setInnerHTML(String::FromUTF8(shadow_inner_html));
GetDocument().body()->UpdateDistributionForFlatTreeTraversal();
}
diff --git a/chromium/third_party/blink/renderer/core/page/spatial_navigation.cc b/chromium/third_party/blink/renderer/core/page/spatial_navigation.cc
index 071f9a6a99e..64e1afd4385 100644
--- a/chromium/third_party/blink/renderer/core/page/spatial_navigation.cc
+++ b/chromium/third_party/blink/renderer/core/page/spatial_navigation.cc
@@ -28,6 +28,7 @@
#include "third_party/blink/renderer/core/page/spatial_navigation.h"
+#include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/node_traversal.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
@@ -43,6 +44,7 @@
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/page/frame_tree.h"
#include "third_party/blink/renderer/core/page/page.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/platform/geometry/int_rect.h"
@@ -53,6 +55,8 @@ namespace blink {
// std::numeric_limits<double>::lowest() because, if subtracted, it becomes
// NaN which will make all following arithmetic NaN too (an unusable number).
constexpr double kMinDistance = std::numeric_limits<int>::lowest();
+constexpr double kPriorityClassA = kMinDistance;
+constexpr double kPriorityClassB = kMinDistance / 2;
constexpr int kFudgeFactor = 2;
@@ -307,7 +311,7 @@ bool ScrollInDirection(Node* container, SpatialNavigationDirection direction) {
if (!scroller)
return false;
- scroller->ScrollBy(ScrollOffset(dx, dy), kUserScroll);
+ scroller->ScrollBy(ScrollOffset(dx, dy), mojom::blink::ScrollType::kUser);
return true;
}
@@ -399,16 +403,16 @@ bool CanScrollInDirection(const LocalFrame* frame,
LayoutView* layoutView = frame->ContentLayoutObject();
if (!layoutView)
return false;
- ScrollbarMode vertical_mode;
- ScrollbarMode horizontal_mode;
+ mojom::blink::ScrollbarMode vertical_mode;
+ mojom::blink::ScrollbarMode horizontal_mode;
layoutView->CalculateScrollbarModes(horizontal_mode, vertical_mode);
if ((direction == SpatialNavigationDirection::kLeft ||
direction == SpatialNavigationDirection::kRight) &&
- ScrollbarMode::kAlwaysOff == horizontal_mode)
+ mojom::blink::ScrollbarMode::kAlwaysOff == horizontal_mode)
return false;
if ((direction == SpatialNavigationDirection::kUp ||
direction == SpatialNavigationDirection::kDown) &&
- ScrollbarMode::kAlwaysOff == vertical_mode)
+ mojom::blink::ScrollbarMode::kAlwaysOff == vertical_mode)
return false;
ScrollableArea* scrollable_area = frame->View()->GetScrollableArea();
LayoutSize size(scrollable_area->ContentsSize());
@@ -581,11 +585,29 @@ double Alignment(SpatialNavigationDirection direction,
}
}
+bool BothOnTopmostPaintLayerInStackingContext(
+ const FocusCandidate& current_interest,
+ const FocusCandidate& candidate) {
+ if (!current_interest.visible_node)
+ return false;
+
+ const LayoutObject* origin = current_interest.visible_node->GetLayoutObject();
+ const PaintLayer* focused_layer = origin->PaintingLayer();
+ if (!focused_layer || focused_layer->IsRootLayer())
+ return false;
+
+ const LayoutObject* next = candidate.visible_node->GetLayoutObject();
+ const PaintLayer* candidate_layer = next->PaintingLayer();
+ if (focused_layer != candidate_layer)
+ return false;
+
+ return !candidate_layer->HasVisibleDescendant();
+}
+
double ComputeDistanceDataForNode(SpatialNavigationDirection direction,
const FocusCandidate& current_interest,
const FocusCandidate& candidate) {
double distance = 0.0;
- double overlap = 0.0;
PhysicalRect node_rect = candidate.rect_in_root_frame;
PhysicalRect current_rect = current_interest.rect_in_root_frame;
if (node_rect.Contains(current_rect)) {
@@ -596,9 +618,10 @@ double ComputeDistanceDataForNode(SpatialNavigationDirection direction,
}
if (current_rect.Contains(node_rect)) {
- // We give priority to "insiders", candidates that are completely inside the
- // current focus rect, by giving them a negative, < 0, distance number.
- distance = kMinDistance;
+ // We give highest priority to "insiders", candidates that are completely
+ // inside the current focus rect, by giving them a negative, < 0, distance
+ // number.
+ distance = kPriorityClassA;
// For insiders we cannot meassure the distance from the outer box. Instead,
// we meassure distance _from_ the focused container's rect's "opposite
@@ -611,10 +634,11 @@ double ComputeDistanceDataForNode(SpatialNavigationDirection direction,
// "outsider".
} else if (!IsRectInDirection(direction, current_rect, node_rect)) {
return kMaxDistance;
- } else {
- PhysicalRect intersection_rect = Intersection(current_rect, node_rect);
- overlap =
- (intersection_rect.Width() * intersection_rect.Height()).ToDouble();
+ } else if (BothOnTopmostPaintLayerInStackingContext(current_interest,
+ candidate)) {
+ // Prioritize "popup candidates" over other candidates by giving them a
+ // negative, < 0, distance number.
+ distance = kPriorityClassB;
}
LayoutPoint exit_point;
@@ -664,10 +688,11 @@ double ComputeDistanceDataForNode(SpatialNavigationDirection direction,
return kMaxDistance;
}
- // Distance calculation is based on https://drafts.csswg.org/css-nav-1/.
- return distance + navigation_axis_distance -
- Alignment(direction, current_rect, node_rect) +
- weighted_orthogonal_axis_distance - sqrt(overlap);
+ // We try to formalize this distance calculation at
+ // https://drafts.csswg.org/css-nav-1/.
+ distance += weighted_orthogonal_axis_distance.ToDouble() +
+ navigation_axis_distance.ToDouble();
+ return distance - Alignment(direction, current_rect, node_rect);
}
// Returns a thin rectangle that represents one of |box|'s edges.
@@ -718,7 +743,7 @@ PhysicalRect StartEdgeForAreaElement(const HTMLAreaElement& area,
}
HTMLFrameOwnerElement* FrameOwnerElement(const FocusCandidate& candidate) {
- return DynamicTo<HTMLFrameOwnerElement>(candidate.visible_node.Get());
+ return DynamicTo<HTMLFrameOwnerElement>(candidate.visible_node);
}
// The visual viewport's rect (given in the root frame's coordinate space).
diff --git a/chromium/third_party/blink/renderer/core/page/spatial_navigation.h b/chromium/third_party/blink/renderer/core/page/spatial_navigation.h
index add9c11515a..9c9690212b5 100644
--- a/chromium/third_party/blink/renderer/core/page/spatial_navigation.h
+++ b/chromium/third_party/blink/renderer/core/page/spatial_navigation.h
@@ -21,7 +21,6 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_SPATIAL_NAVIGATION_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_SPATIAL_NAVIGATION_H_
-#include "third_party/blink/public/platform/web_focus_type.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/layout/geometry/physical_rect.h"
@@ -58,8 +57,8 @@ struct FocusCandidate {
// areas of imagemaps, where visibleNode would represent the image element and
// focusableNode would represent the area element. In all other cases,
// visibleNode and focusableNode are one and the same.
- Member<Node> visible_node;
- Member<Node> focusable_node;
+ Node* visible_node;
+ Node* focusable_node;
PhysicalRect rect_in_root_frame;
bool is_offscreen;
};
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 165b4f180a2..0db2f04a01d 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
@@ -5,7 +5,8 @@
#include "third_party/blink/renderer/core/page/spatial_navigation_controller.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
-#include "third_party/blink/public/platform/web_scroll_into_view_params.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
+#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink.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/dom/element_traversal.h"
@@ -69,6 +70,24 @@ void ClearFocusInExitedFrames(LocalFrame* old_frame,
}
}
+bool IsSkippableCandidate(const Element* element) {
+ // SpatNav tries to ignore certain, inconvenient focus candidates.
+ // If an element is recognized as focusable by
+ // SupportsSpatialNavigationFocus() but has one or several focusable
+ // descendant(s), then we might ignore it in favor for its focusable
+ // descendant(s).
+
+ if (element->GetIntegralAttribute(html_names::kTabindexAttr, -1) >= 0) {
+ // non-negative tabindex was set explicitly.
+ return false;
+ }
+
+ if (IsRootEditableElement(*element))
+ return false;
+
+ return true;
+}
+
// Determines whether the given candidate is closer to the current interested
// node (in the given direction) than the current best. If so, it'll replace
// the current best.
@@ -76,7 +95,9 @@ static void ConsiderForBestCandidate(SpatialNavigationDirection direction,
const FocusCandidate& current_interest,
const FocusCandidate& candidate,
FocusCandidate* best_candidate,
- double* best_distance) {
+ double& best_distance,
+ FocusCandidate* previous_best_candidate,
+ double& previous_best_distance) {
DCHECK(candidate.visible_node->IsElementNode());
DCHECK(candidate.visible_node->GetLayoutObject());
@@ -96,9 +117,26 @@ static void ConsiderForBestCandidate(SpatialNavigationDirection direction,
if (distance == kMaxDistance)
return;
- if (distance < *best_distance && IsUnobscured(candidate)) {
+ Element* candidate_element = To<Element>(candidate.visible_node);
+ Element* best_candidate_element = To<Element>(best_candidate->visible_node);
+
+ if (candidate_element->IsDescendantOf(best_candidate_element) &&
+ IsSkippableCandidate(best_candidate_element) &&
+ best_candidate->rect_in_root_frame.Contains(
+ candidate.rect_in_root_frame)) {
+ // Revert to previous best_candidate because current best_candidate is
+ // a skippable candidate.
+ *best_candidate = *previous_best_candidate;
+ best_distance = previous_best_distance;
+
+ previous_best_distance = kMaxDistance;
+ }
+
+ if (distance < best_distance && IsUnobscured(candidate)) {
+ *previous_best_candidate = *best_candidate;
+ previous_best_distance = best_distance;
*best_candidate = candidate;
- *best_distance = distance;
+ best_distance = distance;
}
}
@@ -182,9 +220,9 @@ bool SpatialNavigationController::HandleEnterKeyboardEvent(
// convert the Enter key into click on down and press (and up) events.
if (RuntimeEnabledFeatures::FocuslessSpatialNavigationEnabled() &&
enter_key_down_seen_ && enter_key_press_seen_) {
- interest_element->focus(FocusParams(SelectionBehaviorOnFocus::kReset,
- kWebFocusTypeSpatialNavigation,
- nullptr));
+ interest_element->focus(
+ FocusParams(SelectionBehaviorOnFocus::kReset,
+ mojom::blink::FocusType::kSpatialNavigation, nullptr));
// We need enter to activate links, etc. The click should be after the
// focus in case the site transfers focus upon clicking.
interest_element->DispatchSimulatedClick(event, kSendMouseUpDownEvents);
@@ -259,7 +297,7 @@ void SpatialNavigationController::DidDetachFrameView(
}
}
-void SpatialNavigationController::Trace(blink::Visitor* visitor) {
+void SpatialNavigationController::Trace(Visitor* visitor) {
visitor->Trace(interest_element_);
visitor->Trace(page_);
}
@@ -272,7 +310,10 @@ bool SpatialNavigationController::Advance(
if (!interest_node)
return false;
- interest_node->GetDocument().UpdateStyleAndLayout();
+ interest_node->GetDocument()
+ .View()
+ ->UpdateLifecycleToCompositingCleanPlusScrolling(
+ DocumentUpdateReason::kSpatialNavigation);
Node* container = ScrollableAreaOrDocumentOf(interest_node);
@@ -310,7 +351,7 @@ bool SpatialNavigationController::Advance(
// Currently this will fail if we're going from an inner document to a
// sub-scroller in a parent document.
if (auto* document = DynamicTo<Document>(container))
- document->UpdateStyleAndLayout();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kSpatialNavigation);
}
return false;
@@ -328,7 +369,8 @@ FocusCandidate SpatialNavigationController::FindNextCandidateInContainer(
current_interest.focusable_node = interest_child_in_container;
current_interest.visible_node = interest_child_in_container;
- FocusCandidate best_candidate;
+ FocusCandidate best_candidate, previous_best_candidate;
+ double previous_best_distance = kMaxDistance;
double best_distance = kMaxDistance;
for (; element;
element =
@@ -349,7 +391,8 @@ FocusCandidate SpatialNavigationController::FindNextCandidateInContainer(
continue;
ConsiderForBestCandidate(direction, current_interest, candidate,
- &best_candidate, &best_distance);
+ &best_candidate, best_distance,
+ &previous_best_candidate, previous_best_distance);
}
return best_candidate;
@@ -373,7 +416,7 @@ bool SpatialNavigationController::AdvanceWithinContainer(
return ScrollInDirection(&container, direction);
}
- auto* element = To<Element>(candidate.focusable_node.Get());
+ auto* element = To<Element>(candidate.focusable_node);
DCHECK(element);
MoveInterestTo(element);
return true;
@@ -441,7 +484,8 @@ void SpatialNavigationController::MoveInterestTo(Node* next_node) {
DCHECK(layout_object);
layout_object->ScrollRectToVisible(
- element->BoundingBoxForScrollIntoView(), WebScrollIntoViewParams());
+ element->BoundingBoxForScrollIntoView(),
+ ScrollAlignment::CreateScrollIntoViewParams());
}
// Despite the name, we actually do move focus in "focusless" mode if we're
@@ -469,8 +513,13 @@ void SpatialNavigationController::MoveInterestTo(Node* next_node) {
ClearFocusInExitedFrames(old_frame, next_node->GetDocument().GetFrame());
element->focus(FocusParams(SelectionBehaviorOnFocus::kReset,
- kWebFocusTypeSpatialNavigation, nullptr));
- DispatchMouseMoveAt(element);
+ mojom::blink::FocusType::kSpatialNavigation,
+ nullptr));
+ // The focused element could be changed due to elm.focus() on focus handlers.
+ // So we need to update the current focused element before DispatchMouseMove.
+ // This is tested in snav-applies-hover-with-focused.html.
+ Element* current_interest = GetInterestedElement();
+ DispatchMouseMoveAt(current_interest);
}
void SpatialNavigationController::DispatchMouseMoveAt(Element* element) {
@@ -564,9 +613,10 @@ void SpatialNavigationController::FocusedNodeChanged(Document* document) {
void SpatialNavigationController::FullscreenStateChanged(Element* element) {
if (!RuntimeEnabledFeatures::FocuslessSpatialNavigationEnabled())
return;
- if (IsHTMLMediaElement(element)) {
+ if (IsA<HTMLMediaElement>(element)) {
element->focus(FocusParams(SelectionBehaviorOnFocus::kReset,
- kWebFocusTypeSpatialNavigation, nullptr));
+ mojom::blink::FocusType::kSpatialNavigation,
+ nullptr));
}
}
@@ -612,7 +662,7 @@ bool SpatialNavigationController::UpdateHasNextFormElement(Element* element) {
bool has_next_form_element =
IsFocused(element) &&
page_->GetFocusController().NextFocusableElementInForm(
- element, kWebFocusTypeForward);
+ element, mojom::blink::FocusType::kForward);
if (has_next_form_element == spatial_navigation_state_->has_next_form_element)
return false;
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 3b90ab1e181..fe6831cca2b 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
@@ -48,7 +48,7 @@ class CORE_EXPORT SpatialNavigationController final
void FocusedNodeChanged(Document*);
void FullscreenStateChanged(Element* element);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
// Entry-point into SpatialNavigation advancement. Will return true if an
diff --git a/chromium/third_party/blink/renderer/core/page/spatial_navigation_test.cc b/chromium/third_party/blink/renderer/core/page/spatial_navigation_test.cc
index 2a8cdca0a37..acad766887e 100644
--- a/chromium/third_party/blink/renderer/core/page/spatial_navigation_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/spatial_navigation_test.cc
@@ -5,7 +5,7 @@
#include "third_party/blink/renderer/core/page/spatial_navigation.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/web_keyboard_event.h"
+#include "third_party/blink/public/common/input/web_keyboard_event.h"
#include "third_party/blink/renderer/core/exported/web_remote_frame_impl.h"
#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -72,8 +72,7 @@ class SpatialNavigationTest : public RenderingTest {
}
void UpdateAllLifecyclePhases(LocalFrameView* frame_view) {
- frame_view->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ frame_view->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
}
};
@@ -449,7 +448,8 @@ TEST_F(SpatialNavigationTest, PartiallyVisible) {
// Do some scrolling.
ScrollableArea* root_scroller = GetDocument().View()->GetScrollableArea();
- root_scroller->SetScrollOffset(ScrollOffset(0, 600), kProgrammaticScroll);
+ root_scroller->SetScrollOffset(ScrollOffset(0, 600),
+ mojom::blink::ScrollType::kProgrammatic);
PhysicalRect button_after_scroll = NodeRectInRootFrame(b);
ASSERT_NE(button_in_root_frame,
button_after_scroll); // As we scrolled, the
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 bd943ba6cb6..f313ea77855 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(blink::Visitor* visitor) { visitor->Trace(node_); }
+ void Trace(Visitor* visitor) { visitor->Trace(node_); }
Node* GetNode() const { return node_; }
FloatQuad Quad() const { return quad_; }
@@ -122,7 +122,7 @@ bool NodeIsZoomTarget(Node* node) {
bool ProvidesContextMenuItems(Node* node) {
// This function tries to match the nodes that receive special context-menu
- // items in ContextMenuController::populate(), and should be kept uptodate
+ // items in ContextMenuController::populate(), and should be kept up to date
// with those.
DCHECK(node->GetLayoutObject() || node->IsShadowRoot());
if (!node->GetLayoutObject())
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 8e9e1a248b4..1096a92e09b 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(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) 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 b9142462dd6..f96d766bb3c 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
@@ -31,7 +31,6 @@
#include "cc/layers/picture_layer.h"
#include "third_party/blink/public/platform/task_type.h"
-#include "third_party/blink/public/web/web_text_direction.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -87,7 +86,8 @@ void ValidationMessageClientImpl::ShowValidationMessage(
overlay_ = std::make_unique<FrameOverlay>(target_frame, std::move(delegate));
overlay_delegate_->CreatePage(*overlay_);
bool success =
- target_frame->View()->UpdateLifecycleToCompositingCleanPlusScrolling();
+ target_frame->View()->UpdateLifecycleToCompositingCleanPlusScrolling(
+ DocumentUpdateReason::kOverlay);
ValidationMessageVisibilityChanged(anchor);
// The lifecycle update should always succeed, because this is not inside
@@ -217,7 +217,7 @@ void ValidationMessageClientImpl::PaintOverlay(GraphicsContext& context) {
overlay_->Paint(context);
}
-void ValidationMessageClientImpl::Trace(blink::Visitor* visitor) {
+void ValidationMessageClientImpl::Trace(Visitor* visitor) {
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 df331109b61..6f422df20ab 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 45dac9f4759..cad8d885d3d 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(main_chrome_client_);
visitor->Trace(anchor_view_);
EmptyChromeClient::Trace(visitor);
@@ -137,8 +137,7 @@ void ValidationMessageOverlayDelegate::UpdateFrameViewState(
// FindVisualRectNeedingUpdateScopeBase::CheckVisualRect().
FrameView().GetLayoutView()->SetSubtreeShouldCheckForPaintInvalidation();
- FrameView().UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kOther);
+ FrameView().UpdateAllLifecyclePhases(DocumentUpdateReason::kOverlay);
}
void ValidationMessageOverlayDelegate::CreatePage(const FrameOverlay& overlay) {
@@ -191,8 +190,7 @@ void ValidationMessageOverlayDelegate::CreatePage(const FrameOverlay& overlay) {
}
// Get the size to decide position later.
// TODO(schenney): This says get size, so we only need to update to layout.
- FrameView().UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kOther);
+ FrameView().UpdateAllLifecyclePhases(DocumentUpdateReason::kOverlay);
bubble_size_ = container.VisibleBoundsInVisualViewport().Size();
// Add one because the content sometimes exceeds the exact width due to
// rounding errors.
@@ -201,8 +199,7 @@ void ValidationMessageOverlayDelegate::CreatePage(const FrameOverlay& overlay) {
bubble_size_.Width() / zoom_factor,
CSSPrimitiveValue::UnitType::kPixels);
container.setAttribute(html_names::kClassAttr, "shown-initially");
- FrameView().UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kOther);
+ FrameView().UpdateAllLifecyclePhases(DocumentUpdateReason::kOverlay);
}
void ValidationMessageOverlayDelegate::WriteDocument(SharedBuffer* data) {
diff --git a/chromium/third_party/blink/renderer/core/page/validation_message_overlay_delegate_test.cc b/chromium/third_party/blink/renderer/core/page/validation_message_overlay_delegate_test.cc
index 0a4a5a3b699..6bf9473626d 100644
--- a/chromium/third_party/blink/renderer/core/page/validation_message_overlay_delegate_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/validation_message_overlay_delegate_test.cc
@@ -7,7 +7,7 @@
#include "build/build_config.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"
+#include "third_party/blink/renderer/core/animation/document_animations.h"
#include "third_party/blink/renderer/core/page/page_widget_delegate.h"
#include "third_party/blink/renderer/core/page/validation_message_client.h"
#include "third_party/blink/renderer/core/page/validation_message_client_impl.h"
@@ -64,8 +64,8 @@ TEST_P(ValidationMessageOverlayDelegateTest,
auto overlay =
std::make_unique<FrameOverlay>(&GetFrame(), std::move(delegate));
delegate_ptr->CreatePage(*overlay);
- ASSERT_TRUE(
- GetFrame().View()->UpdateLifecycleToCompositingCleanPlusScrolling());
+ ASSERT_TRUE(GetFrame().View()->UpdateLifecycleToCompositingCleanPlusScrolling(
+ DocumentUpdateReason::kTest));
// Trigger the overlay animations.
auto paint_controller =
@@ -78,7 +78,8 @@ TEST_P(ValidationMessageOverlayDelegateTest,
To<LocalFrame>(delegate_ptr->GetPageForTesting()->MainFrame())
->GetDocument();
HeapVector<Member<Animation>> animations =
- internal_document->Timeline().getAnimations();
+ internal_document->GetDocumentAnimations().getAnimations(
+ *internal_document);
ASSERT_FALSE(animations.IsEmpty());
for (const auto& animation : animations) {
diff --git a/chromium/third_party/blink/renderer/core/page/viewport_description.h b/chromium/third_party/blink/renderer/core/page/viewport_description.h
index 6c5af02972b..aa8bb6379a5 100644
--- a/chromium/third_party/blink/renderer/core/page/viewport_description.h
+++ b/chromium/third_party/blink/renderer/core/page/viewport_description.h
@@ -68,18 +68,16 @@ struct CORE_EXPORT ViewportDescription {
kTypeCount = 7
};
- enum {
- kValueAuto = -1,
- kValueDeviceWidth = -2,
- kValueDeviceHeight = -3,
- kValuePortrait = -4,
- kValueLandscape = -5,
- kValueDeviceDPI = -6,
- kValueLowDPI = -7,
- kValueMediumDPI = -8,
- kValueHighDPI = -9,
- kValueExtendToZoom = -10
- };
+ constexpr static float kValueAuto = -1.;
+ constexpr static float kValueDeviceWidth = -2.;
+ constexpr static float kValueDeviceHeight = -3.;
+ constexpr static float kValuePortrait = -4.;
+ constexpr static float kValueLandscape = -5.;
+ constexpr static float kValueDeviceDPI = -6.;
+ constexpr static float kValueLowDPI = -7.;
+ constexpr static float kValueMediumDPI = -8.;
+ constexpr static float kValueHighDPI = -9.;
+ constexpr static float kValueExtendToZoom = -10.;
ViewportDescription(Type type = kUserAgentStyleSheet)
: type(type),
diff --git a/chromium/third_party/blink/renderer/core/page/viewport_test.cc b/chromium/third_party/blink/renderer/core/page/viewport_test.cc
index d2a25c006e6..40e96faaee7 100644
--- a/chromium/third_party/blink/renderer/core/page/viewport_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/viewport_test.cc
@@ -29,6 +29,7 @@
*/
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/platform/web_float_rect.h"
#include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
#include "third_party/blink/public/web/web_console_message.h"
#include "third_party/blink/public/web/web_frame.h"
@@ -2921,7 +2922,7 @@ TEST_F(ViewportTest, viewportLimitsAdjustedForNoUserScale) {
nullptr, nullptr, nullptr, SetViewportSettings);
web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
Page* page = web_view_helper.GetWebView()->GetPage();
PageScaleConstraints constraints = RunViewportTest(page, 10, 10);
@@ -2939,7 +2940,7 @@ TEST_F(ViewportTest, viewportLimitsAdjustedForUserScale) {
base_url_ + "viewport/viewport-limits-adjusted-for-user-scale.html",
nullptr, nullptr, nullptr, SetViewportSettings);
web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
Page* page = web_view_helper.GetWebView()->GetPage();
PageScaleConstraints constraints = RunViewportTest(page, 10, 10);
diff --git a/chromium/third_party/blink/renderer/core/paint/BUILD.gn b/chromium/third_party/blink/renderer/core/paint/BUILD.gn
index 335341d4569..98c25ea6a92 100644
--- a/chromium/third_party/blink/renderer/core/paint/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/paint/BUILD.gn
@@ -134,6 +134,8 @@ blink_core_sources("paint") {
"ng/ng_fragment_painter.h",
"ng/ng_inline_box_fragment_painter.cc",
"ng/ng_inline_box_fragment_painter.h",
+ "ng/ng_mathml_painter.cc",
+ "ng/ng_mathml_painter.h",
"ng/ng_paint_fragment.cc",
"ng/ng_paint_fragment.h",
"ng/ng_paint_fragment_traversal.cc",
diff --git a/chromium/third_party/blink/renderer/core/paint/DEPS b/chromium/third_party/blink/renderer/core/paint/DEPS
index 25664f0f1f8..75b3e64e39c 100644
--- a/chromium/third_party/blink/renderer/core/paint/DEPS
+++ b/chromium/third_party/blink/renderer/core/paint/DEPS
@@ -7,11 +7,14 @@ include_rules = [
]
specific_include_rules = {
- "(theme_painter|fallback_theme)\.cc": [
+ "(theme_painter|fallback_theme|object_painter_base)\.cc": [
"+ui/native_theme/native_theme.h",
"+ui/native_theme/native_theme_base.h",
],
".*test\.cc": [
"+base/test/trace_event_analyzer.h",
- ]
+ ],
+ "video_painter_test.cc": [
+ "+components/paint_preview/common/paint_preview_tracker.h",
+ ],
}
diff --git a/chromium/third_party/blink/renderer/core/paint/README.md b/chromium/third_party/blink/renderer/core/paint/README.md
index 7dd05de5f52..6d5696496b2 100644
--- a/chromium/third_party/blink/renderer/core/paint/README.md
+++ b/chromium/third_party/blink/renderer/core/paint/README.md
@@ -165,12 +165,11 @@ most recent step towards CompositeAfterPaint was a project called
which uses the compositing decisions from the current compositor
(PaintLayerCompositor, which produces GraphicsLayers) with the new
CompositeAfterPaint compositor (PaintArtifactCompositor). This is done by a step
-at the end of paint which collects all painted GraphicsLayers (and their
-associated cc::Layers) as a list of
-[ForeignLayerDisplayItem](../../platform/graphics/paint/foreign_layer_display_item.h)s.
-Foreign layers are typically used for cc::Layers managed outside blink (e.g.,
+at the end of paint which collects all painted GraphicsLayers as a list of
+[GraphicsLayerDisplayItem](../../platform/graphics/paint/graphics_layer_display_item.h)s.
+Additionaly, [ForeignLayerDisplayItem](../../platform/graphics/paint/foreign_layer_display_item.h)s are used for cc::Layers managed outside blink (e.g.,
video layers, plugin layers) and are treated as opaque composited content by
-the PaintArtifactCompositor. This approach of using foreign layers starts using
+the PaintArtifactCompositor. This approach starts using
much of the new PaintArtifactCompositor logic (e.g., converting blink property
trees to cc property trees) without changing how compositing decisions are made.
@@ -292,9 +291,9 @@ from layout
|<--------------------------------------------------+
| PaintChunksToCcLayer::Convert() |
v |
-+----------------+ |
-| Foreign layers | |
-+----------------+ |
++--------------------------------------------------+ |
+| GraphicsLayerDisplayItem/ForeignLayerDisplayItem | |
++--------------------------------------------------+ |
| |
| LocalFrameView::PushPaintArtifactToCompositor() |
| PaintArtifactCompositor::Update() |
@@ -647,8 +646,7 @@ a PaintLayer and whether we can use cached subsequence for a PaintLayer. See
During painting, we walk the layout tree multiple times for multiple paint
phases. Sometimes a layer contain nothing needing a certain paint phase and we
can skip tree walk for such empty phases. Now we have optimized
-`PaintPhaseDescendantBlockBackgroundsOnly`, `PaintPhaseDescendantOutlinesOnly`
-and `PaintPhaseFloat` for empty paint phases.
+`PaintPhaseDescendantOutlinesOnly` and `PaintPhaseFloat` for empty paint phases.
During paint invalidation, we set the containing self-painting layer's
`NeedsPaintPhaseXXX` flag if the object has something needing to be painted in
@@ -663,36 +661,40 @@ if an object changes style and creates a self-painting-layer, we copy the flags
from its containing self-painting layer to this layer, assuming that this layer
needs all paint phases that its container self-painting layer needs.
-We could update the `NeedsPaintPhaseXXX` flags in a separate tree walk, but that
-would regress performance of the first paint. For CompositeAfterPaint, we can
-update the flags during the pre-painting tree walk to simplify the logic.
-
-### Hit test painting
+### Hit test information recording
Hit testing is done in paint-order, and to preserve this information the paint
-system is re-used to paint hit test display items in the background phase of
-painting. This information is then used in the compositor to implement cc-side
-hit testing. Hit test display items are produced even if there is no painted
-content.
+system is re-used to record hit test information when painting the background.
+This information is then used in the compositor to implement cc-side hit
+testing. Hit test information is recorded even if there is no painted content.
+
+We record different types of hit test information in the following data
+structures:
+
+1. Paint chunk bounds
-There are two types of hit test painting:
+ The bounds of the current paint chunk are expanded to ensure the bounds
+ contain the hit testable area.
-1. [HitTestDisplayItem](../../platform/graphics/paint/hit_test_display_item.h)
+2. [`HitTestData::touch_action_rects`](../../platform/graphics/paint/hit_test_data.h)
- Used for [touch action rects](http://docs.google.com/document/u/1/d/1ksiqEPkDeDuI_l5HvWlq1MfzFyDxSnsNB8YXIaXa3sE/view)
- which are areas of the page that allow certain gesture effects, as well as
- areas of the page that disallow touch events due to blocking touch event
- handlers.
+ Used for [touch action rects](http://docs.google.com/document/u/1/d/1ksiqEPkDeDuI_l5HvWlq1MfzFyDxSnsNB8YXIaXa3sE/view)
+ which are areas of the page that allow certain gesture effects, as well as
+ areas of the page that disallow touch events due to blocking touch event
+ handlers.
-2. [ScrollHitTestDisplayItem](../../platform/graphics/paint/scroll_hit_test_display_item.h)
+3. [`HitTestData::scroll_translation`](../../platform/graphics/paint/hit_test_data.h)
+ and
+ [`HitTestData::scroll_hit_test_rect`](../../platform/graphics/paint/hit_test_data.h)
- Used to create
- [non-fast scrollable regions](https://docs.google.com/document/d/1IyYJ6bVF7KZq96b_s5NrAzGtVoBXn_LQnya9y4yT3iw/view)
- to prevent compositor scrolling of non-composited scrollers, plugins with
- blocking scroll event handlers, and resize handles.
+ Used to create
+ [non-fast scrollable regions](https://docs.google.com/document/d/1IyYJ6bVF7KZq96b_s5NrAzGtVoBXn_LQnya9y4yT3iw/view)
+ to prevent compositor scrolling of non-composited scrollers, plugins with
+ blocking scroll event handlers, and resize handles.
- This is also used for CompositeAfterPaint to force a special cc::Layer that
- is marked as being scrollable.
+ If `scroll_translation` is not null, this is also used for
+ CompositeAfterPaint to force a special cc::Layer that is marked as being
+ scrollable when composited scrolling is needed for the scroller.
### Scrollbar painting
diff --git a/chromium/third_party/blink/renderer/core/paint/background_image_geometry.cc b/chromium/third_party/blink/renderer/core/paint/background_image_geometry.cc
index a92ade16bda..eadaebbe0fc 100644
--- a/chromium/third_party/blink/renderer/core/paint/background_image_geometry.cc
+++ b/chromium/third_party/blink/renderer/core/paint/background_image_geometry.cc
@@ -39,27 +39,12 @@ inline LayoutUnit GetSpaceBetweenImageTiles(LayoutUnit area_size,
bool FixedBackgroundPaintsInLocalCoordinates(
const LayoutObject& obj,
const GlobalPaintFlags global_paint_flags) {
- if (!obj.IsLayoutView())
+ const auto* view = DynamicTo<LayoutView>(obj);
+ if (!view)
return false;
- const LayoutView& view = ToLayoutView(obj);
-
- // TODO(wangxianzhu): For CAP, inline this function into
- // FixedBackgroundPaintsInLocalCoordinates().
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
- return view.GetBackgroundPaintLocation() !=
- kBackgroundPaintInScrollingContents;
- }
-
- if (global_paint_flags & kGlobalPaintFlattenCompositingLayers)
- return false;
-
- PaintLayer* root_layer = view.Layer();
- if (!root_layer || root_layer->GetCompositingState() == kNotComposited)
- return false;
-
- CompositedLayerMapping* mapping = root_layer->GetCompositedLayerMapping();
- return !mapping->BackgroundPaintsOntoScrollingContentsLayer();
+ return !(view->GetBackgroundPaintLocation() &
+ kBackgroundPaintInScrollingContents);
}
LayoutPoint AccumulatedScrollOffsetForFixedBackground(
@@ -103,15 +88,17 @@ void BackgroundImageGeometry::SetNoRepeatX(const FillLayer& fill_layer,
return;
}
- // The snapped offset may not yet be snapped, so make sure it is an integer.
- snapped_x_offset = LayoutUnit(RoundToInt(snapped_x_offset));
-
if (x_offset > 0) {
DCHECK(snapped_x_offset >= LayoutUnit());
// Move the dest rect if the offset is positive. The image "stays" where
// it is over the dest rect, so this effectively modifies the phase.
unsnapped_dest_rect_.Move(x_offset, LayoutUnit());
- snapped_dest_rect_.Move(snapped_x_offset, LayoutUnit());
+
+ // For the snapped geometry, note that negative x_offsets typically
+ // arise when using positive offsets from the bottom of the background
+ // rect. We try to move the snapped dest rect to give the same offset.
+ LayoutUnit dx = snapped_dest_rect_.Width() - unsnapped_dest_rect_.Width();
+ snapped_dest_rect_.Move(x_offset + dx, LayoutUnit());
// Make the dest as wide as a tile, which will reduce the dest
// rect if the tile is too small to fill the paint_rect. If not,
@@ -147,16 +134,17 @@ void BackgroundImageGeometry::SetNoRepeatY(const FillLayer& fill_layer,
LayoutSize(SpaceSize().Width(), unsnapped_dest_rect_.Height()));
return;
}
-
- // The snapped offset may not yet be snapped, so make sure it is an integer.
- snapped_y_offset = LayoutUnit(RoundToInt(snapped_y_offset));
-
if (y_offset > 0) {
DCHECK(snapped_y_offset >= LayoutUnit());
// Move the dest rect if the offset is positive. The image "stays" where
// it is in the paint rect, so this effectively modifies the phase.
unsnapped_dest_rect_.Move(LayoutUnit(), y_offset);
- snapped_dest_rect_.Move(LayoutUnit(), snapped_y_offset);
+
+ // For the snapped geometry, note that negative y_offsets typically
+ // arise when using positive offsets from the bottom of the background
+ // rect. We try to move the snapped dest rect to give the same offset.
+ LayoutUnit dy = snapped_dest_rect_.Height() - unsnapped_dest_rect_.Height();
+ snapped_dest_rect_.Move(LayoutUnit(), y_offset + dy);
// Make the dest as wide as a tile, which will reduce the dest
// rect if the tile is too small to fill the paint_rect. If not,
@@ -402,17 +390,9 @@ LayoutRect FixedAttachmentPositioningArea(const LayoutBoxModelObject& obj,
// The LayoutView is the only object that can paint a fixed background into
// its scrolling contents layer, so it gets a special adjustment here.
- if (obj.IsLayoutView()) {
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
- DCHECK_EQ(obj.GetBackgroundPaintLocation(),
- kBackgroundPaintInScrollingContents);
- rect.SetLocation(LayoutPoint(ToLayoutView(obj).ScrolledContentOffset()));
- } else if (auto* mapping = obj.Layer()->GetCompositedLayerMapping()) {
- if (mapping->BackgroundPaintsOntoScrollingContentsLayer()) {
- rect.SetLocation(
- LayoutPoint(ToLayoutView(obj).ScrolledContentOffset()));
- }
- }
+ if (auto* layout_view = DynamicTo<LayoutView>(obj)) {
+ if (obj.GetBackgroundPaintLocation() & kBackgroundPaintInScrollingContents)
+ rect.SetLocation(LayoutPoint(layout_view->ScrolledContentOffset()));
}
rect.MoveBy(AccumulatedScrollOffsetForFixedBackground(obj, container));
@@ -442,13 +422,13 @@ LayoutRect FixedAttachmentPositioningArea(const LayoutBoxModelObject& obj,
} // Anonymous namespace
-BackgroundImageGeometry::BackgroundImageGeometry(const LayoutView& view)
+BackgroundImageGeometry::BackgroundImageGeometry(
+ const LayoutView& view,
+ bool root_elemnet_has_transform)
: box_(view),
positioning_box_(view.RootBox()),
- has_non_local_geometry_(false),
painting_view_(true),
- painting_table_cell_(false),
- cell_using_container_background_(false) {
+ root_element_has_transform_(root_elemnet_has_transform) {
// The background of the box generated by the root element covers the
// entire canvas and will be painted by the view object, but the we should
// still use the root element box for positioning.
@@ -457,14 +437,9 @@ BackgroundImageGeometry::BackgroundImageGeometry(const LayoutView& view)
BackgroundImageGeometry::BackgroundImageGeometry(
const LayoutBoxModelObject& obj)
- : box_(obj),
- positioning_box_(obj),
- has_non_local_geometry_(false),
- painting_view_(false),
- painting_table_cell_(false),
- cell_using_container_background_(false) {
+ : box_(obj), positioning_box_(obj) {
// Specialized constructor should be used for LayoutView.
- DCHECK(!obj.IsLayoutView());
+ DCHECK(!IsA<LayoutView>(obj));
}
BackgroundImageGeometry::BackgroundImageGeometry(
@@ -474,8 +449,6 @@ BackgroundImageGeometry::BackgroundImageGeometry(
positioning_box_(background_object && !background_object->IsTableCell()
? ToLayoutBoxModelObject(*background_object)
: cell),
- has_non_local_geometry_(false),
- painting_view_(false),
painting_table_cell_(true) {
cell_using_container_background_ =
background_object && !background_object->IsTableCell();
@@ -729,11 +702,14 @@ void BackgroundImageGeometry::ComputePositioningArea(
snapped_box_offset =
LayoutPoint(snapped_box_outset.Left() - snapped_dest_adjust.Left(),
snapped_box_outset.Top() - snapped_dest_adjust.Top());
- // For view backgrounds, the input paint rect is specified in root element
- // local coordinate (i.e. a transform is applied on the context for
- // painting), and is expanded to cover the whole canvas. Since left/top is
- // relative to the paint rect, we need to offset them back.
- if (painting_view_) {
+
+ // |paint_rect|'s location is usually assumed by BackgroundImageGeometry
+ // to encode paint offset in the local transform space. The one case in
+ // which this is not true is painting the background of the LayoutView
+ // canvas when the HTML element has a transform. In that case, the
+ // paint offset is zero, and the offset gets applied later by a
+ // PaintOffsetTranslation.
+ if (painting_view_ && root_element_has_transform_) {
unsnapped_box_offset -= paint_rect.Location();
snapped_box_offset -= paint_rect.Location();
}
@@ -756,7 +732,8 @@ void BackgroundImageGeometry::CalculateFillTileSize(
: unsnapped_positioning_area_size;
LayoutSize image_intrinsic_size(image->ImageSize(
positioning_box_.GetDocument(),
- positioning_box_.StyleRef().EffectiveZoom(), positioning_area_size));
+ positioning_box_.StyleRef().EffectiveZoom(), positioning_area_size,
+ LayoutObject::ShouldRespectImageOrientation(&box_)));
switch (type) {
case EFillSizeType::kSizeLength: {
tile_size_ = positioning_area_size;
@@ -1039,9 +1016,13 @@ void BackgroundImageGeometry::Calculate(const LayoutBoxModelObject* container,
if (ShouldUseFixedAttachment(fill_layer))
UseFixedAttachment(paint_rect.Location());
- // Clip the final output rect to the paint rect, maintaining snapping.
+ // Clip the final output rect to the paint rect.
unsnapped_dest_rect_.Intersect(paint_rect);
- snapped_dest_rect_.Intersect(LayoutRect(PixelSnappedIntRect(paint_rect)));
+
+ // Clip the snapped rect, and re-snap the dest rect as we may have
+ // adjusted it with unsnapped values.
+ snapped_dest_rect_.Intersect(paint_rect);
+ snapped_dest_rect_ = LayoutRect(PixelSnappedIntRect(snapped_dest_rect_));
}
const ImageResourceObserver& BackgroundImageGeometry::ImageClient() const {
diff --git a/chromium/third_party/blink/renderer/core/paint/background_image_geometry.h b/chromium/third_party/blink/renderer/core/paint/background_image_geometry.h
index cac45a7592c..02c1f2eb794 100644
--- a/chromium/third_party/blink/renderer/core/paint/background_image_geometry.h
+++ b/chromium/third_party/blink/renderer/core/paint/background_image_geometry.h
@@ -31,7 +31,7 @@ class BackgroundImageGeometry {
public:
// Constructor for LayoutView where the coordinate space is different.
- BackgroundImageGeometry(const LayoutView&);
+ BackgroundImageGeometry(const LayoutView&, bool root_elemnet_has_transform);
// Constructor for table cells where background_object may be the row or
// column the background image is attached to.
@@ -181,10 +181,11 @@ class BackgroundImageGeometry {
FloatPoint phase_;
LayoutSize tile_size_;
LayoutSize repeat_spacing_;
- bool has_non_local_geometry_;
- bool painting_view_;
- bool painting_table_cell_;
- bool cell_using_container_background_;
+ bool has_non_local_geometry_ = false;
+ bool painting_view_ = false;
+ bool painting_table_cell_ = false;
+ bool cell_using_container_background_ = false;
+ bool root_element_has_transform_ = false;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/block_flow_paint_invalidator.cc b/chromium/third_party/blink/renderer/core/paint/block_flow_paint_invalidator.cc
index 680513699b2..ca0d9bfebb3 100644
--- a/chromium/third_party/blink/renderer/core/paint/block_flow_paint_invalidator.cc
+++ b/chromium/third_party/blink/renderer/core/paint/block_flow_paint_invalidator.cc
@@ -6,6 +6,8 @@
#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_fragment_items.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h"
#include "third_party/blink/renderer/core/paint/box_paint_invalidator.h"
#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
#include "third_party/blink/renderer/core/paint/paint_invalidator.h"
@@ -58,17 +60,31 @@ void BlockFlowPaintInvalidator::InvalidateDisplayItemClients(
reason == PaintInvalidationReason::kSelection)
return;
- // It's the RootInlineBox that paints the ::first-line background. Note that
- // since it may be expensive to figure out if the first line is affected by
- // any ::first-line selectors at all, we just invalidate it unconditionally
- // which is typically cheaper.
- if (RootInlineBox* line = block_flow_.FirstRootBox()) {
- if (line->IsFirstLineStyle()) {
- object_paint_invalidator.InvalidateDisplayItemClient(*line, reason);
+ NGInlineCursor cursor(block_flow_);
+ if (cursor) {
+ // Line boxes record hit test data (see NGBoxFragmentPainter::PaintLineBox)
+ // and should be invalidated if they change.
+ bool invalidate_all_lines = block_flow_.HasEffectiveAllowedTouchAction();
+
+ for (cursor.MoveToFirstLine(); cursor; cursor.MoveToNextLine()) {
+ // The first line NGLineBoxFragment paints the ::first-line background.
+ // Because it may be expensive to figure out if the first line is affected
+ // by any ::first-line selectors at all, we just invalidate
+ // unconditionally which is typically cheaper.
+ if (invalidate_all_lines || cursor.Current().UsesFirstLineStyle()) {
+ DCHECK(cursor.Current().GetDisplayItemClient());
+ object_paint_invalidator.InvalidateDisplayItemClient(
+ *cursor.Current().GetDisplayItemClient(), reason);
+ }
+ if (!invalidate_all_lines)
+ break;
}
- } else if (paint_fragment) {
- NGPaintFragment* line = paint_fragment->FirstLineBox();
- if (line && line->PhysicalFragment().UsesFirstLineStyle()) {
+ } else if (RootInlineBox* line = block_flow_.FirstRootBox()) {
+ // It's the RootInlineBox that paints the ::first-line background. Note that
+ // since it may be expensive to figure out if the first line is affected by
+ // any ::first-line selectors at all, we just invalidate it unconditionally
+ // which is typically cheaper.
+ if (line->IsFirstLineStyle()) {
object_paint_invalidator.InvalidateDisplayItemClient(*line, reason);
}
}
diff --git a/chromium/third_party/blink/renderer/core/paint/block_painter.cc b/chromium/third_party/blink/renderer/core/paint/block_painter.cc
index 4364b0e0342..60a7b22aa39 100644
--- a/chromium/third_party/blink/renderer/core/paint/block_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/block_painter.cc
@@ -146,7 +146,7 @@ void BlockPainter::PaintChild(const LayoutBox& child,
// paints floats in regular tree order (the FloatingObjects list is only used
// by legacy layout).
if (paint_info.phase != PaintPhase::kFloat &&
- paint_info.phase != PaintPhase::kSelection &&
+ paint_info.phase != PaintPhase::kSelectionDragImage &&
paint_info.phase != PaintPhase::kTextClip)
return;
@@ -182,7 +182,7 @@ void BlockPainter::PaintInlineBox(const InlineBox& inline_box,
const PaintInfo& paint_info) {
if (paint_info.phase != PaintPhase::kForeground &&
paint_info.phase != PaintPhase::kForcedColorsModeBackplate &&
- paint_info.phase != PaintPhase::kSelection)
+ paint_info.phase != PaintPhase::kSelectionDragImage)
return;
// Text clips are painted only for the direct inline children of the object
@@ -287,7 +287,7 @@ void BlockPainter::PaintBlockFlowContents(const PaintInfo& paint_info,
To<LayoutBlockFlow>(layout_block_).GetFloatingObjects();
const PaintPhase paint_phase = paint_info.phase;
if (!floating_objects || !(paint_phase == PaintPhase::kFloat ||
- paint_phase == PaintPhase::kSelection ||
+ paint_phase == PaintPhase::kSelectionDragImage ||
paint_phase == PaintPhase::kTextClip)) {
return;
}
diff --git a/chromium/third_party/blink/renderer/core/paint/block_painter_test.cc b/chromium/third_party/blink/renderer/core/paint/block_painter_test.cc
index 00021a4679e..070d7578f99 100644
--- a/chromium/third_party/blink/renderer/core/paint/block_painter_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/block_painter_test.cc
@@ -12,7 +12,6 @@
#include "third_party/blink/renderer/core/paint/paint_controller_paint_test.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_chunk.h"
-#include "third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h"
using testing::ElementsAre;
@@ -71,93 +70,107 @@ TEST_F(BlockPainterTouchActionTest, TouchActionRectsWithoutPaint) {
</div>
)HTML");
- // Initially there should be no hit test display items because there is no
- // touch action.
+ // Initially there should be no hit test data because there is no touch
+ // action.
const auto& scrolling_client = ViewScrollingBackgroundClient();
EXPECT_THAT(
RootPaintController().GetDisplayItemList(),
ElementsAre(IsSameId(&scrolling_client, kDocumentBackgroundType)));
+ PaintChunk::Id root_chunk_id(scrolling_client, kDocumentBackgroundType);
+ auto root_chunk_properties =
+ GetLayoutView().FirstFragment().ContentsProperties();
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(IsPaintChunk(0, 1, root_chunk_id, root_chunk_properties)));
- // Add a touch action to parent and ensure that hit test display items are
- // created for both the parent and the visible child.
+ // Add a touch action to parent and ensure that hit test data are created
+ // for both the parent and the visible child.
auto* parent_element = GetElementById("parent");
parent_element->setAttribute(html_names::kClassAttr, "touchActionNone");
UpdateAllLifecyclePhasesForTest();
- auto* parent = GetLayoutObjectByElementId("parent");
- auto* child_visible = GetLayoutObjectByElementId("childVisible");
- EXPECT_THAT(RootPaintController().GetDisplayItemList(),
- ElementsAre(IsSameId(&scrolling_client, kDocumentBackgroundType),
- IsSameId(parent, DisplayItem::kHitTest),
- IsSameId(child_visible, DisplayItem::kHitTest)));
+ EXPECT_THAT(
+ RootPaintController().GetDisplayItemList(),
+ ElementsAre(IsSameId(&scrolling_client, kDocumentBackgroundType)));
+ HitTestData hit_test_data;
+ hit_test_data.touch_action_rects = {{IntRect(0, 0, 100, 100)},
+ {IntRect(0, 0, 200, 25)}};
+ EXPECT_THAT(RootPaintController().PaintChunks(),
+ ElementsAre(IsPaintChunk(0, 1, root_chunk_id,
+ root_chunk_properties, &hit_test_data)));
- // Remove the touch action from parent and ensure no hit test display items
- // are left.
+ // Remove the touch action from parent and ensure no hit test data are left.
parent_element->removeAttribute(html_names::kClassAttr);
UpdateAllLifecyclePhasesForTest();
EXPECT_THAT(
RootPaintController().GetDisplayItemList(),
ElementsAre(IsSameId(&scrolling_client, kDocumentBackgroundType)));
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(IsPaintChunk(0, 1, root_chunk_id, root_chunk_properties)));
}
TEST_F(BlockPainterTouchActionTest, TouchActionRectSubsequenceCaching) {
SetBodyInnerHTML(R"HTML(
<style>
body { margin: 0; }
+ #stacking-context {
+ position: absolute;
+ z-index: 1;
+ }
#touchaction {
width: 100px;
height: 100px;
touch-action: none;
}
- #sibling {
- width: 100px;
- height: 100px;
- background: blue;
- }
</style>
- <div id='touchaction'></div>
+ <div id='stacking-context'>
+ <div id='touchaction'></div>
+ </div>
)HTML");
const auto& scrolling_client = ViewScrollingBackgroundClient();
const auto* touchaction = GetLayoutObjectByElementId("touchaction");
- EXPECT_THAT(RootPaintController().GetDisplayItemList(),
- ElementsAre(IsSameId(&scrolling_client, kDocumentBackgroundType),
- IsSameId(touchaction, DisplayItem::kHitTest)));
+ EXPECT_THAT(
+ RootPaintController().GetDisplayItemList(),
+ ElementsAre(IsSameId(&scrolling_client, kDocumentBackgroundType)));
- const auto& hit_test_client = *touchaction->EnclosingLayer();
+ const auto& hit_test_client =
+ *ToLayoutBox(GetLayoutObjectByElementId("stacking-context"))->Layer();
EXPECT_SUBSEQUENCE(hit_test_client, 1, 2);
PaintChunk::Id root_chunk_id(scrolling_client, kDocumentBackgroundType);
auto root_chunk_properties =
GetLayoutView().FirstFragment().ContentsProperties();
- PaintChunk::Id hit_test_chunk_id(hit_test_client,
- kNonScrollingBackgroundChunkType);
+ PaintChunk::Id hit_test_chunk_id(hit_test_client, DisplayItem::kLayerChunk);
auto hit_test_chunk_properties = touchaction->EnclosingLayer()
->GetLayoutObject()
.FirstFragment()
.ContentsProperties();
HitTestData hit_test_data;
- hit_test_data.touch_action_rects.emplace_back(LayoutRect(0, 0, 100, 100));
+ hit_test_data.touch_action_rects = {{IntRect(0, 0, 100, 100)}};
EXPECT_THAT(
RootPaintController().PaintChunks(),
- ElementsAre(IsPaintChunk(0, 1, root_chunk_id, root_chunk_properties),
- IsPaintChunk(1, 2, hit_test_chunk_id,
- hit_test_chunk_properties, hit_test_data)));
+ ElementsAre(
+ IsPaintChunk(0, 1, root_chunk_id, root_chunk_properties),
+ IsPaintChunk(1, 1, hit_test_chunk_id, hit_test_chunk_properties,
+ &hit_test_data, IntRect(0, 0, 100, 100))));
// Trigger a repaint with the whole HTML subsequence cached.
GetLayoutView().Layer()->SetNeedsRepaint();
EXPECT_TRUE(PaintWithoutCommit());
- EXPECT_EQ(2, NumCachedNewItems());
+ EXPECT_EQ(1, NumCachedNewItems());
CommitAndFinishCycle();
EXPECT_SUBSEQUENCE(hit_test_client, 1, 2);
EXPECT_THAT(
RootPaintController().PaintChunks(),
- ElementsAre(IsPaintChunk(0, 1, root_chunk_id, root_chunk_properties),
- IsPaintChunk(1, 2, hit_test_chunk_id,
- hit_test_chunk_properties, hit_test_data)));
+ ElementsAre(
+ IsPaintChunk(0, 1, root_chunk_id, root_chunk_properties),
+ IsPaintChunk(1, 1, hit_test_chunk_id, hit_test_chunk_properties,
+ &hit_test_data, IntRect(0, 0, 100, 100))));
}
TEST_F(BlockPainterTouchActionTest, TouchActionRectPaintCaching) {
@@ -180,45 +193,34 @@ TEST_F(BlockPainterTouchActionTest, TouchActionRectPaintCaching) {
)HTML");
const auto& scrolling_client = ViewScrollingBackgroundClient();
- const auto* touchaction = GetLayoutObjectByElementId("touchaction");
auto* sibling_element = GetElementById("sibling");
const auto* sibling = sibling_element->GetLayoutObject();
EXPECT_THAT(RootPaintController().GetDisplayItemList(),
ElementsAre(IsSameId(&scrolling_client, kDocumentBackgroundType),
- IsSameId(touchaction, DisplayItem::kHitTest),
IsSameId(sibling, kBackgroundType)));
PaintChunk::Id root_chunk_id(scrolling_client, kDocumentBackgroundType);
auto root_chunk_properties =
GetLayoutView().FirstFragment().ContentsProperties();
- PaintChunk::Id hit_test_chunk_id(*touchaction->EnclosingLayer(),
- kNonScrollingBackgroundChunkType);
- auto hit_test_chunk_properties = touchaction->EnclosingLayer()
- ->GetLayoutObject()
- .FirstFragment()
- .ContentsProperties();
HitTestData hit_test_data;
- hit_test_data.touch_action_rects.emplace_back(LayoutRect(0, 0, 100, 100));
+ hit_test_data.touch_action_rects = {{IntRect(0, 0, 100, 100)}};
- EXPECT_THAT(
- RootPaintController().PaintChunks(),
- ElementsAre(IsPaintChunk(0, 1, root_chunk_id, root_chunk_properties),
- IsPaintChunk(1, 3, hit_test_chunk_id,
- hit_test_chunk_properties, hit_test_data)));
+ EXPECT_THAT(RootPaintController().PaintChunks(),
+ ElementsAre(IsPaintChunk(0, 2, root_chunk_id,
+ root_chunk_properties, &hit_test_data)));
sibling_element->setAttribute(html_names::kStyleAttr, "background: green;");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(PaintWithoutCommit());
// Only the background display item of the sibling should be invalidated.
- EXPECT_EQ(2, NumCachedNewItems());
+ EXPECT_EQ(1, NumCachedNewItems());
CommitAndFinishCycle();
- EXPECT_THAT(
- RootPaintController().PaintChunks(),
- ElementsAre(IsPaintChunk(0, 1, root_chunk_id, root_chunk_properties),
- IsPaintChunk(1, 3, hit_test_chunk_id,
- hit_test_chunk_properties, hit_test_data)));
+ EXPECT_THAT(RootPaintController().PaintChunks(),
+ ElementsAre(IsPaintChunk(0, 2, root_chunk_id,
+ root_chunk_properties, &hit_test_data)));
}
TEST_F(BlockPainterTouchActionTest, TouchActionRectScrollingContents) {
@@ -251,25 +253,21 @@ TEST_F(BlockPainterTouchActionTest, TouchActionRectScrollingContents) {
auto* scroller = ToLayoutBoxModelObject(scroller_element->GetLayoutObject());
const auto& scroller_client =
scroller->GetScrollableArea()->GetScrollingBackgroundDisplayItemClient();
- auto* child_element = GetElementById("child");
- auto* child = child_element->GetLayoutObject();
auto& non_scroller_paint_controller = RootPaintController();
auto& scroller_paint_controller = scroller->GetScrollableArea()
->Layer()
->GraphicsLayerBacking()
->GetPaintController();
EXPECT_THAT(scroller_paint_controller.GetDisplayItemList(),
- ElementsAre(IsSameId(&scroller_client, kBackgroundType),
- IsSameId(&scroller_client, DisplayItem::kHitTest),
- IsSameId(child, DisplayItem::kHitTest)));
+ ElementsAre(IsSameId(&scroller_client, kBackgroundType)));
HitTestData hit_test_data;
- hit_test_data.touch_action_rects.emplace_back(LayoutRect(0, 0, 100, 400));
- hit_test_data.touch_action_rects.emplace_back(LayoutRect(0, 0, 10, 400));
+ hit_test_data.touch_action_rects = {{IntRect(0, 0, 100, 400)},
+ {IntRect(0, 0, 10, 400)}};
EXPECT_THAT(
scroller_paint_controller.PaintChunks(),
ElementsAre(IsPaintChunk(
- 0, 3, PaintChunk::Id(*scroller, kScrollingBackgroundChunkType),
- scroller->FirstFragment().ContentsProperties(), hit_test_data)));
+ 0, 1, PaintChunk::Id(*scroller, kScrollingBackgroundChunkType),
+ scroller->FirstFragment().ContentsProperties(), &hit_test_data)));
EXPECT_THAT(non_scroller_paint_controller.GetDisplayItemList(),
ElementsAre(IsSameId(&root_client, kDocumentBackgroundType)));
@@ -309,24 +307,18 @@ TEST_F(BlockPainterTouchActionTest, TouchActionRectPaintChunkChanges) {
touchaction_element->setAttribute(html_names::kStyleAttr,
"touch-action: none;");
UpdateAllLifecyclePhasesForTest();
- EXPECT_THAT(RootPaintController().GetDisplayItemList(),
- ElementsAre(IsSameId(&scrolling_client, kDocumentBackgroundType),
- IsSameId(touchaction, DisplayItem::kHitTest)));
+ EXPECT_THAT(
+ RootPaintController().GetDisplayItemList(),
+ ElementsAre(IsSameId(&scrolling_client, kDocumentBackgroundType)));
PaintChunk::Id hit_test_chunk_id(*touchaction->EnclosingLayer(),
kNonScrollingBackgroundChunkType);
- auto hit_test_chunk_properties = touchaction->EnclosingLayer()
- ->GetLayoutObject()
- .FirstFragment()
- .ContentsProperties();
HitTestData hit_test_data;
- hit_test_data.touch_action_rects.emplace_back(LayoutRect(0, 0, 100, 100));
+ hit_test_data.touch_action_rects = {{IntRect(0, 0, 100, 100)}};
- EXPECT_THAT(
- RootPaintController().PaintChunks(),
- ElementsAre(IsPaintChunk(0, 1, root_chunk_id, root_chunk_properties),
- IsPaintChunk(1, 2, hit_test_chunk_id,
- hit_test_chunk_properties, hit_test_data)));
+ EXPECT_THAT(RootPaintController().PaintChunks(),
+ ElementsAre(IsPaintChunk(0, 1, root_chunk_id,
+ root_chunk_properties, &hit_test_data)));
touchaction_element->removeAttribute(html_names::kStyleAttr);
UpdateAllLifecyclePhasesForTest();
@@ -358,35 +350,46 @@ TEST_F(BlockPainterTouchActionTest, TouchHandlerRectsWithoutPaint) {
</div>
)HTML");
- // Initially there should be no hit test display items because there are no
- // event handlers.
+ // Initially there should be no hit test data because there are no event
+ // handlers.
const auto& scrolling_client = ViewScrollingBackgroundClient();
EXPECT_THAT(
RootPaintController().GetDisplayItemList(),
ElementsAre(IsSameId(&scrolling_client, kDocumentBackgroundType)));
- // Add an event listener to parent and ensure that hit test display items are
- // created for both the parent and child.
+ // Add an event listener to parent and ensure that hit test data are created
+ // for both the parent and child.
BlockPainterMockEventListener* callback =
MakeGarbageCollected<BlockPainterMockEventListener>();
auto* parent_element = GetElementById("parent");
parent_element->addEventListener(event_type_names::kTouchstart, callback);
UpdateAllLifecyclePhasesForTest();
- auto* parent = GetLayoutObjectByElementId("parent");
- auto* child = GetLayoutObjectByElementId("child");
- EXPECT_THAT(RootPaintController().GetDisplayItemList(),
- ElementsAre(IsSameId(&scrolling_client, kDocumentBackgroundType),
- IsSameId(parent, DisplayItem::kHitTest),
- IsSameId(child, DisplayItem::kHitTest)));
+ EXPECT_THAT(
+ RootPaintController().GetDisplayItemList(),
+ ElementsAre(IsSameId(&scrolling_client, kDocumentBackgroundType)));
+ HitTestData hit_test_data;
+ hit_test_data.touch_action_rects = {{IntRect(0, 0, 100, 100)},
+ {IntRect(0, 0, 200, 50)}};
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(IsPaintChunk(
+ 0, 1, PaintChunk::Id(scrolling_client, kDocumentBackgroundType),
+ GetLayoutView().FirstFragment().ContentsProperties(), &hit_test_data,
+ IntRect(0, 0, 800, 600))));
- // Remove the event handler from parent and ensure no hit test display items
- // are left.
+ // Remove the event handler from parent and ensure no hit test data are left.
parent_element->RemoveAllEventListeners();
UpdateAllLifecyclePhasesForTest();
EXPECT_THAT(
RootPaintController().GetDisplayItemList(),
ElementsAre(IsSameId(&scrolling_client, kDocumentBackgroundType)));
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(IsPaintChunk(
+ 0, 1, PaintChunk::Id(scrolling_client, kDocumentBackgroundType),
+ GetLayoutView().FirstFragment().ContentsProperties(), nullptr,
+ IntRect(0, 0, 800, 600))));
}
TEST_F(BlockPainterTouchActionTest, TouchActionRectsAcrossPaintChanges) {
@@ -403,21 +406,32 @@ TEST_F(BlockPainterTouchActionTest, TouchActionRectsAcrossPaintChanges) {
)HTML");
const auto& scrolling_client = ViewScrollingBackgroundClient();
- auto* parent = GetLayoutObjectByElementId("parent");
- auto* child = GetLayoutObjectByElementId("child");
- EXPECT_THAT(RootPaintController().GetDisplayItemList(),
- ElementsAre(IsSameId(&scrolling_client, kDocumentBackgroundType),
- IsSameId(parent, DisplayItem::kHitTest),
- IsSameId(child, DisplayItem::kHitTest)));
+ EXPECT_THAT(
+ RootPaintController().GetDisplayItemList(),
+ ElementsAre(IsSameId(&scrolling_client, kDocumentBackgroundType)));
+ HitTestData hit_test_data;
+ hit_test_data.touch_action_rects = {{IntRect(0, 0, 100, 100)},
+ {IntRect(0, 0, 200, 50)}};
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(IsPaintChunk(
+ 0, 1, PaintChunk::Id(scrolling_client, kDocumentBackgroundType),
+ GetLayoutView().FirstFragment().ContentsProperties(), &hit_test_data,
+ IntRect(0, 0, 800, 600))));
- auto* child_element = GetElementById("parent");
+ auto* child_element = GetElementById("child");
child_element->setAttribute("style", "background: blue;");
UpdateAllLifecyclePhasesForTest();
- EXPECT_THAT(RootPaintController().GetDisplayItemList(),
- ElementsAre(IsSameId(&scrolling_client, kDocumentBackgroundType),
- IsSameId(parent, kBackgroundType),
- IsSameId(parent, DisplayItem::kHitTest),
- IsSameId(child, DisplayItem::kHitTest)));
+ EXPECT_THAT(
+ RootPaintController().GetDisplayItemList(),
+ ElementsAre(IsSameId(&scrolling_client, kDocumentBackgroundType),
+ IsSameId(child_element->GetLayoutObject(), kBackgroundType)));
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(IsPaintChunk(
+ 0, 2, PaintChunk::Id(scrolling_client, kDocumentBackgroundType),
+ GetLayoutView().FirstFragment().ContentsProperties(), &hit_test_data,
+ IntRect(0, 0, 800, 600))));
}
TEST_F(BlockPainterTouchActionTest, ScrolledHitTestChunkProperties) {
@@ -445,24 +459,21 @@ TEST_F(BlockPainterTouchActionTest, ScrolledHitTestChunkProperties) {
const auto& scrolling_client = ViewScrollingBackgroundClient();
const auto* scroller =
To<LayoutBlock>(GetLayoutObjectByElementId("scroller"));
- const auto* child = GetLayoutObjectByElementId("child");
- EXPECT_THAT(RootPaintController().GetDisplayItemList(),
- ElementsAre(IsSameId(&scrolling_client, kDocumentBackgroundType),
- IsSameId(scroller, DisplayItem::kHitTest),
- IsSameId(scroller, DisplayItem::kScrollHitTest),
- IsSameId(child, DisplayItem::kHitTest)));
+ EXPECT_THAT(
+ RootPaintController().GetDisplayItemList(),
+ ElementsAre(IsSameId(&scrolling_client, kDocumentBackgroundType)));
HitTestData scroller_touch_action_hit_test_data;
- scroller_touch_action_hit_test_data.touch_action_rects.emplace_back(
- LayoutRect(0, 0, 100, 100));
+ scroller_touch_action_hit_test_data.touch_action_rects = {
+ {IntRect(0, 0, 100, 100)}};
const auto& scrolling_contents_properties =
scroller->FirstFragment().ContentsProperties();
HitTestData scroll_hit_test_data;
- scroll_hit_test_data.SetScrollHitTest(
- &scrolling_contents_properties.Transform(), IntRect(0, 0, 100, 100));
+ scroll_hit_test_data.scroll_translation =
+ &scrolling_contents_properties.Transform();
+ scroll_hit_test_data.scroll_hit_test_rect = IntRect(0, 0, 100, 100);
HitTestData scrolled_hit_test_data;
- scrolled_hit_test_data.touch_action_rects.emplace_back(
- LayoutRect(0, 0, 200, 50));
+ scrolled_hit_test_data.touch_action_rects = {{IntRect(0, 0, 200, 50)}};
const auto& paint_chunks = RootPaintController().PaintChunks();
EXPECT_THAT(
@@ -470,29 +481,28 @@ TEST_F(BlockPainterTouchActionTest, ScrolledHitTestChunkProperties) {
ElementsAre(
IsPaintChunk(
0, 1, PaintChunk::Id(scrolling_client, kDocumentBackgroundType),
- GetLayoutView().FirstFragment().ContentsProperties()),
- IsPaintChunk(1, 2,
- PaintChunk::Id(*scroller->Layer(),
- kNonScrollingBackgroundChunkType),
- scroller->FirstFragment().LocalBorderBoxProperties(),
- scroller_touch_action_hit_test_data),
- IsPaintChunk(2, 3,
+ GetLayoutView().FirstFragment().ContentsProperties(), nullptr,
+ IntRect(0, 0, 800, 600)),
+ IsPaintChunk(
+ 1, 1,
+ PaintChunk::Id(*scroller->Layer(), DisplayItem::kLayerChunk),
+ scroller->FirstFragment().LocalBorderBoxProperties(),
+ &scroller_touch_action_hit_test_data, IntRect(0, 0, 100, 100)),
+ IsPaintChunk(1, 1,
PaintChunk::Id(*scroller, DisplayItem::kScrollHitTest),
scroller->FirstFragment().LocalBorderBoxProperties(),
- scroll_hit_test_data),
+ &scroll_hit_test_data, IntRect(0, 0, 100, 100)),
IsPaintChunk(
- 3, 4,
- PaintChunk::Id(*scroller, kScrollingContentsBackgroundChunkType),
+ 1, 1,
+ PaintChunk::Id(*scroller, kClippedContentsBackgroundChunkType),
scroller->FirstFragment().ContentsProperties(),
- scrolled_hit_test_data)));
+ &scrolled_hit_test_data, IntRect(0, 0, 200, 50))));
const auto& scroller_paint_chunk = paint_chunks[1];
- EXPECT_EQ(IntRect(0, 0, 100, 100), scroller_paint_chunk.bounds);
// The hit test rect for the scroller itself should not be scrolled.
EXPECT_FALSE(scroller_paint_chunk.properties.Transform().ScrollNode());
const auto& scrolled_paint_chunk = paint_chunks[3];
- EXPECT_EQ(IntRect(0, 0, 200, 50), scrolled_paint_chunk.bounds);
// The hit test rect for the scrolled contents should be scrolled.
EXPECT_TRUE(scrolled_paint_chunk.properties.Transform().ScrollNode());
}
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 eace1c00a23..49772004f87 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
@@ -289,20 +289,12 @@ LayoutRectOutsets DoubleStripeInsets(const BorderEdge edges[],
stripe));
}
-float ClampOrRound(float border_width) {
- // Make sure non-zero borders never disappear
- if (border_width > 0.0f && border_width <= 1.0f)
- return 1.0f;
-
- return roundf(border_width);
-}
-
void DrawSolidBorderRect(GraphicsContext& context,
const FloatRect& border_rect,
float border_width,
const Color& color) {
FloatRect stroke_rect(border_rect);
- border_width = ClampOrRound(border_width);
+ border_width = roundf(border_width);
stroke_rect.Inflate(-border_width / 2);
bool was_antialias = context.ShouldAntialias();
@@ -854,7 +846,7 @@ void BoxBorderPainter::PaintSide(GraphicsContext& context,
if (use_path)
path = &border_info.rounded_border_path;
else
- side_rect.SetHeight(ClampOrRound(edge.Width()));
+ side_rect.SetHeight(roundf(edge.Width()));
PaintOneBorderSide(context, side_rect, BoxSide::kTop, BoxSide::kLeft,
BoxSide::kRight, path, border_info.anti_alias, color,
@@ -869,7 +861,7 @@ void BoxBorderPainter::PaintSide(GraphicsContext& context,
if (use_path)
path = &border_info.rounded_border_path;
else
- side_rect.ShiftYEdgeTo(side_rect.MaxY() - ClampOrRound(edge.Width()));
+ side_rect.ShiftYEdgeTo(side_rect.MaxY() - roundf(edge.Width()));
PaintOneBorderSide(context, side_rect, BoxSide::kBottom, BoxSide::kLeft,
BoxSide::kRight, path, border_info.anti_alias, color,
@@ -884,7 +876,7 @@ void BoxBorderPainter::PaintSide(GraphicsContext& context,
if (use_path)
path = &border_info.rounded_border_path;
else
- side_rect.SetWidth(ClampOrRound(edge.Width()));
+ side_rect.SetWidth(roundf(edge.Width()));
PaintOneBorderSide(context, side_rect, BoxSide::kLeft, BoxSide::kTop,
BoxSide::kBottom, path, border_info.anti_alias, color,
@@ -899,7 +891,7 @@ void BoxBorderPainter::PaintSide(GraphicsContext& context,
if (use_path)
path = &border_info.rounded_border_path;
else
- side_rect.ShiftXEdgeTo(side_rect.MaxX() - ClampOrRound(edge.Width()));
+ side_rect.ShiftXEdgeTo(side_rect.MaxX() - roundf(edge.Width()));
PaintOneBorderSide(context, side_rect, BoxSide::kRight, BoxSide::kTop,
BoxSide::kBottom, path, border_info.anti_alias, color,
@@ -1017,9 +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 ? ClampOrRound(adjacent_edge1.Width()) : 0,
- miter2 != kNoMiter ? ClampOrRound(adjacent_edge2.Width()) : 0,
- antialias);
+ miter1 != kNoMiter ? roundf(adjacent_edge1.Width()) : 0,
+ miter2 != kNoMiter ? roundf(adjacent_edge2.Width()) : 0, antialias);
}
}
diff --git a/chromium/third_party/blink/renderer/core/paint/box_model_object_painter.cc b/chromium/third_party/blink/renderer/core/paint/box_model_object_painter.cc
index 20136ea1566..d9462947cb3 100644
--- a/chromium/third_party/blink/renderer/core/paint/box_model_object_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/box_model_object_painter.cc
@@ -124,13 +124,24 @@ LayoutRectOutsets BoxModelObjectPainter::ComputePadding() const {
BoxPainterBase::FillLayerInfo BoxModelObjectPainter::GetFillLayerInfo(
const Color& color,
const FillLayer& bg_layer,
- BackgroundBleedAvoidance bleed_avoidance) const {
+ BackgroundBleedAvoidance bleed_avoidance,
+ bool is_painting_scrolling_background) const {
return BoxPainterBase::FillLayerInfo(
box_model_.GetDocument(), box_model_.StyleRef(),
box_model_.HasOverflowClip(), color, bg_layer, bleed_avoidance,
+ LayoutObject::ShouldRespectImageOrientation(&box_model_),
(flow_box_ ? flow_box_->IncludeLogicalLeftEdge() : true),
(flow_box_ ? flow_box_->IncludeLogicalRightEdge() : true),
- box_model_.IsInline());
+ box_model_.IsLayoutInline(), is_painting_scrolling_background);
+}
+
+bool BoxModelObjectPainter::IsPaintingScrollingBackground(
+ const PaintInfo& paint_info) const {
+ if (!box_model_.IsBox())
+ return false;
+
+ const auto& this_box = ToLayoutBox(box_model_);
+ return BoxDecorationData::IsPaintingScrollingBackground(paint_info, this_box);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/box_model_object_painter.h b/chromium/third_party/blink/renderer/core/paint/box_model_object_painter.h
index eed39f2c998..03f15100911 100644
--- a/chromium/third_party/blink/renderer/core/paint/box_model_object_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/box_model_object_painter.h
@@ -33,7 +33,9 @@ class BoxModelObjectPainter : public BoxPainterBase {
BoxPainterBase::FillLayerInfo GetFillLayerInfo(
const Color&,
const FillLayer&,
- BackgroundBleedAvoidance) const override;
+ BackgroundBleedAvoidance,
+ bool is_painting_scrolling_background) const override;
+ bool IsPaintingScrollingBackground(const PaintInfo&) const override;
void PaintTextClipMask(GraphicsContext&,
const IntRect& mask_rect,
diff --git a/chromium/third_party/blink/renderer/core/paint/box_paint_invalidator.cc b/chromium/third_party/blink/renderer/core/paint/box_paint_invalidator.cc
index 985e5a237f4..53a09c5d9e4 100644
--- a/chromium/third_party/blink/renderer/core/paint/box_paint_invalidator.cc
+++ b/chromium/third_party/blink/renderer/core/paint/box_paint_invalidator.cc
@@ -17,7 +17,7 @@ namespace blink {
bool BoxPaintInvalidator::HasEffectiveBackground() {
// The view can paint background not from the style.
- if (box_.IsLayoutView())
+ if (IsA<LayoutView>(box_))
return true;
return box_.StyleRef().HasBackground() && !box_.BackgroundTransfersToView();
}
@@ -184,27 +184,14 @@ bool BoxPaintInvalidator::BackgroundGeometryDependsOnLayoutOverflowRect() {
bool BoxPaintInvalidator::BackgroundPaintsOntoScrollingContentsLayer() {
if (!HasEffectiveBackground())
return false;
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
- return box_.GetBackgroundPaintLocation() &
- kBackgroundPaintInScrollingContents;
- }
- if (!box_.HasLayer())
- return false;
- if (auto* mapping = box_.Layer()->GetCompositedLayerMapping())
- return mapping->BackgroundPaintsOntoScrollingContentsLayer();
- return false;
+ return box_.GetBackgroundPaintLocation() &
+ kBackgroundPaintInScrollingContents;
}
bool BoxPaintInvalidator::BackgroundPaintsOntoMainGraphicsLayer() {
if (!HasEffectiveBackground())
return false;
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
- return box_.GetBackgroundPaintLocation() & kBackgroundPaintInGraphicsLayer;
- if (!box_.HasLayer())
- return true;
- if (auto* mapping = box_.Layer()->GetCompositedLayerMapping())
- return mapping->BackgroundPaintsOntoGraphicsLayer();
- return true;
+ return box_.GetBackgroundPaintLocation() & kBackgroundPaintInGraphicsLayer;
}
bool BoxPaintInvalidator::ShouldFullyInvalidateBackgroundOnLayoutOverflowChange(
@@ -227,9 +214,9 @@ bool BoxPaintInvalidator::ShouldFullyInvalidateBackgroundOnLayoutOverflowChange(
BoxPaintInvalidator::BackgroundInvalidationType
BoxPaintInvalidator::ComputeViewBackgroundInvalidation() {
- DCHECK(box_.IsLayoutView());
+ DCHECK(IsA<LayoutView>(box_));
- const auto& layout_view = ToLayoutView(box_);
+ const auto& layout_view = To<LayoutView>(box_);
auto new_background_rect = layout_view.BackgroundRect();
auto old_background_rect = layout_view.PreviousBackgroundRect();
layout_view.SetPreviousBackgroundRect(new_background_rect);
@@ -250,18 +237,31 @@ BoxPaintInvalidator::ComputeViewBackgroundInvalidation() {
layout_view.BackgroundNeedsFullPaintInvalidation())
return BackgroundInvalidationType::kFull;
- // LayoutView's non-fixed-attachment background is positioned in the
- // document element and needs to invalidate if the size changes.
- // See: https://drafts.csswg.org/css-backgrounds-3/#root-background.
- if (BackgroundGeometryDependsOnLayoutOverflowRect()) {
- Element* document_element = box_.GetDocument().documentElement();
+ if (Element* document_element = box_.GetDocument().documentElement()) {
if (document_element) {
- const auto* document_background = document_element->GetLayoutObject();
- if (document_background && document_background->IsBox()) {
- const auto* document_background_box = ToLayoutBox(document_background);
- if (ShouldFullyInvalidateBackgroundOnLayoutOverflowChange(
- document_background_box->PreviousPhysicalLayoutOverflowRect(),
- document_background_box->PhysicalLayoutOverflowRect())) {
+ if (const auto* document_element_object =
+ document_element->GetLayoutObject()) {
+ // LayoutView's non-fixed-attachment background is positioned in the
+ // document element and needs to invalidate if the size changes.
+ // See: https://drafts.csswg.org/css-backgrounds-3/#root-background.
+ if (BackgroundGeometryDependsOnLayoutOverflowRect()) {
+ if (document_element_object->IsBox()) {
+ const auto* document_background_box =
+ ToLayoutBox(document_element_object);
+ if (ShouldFullyInvalidateBackgroundOnLayoutOverflowChange(
+ document_background_box
+ ->PreviousPhysicalLayoutOverflowRect(),
+ document_background_box->PhysicalLayoutOverflowRect())) {
+ return BackgroundInvalidationType::kFull;
+ }
+ }
+ }
+
+ // The document background paints with a transform but nevertheless
+ // extended onto an infinite canvas. In cases where it has a transform
+ // we cna't apply incremental invalidation, because the visual rect is
+ // no longer axis-aligned to the LayoutView.
+ if (document_element_object->StyleRef().HasTransform()) {
return BackgroundInvalidationType::kFull;
}
}
@@ -275,16 +275,6 @@ BoxPaintInvalidator::ComputeViewBackgroundInvalidation() {
BoxPaintInvalidator::BackgroundInvalidationType
BoxPaintInvalidator::ComputeBackgroundInvalidation(
bool& should_invalidate_all_layers) {
- // Need to fully invalidate the background on all layers if background paint
- // location changed.
- auto new_background_location = box_.GetBackgroundPaintLocation();
- if (new_background_location != box_.PreviousBackgroundPaintLocation()) {
- should_invalidate_all_layers = true;
- box_.GetMutableForPainting().SetPreviousBackgroundPaintLocation(
- new_background_location);
- return BackgroundInvalidationType::kFull;
- }
-
// If background changed, we may paint the background on different graphics
// layer, so we need to fully invalidate the background on all layers.
if (box_.BackgroundNeedsFullPaintInvalidation()) {
@@ -332,7 +322,7 @@ void BoxPaintInvalidator::InvalidateBackground() {
bool should_invalidate_all_layers = false;
auto background_invalidation_type =
ComputeBackgroundInvalidation(should_invalidate_all_layers);
- if (box_.IsLayoutView()) {
+ if (IsA<LayoutView>(box_)) {
background_invalidation_type = std::max(
background_invalidation_type, ComputeViewBackgroundInvalidation());
}
@@ -394,9 +384,6 @@ bool BoxPaintInvalidator::
if (context_.fragment_data->VisualRect().IsEmpty())
return false;
- if (box_.PaintedOutputOfObjectHasNoEffectRegardlessOfSize())
- return false;
-
const ComputedStyle& style = box_.StyleRef();
// Background and mask layers can depend on other boxes than border box. See
diff --git a/chromium/third_party/blink/renderer/core/paint/box_paint_invalidator_test.cc b/chromium/third_party/blink/renderer/core/paint/box_paint_invalidator_test.cc
index 714a3777769..c6456900950 100644
--- a/chromium/third_party/blink/renderer/core/paint/box_paint_invalidator_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/box_paint_invalidator_test.cc
@@ -8,6 +8,7 @@
#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/layout/layout_view.h"
+#include "third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.h"
#include "third_party/blink/renderer/core/paint/paint_controller_paint_test.h"
#include "third_party/blink/renderer/core/paint/paint_invalidator.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
@@ -18,11 +19,11 @@
namespace blink {
-class BoxPaintInvalidatorTest : public PaintControllerPaintTest {
+using ::testing::UnorderedElementsAre;
+
+class BoxPaintInvalidatorTest : public PaintAndRasterInvalidationTest {
public:
- BoxPaintInvalidatorTest()
- : PaintControllerPaintTest(
- MakeGarbageCollected<SingleChildLocalFrameClient>()) {}
+ BoxPaintInvalidatorTest() = default;
protected:
PaintInvalidationReason ComputePaintInvalidationReason(
@@ -60,6 +61,7 @@ class BoxPaintInvalidatorTest : public PaintControllerPaintTest {
auto& box = *ToLayoutBox(target.GetLayoutObject());
auto visual_rect = box.FirstFragment().VisualRect();
auto paint_offset = box.FirstFragment().PaintOffset();
+ box.SetShouldCheckForPaintInvalidation();
// No geometry change.
EXPECT_EQ(PaintInvalidationReason::kNone,
@@ -68,7 +70,13 @@ class BoxPaintInvalidatorTest : public PaintControllerPaintTest {
target.setAttribute(
html_names::kStyleAttr,
target.getAttribute(html_names::kStyleAttr) + "; width: 200px");
- GetDocument().View()->UpdateLifecycleToCompositingInputsClean();
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
+ } else {
+ GetDocument().View()->UpdateLifecycleToCompositingInputsClean(
+ DocumentUpdateReason::kTest);
+ }
// Simulate that PaintInvalidator updates visual rect.
box.GetMutableForPainting().SetVisualRect(
IntRect(visual_rect.Location(), RoundedIntSize(box.Size())));
@@ -109,7 +117,10 @@ class BoxPaintInvalidatorTest : public PaintControllerPaintTest {
INSTANTIATE_PAINT_TEST_SUITE_P(BoxPaintInvalidatorTest);
-TEST_P(BoxPaintInvalidatorTest, ComputePaintInvalidationReasonPaintingNothing) {
+// Paint invalidation for empty content is needed for updating composited layer
+// bounds for correct composited hit testing. It won't cause raster invalidation
+// (tested in paint_and_raster_invalidation_test.cc).
+TEST_P(BoxPaintInvalidatorTest, ComputePaintInvalidationReasonEmptyContent) {
SetUpHTML();
auto& target = *GetDocument().getElementById("target");
auto& box = *ToLayoutBox(target.GetLayoutObject());
@@ -117,7 +128,7 @@ TEST_P(BoxPaintInvalidatorTest, ComputePaintInvalidationReasonPaintingNothing) {
target.setAttribute(html_names::kClassAttr, "");
UpdateAllLifecyclePhasesForTest();
- EXPECT_TRUE(box.PaintedOutputOfObjectHasNoEffectRegardlessOfSize());
+ box.SetShouldCheckForPaintInvalidation();
auto visual_rect = box.FirstFragment().VisualRect();
// No geometry change.
@@ -126,19 +137,22 @@ TEST_P(BoxPaintInvalidatorTest, ComputePaintInvalidationReasonPaintingNothing) {
ComputePaintInvalidationReason(box, visual_rect, visual_rect.Location()));
// Paint offset change.
- EXPECT_EQ(PaintInvalidationReason::kNone,
- ComputePaintInvalidationReason(
- box, visual_rect, visual_rect.Location() + IntSize(10, 20)));
+ auto old_visual_rect = visual_rect;
+ old_visual_rect.Move(IntSize(10, 20));
+ EXPECT_EQ(PaintInvalidationReason::kGeometry,
+ ComputePaintInvalidationReason(box, old_visual_rect,
+ old_visual_rect.Location()));
// Visual rect size change.
- auto old_visual_rect = visual_rect;
+ old_visual_rect = visual_rect;
target.setAttribute(html_names::kStyleAttr, "width: 200px");
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
// Simulate that PaintInvalidator updates visual rect.
box.GetMutableForPainting().SetVisualRect(
IntRect(visual_rect.Location(), RoundedIntSize(box.Size())));
- EXPECT_EQ(PaintInvalidationReason::kNone,
+ EXPECT_EQ(PaintInvalidationReason::kIncremental,
ComputePaintInvalidationReason(box, old_visual_rect,
old_visual_rect.Location()));
}
@@ -164,7 +178,8 @@ TEST_P(BoxPaintInvalidatorTest, ComputePaintInvalidationReasonBasic) {
// Visual rect size change.
auto old_visual_rect = visual_rect;
target.setAttribute(html_names::kStyleAttr, "background: blue; width: 200px");
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
// Simulate that PaintInvalidator updates visual rect.
box.GetMutableForPainting().SetVisualRect(
IntRect(visual_rect.Location(), RoundedIntSize(box.Size())));
@@ -193,6 +208,27 @@ TEST_P(BoxPaintInvalidatorTest, ComputePaintInvalidationReasonBasic) {
box, visual_rect, visual_rect.Location() + IntSize(10, 20)));
}
+TEST_P(BoxPaintInvalidatorTest,
+ InvalidateLineBoxHitTestOnCompositingStyleChange) {
+ ScopedPaintUnderInvalidationCheckingForTest under_invalidation_checking(true);
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #target {
+ width: 100px;
+ height: 100px;
+ touch-action: none;
+ }
+ </style>
+ <div id="target" style="will-change: transform;">a<br>b</div>
+ )HTML");
+
+ UpdateAllLifecyclePhasesForTest();
+ auto& target = *GetDocument().getElementById("target");
+ target.setAttribute(html_names::kStyleAttr, "");
+ UpdateAllLifecyclePhasesForTest();
+ // This test passes if no underinvalidation occurs.
+}
+
TEST_P(BoxPaintInvalidatorTest, ComputePaintInvalidationReasonOtherCases) {
SetUpHTML();
auto& target = *GetDocument().getElementById("target");
@@ -211,9 +247,6 @@ TEST_P(BoxPaintInvalidatorTest, ComputePaintInvalidationReasonOtherCases) {
target.setAttribute(html_names::kStyleAttr, "filter: blur(5px)");
ExpectFullPaintInvalidationOnGeometryChange("With filter");
- target.setAttribute(html_names::kStyleAttr, "outline: 2px solid blue");
- ExpectFullPaintInvalidationOnGeometryChange("With outline");
-
target.setAttribute(html_names::kStyleAttr, "box-shadow: inset 3px 2px");
ExpectFullPaintInvalidationOnGeometryChange("With box-shadow");
@@ -222,4 +255,50 @@ TEST_P(BoxPaintInvalidatorTest, ComputePaintInvalidationReasonOtherCases) {
ExpectFullPaintInvalidationOnGeometryChange("With clip-path");
}
+TEST_P(BoxPaintInvalidatorTest, ComputePaintInvalidationReasonOutline) {
+ SetUpHTML();
+ auto& target = *GetDocument().getElementById("target");
+ auto* object = target.GetLayoutObject();
+
+ GetDocument().View()->SetTracksRasterInvalidations(true);
+ target.setAttribute(html_names::kStyleAttr, "outline: 2px solid blue;");
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_THAT(GetRasterInvalidationTracking()->Invalidations(),
+ UnorderedElementsAre(RasterInvalidationInfo{
+ object, object->DebugName(), IntRect(0, 0, 72, 142),
+ PaintInvalidationReason::kStyle}));
+ GetDocument().View()->SetTracksRasterInvalidations(false);
+
+ GetDocument().View()->SetTracksRasterInvalidations(true);
+ target.setAttribute(html_names::kStyleAttr,
+ "outline: 2px solid blue; width: 100px;");
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_THAT(GetRasterInvalidationTracking()->Invalidations(),
+ UnorderedElementsAre(RasterInvalidationInfo{
+ object, object->DebugName(), IntRect(0, 0, 122, 142),
+ PaintInvalidationReason::kGeometry}));
+ GetDocument().View()->SetTracksRasterInvalidations(false);
+}
+
+TEST_P(BoxPaintInvalidatorTest, InvalidateHitTestOnCompositingStyleChange) {
+ ScopedPaintUnderInvalidationCheckingForTest under_invalidation_checking(true);
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #target {
+ width: 400px;
+ height: 300px;
+ overflow: hidden;
+ touch-action: none;
+ }
+ </style>
+ <div id="target" style="will-change: transform;"></div>
+ )HTML");
+
+ UpdateAllLifecyclePhasesForTest();
+ auto& target = *GetDocument().getElementById("target");
+ target.setAttribute(html_names::kStyleAttr, "");
+ UpdateAllLifecyclePhasesForTest();
+ // This test passes if no underinvalidation occurs.
+}
+
} // namespace blink
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 56c647e4f24..be14cf89e05 100644
--- a/chromium/third_party/blink/renderer/core/paint/box_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/box_painter.cc
@@ -29,9 +29,7 @@
#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h"
#include "third_party/blink/renderer/platform/graphics/paint/display_item_cache_skipper.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
-#include "third_party/blink/renderer/platform/graphics/paint/hit_test_display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_properties.h"
-#include "third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h"
namespace blink {
@@ -48,9 +46,8 @@ void BoxPainter::PaintChildren(const PaintInfo& paint_info) {
PaintInfo child_info(paint_info);
for (LayoutObject* child = layout_box_.SlowFirstChild(); child;
child = child->NextSibling()) {
- if (child->IsSVGForeignObject()) {
- SVGForeignObjectPainter(ToLayoutSVGForeignObject(*child))
- .PaintLayer(paint_info);
+ if (auto* foreign_object = DynamicTo<LayoutSVGForeignObject>(*child)) {
+ SVGForeignObjectPainter(*foreign_object).PaintLayer(paint_info);
} else {
child->Paint(child_info);
}
@@ -121,20 +118,6 @@ void BoxPainter::PaintBoxDecorationBackground(
RecordScrollHitTestData(paint_info, *background_client);
}
-bool BoxPainter::BackgroundIsKnownToBeOpaque(const PaintInfo& paint_info) {
- // If the box has multiple fragments, its VisualRect is the bounding box of
- // all fragments' visual rects, which is likely to cover areas that are not
- // covered by painted background.
- if (layout_box_.FirstFragment().NextFragment())
- return false;
-
- PhysicalRect bounds =
- BoxDecorationData::IsPaintingScrollingBackground(paint_info, layout_box_)
- ? layout_box_.PhysicalLayoutOverflowRect()
- : layout_box_.PhysicalSelfVisualOverflowRect();
- return layout_box_.BackgroundIsKnownToBeOpaqueInRect(bounds);
-}
-
void BoxPainter::PaintBoxDecorationBackgroundWithRect(
const PaintInfo& paint_info,
const PhysicalRect& paint_rect,
@@ -142,17 +125,9 @@ void BoxPainter::PaintBoxDecorationBackgroundWithRect(
const ComputedStyle& style = layout_box_.StyleRef();
base::Optional<DisplayItemCacheSkipper> cache_skipper;
- // Disable cache in under-invalidation checking mode for MediaSliderPart
- // because we always paint using the latest data (buffered ranges, current
- // time and duration) which may be different from the cached data, and for
- // delayed-invalidation object because it may change before it's actually
- // invalidated. Note that we still report harmless under-invalidation of
- // non-delayed-invalidation animated background, which should be ignored.
if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() &&
- (style.EffectiveAppearance() == kMediaSliderPart ||
- layout_box_.ShouldDelayFullPaintInvalidation())) {
+ BoxPainterBase::ShouldSkipPaintUnderInvalidationChecking(layout_box_))
cache_skipper.emplace(paint_info.context);
- }
BoxDecorationData box_decoration_data(paint_info, layout_box_);
if (!box_decoration_data.ShouldPaint())
@@ -167,11 +142,6 @@ void BoxPainter::PaintBoxDecorationBackgroundWithRect(
DisplayItem::kBoxDecorationBackground);
GraphicsContextStateSaver state_saver(paint_info.context, false);
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
- paint_rect.EdgesOnPixelBoundaries() &&
- BackgroundIsKnownToBeOpaque(paint_info))
- recorder.SetKnownToBeOpaque();
-
bool needs_end_layer = false;
// FIXME: Should eventually give the theme control over whether the box
// shadow should paint, since controls could have custom shadows of their
@@ -293,8 +263,8 @@ void BoxPainter::PaintMaskImages(const PaintInfo& paint_info,
void BoxPainter::RecordHitTestData(const PaintInfo& paint_info,
const PhysicalRect& paint_rect,
const DisplayItemClient& background_client) {
- // Hit test display items are only needed for compositing. This flag is used
- // for for printing and drag images which do not need hit testing.
+ // Hit test data are only needed for compositing. This flag is used for for
+ // printing and drag images which do not need hit testing.
if (paint_info.GetGlobalPaintFlags() & kGlobalPaintFlattenCompositingLayers)
return;
@@ -302,20 +272,19 @@ void BoxPainter::RecordHitTestData(const PaintInfo& paint_info,
if (layout_box_.StyleRef().Visibility() != EVisibility::kVisible)
return;
- auto touch_action = layout_box_.EffectiveAllowedTouchAction();
- if (touch_action == TouchAction::kTouchActionAuto)
+ if (!paint_info.FragmentToPaint(layout_box_))
return;
- HitTestDisplayItem::Record(
- paint_info.context, background_client,
- HitTestRect(paint_rect.ToLayoutRect(), touch_action));
+ paint_info.context.GetPaintController().RecordHitTestData(
+ background_client, PixelSnappedIntRect(paint_rect),
+ layout_box_.EffectiveAllowedTouchAction());
}
void BoxPainter::RecordScrollHitTestData(
const PaintInfo& paint_info,
const DisplayItemClient& background_client) {
- // Hit test display items are only needed for compositing. This flag is used
- // for for printing and drag images which do not need hit testing.
+ // Scroll hit test data are only needed for compositing. This flag is used for
+ // printing and drag images which do not need hit testing.
if (paint_info.GetGlobalPaintFlags() & kGlobalPaintFlattenCompositingLayers)
return;
@@ -334,25 +303,24 @@ void BoxPainter::RecordScrollHitTestData(
if (layout_box_.GetScrollableArea()->ScrollsOverflow()) {
const auto* properties = fragment->PaintProperties();
- // If there is an associated scroll node, emit a scroll hit test display
- // item.
+ // If there is an associated scroll node, emit scroll hit test data.
if (properties && properties->Scroll()) {
DCHECK(properties->ScrollTranslation());
- // The local border box properties are used instead of the contents
- // properties so that the scroll hit test is not clipped or scrolled.
- ScopedPaintChunkProperties scroll_hit_test_properties(
- paint_info.context.GetPaintController(),
- fragment->LocalBorderBoxProperties(), background_client,
- DisplayItem::kScrollHitTest);
- ScrollHitTestDisplayItem::Record(
- paint_info.context, background_client, DisplayItem::kScrollHitTest,
+ // We record scroll hit test data in the local border box properties
+ // instead of the contents properties so that the scroll hit test is not
+ // clipped or scrolled.
+ auto& paint_controller = paint_info.context.GetPaintController();
+ DCHECK_EQ(fragment->LocalBorderBoxProperties(),
+ paint_controller.CurrentPaintChunkProperties());
+ paint_controller.RecordScrollHitTestData(
+ background_client, DisplayItem::kScrollHitTest,
properties->ScrollTranslation(), fragment->VisualRect());
}
}
ScrollableAreaPainter(*layout_box_.GetScrollableArea())
- .RecordResizerScrollHitTestData(
- paint_info.context, fragment->PaintOffset(), background_client);
+ .RecordResizerScrollHitTestData(paint_info.context,
+ fragment->PaintOffset());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/box_painter.h b/chromium/third_party/blink/renderer/core/paint/box_painter.h
index 0b79434cf20..18322986bea 100644
--- a/chromium/third_party/blink/renderer/core/paint/box_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/box_painter.h
@@ -38,21 +38,19 @@ class BoxPainter {
const PhysicalRect&,
const DisplayItemClient& background_client);
- // Paint a hit test display item and record hit test data. This should be
- // called in the background paint phase even if there is no other painted
- // content.
+ // Expands the bounds of the current paint chunk for hit test, and records
+ // special touch action if any. This should be called in the background paint
+ // phase even if there is no other painted content.
void RecordHitTestData(const PaintInfo&,
const PhysicalRect& paint_rect,
const DisplayItemClient& background_client);
- // Paint a scroll hit test display item and record scroll hit test data. This
- // should be called in the background paint phase even if there is no other
- // painted content.
+ // This should be called in the background paint phase even if there is no
+ // other painted content.
void RecordScrollHitTestData(const PaintInfo&,
const DisplayItemClient& background_client);
private:
- bool BackgroundIsKnownToBeOpaque(const PaintInfo&);
void PaintBackground(const PaintInfo&,
const PhysicalRect&,
const Color& background_color,
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 597dbee509e..660f62adc5b 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
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
+#include "third_party/blink/renderer/core/layout/layout_progress.h"
#include "third_party/blink/renderer/core/paint/background_image_geometry.h"
#include "third_party/blink/renderer/core/paint/box_border_painter.h"
#include "third_party/blink/renderer/core/paint/image_element_timing.h"
@@ -22,6 +23,7 @@
#include "third_party/blink/renderer/core/style/shadow_list.h"
#include "third_party/blink/renderer/core/style/style_fetched_image.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
+#include "third_party/blink/renderer/platform/graphics/bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
#include "third_party/blink/renderer/platform/graphics/scoped_interpolation_quality.h"
@@ -274,11 +276,14 @@ BoxPainterBase::FillLayerInfo::FillLayerInfo(
Color bg_color,
const FillLayer& layer,
BackgroundBleedAvoidance bleed_avoidance,
+ RespectImageOrientationEnum respect_image_orientation,
bool include_left,
bool include_right,
- bool is_inline)
+ bool is_inline,
+ bool is_painting_scrolling_background)
: image(layer.GetImage()),
color(bg_color),
+ respect_image_orientation(respect_image_orientation),
include_left_edge(include_left),
include_right_edge(include_right),
is_bottom_layer(!layer.Next()),
@@ -315,7 +320,7 @@ BoxPainterBase::FillLayerInfo::FillLayerInfo(
// BorderFillBox radius clipping is taken care of by
// BackgroundBleedClip{Only,Layer}
is_rounded_fill =
- has_rounded_border &&
+ has_rounded_border && !is_painting_scrolling_background &&
!(is_border_fill && BleedAvoidanceIsClipping(bleed_avoidance));
should_paint_image = image && image->CanRender();
@@ -369,6 +374,25 @@ FloatRect ComputeSubsetForBackground(const FloatRect& phase_and_size,
subset.Height() / scale.Height());
}
+FloatRect SnapSourceRectIfNearIntegral(const FloatRect src_rect) {
+ // Round to avoid filtering pulling in neighboring pixels, for the
+ // common case of sprite maps, but only if we're close to an integral size.
+ // "Close" in this context means we will allow floating point inaccuracy,
+ // when converted to layout units, to be at most one LayoutUnit::Epsilon and
+ // still snap.
+ if (std::abs(std::round(src_rect.X()) - src_rect.X()) <=
+ LayoutUnit::Epsilon() &&
+ std::abs(std::round(src_rect.Y()) - src_rect.Y()) <=
+ LayoutUnit::Epsilon() &&
+ std::abs(std::round(src_rect.MaxX()) - src_rect.MaxX()) <=
+ LayoutUnit::Epsilon() &&
+ std::abs(std::round(src_rect.MaxY()) - src_rect.MaxY()) <=
+ LayoutUnit::Epsilon()) {
+ return FloatRect(RoundedIntRect(src_rect));
+ }
+ return src_rect;
+}
+
// The unsnapped_subset_size should be the target painting area implied by the
// content, without any snapping applied. It is necessary to correctly
// compute the subset of the source image to paint into the destination.
@@ -385,14 +409,21 @@ void DrawTiledBackground(GraphicsContext& context,
const FloatSize& tile_size,
SkBlendMode op,
const FloatSize& repeat_spacing,
- bool has_filter_property) {
+ bool has_filter_property,
+ RespectImageOrientationEnum respect_orientation) {
DCHECK(!tile_size.IsEmpty());
// Use the intrinsic size of the image if it has one, otherwise force the
// generated image to be the tile size.
FloatSize intrinsic_tile_size(image->Size());
FloatSize scale(1, 1);
- if (!image->HasIntrinsicSize()) {
+ if (!image->HasIntrinsicSize() ||
+ // TODO(crbug.com/1042783): This is not checking for real empty image
+ // (for which we have checked and skipped the whole FillLayer), but for
+ // that a subpixel image size is rounded to empty, to avoid infinite tile
+ // scale that would be calculated in the |else| part.
+ // We should probably support subpixel size here.
+ intrinsic_tile_size.IsEmpty()) {
intrinsic_tile_size = tile_size;
} else {
scale = FloatSize(tile_size.Width() / intrinsic_tile_size.Width(),
@@ -412,26 +443,48 @@ void DrawTiledBackground(GraphicsContext& context,
if (one_tile_rect.Contains(dest_rect_for_subset)) {
FloatRect visible_src_rect = ComputeSubsetForBackground(
one_tile_rect, dest_rect_for_subset, intrinsic_tile_size);
- // Round to avoid filtering pulling in neighboring pixels, for the
- // common case of sprite maps.
- // TODO(schenney): Snapping at this level is a problem for cases where we
- // might be animating background-position to pan over an image. Ideally we
- // would either snap only if close to integral, or move snapping
- // calculations up the stack.
- visible_src_rect = FloatRect(RoundedIntRect(visible_src_rect));
+ visible_src_rect = SnapSourceRectIfNearIntegral(visible_src_rect);
+
+ // When respecting image orientation, the drawing code expects the source
+ // rect to be in the unrotated image space, but we have computed it here in
+ // the rotated space in order to position and size the background. Undo the
+ // src rect rotation if necessary.
+ if (respect_orientation && !image->HasDefaultOrientation()) {
+ visible_src_rect = image->CorrectSrcRectForImageOrientation(
+ visible_src_rect.Size(), visible_src_rect);
+ }
+
context.DrawImage(image, Image::kSyncDecode, snapped_paint_rect,
&visible_src_rect, has_filter_property, op,
- kDoNotRespectImageOrientation);
+ respect_orientation);
return;
}
+ // At this point we have decided to tile the image to fill the dest rect.
// Note that this tile rect the image's pre-scaled size.
FloatRect tile_rect(FloatPoint(), intrinsic_tile_size);
+
+ // Farther down the pipeline we will use the scaled tile size to determine
+ // which dimensions to clamp or repeat in. We do not want to repeat when the
+ // tile size rounds to match the dest in a given dimension, to avoid having
+ // a single row or column repeated when the developer almost certainly
+ // intended the image to not repeat (this generally occurs under zoom).
+ //
+ // So detect when we do not want to repeat and set the scale to round the
+ // values in that dimension.
+ if (fabs(tile_size.Width() - snapped_paint_rect.Width()) <= 0.5) {
+ scale.SetWidth(snapped_paint_rect.Width() / intrinsic_tile_size.Width());
+ }
+ if (fabs(tile_size.Height() - snapped_paint_rect.Height()) <= 0.5) {
+ scale.SetHeight(snapped_paint_rect.Height() / intrinsic_tile_size.Height());
+ }
+
// This call takes the unscaled image, applies the given scale, and paints
// it into the snapped_dest_rect using phase from one_tile_rect and the
// given repeat spacing. Note the phase is already scaled.
context.DrawImageTiled(image, snapped_paint_rect, tile_rect, scale,
- one_tile_rect.Location(), repeat_spacing, op);
+ one_tile_rect.Location(), repeat_spacing, op,
+ respect_orientation);
}
inline bool PaintFastBottomLayer(Node* node,
@@ -528,7 +581,10 @@ inline bool PaintFastBottomLayer(Node* node,
// intrinsic size is the requested tile size.
bool has_intrinsic_size = image->HasIntrinsicSize();
const FloatSize intrinsic_tile_size =
- !has_intrinsic_size ? image_tile.Size() : FloatSize(image->Size());
+ !has_intrinsic_size
+ ? image_tile.Size()
+ : FloatSize(image->Size(info.respect_image_orientation));
+
// Subset computation needs the same location as was used with
// ComputePhaseForBackground above, but needs the unsnapped destination
// size to correctly calculate sprite subsets in the presence of zoom. But if
@@ -544,12 +600,21 @@ inline bool PaintFastBottomLayer(Node* node,
// from integer size, so it is safe to round without introducing major issues.
const FloatRect unrounded_subset = ComputeSubsetForBackground(
image_tile, dest_rect_for_subset, intrinsic_tile_size);
- FloatRect src_rect = FloatRect(RoundedIntRect(unrounded_subset));
+ FloatRect src_rect = SnapSourceRectIfNearIntegral(unrounded_subset);
- // If we have rounded the image size to 0, revert the rounding.
+ // If we have snapped the image size to 0, revert the rounding.
if (src_rect.IsEmpty())
src_rect = unrounded_subset;
+ // When respecting image orientation, the drawing code expects the source rect
+ // to be in the unrotated image space, but we have computed it here in the
+ // rotated space in order to position and size the background. Undo the src
+ // rect rotation if necessaary.
+ if (info.respect_image_orientation && !image->HasDefaultOrientation()) {
+ src_rect =
+ image->CorrectSrcRectForImageOrientation(src_rect.Size(), src_rect);
+ }
+
TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage",
"data",
inspector_paint_image_event::Data(
@@ -561,19 +626,21 @@ inline bool PaintFastBottomLayer(Node* node,
context.DrawImageRRect(
image, Image::kSyncDecode, image_border, src_rect,
node && node->ComputedStyleRef().HasFilterInducingProperty(),
- composite_op);
+ composite_op, info.respect_image_orientation);
if (info.image && info.image->IsImageResource()) {
PaintTimingDetector::NotifyBackgroundImagePaint(
- node, image, To<StyleFetchedImage>(info.image.Get()),
- paint_info.context.GetPaintController().CurrentPaintChunkProperties());
+ node, image, To<StyleFetchedImage>(info.image),
+ paint_info.context.GetPaintController().CurrentPaintChunkProperties(),
+ RoundedIntRect(image_border.Rect()));
}
if (node && info.image && info.image->IsImageResource()) {
LocalDOMWindow* window = node->GetDocument().domWindow();
DCHECK(window);
ImageElementTiming::From(*window).NotifyBackgroundImagePainted(
- node, To<StyleFetchedImage>(info.image.Get()),
- context.GetPaintController().CurrentPaintChunkProperties());
+ node, To<StyleFetchedImage>(info.image),
+ context.GetPaintController().CurrentPaintChunkProperties(),
+ RoundedIntRect(image_border.Rect()));
}
return true;
}
@@ -691,18 +758,21 @@ void PaintFillLayerBackground(GraphicsContext& context,
FloatRect(geometry.SnappedDestRect()), geometry.Phase(),
FloatSize(geometry.TileSize()), composite_op,
FloatSize(geometry.SpaceSize()),
- node && node->ComputedStyleRef().HasFilterInducingProperty());
+ node && node->ComputedStyleRef().HasFilterInducingProperty(),
+ info.respect_image_orientation);
if (info.image && info.image->IsImageResource()) {
PaintTimingDetector::NotifyBackgroundImagePaint(
- node, image, To<StyleFetchedImage>(info.image.Get()),
- context.GetPaintController().CurrentPaintChunkProperties());
+ node, image, To<StyleFetchedImage>(info.image),
+ context.GetPaintController().CurrentPaintChunkProperties(),
+ EnclosingIntRect(geometry.SnappedDestRect()));
}
if (node && info.image && info.image->IsImageResource()) {
LocalDOMWindow* window = node->GetDocument().domWindow();
DCHECK(window);
ImageElementTiming::From(*window).NotifyBackgroundImagePainted(
- node, To<StyleFetchedImage>(info.image.Get()),
- context.GetPaintController().CurrentPaintChunkProperties());
+ node, To<StyleFetchedImage>(info.image),
+ context.GetPaintController().CurrentPaintChunkProperties(),
+ EnclosingIntRect(geometry.SnappedDestRect()));
}
}
}
@@ -743,7 +813,9 @@ void BoxPainterBase::PaintFillLayer(const PaintInfo& paint_info,
if (rect.IsEmpty())
return;
- const FillLayerInfo info = GetFillLayerInfo(color, bg_layer, bleed_avoidance);
+ const FillLayerInfo info =
+ GetFillLayerInfo(color, bg_layer, bleed_avoidance,
+ IsPaintingScrollingBackground(paint_info));
// If we're not actually going to paint anything, abort early.
if (!info.should_paint_image && !info.should_paint_color)
return;
@@ -913,4 +985,31 @@ void BoxPainterBase::PaintMaskImages(const PaintInfo& paint_info,
include_logical_right_edge);
}
+bool BoxPainterBase::ShouldSkipPaintUnderInvalidationChecking(
+ const LayoutBox& box) {
+ DCHECK(RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled());
+
+ // Disable paint under-invalidation checking for cases that under-invalidation
+ // is intensional and/or harmless.
+
+ // A box having delayed-invalidation may change before it's actually
+ // invalidated. Note that we still report harmless under-invalidation of
+ // non-delayed-invalidation animated background, which should be ignored.
+ if (box.ShouldDelayFullPaintInvalidation())
+ return true;
+
+ // We always paint a MediaSliderPart using the latest data (buffered ranges,
+ // current time and duration) which may be different from the cached data.
+ if (box.StyleRef().EffectiveAppearance() == kMediaSliderPart)
+ return true;
+
+ // We paint an indeterminate progress based on the position calculated from
+ // the animation progress. Harmless under-invalidatoin may happen during a
+ // paint that is not scheduled for animation.
+ if (box.IsProgress() && !ToLayoutProgress(box).IsDeterminate())
+ return true;
+
+ return false;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/box_painter_base.h b/chromium/third_party/blink/renderer/core/paint/box_painter_base.h
index 146d65ceb78..7b5bbf22c58 100644
--- a/chromium/third_party/blink/renderer/core/paint/box_painter_base.h
+++ b/chromium/third_party/blink/renderer/core/paint/box_painter_base.h
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/core/style/style_image.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect_outsets.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
+#include "third_party/blink/renderer/platform/graphics/image_orientation.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/skia/include/core/SkBlendMode.h"
@@ -23,6 +24,7 @@ class FloatRoundedRect;
class GraphicsContext;
class ImageResourceObserver;
class IntRect;
+class LayoutBox;
struct PaintInfo;
struct PhysicalOffset;
struct PhysicalRect;
@@ -102,6 +104,8 @@ class BoxPainterBase {
FillLayerOcclusionOutputList& reversed_paint_list,
const FillLayer&);
+ static bool ShouldSkipPaintUnderInvalidationChecking(const LayoutBox&);
+
struct FillLayerInfo {
STACK_ALLOCATED();
@@ -112,16 +116,19 @@ class BoxPainterBase {
Color bg_color,
const FillLayer&,
BackgroundBleedAvoidance,
+ RespectImageOrientationEnum,
bool include_left_edge,
bool include_right_edge,
- bool is_inline);
+ bool is_inline,
+ bool is_painting_scrolling_background);
// FillLayerInfo is a temporary, stack-allocated container which cannot
// outlive the StyleImage. This would normally be a raw pointer, if not for
// the Oilpan tooling complaints.
- Member<StyleImage> image;
+ StyleImage* image;
Color color;
+ RespectImageOrientationEnum respect_image_orientation;
bool include_left_edge;
bool include_right_edge;
bool is_bottom_layer;
@@ -152,9 +159,12 @@ class BoxPainterBase {
virtual PhysicalRect AdjustRectForScrolledContent(const PaintInfo&,
const FillLayerInfo&,
const PhysicalRect&) = 0;
- virtual FillLayerInfo GetFillLayerInfo(const Color&,
- const FillLayer&,
- BackgroundBleedAvoidance) const = 0;
+ virtual FillLayerInfo GetFillLayerInfo(
+ const Color&,
+ const FillLayer&,
+ BackgroundBleedAvoidance,
+ bool is_painting_scrolling_background) const = 0;
+ virtual bool IsPaintingScrollingBackground(const PaintInfo&) const = 0;
static void PaintInsetBoxShadow(const PaintInfo&,
const FloatRoundedRect&,
const ComputedStyle&,
@@ -162,9 +172,9 @@ class BoxPainterBase {
bool include_logical_right_edge = true);
private:
- Member<const Document> document_;
+ const Document* document_;
const ComputedStyle& style_;
- Member<Node> node_;
+ Node* node_;
};
} // namespace blink
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 d651e69e97d..5a929df6094 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
@@ -7,7 +7,6 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
#include "third_party/blink/renderer/core/paint/paint_controller_paint_test.h"
-#include "third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h"
using testing::ElementsAre;
@@ -17,30 +16,50 @@ using BoxPainterTest = PaintControllerPaintTest;
INSTANTIATE_PAINT_TEST_SUITE_P(BoxPainterTest);
-TEST_P(BoxPainterTest, DontPaintEmptyDecorationBackground) {
+TEST_P(BoxPainterTest, EmptyDecorationBackground) {
SetBodyInnerHTML(R"HTML(
+ <style>
+ body {
+ margin: 0;
+ /* to force a subsequene and paint chunk */
+ opacity: 0.5;
+ /* to verify child empty backgrounds expand chunk bounds */
+ height: 0;
+ }
+ </style>
<div id="div1" style="width: 100px; height: 100px; background: green">
</div>
<div id="div2" style="width: 100px; height: 100px; outline: 2px solid blue">
</div>
+ <div id="div3" style="width: 200px; height: 150px"></div>
)HTML");
auto* div1 = GetLayoutObjectByElementId("div1");
auto* div2 = GetLayoutObjectByElementId("div2");
+ auto* body = GetDocument().body()->GetLayoutBox();
+ // Empty backgrounds don't generate display items.
EXPECT_THAT(RootPaintController().GetDisplayItemList(),
ElementsAre(IsSameId(&ViewScrollingBackgroundClient(),
kDocumentBackgroundType),
IsSameId(div1, kBackgroundType),
IsSameId(div2, DisplayItem::PaintPhaseToDrawingType(
PaintPhase::kSelfOutlineOnly))));
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(
+ IsPaintChunk(0, 1,
+ PaintChunk::Id(ViewScrollingBackgroundClient(),
+ kDocumentBackgroundType),
+ GetLayoutView().FirstFragment().ContentsProperties(),
+ nullptr, IntRect(0, 0, 800, 600)),
+ // Empty backgrounds contribute to bounds of paint chunks.
+ IsPaintChunk(1, 3,
+ PaintChunk::Id(*body->Layer(), DisplayItem::kLayerChunk),
+ body->FirstFragment().LocalBorderBoxProperties(),
+ nullptr, IntRect(-2, 0, 202, 350))));
}
-using BoxPainterScrollHitTestTest = PaintControllerPaintTest;
-
-INSTANTIATE_SCROLL_HIT_TEST_SUITE_P(BoxPainterScrollHitTestTest);
-
-TEST_P(BoxPainterScrollHitTestTest,
- ScrollHitTestOrderWithScrollBackgroundAttachment) {
+TEST_P(BoxPainterTest, ScrollHitTestOrderWithScrollBackgroundAttachment) {
SetBodyInnerHTML(R"HTML(
<style>
::-webkit-scrollbar { display: none; }
@@ -60,7 +79,7 @@ TEST_P(BoxPainterScrollHitTestTest,
</div>
)HTML");
- auto& container = *GetLayoutObjectByElementId("container");
+ auto& container = ToLayoutBox(*GetLayoutObjectByElementId("container"));
auto& child = *GetLayoutObjectByElementId("child");
// As a reminder, "background-attachment: scroll" does not move when the
@@ -74,11 +93,29 @@ TEST_P(BoxPainterScrollHitTestTest,
ElementsAre(IsSameId(&ViewScrollingBackgroundClient(),
kDocumentBackgroundType),
IsSameId(&container, kBackgroundType),
- IsSameId(&container, kScrollHitTestType),
IsSameId(&child, kBackgroundType)));
+ HitTestData scroll_hit_test;
+ scroll_hit_test.scroll_translation =
+ &container.FirstFragment().ContentsProperties().Transform();
+ scroll_hit_test.scroll_hit_test_rect = IntRect(0, 0, 200, 200);
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(
+ IsPaintChunk(0, 1,
+ PaintChunk::Id(ViewScrollingBackgroundClient(),
+ kDocumentBackgroundType),
+ GetLayoutView().FirstFragment().ContentsProperties()),
+ IsPaintChunk(
+ 1, 2,
+ PaintChunk::Id(*container.Layer(), DisplayItem::kLayerChunk),
+ container.FirstFragment().LocalBorderBoxProperties()),
+ IsPaintChunk(2, 2,
+ PaintChunk::Id(container, DisplayItem::kScrollHitTest),
+ container.FirstFragment().LocalBorderBoxProperties(),
+ &scroll_hit_test, IntRect(0, 0, 200, 200)),
+ IsPaintChunk(2, 3)));
} else {
- // Because the frame composited scrolls, no scroll hit test display item is
- // needed.
+ // Because the frame composited scrolls, no scroll hit test is needed.
const auto* non_scrolling_layer = To<LayoutBlock>(container)
.Layer()
->GetCompositedLayerMapping()
@@ -94,8 +131,7 @@ TEST_P(BoxPainterScrollHitTestTest,
}
}
-TEST_P(BoxPainterScrollHitTestTest,
- ScrollHitTestOrderWithLocalBackgroundAttachment) {
+TEST_P(BoxPainterTest, ScrollHitTestOrderWithLocalBackgroundAttachment) {
SetBodyInnerHTML(R"HTML(
<style>
::-webkit-scrollbar { display: none; }
@@ -131,12 +167,32 @@ TEST_P(BoxPainterScrollHitTestTest,
RootPaintController().GetDisplayItemList(),
ElementsAre(
IsSameId(&ViewScrollingBackgroundClient(), kDocumentBackgroundType),
- IsSameId(&container, kScrollHitTestType),
IsSameId(container_scrolling_client, kBackgroundType),
IsSameId(&child, kBackgroundType)));
+ HitTestData scroll_hit_test;
+ scroll_hit_test.scroll_translation =
+ &container.FirstFragment().ContentsProperties().Transform();
+ scroll_hit_test.scroll_hit_test_rect = IntRect(0, 0, 200, 200);
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(
+ IsPaintChunk(0, 1,
+ PaintChunk::Id(ViewScrollingBackgroundClient(),
+ kDocumentBackgroundType),
+ GetLayoutView().FirstFragment().ContentsProperties()),
+ IsPaintChunk(
+ 1, 1,
+ PaintChunk::Id(*container.Layer(), DisplayItem::kLayerChunk),
+ container.FirstFragment().LocalBorderBoxProperties()),
+ IsPaintChunk(1, 1,
+ PaintChunk::Id(container, DisplayItem::kScrollHitTest),
+ container.FirstFragment().LocalBorderBoxProperties(),
+ &scroll_hit_test, IntRect(0, 0, 200, 200)),
+ IsPaintChunk(
+ 1, 3, PaintChunk::Id(container, kScrollingBackgroundChunkType),
+ container.FirstFragment().ContentsProperties())));
} else {
- // Because the frame composited scrolls, no scroll hit test display item is
- // needed.
+ // Because the frame composited scrolls, no scroll hit test is needed.
const auto* non_scrolling_layer =
container.Layer()->GetCompositedLayerMapping()->MainGraphicsLayer();
EXPECT_TRUE(non_scrolling_layer->GetPaintController()
@@ -152,12 +208,7 @@ TEST_P(BoxPainterScrollHitTestTest,
}
}
-TEST_P(BoxPainterScrollHitTestTest, ScrollHitTestProperties) {
- // This test depends on the CompositeAfterPaint behavior of painting solid
- // color backgrounds into both the non-scrolled and scrolled spaces.
- if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
- return;
-
+TEST_P(BoxPainterTest, ScrollHitTestProperties) {
SetBodyInnerHTML(R"HTML(
<style>
::-webkit-scrollbar { display: none; }
@@ -183,23 +234,22 @@ TEST_P(BoxPainterScrollHitTestTest, ScrollHitTestProperties) {
// scrolled contents.
EXPECT_EQ(
kBackgroundPaintInGraphicsLayer | kBackgroundPaintInScrollingContents,
- container.GetBackgroundPaintLocation());
+ container.ComputeBackgroundPaintLocationIfComposited());
+ EXPECT_EQ(kBackgroundPaintInGraphicsLayer,
+ container.GetBackgroundPaintLocation());
EXPECT_THAT(
RootPaintController().GetDisplayItemList(),
ElementsAre(
IsSameId(&ViewScrollingBackgroundClient(), kDocumentBackgroundType),
IsSameId(&container, kBackgroundType),
- IsSameId(&container, kScrollHitTestType),
- IsSameId(&container.GetScrollableArea()
- ->GetScrollingBackgroundDisplayItemClient(),
- kBackgroundType),
IsSameId(&child, kBackgroundType)));
HitTestData scroll_hit_test_data;
const auto& scrolling_contents_properties =
container.FirstFragment().ContentsProperties();
- scroll_hit_test_data.SetScrollHitTest(
- &scrolling_contents_properties.Transform(), IntRect(0, 0, 200, 200));
+ scroll_hit_test_data.scroll_translation =
+ &scrolling_contents_properties.Transform();
+ scroll_hit_test_data.scroll_hit_test_rect = IntRect(0, 0, 200, 200);
EXPECT_THAT(
paint_chunks,
ElementsAre(
@@ -207,16 +257,18 @@ TEST_P(BoxPainterScrollHitTestTest, ScrollHitTestProperties) {
PaintChunk::Id(ViewScrollingBackgroundClient(),
kDocumentBackgroundType),
GetLayoutView().FirstFragment().ContentsProperties()),
- IsPaintChunk(1, 2,
- PaintChunk::Id(*container.Layer(),
- kNonScrollingBackgroundChunkType),
- container.FirstFragment().LocalBorderBoxProperties()),
- IsPaintChunk(2, 3, PaintChunk::Id(container, kScrollHitTestType),
+ IsPaintChunk(
+ 1, 2,
+ PaintChunk::Id(*container.Layer(), DisplayItem::kLayerChunk),
+ container.FirstFragment().LocalBorderBoxProperties()),
+ IsPaintChunk(2, 2,
+ PaintChunk::Id(container, DisplayItem::kScrollHitTest),
container.FirstFragment().LocalBorderBoxProperties(),
- scroll_hit_test_data),
- IsPaintChunk(3, 5,
- PaintChunk::Id(container, kScrollingBackgroundChunkType),
- scrolling_contents_properties)));
+ &scroll_hit_test_data, IntRect(0, 0, 200, 200)),
+ IsPaintChunk(
+ 2, 3,
+ PaintChunk::Id(container, kClippedContentsBackgroundChunkType),
+ scrolling_contents_properties)));
// We always create scroll node for the root layer.
const auto& root_transform = paint_chunks[0].properties.Transform();
@@ -237,25 +289,23 @@ TEST_P(BoxPainterScrollHitTestTest, ScrollHitTestProperties) {
EXPECT_EQ(nullptr, scroll_hit_test_transform.ScrollNode());
EXPECT_EQ(&root_transform, scroll_hit_test_transform.Parent());
const auto& scroll_hit_test_clip = scroll_hit_test_chunk.properties.Clip();
- EXPECT_EQ(FloatRect(0, 0, 800, 600), scroll_hit_test_clip.ClipRect().Rect());
+ EXPECT_EQ(FloatRect(0, 0, 800, 600),
+ scroll_hit_test_clip.UnsnappedClipRect().Rect());
// The scrolled contents should be scrolled and clipped.
- const auto& contents_chunk = RootPaintController().PaintChunks()[3];
+ const auto& contents_chunk = paint_chunks[3];
const auto& contents_transform = contents_chunk.properties.Transform();
const auto* contents_scroll = contents_transform.ScrollNode();
EXPECT_EQ(IntSize(200, 300), contents_scroll->ContentsSize());
EXPECT_EQ(IntRect(0, 0, 200, 200), contents_scroll->ContainerRect());
const auto& contents_clip = contents_chunk.properties.Clip();
- EXPECT_EQ(FloatRect(0, 0, 200, 200), contents_clip.ClipRect().Rect());
+ EXPECT_EQ(FloatRect(0, 0, 200, 200),
+ contents_clip.UnsnappedClipRect().Rect());
- // The scroll hit test display item maintains a reference to a scroll offset
- // translation node and the contents should be scrolled by this node.
- const auto& scroll_hit_test_display_item =
- static_cast<const ScrollHitTestDisplayItem&>(
- RootPaintController()
- .GetDisplayItemList()[scroll_hit_test_chunk.begin_index]);
+ // The scroll paint chunk maintains a reference to a scroll translation node
+ // and the contents should be scrolled by this node.
EXPECT_EQ(&contents_transform,
- scroll_hit_test_display_item.scroll_offset_node());
+ scroll_hit_test_chunk.hit_test_data->scroll_translation);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/clip_path_clipper.cc b/chromium/third_party/blink/renderer/core/paint/clip_path_clipper.cc
index 9e1eed19de9..2091d948454 100644
--- a/chromium/third_party/blink/renderer/core/paint/clip_path_clipper.cc
+++ b/chromium/third_party/blink/renderer/core/paint/clip_path_clipper.cc
@@ -25,22 +25,6 @@ namespace blink {
namespace {
-class SVGClipExpansionCycleHelper {
- public:
- void Lock(LayoutSVGResourceClipper& clipper) {
- DCHECK(!clipper.HasCycle());
- clipper.BeginClipExpansion();
- clippers_.push_back(&clipper);
- }
- ~SVGClipExpansionCycleHelper() {
- for (auto* clipper : clippers_)
- clipper->EndClipExpansion();
- }
-
- private:
- Vector<LayoutSVGResourceClipper*, 1> clippers_;
-};
-
LayoutSVGResourceClipper* ResolveElementReference(
const LayoutObject& layout_object,
const ReferenceClipPathOperation& reference_clip_path_operation) {
@@ -65,7 +49,7 @@ LayoutSVGResourceClipper* ResolveElementReference(
FloatRect ClipPathClipper::LocalReferenceBox(const LayoutObject& object) {
if (object.IsSVGChild())
- return object.ObjectBoundingBox();
+ return SVGResources::ReferenceBoxForEffects(object);
if (object.IsBox())
return FloatRect(ToLayoutBox(object).BorderBoxRect());
@@ -127,17 +111,17 @@ static bool IsClipPathOperationValid(
return false;
SECURITY_DCHECK(!resource_clipper->NeedsLayout());
resource_clipper->ClearInvalidationMask();
- if (resource_clipper->HasCycle())
- return false;
}
return true;
}
ClipPathClipper::ClipPathClipper(GraphicsContext& context,
const LayoutObject& layout_object,
+ const DisplayItemClient& display_item_client,
const PhysicalOffset& paint_offset)
: context_(context),
layout_object_(layout_object),
+ display_item_client_(display_item_client),
paint_offset_(paint_offset) {
DCHECK(layout_object.StyleRef().ClipPath());
}
@@ -166,20 +150,20 @@ ClipPathClipper::~ClipPathClipper() {
return;
ScopedPaintChunkProperties scoped_properties(
context_.GetPaintController(),
- layout_object_.FirstFragment().ClipPathProperties(), layout_object_,
+ layout_object_.FirstFragment().ClipPathProperties(), display_item_client_,
DisplayItem::kSVGClip);
bool is_svg_child = layout_object_.IsSVGChild();
FloatRect reference_box = LocalReferenceBox(layout_object_);
- if (DrawingRecorder::UseCachedDrawingIfPossible(context_, layout_object_,
- DisplayItem::kSVGClip))
+ if (DrawingRecorder::UseCachedDrawingIfPossible(
+ context_, display_item_client_, DisplayItem::kSVGClip))
return;
- DrawingRecorder recorder(context_, layout_object_, DisplayItem::kSVGClip);
+ DrawingRecorder recorder(context_, display_item_client_,
+ DisplayItem::kSVGClip);
context_.Save();
context_.Translate(paint_offset_.left, paint_offset_.top);
- SVGClipExpansionCycleHelper locks;
bool is_first = true;
bool rest_of_the_chain_already_appled = false;
const LayoutObject* current_object = &layout_object_;
@@ -201,7 +185,6 @@ ClipPathClipper::~ClipPathClipper() {
// because it would have been applied as path-based clip already.
DCHECK(resource_clipper);
DCHECK_EQ(clip_path->GetType(), ClipPathOperation::REFERENCE);
- locks.Lock(*resource_clipper);
if (resource_clipper->StyleRef().ClipPath()) {
// Try to apply nested clip-path as path-based clip.
bool unused;
diff --git a/chromium/third_party/blink/renderer/core/paint/clip_path_clipper.h b/chromium/third_party/blink/renderer/core/paint/clip_path_clipper.h
index c852040eb9a..a52caedba03 100644
--- a/chromium/third_party/blink/renderer/core/paint/clip_path_clipper.h
+++ b/chromium/third_party/blink/renderer/core/paint/clip_path_clipper.h
@@ -13,6 +13,7 @@
namespace blink {
+class DisplayItemClient;
class GraphicsContext;
class LayoutObject;
@@ -22,6 +23,7 @@ class CORE_EXPORT ClipPathClipper {
public:
ClipPathClipper(GraphicsContext&,
const LayoutObject&,
+ const DisplayItemClient&,
const PhysicalOffset& paint_offset);
~ClipPathClipper();
@@ -52,6 +54,7 @@ class CORE_EXPORT ClipPathClipper {
private:
GraphicsContext& context_;
const LayoutObject& layout_object_;
+ const DisplayItemClient& display_item_client_;
PhysicalOffset paint_offset_;
};
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 0927a3d005f..4a32393fafc 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
@@ -28,7 +28,6 @@
#include <memory>
#include "cc/layers/picture_layer.h"
-#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/core/accessibility/apply_dark_mode.h"
#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
@@ -45,6 +44,7 @@
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/layout/geometry/transform_state.h"
+#include "third_party/blink/renderer/core/layout/layout_box_model_object.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_object.h"
#include "third_party/blink/renderer/core/layout/layout_html_canvas.h"
@@ -180,7 +180,7 @@ static bool NeedsDecorationOutlineLayer(const PaintLayer& paint_layer,
bool could_obscure_decorations =
(paint_layer.GetScrollableArea() &&
paint_layer.GetScrollableArea()->UsesCompositedScrolling()) ||
- layout_object.IsCanvas() || layout_object.IsVideo();
+ layout_object.IsCanvas() || IsA<LayoutVideo>(layout_object);
return could_obscure_decorations && layout_object.StyleRef().HasOutline() &&
layout_object.StyleRef().OutlineOffset() < -min_border_width;
@@ -189,21 +189,12 @@ static bool NeedsDecorationOutlineLayer(const PaintLayer& paint_layer,
CompositedLayerMapping::CompositedLayerMapping(PaintLayer& layer)
: owning_layer_(layer),
pending_update_scope_(kGraphicsLayerUpdateNone),
- is_main_frame_layout_view_layer_(false),
scrolling_contents_are_empty_(false),
- background_paints_onto_scrolling_contents_layer_(false),
- background_paints_onto_graphics_layer_(false),
draws_background_onto_content_layer_(false) {
- if (layer.IsRootLayer() && GetLayoutObject().GetFrame()->IsMainFrame())
- is_main_frame_layout_view_layer_ = true;
-
CreatePrimaryGraphicsLayer();
}
CompositedLayerMapping::~CompositedLayerMapping() {
- // Hits in compositing/squashing/squash-onto-nephew.html.
- DisableCompositingQueryAsserts disabler;
-
// 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) {
@@ -222,7 +213,6 @@ CompositedLayerMapping::~CompositedLayerMapping() {
UpdateMaskLayer(false);
UpdateScrollingLayers(false);
UpdateSquashingLayers(false);
- DestroyGraphicsLayers();
}
std::unique_ptr<GraphicsLayer> CompositedLayerMapping::CreateGraphicsLayer(
@@ -237,6 +227,26 @@ std::unique_ptr<GraphicsLayer> CompositedLayerMapping::CreateGraphicsLayer(
static_cast<int>(DOMNodeIds::IdForNode(owning_node)));
}
+ // Attempt to associate each layer with the frame owner's element ID.
+ Document* owner = nullptr;
+ if (GetLayoutObject().IsLayoutEmbeddedContent()) {
+ auto& embedded = ToLayoutEmbeddedContent(GetLayoutObject());
+ if (auto* frame_view =
+ DynamicTo<LocalFrameView>(embedded.GetEmbeddedContentView())) {
+ owner = frame_view->GetFrame().GetDocument();
+ } else {
+ // Ignore remote and plugin frames.
+ }
+ } else {
+ owner = &GetLayoutObject().GetDocument();
+ }
+ if (owner) {
+ graphics_layer->CcLayer()->SetFrameElementId(
+ CompositorElementIdFromUniqueObjectId(
+ DOMNodeIds::IdForNode(owner),
+ CompositorElementIdNamespace::kDOMNodeId));
+ }
+
return graphics_layer;
}
@@ -248,52 +258,6 @@ void CompositedLayerMapping::CreatePrimaryGraphicsLayer() {
graphics_layer_->SetHitTestable(true);
}
-void CompositedLayerMapping::DestroyGraphicsLayers() {
- if (graphics_layer_)
- graphics_layer_->RemoveFromParent();
-
- graphics_layer_ = nullptr;
- foreground_layer_ = nullptr;
- mask_layer_ = nullptr;
-
- scrolling_layer_ = nullptr;
- scrolling_contents_layer_ = nullptr;
-}
-
-void CompositedLayerMapping::UpdateBackgroundPaintsOntoScrollingContentsLayer(
- bool& invalidate_graphics_layer,
- bool& invalidate_scrolling_contents_layer) {
- invalidate_graphics_layer = false;
- invalidate_scrolling_contents_layer = false;
- // We can only paint the background onto the scrolling contents layer if
- // it would be visually correct and we are using composited scrolling meaning
- // we have a scrolling contents layer to paint it into.
- BackgroundPaintLocation paint_location =
- GetLayoutObject().GetBackgroundPaintLocation();
- bool should_paint_onto_scrolling_contents_layer =
- paint_location & kBackgroundPaintInScrollingContents &&
- owning_layer_.GetScrollableArea()->UsesCompositedScrolling();
- if (should_paint_onto_scrolling_contents_layer !=
- BackgroundPaintsOntoScrollingContentsLayer()) {
- background_paints_onto_scrolling_contents_layer_ =
- should_paint_onto_scrolling_contents_layer;
- // The scrolling contents layer needs to be updated for changed
- // m_backgroundPaintsOntoScrollingContentsLayer.
- if (HasScrollingLayer())
- invalidate_scrolling_contents_layer = true;
- }
- bool should_paint_onto_graphics_layer =
- !background_paints_onto_scrolling_contents_layer_ ||
- paint_location & kBackgroundPaintInGraphicsLayer;
- if (should_paint_onto_graphics_layer !=
- !!background_paints_onto_graphics_layer_) {
- background_paints_onto_graphics_layer_ = should_paint_onto_graphics_layer;
- // The graphics layer needs to be updated for changed
- // m_backgroundPaintsOntoGraphicsLayer.
- invalidate_graphics_layer = true;
- }
-}
-
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
@@ -322,40 +286,35 @@ void CompositedLayerMapping::UpdateContentsOpaque() {
// TODO(crbug.com/705019): Contents could be opaque, but that cannot be
// determined from the main thread. Or can it?
graphics_layer_->SetContentsOpaque(false);
- } else {
- // For non-root layers, background is painted by the scrolling contents
- // layer if all backgrounds are background attachment local, otherwise
- // background is painted by the primary graphics layer.
- if (HasScrollingLayer() &&
- background_paints_onto_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 (GetLayoutObject().GetBackgroundPaintLocation() &
- kBackgroundPaintInGraphicsLayer) {
- 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);
- }
- } else {
- if (HasScrollingLayer())
- scrolling_contents_layer_->SetContentsOpaque(false);
+ } else if (BackgroundPaintsOntoScrollingContentsLayer()) {
+ DCHECK(HasScrollingLayer());
+ // 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);
}
+ } else {
+ DCHECK(BackgroundPaintsOntoGraphicsLayer());
+ if (HasScrollingLayer())
+ scrolling_contents_layer_->SetContentsOpaque(false);
+ graphics_layer_->SetContentsOpaque(
+ owning_layer_.BackgroundIsKnownToBeOpaqueInRect(CompositedBounds(),
+ should_check_children));
}
}
@@ -452,36 +411,30 @@ bool CompositedLayerMapping::UpdateGraphicsLayerConfiguration(
}
}
- if (WebPluginContainerImpl* plugin = GetPluginContainer(layout_object)) {
- graphics_layer_->SetContentsToCcLayer(
- plugin->CcLayer(), plugin->PreventContentsOpaqueChangesToCcLayer());
- } else {
- auto* frame_owner =
- DynamicTo<HTMLFrameOwnerElement>(layout_object.GetNode());
- if (frame_owner && frame_owner->ContentFrame()) {
- Frame* frame = frame_owner->ContentFrame();
- if (auto* remote = DynamicTo<RemoteFrame>(frame)) {
- cc::Layer* layer = remote->GetCcLayer();
+ if (layout_object.IsLayoutEmbeddedContent()) {
+ if (WebPluginContainerImpl* plugin = GetPluginContainer(layout_object)) {
+ graphics_layer_->SetContentsToCcLayer(
+ plugin->CcLayer(), plugin->PreventContentsOpaqueChangesToCcLayer());
+ } else if (auto* frame_owner =
+ DynamicTo<HTMLFrameOwnerElement>(layout_object.GetNode())) {
+ if (auto* remote = DynamicTo<RemoteFrame>(frame_owner->ContentFrame())) {
graphics_layer_->SetContentsToCcLayer(
- layer, remote->WebLayerHasFixedContentsOpaque());
+ remote->GetCcLayer(), remote->WebLayerHasFixedContentsOpaque());
}
- } else if (layout_object.IsVideo()) {
- HTMLMediaElement* media_element =
- ToHTMLMediaElement(layout_object.GetNode());
- graphics_layer_->SetContentsToCcLayer(
- media_element->CcLayer(),
- /*prevent_contents_opaque_changes=*/true);
- } else if (layout_object.IsCanvas()) {
- graphics_layer_->SetContentsToCcLayer(
- To<HTMLCanvasElement>(layout_object.GetNode())->ContentsCcLayer(),
- /*prevent_contents_opaque_changes=*/false);
- layer_config_changed = true;
}
- }
- if (layout_object.IsLayoutEmbeddedContent()) {
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(
+ media_element->CcLayer(),
+ /*prevent_contents_opaque_changes=*/true);
+ } else if (layout_object.IsCanvas()) {
+ graphics_layer_->SetContentsToCcLayer(
+ To<HTMLCanvasElement>(layout_object.GetNode())->ContentsCcLayer(),
+ /*prevent_contents_opaque_changes=*/false);
+ layer_config_changed = true;
}
if (layer_config_changed) {
@@ -769,22 +722,7 @@ void CompositedLayerMapping::UpdateGraphicsLayerGeometry(
UpdateContentsRect();
UpdateBackgroundColor();
-
- bool invalidate_graphics_layer;
- bool invalidate_scrolling_contents_layer;
- UpdateBackgroundPaintsOntoScrollingContentsLayer(
- invalidate_graphics_layer, invalidate_scrolling_contents_layer);
-
- // This depends on background_paints_onto_graphics_layer_.
UpdateDrawsContentAndPaintsHitTest();
-
- // These invalidations need to happen after
- // |UpdateDrawsContentAndPaintsHitTest|.
- if (invalidate_graphics_layer)
- graphics_layer_->SetNeedsDisplay();
- if (invalidate_scrolling_contents_layer)
- scrolling_contents_layer_->SetNeedsDisplay();
-
UpdateElementId();
UpdateContentsOpaque();
UpdateRasterizationPolicy();
@@ -846,11 +784,11 @@ void CompositedLayerMapping::UpdateOverflowControlsHostLayerGeometry(
// To clip the scrollbars correctly, overflow_controls_host_layer_ should
// match our border box size.
- const IntRect border_box =
- owning_layer_.GetLayoutBox()->PixelSnappedBorderBoxRect(
- owning_layer_.SubpixelAccumulation());
- overflow_controls_host_layer_->SetSize(gfx::Size(border_box.Size()));
- overflow_controls_host_layer_->SetMasksToBounds(true);
+ const IntSize border_box_size =
+ owning_layer_.GetLayoutBox()->PixelSnappedBorderBoxSize(
+ PhysicalOffset(owning_layer_.SubpixelAccumulation() +
+ owning_layer_.GetLayoutBox()->PhysicalLocation()));
+ overflow_controls_host_layer_->SetSize(gfx::Size(border_box_size));
}
void CompositedLayerMapping::UpdateMaskLayerGeometry() {
@@ -890,7 +828,8 @@ void CompositedLayerMapping::UpdateScrollingLayerGeometry() {
scroll_size = scroll_size.ExpandedTo(overflow_clip_rect.Size());
auto* scrolling_coordinator = owning_layer_.GetScrollingCoordinator();
- scrolling_coordinator->UpdateCompositedScrollOffset(scrollable_area);
+ scrolling_coordinator->UpdateCompositorScrollOffset(*layout_box.GetFrame(),
+ *scrollable_area);
if (gfx::Size(scroll_size) != scrolling_contents_layer_->Size() ||
scroll_container_size_changed) {
@@ -1028,7 +967,7 @@ void CompositedLayerMapping::UpdateContentsRect() {
void CompositedLayerMapping::UpdateDrawsContentAndPaintsHitTest() {
bool in_overlay_fullscreen_video = false;
- if (GetLayoutObject().IsVideo()) {
+ if (IsA<LayoutVideo>(GetLayoutObject())) {
auto* video_element = To<HTMLVideoElement>(GetLayoutObject().GetNode());
if (video_element->IsFullscreen() &&
video_element->UsesOverlayFullscreenVideo())
@@ -1393,7 +1332,6 @@ bool CompositedLayerMapping::UpdateScrollingLayers(
CreateGraphicsLayer(CompositingReason::kLayerForScrollingContainer);
scrolling_layer_->SetDrawsContent(false);
scrolling_layer_->SetHitTestable(false);
- scrolling_layer_->SetMasksToBounds(true);
// Inner layer which renders the content that scrolls.
scrolling_contents_layer_ =
@@ -1410,8 +1348,8 @@ bool CompositedLayerMapping::UpdateScrollingLayers(
scrolling_coordinator->ScrollableAreaScrollLayerDidChange(
scrollable_area);
const auto& object = GetLayoutObject();
- if (object.IsLayoutView())
- ToLayoutView(object).GetFrameView()->ScrollableAreasDidChange();
+ if (auto* layout_view = DynamicTo<LayoutView>(object))
+ layout_view->GetFrameView()->ScrollableAreasDidChange();
}
}
} else if (scrolling_layer_) {
@@ -1422,8 +1360,8 @@ bool CompositedLayerMapping::UpdateScrollingLayers(
scrolling_coordinator->ScrollableAreaScrollLayerDidChange(
scrollable_area);
const auto& object = GetLayoutObject();
- if (object.IsLayoutView())
- ToLayoutView(object).GetFrameView()->ScrollableAreasDidChange();
+ if (auto* layout_view = DynamicTo<LayoutView>(object))
+ layout_view->GetFrameView()->ScrollableAreasDidChange();
}
}
@@ -1487,8 +1425,9 @@ CompositedLayerMapping::PaintingPhaseForPrimaryLayer() const {
Color CompositedLayerMapping::LayoutObjectBackgroundColor() const {
const auto& object = GetLayoutObject();
auto background_color = object.ResolveColor(GetCSSPropertyBackgroundColor());
- if (object.IsLayoutView() && object.GetDocument().IsInMainFrame()) {
- return ToLayoutView(object).GetFrameView()->BaseBackgroundColor().Blend(
+ auto* layout_view = DynamicTo<LayoutView>(object);
+ if (layout_view && object.GetDocument().IsInMainFrame()) {
+ return layout_view->GetFrameView()->BaseBackgroundColor().Blend(
background_color);
}
return background_color;
@@ -1545,13 +1484,13 @@ bool CompositedLayerMapping::ContainsPaintedContent() const {
// FIXME: we could optimize cases where the image, video or canvas is known to
// fill the border box entirely, and set background color on the layer in that
// case, instead of allocating backing store and painting.
- if (layout_object.IsVideo() &&
- ToLayoutVideo(layout_object).ShouldDisplayVideo())
+ auto* layout_video = DynamicTo<LayoutVideo>(layout_object);
+ if (layout_video && layout_video->ShouldDisplayVideo())
return owning_layer_.HasBoxDecorationsOrBackground();
if (layout_object.GetNode() && layout_object.GetNode()->IsDocumentNode()) {
if (owning_layer_.NeedsCompositedScrolling())
- return background_paints_onto_graphics_layer_;
+ return BackgroundPaintsOntoGraphicsLayer();
// Look to see if the root object has a non-simple background
LayoutObject* root_object =
@@ -1595,9 +1534,6 @@ bool CompositedLayerMapping::ContainsPaintedContent() const {
bool CompositedLayerMapping::IsDirectlyCompositedImage() const {
DCHECK(GetLayoutObject().IsImage());
- if (base::FeatureList::IsEnabled(features::kDisableDirectlyCompositedImages))
- return false;
-
LayoutImage& image_layout_object = ToLayoutImage(GetLayoutObject());
if (owning_layer_.HasBoxDecorationsOrBackground() ||
@@ -1609,8 +1545,7 @@ bool CompositedLayerMapping::IsDirectlyCompositedImage() const {
if (!cached_image->HasImage())
return false;
- Image* image = cached_image->GetImage();
- if (!image->IsBitmapImage())
+ if (!IsA<BitmapImage>(cached_image->GetImage()))
return false;
UseCounter::Count(GetLayoutObject().GetDocument(),
@@ -1944,7 +1879,7 @@ IntRect CompositedLayerMapping::RecomputeInterestRect(
GeometryMapper::LocalToAncestorVisualRect(
source_state, root_view_contents_state, mapping_rect);
- FloatRect visible_content_rect = mapping_rect.Rect();
+ FloatRect visible_content_rect(EnclosingIntRect(mapping_rect.Rect()));
// 3. Move into local border box transform space of the root LayoutView.
// Note that the overflow clip has *not* been applied.
@@ -2175,10 +2110,10 @@ void CompositedLayerMapping::PaintContents(
graphics_layer == mask_layer_.get() ||
graphics_layer == scrolling_contents_layer_.get() ||
graphics_layer == decoration_outline_layer_.get()) {
- if (background_paints_onto_scrolling_contents_layer_) {
+ if (BackgroundPaintsOntoScrollingContentsLayer()) {
if (graphics_layer == scrolling_contents_layer_.get())
paint_layer_flags &= ~kPaintLayerPaintingSkipRootBackground;
- else if (!background_paints_onto_graphics_layer_)
+ else if (!BackgroundPaintsOntoGraphicsLayer())
paint_layer_flags |= kPaintLayerPaintingSkipRootBackground;
}
@@ -2221,12 +2156,12 @@ void CompositedLayerMapping::PaintScrollableArea(
if (graphics_layer == LayerForHorizontalScrollbar()) {
if (const Scrollbar* scrollbar = scrollable_area->HorizontalScrollbar()) {
if (cull_rect.Intersects(scrollbar->FrameRect()))
- scrollbar->Paint(context);
+ scrollbar->Paint(context, IntPoint());
}
} else if (graphics_layer == LayerForVerticalScrollbar()) {
if (const Scrollbar* scrollbar = scrollable_area->VerticalScrollbar()) {
if (cull_rect.Intersects(scrollbar->FrameRect()))
- scrollbar->Paint(context);
+ scrollbar->Paint(context, IntPoint());
}
} else if (graphics_layer == LayerForScrollCorner()) {
ScrollableAreaPainter painter(*scrollable_area);
@@ -2309,33 +2244,6 @@ void CompositedLayerMapping::VerifyNotPainting() {
}
#endif
-// Only used for performance benchmark testing. Intended to be a
-// sufficiently-unique element id name to allow picking out the target element
-// for invalidation.
-static const char kTestPaintInvalidationTargetName[] =
- "blinkPaintInvalidationTarget";
-
-void CompositedLayerMapping::InvalidateTargetElementForTesting() {
- // The below is an artificial construct formed intentionally to focus a
- // microbenchmark on the cost of paint with a partial invalidation.
- Element* target_element =
- owning_layer_.GetLayoutObject().GetDocument().getElementById(
- AtomicString(kTestPaintInvalidationTargetName));
- // TODO(wkorman): If we don't find the expected target element, we could
- // consider walking to the first leaf node so that the partial-invalidation
- // benchmark mode still provides some value when running on generic pages.
- if (!target_element)
- return;
- LayoutObject* target_object = target_element->GetLayoutObject();
- if (!target_object)
- return;
- target_object->EnclosingLayer()->SetNeedsRepaint();
- // TODO(wkorman): Consider revising the below to invalidate all
- // non-compositing descendants as well.
- target_object->InvalidateDisplayItemClients(
- PaintInvalidationReason::kForTesting);
-}
-
bool CompositedLayerMapping::InvalidateLayerIfNoPrecedingEntry(
wtf_size_t index_to_clear) {
PaintLayer* layer_to_remove = squashed_layers_[index_to_clear].paint_layer;
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 4d96ad6ac59..bb399d8b1d5 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
@@ -100,12 +100,6 @@ class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient {
const PaintLayer* compositing_container,
Vector<PaintLayer*>& layers_needing_paint_invalidation);
- // Update whether background paints onto scrolling contents layer.
- // Returns (through the reference params) what invalidations are needed.
- void UpdateBackgroundPaintsOntoScrollingContentsLayer(
- bool& invalidate_graphics_layer,
- bool& invalidate_scrolling_contents_layer);
-
// Update whether layer needs blending.
void UpdateContentsOpaque();
@@ -169,7 +163,6 @@ class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient {
void UpdateElementId();
// GraphicsLayerClient interface
- void InvalidateTargetElementForTesting() override;
IntRect ComputeInterestRect(
const GraphicsLayer*,
const IntRect& previous_interest_rect) const override;
@@ -258,27 +251,29 @@ class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient {
bool AdjustForCompositedScrolling(const GraphicsLayer*,
IntSize& offset) const;
+ bool DrawsBackgroundOntoContentLayer() const {
+ return draws_background_onto_content_layer_;
+ }
+
+ private:
// Returns true for layers with scrollable overflow which have a background
// that can be painted into the composited scrolling contents layer (i.e.
// the background can scroll with the content). When the background is also
// opaque this allows us to composite the scroller even on low DPI as we can
// draw with subpixel anti-aliasing.
bool BackgroundPaintsOntoScrollingContentsLayer() const {
- return background_paints_onto_scrolling_contents_layer_;
+ return GetLayoutObject().GetBackgroundPaintLocation() &
+ kBackgroundPaintInScrollingContents;
}
// Returns true if the background paints onto the main graphics layer.
// In some situations, we may paint background on both the main graphics layer
// and the scrolling contents layer.
bool BackgroundPaintsOntoGraphicsLayer() const {
- return background_paints_onto_graphics_layer_;
+ return GetLayoutObject().GetBackgroundPaintLocation() &
+ kBackgroundPaintInGraphicsLayer;
}
- bool DrawsBackgroundOntoContentLayer() const {
- return draws_background_onto_content_layer_;
- }
-
- private:
IntRect RecomputeInterestRect(const GraphicsLayer*) const;
static bool InterestRectChangedEnoughToRepaint(
const IntRect& previous_interest_rect,
@@ -323,7 +318,6 @@ class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient {
void UpdateScrollingLayerGeometry();
void CreatePrimaryGraphicsLayer();
- void DestroyGraphicsLayers();
std::unique_ptr<GraphicsLayer> CreateGraphicsLayer(
CompositingReasons,
@@ -483,19 +477,9 @@ class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient {
PhysicalRect composited_bounds_;
unsigned pending_update_scope_ : 2;
- unsigned is_main_frame_layout_view_layer_ : 1;
unsigned scrolling_contents_are_empty_ : 1;
- // Keep track of whether the background is painted onto the scrolling contents
- // layer for invalidations.
- unsigned background_paints_onto_scrolling_contents_layer_ : 1;
-
- // Solid color border boxes may be painted into both the scrolling contents
- // layer and the graphics layer because the scrolling contents layer is
- // clipped by the padding box.
- unsigned background_paints_onto_graphics_layer_ : 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 311dcbe9b6c..b43664bfed7 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
@@ -6,8 +6,13 @@
#include "cc/layers/layer.h"
#include "cc/layers/picture_layer.h"
+#include "cc/trees/layer_tree_host.h"
+#include "cc/trees/property_tree.h"
+#include "cc/trees/scroll_node.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
+#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
#include "third_party/blink/renderer/core/layout/layout_box_model_object.h"
#include "third_party/blink/renderer/core/layout/layout_image.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
@@ -64,7 +69,8 @@ TEST_F(CompositedLayerMappingTest, SubpixelAccumulationChange) {
Element* target = GetDocument().getElementById("target");
target->SetInlineStyleProperty(CSSPropertyID::kLeft, "0.6px");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
PaintLayer* paint_layer =
ToLayoutBoxModelObject(target->GetLayoutObject())->Layer();
@@ -86,7 +92,8 @@ TEST_F(CompositedLayerMappingTest,
Element* target = GetDocument().getElementById("target");
target->SetInlineStyleProperty(CSSPropertyID::kLeft, "0.6px");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
PaintLayer* paint_layer =
ToLayoutBoxModelObject(target->GetLayoutObject())->Layer();
@@ -129,7 +136,8 @@ TEST_F(CompositedLayerMappingTest,
Element* target = GetDocument().getElementById("target");
target->SetInlineStyleProperty(CSSPropertyID::kLeft, "0.6px");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
PaintLayer* paint_layer =
ToLayoutBoxModelObject(target->GetLayoutObject())->Layer();
@@ -181,8 +189,8 @@ TEST_F(CompositedLayerMappingTest, TallCompositedScrolledLayerInterestRect) {
)HTML");
UpdateAllLifecyclePhasesForTest();
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 8000),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 8000), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
Element* element = GetDocument().getElementById("target");
@@ -199,8 +207,8 @@ TEST_F(CompositedLayerMappingTest, TallNonCompositedScrolledLayerInterestRect) {
)HTML");
UpdateAllLifecyclePhasesForTest();
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 8000),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 8000), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
PaintLayer* paint_layer = GetDocument().GetLayoutView()->Layer();
@@ -239,7 +247,7 @@ TEST_F(CompositedLayerMappingTest, VerticalRightLeftWritingModeDocument) {
UpdateAllLifecyclePhasesForTest();
GetDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(-5000, 0), kProgrammaticScroll);
+ ScrollOffset(-5000, 0), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
PaintLayer* paint_layer = GetDocument().GetLayoutView()->Layer();
@@ -410,7 +418,7 @@ TEST_F(CompositedLayerMappingTest, 3D45DegRotatedTallInterestRect) {
PaintLayer* paint_layer =
ToLayoutBoxModelObject(element->GetLayoutObject())->Layer();
ASSERT_TRUE(!!paint_layer->GraphicsLayerBacking());
- EXPECT_EQ(IntRect(0, 0, 200, 6249),
+ EXPECT_EQ(IntRect(0, 0, 200, 6226),
RecomputeInterestRect(paint_layer->GraphicsLayerBacking()));
}
@@ -618,8 +626,8 @@ TEST_F(CompositedLayerMappingTest, InterestRectChangeOnViewportScroll) {
EXPECT_EQ(IntRect(0, 0, 800, 4600),
PreviousInterestRect(root_scrolling_layer));
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 300),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 300), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
// Still use the previous interest rect because the recomputed rect hasn't
// changed enough.
@@ -628,8 +636,8 @@ TEST_F(CompositedLayerMappingTest, InterestRectChangeOnViewportScroll) {
EXPECT_EQ(IntRect(0, 0, 800, 4600),
PreviousInterestRect(root_scrolling_layer));
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 600),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 600), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
// Use recomputed interest rect because it changed enough.
EXPECT_EQ(IntRect(0, 0, 800, 5200),
@@ -637,16 +645,16 @@ TEST_F(CompositedLayerMappingTest, InterestRectChangeOnViewportScroll) {
EXPECT_EQ(IntRect(0, 0, 800, 5200),
PreviousInterestRect(root_scrolling_layer));
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 5400),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 5400), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(IntRect(0, 1400, 800, 8600),
RecomputeInterestRect(root_scrolling_layer));
EXPECT_EQ(IntRect(0, 1400, 800, 8600),
PreviousInterestRect(root_scrolling_layer));
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 9000),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 9000), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
// Still use the previous interest rect because it contains the recomputed
// interest rect.
@@ -655,8 +663,8 @@ TEST_F(CompositedLayerMappingTest, InterestRectChangeOnViewportScroll) {
EXPECT_EQ(IntRect(0, 1400, 800, 8600),
PreviousInterestRect(root_scrolling_layer));
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 2000),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 2000), mojom::blink::ScrollType::kProgrammatic);
// Use recomputed interest rect because it changed enough.
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(IntRect(0, 0, 800, 6600),
@@ -856,7 +864,7 @@ TEST_F(CompositedLayerMappingTest, InterestRectOfIframeInScrolledDiv) {
// Scroll 8000 pixels down to move the iframe into view.
GetDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0.0, 8000.0), kProgrammaticScroll);
+ ScrollOffset(0.0, 8000.0), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
Element* target = ChildDocument().getElementById("target");
@@ -887,7 +895,7 @@ TEST_F(CompositedLayerMappingTest, InterestRectOfScrolledIframe) {
// Scroll 7500 pixels down to bring the scrollable area to the bottom.
ChildDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0.0, 7500.0), kProgrammaticScroll);
+ ScrollOffset(0.0, 7500.0), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
ASSERT_TRUE(ChildDocument().View()->GetLayoutView()->HasLayer());
@@ -921,7 +929,7 @@ TEST_F(CompositedLayerMappingTest, InterestRectOfIframeWithContentBoxOffset) {
// Scroll 3000 pixels down to bring the scrollable area to somewhere in the
// middle.
ChildDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0.0, 3000.0), kProgrammaticScroll);
+ ScrollOffset(0.0, 3000.0), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
ASSERT_TRUE(ChildDocument().View()->GetLayoutView()->HasLayer());
@@ -963,7 +971,7 @@ TEST_F(CompositedLayerMappingTest, InterestRectOfIframeWithFixedContents) {
EXPECT_EQ(IntRect(1000, 0, 4400, 300), RecomputeInterestRect(graphics_layer));
ChildDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0.0, 3000.0), kProgrammaticScroll);
+ ScrollOffset(0.0, 3000.0), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
// Because the fixed element does not scroll, the interest rect is unchanged.
@@ -989,7 +997,7 @@ TEST_F(CompositedLayerMappingTest, ScrolledFixedPositionInterestRect) {
EXPECT_EQ(IntRect(0, 500, 100, 4030), RecomputeInterestRect(graphics_layer));
GetDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0.0, 200.0), kProgrammaticScroll);
+ ScrollOffset(0.0, 200.0), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
// Because the fixed element does not scroll, the interest rect is unchanged.
@@ -1142,7 +1150,7 @@ TEST_F(CompositedLayerMappingTest,
const auto* container = ToLayoutBox(GetLayoutObjectByElementId("container"));
EXPECT_EQ(kBackgroundPaintInScrollingContents,
- container->GetBackgroundPaintLocation());
+ 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
@@ -1150,7 +1158,8 @@ TEST_F(CompositedLayerMappingTest,
// this case.
const auto* mapping = container->Layer()->GetCompositedLayerMapping();
EXPECT_FALSE(mapping->HasScrollingLayer());
- EXPECT_FALSE(mapping->BackgroundPaintsOntoScrollingContentsLayer());
+ EXPECT_EQ(kBackgroundPaintInGraphicsLayer,
+ container->GetBackgroundPaintLocation());
}
TEST_F(CompositedLayerMappingTest, StickyPositionMainThreadOffset) {
@@ -1184,7 +1193,8 @@ TEST_F(CompositedLayerMappingTest, StickyPositionMainThreadOffset) {
sticky_layer->SetNeedsCompositingInputsUpdate();
EXPECT_TRUE(sticky_layer->NeedsCompositingInputsUpdate());
- GetDocument().View()->UpdateLifecycleToCompositingCleanPlusScrolling();
+ GetDocument().View()->UpdateLifecycleToCompositingCleanPlusScrolling(
+ DocumentUpdateReason::kTest);
EXPECT_FALSE(sticky_layer->NeedsCompositingInputsUpdate());
}
@@ -1412,22 +1422,28 @@ TEST_F(CompositedLayerMappingTest, ScrollingContainerBoundsChange) {
PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea();
cc::Layer* scrolling_layer = scrollable_area->LayerForScrolling();
- EXPECT_EQ(0, scrolling_layer->CurrentScrollOffset().y());
+ auto element_id = scrollable_area->GetScrollElementId();
+ auto& scroll_tree =
+ scrolling_layer->layer_tree_host()->property_trees()->scroll_tree;
+ EXPECT_EQ(0, scroll_tree.current_scroll_offset(element_id).y());
EXPECT_EQ(150, scrolling_layer->bounds().height());
- EXPECT_EQ(100, scrolling_layer->scroll_container_bounds().height());
+ auto* scroll_node = scroll_tree.FindNodeFromElementId(element_id);
+ EXPECT_EQ(100, scroll_node->container_bounds.height());
scrollerElement->setScrollTop(300);
scrollerElement->setAttribute(html_names::kStyleAttr, "max-height: 25px;");
UpdateAllLifecyclePhasesForTest();
- EXPECT_EQ(50, scrolling_layer->CurrentScrollOffset().y());
+ EXPECT_EQ(50, scroll_tree.current_scroll_offset(element_id).y());
EXPECT_EQ(150, scrolling_layer->bounds().height());
- EXPECT_EQ(25, scrolling_layer->scroll_container_bounds().height());
+ scroll_node = scroll_tree.FindNodeFromElementId(element_id);
+ EXPECT_EQ(25, scroll_node->container_bounds.height());
scrollerElement->setAttribute(html_names::kStyleAttr, "max-height: 300px;");
UpdateAllLifecyclePhasesForTest();
- EXPECT_EQ(50, scrolling_layer->CurrentScrollOffset().y());
+ EXPECT_EQ(50, scroll_tree.current_scroll_offset(element_id).y());
EXPECT_EQ(150, scrolling_layer->bounds().height());
- EXPECT_EQ(100, scrolling_layer->scroll_container_bounds().height());
+ scroll_node = scroll_tree.FindNodeFromElementId(element_id);
+ EXPECT_EQ(100, scroll_node->container_bounds.height());
}
TEST_F(CompositedLayerMappingTest, MainFrameLayerBackgroundColor) {
@@ -1515,27 +1531,6 @@ TEST_F(CompositedLayerMappingTest, ScrollLayerSizingSubpixelAccumulation) {
mapping->ScrollingContentsLayer()->Size().height());
}
-TEST_F(CompositedLayerMappingTest, SquashingScroll) {
- SetHtmlInnerHTML(R"HTML(
- <style>
- * { margin: 0 }
- </style>
- <div id=target
- style='width: 200px; height: 200px; position: relative; will-change: transform'></div>
- <div id=squashed
- style='width: 200px; height: 200px; top: -200px; position: relative;'></div>
- <div style='width: 10px; height: 3000px'></div>
- )HTML");
-
- auto* squashed =
- ToLayoutBoxModelObject(GetLayoutObjectByElementId("squashed"))->Layer();
- EXPECT_EQ(kPaintsIntoGroupedBacking, squashed->GetCompositingState());
-
- GetDocument().View()->LayoutViewport()->ScrollBy(ScrollOffset(0, 25),
- kUserScroll);
- UpdateAllLifecyclePhasesForTest();
-}
-
TEST_F(CompositedLayerMappingTest, SquashingScrollInterestRect) {
SetHtmlInnerHTML(R"HTML(
<style>
@@ -1551,8 +1546,8 @@ TEST_F(CompositedLayerMappingTest, SquashingScrollInterestRect) {
ToLayoutBoxModelObject(GetLayoutObjectByElementId("squashed"))->Layer();
EXPECT_EQ(kPaintsIntoGroupedBacking, squashed->GetCompositingState());
- GetDocument().View()->LayoutViewport()->ScrollBy(ScrollOffset(0, 5000),
- kUserScroll);
+ GetDocument().View()->LayoutViewport()->ScrollBy(
+ ScrollOffset(0, 5000), mojom::blink::ScrollType::kUser);
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(IntRect(0, 1000, 200, 5000),
@@ -1776,13 +1771,101 @@ TEST_F(CompositedLayerMappingTest,
GetDocument()
.getElementById("uncorrelated")
->setAttribute(html_names::kStyleAttr, "width: 200px");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_FALSE(mapping->NeedsRepaint(*vertical_scrollbar_layer));
GetDocument().getElementById("child")->setAttribute(html_names::kStyleAttr,
- "height: 300px");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ "height: 50px");
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(mapping->NeedsRepaint(*vertical_scrollbar_layer));
}
+TEST_F(CompositedLayerMappingTest, IsolationClippingContainer) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #hideable {
+ overflow: hidden;
+ height: 10px;
+ }
+ .isolation {
+ contain: style layout;
+ height: 100px;
+ }
+ .squash-container {
+ will-change: transform;
+ }
+ .squashed {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100px;
+ height: 100px;
+ }
+ </style>
+ <div id="hideable">
+ <div class="isolation" id="isolation_a">
+ <div class="squash-container" id="squash_container_a">a</div>
+ <div class="squashed"></div>
+ </div>
+ <div class="isolation">
+ <div class="squash-container">b</div>
+ <div class="squashed"></div>
+ </div>
+ </div>
+ )HTML");
+
+ Element* hideable = GetDocument().getElementById("hideable");
+ hideable->SetInlineStyleProperty(CSSPropertyID::kOverflow, "visible");
+
+ UpdateAllLifecyclePhasesForTest();
+
+ auto* isolation_a = GetDocument().getElementById("isolation_a");
+ auto* isolation_a_object = isolation_a->GetLayoutObject();
+
+ auto* squash_container_a = GetDocument().getElementById("squash_container_a");
+ PaintLayer* squash_container_a_layer =
+ ToLayoutBoxModelObject(squash_container_a->GetLayoutObject())->Layer();
+ EXPECT_EQ(squash_container_a_layer->ClippingContainer(), isolation_a_object);
+}
+
+TEST_F(CompositedLayerMappingTest, FrameAttribution) {
+ SetBodyInnerHTML(R"HTML(
+ <div id='child' style='will-change: transform;'></div>
+ <iframe id='subframe' style='will-change: transform;'></iframe>
+ )HTML");
+
+ UpdateAllLifecyclePhasesForTest();
+
+ // Ensure that we correctly attribute child layers in the main frame to their
+ // containing document.
+ Element* child = GetDocument().getElementById("child");
+ PaintLayer* child_paint_layer =
+ ToLayoutBoxModelObject(child->GetLayoutObject())->Layer();
+ auto* child_layer = child_paint_layer->GraphicsLayerBacking()->CcLayer();
+ EXPECT_TRUE(child_layer->frame_element_id());
+
+ EXPECT_EQ(child_layer->frame_element_id(),
+ CompositorElementIdFromUniqueObjectId(
+ DOMNodeIds::IdForNode(&GetDocument()),
+ CompositorElementIdNamespace::kDOMNodeId));
+
+ // Test that a layerized subframe's element ID is that of its containing
+ // document.
+ auto* subframe =
+ To<HTMLFrameOwnerElement>(GetDocument().getElementById("subframe"));
+ EXPECT_TRUE(subframe);
+ PaintLayer* subframe_paint_layer =
+ ToLayoutBoxModelObject(subframe->GetLayoutObject())->Layer();
+ auto* subframe_layer =
+ subframe_paint_layer->GraphicsLayerBacking()->CcLayer();
+ EXPECT_TRUE(subframe_layer->frame_element_id());
+
+ EXPECT_EQ(subframe_layer->frame_element_id(),
+ CompositorElementIdFromUniqueObjectId(
+ DOMNodeIds::IdForNode(subframe->contentDocument()),
+ CompositorElementIdNamespace::kDOMNodeId));
+}
+
} // 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 65440c163bd..d745fb4a8fa 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
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.h"
+#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
#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"
@@ -48,6 +49,13 @@ void CompositingInputsUpdater::Update() {
UpdateType update_type = kDoNotForceUpdate;
PaintLayer* layer =
compositing_inputs_root_ ? compositing_inputs_root_ : root_layer_;
+
+ if (DisplayLockUtilities::NearestLockedExclusiveAncestor(
+ layer->GetLayoutObject())) {
+ compositing_inputs_root_ = nullptr;
+ return;
+ }
+
CompositingReasons initial_compositing_reasons =
layer->DirectCompositingReasons();
ApplyAncestorInfoToSelfAndAncestorsRecursively(layer, update_type, info);
@@ -219,6 +227,22 @@ void CompositingInputsUpdater::UpdateAncestorInfo(PaintLayer* const layer,
info.enclosing_stacking_composited_layer;
PaintLayer* enclosing_squashing_composited_layer =
info.enclosing_squashing_composited_layer;
+
+ if (layer->NeedsCompositingInputsUpdate()) {
+ if (enclosing_stacking_composited_layer) {
+ enclosing_stacking_composited_layer->GetCompositedLayerMapping()
+ ->SetNeedsGraphicsLayerUpdate(kGraphicsLayerUpdateSubtree);
+ }
+
+ if (enclosing_squashing_composited_layer) {
+ enclosing_squashing_composited_layer->GetCompositedLayerMapping()
+ ->SetNeedsGraphicsLayerUpdate(kGraphicsLayerUpdateSubtree);
+ }
+
+ update_type = kForceUpdate;
+ }
+
+
switch (layer->GetCompositingState()) {
case kNotComposited:
break;
@@ -232,17 +256,19 @@ void CompositingInputsUpdater::UpdateAncestorInfo(PaintLayer* const layer,
break;
}
+ // invalidate again after the switch, in case
+ // enclosing_stacking_composited_layer or
+ // enclosing_squashing_composited_layer was previously null.
if (layer->NeedsCompositingInputsUpdate()) {
if (enclosing_stacking_composited_layer) {
enclosing_stacking_composited_layer->GetCompositedLayerMapping()
->SetNeedsGraphicsLayerUpdate(kGraphicsLayerUpdateSubtree);
}
+
if (enclosing_squashing_composited_layer) {
enclosing_squashing_composited_layer->GetCompositedLayerMapping()
->SetNeedsGraphicsLayerUpdate(kGraphicsLayerUpdateSubtree);
}
-
- update_type = kForceUpdate;
}
if (style.GetPosition() == EPosition::kAbsolute) {
@@ -287,13 +313,13 @@ void CompositingInputsUpdater::UpdateAncestorInfo(PaintLayer* const layer,
// in the sense that they don't scroll along with its in-flow contents.
// However LayoutView does clip them.
if (layout_object.CanContainFixedPositionObjects() &&
- !layout_object.IsLayoutView()) {
+ !IsA<LayoutView>(layout_object)) {
info.clip_chain_parent_for_fixed = layer;
info.escape_clip_to_for_fixed = info.escape_clip_to;
info.scrolling_ancestor_for_fixed = info.scrolling_ancestor;
info.needs_reparent_scroll_for_fixed = info.needs_reparent_scroll;
}
- if (layout_object.IsLayoutView())
+ if (IsA<LayoutView>(layout_object))
info.clip_chain_parent_for_fixed = layer;
// CSS clip affects all descendants, not just containing-block descendants.
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 3d43a923ee3..4f66645c2eb 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
@@ -69,7 +69,8 @@ TEST_F(CompositingInputsUpdaterTest,
// Before we update compositing inputs, validate that the current ancestor
// overflow no longer has a scrollable area.
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
EXPECT_FALSE(sticky->Layer()->AncestorOverflowLayer()->GetScrollableArea());
EXPECT_EQ(sticky->Layer()->AncestorOverflowLayer(), outer_scroller->Layer());
@@ -99,8 +100,8 @@ TEST_F(CompositingInputsUpdaterTest, UnclippedAndClippedRectsUnderScroll) {
LayoutBoxModelObject* target =
ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"));
- GetDocument().View()->LayoutViewport()->ScrollBy(ScrollOffset(0, 25),
- kUserScroll);
+ GetDocument().View()->LayoutViewport()->ScrollBy(
+ ScrollOffset(0, 25), mojom::blink::ScrollType::kUser);
GetDocument()
.View()
->GetLayoutView()
@@ -125,8 +126,8 @@ TEST_F(CompositingInputsUpdaterTest,
LayoutBoxModelObject* target =
ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"));
- GetDocument().View()->LayoutViewport()->ScrollBy(ScrollOffset(0, 25),
- kUserScroll);
+ GetDocument().View()->LayoutViewport()->ScrollBy(
+ ScrollOffset(0, 25), mojom::blink::ScrollType::kUser);
GetDocument()
.View()
->GetLayoutView()
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 d31bd3e8a32..81eb11a2ed2 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_video.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/scrolling/scrolling_coordinator.h"
@@ -45,8 +46,6 @@ CompositingLayerAssigner::CompositingLayerAssigner(
PaintLayerCompositor* compositor)
: compositor_(compositor), layers_changed_(false) {}
-CompositingLayerAssigner::~CompositingLayerAssigner() = default;
-
void CompositingLayerAssigner::Assign(
PaintLayer* update_root,
Vector<PaintLayer*>& layers_needing_paint_invalidation) {
@@ -135,8 +134,8 @@ CompositingLayerAssigner::GetReasonsPreventingSquashing(
const PaintLayer& squashing_layer =
squashing_state.most_recent_mapping->OwningLayer();
- if (layer->GetLayoutObject().IsVideo() ||
- squashing_layer.GetLayoutObject().IsVideo())
+ if (IsA<LayoutVideo>(layer->GetLayoutObject()) ||
+ IsA<LayoutVideo>(squashing_layer.GetLayoutObject()))
return SquashingDisallowedReason::kSquashingVideoIsDisallowed;
// Don't squash iframes, frames or plugins.
@@ -164,9 +163,6 @@ CompositingLayerAssigner::GetReasonsPreventingSquashing(
if (layer->ScrollsWithRespectTo(&squashing_layer))
return SquashingDisallowedReason::kScrollsWithRespectToSquashingLayer;
- if (layer->ScrollParent() && layer->HasCompositingDescendant())
- return SquashingDisallowedReason::kScrollChildWithCompositedDescendants;
-
if (layer->OpacityAncestor() != squashing_layer.OpacityAncestor())
return SquashingDisallowedReason::kOpacityAncestorMismatch;
@@ -292,15 +288,6 @@ void CompositingLayerAssigner::AssignLayersToBackingsInternal(
layer, composited_layer_update)) {
layers_needing_paint_invalidation.push_back(layer);
layers_changed_ = true;
- if (ScrollingCoordinator* scrolling_coordinator =
- layer->GetScrollingCoordinator()) {
- if (layer->GetLayoutObject()
- .StyleRef()
- .HasViewportConstrainedPosition()) {
- scrolling_coordinator->FrameViewFixedObjectsDidChange(
- layer->GetLayoutObject().View()->GetFrameView());
- }
- }
}
if (composited_layer_update != kNoCompositingStateChange) {
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 e4e34b370fd..557f55726ee 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
@@ -43,7 +43,6 @@ class CompositingLayerAssigner {
public:
explicit CompositingLayerAssigner(PaintLayerCompositor*);
- ~CompositingLayerAssigner();
void Assign(PaintLayer* update_root,
Vector<PaintLayer*>& layers_needing_paint_invalidation);
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 0ee97e10d65..3570a6d184e 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
@@ -4,22 +4,20 @@
#include "third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h"
-#include "base/feature_list.h"
-#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/core/css/css_property_names.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/node.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/fullscreen/fullscreen.h"
-#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
+#include "third_party/blink/renderer/core/html/html_body_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/page.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/public/common/features.h"
-
namespace blink {
CompositingReasons CompositingReasonFinder::DirectReasons(
@@ -70,7 +68,7 @@ CompositingReasonFinder::PotentialCompositingReasonsFromStyle(
if (style.BackfaceVisibility() == EBackfaceVisibility::kHidden)
reasons |= CompositingReason::kBackfaceVisibilityHidden;
- reasons |= CompositingReasonsForAnimation(style);
+ reasons |= CompositingReasonsForAnimation(layout_object);
reasons |= CompositingReasonsForWillChange(style);
// If the implementation of CreatesGroup changes, we need to be aware of that
@@ -106,6 +104,26 @@ CompositingReasonFinder::PotentialCompositingReasonsFromStyle(
return reasons;
}
+static bool ShouldPreferCompositingForLayoutView(
+ const LayoutView& layout_view) {
+ auto has_direct_compositing_reasons = [](const LayoutObject* object) -> bool {
+ return object && CompositingReasonFinder::DirectReasonsForPaintProperties(
+ *object) != CompositingReason::kNone;
+ };
+ if (has_direct_compositing_reasons(
+ layout_view.GetFrame()->OwnerLayoutObject()))
+ return true;
+ if (auto* document_element = layout_view.GetDocument().documentElement()) {
+ if (has_direct_compositing_reasons(document_element->GetLayoutObject()))
+ return true;
+ }
+ if (auto* body = layout_view.GetDocument().FirstBodyElement()) {
+ if (has_direct_compositing_reasons(body->GetLayoutObject()))
+ return true;
+ }
+ return false;
+}
+
CompositingReasons CompositingReasonFinder::DirectReasonsForPaintProperties(
const LayoutObject& object) {
// TODO(wangxianzhu): Don't depend on PaintLayer for CompositeAfterPaint.
@@ -113,7 +131,7 @@ CompositingReasons CompositingReasonFinder::DirectReasonsForPaintProperties(
return CompositingReason::kNone;
const ComputedStyle& style = object.StyleRef();
- auto reasons = CompositingReasonsForAnimation(style) |
+ auto reasons = CompositingReasonsForAnimation(object) |
CompositingReasonsForWillChange(style);
if (RequiresCompositingFor3DTransform(object))
@@ -141,7 +159,15 @@ CompositingReasons CompositingReasonFinder::DirectReasonsForPaintProperties(
if (auto* scrollable_area = layer->GetScrollableArea()) {
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
bool force_prefer_compositing_to_lcd_text =
- reasons != CompositingReason::kNone;
+ 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.
+ style.BackfaceVisibility() == EBackfaceVisibility::kHidden ||
+ (object.IsLayoutView() &&
+ ShouldPreferCompositingForLayoutView(To<LayoutView>(object)));
+
if (scrollable_area->ComputeNeedsCompositedScrolling(
force_prefer_compositing_to_lcd_text)) {
reasons |= CompositingReason::kOverflowScrolling;
@@ -153,6 +179,9 @@ CompositingReasons CompositingReasonFinder::DirectReasonsForPaintProperties(
}
}
+ if (object.CanHaveAdditionalCompositingReasons())
+ reasons |= object.AdditionalCompositingReasons();
+
return reasons;
}
@@ -165,10 +194,8 @@ bool CompositingReasonFinder::RequiresCompositingFor3DTransform(
return false;
// Don't composite "trivial" 3D transforms such as translateZ(0).
- if (Platform::Current()->IsLowEndDevice() ||
- base::FeatureList::IsEnabled(blink::features::kDoNotCompositeTrivial3D)) {
+ if (Platform::Current()->IsLowEndDevice())
return layout_object.StyleRef().HasNonTrivial3DTransformOperation();
- }
return layout_object.StyleRef().Has3DTransformOperation();
}
@@ -202,17 +229,16 @@ CompositingReasons CompositingReasonFinder::NonStyleDeterminedDirectReasons(
// into. These children (the controls) always need to be promoted into their
// own layers to draw on top of the accelerated video.
if (layer.CompositingContainer() &&
- layer.CompositingContainer()->GetLayoutObject().IsVideo())
+ IsA<LayoutVideo>(layer.CompositingContainer()->GetLayoutObject()))
direct_reasons |= CompositingReason::kVideoOverlay;
- const Node* node = layer.GetLayoutObject().GetNode();
-
// Special case for immersive-ar DOM overlay mode, see also
- // PaintLayerCompositor::ApplyXrImmersiveDomOverlayIfNeeded()
- if (node && node->IsElementNode() &&
- node->GetDocument().IsImmersiveArOverlay() &&
- node == Fullscreen::FullscreenElementFrom(node->GetDocument())) {
- direct_reasons |= CompositingReason::kImmersiveArOverlay;
+ // PaintLayerCompositor::GetXrOverlayLayer()
+ if (const Node* node = layer.GetLayoutObject().GetNode()) {
+ if (node->IsElementNode() && node->GetDocument().IsXrOverlay() &&
+ node == Fullscreen::FullscreenElementFrom(node->GetDocument())) {
+ direct_reasons |= CompositingReason::kXrOverlay;
+ }
}
if (layer.IsRootLayer() &&
@@ -221,20 +247,8 @@ CompositingReasons CompositingReasonFinder::NonStyleDeterminedDirectReasons(
direct_reasons |= CompositingReason::kRoot;
}
- // Composite all cross-origin iframes, to improve compositor hit testing for
- // input event targeting. crbug.com/1014273
- if (node && node->IsFrameOwnerElement() &&
- base::FeatureList::IsEnabled(
- blink::features::kCompositeCrossOriginIframes)) {
- if (Frame* iframe_frame = To<HTMLFrameOwnerElement>(node)->ContentFrame()) {
- if (!iframe_frame->GetSecurityContext()->GetSecurityOrigin()->CanAccess(
- node->GetDocument().GetSecurityOrigin())) {
- direct_reasons |= CompositingReason::kCrossOriginIframe;
- }
- }
- }
-
- direct_reasons |= layout_object.AdditionalCompositingReasons();
+ if (layout_object.CanHaveAdditionalCompositingReasons())
+ direct_reasons |= layout_object.AdditionalCompositingReasons();
DCHECK(
!(direct_reasons & CompositingReason::kComboAllStyleDeterminedReasons));
@@ -242,12 +256,15 @@ CompositingReasons CompositingReasonFinder::NonStyleDeterminedDirectReasons(
}
CompositingReasons CompositingReasonFinder::CompositingReasonsForAnimation(
- const ComputedStyle& style) {
+ const LayoutObject& object) {
CompositingReasons reasons = CompositingReason::kNone;
+ const auto& style = object.StyleRef();
if (style.SubtreeWillChangeContents())
return reasons;
- if (style.HasCurrentTransformAnimation())
+ // Transforms don't apply on non-replaced inline elements.
+ // TODO(crbug.com/666244): Support composited transform animation for SVG.
+ if (object.IsBox() && style.HasCurrentTransformAnimation())
reasons |= CompositingReason::kActiveTransformAnimation;
if (style.HasCurrentOpacityAnimation())
reasons |= CompositingReason::kActiveOpacityAnimation;
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 11e4288a051..212d9ef4c33 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
@@ -35,8 +35,7 @@ class CORE_EXPORT CompositingReasonFinder {
const LayoutObject&);
static bool RequiresCompositingForScrollableFrame(const LayoutView&);
- static CompositingReasons CompositingReasonsForAnimation(
- const ComputedStyle&);
+ static CompositingReasons CompositingReasonsForAnimation(const LayoutObject&);
static CompositingReasons CompositingReasonsForWillChange(
const ComputedStyle&);
static bool RequiresCompositingFor3DTransform(const LayoutObject&);
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 670ba475352..ec556f3f98d 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
@@ -23,11 +23,13 @@ class CompositingReasonFinderTest : public RenderingTest {
CompositingReasonFinderTest()
: RenderingTest(MakeGarbageCollected<SingleChildLocalFrameClient>()) {}
- private:
+ protected:
void SetUp() override {
EnableCompositing();
RenderingTest::SetUp();
}
+
+ void CheckCompositingReasonsForAnimation(bool supports_transform_animation);
};
TEST_F(CompositingReasonFinderTest, CompositingReasonDependencies) {
@@ -40,42 +42,7 @@ TEST_F(CompositingReasonFinderTest, CompositingReasonDependencies) {
CompositingReason::kComboAllStyleDeterminedReasons);
}
-class CompositingReasonFinderTestWithDoNotCompositeTrivial3D
- : public CompositingReasonFinderTest {
- public:
- CompositingReasonFinderTestWithDoNotCompositeTrivial3D() {
- scoped_feature_list_.InitAndEnableFeature(
- blink::features::kDoNotCompositeTrivial3D);
- }
-
- base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-TEST_F(CompositingReasonFinderTestWithDoNotCompositeTrivial3D,
- DontPromoteTrivial3D) {
- SetBodyInnerHTML(R"HTML(
- <div id='target'
- style='width: 100px; height: 100px; transform: translateZ(0)'></div>
- )HTML");
-
- Element* target = GetDocument().getElementById("target");
- PaintLayer* paint_layer =
- ToLayoutBoxModelObject(target->GetLayoutObject())->Layer();
- EXPECT_EQ(kNotComposited, paint_layer->GetCompositingState());
-}
-
-class CompositingReasonFinderTestWithCompositeTrivial3D
- : public CompositingReasonFinderTest {
- public:
- CompositingReasonFinderTestWithCompositeTrivial3D() {
- scoped_feature_list_.InitAndDisableFeature(
- blink::features::kDoNotCompositeTrivial3D);
- }
-
- base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-TEST_F(CompositingReasonFinderTestWithCompositeTrivial3D, PromoteTrivial3D) {
+TEST_F(CompositingReasonFinderTest, PromoteTrivial3D) {
SetBodyInnerHTML(R"HTML(
<div id='target'
style='width: 100px; height: 100px; transform: translateZ(0)'></div>
@@ -142,6 +109,42 @@ TEST_F(CompositingReasonFinderTest, OnlyAnchoredStickyPositionPromoted) {
->GetCompositingState());
}
+TEST_F(CompositingReasonFinderTest,
+ OnlyAnchoredStickyPositionPromotedAssumeOverlap) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitWithFeatureState(
+ blink::features::kAssumeOverlapAfterFixedOrStickyPosition, true);
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ .scroller {contain: paint; width: 400px; height: 400px; overflow: auto;
+ will-change: transform;}
+ .sticky { position: sticky; width: 10px; height: 10px;}</style>
+ <div class='scroller'>
+ <div id='sticky-top' class='sticky' style='top: 0px;'></div>
+ <div id='sticky-no-anchor' class='sticky'></div>
+ <div style='height: 2000px;'></div>
+ </div>
+ )HTML");
+
+ EXPECT_EQ(kPaintsIntoOwnBacking,
+ ToLayoutBoxModelObject(GetLayoutObjectByElementId("sticky-top"))
+ ->Layer()
+ ->GetCompositingState());
+ // Any scroll dependent layer, such as sticky-top, assumes that it overlaps
+ // anything which draws after it.
+ EXPECT_EQ(
+ kPaintsIntoOwnBacking,
+ ToLayoutBoxModelObject(GetLayoutObjectByElementId("sticky-no-anchor"))
+ ->Layer()
+ ->GetCompositingState());
+ EXPECT_EQ(
+ CompositingReason::kAssumedOverlap,
+ ToLayoutBoxModelObject(GetLayoutObjectByElementId("sticky-no-anchor"))
+ ->Layer()
+ ->GetCompositingReasons() &
+ CompositingReason::kAssumedOverlap);
+}
+
TEST_F(CompositingReasonFinderTest, OnlyScrollingStickyPositionPromoted) {
SetBodyInnerHTML(R"HTML(
<style>.scroller {width: 400px; height: 400px; overflow: auto;
@@ -169,7 +172,9 @@ TEST_F(CompositingReasonFinderTest, OnlyScrollingStickyPositionPromoted) {
->GetCompositingState());
}
-TEST_F(CompositingReasonFinderTest, CompositingReasonsForAnimation) {
+void CompositingReasonFinderTest::CheckCompositingReasonsForAnimation(
+ bool supports_transform_animation) {
+ auto* object = GetLayoutObjectByElementId("target");
scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
style->SetSubtreeWillChangeContents(false);
@@ -177,32 +182,47 @@ TEST_F(CompositingReasonFinderTest, CompositingReasonsForAnimation) {
style->SetHasCurrentOpacityAnimation(false);
style->SetHasCurrentFilterAnimation(false);
style->SetHasCurrentBackdropFilterAnimation(false);
+ object->SetStyle(style);
+
EXPECT_EQ(CompositingReason::kNone,
- CompositingReasonFinder::CompositingReasonsForAnimation(*style));
+ CompositingReasonFinder::CompositingReasonsForAnimation(*object));
+
+ CompositingReasons expected_compositing_reason_for_transform_animation =
+ supports_transform_animation
+ ? CompositingReason::kActiveTransformAnimation
+ : CompositingReason::kNone;
style->SetHasCurrentTransformAnimation(true);
- EXPECT_EQ(CompositingReason::kActiveTransformAnimation,
- CompositingReasonFinder::CompositingReasonsForAnimation(*style));
+ EXPECT_EQ(expected_compositing_reason_for_transform_animation,
+ CompositingReasonFinder::CompositingReasonsForAnimation(*object));
style->SetHasCurrentOpacityAnimation(true);
- EXPECT_EQ(CompositingReason::kActiveTransformAnimation |
+ EXPECT_EQ(expected_compositing_reason_for_transform_animation |
CompositingReason::kActiveOpacityAnimation,
- CompositingReasonFinder::CompositingReasonsForAnimation(*style));
+ CompositingReasonFinder::CompositingReasonsForAnimation(*object));
style->SetHasCurrentFilterAnimation(true);
- EXPECT_EQ(CompositingReason::kActiveTransformAnimation |
+ EXPECT_EQ(expected_compositing_reason_for_transform_animation |
CompositingReason::kActiveOpacityAnimation |
CompositingReason::kActiveFilterAnimation,
- CompositingReasonFinder::CompositingReasonsForAnimation(*style));
+ CompositingReasonFinder::CompositingReasonsForAnimation(*object));
style->SetHasCurrentBackdropFilterAnimation(true);
- EXPECT_EQ(CompositingReason::kActiveTransformAnimation |
+ EXPECT_EQ(expected_compositing_reason_for_transform_animation |
CompositingReason::kActiveOpacityAnimation |
CompositingReason::kActiveFilterAnimation |
CompositingReason::kActiveBackdropFilterAnimation,
- CompositingReasonFinder::CompositingReasonsForAnimation(*style));
- EXPECT_EQ(CompositingReason::kComboActiveAnimation,
- CompositingReasonFinder::CompositingReasonsForAnimation(*style));
+ CompositingReasonFinder::CompositingReasonsForAnimation(*object));
+}
+
+TEST_F(CompositingReasonFinderTest, CompositingReasonsForAnimationBox) {
+ SetBodyInnerHTML("<div id='target'>Target</div>");
+ CheckCompositingReasonsForAnimation(/*supports_transform_animation*/ true);
+}
+
+TEST_F(CompositingReasonFinderTest, CompositingReasonsForAnimationInline) {
+ SetBodyInnerHTML("<span id='target'>Target</span>");
+ CheckCompositingReasonsForAnimation(/*supports_transform_animation*/ false);
}
TEST_F(CompositingReasonFinderTest, DontPromoteEmptyIframe) {
@@ -241,7 +261,7 @@ TEST_F(CompositingReasonFinderTest, PromoteCrossOriginIframe) {
ASSERT_TRUE(iframe_layer);
ASSERT_FALSE(To<HTMLFrameOwnerElement>(iframe)
->ContentFrame()
- ->IsCrossOriginSubframe());
+ ->IsCrossOriginToMainFrame());
EXPECT_EQ(kNotComposited, iframe_layer->DirectCompositingReasons());
SetBodyInnerHTML(R"HTML(
@@ -256,8 +276,8 @@ TEST_F(CompositingReasonFinderTest, PromoteCrossOriginIframe) {
ASSERT_TRUE(iframe_layer);
ASSERT_TRUE(To<HTMLFrameOwnerElement>(iframe)
->ContentFrame()
- ->IsCrossOriginSubframe());
- EXPECT_EQ(CompositingReason::kCrossOriginIframe,
+ ->IsCrossOriginToMainFrame());
+ EXPECT_EQ(CompositingReason::kIFrame,
iframe_layer->DirectCompositingReasons());
}
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 966c367af23..0b9f70b8b36 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/public/common/features.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"
@@ -209,8 +210,6 @@ CompositingRequirementsUpdater::CompositingRequirementsUpdater(
LayoutView& layout_view)
: layout_view_(layout_view) {}
-CompositingRequirementsUpdater::~CompositingRequirementsUpdater() = default;
-
void CompositingRequirementsUpdater::Update(
PaintLayer* root,
CompositingReasonsStats& compositing_reasons_stats) {
@@ -597,7 +596,10 @@ void CompositingRequirementsUpdater::UpdateRecursive(
CompositingReason::kClipsCompositingDescendants);
if ((!child_recursion_data.testing_overlap_ &&
!is_composited_clipping_layer) ||
- layer->GetLayoutObject().StyleRef().HasCurrentTransformAnimation())
+ layer->GetLayoutObject().StyleRef().HasCurrentTransformAnimation() ||
+ ((direct_reasons & CompositingReason::kScrollDependentPosition) &&
+ base::FeatureList::IsEnabled(
+ features::kAssumeOverlapAfterFixedOrStickyPosition)))
current_recursion_data.testing_overlap_ = false;
if (child_recursion_data.compositing_ancestor_ == layer)
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.h b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.h
index dcb9464a6d9..6f1d051d9da 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.h
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.h
@@ -42,7 +42,6 @@ class CompositingRequirementsUpdater {
public:
CompositingRequirementsUpdater(LayoutView&);
- ~CompositingRequirementsUpdater();
// Recurse through the layers in z-index and overflow order (which is
// equivalent to painting order)
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 8100621f58d..15bb8e48d76 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
@@ -4,13 +4,12 @@
#include "third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.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/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
+#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
namespace blink {
@@ -128,19 +127,7 @@ TEST_F(CompositingRequirementsUpdaterTest,
EXPECT_EQ(IntRect(0, 0, 100, 100), tracking->Invalidations()[0].rect);
}
-class CompositingRequirementsUpdaterTestWithDoNotCompositeTrivial3D
- : public CompositingRequirementsUpdaterTest {
- public:
- CompositingRequirementsUpdaterTestWithDoNotCompositeTrivial3D() {
- scoped_feature_list_.InitAndEnableFeature(
- blink::features::kDoNotCompositeTrivial3D);
- }
-
- base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-TEST_F(CompositingRequirementsUpdaterTestWithDoNotCompositeTrivial3D,
- NonTrivial3DTransforms) {
+TEST_F(CompositingRequirementsUpdaterTest, NonTrivial3DTransforms) {
ScopedCSSIndependentTransformPropertiesForTest feature_scope(true);
SetBodyInnerHTML(R"HTML(
@@ -169,7 +156,7 @@ TEST_F(CompositingRequirementsUpdaterTestWithDoNotCompositeTrivial3D,
ToLayoutBox(transform_3d)->Layer()->GetCompositingReasons());
const auto* transform_2d = GetLayoutObjectByElementId("2d-transform");
EXPECT_FALSE(transform_2d->StyleRef().HasNonTrivial3DTransformOperation());
- EXPECT_FALSE(ToLayoutBox(transform_2d)->Layer()->GetCompositingReasons());
+ EXPECT_TRUE(ToLayoutBox(transform_2d)->Layer()->GetCompositingReasons());
const auto* transform_3d_translate_z =
GetLayoutObjectByElementId("3d-transform-translate-z");
@@ -182,7 +169,7 @@ TEST_F(CompositingRequirementsUpdaterTestWithDoNotCompositeTrivial3D,
GetLayoutObjectByElementId("2d-transform-translate-z");
EXPECT_FALSE(
transform_2d_translate_z->StyleRef().HasNonTrivial3DTransformOperation());
- EXPECT_FALSE(
+ EXPECT_TRUE(
ToLayoutBox(transform_2d_translate_z)->Layer()->GetCompositingReasons());
const auto* transform_2d_translate_x =
GetLayoutObjectByElementId("2d-transform-translate-x");
@@ -197,7 +184,7 @@ TEST_F(CompositingRequirementsUpdaterTestWithDoNotCompositeTrivial3D,
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_FALSE(ToLayoutBox(xform_rot_x_2d)->Layer()->GetCompositingReasons());
+ EXPECT_TRUE(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());
@@ -208,7 +195,7 @@ TEST_F(CompositingRequirementsUpdaterTestWithDoNotCompositeTrivial3D,
ToLayoutBox(rotation_y_3d)->Layer()->GetCompositingReasons());
const auto* rotation_y_2d = GetLayoutObjectByElementId("2d-rotation-y");
EXPECT_FALSE(rotation_y_2d->StyleRef().HasNonTrivial3DTransformOperation());
- EXPECT_FALSE(ToLayoutBox(rotation_y_2d)->Layer()->GetCompositingReasons());
+ EXPECT_TRUE(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 55dfee22796..cefe3499d81 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
@@ -2,18 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "cc/layers/picture_layer.h"
#include "cc/trees/effect_node.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/scroll_and_scale_set.h"
+#include "cc/trees/scroll_node.h"
#include "cc/trees/transform_node.h"
#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/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"
#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_box.h"
#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
@@ -48,9 +52,9 @@ class CompositingTest : public PaintTestConfigurations, public testing::Test {
// Both sets the inner html and runs the document lifecycle.
void InitializeWithHTML(LocalFrame& frame, const String& html_content) {
- frame.GetDocument()->body()->SetInnerHTMLFromString(html_content);
+ frame.GetDocument()->body()->setInnerHTML(html_content);
frame.GetDocument()->View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
}
WebLocalFrame* LocalMainFrame() { return web_view_helper_->LocalMainFrame(); }
@@ -66,7 +70,8 @@ class CompositingTest : public PaintTestConfigurations, public testing::Test {
}
const cc::Layer* CcLayerByDOMElementId(const char* id) {
- return CcLayersByDOMElementId(RootCcLayer(), id)[0];
+ auto layers = CcLayersByDOMElementId(RootCcLayer(), id);
+ return layers.IsEmpty() ? nullptr : layers[0];
}
cc::LayerTreeHost* LayerTreeHost() {
@@ -80,7 +85,7 @@ class CompositingTest : public PaintTestConfigurations, public testing::Test {
void UpdateAllLifecyclePhases() {
WebView()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
}
private:
@@ -92,7 +97,7 @@ class CompositingTest : public PaintTestConfigurations, public testing::Test {
std::unique_ptr<frame_test_helpers::WebViewHelper> web_view_helper_;
};
-INSTANTIATE_LAYER_LIST_TEST_SUITE_P(CompositingTest);
+INSTANTIATE_PAINT_TEST_SUITE_P(CompositingTest);
TEST_P(CompositingTest, DidScrollCallbackAfterScrollableAreaChanges) {
InitializeWithHTML(*WebView()->MainFrameImpl()->GetFrame(),
@@ -121,9 +126,13 @@ TEST_P(CompositingTest, DidScrollCallbackAfterScrollableAreaChanges) {
CompositorElementId scroll_element_id = scrollable_area->GetScrollElementId();
const auto* overflow_scroll_layer =
CcLayerByCcElementId(RootCcLayer(), scroll_element_id);
- EXPECT_TRUE(overflow_scroll_layer->scrollable());
- EXPECT_EQ(overflow_scroll_layer->scroll_container_bounds(),
- gfx::Size(100, 100));
+ const auto* scroll_node =
+ RootCcLayer()
+ ->layer_tree_host()
+ ->property_trees()
+ ->scroll_tree.FindNodeFromElementId(scroll_element_id);
+ EXPECT_TRUE(scroll_node->scrollable);
+ EXPECT_EQ(scroll_node->container_bounds, gfx::Size(100, 100));
// Ensure a synthetic impl-side scroll offset propagates to the scrollable
// area using the DidScroll callback.
@@ -151,8 +160,10 @@ TEST_P(CompositingTest, DidScrollCallbackAfterScrollableAreaChanges) {
// apply impl-side offsets without crashing.
ASSERT_EQ(overflow_scroll_layer,
CcLayerByCcElementId(RootCcLayer(), scroll_element_id));
- const_cast<cc::Layer*>(overflow_scroll_layer)
- ->SetScrollOffsetFromImplSide(gfx::ScrollOffset(0, 3));
+ scroll_and_scale_set.scrolls[0] = {scroll_element_id, gfx::ScrollOffset(0, 1),
+ base::nullopt};
+ overflow_scroll_layer->layer_tree_host()->ApplyScrollAndScale(
+ &scroll_and_scale_set);
UpdateAllLifecyclePhases();
EXPECT_FALSE(CcLayerByCcElementId(RootCcLayer(), scroll_element_id));
@@ -173,9 +184,13 @@ TEST_P(CompositingTest, FrameViewScroll) {
auto* scrollable_area = GetLocalFrameView()->LayoutViewport();
EXPECT_NE(nullptr, scrollable_area);
- const auto* scroll_layer = CcLayerByCcElementId(
- RootCcLayer(), scrollable_area->GetScrollElementId());
- EXPECT_TRUE(scroll_layer->scrollable());
+ const auto* scroll_node = RootCcLayer()
+ ->layer_tree_host()
+ ->property_trees()
+ ->scroll_tree.FindNodeFromElementId(
+ scrollable_area->GetScrollElementId());
+ ASSERT_TRUE(scroll_node);
+ EXPECT_TRUE(scroll_node->scrollable);
// Ensure a synthetic impl-side scroll offset propagates to the scrollable
// area using the DidScroll callback.
@@ -184,16 +199,31 @@ TEST_P(CompositingTest, FrameViewScroll) {
scroll_and_scale_set.scrolls.push_back({scrollable_area->GetScrollElementId(),
gfx::ScrollOffset(0, 1),
base::nullopt});
- scroll_layer->layer_tree_host()->ApplyScrollAndScale(&scroll_and_scale_set);
+ RootCcLayer()->layer_tree_host()->ApplyScrollAndScale(&scroll_and_scale_set);
UpdateAllLifecyclePhases();
EXPECT_EQ(ScrollOffset(0, 1), scrollable_area->GetScrollOffset());
}
+TEST_P(CompositingTest, WillChangeTransformHint) {
+ InitializeWithHTML(*WebView()->MainFrameImpl()->GetFrame(), R"HTML(
+ <style>
+ #willChange {
+ width: 100px;
+ height: 100px;
+ will-change: transform;
+ background: blue;
+ }
+ </style>
+ <div id="willChange"></div>
+ )HTML");
+ UpdateAllLifecyclePhases();
+ auto* layer = CcLayerByDOMElementId("willChange");
+ EXPECT_TRUE(layer->has_will_change_transform_hint());
+}
+
class CompositingSimTest : public PaintTestConfigurations, public SimTest {
public:
void InitializeWithHTML(const String& html) {
- WebView().MainFrameWidget()->Resize(WebSize(800, 600));
-
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
request.Complete(html);
@@ -206,7 +236,8 @@ class CompositingSimTest : public PaintTestConfigurations, public SimTest {
}
const cc::Layer* CcLayerByDOMElementId(const char* id) {
- return CcLayersByDOMElementId(RootCcLayer(), id)[0];
+ auto layers = CcLayersByDOMElementId(RootCcLayer(), id);
+ return layers.IsEmpty() ? nullptr : layers[0];
}
Element* GetElementById(const AtomicString& id) {
@@ -215,17 +246,16 @@ class CompositingSimTest : public PaintTestConfigurations, public SimTest {
void UpdateAllLifecyclePhases() {
WebView().MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
}
void UpdateAllLifecyclePhasesExceptPaint() {
- WebView().MainFrameWidget()->UpdateLifecycle(
- WebWidget::LifecycleUpdate::kPrePaint,
- WebWidget::LifecycleUpdateReason::kTest);
+ WebView().MainFrameWidget()->UpdateLifecycle(WebLifecycleUpdate::kPrePaint,
+ DocumentUpdateReason::kTest);
}
cc::PropertyTrees* GetPropertyTrees() {
- return Compositor().layer_tree_host().property_trees();
+ return Compositor().layer_tree_host()->property_trees();
}
cc::TransformNode* GetTransformNode(const cc::Layer* layer) {
@@ -240,17 +270,18 @@ class CompositingSimTest : public PaintTestConfigurations, public SimTest {
PaintArtifactCompositor* paint_artifact_compositor() {
return MainFrame().GetFrameView()->GetPaintArtifactCompositor();
}
+
+ private:
+ void SetUp() override {
+ SimTest::SetUp();
+ // Ensure a non-empty size so painting does not early-out.
+ WebView().Resize(WebSize(800, 600));
+ }
};
-INSTANTIATE_LAYER_LIST_TEST_SUITE_P(CompositingSimTest);
+INSTANTIATE_PAINT_TEST_SUITE_P(CompositingSimTest);
TEST_P(CompositingSimTest, LayerUpdatesDoNotInvalidateEarlierLayers) {
- // TODO(crbug.com/765003): CAP may make different layerization decisions and
- // we cannot guarantee that both divs will be composited in this test. When
- // CAP gets closer to launch, this test should be updated to pass.
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
- return;
-
InitializeWithHTML(R"HTML(
<!DOCTYPE html>
<style>
@@ -259,6 +290,7 @@ TEST_P(CompositingSimTest, LayerUpdatesDoNotInvalidateEarlierLayers) {
width: 100px;
height: 100px;
will-change: transform;
+ background: lightblue;
}
</style>
<div id='a'></div>
@@ -267,19 +299,12 @@ TEST_P(CompositingSimTest, LayerUpdatesDoNotInvalidateEarlierLayers) {
Compositor().BeginFrame();
- auto* a_element = GetElementById("a");
auto* a_layer = CcLayerByDOMElementId("a");
- DCHECK_EQ(a_layer->element_id(), CompositorElementIdFromUniqueObjectId(
- a_element->GetLayoutObject()->UniqueId(),
- CompositorElementIdNamespace::kPrimary));
auto* b_element = GetElementById("b");
auto* b_layer = CcLayerByDOMElementId("b");
- DCHECK_EQ(b_layer->element_id(), CompositorElementIdFromUniqueObjectId(
- b_element->GetLayoutObject()->UniqueId(),
- CompositorElementIdNamespace::kPrimary));
// Initially, neither a nor b should have a layer that should push properties.
- cc::LayerTreeHost& host = Compositor().layer_tree_host();
+ cc::LayerTreeHost& host = *Compositor().layer_tree_host();
EXPECT_FALSE(host.LayersThatShouldPushProperties().count(a_layer));
EXPECT_FALSE(host.LayersThatShouldPushProperties().count(b_layer));
@@ -296,12 +321,6 @@ TEST_P(CompositingSimTest, LayerUpdatesDoNotInvalidateEarlierLayers) {
}
TEST_P(CompositingSimTest, LayerUpdatesDoNotInvalidateLaterLayers) {
- // TODO(crbug.com/765003): CAP may make different layerization decisions and
- // we cannot guarantee that both divs will be composited in this test. When
- // CAP gets closer to launch, this test should be updated to pass.
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
- return;
-
InitializeWithHTML(R"HTML(
<!DOCTYPE html>
<style>
@@ -310,6 +329,7 @@ TEST_P(CompositingSimTest, LayerUpdatesDoNotInvalidateLaterLayers) {
width: 100px;
height: 100px;
will-change: transform;
+ background: lightblue;
}
</style>
<div id='a'></div>
@@ -321,22 +341,12 @@ TEST_P(CompositingSimTest, LayerUpdatesDoNotInvalidateLaterLayers) {
auto* a_element = GetElementById("a");
auto* a_layer = CcLayerByDOMElementId("a");
- DCHECK_EQ(a_layer->element_id(), CompositorElementIdFromUniqueObjectId(
- a_element->GetLayoutObject()->UniqueId(),
- CompositorElementIdNamespace::kPrimary));
auto* b_element = GetElementById("b");
auto* b_layer = CcLayerByDOMElementId("b");
- DCHECK_EQ(b_layer->element_id(), CompositorElementIdFromUniqueObjectId(
- b_element->GetLayoutObject()->UniqueId(),
- CompositorElementIdNamespace::kPrimary));
- auto* c_element = GetElementById("c");
auto* c_layer = CcLayerByDOMElementId("c");
- DCHECK_EQ(c_layer->element_id(), CompositorElementIdFromUniqueObjectId(
- c_element->GetLayoutObject()->UniqueId(),
- CompositorElementIdNamespace::kPrimary));
// Initially, no layer should need to push properties.
- cc::LayerTreeHost& host = Compositor().layer_tree_host();
+ cc::LayerTreeHost& host = *Compositor().layer_tree_host();
EXPECT_FALSE(host.LayersThatShouldPushProperties().count(a_layer));
EXPECT_FALSE(host.LayersThatShouldPushProperties().count(b_layer));
EXPECT_FALSE(host.LayersThatShouldPushProperties().count(c_layer));
@@ -374,7 +384,7 @@ TEST_P(CompositingSimTest,
Compositor().BeginFrame();
// Initially the host should not need to sync.
- cc::LayerTreeHost& layer_tree_host = Compositor().layer_tree_host();
+ cc::LayerTreeHost& layer_tree_host = *Compositor().layer_tree_host();
EXPECT_FALSE(layer_tree_host.needs_full_tree_sync());
int sequence_number = GetPropertyTrees()->sequence_number;
EXPECT_GT(sequence_number, 0);
@@ -394,12 +404,6 @@ TEST_P(CompositingSimTest,
// non-layer-list mode, this occurs in BuildPropertyTreesInternal (see:
// SetLayerPropertyChangedForChild).
TEST_P(CompositingSimTest, LayerSubtreeTransformPropertyChanged) {
- // TODO(crbug.com/765003): CAP may make different layerization decisions and
- // we cannot guarantee that both divs will be composited in this test. When
- // CAP gets closer to launch, this test should be updated to pass.
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
- return;
-
InitializeWithHTML(R"HTML(
<!DOCTYPE html>
<style>
@@ -409,6 +413,7 @@ TEST_P(CompositingSimTest, LayerSubtreeTransformPropertyChanged) {
height: 100px;
will-change: transform;
transform: translate(10px, 10px);
+ background: lightgreen;
}
#inner {
width: 100px;
@@ -426,16 +431,7 @@ TEST_P(CompositingSimTest, LayerSubtreeTransformPropertyChanged) {
auto* outer_element = GetElementById("outer");
auto* outer_element_layer = CcLayerByDOMElementId("outer");
- DCHECK_EQ(outer_element_layer->element_id(),
- CompositorElementIdFromUniqueObjectId(
- outer_element->GetLayoutObject()->UniqueId(),
- CompositorElementIdNamespace::kPrimary));
- auto* inner_element = GetElementById("inner");
auto* inner_element_layer = CcLayerByDOMElementId("inner");
- DCHECK_EQ(inner_element_layer->element_id(),
- CompositorElementIdFromUniqueObjectId(
- inner_element->GetLayoutObject()->UniqueId(),
- CompositorElementIdNamespace::kPrimary));
// Initially, no layer should have |subtree_property_changed| set.
EXPECT_FALSE(outer_element_layer->subtree_property_changed());
@@ -471,12 +467,6 @@ TEST_P(CompositingSimTest, LayerSubtreeTransformPropertyChanged) {
// |transform_changed| set. In non-layer-list mode, this occurs in
// cc::TransformTree::OnTransformAnimated and cc::Layer::SetTransform.
TEST_P(CompositingSimTest, DirectTransformPropertyUpdate) {
- // TODO(crbug.com/765003): CAP may make different layerization decisions and
- // we cannot guarantee that both divs will be composited in this test. When
- // CAP gets closer to launch, this test should be updated to pass.
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
- return;
-
InitializeWithHTML(R"HTML(
<!DOCTYPE html>
<style>
@@ -486,6 +476,7 @@ TEST_P(CompositingSimTest, DirectTransformPropertyUpdate) {
height: 100px;
will-change: transform;
transform: translate(10px, 10px) scale(1, 2);
+ background: lightgreen;
}
#inner {
width: 100px;
@@ -503,10 +494,6 @@ TEST_P(CompositingSimTest, DirectTransformPropertyUpdate) {
auto* outer_element = GetElementById("outer");
auto* outer_element_layer = CcLayerByDOMElementId("outer");
- DCHECK_EQ(outer_element_layer->element_id(),
- CompositorElementIdFromUniqueObjectId(
- outer_element->GetLayoutObject()->UniqueId(),
- CompositorElementIdNamespace::kPrimary));
auto transform_tree_index = outer_element_layer->transform_tree_index();
auto* transform_node =
GetPropertyTrees()->transform_tree.Node(transform_tree_index);
@@ -531,12 +518,6 @@ TEST_P(CompositingSimTest, DirectTransformPropertyUpdate) {
// the changed value of a directly updated transform is still set if some other
// change causes PaintArtifactCompositor to run and do non-direct updates.
TEST_P(CompositingSimTest, DirectTransformPropertyUpdateCausesChange) {
- // TODO(crbug.com/765003): CAP may make different layerization decisions and
- // we cannot guarantee that both divs will be composited in this test. When
- // CAP gets closer to launch, this test should be updated to pass.
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
- return;
-
InitializeWithHTML(R"HTML(
<!DOCTYPE html>
<style>
@@ -546,6 +527,7 @@ TEST_P(CompositingSimTest, DirectTransformPropertyUpdateCausesChange) {
height: 100px;
will-change: transform;
transform: translate(1px, 2px);
+ background: lightgreen;
}
#inner {
width: 100px;
@@ -564,20 +546,12 @@ TEST_P(CompositingSimTest, DirectTransformPropertyUpdateCausesChange) {
auto* outer_element = GetElementById("outer");
auto* outer_element_layer = CcLayerByDOMElementId("outer");
- DCHECK_EQ(outer_element_layer->element_id(),
- CompositorElementIdFromUniqueObjectId(
- outer_element->GetLayoutObject()->UniqueId(),
- CompositorElementIdNamespace::kPrimary));
auto outer_transform_tree_index = outer_element_layer->transform_tree_index();
auto* outer_transform_node =
GetPropertyTrees()->transform_tree.Node(outer_transform_tree_index);
auto* inner_element = GetElementById("inner");
auto* inner_element_layer = CcLayerByDOMElementId("inner");
- DCHECK_EQ(inner_element_layer->element_id(),
- CompositorElementIdFromUniqueObjectId(
- inner_element->GetLayoutObject()->UniqueId(),
- CompositorElementIdNamespace::kPrimary));
auto inner_transform_tree_index = inner_element_layer->transform_tree_index();
auto* inner_transform_node =
GetPropertyTrees()->transform_tree.Node(inner_transform_tree_index);
@@ -680,12 +654,6 @@ TEST_P(CompositingSimTest, AffectedByOuterViewportBoundsDelta) {
// |transform_changed| set. In non-layer-list mode, this occurs in
// cc::Layer::SetTransformOrigin.
TEST_P(CompositingSimTest, DirectTransformOriginPropertyUpdate) {
- // TODO(crbug.com/765003): CAP may make different layerization decisions and
- // we cannot guarantee that both divs will be composited in this test. When
- // CAP gets closer to launch, this test should be updated to pass.
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
- return;
-
InitializeWithHTML(R"HTML(
<!DOCTYPE html>
<style>
@@ -695,6 +663,7 @@ TEST_P(CompositingSimTest, DirectTransformOriginPropertyUpdate) {
height: 100px;
transform: rotate3d(3, 2, 1, 45deg);
transform-origin: 10px 10px 100px;
+ background: lightblue;
}
</style>
<div id='box'></div>
@@ -704,10 +673,6 @@ TEST_P(CompositingSimTest, DirectTransformOriginPropertyUpdate) {
auto* box_element = GetElementById("box");
auto* box_element_layer = CcLayerByDOMElementId("box");
- DCHECK_EQ(box_element_layer->element_id(),
- CompositorElementIdFromUniqueObjectId(
- box_element->GetLayoutObject()->UniqueId(),
- CompositorElementIdNamespace::kPrimary));
auto transform_tree_index = box_element_layer->transform_tree_index();
auto* transform_node =
GetPropertyTrees()->transform_tree.Node(transform_tree_index);
@@ -803,12 +768,6 @@ TEST_P(CompositingSimTest, LayerSubtreeEffectPropertyChanged) {
// This test is similar to |LayerSubtreeTransformPropertyChanged| but for
// clip property node changes.
TEST_P(CompositingSimTest, LayerSubtreeClipPropertyChanged) {
- // TODO(crbug.com/765003): CAP may make different layerization decisions and
- // we cannot guarantee that both divs will be composited in this test. When
- // CAP gets closer to launch, this test should be updated to pass.
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
- return;
-
InitializeWithHTML(R"HTML(
<!DOCTYPE html>
<style>
@@ -819,6 +778,7 @@ TEST_P(CompositingSimTest, LayerSubtreeClipPropertyChanged) {
will-change: transform;
position: absolute;
clip: rect(10px, 80px, 70px, 40px);
+ background: lightgreen;
}
#inner {
width: 100px;
@@ -836,12 +796,7 @@ TEST_P(CompositingSimTest, LayerSubtreeClipPropertyChanged) {
auto* outer_element = GetElementById("outer");
auto* outer_element_layer = CcLayerByDOMElementId("outer");
- auto* inner_element = GetElementById("inner");
auto* inner_element_layer = CcLayerByDOMElementId("inner");
- DCHECK_EQ(inner_element_layer->element_id(),
- CompositorElementIdFromUniqueObjectId(
- inner_element->GetLayoutObject()->UniqueId(),
- CompositorElementIdNamespace::kPrimary));
// Initially, no layer should have |subtree_property_changed| set.
EXPECT_FALSE(outer_element_layer->subtree_property_changed());
@@ -1118,4 +1073,143 @@ TEST_P(CompositingSimTest, NoRenderSurfaceWithAxisAlignedTransformAnimation) {
}
}
+TEST_P(CompositingSimTest, PromoteCrossOriginIframe) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitWithFeatureState(
+ blink::features::kCompositeCrossOriginIframes, true);
+ InitializeWithHTML("<!DOCTYPE html><iframe id=iframe sandbox></iframe>");
+ Compositor().BeginFrame();
+ EXPECT_TRUE(CcLayerByDOMElementId("iframe"));
+}
+
+// On initial layout, the iframe is not yet loaded and is not considered
+// cross origin. This test ensures the iframe is promoted due to being cross
+// origin after the iframe loads.
+TEST_P(CompositingSimTest, PromoteCrossOriginIframeAfterLoading) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitWithFeatureState(
+ blink::features::kCompositeCrossOriginIframes, true);
+
+ SimRequest main_resource("https://origin-a.com/a.html", "text/html");
+ SimRequest frame_resource("https://origin-b.com/b.html", "text/html");
+
+ LoadURL("https://origin-a.com/a.html");
+ main_resource.Complete(R"HTML(
+ <!DOCTYPE html>
+ <iframe id="iframe" src="https://origin-b.com/b.html"></iframe>
+ )HTML");
+ frame_resource.Complete("<!DOCTYPE html>");
+ Compositor().BeginFrame();
+
+ EXPECT_TRUE(CcLayerByDOMElementId("iframe"));
+}
+
+// An iframe that is cross-origin to the parent should be composited. This test
+// sets up nested frames with domains A -> B -> A. Both the child and grandchild
+// frames should be composited because they are cross-origin to their parent.
+TEST_P(CompositingSimTest, PromoteCrossOriginToParent) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitWithFeatureState(
+ blink::features::kCompositeCrossOriginIframes, true);
+
+ SimRequest main_resource("https://origin-a.com/a.html", "text/html");
+ SimRequest child_resource("https://origin-b.com/b.html", "text/html");
+ SimRequest grandchild_resource("https://origin-a.com/c.html", "text/html");
+
+ LoadURL("https://origin-a.com/a.html");
+ main_resource.Complete(R"HTML(
+ <!DOCTYPE html>
+ <iframe id="main_iframe" src="https://origin-b.com/b.html"></iframe>
+ )HTML");
+ child_resource.Complete(R"HTML(
+ <!DOCTYPE html>
+ <iframe id="child_iframe" src="https://origin-a.com/c.html"></iframe>
+ )HTML");
+ grandchild_resource.Complete("<!DOCTYPE html>");
+ Compositor().BeginFrame();
+
+ EXPECT_TRUE(CcLayerByDOMElementId("main_iframe"));
+ EXPECT_TRUE(CcLayerByDOMElementId("child_iframe"));
+}
+
+// Initially the iframe is cross-origin and should be composited. After changing
+// to same-origin, the frame should no longer be composited.
+TEST_P(CompositingSimTest, PromoteCrossOriginIframeAfterDomainChange) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitWithFeatureState(
+ blink::features::kCompositeCrossOriginIframes, true);
+
+ SimRequest main_resource("https://origin-a.com/a.html", "text/html");
+ SimRequest frame_resource("https://sub.origin-a.com/b.html", "text/html");
+
+ LoadURL("https://origin-a.com/a.html");
+ main_resource.Complete(R"HTML(
+ <!DOCTYPE html>
+ <iframe id="iframe" src="https://sub.origin-a.com/b.html"></iframe>
+ )HTML");
+ frame_resource.Complete("<!DOCTYPE html>");
+ Compositor().BeginFrame();
+
+ EXPECT_TRUE(CcLayerByDOMElementId("iframe"));
+
+ auto* iframe_element =
+ To<HTMLIFrameElement>(GetDocument().getElementById("iframe"));
+ NonThrowableExceptionState exception_state;
+ GetDocument().setDomain(String("origin-a.com"), exception_state);
+ iframe_element->contentDocument()->setDomain(String("origin-a.com"),
+ exception_state);
+ // We may not have scheduled a visual update so force an update instead of
+ // using BeginFrame.
+ UpdateAllLifecyclePhases();
+
+ EXPECT_FALSE(CcLayerByDOMElementId("iframe"));
+}
+
+// This test sets up nested frames with domains A -> B -> A. Initially, the
+// child frame and grandchild frame should be composited. After changing the
+// child frame to A (same-origin), both child and grandchild frames should no
+// longer be composited.
+TEST_P(CompositingSimTest, PromoteCrossOriginToParentIframeAfterDomainChange) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitWithFeatureState(
+ blink::features::kCompositeCrossOriginIframes, true);
+
+ SimRequest main_resource("https://origin-a.com/a.html", "text/html");
+ SimRequest child_resource("https://sub.origin-a.com/b.html", "text/html");
+ SimRequest grandchild_resource("https://origin-a.com/c.html", "text/html");
+
+ LoadURL("https://origin-a.com/a.html");
+ main_resource.Complete(R"HTML(
+ <!DOCTYPE html>
+ <iframe id="main_iframe" src="https://sub.origin-a.com/b.html"></iframe>
+ )HTML");
+ child_resource.Complete(R"HTML(
+ <!DOCTYPE html>
+ <iframe id="child_iframe" src="https://origin-a.com/c.html"></iframe>
+ )HTML");
+ grandchild_resource.Complete("<!DOCTYPE html>");
+ Compositor().BeginFrame();
+
+ EXPECT_TRUE(CcLayerByDOMElementId("main_iframe"));
+ EXPECT_TRUE(CcLayerByDOMElementId("child_iframe"));
+
+ auto* main_iframe_element =
+ To<HTMLIFrameElement>(GetDocument().getElementById("main_iframe"));
+ NonThrowableExceptionState exception_state;
+ GetDocument().setDomain(String("origin-a.com"), exception_state);
+ auto* child_iframe_element = To<HTMLIFrameElement>(
+ main_iframe_element->contentDocument()->getElementById("child_iframe"));
+ child_iframe_element->contentDocument()->setDomain(String("origin-a.com"),
+ exception_state);
+ main_iframe_element->contentDocument()->setDomain(String("origin-a.com"),
+ exception_state);
+
+ // We may not have scheduled a visual update so force an update instead of
+ // using BeginFrame.
+ UpdateAllLifecyclePhases();
+
+ EXPECT_FALSE(CcLayerByDOMElementId("main_iframe"));
+ EXPECT_FALSE(CcLayerByDOMElementId("child_iframe"));
+}
+
} // 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 8be2ec4a1b5..fce32e76d78 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
@@ -15,9 +15,7 @@ namespace {
std::unique_ptr<JSONObject> GraphicsLayerAsJSON(const GraphicsLayer* layer,
LayerTreeFlags flags) {
- // Intentionally passing through 0, 0 for the offset from the transform node
- // as this dump implementation doesn't support transform/position information.
- auto json = CCLayerAsJSON(layer->CcLayer(), flags, FloatPoint());
+ auto json = CCLayerAsJSON(layer->CcLayer(), flags);
// Content dumped after this point, down to AppendAdditionalInfoAsJSON, is
// specific to GraphicsLayer tree dumping when called from one of the methods
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 bceebbc05cd..6e5eaa164fe 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
@@ -38,8 +38,6 @@ namespace blink {
GraphicsLayerTreeBuilder::GraphicsLayerTreeBuilder() = default;
-GraphicsLayerTreeBuilder::~GraphicsLayerTreeBuilder() = default;
-
static bool ShouldAppendLayer(const PaintLayer& layer) {
auto* video_element =
DynamicTo<HTMLVideoElement>(layer.GetLayoutObject().GetNode());
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.h b/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.h
index 88e607b9442..b1ef0a4f661 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.h
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_tree_builder.h
@@ -39,7 +39,6 @@ class GraphicsLayerTreeBuilder {
public:
GraphicsLayerTreeBuilder();
- ~GraphicsLayerTreeBuilder();
void Rebuild(PaintLayer&, GraphicsLayerVector&);
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 e1df9970626..3026c276c50 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
@@ -104,8 +104,6 @@ GraphicsLayerUpdater::UpdateContext::CompositingStackingContext() const {
GraphicsLayerUpdater::GraphicsLayerUpdater() : needs_rebuild_tree_(false) {}
-GraphicsLayerUpdater::~GraphicsLayerUpdater() = default;
-
void GraphicsLayerUpdater::Update(
PaintLayer& layer,
Vector<PaintLayer*>& layers_needing_paint_invalidation) {
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.h b/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.h
index 9a98a937df3..54c765cc6db 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.h
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.h
@@ -39,7 +39,6 @@ class GraphicsLayerUpdater {
public:
GraphicsLayerUpdater();
- ~GraphicsLayerUpdater();
enum UpdateType {
kDoNotForceUpdate,
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 6fcd60085aa..3f7a2b6c166 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
@@ -66,10 +66,9 @@
namespace blink {
PaintLayerCompositor::PaintLayerCompositor(LayoutView& layout_view)
- : layout_view_(layout_view),
- has_accelerated_compositing_(layout_view.GetDocument()
- .GetSettings()
- ->GetAcceleratedCompositingEnabled()) {}
+ : layout_view_(layout_view) {
+ DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
+}
PaintLayerCompositor::~PaintLayerCompositor() {
DCHECK_EQ(root_layer_attachment_, kRootLayerUnattached);
@@ -135,7 +134,9 @@ void PaintLayerCompositor::EnableCompositingModeIfNeeded() {
bool PaintLayerCompositor::RootShouldAlwaysComposite() const {
// If compositing is disabled for the WebView, then nothing composites.
- if (!has_accelerated_compositing_)
+ if (!layout_view_.GetDocument()
+ .GetSettings()
+ ->GetAcceleratedCompositingEnabled())
return false;
// Local roots composite always, when compositing is enabled globally.
if (layout_view_.GetFrame()->IsLocalRoot())
@@ -150,23 +151,11 @@ bool PaintLayerCompositor::RootShouldAlwaysComposite() const {
}
void PaintLayerCompositor::UpdateAcceleratedCompositingSettings() {
- // AcceleratedCompositing setting does not change after initialization.
- DCHECK_EQ(has_accelerated_compositing_,
- layout_view_.GetDocument()
- .GetSettings()
- ->GetAcceleratedCompositingEnabled());
-
root_should_always_composite_dirty_ = true;
if (root_layer_attachment_ != kRootLayerUnattached)
RootLayer()->SetNeedsCompositingInputsUpdate();
}
-bool PaintLayerCompositor::PreferCompositingToLCDTextEnabled() const {
- return layout_view_.GetDocument()
- .GetSettings()
- ->GetPreferCompositingToLCDTextEnabled();
-}
-
static LayoutVideo* FindFullscreenVideoLayoutObject(Document& document) {
// Recursively find the document that is in fullscreen.
Element* fullscreen_element = Fullscreen::FullscreenElementFrom(document);
@@ -181,9 +170,7 @@ static LayoutVideo* FindFullscreenVideoLayoutObject(Document& document) {
if (!IsA<HTMLVideoElement>(fullscreen_element))
return nullptr;
LayoutObject* layout_object = fullscreen_element->GetLayoutObject();
- if (!layout_object)
- return nullptr;
- return ToLayoutVideo(layout_object);
+ return To<LayoutVideo>(layout_object);
}
void PaintLayerCompositor::UpdateIfNeededRecursive(
@@ -321,7 +308,9 @@ GraphicsLayer* PaintLayerCompositor::OverlayFullscreenVideoGraphicsLayer()
void PaintLayerCompositor::UpdateWithoutAcceleratedCompositing(
CompositingUpdateType update_type) {
- DCHECK(!HasAcceleratedCompositing());
+ DCHECK(!layout_view_.GetDocument()
+ .GetSettings()
+ ->GetAcceleratedCompositingEnabled());
if (update_type >= kCompositingUpdateAfterCompositingInputChange) {
CompositingInputsUpdater(RootLayer(), GetCompositingInputsRoot()).Update();
@@ -379,7 +368,9 @@ void PaintLayerCompositor::UpdateIfNeeded(
CompositingUpdateType update_type = pending_update_type_;
pending_update_type_ = kCompositingUpdateNone;
- if (!HasAcceleratedCompositing()) {
+ if (!layout_view_.GetDocument()
+ .GetSettings()
+ ->GetAcceleratedCompositingEnabled()) {
UpdateWithoutAcceleratedCompositing(update_type);
Lifecycle().AdvanceTo(
std::min(DocumentLifecycle::kCompositingClean, target_state));
@@ -563,14 +554,6 @@ bool PaintLayerCompositor::AllocateOrClearCompositedLayerMapping(
layer->ClearClipRects(kPaintingClipRects);
- // If a fixed position layer gained/lost a compositedLayerMapping or the
- // reason not compositing it changed, the scrolling coordinator needs to
- // recalculate whether it can do fast scrolling.
- if (ScrollingCoordinator* scrolling_coordinator = GetScrollingCoordinator()) {
- scrolling_coordinator->FrameViewFixedObjectsDidChange(
- layout_view_.GetFrameView());
- }
-
// Compositing state affects whether to create paint offset translation of
// this layer, and amount of paint offset translation of descendants.
layer->GetLayoutObject().SetNeedsPaintPropertyUpdate();
@@ -658,13 +641,13 @@ GraphicsLayer* PaintLayerCompositor::RootGraphicsLayer() const {
return nullptr;
}
-GraphicsLayer* PaintLayerCompositor::GetXrImmersiveDomOverlayLayer() const {
+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().IsImmersiveArOverlay())
+ if (!layout_view_.GetDocument().IsXrOverlay())
return nullptr;
Element* fullscreen_element =
@@ -695,7 +678,7 @@ GraphicsLayer* PaintLayerCompositor::PaintRootGraphicsLayer() const {
// Start from the full screen overlay layer if exists. Other layers will be
// skipped during painting.
- if (auto* layer = GetXrImmersiveDomOverlayLayer())
+ if (auto* layer = GetXrOverlayLayer())
return layer;
if (auto* layer = OverlayFullscreenVideoGraphicsLayer())
return layer;
@@ -719,8 +702,10 @@ bool PaintLayerCompositor::CanBeComposited(const PaintLayer* layer) const {
const bool has_compositor_animation =
CompositingReasonFinder::CompositingReasonsForAnimation(
- *layer->GetLayoutObject().Style()) != CompositingReason::kNone;
- return has_accelerated_compositing_ &&
+ layer->GetLayoutObject()) != CompositingReason::kNone;
+ return layout_view_.GetDocument()
+ .GetSettings()
+ ->GetAcceleratedCompositingEnabled() &&
(has_compositor_animation || !layer->SubtreeIsInvisible()) &&
layer->IsSelfPaintingLayer() &&
!layer->GetLayoutObject().IsLayoutFlowThread() &&
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 b54493ba61e..e747e628c87 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
@@ -95,13 +95,6 @@ class CORE_EXPORT PaintLayerCompositor {
// to the native view/window system.
void SetCompositingModeEnabled(bool);
- // Returns true if the accelerated compositing is enabled
- bool HasAcceleratedCompositing() const {
- return has_accelerated_compositing_;
- }
-
- bool PreferCompositingToLCDTextEnabled() const;
-
bool RootShouldAlwaysComposite() const;
// Notifies about changes to PreferCompositingToLCDText or
@@ -195,10 +188,9 @@ class CORE_EXPORT PaintLayerCompositor {
bool IsMainFrame() const;
- GraphicsLayer* GetXrImmersiveDomOverlayLayer() const;
+ GraphicsLayer* GetXrOverlayLayer() const;
LayoutView& layout_view_;
- const bool has_accelerated_compositing_ = true;
bool compositing_ = false;
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor_test.cc b/chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor_test.cc
index f79b67a6769..669148c9936 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor_test.cc
@@ -36,7 +36,8 @@ TEST_F(PaintLayerCompositorTest, AdvancingToCompositingInputsClean) {
box_layer->SetNeedsCompositingInputsUpdate();
- GetDocument().View()->UpdateLifecycleToCompositingInputsClean();
+ GetDocument().View()->UpdateLifecycleToCompositingInputsClean(
+ DocumentUpdateReason::kTest);
EXPECT_EQ(DocumentLifecycle::kCompositingInputsClean,
GetDocument().Lifecycle().GetState());
EXPECT_FALSE(box_layer->NeedsCompositingInputsUpdate());
@@ -63,7 +64,8 @@ TEST_F(PaintLayerCompositorTest,
// Update the lifecycle to CompositingInputsClean. This should not start the
// animation lifecycle.
- GetDocument().View()->UpdateLifecycleToCompositingInputsClean();
+ GetDocument().View()->UpdateLifecycleToCompositingInputsClean(
+ DocumentUpdateReason::kTest);
EXPECT_EQ(DocumentLifecycle::kCompositingInputsClean,
GetDocument().Lifecycle().GetState());
@@ -110,7 +112,8 @@ TEST_F(PaintLayerCompositorTest, CompositingInputsUpdateStopsContainStrict) {
EXPECT_FALSE(wrapper->NeedsCompositingInputsUpdate());
EXPECT_TRUE(target->NeedsCompositingInputsUpdate());
- GetDocument().View()->UpdateLifecycleToCompositingInputsClean();
+ GetDocument().View()->UpdateLifecycleToCompositingInputsClean(
+ DocumentUpdateReason::kTest);
EXPECT_EQ(DocumentLifecycle::kCompositingInputsClean,
GetDocument().Lifecycle().GetState());
EXPECT_FALSE(wrapper->NeedsCompositingInputsUpdate());
diff --git a/chromium/third_party/blink/renderer/core/paint/css_mask_painter.cc b/chromium/third_party/blink/renderer/core/paint/css_mask_painter.cc
index 25432d2d1ea..269bc6bc6df 100644
--- a/chromium/third_party/blink/renderer/core/paint/css_mask_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/css_mask_painter.cc
@@ -23,8 +23,9 @@ base::Optional<IntRect> CSSMaskPainter::MaskBoundingBox(
SVGResourcesCache::CachedResourcesForLayoutObject(object);
LayoutSVGResourceMasker* masker = resources ? resources->Masker() : nullptr;
if (masker) {
- return EnclosingIntRect(
- masker->ResourceBoundingBox(object.ObjectBoundingBox()));
+ const FloatRect reference_box =
+ SVGResources::ReferenceBoxForEffects(object);
+ return EnclosingIntRect(masker->ResourceBoundingBox(reference_box));
}
}
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 2e1600aba58..75934b0f5c3 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
@@ -41,13 +41,26 @@ CustomScrollbarTheme* CustomScrollbarTheme::GetCustomScrollbarTheme() {
return &theme;
}
+ScrollbarPart CustomScrollbarTheme::HitTest(const Scrollbar& scrollbar,
+ const IntPoint& test_position) {
+ auto result = ScrollbarTheme::HitTest(scrollbar, test_position);
+ if (result == kScrollbarBGPart) {
+ // The ScrollbarTheme knows nothing about the double buttons.
+ if (ButtonRect(scrollbar, kBackButtonEndPart).Contains(test_position))
+ return kBackButtonEndPart;
+ if (ButtonRect(scrollbar, kForwardButtonStartPart).Contains(test_position))
+ return kForwardButtonStartPart;
+ }
+ return result;
+}
+
void CustomScrollbarTheme::ButtonSizesAlongTrackAxis(const Scrollbar& scrollbar,
int& before_size,
int& after_size) {
- IntRect first_button = BackButtonRect(scrollbar, kBackButtonStartPart);
- IntRect second_button = ForwardButtonRect(scrollbar, kForwardButtonStartPart);
- IntRect third_button = BackButtonRect(scrollbar, kBackButtonEndPart);
- IntRect fourth_button = ForwardButtonRect(scrollbar, kForwardButtonEndPart);
+ IntRect first_button = ButtonRect(scrollbar, kBackButtonStartPart);
+ IntRect second_button = ButtonRect(scrollbar, kForwardButtonStartPart);
+ IntRect third_button = ButtonRect(scrollbar, kBackButtonEndPart);
+ IntRect fourth_button = ButtonRect(scrollbar, kForwardButtonEndPart);
if (scrollbar.Orientation() == kHorizontalScrollbar) {
before_size = first_button.Width() + second_button.Width();
after_size = third_button.Width() + fourth_button.Width();
@@ -74,14 +87,17 @@ int CustomScrollbarTheme::MinimumThumbLength(const Scrollbar& scrollbar) {
return To<CustomScrollbar>(scrollbar).MinimumThumbLength();
}
-IntRect CustomScrollbarTheme::BackButtonRect(const Scrollbar& scrollbar,
- ScrollbarPart part_type) {
+IntRect CustomScrollbarTheme::ButtonRect(const Scrollbar& scrollbar,
+ ScrollbarPart part_type) {
return To<CustomScrollbar>(scrollbar).ButtonRect(part_type);
}
-IntRect CustomScrollbarTheme::ForwardButtonRect(const Scrollbar& scrollbar,
- ScrollbarPart part_type) {
- return To<CustomScrollbar>(scrollbar).ButtonRect(part_type);
+IntRect CustomScrollbarTheme::BackButtonRect(const Scrollbar& scrollbar) {
+ return ButtonRect(scrollbar, kBackButtonStartPart);
+}
+
+IntRect CustomScrollbarTheme::ForwardButtonRect(const Scrollbar& scrollbar) {
+ return ButtonRect(scrollbar, kForwardButtonEndPart);
}
IntRect CustomScrollbarTheme::TrackRect(const Scrollbar& scrollbar) {
@@ -141,17 +157,15 @@ void CustomScrollbarTheme::PaintTrackAndButtons(GraphicsContext& context,
PaintPart(context, scrollbar, scrollbar.FrameRect(), kScrollbarBGPart);
if (HasButtons(scrollbar)) {
- PaintButton(context, scrollbar,
- BackButtonRect(scrollbar, kBackButtonStartPart),
+ PaintButton(context, scrollbar, ButtonRect(scrollbar, kBackButtonStartPart),
kBackButtonStartPart);
- PaintButton(context, scrollbar,
- BackButtonRect(scrollbar, kBackButtonEndPart),
+ PaintButton(context, scrollbar, ButtonRect(scrollbar, kBackButtonEndPart),
kBackButtonEndPart);
PaintButton(context, scrollbar,
- ForwardButtonRect(scrollbar, kForwardButtonStartPart),
+ ButtonRect(scrollbar, kForwardButtonStartPart),
kForwardButtonStartPart);
PaintButton(context, scrollbar,
- ForwardButtonRect(scrollbar, kForwardButtonEndPart),
+ ButtonRect(scrollbar, kForwardButtonEndPart),
kForwardButtonEndPart);
}
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 7b72703ac91..eecbdda3cd1 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
@@ -44,8 +44,8 @@ class CustomScrollbarTheme final : public ScrollbarTheme {
return GetTheme().ScrollbarThickness(control_size);
}
- WebScrollbarButtonsPlacement ButtonsPlacement() const override {
- return GetTheme().ButtonsPlacement();
+ bool NativeThemeHasButtons() override {
+ return GetTheme().NativeThemeHasButtons();
}
void PaintScrollCorner(GraphicsContext&,
@@ -89,11 +89,13 @@ class CustomScrollbarTheme final : public ScrollbarTheme {
const CustomScrollbar* = nullptr);
protected:
+ ScrollbarPart HitTest(const Scrollbar&, const IntPoint&) override;
+
bool HasButtons(const Scrollbar&) override;
bool HasThumb(const Scrollbar&) override;
- IntRect BackButtonRect(const Scrollbar&, ScrollbarPart) override;
- IntRect ForwardButtonRect(const Scrollbar&, ScrollbarPart) override;
+ IntRect BackButtonRect(const Scrollbar&) override;
+ IntRect ForwardButtonRect(const Scrollbar&) override;
IntRect TrackRect(const Scrollbar&) override;
void PaintTrackAndButtons(GraphicsContext&,
@@ -112,6 +114,7 @@ class CustomScrollbarTheme final : public ScrollbarTheme {
const IntRect&) override;
private:
+ IntRect ButtonRect(const Scrollbar&, ScrollbarPart);
void PaintScrollbarBackground(GraphicsContext&, const Scrollbar&);
void PaintTrackBackground(GraphicsContext&, const Scrollbar&, const IntRect&);
void PaintTrackPiece(GraphicsContext&,
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 41bd8afeb85..0d0459e9d09 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
@@ -95,25 +95,8 @@ sk_sp<PaintRecord> RecordMarker(Color blink_color) {
void DrawDocumentMarker(GraphicsContext& context,
const FloatPoint& pt,
float width,
- DocumentMarker::MarkerType marker_type,
- float zoom) {
- DCHECK(marker_type == DocumentMarker::kSpelling ||
- marker_type == DocumentMarker::kGrammar);
-
- DEFINE_STATIC_LOCAL(
- PaintRecord*, spelling_marker,
- (RecordMarker(
- LayoutTheme::GetTheme().PlatformSpellingMarkerUnderlineColor())
- .release()));
- DEFINE_STATIC_LOCAL(
- PaintRecord*, grammar_marker,
- (RecordMarker(
- LayoutTheme::GetTheme().PlatformGrammarMarkerUnderlineColor())
- .release()));
- auto* const marker = marker_type == DocumentMarker::kSpelling
- ? spelling_marker
- : grammar_marker;
-
+ float zoom,
+ PaintRecord* const marker) {
// Position already includes zoom and device scale factor.
SkScalar origin_x = WebCoreFloatToSkScalar(pt.X());
SkScalar origin_y = WebCoreFloatToSkScalar(pt.Y());
@@ -185,14 +168,49 @@ void DocumentMarkerPainter::PaintStyleableMarkerUnderline(
marker.UseTextColor()
? style.VisitedDependentColor(GetCSSPropertyWebkitTextFillColor())
: marker.UnderlineColor();
- context.SetStrokeColor(marker_color);
-
- context.SetStrokeThickness(line_thickness);
- context.DrawLineForText(
- FloatPoint(
- box_origin.left + start,
- (box_origin.top + logical_height.ToInt() - line_thickness).ToFloat()),
- width);
+ if (marker.UnderlineStyle() !=
+ ui::mojom::ImeTextSpanUnderlineStyle::kSquiggle) {
+ context.SetStrokeColor(marker_color);
+ context.SetStrokeThickness(line_thickness);
+ // Set the style of the underline if there is any.
+ switch (marker.UnderlineStyle()) {
+ case ui::mojom::ImeTextSpanUnderlineStyle::kDash:
+ context.SetStrokeStyle(StrokeStyle::kDashedStroke);
+ break;
+ case ui::mojom::ImeTextSpanUnderlineStyle::kDot:
+ context.SetStrokeStyle(StrokeStyle::kDottedStroke);
+ break;
+ case ui::mojom::ImeTextSpanUnderlineStyle::kSolid:
+ context.SetStrokeStyle(StrokeStyle::kSolidStroke);
+ break;
+ case ui::mojom::ImeTextSpanUnderlineStyle::kNone:
+ context.SetStrokeStyle(StrokeStyle::kNoStroke);
+ break;
+ case ui::mojom::ImeTextSpanUnderlineStyle::kSquiggle:
+ // Wavy stroke style is not implemented in DrawLineForText so we handle
+ // it specially in the else condition below only for composition
+ // markers.
+ break;
+ }
+ context.DrawLineForText(
+ FloatPoint(box_origin.left + start,
+ (box_origin.top + logical_height.ToInt() - line_thickness)
+ .ToFloat()),
+ width);
+ } else {
+ // For wavy underline format we use this logic that is very similar to
+ // spelling/grammar squiggles format. Only applicable for composition
+ // markers for now.
+ if (marker.GetType() == DocumentMarker::kComposition) {
+ sk_sp<PaintRecord> composition_marker = (RecordMarker(marker_color));
+ DrawDocumentMarker(
+ context,
+ FloatPoint((box_origin.left + start).ToFloat(),
+ (box_origin.top + logical_height.ToInt() - line_thickness)
+ .ToFloat()),
+ width, line_thickness, composition_marker.get());
+ }
+ }
}
void DocumentMarkerPainter::PaintDocumentMarker(
@@ -210,7 +228,7 @@ void DocumentMarkerPainter::PaintDocumentMarker(
// place the underline at the bottom of the text, but in larger fonts that's
// not so good so we pin to two pixels under the baseline.
float zoom = style.EffectiveZoom();
- int line_thickness = kMarkerHeight * zoom;
+ int line_thickness = static_cast<int>(ceilf(kMarkerHeight * zoom));
const SimpleFontData* font_data = style.GetFont().PrimaryFont();
DCHECK(font_data);
@@ -227,10 +245,24 @@ void DocumentMarkerPainter::PaintDocumentMarker(
// prevent a big gap.
underline_offset = baseline + 2 * zoom;
}
+ DEFINE_STATIC_LOCAL(
+ PaintRecord*, spelling_marker,
+ (RecordMarker(
+ LayoutTheme::GetTheme().PlatformSpellingMarkerUnderlineColor())
+ .release()));
+ DEFINE_STATIC_LOCAL(
+ PaintRecord*, grammar_marker,
+ (RecordMarker(
+ LayoutTheme::GetTheme().PlatformGrammarMarkerUnderlineColor())
+ .release()));
+
+ auto* const marker = marker_type == DocumentMarker::kSpelling
+ ? spelling_marker
+ : grammar_marker;
DrawDocumentMarker(context,
FloatPoint((box_origin.left + local_rect.X()).ToFloat(),
(box_origin.top + underline_offset).ToFloat()),
- local_rect.Width().ToFloat(), marker_type, zoom);
+ local_rect.Width().ToFloat(), zoom, marker);
}
TextPaintStyle DocumentMarkerPainter::ComputeTextPaintStyleFrom(
diff --git a/chromium/third_party/blink/renderer/core/paint/ellipsis_box_painter.cc b/chromium/third_party/blink/renderer/core/paint/ellipsis_box_painter.cc
index df0263b1c2c..d4b65ec7134 100644
--- a/chromium/third_party/blink/renderer/core/paint/ellipsis_box_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/ellipsis_box_painter.cc
@@ -22,7 +22,7 @@ void EllipsisBoxPainter::Paint(const PaintInfo& paint_info,
const LayoutPoint& paint_offset,
LayoutUnit line_top,
LayoutUnit line_bottom) {
- if (paint_info.phase == PaintPhase::kSelection)
+ if (paint_info.phase == PaintPhase::kSelectionDragImage)
return;
const ComputedStyle& style = ellipsis_box_.GetLineLayoutItem().StyleRef(
diff --git a/chromium/third_party/blink/renderer/core/paint/embedded_object_painter.cc b/chromium/third_party/blink/renderer/core/paint/embedded_object_painter.cc
index 43663833e74..9b93bd124de 100644
--- a/chromium/third_party/blink/renderer/core/paint/embedded_object_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/embedded_object_painter.cc
@@ -31,7 +31,6 @@ static Font ReplacementTextFont() {
font_description.SetWeight(BoldWeightValue());
font_description.SetComputedSize(font_description.SpecifiedSize());
Font font(font_description);
- font.Update(nullptr);
return font;
}
@@ -43,7 +42,7 @@ void EmbeddedObjectPainter::PaintReplaced(const PaintInfo& paint_info,
return;
}
- if (paint_info.phase == PaintPhase::kSelection)
+ if (paint_info.phase == PaintPhase::kSelectionDragImage)
return;
GraphicsContext& context = paint_info.context;
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 f6fa95b1c13..900b20688cf 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
@@ -27,7 +27,6 @@
#include "third_party/blink/renderer/core/paint/filter_effect_builder.h"
#include <algorithm>
-#include "third_party/blink/public/platform/web_point.h"
#include "third_party/blink/renderer/core/style/filter_operations.h"
#include "third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.h"
#include "third_party/blink/renderer/core/svg/svg_filter_element.h"
@@ -165,14 +164,16 @@ FilterEffect* FilterEffectBuilder::BuildFilterEffect(
Vector<float> input_parameters = GrayscaleMatrix(
To<BasicColorMatrixFilterOperation>(filter_operation)->Amount());
effect = MakeGarbageCollected<FEColorMatrix>(
- parent_filter, FECOLORMATRIX_TYPE_MATRIX, input_parameters);
+ parent_filter, FECOLORMATRIX_TYPE_MATRIX,
+ std::move(input_parameters));
break;
}
case FilterOperation::SEPIA: {
Vector<float> input_parameters = SepiaMatrix(
To<BasicColorMatrixFilterOperation>(filter_operation)->Amount());
effect = MakeGarbageCollected<FEColorMatrix>(
- parent_filter, FECOLORMATRIX_TYPE_MATRIX, input_parameters);
+ parent_filter, FECOLORMATRIX_TYPE_MATRIX,
+ std::move(input_parameters));
break;
}
case FilterOperation::SATURATE: {
@@ -180,7 +181,8 @@ FilterEffect* FilterEffectBuilder::BuildFilterEffect(
input_parameters.push_back(clampTo<float>(
To<BasicColorMatrixFilterOperation>(filter_operation)->Amount()));
effect = MakeGarbageCollected<FEColorMatrix>(
- parent_filter, FECOLORMATRIX_TYPE_SATURATE, input_parameters);
+ parent_filter, FECOLORMATRIX_TYPE_SATURATE,
+ std::move(input_parameters));
break;
}
case FilterOperation::HUE_ROTATE: {
@@ -188,7 +190,8 @@ FilterEffect* FilterEffectBuilder::BuildFilterEffect(
input_parameters.push_back(clampTo<float>(
To<BasicColorMatrixFilterOperation>(filter_operation)->Amount()));
effect = MakeGarbageCollected<FEColorMatrix>(
- parent_filter, FECOLORMATRIX_TYPE_HUEROTATE, input_parameters);
+ parent_filter, FECOLORMATRIX_TYPE_HUEROTATE,
+ std::move(input_parameters));
break;
}
case FilterOperation::INVERT: {
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 3eaac6137e5..97c06979db0 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
@@ -151,16 +151,15 @@ void FirstMeaningfulPaintDetector::RegisterNotifySwapTime(PaintEvent event) {
WrapCrossThreadWeakPersistent(this), event));
}
-void FirstMeaningfulPaintDetector::ReportSwapTime(
- PaintEvent event,
- WebWidgetClient::SwapResult result,
- base::TimeTicks timestamp) {
+void FirstMeaningfulPaintDetector::ReportSwapTime(PaintEvent event,
+ WebSwapResult result,
+ base::TimeTicks timestamp) {
DCHECK(event == PaintEvent::kProvisionalFirstMeaningfulPaint);
DCHECK_GT(outstanding_swap_promise_count_, 0U);
--outstanding_swap_promise_count_;
// If the swap fails for any reason, we use the timestamp when the SwapPromise
- // was broken. |result| == WebWidgetClient::SwapResult::kDidNotSwapSwapFails
+ // was broken. |result| == WebSwapResult::kDidNotSwapSwapFails
// usually means the compositor decided not swap because there was no actual
// damage, which can happen when what's being painted isn't visible. In this
// case, the timestamp will be consistent with the case where the swap
@@ -224,7 +223,7 @@ void FirstMeaningfulPaintDetector::SetTickClockForTesting(
g_clock = clock;
}
-void FirstMeaningfulPaintDetector::Trace(blink::Visitor* visitor) {
+void FirstMeaningfulPaintDetector::Trace(Visitor* visitor) {
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 a0c9db2c3f2..a093acfcf0b 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
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_FIRST_MEANINGFUL_PAINT_DETECTOR_H_
#include "base/macros.h"
-#include "third_party/blink/public/web/web_widget_client.h"
+#include "third_party/blink/public/web/web_swap_result.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/paint/paint_event.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -39,14 +39,14 @@ class CORE_EXPORT FirstMeaningfulPaintDetector
int visible_height);
void NotifyInputEvent();
void NotifyPaint();
- void ReportSwapTime(PaintEvent, WebWidgetClient::SwapResult, base::TimeTicks);
+ void ReportSwapTime(PaintEvent, WebSwapResult, base::TimeTicks);
void NotifyFirstContentfulPaint(base::TimeTicks swap_stamp);
void OnNetwork2Quiet();
// The caller owns the |clock| which must outlive the paint detector.
static void SetTickClockForTesting(const base::TickClock* clock);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
enum HadUserInput { kNoUserInput, kHadUserInput, kHadUserInputEnumMax };
diff --git a/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector_test.cc b/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector_test.cc
index b4b2344a792..b448877213e 100644
--- a/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector_test.cc
@@ -49,7 +49,7 @@ class FirstMeaningfulPaintDetectorTest : public PageTestBase {
for (int i = 0; i < new_elements; i++)
builder.Append("<span>a</span>");
GetDocument().write(builder.ToString());
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Detector().NotifyPaint();
}
@@ -62,15 +62,14 @@ class FirstMeaningfulPaintDetectorTest : public PageTestBase {
void ClearFirstPaintSwapPromise() {
platform()->AdvanceClock(base::TimeDelta::FromMilliseconds(1));
- GetPaintTiming().ReportSwapTime(
- PaintEvent::kFirstPaint, WebWidgetClient::SwapResult::kDidSwap, Now());
+ GetPaintTiming().ReportSwapTime(PaintEvent::kFirstPaint,
+ WebSwapResult::kDidSwap, Now());
}
void ClearFirstContentfulPaintSwapPromise() {
platform()->AdvanceClock(base::TimeDelta::FromMilliseconds(1));
GetPaintTiming().ReportSwapTime(PaintEvent::kFirstContentfulPaint,
- WebWidgetClient::SwapResult::kDidSwap,
- Now());
+ WebSwapResult::kDidSwap, Now());
}
void ClearProvisionalFirstMeaningfulPaintSwapPromise() {
@@ -81,7 +80,7 @@ class FirstMeaningfulPaintDetectorTest : public PageTestBase {
void ClearProvisionalFirstMeaningfulPaintSwapPromise(
base::TimeTicks timestamp) {
Detector().ReportSwapTime(PaintEvent::kProvisionalFirstMeaningfulPaint,
- WebWidgetClient::SwapResult::kDidSwap, timestamp);
+ WebSwapResult::kDidSwap, timestamp);
}
unsigned OutstandingDetectorSwapPromiseCount() {
diff --git a/chromium/third_party/blink/renderer/core/paint/fragment_data.h b/chromium/third_party/blink/renderer/core/paint/fragment_data.h
index c0b43ea28f1..9ae6c02600d 100644
--- a/chromium/third_party/blink/renderer/core/paint/fragment_data.h
+++ b/chromium/third_party/blink/renderer/core/paint/fragment_data.h
@@ -100,15 +100,16 @@ class CORE_EXPORT FragmentData {
EnsureRareData().logical_top_in_flow_thread = top;
}
- // The pagination offset is the additional factor to add in to map
- // from flow thread coordinates relative to the enclosing pagination
- // layer, to visual coordiantes relative to that pagination layer.
- PhysicalOffset PaginationOffset() const {
- return rare_data_ ? rare_data_->pagination_offset : PhysicalOffset();
+ // The pagination offset is the additional factor to add in to map from flow
+ // thread coordinates relative to the enclosing pagination layer, to visual
+ // coordinates relative to that pagination layer. Not to be used in LayoutNG
+ // fragment painting.
+ PhysicalOffset LegacyPaginationOffset() const {
+ return rare_data_ ? rare_data_->legacy_pagination_offset : PhysicalOffset();
}
- void SetPaginationOffset(const PhysicalOffset& pagination_offset) {
+ void SetLegacyPaginationOffset(const PhysicalOffset& pagination_offset) {
if (rare_data_ || pagination_offset != PhysicalOffset())
- EnsureRareData().pagination_offset = pagination_offset;
+ EnsureRareData().legacy_pagination_offset = pagination_offset;
}
bool IsClipPathCacheValid() const {
@@ -256,7 +257,7 @@ class CORE_EXPORT FragmentData {
IntRect partial_invalidation_visual_rect;
// Fragment specific data.
- PhysicalOffset pagination_offset;
+ PhysicalOffset legacy_pagination_offset;
LayoutUnit logical_top_in_flow_thread;
std::unique_ptr<ObjectPaintProperties> paint_properties;
std::unique_ptr<RefCountedPropertyTreeState> local_border_box_properties;
diff --git a/chromium/third_party/blink/renderer/core/paint/frame_paint_timing.h b/chromium/third_party/blink/renderer/core/paint/frame_paint_timing.h
index 0416f1138b9..1d6d98f6f76 100644
--- a/chromium/third_party/blink/renderer/core/paint/frame_paint_timing.h
+++ b/chromium/third_party/blink/renderer/core/paint/frame_paint_timing.h
@@ -33,7 +33,7 @@ class FramePaintTiming {
private:
GraphicsContext& context_;
- Member<const LocalFrame> frame_;
+ const LocalFrame* frame_;
DISALLOW_COPY_AND_ASSIGN(FramePaintTiming);
};
diff --git a/chromium/third_party/blink/renderer/core/paint/frame_painter.h b/chromium/third_party/blink/renderer/core/paint/frame_painter.h
index 05c33f8fba5..ee2368328ee 100644
--- a/chromium/third_party/blink/renderer/core/paint/frame_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/frame_painter.h
@@ -28,7 +28,7 @@ class FramePainter {
private:
const LocalFrameView& GetFrameView();
- Member<const LocalFrameView> frame_view_;
+ const LocalFrameView* frame_view_;
static bool in_paint_contents_;
DISALLOW_COPY_AND_ASSIGN(FramePainter);
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 dc2531bcd1b..c3b20fb9d6d 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
@@ -71,7 +71,7 @@ TEST_P(HTMLCanvasPainterTestForCAP, Canvas2DLayerAppearsInLayerTree) {
// Insert a <canvas> and force it into accelerated mode.
// Not using SetBodyInnerHTML() because we need to test before document
// lifecyle update.
- GetDocument().body()->SetInnerHTMLFromString("<canvas width=300 height=200>");
+ GetDocument().body()->setInnerHTML("<canvas width=300 height=200>");
auto* element = To<HTMLCanvasElement>(GetDocument().body()->firstChild());
CanvasContextCreationAttributesCore attributes;
attributes.alpha = true;
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 47b371c6cfa..4a824465ff5 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
@@ -101,7 +101,7 @@ void ImageElementTiming::NotifyImagePainted(
it->value.is_painted_ = true;
NotifyImagePaintedInternal(layout_object->GetNode(), *layout_object,
*cached_image, current_paint_chunk_properties,
- it->value.load_time_);
+ it->value.load_time_, nullptr);
}
}
@@ -110,7 +110,8 @@ void ImageElementTiming::NotifyImagePaintedInternal(
const LayoutObject& layout_object,
const ImageResourceContent& cached_image,
const PropertyTreeState& current_paint_chunk_properties,
- base::TimeTicks load_time) {
+ base::TimeTicks load_time,
+ const IntRect* image_border) {
LocalFrame* frame = GetSupplementable()->GetFrame();
DCHECK(frame == layout_object.GetDocument().GetFrame());
DCHECK(node);
@@ -134,8 +135,13 @@ void ImageElementTiming::NotifyImagePaintedInternal(
if (!layout_object.HasNonZeroEffectiveOpacity())
return;
+ RespectImageOrientationEnum respect_orientation =
+ LayoutObject::ShouldRespectImageOrientation(&layout_object);
+
FloatRect intersection_rect = ElementTimingUtils::ComputeIntersectionRect(
- frame, layout_object.FirstFragment().VisualRect(),
+ frame,
+ image_border ? *image_border
+ : layout_object.FragmentsVisualRectBoundingBox(),
current_paint_chunk_properties);
const AtomicString attr =
element->FastGetAttribute(html_names::kElementtimingAttr);
@@ -147,25 +153,35 @@ void ImageElementTiming::NotifyImagePaintedInternal(
DCHECK(layout_object.GetDocument().GetSecurityOrigin());
// It's ok to expose rendering timestamp for data URIs so exclude those from
// the Timing-Allow-Origin check.
- bool response_tainting_not_basic = false;
- bool tainted_origin_flag = false;
- if (!url.ProtocolIsData() &&
- !Performance::PassesTimingAllowCheck(
+ if (!url.ProtocolIsData()) {
+ bool timing_allow_check = false;
+ // Use the TimingAllowPassed() check from the response if OutOfBlinkCors is
+ // enabled. If it is not enabled then that flag is not computed, so use to
+ // the single PassesTimingAllowCheck(), which is incorrect because it does
+ // not check the full redirect chain. See crbug.com/1003943.
+ if (RuntimeEnabledFeatures::OutOfBlinkCorsEnabled()) {
+ timing_allow_check = cached_image.GetResponse().TimingAllowPassed();
+ } else {
+ bool response_tainting_not_basic = false;
+ bool tainted_origin_flag = false;
+ timing_allow_check = Performance::PassesTimingAllowCheck(
cached_image.GetResponse(), cached_image.GetResponse(),
*layout_object.GetDocument().GetSecurityOrigin(),
- &layout_object.GetDocument(), &response_tainting_not_basic,
- &tainted_origin_flag)) {
- WindowPerformance* performance =
- DOMWindowPerformance::performance(*GetSupplementable());
- if (performance) {
- // Create an entry with a |startTime| of 0.
- performance->AddElementTiming(
- ImagePaintString(), url.GetString(), intersection_rect,
- base::TimeTicks(), load_time, attr,
- cached_image.IntrinsicSize(kDoNotRespectImageOrientation), id,
- element);
+ layout_object.GetDocument().ToExecutionContext(),
+ &response_tainting_not_basic, &tainted_origin_flag);
+ }
+ if (!timing_allow_check) {
+ WindowPerformance* performance =
+ DOMWindowPerformance::performance(*GetSupplementable());
+ if (performance) {
+ // Create an entry with a |startTime| of 0.
+ performance->AddElementTiming(
+ ImagePaintString(), url.GetString(), intersection_rect,
+ base::TimeTicks(), load_time, attr,
+ cached_image.IntrinsicSize(respect_orientation), id, element);
+ }
+ return;
}
- return;
}
// If the image URL is a data URL ("data:image/..."), then the |name| of the
@@ -177,7 +193,7 @@ void ImageElementTiming::NotifyImagePaintedInternal(
: url.GetString();
element_timings_.emplace_back(MakeGarbageCollected<ElementTimingInfo>(
image_url, intersection_rect, load_time, attr,
- cached_image.IntrinsicSize(kDoNotRespectImageOrientation), id, element));
+ cached_image.IntrinsicSize(respect_orientation), id, element));
// Only queue a swap promise when |element_timings_| was empty. All of the
// records in |element_timings_| will be processed when the promise succeeds
// or fails, and at that time the vector is cleared.
@@ -192,7 +208,8 @@ void ImageElementTiming::NotifyImagePaintedInternal(
void ImageElementTiming::NotifyBackgroundImagePainted(
Node* node,
const StyleFetchedImage* background_image,
- const PropertyTreeState& current_paint_chunk_properties) {
+ const PropertyTreeState& current_paint_chunk_properties,
+ const IntRect& image_border) {
DCHECK(node);
DCHECK(background_image);
@@ -218,11 +235,11 @@ void ImageElementTiming::NotifyBackgroundImagePainted(
info.is_painted_ = true;
NotifyImagePaintedInternal(layout_object->GetNode(), *layout_object,
*cached_image, current_paint_chunk_properties,
- it->value);
+ it->value, &image_border);
}
}
-void ImageElementTiming::ReportImagePaintSwapTime(WebWidgetClient::SwapResult,
+void ImageElementTiming::ReportImagePaintSwapTime(WebSwapResult,
base::TimeTicks timestamp) {
WindowPerformance* performance =
DOMWindowPerformance::performance(*GetSupplementable());
@@ -243,7 +260,7 @@ void ImageElementTiming::NotifyImageRemoved(const LayoutObject* layout_object,
images_notified_.erase(std::make_pair(layout_object, image));
}
-void ImageElementTiming::Trace(blink::Visitor* visitor) {
+void ImageElementTiming::Trace(Visitor* visitor) {
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 1f6ac8fbcd0..18db86a4047 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
@@ -7,7 +7,7 @@
#include <utility>
-#include "third_party/blink/public/web/web_widget_client.h"
+#include "third_party/blink/public/web/web_swap_result.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
@@ -57,12 +57,13 @@ class CORE_EXPORT ImageElementTiming final
void NotifyBackgroundImagePainted(
Node*,
const StyleFetchedImage* background_image,
- const PropertyTreeState& current_paint_chunk_properties);
+ const PropertyTreeState& current_paint_chunk_properties,
+ const IntRect& image_border);
void NotifyImageRemoved(const LayoutObject*,
const ImageResourceContent* image);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
friend class ImageElementTimingTest;
@@ -72,11 +73,11 @@ class CORE_EXPORT ImageElementTiming final
const LayoutObject&,
const ImageResourceContent& cached_image,
const PropertyTreeState& current_paint_chunk_properties,
- base::TimeTicks load_time);
+ base::TimeTicks load_time,
+ const IntRect* image_border);
// Callback for the swap promise. Reports paint timestamps.
- void ReportImagePaintSwapTime(WebWidgetClient::SwapResult,
- base::TimeTicks timestamp);
+ void ReportImagePaintSwapTime(WebSwapResult, base::TimeTicks timestamp);
// Class containing information about image element timing.
class ElementTimingInfo final : public GarbageCollected<ElementTimingInfo> {
@@ -97,7 +98,7 @@ class CORE_EXPORT ImageElementTiming final
element(element) {}
~ElementTimingInfo() = default;
- void Trace(blink::Visitor* visitor) { visitor->Trace(element); }
+ void Trace(Visitor* visitor) { 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 1349b35b968..c39619a98a3 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
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/core/layout/svg/layout_svg_image.h"
#include "third_party/blink/renderer/core/loader/resource/image_resource_content.h"
#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
+#include "third_party/blink/renderer/platform/testing/paint_test_configurations.h"
#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkSurface.h"
@@ -22,7 +23,8 @@ extern bool IsExplicitlyRegisteredForTiming(const LayoutObject* layout_object);
}
-class ImageElementTimingTest : public testing::Test {
+class ImageElementTimingTest : public testing::Test,
+ public PaintTestConfigurations {
protected:
void SetUp() override {
web_view_helper_.Initialize();
@@ -87,8 +89,7 @@ class ImageElementTimingTest : public testing::Test {
->MainFrameImpl()
->GetFrame()
->View()
- ->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ ->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
}
frame_test_helpers::WebViewHelper web_view_helper_;
@@ -108,13 +109,18 @@ class ImageElementTimingTest : public testing::Test {
}
};
-TEST_F(ImageElementTimingTest, TestIsExplicitlyRegisteredForTiming) {
+INSTANTIATE_PAINT_TEST_SUITE_P(ImageElementTimingTest);
+
+TEST_P(ImageElementTimingTest, TestIsExplicitlyRegisteredForTiming) {
frame_test_helpers::LoadHTMLString(
web_view_helper_.GetWebView()->MainFrameImpl(), R"HTML(
<img id="missing-attribute" style='width: 100px; height: 100px;'/>
- <img id="unset-attribute" elementtiming style='width: 100px; height: 100px;'/>
- <img id="empty-attribute" elementtiming="" style='width: 100px; height: 100px;'/>
- <img id="valid-attribute" elementtiming="valid-id" style='width: 100px; height: 100px;'/>
+ <img id="unset-attribute" elementtiming
+ style='width: 100px; height: 100px;'/>
+ <img id="empty-attribute" elementtiming=""
+ style='width: 100px; height: 100px;'/>
+ <img id="valid-attribute" elementtiming="valid-id"
+ style='width: 100px; height: 100px;'/>
)HTML",
base_url_);
@@ -142,7 +148,7 @@ TEST_F(ImageElementTimingTest, TestIsExplicitlyRegisteredForTiming) {
"should be explicitly registered.";
}
-TEST_F(ImageElementTimingTest, IgnoresUnmarkedElement) {
+TEST_P(ImageElementTimingTest, IgnoresUnmarkedElement) {
// Tests that, if the 'elementtiming' attribute is missing, the element isn't
// considered by ImageElementTiming.
frame_test_helpers::LoadHTMLString(
@@ -157,12 +163,13 @@ TEST_F(ImageElementTimingTest, IgnoresUnmarkedElement) {
std::make_pair(layout_image, layout_image->CachedImage())));
}
-TEST_F(ImageElementTimingTest, ImageInsideSVG) {
+TEST_P(ImageElementTimingTest, ImageInsideSVG) {
frame_test_helpers::LoadHTMLString(
web_view_helper_.GetWebView()->MainFrameImpl(), R"HTML(
<svg>
<foreignObject width="100" height="100">
- <img elementtiming="image-inside-svg" id="target" style='width: 100px; height: 100px;'/>
+ <img elementtiming="image-inside-svg" id="target"
+ style='width: 100px; height: 100px;'/>
</foreignObject>
</svg>
)HTML",
@@ -176,13 +183,14 @@ TEST_F(ImageElementTimingTest, ImageInsideSVG) {
std::make_pair(layout_image, layout_image->CachedImage())));
}
-TEST_F(ImageElementTimingTest, ImageInsideNonRenderedSVG) {
+TEST_P(ImageElementTimingTest, ImageInsideNonRenderedSVG) {
frame_test_helpers::LoadHTMLString(
web_view_helper_.GetWebView()->MainFrameImpl(), R"HTML(
<svg mask="url(#mask)">
<mask id="mask">
<foreignObject width="100" height="100">
- <img elementtiming="image-inside-svg" id="target" style='width: 100px; height: 100px;'/>
+ <img elementtiming="image-inside-svg" id="target"
+ style='width: 100px; height: 100px;'/>
</foreignObject>
</mask>
<rect width="100" height="100" fill="green"/>
@@ -196,10 +204,11 @@ TEST_F(ImageElementTimingTest, ImageInsideNonRenderedSVG) {
EXPECT_FALSE(GetLayoutObjectById("target"));
}
-TEST_F(ImageElementTimingTest, ImageRemoved) {
+TEST_P(ImageElementTimingTest, ImageRemoved) {
frame_test_helpers::LoadHTMLString(
web_view_helper_.GetWebView()->MainFrameImpl(), R"HTML(
- <img elementtiming="will-be-removed" id="target" style='width: 100px; height: 100px;'/>
+ <img elementtiming="will-be-removed" id="target"
+ style='width: 100px; height: 100px;'/>
)HTML",
base_url_);
LayoutImage* layout_image = SetImageResource("target", 5, 5);
@@ -214,11 +223,12 @@ TEST_F(ImageElementTimingTest, ImageRemoved) {
EXPECT_EQ(ImagesNotifiedSize(), 0u);
}
-TEST_F(ImageElementTimingTest, SVGImageRemoved) {
+TEST_P(ImageElementTimingTest, SVGImageRemoved) {
frame_test_helpers::LoadHTMLString(
web_view_helper_.GetWebView()->MainFrameImpl(), R"HTML(
<svg>
- <image elementtiming="svg-will-be-removed" id="target" style='width: 100px; height: 100px;'/>
+ <image elementtiming="svg-will-be-removed" id="target"
+ style='width: 100px; height: 100px;'/>
</svg>
)HTML",
base_url_);
@@ -234,7 +244,7 @@ TEST_F(ImageElementTimingTest, SVGImageRemoved) {
EXPECT_EQ(ImagesNotifiedSize(), 0u);
}
-TEST_F(ImageElementTimingTest, BackgroundImageRemoved) {
+TEST_P(ImageElementTimingTest, BackgroundImageRemoved) {
frame_test_helpers::LoadHTMLString(
web_view_helper_.GetWebView()->MainFrameImpl(), R"HTML(
<style>
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 6f8d03d3cda..eea55437e84 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
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/core/paint/image_paint_timing_detector.h"
+#include "third_party/blink/public/platform/web_float_rect.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/layout/layout_image_resource.h"
@@ -215,7 +216,8 @@ void ImagePaintTimingDetector::RecordImage(
const IntSize& intrinsic_size,
const ImageResourceContent& cached_image,
const PropertyTreeState& current_paint_chunk_properties,
- const StyleFetchedImage* style_image) {
+ const StyleFetchedImage* style_image,
+ const IntRect* image_border) {
Node* node = object.GetNode();
if (!node)
return;
@@ -234,7 +236,8 @@ void ImagePaintTimingDetector::RecordImage(
frame_view_->GetPaintTimingDetector().Visualizer()) {
FloatRect mapped_visual_rect =
frame_view_->GetPaintTimingDetector().CalculateVisualRect(
- object.FragmentsVisualRectBoundingBox(),
+ image_border ? *image_border
+ : object.FragmentsVisualRectBoundingBox(),
current_paint_chunk_properties);
visualizer->DumpImageDebuggingRect(object, mapped_visual_rect,
cached_image);
@@ -244,7 +247,8 @@ void ImagePaintTimingDetector::RecordImage(
if (is_recored_visible_image || !is_recording_)
return;
- IntRect visual_rect = object.FragmentsVisualRectBoundingBox();
+ IntRect visual_rect =
+ image_border ? *image_border : object.FragmentsVisualRectBoundingBox();
// Before the image resource starts loading, <img> has no size info. We wait
// until the size is known.
if (visual_rect.IsEmpty())
@@ -338,7 +342,7 @@ ImageRecord* ImageRecordsManager::FindLargestPaintCandidate() const {
return size_ordered_set_.begin()->get();
}
-void ImagePaintTimingDetector::Trace(blink::Visitor* visitor) {
+void ImagePaintTimingDetector::Trace(Visitor* visitor) {
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 b18203fdb9e..29c490a6481 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
@@ -213,7 +213,8 @@ class CORE_EXPORT ImagePaintTimingDetector final
const IntSize& intrinsic_size,
const ImageResourceContent&,
const PropertyTreeState& current_paint_chunk_properties,
- const StyleFetchedImage*);
+ const StyleFetchedImage*,
+ const IntRect* image_border);
void NotifyImageFinished(const LayoutObject&, const ImageResourceContent*);
void OnPaintFinished();
void LayoutObjectWillBeDestroyed(const LayoutObject&);
@@ -236,7 +237,7 @@ class CORE_EXPORT ImagePaintTimingDetector final
// Return the candidate.
ImageRecord* UpdateCandidate();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
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 6b606789d33..66125f8a9c2 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
@@ -25,7 +25,7 @@
#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
-#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
+#include "third_party/blink/renderer/platform/testing/paint_test_configurations.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/skia/include/core/SkImage.h"
@@ -33,7 +33,25 @@
namespace blink {
-class ImagePaintTimingDetectorTest : public testing::Test {
+#define SIMPLE_IMAGE \
+ "url(data:image/gif;base64," \
+ "R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)"
+
+#define LARGE_IMAGE \
+ "url(data:image/gif;base64," \
+ "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSF" \
+ "lzAAAN1wAADdcBQiibeAAAAb5JREFUOMulkr1KA0EQgGdvTwwnYmER0gQsrFKmSy+pLESw9Qm0" \
+ "F/ICNnba+h6iEOuAEWslKJKTOyJJvIT72d1xZuOFC0giOLA77O7Mt/PnNptN+I+49Xr9GhH3f3" \
+ "mb0v1ht9vtLAUYYw5ItkgDL3KyD8PhcLvdbl/WarXT3DjLMnAcR/f7/YfxeKwtgC5RKQVhGILW" \
+ "eg4hQ6hUKjWyucmhLFEUuWR3QYBWAZABQ9i5CCmXy16pVALP80BKaaG+70MQBLvzFMjRKKXh8j" \
+ "6FSYKF7ITdEWLa4/ktokN74wiqjSMpnVcbQZqmEJHz+ckeCPFjWKwULpyspAqhdXVXdcnZcPjs" \
+ "Ign+2BsVA8jVYuWlgJ3yBj0icgq2uoK+lg4t+ZvLomSKamSQ4AI5BcMADtMhyNoSgNIISUaFNt" \
+ "wlazcDcBc4gjjVwCWid2usCWroYEhnaqbzFJLUzAHIXRDChXCcQP8zhkSZ5eNLgHAUzwDcRu4C" \
+ "oIRn/wsGUQIIy4Vr9TH6SYFCNzw4nALn5627K4vIttOUOwfa5YnrDYzt/9OLv9I5l8kk5hZ3XL" \
+ "O20b7tbR7zHLy/BX8G0IeBEM7ZN1NGIaFUaKLgAAAAAElFTkSuQmCC)"
+
+class ImagePaintTimingDetectorTest : public testing::Test,
+ public PaintTestConfigurations {
public:
ImagePaintTimingDetectorTest()
: test_task_runner_(
@@ -152,8 +170,7 @@ class ImagePaintTimingDetectorTest : public testing::Test {
}
void UpdateAllLifecyclePhases() {
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
}
void UpdateAllLifecyclePhasesAndInvokeCallbackIfAny() {
@@ -177,8 +194,7 @@ class ImagePaintTimingDetectorTest : public testing::Test {
void SetChildBodyInnerHTML(const String& content) {
GetChildDocument()->SetBaseURLOverride(KURL("http://test.com"));
- GetChildDocument()->body()->SetInnerHTMLFromString(content,
- ASSERT_NO_EXCEPTION);
+ GetChildDocument()->body()->setInnerHTML(content, ASSERT_NO_EXCEPTION);
child_mock_callback_manager_ =
MakeGarbageCollected<MockPaintTimingCallbackManager>();
GetChildPaintTimingDetector()
@@ -235,7 +251,13 @@ class ImagePaintTimingDetectorTest : public testing::Test {
To<SVGImageElement>(element)->SetImageForTest(content);
}
- void SimulateScroll() { GetPaintTimingDetector().NotifyScroll(kUserScroll); }
+ void SimulateScroll() {
+ GetPaintTimingDetector().NotifyScroll(mojom::blink::ScrollType::kUser);
+ }
+
+ void SimulateKeyUp() {
+ GetPaintTimingDetector().NotifyInputEvent(WebInputEvent::kKeyUp);
+ }
scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner_;
frame_test_helpers::WebViewHelper web_view_helper_;
@@ -266,7 +288,9 @@ class ImagePaintTimingDetectorTest : public testing::Test {
constexpr base::TimeDelta ImagePaintTimingDetectorTest::kQuantumOfTime;
-TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_NoImage) {
+INSTANTIATE_PAINT_TEST_SUITE_P(ImagePaintTimingDetectorTest);
+
+TEST_P(ImagePaintTimingDetectorTest, LargestImagePaint_NoImage) {
SetBodyInnerHTML(R"HTML(
<div></div>
)HTML");
@@ -274,7 +298,7 @@ TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_NoImage) {
EXPECT_FALSE(record);
}
-TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_OneImage) {
+TEST_P(ImagePaintTimingDetectorTest, LargestImagePaint_OneImage) {
SetBodyInnerHTML(R"HTML(
<img id="target"></img>
)HTML");
@@ -286,7 +310,7 @@ TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_OneImage) {
EXPECT_TRUE(record->loaded);
}
-TEST_F(ImagePaintTimingDetectorTest, InsertionOrderIsSecondaryRankingKey) {
+TEST_P(ImagePaintTimingDetectorTest, InsertionOrderIsSecondaryRankingKey) {
SetBodyInnerHTML(R"HTML(
)HTML");
@@ -311,7 +335,7 @@ TEST_F(ImagePaintTimingDetectorTest, InsertionOrderIsSecondaryRankingKey) {
DOMNodeIds::ExistingIdForNode(image1));
}
-TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_TraceEvent_Candidate) {
+TEST_P(ImagePaintTimingDetectorTest, LargestImagePaint_TraceEvent_Candidate) {
using trace_analyzer::Query;
trace_analyzer::Start("loading");
{
@@ -352,7 +376,7 @@ TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_TraceEvent_Candidate) {
EXPECT_EQ(false, isOOPIF);
}
-TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_TraceEvent_NoCandidate) {
+TEST_P(ImagePaintTimingDetectorTest, LargestImagePaint_TraceEvent_NoCandidate) {
using trace_analyzer::Query;
trace_analyzer::Start("*");
{
@@ -402,7 +426,7 @@ TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_TraceEvent_NoCandidate) {
}
}
-TEST_F(ImagePaintTimingDetectorTest, UpdatePerformanceTiming) {
+TEST_P(ImagePaintTimingDetectorTest, UpdatePerformanceTiming) {
EXPECT_EQ(GetPerformanceTiming().LargestImagePaintSize(), 0u);
EXPECT_EQ(GetPerformanceTiming().LargestImagePaint(), 0u);
SetBodyInnerHTML(R"HTML(
@@ -414,7 +438,7 @@ TEST_F(ImagePaintTimingDetectorTest, UpdatePerformanceTiming) {
EXPECT_GT(GetPerformanceTiming().LargestImagePaint(), 0u);
}
-TEST_F(ImagePaintTimingDetectorTest,
+TEST_P(ImagePaintTimingDetectorTest,
PerformanceTimingHasZeroTimeNonZeroSizeWhenTheLargestIsNotPainted) {
EXPECT_EQ(GetPerformanceTiming().LargestImagePaintSize(), 0u);
EXPECT_EQ(GetPerformanceTiming().LargestImagePaint(), 0u);
@@ -427,7 +451,7 @@ TEST_F(ImagePaintTimingDetectorTest,
EXPECT_EQ(GetPerformanceTiming().LargestImagePaint(), 0u);
}
-TEST_F(ImagePaintTimingDetectorTest, UpdatePerformanceTimingToZero) {
+TEST_P(ImagePaintTimingDetectorTest, UpdatePerformanceTimingToZero) {
SetBodyInnerHTML(R"HTML(
<img id="target"></img>
)HTML");
@@ -441,7 +465,7 @@ TEST_F(ImagePaintTimingDetectorTest, UpdatePerformanceTimingToZero) {
EXPECT_EQ(GetPerformanceTiming().LargestImagePaint(), 0u);
}
-TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_OpacityZero) {
+TEST_P(ImagePaintTimingDetectorTest, LargestImagePaint_OpacityZero) {
SetBodyInnerHTML(R"HTML(
<style>
img {
@@ -457,7 +481,7 @@ TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_OpacityZero) {
EXPECT_FALSE(record);
}
-TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_VisibilityHidden) {
+TEST_P(ImagePaintTimingDetectorTest, LargestImagePaint_VisibilityHidden) {
SetBodyInnerHTML(R"HTML(
<style>
img {
@@ -473,7 +497,7 @@ TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_VisibilityHidden) {
EXPECT_FALSE(record);
}
-TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_DisplayNone) {
+TEST_P(ImagePaintTimingDetectorTest, LargestImagePaint_DisplayNone) {
SetBodyInnerHTML(R"HTML(
<style>
img {
@@ -489,7 +513,7 @@ TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_DisplayNone) {
EXPECT_FALSE(record);
}
-TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_OpacityNonZero) {
+TEST_P(ImagePaintTimingDetectorTest, LargestImagePaint_OpacityNonZero) {
SetBodyInnerHTML(R"HTML(
<style>
img {
@@ -505,7 +529,7 @@ TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_OpacityNonZero) {
EXPECT_TRUE(record);
}
-TEST_F(ImagePaintTimingDetectorTest,
+TEST_P(ImagePaintTimingDetectorTest,
IgnoreImageUntilInvalidatedRectSizeNonZero) {
SetBodyInnerHTML(R"HTML(
<img id="target"></img>
@@ -519,7 +543,7 @@ TEST_F(ImagePaintTimingDetectorTest,
EXPECT_EQ(CountVisibleImageRecords(), 1u);
}
-TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_Largest) {
+TEST_P(ImagePaintTimingDetectorTest, LargestImagePaint_Largest) {
SetBodyInnerHTML(R"HTML(
<style>img { display:block }</style>
<img id="smaller"></img>
@@ -537,7 +561,7 @@ TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_Largest) {
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
}
-TEST_F(ImagePaintTimingDetectorTest,
+TEST_P(ImagePaintTimingDetectorTest,
LargestImagePaint_IgnoreThoseOutsideViewport) {
SetBodyInnerHTML(R"HTML(
<style>
@@ -554,7 +578,7 @@ TEST_F(ImagePaintTimingDetectorTest,
EXPECT_FALSE(record);
}
-TEST_F(ImagePaintTimingDetectorTest,
+TEST_P(ImagePaintTimingDetectorTest,
LargestImagePaint_UpdateOnRemovingTheLastImage) {
SetBodyInnerHTML(R"HTML(
<div id="parent">
@@ -576,7 +600,7 @@ TEST_F(ImagePaintTimingDetectorTest,
EXPECT_EQ(LargestPaintStoredResult(), base::TimeTicks());
}
-TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_UpdateOnRemoving) {
+TEST_P(ImagePaintTimingDetectorTest, LargestImagePaint_UpdateOnRemoving) {
SetBodyInnerHTML(R"HTML(
<div id="parent">
<img id="target1"></img>
@@ -608,7 +632,7 @@ TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_UpdateOnRemoving) {
EXPECT_EQ(first_largest_image_paint, LargestPaintStoredResult());
}
-TEST_F(ImagePaintTimingDetectorTest,
+TEST_P(ImagePaintTimingDetectorTest,
LargestImagePaint_NodeRemovedBetweenRegistrationAndInvocation) {
SetBodyInnerHTML(R"HTML(
<div id="parent">
@@ -628,7 +652,7 @@ TEST_F(ImagePaintTimingDetectorTest,
EXPECT_FALSE(record);
}
-TEST_F(ImagePaintTimingDetectorTest,
+TEST_P(ImagePaintTimingDetectorTest,
RemoveRecordFromAllContainersAfterImageRemoval) {
SetBodyInnerHTML(R"HTML(
<div id="parent">
@@ -644,8 +668,12 @@ TEST_F(ImagePaintTimingDetectorTest,
EXPECT_EQ(ContainerTotalSize(), 0u);
}
-TEST_F(ImagePaintTimingDetectorTest,
+TEST_P(ImagePaintTimingDetectorTest,
RemoveRecordFromAllContainersAfterInvisibleImageRemoved) {
+ // TODO(wangxianzhu): Fix this test for CompositeAfterPaint.
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ return;
+
SetBodyInnerHTML(R"HTML(
<style>
#target {
@@ -673,12 +701,12 @@ TEST_F(ImagePaintTimingDetectorTest,
EXPECT_EQ(CountInvisibleRecords(), 0u);
}
-TEST_F(ImagePaintTimingDetectorTest,
+TEST_P(ImagePaintTimingDetectorTest,
RemoveRecordFromAllContainersAfterBackgroundImageRemoval) {
SetBodyInnerHTML(R"HTML(
<style>
#target {
- background-image: url(data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==);
+ background-image: )HTML" SIMPLE_IMAGE R"HTML(;
}
</style>
<div id="parent">
@@ -695,7 +723,7 @@ TEST_F(ImagePaintTimingDetectorTest,
EXPECT_EQ(ContainerTotalSize(), 0u);
}
-TEST_F(ImagePaintTimingDetectorTest,
+TEST_P(ImagePaintTimingDetectorTest,
RemoveRecordFromAllContainersAfterImageRemovedAndCallbackInvoked) {
SetBodyInnerHTML(R"HTML(
<div id="parent">
@@ -713,7 +741,7 @@ TEST_F(ImagePaintTimingDetectorTest,
EXPECT_EQ(ContainerTotalSize(), 0u);
}
-TEST_F(ImagePaintTimingDetectorTest,
+TEST_P(ImagePaintTimingDetectorTest,
LargestImagePaint_ReattachedNodeTreatedAsNew) {
SetBodyInnerHTML(R"HTML(
<div id="parent">
@@ -756,7 +784,7 @@ TEST_F(ImagePaintTimingDetectorTest,
// This is to prove that a swap time is assigned only to nodes of the frame who
// register the swap time. In other words, swap time A should match frame A;
// swap time B should match frame B.
-TEST_F(ImagePaintTimingDetectorTest, MatchSwapTimeToNodesOfDifferentFrames) {
+TEST_P(ImagePaintTimingDetectorTest, MatchSwapTimeToNodesOfDifferentFrames) {
SetBodyInnerHTML(R"HTML(
<div id="parent">
<img height="5" width="5" id="smaller"></img>
@@ -784,7 +812,7 @@ TEST_F(ImagePaintTimingDetectorTest, MatchSwapTimeToNodesOfDifferentFrames) {
EXPECT_NE(record1Time, record2->paint_time);
}
-TEST_F(ImagePaintTimingDetectorTest,
+TEST_P(ImagePaintTimingDetectorTest,
LargestImagePaint_UpdateResultWhenLargestChanged) {
base::TimeTicks time1 = test_task_runner_->NowTicks();
SetBodyInnerHTML(R"HTML(
@@ -808,7 +836,7 @@ TEST_F(ImagePaintTimingDetectorTest,
EXPECT_GE(time3, result2);
}
-TEST_F(ImagePaintTimingDetectorTest, OneSwapPromiseForOneFrame) {
+TEST_P(ImagePaintTimingDetectorTest, OneSwapPromiseForOneFrame) {
SetBodyInnerHTML(R"HTML(
<style>img { display:block }</style>
<div id="parent">
@@ -840,7 +868,7 @@ TEST_F(ImagePaintTimingDetectorTest, OneSwapPromiseForOneFrame) {
EXPECT_FALSE(record->paint_time.is_null());
}
-TEST_F(ImagePaintTimingDetectorTest, VideoImage) {
+TEST_P(ImagePaintTimingDetectorTest, VideoImage) {
SetBodyInnerHTML(R"HTML(
<video id="target"></video>
)HTML");
@@ -854,17 +882,15 @@ TEST_F(ImagePaintTimingDetectorTest, VideoImage) {
EXPECT_TRUE(record->loaded);
}
-TEST_F(ImagePaintTimingDetectorTest, VideoImage_ImageNotLoaded) {
- SetBodyInnerHTML(R"HTML(
- <video id="target"></video>
- )HTML");
+TEST_P(ImagePaintTimingDetectorTest, VideoImage_ImageNotLoaded) {
+ SetBodyInnerHTML("<video id='target'></video>");
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
ImageRecord* record = FindLargestPaintCandidate();
EXPECT_FALSE(record);
}
-TEST_F(ImagePaintTimingDetectorTest, SVGImage) {
+TEST_P(ImagePaintTimingDetectorTest, SVGImage) {
SetBodyInnerHTML(R"HTML(
<svg>
<image id="target" width="10" height="10"/>
@@ -880,28 +906,26 @@ TEST_F(ImagePaintTimingDetectorTest, SVGImage) {
EXPECT_TRUE(record->loaded);
}
-TEST_F(ImagePaintTimingDetectorTest, BackgroundImage) {
+TEST_P(ImagePaintTimingDetectorTest, BackgroundImage) {
SetBodyInnerHTML(R"HTML(
<style>
div {
- background-image: url(data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==);
+ background-image: )HTML" SIMPLE_IMAGE R"HTML(;
}
</style>
- <div>
- place-holder
- </div>
+ <div>place-holder</div>
)HTML");
ImageRecord* record = FindLargestPaintCandidate();
EXPECT_TRUE(record);
EXPECT_EQ(CountVisibleImageRecords(), 1u);
}
-TEST_F(ImagePaintTimingDetectorTest,
+TEST_P(ImagePaintTimingDetectorTest,
BackgroundImageAndLayoutImageTrackedDifferently) {
SetBodyInnerHTML(R"HTML(
<style>
img {
- background-image: url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAAb5JREFUOMulkr1KA0EQgGdvTwwnYmER0gQsrFKmSy+pLESw9Qm0F/ICNnba+h6iEOuAEWslKJKTOyJJvIT72d1xZuOFC0giOLA77O7Mt/PnNptN+I+49Xr9GhH3f3mb0v1ht9vtLAUYYw5ItkgDL3KyD8PhcLvdbl/WarXT3DjLMnAcR/f7/YfxeKwtgC5RKQVhGILWeg4hQ6hUKjWyucmhLFEUuWR3QYBWAZABQ9i5CCmXy16pVALP80BKaaG+70MQBLvzFMjRKKXh8j6FSYKF7ITdEWLa4/ktokN74wiqjSMpnVcbQZqmEJHz+ckeCPFjWKwULpyspAqhdXVXdcnZcPjsIgn+2BsVA8jVYuWlgJ3yBj0icgq2uoK+lg4t+ZvLomSKamSQ4AI5BcMADtMhyNoSgNIISUaFNtwlazcDcBc4gjjVwCWid2usCWroYEhnaqbzFJLUzAHIXRDChXCcQP8zhkSZ5eNLgHAUzwDcRu4CoIRn/wsGUQIIy4Vr9TH6SYFCNzw4nALn5627K4vIttOUOwfa5YnrDYzt/9OLv9I5l8kk5hZ3XLO20b7tbR7zHLy/BX8G0IeBEM7ZN1NGIaFUaKLgAAAAAElFTkSuQmCC);
+ background-image: )HTML" LARGE_IMAGE R"HTML(;
}
</style>
<img id="target">
@@ -916,31 +940,17 @@ TEST_F(ImagePaintTimingDetectorTest,
EXPECT_EQ(record->first_size, 1u);
}
-TEST_F(ImagePaintTimingDetectorTest, BackgroundImage_IgnoreBody) {
- SetBodyInnerHTML(R"HTML(
- <style>
- body {
- background-image: url(data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==);
- }
- </style>
- )HTML");
+TEST_P(ImagePaintTimingDetectorTest, BackgroundImage_IgnoreBody) {
+ SetBodyInnerHTML("<style>body { background-image: " SIMPLE_IMAGE "}</style>");
EXPECT_EQ(CountVisibleImageRecords(), 0u);
}
-TEST_F(ImagePaintTimingDetectorTest, BackgroundImage_IgnoreHtml) {
- SetBodyInnerHTML(R"HTML(
- <html>
- <style>
- html {
- background-image: url(data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==);
- }
- </style>
- </html>
- )HTML");
+TEST_P(ImagePaintTimingDetectorTest, BackgroundImage_IgnoreHtml) {
+ SetBodyInnerHTML("<style>html { background-image: " SIMPLE_IMAGE "}</style>");
EXPECT_EQ(CountVisibleImageRecords(), 0u);
}
-TEST_F(ImagePaintTimingDetectorTest, BackgroundImage_IgnoreGradient) {
+TEST_P(ImagePaintTimingDetectorTest, BackgroundImage_IgnoreGradient) {
SetBodyInnerHTML(R"HTML(
<style>
div {
@@ -956,15 +966,14 @@ TEST_F(ImagePaintTimingDetectorTest, BackgroundImage_IgnoreGradient) {
// We put two background images in the same object, and test whether FCP++ can
// find two different images.
-TEST_F(ImagePaintTimingDetectorTest, BackgroundImageTrackedDifferently) {
+TEST_P(ImagePaintTimingDetectorTest, BackgroundImageTrackedDifferently) {
SetBodyInnerHTML(R"HTML(
<style>
#d {
width: 50px;
height: 50px;
background-image:
- url("data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="),
- url("data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAAb5JREFUOMulkr1KA0EQgGdvTwwnYmER0gQsrFKmSy+pLESw9Qm0F/ICNnba+h6iEOuAEWslKJKTOyJJvIT72d1xZuOFC0giOLA77O7Mt/PnNptN+I+49Xr9GhH3f3mb0v1ht9vtLAUYYw5ItkgDL3KyD8PhcLvdbl/WarXT3DjLMnAcR/f7/YfxeKwtgC5RKQVhGILWeg4hQ6hUKjWyucmhLFEUuWR3QYBWAZABQ9i5CCmXy16pVALP80BKaaG+70MQBLvzFMjRKKXh8j6FSYKF7ITdEWLa4/ktokN74wiqjSMpnVcbQZqmEJHz+ckeCPFjWKwULpyspAqhdXVXdcnZcPjsIgn+2BsVA8jVYuWlgJ3yBj0icgq2uoK+lg4t+ZvLomSKamSQ4AI5BcMADtMhyNoSgNIISUaFNtwlazcDcBc4gjjVwCWid2usCWroYEhnaqbzFJLUzAHIXRDChXCcQP8zhkSZ5eNLgHAUzwDcRu4CoIRn/wsGUQIIy4Vr9TH6SYFCNzw4nALn5627K4vIttOUOwfa5YnrDYzt/9OLv9I5l8kk5hZ3XLO20b7tbR7zHLy/BX8G0IeBEM7ZN1NGIaFUaKLgAAAAAElFTkSuQmCC");
+ )HTML" SIMPLE_IMAGE "," LARGE_IMAGE R"HTML(;
}
</style>
<div id="d"></div>
@@ -972,7 +981,7 @@ TEST_F(ImagePaintTimingDetectorTest, BackgroundImageTrackedDifferently) {
EXPECT_EQ(CountVisibleImageRecords(), 2u);
}
-TEST_F(ImagePaintTimingDetectorTest, DeactivateAfterUserInput) {
+TEST_P(ImagePaintTimingDetectorTest, DeactivateAfterUserInput) {
SetBodyInnerHTML(R"HTML(
<div id="parent">
<img id="target"></img>
@@ -984,7 +993,19 @@ TEST_F(ImagePaintTimingDetectorTest, DeactivateAfterUserInput) {
EXPECT_FALSE(GetPaintTimingDetector().GetImagePaintTimingDetector());
}
-TEST_F(ImagePaintTimingDetectorTest, NullTimeNoCrash) {
+TEST_P(ImagePaintTimingDetectorTest, ContinueAfterKeyUp) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="parent">
+ <img id="target"></img>
+ </div>
+ )HTML");
+ SimulateKeyUp();
+ SetImageAndPaint("target", 5, 5);
+ UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
+ EXPECT_TRUE(GetPaintTimingDetector().GetImagePaintTimingDetector());
+}
+
+TEST_P(ImagePaintTimingDetectorTest, NullTimeNoCrash) {
SetBodyInnerHTML(R"HTML(
<img id="target"></img>
)HTML");
@@ -993,7 +1014,7 @@ TEST_F(ImagePaintTimingDetectorTest, NullTimeNoCrash) {
UpdateCandidate();
}
-TEST_F(ImagePaintTimingDetectorTest, Iframe) {
+TEST_P(ImagePaintTimingDetectorTest, Iframe) {
SetBodyInnerHTML(R"HTML(
<iframe width=100px height=100px></iframe>
)HTML");
@@ -1013,7 +1034,7 @@ TEST_F(ImagePaintTimingDetectorTest, Iframe) {
EXPECT_EQ(image->first_size, 25ul);
}
-TEST_F(ImagePaintTimingDetectorTest, Iframe_ClippedByMainFrameViewport) {
+TEST_P(ImagePaintTimingDetectorTest, Iframe_ClippedByMainFrameViewport) {
SetBodyInnerHTML(R"HTML(
<style>
#f { margin-top: 1234567px }
@@ -1031,7 +1052,7 @@ TEST_F(ImagePaintTimingDetectorTest, Iframe_ClippedByMainFrameViewport) {
EXPECT_EQ(CountVisibleImageRecords(), 0u);
}
-TEST_F(ImagePaintTimingDetectorTest, Iframe_HalfClippedByMainFrameViewport) {
+TEST_P(ImagePaintTimingDetectorTest, Iframe_HalfClippedByMainFrameViewport) {
SetBodyInnerHTML(R"HTML(
<style>
#f { margin-left: -5px; }
@@ -1052,7 +1073,7 @@ TEST_F(ImagePaintTimingDetectorTest, Iframe_HalfClippedByMainFrameViewport) {
EXPECT_LT(image->first_size, 100ul);
}
-TEST_F(ImagePaintTimingDetectorTest, SameSizeShouldNotBeIgnored) {
+TEST_P(ImagePaintTimingDetectorTest, SameSizeShouldNotBeIgnored) {
SetBodyInnerHTML(R"HTML(
<style>img { display:block }</style>
<img id='1'></img>
@@ -1066,7 +1087,7 @@ TEST_F(ImagePaintTimingDetectorTest, SameSizeShouldNotBeIgnored) {
EXPECT_EQ(CountRankingSetRecords(), 3u);
}
-TEST_F(ImagePaintTimingDetectorTest, UseIntrinsicSizeIfSmaller_Image) {
+TEST_P(ImagePaintTimingDetectorTest, UseIntrinsicSizeIfSmaller_Image) {
SetBodyInnerHTML(R"HTML(
<img height="300" width="300" display="block" id="target">
</img>
@@ -1078,7 +1099,7 @@ TEST_F(ImagePaintTimingDetectorTest, UseIntrinsicSizeIfSmaller_Image) {
EXPECT_EQ(record->first_size, 25u);
}
-TEST_F(ImagePaintTimingDetectorTest, NotUseIntrinsicSizeIfLarger_Image) {
+TEST_P(ImagePaintTimingDetectorTest, NotUseIntrinsicSizeIfLarger_Image) {
SetBodyInnerHTML(R"HTML(
<img height="1" width="1" display="block" id="target">
</img>
@@ -1090,14 +1111,14 @@ TEST_F(ImagePaintTimingDetectorTest, NotUseIntrinsicSizeIfLarger_Image) {
EXPECT_EQ(record->first_size, 1u);
}
-TEST_F(ImagePaintTimingDetectorTest,
+TEST_P(ImagePaintTimingDetectorTest,
UseIntrinsicSizeIfSmaller_BackgroundImage) {
SetBodyInnerHTML(R"HTML(
<style>
#d {
width: 50px;
height: 50px;
- background-image: url("data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==");
+ background-image: )HTML" SIMPLE_IMAGE R"HTML(;
}
</style>
<div id="d"></div>
@@ -1107,7 +1128,7 @@ TEST_F(ImagePaintTimingDetectorTest,
EXPECT_EQ(record->first_size, 1u);
}
-TEST_F(ImagePaintTimingDetectorTest,
+TEST_P(ImagePaintTimingDetectorTest,
NotUseIntrinsicSizeIfLarger_BackgroundImage) {
// The image is in 16x16.
SetBodyInnerHTML(R"HTML(
@@ -1115,7 +1136,7 @@ TEST_F(ImagePaintTimingDetectorTest,
#d {
width: 5px;
height: 5px;
- background-image: url("data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAAb5JREFUOMulkr1KA0EQgGdvTwwnYmER0gQsrFKmSy+pLESw9Qm0F/ICNnba+h6iEOuAEWslKJKTOyJJvIT72d1xZuOFC0giOLA77O7Mt/PnNptN+I+49Xr9GhH3f3mb0v1ht9vtLAUYYw5ItkgDL3KyD8PhcLvdbl/WarXT3DjLMnAcR/f7/YfxeKwtgC5RKQVhGILWeg4hQ6hUKjWyucmhLFEUuWR3QYBWAZABQ9i5CCmXy16pVALP80BKaaG+70MQBLvzFMjRKKXh8j6FSYKF7ITdEWLa4/ktokN74wiqjSMpnVcbQZqmEJHz+ckeCPFjWKwULpyspAqhdXVXdcnZcPjsIgn+2BsVA8jVYuWlgJ3yBj0icgq2uoK+lg4t+ZvLomSKamSQ4AI5BcMADtMhyNoSgNIISUaFNtwlazcDcBc4gjjVwCWid2usCWroYEhnaqbzFJLUzAHIXRDChXCcQP8zhkSZ5eNLgHAUzwDcRu4CoIRn/wsGUQIIy4Vr9TH6SYFCNzw4nALn5627K4vIttOUOwfa5YnrDYzt/9OLv9I5l8kk5hZ3XLO20b7tbR7zHLy/BX8G0IeBEM7ZN1NGIaFUaKLgAAAAAElFTkSuQmCC");
+ background-image: )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 be0a21026fb..86470ade240 100644
--- a/chromium/third_party/blink/renderer/core/paint/image_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/image_painter.cc
@@ -61,7 +61,7 @@ bool CheckForOversizedImagesPolicy(const LayoutImage& layout_image,
cached_image ? cached_image->Url().GetString() : g_empty_string;
return !layout_image.GetDocument().IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kOversizedImages,
+ mojom::blink::DocumentPolicyFeature::kOversizedImages,
blink::PolicyValue(
std::max(downscale_ratio_width, downscale_ratio_height),
blink::mojom::PolicyValueType::kDecDouble),
@@ -142,7 +142,7 @@ void ImagePainter::PaintReplaced(const PaintInfo& paint_info,
if (content_size.IsEmpty())
return;
} else {
- if (paint_info.phase == PaintPhase::kSelection)
+ if (paint_info.phase == PaintPhase::kSelectionDragImage)
return;
if (content_size.Width() <= 2 || content_size.Height() <= 2)
return;
@@ -187,8 +187,8 @@ void ImagePainter::PaintReplaced(const PaintInfo& paint_info,
void ImagePainter::PaintIntoRect(GraphicsContext& context,
const PhysicalRect& dest_rect,
const PhysicalRect& content_rect) {
- if (!layout_image_.ImageResource()->HasImage() ||
- layout_image_.ImageResource()->ErrorOccurred())
+ const LayoutImageResource& image_resource = *layout_image_.ImageResource();
+ if (!image_resource.HasImage() || image_resource.ErrorOccurred())
return; // FIXME: should we just ASSERT these conditions? (audit all
// callers).
@@ -197,11 +197,14 @@ void ImagePainter::PaintIntoRect(GraphicsContext& context,
return;
scoped_refptr<Image> image =
- layout_image_.ImageResource()->GetImage(pixel_snapped_dest_rect.Size());
+ image_resource.GetImage(FloatSize(dest_rect.size));
if (!image || image->IsNull())
return;
- FloatRect src_rect = FloatRect(image->Rect());
+ // Do not respect the image orientation when computing the source rect. It is
+ // in the un-orientated dimensions.
+ FloatRect src_rect(FloatPoint(),
+ image->SizeAsFloat(kDoNotRespectImageOrientation));
// If the content rect requires clipping, adjust |srcRect| and
// |pixelSnappedDestRect| over using a clip.
if (!content_rect.Contains(dest_rect)) {
@@ -249,17 +252,18 @@ void ImagePainter::PaintIntoRect(GraphicsContext& context,
layout_image_.StyleRef().HasFilterInducingProperty(),
SkBlendMode::kSrcOver,
LayoutObject::ShouldRespectImageOrientation(&layout_image_));
+
+ ImageResourceContent* image_content = image_resource.CachedImage();
if ((IsA<HTMLImageElement>(node) || IsA<HTMLVideoElement>(node)) &&
- !context.ContextDisabled() && layout_image_.CachedImage() &&
- layout_image_.CachedImage()->IsLoaded()) {
+ image_content && image_content->IsLoaded()) {
LocalDOMWindow* window = layout_image_.GetDocument().domWindow();
DCHECK(window);
ImageElementTiming::From(*window).NotifyImagePainted(
- &layout_image_, layout_image_.CachedImage(),
+ &layout_image_, image_content,
context.GetPaintController().CurrentPaintChunkProperties());
}
PaintTimingDetector::NotifyImagePaint(
- layout_image_, image->Size(), layout_image_.CachedImage(),
+ layout_image_, image->Size(), image_content,
context.GetPaintController().CurrentPaintChunkProperties());
}
diff --git a/chromium/third_party/blink/renderer/core/paint/inline_box_painter_base.h b/chromium/third_party/blink/renderer/core/paint/inline_box_painter_base.h
index 0dc82e10ad0..4c826eadfa4 100644
--- a/chromium/third_party/blink/renderer/core/paint/inline_box_painter_base.h
+++ b/chromium/third_party/blink/renderer/core/paint/inline_box_painter_base.h
@@ -84,8 +84,8 @@ class InlineBoxPainterBase {
bool object_has_multiple_boxes) const = 0;
const ImageResourceObserver& image_observer_;
- Member<const Document> document_;
- Member<Node> node_;
+ const Document* document_;
+ Node* node_;
// Style for the corresponding node.
const ComputedStyle& style_;
diff --git a/chromium/third_party/blink/renderer/core/paint/inline_flow_box_painter.cc b/chromium/third_party/blink/renderer/core/paint/inline_flow_box_painter.cc
index 4c14b9f3a1c..36a2191b612 100644
--- a/chromium/third_party/blink/renderer/core/paint/inline_flow_box_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/inline_flow_box_painter.cc
@@ -15,7 +15,6 @@
#include "third_party/blink/renderer/core/paint/paint_info.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/hit_test_display_item.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
namespace blink {
@@ -186,12 +185,12 @@ void InlineFlowBoxPainter::PaintBackgroundBorderShadow(
const LayoutPoint& paint_offset) {
DCHECK(paint_info.phase == PaintPhase::kForeground);
- RecordHitTestData(paint_info, paint_offset);
-
if (inline_flow_box_.GetLineLayoutItem().StyleRef().Visibility() !=
EVisibility::kVisible)
return;
+ RecordHitTestData(paint_info, paint_offset);
+
// You can use p::first-line to specify a background. If so, the root line
// boxes for a line may actually have to paint a background.
LayoutObject* inline_flow_box_layout_object =
@@ -340,17 +339,11 @@ void InlineFlowBoxPainter::RecordHitTestData(const PaintInfo& paint_info,
LayoutObject* layout_object =
LineLayoutAPIShim::LayoutObjectFrom(inline_flow_box_.GetLineLayoutItem());
- // If an object is not visible, it does not participate in hit testing.
- if (layout_object->StyleRef().Visibility() != EVisibility::kVisible)
- return;
-
- auto touch_action = layout_object->EffectiveAllowedTouchAction();
- if (touch_action == TouchAction::kTouchActionAuto)
- return;
+ DCHECK_EQ(layout_object->StyleRef().Visibility(), EVisibility::kVisible);
- HitTestDisplayItem::Record(
- paint_info.context, inline_flow_box_,
- HitTestRect(AdjustedPaintRect(paint_offset), touch_action));
+ paint_info.context.GetPaintController().RecordHitTestData(
+ inline_flow_box_, PixelSnappedIntRect(AdjustedPaintRect(paint_offset)),
+ layout_object->EffectiveAllowedTouchAction());
}
void InlineFlowBoxPainter::PaintNormalBoxShadow(const PaintInfo& info,
diff --git a/chromium/third_party/blink/renderer/core/paint/inline_flow_box_painter.h b/chromium/third_party/blink/renderer/core/paint/inline_flow_box_painter.h
index 9b239f13267..f4d6a2831bd 100644
--- a/chromium/third_party/blink/renderer/core/paint/inline_flow_box_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/inline_flow_box_painter.h
@@ -77,9 +77,9 @@ class InlineFlowBoxPainter : public InlineBoxPainterBase {
LayoutRect AdjustedPaintRect(const LayoutPoint& paint_offset) const;
- // Paint a hit test display item and record hit test data. This should be
- // called when painting the background even if there is no other painted
- // content.
+ // Expands the bounds of the current paint chunk for hit test, and records
+ // special touch action if any. This should be called in the background paint
+ // phase even if there is no other painted content.
void RecordHitTestData(const PaintInfo&, const LayoutPoint& paint_offset);
const InlineFlowBox& inline_flow_box_;
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 8f5cb403a0f..065c32ba2e8 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
@@ -149,7 +149,7 @@ void InlineTextBoxPainter::Paint(const PaintInfo& paint_info,
bool have_selection = !is_printing &&
paint_info.phase != PaintPhase::kTextClip &&
inline_text_box_.IsSelected();
- if (!have_selection && paint_info.phase == PaintPhase::kSelection) {
+ if (!have_selection && paint_info.phase == PaintPhase::kSelectionDragImage) {
// When only painting the selection, don't bother to paint if there is none.
return;
}
@@ -264,7 +264,8 @@ void InlineTextBoxPainter::Paint(const PaintInfo& paint_info,
inline_text_box_.GetLineLayoutItem().GetDocument(), style_to_use,
inline_text_box_.GetLineLayoutItem().GetNode(), have_selection,
paint_info, text_style);
- bool paint_selected_text_only = (paint_info.phase == PaintPhase::kSelection);
+ bool paint_selected_text_only =
+ (paint_info.phase == PaintPhase::kSelectionDragImage);
bool paint_selected_text_separately =
!paint_selected_text_only && text_style != selection_style;
@@ -280,7 +281,7 @@ void InlineTextBoxPainter::Paint(const PaintInfo& paint_info,
// 1. Paint backgrounds behind text if needed. Examples of such backgrounds
// include selection and composition highlights.
- if (paint_info.phase != PaintPhase::kSelection &&
+ if (paint_info.phase != PaintPhase::kSelectionDragImage &&
paint_info.phase != PaintPhase::kTextClip && !is_printing) {
PaintDocumentMarkers(markers_to_paint, paint_info, box_origin, style_to_use,
font, DocumentMarkerPaintPhase::kBackground);
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 d5ab8898d63..dd110c79c0b 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
@@ -68,11 +68,13 @@ void LargestContentfulPaintCalculator::UpdateLargestContentPaintIfNeeded(
bool text_has_changed = false;
if (largest_image.has_value()) {
image_has_changed = HasLargestImageChanged(largest_image_, *largest_image);
- OnLargestImageUpdated(*largest_image);
+ if (image_has_changed)
+ OnLargestImageUpdated(*largest_image);
}
if (largest_text.has_value()) {
text_has_changed = HasLargestTextChanged(largest_text_, *largest_text);
- OnLargestTextUpdated(*largest_text);
+ if (text_has_changed)
+ OnLargestTextUpdated(*largest_text);
}
// If |largest_image| does not have value, the detector may have been
// destroyed. In this case, keep using its last candidate for comparison with
@@ -121,17 +123,23 @@ void LargestContentfulPaintCalculator::UpdateLargestContentfulPaint(
return;
const KURL& url = cached_image->Url();
- auto* document = window_performance_->GetExecutionContext();
- bool expose_paint_time_to_api = true;
- bool response_tainting_not_basic = false;
- bool tainted_origin_flag = false;
- if (!url.ProtocolIsData() &&
- (!document ||
- !Performance::PassesTimingAllowCheck(
- cached_image->GetResponse(), cached_image->GetResponse(),
- *document->GetSecurityOrigin(), document,
- &response_tainting_not_basic, &tainted_origin_flag))) {
- expose_paint_time_to_api = false;
+ bool expose_paint_time_to_api = url.ProtocolIsData();
+ // Use TimingAllowPassed() if possible, see comment in ImageElementTiming.
+ if (!expose_paint_time_to_api) {
+ if (RuntimeEnabledFeatures::OutOfBlinkCorsEnabled()) {
+ expose_paint_time_to_api =
+ cached_image->GetResponse().TimingAllowPassed();
+ } else {
+ auto* document = window_performance_->GetExecutionContext();
+ bool response_tainting_not_basic = false;
+ bool tainted_origin_flag = false;
+ expose_paint_time_to_api =
+ document &&
+ Performance::PassesTimingAllowCheck(
+ cached_image->GetResponse(), cached_image->GetResponse(),
+ *document->GetSecurityOrigin(), document,
+ &response_tainting_not_basic, &tainted_origin_flag);
+ }
}
const String& image_url =
url.ProtocolIsData()
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 72de5f84b10..45d35a591a0 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(blink::Visitor* visitor);
+ void Trace(Visitor* visitor);
private:
friend class LargestContentfulPaintCalculatorTest;
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 3df1a8f2a29..1bbdc7dcc45 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
@@ -74,9 +74,7 @@ void BuildBackplate(const InlineFlowBox* box,
}
}
-} // anonymous namespace
-
-static void AddURLRectsForInlineChildrenRecursively(
+void AddURLRectsForInlineChildrenRecursively(
const LayoutObject& layout_object,
const PaintInfo& paint_info,
const PhysicalOffset& paint_offset) {
@@ -90,6 +88,8 @@ static void AddURLRectsForInlineChildrenRecursively(
}
}
+} // anonymous namespace
+
bool LineBoxListPainter::ShouldPaint(const LayoutBoxModelObject& layout_object,
const PaintInfo& paint_info,
const PhysicalOffset& paint_offset) const {
@@ -100,12 +100,6 @@ bool LineBoxListPainter::ShouldPaint(const LayoutBoxModelObject& layout_object,
DCHECK(layout_object.IsLayoutBlock() ||
(layout_object.IsLayoutInline() && layout_object.HasLayer()));
- if (paint_info.phase == PaintPhase::kForeground &&
- paint_info.ShouldAddUrlMetadata()) {
- AddURLRectsForInlineChildrenRecursively(layout_object, paint_info,
- paint_offset);
- }
-
// If we have no lines then we have no work to do.
if (!line_box_list_.First())
return false;
@@ -123,11 +117,17 @@ void LineBoxListPainter::Paint(const LayoutBoxModelObject& layout_object,
const PhysicalOffset& paint_offset) const {
// Only paint during the foreground/selection phases.
if (paint_info.phase != PaintPhase::kForeground &&
- paint_info.phase != PaintPhase::kSelection &&
+ paint_info.phase != PaintPhase::kSelectionDragImage &&
paint_info.phase != PaintPhase::kTextClip &&
paint_info.phase != PaintPhase::kMask)
return;
+ if (paint_info.phase == PaintPhase::kForeground &&
+ paint_info.ShouldAddUrlMetadata()) {
+ AddURLRectsForInlineChildrenRecursively(layout_object, paint_info,
+ paint_offset);
+ }
+
if (!ShouldPaint(layout_object, paint_info, paint_offset))
return;
@@ -158,8 +158,9 @@ void LineBoxListPainter::PaintBackplate(
const LayoutBoxModelObject& layout_object,
const PaintInfo& paint_info,
const PhysicalOffset& paint_offset) const {
- if (paint_info.phase != PaintPhase::kForcedColorsModeBackplate ||
- !ShouldPaint(layout_object, paint_info, paint_offset))
+ DCHECK_EQ(paint_info.phase, PaintPhase::kForcedColorsModeBackplate);
+
+ if (!ShouldPaint(layout_object, paint_info, paint_offset))
return;
// Only paint backplates behind text when forced-color-adjust is auto.
diff --git a/chromium/third_party/blink/renderer/core/paint/link_highlight_impl.cc b/chromium/third_party/blink/renderer/core/paint/link_highlight_impl.cc
index 78ef41eddaa..c67909af9aa 100644
--- a/chromium/third_party/blink/renderer/core/paint/link_highlight_impl.cc
+++ b/chromium/third_party/blink/renderer/core/paint/link_highlight_impl.cc
@@ -33,7 +33,6 @@
#include "cc/layers/picture_layer.h"
#include "cc/paint/display_item_list.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_float_point.h"
#include "third_party/blink/public/platform/web_rect.h"
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/public/web/blink.h"
@@ -47,6 +46,8 @@
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/layout/layout_box_model_object.h"
#include "third_party/blink/renderer/core/layout/layout_object.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/paint/compositing/composited_layer_mapping.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
@@ -112,6 +113,8 @@ LinkHighlightImpl::LinkHighlightImpl(Node* node)
EffectPaintPropertyNode::Root(),
LinkHighlightEffectNodeState(kStartOpacity, element_id_));
+ DCHECK(GetLayoutObject());
+ GetLayoutObject()->SetNeedsPaintPropertyUpdate();
SetPaintArtifactCompositorNeedsUpdate();
#if DCHECK_IS_ON()
@@ -132,7 +135,7 @@ void LinkHighlightImpl::ReleaseResources() {
if (!node_)
return;
- if (auto* layout_object = node_->GetLayoutObject())
+ if (auto* layout_object = GetLayoutObject())
layout_object->SetNeedsPaintPropertyUpdate();
SetPaintArtifactCompositorNeedsUpdate();
@@ -142,7 +145,6 @@ void LinkHighlightImpl::ReleaseResources() {
LinkHighlightImpl::LinkHighlightFragment::LinkHighlightFragment() {
layer_ = cc::PictureLayer::Create(this);
- layer_->SetTransformOrigin(FloatPoint3D());
layer_->SetIsDrawable(true);
layer_->SetOpacity(kStartOpacity);
}
@@ -233,17 +235,15 @@ void LinkHighlightImpl::NotifyAnimationFinished(double, int) {
}
void LinkHighlightImpl::UpdateBeforePrePaint() {
- if (!node_ || !node_->GetLayoutObject() ||
- node_->GetLayoutObject()->GetFrameView()->ShouldThrottleRendering())
+ auto* object = GetLayoutObject();
+ if (!object || object->GetFrameView()->ShouldThrottleRendering())
ReleaseResources();
}
void LinkHighlightImpl::UpdateAfterPrePaint() {
- if (!node_)
+ auto* object = GetLayoutObject();
+ if (!object)
return;
-
- const auto* object = node_->GetLayoutObject();
- DCHECK(object);
DCHECK(!object->GetFrameView()->ShouldThrottleRendering());
size_t fragment_count = 0;
@@ -262,15 +262,12 @@ CompositorAnimation* LinkHighlightImpl::GetCompositorAnimation() const {
}
void LinkHighlightImpl::Paint(GraphicsContext& context) {
- if (!node_)
+ auto* object = GetLayoutObject();
+ if (!object)
return;
- const auto* object = node_->GetLayoutObject();
- // TODO(crbug.com/1016587): Change the CHECKs to DCHECKs after we address
- // the cause of the bug.
- CHECK(object);
- CHECK(object->GetFrameView());
- CHECK(!object->GetFrameView()->ShouldThrottleRendering());
+ DCHECK(object->GetFrameView());
+ DCHECK(!object->GetFrameView()->ShouldThrottleRendering());
static const FloatSize rect_rounding_radii(3, 3);
auto color = object->StyleRef().TapHighlightColor();
@@ -279,7 +276,6 @@ void LinkHighlightImpl::Paint(GraphicsContext& context) {
// otherwise we may sometimes get a chain of adjacent boxes (e.g. for text
// nodes) which end up looking like sausage links: these should ideally be
// merged into a single rect before creating the path.
- CHECK(node_->GetDocument().GetSettings());
bool use_rounded_rects = !node_->GetDocument()
.GetSettings()
->GetMockGestureTapHighlightsEnabled() &&
@@ -293,6 +289,20 @@ void LinkHighlightImpl::Paint(GraphicsContext& context) {
if (rects.size() > 1)
use_rounded_rects = false;
+ // TODO(yosin): We should remove following if-statement once we release
+ // NGFragmentItem to renderer rounded rect even if nested inline, e.g.
+ // <a>ABC<b>DEF</b>GHI</a>.
+ // See gesture-tapHighlight-simple-nested.html
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled() &&
+ use_rounded_rects && object->IsLayoutInline()) {
+ NGInlineCursor cursor;
+ cursor.MoveTo(*object);
+ // When |LayoutInline| has more than one children, we render square
+ // rectangle as |NGPaintFragment|.
+ if (cursor && cursor.CurrentItem()->DescendantsCount() > 2)
+ use_rounded_rects = false;
+ }
+
Path new_path;
for (auto& rect : rects) {
FloatRect snapped_rect(PixelSnappedIntRect(rect));
@@ -302,7 +312,7 @@ void LinkHighlightImpl::Paint(GraphicsContext& context) {
new_path.AddRect(snapped_rect);
}
- CHECK_LT(index, fragments_.size());
+ DCHECK_LT(index, fragments_.size());
auto& link_highlight_fragment = fragments_[index];
link_highlight_fragment.SetColor(color);
@@ -310,7 +320,7 @@ void LinkHighlightImpl::Paint(GraphicsContext& context) {
new_path.Translate(-ToFloatSize(bounding_rect.Location()));
auto* layer = link_highlight_fragment.Layer();
- CHECK(layer);
+ DCHECK(layer);
if (link_highlight_fragment.GetPath() != new_path) {
link_highlight_fragment.SetPath(new_path);
layer->SetBounds(gfx::Size(EnclosingIntRect(bounding_rect).Size()));
@@ -324,7 +334,7 @@ void LinkHighlightImpl::Paint(GraphicsContext& context) {
property_tree_state.SetEffect(Effect());
RecordForeignLayer(context, debug_name_client,
DisplayItem::kForeignLayerLinkHighlight, layer,
- bounding_rect.Location(), property_tree_state);
+ bounding_rect.Location(), &property_tree_state);
}
DCHECK_EQ(index, fragments_.size());
diff --git a/chromium/third_party/blink/renderer/core/paint/link_highlight_impl.h b/chromium/third_party/blink/renderer/core/paint/link_highlight_impl.h
index 7d32caec420..d1acdedd830 100644
--- a/chromium/third_party/blink/renderer/core/paint/link_highlight_impl.h
+++ b/chromium/third_party/blink/renderer/core/paint/link_highlight_impl.h
@@ -30,6 +30,7 @@
#include "cc/layers/content_layer_client.h"
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation_client.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation_delegate.h"
@@ -48,7 +49,6 @@ namespace blink {
class EffectPaintPropertyNode;
class GraphicsContext;
-class Node;
class CORE_EXPORT LinkHighlightImpl final : public CompositorAnimationDelegate,
public CompositorAnimationClient {
@@ -66,7 +66,9 @@ class CORE_EXPORT LinkHighlightImpl final : public CompositorAnimationDelegate,
// CompositorAnimationClient implementation.
CompositorAnimation* GetCompositorAnimation() const override;
- Node* GetNode() const { return node_; }
+ LayoutObject* GetLayoutObject() const {
+ return node_ ? node_->GetLayoutObject() : nullptr;
+ }
CompositorElementId ElementIdForTesting() const { return element_id_; }
@@ -111,7 +113,7 @@ class CORE_EXPORT LinkHighlightImpl final : public CompositorAnimationDelegate,
};
Vector<LinkHighlightFragment> fragments_;
- Persistent<Node> node_;
+ WeakPersistent<Node> node_;
std::unique_ptr<CompositorAnimation> compositor_animation_;
scoped_refptr<EffectPaintPropertyNode> effect_;
diff --git a/chromium/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc b/chromium/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc
index 3b0ff3bb636..c7cb2458cb9 100644
--- a/chromium/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc
@@ -30,8 +30,7 @@
#include "cc/layers/picture_layer.h"
#include "cc/trees/layer_tree_host.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/web_float_point.h"
-#include "third_party/blink/public/platform/web_input_event.h"
+#include "third_party/blink/public/common/input/web_input_event.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/web/web_frame.h"
@@ -104,7 +103,7 @@ class LinkHighlightImplTest : public testing::Test,
void UpdateAllLifecyclePhases() {
web_view_helper_.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
}
LinkHighlight& GetLinkHighlight() {
@@ -141,14 +140,14 @@ TEST_P(LinkHighlightImplTest, verifyWebViewImplIntegration) {
// The coordinates below are linked to absolute positions in the referenced
// .html file.
- touch_event.SetPositionInWidget(WebFloatPoint(20, 20));
+ touch_event.SetPositionInWidget(gfx::PointF(20, 20));
ASSERT_TRUE(web_view_impl->BestTapNode(GetTargetedEvent(touch_event)));
- touch_event.SetPositionInWidget(WebFloatPoint(20, 40));
+ touch_event.SetPositionInWidget(gfx::PointF(20, 40));
EXPECT_FALSE(web_view_impl->BestTapNode(GetTargetedEvent(touch_event)));
- touch_event.SetPositionInWidget(WebFloatPoint(20, 20));
+ touch_event.SetPositionInWidget(gfx::PointF(20, 20));
// Shouldn't crash.
web_view_impl->EnableTapHighlightAtPoint(GetTargetedEvent(touch_event));
@@ -158,7 +157,7 @@ TEST_P(LinkHighlightImplTest, verifyWebViewImplIntegration) {
EXPECT_TRUE(highlight->LayerForTesting(0));
// Find a target inside a scrollable div
- touch_event.SetPositionInWidget(WebFloatPoint(20, 100));
+ touch_event.SetPositionInWidget(gfx::PointF(20, 100));
web_view_impl->EnableTapHighlightAtPoint(GetTargetedEvent(touch_event));
ASSERT_TRUE(highlight);
@@ -167,11 +166,11 @@ TEST_P(LinkHighlightImplTest, verifyWebViewImplIntegration) {
// Don't highlight if no "hand cursor"
touch_event.SetPositionInWidget(
- WebFloatPoint(20, 220)); // An A-link with cross-hair cursor.
+ gfx::PointF(20, 220)); // An A-link with cross-hair cursor.
web_view_impl->EnableTapHighlightAtPoint(GetTargetedEvent(touch_event));
EXPECT_FALSE(GetLinkHighlightImpl());
- touch_event.SetPositionInWidget(WebFloatPoint(20, 260)); // A text input box.
+ touch_event.SetPositionInWidget(gfx::PointF(20, 260)); // A text input box.
web_view_impl->EnableTapHighlightAtPoint(GetTargetedEvent(touch_event));
EXPECT_FALSE(GetLinkHighlightImpl());
}
@@ -188,7 +187,7 @@ TEST_P(LinkHighlightImplTest, resetDuringNodeRemoval) {
WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- touch_event.SetPositionInWidget(WebFloatPoint(20, 20));
+ touch_event.SetPositionInWidget(gfx::PointF(20, 20));
GestureEventWithHitTestResults targeted_event = GetTargetedEvent(touch_event);
Node* touch_node = web_view_impl->BestTapNode(targeted_event);
@@ -197,14 +196,14 @@ TEST_P(LinkHighlightImplTest, resetDuringNodeRemoval) {
web_view_impl->EnableTapHighlightAtPoint(targeted_event);
const auto* highlight = GetLinkHighlightImpl();
ASSERT_TRUE(highlight);
- EXPECT_EQ(touch_node, highlight->GetNode());
+ EXPECT_EQ(touch_node->GetLayoutObject(), highlight->GetLayoutObject());
touch_node->remove(IGNORE_EXCEPTION_FOR_TESTING);
UpdateAllLifecyclePhases();
ASSERT_EQ(highlight, GetLinkHighlightImpl());
ASSERT_TRUE(highlight);
- EXPECT_FALSE(highlight->GetNode());
+ EXPECT_FALSE(highlight->GetLayoutObject());
}
// A lifetime test: delete LayerTreeView while running LinkHighlights.
@@ -220,7 +219,7 @@ TEST_P(LinkHighlightImplTest, resetLayerTreeView) {
WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- touch_event.SetPositionInWidget(WebFloatPoint(20, 20));
+ touch_event.SetPositionInWidget(gfx::PointF(20, 20));
GestureEventWithHitTestResults targeted_event = GetTargetedEvent(touch_event);
Node* touch_node = web_view_impl->BestTapNode(targeted_event);
@@ -245,7 +244,7 @@ TEST_P(LinkHighlightImplTest, HighlightLayerEffectNode) {
WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
- touch_event.SetPositionInWidget(WebFloatPoint(20, 20));
+ touch_event.SetPositionInWidget(gfx::PointF(20, 20));
GestureEventWithHitTestResults targeted_event = GetTargetedEvent(touch_event);
Node* touch_node = web_view_impl->BestTapNode(targeted_event);
@@ -309,7 +308,7 @@ TEST_P(LinkHighlightImplTest, MultiColumn) {
WebInputEvent::GetStaticTimeStampForTests(),
WebGestureDevice::kTouchscreen);
// This will touch the link under multicol.
- touch_event.SetPositionInWidget(WebFloatPoint(20, 300));
+ touch_event.SetPositionInWidget(gfx::PointF(20, 300));
GestureEventWithHitTestResults targeted_event = GetTargetedEvent(touch_event);
Node* touch_node = web_view_impl->BestTapNode(targeted_event);
@@ -380,4 +379,28 @@ TEST_P(LinkHighlightImplTest, MultiColumn) {
EXPECT_EQ(layer_count_before_highlight, LayerCount());
}
+TEST_P(LinkHighlightImplTest, DisplayContents) {
+ WebViewImpl* web_view_impl = web_view_helper_.GetWebView();
+
+ int page_width = 640;
+ int page_height = 480;
+ web_view_impl->MainFrameWidget()->Resize(WebSize(page_width, page_height));
+ UpdateAllLifecyclePhases();
+
+ WebGestureEvent touch_event(WebInputEvent::kGestureShowPress,
+ WebInputEvent::kNoModifiers,
+ WebInputEvent::GetStaticTimeStampForTests(),
+ WebGestureDevice::kTouchscreen);
+ // This will touch the div with display:contents and cursor:pointer.
+ touch_event.SetPositionInWidget(gfx::PointF(20, 400));
+
+ GestureEventWithHitTestResults targeted_event = GetTargetedEvent(touch_event);
+ const Node* touched_node = targeted_event.GetHitTestResult().InnerNode();
+ EXPECT_TRUE(touched_node->IsTextNode());
+ EXPECT_FALSE(web_view_impl->BestTapNode(targeted_event));
+
+ web_view_impl->EnableTapHighlightAtPoint(targeted_event);
+ EXPECT_FALSE(GetLinkHighlightImpl());
+}
+
} // namespace blink
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 3d0509ef618..129ae0e73ca 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
@@ -25,6 +25,8 @@ void ListMarkerPainter::PaintSymbol(const PaintInfo& paint_info,
const IntRect& marker) {
DCHECK(object);
GraphicsContext& context = paint_info.context;
+ ScopedDarkModeElementRoleOverride list_symbol(
+ &context, DarkModeFilter::ElementRole::kListSymbol);
Color color(object->ResolveColor(GetCSSPropertyColor()));
if (BoxModelObjectPainter::ShouldForceWhiteBackgroundForPrintEconomy(
object->GetDocument(), style))
@@ -108,8 +110,7 @@ void ListMarkerPainter::Paint(const PaintInfo& paint_info) {
Color color(layout_list_marker_.ResolveColor(GetCSSPropertyColor()));
if (BoxModelObjectPainter::ShouldForceWhiteBackgroundForPrintEconomy(
- layout_list_marker_.ListItem()->GetDocument(),
- layout_list_marker_.StyleRef()))
+ layout_list_marker_.GetDocument(), layout_list_marker_.StyleRef()))
color = TextPainter::TextColorForWhiteBackground(color);
// Apply the color to the list marker text.
diff --git a/chromium/third_party/blink/renderer/core/paint/multi_column_set_painter.cc b/chromium/third_party/blink/renderer/core/paint/multi_column_set_painter.cc
index c9a4348d6f1..f16be7a8e54 100644
--- a/chromium/third_party/blink/renderer/core/paint/multi_column_set_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/multi_column_set_painter.cc
@@ -29,7 +29,7 @@ void MultiColumnSetPainter::PaintObject(const PaintInfo& paint_info,
// It's also really unlikely that the columns would overlap another block.
if (!layout_multi_column_set_.FlowThread() ||
(paint_info.phase != PaintPhase::kForeground &&
- paint_info.phase != PaintPhase::kSelection))
+ paint_info.phase != PaintPhase::kSelectionDragImage))
return;
PaintColumnRules(paint_info, paint_offset);
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/README.md b/chromium/third_party/blink/renderer/core/paint/ng/README.md
index 70c1fb9bb76..31778f46d11 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/README.md
+++ b/chromium/third_party/blink/renderer/core/paint/ng/README.md
@@ -59,6 +59,25 @@ even though the inline block LayoutObject has children.
If the inline block has another inline block which LayoutNG can handle,
another NGPaintFragment tree is created for the inner inline block.
+### NGPhysicalFragment traversal ###
+
+When possible (when sufficiently transitioned to LayoutNG), we'll paint and
+hit-test by traversing the physical fragment tree, rather than traversing the
+LayoutObject tree. This is important for block fragmentation, where a CSS layout
+box (LayoutObject) may be split into multiple fragments, and it's the
+relationship between the fragments (not the layout objects) that determines the
+offsets. In LayoutNG, there are also fragments that have no corresponding layout
+object - e.g. a column (or other types of [fragmentainer]s too).
+
+Traditionally, when doing block fragmentation (multicol) in legacy layout, we
+have to perform some complicated calculations, where we map and slice layout
+objects into fragments during pre-paint. In LayoutNG this job is now as a
+natural part of layout. So, all we have to do for painting and hit-testing, is
+traverse the fragments. A fragment holds a list of child fragments and their
+offsets. The offsets are relative to the parent fragment. As such, it's a rather
+straight-forward job for pre-paint to calculate the offsets and bounding box.
+
[LayoutNG]: ../../layout/ng/README.md
[NGPaintFragment]: ng_paint_fragment.h
[NGPhysicalFragment]: ../../layout/ng/ng_physical_fragment.h
+[fragmentainer]: https://drafts.csswg.org/css-break/#fragmentation-container
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 6260eae3666..e8ff0f43f2f 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
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h"
+#include "base/containers/adapters.h"
#include "third_party/blink/renderer/core/editing/drag_caret.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -28,6 +29,7 @@
#include "third_party/blink/renderer/core/paint/ng/ng_fieldset_painter.h"
#include "third_party/blink/renderer/core/paint/ng/ng_fragment_painter.h"
#include "third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.h"
+#include "third_party/blink/renderer/core/paint/ng/ng_mathml_painter.h"
#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
#include "third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.h"
#include "third_party/blink/renderer/core/paint/object_painter.h"
@@ -44,8 +46,6 @@
#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h"
#include "third_party/blink/renderer/platform/graphics/paint/display_item_cache_skipper.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
-#include "third_party/blink/renderer/platform/graphics/paint/hit_test_display_item.h"
-#include "third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h"
namespace blink {
@@ -103,7 +103,7 @@ bool HitTestCulledInlineAncestors(HitTestResult& result,
// To be passed as |accumulated_offset| to LayoutInline::HitTestCulledInline,
// where it equals the physical offset of the containing block in paint layer.
const PhysicalOffset fallback_accumulated_offset =
- physical_offset - fragment.InlineOffsetToContainerBox();
+ physical_offset - fragment.OffsetInContainerBlock();
const LayoutObject* limit_layout_object =
parent.PhysicalFragment().IsLineBox() ? parent.Parent()->GetLayoutObject()
: parent.GetLayoutObject();
@@ -156,71 +156,122 @@ bool FragmentRequiresLegacyFallback(const NGPhysicalFragment& fragment) {
// Fallback to LayoutObject if this is a root of NG block layout.
// If this box is for this painter, LayoutNGBlockFlow will call this back.
// Otherwise it calls legacy painters.
- return fragment.IsBlockFormattingContextRoot();
+ return fragment.IsFormattingContextRoot();
}
-// Recursively build up backplates behind inline text boxes, each split at the
-// paragraph level. Store the results in paragraph_backplates.
-void BuildBackplate(const NGPaintFragment* line,
- const PhysicalOffset& paint_offset,
- PhysicalRect* current_backplate,
- int* consecutive_line_breaks,
- Vector<PhysicalRect>* paragraph_backplates) {
- DCHECK(current_backplate && consecutive_line_breaks && paragraph_backplates);
-
+// Returns a vector of backplates that surround the paragraphs of text within
+// line_boxes.
+//
+// This function traverses descendants of an inline formatting context in
+// pre-order DFS and build up backplates behind inline text boxes, each split at
+// the paragraph level. Store the results in paragraph_backplates.
+Vector<PhysicalRect> BuildBackplate(NGInlineCursor* descendants,
+ const PhysicalOffset& paint_offset) {
// The number of consecutive forced breaks that split the backplate by
// paragraph.
static constexpr int kMaxConsecutiveLineBreaks = 2;
+ struct Backplates {
+ STACK_ALLOCATED();
+
+ public:
+ void AddTextRect(const PhysicalRect& box_rect) {
+ if (consecutive_line_breaks >= kMaxConsecutiveLineBreaks) {
+ // This is a paragraph point.
+ paragraph_backplates.push_back(current_backplate);
+ current_backplate = PhysicalRect();
+ }
+ consecutive_line_breaks = 0;
+
+ current_backplate.Unite(box_rect);
+ }
+
+ void AddLineBreak() { consecutive_line_breaks++; }
+
+ Vector<PhysicalRect> paragraph_backplates;
+ PhysicalRect current_backplate;
+ int consecutive_line_breaks = 0;
+ } backplates;
+
// Build up and paint backplates of all child inline text boxes. We are not
// able to simply use the linebox rect to compute the backplate because the
// backplate should only be painted for inline text and not for atomic
// inlines.
- for (const NGPaintFragment* child : line->Children()) {
- const NGPhysicalFragment& child_fragment = child->PhysicalFragment();
- if (child_fragment.IsHiddenForPaint() || child_fragment.IsFloating())
- continue;
- if (auto* text_fragment =
- DynamicTo<NGPhysicalTextFragment>(child_fragment)) {
- if (text_fragment->IsLineBreak()) {
- (*consecutive_line_breaks)++;
+ for (; *descendants; descendants->MoveToNext()) {
+ if (const NGPaintFragment* child = descendants->CurrentPaintFragment()) {
+ const NGPhysicalFragment& child_fragment = child->PhysicalFragment();
+ if (child_fragment.IsHiddenForPaint() || child_fragment.IsFloating())
continue;
- }
+ if (auto* text_fragment =
+ DynamicTo<NGPhysicalTextFragment>(child_fragment)) {
+ if (text_fragment->IsLineBreak()) {
+ backplates.AddLineBreak();
+ continue;
+ }
- if (*consecutive_line_breaks >= kMaxConsecutiveLineBreaks) {
- // This is a paragraph point.
- paragraph_backplates->push_back(*current_backplate);
- *current_backplate = PhysicalRect();
+ PhysicalRect box_rect(child->OffsetInContainerBlock() + paint_offset,
+ child->Size());
+ backplates.AddTextRect(box_rect);
}
- *consecutive_line_breaks = 0;
- PhysicalRect box_rect(child->InlineOffsetToContainerBox() + paint_offset,
- child->Size());
- current_backplate->Unite(box_rect);
+ continue;
}
- if (child_fragment.Type() == NGPhysicalFragment::kFragmentBox) {
- // If a fragment box was reached, continue to recursively build
- // up the backplate.
- BuildBackplate(child, paint_offset, current_backplate,
- consecutive_line_breaks, paragraph_backplates);
+ if (const NGFragmentItem* child_item = descendants->CurrentItem()) {
+ if (child_item->IsHiddenForPaint())
+ continue;
+ if (child_item->IsText()) {
+ if (child_item->IsLineBreak()) {
+ backplates.AddLineBreak();
+ continue;
+ }
+
+ PhysicalRect box_rect(
+ child_item->OffsetInContainerBlock() + paint_offset,
+ child_item->Size());
+ backplates.AddTextRect(box_rect);
+ }
+ continue;
}
+ NOTREACHED();
}
+
+ if (!backplates.current_backplate.IsEmpty())
+ backplates.paragraph_backplates.push_back(backplates.current_backplate);
+ return backplates.paragraph_backplates;
}
-// Returns a vector of backplates that surround the paragraphs of text within
-// line_boxes.
-Vector<PhysicalRect> BuildBackplate(const NGPaintFragment::ChildList line_boxes,
- const PhysicalOffset& paint_offset) {
- Vector<PhysicalRect> paragraph_backplates;
- PhysicalRect current_backplate;
- int consecutive_line_breaks = 0;
- for (const NGPaintFragment* line : line_boxes) {
- // Recursively build up and paint backplates for line boxes containing text.
- BuildBackplate(line, paint_offset, &current_backplate,
- &consecutive_line_breaks, &paragraph_backplates);
+bool HitTestAllPhasesInFragment(const NGPhysicalBoxFragment& fragment,
+ const HitTestLocation& hit_test_location,
+ PhysicalOffset accumulated_offset,
+ HitTestResult* result) {
+ // Hit test all phases of inline blocks, inline tables, replaced elements and
+ // non-positioned floats as if they created their own (pseudo- [1]) stacking
+ // context. https://www.w3.org/TR/CSS22/zindex.html#painting-order
+ //
+ // [1] As if it creates a new stacking context, but any positioned descendants
+ // and descendants which actually create a new stacking context should be
+ // considered part of the parent stacking context, not this new one.
+
+ if (!fragment.CanTraverse()) {
+ return fragment.GetMutableLayoutObject()->HitTestAllPhases(
+ *result, hit_test_location, accumulated_offset);
}
- if (!current_backplate.IsEmpty())
- paragraph_backplates.push_back(current_backplate);
- return paragraph_backplates;
+
+ return NGBoxFragmentPainter(To<NGPhysicalBoxFragment>(fragment))
+ .HitTestAllPhases(*result, hit_test_location, accumulated_offset);
+}
+
+bool NodeAtPointInFragment(const NGPhysicalBoxFragment& fragment,
+ const HitTestLocation& hit_test_location,
+ PhysicalOffset accumulated_offset,
+ HitTestAction action,
+ HitTestResult* result) {
+ if (!fragment.CanTraverse()) {
+ return fragment.GetMutableLayoutObject()->NodeAtPoint(
+ *result, hit_test_location, accumulated_offset, action);
+ }
+
+ return NGBoxFragmentPainter(fragment).NodeAtPoint(*result, hit_test_location,
+ accumulated_offset, action);
}
} // anonymous namespace
@@ -234,16 +285,35 @@ const NGBorderEdges& NGBoxFragmentPainter::BorderEdges() const {
return *border_edges_;
}
+PhysicalRect NGBoxFragmentPainter::SelfInkOverflow() const {
+ if (paint_fragment_)
+ return paint_fragment_->SelfInkOverflow();
+ if (box_item_)
+ return box_item_->SelfInkOverflow();
+ const NGPhysicalFragment& fragment = PhysicalFragment();
+ DCHECK(fragment.IsBox() && !fragment.IsInlineBox());
+ return ToLayoutBox(fragment.GetLayoutObject())
+ ->PhysicalSelfVisualOverflowRect();
+}
+
+PhysicalRect NGBoxFragmentPainter::ContentsInkOverflow() const {
+ if (const LayoutObject* layout_object = box_fragment_.GetLayoutObject())
+ return ToLayoutBox(layout_object)->PhysicalContentsVisualOverflowRect();
+ return box_fragment_.ContentsInkOverflow();
+}
+
void NGBoxFragmentPainter::Paint(const PaintInfo& paint_info) {
- if (PhysicalFragment().IsAtomicInline() &&
+ if (PhysicalFragment().IsPaintedAtomically() &&
!box_fragment_.HasSelfPaintingLayer())
- PaintAtomicInline(paint_info);
+ PaintAllPhasesAtomically(paint_info);
else
PaintInternal(paint_info);
}
void NGBoxFragmentPainter::PaintInternal(const PaintInfo& paint_info) {
- ScopedPaintState paint_state(box_fragment_, paint_info);
+ // Avoid initialization of Optional ScopedPaintState::chunk_properties_
+ // and ScopedPaintState::adjusted_paint_info_.
+ STACK_UNINITIALIZED ScopedPaintState paint_state(box_fragment_, paint_info);
if (!ShouldPaint(paint_state))
return;
@@ -251,6 +321,15 @@ void NGBoxFragmentPainter::PaintInternal(const PaintInfo& paint_info) {
PhysicalOffset paint_offset = paint_state.PaintOffset();
PaintPhase original_phase = info.phase;
+ ScopedPaintTimingDetectorBlockPaintHook
+ scoped_paint_timing_detector_block_paint_hook;
+ if (original_phase == PaintPhase::kForeground &&
+ box_fragment_.GetLayoutObject()->IsBox()) {
+ scoped_paint_timing_detector_block_paint_hook.EmplaceIfNeeded(
+ ToLayoutBox(*box_fragment_.GetLayoutObject()),
+ paint_info.context.GetPaintController().CurrentPaintChunkProperties());
+ }
+
if (original_phase == PaintPhase::kOutline) {
info.phase = PaintPhase::kDescendantOutlinesOnly;
} else if (ShouldPaintSelfBlockBackground(original_phase)) {
@@ -318,17 +397,18 @@ void NGBoxFragmentPainter::RecordScrollHitTestData(
.RecordScrollHitTestData(paint_info, background_client);
}
-void NGBoxFragmentPainter::RecordHitTestDataForLine(
- const PaintInfo& paint_info,
- const PhysicalOffset& paint_offset,
- const NGPhysicalFragment& line,
- const DisplayItemClient& display_item_client) {
- PhysicalRect border_box = line.LocalRect();
- border_box.offset += paint_offset;
- HitTestDisplayItem::Record(
- paint_info.context, display_item_client,
- HitTestRect(border_box.ToLayoutRect(),
- PhysicalFragment().EffectiveAllowedTouchAction()));
+bool NGBoxFragmentPainter::ShouldRecordHitTestData(
+ const PaintInfo& paint_info) {
+ // Hit test data are only needed for compositing. This flag is used for for
+ // printing and drag images which do not need hit testing.
+ if (paint_info.GetGlobalPaintFlags() & kGlobalPaintFlattenCompositingLayers)
+ return false;
+
+ // If an object is not visible, it does not participate in hit testing.
+ if (PhysicalFragment().Style().Visibility() != EVisibility::kVisible)
+ return false;
+
+ return true;
}
void NGBoxFragmentPainter::PaintObject(
@@ -355,39 +435,46 @@ void NGBoxFragmentPainter::PaintObject(
return;
}
- if (paint_phase == PaintPhase::kForeground &&
- paint_info.ShouldAddUrlMetadata()) {
- NGFragmentPainter(box_fragment_, paint_fragment_)
- .AddURLRectIfNeeded(paint_info, paint_offset);
+ if (paint_phase == PaintPhase::kForeground) {
+ if (paint_info.ShouldAddUrlMetadata()) {
+ NGFragmentPainter(box_fragment_, GetDisplayItemClient())
+ .AddURLRectIfNeeded(paint_info, paint_offset);
+ }
+ if (is_visible && box_fragment_.IsMathMLFraction())
+ NGMathMLPainter(box_fragment_).PaintFractionBar(paint_info, paint_offset);
}
if (paint_phase != PaintPhase::kSelfOutlineOnly &&
(!physical_box_fragment.Children().empty() ||
- physical_box_fragment.HasItems() || descendants_) &&
+ physical_box_fragment.HasItems() || inline_box_cursor_) &&
!paint_info.DescendantPaintingBlocked()) {
- if (RuntimeEnabledFeatures::LayoutNGFragmentPaintEnabled()) {
- if (UNLIKELY(paint_phase == PaintPhase::kForeground &&
- box_fragment_.Style().HasColumnRule()))
- PaintColumnRules(paint_info, paint_offset);
- }
+ if (UNLIKELY(paint_phase == PaintPhase::kForeground &&
+ box_fragment_.Style().HasColumnRule()))
+ PaintColumnRules(paint_info, paint_offset);
if (paint_phase != PaintPhase::kFloat) {
- if (UNLIKELY(descendants_)) {
+ if (UNLIKELY(inline_box_cursor_)) {
// Use the descendants cursor for this painter if it is given.
// Self-painting inline box paints only parts of the container block.
// Adjust |paint_offset| because it is the offset of the inline box, but
// |descendants_| has offsets to the contaiing block.
- DCHECK(box_item_ && box_item_->HasSelfPaintingLayer());
+ DCHECK(box_item_);
+ NGInlineCursor descendants = inline_box_cursor_->CursorForDescendants();
const PhysicalOffset paint_offset_to_inline_formatting_context =
- paint_offset - box_item_->Offset();
+ paint_offset - box_item_->OffsetInContainerBlock();
PaintInlineItems(paint_info.ForDescendants(),
paint_offset_to_inline_formatting_context,
- descendants_);
+ box_item_->OffsetInContainerBlock(), &descendants);
} else if (items_) {
- // Paint |NGFragmentItems| for this block if we have one.
- NGInlineCursor cursor(*items_);
- PaintInlineItems(paint_info.ForDescendants(), paint_offset, &cursor);
- } else if (physical_box_fragment.ChildrenInline()) {
+ if (physical_box_fragment.IsBlockFlow()) {
+ PaintBlockFlowContents(paint_info, paint_offset);
+ } else {
+ DCHECK(physical_box_fragment.IsInlineBox());
+ NGInlineCursor cursor(*items_);
+ PaintInlineItems(paint_info.ForDescendants(), paint_offset,
+ PhysicalOffset(), &cursor);
+ }
+ } else if (physical_box_fragment.IsInlineFormattingContext()) {
DCHECK(!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled());
DCHECK(paint_fragment_);
if (physical_box_fragment.IsBlockFlow()) {
@@ -403,12 +490,12 @@ void NGBoxFragmentPainter::PaintObject(
paint_offset);
}
} else {
- PaintBlockChildren(paint_info);
+ PaintBlockChildren(paint_info, paint_offset);
}
}
if (paint_phase == PaintPhase::kFloat ||
- paint_phase == PaintPhase::kSelection ||
+ paint_phase == PaintPhase::kSelectionDragImage ||
paint_phase == PaintPhase::kTextClip) {
if (physical_box_fragment.HasFloatingDescendantsForPaint())
PaintFloats(paint_info);
@@ -416,7 +503,7 @@ void NGBoxFragmentPainter::PaintObject(
}
if (ShouldPaintSelfOutline(paint_phase)) {
- NGFragmentPainter(box_fragment_, paint_fragment_)
+ NGFragmentPainter(box_fragment_, GetDisplayItemClient())
.PaintOutline(paint_info, paint_offset);
}
@@ -445,18 +532,20 @@ void NGBoxFragmentPainter::PaintBlockFlowContents(
const PhysicalOffset& paint_offset) {
const NGPhysicalBoxFragment& fragment = PhysicalFragment();
const LayoutObject* layout_object = fragment.GetLayoutObject();
-
- DCHECK(fragment.ChildrenInline());
- DCHECK(paint_fragment_);
+ DCHECK(fragment.IsInlineFormattingContext());
// When the layout-tree gets into a bad state, we can end up trying to paint
// a fragment with inline children, without a paint fragment. See:
// http://crbug.com/1022545
- if (!paint_fragment_) {
+ if ((!paint_fragment_ && !items_) ||
+ (layout_object && layout_object->NeedsLayout())) {
NOTREACHED();
return;
}
+ // Trying to rule out a null GraphicsContext, see: https://crbug.com/1040298
+ CHECK(&paint_info.context);
+
// Check if there were contents to be painted and return early if none.
// The union of |ContentsInkOverflow()| and |LocalRect()| covers the rect to
// check, in both cases of:
@@ -467,37 +556,73 @@ void NGBoxFragmentPainter::PaintBlockFlowContents(
// |LayoutOverflow()|, but this can be approximiated with
// |ContentsInkOverflow()|.
PhysicalRect content_ink_rect = fragment.LocalRect();
- content_ink_rect.Unite(paint_fragment_->ContentsInkOverflow());
+ content_ink_rect.Unite(ContentsInkOverflow());
content_ink_rect.offset += PhysicalOffset(paint_offset);
if (!paint_info.GetCullRect().Intersects(content_ink_rect.ToLayoutRect()))
return;
- DCHECK(layout_object->IsLayoutBlockFlow());
- const auto& layout_block = To<LayoutBlock>(*layout_object);
- DCHECK(layout_block.ChildrenInline());
- PaintLineBoxChildren(paint_fragment_->Children(), paint_info.ForDescendants(),
- paint_offset);
+ if (paint_fragment_) {
+ NGInlineCursor children(*paint_fragment_);
+ PaintLineBoxChildren(&children, paint_info.ForDescendants(), paint_offset);
+ return;
+ }
+ DCHECK(items_);
+ NGInlineCursor children(*items_);
+ PaintLineBoxChildren(&children, paint_info.ForDescendants(), paint_offset);
}
-void NGBoxFragmentPainter::PaintBlockChildren(const PaintInfo& paint_info) {
- DCHECK(!box_fragment_.ChildrenInline());
- DCHECK(!box_fragment_.GetLayoutObject()->ChildrenInline());
+void NGBoxFragmentPainter::PaintBlockChildren(const PaintInfo& paint_info,
+ PhysicalOffset paint_offset) {
+ DCHECK(!box_fragment_.IsInlineFormattingContext());
PaintInfo paint_info_for_descendants = paint_info.ForDescendants();
for (const NGLink& child : box_fragment_.Children()) {
const NGPhysicalFragment& child_fragment = *child;
+ DCHECK(child_fragment.IsBox());
if (child_fragment.HasSelfPaintingLayer() || child_fragment.IsFloating() ||
child_fragment.IsColumnBox())
continue;
- if (child_fragment.Type() == NGPhysicalFragment::kFragmentBox) {
- // TODO(kojii): We could skip going through |LayoutObject| when we know
- // children are always laid out by NG. See
- // |FragmentRequiresLegacyFallback|.
- child_fragment.GetLayoutObject()->Paint(paint_info_for_descendants);
- } else {
- DCHECK_EQ(child_fragment.Type(),
- NGPhysicalFragment::kFragmentRenderedLegend);
+ const auto& box_child_fragment = To<NGPhysicalBoxFragment>(child_fragment);
+ if (box_child_fragment.CanTraverse()) {
+ if (!box_child_fragment.GetLayoutObject()) {
+ // It's normally FragmentData that provides us with the paint offset.
+ // FragmentData is (at least currently) associated with a LayoutObject.
+ // If we have no LayoutObject, we have no FragmentData, so we need to
+ // calculate the offset on our own (which is very simple, anyway).
+ // Bypass Paint() and jump directly to PaintObject(), to skip the code
+ // that assumes that we have a LayoutObject (and FragmentData).
+ PhysicalOffset child_offset = paint_offset + child.offset;
+ NGBoxFragmentPainter(box_child_fragment)
+ .PaintObject(paint_info, child_offset);
+ continue;
+ }
+
+ NGBoxFragmentPainter(box_child_fragment)
+ .Paint(paint_info_for_descendants);
+ continue;
}
+ child_fragment.GetLayoutObject()->Paint(paint_info_for_descendants);
+ }
+}
+
+void NGBoxFragmentPainter::PaintFloatingItems(const PaintInfo& paint_info,
+ NGInlineCursor* cursor) {
+ for (; *cursor; cursor->MoveToNext()) {
+ const NGFragmentItem* item = cursor->Current().Item();
+ DCHECK(item);
+ const NGPhysicalBoxFragment* child_fragment = item->BoxFragment();
+ if (!child_fragment || child_fragment->HasSelfPaintingLayer() ||
+ !child_fragment->IsFloating())
+ continue;
+ // TODO(kojii): The float is outside of the inline formatting context and
+ // that it maybe another NG inline formatting context, NG block layout, or
+ // legacy. NGBoxFragmentPainter can handle only the first case. In order
+ // to cover more tests for other two cases, we always fallback to legacy,
+ // which will forward back to NGBoxFragmentPainter if the float is for
+ // NGBoxFragmentPainter. We can shortcut this for the first case when
+ // we're more stable.
+ ObjectPainter(*child_fragment->GetLayoutObject())
+ .PaintAllPhasesAtomically(paint_info);
}
}
@@ -505,60 +630,93 @@ void NGBoxFragmentPainter::PaintFloatingChildren(
const NGPhysicalContainerFragment& container,
const PaintInfo& paint_info,
const PaintInfo& float_paint_info) {
-#if DCHECK_IS_ON()
- // Floats are in the fragment tree, not in the fragment item list.
- if (const NGPhysicalBoxFragment* box_fragment =
+ DCHECK(container.HasFloatingDescendantsForPaint());
+
+ if (const NGPhysicalBoxFragment* box =
DynamicTo<NGPhysicalBoxFragment>(&container)) {
- if (const NGFragmentItems* items = box_fragment->Items()) {
- DCHECK(std::none_of(
- items->Items().begin(), items->Items().end(), [](const auto& item) {
- return item->BoxFragment() && item->BoxFragment()->IsFloating();
- }));
+ if (const NGFragmentItems* items = box->Items()) {
+ NGInlineCursor cursor(*items);
+ PaintFloatingItems(float_paint_info, &cursor);
+ return;
+ }
+ if (inline_box_cursor_) {
+ DCHECK(box->IsInlineBox());
+ NGInlineCursor descendants = inline_box_cursor_->CursorForDescendants();
+ PaintFloatingItems(float_paint_info, &descendants);
+ return;
}
+ DCHECK(!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled() ||
+ !box->IsInlineBox());
}
-#endif
for (const NGLink& child : container.Children()) {
const NGPhysicalFragment& child_fragment = *child;
if (child_fragment.HasSelfPaintingLayer() || child_fragment.IsColumnBox())
continue;
- // Atomic-inlines paint atomically, and shouldn't be traversed.
- // TODO(layout-dev): This check should include all children which paint
- // atomically.
- if (child_fragment.IsAtomicInline())
+ if (child_fragment.CanTraverse()) {
+ if (child_fragment.IsFloating()) {
+ NGBoxFragmentPainter(To<NGPhysicalBoxFragment>(child_fragment))
+ .Paint(float_paint_info);
+ continue;
+ }
+
+ // Any non-floated children which paint atomically shouldn't be traversed.
+ if (child_fragment.IsPaintedAtomically())
+ continue;
+ } else {
+ if (child_fragment.IsFloating()) {
+ // TODO(kojii): The float is outside of the inline formatting context
+ // and that it maybe another NG inline formatting context, NG block
+ // layout, or legacy. NGBoxFragmentPainter can handle only the first
+ // case. In order to cover more tests for other two cases, we always
+ // fallback to legacy, which will forward back to NGBoxFragmentPainter
+ // if the float is for NGBoxFragmentPainter. We can shortcut this for
+ // the first case when we're more stable.
+
+ ObjectPainter(*child_fragment.GetLayoutObject())
+ .PaintAllPhasesAtomically(float_paint_info);
+ continue;
+ }
+
+ // Any children which paint atomically shouldn't be traversed.
+ if (child_fragment.IsPaintedAtomically())
+ continue;
+
+ if (child_fragment.Type() == NGPhysicalFragment::kFragmentBox &&
+ FragmentRequiresLegacyFallback(child_fragment)) {
+ child_fragment.GetLayoutObject()->Paint(paint_info);
+ continue;
+ }
+ }
+
+ // The selection paint traversal is special. We will visit all fragments
+ // (including floats) in the normal paint traversal. There isn't any point
+ // performing the special float traversal here.
+ if (paint_info.phase == PaintPhase::kSelectionDragImage)
continue;
- if (child_fragment.IsFloating()) {
- // TODO(kojii): The float is outside of the inline formatting context and
- // that it maybe another NG inline formatting context, NG block layout, or
- // legacy. NGBoxFragmentPainter can handle only the first case. In order
- // to cover more tests for other two cases, we always fallback to legacy,
- // which will forward back to NGBoxFragmentPainter if the float is for
- // NGBoxFragmentPainter. We can shortcut this for the first case when
- // we're more stable.
- ObjectPainter(*child_fragment.GetLayoutObject())
- .PaintAllPhasesAtomically(float_paint_info);
+ const auto* child_container =
+ DynamicTo<NGPhysicalContainerFragment>(&child_fragment);
+ if (!child_container || !child_container->HasFloatingDescendantsForPaint())
continue;
- }
- if (child_fragment.Type() == NGPhysicalFragment::kFragmentBox &&
- FragmentRequiresLegacyFallback(child_fragment)) {
- child_fragment.GetLayoutObject()->Paint(paint_info);
+ if (child_container->HasOverflowClip()) {
+ // We need to properly visit this fragment for painting, rather than
+ // jumping directly to its children (which is what we normally do when
+ // looking for floats), in order to set up the clip rectangle.
+ NGBoxFragmentPainter(To<NGPhysicalBoxFragment>(*child_container))
+ .Paint(paint_info);
continue;
}
- if (const auto* child_container =
- DynamicTo<NGPhysicalContainerFragment>(&child_fragment)) {
- if (child_container->HasFloatingDescendantsForPaint())
- PaintFloatingChildren(*child_container, paint_info, float_paint_info);
- }
+ PaintFloatingChildren(*child_container, paint_info, float_paint_info);
}
}
void NGBoxFragmentPainter::PaintFloats(const PaintInfo& paint_info) {
DCHECK(PhysicalFragment().HasFloatingDescendantsForPaint() ||
- !PhysicalFragment().ChildrenInline());
+ !PhysicalFragment().IsInlineFormattingContext());
PaintInfo float_paint_info(paint_info);
if (paint_info.phase == PaintPhase::kFloat)
@@ -645,12 +803,10 @@ void NGBoxFragmentPainter::PaintBoxDecorationBackground(
}
}
- if (NGFragmentPainter::ShouldRecordHitTestData(paint_info,
- PhysicalFragment())) {
- HitTestDisplayItem::Record(
- paint_info.context, *background_client,
- HitTestRect(paint_rect.ToLayoutRect(),
- PhysicalFragment().EffectiveAllowedTouchAction()));
+ if (ShouldRecordHitTestData(paint_info)) {
+ paint_info.context.GetPaintController().RecordHitTestData(
+ *background_client, PixelSnappedIntRect(paint_rect),
+ PhysicalFragment().EffectiveAllowedTouchAction());
}
bool needs_scroll_hit_test = true;
@@ -677,24 +833,6 @@ void NGBoxFragmentPainter::PaintBoxDecorationBackground(
// TODO(kojii): This logic is kept in sync with BoxPainter. Not much efforts to
// eliminate LayoutObject dependency were done yet.
-bool NGBoxFragmentPainter::BackgroundIsKnownToBeOpaque(
- const PaintInfo& paint_info) {
- const LayoutBox& layout_box = ToLayoutBox(*box_fragment_.GetLayoutObject());
-
- // If the box has multiple fragments, its VisualRect is the bounding box of
- // all fragments' visual rects, which is likely to cover areas that are not
- // covered by painted background.
- if (layout_box.FirstFragment().NextFragment())
- return false;
-
- PhysicalRect bounds = IsPaintingScrollingBackground(paint_info)
- ? layout_box.PhysicalLayoutOverflowRect()
- : layout_box.PhysicalSelfVisualOverflowRect();
- return layout_box.BackgroundIsKnownToBeOpaqueInRect(bounds);
-}
-
-// TODO(kojii): This logic is kept in sync with BoxPainter. Not much efforts to
-// eliminate LayoutObject dependency were done yet.
void NGBoxFragmentPainter::PaintBoxDecorationBackgroundWithRect(
const PaintInfo& paint_info,
const PhysicalRect& paint_rect,
@@ -705,17 +843,9 @@ void NGBoxFragmentPainter::PaintBoxDecorationBackgroundWithRect(
const ComputedStyle& style = box_fragment_.Style();
base::Optional<DisplayItemCacheSkipper> cache_skipper;
- // Disable cache in under-invalidation checking mode for MediaSliderPart
- // because we always paint using the latest data (buffered ranges, current
- // time and duration) which may be different from the cached data, and for
- // delayed-invalidation object because it may change before it's actually
- // invalidated. Note that we still report harmless under-invalidation of
- // non-delayed-invalidation animated background, which should be ignored.
if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() &&
- (style.EffectiveAppearance() == kMediaSliderPart ||
- layout_box.ShouldDelayFullPaintInvalidation())) {
+ ShouldSkipPaintUnderInvalidationChecking(layout_box))
cache_skipper.emplace(paint_info.context);
- }
BoxDecorationData box_decoration_data(paint_info, PhysicalFragment());
if (!box_decoration_data.ShouldPaint())
@@ -730,11 +860,6 @@ void NGBoxFragmentPainter::PaintBoxDecorationBackgroundWithRect(
DisplayItem::kBoxDecorationBackground);
GraphicsContextStateSaver state_saver(paint_info.context, false);
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
- paint_rect.EdgesOnPixelBoundaries() &&
- BackgroundIsKnownToBeOpaque(paint_info))
- recorder.SetKnownToBeOpaque();
-
const NGBorderEdges& border_edges = BorderEdges();
if (box_decoration_data.ShouldPaintShadow()) {
PaintNormalBoxShadow(paint_info, paint_rect, style, border_edges.line_left,
@@ -971,14 +1096,15 @@ void NGBoxFragmentPainter::PaintInlineChildBoxUsingLegacyFallback(
void NGBoxFragmentPainter::PaintAllPhasesAtomically(
const PaintInfo& paint_info) {
// Self-painting AtomicInlines should go to normal paint logic.
- DCHECK(!(PhysicalFragment().IsAtomicInline() &&
+ DCHECK(!(PhysicalFragment().IsPaintedAtomically() &&
box_fragment_.HasSelfPaintingLayer()));
// Pass PaintPhaseSelection and PaintPhaseTextClip is handled by the regular
// foreground paint implementation. We don't need complete painting for these
// phases.
PaintPhase phase = paint_info.phase;
- if (phase == PaintPhase::kSelection || phase == PaintPhase::kTextClip)
+ if (phase == PaintPhase::kSelectionDragImage ||
+ phase == PaintPhase::kTextClip)
return PaintInternal(paint_info);
if (phase != PaintPhase::kForeground)
@@ -1003,39 +1129,33 @@ void NGBoxFragmentPainter::PaintAllPhasesAtomically(
void NGBoxFragmentPainter::PaintInlineItems(const PaintInfo& paint_info,
const PhysicalOffset& paint_offset,
+ const PhysicalOffset& parent_offset,
NGInlineCursor* cursor) {
- ScopedPaintTimingDetectorBlockPaintHook
- scoped_paint_timing_detector_block_paint_hook;
- // TODO(kojii): Copy more from |PaintLineBoxChildren|.
-
while (*cursor) {
const NGFragmentItem* item = cursor->CurrentItem();
DCHECK(item);
switch (item->Type()) {
case NGFragmentItem::kText:
case NGFragmentItem::kGeneratedText:
- PaintTextItem(*cursor, paint_info, paint_offset);
- break;
- case NGFragmentItem::kLine:
- if (PaintLineBoxItem(*item, paint_info, paint_offset) ==
- kSkipChildren) {
- cursor->MoveToNextSkippingChildren();
- continue;
- }
+ if (!item->IsHiddenForPaint())
+ PaintTextItem(*cursor, paint_info, paint_offset, parent_offset);
+ cursor->MoveToNext();
break;
case NGFragmentItem::kBox:
- if (PaintBoxItem(*item, paint_info, paint_offset) == kSkipChildren) {
- cursor->MoveToNextSkippingChildren();
- continue;
- }
+ if (!item->IsHiddenForPaint())
+ PaintBoxItem(*item, *cursor, paint_info, paint_offset, parent_offset);
+ cursor->MoveToNextSkippingChildren();
+ break;
+ case NGFragmentItem::kLine:
+ NOTREACHED();
+ cursor->MoveToNext();
break;
}
- cursor->MoveToNext();
}
}
-// Paint a line box. This function paints only background of `::first-line`. In
-// all other cases, the container box paints background.
+// Paint a line box. This function paints hit tests and backgrounds of
+// `::first-line`. In all other cases, the container box paints background.
inline void NGBoxFragmentPainter::PaintLineBox(
const NGPhysicalFragment& line_box_fragment,
const DisplayItemClient& display_item_client,
@@ -1046,30 +1166,29 @@ inline void NGBoxFragmentPainter::PaintLineBox(
if (paint_info.phase != PaintPhase::kForeground)
return;
- if (NGFragmentPainter::ShouldRecordHitTestData(paint_info,
- PhysicalFragment())) {
- RecordHitTestDataForLine(paint_info, child_offset, line_box_fragment,
- display_item_client);
+ if (ShouldRecordHitTestData(paint_info)) {
+ 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());
+ }
+ if (NGLineBoxFragmentPainter::NeedsPaint(line_box_fragment)) {
+ NGLineBoxFragmentPainter line_box_painter(
+ line_box_fragment, line_box_paint_fragment, line_box_item,
+ PhysicalFragment(), paint_fragment_);
+ line_box_painter.PaintBackgroundBorderShadow(paint_info, child_offset);
}
-
- // Line boxes don't paint anything, except when its ::first-line style has
- // a background.
- if (!NGLineBoxFragmentPainter::NeedsPaint(line_box_fragment))
- return;
- NGLineBoxFragmentPainter line_box_painter(
- line_box_fragment, line_box_paint_fragment, line_box_item,
- PhysicalFragment(), paint_fragment_);
- line_box_painter.PaintBackgroundBorderShadow(paint_info, child_offset);
}
void NGBoxFragmentPainter::PaintLineBoxChildren(
- NGPaintFragment::ChildList line_boxes,
+ NGInlineCursor* children,
const PaintInfo& paint_info,
const PhysicalOffset& paint_offset) {
// Only paint during the foreground/selection phases.
if (paint_info.phase != PaintPhase::kForeground &&
paint_info.phase != PaintPhase::kForcedColorsModeBackplate &&
- paint_info.phase != PaintPhase::kSelection &&
+ paint_info.phase != PaintPhase::kSelectionDragImage &&
paint_info.phase != PaintPhase::kTextClip &&
paint_info.phase != PaintPhase::kMask &&
paint_info.phase != PaintPhase::kDescendantOutlinesOnly &&
@@ -1078,7 +1197,7 @@ void NGBoxFragmentPainter::PaintLineBoxChildren(
// The only way an inline could paint like this is if it has a layer.
const auto* layout_object = box_fragment_.GetLayoutObject();
- DCHECK(layout_object->IsLayoutBlock() ||
+ DCHECK(!layout_object || layout_object->IsLayoutBlock() ||
(layout_object->IsLayoutInline() && layout_object->HasLayer()));
// if (paint_info.phase == PaintPhase::kForeground && paint_info.IsPrinting())
@@ -1086,27 +1205,24 @@ void NGBoxFragmentPainter::PaintLineBoxChildren(
// paint_offset);
// If we have no lines then we have no work to do.
- if (line_boxes.IsEmpty())
+ if (!*children)
return;
- ScopedPaintTimingDetectorBlockPaintHook
- scoped_paint_timing_detector_block_paint_hook;
- const auto& layout_block = To<LayoutBlock>(*layout_object);
- if (paint_info.phase == PaintPhase::kForeground) {
- scoped_paint_timing_detector_block_paint_hook.EmplaceIfNeeded(
- layout_block,
- paint_info.context.GetPaintController().CurrentPaintChunkProperties());
+ if (paint_info.phase == PaintPhase::kForcedColorsModeBackplate &&
+ box_fragment_.GetDocument().InForcedColorsMode()) {
+ PaintBackplate(children, paint_info, paint_offset);
+ return;
}
- if (paint_info.phase == PaintPhase::kForcedColorsModeBackplate &&
- layout_block.GetDocument().InForcedColorsMode()) {
- PaintBackplate(line_boxes, paint_info, paint_offset);
+ if (UNLIKELY(children->IsItemCursor())) {
+ PaintLineBoxChildItems(children, paint_info, paint_offset);
return;
}
const bool is_horizontal = box_fragment_.Style().IsHorizontalWritingMode();
-
- for (const NGPaintFragment* line : line_boxes) {
+ for (; *children; children->MoveToNextSkippingChildren()) {
+ const NGPaintFragment* line = children->CurrentPaintFragment();
+ DCHECK(line);
const NGPhysicalFragment& child_fragment = line->PhysicalFragment();
DCHECK(!child_fragment.IsOutOfFlowPositioned());
if (child_fragment.IsFloating())
@@ -1140,14 +1256,67 @@ void NGBoxFragmentPainter::PaintLineBoxChildren(
}
}
-void NGBoxFragmentPainter::PaintBackplate(NGPaintFragment::ChildList line_boxes,
+void NGBoxFragmentPainter::PaintLineBoxChildItems(
+ NGInlineCursor* children,
+ const PaintInfo& paint_info,
+ const PhysicalOffset& paint_offset) {
+ const bool is_horizontal = box_fragment_.Style().IsHorizontalWritingMode();
+ for (; *children; children->MoveToNextSkippingChildren()) {
+ const NGFragmentItem* child_item = children->CurrentItem();
+ DCHECK(child_item);
+
+ // Check if CullRect intersects with this child, only in block direction
+ // because soft-wrap and <br> needs to paint outside of InkOverflow() in
+ // inline direction.
+ const PhysicalOffset& child_offset =
+ paint_offset + child_item->OffsetInContainerBlock();
+ const PhysicalRect child_rect = child_item->InkOverflow();
+ if (is_horizontal) {
+ LayoutUnit y = child_rect.offset.top + child_offset.top;
+ if (!paint_info.GetCullRect().IntersectsVerticalRange(
+ y, y + child_rect.size.height))
+ continue;
+ } else {
+ LayoutUnit x = child_rect.offset.left + child_offset.left;
+ if (!paint_info.GetCullRect().IntersectsHorizontalRange(
+ x, x + child_rect.size.width))
+ continue;
+ }
+
+ if (child_item->Type() == NGFragmentItem::kLine) {
+ const NGPhysicalLineBoxFragment* line_box_fragment =
+ child_item->LineBoxFragment();
+ DCHECK(line_box_fragment);
+ PaintLineBox(*line_box_fragment, *child_item,
+ /* line_box_paint_fragment */ nullptr, child_item,
+ paint_info, child_offset);
+ NGInlineCursor line_box_cursor = children->CursorForDescendants();
+ PaintInlineItems(paint_info, paint_offset,
+ child_item->OffsetInContainerBlock(), &line_box_cursor);
+ continue;
+ }
+
+ if (const NGPhysicalBoxFragment* child_fragment =
+ child_item->BoxFragment()) {
+ if (child_fragment->IsListMarker()) {
+ PaintBoxItem(*child_item, *child_fragment, *children, paint_info,
+ paint_offset);
+ continue;
+ }
+ }
+
+ NOTREACHED();
+ }
+}
+
+void NGBoxFragmentPainter::PaintBackplate(NGInlineCursor* line_boxes,
const PaintInfo& paint_info,
const PhysicalOffset& paint_offset) {
if (paint_info.phase != PaintPhase::kForcedColorsModeBackplate)
return;
// Only paint backplates behind text when forced-color-adjust is auto.
- const ComputedStyle& style = line_boxes.front().Style();
+ const ComputedStyle& style = PhysicalFragment().Style();
if (style.ForcedColorAdjust() == EForcedColorAdjust::kNone)
return;
@@ -1229,7 +1398,7 @@ void NGBoxFragmentPainter::PaintTextChild(const NGPaintFragment& paint_fragment,
// Only paint during the foreground/selection phases.
if (paint_info.phase != PaintPhase::kForeground &&
- paint_info.phase != PaintPhase::kSelection &&
+ paint_info.phase != PaintPhase::kSelectionDragImage &&
paint_info.phase != PaintPhase::kTextClip &&
paint_info.phase != PaintPhase::kMask)
return;
@@ -1241,24 +1410,20 @@ void NGBoxFragmentPainter::PaintTextChild(const NGPaintFragment& paint_fragment,
void NGBoxFragmentPainter::PaintTextItem(const NGInlineCursor& cursor,
const PaintInfo& paint_info,
- const PhysicalOffset& paint_offset) {
+ const PhysicalOffset& paint_offset,
+ const PhysicalOffset& parent_offset) {
DCHECK(cursor.CurrentItem());
const NGFragmentItem& item = *cursor.CurrentItem();
DCHECK(item.IsText()) << item;
// Only paint during the foreground/selection phases.
if (paint_info.phase != PaintPhase::kForeground &&
- paint_info.phase != PaintPhase::kSelection &&
+ paint_info.phase != PaintPhase::kSelectionDragImage &&
paint_info.phase != PaintPhase::kTextClip &&
paint_info.phase != PaintPhase::kMask)
return;
- // Need to check the style of each text items because they can have different
- // styles than its siblings if inline boxes are culled.
- if (UNLIKELY(!IsVisibleToPaint(item, item.Style())))
- return;
-
- NGTextFragmentPainter<NGInlineCursor> text_painter(cursor);
+ NGTextFragmentPainter<NGInlineCursor> text_painter(cursor, parent_offset);
text_painter.Paint(paint_info, paint_offset);
}
@@ -1269,7 +1434,8 @@ NGBoxFragmentPainter::MoveTo NGBoxFragmentPainter::PaintLineBoxItem(
DCHECK_EQ(item.Type(), NGFragmentItem::kLine);
DCHECK(items_);
// TODO(kojii): Check CullRect.
- const PhysicalOffset line_box__offset = paint_offset + item.Offset();
+ const PhysicalOffset line_box__offset =
+ paint_offset + item.OffsetInContainerBlock();
const NGPhysicalLineBoxFragment* line_box_fragment = item.LineBoxFragment();
DCHECK(line_box_fragment);
PaintLineBox(*line_box_fragment, item, /* line_box_paint_fragment */ nullptr,
@@ -1277,57 +1443,60 @@ NGBoxFragmentPainter::MoveTo NGBoxFragmentPainter::PaintLineBoxItem(
return kDontSkipChildren;
}
-NGBoxFragmentPainter::MoveTo NGBoxFragmentPainter::PaintBoxItem(
+// Paint non-culled box item.
+void NGBoxFragmentPainter::PaintBoxItem(
const NGFragmentItem& item,
+ const NGPhysicalBoxFragment& child_fragment,
+ const NGInlineCursor& cursor,
const PaintInfo& paint_info,
const PhysicalOffset& paint_offset) {
DCHECK_EQ(item.Type(), NGFragmentItem::kBox);
-
- const ComputedStyle& style = item.Style();
- if (UNLIKELY(!IsVisibleToPaint(item, style)))
- return kSkipChildren;
-
- // Nothing to paint if this is a culled inline box. Proceed to its
- // descendants.
- const NGPhysicalBoxFragment* child_fragment = item.BoxFragment();
- if (!child_fragment)
- return kDontSkipChildren;
-
- DCHECK(!child_fragment->IsHiddenForPaint());
- if (child_fragment->HasSelfPaintingLayer() || child_fragment->IsFloating())
- return kSkipChildren;
+ DCHECK_EQ(&item, cursor.Current().Item());
+ DCHECK_EQ(item.BoxFragment(), &child_fragment);
+ DCHECK(!child_fragment.IsHiddenForPaint());
+ if (child_fragment.HasSelfPaintingLayer() || child_fragment.IsFloating())
+ return;
// TODO(kojii): Check CullRect.
- if (child_fragment->IsAtomicInline() || child_fragment->IsListMarker()) {
- if (FragmentRequiresLegacyFallback(*child_fragment)) {
- PaintInlineChildBoxUsingLegacyFallback(*child_fragment, paint_info);
- return kDontSkipChildren;
+ if (child_fragment.IsAtomicInline() || child_fragment.IsListMarker()) {
+ if (FragmentRequiresLegacyFallback(child_fragment)) {
+ PaintInlineChildBoxUsingLegacyFallback(child_fragment, paint_info);
+ return;
}
- NGBoxFragmentPainter(*child_fragment).PaintAllPhasesAtomically(paint_info);
- return kDontSkipChildren;
+ NGBoxFragmentPainter(child_fragment).PaintAllPhasesAtomically(paint_info);
+ return;
}
- NGInlineBoxFragmentPainter(item, *child_fragment)
+ DCHECK(child_fragment.IsInlineBox());
+ NGInlineBoxFragmentPainter(cursor, item, child_fragment)
.Paint(paint_info, paint_offset);
- return kDontSkipChildren;
}
-void NGBoxFragmentPainter::PaintAtomicInline(const PaintInfo& paint_info) {
- DCHECK(PhysicalFragment().IsAtomicInline());
- // Self-painting AtomicInlines should go to normal paint logic.
- DCHECK(!box_fragment_.HasSelfPaintingLayer());
+void NGBoxFragmentPainter::PaintBoxItem(const NGFragmentItem& item,
+ const NGInlineCursor& cursor,
+ const PaintInfo& paint_info,
+ const PhysicalOffset& paint_offset,
+ const PhysicalOffset& parent_offset) {
+ DCHECK_EQ(item.Type(), NGFragmentItem::kBox);
+ DCHECK_EQ(&item, cursor.Current().Item());
- // Text clips are painted only for the direct inline children of the object
- // that has a text clip style on it, not block children.
- if (paint_info.phase == PaintPhase::kTextClip)
+ if (const NGPhysicalBoxFragment* child_fragment = item.BoxFragment()) {
+ PaintBoxItem(item, *child_fragment, cursor, paint_info, paint_offset);
return;
+ }
- PaintAllPhasesAtomically(paint_info);
+ // This |item| is a culled inline box.
+ DCHECK(item.GetLayoutObject()->IsLayoutInline());
+ NGInlineCursor children = cursor.CursorForDescendants();
+ // Pass the given |parent_offset| because culled inline boxes do not affect
+ // the sub-pixel snapping behavior. TODO(kojii): This is for the
+ // compatibility, we may want to revisit in future.
+ PaintInlineItems(paint_info, paint_offset, parent_offset, &children);
}
bool NGBoxFragmentPainter::IsPaintingScrollingBackground(
- const PaintInfo& paint_info) {
+ const PaintInfo& paint_info) const {
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return paint_info.IsPaintingScrollingBackground();
@@ -1361,27 +1530,43 @@ void NGBoxFragmentPainter::PaintTextClipMask(GraphicsContext& context,
bool object_has_multiple_boxes) {
PaintInfo paint_info(context, mask_rect, PaintPhase::kTextClip,
kGlobalPaintNormalPhase, 0);
- if (object_has_multiple_boxes) {
- DCHECK(paint_fragment_);
- PhysicalOffset local_offset = paint_fragment_->Offset();
- DCHECK(paint_fragment_);
- NGInlineBoxFragmentPainter inline_box_painter(*paint_fragment_);
- if (box_fragment_.Style().BoxDecorationBreak() ==
- EBoxDecorationBreak::kSlice) {
- LayoutUnit offset_on_line;
- LayoutUnit total_width;
- inline_box_painter.ComputeFragmentOffsetOnLine(
- box_fragment_.Style().Direction(), &offset_on_line, &total_width);
- LayoutSize line_offset(offset_on_line, LayoutUnit());
- local_offset -=
- PhysicalOffset(box_fragment_.Style().IsHorizontalWritingMode()
- ? line_offset
- : line_offset.TransposedSize());
- }
- inline_box_painter.Paint(paint_info, paint_offset - local_offset);
- } else {
+ if (!object_has_multiple_boxes) {
PaintObject(paint_info, paint_offset);
+ return;
}
+
+ if (paint_fragment_) {
+ NGInlineBoxFragmentPainter inline_box_painter(*paint_fragment_);
+ PaintTextClipMask(paint_info, paint_offset - paint_fragment_->Offset(),
+ &inline_box_painter);
+ return;
+ }
+
+ DCHECK(inline_box_cursor_);
+ DCHECK(box_item_);
+ NGInlineBoxFragmentPainter inline_box_painter(*inline_box_cursor_,
+ *box_item_);
+ PaintTextClipMask(paint_info,
+ paint_offset - box_item_->OffsetInContainerBlock(),
+ &inline_box_painter);
+}
+
+void NGBoxFragmentPainter::PaintTextClipMask(
+ const PaintInfo& paint_info,
+ PhysicalOffset paint_offset,
+ NGInlineBoxFragmentPainter* inline_box_painter) {
+ const ComputedStyle& style = box_fragment_.Style();
+ if (style.BoxDecorationBreak() == EBoxDecorationBreak::kSlice) {
+ LayoutUnit offset_on_line;
+ LayoutUnit total_width;
+ inline_box_painter->ComputeFragmentOffsetOnLine(
+ style.Direction(), &offset_on_line, &total_width);
+ if (style.IsHorizontalWritingMode())
+ paint_offset.left += offset_on_line;
+ else
+ paint_offset.top += offset_on_line;
+ }
+ inline_box_painter->Paint(paint_info, paint_offset);
}
PhysicalRect NGBoxFragmentPainter::AdjustRectForScrolledContent(
@@ -1421,219 +1606,249 @@ LayoutRectOutsets NGBoxFragmentPainter::ComputePadding() const {
BoxPainterBase::FillLayerInfo NGBoxFragmentPainter::GetFillLayerInfo(
const Color& color,
const FillLayer& bg_layer,
- BackgroundBleedAvoidance bleed_avoidance) const {
+ BackgroundBleedAvoidance bleed_avoidance,
+ bool is_painting_scrolling_background) const {
const NGBorderEdges& border_edges = BorderEdges();
const NGPhysicalBoxFragment& fragment = PhysicalFragment();
return BoxPainterBase::FillLayerInfo(
fragment.GetLayoutObject()->GetDocument(), fragment.Style(),
fragment.HasOverflowClip(), color, bg_layer, bleed_avoidance,
+ LayoutObject::ShouldRespectImageOrientation(fragment.GetLayoutObject()),
border_edges.line_left, border_edges.line_right,
- fragment.GetLayoutObject()->IsInline());
+ fragment.GetLayoutObject()->IsLayoutInline(),
+ is_painting_scrolling_background);
+}
+
+bool NGBoxFragmentPainter::HitTestContext::AddNodeToResult(
+ Node* node,
+ const PhysicalRect& bounds_rect,
+ const PhysicalOffset& offset) const {
+ if (node && !result->InnerNode())
+ result->SetNodeAndPosition(node, location.Point() - offset);
+ return result->AddNodeToListBasedTestResult(node, location, bounds_rect) ==
+ kStopHitTesting;
}
-bool NGBoxFragmentPainter::IsInSelfHitTestingPhase(HitTestAction action) const {
- // TODO(layout-dev): We should set an IsContainingBlock flag on
- // NGPhysicalBoxFragment, instead of routing back to LayoutObject.
- if (const auto* box = ToLayoutBoxOrNull(PhysicalFragment().GetLayoutObject()))
- return box->IsInSelfHitTestingPhase(action);
- return action == kHitTestForeground;
+bool NGBoxFragmentPainter::NodeAtPoint(HitTestResult& result,
+ const HitTestLocation& hit_test_location,
+ const PhysicalOffset& physical_offset,
+ HitTestAction action) {
+ HitTestContext hit_test(action, hit_test_location, physical_offset, &result);
+ return NodeAtPoint(hit_test, physical_offset);
}
bool NGBoxFragmentPainter::NodeAtPoint(HitTestResult& result,
const HitTestLocation& hit_test_location,
const PhysicalOffset& physical_offset,
+ const PhysicalOffset& inline_root_offset,
HitTestAction action) {
+ HitTestContext hit_test(action, hit_test_location, inline_root_offset,
+ &result);
+ return NodeAtPoint(hit_test, physical_offset);
+}
+
+bool NGBoxFragmentPainter::NodeAtPoint(const HitTestContext& hit_test,
+ const PhysicalOffset& physical_offset) {
const NGPhysicalBoxFragment& fragment = PhysicalFragment();
const PhysicalSize& size = box_fragment_.Size();
const ComputedStyle& style = box_fragment_.Style();
- bool hit_test_self = IsInSelfHitTestingPhase(action);
+ bool hit_test_self = fragment.IsInSelfHitTestingPhase(hit_test.action);
- // TODO(layout-dev): Add support for hit testing overflow controls once we
- // overflow has been implemented.
- // if (hit_test_self && HasOverflowClip() &&
- // HitTestOverflowControl(result, hit_test_location, physical_offset))
- // return true;
+ if (hit_test_self && box_fragment_.HasOverflowClip() &&
+ HitTestOverflowControl(hit_test, physical_offset))
+ return true;
- bool skip_children = result.GetHitTestRequest().GetStopNode() ==
- PhysicalFragment().GetLayoutObject();
+ const LayoutObject* layout_object = PhysicalFragment().GetLayoutObject();
+ bool skip_children =
+ layout_object &&
+ layout_object == hit_test.result->GetHitTestRequest().GetStopNode();
if (!skip_children && box_fragment_.ShouldClipOverflow()) {
// PaintLayer::HitTestContentsForFragments checked the fragments'
// foreground rect for intersection if a layer is self painting,
// so only do the overflow clip check here for non-self-painting layers.
if (!box_fragment_.HasSelfPaintingLayer() &&
- !hit_test_location.Intersects(PhysicalFragment().OverflowClipRect(
+ !hit_test.location.Intersects(PhysicalFragment().OverflowClipRect(
physical_offset, kExcludeOverlayScrollbarSizeForHitTesting))) {
skip_children = true;
}
if (!skip_children && style.HasBorderRadius()) {
PhysicalRect bounds_rect(physical_offset, size);
- skip_children = !hit_test_location.Intersects(
+ skip_children = !hit_test.location.Intersects(
style.GetRoundedInnerBorderFor(bounds_rect.ToLayoutRect()));
}
}
if (!skip_children) {
- PhysicalOffset scrolled_offset = physical_offset;
- if (box_fragment_.HasOverflowClip()) {
- scrolled_offset -= PhysicalOffset(
- PhysicalFragment().PixelSnappedScrolledContentOffset());
+ if (!box_fragment_.HasOverflowClip()) {
+ if (HitTestChildren(hit_test, physical_offset))
+ return true;
+ } else {
+ const PhysicalOffset scrolled_offset =
+ physical_offset -
+ PhysicalOffset(
+ PhysicalFragment().PixelSnappedScrolledContentOffset());
+ HitTestContext adjusted_hit_test(hit_test.action, hit_test.location,
+ scrolled_offset, hit_test.result);
+ if (HitTestChildren(adjusted_hit_test, scrolled_offset))
+ return true;
}
- if (HitTestChildren(result, hit_test_location, scrolled_offset, action))
- return true;
}
if (style.HasBorderRadius() &&
- HitTestClippedOutByBorder(hit_test_location, physical_offset))
+ HitTestClippedOutByBorder(hit_test.location, physical_offset))
return false;
// Now hit test ourselves.
- if (hit_test_self && VisibleToHitTestRequest(result.GetHitTestRequest())) {
+ if (hit_test_self &&
+ VisibleToHitTestRequest(hit_test.result->GetHitTestRequest())) {
PhysicalRect bounds_rect(physical_offset, size);
- if (UNLIKELY(result.GetHitTestRequest().GetType() &
+ if (UNLIKELY(hit_test.result->GetHitTestRequest().GetType() &
HitTestRequest::kHitTestVisualOverflow)) {
- bounds_rect = paint_fragment_->SelfInkOverflow();
+ bounds_rect = SelfInkOverflow();
bounds_rect.Move(physical_offset);
}
// TODO(kojii): Don't have good explanation why only inline box needs to
// snap, but matches to legacy and fixes crbug.com/976606.
if (fragment.IsInlineBox())
bounds_rect = PhysicalRect(PixelSnappedIntRect(bounds_rect));
- if (hit_test_location.Intersects(bounds_rect)) {
- Node* node = fragment.NodeForHitTest();
- if (!result.InnerNode() && node) {
- PhysicalOffset point = hit_test_location.Point() - physical_offset;
- result.SetNodeAndPosition(node, point);
- }
- if (result.AddNodeToListBasedTestResult(node, hit_test_location,
- bounds_rect) == kStopHitTesting) {
+ if (hit_test.location.Intersects(bounds_rect)) {
+ if (hit_test.AddNodeToResult(fragment.NodeForHitTest(), bounds_rect,
+ physical_offset))
return true;
- }
}
}
return false;
}
+bool NGBoxFragmentPainter::HitTestAllPhases(
+ HitTestResult& result,
+ const HitTestLocation& hit_test_location,
+ const PhysicalOffset& accumulated_offset,
+ HitTestFilter hit_test_filter) {
+ // Logic taken from LayoutObject::HitTestAllPhases().
+ HitTestContext hit_test(kHitTestForeground, hit_test_location,
+ accumulated_offset, &result);
+ bool inside = false;
+ if (hit_test_filter != kHitTestSelf) {
+ // First test the foreground layer (lines and inlines).
+ inside = NodeAtPoint(hit_test, accumulated_offset);
+
+ // Test floats next.
+ if (!inside) {
+ hit_test.action = kHitTestFloat;
+ inside = NodeAtPoint(hit_test, accumulated_offset);
+ }
+
+ // Finally test to see if the mouse is in the background (within a child
+ // block's background).
+ if (!inside) {
+ hit_test.action = kHitTestChildBlockBackgrounds;
+ inside = NodeAtPoint(hit_test, accumulated_offset);
+ }
+ }
+
+ // See if the pointer is inside us but not any of our descendants.
+ if (hit_test_filter != kHitTestDescendants && !inside) {
+ hit_test.action = kHitTestChildBlockBackground;
+ inside = NodeAtPoint(hit_test, accumulated_offset);
+ }
+
+ return inside;
+}
+
bool NGBoxFragmentPainter::VisibleToHitTestRequest(
const HitTestRequest& request) const {
return FragmentVisibleToHitTestRequest(box_fragment_, request);
}
bool NGBoxFragmentPainter::HitTestTextFragment(
- HitTestResult& result,
+ const HitTestContext& hit_test,
const NGInlineBackwardCursor& cursor,
- const HitTestLocation& hit_test_location,
- const PhysicalOffset& physical_offset,
- HitTestAction action) {
- if (action != kHitTestForeground)
+ const PhysicalOffset& physical_offset) {
+ if (hit_test.action != kHitTestForeground)
return false;
- const NGPaintFragment* text_paint_fragment = cursor.CurrentPaintFragment();
+ const NGPaintFragment* text_paint_fragment = cursor.Current().PaintFragment();
DCHECK(text_paint_fragment);
const auto& text_fragment =
To<NGPhysicalTextFragment>(text_paint_fragment->PhysicalFragment());
- PhysicalRect border_rect(physical_offset, text_fragment.Size());
+ if (!FragmentVisibleToHitTestRequest(text_fragment,
+ hit_test.result->GetHitTestRequest()))
+ return false;
// TODO(layout-dev): Clip to line-top/bottom.
+ PhysicalRect border_rect(physical_offset, text_fragment.Size());
PhysicalRect rect(PixelSnappedIntRect(border_rect));
- if (UNLIKELY(result.GetHitTestRequest().GetType() &
+ if (UNLIKELY(hit_test.result->GetHitTestRequest().GetType() &
HitTestRequest::kHitTestVisualOverflow)) {
rect = text_fragment.SelfInkOverflow();
rect.Move(border_rect.offset);
}
+ if (!hit_test.location.Intersects(rect))
+ return false;
- if (FragmentVisibleToHitTestRequest(text_fragment,
- result.GetHitTestRequest()) &&
- hit_test_location.Intersects(rect)) {
- Node* node = text_fragment.NodeForHitTest();
- if (!result.InnerNode() && node) {
- PhysicalOffset point = hit_test_location.Point() - physical_offset +
- text_paint_fragment->InlineOffsetToContainerBox();
- result.SetNodeAndPosition(node, point);
- }
-
- if (result.AddNodeToListBasedTestResult(node, hit_test_location, rect) ==
- kStopHitTesting) {
- return true;
- }
- }
-
- return false;
+ return hit_test.AddNodeToResult(
+ text_fragment.NodeForHitTest(), rect,
+ physical_offset - text_paint_fragment->OffsetInContainerBlock());
}
-bool NGBoxFragmentPainter::HitTestTextItem(
- HitTestResult& result,
- const NGFragmentItem& text_item,
- const HitTestLocation& hit_test_location,
- const PhysicalOffset& physical_offset,
- HitTestAction action) {
+bool NGBoxFragmentPainter::HitTestTextItem(const HitTestContext& hit_test,
+ const NGFragmentItem& text_item) {
DCHECK(text_item.IsText());
- if (action != kHitTestForeground)
+ if (hit_test.action != kHitTestForeground)
+ return false;
+ if (!IsVisibleToHitTest(text_item, hit_test.result->GetHitTestRequest()))
return false;
-
- PhysicalRect border_rect(physical_offset, text_item.Size());
// TODO(layout-dev): Clip to line-top/bottom.
+ const PhysicalOffset offset =
+ hit_test.inline_root_offset + text_item.OffsetInContainerBlock();
+ PhysicalRect border_rect(offset, text_item.Size());
PhysicalRect rect(PixelSnappedIntRect(border_rect));
- if (UNLIKELY(result.GetHitTestRequest().GetType() &
+ if (UNLIKELY(hit_test.result->GetHitTestRequest().GetType() &
HitTestRequest::kHitTestVisualOverflow)) {
rect = text_item.SelfInkOverflow();
rect.Move(border_rect.offset);
}
+ if (!hit_test.location.Intersects(rect))
+ return false;
- if (IsVisibleToHitTest(text_item, result.GetHitTestRequest()) &&
- hit_test_location.Intersects(rect)) {
- Node* node = text_item.NodeForHitTest();
- if (!result.InnerNode() && node) {
- PhysicalOffset point =
- hit_test_location.Point() - physical_offset + text_item.Offset();
- result.SetNodeAndPosition(node, point);
- }
-
- if (result.AddNodeToListBasedTestResult(node, hit_test_location, rect) ==
- kStopHitTesting) {
- return true;
- }
- }
-
- return false;
+ return hit_test.AddNodeToResult(text_item.NodeForHitTest(), rect,
+ hit_test.inline_root_offset);
}
// Replicates logic in legacy InlineFlowBox::NodeAtPoint().
bool NGBoxFragmentPainter::HitTestLineBoxFragment(
- HitTestResult& result,
+ const HitTestContext& hit_test,
const NGPhysicalLineBoxFragment& fragment,
const NGInlineBackwardCursor& cursor,
- const HitTestLocation& hit_test_location,
- const PhysicalOffset& physical_offset,
- HitTestAction action) {
- if (HitTestChildren(result, cursor.CursorForDescendants(), hit_test_location,
- physical_offset, action))
+ const PhysicalOffset& physical_offset) {
+ if (HitTestChildren(hit_test, cursor.CursorForDescendants(), physical_offset))
return true;
- if (action != kHitTestForeground)
+ if (hit_test.action != kHitTestForeground)
return false;
- if (!VisibleToHitTestRequest(result.GetHitTestRequest()))
+ if (!VisibleToHitTestRequest(hit_test.result->GetHitTestRequest()))
return false;
const PhysicalOffset overflow_location =
- cursor.CurrentSelfInkOverflow().offset + physical_offset;
- if (HitTestClippedOutByBorder(hit_test_location, overflow_location))
+ cursor.Current().SelfInkOverflow().offset + physical_offset;
+ if (HitTestClippedOutByBorder(hit_test.location, overflow_location))
return false;
const PhysicalRect bounds_rect(physical_offset, fragment.Size());
const ComputedStyle& containing_box_style = box_fragment_.Style();
if (containing_box_style.HasBorderRadius() &&
- !hit_test_location.Intersects(containing_box_style.GetRoundedBorderFor(
- bounds_rect.ToLayoutRect()))) {
+ !hit_test.location.Intersects(
+ containing_box_style.GetRoundedBorderFor(bounds_rect.ToLayoutRect())))
return false;
- }
// Now hit test ourselves.
- if (!hit_test_location.Intersects(bounds_rect))
+ if (!hit_test.location.Intersects(bounds_rect))
return false;
// Floats will be hit-tested in |kHitTestFloat| phase, but
@@ -1643,123 +1858,207 @@ bool NGBoxFragmentPainter::HitTestLineBoxFragment(
// restructuring. Changing the caller logic isn't easy because currently
// floats are in the bounds of line boxes only in NG.
if (fragment.HasFloatingDescendantsForPaint()) {
- DCHECK_NE(action, kHitTestFloat);
- if (HitTestChildren(result, cursor.CursorForDescendants(),
- hit_test_location, physical_offset, kHitTestFloat)) {
+ DCHECK_NE(hit_test.action, kHitTestFloat);
+ HitTestContext hit_test_float = hit_test;
+ hit_test_float.action = kHitTestFloat;
+ if (HitTestChildren(hit_test_float, cursor.CursorForDescendants(),
+ physical_offset))
return false;
- }
}
- Node* node = fragment.NodeForHitTest();
- if (!result.InnerNode() && node) {
- const PhysicalOffset point =
- hit_test_location.Point() - physical_offset + cursor.CurrentOffset();
- result.SetNodeAndPosition(node, point);
- }
- return result.AddNodeToListBasedTestResult(node, hit_test_location,
- bounds_rect) == kStopHitTesting;
+ return hit_test.AddNodeToResult(
+ fragment.NodeForHitTest(), bounds_rect,
+ physical_offset - cursor.Current().OffsetInContainerBlock());
}
bool NGBoxFragmentPainter::HitTestChildBoxFragment(
- HitTestResult& result,
+ const HitTestContext& hit_test,
const NGPhysicalBoxFragment& fragment,
- const NGInlineBackwardCursor& cursor,
- const HitTestLocation& hit_test_location,
- const PhysicalOffset& physical_offset,
- HitTestAction action) {
+ const NGInlineBackwardCursor& backward_cursor,
+ const PhysicalOffset& physical_offset) {
// Note: Floats should only be hit tested in the |kHitTestFloat| phase, so we
// shouldn't enter a float when |action| doesn't match. However, as floats may
// scatter around in the entire inline formatting context, we should always
// enter non-floating inline child boxes to search for floats in the
// |kHitTestFloat| phase, unless the child box forms another context.
- if (fragment.IsFloating() && action != kHitTestFloat)
+ if (fragment.IsFloating() && hit_test.action != kHitTestFloat)
return false;
if (!FragmentRequiresLegacyFallback(fragment)) {
- // TODO(layout-dev): Implement HitTestAllPhases in NG after we stop
- // falling back to legacy for child atomic inlines and floats.
DCHECK(!fragment.IsAtomicInline());
DCHECK(!fragment.IsFloating());
- if (const NGPaintFragment* paint_fragment = cursor.CurrentPaintFragment()) {
+ if (const NGPaintFragment* paint_fragment =
+ backward_cursor.Current().PaintFragment()) {
+ if (fragment.IsInlineBox()) {
+ return NGBoxFragmentPainter(*paint_fragment)
+ .NodeAtPoint(hit_test, physical_offset);
+ }
+ // When traversing into a different inline formatting context,
+ // |inline_root_offset| needs to be updated.
return NGBoxFragmentPainter(*paint_fragment)
- .NodeAtPoint(result, hit_test_location, physical_offset, action);
+ .NodeAtPoint(*hit_test.result, hit_test.location, physical_offset,
+ hit_test.action);
}
- const NGFragmentItem* item = cursor.CurrentItem();
+ NGInlineCursor cursor(backward_cursor);
+ const NGFragmentItem* item = cursor.Current().Item();
DCHECK(item);
DCHECK_EQ(item->BoxFragment(), &fragment);
- NGInlineCursor descendants = cursor.CursorForDescendants();
- return NGBoxFragmentPainter(*item, fragment, &descendants)
- .NodeAtPoint(result, hit_test_location, physical_offset, action);
+ if (fragment.IsInlineBox()) {
+ return NGBoxFragmentPainter(cursor, *item, fragment)
+ .NodeAtPoint(hit_test, physical_offset);
+ }
+ // When traversing into a different inline formatting context,
+ // |inline_root_offset| needs to be updated.
+ return NGBoxFragmentPainter(cursor, *item, fragment)
+ .NodeAtPoint(*hit_test.result, hit_test.location, physical_offset,
+ hit_test.action);
}
- if (fragment.IsInline() && action != kHitTestForeground)
+ if (fragment.IsInline() && hit_test.action != kHitTestForeground)
return false;
- LayoutBox* const layout_box = ToLayoutBox(fragment.GetMutableLayoutObject());
+ if (fragment.IsPaintedAtomically()) {
+ return HitTestAllPhasesInFragment(fragment, hit_test.location,
+ physical_offset, hit_test.result);
+ }
- // https://www.w3.org/TR/CSS22/zindex.html#painting-order
- // Hit test all phases of inline blocks, inline tables, replaced elements and
- // non-positioned floats as if they created their own stacking contexts.
- if (fragment.IsAtomicInline() || fragment.IsFloating()) {
- return layout_box->HitTestAllPhases(result, hit_test_location,
- physical_offset);
+ return fragment.GetMutableLayoutObject()->NodeAtPoint(
+ *hit_test.result, hit_test.location, physical_offset, hit_test.action);
+}
+
+bool NGBoxFragmentPainter::HitTestChildBoxItem(
+ const HitTestContext& hit_test,
+ const NGFragmentItem& item,
+ const NGInlineBackwardCursor& cursor) {
+ DCHECK_EQ(&item, cursor.Current().Item());
+
+ if (const NGPhysicalBoxFragment* child_fragment = item.BoxFragment()) {
+ const PhysicalOffset child_offset =
+ hit_test.inline_root_offset + item.OffsetInContainerBlock();
+ return HitTestChildBoxFragment(hit_test, *child_fragment, cursor,
+ child_offset);
+ }
+
+ DCHECK(item.GetLayoutObject()->IsLayoutInline());
+ DCHECK(!ToLayoutInline(item.GetLayoutObject())->ShouldCreateBoxFragment());
+ if (NGInlineCursor descendants = cursor.CursorForDescendants()) {
+ if (HitTestItemsChildren(hit_test, descendants))
+ return true;
}
- return layout_box->NodeAtPoint(result, hit_test_location, physical_offset,
- action);
+
+ // Now hit test ourselves.
+ if (hit_test.action == kHitTestForeground &&
+ IsVisibleToHitTest(item, hit_test.result->GetHitTestRequest())) {
+ const PhysicalOffset child_offset =
+ hit_test.inline_root_offset + item.OffsetInContainerBlock();
+ PhysicalRect bounds_rect(child_offset, item.Size());
+ if (UNLIKELY(hit_test.result->GetHitTestRequest().GetType() &
+ HitTestRequest::kHitTestVisualOverflow)) {
+ bounds_rect = item.SelfInkOverflow();
+ bounds_rect.Move(child_offset);
+ }
+ // TODO(kojii): Don't have good explanation why only inline box needs to
+ // snap, but matches to legacy and fixes crbug.com/976606.
+ bounds_rect = PhysicalRect(PixelSnappedIntRect(bounds_rect));
+ if (hit_test.location.Intersects(bounds_rect)) {
+ if (hit_test.AddNodeToResult(item.NodeForHitTest(), bounds_rect,
+ child_offset))
+ return true;
+ }
+ }
+
+ return false;
}
bool NGBoxFragmentPainter::HitTestChildren(
- HitTestResult& result,
- const HitTestLocation& hit_test_location,
- const PhysicalOffset& accumulated_offset,
- HitTestAction action) {
+ const HitTestContext& hit_test,
+ const PhysicalOffset& accumulated_offset) {
if (paint_fragment_) {
NGInlineCursor cursor(*paint_fragment_);
- return HitTestChildren(result, cursor, hit_test_location,
- accumulated_offset, action);
+ return HitTestChildren(hit_test, cursor, accumulated_offset);
}
- if (UNLIKELY(descendants_)) {
- if (!*descendants_)
- return false;
- return HitTestChildren(result, *descendants_, hit_test_location,
- accumulated_offset, action);
+ if (UNLIKELY(inline_box_cursor_)) {
+ NGInlineCursor descendants = inline_box_cursor_->CursorForDescendants();
+ if (descendants)
+ return HitTestChildren(hit_test, descendants, accumulated_offset);
+ return false;
}
if (items_) {
NGInlineCursor cursor(*items_);
- return HitTestChildren(result, cursor, hit_test_location,
- accumulated_offset, action);
+ return HitTestChildren(hit_test, cursor, accumulated_offset);
}
- NOTREACHED();
- return false;
+ // Check descendants of this fragment because floats may be in the
+ // |NGFragmentItems| of the descendants.
+ if (hit_test.action == kHitTestFloat &&
+ box_fragment_.HasFloatingDescendantsForPaint() &&
+ RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ return HitTestFloatingChildren(hit_test, box_fragment_, accumulated_offset);
+ }
+
+ if (hit_test.action == kHitTestFloat) {
+ return box_fragment_.HasFloatingDescendantsForPaint() &&
+ HitTestFloatingChildren(hit_test, box_fragment_, accumulated_offset);
+ }
+ return HitTestBlockChildren(*hit_test.result, hit_test.location,
+ accumulated_offset, hit_test.action);
}
bool NGBoxFragmentPainter::HitTestChildren(
- HitTestResult& result,
+ const HitTestContext& hit_test,
const NGInlineCursor& children,
+ const PhysicalOffset& accumulated_offset) {
+ if (children.IsPaintFragmentCursor())
+ return HitTestPaintFragmentChildren(hit_test, children, accumulated_offset);
+ if (children.IsItemCursor())
+ return HitTestItemsChildren(hit_test, children);
+ // Hits nothing if there were no children.
+ return false;
+}
+
+bool NGBoxFragmentPainter::HitTestBlockChildren(
+ HitTestResult& result,
const HitTestLocation& hit_test_location,
- const PhysicalOffset& accumulated_offset,
+ PhysicalOffset accumulated_offset,
HitTestAction action) {
- if (children.IsPaintFragmentCursor()) {
- return HitTestPaintFragmentChildren(result, children, hit_test_location,
- accumulated_offset, action);
- }
- if (children.IsItemCursor()) {
- return HitTestItemsChildren(result, children, hit_test_location,
- accumulated_offset, action);
+ if (action == kHitTestChildBlockBackgrounds)
+ action = kHitTestChildBlockBackground;
+ auto children = box_fragment_.Children();
+ for (const NGLink& child : base::Reversed(children)) {
+ const auto& block_child = To<NGPhysicalBoxFragment>(*child);
+ if (block_child.HasSelfPaintingLayer() || block_child.IsFloating())
+ continue;
+
+ const PhysicalOffset child_offset = accumulated_offset + child.offset;
+
+ if (block_child.IsPaintedAtomically()) {
+ if (HitTestAllPhasesInFragment(block_child, hit_test_location,
+ child_offset, &result))
+ return true;
+
+ continue;
+ }
+
+ if (NodeAtPointInFragment(block_child, hit_test_location, child_offset,
+ action, &result)) {
+ if (const LayoutObject* child_object = block_child.GetLayoutObject()) {
+ child_object->UpdateHitTestResult(
+ result, hit_test_location.Point() - accumulated_offset);
+ }
+ return true;
+ }
}
- // Hits nothing if there were no children.
+
return false;
}
bool NGBoxFragmentPainter::HitTestPaintFragmentChildren(
- HitTestResult& result,
+ const HitTestContext& hit_test,
const NGInlineCursor& children,
- const HitTestLocation& hit_test_location,
- const PhysicalOffset& accumulated_offset,
- HitTestAction action) {
+ const PhysicalOffset& accumulated_offset) {
DCHECK(children.IsPaintFragmentCursor());
for (NGInlineBackwardCursor cursor(children); cursor;) {
- const NGPaintFragment* child_paint_fragment = cursor.CurrentPaintFragment();
+ const NGPaintFragment* child_paint_fragment =
+ cursor.Current().PaintFragment();
DCHECK(child_paint_fragment);
const NGPhysicalFragment& child_fragment =
child_paint_fragment->PhysicalFragment();
@@ -1771,30 +2070,29 @@ bool NGBoxFragmentPainter::HitTestPaintFragmentChildren(
const PhysicalOffset child_offset =
child_paint_fragment->Offset() + accumulated_offset;
if (child_fragment.Type() == NGPhysicalFragment::kFragmentBox) {
- if (HitTestChildBoxFragment(
- result, To<NGPhysicalBoxFragment>(child_fragment), cursor,
- hit_test_location, child_offset, action))
+ if (HitTestChildBoxFragment(hit_test,
+ To<NGPhysicalBoxFragment>(child_fragment),
+ cursor, child_offset))
return true;
} else if (child_fragment.Type() == NGPhysicalFragment::kFragmentLineBox) {
- if (HitTestLineBoxFragment(
- result, To<NGPhysicalLineBoxFragment>(child_fragment), cursor,
- hit_test_location, child_offset, action))
+ if (HitTestLineBoxFragment(hit_test,
+ To<NGPhysicalLineBoxFragment>(child_fragment),
+ cursor, child_offset))
return true;
} else if (child_fragment.Type() == NGPhysicalFragment::kFragmentText) {
- if (HitTestTextFragment(result, cursor, hit_test_location, child_offset,
- action))
+ if (HitTestTextFragment(hit_test, cursor, child_offset))
return true;
}
cursor.MoveToPreviousSibling();
- if (child_fragment.IsInline() && action == kHitTestForeground) {
+ if (child_fragment.IsInline() && hit_test.action == kHitTestForeground) {
// Hit test culled inline boxes between |fragment| and its parent
// fragment.
const NGPaintFragment* previous_sibling =
- cursor ? cursor.CurrentPaintFragment() : nullptr;
- if (HitTestCulledInlineAncestors(result, *child_paint_fragment,
- previous_sibling, hit_test_location,
+ cursor ? cursor.Current().PaintFragment() : nullptr;
+ if (HitTestCulledInlineAncestors(*hit_test.result, *child_paint_fragment,
+ previous_sibling, hit_test.location,
child_offset))
return true;
}
@@ -1804,44 +2102,142 @@ bool NGBoxFragmentPainter::HitTestPaintFragmentChildren(
}
bool NGBoxFragmentPainter::HitTestItemsChildren(
- HitTestResult& result,
- const NGInlineCursor& children,
- const HitTestLocation& hit_test_location,
- const PhysicalOffset& accumulated_offset,
- HitTestAction action) {
+ const HitTestContext& hit_test,
+ const NGInlineCursor& children) {
DCHECK(children.IsItemCursor());
for (NGInlineBackwardCursor cursor(children); cursor;) {
- const NGFragmentItem* item = cursor.CurrentItem();
+ const NGFragmentItem* item = cursor.Current().Item();
DCHECK(item);
if (item->HasSelfPaintingLayer()) {
cursor.MoveToPreviousSibling();
continue;
}
- const PhysicalOffset child_offset = item->Offset() + accumulated_offset;
if (item->IsText()) {
- if (HitTestTextItem(result, *item, hit_test_location, child_offset,
- action))
+ if (HitTestTextItem(hit_test, *item))
return true;
} else if (item->Type() == NGFragmentItem::kLine) {
const NGPhysicalLineBoxFragment* child_fragment = item->LineBoxFragment();
DCHECK(child_fragment);
- if (HitTestLineBoxFragment(result, *child_fragment, cursor,
- hit_test_location, child_offset, action))
+ const PhysicalOffset child_offset =
+ hit_test.inline_root_offset + item->OffsetInContainerBlock();
+ if (HitTestLineBoxFragment(hit_test, *child_fragment, cursor,
+ child_offset))
return true;
} else if (item->Type() == NGFragmentItem::kBox) {
- if (const NGPhysicalBoxFragment* child_fragment = item->BoxFragment()) {
- if (HitTestChildBoxFragment(result, *child_fragment, cursor,
- hit_test_location, child_offset, action))
- return true;
- }
+ if (HitTestChildBoxItem(hit_test, *item, cursor))
+ return true;
} else {
NOTREACHED();
}
cursor.MoveToPreviousSibling();
+ }
+
+ return false;
+}
- // TODO(kojii): Implement hit-testing culled inline box.
+bool NGBoxFragmentPainter::HitTestFloatingChildren(
+ const HitTestContext& hit_test,
+ const NGPhysicalContainerFragment& container,
+ const PhysicalOffset& accumulated_offset) {
+ DCHECK_EQ(hit_test.action, kHitTestFloat);
+ DCHECK(container.HasFloatingDescendantsForPaint());
+
+ if (const auto* box = DynamicTo<NGPhysicalBoxFragment>(&container)) {
+ if (const NGFragmentItems* items = box->Items()) {
+ NGInlineCursor children(*items);
+ return HitTestFloatingChildItems(hit_test, children, accumulated_offset);
+ }
+ }
+
+ auto children = container.Children();
+ for (const NGLink& child : base::Reversed(children)) {
+ const NGPhysicalFragment& child_fragment = *child.fragment;
+ if (child_fragment.HasSelfPaintingLayer())
+ continue;
+
+ const PhysicalOffset child_offset = accumulated_offset + child.offset;
+
+ if (child_fragment.IsFloating()) {
+ if (HitTestAllPhasesInFragment(To<NGPhysicalBoxFragment>(child_fragment),
+ hit_test.location, child_offset,
+ hit_test.result))
+ return true;
+ continue;
+ }
+
+ if (child_fragment.IsPaintedAtomically())
+ continue;
+
+ const auto* child_container =
+ DynamicTo<NGPhysicalContainerFragment>(&child_fragment);
+ if (!child_container || !child_container->HasFloatingDescendantsForPaint())
+ continue;
+
+ if (child_container->HasOverflowClip()) {
+ // We need to properly visit this fragment for hit-testing, rather than
+ // jumping directly to its children (which is what we normally do when
+ // looking for floats), in order to set up the clip rectangle.
+ if (child_container->CanTraverse()) {
+ if (NGBoxFragmentPainter(*To<NGPhysicalBoxFragment>(child_container))
+ .NodeAtPoint(*hit_test.result, hit_test.location, child_offset,
+ kHitTestFloat))
+ return true;
+ } else if (child_fragment.GetMutableLayoutObject()->NodeAtPoint(
+ *hit_test.result, hit_test.location, child_offset,
+ kHitTestFloat)) {
+ return true;
+ }
+ continue;
+ }
+
+ if (HitTestFloatingChildren(hit_test, *child_container, child_offset))
+ return true;
+ }
+ return false;
+}
+
+bool NGBoxFragmentPainter::HitTestFloatingChildItems(
+ const HitTestContext& hit_test,
+ const NGInlineCursor& children,
+ const PhysicalOffset& accumulated_offset) {
+ for (NGInlineBackwardCursor cursor(children); cursor;
+ cursor.MoveToPreviousSibling()) {
+ const NGFragmentItem* item = cursor.Current().Item();
+ DCHECK(item);
+ if (item->Type() == NGFragmentItem::kBox) {
+ if (const NGPhysicalBoxFragment* child_box = item->BoxFragment()) {
+ if (child_box->HasSelfPaintingLayer())
+ continue;
+
+ const PhysicalOffset child_offset =
+ accumulated_offset + item->OffsetInContainerBlock();
+ if (child_box->IsFloating()) {
+ if (HitTestAllPhasesInFragment(*child_box, hit_test.location,
+ child_offset, hit_test.result))
+ return true;
+ continue;
+ }
+
+ // Look into descendants of all inline boxes because inline boxes do not
+ // have |HasFloatingDescendantsForPaint()| flag.
+ if (!child_box->IsInlineBox())
+ continue;
+ }
+ DCHECK(item->GetLayoutObject()->IsLayoutInline());
+ } else if (item->Type() == NGFragmentItem::kLine) {
+ const NGPhysicalLineBoxFragment* child_line = item->LineBoxFragment();
+ DCHECK(child_line);
+ if (!child_line->HasFloatingDescendantsForPaint())
+ continue;
+ } else {
+ continue;
+ }
+
+ NGInlineCursor descendants = cursor.CursorForDescendants();
+ if (HitTestFloatingChildItems(hit_test, descendants, accumulated_offset))
+ return true;
}
return false;
@@ -1858,4 +2254,13 @@ bool NGBoxFragmentPainter::HitTestClippedOutByBorder(
rect.ToLayoutRect(), border_edges.line_left, border_edges.line_right));
}
+bool NGBoxFragmentPainter::HitTestOverflowControl(
+ const HitTestContext& hit_test,
+ PhysicalOffset accumulated_offset) {
+ const auto* layout_box = ToLayoutBoxOrNull(box_fragment_.GetLayoutObject());
+ return layout_box &&
+ layout_box->HitTestOverflowControl(*hit_test.result, hit_test.location,
+ accumulated_offset);
+}
+
} // namespace blink
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 08fd0e73eda..5fe1f5fe9a1 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
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/layout/api/hit_test_action.h"
#include "third_party/blink/renderer/core/layout/background_bleed_avoidance.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_border_edges.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
#include "third_party/blink/renderer/core/paint/box_painter_base.h"
#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
@@ -24,6 +25,7 @@ class HitTestResult;
class NGFragmentItems;
class NGInlineCursor;
class NGInlineBackwardCursor;
+class NGInlineBoxFragmentPainter;
class NGPhysicalFragment;
class ScopedPaintState;
struct PaintInfo;
@@ -41,9 +43,9 @@ class NGBoxFragmentPainter : public BoxPainterBase {
// Construct for an inline formatting context.
NGBoxFragmentPainter(const NGPaintFragment&);
// Construct for an inline box.
- NGBoxFragmentPainter(const NGFragmentItem& item,
- const NGPhysicalBoxFragment& fragment,
- NGInlineCursor* descendants);
+ NGBoxFragmentPainter(const NGInlineCursor& inline_box_cursor,
+ const NGFragmentItem& item,
+ const NGPhysicalBoxFragment& fragment);
void Paint(const PaintInfo&);
void PaintObject(const PaintInfo&,
@@ -58,6 +60,16 @@ class NGBoxFragmentPainter : public BoxPainterBase {
const HitTestLocation& hit_test_location,
const PhysicalOffset& physical_offset,
HitTestAction);
+ bool NodeAtPoint(HitTestResult&,
+ const HitTestLocation& hit_test_location,
+ const PhysicalOffset& physical_offset,
+ const PhysicalOffset& inline_root_offset,
+ HitTestAction);
+
+ bool HitTestAllPhases(HitTestResult&,
+ const HitTestLocation&,
+ const PhysicalOffset& accumulated_offset,
+ HitTestFilter = kHitTestAll);
protected:
LayoutRectOutsets ComputeBorders() const override;
@@ -65,12 +77,17 @@ class NGBoxFragmentPainter : public BoxPainterBase {
BoxPainterBase::FillLayerInfo GetFillLayerInfo(
const Color&,
const FillLayer&,
- BackgroundBleedAvoidance) const override;
+ BackgroundBleedAvoidance,
+ bool is_painting_scrolling_background) const override;
+ bool IsPaintingScrollingBackground(const PaintInfo&) const override;
void PaintTextClipMask(GraphicsContext&,
const IntRect& mask_rect,
const PhysicalOffset& paint_offset,
bool object_has_multiple_boxes) override;
+ void PaintTextClipMask(const PaintInfo& paint_info,
+ PhysicalOffset paint_offset,
+ NGInlineBoxFragmentPainter* inline_box_painter);
PhysicalRect AdjustRectForScrolledContent(
const PaintInfo&,
const BoxPainterBase::FillLayerInfo&,
@@ -80,10 +97,10 @@ class NGBoxFragmentPainter : public BoxPainterBase {
NGBoxFragmentPainter(const NGPhysicalBoxFragment&,
const DisplayItemClient& display_item_client,
const NGPaintFragment* = nullptr,
- NGInlineCursor* descendants = nullptr);
+ const NGInlineCursor* inline_box_cursor = nullptr,
+ const NGFragmentItem* = nullptr);
enum MoveTo { kDontSkipChildren, kSkipChildren };
- bool IsPaintingScrollingBackground(const PaintInfo&);
bool ShouldPaint(const ScopedPaintState&) const;
void PaintBoxDecorationBackground(const PaintInfo&,
@@ -93,24 +110,27 @@ class NGBoxFragmentPainter : public BoxPainterBase {
const PhysicalRect&,
const DisplayItemClient&);
void PaintColumnRules(const PaintInfo&, const PhysicalOffset& paint_offset);
- bool BackgroundIsKnownToBeOpaque(const PaintInfo&);
void PaintInternal(const PaintInfo&);
void PaintAllPhasesAtomically(const PaintInfo&);
- void PaintBlockChildren(const PaintInfo&);
+ void PaintBlockChildren(const PaintInfo&, PhysicalOffset);
void PaintInlineItems(const PaintInfo&,
const PhysicalOffset& paint_offset,
+ const PhysicalOffset& parent_offset,
NGInlineCursor* cursor);
- void PaintLineBoxChildren(NGPaintFragment::ChildList,
+ void PaintLineBoxChildren(NGInlineCursor* children,
const PaintInfo&,
const PhysicalOffset& paint_offset);
+ void PaintLineBoxChildItems(NGInlineCursor* children,
+ const PaintInfo&,
+ const PhysicalOffset& paint_offset);
void PaintLineBox(const NGPhysicalFragment& line_box_fragment,
const DisplayItemClient& display_item_client,
const NGPaintFragment* line_box_paint_fragment,
const NGFragmentItem* line_box_item,
const PaintInfo&,
const PhysicalOffset& paint_offset);
- void PaintBackplate(NGPaintFragment::ChildList,
+ void PaintBackplate(NGInlineCursor* descendants,
const PaintInfo&,
const PhysicalOffset& paint_offset);
void PaintInlineChildren(NGPaintFragment::ChildList,
@@ -126,97 +146,128 @@ class NGBoxFragmentPainter : public BoxPainterBase {
const PhysicalOffset& paint_offset);
void PaintTextItem(const NGInlineCursor& cursor,
const PaintInfo&,
- const PhysicalOffset& paint_offset);
+ const PhysicalOffset& paint_offset,
+ const PhysicalOffset& parent_offset);
MoveTo PaintLineBoxItem(const NGFragmentItem& item,
const PaintInfo& paint_info,
const PhysicalOffset& paint_offset);
- MoveTo PaintBoxItem(const NGFragmentItem& item,
- const PaintInfo& paint_info,
- const PhysicalOffset& paint_offset);
+ void PaintBoxItem(const NGFragmentItem& item,
+ const NGPhysicalBoxFragment& child_fragment,
+ const NGInlineCursor& cursor,
+ const PaintInfo& paint_info,
+ const PhysicalOffset& paint_offset);
+ void PaintBoxItem(const NGFragmentItem& item,
+ const NGInlineCursor& cursor,
+ const PaintInfo& paint_info,
+ const PhysicalOffset& paint_offset,
+ const PhysicalOffset& parent_offset);
+ void PaintFloatingItems(const PaintInfo&, NGInlineCursor* cursor);
void PaintFloatingChildren(const NGPhysicalContainerFragment&,
const PaintInfo& paint_info,
const PaintInfo& float_paint_info);
void PaintFloats(const PaintInfo&);
void PaintMask(const PaintInfo&, const PhysicalOffset& paint_offset);
- void PaintAtomicInline(const PaintInfo&);
void PaintBackground(const PaintInfo&,
const PhysicalRect&,
const Color& background_color,
BackgroundBleedAvoidance = kBackgroundBleedNone);
void PaintCarets(const PaintInfo&, const PhysicalOffset& paint_offset);
- // Paint a scroll hit test display item and record scroll hit test data. This
- // should be called in the background paint phase even if there is no other
- // painted content.
+ // This should be called in the background paint phase even if there is no
+ // other painted content.
void RecordScrollHitTestData(const PaintInfo&,
const DisplayItemClient& background_client);
- void RecordHitTestDataForLine(const PaintInfo& paint_info,
- const PhysicalOffset& paint_offset,
- const NGPhysicalFragment& line,
- const DisplayItemClient& display_item_client);
+ bool ShouldRecordHitTestData(const PaintInfo&);
- bool IsInSelfHitTestingPhase(HitTestAction) const;
bool VisibleToHitTestRequest(const HitTestRequest&) const;
+ // This struct has common data needed while traversing trees for the hit
+ // testing.
+ struct HitTestContext {
+ STACK_ALLOCATED();
+
+ public:
+ HitTestContext(HitTestAction action,
+ const HitTestLocation& location,
+ const PhysicalOffset& inline_root_offset,
+ HitTestResult* result)
+ : action(action),
+ location(location),
+ inline_root_offset(inline_root_offset),
+ result(result) {}
+
+ // Add |node| to |HitTestResult|. Returns true if the hit-testing should
+ // stop.
+ bool AddNodeToResult(Node* node,
+ const PhysicalRect& bounds_rect,
+ const PhysicalOffset& offset) const;
+
+ HitTestAction action;
+ const HitTestLocation& location;
+ // When traversing within an inline formatting context, this member
+ // represents the offset of the root of the inline formatting context.
+ PhysicalOffset inline_root_offset;
+ // The result is set to this member, but its address does not change during
+ // the traversal.
+ HitTestResult* result;
+ };
+
// Hit tests the children of a container fragment, which is either
// |box_fragment_|, or one of its child line box fragments.
// @param physical_offset Physical offset of the container fragment's content
// box in paint layer. Note that this includes scrolling offset when the
// container has 'overflow: scroll'.
- bool HitTestChildren(HitTestResult&,
- const HitTestLocation& hit_test_location,
- const PhysicalOffset& physical_offset,
- HitTestAction);
- bool HitTestChildren(HitTestResult&,
+ bool NodeAtPoint(const HitTestContext& hit_test,
+ const PhysicalOffset& physical_offset);
+ bool HitTestChildren(const HitTestContext& hit_test,
+ const PhysicalOffset& physical_offset);
+ bool HitTestChildren(const HitTestContext& hit_test,
const NGInlineCursor& children,
- const HitTestLocation& hit_test_location,
- const PhysicalOffset& physical_offset,
- HitTestAction);
- bool HitTestPaintFragmentChildren(HitTestResult&,
- const NGInlineCursor& children,
- const HitTestLocation& hit_test_location,
- const PhysicalOffset& physical_offset,
- HitTestAction);
- bool HitTestItemsChildren(HitTestResult&,
- const NGInlineCursor& children,
- const HitTestLocation& hit_test_location,
- const PhysicalOffset& physical_offset,
+ const PhysicalOffset& physical_offset);
+ bool HitTestBlockChildren(HitTestResult&,
+ const HitTestLocation&,
+ PhysicalOffset,
HitTestAction);
+ bool HitTestPaintFragmentChildren(const HitTestContext& hit_test,
+ const NGInlineCursor& children,
+ const PhysicalOffset& physical_offset);
+ bool HitTestItemsChildren(const HitTestContext& hit_test,
+ const NGInlineCursor& children);
+ bool HitTestFloatingChildren(const HitTestContext& hit_test,
+ const NGPhysicalContainerFragment& container,
+ const PhysicalOffset& accumulated_offset);
+ bool HitTestFloatingChildItems(const HitTestContext& hit_test,
+ const NGInlineCursor& children,
+ const PhysicalOffset& accumulated_offset);
// Hit tests a box fragment, which is a child of either |box_fragment_|, or
// one of its child line box fragments.
// @param physical_offset Physical offset of the given box fragment in the
// paint layer.
- bool HitTestChildBoxFragment(HitTestResult&,
+ bool HitTestChildBoxFragment(const HitTestContext& hit_test,
const NGPhysicalBoxFragment& fragment,
const NGInlineBackwardCursor& cursor,
- const HitTestLocation& hit_test_location,
- const PhysicalOffset& physical_offset,
- HitTestAction);
+ const PhysicalOffset& physical_offset);
+ bool HitTestChildBoxItem(const HitTestContext& hit_test,
+ const NGFragmentItem& item,
+ const NGInlineBackwardCursor& cursor);
// Hit tests the given text fragment.
// @param physical_offset Physical offset of the text fragment in paint layer.
- bool HitTestTextFragment(HitTestResult&,
+ bool HitTestTextFragment(const HitTestContext& hit_test,
const NGInlineBackwardCursor& cursor,
- const HitTestLocation& hit_test_location,
- const PhysicalOffset& physical_offset,
- HitTestAction);
- bool HitTestTextItem(HitTestResult& result,
- const NGFragmentItem& text_item,
- const HitTestLocation& hit_test_location,
- const PhysicalOffset& physical_offset,
- HitTestAction action);
+ const PhysicalOffset& physical_offset);
+ bool HitTestTextItem(const HitTestContext& hit_test,
+ const NGFragmentItem& text_item);
// Hit tests the given line box fragment.
// @param physical_offset Physical offset of the line box fragment in paint
// layer.
- bool HitTestLineBoxFragment(HitTestResult&,
+ bool HitTestLineBoxFragment(const HitTestContext& hit_test,
const NGPhysicalLineBoxFragment& fragment,
const NGInlineBackwardCursor& cursor,
- const HitTestLocation& hit_test_location,
- const PhysicalOffset& physical_offset,
- HitTestAction);
+ const PhysicalOffset& physical_offset);
// Returns whether the hit test location is completely outside the border box,
// which possibly has rounded corners.
@@ -224,6 +275,9 @@ class NGBoxFragmentPainter : public BoxPainterBase {
const HitTestLocation&,
const PhysicalOffset& border_box_location) const;
+ bool HitTestOverflowControl(const HitTestContext&,
+ PhysicalOffset accumulated_offset);
+
const NGPhysicalBoxFragment& PhysicalFragment() const {
return box_fragment_;
}
@@ -231,6 +285,8 @@ class NGBoxFragmentPainter : public BoxPainterBase {
return display_item_client_;
}
const NGBorderEdges& BorderEdges() const;
+ PhysicalRect SelfInkOverflow() const;
+ PhysicalRect ContentsInkOverflow() const;
const NGPhysicalBoxFragment& box_fragment_;
const DisplayItemClient& display_item_client_;
@@ -240,7 +296,7 @@ class NGBoxFragmentPainter : public BoxPainterBase {
const NGPaintFragment* paint_fragment_;
const NGFragmentItems* items_;
const NGFragmentItem* box_item_ = nullptr;
- NGInlineCursor* descendants_ = nullptr;
+ const NGInlineCursor* inline_box_cursor_ = nullptr;
mutable base::Optional<NGBorderEdges> border_edges_;
};
@@ -248,34 +304,45 @@ inline NGBoxFragmentPainter::NGBoxFragmentPainter(
const NGPhysicalBoxFragment& box,
const DisplayItemClient& display_item_client,
const NGPaintFragment* paint_fragment,
- NGInlineCursor* descendants)
+ const NGInlineCursor* inline_box_cursor,
+ const NGFragmentItem* box_item)
: BoxPainterBase(&box.GetDocument(), box.Style(), box.GeneratingNode()),
box_fragment_(box),
display_item_client_(display_item_client),
paint_fragment_(paint_fragment),
items_(box.Items()),
- descendants_(descendants) {
+ box_item_(box_item),
+ inline_box_cursor_(inline_box_cursor) {
DCHECK(box.IsBox() || box.IsRenderedLegend());
- DCHECK(!paint_fragment || !descendants);
#if DCHECK_IS_ON()
- if (box.IsInlineBox()) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
+ DCHECK(!paint_fragment_);
+ if (inline_box_cursor_)
+ DCHECK_EQ(inline_box_cursor_->Current().Item(), box_item_);
+ if (box_item_)
+ DCHECK_EQ(box_item_->BoxFragment(), &box);
+ DCHECK_EQ(box.IsInlineBox(), !!inline_box_cursor_);
+ DCHECK_EQ(box.IsInlineBox(), !!box_item_);
+ } else {
+ DCHECK(!inline_box_cursor_);
+ DCHECK(!box_item_);
if (paint_fragment)
DCHECK_EQ(&paint_fragment->PhysicalFragment(), &box);
- } else if (box.ChildrenInline()) {
- // If no children, there maybe or may not be NGPaintFragment.
- // TODO(kojii): To be investigated if this correct or should be fixed.
- if (!box.Children().empty()) {
- DCHECK(paint_fragment || box.HasItems());
- if (paint_fragment)
- DCHECK_EQ(&paint_fragment->PhysicalFragment(), &box);
+ if (box.IsInlineBox()) {
+ DCHECK(paint_fragment_);
+ } else if (box.IsInlineFormattingContext()) {
+ // If no children, there maybe or may not be NGPaintFragment.
+ // TODO(kojii): To be investigated if this correct or should be fixed.
+ if (!box.Children().empty()) {
+ if (!box.GetLayoutObject() ||
+ !box.GetLayoutObject()->PaintBlockedByDisplayLock(
+ DisplayLockLifecycleTarget::kChildren)) {
+ DCHECK(paint_fragment);
+ }
+ }
+ } else {
+ // We may not have |paint_fragment_| nor |box_item_|.
}
- } else if (box.IsColumnBox() ||
- (box.GetLayoutObject()->SlowFirstChild() &&
- box.GetLayoutObject()->SlowFirstChild()->IsLayoutFlowThread())) {
- // TODO(kojii): NGPaintFragment for multicol has non-inline children
- // (kColumnBox). Could this be regular box fragments?
- } else {
- DCHECK(!paint_fragment);
}
#endif
}
@@ -285,7 +352,8 @@ inline NGBoxFragmentPainter::NGBoxFragmentPainter(
: NGBoxFragmentPainter(fragment,
*fragment.GetLayoutObject(),
/* paint_fragment */ nullptr,
- /* descendants */ nullptr) {}
+ /* inline_box_cursor */ nullptr,
+ /* box_item */ nullptr) {}
inline NGBoxFragmentPainter::NGBoxFragmentPainter(
const NGPhysicalBoxFragment& fragment,
@@ -297,7 +365,8 @@ inline NGBoxFragmentPainter::NGBoxFragmentPainter(
: *static_cast<const DisplayItemClient*>(
fragment.GetLayoutObject()),
paint_fragment,
- /* descendants */ nullptr) {}
+ /* inline_box_cursor */ nullptr,
+ /* box_item */ nullptr) {}
inline NGBoxFragmentPainter::NGBoxFragmentPainter(
const NGPaintFragment& paint_fragment)
@@ -307,16 +376,16 @@ inline NGBoxFragmentPainter::NGBoxFragmentPainter(
&paint_fragment) {}
inline NGBoxFragmentPainter::NGBoxFragmentPainter(
+ const NGInlineCursor& inline_box_cursor,
const NGFragmentItem& item,
- const NGPhysicalBoxFragment& fragment,
- NGInlineCursor* descendants)
+ const NGPhysicalBoxFragment& fragment)
: NGBoxFragmentPainter(fragment,
item,
/* paint_fragment */ nullptr,
- descendants) {
+ &inline_box_cursor,
+ &item) {
DCHECK_EQ(item.BoxFragment(), &fragment);
DCHECK(fragment.IsInlineBox());
- box_item_ = &item;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter_test.cc b/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter_test.cc
index 813071ca277..ccaf7fcbf22 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter_test.cc
@@ -6,6 +6,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h"
#include "third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
@@ -24,10 +25,9 @@ class NGBoxFragmentPainterTest : public PaintControllerPaintTest,
ScopedLayoutNGForTest(true) {}
};
-using NGBoxFragmentPainterScrollHitTestTest = NGBoxFragmentPainterTest;
-INSTANTIATE_SCROLL_HIT_TEST_SUITE_P(NGBoxFragmentPainterScrollHitTestTest);
+INSTANTIATE_PAINT_TEST_SUITE_P(NGBoxFragmentPainterTest);
-TEST_P(NGBoxFragmentPainterScrollHitTestTest, ScrollHitTestOrder) {
+TEST_P(NGBoxFragmentPainterTest, ScrollHitTestOrder) {
GetPage().GetSettings().SetPreferCompositingToLCDTextEnabled(false);
SetBodyInnerHTML(R"HTML(
<!DOCTYPE html>
@@ -43,17 +43,59 @@ TEST_P(NGBoxFragmentPainterScrollHitTestTest, ScrollHitTestOrder) {
</style>
<div id='scroller'>TEXT</div>
)HTML");
- auto& scroller = *GetLayoutObjectByElementId("scroller");
+ auto& scroller = ToLayoutBox(*GetLayoutObjectByElementId("scroller"));
- const NGPaintFragment& root_fragment = *scroller.PaintFragment();
- const NGPaintFragment& line_box_fragment = *root_fragment.FirstChild();
- const NGPaintFragment& text_fragment = *line_box_fragment.FirstChild();
+ const DisplayItemClient& root_fragment =
+ scroller.PaintFragment()
+ ? static_cast<const DisplayItemClient&>(*scroller.PaintFragment())
+ : static_cast<const DisplayItemClient&>(scroller);
+
+ NGInlineCursor cursor;
+ cursor.MoveTo(*scroller.SlowFirstChild());
+ const DisplayItemClient& text_fragment =
+ *cursor.Current().GetDisplayItemClient();
EXPECT_THAT(RootPaintController().GetDisplayItemList(),
ElementsAre(IsSameId(&ViewScrollingBackgroundClient(),
DisplayItem::kDocumentBackground),
- IsSameId(&root_fragment, DisplayItem::kScrollHitTest),
IsSameId(&text_fragment, kForegroundType)));
+ HitTestData scroll_hit_test;
+ scroll_hit_test.scroll_translation =
+ &scroller.FirstFragment().ContentsProperties().Transform();
+ scroll_hit_test.scroll_hit_test_rect = IntRect(0, 0, 40, 40);
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(
+ IsPaintChunk(0, 1,
+ PaintChunk::Id(ViewScrollingBackgroundClient(),
+ DisplayItem::kDocumentBackground),
+ GetLayoutView().FirstFragment().ContentsProperties()),
+ IsPaintChunk(
+ 1, 1,
+ PaintChunk::Id(*scroller.Layer(), DisplayItem::kLayerChunk),
+ scroller.FirstFragment().LocalBorderBoxProperties()),
+ IsPaintChunk(
+ 1, 1,
+ PaintChunk::Id(root_fragment, DisplayItem::kScrollHitTest),
+ scroller.FirstFragment().LocalBorderBoxProperties(),
+ &scroll_hit_test, IntRect(0, 0, 40, 40)),
+ IsPaintChunk(1, 2)));
+ } else {
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(
+ IsPaintChunk(0, 1,
+ PaintChunk::Id(ViewScrollingBackgroundClient(),
+ DisplayItem::kDocumentBackground),
+ GetLayoutView().FirstFragment().ContentsProperties()),
+ IsPaintChunk(
+ 1, 1,
+ PaintChunk::Id(root_fragment, DisplayItem::kScrollHitTest),
+ scroller.FirstFragment().LocalBorderBoxProperties(),
+ &scroll_hit_test, IntRect(0, 0, 40, 40)),
+ IsPaintChunk(1, 2)));
+ }
}
} // namespace blink
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 a79eee1c887..fe8baf7fa64 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
@@ -32,11 +32,6 @@ void NGFieldsetPainter::PaintBoxDecorationBackground(
// Paint the fieldset (background, other decorations, and) border, with the
// cutout hole for the legend.
PaintFieldsetDecorationBackground(legend, paint_info, paint_offset);
-
- // Proceed to painting the legend. According to the spec, it should be done as
- // part of the border phase.
- if (legend)
- PaintLegend(To<NGPhysicalBoxFragment>(**legend), paint_info);
}
void NGFieldsetPainter::PaintFieldsetDecorationBackground(
@@ -103,16 +98,4 @@ void NGFieldsetPainter::PaintFieldsetDecorationBackground(
}
}
-void NGFieldsetPainter::PaintLegend(const NGPhysicalBoxFragment& legend,
- const PaintInfo& paint_info) {
- // Unless the legend establishes its own self-painting layer, paint the legend
- // as part of the border phase, according to spec.
- const LayoutObject* legend_object = legend.GetLayoutObject();
- if (ToLayoutBox(legend_object)->HasSelfPaintingLayer())
- return;
- PaintInfo legend_paint_info = paint_info;
- legend_paint_info.phase = PaintPhase::kForeground;
- ObjectPainter(*legend_object).PaintAllPhasesAtomically(legend_paint_info);
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_fieldset_painter.h b/chromium/third_party/blink/renderer/core/paint/ng/ng_fieldset_painter.h
index ce6012566e4..5a5f601b09d 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_fieldset_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_fieldset_painter.h
@@ -27,7 +27,6 @@ class NGFieldsetPainter {
void PaintFieldsetDecorationBackground(const NGLink* legend,
const PaintInfo&,
const PhysicalOffset&);
- void PaintLegend(const NGPhysicalBoxFragment& legend, const PaintInfo&);
const NGPhysicalBoxFragment& fieldset_;
};
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.cc b/chromium/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.cc
index 3fcbfa66af4..c27547d8ed0 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.cc
@@ -83,23 +83,4 @@ void NGFragmentPainter::AddURLRectIfNeeded(const PaintInfo& paint_info,
paint_info.context.SetURLForRect(url, rect);
}
-bool NGFragmentPainter::ShouldRecordHitTestData(
- const PaintInfo& paint_info,
- const NGPhysicalBoxFragment& fragment) {
- // Hit test display items are only needed for compositing. This flag is used
- // for for printing and drag images which do not need hit testing.
- if (paint_info.GetGlobalPaintFlags() & kGlobalPaintFlattenCompositingLayers)
- return false;
-
- // If an object is not visible, it does not participate in hit testing.
- if (fragment.Style().Visibility() != EVisibility::kVisible)
- return false;
-
- auto touch_action = fragment.EffectiveAllowedTouchAction();
- if (touch_action == TouchAction::kTouchActionAuto)
- return false;
-
- return true;
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.h b/chromium/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.h
index 5d7cee1a9ed..60a21cf012d 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.h
@@ -22,28 +22,23 @@ class NGFragmentPainter : public ObjectPainterBase {
public:
NGFragmentPainter(const NGPhysicalBoxFragment& box,
- const NGPaintFragment* paint_fragment)
- : box_fragment_(box), paint_fragment_(paint_fragment) {}
+ const DisplayItemClient& display_item_client)
+ : box_fragment_(box), display_item_client_(display_item_client) {}
void PaintOutline(const PaintInfo&, const PhysicalOffset& paint_offset);
void AddURLRectIfNeeded(const PaintInfo&, const PhysicalOffset& paint_offset);
- static bool ShouldRecordHitTestData(const PaintInfo&,
- const NGPhysicalBoxFragment&);
-
private:
const NGPhysicalBoxFragment& PhysicalFragment() const {
return box_fragment_;
}
const DisplayItemClient& GetDisplayItemClient() const {
- if (paint_fragment_)
- return *paint_fragment_;
- return *PhysicalFragment().GetLayoutObject();
+ return display_item_client_;
}
const NGPhysicalBoxFragment& box_fragment_;
- const NGPaintFragment* paint_fragment_;
+ const DisplayItemClient& display_item_client_;
};
} // namespace blink
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 dda54a466e9..15aa6b95573 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
@@ -34,7 +34,14 @@ inline bool HasMultiplePaintFragments(const LayoutObject& layout_object) {
}
inline bool HasMultipleFragmentItems(const LayoutObject& layout_object) {
- return HasMultipleItems(NGFragmentItem::ItemsFor(layout_object));
+ NGInlineCursor cursor;
+ cursor.MoveTo(layout_object);
+ DCHECK(cursor);
+ if (cursor) {
+ cursor.MoveToNextForSameLayoutObject();
+ return cursor;
+ }
+ return false;
}
} // namespace
@@ -52,7 +59,7 @@ void NGInlineBoxFragmentPainter::Paint(const PaintInfo& paint_info,
const PhysicalOffset adjusted_paint_offset =
paint_offset + (inline_box_paint_fragment_
? inline_box_paint_fragment_->Offset()
- : inline_box_item_->Offset());
+ : inline_box_item_->OffsetInContainerBlock());
if (paint_info.phase == PaintPhase::kForeground)
PaintBackgroundBorderShadow(paint_info, adjusted_paint_offset);
@@ -64,9 +71,10 @@ void NGInlineBoxFragmentPainter::Paint(const PaintInfo& paint_info,
suppress_box_decoration_background);
return;
}
+ DCHECK(inline_box_cursor_);
DCHECK(inline_box_item_);
- NGBoxFragmentPainter box_painter(*inline_box_item_, PhysicalFragment(),
- descendants_);
+ NGBoxFragmentPainter box_painter(*inline_box_cursor_, *inline_box_item_,
+ PhysicalFragment());
box_painter.PaintObject(paint_info, adjusted_paint_offset,
suppress_box_decoration_background);
}
@@ -112,11 +120,21 @@ void NGInlineBoxFragmentPainterBase::PaintBackgroundBorderShadow(
// TODO(eae): Switch to LayoutNG version of BackgroundImageGeometry.
BackgroundImageGeometry geometry(*static_cast<const LayoutBoxModelObject*>(
inline_box_fragment_.GetLayoutObject()));
- // TODO(kojii): not applicable for line box
- NGBoxFragmentPainter box_painter(
- To<NGPhysicalBoxFragment>(inline_box_fragment_),
- inline_box_paint_fragment_);
const NGBorderEdges& border_edges = BorderEdges();
+ if (inline_box_paint_fragment_) {
+ NGBoxFragmentPainter box_painter(
+ To<NGPhysicalBoxFragment>(inline_box_fragment_),
+ inline_box_paint_fragment_);
+ PaintBoxDecorationBackground(
+ box_painter, paint_info, paint_offset, adjusted_frame_rect, geometry,
+ object_has_multiple_boxes, border_edges.line_left,
+ border_edges.line_right);
+ return;
+ }
+ DCHECK(inline_box_cursor_);
+ NGBoxFragmentPainter box_painter(
+ *inline_box_cursor_, *inline_box_item_,
+ To<NGPhysicalBoxFragment>(inline_box_fragment_));
PaintBoxDecorationBackground(box_painter, paint_info, paint_offset,
adjusted_frame_rect, geometry,
object_has_multiple_boxes,
@@ -178,22 +196,34 @@ void NGInlineBoxFragmentPainterBase::ComputeFragmentOffsetOnLine(
LayoutUnit* offset_on_line,
LayoutUnit* total_width) const {
WritingMode writing_mode = inline_box_fragment_.Style().GetWritingMode();
- NGPaintFragment::FragmentRange fragments =
- inline_box_paint_fragment_->InlineFragmentsFor(
- inline_box_fragment_.GetLayoutObject());
+ NGInlineCursor cursor;
+ DCHECK(inline_box_fragment_.GetLayoutObject());
+ cursor.MoveTo(*inline_box_fragment_.GetLayoutObject());
LayoutUnit before;
LayoutUnit after;
bool before_self = true;
- for (auto iter = fragments.begin(); iter != fragments.end(); ++iter) {
- if (*iter == inline_box_paint_fragment_) {
- before_self = false;
- continue;
+ for (; cursor; cursor.MoveToNextForSameLayoutObject()) {
+ if (inline_box_paint_fragment_) {
+ DCHECK(cursor.CurrentPaintFragment());
+ if (cursor.CurrentPaintFragment() == inline_box_paint_fragment_) {
+ before_self = false;
+ continue;
+ }
+ } else {
+ DCHECK(inline_box_item_);
+ DCHECK(cursor.CurrentItem());
+ if (cursor.CurrentItem() == inline_box_item_) {
+ before_self = false;
+ continue;
+ }
}
+ const NGPhysicalBoxFragment* box_fragment = cursor.Current().BoxFragment();
+ DCHECK(box_fragment);
if (before_self)
- before += NGFragment(writing_mode, iter->PhysicalFragment()).InlineSize();
+ before += NGFragment(writing_mode, *box_fragment).InlineSize();
else
- after += NGFragment(writing_mode, iter->PhysicalFragment()).InlineSize();
+ after += NGFragment(writing_mode, *box_fragment).InlineSize();
}
NGFragment logical_fragment(writing_mode, inline_box_fragment_);
@@ -326,7 +356,7 @@ void NGInlineBoxFragmentPainter::PaintAllFragments(
for (const NGPaintFragment* fragment : fragments) {
PhysicalOffset child_offset = paint_offset +
- fragment->InlineOffsetToContainerBox() -
+ fragment->OffsetInContainerBlock() -
fragment->Offset();
DCHECK(fragment->PhysicalFragment().IsBox());
NGInlineBoxFragmentPainter(*fragment).Paint(paint_info, child_offset);
@@ -334,7 +364,6 @@ void NGInlineBoxFragmentPainter::PaintAllFragments(
return;
}
- DCHECK(layout_inline.ShouldCreateBoxFragment());
NGInlineCursor cursor(*block_flow);
cursor.MoveTo(layout_inline);
for (; cursor; cursor.MoveToNextForSameLayoutObject()) {
@@ -342,10 +371,23 @@ void NGInlineBoxFragmentPainter::PaintAllFragments(
DCHECK(item);
const NGPhysicalBoxFragment* box_fragment = item->BoxFragment();
DCHECK(box_fragment);
- NGInlineCursor descendants = cursor.CursorForDescendants();
- NGInlineBoxFragmentPainter(*item, *box_fragment, &descendants)
+ NGInlineBoxFragmentPainter(cursor, *item, *box_fragment)
.Paint(paint_info, paint_offset);
}
}
+#if DCHECK_IS_ON()
+void NGInlineBoxFragmentPainter::CheckValid() const {
+ if (inline_box_item_) {
+ DCHECK(inline_box_cursor_);
+ DCHECK_EQ(inline_box_cursor_->Current().Item(), inline_box_item_);
+ }
+
+ DCHECK_EQ(inline_box_fragment_.Type(),
+ NGPhysicalFragment::NGFragmentType::kFragmentBox);
+ DCHECK_EQ(inline_box_fragment_.BoxType(),
+ NGPhysicalFragment::NGBoxType::kInlineBox);
+}
+#endif
+
} // namespace blink
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 478e697015a..5b2529a74ae 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
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_NG_NG_INLINE_BOX_FRAGMENT_PAINTER_H_
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_border_edges.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h"
#include "third_party/blink/renderer/core/paint/inline_box_painter_base.h"
#include "third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h"
@@ -30,6 +31,7 @@ class NGInlineBoxFragmentPainterBase : public InlineBoxPainterBase {
protected:
NGInlineBoxFragmentPainterBase(
const NGPhysicalFragment& inline_box_fragment,
+ const NGInlineCursor* inline_box_cursor,
const NGPaintFragment* inline_box_paint_fragment,
const NGFragmentItem* inline_box_item,
const LayoutObject& layout_object,
@@ -42,8 +44,13 @@ class NGInlineBoxFragmentPainterBase : public InlineBoxPainterBase {
line_style),
inline_box_fragment_(inline_box_fragment),
inline_box_paint_fragment_(inline_box_paint_fragment),
- inline_box_item_(inline_box_item) {
+ inline_box_item_(inline_box_item),
+ inline_box_cursor_(inline_box_cursor) {
#if DCHECK_IS_ON()
+ if (inline_box_cursor) {
+ DCHECK(inline_box_item);
+ DCHECK_EQ(inline_box_cursor->Current().Item(), inline_box_item);
+ }
if (inline_box_paint_fragment) {
DCHECK_EQ(&inline_box_paint_fragment->PhysicalFragment(),
&inline_box_fragment);
@@ -65,6 +72,7 @@ class NGInlineBoxFragmentPainterBase : public InlineBoxPainterBase {
const ComputedStyle& style,
const ComputedStyle& line_style)
: NGInlineBoxFragmentPainterBase(inline_box_fragment.PhysicalFragment(),
+ /* inline_box_cursor */ nullptr,
&inline_box_fragment,
/* inline_box_item */ nullptr,
layout_object,
@@ -73,12 +81,14 @@ class NGInlineBoxFragmentPainterBase : public InlineBoxPainterBase {
// Constructor for |NGFragmentItem|.
NGInlineBoxFragmentPainterBase(
+ const NGInlineCursor& inline_box_cursor,
const NGFragmentItem& inline_box_item,
const NGPhysicalBoxFragment& inline_box_fragment,
const LayoutObject& layout_object,
const ComputedStyle& style,
const ComputedStyle& line_style)
: NGInlineBoxFragmentPainterBase(inline_box_fragment,
+ &inline_box_cursor,
/* inline_box_paint_fragment */ nullptr,
&inline_box_item,
layout_object,
@@ -114,6 +124,7 @@ class NGInlineBoxFragmentPainterBase : public InlineBoxPainterBase {
const NGPhysicalFragment& inline_box_fragment_;
const NGPaintFragment* inline_box_paint_fragment_ = nullptr;
const NGFragmentItem* inline_box_item_ = nullptr;
+ const NGInlineCursor* inline_box_cursor_ = nullptr;
};
// Painter for LayoutNG inline box fragments. Delegates to NGBoxFragmentPainter
@@ -135,19 +146,23 @@ class NGInlineBoxFragmentPainter : public NGInlineBoxFragmentPainterBase {
}
// Constructor for |NGFragmentItem|.
- NGInlineBoxFragmentPainter(const NGFragmentItem& inline_box_item,
- const NGPhysicalBoxFragment& inline_box_fragment,
- NGInlineCursor* descendants = nullptr)
- : NGInlineBoxFragmentPainterBase(inline_box_item,
+ NGInlineBoxFragmentPainter(const NGInlineCursor& inline_box_cursor,
+ const NGFragmentItem& inline_box_item,
+ const NGPhysicalBoxFragment& inline_box_fragment)
+ : NGInlineBoxFragmentPainterBase(inline_box_cursor,
+ inline_box_item,
inline_box_fragment,
*inline_box_fragment.GetLayoutObject(),
inline_box_fragment.Style(),
- inline_box_fragment.Style()),
- descendants_(descendants) {
- DCHECK_EQ(inline_box_fragment.Type(),
- NGPhysicalFragment::NGFragmentType::kFragmentBox);
- DCHECK_EQ(inline_box_fragment.BoxType(),
- NGPhysicalFragment::NGBoxType::kInlineBox);
+ inline_box_fragment.Style()) {
+ CheckValid();
+ }
+ NGInlineBoxFragmentPainter(const NGInlineCursor& inline_box_cursor,
+ const NGFragmentItem& inline_box_item)
+ : NGInlineBoxFragmentPainter(inline_box_cursor,
+ inline_box_item,
+ *inline_box_item.BoxFragment()) {
+ DCHECK(inline_box_item.BoxFragment());
}
void Paint(const PaintInfo&, const PhysicalOffset& paint_offset);
@@ -163,8 +178,13 @@ class NGInlineBoxFragmentPainter : public NGInlineBoxFragmentPainterBase {
const NGBorderEdges BorderEdges() const final;
+#if DCHECK_IS_ON()
+ void CheckValid() const;
+#else
+ void CheckValid() const {}
+#endif
+
mutable base::Optional<NGBorderEdges> border_edges_;
- NGInlineCursor* descendants_ = nullptr;
};
// Painter for LayoutNG line box fragments. Line boxes don't paint anything,
@@ -206,6 +226,7 @@ class NGLineBoxFragmentPainter : public NGInlineBoxFragmentPainterBase {
const LayoutObject& layout_block_flow)
: NGInlineBoxFragmentPainterBase(
line_box_fragment,
+ /* inline_box_cursor */ nullptr,
line_box_paint_fragment,
line_box_item,
layout_block_flow,
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
new file mode 100644
index 00000000000..68e778f333d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_mathml_painter.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 "third_party/blink/renderer/core/paint/ng/ng_mathml_painter.h"
+
+#include "third_party/blink/renderer/core/layout/ng/mathml/ng_math_layout_utils.h"
+#include "third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h"
+#include "third_party/blink/renderer/core/paint/paint_info.h"
+#include "third_party/blink/renderer/platform/geometry/layout_unit.h"
+#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h"
+#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
+
+namespace blink {
+
+void NGMathMLPainter::PaintBar(const PaintInfo& info, const IntRect& bar) {
+ if (bar.IsEmpty())
+ return;
+
+ GraphicsContextStateSaver state_saver(info.context);
+ info.context.SetStrokeThickness(bar.Height());
+ info.context.SetStrokeStyle(kSolidStroke);
+ info.context.SetStrokeColor(
+ box_fragment_.Style().VisitedDependentColor(GetCSSPropertyColor()));
+ IntPoint line_end_point = {bar.Width(), 0};
+ info.context.DrawLine(bar.Location(), bar.Location() + line_end_point);
+}
+
+void NGMathMLPainter::PaintFractionBar(const PaintInfo& info,
+ PhysicalOffset paint_offset) {
+ const DisplayItemClient& display_item_client =
+ *box_fragment_.GetLayoutObject();
+ if (DrawingRecorder::UseCachedDrawingIfPossible(
+ info.context, display_item_client, info.phase))
+ return;
+
+ DrawingRecorder recorder(info.context, display_item_client, info.phase);
+
+ DCHECK(box_fragment_.Style().IsHorizontalWritingMode());
+ const ComputedStyle& style = box_fragment_.Style();
+ LayoutUnit line_thickness = FractionLineThickness(style);
+ if (!line_thickness)
+ return;
+ LayoutUnit axis_height = MathAxisHeight(style);
+ if (auto baseline = box_fragment_.Baseline()) {
+ auto borders = box_fragment_.Borders();
+ auto padding = box_fragment_.Padding();
+ PhysicalRect bar_rect = {
+ borders.left + padding.left, *baseline - axis_height,
+ box_fragment_.Size().width - borders.HorizontalSum() -
+ padding.HorizontalSum(),
+ line_thickness};
+ bar_rect.Move(paint_offset);
+ PaintBar(info, PixelSnappedIntRect(bar_rect));
+ }
+}
+
+} // 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
new file mode 100644
index 00000000000..70233e8017f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_mathml_painter.h
@@ -0,0 +1,33 @@
+// 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_PAINT_NG_NG_MATHML_PAINTER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_NG_NG_MATHML_PAINTER_H_
+
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+
+namespace blink {
+
+struct PaintInfo;
+struct PhysicalOffset;
+class IntRect;
+class NGPhysicalBoxFragment;
+
+class NGMathMLPainter {
+ STACK_ALLOCATED();
+
+ public:
+ explicit NGMathMLPainter(const NGPhysicalBoxFragment& box_fragment)
+ : box_fragment_(box_fragment) {}
+ void PaintFractionBar(const PaintInfo&, PhysicalOffset);
+
+ private:
+ void PaintBar(const PaintInfo&, const IntRect&);
+
+ const NGPhysicalBoxFragment& box_fragment_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_NG_NG_MATHML_PAINTER_H_
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 8d5848d2cd6..9cd79dd07b2 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
@@ -21,7 +21,6 @@
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.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_list_marker.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h"
#include "third_party/blink/renderer/core/layout/ng/ng_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_ink_overflow.h"
@@ -116,7 +115,7 @@ LogicalRect ExpandedSelectionRectForSoftLineBreakIfNeeded(
if (layout_block_flow && layout_block_flow->ShouldTruncateOverflowingText())
return rect;
// Copy from InlineTextBoxPainter::PaintSelection.
- const LayoutUnit space_width(cursor.CurrentStyle().GetFont().SpaceWidth());
+ const LayoutUnit space_width(cursor.Current().Style().GetFont().SpaceWidth());
return {rect.offset,
{rect.size.inline_size + space_width, rect.size.block_size}};
}
@@ -139,7 +138,9 @@ LogicalRect ExpandSelectionRectToLineHeight(const LogicalRect& rect,
NGInlineCursor line(cursor);
line.MoveToContainingLine();
const PhysicalRect line_physical_rect(
- line.CurrentOffset() - cursor.CurrentOffset(), line.CurrentSize());
+ line.Current().OffsetInContainerBlock() -
+ cursor.Current().OffsetInContainerBlock(),
+ line.Current().Size());
return ExpandSelectionRectToLineHeight(
rect, ComputeLogicalRectFor(line_physical_rect, cursor));
}
@@ -432,8 +433,8 @@ void NGPaintFragment::PopulateDescendants(CreateContext* parent_context) {
scoped_refptr<NGPaintFragment>* last_child_ptr = &first_child_;
auto* box_physical_fragment = DynamicTo<NGPhysicalBoxFragment>(fragment);
- bool children_are_inline =
- !box_physical_fragment || box_physical_fragment->ChildrenInline();
+ bool is_inline_fc = !box_physical_fragment ||
+ box_physical_fragment->IsInlineFormattingContext();
for (const NGLink& child_fragment : container.Children()) {
child_fragment->CheckType();
@@ -444,11 +445,11 @@ void NGPaintFragment::PopulateDescendants(CreateContext* parent_context) {
child_context.populate_children =
child_fragment->IsContainer() &&
- !child_fragment->IsBlockFormattingContextRoot();
+ !child_fragment->IsFormattingContextRoot();
scoped_refptr<NGPaintFragment> child = CreateOrReuse(
child_fragment.get(), child_fragment.Offset(), &child_context);
- if (children_are_inline) {
+ if (is_inline_fc) {
DCHECK(!child_fragment->IsOutOfFlowPositioned());
if (child_fragment->IsText() || child_fragment->IsInlineBox() ||
child_fragment->IsAtomicInline()) {
@@ -506,12 +507,15 @@ void NGPaintFragment::AssociateWithLayoutObject(
return;
}
// This |layout_object| was fragmented across multiple blocks.
+ DCHECK_EQ(layout_object, first_fragment->GetLayoutObject());
NGPaintFragment* last_fragment = first_fragment->LastForSameLayoutObject();
last_fragment->next_for_same_layout_object_ = this;
return;
}
- DCHECK(add_result.stored_value->value);
- add_result.stored_value->value->next_for_same_layout_object_ = this;
+ NGPaintFragment* last_fragment = add_result.stored_value->value;
+ DCHECK(last_fragment) << layout_object;
+ DCHECK_EQ(layout_object, last_fragment->GetLayoutObject());
+ last_fragment->next_for_same_layout_object_ = this;
add_result.stored_value->value = this;
}
@@ -537,7 +541,7 @@ void NGPaintFragment::ClearAssociationWithLayoutObject() {
fragment.IsColumnBox()) {
child->ClearAssociationWithLayoutObject();
} else {
- DCHECK(fragment.IsText() || fragment.IsBlockFormattingContextRoot());
+ DCHECK(fragment.IsText() || fragment.IsFormattingContextRoot());
DCHECK(child->Children().IsEmpty());
}
}
@@ -640,7 +644,7 @@ PhysicalRect NGPaintFragment::RecalcContentsInkOverflow() const {
// A BFC root establishes a separate NGPaintFragment tree. Re-compute the
// child tree using its LayoutObject, because it may not be NG.
- if (child_fragment.IsBlockFormattingContextRoot()) {
+ if (child_fragment.IsFormattingContextRoot()) {
LayoutBox* layout_box =
ToLayoutBox(child_fragment.GetMutableLayoutObject());
layout_box->RecalcVisualOverflow();
@@ -661,7 +665,7 @@ PhysicalRect NGPaintFragment::RecalcContentsInkOverflow() const {
PhysicalRect NGPaintFragment::RecalcInkOverflow() {
const NGPhysicalFragment& fragment = PhysicalFragment();
fragment.CheckCanUpdateInkOverflow();
- DCHECK(!fragment.IsBlockFormattingContextRoot());
+ DCHECK(!fragment.IsFormattingContextRoot());
// NGPhysicalTextFragment caches ink overflow in layout. No need to recalc nor
// to store in NGPaintFragment.
@@ -755,7 +759,7 @@ base::Optional<PhysicalRect> NGPaintFragment::LocalVisualRectFor(
if (fragment->PhysicalFragment().IsHiddenForPaint())
continue;
PhysicalRect child_visual_rect = fragment->SelfInkOverflow();
- child_visual_rect.offset += fragment->InlineOffsetToContainerBox();
+ child_visual_rect.offset += fragment->OffsetInContainerBlock();
visual_rect.Unite(child_visual_rect);
}
return visual_rect;
@@ -781,7 +785,9 @@ NGPaintFragment* NGPaintFragment::FirstLineBox() const {
}
const NGPaintFragment* NGPaintFragment::Root() const {
- DCHECK(PhysicalFragment().IsInline());
+ // Because of this function can be called during |LayoutObject::Destroy()|,
+ // we use |physical_fragment_| to avoid calling |IsAlive()|.
+ DCHECK(physical_fragment_->IsInline());
const NGPaintFragment* root = this;
for (const NGPaintFragment* fragment :
NGPaintFragmentTraversal::InclusiveAncestorsOf(*this)) {
@@ -915,17 +921,19 @@ PhysicalRect ComputeLocalSelectionRectForText(
LogicalRect logical_rect = ComputeLogicalRectFor(selection_rect, cursor);
// 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 && cursor.IsLineBreak() &&
+ if (selection_status.start != selection_status.end &&
+ cursor.Current().IsLineBreak() &&
// This is for old compatible that old doesn't paint last br in a page.
- !IsLastBRInPage(*cursor.CurrentLayoutObject())) {
+ !IsLastBRInPage(*cursor.Current().GetLayoutObject())) {
DCHECK(!logical_rect.size.inline_size);
logical_rect.size.inline_size =
- LayoutUnit(cursor.CurrentStyle().GetFont().SpaceWidth());
+ LayoutUnit(cursor.Current().Style().GetFont().SpaceWidth());
}
const LogicalRect line_break_extended_rect =
- cursor.IsLineBreak() ? logical_rect
- : ExpandedSelectionRectForSoftLineBreakIfNeeded(
- logical_rect, cursor, selection_status);
+ cursor.Current().IsLineBreak()
+ ? logical_rect
+ : ExpandedSelectionRectForSoftLineBreakIfNeeded(logical_rect, cursor,
+ selection_status);
const LogicalRect line_height_expanded_rect =
ExpandSelectionRectToLineHeight(line_break_extended_rect, cursor);
const PhysicalRect physical_rect =
@@ -937,8 +945,8 @@ PhysicalRect ComputeLocalSelectionRectForText(
// "ng_selection_painter.cc".
PhysicalRect ComputeLocalSelectionRectForReplaced(
const NGInlineCursor& cursor) {
- DCHECK(cursor.CurrentLayoutObject()->IsLayoutReplaced());
- const PhysicalRect selection_rect = PhysicalRect({}, cursor.CurrentSize());
+ DCHECK(cursor.Current().GetLayoutObject()->IsLayoutReplaced());
+ const PhysicalRect selection_rect = PhysicalRect({}, cursor.Current().Size());
LogicalRect logical_rect = ComputeLogicalRectFor(selection_rect, cursor);
const LogicalRect line_height_expanded_rect =
ExpandSelectionRectToLineHeight(logical_rect, cursor);
@@ -1038,7 +1046,9 @@ PositionWithAffinity NGPaintFragment::PositionForPointInInlineFormattingContext(
const PhysicalOffset& point) const {
DCHECK(PhysicalFragment().IsBlockFlow());
DCHECK(PhysicalFragment().IsBox());
- DCHECK(To<NGPhysicalBoxFragment>(PhysicalFragment()).ChildrenInline());
+ DCHECK(To<NGPhysicalBoxFragment>(PhysicalFragment())
+ .GetLayoutObject()
+ ->ChildrenInline());
const LogicalOffset logical_point = point.ConvertToLogical(
Style().GetWritingMode(), Style().Direction(), Size(),
@@ -1117,7 +1127,6 @@ PositionWithAffinity NGPaintFragment::PositionForPoint(
// We current fall back to legacy for block formatting contexts, so we
// should reach here only for inline formatting contexts.
// TODO(xiaochengh): Do not fall back.
- DCHECK(To<NGPhysicalBoxFragment>(PhysicalFragment()).ChildrenInline());
return PositionForPointInInlineFormattingContext(point);
}
@@ -1131,13 +1140,16 @@ String NGPaintFragment::DebugName() const {
DCHECK(physical_fragment_);
const NGPhysicalFragment& physical_fragment = *physical_fragment_;
if (physical_fragment.IsBox()) {
+ const LayoutObject* layout_object = physical_fragment.GetLayoutObject();
+ if (!layout_object)
+ return "NGPhysicalBoxFragment";
+ // For the root |NGPaintFragment|, return the name of the |LayoutObject| to
+ // ease the transition to |NGFragmentItem|.
+ if (!Parent())
+ return layout_object->DebugName();
name.Append("NGPhysicalBoxFragment");
- if (const LayoutObject* layout_object =
- physical_fragment.GetLayoutObject()) {
- DCHECK(physical_fragment.IsBox());
- name.Append(' ');
- name.Append(layout_object->DebugName());
- }
+ name.Append(' ');
+ name.Append(layout_object->DebugName());
} else if (physical_fragment.IsText()) {
name.Append("NGPhysicalTextFragment '");
name.Append(To<NGPhysicalTextFragment>(physical_fragment).Text());
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 6ec7dadfd82..fd197b7cd86 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
@@ -155,10 +155,13 @@ class CORE_EXPORT NGPaintFragment : public RefCounted<NGPaintFragment>,
bool IsDirty() const { return is_dirty_inline_; }
// Returns offset to its container box for inline and line box fragments.
- const PhysicalOffset& InlineOffsetToContainerBox() const {
+ const PhysicalOffset& OffsetInContainerBlock() const {
DCHECK(PhysicalFragment().IsInline() || PhysicalFragment().IsLineBox());
return inline_offset_to_container_box_;
}
+ const PhysicalRect RectInContainerBlock() const {
+ return PhysicalRect(OffsetInContainerBlock(), Size());
+ }
// InkOverflow of itself, not including contents, in the local coordinate.
PhysicalRect SelfInkOverflow() const;
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_test.cc b/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_test.cc
index c301ed5cc5c..d778705c23d 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_test.cc
@@ -45,6 +45,8 @@ class NGPaintFragmentTest : public RenderingTest,
};
TEST_F(NGPaintFragmentTest, InlineFragmentsFor) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
LoadAhem();
SetBodyInnerHTML(R"HTML(
<!DOCTYPE html>
@@ -70,7 +72,7 @@ TEST_F(NGPaintFragmentTest, InlineFragmentsFor) {
results.AppendRange(it.begin(), it.end());
EXPECT_EQ(1u, results.size());
EXPECT_EQ(text1, results[0]->GetLayoutObject());
- EXPECT_EQ(PhysicalOffset(), results[0]->InlineOffsetToContainerBox());
+ EXPECT_EQ(PhysicalOffset(), results[0]->OffsetInContainerBlock());
results.clear();
it = NGPaintFragment::InlineFragmentsFor(box);
@@ -80,15 +82,15 @@ TEST_F(NGPaintFragmentTest, InlineFragmentsFor) {
EXPECT_EQ(box, results[1]->GetLayoutObject());
EXPECT_EQ(box, results[2]->GetLayoutObject());
- EXPECT_EQ(PhysicalOffset(60, 0), results[0]->InlineOffsetToContainerBox());
+ EXPECT_EQ(PhysicalOffset(60, 0), results[0]->OffsetInContainerBlock());
EXPECT_EQ("789", To<NGPhysicalTextFragment>(
results[0]->FirstChild()->PhysicalFragment())
.Text());
- EXPECT_EQ(PhysicalOffset(0, 10), results[1]->InlineOffsetToContainerBox());
+ EXPECT_EQ(PhysicalOffset(0, 10), results[1]->OffsetInContainerBlock());
EXPECT_EQ("123456789", To<NGPhysicalTextFragment>(
results[1]->FirstChild()->PhysicalFragment())
.Text());
- EXPECT_EQ(PhysicalOffset(0, 20), results[2]->InlineOffsetToContainerBox());
+ EXPECT_EQ(PhysicalOffset(0, 20), results[2]->OffsetInContainerBlock());
EXPECT_EQ("123", To<NGPhysicalTextFragment>(
results[2]->FirstChild()->PhysicalFragment())
.Text());
@@ -102,6 +104,8 @@ TEST_F(NGPaintFragmentTest, InlineFragmentsFor) {
} while (false)
TEST_F(NGPaintFragmentTest, InlineBox) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
LoadAhem();
SetBodyInnerHTML(R"HTML(
<!DOCTYPE html>
@@ -145,6 +149,8 @@ TEST_F(NGPaintFragmentTest, InlineBox) {
}
TEST_F(NGPaintFragmentTest, InlineBoxVerticalRL) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
LoadAhem();
SetBodyInnerHTML(R"HTML(
<!DOCTYPE html>
@@ -189,6 +195,8 @@ TEST_F(NGPaintFragmentTest, InlineBoxVerticalRL) {
}
TEST_F(NGPaintFragmentTest, InlineBoxWithDecorations) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
LoadAhem();
SetBodyInnerHTML(R"HTML(
<!DOCTYPE html>
@@ -244,6 +252,8 @@ TEST_F(NGPaintFragmentTest, InlineBoxWithDecorations) {
}
TEST_F(NGPaintFragmentTest, InlineBoxWithDecorationsVerticalRL) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
LoadAhem();
SetBodyInnerHTML(R"HTML(
<!DOCTYPE html>
@@ -300,6 +310,8 @@ TEST_F(NGPaintFragmentTest, InlineBoxWithDecorationsVerticalRL) {
}
TEST_F(NGPaintFragmentTest, InlineBlock) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
LoadAhem();
SetBodyInnerHTML(R"HTML(
<!DOCTYPE html>
@@ -404,6 +416,8 @@ TEST_F(NGPaintFragmentTest, InlineBlock) {
}
TEST_F(NGPaintFragmentTest, InlineBlockVerticalRL) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
LoadAhem();
SetBodyInnerHTML(R"HTML(
<!DOCTYPE html>
@@ -511,6 +525,8 @@ TEST_F(NGPaintFragmentTest, InlineBlockVerticalRL) {
}
TEST_F(NGPaintFragmentTest, RelativeBlock) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
LoadAhem();
SetBodyInnerHTML(R"HTML(
<!DOCTYPE html>
@@ -550,6 +566,8 @@ TEST_F(NGPaintFragmentTest, RelativeBlock) {
}
TEST_F(NGPaintFragmentTest, RelativeInline) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
LoadAhem();
SetBodyInnerHTML(R"HTML(
<!DOCTYPE html>
@@ -604,6 +622,8 @@ TEST_F(NGPaintFragmentTest, RelativeInline) {
}
TEST_F(NGPaintFragmentTest, RelativeBlockAndInline) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
LoadAhem();
SetBodyInnerHTML(R"HTML(
<!DOCTYPE html>
@@ -659,6 +679,8 @@ TEST_F(NGPaintFragmentTest, RelativeBlockAndInline) {
// Test that OOF should not create a NGPaintFragment.
TEST_F(NGPaintFragmentTest, OutOfFlow) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
SetBodyInnerHTML(R"HTML(
<!DOCTYPE html>
<style>
@@ -683,6 +705,8 @@ TEST_F(NGPaintFragmentTest, OutOfFlow) {
}
TEST_F(NGPaintFragmentTest, MarkLineBoxesDirtyByRemoveBr) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
if (!RuntimeEnabledFeatures::LayoutNGLineCacheEnabled())
return;
SetBodyInnerHTML(
@@ -710,6 +734,8 @@ INSTANTIATE_TEST_SUITE_P(NGPaintFragmentTest,
testing::ValuesIn(inline_child_data));
TEST_P(InlineChildTest, RemoveInlineChild) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
SetBodyInnerHTML(String(R"HTML(
<!DOCTYPE html>
<style>
@@ -735,6 +761,8 @@ TEST_P(InlineChildTest, RemoveInlineChild) {
}
TEST_F(NGPaintFragmentTest, MarkLineBoxesDirtyByRemoveChild) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
if (!RuntimeEnabledFeatures::LayoutNGLineCacheEnabled())
return;
SetBodyInnerHTML(
@@ -750,6 +778,8 @@ TEST_F(NGPaintFragmentTest, MarkLineBoxesDirtyByRemoveChild) {
}
TEST_F(NGPaintFragmentTest, MarkLineBoxesDirtyByRemoveSpanWithBr) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
if (!RuntimeEnabledFeatures::LayoutNGLineCacheEnabled())
return;
SetBodyInnerHTML(
@@ -768,6 +798,8 @@ TEST_F(NGPaintFragmentTest, MarkLineBoxesDirtyByRemoveSpanWithBr) {
// to update |IsDirty|, but NGPaintFragment maybe re-used during the layout. In
// such case, the result is not deterministic.
TEST_F(NGPaintFragmentTest, DISABLED_MarkLineBoxesDirtyByInsertAtStart) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
if (!RuntimeEnabledFeatures::LayoutNGLineCacheEnabled())
return;
SetBodyInnerHTML(
@@ -785,7 +817,7 @@ TEST_F(NGPaintFragmentTest, DISABLED_MarkLineBoxesDirtyByInsertAtStart) {
Element& target = *GetDocument().getElementById("target");
target.parentNode()->insertBefore(Text::Create(GetDocument(), "XYZ"),
&target);
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_TRUE(line1->IsDirty());
EXPECT_FALSE(line2->IsDirty());
@@ -796,6 +828,8 @@ TEST_F(NGPaintFragmentTest, DISABLED_MarkLineBoxesDirtyByInsertAtStart) {
// to update |IsDirty|, but NGPaintFragment maybe re-used during the layout. In
// such case, the result is not deterministic.
TEST_F(NGPaintFragmentTest, DISABLED_MarkLineBoxesDirtyByInsertAtLast) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
if (!RuntimeEnabledFeatures::LayoutNGLineCacheEnabled())
return;
SetBodyInnerHTML(
@@ -812,7 +846,7 @@ TEST_F(NGPaintFragmentTest, DISABLED_MarkLineBoxesDirtyByInsertAtLast) {
ASSERT_TRUE(line3->PhysicalFragment().IsLineBox()) << line3;
Element& target = *GetDocument().getElementById("target");
target.parentNode()->appendChild(Text::Create(GetDocument(), "XYZ"));
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_FALSE(line1->IsDirty());
EXPECT_FALSE(line2->IsDirty());
@@ -823,6 +857,8 @@ TEST_F(NGPaintFragmentTest, DISABLED_MarkLineBoxesDirtyByInsertAtLast) {
// to update |IsDirty|, but NGPaintFragment maybe re-used during the layout. In
// such case, the result is not deterministic.
TEST_F(NGPaintFragmentTest, DISABLED_MarkLineBoxesDirtyByInsertAtMiddle) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
if (!RuntimeEnabledFeatures::LayoutNGLineCacheEnabled())
return;
SetBodyInnerHTML(
@@ -840,7 +876,7 @@ TEST_F(NGPaintFragmentTest, DISABLED_MarkLineBoxesDirtyByInsertAtMiddle) {
Element& target = *GetDocument().getElementById("target");
target.parentNode()->insertBefore(Text::Create(GetDocument(), "XYZ"),
target.nextSibling());
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EXPECT_TRUE(line1->IsDirty());
EXPECT_FALSE(line2->IsDirty());
@@ -848,6 +884,8 @@ TEST_F(NGPaintFragmentTest, DISABLED_MarkLineBoxesDirtyByInsertAtMiddle) {
}
TEST_F(NGPaintFragmentTest, MarkLineBoxesDirtyByTextSetData) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
if (!RuntimeEnabledFeatures::LayoutNGLineCacheEnabled())
return;
SetBodyInnerHTML(
@@ -863,6 +901,8 @@ TEST_F(NGPaintFragmentTest, MarkLineBoxesDirtyByTextSetData) {
}
TEST_F(NGPaintFragmentTest, MarkLineBoxesDirtyWrappedLine) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
if (!RuntimeEnabledFeatures::LayoutNGLineCacheEnabled())
return;
SetBodyInnerHTML(R"HTML(
@@ -887,6 +927,8 @@ TEST_F(NGPaintFragmentTest, MarkLineBoxesDirtyWrappedLine) {
}
TEST_F(NGPaintFragmentTest, MarkLineBoxesDirtyInsideInlineBlock) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
if (!RuntimeEnabledFeatures::LayoutNGLineCacheEnabled())
return;
SetBodyInnerHTML(R"HTML(
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_traversal.cc b/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_traversal.cc
index 9714f1cc1cc..e5c4b783bc7 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_traversal.cc
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_traversal.cc
@@ -272,7 +272,7 @@ bool NGPaintFragmentTraversal::InlineDescendantsRange::Iterator::
bool NGPaintFragmentTraversal::InlineDescendantsRange::Iterator::ShouldTraverse(
const NGPaintFragment& fragment) {
return fragment.PhysicalFragment().IsContainer() &&
- !fragment.PhysicalFragment().IsBlockFormattingContextRoot();
+ !fragment.PhysicalFragment().IsFormattingContextRoot();
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_traversal_test.cc b/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_traversal_test.cc
index e4e8110f82c..78d645533bf 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_traversal_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_traversal_test.cc
@@ -63,6 +63,8 @@ class NGPaintFragmentTraversalTest : public RenderingTest,
};
TEST_F(NGPaintFragmentTraversalTest, MoveToNext) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
SetUpHtml("t", R"HTML(
<div id=t>
line0
@@ -83,6 +85,8 @@ TEST_F(NGPaintFragmentTraversalTest, MoveToNext) {
}
TEST_F(NGPaintFragmentTraversalTest, MoveToNextWithRoot) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
SetUpHtml("t", R"HTML(
<div id=t>
line0
@@ -101,6 +105,8 @@ TEST_F(NGPaintFragmentTraversalTest, MoveToNextWithRoot) {
}
TEST_F(NGPaintFragmentTraversalTest, MoveToPrevious) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
SetUpHtml("t", R"HTML(
<div id=t>
line0
@@ -122,6 +128,8 @@ TEST_F(NGPaintFragmentTraversalTest, MoveToPrevious) {
}
TEST_F(NGPaintFragmentTraversalTest, MoveToPreviousWithRoot) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
SetUpHtml("t", R"HTML(
<div id=t>
line0
@@ -141,6 +149,8 @@ TEST_F(NGPaintFragmentTraversalTest, MoveToPreviousWithRoot) {
}
TEST_F(NGPaintFragmentTraversalTest, MoveTo) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
SetUpHtml("t", R"HTML(
<div id=t>
line0
@@ -162,6 +172,8 @@ TEST_F(NGPaintFragmentTraversalTest, MoveTo) {
}
TEST_F(NGPaintFragmentTraversalTest, MoveToWithRoot) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
SetUpHtml("t", R"HTML(
<div id=t>
line0
@@ -181,6 +193,8 @@ TEST_F(NGPaintFragmentTraversalTest, MoveToWithRoot) {
}
TEST_F(NGPaintFragmentTraversalTest, InlineDescendantsOf) {
+ if (RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled())
+ return;
SetUpHtml("t",
"<ul>"
"<li id=t style='position: absolute'>"
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 4ecd342ed01..23d62f21cb8 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
@@ -64,6 +64,49 @@ inline const NGPaintFragment& AsDisplayItemClient(
return cursor.PaintFragment();
}
+inline PhysicalRect ComputeBoxRect(const NGInlineCursor& cursor,
+ const PhysicalOffset& paint_offset,
+ const PhysicalOffset& parent_offset) {
+ PhysicalRect box_rect = cursor.CurrentItem()->RectInContainerBlock();
+ box_rect.offset.left += paint_offset.left;
+ // We round the y-axis to ensure consistent line heights.
+ box_rect.offset.top =
+ LayoutUnit((paint_offset.top + parent_offset.top).Round()) +
+ (box_rect.offset.top - parent_offset.top);
+ return box_rect;
+}
+
+inline PhysicalRect ComputeBoxRect(const NGTextPainterCursor& cursor,
+ const PhysicalOffset& paint_offset,
+ const PhysicalOffset& parent_offset) {
+ PhysicalRect box_rect = cursor.PaintFragment().Rect();
+ // We round the y-axis to ensure consistent line heights.
+ PhysicalOffset adjusted_paint_offset(paint_offset.left,
+ LayoutUnit(paint_offset.top.Round()));
+ box_rect.offset += adjusted_paint_offset;
+ return box_rect;
+}
+
+inline const NGInlineCursor& InlineCursorForBlockFlow(
+ const NGInlineCursor& cursor,
+ base::Optional<NGInlineCursor>* storage) {
+ if (*storage)
+ return **storage;
+ *storage = cursor;
+ (*storage)->ExpandRootToContainingBlock();
+ return **storage;
+}
+
+inline const NGInlineCursor& InlineCursorForBlockFlow(
+ const NGTextPainterCursor& cursor,
+ base::Optional<NGInlineCursor>* storage) {
+ if (*storage)
+ return **storage;
+ storage->emplace(cursor.RootPaintFragment());
+ (*storage)->MoveTo(cursor.PaintFragment());
+ return **storage;
+}
+
// TODO(yosin): Remove |GetTextFragmentPaintInfo| once the transition to
// |NGFragmentItem| is done. http://crbug.com/982194
inline NGTextFragmentPaintInfo GetTextFragmentPaintInfo(
@@ -98,28 +141,14 @@ inline std::pair<LayoutUnit, LayoutUnit> GetLineLeftAndRightForOffsets(
// |NGFragmentItem| is done. http://crbug.com/982194
inline LayoutSelectionStatus ComputeLayoutSelectionStatus(
const NGInlineCursor& cursor) {
- return cursor.CurrentItem()
- ->GetLayoutObject()
+ return cursor.Current()
+ .GetLayoutObject()
->GetDocument()
.GetFrame()
->Selection()
.ComputeLayoutSelectionStatus(cursor);
}
-inline LayoutSelectionStatus ComputeLayoutSelectionStatus(
- const NGTextPainterCursor& cursor) {
- // Note:: Because of this function is hot, we should not use |NGInlineCursor|
- // on paint fragment which requires traversing ancestors to root.
- NGInlineCursor inline_cursor(cursor.RootPaintFragment());
- inline_cursor.MoveTo(cursor.PaintFragment());
- return cursor.CurrentItem()
- ->GetLayoutObject()
- ->GetDocument()
- .GetFrame()
- ->Selection()
- .ComputeLayoutSelectionStatus(inline_cursor);
-}
-
// TODO(yosin): Remove |ComputeLocalRect| once the transition to
// |NGFragmentItem| is done. http://crbug.com/982194
inline PhysicalRect ComputeLocalRect(const NGFragmentItem& text_item,
@@ -181,19 +210,24 @@ unsigned ClampOffset(unsigned offset, const TextItem& text_fragment) {
}
void PaintRect(GraphicsContext& context,
- const PhysicalOffset& location,
const PhysicalRect& rect,
const Color color) {
if (!color.Alpha())
return;
if (rect.size.IsEmpty())
return;
- const IntRect pixel_snapped_rect =
- PixelSnappedIntRect(PhysicalRect(rect.offset + location, rect.size));
+ const IntRect pixel_snapped_rect = PixelSnappedIntRect(rect);
if (!pixel_snapped_rect.IsEmpty())
context.FillRect(pixel_snapped_rect, color);
}
+void PaintRect(GraphicsContext& context,
+ const PhysicalOffset& location,
+ const PhysicalRect& rect,
+ const Color color) {
+ PaintRect(context, PhysicalRect(rect.offset + location, rect.size), color);
+}
+
template <typename TextItem>
PhysicalRect MarkerRectForForeground(const TextItem& text_fragment,
StringView text,
@@ -310,6 +344,92 @@ void PaintDocumentMarkers(GraphicsContext& context,
}
}
+class SelectionPaintState {
+ STACK_ALLOCATED();
+
+ public:
+ explicit SelectionPaintState(const NGInlineCursor& containing_block)
+ : selection_status_(ComputeLayoutSelectionStatus(containing_block)),
+ containing_block_(containing_block) {}
+
+ const LayoutSelectionStatus& Status() const { return selection_status_; }
+
+ bool ShouldPaintSelectedTextOnly() const { return paint_selected_text_only_; }
+
+ bool ShouldPaintSelectedTextSeparately() const {
+ return paint_selected_text_separately_;
+ }
+
+ bool IsSelectionRectComputed() const { return selection_rect_.has_value(); }
+
+ void ComputeSelectionStyle(const Document& document,
+ const ComputedStyle& style,
+ Node* node,
+ const PaintInfo& paint_info,
+ const TextPaintStyle& text_style) {
+ selection_style_ = TextPainterBase::SelectionPaintingStyle(
+ document, style, node, /*have_selection*/ true, paint_info, text_style);
+ paint_selected_text_only_ =
+ (paint_info.phase == PaintPhase::kSelectionDragImage);
+ paint_selected_text_separately_ =
+ !paint_selected_text_only_ && text_style != selection_style_;
+ }
+
+ void ComputeSelectionRect(const PhysicalOffset& box_offset) {
+ DCHECK(!selection_rect_);
+ selection_rect_ =
+ ComputeLocalSelectionRectForText(containing_block_, selection_status_);
+ selection_rect_->offset += box_offset;
+ }
+
+ // Logic is copied from InlineTextBoxPainter::PaintSelection.
+ // |selection_start| and |selection_end| should be between
+ // [text_fragment.StartOffset(), text_fragment.EndOffset()].
+ void PaintSelectionBackground(GraphicsContext& context,
+ Node* node,
+ const Document& document,
+ const ComputedStyle& style) {
+ const Color color = SelectionBackgroundColor(document, style, node,
+ selection_style_.fill_color);
+ PaintRect(context, *selection_rect_, color);
+ }
+
+ // Paint the selected text only.
+ void PaintSelectedText(NGTextPainter& text_painter,
+ unsigned length,
+ const TextPaintStyle& text_style,
+ DOMNodeId node_id) {
+ text_painter.PaintSelectedText(selection_status_.start,
+ selection_status_.end, length, text_style,
+ selection_style_, *selection_rect_, node_id);
+ }
+
+ // Paint the text except selected parts. Does nothing if all is selected.
+ void PaintBeforeAndAfterSelectedText(NGTextPainter& text_painter,
+ unsigned start_offset,
+ unsigned end_offset,
+ unsigned length,
+ const TextPaintStyle& text_style,
+ DOMNodeId node_id) {
+ if (start_offset < selection_status_.start) {
+ text_painter.Paint(start_offset, selection_status_.start, length,
+ text_style, node_id);
+ }
+ if (selection_status_.end < end_offset) {
+ text_painter.Paint(selection_status_.end, end_offset, length, text_style,
+ node_id);
+ }
+ }
+
+ private:
+ LayoutSelectionStatus selection_status_;
+ TextPaintStyle selection_style_;
+ base::Optional<PhysicalRect> selection_rect_;
+ const NGInlineCursor& containing_block_;
+ bool paint_selected_text_only_;
+ bool paint_selected_text_separately_;
+};
+
} // namespace
StringView NGTextPainterCursor::CurrentText() const {
@@ -323,37 +443,6 @@ const NGPaintFragment& NGTextPainterCursor::RootPaintFragment() const {
}
template <typename Cursor>
-NGTextFragmentPainter<Cursor>::NGTextFragmentPainter(const Cursor& cursor)
- : cursor_(cursor) {}
-
-static PhysicalRect ComputeLocalSelectionRectForText(
- const NGTextPainterCursor& cursor,
- const LayoutSelectionStatus& selection_status) {
- NGInlineCursor inline_cursor(cursor.RootPaintFragment());
- inline_cursor.MoveTo(cursor.PaintFragment());
- return ComputeLocalSelectionRectForText(inline_cursor, selection_status);
-}
-
-// Logic is copied from InlineTextBoxPainter::PaintSelection.
-// |selection_start| and |selection_end| should be between
-// [text_fragment.StartOffset(), text_fragment.EndOffset()].
-template <typename Cursor>
-static void PaintSelection(GraphicsContext& context,
- const Cursor& cursor,
- Node* node,
- const Document& document,
- const ComputedStyle& style,
- Color text_color,
- const PhysicalRect& box_rect,
- const LayoutSelectionStatus& selection_status) {
- const Color color =
- SelectionBackgroundColor(document, style, node, text_color);
- const PhysicalRect selection_rect =
- ComputeLocalSelectionRectForText(cursor, selection_status);
- PaintRect(context, box_rect.offset, selection_rect, color);
-}
-
-template <typename Cursor>
void NGTextFragmentPainter<Cursor>::PaintSymbol(
const LayoutObject* layout_object,
const ComputedStyle& style,
@@ -390,23 +479,23 @@ void NGTextFragmentPainter<Cursor>::Paint(const PaintInfo& paint_info,
GetTextFragmentPaintInfo(cursor_);
const LayoutObject* layout_object = text_item.GetLayoutObject();
const ComputedStyle& style = text_item.Style();
- PhysicalRect box_rect = AsDisplayItemClient(cursor_).Rect();
const Document& document = layout_object->GetDocument();
const bool is_printing = paint_info.IsPrinting();
// Determine whether or not we're selected.
- bool have_selection = !is_printing &&
- paint_info.phase != PaintPhase::kTextClip &&
- layout_object->IsSelected();
- base::Optional<LayoutSelectionStatus> selection_status;
- if (have_selection) {
- selection_status = ComputeLayoutSelectionStatus(cursor_);
- DCHECK_LE(selection_status->start, selection_status->end);
- have_selection = selection_status->start < selection_status->end;
+ base::Optional<SelectionPaintState> selection;
+ if (UNLIKELY(!is_printing && paint_info.phase != PaintPhase::kTextClip &&
+ layout_object->IsSelected())) {
+ const NGInlineCursor& root_inline_cursor =
+ InlineCursorForBlockFlow(cursor_, &inline_cursor_for_block_flow_);
+ selection.emplace(root_inline_cursor);
+ if (!selection->Status().HasValidRange())
+ selection.reset();
}
- if (!have_selection) {
- // When only painting the selection, don't bother to paint if there is none.
- if (paint_info.phase == PaintPhase::kSelection)
+ if (!selection) {
+ // When only painting the selection drag image, don't bother to paint if
+ // there is none.
+ if (paint_info.phase == PaintPhase::kSelectionDragImage)
return;
// Flow controls (line break, tab, <wbr>) need only selection painting.
@@ -426,6 +515,8 @@ void NGTextFragmentPainter<Cursor>::Paint(const PaintInfo& paint_info,
paint_info.phase);
}
+ PhysicalRect box_rect = ComputeBoxRect(cursor_, paint_offset, parent_offset_);
+
if (UNLIKELY(text_item.IsSymbolMarker())) {
// The NGInlineItem of marker might be Split(). To avoid calling PaintSymbol
// multiple times, only call it the first time. For an outside marker, this
@@ -438,15 +529,10 @@ void NGTextFragmentPainter<Cursor>::Paint(const PaintInfo& paint_info,
return;
}
PaintSymbol(layout_object, style, box_rect.size, paint_info,
- paint_offset + box_rect.offset);
+ box_rect.offset);
return;
}
- // We round the y-axis to ensure consistent line heights.
- PhysicalOffset adjusted_paint_offset(paint_offset.left,
- LayoutUnit(paint_offset.top.Round()));
- box_rect.offset += adjusted_paint_offset;
-
GraphicsContext& context = paint_info.context;
// Determine text colors.
@@ -454,11 +540,10 @@ void NGTextFragmentPainter<Cursor>::Paint(const PaintInfo& paint_info,
Node* node = layout_object->GetNode();
TextPaintStyle text_style =
TextPainterBase::TextPaintingStyle(document, style, paint_info);
- TextPaintStyle selection_style = TextPainterBase::SelectionPaintingStyle(
- document, style, node, have_selection, paint_info, text_style);
- bool paint_selected_text_only = (paint_info.phase == PaintPhase::kSelection);
- bool paint_selected_text_separately =
- !paint_selected_text_only && text_style != selection_style;
+ if (UNLIKELY(selection)) {
+ selection->ComputeSelectionStyle(document, style, node, paint_info,
+ text_style);
+ }
// Set our font.
const Font& font = style.GetFont();
@@ -474,17 +559,17 @@ void NGTextFragmentPainter<Cursor>::Paint(const PaintInfo& paint_info,
// before GraphicsContext flip.
// TODO(yoichio): Make NGPhysicalTextFragment::LocalRect and
// NGPaintFragment::ComputeLocalSelectionRectForText logical so that we can
- // paint selection in same fliped dimention as NGTextPainter.
+ // paint selection in same flipped dimension as NGTextPainter.
const DocumentMarkerVector& markers_to_paint =
ComputeMarkersToPaint(node, text_item.IsEllipsis());
- if (paint_info.phase != PaintPhase::kSelection &&
+ if (paint_info.phase != PaintPhase::kSelectionDragImage &&
paint_info.phase != PaintPhase::kTextClip && !is_printing) {
PaintDocumentMarkers(context, text_item, cursor_.CurrentText(),
markers_to_paint, box_rect.offset, style,
DocumentMarkerPaintPhase::kBackground, nullptr);
- if (have_selection) {
- PaintSelection(context, cursor_, node, document, style,
- selection_style.fill_color, box_rect, *selection_status);
+ if (UNLIKELY(selection)) {
+ selection->ComputeSelectionRect(box_rect.offset);
+ selection->PaintSelectionBackground(context, node, document, style);
}
}
@@ -520,7 +605,7 @@ void NGTextFragmentPainter<Cursor>::Paint(const PaintInfo& paint_info,
}
const unsigned length = fragment_paint_info.to - fragment_paint_info.from;
- if (!paint_selected_text_only) {
+ if (!selection || !selection->ShouldPaintSelectedTextOnly()) {
// Paint text decorations except line-through.
DecorationInfo decoration_info;
bool has_line_through_decoration = false;
@@ -549,16 +634,9 @@ void NGTextFragmentPainter<Cursor>::Paint(const PaintInfo& paint_info,
unsigned start_offset = fragment_paint_info.from;
unsigned end_offset = fragment_paint_info.to;
- if (have_selection && paint_selected_text_separately) {
- // Paint only the text that is not selected.
- if (start_offset < selection_status->start) {
- text_painter.Paint(start_offset, selection_status->start, length,
- text_style, node_id);
- }
- if (selection_status->end < end_offset) {
- text_painter.Paint(selection_status->end, end_offset, length,
- text_style, node_id);
- }
+ if (UNLIKELY(selection && selection->ShouldPaintSelectedTextSeparately())) {
+ selection->PaintBeforeAndAfterSelectedText(
+ text_painter, start_offset, end_offset, length, text_style, node_id);
} else {
text_painter.Paint(start_offset, end_offset, length, text_style, node_id);
}
@@ -571,11 +649,12 @@ void NGTextFragmentPainter<Cursor>::Paint(const PaintInfo& paint_info,
}
}
- if (have_selection &&
- (paint_selected_text_only || paint_selected_text_separately)) {
+ if (UNLIKELY(selection && (selection->ShouldPaintSelectedTextOnly() ||
+ selection->ShouldPaintSelectedTextSeparately()))) {
// Paint only the text that is selected.
- text_painter.Paint(selection_status->start, selection_status->end, length,
- selection_style, node_id);
+ if (!selection->IsSelectionRectComputed())
+ selection->ComputeSelectionRect(box_rect.offset);
+ selection->PaintSelectedText(text_painter, length, text_style, node_id);
}
if (paint_info.phase != PaintPhase::kForeground)
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.h b/chromium/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.h
index d1c4ab8c517..beddc4dc958 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_NG_NG_TEXT_FRAGMENT_PAINTER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_NG_NG_TEXT_FRAGMENT_PAINTER_H_
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h"
#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
#include "third_party/blink/renderer/core/style/computed_style_constants.h"
@@ -57,7 +58,10 @@ class NGTextFragmentPainter {
STACK_ALLOCATED();
public:
- explicit NGTextFragmentPainter(const Cursor&);
+ explicit NGTextFragmentPainter(const Cursor& cursor) : cursor_(cursor) {}
+ NGTextFragmentPainter(const Cursor& cursor,
+ const PhysicalOffset& parent_offset)
+ : cursor_(cursor), parent_offset_(parent_offset) {}
void Paint(const PaintInfo&, const PhysicalOffset& paint_offset);
@@ -80,6 +84,8 @@ class NGTextFragmentPainter {
const PhysicalOffset& paint_offset);
const Cursor& cursor_;
+ PhysicalOffset parent_offset_;
+ base::Optional<NGInlineCursor> inline_cursor_for_block_flow_;
};
extern template class NGTextFragmentPainter<NGTextPainterCursor>;
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter_test.cc b/chromium/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter_test.cc
index 0dfa168b059..e1d5ac5fa23 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter_test.cc
@@ -6,6 +6,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h"
#include "third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
@@ -39,14 +40,14 @@ TEST_P(NGTextFragmentPainterTest, TestTextStyle) {
const LayoutNGBlockFlow& block_flow = ToLayoutNGBlockFlow(container);
InvalidateAll(RootPaintController());
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
Paint(IntRect(0, 0, 640, 480));
- const NGPaintFragment& root_fragment = *block_flow.PaintFragment();
- EXPECT_EQ(1u, root_fragment.Children().size());
- const NGPaintFragment& line_box_fragment = *root_fragment.FirstChild();
- EXPECT_EQ(1u, line_box_fragment.Children().size());
- const NGPaintFragment& text_fragment = *line_box_fragment.FirstChild();
+ NGInlineCursor cursor;
+ cursor.MoveTo(*block_flow.FirstChild());
+ const DisplayItemClient& text_fragment =
+ *cursor.Current().GetDisplayItemClient();
EXPECT_THAT(RootPaintController().GetDisplayItemList(),
ElementsAre(IsSameId(&ViewScrollingBackgroundClient(),
@@ -65,4 +66,21 @@ TEST_P(NGTextFragmentPainterTest, LineBreak) {
EXPECT_EQ(6u, RootPaintController().GetDisplayItemList().size());
}
+TEST_P(NGTextFragmentPainterTest, DegenerateUnderlineIntercepts) {
+ SetBodyInnerHTML(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ span {
+ font-size: 20px;
+ text-decoration: underline;
+ }
+ </style>
+ <span style="letter-spacing: -1e9999em;">a|b|c d{e{f{</span>
+ <span style="letter-spacing: 1e9999em;">a|b|c d{e{f{</span>
+ )HTML");
+ UpdateAllLifecyclePhasesForTest();
+ // Test for https://crbug.com/1043753: the underline intercepts are infinite
+ // due to letter spacing and this test passes if that does not cause a crash.
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_text_painter.cc b/chromium/third_party/blink/renderer/core/paint/ng/ng_text_painter.cc
index 431ff2304ba..bb35f02d633 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_text_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_text_painter.cc
@@ -40,6 +40,52 @@ void NGTextPainter::Paint(unsigned start_offset,
}
}
+// This function paints text twice with different styles in order to:
+// 1. Paint glyphs inside of |selection_rect| using |selection_style|, and
+// outside using |text_style|.
+// 2. Paint parts of a ligature glyph.
+void NGTextPainter::PaintSelectedText(unsigned start_offset,
+ unsigned end_offset,
+ unsigned length,
+ const TextPaintStyle& text_style,
+ const TextPaintStyle& selection_style,
+ const PhysicalRect& selection_rect,
+ DOMNodeId node_id) {
+ if (!fragment_paint_info_.shape_result)
+ return;
+
+ // Use fast path if all glyphs fit in |selection_rect|. Note |text_bounds_| is
+ // the bounds of all glyphs of this text fragment, including characters before
+ // |start_offset| or after |end_offset|. Computing exact bounds is expensive
+ // that this code only checks bounds of all glyphs.
+ if (selection_rect.Contains(text_bounds_)) {
+ Paint(start_offset, end_offset, length, selection_style, node_id);
+ return;
+ }
+
+ // Adjust start/end offset when they are in the middle of a ligature. e.g.,
+ // when |start_offset| is between a ligature of "fi", it needs to be adjusted
+ // to before "f".
+ fragment_paint_info_.shape_result->ExpandRangeToIncludePartialGlyphs(
+ &start_offset, &end_offset);
+
+ // Because only a part of the text glyph can be selected, we need to draw
+ // the selection twice. First, draw the glyphs outside the selection area,
+ // with the original style.
+ FloatRect float_selection_rect(selection_rect);
+ {
+ GraphicsContextStateSaver state_saver(graphics_context_);
+ graphics_context_.ClipOut(float_selection_rect);
+ Paint(start_offset, end_offset, length, text_style, node_id);
+ }
+ // Then draw the glyphs inside the selection area, with the selection style.
+ {
+ GraphicsContextStateSaver state_saver(graphics_context_);
+ graphics_context_.Clip(float_selection_rect);
+ Paint(start_offset, end_offset, length, selection_style, node_id);
+ }
+}
+
template <NGTextPainter::PaintInternalStep step>
void NGTextPainter::PaintInternalFragment(
unsigned from,
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_text_painter.h b/chromium/third_party/blink/renderer/core/paint/ng/ng_text_painter.h
index dc8c2bd5f19..b9b96936f54 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_text_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_text_painter.h
@@ -44,6 +44,14 @@ class CORE_EXPORT NGTextPainter : public TextPainterBase {
const TextPaintStyle&,
DOMNodeId);
+ void PaintSelectedText(unsigned start_offset,
+ unsigned end_offset,
+ unsigned length,
+ const TextPaintStyle& text_style,
+ const TextPaintStyle& selection_style,
+ const PhysicalRect& selection_rect,
+ DOMNodeId node_id);
+
private:
template <PaintInternalStep step>
void PaintInternalFragment(unsigned from, unsigned to, DOMNodeId node_id);
diff --git a/chromium/third_party/blink/renderer/core/paint/nine_piece_image_painter.cc b/chromium/third_party/blink/renderer/core/paint/nine_piece_image_painter.cc
index b903af4b71d..ca91cbaff74 100644
--- a/chromium/third_party/blink/renderer/core/paint/nine_piece_image_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/nine_piece_image_painter.cc
@@ -177,8 +177,9 @@ bool NinePieceImagePainter::Paint(GraphicsContext& graphics_context,
// is one. For generated images, the actual image data (gradient stops, etc.)
// are scaled to effective zoom instead so we must take care not to cause
// scale of them again.
- IntSize image_size = RoundedIntSize(style_image->ImageSize(
- document, 1, border_image_rect.size.ToLayoutSize()));
+ IntSize image_size = RoundedIntSize(
+ style_image->ImageSize(document, 1, border_image_rect.size.ToLayoutSize(),
+ kRespectImageOrientation));
scoped_refptr<Image> image =
style_image->GetImage(observer, document, style, FloatSize(image_size));
if (!image)
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 d7e46c2cda9..e3f8aeb9891 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
@@ -228,9 +228,6 @@ ObjectPaintInvalidatorWithContext::ComputePaintInvalidationReason() {
context_.fragment_data->VisualRect().IsEmpty())
return PaintInvalidationReason::kNone;
- if (object_.PaintedOutputOfObjectHasNoEffectRegardlessOfSize())
- return PaintInvalidationReason::kNone;
-
// Force full paint invalidation if the outline may be affected by descendants
// and this object is marked for checking paint invalidation for any reason.
if (object_.OutlineMayBeAffectedByDescendants() ||
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 179caace7b3..a84527533ee 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
@@ -56,7 +56,9 @@ TEST_F(ObjectPaintInvalidatorTest,
style='position: relative'></div>
<div
id='non-stacked-layered-child-of-composited-non-stacking-context'
- style='overflow: scroll'></div>
+ style='overflow: scroll'>
+ <div style="height:40px"></div>
+ </div>
</div>
</div>
)HTML");
@@ -326,7 +328,8 @@ TEST_F(ObjectPaintInvalidatorTest, InvalidatePaintRectangle) {
EXPECT_TRUE(target->ShouldCheckForPaintInvalidation());
EXPECT_TRUE(IsValidDisplayItemClient(target));
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_EQ(PhysicalRect(), target->PartialInvalidationLocalRect());
EXPECT_EQ(IntRect(18, 18, 80, 80), target->PartialInvalidationVisualRect());
EXPECT_FALSE(IsValidDisplayItemClient(target));
@@ -334,7 +337,8 @@ TEST_F(ObjectPaintInvalidatorTest, InvalidatePaintRectangle) {
target->InvalidatePaintRectangle(PhysicalRect(30, 30, 50, 80));
EXPECT_EQ(PhysicalRect(30, 30, 50, 80),
target->PartialInvalidationLocalRect());
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
// PartialInvalidationVisualRect should accumulate until painting.
EXPECT_EQ(IntRect(18, 18, 80, 100), target->PartialInvalidationVisualRect());
diff --git a/chromium/third_party/blink/renderer/core/paint/object_painter.cc b/chromium/third_party/blink/renderer/core/paint/object_painter.cc
index 42c8caf0167..633e6518e9e 100644
--- a/chromium/third_party/blink/renderer/core/paint/object_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/object_painter.cc
@@ -99,10 +99,10 @@ void ObjectPainter::AddURLRectIfNeeded(const PaintInfo& paint_info,
}
void ObjectPainter::PaintAllPhasesAtomically(const PaintInfo& paint_info) {
- // Pass kSelection and kTextClip to the descendants so that
+ // Pass kSelectionDragImage and kTextClip to the descendants so that
// they will paint for selection and text clip respectively. We don't need
// complete painting for these phases.
- if (paint_info.phase == PaintPhase::kSelection ||
+ if (paint_info.phase == PaintPhase::kSelectionDragImage ||
paint_info.phase == PaintPhase::kTextClip) {
layout_object_.Paint(paint_info);
return;
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 f165ceeecf8..096fd2913e1 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
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/paint/object_painter_base.h"
+#include "base/optional.h"
#include "third_party/blink/renderer/core/paint/box_border_painter.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
#include "third_party/blink/renderer/core/style/border_edge.h"
@@ -12,6 +13,8 @@
#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/graphics/skia/skia_utils.h"
+#include "ui/base/ui_base_features.h"
+#include "ui/native_theme/native_theme.h"
namespace blink {
@@ -486,6 +489,46 @@ void DrawSolidBoxSide(GraphicsContext& graphics_context,
FillQuad(graphics_context, quad, color, antialias);
}
+float GetFocusRingBorderRadius(const ComputedStyle& style) {
+ // Default style is border-radius equal to outline width.
+ float border_radius = style.GetOutlineStrokeWidthForFocusRing();
+
+ if (::features::IsFormControlsRefreshEnabled() && !style.HasAuthorBorder() &&
+ style.HasEffectiveAppearance()) {
+ // For the elements that have not been styled and that have an appearance,
+ // the focus ring should use the same border radius as the one used for
+ // drawing the element.
+ base::Optional<ui::NativeTheme::Part> part;
+ switch (style.EffectiveAppearance()) {
+ case kCheckboxPart:
+ part = ui::NativeTheme::kCheckbox;
+ break;
+ case kRadioPart:
+ part = ui::NativeTheme::kRadio;
+ break;
+ case kPushButtonPart:
+ case kSquareButtonPart:
+ case kButtonPart:
+ part = ui::NativeTheme::kPushButton;
+ break;
+ case kTextFieldPart:
+ case kTextAreaPart:
+ case kSearchFieldPart:
+ part = ui::NativeTheme::kTextField;
+ break;
+ default:
+ break;
+ }
+ if (part) {
+ return ui::NativeTheme::GetInstanceForWeb()->GetBorderRadiusForPart(
+ part.value(), style.Width().GetFloatValue(),
+ style.Height().GetFloatValue(), style.EffectiveZoom());
+ }
+ }
+
+ return border_radius;
+}
+
} // anonymous namespace
void ObjectPainterBase::PaintOutlineRects(
@@ -498,9 +541,17 @@ void ObjectPainterBase::PaintOutlineRects(
Color color = style.VisitedDependentColor(GetCSSPropertyOutlineColor());
if (style.OutlineStyleIsAuto()) {
+ // Logic in draw focus ring is dependent on whether the border is large
+ // enough to have an inset outline. Use the smallest border edge for that
+ // test.
+ float min_border_width =
+ std::min(std::min(style.BorderTopWidth(), style.BorderBottomWidth()),
+ std::min(style.BorderLeftWidth(), style.BorderRightWidth()));
+ float border_radius = GetFocusRingBorderRadius(style);
paint_info.context.DrawFocusRing(
pixel_snapped_outline_rects, style.GetOutlineStrokeWidthForFocusRing(),
- style.OutlineOffset(), color,
+ style.OutlineOffset(), style.GetDefaultOffsetForFocusRing(),
+ border_radius, min_border_width, color,
LayoutTheme::GetTheme().IsFocusRingOutset());
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 c0b3b43e62d..773e223519d 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
@@ -163,6 +163,20 @@ TEST_P(PaintAndRasterInvalidationTest, IncrementalInvalidationMixed) {
GetDocument().View()->SetTracksRasterInvalidations(false);
}
+TEST_P(PaintAndRasterInvalidationTest, ResizeEmptyContent) {
+ SetUpHTML(*this);
+ Element* target = GetDocument().getElementById("target");
+ // Make the box empty.
+ target->setAttribute(html_names::kClassAttr, "");
+ UpdateAllLifecyclePhasesForTest();
+
+ GetDocument().View()->SetTracksRasterInvalidations(true);
+ target->setAttribute(html_names::kStyleAttr, "width: 100px; height: 80px");
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_FALSE(GetRasterInvalidationTracking()->HasInvalidations());
+ GetDocument().View()->SetTracksRasterInvalidations(false);
+}
+
TEST_P(PaintAndRasterInvalidationTest, SubpixelVisualRectChagne) {
SetUpHTML(*this);
Element* target = GetDocument().getElementById("target");
@@ -286,7 +300,7 @@ TEST_P(PaintAndRasterInvalidationTest, ResizeRotatedChild) {
Element* target = GetDocument().getElementById("target");
target->setAttribute(html_names::kStyleAttr,
"transform: rotate(45deg); width: 200px");
- target->SetInnerHTMLFromString(
+ target->setInnerHTML(
"<div id=child style='width: 50px; height: 50px; background: "
"red'></div>");
UpdateAllLifecyclePhasesForTest();
@@ -315,11 +329,6 @@ TEST_P(PaintAndRasterInvalidationTest, CompositedLayoutViewResize) {
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(kBackgroundPaintInScrollingContents,
GetLayoutView().GetBackgroundPaintLocation());
- if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
- const auto* mapping = GetLayoutView().Layer()->GetCompositedLayerMapping();
- EXPECT_TRUE(mapping->BackgroundPaintsOntoScrollingContentsLayer());
- EXPECT_FALSE(mapping->BackgroundPaintsOntoGraphicsLayer());
- }
// Resize the content.
GetDocument().View()->SetTracksRasterInvalidations(true);
@@ -350,11 +359,6 @@ TEST_P(PaintAndRasterInvalidationTest, CompositedLayoutViewGradientResize) {
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(kBackgroundPaintInScrollingContents,
GetLayoutView().GetBackgroundPaintLocation());
- if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
- const auto* mapping = GetLayoutView().Layer()->GetCompositedLayerMapping();
- EXPECT_TRUE(mapping->BackgroundPaintsOntoScrollingContentsLayer());
- EXPECT_FALSE(mapping->BackgroundPaintsOntoGraphicsLayer());
- }
// Resize the content.
GetDocument().View()->SetTracksRasterInvalidations(true);
@@ -395,9 +399,15 @@ TEST_P(PaintAndRasterInvalidationTest, NonCompositedLayoutViewResize) {
UpdateAllLifecyclePhasesForTest();
Element* iframe = GetDocument().getElementById("iframe");
Element* content = ChildDocument().getElementById("content");
- EXPECT_EQ(GetLayoutView(),
- content->GetLayoutObject()->ContainerForPaintInvalidation());
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ EXPECT_EQ(GetLayoutView(),
+ content->GetLayoutObject()->ContainerForPaintInvalidation());
+ }
EXPECT_EQ(kBackgroundPaintInScrollingContents,
+ content->GetLayoutObject()
+ ->View()
+ ->ComputeBackgroundPaintLocationIfComposited());
+ EXPECT_EQ(kBackgroundPaintInGraphicsLayer,
content->GetLayoutObject()->View()->GetBackgroundPaintLocation());
// Resize the content.
@@ -414,11 +424,7 @@ TEST_P(PaintAndRasterInvalidationTest, NonCompositedLayoutViewResize) {
UpdateAllLifecyclePhasesForTest();
// The iframe doesn't have anything visible by itself, so we only issue
// raster invalidation for the frame contents.
- const auto* iframe_layout_view = content->GetLayoutObject()->View();
- const auto* client = RuntimeEnabledFeatures::CompositeAfterPaintEnabled()
- ? &iframe_layout_view->GetScrollableArea()
- ->GetScrollingBackgroundDisplayItemClient()
- : iframe_layout_view;
+ const auto* client = content->GetLayoutObject()->View();
EXPECT_THAT(GetRasterInvalidationTracking()->Invalidations(),
UnorderedElementsAre(RasterInvalidationInfo{
client, client->DebugName(), IntRect(0, 100, 100, 100),
@@ -426,6 +432,31 @@ TEST_P(PaintAndRasterInvalidationTest, NonCompositedLayoutViewResize) {
GetDocument().View()->SetTracksRasterInvalidations(false);
}
+TEST_P(PaintAndRasterInvalidationTest, FullInvalidationWithHTMLTransform) {
+ GetDocument().documentElement()->setAttribute(html_names::kStyleAttr,
+ "transform: scale(0.5)");
+ const DisplayItemClient* client =
+ &GetDocument()
+ .View()
+ ->GetLayoutView()
+ ->GetScrollableArea()
+ ->GetScrollingBackgroundDisplayItemClient();
+ UpdateAllLifecyclePhasesForTest();
+
+ GetDocument().View()->SetTracksRasterInvalidations(true);
+ GetDocument().View()->Resize(WebSize(500, 500));
+ UpdateAllLifecyclePhasesForTest();
+
+ EXPECT_THAT(GetRasterInvalidationTracking()->Invalidations(),
+ UnorderedElementsAre(
+ RasterInvalidationInfo{client, client->DebugName(),
+ IntRect(0, 0, 500, 500),
+ PaintInvalidationReason::kBackground},
+ RasterInvalidationInfo{
+ client, client->DebugName(), IntRect(0, 0, 500, 500),
+ PaintInvalidationReason::kPaintProperty}));
+}
+
TEST_P(PaintAndRasterInvalidationTest, NonCompositedLayoutViewGradientResize) {
SetBodyInnerHTML(R"HTML(
<style>
@@ -448,36 +479,20 @@ TEST_P(PaintAndRasterInvalidationTest, NonCompositedLayoutViewGradientResize) {
UpdateAllLifecyclePhasesForTest();
Element* iframe = GetDocument().getElementById("iframe");
Element* content = ChildDocument().getElementById("content");
- LayoutView* frame_layout_view = content->GetLayoutObject()->View();
- EXPECT_EQ(GetLayoutView(),
- content->GetLayoutObject()->ContainerForPaintInvalidation());
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ EXPECT_EQ(GetLayoutView(),
+ content->GetLayoutObject()->ContainerForPaintInvalidation());
+ }
// Resize the content.
GetDocument().View()->SetTracksRasterInvalidations(true);
content->setAttribute(html_names::kStyleAttr, "height: 500px");
UpdateAllLifecyclePhasesForTest();
- const auto* client = RuntimeEnabledFeatures::CompositeAfterPaintEnabled()
- ? &frame_layout_view->GetScrollableArea()
- ->GetScrollingBackgroundDisplayItemClient()
- : frame_layout_view;
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
- // The duplication is because we invalidated both the old visual rect and
- // the new visual rect of the scrolling background display item which
- // changed size, and then both mapped to the same rect in the layer.
- EXPECT_THAT(GetRasterInvalidationTracking()->Invalidations(),
- UnorderedElementsAre(
- RasterInvalidationInfo{
- client, client->DebugName(), IntRect(0, 0, 100, 100),
- PaintInvalidationReason::kBackground},
- RasterInvalidationInfo{
- client, client->DebugName(), IntRect(0, 0, 100, 100),
- PaintInvalidationReason::kBackground}));
- } else {
- EXPECT_THAT(GetRasterInvalidationTracking()->Invalidations(),
- UnorderedElementsAre(RasterInvalidationInfo{
- client, client->DebugName(), IntRect(0, 0, 100, 100),
- PaintInvalidationReason::kBackground}));
- }
+ const auto* client = content->GetLayoutObject()->View();
+ EXPECT_THAT(GetRasterInvalidationTracking()->Invalidations(),
+ UnorderedElementsAre(RasterInvalidationInfo{
+ client, client->DebugName(), IntRect(0, 0, 100, 100),
+ PaintInvalidationReason::kBackground}));
GetDocument().View()->SetTracksRasterInvalidations(false);
// Resize the iframe.
@@ -499,7 +514,8 @@ TEST_P(PaintAndRasterInvalidationTest,
Element* target = GetDocument().getElementById("target");
target->setAttribute(html_names::kClassAttr,
"solid composited scroll local-attachment border");
- target->SetInnerHTMLFromString(
+ UpdateAllLifecyclePhasesForTest();
+ target->setInnerHTML(
"<div id=child style='width: 500px; height: 500px'></div>",
ASSERT_NO_EXCEPTION);
Element* child = GetDocument().getElementById("child");
@@ -508,11 +524,6 @@ TEST_P(PaintAndRasterInvalidationTest,
auto* target_obj = ToLayoutBoxModelObject(target->GetLayoutObject());
EXPECT_EQ(kBackgroundPaintInScrollingContents,
target_obj->GetBackgroundPaintLocation());
- if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
- const auto* mapping = target_obj->Layer()->GetCompositedLayerMapping();
- EXPECT_TRUE(mapping->BackgroundPaintsOntoScrollingContentsLayer());
- EXPECT_FALSE(mapping->BackgroundPaintsOntoGraphicsLayer());
- }
auto container_raster_invalidation_tracking =
[&]() -> const RasterInvalidationTracking* {
@@ -566,7 +577,7 @@ TEST_P(PaintAndRasterInvalidationTest,
Element* target = GetDocument().getElementById("target");
target->setAttribute(html_names::kClassAttr,
"gradient composited scroll local-attachment border");
- target->SetInnerHTMLFromString(
+ target->setInnerHTML(
"<div id='child' style='width: 500px; height: 500px'></div>",
ASSERT_NO_EXCEPTION);
Element* child = GetDocument().getElementById("child");
@@ -597,11 +608,6 @@ TEST_P(PaintAndRasterInvalidationTest,
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(kBackgroundPaintInScrollingContents,
target_obj->GetBackgroundPaintLocation());
- if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
- const auto* mapping = target_obj->Layer()->GetCompositedLayerMapping();
- EXPECT_TRUE(mapping->BackgroundPaintsOntoScrollingContentsLayer());
- EXPECT_FALSE(mapping->BackgroundPaintsOntoGraphicsLayer());
- }
// No invalidation on the container layer.
EXPECT_FALSE(container_raster_invalidation_tracking()->HasInvalidations());
@@ -635,14 +641,18 @@ TEST_P(PaintAndRasterInvalidationTest,
Element* target = GetDocument().getElementById("target");
auto* object = target->GetLayoutObject();
target->setAttribute(html_names::kClassAttr, "solid local-attachment scroll");
- target->SetInnerHTMLFromString(
+ target->setInnerHTML(
"<div id=child style='width: 500px; height: 500px'></div>",
ASSERT_NO_EXCEPTION);
Element* child = GetDocument().getElementById("child");
UpdateAllLifecyclePhasesForTest();
- EXPECT_EQ(&GetLayoutView(), object->ContainerForPaintInvalidation());
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ EXPECT_EQ(&GetLayoutView(), object->ContainerForPaintInvalidation());
EXPECT_EQ(kBackgroundPaintInScrollingContents,
- ToLayoutBoxModelObject(object)->GetBackgroundPaintLocation());
+ ToLayoutBoxModelObject(object)
+ ->ComputeBackgroundPaintLocationIfComposited());
+ EXPECT_EQ(kBackgroundPaintInGraphicsLayer,
+ object->GetBackgroundPaintLocation());
// Resize the content.
GetDocument().View()->SetTracksRasterInvalidations(true);
@@ -671,8 +681,8 @@ TEST_P(PaintAndRasterInvalidationTest, CompositedSolidBackgroundResize) {
SetUpHTML(*this);
Element* target = GetDocument().getElementById("target");
target->setAttribute(html_names::kClassAttr, "solid composited scroll");
- target->SetInnerHTMLFromString("<div style='height: 500px'></div>",
- ASSERT_NO_EXCEPTION);
+ target->setInnerHTML("<div style='height: 500px'></div>",
+ ASSERT_NO_EXCEPTION);
UpdateAllLifecyclePhasesForTest();
// Resize the scroller.
@@ -685,11 +695,6 @@ TEST_P(PaintAndRasterInvalidationTest, CompositedSolidBackgroundResize) {
EXPECT_EQ(
kBackgroundPaintInScrollingContents | kBackgroundPaintInGraphicsLayer,
target_object->GetBackgroundPaintLocation());
- if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
- const auto* mapping = target_object->Layer()->GetCompositedLayerMapping();
- EXPECT_TRUE(mapping->BackgroundPaintsOntoScrollingContentsLayer());
- EXPECT_TRUE(mapping->BackgroundPaintsOntoGraphicsLayer());
- }
const auto* contents_raster_invalidation_tracking =
RuntimeEnabledFeatures::CompositeAfterPaintEnabled()
@@ -767,15 +772,19 @@ TEST_P(PaintAndRasterInvalidationTest,
Element* iframe = GetDocument().getElementById("iframe");
LayoutView* child_layout_view = ChildDocument().GetLayoutView();
- EXPECT_EQ(GetDocument().GetLayoutView(),
- &child_layout_view->ContainerForPaintInvalidation());
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ EXPECT_EQ(GetDocument().GetLayoutView(),
+ &child_layout_view->ContainerForPaintInvalidation());
+ }
EXPECT_EQ(IntRect(0, 0, 100, 100),
child_layout_view->FirstFragment().VisualRect());
iframe->setAttribute(html_names::kStyleAttr, "border: 20px solid blue");
UpdateAllLifecyclePhasesForTest();
- EXPECT_EQ(GetDocument().GetLayoutView(),
- &child_layout_view->ContainerForPaintInvalidation());
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ EXPECT_EQ(GetDocument().GetLayoutView(),
+ &child_layout_view->ContainerForPaintInvalidation());
+ }
EXPECT_EQ(IntRect(0, 0, 100, 100),
child_layout_view->FirstFragment().VisualRect());
}
@@ -927,7 +936,8 @@ TEST_P(PaintAndRasterInvalidationTest, PaintPropertyChange) {
auto* layer = ToLayoutBoxModelObject(object)->Layer();
GetDocument().View()->SetTracksRasterInvalidations(true);
target->setAttribute(html_names::kStyleAttr, "transform: scale(3)");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_FALSE(layer->SelfNeedsRepaint());
const auto* transform =
object->FirstFragment().PaintProperties()->Transform();
@@ -963,7 +973,8 @@ TEST_P(PaintAndRasterInvalidationTest, ResizeContainerOfFixedSizeSVG) {
GetDocument().View()->SetTracksRasterInvalidations(true);
target->setAttribute(html_names::kStyleAttr, "width: 200px; height: 200px");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
// We don't invalidate paint of the SVG rect.
EXPECT_TRUE(static_cast<const DisplayItemClient*>(rect)->IsValid());
@@ -1115,7 +1126,8 @@ TEST_F(PaintInvalidatorCustomClientTest,
ResetInvalidationRecorded();
target->setAttribute(html_names::kStyleAttr, "opacity: 0.98");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(
GetDocument().View()->GetLayoutView()->Layer()->DescendantNeedsRepaint());
EXPECT_TRUE(InvalidationRecorded());
@@ -1123,7 +1135,8 @@ TEST_F(PaintInvalidatorCustomClientTest,
ResetInvalidationRecorded();
// Let PrePaintTreeWalk do something instead of no-op.
GetDocument().View()->SetNeedsPaintPropertyUpdate();
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
// The layer DescendantNeedsRepaint flag is only cleared after paint.
EXPECT_TRUE(
GetDocument().View()->GetLayoutView()->Layer()->DescendantNeedsRepaint());
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 d9c7752ecf8..cafc50592fd 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
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/layout/layout_text.h"
#include "third_party/blink/renderer/core/layout/line/inline_text_box.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h"
#include "third_party/blink/renderer/core/page/focus_controller.h"
#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
#include "third_party/blink/renderer/core/paint/object_paint_properties.h"
@@ -58,37 +59,39 @@ TEST_P(PaintControllerPaintTest, InlineRelayout) {
auto& div_block =
*To<LayoutBlock>(GetDocument().body()->firstChild()->GetLayoutObject());
LayoutText& text = *ToLayoutText(div_block.FirstChild());
- DisplayItemClient& first_text_box =
- text.FirstInlineFragment()
- ? (DisplayItemClient&)*text.FirstInlineFragment()
- : (DisplayItemClient&)*text.FirstTextBox();
+ const DisplayItemClient* first_text_box = text.FirstTextBox();
+ if (text.IsInLayoutNGInlineFormattingContext()) {
+ NGInlineCursor cursor;
+ cursor.MoveTo(text);
+ first_text_box = cursor.Current().GetDisplayItemClient();
+ }
EXPECT_THAT(RootPaintController().GetDisplayItemList(),
ElementsAre(IsSameId(&ViewScrollingBackgroundClient(),
kDocumentBackgroundType),
- IsSameId(&first_text_box, kForegroundType)));
+ IsSameId(first_text_box, kForegroundType)));
div.setAttribute(html_names::kStyleAttr, "width: 10px; height: 200px");
UpdateAllLifecyclePhasesForTest();
LayoutText& new_text = *ToLayoutText(div_block.FirstChild());
- DisplayItemClient& new_first_text_box =
- new_text.FirstInlineFragment()
- ? (DisplayItemClient&)*new_text.FirstInlineFragment()
- : (DisplayItemClient&)*text.FirstTextBox();
- DisplayItemClient& second_text_box =
- new_text.FirstInlineFragment()
- ? (DisplayItemClient&)*NGPaintFragment::
- TraverseNextForSameLayoutObject::Next(
- new_text.FirstInlineFragment())
- : (DisplayItemClient&)*new_text.FirstTextBox()
- ->NextForSameLayoutObject();
+ const DisplayItemClient* new_first_text_box = text.FirstTextBox();
+ const DisplayItemClient* second_text_box = nullptr;
+ if (!text.IsInLayoutNGInlineFormattingContext()) {
+ second_text_box = new_text.FirstTextBox()->NextForSameLayoutObject();
+ } else {
+ NGInlineCursor cursor;
+ cursor.MoveTo(text);
+ new_first_text_box = cursor.Current().GetDisplayItemClient();
+ cursor.MoveToNextForSameLayoutObject();
+ second_text_box = cursor.Current().GetDisplayItemClient();
+ }
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),
+ IsSameId(second_text_box, kForegroundType)));
}
TEST_P(PaintControllerPaintTest, ChunkIdClientCacheFlag) {
@@ -156,21 +159,47 @@ TEST_P(PaintControllerPaintTestForCAP, FrameScrollingContents) {
EXPECT_THAT(
RootPaintController().GetDisplayItemList(),
ElementsAre(
- IsSameId(&GetLayoutView(), kScrollHitTestType),
IsSameId(&ViewScrollingBackgroundClient(), kDocumentBackgroundType),
IsSameId(&div1, kBackgroundType), IsSameId(&div2, kBackgroundType)));
+ HitTestData view_scroll_hit_test;
+ view_scroll_hit_test.scroll_translation =
+ &GetLayoutView().FirstFragment().ContentsProperties().Transform();
+ view_scroll_hit_test.scroll_hit_test_rect = IntRect(0, 0, 800, 600);
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(
+ IsPaintChunk(
+ 0, 0,
+ PaintChunk::Id(GetLayoutView(), DisplayItem::kScrollHitTest),
+ GetLayoutView().FirstFragment().LocalBorderBoxProperties(),
+ &view_scroll_hit_test, IntRect(0, 0, 800, 600)),
+ IsPaintChunk(0, 3,
+ PaintChunk::Id(ViewScrollingBackgroundClient(),
+ DisplayItem::kDocumentBackground),
+ GetLayoutView().FirstFragment().ContentsProperties())));
GetDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(5000, 5000), kProgrammaticScroll);
+ ScrollOffset(5000, 5000), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
EXPECT_THAT(
RootPaintController().GetDisplayItemList(),
ElementsAre(
- IsSameId(&GetLayoutView(), kScrollHitTestType),
IsSameId(&ViewScrollingBackgroundClient(), kDocumentBackgroundType),
IsSameId(&div2, kBackgroundType), IsSameId(&div3, kBackgroundType),
IsSameId(&div4, kBackgroundType)));
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(
+ IsPaintChunk(
+ 0, 0,
+ PaintChunk::Id(GetLayoutView(), DisplayItem::kScrollHitTest),
+ GetLayoutView().FirstFragment().LocalBorderBoxProperties(),
+ &view_scroll_hit_test, IntRect(0, 0, 800, 600)),
+ IsPaintChunk(0, 4,
+ PaintChunk::Id(ViewScrollingBackgroundClient(),
+ DisplayItem::kDocumentBackground),
+ GetLayoutView().FirstFragment().ContentsProperties())));
}
TEST_P(PaintControllerPaintTestForCAP, BlockScrollingNonLayeredContents) {
@@ -201,11 +230,34 @@ TEST_P(PaintControllerPaintTestForCAP, BlockScrollingNonLayeredContents) {
RootPaintController().GetDisplayItemList(),
ElementsAre(
IsSameId(&ViewScrollingBackgroundClient(), kDocumentBackgroundType),
- IsSameId(&container, kScrollHitTestType),
IsSameId(&div1, kBackgroundType), IsSameId(&div2, kBackgroundType)));
-
- container.GetScrollableArea()->SetScrollOffset(ScrollOffset(5000, 5000),
- kProgrammaticScroll);
+ HitTestData container_scroll_hit_test;
+ container_scroll_hit_test.scroll_translation =
+ &container.FirstFragment().ContentsProperties().Transform();
+ container_scroll_hit_test.scroll_hit_test_rect = IntRect(0, 0, 200, 200);
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(
+ IsPaintChunk(0, 1,
+ PaintChunk::Id(ViewScrollingBackgroundClient(),
+ DisplayItem::kDocumentBackground),
+ GetLayoutView().FirstFragment().ContentsProperties()),
+ IsPaintChunk(
+ 1, 1,
+ PaintChunk::Id(*container.Layer(), DisplayItem::kLayerChunk),
+ container.FirstFragment().LocalBorderBoxProperties(), nullptr,
+ IntRect(0, 0, 200, 200)),
+ IsPaintChunk(1, 1,
+ PaintChunk::Id(container, DisplayItem::kScrollHitTest),
+ container.FirstFragment().LocalBorderBoxProperties(),
+ &container_scroll_hit_test, IntRect(0, 0, 200, 200)),
+ IsPaintChunk(
+ 1, 3,
+ PaintChunk::Id(container, kClippedContentsBackgroundChunkType),
+ container.FirstFragment().ContentsProperties())));
+
+ container.GetScrollableArea()->SetScrollOffset(
+ ScrollOffset(5000, 5000), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
// Cull rect after scroll: (1000,1000 8100x8100)
@@ -213,9 +265,28 @@ TEST_P(PaintControllerPaintTestForCAP, BlockScrollingNonLayeredContents) {
RootPaintController().GetDisplayItemList(),
ElementsAre(
IsSameId(&ViewScrollingBackgroundClient(), kDocumentBackgroundType),
- IsSameId(&container, kScrollHitTestType),
IsSameId(&div2, kBackgroundType), IsSameId(&div3, kBackgroundType),
IsSameId(&div4, kBackgroundType)));
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(
+ IsPaintChunk(0, 1,
+ PaintChunk::Id(ViewScrollingBackgroundClient(),
+ DisplayItem::kDocumentBackground),
+ GetLayoutView().FirstFragment().ContentsProperties()),
+ IsPaintChunk(
+ 1, 1,
+ PaintChunk::Id(*container.Layer(), DisplayItem::kLayerChunk),
+ container.FirstFragment().LocalBorderBoxProperties(), nullptr,
+ IntRect(0, 0, 200, 200)),
+ IsPaintChunk(1, 1,
+ PaintChunk::Id(container, DisplayItem::kScrollHitTest),
+ container.FirstFragment().LocalBorderBoxProperties(),
+ &container_scroll_hit_test, IntRect(0, 0, 200, 200)),
+ IsPaintChunk(
+ 1, 4,
+ PaintChunk::Id(container, kClippedContentsBackgroundChunkType),
+ container.FirstFragment().ContentsProperties())));
}
TEST_P(PaintControllerPaintTestForCAP, ScrollHitTestOrder) {
@@ -243,14 +314,42 @@ TEST_P(PaintControllerPaintTestForCAP, ScrollHitTestOrder) {
EXPECT_THAT(
RootPaintController().GetDisplayItemList(),
ElementsAre(
- IsSameId(&GetLayoutView(), kScrollHitTestType),
IsSameId(&ViewScrollingBackgroundClient(), kDocumentBackgroundType),
IsSameId(&container, kBackgroundType),
- IsSameId(&container, kScrollHitTestType),
- IsSameId(&container.GetScrollableArea()
- ->GetScrollingBackgroundDisplayItemClient(),
- kBackgroundType),
IsSameId(&child, kBackgroundType)));
+ HitTestData view_scroll_hit_test;
+ view_scroll_hit_test.scroll_translation =
+ &GetLayoutView().FirstFragment().ContentsProperties().Transform();
+ view_scroll_hit_test.scroll_hit_test_rect = IntRect(0, 0, 800, 600);
+ HitTestData container_scroll_hit_test;
+ container_scroll_hit_test.scroll_translation =
+ &container.FirstFragment().ContentsProperties().Transform();
+ container_scroll_hit_test.scroll_hit_test_rect = IntRect(0, 0, 200, 200);
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(
+ IsPaintChunk(
+ 0, 0,
+ PaintChunk::Id(GetLayoutView(), DisplayItem::kScrollHitTest),
+ GetLayoutView().FirstFragment().LocalBorderBoxProperties(),
+ &view_scroll_hit_test, IntRect(0, 0, 800, 600)),
+ IsPaintChunk(0, 1,
+ PaintChunk::Id(ViewScrollingBackgroundClient(),
+ DisplayItem::kDocumentBackground),
+ GetLayoutView().FirstFragment().ContentsProperties()),
+ IsPaintChunk(
+ 1, 2,
+ PaintChunk::Id(*container.Layer(), DisplayItem::kLayerChunk),
+ container.FirstFragment().LocalBorderBoxProperties(), nullptr,
+ IntRect(0, 0, 200, 200)),
+ IsPaintChunk(2, 2,
+ 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())));
}
TEST_P(PaintControllerPaintTestForCAP, NonStackingScrollHitTestOrder) {
@@ -274,16 +373,17 @@ TEST_P(PaintControllerPaintTestForCAP, NonStackingScrollHitTestOrder) {
</div>
)HTML");
- auto& container = *To<LayoutBlock>(GetLayoutObjectByElementId("container"));
+ auto& html = *GetDocument().documentElement()->GetLayoutBox();
+ auto& container = *ToLayoutBox(GetLayoutObjectByElementId("container"));
auto& child = *GetLayoutObjectByElementId("child");
- auto& neg_z_child = *GetLayoutObjectByElementId("negZChild");
- auto& pos_z_child = *GetLayoutObjectByElementId("posZChild");
+ auto& neg_z_child = *ToLayoutBox(GetLayoutObjectByElementId("negZChild"));
+ auto& pos_z_child = *ToLayoutBox(GetLayoutObjectByElementId("posZChild"));
// Container is not a stacking context because no z-index is auto.
// Negative z-index descendants are painted before the background and
// positive z-index descendants are painted after the background. Scroll hit
// testing should hit positive descendants, the container, and then negative
- // descendants so the ScrollHitTest item should be immediately after the
+ // descendants so the scroll hit test should be immediately after the
// background.
EXPECT_THAT(
RootPaintController().GetDisplayItemList(),
@@ -291,12 +391,45 @@ TEST_P(PaintControllerPaintTestForCAP, NonStackingScrollHitTestOrder) {
IsSameId(&ViewScrollingBackgroundClient(), kDocumentBackgroundType),
IsSameId(&neg_z_child, kBackgroundType),
IsSameId(&container, kBackgroundType),
- IsSameId(&container, kScrollHitTestType),
- IsSameId(&container.GetScrollableArea()
- ->GetScrollingBackgroundDisplayItemClient(),
- kBackgroundType),
IsSameId(&child, kBackgroundType),
IsSameId(&pos_z_child, kBackgroundType)));
+ HitTestData container_scroll_hit_test;
+ container_scroll_hit_test.scroll_translation =
+ &container.FirstFragment().ContentsProperties().Transform();
+ container_scroll_hit_test.scroll_hit_test_rect = IntRect(0, 0, 200, 200);
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(
+ IsPaintChunk(0, 1,
+ PaintChunk::Id(ViewScrollingBackgroundClient(),
+ DisplayItem::kDocumentBackground),
+ GetLayoutView().FirstFragment().ContentsProperties()),
+ IsPaintChunk(
+ 1, 2,
+ PaintChunk::Id(*neg_z_child.Layer(), DisplayItem::kLayerChunk),
+ neg_z_child.FirstFragment().LocalBorderBoxProperties()),
+ IsPaintChunk(
+ 2, 2,
+ PaintChunk::Id(*html.Layer(), DisplayItem::kLayerChunkForeground),
+ html.FirstFragment().LocalBorderBoxProperties(), nullptr,
+ IntRect(0, 0, 800, 200)),
+ IsPaintChunk(
+ 2, 3,
+ PaintChunk::Id(*container.Layer(), DisplayItem::kLayerChunk),
+ container.FirstFragment().LocalBorderBoxProperties(), nullptr,
+ IntRect(0, 0, 200, 200)),
+ IsPaintChunk(3, 3,
+ PaintChunk::Id(container, DisplayItem::kScrollHitTest),
+ container.FirstFragment().LocalBorderBoxProperties(),
+ &container_scroll_hit_test, IntRect(0, 0, 200, 200)),
+ IsPaintChunk(
+ 3, 4,
+ PaintChunk::Id(container, kClippedContentsBackgroundChunkType),
+ container.FirstFragment().ContentsProperties()),
+ IsPaintChunk(
+ 4, 5,
+ PaintChunk::Id(*pos_z_child.Layer(), DisplayItem::kLayerChunk),
+ pos_z_child.FirstFragment().LocalBorderBoxProperties())));
}
TEST_P(PaintControllerPaintTestForCAP, StackingScrollHitTestOrder) {
@@ -320,10 +453,10 @@ TEST_P(PaintControllerPaintTestForCAP, StackingScrollHitTestOrder) {
</div>
)HTML");
- auto& container = *To<LayoutBlock>(GetLayoutObjectByElementId("container"));
+ auto& container = *ToLayoutBox(GetLayoutObjectByElementId("container"));
auto& child = *GetLayoutObjectByElementId("child");
- auto& neg_z_child = *GetLayoutObjectByElementId("negZChild");
- auto& pos_z_child = *GetLayoutObjectByElementId("posZChild");
+ auto& neg_z_child = *ToLayoutBox(GetLayoutObjectByElementId("negZChild"));
+ auto& pos_z_child = *ToLayoutBox(GetLayoutObjectByElementId("posZChild"));
// Container is a stacking context because z-index is non-auto.
// Both positive and negative z-index descendants are painted after the
@@ -334,13 +467,47 @@ TEST_P(PaintControllerPaintTestForCAP, StackingScrollHitTestOrder) {
ElementsAre(
IsSameId(&ViewScrollingBackgroundClient(), kDocumentBackgroundType),
IsSameId(&container, kBackgroundType),
- IsSameId(&container, kScrollHitTestType),
IsSameId(&container.GetScrollableArea()
->GetScrollingBackgroundDisplayItemClient(),
kBackgroundType),
IsSameId(&neg_z_child, kBackgroundType),
IsSameId(&child, kBackgroundType),
IsSameId(&pos_z_child, kBackgroundType)));
+ HitTestData container_scroll_hit_test;
+ container_scroll_hit_test.scroll_translation =
+ &container.FirstFragment().ContentsProperties().Transform();
+ container_scroll_hit_test.scroll_hit_test_rect = IntRect(0, 0, 200, 200);
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(
+ IsPaintChunk(0, 1,
+ PaintChunk::Id(ViewScrollingBackgroundClient(),
+ DisplayItem::kDocumentBackground),
+ GetLayoutView().FirstFragment().ContentsProperties()),
+ IsPaintChunk(
+ 1, 2,
+ PaintChunk::Id(*container.Layer(), DisplayItem::kLayerChunk),
+ container.FirstFragment().LocalBorderBoxProperties(), nullptr,
+ IntRect(0, 0, 200, 200)),
+ IsPaintChunk(2, 2,
+ PaintChunk::Id(container, DisplayItem::kScrollHitTest),
+ container.FirstFragment().LocalBorderBoxProperties(),
+ &container_scroll_hit_test, IntRect(0, 0, 200, 200)),
+ IsPaintChunk(2, 3,
+ PaintChunk::Id(container, kScrollingBackgroundChunkType),
+ container.FirstFragment().ContentsProperties()),
+ IsPaintChunk(
+ 3, 4,
+ PaintChunk::Id(*neg_z_child.Layer(), DisplayItem::kLayerChunk),
+ neg_z_child.FirstFragment().LocalBorderBoxProperties()),
+ IsPaintChunk(
+ 4, 5,
+ PaintChunk::Id(container, kClippedContentsBackgroundChunkType),
+ container.FirstFragment().ContentsProperties()),
+ IsPaintChunk(
+ 5, 6,
+ PaintChunk::Id(*pos_z_child.Layer(), DisplayItem::kLayerChunk),
+ pos_z_child.FirstFragment().LocalBorderBoxProperties())));
}
TEST_P(PaintControllerPaintTestForCAP,
@@ -365,20 +532,57 @@ TEST_P(PaintControllerPaintTestForCAP,
</div>
)HTML");
- auto& container = *To<LayoutBlock>(GetLayoutObjectByElementId("container"));
+ auto& html = *GetDocument().documentElement()->GetLayoutBox();
+ auto& container = *ToLayoutBox(GetLayoutObjectByElementId("container"));
auto& child = *GetLayoutObjectByElementId("child");
- auto& neg_z_child = *GetLayoutObjectByElementId("negZChild");
- auto& pos_z_child = *GetLayoutObjectByElementId("posZChild");
+ auto& neg_z_child = *ToLayoutBox(GetLayoutObjectByElementId("negZChild"));
+ auto& pos_z_child = *ToLayoutBox(GetLayoutObjectByElementId("posZChild"));
- // Even though container does not paint a background, the scroll hit test item
+ // Even though container does not paint a background, the scroll hit test
// should still be between the negative z-index child and the regular child.
EXPECT_THAT(RootPaintController().GetDisplayItemList(),
ElementsAre(IsSameId(&ViewScrollingBackgroundClient(),
kDocumentBackgroundType),
IsSameId(&neg_z_child, kBackgroundType),
- IsSameId(&container, kScrollHitTestType),
IsSameId(&child, kBackgroundType),
IsSameId(&pos_z_child, kBackgroundType)));
+ HitTestData container_scroll_hit_test;
+ container_scroll_hit_test.scroll_translation =
+ &container.FirstFragment().ContentsProperties().Transform();
+ container_scroll_hit_test.scroll_hit_test_rect = IntRect(0, 0, 200, 200);
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(
+ IsPaintChunk(0, 1,
+ PaintChunk::Id(ViewScrollingBackgroundClient(),
+ DisplayItem::kDocumentBackground),
+ GetLayoutView().FirstFragment().ContentsProperties()),
+ IsPaintChunk(
+ 1, 2,
+ PaintChunk::Id(*neg_z_child.Layer(), DisplayItem::kLayerChunk),
+ neg_z_child.FirstFragment().LocalBorderBoxProperties()),
+ IsPaintChunk(
+ 2, 2,
+ PaintChunk::Id(*html.Layer(), DisplayItem::kLayerChunkForeground),
+ html.FirstFragment().LocalBorderBoxProperties(), nullptr,
+ IntRect(0, 0, 800, 200)),
+ IsPaintChunk(
+ 2, 2,
+ PaintChunk::Id(*container.Layer(), DisplayItem::kLayerChunk),
+ container.FirstFragment().LocalBorderBoxProperties(), nullptr,
+ IntRect(0, 0, 200, 200)),
+ IsPaintChunk(2, 2,
+ 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(
+ 3, 4,
+ PaintChunk::Id(*pos_z_child.Layer(), DisplayItem::kLayerChunk),
+ pos_z_child.FirstFragment().LocalBorderBoxProperties())));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_controller_paint_test.h b/chromium/third_party/blink/renderer/core/paint/paint_controller_paint_test.h
index c88fa5805fe..f87c116d72f 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_controller_paint_test.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_controller_paint_test.h
@@ -137,24 +137,10 @@ const DisplayItem::Type kNonScrollingBackgroundChunkType =
DisplayItem::PaintPhaseToDrawingType(PaintPhase::kSelfBlockBackgroundOnly);
const DisplayItem::Type kScrollingBackgroundChunkType =
DisplayItem::PaintPhaseToClipType(PaintPhase::kSelfBlockBackgroundOnly);
-const DisplayItem::Type kNonScrollingContentsBackgroundChunkType =
- DisplayItem::PaintPhaseToDrawingType(
- PaintPhase::kDescendantBlockBackgroundsOnly);
-const DisplayItem::Type kScrollingContentsBackgroundChunkType =
+const DisplayItem::Type kClippedContentsBackgroundChunkType =
DisplayItem::PaintPhaseToClipType(
PaintPhase::kDescendantBlockBackgroundsOnly);
-#define EXPECT_SUBSEQUENCE(client, expected_start, expected_end) \
- do { \
- auto* subsequence = GetSubsequenceMarkers(client); \
- ASSERT_NE(nullptr, subsequence); \
- EXPECT_EQ(static_cast<size_t>(expected_start), subsequence->start); \
- EXPECT_EQ(static_cast<size_t>(expected_end), subsequence->end); \
- } while (false)
-
-#define EXPECT_NO_SUBSEQUENCE(client) \
- EXPECT_EQ(nullptr, GetSubsequenceMarkers(client)
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_CONTROLLER_PAINT_TEST_H_
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_info.h b/chromium/third_party/blink/renderer/core/paint/paint_info.h
index 6927f0aed5a..7716d6e8cc0 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_info.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_info.h
@@ -29,6 +29,7 @@
#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/ng_physical_fragment.h"
// TODO(jchaffraix): Once we unify PaintBehavior and PaintLayerFlags, we should
// move PaintLayerFlags to PaintPhase and rename it. Thus removing the need for
// this #include
@@ -168,6 +169,17 @@ struct CORE_EXPORT PaintInfo {
return nullptr;
}
+ // Returns the FragmentData of the specified physical fragment. If fragment
+ // traversal is supported, it will map directly to the right FragmentData.
+ // Otherwise we'll fall back to matching against the current
+ // PaintLayerFragment.
+ const FragmentData* FragmentToPaint(
+ const NGPhysicalFragment& fragment) const {
+ if (fragment.CanTraverse())
+ return fragment.GetFragmentData();
+ return FragmentToPaint(*fragment.GetLayoutObject());
+ }
+
void SetFragmentLogicalTopInFlowThread(LayoutUnit fragment_logical_top) {
fragment_logical_top_in_flow_thread_ = fragment_logical_top;
}
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 358f04b3639..12031a700f8 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_invalidator.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_invalidator.cc
@@ -14,7 +14,10 @@
#include "third_party/blink/renderer/core/layout/layout_table.h"
#include "third_party/blink/renderer/core/layout/layout_table_section.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h"
#include "third_party/blink/renderer/core/layout/ng/legacy_layout_tree_walking.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
#include "third_party/blink/renderer/core/layout/svg/svg_layout_support.h"
#include "third_party/blink/renderer/core/page/link_highlight.h"
#include "third_party/blink/renderer/core/page/page.h"
@@ -131,22 +134,43 @@ PaintInvalidatorContext::ParentContextAccessor::ParentContext() const {
IntRect PaintInvalidator::ComputeVisualRect(
const LayoutObject& object,
+ const NGPrePaintInfo* pre_paint_info,
const PaintInvalidatorContext& context) {
if (object.IsSVGChild()) {
return context.MapLocalRectToVisualRectForSVGChild(
object, SVGLayoutSupport::LocalVisualRect(object));
}
- return context.MapLocalRectToVisualRect(object, object.LocalVisualRect());
+ PhysicalRect rect;
+ if (pre_paint_info) {
+ const NGFragmentChildIterator& iterator = pre_paint_info->iterator;
+ DCHECK(iterator->BoxFragment() || iterator->FragmentItem());
+ if (object.StyleRef().Visibility() == EVisibility::kVisible) {
+ if (const auto* box_fragment = iterator->BoxFragment())
+ rect = box_fragment->InkOverflow();
+ else
+ rect = iterator->FragmentItem()->InkOverflow();
+ // The paint offset of text and non-atomic inlines are special; they are
+ // set to the paint offset of their container. Add the offset to the
+ // fragment now, to set the correct visual rectangle.
+ if (!object.IsBox())
+ rect.Move(iterator->Link().offset);
+ }
+ } else {
+ rect = object.LocalVisualRect();
+ }
+ return context.MapLocalRectToVisualRect(object, rect);
}
void PaintInvalidator::UpdatePaintingLayer(const LayoutObject& object,
- PaintInvalidatorContext& context) {
+ PaintInvalidatorContext& context,
+ bool is_ng_painting) {
if (object.HasLayer() &&
ToLayoutBoxModelObject(object).HasSelfPaintingLayer()) {
context.painting_layer = ToLayoutBoxModelObject(object).Layer();
- } else if (object.IsColumnSpanAll() ||
- object.IsFloatingWithNonContainingBlockParent()) {
+ } else if (!is_ng_painting &&
+ (object.IsColumnSpanAll() ||
+ object.IsFloatingWithNonContainingBlockParent())) {
// See |LayoutObject::PaintingLayer| for the special-cases of floating under
// inline and multicolumn.
// Post LayoutNG the |LayoutObject::IsFloatingWithNonContainingBlockParent|
@@ -164,47 +188,24 @@ void PaintInvalidator::UpdatePaintingLayer(const LayoutObject& object,
IsLayoutNGContainingBlock(object.ContainingBlock())))
context.painting_layer->SetNeedsPaintPhaseFloat();
- // Table collapsed borders are painted in PaintPhaseDescendantBlockBackgrounds
- // on the table's layer.
- if (object.IsTable() &&
- ToInterface<LayoutNGTableInterface>(object).HasCollapsedBorders())
- context.painting_layer->SetNeedsPaintPhaseDescendantBlockBackgrounds();
-
- // The following flags are for descendants of the layer object only.
- if (object == context.painting_layer->GetLayoutObject())
- return;
-
- if (object.IsTableSection()) {
- const auto& section = ToInterface<LayoutNGTableSectionInterface>(object);
- if (section.TableInterface()->HasColElements())
- context.painting_layer->SetNeedsPaintPhaseDescendantBlockBackgrounds();
- }
-
- if (object.StyleRef().HasOutline())
+ if (object != context.painting_layer->GetLayoutObject() &&
+ object.StyleRef().HasOutline())
context.painting_layer->SetNeedsPaintPhaseDescendantOutlines();
-
- if (object.HasBoxDecorationBackground()
- // We also paint non-overlay overflow controls in background phase.
- || (object.HasOverflowClip() && ToLayoutBox(object)
- .GetScrollableArea()
- ->HasNonOverlayOverflowControls())) {
- context.painting_layer->SetNeedsPaintPhaseDescendantBlockBackgrounds();
- } else {
- // Hit testing rects for touch action paint in the background phase.
- if (object.HasEffectiveAllowedTouchAction())
- context.painting_layer->SetNeedsPaintPhaseDescendantBlockBackgrounds();
- }
}
void PaintInvalidator::UpdatePaintInvalidationContainer(
const LayoutObject& object,
- PaintInvalidatorContext& context) {
+ PaintInvalidatorContext& context,
+ bool is_ng_painting) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ return;
+
if (object.IsPaintInvalidationContainer()) {
context.paint_invalidation_container = ToLayoutBoxModelObject(&object);
if (object.StyleRef().IsStackingContext() || object.IsSVGRoot())
context.paint_invalidation_container_for_stacked_contents =
ToLayoutBoxModelObject(&object);
- } else if (object.IsLayoutView()) {
+ } else if (IsA<LayoutView>(object)) {
// paint_invalidation_container_for_stacked_contents is only for stacked
// descendants in its own frame, because it doesn't establish stacking
// context for stacked contents in sub-frames.
@@ -213,8 +214,9 @@ void PaintInvalidator::UpdatePaintInvalidationContainer(
context.paint_invalidation_container_for_stacked_contents =
context.paint_invalidation_container =
&object.ContainerForPaintInvalidation();
- } else if (object.IsColumnSpanAll() ||
- object.IsFloatingWithNonContainingBlockParent()) {
+ } else if (!is_ng_painting &&
+ (object.IsColumnSpanAll() ||
+ object.IsFloatingWithNonContainingBlockParent())) {
// In these cases, the object may belong to an ancestor of the current
// paint invalidation container, in paint order.
// Post LayoutNG the |LayoutObject::IsFloatingWithNonContainingBlockParent|
@@ -265,16 +267,27 @@ void PaintInvalidator::UpdatePaintInvalidationContainer(
}
void PaintInvalidator::UpdateVisualRect(const LayoutObject& object,
+ const NGPrePaintInfo* pre_paint_info,
FragmentData& fragment_data,
PaintInvalidatorContext& context) {
if (!context.NeedsVisualRectUpdate(object))
return;
DCHECK(context.tree_builder_context_);
- DCHECK(context.tree_builder_context_->current.paint_offset ==
- fragment_data.PaintOffset());
-
- fragment_data.SetVisualRect(ComputeVisualRect(object, context));
+ DCHECK(!pre_paint_info || &fragment_data == &pre_paint_info->fragment_data);
+
+ IntRect visual_rect = ComputeVisualRect(object, pre_paint_info, context);
+ if (pre_paint_info && !object.IsBox()) {
+ DCHECK(object.IsInline());
+ // Text and non-atomic inlines share the same FragmentData object per block
+ // fragment, and their FragmentData objects are reset when visiting their
+ // first fragment. So just add to the visual rectangle.
+ visual_rect.Unite(fragment_data.VisualRect());
+ } else {
+ DCHECK_EQ(context.tree_builder_context_->current.paint_offset,
+ fragment_data.PaintOffset());
+ }
+ fragment_data.SetVisualRect(visual_rect);
object.GetFrameView()->GetLayoutShiftTracker().NotifyObjectPrePaint(
object,
@@ -286,7 +299,7 @@ void PaintInvalidator::UpdateVisualRect(const LayoutObject& object,
// it has was inherited from the parent frame, and movements of a
// frame relative to its parent are tracked in the parent frame's
// LayoutShiftTracker, not the child frame's.
- object.IsLayoutView()
+ IsA<LayoutView>(object)
? FloatSize()
: context.tree_builder_context_->paint_offset_delta);
}
@@ -315,13 +328,14 @@ void PaintInvalidator::UpdateEmptyVisualRectFlag(
bool PaintInvalidator::InvalidatePaint(
const LayoutObject& object,
+ const NGPrePaintInfo* pre_paint_info,
const PaintPropertyTreeBuilderContext* tree_builder_context,
PaintInvalidatorContext& context) {
TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"),
"PaintInvalidator::InvalidatePaint()", "object",
object.DebugName().Ascii());
- if (object.IsSVGHiddenContainer())
+ if (object.IsSVGHiddenContainer() || object.IsLayoutTableCol())
context.subtree_flags |= PaintInvalidatorContext::kSubtreeNoInvalidation;
if (context.subtree_flags & PaintInvalidatorContext::kSubtreeNoInvalidation)
@@ -329,8 +343,9 @@ bool PaintInvalidator::InvalidatePaint(
object.GetMutableForPainting().EnsureIsReadyForPaintInvalidation();
- UpdatePaintingLayer(object, context);
- UpdatePaintInvalidationContainer(object, context);
+ UpdatePaintingLayer(object, context, /* is_ng_painting */ !!pre_paint_info);
+ UpdatePaintInvalidationContainer(object, context,
+ /* is_ng_painting */ !!pre_paint_info);
UpdateEmptyVisualRectFlag(object, context);
if (!object.ShouldCheckForPaintInvalidation() && !context.NeedsSubtreeWalk())
@@ -346,38 +361,72 @@ bool PaintInvalidator::InvalidatePaint(
object.GetFrameView()->SetForeignLayerListNeedsUpdate();
}
- unsigned tree_builder_index = 0;
+ if (pre_paint_info) {
+ FragmentData& fragment_data = pre_paint_info->fragment_data;
+ if (!object.IsBox()) {
+ // Text and non-atomic inlines may generate multiple physical fragments,
+ // and we're updating the VisualRect in the FragmentData as we visit each
+ // of them. As such, the current VisualRect in FragmentData is possibly
+ // incomplete, so letting anyone use it for comparisons is meaningless.
+ // TODO(crbug.com/1043787): Fix this. The way we use FragmentData for
+ // non-atomic inlines is not ideal for how LayoutNG works.
+ context.old_visual_rect = IntRect();
+ } else {
+ context.old_visual_rect = fragment_data.VisualRect();
+ }
+ context.fragment_data = &fragment_data;
- for (auto* fragment_data = &object.GetMutableForPainting().FirstFragment();
- fragment_data;
- fragment_data = fragment_data->NextFragment(), tree_builder_index++) {
- context.old_visual_rect = fragment_data->VisualRect();
- context.fragment_data = fragment_data;
+#if DCHECK_IS_ON()
+ context.tree_builder_context_actually_needed_ =
+ tree_builder_context && tree_builder_context->is_actually_needed;
+#endif
+ if (tree_builder_context) {
+ DCHECK_EQ(tree_builder_context->fragments.size(), 1u);
+ context.tree_builder_context_ = &tree_builder_context->fragments[0];
+ context.old_paint_offset =
+ context.tree_builder_context_->old_paint_offset;
+ } else {
+ context.tree_builder_context_ = nullptr;
+ context.old_paint_offset = fragment_data.PaintOffset();
+ }
+
+ UpdateVisualRect(object, pre_paint_info, fragment_data, context);
+ object.InvalidatePaint(context);
+ } else {
+ unsigned tree_builder_index = 0;
- DCHECK(!tree_builder_context ||
- tree_builder_index < tree_builder_context->fragments.size());
+ for (auto* fragment_data = &object.GetMutableForPainting().FirstFragment();
+ fragment_data;
+ fragment_data = fragment_data->NextFragment(), tree_builder_index++) {
+ context.old_visual_rect = fragment_data->VisualRect();
+ context.fragment_data = fragment_data;
- {
+ DCHECK(!tree_builder_context ||
+ tree_builder_index < tree_builder_context->fragments.size());
+
+ {
#if DCHECK_IS_ON()
- context.tree_builder_context_actually_needed_ =
- tree_builder_context && tree_builder_context->is_actually_needed;
- FindObjectVisualRectNeedingUpdateScope finder(object, *fragment_data,
- context);
+ context.tree_builder_context_actually_needed_ =
+ tree_builder_context && tree_builder_context->is_actually_needed;
+ FindObjectVisualRectNeedingUpdateScope finder(object, *fragment_data,
+ context);
#endif
- if (tree_builder_context) {
- context.tree_builder_context_ =
- &tree_builder_context->fragments[tree_builder_index];
- context.old_paint_offset =
- context.tree_builder_context_->old_paint_offset;
- } else {
- context.tree_builder_context_ = nullptr;
- context.old_paint_offset = fragment_data->PaintOffset();
+ if (tree_builder_context) {
+ context.tree_builder_context_ =
+ &tree_builder_context->fragments[tree_builder_index];
+ context.old_paint_offset =
+ context.tree_builder_context_->old_paint_offset;
+ } else {
+ context.tree_builder_context_ = nullptr;
+ context.old_paint_offset = fragment_data->PaintOffset();
+ }
+
+ UpdateVisualRect(object, /* pre_paint_info */ nullptr, *fragment_data,
+ context);
}
- UpdateVisualRect(object, *fragment_data, context);
+ object.InvalidatePaint(context);
}
-
- object.InvalidatePaint(context);
}
auto reason = static_cast<const DisplayItemClient&>(object)
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_invalidator.h b/chromium/third_party/blink/renderer/core/paint/paint_invalidator.h
index a8aed714d64..85e7d672bef 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_invalidator.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_invalidator.h
@@ -152,6 +152,7 @@ class PaintInvalidator {
public:
// Returns true if the object is invalidated.
bool InvalidatePaint(const LayoutObject&,
+ const NGPrePaintInfo*,
const PaintPropertyTreeBuilderContext*,
PaintInvalidatorContext&);
@@ -164,14 +165,18 @@ class PaintInvalidator {
friend class PrePaintTreeWalk;
ALWAYS_INLINE IntRect ComputeVisualRect(const LayoutObject&,
+ const NGPrePaintInfo*,
const PaintInvalidatorContext&);
ALWAYS_INLINE void UpdatePaintingLayer(const LayoutObject&,
- PaintInvalidatorContext&);
+ PaintInvalidatorContext&,
+ bool is_ng_painting);
ALWAYS_INLINE void UpdatePaintInvalidationContainer(const LayoutObject&,
- PaintInvalidatorContext&);
+ PaintInvalidatorContext&,
+ bool is_ng_painting);
ALWAYS_INLINE void UpdateEmptyVisualRectFlag(const LayoutObject&,
PaintInvalidatorContext&);
ALWAYS_INLINE void UpdateVisualRect(const LayoutObject&,
+ const NGPrePaintInfo*,
FragmentData&,
PaintInvalidatorContext&);
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 b480f2e1c35..0d52eb19e02 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -77,6 +77,7 @@
#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/filter_effect_builder.h"
+#include "third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h"
#include "third_party/blink/renderer/core/paint/object_paint_invalidator.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
#include "third_party/blink/renderer/core/paint/paint_layer_paint_order_iterator.h"
@@ -92,6 +93,7 @@
#include "third_party/blink/renderer/platform/graphics/compositor_filter_operations.h"
#include "third_party/blink/renderer/platform/graphics/filters/filter.h"
#include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.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/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
@@ -138,7 +140,7 @@ PaintLayerRareData::PaintLayerRareData()
PaintLayerRareData::~PaintLayerRareData() = default;
PaintLayer::PaintLayer(LayoutBoxModelObject& layout_object)
- : is_root_layer_(layout_object.IsLayoutView()),
+ : is_root_layer_(IsA<LayoutView>(layout_object)),
has_visible_content_(false),
needs_descendant_dependent_flags_update_(true),
needs_visual_overflow_recalc_(true),
@@ -161,7 +163,6 @@ PaintLayer::PaintLayer(LayoutBoxModelObject& layout_object)
previous_paint_result_(kFullyPainted),
needs_paint_phase_descendant_outlines_(false),
needs_paint_phase_float_(false),
- needs_paint_phase_descendant_block_backgrounds_(false),
has_descendant_with_clip_path_(false),
has_non_isolated_descendant_with_blend_mode_(false),
has_fixed_position_descendant_(false),
@@ -307,12 +308,9 @@ PhysicalOffset PaintLayer::SubpixelAccumulation() const {
}
void PaintLayer::SetSubpixelAccumulation(const PhysicalOffset& accumulation) {
- if (rare_data_ || !accumulation.IsZero()) {
+ DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
+ if (rare_data_ || !accumulation.IsZero())
EnsureRareData().subpixel_accumulation = accumulation;
- if (PaintLayerScrollableArea* scrollable_area = GetScrollableArea()) {
- scrollable_area->PositionOverflowControls();
- }
- }
}
void PaintLayer::UpdateLayerPositionsAfterLayout() {
@@ -411,7 +409,7 @@ void PaintLayer::UpdateTransformationMatrix() {
ComputedStyle::kIncludeIndependentTransformProperties);
MakeMatrixRenderable(
*transform,
- Compositor() ? Compositor()->HasAcceleratedCompositing() : false);
+ box->GetDocument().GetSettings()->GetAcceleratedCompositingEnabled());
}
}
@@ -690,8 +688,16 @@ void PaintLayer::UpdateDescendantDependentFlags() {
UpdateStackingNode();
if (old_has_non_isolated_descendant_with_blend_mode !=
- static_cast<bool>(has_non_isolated_descendant_with_blend_mode_))
+ static_cast<bool>(has_non_isolated_descendant_with_blend_mode_)) {
+ // The LayoutView DisplayItemClient owns painting of the background
+ // of the HTML element. When blending isolation of the HTML element's
+ // descendants change, there will be an addition or removal of an
+ // isolation effect node for the HTML element to add (or remove)
+ // isolated blending, and that case we need to re-paint the LayoutView.
+ if (Parent() && Parent()->IsRootLayer())
+ GetLayoutObject().View()->SetBackgroundNeedsFullPaintInvalidation();
GetLayoutObject().SetNeedsPaintPropertyUpdate();
+ }
needs_descendant_dependent_flags_update_ = false;
if (IsSelfPaintingLayer() && needs_visual_overflow_recalc_) {
@@ -859,19 +865,6 @@ void PaintLayer::UpdateSizeAndScrollingAfterLayout() {
}
}
-TransformationMatrix PaintLayer::PerspectiveTransform() const {
- if (!GetLayoutObject().HasTransformRelatedProperty())
- return TransformationMatrix();
-
- const ComputedStyle& style = GetLayoutObject().StyleRef();
- if (!style.HasPerspective())
- return TransformationMatrix();
-
- TransformationMatrix t;
- t.ApplyPerspective(style.Perspective());
- return t;
-}
-
FloatPoint PaintLayer::PerspectiveOrigin() const {
if (!GetLayoutObject().HasTransformRelatedProperty())
return FloatPoint();
@@ -1027,14 +1020,15 @@ PaintLayer* PaintLayer::EnclosingLayerForPaintInvalidation() const {
return nullptr;
}
-void PaintLayer::SetNeedsCompositingInputsUpdate() {
+void PaintLayer::SetNeedsCompositingInputsUpdate(bool mark_ancestor_flags) {
SetNeedsCompositingInputsUpdateInternal();
// TODO(chrishtr): These are a bit of a heavy hammer, because not all
// things which require compositing inputs update require a descendant-
// dependent flags update. Reduce call sites after CAP launch allows
/// removal of CompositingInputsUpdater.
- MarkAncestorChainForFlagsUpdate(NeedsDescendantDependentUpdate);
+ if (mark_ancestor_flags)
+ MarkAncestorChainForFlagsUpdate(NeedsDescendantDependentUpdate);
}
void PaintLayer::SetNeedsVisualOverflowRecalc() {
@@ -1083,6 +1077,8 @@ void PaintLayer::SetNeedsCompositingInputsUpdateInternal() {
last_ancestor = current;
current->child_needs_compositing_inputs_update_ = true;
if (Compositor() &&
+ (current != initial_layer ||
+ !current->GetLayoutObject().IsStickyPositioned()) &&
current->GetLayoutObject().ShouldApplyStrictContainment())
break;
}
@@ -1175,106 +1171,6 @@ bool PaintLayer::HasAncestorWithFilterThatMovesPixels() const {
return false;
}
-static void ExpandClipRectForDescendants(
- PhysicalRect& clip_rect,
- const PaintLayer* layer,
- const PaintLayer* root_layer,
- PaintLayer::TransparencyClipBoxBehavior transparency_behavior,
- const PhysicalOffset& sub_pixel_accumulation,
- GlobalPaintFlags global_paint_flags) {
- // If we have a mask, then the clip is limited to the border box area (and
- // there is no need to examine child layers).
- if (!layer->GetLayoutObject().HasMask()) {
- // Note: we don't have to walk z-order lists since transparent elements
- // always establish a stacking container. This means we can just walk the
- // layer tree directly.
- for (PaintLayer* curr = layer->FirstChild(); curr;
- curr = curr->NextSibling())
- clip_rect.Unite(PaintLayer::TransparencyClipBox(
- curr, root_layer, transparency_behavior,
- PaintLayer::kDescendantsOfTransparencyClipBox, sub_pixel_accumulation,
- global_paint_flags));
- }
-}
-
-PhysicalRect PaintLayer::TransparencyClipBox(
- const PaintLayer* layer,
- const PaintLayer* root_layer,
- TransparencyClipBoxBehavior transparency_behavior,
- TransparencyClipBoxMode transparency_mode,
- const PhysicalOffset& sub_pixel_accumulation,
- GlobalPaintFlags global_paint_flags) {
- // FIXME: Although this function completely ignores CSS-imposed clipping, we
- // did already intersect with the paintDirtyRect, and that should cut down on
- // the amount we have to paint. Still it would be better to respect clips.
-
- if (root_layer != layer &&
- ((transparency_behavior == kPaintingTransparencyClipBox &&
- layer->PaintsWithTransform(global_paint_flags)) ||
- (transparency_behavior == kHitTestingTransparencyClipBox &&
- layer->HasTransformRelatedProperty()))) {
- // The best we can do here is to use enclosed bounding boxes to establish a
- // "fuzzy" enough clip to encompass the transformed layer and all of its
- // children.
- const PaintLayer* pagination_layer =
- transparency_mode == kDescendantsOfTransparencyClipBox
- ? layer->EnclosingPaginationLayer()
- : nullptr;
- const PaintLayer* root_layer_for_transform =
- pagination_layer ? pagination_layer : root_layer;
- PhysicalOffset delta;
- layer->ConvertToLayerCoords(root_layer_for_transform, delta);
-
- delta += sub_pixel_accumulation;
- IntPoint pixel_snapped_delta = RoundedIntPoint(delta);
- TransformationMatrix transform;
- transform.Translate(pixel_snapped_delta.X(), pixel_snapped_delta.Y());
- if (layer->Transform())
- transform = transform * *layer->Transform();
-
- // We don't use fragment boxes when collecting a transformed layer's
- // bounding box, since it always paints unfragmented.
- PhysicalRect clip_rect = layer->LocalBoundingBox();
- ExpandClipRectForDescendants(clip_rect, layer, layer, transparency_behavior,
- sub_pixel_accumulation, global_paint_flags);
- PhysicalRect result = PhysicalRect::EnclosingRect(
- transform.MapRect(layer->MapRectForFilter(FloatRect(clip_rect))));
- if (!pagination_layer)
- return result;
-
- // We have to break up the transformed extent across our columns.
- // Split our box up into the actual fragment boxes that layout in the
- // columns/pages and unite those together to get our true bounding box.
- LayoutFlowThread& enclosing_flow_thread =
- ToLayoutFlowThread(pagination_layer->GetLayoutObject());
- result = PhysicalRectToBeNoop(
- enclosing_flow_thread.FragmentsBoundingBox(result.ToLayoutRect()));
-
- PhysicalOffset root_layer_delta;
- pagination_layer->ConvertToLayerCoords(root_layer, root_layer_delta);
- result.Move(root_layer_delta);
- return result;
- }
-
- PhysicalRect clip_rect = layer->ShouldFragmentCompositedBounds(root_layer)
- ? layer->FragmentsBoundingBox(root_layer)
- : layer->PhysicalBoundingBox(root_layer);
- ExpandClipRectForDescendants(clip_rect, layer, root_layer,
- transparency_behavior, sub_pixel_accumulation,
- global_paint_flags);
-
- // Convert clipRect into local coordinates for mapLayerRectForFilter(), and
- // convert back after.
- PhysicalOffset delta;
- layer->ConvertToLayerCoords(root_layer, delta);
- clip_rect.Move(-delta);
- clip_rect = layer->MapRectForFilter(clip_rect);
- clip_rect.Move(delta);
-
- clip_rect.Move(sub_pixel_accumulation);
- return clip_rect;
-}
-
void* PaintLayer::operator new(size_t sz) {
return WTF::Partitions::LayoutPartition()->Alloc(
sz, WTF_HEAP_PROFILER_TYPE_NAME(PaintLayer));
@@ -1367,6 +1263,9 @@ void PaintLayer::RemoveChild(PaintLayer* old_child) {
if (Compositor()) {
if (!old_child_style.IsStacked())
Compositor()->SetNeedsCompositingUpdate(kCompositingUpdateRebuildTree);
+
+ if (Compositor()->GetCompositingInputsRoot() == old_child)
+ Compositor()->ClearCompositingInputsRoot();
}
// Dirty the z-order list in which we are contained.
old_child->DirtyStackingContextZOrderLists();
@@ -1475,7 +1374,7 @@ void PaintLayer::InsertOnlyThisLayerAfterStyleChange() {
// and its descendants to change paint invalidation container.
bool did_set_paint_invalidation = false;
if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
- !GetLayoutObject().IsLayoutView() && GetLayoutObject().IsRooted() &&
+ !IsA<LayoutView>(GetLayoutObject()) && GetLayoutObject().IsRooted() &&
GetLayoutObject().StyleRef().IsStacked()) {
const LayoutBoxModelObject& previous_paint_invalidation_container =
GetLayoutObject().Parent()->ContainerForPaintInvalidation();
@@ -1639,16 +1538,20 @@ bool PaintLayer::RequiresScrollableArea() const {
void PaintLayer::UpdateScrollableArea() {
if (RequiresScrollableArea() && !scrollable_area_) {
- scrollable_area_ = PaintLayerScrollableArea::Create(*this);
+ scrollable_area_ = MakeGarbageCollected<PaintLayerScrollableArea>(*this);
if (Compositor()) {
Compositor()->SetNeedsCompositingUpdate(kCompositingUpdateRebuildTree);
}
+ GetLayoutObject().SetNeedsPaintPropertyUpdate();
} else if (!RequiresScrollableArea() && scrollable_area_) {
scrollable_area_->Dispose();
scrollable_area_.Clear();
if (Compositor()) {
Compositor()->SetNeedsCompositingUpdate(kCompositingUpdateRebuildTree);
}
+ GetLayoutObject().SetBackgroundPaintLocation(
+ kBackgroundPaintInGraphicsLayer);
+ GetLayoutObject().SetNeedsPaintPropertyUpdate();
}
}
@@ -1787,6 +1690,16 @@ void PaintLayer::CollectFragments(
fragment.root_fragment_data = root_fragment_data;
fragment.fragment_data = fragment_data;
+ if (GetLayoutObject().CanTraversePhysicalFragments()) {
+ if (const auto* block = DynamicTo<LayoutBlock>(&GetLayoutObject())) {
+ fragment.physical_fragment = block->CurrentFragment();
+ DCHECK(fragment.physical_fragment);
+
+ // TODO(mstensho): Implement support for multiple fragments per node.
+ DCHECK(!fragment_data->NextFragment());
+ }
+ }
+
fragments.push_back(fragment);
}
}
@@ -2052,7 +1965,7 @@ PaintLayer* PaintLayer::HitTestLayer(PaintLayer* root_layer,
// The natural thing would be to keep HitTestingTransformState on the stack,
// but it's big, so we heap-allocate.
HitTestingTransformState* local_transform_state = nullptr;
- base::Optional<HitTestingTransformState> storage;
+ STACK_UNINITIALIZED base::Optional<HitTestingTransformState> storage;
if (applied_transform) {
// We computed the correct state in the caller (above code), so just
@@ -2071,7 +1984,7 @@ PaintLayer* PaintLayer::HitTestLayer(PaintLayer* root_layer,
// Check for hit test on backface if backface-visibility is 'hidden'
if (local_transform_state && layout_object.StyleRef().BackfaceVisibility() ==
EBackfaceVisibility::kHidden) {
- TransformationMatrix inverted_matrix =
+ STACK_UNINITIALIZED TransformationMatrix inverted_matrix =
local_transform_state->accumulated_transform_.Inverse();
// If the z-vector of the matrix is negative, the back is facing towards the
// viewer.
@@ -2080,7 +1993,8 @@ PaintLayer* PaintLayer::HitTestLayer(PaintLayer* root_layer,
}
HitTestingTransformState* unflattened_transform_state = local_transform_state;
- base::Optional<HitTestingTransformState> unflattened_storage;
+ STACK_UNINITIALIZED base::Optional<HitTestingTransformState>
+ unflattened_storage;
if (local_transform_state && !Preserves3D()) {
// Keep a copy of the pre-flattening state, for computing z-offsets for the
// container
@@ -2111,7 +2025,7 @@ PaintLayer* PaintLayer::HitTestLayer(PaintLayer* root_layer,
// Collect the fragments. This will compute the clip rectangles for each
// layer fragment.
- base::Optional<PaintLayerFragments> layer_fragments;
+ STACK_UNINITIALIZED base::Optional<PaintLayerFragments> layer_fragments;
if (recursion_data.intersects_location) {
layer_fragments.emplace();
if (applied_transform) {
@@ -2189,8 +2103,8 @@ PaintLayer* PaintLayer::HitTestLayer(PaintLayer* root_layer,
DisplayLockLifecycleTarget::kChildren)) {
// Hit test with a temporary HitTestResult, because we only want to commit
// to 'result' if we know we're frontmost.
- HitTestResult temp_result(result.GetHitTestRequest(),
- recursion_data.original_location);
+ STACK_UNINITIALIZED HitTestResult temp_result(
+ result.GetHitTestRequest(), recursion_data.original_location);
temp_result.SetInertNode(result.InertNode());
bool inside_fragment_foreground_rect = false;
@@ -2237,8 +2151,8 @@ PaintLayer* PaintLayer::HitTestLayer(PaintLayer* root_layer,
return candidate_layer;
if (recursion_data.intersects_location && IsSelfPaintingLayer()) {
- HitTestResult temp_result(result.GetHitTestRequest(),
- recursion_data.original_location);
+ STACK_UNINITIALIZED HitTestResult temp_result(
+ result.GetHitTestRequest(), recursion_data.original_location);
temp_result.SetInertNode(result.InertNode());
bool inside_fragment_background_rect = false;
if (HitTestContentsForFragments(*layer_fragments, offset, temp_result,
@@ -2286,8 +2200,8 @@ bool PaintLayer::HitTestContentsForFragments(
inside_clip_rect = true;
PhysicalOffset fragment_offset = offset;
fragment_offset += fragment.layer_bounds.offset;
- if (HitTestContents(result, fragment_offset, hit_test_location,
- hit_test_filter))
+ if (HitTestContents(result, fragment.physical_fragment, fragment_offset,
+ hit_test_location, hit_test_filter))
return true;
}
@@ -2321,7 +2235,7 @@ PaintLayer* PaintLayer::HitTestTransformedLayerInFragments(
PaintLayer* hit_layer = HitTestLayerByApplyingTransform(
root_layer, container_layer, result, recursion_data, transform_state,
z_offset, check_resizer_only,
- fragment.fragment_data->PaginationOffset());
+ fragment.fragment_data->LegacyPaginationOffset());
if (hit_layer)
return hit_layer;
}
@@ -2370,12 +2284,23 @@ PaintLayer* PaintLayer::HitTestLayerByApplyingTransform(
}
bool PaintLayer::HitTestContents(HitTestResult& result,
+ const NGPhysicalBoxFragment* physical_fragment,
const PhysicalOffset& fragment_offset,
const HitTestLocation& hit_test_location,
HitTestFilter hit_test_filter) const {
DCHECK(IsSelfPaintingLayer() || HasSelfPaintingLayerDescendant());
- if (!GetLayoutObject().HitTestAllPhases(result, hit_test_location,
- fragment_offset, hit_test_filter)) {
+
+ bool did_hit;
+ if (physical_fragment) {
+ did_hit = NGBoxFragmentPainter(*physical_fragment)
+ .HitTestAllPhases(result, hit_test_location, fragment_offset,
+ hit_test_filter);
+ } else {
+ did_hit = GetLayoutObject().HitTestAllPhases(
+ result, hit_test_location, fragment_offset, hit_test_filter);
+ }
+
+ if (!did_hit) {
// It's wrong to set innerNode, but then claim that you didn't hit anything,
// unless it is a list-based test.
DCHECK(!result.InnerNode() || (result.GetHitTestRequest().ListBased() &&
@@ -2469,8 +2394,8 @@ PaintLayer* PaintLayer::HitTestChildren(
}
PaintLayer* hit_layer = nullptr;
- HitTestResult temp_result(result.GetHitTestRequest(),
- recursion_data.original_location);
+ STACK_UNINITIALIZED HitTestResult temp_result(
+ result.GetHitTestRequest(), recursion_data.original_location);
temp_result.SetInertNode(result.InertNode());
hit_layer = child_layer->HitTestLayer(
root_layer, this, temp_result, recursion_data, false, transform_state,
@@ -2497,7 +2422,7 @@ PaintLayer* PaintLayer::HitTestChildren(
}
void PaintLayer::UpdateFilterReferenceBox() {
- if (!NeedsFilterReferenceBox())
+ if (!HasFilterThatMovesPixels())
return;
FloatRect reference_box =
FloatRect(PhysicalBoundingBoxIncludingStackingChildren(
@@ -2511,16 +2436,6 @@ void PaintLayer::UpdateFilterReferenceBox() {
EnsureResourceInfo().SetFilterReferenceBox(reference_box);
}
-bool PaintLayer::NeedsFilterReferenceBox() const {
- if (GetLayoutObject().HasReflection() && GetLayoutObject().IsBox())
- return true;
- FilterOperations operations = GetLayoutObject().StyleRef().Filter();
- if (operations.HasBlurOrReferenceFilter())
- return true;
- operations = GetLayoutObject().StyleRef().BackdropFilter();
- return !operations.IsEmpty();
-}
-
FloatRect PaintLayer::FilterReferenceBox() const {
DCHECK(IsAllowedToQueryCompositingState());
if (ResourceInfo())
@@ -2571,13 +2486,9 @@ bool PaintLayer::HitTestClippedOutByClipPath(
return !clip_path->GetPath(reference_box).Contains(point);
}
DCHECK_EQ(clip_path_operation->GetType(), ClipPathOperation::REFERENCE);
- SVGResource* resource =
- To<ReferenceClipPathOperation>(*clip_path_operation).Resource();
- LayoutSVGResourceContainer* container =
- resource ? resource->ResourceContainer() : nullptr;
- if (!container || container->ResourceType() != kClipperResourceType)
+ LayoutSVGResourceClipper* clipper = GetSVGResourceAsType(clip_path_operation);
+ if (!clipper)
return false;
- auto* clipper = ToLayoutSVGResourceClipper(container);
// If the clipPath is using "userspace on use" units, then the origin of
// the coordinate system is the top-left of the reference box, so adjust
// the point accordingly.
@@ -2678,6 +2589,14 @@ void PaintLayer::ExpandRectForStackingChildren(
const PaintLayer& composited_layer,
PhysicalRect& result,
PaintLayer::CalculateBoundsOptions options) const {
+ // If we're locked, th en the subtree does not contribute painted output.
+ // Furthermore, we might not have up-to-date sizing and position information
+ // in the subtree, so skip recursing into the subtree.
+ if (GetLayoutObject().PaintBlockedByDisplayLock(
+ DisplayLockLifecycleTarget::kChildren)) {
+ return;
+ }
+
PaintLayerPaintOrderIterator iterator(*this, kAllChildren);
while (PaintLayer* child_layer = iterator.Next()) {
// Here we exclude both directly composited layers and squashing layers
@@ -2928,6 +2847,12 @@ bool PaintLayer::SupportsSubsequenceCaching() const {
if (GetLayoutObject().IsSVGRoot())
return true;
+ // Don't create subsequence for the document element because the subsequence
+ // for LayoutView serves the same purpose. This can avoid unnecessary paint
+ // chunks that would otherwise be forced by the subsequence.
+ if (GetLayoutObject().IsDocumentElement())
+ return false;
+
// Create subsequence for only stacking contexts whose painting are atomic.
return GetLayoutObject().StyleRef().IsStackingContext();
}
@@ -3438,7 +3363,7 @@ bool PaintLayer::HasFilterThatMovesPixels() const {
const ComputedStyle& style = GetLayoutObject().StyleRef();
if (style.HasFilter() && style.Filter().HasFilterThatMovesPixels())
return true;
- if (style.HasBoxReflect())
+ if (GetLayoutObject().HasReflection())
return true;
return false;
}
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 29b9f163f4a..98a46602c6d 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer.h
@@ -315,6 +315,9 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
// FIXME: size() should DCHECK(!needs_position_update_) as well, but that
// fails in some tests, for example, fast/repaint/clipped-relative.html.
const LayoutSize& Size() const { return size_; }
+ // TODO(crbug.com/962299): This method snaps to pixels incorrectly because
+ // Location() is not the correct paint offset. It's also incorrect in flipped
+ // blocks writing mode.
IntSize PixelSnappedSize() const {
LayoutPoint location = layout_object_.IsBox()
? ToLayoutBox(layout_object_).Location()
@@ -506,10 +509,6 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
TransformationMatrix CurrentTransform() const;
TransformationMatrix RenderableTransform(GlobalPaintFlags) const;
- // Get the perspective transform, which is applied to transformed sublayers.
- // Returns true if the layer has a -webkit-perspective.
- // Note that this transform does not have the perspective-origin baked in.
- TransformationMatrix PerspectiveTransform() const;
FloatPoint PerspectiveOrigin() const;
bool Preserves3D() const {
return GetLayoutObject().StyleRef().Preserves3D();
@@ -793,8 +792,11 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
bool is_under_position_sticky = false;
};
+ bool NeedsVisualOverflowRecalc() const {
+ return needs_visual_overflow_recalc_;
+ }
void SetNeedsVisualOverflowRecalc();
- void SetNeedsCompositingInputsUpdate();
+ void SetNeedsCompositingInputsUpdate(bool mark_ancestor_flags = true);
// This methods marks everything from this layer up to the |ancestor| argument
// (both included).
@@ -975,24 +977,6 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
const PhysicalOffset* offset_from_root = nullptr,
const PhysicalOffset& sub_pixel_accumulation = PhysicalOffset()) const;
- enum TransparencyClipBoxBehavior {
- kPaintingTransparencyClipBox,
- kHitTestingTransparencyClipBox
- };
-
- enum TransparencyClipBoxMode {
- kDescendantsOfTransparencyClipBox,
- kRootOfTransparencyClipBox
- };
-
- static PhysicalRect TransparencyClipBox(
- const PaintLayer*,
- const PaintLayer* root_layer,
- TransparencyClipBoxBehavior transparency_behavior,
- TransparencyClipBoxMode transparency_mode,
- const PhysicalOffset& sub_pixel_accumulation,
- GlobalPaintFlags = kGlobalPaintNormalPhase);
-
bool SelfNeedsRepaint() const { return self_needs_repaint_; }
bool DescendantNeedsRepaint() const { return descendant_needs_repaint_; }
bool SelfOrDescendantNeedsRepaint() const {
@@ -1037,15 +1021,6 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
needs_paint_phase_float_ = true;
}
- // Similar to above, but for PaintPhaseDescendantBlockBackgroundsOnly.
- bool NeedsPaintPhaseDescendantBlockBackgrounds() const {
- return needs_paint_phase_descendant_block_backgrounds_;
- }
- void SetNeedsPaintPhaseDescendantBlockBackgrounds() {
- DCHECK(IsSelfPaintingLayer());
- needs_paint_phase_descendant_block_backgrounds_ = true;
- }
-
bool DescendantHasDirectOrScrollingCompositingReason() const {
return descendant_has_direct_or_scrolling_compositing_reason_;
}
@@ -1123,10 +1098,6 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
void DirtyStackingContextZOrderLists();
- bool NeedsVisualOverflowRecalcForTesting() const {
- return needs_visual_overflow_recalc_;
- }
-
PhysicalOffset OffsetForInFlowRelPosition() const {
return rare_data_ ? rare_data_->offset_for_in_flow_rel_position
: PhysicalOffset();
@@ -1198,6 +1169,7 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
const PhysicalOffset& translation_offset = PhysicalOffset()) const;
bool HitTestContents(HitTestResult&,
+ const NGPhysicalBoxFragment*,
const PhysicalOffset& fragment_offset,
const HitTestLocation&,
HitTestFilter) const;
@@ -1264,8 +1236,6 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
needs_paint_phase_descendant_outlines_ |=
layer.needs_paint_phase_descendant_outlines_;
needs_paint_phase_float_ |= layer.needs_paint_phase_float_;
- needs_paint_phase_descendant_block_backgrounds_ |=
- layer.needs_paint_phase_descendant_block_backgrounds_;
}
void ExpandRectForStackingChildren(const PaintLayer& composited_layer,
@@ -1281,8 +1251,6 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
bool ShouldApplyTransformToBoundingBox(const PaintLayer& composited_layer,
CalculateBoundsOptions) const;
- bool NeedsFilterReferenceBox() const;
-
AncestorDependentCompositingInputs& EnsureAncestorDependentCompositingInputs()
const {
if (!ancestor_dependent_compositing_inputs_) {
@@ -1347,7 +1315,6 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
unsigned needs_paint_phase_descendant_outlines_ : 1;
unsigned needs_paint_phase_float_ : 1;
- unsigned needs_paint_phase_descendant_block_backgrounds_ : 1;
// These bitfields are part of ancestor/descendant dependent compositing
// inputs.
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_clipper_test.cc b/chromium/third_party/blink/renderer/core/paint/paint_layer_clipper_test.cc
index 661c7c33a8b..6aaa19c0b1d 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_clipper_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_clipper_test.cc
@@ -183,21 +183,12 @@ TEST_F(PaintLayerClipperTest, ControlClip) {
.CalculateRects(context,
&target_paint_layer->GetLayoutObject().FirstFragment(),
nullptr, layer_bounds, background_rect, foreground_rect);
-#if defined(OS_MACOSX)
- // If the PaintLayer clips overflow, the background rect is intersected with
- // the PaintLayer bounds...
- EXPECT_EQ(PhysicalRect(3, 4, 210, 28), background_rect.Rect());
- // and the foreground rect is intersected with the control clip in this case.
- EXPECT_EQ(PhysicalRect(8, 8, 200, 18), foreground_rect.Rect());
- EXPECT_EQ(PhysicalRect(8, 8, 200, 18), layer_bounds);
-#else
// If the PaintLayer clips overflow, the background rect is intersected with
// the PaintLayer bounds...
EXPECT_EQ(PhysicalRect(8, 8, 200, 300), background_rect.Rect());
// and the foreground rect is intersected with the control clip in this case.
EXPECT_EQ(PhysicalRect(10, 10, 196, 296), foreground_rect.Rect());
EXPECT_EQ(PhysicalRect(8, 8, 200, 300), layer_bounds);
-#endif
}
TEST_F(PaintLayerClipperTest, RoundedClip) {
@@ -302,8 +293,8 @@ TEST_F(PaintLayerClipperTest, ControlClipSelect) {
PhysicalRect content_box_rect = target->PhysicalContentBoxRect();
EXPECT_GT(foreground_rect.Rect().X(),
content_box_rect.X() + target->Location().X());
- EXPECT_LT(foreground_rect.Rect().Width(), content_box_rect.Width());
-} // namespace blink
+ EXPECT_LE(foreground_rect.Rect().Width(), content_box_rect.Width());
+}
TEST_F(PaintLayerClipperTest, LayoutSVGRootChild) {
SetBodyInnerHTML(R"HTML(
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_fragment.h b/chromium/third_party/blink/renderer/core/paint/paint_layer_fragment.h
index 6b0d2e3a7d7..9ffa07ab179 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_fragment.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_fragment.h
@@ -33,6 +33,7 @@
namespace blink {
class FragmentData;
+class NGPhysicalBoxFragment;
// PaintLayerFragment is the representation of a fragment.
// https://drafts.csswg.org/css-break/#fragment
@@ -84,6 +85,8 @@ struct PaintLayerFragment {
// The corresponding FragmentData of this structure.
const FragmentData* fragment_data = nullptr;
+
+ const NGPhysicalBoxFragment* physical_fragment = nullptr;
};
typedef Vector<PaintLayerFragment, 1> PaintLayerFragments;
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 7e1b0ab4992..9017869339e 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
@@ -7,21 +7,24 @@
#include "base/optional.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/layout/layout_video.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/paint/clip_path_clipper.h"
#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
+#include "third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h"
#include "third_party/blink/renderer/core/paint/object_paint_properties.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/paint_layer_paint_order_iterator.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
+#include "third_party/blink/renderer/core/paint/paint_timing_detector.h"
#include "third_party/blink/renderer/core/paint/scrollable_area_painter.h"
#include "third_party/blink/renderer/platform/geometry/float_point_3d.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
#include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h"
#include "third_party/blink/renderer/platform/graphics/paint/scoped_display_item_fragment.h"
-#include "third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_properties.h"
+#include "third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_hint.h"
#include "third_party/blink/renderer/platform/graphics/paint/subsequence_recorder.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -46,8 +49,6 @@ static ShouldRespectOverflowClipType ShouldRespectOverflowClip(
}
bool PaintLayerPainter::PaintedOutputInvisible(const ComputedStyle& style) {
- DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
-
if (style.HasBackdropFilter())
return false;
@@ -75,19 +76,16 @@ PaintResult PaintLayerPainter::Paint(
if (paint_layer_.GetLayoutObject().GetFrameView()->ShouldThrottleRendering())
return kFullyPainted;
- // https://code.google.com/p/chromium/issues/detail?id=343772
- DisableCompositingQueryAsserts disabler;
-
// Non self-painting layers without self-painting descendants don't need to be
// painted as their layoutObject() should properly paint itself.
if (!paint_layer_.IsSelfPaintingLayer() &&
!paint_layer_.HasSelfPaintingLayerDescendant())
return kFullyPainted;
- // If this layer is totally invisible then there is nothing to paint. In CAP
- // we simplify this optimization by painting even when effectively invisible
- // but skipping the painted content during layerization in
- // PaintArtifactCompositor.
+ // If this layer is totally invisible then there is nothing to paint.
+ // In CompositeAfterPaint we simplify this optimization by painting even when
+ // effectively invisible but skipping the painted content during layerization
+ // in PaintArtifactCompositor.
if (paint_layer_.PaintsWithTransparency(
painting_info.GetGlobalPaintFlags())) {
if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
@@ -108,10 +106,10 @@ PaintResult PaintLayerPainter::Paint(
return PaintLayerContents(context, painting_info, paint_flags);
}
-static bool ShouldCreateSubsequence(const PaintLayer& paint_layer,
- const GraphicsContext& context,
- const PaintLayerPaintingInfo& painting_info,
- PaintLayerFlags paint_flags) {
+static bool ShouldCreateSubsequence(
+ const PaintLayer& paint_layer,
+ const GraphicsContext& context,
+ const PaintLayerPaintingInfo& painting_info) {
// Caching is not needed during printing or painting previews.
if (context.Printing() || context.IsPaintingPreview())
return false;
@@ -127,7 +125,8 @@ static bool ShouldCreateSubsequence(const PaintLayer& paint_layer,
// CachedDisplayItemList. This also avoids conflict of
// PaintLayer::previousXXX() when paintLayer is composited scrolling and is
// painted twice for GraphicsLayers of container and scrolling contents.
- if (paint_layer.GetCompositingState() == kPaintsIntoOwnBacking)
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
+ paint_layer.GetCompositingState() == kPaintsIntoOwnBacking)
return false;
// Don't create subsequence during special painting to avoid cache conflict
@@ -136,9 +135,6 @@ static bool ShouldCreateSubsequence(const PaintLayer& paint_layer,
kGlobalPaintFlattenCompositingLayers)
return false;
- if (paint_flags & kPaintLayerPaintingOverlayOverflowControls)
- return false;
-
return true;
}
@@ -196,7 +192,7 @@ static bool IsMainFrameNotClippingContents(const PaintLayer& layer) {
// If MainFrameClipsContent is false which means that WebPreferences::
// record_whole_document is true, we should not cull the scrolling contents
// of the main frame.
- if (layer.GetLayoutObject().IsLayoutView()) {
+ if (IsA<LayoutView>(layer.GetLayoutObject())) {
const auto* frame = layer.GetLayoutObject().GetFrame();
if (frame && frame->IsMainFrame() && !frame->ClipsContent())
return true;
@@ -326,6 +322,15 @@ PaintResult PaintLayerPainter::PaintLayerContents(
return kMayBeClippedByCullRect;
}
+ bool selection_drag_image_only = painting_info_arg.GetGlobalPaintFlags() &
+ kGlobalPaintSelectionDragImageOnly;
+ if (selection_drag_image_only && !paint_layer_.GetLayoutObject().IsSelected())
+ return result;
+
+ base::Optional<IgnorePaintTimingScope> ignore_paint_timing;
+ if (PaintedOutputInvisible(paint_layer_.GetLayoutObject().StyleRef()))
+ ignore_paint_timing.emplace();
+
PaintLayerFlags paint_flags = paint_flags_arg;
PaintLayerPaintingInfo painting_info = painting_info_arg;
AdjustForPaintProperties(context, painting_info, paint_flags);
@@ -355,15 +360,25 @@ PaintResult PaintLayerPainter::PaintLayerContents(
paint_layer_.GetLayoutObject().StyleRef().HasOutline();
PhysicalOffset subpixel_accumulation =
- paint_layer_.GetCompositingState() == kPaintsIntoOwnBacking
+ (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
+ paint_layer_.GetCompositingState() == kPaintsIntoOwnBacking)
? paint_layer_.SubpixelAccumulation()
: painting_info.sub_pixel_accumulation;
ShouldRespectOverflowClipType respect_overflow_clip =
ShouldRespectOverflowClip(paint_flags, paint_layer_.GetLayoutObject());
- bool should_create_subsequence = ShouldCreateSubsequence(
- paint_layer_, context, painting_info, paint_flags);
+ bool should_paint_content =
+ paint_layer_.HasVisibleContent() &&
+ // Content under a LayoutSVGHiddenContainer is auxiliary resources for
+ // painting. Foreign content should never paint in this situation, as it
+ // is primary, not auxiliary.
+ !paint_layer_.IsUnderSVGHiddenContainer() && is_self_painting_layer &&
+ !is_painting_overlay_overflow_controls;
+
+ bool should_create_subsequence =
+ should_paint_content &&
+ ShouldCreateSubsequence(paint_layer_, context, painting_info);
base::Optional<SubsequenceRecorder> subsequence_recorder;
if (should_create_subsequence) {
@@ -397,20 +412,13 @@ PaintResult PaintLayerPainter::PaintLayerContents(
subpixel_accumulation)
: offset_from_root;
clip_path_clipper.emplace(context, paint_layer_.GetLayoutObject(),
+ paint_layer_.GetLayoutObject(),
visual_offset_from_root);
}
PaintLayerPaintingInfo local_painting_info(painting_info);
local_painting_info.sub_pixel_accumulation = subpixel_accumulation;
- bool should_paint_content =
- paint_layer_.HasVisibleContent() &&
- // Content under a LayoutSVGHiddenContainer is auxiliary resources for
- // painting. Foreign content should never paint in this situation, as it
- // is primary, not auxiliary.
- !paint_layer_.IsUnderSVGHiddenContainer() && is_self_painting_layer &&
- !is_painting_overlay_overflow_controls;
-
PaintLayerFragments layer_fragments;
if (should_paint_content || should_paint_self_outline ||
@@ -437,16 +445,10 @@ PaintResult PaintLayerPainter::PaintLayerContents(
}
}
- bool selection_only =
- local_painting_info.GetGlobalPaintFlags() & kGlobalPaintSelectionOnly;
-
{ // Begin block for the lifetime of any filter.
- size_t display_item_list_size_before_painting =
- context.GetPaintController().NewDisplayItemList().size();
-
bool is_painting_root_layer = (&paint_layer_) == painting_info.root_layer;
bool should_paint_background =
- should_paint_content && !selection_only &&
+ should_paint_content && !selection_drag_image_only &&
(is_painting_composited_background ||
(is_painting_root_layer &&
!(paint_flags & kPaintLayerPaintingSkipRootBackground)));
@@ -459,46 +461,45 @@ PaintResult PaintLayerPainter::PaintLayerContents(
bool should_paint_normal_flow_and_pos_z_order_lists =
is_painting_composited_foreground &&
!is_painting_overlay_overflow_controls;
- bool is_video = paint_layer_.GetLayoutObject().IsVideo();
-
- base::Optional<ScopedPaintChunkProperties>
- subsequence_forced_chunk_properties;
- if (subsequence_recorder && paint_layer_.HasSelfPaintingLayerDescendant()) {
- // Prepare for forced paint chunks to ensure chunk id stability to avoid
- // unnecessary full chunk raster invalidations on changed chunk ids.
- // TODO(crbug.com/834606): This may be unnecessary after we refactor
- // raster invalidation not to depend on chunk ids too much.
- subsequence_forced_chunk_properties.emplace(
- context.GetPaintController(),
- paint_layer_.GetLayoutObject()
- .FirstFragment()
- .LocalBorderBoxProperties(),
- paint_layer_, DisplayItem::kUninitializedType);
+ bool is_video = IsA<LayoutVideo>(paint_layer_.GetLayoutObject());
+
+ base::Optional<ScopedPaintChunkHint> paint_chunk_hint;
+ if (should_paint_content) {
+ paint_chunk_hint.emplace(context.GetPaintController(),
+ paint_layer_.GetLayoutObject()
+ .FirstFragment()
+ .LocalBorderBoxProperties(),
+ paint_layer_, DisplayItem::kLayerChunk);
}
if (should_paint_background) {
- if (subsequence_forced_chunk_properties) {
- context.GetPaintController().ForceNewChunk(
- paint_layer_, DisplayItem::kLayerChunkBackground);
- }
PaintBackgroundForFragments(layer_fragments, context, local_painting_info,
paint_flags);
}
if (should_paint_neg_z_order_list) {
- if (subsequence_forced_chunk_properties) {
- context.GetPaintController().ForceNewChunk(
- paint_layer_, DisplayItem::kLayerChunkNegativeZOrderChildren);
- }
if (PaintChildren(kNegativeZOrderChildren, context, painting_info,
paint_flags) == kMayBeClippedByCullRect)
result = kMayBeClippedByCullRect;
}
if (should_paint_own_contents) {
- PaintForegroundForFragments(
- layer_fragments, context, local_painting_info, selection_only,
- !!subsequence_forced_chunk_properties, paint_flags);
+ base::Optional<ScopedPaintChunkHint> paint_chunk_hint_foreground;
+ if (paint_chunk_hint && paint_chunk_hint->HasCreatedPaintChunk()) {
+ // Hint a foreground chunk if we have created any chunks, to give the
+ // paint chunk after the previous forced paint chunks a stable id.
+ paint_chunk_hint_foreground.emplace(context.GetPaintController(),
+ paint_layer_,
+ DisplayItem::kLayerChunkForeground);
+ }
+ if (selection_drag_image_only) {
+ PaintForegroundForFragmentsWithPhase(PaintPhase::kSelectionDragImage,
+ layer_fragments, context,
+ local_painting_info, paint_flags);
+ } else {
+ PaintForegroundForFragments(layer_fragments, context,
+ local_painting_info, paint_flags);
+ }
}
if (!is_video && should_paint_self_outline) {
@@ -507,11 +508,6 @@ PaintResult PaintLayerPainter::PaintLayerContents(
}
if (should_paint_normal_flow_and_pos_z_order_lists) {
- if (subsequence_forced_chunk_properties) {
- context.GetPaintController().ForceNewChunk(
- paint_layer_,
- DisplayItem::kLayerChunkNormalFlowAndPositiveZOrderChildren);
- }
if (PaintChildren(kNormalFlowAndPositiveZOrderChildren, context,
painting_info, paint_flags) == kMayBeClippedByCullRect)
result = kMayBeClippedByCullRect;
@@ -532,24 +528,11 @@ PaintResult PaintLayerPainter::PaintLayerContents(
PaintSelfOutlineForFragments(layer_fragments, context,
local_painting_info, paint_flags);
}
-
- if (!is_painting_overlay_overflow_controls) {
- // For filters, if the layer painted nothing, we need to issue a no-op
- // display item to ensure the filters won't be ignored. For backdrop
- // filters, we issue the display item regardless of other paintings to
- // ensure correct bounds of the composited layer for the backdrop filter.
- if ((paint_layer_.PaintsWithFilters() &&
- display_item_list_size_before_painting ==
- context.GetPaintController().NewDisplayItemList().size()) ||
- paint_layer_.GetLayoutObject().HasBackdropFilter()) {
- PaintEmptyContentForFilters(context);
- }
- }
} // FilterPainter block
bool should_paint_mask = is_painting_mask && should_paint_content &&
paint_layer_.GetLayoutObject().HasMask() &&
- !selection_only;
+ !selection_drag_image_only;
if (should_paint_mask) {
PaintMaskForFragments(layer_fragments, context, local_painting_info,
paint_flags);
@@ -739,7 +722,10 @@ void PaintLayerPainter::PaintFragmentWithPhase(
DisplayLockLifecycleTarget::kChildren))) {
paint_info.SetDescendantPaintingBlocked(true);
}
- paint_layer_.GetLayoutObject().Paint(paint_info);
+ if (fragment.physical_fragment)
+ NGBoxFragmentPainter(*fragment.physical_fragment).Paint(paint_info);
+ else
+ paint_layer_.GetLayoutObject().Paint(paint_info);
}
void PaintLayerPainter::PaintBackgroundForFragments(
@@ -759,57 +745,33 @@ void PaintLayerPainter::PaintForegroundForFragments(
const PaintLayerFragments& layer_fragments,
GraphicsContext& context,
const PaintLayerPaintingInfo& local_painting_info,
- bool selection_only,
- bool force_paint_chunks,
PaintLayerFlags paint_flags) {
- if (selection_only) {
- PaintForegroundForFragmentsWithPhase(PaintPhase::kSelection,
+ PaintForegroundForFragmentsWithPhase(
+ PaintPhase::kDescendantBlockBackgroundsOnly, layer_fragments, context,
+ local_painting_info, paint_flags);
+
+ if (paint_layer_.GetLayoutObject().GetDocument().InForcedColorsMode()) {
+ PaintForegroundForFragmentsWithPhase(PaintPhase::kForcedColorsModeBackplate,
layer_fragments, context,
local_painting_info, paint_flags);
- } else {
- if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() ||
- paint_layer_.NeedsPaintPhaseDescendantBlockBackgrounds()) {
- if (force_paint_chunks) {
- context.GetPaintController().ForceNewChunk(
- paint_layer_, DisplayItem::kLayerChunkDescendantBackgrounds);
- }
- PaintForegroundForFragmentsWithPhase(
- PaintPhase::kDescendantBlockBackgroundsOnly, layer_fragments, context,
- local_painting_info, paint_flags);
- }
-
- if (paint_layer_.GetLayoutObject().GetDocument().InForcedColorsMode()) {
- PaintForegroundForFragmentsWithPhase(
- PaintPhase::kForcedColorsModeBackplate, layer_fragments, context,
- local_painting_info, paint_flags);
- }
+ }
- if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() ||
- paint_layer_.NeedsPaintPhaseFloat()) {
- if (force_paint_chunks) {
- context.GetPaintController().ForceNewChunk(
- paint_layer_, DisplayItem::kLayerChunkFloat);
- }
- PaintForegroundForFragmentsWithPhase(PaintPhase::kFloat, layer_fragments,
- context, local_painting_info,
- paint_flags);
- }
+ if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() ||
+ paint_layer_.NeedsPaintPhaseFloat()) {
+ PaintForegroundForFragmentsWithPhase(PaintPhase::kFloat, layer_fragments,
+ context, local_painting_info,
+ paint_flags);
+ }
- if (force_paint_chunks) {
- context.GetPaintController().ForceNewChunk(
- paint_layer_, DisplayItem::kLayerChunkForeground);
- }
+ PaintForegroundForFragmentsWithPhase(PaintPhase::kForeground, layer_fragments,
+ context, local_painting_info,
+ paint_flags);
- PaintForegroundForFragmentsWithPhase(PaintPhase::kForeground,
+ if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() ||
+ paint_layer_.NeedsPaintPhaseDescendantOutlines()) {
+ PaintForegroundForFragmentsWithPhase(PaintPhase::kDescendantOutlinesOnly,
layer_fragments, context,
local_painting_info, paint_flags);
-
- if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() ||
- paint_layer_.NeedsPaintPhaseDescendantOutlines()) {
- PaintForegroundForFragmentsWithPhase(PaintPhase::kDescendantOutlinesOnly,
- layer_fragments, context,
- local_painting_info, paint_flags);
- }
}
}
@@ -878,21 +840,4 @@ void PaintLayerPainter::FillMaskingFragment(GraphicsContext& context,
context.FillRect(snapped_clip_rect, Color::kBlack);
}
-// Generate a no-op DrawingDisplayItem to ensure a non-empty chunk for the
-// filter without content.
-void PaintLayerPainter::PaintEmptyContentForFilters(GraphicsContext& context) {
- DCHECK(paint_layer_.PaintsWithFilters() ||
- paint_layer_.GetLayoutObject().HasBackdropFilter());
-
- ScopedPaintChunkProperties paint_chunk_properties(
- context.GetPaintController(),
- paint_layer_.GetLayoutObject().FirstFragment().LocalBorderBoxProperties(),
- paint_layer_, DisplayItem::kEmptyContentForFilters);
- if (DrawingRecorder::UseCachedDrawingIfPossible(
- context, paint_layer_, DisplayItem::kEmptyContentForFilters))
- return;
- DrawingRecorder recorder(context, paint_layer_,
- DisplayItem::kEmptyContentForFilters);
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_painter.h b/chromium/third_party/blink/renderer/core/paint/paint_layer_painter.h
index e61f2ceadc5..29e13df3cb4 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_painter.h
@@ -82,8 +82,6 @@ class CORE_EXPORT PaintLayerPainter {
void PaintForegroundForFragments(const PaintLayerFragments&,
GraphicsContext&,
const PaintLayerPaintingInfo&,
- bool selection_only,
- bool force_paint_chunks,
PaintLayerFlags);
void PaintForegroundForFragmentsWithPhase(PaintPhase,
const PaintLayerFragments&,
@@ -107,8 +105,6 @@ class CORE_EXPORT PaintLayerPainter {
const ClipRect&,
const DisplayItemClient&);
- void PaintEmptyContentForFilters(GraphicsContext&);
-
void AdjustForPaintProperties(const GraphicsContext&,
PaintLayerPaintingInfo&,
PaintLayerFlags&);
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc b/chromium/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc
index c2c9d6a4ddc..c191b7a6e9a 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc
@@ -48,8 +48,9 @@ class PaintLayerPainterTest : public PaintControllerPaintTest {
INSTANTIATE_PAINT_TEST_SUITE_P(PaintLayerPainterTest);
-TEST_P(PaintLayerPainterTest, CachedSubsequence) {
+TEST_P(PaintLayerPainterTest, CachedSubsequenceAndChunksWithBackgrounds) {
SetBodyInnerHTML(R"HTML(
+ <style>body { margin: 0 }</style>
<div id='container1' style='position: relative; z-index: 1;
width: 200px; height: 200px; background-color: blue'>
<div id='content1' style='position: absolute; width: 100px;
@@ -66,101 +67,179 @@ TEST_P(PaintLayerPainterTest, CachedSubsequence) {
width: 20px; height: 20px; background-color: gray'></div>
)HTML");
- auto& container1 = *GetLayoutObjectByElementId("container1");
- auto& content1 = *GetLayoutObjectByElementId("content1");
- auto& filler1 = *GetLayoutObjectByElementId("filler1");
- auto& container2 = *GetLayoutObjectByElementId("container2");
- auto& content2 = *GetLayoutObjectByElementId("content2");
- auto& filler2 = *GetLayoutObjectByElementId("filler2");
-
+ auto* container1 = GetLayoutObjectByElementId("container1");
+ auto* content1 = GetLayoutObjectByElementId("content1");
+ auto* filler1 = GetLayoutObjectByElementId("filler1");
+ auto* container2 = GetLayoutObjectByElementId("container2");
+ auto* content2 = GetLayoutObjectByElementId("content2");
+ auto* filler2 = GetLayoutObjectByElementId("filler2");
const auto& view_client = ViewScrollingBackgroundClient();
- EXPECT_THAT(
- RootPaintController().GetDisplayItemList(),
- ElementsAre(IsSameId(&view_client, kDocumentBackgroundType),
- IsSameId(GetDisplayItemClientFromLayoutObject(&container1),
- kBackgroundType),
- IsSameId(GetDisplayItemClientFromLayoutObject(&content1),
- kBackgroundType),
- IsSameId(GetDisplayItemClientFromLayoutObject(&filler1),
- kBackgroundType),
- IsSameId(GetDisplayItemClientFromLayoutObject(&container2),
- kBackgroundType),
- IsSameId(GetDisplayItemClientFromLayoutObject(&content2),
- kBackgroundType),
- IsSameId(GetDisplayItemClientFromLayoutObject(&filler2),
- kBackgroundType)));
- auto* container1_layer = ToLayoutBoxModelObject(container1).Layer();
- auto* filler1_layer = ToLayoutBoxModelObject(filler1).Layer();
- auto* container2_layer = ToLayoutBoxModelObject(container2).Layer();
- auto* filler2_layer = ToLayoutBoxModelObject(filler2).Layer();
+ auto* container1_layer = ToLayoutBoxModelObject(container1)->Layer();
+ auto* filler1_layer = ToLayoutBoxModelObject(filler1)->Layer();
+ auto* container2_layer = ToLayoutBoxModelObject(container2)->Layer();
+ auto* filler2_layer = ToLayoutBoxModelObject(filler2)->Layer();
auto chunk_state = GetLayoutView().FirstFragment().ContentsProperties();
- auto view_chunk_type = kDocumentBackgroundType;
- auto chunk_background_type = DisplayItem::kLayerChunkBackground;
- auto chunk_foreground_type =
- DisplayItem::kLayerChunkNormalFlowAndPositiveZOrderChildren;
- auto filler_chunk_type = DisplayItem::PaintPhaseToDrawingType(
- PaintPhase::kSelfBlockBackgroundOnly);
-
- auto check_chunks = [&]() {
- // Check that new paint chunks were forced for |container1| and
- // |container2|.
+ auto check_results = [&]() {
+ EXPECT_THAT(
+ RootPaintController().GetDisplayItemList(),
+ ElementsAre(IsSameId(&view_client, kDocumentBackgroundType),
+ IsSameId(GetDisplayItemClientFromLayoutObject(container1),
+ kBackgroundType),
+ IsSameId(GetDisplayItemClientFromLayoutObject(content1),
+ kBackgroundType),
+ IsSameId(GetDisplayItemClientFromLayoutObject(filler1),
+ kBackgroundType),
+ IsSameId(GetDisplayItemClientFromLayoutObject(container2),
+ kBackgroundType),
+ IsSameId(GetDisplayItemClientFromLayoutObject(content2),
+ kBackgroundType),
+ IsSameId(GetDisplayItemClientFromLayoutObject(filler2),
+ kBackgroundType)));
+
+ EXPECT_SUBSEQUENCE(*container1_layer, 1, 2);
+ EXPECT_SUBSEQUENCE(*filler1_layer, 2, 3);
+ EXPECT_SUBSEQUENCE(*container2_layer, 3, 4);
+ EXPECT_SUBSEQUENCE(*filler2_layer, 4, 5);
+
+ // Check that new paint chunks were forced for the layers.
EXPECT_THAT(
RootPaintController().PaintChunks(),
ElementsAre(
- IsPaintChunk(0, 1, PaintChunk::Id(view_client, view_chunk_type),
- chunk_state),
+ IsPaintChunk(0, 1),
IsPaintChunk(
- 1, 2, PaintChunk::Id(*container1_layer, chunk_background_type),
- chunk_state),
+ 1, 3,
+ PaintChunk::Id(*container1_layer, DisplayItem::kLayerChunk),
+ chunk_state, nullptr, IntRect(0, 0, 200, 200)),
IsPaintChunk(
- 2, 3, PaintChunk::Id(*container1_layer, chunk_foreground_type),
- chunk_state),
- IsPaintChunk(3, 4,
- PaintChunk::Id(*filler1_layer, filler_chunk_type),
- chunk_state),
+ 3, 4, PaintChunk::Id(*filler1_layer, DisplayItem::kLayerChunk),
+ chunk_state, nullptr, IntRect(0, 200, 20, 20)),
IsPaintChunk(
- 4, 5, PaintChunk::Id(*container2_layer, chunk_background_type),
- chunk_state),
+ 4, 6,
+ PaintChunk::Id(*container2_layer, DisplayItem::kLayerChunk),
+ chunk_state, nullptr, IntRect(0, 220, 200, 200)),
IsPaintChunk(
- 5, 6, PaintChunk::Id(*container2_layer, chunk_foreground_type),
- chunk_state),
- IsPaintChunk(6, 7,
- PaintChunk::Id(*filler2_layer, filler_chunk_type),
- chunk_state)));
+ 6, 7, PaintChunk::Id(*filler2_layer, DisplayItem::kLayerChunk),
+ chunk_state, nullptr, IntRect(0, 420, 20, 20))));
};
- check_chunks();
+ check_results();
- To<HTMLElement>(content1.GetNode())
+ To<HTMLElement>(content1->GetNode())
->setAttribute(html_names::kStyleAttr,
"position: absolute; width: 100px; height: 100px; "
"background-color: green");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(PaintWithoutCommit());
EXPECT_EQ(6, NumCachedNewItems());
CommitAndFinishCycle();
+ // We should still have the paint chunks forced by the cached subsequences.
+ check_results();
+}
+
+TEST_P(PaintLayerPainterTest, CachedSubsequenceAndChunksWithoutBackgrounds) {
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ return;
+
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ body { margin: 0 }
+ ::-webkit-scrollbar { display: none }
+ </style>
+ <div id='container' style='position: relative; z-index: 0;
+ width: 150px; height: 150px; overflow: scroll'>
+ <div id='content' style='position: relative; z-index: 1;
+ width: 200px; height: 100px'>
+ <div id='inner-content'
+ style='position: absolute; width: 100px; height: 100px'></div>
+ </div>
+ <div id='filler' style='position: relative; z-index: 2;
+ width: 300px; height: 300px'></div>
+ </div>
+ )HTML");
+
+ auto* container = GetLayoutObjectByElementId("container");
+ auto* content = GetLayoutObjectByElementId("content");
+ auto* inner_content = GetLayoutObjectByElementId("inner-content");
+ auto* filler = GetLayoutObjectByElementId("filler");
+ const auto& view_client = ViewScrollingBackgroundClient();
+
+ EXPECT_THAT(RootPaintController().GetDisplayItemList(),
+ ElementsAre(IsSameId(&view_client, kDocumentBackgroundType)));
+
+ auto* container_layer = ToLayoutBoxModelObject(container)->Layer();
+ auto* content_layer = ToLayoutBoxModelObject(content)->Layer();
+ auto* inner_content_layer = ToLayoutBoxModelObject(inner_content)->Layer();
+ auto* filler_layer = ToLayoutBoxModelObject(filler)->Layer();
+
+ EXPECT_SUBSEQUENCE(*container_layer, 1, 5);
+ EXPECT_SUBSEQUENCE(*content_layer, 3, 4);
+ EXPECT_SUBSEQUENCE(*filler_layer, 4, 5);
+
+ auto container_properties =
+ container->FirstFragment().LocalBorderBoxProperties();
+ auto content_properties = container->FirstFragment().ContentsProperties();
+ HitTestData scroll_hit_test;
+ scroll_hit_test.scroll_translation = &content_properties.Transform();
+ scroll_hit_test.scroll_hit_test_rect = IntRect(0, 0, 150, 150);
+
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(
+ IsPaintChunk(0, 1),
+ IsPaintChunk(
+ 1, 1, PaintChunk::Id(*container_layer, DisplayItem::kLayerChunk),
+ container_properties, nullptr, IntRect(0, 0, 150, 150)),
+ IsPaintChunk(
+ 1, 1, PaintChunk::Id(*container, DisplayItem::kScrollHitTest),
+ container_properties, &scroll_hit_test, IntRect(0, 0, 150, 150)),
+ IsPaintChunk(1, 1,
+ PaintChunk::Id(*content_layer, DisplayItem::kLayerChunk),
+ content_properties, nullptr, IntRect(0, 0, 200, 100)),
+ IsPaintChunk(
+ 1, 1, PaintChunk::Id(*filler_layer, DisplayItem::kLayerChunk),
+ content_properties, nullptr, IntRect(0, 100, 300, 300))));
+
+ To<HTMLElement>(inner_content->GetNode())
+ ->setAttribute(html_names::kStyleAttr,
+ "position: absolute; width: 100px; height: 100px; "
+ "top: 100px; background-color: green");
+ UpdateAllLifecyclePhasesForTest();
+
EXPECT_THAT(
RootPaintController().GetDisplayItemList(),
ElementsAre(IsSameId(&view_client, kDocumentBackgroundType),
- IsSameId(GetDisplayItemClientFromLayoutObject(&container1),
- kBackgroundType),
- IsSameId(GetDisplayItemClientFromLayoutObject(&content1),
- kBackgroundType),
- IsSameId(GetDisplayItemClientFromLayoutObject(&filler1),
- kBackgroundType),
- IsSameId(GetDisplayItemClientFromLayoutObject(&container2),
- kBackgroundType),
- IsSameId(GetDisplayItemClientFromLayoutObject(&content2),
- kBackgroundType),
- IsSameId(GetDisplayItemClientFromLayoutObject(&filler2),
+ IsSameId(GetDisplayItemClientFromLayoutObject(inner_content),
kBackgroundType)));
- // We should still have the paint chunks forced by the cached subsequences.
- check_chunks();
+ EXPECT_SUBSEQUENCE(*container_layer, 1, 6);
+ EXPECT_SUBSEQUENCE(*content_layer, 3, 5);
+ EXPECT_SUBSEQUENCE(*filler_layer, 5, 6);
+
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(
+ IsPaintChunk(0, 1),
+ IsPaintChunk(
+ 1, 1, PaintChunk::Id(*container_layer, DisplayItem::kLayerChunk),
+ container_properties, nullptr, IntRect(0, 0, 150, 150)),
+ IsPaintChunk(
+ 1, 1, PaintChunk::Id(*container, DisplayItem::kScrollHitTest),
+ container_properties, &scroll_hit_test, IntRect(0, 0, 150, 150)),
+ IsPaintChunk(1, 1,
+ PaintChunk::Id(*content_layer, DisplayItem::kLayerChunk),
+ content_properties, nullptr, IntRect(0, 0, 200, 100)),
+ IsPaintChunk(
+ 1, 2,
+ PaintChunk::Id(*inner_content_layer, DisplayItem::kLayerChunk),
+ content_properties, nullptr, IntRect(0, 100, 100, 100)),
+ IsPaintChunk(
+ 2, 2, PaintChunk::Id(*filler_layer, DisplayItem::kLayerChunk),
+ content_properties, nullptr, IntRect(0, 100, 300, 300))));
}
TEST_P(PaintLayerPainterTest, CachedSubsequenceOnCullRectChange) {
@@ -207,7 +286,8 @@ TEST_P(PaintLayerPainterTest, CachedSubsequenceOnCullRectChange) {
const DisplayItemClient& content3 =
*GetDisplayItemClientFromElementId("content3");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
Paint(IntRect(0, 0, 400, 300));
const auto& background_display_item_client = ViewScrollingBackgroundClient();
@@ -226,7 +306,8 @@ TEST_P(PaintLayerPainterTest, CachedSubsequenceOnCullRectChange) {
IsSameId(&container3, kBackgroundType),
IsSameId(&content3, kBackgroundType)));
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(PaintWithoutCommit(IntRect(0, 100, 300, 1000)));
// Container1 becomes partly in the interest rect, but uses cached subsequence
@@ -262,12 +343,14 @@ TEST_P(PaintLayerPainterTest,
InvalidateAll(RootPaintController());
// |target| will be fully painted.
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
Paint(IntRect(0, 0, 400, 300));
// |target| will be partially painted. Should not trigger under-invalidation
// checking DCHECKs.
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
Paint(IntRect(0, 100, 300, 1000));
}
@@ -285,7 +368,8 @@ TEST_P(PaintLayerPainterTest,
height: 100px; background-color: green'></div>
</div>
)HTML");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
// PaintResult of all subsequences will be MayBeClippedByCullRect.
Paint(IntRect(0, 0, 50, 300));
@@ -311,7 +395,8 @@ TEST_P(PaintLayerPainterTest,
->setAttribute(html_names::kStyleAttr,
"position: absolute; width: 100px; height: 100px; "
"background-color: green");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(PaintWithoutCommit(IntRect(0, 0, 50, 300)));
EXPECT_EQ(4, NumCachedNewItems());
@@ -340,8 +425,8 @@ TEST_P(PaintLayerPainterTest, CachedSubsequenceRetainsPreviousPaintResult) {
<div id="change" style="display: none"></div>
)HTML");
- const auto* target_layer =
- ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))->Layer();
+ const auto* target = ToLayoutBox(GetLayoutObjectByElementId("target"));
+ const auto* target_layer = target->Layer();
const auto* content1 = GetLayoutObjectByElementId("content1");
const auto* content2 = GetLayoutObjectByElementId("content2");
const auto& view_client = ViewScrollingBackgroundClient();
@@ -353,13 +438,13 @@ TEST_P(PaintLayerPainterTest, CachedSubsequenceRetainsPreviousPaintResult) {
EXPECT_EQ(CullRect(IntRect(-4000, -4000, 8800, 8600)),
target_layer->PreviousCullRect());
// |content2| is out of the cull rect.
- EXPECT_THAT(
- RootPaintController().GetDisplayItemList(),
- ElementsAre(IsSameId(&GetLayoutView(), DisplayItem::kScrollHitTest),
- IsSameId(&view_client, kDocumentBackgroundType),
- IsSameId(content1, kBackgroundType)));
+ EXPECT_THAT(RootPaintController().GetDisplayItemList(),
+ ElementsAre(IsSameId(&view_client, kDocumentBackgroundType),
+ IsSameId(content1, kBackgroundType)));
// |target| created subsequence.
- EXPECT_SUBSEQUENCE(*target_layer, 2, 3);
+ EXPECT_SUBSEQUENCE(*target_layer, 2, 4);
+ EXPECT_EQ(0u, RootPaintController().PaintChunks()[2].size());
+ EXPECT_EQ(1u, RootPaintController().PaintChunks()[3].size());
} else {
EXPECT_EQ(CullRect(IntRect(0, 0, 800, 4600)),
target_layer->PreviousCullRect());
@@ -369,35 +454,34 @@ TEST_P(PaintLayerPainterTest, CachedSubsequenceRetainsPreviousPaintResult) {
IsSameId(content1, kBackgroundType)));
// |target| created subsequence.
EXPECT_SUBSEQUENCE(*target_layer, 1, 2);
+ EXPECT_EQ(1u, RootPaintController().PaintChunks()[1].size());
}
// Change something that triggers a repaint but |target| should use cached
// subsequence.
GetDocument().getElementById("change")->setAttribute(html_names::kStyleAttr,
"display: block");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_FALSE(target_layer->SelfNeedsRepaint());
EXPECT_TRUE(PaintWithoutCommit());
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
- EXPECT_EQ(3, NumCachedNewItems());
- else
- EXPECT_EQ(2, NumCachedNewItems());
+ EXPECT_EQ(2, NumCachedNewItems());
CommitAndFinishCycle();
// |target| is still partially painted.
EXPECT_EQ(kMayBeClippedByCullRect, target_layer->PreviousPaintResult());
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
- // CAP doens't clip the cull rect by the scrolling contents rect, which
+ // CAP doesn't clip the cull rect by the scrolling contents rect, which
// doesn't affect painted results.
EXPECT_EQ(CullRect(IntRect(-4000, -4000, 8800, 8600)),
target_layer->PreviousCullRect());
- EXPECT_THAT(
- RootPaintController().GetDisplayItemList(),
- ElementsAre(IsSameId(&GetLayoutView(), DisplayItem::kScrollHitTest),
- IsSameId(&view_client, kDocumentBackgroundType),
- IsSameId(content1, kBackgroundType)));
+ EXPECT_THAT(RootPaintController().GetDisplayItemList(),
+ ElementsAre(IsSameId(&view_client, kDocumentBackgroundType),
+ IsSameId(content1, kBackgroundType)));
// |target| still created subsequence (cached).
- EXPECT_SUBSEQUENCE(*target_layer, 2, 3);
+ EXPECT_SUBSEQUENCE(*target_layer, 2, 4);
+ EXPECT_EQ(0u, RootPaintController().PaintChunks()[2].size());
+ EXPECT_EQ(1u, RootPaintController().PaintChunks()[3].size());
} else {
EXPECT_EQ(CullRect(IntRect(0, 0, 800, 4600)),
target_layer->PreviousCullRect());
@@ -406,39 +490,38 @@ TEST_P(PaintLayerPainterTest, CachedSubsequenceRetainsPreviousPaintResult) {
IsSameId(content1, kBackgroundType)));
// |target| still created subsequence (cached).
EXPECT_SUBSEQUENCE(*target_layer, 1, 2);
+ EXPECT_EQ(1u, RootPaintController().PaintChunks()[1].size());
}
// Scroll the view so that both |content1| and |content2| are in the interest
// rect.
- GetLayoutView().GetScrollableArea()->SetScrollOffset(ScrollOffset(0, 3000),
- kProgrammaticScroll);
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetLayoutView().GetScrollableArea()->SetScrollOffset(
+ ScrollOffset(0, 3000), mojom::blink::ScrollType::kProgrammatic);
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
// Scrolling doesn't set SelfNeedsRepaint flag. Change of paint dirty rect of
// a partially painted layer will trigger repaint.
EXPECT_FALSE(target_layer->SelfNeedsRepaint());
EXPECT_TRUE(PaintWithoutCommit());
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
- EXPECT_EQ(3, NumCachedNewItems());
- else
- EXPECT_EQ(2, NumCachedNewItems());
+ EXPECT_EQ(2, NumCachedNewItems());
CommitAndFinishCycle();
// |target| is still partially painted.
EXPECT_EQ(kMayBeClippedByCullRect, target_layer->PreviousPaintResult());
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
- // CAP doens't clip the cull rect by the scrolling contents rect, which
+ // CAP doesn't clip the cull rect by the scrolling contents rect, which
// doesn't affect painted results.
EXPECT_EQ(CullRect(IntRect(-4000, -1000, 8800, 8600)),
target_layer->PreviousCullRect());
// Painted result should include both |content1| and |content2|.
- EXPECT_THAT(
- RootPaintController().GetDisplayItemList(),
- ElementsAre(IsSameId(&GetLayoutView(), DisplayItem::kScrollHitTest),
- IsSameId(&view_client, kDocumentBackgroundType),
- IsSameId(content1, kBackgroundType),
- IsSameId(content2, kBackgroundType)));
+ EXPECT_THAT(RootPaintController().GetDisplayItemList(),
+ ElementsAre(IsSameId(&view_client, kDocumentBackgroundType),
+ IsSameId(content1, kBackgroundType),
+ IsSameId(content2, kBackgroundType)));
// |target| still created subsequence (repainted).
EXPECT_SUBSEQUENCE(*target_layer, 2, 4);
+ EXPECT_EQ(0u, RootPaintController().PaintChunks()[2].size());
+ EXPECT_EQ(2u, RootPaintController().PaintChunks()[3].size());
} else {
EXPECT_EQ(CullRect(IntRect(0, 0, 800, 7600)),
target_layer->PreviousCullRect());
@@ -448,10 +531,133 @@ TEST_P(PaintLayerPainterTest, CachedSubsequenceRetainsPreviousPaintResult) {
IsSameId(content1, kBackgroundType),
IsSameId(content2, kBackgroundType)));
// |target| still created subsequence (repainted).
- EXPECT_SUBSEQUENCE(*target_layer, 1, 3);
+ EXPECT_SUBSEQUENCE(*target_layer, 1, 2);
+ EXPECT_EQ(2u, RootPaintController().PaintChunks()[1].size());
}
}
+TEST_P(PaintLayerPainterTest, HintedPaintChunksWithBackgrounds) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ body { margin: 0 }
+ div { background: blue }
+ </style>
+ <div id='container1' style='position: relative; height: 150px; z-index: 1'>
+ <div id='content1a' style='position: relative; height: 100px'></div>
+ <div id='content1b' style='position: relative; height: 100px'></div>
+ </div>
+ <div id='container2' style='position: relative; z-index: 1'>
+ <div id='content2a' style='position: relative; height: 100px'></div>
+ <div id='content2b' style='position: relative; z-index: -1; height: 100px'></div>
+ </div>
+ )HTML");
+
+ auto* container1 = ToLayoutBox(GetLayoutObjectByElementId("container1"));
+ auto* content1a = ToLayoutBox(GetLayoutObjectByElementId("content1a"));
+ auto* content1b = ToLayoutBox(GetLayoutObjectByElementId("content1b"));
+ auto* container2 = ToLayoutBox(GetLayoutObjectByElementId("container2"));
+ auto* content2a = ToLayoutBox(GetLayoutObjectByElementId("content2a"));
+ auto* content2b = ToLayoutBox(GetLayoutObjectByElementId("content2b"));
+ auto chunk_state = GetLayoutView().FirstFragment().ContentsProperties();
+
+ EXPECT_THAT(RootPaintController().GetDisplayItemList(),
+ ElementsAre(IsSameId(&ViewScrollingBackgroundClient(),
+ kDocumentBackgroundType),
+ IsSameId(container1, kBackgroundType),
+ IsSameId(content1a, kBackgroundType),
+ IsSameId(content1b, kBackgroundType),
+ IsSameId(container2, kBackgroundType),
+ IsSameId(content2b, kBackgroundType),
+ IsSameId(content2a, kBackgroundType)));
+
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(
+ IsPaintChunk(0, 1,
+ PaintChunk::Id(ViewScrollingBackgroundClient(),
+ kDocumentBackgroundType),
+ chunk_state),
+ // Includes |container1| and |content1a|.
+ IsPaintChunk(
+ 1, 3,
+ PaintChunk::Id(*container1->Layer(), DisplayItem::kLayerChunk),
+ chunk_state, nullptr, IntRect(0, 0, 800, 150)),
+ // Includes |content1b| which overflows |container1|.
+ IsPaintChunk(
+ 3, 4,
+ PaintChunk::Id(*content1b->Layer(), DisplayItem::kLayerChunk),
+ chunk_state, nullptr, IntRect(0, 100, 800, 100)),
+ IsPaintChunk(
+ 4, 5,
+ PaintChunk::Id(*container2->Layer(), DisplayItem::kLayerChunk),
+ chunk_state, nullptr, IntRect(0, 150, 800, 200)),
+ IsPaintChunk(
+ 5, 6,
+ PaintChunk::Id(*content2b->Layer(), DisplayItem::kLayerChunk),
+ chunk_state, nullptr, IntRect(0, 250, 800, 100)),
+ IsPaintChunk(
+ 6, 7,
+ PaintChunk::Id(*content2a->Layer(), DisplayItem::kLayerChunk),
+ chunk_state, nullptr, IntRect(0, 150, 800, 100))));
+}
+
+TEST_P(PaintLayerPainterTest, HintedPaintChunksWithoutBackgrounds) {
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ return;
+
+ SetBodyInnerHTML(R"HTML(
+ <style>body { margin: 0 }</style>
+ <div id='container1' style='position: relative; height: 150px; z-index: 1'>
+ <div id='content1a' style='position: relative; height: 100px'></div>
+ <div id='content1b' style='position: relative; height: 100px'></div>
+ </div>
+ <div id='container2' style='position: relative; z-index: 1'>
+ <div id='content2a' style='position: relative; height: 100px'></div>
+ <div id='content2b'
+ style='position: relative; z-index: -1; height: 100px'></div>
+ </div>
+ )HTML");
+
+ auto* container1 = ToLayoutBox(GetLayoutObjectByElementId("container1"));
+ auto* content1b = ToLayoutBox(GetLayoutObjectByElementId("content1b"));
+ auto* container2 = ToLayoutBox(GetLayoutObjectByElementId("container2"));
+ auto* content2a = ToLayoutBox(GetLayoutObjectByElementId("content2a"));
+ auto* content2b = ToLayoutBox(GetLayoutObjectByElementId("content2b"));
+ auto chunk_state = GetLayoutView().FirstFragment().ContentsProperties();
+
+ EXPECT_THAT(RootPaintController().GetDisplayItemList(),
+ ElementsAre(IsSameId(&ViewScrollingBackgroundClient(),
+ kDocumentBackgroundType)));
+
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(
+ IsPaintChunk(0, 1,
+ PaintChunk::Id(ViewScrollingBackgroundClient(),
+ kDocumentBackgroundType),
+ chunk_state),
+ IsPaintChunk(
+ 1, 1,
+ PaintChunk::Id(*container1->Layer(), DisplayItem::kLayerChunk),
+ chunk_state, nullptr, IntRect(0, 0, 800, 150)),
+ IsPaintChunk(
+ 1, 1,
+ PaintChunk::Id(*content1b->Layer(), DisplayItem::kLayerChunk),
+ chunk_state, nullptr, IntRect(0, 100, 800, 100)),
+ IsPaintChunk(
+ 1, 1,
+ PaintChunk::Id(*container2->Layer(), DisplayItem::kLayerChunk),
+ chunk_state, nullptr, IntRect(0, 150, 800, 200)),
+ IsPaintChunk(
+ 1, 1,
+ PaintChunk::Id(*content2b->Layer(), DisplayItem::kLayerChunk),
+ chunk_state, nullptr, IntRect(0, 250, 800, 100)),
+ IsPaintChunk(
+ 1, 1,
+ PaintChunk::Id(*content2a->Layer(), DisplayItem::kLayerChunk),
+ chunk_state, nullptr, IntRect(0, 150, 800, 100))));
+}
+
TEST_P(PaintLayerPainterTest, PaintPhaseOutline) {
AtomicString style_without_outline =
"width: 50px; height: 50px; background-color: green";
@@ -503,7 +709,8 @@ TEST_P(PaintLayerPainterTest, PaintPhaseOutline) {
// same layer has outline.
To<HTMLElement>(outline_div.GetNode())
->setAttribute(html_names::kStyleAttr, style_with_outline);
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(self_painting_layer.NeedsPaintPhaseDescendantOutlines());
EXPECT_FALSE(non_self_painting_layer.NeedsPaintPhaseDescendantOutlines());
Paint();
@@ -558,7 +765,8 @@ TEST_P(PaintLayerPainterTest, PaintPhaseFloat) {
// has float.
To<HTMLElement>(float_div.GetNode())
->setAttribute(html_names::kStyleAttr, style_with_float);
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(self_painting_layer.NeedsPaintPhaseFloat());
EXPECT_FALSE(non_self_painting_layer.NeedsPaintPhaseFloat());
Paint();
@@ -622,75 +830,6 @@ TEST_P(PaintLayerPainterTest, PaintPhaseFloatUnderInlineLayer) {
DisplayItem::kBoxDecorationBackground));
}
-TEST_P(PaintLayerPainterTest, PaintPhaseBlockBackground) {
- AtomicString style_without_background = "width: 50px; height: 50px";
- AtomicString style_with_background =
- "background: blue; " + style_without_background;
- SetBodyInnerHTML(R"HTML(
- <div id='self-painting-layer' style='position: absolute'>
- <div id='non-self-painting-layer' style='overflow: hidden'>
- <div>
- <div id='background'></div>
- </div>
- </div>
- </div>
- )HTML");
- LayoutObject& background_div =
- *GetDocument().getElementById("background")->GetLayoutObject();
- To<HTMLElement>(background_div.GetNode())
- ->setAttribute(html_names::kStyleAttr, style_without_background);
- UpdateAllLifecyclePhasesForTest();
-
- LayoutBoxModelObject& self_painting_layer_object = *ToLayoutBoxModelObject(
- GetDocument().getElementById("self-painting-layer")->GetLayoutObject());
- PaintLayer& self_painting_layer = *self_painting_layer_object.Layer();
- ASSERT_TRUE(self_painting_layer.IsSelfPaintingLayer());
- PaintLayer& non_self_painting_layer =
- *ToLayoutBoxModelObject(GetDocument()
- .getElementById("non-self-painting-layer")
- ->GetLayoutObject())
- ->Layer();
- ASSERT_FALSE(non_self_painting_layer.IsSelfPaintingLayer());
- ASSERT_TRUE(&non_self_painting_layer == background_div.EnclosingLayer());
-
- EXPECT_FALSE(self_painting_layer.NeedsPaintPhaseDescendantBlockBackgrounds());
- EXPECT_FALSE(
- non_self_painting_layer.NeedsPaintPhaseDescendantBlockBackgrounds());
-
- // Background on the self-painting-layer node itself doesn't affect
- // PaintPhaseDescendantBlockBackgrounds.
- To<HTMLElement>(self_painting_layer_object.GetNode())
- ->setAttribute(html_names::kStyleAttr,
- "position: absolute; background: green");
- UpdateAllLifecyclePhasesForTest();
- EXPECT_FALSE(self_painting_layer.NeedsPaintPhaseDescendantBlockBackgrounds());
- EXPECT_FALSE(
- non_self_painting_layer.NeedsPaintPhaseDescendantBlockBackgrounds());
- EXPECT_TRUE(DisplayItemListContains(
- RootPaintController().GetDisplayItemList(), self_painting_layer_object,
- DisplayItem::kBoxDecorationBackground));
-
- // needsPaintPhaseDescendantBlockBackgrounds should be set when any descendant
- // on the same layer has Background.
- To<HTMLElement>(background_div.GetNode())
- ->setAttribute(html_names::kStyleAttr, style_with_background);
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
- EXPECT_TRUE(self_painting_layer.NeedsPaintPhaseDescendantBlockBackgrounds());
- EXPECT_FALSE(
- non_self_painting_layer.NeedsPaintPhaseDescendantBlockBackgrounds());
- Paint();
- EXPECT_TRUE(DisplayItemListContains(
- RootPaintController().GetDisplayItemList(), background_div,
- DisplayItem::kBoxDecorationBackground));
-
- // needsPaintPhaseDescendantBlockBackgrounds should be reset when no outline
- // is actually painted.
- To<HTMLElement>(background_div.GetNode())
- ->setAttribute(html_names::kStyleAttr, style_without_background);
- UpdateAllLifecyclePhasesForTest();
- EXPECT_TRUE(self_painting_layer.NeedsPaintPhaseDescendantBlockBackgrounds());
-}
-
TEST_P(PaintLayerPainterTest, PaintPhasesUpdateOnLayerAddition) {
SetBodyInnerHTML(R"HTML(
<div id='will-be-layer'>
@@ -712,7 +851,6 @@ TEST_P(PaintLayerPainterTest, PaintPhasesUpdateOnLayerAddition) {
->Layer();
EXPECT_TRUE(html_layer.NeedsPaintPhaseDescendantOutlines());
EXPECT_TRUE(html_layer.NeedsPaintPhaseFloat());
- EXPECT_TRUE(html_layer.NeedsPaintPhaseDescendantBlockBackgrounds());
To<HTMLElement>(layer_div.GetNode())
->setAttribute(html_names::kStyleAttr, "position: relative");
@@ -722,7 +860,6 @@ TEST_P(PaintLayerPainterTest, PaintPhasesUpdateOnLayerAddition) {
ASSERT_TRUE(layer.IsSelfPaintingLayer());
EXPECT_TRUE(layer.NeedsPaintPhaseDescendantOutlines());
EXPECT_TRUE(layer.NeedsPaintPhaseFloat());
- EXPECT_TRUE(layer.NeedsPaintPhaseDescendantBlockBackgrounds());
}
TEST_P(PaintLayerPainterTest, PaintPhasesUpdateOnBecomingSelfPainting) {
@@ -747,7 +884,6 @@ TEST_P(PaintLayerPainterTest, PaintPhasesUpdateOnBecomingSelfPainting) {
GetDocument().documentElement()->GetLayoutObject())
->Layer();
EXPECT_TRUE(html_layer.NeedsPaintPhaseDescendantOutlines());
- EXPECT_TRUE(html_layer.NeedsPaintPhaseDescendantBlockBackgrounds());
To<HTMLElement>(layer_div.GetNode())
->setAttribute(
@@ -757,7 +893,6 @@ TEST_P(PaintLayerPainterTest, PaintPhasesUpdateOnBecomingSelfPainting) {
PaintLayer& layer = *layer_div.Layer();
ASSERT_TRUE(layer.IsSelfPaintingLayer());
EXPECT_TRUE(layer.NeedsPaintPhaseDescendantOutlines());
- EXPECT_TRUE(layer.NeedsPaintPhaseDescendantBlockBackgrounds());
}
TEST_P(PaintLayerPainterTest, PaintPhasesUpdateOnBecomingNonSelfPainting) {
@@ -780,14 +915,12 @@ TEST_P(PaintLayerPainterTest, PaintPhasesUpdateOnBecomingNonSelfPainting) {
PaintLayer& layer = *layer_div.Layer();
EXPECT_TRUE(layer.IsSelfPaintingLayer());
EXPECT_TRUE(layer.NeedsPaintPhaseDescendantOutlines());
- EXPECT_TRUE(layer.NeedsPaintPhaseDescendantBlockBackgrounds());
PaintLayer& html_layer =
*ToLayoutBoxModelObject(
GetDocument().documentElement()->GetLayoutObject())
->Layer();
EXPECT_FALSE(html_layer.NeedsPaintPhaseDescendantOutlines());
- EXPECT_FALSE(html_layer.NeedsPaintPhaseDescendantBlockBackgrounds());
To<HTMLElement>(layer_div.GetNode())
->setAttribute(html_names::kStyleAttr,
@@ -795,52 +928,6 @@ TEST_P(PaintLayerPainterTest, PaintPhasesUpdateOnBecomingNonSelfPainting) {
UpdateAllLifecyclePhasesForTest();
EXPECT_FALSE(layer.IsSelfPaintingLayer());
EXPECT_TRUE(html_layer.NeedsPaintPhaseDescendantOutlines());
- EXPECT_TRUE(html_layer.NeedsPaintPhaseDescendantBlockBackgrounds());
-}
-
-TEST_P(PaintLayerPainterTest,
- TableCollapsedBorderNeedsPaintPhaseDescendantBlockBackgrounds) {
- // "position: relative" makes the table and td self-painting layers.
- // The table's layer should be marked needsPaintPhaseDescendantBlockBackground
- // because it will paint collapsed borders in the phase.
- SetBodyInnerHTML(R"HTML(
- <table id='table' style='position: relative; border-collapse: collapse'>
- <tr><td style='position: relative; border: 1px solid green'>
- Cell
- </td></tr>
- </table>
- )HTML");
-
- LayoutBoxModelObject& table =
- *ToLayoutBoxModelObject(GetLayoutObjectByElementId("table"));
- ASSERT_TRUE(table.HasLayer());
- PaintLayer& layer = *table.Layer();
- EXPECT_TRUE(layer.IsSelfPaintingLayer());
- EXPECT_TRUE(layer.NeedsPaintPhaseDescendantBlockBackgrounds());
-}
-
-TEST_P(PaintLayerPainterTest,
- TableCollapsedBorderNeedsPaintPhaseDescendantBlockBackgroundsDynamic) {
- SetBodyInnerHTML(R"HTML(
- <table id='table' style='position: relative'>
- <tr><td style='position: relative; border: 1px solid green'>
- Cell
- </td></tr>
- </table>
- )HTML");
-
- LayoutBoxModelObject& table =
- *ToLayoutBoxModelObject(GetLayoutObjectByElementId("table"));
- ASSERT_TRUE(table.HasLayer());
- PaintLayer& layer = *table.Layer();
- EXPECT_TRUE(layer.IsSelfPaintingLayer());
- EXPECT_FALSE(layer.NeedsPaintPhaseDescendantBlockBackgrounds());
-
- To<HTMLElement>(table.GetNode())
- ->setAttribute(html_names::kStyleAttr,
- "position: relative; border-collapse: collapse");
- UpdateAllLifecyclePhasesForTest();
- EXPECT_TRUE(layer.NeedsPaintPhaseDescendantBlockBackgrounds());
}
TEST_P(PaintLayerPainterTest, DontPaintWithTinyOpacity) {
@@ -1035,21 +1122,21 @@ TEST_P(PaintLayerPainterTestCAP, TallScrolledLayerCullRect) {
EXPECT_EQ(IntRect(-4000, -4000, 8800, 8600),
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 6000),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 6000), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(IntRect(-4000, 2000, 8800, 8600),
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 6500),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 6500), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
// Used the previous cull rect because the scroll amount is small.
EXPECT_EQ(IntRect(-4000, 2000, 8800, 8600),
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
- GetDocument().View()->LayoutViewport()->SetScrollOffset(ScrollOffset(0, 6600),
- kProgrammaticScroll);
+ GetDocument().View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(0, 6600), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
// Used new cull rect.
EXPECT_EQ(IntRect(-4000, 2600, 8800, 8600),
@@ -1093,14 +1180,11 @@ TEST_P(PaintLayerPainterTestCAP, WholeDocumentCullRect) {
EXPECT_THAT(
RootPaintController().GetDisplayItemList(),
UnorderedElementsAre(
- IsSameId(&GetLayoutView(), DisplayItem::kScrollHitTest),
IsSameId(&ViewScrollingBackgroundClient(), kDocumentBackgroundType),
IsSameId(GetDisplayItemClientFromElementId("relative"),
kBackgroundType),
IsSameId(GetDisplayItemClientFromElementId("normal"),
kBackgroundType),
- IsSameId(GetLayoutObjectByElementId("scroll"),
- DisplayItem::kScrollHitTest),
IsSameId(GetDisplayItemClientFromElementId("scroll"),
kBackgroundType),
IsSameId(&ToLayoutBox(GetLayoutObjectByElementId("scroll"))
@@ -1124,7 +1208,7 @@ TEST_P(PaintLayerPainterTestCAP, VerticalRightLeftWritingModeDocument) {
)HTML");
GetDocument().View()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(-5000, 0), kProgrammaticScroll);
+ ScrollOffset(-5000, 0), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
// A scroll by -5000px is equivalent to a scroll by (10000 - 5000 - 800)px =
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 c2ff5b6ecf3..01c3537f381 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
@@ -49,9 +49,11 @@
#include "cc/input/main_thread_scrolling_reason.h"
#include "cc/input/snap_selection_strategy.h"
#include "cc/layers/picture_layer.h"
+#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink.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/task_type.h"
-#include "third_party/blink/public/platform/web_scroll_into_view_params.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/content_capture/content_capture_manager.h"
@@ -98,6 +100,8 @@
#include "third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "ui/base/ui_base_features.h"
namespace blink {
@@ -123,6 +127,7 @@ PaintLayerScrollableArea::PaintLayerScrollableArea(PaintLayer& layer)
needs_composited_scrolling_(false),
rebuild_horizontal_scrollbar_layer_(false),
rebuild_vertical_scrollbar_layer_(false),
+ previous_vertical_scrollbar_on_left_(false),
needs_scroll_offset_clamp_(false),
needs_relayout_(false),
had_horizontal_scrollbar_before_relayout_(false),
@@ -224,11 +229,32 @@ void PaintLayerScrollableArea::DisposeImpl() {
sequencer->DidDisposeScrollableArea(*this);
RunScrollCompleteCallbacks();
+ InvalidateScrollTimeline();
layer_ = nullptr;
}
-void PaintLayerScrollableArea::Trace(blink::Visitor* visitor) {
+void PaintLayerScrollableArea::ApplyPendingHistoryRestoreScrollOffset() {
+ if (!pending_view_state_)
+ return;
+
+ // TODO(pnoland): attempt to restore the anchor in more places than this.
+ // Anchor-based restore should allow for earlier restoration.
+ bool did_restore = RestoreScrollAnchor(
+ {pending_view_state_->scroll_anchor_data_.selector_,
+ LayoutPoint(pending_view_state_->scroll_anchor_data_.offset_.x(),
+ pending_view_state_->scroll_anchor_data_.offset_.y()),
+ pending_view_state_->scroll_anchor_data_.simhash_});
+ if (!did_restore) {
+ SetScrollOffset(pending_view_state_->scroll_offset_,
+ mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kAuto);
+ }
+
+ pending_view_state_.reset();
+}
+
+void PaintLayerScrollableArea::Trace(Visitor* visitor) {
visitor->Trace(scrollbar_manager_);
visitor->Trace(scroll_anchor_);
visitor->Trace(scrolling_background_display_item_client_);
@@ -335,8 +361,7 @@ static int CornerStart(const LayoutBox& box,
return max_x - thickness - box.StyleRef().BorderRightWidth();
}
-IntRect PaintLayerScrollableArea::PaintLayerScrollableArea::CornerRect(
- const IntRect& bounds) const {
+IntRect PaintLayerScrollableArea::CornerRect() const {
int horizontal_thickness;
int vertical_thickness;
if (!VerticalScrollbar() && !HorizontalScrollbar()) {
@@ -362,9 +387,10 @@ IntRect PaintLayerScrollableArea::PaintLayerScrollableArea::CornerRect(
horizontal_thickness = VerticalScrollbar()->ScrollbarThickness();
vertical_thickness = HorizontalScrollbar()->ScrollbarThickness();
}
- return IntRect(CornerStart(*GetLayoutBox(), bounds.X(), bounds.MaxX(),
+ IntSize border_box_size = PixelSnappedBorderBoxSize();
+ return IntRect(CornerStart(*GetLayoutBox(), 0, border_box_size.Width(),
horizontal_thickness),
- bounds.MaxY() - vertical_thickness -
+ border_box_size.Height() - vertical_thickness -
GetLayoutBox()->StyleRef().BorderBottomWidth(),
horizontal_thickness, vertical_thickness);
}
@@ -380,8 +406,7 @@ IntRect PaintLayerScrollableArea::ScrollCornerRect() const {
bool has_resizer = GetLayoutBox()->StyleRef().HasResize();
if ((has_horizontal_bar && has_vertical_bar) ||
(has_resizer && (has_horizontal_bar || has_vertical_bar))) {
- return CornerRect(GetLayoutBox()->PixelSnappedBorderBoxRect(
- Layer()->SubpixelAccumulation()));
+ return CornerRect();
}
return IntRect();
}
@@ -466,7 +491,7 @@ int PaintLayerScrollableArea::ScrollSize(
void PaintLayerScrollableArea::UpdateScrollOffset(
const ScrollOffset& new_offset,
- ScrollType scroll_type) {
+ mojom::blink::ScrollType scroll_type) {
if (HasBeenDisposed() || GetScrollOffset() == new_offset)
return;
@@ -494,7 +519,7 @@ void PaintLayerScrollableArea::UpdateScrollOffset(
// should be impacted by a scroll).
if (!frame_view->IsInPerformLayout()) {
if (!Layer()->IsRootLayer()) {
- Layer()->SetNeedsCompositingInputsUpdate();
+ Layer()->SetNeedsCompositingInputsUpdate(false);
Layer()->ClearClipRects();
}
@@ -509,12 +534,21 @@ void PaintLayerScrollableArea::UpdateScrollOffset(
else
frame_view->SetNeedsUpdateGeometries();
}
- UpdateCompositingLayersAfterScroll();
- GetLayoutBox()->MayUpdateHoverWhenContentUnderMouseChanged(
- frame->GetEventHandler());
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ if (auto* scrolling_coordinator = GetScrollingCoordinator())
+ scrolling_coordinator->UpdateCompositorScrollOffset(*frame, *this);
+ } else {
+ UpdateCompositingLayersAfterScroll();
+ }
- if (scroll_type == kUserScroll || scroll_type == kCompositorScroll) {
+ // The ScrollOffsetTranslation paint property depends on the scroll offset.
+ // (see: PaintPropertyTreeBuilder::UpdateScrollAndScrollTranslation).
+ GetLayoutBox()->SetNeedsPaintPropertyUpdatePreservingCachedRects();
+ InvalidateScrollTimeline();
+
+ if (scroll_type == mojom::blink::ScrollType::kUser ||
+ scroll_type == mojom::blink::ScrollType::kCompositor) {
Page* page = frame->GetPage();
if (page)
page->GetChromeClient().ClearToolTip(*frame);
@@ -522,10 +556,6 @@ void PaintLayerScrollableArea::UpdateScrollOffset(
InvalidatePaintForScrollOffsetChange();
- // The scrollOffsetTranslation paint property depends on the scroll offset.
- // (see: PaintPropertyTreeBuilder::UpdateScrollAndScrollTranslation).
- GetLayoutBox()->SetNeedsPaintPropertyUpdate();
-
// Don't enqueue a scroll event yet for scroll reasons that are not about
// explicit changes to scroll. Instead, only do so at the time of the next
// lifecycle update, to avoid scroll events that are out of date or don't
@@ -535,7 +565,8 @@ void PaintLayerScrollableArea::UpdateScrollOffset(
// events is at the next lifecycle update (*).
//
// (*) https://html.spec.whatwg.org/#update-the-rendering steps
- if (scroll_type == kClampingScroll || scroll_type == kAnchoringScroll) {
+ if (scroll_type == mojom::blink::ScrollType::kClamping ||
+ scroll_type == mojom::blink::ScrollType::kAnchoring) {
if (GetLayoutBox()->GetNode())
frame_view->SetNeedsEnqueueScrollEvent(this);
} else {
@@ -549,7 +580,8 @@ void PaintLayerScrollableArea::UpdateScrollOffset(
if (is_root_layer) {
frame_view->GetFrame().Loader().SaveScrollState();
frame_view->DidChangeScrollOffset();
- if (scroll_type == kCompositorScroll || scroll_type == kUserScroll) {
+ if (scroll_type == mojom::blink::ScrollType::kCompositor ||
+ scroll_type == mojom::blink::ScrollType::kUser) {
if (DocumentLoader* document_loader = frame->Loader().GetDocumentLoader())
document_loader->GetInitialScrollState().was_scrolled_by_user = true;
}
@@ -559,8 +591,8 @@ void PaintLayerScrollableArea::UpdateScrollOffset(
anchor->DidScroll(scroll_type);
if (IsExplicitScrollType(scroll_type)) {
- if (scroll_type != kCompositorScroll)
- ShowOverlayScrollbars();
+ if (scroll_type != mojom::blink::ScrollType::kCompositor)
+ ShowNonMacOverlayScrollbars();
GetScrollAnchor()->Clear();
}
if (ContentCaptureManager* manager =
@@ -579,7 +611,7 @@ void PaintLayerScrollableArea::InvalidatePaintForScrollOffsetChange() {
auto* frame_view = box->GetFrameView();
frame_view->InvalidateBackgroundAttachmentFixedDescendantsOnScroll(*box);
- if (box->IsLayoutView() && frame_view->HasViewportConstrainedObjects() &&
+ if (IsA<LayoutView>(box) && frame_view->HasViewportConstrainedObjects() &&
!frame_view->InvalidateViewportConstrainedObjects()) {
box->SetShouldDoFullPaintInvalidation();
box->SetSubtreeShouldCheckForPaintInvalidation();
@@ -590,28 +622,24 @@ void PaintLayerScrollableArea::InvalidatePaintForScrollOffsetChange() {
if (Layer()->EnclosingPaginationLayer())
box->SetSubtreeShouldCheckForPaintInvalidation();
- // If not composited, background always paints into the main graphics layer.
- bool background_paint_in_graphics_layer = true;
- bool background_paint_in_scrolling_contents = false;
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
- UsesCompositedScrolling()) {
+ if (!box->BackgroundNeedsFullPaintInvalidation()) {
auto background_paint_location = box->GetBackgroundPaintLocation();
- background_paint_in_graphics_layer =
+ bool background_paint_in_graphics_layer =
background_paint_location & kBackgroundPaintInGraphicsLayer;
- background_paint_in_scrolling_contents =
+ bool background_paint_in_scrolling_contents =
background_paint_location & kBackgroundPaintInScrollingContents;
- }
- // Both local attachment background painted in graphics layer and normal
- // attachment background painted in scrolling contents require paint
- // invalidation. Fixed attachment background has been dealt with in
- // frame_view->InvalidateBackgroundAttachmentFixedDescendantsOnScroll().
- auto background_layers = box->StyleRef().BackgroundLayers();
- if ((background_layers.AnyLayerHasLocalAttachmentImage() &&
- background_paint_in_graphics_layer) ||
- (background_layers.AnyLayerHasDefaultAttachmentImage() &&
- background_paint_in_scrolling_contents))
- box->SetBackgroundNeedsFullPaintInvalidation();
+ // Both local attachment background painted in graphics layer and normal
+ // attachment background painted in scrolling contents require paint
+ // invalidation. Fixed attachment background has been dealt with in
+ // frame_view->InvalidateBackgroundAttachmentFixedDescendantsOnScroll().
+ auto background_layers = box->StyleRef().BackgroundLayers();
+ if ((background_layers.AnyLayerHasLocalAttachmentImage() &&
+ background_paint_in_graphics_layer) ||
+ (background_layers.AnyLayerHasDefaultAttachmentImage() &&
+ background_paint_in_scrolling_contents))
+ box->SetBackgroundNeedsFullPaintInvalidation();
+ }
// If any scrolling content might have been clipped by a cull rect, then
// that cull rect could be affected by scroll offset. For composited
@@ -684,7 +712,8 @@ IntSize PaintLayerScrollableArea::MaximumScrollOffsetInt() const {
}
void PaintLayerScrollableArea::VisibleSizeChanged() {
- ShowOverlayScrollbars();
+ InvalidateScrollTimeline();
+ ShowNonMacOverlayScrollbars();
}
PhysicalRect PaintLayerScrollableArea::LayoutContentRect(
@@ -759,6 +788,7 @@ void PaintLayerScrollableArea::ContentsResized() {
// Need to update the bounds of the scroll property.
GetLayoutBox()->SetNeedsPaintPropertyUpdate();
Layer()->SetNeedsCompositingInputsUpdate();
+ InvalidateScrollTimeline();
}
IntPoint PaintLayerScrollableArea::LastKnownMousePosition() const {
@@ -849,18 +879,19 @@ bool PaintLayerScrollableArea::UserInputScrollable(
if (GetLayoutBox()->IsIntrinsicallyScrollable(orientation))
return true;
- if (GetLayoutBox()->IsLayoutView()) {
+ if (IsA<LayoutView>(GetLayoutBox())) {
Document& document = GetLayoutBox()->GetDocument();
Element* fullscreen_element = Fullscreen::FullscreenElementFrom(document);
if (fullscreen_element && fullscreen_element != document.documentElement())
return false;
- ScrollbarMode h_mode;
- ScrollbarMode v_mode;
- ToLayoutView(GetLayoutBox())->CalculateScrollbarModes(h_mode, v_mode);
- ScrollbarMode mode =
+ mojom::blink::ScrollbarMode h_mode;
+ mojom::blink::ScrollbarMode v_mode;
+ To<LayoutView>(GetLayoutBox())->CalculateScrollbarModes(h_mode, v_mode);
+ mojom::blink::ScrollbarMode mode =
(orientation == kHorizontalScrollbar) ? h_mode : v_mode;
- return mode == ScrollbarMode::kAuto || mode == ScrollbarMode::kAlwaysOn;
+ return mode == mojom::blink::ScrollbarMode::kAuto ||
+ mode == mojom::blink::ScrollbarMode::kAlwaysOn;
}
EOverflow overflow_style = (orientation == kHorizontalScrollbar)
@@ -929,9 +960,10 @@ void PaintLayerScrollableArea::UpdateScrollDimensions() {
new_overflow_rect.Unite(PhysicalRect(
new_overflow_rect.offset, LayoutContentRect(kExcludeScrollbars).size));
- if (overflow_rect_.size != new_overflow_rect.size)
- ContentsResized();
+ bool resized = overflow_rect_.size != new_overflow_rect.size;
overflow_rect_ = new_overflow_rect;
+ if (resized)
+ ContentsResized();
UpdateScrollOrigin();
}
@@ -956,7 +988,7 @@ void PaintLayerScrollableArea::UpdateScrollbarProportions() {
void PaintLayerScrollableArea::SetScrollOffsetUnconditionally(
const ScrollOffset& offset,
- ScrollType scroll_type) {
+ mojom::blink::ScrollType scroll_type) {
CancelScrollAnimation();
ScrollOffsetChanged(offset, scroll_type);
}
@@ -1039,7 +1071,7 @@ void PaintLayerScrollableArea::UpdateAfterLayout() {
GetLayoutBox()->IsHorizontalWritingMode()) ||
(horizontal_scrollbar_should_change &&
!GetLayoutBox()->IsHorizontalWritingMode())) {
- GetLayoutBox()->SetPreferredLogicalWidthsDirty();
+ GetLayoutBox()->SetIntrinsicLogicalWidthsDirty();
}
if (IsManagedByLayoutNG(*GetLayoutBox())) {
// If the box is managed by LayoutNG, don't go here. We don't want to
@@ -1080,7 +1112,9 @@ void PaintLayerScrollableArea::UpdateAfterLayout() {
} else if (!HasScrollbar() && resizer_will_change) {
Layer()->DirtyStackingContextZOrderLists();
}
-
+ // The snap container data will be updated at the end of the layout update. If
+ // 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.
@@ -1091,13 +1125,6 @@ void PaintLayerScrollableArea::UpdateAfterLayout() {
UpdateScrollbarProportions();
}
- if (!scrollbars_are_frozen && HasOverlayScrollbars()) {
- if (!ScrollSize(kHorizontalScrollbar))
- SetHasHorizontalScrollbar(false);
- if (!ScrollSize(kVerticalScrollbar))
- SetHasVerticalScrollbar(false);
- }
-
ClampScrollOffsetAfterOverflowChange();
if (!scrollbars_are_frozen) {
@@ -1123,10 +1150,12 @@ void PaintLayerScrollableArea::ClampScrollOffsetAfterOverflowChange() {
}
UpdateScrollDimensions();
- if (ScrollOriginChanged())
+ if (ScrollOriginChanged()) {
SetScrollOffsetUnconditionally(ClampScrollOffset(GetScrollOffset()));
- else
- ScrollableArea::SetScrollOffset(GetScrollOffset(), kClampingScroll);
+ } else {
+ ScrollableArea::SetScrollOffset(GetScrollOffset(),
+ mojom::blink::ScrollType::kClamping);
+ }
SetNeedsScrollOffsetClamp(false);
ResetScrollOriginChanged();
@@ -1158,8 +1187,7 @@ void PaintLayerScrollableArea::DidChangeGlobalRootScroller() {
// Recalculate the snap container data since the scrolling behaviour for this
// layout box changed (i.e. it either became the layout viewport or it
// is no longer the layout viewport).
- GetLayoutBox()->GetDocument().GetSnapCoordinator().UpdateSnapContainerData(
- *GetLayoutBox());
+ SetSnapContainerDataNeedsUpdate(true);
}
bool PaintLayerScrollableArea::ShouldPerformScrollAnchoring() const {
@@ -1191,7 +1219,8 @@ PaintLayerScrollableArea::GetTimerTaskRunner() const {
return GetLayoutBox()->GetFrame()->GetTaskRunner(TaskType::kInternalDefault);
}
-ScrollBehavior PaintLayerScrollableArea::ScrollBehaviorStyle() const {
+mojom::blink::ScrollBehavior PaintLayerScrollableArea::ScrollBehaviorStyle()
+ const {
return GetLayoutBox()->StyleRef().GetScrollBehavior();
}
@@ -1264,9 +1293,8 @@ void PaintLayerScrollableArea::UpdateAfterStyleChange(
bool needs_horizontal_scrollbar;
bool needs_vertical_scrollbar;
- // We add auto scrollbars only during layout to prevent spurious activations.
ComputeScrollbarExistence(needs_horizontal_scrollbar,
- needs_vertical_scrollbar, kForbidAddingAutoBars);
+ needs_vertical_scrollbar, kOverflowIndependent);
UpdateResizerStyle(old_style);
@@ -1288,20 +1316,6 @@ void PaintLayerScrollableArea::UpdateAfterStyleChange(
LayoutBlock::ScrollbarChangeContext::kStyleChange);
}
- // With overflow: scroll, scrollbars are always visible but may be disabled.
- // When switching to another value, we need to re-enable them (see bug 11985).
- if (HasHorizontalScrollbar() && old_style &&
- old_style->OverflowX() == EOverflow::kScroll &&
- GetLayoutBox()->StyleRef().OverflowX() != EOverflow::kScroll) {
- HorizontalScrollbar()->SetEnabled(true);
- }
-
- if (HasVerticalScrollbar() && old_style &&
- old_style->OverflowY() == EOverflow::kScroll &&
- GetLayoutBox()->StyleRef().OverflowY() != EOverflow::kScroll) {
- VerticalScrollbar()->SetEnabled(true);
- }
-
// FIXME: Need to detect a swap from custom to native scrollbars (and vice
// versa).
if (HorizontalScrollbar())
@@ -1310,6 +1324,14 @@ void PaintLayerScrollableArea::UpdateAfterStyleChange(
VerticalScrollbar()->StyleChanged();
UpdateScrollCornerStyle();
+
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ bool vertical_scrollbar_on_left = ShouldPlaceVerticalScrollbarOnLeft();
+ if (vertical_scrollbar_on_left != previous_vertical_scrollbar_on_left_) {
+ rebuild_vertical_scrollbar_layer_ = true;
+ previous_vertical_scrollbar_on_left_ = vertical_scrollbar_on_left;
+ }
+ }
}
void PaintLayerScrollableArea::UpdateAfterOverflowRecalc() {
@@ -1339,58 +1361,51 @@ void PaintLayerScrollableArea::UpdateAfterOverflowRecalc() {
UpdateScrollableAreaSet();
}
-IntRect PaintLayerScrollableArea::RectForHorizontalScrollbar(
- const IntRect& border_box_rect) const {
+IntRect PaintLayerScrollableArea::RectForHorizontalScrollbar() const {
if (!HasHorizontalScrollbar())
return IntRect();
const IntRect& scroll_corner = ScrollCornerRect();
-
+ IntSize border_box_size = PixelSnappedBorderBoxSize();
return IntRect(
- HorizontalScrollbarStart(border_box_rect.X()),
- border_box_rect.MaxY() - GetLayoutBox()->BorderBottom().ToInt() -
+ HorizontalScrollbarStart(),
+ border_box_size.Height() - GetLayoutBox()->BorderBottom().ToInt() -
HorizontalScrollbar()->ScrollbarThickness(),
- border_box_rect.Width() -
+ border_box_size.Width() -
(GetLayoutBox()->BorderLeft() + GetLayoutBox()->BorderRight())
.ToInt() -
scroll_corner.Width(),
HorizontalScrollbar()->ScrollbarThickness());
}
-IntRect PaintLayerScrollableArea::RectForVerticalScrollbar(
- const IntRect& border_box_rect) const {
+IntRect PaintLayerScrollableArea::RectForVerticalScrollbar() const {
if (!HasVerticalScrollbar())
return IntRect();
const IntRect& scroll_corner = ScrollCornerRect();
-
return IntRect(
- VerticalScrollbarStart(border_box_rect.X(), border_box_rect.MaxX()),
- border_box_rect.Y() + GetLayoutBox()->BorderTop().ToInt(),
+ VerticalScrollbarStart(), GetLayoutBox()->BorderTop().ToInt(),
VerticalScrollbar()->ScrollbarThickness(),
- border_box_rect.Height() -
+ PixelSnappedBorderBoxSize().Height() -
(GetLayoutBox()->BorderTop() + GetLayoutBox()->BorderBottom())
.ToInt() -
scroll_corner.Height());
}
-int PaintLayerScrollableArea::VerticalScrollbarStart(int min_x,
- int max_x) const {
+int PaintLayerScrollableArea::VerticalScrollbarStart() const {
if (GetLayoutBox()->ShouldPlaceBlockDirectionScrollbarOnLogicalLeft())
- return min_x + GetLayoutBox()->BorderLeft().ToInt();
- return max_x - GetLayoutBox()->BorderRight().ToInt() -
+ return GetLayoutBox()->BorderLeft().ToInt();
+ return PixelSnappedBorderBoxSize().Width() -
+ GetLayoutBox()->BorderRight().ToInt() -
VerticalScrollbar()->ScrollbarThickness();
}
-int PaintLayerScrollableArea::HorizontalScrollbarStart(int min_x) const {
- int x = min_x + GetLayoutBox()->BorderLeft().ToInt();
- if (GetLayoutBox()->ShouldPlaceBlockDirectionScrollbarOnLogicalLeft())
- x += HasVerticalScrollbar()
- ? VerticalScrollbar()->ScrollbarThickness()
- : ResizerCornerRect(GetLayoutBox()->PixelSnappedBorderBoxRect(
- Layer()->SubpixelAccumulation()),
- kResizerForPointer)
- .Width();
+int PaintLayerScrollableArea::HorizontalScrollbarStart() const {
+ int x = GetLayoutBox()->BorderLeft().ToInt();
+ if (GetLayoutBox()->ShouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
+ x += HasVerticalScrollbar() ? VerticalScrollbar()->ScrollbarThickness()
+ : ResizerCornerRect(kResizerForPointer).Width();
+ }
return x;
}
@@ -1399,13 +1414,12 @@ IntSize PaintLayerScrollableArea::ScrollbarOffset(
// TODO(szager): Factor out vertical offset calculation into other methods,
// for symmetry with *ScrollbarStart methods for horizontal offset.
if (&scrollbar == VerticalScrollbar()) {
- return IntSize(
- VerticalScrollbarStart(0, Layer()->PixelSnappedSize().Width()),
- GetLayoutBox()->BorderTop().ToInt());
+ return IntSize(VerticalScrollbarStart(),
+ GetLayoutBox()->BorderTop().ToInt());
}
if (&scrollbar == HorizontalScrollbar()) {
- return IntSize(HorizontalScrollbarStart(0),
+ return IntSize(HorizontalScrollbarStart(),
GetLayoutBox()->BorderTop().ToInt() +
VisibleContentRect(kIncludeScrollbars).Height() -
HorizontalScrollbar()->ScrollbarThickness());
@@ -1417,7 +1431,7 @@ IntSize PaintLayerScrollableArea::ScrollbarOffset(
static inline const LayoutObject& ScrollbarStyleSource(
const LayoutBox& layout_box) {
- if (layout_box.IsLayoutView()) {
+ if (IsA<LayoutView>(layout_box)) {
Document& doc = layout_box.GetDocument();
if (Settings* settings = doc.GetSettings()) {
if (!settings->GetAllowCustomScrollbarInMainFrame() &&
@@ -1532,45 +1546,89 @@ void PaintLayerScrollableArea::ComputeScrollbarExistence(
return;
}
- needs_horizontal_scrollbar = GetLayoutBox()->ScrollsOverflowX();
- needs_vertical_scrollbar = GetLayoutBox()->ScrollsOverflowY();
+ mojom::blink::ScrollbarMode h_mode = mojom::blink::ScrollbarMode::kAuto;
+ mojom::blink::ScrollbarMode v_mode = mojom::blink::ScrollbarMode::kAuto;
- // Don't add auto scrollbars if the box contents aren't visible.
- if (GetLayoutBox()->HasAutoHorizontalScrollbar()) {
- if (option == kForbidAddingAutoBars)
- needs_horizontal_scrollbar &= HasHorizontalScrollbar();
- needs_horizontal_scrollbar &=
- GetLayoutBox()->IsRooted() && HasHorizontalOverflow() &&
- VisibleContentRect(kIncludeScrollbars).Height();
- }
+ // First, determine what behavior the scrollbars say they should have.
+ {
+ if (auto* layout_view = DynamicTo<LayoutView>(GetLayoutBox())) {
+ // LayoutView is special as there's various quirks and settings that
+ // style doesn't account for.
+ layout_view->CalculateScrollbarModes(h_mode, v_mode);
+ } else {
+ auto overflow_x = GetLayoutBox()->StyleRef().OverflowX();
+ if (overflow_x == EOverflow::kScroll) {
+ h_mode = mojom::blink::ScrollbarMode::kAlwaysOn;
+ } else if (overflow_x == EOverflow::kHidden ||
+ overflow_x == EOverflow::kVisible) {
+ h_mode = mojom::blink::ScrollbarMode::kAlwaysOff;
+ }
+
+ auto overflow_y = GetLayoutBox()->StyleRef().OverflowY();
+ if (overflow_y == EOverflow::kScroll) {
+ v_mode = mojom::blink::ScrollbarMode::kAlwaysOn;
+ } else if (overflow_y == EOverflow::kHidden ||
+ overflow_y == EOverflow::kVisible) {
+ v_mode = mojom::blink::ScrollbarMode::kAlwaysOff;
+ }
+ }
- if (GetLayoutBox()->HasAutoVerticalScrollbar()) {
- if (option == kForbidAddingAutoBars)
- needs_vertical_scrollbar &= HasVerticalScrollbar();
- needs_vertical_scrollbar &= GetLayoutBox()->IsRooted() &&
- HasVerticalOverflow() &&
- VisibleContentRect(kIncludeScrollbars).Width();
+ // Since overlay scrollbars (the fade-in/out kind, not overflow: overlay)
+ // only appear when scrolling, we don't create them if there isn't overflow
+ // to scroll. Thus, overlay scrollbars can't be "always on". i.e.
+ // |overlay:scroll| behaves like |overlay:auto|.
+ bool has_custom_scrollbar_style =
+ ScrollbarStyleSource(*GetLayoutBox())
+ .StyleRef()
+ .HasPseudoElementStyle(kPseudoIdScrollbar);
+ bool will_be_overlay = GetPageScrollbarTheme().UsesOverlayScrollbars() &&
+ !has_custom_scrollbar_style;
+ if (will_be_overlay) {
+ if (h_mode == mojom::blink::ScrollbarMode::kAlwaysOn)
+ h_mode = mojom::blink::ScrollbarMode::kAuto;
+ if (v_mode == mojom::blink::ScrollbarMode::kAlwaysOn)
+ v_mode = mojom::blink::ScrollbarMode::kAuto;
+ }
}
- if (GetLayoutBox()->IsLayoutView()) {
- ScrollbarMode h_mode;
- ScrollbarMode v_mode;
- ToLayoutView(GetLayoutBox())->CalculateScrollbarModes(h_mode, v_mode);
+ // By default, don't make any changes.
+ needs_horizontal_scrollbar = HasHorizontalScrollbar();
+ needs_vertical_scrollbar = HasVerticalScrollbar();
- // Look for the scrollbarModes and reset the needs Horizontal & vertical
- // Scrollbar values based on scrollbarModes, as during force style change
- // StyleResolver::styleForDocument returns documentStyle with no overflow
- // values, due to which we are destroying the scrollbars that were already
- // present.
- if (h_mode == ScrollbarMode::kAlwaysOn)
+ // If the behavior doesn't depend on overflow or any other information, we
+ // can set it now.
+ {
+ if (h_mode == mojom::blink::ScrollbarMode::kAlwaysOn)
needs_horizontal_scrollbar = true;
- else if (h_mode == ScrollbarMode::kAlwaysOff)
+ else if (h_mode == mojom::blink::ScrollbarMode::kAlwaysOff)
needs_horizontal_scrollbar = false;
- if (v_mode == ScrollbarMode::kAlwaysOn)
+
+ if (v_mode == mojom::blink::ScrollbarMode::kAlwaysOn)
needs_vertical_scrollbar = true;
- else if (v_mode == ScrollbarMode::kAlwaysOff)
+ else if (v_mode == mojom::blink::ScrollbarMode::kAlwaysOff)
needs_vertical_scrollbar = false;
}
+
+ // If this is being performed before layout, we want to only update scrollbar
+ // existence if its based on purely style based reasons.
+ if (option == kOverflowIndependent)
+ return;
+
+ // If we have clean layout, we can make a decision on any scrollbars that
+ // depend on overflow.
+ {
+ if (h_mode == mojom::blink::ScrollbarMode::kAuto) {
+ // Don't add auto scrollbars if the box contents aren't visible.
+ needs_horizontal_scrollbar =
+ GetLayoutBox()->IsRooted() && HasHorizontalOverflow() &&
+ VisibleContentRect(kIncludeScrollbars).Height();
+ }
+ if (v_mode == mojom::blink::ScrollbarMode::kAuto) {
+ needs_vertical_scrollbar = GetLayoutBox()->IsRooted() &&
+ HasVerticalOverflow() &&
+ VisibleContentRect(kIncludeScrollbars).Width();
+ }
+ }
}
bool PaintLayerScrollableArea::TryRemovingAutoScrollbars(
@@ -1584,11 +1642,12 @@ bool PaintLayerScrollableArea::TryRemovingAutoScrollbars(
if (!needs_horizontal_scrollbar && !needs_vertical_scrollbar)
return false;
- if (GetLayoutBox()->IsLayoutView()) {
- ScrollbarMode h_mode;
- ScrollbarMode v_mode;
- ToLayoutView(GetLayoutBox())->CalculateScrollbarModes(h_mode, v_mode);
- if (h_mode != ScrollbarMode::kAuto || v_mode != ScrollbarMode::kAuto)
+ if (auto* layout_view = DynamicTo<LayoutView>(GetLayoutBox())) {
+ mojom::blink::ScrollbarMode h_mode;
+ mojom::blink::ScrollbarMode v_mode;
+ layout_view->CalculateScrollbarModes(h_mode, v_mode);
+ if (h_mode != mojom::blink::ScrollbarMode::kAuto ||
+ v_mode != mojom::blink::ScrollbarMode::kAuto)
return false;
IntSize visible_size_with_scrollbars =
@@ -1738,6 +1797,29 @@ bool PaintLayerScrollableArea::SetTargetSnapAreaElementIds(
return false;
}
+bool PaintLayerScrollableArea::SnapContainerDataNeedsUpdate() const {
+ return RareData() ? RareData()->snap_container_data_needs_update_ : false;
+}
+
+void PaintLayerScrollableArea::SetSnapContainerDataNeedsUpdate(
+ bool needs_update) {
+ EnsureRareData().snap_container_data_needs_update_ = needs_update;
+ if (!needs_update)
+ return;
+ GetLayoutBox()
+ ->GetDocument()
+ .GetSnapCoordinator()
+ .SetAnySnapContainerDataNeedsUpdate(true);
+}
+
+bool PaintLayerScrollableArea::NeedsResnap() const {
+ return RareData() ? RareData()->needs_resnap_ : false;
+}
+
+void PaintLayerScrollableArea::SetNeedsResnap(bool needs_resnap) {
+ EnsureRareData().needs_resnap_ = needs_resnap;
+}
+
base::Optional<FloatPoint>
PaintLayerScrollableArea::GetSnapPositionAndSetTarget(
const cc::SnapSelectionStrategy& strategy) {
@@ -1779,21 +1861,17 @@ void PaintLayerScrollableArea::PositionOverflowControls() {
if (!HasOverflowControls())
return;
- const IntRect border_box =
- GetLayoutBox()->PixelSnappedBorderBoxRect(layer_->SubpixelAccumulation());
-
if (Scrollbar* vertical_scrollbar = VerticalScrollbar())
- vertical_scrollbar->SetFrameRect(RectForVerticalScrollbar(border_box));
+ vertical_scrollbar->SetFrameRect(RectForVerticalScrollbar());
if (Scrollbar* horizontal_scrollbar = HorizontalScrollbar())
- horizontal_scrollbar->SetFrameRect(RectForHorizontalScrollbar(border_box));
+ horizontal_scrollbar->SetFrameRect(RectForHorizontalScrollbar());
if (scroll_corner_)
scroll_corner_->SetFrameRect(LayoutRect(ScrollCornerRect()));
if (resizer_)
- resizer_->SetFrameRect(
- LayoutRect(ResizerCornerRect(border_box, kResizerForPointer)));
+ resizer_->SetFrameRect(LayoutRect(ResizerCornerRect(kResizerForPointer)));
// FIXME, this should eventually be removed, once we are certain that
// composited controls get correctly positioned on a compositor update. For
@@ -1837,10 +1915,7 @@ bool PaintLayerScrollableArea::HitTestOverflowControls(
IntRect resize_control_rect;
if (GetLayoutBox()->StyleRef().HasResize()) {
- resize_control_rect =
- ResizerCornerRect(GetLayoutBox()->PixelSnappedBorderBoxRect(
- Layer()->SubpixelAccumulation()),
- kResizerForPointer);
+ resize_control_rect = ResizerCornerRect(kResizerForPointer);
if (resize_control_rect.Contains(local_point))
return true;
}
@@ -1850,14 +1925,13 @@ bool PaintLayerScrollableArea::HitTestOverflowControls(
if (HasVerticalScrollbar() &&
VerticalScrollbar()->ShouldParticipateInHitTesting()) {
- LayoutRect v_bar_rect(
- VerticalScrollbarStart(0, Layer()->PixelSnappedSize().Width()),
- GetLayoutBox()->BorderTop().ToInt(),
- VerticalScrollbar()->ScrollbarThickness(),
- visible_rect.Height() -
- (HasHorizontalScrollbar()
- ? HorizontalScrollbar()->ScrollbarThickness()
- : resize_control_size));
+ LayoutRect v_bar_rect(VerticalScrollbarStart(),
+ GetLayoutBox()->BorderTop().ToInt(),
+ VerticalScrollbar()->ScrollbarThickness(),
+ visible_rect.Height() -
+ (HasHorizontalScrollbar()
+ ? HorizontalScrollbar()->ScrollbarThickness()
+ : resize_control_size));
if (v_bar_rect.Contains(local_point)) {
result.SetScrollbar(VerticalScrollbar());
return true;
@@ -1870,7 +1944,7 @@ bool PaintLayerScrollableArea::HitTestOverflowControls(
// TODO(crbug.com/638981): Are the conversions to int intentional?
int h_scrollbar_thickness = HorizontalScrollbar()->ScrollbarThickness();
LayoutRect h_bar_rect(
- HorizontalScrollbarStart(0),
+ HorizontalScrollbarStart(),
GetLayoutBox()->BorderTop().ToInt() + visible_rect.Height() -
h_scrollbar_thickness,
visible_rect.Width() - (HasVerticalScrollbar()
@@ -1890,11 +1964,10 @@ bool PaintLayerScrollableArea::HitTestOverflowControls(
}
IntRect PaintLayerScrollableArea::ResizerCornerRect(
- const IntRect& bounds,
ResizerHitTestType resizer_hit_test_type) const {
if (!GetLayoutBox()->StyleRef().HasResize())
return IntRect();
- IntRect corner = CornerRect(bounds);
+ IntRect corner = CornerRect();
if (resizer_hit_test_type == kResizerForTouch) {
// We make the resizer virtually larger for touch hit testing. With the
@@ -1913,12 +1986,8 @@ IntRect PaintLayerScrollableArea::ResizerCornerRect(
IntRect PaintLayerScrollableArea::ScrollCornerAndResizerRect() const {
IntRect scroll_corner_and_resizer = ScrollCornerRect();
- if (scroll_corner_and_resizer.IsEmpty()) {
- scroll_corner_and_resizer =
- ResizerCornerRect(GetLayoutBox()->PixelSnappedBorderBoxRect(
- Layer()->SubpixelAccumulation()),
- kResizerForPointer);
- }
+ if (scroll_corner_and_resizer.IsEmpty())
+ return ResizerCornerRect(kResizerForPointer);
return scroll_corner_and_resizer;
}
@@ -1930,9 +1999,7 @@ bool PaintLayerScrollableArea::IsPointInResizeControl(
IntPoint local_point = RoundedIntPoint(
GetLayoutBox()->AbsoluteToLocalPoint(PhysicalOffset(absolute_point)));
- IntRect local_bounds(IntPoint(), Layer()->PixelSnappedSize());
- return ResizerCornerRect(local_bounds, resizer_hit_test_type)
- .Contains(local_point);
+ return ResizerCornerRect(resizer_hit_test_type).Contains(local_point);
}
bool PaintLayerScrollableArea::HitTestResizerInFragments(
@@ -1946,11 +2013,12 @@ bool PaintLayerScrollableArea::HitTestResizerInFragments(
for (int i = layer_fragments.size() - 1; i >= 0; --i) {
const PaintLayerFragment& fragment = layer_fragments.at(i);
- if (fragment.background_rect.Intersects(hit_test_location) &&
- ResizerCornerRect(PixelSnappedIntRect(fragment.layer_bounds),
- kResizerForPointer)
- .Contains(hit_test_location.RoundedPoint()))
- return true;
+ if (fragment.background_rect.Intersects(hit_test_location)) {
+ IntRect resizer_corner_rect = ResizerCornerRect(kResizerForPointer);
+ resizer_corner_rect.MoveBy(RoundedIntPoint(fragment.layer_bounds.offset));
+ if (resizer_corner_rect.Contains(hit_test_location.RoundedPoint()))
+ return true;
+ }
}
return false;
@@ -2002,12 +2070,10 @@ void PaintLayerScrollableArea::InvalidateAllStickyConstraints() {
}
void PaintLayerScrollableArea::InvalidateStickyConstraintsFor(
- PaintLayer* layer,
- bool needs_compositing_update) {
+ PaintLayer* layer) {
if (PaintLayerScrollableAreaRareData* d = RareData()) {
d->sticky_constraints_map_.erase(layer);
- if (needs_compositing_update &&
- layer->GetLayoutObject().StyleRef().HasStickyConstrainedPosition()) {
+ if (layer->GetLayoutObject().StyleRef().HasStickyConstrainedPosition()) {
layer->SetNeedsCompositingInputsUpdate();
layer->GetLayoutObject().SetNeedsPaintPropertyUpdate();
}
@@ -2037,7 +2103,7 @@ IntSize PaintLayerScrollableArea::OffsetFromResizeCorner(
// left corner.
// FIXME: This assumes the location is 0, 0. Is this guaranteed to always be
// the case?
- IntSize element_size = Layer()->PixelSnappedSize();
+ IntSize element_size = PixelSnappedBorderBoxSize();
if (GetLayoutBox()->ShouldPlaceBlockDirectionScrollbarOnLogicalLeft())
element_size.SetWidth(0);
IntPoint resizer_point = IntPoint(element_size);
@@ -2143,15 +2209,15 @@ void PaintLayerScrollableArea::Resize(const IntPoint& pos,
CSSPrimitiveValue::UnitType::kPixels);
}
- document.UpdateStyleAndLayout();
+ document.UpdateStyleAndLayout(DocumentUpdateReason::kSizeChange);
- // FIXME (Radar 4118564): We should also autoscroll the window as necessary to
+ // FIXME: We should also autoscroll the window as necessary to
// keep the point under the cursor in view.
}
PhysicalRect PaintLayerScrollableArea::ScrollIntoView(
const PhysicalRect& absolute_rect,
- const WebScrollIntoViewParams& params) {
+ const mojom::blink::ScrollIntoViewParamsPtr& params) {
PhysicalRect local_expose_rect =
GetLayoutBox()->AbsoluteToLocalRect(absolute_rect);
PhysicalOffset border_origin_to_scroll_origin(-GetLayoutBox()->BorderLeft(),
@@ -2168,13 +2234,13 @@ PhysicalRect PaintLayerScrollableArea::ScrollIntoView(
PhysicalRect scroll_snapport_rect = VisibleScrollSnapportRect();
ScrollOffset target_offset = ScrollAlignment::GetScrollOffsetToExpose(
- scroll_snapport_rect, local_expose_rect, params.GetScrollAlignmentX(),
- params.GetScrollAlignmentY(), GetScrollOffset());
+ scroll_snapport_rect, local_expose_rect, *params->align_x.get(),
+ *params->align_y.get(), GetScrollOffset());
ScrollOffset new_scroll_offset(
ClampScrollOffset(RoundedIntSize(target_offset)));
ScrollOffset old_scroll_offset = GetScrollOffset();
- if (params.GetScrollType() == kUserScroll) {
+ if (params->type == mojom::blink::ScrollType::kUser) {
if (!UserInputScrollable(kHorizontalScrollbar))
new_scroll_offset.SetWidth(old_scroll_offset.Width());
if (!UserInputScrollable(kVerticalScrollbar))
@@ -2188,17 +2254,16 @@ PhysicalRect PaintLayerScrollableArea::ScrollIntoView(
end_point = GetSnapPositionAndSetTarget(*strategy).value_or(end_point);
new_scroll_offset = ScrollPositionToOffset(end_point);
- if (params.is_for_scroll_sequence) {
- DCHECK(params.GetScrollType() == kProgrammaticScroll ||
- params.GetScrollType() == kUserScroll);
- ScrollBehavior behavior =
- DetermineScrollBehavior(params.GetScrollBehavior(),
- GetLayoutBox()->StyleRef().GetScrollBehavior());
+ if (params->is_for_scroll_sequence) {
+ DCHECK(params->type == mojom::blink::ScrollType::kProgrammatic ||
+ params->type == mojom::blink::ScrollType::kUser);
+ mojom::blink::ScrollBehavior behavior = DetermineScrollBehavior(
+ params->behavior, GetLayoutBox()->StyleRef().GetScrollBehavior());
GetSmoothScrollSequencer()->QueueAnimation(this, new_scroll_offset,
behavior);
} else {
- SetScrollOffset(new_scroll_offset, params.GetScrollType(),
- kScrollBehaviorInstant);
+ SetScrollOffset(new_scroll_offset, params->type,
+ mojom::blink::ScrollBehavior::kInstant);
}
ScrollOffset scroll_offset_difference = new_scroll_offset - old_scroll_offset;
@@ -2239,12 +2304,12 @@ void PaintLayerScrollableArea::UpdateScrollableAreaSet() {
bool is_visible_to_hit_test =
GetLayoutBox()->StyleRef().VisibleToHitTesting();
bool did_scroll_overflow = scrolls_overflow_;
- if (GetLayoutBox()->IsLayoutView()) {
- ScrollbarMode h_mode;
- ScrollbarMode v_mode;
- ToLayoutView(GetLayoutBox())->CalculateScrollbarModes(h_mode, v_mode);
- if (h_mode == ScrollbarMode::kAlwaysOff &&
- v_mode == ScrollbarMode::kAlwaysOff)
+ if (auto* layout_view = DynamicTo<LayoutView>(GetLayoutBox())) {
+ mojom::blink::ScrollbarMode h_mode;
+ mojom::blink::ScrollbarMode v_mode;
+ layout_view->CalculateScrollbarModes(h_mode, v_mode);
+ if (h_mode == mojom::blink::ScrollbarMode::kAlwaysOff &&
+ v_mode == mojom::blink::ScrollbarMode::kAlwaysOff)
has_overflow = false;
}
@@ -2264,7 +2329,7 @@ void PaintLayerScrollableArea::UpdateScrollableAreaSet() {
if (RuntimeEnabledFeatures::ImplicitRootScrollerEnabled() &&
scrolls_overflow_) {
- if (GetLayoutBox()->IsLayoutView()) {
+ if (IsA<LayoutView>(GetLayoutBox())) {
if (Element* owner = GetLayoutBox()->GetDocument().LocalOwner()) {
owner->GetDocument().GetRootScrollerController().ConsiderForImplicit(
*owner);
@@ -2281,8 +2346,8 @@ void PaintLayerScrollableArea::UpdateScrollableAreaSet() {
// PaintPropertyTreeBuilder::updateScrollAndScrollTranslation).
GetLayoutBox()->SetNeedsPaintPropertyUpdate();
- // Scroll hit test display items depend on whether the box scrolls overflow.
- // The scroll hit test display items paint in the background phase
+ // Scroll hit test data depend on whether the box scrolls overflow.
+ // They are painted in the background phase
// (see: BoxPainter::PaintBoxDecorationBackground).
GetLayoutBox()->SetBackgroundNeedsFullPaintInvalidation();
@@ -2290,16 +2355,18 @@ void PaintLayerScrollableArea::UpdateScrollableAreaSet() {
}
void PaintLayerScrollableArea::UpdateCompositingLayersAfterScroll() {
+ DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
+
PaintLayerCompositor* compositor = GetLayoutBox()->View()->Compositor();
- if (!compositor->InCompositingMode())
+ if (!compositor || !compositor->InCompositingMode())
return;
if (UsesCompositedScrolling()) {
DCHECK(Layer()->HasCompositedLayerMapping());
ScrollingCoordinator* scrolling_coordinator = GetScrollingCoordinator();
- bool handled_scroll =
- scrolling_coordinator &&
- scrolling_coordinator->UpdateCompositedScrollOffset(this);
+ bool handled_scroll = scrolling_coordinator &&
+ scrolling_coordinator->UpdateCompositorScrollOffset(
+ *GetLayoutBox()->GetFrame(), *this);
if (!handled_scroll) {
compositor->SetNeedsCompositingUpdate(
@@ -2309,15 +2376,18 @@ void PaintLayerScrollableArea::UpdateCompositingLayersAfterScroll() {
// If we have fixed elements and we scroll the root layer we might
// change compositing since the fixed elements might now overlap a
// composited layer.
- if (Layer()->IsRootLayer()) {
- LocalFrame* frame = GetLayoutBox()->GetFrame();
- if (frame && frame->View() &&
- frame->View()->HasViewportConstrainedObjects()) {
- Layer()->SetNeedsCompositingInputsUpdate();
+ if (!base::FeatureList::IsEnabled(
+ features::kAssumeOverlapAfterFixedOrStickyPosition)) {
+ if (Layer()->IsRootLayer()) {
+ LocalFrame* frame = GetLayoutBox()->GetFrame();
+ if (frame && frame->View() &&
+ frame->View()->HasViewportConstrainedObjects()) {
+ Layer()->SetNeedsCompositingInputsUpdate();
+ }
}
}
} else {
- Layer()->SetNeedsCompositingInputsUpdate();
+ Layer()->SetNeedsCompositingInputsUpdate(false);
}
}
@@ -2385,7 +2455,29 @@ bool PaintLayerScrollableArea::ComputeNeedsCompositedScrolling(
: DocumentLifecycle::kInCompositingUpdate,
GetDocument()->Lifecycle().GetState());
+ const auto* box = GetLayoutBox();
+ auto old_background_paint_location = box->GetBackgroundPaintLocation();
non_composited_main_thread_scrolling_reasons_ = 0;
+ auto new_background_paint_location =
+ box->ComputeBackgroundPaintLocationIfComposited(
+ &non_composited_main_thread_scrolling_reasons_);
+ bool needs_composited_scrolling = ComputeNeedsCompositedScrollingInternal(
+ new_background_paint_location, force_prefer_compositing_to_lcd_text);
+ if (!needs_composited_scrolling)
+ new_background_paint_location = kBackgroundPaintInGraphicsLayer;
+ if (new_background_paint_location != old_background_paint_location) {
+ box->GetMutableForPainting().SetBackgroundPaintLocation(
+ new_background_paint_location);
+ }
+
+ return needs_composited_scrolling;
+}
+
+bool PaintLayerScrollableArea::ComputeNeedsCompositedScrollingInternal(
+ BackgroundPaintLocation background_paint_location_if_composited,
+ bool force_prefer_compositing_to_lcd_text) {
+ DCHECK_EQ(background_paint_location_if_composited,
+ GetLayoutBox()->ComputeBackgroundPaintLocationIfComposited());
if (CompositingReasonFinder::RequiresCompositingForRootScroller(*layer_))
return true;
@@ -2419,15 +2511,16 @@ bool PaintLayerScrollableArea::ComputeNeedsCompositedScrolling(
// transforms are also integer.
bool background_supports_lcd_text =
box->StyleRef().IsStackingContext() &&
- (box->GetBackgroundPaintLocation(
- &non_composited_main_thread_scrolling_reasons_) &
+ (background_paint_location_if_composited &
kBackgroundPaintInScrollingContents) &&
layer_->BackgroundIsKnownToBeOpaqueInRect(box->PhysicalPaddingBoxRect(),
true) &&
!layer_->CompositesWithTransform() && !layer_->CompositesWithOpacity();
if (!force_prefer_compositing_to_lcd_text &&
- !layer_->Compositor()->PreferCompositingToLCDTextEnabled() &&
+ !box->GetDocument()
+ .GetSettings()
+ ->GetPreferCompositingToLCDTextEnabled() &&
!background_supports_lcd_text) {
if (layer_->CompositesWithOpacity()) {
non_composited_main_thread_scrolling_reasons_ |=
@@ -2511,12 +2604,13 @@ PaintLayerScrollableArea::GetCompositorAnimationTimeline() const {
}
bool PaintLayerScrollableArea::HasTickmarks() const {
- return layer_->IsRootLayer() && ToLayoutView(GetLayoutBox())->HasTickmarks();
+ return layer_->IsRootLayer() &&
+ To<LayoutView>(GetLayoutBox())->HasTickmarks();
}
Vector<IntRect> PaintLayerScrollableArea::GetTickmarks() const {
if (layer_->IsRootLayer())
- return ToLayoutView(GetLayoutBox())->GetTickmarks();
+ return To<LayoutView>(GetLayoutBox())->GetTickmarks();
return Vector<IntRect>();
}
@@ -2571,7 +2665,7 @@ Scrollbar* PaintLayerScrollableArea::ScrollbarManager::CreateScrollbar(
style_source.StyleRef().HasPseudoElementStyle(kPseudoIdScrollbar);
if (has_custom_scrollbar_style) {
DCHECK(style_source.GetNode() && style_source.GetNode()->IsElementNode());
- scrollbar = CustomScrollbar::CreateCustomScrollbar(
+ scrollbar = MakeGarbageCollected<CustomScrollbar>(
ScrollableArea(), orientation, To<Element>(style_source.GetNode()));
} else {
ScrollbarControlSize scrollbar_size = kRegularScrollbar;
@@ -2580,7 +2674,7 @@ Scrollbar* PaintLayerScrollableArea::ScrollbarManager::CreateScrollbar(
style_source.StyleRef().EffectiveAppearance());
}
Element* style_source_element = nullptr;
- if (RuntimeEnabledFeatures::FormControlsRefreshEnabled()) {
+ if (::features::IsFormControlsRefreshEnabled()) {
style_source_element = DynamicTo<Element>(style_source.GetNode());
}
scrollbar = MakeGarbageCollected<Scrollbar>(
@@ -2832,8 +2926,13 @@ static IntRect InvalidatePaintOfScrollbarIfNeeded(
bool is_overlay = scrollbar && scrollbar->IsOverlayScrollbar();
IntRect new_visual_rect;
- if (scrollbar)
+ if (scrollbar) {
new_visual_rect = scrollbar->FrameRect();
+ // TODO(crbug.com/1020913): We should not round paint_offset but should
+ // consider subpixel accumulation when painting scrollbars.
+ new_visual_rect.MoveBy(
+ RoundedIntPoint(context.fragment_data->PaintOffset()));
+ }
if (needs_paint_invalidation && graphics_layer) {
// If the scrollbar needs paint invalidation but didn't change location/size
@@ -2906,8 +3005,10 @@ void PaintLayerScrollableArea::InvalidatePaintOfScrollControlsIfNeeded(
box_geometry_has_been_invalidated, context));
IntRect scroll_corner_and_resizer_visual_rect = ScrollCornerAndResizerRect();
+ // TODO(crbug.com/1020913): We should not round paint_offset but should
+ // consider subpixel accumulation when painting scrollbars.
scroll_corner_and_resizer_visual_rect.MoveBy(
- RoundedIntPoint(box.FirstFragment().PaintOffset()));
+ RoundedIntPoint(context.fragment_data->PaintOffset()));
if (ScrollControlNeedsPaintInvalidation(
scroll_corner_and_resizer_visual_rect,
scroll_corner_and_resizer_visual_rect_,
@@ -3020,10 +3121,21 @@ CompositorElementId PaintLayerScrollableArea::GetScrollElementId() const {
GetLayoutBox()->UniqueId(), CompositorElementIdNamespace::kScroll);
}
+IntSize PaintLayerScrollableArea::PixelSnappedBorderBoxSize() const {
+ // TODO(crbug.com/1020913): We use this method during
+ // PositionOverflowControls() even before the paint offset is updated.
+ // This can be fixed only after we support subpixels in overflow control
+ // geometry. For now we ensure correct pixel snapping of overflow controls by
+ // calling PositionOverflowControls() again when paint offset is updated.
+ return GetLayoutBox()->PixelSnappedBorderBoxSize(
+ GetLayoutBox()->FirstFragment().PaintOffset());
+}
+
IntRect
PaintLayerScrollableArea::ScrollingBackgroundDisplayItemClient::VisualRect()
const {
const auto* box = scrollable_area_->GetLayoutBox();
+
const auto& paint_offset = box->FirstFragment().PaintOffset();
auto overflow_clip_rect =
PixelSnappedIntRect(box->OverflowClipRect(paint_offset));
@@ -3037,6 +3149,30 @@ PaintLayerScrollableArea::ScrollingBackgroundDisplayItemClient::VisualRect()
scrollable_area_->layer_->GraphicsLayerBacking()->VisualRect());
}
#endif
+
+ // The HTML element of a document is special, in that it can have a transform,
+ // but the bounds of the painted area of the element still extends beyond
+ // its actual size to encompass the entire viewport canvas. This is
+ // accomplished in ViewPainter by starting with a rect in viewport canvas
+ // space that is equal to the size of the viewport canvas, then mapping it
+ // into the local border box space of the HTML element, and painting a rect
+ // equal to the bounding box of the result. We need to add in that mapped rect
+ // in such cases.
+ const Document& document = box->GetDocument();
+ if (IsA<LayoutView>(box) &&
+ (document.IsXMLDocument() || document.IsHTMLDocument())) {
+ if (const auto* document_element = document.documentElement()) {
+ if (const auto* document_element_object =
+ document_element->GetLayoutObject()) {
+ TransformationMatrix matrix;
+ document_element_object->GetTransformFromContainer(
+ box, PhysicalOffset(), matrix);
+ if (matrix.IsInvertible())
+ result.Unite(matrix.Inverse().MapRect(result));
+ }
+ }
+ }
+
return result;
}
@@ -3054,12 +3190,6 @@ PaintLayerScrollableArea::ScrollingBackgroundDisplayItemClient::OwnerNodeId()
->OwnerNodeId();
}
-bool PaintLayerScrollableArea::ScrollingBackgroundDisplayItemClient::
- PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const {
- return scrollable_area_->GetLayoutBox()
- ->PaintedOutputOfObjectHasNoEffectRegardlessOfSize();
-}
-
IntRect PaintLayerScrollableArea::ScrollCornerDisplayItemClient::VisualRect()
const {
return scrollable_area_->scroll_corner_and_resizer_visual_rect_;
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 c5a4495f359..afe17a03130 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
@@ -46,6 +46,7 @@
#include <memory>
#include "base/macros.h"
+#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/scroll_anchor.h"
#include "third_party/blink/renderer/core/page/scrolling/sticky_position_scrolling_constraints.h"
@@ -77,6 +78,8 @@ struct CORE_EXPORT PaintLayerScrollableAreaRareData {
StickyConstraintsMap sticky_constraints_map_;
base::Optional<cc::SnapContainerData> snap_container_data_;
+ bool snap_container_data_needs_update_ = true;
+ bool needs_resnap_ = false;
DISALLOW_COPY_AND_ASSIGN(PaintLayerScrollableAreaRareData);
};
@@ -162,7 +165,7 @@ class CORE_EXPORT PaintLayerScrollableArea final
void DestroyDetachedScrollbars();
void Dispose();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
Scrollbar* CreateScrollbar(ScrollbarOrientation);
@@ -246,10 +249,6 @@ class CORE_EXPORT PaintLayerScrollableArea final
// FIXME: We should pass in the LayoutBox but this opens a window
// for crashers during PaintLayer setup (see crbug.com/368062).
- static PaintLayerScrollableArea* Create(PaintLayer& layer) {
- return MakeGarbageCollected<PaintLayerScrollableArea>(layer);
- }
-
explicit PaintLayerScrollableArea(PaintLayer&);
~PaintLayerScrollableArea() override;
@@ -345,7 +344,7 @@ class CORE_EXPORT PaintLayerScrollableArea final
bool UserInputScrollable(ScrollbarOrientation) const override;
bool ShouldPlaceVerticalScrollbarOnLeft() const override;
int PageStep(ScrollbarOrientation) const override;
- ScrollBehavior ScrollBehaviorStyle() const override;
+ mojom::blink::ScrollBehavior ScrollBehaviorStyle() const override;
WebColorScheme UsedColorScheme() const override;
cc::AnimationHost* GetCompositorAnimationHost() const override;
CompositorAnimationTimeline* GetCompositorAnimationTimeline() const override;
@@ -358,22 +357,25 @@ class CORE_EXPORT PaintLayerScrollableArea final
IntPoint ScrollOrigin() const { return scroll_origin_; }
bool ScrollOriginChanged() const { return scroll_origin_changed_; }
- void ScrollToAbsolutePosition(
- const FloatPoint& position,
- ScrollBehavior scroll_behavior = kScrollBehaviorInstant,
- ScrollType scroll_type = kProgrammaticScroll) {
+ void ScrollToAbsolutePosition(const FloatPoint& position,
+ mojom::blink::ScrollBehavior scroll_behavior =
+ mojom::blink::ScrollBehavior::kInstant,
+ mojom::blink::ScrollType scroll_type =
+ mojom::blink::ScrollType::kProgrammatic) {
SetScrollOffset(position - ScrollOrigin(), scroll_type, scroll_behavior);
}
// This will set the scroll position without clamping, and it will do all
// post-update work even if the scroll position didn't change.
- void SetScrollOffsetUnconditionally(const ScrollOffset&,
- ScrollType = kProgrammaticScroll);
+ void SetScrollOffsetUnconditionally(
+ const ScrollOffset&,
+ mojom::blink::ScrollType = mojom::blink::ScrollType::kProgrammatic);
// This will set the scroll position without clamping, and it will do all
// post-update work even if the scroll position didn't change.
- void SetScrollPositionUnconditionally(const DoublePoint&,
- ScrollType = kProgrammaticScroll);
+ void SetScrollPositionUnconditionally(
+ const DoublePoint&,
+ mojom::blink::ScrollType = mojom::blink::ScrollType::kProgrammatic);
// TODO(szager): Actually run these after all of layout is finished.
// Currently, they run at the end of box()'es layout (or after all flexbox
@@ -439,8 +441,9 @@ class CORE_EXPORT PaintLayerScrollableArea final
// Returns the new offset, after scrolling, of the given rect in absolute
// coordinates, clipped by the parent's client rect.
- PhysicalRect ScrollIntoView(const PhysicalRect&,
- const WebScrollIntoViewParams&) override;
+ PhysicalRect ScrollIntoView(
+ const PhysicalRect&,
+ const mojom::blink::ScrollIntoViewParamsPtr&) override;
// Returns true if scrollable area is in the FrameView's collection of
// scrollable areas. This can only happen if we're scrollable, visible to hit
@@ -452,6 +455,8 @@ class CORE_EXPORT PaintLayerScrollableArea final
// Rectangle encompassing the scroll corner and resizer rect.
IntRect ScrollCornerAndResizerRect() const;
+ // This also updates main thread scrolling reasons and the LayoutBox's
+ // background paint location.
bool ComputeNeedsCompositedScrolling(
bool force_prefer_compositing_to_lcd_text);
@@ -463,14 +468,14 @@ class CORE_EXPORT PaintLayerScrollableArea final
return needs_composited_scrolling_;
}
- IntRect ResizerCornerRect(const IntRect&, ResizerHitTestType) const;
+ IntRect ResizerCornerRect(ResizerHitTestType) const;
PaintLayer* Layer() const override;
LayoutCustomScrollbarPart* Resizer() const { return resizer_; }
- IntRect RectForHorizontalScrollbar(const IntRect& border_box_rect) const;
- IntRect RectForVerticalScrollbar(const IntRect& border_box_rect) const;
+ IntRect RectForHorizontalScrollbar() const;
+ IntRect RectForVerticalScrollbar() const;
bool ScheduleAnimation() override;
bool ShouldPerformScrollAnchoring() const override;
@@ -527,8 +532,7 @@ class CORE_EXPORT PaintLayerScrollableArea final
}
void InvalidateAllStickyConstraints();
- void InvalidateStickyConstraintsFor(PaintLayer*,
- bool needs_compositing_update = true);
+ void InvalidateStickyConstraintsFor(PaintLayer*);
void InvalidatePaintForStickyDescendants();
uint32_t GetNonCompositedMainThreadScrollingReasons() {
return non_composited_main_thread_scrolling_reasons_;
@@ -562,7 +566,7 @@ class CORE_EXPORT PaintLayerScrollableArea final
bool HasHorizontalOverflow() const;
bool HasVerticalOverflow() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
const DisplayItemClient& GetScrollingBackgroundDisplayItemClient() const {
return scrolling_background_display_item_client_;
@@ -574,12 +578,30 @@ class CORE_EXPORT PaintLayerScrollableArea final
const cc::SnapContainerData* GetSnapContainerData() const override;
void SetSnapContainerData(base::Optional<cc::SnapContainerData>) override;
bool SetTargetSnapAreaElementIds(cc::TargetSnapAreaElementIds) override;
+ bool SnapContainerDataNeedsUpdate() const override;
+ void SetSnapContainerDataNeedsUpdate(bool) override;
+ bool NeedsResnap() const override;
+ void SetNeedsResnap(bool) override;
base::Optional<FloatPoint> GetSnapPositionAndSetTarget(
const cc::SnapSelectionStrategy& strategy) override;
void DisposeImpl() override;
+ void SetPendingHistoryRestoreScrollOffset(
+ const HistoryItem::ViewState& view_state,
+ bool should_restore_scroll) override {
+ if (!should_restore_scroll)
+ return;
+ pending_view_state_ = view_state;
+ }
+
+ void ApplyPendingHistoryRestoreScrollOffset() override;
+
+ bool HasPendingHistoryRestoreScrollOffset() override {
+ return !!pending_view_state_;
+ }
+
private:
bool NeedsScrollbarReconstruction() const;
@@ -591,18 +613,29 @@ class CORE_EXPORT PaintLayerScrollableArea final
// Update the proportions used for thumb rect dimensions.
void UpdateScrollbarProportions();
- void UpdateScrollOffset(const ScrollOffset&, ScrollType) override;
+ void UpdateScrollOffset(const ScrollOffset&,
+ mojom::blink::ScrollType) override;
void InvalidatePaintForScrollOffsetChange();
- int VerticalScrollbarStart(int min_x, int max_x) const;
- int HorizontalScrollbarStart(int min_x) const;
+ int VerticalScrollbarStart() const;
+ int HorizontalScrollbarStart() const;
IntSize ScrollbarOffset(const Scrollbar&) const;
- enum ComputeScrollbarExistenceOption { kDefault, kForbidAddingAutoBars };
+ // If OverflowIndependent is specified, will only change current scrollbar
+ // existence if the new style doesn't depend on overflow which requires
+ // layout to be clean. It'd be nice if we could always determine existence at
+ // one point, after layout. Unfortunately, it seems that parts of layout are
+ // dependent on scrollbar existence in cases like |overflow:scroll|, removing
+ // the post style pass causes breaks in tests e.g. forms web_tests. Thus, we
+ // must do two scrollbar existence passes.
+ enum ComputeScrollbarExistenceOption {
+ kDependsOnOverflow,
+ kOverflowIndependent
+ };
void ComputeScrollbarExistence(
bool& needs_horizontal_scrollbar,
bool& needs_vertical_scrollbar,
- ComputeScrollbarExistenceOption = kDefault) const;
+ ComputeScrollbarExistenceOption = kDependsOnOverflow) const;
// If the content fits entirely in the area without auto scrollbars, returns
// true to try to remove them. This is a heuristic and can be incorrect if the
@@ -637,7 +670,7 @@ class CORE_EXPORT PaintLayerScrollableArea final
return *rare_data_.get();
}
- IntRect CornerRect(const IntRect& bounds) const;
+ IntRect CornerRect() const;
void ScrollControlWasSetNeedsPaintInvalidation() override;
@@ -647,6 +680,13 @@ class CORE_EXPORT PaintLayerScrollableArea final
bool HasNonCompositedStickyDescendants() const;
+ IntSize PixelSnappedBorderBoxSize() const;
+
+ using BackgroundPaintLocation = uint8_t;
+ bool ComputeNeedsCompositedScrollingInternal(
+ BackgroundPaintLocation background_paint_location_if_composited,
+ bool force_prefer_compositing_to_lcd_text);
+
// PaintLayer is destructed before PaintLayerScrollable area, during this
// time before PaintLayerScrollableArea has been collected layer_ will
// be set to nullptr by the Dispose method.
@@ -672,6 +712,7 @@ class CORE_EXPORT PaintLayerScrollableArea final
// instance has been reconstructed.
unsigned rebuild_horizontal_scrollbar_layer_ : 1;
unsigned rebuild_vertical_scrollbar_layer_ : 1;
+ unsigned previous_vertical_scrollbar_on_left_ : 1;
unsigned needs_scroll_offset_clamp_ : 1;
unsigned needs_relayout_ : 1;
@@ -742,7 +783,6 @@ class CORE_EXPORT PaintLayerScrollableArea final
IntRect VisualRect() const final;
String DebugName() const final;
DOMNodeId OwnerNodeId() const final;
- bool PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const final;
Member<const PaintLayerScrollableArea> scrollable_area_;
};
@@ -768,14 +808,9 @@ class CORE_EXPORT PaintLayerScrollableArea final
ScrollingBackgroundDisplayItemClient
scrolling_background_display_item_client_{*this};
ScrollCornerDisplayItemClient scroll_corner_display_item_client_{*this};
+ base::Optional<HistoryItem::ViewState> pending_view_state_;
};
-DEFINE_TYPE_CASTS(PaintLayerScrollableArea,
- ScrollableArea,
- scrollableArea,
- scrollableArea->IsPaintLayerScrollableArea(),
- scrollableArea.IsPaintLayerScrollableArea());
-
} // namespace blink
#endif // LayerScrollableArea_h
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 70a2bd4c2e0..da749e252a3 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
@@ -8,8 +8,11 @@
#include "build/build_config.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/renderer/core/animation/scroll_timeline.h"
+#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/layout/layout_box_model_object.h"
+#include "third_party/blink/renderer/core/page/scrolling/snap_coordinator.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/scroll/scroll_types.h"
#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
@@ -677,14 +680,16 @@ TEST_P(PaintLayerScrollableAreaTest, HideTooltipWhenScrollPositionChanges) {
EXPECT_CALL(GetChromeClient(),
MockSetToolTip(GetDocument().GetFrame(), String(), _))
.Times(1);
- scrollable_area->SetScrollOffset(ScrollOffset(1, 1), kUserScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(1, 1),
+ mojom::blink::ScrollType::kUser);
// Programmatic scrolling should not dismiss the tooltip, so setToolTip
// should not be called for this invocation.
EXPECT_CALL(GetChromeClient(),
MockSetToolTip(GetDocument().GetFrame(), String(), _))
.Times(0);
- scrollable_area->SetScrollOffset(ScrollOffset(2, 2), kProgrammaticScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(2, 2),
+ mojom::blink::ScrollType::kProgrammatic);
}
TEST_P(PaintLayerScrollableAreaTest, IncludeOverlayScrollbarsInVisibleWidth) {
@@ -703,7 +708,8 @@ TEST_P(PaintLayerScrollableAreaTest, IncludeOverlayScrollbarsInVisibleWidth) {
PaintLayerScrollableArea* scrollable_area =
ToLayoutBoxModelObject(scroller->GetLayoutObject())->GetScrollableArea();
ASSERT_TRUE(scrollable_area);
- scrollable_area->SetScrollOffset(ScrollOffset(100, 0), kClampingScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(100, 0),
+ mojom::blink::ScrollType::kClamping);
EXPECT_EQ(scrollable_area->GetScrollOffset().Width(), 0);
}
@@ -819,7 +825,8 @@ TEST_P(PaintLayerScrollableAreaTest, OverflowHiddenScrollOffsetInvalidation) {
// Going from zero scroll offset to non-zero may require a new paint property
// and should invalidate paint and paint properties.
- scrollable_area->SetScrollOffset(ScrollOffset(0, 1), kProgrammaticScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 1),
+ mojom::blink::ScrollType::kProgrammatic);
EXPECT_TRUE(scroller->PaintingLayer()->SelfNeedsRepaint());
EXPECT_TRUE(scroller->NeedsPaintPropertyUpdate());
UpdateAllLifecyclePhasesForTest();
@@ -829,7 +836,8 @@ TEST_P(PaintLayerScrollableAreaTest, OverflowHiddenScrollOffsetInvalidation) {
EXPECT_NE(nullptr, properties->ScrollTranslation());
// A property update is needed when scroll offset changes.
- scrollable_area->SetScrollOffset(ScrollOffset(0, 2), kProgrammaticScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 2),
+ mojom::blink::ScrollType::kProgrammatic);
EXPECT_TRUE(scroller->NeedsPaintPropertyUpdate());
UpdateAllLifecyclePhasesForTest();
@@ -839,7 +847,8 @@ TEST_P(PaintLayerScrollableAreaTest, OverflowHiddenScrollOffsetInvalidation) {
// Going from non-zero scroll offset to zero may require destroying a paint
// property and should invalidate paint and paint properties.
- scrollable_area->SetScrollOffset(ScrollOffset(0, 0), kProgrammaticScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 0),
+ mojom::blink::ScrollType::kProgrammatic);
EXPECT_TRUE(scroller->PaintingLayer()->SelfNeedsRepaint());
EXPECT_TRUE(scroller->NeedsPaintPropertyUpdate());
UpdateAllLifecyclePhasesForTest();
@@ -873,7 +882,8 @@ TEST_P(PaintLayerScrollableAreaTest, ScrollDoesNotInvalidate) {
EXPECT_EQ(FloatSize(0, 0), scrollable_area->GetScrollOffset());
// Changing the scroll offset should not require paint invalidation.
- scrollable_area->SetScrollOffset(ScrollOffset(0, 1), kProgrammaticScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 1),
+ mojom::blink::ScrollType::kProgrammatic);
EXPECT_FALSE(scroller->ShouldDoFullPaintInvalidation());
EXPECT_TRUE(scroller->NeedsPaintPropertyUpdate());
UpdateAllLifecyclePhasesForTest();
@@ -901,19 +911,17 @@ TEST_P(PaintLayerScrollableAreaTest,
auto* scroller = ToLayoutBox(GetLayoutObjectByElementId("scroller"));
auto* scrollable_area = scroller->GetScrollableArea();
EXPECT_EQ(kBackgroundPaintInScrollingContents,
+ scroller->ComputeBackgroundPaintLocationIfComposited());
+ EXPECT_EQ(kBackgroundPaintInGraphicsLayer,
scroller->GetBackgroundPaintLocation());
// Programmatically changing the scroll offset.
- scrollable_area->SetScrollOffset(ScrollOffset(0, 1), kProgrammaticScroll);
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
- // No invalidation because the background paints into scrolling contents.
- EXPECT_FALSE(scroller->ShouldDoFullPaintInvalidation());
- EXPECT_FALSE(scroller->BackgroundNeedsFullPaintInvalidation());
- } else {
- // Full invalidation because there is no separate scrolling contents layer.
- EXPECT_TRUE(scroller->ShouldDoFullPaintInvalidation());
- EXPECT_TRUE(scroller->BackgroundNeedsFullPaintInvalidation());
- }
+ 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());
+
EXPECT_TRUE(scroller->NeedsPaintPropertyUpdate());
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(FloatSize(0, 1), scrollable_area->GetScrollOffset());
@@ -942,10 +950,13 @@ TEST_P(PaintLayerScrollableAreaTest,
auto* scrollable_area = scroller->GetScrollableArea();
EXPECT_EQ(
kBackgroundPaintInGraphicsLayer | kBackgroundPaintInScrollingContents,
- scroller->GetBackgroundPaintLocation());
+ scroller->ComputeBackgroundPaintLocationIfComposited());
+ EXPECT_EQ(kBackgroundPaintInGraphicsLayer,
+ scroller->GetBackgroundPaintLocation());
// Programmatically changing the scroll offset.
- scrollable_area->SetScrollOffset(ScrollOffset(0, 1), kProgrammaticScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 1),
+ mojom::blink::ScrollType::kProgrammatic);
// No invalidation because the background paints into the main layer.
EXPECT_TRUE(scroller->ShouldDoFullPaintInvalidation());
EXPECT_TRUE(scroller->BackgroundNeedsFullPaintInvalidation());
@@ -985,8 +996,8 @@ TEST_P(PaintLayerScrollableAreaTest, ViewScrollWithFixedAttachmentBackground) {
// Programmatically changing the view's scroll offset. Should invalidate all
// objects with fixed attachment background.
- view_scrollable_area->SetScrollOffset(ScrollOffset(0, 1),
- kProgrammaticScroll);
+ view_scrollable_area->SetScrollOffset(
+ ScrollOffset(0, 1), mojom::blink::ScrollType::kProgrammatic);
EXPECT_TRUE(fixed_background_div->ShouldDoFullPaintInvalidation());
EXPECT_TRUE(fixed_background_div->BackgroundNeedsFullPaintInvalidation());
EXPECT_FALSE(fixed_background_div->NeedsPaintPropertyUpdate());
@@ -997,13 +1008,14 @@ TEST_P(PaintLayerScrollableAreaTest, ViewScrollWithFixedAttachmentBackground) {
// Programmatically changing the div's scroll offset. Should invalidate the
// scrolled div with fixed attachment background.
- div_scrollable_area->SetScrollOffset(ScrollOffset(0, 1), kProgrammaticScroll);
+ div_scrollable_area->SetScrollOffset(ScrollOffset(0, 1),
+ mojom::blink::ScrollType::kProgrammatic);
EXPECT_TRUE(fixed_background_div->ShouldDoFullPaintInvalidation());
EXPECT_TRUE(fixed_background_div->BackgroundNeedsFullPaintInvalidation());
EXPECT_TRUE(fixed_background_div->NeedsPaintPropertyUpdate());
EXPECT_FALSE(GetLayoutView().ShouldDoFullPaintInvalidation());
EXPECT_FALSE(GetLayoutView().BackgroundNeedsFullPaintInvalidation());
- EXPECT_TRUE(GetLayoutView().NeedsPaintPropertyUpdate());
+ EXPECT_FALSE(GetLayoutView().NeedsPaintPropertyUpdate());
}
TEST_P(PaintLayerScrollableAreaTest,
@@ -1032,14 +1044,16 @@ TEST_P(PaintLayerScrollableAreaTest,
auto* fixed_background_div =
ToLayoutBox(GetLayoutObjectByElementId("fixed-background"));
EXPECT_EQ(kBackgroundPaintInScrollingContents,
+ fixed_background_div->ComputeBackgroundPaintLocationIfComposited());
+ EXPECT_EQ(kBackgroundPaintInGraphicsLayer,
fixed_background_div->GetBackgroundPaintLocation());
auto* div_scrollable_area = fixed_background_div->GetScrollableArea();
auto* view_scrollable_area = GetLayoutView().GetScrollableArea();
// Programmatically changing the view's scroll offset. Should invalidate all
// objects with fixed attachment background.
- view_scrollable_area->SetScrollOffset(ScrollOffset(0, 1),
- kProgrammaticScroll);
+ view_scrollable_area->SetScrollOffset(
+ ScrollOffset(0, 1), mojom::blink::ScrollType::kProgrammatic);
EXPECT_FALSE(fixed_background_div->ShouldDoFullPaintInvalidation());
EXPECT_FALSE(fixed_background_div->BackgroundNeedsFullPaintInvalidation());
EXPECT_FALSE(fixed_background_div->NeedsPaintPropertyUpdate());
@@ -1050,13 +1064,14 @@ TEST_P(PaintLayerScrollableAreaTest,
// Programmatically changing the div's scroll offset. Should invalidate the
// scrolled div with fixed attachment background.
- div_scrollable_area->SetScrollOffset(ScrollOffset(0, 1), kProgrammaticScroll);
+ div_scrollable_area->SetScrollOffset(ScrollOffset(0, 1),
+ mojom::blink::ScrollType::kProgrammatic);
EXPECT_FALSE(fixed_background_div->ShouldDoFullPaintInvalidation());
EXPECT_FALSE(fixed_background_div->BackgroundNeedsFullPaintInvalidation());
EXPECT_TRUE(fixed_background_div->NeedsPaintPropertyUpdate());
EXPECT_FALSE(GetLayoutView().ShouldDoFullPaintInvalidation());
EXPECT_FALSE(GetLayoutView().BackgroundNeedsFullPaintInvalidation());
- EXPECT_TRUE(GetLayoutView().NeedsPaintPropertyUpdate());
+ EXPECT_FALSE(GetLayoutView().NeedsPaintPropertyUpdate());
}
TEST_P(PaintLayerScrollableAreaTest,
@@ -1091,8 +1106,8 @@ TEST_P(PaintLayerScrollableAreaTest,
// Programmatically changing the view's scroll offset. Should invalidate all
// objects with fixed attachment background except the layout view.
- view_scrollable_area->SetScrollOffset(ScrollOffset(0, 1),
- kProgrammaticScroll);
+ view_scrollable_area->SetScrollOffset(
+ ScrollOffset(0, 1), mojom::blink::ScrollType::kProgrammatic);
EXPECT_TRUE(fixed_background_div->ShouldDoFullPaintInvalidation());
EXPECT_TRUE(fixed_background_div->BackgroundNeedsFullPaintInvalidation());
EXPECT_FALSE(fixed_background_div->NeedsPaintPropertyUpdate());
@@ -1103,13 +1118,14 @@ TEST_P(PaintLayerScrollableAreaTest,
// Programmatically changing the div's scroll offset. Should invalidate the
// scrolled div with fixed attachment background.
- div_scrollable_area->SetScrollOffset(ScrollOffset(0, 1), kProgrammaticScroll);
+ div_scrollable_area->SetScrollOffset(ScrollOffset(0, 1),
+ mojom::blink::ScrollType::kProgrammatic);
EXPECT_TRUE(fixed_background_div->ShouldDoFullPaintInvalidation());
EXPECT_TRUE(fixed_background_div->BackgroundNeedsFullPaintInvalidation());
EXPECT_TRUE(fixed_background_div->NeedsPaintPropertyUpdate());
EXPECT_FALSE(GetLayoutView().ShouldDoFullPaintInvalidation());
EXPECT_FALSE(GetLayoutView().BackgroundNeedsFullPaintInvalidation());
- EXPECT_TRUE(GetLayoutView().NeedsPaintPropertyUpdate());
+ EXPECT_FALSE(GetLayoutView().NeedsPaintPropertyUpdate());
}
TEST_P(PaintLayerScrollableAreaTest, HitTestOverlayScrollbars) {
@@ -1179,7 +1195,8 @@ TEST_P(PaintLayerScrollableAreaTest, CompositedStickyDescendant) {
.Transform()
.IsIdentity());
- scrollable_area->SetScrollOffset(ScrollOffset(0, 50), kUserScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 50),
+ mojom::blink::ScrollType::kUser);
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(FloatSize(0, 50), sticky->FirstFragment()
@@ -1233,7 +1250,8 @@ TEST_P(PaintLayerScrollableAreaTest, ScrollbarMaximum) {
PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea();
Scrollbar* scrollbar = scrollable_area->VerticalScrollbar();
- scrollable_area->ScrollBy(ScrollOffset(0, 1000), kProgrammaticScroll);
+ scrollable_area->ScrollBy(ScrollOffset(0, 1000),
+ mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(scrollbar->CurrentPos(), scrollbar->Maximum());
}
@@ -1332,28 +1350,39 @@ TEST_P(PaintLayerScrollableAreaTest, ShowCustomResizerInTextarea) {
EXPECT_NE(paint_layer->GetScrollableArea()->Resizer(), nullptr);
}
-class PaintLayerScrollableAreaCompositingTest
- : public PaintLayerScrollableAreaTest {
- public:
- PaintLayerScrollableAreaCompositingTest() {
- if (GetParam() & kDoNotCompositeTrivial3D) {
- scoped_feature_list_.InitAndEnableFeature(
- blink::features::kDoNotCompositeTrivial3D);
- } else {
- scoped_feature_list_.InitAndDisableFeature(
- blink::features::kDoNotCompositeTrivial3D);
- }
- }
+TEST_P(PaintLayerScrollableAreaTest,
+ ApplyPendingHistoryRestoreScrollOffsetTwice) {
+ GetPage().GetSettings().SetTextAreasAreResizable(true);
+ SetBodyInnerHTML(R"HTML(
+ <!doctype HTML>
+ <div id="target" style="overflow: scroll; width: 50px; height: 50px">
+ <div style="width: 50px; height: 500px">
+ </div>
+ </div>
+ )HTML");
- private:
- base::test::ScopedFeatureList scoped_feature_list_;
-};
+ const auto* paint_layer =
+ ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))->Layer();
+
+ auto* scrollable_area = paint_layer->GetScrollableArea();
+
+ HistoryItem::ViewState view_state;
+ view_state.scroll_offset_ = ScrollOffset(0, 100);
+ scrollable_area->SetPendingHistoryRestoreScrollOffset(view_state, true);
+ scrollable_area->ApplyPendingHistoryRestoreScrollOffset();
+ EXPECT_EQ(ScrollOffset(0, 100), scrollable_area->GetScrollOffset());
-INSTANTIATE_DO_NOT_COMPOSITE_TRIVIAL_3D_P(
- PaintLayerScrollableAreaCompositingTest);
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 50),
+ mojom::blink::ScrollType::kUser);
+
+ // The second call to ApplyPendingHistoryRestoreScrollOffset should
+ // do nothing, since the history was already restored.
+ scrollable_area->ApplyPendingHistoryRestoreScrollOffset();
+ EXPECT_EQ(ScrollOffset(0, 50), scrollable_area->GetScrollOffset());
+}
// Test that a trivial 3D transform results in composited scrolling.
-TEST_P(PaintLayerScrollableAreaCompositingTest, CompositeWithTrivial3D) {
+TEST_P(PaintLayerScrollableAreaTest, CompositeWithTrivial3D) {
SetBodyInnerHTML(R"HTML(
<style>
#scroller {
@@ -1375,4 +1404,156 @@ TEST_P(PaintLayerScrollableAreaCompositingTest, CompositeWithTrivial3D) {
EXPECT_TRUE(UsesCompositedScrolling(GetLayoutObjectByElementId("scroller")));
}
+class PaintLayerScrollableAreaTestLowEndPlatform
+ : public TestingPlatformSupport {
+ public:
+ bool IsLowEndDevice() override { return true; }
+};
+
+// Test that a trivial 3D transform results in composited scrolling even on
+// low-end devices that may not composite trivial 3D transforms.
+TEST_P(PaintLayerScrollableAreaTest, LowEndCompositeWithTrivial3D) {
+ ScopedTestingPlatformSupport<PaintLayerScrollableAreaTestLowEndPlatform>
+ platform;
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #scroller {
+ width: 100px;
+ height: 100px;
+ overflow: scroll;
+ transform: translateZ(0);
+ }
+ #scrolled {
+ width: 200px;
+ height: 200px;
+ }
+ </style>
+ <div id="scroller">
+ <div id="scrolled"></div>
+ </div>
+ )HTML");
+
+ EXPECT_TRUE(UsesCompositedScrolling(GetLayoutObjectByElementId("scroller")));
+}
+
+TEST_P(PaintLayerScrollableAreaTest, SetSnapContainerDataNeedsUpdate) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ .scroller {
+ overflow: scroll;
+ height: 200px;
+ width: 200px;
+ }
+ </style>
+ <div id='first_scroller' class='scroller'>
+ <div style='height: 2000px;'></div>
+ </div>
+ <div id='second_scroller' class='scroller'>
+ <div style='height: 2000px;'></div>
+ </div>
+ )HTML");
+
+ auto* first_scroller = GetLayoutObjectByElementId("first_scroller");
+ auto* first_scrollable_area =
+ ToLayoutBoxModelObject(first_scroller)->GetScrollableArea();
+
+ auto* second_scroller = GetLayoutObjectByElementId("second_scroller");
+ auto* second_scrollable_area =
+ ToLayoutBoxModelObject(second_scroller)->GetScrollableArea();
+
+ EXPECT_EQ(&first_scroller->GetDocument().GetSnapCoordinator(),
+ &second_scroller->GetDocument().GetSnapCoordinator());
+
+ auto& snap_coordinator = first_scroller->GetDocument().GetSnapCoordinator();
+ EXPECT_FALSE(snap_coordinator.AnySnapContainerDataNeedsUpdate());
+
+ // SnapCoordinator needs to update all its snap containers if one of them asks
+ // for an update.
+ first_scrollable_area->SetSnapContainerDataNeedsUpdate(true);
+ EXPECT_TRUE(snap_coordinator.AnySnapContainerDataNeedsUpdate());
+
+ // SnapCoordinator still needs to update all its snap containers even if one
+ // of them asks not to.
+ second_scrollable_area->SetSnapContainerDataNeedsUpdate(false);
+ EXPECT_TRUE(snap_coordinator.AnySnapContainerDataNeedsUpdate());
+
+ first_scrollable_area->SetSnapContainerDataNeedsUpdate(false);
+ EXPECT_TRUE(snap_coordinator.AnySnapContainerDataNeedsUpdate());
+
+ snap_coordinator.UpdateAllSnapContainerDataIfNeeded();
+ EXPECT_FALSE(snap_coordinator.AnySnapContainerDataNeedsUpdate());
+}
+
+class ScrollTimelineForTest : public ScrollTimeline {
+ public:
+ ScrollTimelineForTest(
+ Document* document,
+ Element* scroll_source,
+ CSSPrimitiveValue* start_scroll_offset =
+ CSSNumericLiteralValue::Create(10.0,
+ CSSPrimitiveValue::UnitType::kPixels),
+ CSSPrimitiveValue* end_scroll_offset =
+ CSSNumericLiteralValue::Create(90.0,
+ CSSPrimitiveValue::UnitType::kPixels))
+ : ScrollTimeline(document,
+ scroll_source,
+ ScrollTimeline::Vertical,
+ start_scroll_offset,
+ end_scroll_offset,
+ 100.0),
+ invalidated_(false) {}
+ void Invalidate() override {
+ ScrollTimeline::Invalidate();
+ invalidated_ = true;
+ }
+ bool Invalidated() const { return invalidated_; }
+ void ResetInvalidated() { invalidated_ = false; }
+ void Trace(Visitor* visitor) override { ScrollTimeline::Trace(visitor); }
+
+ private:
+ bool invalidated_;
+};
+
+// Verify that scrollable area changes invalidate scroll timeline.
+TEST_P(PaintLayerScrollableAreaTest, ScrollTimelineInvalidation) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #scroller { overflow: scroll; width: 100px; height: 100px; }
+ #spacer { height: 1000px; }
+ </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");
+ ScrollTimelineForTest* scroll_timeline =
+ MakeGarbageCollected<ScrollTimelineForTest>(&GetDocument(),
+ scroller_element);
+ scroll_timeline->ResetInvalidated();
+ // Verify that changing scroll offset invalidates scroll timeline.
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 30),
+ mojom::blink::ScrollType::kProgrammatic);
+ EXPECT_TRUE(scroll_timeline->Invalidated());
+ scroll_timeline->ResetInvalidated();
+
+ // Verify that changing scroller size invalidates scroll timeline.
+ scroller_element->setAttribute(html_names::kStyleAttr, "height:110px;");
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_TRUE(scroll_timeline->Invalidated());
+ scroll_timeline->ResetInvalidated();
+
+ // Verify that changing content area size invalidates scroll timeline.
+ Element* spacer_element = GetElementById("spacer");
+ spacer_element->setAttribute(html_names::kStyleAttr, "height:900px;");
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_TRUE(scroll_timeline->Invalidated());
+ scroll_timeline->ResetInvalidated();
+}
+
} // namespace blink
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 4e1c981916e..e660390d496 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
@@ -109,21 +109,47 @@ static bool ZIndexLessThan(const PaintLayer* first, const PaintLayer* second) {
second->GetLayoutObject().StyleRef().ZIndex();
}
-static void SetIfHigher(const PaintLayer*& first, const PaintLayer* second) {
+static bool SetIfHigher(const PaintLayer*& first, const PaintLayer* second) {
if (!second)
- return;
+ return false;
DCHECK_GE(second->GetLayoutObject().StyleRef().ZIndex(), 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))
+ if (!first || !ZIndexLessThan(second, first)) {
first = second;
+ return true;
+ }
+ return false;
}
-// For finding the proper z-order of reparented overlay scrollbars.
+// For finding the proper z-order of reparented overlay overflow controls.
struct PaintLayerStackingNode::HighestLayers {
- const PaintLayer* highest_absolute_position = nullptr;
- const PaintLayer* highest_fixed_position = nullptr;
- const PaintLayer* highest_in_flow_stacked = nullptr;
+ enum LayerType {
+ kAbsolutePosition,
+ kFixedPosition,
+ kInFlowStacked,
+ kLayerTypeCount
+ };
+ std::array<const PaintLayer*, kLayerTypeCount> highest_layers = {
+ nullptr, nullptr, nullptr};
+ Vector<LayerType, kLayerTypeCount> highest_layers_order;
+
+ void UpdateOrderForSubtreeHighestLayers(LayerType type,
+ const PaintLayer* layer) {
+ if (SetIfHigher(highest_layers[type], layer)) {
+ auto* new_end = std::remove(highest_layers_order.begin(),
+ highest_layers_order.end(), type);
+ if (new_end != highest_layers_order.end()) {
+ // |highest_layers_order| doesn't have duplicate elements, std::remove
+ // will find at most one element at a time. So we don't shrink it and
+ // just update the value of the |new_end|.
+ DCHECK(new_end + 1 == highest_layers_order.end());
+ *new_end = type;
+ } else {
+ highest_layers_order.push_back(type);
+ }
+ }
+ }
void Update(const PaintLayer& layer) {
const auto& style = layer.GetLayoutObject().StyleRef();
@@ -136,17 +162,18 @@ struct PaintLayerStackingNode::HighestLayers {
return;
if (style.GetPosition() == EPosition::kAbsolute)
- SetIfHigher(highest_absolute_position, &layer);
+ UpdateOrderForSubtreeHighestLayers(kAbsolutePosition, &layer);
else if (style.GetPosition() == EPosition::kFixed)
- SetIfHigher(highest_fixed_position, &layer);
+ UpdateOrderForSubtreeHighestLayers(kFixedPosition, &layer);
else
- SetIfHigher(highest_in_flow_stacked, &layer);
+ UpdateOrderForSubtreeHighestLayers(kInFlowStacked, &layer);
}
void Merge(HighestLayers& child) {
- SetIfHigher(highest_absolute_position, child.highest_absolute_position);
- SetIfHigher(highest_fixed_position, child.highest_fixed_position);
- SetIfHigher(highest_in_flow_stacked, child.highest_in_flow_stacked);
+ for (auto layer_type : child.highest_layers_order) {
+ UpdateOrderForSubtreeHighestLayers(layer_type,
+ child.highest_layers[layer_type]);
+ }
}
};
@@ -231,16 +258,18 @@ void PaintLayerStackingNode::CollectLayers(PaintLayer& paint_layer,
}
if (has_overlay_overflow_controls) {
- const PaintLayer* layer_to_paint_overlay_overflow_controls_after =
- subtree_highest_layers->highest_in_flow_stacked;
- if (object.CanContainFixedPositionObjects()) {
+ const PaintLayer* layer_to_paint_overlay_overflow_controls_after = nullptr;
+ for (auto layer_type : subtree_highest_layers->highest_layers_order) {
+ if (layer_type == HighestLayers::kFixedPosition &&
+ !object.CanContainFixedPositionObjects())
+ continue;
+ if (layer_type == HighestLayers::kAbsolutePosition &&
+ !object.CanContainAbsolutePositionObjects())
+ continue;
SetIfHigher(layer_to_paint_overlay_overflow_controls_after,
- subtree_highest_layers->highest_fixed_position);
- }
- if (object.CanContainAbsolutePositionObjects()) {
- SetIfHigher(layer_to_paint_overlay_overflow_controls_after,
- subtree_highest_layers->highest_absolute_position);
+ subtree_highest_layers->highest_layers[layer_type]);
}
+
if (layer_to_paint_overlay_overflow_controls_after) {
layer_to_overlay_overflow_controls_painting_after_
.insert(layer_to_paint_overlay_overflow_controls_after, PaintLayers())
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 247a10f525d..f0dc94a3304 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
@@ -206,9 +206,10 @@ TEST_P(PaintLayerTest, CompositedScrollingNoNeedsRepaint) {
EXPECT_EQ(kNotComposited, content_layer->GetCompositingState());
EXPECT_EQ(PhysicalOffset(), content_layer->LocationWithoutPositionOffset());
- scroll_layer->GetScrollableArea()->SetScrollOffset(ScrollOffset(1000, 1000),
- kProgrammaticScroll);
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ scroll_layer->GetScrollableArea()->SetScrollOffset(
+ ScrollOffset(1000, 1000), mojom::blink::ScrollType::kProgrammatic);
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_EQ(PhysicalOffset(0, 0),
content_layer->LocationWithoutPositionOffset());
EXPECT_EQ(
@@ -240,9 +241,10 @@ TEST_P(PaintLayerTest, NonCompositedScrollingNeedsRepaint) {
EXPECT_EQ(kNotComposited, scroll_layer->GetCompositingState());
EXPECT_EQ(PhysicalOffset(), content_layer->LocationWithoutPositionOffset());
- scroll_layer->GetScrollableArea()->SetScrollOffset(ScrollOffset(1000, 1000),
- kProgrammaticScroll);
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ scroll_layer->GetScrollableArea()->SetScrollOffset(
+ ScrollOffset(1000, 1000), mojom::blink::ScrollType::kProgrammatic);
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_EQ(PhysicalOffset(0, 0),
content_layer->LocationWithoutPositionOffset());
EXPECT_EQ(
@@ -972,7 +974,41 @@ TEST_P(ReorderOverlayOverflowControlsTest,
EXPECT_FALSE(LayersPaintingOverlayOverflowControlsAfter(child));
}
-TEST_P(PaintLayerTest, SubsequenceCachingStackingContexts) {
+TEST_P(ReorderOverlayOverflowControlsTest,
+ AdjustAccessingOrderForSubtreeHighestLayers) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ div {
+ width: 200px;
+ height: 200px;
+ }
+ div > div {
+ height: 300px;
+ }
+ #ancestor, #child_2 {
+ position: relative;
+ }
+ #child_1 {
+ position: absolute;
+ }
+ </style>
+ <div id='ancestor'>
+ <div id='child_1'></div>
+ <div id='child_2'>
+ <div id='descendant'></div>
+ </div>
+ </div>
+ )HTML");
+
+ InitOverflowStyle("ancestor");
+
+ auto* ancestor = GetPaintLayerByElementId("ancestor");
+ auto* child = GetPaintLayerByElementId("child_2");
+ EXPECT_TRUE(ancestor->NeedsReorderOverlayOverflowControls());
+ EXPECT_TRUE(LayersPaintingOverlayOverflowControlsAfter(child));
+}
+
+TEST_P(PaintLayerTest, SubsequenceCachingStackedLayers) {
SetBodyInnerHTML(R"HTML(
<div id='parent' style='position:relative'>
<div id='child1' style='position: relative'>
@@ -1242,8 +1278,8 @@ TEST_P(PaintLayerTest, PaintInvalidationOnNonCompositedScroll) {
content_layer->FirstFragment().VisualRect());
EXPECT_EQ(IntRect(0, 30, 50, 5), content->FirstFragment().VisualRect());
- scroller->GetScrollableArea()->SetScrollOffset(ScrollOffset(0, 20),
- kProgrammaticScroll);
+ scroller->GetScrollableArea()->SetScrollOffset(
+ ScrollOffset(0, 20), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(IntRect(0, 30, 50, 10),
content_layer->FirstFragment().VisualRect());
@@ -1271,8 +1307,8 @@ TEST_P(PaintLayerTest, PaintInvalidationOnCompositedScroll) {
content_layer->FirstFragment().VisualRect());
EXPECT_EQ(IntRect(0, 30, 50, 5), content->FirstFragment().VisualRect());
- scroller->GetScrollableArea()->SetScrollOffset(ScrollOffset(0, 20),
- kProgrammaticScroll);
+ scroller->GetScrollableArea()->SetScrollOffset(
+ ScrollOffset(0, 20), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(IntRect(0, 30, 50, 10),
content_layer->FirstFragment().VisualRect());
@@ -1602,8 +1638,8 @@ TEST_P(PaintLayerTest, FloatLayerUnderInlineLayerScrolled) {
PaintLayer* floating = GetPaintLayerByElementId("floating");
PaintLayer* span = GetPaintLayerByElementId("span");
PaintLayer* container = GetPaintLayerByElementId("container");
- container->GetScrollableArea()->SetScrollOffset(ScrollOffset(0, 400),
- kProgrammaticScroll);
+ container->GetScrollableArea()->SetScrollOffset(
+ ScrollOffset(0, 400), mojom::blink::ScrollType::kProgrammatic);
EXPECT_EQ(span, floating->Parent());
if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
@@ -1883,8 +1919,8 @@ TEST_P(PaintLayerTest, ColumnSpanLayerUnderExtraLayerScrolled) {
PaintLayer* spanner = GetPaintLayerByElementId("spanner");
PaintLayer* extra_layer = GetPaintLayerByElementId("extraLayer");
PaintLayer* columns = GetPaintLayerByElementId("columns");
- columns->GetScrollableArea()->SetScrollOffset(ScrollOffset(200, 0),
- kProgrammaticScroll);
+ columns->GetScrollableArea()->SetScrollOffset(
+ ScrollOffset(200, 0), mojom::blink::ScrollType::kProgrammatic);
EXPECT_EQ(extra_layer, spanner->Parent());
EXPECT_EQ(columns, spanner->ContainingLayer());
@@ -1952,7 +1988,8 @@ TEST_P(PaintLayerTest, NeedsRepaintOnSelfPaintingStatusChange) {
target_element->setAttribute(html_names::kStyleAttr,
"overflow: hidden; float: left");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
// TODO(yosin): Once multicol in LayoutNG, we should remove following
// assignments. This is because the layout tree maybe reattached. In LayoutNG
// phase 1, layout tree is reattached because multicol forces legacy layout.
@@ -1989,7 +2026,8 @@ TEST_P(PaintLayerTest, NeedsRepaintOnRemovingStackedLayer) {
body->setAttribute(html_names::kStyleAttr, "margin-top: 0");
target_element->setAttribute(html_names::kStyleAttr, "top: 0");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_FALSE(target_object->HasLayer());
EXPECT_TRUE(body_layer->SelfNeedsRepaint());
@@ -2087,8 +2125,8 @@ TEST_P(PaintLayerTest, SquashingOffsets) {
EXPECT_EQ(PhysicalOffset(), squashed->ComputeOffsetFromAncestor(
squashed->TransformAncestorOrRoot()));
- GetDocument().View()->LayoutViewport()->ScrollBy(ScrollOffset(0, 25),
- kUserScroll);
+ GetDocument().View()->LayoutViewport()->ScrollBy(
+ ScrollOffset(0, 25), mojom::blink::ScrollType::kUser);
UpdateAllLifecyclePhasesForTest();
PaintLayer::MapPointInPaintInvalidationContainerToBacking(
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_phase.h b/chromium/third_party/blink/renderer/core/paint/paint_phase.h
index 039da1239f3..579ecf8f9a3 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_phase.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_phase.h
@@ -93,7 +93,7 @@ enum class PaintPhase {
// The below are auxiliary phases which are used to paint special effects.
kOverlayOverflowControls,
- kSelection,
+ kSelectionDragImage,
kTextClip,
kMask,
@@ -128,7 +128,7 @@ enum GlobalPaintFlag {
// Used when painting selection as part of a drag-image. This
// flag disables a lot of the painting code and specifically
// triggers a PaintPhaseSelection.
- kGlobalPaintSelectionOnly = 1 << 0,
+ kGlobalPaintSelectionDragImageOnly = 1 << 0,
// Used when painting a drag-image or printing in order to
// ignore the hardware layers and paint the whole tree
// into the topmost layer.
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 6e0a4994f2e..6810fb3e4f7 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
@@ -20,7 +20,11 @@
#include "third_party/blink/renderer/core/layout/layout_inline.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_video.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_root.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_viewport_container.h"
@@ -135,13 +139,17 @@ void PaintPropertyTreeBuilder::SetupContextForFrame(
namespace {
class FragmentPaintPropertyTreeBuilder {
+ STACK_ALLOCATED();
+
public:
FragmentPaintPropertyTreeBuilder(
const LayoutObject& object,
+ NGPrePaintInfo* pre_paint_info,
PaintPropertyTreeBuilderContext& full_context,
PaintPropertyTreeBuilderFragmentContext& context,
FragmentData& fragment_data)
: object_(object),
+ pre_paint_info_(pre_paint_info),
full_context_(full_context),
context_(context),
fragment_data_(fragment_data),
@@ -187,7 +195,7 @@ class FragmentPaintPropertyTreeBuilder {
ALWAYS_INLINE void UpdateClipPathCache();
ALWAYS_INLINE void UpdateStickyTranslation();
ALWAYS_INLINE void UpdateTransform();
- ALWAYS_INLINE void UpdateTransformForNonRootSVG();
+ ALWAYS_INLINE void UpdateTransformForSVGChild();
ALWAYS_INLINE bool EffectCanUseCurrentClipAsOutputClip() const;
ALWAYS_INLINE void UpdateEffect();
ALWAYS_INLINE void UpdateFilter();
@@ -213,6 +221,8 @@ class FragmentPaintPropertyTreeBuilder {
full_context_.force_subtree_update_reasons;
}
+ bool IsInNGFragmentTraversal() const { return pre_paint_info_; }
+
void OnUpdate(PaintPropertyChangeType change) {
property_changed_ = std::max(property_changed_, change);
}
@@ -251,6 +261,7 @@ class FragmentPaintPropertyTreeBuilder {
}
const LayoutObject& object_;
+ NGPrePaintInfo* pre_paint_info_;
// The tree builder context for the whole object.
PaintPropertyTreeBuilderContext& full_context_;
// The tree builder context for the current fragment, which is one of the
@@ -262,17 +273,6 @@ class FragmentPaintPropertyTreeBuilder {
PaintPropertyChangeType::kUnchanged;
};
-static bool NeedsScrollNode(const LayoutObject& object,
- CompositingReasons direct_compositing_reasons) {
- if (!object.HasOverflowClip())
- return false;
-
- if (direct_compositing_reasons & CompositingReason::kRootScroller)
- return true;
-
- return ToLayoutBox(object).GetScrollableArea()->ScrollsOverflow();
-}
-
// True if a scroll translation is needed for static scroll offset (e.g.,
// overflow hidden with scroll), or if a scroll node is needed for composited
// scrolling.
@@ -288,7 +288,7 @@ static bool NeedsScrollOrScrollTranslation(
ScrollOffset scroll_offset = box.GetScrollableArea()->GetScrollOffset();
return !scroll_offset.IsZero() ||
- NeedsScrollNode(object, direct_compositing_reasons);
+ box.NeedsScrollNode(direct_compositing_reasons);
}
static bool NeedsReplacedContentTransform(const LayoutObject& object) {
@@ -350,7 +350,7 @@ static bool NeedsIsolationNodes(const LayoutObject& object) {
// Layout view establishes isolation with the exception of local roots (since
// they are already essentially isolated).
- if (object.IsLayoutView()) {
+ if (IsA<LayoutView>(object)) {
const auto* parent_frame = object.GetFrame()->Tree().Parent();
return IsA<LocalFrame>(parent_frame);
}
@@ -382,7 +382,7 @@ static bool NeedsPaintOffsetTranslation(
const LayoutBoxModelObject& box_model = ToLayoutBoxModelObject(object);
- if (box_model.IsLayoutView()) {
+ if (IsA<LayoutView>(box_model)) {
// A translation node for LayoutView is always created to ensure fixed and
// absolute contexts use the correct transform space.
return true;
@@ -421,6 +421,12 @@ static bool NeedsPaintOffsetTranslation(
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
if (direct_compositing_reasons != CompositingReason::kNone)
return true;
+ // In CompositeAfterPaint though we don't treat hidden backface as
+ // a direct compositing reason, it's very likely that the object will
+ // be composited, so a paint offset translation will be beneficial.
+ if (box_model.StyleRef().BackfaceVisibility() ==
+ EBackfaceVisibility::kHidden)
+ return true;
} else if (box_model.GetCompositingState() == kPaintsIntoOwnBacking) {
return true;
}
@@ -481,7 +487,7 @@ bool FragmentPaintPropertyTreeBuilder::IsAffectedByOuterViewportBoundsDelta()
// It's affected by viewport only if the container is the LayoutView.
DCHECK_EQ(full_context_.container_for_fixed_position, object_.Container());
- return full_context_.container_for_fixed_position->IsLayoutView();
+ return IsA<LayoutView>(full_context_.container_for_fixed_position);
}
void FragmentPaintPropertyTreeBuilder::UpdatePaintOffsetTranslation(
@@ -502,12 +508,12 @@ void FragmentPaintPropertyTreeBuilder::UpdatePaintOffsetTranslation(
IsAffectedByOuterViewportBoundsDelta();
state.direct_compositing_reasons =
full_context_.direct_compositing_reasons &
- CompositingReason::kScrollDependentPosition;
+ CompositingReason::kDirectReasonsForPaintOffsetTranslationProperty;
state.rendering_context_id = context_.current.rendering_context_id;
OnUpdate(properties_->UpdatePaintOffsetTranslation(
*context_.current.transform, std::move(state)));
context_.current.transform = properties_->PaintOffsetTranslation();
- if (object_.IsLayoutView()) {
+ if (IsA<LayoutView>(object_)) {
context_.absolute_position.transform =
properties_->PaintOffsetTranslation();
context_.fixed_position.transform = properties_->PaintOffsetTranslation();
@@ -548,8 +554,20 @@ void FragmentPaintPropertyTreeBuilder::UpdateStickyTranslation() {
// DCHECK_EQ(scroller_properties->Scroll(), context_.current.scroll);
// However there is a bug that AncestorOverflowLayer() may be computed
// incorrectly with clip escaping involved.
- if (scroller_properties &&
- scroller_properties->Scroll() == context_.current.scroll) {
+ bool nearest_scroller_is_clip =
+ scroller_properties &&
+ scroller_properties->Scroll() == context_.current.scroll;
+
+ // Additionally, we also want to make sure that the nearest scroller
+ // actually translates this node. If it doesn't (e.g. a position fixed
+ // node in a scrolling document), there's no point in adding a constraint
+ // since scrolling won't affect it. Indeed, if we do add it, the
+ // compositor assumes scrolling does affect it and produces incorrect
+ // results.
+ bool translates_with_nearest_scroller =
+ context_.current.transform->NearestScrollTranslationNode()
+ .ScrollNode() == context_.current.scroll;
+ if (nearest_scroller_is_clip && translates_with_nearest_scroller) {
const StickyPositionScrollingConstraints& layout_constraint =
layer->AncestorOverflowLayer()
->GetScrollableArea()
@@ -560,19 +578,17 @@ void FragmentPaintPropertyTreeBuilder::UpdateStickyTranslation() {
constraint->is_anchored_right = layout_constraint.is_anchored_right;
constraint->is_anchored_top = layout_constraint.is_anchored_top;
constraint->is_anchored_bottom = layout_constraint.is_anchored_bottom;
+
constraint->left_offset = layout_constraint.left_offset.ToFloat();
constraint->right_offset = layout_constraint.right_offset.ToFloat();
constraint->top_offset = layout_constraint.top_offset.ToFloat();
constraint->bottom_offset = layout_constraint.bottom_offset.ToFloat();
constraint->constraint_box_rect =
- PixelSnappedIntRect(box_model.ComputeStickyConstrainingRect());
- constraint->scroll_container_relative_sticky_box_rect =
- PixelSnappedIntRect(
- layout_constraint.scroll_container_relative_sticky_box_rect);
- constraint->scroll_container_relative_containing_block_rect =
- PixelSnappedIntRect(
- layout_constraint
- .scroll_container_relative_containing_block_rect);
+ FloatRect(box_model.ComputeStickyConstrainingRect());
+ constraint->scroll_container_relative_sticky_box_rect = FloatRect(
+ layout_constraint.scroll_container_relative_sticky_box_rect);
+ constraint->scroll_container_relative_containing_block_rect = FloatRect(
+ layout_constraint.scroll_container_relative_containing_block_rect);
if (PaintLayer* sticky_box_shifting_ancestor =
layout_constraint.nearest_sticky_layer_shifting_sticky_box) {
constraint->nearest_element_shifting_sticky_box =
@@ -603,18 +619,29 @@ void FragmentPaintPropertyTreeBuilder::UpdateStickyTranslation() {
context_.current.transform = properties_->StickyTranslation();
}
-static bool NeedsTransformForNonRootSVG(const LayoutObject& object) {
+static bool NeedsTransformForSVGChild(const LayoutObject& object) {
// TODO(pdr): Check for the presence of a transform instead of the value.
// Checking for an identity matrix will cause the property tree structure
// to change during animations if the animation passes through the
// identity matrix.
+ // TODO(crbug.com/666244): Check CompositingReasonsForAnimation here when we
+ // support composited transform animations in SVG.
return object.IsSVGChild() && !object.IsText() &&
!object.LocalToSVGParentTransform().IsIdentity();
}
+static void SetTransformNodeStateFromAffineTransform(
+ TransformPaintPropertyNode::State& state,
+ const AffineTransform& transform) {
+ if (transform.IsIdentityOrTranslation())
+ state.transform_and_origin = {FloatSize(transform.E(), transform.F())};
+ else
+ state.transform_and_origin = {TransformationMatrix(transform)};
+}
+
// SVG does not use the general transform update of |UpdateTransform|, instead
// creating a transform node for SVG-specific transforms without 3D.
-void FragmentPaintPropertyTreeBuilder::UpdateTransformForNonRootSVG() {
+void FragmentPaintPropertyTreeBuilder::UpdateTransformForSVGChild() {
DCHECK(properties_);
DCHECK(object_.IsSVGChild());
// SVG does not use paint offset internally, except for SVGForeignObject which
@@ -624,9 +651,12 @@ void FragmentPaintPropertyTreeBuilder::UpdateTransformForNonRootSVG() {
if (NeedsPaintPropertyUpdate()) {
AffineTransform transform = object_.LocalToSVGParentTransform();
- if (NeedsTransformForNonRootSVG(object_)) {
+ if (NeedsTransformForSVGChild(object_)) {
// The origin is included in the local transform, so leave origin empty.
- TransformPaintPropertyNode::State state{TransformationMatrix(transform)};
+ // TODO(crbug.com/666244): Support composited transform animation for SVG
+ // using similar code as |UpdateTransform| for animations.
+ TransformPaintPropertyNode::State state;
+ SetTransformNodeStateFromAffineTransform(state, transform);
OnUpdate(properties_->UpdateTransform(*context_.current.transform,
std::move(state)));
} else {
@@ -666,8 +696,7 @@ static CompositingReasons CompositingReasonsForTransformProperty() {
// will-change:opacity to avoid raster invalidation (caused by otherwise a
// created/deleted effect node) when we start/stop an opacity animation.
// https://crbug.com/942681
- if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
- reasons |= CompositingReason::kWillChangeOpacity;
+ reasons |= CompositingReason::kWillChangeOpacity;
return reasons;
}
@@ -707,7 +736,7 @@ static bool ActiveTransformAnimationIsAxisAligned(
void FragmentPaintPropertyTreeBuilder::UpdateTransform() {
if (object_.IsSVGChild()) {
- UpdateTransformForNonRootSVG();
+ UpdateTransformForSVGChild();
return;
}
@@ -738,10 +767,12 @@ void FragmentPaintPropertyTreeBuilder::UpdateTransform() {
bool disable_2d_translation_optimization =
full_context_.direct_compositing_reasons &
CompositingReason::kActiveTransformAnimation;
- state.transform_and_origin =
- TransformPaintPropertyNode::TransformAndOrigin(
- matrix, TransformOrigin(box),
- disable_2d_translation_optimization);
+ if (!disable_2d_translation_optimization &&
+ matrix.IsIdentityOr2DTranslation()) {
+ state.transform_and_origin = {matrix.To2DTranslation()};
+ } else {
+ state.transform_and_origin = {matrix, TransformOrigin(box)};
+ }
// TODO(trchen): transform-style should only be respected if a
// PaintLayer is created. If a node with transform-style: preserve-3d
@@ -778,9 +809,7 @@ void FragmentPaintPropertyTreeBuilder::UpdateTransform() {
style.IsRunningTransformAnimationOnCompositor();
auto effective_change_type = properties_->UpdateTransform(
*context_.current.transform, std::move(state), animation_state);
- // TODO(crbug.com/953322): We need to fix this to work with CAP as well.
- if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
- effective_change_type ==
+ if (effective_change_type ==
PaintPropertyChangeType::kChangedOnlySimpleValues &&
properties_->Transform()->HasDirectCompositingReasons()) {
if (auto* paint_artifact_compositor =
@@ -826,8 +855,9 @@ static bool NeedsClipPathClip(const LayoutObject& object) {
return false;
}
-// TODO(crbug.com/900241): Remove this function and let the caller use
-// CompositingReason::kDirectReasonForEffectProperty directly.
+// TODO(crbug.com/900241): When this bug is fixed, we should let NeedsEffect()
+// use CompositingReason::kDirectReasonForEffectProperty directly instead of
+// calling this function. We should still call this function in UpdateEffect().
static CompositingReasons CompositingReasonsForEffectProperty() {
CompositingReasons reasons =
CompositingReason::kDirectReasonsForEffectProperty;
@@ -839,8 +869,9 @@ static CompositingReasons CompositingReasonsForEffectProperty() {
// will-change:transform to avoid raster invalidation (caused by otherwise a
// created/deleted effect node) when we start/stop a transform animation.
// https://crbug.com/942681
- if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
- reasons |= CompositingReason::kWillChangeTransform;
+ // In CompositeAfterPaint, this also avoids decomposition of the effect when
+ // the object is forced compositing with will-change:transform.
+ reasons |= CompositingReason::kWillChangeTransform;
return reasons;
}
@@ -1005,8 +1036,8 @@ void FragmentPaintPropertyTreeBuilder::UpdateEffect() {
OnUpdateClip(properties_->UpdateMaskClip(
*context_.current.clip,
- ClipPaintPropertyNode::State{context_.current.transform,
- FloatRoundedRect(combined_clip)}));
+ ClipPaintPropertyNode::State(context_.current.transform,
+ FloatRoundedRect(combined_clip))));
output_clip = properties_->MaskClip();
} else {
OnClearClip(properties_->ClearMaskClip());
@@ -1079,9 +1110,7 @@ void FragmentPaintPropertyTreeBuilder::UpdateEffect() {
// If we have simple value change, which means opacity, we should try to
// directly update it on the PaintArtifactCompositor in order to avoid
// doing a full rebuild.
- // TODO(crbug.com/953322): We need to fix this to work with CAP as well.
- if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
- effective_change_type ==
+ if (effective_change_type ==
PaintPropertyChangeType::kChangedOnlySimpleValues &&
properties_->Effect()->HasDirectCompositingReasons()) {
if (auto* paint_artifact_compositor =
@@ -1150,8 +1179,9 @@ static bool NeedsLinkHighlightEffect(const LayoutObject& object) {
return page->GetLinkHighlight().NeedsHighlightEffect(object);
}
-// TODO(crbug.com/900241): Remove this function and let the caller use
-// CompositingReason::kDirectReasonForFilterProperty directly.
+// TODO(crbug.com/900241): When this bug is fixed, we should let NeedsFilter()
+// use CompositingReason::kDirectReasonForFilterProperty directly instead of
+// calling this function. We should still call this function in UpdateFilter().
static CompositingReasons CompositingReasonsForFilterProperty() {
CompositingReasons reasons =
CompositingReason::kDirectReasonsForFilterProperty;
@@ -1163,10 +1193,10 @@ static CompositingReasons CompositingReasonsForFilterProperty() {
// created for will-change:transform/opacity to avoid raster invalidation
// (caused by otherwise a created/deleted filter node) when we start/stop a
// transform/opacity animation. https://crbug.com/942681
- if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
- reasons |= CompositingReason::kWillChangeTransform |
- CompositingReason::kWillChangeOpacity;
- }
+ // In CompositeAfterPaint, this also avoids decomposition of the filter when
+ // the object is forced compositing with will-change:transform/opacity.
+ reasons |= CompositingReason::kWillChangeTransform |
+ CompositingReason::kWillChangeOpacity;
return reasons;
}
@@ -1220,7 +1250,9 @@ void FragmentPaintPropertyTreeBuilder::UpdateFilter() {
// On the other hand, "B" should not be clipped because the overflow clip
// is not in its containing block chain, but as the filter output will be
// clipped, so a blurred "B" may still be invisible.
- if (!state.filter.IsEmpty())
+ if (!state.filter.IsEmpty() ||
+ (full_context_.direct_compositing_reasons &
+ CompositingReason::kActiveFilterAnimation))
state.output_clip = context_.current.clip;
// TODO(trchen): A filter may contain spatial operations such that an
@@ -1271,10 +1303,12 @@ void FragmentPaintPropertyTreeBuilder::UpdateFragmentClip() {
if (NeedsPaintPropertyUpdate()) {
if (context_.fragment_clip) {
- const auto& clip_rect = ToSnappedClipRect(*context_.fragment_clip);
+ const auto& clip_rect = *context_.fragment_clip;
OnUpdateClip(properties_->UpdateFragmentClip(
*context_.current.clip,
- ClipPaintPropertyNode::State{context_.current.transform, clip_rect}));
+ ClipPaintPropertyNode::State(context_.current.transform,
+ FloatRoundedRect(FloatRect(clip_rect)),
+ ToSnappedClipRect(clip_rect))));
} else {
OnClearClip(properties_->ClearFragmentClip());
}
@@ -1302,11 +1336,13 @@ void FragmentPaintPropertyTreeBuilder::UpdateCssClip() {
// object must be a container for absolute position descendants, and will
// copy from in-flow context later at updateOutOfFlowContext() step.
DCHECK(object_.CanContainAbsolutePositionObjects());
- const auto& clip_rect = ToSnappedClipRect(
- ToLayoutBox(object_).ClipRect(context_.current.paint_offset));
+ const auto& clip_rect =
+ ToLayoutBox(object_).ClipRect(context_.current.paint_offset);
OnUpdateClip(properties_->UpdateCssClip(
*context_.current.clip,
- ClipPaintPropertyNode::State{context_.current.transform, clip_rect}));
+ ClipPaintPropertyNode::State(context_.current.transform,
+ FloatRoundedRect(FloatRect(clip_rect)),
+ ToSnappedClipRect(clip_rect))));
} else {
OnClearClip(properties_->ClearCssClip());
}
@@ -1331,9 +1367,9 @@ void FragmentPaintPropertyTreeBuilder::UpdateClipPathClip(
if (!NeedsClipPathClip(object_)) {
OnClearClip(properties_->ClearClipPathClip());
} else {
- ClipPaintPropertyNode::State state;
- state.local_transform_space = context_.current.transform;
- state.clip_rect = FloatRoundedRect(*fragment_data_.ClipPathBoundingBox());
+ ClipPaintPropertyNode::State state(
+ context_.current.transform,
+ FloatRoundedRect(*fragment_data_.ClipPathBoundingBox()));
state.clip_path = fragment_data_.ClipPathPath();
OnUpdateClip(properties_->UpdateClipPathClip(*context_.current.clip,
std::move(state)));
@@ -1351,7 +1387,7 @@ void FragmentPaintPropertyTreeBuilder::UpdateClipPathClip(
// issue artificial page clip for each page, and always print from the origin
// of the contents for which no scroll offset should be applied.
static bool IsPrintingRootLayoutView(const LayoutObject& object) {
- if (!object.IsLayoutView())
+ if (!IsA<LayoutView>(object))
return false;
const auto& frame = *object.GetFrame();
@@ -1441,9 +1477,8 @@ bool FragmentPaintPropertyTreeBuilder::NeedsOverflowControlsClip() const {
scroll_controls_bounds.Unite(scrollbar->FrameRect());
if (const auto* scrollbar = scrollable_area->VerticalScrollbar())
scroll_controls_bounds.Unite(scrollbar->FrameRect());
- auto pixel_snapped_border_box_rect =
- box.PixelSnappedBorderBoxRect(context_.current.paint_offset);
- pixel_snapped_border_box_rect.SetLocation(IntPoint());
+ IntRect pixel_snapped_border_box_rect(
+ IntPoint(), box.PixelSnappedBorderBoxSize(context_.current.paint_offset));
return !pixel_snapped_border_box_rect.Contains(scroll_controls_bounds);
}
@@ -1491,11 +1526,13 @@ void FragmentPaintPropertyTreeBuilder::UpdateOverflowControlsClip() {
if (NeedsOverflowControlsClip()) {
// Clip overflow controls to the border box rect. Not wrapped with
// OnUpdateClip() because this clip doesn't affect descendants.
- const auto& clip_rect = ToSnappedClipRect(PhysicalRect(
- context_.current.paint_offset, ToLayoutBox(object_).Size()));
+ const auto& clip_rect = PhysicalRect(context_.current.paint_offset,
+ ToLayoutBox(object_).Size());
properties_->UpdateOverflowControlsClip(
*context_.current.clip,
- ClipPaintPropertyNode::State{context_.current.transform, clip_rect});
+ ClipPaintPropertyNode::State(context_.current.transform,
+ FloatRoundedRect(FloatRect(clip_rect)),
+ ToSnappedClipRect(clip_rect)));
} else {
properties_->ClearOverflowControlsClip();
}
@@ -1512,10 +1549,12 @@ void FragmentPaintPropertyTreeBuilder::UpdateInnerBorderRadiusClip() {
if (NeedsPaintPropertyUpdate()) {
if (NeedsInnerBorderRadiusClip(object_)) {
const LayoutBox& box = ToLayoutBox(object_);
- ClipPaintPropertyNode::State state;
- state.local_transform_space = context_.current.transform;
- state.clip_rect = box.StyleRef().GetRoundedInnerBorderFor(LayoutRect(
- context_.current.paint_offset.ToLayoutPoint(), box.Size()));
+ LayoutRect box_rect(context_.current.paint_offset.ToLayoutPoint(),
+ box.Size());
+ ClipPaintPropertyNode::State state(
+ context_.current.transform,
+ box.StyleRef().GetInnerBorderFor(box_rect),
+ box.StyleRef().GetRoundedInnerBorderFor(box_rect));
OnUpdateClip(properties_->UpdateInnerBorderRadiusClip(
*context_.current.clip, std::move(state)));
} else {
@@ -1534,15 +1573,16 @@ static PhysicalRect OverflowClipRect(const LayoutBox& box,
// here instead of LayoutBox::OverflowClipRect because the layout size of the
// scrolling content is still affected by overlay scrollbar behavior, just not
// the clip.
- auto behavior = box.IsLayoutView() ? kIgnorePlatformAndCSSOverlayScrollbarSize
- : kIgnorePlatformOverlayScrollbarSize;
+ auto behavior = IsA<LayoutView>(box)
+ ? kIgnorePlatformAndCSSOverlayScrollbarSize
+ : kIgnorePlatformOverlayScrollbarSize;
return box.OverflowClipRect(offset, behavior);
}
static bool CanOmitOverflowClip(const LayoutObject& object) {
DCHECK(NeedsOverflowClip(object));
- if (object.IsLayoutView() && !object.GetFrame()->ClipsContent()) {
+ if (IsA<LayoutView>(object) && !object.GetFrame()->ClipsContent()) {
return true;
}
@@ -1589,8 +1629,8 @@ void FragmentPaintPropertyTreeBuilder::UpdateOverflowClip() {
if (NeedsPaintPropertyUpdate()) {
if (NeedsOverflowClip(object_) && !CanOmitOverflowClip(object_)) {
- ClipPaintPropertyNode::State state;
- state.local_transform_space = context_.current.transform;
+ ClipPaintPropertyNode::State state(context_.current.transform,
+ FloatRoundedRect());
if (object_.IsLayoutReplaced()) {
const LayoutReplaced& replaced = ToLayoutReplaced(object_);
@@ -1600,39 +1640,46 @@ void FragmentPaintPropertyTreeBuilder::UpdateOverflowClip() {
// here, before applying padding and corner rounding.
PhysicalRect content_rect(context_.current.paint_offset,
replaced.Size());
- if (replaced.IsVideo()) {
+ if (IsA<LayoutVideo>(replaced)) {
content_rect =
LayoutReplaced::PreSnappedRectForPersistentSizing(content_rect);
}
// LayoutReplaced clips the foreground by rounded content box.
- state.clip_rect = replaced.StyleRef().GetRoundedInnerBorderFor(
+ auto clip_rect = replaced.StyleRef().GetRoundedInnerBorderFor(
content_rect.ToLayoutRect(),
LayoutRectOutsets(
-(replaced.PaddingTop() + replaced.BorderTop()),
-(replaced.PaddingRight() + replaced.BorderRight()),
-(replaced.PaddingBottom() + replaced.BorderBottom()),
-(replaced.PaddingLeft() + replaced.BorderLeft())));
+ state.SetClipRect(clip_rect, clip_rect);
if (replaced.IsLayoutEmbeddedContent()) {
// Embedded objects are always sized to fit the content rect, but they
// could overflow by 1px due to pre-snapping. Adjust clip rect to
// match pre-snapped box as a special case.
- FloatRect adjusted_rect = state.clip_rect.Rect();
+ FloatRect adjusted_rect = clip_rect.Rect();
adjusted_rect.SetSize(FloatSize(replaced.ReplacedContentRect().size));
- state.clip_rect.SetRect(adjusted_rect);
+ FloatRoundedRect adjusted_clip_rect(adjusted_rect,
+ clip_rect.GetRadii());
+ state.SetClipRect(adjusted_clip_rect, adjusted_clip_rect);
}
} else if (object_.IsBox()) {
- state.clip_rect = ToSnappedClipRect(OverflowClipRect(
- ToLayoutBox(object_), context_.current.paint_offset));
- state.clip_rect_excluding_overlay_scrollbars = FloatClipRect(
- FloatRect(PixelSnappedIntRect(ToLayoutBox(object_).OverflowClipRect(
+ const auto& clip_rect = OverflowClipRect(ToLayoutBox(object_),
+ context_.current.paint_offset);
+ state.SetClipRect(FloatRoundedRect(FloatRect(clip_rect)),
+ ToSnappedClipRect(clip_rect));
+
+ state.clip_rect_excluding_overlay_scrollbars =
+ FloatClipRect(FloatRect(ToLayoutBox(object_).OverflowClipRect(
context_.current.paint_offset,
- kExcludeOverlayScrollbarSizeForHitTesting))));
+ kExcludeOverlayScrollbarSizeForHitTesting)));
} else {
DCHECK(object_.IsSVGViewportContainer());
const auto& viewport_container = ToLayoutSVGViewportContainer(object_);
- state.clip_rect = FloatRoundedRect(
+ const auto clip_rect = FloatRoundedRect(
viewport_container.LocalToSVGParentTransform().Inverse().MapRect(
viewport_container.Viewport()));
+ state.SetClipRect(clip_rect, clip_rect);
}
OnUpdateClip(properties_->UpdateOverflowClip(*context_.current.clip,
std::move(state)));
@@ -1687,14 +1734,6 @@ void FragmentPaintPropertyTreeBuilder::UpdatePerspective() {
}
}
-static bool ImageWasTransposed(const LayoutImage& layout_image,
- const Image& image) {
- return LayoutObject::ShouldRespectImageOrientation(&layout_image) ==
- kRespectImageOrientation &&
- image.IsBitmapImage() &&
- ToBitmapImage(image).CurrentFrameOrientation().UsesWidthAsHeight();
-}
-
static AffineTransform RectToRect(const FloatRect& src_rect,
const FloatRect& dst_rect) {
float x_scale = dst_rect.Width() / src_rect.Width();
@@ -1723,9 +1762,9 @@ void FragmentPaintPropertyTreeBuilder::UpdateReplacedContentTransform() {
scoped_refptr<Image> image =
layout_image.ImageResource()->GetImage(replaced_rect.Size());
if (image && !image->IsNull()) {
- IntRect src_rect = image->Rect();
- if (ImageWasTransposed(layout_image, *image))
- src_rect = src_rect.TransposedRect();
+ IntRect src_rect(
+ IntPoint(), image->Size(LayoutObject::ShouldRespectImageOrientation(
+ &layout_image)));
content_to_parent_space =
RectToRect(FloatRect(src_rect), FloatRect(replaced_rect));
}
@@ -1733,8 +1772,8 @@ void FragmentPaintPropertyTreeBuilder::UpdateReplacedContentTransform() {
NOTREACHED();
}
if (!content_to_parent_space.IsIdentity()) {
- TransformPaintPropertyNode::State state{
- TransformationMatrix(content_to_parent_space)};
+ TransformPaintPropertyNode::State state;
+ SetTransformNodeStateFromAffineTransform(state, content_to_parent_space);
state.flags.flattens_inherited_transform =
context_.current.should_flatten_inherited_transform;
OnUpdate(properties_->UpdateReplacedContentTransform(
@@ -1769,7 +1808,7 @@ static MainThreadScrollingReasons GetMainThreadScrollingReasons(
if (!object.IsBox())
return reasons;
- if (object.IsLayoutView()) {
+ if (IsA<LayoutView>(object)) {
if (object.GetFrameView()
->RequiresMainThreadScrollingForBackgroundAttachmentFixed()) {
reasons |=
@@ -1819,7 +1858,8 @@ void FragmentPaintPropertyTreeBuilder::UpdateScrollAndScrollTranslation() {
DCHECK(properties_);
if (NeedsPaintPropertyUpdate()) {
- if (NeedsScrollNode(object_, full_context_.direct_compositing_reasons)) {
+ if (object_.IsBox() && ToLayoutBox(object_).NeedsScrollNode(
+ full_context_.direct_compositing_reasons)) {
const LayoutBox& box = ToLayoutBox(object_);
PaintLayerScrollableArea* scrollable_area = box.GetScrollableArea();
ScrollPaintPropertyNode::State state;
@@ -1837,8 +1877,6 @@ void FragmentPaintPropertyTreeBuilder::UpdateScrollAndScrollTranslation() {
state.user_scrollable_vertical =
scrollable_area->UserInputScrollable(kVerticalScrollbar);
- state.scrolls_outer_viewport = box.IsGlobalRootScroller();
-
// TODO(bokan): We probably don't need to pass ancestor reasons down the
// scroll tree. On the compositor, in
// LayerTreeHostImpl::FindScrollNodeForDeviceViewportPoint, we walk up
@@ -1981,7 +2019,7 @@ void FragmentPaintPropertyTreeBuilder::UpdateOutOfFlowContext() {
if (object_.CanContainAbsolutePositionObjects())
context_.absolute_position = context_.current;
- if (object_.IsLayoutView()) {
+ if (IsA<LayoutView>(object_)) {
const auto* initial_fixed_transform = context_.fixed_position.transform;
context_.fixed_position = context_.current;
@@ -2020,8 +2058,8 @@ void FragmentPaintPropertyTreeBuilder::UpdateOutOfFlowContext() {
if (NeedsPaintPropertyUpdate()) {
OnUpdate(properties_->UpdateCssClipFixedPosition(
*context_.fixed_position.clip,
- ClipPaintPropertyNode::State{&css_clip->LocalTransformSpace(),
- css_clip->ClipRect()}));
+ ClipPaintPropertyNode::State(&css_clip->LocalTransformSpace(),
+ css_clip->PixelSnappedClipRect())));
}
if (properties_->CssClipFixedPosition())
context_.fixed_position.clip = properties_->CssClipFixedPosition();
@@ -2202,48 +2240,104 @@ static PhysicalOffset PaintOffsetInPaginationContainer(
}
void FragmentPaintPropertyTreeBuilder::UpdatePaintOffset() {
- // Paint offsets for fragmented content are computed from scratch.
- const auto* enclosing_pagination_layer =
- full_context_.painting_layer->EnclosingPaginationLayer();
- if (enclosing_pagination_layer &&
- // Except if the paint_offset_root is below the pagination container,
- // in which case fragmentation offsets are already baked into the paint
- // offset transform for paint_offset_root.
- !context_.current.paint_offset_root->PaintingLayer()
- ->EnclosingPaginationLayer()) {
- // Set fragment visual paint offset.
- PhysicalOffset paint_offset =
- PaintOffsetInPaginationContainer(object_, *enclosing_pagination_layer);
-
- paint_offset += fragment_data_.PaginationOffset();
- paint_offset += context_.repeating_paint_offset_adjustment;
- paint_offset +=
- VisualOffsetFromPaintOffsetRoot(context_, enclosing_pagination_layer);
-
- // The paint offset root can have a subpixel paint offset adjustment.
- // The paint offset root always has one fragment.
- const auto& paint_offset_root_fragment =
- context_.current.paint_offset_root->FirstFragment();
- paint_offset += paint_offset_root_fragment.PaintOffset();
-
- context_.current.paint_offset = paint_offset;
- return;
- }
+ if (!IsInNGFragmentTraversal()) {
+ // Paint offsets for fragmented content are computed from scratch.
+ const auto* enclosing_pagination_layer =
+ full_context_.painting_layer->EnclosingPaginationLayer();
+ if (enclosing_pagination_layer &&
+ // Except if the paint_offset_root is below the pagination container, in
+ // which case fragmentation offsets are already baked into the paint
+ // offset transform for paint_offset_root.
+ !context_.current.paint_offset_root->PaintingLayer()
+ ->EnclosingPaginationLayer()) {
+ // Set fragment visual paint offset.
+ PhysicalOffset paint_offset = PaintOffsetInPaginationContainer(
+ object_, *enclosing_pagination_layer);
+
+ paint_offset += fragment_data_.LegacyPaginationOffset();
+ paint_offset += context_.repeating_paint_offset_adjustment;
+ paint_offset +=
+ VisualOffsetFromPaintOffsetRoot(context_, enclosing_pagination_layer);
+
+ // The paint offset root can have a subpixel paint offset adjustment.
+ // The paint offset root always has one fragment.
+ const auto& paint_offset_root_fragment =
+ context_.current.paint_offset_root->FirstFragment();
+ paint_offset += paint_offset_root_fragment.PaintOffset();
+
+ context_.current.paint_offset = paint_offset;
+ return;
+ }
- if (object_.IsFloating() && !object_.IsInLayoutNGInlineFormattingContext())
- context_.current.paint_offset = context_.paint_offset_for_float;
+ if (object_.IsFloating() && !object_.IsInLayoutNGInlineFormattingContext())
+ context_.current.paint_offset = context_.paint_offset_for_float;
- // Multicolumn spanners are painted starting at the multicolumn container (but
- // still inherit properties in layout-tree order) so reset the paint offset.
- if (object_.IsColumnSpanAll()) {
- context_.current.paint_offset =
- object_.Container()->FirstFragment().PaintOffset();
+ // Multicolumn spanners are painted starting at the multicolumn container
+ // (but still inherit properties in layout-tree order) so reset the paint
+ // offset.
+ if (object_.IsColumnSpanAll()) {
+ context_.current.paint_offset =
+ object_.Container()->FirstFragment().PaintOffset();
+ }
}
if (object_.IsBoxModelObject()) {
const LayoutBoxModelObject& box_model_object =
ToLayoutBoxModelObject(object_);
- switch (box_model_object.StyleRef().GetPosition()) {
+ EPosition position = box_model_object.StyleRef().GetPosition();
+ if (IsInNGFragmentTraversal() &&
+ (position == EPosition::kAbsolute || position == EPosition::kFixed)) {
+ // The LayoutNG fragment tree structure is very similar to the containing
+ // block structure, with the exception of out-of-flow positioned boxes
+ // whose containing block is a non-atomic inline. If this is the case, we
+ // now need to add the offsets introduced by all inlines in the ancestry
+ // that affect us. This is a way to work around the discrepancy between
+ // the NG fragment tree structure and the actual containing block tree
+ // structure.
+ // TODO(mstensho): It's not good to walk up the ancestry
+ // (LayoutObject::Container()) like this, in fact pretty disastrous for
+ // e.g. fixed positioned objects, whose containing block is typically far
+ // up in the tree. Should we introduce a bit on LayoutObject that's set
+ // when this is necessary (or likely to be necessary)?
+ const LayoutObject* container = object_.Container();
+ if (container->IsLayoutInline() || container->IsAnonymousBlock()) {
+ // Set up context_ and full_context_ to be aware of the inline that is
+ // the actual containing block. This will be used by the code further
+ // down in this method.
+ // TODO(mstensho): This is currently incomplete. We're failing cases
+ // where the containing block sets up a filter, for instance.
+ if (position == EPosition::kFixed)
+ full_context_.container_for_fixed_position = container;
+ full_context_.container_for_absolute_position = container;
+ PhysicalOffset relative_offset;
+ if (const LayoutBox* box = ToLayoutBoxOrNull(container)) {
+ // If the OOF is contained by an anonymous block (because of inline
+ // continuations), we need to take that into account.
+ //
+ // Example:
+ // <span style="position:relative;">
+ // <div>
+ // <div id="box_model_object" style="position:absolute;">
+ DCHECK(box->IsAnonymousBlock());
+ relative_offset =
+ box->PhysicalLocation() + box->OffsetForInFlowPosition();
+ } else {
+ do {
+ relative_offset +=
+ ToLayoutInline(container)->OffsetForInFlowPosition();
+ container = container->Container();
+ } while (container->IsLayoutInline());
+ }
+ if (position == EPosition::kFixed) {
+ context_.fixed_position = context_.current;
+ context_.fixed_position.paint_offset += relative_offset;
+ }
+ context_.absolute_position = context_.current;
+ context_.absolute_position.paint_offset += relative_offset;
+ }
+ }
+
+ switch (position) {
case EPosition::kStatic:
break;
case EPosition::kRelative:
@@ -2294,6 +2388,15 @@ void FragmentPaintPropertyTreeBuilder::UpdatePaintOffset() {
}
}
+ if (IsInNGFragmentTraversal()) {
+ // Text and non-atomic inlines are special, in that they share one
+ // FragmentData per fragmentainer, so their paint offset is kept at their
+ // container. For all other objects, include the offset now.
+ if (object_.IsBox())
+ context_.current.paint_offset += pre_paint_info_->iterator->Link().offset;
+ return;
+ }
+
if (object_.IsBox()) {
// TODO(pdr): Several calls in this function walk back up the tree to
// calculate containers (e.g., physicalLocation, offsetForInFlowPosition*).
@@ -2396,6 +2499,14 @@ void FragmentPaintPropertyTreeBuilder::UpdateForObjectLocationAndSize(
fragment_data_.SetPaintOffset(context_.current.paint_offset);
fragment_data_.InvalidateClipPathCache();
+ if (object_.IsBox()) {
+ // See PaintLayerScrollableArea::PixelSnappedBorderBoxRect() for the
+ // reason of this.
+ if (auto* scrollable_area = ToLayoutBox(object_).GetScrollableArea())
+ scrollable_area->PositionOverflowControls();
+ }
+
+ object_.GetMutableForPainting().InvalidateIntersectionObserverCachedRects();
object_.GetFrameView()->SetIntersectionObservationState(
LocalFrameView::kDesired);
}
@@ -2513,9 +2624,7 @@ void FragmentPaintPropertyTreeBuilder::UpdateForChildren() {
void PaintPropertyTreeBuilder::InitFragmentPaintProperties(
FragmentData& fragment,
- bool needs_paint_properties,
- const PhysicalOffset& pagination_offset,
- LayoutUnit logical_top_in_flow_thread) {
+ bool needs_paint_properties) {
if (needs_paint_properties) {
fragment.EnsurePaintProperties();
} else if (fragment.PaintProperties()) {
@@ -2524,16 +2633,35 @@ void PaintPropertyTreeBuilder::InitFragmentPaintProperties(
PaintPropertyTreeBuilderContext::kSubtreeUpdateIsolationBlocked;
fragment.ClearPaintProperties();
}
- fragment.SetPaginationOffset(pagination_offset);
+}
+
+void PaintPropertyTreeBuilder::InitFragmentPaintPropertiesForLegacy(
+ FragmentData& fragment,
+ bool needs_paint_properties,
+ const PhysicalOffset& pagination_offset,
+ LayoutUnit logical_top_in_flow_thread) {
+ DCHECK(!IsInNGFragmentTraversal());
+ InitFragmentPaintProperties(fragment, needs_paint_properties);
+ fragment.SetLegacyPaginationOffset(pagination_offset);
fragment.SetLogicalTopInFlowThread(logical_top_in_flow_thread);
}
+void PaintPropertyTreeBuilder::InitFragmentPaintPropertiesForNG(
+ bool needs_paint_properties) {
+ InitFragmentPaintProperties(pre_paint_info_->fragment_data,
+ needs_paint_properties);
+ if (context_.fragments.IsEmpty())
+ context_.fragments.push_back(PaintPropertyTreeBuilderFragmentContext());
+ else
+ context_.fragments.resize(1);
+}
+
void PaintPropertyTreeBuilder::InitSingleFragmentFromParent(
bool needs_paint_properties) {
FragmentData& first_fragment =
object_.GetMutableForPainting().FirstFragment();
first_fragment.ClearNextFragment();
- InitFragmentPaintProperties(first_fragment, needs_paint_properties);
+ InitFragmentPaintPropertiesForLegacy(first_fragment, needs_paint_properties);
if (context_.fragments.IsEmpty()) {
context_.fragments.push_back(PaintPropertyTreeBuilderFragmentContext());
} else {
@@ -2591,6 +2719,7 @@ void PaintPropertyTreeBuilder::InitSingleFragmentFromParent(
}
void PaintPropertyTreeBuilder::UpdateCompositedLayerPaginationOffset() {
+ DCHECK(!IsInNGFragmentTraversal());
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
@@ -2620,7 +2749,7 @@ void PaintPropertyTreeBuilder::UpdateCompositedLayerPaginationOffset() {
BoundingBoxInPaginationContainer(object_, *enclosing_pagination_layer)
.ToLayoutRect());
if (!iterator.AtEnd()) {
- first_fragment.SetPaginationOffset(
+ first_fragment.SetLegacyPaginationOffset(
PhysicalOffsetToBeNoop(iterator.PaginationOffset()));
first_fragment.SetLogicalTopInFlowThread(
iterator.FragmentainerLogicalTopInFlowThread());
@@ -2629,7 +2758,7 @@ void PaintPropertyTreeBuilder::UpdateCompositedLayerPaginationOffset() {
// All objects under the composited layer use the same pagination offset.
const auto& fragment =
parent_composited_layer->GetLayoutObject().FirstFragment();
- first_fragment.SetPaginationOffset(fragment.PaginationOffset());
+ first_fragment.SetLegacyPaginationOffset(fragment.LegacyPaginationOffset());
first_fragment.SetLogicalTopInFlowThread(fragment.LogicalTopInFlowThread());
}
}
@@ -2867,6 +2996,7 @@ PaintPropertyTreeBuilderFragmentContext
PaintPropertyTreeBuilder::ContextForFragment(
const base::Optional<PhysicalRect>& fragment_clip,
LayoutUnit logical_top_in_flow_thread) const {
+ DCHECK(!IsInNGFragmentTraversal());
const auto& parent_fragments = context_.fragments;
if (parent_fragments.IsEmpty())
return PaintPropertyTreeBuilderFragmentContext();
@@ -2977,6 +3107,7 @@ PaintPropertyTreeBuilder::ContextForFragment(
void PaintPropertyTreeBuilder::CreateFragmentContextsInFlowThread(
bool needs_paint_properties) {
+ DCHECK(!IsInNGFragmentTraversal());
// We need at least the fragments for all fragmented objects, which store
// their local border box properties and paint invalidation data (such
// as paint offset and visual rect) on each fragment.
@@ -3068,11 +3199,11 @@ void PaintPropertyTreeBuilder::CreateFragmentContextsInFlowThread(
new_fragment_contexts.back().fragment_clip;
fragments_changed = !!old_fragment_clip != !!new_fragment_clip ||
(old_fragment_clip && new_fragment_clip &&
- old_fragment_clip->ClipRect() !=
+ old_fragment_clip->PixelSnappedClipRect() !=
ToSnappedClipRect(*new_fragment_clip));
}
- InitFragmentPaintProperties(
+ InitFragmentPaintPropertiesForLegacy(
*current_fragment_data,
needs_paint_properties || new_fragment_contexts.back().fragment_clip,
pagination_offset, logical_top_in_flow_thread);
@@ -3190,9 +3321,9 @@ void PaintPropertyTreeBuilder::CreateFragmentDataForRepeatingInPagedMedia(
fragment_data = fragment_data
? &fragment_data->EnsureNextFragment()
: &object_.GetMutableForPainting().FirstFragment();
- InitFragmentPaintProperties(*fragment_data, needs_paint_properties,
- PhysicalOffset(),
- fragment_context.logical_top_in_flow_thread);
+ InitFragmentPaintPropertiesForLegacy(
+ *fragment_data, needs_paint_properties, PhysicalOffset(),
+ fragment_context.logical_top_in_flow_thread);
}
DCHECK(fragment_data);
fragment_data->ClearNextFragment();
@@ -3215,7 +3346,7 @@ bool PaintPropertyTreeBuilder::UpdateFragments() {
// the paint offset and border box has been computed.
MayNeedClipPathClip(object_) ||
NeedsEffect(object_, context_.direct_compositing_reasons) ||
- NeedsTransformForNonRootSVG(object_) ||
+ NeedsTransformForSVGChild(object_) ||
NeedsFilter(object_, context_.direct_compositing_reasons) ||
NeedsCssClip(object_) || NeedsInnerBorderRadiusClip(object_) ||
NeedsOverflowClip(object_) || NeedsPerspective(object_) ||
@@ -3229,25 +3360,29 @@ bool PaintPropertyTreeBuilder::UpdateFragments() {
// Need of fragmentation clip will be determined in CreateFragmentContexts().
- if (object_.IsFixedPositionObjectInPagedMedia()) {
- // This flag applies to the object itself and descendants.
- context_.is_repeating_fixed_position = true;
- CreateFragmentContextsForRepeatingFixedPosition();
- } else if (ObjectIsRepeatingTableSectionInPagedMedia()) {
- context_.repeating_table_section =
- &ToInterface<LayoutNGTableSectionInterface>(object_);
- CreateFragmentContextsForRepeatingTableSectionInPagedMedia();
- }
-
- if (IsRepeatingInPagedMedia()) {
- CreateFragmentDataForRepeatingInPagedMedia(needs_paint_properties);
- } else if (context_.painting_layer->ShouldFragmentCompositedBounds()) {
- CreateFragmentContextsInFlowThread(needs_paint_properties);
+ if (IsInNGFragmentTraversal()) {
+ InitFragmentPaintPropertiesForNG(needs_paint_properties);
} else {
- InitSingleFragmentFromParent(needs_paint_properties);
- UpdateCompositedLayerPaginationOffset();
- context_.is_repeating_fixed_position = false;
- context_.repeating_table_section = nullptr;
+ if (object_.IsFixedPositionObjectInPagedMedia()) {
+ // This flag applies to the object itself and descendants.
+ context_.is_repeating_fixed_position = true;
+ CreateFragmentContextsForRepeatingFixedPosition();
+ } else if (ObjectIsRepeatingTableSectionInPagedMedia()) {
+ context_.repeating_table_section =
+ &ToInterface<LayoutNGTableSectionInterface>(object_);
+ CreateFragmentContextsForRepeatingTableSectionInPagedMedia();
+ }
+
+ if (IsRepeatingInPagedMedia()) {
+ CreateFragmentDataForRepeatingInPagedMedia(needs_paint_properties);
+ } else if (context_.painting_layer->ShouldFragmentCompositedBounds()) {
+ CreateFragmentContextsInFlowThread(needs_paint_properties);
+ } else {
+ InitSingleFragmentFromParent(needs_paint_properties);
+ UpdateCompositedLayerPaginationOffset();
+ context_.is_repeating_fixed_position = false;
+ context_.repeating_table_section = nullptr;
+ }
}
if (object_.IsSVGHiddenContainer()) {
@@ -3272,7 +3407,8 @@ bool PaintPropertyTreeBuilder::UpdateFragments() {
context_.has_svg_hidden_container_ancestor);
}
- UpdateRepeatingTableSectionPaintOffsetAdjustment();
+ if (!IsInNGFragmentTraversal())
+ UpdateRepeatingTableSectionPaintOffsetAdjustment();
return needs_paint_properties != had_paint_properties;
}
@@ -3288,17 +3424,15 @@ bool PaintPropertyTreeBuilder::ObjectTypeMightNeedMultipleFragmentData() const {
}
void PaintPropertyTreeBuilder::UpdatePaintingLayer() {
- bool changed_painting_layer = false;
if (object_.HasLayer() &&
ToLayoutBoxModelObject(object_).HasSelfPaintingLayer()) {
context_.painting_layer = ToLayoutBoxModelObject(object_).Layer();
- changed_painting_layer = true;
- } else if (object_.IsColumnSpanAll() ||
- object_.IsFloatingWithNonContainingBlockParent()) {
+ } else if (!IsInNGFragmentTraversal() &&
+ (object_.IsColumnSpanAll() ||
+ object_.IsFloatingWithNonContainingBlockParent())) {
// See LayoutObject::paintingLayer() for the special-cases of floating under
// inline and multicolumn.
context_.painting_layer = object_.PaintingLayer();
- changed_painting_layer = true;
}
DCHECK(context_.painting_layer == object_.PaintingLayer());
}
@@ -3318,22 +3452,48 @@ PaintPropertyChangeType PaintPropertyTreeBuilder::UpdateForSelf() {
property_changed = PaintPropertyChangeType::kNodeAddedOrRemoved;
} else {
DCHECK_EQ(context_.direct_compositing_reasons, CompositingReason::kNone);
- object_.GetMutableForPainting().FirstFragment().ClearNextFragment();
+ if (!IsInNGFragmentTraversal())
+ object_.GetMutableForPainting().FirstFragment().ClearNextFragment();
}
- auto* fragment_data = &object_.GetMutableForPainting().FirstFragment();
- for (auto& fragment_context : context_.fragments) {
- FragmentPaintPropertyTreeBuilder builder(object_, context_,
- fragment_context, *fragment_data);
+ if (pre_paint_info_) {
+ DCHECK_EQ(context_.fragments.size(), 1u);
+ FragmentPaintPropertyTreeBuilder builder(object_, pre_paint_info_, context_,
+ context_.fragments[0],
+ pre_paint_info_->fragment_data);
builder.UpdateForSelf();
property_changed = std::max(property_changed, builder.PropertyChanged());
- fragment_data = fragment_data->NextFragment();
+ } else {
+ auto* fragment_data = &object_.GetMutableForPainting().FirstFragment();
+ for (auto& fragment_context : context_.fragments) {
+ FragmentPaintPropertyTreeBuilder builder(
+ object_, /* pre_paint_info */ nullptr, context_, fragment_context,
+ *fragment_data);
+ builder.UpdateForSelf();
+ property_changed = std::max(property_changed, builder.PropertyChanged());
+ fragment_data = fragment_data->NextFragment();
+ }
+ DCHECK(!fragment_data);
}
- DCHECK(!fragment_data);
// We need to update property tree states of paint chunks.
if (property_changed >= PaintPropertyChangeType::kNodeAddedOrRemoved) {
context_.painting_layer->SetNeedsRepaint();
+ if (object_.IsDocumentElement()) {
+ // View background painting depends on existence of the document element's
+ // paint properties (see callsite of ViewPainter::PaintRootGroup()).
+ // Invalidate view background display item clients.
+ // SetBackgroundNeedsFullPaintInvalidation() won't work here because we
+ // have already walked the LayoutView in PrePaintTreeWalk.
+ LayoutView* layout_view = object_.View();
+ layout_view->Layer()->SetNeedsRepaint();
+ auto reason = PaintInvalidationReason::kBackground;
+ static_cast<const DisplayItemClient*>(layout_view)->Invalidate(reason);
+ if (auto* scrollable_area = layout_view->GetScrollableArea()) {
+ scrollable_area->GetScrollingBackgroundDisplayItemClient().Invalidate(
+ reason);
+ }
+ }
}
return property_changed;
@@ -3345,13 +3505,21 @@ PaintPropertyChangeType PaintPropertyTreeBuilder::UpdateForChildren() {
if (!ObjectTypeMightNeedPaintProperties())
return property_changed;
- auto* fragment_data = &object_.GetMutableForPainting().FirstFragment();
+ FragmentData* fragment_data;
+ if (pre_paint_info_) {
+ DCHECK_EQ(context_.fragments.size(), 1u);
+ fragment_data = &pre_paint_info_->fragment_data;
+ DCHECK(fragment_data);
+ } else {
+ fragment_data = &object_.GetMutableForPainting().FirstFragment();
+ }
+
// For now, only consider single fragment elements as possible isolation
// boundaries.
// TODO(crbug.com/890932): See if this is needed.
bool is_isolated = context_.fragments.size() == 1u;
for (auto& fragment_context : context_.fragments) {
- FragmentPaintPropertyTreeBuilder builder(object_, context_,
+ FragmentPaintPropertyTreeBuilder builder(object_, pre_paint_info_, context_,
fragment_context, *fragment_data);
// The element establishes an isolation boundary if it has isolation nodes
// before and after updating the children. In other words, if it didn't have
@@ -3364,7 +3532,12 @@ PaintPropertyChangeType PaintPropertyTreeBuilder::UpdateForChildren() {
property_changed = std::max(property_changed, builder.PropertyChanged());
fragment_data = fragment_data->NextFragment();
}
- DCHECK(!fragment_data);
+
+ // With NG fragment traversal we were supplied with the right FragmentData by
+ // the caller, and we only ran one lap in the loop above. Whether or not there
+ // are more FragmentData objects following is irrelevant then.
+ DCHECK(pre_paint_info_ || !fragment_data);
+
if (object_.SubtreePaintPropertyUpdateReasons() !=
static_cast<unsigned>(SubtreePaintPropertyUpdateReason::kNone)) {
if (AreSubtreeUpdateReasonsIsolationPiercing(
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder.h b/chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder.h
index 812cb587cc8..22e4495fda1 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder.h
@@ -20,6 +20,7 @@ class FragmentData;
class LayoutObject;
class LayoutNGTableSectionInterface;
class LocalFrameView;
+class NGFragmentChildIterator;
class PaintLayer;
class VisualViewport;
@@ -194,6 +195,18 @@ class VisualViewportPaintPropertyTreeBuilder {
PaintPropertyTreeBuilderContext&);
};
+struct NGPrePaintInfo {
+ STACK_ALLOCATED();
+
+ public:
+ NGPrePaintInfo(const NGFragmentChildIterator& iterator,
+ FragmentData& fragment_data)
+ : iterator(iterator), fragment_data(fragment_data) {}
+
+ const NGFragmentChildIterator& iterator;
+ FragmentData& fragment_data;
+};
+
// Creates paint property tree nodes for non-local effects in the layout tree.
// Non-local effects include but are not limited to: overflow clip, transform,
// fixed-pos, animation, mask, filters, etc. It expects to be invoked for each
@@ -206,8 +219,9 @@ class PaintPropertyTreeBuilder {
PaintPropertyTreeBuilderContext&);
PaintPropertyTreeBuilder(const LayoutObject& object,
+ NGPrePaintInfo* pre_paint_info,
PaintPropertyTreeBuilderContext& context)
- : object_(object), context_(context) {}
+ : object_(object), pre_paint_info_(pre_paint_info), context_(context) {}
// Update the paint properties that affect this object (e.g., properties like
// paint offset translation) and ensure the context is up to date. Also
@@ -221,11 +235,15 @@ class PaintPropertyTreeBuilder {
PaintPropertyChangeType UpdateForChildren();
private:
- ALWAYS_INLINE void InitFragmentPaintProperties(
+ ALWAYS_INLINE void InitFragmentPaintProperties(FragmentData&,
+ bool needs_paint_properties);
+ ALWAYS_INLINE void InitFragmentPaintPropertiesForLegacy(
FragmentData&,
bool needs_paint_properties,
const PhysicalOffset& pagination_offset = PhysicalOffset(),
LayoutUnit logical_top_in_flow_thread = LayoutUnit());
+ ALWAYS_INLINE void InitFragmentPaintPropertiesForNG(
+ bool needs_paint_properties);
ALWAYS_INLINE void InitSingleFragmentFromParent(bool needs_paint_properties);
ALWAYS_INLINE bool ObjectTypeMightNeedMultipleFragmentData() const;
ALWAYS_INLINE bool ObjectTypeMightNeedPaintProperties() const;
@@ -249,7 +267,11 @@ class PaintPropertyTreeBuilder {
ALWAYS_INLINE void UpdateRepeatingTableHeaderPaintOffsetAdjustment();
ALWAYS_INLINE void UpdateRepeatingTableFooterPaintOffsetAdjustment();
+ bool IsInNGFragmentTraversal() const { return pre_paint_info_; }
+
const LayoutObject& object_;
+ NGPrePaintInfo* pre_paint_info_;
+
PaintPropertyTreeBuilderContext& context_;
};
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 030a1f0ed31..1805b3db5f4 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
@@ -135,8 +135,7 @@ TEST_P(PaintPropertyTreeBuilderTest, FixedPosition) {
transformed_scroll->setScrollTop(5);
LocalFrameView* frame_view = GetDocument().View();
- frame_view->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ frame_view->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
// target1 is a fixed-position element inside an absolute-position scrolling
// element. It should be attached under the viewport to skip scrolling and
@@ -145,7 +144,7 @@ TEST_P(PaintPropertyTreeBuilderTest, FixedPosition) {
const ObjectPaintProperties* target1_properties =
target1->GetLayoutObject()->FirstFragment().PaintProperties();
EXPECT_EQ(FloatRoundedRect(200, 150, 100, 100),
- target1_properties->OverflowClip()->ClipRect());
+ target1_properties->OverflowClip()->UnsnappedClipRect());
// Likewise, it inherits clip from the viewport, skipping overflow clip of the
// scroller.
EXPECT_EQ(DocContentClip(), target1_properties->OverflowClip()->Parent());
@@ -172,7 +171,7 @@ TEST_P(PaintPropertyTreeBuilderTest, FixedPosition) {
const ObjectPaintProperties* scroller_properties =
scroller->GetLayoutObject()->FirstFragment().PaintProperties();
EXPECT_EQ(FloatRoundedRect(200, 150, 100, 100),
- target2_properties->OverflowClip()->ClipRect());
+ target2_properties->OverflowClip()->UnsnappedClipRect());
EXPECT_EQ(scroller_properties->OverflowClip(),
target2_properties->OverflowClip()->Parent());
// target2 should not have it's own scroll node and instead should inherit
@@ -198,8 +197,7 @@ TEST_P(PaintPropertyTreeBuilderTest, PositionAndScroll) {
Element* scroller = GetDocument().getElementById("scroller");
scroller->scrollTo(0, 100);
LocalFrameView* frame_view = GetDocument().View();
- frame_view->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ frame_view->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
const ObjectPaintProperties* scroller_properties =
scroller->GetLayoutObject()->FirstFragment().PaintProperties();
EXPECT_EQ(FloatSize(0, -100),
@@ -219,7 +217,7 @@ TEST_P(PaintPropertyTreeBuilderTest, PositionAndScroll) {
EXPECT_EQ(FloatSize(120, 340),
scroller_properties->PaintOffsetTranslation()->Translation2D());
EXPECT_EQ(FloatRoundedRect(0, 0, 413, 317),
- scroller_properties->OverflowClip()->ClipRect());
+ scroller_properties->OverflowClip()->UnsnappedClipRect());
EXPECT_EQ(DocContentClip(), scroller_properties->OverflowClip()->Parent());
CHECK_EXACT_VISUAL_RECT(PhysicalRect(120, 340, 413, 317),
scroller->GetLayoutObject(),
@@ -237,7 +235,7 @@ TEST_P(PaintPropertyTreeBuilderTest, PositionAndScroll) {
EXPECT_EQ(rel_pos_properties->Transform(),
&rel_pos_properties->OverflowClip()->LocalTransformSpace());
EXPECT_EQ(FloatRoundedRect(0, 0, 100, 200),
- rel_pos_properties->OverflowClip()->ClipRect());
+ rel_pos_properties->OverflowClip()->UnsnappedClipRect());
EXPECT_EQ(scroller_properties->OverflowClip(),
rel_pos_properties->OverflowClip()->Parent());
CHECK_EXACT_VISUAL_RECT(PhysicalRect(), rel_pos->GetLayoutObject(),
@@ -255,7 +253,7 @@ TEST_P(PaintPropertyTreeBuilderTest, PositionAndScroll) {
EXPECT_EQ(abs_pos_properties->Transform(),
&abs_pos_properties->OverflowClip()->LocalTransformSpace());
EXPECT_EQ(FloatRoundedRect(0, 0, 300, 400),
- abs_pos_properties->OverflowClip()->ClipRect());
+ abs_pos_properties->OverflowClip()->UnsnappedClipRect());
EXPECT_EQ(DocContentClip(), abs_pos_properties->OverflowClip()->Parent());
CHECK_EXACT_VISUAL_RECT(PhysicalRect(123, 456, 300, 400),
abs_pos->GetLayoutObject(),
@@ -278,7 +276,8 @@ TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollExcludeScrollbars) {
EXPECT_EQ(DocContentClip(), overflow_clip->Parent());
EXPECT_EQ(properties->PaintOffsetTranslation(),
&overflow_clip->LocalTransformSpace());
- EXPECT_EQ(FloatRoundedRect(10, 10, 100, 100), overflow_clip->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(10, 10, 100, 100),
+ overflow_clip->UnsnappedClipRect());
PaintLayer* paint_layer =
ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller"))->Layer();
@@ -287,7 +286,7 @@ TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollExcludeScrollbars) {
->IsOverlayScrollbar());
EXPECT_EQ(FloatClipRect(FloatRect(10, 10, 93, 93)),
- overflow_clip->ClipRectExcludingOverlayScrollbars());
+ overflow_clip->UnsnappedClipRectExcludingOverlayScrollbars());
}
TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollExcludeScrollbarsSubpixel) {
@@ -307,15 +306,18 @@ TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollExcludeScrollbarsSubpixel) {
EXPECT_EQ(DocContentClip(), overflow_clip->Parent());
EXPECT_EQ(properties->PaintOffsetTranslation(),
&overflow_clip->LocalTransformSpace());
- EXPECT_EQ(FloatRoundedRect(10, 10, 101, 100), overflow_clip->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(10, 10, 100.5, 100),
+ overflow_clip->UnsnappedClipRect());
+ EXPECT_EQ(FloatRoundedRect(10, 10, 101, 100),
+ overflow_clip->PixelSnappedClipRect());
EXPECT_TRUE(ToLayoutBox(scroller)
->GetScrollableArea()
->VerticalScrollbar()
->IsOverlayScrollbar());
- EXPECT_EQ(FloatClipRect(FloatRect(10, 10, 94, 93)),
- overflow_clip->ClipRectExcludingOverlayScrollbars());
+ EXPECT_EQ(FloatClipRect(FloatRect(10, 10, 93.5, 93)),
+ overflow_clip->UnsnappedClipRectExcludingOverlayScrollbars());
}
TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollExcludeCssOverlayScrollbar) {
@@ -335,7 +337,8 @@ TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollExcludeCssOverlayScrollbar) {
)HTML");
// The document content should not be clipped by the overlay scrollbar because
// the scrollbar can be transparent and the content needs to paint below.
- EXPECT_EQ(DocContentClip()->ClipRect(), FloatRoundedRect(0, 0, 800, 600));
+ EXPECT_EQ(DocContentClip()->UnsnappedClipRect(),
+ FloatRoundedRect(0, 0, 800, 600));
}
TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollVerticalRL) {
@@ -368,9 +371,11 @@ TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollVerticalRL) {
EXPECT_EQ(DocContentClip(), overflow_clip->Parent());
EXPECT_EQ(properties->PaintOffsetTranslation(),
&overflow_clip->LocalTransformSpace());
- EXPECT_EQ(FloatRoundedRect(10, 10, 85, 85), overflow_clip->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(10, 10, 85, 85),
+ overflow_clip->UnsnappedClipRect());
- scroller->GetScrollableArea()->ScrollBy(ScrollOffset(-100, 0), kUserScroll);
+ scroller->GetScrollableArea()->ScrollBy(ScrollOffset(-100, 0),
+ mojom::blink::ScrollType::kUser);
UpdateAllLifecyclePhasesForTest();
// Only scroll_translation is affected by scrolling.
@@ -386,7 +391,8 @@ TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollVerticalRL) {
EXPECT_EQ(DocContentClip(), overflow_clip->Parent());
EXPECT_EQ(properties->PaintOffsetTranslation(),
&overflow_clip->LocalTransformSpace());
- EXPECT_EQ(FloatRoundedRect(10, 10, 85, 85), overflow_clip->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(10, 10, 85, 85),
+ overflow_clip->UnsnappedClipRect());
}
TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollRTL) {
@@ -420,9 +426,11 @@ TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollRTL) {
EXPECT_EQ(DocContentClip(), overflow_clip->Parent());
EXPECT_EQ(properties->PaintOffsetTranslation(),
&overflow_clip->LocalTransformSpace());
- EXPECT_EQ(FloatRoundedRect(25, 10, 85, 85), overflow_clip->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(25, 10, 85, 85),
+ overflow_clip->UnsnappedClipRect());
- scroller->GetScrollableArea()->ScrollBy(ScrollOffset(-100, 0), kUserScroll);
+ scroller->GetScrollableArea()->ScrollBy(ScrollOffset(-100, 0),
+ mojom::blink::ScrollType::kUser);
UpdateAllLifecyclePhasesForTest();
// Only scroll_translation is affected by scrolling.
@@ -438,7 +446,8 @@ TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollRTL) {
EXPECT_EQ(DocContentClip(), overflow_clip->Parent());
EXPECT_EQ(properties->PaintOffsetTranslation(),
&overflow_clip->LocalTransformSpace());
- EXPECT_EQ(FloatRoundedRect(25, 10, 85, 85), overflow_clip->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(25, 10, 85, 85),
+ overflow_clip->UnsnappedClipRect());
}
TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollVerticalRLMulticol) {
@@ -462,7 +471,7 @@ TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollVerticalRLMulticol) {
EXPECT_EQ(410, FragmentAt(flow_thread, 0)
.PaintProperties()
->FragmentClip()
- ->ClipRect()
+ ->UnsnappedClipRect()
.Rect()
.X());
EXPECT_EQ(PhysicalOffset(360, 10),
@@ -470,7 +479,7 @@ TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollVerticalRLMulticol) {
EXPECT_EQ(460, FragmentAt(flow_thread, 1)
.PaintProperties()
->FragmentClip()
- ->ClipRect()
+ ->UnsnappedClipRect()
.Rect()
.MaxX());
EXPECT_EQ(PhysicalOffset(410, 210),
@@ -481,7 +490,7 @@ TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollVerticalRLMulticol) {
// Fragment geometries are not affected by parent scrolling.
ToLayoutBox(GetLayoutObjectByElementId("scroller"))
->GetScrollableArea()
- ->ScrollBy(ScrollOffset(-100, 200), kUserScroll);
+ ->ScrollBy(ScrollOffset(-100, 200), mojom::blink::ScrollType::kUser);
UpdateAllLifecyclePhasesForTest();
check_fragments();
}
@@ -492,8 +501,7 @@ TEST_P(PaintPropertyTreeBuilderTest, DocScrollingTraditional) {
GetDocument().domWindow()->scrollTo(0, 100);
LocalFrameView* frame_view = GetDocument().View();
- frame_view->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ frame_view->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
EXPECT_TRUE(DocPreTranslation()->IsIdentity());
EXPECT_EQ(
GetDocument().GetPage()->GetVisualViewport().GetScrollTranslationNode(),
@@ -501,7 +509,8 @@ TEST_P(PaintPropertyTreeBuilderTest, DocScrollingTraditional) {
EXPECT_EQ(FloatSize(0, -100), DocScrollTranslation()->Translation2D());
EXPECT_EQ(DocPreTranslation(), DocScrollTranslation()->Parent());
EXPECT_EQ(DocPreTranslation(), &DocContentClip()->LocalTransformSpace());
- EXPECT_EQ(FloatRoundedRect(0, 0, 800, 600), DocContentClip()->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(0, 0, 800, 600),
+ DocContentClip()->UnsnappedClipRect());
EXPECT_TRUE(DocContentClip()->Parent()->IsRoot());
CHECK_EXACT_VISUAL_RECT(PhysicalRect(8, 8, 784, 10000),
@@ -1444,7 +1453,7 @@ TEST_P(PaintPropertyTreeBuilderTest, SVGViewportContainer) {
ASSERT_NE(nullptr, clip);
EXPECT_EQ(nullptr, transform);
EXPECT_EQ(parent_clip, clip->Parent());
- EXPECT_EQ(FloatRect(0, 0, 30, 30), clip->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(0, 0, 30, 30), clip->UnsnappedClipRect().Rect());
EXPECT_EQ(parent_transform, &clip->LocalTransformSpace());
// overflow: hidden and non-zero offset and viewport scale:
@@ -1456,7 +1465,7 @@ TEST_P(PaintPropertyTreeBuilderTest, SVGViewportContainer) {
ASSERT_NE(nullptr, clip);
ASSERT_NE(nullptr, transform);
EXPECT_EQ(parent_clip, clip->Parent());
- EXPECT_EQ(FloatRect(0, 0, 60, 60), clip->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(0, 0, 60, 60), clip->UnsnappedClipRect().Rect());
EXPECT_EQ(transform, &clip->LocalTransformSpace());
EXPECT_EQ(TransformationMatrix().Translate(40, 50).Scale(0.5),
transform->Matrix());
@@ -1499,7 +1508,7 @@ TEST_P(PaintPropertyTreeBuilderTest, SVGForeignObjectOverflowClip) {
const auto* clip = properties1->OverflowClip();
ASSERT_NE(nullptr, clip);
EXPECT_EQ(parent_clip, clip->Parent());
- EXPECT_EQ(FloatRect(10, 20, 30, 40), clip->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(10, 20, 30, 40), clip->UnsnappedClipRect().Rect());
EXPECT_EQ(parent_transform, &clip->LocalTransformSpace());
const auto* properties2 = PaintPropertiesForElement("object2");
@@ -1523,7 +1532,7 @@ TEST_P(PaintPropertyTreeBuilderTest, OverflowClipWithEmptyVisualOverflow) {
const auto* clip = PaintPropertiesForElement("container")->OverflowClip();
EXPECT_NE(nullptr, clip);
- EXPECT_EQ(FloatRect(0, 0, 90, 90), clip->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(0, 0, 90, 90), clip->UnsnappedClipRect().Rect());
}
TEST_P(PaintPropertyTreeBuilderTest,
@@ -1615,7 +1624,7 @@ TEST_P(PaintPropertyTreeBuilderTest, ControlClip) {
&button_properties->OverflowClip()->LocalTransformSpace());
EXPECT_EQ(FloatRoundedRect(5, 5, 335, 113),
- button_properties->OverflowClip()->ClipRect());
+ button_properties->OverflowClip()->UnsnappedClipRect());
EXPECT_EQ(DocContentClip(), button_properties->OverflowClip()->Parent());
CHECK_EXACT_VISUAL_RECT(PhysicalRect(0, 0, 345, 123), &button,
GetDocument().View()->GetLayoutView());
@@ -1643,7 +1652,7 @@ TEST_P(PaintPropertyTreeBuilderTest, ControlClipInsideForeignObject) {
// not scroll (not enough content).
EXPECT_TRUE(DocScrollTranslation());
EXPECT_EQ(FloatRoundedRect(2, 2, 341, 119),
- button_properties->OverflowClip()->ClipRect());
+ button_properties->OverflowClip()->UnsnappedClipRect());
CHECK_EXACT_VISUAL_RECT(PhysicalRect(8, 8, 345, 123), &button,
GetDocument().View()->GetLayoutView());
}
@@ -1682,7 +1691,7 @@ TEST_P(PaintPropertyTreeBuilderTest, BorderRadiusClip) {
// padding box = border box(500+60+50, 400+45+55) - border outset(60+50,
// 45+55) - scrollbars(15, 15)
EXPECT_EQ(FloatRoundedRect(60, 45, 500, 400),
- div_properties->OverflowClip()->ClipRect());
+ div_properties->OverflowClip()->UnsnappedClipRect());
const ClipPaintPropertyNode* border_radius_clip =
div_properties->OverflowClip()->Parent();
EXPECT_EQ(DocScrollTranslation(), &border_radius_clip->LocalTransformSpace());
@@ -1703,12 +1712,44 @@ TEST_P(PaintPropertyTreeBuilderTest, BorderRadiusClip) {
FloatSize(), // (top right) = max((34, 34) - (50, 45), (0, 0))
FloatSize(18, 23), // (bot left) = max((78, 78) - (60, 55), (0, 0))
FloatSize(6, 1)), // (bot right) = max((56, 56) - (50, 55), (0, 0))
- border_radius_clip->ClipRect());
+ border_radius_clip->UnsnappedClipRect());
EXPECT_EQ(DocContentClip(), border_radius_clip->Parent());
CHECK_EXACT_VISUAL_RECT(PhysicalRect(0, 0, 610, 500), &div,
GetDocument().View()->GetLayoutView());
}
+TEST_P(PaintPropertyTreeBuilderTest, SubpixelBorderRadiusClip) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ body {
+ margin: 0px;
+ }
+ #div {
+ margin-top: 0.5px;
+ width: 100px;
+ height: 100px;
+ overflow: hidden;
+ border-radius: 50%;
+ }
+ </style>
+ <div id='div'></div>
+ )HTML");
+
+ LayoutObject& div = *GetLayoutObjectByElementId("div");
+ const ObjectPaintProperties* div_properties =
+ div.FirstFragment().PaintProperties();
+
+ const ClipPaintPropertyNode* border_radius_clip =
+ div_properties->InnerBorderRadiusClip();
+ FloatSize corner(50, 50);
+ EXPECT_EQ(FloatRoundedRect(FloatRect(0, 0.5, 100, 100), corner, corner,
+ corner, corner),
+ border_radius_clip->UnsnappedClipRect());
+ EXPECT_EQ(FloatRoundedRect(FloatRect(0, 1, 100, 100), corner, corner, corner,
+ corner),
+ border_radius_clip->PixelSnappedClipRect());
+}
+
TEST_P(PaintPropertyTreeBuilderTest, TransformNodesAcrossSubframes) {
SetBodyInnerHTML(R"HTML(
<style>
@@ -1734,8 +1775,7 @@ TEST_P(PaintPropertyTreeBuilderTest, TransformNodesAcrossSubframes) {
)HTML");
LocalFrameView* frame_view = GetDocument().View();
- frame_view->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ frame_view->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
LayoutObject* div_with_transform =
GetLayoutObjectByElementId("divWithTransform");
@@ -1825,8 +1865,7 @@ TEST_P(PaintPropertyTreeBuilderTest, FramesEstablishIsolation) {
)HTML");
LocalFrameView* frame_view = GetDocument().View();
- frame_view->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ frame_view->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
LayoutObject* frame = ChildFrame().View()->GetLayoutView();
const auto& frame_contents_properties =
@@ -1884,8 +1923,7 @@ TEST_P(PaintPropertyTreeBuilderTest, FramesEstablishIsolation) {
// However, isolation stops this recursion.
GetDocument().getElementById("parent")->setAttribute(html_names::kClassAttr,
"transformed");
- frame_view->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ frame_view->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
// Verify that our clobbered state is still clobbered.
EXPECT_EQ(FloatSize(123, 321),
@@ -1922,8 +1960,7 @@ TEST_P(PaintPropertyTreeBuilderTest, TransformNodesInTransformedSubframes) {
<div id='transform'></div>
)HTML");
LocalFrameView* frame_view = GetDocument().View();
- frame_view->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ frame_view->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
// Assert that we have the following tree structure:
// ...
@@ -2126,7 +2163,7 @@ TEST_P(PaintPropertyTreeBuilderTest, CSSClipFixedPositionDescendant) {
EXPECT_EQ(DocScrollTranslation(),
&clip_properties->CssClip()->LocalTransformSpace());
EXPECT_EQ(FloatRoundedRect(FloatRect(absolute_clip_rect)),
- clip_properties->CssClip()->ClipRect());
+ clip_properties->CssClip()->UnsnappedClipRect());
CHECK_VISUAL_RECT(absolute_clip_rect, &clip,
GetDocument().View()->GetLayoutView(),
// TODO(crbug.com/599939): mapToVisualRectInAncestorSpace()
@@ -2186,7 +2223,7 @@ TEST_P(PaintPropertyTreeBuilderTest, CSSClipAbsPositionDescendant) {
EXPECT_EQ(DocScrollTranslation(),
&clip_properties->CssClip()->LocalTransformSpace());
EXPECT_EQ(FloatRoundedRect(FloatRect(absolute_clip_rect)),
- clip_properties->CssClip()->ClipRect());
+ clip_properties->CssClip()->UnsnappedClipRect());
CHECK_VISUAL_RECT(absolute_clip_rect, clip,
GetDocument().View()->GetLayoutView(),
// TODO(crbug.com/599939): mapToVisualRectInAncestorSpace()
@@ -2228,7 +2265,8 @@ TEST_P(PaintPropertyTreeBuilderTest, CSSClipSubpixel) {
PhysicalRect local_clip_rect(40, 10, 40, 60);
PhysicalRect absolute_clip_rect = local_clip_rect;
// Moved by 124 pixels due to pixel-snapping.
- absolute_clip_rect.offset += PhysicalOffset(124, 456);
+ absolute_clip_rect.offset +=
+ PhysicalOffset(LayoutSize(FloatSize(123.5, 456)));
auto* clip = GetLayoutObjectByElementId("clip");
const ObjectPaintProperties* clip_properties =
@@ -2240,7 +2278,9 @@ TEST_P(PaintPropertyTreeBuilderTest, CSSClipSubpixel) {
EXPECT_EQ(DocScrollTranslation(),
&clip_properties->CssClip()->LocalTransformSpace());
EXPECT_EQ(FloatRoundedRect(FloatRect(absolute_clip_rect)),
- clip_properties->CssClip()->ClipRect());
+ clip_properties->CssClip()->UnsnappedClipRect());
+ EXPECT_EQ(FloatRoundedRect(PixelSnappedIntRect((absolute_clip_rect))),
+ clip_properties->CssClip()->PixelSnappedClipRect());
}
TEST_P(PaintPropertyTreeBuilderTest, CSSClipFixedPositionDescendantNonShared) {
@@ -2298,13 +2338,13 @@ TEST_P(PaintPropertyTreeBuilderTest, CSSClipFixedPositionDescendantNonShared) {
EXPECT_EQ(overflow_properties->ScrollTranslation(),
&clip_properties->CssClip()->LocalTransformSpace());
EXPECT_EQ(FloatRoundedRect(FloatRect(absolute_clip_rect)),
- clip_properties->CssClip()->ClipRect());
+ clip_properties->CssClip()->UnsnappedClipRect());
EXPECT_EQ(DocContentClip(),
clip_properties->CssClipFixedPosition()->Parent());
EXPECT_EQ(overflow_properties->ScrollTranslation(),
&clip_properties->CssClipFixedPosition()->LocalTransformSpace());
EXPECT_EQ(FloatRoundedRect(FloatRect(absolute_clip_rect)),
- clip_properties->CssClipFixedPosition()->ClipRect());
+ clip_properties->CssClipFixedPosition()->UnsnappedClipRect());
CHECK_EXACT_VISUAL_RECT(PhysicalRect(), clip,
GetDocument().View()->GetLayoutView());
@@ -3411,9 +3451,10 @@ TEST_P(PaintPropertyTreeBuilderTest, ContainPaintOrStyleLayoutTreeState) {
&clipper->FirstFragment().LocalBorderBoxProperties().Clip());
// Clip isolation node should be big enough to encompass all other clips,
// including DocContentClip.
- EXPECT_TRUE(
- clip_properties->ClipIsolationNode()->ClipRect().Rect().Contains(
- DocContentClip()->ClipRect().Rect()));
+ EXPECT_TRUE(clip_properties->ClipIsolationNode()
+ ->UnsnappedClipRect()
+ .Rect()
+ .Contains(DocContentClip()->UnsnappedClipRect().Rect()));
// Verify contents properties and child properties:
@@ -3519,12 +3560,12 @@ TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollWithRoundedRect) {
EXPECT_EQ(
FloatRoundedRect(FloatRect(50, 50, 200, 200), FloatSize(50, 50),
FloatSize(50, 50), FloatSize(50, 50), FloatSize(50, 50)),
- rounded_box_properties->InnerBorderRadiusClip()->ClipRect());
+ rounded_box_properties->InnerBorderRadiusClip()->UnsnappedClipRect());
// Unlike the inner border radius clip, the overflow clip is inset by the
// scrollbars (13px).
EXPECT_EQ(FloatRoundedRect(50, 50, 187, 187),
- rounded_box_properties->OverflowClip()->ClipRect());
+ rounded_box_properties->OverflowClip()->UnsnappedClipRect());
EXPECT_EQ(DocContentClip(),
rounded_box_properties->InnerBorderRadiusClip()->Parent());
EXPECT_EQ(rounded_box_properties->InnerBorderRadiusClip(),
@@ -3920,7 +3961,7 @@ TEST_P(PaintPropertyTreeBuilderTest, SVGRootClip) {
.PaintProperties()
->PaintOffsetTranslation()
->Translation2D());
- EXPECT_EQ(FloatRoundedRect(0, 0, 100, 100), clip->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(0, 0, 100, 100), clip->UnsnappedClipRect());
}
TEST_P(PaintPropertyTreeBuilderTest, SVGRootNoClip) {
@@ -3982,8 +4023,8 @@ TEST_P(PaintPropertyTreeBuilderTest, PaintOffsetsUnderMultiColumnScrolled) {
)HTML");
LayoutObject* scroller = GetLayoutObjectByElementId("scroller");
- ToLayoutBox(scroller)->GetScrollableArea()->ScrollBy(ScrollOffset(0, 300),
- kUserScroll);
+ ToLayoutBox(scroller)->GetScrollableArea()->ScrollBy(
+ ScrollOffset(0, 300), mojom::blink::ScrollType::kUser);
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(FloatSize(8, 8), scroller->FirstFragment()
@@ -4072,8 +4113,8 @@ TEST_P(PaintPropertyTreeBuilderTest,
EXPECT_EQ(PhysicalOffset(51, -20),
multicol_container->FirstFragment().NextFragment()->PaintOffset());
- GetDocument().View()->LayoutViewport()->ScrollBy(ScrollOffset(0, 25),
- kUserScroll);
+ GetDocument().View()->LayoutViewport()->ScrollBy(
+ ScrollOffset(0, 25), mojom::blink::ScrollType::kUser);
UpdateAllLifecyclePhasesForTest();
ASSERT_TRUE(multicol_container->FirstFragment().NextFragment());
@@ -4113,62 +4154,66 @@ TEST_P(PaintPropertyTreeBuilderTest, FragmentsUnderMultiColumn) {
EXPECT_EQ(4u, NumFragments(flowthread));
EXPECT_EQ(PhysicalOffset(), FragmentAt(relpos, 0).PaintOffset());
- EXPECT_EQ(PhysicalOffset(), FragmentAt(relpos, 0).PaginationOffset());
+ EXPECT_EQ(PhysicalOffset(), FragmentAt(relpos, 0).LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(), FragmentAt(relpos, 0).LogicalTopInFlowThread());
EXPECT_EQ(nullptr, FragmentAt(relpos, 0).PaintProperties());
EXPECT_EQ(PhysicalOffset(), FragmentAt(flowthread, 0).PaintOffset());
- EXPECT_EQ(PhysicalOffset(), FragmentAt(flowthread, 0).PaginationOffset());
+ EXPECT_EQ(PhysicalOffset(),
+ FragmentAt(flowthread, 0).LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(), FragmentAt(flowthread, 0).LogicalTopInFlowThread());
const auto* fragment_clip =
FragmentAt(flowthread, 0).PaintProperties()->FragmentClip();
ASSERT_NE(nullptr, fragment_clip);
EXPECT_EQ(FloatRect(-1000000, -1000000, 2000000, 1000030),
- fragment_clip->ClipRect().Rect());
+ fragment_clip->UnsnappedClipRect().Rect());
EXPECT_EQ(fragment_clip,
&FragmentAt(relpos, 0).LocalBorderBoxProperties().Clip());
EXPECT_EQ(PhysicalOffset(100, -30), FragmentAt(relpos, 1).PaintOffset());
- EXPECT_EQ(PhysicalOffset(100, -30), FragmentAt(relpos, 1).PaginationOffset());
+ EXPECT_EQ(PhysicalOffset(100, -30),
+ FragmentAt(relpos, 1).LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(30), FragmentAt(relpos, 1).LogicalTopInFlowThread());
EXPECT_EQ(nullptr, FragmentAt(relpos, 1).PaintProperties());
EXPECT_EQ(PhysicalOffset(100, -30), FragmentAt(flowthread, 1).PaintOffset());
EXPECT_EQ(PhysicalOffset(100, -30),
- FragmentAt(flowthread, 1).PaginationOffset());
+ FragmentAt(flowthread, 1).LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(30), FragmentAt(flowthread, 1).LogicalTopInFlowThread());
fragment_clip = FragmentAt(flowthread, 1).PaintProperties()->FragmentClip();
ASSERT_NE(nullptr, fragment_clip);
EXPECT_EQ(FloatRect(-999900, 0, 2000000, 30),
- fragment_clip->ClipRect().Rect());
+ fragment_clip->UnsnappedClipRect().Rect());
EXPECT_EQ(fragment_clip,
&FragmentAt(relpos, 1).LocalBorderBoxProperties().Clip());
EXPECT_EQ(PhysicalOffset(0, 20), FragmentAt(relpos, 2).PaintOffset());
- EXPECT_EQ(PhysicalOffset(0, 20), FragmentAt(relpos, 2).PaginationOffset());
+ EXPECT_EQ(PhysicalOffset(0, 20),
+ FragmentAt(relpos, 2).LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(60), FragmentAt(relpos, 2).LogicalTopInFlowThread());
EXPECT_EQ(nullptr, FragmentAt(relpos, 2).PaintProperties());
EXPECT_EQ(PhysicalOffset(0, 20), FragmentAt(flowthread, 2).PaintOffset());
EXPECT_EQ(PhysicalOffset(0, 20),
- FragmentAt(flowthread, 2).PaginationOffset());
+ FragmentAt(flowthread, 2).LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(60), FragmentAt(flowthread, 2).LogicalTopInFlowThread());
fragment_clip = FragmentAt(flowthread, 2).PaintProperties()->FragmentClip();
ASSERT_NE(nullptr, fragment_clip);
EXPECT_EQ(FloatRect(-1000000, 80, 2000000, 30),
- fragment_clip->ClipRect().Rect());
+ fragment_clip->UnsnappedClipRect().Rect());
EXPECT_EQ(fragment_clip,
&FragmentAt(relpos, 2).LocalBorderBoxProperties().Clip());
EXPECT_EQ(PhysicalOffset(100, -10), FragmentAt(relpos, 3).PaintOffset());
- EXPECT_EQ(PhysicalOffset(100, -10), FragmentAt(relpos, 3).PaginationOffset());
+ EXPECT_EQ(PhysicalOffset(100, -10),
+ FragmentAt(relpos, 3).LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(90), FragmentAt(relpos, 3).LogicalTopInFlowThread());
EXPECT_EQ(nullptr, FragmentAt(relpos, 3).PaintProperties());
EXPECT_EQ(PhysicalOffset(100, -10), FragmentAt(flowthread, 3).PaintOffset());
EXPECT_EQ(PhysicalOffset(100, -10),
- FragmentAt(flowthread, 3).PaginationOffset());
+ FragmentAt(flowthread, 3).LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(90), FragmentAt(flowthread, 3).LogicalTopInFlowThread());
fragment_clip = FragmentAt(flowthread, 3).PaintProperties()->FragmentClip();
ASSERT_NE(nullptr, fragment_clip);
EXPECT_EQ(FloatRect(-999900, 80, 2000000, 999910),
- fragment_clip->ClipRect().Rect());
+ fragment_clip->UnsnappedClipRect().Rect());
EXPECT_EQ(fragment_clip,
&FragmentAt(relpos, 3).LocalBorderBoxProperties().Clip());
@@ -4242,20 +4287,21 @@ TEST_P(PaintPropertyTreeBuilderTest,
EXPECT_TRUE(thread->IsLayoutFlowThread());
EXPECT_EQ(2u, NumFragments(thread));
EXPECT_EQ(PhysicalOffset(100, 0), FragmentAt(thread, 0).PaintOffset());
- EXPECT_EQ(PhysicalOffset(), FragmentAt(thread, 0).PaginationOffset());
+ EXPECT_EQ(PhysicalOffset(), FragmentAt(thread, 0).LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(), FragmentAt(thread, 0).LogicalTopInFlowThread());
EXPECT_EQ(PhysicalOffset(300, 100), FragmentAt(thread, 1).PaintOffset());
- EXPECT_EQ(PhysicalOffset(200, 100), FragmentAt(thread, 1).PaginationOffset());
+ EXPECT_EQ(PhysicalOffset(200, 100),
+ FragmentAt(thread, 1).LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(200), FragmentAt(thread, 1).LogicalTopInFlowThread());
LayoutObject* content = GetLayoutObjectByElementId("content");
EXPECT_EQ(2u, NumFragments(content));
EXPECT_EQ(PhysicalOffset(-200, 0), FragmentAt(content, 0).PaintOffset());
- EXPECT_EQ(PhysicalOffset(), FragmentAt(content, 0).PaginationOffset());
+ EXPECT_EQ(PhysicalOffset(), FragmentAt(content, 0).LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(), FragmentAt(content, 0).LogicalTopInFlowThread());
EXPECT_EQ(PhysicalOffset(0, 100), FragmentAt(content, 1).PaintOffset());
EXPECT_EQ(PhysicalOffset(200, 100),
- FragmentAt(content, 1).PaginationOffset());
+ FragmentAt(content, 1).LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(200), FragmentAt(content, 1).LogicalTopInFlowThread());
}
@@ -4277,6 +4323,10 @@ TEST_P(PaintPropertyTreeBuilderTest, LayerUnderOverflowClipUnderMultiColumn) {
}
TEST_P(PaintPropertyTreeBuilderTest, CompositedUnderMultiColumn) {
+ // TODO(crbug.com/1064341): This test crashes in CompositeAfterPaint. Fix it.
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ return;
+
SetBodyInnerHTML(R"HTML(
<style>body { margin: 0; }</style>
<div id='multicol' style='columns:3; column-fill:auto; column-gap: 0;
@@ -4295,15 +4345,15 @@ TEST_P(PaintPropertyTreeBuilderTest, CompositedUnderMultiColumn) {
EXPECT_TRUE(thread->IsLayoutFlowThread());
EXPECT_EQ(3u, NumFragments(thread));
EXPECT_EQ(PhysicalOffset(), FragmentAt(thread, 0).PaintOffset());
- EXPECT_EQ(PhysicalOffset(), FragmentAt(thread, 0).PaginationOffset());
+ EXPECT_EQ(PhysicalOffset(), FragmentAt(thread, 0).LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(), FragmentAt(thread, 0).LogicalTopInFlowThread());
EXPECT_EQ(PhysicalOffset(100, -200), FragmentAt(thread, 1).PaintOffset());
EXPECT_EQ(PhysicalOffset(100, -200),
- FragmentAt(thread, 1).PaginationOffset());
+ FragmentAt(thread, 1).LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(200), FragmentAt(thread, 1).LogicalTopInFlowThread());
EXPECT_EQ(PhysicalOffset(200, -400), FragmentAt(thread, 2).PaintOffset());
EXPECT_EQ(PhysicalOffset(200, -400),
- FragmentAt(thread, 2).PaginationOffset());
+ FragmentAt(thread, 2).LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(400), FragmentAt(thread, 2).LogicalTopInFlowThread());
LayoutObject* composited = GetLayoutObjectByElementId("composited");
@@ -4317,33 +4367,33 @@ TEST_P(PaintPropertyTreeBuilderTest, CompositedUnderMultiColumn) {
EXPECT_EQ(PhysicalOffset(100, 100),
FragmentAt(composited, 0).PaintOffset());
EXPECT_EQ(PhysicalOffset(100, -200),
- FragmentAt(composited, 0).PaginationOffset());
+ FragmentAt(composited, 0).LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(200),
FragmentAt(composited, 0).LogicalTopInFlowThread());
EXPECT_EQ(PhysicalOffset(200, -100),
FragmentAt(composited, 1).PaintOffset());
EXPECT_EQ(PhysicalOffset(200, -400),
- FragmentAt(composited, 1).PaginationOffset());
+ FragmentAt(composited, 1).LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(400),
FragmentAt(composited, 1).LogicalTopInFlowThread());
EXPECT_EQ(2u, NumFragments(non_composited_child));
EXPECT_EQ(PhysicalOffset(100, 100),
FragmentAt(non_composited_child, 0).PaintOffset());
EXPECT_EQ(PhysicalOffset(100, -200),
- FragmentAt(non_composited_child, 0).PaginationOffset());
+ FragmentAt(non_composited_child, 0).LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(200),
FragmentAt(non_composited_child, 0).LogicalTopInFlowThread());
EXPECT_EQ(PhysicalOffset(200, -100),
FragmentAt(non_composited_child, 1).PaintOffset());
EXPECT_EQ(PhysicalOffset(200, -400),
- FragmentAt(non_composited_child, 1).PaginationOffset());
+ FragmentAt(non_composited_child, 1).LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(400),
FragmentAt(non_composited_child, 1).LogicalTopInFlowThread());
EXPECT_EQ(1u, NumFragments(composited_child));
EXPECT_EQ(PhysicalOffset(200, 50),
FragmentAt(composited_child, 0).PaintOffset());
EXPECT_EQ(PhysicalOffset(200, -400),
- FragmentAt(composited_child, 0).PaginationOffset());
+ FragmentAt(composited_child, 0).LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(400),
FragmentAt(composited_child, 0).LogicalTopInFlowThread());
} else {
@@ -4352,21 +4402,21 @@ TEST_P(PaintPropertyTreeBuilderTest, CompositedUnderMultiColumn) {
EXPECT_EQ(PhysicalOffset(100, 100),
FragmentAt(composited, 0).PaintOffset());
EXPECT_EQ(PhysicalOffset(100, -200),
- FragmentAt(composited, 0).PaginationOffset());
+ FragmentAt(composited, 0).LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(200),
FragmentAt(composited, 0).LogicalTopInFlowThread());
EXPECT_EQ(1u, NumFragments(non_composited_child));
EXPECT_EQ(PhysicalOffset(100, 100),
FragmentAt(non_composited_child, 0).PaintOffset());
EXPECT_EQ(PhysicalOffset(100, -200),
- FragmentAt(non_composited_child, 0).PaginationOffset());
+ FragmentAt(non_composited_child, 0).LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(200),
FragmentAt(non_composited_child, 0).LogicalTopInFlowThread());
EXPECT_EQ(1u, NumFragments(composited_child));
EXPECT_EQ(PhysicalOffset(100, 250),
FragmentAt(composited_child, 0).PaintOffset());
EXPECT_EQ(PhysicalOffset(100, -200),
- FragmentAt(composited_child, 0).PaginationOffset());
+ FragmentAt(composited_child, 0).LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(200),
FragmentAt(composited_child, 0).LogicalTopInFlowThread());
}
@@ -4425,6 +4475,10 @@ TEST_P(PaintPropertyTreeBuilderTest, FrameUnderMulticol) {
}
TEST_P(PaintPropertyTreeBuilderTest, CompositedMulticolFrameUnderMulticol) {
+ // TODO(crbug.com/1064341): This test crashes in CompositeAfterPaint. Fix it.
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ return;
+
SetBodyInnerHTML(R"HTML(
<style>body { margin: 0 }</style>
<div style='columns: 3; column-gap: 0; column-fill: auto;
@@ -4448,8 +4502,9 @@ TEST_P(PaintPropertyTreeBuilderTest, CompositedMulticolFrameUnderMulticol) {
// TODO(crbug.com/797779): Add code to verify fragments under the iframe.
}
-TEST_P(PaintPropertyTreeBuilderTest,
- BecomingUnfragmentedClearsPaginationOffsetAndLogicalTopInFlowThread) {
+TEST_P(
+ PaintPropertyTreeBuilderTest,
+ BecomingUnfragmentedClearsLegacyPaginationOffsetAndLogicalTopInFlowThread) {
SetBodyInnerHTML(R"HTML(
<style>
#target {
@@ -4465,13 +4520,13 @@ TEST_P(PaintPropertyTreeBuilderTest,
LayoutObject* target = GetLayoutObjectByElementId("target");
EXPECT_EQ(PhysicalOffset(LayoutUnit(392.5f), LayoutUnit(-20)),
- target->FirstFragment().PaginationOffset());
+ target->FirstFragment().LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(20), target->FirstFragment().LogicalTopInFlowThread());
Element* target_element = GetDocument().getElementById("target");
target_element->setAttribute(html_names::kStyleAttr, "position: absolute");
UpdateAllLifecyclePhasesForTest();
- EXPECT_EQ(PhysicalOffset(), target->FirstFragment().PaginationOffset());
+ EXPECT_EQ(PhysicalOffset(), target->FirstFragment().LegacyPaginationOffset());
EXPECT_EQ(LayoutUnit(), target->FirstFragment().LogicalTopInFlowThread());
}
@@ -4740,8 +4795,10 @@ TEST_P(PaintPropertyTreeBuilderTest, OverflowClipSubpixelPosition) {
EXPECT_EQ(PhysicalOffset(LayoutUnit(31.5), LayoutUnit(20)),
clipper->FirstFragment().PaintOffset());
// Result is pixel-snapped.
+ EXPECT_EQ(FloatRect(31.5, 20, 400, 300),
+ clip_properties->OverflowClip()->UnsnappedClipRect().Rect());
EXPECT_EQ(FloatRect(32, 20, 400, 300),
- clip_properties->OverflowClip()->ClipRect().Rect());
+ clip_properties->OverflowClip()->PixelSnappedClipRect().Rect());
}
TEST_P(PaintPropertyTreeBuilderTest, MaskSimple) {
@@ -4759,7 +4816,7 @@ TEST_P(PaintPropertyTreeBuilderTest, MaskSimple) {
EXPECT_EQ(output_clip,
&target->FirstFragment().LocalBorderBoxProperties().Clip());
EXPECT_EQ(DocContentClip(), output_clip->Parent());
- EXPECT_EQ(FloatRoundedRect(8, 8, 300, 200), output_clip->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(8, 8, 300, 200), output_clip->UnsnappedClipRect());
EXPECT_EQ(properties->Effect(),
&target->FirstFragment().LocalBorderBoxProperties().Effect());
@@ -4788,7 +4845,8 @@ TEST_P(PaintPropertyTreeBuilderTest, MaskWithOutset) {
EXPECT_EQ(output_clip,
&target->FirstFragment().LocalBorderBoxProperties().Clip());
EXPECT_EQ(DocContentClip(), output_clip->Parent());
- EXPECT_EQ(FloatRoundedRect(-12, -2, 340, 220), output_clip->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(-12, -2, 340, 220),
+ output_clip->UnsnappedClipRect());
EXPECT_EQ(properties->Effect(),
&target->FirstFragment().LocalBorderBoxProperties().Effect());
@@ -4831,18 +4889,20 @@ TEST_P(PaintPropertyTreeBuilderTest, MaskEscapeClip) {
PaintPropertiesForElement("scroll");
EXPECT_EQ(DocContentClip(), overflow_clip1->Parent());
- EXPECT_EQ(FloatRoundedRect(0, 0, 300, 200), overflow_clip1->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(0, 0, 300, 200),
+ overflow_clip1->UnsnappedClipRect());
EXPECT_EQ(scroll_properties->PaintOffsetTranslation(),
&overflow_clip1->LocalTransformSpace());
EXPECT_EQ(mask_clip,
&target->FirstFragment().LocalBorderBoxProperties().Clip());
EXPECT_EQ(overflow_clip1, mask_clip->Parent());
- EXPECT_EQ(FloatRoundedRect(0, 0, 220, 320), mask_clip->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(0, 0, 220, 320), mask_clip->UnsnappedClipRect());
EXPECT_EQ(&scroll_translation, &mask_clip->LocalTransformSpace());
EXPECT_EQ(mask_clip, overflow_clip2->Parent());
- EXPECT_EQ(FloatRoundedRect(10, 10, 200, 300), overflow_clip2->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(10, 10, 200, 300),
+ overflow_clip2->UnsnappedClipRect());
EXPECT_EQ(&scroll_translation, &overflow_clip2->LocalTransformSpace());
EXPECT_EQ(target_properties->Effect(),
@@ -4894,7 +4954,8 @@ TEST_P(PaintPropertyTreeBuilderTest, MaskInline) {
EXPECT_EQ(output_clip,
&target->FirstFragment().LocalBorderBoxProperties().Clip());
EXPECT_EQ(DocContentClip(), output_clip->Parent());
- EXPECT_EQ(FloatRoundedRect(104, 21, 432, 16), output_clip->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(104, 21, 432, 16),
+ output_clip->UnsnappedClipRect());
EXPECT_EQ(properties->Effect(),
&target->FirstFragment().LocalBorderBoxProperties().Effect());
@@ -5097,16 +5158,10 @@ TEST_P(PaintPropertyTreeBuilderTest, BackfaceHidden) {
ASSERT_NE(nullptr, target_properties);
const auto* paint_offset_translation =
target_properties->PaintOffsetTranslation();
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
- EXPECT_EQ(nullptr, paint_offset_translation);
- EXPECT_EQ(PhysicalOffset(60, 50), target->FirstFragment().PaintOffset());
- } else {
- // For SPv1, |target| is composited so we created PaintOffsetTranslation.
- ASSERT_NE(nullptr, paint_offset_translation);
- EXPECT_EQ(FloatSize(60, 50), paint_offset_translation->Translation2D());
- EXPECT_EQ(TransformPaintPropertyNode::BackfaceVisibility::kInherited,
- paint_offset_translation->GetBackfaceVisibilityForTesting());
- }
+ ASSERT_NE(nullptr, paint_offset_translation);
+ EXPECT_EQ(FloatSize(60, 50), paint_offset_translation->Translation2D());
+ EXPECT_EQ(TransformPaintPropertyNode::BackfaceVisibility::kInherited,
+ paint_offset_translation->GetBackfaceVisibilityForTesting());
const auto* transform = target_properties->Transform();
ASSERT_NE(nullptr, transform);
@@ -5140,7 +5195,7 @@ TEST_P(PaintPropertyTreeBuilderTest, FrameBorderRadius) {
FloatSize radius(30, 30);
EXPECT_EQ(FloatRoundedRect(FloatRect(28, 28, 200, 200), radius, radius,
radius, radius),
- border_radius_clip->ClipRect());
+ border_radius_clip->UnsnappedClipRect());
EXPECT_EQ(DocContentClip(), border_radius_clip->Parent());
EXPECT_EQ(DocScrollTranslation(), &border_radius_clip->LocalTransformSpace());
EXPECT_EQ(nullptr, properties->InnerBorderRadiusClip());
@@ -5167,7 +5222,7 @@ TEST_P(PaintPropertyTreeBuilderTest, ImageBorderRadius) {
FloatSize radius(20, 20);
EXPECT_EQ(FloatRoundedRect(FloatRect(18, 18, 50, 50), radius, radius, radius,
radius),
- border_radius_clip->ClipRect());
+ border_radius_clip->UnsnappedClipRect());
EXPECT_EQ(DocContentClip(), border_radius_clip->Parent());
EXPECT_EQ(DocScrollTranslation(), &border_radius_clip->LocalTransformSpace());
EXPECT_EQ(nullptr, properties->InnerBorderRadiusClip());
@@ -5183,10 +5238,10 @@ TEST_P(PaintPropertyTreeBuilderTest, FrameClipWhenPrinting) {
auto* const child_frame_doc = &ChildDocument();
ASSERT_NE(nullptr, DocContentClip(main_frame_doc));
EXPECT_NE(FloatRect(LayoutRect::InfiniteIntRect()),
- DocContentClip(main_frame_doc)->ClipRect().Rect());
+ DocContentClip(main_frame_doc)->UnsnappedClipRect().Rect());
ASSERT_NE(nullptr, DocContentClip(child_frame_doc));
EXPECT_NE(FloatRect(LayoutRect::InfiniteIntRect()),
- DocContentClip(child_frame_doc)->ClipRect().Rect());
+ DocContentClip(child_frame_doc)->UnsnappedClipRect().Rect());
// When the main frame is printing, it should not have content clip.
FloatSize page_size(100, 100);
@@ -5195,7 +5250,7 @@ TEST_P(PaintPropertyTreeBuilderTest, FrameClipWhenPrinting) {
EXPECT_EQ(nullptr, DocContentClip(main_frame_doc));
ASSERT_NE(nullptr, DocContentClip(child_frame_doc));
EXPECT_NE(FloatRect(LayoutRect::InfiniteIntRect()),
- DocContentClip(child_frame_doc)->ClipRect().Rect());
+ DocContentClip(child_frame_doc)->UnsnappedClipRect().Rect());
GetFrame().EndPrinting();
UpdateAllLifecyclePhasesForTest();
@@ -5206,7 +5261,7 @@ TEST_P(PaintPropertyTreeBuilderTest, FrameClipWhenPrinting) {
GetDocument().View()->UpdateLifecyclePhasesForPrinting();
ASSERT_NE(nullptr, DocContentClip(main_frame_doc));
EXPECT_NE(FloatRect(LayoutRect::InfiniteIntRect()),
- DocContentClip(main_frame_doc)->ClipRect().Rect());
+ DocContentClip(main_frame_doc)->UnsnappedClipRect().Rect());
EXPECT_EQ(nullptr, DocContentClip(child_frame_doc));
}
@@ -5220,7 +5275,8 @@ TEST_P(PaintPropertyTreeBuilderTest, OverflowControlsClip) {
const auto* properties1 = PaintPropertiesForElement("div1");
ASSERT_NE(nullptr, properties1);
const auto* overflow_controls_clip = properties1->OverflowControlsClip();
- EXPECT_EQ(FloatRect(0, 0, 5, 50), overflow_controls_clip->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(0, 0, 5, 50),
+ overflow_controls_clip->UnsnappedClipRect().Rect());
const auto* properties2 = PaintPropertiesForElement("div2");
ASSERT_NE(nullptr, properties2);
@@ -5237,7 +5293,10 @@ TEST_P(PaintPropertyTreeBuilderTest, OverflowControlsClipSubpixel) {
const auto* properties1 = PaintPropertiesForElement("div1");
ASSERT_NE(nullptr, properties1);
const auto* overflow_controls_clip = properties1->OverflowControlsClip();
- EXPECT_EQ(FloatRect(0, 0, 6, 50), overflow_controls_clip->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(0, 0, 5.5, 50),
+ overflow_controls_clip->UnsnappedClipRect().Rect());
+ EXPECT_EQ(FloatRect(0, 0, 6, 50),
+ overflow_controls_clip->PixelSnappedClipRect().Rect());
const auto* properties2 = PaintPropertiesForElement("div2");
ASSERT_NE(nullptr, properties2);
@@ -5289,9 +5348,10 @@ TEST_P(PaintPropertyTreeBuilderTest, FragmentClipPixelSnapped) {
FragmentAt(flow_thread, 1).PaintProperties()->FragmentClip();
EXPECT_EQ(FloatRect(-999992, -999992, 2000000, 1000050),
- first_clip->ClipRect().Rect());
+ first_clip->PixelSnappedClipRect().Rect());
+
EXPECT_EQ(FloatRect(-999967, 8, 2000000, 999951),
- second_clip->ClipRect().Rect());
+ second_clip->PixelSnappedClipRect().Rect());
}
TEST_P(PaintPropertyTreeBuilderTest,
@@ -5310,18 +5370,11 @@ TEST_P(PaintPropertyTreeBuilderTest,
EXPECT_FALSE(ToLayoutBoxModelObject(target)->Layer()->SelfNeedsRepaint());
opacity_element->setAttribute(html_names::kStyleAttr, "opacity: 0.5");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
- if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
- // TODO(crbug.com/900241): Without CompositeAfterPaint, we create effect and
- // filter nodes when the transform node needs compositing for
- // will-change:transform, for crbug.com/942681.
- EXPECT_FALSE(ToLayoutBoxModelObject(target)->Layer()->SelfNeedsRepaint());
- } else {
- // All paint chunks contained by the new opacity effect node need to be
- // re-painted.
- EXPECT_TRUE(ToLayoutBoxModelObject(target)->Layer()->SelfNeedsRepaint());
- }
+ EXPECT_TRUE(opacity_element->GetLayoutBox()->Layer()->SelfNeedsRepaint());
+ EXPECT_FALSE(ToLayoutBoxModelObject(target)->Layer()->SelfNeedsRepaint());
}
TEST_P(PaintPropertyTreeBuilderTest, SVGRootWithMask) {
@@ -5374,7 +5427,8 @@ TEST_P(PaintPropertyTreeBuilderTest, ClearClipPathEffectNode) {
Element* clip = GetDocument().getElementById("clip");
ASSERT_TRUE(clip);
clip->remove();
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
{
const auto* rect = GetLayoutObjectByElementId("rect");
@@ -5395,7 +5449,8 @@ TEST_P(PaintPropertyTreeBuilderTest, RootHasCompositedScrolling) {
// Remove scrolling from the root.
Element* force_scroll_element = GetDocument().getElementById("forceScroll");
force_scroll_element->setAttribute(html_names::kStyleAttr, "");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
// Always create scroll translation for layout view even the document does
// not scroll (not enough content).
EXPECT_TRUE(DocScrollTranslation());
@@ -5505,7 +5560,8 @@ TEST_P(PaintPropertyTreeBuilderTest, ClipHitTestChangeDoesNotCauseFullRepaint) {
EXPECT_FALSE(child_layer->SelfNeedsRepaint());
GetDocument().body()->setAttribute(html_names::kClassAttr, "noscrollbars");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_FALSE(child_layer->SelfNeedsRepaint());
}
@@ -5570,7 +5626,11 @@ TEST_P(PaintPropertyTreeBuilderTest, CompositedLayerSkipsFragmentClip) {
.Clip());
}
-TEST_P(PaintPropertyTreeBuilderTest, CompositedLayerUnderClipUnerMulticol) {
+TEST_P(PaintPropertyTreeBuilderTest, CompositedLayerUnderClipUnderMulticol) {
+ // TODO(crbug.com/1064341): This test crashes in CompositeAfterPaint. Fix it.
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ return;
+
SetBodyInnerHTML(R"HTML(
<div id="multicol" style="columns: 2">
<div id="clip" style="height: 100px; overflow: hidden">
@@ -6024,26 +6084,6 @@ TEST_P(PaintPropertyTreeBuilderTest, StickyConstraintChain) {
->nearest_element_shifting_containing_block);
}
-TEST_P(PaintPropertyTreeBuilderTest, RoundedStickyConstraints) {
- // This test verifies that sticky constraint rects are rounded to the nearest
- // integer.
- SetBodyInnerHTML(R"HTML(
- <div id="scroller" style="overflow:scroll; width:300px; height:199.5px;">
- <div id="outer" style="position:sticky; top:10px; height:300px">
- </div>
- <div style="height:1000px;"></div>
- </div>
- )HTML");
- GetDocument().getElementById("scroller")->setScrollTop(50);
- UpdateAllLifecyclePhasesForTest();
-
- const auto* outer_properties = PaintPropertiesForElement("outer");
- ASSERT_TRUE(outer_properties && outer_properties->StickyTranslation());
- EXPECT_EQ(gfx::Rect(0, 0, 300, 200), outer_properties->StickyTranslation()
- ->GetStickyConstraint()
- ->constraint_box_rect);
-}
-
TEST_P(PaintPropertyTreeBuilderTest, NonScrollableSticky) {
// This test verifies the property tree builder applies sticky offset
// correctly when the clipping container cannot be scrolled, and
@@ -6098,7 +6138,8 @@ TEST_P(PaintPropertyTreeBuilderTest, WillChangeOpacityInducesAnEffectNode) {
auto* div = GetDocument().getElementById("div");
div->setAttribute(html_names::kClassAttr, "transluscent");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_FALSE(
ToLayoutBox(div->GetLayoutObject())->Layer()->SelfNeedsRepaint());
@@ -6208,39 +6249,49 @@ TEST_P(PaintPropertyTreeBuilderTest, SVGRootCompositedClipPath) {
const auto* clip_path_clip = properties->ClipPathClip();
ASSERT_NE(nullptr, clip_path_clip);
EXPECT_EQ(DocContentClip(), clip_path_clip->Parent());
- EXPECT_EQ(FloatRect(75, 0, 150, 150), clip_path_clip->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(75, 0, 150, 150),
+ clip_path_clip->UnsnappedClipRect().Rect());
EXPECT_EQ(transform, &clip_path_clip->LocalTransformSpace());
EXPECT_NE(nullptr, clip_path_clip->ClipPath());
const auto* overflow_clip = properties->OverflowClip();
ASSERT_NE(nullptr, overflow_clip);
EXPECT_EQ(clip_path_clip, overflow_clip->Parent());
- EXPECT_EQ(FloatRect(0, 0, 300, 150), overflow_clip->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(0, 0, 300, 150),
+ overflow_clip->UnsnappedClipRect().Rect());
EXPECT_EQ(transform, &overflow_clip->LocalTransformSpace());
- // TODO(wangxianzhu): Are the following correct?
- EXPECT_EQ(nullptr, properties->Effect());
+ const auto* effect = properties->Effect();
+ ASSERT_NE(nullptr, effect);
+ EXPECT_EQ(&EffectPaintPropertyNode::Root(), effect->Parent());
+ EXPECT_EQ(transform, &effect->LocalTransformSpace());
+ EXPECT_EQ(clip_path_clip, effect->OutputClip());
+ EXPECT_EQ(SkBlendMode::kSrcOver, effect->BlendMode());
+
EXPECT_EQ(nullptr, properties->Mask());
EXPECT_EQ(nullptr, properties->ClipPath());
} else {
const auto* mask_clip = properties->MaskClip();
ASSERT_NE(nullptr, mask_clip);
EXPECT_EQ(DocContentClip(), mask_clip->Parent());
- EXPECT_EQ(FloatRect(75, 0, 150, 150), mask_clip->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(75, 0, 150, 150),
+ mask_clip->UnsnappedClipRect().Rect());
EXPECT_EQ(nullptr, mask_clip->ClipPath());
EXPECT_EQ(transform, &mask_clip->LocalTransformSpace());
const auto* clip_path_clip = properties->ClipPathClip();
ASSERT_NE(nullptr, clip_path_clip);
EXPECT_EQ(mask_clip, clip_path_clip->Parent());
- EXPECT_EQ(FloatRect(75, 0, 150, 150), clip_path_clip->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(75, 0, 150, 150),
+ clip_path_clip->UnsnappedClipRect().Rect());
EXPECT_EQ(transform, &clip_path_clip->LocalTransformSpace());
EXPECT_NE(nullptr, clip_path_clip->ClipPath());
const auto* overflow_clip = properties->OverflowClip();
ASSERT_NE(nullptr, overflow_clip);
EXPECT_EQ(mask_clip, overflow_clip->Parent());
- EXPECT_EQ(FloatRect(0, 0, 300, 150), overflow_clip->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(0, 0, 300, 150),
+ overflow_clip->UnsnappedClipRect().Rect());
EXPECT_EQ(transform, &overflow_clip->LocalTransformSpace());
const auto* effect = properties->Effect();
@@ -6305,7 +6356,8 @@ TEST_P(PaintPropertyTreeBuilderTest, SimpleOpacityChangeDoesNotCausePacUpdate) {
Element* element = GetDocument().getElementById("element");
element->setAttribute(html_names::kStyleAttr, "opacity: 0.9");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_FLOAT_EQ(properties->Effect()->Opacity(), 0.9f);
EXPECT_FLOAT_EQ(cc_effect->opacity, 0.9f);
EXPECT_TRUE(cc_effect->effect_changed);
@@ -6369,7 +6421,8 @@ TEST_P(PaintPropertyTreeBuilderTest, SimpleScrollChangeDoesNotCausePacUpdate) {
EXPECT_FLOAT_EQ(current_scroll_offset.y(), 0);
GetDocument().getElementById("element")->setScrollTop(10.);
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_FLOAT_SIZE_EQ(FloatSize(0, -10),
properties->ScrollTranslation()->Translation2D());
@@ -6381,7 +6434,6 @@ TEST_P(PaintPropertyTreeBuilderTest, SimpleScrollChangeDoesNotCausePacUpdate) {
properties->ScrollTranslation()->ScrollNode()->GetCompositorElementId());
EXPECT_FLOAT_EQ(current_scroll_offset.x(), 0);
EXPECT_FLOAT_EQ(current_scroll_offset.y(), 10);
- EXPECT_TRUE(property_trees->scroll_tree.needs_update());
EXPECT_TRUE(property_trees->transform_tree.needs_update());
EXPECT_TRUE(cc_transform_node->transform_changed);
@@ -6413,7 +6465,8 @@ TEST_P(PaintPropertyTreeBuilderTest,
Element* outer = GetDocument().getElementById("outer");
outer->setAttribute(html_names::kStyleAttr, "transform: translateY(10px)");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(
GetDocument().View()->GetPaintArtifactCompositor()->NeedsUpdate());
@@ -6464,24 +6517,22 @@ TEST_P(PaintPropertyTreeBuilderTest, VideoClipRect) {
video_element->SetInlineStyleProperty(CSSPropertyID::kTop, "0.1px");
video_element->SetInlineStyleProperty(CSSPropertyID::kLeft, "0.1px");
LocalFrameView* frame_view = GetDocument().View();
- frame_view->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ frame_view->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
const ObjectPaintProperties* video_element_properties =
video_element->GetLayoutObject()->FirstFragment().PaintProperties();
// |video_element| is now sub-pixel positioned, at 0.1,0.1 320.2x240. With or
// without pixel-snapped clipping, this will get clipped at 0,0 320x240.
EXPECT_EQ(FloatRoundedRect(0, 0, 320, 240),
- video_element_properties->OverflowClip()->ClipRect());
+ video_element_properties->OverflowClip()->UnsnappedClipRect());
// Now, move |video_element| to 10.4,10.4. At this point, without pixel
// snapping that doesn't depend on paint offset, it will be clipped at 10,10
// 321x240. With proper pixel snapping, the clip will be at 10,10,320,240.
video_element->SetInlineStyleProperty(CSSPropertyID::kTop, "10.4px");
video_element->SetInlineStyleProperty(CSSPropertyID::kLeft, "10.4px");
- frame_view->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ frame_view->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
EXPECT_EQ(FloatRoundedRect(10, 10, 320, 240),
- video_element_properties->OverflowClip()->ClipRect());
+ video_element_properties->OverflowClip()->UnsnappedClipRect());
}
// For NoPaintPropertyForXXXText cases. The styles trigger almost all paint
@@ -6529,65 +6580,6 @@ TEST_P(PaintPropertyTreeBuilderTest, NoPaintPropertyForSVGText) {
EXPECT_FALSE(text->FirstFragment().PaintProperties());
}
-TEST_P(PaintPropertyTreeBuilderTest, SetViewportScrollingBits) {
- SetBodyInnerHTML(R"HTML(
- <style>
- body, html {
- margin: 0;
- width: 100%;
- height: 100%;
- }
- #scroller {
- width: 100%;
- height: 200%;
- overflow: auto;
- }
- </style>
- <div id="scroller">
- <div style="height: 3000px"></div>
- </div>
- )HTML");
-
- const auto* scroller_node = PaintPropertiesForElement("scroller")->Scroll();
- const auto* document_node = DocScroll();
-
- // Ensure the LayoutView's ScrollNode is marked as scrolling the "outer" or
- // "layout" viewport.
- {
- EXPECT_FALSE(scroller_node->ScrollsOuterViewport());
- EXPECT_TRUE(document_node->ScrollsOuterViewport());
- }
-
- // Ensure the visual viewport is the only one that sets the inner scroll bit.
- {
- EXPECT_TRUE(GetDocument()
- .GetPage()
- ->GetVisualViewport()
- .GetScrollNode()
- ->ScrollsInnerViewport());
- EXPECT_FALSE(scroller_node->ScrollsInnerViewport());
- EXPECT_FALSE(document_node->ScrollsInnerViewport());
- }
-
- // Make the scroller fill the viewport. This will make it eligible for root
- // scroller promotion. Ensure the outer viewport scrolling property is
- // correctly recomputed, moving it from the LayoutView to the scroller.
- {
- Element* scroller = GetDocument().getElementById("scroller");
- scroller->setAttribute(html_names::kStyleAttr, "height: 100%");
- LocalFrameView* frame_view = GetDocument().View();
- frame_view->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
- ASSERT_TRUE(scroller->GetLayoutObject()->IsGlobalRootScroller());
-
- EXPECT_TRUE(scroller_node->ScrollsOuterViewport());
-
- // Since the document is no longer scrollable and isn't the root scroller
- // it shouldn't have a node.
- EXPECT_FALSE(DocScroll());
- }
-}
-
TEST_P(PaintPropertyTreeBuilderTest, IsAffectedByOuterViewportBoundsDelta) {
SetBodyInnerHTML(R"HTML(
<style>div { will-change: transform; position: fixed; }</style>
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_property_tree_printer.cc b/chromium/third_party/blink/renderer/core/paint/paint_property_tree_printer.cc
index 057f90eb7a5..59a6b43f841 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_property_tree_printer.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_property_tree_printer.cc
@@ -54,7 +54,7 @@ class FrameViewPropertyTreePrinter
for (const auto* fragment = &object.FirstFragment(); fragment;
fragment = fragment->NextFragment()) {
if (const auto* properties = fragment->PaintProperties())
- Traits::AddObjectPaintProperties(object, *properties, *this);
+ Traits::AddObjectPaintProperties(*properties, *this);
}
for (const auto* child = object.SlowFirstChild(); child;
child = child->NextSibling()) {
@@ -75,7 +75,6 @@ class PropertyTreePrinterTraits<TransformPaintPropertyNode> {
printer.AddNode(visual_viewport.GetScrollTranslationNode());
}
static void AddObjectPaintProperties(
- const LayoutObject& object,
const ObjectPaintProperties& properties,
PropertyTreePrinter<TransformPaintPropertyNode>& printer) {
printer.AddNode(properties.PaintOffsetTranslation());
@@ -95,7 +94,6 @@ class PropertyTreePrinterTraits<ClipPaintPropertyNode> {
const VisualViewport& visual_viewport,
PropertyTreePrinter<ClipPaintPropertyNode>& printer) {}
static void AddObjectPaintProperties(
- const LayoutObject& object,
const ObjectPaintProperties& properties,
PropertyTreePrinter<ClipPaintPropertyNode>& printer) {
printer.AddNode(properties.FragmentClip());
@@ -118,7 +116,6 @@ class PropertyTreePrinterTraits<EffectPaintPropertyNode> {
PropertyTreePrinter<EffectPaintPropertyNode>& printer) {}
static void AddObjectPaintProperties(
- const LayoutObject& object,
const ObjectPaintProperties& properties,
PropertyTreePrinter<EffectPaintPropertyNode>& printer) {
printer.AddNode(properties.Effect());
@@ -141,7 +138,6 @@ class PropertyTreePrinterTraits<ScrollPaintPropertyNode> {
}
static void AddObjectPaintProperties(
- const LayoutObject& object,
const ObjectPaintProperties& properties,
PropertyTreePrinter<ScrollPaintPropertyNode>& printer) {
printer.AddNode(properties.Scroll());
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc b/chromium/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc
index da6c4c0a9bf..8f6de40bed2 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc
@@ -315,8 +315,7 @@ TEST_P(PaintPropertyTreeUpdateTest, DescendantNeedsUpdateAcrossFrames) {
"translate3d(4px, 5px, 6px); width: 100px; height: 200px'></div>");
LocalFrameView* frame_view = GetDocument().View();
- frame_view->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ frame_view->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
LayoutObject* div_with_transform =
GetLayoutObjectByElementId("divWithTransform");
@@ -342,8 +341,7 @@ TEST_P(PaintPropertyTreeUpdateTest, DescendantNeedsUpdateAcrossFrames) {
EXPECT_FALSE(inner_div_with_transform->DescendantNeedsPaintPropertyUpdate());
// After a lifecycle update, no nodes should need a descendant update.
- frame_view->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ frame_view->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
EXPECT_FALSE(
GetDocument().GetLayoutView()->DescendantNeedsPaintPropertyUpdate());
EXPECT_FALSE(div_with_transform->DescendantNeedsPaintPropertyUpdate());
@@ -356,8 +354,7 @@ TEST_P(PaintPropertyTreeUpdateTest, DescendantNeedsUpdateAcrossFrames) {
child_frame_view->SetNeedsPaintPropertyUpdate();
EXPECT_TRUE(
GetDocument().GetLayoutView()->DescendantNeedsPaintPropertyUpdate());
- frame_view->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ frame_view->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
EXPECT_FALSE(
GetDocument().GetLayoutView()->DescendantNeedsPaintPropertyUpdate());
EXPECT_FALSE(GetDocument().GetLayoutView()->NeedsPaintPropertyUpdate());
@@ -368,16 +365,20 @@ TEST_P(PaintPropertyTreeUpdateTest, DescendantNeedsUpdateAcrossFrames) {
TEST_P(PaintPropertyTreeUpdateTest, UpdatingFrameViewContentClip) {
SetBodyInnerHTML("hello world.");
- EXPECT_EQ(FloatRoundedRect(0, 0, 800, 600), DocContentClip()->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(0, 0, 800, 600),
+ DocContentClip()->UnsnappedClipRect());
GetDocument().View()->Resize(800, 599);
UpdateAllLifecyclePhasesForTest();
- EXPECT_EQ(FloatRoundedRect(0, 0, 800, 599), DocContentClip()->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(0, 0, 800, 599),
+ DocContentClip()->UnsnappedClipRect());
GetDocument().View()->Resize(800, 600);
UpdateAllLifecyclePhasesForTest();
- EXPECT_EQ(FloatRoundedRect(0, 0, 800, 600), DocContentClip()->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(0, 0, 800, 600),
+ DocContentClip()->UnsnappedClipRect());
GetDocument().View()->Resize(5, 5);
UpdateAllLifecyclePhasesForTest();
- EXPECT_EQ(FloatRoundedRect(0, 0, 5, 5), DocContentClip()->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(0, 0, 5, 5),
+ DocContentClip()->UnsnappedClipRect());
}
// There is also FrameThrottlingTest.UpdatePaintPropertiesOnUnthrottling
@@ -477,17 +478,17 @@ TEST_P(PaintPropertyTreeUpdateTest, ClipChangesUpdateOverflowClip) {
UpdateAllLifecyclePhasesForTest();
auto* clip_properties =
div->GetLayoutObject()->FirstFragment().PaintProperties()->OverflowClip();
- EXPECT_EQ(FloatRect(0, 0, 7, 0), clip_properties->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(0, 0, 7, 0), clip_properties->UnsnappedClipRect().Rect());
// Width changes should update the overflow clip.
div->setAttribute(html_names::kStyleAttr, "display:inline-block; width:7px;");
UpdateAllLifecyclePhasesForTest();
clip_properties =
div->GetLayoutObject()->FirstFragment().PaintProperties()->OverflowClip();
- EXPECT_EQ(FloatRect(0, 0, 7, 0), clip_properties->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(0, 0, 7, 0), clip_properties->UnsnappedClipRect().Rect());
div->setAttribute(html_names::kStyleAttr, "display:inline-block; width:9px;");
UpdateAllLifecyclePhasesForTest();
- EXPECT_EQ(FloatRect(0, 0, 9, 0), clip_properties->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(0, 0, 9, 0), clip_properties->UnsnappedClipRect().Rect());
// An inline block's overflow clip should be updated when padding changes,
// even if the border box remains unchanged.
@@ -496,33 +497,39 @@ TEST_P(PaintPropertyTreeUpdateTest, ClipChangesUpdateOverflowClip) {
UpdateAllLifecyclePhasesForTest();
clip_properties =
div->GetLayoutObject()->FirstFragment().PaintProperties()->OverflowClip();
- EXPECT_EQ(FloatRect(0, 0, 10, 0), clip_properties->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(0, 0, 10, 0),
+ clip_properties->UnsnappedClipRect().Rect());
div->setAttribute(html_names::kStyleAttr,
"display:inline-block; width:8px; padding-right:2px;");
UpdateAllLifecyclePhasesForTest();
- EXPECT_EQ(FloatRect(0, 0, 10, 0), clip_properties->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(0, 0, 10, 0),
+ clip_properties->UnsnappedClipRect().Rect());
div->setAttribute(html_names::kStyleAttr,
"display:inline-block; width:8px;"
"padding-right:1px; padding-left:1px;");
UpdateAllLifecyclePhasesForTest();
- EXPECT_EQ(FloatRect(0, 0, 10, 0), clip_properties->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(0, 0, 10, 0),
+ clip_properties->UnsnappedClipRect().Rect());
// An block's overflow clip should be updated when borders change.
div->setAttribute(html_names::kStyleAttr, "border-right:3px solid red;");
UpdateAllLifecyclePhasesForTest();
clip_properties =
div->GetLayoutObject()->FirstFragment().PaintProperties()->OverflowClip();
- EXPECT_EQ(FloatRect(0, 0, 797, 0), clip_properties->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(0, 0, 797, 0),
+ clip_properties->UnsnappedClipRect().Rect());
div->setAttribute(html_names::kStyleAttr, "border-right:5px solid red;");
UpdateAllLifecyclePhasesForTest();
- EXPECT_EQ(FloatRect(0, 0, 795, 0), clip_properties->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(0, 0, 795, 0),
+ clip_properties->UnsnappedClipRect().Rect());
// Removing overflow clip should remove the property.
div->setAttribute(html_names::kStyleAttr, "overflow:hidden;");
UpdateAllLifecyclePhasesForTest();
clip_properties =
div->GetLayoutObject()->FirstFragment().PaintProperties()->OverflowClip();
- EXPECT_EQ(FloatRect(0, 0, 800, 0), clip_properties->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(0, 0, 800, 0),
+ clip_properties->UnsnappedClipRect().Rect());
div->setAttribute(html_names::kStyleAttr, "overflow:visible;");
UpdateAllLifecyclePhasesForTest();
EXPECT_TRUE(!div->GetLayoutObject()->FirstFragment().PaintProperties() ||
@@ -546,7 +553,7 @@ TEST_P(PaintPropertyTreeUpdateTest, ContainPaintChangesUpdateOverflowClip) {
auto* div = GetDocument().getElementById("div");
auto* properties =
div->GetLayoutObject()->FirstFragment().PaintProperties()->OverflowClip();
- EXPECT_EQ(FloatRect(0, 0, 7, 6), properties->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(0, 0, 7, 6), properties->UnsnappedClipRect().Rect());
div->setAttribute(html_names::kStyleAttr, "");
UpdateAllLifecyclePhasesForTest();
@@ -564,7 +571,8 @@ TEST_P(PaintPropertyTreeUpdateTest, NoPaintPropertyUpdateOnBackgroundChange) {
UpdateAllLifecyclePhasesForTest();
div->setAttribute(html_names::kStyleAttr, "background-color: green");
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
EXPECT_FALSE(div->GetLayoutObject()->NeedsPaintPropertyUpdate());
}
@@ -582,16 +590,14 @@ TEST_P(PaintPropertyTreeUpdateTest,
"<div id='forceScroll' style='height: 3000px;'></div>");
LocalFrameView* frame_view = GetDocument().View();
- frame_view->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ frame_view->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
EXPECT_EQ(nullptr, DocScroll());
Document* child_doc = &ChildDocument();
EXPECT_NE(nullptr, DocScroll(child_doc));
auto* iframe_container = GetDocument().getElementById("iframeContainer");
iframe_container->setAttribute(html_names::kStyleAttr, "visibility: hidden;");
- frame_view->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ frame_view->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
EXPECT_EQ(nullptr, DocScroll());
EXPECT_EQ(nullptr, DocScroll(child_doc));
@@ -760,15 +766,19 @@ TEST_P(PaintPropertyTreeUpdateTest, CSSClipDependingOnSize) {
auto* outer = GetDocument().getElementById("outer");
auto* clip = GetLayoutObjectByElementId("clip");
- EXPECT_EQ(
- FloatRect(45, 50, 105, 100),
- clip->FirstFragment().PaintProperties()->CssClip()->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(45, 50, 105, 100), clip->FirstFragment()
+ .PaintProperties()
+ ->CssClip()
+ ->UnsnappedClipRect()
+ .Rect());
outer->setAttribute(html_names::kStyleAttr, "height: 200px");
UpdateAllLifecyclePhasesForTest();
- EXPECT_EQ(
- FloatRect(45, 50, 105, 200),
- clip->FirstFragment().PaintProperties()->CssClip()->ClipRect().Rect());
+ EXPECT_EQ(FloatRect(45, 50, 105, 200), clip->FirstFragment()
+ .PaintProperties()
+ ->CssClip()
+ ->UnsnappedClipRect()
+ .Rect());
}
TEST_P(PaintPropertyTreeUpdateTest, ScrollBoundsChange) {
@@ -888,7 +898,8 @@ TEST_P(PaintPropertyTreeUpdateTest, ScrollbarWidthChange) {
auto* container = GetLayoutObjectByElementId("container");
auto* overflow_clip =
container->FirstFragment().PaintProperties()->OverflowClip();
- EXPECT_EQ(FloatSize(80, 80), overflow_clip->ClipRect().Rect().Size());
+ EXPECT_EQ(FloatSize(80, 80),
+ overflow_clip->UnsnappedClipRect().Rect().Size());
auto* new_style = GetDocument().CreateRawElement(html_names::kStyleTag);
new_style->setTextContent("::-webkit-scrollbar {width: 40px; height: 40px}");
@@ -897,7 +908,8 @@ TEST_P(PaintPropertyTreeUpdateTest, ScrollbarWidthChange) {
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(overflow_clip,
container->FirstFragment().PaintProperties()->OverflowClip());
- EXPECT_EQ(FloatSize(60, 60), overflow_clip->ClipRect().Rect().Size());
+ EXPECT_EQ(FloatSize(60, 60),
+ overflow_clip->UnsnappedClipRect().Rect().Size());
}
TEST_P(PaintPropertyTreeUpdateTest, Preserve3DChange) {
@@ -956,7 +968,7 @@ TEST_P(PaintPropertyTreeUpdateTest, BoxAddRemoveMask) {
EXPECT_NE(nullptr, properties->Mask());
const auto* mask_clip = properties->MaskClip();
ASSERT_NE(nullptr, mask_clip);
- EXPECT_EQ(FloatRoundedRect(8, 8, 100, 100), mask_clip->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(8, 8, 100, 100), mask_clip->UnsnappedClipRect());
target->setAttribute(html_names::kStyleAttr, "");
UpdateAllLifecyclePhasesForTest();
@@ -981,14 +993,14 @@ TEST_P(PaintPropertyTreeUpdateTest, MaskClipNodeBoxSizeChange) {
ASSERT_NE(nullptr, properties);
const auto* mask_clip = properties->MaskClip();
ASSERT_NE(nullptr, mask_clip);
- EXPECT_EQ(FloatRoundedRect(8, 8, 100, 100), mask_clip->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(8, 8, 100, 100), mask_clip->UnsnappedClipRect());
GetDocument().getElementById("target")->setAttribute(html_names::kStyleAttr,
"height: 200px");
UpdateAllLifecyclePhasesForTest();
ASSERT_EQ(mask_clip, properties->MaskClip());
- EXPECT_EQ(FloatRoundedRect(8, 8, 100, 200), mask_clip->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(8, 8, 100, 200), mask_clip->UnsnappedClipRect());
}
TEST_P(PaintPropertyTreeUpdateTest, InlineAddRemoveMask) {
@@ -1008,7 +1020,7 @@ TEST_P(PaintPropertyTreeUpdateTest, InlineAddRemoveMask) {
EXPECT_NE(nullptr, properties->Mask());
const auto* mask_clip = properties->MaskClip();
ASSERT_NE(nullptr, mask_clip);
- EXPECT_EQ(50, mask_clip->ClipRect().Rect().Width());
+ EXPECT_EQ(50, mask_clip->UnsnappedClipRect().Rect().Width());
target->setAttribute(html_names::kStyleAttr, "");
UpdateAllLifecyclePhasesForTest();
@@ -1026,14 +1038,14 @@ TEST_P(PaintPropertyTreeUpdateTest, MaskClipNodeInlineBoundsChange) {
ASSERT_NE(nullptr, properties);
const auto* mask_clip = properties->MaskClip();
ASSERT_NE(nullptr, mask_clip);
- EXPECT_EQ(50, mask_clip->ClipRect().Rect().Width());
+ EXPECT_EQ(50, mask_clip->UnsnappedClipRect().Rect().Width());
GetDocument().getElementById("img")->setAttribute(html_names::kStyleAttr,
"width: 100px");
UpdateAllLifecyclePhasesForTest();
ASSERT_EQ(mask_clip, properties->MaskClip());
- EXPECT_EQ(100, mask_clip->ClipRect().Rect().Width());
+ EXPECT_EQ(100, mask_clip->UnsnappedClipRect().Rect().Width());
}
TEST_P(PaintPropertyTreeUpdateTest, AddRemoveSVGMask) {
@@ -1058,7 +1070,7 @@ TEST_P(PaintPropertyTreeUpdateTest, AddRemoveSVGMask) {
EXPECT_NE(nullptr, properties->Mask());
const auto* mask_clip = properties->MaskClip();
ASSERT_NE(nullptr, mask_clip);
- EXPECT_EQ(FloatRoundedRect(0, 100, 100, 100), mask_clip->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(0, 100, 100, 100), mask_clip->UnsnappedClipRect());
GetDocument().getElementById("rect")->removeAttribute("mask");
UpdateAllLifecyclePhasesForTest();
@@ -1085,13 +1097,13 @@ TEST_P(PaintPropertyTreeUpdateTest, SVGMaskTargetBoundsChange) {
EXPECT_NE(nullptr, properties->Mask());
const auto* mask_clip = properties->MaskClip();
ASSERT_NE(nullptr, mask_clip);
- EXPECT_EQ(FloatRoundedRect(0, 50, 100, 150), mask_clip->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(0, 50, 100, 150), mask_clip->UnsnappedClipRect());
GetDocument().getElementById("rect")->setAttribute("width", "200");
UpdateAllLifecyclePhasesForTest();
EXPECT_NE(nullptr, properties->Effect());
EXPECT_NE(nullptr, properties->Mask());
- EXPECT_EQ(FloatRoundedRect(0, 50, 100, 150), mask_clip->ClipRect());
+ EXPECT_EQ(FloatRoundedRect(0, 50, 100, 150), mask_clip->UnsnappedClipRect());
}
TEST_P(PaintPropertyTreeUpdateTest, WillTransformChangeAboveFixed) {
@@ -1184,7 +1196,7 @@ TEST_P(PaintPropertyTreeUpdateTest, SVGViewportContainerOverflowChange) {
const auto* properties = PaintPropertiesForElement("target");
ASSERT_NE(nullptr, properties);
EXPECT_EQ(FloatRect(0, 0, 30, 40),
- properties->OverflowClip()->ClipRect().Rect());
+ properties->OverflowClip()->UnsnappedClipRect().Rect());
GetDocument().getElementById("target")->setAttribute("overflow", "visible");
UpdateAllLifecyclePhasesForTest();
@@ -1195,7 +1207,7 @@ TEST_P(PaintPropertyTreeUpdateTest, SVGViewportContainerOverflowChange) {
properties = PaintPropertiesForElement("target");
ASSERT_NE(nullptr, properties);
EXPECT_EQ(FloatRect(0, 0, 30, 40),
- properties->OverflowClip()->ClipRect().Rect());
+ properties->OverflowClip()->UnsnappedClipRect().Rect());
}
TEST_P(PaintPropertyTreeUpdateTest, SVGForeignObjectOverflowChange) {
@@ -1210,7 +1222,7 @@ TEST_P(PaintPropertyTreeUpdateTest, SVGForeignObjectOverflowChange) {
const auto* properties = PaintPropertiesForElement("target");
ASSERT_NE(nullptr, properties);
EXPECT_EQ(FloatRect(10, 20, 30, 40),
- properties->OverflowClip()->ClipRect().Rect());
+ properties->OverflowClip()->UnsnappedClipRect().Rect());
GetDocument().getElementById("target")->setAttribute("overflow", "visible");
UpdateAllLifecyclePhasesForTest();
@@ -1221,7 +1233,7 @@ TEST_P(PaintPropertyTreeUpdateTest, SVGForeignObjectOverflowChange) {
properties = PaintPropertiesForElement("target");
ASSERT_NE(nullptr, properties);
EXPECT_EQ(FloatRect(10, 20, 30, 40),
- properties->OverflowClip()->ClipRect().Rect());
+ properties->OverflowClip()->UnsnappedClipRect().Rect());
}
TEST_P(PaintPropertyTreeBuilderTest, OmitOverflowClipOnSelectionChange) {
@@ -1280,13 +1292,13 @@ TEST_P(PaintPropertyTreeUpdateTest,
EXPECT_EQ(1000000, FragmentAt(flow_thread, 0)
.PaintProperties()
->FragmentClip()
- ->ClipRect()
+ ->UnsnappedClipRect()
.Rect()
.MaxX());
EXPECT_EQ(-999950, FragmentAt(flow_thread, 1)
.PaintProperties()
->FragmentClip()
- ->ClipRect()
+ ->UnsnappedClipRect()
.Rect()
.X());
@@ -1298,13 +1310,13 @@ TEST_P(PaintPropertyTreeUpdateTest,
EXPECT_EQ(1000000, FragmentAt(flow_thread, 0)
.PaintProperties()
->FragmentClip()
- ->ClipRect()
+ ->UnsnappedClipRect()
.Rect()
.MaxX());
EXPECT_EQ(-999750, FragmentAt(flow_thread, 1)
.PaintProperties()
->FragmentClip()
- ->ClipRect()
+ ->UnsnappedClipRect()
.Rect()
.X());
}
@@ -1522,7 +1534,7 @@ TEST_P(PaintPropertyTreeUpdateTest, OverflowClipUpdateForImage) {
FloatSize corner(2, 2);
FloatRoundedRect::Radii radii(corner, corner, corner, corner);
EXPECT_EQ(FloatRoundedRect(FloatRect(8, 8, 8, 8), radii),
- properties->OverflowClip()->ClipRect());
+ properties->OverflowClip()->UnsnappedClipRect());
// We should update clip rect on border radius change.
target->setAttribute(html_names::kStyleAttr,
@@ -1532,7 +1544,7 @@ TEST_P(PaintPropertyTreeUpdateTest, OverflowClipUpdateForImage) {
ASSERT_TRUE(properties->OverflowClip());
radii.Expand(1);
EXPECT_EQ(FloatRoundedRect(FloatRect(8, 8, 8, 8), radii),
- properties->OverflowClip()->ClipRect());
+ properties->OverflowClip()->UnsnappedClipRect());
// We should update clip rect on padding change.
target->setAttribute(
@@ -1547,7 +1559,7 @@ TEST_P(PaintPropertyTreeUpdateTest, OverflowClipUpdateForImage) {
FloatRoundedRect(FloatRect(12, 9, 2, 4),
FloatRoundedRect::Radii(FloatSize(0, 2), FloatSize(1, 2),
FloatSize(), FloatSize(1, 0))),
- properties->OverflowClip()->ClipRect());
+ properties->OverflowClip()->UnsnappedClipRect());
}
TEST_P(PaintPropertyTreeUpdateTest, OverflowClipUpdateForVideo) {
@@ -1570,14 +1582,14 @@ TEST_P(PaintPropertyTreeUpdateTest, OverflowClipUpdateForVideo) {
ASSERT_TRUE(properties);
ASSERT_TRUE(properties->OverflowClip());
EXPECT_EQ(FloatRoundedRect(8, 8, 8, 8),
- properties->OverflowClip()->ClipRect());
+ properties->OverflowClip()->UnsnappedClipRect());
target->setAttribute(html_names::kStyleAttr, "object-fit: cover");
UpdateAllLifecyclePhasesForTest();
ASSERT_EQ(properties, PaintPropertiesForElement("target"));
ASSERT_TRUE(properties->OverflowClip());
EXPECT_EQ(FloatRoundedRect(8, 8, 8, 8),
- properties->OverflowClip()->ClipRect());
+ properties->OverflowClip()->UnsnappedClipRect());
// We need OverflowClip for object-fit: cover, too.
target->setAttribute(html_names::kStyleAttr, "object-fit: none");
@@ -1585,7 +1597,7 @@ TEST_P(PaintPropertyTreeUpdateTest, OverflowClipUpdateForVideo) {
ASSERT_EQ(properties, PaintPropertiesForElement("target"));
ASSERT_TRUE(properties->OverflowClip());
EXPECT_EQ(FloatRoundedRect(8, 8, 8, 8),
- properties->OverflowClip()->ClipRect());
+ properties->OverflowClip()->UnsnappedClipRect());
// We should update clip rect on padding change.
target->setAttribute(html_names::kStyleAttr,
@@ -1594,7 +1606,7 @@ TEST_P(PaintPropertyTreeUpdateTest, OverflowClipUpdateForVideo) {
ASSERT_EQ(properties, PaintPropertiesForElement("target"));
ASSERT_TRUE(properties->OverflowClip());
EXPECT_EQ(FloatRoundedRect(12, 9, 2, 4),
- properties->OverflowClip()->ClipRect());
+ properties->OverflowClip()->UnsnappedClipRect());
}
TEST_P(PaintPropertyTreeUpdateTest, ChangingClipPath) {
@@ -1690,7 +1702,8 @@ TEST_P(PaintPropertyTreeUpdateTest, ChangeDuringAnimation) {
target->SetStyle(std::move(style));
EXPECT_TRUE(target->NeedsPaintPropertyUpdate());
GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kStyleClean);
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
const auto* transform_node =
target->FirstFragment().PaintProperties()->Transform();
@@ -1718,7 +1731,8 @@ TEST_P(PaintPropertyTreeUpdateTest, ChangeDuringAnimation) {
target->SetStyle(std::move(style));
EXPECT_TRUE(target->NeedsPaintPropertyUpdate());
GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kStyleClean);
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
ASSERT_EQ(transform_node,
target->FirstFragment().PaintProperties()->Transform());
@@ -1737,7 +1751,8 @@ TEST_P(PaintPropertyTreeUpdateTest, ChangeDuringAnimation) {
target->SetStyle(std::move(style));
EXPECT_TRUE(target->NeedsPaintPropertyUpdate());
GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kStyleClean);
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
ASSERT_EQ(transform_node,
target->FirstFragment().PaintProperties()->Transform());
@@ -1756,7 +1771,8 @@ TEST_P(PaintPropertyTreeUpdateTest, BackfaceVisibilityInvalidatesProperties) {
auto* span = GetDocument().getElementById("span");
span->setAttribute(html_names::kStyleAttr, "backface-visibility: hidden;");
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(span->GetLayoutObject()->NeedsPaintPropertyUpdate());
}
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 d4c99d65d9f..6e7140526b6 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_timing.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_timing.cc
@@ -99,12 +99,6 @@ void PaintTiming::SetFirstMeaningfulPaint(
"loading,rail,devtools.timeline", "firstMeaningfulPaint", swap_stamp,
"frame", ToTraceValue(GetFrame()), "afterUserInput", had_input);
- InteractiveDetector* interactive_detector(
- InteractiveDetector::From(*GetSupplementable()));
- if (interactive_detector) {
- interactive_detector->OnFirstMeaningfulPaintDetected(swap_stamp, had_input);
- }
-
// Notify FMP for UMA only if there's no user input before FMP, so that layout
// changes caused by user interactions wouldn't be considered as FMP.
if (had_input == FirstMeaningfulPaintDetector::kNoUserInput) {
@@ -129,7 +123,7 @@ void PaintTiming::SetTickClockForTesting(const base::TickClock* clock) {
clock_ = clock;
}
-void PaintTiming::Trace(blink::Visitor* visitor) {
+void PaintTiming::Trace(Visitor* visitor) {
visitor->Trace(fmp_detector_);
Supplement<Document>::Trace(visitor);
}
@@ -190,11 +184,11 @@ void PaintTiming::RegisterNotifySwapTime(PaintEvent event,
}
void PaintTiming::ReportSwapTime(PaintEvent event,
- WebWidgetClient::SwapResult result,
+ WebSwapResult result,
base::TimeTicks timestamp) {
DCHECK(IsMainThread());
// If the swap fails for any reason, we use the timestamp when the SwapPromise
- // was broken. |result| == WebWidgetClient::SwapResult::kDidNotSwapSwapFails
+ // was broken. |result| == WebSwapResult::kDidNotSwapSwapFails
// usually means the compositor decided not swap because there was no actual
// damage, which can happen when what's being painted isn't visible. In this
// case, the timestamp will be consistent with the case where the swap
@@ -246,6 +240,11 @@ void PaintTiming::SetFirstContentfulPaintSwap(base::TimeTicks stamp) {
GetFrame()->Loader().Progress().DidFirstContentfulPaint();
NotifyPaintTimingChanged();
fmp_detector_->NotifyFirstContentfulPaint(first_contentful_paint_swap_);
+ InteractiveDetector* interactive_detector =
+ InteractiveDetector::From(*GetSupplementable());
+ if (interactive_detector) {
+ interactive_detector->OnFirstContentfulPaint(first_contentful_paint_swap_);
+ }
}
void PaintTiming::SetFirstImagePaintSwap(base::TimeTicks stamp) {
@@ -256,12 +255,12 @@ void PaintTiming::SetFirstImagePaintSwap(base::TimeTicks stamp) {
NotifyPaintTimingChanged();
}
-void PaintTiming::ReportSwapResultHistogram(
- WebWidgetClient::SwapResult result) {
- DEFINE_STATIC_LOCAL(EnumerationHistogram, did_swap_histogram,
- ("PageLoad.Internal.Renderer.PaintTiming.SwapResult",
- WebWidgetClient::SwapResult::kSwapResultMax));
- did_swap_histogram.Count(result);
+void PaintTiming::ReportSwapResultHistogram(WebSwapResult result) {
+ DEFINE_STATIC_LOCAL(
+ EnumerationHistogram, did_swap_histogram,
+ ("PageLoad.Internal.Renderer.PaintTiming.SwapResult",
+ static_cast<uint32_t>(WebSwapResult::kSwapResultLast) + 1));
+ did_swap_histogram.Count(static_cast<uint32_t>(result));
}
} // 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 ffb1ae2133f..61e4358f997 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_timing.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_timing.h
@@ -8,7 +8,7 @@
#include <memory>
#include "base/macros.h"
-#include "third_party/blink/public/web/web_widget_client.h"
+#include "third_party/blink/public/web/web_swap_result.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h"
#include "third_party/blink/renderer/core/paint/paint_event.h"
@@ -31,8 +31,7 @@ class CORE_EXPORT PaintTiming final : public GarbageCollected<PaintTiming>,
USING_GARBAGE_COLLECTED_MIXIN(PaintTiming);
friend class FirstMeaningfulPaintDetector;
using ReportTimeCallback =
- WTF::CrossThreadOnceFunction<void(WebWidgetClient::SwapResult,
- base::TimeTicks)>;
+ WTF::CrossThreadOnceFunction<void(WebSwapResult, base::TimeTicks)>;
public:
static const char kSupplementName[];
@@ -99,16 +98,14 @@ class CORE_EXPORT PaintTiming final : public GarbageCollected<PaintTiming>,
}
void RegisterNotifySwapTime(PaintEvent, ReportTimeCallback);
- void ReportSwapTime(PaintEvent,
- WebWidgetClient::SwapResult,
- base::TimeTicks timestamp);
+ void ReportSwapTime(PaintEvent, WebSwapResult, base::TimeTicks timestamp);
- void ReportSwapResultHistogram(WebWidgetClient::SwapResult);
+ void ReportSwapResultHistogram(WebSwapResult);
// The caller owns the |clock| which must outlive the PaintTiming.
void SetTickClockForTesting(const base::TickClock* clock);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
LocalFrame* GetFrame() const;
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 8c16c5fc6ce..a5940c4d407 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
@@ -3,7 +3,8 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/core/paint/paint_timing_detector.h"
-#include "third_party/blink/public/platform/web_input_event.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
+#include "third_party/blink/public/platform/web_float_rect.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/frame/local_frame_view.h"
@@ -21,13 +22,16 @@
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/text_paint_timing_detector.h"
#include "third_party/blink/renderer/core/style/style_fetched_image.h"
+#include "third_party/blink/renderer/core/svg/graphics/svg_image.h"
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
+#include "third_party/blink/renderer/platform/graphics/bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
#include "third_party/blink/renderer/platform/graphics/paint/float_clip_rect.h"
#include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h"
#include "third_party/blink/renderer/platform/graphics/paint/property_tree_state.h"
#include "third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_properties.h"
+#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -45,19 +49,22 @@ bool IsBackgroundImageContentful(const LayoutObject& object,
const Image& image) {
// Background images attached to <body> or <html> are likely for background
// purpose, so we rule them out.
- if (object.IsLayoutView() || object.IsBody() || object.IsDocumentElement()) {
+ if (IsA<LayoutView>(object) || object.IsBody() ||
+ object.IsDocumentElement()) {
return false;
}
// Generated images are excluded here, as they are likely to serve for
// background purpose.
- if (!image.IsBitmapImage() && !image.IsStaticBitmapImage() &&
- !image.IsSVGImage() && !image.IsPlaceholderImage())
+ if (!IsA<BitmapImage>(image) && !IsA<StaticBitmapImage>(image) &&
+ !IsA<SVGImage>(image) && !image.IsPlaceholderImage())
return false;
return true;
}
} // namespace
+bool IgnorePaintTimingScope::should_ignore_ = false;
+
PaintTimingDetector::PaintTimingDetector(LocalFrameView* frame_view)
: frame_view_(frame_view),
text_paint_timing_detector_(
@@ -99,7 +106,11 @@ void PaintTimingDetector::NotifyBackgroundImagePaint(
const Node* node,
const Image* image,
const StyleFetchedImage* style_image,
- const PropertyTreeState& current_paint_chunk_properties) {
+ const PropertyTreeState& current_paint_chunk_properties,
+ const IntRect& image_border) {
+ if (IgnorePaintTimingScope::ShouldIgnore())
+ return;
+
DCHECK(image);
DCHECK(style_image->CachedImage());
if (!node)
@@ -117,7 +128,7 @@ void PaintTimingDetector::NotifyBackgroundImagePaint(
return;
detector.GetImagePaintTimingDetector()->RecordImage(
*object, image->Size(), *style_image->CachedImage(),
- current_paint_chunk_properties, style_image);
+ current_paint_chunk_properties, style_image, &image_border);
}
// static
@@ -126,6 +137,9 @@ void PaintTimingDetector::NotifyImagePaint(
const IntSize& intrinsic_size,
const ImageResourceContent* cached_image,
const PropertyTreeState& current_paint_chunk_properties) {
+ if (IgnorePaintTimingScope::ShouldIgnore())
+ return;
+
LocalFrameView* frame_view = object.GetFrameView();
if (!frame_view)
return;
@@ -136,7 +150,7 @@ void PaintTimingDetector::NotifyImagePaint(
return;
detector.GetImagePaintTimingDetector()->RecordImage(
object, intrinsic_size, *cached_image, current_paint_chunk_properties,
- nullptr);
+ nullptr, nullptr);
}
void PaintTimingDetector::NotifyImageFinished(
@@ -162,8 +176,11 @@ void PaintTimingDetector::NotifyImageRemoved(
}
}
-void PaintTimingDetector::StopRecordingLargestContentfulPaint() {
- DCHECK(frame_view_);
+void PaintTimingDetector::OnInputOrScroll() {
+ // If we have already stopped, then abort.
+ if (!is_recording_largest_contentful_paint_)
+ return;
+
// TextPaintTimingDetector is used for both Largest Contentful Paint and for
// Element Timing. Therefore, here we only want to stop recording Largest
// Contentful Paint.
@@ -173,21 +190,29 @@ void PaintTimingDetector::StopRecordingLargestContentfulPaint() {
if (image_paint_timing_detector_)
image_paint_timing_detector_->StopRecordEntries();
largest_contentful_paint_calculator_ = nullptr;
+
+ DCHECK_EQ(first_input_or_scroll_notified_timestamp_, base::TimeTicks());
+ first_input_or_scroll_notified_timestamp_ = base::TimeTicks::Now();
+ DidChangePerformanceTiming();
+ is_recording_largest_contentful_paint_ = false;
}
void PaintTimingDetector::NotifyInputEvent(WebInputEvent::Type type) {
+ // A single keyup event should be ignored. It could be caused by user actions
+ // such as refreshing via Ctrl+R.
if (type == WebInputEvent::kMouseMove || type == WebInputEvent::kMouseEnter ||
- type == WebInputEvent::kMouseLeave ||
+ type == WebInputEvent::kMouseLeave || type == WebInputEvent::kKeyUp ||
WebInputEvent::IsPinchGestureEventType(type)) {
return;
}
- StopRecordingLargestContentfulPaint();
+ OnInputOrScroll();
}
-void PaintTimingDetector::NotifyScroll(ScrollType scroll_type) {
- if (scroll_type != kUserScroll && scroll_type != kCompositorScroll)
+void PaintTimingDetector::NotifyScroll(mojom::blink::ScrollType scroll_type) {
+ if (scroll_type != mojom::blink::ScrollType::kUser &&
+ scroll_type != mojom::blink::ScrollType::kCompositor)
return;
- StopRecordingLargestContentfulPaint();
+ OnInputOrScroll();
}
bool PaintTimingDetector::NeedToNotifyInputOrScroll() const {
@@ -332,6 +357,9 @@ ScopedPaintTimingDetectorBlockPaintHook*
void ScopedPaintTimingDetectorBlockPaintHook::EmplaceIfNeeded(
const LayoutBoxModelObject& aggregator,
const PropertyTreeState& property_tree_state) {
+ if (IgnorePaintTimingScope::ShouldIgnore())
+ return;
+
// |reset_top_| is unset when |aggregator| is anonymous so that each
// aggregation corresponds to an element. See crbug.com/988593. When set,
// |top_| becomes |this|, and |top_| is restored to the previous value when
@@ -402,7 +430,7 @@ void PaintTimingCallbackManagerImpl::
void PaintTimingCallbackManagerImpl::ReportPaintTime(
std::unique_ptr<PaintTimingCallbackManager::CallbackQueue> frame_callbacks,
- WebWidgetClient::SwapResult result,
+ WebSwapResult result,
base::TimeTicks paint_time) {
while (!frame_callbacks->empty()) {
std::move(frame_callbacks->front()).Run(paint_time);
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 f27a0e04ce2..82391ba7022 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
@@ -5,8 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_TIMING_DETECTOR_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_TIMING_DETECTOR_H_
-#include "third_party/blink/public/platform/web_input_event.h"
-#include "third_party/blink/public/web/web_widget_client.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
+#include "third_party/blink/public/web/web_swap_result.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/layout_box_model_object.h"
#include "third_party/blink/renderer/core/paint/paint_timing_visualizer.h"
@@ -86,7 +86,7 @@ class PaintTimingCallbackManagerImpl final
void ReportPaintTime(
std::unique_ptr<std::queue<
PaintTimingCallbackManager::LocalThreadCallback>> frame_callbacks,
- WebWidgetClient::SwapResult,
+ WebSwapResult,
base::TimeTicks paint_time);
void Trace(Visitor* visitor) override;
@@ -124,7 +124,8 @@ class CORE_EXPORT PaintTimingDetector
const Node*,
const Image*,
const StyleFetchedImage*,
- const PropertyTreeState& current_paint_chunk_properties);
+ const PropertyTreeState& current_paint_chunk_properties,
+ const IntRect& image_border);
static void NotifyImagePaint(
const LayoutObject&,
const IntSize& intrinsic_size,
@@ -138,7 +139,7 @@ class CORE_EXPORT PaintTimingDetector
void NotifyPaintFinished();
void NotifyInputEvent(WebInputEvent::Type);
bool NeedToNotifyInputOrScroll() const;
- void NotifyScroll(ScrollType);
+ void NotifyScroll(mojom::blink::ScrollType);
// The returned value indicates whether the candidates have changed.
bool NotifyIfChangedLargestImagePaint(base::TimeTicks, uint64_t size);
bool NotifyIfChangedLargestTextPaint(base::TimeTicks, uint64_t size);
@@ -171,6 +172,9 @@ 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_; }
+ base::TimeTicks FirstInputOrScrollNotifiedTimestamp() const {
+ return first_input_or_scroll_notified_timestamp_;
+ }
void UpdateLargestContentfulPaintCandidate();
@@ -178,7 +182,8 @@ class CORE_EXPORT PaintTimingDetector
void Trace(Visitor* visitor);
private:
- void StopRecordingLargestContentfulPaint();
+ // Method called to stop recording the Largest Contentful Paint.
+ void OnInputOrScroll();
bool HasLargestImagePaintChanged(base::TimeTicks, uint64_t size) const;
bool HasLargestTextPaintChanged(base::TimeTicks, uint64_t size) const;
Member<LocalFrameView> frame_view_;
@@ -188,7 +193,14 @@ class CORE_EXPORT PaintTimingDetector
// image paint is found.
Member<ImagePaintTimingDetector> image_paint_timing_detector_;
+ // This member lives for as long as the largest contentful paint is being
+ // computed. However, it is initialized lazily, so it may be nullptr because
+ // it has not yet been initialized or because we have stopped computing LCP.
Member<LargestContentfulPaintCalculator> largest_contentful_paint_calculator_;
+ // Time at which the first input or scroll is notified to PaintTimingDetector,
+ // hence causing LCP to stop being recorded. This is the same time at which
+ // |largest_contentful_paint_calculator_| is set to nullptr.
+ base::TimeTicks first_input_or_scroll_notified_timestamp_;
Member<PaintTimingCallbackManagerImpl> callback_manager_;
@@ -200,6 +212,7 @@ class CORE_EXPORT PaintTimingDetector
// Largest text information.
base::TimeTicks largest_text_paint_time_;
uint64_t largest_text_paint_size_ = 0;
+ bool is_recording_largest_contentful_paint_ = true;
};
// Largest Text Paint and Text Element Timing aggregate text nodes by these
@@ -251,7 +264,7 @@ class ScopedPaintTimingDetectorBlockPaintHook {
const LayoutBoxModelObject& aggregator_;
const PropertyTreeState& property_tree_state_;
- Member<TextPaintTimingDetector> detector_;
+ TextPaintTimingDetector* detector_;
IntRect aggregated_visual_rect_;
};
base::Optional<Data> data_;
@@ -260,9 +273,27 @@ class ScopedPaintTimingDetectorBlockPaintHook {
DISALLOW_COPY_AND_ASSIGN(ScopedPaintTimingDetectorBlockPaintHook);
};
+// Creates a scope to ignore paint timing, e.g. when we are painting contents
+// under opacity:0.
+class IgnorePaintTimingScope {
+ STACK_ALLOCATED();
+
+ public:
+ IgnorePaintTimingScope() : auto_reset_(&should_ignore_, true) {}
+ ~IgnorePaintTimingScope() = default;
+
+ static bool ShouldIgnore() { return should_ignore_; }
+
+ private:
+ base::AutoReset<bool> auto_reset_;
+ static bool should_ignore_;
+};
+
// static
inline void PaintTimingDetector::NotifyTextPaint(
const IntRect& text_visual_rect) {
+ if (IgnorePaintTimingScope::ShouldIgnore())
+ return;
ScopedPaintTimingDetectorBlockPaintHook::AggregateTextPaint(text_visual_rect);
}
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 91577fd6474..4fffe2ebb46 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
@@ -16,6 +16,9 @@
#include "third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.h"
#include "third_party/blink/renderer/core/layout/layout_shift_tracker.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_fragment_child_iterator.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.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/compositing/composited_layer_mapping.h"
@@ -28,6 +31,42 @@
namespace blink {
+namespace {
+
+// Locate or/and set up the current FragmentData object. This may involve
+// creating it, or resetting an existing one. If |allow_reset| is set, we're
+// allowed to clear old FragmentData objects.
+NGPrePaintInfo SetupFragmentData(const NGFragmentChildIterator& iterator,
+ bool allow_reset) {
+ DCHECK(iterator->GetLayoutObject());
+ const LayoutObject& object = *iterator->GetLayoutObject();
+ FragmentData* fragment_data = &object.GetMutableForPainting().FirstFragment();
+ // TODO(crbug.com/1043787): Add support for block fragmentation. Furthermore,
+ // what's here is mostly gross, and we need to come up with something
+ // better. The way FragmentData works (and is stored) vs. the way
+ // NGPhysicalFragment works is less than ideal.
+ fragment_data->ClearNextFragment();
+ if (const NGFragmentItem* fragment_item = iterator->FragmentItem()) {
+ // We're in an inline formatting context.
+ if (fragment_item->IsFirstForNode()) {
+ // This is the first fragment generated for the node (i.e. we're on the
+ // first line and first fragmentainer (column) that this node occurs
+ // in). Now is our chance to reset everything (the number or size of
+ // fragments may have changed since last time). All the other fragments
+ // will be visited in due course.
+ if (allow_reset && !object.IsBox()) {
+ // For text and non-atomic inlines we now reset the visual rect. The
+ // visual rect will be set and expanded, as we visit each individual
+ // fragment.
+ fragment_data->SetVisualRect(IntRect());
+ }
+ }
+ }
+ return NGPrePaintInfo(iterator, *fragment_data);
+}
+
+} // anonymous namespace
+
void PrePaintTreeWalk::WalkTree(LocalFrameView& root_frame_view) {
if (root_frame_view.ShouldThrottleRendering()) {
// Skip the throttled frame. Will update it when it becomes unthrottled.
@@ -135,7 +174,7 @@ void PrePaintTreeWalk::Walk(LocalFrameView& frame_view) {
}
#endif
- Walk(*view);
+ Walk(*view, /* iterator */ nullptr);
#if DCHECK_IS_ON()
view->AssertSubtreeClearedPaintInvalidationFlags();
#endif
@@ -167,7 +206,7 @@ bool HasBlockingTouchEventHandler(const LocalFrame& frame,
}
bool HasBlockingTouchEventHandler(const LayoutObject& object) {
- if (object.IsLayoutView()) {
+ if (IsA<LayoutView>(object)) {
auto* frame = object.GetFrame();
if (HasBlockingTouchEventHandler(*frame, *frame->DomWindow()))
return true;
@@ -312,10 +351,23 @@ void PrePaintTreeWalk::CheckTreeBuilderContextState(
}
void PrePaintTreeWalk::WalkInternal(const LayoutObject& object,
+ const NGFragmentChildIterator* iterator,
PrePaintTreeWalkContext& context) {
PaintInvalidatorContext& paint_invalidator_context =
context.paint_invalidator_context;
+ base::Optional<NGPrePaintInfo> pre_paint_info_storage;
+ NGPrePaintInfo* pre_paint_info = nullptr;
+ if (iterator) {
+ bool allow_reset = context.tree_builder_context.has_value()
+#if DCHECK_IS_ON()
+ && context.tree_builder_context->is_actually_needed
+#endif
+ ;
+ pre_paint_info_storage.emplace(SetupFragmentData(*iterator, allow_reset));
+ pre_paint_info = &pre_paint_info_storage.value();
+ }
+
// This must happen before updatePropertiesForSelf, because the latter reads
// some of the state computed here.
UpdateAuxiliaryObjectProperties(object, context);
@@ -324,7 +376,9 @@ void PrePaintTreeWalk::WalkInternal(const LayoutObject& object,
PaintPropertyChangeType property_changed =
PaintPropertyChangeType::kUnchanged;
if (context.tree_builder_context) {
- property_tree_builder.emplace(object, *context.tree_builder_context);
+ property_tree_builder.emplace(object, pre_paint_info,
+ *context.tree_builder_context);
+
property_changed =
std::max(property_changed, property_tree_builder->UpdateForSelf());
@@ -341,7 +395,8 @@ void PrePaintTreeWalk::WalkInternal(const LayoutObject& object,
UpdateEffectiveAllowedTouchAction(object, context);
if (paint_invalidator_.InvalidatePaint(
- object, base::OptionalOrNullptr(context.tree_builder_context),
+ object, pre_paint_info,
+ base::OptionalOrNullptr(context.tree_builder_context),
paint_invalidator_context))
needs_invalidate_chrome_client_ = true;
@@ -389,6 +444,8 @@ void PrePaintTreeWalk::WalkInternal(const LayoutObject& object,
if (context.clip_changed && object.HasLayer())
ToLayoutBoxModelObject(object).Layer()->SetNeedsRepaint();
+ // TODO(crbug.com/1058792): Allow multiple fragments for composited elements
+ // (passing |iterator| here is probably part of the solution).
CompositingLayerPropertyUpdater::Update(object);
}
@@ -403,7 +460,140 @@ LocalFrameView* FindWebViewPluginContentFrameView(
return nullptr;
}
-void PrePaintTreeWalk::Walk(const LayoutObject& object) {
+void PrePaintTreeWalk::WalkNGChildren(const LayoutObject* parent,
+ NGFragmentChildIterator* iterator) {
+ for (; !iterator->IsAtEnd(); iterator->Advance()) {
+ const LayoutObject* object = (*iterator)->GetLayoutObject();
+ if (const auto* fragment_item = (*iterator)->FragmentItem()) {
+ // Line boxes are not interesting. They have no paint effects. Descend
+ // directly into children.
+ bool descend_directly = fragment_item->Type() == NGFragmentItem::kLine;
+ if (!descend_directly && fragment_item->IsInlineBox() &&
+ !fragment_item->BoxFragment()) {
+ // Likewise for culled inlines.
+ descend_directly = true;
+ object->GetMutableForPainting().ClearPaintFlags();
+ }
+ if (descend_directly) {
+ WalkChildren(/* parent */ nullptr, iterator);
+ continue;
+ }
+ }
+ DCHECK(object);
+ Walk(*object, iterator);
+ }
+}
+
+void PrePaintTreeWalk::WalkLegacyChildren(const LayoutObject& object) {
+ if (const LayoutBox* layout_box = ToLayoutBoxOrNull(&object)) {
+ if (layout_box->CanTraversePhysicalFragments()) {
+ // Enter NG child fragment traversal. We'll stay in this mode for all
+ // descendants that support fragment traversal. We'll re-enter
+ // LayoutObject traversal for descendants that don't support it. This only
+ // works correctly if we're not block-fragmented, though, so DCHECK for
+ // that.
+ DCHECK_EQ(layout_box->PhysicalFragmentCount(), 1u);
+ const NGPhysicalBoxFragment& fragment =
+ To<NGPhysicalBoxFragment>(*layout_box->GetPhysicalFragment(0));
+ NGFragmentChildIterator child_iterator(fragment);
+ WalkNGChildren(&object, &child_iterator);
+ return;
+ }
+ }
+
+ for (const LayoutObject* child = object.SlowFirstChild(); child;
+ child = child->NextSibling()) {
+ if (child->IsLayoutMultiColumnSpannerPlaceholder()) {
+ child->GetMutableForPainting().ClearPaintFlags();
+ continue;
+ }
+ Walk(*child, /* iterator */ nullptr);
+ }
+
+ if (!RuntimeEnabledFeatures::LayoutNGFragmentTraversalEnabled())
+ return;
+
+ const LayoutBlock* block = DynamicTo<LayoutBlock>(&object);
+ if (!block)
+ return;
+ const auto* positioned_objects = block->PositionedObjects();
+ if (!positioned_objects)
+ return;
+
+ // If we have performed NG fragment traversal in any part of the subtree, we
+ // may have missed certain out-of-flow positioned objects. LayoutNG fragments
+ // are always children of their containing block, while the structure of the
+ // LayoutObject tree corresponds more closely to that of the DOM tree.
+ //
+ // Example: if we assume that flexbox isn't natively supported in LayoutNG:
+ //
+ // <div id="flex" style="display:flex; position:relative;">
+ // <div id="flexitem">
+ // <div id="abs" style="position:absolute;"></div>
+ // <div id="regular"></div>
+ //
+ // If we let |object| be #flex, it will be handled by legacy LayoutObject
+ // traversal, while #flexitem, on the other hand, can traverse its NG child
+ // fragments. However, #regular will be the only child fragment of #flexitem,
+ // since the containing block for #abs is #flex. So we'd miss it, unless we
+ // walk it now.
+ for (const LayoutBox* box : *positioned_objects) {
+ // It's important that objects that have already been walked be left alone.
+ // Otherwise, we might calculate the wrong offsets (and overwrite the
+ // correct ones) in case of out-of-flow positioned objects whose containing
+ // block is a relatively positioned non-atomic inline (such objects will
+ // already have been properly walked, since we don't switch engines within
+ // an inline formatting context). Put differently, the code here will only
+ // do the right thing if |object| is truly the containing block of the
+ // positioned objects in its list (which isn't the case if the containing
+ // block is a non-atomic inline).
+ if (!ObjectRequiresPrePaint(*box) &&
+ !ObjectRequiresTreeBuilderContext(*box))
+ continue;
+ DCHECK_EQ(box->Container(), &object);
+ Walk(*box, /* iterator */ nullptr);
+ }
+}
+
+void PrePaintTreeWalk::WalkChildren(const LayoutObject* object,
+ const NGFragmentChildIterator* iterator) {
+ DCHECK(iterator || object);
+
+ if (!iterator) {
+ // We're not doing LayoutNG fragment traversal of this object.
+ WalkLegacyChildren(*object);
+ return;
+ }
+
+ // If we are performing LayoutNG fragment traversal, but this object doesn't
+ // support that, we need to switch back to legacy LayoutObject traversal for
+ // its children. We're then also assuming that we're either not
+ // block-fragmenting, or that this is monolithic content. We may re-enter
+ // LayoutNG fragment traversal if we get to a descendant that supports that.
+ if (object && !object->CanTraversePhysicalFragments()) {
+ DCHECK(
+ !object->FlowThreadContainingBlock() ||
+ (object->IsBox() && ToLayoutBox(object)->GetPaginationBreakability() ==
+ LayoutBox::kForbidBreaks));
+ WalkLegacyChildren(*object);
+ return;
+ }
+
+ // Traverse child NG fragments.
+ NGFragmentChildIterator child_iterator(iterator->Descend());
+ WalkNGChildren(object, &child_iterator);
+}
+
+void PrePaintTreeWalk::Walk(const LayoutObject& object,
+ const NGFragmentChildIterator* iterator) {
+ const NGPhysicalBoxFragment* physical_fragment = nullptr;
+ bool is_last_fragment = true;
+ if (iterator) {
+ physical_fragment = (*iterator)->BoxFragment();
+ if (const auto* fragment_item = (*iterator)->FragmentItem())
+ is_last_fragment = fragment_item->IsLastForNode();
+ }
+
// We need to be careful not to have a reference to the parent context, since
// this reference will be to the context_storage_ memory which may be
// reallocated during this function call.
@@ -447,8 +637,10 @@ void PrePaintTreeWalk::Walk(const LayoutObject& object) {
context().tree_builder_context->clip_changed = false;
}
- WalkInternal(object, context());
- object.NotifyDisplayLockDidPrePaint(DisplayLockLifecycleTarget::kSelf);
+ WalkInternal(object, iterator, context());
+
+ if (is_last_fragment)
+ object.NotifyDisplayLockDidPrePaint(DisplayLockLifecycleTarget::kSelf);
bool child_walk_blocked = object.PrePaintBlockedByDisplayLock(
DisplayLockLifecycleTarget::kChildren);
@@ -469,14 +661,7 @@ void PrePaintTreeWalk::Walk(const LayoutObject& object) {
}
if (!child_walk_blocked) {
- for (const LayoutObject* child = object.SlowFirstChild(); child;
- child = child->NextSibling()) {
- if (child->IsLayoutMultiColumnSpannerPlaceholder()) {
- child->GetMutableForPainting().ClearPaintFlags();
- continue;
- }
- Walk(*child);
- }
+ WalkChildren(&object, iterator);
if (object.IsLayoutEmbeddedContent()) {
const LayoutEmbeddedContent& layout_embedded_content =
@@ -505,8 +690,8 @@ void PrePaintTreeWalk::Walk(const LayoutObject& object) {
object.NotifyDisplayLockDidPrePaint(DisplayLockLifecycleTarget::kChildren);
}
-
- object.GetMutableForPainting().ClearPaintFlags();
+ if (is_last_fragment)
+ object.GetMutableForPainting().ClearPaintFlags();
context_storage_.pop_back();
}
diff --git a/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h b/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h
index fa95f4bd2fe..5ded2b4f51c 100644
--- a/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h
+++ b/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h
@@ -14,6 +14,7 @@ namespace blink {
class LayoutObject;
class LocalFrameView;
+class NGFragmentChildIterator;
// This class walks the whole layout tree, beginning from the root
// LocalFrameView, across frame boundaries. Helper classes are called for each
@@ -101,8 +102,13 @@ class CORE_EXPORT PrePaintTreeWalk {
// very big stack frames. Splitting the heavy lifting to a separate function
// makes sure the stack frame is freed prior to making a recursive call.
// See https://crbug.com/781301 .
- NOINLINE void WalkInternal(const LayoutObject&, PrePaintTreeWalkContext&);
- void Walk(const LayoutObject&);
+ NOINLINE void WalkInternal(const LayoutObject&,
+ const NGFragmentChildIterator*,
+ PrePaintTreeWalkContext&);
+ void WalkNGChildren(const LayoutObject* parent, NGFragmentChildIterator*);
+ void WalkLegacyChildren(const LayoutObject&);
+ void WalkChildren(const LayoutObject*, const NGFragmentChildIterator*);
+ void Walk(const LayoutObject&, const NGFragmentChildIterator*);
bool NeedsTreeBuilderContextUpdate(const LocalFrameView&,
const PrePaintTreeWalkContext&);
diff --git a/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk_test.cc b/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk_test.cc
index b49316436fa..3665e2c0f48 100644
--- a/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk_test.cc
@@ -164,7 +164,8 @@ TEST_P(PrePaintTreeWalkTest, ClearSubsequenceCachingClipChange) {
EXPECT_FALSE(child_paint_layer->NeedsPaintPhaseFloat());
parent->setAttribute(html_names::kClassAttr, "clip");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(child_paint_layer->SelfNeedsRepaint());
}
@@ -190,7 +191,8 @@ TEST_P(PrePaintTreeWalkTest, ClearSubsequenceCachingClipChange2DTransform) {
EXPECT_FALSE(child_paint_layer->NeedsPaintPhaseFloat());
parent->setAttribute(html_names::kClassAttr, "clip");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(child_paint_layer->SelfNeedsRepaint());
}
@@ -219,7 +221,8 @@ TEST_P(PrePaintTreeWalkTest, ClearSubsequenceCachingClipChangePosAbs) {
// This changes clips for absolute-positioned descendants of "child" but not
// normal-position ones, which are already clipped to 50x50.
parent->setAttribute(html_names::kClassAttr, "clip");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(child_paint_layer->SelfNeedsRepaint());
}
@@ -248,7 +251,8 @@ TEST_P(PrePaintTreeWalkTest, ClearSubsequenceCachingClipChangePosFixed) {
// This changes clips for absolute-positioned descendants of "child" but not
// normal-position ones, which are already clipped to 50x50.
parent->setAttribute(html_names::kClassAttr, "clip");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(child_paint_layer->SelfNeedsRepaint());
}
@@ -272,7 +276,8 @@ TEST_P(PrePaintTreeWalkTest, ClipChangeRepaintsDescendants) {
)HTML");
GetDocument().getElementById("parent")->removeAttribute("style");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
auto* greatgrandchild = GetLayoutObjectByElementId("greatgrandchild");
auto* paint_layer = ToLayoutBoxModelObject(greatgrandchild)->Layer();
@@ -320,7 +325,8 @@ TEST_P(PrePaintTreeWalkTest, ClipChangeHasRadius) {
auto* target = GetDocument().getElementById("target");
auto* target_object = ToLayoutBoxModelObject(target->GetLayoutObject());
target->setAttribute(html_names::kStyleAttr, "border-radius: 5px");
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_TRUE(target_object->Layer()->SelfNeedsRepaint());
// And should not trigger any assert failure.
UpdateAllLifecyclePhasesForTest();
@@ -413,7 +419,8 @@ TEST_P(PrePaintTreeWalkTest, EffectiveTouchActionStyleUpdate) {
GetDocument()
.getElementById("touchaction")
->setAttribute(html_names::kClassAttr, "touchaction");
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
EXPECT_FALSE(ancestor.EffectiveAllowedTouchActionChanged());
EXPECT_TRUE(touchaction.EffectiveAllowedTouchActionChanged());
EXPECT_FALSE(descendant.EffectiveAllowedTouchActionChanged());
diff --git a/chromium/third_party/blink/renderer/core/paint/replaced_painter.cc b/chromium/third_party/blink/renderer/core/paint/replaced_painter.cc
index 133aa11e6d4..47048c35bf9 100644
--- a/chromium/third_party/blink/renderer/core/paint/replaced_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/replaced_painter.cc
@@ -141,11 +141,11 @@ void ReplacedPainter::Paint(const PaintInfo& paint_info) {
}
if (local_paint_info.phase != PaintPhase::kForeground &&
- local_paint_info.phase != PaintPhase::kSelection &&
+ local_paint_info.phase != PaintPhase::kSelectionDragImage &&
!layout_replaced_.CanHaveChildren())
return;
- if (local_paint_info.phase == PaintPhase::kSelection &&
+ if (local_paint_info.phase == PaintPhase::kSelectionDragImage &&
!layout_replaced_.IsSelected())
return;
@@ -200,7 +200,7 @@ bool ReplacedPainter::ShouldPaint(const ScopedPaintState& paint_state) const {
if (paint_info.phase != PaintPhase::kForeground &&
paint_info.phase != PaintPhase::kForcedColorsModeBackplate &&
!ShouldPaintSelfOutline(paint_info.phase) &&
- paint_info.phase != PaintPhase::kSelection &&
+ paint_info.phase != PaintPhase::kSelectionDragImage &&
paint_info.phase != PaintPhase::kMask &&
!ShouldPaintSelfBlockBackground(paint_info.phase))
return false;
diff --git a/chromium/third_party/blink/renderer/core/paint/scoped_paint_state.cc b/chromium/third_party/blink/renderer/core/paint/scoped_paint_state.cc
index 759d8bd72f7..c7ef1d33d18 100644
--- a/chromium/third_party/blink/renderer/core/paint/scoped_paint_state.cc
+++ b/chromium/third_party/blink/renderer/core/paint/scoped_paint_state.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/paint/scoped_paint_state.h"
#include "third_party/blink/renderer/core/layout/layout_replaced.h"
+#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/paint/box_model_object_painter.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
@@ -74,7 +75,7 @@ void ScopedBoxContentsPaintState::AdjustForBoxContents(const LayoutBox& box) {
// with a smaller cull rect, and the scrolling document contents are under the
// layer of document element which will use infinite cull rect calculated in
// PaintLayerPainter::AdjustForPaintProperties().
- if (box.IsLayoutView() && input_paint_info_.GetCullRect().IsInfinite())
+ if (IsA<LayoutView>(box) && input_paint_info_.GetCullRect().IsInfinite())
return;
adjusted_paint_info_.emplace(input_paint_info_);
diff --git a/chromium/third_party/blink/renderer/core/paint/scoped_paint_state.h b/chromium/third_party/blink/renderer/core/paint/scoped_paint_state.h
index 158e6727141..97bf34b9272 100644
--- a/chromium/third_party/blink/renderer/core/paint/scoped_paint_state.h
+++ b/chromium/third_party/blink/renderer/core/paint/scoped_paint_state.h
@@ -28,9 +28,10 @@ class ScopedPaintState {
STACK_ALLOCATED();
public:
- ScopedPaintState(const LayoutObject& object, const PaintInfo& paint_info)
- : fragment_to_paint_(paint_info.FragmentToPaint(object)),
- input_paint_info_(paint_info) {
+ ScopedPaintState(const LayoutObject& object,
+ const PaintInfo& paint_info,
+ const FragmentData* fragment_data)
+ : fragment_to_paint_(fragment_data), input_paint_info_(paint_info) {
if (!fragment_to_paint_) {
// The object has nothing to paint in the current fragment.
// TODO(wangxianzhu): Use DCHECK(fragment_to_paint_) in PaintOffset()
@@ -55,9 +56,16 @@ class ScopedPaintState {
}
}
+ ScopedPaintState(const LayoutObject& object, const PaintInfo& paint_info)
+ : ScopedPaintState(object,
+ paint_info,
+ paint_info.FragmentToPaint(object)) {}
+
ScopedPaintState(const NGPhysicalFragment& fragment,
const PaintInfo& paint_info)
- : ScopedPaintState(*fragment.GetLayoutObject(), paint_info) {}
+ : ScopedPaintState(*fragment.GetLayoutObject(),
+ paint_info,
+ paint_info.FragmentToPaint(fragment)) {}
~ScopedPaintState() {
if (paint_offset_translation_as_drawing_)
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 e293f0caa1d..cf1ec8de0e0 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
@@ -25,47 +25,59 @@
#include "third_party/blink/renderer/core/paint/scoped_svg_paint_state.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter.h"
-#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.h"
-#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/paint/svg_mask_painter.h"
+#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
namespace blink {
-ScopedSVGPaintState::~ScopedSVGPaintState() {
- if (filter_) {
- DCHECK(SVGResourcesCache::CachedResourcesForLayoutObject(object_));
- DCHECK(
- SVGResourcesCache::CachedResourcesForLayoutObject(object_)->Filter() ==
- filter_);
- DCHECK(filter_recording_context_);
- SVGFilterPainter(*filter_).FinishEffect(object_,
- *filter_recording_context_);
-
- // Reset the paint info after the filter effect has been completed.
- filter_paint_info_ = nullptr;
- }
+static void PaintFilteredContent(GraphicsContext& context,
+ const LayoutObject& object,
+ const DisplayItemClient& display_item_client,
+ FilterData* filter_data) {
+ if (DrawingRecorder::UseCachedDrawingIfPossible(context, display_item_client,
+ DisplayItem::kSVGFilter))
+ return;
- if (masker_) {
+ DrawingRecorder recorder(context, display_item_client,
+ DisplayItem::kSVGFilter);
+ sk_sp<PaintFilter> image_filter = filter_data->CreateFilter();
+ context.Save();
+
+ // Clip drawing of filtered image to the minimum required paint rect.
+ const FloatRect object_bounds = object.StrokeBoundingBox();
+ const FloatRect paint_rect = filter_data->MapRect(object_bounds);
+ context.ClipRect(paint_rect);
+
+ // Use the union of the pre-image and the post-image as the layer bounds.
+ const FloatRect layer_bounds = UnionRect(object_bounds, paint_rect);
+ context.BeginLayer(1, SkBlendMode::kSrcOver, &layer_bounds, kColorFilterNone,
+ std::move(image_filter));
+ context.EndLayer();
+ context.Restore();
+}
+
+ScopedSVGPaintState::~ScopedSVGPaintState() {
+ if (filter_data_ && filter_data_->UpdateStateOnFinish()) {
DCHECK(SVGResourcesCache::CachedResourcesForLayoutObject(object_));
DCHECK(
- SVGResourcesCache::CachedResourcesForLayoutObject(object_)->Masker() ==
- masker_);
- SVGMaskPainter(*masker_).FinishEffect(object_, GetPaintInfo().context);
+ SVGResourcesCache::CachedResourcesForLayoutObject(object_)->Filter());
+ if (filter_recording_context_) {
+ filter_data_->UpdateContent(
+ filter_recording_context_->GetPaintRecord(paint_info_));
+ filter_recording_context_ = nullptr;
+ }
+ PaintFilteredContent(paint_info_.context, object_, display_item_client_,
+ filter_data_);
+ filter_data_ = nullptr;
}
}
-bool ScopedSVGPaintState::ApplyClipMaskAndFilterIfNecessary() {
+bool ScopedSVGPaintState::ApplyEffects() {
#if DCHECK_IS_ON()
DCHECK(!apply_clip_mask_and_filter_if_necessary_called_);
apply_clip_mask_and_filter_if_necessary_called_ = true;
#endif
- // In CAP we should early exit once the paint property state has been
- // applied, because all meta (non-drawing) display items are ignored in
- // CAP. However we can't simply omit them because there are still
- // non-composited painting (e.g. SVG filters in particular) that rely on
- // these meta display items.
ApplyPaintPropertyState();
// When rendering clip paths as masks, only geometric operations should be
@@ -93,8 +105,7 @@ bool ScopedSVGPaintState::ApplyClipMaskAndFilterIfNecessary() {
SVGResources* resources =
SVGResourcesCache::CachedResourcesForLayoutObject(object_);
- if (!ApplyMaskIfNecessary(resources))
- return false;
+ ApplyMaskIfNecessary(resources);
if (is_svg_root_or_foreign_object) {
// PaintLayerPainter takes care of filter.
@@ -102,7 +113,6 @@ bool ScopedSVGPaintState::ApplyClipMaskAndFilterIfNecessary() {
} else if (!ApplyFilterIfNecessary(resources)) {
return false;
}
-
return true;
}
@@ -129,25 +139,20 @@ void ScopedSVGPaintState::ApplyPaintPropertyState() {
else if (const auto* clip_path_clip = properties->ClipPathClip())
state.SetClip(*clip_path_clip);
scoped_paint_chunk_properties_.emplace(
- paint_controller, state, object_,
+ paint_controller, state, display_item_client_,
DisplayItem::PaintPhaseToSVGEffectType(GetPaintInfo().phase));
}
void ScopedSVGPaintState::ApplyClipIfNecessary() {
if (object_.StyleRef().ClipPath()) {
clip_path_clipper_.emplace(GetPaintInfo().context, object_,
- PhysicalOffset());
+ display_item_client_, PhysicalOffset());
}
}
-bool ScopedSVGPaintState::ApplyMaskIfNecessary(SVGResources* resources) {
- if (LayoutSVGResourceMasker* masker =
- resources ? resources->Masker() : nullptr) {
- if (!SVGMaskPainter(*masker).PrepareEffect(object_, GetPaintInfo().context))
- return false;
- masker_ = masker;
- }
- return true;
+void ScopedSVGPaintState::ApplyMaskIfNecessary(SVGResources* resources) {
+ if (resources && resources->Masker())
+ mask_painter_.emplace(paint_info_.context, object_, display_item_client_);
}
static bool HasReferenceFilterOnly(const ComputedStyle& style) {
@@ -162,27 +167,20 @@ static bool HasReferenceFilterOnly(const ComputedStyle& style) {
bool ScopedSVGPaintState::ApplyFilterIfNecessary(SVGResources* resources) {
if (!resources)
return !HasReferenceFilterOnly(object_.StyleRef());
-
LayoutSVGResourceFilter* filter = resources->Filter();
if (!filter)
return true;
- filter_recording_context_ =
- std::make_unique<SVGFilterRecordingContext>(GetPaintInfo().context);
- filter_ = filter;
- GraphicsContext* filter_context = SVGFilterPainter(*filter).PrepareEffect(
- object_, *filter_recording_context_);
- if (!filter_context)
+ filter->ClearInvalidationMask();
+ filter_data_ = SVGFilterPainter(*filter).PrepareEffect(object_);
+ // If we have no filter data (== the filter was invalid) or if we
+ // don't need to update the source graphics, we can short-circuit
+ // here.
+ if (!filter_data_ || !filter_data_->ContentNeedsUpdate())
return false;
-
// Because the filter needs to cache its contents we replace the context
// during filtering with the filter's context.
- filter_paint_info_ =
- std::make_unique<PaintInfo>(*filter_context, paint_info_);
-
- // Because we cache the filter contents and do not invalidate on paint
- // invalidation rect changes, we need to paint the entire filter region
- // so elements outside the initial paint (due to scrolling, etc) paint.
- filter_paint_info_->ApplyInfiniteCullRect();
+ filter_recording_context_ =
+ std::make_unique<SVGFilterRecordingContext>(paint_info_);
return true;
}
diff --git a/chromium/third_party/blink/renderer/core/paint/scoped_svg_paint_state.h b/chromium/third_party/blink/renderer/core/paint/scoped_svg_paint_state.h
index 479b12c09f7..8d467e7b4a2 100644
--- a/chromium/third_party/blink/renderer/core/paint/scoped_svg_paint_state.h
+++ b/chromium/third_party/blink/renderer/core/paint/scoped_svg_paint_state.h
@@ -30,14 +30,14 @@
#include "third_party/blink/renderer/core/paint/object_paint_properties.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
#include "third_party/blink/renderer/core/paint/svg_filter_painter.h"
+#include "third_party/blink/renderer/core/paint/svg_mask_painter.h"
#include "third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_properties.h"
#include "third_party/blink/renderer/platform/transforms/affine_transform.h"
namespace blink {
+class FilterData;
class LayoutObject;
-class LayoutSVGResourceFilter;
-class LayoutSVGResourceMasker;
class SVGResources;
// Hooks up the correct paint property transform node.
@@ -81,28 +81,31 @@ class ScopedSVGPaintState {
public:
ScopedSVGPaintState(const LayoutObject& object, const PaintInfo& paint_info)
+ : ScopedSVGPaintState(object, paint_info, object) {}
+
+ ScopedSVGPaintState(const LayoutObject& object,
+ const PaintInfo& paint_info,
+ const DisplayItemClient& display_item_client)
: object_(object),
paint_info_(paint_info),
- filter_(nullptr),
- masker_(nullptr) {}
+ display_item_client_(display_item_client),
+ filter_data_(nullptr) {}
~ScopedSVGPaintState();
- PaintInfo& GetPaintInfo() {
- return filter_paint_info_ ? *filter_paint_info_ : paint_info_;
+ const PaintInfo& GetPaintInfo() const {
+ return filter_recording_context_ ? filter_recording_context_->GetPaintInfo()
+ : paint_info_;
}
// Return true if these operations aren't necessary or if they are
// successfully applied.
- bool ApplyClipMaskAndFilterIfNecessary();
+ bool ApplyEffects();
private:
void ApplyPaintPropertyState();
void ApplyClipIfNecessary();
-
- // Return true if no masking is necessary or if the mask is successfully
- // applied.
- bool ApplyMaskIfNecessary(SVGResources*);
+ void ApplyMaskIfNecessary(SVGResources*);
// Return true if no filtering is necessary or if the filter is successfully
// applied.
@@ -110,12 +113,12 @@ class ScopedSVGPaintState {
const LayoutObject& object_;
PaintInfo paint_info_;
- std::unique_ptr<PaintInfo> filter_paint_info_;
- LayoutSVGResourceFilter* filter_;
- LayoutSVGResourceMasker* masker_;
+ const DisplayItemClient& display_item_client_;
+ FilterData* filter_data_;
base::Optional<ClipPathClipper> clip_path_clipper_;
std::unique_ptr<SVGFilterRecordingContext> filter_recording_context_;
base::Optional<ScopedPaintChunkProperties> scoped_paint_chunk_properties_;
+ base::Optional<SVGMaskPainter> mask_painter_;
#if DCHECK_IS_ON()
bool apply_clip_mask_and_filter_if_necessary_called_ = false;
#endif
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 ab01fef7a7c..df26ad02982 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
@@ -19,7 +19,6 @@
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
#include "third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_properties.h"
-#include "third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.h"
namespace blink {
@@ -30,10 +29,7 @@ void ScrollableAreaPainter::PaintResizer(GraphicsContext& context,
if (!GetScrollableArea().GetLayoutBox()->StyleRef().HasResize())
return;
- IntRect abs_rect = GetScrollableArea().ResizerCornerRect(
- GetScrollableArea().GetLayoutBox()->PixelSnappedBorderBoxRect(
- GetScrollableArea().Layer()->SubpixelAccumulation()),
- kResizerForPointer);
+ IntRect abs_rect = GetScrollableArea().ResizerCornerRect(kResizerForPointer);
if (abs_rect.IsEmpty())
return;
abs_rect.MoveBy(paint_offset);
@@ -73,18 +69,15 @@ void ScrollableAreaPainter::PaintResizer(GraphicsContext& context,
void ScrollableAreaPainter::RecordResizerScrollHitTestData(
GraphicsContext& context,
- const PhysicalOffset& paint_offset,
- const DisplayItemClient& client) {
+ const PhysicalOffset& paint_offset) {
if (!GetScrollableArea().GetLayoutBox()->CanResize())
return;
- IntRect touch_rect = scrollable_area_->ResizerCornerRect(
- GetScrollableArea().GetLayoutBox()->PixelSnappedBorderBoxRect(
- paint_offset),
- kResizerForTouch);
+ IntRect touch_rect = scrollable_area_->ResizerCornerRect(kResizerForTouch);
touch_rect.MoveBy(RoundedIntPoint(paint_offset));
- ScrollHitTestDisplayItem::Record(
- context, client, DisplayItem::kResizerScrollHitTest, nullptr, touch_rect);
+ context.GetPaintController().RecordScrollHitTestData(
+ DisplayItemClientForCorner(), DisplayItem::kResizerScrollHitTest, nullptr,
+ touch_rect);
}
void ScrollableAreaPainter::DrawPlatformResizerImage(
@@ -201,18 +194,16 @@ void ScrollableAreaPainter::PaintScrollbar(GraphicsContext& context,
Scrollbar& scrollbar,
const CullRect& cull_rect,
const IntPoint& paint_offset) {
- // We create PaintOffsetTranslation for scrollable area, so the rounded
- // paint offset is always zero.
// TODO(crbug.com/1020913): We should not round paint_offset but should
// consider subpixel accumulation when painting scrollbars.
- DCHECK_EQ(paint_offset, IntPoint());
IntRect rect = scrollbar.FrameRect();
+ rect.MoveBy(paint_offset);
if (!cull_rect.Intersects(rect))
return;
if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
scrollbar.IsCustomScrollbar()) {
- scrollbar.Paint(context);
+ scrollbar.Paint(context, paint_offset);
return;
}
diff --git a/chromium/third_party/blink/renderer/core/paint/scrollable_area_painter.h b/chromium/third_party/blink/renderer/core/paint/scrollable_area_painter.h
index 54d27f793e8..9b702249b5a 100644
--- a/chromium/third_party/blink/renderer/core/paint/scrollable_area_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/scrollable_area_painter.h
@@ -38,10 +38,8 @@ class ScrollableAreaPainter {
// Records a scroll hit test data to force main thread handling of events
// in the expanded resizer touch area.
- void RecordResizerScrollHitTestData(
- GraphicsContext&,
- const PhysicalOffset& paint_offset,
- const DisplayItemClient& background_client);
+ void RecordResizerScrollHitTestData(GraphicsContext&,
+ const PhysicalOffset& paint_offset);
private:
void DrawPlatformResizerImage(GraphicsContext&,
@@ -54,7 +52,7 @@ class ScrollableAreaPainter {
PaintLayerScrollableArea& GetScrollableArea() const;
const DisplayItemClient& DisplayItemClientForCorner() const;
- Member<PaintLayerScrollableArea> scrollable_area_;
+ PaintLayerScrollableArea* scrollable_area_;
DISALLOW_COPY_AND_ASSIGN(ScrollableAreaPainter);
};
diff --git a/chromium/third_party/blink/renderer/core/paint/selection_painting_utils.cc b/chromium/third_party/blink/renderer/core/paint/selection_painting_utils.cc
index 98cd2b17a71..d4ed87b374c 100644
--- a/chromium/third_party/blink/renderer/core/paint/selection_painting_utils.cc
+++ b/chromium/third_party/blink/renderer/core/paint/selection_painting_utils.cc
@@ -73,7 +73,7 @@ Color SelectionColor(const Document& document,
// If the element is unselectable, or we are only painting the selection,
// don't override the foreground color with the selection foreground color.
if ((node && !NodeIsSelectable(style, node)) ||
- (global_paint_flags & kGlobalPaintSelectionOnly))
+ (global_paint_flags & kGlobalPaintSelectionDragImageOnly))
return style.VisitedDependentColor(color_property);
if (scoped_refptr<ComputedStyle> pseudo_style =
diff --git a/chromium/third_party/blink/renderer/core/paint/svg_container_painter.cc b/chromium/third_party/blink/renderer/core/paint/svg_container_painter.cc
index 77847cb1415..0da8574d1e4 100644
--- a/chromium/third_party/blink/renderer/core/paint/svg_container_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/svg_container_painter.cc
@@ -32,10 +32,8 @@ void SVGContainerPainter::Paint(const PaintInfo& paint_info) {
if (svg_svg_element && svg_svg_element->HasEmptyViewBox())
return;
- PaintInfo paint_info_before_filtering(paint_info);
-
if (SVGModelObjectPainter(layout_svg_container_)
- .CullRectSkipsPainting(paint_info_before_filtering)) {
+ .CullRectSkipsPainting(paint_info)) {
return;
}
@@ -44,6 +42,7 @@ void SVGContainerPainter::Paint(const PaintInfo& paint_info) {
// 2) Complexity: Difficulty updating clips when ancestor transforms change.
// This is why we use an infinite cull rect if there is a transform. Non-svg
// content, does this in PaintLayerPainter::PaintSingleFragment.
+ PaintInfo paint_info_before_filtering(paint_info);
if (layout_svg_container_.StyleRef().HasTransform()) {
paint_info_before_filtering.ApplyInfiniteCullRect();
} else if (const auto* properties =
@@ -59,7 +58,8 @@ void SVGContainerPainter::Paint(const PaintInfo& paint_info) {
base::Optional<ScopedPaintChunkProperties> scoped_paint_chunk_properties;
if (layout_svg_container_.IsSVGViewportContainer() &&
SVGLayoutSupport::IsOverflowHidden(layout_svg_container_)) {
- const auto* fragment = paint_info.FragmentToPaint(layout_svg_container_);
+ const auto* fragment =
+ paint_info_before_filtering.FragmentToPaint(layout_svg_container_);
if (!fragment)
return;
const auto* properties = fragment->PaintProperties();
@@ -68,9 +68,9 @@ void SVGContainerPainter::Paint(const PaintInfo& paint_info) {
// properties are ready.
if (properties && properties->OverflowClip()) {
scoped_paint_chunk_properties.emplace(
- paint_info.context.GetPaintController(),
+ paint_info_before_filtering.context.GetPaintController(),
*properties->OverflowClip(), layout_svg_container_,
- paint_info.DisplayItemTypeForClipping());
+ paint_info_before_filtering.DisplayItemTypeForClipping());
}
}
@@ -78,13 +78,13 @@ void SVGContainerPainter::Paint(const PaintInfo& paint_info) {
paint_info_before_filtering);
bool continue_rendering = true;
if (paint_state.GetPaintInfo().phase == PaintPhase::kForeground)
- continue_rendering = paint_state.ApplyClipMaskAndFilterIfNecessary();
+ continue_rendering = paint_state.ApplyEffects();
if (continue_rendering) {
for (LayoutObject* child = layout_svg_container_.FirstChild(); child;
child = child->NextSibling()) {
- if (child->IsSVGForeignObject()) {
- SVGForeignObjectPainter(ToLayoutSVGForeignObject(*child))
+ if (auto* foreign_object = DynamicTo<LayoutSVGForeignObject>(*child)) {
+ SVGForeignObjectPainter(*foreign_object)
.PaintLayer(paint_state.GetPaintInfo());
} else {
child->Paint(paint_state.GetPaintInfo());
diff --git a/chromium/third_party/blink/renderer/core/paint/svg_filter_painter.cc b/chromium/third_party/blink/renderer/core/paint/svg_filter_painter.cc
index 66b1ae84e13..47552d0011e 100644
--- a/chromium/third_party/blink/renderer/core/paint/svg_filter_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/svg_filter_painter.cc
@@ -12,157 +12,65 @@
#include "third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.h"
#include "third_party/blink/renderer/core/svg/svg_filter_element.h"
#include "third_party/blink/renderer/platform/graphics/filters/filter.h"
-#include "third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h"
#include "third_party/blink/renderer/platform/graphics/filters/source_graphic.h"
-#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
+#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
+#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
namespace blink {
-GraphicsContext* SVGFilterRecordingContext::BeginContent() {
- // Create a new context so the contents of the filter can be drawn and cached.
- paint_controller_ = std::make_unique<PaintController>();
- context_ = std::make_unique<GraphicsContext>(*paint_controller_);
-
- // Use initial_context_'s current paint chunk properties so that any new
+SVGFilterRecordingContext::SVGFilterRecordingContext(
+ const PaintInfo& initial_paint_info)
+ // Create a new context so the contents of the filter can be drawn and
+ // cached.
+ : paint_controller_(std::make_unique<PaintController>()),
+ 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
// chunk created during painting the content will be in the correct state.
paint_controller_->UpdateCurrentPaintChunkProperties(
- base::nullopt,
- initial_context_.GetPaintController().CurrentPaintChunkProperties());
-
- return context_.get();
+ nullptr, initial_paint_info.context.GetPaintController()
+ .CurrentPaintChunkProperties());
+ // Because we cache the filter contents and do not invalidate on paint
+ // invalidation rect changes, we need to paint the entire filter region so
+ // elements outside the initial paint (due to scrolling, etc) paint.
+ paint_info_.ApplyInfiniteCullRect();
}
-sk_sp<PaintRecord> SVGFilterRecordingContext::EndContent(
- const FloatRect& bounds) {
- // Use the context that contains the filtered content.
- DCHECK(paint_controller_);
- DCHECK(context_);
- context_->BeginRecording(bounds);
- paint_controller_->CommitNewDisplayItems();
-
- paint_controller_->GetPaintArtifact().Replay(
- *context_,
- initial_context_.GetPaintController().CurrentPaintChunkProperties());
+SVGFilterRecordingContext::~SVGFilterRecordingContext() = default;
- sk_sp<PaintRecord> content = context_->EndRecording();
- // Content is cached by the source graphic so temporaries can be freed.
- paint_controller_ = nullptr;
- context_ = nullptr;
- return content;
-}
-
-void SVGFilterRecordingContext::Abort() {
- if (!paint_controller_)
- return;
- EndContent(FloatRect());
-}
-
-static void PaintFilteredContent(GraphicsContext& context,
- const LayoutObject& object,
- const FloatRect& bounds,
- FilterEffect* effect) {
- if (DrawingRecorder::UseCachedDrawingIfPossible(context, object,
- DisplayItem::kSVGFilter))
- return;
-
- DrawingRecorder recorder(context, object, DisplayItem::kSVGFilter);
- sk_sp<PaintFilter> image_filter =
- paint_filter_builder::Build(effect, kInterpolationSpaceSRGB);
- context.Save();
-
- // Clip drawing of filtered image to the minimum required paint rect.
- context.ClipRect(effect->MapRect(object.StrokeBoundingBox()));
-
- context.BeginLayer(1, SkBlendMode::kSrcOver, &bounds, kColorFilterNone,
- std::move(image_filter));
- context.EndLayer();
- context.Restore();
+sk_sp<PaintRecord> SVGFilterRecordingContext::GetPaintRecord(
+ const PaintInfo& initial_paint_info) {
+ paint_controller_->CommitNewDisplayItems();
+ return paint_controller_->GetPaintArtifact().GetPaintRecord(
+ initial_paint_info.context.GetPaintController()
+ .CurrentPaintChunkProperties());
}
-GraphicsContext* SVGFilterPainter::PrepareEffect(
- const LayoutObject& object,
- SVGFilterRecordingContext& recording_context) {
- filter_.ClearInvalidationMask();
-
- SVGResourceClient* client = SVGResources::GetClient(object);
- if (FilterData* filter_data = filter_.GetFilterDataForClient(client)) {
+FilterData* SVGFilterPainter::PrepareEffect(const LayoutObject& object) {
+ SVGElementResourceClient* client = SVGResources::GetClient(object);
+ if (FilterData* filter_data = client->GetFilterData()) {
// If the filterData already exists we do not need to record the content
// to be filtered. This can occur if the content was previously recorded
// or we are in a cycle.
- if (filter_data->state_ == FilterData::kPaintingFilter)
- filter_data->state_ = FilterData::kPaintingFilterCycleDetected;
-
- if (filter_data->state_ == FilterData::kRecordingContent)
- filter_data->state_ = FilterData::kRecordingContentCycleDetected;
-
- return nullptr;
+ filter_data->UpdateStateOnPrepare();
+ return filter_data;
}
auto* node_map = MakeGarbageCollected<SVGFilterGraphNodeMap>();
- FilterEffectBuilder builder(object.ObjectBoundingBox(), 1);
+ FilterEffectBuilder builder(SVGResources::ReferenceBoxForEffects(object), 1);
Filter* filter = builder.BuildReferenceFilter(
To<SVGFilterElement>(*filter_.GetElement()), nullptr, node_map);
if (!filter || !filter->LastEffect())
return nullptr;
- IntRect source_region = EnclosingIntRect(
- Intersection(filter->FilterRegion(), object.StrokeBoundingBox()));
+ IntRect source_region = EnclosingIntRect(object.StrokeBoundingBox());
filter->GetSourceGraphic()->SetSourceRect(source_region);
- auto* filter_data = MakeGarbageCollected<FilterData>();
- filter_data->last_effect = filter->LastEffect();
- filter_data->node_map = node_map;
- DCHECK_EQ(filter_data->state_, FilterData::kInitial);
-
+ auto* filter_data =
+ MakeGarbageCollected<FilterData>(filter->LastEffect(), node_map);
// TODO(pdr): Can this be moved out of painter?
- filter_.SetFilterDataForClient(client, filter_data);
- filter_data->state_ = FilterData::kRecordingContent;
- return recording_context.BeginContent();
-}
-
-void SVGFilterPainter::FinishEffect(
- const LayoutObject& object,
- SVGFilterRecordingContext& recording_context) {
- SVGResourceClient* client = SVGResources::GetClient(object);
- FilterData* filter_data = filter_.GetFilterDataForClient(client);
- if (!filter_data) {
- // Our state was torn down while we were being painted (selection style for
- // <text> can have this effect), or it was never created (invalid filter.)
- // In the former case we may have been in the process of recording content,
- // so make sure we put recording state into a consistent state.
- recording_context.Abort();
- return;
- }
-
- // A painting cycle can occur when an FeImage references a source that
- // makes use of the FeImage itself. This is the first place we would hit
- // the cycle so we reset the state and continue.
- if (filter_data->state_ == FilterData::kPaintingFilterCycleDetected) {
- filter_data->state_ = FilterData::kPaintingFilter;
- return;
- }
- if (filter_data->state_ == FilterData::kRecordingContentCycleDetected) {
- filter_data->state_ = FilterData::kRecordingContent;
- return;
- }
-
- // Check for RecordingContent here because we may can be re-painting
- // without re-recording the contents to be filtered.
- Filter* filter = filter_data->last_effect->GetFilter();
- FloatRect bounds = filter->FilterRegion();
- if (filter_data->state_ == FilterData::kRecordingContent) {
- DCHECK(filter->GetSourceGraphic());
- sk_sp<PaintRecord> content = recording_context.EndContent(bounds);
- paint_filter_builder::BuildSourceGraphic(filter->GetSourceGraphic(),
- std::move(content), bounds);
- filter_data->state_ = FilterData::kReadyToPaint;
- }
-
- DCHECK_EQ(filter_data->state_, FilterData::kReadyToPaint);
- filter_data->state_ = FilterData::kPaintingFilter;
- PaintFilteredContent(recording_context.PaintingContext(), object, bounds,
- filter_data->last_effect);
- filter_data->state_ = FilterData::kReadyToPaint;
+ client->SetFilterData(filter_data);
+ return filter_data;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/svg_filter_painter.h b/chromium/third_party/blink/renderer/core/paint/svg_filter_painter.h
index 7dd90ff7c54..f38d6937347 100644
--- a/chromium/third_party/blink/renderer/core/paint/svg_filter_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/svg_filter_painter.h
@@ -7,32 +7,31 @@
#include <memory>
#include "base/macros.h"
-#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
-#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
+#include "third_party/blink/renderer/core/paint/paint_info.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
namespace blink {
+class FilterData;
+class GraphicsContext;
class LayoutObject;
class LayoutSVGResourceFilter;
+class PaintController;
class SVGFilterRecordingContext {
USING_FAST_MALLOC(SVGFilterRecordingContext);
public:
- explicit SVGFilterRecordingContext(GraphicsContext& initial_context)
- : initial_context_(initial_context) {}
+ explicit SVGFilterRecordingContext(const PaintInfo&);
+ ~SVGFilterRecordingContext();
- GraphicsContext* BeginContent();
- sk_sp<PaintRecord> EndContent(const FloatRect&);
- void Abort();
-
- GraphicsContext& PaintingContext() const { return initial_context_; }
+ const PaintInfo& GetPaintInfo() const { return paint_info_; }
+ sk_sp<PaintRecord> GetPaintRecord(const PaintInfo&);
private:
std::unique_ptr<PaintController> paint_controller_;
std::unique_ptr<GraphicsContext> context_;
- GraphicsContext& initial_context_;
+ PaintInfo paint_info_;
DISALLOW_COPY_AND_ASSIGN(SVGFilterRecordingContext);
};
@@ -42,11 +41,9 @@ class SVGFilterPainter {
public:
SVGFilterPainter(LayoutSVGResourceFilter& filter) : filter_(filter) {}
- // Returns the context that should be used to paint the filter contents, or
- // null if the content should not be recorded.
- GraphicsContext* PrepareEffect(const LayoutObject&,
- SVGFilterRecordingContext&);
- void FinishEffect(const LayoutObject&, SVGFilterRecordingContext&);
+ // Returns the FilterData for the filter effect, or null if the
+ // filter is invalid.
+ FilterData* PrepareEffect(const LayoutObject&);
private:
LayoutSVGResourceFilter& filter_;
diff --git a/chromium/third_party/blink/renderer/core/paint/svg_foreign_object_painter.cc b/chromium/third_party/blink/renderer/core/paint/svg_foreign_object_painter.cc
index 4d7405fcc7c..fa811d7863e 100644
--- a/chromium/third_party/blink/renderer/core/paint/svg_foreign_object_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/svg_foreign_object_painter.cc
@@ -6,9 +6,7 @@
#include "base/optional.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.h"
-#include "third_party/blink/renderer/core/layout/svg/svg_layout_support.h"
#include "third_party/blink/renderer/core/paint/block_painter.h"
-#include "third_party/blink/renderer/core/paint/object_painter.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/paint_layer_painter.h"
@@ -19,7 +17,7 @@ namespace blink {
void SVGForeignObjectPainter::PaintLayer(const PaintInfo& paint_info) {
if (paint_info.phase != PaintPhase::kForeground &&
- paint_info.phase != PaintPhase::kSelection)
+ paint_info.phase != PaintPhase::kSelectionDragImage)
return;
// Early out in the case of trying to paint an image filter before
@@ -51,14 +49,13 @@ void SVGForeignObjectPainter::PaintLayer(const PaintInfo& paint_info) {
}
void SVGForeignObjectPainter::Paint(const PaintInfo& paint_info) {
- PaintInfo paint_info_before_filtering(paint_info);
- ScopedSVGPaintState paint_state(layout_svg_foreign_object_,
- paint_info_before_filtering);
-
- if (paint_state.GetPaintInfo().phase == PaintPhase::kForeground &&
- !paint_state.ApplyClipMaskAndFilterIfNecessary())
+ ScopedSVGPaintState paint_state(layout_svg_foreign_object_, paint_info);
+ // ScopedSVGPaintState only applies masks (and clips-within-clips)
+ // here and thus does not mutate PaintInfo, so we can use the passed
+ // in PaintInfo below.
+ if (paint_info.phase == PaintPhase::kForeground &&
+ !paint_state.ApplyEffects())
return;
-
BlockPainter(layout_svg_foreign_object_).Paint(paint_info);
}
diff --git a/chromium/third_party/blink/renderer/core/paint/svg_image_painter.cc b/chromium/third_party/blink/renderer/core/paint/svg_image_painter.cc
index de9deb79d00..e3b5622f87d 100644
--- a/chromium/third_party/blink/renderer/core/paint/svg_image_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/svg_image_painter.cc
@@ -27,25 +27,23 @@ void SVGImagePainter::Paint(const PaintInfo& paint_info) {
!layout_svg_image_.ImageResource()->HasImage())
return;
- PaintInfo paint_info_before_filtering(paint_info);
-
if (SVGModelObjectPainter(layout_svg_image_)
- .CullRectSkipsPainting(paint_info_before_filtering)) {
+ .CullRectSkipsPainting(paint_info)) {
return;
}
// Images cannot have children so do not call TransformCullRect.
ScopedSVGTransformState transform_state(
- paint_info_before_filtering, layout_svg_image_,
+ paint_info, layout_svg_image_,
layout_svg_image_.LocalToSVGParentTransform());
{
- ScopedSVGPaintState paint_state(layout_svg_image_,
- paint_info_before_filtering);
- if (paint_state.ApplyClipMaskAndFilterIfNecessary() &&
+ ScopedSVGPaintState paint_state(layout_svg_image_, paint_info);
+ if (paint_state.ApplyEffects() &&
!DrawingRecorder::UseCachedDrawingIfPossible(
paint_state.GetPaintInfo().context, layout_svg_image_,
paint_state.GetPaintInfo().phase)) {
- SVGModelObjectPainter::RecordHitTestData(layout_svg_image_, paint_info);
+ SVGModelObjectPainter::RecordHitTestData(layout_svg_image_,
+ paint_state.GetPaintInfo());
DrawingRecorder recorder(paint_state.GetPaintInfo().context,
layout_svg_image_,
paint_state.GetPaintInfo().phase);
@@ -53,8 +51,7 @@ void SVGImagePainter::Paint(const PaintInfo& paint_info) {
}
}
- SVGModelObjectPainter(layout_svg_image_)
- .PaintOutline(paint_info_before_filtering);
+ SVGModelObjectPainter(layout_svg_image_).PaintOutline(paint_info);
}
void SVGImagePainter::PaintForeground(const PaintInfo& paint_info) {
@@ -64,14 +61,27 @@ void SVGImagePainter::PaintForeground(const PaintInfo& paint_info) {
if (image_viewport_size.IsEmpty())
return;
- scoped_refptr<Image> image =
- image_resource->GetImage(ExpandedIntSize(image_viewport_size));
+ scoped_refptr<Image> image = image_resource->GetImage(image_viewport_size);
FloatRect dest_rect = layout_svg_image_.ObjectBoundingBox();
- FloatRect src_rect(0, 0, image->width(), image->height());
auto* image_element = To<SVGImageElement>(layout_svg_image_.GetElement());
- image_element->preserveAspectRatio()->CurrentValue()->TransformRect(dest_rect,
- src_rect);
+ RespectImageOrientationEnum respect_orientation =
+ LayoutObject::ShouldRespectImageOrientation(&layout_svg_image_);
+ FloatRect src_rect(FloatPoint(), image->SizeAsFloat(respect_orientation));
+ if (respect_orientation && !image->HasDefaultOrientation()) {
+ // We need the oriented source rect for adjusting the aspect ratio
+ FloatSize unadjusted_size(src_rect.Size());
+ image_element->preserveAspectRatio()->CurrentValue()->TransformRect(
+ dest_rect, src_rect);
+
+ // Map the oriented_src_rect back into the src_rect space
+ src_rect =
+ image->CorrectSrcRectForImageOrientation(unadjusted_size, src_rect);
+ } else {
+ image_element->preserveAspectRatio()->CurrentValue()->TransformRect(
+ dest_rect, src_rect);
+ }
+
ScopedInterpolationQuality interpolation_quality_scope(
paint_info.context,
layout_svg_image_.StyleRef().GetInterpolationQuality());
@@ -79,8 +89,9 @@ void SVGImagePainter::PaintForeground(const PaintInfo& paint_info) {
image_element->GetDecodingModeForPainting(image->paint_image_id());
paint_info.context.DrawImage(
image.get(), decode_mode, dest_rect, &src_rect,
- layout_svg_image_.StyleRef().HasFilterInducingProperty());
- if (!paint_info.context.ContextDisabled() && image_resource->CachedImage() &&
+ layout_svg_image_.StyleRef().HasFilterInducingProperty(),
+ SkBlendMode::kSrcOver, respect_orientation);
+ if (image_resource->CachedImage() &&
image_resource->CachedImage()->IsLoaded()) {
LocalDOMWindow* window = layout_svg_image_.GetDocument().domWindow();
DCHECK(window);
@@ -117,11 +128,12 @@ FloatSize SVGImagePainter::ComputeImageViewportSize() const {
if (cached_image->ErrorOccurred())
return FloatSize();
Image* image = cached_image->GetImage();
- if (image->IsSVGImage()) {
- return ToSVGImage(image)->ConcreteObjectSize(
+ if (auto* svg_image = DynamicTo<SVGImage>(image)) {
+ return svg_image->ConcreteObjectSize(
layout_svg_image_.ObjectBoundingBox().Size());
}
- return FloatSize(image->Size());
+ // The orientation here does not matter. Just use kRespectImageOrientation.
+ return image->SizeAsFloat(kRespectImageOrientation);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/svg_inline_flow_box_painter.cc b/chromium/third_party/blink/renderer/core/paint/svg_inline_flow_box_painter.cc
index a47b291f354..864602286f4 100644
--- a/chromium/third_party/blink/renderer/core/paint/svg_inline_flow_box_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/svg_inline_flow_box_painter.cc
@@ -16,33 +16,34 @@ namespace blink {
void SVGInlineFlowBoxPainter::PaintSelectionBackground(
const PaintInfo& paint_info) {
DCHECK(paint_info.phase == PaintPhase::kForeground ||
- paint_info.phase == PaintPhase::kSelection);
+ paint_info.phase == PaintPhase::kSelectionDragImage);
- PaintInfo child_paint_info(paint_info);
for (InlineBox* child = svg_inline_flow_box_.FirstChild(); child;
child = child->NextOnLine()) {
- if (child->IsSVGInlineTextBox())
- SVGInlineTextBoxPainter(*ToSVGInlineTextBox(child))
- .PaintSelectionBackground(child_paint_info);
- else if (child->IsSVGInlineFlowBox())
- SVGInlineFlowBoxPainter(*ToSVGInlineFlowBox(child))
- .PaintSelectionBackground(child_paint_info);
+ if (auto* svg_inline_text_box = DynamicTo<SVGInlineTextBox>(child)) {
+ SVGInlineTextBoxPainter(*svg_inline_text_box)
+ .PaintSelectionBackground(paint_info);
+ } else if (auto* svg_inline_flow_box = DynamicTo<SVGInlineFlowBox>(child)) {
+ SVGInlineFlowBoxPainter(*svg_inline_flow_box)
+ .PaintSelectionBackground(paint_info);
+ }
}
}
void SVGInlineFlowBoxPainter::Paint(const PaintInfo& paint_info,
const LayoutPoint& paint_offset) {
DCHECK(paint_info.phase == PaintPhase::kForeground ||
- paint_info.phase == PaintPhase::kSelection);
+ paint_info.phase == PaintPhase::kSelectionDragImage);
ScopedSVGPaintState paint_state(*LineLayoutAPIShim::ConstLayoutObjectFrom(
svg_inline_flow_box_.GetLineLayoutItem()),
- paint_info);
- if (paint_state.ApplyClipMaskAndFilterIfNecessary()) {
- for (InlineBox* child = svg_inline_flow_box_.FirstChild(); child;
- child = child->NextOnLine())
- child->Paint(paint_state.GetPaintInfo(), paint_offset, LayoutUnit(),
- LayoutUnit());
+ paint_info, svg_inline_flow_box_);
+ if (!paint_state.ApplyEffects())
+ return;
+ for (InlineBox* child = svg_inline_flow_box_.FirstChild(); child;
+ child = child->NextOnLine()) {
+ child->Paint(paint_state.GetPaintInfo(), paint_offset, LayoutUnit(),
+ LayoutUnit());
}
}
diff --git a/chromium/third_party/blink/renderer/core/paint/svg_inline_text_box_painter.cc b/chromium/third_party/blink/renderer/core/paint/svg_inline_text_box_painter.cc
index ea50d27ec60..8dd8f84c994 100644
--- a/chromium/third_party/blink/renderer/core/paint/svg_inline_text_box_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/svg_inline_text_box_painter.cc
@@ -74,7 +74,7 @@ LayoutSVGInlineText& SVGInlineTextBoxPainter::InlineText() const {
void SVGInlineTextBoxPainter::Paint(const PaintInfo& paint_info,
const LayoutPoint& paint_offset) {
DCHECK(paint_info.phase == PaintPhase::kForeground ||
- paint_info.phase == PaintPhase::kSelection);
+ paint_info.phase == PaintPhase::kSelectionDragImage);
DCHECK(svg_inline_text_box_.Truncation() == kCNoTruncation);
if (svg_inline_text_box_.GetLineLayoutItem().StyleRef().Visibility() !=
@@ -87,7 +87,7 @@ void SVGInlineTextBoxPainter::Paint(const PaintInfo& paint_info,
// very easy to refactor and reuse the code.
bool have_selection = ShouldPaintSelection(paint_info);
- if (!have_selection && paint_info.phase == PaintPhase::kSelection)
+ if (!have_selection && paint_info.phase == PaintPhase::kSelectionDragImage)
return;
LayoutSVGInlineText& text_layout_object = InlineText();
@@ -213,7 +213,7 @@ void SVGInlineTextBoxPainter::PaintSelectionBackground(
DCHECK(!paint_info.IsPrinting());
- if (paint_info.phase == PaintPhase::kSelection ||
+ if (paint_info.phase == PaintPhase::kSelectionDragImage ||
!ShouldPaintSelection(paint_info))
return;
@@ -507,7 +507,8 @@ void SVGInlineTextBoxPainter::PaintText(
// Eventually draw text using regular style until the start position of the
// selection.
- bool paint_selected_text_only = paint_info.phase == PaintPhase::kSelection;
+ bool paint_selected_text_only =
+ paint_info.phase == PaintPhase::kSelectionDragImage;
if (start_position > 0 && !paint_selected_text_only) {
PaintFlags flags;
if (SetupTextPaint(paint_info, style, resource_mode, flags,
diff --git a/chromium/third_party/blink/renderer/core/paint/svg_mask_painter.cc b/chromium/third_party/blink/renderer/core/paint/svg_mask_painter.cc
index fbac7c37aa4..b579318ec3b 100644
--- a/chromium/third_party/blink/renderer/core/paint/svg_mask_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/svg_mask_painter.cc
@@ -5,8 +5,8 @@
#include "third_party/blink/renderer/core/paint/svg_mask_painter.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.h"
+#include "third_party/blink/renderer/core/layout/svg/svg_resources.h"
#include "third_party/blink/renderer/core/paint/object_paint_properties.h"
-#include "third_party/blink/renderer/core/paint/paint_info.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
@@ -14,44 +14,48 @@
namespace blink {
-bool SVGMaskPainter::PrepareEffect(const LayoutObject& object,
- GraphicsContext& context) {
- DCHECK(mask_.Style());
- SECURITY_DCHECK(!mask_.NeedsLayout());
-
- mask_.ClearInvalidationMask();
- return mask_.GetElement()->HasChildren();
+SVGMaskPainter::SVGMaskPainter(GraphicsContext& context,
+ const LayoutObject& layout_object,
+ const DisplayItemClient& display_item_client)
+ : context_(context),
+ layout_object_(layout_object),
+ display_item_client_(display_item_client) {
+ DCHECK(layout_object_.StyleRef().SvgStyle().MaskerResource());
}
-void SVGMaskPainter::FinishEffect(const LayoutObject& object,
- GraphicsContext& context) {
- DCHECK(mask_.Style());
- SECURITY_DCHECK(!mask_.NeedsLayout());
-
- base::Optional<ScopedPaintChunkProperties> scoped_paint_chunk_properties;
- const auto* properties = object.FirstFragment().PaintProperties();
+SVGMaskPainter::~SVGMaskPainter() {
+ const auto* properties = layout_object_.FirstFragment().PaintProperties();
// TODO(crbug.com/814815): This condition should be a DCHECK, but for now
// we may paint the object for filters during PrePaint before the
// properties are ready.
- if (properties && properties->Mask()) {
- scoped_paint_chunk_properties.emplace(context.GetPaintController(),
- *properties->Mask(), object,
- DisplayItem::kSVGMask);
- }
-
- AffineTransform content_transformation;
- sk_sp<const PaintRecord> record = mask_.CreatePaintRecord(
- content_transformation, object.ObjectBoundingBox(), context);
+ if (!properties || !properties->Mask())
+ return;
+ ScopedPaintChunkProperties scoped_paint_chunk_properties(
+ context_.GetPaintController(), *properties->Mask(), display_item_client_,
+ DisplayItem::kSVGMask);
- if (DrawingRecorder::UseCachedDrawingIfPossible(context, object,
- DisplayItem::kSVGMask))
+ if (DrawingRecorder::UseCachedDrawingIfPossible(
+ context_, display_item_client_, DisplayItem::kSVGMask))
return;
+ DrawingRecorder recorder(context_, display_item_client_,
+ DisplayItem::kSVGMask);
+
+ const SVGComputedStyle& svg_style = layout_object_.StyleRef().SvgStyle();
+ auto* masker =
+ GetSVGResourceAsType<LayoutSVGResourceMasker>(svg_style.MaskerResource());
+ DCHECK(masker);
+ SECURITY_DCHECK(!masker->NeedsLayout());
+ masker->ClearInvalidationMask();
- DrawingRecorder recorder(context, object, DisplayItem::kSVGMask);
- context.Save();
- context.ConcatCTM(content_transformation);
- context.DrawRecord(std::move(record));
- context.Restore();
+ AffineTransform content_transformation;
+ sk_sp<const PaintRecord> record = masker->CreatePaintRecord(
+ content_transformation,
+ SVGResources::ReferenceBoxForEffects(layout_object_), context_);
+
+ context_.Save();
+ context_.ConcatCTM(content_transformation);
+ context_.DrawRecord(std::move(record));
+ context_.Restore();
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/svg_mask_painter.h b/chromium/third_party/blink/renderer/core/paint/svg_mask_painter.h
index af65990bf2e..d7f37cdb526 100644
--- a/chromium/third_party/blink/renderer/core/paint/svg_mask_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/svg_mask_painter.h
@@ -5,26 +5,27 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_SVG_MASK_PAINTER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_SVG_MASK_PAINTER_H_
-#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
namespace blink {
+class DisplayItemClient;
class GraphicsContext;
class LayoutObject;
-class LayoutSVGResourceMasker;
class SVGMaskPainter {
STACK_ALLOCATED();
public:
- SVGMaskPainter(LayoutSVGResourceMasker& mask) : mask_(mask) {}
-
- bool PrepareEffect(const LayoutObject&, GraphicsContext&);
- void FinishEffect(const LayoutObject&, GraphicsContext&);
+ SVGMaskPainter(GraphicsContext&,
+ const LayoutObject&,
+ const DisplayItemClient&);
+ ~SVGMaskPainter();
private:
- LayoutSVGResourceMasker& mask_;
+ GraphicsContext& context_;
+ const LayoutObject& layout_object_;
+ const DisplayItemClient& display_item_client_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/svg_model_object_painter.cc b/chromium/third_party/blink/renderer/core/paint/svg_model_object_painter.cc
index dc21e160d02..81e3d4b6b97 100644
--- a/chromium/third_party/blink/renderer/core/paint/svg_model_object_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/svg_model_object_painter.cc
@@ -7,7 +7,7 @@
#include "third_party/blink/renderer/core/layout/svg/layout_svg_model_object.h"
#include "third_party/blink/renderer/core/paint/object_painter.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
-#include "third_party/blink/renderer/platform/graphics/paint/hit_test_display_item.h"
+#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
namespace blink {
@@ -29,23 +29,19 @@ bool SVGModelObjectPainter::CullRectSkipsPainting(const PaintInfo& paint_info) {
layout_svg_model_object_.VisualRectInLocalSVGCoordinates());
}
-void SVGModelObjectPainter::RecordHitTestData(
- const LayoutSVGModelObject& layout_svg_model_object,
- const PaintInfo& paint_info) {
+void SVGModelObjectPainter::RecordHitTestData(const LayoutObject& svg_object,
+ const PaintInfo& paint_info) {
+ DCHECK(svg_object.IsSVGChild());
DCHECK(paint_info.phase == PaintPhase::kForeground);
// Hit test display items are only needed for compositing. This flag is used
// for for printing and drag images which do not need hit testing.
if (paint_info.GetGlobalPaintFlags() & kGlobalPaintFlattenCompositingLayers)
return;
- auto touch_action = layout_svg_model_object.EffectiveAllowedTouchAction();
- if (touch_action == TouchAction::kTouchActionAuto)
- return;
-
- auto rect =
- LayoutRect(layout_svg_model_object.VisualRectInLocalSVGCoordinates());
- HitTestDisplayItem::Record(paint_info.context, layout_svg_model_object,
- HitTestRect(rect, touch_action));
+ paint_info.context.GetPaintController().RecordHitTestData(
+ svg_object,
+ EnclosingIntRect(svg_object.VisualRectInLocalSVGCoordinates()),
+ svg_object.EffectiveAllowedTouchAction());
}
void SVGModelObjectPainter::PaintOutline(const PaintInfo& paint_info) {
diff --git a/chromium/third_party/blink/renderer/core/paint/svg_model_object_painter.h b/chromium/third_party/blink/renderer/core/paint/svg_model_object_painter.h
index 7498f380893..21578ed5f37 100644
--- a/chromium/third_party/blink/renderer/core/paint/svg_model_object_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/svg_model_object_painter.h
@@ -10,20 +10,22 @@
namespace blink {
struct PaintInfo;
+class LayoutObject;
class LayoutSVGModelObject;
class SVGModelObjectPainter {
STACK_ALLOCATED();
public:
- // Paint a hit test display item and record hit test data. This should be
- // called when painting the background even if there is no other painted
- // content. SVG backgrounds are painted in the kForeground paint phase.
- static void RecordHitTestData(
- const LayoutSVGModelObject& layout_svg_model_object,
- const PaintInfo&);
-
- SVGModelObjectPainter(const LayoutSVGModelObject& layout_svg_model_object)
+ // Expands the bounds of the current paint chunk for hit test, and records
+ // special touch action if any. This should be called when painting the
+ // background even if there is no other painted content. SVG backgrounds are
+ // painted in the kForeground paint phase.
+ static void RecordHitTestData(const LayoutObject& svg_object,
+ const PaintInfo&);
+
+ explicit SVGModelObjectPainter(
+ const LayoutSVGModelObject& layout_svg_model_object)
: layout_svg_model_object_(layout_svg_model_object) {}
// If the object is outside the cull rect, painting can be skipped in most
diff --git a/chromium/third_party/blink/renderer/core/paint/svg_root_inline_box_painter.cc b/chromium/third_party/blink/renderer/core/paint/svg_root_inline_box_painter.cc
index fd9eba5ae8b..2b3079f273f 100644
--- a/chromium/third_party/blink/renderer/core/paint/svg_root_inline_box_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/svg_root_inline_box_painter.cc
@@ -19,40 +19,42 @@ namespace blink {
void SVGRootInlineBoxPainter::Paint(const PaintInfo& paint_info,
const LayoutPoint& paint_offset) {
DCHECK(paint_info.phase == PaintPhase::kForeground ||
- paint_info.phase == PaintPhase::kSelection);
+ paint_info.phase == PaintPhase::kSelectionDragImage);
bool has_selection =
!paint_info.IsPrinting() && svg_root_inline_box_.IsSelected();
- PaintInfo paint_info_before_filtering(paint_info);
if (has_selection && !DrawingRecorder::UseCachedDrawingIfPossible(
- paint_info_before_filtering.context,
+ paint_info.context,
*LineLayoutAPIShim::ConstLayoutObjectFrom(
svg_root_inline_box_.GetLineLayoutItem()),
- paint_info_before_filtering.phase)) {
- DrawingRecorder recorder(paint_info_before_filtering.context,
+ paint_info.phase)) {
+ DrawingRecorder recorder(paint_info.context,
*LineLayoutAPIShim::ConstLayoutObjectFrom(
svg_root_inline_box_.GetLineLayoutItem()),
- paint_info_before_filtering.phase);
+ paint_info.phase);
for (InlineBox* child = svg_root_inline_box_.FirstChild(); child;
child = child->NextOnLine()) {
- if (child->IsSVGInlineTextBox())
- SVGInlineTextBoxPainter(*ToSVGInlineTextBox(child))
- .PaintSelectionBackground(paint_info_before_filtering);
- else if (child->IsSVGInlineFlowBox())
- SVGInlineFlowBoxPainter(*ToSVGInlineFlowBox(child))
- .PaintSelectionBackground(paint_info_before_filtering);
+ if (auto* svg_inline_text_box = DynamicTo<SVGInlineTextBox>(child)) {
+ SVGInlineTextBoxPainter(*svg_inline_text_box)
+ .PaintSelectionBackground(paint_info);
+ } else if (auto* svg_inline_flow_box =
+ DynamicTo<SVGInlineFlowBox>(child)) {
+ SVGInlineFlowBoxPainter(*svg_inline_flow_box)
+ .PaintSelectionBackground(paint_info);
+ }
}
}
ScopedSVGPaintState paint_state(*LineLayoutAPIShim::ConstLayoutObjectFrom(
svg_root_inline_box_.GetLineLayoutItem()),
- paint_info_before_filtering);
- if (paint_state.ApplyClipMaskAndFilterIfNecessary()) {
- for (InlineBox* child = svg_root_inline_box_.FirstChild(); child;
- child = child->NextOnLine())
- child->Paint(paint_state.GetPaintInfo(), paint_offset, LayoutUnit(),
- LayoutUnit());
+ paint_info);
+ if (!paint_state.ApplyEffects())
+ return;
+ for (InlineBox* child = svg_root_inline_box_.FirstChild(); child;
+ child = child->NextOnLine()) {
+ child->Paint(paint_state.GetPaintInfo(), paint_offset, LayoutUnit(),
+ LayoutUnit());
}
}
diff --git a/chromium/third_party/blink/renderer/core/paint/svg_root_painter.cc b/chromium/third_party/blink/renderer/core/paint/svg_root_painter.cc
index 50f5aab44c8..ccccf6411ca 100644
--- a/chromium/third_party/blink/renderer/core/paint/svg_root_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/svg_root_painter.cc
@@ -53,7 +53,7 @@ void SVGRootPainter::PaintReplaced(const PaintInfo& paint_info,
ScopedSVGPaintState paint_state(layout_svg_root_, paint_info);
if (paint_state.GetPaintInfo().phase == PaintPhase::kForeground &&
- !paint_state.ApplyClipMaskAndFilterIfNecessary())
+ !paint_state.ApplyEffects())
return;
BoxPainter(layout_svg_root_).PaintChildren(paint_state.GetPaintInfo());
diff --git a/chromium/third_party/blink/renderer/core/paint/svg_shape_painter.cc b/chromium/third_party/blink/renderer/core/paint/svg_shape_painter.cc
index 0aea12af64b..1d744ec0f76 100644
--- a/chromium/third_party/blink/renderer/core/paint/svg_shape_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/svg_shape_painter.cc
@@ -4,7 +4,6 @@
#include "third_party/blink/renderer/core/paint/svg_shape_painter.h"
-#include "base/optional.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_shape.h"
#include "third_party/blink/renderer/core/layout/svg/svg_layout_support.h"
@@ -47,25 +46,22 @@ void SVGShapePainter::Paint(const PaintInfo& paint_info) {
layout_svg_shape_.IsShapeEmpty())
return;
- PaintInfo paint_info_before_filtering(paint_info);
-
if (SVGModelObjectPainter(layout_svg_shape_)
- .CullRectSkipsPainting(paint_info_before_filtering)) {
+ .CullRectSkipsPainting(paint_info)) {
return;
}
// Shapes cannot have children so do not call TransformCullRect.
ScopedSVGTransformState transform_state(
- paint_info_before_filtering, layout_svg_shape_,
- layout_svg_shape_.LocalSVGTransform());
+ paint_info, layout_svg_shape_, layout_svg_shape_.LocalSVGTransform());
{
- ScopedSVGPaintState paint_state(layout_svg_shape_,
- paint_info_before_filtering);
- if (paint_state.ApplyClipMaskAndFilterIfNecessary() &&
+ ScopedSVGPaintState paint_state(layout_svg_shape_, paint_info);
+ if (paint_state.ApplyEffects() &&
!DrawingRecorder::UseCachedDrawingIfPossible(
paint_state.GetPaintInfo().context, layout_svg_shape_,
paint_state.GetPaintInfo().phase)) {
- SVGModelObjectPainter::RecordHitTestData(layout_svg_shape_, paint_info);
+ SVGModelObjectPainter::RecordHitTestData(layout_svg_shape_,
+ paint_state.GetPaintInfo());
DrawingRecorder recorder(paint_state.GetPaintInfo().context,
layout_svg_shape_,
paint_state.GetPaintInfo().phase);
@@ -128,8 +124,7 @@ void SVGShapePainter::Paint(const PaintInfo& paint_info) {
}
break;
case PT_MARKERS:
- PaintMarkers(paint_state.GetPaintInfo(),
- layout_svg_shape_.VisualRectInLocalSVGCoordinates());
+ PaintMarkers(paint_state.GetPaintInfo());
break;
default:
NOTREACHED();
@@ -139,8 +134,7 @@ void SVGShapePainter::Paint(const PaintInfo& paint_info) {
}
}
- SVGModelObjectPainter(layout_svg_shape_)
- .PaintOutline(paint_info_before_filtering);
+ SVGModelObjectPainter(layout_svg_shape_).PaintOutline(paint_info);
}
class PathWithTemporaryWindingRule {
@@ -182,8 +176,7 @@ void SVGShapePainter::FillShape(GraphicsContext& context,
void SVGShapePainter::StrokeShape(GraphicsContext& context,
const PaintFlags& flags) {
- if (!layout_svg_shape_.StyleRef().SvgStyle().HasVisibleStroke())
- return;
+ DCHECK(layout_svg_shape_.StyleRef().SvgStyle().HasVisibleStroke());
switch (layout_svg_shape_.GeometryCodePath()) {
case kRectGeometryFastPath:
@@ -204,8 +197,7 @@ void SVGShapePainter::StrokeShape(GraphicsContext& context,
}
}
-void SVGShapePainter::PaintMarkers(const PaintInfo& paint_info,
- const FloatRect& bounding_box) {
+void SVGShapePainter::PaintMarkers(const PaintInfo& paint_info) {
const Vector<MarkerPosition>* marker_positions =
layout_svg_shape_.MarkerPositions();
if (!marker_positions || marker_positions->IsEmpty())
@@ -222,7 +214,7 @@ void SVGShapePainter::PaintMarkers(const PaintInfo& paint_info,
if (!marker_start && !marker_mid && !marker_end)
return;
- float stroke_width = layout_svg_shape_.StrokeWidth();
+ const float stroke_width = layout_svg_shape_.StrokeWidthForMarkerUnits();
for (const MarkerPosition& marker_position : *marker_positions) {
if (LayoutSVGResourceMarker* marker = marker_position.SelectMarker(
diff --git a/chromium/third_party/blink/renderer/core/paint/svg_shape_painter.h b/chromium/third_party/blink/renderer/core/paint/svg_shape_painter.h
index 7be80f48835..8c991f0df31 100644
--- a/chromium/third_party/blink/renderer/core/paint/svg_shape_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/svg_shape_painter.h
@@ -11,7 +11,6 @@
namespace blink {
-class FloatRect;
class GraphicsContext;
class LayoutSVGResourceMarker;
class LayoutSVGShape;
@@ -31,7 +30,7 @@ class SVGShapePainter {
void FillShape(GraphicsContext&, const PaintFlags&, SkPathFillType);
void StrokeShape(GraphicsContext&, const PaintFlags&);
- void PaintMarkers(const PaintInfo&, const FloatRect& bounding_box);
+ void PaintMarkers(const PaintInfo&);
void PaintMarker(const PaintInfo&,
LayoutSVGResourceMarker&,
const MarkerPosition&,
diff --git a/chromium/third_party/blink/renderer/core/paint/svg_text_painter.cc b/chromium/third_party/blink/renderer/core/paint/svg_text_painter.cc
index 8398f6a8f3c..d6a3ec5d4ae 100644
--- a/chromium/third_party/blink/renderer/core/paint/svg_text_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/svg_text_painter.cc
@@ -8,14 +8,14 @@
#include "third_party/blink/renderer/core/paint/block_painter.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
#include "third_party/blink/renderer/core/paint/scoped_svg_paint_state.h"
-#include "third_party/blink/renderer/platform/graphics/paint/hit_test_display_item.h"
+#include "third_party/blink/renderer/core/paint/svg_model_object_painter.h"
namespace blink {
void SVGTextPainter::Paint(const PaintInfo& paint_info) {
if (paint_info.phase != PaintPhase::kForeground &&
paint_info.phase != PaintPhase::kForcedColorsModeBackplate &&
- paint_info.phase != PaintPhase::kSelection)
+ paint_info.phase != PaintPhase::kSelectionDragImage)
return;
PaintInfo block_info(paint_info);
@@ -28,32 +28,16 @@ void SVGTextPainter::Paint(const PaintInfo& paint_info) {
block_info, layout_svg_text_,
layout_svg_text_.LocalToSVGParentTransform());
- RecordHitTestData(paint_info);
+ if (block_info.phase == PaintPhase::kForeground)
+ SVGModelObjectPainter::RecordHitTestData(layout_svg_text_, block_info);
+
BlockPainter(layout_svg_text_).Paint(block_info);
// Paint the outlines, if any
- if (paint_info.phase == PaintPhase::kForeground) {
+ if (block_info.phase == PaintPhase::kForeground) {
block_info.phase = PaintPhase::kOutline;
BlockPainter(layout_svg_text_).Paint(block_info);
}
}
-void SVGTextPainter::RecordHitTestData(const PaintInfo& paint_info) {
- // Hit test display items are only needed for compositing. This flag is used
- // for for printing and drag images which do not need hit testing.
- if (paint_info.GetGlobalPaintFlags() & kGlobalPaintFlattenCompositingLayers)
- return;
-
- if (paint_info.phase != PaintPhase::kForeground)
- return;
-
- auto touch_action = layout_svg_text_.EffectiveAllowedTouchAction();
- if (touch_action == TouchAction::kTouchActionAuto)
- return;
-
- auto rect = LayoutRect(layout_svg_text_.VisualRectInLocalSVGCoordinates());
- HitTestDisplayItem::Record(paint_info.context, layout_svg_text_,
- HitTestRect(rect, touch_action));
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/svg_text_painter.h b/chromium/third_party/blink/renderer/core/paint/svg_text_painter.h
index cb4e44505c4..b05182c36c8 100644
--- a/chromium/third_party/blink/renderer/core/paint/svg_text_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/svg_text_painter.h
@@ -21,11 +21,6 @@ class SVGTextPainter {
void Paint(const PaintInfo&);
private:
- // Paint a hit test display item and record hit test data. This should be
- // called when painting the background even if there is no other painted
- // content.
- void RecordHitTestData(const PaintInfo&);
-
const LayoutSVGText& layout_svg_text_;
};
diff --git a/chromium/third_party/blink/renderer/core/paint/table_painter_test.cc b/chromium/third_party/blink/renderer/core/paint/table_painter_test.cc
index 91436bbf1db..f63f5e08aec 100644
--- a/chromium/third_party/blink/renderer/core/paint/table_painter_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/table_painter_test.cc
@@ -35,7 +35,8 @@ TEST_P(TablePainterTest, Background) {
LayoutObject& row2 = *GetLayoutObjectByElementId("row2");
InvalidateAll(RootPaintController());
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
Paint(IntRect(0, 0, 200, 200));
EXPECT_THAT(
@@ -44,7 +45,8 @@ TEST_P(TablePainterTest, Background) {
DisplayItem::kDocumentBackground),
IsSameId(&row1, DisplayItem::kBoxDecorationBackground)));
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
Paint(IntRect(0, 300, 200, 1000));
EXPECT_THAT(
@@ -77,7 +79,8 @@ TEST_P(TablePainterTest, BackgroundWithCellSpacing) {
LayoutObject& cell2 = *GetLayoutObjectByElementId("cell2");
InvalidateAll(RootPaintController());
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
// Intersects cell1 and the spacing between cell1 and cell2.
Paint(IntRect(0, 200, 200, 150));
@@ -88,7 +91,8 @@ TEST_P(TablePainterTest, BackgroundWithCellSpacing) {
IsSameId(&row1, DisplayItem::kBoxDecorationBackground),
IsSameId(&cell1, DisplayItem::kBoxDecorationBackground)));
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
// Intersects the spacing only.
Paint(IntRect(0, 250, 100, 100));
@@ -98,7 +102,8 @@ TEST_P(TablePainterTest, BackgroundWithCellSpacing) {
DisplayItem::kDocumentBackground),
IsSameId(&row1, DisplayItem::kBoxDecorationBackground)));
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
// Intersects cell2 only.
Paint(IntRect(0, 350, 200, 150));
@@ -130,7 +135,8 @@ TEST_P(TablePainterTest, BackgroundInSelfPaintingRow) {
LayoutObject& row = *GetLayoutObjectByElementId("row");
InvalidateAll(RootPaintController());
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
// Intersects cell1 and the spacing between cell1 and cell2.
Paint(IntRect(200, 0, 200, 200));
@@ -141,7 +147,8 @@ TEST_P(TablePainterTest, BackgroundInSelfPaintingRow) {
IsSameId(&row, DisplayItem::kBoxDecorationBackground),
IsSameId(&cell1, DisplayItem::kBoxDecorationBackground)));
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
// Intersects the spacing only.
Paint(IntRect(300, 0, 100, 100));
@@ -149,7 +156,8 @@ TEST_P(TablePainterTest, BackgroundInSelfPaintingRow) {
ElementsAre(IsSameId(&ViewScrollingBackgroundClient(),
DisplayItem::kDocumentBackground)));
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
// Intersects cell2 only.
Paint(IntRect(450, 0, 200, 200));
@@ -178,7 +186,8 @@ TEST_P(TablePainterTest, CollapsedBorderAndOverflow) {
const LayoutNGTableCellInterface* cell =
ToInterface<LayoutNGTableCellInterface>(cell_layout_object);
InvalidateAll(RootPaintController());
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
// Intersects the overflowing part of cell but not border box.
Paint(IntRect(0, 0, 100, 100));
diff --git a/chromium/third_party/blink/renderer/core/paint/table_row_painter.cc b/chromium/third_party/blink/renderer/core/paint/table_row_painter.cc
index 384e9a722fc..d777b775dc3 100644
--- a/chromium/third_party/blink/renderer/core/paint/table_row_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/table_row_painter.cc
@@ -14,7 +14,6 @@
#include "third_party/blink/renderer/core/paint/scoped_paint_state.h"
#include "third_party/blink/renderer/core/paint/table_cell_painter.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
-#include "third_party/blink/renderer/platform/graphics/paint/hit_test_display_item.h"
namespace blink {
@@ -68,34 +67,16 @@ void TableRowPainter::HandleChangedPartialPaint(
paint_result, paint_info.GetCullRect());
}
-void TableRowPainter::RecordHitTestData(const PaintInfo& paint_info,
- const PhysicalOffset& paint_offset) {
- // Hit test display items are only needed for compositing. This flag is used
- // for for printing and drag images which do not need hit testing.
- if (paint_info.GetGlobalPaintFlags() & kGlobalPaintFlattenCompositingLayers)
- return;
-
- // If an object is not visible, it does not participate in hit testing.
- if (layout_table_row_.StyleRef().Visibility() != EVisibility::kVisible)
- return;
-
- auto touch_action = layout_table_row_.EffectiveAllowedTouchAction();
- if (touch_action == TouchAction::kTouchActionAuto)
- return;
-
- auto rect = layout_table_row_.PhysicalBorderBoxRect();
- rect.offset += paint_offset;
- HitTestDisplayItem::Record(paint_info.context, layout_table_row_,
- HitTestRect(rect.ToLayoutRect(), touch_action));
-}
-
void TableRowPainter::PaintBoxDecorationBackground(
const PaintInfo& paint_info,
const CellSpan& dirtied_columns) {
ScopedPaintState paint_state(layout_table_row_, paint_info);
const auto& local_paint_info = paint_state.GetPaintInfo();
auto paint_offset = paint_state.PaintOffset();
- RecordHitTestData(local_paint_info, paint_offset);
+ PhysicalRect paint_rect(paint_offset, layout_table_row_.Size());
+
+ BoxPainter(layout_table_row_)
+ .RecordHitTestData(local_paint_info, paint_rect, layout_table_row_);
bool has_background = layout_table_row_.StyleRef().HasBackground();
bool has_box_shadow = layout_table_row_.StyleRef().BoxShadow();
@@ -111,7 +92,6 @@ void TableRowPainter::PaintBoxDecorationBackground(
DrawingRecorder recorder(local_paint_info.context, layout_table_row_,
DisplayItem::kBoxDecorationBackground);
- PhysicalRect paint_rect(paint_offset, layout_table_row_.Size());
if (has_box_shadow) {
BoxPainterBase::PaintNormalBoxShadow(local_paint_info, paint_rect,
diff --git a/chromium/third_party/blink/renderer/core/paint/table_row_painter.h b/chromium/third_party/blink/renderer/core/paint/table_row_painter.h
index 09716046eb4..95dd74fa978 100644
--- a/chromium/third_party/blink/renderer/core/paint/table_row_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/table_row_painter.h
@@ -13,7 +13,6 @@ namespace blink {
class CellSpan;
class LayoutTableRow;
struct PaintInfo;
-struct PhysicalOffset;
class TableRowPainter {
STACK_ALLOCATED();
@@ -31,10 +30,6 @@ class TableRowPainter {
private:
void HandleChangedPartialPaint(const PaintInfo&,
const CellSpan& dirtied_columns);
- // Paint a hit test display item and record hit test data. This should be
- // called in the background paint phase even if there is no other painted
- // content.
- void RecordHitTestData(const PaintInfo&, const PhysicalOffset& paint_offset);
const LayoutTableRow& layout_table_row_;
};
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 6641f3e2275..374063ce4c3 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
@@ -19,6 +19,7 @@
#include "third_party/blink/renderer/core/paint/table_row_painter.h"
#include "third_party/blink/renderer/platform/graphics/paint/display_item_cache_skipper.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 {
@@ -43,11 +44,14 @@ void TableSectionPainter::Paint(const PaintInfo& paint_info) {
return;
}
+ unsigned fragment_index = 0;
for (const auto* fragment = &layout_table_section_.FirstFragment(); fragment;
fragment = fragment->NextFragment()) {
PaintInfo fragment_paint_info = paint_info;
fragment_paint_info.SetFragmentLogicalTopInFlowThread(
fragment->LogicalTopInFlowThread());
+ ScopedDisplayItemFragment scoped_display_item_fragment(
+ fragment_paint_info.context, fragment_index++);
PaintSection(fragment_paint_info);
}
}
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 e6e149f5129..676b3e86c54 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(blink::Visitor* visitor) {
+void TextElementTiming::Trace(Visitor* visitor) {
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 664a4aed6cc..10f91076462 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(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
Member<WindowPerformance> performance_;
diff --git a/chromium/third_party/blink/renderer/core/paint/text_paint_style.h b/chromium/third_party/blink/renderer/core/paint/text_paint_style.h
index e5411fdebd5..e184e7338ce 100644
--- a/chromium/third_party/blink/renderer/core/paint/text_paint_style.h
+++ b/chromium/third_party/blink/renderer/core/paint/text_paint_style.h
@@ -24,14 +24,16 @@ struct CORE_EXPORT TextPaintStyle {
float stroke_width;
const ShadowList* shadow;
- bool operator==(const TextPaintStyle& other) {
+ bool operator==(const TextPaintStyle& other) const {
return current_color == other.current_color &&
fill_color == other.fill_color &&
stroke_color == other.stroke_color &&
emphasis_mark_color == other.emphasis_mark_color &&
stroke_width == other.stroke_width && shadow == other.shadow;
}
- bool operator!=(const TextPaintStyle& other) { return !(*this == other); }
+ bool operator!=(const TextPaintStyle& other) const {
+ return !(*this == other);
+ }
};
} // namespace blink
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 93c7e63670a..196fc8e59cd 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(blink::Visitor* visitor) {
+void TextPaintTimingDetector::Trace(Visitor* visitor) {
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(blink::Visitor* visitor) {
+void LargestTextPaintManager::Trace(Visitor* visitor) {
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(blink::Visitor* visitor) {
+void TextRecordsManager::Trace(Visitor* visitor) {
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 500a3003a8c..6f48bf95211 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(blink::Visitor*);
+ void Trace(Visitor*);
private:
friend class LargestContentfulPaintCalculatorTest;
@@ -148,7 +148,7 @@ class CORE_EXPORT TextRecordsManager {
return ltp_manager_.has_value();
}
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
friend class LargestContentfulPaintCalculatorTest;
@@ -216,7 +216,7 @@ class CORE_EXPORT TextPaintTimingDetector final
return records_manager_.UpdateCandidate();
}
void ReportSwapTime(base::TimeTicks timestamp);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
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 4cdf7c03b0f..9cec3867170 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
@@ -108,7 +108,11 @@ class TextPaintTimingDetectorTest : public testing::Test {
}
void SimulateScroll() {
- GetPaintTimingDetector().NotifyScroll(ScrollType::kUserScroll);
+ GetPaintTimingDetector().NotifyScroll(mojom::blink::ScrollType::kUser);
+ }
+
+ void SimulateKeyUp() {
+ GetPaintTimingDetector().NotifyInputEvent(WebInputEvent::kKeyUp);
}
void InvokeCallback() {
@@ -145,8 +149,7 @@ class TextPaintTimingDetectorTest : public testing::Test {
void SetChildBodyInnerHTML(const String& content) {
GetChildDocument()->SetBaseURLOverride(KURL("http://test.com"));
- GetChildDocument()->body()->SetInnerHTMLFromString(content,
- ASSERT_NO_EXCEPTION);
+ GetChildDocument()->body()->setInnerHTML(content, ASSERT_NO_EXCEPTION);
child_frame_mock_callback_manager_ =
MakeGarbageCollected<MockPaintTimingCallbackManager>();
GetChildFrameTextPaintTimingDetector()->ResetCallbackManager(
@@ -155,8 +158,7 @@ class TextPaintTimingDetectorTest : public testing::Test {
}
void UpdateAllLifecyclePhases() {
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
}
// This only triggers ReportSwapTime in main frame.
@@ -236,6 +238,25 @@ class TextPaintTimingDetectorTest : public testing::Test {
Persistent<MockPaintTimingCallbackManager> child_frame_mock_callback_manager_;
};
+// Helper class to run the same test code with and without LayoutNG
+class ParameterizedTextPaintTimingDetectorTest
+ : public ::testing::WithParamInterface<bool>,
+ private ScopedLayoutNGForTest,
+ public TextPaintTimingDetectorTest {
+ public:
+ ParameterizedTextPaintTimingDetectorTest()
+ : ScopedLayoutNGForTest(GetParam()) {}
+
+ protected:
+ bool LayoutNGEnabled() const {
+ return RuntimeEnabledFeatures::LayoutNGEnabled();
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(All,
+ ParameterizedTextPaintTimingDetectorTest,
+ testing::Bool());
+
TEST_F(TextPaintTimingDetectorTest, LargestTextPaint_NoText) {
SetBodyInnerHTML(R"HTML(
)HTML");
@@ -422,8 +443,7 @@ TEST_F(TextPaintTimingDetectorTest, PendingTextIsLargest) {
SetBodyInnerHTML(R"HTML(
)HTML");
AppendDivElementToBody("text");
- GetFrameView().UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetFrameView().UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
// We do not call swap-time callback here in order to not set the paint time.
EXPECT_FALSE(TextRecordOfLargestTextPaint());
}
@@ -434,12 +454,10 @@ TEST_F(TextPaintTimingDetectorTest, VisitSameNodeTwiceBeforePaintTimeIsSet) {
SetBodyInnerHTML(R"HTML(
)HTML");
Element* text = AppendDivElementToBody("text");
- GetFrameView().UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetFrameView().UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
// Change a property of the text to trigger repaint.
text->setAttribute(html_names::kStyleAttr, AtomicString("color:red;"));
- GetFrameView().UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetFrameView().UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
InvokeCallback();
EXPECT_EQ(TextRecordOfLargestTextPaint()->node_id,
DOMNodeIds::ExistingIdForNode(text));
@@ -544,6 +562,17 @@ TEST_F(TextPaintTimingDetectorTest,
EXPECT_FALSE(GetLargestTextPaintManager());
}
+TEST_F(TextPaintTimingDetectorTest, KeepLargestTextPaintMangerAfterUserInput) {
+ SetBodyInnerHTML(R"HTML(
+ )HTML");
+ AppendDivElementToBody("text");
+ UpdateAllLifecyclePhasesAndSimulateSwapTime();
+ EXPECT_TRUE(GetLargestTextPaintManager());
+
+ SimulateKeyUp();
+ EXPECT_TRUE(GetLargestTextPaintManager());
+}
+
TEST_F(TextPaintTimingDetectorTest, LargestTextPaint_ReportLastNullCandidate) {
SetBodyInnerHTML(R"HTML(
)HTML");
@@ -607,7 +636,7 @@ TEST_F(TextPaintTimingDetectorTest, CaptureFileUploadController) {
DOMNodeIds::ExistingIdForNode(element));
}
-TEST_F(TextPaintTimingDetectorTest, CapturingListMarkers) {
+TEST_P(ParameterizedTextPaintTimingDetectorTest, CapturingListMarkers) {
SetBodyInnerHTML(R"HTML(
<ul>
<li>List item</li>
@@ -618,7 +647,7 @@ TEST_F(TextPaintTimingDetectorTest, CapturingListMarkers) {
)HTML");
UpdateAllLifecyclePhasesAndSimulateSwapTime();
- EXPECT_EQ(CountVisibleTexts(), 2u);
+ EXPECT_EQ(CountVisibleTexts(), LayoutNGEnabled() ? 3u : 2u);
}
TEST_F(TextPaintTimingDetectorTest, CaptureSVGText) {
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 419b89adbb9..e6b2b918f1f 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
@@ -131,8 +131,7 @@ TextPaintStyle TextPainterBase::TextPaintingStyle(const Document& document,
text_style.shadow = style.TextShadow();
// Adjust text color when printing with a white background.
- DCHECK(document.Printing() == is_printing ||
- RuntimeEnabledFeatures::PrintBrowserEnabled());
+ DCHECK_EQ(document.Printing(), is_printing);
bool force_background_to_white =
BoxPainterBase::ShouldForceWhiteBackgroundForPrintEconomy(document,
style);
@@ -179,6 +178,9 @@ void TextPainterBase::DecorationsStripeIntercepts(
// pixel makes sure we're always covering. This should only be done on the
// clipping rectangle, not when computing the glyph intersects.
clip_rect.InflateY(1.0);
+
+ if (!clip_rect.IsFinite())
+ continue;
graphics_context_.ClipOut(clip_rect);
}
}
diff --git a/chromium/third_party/blink/renderer/core/paint/theme_painter.cc b/chromium/third_party/blink/renderer/core/paint/theme_painter.cc
index 8535fc1e91c..343d3275d4a 100644
--- a/chromium/third_party/blink/renderer/core/paint/theme_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/theme_painter.cc
@@ -24,15 +24,12 @@
#include "build/build_config.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_rect.h"
-#include "third_party/blink/renderer/core/frame/deprecation.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/html/forms/html_data_list_element.h"
#include "third_party/blink/renderer/core/html/forms/html_data_list_options_collection.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/forms/html_option_element.h"
#include "third_party/blink/renderer/core/html/forms/html_select_element.h"
-#include "third_party/blink/renderer/core/html/forms/html_text_area_element.h"
-#include "third_party/blink/renderer/core/html/forms/spin_button_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/input_type_names.h"
@@ -44,6 +41,7 @@
#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
+#include "ui/base/ui_base_features.h"
#include "ui/native_theme/native_theme.h"
// The methods in this file are shared by all themes on every platform.
@@ -73,28 +71,12 @@ static ui::NativeTheme::ColorScheme ToNativeColorScheme(
}
}
-bool IsTemporalInput(const AtomicString& type) {
+bool IsMultipleFieldsTemporalInput(const AtomicString& type) {
+#if !defined(OS_ANDROID)
return type == input_type_names::kDate ||
type == input_type_names::kDatetimeLocal ||
type == input_type_names::kMonth || type == input_type_names::kTime ||
type == input_type_names::kWeek;
-}
-
-bool IsMenulistInput(const Node* node) {
- if (auto* input = DynamicTo<HTMLInputElement>(node)) {
-#if defined(OS_ANDROID)
- if (IsTemporalInput(input->type()))
- return true;
-#endif
- return input->type() == input_type_names::kColor &&
- input->FastHasAttribute(html_names::kListAttr);
- }
- return false;
-}
-
-bool IsMultipleFieldsTemporalInput(const AtomicString& type) {
-#if !defined(OS_ANDROID)
- return IsTemporalInput(type);
#else
return false;
#endif
@@ -106,33 +88,23 @@ ThemePainter::ThemePainter() = default;
#define COUNT_APPEARANCE(doc, feature) \
doc.CountUse(WebFeature::kCSSValueAppearance##feature##Rendered)
-#define DEPRECATE_APPEARANCE(doc, feature) \
- Deprecation::CountDeprecation( \
- doc, WebFeature::kCSSValueAppearance##feature##Rendered)
void CountAppearanceTextFieldPart(const Node* node) {
- if (!node) {
- return;
- }
- UseCounter::Count(node->GetDocument(),
- WebFeature::kCSSValueAppearanceTextFieldRendered);
- WebFeature feature =
- WebFeature::kCSSValueAppearanceTextFieldForOthersRendered;
+ DCHECK(node);
if (auto* input = DynamicTo<HTMLInputElement>(node)) {
const AtomicString& type = input->type();
if (type == input_type_names::kSearch) {
- feature = WebFeature::kCSSValueAppearanceTextFieldForSearch;
+ UseCounter::Count(node->GetDocument(),
+ WebFeature::kCSSValueAppearanceTextFieldForSearch);
} else if (input->IsTextField()) {
- feature = WebFeature::kCSSValueAppearanceTextFieldForTextField;
+ UseCounter::Count(node->GetDocument(),
+ WebFeature::kCSSValueAppearanceTextFieldForTextField);
} else if (IsMultipleFieldsTemporalInput(type)) {
- feature = WebFeature::kCSSValueAppearanceTextFieldForTemporalRendered;
+ UseCounter::Count(
+ node->GetDocument(),
+ WebFeature::kCSSValueAppearanceTextFieldForTemporalRendered);
}
}
- if (feature == WebFeature::kCSSValueAppearanceTextFieldForOthersRendered) {
- Deprecation::CountDeprecation(node->GetDocument(), feature);
- } else {
- UseCounter::Count(node->GetDocument(), feature);
- }
}
// Returns true; Needs CSS painting and/or PaintBorderOnly().
@@ -143,18 +115,16 @@ bool ThemePainter::Paint(const LayoutObject& o,
Document& doc = o.GetDocument();
const ComputedStyle& style = o.StyleRef();
ControlPart part = o.StyleRef().EffectiveAppearance();
+ // LayoutTheme::AdjustAppearanceWithElementType() ensures |node| is a
+ // non-null Element.
+ DCHECK(node);
+ DCHECK_NE(part, kNoControlPart);
if (LayoutTheme::GetTheme().ShouldUseFallbackTheme(style))
return PaintUsingFallbackTheme(node, style, paint_info, r);
- // TODO(tkent): Clean the counting code when M80 is promoted to the stable
- // channel.
- if (part == kButtonPart && node) {
- if (IsA<HTMLAnchorElement>(node)) {
- Deprecation::CountDeprecation(
- doc, WebFeature::kCSSValueAppearanceButtonForAnchor);
- COUNT_APPEARANCE(doc, ButtonForNonButton);
- } else if (IsA<HTMLButtonElement>(node)) {
+ if (part == kButtonPart) {
+ if (IsA<HTMLButtonElement>(node)) {
UseCounter::Count(doc, WebFeature::kCSSValueAppearanceButtonForButton);
} else if (IsA<HTMLInputElement>(node) &&
To<HTMLInputElement>(node)->IsTextButton()) {
@@ -166,22 +136,6 @@ bool ThemePainter::Paint(const LayoutObject& o,
To<HTMLInputElement>(node)->type() == input_type_names::kColor) {
// 'button' for input[type=color], of which default appearance is
// 'square-button', is not deprecated.
- } else {
- COUNT_APPEARANCE(doc, ButtonForNonButton);
- COUNT_APPEARANCE(doc, ButtonForOthers);
- if (IsA<HTMLSelectElement>(node) &&
- To<HTMLSelectElement>(node)->UsesMenuList()) {
- DEPRECATE_APPEARANCE(doc, ButtonForSelect);
- } else {
- const AtomicString& type =
- To<Element>(node)->getAttribute(html_names::kTypeAttr);
- // https://github.com/twbs/bootstrap/pull/29053
- if (type == "button" || type == "reset" || type == "submit") {
- DEPRECATE_APPEARANCE(doc, ButtonForBootstrapLooseSelector);
- } else {
- DEPRECATE_APPEARANCE(doc, ButtonForOthers2);
- }
- }
}
}
@@ -189,30 +143,18 @@ bool ThemePainter::Paint(const LayoutObject& o,
switch (part) {
case kCheckboxPart: {
COUNT_APPEARANCE(doc, Checkbox);
- auto* input = DynamicTo<HTMLInputElement>(node);
- if (!input || input->type() != input_type_names::kCheckbox)
- DEPRECATE_APPEARANCE(doc, CheckboxForOthers);
return PaintCheckbox(node, o.GetDocument(), style, paint_info, r);
}
case kRadioPart: {
COUNT_APPEARANCE(doc, Radio);
- auto* input = DynamicTo<HTMLInputElement>(node);
- if (!input || input->type() != input_type_names::kRadio)
- DEPRECATE_APPEARANCE(doc, RadioForOthers);
return PaintRadio(node, o.GetDocument(), style, paint_info, r);
}
case kPushButtonPart: {
COUNT_APPEARANCE(doc, PushButton);
- auto* input = DynamicTo<HTMLInputElement>(node);
- if (!input || !input->IsTextButton())
- DEPRECATE_APPEARANCE(doc, PushButtonForOthers);
return PaintButton(node, o.GetDocument(), style, paint_info, r);
}
case kSquareButtonPart: {
COUNT_APPEARANCE(doc, SquareButton);
- auto* input = DynamicTo<HTMLInputElement>(node);
- if (!input || input->type() != input_type_names::kColor)
- DEPRECATE_APPEARANCE(doc, SquareButtonForOthers);
return PaintButton(node, o.GetDocument(), style, paint_info, r);
}
case kButtonPart:
@@ -220,54 +162,31 @@ bool ThemePainter::Paint(const LayoutObject& o,
return PaintButton(node, o.GetDocument(), style, paint_info, r);
case kInnerSpinButtonPart: {
COUNT_APPEARANCE(doc, InnerSpinButton);
- if (!DynamicTo<SpinButtonElement>(node))
- DEPRECATE_APPEARANCE(doc, InnerSpinButtonForOthers);
return PaintInnerSpinButton(node, style, paint_info, r);
}
case kMenulistPart:
COUNT_APPEARANCE(doc, MenuList);
- if (!IsA<HTMLSelectElement>(node) && !IsMenulistInput(node))
- DEPRECATE_APPEARANCE(doc, MenuListForOthers);
return PaintMenuList(node, o.GetDocument(), style, paint_info, r);
case kMeterPart:
- if (node && !IsA<HTMLMeterElement>(node) &&
- !IsA<HTMLMeterElement>(node->OwnerShadowHost()))
- DEPRECATE_APPEARANCE(doc, MeterForOthers);
return true;
case kProgressBarPart:
COUNT_APPEARANCE(doc, ProgressBar);
- if (!o.IsProgress())
- DEPRECATE_APPEARANCE(doc, ProgressBarForOthers);
// Note that |-webkit-appearance: progress-bar| works only for <progress>.
return PaintProgressBar(o, paint_info, r);
case kSliderHorizontalPart: {
COUNT_APPEARANCE(doc, SliderHorizontal);
- auto* input = DynamicTo<HTMLInputElement>(node);
- if (!input || input->type() != input_type_names::kRange)
- DEPRECATE_APPEARANCE(doc, SliderHorizontalForOthers);
return PaintSliderTrack(o, paint_info, r);
}
case kSliderVerticalPart: {
COUNT_APPEARANCE(doc, SliderVertical);
- auto* input = DynamicTo<HTMLInputElement>(node);
- if (!input || input->type() != input_type_names::kRange)
- DEPRECATE_APPEARANCE(doc, SliderVerticalForOthers);
return PaintSliderTrack(o, paint_info, r);
}
case kSliderThumbHorizontalPart: {
COUNT_APPEARANCE(doc, SliderThumbHorizontal);
- auto* input =
- DynamicTo<HTMLInputElement>(node ? node->OwnerShadowHost() : nullptr);
- if (!input || input->type() != input_type_names::kRange)
- DEPRECATE_APPEARANCE(doc, SliderThumbHorizontalForOthers);
return PaintSliderThumb(node, style, paint_info, r);
}
case kSliderThumbVerticalPart: {
COUNT_APPEARANCE(doc, SliderThumbVertical);
- auto* input =
- DynamicTo<HTMLInputElement>(node ? node->OwnerShadowHost() : nullptr);
- if (!input || input->type() != input_type_names::kRange)
- DEPRECATE_APPEARANCE(doc, SliderThumbVerticalForOthers);
return PaintSliderThumb(node, style, paint_info, r);
}
case kMediaSliderPart:
@@ -278,53 +197,26 @@ bool ThemePainter::Paint(const LayoutObject& o,
case kMenulistButtonPart:
return true;
case kTextFieldPart:
- if (!RuntimeEnabledFeatures::FormControlsRefreshEnabled()) {
+ if (!features::IsFormControlsRefreshEnabled()) {
return true;
}
CountAppearanceTextFieldPart(node);
return PaintTextField(node, style, paint_info, r);
case kTextAreaPart:
- if (!RuntimeEnabledFeatures::FormControlsRefreshEnabled()) {
+ if (!features::IsFormControlsRefreshEnabled()) {
return true;
}
- if (node) {
- const auto& doc = node->GetDocument();
- COUNT_APPEARANCE(doc, TextArea);
- if (!IsA<HTMLTextAreaElement>(node))
- DEPRECATE_APPEARANCE(doc, TextAreaForOthers);
- }
+ COUNT_APPEARANCE(doc, TextArea);
return PaintTextArea(node, style, paint_info, r);
case kSearchFieldPart: {
COUNT_APPEARANCE(doc, SearchField);
- auto* input = DynamicTo<HTMLInputElement>(node);
- if (!input || input->type() != input_type_names::kSearch)
- DEPRECATE_APPEARANCE(doc, SearchFieldForOthers);
return PaintSearchField(node, style, paint_info, r);
}
case kSearchFieldCancelButtonPart: {
COUNT_APPEARANCE(doc, SearchCancel);
- auto* element = DynamicTo<Element>(node);
- if (!element || !element->OwnerShadowHost()) {
- COUNT_APPEARANCE(doc, SearchCancelForOthers);
- DEPRECATE_APPEARANCE(doc, SearchCancelForOthers2);
- } else {
- const AtomicString& shadow_id =
- element->FastGetAttribute(html_names::kIdAttr);
- if (shadow_id == shadow_element_names::SearchClearButton()) {
- // Count nothing.
- } else if (shadow_id == shadow_element_names::ClearButton()) {
- COUNT_APPEARANCE(doc, SearchCancelForOthers);
- } else {
- COUNT_APPEARANCE(doc, SearchCancelForOthers);
- DEPRECATE_APPEARANCE(doc, SearchCancelForOthers2);
- }
- }
return PaintSearchFieldCancelButton(o, paint_info, r);
}
case kListboxPart:
- if (!IsA<HTMLSelectElement>(node) ||
- To<HTMLSelectElement>(node)->UsesMenuList())
- DEPRECATE_APPEARANCE(doc, ListboxForOthers);
return true;
default:
break;
@@ -342,21 +234,16 @@ bool ThemePainter::PaintBorderOnly(const Node* node,
// Call the appropriate paint method based off the appearance value.
switch (style.EffectiveAppearance()) {
case kTextFieldPart:
- if (RuntimeEnabledFeatures::FormControlsRefreshEnabled()) {
+ if (features::IsFormControlsRefreshEnabled()) {
return false;
}
CountAppearanceTextFieldPart(node);
return PaintTextField(node, style, paint_info, r);
case kTextAreaPart:
- if (RuntimeEnabledFeatures::FormControlsRefreshEnabled()) {
+ if (features::IsFormControlsRefreshEnabled()) {
return false;
}
- if (node) {
- const auto& doc = node->GetDocument();
- COUNT_APPEARANCE(doc, TextArea);
- if (!IsA<HTMLTextAreaElement>(node))
- DEPRECATE_APPEARANCE(doc, TextAreaForOthers);
- }
+ COUNT_APPEARANCE(node->GetDocument(), TextArea);
return PaintTextArea(node, style, paint_info, r);
case kMenulistButtonPart:
case kSearchFieldPart:
@@ -378,11 +265,9 @@ bool ThemePainter::PaintBorderOnly(const Node* node,
// Supported appearance values don't need CSS border painting.
return false;
default:
- if (node) {
- UseCounter::Count(
- node->GetDocument(),
- WebFeature::kCSSValueAppearanceNoImplementationSkipBorder);
- }
+ UseCounter::Count(
+ node->GetDocument(),
+ WebFeature::kCSSValueAppearanceNoImplementationSkipBorder);
// TODO(tkent): Should do CSS border painting for non-supported
// appearance values.
return false;
@@ -400,8 +285,6 @@ bool ThemePainter::PaintDecorations(const Node* node,
switch (style.EffectiveAppearance()) {
case kMenulistButtonPart:
COUNT_APPEARANCE(document, MenuListButton);
- if (!IsA<HTMLSelectElement>(node) && !IsMenulistInput(node))
- DEPRECATE_APPEARANCE(document, MenuListButtonForOthers);
return PaintMenuListButton(node, document, style, paint_info, r);
case kTextFieldPart:
case kTextAreaPart:
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 cc25ef54157..9da24a1c670 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
@@ -38,6 +38,7 @@
#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h"
+#include "ui/base/ui_base_features.h"
namespace blink {
@@ -151,8 +152,7 @@ bool ThemePainterDefault::PaintCheckbox(const Node* node,
extra_params.button.zoom = zoom_level;
GraphicsContextStateSaver state_saver(paint_info.context, false);
IntRect unzoomed_rect = rect;
- if (zoom_level != 1 &&
- !RuntimeEnabledFeatures::FormControlsRefreshEnabled()) {
+ if (zoom_level != 1 && !features::IsFormControlsRefreshEnabled()) {
state_saver.Save();
unzoomed_rect.SetWidth(unzoomed_rect.Width() / zoom_level);
unzoomed_rect.SetHeight(unzoomed_rect.Height() / zoom_level);
@@ -227,12 +227,15 @@ bool ThemePainterDefault::PaintTextField(const Node* node,
WebThemeEngine::ExtraParams extra_params;
extra_params.text_field.is_text_area = part == kTextAreaPart;
extra_params.text_field.is_listbox = part == kListboxPart;
+ extra_params.text_field.has_border = true;
cc::PaintCanvas* canvas = paint_info.context.Canvas();
Color background_color =
style.VisitedDependentColor(GetCSSPropertyBackgroundColor());
extra_params.text_field.background_color = background_color.Rgb();
+ extra_params.text_field.auto_complete_active =
+ DynamicTo<HTMLFormControlElement>(node)->IsAutofilled();
Platform::Current()->ThemeEngine()->Paint(
canvas, WebThemeEngine::kPartTextField, GetWebThemeState(node),
@@ -307,9 +310,8 @@ void ThemePainterDefault::SetupMenuListArrow(
theme_.ClampedMenuListArrowPaddingSize(document.GetFrame(), style);
float arrow_scale_factor = arrow_box_width / theme_.MenuListArrowWidthInDIP();
// TODO(tkent): This should be 7.0 to match scroll bar buttons.
- float arrow_size =
- (RuntimeEnabledFeatures::FormControlsRefreshEnabled() ? 8.0 : 6.0) *
- arrow_scale_factor;
+ float arrow_size = (features::IsFormControlsRefreshEnabled() ? 8.0 : 6.0) *
+ arrow_scale_factor;
// Put the arrow at the center of paddingForArrow area.
// |arrowX| is the left position for Aura theme engine.
extra_params.menu_list.arrow_x =
@@ -336,8 +338,7 @@ bool ThemePainterDefault::PaintSliderTrack(const LayoutObject& o,
extra_params.slider.zoom = zoom_level;
GraphicsContextStateSaver state_saver(i.context, false);
IntRect unzoomed_rect = rect;
- if (zoom_level != 1 &&
- !RuntimeEnabledFeatures::FormControlsRefreshEnabled()) {
+ if (zoom_level != 1 && !features::IsFormControlsRefreshEnabled()) {
state_saver.Save();
unzoomed_rect.SetWidth(unzoomed_rect.Width() / zoom_level);
unzoomed_rect.SetHeight(unzoomed_rect.Height() / zoom_level);
@@ -357,7 +358,7 @@ bool ThemePainterDefault::PaintSliderTrack(const LayoutObject& o,
LayoutBox* thumb = thumb_element ? thumb_element->GetLayoutBox() : nullptr;
if (thumb) {
IntRect thumb_rect = PixelSnappedIntRect(thumb->FrameRect());
- if (RuntimeEnabledFeatures::FormControlsRefreshEnabled()) {
+ if (features::IsFormControlsRefreshEnabled()) {
extra_params.slider.thumb_x = thumb_rect.X();
extra_params.slider.thumb_y = thumb_rect.Y();
} else {
@@ -387,8 +388,7 @@ bool ThemePainterDefault::PaintSliderThumb(const Node* node,
extra_params.slider.zoom = zoom_level;
GraphicsContextStateSaver state_saver(paint_info.context, false);
IntRect unzoomed_rect = rect;
- if (zoom_level != 1 &&
- !RuntimeEnabledFeatures::FormControlsRefreshEnabled()) {
+ if (zoom_level != 1 && !features::IsFormControlsRefreshEnabled()) {
state_saver.Save();
unzoomed_rect.SetWidth(unzoomed_rect.Width() / zoom_level);
unzoomed_rect.SetHeight(unzoomed_rect.Height() / 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 27c37014ec4..b15d3ec197a 100644
--- a/chromium/third_party/blink/renderer/core/paint/video_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/video_painter.cc
@@ -41,6 +41,11 @@ void VideoPainter::PaintReplaced(const PaintInfo& paint_info,
PhysicalRect content_box_rect = layout_video_.PhysicalContentBoxRect();
content_box_rect.Move(paint_offset);
+ if (context.IsPaintingPreview()) {
+ context.SetURLForRect(layout_video_.GetDocument().Url(),
+ snapped_replaced_rect);
+ }
+
// Since we may have changed the location of the replaced content, we need to
// notify PaintArtifactCompositor.
if (layout_video_.GetFrameView())
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 3e03db3ede0..954e9b4fb13 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
@@ -4,9 +4,13 @@
#include "third_party/blink/renderer/core/paint/video_painter.h"
+#include "base/unguessable_token.h"
#include "cc/layers/layer.h"
+#include "components/paint_preview/common/paint_preview_tracker.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_size.h"
+#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
+#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/core/paint/paint_controller_paint_test.h"
#include "third_party/blink/renderer/platform/testing/empty_web_media_player.h"
@@ -86,17 +90,87 @@ TEST_F(VideoPainterTestForCAP, VideoLayerAppearsInLayerTree) {
// Fetch the layer associated with the <video>, and check that it was
// correctly configured in the layer tree.
- HTMLMediaElement* element =
- ToHTMLMediaElement(GetDocument().body()->firstChild());
+ auto* element = To<HTMLMediaElement>(GetDocument().body()->firstChild());
StubWebMediaPlayer* player =
static_cast<StubWebMediaPlayer*>(element->GetWebMediaPlayer());
const cc::Layer* layer = player->GetCcLayer();
ASSERT_TRUE(layer);
EXPECT_TRUE(HasLayerAttached(*layer));
- // The layer bounds reflects the aspectn ratio and object-fit of the video.
- EXPECT_EQ(gfx::Vector2dF(8, 83), layer->offset_to_transform_parent());
+ // The layer bounds reflects the aspect ratio and object-fit of the video.
+ EXPECT_EQ(gfx::Vector2dF(0, 75), layer->offset_to_transform_parent());
EXPECT_EQ(gfx::Size(300, 150), layer->bounds());
}
+class VideoPaintPreviewTest : public testing::Test,
+ public PaintTestConfigurations {
+ public:
+ void SetUp() override {
+ web_view_helper_.Initialize();
+
+ WebLocalFrameImpl& frame_impl = GetLocalMainFrame();
+ frame_impl.ViewImpl()->MainFrameWidget()->Resize(WebSize(bounds().size()));
+
+ frame_test_helpers::LoadFrame(&GetLocalMainFrame(), "about:blank");
+ GetDocument().View()->SetParentVisible(true);
+ GetDocument().View()->SetSelfVisible(true);
+ }
+
+ void SetBodyInnerHTML(const std::string& content) {
+ frame_test_helpers::LoadHTMLString(&GetLocalMainFrame(), content,
+ KURL("http://test.com"));
+ }
+
+ Document& GetDocument() { return *GetFrame()->GetDocument(); }
+
+ WebLocalFrameImpl& GetLocalMainFrame() {
+ return *web_view_helper_.LocalMainFrame();
+ }
+
+ const gfx::Rect& bounds() { return bounds_; }
+
+ private:
+ LocalFrame* GetFrame() { return GetLocalMainFrame().GetFrame(); }
+
+ frame_test_helpers::WebViewHelper web_view_helper_;
+ gfx::Rect bounds_ = {0, 0, 640, 480};
+};
+
+INSTANTIATE_PAINT_TEST_SUITE_P(VideoPaintPreviewTest);
+
+TEST_P(VideoPaintPreviewTest, URLIsRecordedWhenPaintingPreview) {
+ // Insert a <video> and allow it to begin loading. The image was taken from
+ // the RFC for the data URI scheme https://tools.ietf.org/html/rfc2397.
+ SetBodyInnerHTML(R"HTML(
+ <style>body{margin:0}</style>
+ <video width=300 height=300 src="test.ogv" poster="data:image/gif;base64,R0
+ lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAwAAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yq
+ mCYsapyuvUUlvONmOZtfzgFzByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP
+ 5yLWGsEbtLiOSpa/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGe
+ jmJlZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uisF81M1O
+ IcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PHhhx4dbgYKAAA7"
+ controls>
+ )HTML");
+ test::RunPendingTasks();
+
+ auto token = base::UnguessableToken::Create();
+ const base::UnguessableToken embedding_token =
+ base::UnguessableToken::Create();
+ const bool is_main_frame = true;
+
+ cc::PaintRecorder recorder;
+ paint_preview::PaintPreviewTracker tracker(token, embedding_token,
+ is_main_frame);
+ cc::PaintCanvas* canvas =
+ recorder.beginRecording(bounds().width(), bounds().height());
+ canvas->SetPaintPreviewTracker(&tracker);
+
+ EXPECT_EQ(0lu, tracker.GetLinks().size());
+ GetLocalMainFrame().CapturePaintPreview(WebRect(bounds()), canvas);
+
+ ASSERT_EQ(1lu, tracker.GetLinks().size());
+ EXPECT_EQ("http://test.com/", tracker.GetLinks()[0].url);
+ EXPECT_EQ(gfx::Rect(300, 300), tracker.GetLinks()[0].rect);
+}
+
} // namespace
} // namespace blink
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 2b8c3cc46eb..1ce2481e0a0 100644
--- a/chromium/third_party/blink/renderer/core/paint/view_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/view_painter.cc
@@ -33,6 +33,38 @@ void ViewPainter::Paint(const PaintInfo& paint_info) {
BlockPainter(layout_view_).Paint(paint_info);
}
+// Behind the root element of the main frame of the page, there is an infinite
+// canvas. This is by default white, but it can be overridden by
+// BaseBackgroundColor on the LocalFrameView.
+// https://drafts.fxtf.org/compositing/#rootgroup
+void ViewPainter::PaintRootGroup(const PaintInfo& paint_info,
+ const IntRect& pixel_snapped_background_rect,
+ const Document& document,
+ const DisplayItemClient& client,
+ const PropertyTreeState& state) {
+ if (!document.IsInMainFrame())
+ return;
+ bool should_clear_canvas =
+ document.GetSettings() &&
+ document.GetSettings()->GetShouldClearDocumentBackground();
+
+ Color base_background_color =
+ layout_view_.GetFrameView()->BaseBackgroundColor();
+
+ ScopedPaintChunkProperties frame_view_background_state(
+ paint_info.context.GetPaintController(), state, client,
+ DisplayItem::kDocumentRootBackdrop);
+ GraphicsContext& context = paint_info.context;
+ if (!DrawingRecorder::UseCachedDrawingIfPossible(
+ context, client, DisplayItem::kDocumentRootBackdrop)) {
+ DrawingRecorder recorder(context, client,
+ DisplayItem::kDocumentRootBackdrop);
+ context.FillRect(
+ pixel_snapped_background_rect, base_background_color,
+ should_clear_canvas ? SkBlendMode::kSrc : SkBlendMode::kSrcOver);
+ }
+}
+
void ViewPainter::PaintBoxDecorationBackground(const PaintInfo& paint_info) {
if (layout_view_.StyleRef().Visibility() != EVisibility::kVisible)
return;
@@ -57,7 +89,6 @@ void ViewPainter::PaintBoxDecorationBackground(const PaintInfo& paint_info) {
const DisplayItemClient* background_client = &layout_view_;
- base::Optional<ScopedPaintChunkProperties> scoped_scroll_property;
bool painting_scrolling_background =
BoxDecorationData::IsPaintingScrollingBackground(paint_info,
layout_view_);
@@ -71,20 +102,84 @@ void ViewPainter::PaintBoxDecorationBackground(const PaintInfo& paint_info) {
background_rect.Unite(document_rect);
background_client = &layout_view_.GetScrollableArea()
->GetScrollingBackgroundDisplayItemClient();
- scoped_scroll_property.emplace(
- paint_info.context.GetPaintController(),
- layout_view_.FirstFragment().ContentsProperties(), *background_client,
- DisplayItem::kDocumentBackground);
}
- if (layout_view_.HasBoxDecorationBackground()) {
- PaintBoxDecorationBackgroundInternal(
- paint_info, PixelSnappedIntRect(background_rect), *background_client);
+ IntRect pixel_snapped_background_rect(PixelSnappedIntRect(background_rect));
+
+ const Document& document = layout_view_.GetDocument();
+
+ PropertyTreeState root_element_background_painting_state =
+ layout_view_.FirstFragment().ContentsProperties();
+
+ base::Optional<ScopedPaintChunkProperties> scoped_properties;
+
+ bool painted_separate_backdrop = false;
+ bool painted_separate_effect = false;
+
+ bool should_apply_root_background_behavior =
+ layout_view_.GetDocument().IsHTMLDocument() ||
+ layout_view_.GetDocument().IsXHTMLDocument();
+
+ bool should_paint_background = !paint_info.SkipRootBackground() &&
+ layout_view_.HasBoxDecorationBackground();
+
+ LayoutObject* root_object = nullptr;
+ if (layout_view_.GetDocument().documentElement()) {
+ root_object =
+ layout_view_.GetDocument().documentElement()->GetLayoutObject();
+ }
+
+ // For HTML and XHTML documents, the root element may paint in a different
+ // clip, effect or transform state than the LayoutView. For
+ // example, the HTML element may have a clip-path, filter, blend-mode,
+ // opacity or transform.
+ //
+ // In these cases, we should paint the background of the root element in
+ // its LocalBorderBoxProperties() state, as part of the Root Element Group
+ // [1]. In addition, for the main frame of the page, we also need to paint the
+ // default backdrop color in the Root Group [2]. The Root Group paints in
+ // the scrolling space of the LayoutView (i.e. its ContentsProperties()).
+ //
+ // [1] https://drafts.fxtf.org/compositing/#pagebackdrop
+ // [2] https://drafts.fxtf.org/compositing/#rootgroup
+ if (should_paint_background && painting_scrolling_background &&
+ should_apply_root_background_behavior && root_object) {
+ const PropertyTreeState& document_element_state =
+ root_object->FirstFragment().LocalBorderBoxProperties();
+
+ // As an optimization, only paint a separate PaintChunk for the
+ // root group if its property tree state differs from root element
+ // group's. Otherwise we can usually avoid both a separate
+ // PaintChunk and a BeginLayer/EndLayer.
+ if (document_element_state != root_element_background_painting_state) {
+ if (&document_element_state.Effect() !=
+ &root_element_background_painting_state.Effect())
+ painted_separate_effect = true;
+
+ root_element_background_painting_state = document_element_state;
+ PaintRootGroup(paint_info, pixel_snapped_background_rect, document,
+ *background_client,
+ layout_view_.FirstFragment().ContentsProperties());
+ painted_separate_backdrop = true;
+ }
+ }
+
+ if (painting_scrolling_background) {
+ scoped_properties.emplace(paint_info.context.GetPaintController(),
+ root_element_background_painting_state,
+ *background_client,
+ DisplayItem::kDocumentBackground);
+ }
+
+ if (should_paint_background) {
+ PaintRootElementGroup(paint_info, pixel_snapped_background_rect,
+ *background_client, painted_separate_backdrop,
+ painted_separate_effect);
}
if (has_touch_action_rect) {
BoxPainter(layout_view_)
.RecordHitTestData(paint_info,
- PhysicalRect(PixelSnappedIntRect(background_rect)),
+ PhysicalRect(pixel_snapped_background_rect),
*background_client);
}
@@ -119,22 +214,23 @@ void ViewPainter::PaintBoxDecorationBackground(const PaintInfo& paint_info) {
// View background painting is special in the following ways:
// 1. The view paints background for the root element, the background
// positioning respects the positioning and transformation of the root
-// element.
+// element. However, this method assumes that there is already an
+// PaintChunk being recorded with the LocalBorderBoxProperties of the
+// root element. Therefore the transform of the root element
+// are applied via PaintChunksToCcLayer, and not via the display list of the
+// PaintChunk itself.
// 2. CSS background-clip is ignored, the background layers always expand to
-// cover the whole canvas. None of the stacking context effects (except
-// transformation) on the root element affects the background.
+// cover the whole canvas.
// 3. The main frame is also responsible for painting the user-agent-defined
// base background color. Conceptually it should be painted by the embedder
// but painting it here allows culling and pre-blending optimization when
// possible.
-void ViewPainter::PaintBoxDecorationBackgroundInternal(
+void ViewPainter::PaintRootElementGroup(
const PaintInfo& paint_info,
- const IntRect& background_rect,
- const DisplayItemClient& background_client) {
- // TODO(pdr): Can this check be removed? It is not hit in any test.
- if (paint_info.SkipRootBackground())
- return;
-
+ const IntRect& pixel_snapped_background_rect,
+ const DisplayItemClient& background_client,
+ bool painted_separate_backdrop,
+ bool painted_separate_effect) {
GraphicsContext& context = paint_info.context;
if (DrawingRecorder::UseCachedDrawingIfPossible(
context, background_client, DisplayItem::kDocumentBackground)) {
@@ -149,8 +245,9 @@ void ViewPainter::PaintBoxDecorationBackgroundInternal(
(frame_view.BaseBackgroundColor().Alpha() > 0);
Color base_background_color =
paints_base_background ? frame_view.BaseBackgroundColor() : Color();
- Color root_background_color = layout_view_.StyleRef().VisitedDependentColor(
- GetCSSPropertyBackgroundColor());
+ Color root_element_background_color =
+ layout_view_.StyleRef().VisitedDependentColor(
+ GetCSSPropertyBackgroundColor());
const LayoutObject* root_object =
document.documentElement() ? document.documentElement()->GetLayoutObject()
: nullptr;
@@ -162,9 +259,11 @@ void ViewPainter::PaintBoxDecorationBackgroundInternal(
if (force_background_to_white) {
// If for any reason the view background is not transparent, paint white
// instead, otherwise keep transparent as is.
- if (paints_base_background || root_background_color.Alpha() ||
- layout_view_.StyleRef().BackgroundLayers().AnyLayerHasImage())
- context.FillRect(background_rect, Color::kWhite, SkBlendMode::kSrc);
+ if (paints_base_background || root_element_background_color.Alpha() ||
+ layout_view_.StyleRef().BackgroundLayers().AnyLayerHasImage()) {
+ context.FillRect(pixel_snapped_background_rect, Color::kWhite,
+ SkBlendMode::kSrc);
+ }
return;
}
@@ -177,49 +276,39 @@ void ViewPainter::PaintBoxDecorationBackgroundInternal(
// transform on the document rect to get to the root element space.
// Local / scroll positioned background images will be painted into scrolling
// contents layer with root layer scrolling. Therefore we need to switch both
- // the background_rect and context to documentElement visual space.
+ // the pixel_snapped_background_rect and context to documentElement visual
+ // space.
bool background_renderable = true;
- TransformationMatrix transform;
- IntRect paint_rect = background_rect;
+ bool root_element_has_transform = false;
+ IntRect paint_rect = pixel_snapped_background_rect;
if (!root_object || !root_object->IsBox()) {
background_renderable = false;
- } else if (root_object->HasLayer()) {
- if (BoxDecorationData::IsPaintingScrollingBackground(paint_info,
- layout_view_)) {
- transform.Translate(
- layout_view_.PixelSnappedScrolledContentOffset().Width(),
- layout_view_.PixelSnappedScrolledContentOffset().Height());
- }
- const PaintLayer& root_layer =
- *ToLayoutBoxModelObject(root_object)->Layer();
- PhysicalOffset offset;
- root_layer.ConvertToLayerCoords(nullptr, offset);
- transform.Translate(offset.left, offset.top);
- transform.Multiply(
- root_layer.RenderableTransform(paint_info.GetGlobalPaintFlags()));
-
- if (!transform.IsInvertible()) {
+ } else {
+ root_element_has_transform = root_object->StyleRef().HasTransform();
+ TransformationMatrix transform;
+ root_object->GetTransformFromContainer(root_object->View(),
+ PhysicalOffset(), transform);
+ if (!transform.IsInvertible())
background_renderable = false;
- } else {
- bool is_clamped;
- paint_rect = transform.Inverse()
- .ProjectQuad(FloatQuad(background_rect), &is_clamped)
- .EnclosingBoundingBox();
- background_renderable = !is_clamped;
- }
+ else
+ paint_rect = transform.Inverse().MapRect(pixel_snapped_background_rect);
}
bool should_clear_canvas =
paints_base_background &&
(document.GetSettings() &&
document.GetSettings()->GetShouldClearDocumentBackground());
+
if (!background_renderable) {
- if (base_background_color.Alpha()) {
- context.FillRect(
- background_rect, base_background_color,
- should_clear_canvas ? SkBlendMode::kSrc : SkBlendMode::kSrcOver);
- } else if (should_clear_canvas) {
- context.FillRect(background_rect, Color(), SkBlendMode::kClear);
+ if (!painted_separate_backdrop) {
+ if (base_background_color.Alpha()) {
+ context.FillRect(
+ pixel_snapped_background_rect, base_background_color,
+ should_clear_canvas ? SkBlendMode::kSrc : SkBlendMode::kSrcOver);
+ } else if (should_clear_canvas) {
+ context.FillRect(pixel_snapped_background_rect, Color(),
+ SkBlendMode::kClear);
+ }
}
return;
}
@@ -231,21 +320,30 @@ void ViewPainter::PaintBoxDecorationBackgroundInternal(
reversed_paint_list, layout_view_.StyleRef().BackgroundLayers());
DCHECK(reversed_paint_list.size());
- // If the root background color is opaque, isolation group can be skipped
- // because the canvas
- // will be cleared by root background color.
- if (!root_background_color.HasAlpha())
- should_draw_background_in_separate_buffer = false;
-
- // We are going to clear the canvas with transparent pixels, isolation group
- // can be skipped.
- if (!base_background_color.Alpha() && should_clear_canvas)
- should_draw_background_in_separate_buffer = false;
+ if (painted_separate_effect) {
+ should_draw_background_in_separate_buffer = true;
+ } else {
+ // If the root background color is opaque, isolation group can be skipped
+ // because the canvas
+ // will be cleared by root background color.
+ if (!root_element_background_color.HasAlpha())
+ should_draw_background_in_separate_buffer = false;
+
+ // We are going to clear the canvas with transparent pixels, isolation group
+ // can be skipped.
+ if (!base_background_color.Alpha() && should_clear_canvas)
+ should_draw_background_in_separate_buffer = false;
+ }
- if (should_draw_background_in_separate_buffer) {
+ // Only use BeginLayer if not only we should draw in a separate buffer, but
+ // we also didn't paint a separate backdrop. Separate backdrops are always
+ // painted when there is any effect on the root element, such as a blend
+ // mode. An extra BeginLayer will result in incorrect blend isolation if
+ // it is added on top of any effect on the root element.
+ if (should_draw_background_in_separate_buffer && !painted_separate_effect) {
if (base_background_color.Alpha()) {
context.FillRect(
- background_rect, base_background_color,
+ paint_rect, base_background_color,
should_clear_canvas ? SkBlendMode::kSrc : SkBlendMode::kSrcOver);
}
context.BeginLayer();
@@ -253,48 +351,38 @@ void ViewPainter::PaintBoxDecorationBackgroundInternal(
Color combined_background_color =
should_draw_background_in_separate_buffer
- ? root_background_color
- : base_background_color.Blend(root_background_color);
+ ? root_element_background_color
+ : base_background_color.Blend(root_element_background_color);
if (combined_background_color != frame_view.BaseBackgroundColor())
context.GetPaintController().SetFirstPainted();
if (combined_background_color.Alpha()) {
- if (!combined_background_color.HasAlpha() &&
- RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
- recorder.SetKnownToBeOpaque();
context.FillRect(
- background_rect, combined_background_color,
+ paint_rect, combined_background_color,
(should_draw_background_in_separate_buffer || should_clear_canvas)
? SkBlendMode::kSrc
: SkBlendMode::kSrcOver);
} else if (should_clear_canvas &&
!should_draw_background_in_separate_buffer) {
- context.FillRect(background_rect, Color(), SkBlendMode::kClear);
+ context.FillRect(paint_rect, Color(), SkBlendMode::kClear);
}
- BackgroundImageGeometry geometry(layout_view_);
+ BackgroundImageGeometry geometry(layout_view_, root_element_has_transform);
BoxModelObjectPainter box_model_painter(layout_view_);
for (const auto* fill_layer : base::Reversed(reversed_paint_list)) {
DCHECK(fill_layer->Clip() == EFillBox::kBorder);
- if (BackgroundImageGeometry::ShouldUseFixedAttachment(*fill_layer)) {
- box_model_painter.PaintFillLayer(paint_info, Color(), *fill_layer,
- PhysicalRect(background_rect),
- kBackgroundBleedNone, geometry);
- } else {
- context.Save();
- // TODO(trchen): We should be able to handle 3D-transformed root
- // background with slimming paint by using transform display items.
- context.ConcatCTM(transform.ToAffineTransform());
- box_model_painter.PaintFillLayer(paint_info, Color(), *fill_layer,
- PhysicalRect(paint_rect),
- kBackgroundBleedNone, geometry);
- context.Restore();
- }
+ PhysicalRect painting_rect(paint_rect);
+ if (!BackgroundImageGeometry::ShouldUseFixedAttachment(*fill_layer))
+ painting_rect.Move(root_object->FirstFragment().PaintOffset());
+
+ box_model_painter.PaintFillLayer(paint_info, Color(), *fill_layer,
+ painting_rect, kBackgroundBleedNone,
+ geometry);
}
- if (should_draw_background_in_separate_buffer)
+ if (should_draw_background_in_separate_buffer && !painted_separate_effect)
context.EndLayer();
}
diff --git a/chromium/third_party/blink/renderer/core/paint/view_painter.h b/chromium/third_party/blink/renderer/core/paint/view_painter.h
index 652ffd6cb9e..921839b76f8 100644
--- a/chromium/third_party/blink/renderer/core/paint/view_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/view_painter.h
@@ -11,8 +11,10 @@ namespace blink {
struct PaintInfo;
class DisplayItemClient;
+class Document;
class IntRect;
class LayoutView;
+class PropertyTreeState;
class ViewPainter {
STACK_ALLOCATED();
@@ -26,10 +28,17 @@ class ViewPainter {
private:
const LayoutView& layout_view_;
- void PaintBoxDecorationBackgroundInternal(
- const PaintInfo&,
- const IntRect& background_rect,
- const DisplayItemClient& background_client);
+ void PaintRootElementGroup(const PaintInfo&,
+ const IntRect& pixel_snapped_background_rect,
+ const DisplayItemClient& background_client,
+ bool painted_separate_backdrop,
+ bool painted_separate_effect);
+
+ void PaintRootGroup(const PaintInfo& paint_info,
+ const IntRect& pixel_snapped_background_rect,
+ const Document&,
+ const DisplayItemClient& background_client,
+ const PropertyTreeState& state);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/view_painter_test.cc b/chromium/third_party/blink/renderer/core/paint/view_painter_test.cc
index 60d2ceb43db..e26b77a20d5 100644
--- a/chromium/third_party/blink/renderer/core/paint/view_painter_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/view_painter_test.cc
@@ -9,20 +9,19 @@
#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
#include "third_party/blink/renderer/core/paint/paint_controller_paint_test.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h"
-#include "third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h"
using testing::ElementsAre;
namespace blink {
-class ViewPainterTest : public PaintControllerPaintTest {
+class ViewPainterFixedBackgroundTest : public PaintControllerPaintTest {
protected:
void RunFixedBackgroundTest(bool prefer_compositing_to_lcd_text);
};
-INSTANTIATE_PAINT_TEST_SUITE_P(ViewPainterTest);
+INSTANTIATE_PAINT_TEST_SUITE_P(ViewPainterFixedBackgroundTest);
-void ViewPainterTest::RunFixedBackgroundTest(
+void ViewPainterFixedBackgroundTest::RunFixedBackgroundTest(
bool prefer_compositing_to_lcd_text) {
if (prefer_compositing_to_lcd_text) {
Settings* settings = GetDocument().GetFrame()->GetSettings();
@@ -45,27 +44,19 @@ void ViewPainterTest::RunFixedBackgroundTest(
ScrollableArea* layout_viewport = frame_view->LayoutViewport();
ScrollOffset scroll_offset(200, 150);
- layout_viewport->SetScrollOffset(scroll_offset, kUserScroll);
- frame_view->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ layout_viewport->SetScrollOffset(scroll_offset,
+ mojom::blink::ScrollType::kUser);
+ frame_view->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
const DisplayItem* background_display_item = nullptr;
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
const auto& display_items = RootPaintController().GetDisplayItemList();
- if (prefer_compositing_to_lcd_text) {
- EXPECT_THAT(
- display_items,
- ElementsAre(IsSameId(&GetLayoutView(), kDocumentBackgroundType),
- IsSameId(&GetLayoutView(), DisplayItem::kScrollHitTest)));
- background_display_item = &display_items[0];
- } else {
- EXPECT_THAT(
- display_items,
- ElementsAre(IsSameId(&GetLayoutView(), DisplayItem::kScrollHitTest),
- IsSameId(&ViewScrollingBackgroundClient(),
- kDocumentBackgroundType)));
- background_display_item = &display_items[1];
- }
+ const auto& background_client = prefer_compositing_to_lcd_text
+ ? GetLayoutView()
+ : ViewScrollingBackgroundClient();
+ EXPECT_THAT(display_items, ElementsAre(IsSameId(&background_client,
+ kDocumentBackgroundType)));
+ background_display_item = &display_items[0];
} else {
// If we prefer compositing to LCD text, the fixed background should go in a
// different layer from the scrolling content; otherwise, it should go in
@@ -108,66 +99,65 @@ void ViewPainterTest::RunFixedBackgroundTest(
}
}
-TEST_P(ViewPainterTest, DocumentFixedBackgroundLowDPI) {
+TEST_P(ViewPainterFixedBackgroundTest, DocumentFixedBackgroundLowDPI) {
RunFixedBackgroundTest(false);
}
-TEST_P(ViewPainterTest, DocumentFixedBackgroundHighDPI) {
+TEST_P(ViewPainterFixedBackgroundTest, DocumentFixedBackgroundHighDPI) {
RunFixedBackgroundTest(true);
}
-using ViewPainterScrollHitTestTest = PaintControllerPaintTest;
+using ViewPainterTest = PaintControllerPaintTest;
-INSTANTIATE_SCROLL_HIT_TEST_SUITE_P(ViewPainterScrollHitTestTest);
+INSTANTIATE_PAINT_TEST_SUITE_P(ViewPainterTest);
-TEST_P(ViewPainterScrollHitTestTest, DocumentBackgroundWithScroll) {
+TEST_P(ViewPainterTest, DocumentBackgroundWithScroll) {
SetBodyInnerHTML(R"HTML(
<style>::-webkit-scrollbar { display: none }</style>
<div style='height: 5000px'></div>
)HTML");
+ const auto& scrolling_contents_properties =
+ GetLayoutView().FirstFragment().ContentsProperties();
+
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ EXPECT_THAT(RootPaintController().GetDisplayItemList(),
+ ElementsAre(IsSameId(&ViewScrollingBackgroundClient(),
+ kDocumentBackgroundType)));
+ HitTestData scroll_hit_test_data;
+ scroll_hit_test_data.scroll_translation =
+ &scrolling_contents_properties.Transform();
+ scroll_hit_test_data.scroll_hit_test_rect = IntRect(0, 0, 800, 600);
// The scroll hit test should be before the scrolled contents to ensure the
// hit test does not prevent the background squashing with the scrolling
// contents.
EXPECT_THAT(
- RootPaintController().GetDisplayItemList(),
- ElementsAre(IsSameId(&GetLayoutView(), DisplayItem::kScrollHitTest),
- IsSameId(&ViewScrollingBackgroundClient(),
- kDocumentBackgroundType)));
- HitTestData scroll_hit_test_data;
- const auto& scrolling_contents_properties =
- GetLayoutView().FirstFragment().ContentsProperties();
- scroll_hit_test_data.SetScrollHitTest(
- &scrolling_contents_properties.Transform(), IntRect(0, 0, 800, 600));
- EXPECT_THAT(
RootPaintController().PaintChunks(),
ElementsAre(
IsPaintChunk(
- 0, 1,
+ 0, 0,
PaintChunk::Id(GetLayoutView(), DisplayItem::kScrollHitTest),
GetLayoutView().FirstFragment().LocalBorderBoxProperties(),
- scroll_hit_test_data),
- IsPaintChunk(1, 2,
+ &scroll_hit_test_data, IntRect(0, 0, 800, 600)),
+ IsPaintChunk(0, 1,
PaintChunk::Id(ViewScrollingBackgroundClient(),
kDocumentBackgroundType),
scrolling_contents_properties)));
} else {
- // Because the frame composited scrolls, no scroll hit test display item is
- // needed.
+ // Because the frame composited scrolls, no scroll hit test data is needed.
EXPECT_THAT(RootPaintController().GetDisplayItemList(),
ElementsAre(IsSameId(&ViewScrollingBackgroundClient(),
kDocumentBackgroundType)));
- EXPECT_THAT(RootPaintController().PaintChunks(),
- ElementsAre(IsPaintChunk(
- 0, 1,
- PaintChunk::Id(ViewScrollingBackgroundClient(),
- kDocumentBackgroundType),
- GetLayoutView().FirstFragment().ContentsProperties())));
+ EXPECT_THAT(
+ RootPaintController().PaintChunks(),
+ ElementsAre(IsPaintChunk(0, 1,
+ PaintChunk::Id(ViewScrollingBackgroundClient(),
+ kDocumentBackgroundType),
+ scrolling_contents_properties)));
}
}
-TEST_P(ViewPainterScrollHitTestTest, FrameScrollHitTestProperties) {
+TEST_P(ViewPainterTest, FrameScrollHitTestProperties) {
// This test depends on the CompositeAfterPaint behavior of painting solid
// color backgrounds into both the non-scrolled and scrolled spaces.
if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
@@ -181,16 +171,10 @@ TEST_P(ViewPainterScrollHitTestTest, FrameScrollHitTestProperties) {
<div id='child'></div>
)HTML");
- auto& html =
- To<LayoutBlock>(*GetDocument().documentElement()->GetLayoutObject());
auto& child = *GetLayoutObjectByElementId("child");
- // The scroll hit test should be before the scrolled contents to ensure the
- // hit test does not prevent the background squashing with the scrolling
- // contents.
EXPECT_THAT(RootPaintController().GetDisplayItemList(),
- ElementsAre(IsSameId(&GetLayoutView(), kScrollHitTestType),
- IsSameId(&ViewScrollingBackgroundClient(),
+ ElementsAre(IsSameId(&ViewScrollingBackgroundClient(),
kDocumentBackgroundType),
IsSameId(&child, kBackgroundType)));
@@ -198,24 +182,24 @@ TEST_P(ViewPainterScrollHitTestTest, FrameScrollHitTestProperties) {
const auto& view_contents_properties =
GetLayoutView().FirstFragment().ContentsProperties();
HitTestData scroll_hit_test_data;
- scroll_hit_test_data.SetScrollHitTest(&view_contents_properties.Transform(),
- IntRect(0, 0, 800, 600));
+ scroll_hit_test_data.scroll_translation =
+ &view_contents_properties.Transform();
+ scroll_hit_test_data.scroll_hit_test_rect = IntRect(0, 0, 800, 600);
+ // The scroll hit test should be before the scrolled contents to ensure the
+ // hit test does not prevent the background squashing with the scrolling
+ // contents.
EXPECT_THAT(
paint_chunks,
ElementsAre(
IsPaintChunk(
- 0, 1,
+ 0, 0,
PaintChunk::Id(GetLayoutView(), DisplayItem::kScrollHitTest),
GetLayoutView().FirstFragment().LocalBorderBoxProperties(),
- scroll_hit_test_data),
- IsPaintChunk(1, 2,
+ &scroll_hit_test_data),
+ IsPaintChunk(0, 2,
PaintChunk::Id(ViewScrollingBackgroundClient(),
kDocumentBackgroundType),
- view_contents_properties),
- IsPaintChunk(2, 3,
- PaintChunk::Id(*html.Layer(),
- kNonScrollingContentsBackgroundChunkType),
- html.FirstFragment().ContentsProperties())));
+ view_contents_properties)));
// The scroll hit test should not be scrolled and should not be clipped.
const auto& scroll_hit_test_chunk = RootPaintController().PaintChunks()[0];
@@ -224,25 +208,22 @@ TEST_P(ViewPainterScrollHitTestTest, FrameScrollHitTestProperties) {
EXPECT_EQ(nullptr, scroll_hit_test_transform.ScrollNode());
const auto& scroll_hit_test_clip = scroll_hit_test_chunk.properties.Clip();
EXPECT_EQ(FloatRect(LayoutRect::InfiniteIntRect()),
- scroll_hit_test_clip.ClipRect().Rect());
+ scroll_hit_test_clip.UnsnappedClipRect().Rect());
// The scrolled contents should be scrolled and clipped.
- const auto& contents_chunk = RootPaintController().PaintChunks()[2];
+ const auto& contents_chunk = RootPaintController().PaintChunks()[1];
const auto& contents_transform = contents_chunk.properties.Transform();
const auto* contents_scroll = contents_transform.ScrollNode();
EXPECT_EQ(IntSize(800, 2000), contents_scroll->ContentsSize());
EXPECT_EQ(IntRect(0, 0, 800, 600), contents_scroll->ContainerRect());
const auto& contents_clip = contents_chunk.properties.Clip();
- EXPECT_EQ(FloatRect(0, 0, 800, 600), contents_clip.ClipRect().Rect());
+ EXPECT_EQ(FloatRect(0, 0, 800, 600),
+ contents_clip.UnsnappedClipRect().Rect());
- // The scroll hit test display item maintains a reference to a scroll offset
+ // The scroll hit test paint chunk maintains a reference to a scroll offset
// translation node and the contents should be scrolled by this node.
- const auto& scroll_hit_test_display_item =
- static_cast<const ScrollHitTestDisplayItem&>(
- RootPaintController()
- .GetDisplayItemList()[scroll_hit_test_chunk.begin_index]);
EXPECT_EQ(&contents_transform,
- scroll_hit_test_display_item.scroll_offset_node());
+ scroll_hit_test_chunk.hit_test_data->scroll_translation);
}
class ViewPainterTouchActionRectTest : public ViewPainterTest {
@@ -278,56 +259,42 @@ TEST_P(ViewPainterTouchActionRectTest, TouchActionRectScrollingContents) {
auto scrolling_properties =
GetLayoutView().FirstFragment().ContentsProperties();
HitTestData view_hit_test_data;
- view_hit_test_data.touch_action_rects.emplace_back(
- LayoutRect(0, 0, 800, 3000));
-
- auto* html =
- To<LayoutBlock>(GetDocument().documentElement()->GetLayoutObject());
- HitTestData html_hit_test_data;
- html_hit_test_data.touch_action_rects.emplace_back(
- LayoutRect(0, 0, 800, 3000));
- html_hit_test_data.touch_action_rects.emplace_back(
- LayoutRect(0, 0, 800, 3000));
+ view_hit_test_data.touch_action_rects = {{IntRect(0, 0, 800, 3000)},
+ {IntRect(0, 0, 800, 3000)},
+ {IntRect(0, 0, 800, 3000)}};
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
HitTestData non_scrolling_hit_test_data;
- non_scrolling_hit_test_data.touch_action_rects.emplace_back(
- LayoutRect(0, 0, 800, 600));
+ non_scrolling_hit_test_data.touch_action_rects = {
+ {IntRect(0, 0, 800, 600)}};
HitTestData scroll_hit_test_data;
- scroll_hit_test_data.SetScrollHitTest(&scrolling_properties.Transform(),
- IntRect(0, 0, 800, 600));
+ scroll_hit_test_data.scroll_translation = &scrolling_properties.Transform();
+ scroll_hit_test_data.scroll_hit_test_rect = IntRect(0, 0, 800, 600);
EXPECT_THAT(
RootPaintController().PaintChunks(),
ElementsAre(
IsPaintChunk(
- 0, 1,
+ 0, 0,
PaintChunk::Id(*GetLayoutView().Layer(),
- DisplayItem::kLayerChunkBackground),
+ DisplayItem::kLayerChunk),
GetLayoutView().FirstFragment().LocalBorderBoxProperties(),
- non_scrolling_hit_test_data),
+ &non_scrolling_hit_test_data, IntRect(0, 0, 800, 600)),
IsPaintChunk(
- 1, 2,
+ 0, 0,
PaintChunk::Id(GetLayoutView(), DisplayItem::kScrollHitTest),
GetLayoutView().FirstFragment().LocalBorderBoxProperties(),
- scroll_hit_test_data),
+ &scroll_hit_test_data, IntRect(0, 0, 800, 600)),
IsPaintChunk(
- 2, 4, PaintChunk::Id(scrolling_client, kDocumentBackgroundType),
- scrolling_properties, view_hit_test_data),
- IsPaintChunk(4, 6,
- PaintChunk::Id(*html->Layer(),
- kNonScrollingBackgroundChunkType),
- scrolling_properties, html_hit_test_data)));
+ 0, 1, PaintChunk::Id(scrolling_client, kDocumentBackgroundType),
+ scrolling_properties, &view_hit_test_data,
+ IntRect(0, 0, 800, 3000))));
} else {
EXPECT_THAT(
RootPaintController().PaintChunks(),
- ElementsAre(
- IsPaintChunk(
- 0, 2, PaintChunk::Id(scrolling_client, kDocumentBackgroundType),
- scrolling_properties, view_hit_test_data),
- IsPaintChunk(2, 4,
- PaintChunk::Id(*html->Layer(),
- kNonScrollingBackgroundChunkType),
- scrolling_properties, html_hit_test_data)));
+ ElementsAre(IsPaintChunk(
+ 0, 1, PaintChunk::Id(scrolling_client, kDocumentBackgroundType),
+ scrolling_properties, &view_hit_test_data,
+ IntRect(0, 0, 800, 3000))));
}
}
@@ -354,49 +321,46 @@ TEST_P(ViewPainterTouchActionRectTest, TouchActionRectNonScrollingContents) {
auto non_scrolling_properties =
view->FirstFragment().LocalBorderBoxProperties();
HitTestData view_hit_test_data;
- view_hit_test_data.touch_action_rects.emplace_back(
- LayoutRect(0, 0, 800, 600));
- auto* html =
- To<LayoutBlock>(GetDocument().documentElement()->GetLayoutObject());
+ view_hit_test_data.touch_action_rects = {{IntRect(0, 0, 800, 600)}};
+ auto* html = GetDocument().documentElement()->GetLayoutBox();
auto scrolling_properties = view->FirstFragment().ContentsProperties();
HitTestData scrolling_hit_test_data;
- scrolling_hit_test_data.touch_action_rects.emplace_back(
- LayoutRect(0, 0, 800, 3000));
- scrolling_hit_test_data.touch_action_rects.emplace_back(
- LayoutRect(0, 0, 800, 3000));
+ scrolling_hit_test_data.touch_action_rects = {{IntRect(0, 0, 800, 3000)},
+ {IntRect(0, 0, 800, 3000)}};
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
HitTestData scroll_hit_test_data;
- scroll_hit_test_data.SetScrollHitTest(&scrolling_properties.Transform(),
- IntRect(0, 0, 800, 600));
+ scroll_hit_test_data.scroll_translation = &scrolling_properties.Transform();
+ scroll_hit_test_data.scroll_hit_test_rect = IntRect(0, 0, 800, 600);
EXPECT_THAT(
RootPaintController().PaintChunks(),
ElementsAre(
- IsPaintChunk(0, 2,
- PaintChunk::Id(*view->Layer(),
- DisplayItem::kLayerChunkBackground),
- non_scrolling_properties, view_hit_test_data),
- IsPaintChunk(2, 3,
+ IsPaintChunk(
+ 0, 1, PaintChunk::Id(*view->Layer(), DisplayItem::kLayerChunk),
+ non_scrolling_properties, &view_hit_test_data,
+ IntRect(0, 0, 800, 600)),
+ IsPaintChunk(1, 1,
PaintChunk::Id(*view, DisplayItem::kScrollHitTest),
- non_scrolling_properties, scroll_hit_test_data),
- IsPaintChunk(3, 5,
- PaintChunk::Id(*html->Layer(),
- kNonScrollingBackgroundChunkType),
- scrolling_properties, scrolling_hit_test_data)));
+ non_scrolling_properties, &scroll_hit_test_data,
+ IntRect(0, 0, 800, 600)),
+ IsPaintChunk(
+ 1, 1, PaintChunk::Id(*html->Layer(), DisplayItem::kLayerChunk),
+ scrolling_properties, &scrolling_hit_test_data,
+ IntRect(0, 0, 800, 3000))));
} else {
auto& non_scrolling_paint_controller =
view->Layer()->GraphicsLayerBacking(view)->GetPaintController();
EXPECT_THAT(
non_scrolling_paint_controller.PaintChunks(),
ElementsAre(IsPaintChunk(
- 0, 2,
- PaintChunk::Id(*view->Layer(), kNonScrollingBackgroundChunkType),
- non_scrolling_properties, view_hit_test_data)));
+ 0, 1, PaintChunk::Id(*view->Layer(), DisplayItem::kLayerChunk),
+ non_scrolling_properties, &view_hit_test_data,
+ IntRect(0, 0, 800, 600))));
EXPECT_THAT(
RootPaintController().PaintChunks(),
ElementsAre(IsPaintChunk(
- 0, 2,
- PaintChunk::Id(*html->Layer(), kNonScrollingBackgroundChunkType),
- scrolling_properties, scrolling_hit_test_data)));
+ 0, 0, PaintChunk::Id(*html->Layer(), DisplayItem::kLayerChunk),
+ scrolling_properties, &scrolling_hit_test_data,
+ IntRect(0, 0, 800, 3000))));
}
}
diff --git a/chromium/third_party/blink/renderer/core/precompile_core.h b/chromium/third_party/blink/renderer/core/precompile_core.h
index 1cf10f38be4..30a97e9089d 100644
--- a/chromium/third_party/blink/renderer/core/precompile_core.h
+++ b/chromium/third_party/blink/renderer/core/precompile_core.h
@@ -6,15 +6,13 @@
#error You shouldn't include the precompiled header file more than once.
#endif
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PRECOMPILE_CORE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PRECOMPILE_CORE_H_
#if defined(_MSC_VER)
#include "third_party/blink/renderer/build/win/precompile.h"
#elif defined(__APPLE__)
#include "third_party/blink/renderer/build/mac/prefix.h"
-#else
-#error implement
-#endif
// In Blink a lot of operations center around dom and Document, or around
// layout/rendering and LayoutObject. Those two headers are in turn pulling
@@ -23,5 +21,13 @@
// and layout_object.h we only have to compile those parts once rather
// than 1500 times. It can make a large difference in compilation
// times (3-4 times faster).
+
+// Precompiling these headers has not been found to be helpful on Windows
+// compiles in 2020.
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
+#else
+#error implement
+#endif
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PRECOMPILE_CORE_H_
diff --git a/chromium/third_party/blink/renderer/core/probe/BUILD.gn b/chromium/third_party/blink/renderer/core/probe/BUILD.gn
index 93ef592b91d..6e85e2b4626 100644
--- a/chromium/third_party/blink/renderer/core/probe/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/probe/BUILD.gn
@@ -31,9 +31,7 @@ action("instrumentation_probes") {
}
source_set("generated") {
- deps = [
- ":instrumentation_probes",
- ]
+ deps = [ ":instrumentation_probes" ]
}
# Compiles the sources generated above.
diff --git a/chromium/third_party/blink/renderer/core/probe/async_task_id.h b/chromium/third_party/blink/renderer/core/probe/async_task_id.h
index eeba800d382..667a864cdcf 100644
--- a/chromium/third_party/blink/renderer/core/probe/async_task_id.h
+++ b/chromium/third_party/blink/renderer/core/probe/async_task_id.h
@@ -14,6 +14,13 @@ namespace probe {
// The core probes use this class as an identifier for an async task.
class CORE_EXPORT AsyncTaskId {
public:
+ AsyncTaskId() = default;
+
+ // Not copyable or movable, since the address of an AsyncTaskId is what's used
+ // to keep track of them.
+ AsyncTaskId(const AsyncTaskId&) = delete;
+ AsyncTaskId& operator=(const AsyncTaskId&) = delete;
+
void SetAdTask() { ad_task_ = true; }
bool IsAdTask() const { return ad_task_; }
diff --git a/chromium/third_party/blink/renderer/core/probe/core_probes.cc b/chromium/third_party/blink/renderer/core/probe/core_probes.cc
index 354e3c72bc3..8fab6e1d2ac 100644
--- a/chromium/third_party/blink/renderer/core/probe/core_probes.cc
+++ b/chromium/third_party/blink/renderer/core/probe/core_probes.cc
@@ -82,7 +82,8 @@ AsyncTask::AsyncTask(ExecutionContext* context,
: nullptr),
task_(task),
recurring_(step),
- ad_tracker_(AdTracker::FromExecutionContext(context)) {
+ ad_tracker_(enabled ? AdTracker::FromExecutionContext(context)
+ : nullptr) {
if (recurring_) {
TRACE_EVENT_FLOW_STEP0("devtools.timeline.async", "AsyncTask",
TRACE_ID_LOCAL(reinterpret_cast<uintptr_t>(task)),
diff --git a/chromium/third_party/blink/renderer/core/probe/core_probes.h b/chromium/third_party/blink/renderer/core/probe/core_probes.h
index 46801ea348e..bc9b68a0873 100644
--- a/chromium/third_party/blink/renderer/core/probe/core_probes.h
+++ b/chromium/third_party/blink/renderer/core/probe/core_probes.h
@@ -68,11 +68,20 @@ class CORE_EXPORT ProbeBase {
mutable base::TimeTicks end_time_;
};
+// Tracks execution of a (previously scheduled) asynchronous task. An instance
+// should exist for the full duration of the task's execution.
class CORE_EXPORT AsyncTask {
STACK_ALLOCATED();
public:
- AsyncTask(ExecutionContext*,
+ // Args:
+ // context: The ExecutionContext in which the task is executed.
+ // task: An identifier for the AsyncTask.
+ // step: A nullptr indicates a task that is not recurring. A non-null value
+ // indicates a recurring task with the value used for tracing events.
+ // enabled: Whether the task is asynchronous. If false, the task is not
+ // reported to the debugger and AdTracker.
+ AsyncTask(ExecutionContext* context,
AsyncTaskId* task,
const char* step = nullptr,
bool enabled = true);
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 2995f511183..f75394cfce1 100644
--- a/chromium/third_party/blink/renderer/core/probe/core_probes.json5
+++ b/chromium/third_party/blink/renderer/core/probe/core_probes.json5
@@ -37,6 +37,11 @@
"UpdateApplicationCacheStatus",
]
},
+ InspectorAuditsAgent: {
+ probes: [
+ "InspectorIssueAdded"
+ ]
+ },
InspectorCSSAgent: {
probes: [
"ActiveStyleSheetsUpdated",
@@ -208,6 +213,8 @@
"RecalculateStyle",
"UpdateLayout",
"V8Compile",
+ "WillStartDebuggerTask",
+ "DidFinishDebuggerTask",
]
},
InspectorTraceEvents: {
@@ -231,6 +238,8 @@
"DidStartProvisionalLoad",
"DidFailProvisionalLoad",
"DidCommitLoad",
+ "PaintTiming",
+ "DomContentLoadedEventFired",
]
},
}
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 2b8af8b75e2..c4d4e21f0d1 100644
--- a/chromium/third_party/blink/renderer/core/probe/core_probes.pidl
+++ b/chromium/third_party/blink/renderer/core/probe/core_probes.pidl
@@ -53,6 +53,7 @@
interface CoreProbes {
+ class InspectorIssue;
class ConsoleMessage;
class FontCustomPlatformData;
class FontFace;
@@ -102,7 +103,7 @@ interface CoreProbes {
void DidFailLoading(CoreProbeSink*, uint64_t identifier, DocumentLoader*, const ResourceError&);
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, EncodedFormData* form_data, const HTTPHeaderMap& headers, bool include_credentials);
+ void WillLoadXHR([Keep] ExecutionContext*, const AtomicString& method, const KURL& url, bool async, const HTTPHeaderMap& headers, bool include_credentials);
void DidFinishXHR(ExecutionContext*, XMLHttpRequest* xhr);
void ScriptImported(ExecutionContext*, uint64_t identifier, const String& source_string);
void ScriptExecutionBlockedByCSP(ExecutionContext*, const String& directive_text);
@@ -142,6 +143,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 WillRunJavaScriptDialog(LocalFrame* frame);
void DidRunJavaScriptDialog(LocalFrame* frame);
void DocumentWriteFetchScript([Keep] Document*);
@@ -159,6 +161,8 @@ interface CoreProbes {
void ShouldBlockRequest(CoreProbeSink*, const KURL&, bool* result);
void ShouldBypassServiceWorker(ExecutionContext* context, bool* result);
void ConsoleTimeStamp(ExecutionContext*, const String& title);
+ void WillStartDebuggerTask(CoreProbeSink*);
+ void DidFinishDebuggerTask(CoreProbeSink*);
void LifecycleEvent([Keep] LocalFrame*, DocumentLoader*, const char* name, double timestamp);
void PaintTiming([Keep] Document*, const char* name, double timestamp);
void DidCreateAudioContext(Document*);
diff --git a/chromium/third_party/blink/renderer/core/resize_observer/BUILD.gn b/chromium/third_party/blink/renderer/core/resize_observer/BUILD.gn
index 6fb48dcfec6..94e42d6b0b3 100644
--- a/chromium/third_party/blink/renderer/core/resize_observer/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/resize_observer/BUILD.gn
@@ -10,9 +10,12 @@ blink_core_sources("resize_observer") {
"resize_observation.h",
"resize_observer.cc",
"resize_observer.h",
+ "resize_observer_box_options.h",
"resize_observer_controller.cc",
"resize_observer_controller.h",
"resize_observer_entry.cc",
"resize_observer_entry.h",
+ "resize_observer_size.cc",
+ "resize_observer_size.h",
]
}
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 855dbf5c50e..f6eb3c33a46 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
@@ -3,26 +3,29 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/core/resize_observer/resize_observation.h"
-
#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
+#include "third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/resize_observer/resize_observer.h"
+#include "third_party/blink/renderer/core/resize_observer/resize_observer_box_options.h"
#include "third_party/blink/renderer/core/svg/svg_element.h"
#include "third_party/blink/renderer/core/svg/svg_graphics_element.h"
+#include "third_party/blink/renderer/platform/geometry/layout_unit.h"
namespace blink {
-ResizeObservation::ResizeObservation(Element* target, ResizeObserver* observer)
+ResizeObservation::ResizeObservation(Element* target,
+ ResizeObserver* observer,
+ ResizeObserverBoxOptions observed_box)
: target_(target),
observer_(observer),
observation_size_(0, 0),
- element_size_changed_(true) {
+ observed_box_(observed_box) {
DCHECK(target_);
- observer_->ElementSizeChanged();
}
bool ResizeObservation::ObservationSizeOutOfSync() {
- if (!element_size_changed_ || observation_size_ == ComputeTargetSize())
+ if (observation_size_ == ComputeTargetSize())
return false;
// Skip resize observations on locked elements.
@@ -36,13 +39,6 @@ bool ResizeObservation::ObservationSizeOutOfSync() {
void ResizeObservation::SetObservationSize(const LayoutSize& observation_size) {
observation_size_ = observation_size;
-
- // Don't clear the dirty bit while locked. This allows us to make sure to
- // compare sizes when becoming unlocked.
- if (UNLIKELY(DisplayLockUtilities::IsInLockedSubtreeCrossingFrames(*target_)))
- return;
-
- element_size_changed_ = false;
}
size_t ResizeObservation::TargetDepth() {
@@ -55,31 +51,52 @@ size_t ResizeObservation::TargetDepth() {
LayoutSize ResizeObservation::ComputeTargetSize() const {
if (target_) {
if (LayoutObject* layout_object = target_->GetLayoutObject()) {
+ // https://drafts.csswg.org/resize-observer/#calculate-box-size states
+ // that the bounding box should be used for SVGGraphicsElements regardless
+ // of the observed box.
if (auto* svg_graphics_element =
DynamicTo<SVGGraphicsElement>(target_.Get())) {
return LayoutSize(svg_graphics_element->GetBBox().Size());
}
- if (layout_object->IsBox())
- return ToLayoutBox(layout_object)->ContentSize();
+ if (!layout_object->IsBox())
+ return LayoutSize();
+
+ if (LayoutBox* layout_box = ToLayoutBox(layout_object)) {
+ const ComputedStyle& style = layout_object->StyleRef();
+ switch (observed_box_) {
+ case ResizeObserverBoxOptions::BorderBox:
+ return LayoutSize(AdjustForAbsoluteZoom::AdjustLayoutUnit(
+ layout_box->LogicalWidth(), style),
+ AdjustForAbsoluteZoom::AdjustLayoutUnit(
+ layout_box->LogicalHeight(), style));
+ case ResizeObserverBoxOptions::ContentBox:
+ return LayoutSize(AdjustForAbsoluteZoom::AdjustLayoutUnit(
+ layout_box->ContentLogicalWidth(), style),
+ AdjustForAbsoluteZoom::AdjustLayoutUnit(
+ layout_box->ContentLogicalHeight(), style));
+ case ResizeObserverBoxOptions::DevicePixelContentBox: {
+ LayoutSize paint_offset =
+ layout_object->FirstFragment().PaintOffset().ToLayoutSize();
+ return LayoutSize(
+ SnapSizeToPixel(layout_box->ContentLogicalWidth(),
+ style.IsHorizontalWritingMode()
+ ? paint_offset.Width()
+ : paint_offset.Height()),
+ SnapSizeToPixel(layout_box->ContentLogicalHeight(),
+ style.IsHorizontalWritingMode()
+ ? paint_offset.Height()
+ : paint_offset.Width()));
+ }
+ default:
+ NOTREACHED();
+ }
+ }
}
}
return LayoutSize();
}
-LayoutPoint ResizeObservation::ComputeTargetLocation() const {
- if (target_ && !target_->IsSVGElement()) {
- if (LayoutBox* layout = target_->GetLayoutBox())
- return LayoutPoint(layout->PaddingLeft(), layout->PaddingTop());
- }
- return LayoutPoint();
-}
-
-void ResizeObservation::ElementSizeChanged() {
- element_size_changed_ = true;
- observer_->ElementSizeChanged();
-}
-
-void ResizeObservation::Trace(blink::Visitor* visitor) {
+void ResizeObservation::Trace(Visitor* visitor) {
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 444fd0ac83a..66c0ac6561c 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
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_RESIZE_OBSERVER_RESIZE_OBSERVATION_H_
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/resize_observer/resize_observer_box_options.h"
#include "third_party/blink/renderer/core/resize_observer/resize_observer_entry.h"
#include "third_party/blink/renderer/platform/geometry/layout_size.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -13,33 +14,33 @@
namespace blink {
class Element;
-class LayoutPoint;
class ResizeObserver;
// ResizeObservation represents an element that is being observed.
class CORE_EXPORT ResizeObservation final
: public GarbageCollected<ResizeObservation> {
public:
- ResizeObservation(Element* target, ResizeObserver*);
+ ResizeObservation(Element* target,
+ ResizeObserver*,
+ ResizeObserverBoxOptions observed_box);
Element* Target() const { return target_; }
size_t TargetDepth();
// True if observationSize differs from target's current size.
bool ObservationSizeOutOfSync();
void SetObservationSize(const LayoutSize&);
- void ElementSizeChanged();
+ ResizeObserverBoxOptions observedBox() const { return observed_box_; }
LayoutSize ComputeTargetSize() const;
- LayoutPoint ComputeTargetLocation() const;
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
WeakMember<Element> target_;
Member<ResizeObserver> observer_;
// Target size sent in last observation notification.
LayoutSize observation_size_;
- bool element_size_changed_;
+ ResizeObserverBoxOptions observed_box_;
};
} // namespace blink
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 831ac96a5de..2290704ac1d 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
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/resize_observer/resize_observer.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_resize_observer_callback.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_resize_observer_options.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h"
@@ -15,6 +16,11 @@
namespace blink {
+constexpr const char* kBoxOptionBorderBox = "border-box";
+constexpr const char* kBoxOptionContentBox = "content-box";
+constexpr const char* kBoxOptionDevicePixelContentBox =
+ "device-pixel-content-box";
+
ResizeObserver* ResizeObserver::Create(Document& document,
V8ResizeObserverCallback* callback) {
return MakeGarbageCollected<ResizeObserver>(callback, document);
@@ -26,31 +32,57 @@ ResizeObserver* ResizeObserver::Create(Document& document, Delegate* delegate) {
ResizeObserver::ResizeObserver(V8ResizeObserverCallback* callback,
Document& document)
- : ContextClient(&document),
+ : ExecutionContextClient(document.ToExecutionContext()),
callback_(callback),
- skipped_observations_(false),
- element_size_changed_(false) {
+ skipped_observations_(false) {
DCHECK(callback_);
controller_ = &document.EnsureResizeObserverController();
controller_->AddObserver(*this);
}
ResizeObserver::ResizeObserver(Delegate* delegate, Document& document)
- : ContextClient(&document),
+ : ExecutionContextClient(document.ToExecutionContext()),
delegate_(delegate),
- skipped_observations_(false),
- element_size_changed_(false) {
+ skipped_observations_(false) {
DCHECK(delegate_);
controller_ = &document.EnsureResizeObserverController();
controller_->AddObserver(*this);
}
-void ResizeObserver::observe(Element* target) {
+ResizeObserverBoxOptions ResizeObserver::ParseBoxOptions(
+ const String& box_options) {
+ if (box_options == kBoxOptionBorderBox)
+ return ResizeObserverBoxOptions::BorderBox;
+ if (box_options == kBoxOptionContentBox)
+ return ResizeObserverBoxOptions::ContentBox;
+ if (box_options == kBoxOptionDevicePixelContentBox)
+ return ResizeObserverBoxOptions::DevicePixelContentBox;
+ return ResizeObserverBoxOptions::ContentBox;
+}
+
+void ResizeObserver::observeInternal(Element* target,
+ ResizeObserverBoxOptions box_option) {
auto& observer_map = target->EnsureResizeObserverData();
- if (observer_map.Contains(this))
- return; // Already registered.
- auto* observation = MakeGarbageCollected<ResizeObservation>(target, this);
+ if (observer_map.Contains(this)) {
+ auto observation = observer_map.find(this);
+ if ((*observation).value->observedBox() == box_option)
+ return;
+
+ // Unobserve target if box_option has changed and target already existed. If
+ // there is an existing observation of a different box, this new observation
+ // takes precedence. See:
+ // https://drafts.csswg.org/resize-observer/#processing-model
+ observations_.erase((*observation).value);
+ auto index = active_observations_.Find((*observation).value);
+ if (index != kNotFound) {
+ active_observations_.EraseAt(index);
+ }
+ observer_map.erase(observation);
+ }
+
+ auto* observation =
+ MakeGarbageCollected<ResizeObservation>(target, this, box_option);
observations_.insert(observation);
observer_map.Set(this, observation);
@@ -58,6 +90,16 @@ void ResizeObserver::observe(Element* target) {
frame_view->ScheduleAnimation();
}
+void ResizeObserver::observe(Element* target,
+ const ResizeObserverOptions* options) {
+ ResizeObserverBoxOptions box_option = ParseBoxOptions(options->box());
+ observeInternal(target, box_option);
+}
+
+void ResizeObserver::observe(Element* target) {
+ observeInternal(target, ResizeObserverBoxOptions::ContentBox);
+}
+
void ResizeObserver::unobserve(Element* target) {
auto* observer_map = target ? target->ResizeObserverData() : nullptr;
if (!observer_map)
@@ -89,8 +131,6 @@ size_t ResizeObserver::GatherObservations(size_t deeper_than) {
DCHECK(active_observations_.IsEmpty());
size_t min_observed_depth = ResizeObserverController::kDepthBottom;
- if (!element_size_changed_)
- return min_observed_depth;
for (auto& observation : observations_) {
if (!observation->ObservationSizeOutOfSync())
continue;
@@ -106,9 +146,6 @@ size_t ResizeObserver::GatherObservations(size_t deeper_than) {
}
void ResizeObserver::DeliverObservations() {
- // We can only clear this flag after all observations have been
- // broadcast.
- element_size_changed_ = skipped_observations_;
if (active_observations_.IsEmpty())
return;
@@ -123,26 +160,9 @@ void ResizeObserver::DeliverObservations() {
if (!execution_context || execution_context->IsContextDestroyed())
continue;
- LayoutPoint location = observation->ComputeTargetLocation();
- LayoutSize size = observation->ComputeTargetSize();
- observation->SetObservationSize(size);
-
- LayoutRect content_rect(location, size);
- if (observation->Target()->GetLayoutObject()) {
- // Must adjust for zoom in order to report non-zoomed size.
- const ComputedStyle& style =
- observation->Target()->GetLayoutObject()->StyleRef();
- content_rect.SetX(
- AdjustForAbsoluteZoom::AdjustLayoutUnit(content_rect.X(), style));
- content_rect.SetY(
- AdjustForAbsoluteZoom::AdjustLayoutUnit(content_rect.Y(), style));
- content_rect.SetWidth(
- AdjustForAbsoluteZoom::AdjustLayoutUnit(content_rect.Width(), style));
- content_rect.SetHeight(AdjustForAbsoluteZoom::AdjustLayoutUnit(
- content_rect.Height(), style));
- }
- auto* entry = MakeGarbageCollected<ResizeObserverEntry>(
- observation->Target(), content_rect);
+ observation->SetObservationSize(observation->ComputeTargetSize());
+ auto* entry =
+ MakeGarbageCollected<ResizeObserverEntry>(observation->Target());
entries.push_back(entry);
}
@@ -168,24 +188,18 @@ void ResizeObserver::ClearObservations() {
skipped_observations_ = false;
}
-void ResizeObserver::ElementSizeChanged() {
- element_size_changed_ = true;
- if (controller_)
- controller_->ObserverChanged();
-}
-
bool ResizeObserver::HasPendingActivity() const {
return !observations_.IsEmpty();
}
-void ResizeObserver::Trace(blink::Visitor* visitor) {
+void ResizeObserver::Trace(Visitor* visitor) {
visitor->Trace(callback_);
visitor->Trace(delegate_);
visitor->Trace(observations_);
visitor->Trace(active_observations_);
visitor->Trace(controller_);
ScriptWrappable::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 572f88ee1c4..8e8dd97ea24 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
@@ -7,7 +7,8 @@
#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/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/resize_observer/resize_observer_box_options.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -19,13 +20,14 @@ class ResizeObserverController;
class ResizeObserverEntry;
class ResizeObservation;
class V8ResizeObserverCallback;
+class ResizeObserverOptions;
// ResizeObserver represents ResizeObserver javascript api:
// https://github.com/WICG/ResizeObserver/
class CORE_EXPORT ResizeObserver final
: public ScriptWrappable,
public ActiveScriptWrappable<ResizeObserver>,
- public ContextClient {
+ public ExecutionContextClient {
USING_GARBAGE_COLLECTED_MIXIN(ResizeObserver);
DEFINE_WRAPPERTYPEINFO();
@@ -36,7 +38,7 @@ class CORE_EXPORT ResizeObserver final
virtual ~Delegate() = default;
virtual void OnResize(
const HeapVector<Member<ResizeObserverEntry>>& entries) = 0;
- virtual void Trace(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
};
static ResizeObserver* Create(Document&, V8ResizeObserverCallback*);
@@ -47,6 +49,7 @@ class CORE_EXPORT ResizeObserver final
~ResizeObserver() override = default;
// API methods
+ void observe(Element*, const ResizeObserverOptions* options);
void observe(Element*);
void unobserve(Element*);
void disconnect();
@@ -56,15 +59,17 @@ class CORE_EXPORT ResizeObserver final
bool SkippedObservations() { return skipped_observations_; }
void DeliverObservations();
void ClearObservations();
- void ElementSizeChanged();
- bool HasElementSizeChanged() { return element_size_changed_; }
+
+ ResizeObserverBoxOptions ParseBoxOptions(const String& box_options);
// ScriptWrappable override:
bool HasPendingActivity() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
+ void observeInternal(Element* target, ResizeObserverBoxOptions box_option);
+
using ObservationList = HeapLinkedHashSet<WeakMember<ResizeObservation>>;
// Either of |callback_| and |delegate_| should be non-null.
@@ -79,8 +84,7 @@ class CORE_EXPORT ResizeObserver final
HeapVector<Member<ResizeObservation>> active_observations_;
// True if observations were skipped gatherObservations
bool skipped_observations_;
- // True if any ResizeObservation reported size change
- bool element_size_changed_;
+
WeakMember<ResizeObserverController> controller_;
};
diff --git a/chromium/third_party/blink/renderer/core/resize_observer/resize_observer.idl b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer.idl
index 8e09fdd4212..f6e0e947513 100644
--- a/chromium/third_party/blink/renderer/core/resize_observer/resize_observer.idl
+++ b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer.idl
@@ -10,11 +10,10 @@ callback ResizeObserverCallback = void (sequence<ResizeObserverEntry> entries, R
[
Exposed=Window,
- ActiveScriptWrappable,
- Constructor(ResizeObserverCallback callback),
- MeasureAs=ResizeObserver_Constructor,
- ConstructorCallWith=Document
+ ActiveScriptWrappable
] interface ResizeObserver {
+ [CallWith=Document, MeasureAs=ResizeObserver_Constructor] constructor(ResizeObserverCallback callback);
+ [RuntimeEnabled=ResizeObserverUpdates] void observe(Element target, ResizeObserverOptions options);
void observe(Element target);
void unobserve(Element target);
void disconnect();
diff --git a/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_box_options.h b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_box_options.h
new file mode 100644
index 00000000000..15e4cd9bdf6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_box_options.h
@@ -0,0 +1,12 @@
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_RESIZE_OBSERVER_RESIZE_OBSERVER_BOX_OPTIONS_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_RESIZE_OBSERVER_RESIZE_OBSERVER_BOX_OPTIONS_H_
+
+namespace blink {
+enum class ResizeObserverBoxOptions {
+ BorderBox,
+ ContentBox,
+ DevicePixelContentBox
+};
+}
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_RESIZE_OBSERVER_RESIZE_OBSERVER_BOX_OPTIONS_H_
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 e1ae935916c..4a7aa879403 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
@@ -8,31 +8,22 @@
namespace blink {
-ResizeObserverController::ResizeObserverController()
- : observers_changed_(false) {}
+ResizeObserverController::ResizeObserverController() = default;
void ResizeObserverController::AddObserver(ResizeObserver& observer) {
observers_.insert(&observer);
}
-size_t ResizeObserverController::GatherObservations(size_t deeper_than) {
+size_t ResizeObserverController::GatherObservations() {
size_t shallowest = ResizeObserverController::kDepthBottom;
- if (!observers_changed_)
- return shallowest;
+
for (auto& observer : observers_) {
- size_t depth = observer->GatherObservations(deeper_than);
+ size_t depth = observer->GatherObservations(min_depth_);
if (depth < shallowest)
shallowest = depth;
}
- return shallowest;
-}
-
-void ResizeObserverController::SetNeedsForcedResizeObservations() {
- for (auto& observer : observers_) {
- // Set ElementSizeChanged as a way of forcing the observer to check all
- // observations.
- observer->ElementSizeChanged();
- }
+ min_depth_ = shallowest;
+ return min_depth_;
}
bool ResizeObserverController::SkippedObservations() {
@@ -44,7 +35,6 @@ bool ResizeObserverController::SkippedObservations() {
}
void ResizeObserverController::DeliverObservations() {
- observers_changed_ = false;
// Copy is needed because m_observers might get modified during
// deliverObservations.
HeapVector<Member<ResizeObserver>> observers;
@@ -53,8 +43,6 @@ void ResizeObserverController::DeliverObservations() {
for (auto& observer : observers) {
if (observer) {
observer->DeliverObservations();
- observers_changed_ =
- observers_changed_ || observer->HasElementSizeChanged();
}
}
}
@@ -64,7 +52,7 @@ void ResizeObserverController::ClearObservations() {
observer->ClearObservations();
}
-void ResizeObserverController::Trace(blink::Visitor* visitor) {
+void ResizeObserverController::Trace(Visitor* 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 27511e15ddc..f8de314f644 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
@@ -28,29 +28,28 @@ class ResizeObserverController final
void AddObserver(ResizeObserver&);
// observation API
- // Returns depth of shallowest observed node, kDepthLimit if none.
- size_t GatherObservations(size_t deeper_than);
+ // Returns min depth of shallowest observed node, kDepthLimit if none.
+ size_t GatherObservations();
// Returns true if gatherObservations has skipped observations
// because they were too shallow.
bool SkippedObservations();
void DeliverObservations();
void ClearObservations();
- void ObserverChanged() { observers_changed_ = true; }
- void SetNeedsForcedResizeObservations();
+ void ClearMinDepth() { min_depth_ = 0; }
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
// For testing only.
- const HeapHashSet<WeakMember<ResizeObserver>>& Observers() {
+ const HeapLinkedHashSet<WeakMember<ResizeObserver>>& Observers() {
return observers_;
}
private:
// Active observers
- HeapHashSet<WeakMember<ResizeObserver>> observers_;
- // True if any observers were changed since last notification.
- bool observers_changed_;
+ HeapLinkedHashSet<WeakMember<ResizeObserver>> observers_;
+ // Minimum depth for observations to be active
+ size_t min_depth_ = 0;
};
} // namespace blink
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 53d101951cd..e4c23d5b7a1 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
@@ -3,24 +3,115 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/core/resize_observer/resize_observer_entry.h"
-
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/geometry/dom_rect_read_only.h"
+#include "third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h"
+#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/resize_observer/resize_observation.h"
+#include "third_party/blink/renderer/core/resize_observer/resize_observer_size.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
+#include "third_party/blink/renderer/core/svg/svg_graphics_element.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.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/runtime_enabled_features.h"
namespace blink {
-ResizeObserverEntry::ResizeObserverEntry(Element* target,
- const LayoutRect& content_rect)
- : target_(target) {
- content_rect_ = DOMRectReadOnly::FromFloatRect(FloatRect(
+DOMRectReadOnly* ResizeObserverEntry::ZoomAdjustedLayoutRect(
+ LayoutRect content_rect,
+ const ComputedStyle& style) {
+ content_rect.SetX(
+ AdjustForAbsoluteZoom::AdjustLayoutUnit(content_rect.X(), style));
+ content_rect.SetY(
+ AdjustForAbsoluteZoom::AdjustLayoutUnit(content_rect.Y(), style));
+ content_rect.SetWidth(
+ AdjustForAbsoluteZoom::AdjustLayoutUnit(content_rect.Width(), style));
+ content_rect.SetHeight(
+ AdjustForAbsoluteZoom::AdjustLayoutUnit(content_rect.Height(), style));
+
+ return DOMRectReadOnly::FromFloatRect(FloatRect(
FloatPoint(content_rect.Location()), FloatSize(content_rect.Size())));
}
-void ResizeObserverEntry::Trace(blink::Visitor* visitor) {
+ResizeObserverSize* ResizeObserverEntry::ZoomAdjustedSize(
+ const LayoutSize box_size,
+ const ComputedStyle& style) {
+ return ResizeObserverSize::Create(
+ AdjustForAbsoluteZoom::AdjustLayoutUnit(box_size.Width(), style),
+ AdjustForAbsoluteZoom::AdjustLayoutUnit(box_size.Height(), style));
+}
+
+ResizeObserverEntry::ResizeObserverEntry(Element* target) : target_(target) {
+ if (LayoutObject* layout_object = target->GetLayoutObject()) {
+ const ComputedStyle& style = layout_object->StyleRef();
+ // SVG box properties are always based on bounding box
+ if (auto* svg_graphics_element = DynamicTo<SVGGraphicsElement>(target)) {
+ LayoutSize bounding_box_size =
+ LayoutSize(svg_graphics_element->GetBBox().Size());
+ content_rect_ = DOMRectReadOnly::FromFloatRect(
+ FloatRect(FloatPoint(), FloatSize(bounding_box_size)));
+ if (RuntimeEnabledFeatures::ResizeObserverUpdatesEnabled()) {
+ ResizeObserverSize* size = ResizeObserverSize::Create(
+ bounding_box_size.Width(), bounding_box_size.Height());
+ content_box_size_.push_back(size);
+ border_box_size_.push_back(size);
+ device_pixel_content_box_size_.push_back(size);
+ }
+ } else if (layout_object->IsBox()) {
+ LayoutBox* layout_box = target->GetLayoutBox();
+ LayoutRect content_rect(
+ LayoutPoint(layout_box->PaddingLeft(), layout_box->PaddingTop()),
+ layout_box->ContentSize());
+ content_rect_ = ZoomAdjustedLayoutRect(content_rect, style);
+
+ if (RuntimeEnabledFeatures::ResizeObserverUpdatesEnabled()) {
+ LayoutSize content_box_size =
+ LayoutSize(layout_box->ContentLogicalWidth(),
+ layout_box->ContentLogicalHeight());
+ LayoutSize border_box_size =
+ LayoutSize(layout_box->LogicalWidth(), layout_box->LogicalHeight());
+
+ LayoutSize paint_offset =
+ layout_object->FirstFragment().PaintOffset().ToLayoutSize();
+ ResizeObserverSize* device_pixel_content_box_size =
+ ResizeObserverSize::Create(
+ SnapSizeToPixel(layout_box->ContentLogicalWidth(),
+ style.IsHorizontalWritingMode()
+ ? paint_offset.Width()
+ : paint_offset.Height()),
+ SnapSizeToPixel(layout_box->ContentLogicalHeight(),
+ style.IsHorizontalWritingMode()
+ ? paint_offset.Height()
+ : paint_offset.Width()));
+
+ content_box_size_.push_back(ZoomAdjustedSize(content_box_size, style));
+ border_box_size_.push_back(ZoomAdjustedSize(border_box_size, style));
+ device_pixel_content_box_size_.push_back(device_pixel_content_box_size);
+ }
+ }
+ }
+ if (!content_rect_)
+ content_rect_ = DOMRectReadOnly::FromFloatRect(
+ FloatRect(FloatPoint(LayoutPoint()), FloatSize(LayoutSize())));
+ if (RuntimeEnabledFeatures::ResizeObserverUpdatesEnabled()) {
+ if (content_box_size_.size() == 0)
+ content_box_size_.push_back(ResizeObserverSize::Create(0, 0));
+ if (border_box_size_.size() == 0)
+ border_box_size_.push_back(ResizeObserverSize::Create(0, 0));
+ if (device_pixel_content_box_size_.size() == 0) {
+ device_pixel_content_box_size_.push_back(
+ ResizeObserverSize::Create(0, 0));
+ }
+ }
+}
+
+void ResizeObserverEntry::Trace(Visitor* visitor) {
visitor->Trace(target_);
visitor->Trace(content_rect_);
+ visitor->Trace(content_box_size_);
+ visitor->Trace(border_box_size_);
+ visitor->Trace(device_pixel_content_box_size_);
ScriptWrappable::Trace(visitor);
}
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 379cc05381d..39494322080 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
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_RESIZE_OBSERVER_RESIZE_OBSERVER_ENTRY_H_
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/resize_observer/resize_observer_size.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -13,22 +14,42 @@ namespace blink {
class Element;
class DOMRectReadOnly;
+class LayoutSize;
+class ComputedStyle;
+class ResizeObserverSize;
class LayoutRect;
class CORE_EXPORT ResizeObserverEntry final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- ResizeObserverEntry(Element* target, const LayoutRect& content_rect);
+ ResizeObserverEntry(Element* target);
Element* target() const { return target_; }
DOMRectReadOnly* contentRect() const { return content_rect_; }
-
- void Trace(blink::Visitor*) override;
+ HeapVector<Member<ResizeObserverSize>> contentBoxSize() const {
+ return content_box_size_;
+ }
+ HeapVector<Member<ResizeObserverSize>> borderBoxSize() const {
+ return border_box_size_;
+ }
+ HeapVector<Member<ResizeObserverSize>> devicePixelContentBoxSize() const {
+ return device_pixel_content_box_size_;
+ }
+
+ void Trace(Visitor*) override;
private:
Member<Element> target_;
Member<DOMRectReadOnly> content_rect_;
+ HeapVector<Member<ResizeObserverSize>> device_pixel_content_box_size_;
+ HeapVector<Member<ResizeObserverSize>> content_box_size_;
+ HeapVector<Member<ResizeObserverSize>> border_box_size_;
+
+ static DOMRectReadOnly* ZoomAdjustedLayoutRect(LayoutRect content_rect,
+ const ComputedStyle& style);
+ static ResizeObserverSize* ZoomAdjustedSize(const LayoutSize box_size,
+ const ComputedStyle& style);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_entry.idl b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_entry.idl
index 969b0f53a73..4a4006cc795 100644
--- a/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_entry.idl
+++ b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_entry.idl
@@ -8,4 +8,7 @@
interface ResizeObserverEntry {
readonly attribute Element target;
readonly attribute DOMRectReadOnly contentRect;
+ [RuntimeEnabled=ResizeObserverUpdates] readonly attribute FrozenArray<ResizeObserverSize> contentBoxSize;
+ [RuntimeEnabled=ResizeObserverUpdates] readonly attribute FrozenArray<ResizeObserverSize> borderBoxSize;
+ [RuntimeEnabled=ResizeObserverUpdates] readonly attribute FrozenArray<ResizeObserverSize> devicePixelContentBoxSize;
};
diff --git a/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_options.idl b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_options.idl
new file mode 100644
index 00000000000..4b58e04f842
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_options.idl
@@ -0,0 +1,15 @@
+// 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://drafts.csswg.org/resize-observer/#enumdef-resizeobserverboxoptions
+
+enum ResizeObserverBoxOptions {
+ "border-box", "content-box", "device-pixel-content-box"
+};
+
+// https://drafts.csswg.org/resize-observer/#dictdef-resizeobserveroptions
+
+dictionary ResizeObserverOptions {
+ ResizeObserverBoxOptions box = "content-box";
+};
diff --git a/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_size.cc b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_size.cc
new file mode 100644
index 00000000000..e6a190d62d2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_size.cc
@@ -0,0 +1,22 @@
+// 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/resize_observer/resize_observer_size.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+
+namespace blink {
+
+ResizeObserverSize* ResizeObserverSize::Create(double inline_size,
+ double block_size) {
+ return MakeGarbageCollected<ResizeObserverSize>(inline_size, block_size);
+}
+
+ResizeObserverSize::ResizeObserverSize(double inline_size, double block_size)
+ : inline_size_(inline_size), block_size_(block_size) {}
+
+ResizeObserverSize::ResizeObserverSize() = default;
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_size.h b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_size.h
new file mode 100644
index 00000000000..1d0e50f9281
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_size.h
@@ -0,0 +1,32 @@
+// 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_RESIZE_OBSERVER_RESIZE_OBSERVER_SIZE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_RESIZE_OBSERVER_RESIZE_OBSERVER_SIZE_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+
+namespace blink {
+
+class CORE_EXPORT ResizeObserverSize final : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static ResizeObserverSize* Create(double inline_size, double block_size);
+
+ ResizeObserverSize(const double inline_size, const double block_size);
+ ResizeObserverSize();
+
+ double inlineSize() const { return inline_size_; }
+ double blockSize() const { return block_size_; }
+
+ private:
+ double inline_size_;
+ double block_size_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_RESIZE_OBSERVER_RESIZE_OBSERVER_SIZE_H_
diff --git a/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_size.idl b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_size.idl
new file mode 100644
index 00000000000..a9d93b39056
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/resize_observer/resize_observer_size.idl
@@ -0,0 +1,12 @@
+// 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://drafts.csswg.org/resize-observer-1/#resizeobserversize
+
+[
+ RuntimeEnabled=ResizeObserverUpdates
+] interface ResizeObserverSize {
+ readonly attribute unrestricted double inlineSize;
+ readonly attribute unrestricted double blockSize;
+};
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 abc73217cd1..988b84e3d24 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
@@ -9,9 +9,13 @@
#include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_resize_observer_options.h"
#include "third_party/blink/renderer/core/exported/web_view_impl.h"
+#include "third_party/blink/renderer/core/geometry/dom_rect_read_only.h"
#include "third_party/blink/renderer/core/resize_observer/resize_observation.h"
+#include "third_party/blink/renderer/core/resize_observer/resize_observer_box_options.h"
#include "third_party/blink/renderer/core/resize_observer/resize_observer_controller.h"
+#include "third_party/blink/renderer/core/resize_observer/resize_observer_size.h"
#include "third_party/blink/renderer/core/testing/sim/sim_compositor.h"
#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
@@ -30,10 +34,12 @@ class TestResizeObserverDelegate : public ResizeObserver::Delegate {
const HeapVector<Member<ResizeObserverEntry>>& entries) override {
call_count_++;
}
- ExecutionContext* GetExecutionContext() const { return document_; }
+ ExecutionContext* GetExecutionContext() const {
+ return document_->ToExecutionContext();
+ }
int CallCount() const { return call_count_; }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
ResizeObserver::Delegate::Trace(visitor);
visitor->Trace(document_);
}
@@ -54,7 +60,7 @@ class TestResizeObserverDelegate : public ResizeObserver::Delegate {
*/
class ResizeObserverUnitTest : public SimTest {};
-TEST_F(ResizeObserverUnitTest, ResizeObservationSize) {
+TEST_F(ResizeObserverUnitTest, ResizeObserverDOMContentBoxAndSVG) {
SimRequest main_resource("https://example.com/", "text/html");
LoadURL("https://example.com/");
@@ -71,10 +77,10 @@ TEST_F(ResizeObserverUnitTest, ResizeObservationSize) {
ResizeObserver* observer = ResizeObserver::Create(GetDocument(), delegate);
Element* dom_target = GetDocument().getElementById("domTarget");
Element* svg_target = GetDocument().getElementById("svgTarget");
- ResizeObservation* dom_observation =
- MakeGarbageCollected<ResizeObservation>(dom_target, observer);
- ResizeObservation* svg_observation =
- MakeGarbageCollected<ResizeObservation>(svg_target, observer);
+ ResizeObservation* dom_observation = MakeGarbageCollected<ResizeObservation>(
+ dom_target, observer, ResizeObserverBoxOptions::ContentBox);
+ ResizeObservation* svg_observation = MakeGarbageCollected<ResizeObservation>(
+ svg_target, observer, ResizeObserverBoxOptions::ContentBox);
// Initial observation is out of sync
ASSERT_TRUE(dom_observation->ObservationSizeOutOfSync());
@@ -93,16 +99,160 @@ TEST_F(ResizeObserverUnitTest, ResizeObservationSize) {
// Target size is in sync
ASSERT_FALSE(dom_observation->ObservationSizeOutOfSync());
+ ASSERT_FALSE(svg_observation->ObservationSizeOutOfSync());
// Target depths
ASSERT_EQ(svg_observation->TargetDepth() - dom_observation->TargetDepth(),
(size_t)1);
}
+TEST_F(ResizeObserverUnitTest, ResizeObserverDOMBorderBox) {
+ SimRequest main_resource("https://example.com/", "text/html");
+ LoadURL("https://example.com/");
+
+ main_resource.Write(R"HTML(
+ <div id='domBorderTarget' style='width:100px;height:100px;padding:5px'>
+ yoyo
+ </div>
+ )HTML");
+ main_resource.Finish();
+
+ ResizeObserver::Delegate* delegate =
+ MakeGarbageCollected<TestResizeObserverDelegate>(GetDocument());
+ ResizeObserver* observer = ResizeObserver::Create(GetDocument(), delegate);
+ Element* dom_border_target = GetDocument().getElementById("domBorderTarget");
+ ResizeObservation* dom_border_observation =
+ MakeGarbageCollected<ResizeObservation>(
+ dom_border_target, observer, ResizeObserverBoxOptions::BorderBox);
+
+ // Initial observation is out of sync
+ ASSERT_TRUE(dom_border_observation->ObservationSizeOutOfSync());
+
+ // Target size is correct
+ LayoutSize size = dom_border_observation->ComputeTargetSize();
+ ASSERT_EQ(size.Width(), 110);
+ ASSERT_EQ(size.Height(), 110);
+ dom_border_observation->SetObservationSize(size);
+
+ // Target size is in sync
+ ASSERT_FALSE(dom_border_observation->ObservationSizeOutOfSync());
+}
+
+TEST_F(ResizeObserverUnitTest, ResizeObserverDOMDevicePixelContentBox) {
+ SimRequest main_resource("https://example.com/", "text/html");
+ LoadURL("https://example.com/");
+
+ main_resource.Write(R"HTML(
+ <div id='domTarget' style='width:100px;height:100px'>yo</div>
+ <svg height='200' width='200'>
+ <div style='zoom:3;'>
+ <div id='domDPTarget' style='width:50px;height:30px'></div>
+ </div>
+ </svg>
+ )HTML");
+ main_resource.Finish();
+
+ ResizeObserver::Delegate* delegate =
+ MakeGarbageCollected<TestResizeObserverDelegate>(GetDocument());
+ ResizeObserver* observer = ResizeObserver::Create(GetDocument(), delegate);
+ Element* dom_target = GetDocument().getElementById("domTarget");
+ Element* dom_dp_target = GetDocument().getElementById("domDPTarget");
+
+ ResizeObservation* dom_dp_nested_observation =
+ MakeGarbageCollected<ResizeObservation>(
+ dom_dp_target, observer,
+ ResizeObserverBoxOptions::DevicePixelContentBox);
+ ResizeObservation* dom_dp_observation =
+ MakeGarbageCollected<ResizeObservation>(
+ dom_target, observer,
+ ResizeObserverBoxOptions::DevicePixelContentBox);
+
+ // Initial observation is out of sync
+ ASSERT_TRUE(dom_dp_observation->ObservationSizeOutOfSync());
+ ASSERT_TRUE(dom_dp_nested_observation->ObservationSizeOutOfSync());
+
+ // Target size is correct
+ LayoutSize size = dom_dp_observation->ComputeTargetSize();
+ ASSERT_EQ(size.Width(), 100);
+ ASSERT_EQ(size.Height(), 100);
+ dom_dp_observation->SetObservationSize(size);
+
+ size = dom_dp_nested_observation->ComputeTargetSize();
+ ASSERT_EQ(size.Width(), 150);
+ ASSERT_EQ(size.Height(), 90);
+ dom_dp_nested_observation->SetObservationSize(size);
+
+ // Target size is in sync
+ ASSERT_FALSE(dom_dp_observation->ObservationSizeOutOfSync());
+ ASSERT_FALSE(dom_dp_nested_observation->ObservationSizeOutOfSync());
+}
+
+// Test whether a new observation is created when an observation's
+// observed box is changed
+TEST_F(ResizeObserverUnitTest, TestBoxOverwrite) {
+ SimRequest main_resource("https://example.com/", "text/html");
+ LoadURL("https://example.com/");
+
+ main_resource.Write(R"HTML(
+ <div id='domTarget' style='width:100px;height:100px'>yo</div>
+ <svg height='200' width='200'>
+ <circle id='svgTarget' cx='100' cy='100' r='100'/>
+ </svg>
+ )HTML");
+ main_resource.Finish();
+
+ ResizeObserverOptions* border_box_option = ResizeObserverOptions::Create();
+ border_box_option->setBox("border-box");
+
+ ResizeObserver::Delegate* delegate =
+ MakeGarbageCollected<TestResizeObserverDelegate>(GetDocument());
+ ResizeObserver* observer = ResizeObserver::Create(GetDocument(), delegate);
+ Element* dom_target = GetDocument().getElementById("domTarget");
+
+ // Assert no observations (depth returned is kDepthBottom)
+ size_t min_observed_depth = ResizeObserverController::kDepthBottom;
+ ASSERT_EQ(observer->GatherObservations(0), min_observed_depth);
+ observer->observe(dom_target);
+
+ // 3 is Depth of observed element
+ ASSERT_EQ(observer->GatherObservations(0), (size_t)3);
+ observer->observe(dom_target, border_box_option);
+ // Active observations should be empty and GatherObservations should run
+ ASSERT_EQ(observer->GatherObservations(0), (size_t)3);
+}
+
+// Test that default content rect, content box, and border box are created when
+// a non box target's entry is made
+TEST_F(ResizeObserverUnitTest, TestNonBoxTarget) {
+ SimRequest main_resource("https://example.com/", "text/html");
+ LoadURL("https://example.com/");
+
+ main_resource.Write(R"HTML(
+ <span id='domTarget'>yo</div>
+ )HTML");
+ main_resource.Finish();
+
+ ResizeObserverOptions* border_box_option = ResizeObserverOptions::Create();
+ border_box_option->setBox("border-box");
+
+ Element* dom_target = GetDocument().getElementById("domTarget");
+
+ auto* entry = MakeGarbageCollected<ResizeObserverEntry>(dom_target);
+
+ EXPECT_EQ(entry->contentRect()->width(), 0);
+ EXPECT_EQ(entry->contentRect()->height(), 0);
+ EXPECT_EQ(entry->contentBoxSize().at(0)->inlineSize(), 0);
+ EXPECT_EQ(entry->contentBoxSize().at(0)->blockSize(), 0);
+ EXPECT_EQ(entry->borderBoxSize().at(0)->inlineSize(), 0);
+ EXPECT_EQ(entry->borderBoxSize().at(0)->blockSize(), 0);
+ EXPECT_EQ(entry->devicePixelContentBoxSize().at(0)->inlineSize(), 0);
+ EXPECT_EQ(entry->devicePixelContentBoxSize().at(0)->blockSize(), 0);
+}
+
TEST_F(ResizeObserverUnitTest, TestMemoryLeaks) {
ResizeObserverController& controller =
GetDocument().EnsureResizeObserverController();
- const HeapHashSet<WeakMember<ResizeObserver>>& observers =
+ const HeapLinkedHashSet<WeakMember<ResizeObserver>>& observers =
controller.Observers();
ASSERT_EQ(observers.size(), 0U);
v8::HandleScope scope(v8::Isolate::GetCurrent());
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 f4a41edd17d..18b79eaea43 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
@@ -67,8 +67,7 @@ class FrameThrottlingTest : public PaintTestConfigurations, public SimTest {
}
void UpdateAllLifecyclePhases() {
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
}
};
@@ -186,42 +185,98 @@ TEST_P(FrameThrottlingTest, IntersectionObservationOverridesThrottling) {
EXPECT_FALSE(frame_document->View()->CanThrottleRendering());
EXPECT_TRUE(inner_frame_document->View()->ShouldThrottleRendering());
- // An intersection observation overrides...
+ // An intersection observation overrides throttling during a lifecycle update.
inner_frame_document->View()->SetIntersectionObservationState(
LocalFrameView::kRequired);
- EXPECT_FALSE(inner_frame_document->View()->ShouldThrottleRendering());
+ {
+ GetDocument().GetFrame()->View()->SetInLifecycleUpdateForTest(true);
+ EXPECT_FALSE(inner_frame_document->View()->ShouldThrottleRendering());
+ GetDocument().GetFrame()->View()->SetInLifecycleUpdateForTest(false);
+ }
+
inner_frame_document->View()->ScheduleAnimation();
LayoutView* inner_view = inner_frame_document->View()->GetLayoutView();
inner_view->SetNeedsLayout("test");
- inner_view->Compositor()->SetNeedsCompositingUpdate(
- kCompositingUpdateRebuildTree);
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ inner_view->Compositor()->SetNeedsCompositingUpdate(
+ kCompositingUpdateRebuildTree);
+ }
inner_view->SetShouldDoFullPaintInvalidation(
PaintInvalidationReason::kForTesting);
inner_view->Layer()->SetNeedsRepaint();
EXPECT_TRUE(inner_frame_document->View()
->GetLayoutView()
->ShouldDoFullPaintInvalidation());
- inner_view->Compositor()->SetNeedsCompositingUpdate(
- kCompositingUpdateRebuildTree);
- EXPECT_EQ(kCompositingUpdateRebuildTree,
- inner_view->Compositor()->pending_update_type_);
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ inner_view->Compositor()->SetNeedsCompositingUpdate(
+ kCompositingUpdateRebuildTree);
+ EXPECT_EQ(kCompositingUpdateRebuildTree,
+ inner_view->Compositor()->pending_update_type_);
+ }
EXPECT_TRUE(inner_view->Layer()->SelfNeedsRepaint());
CompositeFrame();
- // ...but only for one frame.
+ // The lifecycle update should only be overridden for one frame.
EXPECT_TRUE(inner_frame_document->View()->ShouldThrottleRendering());
EXPECT_FALSE(inner_view->NeedsLayout());
EXPECT_TRUE(inner_frame_document->View()
->GetLayoutView()
->ShouldDoFullPaintInvalidation());
- EXPECT_EQ(kCompositingUpdateRebuildTree,
- inner_view->Compositor()->pending_update_type_);
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ EXPECT_EQ(kCompositingUpdateRebuildTree,
+ inner_view->Compositor()->pending_update_type_);
+ }
EXPECT_TRUE(inner_view->Layer()->SelfNeedsRepaint());
}
+TEST_P(FrameThrottlingTest,
+ ThrottlingOverrideOnlyAppliesDuringLifecycleUpdate) {
+ // Create a document with a hidden cross-origin subframe.
+ 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(R"HTML(
+ <iframe id="frame" sandbox src="iframe.html"
+ style="transform: translateY(480px)">
+ )HTML");
+ frame_resource.Complete("<!doctype html>");
+
+ DocumentLifecycle::AllowThrottlingScope throttling_scope(
+ GetDocument().Lifecycle());
+ CompositeFrame();
+
+ auto* frame_element =
+ To<HTMLIFrameElement>(GetDocument().getElementById("frame"));
+ auto* frame_document = frame_element->contentDocument();
+ // Hidden cross origin frames are throttled.
+ EXPECT_TRUE(frame_document->View()->ShouldThrottleRendering());
+
+ // An intersection observation overrides throttling, but this is only during
+ // the lifecycle.
+ frame_document->View()->SetIntersectionObservationState(
+ LocalFrameView::kRequired);
+ EXPECT_TRUE(frame_document->View()->ShouldThrottleRendering());
+ {
+ GetDocument().GetFrame()->View()->SetInLifecycleUpdateForTest(true);
+ EXPECT_FALSE(frame_document->View()->ShouldThrottleRendering());
+ GetDocument().GetFrame()->View()->SetInLifecycleUpdateForTest(false);
+ }
+
+ // A lifecycle update can update the throttled frame to just LayoutClean but
+ // the frame should still be considered throttled outside the lifecycle
+ // because it is not fully running the lifecycle.
+ frame_document->View()->GetLayoutView()->SetNeedsLayout("test");
+ frame_document->View()->ScheduleAnimation();
+ frame_document->View()->GetLayoutView()->Layer()->SetNeedsRepaint();
+ CompositeFrame();
+ EXPECT_EQ(DocumentLifecycle::kLayoutClean,
+ frame_document->Lifecycle().GetState());
+ EXPECT_TRUE(frame_document->View()->ShouldThrottleRendering());
+}
+
TEST_P(FrameThrottlingTest, HiddenCrossOriginZeroByZeroFramesAreNotThrottled) {
// Create a document with doubly nested iframes.
SimRequest main_resource("https://example.com/", "text/html");
@@ -405,7 +460,7 @@ TEST_P(FrameThrottlingTest, UnthrottlingTriggersRepaint) {
// Scroll down to unthrottle the frame. The first frame we composite after
// scrolling won't contain the frame yet, but will schedule another repaint.
WebView().MainFrameImpl()->GetFrameView()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, 480), kProgrammaticScroll);
+ ScrollOffset(0, 480), mojom::blink::ScrollType::kProgrammatic);
auto commands = CompositeFrame();
EXPECT_FALSE(commands.Contains(SimCanvas::kRect, "green"));
@@ -444,7 +499,7 @@ TEST_P(FrameThrottlingTest, UnthrottlingTriggersRepaintInCompositedChild) {
// Scroll down to unthrottle the frame. The first frame we composite after
// scrolling won't contain the frame yet, but will schedule another repaint.
WebView().MainFrameImpl()->GetFrameView()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, 480), kProgrammaticScroll);
+ ScrollOffset(0, 480), mojom::blink::ScrollType::kProgrammatic);
auto commands = CompositeFrame();
EXPECT_FALSE(commands.Contains(SimCanvas::kRect, "green"));
@@ -477,7 +532,7 @@ TEST_P(FrameThrottlingTest, ChangeStyleInThrottledFrame) {
// Scroll down to unthrottle the frame.
WebView().MainFrameImpl()->GetFrameView()->LayoutViewport()->SetScrollOffset(
- ScrollOffset(0, 480), kProgrammaticScroll);
+ ScrollOffset(0, 480), mojom::blink::ScrollType::kProgrammatic);
auto commands = CompositeFrame();
EXPECT_FALSE(commands.Contains(SimCanvas::kRect, "red"));
EXPECT_FALSE(commands.Contains(SimCanvas::kRect, "green"));
@@ -504,7 +559,7 @@ TEST_P(FrameThrottlingTest, ChangeOriginInThrottledFrame) {
EXPECT_TRUE(frame_element->contentDocument()->View()->CanThrottleRendering());
EXPECT_TRUE(
- frame_element->contentDocument()->GetFrame()->IsCrossOriginSubframe());
+ frame_element->contentDocument()->GetFrame()->IsCrossOriginToMainFrame());
EXPECT_FALSE(frame_element->contentDocument()
->View()
->GetLayoutView()
@@ -518,7 +573,7 @@ TEST_P(FrameThrottlingTest, ChangeOriginInThrottledFrame) {
exception_state);
EXPECT_FALSE(
- frame_element->contentDocument()->GetFrame()->IsCrossOriginSubframe());
+ frame_element->contentDocument()->GetFrame()->IsCrossOriginToMainFrame());
EXPECT_FALSE(
frame_element->contentDocument()->View()->CanThrottleRendering());
EXPECT_TRUE(frame_element->contentDocument()
@@ -527,6 +582,46 @@ TEST_P(FrameThrottlingTest, ChangeOriginInThrottledFrame) {
->NeedsPaintPropertyUpdate());
}
+TEST_P(FrameThrottlingTest, MainFrameOriginChangeInvalidatesDescendants) {
+ // Create a hidden frame which is throttled.
+ SimRequest main_resource("https://sub.example.com/", "text/html");
+ SimRequest frame_resource("https://example.com/iframe.html", "text/html");
+ LoadURL("https://sub.example.com/");
+ main_resource.Complete(R"HTML(
+ <iframe id='frame' style='position: absolute; top: 10000px'
+ src='https://example.com/iframe.html'></iframe>
+ )HTML");
+ frame_resource.Complete("");
+
+ CompositeFrame();
+
+ auto* frame_element =
+ To<HTMLIFrameElement>(GetDocument().getElementById("frame"));
+ auto* frame_document = frame_element->contentDocument();
+ EXPECT_TRUE(frame_document->View()->CanThrottleRendering());
+ EXPECT_TRUE(frame_document->GetFrame()->IsCrossOriginToMainFrame());
+ EXPECT_FALSE(
+ frame_document->View()->GetLayoutView()->NeedsPaintPropertyUpdate());
+
+ // Set the domain of the child frame first which should be a no-op in terms of
+ // cross-origin status changes.
+ NonThrowableExceptionState exception_state;
+ frame_element->contentDocument()->setDomain(String("example.com"),
+ exception_state);
+ EXPECT_TRUE(frame_document->View()->CanThrottleRendering());
+ EXPECT_TRUE(frame_document->GetFrame()->IsCrossOriginToMainFrame());
+ EXPECT_FALSE(
+ frame_document->View()->GetLayoutView()->NeedsPaintPropertyUpdate());
+
+ // Then change the main frame origin which needs to invalidate the newly
+ // cross-origin child.
+ GetDocument().setDomain(String("example.com"), exception_state);
+ EXPECT_FALSE(frame_document->GetFrame()->IsCrossOriginToMainFrame());
+ EXPECT_FALSE(frame_document->View()->CanThrottleRendering());
+ EXPECT_TRUE(
+ frame_document->View()->GetLayoutView()->NeedsPaintPropertyUpdate());
+}
+
TEST_P(FrameThrottlingTest, ThrottledFrameWithFocus) {
WebView().GetSettings()->SetJavaScriptEnabled(true);
ScopedCompositedSelectionUpdateForTest composited_selection_update(true);
@@ -572,9 +667,15 @@ TEST_P(FrameThrottlingTest, ScrollingCoordinatorShouldSkipThrottledFrame) {
LoadURL("https://example.com/");
main_resource.Complete("<iframe id=frame sandbox src=iframe.html></iframe>");
- frame_resource.Complete(
- "<style> html { background-image: linear-gradient(red, blue); "
- "background-attachment: fixed; } </style>");
+ frame_resource.Complete(R"HTML(
+ <style>
+ html {
+ background-image: linear-gradient(red, blue);
+ background-attachment: fixed;
+ will-change: transform;
+ }
+ </style>
+ )HTML");
// Move the frame offscreen to throttle it.
auto* frame_element =
@@ -615,6 +716,9 @@ TEST_P(FrameThrottlingTest, ScrollingCoordinatorShouldSkipThrottledFrame) {
CompositeFrame();
EXPECT_FALSE(
frame_element->contentDocument()->View()->CanThrottleRendering());
+ // This CompositeFrame handles the visual update scheduled when we unthrottle
+ // the iframe.
+ CompositeFrame();
// The fixed background in the throttled sub frame should be considered.
EXPECT_TRUE(frame_element->contentDocument()
->View()
@@ -951,7 +1055,8 @@ TEST_P(FrameThrottlingTest, ThrottleInnerCompositedLayer) {
inner_div->setAttribute(kStyleAttr, "background: yellow; overflow: hidden");
// Do an unthrottled style and layout update, simulating the situation
// triggered by script style/layout access.
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
{
// And a throttled full lifecycle update.
DocumentLifecycle::AllowThrottlingScope throttling_scope(
@@ -1288,7 +1393,8 @@ TEST_P(FrameThrottlingTest, RebuildCompositedLayerTreeOnLayerRemoval) {
// This simulates a javascript query to layout results, e.g.
// document.body.offsetTop, which will force style & layout to be computed,
// whether the frame is throttled or not.
- frame_element->contentDocument()->UpdateStyleAndLayout();
+ frame_element->contentDocument()->UpdateStyleAndLayout(
+ DocumentUpdateReason::kTest);
EXPECT_EQ(DocumentLifecycle::kLayoutClean,
frame_element->contentDocument()->Lifecycle().GetState());
{
@@ -1330,7 +1436,8 @@ TEST_P(FrameThrottlingTest, LifecycleUpdateAfterUnthrottledCompositingUpdate) {
frame_document->getElementById("div")->setAttribute(kStyleAttr,
"will-change: transform");
- GetDocument().View()->UpdateLifecycleToCompositingCleanPlusScrolling();
+ GetDocument().View()->UpdateLifecycleToCompositingCleanPlusScrolling(
+ DocumentUpdateReason::kTest);
{
// Then do a full lifecycle with throttling enabled. This should not crash.
diff --git a/chromium/third_party/blink/renderer/core/scheduler_integration_tests/scheduler_affecting_features_test.cc b/chromium/third_party/blink/renderer/core/scheduler_integration_tests/scheduler_affecting_features_test.cc
index 270359ec6b9..d1acb022da3 100644
--- a/chromium/third_party/blink/renderer/core/scheduler_integration_tests/scheduler_affecting_features_test.cc
+++ b/chromium/third_party/blink/renderer/core/scheduler_integration_tests/scheduler_affecting_features_test.cc
@@ -35,8 +35,14 @@ class SchedulingAffectingFeaturesTest : public SimTest {
->GetActiveFeaturesTrackedForBackForwardCacheMetrics()) {
if (feature == SchedulingPolicy::Feature::kDocumentLoaded)
continue;
- if (feature == SchedulingPolicy::Feature::kOutstandingNetworkRequest)
+ if (feature == SchedulingPolicy::Feature::kOutstandingNetworkRequestFetch)
continue;
+ if (feature == SchedulingPolicy::Feature::kOutstandingNetworkRequestXHR)
+ continue;
+ if (feature ==
+ SchedulingPolicy::Feature::kOutstandingNetworkRequestOthers) {
+ continue;
+ }
result.push_back(feature);
}
return result;
diff --git a/chromium/third_party/blink/renderer/core/script/BUILD.gn b/chromium/third_party/blink/renderer/core/script/BUILD.gn
index c4d16409cd2..3b088840c47 100644
--- a/chromium/third_party/blink/renderer/core/script/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/script/BUILD.gn
@@ -26,10 +26,6 @@ blink_core_sources("script") {
"import_map.h",
"js_module_script.cc",
"js_module_script.h",
- "layered_api.cc",
- "layered_api.h",
- "layered_api_module.h",
- "layered_api_resources.h",
"modulator.cc",
"modulator.h",
"modulator_impl_base.cc",
@@ -50,6 +46,7 @@ blink_core_sources("script") {
"pending_import_map.h",
"pending_script.cc",
"pending_script.h",
+ "script.cc",
"script.h",
"script_element_base.cc",
"script_element_base.h",
@@ -69,30 +66,7 @@ blink_core_sources("script") {
"xml_parser_script_runner_host.h",
]
- deps = [
- "//third_party/blink/public:resources",
- ]
+ deps = [ "//third_party/blink/public:resources" ]
jumbo_excluded_sources = [ "modulator.cc" ] # https://crbug.com/716395
}
-
-copy("layered_apis_elements_virtual_scroller_js") {
- testonly = true
-
- sources = [
- "resources/layered_api/elements/virtual-scroller/find-element.mjs",
- "resources/layered_api/elements/virtual-scroller/sets.mjs",
- "resources/layered_api/elements/virtual-scroller/visibility-manager.mjs",
- ]
-
- outputs = [
- "{{source_gen_dir}}/{{source_file_part}}",
- ]
-}
-
-group("js_files_for_web_tests") {
- testonly = true
- data_deps = [
- ":layered_apis_elements_virtual_scroller_js",
- ]
-}
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 f516bc6134f..99d8e6a6d81 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
@@ -258,8 +258,9 @@ void ClassicPendingScript::NotifyFinished(Resource* resource) {
DCHECK(GetResource());
ScriptElementBase* element = GetElement();
if (element) {
- SubresourceIntegrityHelper::DoReport(element->GetDocument(),
- GetResource()->IntegrityReportInfo());
+ SubresourceIntegrityHelper::DoReport(
+ *element->GetDocument().GetExecutionContext(),
+ GetResource()->IntegrityReportInfo());
// It is possible to get back a script resource with integrity metadata
// for a request with an empty integrity attribute. In that case, the
diff --git a/chromium/third_party/blink/renderer/core/script/document_modulator_impl.cc b/chromium/third_party/blink/renderer/core/script/document_modulator_impl.cc
index 3fbdac959c4..f8edf807ba6 100644
--- a/chromium/third_party/blink/renderer/core/script/document_modulator_impl.cc
+++ b/chromium/third_party/blink/renderer/core/script/document_modulator_impl.cc
@@ -16,9 +16,10 @@ DocumentModulatorImpl::DocumentModulatorImpl(ScriptState* script_state)
: ModulatorImplBase(script_state) {}
ModuleScriptFetcher* DocumentModulatorImpl::CreateModuleScriptFetcher(
- ModuleScriptCustomFetchType custom_fetch_type) {
+ ModuleScriptCustomFetchType custom_fetch_type,
+ util::PassKey<ModuleScriptLoader> pass_key) {
DCHECK_EQ(ModuleScriptCustomFetchType::kNone, custom_fetch_type);
- return MakeGarbageCollected<DocumentModuleScriptFetcher>();
+ return MakeGarbageCollected<DocumentModuleScriptFetcher>(pass_key);
}
bool DocumentModulatorImpl::IsDynamicImportForbidden(String* reason) {
@@ -26,7 +27,7 @@ bool DocumentModulatorImpl::IsDynamicImportForbidden(String* reason) {
}
V8CacheOptions DocumentModulatorImpl::GetV8CacheOptions() const {
- Document* document = To<Document>(GetExecutionContext());
+ Document* document = Document::From(GetExecutionContext());
const Settings* settings = document->GetFrame()->GetSettings();
if (settings)
return settings->GetV8CacheOptions();
diff --git a/chromium/third_party/blink/renderer/core/script/document_modulator_impl.h b/chromium/third_party/blink/renderer/core/script/document_modulator_impl.h
index dd2153f2954..a0eac9f5ff6 100644
--- a/chromium/third_party/blink/renderer/core/script/document_modulator_impl.h
+++ b/chromium/third_party/blink/renderer/core/script/document_modulator_impl.h
@@ -24,7 +24,8 @@ class DocumentModulatorImpl final : public ModulatorImplBase {
// Implements Modulator.
ModuleScriptFetcher* CreateModuleScriptFetcher(
- ModuleScriptCustomFetchType) override;
+ ModuleScriptCustomFetchType,
+ util::PassKey<ModuleScriptLoader>) override;
private:
// Implements ModulatorImplBase.
diff --git a/chromium/third_party/blink/renderer/core/script/document_write_intervention.cc b/chromium/third_party/blink/renderer/core/script/document_write_intervention.cc
index 1106bd8e7a9..1670b367050 100644
--- a/chromium/third_party/blink/renderer/core/script/document_write_intervention.cc
+++ b/chromium/third_party/blink/renderer/core/script/document_write_intervention.cc
@@ -13,6 +13,7 @@
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/loader/resource/script_resource.h"
#include "third_party/blink/renderer/core/probe/core_probes.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/loader/fetch/script_fetch_options.h"
#include "third_party/blink/renderer/platform/network/network_state_notifier.h"
@@ -31,9 +32,9 @@ void EmitWarningMayBeBlocked(const String& url, Document& document) {
"confirmed in a subsequent console message. "
"See https://www.chromestatus.com/feature/5718547946799104 "
"for more details.";
- document.AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning, message));
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning, message));
DVLOG(1) << message.Utf8();
}
@@ -43,9 +44,9 @@ void EmitWarningNotBlocked(const String& url, Document& document) {
", invoked via document.write was NOT BLOCKED on this page load, but MAY "
"be blocked by the browser in future page loads with poor network "
"connectivity.";
- document.AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning, message));
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning, message));
}
void EmitErrorBlocked(const String& url, Document& document) {
@@ -55,9 +56,9 @@ void EmitErrorBlocked(const String& url, Document& document) {
url +
", invoked via document.write was BLOCKED by the browser due to poor "
"network connectivity. ";
- document.AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kIntervention,
- mojom::ConsoleMessageLevel::kError, message));
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kIntervention,
+ mojom::ConsoleMessageLevel::kError, message));
}
void AddWarningHeader(FetchParameters* params) {
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 cb2a7265c1a..d0eb4560747 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
@@ -265,7 +265,8 @@ void DynamicModuleResolver::ResolveDynamically(
if (auto* scope = DynamicTo<WorkerGlobalScope>(*execution_context))
scope->EnsureFetcher();
modulator_->FetchTree(url, execution_context->Fetcher(),
- mojom::RequestContextType::SCRIPT, options,
+ mojom::RequestContextType::SCRIPT,
+ network::mojom::RequestDestination::kScript, options,
ModuleScriptCustomFetchType::kNone, tree_client);
// Steps 6-9 are implemented at
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 5ccf159d035..bc58f764374 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
@@ -74,6 +74,7 @@ class DynamicModuleResolverTestModulator final : public DummyModulator {
void FetchTree(const KURL& url,
ResourceFetcher*,
mojom::RequestContextType,
+ network::mojom::RequestDestination,
const ScriptFetchOptions&,
ModuleScriptCustomFetchType custom_fetch_type,
ModuleTreeClient* client) final {
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 d4a2c6167fd..648a0b0e563 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
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/execution_context/security_context.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -76,7 +77,7 @@ network::mojom::IPAddressSpace FetchClientSettingsObjectImpl::GetAddressSpace()
return execution_context_->GetSecurityContext().AddressSpace();
}
-WebInsecureRequestPolicy
+mojom::blink::InsecureRequestPolicy
FetchClientSettingsObjectImpl::GetInsecureRequestsPolicy() const {
return execution_context_->GetSecurityContext().GetInsecureRequestPolicy();
}
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 932ba5bfc82..783ca717269 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
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_FETCH_CLIENT_SETTINGS_OBJECT_IMPL_H_
#include "services/network/public/mojom/referrer_policy.mojom-blink-forward.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/heap/member.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object.h"
@@ -44,7 +45,8 @@ class CORE_EXPORT FetchClientSettingsObjectImpl final
network::mojom::IPAddressSpace GetAddressSpace() const override;
- WebInsecureRequestPolicy GetInsecureRequestsPolicy() const override;
+ mojom::blink::InsecureRequestPolicy GetInsecureRequestsPolicy()
+ const override;
const InsecureNavigationsSet& GetUpgradeInsecureNavigationsSet()
const override;
diff --git a/chromium/third_party/blink/renderer/core/script/generate_lapi_grdp.py b/chromium/third_party/blink/renderer/core/script/generate_lapi_grdp.py
deleted file mode 100755
index fcb15ba5047..00000000000
--- a/chromium/third_party/blink/renderer/core/script/generate_lapi_grdp.py
+++ /dev/null
@@ -1,153 +0,0 @@
-#!/usr/bin/env python
-# 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.
-
-import sys
-import os
-import re
-
-
-def main():
- core_script_path = os.path.dirname(sys.argv[0])
-
- # The path to the directory containing layered API files.
- input_path = os.path.join(core_script_path, 'resources/layered_api')
-
- # Relative path from the main grd file; in this case,
- # third_party/blink/public/blink_resources.grd.
- input_relative_path = '../renderer/core/script/resources/layered_api'
-
- # Output .grdp file.
- output_grdp_file = open(
- os.path.join(core_script_path, 'resources/layered_api/resources.grdp'),
- 'w')
-
- # Output layered_api_resources.h file.
- output_header_file = open(
- os.path.join(core_script_path, 'layered_api_resources.h'), 'w')
-
- # Output layered_api_module.h file.
- output_module_header_file = open(
- os.path.join(core_script_path, 'layered_api_module.h'), 'w')
-
- print >> output_grdp_file, '''<?xml version="1.0" encoding="utf-8"?>
-<grit-part>
- <!-- Layered API scripts. This file is generated by
- core/script/generate_lapi_grdp.py and shouldn't modified manually.
- A corresponding header file (layered_api_resources.h) is also generated.
- The paths are relative to the main grd file, i.e.
- third_party/blink/public/blink_resources.grd.
- -->'''
-
- resource_list_in_header_file = ''
- # A list of (name, path)
- modules = []
- for root, _, filenames in sorted(os.walk(input_path)):
- # A directory represents a built-in module if
- # - it contains index.mjs (web-exposed module) or
- # - the directory name is 'internal' (private module)
- if 'index.mjs' in filenames or re.search(r'\binternal$', root):
- # Get e.g. "kKvStorage" for kv-storage.
- module_name = os.path.relpath(root, input_path)
- module_name = "k" + re.sub(r'\W', '', module_name.title())
- modules.append((module_name, root))
-
- for module_name, module_path in modules:
- for root, _, filenames in sorted(os.walk(module_path)):
- for filename in sorted(filenames):
- if filename.startswith('.') or filename.startswith(
- 'README') or filename.startswith('OWNERS'):
- continue
- relpath = os.path.relpath(os.path.join(root, filename), input_path)
- relpath = relpath.replace('\\', '/')
- resource_id = relpath
- resource_id = resource_id.replace('/', '_')
- resource_id = resource_id.replace('-', '_')
- resource_id = resource_id.replace('.', '_')
- resource_id = resource_id.upper()
- resource_id = "IDR_LAYERED_API_" + resource_id
- resource_list_in_header_file += \
- ' {"%s",\n %s,\n Module::%s},\n' % (relpath, resource_id, module_name)
- print >> output_grdp_file, (
- ' <include name="%s" file="%s/%s" type="BINDATA" skip_minify="true" compress="gzip"/>'
- % (resource_id, input_relative_path, relpath))
- resource_list_in_header_file += '\n'
- print >> output_grdp_file, '</grit-part>'
-
- module_list_in_header_file = ''
- for module, _ in modules:
- module_list_in_header_file += (' %s,\n' % module)
-
- print >> output_module_header_file, '''// 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_SCRIPT_LAYERED_API_MODULE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_LAYERED_API_MODULE_H_
-
-// This file is generated by
-// core/script/generate_lapi_grdp.py and shouldn't modified manually.
-// A corresponding grdp file (layered_api_resources.grdp) is also generated.
-
-namespace blink {
-
-namespace layered_api {
-
-enum class Module {
-%s};
-
-} // namespace layered_api
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_LAYERED_API_MODULE_H_''' % \
- module_list_in_header_file
-
- print >> output_header_file, '''// 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/public/resources/grit/blink_resources.h"
-#include "third_party/blink/renderer/core/script/layered_api_module.h"
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_LAYERED_API_RESOURCES_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_LAYERED_API_RESOURCES_H_
-
-// This file is generated by
-// core/script/generate_lapi_grdp.py and shouldn't modified manually.
-// A corresponding grdp file (layered_api_resources.grdp) is also generated.
-
-// This file should be included only once from core/script/layered_api.cc.
-
-namespace blink {
-
-namespace layered_api {
-
-namespace {
-
-struct LayeredAPIResource {
- const char* path;
- int resource_id;
- Module module;
-};
-
-const LayeredAPIResource kLayeredAPIResources[] = {
-%s};
-
-} // namespace
-
-} // namespace layered_api
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_LAYERED_API_RESOURCES_H_''' % \
- resource_list_in_header_file
-
- output_grdp_file.close()
- output_header_file.close()
- output_module_header_file.close()
-
-
-if __name__ == '__main__':
- main()
diff --git a/chromium/third_party/blink/renderer/core/script/import_map.cc b/chromium/third_party/blink/renderer/core/script/import_map.cc
index 0aed827a7c7..7149f83766b 100644
--- a/chromium/third_party/blink/renderer/core/script/import_map.cc
+++ b/chromium/third_party/blink/renderer/core/script/import_map.cc
@@ -8,7 +8,6 @@
#include <utility>
#include "third_party/blink/public/mojom/devtools/console_message.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
-#include "third_party/blink/renderer/core/script/layered_api.h"
#include "third_party/blink/renderer/core/script/modulator.h"
#include "third_party/blink/renderer/core/script/parsed_specifier.h"
#include "third_party/blink/renderer/platform/json/json_parser.h"
@@ -18,19 +17,6 @@
#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
-// We implement two variants of specs:
-// - When |support_builtin_modules| is false, import maps without built-in
-// module & fallback supports are implemented.
-// This follows the ToT spec https://wicg.github.io/import-maps/, which is
-// marked by <spec> tags.
-// - When |support_builtin_modules| is true, import maps with built-in module &
-// fallback supports are implemented.
-// This basically follows the spec before
-// https://github.com/WICG/import-maps/pull/176, which is marked as
-// [Spec w/ Built-in].
-// This is needed for the fallback mechanism for built-in modules, which was
-// temporarily removed from the spec but is still implemented behind the flag.
-
namespace blink {
namespace {
@@ -58,7 +44,6 @@ void AddIgnoredValueMessage(ConsoleLogger& logger,
// href="https://wicg.github.io/import-maps/#normalize-a-specifier-key">
String NormalizeSpecifierKey(const String& key_string,
const KURL& base_url,
- bool support_builtin_modules,
ConsoleLogger& logger) {
// <spec step="1">If specifierKey is the empty string, then:</spec>
if (key_string.IsEmpty()) {
@@ -73,8 +58,7 @@ String NormalizeSpecifierKey(const String& key_string,
// <spec step="2">Let url be the result of parsing a URL-like import
// specifier, given specifierKey and baseURL.</spec>
- ParsedSpecifier key =
- ParsedSpecifier::Create(key_string, base_url, support_builtin_modules);
+ ParsedSpecifier key = ParsedSpecifier::Create(key_string, base_url);
switch (key.GetType()) {
case ParsedSpecifier::Type::kInvalid:
@@ -95,12 +79,10 @@ String NormalizeSpecifierKey(const String& key_string,
KURL NormalizeValue(const String& key,
const String& value_string,
const KURL& base_url,
- bool support_builtin_modules,
ConsoleLogger& logger) {
// <spec step="2.4">Let addressURL be the result of parsing a URL-like import
// specifier given value and baseURL.</spec>
- ParsedSpecifier value =
- ParsedSpecifier::Create(value_string, base_url, support_builtin_modules);
+ ParsedSpecifier value = ParsedSpecifier::Create(value_string, base_url);
switch (value.GetType()) {
case ParsedSpecifier::Type::kInvalid:
@@ -109,7 +91,10 @@ KURL NormalizeValue(const String& key,
// <spec step="2.5.1">Report a warning to the console that the address was
// invalid.</spec>
AddIgnoredValueMessage(logger, key, "Invalid URL: " + value_string);
- // <spec step="2.5.2">Continue.</spec>
+
+ // <spec step="2.5.2">Set normalized[specifierKey] to null.</spec>
+ //
+ // <spec step="2.5.3">Continue.</spec>
return NullURL();
case ParsedSpecifier::Type::kBare:
@@ -128,10 +113,13 @@ KURL NormalizeValue(const String& key,
"Since specifierKey ended in a slash, so must the address: " +
value_string);
- // <spec step="2.6.2">Continue.</spec>
+ // <spec step="2.6.2">Set normalized[specifierKey] to null.</spec>
+ //
+ // <spec step="2.6.3">Continue.</spec>
return NullURL();
}
+ DCHECK(value.GetUrl().IsValid());
return value.GetUrl();
}
}
@@ -147,7 +135,6 @@ KURL NormalizeValue(const String& key,
ImportMap* ImportMap::Parse(const Modulator& modulator,
const String& input,
const KURL& base_url,
- bool support_builtin_modules,
ConsoleLogger& logger,
ScriptValue* error_to_rethrow) {
DCHECK(error_to_rethrow);
@@ -190,8 +177,8 @@ ImportMap* ImportMap::Parse(const Modulator& modulator,
// <spec step="4.2">Set sortedAndNormalizedImports to the result of sorting
// and normalizing a specifier map given parsed["imports"] and
// baseURL.</spec>
- sorted_and_normalized_imports = SortAndNormalizeSpecifierMap(
- imports, base_url, support_builtin_modules, logger);
+ sorted_and_normalized_imports =
+ SortAndNormalizeSpecifierMap(imports, base_url, logger);
}
// <spec step="5">Let sortedAndNormalizedScopes be an empty map.</spec>
@@ -256,21 +243,20 @@ ImportMap* ImportMap::Parse(const Modulator& modulator,
continue;
}
- // <spec label="sort-and-normalize-scopes" step="2.5">Let
+ // <spec label="sort-and-normalize-scopes" step="2.4">Let
// normalizedScopePrefix be the serialization of scopePrefixURL.</spec>
//
- // <spec label="sort-and-normalize-scopes" step="2.6">Set
+ // <spec label="sort-and-normalize-scopes" step="2.5">Set
// normalized[normalizedScopePrefix] to the result of sorting and
// normalizing a specifier map given potentialSpecifierMap and
// baseURL.</spec>
sorted_and_normalized_scopes.push_back(std::make_pair(
prefix_url.GetString(),
- SortAndNormalizeSpecifierMap(specifier_map, base_url,
- support_builtin_modules, logger)));
+ SortAndNormalizeSpecifierMap(specifier_map, base_url, logger)));
}
// <spec label="sort-and-normalize-scopes" step="3">Return the result of
- // sorting normalized, with an entry a being less than an entry b if a’s key
- // is longer or code unit less than b’s key.</spec>
+ // sorting normalized, with an entry a being less than an entry b if b’s key
+ // is code unit less than a’s key.</spec>
std::sort(sorted_and_normalized_scopes.begin(),
sorted_and_normalized_scopes.end(),
[](const ScopeEntryType& a, const ScopeEntryType& b) {
@@ -284,7 +270,6 @@ ImportMap* ImportMap::Parse(const Modulator& modulator,
// sortedAndNormalizedImports and whose scopes scopes are
// sortedAndNormalizedScopes.</spec>
return MakeGarbageCollected<ImportMap>(
- modulator, support_builtin_modules,
std::move(sorted_and_normalized_imports),
std::move(sorted_and_normalized_scopes));
}
@@ -294,7 +279,6 @@ ImportMap* ImportMap::Parse(const Modulator& modulator,
ImportMap::SpecifierMap ImportMap::SortAndNormalizeSpecifierMap(
const JSONObject* imports,
const KURL& base_url,
- bool support_builtin_modules,
ConsoleLogger& logger) {
// <spec step="1">Let normalized be an empty map.</spec>
SpecifierMap normalized;
@@ -305,131 +289,49 @@ ImportMap::SpecifierMap ImportMap::SortAndNormalizeSpecifierMap(
// <spec step="2.1">Let normalizedSpecifierKey be the result of normalizing
// a specifier key given specifierKey and baseURL.</spec>
- const String normalized_specifier_key = NormalizeSpecifierKey(
- entry.first, base_url, support_builtin_modules, logger);
+ const String normalized_specifier_key =
+ NormalizeSpecifierKey(entry.first, base_url, logger);
// <spec step="2.2">If normalizedSpecifierKey is null, then continue.</spec>
if (normalized_specifier_key.IsEmpty())
continue;
- Vector<KURL> values;
switch (entry.second->GetType()) {
- case JSONValue::ValueType::kTypeNull:
- if (!support_builtin_modules) {
- // <spec step="2.3">If value is not a string, then:</spec>
- //
- // <spec step="2.3.1">Report a warning to the console that addresses
- // must be strings.</spec>
- AddIgnoredValueMessage(logger, entry.first, "Invalid value type.");
-
- // <spec step="2.3.2">Continue.</spec>
- continue;
- }
- // [Spec w/ Built-in] Otherwise, if value is null, then set
- // normalized[normalizedSpecifierKey] to a new empty list.
- break;
-
- case JSONValue::ValueType::kTypeBoolean:
- case JSONValue::ValueType::kTypeInteger:
- case JSONValue::ValueType::kTypeDouble:
- case JSONValue::ValueType::kTypeObject:
- // <spec step="2.3">If value is not a string, then:</spec>
- //
- // <spec step="2.3.1">Report a warning to the console that addresses
- // must be strings.</spec>
- AddIgnoredValueMessage(logger, entry.first, "Invalid value type.");
-
- // <spec step="2.3.2">Continue.</spec>
- //
- // By continuing here, we leave |normalized[normalized_specifier_key]|
- // unset, and continue processing.
- continue;
-
case JSONValue::ValueType::kTypeString: {
// Steps 2.4-2.6 are implemented in NormalizeValue().
String value_string;
if (!imports->GetString(entry.first, &value_string)) {
AddIgnoredValueMessage(logger, entry.first,
"Internal error in GetString().");
+ normalized.Set(normalized_specifier_key, NullURL());
break;
}
- KURL value = NormalizeValue(entry.first, value_string, base_url,
- support_builtin_modules, logger);
- // <spec step="2.7">Set normalized[specifierKey] to addressURL.</spec>
- if (value.IsValid())
- values.push_back(value);
+ normalized.Set(
+ normalized_specifier_key,
+ NormalizeValue(entry.first, value_string, base_url, logger));
break;
}
- case JSONValue::ValueType::kTypeArray: {
- if (!support_builtin_modules) {
- // <spec step="2.3">If value is not a string, then:</spec>
- //
- // <spec step="2.3.1">Report a warning to the console that addresses
- // must be strings.</spec>
- AddIgnoredValueMessage(logger, entry.first, "Invalid value type.");
-
- // <spec step="2.3.2">Continue.</spec>
- continue;
- }
+ case JSONValue::ValueType::kTypeNull:
+ case JSONValue::ValueType::kTypeBoolean:
+ case JSONValue::ValueType::kTypeInteger:
+ case JSONValue::ValueType::kTypeDouble:
+ case JSONValue::ValueType::kTypeObject:
+ case JSONValue::ValueType::kTypeArray:
+ // <spec step="2.3">If value is not a string, then:</spec>
+ //
+ // <spec step="2.3.1">Report a warning to the console that addresses
+ // must be strings.</spec>
+ AddIgnoredValueMessage(logger, entry.first, "Invalid value type.");
- // [Spec w/ Built-in] Otherwise, if value is a list, then set
- // normalized[normalizedSpecifierKey] to value.
- JSONArray* array = imports->GetArray(entry.first);
- if (!array) {
- AddIgnoredValueMessage(logger, entry.first,
- "Internal error in GetArray().");
- break;
- }
+ // <spec step="2.3.2">Set normalized[specifierKey] to null.</spec>
+ normalized.Set(normalized_specifier_key, NullURL());
- // <spec step="2">For each specifierKey → value of ...</spec>
- for (wtf_size_t j = 0; j < array->size(); ++j) {
- // <spec step="2.3">If value is not a string, then:</spec>
- String value_string;
- if (!array->at(j)->AsString(&value_string)) {
- // <spec step="2.3.1">Report a warning to the console that addresses
- // must be strings.</spec>
- AddIgnoredValueMessage(logger, entry.first,
- "Non-string in the value.");
- // <spec step="2.3.2">Continue.</spec>
- continue;
- }
- KURL value = NormalizeValue(entry.first, value_string, base_url,
- support_builtin_modules, logger);
-
- if (value.IsValid())
- values.push_back(value);
- }
+ // <spec step="2.3.3">Continue.</spec>
break;
- }
}
- if (!support_builtin_modules) {
- DCHECK_LE(values.size(), 1u);
- }
-
- // TODO(hiroshige): Move these checks to resolution time.
- if (values.size() > 2) {
- AddIgnoredValueMessage(logger, entry.first,
- "An array of length > 2 is not yet supported.");
- values.clear();
- }
- if (values.size() == 2) {
- if (layered_api::GetBuiltinPath(values[0]).IsNull()) {
- AddIgnoredValueMessage(
- logger, entry.first,
- "Fallback from a non-builtin URL is not yet supported.");
- values.clear();
- } else if (normalized_specifier_key != values[1]) {
- AddIgnoredValueMessage(logger, entry.first,
- "Fallback URL should match the original URL.");
- values.clear();
- }
- }
-
- // <spec step="2.7">Set normalized[specifierKey] to addressURL.</spec>
- normalized.Set(normalized_specifier_key, values);
}
return normalized;
@@ -439,10 +341,6 @@ ImportMap::SpecifierMap ImportMap::SortAndNormalizeSpecifierMap(
base::Optional<ImportMap::MatchResult> ImportMap::MatchPrefix(
const ParsedSpecifier& parsed_specifier,
const SpecifierMap& specifier_map) const {
- // Do not perform prefix match for non-bare specifiers.
- if (parsed_specifier.GetType() != ParsedSpecifier::Type::kBare)
- return base::nullopt;
-
const String key = parsed_specifier.GetImportMapKeyString();
// Prefix match, i.e. "Packages" via trailing slashes.
@@ -457,7 +355,8 @@ base::Optional<ImportMap::MatchResult> ImportMap::MatchPrefix(
// https://github.com/WICG/import-maps/issues/102
base::Optional<MatchResult> best_match;
- // <spec step="1">For each specifierKey → address of specifierMap,</spec>
+ // <spec step="1">For each specifierKey → resolutionResult of
+ // specifierMap,</spec>
for (auto it = specifier_map.begin(); it != specifier_map.end(); ++it) {
// <spec step="1.2">If specifierKey ends with U+002F (/) and
// normalizedSpecifier starts with specifierKey, then:</spec>
@@ -478,18 +377,10 @@ base::Optional<ImportMap::MatchResult> ImportMap::MatchPrefix(
return best_match;
}
-ImportMap::ImportMap()
- : support_builtin_modules_(false),
- modulator_for_built_in_modules_(nullptr) {}
+ImportMap::ImportMap() = default;
-ImportMap::ImportMap(const Modulator& modulator_for_built_in_modules,
- bool support_builtin_modules,
- SpecifierMap&& imports,
- ScopeType&& scopes)
- : imports_(std::move(imports)),
- scopes_(std::move(scopes)),
- support_builtin_modules_(support_builtin_modules),
- modulator_for_built_in_modules_(&modulator_for_built_in_modules) {}
+ImportMap::ImportMap(SpecifierMap&& imports, ScopeType&& scopes)
+ : imports_(std::move(imports)), scopes_(std::move(scopes)) {}
// <specdef
// href="https://wicg.github.io/import-maps/#resolve-a-module-specifier">
@@ -534,7 +425,7 @@ base::Optional<KURL> ImportMap::ResolveImportsMatch(
DCHECK(debug_message);
const String key = parsed_specifier.GetImportMapKeyString();
- // <spec step="1.1">If specifierKey is normalizedSpecifier, then ...</spec>
+ // <spec step="1.1">If specifierKey is normalizedSpecifier, then:</spec>
MatchResult exact = specifier_map.find(key);
if (exact != specifier_map.end()) {
return ResolveImportsMatchInternal(key, exact, debug_message);
@@ -552,52 +443,53 @@ base::Optional<KURL> ImportMap::ResolveImportsMatch(
}
// <specdef href="https://wicg.github.io/import-maps/#resolve-an-imports-match">
-base::Optional<KURL> ImportMap::ResolveImportsMatchInternal(
- const String& key,
- const MatchResult& matched,
- String* debug_message) const {
- // <spec step="1.2.1">Let afterPrefix be the portion of normalizedSpecifier
+KURL ImportMap::ResolveImportsMatchInternal(const String& key,
+ const MatchResult& matched,
+ String* debug_message) const {
+ // <spec step="1.2.3">Let afterPrefix be the portion of normalizedSpecifier
// after the initial specifierKey prefix.</spec>
const String after_prefix = key.Substring(matched->key.length());
- for (const KURL& value : matched->value) {
- // <spec step="1.1">If specifierKey is normalizedSpecifier, then return
- // address.</spec>
- //
- // <spec step="1.2">If specifierKey ends with U+002F (/) and
- // normalizedSpecifier starts with specifierKey, then:</spec>
- //
- // <spec step="1.2.3">Let url be the result of parsing afterPrefix relative
- // to the base URL address.</spec>
- const KURL url = after_prefix.IsEmpty() ? value : KURL(value, after_prefix);
-
- // [Spec w/ Built-in] Return url0, if moduleMap[url0] exists; otherwise,
- // return url1.
- //
- // Note: Here we filter out non-existing built-in modules in all cases.
- if (!support_builtin_modules_ ||
- layered_api::ResolveFetchingURL(*modulator_for_built_in_modules_, url)
- .IsValid()) {
- *debug_message = "Import Map: \"" + key + "\" matches with \"" +
- matched->key + "\" and is mapped to " +
- url.ElidedString();
-
- // <spec step="1.2.4">If url is failure, then return null.</spec>
- //
- // <spec step="1.2.5">Return url.</spec>
- return url;
- }
+ // <spec step="1.1.1">If resolutionResult is null, then throw a TypeError
+ // indicating that resolution of specifierKey was blocked by a null
+ // entry.</spec>
+ //
+ // <spec step="1.2.1">If resolutionResult is null, then throw a TypeError
+ // indicating that resolution of specifierKey was blocked by a null
+ // entry.</spec>
+ if (!matched->value.IsValid()) {
+ *debug_message = "Import Map: \"" + key + "\" matches with \"" +
+ matched->key + "\" but is blocked by a null value";
+ return NullURL();
}
- // [Spec w/ Built-in] If addresses’s size is 0, then throw a TypeError
- // indicating that normalizedSpecifier was mapped to no addresses.
+ // <spec step="1.1">If specifierKey is normalizedSpecifier, then:</spec>
+ //
+ // <spec step="1.2">If specifierKey ends with U+002F (/) and
+ // normalizedSpecifier starts with specifierKey, then:</spec>
+ //
+ // <spec step="1.2.5">Let url be the result of parsing afterPrefix relative
+ // to the base URL resolutionResult.</spec>
+ const KURL url = after_prefix.IsEmpty() ? matched->value
+ : KURL(matched->value, after_prefix);
+
+ // <spec step="1.2.6">If url is failure, then throw a TypeError indicating
+ // that resolution of specifierKey was blocked due to a URL parse
+ // failure.</spec>
+ if (!url.IsValid()) {
+ *debug_message = "Import Map: \"" + key + "\" matches with \"" +
+ matched->key +
+ "\" but is blocked due to relative URL parse failure";
+ return NullURL();
+ }
+
+ // <spec step="1.2.8">Return url.</spec>
*debug_message = "Import Map: \"" + key + "\" matches with \"" +
- matched->key + "\" but fails to be mapped (no viable URLs)";
- return NullURL();
+ matched->key + "\" and is mapped to " + url.ElidedString();
+ return url;
}
static void SpecifierMapToString(StringBuilder& builder,
- bool support_builtin_modules,
const ImportMap::SpecifierMap& specifier_map) {
builder.Append("{");
bool is_first_key = true;
@@ -607,24 +499,10 @@ static void SpecifierMapToString(StringBuilder& builder,
is_first_key = false;
builder.Append(it.key.EncodeForDebugging());
builder.Append(":");
- if (support_builtin_modules) {
- builder.Append("[");
- bool is_first_value = true;
- for (const auto& v : it.value) {
- if (!is_first_value)
- builder.Append(",");
- is_first_value = false;
- builder.Append(v.GetString().EncodeForDebugging());
- }
- builder.Append("]");
- } else {
- if (it.value.size() == 0) {
- builder.Append("[]");
- } else {
- DCHECK_EQ(it.value.size(), 1u);
- builder.Append(it.value[0].GetString().EncodeForDebugging());
- }
- }
+ if (it.value.IsValid())
+ builder.Append(it.value.GetString().EncodeForDebugging());
+ else
+ builder.Append("null");
}
builder.Append("}");
}
@@ -632,7 +510,7 @@ static void SpecifierMapToString(StringBuilder& builder,
String ImportMap::ToString() const {
StringBuilder builder;
builder.Append("{\"imports\":");
- SpecifierMapToString(builder, support_builtin_modules_, imports_);
+ SpecifierMapToString(builder, imports_);
builder.Append(",\"scopes\":{");
@@ -643,7 +521,7 @@ String ImportMap::ToString() const {
is_first_scope = false;
builder.Append(entry.first.EncodeForDebugging());
builder.Append(":");
- SpecifierMapToString(builder, support_builtin_modules_, entry.second);
+ SpecifierMapToString(builder, entry.second);
}
builder.Append("}");
@@ -653,8 +531,4 @@ String ImportMap::ToString() const {
return builder.ToString();
}
-void ImportMap::Trace(Visitor* visitor) {
- visitor->Trace(modulator_for_built_in_modules_);
-}
-
} // namespace blink
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 cc38cf9c3e5..7236bd5f710 100644
--- a/chromium/third_party/blink/renderer/core/script/import_map.h
+++ b/chromium/third_party/blink/renderer/core/script/import_map.h
@@ -28,16 +28,17 @@ class CORE_EXPORT ImportMap final : public GarbageCollected<ImportMap> {
static ImportMap* Parse(const Modulator&,
const String& text,
const KURL& base_url,
- bool support_builtin_modules,
ConsoleLogger& logger,
ScriptValue* error_to_rethrow);
// <spec href="https://wicg.github.io/import-maps/#specifier-map">A specifier
- // map is an ordered map from strings to lists of URLs.</spec>
+ // map is an ordered map from strings to resolution results.</spec>
+ //
+ // An invalid KURL corresponds to a null resolution result in the spec.
//
// In Blink, we actually use an unordered map here, and related algorithms
// are implemented differently from the spec.
- using SpecifierMap = HashMap<String, Vector<KURL>>;
+ using SpecifierMap = HashMap<String, KURL>;
// <spec href="https://wicg.github.io/import-maps/#import-map-scopes">an
// ordered map of URLs to specifier maps.</spec>
@@ -47,26 +48,26 @@ class CORE_EXPORT ImportMap final : public GarbageCollected<ImportMap> {
// Empty import map.
ImportMap();
- ImportMap(const Modulator&,
- bool support_builtin_modules,
- SpecifierMap&& imports,
- ScopeType&& scopes);
+ ImportMap(SpecifierMap&& imports, ScopeType&& scopes);
+ // Return values of Resolve(), ResolveImportsMatch() and
+ // ResolveImportsMatchInternal():
+ // - base::nullopt: corresponds to returning a null in the spec,
+ // i.e. allowing fallback to a less specific scope etc.
+ // - An invalid KURL: corresponds to throwing an error in the spec.
+ // - A valid KURL: corresponds to returning a valid URL in the spec.
base::Optional<KURL> Resolve(const ParsedSpecifier&,
const KURL& base_url,
String* debug_message) const;
String ToString() const;
- void Trace(Visitor*);
+ void Trace(Visitor*) {}
private:
using MatchResult = SpecifierMap::const_iterator;
// https://wicg.github.io/import-maps/#resolve-an-imports-match
- // Returns nullopt when not mapped by |this| import map (i.e. the import map
- // doesn't have corresponding keys).
- // Returns a null URL when resolution fails.
base::Optional<KURL> ResolveImportsMatch(const ParsedSpecifier&,
const SpecifierMap&,
String* debug_message) const;
@@ -74,23 +75,17 @@ class CORE_EXPORT ImportMap final : public GarbageCollected<ImportMap> {
const SpecifierMap&) const;
static SpecifierMap SortAndNormalizeSpecifierMap(const JSONObject* imports,
const KURL& base_url,
- bool support_builtin_modules,
ConsoleLogger&);
- base::Optional<KURL> ResolveImportsMatchInternal(
- const String& normalizedSpecifier,
- const MatchResult&,
- String* debug_message) const;
+ KURL ResolveImportsMatchInternal(const String& normalizedSpecifier,
+ const MatchResult&,
+ String* debug_message) const;
// https://wicg.github.io/import-maps/#import-map-imports
SpecifierMap imports_;
// https://wicg.github.io/import-maps/#import-map-scopes.
ScopeType scopes_;
-
- const bool support_builtin_modules_;
-
- Member<const Modulator> modulator_for_built_in_modules_;
};
} // namespace blink
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 adc2b408d2e..d35598276cd 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
@@ -80,7 +80,8 @@ class CORE_EXPORT JSModuleScript final : public ModuleScript,
const TextPosition start_position_;
- // Only for ProduceCache(). JSModuleScript keeps |produce_cache_data| because:
+ // Only for ProduceCache(). JSModuleScript keeps |produce_cache_data_|
+ // because:
// - CompileModule() and ProduceCache() should be called at different
// timings, and
// - There are no persistent object that can hold this in
diff --git a/chromium/third_party/blink/renderer/core/script/layered_api.cc b/chromium/third_party/blink/renderer/core/script/layered_api.cc
deleted file mode 100644
index 6e999dd7008..00000000000
--- a/chromium/third_party/blink/renderer/core/script/layered_api.cc
+++ /dev/null
@@ -1,113 +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/core/script/layered_api.h"
-
-#include "base/stl_util.h"
-#include "third_party/blink/renderer/core/script/layered_api_resources.h"
-#include "third_party/blink/renderer/core/script/modulator.h"
-#include "third_party/blink/renderer/platform/data_resource_helper.h"
-#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
-
-namespace blink {
-
-namespace layered_api {
-
-namespace {
-
-static const char kStdScheme[] = "std";
-static const char kInternalScheme[] = "std-internal";
-
-constexpr char kTopLevelScriptPostfix[] = "/index.mjs";
-
-const LayeredAPIResource* GetResourceFromPath(const Modulator& modulator,
- const String& path) {
- for (size_t i = 0; i < base::size(kLayeredAPIResources); ++i) {
- if (modulator.BuiltInModuleEnabled(kLayeredAPIResources[i].module) &&
- path == kLayeredAPIResources[i].path) {
- return &kLayeredAPIResources[i];
- }
- }
- return nullptr;
-}
-
-bool IsImplemented(const Modulator& modulator, const String& name) {
- return GetResourceFromPath(modulator, name + kTopLevelScriptPostfix);
-}
-
-} // namespace
-
-String GetBuiltinPath(const KURL& url) {
- if (url.ProtocolIs(kStdScheme))
- return url.GetPath();
-
- return String();
-}
-
-// https://github.com/drufball/layered-apis/blob/master/spec.md#user-content-layered-api-fetching-url
-KURL ResolveFetchingURL(const Modulator& modulator, const KURL& url) {
- // <spec step="1">If url's scheme is not "std", return url.</spec>
- // <spec step="2">Let path be url's path[0].</spec>
- String path = GetBuiltinPath(url);
- if (path.IsNull())
- return url;
-
- // <spec step="5">If the layered API identified by path is implemented by this
- // user agent, return the result of parsing the concatenation of "std:" with
- // identifier.</spec>
- if (IsImplemented(modulator, path)) {
- StringBuilder url_string;
- url_string.Append(kStdScheme);
- url_string.Append(":");
- url_string.Append(path);
- return KURL(NullURL(), url_string.ToString());
- }
-
- return NullURL();
-}
-
-KURL GetInternalURL(const KURL& url) {
- String path = GetBuiltinPath(url);
- if (!path.IsNull()) {
- StringBuilder url_string;
- url_string.Append(kInternalScheme);
- url_string.Append("://");
- url_string.Append(path);
- url_string.Append(kTopLevelScriptPostfix);
- return KURL(NullURL(), url_string.ToString());
- }
-
- if (url.ProtocolIs(kInternalScheme)) {
- return url;
- }
-
- return NullURL();
-}
-
-String GetSourceText(const Modulator& modulator, const KURL& url) {
- if (!url.ProtocolIs(kInternalScheme))
- return String();
-
- String path = url.GetPath();
- // According to the URL spec, the host/path of "std-internal://foo/bar"
- // is "foo" and "/bar", respectively, but in Blink they are "" and
- // "//foo/bar". This is a workaround to get "foo/bar" here.
- if (path.StartsWith("//")) {
- path = path.Substring(2);
- }
-
- const LayeredAPIResource* resource = GetResourceFromPath(modulator, path);
- if (!resource)
- return String();
-
- // Only count the use of top-level scripts of each built-in module.
- if (path.EndsWith(kTopLevelScriptPostfix))
- modulator.BuiltInModuleUseCount(resource->module);
-
- return UncompressResourceAsString(resource->resource_id);
-}
-
-} // namespace layered_api
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/script/layered_api.h b/chromium/third_party/blink/renderer/core/script/layered_api.h
deleted file mode 100644
index 01f5416c47d..00000000000
--- a/chromium/third_party/blink/renderer/core/script/layered_api.h
+++ /dev/null
@@ -1,57 +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_SCRIPT_LAYERED_API_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_LAYERED_API_H_
-
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/platform/weborigin/kurl.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-
-class Modulator;
-
-// Implements Layered API.
-// Spec: https://github.com/drufball/layered-apis/blob/master/spec.md
-// Implementation Design Doc:
-// https://docs.google.com/document/d/1V-WaCZQbBcQJRSYSYBb8Y6p0DOdDpiNDSmD41ui_73s/edit
-
-// Some methods takes Modulator as an argument, to support origin trials
-// (which depends on ExecutionContext).
-// TODO(hiroshige): Using Modulator here means Layered API fetching and
-// import maps fallback depends on module map settings object. Currently
-// this is consistent throughout Blink implementation, but this might cause
-// problems when we support built-in modules around workers
-// (https://crbug.com/927477), and we might switch to fetch client settings
-// object in the future (https://crbug.com/928435).
-namespace layered_api {
-
-// Returns the path part (`x`) for std:x or import:@std/x URLs.
-// For other URLs, returns a null String.
-//
-// Currently accepts both "std:x" and "import:@std/x", but
-// because the spec discussion about notation is ongoing:
-// https://github.com/tc39/proposal-javascript-standard-library/issues/12
-// TODO(hiroshige): Update the implementation once the discussion converges.
-CORE_EXPORT String GetBuiltinPath(const KURL&);
-
-// https://github.com/drufball/layered-apis/blob/master/spec.md#user-content-layered-api-fetching-url
-//
-// Currently fallback syntax is disabled and only "std:x" (not "std:x|y") is
-// accepted. https://crbug.com/864748
-CORE_EXPORT KURL ResolveFetchingURL(const Modulator&, const KURL&);
-
-// Returns std-internal://x/index.mjs if the URL is Layered API, or null URL
-// otherwise (not specced).
-CORE_EXPORT KURL GetInternalURL(const KURL&);
-
-// Gets source text for std-internal://x/index.mjs.
-CORE_EXPORT String GetSourceText(const Modulator&, const KURL&);
-
-} // namespace layered_api
-
-} // namespace blink
-
-#endif
diff --git a/chromium/third_party/blink/renderer/core/script/layered_api_module.h b/chromium/third_party/blink/renderer/core/script/layered_api_module.h
deleted file mode 100644
index 7dd7d687dab..00000000000
--- a/chromium/third_party/blink/renderer/core/script/layered_api_module.h
+++ /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.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_LAYERED_API_MODULE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_LAYERED_API_MODULE_H_
-
-// This file is generated by
-// core/script/generate_lapi_grdp.py and shouldn't modified manually.
-// A corresponding grdp file (layered_api_resources.grdp) is also generated.
-
-namespace blink {
-
-namespace layered_api {
-
-enum class Module {
- kBlank,
- kElementsInternal,
- kElementsSwitch,
- kElementsToast,
- kElementsVirtualScroller,
- kKvStorage,
-};
-
-} // namespace layered_api
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_LAYERED_API_MODULE_H_
diff --git a/chromium/third_party/blink/renderer/core/script/layered_api_resources.h b/chromium/third_party/blink/renderer/core/script/layered_api_resources.h
deleted file mode 100644
index 98be4b31e1a..00000000000
--- a/chromium/third_party/blink/renderer/core/script/layered_api_resources.h
+++ /dev/null
@@ -1,76 +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/public/resources/grit/blink_resources.h"
-#include "third_party/blink/renderer/core/script/layered_api_module.h"
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_LAYERED_API_RESOURCES_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_LAYERED_API_RESOURCES_H_
-
-// This file is generated by
-// core/script/generate_lapi_grdp.py and shouldn't modified manually.
-// A corresponding grdp file (layered_api_resources.grdp) is also generated.
-
-// This file should be included only once from core/script/layered_api.cc.
-
-namespace blink {
-
-namespace layered_api {
-
-namespace {
-
-struct LayeredAPIResource {
- const char* path;
- int resource_id;
- Module module;
-};
-
-const LayeredAPIResource kLayeredAPIResources[] = {
- {"blank/index.mjs", IDR_LAYERED_API_BLANK_INDEX_MJS, Module::kBlank},
-
- {"elements/internal/reflection.mjs",
- IDR_LAYERED_API_ELEMENTS_INTERNAL_REFLECTION_MJS,
- Module::kElementsInternal},
-
- {"elements/switch/face_utils.mjs",
- IDR_LAYERED_API_ELEMENTS_SWITCH_FACE_UTILS_MJS, Module::kElementsSwitch},
- {"elements/switch/index.mjs", IDR_LAYERED_API_ELEMENTS_SWITCH_INDEX_MJS,
- Module::kElementsSwitch},
- {"elements/switch/style.mjs", IDR_LAYERED_API_ELEMENTS_SWITCH_STYLE_MJS,
- Module::kElementsSwitch},
- {"elements/switch/track.mjs", IDR_LAYERED_API_ELEMENTS_SWITCH_TRACK_MJS,
- Module::kElementsSwitch},
-
- {"elements/toast/index.mjs", IDR_LAYERED_API_ELEMENTS_TOAST_INDEX_MJS,
- Module::kElementsToast},
-
- {"elements/virtual-scroller/find-element.mjs",
- IDR_LAYERED_API_ELEMENTS_VIRTUAL_SCROLLER_FIND_ELEMENT_MJS,
- Module::kElementsVirtualScroller},
- {"elements/virtual-scroller/index.mjs",
- IDR_LAYERED_API_ELEMENTS_VIRTUAL_SCROLLER_INDEX_MJS,
- Module::kElementsVirtualScroller},
- {"elements/virtual-scroller/sets.mjs",
- IDR_LAYERED_API_ELEMENTS_VIRTUAL_SCROLLER_SETS_MJS,
- Module::kElementsVirtualScroller},
- {"elements/virtual-scroller/visibility-manager.mjs",
- IDR_LAYERED_API_ELEMENTS_VIRTUAL_SCROLLER_VISIBILITY_MANAGER_MJS,
- Module::kElementsVirtualScroller},
-
- {"kv-storage/async_iterator.mjs",
- IDR_LAYERED_API_KV_STORAGE_ASYNC_ITERATOR_MJS, Module::kKvStorage},
- {"kv-storage/idb_utils.mjs", IDR_LAYERED_API_KV_STORAGE_IDB_UTILS_MJS,
- Module::kKvStorage},
- {"kv-storage/index.mjs", IDR_LAYERED_API_KV_STORAGE_INDEX_MJS,
- Module::kKvStorage},
-
-};
-
-} // namespace
-
-} // namespace layered_api
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_LAYERED_API_RESOURCES_H_
diff --git a/chromium/third_party/blink/renderer/core/script/layered_api_test.cc b/chromium/third_party/blink/renderer/core/script/layered_api_test.cc
deleted file mode 100644
index f318f7fc807..00000000000
--- a/chromium/third_party/blink/renderer/core/script/layered_api_test.cc
+++ /dev/null
@@ -1,93 +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/core/script/layered_api.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/core/testing/dummy_modulator.h"
-
-namespace blink {
-
-namespace layered_api {
-
-namespace {
-
-class LayeredAPITestModulator final : public DummyModulator {
- public:
- bool BuiltInModuleInfraEnabled() const override { return true; }
- bool BuiltInModuleEnabled(layered_api::Module) const override { return true; }
-};
-
-class LayeredAPITest : public testing::Test {
- public:
- LayeredAPITest()
- : modulator_(MakeGarbageCollected<LayeredAPITestModulator>()) {}
- const Modulator& GetModulator() const { return *modulator_; }
-
- private:
- Persistent<LayeredAPITestModulator> modulator_;
-};
-
-TEST_F(LayeredAPITest, ResolveFetchingURL) {
- KURL base_url("https://example.com/base/path/");
-
- EXPECT_EQ(ResolveFetchingURL(GetModulator(), KURL("https://example.com/")),
- KURL("https://example.com/"));
-
- EXPECT_EQ(ResolveFetchingURL(GetModulator(), KURL("std:blank")),
- KURL("std:blank"));
-
- EXPECT_EQ(ResolveFetchingURL(GetModulator(), KURL("std:none")), NullURL());
-
- // Fallback syntax is currently disabled and rejected.
- // https://crbug.com/864748
- EXPECT_EQ(ResolveFetchingURL(GetModulator(),
- KURL("std:blank|https://example.com/")),
- NullURL());
-}
-
-TEST_F(LayeredAPITest, GetInternalURL) {
- EXPECT_EQ(GetInternalURL(KURL("https://example.com/")), NullURL());
-
- EXPECT_EQ(GetInternalURL(KURL("std:blank")),
- KURL("std-internal://blank/index.mjs"));
-
- EXPECT_EQ(GetInternalURL(KURL("std-internal://blank/index.mjs")),
- KURL("std-internal://blank/index.mjs"));
- EXPECT_EQ(GetInternalURL(KURL("std-internal://blank/foo/bar.mjs")),
- KURL("std-internal://blank/foo/bar.mjs"));
-}
-
-TEST_F(LayeredAPITest, InternalURLRelativeResolution) {
- EXPECT_EQ(KURL(KURL("std-internal://blank/index.mjs"), "./sub.mjs"),
- KURL("std-internal://blank/sub.mjs"));
- EXPECT_EQ(KURL(KURL("std-internal://blank/index.mjs"), "/sub.mjs"),
- KURL("std-internal://blank/sub.mjs"));
- EXPECT_EQ(KURL(KURL("std-internal://blank/index.mjs"), "./foo/bar.mjs"),
- KURL("std-internal://blank/foo/bar.mjs"));
- EXPECT_EQ(KURL(KURL("std-internal://blank/foo/bar.mjs"), "../baz.mjs"),
- KURL("std-internal://blank/baz.mjs"));
-}
-
-TEST_F(LayeredAPITest, GetSourceText) {
- EXPECT_EQ(
- GetSourceText(GetModulator(), KURL("std-internal://blank/index.mjs")),
- String(""));
-
- EXPECT_EQ(
- GetSourceText(GetModulator(), KURL("std-internal://blank/not-found.mjs")),
- String());
- EXPECT_EQ(
- GetSourceText(GetModulator(), KURL("std-internal://none/index.mjs")),
- String());
-
- EXPECT_EQ(GetSourceText(GetModulator(), KURL("https://example.com/")),
- String());
-}
-
-} // namespace
-
-} // namespace layered_api
-
-} // namespace blink
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 0bd11bbb020..92513c146a2 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
@@ -37,8 +37,8 @@ class MockScriptElementBase : public GarbageCollected<MockScriptElementBase>,
MOCK_CONST_METHOD0(NomoduleAttributeValue, bool());
MOCK_CONST_METHOD0(SourceAttributeValue, String());
MOCK_CONST_METHOD0(TypeAttributeValue, String());
-
- MOCK_METHOD0(TextFromChildren, String());
+ MOCK_METHOD0(ChildTextContent, String());
+ MOCK_CONST_METHOD0(ScriptTextInternalSlot, String());
MOCK_CONST_METHOD0(HasSourceAttribute, bool());
MOCK_CONST_METHOD0(IsConnected, bool());
MOCK_CONST_METHOD0(HasChildren, bool());
@@ -54,6 +54,9 @@ class MockScriptElementBase : public GarbageCollected<MockScriptElementBase>,
void(HTMLScriptElementOrSVGScriptElement&));
MOCK_CONST_METHOD0(Loader, ScriptLoader*());
+ ScriptElementBase::Type GetScriptElementType() override {
+ return ScriptElementBase::Type::kHTMLScriptElement;
+ }
void Trace(Visitor* visitor) override { ScriptElementBase::Trace(visitor); }
};
diff --git a/chromium/third_party/blink/renderer/core/script/modulator.cc b/chromium/third_party/blink/renderer/core/script/modulator.cc
index 84fc9a6b34e..2f48e3a2cef 100644
--- a/chromium/third_party/blink/renderer/core/script/modulator.cc
+++ b/chromium/third_party/blink/renderer/core/script/modulator.cc
@@ -35,7 +35,7 @@ Modulator* Modulator::From(ScriptState* script_state) {
if (modulator)
return modulator;
ExecutionContext* execution_context = ExecutionContext::From(script_state);
- if (auto* document = DynamicTo<Document>(execution_context)) {
+ if (auto* document = Document::DynamicFrom(execution_context)) {
modulator = MakeGarbageCollected<DocumentModulatorImpl>(script_state);
Modulator::SetModulator(script_state, modulator);
diff --git a/chromium/third_party/blink/renderer/core/script/modulator.h b/chromium/third_party/blink/renderer/core/script/modulator.h
index 39b6255073c..25985a349da 100644
--- a/chromium/third_party/blink/renderer/core/script/modulator.h
+++ b/chromium/third_party/blink/renderer/core/script/modulator.h
@@ -12,7 +12,6 @@
#include "third_party/blink/renderer/bindings/core/v8/sanitize_script_errors.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_code_cache.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/script/layered_api_module.h"
#include "third_party/blink/renderer/core/script/module_import_meta.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -28,6 +27,7 @@ namespace blink {
class ModuleScript;
class ModuleScriptFetchRequest;
class ModuleScriptFetcher;
+class ModuleScriptLoader;
class ImportMap;
class ReferrerScriptInfo;
class ResourceFetcher;
@@ -121,9 +121,6 @@ class CORE_EXPORT Modulator : public GarbageCollected<Modulator>,
virtual bool IsScriptingDisabled() const = 0;
virtual bool ImportMapsEnabled() const = 0;
- virtual bool BuiltInModuleInfraEnabled() const = 0;
- virtual bool BuiltInModuleEnabled(layered_api::Module) const = 0;
- virtual void BuiltInModuleUseCount(layered_api::Module) const = 0;
// https://html.spec.whatwg.org/C/#fetch-a-module-script-tree
// https://html.spec.whatwg.org/C/#fetch-a-module-worker-script-tree
@@ -132,7 +129,8 @@ class CORE_EXPORT Modulator : public GarbageCollected<Modulator>,
// used in the "fetch a module worker script graph" algorithm.
virtual void FetchTree(const KURL&,
ResourceFetcher* fetch_client_settings_object_fetcher,
- mojom::RequestContextType destination,
+ mojom::RequestContextType context_type,
+ network::mojom::RequestDestination destination,
const ScriptFetchOptions&,
ModuleScriptCustomFetchType,
ModuleTreeClient*) = 0;
@@ -154,7 +152,8 @@ class CORE_EXPORT Modulator : public GarbageCollected<Modulator>,
virtual void FetchDescendantsForInlineScript(
ModuleScript*,
ResourceFetcher* fetch_client_settings_object_fetcher,
- mojom::RequestContextType destination,
+ mojom::RequestContextType context_type,
+ network::mojom::RequestDestination destination,
ModuleTreeClient*) = 0;
// Synchronously retrieves a single module script from existing module map
@@ -215,7 +214,8 @@ class CORE_EXPORT Modulator : public GarbageCollected<Modulator>,
virtual ScriptValue ExecuteModule(ModuleScript*, CaptureEvalErrorFlag) = 0;
virtual ModuleScriptFetcher* CreateModuleScriptFetcher(
- ModuleScriptCustomFetchType) = 0;
+ ModuleScriptCustomFetchType,
+ util::PassKey<ModuleScriptLoader> pass_key) = 0;
};
} // namespace blink
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 b32a3eeb9ab..c86c9be0937 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
@@ -53,82 +53,6 @@ bool ModulatorImplBase::ImportMapsEnabled() const {
return RuntimeEnabledFeatures::ImportMapsEnabled(GetExecutionContext());
}
-bool ModulatorImplBase::BuiltInModuleInfraEnabled() const {
- return RuntimeEnabledFeatures::BuiltInModuleInfraEnabled(
- GetExecutionContext());
-}
-
-bool ModulatorImplBase::BuiltInModuleEnabled(layered_api::Module module) const {
- DCHECK(BuiltInModuleInfraEnabled());
-
- // Some built-in APIs are available only on SecureContexts.
- // https://crbug.com/977470
- if (BuiltInModuleRequireSecureContext(module) &&
- !GetExecutionContext()->IsSecureContext()) {
- return false;
- }
-
- if (RuntimeEnabledFeatures::BuiltInModuleAllEnabled())
- return true;
- switch (module) {
- case layered_api::Module::kBlank:
- return true;
- case layered_api::Module::kKvStorage:
- return RuntimeEnabledFeatures::BuiltInModuleKvStorageEnabled(
- GetExecutionContext());
- case layered_api::Module::kElementsInternal:
- // Union of conditions of KElementsSwitch and kElementsToast.
- return RuntimeEnabledFeatures::BuiltInModuleSwitchElementEnabled();
- case layered_api::Module::kElementsSwitch:
- return RuntimeEnabledFeatures::BuiltInModuleSwitchElementEnabled();
- case layered_api::Module::kElementsToast:
- return RuntimeEnabledFeatures::BuiltInModuleAllEnabled();
- case layered_api::Module::kElementsVirtualScroller:
- return false;
- }
-}
-
-bool ModulatorImplBase::BuiltInModuleRequireSecureContext(
- layered_api::Module module) {
- switch (module) {
- case layered_api::Module::kBlank:
- case layered_api::Module::kElementsInternal:
- case layered_api::Module::kElementsSwitch:
- case layered_api::Module::kElementsToast:
- case layered_api::Module::kElementsVirtualScroller:
- return false;
- case layered_api::Module::kKvStorage:
- return true;
- }
-}
-
-void ModulatorImplBase::BuiltInModuleUseCount(
- layered_api::Module module) const {
- DCHECK(BuiltInModuleInfraEnabled());
- DCHECK(BuiltInModuleEnabled(module));
- switch (module) {
- case layered_api::Module::kBlank:
- break;
- case layered_api::Module::kElementsInternal:
- break;
- case layered_api::Module::kElementsSwitch:
- UseCounter::Count(GetExecutionContext(),
- WebFeature::kBuiltInModuleSwitchImported);
- break;
- case layered_api::Module::kElementsToast:
- UseCounter::Count(GetExecutionContext(), WebFeature::kBuiltInModuleToast);
- break;
- case layered_api::Module::kElementsVirtualScroller:
- UseCounter::Count(GetExecutionContext(),
- WebFeature::kBuiltInModuleVirtualScroller);
- break;
- case layered_api::Module::kKvStorage:
- UseCounter::Count(GetExecutionContext(),
- WebFeature::kBuiltInModuleKvStorage);
- break;
- }
-}
-
// <specdef label="fetch-a-module-script-tree"
// href="https://html.spec.whatwg.org/C/#fetch-a-module-script-tree">
// <specdef label="fetch-a-module-worker-script-tree"
@@ -136,23 +60,26 @@ void ModulatorImplBase::BuiltInModuleUseCount(
void ModulatorImplBase::FetchTree(
const KURL& url,
ResourceFetcher* fetch_client_settings_object_fetcher,
- mojom::RequestContextType destination,
+ mojom::RequestContextType context_type,
+ network::mojom::RequestDestination destination,
const ScriptFetchOptions& options,
ModuleScriptCustomFetchType custom_fetch_type,
ModuleTreeClient* client) {
ModuleTreeLinker::Fetch(url, fetch_client_settings_object_fetcher,
- destination, options, this, custom_fetch_type,
- tree_linker_registry_, client);
+ context_type, destination, options, this,
+ custom_fetch_type, tree_linker_registry_, client);
}
void ModulatorImplBase::FetchDescendantsForInlineScript(
ModuleScript* module_script,
ResourceFetcher* fetch_client_settings_object_fetcher,
- mojom::RequestContextType destination,
+ mojom::RequestContextType context_type,
+ network::mojom::RequestDestination destination,
ModuleTreeClient* client) {
ModuleTreeLinker::FetchDescendantsForInlineScript(
- module_script, fetch_client_settings_object_fetcher, destination, this,
- ModuleScriptCustomFetchType::kNone, tree_linker_registry_, client);
+ module_script, fetch_client_settings_object_fetcher, context_type,
+ destination, this, ModuleScriptCustomFetchType::kNone,
+ tree_linker_registry_, client);
}
void ModulatorImplBase::FetchSingle(
@@ -174,7 +101,7 @@ KURL ModulatorImplBase::ResolveModuleSpecifier(const String& specifier,
const KURL& base_url,
String* failure_reason) {
ParsedSpecifier parsed_specifier =
- ParsedSpecifier::Create(specifier, base_url, BuiltInModuleInfraEnabled());
+ ParsedSpecifier::Create(specifier, base_url);
if (!parsed_specifier.IsValid()) {
if (failure_reason) {
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 ce0267f4b81..fcae74ca783 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
@@ -42,11 +42,6 @@ class ModulatorImplBase : public Modulator {
bool IsScriptingDisabled() const override;
bool ImportMapsEnabled() const override;
- bool BuiltInModuleInfraEnabled() const override;
- bool BuiltInModuleEnabled(layered_api::Module) const override;
- void BuiltInModuleUseCount(layered_api::Module) const override;
-
- static bool BuiltInModuleRequireSecureContext(layered_api::Module);
ModuleRecordResolver* GetModuleRecordResolver() override {
return module_record_resolver_.Get();
@@ -57,14 +52,16 @@ class ModulatorImplBase : public Modulator {
void FetchTree(const KURL&,
ResourceFetcher* fetch_client_settings_object_fetcher,
- mojom::RequestContextType destination,
+ mojom::RequestContextType context_type,
+ network::mojom::RequestDestination destination,
const ScriptFetchOptions&,
ModuleScriptCustomFetchType,
ModuleTreeClient*) override;
void FetchDescendantsForInlineScript(
ModuleScript*,
ResourceFetcher* fetch_client_settings_object_fetcher,
- mojom::RequestContextType destination,
+ mojom::RequestContextType context_type,
+ network::mojom::RequestDestination destination,
ModuleTreeClient*) override;
void FetchSingle(const ModuleScriptFetchRequest&,
ResourceFetcher* fetch_client_settings_object_fetcher,
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 09c772807ed..93738d839f8 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
@@ -108,11 +108,11 @@ class ModuleMapTestModulator final : public DummyModulator {
USING_GARBAGE_COLLECTED_MIXIN(TestModuleScriptFetcher);
public:
- explicit TestModuleScriptFetcher(ModuleMapTestModulator* modulator)
- : modulator_(modulator) {}
+ TestModuleScriptFetcher(ModuleMapTestModulator* modulator,
+ util::PassKey<ModuleScriptLoader> pass_key)
+ : ModuleScriptFetcher(pass_key), modulator_(modulator) {}
void Fetch(FetchParameters& request,
ResourceFetcher*,
- const Modulator* modulator_for_built_in_modules,
ModuleGraphLevel,
ModuleScriptFetcher::Client* client) override {
TestRequest* test_request = MakeGarbageCollected<TestRequest>(
@@ -135,8 +135,9 @@ class ModuleMapTestModulator final : public DummyModulator {
};
ModuleScriptFetcher* CreateModuleScriptFetcher(
- ModuleScriptCustomFetchType) override {
- return MakeGarbageCollected<TestModuleScriptFetcher>(this);
+ ModuleScriptCustomFetchType,
+ util::PassKey<ModuleScriptLoader> pass_key) override {
+ return MakeGarbageCollected<TestModuleScriptFetcher>(this, pass_key);
}
Vector<ModuleRequest> ModuleRequestsFromModuleRecord(
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 174cf5e338c..a0be66aa0ab 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
@@ -114,7 +114,7 @@ v8::Local<v8::Module> ModuleRecordResolverImpl::Resolve(
return record;
}
-void ModuleRecordResolverImpl::ContextDestroyed(ExecutionContext*) {
+void ModuleRecordResolverImpl::ContextDestroyed() {
// crbug.com/725816 : What we should really do is to make the map key
// weak reference to v8::Module.
record_to_module_script_map_.clear();
@@ -122,7 +122,7 @@ void ModuleRecordResolverImpl::ContextDestroyed(ExecutionContext*) {
void ModuleRecordResolverImpl::Trace(Visitor* visitor) {
ModuleRecordResolver::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
visitor->Trace(record_to_module_script_map_);
visitor->Trace(modulator_);
}
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 c1a021cda4a..116fead2bad 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
@@ -8,7 +8,7 @@
#include "third_party/blink/renderer/bindings/core/v8/boxed_v8_module.h"
#include "third_party/blink/renderer/bindings/core/v8/module_record.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/script/module_record_resolver.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
@@ -25,11 +25,12 @@ class ModuleRecord;
// ModuleMap (via Modulator) and V8 bindings.
class CORE_EXPORT ModuleRecordResolverImpl final
: public ModuleRecordResolver,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
public:
explicit ModuleRecordResolverImpl(Modulator* modulator,
ExecutionContext* execution_context)
- : ContextLifecycleObserver(execution_context), modulator_(modulator) {}
+ : ExecutionContextLifecycleObserver(execution_context),
+ modulator_(modulator) {}
void Trace(Visitor*) override;
USING_GARBAGE_COLLECTED_MIXIN(ModuleRecordResolverImpl);
@@ -48,8 +49,8 @@ class CORE_EXPORT ModuleRecordResolverImpl final
v8::Local<v8::Module> referrer,
ExceptionState&) final;
- // Implements ContextLifecycleObserver:
- void ContextDestroyed(ExecutionContext*) final;
+ // Implements ExecutionContextLifecycleObserver:
+ void ContextDestroyed() final;
// Corresponds to the spec concept "referencingModule.[[HostDefined]]".
// crbug.com/725816 : ModuleRecord contains strong ref to v8::Module thus we
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 1a89882a4f0..dcda9136481 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
@@ -4,8 +4,10 @@
#include "third_party/blink/renderer/core/script/module_script.h"
+#include "base/test/scoped_feature_list.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/renderer/bindings/core/v8/script_controller.h"
#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
@@ -116,11 +118,24 @@ class ModuleScriptTest : public ::testing::Test {
const JSModuleScript* module_script) {
return module_script->produce_cache_data_->GetProduceCacheOptions();
}
+
+ static bool HandlerCachedMetadataWasDiscarded(
+ SingleCachedMetadataHandler* cache_handler) {
+ auto* handler = static_cast<ScriptCachedMetadataHandler*>(cache_handler);
+ if (!handler)
+ return false;
+ return handler->cached_metadata_discarded_;
+ }
+
+ base::test::ScopedFeatureList feature_list_;
};
// Test expectations depends on heuristics in V8CodeCache and therefore these
-// tests should be updated if necessary when V8CodeCache is modified.
-TEST_F(ModuleScriptTest, V8CodeCache) {
+// tests should be updated if necessary when V8CodeCache is modified. The
+// version without code cache discarding.
+TEST_F(ModuleScriptTest, V8CodeCacheWithoutDiscarding) {
+ feature_list_.InitAndDisableFeature(
+ blink::features::kDiscardCodeCacheAfterFirstUse);
using Checkpoint = testing::StrictMock<testing::MockFunction<void(int)>>;
V8TestingScope scope;
@@ -133,6 +148,8 @@ TEST_F(ModuleScriptTest, V8CodeCache) {
SingleCachedMetadataHandler* cache_handler =
MakeGarbageCollected<ScriptCachedMetadataHandler>(UTF8Encoding(),
std::move(sender));
+ const uint32_t kTimeStampTag = V8CodeCache::TagForTimeStamp(cache_handler);
+ const uint32_t kCodeTag = V8CodeCache::TagForCodeCache(cache_handler);
// Tests the main code path: simply produce and consume code cache.
for (int nth_load = 0; nth_load < 3; ++nth_load) {
@@ -159,10 +176,8 @@ TEST_F(ModuleScriptTest, V8CodeCache) {
case 0:
// For the first time, the cache handler doesn't contain any data, and
// we'll set timestamp in ProduceCache() below.
- EXPECT_FALSE(cache_handler->GetCachedMetadata(
- V8CodeCache::TagForTimeStamp(cache_handler)));
- EXPECT_FALSE(cache_handler->GetCachedMetadata(
- V8CodeCache::TagForCodeCache(cache_handler)));
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kTimeStampTag));
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kCodeTag));
EXPECT_EQ(V8CodeCache::ProduceCacheOptions::kSetTimeStamp,
GetProduceCacheOptions(module_script));
EXPECT_CALL(*sender_ptr, Send(_, _));
@@ -171,10 +186,8 @@ TEST_F(ModuleScriptTest, V8CodeCache) {
case 1:
// For the second time, as timestamp is already set, we'll produce code
// cache in ProduceCache() below.
- EXPECT_TRUE(cache_handler->GetCachedMetadata(
- V8CodeCache::TagForTimeStamp(cache_handler)));
- EXPECT_FALSE(cache_handler->GetCachedMetadata(
- V8CodeCache::TagForCodeCache(cache_handler)));
+ EXPECT_TRUE(cache_handler->GetCachedMetadata(kTimeStampTag));
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kCodeTag));
EXPECT_EQ(V8CodeCache::ProduceCacheOptions::kProduceCodeCache,
GetProduceCacheOptions(module_script));
EXPECT_CALL(*sender_ptr, Send(_, _));
@@ -183,10 +196,8 @@ TEST_F(ModuleScriptTest, V8CodeCache) {
case 2:
// For the third time, the code cache is already there and we've
// consumed the code cache and won't do anything in ProduceCache().
- EXPECT_FALSE(cache_handler->GetCachedMetadata(
- V8CodeCache::TagForTimeStamp(cache_handler)));
- EXPECT_TRUE(cache_handler->GetCachedMetadata(
- V8CodeCache::TagForCodeCache(cache_handler)));
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kTimeStampTag));
+ EXPECT_TRUE(cache_handler->GetCachedMetadata(kCodeTag));
EXPECT_EQ(V8CodeCache::ProduceCacheOptions::kNoProduceCache,
GetProduceCacheOptions(module_script));
break;
@@ -200,24 +211,18 @@ TEST_F(ModuleScriptTest, V8CodeCache) {
switch (nth_load) {
case 0:
- EXPECT_TRUE(cache_handler->GetCachedMetadata(
- V8CodeCache::TagForTimeStamp(cache_handler)));
- EXPECT_FALSE(cache_handler->GetCachedMetadata(
- V8CodeCache::TagForCodeCache(cache_handler)));
+ EXPECT_TRUE(cache_handler->GetCachedMetadata(kTimeStampTag));
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kCodeTag));
break;
case 1:
- EXPECT_FALSE(cache_handler->GetCachedMetadata(
- V8CodeCache::TagForTimeStamp(cache_handler)));
- EXPECT_TRUE(cache_handler->GetCachedMetadata(
- V8CodeCache::TagForCodeCache(cache_handler)));
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kTimeStampTag));
+ EXPECT_TRUE(cache_handler->GetCachedMetadata(kCodeTag));
break;
case 2:
- EXPECT_FALSE(cache_handler->GetCachedMetadata(
- V8CodeCache::TagForTimeStamp(cache_handler)));
- EXPECT_TRUE(cache_handler->GetCachedMetadata(
- V8CodeCache::TagForCodeCache(cache_handler)));
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kTimeStampTag));
+ EXPECT_TRUE(cache_handler->GetCachedMetadata(kCodeTag));
break;
}
}
@@ -247,10 +252,149 @@ TEST_F(ModuleScriptTest, V8CodeCache) {
TestFoo(scope);
// The CachedMetadata are cleared.
- EXPECT_FALSE(cache_handler->GetCachedMetadata(
- V8CodeCache::TagForTimeStamp(cache_handler)));
- EXPECT_FALSE(cache_handler->GetCachedMetadata(
- V8CodeCache::TagForCodeCache(cache_handler)));
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kTimeStampTag));
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kCodeTag));
+}
+
+// Test expectations depends on heuristics in V8CodeCache and therefore these
+// tests should be updated if necessary when V8CodeCache is modified. The
+// version with code cache discarding.
+TEST_F(ModuleScriptTest, V8CodeCacheWithDiscarding) {
+ feature_list_.InitAndEnableFeature(
+ blink::features::kDiscardCodeCacheAfterFirstUse);
+ using Checkpoint = testing::StrictMock<testing::MockFunction<void(int)>>;
+
+ V8TestingScope scope;
+ Modulator* modulator =
+ MakeGarbageCollected<ModuleScriptTestModulator>(scope.GetScriptState());
+ Modulator::SetModulator(scope.GetScriptState(), modulator);
+
+ auto sender = std::make_unique<MockCachedMetadataSender>();
+ MockCachedMetadataSender* sender_ptr = sender.get();
+ SingleCachedMetadataHandler* cache_handler =
+ MakeGarbageCollected<ScriptCachedMetadataHandler>(UTF8Encoding(),
+ std::move(sender));
+ const uint32_t kTimeStampTag = V8CodeCache::TagForTimeStamp(cache_handler);
+ const uint32_t kCodeTag = V8CodeCache::TagForCodeCache(cache_handler);
+
+ // Tests the main code path: simply produce and consume code cache.
+ for (int nth_load = 0; nth_load < 4; ++nth_load) {
+ // Compile a module script.
+ JSModuleScript* module_script =
+ CreateJSModuleScript(modulator, LargeSourceText(), cache_handler);
+ ASSERT_TRUE(module_script);
+
+ // Check that the module script is instantiated/evaluated correctly.
+ ASSERT_TRUE(ModuleRecord::Instantiate(scope.GetScriptState(),
+ module_script->V8Module(),
+ module_script->SourceURL())
+ .IsEmpty());
+ ASSERT_TRUE(ModuleRecord::Evaluate(scope.GetScriptState(),
+ module_script->V8Module(),
+ module_script->SourceURL())
+ .IsEmpty());
+ TestFoo(scope);
+
+ Checkpoint checkpoint;
+ ::testing::InSequence s;
+
+ switch (nth_load) {
+ case 0:
+ // For the first time, the cache handler doesn't contain any data, and
+ // we'll set timestamp in ProduceCache() below.
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kTimeStampTag));
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kCodeTag));
+ EXPECT_EQ(V8CodeCache::ProduceCacheOptions::kSetTimeStamp,
+ GetProduceCacheOptions(module_script));
+ EXPECT_CALL(*sender_ptr, Send(_, _));
+ break;
+
+ case 1:
+ // For the second time, as timestamp is already set, we'll produce code
+ // cache in ProduceCache() below.
+ EXPECT_TRUE(cache_handler->GetCachedMetadata(kTimeStampTag));
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kCodeTag));
+ EXPECT_EQ(V8CodeCache::ProduceCacheOptions::kProduceCodeCache,
+ GetProduceCacheOptions(module_script));
+ EXPECT_CALL(*sender_ptr, Send(_, _));
+ break;
+
+ case 2:
+ // For the third time, the code cache is already there, we've
+ // consumed and discarded the code cache.
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kTimeStampTag));
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kCodeTag));
+ EXPECT_EQ(V8CodeCache::ProduceCacheOptions::kNoProduceCache,
+ GetProduceCacheOptions(module_script));
+ break;
+
+ case 3:
+ // The script is recompiled from source and wants to set the timestamp,
+ // but having cleared the CachedMetadata in the |cache_handler| prevents
+ // further code caching.
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kTimeStampTag));
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kCodeTag));
+ EXPECT_EQ(V8CodeCache::ProduceCacheOptions::kSetTimeStamp,
+ GetProduceCacheOptions(module_script));
+ EXPECT_TRUE(HandlerCachedMetadataWasDiscarded(cache_handler));
+ break;
+ }
+
+ EXPECT_CALL(checkpoint, Call(4));
+
+ module_script->ProduceCache();
+
+ checkpoint.Call(4);
+
+ switch (nth_load) {
+ case 0:
+ EXPECT_TRUE(cache_handler->GetCachedMetadata(kTimeStampTag));
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kCodeTag));
+ break;
+
+ case 1:
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kTimeStampTag));
+ EXPECT_TRUE(cache_handler->GetCachedMetadata(kCodeTag));
+ break;
+
+ case 2:
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kTimeStampTag));
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kCodeTag));
+ break;
+
+ case 3:
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kTimeStampTag));
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kCodeTag));
+ break;
+ }
+ }
+
+ // Tests nothing wrong occurs when module script code cache is consumed by a
+ // classic script.
+
+ Checkpoint checkpoint;
+ ::testing::InSequence s;
+
+ // Not expecting Send() because the |cache_handler| prevents updating the
+ // CachedMetadata after it has been cleared.
+ EXPECT_CALL(checkpoint, Call(4));
+
+ // In actual cases CachedMetadataHandler and its code cache data are passed
+ // via ScriptSourceCode+ScriptResource, but here they are passed via
+ // ScriptSourceCode constructor for inline scripts. So far, this is sufficient
+ // for unit testing.
+ scope.GetFrame().GetScriptController().ExecuteScriptInMainWorldAndReturnValue(
+ ScriptSourceCode(LargeSourceText(), ScriptSourceLocationType::kInternal,
+ cache_handler),
+ KURL(), SanitizeScriptErrors::kSanitize);
+
+ checkpoint.Call(4);
+
+ TestFoo(scope);
+
+ // Still in the cleared state.
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kTimeStampTag));
+ EXPECT_FALSE(cache_handler->GetCachedMetadata(kCodeTag));
}
TEST_F(ModuleScriptTest, ValueWrapperSyntheticModuleScript) {
@@ -263,4 +407,4 @@ TEST_F(ModuleScriptTest, ValueWrapperSyntheticModuleScript) {
ASSERT_FALSE(module_script->V8Module().IsEmpty());
}
-} // namespace blink \ No newline at end of file
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/script/parsed_specifier.cc b/chromium/third_party/blink/renderer/core/script/parsed_specifier.cc
index 81867f536d8..bc9a2d22045 100644
--- a/chromium/third_party/blink/renderer/core/script/parsed_specifier.cc
+++ b/chromium/third_party/blink/renderer/core/script/parsed_specifier.cc
@@ -8,14 +8,6 @@
namespace blink {
-namespace {
-
-static const char kStdScheme[] = "std";
-
-constexpr char kBuiltinSpecifierPrefix[] = "@std/";
-
-} // namespace
-
// <specdef href="https://html.spec.whatwg.org/#resolve-a-module-specifier">
// <specdef label="import-specifier"
// href="https://wicg.github.io/import-maps/#parse-a-url-like-import-specifier">
@@ -24,22 +16,7 @@ constexpr char kBuiltinSpecifierPrefix[] = "@std/";
// handle kBare cases properly, depending on contexts and whether import maps
// are enabled.
ParsedSpecifier ParsedSpecifier::Create(const String& specifier,
- const KURL& base_url,
- bool support_builtin_modules) {
- if (support_builtin_modules) {
- // Not spec'ed: we support @std/foo specifiers as an alias of std:foo.
- const StringView prefix(kBuiltinSpecifierPrefix);
- if (specifier.StartsWith(prefix)) {
- StringBuilder url_string;
- url_string.Append(kStdScheme);
- url_string.Append(":");
- url_string.Append(specifier.Substring(prefix.length()));
- KURL url(NullURL(), url_string.ToString());
- if (url.IsValid())
- return ParsedSpecifier(url);
- }
- }
-
+ const KURL& base_url) {
// <spec step="1">Apply the URL parser to specifier. If the result is not
// failure, return the result.</spec>
//
diff --git a/chromium/third_party/blink/renderer/core/script/parsed_specifier.h b/chromium/third_party/blink/renderer/core/script/parsed_specifier.h
index 8225af4a91d..c95e30f8f05 100644
--- a/chromium/third_party/blink/renderer/core/script/parsed_specifier.h
+++ b/chromium/third_party/blink/renderer/core/script/parsed_specifier.h
@@ -37,9 +37,7 @@ class ParsedSpecifier final {
// https://html.spec.whatwg.org/#resolve-a-module-specifier
// but doesn't reject bare specifiers, which should be rejected by callers
// if needed.
- static ParsedSpecifier Create(const String& specifier,
- const KURL& base_url,
- bool support_builtin_modules);
+ static ParsedSpecifier Create(const String& specifier, const KURL& base_url);
enum class Type { kInvalid, kBare, kURL };
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 0d443f9b8f8..2d51fbf4301 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
@@ -23,10 +23,9 @@ PendingImportMap* PendingImportMap::CreateInline(ScriptElementBase& element,
Modulator* modulator = Modulator::From(script_state);
ScriptValue error_to_rethrow;
- ImportMap* import_map =
- ImportMap::Parse(*modulator, import_map_text, base_url,
- modulator->BuiltInModuleInfraEnabled(),
- *context_document, &error_to_rethrow);
+ ImportMap* import_map = ImportMap::Parse(
+ *modulator, import_map_text, base_url,
+ *context_document->GetExecutionContext(), &error_to_rethrow);
return MakeGarbageCollected<PendingImportMap>(
script_state, element, import_map, error_to_rethrow, *context_document);
}
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/.eslintrc.js b/chromium/third_party/blink/renderer/core/script/resources/layered_api/.eslintrc.js
deleted file mode 100644
index 09834f57f39..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/.eslintrc.js
+++ /dev/null
@@ -1,341 +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.
-
-module.exports = {
- root: true,
- env: {
- es6: true,
- browser: true
- },
- 'parser': 'babel-eslint',
- parserOptions: {
- sourceType: 'module',
- ecmaVersion: 2019
- },
- rules: {
- 'for-direction': 'error',
- 'getter-return': 'error',
- 'no-async-promise-executor': 'error',
- 'no-await-in-loop': 'error',
- 'no-compare-neg-zero': 'error',
- 'no-cond-assign': ['error', 'except-parens'],
- 'no-console': 'error',
- 'no-constant-condition': ['error', {checkLoops: false}],
- 'no-control-regex': 'error',
- 'no-debugger': 'error',
- 'no-dupe-args': 'error',
- 'no-dupe-keys': 'error',
- 'no-duplicate-case': 'error',
- 'no-empty': 'error',
- 'no-empty-character-class': 'error',
- 'no-ex-assign': 'error',
- 'no-extra-boolean-cast': 'error',
- 'no-extra-parens': [
- 'error',
- 'all',
- {
- conditionalAssign: false,
- nestedBinaryExpressions: false,
- returnAssign: false
- }
- ],
- 'no-extra-semi': 'error',
- 'no-func-assign': 'error',
- 'no-inner-declarations': 'off',
- 'no-invalid-regexp': 'error',
- 'no-irregular-whitespace': 'error',
- 'no-misleading-character-class': 'error',
- 'no-obj-calls': 'error',
- 'no-prototype-builtins': 'error',
- 'no-regex-spaces': 'error',
- 'no-sparse-arrays': 'error',
- 'no-template-curly-in-string': 'error',
- 'no-unexpected-multiline': 'error',
- 'no-unreachable': 'error',
- 'no-unsafe-finally': 'off',
- 'no-unsafe-negation': 'error',
- 'use-isnan': 'error',
- 'valid-typeof': 'error',
- 'accessor-pairs': 'error',
- 'array-callback-return': 'error',
- 'block-scoped-var': 'off',
- 'class-methods-use-this': 'off',
- 'complexity': 'off',
- 'consistent-return': 'error',
- 'curly': ['error', 'all'],
- 'default-case': 'off',
- 'dot-location': ['error', 'property'],
- 'dot-notation': 'error',
- 'eqeqeq': 'error',
- 'guard-for-in': 'off',
- 'no-alert': 'error',
- 'no-caller': 'error',
- 'no-case-declarations': 'error',
- 'no-div-regex': 'off',
- 'no-empty-function': 'off',
- 'no-empty-pattern': 'error',
- 'no-eq-null': 'error',
- 'no-eval': 'error',
- 'no-extend-native': 'error',
- 'no-extra-bind': 'error',
- 'no-extra-label': 'error',
- 'no-fallthrough': 'error',
- 'no-floating-decimal': 'error',
- 'no-global-assign': 'error',
- 'no-implicit-coercion': 'error',
- 'no-implicit-globals': 'error',
- 'no-implied-eval': 'error',
- // no-invalid-this doesn't work well for private fields.
- // https://github.com/babel/eslint-plugin-babel/issues/182
- // 'no-invalid-this': 'error',
- 'no-iterator': 'error',
- 'no-labels': ['error', {allowLoop: true}],
- 'no-lone-blocks': 'error',
- 'no-loop-func': 'error',
- 'no-magic-numbers': ['error', {ignore: [0, 1, 2]}],
- 'no-multi-spaces': ['error', {ignoreEOLComments: true}],
- 'no-multi-str': 'error',
- 'no-new': 'error',
- 'no-new-func': 'error',
- 'no-new-wrappers': 'error',
- 'no-octal': 'error',
- 'no-octal-escape': 'error',
- 'no-param-reassign': 'off',
- 'no-process-env': 'error',
- 'no-proto': 'error',
- 'no-redeclare': 'error',
- 'no-restricted-properties': 'off',
- 'no-return-assign': ['error', 'except-parens'],
- 'no-return-await': 'error',
- 'no-script-url': 'off',
- 'no-self-assign': 'error',
- 'no-self-compare': 'error',
- 'no-sequences': 'error',
- 'no-throw-literal': 'error',
- 'no-unmodified-loop-condition': 'error',
- 'no-unused-expressions': 'error',
- 'no-unused-labels': 'error',
- 'no-useless-call': 'error',
- 'no-useless-concat': 'error',
- 'no-useless-escape': 'error',
- 'no-useless-return': 'error',
- 'no-void': 'error',
- 'no-warning-comments': 'off',
- 'no-with': 'error',
- 'prefer-promise-reject-errors': 'error',
- 'radix': ['error', 'as-needed'],
- 'require-await': 'off',
- 'vars-on-top': 'off',
- 'wrap-iife': ['error', 'outside'],
- 'yoda': ['error', 'never'],
- 'strict': ['error', 'global'],
- 'init-declarations': 'off',
- 'no-delete-var': 'error',
- 'no-label-var': 'error',
- 'no-restricted-globals': 'off',
- 'no-shadow': 'error',
- 'no-shadow-restricted-names': 'error',
- 'no-undef': 'error',
- 'no-undef-init': 'error',
- 'no-undefined': 'off',
- 'no-unused-vars': 'error',
- 'no-use-before-define': ['error', 'nofunc'],
- 'callback-return': 'off',
- 'global-require': 'error',
- 'handle-callback-err': 'error',
- 'no-buffer-constructor': 'error',
- 'no-mixed-requires': ['error', true],
- 'no-new-require': 'error',
- 'no-path-concat': 'error',
- 'no-process-exit': 'error',
- 'no-restricted-modules': 'off',
- 'no-sync': 'off',
- 'array-bracket-newline': ['error', {multiline: true}],
- 'array-bracket-spacing': ['error', 'never'],
- 'array-element-newline': 'off',
- 'block-spacing': ['error', 'always'],
- 'brace-style': [
- 'error',
- '1tbs',
- {allowSingleLine: false}
- ],
- camelcase: ['error', {properties: 'always'}],
- 'capitalized-comments': 'off',
- 'comma-dangle': ['error', 'always-multiline'],
- 'comma-spacing': [
- 'error',
- {
- before: false,
- after: true
- }
- ],
- 'comma-style': ['error', 'last'],
- 'computed-property-spacing': ['error', 'never'],
- 'consistent-this': 'off',
- 'eol-last': 'error',
- 'func-call-spacing': ['error', 'never'],
- 'func-name-matching': 'error',
- 'func-names': 'off',
- 'func-style': ['error', 'declaration'],
- 'function-paren-newline': 'off',
- 'id-blacklist': 'off',
- 'id-length': 'off',
- 'id-match': 'off',
- indent: 'off', // not really compatible with clang-format
- 'jsx-quotes': 'off',
- 'key-spacing': [
- 'error',
- {
- beforeColon: false,
- afterColon: true,
- mode: 'strict'
- }
- ],
- 'keyword-spacing': [
- 'error',
- {
- before: true,
- after: true
- }
- ],
- 'line-comment-position': 'off',
- 'linebreak-style': ['error', 'unix'],
- 'lines-around-comment': 'off',
- 'max-depth': 'off',
- 'max-len': ['error', {
- tabWidth: 2,
- ignorePattern: "(^import |// eslint-disable-line |https?://)"}],
- 'max-lines': 'off',
- 'max-nested-callbacks': 'off',
- 'max-params': 'off',
- 'max-statements': 'off',
- 'max-statements-per-line': ['error', {max: 1}],
- 'multiline-ternary': ['error', 'always-multiline'],
- 'new-cap': 'error',
- 'new-parens': 'error',
- 'newline-per-chained-call': 'off',
- 'no-array-constructor': 'error',
- 'no-bitwise': 'off',
- 'no-continue': 'off',
- 'no-inline-comments': 'off',
- 'no-mixed-operators': [
- 'error',
- {
- groups: [
- ['&', '|', '^', '~', '<<', '>>', '>>>'],
- ['==', '!=', '===', '!==', '>', '>=', '<', '<='],
- ['&&', '||'],
- ['in', 'instanceof']
- ]
- }
- ],
- 'no-mixed-spaces-and-tabs': 'error',
- 'no-multi-assign': 'off',
- 'no-multiple-empty-lines': 'error',
- 'no-negated-condition': 'off',
- 'no-nested-ternary': 'error',
- 'no-new-object': 'error',
- 'no-plusplus': 'off',
- 'no-restricted-syntax': 'off',
- 'no-tabs': 'error',
- 'no-ternary': 'off',
- 'no-trailing-spaces': 'error',
- 'no-underscore-dangle': 'off',
- 'no-unneeded-ternary': 'error',
- 'no-whitespace-before-property': 'error',
- 'nonblock-statement-body-position': 'error',
- 'object-curly-newline': ['error', {consistent: true}],
- 'object-curly-spacing': ['error', 'never'],
- 'object-property-newline': 'off',
- 'one-var': ['error', 'never'],
- 'one-var-declaration-per-line': ['error', 'initializations'],
- 'operator-assignment': ['error', 'always'],
- 'operator-linebreak': ['error', 'after'],
- 'padded-blocks': ['error', 'never'],
- 'padding-line-between-statements': 'off',
- 'quote-props': ['error', 'as-needed'],
- quotes: [
- 'error',
- 'single',
- {
- avoidEscape: true,
- allowTemplateLiterals: true
- }
- ],
- semi: ['error', 'always'],
- 'semi-spacing': 'error',
- 'semi-style': 'error',
- 'sort-keys': 'off',
- 'sort-vars': 'off',
- 'space-before-blocks': ['error', 'always'],
- 'space-before-function-paren': [
- 'error',
- {
- anonymous: 'never',
- asyncArrow: 'always',
- named: 'never'
- }
- ],
- 'space-in-parens': ['error', 'never'],
- 'space-infix-ops': 'error',
- 'space-unary-ops': [
- 'error',
- {
- words: true,
- nonwords: false
- }
- ],
- 'spaced-comment': ['error', 'always'],
- 'switch-colon-spacing': 'error',
- 'template-tag-spacing': 'error',
- 'unicode-bom': 'error',
- 'wrap-regex': 'off',
- 'arrow-body-style': 'off',
- 'arrow-parens': ['error', 'as-needed'],
- 'arrow-spacing': 'error',
- 'constructor-super': 'error',
- 'generator-star-spacing': ['error', 'neither'],
- 'no-class-assign': 'error',
- 'no-confusing-arrow': 'off',
- 'no-const-assign': 'error',
- 'no-dupe-class-members': 'error',
- 'no-duplicate-imports': 'error',
- 'no-new-symbol': 'error',
- 'no-restricted-imports': 'off',
- 'no-this-before-super': 'error',
- 'no-useless-computed-key': 'error',
- 'no-useless-constructor': 'error',
- 'no-useless-rename': 'error',
- 'no-var': 'error',
- 'object-shorthand': 'error',
- 'prefer-arrow-callback': 'error',
- 'prefer-const': ['error', {ignoreReadBeforeAssign: true}],
- 'prefer-destructuring': [
- 'error',
- {
- VariableDeclarator: {
- array: false,
- object: true
- },
- AssignmentExpression: {
- array: false,
- object: false
- }
- },
- {
- enforceForRenamedProperties: false
- }
- ],
- 'prefer-numeric-literals': 'error',
- 'prefer-rest-params': 'error',
- 'prefer-spread': 'error',
- 'prefer-template': 'off',
- 'require-yield': 'error',
- 'rest-spread-spacing': 'error',
- 'sort-imports': 'off',
- 'symbol-description': 'error',
- 'template-curly-spacing': ['error', 'never'],
- 'yield-star-spacing': ['error', 'after']
- }
-};
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/PRESUBMIT.py b/chromium/third_party/blink/renderer/core/script/resources/layered_api/PRESUBMIT.py
deleted file mode 100644
index 3dafa97e59f..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/PRESUBMIT.py
+++ /dev/null
@@ -1,34 +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.
-
-
-import sys
-
-
-def _CommonChecks(input_api, output_api):
- results = []
- mjs_files = input_api.AffectedFiles(
- file_filter=lambda f: f.LocalPath().endswith('.mjs'),
- include_deletes=False)
- if not mjs_files:
- return results
- try:
- old_sys_path = sys.path[:]
- cwd = input_api.PresubmitLocalPath()
- sys.path += [input_api.os_path.join(cwd, '..', '..', '..', '..', '..',
- '..', '..', 'tools')]
- import web_dev_style.js_checker
- checker = web_dev_style.js_checker.JSChecker(input_api, output_api)
- results += checker.RunEsLintChecks(mjs_files)
- finally:
- sys.path = old_sys_path
- return results
-
-
-def CheckChangeOnUpload(input_api, output_api):
- return _CommonChecks(input_api, output_api)
-
-
-def CheckChangeOnCommit(input_api, output_api):
- return _CommonChecks(input_api, output_api)
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/README.md b/chromium/third_party/blink/renderer/core/script/resources/layered_api/README.md
deleted file mode 100644
index 479818efa35..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/README.md
+++ /dev/null
@@ -1,48 +0,0 @@
-# Layered API resources directory
-
-This directory stores module JavaScript implementation files of
-[Layered APIs](https://github.com/drufball/layered-apis),
-that are to be bundled with the browser.
-
-## Adding/removing files
-
-When adding/removing files, execute
-
-- `core/script/generate_lapi_grdp.py`
-- `git cl format`
-
-to update the following files:
-
-- `core/script/layered_api_resources.h`
-- `core/script/resources/layered_api/resources.grdp`
-
-and commit these files together with the changes under resources/layered_api/.
-
-(This is not needed when the content of the files are modified)
-
-## Which files are bundled
-
-All files under
-
-- Sub-directories which have 'index.mjs' or
-- Directories of which last path component is 'internal'
-
-will be included in the grdp and thus bundled in the Chrome binary,
-except for files starting with '.', 'README', or 'OWNERS'.
-
-So be careful about binary size increase when you add new files or add more
-contents to existing files.
-
-## What are exposed
-
-All bundled resources are mapped to `std-internal://path-relative-to-here`, and
-`std-internal:` resources are not accessible from the web. Resources loaded as
-`std-internal:` can import other `std-internal:` resources.
-
-For example, `layered_api/foo/bar/baz.mjs` is mapped to
-`std-internal://foo/bar/baz.mjs`.
-
-All `index.mjs` resources are mapped to `std:directory-name-relative-to-here`
-too, and they are web-exposed. For example,
-`layered_api/elements/toast/index.mjs` is mapped to `std:elements/toast` as
-well as `std-internal://elements/toast/index.mjs`.
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/blank/index.mjs b/chromium/third_party/blink/renderer/core/script/resources/layered_api/blank/index.mjs
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/blank/index.mjs
+++ /dev/null
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/internal/reflection.mjs b/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/internal/reflection.mjs
deleted file mode 100644
index 085a94a01f6..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/internal/reflection.mjs
+++ /dev/null
@@ -1,63 +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.
-
-/**
- * @file Manage attribute-property reflections.
- * https://html.spec.whatwg.org/C/common-dom-interfaces.html#reflecting-content-attributes-in-idl-attributes
- */
-
-/**
- * Add a bool reflection property to the specified prototype for the specified
- * attribute.
- *
- * @param {!Object} proto An element prototype
- * @param {string} attrName An attribute name
- * @param {string} propName An optional property name. attrName will be used if
- * this argument is omitted.
- */
-export function installBool(proto, attrName, propName = attrName) {
- function getter() {
- return this.hasAttribute(attrName);
- }
- function setter(value) {
- this.toggleAttribute(attrName, Boolean(value));
- }
- Object.defineProperty(
- getter, 'name',
- {configurable: true, enumerable: false, value: 'get ' + propName});
- Object.defineProperty(
- setter, 'name',
- {configurable: true, enumerable: false, value: 'set ' + propName});
- Object.defineProperty(
- proto, propName,
- {configurable: true, enumerable: true, get: getter, set: setter});
-}
-
-/**
- * Add a DOMString reflection property to the specified prototype for the
- * specified attribute.
- *
- * @param {!Element} element An element prototype
- * @param {string} attrName An attribute name
- * @param {string} propName An optional property name. attrName will be used if
- * this argument is omitted.
- */
-export function installString(proto, attrName, propName = attrName) {
- function getter() {
- const value = this.getAttribute(attrName);
- return value === null ? '' : value;
- }
- function setter(value) {
- this.setAttribute(attrName, value);
- }
- Object.defineProperty(
- getter, 'name',
- {configurable: true, enumerable: false, value: 'get ' + propName});
- Object.defineProperty(
- setter, 'name',
- {configurable: true, enumerable: false, value: 'set ' + propName});
- Object.defineProperty(
- proto, propName,
- {configurable: true, enumerable: true, get: getter, set: setter});
-}
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/switch/README.md b/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/switch/README.md
deleted file mode 100644
index c8962f767cb..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/switch/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Switch control element
-
-https://github.com/tkent-google/std-switch/blob/master/README.md
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/switch/face_utils.mjs b/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/switch/face_utils.mjs
deleted file mode 100644
index 77002a00ad3..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/switch/face_utils.mjs
+++ /dev/null
@@ -1,56 +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.
-
-/**
- * @file Utilities for form-associated custom elements
- */
-
-import * as reflection from '../internal/reflection.mjs';
-
-function installGetter(proto, propName, getter) {
- Object.defineProperty(
- getter, 'name',
- {configurable: true, enumerable: false, value: 'get ' + propName});
- Object.defineProperty(
- proto, propName, {configurable: true, enumerable: true, get: getter});
-}
-
-/**
- * Add the following properties to |proto|
- * - disabled
- * - name
- * - type
- * and make the following properties and functions enumerable
- * - form
- * - willValidate
- * - validity
- * - validationMessage
- * - labels
- * - checkValidity()
- * - reportValidity()
- * - setCustomValidity(error)
- *
- * @param {!Object} proto An Element prototype which will have properties
- */
-export function installProperties(proto) {
- reflection.installBool(proto, 'disabled');
- reflection.installString(proto, 'name');
- installGetter(proto, 'type', function() {
- if (!(this instanceof proto.constructor)) {
- throw new TypeError(
- 'The context object is not an instance of ' + proto.contructor.name);
- }
- return this.localName;
- });
-
- Object.defineProperty(proto, 'form', {enumerable: true});
- Object.defineProperty(proto, 'willValidate', {enumerable: true});
- Object.defineProperty(proto, 'validity', {enumerable: true});
- Object.defineProperty(proto, 'validationMessage', {enumerable: true});
- Object.defineProperty(proto, 'labels', {enumerable: true});
-
- Object.defineProperty(proto, 'checkValidity', {enumerable: true});
- Object.defineProperty(proto, 'reportValidity', {enumerable: true});
- Object.defineProperty(proto, 'setCustomValidity', {enumerable: true});
-}
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/switch/index.mjs b/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/switch/index.mjs
deleted file mode 100644
index 6732ffd963f..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/switch/index.mjs
+++ /dev/null
@@ -1,221 +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.
-
-import * as reflection from '../internal/reflection.mjs';
-
-import * as face from './face_utils.mjs';
-import * as style from './style.mjs';
-import {SwitchTrack} from './track.mjs';
-
-const generateStyleSheet = style.styleSheetFactory();
-const generateMaterialStyleSheet = style.materialStyleSheetFactory();
-
-// https://github.com/tkent-google/std-switch/issues/2
-const STATE_ATTR = 'on';
-
-function parentOrHostElement(element) {
- const parent = element.parentNode;
- if (!parent) {
- return null;
- }
- if (parent.nodeType === Node.ELEMENT_NODE) {
- return parent;
- }
- if (parent.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
- return parent.host;
- }
- return null;
-}
-
-function shouldUsePlatformTheme(element) {
- for (; element; element = parentOrHostElement(element)) {
- const themeValue = element.getAttribute('theme');
- if (themeValue === 'match-platform') {
- return true;
- } else if (themeValue === 'platform-agnostic') {
- return false;
- }
- }
- return false;
-}
-
-export class StdSwitchElement extends HTMLElement {
- // TODO(tkent): The following should be |static fooBar = value;|
- // after enabling babel-eslint.
- static get formAssociated() {
- return true;
- }
- static get observedAttributes() {
- return [STATE_ATTR];
- }
-
- #internals;
- #track;
- #containerElement;
- #inUserAction = false;
- #shadowRoot;
-
- constructor() {
- super();
- if (new.target !== StdSwitchElement) {
- throw new TypeError(
- 'Illegal constructor: StdSwitchElement is not ' +
- 'extensible for now');
- }
- this.#internals = this.attachInternals();
- this.#internals.setFormValue('off');
- this.#initializeDOM();
-
- this.addEventListener('click', this.#onClick);
- this.addEventListener('keypress', this.#onKeyPress);
- }
-
- attributeChangedCallback(attrName, oldValue, newValue) {
- if (attrName === STATE_ATTR) {
- this.#internals.setFormValue(newValue !== null ? 'on' : 'off');
- this.#track.value = newValue !== null;
- if (this.#internals.ariaChecked !== undefined) {
- this.#internals.ariaChecked = newValue !== null ? 'true' : 'false';
- } else {
- // TODO(tkent): Remove this when we ship AOM.
- this.setAttribute('aria-checked', newValue !== null ? 'true' : 'false');
- }
- if (!this.#inUserAction) {
- for (const element of this.#containerElement.querySelectorAll('*')) {
- style.unmarkTransition(element);
- }
- }
- }
- }
-
- connectedCallback() {
- // The element might have been disconnected when the callback is invoked.
- if (!this.isConnected) {
- return;
- }
-
- // TODO(tkent): We should not add tabindex attribute.
- // https://github.com/w3c/webcomponents/issues/762
- if (!this.hasAttribute('tabindex')) {
- this.setAttribute('tabindex', '0');
- }
-
- if (this.#internals.role !== undefined) {
- this.#internals.role = 'switch';
- } else {
- // TODO(tkent): Remove this when we ship AOM.
- if (!this.hasAttribute('role')) {
- this.setAttribute('role', 'switch');
- }
- }
-
- if (shouldUsePlatformTheme(this)) {
- // TODO(tkent): Should we apply Cocoa-like on macOS and Fluent-like
- // on Windows?
- this.#shadowRoot.adoptedStyleSheets =
- [generateStyleSheet(), generateMaterialStyleSheet()];
- } else {
- this.#shadowRoot.adoptedStyleSheets = [generateStyleSheet()];
- }
- }
-
- formResetCallback() {
- this.on = this.defaultOn;
- }
-
- #initializeDOM = () => {
- const factory = this.ownerDocument;
- const root = this.attachShadow({mode: 'closed'});
- this.#containerElement = factory.createElement('span');
- this.#containerElement.id = 'container';
- // Shadow elements should be invisible for a11y technologies.
- this.#containerElement.setAttribute('aria-hidden', 'true');
- root.appendChild(this.#containerElement);
-
- this.#track = new SwitchTrack(factory);
- this.#containerElement.appendChild(this.#track.element);
- this.#track.value = this.on;
-
- const thumbElement =
- this.#containerElement.appendChild(factory.createElement('span'));
- thumbElement.id = 'thumb';
- thumbElement.part.add('thumb');
-
- this.#shadowRoot = root;
- };
-
- #onClick = () => {
- for (const element of this.#containerElement.querySelectorAll('*')) {
- style.markTransition(element);
- }
- this.#inUserAction = true;
- try {
- this.on = !this.on;
- } finally {
- this.#inUserAction = false;
- }
- this.dispatchEvent(new Event('input', {bubbles: true}));
- this.dispatchEvent(new Event('change', {bubbles: true}));
- };
-
- #onKeyPress = event => {
- if (event.code === 'Space') {
- // Do not scroll the page.
- event.preventDefault();
- this.#onClick(event);
- }
- };
-
- // -------- Boilerplate code for form-associated custom elements --------
- // They can't be in face_utils.mjs because private fields are available
- // only in the class.
- get form() {
- return this.#internals.form;
- }
- get willValidate() {
- return this.#internals.willValidate;
- }
- get validity() {
- return this.#internals.validity;
- }
- get validationMessage() {
- return this.#internals.validationMessage;
- }
- get labels() {
- return this.#internals.labels;
- }
- checkValidity() {
- return this.#internals.checkValidity();
- }
- reportValidity() {
- return this.#internals.reportValidity();
- }
- setCustomValidity(error) {
- if (error === undefined) {
- throw new TypeError('Too few arguments');
- }
- this.#internals.setValidity({customError: true}, error);
- }
-}
-
-reflection.installBool(StdSwitchElement.prototype, STATE_ATTR);
-reflection.installBool(
- StdSwitchElement.prototype, 'default' + STATE_ATTR,
- 'default' + STATE_ATTR.charAt(0).toUpperCase() + STATE_ATTR.substring(1));
-face.installProperties(StdSwitchElement.prototype);
-
-// This is necessary for anyObject.toString.call(switchInstance).
-Object.defineProperty(StdSwitchElement.prototype, Symbol.toStringTag, {
- configurable: true,
- enumerable: false,
- value: 'StdSwitchElement',
- writable: false,
-});
-
-customElements.define('std-switch', StdSwitchElement);
-delete StdSwitchElement.formAssociated;
-delete StdSwitchElement.observedAttributes;
-delete StdSwitchElement.prototype.attributeChangedCallback;
-delete StdSwitchElement.prototype.connectedCallback;
-delete StdSwitchElement.prototype.formResetCallback;
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/switch/style.mjs b/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/switch/style.mjs
deleted file mode 100644
index ded00d06040..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/switch/style.mjs
+++ /dev/null
@@ -1,304 +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.
-
-// Style constant values.
-const COLOR_ON = '#0077FF';
-const TRACK_RADIUS = '13px';
-const TRACK_BORDER_WIDTH = '2px';
-const THUMB_HEIGHT = '22px';
-const THUMB_WIDTH = '22px';
-const THUMB_MARGIN_START = '2px';
-const THUMB_MARGIN_END = '2px';
-
-const MATERIAL_THUMB_SIZE = '20px';
-const RIPPLE_COLOR = 'rgba(100,100,100,0.3)';
-const RIPPLE_MAX_SIZE = '48px';
-
-// Returns a function returning a CSSStyleSheet().
-// TODO(tkent): Share this stylesheet factory feature with elements/toast/.
-export function styleSheetFactory() {
- let styleSheet;
- return () => {
- if (!styleSheet) {
- styleSheet = new CSSStyleSheet();
- styleSheet.replaceSync(`
-:host {
- block-size: 26px;
- border: none;
- box-sizing: border-box;
- display: inline-block;
- inline-size: 54px;
- user-select: none;
- vertical-align: middle;
-}
-
-#container {
- align-items: center;
- block-size: 100%;
- display: inline-flex;
- inline-size: 100%;
-}
-
-#thumb {
- background: white;
- block-size: ${THUMB_HEIGHT};
- border-radius: calc(${THUMB_HEIGHT} / 2);
- border: 1px solid black;
- box-sizing: border-box;
- display: inline-block;
- margin-inline-start: calc(-100% + ${THUMB_MARGIN_START});
- inline-size: ${THUMB_WIDTH};
-}
-
-/* :host::part(thumb-transitioning) doesn't work. crbug.com/980506 */
-#thumb[part~="thumb-transitioning"] {
- transition: all linear 0.1s;
-}
-
-:host([on]) #thumb {
- border: 1px solid ${COLOR_ON};
- margin-inline-start: calc(0px - ${THUMB_WIDTH} - ${THUMB_MARGIN_END});
-}
-
-#track {
- block-size: 100%;
- border-radius: ${TRACK_RADIUS};
- border: ${TRACK_BORDER_WIDTH} solid #dddddd;
- box-shadow: 0 0 0 1px #f8f8f8;
- box-sizing: border-box;
- display: inline-block;
- inline-size: 100%;
- overflow: hidden;
- padding: 0px;
-}
-
-#trackFill {
- background: ${COLOR_ON};
- block-size: 100%;
- border-radius: calc(${TRACK_RADIUS}) - ${TRACK_BORDER_WIDTH});
- box-shadow: none;
- box-sizing: border-box;
- display: inline-block;
- inline-size: 0%;
- vertical-align: top;
-}
-
-#trackFill[part~="track-fill-transitioning"] {
- transition: all linear 0.1s;
-}
-
-:host([on]) #track {
- border: ${TRACK_BORDER_WIDTH} solid ${COLOR_ON};
-}
-
-:host(:focus) {
- outline-offset: 4px;
-}
-
-:host(:focus) #track {
- box-shadow: 0 0 0 2px #f8f8f8;
-}
-
-:host([on]:focus) #track {
- box-shadow: 0 0 0 2px #dddddd;
-}
-
-:host(:focus) #thumb {
- border: 2px solid black;
-}
-
-:host([on]:focus) #thumb {
- border: 2px solid ${COLOR_ON};
-}
-
-:host(:not(:focus-visible):focus) {
- outline: none;
-}
-
-:host(:not(:disabled):hover) #thumb {
- inline-size: 26px;
-}
-
-:host([on]:not(:disabled):hover) #thumb {
- margin-inline-start: calc(0px - 26px - ${THUMB_MARGIN_END});
-}
-
-:host(:active) #track {
- background: #dddddd;
-}
-
-:host([on]:active) #track {
- border: 2px solid #77bbff;
- box-shadow: 0 0 0 2px #f8f8f8;
-}
-
-:host([on]:active) #trackFill {
- background: #77bbff;
-}
-
-:host(:disabled) {
- opacity: 0.38;
-}
-
-/*
- * display:inline-block in the :host ruleset overrides 'hidden' handling
- * by the user agent.
- */
-:host([hidden]) {
- display: none;
-}
-
-`);
- }
- return styleSheet;
- };
-}
-
-export function materialStyleSheetFactory() {
- let styleSheet;
- return () => {
- if (!styleSheet) {
- styleSheet = new CSSStyleSheet();
- styleSheet.replaceSync(`
-:host {
- block-size: 20px;
- inline-size: 36px;
-}
-
-#track,
-:host(:active) #track {
- background: rgba(0,0,0,0.4);
- block-size: 14px;
- border: none;
- box-shadow: none;
-}
-
-:host([on]) #track,
-:host([on]:active) #track,
-:host([on]:focus) #track {
- border: none;
- box-shadow: none;
-}
-
-#trackFill,
-:host([on]:active) #trackFill {
- background: rgba(63,81,181,0.5);
-}
-
-#thumb,
-:host(:focus) #thumb {
- block-size: ${MATERIAL_THUMB_SIZE};
- border-radius: calc(${MATERIAL_THUMB_SIZE} / 2);
- border: none;
- box-shadow: 0 1px 5px 0 rgba(0,0,0,0.6);
- inline-size: ${MATERIAL_THUMB_SIZE};
- margin-inline-start: -100%;
-}
-
-:host([on]) #thumb,
-:host([on]:focus) #thumb,
-:host([on]:not(:disabled):hover) #thumb {
- background: rgb(63,81,181);
- border: none;
- margin-inline-start: calc(0px - 20px);
-}
-
-:host(:not(:disabled):hover) #thumb {
- inline-size: ${MATERIAL_THUMB_SIZE};
-}
-
-/*
- * Ripple effect
- *
- * Translucent circle is painted on the thumb if the element is :active or
- * :focus-visible. It has
- * - Size transition when it appears
- * - Opacity transition when it disappears
- * part(thumb)::before represents the former, and part(thumb)::after represents
- * the latter.
- */
-#thumb::before {
- background: ${RIPPLE_COLOR};
- block-size: 0px;
- border-radius: 0px;
- content: "";
- display: inline-block;
- inline-size: 0px;
- left: calc(${MATERIAL_THUMB_SIZE} / 2);
- position: relative;
- top: calc(${MATERIAL_THUMB_SIZE} / 2);
- transition: none;
-}
-
-:host(:active) #thumb::before,
-:host(:focus-visible) #thumb::before {
- block-size: ${RIPPLE_MAX_SIZE};
- border-radius: calc(${RIPPLE_MAX_SIZE} / 2);
- inline-size: ${RIPPLE_MAX_SIZE};
- left: calc((${MATERIAL_THUMB_SIZE} - ${RIPPLE_MAX_SIZE}) / 2);
- top: calc((${MATERIAL_THUMB_SIZE} - ${RIPPLE_MAX_SIZE}) / 2);
- transition: all linear 0.1s;
-}
-
-#thumb::after {
- background: ${RIPPLE_COLOR};
- block-size: ${RIPPLE_MAX_SIZE};
- border-radius: calc(${RIPPLE_MAX_SIZE} / 2);
- content: "";
- display: inline-block;
- inline-size: ${RIPPLE_MAX_SIZE};
- left: calc((${MATERIAL_THUMB_SIZE} - ${RIPPLE_MAX_SIZE}) / 2);
- opacity: 0;
- position: relative;
- /* Why 18px? */
- top: calc((${MATERIAL_THUMB_SIZE} - ${RIPPLE_MAX_SIZE}) / 2 - 18px);
- transition: opacity linear 0.3s;
-}
-
-:host(:active) #thumb::after,
-:host(:focus-visible) #thumb::after {
- block-size: 0px;
- content: "";
- inline-size: 0px;
- opacity: 1;
- transition: none;
-}
-
-`);
- }
- return styleSheet;
- };
-}
-
-/**
- * Add '$part-transitioning' part to the element if the element already has
- * a part name.
- *
- * TODO(tkent): We should apply custom state.
- *
- * @param {!Element} element
- */
-export function markTransition(element) {
- // Should check hasAttribute() to avoid creating a DOMTokenList instance.
- if (!element.hasAttribute('part') || element.part.length < 1) {
- return;
- }
- element.part.add(element.part[0] + '-transitioning');
-}
-
-/**
- * Remove '$part-transitioning' part from the element if the element already has
- * a part name.
- *
- * TODO(tkent): We should apply custom state.
- *
- * @param {!Element} element
- */
-export function unmarkTransition(element) {
- // Should check hasAttribute() to avoid creating a DOMTokenList instance.
- if (!element.hasAttribute('part') || element.part.length < 1) {
- return;
- }
- element.part.remove(element.part[0] + '-transitioning');
-}
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/switch/track.mjs b/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/switch/track.mjs
deleted file mode 100644
index f29cdacc810..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/switch/track.mjs
+++ /dev/null
@@ -1,70 +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.
-
-export class SwitchTrack {
- #value;
- #trackElement;
- #fillElement;
- #slotElement;
-
- /**
- * @param {!Document} factory A factory for elements created for this track.
- */
- constructor(factory) {
- this.#value = false;
- this.#initializeDOM(factory);
- }
-
- /**
- * @return {!Element}
- */
- get element() {
- return this.#trackElement;
- }
-
- /**
- * @param {Boolean} newValue
- */
- set value(newValue) {
- const oldValue = this.#value;
- this.#value = Boolean(newValue);
-
- const bar = this.#fillElement;
- if (bar) {
- bar.style.inlineSize = this.#value ? '100%' : '0%';
- if (oldValue !== this.#value) {
- this.#addSlot();
- }
- }
- }
-
- /**
- * @param {!Document} factory A factory for elements created for this track.
- */
- #initializeDOM = factory => {
- this.#trackElement = factory.createElement('div');
- this.#trackElement.id = 'track';
- this.#trackElement.part.add('track');
- this.#fillElement = factory.createElement('span');
- this.#fillElement.id = 'trackFill';
- this.#fillElement.part.add('track-fill');
- this.#trackElement.appendChild(this.#fillElement);
- this.#slotElement = factory.createElement('slot');
- this.#addSlot();
- };
-
- /**
- * Add the <slot>
- * - next to _fillElement if _value is true
- * - as a child of _fillElement if _value is false
- * This behavior is helpful to show text in the track.
- */
- #addSlot = () => {
- if (this.#value) {
- this.#fillElement.appendChild(this.#slotElement);
- } else {
- this.#trackElement.appendChild(this.#slotElement);
- }
- };
-}
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/toast/OWNERS b/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/toast/OWNERS
deleted file mode 100644
index d76cdfa11f0..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/toast/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-fergal@chromium.org
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/toast/index.mjs b/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/toast/index.mjs
deleted file mode 100644
index ef944b42809..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/toast/index.mjs
+++ /dev/null
@@ -1,277 +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.
- *
- * @fileoverview This file defines the class for the Standard Toast LAPI
- * and the accompanying showToast() function.
- * EXPLAINER: https://github.com/jackbsteinberg/std-toast
- * TEST PATH: /chromium/src/third_party/blink/web_tests/external/wpt/std-toast/*
- * @package
- */
-
-import * as reflection from '../internal/reflection.mjs';
-
-const DEFAULT_DURATION = 3000;
-const TYPES = new Set(['success', 'warning', 'error']);
-
-function styleSheetFactory() {
- let stylesheet;
- return () => {
- if (!stylesheet) {
- stylesheet = new CSSStyleSheet();
- stylesheet.replaceSync(`
- :host {
- position: fixed;
- bottom: 1em;
- right: 1em;
- border: solid;
- padding: 1em;
- background: white;
- color: black;
- z-index: 1;
- }
-
- :host(:not([open])) {
- display: none;
- }
-
- .default-closebutton {
- user-select: none;
- }
-
- :host([type=success i]) {
- border-color: green;
- }
-
- :host([type=warning i]) {
- border-color: orange;
- }
-
- :host([type=error i]) {
- border-color: red;
- }
- `);
- // TODO(jacksteinberg): use offset-block-end: / offset-inline-end: over
- // bottom: / right: when implemented http://crbug.com/538475.
- }
- return stylesheet;
- };
-}
-
-const generateStyleSheet = styleSheetFactory();
-
-export class StdToastElement extends HTMLElement {
- static observedAttributes = ['open', 'closebutton'];
- #shadow = this.attachShadow({mode: 'closed'});
- #timeoutID;
- #actionSlot;
- #closeButtonElement;
- #setCloseTimeout = duration => {
- clearTimeout(this.#timeoutID);
-
- if (duration === Infinity) {
- this.#timeoutID = null;
- } else {
- this.#timeoutID = setTimeout(() => {
- this.removeAttribute('open');
- }, duration);
- }
- };
-
- constructor(message) {
- super();
-
- this.#shadow.adoptedStyleSheets = [generateStyleSheet()];
-
- this.#shadow.appendChild(document.createElement('slot'));
-
- this.#actionSlot = document.createElement('slot');
- this.#actionSlot.setAttribute('name', 'action');
- this.#shadow.appendChild(this.#actionSlot);
-
- this.#closeButtonElement = document.createElement('button');
- this.#closeButtonElement.setAttribute('part', 'closebutton');
- setDefaultCloseButton(this.#closeButtonElement);
- this.#shadow.appendChild(this.#closeButtonElement);
-
- this.#closeButtonElement.addEventListener('click', () => {
- this.hide();
- });
-
- if (message !== undefined) {
- this.textContent = message;
- }
- }
-
- connectedCallback() {
- if (!this.hasAttribute('role')) {
- this.setAttribute('role', 'status');
- }
- // TODO(jacksteinberg): use https://github.com/whatwg/html/pull/4658
- // when implemented
- }
-
- get action() {
- return this.#actionSlot.assignedNodes().length !== 0 ?
- this.#actionSlot.assignedNodes()[0] :
- null;
- }
-
- set action(val) {
- const previousAction = this.action;
- if (val !== null) {
- if (!isElement(val)) {
- throw new TypeError('Invalid argument: must be type Element');
- }
-
- val.setAttribute('slot', 'action');
- this.insertBefore(val, previousAction);
- }
-
- if (previousAction !== null) {
- previousAction.remove();
- }
- }
-
- get closeButton() {
- if (this.hasAttribute('closebutton')) {
- const closeAttr = this.getAttribute('closebutton');
- return closeAttr === '' ? true : closeAttr;
- }
- return false;
- }
-
- set closeButton(val) {
- if (val === true) {
- this.setAttribute('closebutton', '');
- } else if (val === false) {
- this.removeAttribute('closebutton');
- } else {
- this.setAttribute('closebutton', val);
- }
- }
-
- get type() {
- const typeAttr = this.getAttribute('type');
- if (typeAttr === null) {
- return '';
- }
-
- const typeAttrLower = typeAttr.toLowerCase();
-
- if (TYPES.has(typeAttrLower)) {
- return typeAttrLower;
- }
-
- return '';
- }
-
- set type(val) {
- this.setAttribute('type', val);
- }
-
- show({duration = DEFAULT_DURATION} = {}) {
- if (duration <= 0) {
- throw new RangeError(
- `Invalid Argument: duration must be greater ` +
- `than 0 [${duration} given]`);
- }
-
- this.setAttribute('open', '');
- this.#setCloseTimeout(duration);
- }
-
- hide() {
- this.removeAttribute('open');
- }
-
- toggle(force) {
- this.toggleAttribute('open', force);
- }
-
- attributeChangedCallback(name, oldValue, newValue) {
- switch (name) {
- case 'open':
- if (newValue !== null && oldValue === null) {
- this.dispatchEvent(new Event('show'));
- } else if (newValue === null) {
- this.dispatchEvent(new Event('hide'));
- this.#setCloseTimeout(Infinity);
- }
- break;
- case 'closebutton':
- if (newValue !== null) {
- if (newValue === '') {
- setDefaultCloseButton(this.#closeButtonElement);
- } else {
- replaceDefaultCloseButton(this.#closeButtonElement, newValue);
- }
- }
- // if newValue === null we do nothing, since CSS will hide the button
- break;
- }
- }
-}
-
-reflection.installBool(StdToastElement.prototype, 'open');
-
-customElements.define('std-toast', StdToastElement);
-
-delete StdToastElement.prototype.attributeChangedCallback;
-delete StdToastElement.prototype.observedAttributes;
-delete StdToastElement.prototype.connectedCallback;
-
-export function showToast(message, options = {}) {
- const toast = new StdToastElement(message);
-
- const {action, closeButton, type, ...showOptions} = options;
-
- if (isElement(action)) {
- toast.action = action;
- } else if (action !== undefined) {
- const actionButton = document.createElement('button');
-
- // Unlike String(), this performs the desired JavaScript ToString operation.
- // https://gist.github.com/domenic/82adbe7edc4a33a70f42f255479cec39
- actionButton.textContent = `${action}`;
-
- actionButton.setAttribute('slot', 'action');
- toast.appendChild(actionButton);
- }
-
- if (closeButton !== undefined) {
- toast.closeButton = closeButton;
- }
-
- if (type !== undefined) {
- toast.type = type;
- }
-
- document.body.append(toast);
- toast.show(showOptions);
-
- return toast;
-}
-
-const idGetter = Object.getOwnPropertyDescriptor(Element.prototype, 'id').get;
-function isElement(value) {
- try {
- idGetter.call(value);
- return true;
- } catch {
- return false;
- }
-}
-
-function setDefaultCloseButton(closeButton) {
- closeButton.setAttribute('aria-label', 'close');
- closeButton.setAttribute('class', 'default-closebutton');
- closeButton.textContent = '×';
-}
-
-function replaceDefaultCloseButton(closeButton, value) {
- closeButton.textContent = value;
- closeButton.removeAttribute('aria-label');
- closeButton.removeAttribute('class');
-}
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/OWNERS b/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/OWNERS
deleted file mode 100644
index d76cdfa11f0..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-fergal@chromium.org
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/docs/README.md b/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/docs/README.md
deleted file mode 100644
index c5ea6fc86c3..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/docs/README.md
+++ /dev/null
@@ -1,297 +0,0 @@
-# Virtual Scroller Notes
-
-This is Blink's implementation of the [`<virtual-scroller>`](https://github.com/WICG/virtual-scroller) element.
-
-## Status
-
-This is a prototype with many known issues.
-
-## Principles
-
-- Avoid operations that are O(number of children)
-- Ensure that we only perform operations that cause DOM, style or rendering work in the browser
- that is O(number of visible elements).
-- Avoid forcing layout from JS.
-
-## Current Implementation Strategy
-
-The prototype uses a custom element implemented in JS.
-It only handles vertical block layout,
-so this talks only about height.
-This custom element manages the display-locking status of its child items.
-It considers a range of pixels to be the "unlocked range".
-This range is determined from the window size.
-
-TODO(crbug.com/983052): Be smarter about determining the buffer size,
-given that the window can be resized.
-
-Items which are within the unlocked range are left unlocked.
-All other items are locked
-so that they do not incur style and rendering costs for their contents.
-They are locked with a height that is our best guess at their rendered height.
-This guess is based on
-- a fixed default
-- a previously measured height of this item
-- an average of previous observed heights of items
-
-The virtual scroller listens to observers to know when it needs to reconsider which items should be locked.
-It keeps a resize observer on itself since if it is resized,
-items may need to be newly locked or unlocked.
-It keeps an intersection observer on all unlocked child items.
-Along with the buffer around the screen,
-this allows it to know when the state has changed such that we may need to lock or unlock different items.
-
-TODO(crbug.com/983050): Observe one item above and below the unlocked items too,
-without this, if the edge item is larger than the window,
-we can scroll empty space into the visible region.
-
-TODO(crbug.com/983046): Keep an intersection observer on the scroller.
-This allows us to know whether the scroller is offscreen.
-In that case we lock all elements
-and pause all activity.
-This includes if the scroller is contained in a locked element
-(e.g. nested in another virtual scroller).
-
-The virtual scroller keeps a mutation observer on itself
-so that it can react to elements being added, removed or moved around.
-When dealing with mutations,
-elements which are newly added are treated differently
-to elements which are removed and re-added.
-Newly added elements are immediately locked.
-This allows a large number of elements to be added,
-without a large rendering/style cost for these elements.
-
-The virtual scroller does not listen directly for scroll events
-and does not know or care whether it is in a scrollable region.
-It is tempting to try discover whether the scroller is contained in a scrolling region
-and then listen for scroll events,
-however the scroller may be contained in any number of nested scrollable regions
-and DOM changes can cause it to be reparented.
-Also, we only need to change state when an item enters or leaves the visible range
-but scroll events may occur much more frequently than that.
-
-The virtual scroller takes no action directly in response to these events.
-It simply ensures that a `requestAnimationFrame` (RAF) callback will run this frame
-(max one per frame).
-This callback is the "sync" callback.
-It will attempt to react to the new state of the world
-and try to ensure that the scroller is in sync with it.
-This is where we determine which elements to lock or unlock.
-
-When determining which items should be locked and which should be unlocked,
-the virtual scroller uses `getBoundingClientRect`
-to get the coordinates of its items,
-relative to the root viewport.
-It binary searches on the array of items
-to find the element at the top and bottom of the visible range.
-At the end of the sync,
-these and the elements in between them will be unlocked
-and all other elements will be locked.
-The scroller knows which elements are currently unlocked
-and does the minimal amount of locking and unlocking
-to bring it to the desired state.
-Also the intersection observers will be updated to match this range of elements.
-
-It is very possible that the range of elements we have unlocked
-is too big or too small for the viewport.
-We cannot know the rendered size of these elements
-until we have unlocked and measured them.
-In order to avoid extra forced layouts,
-we simply queue another sync callback for the next frame.
-We continue to queue sync callbacks until one of them makes no changes.
-
-Internally, the virtual scroller slots all children into a single slot.
-It changes the locked state of the light tree children directly.
-
-## Known issues specific to the current prototype
-
-### Display locking items directly
-
-The current prototype changes the locked state of the light tree children directly.
-This means that the scroller's actions can be detected from outside.
-It also means that an author cannot (in general) safely use display locking
-on the children of a virtual scroller.
-
-Other approaches do not have this issue,
-because they slot the items into more than one slot,
-however, this requires either manipulating the `slot` attribute on the items
-or [imperative slotting](https://www.chromestatus.com/feature/5711021289242624).
-
-### Binary searching the items
-
-The first problem with this is that it requires forced layout (see below).
-
-The second (potential) problem is that
-while JS presents an `Array` interface for the children of the virtual scroller,
-the reality is that in Blink,
-the elements are stored in a linked list
-with some extra logic to remember the most recent indexed access
-and use that to speed up subsequent index accesses
-(e.g. accessing `[n+1]` after `[n]` is fast).
-This makes the binary search actually O(number of children)
-because the C++ code must traverse a linked list.
-However C++ traversing a link list is very fast
-so this tends not to be noticeable.
-
-### Locked elements still have a cost
-
-While the descendants of locked elements are skipped for style and layout,
-the locked elements themselves are still traversed
-and participate in style and layout.
-In the scroller,
-the elements are locked with a size
-and behave just as an empty div with that size.
-This means that when we add many children to the virtual scroller,
-even though most of them are locked,
-there can still be quite a large style and rendering cost
-from the locked elements in aggregate.
-
-## Known issues common to many approaches
-
-### Intersection observers are slow
-
-Intersection observers signal the intersection state *after* it has happened.
-This means that by only reacting to intersection observers,
-the scroller may react late to scrolls and jumps.
-Once a scroll begins,
-it's likely that the element will keep up,
-since it is not using the details of the events to compute the state of the scroller.
-
-### Forced layouts to measure item sizes
-
-After unlocking, the scroller needs to know the rendered size of an element.
-In order to do that it must call `getBoundingClientRect`.
-This forces the browser to have clean style and layout
-for all unlocked elements in the document
-(whether this is expensive depends on what has changed since the last time layout).
-It may be better to perform these measurements in a
-[post animation frame callback](https://github.com/WICG/requestPostAnimationFrame/blob/master/explainer.md)
-when that feature becomes available
-because this callback guarantees that style and layout are clean,
-so measuring elements should be inexpensive.
-
-## Alternative approaches
-
-### Unlocked tree of divs with `<slot>`s for leaves (rejected)
-
-We could avoid the O(number of children) run of locked divs
-by building a tree of divs (e.g. a binary tree)
-and locking all of the slots except those containing the visible items.
-
-*PROBLEM:* This breaks margin collapsing between items
-and maybe other layout or style features.
-In order to make margin collapsing work correctly
-we would need to make all of the divs in this tree have style `display: contents`
-but for layout, this would have exactly the same performance problem as placing them all as siblings in one slot.
-
-### One visible slot in the middle (rejected)
-
-We could assign all of the visible items to a single slot,
-ensuring they behave correctly with respect to margin collapsing
-and keep all other items in other slots.
-
-We need to ensure that elements are slotted in their light-tree order
-for find-in-page, accessibility etc to work correctly.
-The simplest form of this is a three-slot approach
-with one slot for the invisible items at the top,
-another slot for the visible items in the middle
-and a third slot for the invisible items at the bottom.
-The top and bottom slot remain locked always
-and items are moved into the visible slot when they should be visible.
-The top and bottom slots are inside a locked div.
-These divs are locked with a size estimated to be the correct aggregate size for their slotted elements.
-
-*PROBLEM:* Gradually scrolling down moves items one at a time
-from the bottom slot, to the visible slot and then into the top slot
-but long-range jumps require moving O(number of children) items between slots.
-E.g. if the top items are visible and we jump to make the bottom items visible,
-then we have to assign almost all of the items that were in the bottom slot to the top slot.
-
-### Roaming visible slot (not preferred)
-
-This is similar to [One visible slot in the middle](#One-visible-slot-in-the-middle) approach
-but rather than a top and bottom slot,
-item assignment is divided over many slots.
-Each item has a natural "leaf" slot that it should be assigned to.
-All of the leaf slots are kept locked.
-There is a single visible slot that contains the currently unlocked items
-and it roams around between the leaf slots
-to ensure that order is correct for find-in-page etc.
-If we keep the number of items per slot low,
-then long jumps never cause a large number of items to be reassigned,
-at worst we need to reassign the currently visible items back to their leaf slots,
-move the visible slot to a new place
-and fill it with newly visible items.
-
-It's possible that there will be so many slots
-that once again we run into the problem of large numbers of empty divs.
-So we may need to maintain a tree of divs and `<slot>`s.
-Most of this tree would be locked
-but the path from the visible slot to the root would be unlocked.
-
-It looks like this:
-
-![Diagram of a sample roaming visible slot tree](roaming-slot.png)
-
-Original diagram [here](https://docs.google.com/drawings/d/1oZ8U16GzkxO3GaYLDygPsrmXiHO7SLNFXvVUK6WkG4I/edit)
-
-*CHALLENGES:* This approach does not seem to have any insurmountable problems,
-however it is not simple:
-- We need to ensure that the tree remains balanced in the face of mutations of the virtual scrollers contents.
-- A tree may introduce a large number of tree-only elements.
- With a binary tree, this would be equal to the number of items in the scroller.
- It might be worth using a larger branching factor, to reduce this cost.
- E.g. in a 10-way tree the overhead is only 1/9 the number of leaves.
-- There is a lot of re-slotting of items.
-- The visible slot may contain a large number of elements (if elements are small)
- and Blink has some [optimizations](https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/html/html_slot_element.cc?q=symbol:HTMLSlotElement::NotifySlottedNodesOfFlatTreeChange)
- that only work when slots contain <= 16 elements.
-- Adding slots and/or assigning elements to slots currently involves operations that are O(number of children).
- Adding N slots can take O(N^2) time.
- This was previously not a concern in Blink
- because, in general, the style and layout costs dominated.
- However display locking eliminates these costs,
- leaving the slotting costs as the bottleneck when there are large numbers of items.
-
-### One slot per item (most promising alternative)
-
-This is similar to [Roaming visible slot](#Roaming-visible-slot).
-We have a tree of divs with slots as leaves
-but in this approach we have exactly one slot per item.
-For any item that should be unlocked,
-we ensure that all of its tree ancestors are unlocked
-and have style `display: contents`.
-All other nodes in the tree have style `display: block; contain: style layout`,
-to allow them to be locked.
-
-This has the effect of making all of the visible items siblings,
-from the perspective of layout,
-so that margin collapsing, etc. works correctly.
-It also ensures that not only are the invisible items and tree divs locked
-but they are *inside* locked ancestors,
-so do not incur *any* costs.
-
-There is no need to maintain spacer divs above and below the visible region.
-Instead, when we lock any tree element,
-we set its locked size to be its current visible size.
-If its contents don't change then this element has the correct aggregate size for its contents.
-If this element's parent is unlocked then this correct size will be used in sizing the parent.
-
-Mutations to the tree require size updates to propagate up the ancestor chain.
-E.g. inserting an element causes all of the elements ancestors to grow by our best guess at its size.
-So, the initial state of the tree
-(which comes from an initial insert)
-is that everything is an estimate or sum of estimates,
-with the sizes getting more accurate
-as more elements are rendered, measured and re-locked with correct sizes.
-
-It's likely that the sizes above will be off by some amount due to margins
-but they should be good enough for maintaining a usable scrollbar.
-
-*CHALLENGES:* This approach does not seem to have any insurmountable problems,
-however it is not so simple.
-It has a subset of the challenges of [Roaming visible slot](#Roaming-visible-slot):
-
-- Needs a balanced tree.
-- Possible large number of tree-only elements.
-- Slot performance issues.
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/docs/roaming-slot.png b/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/docs/roaming-slot.png
deleted file mode 100644
index 2f9b6844694..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/docs/roaming-slot.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/find-element.mjs b/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/find-element.mjs
deleted file mode 100644
index c25edc0a7fd..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/find-element.mjs
+++ /dev/null
@@ -1,104 +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.
- *
- * @fileoverview Utilities for binary searching by layed-out pixed offset in a
- * list of elements.
- * @package
- */
-
-/** Symbols for use with @see findElement */
-export const BIAS_LOW = Symbol('BIAS_LOW');
-export const BIAS_HIGH = Symbol('BIAS_HIGH');
-
-function getBound(elements, edgeIndex) {
- const element = elements[Math.floor(edgeIndex / 2)];
- const rect = element.getBoundingClientRect();
- return edgeIndex % 2 ? rect.bottom : rect.top;
-}
-
-/**
- * Does the actual work of binary searching. This searches amongst the 2*N edges
- * of the N elements. Returns the index of an edge found, 2i is the low edge of
- * the ith element, 2i+1 is the high edge of the ith element. If |bias| is low
- * then we find the index of the lowest edge >= offset. Otherwise we find index
- * of the highest edge > offset.
- */
-function findEdgeIndex(elements, offset, bias) {
- let low = 0;
- let high = elements.length * 2 - 1;
- while (low < high) {
- const i = Math.floor((low + high) / 2);
- const bound = getBound(elements, i);
- if (bias === BIAS_LOW) {
- if (bound < offset) {
- low = i + 1;
- } else {
- high = i;
- }
- } else {
- if (offset < bound) {
- high = i;
- } else {
- low = i + 1;
- }
- }
- }
- return low;
-}
-
-/**
- * Binary searches inside the array |elements| to find an element containing or
- * nearest to |offset| (based on @see Element#getBoundingClientRect()). Assumes
- * that the elements are already sorted in increasing pixel order. |bias|
- * controls what happens if |offset| is not contained within any element or if
- * |offset| is contained with 2 elements (this only happens if there is no
- * margin between the elements). If |bias| is BIAS_LOW, then this selects the
- * lower element nearest |offset|, otherwise it selects the higher element.
- *
- * Returns null if |offset| is not within any element.
- *
- * @param {!Element[]} elements An array of Elements in display order,
- * i.e. the pixel offsets of later element are higher than those of earlier
- * elements.
- * @param {!number} offset The target offset in pixels to search for.
- * @param {!Symbol} bias Controls whether we prefer a higher or lower element
- * when there is a choice between two elements.
- */
-export function findElement(elements, offset, bias) {
- if (elements.length === 0) {
- return null;
- }
- // Check if the offset is outside the range entirely.
- if (offset < getBound(elements, 0) ||
- offset > getBound(elements, elements.length * 2 - 1)) {
- return null;
- }
-
- let edgeIndex = findEdgeIndex(elements, offset, bias);
-
- // Fix up edge cases.
- if (bias === BIAS_LOW) {
- // bound(0)..bound(edgeIndex) < offset <= bound(edgeIndex+1) ...
- // If we bias low and we got a low edge and we weren't exactly on the edge
- // then we want to select the element that's lower.
- if (edgeIndex % 2 === 0) {
- const bound = getBound(elements, edgeIndex);
- if (offset < bound) {
- edgeIndex--;
- }
- }
- } else {
- // bound(0)..bound(edgeIndex - 1) <= offset < bound(edgeIndex) ...
- // If we bias high and we got a low edge, we need to check if we were
- // exactly on the edge of the previous element.
- if (edgeIndex % 2 === 0) {
- const bound = getBound(elements, edgeIndex - 1);
- if (offset === bound) {
- edgeIndex--;
- }
- }
- }
- return elements[Math.floor(edgeIndex / 2)];
-}
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/index.mjs b/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/index.mjs
deleted file mode 100644
index f7951f47198..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/index.mjs
+++ /dev/null
@@ -1,55 +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.
- *
- * @fileoverview This file defines virtual-scroller element.
- * EXPLAINER: https://github.com/fergald/virtual-scroller/blob/master/README.md
- * TEST PATH: third_party/blink/web_tests/http/tests/virtual-scroller/*
- * third_party/blink/web_tests/wpt_internal/virtual-scroller/*
- * @package
- */
-import {VisibilityManager} from './visibility-manager.mjs';
-
-function styleSheetFactory() {
- let styleSheet;
- return () => {
- if (!styleSheet) {
- styleSheet = new CSSStyleSheet();
- styleSheet.replaceSync(`
-:host {
- display: block;
-}
-
-::slotted(*) {
- display: block !important;
- contain: layout style;
-}
-`);
- }
- return styleSheet;
- };
-}
-
-const generateStyleSheet = styleSheetFactory();
-
-/**
- * The class backing the virtual-scroller custom element.
- */
-export class VirtualScrollerElement extends HTMLElement {
- constructor() {
- super();
-
- const shadowRoot = this.attachShadow({mode: 'closed'});
- shadowRoot.adoptedStyleSheets = [generateStyleSheet()];
- shadowRoot.appendChild(document.createElement('slot'));
-
- const visibilityManager = new VisibilityManager(this);
-
- new MutationObserver(records => {
- visibilityManager.applyMutationObserverRecords(records);
- }).observe(this, {childList: true});
- }
-}
-
-customElements.define('virtual-scroller', VirtualScrollerElement);
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/sets.mjs b/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/sets.mjs
deleted file mode 100644
index cd89ffef9df..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/sets.mjs
+++ /dev/null
@@ -1,50 +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.
- *
- * @fileoverview Utility functions for set operations.
- * @package
- */
-
-/*
- * Returns the set of elements in |a| that are not in |b|.
- *
- * @param {!Set} a A set of elements.
- * @param {!Set} b A set of elements.
- */
-export function difference(a, b) {
- const result = new Set();
- for (const element of a) {
- if (!b.has(element)) {
- result.add(element);
- }
- }
- return result;
-}
-
-/**
- * Callback applying to an item in a set.
- *
- * @callback applyToDiff
- * @param {any} item
- */
-
-/**
- * Calculates the difference between |oldSet| and |newSet| and applies
- * |deletedFunc| or |addedFunc| to the elements that were deleted or added.
- *
- * Returns the number of elements operated on.
- *
- * @param {!Set} oldSet A set of elements.
- * @param {!Set} newSet A set of elements.
- * @param {applyToDiff} deletedFun A function to be applied to deleted elements.
- * @param {applyToDiff} addedFun A function to be applied to added elements.
- */
-export function applyToDiffs(oldSet, newSet, deletedFunc, addedFunc) {
- const deleted = difference(oldSet, newSet);
- const added = difference(newSet, oldSet);
- deleted.forEach(deletedFunc);
- added.forEach(addedFunc);
- return deleted.size + added.size;
-}
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/visibility-manager.mjs b/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/visibility-manager.mjs
deleted file mode 100644
index cb6b550d382..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/elements/virtual-scroller/visibility-manager.mjs
+++ /dev/null
@@ -1,453 +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.
- *
- * @fileoverview This file provides the class backing the virtual-scroller
- * element.
- * @package
- */
-import * as findElement from './find-element.mjs';
-import * as sets from './sets.mjs';
-
-
-// This controls how much above and below the current screen we
-// reveal, e.g. 1 = 1 screen of content.
-const BUFFER = 0.2;
-// When we know about the heights of elements we default this height.
-const DEFAULT_HEIGHT_ESTIMATE_PX = 100;
-// When we lock an element, we use this as the width. We use 1px because locked
-// items will not resize when their container changes and so could result in a
-// horizontal scroll-bar appearing if it they are wide enough.
-const LOCKED_WIDTH_PX = 1;
-
-/**
- * Represents a range of elements from |low| to |high|, inclusive.
- * If either |low| or |high| are null then we treat this as an empty range.
- */
-class ElementBounds {
- /** @const {Element} */
- low;
- /** @const {Element} */
- high;
-
- constructor(low, high) {
- this.low = low;
- this.high = high;
- }
-
- // Returns a Set containing all of the elements from low to high.
- elementSet() {
- const result = new Set();
- if (this.low === null || this.high === null) {
- return result;
- }
- let element = this.low;
- while (element) {
- result.add(element);
- if (element === this.high) {
- break;
- }
- element = element.nextElementSibling;
- }
- return result;
- }
-}
-
-const EMPTY_ELEMENT_BOUNDS = new ElementBounds(null, null);
-
-/**
- * Manages measuring and estimating sizes of elements.
- *
- * This tracks an average measured element size as elements are added
- * and removed.
- */
-class SizeManager {
- #sizes = new WeakMap();
-
- #totalMeasuredSize = 0;
- #measuredCount = 0;
-
- /**
- * Measures and stores |element|'s size. If |element| was measured
- * previously, this updates everything to use the new current size.
- *
- * @param {!Element} element The element to measure.
- */
- measure(element) {
- let oldSize = this.#sizes.get(element);
- if (oldSize === undefined) {
- oldSize = 0;
- this.#measuredCount++;
- }
- const newSize = element.getBoundingClientRect().height;
- this.#totalMeasuredSize += newSize - oldSize;
- this.#sizes.set(element, newSize);
- }
-
- /**
- * Returns a size for |element|, either the last stored size or an
- * estimate based on all other previously measured elements or a
- * default.
- *
- * @param {!Element} element The element to produce a size for.
- */
- getHopefulSize(element) {
- const size = this.#sizes.get(element);
- return size === undefined ? this.#getAverageSize() : size;
- }
-
- #getAverageSize =
- () => {
- return this.#measuredCount > 0 ?
- this.#totalMeasuredSize / this.#measuredCount :
- DEFAULT_HEIGHT_ESTIMATE_PX;
- }
-
- /**
- * Removes all data related to |element| from the manager.
- *
- * @param {!Element} element The element to remove.
- */
- remove(element) {
- const oldSize = this.#sizes.get(element);
- if (oldSize === undefined) {
- return;
- }
- this.#totalMeasuredSize -= oldSize;
- this.#measuredCount--;
- this.#sizes.delete(element);
- }
-}
-
-/**
- * Manages the visibility (locked/unlocked state) of a list of
- * elements. This list of elements is assumed to be in vertical
- * display order (e.g. from lowest to highest offset).
- *
- * It uses intersection observers to ensure that changes that impact
- * visibility cause us to recalulate things (e.g. scrolling,
- * restyling).
- */
-export class VisibilityManager {
- #sizeManager = new SizeManager();
- #elements;
- #syncRAFToken;
-
- #intersectionObserver;
-
- #revealed = new Set();
- #observed = new Set();
-
- constructor(container) {
- this.#elements = container.children;
-
- // We want to sync if any element's size changes or if it becomes
- // more/less visible.
- this.#intersectionObserver = new IntersectionObserver(() => {
- this.scheduleSync();
- });
- this.#intersectionObserver.observe(container);
-
- for (const element of this.#elements) {
- this.#didAdd(element);
- }
- this.scheduleSync();
- }
-
- /**
- * Attempts to unlock a range of elements suitable for the current
- * viewport. This causes one forced layout.
- */
- #sync =
- () => {
- if (this.#elements.length === 0) {
- return;
- }
-
- // The basic idea is ...
- // The forced layout occurs at the start. We then use the laid out
- // coordinates (which are based on a mix of real sizes for
- // unlocked elements and the estimated sizes at the time of
- // locking for locked elements) to calculate a set of elements
- // which should be revealed. We use unlock/lock to move to this
- // new set of revealed elements. We will check in the next frame
- // whether we got it correct.
-
- // This causes a forced layout and takes measurements of all
- // currently revealed elements.
- this.#measureRevealed();
-
- // Compute the pixel bounds of what we would like to reveal. Then
- // find the elements corresponding to these bounds.
- // TODO(fergal): Use nearest scrolling ancestor?
- const desiredLow = 0 - window.innerHeight * BUFFER;
- const desiredHigh = window.innerHeight + window.innerHeight * BUFFER;
- const newBounds = this.#findElementBounds(desiredLow, desiredHigh);
- const newRevealed = newBounds.elementSet();
-
- // This should include all of the elements to be revealed and
- // also 1 element above and below those (if such elements
- // exist).
- const newObserved = new Set(newRevealed);
- if (newRevealed.size !== 0) {
- const p = newBounds.low.previousElementSibling;
- if (p) {
- newObserved.add(p);
- }
- const n = newBounds.high.nextElementSibling;
- if (n) {
- newObserved.add(n);
- }
- }
-
- // Having revealed what we hope will fill the screen. It
- // could be incorrect. Rather than measuring now and correcting it
- // which would involve an unknown number of forced layouts, we
- // come back next frame and try to make it better. We know we can
- // stop when we didn't hide or reveal any elements.
- if (this.#syncRevealed(newRevealed) + this.#syncObserved(newObserved) >
- 0) {
- this.scheduleSync();
- }
- }
-
- /**
- * Calls hide and reveal on child elements to take us to the new state.
- *
- * Returns the number of elements impacted.
- */
- #syncRevealed =
- newRevealed => {
- return sets.applyToDiffs(
- this.#revealed, newRevealed, e => this.#hide(e),
- e => this.#reveal(e));
- }
-
- /**
- * Calls observe and unobserve on child elements to take us to the new state.
- *
- * Returns the number of elements impacted.
- */
- #syncObserved =
- newObserved => {
- return sets.applyToDiffs(
- this.#observed, newObserved, e => this.#unobserve(e),
- e => this.#observe(e));
- }
-
- /**
- * Searches within the managed elements and returns an ElementBounds
- * object. This object may represent an empty range or a range whose low
- * element contains or is lower than |low| (or the lowest element
- * possible). Similarly for |high|. If the bounds do not intersect with any
- * elements then an EMPTY_ELEMENT_BOUNDS is returned, otherwise, if the
- * |low| (|high|) is entirely outside the area of the managed elements
- * then the low (high) part of the ElementBounds will be snapped to the
- * lowest (highest) element.
- *
- * @param {!number} low The lower bound to locate.
- * @param {!number} high The upper bound to locate.
- */
- #findElementBounds =
- (low, high) => {
- const lastIndex = this.#elements.length - 1;
- const lowest = this.#elements[0].getBoundingClientRect().top;
- const highest =
- this.#elements[lastIndex].getBoundingClientRect().bottom;
- if (highest < low || lowest > high) {
- return EMPTY_ELEMENT_BOUNDS;
- }
-
- let lowElement =
- findElement.findElement(this.#elements, low, findElement.BIAS_LOW);
- let highElement = findElement.findElement(
- this.#elements, high, findElement.BIAS_HIGH);
-
- if (lowElement === null) {
- lowElement = this.#elements[0];
- }
- if (highElement === null) {
- highElement = this.#elements[lastIndex];
- }
- return new ElementBounds(lowElement, highElement);
- }
-
- /**
- * Updates the size manager with all of the currently revealed
- * elements' sizes. This will cause a forced layout.
- */
- #measureRevealed =
- () => {
- for (const element of this.#revealed) {
- this.#sizeManager.measure(element);
- }
- }
-
- /**
- * Unlocks |element| so that it can be rendered.
- *
- * @param {!Element} element The element to reveal.
- */
- #reveal =
- element => {
- this.#revealed.add(element);
- this.#unlock(element);
- }
-
- /**
- * Observes |element| so that it coming on-/off-screen causes a sync.
- *
- * @param {!Element} element The element to observe.
- */
- #observe =
- element => {
- this.#intersectionObserver.observe(element);
- this.#observed.add(element);
- }
-
- #logLockingError =
- (operation, reason, element) => {
- // TODO: Figure out the LAPIs error/warning logging story.
- console.error( // eslint-disable-line no-console
- 'Rejected: ', operation, element, reason);
- }
-
- /**
- * Unlocks |element|.
- *
- * @param {!Element} element The element to unlock.
- */
- #unlock =
- element => {
- element.removeAttribute('rendersubtree');
- element.style.intrinsicSize = '';
- }
-
- /**
- * Locks |element| so that it cannot be rendered.
- *
- * @param {!Element} element The element to lock.
- */
- #hide =
- element => {
- this.#revealed.delete(element);
- const size = this.#sizeManager.getHopefulSize(element);
- element.setAttribute('rendersubtree', 'invisible activatable');
- element.style.intrinsicSize = `${LOCKED_WIDTH_PX}px ${size}px`;
- }
-
- /**
- * Unobserves |element| so that it coming on-/off-screen does not
- * cause a sync.
- *
- * @param {!Element} element The element to unobserve.
- */
- #unobserve =
- element => {
- this.#intersectionObserver.unobserve(element);
- this.#observed.delete(element);
- }
-
- /**
- * Notify the manager that |element| has been added to the list of
- * managed elements.
- *
- * @param {!Element} element The element that was added.
- */
- #didAdd =
- element => {
- // Added children should be invisible initially. We want to make them
- // invisible at this MutationObserver timing, so that there is no
- // frame where the browser is asked to render all of the children
- // (which could be a lot).
- this.#hide(element);
- }
-
- /**
- * Notify the manager that |element| has been removed from the list
- * of managed elements.
- *
- * @param {!Element} element The element that was removed.
- */
- #didRemove =
- element => {
- // Removed children should be made visible again. We should stop
- // observing them and discard any size info we have for them as it
- // may have become incorrect. We unlock unconditionally,
- // because it's simple and because it defends against
- // potential bugs in our own tracking of what is locked. Users
- // must not lock the children in the light tree, so there is
- // no concern about this having an impact on the users'
- // locking plans.
- this.#unlock(element);
- this.#revealed.delete(element);
- this.#unobserve(element);
- this.#sizeManager.remove(element);
- }
-
- /**
- * Ensures that @see #sync() will be called at the next animation frame.
- */
- scheduleSync() {
- if (this.#syncRAFToken !== undefined) {
- return;
- }
-
- this.#syncRAFToken = window.requestAnimationFrame(() => {
- this.#syncRAFToken = undefined;
- this.#sync();
- });
- }
-
- /**
- * Applys |records| generated by a mutation event to the manager.
- * This computes the elements that were newly added/removed and
- * notifies the managers for each.
- *
- * @param {!Object} records The mutations records.
- */
- applyMutationObserverRecords(records) {
- // It's unclear if we can support children which are not
- // elements. We cannot control their visibility using display
- // locking but we can just leave them alone.
- //
- // Relevant mutations are any additions or removals, including
- // non-elements and also elements that are removed and then
- // re-added as this may impact element bounds.
- let relevantMutation = false;
- const toRemove = new Set();
- for (const record of records) {
- relevantMutation = relevantMutation || record.removedNodes.length > 0;
- for (const node of record.removedNodes) {
- if (node.nodeType === Node.ELEMENT_NODE) {
- toRemove.add(node);
- }
- }
- }
-
- const toAdd = new Set();
- for (const record of records) {
- relevantMutation = relevantMutation || record.addedNodes.length > 0;
- for (const node of record.addedNodes) {
- if (node.nodeType === Node.ELEMENT_NODE) {
- if (toRemove.has(node)) {
- toRemove.delete(node);
- } else {
- toAdd.add(node);
- }
- }
- }
- }
- for (const node of toRemove) {
- this.#didRemove(node);
- }
- for (const node of toAdd) {
- this.#didAdd(node);
- }
-
- if (relevantMutation) {
- this.scheduleSync();
- }
- }
-}
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/OWNERS b/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/OWNERS
deleted file mode 100644
index b891d42816e..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-jsbell@chromium.org
-pwnall@chromium.org
-
-# TEAM: storage-dev@chromium.org
-# COMPONENT: Blink>Storage>IndexedDB
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/async_iterator.mjs b/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/async_iterator.mjs
deleted file mode 100644
index 91c4b4311a4..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/async_iterator.mjs
+++ /dev/null
@@ -1,94 +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.
-
-import {getNextKey, getNextKeyValuePair, HASNT_STARTED_YET} from './idb_utils.mjs';
-
-const _performDatabaseOperation = new WeakMap();
-const _lastKey = new WeakMap(); // undefined = got to the end;
- // HASNT_STARTED_YET = not yet started
-const _ongoingPromise = new WeakMap();
-const _mode = new WeakMap();
-
-const AsyncIteratorPrototype = Object.getPrototypeOf(
- Object.getPrototypeOf(async function*() {}).prototype);
-
-const StorageAreaAsyncIteratorPrototype = {
- __proto__: AsyncIteratorPrototype,
-
- [Symbol.toStringTag]: 'StorageArea AsyncIterator',
-
- next() {
- const performDatabaseOperation = _performDatabaseOperation.get(this);
- if (!performDatabaseOperation) {
- return Promise.reject(new TypeError('Invalid this value'));
- }
-
- // We need to avoid multiple concurrent calls into the main logic of next(),
- // which can happen if you manually manipulate the async iterator, i.e.
- // `iter.next(); iter.next()` with no `await`s. This is because until we
- // actually have the last key set correctly, such concurrent calls will use
- // the wrong value for lastKey.
-
- const currentOngoingPromise = _ongoingPromise.get(this);
- let thisNextPromise;
- if (currentOngoingPromise !== undefined) {
- thisNextPromise = currentOngoingPromise.then(
- () => getNextIterResult(this, performDatabaseOperation));
- } else {
- thisNextPromise = getNextIterResult(this, performDatabaseOperation);
- }
-
- _ongoingPromise.set(this, thisNextPromise);
- return thisNextPromise;
- },
-};
-
-Object.defineProperty(
- StorageAreaAsyncIteratorPrototype, Symbol.toStringTag,
- {writable: false, enumerable: false});
-
-function getNextIterResult(iter, performDatabaseOperation) {
- return performDatabaseOperation(async (transaction, store) => {
- const lastKey = _lastKey.get(iter);
- if (lastKey === undefined) {
- return {value: undefined, done: true};
- }
-
- const mode = _mode.get(iter);
- let key;
- let value;
- let iterResultValue;
- switch (mode) {
- case 'keys': {
- key = await getNextKey(store, lastKey);
- iterResultValue = key;
- break;
- }
- case 'values': {
- [key, value] = await getNextKeyValuePair(store, lastKey);
- iterResultValue = value;
- break;
- }
- case 'entries': {
- [key, value] = await getNextKeyValuePair(store, lastKey);
- iterResultValue = key === undefined ? undefined : [key, value];
- break;
- }
- }
-
- _lastKey.set(iter, key);
- _ongoingPromise.set(iter, undefined);
-
- return {value: iterResultValue, done: key === undefined};
- });
-}
-
-export function createStorageAreaAsyncIterator(mode, performDatabaseOperation) {
- const iter = Object.create(StorageAreaAsyncIteratorPrototype);
- _mode.set(iter, mode);
- _performDatabaseOperation.set(iter, performDatabaseOperation);
- _lastKey.set(iter, HASNT_STARTED_YET);
- _ongoingPromise.set(iter, undefined);
- return iter;
-}
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/idb_utils.mjs b/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/idb_utils.mjs
deleted file mode 100644
index 6c66ab95a02..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/idb_utils.mjs
+++ /dev/null
@@ -1,107 +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.
-
-export function promiseForRequest(request) {
- return new Promise((resolve, reject) => {
- request.onsuccess = () => resolve(request.result);
- request.onerror = () => reject(request.error);
- });
-}
-
-export function keyValuePairPromise(store, range) {
- const keyRequest = store.getKey(range);
- const valueRequest = store.get(range);
-
- return new Promise((resolve, reject) => {
- keyRequest.onerror = () => reject(keyRequest.error);
- valueRequest.onerror = () => reject(valueRequest.error);
- valueRequest.onsuccess = () =>
- resolve([keyRequest.result, valueRequest.result]);
- });
-}
-
-export function promiseForTransaction(transaction) {
- return new Promise((resolve, reject) => {
- transaction.oncomplete = () => resolve();
- transaction.onabort = () => reject(transaction.error);
- transaction.onerror = () => reject(transaction.error);
- });
-}
-
-export function throwForDisallowedKey(key) {
- if (!isAllowedAsAKey(key)) {
- throw new DOMException(
- 'The given value is not allowed as a key', 'DataError');
- }
-}
-
-export const HASNT_STARTED_YET = {};
-
-export function getNextKey(store, lastKey) {
- const range = getRangeForKey(lastKey);
- return promiseForRequest(store.getKey(range));
-}
-
-export function getNextKeyValuePair(store, lastKey) {
- const range = getRangeForKey(lastKey);
- return keyValuePairPromise(store, range);
-}
-
-function getRangeForKey(key) {
- if (key === HASNT_STARTED_YET) {
- // This is a stand-in for the spec's "unbounded" range, which isn't exposed
- // to JS currently. If we ever get keys that sort below -Infinity, e.g. per
- // https://github.com/w3c/IndexedDB/issues/76, then this needs to change.
- // Alternately, if we add better primitives to IDB for getting the first
- // key, per
- // https://github.com/WICG/kv-storage/issues/6#issuecomment-452054944, then
- // we could use those.
- return IDBKeyRange.lowerBound(-Infinity);
- }
- return IDBKeyRange.lowerBound(key, true);
-}
-
-function isAllowedAsAKey(value) {
- if (typeof value === 'number' || typeof value === 'string') {
- return true;
- }
-
- if (Array.isArray(value)) {
- return true;
- }
-
- if (isDate(value)) {
- return true;
- }
-
- if (ArrayBuffer.isView(value)) {
- return true;
- }
-
- if (isArrayBuffer(value)) {
- return true;
- }
-
- return false;
-}
-
-function isDate(value) {
- try {
- Date.prototype.getTime.call(value);
- return true;
- } catch {
- return false;
- }
-}
-
-const byteLengthGetter =
- Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, 'byteLength').get;
-function isArrayBuffer(value) {
- try {
- byteLengthGetter.call(value);
- return true;
- } catch {
- return false;
- }
-}
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/index.mjs b/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/index.mjs
deleted file mode 100644
index 45a01fdf206..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/index.mjs
+++ /dev/null
@@ -1,242 +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.
-
-import {createStorageAreaAsyncIterator} from './async_iterator.mjs';
-import {promiseForRequest, promiseForTransaction, throwForDisallowedKey} from './idb_utils.mjs';
-
-// Overall TODOs/spec-noncompliances:
-// - Susceptible to tampering of built-in prototypes and globals. We want to
-// work on tooling to ameliorate that.
-
-const DEFAULT_STORAGE_AREA_NAME = 'default';
-const DEFAULT_IDB_STORE_NAME = 'store';
-
-// TODO(crbug.com/977470): this should be handled via infrastructure that
-// avoids putting it in the module map entirely, not as a runtime check.
-// Several web platform tests fail because of this.
-if (!self.isSecureContext) {
- throw new TypeError('KV Storage is only available in secure contexts');
-}
-
-export class StorageArea {
- #backingStoreObject;
- #databaseName;
- #databasePromise;
-
- // TODO: Once private methods land in Chrome, this private field can
- // be refactored out with a private static method.
- #setPromise = promise => {
- this.#databasePromise = promise;
- };
-
- constructor(name) {
- this.#databaseName = `kv-storage:${name}`;
- }
-
- async set(key, value) {
- throwForDisallowedKey(key);
-
- return performDatabaseOperation(
- this.#databasePromise, this.#setPromise, this.#databaseName,
- 'readwrite', (transaction, store) => {
- if (value === undefined) {
- store.delete(key);
- } else {
- store.put(value, key);
- }
-
- return promiseForTransaction(transaction);
- });
- }
-
- async get(key) {
- throwForDisallowedKey(key);
-
- return performDatabaseOperation(
- this.#databasePromise, this.#setPromise, this.#databaseName, 'readonly',
- (transaction, store) => {
- return promiseForRequest(store.get(key));
- });
- }
-
- async delete(key) {
- throwForDisallowedKey(key);
-
- return performDatabaseOperation(
- this.#databasePromise, this.#setPromise, this.#databaseName,
- 'readwrite', (transaction, store) => {
- store.delete(key);
- return promiseForTransaction(transaction);
- });
- }
-
- async clear() {
- if (!this.#databasePromise) {
- // Don't try to delete, and clear the promise, while we're opening the
- // database; wait for that first.
- try {
- await this.#databasePromise;
- } catch {
- // If the database failed to initialize, then that's fine, we'll still
- // try to delete it.
- }
-
- this.#databasePromise = undefined;
- }
-
- return promiseForRequest(self.indexedDB.deleteDatabase(this.#databaseName));
- }
-
- keys() {
- // Brand check: throw if there is no such private field.
- // eslint-disable-next-line no-unused-expressions
- this.#databaseName;
-
- return createStorageAreaAsyncIterator(
- 'keys',
- steps => performDatabaseOperation(
- this.#databasePromise, this.#setPromise, this.#databaseName,
- 'readonly', steps));
- }
-
- values() {
- // Brand check: throw if there is no such private field.
- // eslint-disable-next-line no-unused-expressions
- this.#databaseName;
-
- return createStorageAreaAsyncIterator(
- 'values',
- steps => performDatabaseOperation(
- this.#databasePromise, this.#setPromise, this.#databaseName,
- 'readonly', steps));
- }
-
- entries() {
- // Brand check: throw if there is no such private field.
- // eslint-disable-next-line no-unused-expressions
- this.#databaseName;
-
- return createStorageAreaAsyncIterator(
- 'entries',
- steps => performDatabaseOperation(
- this.#databasePromise, this.#setPromise, this.#databaseName,
- 'readonly', steps));
- }
-
- get backingStore() {
- if (!this.#backingStoreObject) {
- this.#backingStoreObject = Object.freeze({
- database: this.#databaseName,
- store: DEFAULT_IDB_STORE_NAME,
- version: 1,
- });
- }
-
- return this.#backingStoreObject;
- }
-}
-
-StorageArea.prototype[Symbol.asyncIterator] = StorageArea.prototype.entries;
-StorageArea.prototype[Symbol.toStringTag] = 'StorageArea';
-
-// Override the defaults that are implied by using class declarations and
-// assignment, to be more Web IDL-ey.
-// https://github.com/heycam/webidl/issues/738 may modify these a bit.
-Object.defineProperties(StorageArea.prototype, {
- set: {enumerable: true},
- get: {enumerable: true},
- delete: {enumerable: true},
- clear: {enumerable: true},
- keys: {enumerable: true},
- values: {enumerable: true},
- entries: {enumerable: true},
- backingStore: {enumerable: true},
- [Symbol.asyncIterator]: {enumerable: false},
- [Symbol.toStringTag]: {writable: false, enumerable: false},
-});
-
-export default new StorageArea(DEFAULT_STORAGE_AREA_NAME);
-
-async function performDatabaseOperation(
- promise, setPromise, name, mode, steps) {
- if (!promise) {
- promise = initializeDatabasePromise(setPromise, name);
- }
-
- const database = await promise;
- const transaction = database.transaction(DEFAULT_IDB_STORE_NAME, mode);
- const store = transaction.objectStore(DEFAULT_IDB_STORE_NAME);
-
- const result = steps(transaction, store);
- transaction.commit();
- return result;
-}
-
-function initializeDatabasePromise(setPromise, databaseName) {
- const promise = new Promise((resolve, reject) => {
- const request = self.indexedDB.open(databaseName, 1);
-
- request.onsuccess = () => {
- const database = request.result;
-
- if (!checkDatabaseSchema(database, databaseName, reject)) {
- return;
- }
-
- database.onclose = () => setPromise(undefined);
- database.onversionchange = () => {
- database.close();
- setPromise(undefined);
- };
- resolve(database);
- };
-
- request.onerror = () => reject(request.error);
-
- request.onupgradeneeded = () => {
- try {
- request.result.createObjectStore(DEFAULT_IDB_STORE_NAME);
- } catch (e) {
- reject(e);
- }
- };
- });
- setPromise(promise);
- return promise;
-}
-
-function checkDatabaseSchema(database, databaseName, reject) {
- if (database.objectStoreNames.length !== 1) {
- reject(new DOMException(
- `KV storage database "${databaseName}" corrupted: there are ` +
- `${database.objectStoreNames.length} object stores, instead of ` +
- `the expected 1.`,
- 'InvalidStateError'));
- return false;
- }
-
- if (database.objectStoreNames[0] !== DEFAULT_IDB_STORE_NAME) {
- reject(new DOMException(
- `KV storage database "${databaseName}" corrupted: the object store ` +
- `is named "${database.objectStoreNames[0]}" instead of the ` +
- `expected "${DEFAULT_IDB_STORE_NAME}".`,
- 'InvalidStateError'));
- return false;
- }
-
- const transaction = database.transaction(DEFAULT_IDB_STORE_NAME, 'readonly');
- const store = transaction.objectStore(DEFAULT_IDB_STORE_NAME);
-
- if (store.autoIncrement !== false || store.keyPath !== null ||
- store.indexNames.length !== 0) {
- reject(new DOMException(
- `KV storage database "${databaseName}" corrupted: the ` +
- `"${DEFAULT_IDB_STORE_NAME}" object store has a non-default ` +
- `schema.`,
- 'InvalidStateError'));
- return false;
- }
-
- return true;
-}
diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/resources.grdp b/chromium/third_party/blink/renderer/core/script/resources/layered_api/resources.grdp
deleted file mode 100644
index 255d05543d1..00000000000
--- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/resources.grdp
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<grit-part>
- <!-- Layered API scripts. This file is generated by
- core/script/generate_lapi_grdp.py and shouldn't modified manually.
- A corresponding header file (layered_api_resources.h) is also generated.
- The paths are relative to the main grd file, i.e.
- third_party/blink/public/blink_resources.grd.
- -->
- <include name="IDR_LAYERED_API_BLANK_INDEX_MJS" file="../renderer/core/script/resources/layered_api/blank/index.mjs" type="BINDATA" skip_minify="true" compress="gzip"/>
- <include name="IDR_LAYERED_API_ELEMENTS_INTERNAL_REFLECTION_MJS" file="../renderer/core/script/resources/layered_api/elements/internal/reflection.mjs" type="BINDATA" skip_minify="true" compress="gzip"/>
- <include name="IDR_LAYERED_API_ELEMENTS_SWITCH_FACE_UTILS_MJS" file="../renderer/core/script/resources/layered_api/elements/switch/face_utils.mjs" type="BINDATA" skip_minify="true" compress="gzip"/>
- <include name="IDR_LAYERED_API_ELEMENTS_SWITCH_INDEX_MJS" file="../renderer/core/script/resources/layered_api/elements/switch/index.mjs" type="BINDATA" skip_minify="true" compress="gzip"/>
- <include name="IDR_LAYERED_API_ELEMENTS_SWITCH_STYLE_MJS" file="../renderer/core/script/resources/layered_api/elements/switch/style.mjs" type="BINDATA" skip_minify="true" compress="gzip"/>
- <include name="IDR_LAYERED_API_ELEMENTS_SWITCH_TRACK_MJS" file="../renderer/core/script/resources/layered_api/elements/switch/track.mjs" type="BINDATA" skip_minify="true" compress="gzip"/>
- <include name="IDR_LAYERED_API_ELEMENTS_TOAST_INDEX_MJS" file="../renderer/core/script/resources/layered_api/elements/toast/index.mjs" type="BINDATA" skip_minify="true" compress="gzip"/>
- <include name="IDR_LAYERED_API_ELEMENTS_VIRTUAL_SCROLLER_FIND_ELEMENT_MJS" file="../renderer/core/script/resources/layered_api/elements/virtual-scroller/find-element.mjs" type="BINDATA" skip_minify="true" compress="gzip"/>
- <include name="IDR_LAYERED_API_ELEMENTS_VIRTUAL_SCROLLER_INDEX_MJS" file="../renderer/core/script/resources/layered_api/elements/virtual-scroller/index.mjs" type="BINDATA" skip_minify="true" compress="gzip"/>
- <include name="IDR_LAYERED_API_ELEMENTS_VIRTUAL_SCROLLER_SETS_MJS" file="../renderer/core/script/resources/layered_api/elements/virtual-scroller/sets.mjs" type="BINDATA" skip_minify="true" compress="gzip"/>
- <include name="IDR_LAYERED_API_ELEMENTS_VIRTUAL_SCROLLER_VISIBILITY_MANAGER_MJS" file="../renderer/core/script/resources/layered_api/elements/virtual-scroller/visibility-manager.mjs" type="BINDATA" skip_minify="true" compress="gzip"/>
- <include name="IDR_LAYERED_API_KV_STORAGE_ASYNC_ITERATOR_MJS" file="../renderer/core/script/resources/layered_api/kv-storage/async_iterator.mjs" type="BINDATA" skip_minify="true" compress="gzip"/>
- <include name="IDR_LAYERED_API_KV_STORAGE_IDB_UTILS_MJS" file="../renderer/core/script/resources/layered_api/kv-storage/idb_utils.mjs" type="BINDATA" skip_minify="true" compress="gzip"/>
- <include name="IDR_LAYERED_API_KV_STORAGE_INDEX_MJS" file="../renderer/core/script/resources/layered_api/kv-storage/index.mjs" type="BINDATA" skip_minify="true" compress="gzip"/>
-</grit-part>
diff --git a/chromium/third_party/blink/renderer/core/script/script.cc b/chromium/third_party/blink/renderer/core/script/script.cc
new file mode 100644
index 00000000000..bfa6a5fdf68
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/script/script.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/script/script.h"
+
+#include "base/optional.h"
+
+namespace blink {
+
+base::Optional<mojom::ScriptType> Script::ParseScriptType(
+ const String& script_type) {
+ if (script_type == "classic")
+ return mojom::ScriptType::kClassic;
+ if (script_type == "module")
+ return mojom::ScriptType::kModule;
+ return base::nullopt;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/script/script.h b/chromium/third_party/blink/renderer/core/script/script.h
index 1f633a9e6b2..8e0ba7ce576 100644
--- a/chromium/third_party/blink/renderer/core/script/script.h
+++ b/chromium/third_party/blink/renderer/core/script/script.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_SCRIPT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_SCRIPT_H_
+#include "base/optional.h"
#include "third_party/blink/public/mojom/script/script_type.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -26,6 +27,8 @@ class CORE_EXPORT Script : public GarbageCollected<Script> {
virtual ~Script() {}
virtual mojom::ScriptType GetScriptType() const = 0;
+ static base::Optional<mojom::ScriptType> ParseScriptType(
+ const String& script_type);
// https://html.spec.whatwg.org/C/#run-a-classic-script
// or
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 b3d7d916260..875ac0468e9 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
@@ -38,6 +38,7 @@ ScriptLoader* ScriptLoaderFromElement(Element*);
class CORE_EXPORT ScriptElementBase : public GarbageCollectedMixin {
public:
+ enum class Type { kHTMLScriptElement, kSVGScriptElement };
virtual bool AsyncAttributeValue() const = 0;
virtual String CharsetAttributeValue() const = 0;
virtual String CrossOriginAttributeValue() const = 0;
@@ -52,7 +53,11 @@ class CORE_EXPORT ScriptElementBase : public GarbageCollectedMixin {
virtual String ReferrerPolicyAttributeValue() const = 0;
virtual String ImportanceAttributeValue() const = 0;
- virtual String TextFromChildren() = 0;
+ // This implements https://dom.spec.whatwg.org/#concept-child-text-content
+ virtual String ChildTextContent() = 0;
+ // This supports
+ // https://w3c.github.io/webappsec-trusted-types/dist/spec/#prepare-script-url-and-text
+ virtual String ScriptTextInternalSlot() const = 0;
virtual bool HasSourceAttribute() const = 0;
virtual bool IsConnected() const = 0;
virtual bool HasChildren() const = 0;
@@ -72,6 +77,8 @@ class CORE_EXPORT ScriptElementBase : public GarbageCollectedMixin {
virtual void DispatchLoadEvent() = 0;
virtual void DispatchErrorEvent() = 0;
+ virtual Type GetScriptElementType() = 0;
+
protected:
ScriptLoader* InitializeScriptLoader(bool parser_inserted,
bool already_started);
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 5aad7de62b8..211d52589e8 100644
--- a/chromium/third_party/blink/renderer/core/script/script_loader.cc
+++ b/chromium/third_party/blink/renderer/core/script/script_loader.cc
@@ -24,6 +24,7 @@
#include "third_party/blink/renderer/core/script/script_loader.h"
+#include "base/feature_list.h"
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink.h"
@@ -35,6 +36,7 @@
#include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html/imports/html_import.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/core/html_names.h"
@@ -53,7 +55,9 @@
#include "third_party/blink/renderer/core/script/script_element_base.h"
#include "third_party/blink/renderer/core/script/script_runner.h"
#include "third_party/blink/renderer/core/svg_names.h"
+#include "third_party/blink/renderer/core/trustedtypes/trusted_types_util.h"
#include "third_party/blink/renderer/platform/bindings/parkable_string.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/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h"
@@ -249,8 +253,8 @@ network::mojom::CredentialsMode ScriptLoader::ModuleScriptCredentialsMode(
bool ShouldBlockSyncScriptForFeaturePolicy(const ScriptElementBase* element,
mojom::ScriptType script_type,
bool parser_inserted) {
- if (element->GetDocument().GetFeaturePolicy()->IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kSyncScript)) {
+ if (element->GetDocument().IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kSyncScript)) {
return false;
}
@@ -289,7 +293,15 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position,
non_blocking_ = true;
// <spec step="4">Let source text be the element's child text content.</spec>
- const String source_text = element_->TextFromChildren();
+ //
+ // Trusted Types additionally requires:
+ // https://w3c.github.io/webappsec-trusted-types/dist/spec/#slot-value-verification
+ // - Step 4: Execute the Prepare the script URL and text algorithm upon the
+ // script element. If that algorithm threw an error, then return. The
+ // script is not executed.
+ // - Step 5: Let source text be the element’s [[ScriptText]] internal slot
+ // value.
+ const String source_text = GetScriptText();
// <spec step="5">If the element has no src attribute, and source text is the
// empty string, then return. The script is not executed.</spec>
@@ -386,8 +398,7 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position,
// executed. [CSP]</spec>
if (!element_->HasSourceAttribute() &&
!element_->AllowInlineScriptForCSP(element_->GetNonceForElement(),
- position.line_,
- element_->TextFromChildren())) {
+ position.line_, source_text)) {
return false;
}
@@ -398,7 +409,7 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position,
// This FeaturePolicy is still in the process of being added to the spec.
if (ShouldBlockSyncScriptForFeaturePolicy(element_.Get(), GetScriptType(),
parser_inserted_)) {
- element_document.AddConsoleMessage(ConsoleMessage::Create(
+ element_document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kError,
"Synchronous script execution is disabled by Feature Policy"));
@@ -428,11 +439,13 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position,
IntegrityMetadataSet integrity_metadata;
if (!integrity_attr.IsEmpty()) {
SubresourceIntegrity::IntegrityFeatures integrity_features =
- SubresourceIntegrityHelper::GetFeatures(&element_document);
+ SubresourceIntegrityHelper::GetFeatures(
+ element_document.ToExecutionContext());
SubresourceIntegrity::ReportInfo report_info;
SubresourceIntegrity::ParseIntegrityAttribute(
integrity_attr, integrity_features, integrity_metadata, &report_info);
- SubresourceIntegrityHelper::DoReport(element_document, report_info);
+ SubresourceIntegrityHelper::DoReport(*element_document.ToExecutionContext(),
+ report_info);
}
// <spec step="20">Let referrer policy be the current state of the element's
@@ -490,7 +503,7 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position,
Modulator* modulator = Modulator::From(
ToScriptStateForMainWorld(context_document->GetFrame()));
if (!modulator->IsAcquiringImportMaps()) {
- element_document.AddConsoleMessage(ConsoleMessage::Create(
+ element_document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kError,
"An import map is added after module script load was triggered."));
@@ -540,7 +553,7 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position,
// <spec step="24.6">Switch on the script's type:</spec>
if (is_import_map) {
// TODO(crbug.com/922212): Implement external import maps.
- element_document.AddConsoleMessage(ConsoleMessage::Create(
+ element_document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kError,
"External import maps are not yet supported."));
@@ -572,9 +585,7 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position,
// Fetch a classic script given url, settings object, options, classic
// script CORS setting, and encoding.</spec>
Document* document_for_origin = &element_document;
- if (base::FeatureList::IsEnabled(
- features::kHtmlImportsRequestInitiatorLock) &&
- element_document.ImportsController()) {
+ if (element_document.ImportsController()) {
document_for_origin = context_document;
}
FetchClassicScript(url, *document_for_origin, options, cross_origin,
@@ -612,7 +623,7 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position,
// <spec step="24.1">Let src be the value of the element's src
// attribute.</spec>
//
- // This step is done later as ScriptElementBase::TextFromChildren():
+ // This step is done later as ScriptElementBase::ChildTextContent():
// - in ScriptLoader::PrepareScript() (Step 26, 6th Clause),
// - in HTMLParserScriptRunner::ProcessScriptElementInternal()
// (Duplicated code of Step 26, 6th Clause),
@@ -634,8 +645,8 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position,
// 1. Let import map parse result be the result of create an import map
// parse result, given source text, base URL and settings object. [spec
// text]
- PendingImportMap* pending_import_map = PendingImportMap::CreateInline(
- *element_, element_->TextFromChildren(), base_url);
+ PendingImportMap* pending_import_map =
+ PendingImportMap::CreateInline(*element_, source_text, base_url);
// Because we currently support inline import maps only, the pending
// import map is ready immediately and thus we call `register an import
@@ -663,8 +674,8 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position,
}
prepared_pending_script_ = ClassicPendingScript::CreateInline(
- element_, position, base_url, element_->TextFromChildren(),
- script_location_type, options);
+ element_, position, base_url, source_text, script_location_type,
+ options);
// <spec step="25.2.A.2">Set the script's script to script.</spec>
//
@@ -690,10 +701,10 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position,
// <spec label="fetch-an-inline-module-script-graph" step="1">Let script
// be the result of creating a JavaScript module script using source
// text, settings object, base URL, and options.</spec>
- ModuleScript* module_script = JSModuleScript::Create(
- ParkableString(element_->TextFromChildren().Impl()), nullptr,
- ScriptSourceLocationType::kInline, modulator, source_url, base_url,
- options, position);
+ ModuleScript* module_script =
+ JSModuleScript::Create(ParkableString(source_text.Impl()), nullptr,
+ ScriptSourceLocationType::kInline, modulator,
+ source_url, base_url, options, position);
// <spec label="fetch-an-inline-module-script-graph" step="2">If script
// is null, asynchronously complete this algorithm with null, and abort
@@ -710,7 +721,8 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position,
MakeGarbageCollected<ModulePendingScriptTreeClient>();
modulator->FetchDescendantsForInlineScript(
module_script, fetch_client_settings_object_fetcher,
- mojom::RequestContextType::SCRIPT, module_tree_client);
+ mojom::RequestContextType::SCRIPT,
+ network::mojom::RequestDestination::kScript, module_tree_client);
prepared_pending_script_ = MakeGarbageCollected<ModulePendingScript>(
element_, module_tree_client, is_external_script_);
break;
@@ -756,7 +768,7 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position,
if (GetScriptType() == mojom::ScriptType::kClassic &&
element_->HasSourceAttribute() &&
context_document->GetFrame()->ShouldForceDeferScript() &&
- context_document->IsHTMLDocument() && parser_inserted_ &&
+ IsA<HTMLDocument>(context_document) && parser_inserted_ &&
!element_->AsyncAttributeValue()) {
// In terms of ScriptLoader flags, force deferred scripts behave like
// parser-blocking scripts, except that |force_deferred_| is set.
@@ -848,7 +860,7 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position,
// Check for inline script that should be force deferred.
if (context_document->GetFrame()->ShouldForceDeferScript() &&
- context_document->IsHTMLDocument() && parser_inserted_) {
+ IsA<HTMLDocument>(context_document) && parser_inserted_) {
force_deferred_ = true;
will_be_parser_executed_ = true;
return true;
@@ -927,7 +939,8 @@ void ScriptLoader::FetchModuleScriptTree(
auto* module_tree_client =
MakeGarbageCollected<ModulePendingScriptTreeClient>();
modulator->FetchTree(url, fetch_client_settings_object_fetcher,
- mojom::RequestContextType::SCRIPT, options,
+ mojom::RequestContextType::SCRIPT,
+ network::mojom::RequestDestination::kScript, options,
ModuleScriptCustomFetchType::kNone, module_tree_client);
prepared_pending_script_ = MakeGarbageCollected<ModulePendingScript>(
element_, module_tree_client, is_external_script_);
@@ -962,7 +975,9 @@ void ScriptLoader::PendingScriptFinished(PendingScript* pending_script) {
// memory cache not be in the HTTPCache. So we keep |resource_keep_alive_| to
// keep the resource in the memory cache.
if (resource_keep_alive_ &&
- !resource_keep_alive_->GetResponse().IsSignedExchangeInnerResponse()) {
+ !resource_keep_alive_->GetResponse().IsSignedExchangeInnerResponse() &&
+ !base::FeatureList::IsEnabled(
+ blink::features::kKeepScriptResourceAlive)) {
resource_keep_alive_ = nullptr;
}
@@ -1016,4 +1031,21 @@ ScriptLoader::GetPendingScriptIfControlledByScriptRunnerForCrossDocMove() {
return pending_script_;
}
+String ScriptLoader::GetScriptText() const {
+ // Step 3 of
+ // https://w3c.github.io/webappsec-trusted-types/dist/spec/#abstract-opdef-prepare-the-script-url-and-text
+ // called from § 4.1.3.3, step 4 of
+ // https://w3c.github.io/webappsec-trusted-types/dist/spec/#slot-value-verification
+ // This will return the [[ScriptText]] internal slot value after that step,
+ // or a null string if the the Trusted Type algorithm threw an error.
+ String child_text_content = element_->ChildTextContent();
+ DCHECK(!child_text_content.IsNull());
+ String script_text_internal_slot = element_->ScriptTextInternalSlot();
+ if (child_text_content == script_text_internal_slot)
+ return child_text_content;
+ return GetStringForScriptExecution(child_text_content,
+ element_->GetScriptElementType(),
+ element_->GetDocument().ContextDocument());
+}
+
} // namespace blink
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 22b68380c39..b0aee119e05 100644
--- a/chromium/third_party/blink/renderer/core/script/script_loader.h
+++ b/chromium/third_party/blink/renderer/core/script/script_loader.h
@@ -140,6 +140,9 @@ class CORE_EXPORT ScriptLoader final : public GarbageCollected<ScriptLoader>,
// PendingScriptClient
void PendingScriptFinished(PendingScript*) override;
+ // Get the effective script text (after Trusted Types checking).
+ String GetScriptText() const;
+
Member<ScriptElementBase> element_;
// https://html.spec.whatwg.org/C/#script-processing-model
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 6965a18ccf6..9a81bdc25bd 100644
--- a/chromium/third_party/blink/renderer/core/script/script_runner.cc
+++ b/chromium/third_party/blink/renderer/core/script/script_runner.cc
@@ -35,13 +35,16 @@
#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
ScriptRunner::ScriptRunner(Document* document)
- : document_(document),
+ : ExecutionContextLifecycleStateObserver(document),
+ document_(document),
task_runner_(document->GetTaskRunner(TaskType::kNetworking)) {
DCHECK(document);
+ UpdateStateIfNeeded();
}
void ScriptRunner::QueueScriptForExecution(PendingScript* pending_script) {
@@ -70,18 +73,17 @@ void ScriptRunner::PostTask(const base::Location& web_trace_location) {
WTF::Bind(&ScriptRunner::ExecuteTask, WrapWeakPersistent(this)));
}
-void ScriptRunner::Suspend() {
- is_suspended_ = true;
-}
-
-void ScriptRunner::Resume() {
- DCHECK(is_suspended_);
-
- is_suspended_ = false;
+void ScriptRunner::ContextLifecycleStateChanged(
+ mojom::FrameLifecycleState state) {
if (!IsExecutionSuspended())
PostTasksForReadyScripts(FROM_HERE);
}
+bool ScriptRunner::IsExecutionSuspended() {
+ return !GetExecutionContext() || GetExecutionContext()->IsContextPaused() ||
+ is_force_deferred_;
+}
+
void ScriptRunner::SetForceDeferredExecution(bool force_deferred) {
DCHECK(force_deferred != is_force_deferred_);
@@ -260,6 +262,7 @@ void ScriptRunner::ExecuteTask() {
}
void ScriptRunner::Trace(Visitor* visitor) {
+ ExecutionContextLifecycleStateObserver::Trace(visitor);
visitor->Trace(document_);
visitor->Trace(pending_in_order_scripts_);
visitor->Trace(pending_async_scripts_);
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 ad3084aede0..08362220752 100644
--- a/chromium/third_party/blink/renderer/core/script/script_runner.h
+++ b/chromium/third_party/blink/renderer/core/script/script_runner.h
@@ -30,6 +30,7 @@
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/deque.h"
@@ -41,8 +42,12 @@ class Document;
class PendingScript;
class ScriptLoader;
-class CORE_EXPORT ScriptRunner final : public GarbageCollected<ScriptRunner>,
- public NameClient {
+class CORE_EXPORT ScriptRunner final
+ : public GarbageCollected<ScriptRunner>,
+ public ExecutionContextLifecycleStateObserver,
+ public NameClient {
+ USING_GARBAGE_COLLECTED_MIXIN(ScriptRunner);
+
public:
explicit ScriptRunner(Document*);
@@ -51,14 +56,19 @@ class CORE_EXPORT ScriptRunner final : public GarbageCollected<ScriptRunner>,
return !pending_in_order_scripts_.IsEmpty() ||
!pending_async_scripts_.IsEmpty();
}
- void Suspend();
- void Resume();
void SetForceDeferredExecution(bool force_deferred);
void NotifyScriptReady(PendingScript*);
+ void ContextLifecycleStateChanged(mojom::FrameLifecycleState) final;
+ void ContextDestroyed() final {}
+
static void MovePendingScript(Document&, Document&, ScriptLoader*);
- void Trace(Visitor*);
+ void SetTaskRunnerForTesting(base::SingleThreadTaskRunner* task_runner) {
+ task_runner_ = task_runner;
+ }
+
+ void Trace(Visitor*) override;
const char* NameInHeapSnapshot() const override { return "ScriptRunner"; }
private:
@@ -81,7 +91,7 @@ class CORE_EXPORT ScriptRunner final : public GarbageCollected<ScriptRunner>,
void ExecuteTask();
- bool IsExecutionSuspended() { return is_suspended_ || is_force_deferred_; }
+ bool IsExecutionSuspended();
Member<Document> document_;
@@ -96,8 +106,6 @@ class CORE_EXPORT ScriptRunner final : public GarbageCollected<ScriptRunner>,
int number_of_in_order_scripts_with_pending_notification_ = 0;
- bool is_suspended_ = false;
-
// Whether script execution is suspended due to there being force deferred
// scripts that have not yet been executed. This is expected to be in sync
// with HTMLParserScriptRunner::suspended_async_script_execution_.
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 93fe88a8522..27fd139e173 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
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/core/script/mock_script_element_base.h"
#include "third_party/blink/renderer/core/script/pending_script.h"
#include "third_party/blink/renderer/core/script/script.h"
+#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
@@ -76,14 +77,16 @@ class MockPendingScript : public PendingScript {
class ScriptRunnerTest : public testing::Test {
public:
- ScriptRunnerTest() : document_(MakeGarbageCollected<Document>()) {}
+ ScriptRunnerTest()
+ : page_holder_(std::make_unique<DummyPageHolder>()),
+ document_(&page_holder_->GetDocument()) {}
void SetUp() override {
- // We have to create ScriptRunner after initializing platform, because we
- // need Platform::current()->currentThread()->scheduler()->
- // loadingTaskRunner() to be initialized before creating ScriptRunner to
- // save it in constructor.
script_runner_ = MakeGarbageCollected<ScriptRunner>(document_.Get());
+ // Give ScriptRunner a task runner that platform_ will pump in
+ // RunUntilIdle()/RunSingleTask().
+ script_runner_->SetTaskRunnerForTesting(
+ Thread::Current()->GetTaskRunner().get());
RuntimeCallStats::SetRuntimeCallStatsForTesting();
}
void TearDown() override {
@@ -101,6 +104,7 @@ class ScriptRunnerTest : public testing::Test {
script_runner_->QueueScriptForExecution(pending_script);
}
+ std::unique_ptr<DummyPageHolder> page_holder_;
Persistent<Document> document_;
Persistent<ScriptRunner> script_runner_;
WTF::Vector<int> order_;
@@ -327,8 +331,10 @@ TEST_F(ScriptRunnerTest, ResumeAndSuspend_InOrder) {
NotifyScriptReady(pending_script3);
platform_->RunSingleTask();
- script_runner_->Suspend();
- script_runner_->Resume();
+ script_runner_->ContextLifecycleStateChanged(
+ mojom::FrameLifecycleState::kPaused);
+ script_runner_->ContextLifecycleStateChanged(
+ mojom::FrameLifecycleState::kRunning);
platform_->RunUntilIdle();
// Make sure elements are correct and in right order.
@@ -356,8 +362,10 @@ TEST_F(ScriptRunnerTest, ResumeAndSuspend_Async) {
.WillOnce(InvokeWithoutArgs([this] { order_.push_back(3); }));
platform_->RunSingleTask();
- script_runner_->Suspend();
- script_runner_->Resume();
+ script_runner_->ContextLifecycleStateChanged(
+ mojom::FrameLifecycleState::kPaused);
+ script_runner_->ContextLifecycleStateChanged(
+ mojom::FrameLifecycleState::kRunning);
platform_->RunUntilIdle();
// Make sure elements are correct.
@@ -400,12 +408,14 @@ TEST_F(ScriptRunnerTest, SetForceDeferredAndResumeAndSuspend) {
platform_->RunSingleTask();
ASSERT_EQ(0u, order_.size());
- script_runner_->Suspend();
+ script_runner_->ContextLifecycleStateChanged(
+ mojom::FrameLifecycleState::kPaused);
platform_->RunSingleTask();
ASSERT_EQ(0u, order_.size());
- // Resume will not execute script while still in ForceDeferred state.
- script_runner_->Resume();
+ // Resuming will not execute script while still in ForceDeferred state.
+ script_runner_->ContextLifecycleStateChanged(
+ mojom::FrameLifecycleState::kRunning);
platform_->RunUntilIdle();
ASSERT_EQ(0u, order_.size());
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 ca8e5b58153..ddbd7b22482 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
@@ -6,15 +6,65 @@
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_css_style_sheet_init.h"
+#include "third_party/blink/renderer/core/css/css_style_sheet.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/loader/modulescript/module_script_creation_params.h"
#include "third_party/blink/renderer/core/script/modulator.h"
#include "third_party/blink/renderer/core/script/module_record_resolver.h"
+#include "third_party/blink/renderer/platform/bindings/to_v8.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/text/text_position.h"
#include "v8/include/v8.h"
namespace blink {
+// https://whatpr.org/html/4898/webappapis.html#creating-a-css-module-script
+ValueWrapperSyntheticModuleScript*
+ValueWrapperSyntheticModuleScript::CreateCSSWrapperSyntheticModuleScript(
+ const base::Optional<ModuleScriptCreationParams>& params,
+ Modulator* settings_object) {
+ DCHECK(settings_object->HasValidContext());
+ ScriptState* script_state = settings_object->GetScriptState();
+ ScriptState::Scope scope(script_state);
+ v8::Isolate* isolate = script_state->GetIsolate();
+ ExceptionState exception_state(isolate, ExceptionState::kExecutionContext,
+ "ModuleScriptLoader",
+ "CreateCSSWrapperSyntheticModuleScript");
+ ExecutionContext* execution_context = ExecutionContext::From(script_state);
+ Document* context_document = Document::DynamicFrom(execution_context);
+ if (!context_document) {
+ v8::Local<v8::Value> error = V8ThrowException::CreateTypeError(
+ isolate, "Cannot create CSS Module in non-document context");
+ return ValueWrapperSyntheticModuleScript::CreateWithError(
+ v8::Local<v8::Value>(), settings_object, params->GetResponseUrl(),
+ KURL(), ScriptFetchOptions(), error);
+ }
+ CSSStyleSheetInit* init = CSSStyleSheetInit::Create();
+ CSSStyleSheet* style_sheet =
+ CSSStyleSheet::Create(*context_document, init, exception_state);
+ if (exception_state.HadException()) {
+ v8::Local<v8::Value> error = exception_state.GetException();
+ exception_state.ClearException();
+ return ValueWrapperSyntheticModuleScript::CreateWithError(
+ v8::Local<v8::Value>(), settings_object, params->GetResponseUrl(),
+ KURL(), ScriptFetchOptions(), error);
+ }
+ style_sheet->replaceSync(params->GetSourceText().ToString(), exception_state);
+ if (exception_state.HadException()) {
+ v8::Local<v8::Value> error = exception_state.GetException();
+ exception_state.ClearException();
+ return ValueWrapperSyntheticModuleScript::CreateWithError(
+ v8::Local<v8::Value>(), settings_object, params->GetResponseUrl(),
+ KURL(), ScriptFetchOptions(), error);
+ }
+ v8::Local<v8::Value> v8_value_stylesheet = ToV8(style_sheet, script_state);
+ return ValueWrapperSyntheticModuleScript::CreateWithDefaultExport(
+ v8_value_stylesheet, settings_object, params->GetResponseUrl(), KURL(),
+ ScriptFetchOptions());
+}
+
ValueWrapperSyntheticModuleScript*
ValueWrapperSyntheticModuleScript::CreateJSONWrapperSyntheticModuleScript(
const base::Optional<ModuleScriptCreationParams>& params,
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 74216837fd7..1c51738e900 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
@@ -26,6 +26,11 @@ class CORE_EXPORT ValueWrapperSyntheticModuleScript final
: public ModuleScript {
public:
static ValueWrapperSyntheticModuleScript*
+ CreateCSSWrapperSyntheticModuleScript(
+ const base::Optional<ModuleScriptCreationParams>& params,
+ Modulator* settings_object);
+
+ static ValueWrapperSyntheticModuleScript*
CreateJSONWrapperSyntheticModuleScript(
const base::Optional<ModuleScriptCreationParams>& params,
Modulator* settings_object);
@@ -65,7 +70,7 @@ class CORE_EXPORT ValueWrapperSyntheticModuleScript final
v8::Local<v8::Context> context,
v8::Local<v8::Module> module);
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
TraceWrapperV8Reference<v8::Value> export_value_;
diff --git a/chromium/third_party/blink/renderer/core/script/worker_modulator_impl.cc b/chromium/third_party/blink/renderer/core/script/worker_modulator_impl.cc
index 10b82a77049..6541c78624b 100644
--- a/chromium/third_party/blink/renderer/core/script/worker_modulator_impl.cc
+++ b/chromium/third_party/blink/renderer/core/script/worker_modulator_impl.cc
@@ -18,33 +18,37 @@ WorkerModulatorImpl::WorkerModulatorImpl(ScriptState* script_state)
: ModulatorImplBase(script_state) {}
ModuleScriptFetcher* WorkerModulatorImpl::CreateModuleScriptFetcher(
- ModuleScriptCustomFetchType custom_fetch_type) {
+ ModuleScriptCustomFetchType custom_fetch_type,
+ util::PassKey<ModuleScriptLoader> pass_key) {
auto* global_scope = To<WorkerGlobalScope>(GetExecutionContext());
switch (custom_fetch_type) {
case ModuleScriptCustomFetchType::kNone:
- return MakeGarbageCollected<DocumentModuleScriptFetcher>();
+ return MakeGarbageCollected<DocumentModuleScriptFetcher>(pass_key);
case ModuleScriptCustomFetchType::kWorkerConstructor:
- return MakeGarbageCollected<WorkerModuleScriptFetcher>(global_scope);
+ return MakeGarbageCollected<WorkerModuleScriptFetcher>(global_scope,
+ pass_key);
case ModuleScriptCustomFetchType::kWorkletAddModule:
break;
case ModuleScriptCustomFetchType::kInstalledServiceWorker:
return MakeGarbageCollected<InstalledServiceWorkerModuleScriptFetcher>(
- global_scope);
+ global_scope, pass_key);
}
NOTREACHED();
return nullptr;
}
bool WorkerModulatorImpl::IsDynamicImportForbidden(String* reason) {
- // TODO(nhiroki): Remove this flag check once module loading for
- // DedicatedWorker is enabled by default (https://crbug.com/680046).
- if (GetExecutionContext()->IsDedicatedWorkerGlobalScope() &&
- RuntimeEnabledFeatures::ModuleDedicatedWorkerEnabled()) {
+ if (GetExecutionContext()->IsDedicatedWorkerGlobalScope())
+ return false;
+
+ // TODO(https://crbug.com/824646): Remove this flag check once module loading
+ // for SharedWorker is enabled by default.
+ if (GetExecutionContext()->IsSharedWorkerGlobalScope() &&
+ RuntimeEnabledFeatures::ModuleSharedWorkerEnabled()) {
return false;
}
- // TODO(nhiroki): Support module loading for SharedWorker and Service Worker.
- // (https://crbug.com/680046)
+ // TODO(https://crbug.com/824647): Support module loading for Service Worker.
*reason =
"Module scripts are not supported on WorkerGlobalScope yet (see "
"https://crbug.com/680046).";
diff --git a/chromium/third_party/blink/renderer/core/script/worker_modulator_impl.h b/chromium/third_party/blink/renderer/core/script/worker_modulator_impl.h
index 205951cdfc5..3e90e7128b7 100644
--- a/chromium/third_party/blink/renderer/core/script/worker_modulator_impl.h
+++ b/chromium/third_party/blink/renderer/core/script/worker_modulator_impl.h
@@ -21,7 +21,8 @@ class WorkerModulatorImpl final : public ModulatorImplBase {
// Implements ModulatorImplBase.
ModuleScriptFetcher* CreateModuleScriptFetcher(
- ModuleScriptCustomFetchType) override;
+ ModuleScriptCustomFetchType,
+ util::PassKey<ModuleScriptLoader> pass_key) override;
private:
// Implements ModulatorImplBase.
diff --git a/chromium/third_party/blink/renderer/core/script/worklet_modulator_impl.cc b/chromium/third_party/blink/renderer/core/script/worklet_modulator_impl.cc
index 57fc266b056..7b77edd0b4e 100644
--- a/chromium/third_party/blink/renderer/core/script/worklet_modulator_impl.cc
+++ b/chromium/third_party/blink/renderer/core/script/worklet_modulator_impl.cc
@@ -13,12 +13,13 @@ WorkletModulatorImpl::WorkletModulatorImpl(ScriptState* script_state)
: ModulatorImplBase(script_state) {}
ModuleScriptFetcher* WorkletModulatorImpl::CreateModuleScriptFetcher(
- ModuleScriptCustomFetchType custom_fetch_type) {
+ ModuleScriptCustomFetchType custom_fetch_type,
+ util::PassKey<ModuleScriptLoader> pass_key) {
DCHECK_EQ(ModuleScriptCustomFetchType::kWorkletAddModule, custom_fetch_type);
WorkletGlobalScope* global_scope =
To<WorkletGlobalScope>(GetExecutionContext());
return MakeGarbageCollected<WorkletModuleScriptFetcher>(
- global_scope->GetModuleResponsesMap());
+ global_scope->GetModuleResponsesMap(), pass_key);
}
bool WorkletModulatorImpl::IsDynamicImportForbidden(String* reason) {
diff --git a/chromium/third_party/blink/renderer/core/script/worklet_modulator_impl.h b/chromium/third_party/blink/renderer/core/script/worklet_modulator_impl.h
index e5881e93427..cfd769b9467 100644
--- a/chromium/third_party/blink/renderer/core/script/worklet_modulator_impl.h
+++ b/chromium/third_party/blink/renderer/core/script/worklet_modulator_impl.h
@@ -23,7 +23,8 @@ class WorkletModulatorImpl final : public ModulatorImplBase {
// Implements ModulatorImplBase.
ModuleScriptFetcher* CreateModuleScriptFetcher(
- ModuleScriptCustomFetchType) override;
+ ModuleScriptCustomFetchType,
+ util::PassKey<ModuleScriptLoader>) override;
private:
// Implements ModulatorImplBase.
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 e4fa433e684..c4c945b8f7b 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
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/script/classic_pending_script.h"
#include "third_party/blink/renderer/core/script/script_loader.h"
#include "third_party/blink/renderer/core/script/xml_parser_script_runner_host.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
@@ -79,11 +80,11 @@ void XMLParserScriptRunner::ProcessScriptElement(
if (script_loader->GetScriptType() != mojom::ScriptType::kClassic) {
// XMLDocumentParser does not support a module script, and thus ignores it.
success = false;
- document.AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kError,
- "Module scripts in XML documents are currently "
- "not supported. See crbug.com/717643"));
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kError,
+ "Module scripts in XML documents are currently "
+ "not supported. See crbug.com/717643"));
}
if (!success)
diff --git a/chromium/third_party/blink/renderer/core/scroll/BUILD.gn b/chromium/third_party/blink/renderer/core/scroll/BUILD.gn
index 1e5a1e749b4..071ac501f43 100644
--- a/chromium/third_party/blink/renderer/core/scroll/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/scroll/BUILD.gn
@@ -42,7 +42,6 @@ blink_core_sources("scroll") {
"scrollbar_theme_overlay_mock.h",
"smooth_scroll_sequencer.cc",
"smooth_scroll_sequencer.h",
- "web_scroll_into_view_params.cc",
]
if (is_mac) {
diff --git a/chromium/third_party/blink/renderer/core/scroll/OWNERS b/chromium/third_party/blink/renderer/core/scroll/OWNERS
new file mode 100644
index 00000000000..a1660982293
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/scroll/OWNERS
@@ -0,0 +1,2 @@
+per-file *_type_converter*.*=set noparent
+per-file *_type_converter*.*=file://ipc/SECURITY_OWNERS
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 dd87274e9e7..f4d02dacf88 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
@@ -34,8 +34,9 @@ void ProgrammaticScrollAnimator::ResetAnimationState() {
void ProgrammaticScrollAnimator::NotifyOffsetChanged(
const ScrollOffset& offset) {
- ScrollType scroll_type =
- is_sequenced_scroll_ ? kSequencedScroll : kProgrammaticScroll;
+ mojom::blink::ScrollType scroll_type =
+ is_sequenced_scroll_ ? mojom::blink::ScrollType::kSequenced
+ : mojom::blink::ScrollType::kProgrammatic;
ScrollOffsetChanged(offset, scroll_type);
}
@@ -201,7 +202,7 @@ void ProgrammaticScrollAnimator::AnimationFinished() {
}
}
-void ProgrammaticScrollAnimator::Trace(blink::Visitor* visitor) {
+void ProgrammaticScrollAnimator::Trace(Visitor* visitor) {
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 e9f8feb54da..5bf0f85eca8 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void NotifyOffsetChanged(const ScrollOffset&);
diff --git a/chromium/third_party/blink/renderer/core/scroll/scroll_alignment.cc b/chromium/third_party/blink/renderer/core/scroll/scroll_alignment.cc
index a2de3d219bb..976c9048fab 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scroll_alignment.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_alignment.cc
@@ -47,28 +47,12 @@
namespace blink {
-const ScrollAlignment ScrollAlignment::kAlignCenterIfNeeded = {
- kScrollAlignmentNoScroll, kScrollAlignmentCenter,
- kScrollAlignmentClosestEdge};
-const ScrollAlignment ScrollAlignment::kAlignToEdgeIfNeeded = {
- kScrollAlignmentNoScroll, kScrollAlignmentClosestEdge,
- kScrollAlignmentClosestEdge};
-const ScrollAlignment ScrollAlignment::kAlignCenterAlways = {
- kScrollAlignmentCenter, kScrollAlignmentCenter, kScrollAlignmentCenter};
-const ScrollAlignment ScrollAlignment::kAlignTopAlways = {
- kScrollAlignmentTop, kScrollAlignmentTop, kScrollAlignmentTop};
-const ScrollAlignment ScrollAlignment::kAlignBottomAlways = {
- kScrollAlignmentBottom, kScrollAlignmentBottom, kScrollAlignmentBottom};
-const ScrollAlignment ScrollAlignment::kAlignLeftAlways = {
- kScrollAlignmentLeft, kScrollAlignmentLeft, kScrollAlignmentLeft};
-const ScrollAlignment ScrollAlignment::kAlignRightAlways = {
- kScrollAlignmentRight, kScrollAlignmentRight, kScrollAlignmentRight};
-
+// static
ScrollOffset ScrollAlignment::GetScrollOffsetToExpose(
const PhysicalRect& scroll_snapport_rect,
const PhysicalRect& expose_rect,
- const ScrollAlignment& align_x,
- const ScrollAlignment& align_y,
+ const mojom::blink::ScrollAlignment& align_x,
+ const mojom::blink::ScrollAlignment& align_y,
const ScrollOffset& current_scroll_offset) {
// Prevent degenerate cases by giving the visible rect a minimum non-0 size.
PhysicalRect non_zero_visible_rect = scroll_snapport_rect;
@@ -80,7 +64,7 @@ ScrollOffset ScrollAlignment::GetScrollOffsetToExpose(
non_zero_visible_rect.SetHeight(minimum_layout_unit);
// Determine the appropriate X behavior.
- ScrollAlignmentBehavior scroll_x;
+ mojom::blink::ScrollAlignment::Behavior scroll_x;
PhysicalRect expose_rect_x(expose_rect.X(), non_zero_visible_rect.Y(),
expose_rect.Width(),
non_zero_visible_rect.Height());
@@ -90,22 +74,22 @@ ScrollOffset ScrollAlignment::GetScrollOffsetToExpose(
// If the rectangle is fully visible, use the specified visible behavior.
// If the rectangle is partially visible, but over a certain threshold,
// then treat it as fully visible to avoid unnecessary horizontal scrolling
- scroll_x = GetVisibleBehavior(align_x);
+ scroll_x = align_x.rect_visible;
} else if (intersect_width == non_zero_visible_rect.Width()) {
// If the rect is bigger than the visible area, don't bother trying to
// center. Other alignments will work.
- scroll_x = GetVisibleBehavior(align_x);
- if (scroll_x == kScrollAlignmentCenter)
- scroll_x = kScrollAlignmentNoScroll;
+ scroll_x = align_x.rect_visible;
+ if (scroll_x == mojom::blink::ScrollAlignment::Behavior::kCenter)
+ scroll_x = mojom::blink::ScrollAlignment::Behavior::kNoScroll;
} else if (intersect_width > 0) {
// If the rectangle is partially visible, but not above the minimum
// threshold, use the specified partial behavior
- scroll_x = GetPartialBehavior(align_x);
+ scroll_x = align_x.rect_partial;
} else {
- scroll_x = GetHiddenBehavior(align_x);
+ scroll_x = align_x.rect_hidden;
}
- if (scroll_x == kScrollAlignmentClosestEdge) {
+ if (scroll_x == mojom::blink::ScrollAlignment::Behavior::kClosestEdge) {
// Closest edge is the right in two cases:
// (1) exposeRect to the right of and smaller than nonZeroVisibleRect
// (2) exposeRect to the left of and larger than nonZeroVisibleRect
@@ -113,12 +97,12 @@ ScrollOffset ScrollAlignment::GetScrollOffsetToExpose(
expose_rect.Width() < non_zero_visible_rect.Width()) ||
(expose_rect.Right() < non_zero_visible_rect.Right() &&
expose_rect.Width() > non_zero_visible_rect.Width())) {
- scroll_x = kScrollAlignmentRight;
+ scroll_x = mojom::blink::ScrollAlignment::Behavior::kRight;
}
}
// Determine the appropriate Y behavior.
- ScrollAlignmentBehavior scroll_y;
+ mojom::blink::ScrollAlignment::Behavior scroll_y;
PhysicalRect expose_rect_y(non_zero_visible_rect.X(), expose_rect.Y(),
non_zero_visible_rect.Width(),
expose_rect.Height());
@@ -126,21 +110,21 @@ ScrollOffset ScrollAlignment::GetScrollOffsetToExpose(
Intersection(non_zero_visible_rect, expose_rect_y).Height();
if (intersect_height == expose_rect.Height()) {
// If the rectangle is fully visible, use the specified visible behavior.
- scroll_y = GetVisibleBehavior(align_y);
+ scroll_y = align_y.rect_visible;
} else if (intersect_height == non_zero_visible_rect.Height()) {
// If the rect is bigger than the visible area, don't bother trying to
// center. Other alignments will work.
- scroll_y = GetVisibleBehavior(align_y);
- if (scroll_y == kScrollAlignmentCenter)
- scroll_y = kScrollAlignmentNoScroll;
+ scroll_y = align_y.rect_visible;
+ if (scroll_y == mojom::blink::ScrollAlignment::Behavior::kCenter)
+ scroll_y = mojom::blink::ScrollAlignment::Behavior::kNoScroll;
} else if (intersect_height > 0) {
// If the rectangle is partially visible, use the specified partial behavior
- scroll_y = GetPartialBehavior(align_y);
+ scroll_y = align_y.rect_partial;
} else {
- scroll_y = GetHiddenBehavior(align_y);
+ scroll_y = align_y.rect_hidden;
}
- if (scroll_y == kScrollAlignmentClosestEdge) {
+ if (scroll_y == mojom::blink::ScrollAlignment::Behavior::kClosestEdge) {
// Closest edge is the bottom in two cases:
// (1) exposeRect below and smaller than nonZeroVisibleRect
// (2) exposeRect above and larger than nonZeroVisibleRect
@@ -148,7 +132,7 @@ ScrollOffset ScrollAlignment::GetScrollOffsetToExpose(
expose_rect.Height() < non_zero_visible_rect.Height()) ||
(expose_rect.Bottom() < non_zero_visible_rect.Bottom() &&
expose_rect.Height() > non_zero_visible_rect.Height())) {
- scroll_y = kScrollAlignmentBottom;
+ scroll_y = mojom::blink::ScrollAlignment::Behavior::kBottom;
}
}
@@ -159,11 +143,11 @@ ScrollOffset ScrollAlignment::GetScrollOffsetToExpose(
// Given the X behavior, compute the X coordinate.
float x;
- if (scroll_x == kScrollAlignmentNoScroll) {
+ if (scroll_x == mojom::blink::ScrollAlignment::Behavior::kNoScroll) {
x = current_scroll_offset.Width();
- } else if (scroll_x == kScrollAlignmentRight) {
+ } else if (scroll_x == mojom::blink::ScrollAlignment::Behavior::kRight) {
x = (expose_rect.Right() - non_zero_visible_rect.Right()).ToFloat();
- } else if (scroll_x == kScrollAlignmentCenter) {
+ } else if (scroll_x == mojom::blink::ScrollAlignment::Behavior::kCenter) {
x = ((expose_rect.X() + expose_rect.Right() -
(non_zero_visible_rect.X() + non_zero_visible_rect.Right())) /
2)
@@ -174,11 +158,11 @@ ScrollOffset ScrollAlignment::GetScrollOffsetToExpose(
// Given the Y behavior, compute the Y coordinate.
float y;
- if (scroll_y == kScrollAlignmentNoScroll) {
+ if (scroll_y == mojom::blink::ScrollAlignment::Behavior::kNoScroll) {
y = current_scroll_offset.Height();
- } else if (scroll_y == kScrollAlignmentBottom) {
+ } else if (scroll_y == mojom::blink::ScrollAlignment::Behavior::kBottom) {
y = (expose_rect.Bottom() - non_zero_visible_rect.Bottom()).ToFloat();
- } else if (scroll_y == kScrollAlignmentCenter) {
+ } else if (scroll_y == mojom::blink::ScrollAlignment::Behavior::kCenter) {
y = ((expose_rect.Y() + expose_rect.Bottom() -
(non_zero_visible_rect.Y() + non_zero_visible_rect.Bottom())) /
2)
@@ -190,4 +174,95 @@ ScrollOffset ScrollAlignment::GetScrollOffsetToExpose(
return ScrollOffset(x, y);
}
+// static
+const mojom::blink::ScrollAlignment& ScrollAlignment::CenterIfNeeded() {
+ DEFINE_STATIC_LOCAL(const mojom::blink::ScrollAlignment,
+ g_scroll_align_center_if_needed,
+ (mojom::blink::ScrollAlignment::Behavior::kNoScroll,
+ mojom::blink::ScrollAlignment::Behavior::kCenter,
+ mojom::blink::ScrollAlignment::Behavior::kClosestEdge));
+ return g_scroll_align_center_if_needed;
+}
+
+// static
+const mojom::blink::ScrollAlignment& ScrollAlignment::ToEdgeIfNeeded() {
+ DEFINE_STATIC_LOCAL(const mojom::blink::ScrollAlignment,
+ g_scroll_align_to_edge_if_needed,
+ (mojom::blink::ScrollAlignment::Behavior::kNoScroll,
+ mojom::blink::ScrollAlignment::Behavior::kClosestEdge,
+ mojom::blink::ScrollAlignment::Behavior::kClosestEdge));
+ return g_scroll_align_to_edge_if_needed;
+}
+
+// static
+const mojom::blink::ScrollAlignment& ScrollAlignment::CenterAlways() {
+ DEFINE_STATIC_LOCAL(const mojom::blink::ScrollAlignment,
+ g_scroll_align_center_always,
+ (mojom::blink::ScrollAlignment::Behavior::kCenter,
+ mojom::blink::ScrollAlignment::Behavior::kCenter,
+ mojom::blink::ScrollAlignment::Behavior::kCenter));
+ return g_scroll_align_center_always;
+}
+
+// static
+const mojom::blink::ScrollAlignment& ScrollAlignment::TopAlways() {
+ DEFINE_STATIC_LOCAL(const mojom::blink::ScrollAlignment,
+ g_scroll_align_top_always,
+ (mojom::blink::ScrollAlignment::Behavior::kTop,
+ mojom::blink::ScrollAlignment::Behavior::kTop,
+ mojom::blink::ScrollAlignment::Behavior::kTop));
+ return g_scroll_align_top_always;
+}
+
+// static
+const mojom::blink::ScrollAlignment& ScrollAlignment::BottomAlways() {
+ DEFINE_STATIC_LOCAL(const mojom::blink::ScrollAlignment,
+ g_scroll_align_bottom_always,
+ (mojom::blink::ScrollAlignment::Behavior::kBottom,
+ mojom::blink::ScrollAlignment::Behavior::kBottom,
+ mojom::blink::ScrollAlignment::Behavior::kBottom));
+ return g_scroll_align_bottom_always;
+}
+
+// static
+const mojom::blink::ScrollAlignment& ScrollAlignment::LeftAlways() {
+ DEFINE_STATIC_LOCAL(const mojom::blink::ScrollAlignment,
+ g_scroll_align_left_always,
+ (mojom::blink::ScrollAlignment::Behavior::kLeft,
+ mojom::blink::ScrollAlignment::Behavior::kLeft,
+ mojom::blink::ScrollAlignment::Behavior::kLeft));
+ return g_scroll_align_left_always;
+}
+
+// static
+const mojom::blink::ScrollAlignment& ScrollAlignment::RightAlways() {
+ DEFINE_STATIC_LOCAL(const mojom::blink::ScrollAlignment,
+ g_scroll_align_right_always,
+ (mojom::blink::ScrollAlignment::Behavior::kRight,
+ mojom::blink::ScrollAlignment::Behavior::kRight,
+ mojom::blink::ScrollAlignment::Behavior::kRight));
+ return g_scroll_align_right_always;
+}
+
+// static
+mojom::blink::ScrollIntoViewParamsPtr
+ScrollAlignment::CreateScrollIntoViewParams(
+ const mojom::blink::ScrollAlignment& align_x,
+ const mojom::blink::ScrollAlignment& align_y,
+ mojom::blink::ScrollType scroll_type,
+ bool make_visible_in_visual_viewport,
+ mojom::blink::ScrollBehavior scroll_behavior,
+ bool is_for_scroll_sequence,
+ bool zoom_into_rect) {
+ auto params = mojom::blink::ScrollIntoViewParams::New();
+ params->align_x = mojom::blink::ScrollAlignment::New(align_x);
+ params->align_y = mojom::blink::ScrollAlignment::New(align_y);
+ params->type = scroll_type;
+ params->make_visible_in_visual_viewport = make_visible_in_visual_viewport;
+ params->behavior = scroll_behavior;
+ params->is_for_scroll_sequence = is_for_scroll_sequence;
+ params->zoom_into_rect = zoom_into_rect;
+ return params;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/scroll/scroll_alignment.h b/chromium/third_party/blink/renderer/core/scroll/scroll_alignment.h
index 1e9ab6f42ce..5ebc15d47da 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scroll_alignment.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_alignment.h
@@ -50,32 +50,10 @@
namespace blink {
-enum ScrollAlignmentBehavior {
- kScrollAlignmentNoScroll,
- kScrollAlignmentCenter,
- kScrollAlignmentTop,
- kScrollAlignmentBottom,
- kScrollAlignmentLeft,
- kScrollAlignmentRight,
- kScrollAlignmentClosestEdge
-};
-
struct PhysicalRect;
-struct CORE_EXPORT ScrollAlignment {
- STACK_ALLOCATED();
-
+class CORE_EXPORT ScrollAlignment {
public:
- static ScrollAlignmentBehavior GetVisibleBehavior(const ScrollAlignment& s) {
- return s.rect_visible_;
- }
- static ScrollAlignmentBehavior GetPartialBehavior(const ScrollAlignment& s) {
- return s.rect_partial_;
- }
- static ScrollAlignmentBehavior GetHiddenBehavior(const ScrollAlignment& s) {
- return s.rect_hidden_;
- }
-
// Returns the scroll offset the scroller needs to scroll to in order to put
// |expose_rect| into |visible_scroll_snapport_rect| aligned by |align_x| and
// |align_y|.
@@ -88,30 +66,30 @@ struct CORE_EXPORT ScrollAlignment {
static ScrollOffset GetScrollOffsetToExpose(
const PhysicalRect& visible_scroll_snapport_rect,
const PhysicalRect& expose_rect,
- const ScrollAlignment& align_x,
- const ScrollAlignment& align_y,
+ const mojom::blink::ScrollAlignment& align_x,
+ const mojom::blink::ScrollAlignment& align_y,
const ScrollOffset& current_scroll_offset);
- static const ScrollAlignment kAlignCenterIfNeeded;
- static const ScrollAlignment kAlignToEdgeIfNeeded;
- static const ScrollAlignment kAlignCenterAlways;
- static const ScrollAlignment kAlignTopAlways;
- static const ScrollAlignment kAlignBottomAlways;
- static const ScrollAlignment kAlignLeftAlways;
- static const ScrollAlignment kAlignRightAlways;
+ static const mojom::blink::ScrollAlignment& CenterIfNeeded();
+ static const mojom::blink::ScrollAlignment& ToEdgeIfNeeded();
+ static const mojom::blink::ScrollAlignment& CenterAlways();
+ static const mojom::blink::ScrollAlignment& TopAlways();
+ static const mojom::blink::ScrollAlignment& BottomAlways();
+ static const mojom::blink::ScrollAlignment& LeftAlways();
+ static const mojom::blink::ScrollAlignment& RightAlways();
- ScrollAlignmentBehavior rect_visible_;
- ScrollAlignmentBehavior rect_hidden_;
- ScrollAlignmentBehavior rect_partial_;
+ static mojom::blink::ScrollIntoViewParamsPtr CreateScrollIntoViewParams(
+ const mojom::blink::ScrollAlignment& align_x = CenterIfNeeded(),
+ const mojom::blink::ScrollAlignment& align_y = CenterIfNeeded(),
+ mojom::blink::ScrollType scroll_type =
+ mojom::blink::ScrollType::kProgrammatic,
+ bool make_visible_in_visual_viewport = true,
+ mojom::blink::ScrollBehavior scroll_behavior =
+ mojom::blink::ScrollBehavior::kAuto,
+ bool is_for_scroll_sequence = false,
+ bool zoom_into_rect = false);
};
-inline bool PLATFORM_EXPORT operator==(const ScrollAlignment& lhs,
- const ScrollAlignment& rhs) {
- return lhs.rect_visible_ == rhs.rect_visible_ &&
- lhs.rect_hidden_ == rhs.rect_hidden_ &&
- lhs.rect_partial_ == rhs.rect_partial_;
-}
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLL_ALIGNMENT_H_
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 53814bea940..d2dc57d9b30 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scroll_animator.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_animator.cc
@@ -211,7 +211,7 @@ bool ScrollAnimator::WillAnimateToOffset(const ScrollOffset& target_offset) {
void ScrollAnimator::AdjustAnimationAndSetScrollOffset(
const ScrollOffset& offset,
- ScrollType scroll_type) {
+ mojom::blink::ScrollType scroll_type) {
IntSize adjustment = RoundedIntSize(offset) -
RoundedIntSize(scrollable_area_->GetScrollOffset());
ScrollOffsetChanged(offset, scroll_type);
@@ -407,7 +407,7 @@ bool ScrollAnimator::RegisterAndScheduleAnimation() {
return true;
}
-void ScrollAnimator::Trace(blink::Visitor* visitor) {
+void ScrollAnimator::Trace(Visitor* visitor) {
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 364beb8e667..c4366bd6c44 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scroll_animator.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_animator.h
@@ -122,7 +122,7 @@ class CORE_EXPORT ScrollAnimator : public ScrollAnimatorBase {
void TickAnimation(double monotonic_time) override;
void CancelAnimation() override;
void AdjustAnimationAndSetScrollOffset(const ScrollOffset&,
- ScrollType) override;
+ mojom::blink::ScrollType) override;
void TakeOverCompositorAnimation() override;
void ResetAnimationState() override;
void UpdateCompositorAnimations() override;
@@ -131,7 +131,7 @@ class CORE_EXPORT ScrollAnimator : public ScrollAnimatorBase {
void LayerForCompositedScrollingDidChange(
CompositorAnimationTimeline*) override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 9705984b08a..3b9e3cb4915 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
@@ -84,10 +84,10 @@ ScrollOffset ScrollAnimatorBase::CurrentOffset() const {
}
void ScrollAnimatorBase::NotifyOffsetChanged() {
- ScrollOffsetChanged(current_offset_, kUserScroll);
+ ScrollOffsetChanged(current_offset_, mojom::blink::ScrollType::kUser);
}
-void ScrollAnimatorBase::Trace(blink::Visitor* visitor) {
+void ScrollAnimatorBase::Trace(Visitor* visitor) {
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 6a8ca92c245..272f188e19a 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
@@ -111,11 +111,12 @@ class CORE_EXPORT ScrollAnimatorBase
virtual void DidAddHorizontalScrollbar(Scrollbar&) {}
virtual void WillRemoveHorizontalScrollbar(Scrollbar&) {}
- virtual void NotifyContentAreaScrolled(const ScrollOffset&, ScrollType) {}
+ virtual void NotifyContentAreaScrolled(const ScrollOffset&,
+ mojom::blink::ScrollType) {}
virtual bool SetScrollbarsVisibleForTesting(bool) { return false; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
virtual void NotifyOffsetChanged();
diff --git a/chromium/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.cc b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.cc
index 7c15e45dbce..97e5b4a1cb4 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.cc
@@ -288,14 +288,14 @@ void ScrollAnimatorCompositorCoordinator::UpdateCompositorAnimations() {
void ScrollAnimatorCompositorCoordinator::ScrollOffsetChanged(
const ScrollOffset& offset,
- ScrollType scroll_type) {
+ mojom::blink::ScrollType scroll_type) {
ScrollOffset clamped_offset = GetScrollableArea()->ClampScrollOffset(offset);
GetScrollableArea()->ScrollOffsetChanged(clamped_offset, scroll_type);
}
void ScrollAnimatorCompositorCoordinator::AdjustAnimationAndSetScrollOffset(
const ScrollOffset& offset,
- ScrollType scroll_type) {
+ mojom::blink::ScrollType scroll_type) {
// Subclasses should override this and adjust the animation as necessary.
ScrollOffsetChanged(offset, scroll_type);
}
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 fcbcbc9bcf7..03517d90b8c 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
@@ -99,7 +99,7 @@ class CORE_EXPORT ScrollAnimatorCompositorCoordinator
// Updates the scroll offset of the animator's ScrollableArea by
// adjustment and update the target of an ongoing scroll offset animation.
virtual void AdjustAnimationAndSetScrollOffset(const ScrollOffset&,
- ScrollType);
+ mojom::blink::ScrollType);
virtual void UpdateCompositorAnimations();
virtual ScrollableArea* GetScrollableArea() const = 0;
@@ -111,12 +111,12 @@ class CORE_EXPORT ScrollAnimatorCompositorCoordinator
RunState RunStateForTesting() { return run_state_; }
- virtual void Trace(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
protected:
explicit ScrollAnimatorCompositorCoordinator();
- void ScrollOffsetChanged(const ScrollOffset&, ScrollType);
+ void ScrollOffsetChanged(const ScrollOffset&, mojom::blink::ScrollType);
void AdjustImplOnlyScrollOffsetAnimation(const IntSize& adjustment);
IntSize ImplOnlyAnimationAdjustmentForTesting() {
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 be3c1b940f4..a5b81033633 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,9 +114,7 @@ class CORE_EXPORT ScrollAnimatorMac : public ScrollAnimatorBase {
void SendContentAreaScrolledSoon(const ScrollOffset& scroll_delta);
- void Trace(blink::Visitor* visitor) override {
- ScrollAnimatorBase::Trace(visitor);
- }
+ void Trace(Visitor* visitor) override { ScrollAnimatorBase::Trace(visitor); }
private:
base::scoped_nsobject<id> scroll_animation_helper_;
@@ -165,7 +163,7 @@ class CORE_EXPORT ScrollAnimatorMac : public ScrollAnimatorBase {
void WillRemoveHorizontalScrollbar(Scrollbar&) override;
void NotifyContentAreaScrolled(const ScrollOffset& delta,
- ScrollType) override;
+ mojom::blink::ScrollType) override;
bool SetScrollbarsVisibleForTesting(bool) override;
diff --git a/chromium/third_party/blink/renderer/core/scroll/scroll_animator_mac.mm b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_mac.mm
index 4d860b03bef..222138c6dbc 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scroll_animator_mac.mm
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_animator_mac.mm
@@ -807,7 +807,7 @@ void ScrollAnimatorMac::ImmediateScrollTo(const ScrollOffset& new_offset) {
ScrollOffset delta = adjusted_offset - current_offset_;
current_offset_ = adjusted_offset;
- NotifyContentAreaScrolled(delta, kUserScroll);
+ NotifyContentAreaScrolled(delta, mojom::blink::ScrollType::kUser);
NotifyOffsetChanged();
}
@@ -935,8 +935,9 @@ void ScrollAnimatorMac::WillRemoveHorizontalScrollbar(Scrollbar& scrollbar) {
[scrollbar_painter_controller_ setHorizontalScrollerImp:nil];
}
-void ScrollAnimatorMac::NotifyContentAreaScrolled(const ScrollOffset& delta,
- ScrollType scrollType) {
+void ScrollAnimatorMac::NotifyContentAreaScrolled(
+ const ScrollOffset& delta,
+ mojom::blink::ScrollType scrollType) {
// This function is called when a page is going into the page cache, but the
// page
// isn't really scrolling in that case. We should only pass the message on to
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 ac8b62b6116..f1a21a1ea30 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
@@ -74,7 +74,8 @@ class MockScrollableAreaForAnimatorTest
MOCK_CONST_METHOD1(ScrollSize, int(ScrollbarOrientation));
MOCK_CONST_METHOD0(IsScrollCornerVisible, bool());
MOCK_CONST_METHOD0(ScrollCornerRect, IntRect());
- MOCK_METHOD2(UpdateScrollOffset, void(const ScrollOffset&, ScrollType));
+ MOCK_METHOD2(UpdateScrollOffset,
+ void(const ScrollOffset&, mojom::blink::ScrollType));
MOCK_METHOD0(ScrollControlWasSetNeedsPaintInvalidation, void());
MOCK_CONST_METHOD0(EnclosingScrollableArea, ScrollableArea*());
MOCK_CONST_METHOD1(VisibleContentRect, IntRect(IncludeScrollbarsInRect));
@@ -114,8 +115,9 @@ class MockScrollableAreaForAnimatorTest
}
void SetScrollOffset(const ScrollOffset& offset,
- ScrollType type,
- ScrollBehavior behavior = kScrollBehaviorInstant,
+ mojom::blink::ScrollType type,
+ mojom::blink::ScrollBehavior behavior =
+ mojom::blink::ScrollBehavior::kInstant,
ScrollCallback on_finish = ScrollCallback()) override {
if (animator)
animator->SetCurrentOffset(offset);
@@ -135,7 +137,7 @@ class MockScrollableAreaForAnimatorTest
return ScrollbarTheme::GetTheme();
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(animator);
ScrollableArea::Trace(visitor);
}
@@ -850,7 +852,8 @@ TEST(ScrollAnimatorTest, MainThreadAnimationTargetAdjustment) {
// Adjustment
ScrollOffset new_offset = offset + ScrollOffset(10, -10);
- animator->AdjustAnimationAndSetScrollOffset(new_offset, kAnchoringScroll);
+ animator->AdjustAnimationAndSetScrollOffset(
+ new_offset, mojom::blink::ScrollType::kAnchoring);
EXPECT_EQ(ScrollOffset(110, 90), animator->DesiredTargetOffset());
// Adjusting after finished animation should do nothing.
@@ -861,7 +864,8 @@ TEST(ScrollAnimatorTest, MainThreadAnimationTargetAdjustment) {
animator->RunStateForTesting(),
ScrollAnimatorCompositorCoordinator::RunState::kPostAnimationCleanup);
new_offset = animator->CurrentOffset() + ScrollOffset(10, -10);
- animator->AdjustAnimationAndSetScrollOffset(new_offset, kAnchoringScroll);
+ animator->AdjustAnimationAndSetScrollOffset(
+ new_offset, mojom::blink::ScrollType::kAnchoring);
EXPECT_EQ(
animator->RunStateForTesting(),
ScrollAnimatorCompositorCoordinator::RunState::kPostAnimationCleanup);
diff --git a/chromium/third_party/blink/renderer/core/scroll/scrolling_test.cc b/chromium/third_party/blink/renderer/core/scroll/scroll_test.cc
index fabce2ecb30..5203ba517a9 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrolling_test.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_test.cc
@@ -67,7 +67,8 @@ TEST_F(FractionalScrollSimTest, GetBoundingClientRectAtFractional) {
// Scroll on the layout viewport.
GetDocument().View()->GetScrollableArea()->SetScrollOffset(
- FloatSize(700.5f, 500.6f), kProgrammaticScroll, kScrollBehaviorInstant);
+ FloatSize(700.5f, 500.6f), mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kInstant);
Compositor().BeginFrame();
@@ -129,7 +130,8 @@ TEST_F(FractionalScrollSimTest, NoRepaintOnScrollFromSubpixel) {
// Scroll on the layout viewport.
GetDocument().View()->GetScrollableArea()->SetScrollOffset(
- FloatSize(0.f, 100.5f), kProgrammaticScroll, kScrollBehaviorInstant);
+ FloatSize(0.f, 100.5f), mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kInstant);
Compositor().BeginFrame();
EXPECT_FALSE(
@@ -382,8 +384,8 @@ TEST_F(ScrollAnimatorSimTest, TestRootFrameUserScrollCallBackCancelAnimation) {
// Programmatic scroll will cancel the current user scroll animation and the
// callback will be executed.
GetDocument().View()->GetScrollableArea()->SetScrollOffset(
- ScrollOffset(0, 300), kProgrammaticScroll, kScrollBehaviorSmooth,
- ScrollableArea::ScrollCallback());
+ ScrollOffset(0, 300), mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kSmooth, ScrollableArea::ScrollCallback());
Compositor().BeginFrame();
ASSERT_TRUE(finished);
}
@@ -412,10 +414,10 @@ class ScrollInfacesUseCounterSimTest : public SimTest {
)HTML");
auto& document = GetDocument();
auto* style = document.getElementById("scroller")->style();
- style->setProperty(&document, "direction", direction, String(),
- ASSERT_NO_EXCEPTION);
- style->setProperty(&document, "writing-mode", writing_mode, String(),
- ASSERT_NO_EXCEPTION);
+ style->setProperty(document.ToExecutionContext(), "direction", direction,
+ String(), ASSERT_NO_EXCEPTION);
+ style->setProperty(document.ToExecutionContext(), "writing-mode",
+ writing_mode, String(), ASSERT_NO_EXCEPTION);
Compositor().BeginFrame();
EXPECT_FALSE(document.IsUseCounted(
WebFeature::
@@ -509,7 +511,7 @@ TEST_F(ScrollInfacesUseCounterSimTest, ScrollTestAll) {
{"rtl", "vertical-rl", true, true},
};
- for (const TestCase test_case : test_cases) {
+ for (const TestCase& test_case : test_cases) {
Reset(test_case.direction, test_case.writingMode);
CheckScrollLeftOrTop("scrollLeft", test_case.scrollLeftUseCounted);
@@ -535,4 +537,50 @@ TEST_F(ScrollInfacesUseCounterSimTest, ScrollTestAll) {
}
}
+class ScrollPositionsInNonDefaultWritingModeSimTest : public SimTest {};
+
+// Verify that scrollIntoView() does not trigger the use counter
+// kElementWithLeftwardOrUpwardOverflowDirection_ScrollLeftOrTopSetPositive
+// and can be used to feature detect the convention of scroll coordinates.
+TEST_F(ScrollPositionsInNonDefaultWritingModeSimTest,
+ ScrollIntoViewAndCounters) {
+ SimRequest main_resource("https://example.com/", "text/html");
+ SimRequest child_frame_resource("https://example.com/subframe.html",
+ "text/html");
+ LoadURL("https://example.com/");
+ // Load a page that performs feature detection of scroll behavior by relying
+ // on scrollIntoView().
+ main_resource.Complete(
+ R"HTML(
+ <body>
+ <div style="direction: rtl; position: fixed; left: 0; top: 0; overflow: hidden; width: 1px; height: 1px;"><div style="width: 2px; height: 1px;"><div style="display: inline-block; width: 1px;"></div><div style="display: inline-block; width: 1px;"></div></div></div>
+ <script>
+ var scroller = document.body.firstElementChild;
+ scroller.firstElementChild.children[0].scrollIntoView();
+ var right = scroller.scrollLeft;
+ scroller.firstElementChild.children[1].scrollIntoView();
+ var left = scroller.scrollLeft;
+ if (left < right)
+ console.log("decreasing");
+ if (left < 0)
+ console.log("nonpositive");
+ </script>
+ </body>)HTML");
+ Compositor().BeginFrame();
+ test::RunPendingTasks();
+ // Per the CSSOM specification, the standard behavior is:
+ // - decreasing coordinates when scrolling leftward.
+ // - nonpositive coordinates for leftward scroller.
+ EXPECT_TRUE(ConsoleMessages().Contains("decreasing"));
+ EXPECT_TRUE(ConsoleMessages().Contains("nonpositive"));
+ // Reading scrollLeft triggers the first counter:
+ EXPECT_TRUE(GetDocument().IsUseCounted(
+ WebFeature::
+ kElementWithLeftwardOrUpwardOverflowDirection_ScrollLeftOrTop));
+ // However, calling scrollIntoView() should not trigger the second counter:
+ EXPECT_FALSE(GetDocument().IsUseCounted(
+ WebFeature::
+ kElementWithLeftwardOrUpwardOverflowDirection_ScrollLeftOrTopSetPositive));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/scroll/scroll_types.h b/chromium/third_party/blink/renderer/core/scroll/scroll_types.h
index 151c7fe2714..83f1cb8d674 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scroll_types.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scroll_types.h
@@ -26,8 +26,10 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLL_TYPES_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLL_TYPES_H_
-#include "third_party/blink/public/platform/web_gesture_event.h"
-#include "third_party/blink/public/platform/web_scroll_types.h"
+#include "third_party/blink/public/common/input/web_gesture_event.h"
+#include "third_party/blink/public/mojom/input/scroll_direction.mojom-blink.h"
+#include "third_party/blink/public/mojom/scroll/scroll_enums.mojom-blink.h"
+#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink.h"
#include "third_party/blink/renderer/platform/geometry/float_point.h"
#include "third_party/blink/renderer/platform/geometry/float_size.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
@@ -45,8 +47,11 @@ inline ScrollOffset ToScrollOffset(const FloatPoint& p) {
return ScrollOffset(p.X(), p.Y());
}
-using ScrollDirection = WebScrollDirection;
-using ui::input_types::ScrollGranularity;
+inline ScrollOffset ToScrollOffset(const gfx::PointF& p) {
+ return ScrollOffset(p.x(), p.y());
+}
+
+using ui::ScrollGranularity;
enum ScrollDirectionPhysical {
kScrollUp,
@@ -55,32 +60,23 @@ enum ScrollDirectionPhysical {
kScrollRight
};
-enum ScrollType {
- kUserScroll,
- kProgrammaticScroll,
- kClampingScroll,
- kCompositorScroll,
- kAnchoringScroll,
- // These are programmatic sequenced scrolls from SmoothScrollSequencer.
- // SetScrollOffset called with kSequencedScroll should not abort the smooth
- // scroll sequence.
- kSequencedScroll
-};
-
// An explicit scroll is one that was requested by the user or the webpage.
// An implicit scroll is a side effect of a layout change.
-inline bool IsExplicitScrollType(ScrollType scroll_type) {
- return scroll_type == kUserScroll || scroll_type == kProgrammaticScroll ||
- scroll_type == kCompositorScroll || scroll_type == kSequencedScroll;
+inline bool IsExplicitScrollType(mojom::blink::ScrollType scroll_type) {
+ return scroll_type == mojom::blink::ScrollType::kUser ||
+ scroll_type == mojom::blink::ScrollType::kProgrammatic ||
+ scroll_type == mojom::blink::ScrollType::kCompositor ||
+ scroll_type == mojom::blink::ScrollType::kSequenced;
}
// Convert logical scroll direction to physical. Physical scroll directions are
// unaffected.
-inline ScrollDirectionPhysical ToPhysicalDirection(ScrollDirection direction,
- bool is_vertical,
- bool is_flipped) {
+inline ScrollDirectionPhysical ToPhysicalDirection(
+ mojom::blink::ScrollDirection direction,
+ bool is_vertical,
+ bool is_flipped) {
switch (direction) {
- case kScrollBlockDirectionBackward: {
+ case mojom::blink::ScrollDirection::kScrollBlockDirectionBackward: {
if (is_vertical) {
if (!is_flipped)
return kScrollUp;
@@ -90,7 +86,7 @@ inline ScrollDirectionPhysical ToPhysicalDirection(ScrollDirection direction,
return kScrollLeft;
return kScrollRight;
}
- case kScrollBlockDirectionForward: {
+ case mojom::blink::ScrollDirection::kScrollBlockDirectionForward: {
if (is_vertical) {
if (!is_flipped)
return kScrollDown;
@@ -100,7 +96,7 @@ inline ScrollDirectionPhysical ToPhysicalDirection(ScrollDirection direction,
return kScrollRight;
return kScrollLeft;
}
- case kScrollInlineDirectionBackward: {
+ case mojom::blink::ScrollDirection::kScrollInlineDirectionBackward: {
if (is_vertical) {
if (!is_flipped)
return kScrollLeft;
@@ -110,7 +106,7 @@ inline ScrollDirectionPhysical ToPhysicalDirection(ScrollDirection direction,
return kScrollUp;
return kScrollDown;
}
- case kScrollInlineDirectionForward: {
+ case mojom::blink::ScrollDirection::kScrollInlineDirectionForward: {
if (is_vertical) {
if (!is_flipped)
return kScrollRight;
@@ -121,13 +117,13 @@ inline ScrollDirectionPhysical ToPhysicalDirection(ScrollDirection direction,
return kScrollUp;
}
// Direction is already physical
- case kScrollUpIgnoringWritingMode:
+ case mojom::blink::ScrollDirection::kScrollUpIgnoringWritingMode:
return kScrollUp;
- case kScrollDownIgnoringWritingMode:
+ case mojom::blink::ScrollDirection::kScrollDownIgnoringWritingMode:
return kScrollDown;
- case kScrollLeftIgnoringWritingMode:
+ case mojom::blink::ScrollDirection::kScrollLeftIgnoringWritingMode:
return kScrollLeft;
- case kScrollRightIgnoringWritingMode:
+ case mojom::blink::ScrollDirection::kScrollRightIgnoringWritingMode:
return kScrollRight;
default:
NOTREACHED();
@@ -136,21 +132,22 @@ inline ScrollDirectionPhysical ToPhysicalDirection(ScrollDirection direction,
return kScrollUp;
}
-inline ScrollDirection ToScrollDirection(ScrollDirectionPhysical direction) {
+inline mojom::blink::ScrollDirection ToScrollDirection(
+ ScrollDirectionPhysical direction) {
switch (direction) {
case kScrollUp:
- return kScrollUpIgnoringWritingMode;
+ return mojom::blink::ScrollDirection::kScrollUpIgnoringWritingMode;
case kScrollDown:
- return kScrollDownIgnoringWritingMode;
+ return mojom::blink::ScrollDirection::kScrollDownIgnoringWritingMode;
case kScrollLeft:
- return kScrollLeftIgnoringWritingMode;
+ return mojom::blink::ScrollDirection::kScrollLeftIgnoringWritingMode;
case kScrollRight:
- return kScrollRightIgnoringWritingMode;
+ return mojom::blink::ScrollDirection::kScrollRightIgnoringWritingMode;
default:
NOTREACHED();
break;
}
- return kScrollUpIgnoringWritingMode;
+ return mojom::blink::ScrollDirection::kScrollUpIgnoringWritingMode;
}
enum ScrollInertialPhase {
@@ -163,8 +160,6 @@ enum ScrollbarOrientation { kHorizontalScrollbar, kVerticalScrollbar };
enum ScrollOrientation { kHorizontalScroll, kVerticalScroll };
-enum class ScrollbarMode { kAuto, kAlwaysOff, kAlwaysOn };
-
enum ScrollbarControlSize { kRegularScrollbar, kSmallScrollbar };
typedef unsigned ScrollbarControlState;
@@ -194,12 +189,6 @@ enum ScrollbarOverlayColorTheme {
kScrollbarOverlayColorThemeLight
};
-enum ScrollBehavior {
- kScrollBehaviorAuto,
- kScrollBehaviorInstant,
- kScrollBehaviorSmooth,
-};
-
// The result of an attempt to scroll. If didScroll is true, then
// unusedScrollDelta gives the amount of the scroll delta that was not consumed
// by scrolling.
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 eb73639f664..fdadcbb9872 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollable_area.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollable_area.cc
@@ -36,6 +36,7 @@
#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/input/event_handler.h"
@@ -71,18 +72,25 @@ int ScrollableArea::MaxOverlapBetweenPages() const {
}
// static
-ScrollBehavior ScrollableArea::DetermineScrollBehavior(
- ScrollBehavior behavior_from_param,
- ScrollBehavior behavior_from_style) {
- if (behavior_from_param == kScrollBehaviorSmooth)
- return kScrollBehaviorSmooth;
-
- if (behavior_from_param == kScrollBehaviorAuto &&
- behavior_from_style == kScrollBehaviorSmooth) {
- return kScrollBehaviorSmooth;
+float ScrollableArea::DirectionBasedScrollDelta(ScrollGranularity granularity) {
+ return (granularity == ScrollGranularity::kScrollByPercentage)
+ ? kPercentDeltaForDirectionalScroll
+ : 1;
+}
+
+// static
+mojom::blink::ScrollBehavior ScrollableArea::DetermineScrollBehavior(
+ mojom::blink::ScrollBehavior behavior_from_param,
+ mojom::blink::ScrollBehavior behavior_from_style) {
+ if (behavior_from_param == mojom::blink::ScrollBehavior::kSmooth)
+ return mojom::blink::ScrollBehavior::kSmooth;
+
+ if (behavior_from_param == mojom::blink::ScrollBehavior::kAuto &&
+ behavior_from_style == mojom::blink::ScrollBehavior::kSmooth) {
+ return mojom::blink::ScrollBehavior::kSmooth;
}
- return kScrollBehaviorInstant;
+ return mojom::blink::ScrollBehavior::kInstant;
}
ScrollableArea::ScrollableArea()
@@ -156,6 +164,8 @@ float ScrollableArea::ScrollStep(ScrollGranularity granularity,
case ScrollGranularity::kScrollByPixel:
case ScrollGranularity::kScrollByPrecisePixel:
return PixelStep(orientation);
+ case ScrollGranularity::kScrollByPercentage:
+ return PercentageStep(orientation);
default:
NOTREACHED();
return 0.0f;
@@ -206,8 +216,8 @@ ScrollResult ScrollableArea::UserScroll(ScrollGranularity granularity,
}
void ScrollableArea::SetScrollOffset(const ScrollOffset& offset,
- ScrollType scroll_type,
- ScrollBehavior behavior,
+ mojom::blink::ScrollType scroll_type,
+ mojom::blink::ScrollBehavior behavior,
ScrollCallback on_finish) {
if (on_finish)
RegisterScrollCompleteCallback(std::move(on_finish));
@@ -233,30 +243,30 @@ void ScrollableArea::SetScrollOffset(const ScrollOffset& offset,
TRACE_EVENT_INSTANT1("blink", "Behavior", TRACE_EVENT_SCOPE_THREAD,
"behavior", behavior);
- if (behavior == kScrollBehaviorAuto)
+ if (behavior == mojom::blink::ScrollBehavior::kAuto)
behavior = ScrollBehaviorStyle();
switch (scroll_type) {
- case kCompositorScroll:
+ case mojom::blink::ScrollType::kCompositor:
ScrollOffsetChanged(clamped_offset, scroll_type);
break;
- case kClampingScroll:
+ case mojom::blink::ScrollType::kClamping:
GetScrollAnimator().AdjustAnimationAndSetScrollOffset(clamped_offset,
scroll_type);
break;
- case kAnchoringScroll:
+ case mojom::blink::ScrollType::kAnchoring:
GetScrollAnimator().AdjustAnimationAndSetScrollOffset(clamped_offset,
scroll_type);
break;
- case kProgrammaticScroll:
+ case mojom::blink::ScrollType::kProgrammatic:
ProgrammaticScrollHelper(clamped_offset, behavior, false,
run_on_return.Release());
break;
- case kSequencedScroll:
+ case mojom::blink::ScrollType::kSequenced:
ProgrammaticScrollHelper(clamped_offset, behavior, true,
run_on_return.Release());
break;
- case kUserScroll:
+ case mojom::blink::ScrollType::kUser:
UserScrollHelper(clamped_offset, behavior);
break;
default:
@@ -265,57 +275,37 @@ void ScrollableArea::SetScrollOffset(const ScrollOffset& offset,
}
void ScrollableArea::SetScrollOffset(const ScrollOffset& offset,
- ScrollType type,
- ScrollBehavior behavior) {
+ mojom::blink::ScrollType type,
+ mojom::blink::ScrollBehavior behavior) {
SetScrollOffset(offset, type, behavior, ScrollCallback());
}
void ScrollableArea::ScrollBy(const ScrollOffset& delta,
- ScrollType type,
- ScrollBehavior behavior) {
+ mojom::blink::ScrollType type,
+ mojom::blink::ScrollBehavior behavior) {
SetScrollOffset(GetScrollOffset() + delta, type, behavior);
}
-void ScrollableArea::SetScrollOffsetSingleAxis(ScrollbarOrientation orientation,
- float offset,
- ScrollType scroll_type,
- ScrollBehavior behavior) {
- ScrollOffset new_offset;
- if (orientation == kHorizontalScrollbar)
- new_offset =
- ScrollOffset(offset, GetScrollAnimator().CurrentOffset().Height());
- else
- new_offset =
- ScrollOffset(GetScrollAnimator().CurrentOffset().Width(), offset);
-
- // TODO(bokan): Note, this doesn't use the derived class versions since this
- // method is currently used exclusively by code that adjusts the position by
- // the scroll origin and the derived class versions differ on whether they
- // take that into account or not.
- ScrollableArea::SetScrollOffset(new_offset, scroll_type, behavior);
-}
-
-void ScrollableArea::ProgrammaticScrollHelper(const ScrollOffset& offset,
- ScrollBehavior scroll_behavior,
- bool is_sequenced_scroll,
- ScrollCallback on_finish) {
+void ScrollableArea::ProgrammaticScrollHelper(
+ const ScrollOffset& offset,
+ mojom::blink::ScrollBehavior scroll_behavior,
+ bool is_sequenced_scroll,
+ ScrollCallback on_finish) {
CancelScrollAnimation();
ScrollCallback callback = std::move(on_finish);
- if (RuntimeEnabledFeatures::UpdateHoverAtBeginFrameEnabled() ||
- RuntimeEnabledFeatures::OverscrollCustomizationEnabled()) {
- callback = ScrollCallback(WTF::Bind(
- [](ScrollCallback original_callback,
- WeakPersistent<ScrollableArea> area) {
- if (area)
- area->OnScrollFinished();
- if (original_callback)
- std::move(original_callback).Run();
- },
- std::move(callback), WrapWeakPersistent(this)));
- }
-
- if (scroll_behavior == kScrollBehaviorSmooth) {
+ callback = ScrollCallback(WTF::Bind(
+ [](ScrollCallback original_callback,
+ WeakPersistent<ScrollableArea> area) {
+ if (area)
+ area->OnScrollFinished();
+ if (original_callback)
+ std::move(original_callback).Run();
+ },
+ std::move(callback), WrapWeakPersistent(this)));
+
+ if (scroll_behavior == mojom::blink::ScrollBehavior::kSmooth &&
+ ScrollAnimatorEnabled()) {
GetProgrammaticScrollAnimator().AnimateToOffset(offset, is_sequenced_scroll,
std::move(callback));
} else {
@@ -326,8 +316,9 @@ void ScrollableArea::ProgrammaticScrollHelper(const ScrollOffset& offset,
}
}
-void ScrollableArea::UserScrollHelper(const ScrollOffset& offset,
- ScrollBehavior scroll_behavior) {
+void ScrollableArea::UserScrollHelper(
+ const ScrollOffset& offset,
+ mojom::blink::ScrollBehavior scroll_behavior) {
CancelProgrammaticScrollAnimation();
if (SmoothScrollSequencer* sequencer = GetSmoothScrollSequencer())
sequencer->AbortAnimations();
@@ -344,13 +335,13 @@ void ScrollableArea::UserScrollHelper(const ScrollOffset& offset,
// TODO(bokan): The userScroll method should probably be modified to call this
// method and ScrollAnimatorBase to have a simpler
// animateToOffset method like the ProgrammaticScrollAnimator.
- DCHECK_EQ(scroll_behavior, kScrollBehaviorInstant);
+ DCHECK_EQ(scroll_behavior, mojom::blink::ScrollBehavior::kInstant);
GetScrollAnimator().ScrollToOffsetWithoutAnimation(ScrollOffset(x, y));
}
PhysicalRect ScrollableArea::ScrollIntoView(
const PhysicalRect& rect_in_absolute,
- const WebScrollIntoViewParams& params) {
+ const mojom::blink::ScrollIntoViewParamsPtr& params) {
// TODO(bokan): This should really be implemented here but ScrollAlignment is
// in Core which is a dependency violation.
NOTREACHED();
@@ -358,7 +349,7 @@ PhysicalRect ScrollableArea::ScrollIntoView(
}
void ScrollableArea::ScrollOffsetChanged(const ScrollOffset& offset,
- ScrollType scroll_type) {
+ mojom::blink::ScrollType scroll_type) {
TRACE_EVENT0("blink", "ScrollableArea::scrollOffsetChanged");
ScrollOffset old_offset = GetScrollOffset();
@@ -379,9 +370,9 @@ void ScrollableArea::ScrollOffsetChanged(const ScrollOffset& offset,
// invalidated to reflect the new thumb offset, even if the theme did not
// invalidate any individual part.
if (Scrollbar* horizontal_scrollbar = this->HorizontalScrollbar())
- horizontal_scrollbar->OffsetDidChange();
+ horizontal_scrollbar->OffsetDidChange(scroll_type);
if (Scrollbar* vertical_scrollbar = this->VerticalScrollbar())
- vertical_scrollbar->OffsetDidChange();
+ vertical_scrollbar->OffsetDidChange(scroll_type);
ScrollOffset delta = GetScrollOffset() - old_offset;
// TODO(skobes): Should we exit sooner when the offset has not changed?
@@ -411,14 +402,15 @@ void ScrollableArea::ScrollOffsetChanged(const ScrollOffset& offset,
GetScrollAnimator().SetCurrentOffset(offset);
}
-bool ScrollableArea::ScrollBehaviorFromString(const String& behavior_string,
- ScrollBehavior& behavior) {
+bool ScrollableArea::ScrollBehaviorFromString(
+ const String& behavior_string,
+ mojom::blink::ScrollBehavior& behavior) {
if (behavior_string == "auto")
- behavior = kScrollBehaviorAuto;
+ behavior = mojom::blink::ScrollBehavior::kAuto;
else if (behavior_string == "instant")
- behavior = kScrollBehaviorInstant;
+ behavior = mojom::blink::ScrollBehavior::kInstant;
else if (behavior_string == "smooth")
- behavior = kScrollBehaviorSmooth;
+ behavior = mojom::blink::ScrollBehavior::kSmooth;
else
return false;
@@ -427,7 +419,8 @@ bool ScrollableArea::ScrollBehaviorFromString(const String& behavior_string,
// NOTE: Only called from Internals for testing.
void ScrollableArea::UpdateScrollOffsetFromInternals(const IntSize& offset) {
- ScrollOffsetChanged(ScrollOffset(offset), kProgrammaticScroll);
+ ScrollOffsetChanged(ScrollOffset(offset),
+ mojom::blink::ScrollType::kProgrammatic);
}
void ScrollableArea::RegisterScrollCompleteCallback(ScrollCallback callback) {
@@ -465,7 +458,7 @@ void ScrollableArea::MouseMovedInContentArea() const {
void ScrollableArea::MouseEnteredScrollbar(Scrollbar& scrollbar) {
mouse_over_scrollbar_ = true;
GetScrollAnimator().MouseEnteredScrollbar(scrollbar);
- ShowOverlayScrollbars();
+ ShowNonMacOverlayScrollbars();
if (fade_overlay_scrollbars_timer_)
fade_overlay_scrollbars_timer_->Stop();
}
@@ -475,13 +468,13 @@ void ScrollableArea::MouseExitedScrollbar(Scrollbar& scrollbar) {
GetScrollAnimator().MouseExitedScrollbar(scrollbar);
if (HasOverlayScrollbars() && !scrollbars_hidden_if_overlay_) {
// This will kick off the fade out timer.
- ShowOverlayScrollbars();
+ ShowNonMacOverlayScrollbars();
}
}
void ScrollableArea::MouseCapturedScrollbar() {
scrollbar_captured_ = true;
- ShowOverlayScrollbars();
+ ShowNonMacOverlayScrollbars();
if (fade_overlay_scrollbars_timer_)
fade_overlay_scrollbars_timer_->Stop();
}
@@ -489,7 +482,7 @@ void ScrollableArea::MouseCapturedScrollbar() {
void ScrollableArea::MouseReleasedScrollbar() {
scrollbar_captured_ = false;
// This will kick off the fade out timer.
- ShowOverlayScrollbars();
+ ShowNonMacOverlayScrollbars();
}
void ScrollableArea::ContentAreaDidShow() const {
@@ -534,6 +527,13 @@ void ScrollableArea::ContentsResized() {
scroll_animator->ContentsResized();
}
+void ScrollableArea::InvalidateScrollTimeline() {
+ if (auto* layout_box = GetLayoutBox()) {
+ if (auto* node = layout_box->GetNode())
+ ScrollTimeline::Invalidate(node);
+ }
+}
+
bool ScrollableArea::HasOverlayScrollbars() const {
Scrollbar* v_scrollbar = VerticalScrollbar();
if (v_scrollbar && v_scrollbar->IsOverlayScrollbar())
@@ -662,12 +662,36 @@ bool ScrollableArea::ScrollbarsHiddenIfOverlay() const {
return HasOverlayScrollbars() && scrollbars_hidden_if_overlay_;
}
+void ScrollableArea::SetScrollbarsHiddenForTesting(bool hidden) {
+ // If scrollable area has been disposed, we can not get the page scrollbar
+ // theme setting. Should early return here.
+ if (HasBeenDisposed())
+ return;
+
+ SetScrollbarsHiddenIfOverlayInternal(hidden);
+}
+
+void ScrollableArea::SetScrollbarsHiddenFromExternalAnimator(bool hidden) {
+ // If scrollable area has been disposed, we can not get the page scrollbar
+ // theme setting. Should early return here.
+ if (HasBeenDisposed())
+ return;
+
+ DCHECK(!GetPageScrollbarTheme().BlinkControlsOverlayVisibility());
+ SetScrollbarsHiddenIfOverlayInternal(hidden);
+}
+
void ScrollableArea::SetScrollbarsHiddenIfOverlay(bool hidden) {
// If scrollable area has been disposed, we can not get the page scrollbar
// theme setting. Should early return here.
if (HasBeenDisposed())
return;
+ DCHECK(GetPageScrollbarTheme().BlinkControlsOverlayVisibility());
+ SetScrollbarsHiddenIfOverlayInternal(hidden);
+}
+
+void ScrollableArea::SetScrollbarsHiddenIfOverlayInternal(bool hidden) {
if (!GetPageScrollbarTheme().UsesOverlayScrollbars())
return;
@@ -682,8 +706,9 @@ void ScrollableArea::FadeOverlayScrollbarsTimerFired(TimerBase*) {
SetScrollbarsHiddenIfOverlay(true);
}
-void ScrollableArea::ShowOverlayScrollbars() {
- if (!GetPageScrollbarTheme().UsesOverlayScrollbars())
+void ScrollableArea::ShowNonMacOverlayScrollbars() {
+ if (!GetPageScrollbarTheme().UsesOverlayScrollbars() ||
+ !GetPageScrollbarTheme().BlinkControlsOverlayVisibility())
return;
SetScrollbarsHiddenIfOverlay(false);
@@ -694,9 +719,9 @@ void ScrollableArea::ShowOverlayScrollbars() {
GetPageScrollbarTheme().OverlayScrollbarFadeOutDuration();
// If the overlay scrollbars don't fade out, don't do anything. This is the
- // case for the mock overlays used in tests and on Mac, where the fade-out is
- // animated in ScrollAnimatorMac.
- // We also don't fade out overlay scrollbar for popup since we don't create
+ // case for the mock overlays used in tests (and also Mac but its scrollbars
+ // are animated by OS APIs and so we've already early-out'ed above). We also
+ // don't fade out overlay scrollbar for popup since we don't create
// compositor for popup and thus they don't appear on hover so users without
// a wheel can't scroll if they fade out.
if (time_until_disable.is_zero() || GetChromeClient()->IsPopup())
@@ -756,6 +781,14 @@ float ScrollableArea::PixelStep(ScrollbarOrientation) const {
return 1;
}
+float ScrollableArea::PercentageStep(ScrollbarOrientation orientation) const {
+ int percent_basis =
+ (orientation == ScrollbarOrientation::kHorizontalScrollbar)
+ ? VisibleWidth()
+ : VisibleHeight();
+ return static_cast<float>(percent_basis);
+}
+
int ScrollableArea::VerticalScrollbarWidth(
OverlayScrollbarClipBehavior behavior) const {
DCHECK_EQ(behavior, kIgnorePlatformOverlayScrollbarSize);
@@ -787,7 +820,7 @@ IntSize ScrollableArea::ExcludeScrollbars(const IntSize& size) const {
void ScrollableArea::DidScroll(const FloatPoint& position) {
ScrollOffset new_offset(ScrollPositionToOffset(position));
- SetScrollOffset(new_offset, kCompositorScroll);
+ SetScrollOffset(new_offset, mojom::blink::ScrollType::kCompositor);
}
CompositorElementId ScrollableArea::GetScrollbarElementId(
@@ -808,13 +841,11 @@ void ScrollableArea::OnScrollFinished() {
if (Node* node = GetLayoutBox()->GetNode())
node->GetDocument().EnqueueScrollEndEventForNode(node);
}
- if (RuntimeEnabledFeatures::UpdateHoverAtBeginFrameEnabled()) {
- GetLayoutBox()
- ->GetFrame()
- ->LocalFrameRoot()
- .GetEventHandler()
- .MarkHoverStateDirty();
- }
+ GetLayoutBox()
+ ->GetFrame()
+ ->LocalFrameRoot()
+ .GetEventHandler()
+ .MarkHoverStateDirty();
}
}
@@ -842,7 +873,7 @@ bool ScrollableArea::SnapForEndPosition(const FloatPoint& end_position,
std::unique_ptr<cc::SnapSelectionStrategy> strategy =
cc::SnapSelectionStrategy::CreateForEndPosition(
gfx::ScrollOffset(end_position), scrolled_x, scrolled_y);
- return PerformSnapping(*strategy, kScrollBehaviorSmooth,
+ return PerformSnapping(*strategy, mojom::blink::ScrollBehavior::kSmooth,
std::move(on_finish));
}
@@ -853,8 +884,9 @@ bool ScrollableArea::SnapForDirection(const ScrollOffset& delta,
std::unique_ptr<cc::SnapSelectionStrategy> strategy =
cc::SnapSelectionStrategy::CreateForDirection(
gfx::ScrollOffset(current_position),
- gfx::ScrollOffset(delta.Width(), delta.Height()));
- return PerformSnapping(*strategy, kScrollBehaviorSmooth,
+ gfx::ScrollOffset(delta.Width(), delta.Height()),
+ RuntimeEnabledFeatures::FractionalScrollOffsetsEnabled());
+ return PerformSnapping(*strategy, mojom::blink::ScrollBehavior::kSmooth,
std::move(on_finish));
}
@@ -864,7 +896,8 @@ bool ScrollableArea::SnapForEndAndDirection(const ScrollOffset& delta) {
std::unique_ptr<cc::SnapSelectionStrategy> strategy =
cc::SnapSelectionStrategy::CreateForEndAndDirection(
gfx::ScrollOffset(current_position),
- gfx::ScrollOffset(delta.Width(), delta.Height()));
+ gfx::ScrollOffset(delta.Width(), delta.Height()),
+ RuntimeEnabledFeatures::FractionalScrollOffsetsEnabled());
return PerformSnapping(*strategy);
}
@@ -878,23 +911,25 @@ void ScrollableArea::SnapAfterLayout() {
cc::SnapSelectionStrategy::CreateForTargetElement(
gfx::ScrollOffset(current_position));
- PerformSnapping(*strategy, kScrollBehaviorInstant);
+ PerformSnapping(*strategy, mojom::blink::ScrollBehavior::kInstant);
}
-bool ScrollableArea::PerformSnapping(const cc::SnapSelectionStrategy& strategy,
- ScrollBehavior scroll_behavior,
- base::ScopedClosureRunner on_finish) {
+bool ScrollableArea::PerformSnapping(
+ const cc::SnapSelectionStrategy& strategy,
+ mojom::blink::ScrollBehavior scroll_behavior,
+ base::ScopedClosureRunner on_finish) {
base::Optional<FloatPoint> snap_point = GetSnapPositionAndSetTarget(strategy);
if (!snap_point)
return false;
CancelScrollAnimation();
CancelProgrammaticScrollAnimation();
SetScrollOffset(ScrollPositionToOffset(snap_point.value()),
- kProgrammaticScroll, scroll_behavior, on_finish.Release());
+ mojom::blink::ScrollType::kProgrammatic, scroll_behavior,
+ on_finish.Release());
return true;
}
-void ScrollableArea::Trace(blink::Visitor* visitor) {
+void ScrollableArea::Trace(Visitor* visitor) {
visitor->Trace(scroll_animator_);
visitor->Trace(programmatic_scroll_animator_);
}
@@ -909,7 +944,8 @@ void ScrollableArea::InjectGestureScrollEvent(
// it is not hit-testable.
DCHECK(GetLayoutBox());
GetChromeClient()->InjectGestureScrollEvent(
- *GetLayoutBox()->GetFrame(), device, delta, granularity,
+ *GetLayoutBox()->GetFrame(), device,
+ gfx::Vector2dF(delta.Width(), delta.Height()), granularity,
GetScrollElementId(), gesture_type);
}
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 284280d5552..56c34cab314 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollable_area.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollable_area.h
@@ -28,9 +28,11 @@
#include "base/callback_helpers.h"
#include "cc/input/scroll_snap_data.h"
+#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink-forward.h"
#include "third_party/blink/public/platform/web_color_scheme.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/geometry/physical_rect.h"
+#include "third_party/blink/renderer/core/loader/history_item.h"
#include "third_party/blink/renderer/core/scroll/scrollbar.h"
#include "third_party/blink/renderer/platform/geometry/float_quad.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
@@ -63,7 +65,6 @@ class ScrollAnchor;
class ScrollAnimatorBase;
struct SerializedAnchor;
class SmoothScrollSequencer;
-struct WebScrollIntoViewParams;
using MainThreadScrollingReasons = uint32_t;
@@ -83,6 +84,10 @@ class CORE_EXPORT ScrollableArea : public GarbageCollectedMixin {
static float MinFractionToStepWhenPaging();
int MaxOverlapBetweenPages() const;
+ // Returns the amount of delta, in |granularity| units, for a direction-based
+ // (i.e. keyboard or scrollbar arrow) scroll.
+ static float DirectionBasedScrollDelta(ScrollGranularity granularity);
+
// Convert a non-finite scroll value (Infinity, -Infinity, NaN) to 0 as
// per https://drafts.csswg.org/cssom-view/#normalize-non-finite-values.
static float NormalizeNonFiniteScroll(float value) {
@@ -100,27 +105,34 @@ class CORE_EXPORT ScrollableArea : public GarbageCollectedMixin {
ScrollCallback on_finish);
virtual void SetScrollOffset(const ScrollOffset&,
- ScrollType,
- ScrollBehavior,
+ mojom::blink::ScrollType,
+ mojom::blink::ScrollBehavior,
ScrollCallback on_finish);
- void SetScrollOffset(const ScrollOffset&,
- ScrollType,
- ScrollBehavior = kScrollBehaviorInstant);
- void ScrollBy(const ScrollOffset&,
- ScrollType,
- ScrollBehavior = kScrollBehaviorInstant);
- void SetScrollOffsetSingleAxis(ScrollbarOrientation,
- float,
- ScrollType,
- ScrollBehavior = kScrollBehaviorInstant);
+ virtual void SetScrollOffset(
+ const ScrollOffset&,
+ mojom::blink::ScrollType,
+ mojom::blink::ScrollBehavior = mojom::blink::ScrollBehavior::kInstant);
+ void ScrollBy(
+ const ScrollOffset&,
+ mojom::blink::ScrollType,
+ mojom::blink::ScrollBehavior = mojom::blink::ScrollBehavior::kInstant);
+
+ virtual void SetPendingHistoryRestoreScrollOffset(
+ const HistoryItem::ViewState& view_state,
+ bool should_restore_scroll) {}
+ virtual void ApplyPendingHistoryRestoreScrollOffset() {}
+
+ virtual bool HasPendingHistoryRestoreScrollOffset() { return false; }
// Scrolls the area so that the given rect, given in absolute coordinates,
// such that it's visible in the area. Returns the new location of the input
// rect in absolute coordinates.
- virtual PhysicalRect ScrollIntoView(const PhysicalRect&,
- const WebScrollIntoViewParams&);
+ virtual PhysicalRect ScrollIntoView(
+ const PhysicalRect&,
+ const mojom::blink::ScrollIntoViewParamsPtr&);
- static bool ScrollBehaviorFromString(const String&, ScrollBehavior&);
+ static bool ScrollBehaviorFromString(const String&,
+ mojom::blink::ScrollBehavior&);
// Register a callback that will be invoked when the next scroll completes -
// this includes the scroll animation time.
@@ -145,6 +157,10 @@ class CORE_EXPORT ScrollableArea : public GarbageCollectedMixin {
virtual bool SetTargetSnapAreaElementIds(cc::TargetSnapAreaElementIds) {
return false;
}
+ virtual bool SnapContainerDataNeedsUpdate() const { return false; }
+ virtual void SetSnapContainerDataNeedsUpdate(bool) {}
+ virtual bool NeedsResnap() const { return false; }
+ virtual void SetNeedsResnap(bool) {}
void SnapAfterScrollbarScrolling(ScrollbarOrientation);
// SnapAtCurrentPosition(), SnapForEndPosition(), SnapForDirection(), and
@@ -359,9 +375,18 @@ class CORE_EXPORT ScrollableArea : public GarbageCollectedMixin {
}
virtual bool ShouldScrollOnMainThread() const { return false; }
- // Overlay scrollbars can "fade-out" when inactive.
+ // Overlay scrollbars can "fade-out" when inactive. This value should only be
+ // updated if BlinkControlsOverlayVisibility is true in the
+ // ScrollbarTheme. On Mac, where it is false, this can only be updated from
+ // the ScrollbarAnimatorMac painting code which will do so via
+ // SetScrollbarsHiddenFromExternalAnimator.
virtual bool ScrollbarsHiddenIfOverlay() const;
- virtual void SetScrollbarsHiddenIfOverlay(bool);
+ void SetScrollbarsHiddenIfOverlay(bool);
+
+ // This should only be called from Mac's painting code.
+ void SetScrollbarsHiddenFromExternalAnimator(bool);
+
+ void SetScrollbarsHiddenForTesting(bool);
virtual bool UserInputScrollable(ScrollbarOrientation) const = 0;
virtual bool ShouldPlaceVerticalScrollbarOnLeft() const = 0;
@@ -419,8 +444,8 @@ class CORE_EXPORT ScrollableArea : public GarbageCollectedMixin {
// Returns the default scroll style this area should scroll with when not
// explicitly specified. E.g. The scrolling behavior of an element can be
// specified in CSS.
- virtual ScrollBehavior ScrollBehaviorStyle() const {
- return kScrollBehaviorInstant;
+ virtual mojom::blink::ScrollBehavior ScrollBehaviorStyle() const {
+ return mojom::blink::ScrollBehavior::kInstant;
}
virtual WebColorScheme UsedColorScheme() const = 0;
@@ -453,7 +478,7 @@ class CORE_EXPORT ScrollableArea : public GarbageCollectedMixin {
// for layout movements (bit.ly/scroll-anchoring).
virtual bool ShouldPerformScrollAnchoring() const { return false; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
virtual void ClearScrollableArea();
@@ -486,18 +511,19 @@ class CORE_EXPORT ScrollableArea : public GarbageCollectedMixin {
ScrollOffset delta,
ScrollGranularity granularity,
WebInputEvent::Type gesture_type) const;
-
+ void InvalidateScrollTimeline();
// If the layout box is a global root scroller then the root frame view's
// ScrollableArea is returned. Otherwise, the layout box's
// PaintLayerScrollableArea (which can be null) is returned.
static ScrollableArea* GetForScrolling(const LayoutBox* layout_box);
protected:
- // Deduces the ScrollBehavior based on the element style and the parameter set
- // by programmatic scroll into either instant or smooth scroll.
- static ScrollBehavior DetermineScrollBehavior(
- ScrollBehavior behavior_from_style,
- ScrollBehavior behavior_from_param);
+ // Deduces the mojom::blink::ScrollBehavior based on the
+ // element style and the parameter set by programmatic scroll into either
+ // instant or smooth scroll.
+ static mojom::blink::ScrollBehavior DetermineScrollBehavior(
+ mojom::blink::ScrollBehavior behavior_from_style,
+ mojom::blink::ScrollBehavior behavior_from_param);
ScrollableArea();
@@ -506,14 +532,14 @@ class CORE_EXPORT ScrollableArea : public GarbageCollectedMixin {
// Needed to let the animators call scrollOffsetChanged.
friend class ScrollAnimatorCompositorCoordinator;
- void ScrollOffsetChanged(const ScrollOffset&, ScrollType);
+ void ScrollOffsetChanged(const ScrollOffset&, mojom::blink::ScrollType);
void ClearNeedsPaintInvalidationForScrollControls() {
horizontal_scrollbar_needs_paint_invalidation_ = false;
vertical_scrollbar_needs_paint_invalidation_ = false;
scroll_corner_needs_paint_invalidation_ = false;
}
- void ShowOverlayScrollbars();
+ void ShowNonMacOverlayScrollbars();
// Called when scrollbar hides/shows for overlay scrollbars. This callback
// shouldn't do any significant work as it can be called unexpectadly often
@@ -529,27 +555,37 @@ class CORE_EXPORT ScrollableArea : public GarbageCollectedMixin {
FRIEND_TEST_ALL_PREFIXES(ScrollableAreaTest,
PopupOverlayScrollbarShouldNotFadeOut);
+ void SetScrollbarsHiddenIfOverlayInternal(bool);
+
void ProgrammaticScrollHelper(const ScrollOffset&,
- ScrollBehavior,
+ mojom::blink::ScrollBehavior,
bool,
ScrollCallback on_finish);
- void UserScrollHelper(const ScrollOffset&, ScrollBehavior);
+ void UserScrollHelper(const ScrollOffset&, mojom::blink::ScrollBehavior);
void FadeOverlayScrollbarsTimerFired(TimerBase*);
- // This function should be overriden by subclasses to perform the actual
+ // This function should be overridden by subclasses to perform the actual
// scroll of the content.
- virtual void UpdateScrollOffset(const ScrollOffset&, ScrollType) = 0;
+ virtual void UpdateScrollOffset(const ScrollOffset&,
+ mojom::blink::ScrollType) = 0;
virtual int LineStep(ScrollbarOrientation) const;
virtual int PageStep(ScrollbarOrientation) const;
virtual int DocumentStep(ScrollbarOrientation) const;
virtual float PixelStep(ScrollbarOrientation) const;
+ // This returns the amount a percent-based delta should be resolved against;
+ // which is the visible height of the scroller. This value is eventually
+ // used to scroll the incoming scroll delta, where a scroll delta of 1
+ // represents one hundred percent.
+ float PercentageStep(ScrollbarOrientation) const;
+
// Returns true if a snap point was found.
bool PerformSnapping(
const cc::SnapSelectionStrategy& strategy,
- ScrollBehavior behavior = ScrollBehavior::kScrollBehaviorSmooth,
+ mojom::blink::ScrollBehavior behavior =
+ mojom::blink::ScrollBehavior::kSmooth,
base::ScopedClosureRunner on_finish = base::ScopedClosureRunner());
mutable Member<ScrollAnimatorBase> scroll_animator_;
diff --git a/chromium/third_party/blink/renderer/core/scroll/scrollable_area_test.cc b/chromium/third_party/blink/renderer/core/scroll/scrollable_area_test.cc
index 360fcc24749..d5f03654e69 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollable_area_test.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollable_area_test.cc
@@ -24,8 +24,26 @@ namespace blink {
namespace {
using testing::_;
+using testing::Mock;
using testing::Return;
+class MockAnimatingScrollableArea : public MockScrollableArea {
+ public:
+ static MockAnimatingScrollableArea* Create() {
+ return MakeGarbageCollected<MockAnimatingScrollableArea>();
+ }
+ static MockAnimatingScrollableArea* Create(
+ const ScrollOffset& maximum_scroll_offset) {
+ MockAnimatingScrollableArea* mock = Create();
+ mock->SetMaximumScrollOffset(maximum_scroll_offset);
+ return mock;
+ }
+ Scrollbar* HorizontalScrollbar() const override { return nullptr; }
+ Scrollbar* VerticalScrollbar() const override { return nullptr; }
+ MOCK_CONST_METHOD0(ScrollAnimatorEnabled, bool());
+ MOCK_METHOD0(ScheduleAnimation, bool());
+};
+
class ScrollbarThemeWithMockInvalidation : public ScrollbarThemeOverlayMock {
public:
MOCK_CONST_METHOD0(ShouldRepaintAllPartsOnInvalidation, bool());
@@ -43,7 +61,8 @@ TEST_F(ScrollableAreaTest, ScrollAnimatorCurrentPositionShouldBeSync) {
MockScrollableArea* scrollable_area =
MockScrollableArea::Create(ScrollOffset(0, 100));
- scrollable_area->SetScrollOffset(ScrollOffset(0, 10000), kCompositorScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 10000),
+ mojom::blink::ScrollType::kCompositor);
EXPECT_EQ(100.0,
scrollable_area->GetScrollAnimator().CurrentOffset().Height());
}
@@ -146,11 +165,13 @@ TEST_F(ScrollableAreaTest, InvalidatesNonCompositedScrollbarsWhenThumbMoves) {
.WillRepeatedly(Return(kNoPart));
// A scroll in each direction should only invalidate one scrollbar.
- scrollable_area->SetScrollOffset(ScrollOffset(0, 50), kProgrammaticScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 50),
+ mojom::blink::ScrollType::kProgrammatic);
EXPECT_FALSE(scrollable_area->HorizontalScrollbarNeedsPaintInvalidation());
EXPECT_TRUE(scrollable_area->VerticalScrollbarNeedsPaintInvalidation());
scrollable_area->ClearNeedsPaintInvalidationForScrollControls();
- scrollable_area->SetScrollOffset(ScrollOffset(50, 50), kProgrammaticScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(50, 50),
+ mojom::blink::ScrollType::kProgrammatic);
EXPECT_TRUE(scrollable_area->HorizontalScrollbarNeedsPaintInvalidation());
EXPECT_FALSE(scrollable_area->VerticalScrollbarNeedsPaintInvalidation());
scrollable_area->ClearNeedsPaintInvalidationForScrollControls();
@@ -203,7 +224,8 @@ TEST_F(ScrollableAreaTest, InvalidatesCompositedScrollbarsIfPartsNeedRepaint) {
// the back button (i.e. the track).
EXPECT_CALL(theme, PartsToInvalidateOnThumbPositionChange(_, _, _))
.WillOnce(Return(kBackButtonStartPart));
- scrollable_area->SetScrollOffset(ScrollOffset(50, 0), kProgrammaticScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(50, 0),
+ mojom::blink::ScrollType::kProgrammatic);
EXPECT_FALSE(layer_for_horizontal_scrollbar->update_rect().IsEmpty());
EXPECT_TRUE(layer_for_vertical_scrollbar->update_rect().IsEmpty());
EXPECT_TRUE(horizontal_scrollbar->TrackNeedsRepaint());
@@ -214,7 +236,8 @@ TEST_F(ScrollableAreaTest, InvalidatesCompositedScrollbarsIfPartsNeedRepaint) {
// Next, we'll scroll vertically, but invalidate the thumb.
EXPECT_CALL(theme, PartsToInvalidateOnThumbPositionChange(_, _, _))
.WillOnce(Return(kThumbPart));
- scrollable_area->SetScrollOffset(ScrollOffset(50, 50), kProgrammaticScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(50, 50),
+ mojom::blink::ScrollType::kProgrammatic);
EXPECT_TRUE(layer_for_horizontal_scrollbar->update_rect().IsEmpty());
EXPECT_FALSE(layer_for_vertical_scrollbar->update_rect().IsEmpty());
EXPECT_FALSE(vertical_scrollbar->TrackNeedsRepaint());
@@ -229,7 +252,8 @@ TEST_F(ScrollableAreaTest, InvalidatesCompositedScrollbarsIfPartsNeedRepaint) {
EXPECT_CALL(theme, PartsToInvalidateOnThumbPositionChange(_, _, _))
.Times(2)
.WillRepeatedly(Return(kNoPart));
- scrollable_area->SetScrollOffset(ScrollOffset(70, 70), kProgrammaticScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(70, 70),
+ mojom::blink::ScrollType::kProgrammatic);
EXPECT_FALSE(layer_for_horizontal_scrollbar->update_rect().IsEmpty());
EXPECT_FALSE(layer_for_vertical_scrollbar->update_rect().IsEmpty());
EXPECT_FALSE(horizontal_scrollbar->TrackNeedsRepaint());
@@ -270,6 +294,37 @@ TEST_F(ScrollableAreaTest, ScrollableAreaDidScroll) {
EXPECT_EQ(51, scrollable_area->ScrollOffsetInt().Height());
}
+TEST_F(ScrollableAreaTest, ProgrammaticScrollRespectAnimatorEnabled) {
+ ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
+ platform;
+ MockAnimatingScrollableArea* scrollable_area =
+ MockAnimatingScrollableArea::Create(ScrollOffset(0, 100));
+ // Disable animations. Make sure an explicitly smooth programmatic scroll is
+ // instantly scrolled.
+ {
+ EXPECT_CALL(*scrollable_area, ScrollAnimatorEnabled())
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(*scrollable_area, ScheduleAnimation()).Times(0);
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 100),
+ mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kSmooth);
+ EXPECT_EQ(100, scrollable_area->GetScrollOffset().Height());
+ }
+ Mock::VerifyAndClearExpectations(scrollable_area);
+ // Enable animations. A smooth programmatic scroll should now schedule an
+ // animation rather than immediately mutating the offset.
+ {
+ EXPECT_CALL(*scrollable_area, ScrollAnimatorEnabled())
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(*scrollable_area, ScheduleAnimation()).WillOnce(Return(true));
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 50),
+ mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kSmooth);
+ // Offset is unchanged.
+ EXPECT_EQ(100, scrollable_area->GetScrollOffset().Height());
+ }
+}
+
// Scrollbars in popups shouldn't fade out since they aren't composited and thus
// they don't appear on hover so users without a wheel can't scroll if they fade
// out.
@@ -292,7 +347,7 @@ TEST_F(ScrollableAreaTest, PopupOverlayScrollbarShouldNotFadeOut) {
DCHECK(scrollbar->IsOverlayScrollbar());
DCHECK(scrollbar->Enabled());
- scrollable_area->ShowOverlayScrollbars();
+ scrollable_area->ShowNonMacOverlayScrollbars();
// No fade out animation should be posted.
EXPECT_FALSE(scrollable_area->fade_overlay_scrollbars_timer_);
@@ -311,7 +366,8 @@ TEST_F(ScrollableAreaTest, ScrollAnimatorCallbackFiresOnAnimationCancel) {
.WillRepeatedly(Return(true));
bool finished = false;
scrollable_area->SetScrollOffset(
- ScrollOffset(0, 10000), kProgrammaticScroll, kScrollBehaviorSmooth,
+ ScrollOffset(0, 10000), mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kSmooth,
ScrollableArea::ScrollCallback(
base::BindOnce([](bool* finished) { *finished = true; }, &finished)));
EXPECT_EQ(0.0, scrollable_area->GetScrollAnimator().CurrentOffset().Height());
@@ -331,7 +387,8 @@ TEST_F(ScrollableAreaTest, ScrollAnimatorCallbackFiresOnInstantScroll) {
.WillRepeatedly(Return(true));
bool finished = false;
scrollable_area->SetScrollOffset(
- ScrollOffset(0, 10000), kProgrammaticScroll, kScrollBehaviorInstant,
+ ScrollOffset(0, 10000), mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kInstant,
ScrollableArea::ScrollCallback(
base::BindOnce([](bool* finished) { *finished = true; }, &finished)));
EXPECT_EQ(100, scrollable_area->GetScrollAnimator().CurrentOffset().Height());
@@ -348,7 +405,8 @@ TEST_F(ScrollableAreaTest, ScrollAnimatorCallbackFiresOnAnimationFinish) {
.WillRepeatedly(Return(true));
bool finished = false;
scrollable_area->SetScrollOffset(
- ScrollOffset(0, 9), kProgrammaticScroll, kScrollBehaviorSmooth,
+ ScrollOffset(0, 9), mojom::blink::ScrollType::kProgrammatic,
+ mojom::blink::ScrollBehavior::kSmooth,
ScrollableArea::ScrollCallback(
base::BindOnce([](bool* finished) { *finished = true; }, &finished)));
EXPECT_EQ(0.0, scrollable_area->GetScrollAnimator().CurrentOffset().Height());
diff --git a/chromium/third_party/blink/renderer/core/scroll/scrollbar.cc b/chromium/third_party/blink/renderer/core/scroll/scrollbar.cc
index 9cfbe4acc1e..ac4f250c127 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollbar.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar.cc
@@ -28,8 +28,8 @@
#include <algorithm>
#include "base/feature_list.h"
#include "third_party/blink/public/common/features.h"
-#include "third_party/blink/public/platform/web_gesture_event.h"
-#include "third_party/blink/public/platform/web_mouse_event.h"
+#include "third_party/blink/public/common/input/web_gesture_event.h"
+#include "third_party/blink/public/common/input/web_mouse_event.h"
#include "third_party/blink/public/platform/web_scrollbar_overlay_color_theme.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
@@ -39,6 +39,7 @@
#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/text/text_direction.h"
+#include "ui/base/ui_base_features.h"
namespace blink {
@@ -71,6 +72,7 @@ Scrollbar::Scrollbar(ScrollableArea* scrollable_area,
track_needs_repaint_(true),
thumb_needs_repaint_(true),
injected_gesture_scroll_begin_(false),
+ scrollbar_manipulation_in_progress_on_cc_thread_(false),
style_source_(style_source) {
theme_.RegisterScrollbar(*this);
@@ -91,7 +93,7 @@ Scrollbar::Scrollbar(ScrollableArea* scrollable_area,
Scrollbar::~Scrollbar() = default;
-void Scrollbar::Trace(blink::Visitor* visitor) {
+void Scrollbar::Trace(Visitor* visitor) {
visitor->Trace(scrollable_area_);
visitor->Trace(chrome_client_);
visitor->Trace(style_source_);
@@ -140,7 +142,7 @@ int Scrollbar::Maximum() const {
: max_offset.Height();
}
-void Scrollbar::OffsetDidChange() {
+void Scrollbar::OffsetDidChange(mojom::blink::ScrollType scroll_type) {
DCHECK(scrollable_area_);
float position = ScrollableAreaCurrentPos();
@@ -156,9 +158,13 @@ void Scrollbar::OffsetDidChange() {
position);
SetNeedsPaintInvalidation(invalid_parts);
- if (pressed_part_ == kThumbPart)
+ // Don't update the pressed position if scroll anchoring takes place as
+ // otherwise the next thumb movement will undo anchoring.
+ if (pressed_part_ == kThumbPart &&
+ scroll_type != mojom::blink::ScrollType::kAnchoring) {
SetPressedPos(pressed_pos_ + GetTheme().ThumbPosition(*this) -
old_thumb_position);
+ }
}
void Scrollbar::DisconnectFromScrollableArea() {
@@ -175,8 +181,9 @@ void Scrollbar::SetProportion(int visible_size, int total_size) {
SetNeedsPaintInvalidation(kAllParts);
}
-void Scrollbar::Paint(GraphicsContext& context) const {
- GetTheme().Paint(*this, context);
+void Scrollbar::Paint(GraphicsContext& context,
+ const IntPoint& paint_offset) const {
+ GetTheme().Paint(*this, context, paint_offset);
}
void Scrollbar::AutoscrollTimerFired(TimerBase*) {
@@ -258,8 +265,11 @@ ScrollGranularity Scrollbar::PressedPartScrollGranularity() {
if (pressed_part_ == kBackButtonStartPart ||
pressed_part_ == kBackButtonEndPart ||
pressed_part_ == kForwardButtonStartPart ||
- pressed_part_ == kForwardButtonEndPart)
- return ScrollGranularity::kScrollByLine;
+ pressed_part_ == kForwardButtonEndPart) {
+ return RuntimeEnabledFeatures::PercentBasedScrollingEnabled()
+ ? ScrollGranularity::kScrollByPercentage
+ : ScrollGranularity::kScrollByLine;
+ }
return ScrollGranularity::kScrollByPage;
}
@@ -349,7 +359,8 @@ bool Scrollbar::GestureEvent(const WebGestureEvent& evt,
switch (evt.GetType()) {
case WebInputEvent::kGestureTapDown: {
IntPoint position = FlooredIntPoint(evt.PositionInRootFrame());
- SetPressedPart(GetTheme().HitTest(*this, position), evt.GetType());
+ SetPressedPart(GetTheme().HitTestRootFramePosition(*this, position),
+ evt.GetType());
pressed_pos_ = Orientation() == kHorizontalScrollbar
? ConvertFromRootFrame(position).X()
: ConvertFromRootFrame(position).Y();
@@ -443,6 +454,15 @@ bool Scrollbar::HandleTapGesture() {
void Scrollbar::MouseMoved(const WebMouseEvent& evt) {
IntPoint position = FlooredIntPoint(evt.PositionInRootFrame());
+ ScrollbarPart part = GetTheme().HitTestRootFramePosition(*this, position);
+
+ // If the WebMouseEvent was already handled on the compositor thread, simply
+ // set up the ScrollbarPart for invalidation and exit.
+ if (scrollbar_manipulation_in_progress_on_cc_thread_) {
+ SetHoveredPart(part);
+ return;
+ }
+
if (pressed_part_ == kThumbPart) {
if (GetTheme().ShouldSnapBackToDragOrigin(*this, evt)) {
if (scrollable_area_) {
@@ -465,7 +485,6 @@ void Scrollbar::MouseMoved(const WebMouseEvent& evt) {
: ConvertFromRootFrame(position).Y();
}
- ScrollbarPart part = GetTheme().HitTest(*this, position);
if (part != hovered_part_) {
if (pressed_part_ != kNoPart) {
if (part == pressed_part_) {
@@ -499,6 +518,11 @@ void Scrollbar::MouseExited() {
void Scrollbar::MouseUp(const WebMouseEvent& mouse_event) {
bool is_captured = pressed_part_ == kThumbPart;
SetPressedPart(kNoPart, mouse_event.GetType());
+ if (scrollbar_manipulation_in_progress_on_cc_thread_) {
+ scrollbar_manipulation_in_progress_on_cc_thread_ = false;
+ return;
+ }
+
pressed_pos_ = 0;
dragging_document_ = false;
StopTimerIfNeeded();
@@ -511,7 +535,7 @@ void Scrollbar::MouseUp(const WebMouseEvent& mouse_event) {
ScrollableArea::GetForScrolling(scrollable_area_->GetLayoutBox());
scrollable_area_for_scrolling->SnapAfterScrollbarScrolling(orientation_);
- ScrollbarPart part = GetTheme().HitTest(
+ ScrollbarPart part = GetTheme().HitTestRootFramePosition(
*this, FlooredIntPoint(mouse_event.PositionInRootFrame()));
if (part == kNoPart) {
SetHoveredPart(kNoPart);
@@ -528,7 +552,21 @@ void Scrollbar::MouseDown(const WebMouseEvent& evt) {
return;
IntPoint position = FlooredIntPoint(evt.PositionInRootFrame());
- SetPressedPart(GetTheme().HitTest(*this, position), evt.GetType());
+ SetPressedPart(GetTheme().HitTestRootFramePosition(*this, position),
+ evt.GetType());
+
+ // Scrollbar manipulation (for a mouse) always begins with a MouseDown. If
+ // this is already being handled by the compositor thread, blink::Scrollbar
+ // needs to be made aware of this. It also means that, all the actions which
+ // follow (like MouseMove(s) and MouseUp) will also be handled on the cc
+ // thread. However, the scrollbar parts still need to be invalidated on the
+ // main thread.
+ scrollbar_manipulation_in_progress_on_cc_thread_ =
+ evt.GetModifiers() &
+ WebInputEvent::Modifiers::kScrollbarManipulationHandledOnCompositorThread;
+ if (scrollbar_manipulation_in_progress_on_cc_thread_)
+ return;
+
int pressed_pos = Orientation() == kHorizontalScrollbar
? ConvertFromRootFrame(position).X()
: ConvertFromRootFrame(position).Y();
@@ -561,8 +599,10 @@ void Scrollbar::MouseDown(const WebMouseEvent& evt) {
void Scrollbar::InjectScrollGestureForPressedPart(
WebInputEvent::Type gesture_type) {
- ScrollOffset delta = ToScrollDelta(PressedPartScrollDirectionPhysical(), 1);
ScrollGranularity granularity = PressedPartScrollGranularity();
+ ScrollOffset delta =
+ ToScrollDelta(PressedPartScrollDirectionPhysical(),
+ ScrollableArea::DirectionBasedScrollDelta(granularity));
InjectScrollGesture(gesture_type, delta, granularity);
}
@@ -647,9 +687,9 @@ bool Scrollbar::DeltaWillScroll(ScrollOffset delta) const {
return clamped_offset != current_offset;
}
-void Scrollbar::SetScrollbarsHiddenIfOverlay(bool hidden) {
+void Scrollbar::SetScrollbarsHiddenFromExternalAnimator(bool hidden) {
if (scrollable_area_)
- scrollable_area_->SetScrollbarsHiddenIfOverlay(hidden);
+ scrollable_area_->SetScrollbarsHiddenFromExternalAnimator(hidden);
}
void Scrollbar::SetEnabled(bool e) {
@@ -770,7 +810,7 @@ CompositorElementId Scrollbar::GetElementId() {
}
float Scrollbar::EffectiveZoom() const {
- if (RuntimeEnabledFeatures::FormControlsRefreshEnabled() && style_source_ &&
+ if (::features::IsFormControlsRefreshEnabled() && style_source_ &&
style_source_->GetLayoutObject()) {
return style_source_->GetLayoutObject()->Style()->EffectiveZoom();
}
@@ -778,7 +818,7 @@ float Scrollbar::EffectiveZoom() const {
}
bool Scrollbar::ContainerIsRightToLeft() const {
- if (RuntimeEnabledFeatures::FormControlsRefreshEnabled() && style_source_ &&
+ if (::features::IsFormControlsRefreshEnabled() && style_source_ &&
style_source_->GetLayoutObject()) {
TextDirection dir = style_source_->GetLayoutObject()->Style()->Direction();
return IsRtl(dir);
diff --git a/chromium/third_party/blink/renderer/core/scroll/scrollbar.h b/chromium/third_party/blink/renderer/core/scroll/scrollbar.h
index 544461b7296..5082cb9232a 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollbar.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar.h
@@ -99,7 +99,7 @@ class CORE_EXPORT Scrollbar : public GarbageCollected<Scrollbar>,
ScrollbarPart HoveredPart() const { return hovered_part_; }
virtual void StyleChanged() {}
- void SetScrollbarsHiddenIfOverlay(bool);
+ void SetScrollbarsHiddenFromExternalAnimator(bool);
bool Enabled() const { return enabled_; }
virtual void SetEnabled(bool);
@@ -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();
+ void OffsetDidChange(mojom::blink::ScrollType scroll_type);
virtual void DisconnectFromScrollableArea();
ScrollableArea* GetScrollableArea() const { return scrollable_area_; }
@@ -124,7 +124,7 @@ class CORE_EXPORT Scrollbar : public GarbageCollected<Scrollbar>,
void SetProportion(int visible_size, int total_size);
void SetPressedPos(int p) { pressed_pos_ = p; }
- void Paint(GraphicsContext&) const;
+ void Paint(GraphicsContext&, const IntPoint& paint_offset) const;
virtual bool IsSolidColor() const;
virtual bool IsOverlayScrollbar() const;
@@ -204,7 +204,7 @@ class CORE_EXPORT Scrollbar : public GarbageCollected<Scrollbar>,
WebColorScheme UsedColorScheme() const;
- virtual void Trace(blink::Visitor*);
+ virtual void Trace(Visitor*);
protected:
void AutoscrollTimerFired(TimerBase*);
@@ -254,6 +254,15 @@ class CORE_EXPORT Scrollbar : public GarbageCollected<Scrollbar>,
bool track_needs_repaint_;
bool thumb_needs_repaint_;
bool injected_gesture_scroll_begin_;
+
+ // This is set based on the event modifiers. In scenarios like scrolling or
+ // layout, the element that the cursor is over can change without the cursor
+ // itself moving. In these cases, a "fake" mouse move may be dispatched (see
+ // MouseEventManager::RecomputeMouseHoverState) in order to apply hover etc.
+ // Such mouse events do not have the modifier set and hence, maintaining this
+ // additional state is necessary.
+ bool scrollbar_manipulation_in_progress_on_cc_thread_;
+
IntRect visual_rect_;
IntRect frame_rect_;
Member<Element> style_source_;
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 5aa2c734198..e8ba3ace2fb 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
@@ -84,29 +84,22 @@ bool ScrollbarLayerDelegate::SupportsDragSnapBack() const {
}
gfx::Rect ScrollbarLayerDelegate::BackButtonRect() const {
- if (scrollbar_->GetTheme().ButtonsPlacement() ==
- kWebScrollbarButtonsPlacementNone)
- return gfx::Rect();
-
- IntRect back_button_rect = scrollbar_->GetTheme().BackButtonRect(
- *scrollbar_, blink::kBackButtonStartPart);
- back_button_rect.MoveBy(-scrollbar_->Location());
+ IntRect back_button_rect = scrollbar_->GetTheme().BackButtonRect(*scrollbar_);
+ if (!back_button_rect.IsEmpty())
+ back_button_rect.MoveBy(-scrollbar_->Location());
return back_button_rect;
}
gfx::Rect ScrollbarLayerDelegate::ForwardButtonRect() const {
- if (scrollbar_->GetTheme().ButtonsPlacement() ==
- kWebScrollbarButtonsPlacementNone)
- return gfx::Rect();
-
- IntRect forward_button_rect = scrollbar_->GetTheme().ForwardButtonRect(
- *scrollbar_, blink::kForwardButtonEndPart);
- forward_button_rect.MoveBy(-scrollbar_->Location());
+ IntRect forward_button_rect =
+ scrollbar_->GetTheme().ForwardButtonRect(*scrollbar_);
+ if (!forward_button_rect.IsEmpty())
+ forward_button_rect.MoveBy(-scrollbar_->Location());
return forward_button_rect;
}
-float ScrollbarLayerDelegate::ThumbOpacity() const {
- return scrollbar_->GetTheme().ThumbOpacity(*scrollbar_);
+float ScrollbarLayerDelegate::Opacity() const {
+ return scrollbar_->GetTheme().Opacity(*scrollbar_);
}
bool ScrollbarLayerDelegate::NeedsRepaintPart(cc::ScrollbarPart part) const {
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 42b85882059..0275a3b9284 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
@@ -35,7 +35,7 @@ class CORE_EXPORT ScrollbarLayerDelegate : public cc::Scrollbar {
gfx::Rect BackButtonRect() const override;
gfx::Rect ForwardButtonRect() const override;
- float ThumbOpacity() const override;
+ float Opacity() const override;
bool NeedsRepaintPart(cc::ScrollbarPart part) const override;
bool HasTickmarks() const override;
void PaintPart(cc::PaintCanvas* canvas,
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 dbb84c9a9ee..8871777f578 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
@@ -78,7 +78,8 @@ class MockScrollableArea : public GarbageCollected<MockScrollableArea>,
bool UserInputScrollable(ScrollbarOrientation) const override { return true; }
bool ScrollbarsCanBeActive() const override { return true; }
bool ShouldPlaceVerticalScrollbarOnLeft() const override { return false; }
- void UpdateScrollOffset(const ScrollOffset& offset, ScrollType) override {
+ void UpdateScrollOffset(const ScrollOffset& offset,
+ mojom::blink::ScrollType) override {
scroll_offset_ = offset.ShrunkTo(maximum_scroll_offset_);
}
IntSize ScrollOffsetInt() const override {
@@ -93,9 +94,17 @@ class MockScrollableArea : public GarbageCollected<MockScrollableArea>,
CompositorElementId GetScrollElementId() const override {
return CompositorElementId();
}
- bool ScrollAnimatorEnabled() const override { return false; }
+ bool ScrollAnimatorEnabled() const override { return true; }
int PageStep(ScrollbarOrientation) const override { return 0; }
void ScrollControlWasSetNeedsPaintInvalidation() override {}
+ IntPoint ConvertFromRootFrame(const IntPoint& point_in_root_frame) const {
+ return point_in_root_frame;
+ }
+ IntPoint ConvertFromContainingEmbeddedContentViewToScrollbar(
+ const Scrollbar& scrollbar,
+ const IntPoint& parent_point) const {
+ return parent_point;
+ }
scoped_refptr<base::SingleThreadTaskRunner> GetTimerTaskRunner() const final {
return blink::scheduler::GetSingleThreadTaskRunnerForTesting();
@@ -111,21 +120,22 @@ class MockScrollableArea : public GarbageCollected<MockScrollableArea>,
return ScrollbarTheme::GetTheme();
}
- using ScrollableArea::ShowOverlayScrollbars;
+ using ScrollableArea::ClearNeedsPaintInvalidationForScrollControls;
using ScrollableArea::HorizontalScrollbarNeedsPaintInvalidation;
+ using ScrollableArea::ShowNonMacOverlayScrollbars;
using ScrollableArea::VerticalScrollbarNeedsPaintInvalidation;
- using ScrollableArea::ClearNeedsPaintInvalidationForScrollControls;
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(chrome_client_);
ScrollableArea::Trace(visitor);
}
- private:
+ protected:
void SetMaximumScrollOffset(const ScrollOffset& maximum_scroll_offset) {
maximum_scroll_offset_ = maximum_scroll_offset;
}
+ private:
ScrollOffset scroll_offset_;
ScrollOffset maximum_scroll_offset_;
Member<MockPlatformChromeClient> chrome_client_;
diff --git a/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme.cc b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme.cc
index 1478704a8eb..2f8f6dc37aa 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme.cc
@@ -28,9 +28,8 @@
#include "base/optional.h"
#include "build/build_config.h"
#include "cc/input/scrollbar.h"
+#include "third_party/blink/public/common/input/web_mouse_event.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_mouse_event.h"
-#include "third_party/blink/public/platform/web_point.h"
#include "third_party/blink/public/platform/web_rect.h"
#include "third_party/blink/renderer/core/scroll/scrollbar.h"
#include "third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_mock.h"
@@ -50,29 +49,37 @@
namespace blink {
void ScrollbarTheme::Paint(const Scrollbar& scrollbar,
- GraphicsContext& graphics_context) {
- PaintTrackButtonsTickmarks(graphics_context, scrollbar, IntPoint());
+ GraphicsContext& graphics_context,
+ const IntPoint& paint_offset) {
+ PaintTrackButtonsTickmarks(graphics_context, scrollbar, paint_offset);
- IntRect thumb_rect = ThumbRect(scrollbar);
- if (HasThumb(scrollbar))
+ if (HasThumb(scrollbar)) {
+ IntRect thumb_rect = ThumbRect(scrollbar);
+ thumb_rect.MoveBy(paint_offset);
PaintThumbWithOpacity(graphics_context, scrollbar, thumb_rect);
+ }
}
-ScrollbarPart ScrollbarTheme::HitTest(const Scrollbar& scrollbar,
- const IntPoint& position_in_root_frame) {
- ScrollbarPart result = kNoPart;
+ScrollbarPart ScrollbarTheme::HitTestRootFramePosition(
+ const Scrollbar& scrollbar,
+ const IntPoint& position_in_root_frame) {
+ if (!AllowsHitTest())
+ return kNoPart;
+
if (!scrollbar.Enabled())
- return result;
+ return kNoPart;
IntPoint test_position =
scrollbar.ConvertFromRootFrame(position_in_root_frame);
test_position.Move(scrollbar.X(), scrollbar.Y());
+ return HitTest(scrollbar, test_position);
+}
+ScrollbarPart ScrollbarTheme::HitTest(const Scrollbar& scrollbar,
+ const IntPoint& test_position) {
if (!scrollbar.FrameRect().Contains(test_position))
return kNoPart;
- result = kScrollbarBGPart;
-
IntRect track = TrackRect(scrollbar);
if (track.Contains(test_position)) {
IntRect before_thumb_rect;
@@ -81,27 +88,20 @@ ScrollbarPart ScrollbarTheme::HitTest(const Scrollbar& scrollbar,
SplitTrack(scrollbar, track, before_thumb_rect, thumb_rect,
after_thumb_rect);
if (thumb_rect.Contains(test_position))
- result = kThumbPart;
- else if (before_thumb_rect.Contains(test_position))
- result = kBackTrackPart;
- else if (after_thumb_rect.Contains(test_position))
- result = kForwardTrackPart;
- else
- result = kTrackBGPart;
- } else if (BackButtonRect(scrollbar, kBackButtonStartPart)
- .Contains(test_position)) {
- result = kBackButtonStartPart;
- } else if (BackButtonRect(scrollbar, kBackButtonEndPart)
- .Contains(test_position)) {
- result = kBackButtonEndPart;
- } else if (ForwardButtonRect(scrollbar, kForwardButtonStartPart)
- .Contains(test_position)) {
- result = kForwardButtonStartPart;
- } else if (ForwardButtonRect(scrollbar, kForwardButtonEndPart)
- .Contains(test_position)) {
- result = kForwardButtonEndPart;
+ return kThumbPart;
+ if (before_thumb_rect.Contains(test_position))
+ return kBackTrackPart;
+ if (after_thumb_rect.Contains(test_position))
+ return kForwardTrackPart;
+ return kTrackBGPart;
}
- return result;
+
+ if (BackButtonRect(scrollbar).Contains(test_position))
+ return kBackButtonStartPart;
+ if (ForwardButtonRect(scrollbar).Contains(test_position))
+ return kForwardButtonEndPart;
+
+ return kScrollbarBGPart;
}
void ScrollbarTheme::PaintScrollCorner(
@@ -312,19 +312,13 @@ void ScrollbarTheme::PaintTrackAndButtons(GraphicsContext& context,
DisplayItem::kScrollbarTrackAndButtons);
if (HasButtons(scrollbar)) {
- IntRect back_button_rect = BackButtonRect(scrollbar, kBackButtonStartPart);
+ IntRect back_button_rect = BackButtonRect(scrollbar);
back_button_rect.MoveBy(offset);
PaintButton(context, scrollbar, back_button_rect, kBackButtonStartPart);
- IntRect forward_button_rect =
- ForwardButtonRect(scrollbar, kForwardButtonEndPart);
+ IntRect forward_button_rect = ForwardButtonRect(scrollbar);
forward_button_rect.MoveBy(offset);
PaintButton(context, scrollbar, forward_button_rect, kForwardButtonEndPart);
-
- // Non-custom scrollbars don't have kBackButtonEndPart and
- // kForwardButtonStartPart.
- DCHECK(BackButtonRect(scrollbar, kBackButtonEndPart).IsEmpty());
- DCHECK(ForwardButtonRect(scrollbar, kForwardButtonStartPart).IsEmpty());
}
IntRect track_rect = TrackRect(scrollbar);
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 15f19729947..acbfd1d3912 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme.h
@@ -26,7 +26,6 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_THEME_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_THEME_H_
-#include "third_party/blink/public/platform/web_scrollbar_buttons_placement.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/scroll/scroll_types.h"
#include "third_party/blink/renderer/core/scroll/scrollbar.h"
@@ -55,9 +54,11 @@ class CORE_EXPORT ScrollbarTheme {
virtual void UpdateEnabledState(const Scrollbar&) {}
// |context|'s current space is the space of the scrollbar's FrameRect().
- void Paint(const Scrollbar&, GraphicsContext& context);
+ void Paint(const Scrollbar&,
+ GraphicsContext& context,
+ const IntPoint& paint_offset);
- virtual ScrollbarPart HitTest(const Scrollbar&, const IntPoint&);
+ ScrollbarPart HitTestRootFramePosition(const Scrollbar&, const IntPoint&);
// This returns a fixed value regardless of device-scale-factor.
// This returns thickness when scrollbar is painted. i.e. It's not 0 even in
@@ -68,10 +69,6 @@ class CORE_EXPORT ScrollbarTheme {
}
virtual int ScrollbarMargin() const { return 0; }
- virtual WebScrollbarButtonsPlacement ButtonsPlacement() const {
- return kWebScrollbarButtonsPlacementSingle;
- }
-
virtual bool IsSolidColor() const { return false; }
virtual bool UsesOverlayScrollbars() const { return false; }
virtual void UpdateScrollbarOverlayColorTheme(const Scrollbar&) {}
@@ -83,6 +80,13 @@ class CORE_EXPORT ScrollbarTheme {
// to prevent painting it.
virtual bool ShouldDisableInvisibleScrollbars() const { return true; }
+ // If true, Blink is in charge of hiding/showing of overlay scrollbars. As
+ // above, this option exists because on Mac the visibility is controlled by
+ // Mac painting code which Blink doesn't have an input into. In order to
+ // prevent the two from getting out of sync we disable setting the Blink-side
+ // parameter on Mac.
+ virtual bool BlinkControlsOverlayVisibility() const { return true; }
+
virtual bool InvalidateOnMouseEnterExit() { return false; }
// Returns parts of the scrollbar which must be repainted following a change
@@ -132,17 +136,22 @@ class CORE_EXPORT ScrollbarTheme {
virtual int TrackPosition(const Scrollbar&);
// The length of the track along the axis of the scrollbar.
virtual int TrackLength(const Scrollbar&);
- // The opacity to be applied to the thumb. A theme overriding ThumbOpacity()
+ // The opacity to be applied to the scrollbar. A theme overriding Opacity()
// should also override PaintThumbWithOpacity().
- virtual float ThumbOpacity(const Scrollbar&) const { return 1.0f; }
+ virtual float Opacity(const Scrollbar&) const { return 1.0f; }
+
+ // Whether the native theme of the OS has scrollbar buttons.
+ virtual bool NativeThemeHasButtons() = 0;
+ // Whether the scrollbar has buttons. It's the same as NativeThemeHasButtons()
+ // except for custom scrollbars which can override the OS settings.
+ virtual bool HasButtons(const Scrollbar&) { return NativeThemeHasButtons(); }
- virtual bool HasButtons(const Scrollbar&) = 0;
virtual bool HasThumb(const Scrollbar&) = 0;
// All these rects are in the same coordinate space as the scrollbar's
// FrameRect.
- virtual IntRect BackButtonRect(const Scrollbar&, ScrollbarPart) = 0;
- virtual IntRect ForwardButtonRect(const Scrollbar&, ScrollbarPart) = 0;
+ virtual IntRect BackButtonRect(const Scrollbar&) = 0;
+ virtual IntRect ForwardButtonRect(const Scrollbar&) = 0;
virtual IntRect TrackRect(const Scrollbar&) = 0;
virtual IntRect ThumbRect(const Scrollbar&);
virtual int ThumbThickness(const Scrollbar&);
@@ -200,6 +209,9 @@ class CORE_EXPORT ScrollbarTheme {
virtual bool AllowsHitTest() const { return true; }
protected:
+ // The point is in the same coordinate space as the scrollbar's FrameRect.
+ virtual ScrollbarPart HitTest(const Scrollbar&, const IntPoint&);
+
virtual int TickmarkBorderWidth() { return 0; }
virtual void PaintTrack(GraphicsContext&, const Scrollbar&, const IntRect&) {}
virtual void PaintButton(GraphicsContext&,
@@ -213,13 +225,13 @@ class CORE_EXPORT ScrollbarTheme {
const Scrollbar&,
const IntPoint& offset);
- // Paint the thumb with ThumbOpacity() applied.
+ // Paint the thumb with Opacity() applied.
virtual void PaintThumbWithOpacity(GraphicsContext& context,
const Scrollbar& scrollbar,
const IntRect& rect) {
// By default this method just calls PaintThumb(). A theme with custom
- // ThumbOpacity() should override this method to apply the opacity.
- DCHECK_EQ(1.0f, ThumbOpacity(scrollbar));
+ // Opacity() should override this method to apply the opacity.
+ DCHECK_EQ(1.0f, Opacity(scrollbar));
PaintThumb(context, scrollbar, rect);
}
diff --git a/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.cc b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.cc
index 5952afb54a6..a97ee2b26f4 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.cc
@@ -32,8 +32,8 @@
#include "build/build_config.h"
#include "cc/input/scrollbar.h"
+#include "third_party/blink/public/common/input/web_mouse_event.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_mouse_event.h"
#include "third_party/blink/public/platform/web_rect.h"
#include "third_party/blink/public/platform/web_theme_engine.h"
#include "third_party/blink/renderer/core/scroll/scrollable_area.h"
@@ -139,9 +139,9 @@ bool ScrollbarThemeAura::SupportsDragSnapBack() const {
// is true for at least GTK and QT apps).
#if (defined(OS_LINUX) && !defined(OS_CHROMEOS))
return false;
-#endif
-
+#else
return true;
+#endif
}
int ScrollbarThemeAura::ScrollbarThickness(ScrollbarControlSize control_size) {
@@ -160,22 +160,12 @@ bool ScrollbarThemeAura::HasThumb(const Scrollbar& scrollbar) {
return ThumbLength(scrollbar) > 0;
}
-IntRect ScrollbarThemeAura::BackButtonRect(const Scrollbar& scrollbar,
- ScrollbarPart part) {
- // Windows and Linux just have single arrows.
- if (part == kBackButtonEndPart)
- return IntRect();
-
+IntRect ScrollbarThemeAura::BackButtonRect(const Scrollbar& scrollbar) {
IntSize size = ButtonSize(scrollbar);
return IntRect(scrollbar.X(), scrollbar.Y(), size.Width(), size.Height());
}
-IntRect ScrollbarThemeAura::ForwardButtonRect(const Scrollbar& scrollbar,
- ScrollbarPart part) {
- // Windows and Linux just have single arrows.
- if (part == kForwardButtonStartPart)
- return IntRect();
-
+IntRect ScrollbarThemeAura::ForwardButtonRect(const Scrollbar& scrollbar) {
IntSize size = ButtonSize(scrollbar);
int x, y;
if (scrollbar.Orientation() == kHorizontalScrollbar) {
@@ -299,7 +289,6 @@ ScrollbarPart ScrollbarThemeAura::PartsToInvalidateOnThumbPositionChange(
float old_position,
float new_position) const {
ScrollbarPart invalid_parts = kNoPart;
- DCHECK_EQ(ButtonsPlacement(), kWebScrollbarButtonsPlacementSingle);
static const ScrollbarPart kButtonParts[] = {kBackButtonStartPart,
kForwardButtonEndPart};
for (ScrollbarPart part : kButtonParts) {
diff --git a/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.h b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.h
index b73ced6647b..ed0c7bc4227 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.h
@@ -41,11 +41,11 @@ class CORE_EXPORT ScrollbarThemeAura : public ScrollbarTheme {
int ScrollbarThickness(ScrollbarControlSize) override;
protected:
- bool HasButtons(const Scrollbar&) override { return true; }
+ bool NativeThemeHasButtons() override { return true; }
bool HasThumb(const Scrollbar&) override;
- IntRect BackButtonRect(const Scrollbar&, ScrollbarPart) override;
- IntRect ForwardButtonRect(const Scrollbar&, ScrollbarPart) override;
+ IntRect BackButtonRect(const Scrollbar&) override;
+ IntRect ForwardButtonRect(const Scrollbar&) override;
IntRect TrackRect(const Scrollbar&) override;
int MinimumThumbLength(const Scrollbar&) override;
diff --git a/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura_test.cc b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura_test.cc
index 76125552976..e76a22a47ad 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura_test.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_aura_test.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/scroll/scrollbar_theme_aura.h"
+#include "third_party/blink/public/common/input/web_mouse_event.h"
#include "third_party/blink/renderer/core/scroll/scrollbar_test_suite.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
@@ -23,6 +24,10 @@ class ScrollbarThemeAuraButtonOverride final : public ScrollbarThemeAura {
return has_scrollbar_buttons_;
}
+ int MinimumThumbLength(const Scrollbar& scrollbar) override {
+ return ThumbThickness(scrollbar);
+ }
+
private:
bool has_scrollbar_buttons_;
};
@@ -31,6 +36,35 @@ class ScrollbarThemeAuraButtonOverride final : public ScrollbarThemeAura {
class ScrollbarThemeAuraTest : public testing::Test {};
+// Note that this helper only sends mouse events that are already handled on the
+// compositor thread, to the scrollbar (i.e they will have the event modifier
+// "kScrollbarManipulationHandledOnCompositorThread" set). The point of this
+// exercise is to validate that the scrollbar parts invalidate as expected
+// (since we still rely on the main thread for invalidation).
+void SendEvent(Scrollbar* scrollbar,
+ blink::WebInputEvent::Type type,
+ gfx::PointF point) {
+ const blink::WebMouseEvent web_mouse_event(
+ type, point, point, blink::WebPointerProperties::Button::kLeft, 0,
+ blink::WebInputEvent::kScrollbarManipulationHandledOnCompositorThread,
+ base::TimeTicks::Now());
+ switch (type) {
+ case blink::WebInputEvent::kMouseDown:
+ scrollbar->MouseDown(web_mouse_event);
+ break;
+ case blink::WebInputEvent::kMouseMove:
+ scrollbar->MouseMoved(web_mouse_event);
+ break;
+ case blink::WebInputEvent::kMouseUp:
+ scrollbar->MouseUp(web_mouse_event);
+ break;
+ default:
+ // The rest are unhandled. Let the called know that this helper has not
+ // yet implemented them.
+ NOTIMPLEMENTED();
+ }
+}
+
TEST_F(ScrollbarThemeAuraTest, ButtonSizeHorizontal) {
ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
platform;
@@ -97,4 +131,74 @@ TEST_F(ScrollbarThemeAuraTest, NoButtonsReturnsSize0) {
ThreadState::Current()->CollectAllGarbageForTesting();
}
+TEST_F(ScrollbarThemeAuraTest, ScrollbarPartsInvalidationTest) {
+ ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
+ platform;
+
+ MockScrollableArea* mock_scrollable_area =
+ MockScrollableArea::Create(ScrollOffset(0, 1000));
+ ScrollbarThemeAuraButtonOverride theme;
+ Scrollbar* scrollbar = Scrollbar::CreateForTesting(
+ mock_scrollable_area, kVerticalScrollbar, kRegularScrollbar, &theme);
+ ON_CALL(*mock_scrollable_area, VerticalScrollbar())
+ .WillByDefault(Return(scrollbar));
+
+ IntRect vertical_rect(1010, 0, 14, 768);
+ scrollbar->SetFrameRect(vertical_rect);
+ scrollbar->ClearThumbNeedsRepaint();
+ scrollbar->ClearTrackNeedsRepaint();
+
+ // Tests that mousedown on the thumb causes an invalidation.
+ SendEvent(scrollbar, blink::WebInputEvent::kMouseMove, gfx::PointF(10, 20));
+ SendEvent(scrollbar, blink::WebInputEvent::kMouseDown, gfx::PointF(10, 20));
+ EXPECT_TRUE(scrollbar->ThumbNeedsRepaint());
+
+ // Tests that mouseup on the thumb causes an invalidation.
+ scrollbar->ClearThumbNeedsRepaint();
+ SendEvent(scrollbar, blink::WebInputEvent::kMouseUp, gfx::PointF(10, 20));
+ EXPECT_TRUE(scrollbar->ThumbNeedsRepaint());
+
+ // Note that, since these tests run with the assumption that the compositor
+ // thread has already handled scrolling, a "scroll" will be simulated by
+ // calling SetScrollOffset. To check if the arrow was invalidated,
+ // TrackNeedsRepaint needs to be used. TrackNeedsRepaint here means
+ // "everything except the thumb needs to be repainted". The following verifies
+ // that when the offset changes from 0 to a value > 0, an invalidation gets
+ // triggered. At (0, 0) there is no upwards scroll available, so the arrow is
+ // disabled. When we change the offset, it must be repainted to show available
+ // scroll extent.
+ EXPECT_FALSE(scrollbar->TrackNeedsRepaint());
+ mock_scrollable_area->SetScrollOffset(ScrollOffset(0, 10),
+ mojom::blink::ScrollType::kCompositor);
+ EXPECT_TRUE(scrollbar->TrackNeedsRepaint());
+
+ // Tests that when the scroll offset changes from a value greater than 0 to a
+ // value less than the max scroll offset, a track invalidation is *not*
+ // triggered.
+ scrollbar->ClearTrackNeedsRepaint();
+ mock_scrollable_area->SetScrollOffset(ScrollOffset(0, 20),
+ mojom::blink::ScrollType::kCompositor);
+ EXPECT_FALSE(scrollbar->TrackNeedsRepaint());
+
+ // Tests that when the scroll offset changes to 0, a track invalidation is
+ // gets triggered (for the arrow).
+ scrollbar->ClearTrackNeedsRepaint();
+ mock_scrollable_area->SetScrollOffset(ScrollOffset(0, 0),
+ mojom::blink::ScrollType::kCompositor);
+ EXPECT_TRUE(scrollbar->TrackNeedsRepaint());
+
+ // Tests that mousedown on the arrow causes an invalidation.
+ scrollbar->ClearTrackNeedsRepaint();
+ SendEvent(scrollbar, blink::WebInputEvent::kMouseMove, gfx::PointF(10, 760));
+ SendEvent(scrollbar, blink::WebInputEvent::kMouseDown, gfx::PointF(10, 760));
+ EXPECT_TRUE(scrollbar->TrackNeedsRepaint());
+
+ // Tests that mouseup on the arrow causes an invalidation.
+ scrollbar->ClearTrackNeedsRepaint();
+ SendEvent(scrollbar, blink::WebInputEvent::kMouseUp, gfx::PointF(10, 760));
+ EXPECT_TRUE(scrollbar->TrackNeedsRepaint());
+
+ ThreadState::Current()->CollectAllGarbageForTesting();
+}
+
} // namespace blink
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 f12f6f08b62..c34380e4696 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
@@ -50,6 +50,13 @@ class PLATFORM_EXPORT ScrollbarThemeMac : public ScrollbarTheme {
// Mac queues up scrollbar paint timers.
bool ShouldDisableInvisibleScrollbars() const override { return false; }
+ // On Mac, if Blink updates the visibility itself, it cannot tell the Mac
+ // painting code about the change. Allowing it to change means the two can
+ // get out of sync and can cause issues like Blink believing a scrollbar is
+ // visible while the user cannot see it; this can lead to odd hit testing
+ // behavior.
+ bool BlinkControlsOverlayVisibility() const override { return false; }
+
base::TimeDelta InitialAutoscrollTimerDelay() override;
base::TimeDelta AutoscrollTimerDelay() override;
@@ -68,7 +75,6 @@ class PLATFORM_EXPORT ScrollbarThemeMac : public ScrollbarTheme {
int ScrollbarThickness(ScrollbarControlSize = kRegularScrollbar) override;
bool UsesOverlayScrollbars() const override;
void UpdateScrollbarOverlayColorTheme(const Scrollbar&) override;
- WebScrollbarButtonsPlacement ButtonsPlacement() const override;
void SetNewPainterForScrollbar(Scrollbar&, ScrollbarPainter);
ScrollbarPainter PainterForScrollbar(const Scrollbar&) const;
@@ -81,10 +87,10 @@ class PLATFORM_EXPORT ScrollbarThemeMac : public ScrollbarTheme {
void PaintThumbWithOpacity(GraphicsContext& context,
const Scrollbar& scrollbar,
const IntRect& rect) override {
- PaintThumbInternal(context, scrollbar, rect, ThumbOpacity(scrollbar));
+ PaintThumbInternal(context, scrollbar, rect, Opacity(scrollbar));
}
- float ThumbOpacity(const Scrollbar&) const override;
+ float Opacity(const Scrollbar&) const override;
static NSScrollerStyle RecommendedScrollerStyle();
@@ -102,13 +108,11 @@ class PLATFORM_EXPORT ScrollbarThemeMac : public ScrollbarTheme {
bool ShouldDragDocumentInsteadOfThumb(const Scrollbar&,
const WebMouseEvent&) override;
- virtual void UpdateButtonPlacement(WebScrollbarButtonsPlacement) {}
-
IntRect TrackRect(const Scrollbar&) override;
- IntRect BackButtonRect(const Scrollbar&, ScrollbarPart) override;
- IntRect ForwardButtonRect(const Scrollbar&, ScrollbarPart) override;
+ IntRect BackButtonRect(const Scrollbar&) override;
+ IntRect ForwardButtonRect(const Scrollbar&) override;
- bool HasButtons(const Scrollbar&) override { return false; }
+ bool NativeThemeHasButtons() override { return false; }
bool HasThumb(const Scrollbar&) override;
int MinimumThumbLength(const Scrollbar&) override;
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 444f5f8f491..28ff7ed1e6f 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
@@ -29,9 +29,9 @@
#include "base/mac/scoped_nsobject.h"
#include "base/memory/scoped_policy.h"
#include "skia/ext/skia_utils_mac.h"
+#include "third_party/blink/public/common/input/web_mouse_event.h"
#include "third_party/blink/public/platform/mac/web_scrollbar_theme.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_mouse_event.h"
#include "third_party/blink/public/platform/web_rect.h"
#include "third_party/blink/public/platform/web_theme_engine.h"
#include "third_party/blink/renderer/core/scroll/ns_scroller_imp_details.h"
@@ -83,7 +83,7 @@ using gfx::CocoaScrollbarPainter;
_saved_knob_alpha = [_scrollbarPainter knobAlpha];
} else {
[_scrollbarPainter setKnobAlpha:_saved_knob_alpha];
- _scrollbar->SetScrollbarsHiddenIfOverlay(_saved_knob_alpha == 0);
+ _scrollbar->SetScrollbarsHiddenFromExternalAnimator(_saved_knob_alpha == 0);
}
}
@@ -99,7 +99,7 @@ using gfx::CocoaScrollbarPainter;
if ([keyPath isEqualToString:@"knobAlpha"]) {
if (!_suppressSetScrollbarsHidden) {
BOOL visible = [_scrollbarPainter knobAlpha] > 0;
- _scrollbar->SetScrollbarsHiddenIfOverlay(!visible);
+ _scrollbar->SetScrollbarsHiddenFromExternalAnimator(!visible);
}
}
}
@@ -423,10 +423,6 @@ void ScrollbarThemeMac::UpdateScrollbarOverlayColorTheme(
}
}
-WebScrollbarButtonsPlacement ScrollbarThemeMac::ButtonsPlacement() const {
- return kWebScrollbarButtonsPlacementNone;
-}
-
bool ScrollbarThemeMac::HasThumb(const Scrollbar& scrollbar) {
ScrollbarPainter painter = PainterForScrollbar(scrollbar);
int min_length_for_thumb =
@@ -439,20 +435,15 @@ bool ScrollbarThemeMac::HasThumb(const Scrollbar& scrollbar) {
: scrollbar.Height()) >= min_length_for_thumb;
}
-IntRect ScrollbarThemeMac::BackButtonRect(const Scrollbar& scrollbar,
- ScrollbarPart part) {
- DCHECK_EQ(ButtonsPlacement(), kWebScrollbarButtonsPlacementNone);
+IntRect ScrollbarThemeMac::BackButtonRect(const Scrollbar& scrollbar) {
return IntRect();
}
-IntRect ScrollbarThemeMac::ForwardButtonRect(const Scrollbar& scrollbar,
- ScrollbarPart part) {
- DCHECK_EQ(ButtonsPlacement(), kWebScrollbarButtonsPlacementNone);
+IntRect ScrollbarThemeMac::ForwardButtonRect(const Scrollbar& scrollbar) {
return IntRect();
}
IntRect ScrollbarThemeMac::TrackRect(const Scrollbar& scrollbar) {
- DCHECK(!HasButtons(scrollbar));
return scrollbar.FrameRect();
}
@@ -464,7 +455,7 @@ void ScrollbarThemeMac::UpdateEnabledState(const Scrollbar& scrollbar) {
[PainterForScrollbar(scrollbar) setEnabled:scrollbar.Enabled()];
}
-float ScrollbarThemeMac::ThumbOpacity(const Scrollbar& scrollbar) const {
+float ScrollbarThemeMac::Opacity(const Scrollbar& scrollbar) const {
ScrollbarPainter scrollbar_painter = PainterForScrollbar(scrollbar);
return [scrollbar_painter knobAlpha];
}
diff --git a/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.cc b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.cc
index 790068b8e15..6d6ae6deca5 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.cc
@@ -109,12 +109,11 @@ bool ScrollbarThemeOverlay::HasThumb(const Scrollbar& scrollbar) {
return true;
}
-IntRect ScrollbarThemeOverlay::BackButtonRect(const Scrollbar&, ScrollbarPart) {
+IntRect ScrollbarThemeOverlay::BackButtonRect(const Scrollbar&) {
return IntRect();
}
-IntRect ScrollbarThemeOverlay::ForwardButtonRect(const Scrollbar&,
- ScrollbarPart) {
+IntRect ScrollbarThemeOverlay::ForwardButtonRect(const Scrollbar&) {
return IntRect();
}
@@ -241,8 +240,4 @@ int ScrollbarThemeOverlay::MinimumThumbLength(const Scrollbar& scrollbar) {
.width;
}
-bool ScrollbarThemeOverlay::AllowsHitTest() const {
- return true;
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.h b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.h
index 2c9c4a65166..19d5946c81a 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.h
@@ -53,19 +53,17 @@ class CORE_EXPORT ScrollbarThemeOverlay : public ScrollbarTheme {
int ThumbLength(const Scrollbar&) override;
- bool HasButtons(const Scrollbar&) override { return false; }
+ bool NativeThemeHasButtons() override { return false; }
bool HasThumb(const Scrollbar&) override;
- IntRect BackButtonRect(const Scrollbar&, ScrollbarPart) override;
- IntRect ForwardButtonRect(const Scrollbar&, ScrollbarPart) override;
+ IntRect BackButtonRect(const Scrollbar&) override;
+ IntRect ForwardButtonRect(const Scrollbar&) override;
IntRect TrackRect(const Scrollbar&) override;
IntRect ThumbRect(const Scrollbar&) override;
int ThumbThickness(const Scrollbar&) override;
int ThumbThickness() { return thumb_thickness_; }
void PaintThumb(GraphicsContext&, const Scrollbar&, const IntRect&) override;
- bool AllowsHitTest() const override;
- ScrollbarPart HitTest(const Scrollbar&, const IntPoint&) override;
bool UsesNinePatchThumbResource() const override;
IntSize NinePatchThumbCanvasSize(const Scrollbar&) const override;
@@ -76,6 +74,7 @@ class CORE_EXPORT ScrollbarThemeOverlay : public ScrollbarTheme {
protected:
FRIEND_TEST_ALL_PREFIXES(ScrollbarThemeOverlayTest, PaintInvalidation);
+ ScrollbarPart HitTest(const Scrollbar&, const IntPoint&) override;
ScrollbarThemeOverlay(int thumb_thickness, int scrollbar_margin);
private:
diff --git a/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_mobile.h b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_mobile.h
index a903c04e14f..6efd0a8aef6 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_mobile.h
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_mobile.h
@@ -16,15 +16,17 @@ class CORE_EXPORT ScrollbarThemeOverlayMobile : public ScrollbarThemeOverlay {
void PaintThumb(GraphicsContext&, const Scrollbar&, const IntRect&) override;
bool AllowsHitTest() const override { return false; }
- ScrollbarPart HitTest(const Scrollbar&, const IntPoint&) override {
- return kNoPart;
- }
bool IsSolidColor() const override { return true; }
bool UsesNinePatchThumbResource() const override { return false; }
protected:
ScrollbarThemeOverlayMobile(int thumb_thickness, int scrollbar_margin, Color);
+ ScrollbarPart HitTest(const Scrollbar&, const IntPoint&) override {
+ NOTREACHED();
+ return kNoPart;
+ }
+
private:
Color color_;
};
diff --git a/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_test.cc b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_test.cc
index c41d561994a..d27ef082bc3 100644
--- a/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_test.cc
+++ b/chromium/third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_test.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/scroll/scrollbar_theme_overlay.h"
+#include "third_party/blink/renderer/core/scroll/scroll_types.h"
#include "third_party/blink/renderer/core/scroll/scrollbar_test_suite.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
@@ -54,12 +55,13 @@ TEST_F(ScrollbarThemeOverlayTest, PaintInvalidation) {
ASSERT_FALSE(
mock_scrollable_area->HorizontalScrollbarNeedsPaintInvalidation());
- // Changing the scroll offset shouldn't invalide the thumb nor track, but it
+ // Changing the scroll offset shouldn't invalid the thumb nor track, but it
// should cause a "general" invalidation for non-composited scrollbars.
// Ensure the horizontal scrollbar is unaffected.
- mock_scrollable_area->UpdateScrollOffset(ScrollOffset(0, 5), kUserScroll);
- vertical_scrollbar->OffsetDidChange();
- horizontal_scrollbar->OffsetDidChange();
+ mock_scrollable_area->UpdateScrollOffset(ScrollOffset(0, 5),
+ mojom::blink::ScrollType::kUser);
+ vertical_scrollbar->OffsetDidChange(mojom::blink::ScrollType::kUser);
+ horizontal_scrollbar->OffsetDidChange(mojom::blink::ScrollType::kUser);
EXPECT_FALSE(vertical_scrollbar->ThumbNeedsRepaint());
EXPECT_FALSE(vertical_scrollbar->TrackNeedsRepaint());
EXPECT_TRUE(mock_scrollable_area->VerticalScrollbarNeedsPaintInvalidation());
@@ -70,9 +72,10 @@ TEST_F(ScrollbarThemeOverlayTest, PaintInvalidation) {
// Try the horizontal scrollbar.
mock_scrollable_area->ClearNeedsPaintInvalidationForScrollControls();
- mock_scrollable_area->UpdateScrollOffset(ScrollOffset(5, 5), kUserScroll);
- horizontal_scrollbar->OffsetDidChange();
- vertical_scrollbar->OffsetDidChange();
+ mock_scrollable_area->UpdateScrollOffset(ScrollOffset(5, 5),
+ mojom::blink::ScrollType::kUser);
+ horizontal_scrollbar->OffsetDidChange(mojom::blink::ScrollType::kUser);
+ vertical_scrollbar->OffsetDidChange(mojom::blink::ScrollType::kUser);
EXPECT_FALSE(vertical_scrollbar->ThumbNeedsRepaint());
EXPECT_FALSE(vertical_scrollbar->TrackNeedsRepaint());
EXPECT_FALSE(mock_scrollable_area->VerticalScrollbarNeedsPaintInvalidation());
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 6e6cfd627a5..707905fc146 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,13 +9,14 @@
namespace blink {
-void SequencedScroll::Trace(blink::Visitor* visitor) {
+void SequencedScroll::Trace(Visitor* visitor) {
visitor->Trace(scrollable_area);
}
-void SmoothScrollSequencer::QueueAnimation(ScrollableArea* scrollable,
- ScrollOffset offset,
- ScrollBehavior behavior) {
+void SmoothScrollSequencer::QueueAnimation(
+ ScrollableArea* scrollable,
+ ScrollOffset offset,
+ mojom::blink::ScrollBehavior behavior) {
if (scrollable->ClampScrollOffset(offset) != scrollable->GetScrollOffset()) {
queue_.push_back(
MakeGarbageCollected<SequencedScroll>(scrollable, offset, behavior));
@@ -25,14 +26,14 @@ void SmoothScrollSequencer::QueueAnimation(ScrollableArea* scrollable,
void SmoothScrollSequencer::RunQueuedAnimations() {
if (queue_.IsEmpty()) {
current_scrollable_ = nullptr;
- scroll_type_ = kProgrammaticScroll;
+ scroll_type_ = mojom::blink::ScrollType::kProgrammatic;
return;
}
SequencedScroll* sequenced_scroll = queue_.back();
queue_.pop_back();
current_scrollable_ = sequenced_scroll->scrollable_area;
current_scrollable_->SetScrollOffset(sequenced_scroll->scroll_offset,
- kSequencedScroll,
+ mojom::blink::ScrollType::kSequenced,
sequenced_scroll->scroll_behavior);
}
@@ -42,20 +43,22 @@ void SmoothScrollSequencer::AbortAnimations() {
current_scrollable_ = nullptr;
}
queue_.clear();
- scroll_type_ = kProgrammaticScroll;
+ scroll_type_ = mojom::blink::ScrollType::kProgrammatic;
}
bool SmoothScrollSequencer::FilterNewScrollOrAbortCurrent(
- ScrollType incoming_type) {
+ mojom::blink::ScrollType incoming_type) {
// Allow the incoming scroll to co-exist if its scroll type is
- // kSequencedScroll, kClampingScroll, or kAnchoringScroll
- if (incoming_type == kSequencedScroll || incoming_type == kClampingScroll ||
- incoming_type == kAnchoringScroll)
+ // kSequenced, kClamping, or kAnchoring
+ if (incoming_type == mojom::blink::ScrollType::kSequenced ||
+ incoming_type == mojom::blink::ScrollType::kClamping ||
+ incoming_type == mojom::blink::ScrollType::kAnchoring)
return false;
// If the current sequenced scroll is UserScroll, but the incoming scroll is
// not, filter the incoming scroll. See crbug.com/913009 for more details.
- if (scroll_type_ == kUserScroll && incoming_type != kUserScroll)
+ if (scroll_type_ == mojom::blink::ScrollType::kUser &&
+ incoming_type != mojom::blink::ScrollType::kUser)
return true;
// Otherwise, abort the current sequenced scroll.
@@ -73,7 +76,7 @@ void SmoothScrollSequencer::DidDisposeScrollableArea(
}
}
-void SmoothScrollSequencer::Trace(blink::Visitor* visitor) {
+void SmoothScrollSequencer::Trace(Visitor* visitor) {
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 a376a1794f2..3d120d4cff1 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
@@ -19,7 +19,7 @@ struct SequencedScroll final : public GarbageCollected<SequencedScroll> {
SequencedScroll(ScrollableArea* area,
ScrollOffset offset,
- ScrollBehavior behavior)
+ mojom::blink::ScrollBehavior behavior)
: scrollable_area(area),
scroll_offset(offset),
scroll_behavior(behavior) {}
@@ -31,9 +31,9 @@ struct SequencedScroll final : public GarbageCollected<SequencedScroll> {
Member<ScrollableArea> scrollable_area;
ScrollOffset scroll_offset;
- ScrollBehavior scroll_behavior;
+ mojom::blink::ScrollBehavior scroll_behavior;
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
};
// A sequencer that queues the nested scrollers from inside to outside,
@@ -42,11 +42,14 @@ struct SequencedScroll final : public GarbageCollected<SequencedScroll> {
class CORE_EXPORT SmoothScrollSequencer final
: public GarbageCollected<SmoothScrollSequencer> {
public:
- SmoothScrollSequencer() : scroll_type_(kProgrammaticScroll) {}
- void SetScrollType(ScrollType type) { scroll_type_ = type; }
+ SmoothScrollSequencer()
+ : scroll_type_(mojom::blink::ScrollType::kProgrammatic) {}
+ void SetScrollType(mojom::blink::ScrollType type) { scroll_type_ = type; }
// Add a scroll offset animation to the back of a queue.
- void QueueAnimation(ScrollableArea*, ScrollOffset, ScrollBehavior);
+ void QueueAnimation(ScrollableArea*,
+ ScrollOffset,
+ mojom::blink::ScrollBehavior);
// Run the animation at the back of the queue.
void RunQueuedAnimations();
@@ -56,16 +59,16 @@ class CORE_EXPORT SmoothScrollSequencer final
// Given the incoming scroll's scroll type, returns whether to filter the
// incoming scroll. It may also abort the current sequenced scroll.
- bool FilterNewScrollOrAbortCurrent(ScrollType incoming_type);
+ bool FilterNewScrollOrAbortCurrent(mojom::blink::ScrollType incoming_type);
void DidDisposeScrollableArea(const ScrollableArea&);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
HeapVector<Member<SequencedScroll>> queue_;
Member<ScrollableArea> current_scrollable_;
- ScrollType scroll_type_;
+ mojom::blink::ScrollType scroll_type_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/scroll/web_scroll_into_view_params.cc b/chromium/third_party/blink/renderer/core/scroll/web_scroll_into_view_params.cc
deleted file mode 100644
index 9b3ee111c3c..00000000000
--- a/chromium/third_party/blink/renderer/core/scroll/web_scroll_into_view_params.cc
+++ /dev/null
@@ -1,122 +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/public/platform/web_scroll_into_view_params.h"
-
-#include "third_party/blink/renderer/platform/wtf/size_assertions.h"
-
-namespace blink {
-namespace {
-using AlignmentBehavior = WebScrollIntoViewParams::AlignmentBehavior;
-using Alignment = WebScrollIntoViewParams::Alignment;
-using Type = WebScrollIntoViewParams::Type;
-using Behavior = WebScrollIntoViewParams::Behavior;
-
-// Make sure we keep the public enums in sync with the internal ones.
-ASSERT_SIZE(AlignmentBehavior, ScrollAlignmentBehavior);
-STATIC_ASSERT_ENUM(AlignmentBehavior::kNoScroll,
- ScrollAlignmentBehavior::kScrollAlignmentNoScroll);
-STATIC_ASSERT_ENUM(AlignmentBehavior::kCenter,
- ScrollAlignmentBehavior::kScrollAlignmentCenter);
-STATIC_ASSERT_ENUM(AlignmentBehavior::kTop,
- ScrollAlignmentBehavior::kScrollAlignmentTop);
-STATIC_ASSERT_ENUM(AlignmentBehavior::kBottom,
- ScrollAlignmentBehavior::kScrollAlignmentBottom);
-STATIC_ASSERT_ENUM(AlignmentBehavior::kLeft,
- ScrollAlignmentBehavior::kScrollAlignmentLeft);
-STATIC_ASSERT_ENUM(AlignmentBehavior::kRight,
- ScrollAlignmentBehavior::kScrollAlignmentRight);
-STATIC_ASSERT_ENUM(AlignmentBehavior::kClosestEdge,
- ScrollAlignmentBehavior::kScrollAlignmentClosestEdge);
-
-ASSERT_SIZE(Type, ScrollType);
-STATIC_ASSERT_ENUM(Type::kUser, ScrollType::kUserScroll);
-STATIC_ASSERT_ENUM(Type::kProgrammatic, ScrollType::kProgrammaticScroll);
-STATIC_ASSERT_ENUM(Type::kClamping, ScrollType::kClampingScroll);
-STATIC_ASSERT_ENUM(Type::kAnchoring, ScrollType::kAnchoringScroll);
-STATIC_ASSERT_ENUM(Type::kSequenced, ScrollType::kSequencedScroll);
-
-ASSERT_SIZE(Behavior, ScrollBehavior);
-STATIC_ASSERT_ENUM(Behavior::kAuto, ScrollBehavior::kScrollBehaviorAuto);
-STATIC_ASSERT_ENUM(Behavior::kInstant, ScrollBehavior::kScrollBehaviorInstant);
-STATIC_ASSERT_ENUM(Behavior::kSmooth, ScrollBehavior::kScrollBehaviorSmooth);
-
-AlignmentBehavior ToAlignmentBehavior(
- ScrollAlignmentBehavior scroll_alignment_behavior) {
- return static_cast<AlignmentBehavior>(
- static_cast<int>(scroll_alignment_behavior));
-}
-
-ScrollAlignmentBehavior ToScrollAlignmentBehavior(
- AlignmentBehavior alignment_behavior) {
- return static_cast<ScrollAlignmentBehavior>(
- static_cast<int>(alignment_behavior));
-}
-
-ScrollAlignment ToScrollAlignment(Alignment alignment) {
- return {ToScrollAlignmentBehavior(alignment.rect_visible),
- ToScrollAlignmentBehavior(alignment.rect_hidden),
- ToScrollAlignmentBehavior(alignment.rect_partial)};
-}
-
-Type FromScrollType(ScrollType type) {
- return static_cast<Type>(static_cast<int>(type));
-}
-
-ScrollType ToScrollType(Type type) {
- return static_cast<ScrollType>(static_cast<int>(type));
-}
-
-Behavior FromScrollBehavior(ScrollBehavior behavior) {
- return static_cast<Behavior>(static_cast<int>(behavior));
-}
-
-ScrollBehavior ToScrollBehavior(Behavior behavior) {
- return static_cast<ScrollBehavior>(static_cast<int>(behavior));
-}
-
-} // namespace
-
-WebScrollIntoViewParams::Alignment::Alignment(
- const ScrollAlignment& scroll_alignment)
- : rect_visible(ToAlignmentBehavior(
- ScrollAlignment::GetVisibleBehavior(scroll_alignment))),
- rect_hidden(ToAlignmentBehavior(
- ScrollAlignment::GetHiddenBehavior(scroll_alignment))),
- rect_partial(ToAlignmentBehavior(
- ScrollAlignment::GetPartialBehavior(scroll_alignment))) {}
-
-WebScrollIntoViewParams::WebScrollIntoViewParams(
- ScrollAlignment scroll_alignment_x,
- ScrollAlignment scroll_alignment_y,
- ScrollType scroll_type,
- bool make_visible_in_visual_viewport,
- ScrollBehavior scroll_behavior,
- bool is_for_scroll_sequence,
- bool zoom_into_rect)
- : align_x(scroll_alignment_x),
- align_y(scroll_alignment_y),
- type(FromScrollType(scroll_type)),
- make_visible_in_visual_viewport(make_visible_in_visual_viewport),
- behavior(FromScrollBehavior(scroll_behavior)),
- is_for_scroll_sequence(is_for_scroll_sequence),
- zoom_into_rect(zoom_into_rect) {}
-
-ScrollAlignment WebScrollIntoViewParams::GetScrollAlignmentX() const {
- return ToScrollAlignment(align_x);
-}
-
-ScrollAlignment WebScrollIntoViewParams::GetScrollAlignmentY() const {
- return ToScrollAlignment(align_y);
-}
-
-ScrollType WebScrollIntoViewParams::GetScrollType() const {
- return ToScrollType(type);
-}
-
-ScrollBehavior WebScrollIntoViewParams::GetScrollBehavior() const {
- return ToScrollBehavior(behavior);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/streams/PRESUBMIT.py b/chromium/third_party/blink/renderer/core/streams/PRESUBMIT.py
index c3243c4d5d4..7935e32c18d 100644
--- a/chromium/third_party/blink/renderer/core/streams/PRESUBMIT.py
+++ b/chromium/third_party/blink/renderer/core/streams/PRESUBMIT.py
@@ -3,7 +3,6 @@
# 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
@@ -23,8 +22,8 @@ def CheckChangeOnCommit(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')
+ 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
@@ -33,5 +32,5 @@ def common_checks(input_api, output_api):
def is_resource(maybe_resource):
return maybe_resource.AbsoluteLocalPath().endswith('.js')
- return js_checker.JSChecker(input_api, output_api,
- file_filter=is_resource).RunChecks()
+ 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 e5ea5c46b42..b747c7180e9 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
@@ -6,8 +6,8 @@
#include "third_party/blink/renderer/bindings/core/v8/script_function.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_queuing_strategy_init.h"
#include "third_party/blink/renderer/core/streams/queuing_strategy_common.h"
-#include "third_party/blink/renderer/core/streams/queuing_strategy_init.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
diff --git a/chromium/third_party/blink/renderer/core/streams/byte_length_queuing_strategy.idl b/chromium/third_party/blink/renderer/core/streams/byte_length_queuing_strategy.idl
index 83f20847045..ac23897bc47 100644
--- a/chromium/third_party/blink/renderer/core/streams/byte_length_queuing_strategy.idl
+++ b/chromium/third_party/blink/renderer/core/streams/byte_length_queuing_strategy.idl
@@ -5,11 +5,9 @@
// https://streams.spec.whatwg.org/#blqs-class
[
- Exposed=(Window,Worker,Worklet),
- ConstructorCallWith=ScriptState,
- Constructor([PermissiveDictionaryConversion] QueuingStrategyInit init),
- MeasureAs=ByteLengthQueuingStrategyConstructor
+ Exposed=(Window,Worker,Worklet)
] interface ByteLengthQueuingStrategy {
+ [CallWith=ScriptState, MeasureAs=ByteLengthQueuingStrategyConstructor] constructor([PermissiveDictionaryConversion] QueuingStrategyInit init);
[CallWith=ScriptState] readonly attribute any highWaterMark;
// size is an accessor that returns a function.
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 601fecf4ab0..079e8b7261f 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
@@ -6,8 +6,8 @@
#include "third_party/blink/renderer/bindings/core/v8/script_function.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_queuing_strategy_init.h"
#include "third_party/blink/renderer/core/streams/queuing_strategy_common.h"
-#include "third_party/blink/renderer/core/streams/queuing_strategy_init.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
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 246c4599d14..cd001b1dadb 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
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_COUNT_QUEUING_STRATEGY_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_STREAMS_COUNT_QUEUING_STRATEGY_H_
+#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h"
#include "v8/include/v8.h"
@@ -17,7 +18,7 @@ class ScriptValue;
class Visitor;
// https://streams.spec.whatwg.org/#blqs-class
-class CountQueuingStrategy final : public ScriptWrappable {
+class CORE_EXPORT CountQueuingStrategy final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
diff --git a/chromium/third_party/blink/renderer/core/streams/count_queuing_strategy.idl b/chromium/third_party/blink/renderer/core/streams/count_queuing_strategy.idl
index fe18a1e03dd..fca10ee2218 100644
--- a/chromium/third_party/blink/renderer/core/streams/count_queuing_strategy.idl
+++ b/chromium/third_party/blink/renderer/core/streams/count_queuing_strategy.idl
@@ -5,11 +5,9 @@
// https://streams.spec.whatwg.org/#cqs-class
[
- Exposed=(Window,Worker,Worklet),
- ConstructorCallWith=ScriptState,
- Constructor([PermissiveDictionaryConversion] QueuingStrategyInit init),
- MeasureAs=CountQueuingStrategyConstructor
+ Exposed=(Window,Worker,Worklet)
] interface CountQueuingStrategy {
+ [CallWith=ScriptState, MeasureAs=CountQueuingStrategyConstructor] constructor([PermissiveDictionaryConversion] QueuingStrategyInit init);
[CallWith=ScriptState] readonly attribute any highWaterMark;
// size is an accessor that returns a function.
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 334e59642c9..967342344e4 100644
--- a/chromium/third_party/blink/renderer/core/streams/miscellaneous_operations.cc
+++ b/chromium/third_party/blink/renderer/core/streams/miscellaneous_operations.cc
@@ -485,7 +485,7 @@ void ScriptValueToObject(ScriptState* script_state,
v8::Local<v8::Object>* object,
ExceptionState& exception_state) {
auto* isolate = script_state->GetIsolate();
- DCHECK(!value.IsEmpty());
+ CHECK(!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/promise_handler.cc b/chromium/third_party/blink/renderer/core/streams/promise_handler.cc
index 556956f921e..76096197f3b 100644
--- a/chromium/third_party/blink/renderer/core/streams/promise_handler.cc
+++ b/chromium/third_party/blink/renderer/core/streams/promise_handler.cc
@@ -12,6 +12,28 @@ namespace {
void NoopFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>&) {}
+// Creating a new v8::Promise::Resolver to create a new promise can fail. If
+// JavaScript will no longer execute, then we can safely return the original
+// promise. Otherwise we have no choice but to crash.
+v8::Local<v8::Promise> AttemptToReturnDummyPromise(
+ v8::Local<v8::Context> context,
+ v8::Local<v8::Promise> original_promise) {
+ v8::Local<v8::Promise::Resolver> resolver;
+ if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) {
+ if (!context->GetIsolate()->IsExecutionTerminating()) {
+ // It's not safe to leak |original_promise| unless we have a guarantee
+ // that no further JavaScript will run.
+ LOG(FATAL) << "Cannot recover from failure to create a new "
+ "v8::Promise::Resolver object (OOM?)";
+ }
+
+ // We are probably in the process of worker termination.
+ return original_promise;
+ }
+
+ return resolver->GetPromise();
+}
+
} // namespace
PromiseHandler::PromiseHandler(ScriptState* script_state)
@@ -48,7 +70,7 @@ v8::Local<v8::Promise> StreamThenPromise(v8::Local<v8::Context> context,
if (!v8::Function::New(context, NoopFunctionCallback).ToLocal(&noop)) {
DVLOG(3) << "Assuming that the failure of v8::Function::New() is caused "
<< "by shutdown and ignoring it";
- return v8::Promise::Resolver::New(context).ToLocalChecked()->GetPromise();
+ return AttemptToReturnDummyPromise(context, promise);
}
result_maybe =
promise->Then(context, noop, on_rejected->BindToV8Function());
@@ -64,10 +86,7 @@ v8::Local<v8::Promise> StreamThenPromise(v8::Local<v8::Context> context,
DVLOG(3)
<< "assuming that failure of promise->Then() is caused by shutdown and"
"ignoring it";
- // Try to create a dummy promise so that the calling code can continue. If
- // we can't create one, then we can't return to the calling context so we
- // have to crash. This shouldn't happen except on OOM.
- result = v8::Promise::Resolver::New(context).ToLocalChecked()->GetPromise();
+ result = AttemptToReturnDummyPromise(context, promise);
}
return result;
}
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 1fcd96a1cda..d46e3d88095 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
@@ -42,7 +42,6 @@ class QueueWithSizes::ValueSizePair final
};
QueueWithSizes::QueueWithSizes() = default;
-QueueWithSizes::~QueueWithSizes() = default;
v8::Local<v8::Value> QueueWithSizes::DequeueValue(v8::Isolate* isolate) {
DCHECK(!queue_.empty());
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 c114ea75be3..fee10c349a7 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
@@ -25,7 +25,6 @@ class CORE_EXPORT QueueWithSizes final
: public GarbageCollected<QueueWithSizes> {
public:
QueueWithSizes();
- ~QueueWithSizes();
// https://streams.spec.whatwg.org/#dequeue-value
v8::Local<v8::Value> DequeueValue(v8::Isolate*);
diff --git a/chromium/third_party/blink/renderer/core/streams/queuing_strategy_common.cc b/chromium/third_party/blink/renderer/core/streams/queuing_strategy_common.cc
index 4441a896a38..f50890a6fb0 100644
--- a/chromium/third_party/blink/renderer/core/streams/queuing_strategy_common.cc
+++ b/chromium/third_party/blink/renderer/core/streams/queuing_strategy_common.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/core/streams/queuing_strategy_common.h"
-#include "third_party/blink/renderer/core/streams/queuing_strategy_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_queuing_strategy_init.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
namespace blink {
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 08da2f75831..785e3944536 100644
--- a/chromium/third_party/blink/renderer/core/streams/readable_stream.idl
+++ b/chromium/third_party/blink/renderer/core/streams/readable_stream.idl
@@ -4,11 +4,9 @@
// https://streams.spec.whatwg.org/#rs-class
[
- Exposed=(Window,Worker,Worklet),
- Constructor(optional any underlyingSource, optional any strategy),
- RaisesException=Constructor,
- ConstructorCallWith=ScriptState
+ 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;
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 ba3ca826e0f..8dcbbf3e4ea 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
@@ -28,7 +28,9 @@ class ReadableStreamDefaultController : public ScriptWrappable {
ReadableStreamDefaultController();
// https://streams.spec.whatwg.org/#rs-default-controller-desired-size
- double desiredSize(bool& is_null) const;
+ base::Optional<double> desiredSize() const { return GetDesiredSize(); }
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ double desiredSize(bool& is_null) const; // DEPRECATED
// https://streams.spec.whatwg.org/#rs-default-controller-close
void close(ScriptState*, ExceptionState&);
diff --git a/chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller.idl b/chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller.idl
index af13a9c9916..3d2f119b790 100644
--- a/chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller.idl
+++ b/chromium/third_party/blink/renderer/core/streams/readable_stream_default_controller.idl
@@ -5,8 +5,7 @@
// https://streams.spec.whatwg.org/#rs-default-controller-class-definition
[
Exposed=(Window,Worker,Worklet),
- NoInterfaceObject,
- RaisesException=Constructor
+ NoInterfaceObject
] interface ReadableStreamDefaultController {
[NotEnumerable] readonly attribute double? desiredSize;
[CallWith=ScriptState, NotEnumerable, RaisesException] void close();
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 b13f7436940..ec720e176f4 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
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_readable_stream_default_controller.h"
#include "third_party/blink/renderer/core/streams/readable_stream_default_controller.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/scoped_persistent.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -34,7 +35,9 @@ void ReadableStreamDefaultControllerWithScriptScope::Close() {
ScriptState::Scope scope(script_state_);
- ReadableStreamDefaultController::Close(script_state_, controller_);
+ if (ReadableStreamDefaultController::CanCloseOrEnqueue(controller_)) {
+ ReadableStreamDefaultController::Close(script_state_, controller_);
+ }
controller_ = nullptr;
}
@@ -52,6 +55,10 @@ void ReadableStreamDefaultControllerWithScriptScope::Enqueue(
if (!controller_)
return;
+ if (!ReadableStreamDefaultController::CanCloseOrEnqueue(controller_)) {
+ return;
+ }
+
ScriptState::Scope scope(script_state_);
ExceptionState exception_state(script_state_->GetIsolate(),
diff --git a/chromium/third_party/blink/renderer/core/streams/readable_stream_default_reader.idl b/chromium/third_party/blink/renderer/core/streams/readable_stream_default_reader.idl
index f7996e5df10..5fb3288dae2 100644
--- a/chromium/third_party/blink/renderer/core/streams/readable_stream_default_reader.idl
+++ b/chromium/third_party/blink/renderer/core/streams/readable_stream_default_reader.idl
@@ -5,15 +5,14 @@
// https://streams.spec.whatwg.org/#default-reader-class-definition
[
Exposed=(Window,Worker,Worklet),
- RaisesException=Constructor,
- ConstructorCallWith=ScriptState,
- Constructor(ReadableStream stream)
+ ImplementedAs=ReadableStreamReader
] interface ReadableStreamDefaultReader {
+ [CallWith=ScriptState, RaisesException] constructor(ReadableStream stream);
[CallWith=ScriptState, NotEnumerable] readonly attribute Promise<void>
closed;
- [CallWith=ScriptState, NotEnumerable] Promise<void> cancel(
+ [CallWith=ScriptState, RaisesException, NotEnumerable] Promise<void> cancel(
optional any reason);
- [CallWith=ScriptState, NotEnumerable] Promise<void> read();
+ [CallWith=ScriptState, RaisesException, NotEnumerable] Promise<void> read();
[CallWith=ScriptState, NotEnumerable, RaisesException] void releaseLock();
};
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 f09739e235b..0039f56ee59 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
@@ -55,24 +55,25 @@ ScriptPromise ReadableStreamReader::closed(ScriptState* script_state) const {
return closed_promise_->GetScriptPromise(script_state);
}
-ScriptPromise ReadableStreamReader::cancel(ScriptState* script_state) {
+ScriptPromise ReadableStreamReader::cancel(ScriptState* script_state,
+ ExceptionState& exception_state) {
return cancel(script_state,
ScriptValue(script_state->GetIsolate(),
- v8::Undefined(script_state->GetIsolate())));
+ v8::Undefined(script_state->GetIsolate())),
+ exception_state);
}
ScriptPromise ReadableStreamReader::cancel(ScriptState* script_state,
- ScriptValue reason) {
+ ScriptValue reason,
+ ExceptionState& exception_state) {
// https://streams.spec.whatwg.org/#default-reader-cancel
// 2. If this.[[ownerReadableStream]] is undefined, return a promise rejected
// with a TypeError exception.
if (!owner_readable_stream_) {
- return ScriptPromise::Reject(
- script_state,
- v8::Exception::TypeError(V8String(
- script_state->GetIsolate(),
- "This readable stream reader has been released and cannot be used "
- "to cancel its previous owner stream")));
+ exception_state.ThrowTypeError(
+ "This readable stream reader has been released and cannot be used to "
+ "cancel its previous owner stream");
+ return ScriptPromise();
}
// 3. Return ! ReadableStreamReaderGenericCancel(this, reason).
@@ -81,17 +82,16 @@ ScriptPromise ReadableStreamReader::cancel(ScriptState* script_state,
return ScriptPromise(script_state, result);
}
-ScriptPromise ReadableStreamReader::read(ScriptState* script_state) {
+ScriptPromise ReadableStreamReader::read(ScriptState* script_state,
+ ExceptionState& exception_state) {
// https://streams.spec.whatwg.org/#default-reader-read
// 2. If this.[[ownerReadableStream]] is undefined, return a promise rejected
// with a TypeError exception.
if (!owner_readable_stream_) {
- return ScriptPromise::Reject(
- script_state,
- v8::Exception::TypeError(V8String(
- script_state->GetIsolate(),
- "This readable stream reader has been released and cannot be used "
- "to read from its previous owner stream")));
+ exception_state.ThrowTypeError(
+ "This readable stream reader has been released and cannot be used to "
+ "read from its previous owner stream");
+ return ScriptPromise();
}
// 3. Return ! ReadableStreamReaderRead(this).
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 a112b8d994f..08dc0ff4569 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
@@ -41,11 +41,11 @@ class CORE_EXPORT ReadableStreamReader : public ScriptWrappable {
ScriptPromise closed(ScriptState*) const;
// https://streams.spec.whatwg.org/#default-reader-cancel
- ScriptPromise cancel(ScriptState*);
- ScriptPromise cancel(ScriptState*, ScriptValue reason);
+ ScriptPromise cancel(ScriptState*, ExceptionState&);
+ ScriptPromise cancel(ScriptState*, ScriptValue reason, ExceptionState&);
// https://streams.spec.whatwg.org/#default-reader-read
- ScriptPromise read(ScriptState*);
+ ScriptPromise read(ScriptState*, ExceptionState&);
// https://streams.spec.whatwg.org/#default-reader-release-lock
void releaseLock(ScriptState*, ExceptionState&);
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 fcebcbaf07c..9601e3ae57e 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
@@ -191,7 +191,7 @@ TEST_F(ReadableStreamTest, GetReader) {
EXPECT_EQ(stream->IsDisturbed(script_state, ASSERT_NO_EXCEPTION),
base::make_optional(false));
- reader->read(script_state);
+ reader->read(script_state, ASSERT_NO_EXCEPTION);
EXPECT_EQ(stream->IsDisturbed(script_state, ASSERT_NO_EXCEPTION),
base::make_optional(true));
@@ -417,6 +417,58 @@ TEST_F(ReadableStreamTest, Serialize) {
base::make_optional<String>("hello, bye"));
}
+TEST_F(ReadableStreamTest, GarbageCollectJavaScriptUnderlyingSource) {
+ V8TestingScope scope;
+ auto* isolate = scope.GetIsolate();
+
+ v8::Global<v8::Object> weak_underlying_source;
+
+ {
+ v8::HandleScope handle_scope(isolate);
+ v8::Local<v8::Object> underlying_source = v8::Object::New(isolate);
+ ReadableStream::Create(scope.GetScriptState(),
+ ScriptValue(isolate, underlying_source),
+ ASSERT_NO_EXCEPTION);
+ weak_underlying_source = v8::Global<v8::Object>(isolate, underlying_source);
+ weak_underlying_source.SetWeak();
+ }
+
+ V8GCController::CollectAllGarbageForTesting(
+ isolate, v8::EmbedderHeapTracer::EmbedderStackState::kEmpty);
+
+ EXPECT_TRUE(weak_underlying_source.IsEmpty());
+}
+
+TEST_F(ReadableStreamTest, GarbageCollectCPlusPlusUnderlyingSource) {
+ class NoopUnderlyingSource : public UnderlyingSourceBase {
+ public:
+ NoopUnderlyingSource(ScriptState* script_state)
+ : UnderlyingSourceBase(script_state) {}
+ };
+
+ V8TestingScope scope;
+ auto* isolate = scope.GetIsolate();
+
+ WeakPersistent<NoopUnderlyingSource> weak_underlying_source;
+
+ {
+ v8::HandleScope handle_scope(isolate);
+ auto* underlying_source =
+ MakeGarbageCollected<NoopUnderlyingSource>(scope.GetScriptState());
+ weak_underlying_source = underlying_source;
+ ReadableStream::CreateWithCountQueueingStrategy(scope.GetScriptState(),
+ underlying_source, 0);
+ }
+
+ // Allow Promises to resolve.
+ v8::MicrotasksScope::PerformCheckpoint(isolate);
+
+ V8GCController::CollectAllGarbageForTesting(
+ isolate, v8::EmbedderHeapTracer::EmbedderStackState::kEmpty);
+
+ EXPECT_FALSE(weak_underlying_source);
+}
+
} // namespace
} // 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 fb089841c19..98d0ff08ee6 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
@@ -41,8 +41,6 @@ StreamPromiseResolver::StreamPromiseResolver(ScriptState* script_state)
v8::Promise::Resolver::New(script_state->GetContext())
.ToLocalChecked()) {}
-StreamPromiseResolver::~StreamPromiseResolver() = default;
-
void StreamPromiseResolver::Resolve(ScriptState* script_state,
v8::Local<v8::Value> value) {
DCHECK(!resolver_.IsEmpty());
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 02a7014e9b7..500ecd7b211 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
@@ -47,7 +47,6 @@ class CORE_EXPORT StreamPromiseResolver final
// Creates an initialised promise.
explicit StreamPromiseResolver(ScriptState*);
- ~StreamPromiseResolver();
// Resolves the promise with |value|. Does nothing if the promise is already
// settled.
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 d68374c20be..ee7dbc81708 100644
--- a/chromium/third_party/blink/renderer/core/streams/transferable_streams.cc
+++ b/chromium/third_party/blink/renderer/core/streams/transferable_streams.cc
@@ -10,11 +10,11 @@
#include "base/stl_util.h"
#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_post_message_options.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
#include "third_party/blink/renderer/core/events/message_event.h"
#include "third_party/blink/renderer/core/messaging/message_port.h"
-#include "third_party/blink/renderer/core/messaging/post_message_options.h"
#include "third_party/blink/renderer/core/streams/miscellaneous_operations.h"
#include "third_party/blink/renderer/core/streams/promise_handler.h"
#include "third_party/blink/renderer/core/streams/readable_stream.h"
@@ -812,21 +812,25 @@ void CrossRealmTransformReadable::HandleMessage(MessageType type,
v8::Local<v8::Value> value) {
switch (type) {
case MessageType::kChunk: {
- // This can't throw because we always use the default strategy size
- // algorithm, which doesn't throw, and always returns a valid value of
- // 1.0.
- ReadableStreamDefaultController::Enqueue(script_state_, controller_,
- value, ASSERT_NO_EXCEPTION);
+ if (ReadableStreamDefaultController::CanCloseOrEnqueue(controller_)) {
+ // This can't throw because we always use the default strategy size
+ // algorithm, which doesn't throw, and always returns a valid value of
+ // 1.0.
+ ReadableStreamDefaultController::Enqueue(script_state_, controller_,
+ value, ASSERT_NO_EXCEPTION);
- backpressure_promise_->ResolveWithUndefined(script_state_);
- backpressure_promise_ =
- MakeGarbageCollected<StreamPromiseResolver>(script_state_);
+ backpressure_promise_->ResolveWithUndefined(script_state_);
+ backpressure_promise_ =
+ MakeGarbageCollected<StreamPromiseResolver>(script_state_);
+ }
return;
}
case MessageType::kClose:
finished_ = true;
- ReadableStreamDefaultController::Close(script_state_, controller_);
+ if (ReadableStreamDefaultController::CanCloseOrEnqueue(controller_)) {
+ ReadableStreamDefaultController::Close(script_state_, controller_);
+ }
message_port_->close();
return;
diff --git a/chromium/third_party/blink/renderer/core/streams/transferable_streams_test.cc b/chromium/third_party/blink/renderer/core/streams/transferable_streams_test.cc
index fb2b46ba9b6..8485423cb9f 100644
--- a/chromium/third_party/blink/renderer/core/streams/transferable_streams_test.cc
+++ b/chromium/third_party/blink/renderer/core/streams/transferable_streams_test.cc
@@ -43,7 +43,8 @@ TEST(TransferableStreamsTest, SmokeTest) {
auto* writer = writable->getWriter(script_state, ASSERT_NO_EXCEPTION);
auto* reader = readable->getReader(script_state, ASSERT_NO_EXCEPTION);
- writer->write(script_state, ScriptValue::CreateNull(scope.GetIsolate()));
+ writer->write(script_state, ScriptValue::CreateNull(scope.GetIsolate()),
+ ASSERT_NO_EXCEPTION);
class ExpectNullResponse : public ScriptFunction {
public:
@@ -105,7 +106,7 @@ TEST(TransferableStreamsTest, SmokeTest) {
};
bool got_response = false;
- reader->read(script_state)
+ reader->read(script_state, ASSERT_NO_EXCEPTION)
.Then(ExpectNullResponse::Create(script_state, &got_response),
ExpectNotReached::Create(script_state));
diff --git a/chromium/third_party/blink/renderer/core/streams/transform_stream.idl b/chromium/third_party/blink/renderer/core/streams/transform_stream.idl
index 31a44c7a440..ad26ffa35da 100644
--- a/chromium/third_party/blink/renderer/core/streams/transform_stream.idl
+++ b/chromium/third_party/blink/renderer/core/streams/transform_stream.idl
@@ -4,13 +4,11 @@
// https://streams.spec.whatwg.org/#ts-class
[
- Exposed=(Window,Worker,Worklet),
- Constructor(optional any transformer,
- optional any writableStrategy,
- optional any readableStrategy),
- RaisesException=Constructor,
- ConstructorCallWith=ScriptState
+ Exposed=(Window,Worker,Worklet)
] interface TransformStream {
+ [CallWith=ScriptState, RaisesException] constructor(optional any transformer,
+ optional any writableStrategy,
+ optional any readableStrategy);
[NotEnumerable] readonly attribute ReadableStream readable;
[NotEnumerable] readonly attribute WritableStream writable;
};
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 90ee1e77629..db3e39a83d2 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
@@ -24,6 +24,21 @@ namespace blink {
TransformStreamDefaultController::TransformStreamDefaultController() = default;
TransformStreamDefaultController::~TransformStreamDefaultController() = default;
+base::Optional<double> TransformStreamDefaultController::desiredSize() const {
+ // https://streams.spec.whatwg.org/#ts-default-controller-desired-size
+ // 2. Let readableController be
+ // this.[[controlledTransformStream]].[[readable]].
+ // [[readableStreamController]].
+ const auto* readable_controller =
+ controlled_transform_stream_->readable_->GetController();
+
+ // 3. Return !
+ // ReadableStreamDefaultControllerGetDesiredSize(readableController).
+ // Use the accessor instead as it already has the semantics we need and can't
+ // be interfered with from JavaScript.
+ return readable_controller->desiredSize();
+}
+
double TransformStreamDefaultController::desiredSize(bool& is_null) const {
// https://streams.spec.whatwg.org/#ts-default-controller-desired-size
// 2. Let readableController be
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 1940931db86..4e859c06037 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
@@ -26,7 +26,9 @@ class CORE_EXPORT TransformStreamDefaultController : public ScriptWrappable {
~TransformStreamDefaultController() override;
// https://streams.spec.whatwg.org/#ts-default-controller-desired-size
- double desiredSize(bool& is_null) const;
+ base::Optional<double> desiredSize() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ double desiredSize(bool& is_null) const; // DEPRECATED
// https://streams.spec.whatwg.org/#ts-default-controller-enqueue
void enqueue(ScriptState*, ExceptionState&);
diff --git a/chromium/third_party/blink/renderer/core/streams/transform_stream_default_controller.idl b/chromium/third_party/blink/renderer/core/streams/transform_stream_default_controller.idl
index 19aebfb2c15..080f78e7a98 100644
--- a/chromium/third_party/blink/renderer/core/streams/transform_stream_default_controller.idl
+++ b/chromium/third_party/blink/renderer/core/streams/transform_stream_default_controller.idl
@@ -7,8 +7,7 @@
// https://streams.spec.whatwg.org/#rs-default-controller-class-definition
[
Exposed=(Window,Worker,Worklet),
- NoInterfaceObject,
- RaisesException=Constructor
+ NoInterfaceObject
] interface TransformStreamDefaultController {
[NotEnumerable] readonly attribute double? desiredSize;
[CallWith=ScriptState, NotEnumerable, RaisesException] void enqueue(
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 7d0ea4b3243..13debfef60a 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
@@ -265,7 +265,8 @@ TEST_F(TransformStreamTest, EnqueueFromTransform) {
ReadableStream* readable = Stream()->Readable();
auto* reader = readable->getReader(script_state, ASSERT_NO_EXCEPTION);
- ScriptPromiseTester tester(script_state, reader->read(script_state));
+ ScriptPromiseTester tester(script_state,
+ reader->read(script_state, ASSERT_NO_EXCEPTION));
tester.WaitUntilSettled();
EXPECT_TRUE(tester.IsFulfilled());
EXPECT_TRUE(IsIteratorForStringMatching(script_state, tester.Value(), "a"));
@@ -298,7 +299,8 @@ TEST_F(TransformStreamTest, EnqueueFromFlush) {
ReadableStream* readable = Stream()->Readable();
auto* reader = readable->getReader(script_state, ASSERT_NO_EXCEPTION);
- ScriptPromiseTester tester(script_state, reader->read(script_state));
+ ScriptPromiseTester tester(script_state,
+ reader->read(script_state, ASSERT_NO_EXCEPTION));
tester.WaitUntilSettled();
EXPECT_TRUE(tester.IsFulfilled());
EXPECT_TRUE(IsIteratorForStringMatching(script_state, tester.Value(), "a"));
@@ -333,7 +335,8 @@ TEST_F(TransformStreamTest, ThrowFromTransform) {
ReadableStream* readable = Stream()->Readable();
auto* reader = readable->getReader(script_state, ASSERT_NO_EXCEPTION);
- ScriptPromiseTester read_tester(script_state, reader->read(script_state));
+ ScriptPromiseTester read_tester(
+ script_state, reader->read(script_state, ASSERT_NO_EXCEPTION));
read_tester.WaitUntilSettled();
EXPECT_TRUE(read_tester.IsRejected());
EXPECT_TRUE(IsTypeError(script_state, read_tester.Value(), kMessage));
@@ -370,7 +373,8 @@ TEST_F(TransformStreamTest, ThrowFromFlush) {
ReadableStream* readable = Stream()->Readable();
auto* reader = readable->getReader(script_state, ASSERT_NO_EXCEPTION);
- ScriptPromiseTester read_tester(script_state, reader->read(script_state));
+ ScriptPromiseTester read_tester(
+ script_state, reader->read(script_state, ASSERT_NO_EXCEPTION));
read_tester.WaitUntilSettled();
EXPECT_TRUE(read_tester.IsRejected());
EXPECT_TRUE(IsTypeError(script_state, read_tester.Value(), kMessage));
@@ -441,7 +445,7 @@ TEST_F(TransformStreamTest, WaitInTransform) {
Stream()
->Readable()
->getReader(script_state, ASSERT_NO_EXCEPTION)
- ->read(script_state);
+ ->read(script_state, ASSERT_NO_EXCEPTION);
ScriptPromiseTester write_tester(script_state,
ScriptPromise::Cast(script_state, promise));
@@ -499,7 +503,7 @@ TEST_F(TransformStreamTest, WaitInFlush) {
Stream()
->Readable()
->getReader(script_state, ASSERT_NO_EXCEPTION)
- ->read(script_state);
+ ->read(script_state, ASSERT_NO_EXCEPTION);
ScriptPromiseTester close_tester(script_state,
ScriptPromise::Cast(script_state, promise));
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 900dcbf94a2..5e2a020fa2e 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
@@ -13,6 +13,7 @@
namespace blink {
+class ExceptionState;
class ScriptValue;
class ScriptState;
@@ -26,22 +27,29 @@ class CORE_EXPORT UnderlyingSinkBase : public ScriptWrappable {
// |controller| and are called from IDL. Also we define virtual |start| and
// |write| which take WritableStreamDefaultController.
virtual ScriptPromise start(ScriptState*,
- WritableStreamDefaultController*) = 0;
+ WritableStreamDefaultController*,
+ ExceptionState&) = 0;
virtual ScriptPromise write(ScriptState*,
ScriptValue chunk,
- WritableStreamDefaultController*) = 0;
- virtual ScriptPromise close(ScriptState*) = 0;
- virtual ScriptPromise abort(ScriptState*, ScriptValue reason) = 0;
+ WritableStreamDefaultController*,
+ ExceptionState&) = 0;
+ virtual ScriptPromise close(ScriptState*, ExceptionState&) = 0;
+ virtual ScriptPromise abort(ScriptState*,
+ ScriptValue reason,
+ ExceptionState&) = 0;
- ScriptPromise start(ScriptState* script_state, ScriptValue controller) {
+ ScriptPromise start(ScriptState* script_state,
+ ScriptValue controller,
+ ExceptionState& exception_state) {
controller_ = WritableStreamDefaultController::From(controller);
- return start(script_state, controller_);
+ return start(script_state, controller_, exception_state);
}
ScriptPromise write(ScriptState* script_state,
ScriptValue chunk,
- ScriptValue controller) {
+ ScriptValue controller,
+ ExceptionState& exception_state) {
DCHECK(controller_);
- return write(script_state, chunk, controller_);
+ return write(script_state, chunk, controller_, exception_state);
}
void Trace(Visitor* visitor) override {
diff --git a/chromium/third_party/blink/renderer/core/streams/underlying_sink_base.idl b/chromium/third_party/blink/renderer/core/streams/underlying_sink_base.idl
index 288fd473b17..250a8acbaa4 100644
--- a/chromium/third_party/blink/renderer/core/streams/underlying_sink_base.idl
+++ b/chromium/third_party/blink/renderer/core/streams/underlying_sink_base.idl
@@ -10,8 +10,8 @@
NoInterfaceObject
]
interface UnderlyingSinkBase {
- [CallWith=ScriptState] Promise<void> start(any controller);
- [CallWith=ScriptState] Promise<void> write(any chunk, any controller);
- [CallWith=ScriptState] Promise<void> close();
- [CallWith=ScriptState] Promise<void> abort(any reason);
+ [CallWith=ScriptState, RaisesException] Promise<void> start(any controller);
+ [CallWith=ScriptState, RaisesException] Promise<void> write(any chunk, any controller);
+ [CallWith=ScriptState, RaisesException] Promise<void> close();
+ [CallWith=ScriptState, RaisesException] Promise<void> abort(any reason);
};
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 d8c0c90ddb8..f966b055246 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
@@ -33,6 +33,12 @@ ScriptPromise UnderlyingSourceBase::pull(ScriptState* script_state) {
return ScriptPromise::CastUndefined(script_state);
}
+ScriptPromise UnderlyingSourceBase::cancelWrapper(ScriptState* script_state) {
+ v8::Isolate* isolate = script_state->GetIsolate();
+ return cancelWrapper(script_state,
+ ScriptValue(isolate, v8::Undefined(isolate)));
+}
+
ScriptPromise UnderlyingSourceBase::cancelWrapper(ScriptState* script_state,
ScriptValue reason) {
if (controller_)
@@ -50,17 +56,17 @@ ScriptValue UnderlyingSourceBase::type(ScriptState* script_state) const {
v8::Undefined(script_state->GetIsolate()));
}
-void UnderlyingSourceBase::ContextDestroyed(ExecutionContext*) {
+void UnderlyingSourceBase::ContextDestroyed() {
if (controller_) {
controller_->NoteHasBeenCanceled();
controller_.Clear();
}
}
-void UnderlyingSourceBase::Trace(blink::Visitor* visitor) {
+void UnderlyingSourceBase::Trace(Visitor* visitor) {
visitor->Trace(controller_);
ScriptWrappable::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 416ebd3ce64..a94d9fc5523 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
@@ -9,8 +9,8 @@
#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"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
@@ -22,12 +22,12 @@ class ReadableStreamDefaultControllerWithScriptScope;
class CORE_EXPORT UnderlyingSourceBase
: public ScriptWrappable,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(UnderlyingSourceBase);
public:
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
~UnderlyingSourceBase() override = default;
ScriptPromise startWrapper(ScriptState*, ScriptValue stream);
@@ -35,18 +35,20 @@ class CORE_EXPORT UnderlyingSourceBase
virtual ScriptPromise pull(ScriptState*);
+ ScriptPromise cancelWrapper(ScriptState*);
ScriptPromise cancelWrapper(ScriptState*, ScriptValue reason);
virtual ScriptPromise Cancel(ScriptState*, ScriptValue reason);
ScriptValue type(ScriptState*) const;
- // ContextLifecycleObserver
+ // ExecutionContextLifecycleObserver
// TODO(ricea): Is this still useful?
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
protected:
explicit UnderlyingSourceBase(ScriptState* script_state)
- : ContextLifecycleObserver(ExecutionContext::From(script_state)) {}
+ : ExecutionContextLifecycleObserver(
+ ExecutionContext::From(script_state)) {}
ReadableStreamDefaultControllerWithScriptScope* Controller() const {
return controller_;
diff --git a/chromium/third_party/blink/renderer/core/streams/underlying_source_base.idl b/chromium/third_party/blink/renderer/core/streams/underlying_source_base.idl
index bdf11311634..7935b92a7f3 100644
--- a/chromium/third_party/blink/renderer/core/streams/underlying_source_base.idl
+++ b/chromium/third_party/blink/renderer/core/streams/underlying_source_base.idl
@@ -13,7 +13,7 @@
interface UnderlyingSourceBase {
[CallWith=ScriptState, ImplementedAs=startWrapper] Promise<void> start(any stream);
[CallWith=ScriptState] Promise<void> pull();
- [CallWith=ScriptState, ImplementedAs=cancelWrapper] Promise<void> cancel([DefaultValue=Undefined] optional any reason);
+ [CallWith=ScriptState, ImplementedAs=cancelWrapper] Promise<void> cancel(optional any reason);
// This only exists to prevent Object.prototype.type being accessed.
[CallWith=ScriptState] readonly attribute any type;
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 2b607f84bce..8446b4a9e33 100644
--- a/chromium/third_party/blink/renderer/core/streams/writable_stream.cc
+++ b/chromium/third_party/blink/renderer/core/streams/writable_stream.cc
@@ -6,10 +6,10 @@
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_queuing_strategy_init.h"
#include "third_party/blink/renderer/core/streams/count_queuing_strategy.h"
#include "third_party/blink/renderer/core/streams/miscellaneous_operations.h"
#include "third_party/blink/renderer/core/streams/promise_handler.h"
-#include "third_party/blink/renderer/core/streams/queuing_strategy_init.h"
#include "third_party/blink/renderer/core/streams/readable_stream.h"
#include "third_party/blink/renderer/core/streams/stream_promise_resolver.h"
#include "third_party/blink/renderer/core/streams/transferable_streams.h"
@@ -124,6 +124,26 @@ ScriptPromise WritableStream::abort(ScriptState* script_state,
Abort(script_state, this, reason.V8Value()));
}
+ScriptPromise WritableStream::close(ScriptState* script_state,
+ ExceptionState& exception_state) {
+ // https://streams.spec.whatwg.org/#ws-close
+ // 2. If ! IsWritableStreamLocked(this) is true, return a promise rejected
+ // with a TypeError exception.
+ if (IsLocked(this)) {
+ exception_state.ThrowTypeError("Cannot close a locked stream");
+ return ScriptPromise();
+ }
+
+ // 3. If ! WritableStreamCloseQueuedOrInFlight(this) is true, return a promise
+ // rejected with a TypeError exception.
+ if (CloseQueuedOrInFlight(this)) {
+ exception_state.ThrowTypeError("Cannot close a closed or closing stream");
+ return ScriptPromise();
+ }
+
+ return ScriptPromise(script_state, Close(script_state, this));
+}
+
WritableStreamDefaultWriter* WritableStream::getWriter(
ScriptState* script_state,
ExceptionState& exception_state) {
@@ -324,6 +344,49 @@ v8::Local<v8::Promise> WritableStream::AddWriteRequest(
return promise->V8Promise(script_state->GetIsolate());
}
+v8::Local<v8::Promise> WritableStream::Close(ScriptState* script_state,
+ WritableStream* stream) {
+ // https://streams.spec.whatwg.org/#writable-stream-close
+ // 1. Let state be stream.[[state]].
+ const auto state = stream->GetState();
+
+ // 2. If state is "closed" or "errored", return a promise rejected with a
+ // TypeError exception.
+ if (state == kClosed || state == kErrored) {
+ return PromiseReject(script_state,
+ CreateCannotActionOnStateStreamException(
+ script_state->GetIsolate(), "close", state));
+ }
+
+ // 3. Assert: state is "writable" or "erroring".
+ CHECK(state == kWritable || state == kErroring);
+
+ // 4. Assert: ! WritableStreamCloseQueuedOrInFlight(stream) is false.
+ CHECK(!CloseQueuedOrInFlight(stream));
+
+ // 5. Let promise be a new promise.
+ auto* promise = MakeGarbageCollected<StreamPromiseResolver>(script_state);
+
+ // 6. Set stream.[[closeRequest]] to promise.
+ stream->SetCloseRequest(promise);
+
+ // 7. Let writer be stream.[[writer]].
+ WritableStreamDefaultWriter* writer = stream->writer_;
+
+ // 8. If writer is not undefined, and stream.[[backpressure]] is true, and
+ // state is "writable", resolve writer.[[readyPromise]] with undefined.
+ if (writer && stream->HasBackpressure() && state == kWritable) {
+ writer->ReadyPromise()->ResolveWithUndefined(script_state);
+ }
+
+ // 9. Perform ! WritableStreamDefaultControllerClose(
+ // stream.[[writableStreamController]]).
+ WritableStreamDefaultController::Close(script_state, stream->Controller());
+
+ // 10. Return promise.
+ return promise->V8Promise(script_state->GetIsolate());
+}
+
bool WritableStream::CloseQueuedOrInFlight(const WritableStream* stream) {
// https://streams.spec.whatwg.org/#writable-stream-close-queued-or-in-flight
// 1. If stream.[[closeRequest]] is undefined and
@@ -725,6 +788,37 @@ void WritableStream::SetWriter(WritableStreamDefaultWriter* writer) {
writer_ = writer;
}
+// static
+v8::Local<v8::String> WritableStream::CreateCannotActionOnStateStreamMessage(
+ v8::Isolate* isolate,
+ const char* action,
+ const char* state_name) {
+ return V8String(isolate, String::Format("Cannot %s a %s writable stream",
+ action, state_name));
+}
+
+// static
+v8::Local<v8::Value> WritableStream::CreateCannotActionOnStateStreamException(
+ v8::Isolate* isolate,
+ const char* action,
+ State state) {
+ const char* state_name = nullptr;
+ switch (state) {
+ case WritableStream::kClosed:
+ state_name = "CLOSED";
+ break;
+
+ case WritableStream::kErrored:
+ state_name = "ERRORED";
+ break;
+
+ default:
+ NOTREACHED();
+ }
+ return v8::Exception::TypeError(
+ CreateCannotActionOnStateStreamMessage(isolate, action, state_name));
+}
+
void WritableStream::Trace(Visitor* visitor) {
visitor->Trace(close_request_);
visitor->Trace(in_flight_write_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 27c840f4ac6..70533b494fa 100644
--- a/chromium/third_party/blink/renderer/core/streams/writable_stream.h
+++ b/chromium/third_party/blink/renderer/core/streams/writable_stream.h
@@ -84,6 +84,9 @@ class CORE_EXPORT WritableStream : public ScriptWrappable {
ScriptPromise abort(ScriptState*, ExceptionState&);
ScriptPromise abort(ScriptState*, ScriptValue reason, ExceptionState&);
+ // https://streams.spec.whatwg.org/#ws-close
+ ScriptPromise close(ScriptState*, ExceptionState&);
+
// https://streams.spec.whatwg.org/#ws-get-writer
WritableStreamDefaultWriter* getWriter(ScriptState*, ExceptionState&);
@@ -126,6 +129,8 @@ class CORE_EXPORT WritableStream : public ScriptWrappable {
// https://streams.spec.whatwg.org/#writable-stream-add-write-request
static v8::Local<v8::Promise> AddWriteRequest(ScriptState*, WritableStream*);
+ static v8::Local<v8::Promise> Close(ScriptState*, WritableStream*);
+
// https://streams.spec.whatwg.org/#writable-stream-close-queued-or-in-flight
static bool CloseQueuedOrInFlight(const WritableStream*);
@@ -204,13 +209,20 @@ class CORE_EXPORT WritableStream : public ScriptWrappable {
void SetController(WritableStreamDefaultController*);
void SetWriter(WritableStreamDefaultWriter*);
- void Trace(Visitor*) override;
+ // Utility methods shared with other classes.
+ static v8::Local<v8::String> CreateCannotActionOnStateStreamMessage(
+ v8::Isolate*,
+ const char* action,
+ const char* state_name);
- private:
- using PromiseQueue = HeapDeque<Member<StreamPromiseResolver>>;
+ static v8::Local<v8::Value> CreateCannotActionOnStateStreamException(
+ v8::Isolate*,
+ const char* action,
+ State);
- class PendingAbortRequest;
+ void Trace(Visitor*) override;
+ protected:
// Used when creating a stream from JavaScript. Called from Create().
// https://streams.spec.whatwg.org/#ws-constructor
void InitInternal(ScriptState*,
@@ -218,6 +230,11 @@ class CORE_EXPORT WritableStream : public ScriptWrappable {
ScriptValue raw_strategy,
ExceptionState&);
+ private:
+ using PromiseQueue = HeapDeque<Member<StreamPromiseResolver>>;
+
+ class PendingAbortRequest;
+
// https://streams.spec.whatwg.org/#writable-stream-has-operation-marked-in-flight
static bool HasOperationMarkedInFlight(const WritableStream*);
diff --git a/chromium/third_party/blink/renderer/core/streams/writable_stream.idl b/chromium/third_party/blink/renderer/core/streams/writable_stream.idl
index 790b74ba44d..8cb0ff8c533 100644
--- a/chromium/third_party/blink/renderer/core/streams/writable_stream.idl
+++ b/chromium/third_party/blink/renderer/core/streams/writable_stream.idl
@@ -4,14 +4,12 @@
// https://streams.spec.whatwg.org/#ws-class
[
- Exposed=(Window,Worker,Worklet),
- Constructor(optional any underlyingSink, optional any strategy),
- MeasureAs=WritableStreamConstructor,
- RaisesException=Constructor,
- ConstructorCallWith=ScriptState
+ Exposed=(Window,Worker,Worklet)
] interface WritableStream {
+ [CallWith=ScriptState, RaisesException, MeasureAs=WritableStreamConstructor] constructor(optional any underlyingSink, optional any strategy);
[NotEnumerable] readonly attribute boolean locked;
[RaisesException, CallWith=ScriptState, NotEnumerable] Promise<void> abort(
optional any reason);
+ [RaisesException, CallWith=ScriptState, NotEnumerable] Promise<void> close();
[RaisesException, CallWith=ScriptState, NotEnumerable] WritableStreamDefaultWriter getWriter();
};
diff --git a/chromium/third_party/blink/renderer/core/streams/writable_stream_default_controller.idl b/chromium/third_party/blink/renderer/core/streams/writable_stream_default_controller.idl
index 96086b6a643..fd2327f5486 100644
--- a/chromium/third_party/blink/renderer/core/streams/writable_stream_default_controller.idl
+++ b/chromium/third_party/blink/renderer/core/streams/writable_stream_default_controller.idl
@@ -7,8 +7,7 @@
// https://streams.spec.whatwg.org/#ws-default-controller-class-definition
[
Exposed=(Window,Worker,Worklet),
- NoInterfaceObject,
- RaisesException=Constructor
+ NoInterfaceObject
] interface WritableStreamDefaultController {
[CallWith=ScriptState, NotEnumerable] void error(optional any e);
};
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 2819f282718..d6adf54e57d 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
@@ -21,42 +21,15 @@ namespace blink {
namespace {
-v8::Local<v8::Value> CreateWriterLockReleasedException(v8::Isolate* isolate,
- const char* verbed) {
- return v8::Exception::TypeError(V8String(
- isolate,
- String::Format(
- "This writable stream writer has been released and cannot be %s",
- verbed)));
-}
-
-v8::Local<v8::String> CreateCannotActionOnStateStreamMessage(
- v8::Isolate* isolate,
- const char* action,
- const char* state_name) {
- return V8String(isolate, String::Format("Cannot %s a %s writable stream",
- action, state_name));
+String CreateWriterLockReleasedMessage(const char* verbed) {
+ return String::Format(
+ "This writable stream writer has been released and cannot be %s", verbed);
}
-v8::Local<v8::Value> CreateCannotActionOnStateStreamException(
- v8::Isolate* isolate,
- const char* action,
- WritableStream::State state) {
- const char* state_name = nullptr;
- switch (state) {
- case WritableStream::kClosed:
- state_name = "CLOSED";
- break;
-
- case WritableStream::kErrored:
- state_name = "ERRORED";
- break;
-
- default:
- NOTREACHED();
- }
+v8::Local<v8::Value> CreateWriterLockReleasedException(v8::Isolate* isolate,
+ const char* verbed) {
return v8::Exception::TypeError(
- CreateCannotActionOnStateStreamMessage(isolate, action, state_name));
+ V8String(isolate, CreateWriterLockReleasedMessage(verbed)));
}
} // namespace
@@ -207,21 +180,25 @@ ScriptPromise WritableStreamDefaultWriter::ready(
return ready_promise_->GetScriptPromise(script_state);
}
-ScriptPromise WritableStreamDefaultWriter::abort(ScriptState* script_state) {
+ScriptPromise WritableStreamDefaultWriter::abort(
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
return abort(script_state,
ScriptValue(script_state->GetIsolate(),
- v8::Undefined(script_state->GetIsolate())));
+ v8::Undefined(script_state->GetIsolate())),
+ exception_state);
}
-ScriptPromise WritableStreamDefaultWriter::abort(ScriptState* script_state,
- ScriptValue reason) {
+ScriptPromise WritableStreamDefaultWriter::abort(
+ ScriptState* script_state,
+ ScriptValue reason,
+ ExceptionState& exception_state) {
// https://streams.spec.whatwg.org/#default-writer-abort
// 2. If this.[[ownerWritableStream]] is undefined, return a promise rejected
// with a TypeError exception.
if (!owner_writable_stream_) {
- return ScriptPromise::Reject(script_state,
- CreateWriterLockReleasedException(
- script_state->GetIsolate(), "aborted"));
+ exception_state.ThrowTypeError(CreateWriterLockReleasedMessage("aborted"));
+ return ScriptPromise();
}
// 3. Return ! WritableStreamDefaultWriterAbort(this, reason).
@@ -229,7 +206,9 @@ ScriptPromise WritableStreamDefaultWriter::abort(ScriptState* script_state,
Abort(script_state, this, reason.V8Value()));
}
-ScriptPromise WritableStreamDefaultWriter::close(ScriptState* script_state) {
+ScriptPromise WritableStreamDefaultWriter::close(
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
// https://streams.spec.whatwg.org/#default-writer-close
// 2. Let stream be this.[[ownerWritableStream]].
WritableStream* stream = owner_writable_stream_;
@@ -237,19 +216,17 @@ ScriptPromise WritableStreamDefaultWriter::close(ScriptState* script_state) {
// 3. If stream is undefined, return a promise rejected with a TypeError
// exception.
if (!stream) {
- return ScriptPromise::Reject(script_state,
- CreateWriterLockReleasedException(
- script_state->GetIsolate(), "closed"));
+ exception_state.ThrowTypeError(CreateWriterLockReleasedMessage("closed"));
+ return ScriptPromise();
}
// 4. If ! WritableStreamCloseQueuedOrInFlight(stream) is true, return a
// promise rejected with a TypeError exception.
if (WritableStream::CloseQueuedOrInFlight(stream)) {
- return ScriptPromise::Reject(
- script_state, v8::Exception::TypeError(
- V8String(script_state->GetIsolate(),
- "Cannot close a writable stream that has "
- "already been requested to be closed")));
+ exception_state.ThrowTypeError(
+ "Cannot close a writable stream that has "
+ "already been requested to be closed");
+ return ScriptPromise();
}
// 5. Return ! WritableStreamDefaultWriterClose(this).
@@ -273,21 +250,26 @@ void WritableStreamDefaultWriter::releaseLock(ScriptState* script_state) {
Release(script_state, this);
}
-ScriptPromise WritableStreamDefaultWriter::write(ScriptState* script_state) {
+ScriptPromise WritableStreamDefaultWriter::write(
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
return write(script_state,
ScriptValue(script_state->GetIsolate(),
- v8::Undefined(script_state->GetIsolate())));
+ v8::Undefined(script_state->GetIsolate())),
+ exception_state);
}
-ScriptPromise WritableStreamDefaultWriter::write(ScriptState* script_state,
- ScriptValue chunk) {
+ScriptPromise WritableStreamDefaultWriter::write(
+ ScriptState* script_state,
+ ScriptValue chunk,
+ ExceptionState& exception_state) {
// https://streams.spec.whatwg.org/#default-writer-write
// 2. If this.[[ownerWritableStream]] is undefined, return a promise rejected
// with a TypeError exception.
if (!owner_writable_stream_) {
- return ScriptPromise::Reject(script_state,
- CreateWriterLockReleasedException(
- script_state->GetIsolate(), "written to"));
+ exception_state.ThrowTypeError(
+ CreateWriterLockReleasedMessage("written to"));
+ return ScriptPromise();
}
// 3. Return ! WritableStreamDefaultWriterWrite(this, chunk).
@@ -427,13 +409,14 @@ v8::Local<v8::Promise> WritableStreamDefaultWriter::Write(
if (WritableStream::CloseQueuedOrInFlight(stream)) {
return PromiseReject(
script_state,
- v8::Exception::TypeError(CreateCannotActionOnStateStreamMessage(
- isolate, "write to", "closing")));
+ v8::Exception::TypeError(
+ WritableStream::CreateCannotActionOnStateStreamMessage(
+ isolate, "write to", "closing")));
}
if (state == WritableStream::kClosed) {
- return PromiseReject(script_state,
- CreateCannotActionOnStateStreamException(
- isolate, "write to", WritableStream::kClosed));
+ return PromiseReject(
+ script_state, WritableStream::CreateCannotActionOnStateStreamException(
+ isolate, "write to", WritableStream::kClosed));
}
// 9. If state is "erroring", return a promise rejected with
@@ -523,42 +506,8 @@ v8::Local<v8::Promise> WritableStreamDefaultWriter::Close(
// 2. Assert: stream is not undefined.
DCHECK(stream);
- // 3. Let state be stream.[[state]].
- const auto state = stream->GetState();
-
- // 4. If state is "closed" or "errored", return a promise rejected with a
- // TypeError exception.
- if (state == WritableStream::kClosed || state == WritableStream::kErrored) {
- return PromiseReject(script_state,
- CreateCannotActionOnStateStreamException(
- script_state->GetIsolate(), "close", state));
- }
-
- // 5. Assert: state is "writable" or "erroring".
- DCHECK(state == WritableStream::kWritable ||
- state == WritableStream::kErroring);
-
- // 6. Assert: ! WritableStreamCloseQueuedOrInFlight(stream) is false.
- DCHECK(!WritableStream::CloseQueuedOrInFlight(stream));
-
- // 7. Let promise be a new promise.
- auto* promise = MakeGarbageCollected<StreamPromiseResolver>(script_state);
-
- // 8. Set stream.[[closeRequest]] to promise.
- stream->SetCloseRequest(promise);
-
- // 9. If stream.[[backpressure]] is true and state is "writable", resolve
- // writer.[[readyPromise]] with undefined.
- if (stream->HasBackpressure() && state == WritableStream::kWritable) {
- writer->ready_promise_->ResolveWithUndefined(script_state);
- }
-
- // 10. Perform ! WritableStreamDefaultControllerClose(
- // stream.[[writableStreamController]]).
- WritableStreamDefaultController::Close(script_state, stream->Controller());
-
- // 11. Return promise.
- return promise->V8Promise(script_state->GetIsolate());
+ // 3. Return ! WritableStreamClose(stream).
+ return WritableStream::Close(script_state, stream);
}
void WritableStreamDefaultWriter::EnsureClosedPromiseRejected(
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 71a102ff4d5..cb8fc99f655 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
@@ -51,18 +51,18 @@ class CORE_EXPORT WritableStreamDefaultWriter final : public ScriptWrappable {
// Methods
// https://streams.spec.whatwg.org/#default-writer-abort
- ScriptPromise abort(ScriptState*);
- ScriptPromise abort(ScriptState*, ScriptValue reason);
+ ScriptPromise abort(ScriptState*, ExceptionState&);
+ ScriptPromise abort(ScriptState*, ScriptValue reason, ExceptionState&);
// https://streams.spec.whatwg.org/#default-writer-close
- ScriptPromise close(ScriptState*);
+ ScriptPromise close(ScriptState*, ExceptionState&);
// https://streams.spec.whatwg.org/#default-writer-release-lock
void releaseLock(ScriptState*);
// https://streams.spec.whatwg.org/#default-writer-write
- ScriptPromise write(ScriptState*);
- ScriptPromise write(ScriptState*, ScriptValue chunk);
+ ScriptPromise write(ScriptState*, ExceptionState&);
+ ScriptPromise write(ScriptState*, ScriptValue chunk, ExceptionState&);
//
// Methods used by WritableStream
diff --git a/chromium/third_party/blink/renderer/core/streams/writable_stream_default_writer.idl b/chromium/third_party/blink/renderer/core/streams/writable_stream_default_writer.idl
index 68cf0dd6a55..0b59cdf3c0d 100644
--- a/chromium/third_party/blink/renderer/core/streams/writable_stream_default_writer.idl
+++ b/chromium/third_party/blink/renderer/core/streams/writable_stream_default_writer.idl
@@ -6,11 +6,9 @@
// https://streams.spec.whatwg.org/#default-writer-class-definition
[
- Exposed=(Window,Worker,Worklet),
- RaisesException=Constructor,
- ConstructorCallWith=ScriptState,
- Constructor(WritableStream stream)
+ Exposed=(Window,Worker,Worklet)
] interface WritableStreamDefaultWriter {
+ [CallWith=ScriptState, RaisesException] constructor(WritableStream stream);
[CallWith=ScriptState, NotEnumerable] readonly attribute Promise<void>
closed;
[RaisesException, CallWith=ScriptState, NotEnumerable] readonly attribute
@@ -18,10 +16,10 @@
[CallWith=ScriptState, NotEnumerable] readonly attribute Promise<void>
ready;
- [CallWith=ScriptState, NotEnumerable] Promise<void> abort(
+ [CallWith=ScriptState, RaisesException, NotEnumerable] Promise<void> abort(
optional any reason);
- [CallWith=ScriptState, NotEnumerable] Promise<void> close();
+ [CallWith=ScriptState, RaisesException, NotEnumerable] Promise<void> close();
[CallWith=ScriptState, NotEnumerable] void releaseLock();
- [CallWith=ScriptState, NotEnumerable] Promise<void> write(
+ [CallWith=ScriptState, RaisesException, NotEnumerable] Promise<void> write(
optional any chunk);
};
diff --git a/chromium/third_party/blink/renderer/core/streams/writable_stream_test.cc b/chromium/third_party/blink/renderer/core/streams/writable_stream_test.cc
index 6c1ff8e1c73..731c0d3d428 100644
--- a/chromium/third_party/blink/renderer/core/streams/writable_stream_test.cc
+++ b/chromium/third_party/blink/renderer/core/streams/writable_stream_test.cc
@@ -86,7 +86,8 @@ underlying_sink)JS";
transferred->getWriter(script_state, ASSERT_NO_EXCEPTION);
auto* isolate = script_state->GetIsolate();
- writer->write(script_state, ScriptValue(isolate, V8String(isolate, "a")));
+ writer->write(script_state, ScriptValue(isolate, V8String(isolate, "a")),
+ ASSERT_NO_EXCEPTION);
// Run the message loop to allow messages to be delivered.
test::RunPendingTasks();
diff --git a/chromium/third_party/blink/renderer/core/style/BUILD.gn b/chromium/third_party/blink/renderer/core/style/BUILD.gn
index 34c2906ad2c..3c0bba4f189 100644
--- a/chromium/third_party/blink/renderer/core/style/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/style/BUILD.gn
@@ -47,7 +47,6 @@ blink_core_sources("rendering") {
"grid_positions_resolver.cc",
"grid_positions_resolver.h",
"grid_track_size.h",
- "intrinsic_length.h",
"member_copy.h",
"named_grid_lines_map.h",
"nine_piece_image.cc",
diff --git a/chromium/third_party/blink/renderer/core/style/OWNERS b/chromium/third_party/blink/renderer/core/style/OWNERS
index d1eb1c37ec5..a007a39a025 100644
--- a/chromium/third_party/blink/renderer/core/style/OWNERS
+++ b/chromium/third_party/blink/renderer/core/style/OWNERS
@@ -2,6 +2,7 @@ alancutter@chromium.org
andruud@chromium.org
ericwilligers@chromium.org
futhark@chromium.org
+xiaochengh@chromium.org
# TEAM: layout-dev@chromium.org
# COMPONENT: Blink>CSS
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 7f502c62f32..10d353555c7 100644
--- a/chromium/third_party/blink/renderer/core/style/computed_style.cc
+++ b/chromium/third_party/blink/renderer/core/style/computed_style.cc
@@ -27,7 +27,9 @@
#include <memory>
#include <utility>
+#include "base/metrics/histogram_functions.h"
#include "base/numerics/clamped_math.h"
+#include "base/numerics/ranges.h"
#include "build/build_config.h"
#include "cc/input/overscroll_behavior.h"
#include "third_party/blink/renderer/core/animation/css/css_animation_data.h"
@@ -74,6 +76,7 @@
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
#include "third_party/blink/renderer/platform/wtf/size_assertions.h"
#include "third_party/blink/renderer/platform/wtf/text/case_map.h"
+#include "ui/base/ui_base_features.h"
namespace blink {
@@ -220,12 +223,9 @@ bool ComputedStyle::NeedsReattachLayoutTree(const ComputedStyle* old_style,
// line-clamping is currently only handled by LayoutDeprecatedFlexibleBox,
// so that if line-clamping changes then the LayoutObject needs to be
// recreated.
- if (RuntimeEnabledFeatures::WebkitBoxLayoutUsesFlexLayoutEnabled() &&
- (new_style->IsDeprecatedWebkitBox()) &&
- (old_style->HasLineClamp() != new_style->HasLineClamp() &&
- new_style->BoxOrient() == EBoxOrient::kVertical)) {
+ if (old_style->IsDeprecatedFlexboxUsingFlexLayout() !=
+ new_style->IsDeprecatedFlexboxUsingFlexLayout())
return true;
- }
// We need to perform a reattach if a "display: layout(foo)" has changed to a
// "display: layout(bar)". This is because one custom layout could be
// registered and the other may not, affecting the box-tree construction.
@@ -301,6 +301,10 @@ ComputedStyle::ComputeDifferenceIgnoringInheritedFirstLineStyle(
if (new_style.HasAnyPseudoElementStyles() ||
old_style.HasAnyPseudoElementStyles())
return Difference::kPseudoElementStyle;
+ if (old_style.Display() != new_style.Display() &&
+ (new_style.Display() == EDisplay::kListItem ||
+ old_style.Display() == EDisplay::kListItem))
+ return Difference::kPseudoElementStyle;
return Difference::kNonInherited;
}
@@ -496,6 +500,20 @@ const ComputedStyle* ComputedStyle::GetCachedPseudoElementStyle(
return nullptr;
}
+bool ComputedStyle::CachedPseudoElementStylesDependOnFontMetrics() const {
+ if (!cached_pseudo_element_styles_ || !cached_pseudo_element_styles_->size())
+ return false;
+
+ DCHECK_EQ(StyleType(), kPseudoIdNone);
+
+ for (const auto& pseudo_style : *cached_pseudo_element_styles_) {
+ if (pseudo_style->DependsOnFontMetrics())
+ return true;
+ }
+
+ return false;
+}
+
const ComputedStyle* ComputedStyle::AddCachedPseudoElementStyle(
scoped_refptr<const ComputedStyle> pseudo) const {
DCHECK(pseudo);
@@ -565,25 +583,25 @@ StyleDifference ComputedStyle::VisualInvalidationDiff(
diff = svg_style_->Diff(*other.svg_style_);
if ((!diff.NeedsReshape() || !diff.NeedsFullLayout() ||
- !diff.NeedsFullPaintInvalidation()) &&
+ !diff.NeedsPaintInvalidation()) &&
DiffNeedsReshapeAndFullLayoutAndPaintInvalidation(*this, other)) {
diff.SetNeedsReshape();
diff.SetNeedsFullLayout();
- diff.SetNeedsPaintInvalidationObject();
+ diff.SetNeedsPaintInvalidation();
}
if ((!diff.NeedsCollectInlines() || !diff.NeedsFullLayout() ||
- !diff.NeedsFullPaintInvalidation()) &&
+ !diff.NeedsPaintInvalidation()) &&
DiffNeedsCollectInlinesAndFullLayoutAndPaintInvalidation(*this, other)) {
diff.SetNeedsCollectInlines();
diff.SetNeedsFullLayout();
- diff.SetNeedsPaintInvalidationObject();
+ diff.SetNeedsPaintInvalidation();
}
- if ((!diff.NeedsFullLayout() || !diff.NeedsFullPaintInvalidation()) &&
+ if ((!diff.NeedsFullLayout() || !diff.NeedsPaintInvalidation()) &&
DiffNeedsFullLayoutAndPaintInvalidation(other)) {
diff.SetNeedsFullLayout();
- diff.SetNeedsPaintInvalidationObject();
+ diff.SetNeedsPaintInvalidation();
}
if (!diff.NeedsFullLayout() && DiffNeedsFullLayout(document, other))
@@ -608,10 +626,7 @@ StyleDifference ComputedStyle::VisualInvalidationDiff(
diff.SetNeedsPositionedMovementLayout();
}
- if (DiffNeedsPaintInvalidationSubtree(other))
- diff.SetNeedsPaintInvalidationSubtree();
- else
- AdjustDiffForNeedsPaintInvalidationObject(other, diff, document);
+ AdjustDiffForNeedsPaintInvalidation(other, diff, document);
if (DiffNeedsVisualRectUpdate(other))
diff.SetNeedsVisualRectUpdate();
@@ -768,30 +783,24 @@ bool ComputedStyle::DiffNeedsFullLayoutForLayoutCustomChild(
return false;
}
-bool ComputedStyle::DiffNeedsPaintInvalidationSubtree(
- const ComputedStyle& other) const {
- return ComputedStyleBase::DiffNeedsPaintInvalidationSubtree(*this, other);
-}
-
-void ComputedStyle::AdjustDiffForNeedsPaintInvalidationObject(
+void ComputedStyle::AdjustDiffForNeedsPaintInvalidation(
const ComputedStyle& other,
StyleDifference& diff,
const Document& document) const {
- if (ComputedStyleBase::DiffNeedsPaintInvalidationObject(*this, other) ||
+ if (ComputedStyleBase::DiffNeedsPaintInvalidation(*this, other) ||
!BorderVisuallyEqual(other) || !RadiiEqual(other))
- diff.SetNeedsPaintInvalidationObject();
+ diff.SetNeedsPaintInvalidation();
AdjustDiffForBackgroundVisuallyEqual(other, diff);
- if (diff.NeedsPaintInvalidationObject())
+ if (diff.NeedsPaintInvalidation())
return;
if (PaintImagesInternal()) {
for (const auto& image : *PaintImagesInternal()) {
DCHECK(image);
- if (DiffNeedsPaintInvalidationObjectForPaintImage(*image, other,
- document)) {
- diff.SetNeedsPaintInvalidationObject();
+ if (DiffNeedsPaintInvalidationForPaintImage(*image, other, document)) {
+ diff.SetNeedsPaintInvalidation();
return;
}
}
@@ -802,7 +811,7 @@ void ComputedStyle::AdjustDiffForBackgroundVisuallyEqual(
const ComputedStyle& other,
StyleDifference& diff) const {
if (BackgroundColorInternal() != other.BackgroundColorInternal()) {
- diff.SetNeedsPaintInvalidationObject();
+ diff.SetNeedsPaintInvalidation();
if (BackgroundColorInternal().HasAlpha() !=
other.BackgroundColorInternal().HasAlpha()) {
diff.SetHasAlphaChanged();
@@ -810,14 +819,14 @@ void ComputedStyle::AdjustDiffForBackgroundVisuallyEqual(
}
}
if (!BackgroundInternal().VisuallyEqual(other.BackgroundInternal())) {
- diff.SetNeedsPaintInvalidationObject();
+ diff.SetNeedsPaintInvalidation();
// Changes of background fill layers, such as images, may have
// changed alpha.
diff.SetHasAlphaChanged();
}
}
-bool ComputedStyle::DiffNeedsPaintInvalidationObjectForPaintImage(
+bool ComputedStyle::DiffNeedsPaintInvalidationForPaintImage(
const StyleImage& image,
const ComputedStyle& other,
const Document& document) const {
@@ -906,14 +915,15 @@ void ComputedStyle::UpdatePropertySpecificDifferences(
diff.SetFilterChanged();
if (ComputedStyleBase::
- UpdatePropertySpecificDifferencesNeedsRecomputeOverflow(*this, other))
- diff.SetNeedsRecomputeOverflow();
+ UpdatePropertySpecificDifferencesNeedsRecomputeVisualOverflow(*this,
+ other))
+ diff.SetNeedsRecomputeVisualOverflow();
if (ComputedStyleBase::UpdatePropertySpecificDifferencesBackdropFilter(*this,
other))
diff.SetBackdropFilterChanged();
- if (!diff.NeedsFullPaintInvalidation() &&
+ if (!diff.NeedsPaintInvalidation() &&
ComputedStyleBase::UpdatePropertySpecificDifferencesTextDecorationOrColor(
*this, other)) {
diff.SetTextDecorationOrColorChanged();
@@ -1020,6 +1030,7 @@ static bool HasPropertyThatCreatesStackingContext(
case CSSPropertyID::kPosition:
case CSSPropertyID::kMixBlendMode:
case CSSPropertyID::kIsolation:
+ case CSSPropertyID::kContain:
return true;
default:
break;
@@ -1316,11 +1327,24 @@ Color ComputedStyle::GetColor() const {
return ColorInternal();
}
void ComputedStyle::SetColor(const Color& v) {
- SetIsColorInternalText(false);
SetColorInternal(v);
}
-void ComputedStyle::ResolveInternalTextColor(const Color& v) {
- SetColorInternal(v);
+
+bool ComputedStyle::SetEffectiveZoom(float f) {
+ // Clamp the effective zoom value to a smaller (but hopeful still large
+ // enough) range, to avoid overflow in derived computations.
+ float clamped_effective_zoom = clampTo<float>(f, 1e-6, 1e6);
+ if (EffectiveZoom() == clamped_effective_zoom)
+ return false;
+ SetInternalEffectiveZoom(clamped_effective_zoom);
+ // Record UMA for the effective zoom in order to assess the relative
+ // importance of sub-pixel behavior, and related features and bugs.
+ // Clamp to a max of 400%, to make the histogram behave better at no
+ // real cost to our understanding of the zooms in use.
+ base::UmaHistogramSparse(
+ "Blink.EffectiveZoom",
+ base::ClampToRange<float>(clamped_effective_zoom * 100, 0, 400));
+ return true;
}
static FloatRoundedRect::Radii CalcRadiiFor(const LengthSize& top_left,
@@ -1334,6 +1358,20 @@ static FloatRoundedRect::Radii CalcRadiiFor(const LengthSize& top_left,
FloatSizeForLengthSize(bottom_right, size));
}
+FloatRoundedRect ComputedStyle::GetBorderFor(
+ const LayoutRect& border_rect) const {
+ FloatRoundedRect rounded_rect((FloatRect(border_rect)));
+ if (HasBorderRadius()) {
+ FloatRoundedRect::Radii radii = CalcRadiiFor(
+ BorderTopLeftRadius(), BorderTopRightRadius(), BorderBottomLeftRadius(),
+ BorderBottomRightRadius(), FloatSize(border_rect.Size()));
+ rounded_rect.IncludeLogicalEdges(radii, IsHorizontalWritingMode(), true,
+ true);
+ rounded_rect.ConstrainRadii();
+ }
+ return rounded_rect;
+}
+
FloatRoundedRect ComputedStyle::GetRoundedBorderFor(
const LayoutRect& border_rect,
bool include_logical_left_edge,
@@ -1351,6 +1389,36 @@ FloatRoundedRect ComputedStyle::GetRoundedBorderFor(
return rounded_rect;
}
+FloatRoundedRect ComputedStyle::GetInnerBorderFor(
+ const LayoutRect& border_rect) const {
+ int left_width = BorderLeftWidth();
+ int right_width = BorderRightWidth();
+ int top_width = BorderTopWidth();
+ int bottom_width = BorderBottomWidth();
+
+ LayoutRectOutsets insets(-top_width, -right_width, -bottom_width,
+ -left_width);
+
+ LayoutRect inner_rect(border_rect);
+ inner_rect.Expand(insets);
+ LayoutSize inner_rect_size = inner_rect.Size();
+ inner_rect_size.ClampNegativeToZero();
+ inner_rect.SetSize(inner_rect_size);
+
+ FloatRoundedRect float_inner_rect((FloatRect(inner_rect)));
+
+ if (HasBorderRadius()) {
+ FloatRoundedRect::Radii radii = GetBorderFor(border_rect).GetRadii();
+
+ // Insets use negative values.
+ radii.Shrink(-insets.Top().ToFloat(), -insets.Bottom().ToFloat(),
+ -insets.Left().ToFloat(), -insets.Right().ToFloat());
+ float_inner_rect.IncludeLogicalEdges(radii, IsHorizontalWritingMode(), true,
+ true);
+ }
+ return float_inner_rect;
+}
+
FloatRoundedRect ComputedStyle::GetRoundedInnerBorderFor(
const LayoutRect& border_rect,
bool include_logical_left_edge,
@@ -1711,11 +1779,9 @@ void ComputedStyle::UpdateFontOrientation() {
FontOrientation orientation = ComputeFontOrientation();
if (GetFontDescription().Orientation() == orientation)
return;
- FontSelector* current_font_selector = GetFont().GetFontSelector();
FontDescription font_description = GetFontDescription();
font_description.SetOrientation(orientation);
SetFontDescription(font_description);
- GetFont().Update(current_font_selector);
}
TextDecoration ComputedStyle::TextDecorationsInEffect() const {
@@ -1891,7 +1957,7 @@ const CSSValue* ComputedStyle::GetVariableValue(
bool ComputedStyle::SetFontDescription(const FontDescription& v) {
if (FontInternal().GetFontDescription() != v) {
- SetFontInternal(Font(v));
+ SetFontInternal(Font(v, FontInternal().GetFontSelector()));
return true;
}
return false;
@@ -1952,30 +2018,15 @@ LayoutUnit ComputedStyle::ComputedLineHeightAsFixed() const {
}
void ComputedStyle::SetWordSpacing(float word_spacing) {
- FontSelector* current_font_selector = GetFont().GetFontSelector();
FontDescription desc(GetFontDescription());
desc.SetWordSpacing(word_spacing);
SetFontDescription(desc);
- GetFont().Update(current_font_selector);
}
void ComputedStyle::SetLetterSpacing(float letter_spacing) {
- FontSelector* current_font_selector = GetFont().GetFontSelector();
FontDescription desc(GetFontDescription());
desc.SetLetterSpacing(letter_spacing);
SetFontDescription(desc);
- GetFont().Update(current_font_selector);
-}
-
-void ComputedStyle::SetFontVariantNumericSpacing(
- FontVariantNumeric::NumericSpacing numeric_spacing) {
- FontSelector* current_font_selector = GetFont().GetFontSelector();
- FontDescription desc(GetFontDescription());
- FontVariantNumeric variant_numeric = desc.VariantNumeric();
- variant_numeric.SetNumericSpacing(numeric_spacing);
- desc.SetVariantNumeric(variant_numeric);
- SetFontDescription(desc);
- GetFont().Update(current_font_selector);
}
void ComputedStyle::SetTextAutosizingMultiplier(float multiplier) {
@@ -1989,7 +2040,6 @@ void ComputedStyle::SetTextAutosizingMultiplier(float multiplier) {
else
size = std::min(kMaximumAllowedFontSize, size);
- FontSelector* current_font_selector = GetFont().GetFontSelector();
FontDescription desc(GetFontDescription());
desc.SetSpecifiedSize(size);
@@ -2000,7 +2050,6 @@ void ComputedStyle::SetTextAutosizingMultiplier(float multiplier) {
desc.SetComputedSize(std::min(kMaximumAllowedFontSize, autosized_font_size));
SetFontDescription(desc);
- GetFont().Update(current_font_selector);
}
void ComputedStyle::AddAppliedTextDecoration(
@@ -2185,13 +2234,18 @@ int ComputedStyle::OutlineOutsetExtent() const {
return 0;
if (OutlineStyleIsAuto()) {
return GraphicsContext::FocusRingOutsetExtent(
- OutlineOffset(), std::ceil(GetOutlineStrokeWidthForFocusRing()),
+ OutlineOffset(), GetDefaultOffsetForFocusRing(),
+ std::ceil(GetOutlineStrokeWidthForFocusRing()),
LayoutTheme::GetTheme().IsFocusRingOutset());
}
return base::ClampAdd(OutlineWidth(), OutlineOffset()).Max(0);
}
float ComputedStyle::GetOutlineStrokeWidthForFocusRing() const {
+ if (::features::IsFormControlsRefreshEnabled() && OutlineStyleIsAuto()) {
+ return std::max(EffectiveZoom(), 3.f);
+ }
+
#if defined(OS_MACOSX)
return OutlineWidth();
#else
@@ -2204,6 +2258,20 @@ float ComputedStyle::GetOutlineStrokeWidthForFocusRing() const {
#endif
}
+int ComputedStyle::GetDefaultOffsetForFocusRing() const {
+ if (!::features::IsFormControlsRefreshEnabled())
+ return 0;
+
+ if (EffectiveAppearance() == kCheckboxPart ||
+ EffectiveAppearance() == kRadioPart) {
+ return 2;
+ } else if (IsLink()) {
+ return 1;
+ }
+
+ return 0;
+}
+
bool ComputedStyle::ColumnRuleEquivalent(
const ComputedStyle& other_style) const {
return ColumnRuleStyle() == other_style.ColumnRuleStyle() &&
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 02cdafc27a3..c15c7b5417f 100644
--- a/chromium/third_party/blink/renderer/core/style/computed_style.h
+++ b/chromium/third_party/blink/renderer/core/style/computed_style.h
@@ -237,6 +237,7 @@ class ComputedStyle : public ComputedStyleBase,
// Access to private Appearance() and HasAppearance().
friend class LayoutTheme;
friend class StyleAdjuster;
+ friend class StyleCascade;
friend class css_longhand::WebkitAppearance;
// Editing has to only reveal unvisited info.
friend class ApplyStyleCommand;
@@ -252,6 +253,8 @@ class ComputedStyle : public ComputedStyleBase,
friend class ColorPropertyFunctions;
// Edits the background for media controls.
friend class StyleAdjuster;
+ // Access to private SetFontInternal().
+ friend class FontBuilder;
// FIXME: When we stop resolving currentColor at style time, these can be
// removed.
@@ -726,8 +729,6 @@ class ComputedStyle : public ComputedStyleBase,
// outline-offset
int OutlineOffset() const {
- if (OutlineStyle() == EBorderStyle::kNone)
- return 0;
return OutlineOffsetInternal();
}
@@ -897,7 +898,7 @@ class ComputedStyle : public ComputedStyleBase,
SetZIndexInternal(0);
}
- bool SetEffectiveZoom(float);
+ CORE_EXPORT bool SetEffectiveZoom(float);
float EffectiveZoom() const;
// -webkit-clip-path
@@ -948,7 +949,6 @@ class ComputedStyle : public ComputedStyleBase,
// color
void SetColor(const Color&);
- void ResolveInternalTextColor(const Color&);
// line-height
Length LineHeight() const;
@@ -1005,6 +1005,15 @@ class ComputedStyle : public ComputedStyleBase,
}
CORE_EXPORT bool SetFontDescription(const FontDescription&);
bool HasIdenticalAscentDescentAndLineGap(const ComputedStyle& other) const;
+ bool HasFontRelativeUnits() const {
+ return HasEmUnits() || HasRemUnits() || HasGlyphRelativeUnits();
+ }
+
+ // If true, the ComputedStyle must be recalculated when fonts are updated.
+ bool DependsOnFontMetrics() const {
+ return HasGlyphRelativeUnits() || HasFontSizeAdjust();
+ }
+ bool CachedPseudoElementStylesDependOnFontMetrics() const;
// font-size
int FontSize() const { return GetFontDescription().ComputedPixelSize(); }
@@ -1075,9 +1084,6 @@ class ComputedStyle : public ComputedStyleBase,
float WordSpacing() const { return GetFontDescription().WordSpacing(); }
void SetWordSpacing(float);
- // font-variant-numeric spacing
- void SetFontVariantNumericSpacing(FontVariantNumeric::NumericSpacing);
-
// orphans
void SetOrphans(int16_t o) { SetOrphansInternal(clampTo<int16_t>(o, 1)); }
@@ -1214,8 +1220,11 @@ class ComputedStyle : public ComputedStyleBase,
}
bool IsDeprecatedFlexboxUsingFlexLayout() const {
return IsDeprecatedWebkitBox() &&
- RuntimeEnabledFeatures::WebkitBoxLayoutUsesFlexLayoutEnabled() &&
- (!HasLineClamp() || BoxOrient() == EBoxOrient::kHorizontal);
+ !IsDeprecatedWebkitBoxWithVerticalLineClamp();
+ }
+ bool IsDeprecatedWebkitBoxWithVerticalLineClamp() const {
+ return IsDeprecatedWebkitBox() && BoxOrient() == EBoxOrient::kVertical &&
+ HasLineClamp();
}
// Variables.
@@ -1340,19 +1349,23 @@ class ComputedStyle : public ComputedStyleBase,
// Grid utility functions.
GridAutoFlow GetGridAutoFlow() const { return GridAutoFlowInternal(); }
bool IsGridAutoFlowDirectionRow() const {
- return (GridAutoFlowInternal() & kInternalAutoFlowDirectionRow) ==
+ return (GridAutoFlowInternal() &
+ static_cast<int>(kInternalAutoFlowDirectionRow)) ==
kInternalAutoFlowDirectionRow;
}
bool IsGridAutoFlowDirectionColumn() const {
- return (GridAutoFlowInternal() & kInternalAutoFlowDirectionColumn) ==
+ return (GridAutoFlowInternal() &
+ static_cast<int>(kInternalAutoFlowDirectionColumn)) ==
kInternalAutoFlowDirectionColumn;
}
bool IsGridAutoFlowAlgorithmSparse() const {
- return (GridAutoFlowInternal() & kInternalAutoFlowAlgorithmSparse) ==
+ return (GridAutoFlowInternal() &
+ static_cast<int>(kInternalAutoFlowAlgorithmSparse)) ==
kInternalAutoFlowAlgorithmSparse;
}
bool IsGridAutoFlowAlgorithmDense() const {
- return (GridAutoFlowInternal() & kInternalAutoFlowAlgorithmDense) ==
+ return (GridAutoFlowInternal() &
+ static_cast<int>(kInternalAutoFlowAlgorithmDense)) ==
kInternalAutoFlowAlgorithmDense;
}
@@ -1934,10 +1947,15 @@ class ComputedStyle : public ComputedStyleBase,
LengthSize(Length::Fixed(s.Width()), Length::Fixed(s.Height())));
}
+ FloatRoundedRect GetBorderFor(const LayoutRect& border_rect) const;
+
FloatRoundedRect GetRoundedBorderFor(
const LayoutRect& border_rect,
bool include_logical_left_edge = true,
bool include_logical_right_edge = true) const;
+
+ FloatRoundedRect GetInnerBorderFor(const LayoutRect& border_rect) const;
+
FloatRoundedRect GetRoundedInnerBorderFor(
const LayoutRect& border_rect,
bool include_logical_left_edge = true,
@@ -1996,6 +2014,7 @@ class ComputedStyle : public ComputedStyleBase,
}
CORE_EXPORT int OutlineOutsetExtent() const;
CORE_EXPORT float GetOutlineStrokeWidthForFocusRing() const;
+ CORE_EXPORT int GetDefaultOffsetForFocusRing() const;
bool HasOutlineWithCurrentColor() const {
return HasOutline() && OutlineColor().IsCurrentColor();
}
@@ -2117,8 +2136,10 @@ class ComputedStyle : public ComputedStyleBase,
bool IsDisplayTableType() const { return IsDisplayTableType(Display()); }
+ bool IsDisplayMathType() const { return IsDisplayMathBox(Display()); }
+
bool BlockifiesChildren() const {
- return IsDisplayFlexibleOrGridBox() || IsDisplayMathBox(Display()) ||
+ return IsDisplayFlexibleOrGridBox() || IsDisplayMathType() ||
IsDisplayLayoutCustomBox() ||
(Display() == EDisplay::kContents && IsInBlockifyingDisplay());
}
@@ -2127,7 +2148,25 @@ class ComputedStyle : public ComputedStyleBase,
bool HasIsolation() const { return Isolation() != EIsolation::kAuto; }
// Content utility functions.
- bool HasContent() const { return GetContentData(); }
+ bool ContentBehavesAsNormal() const {
+ switch (StyleType()) {
+ case kPseudoIdMarker:
+ return !GetContentData();
+ default:
+ return !GetContentData() || GetContentData()->IsNone();
+ }
+ }
+ bool ContentPreventsBoxGeneration() const {
+ switch (StyleType()) {
+ case kPseudoIdBefore:
+ case kPseudoIdAfter:
+ return ContentBehavesAsNormal();
+ case kPseudoIdMarker:
+ return GetContentData() && GetContentData()->IsNone();
+ default:
+ return false;
+ }
+ }
// Cursor utility functions.
CursorList* Cursors() const { return CursorDataInternal().Get(); }
@@ -2514,14 +2553,14 @@ class ComputedStyle : public ComputedStyleBase,
InterpolationQuality GetInterpolationQuality() const;
bool CanGeneratePseudoElement(PseudoId pseudo) const {
- if (!HasPseudoElementStyle(pseudo))
- return false;
if (Display() == EDisplay::kNone)
return false;
if (IsEnsuredInDisplayNone())
return false;
if (pseudo == kPseudoIdMarker)
return Display() == EDisplay::kListItem;
+ if (!HasPseudoElementStyle(pseudo))
+ return false;
if (Display() != EDisplay::kContents)
return true;
// For display: contents elements, we still need to generate ::before and
@@ -2534,26 +2573,32 @@ class ComputedStyle : public ComputedStyleBase,
void LoadDeferredImages(Document&) const;
enum WebColorScheme UsedColorScheme() const {
+ return DarkColorScheme() &&
+ RuntimeEnabledFeatures::CSSColorSchemeUARenderingEnabled()
+ ? WebColorScheme::kDark
+ : WebColorScheme::kLight;
+ }
+
+ enum WebColorScheme UsedColorSchemeForInitialColors() const {
return DarkColorScheme() ? WebColorScheme::kDark : WebColorScheme::kLight;
}
+ Color InitialColorForColorScheme() const {
+ // TODO(crbug.com/1046753, crbug.com/929098): The initial value of the color
+ // property should be canvastext, but since we do not yet ship color-scheme
+ // aware system colors, we use this method instead. This should be replaced
+ // by default_value:"canvastext" in css_properties.json5.
+ return DarkColorScheme() ? Color::kWhite : Color::kBlack;
+ }
+
Color ForcedBackplateColor() const {
- return LayoutTheme::GetTheme().SystemColor(CSSValueID::kWindow,
+ return LayoutTheme::GetTheme().SystemColor(CSSValueID::kCanvas,
WebColorScheme::kLight);
}
- // render-subtree helpers.
- bool RenderSubtreeInvisible() const {
- return static_cast<unsigned>(RenderSubtree()) &
- static_cast<unsigned>(RenderSubtreeFlags::kInvisible);
- }
- bool RenderSubtreeSkipActivation() const {
- return static_cast<unsigned>(RenderSubtree()) &
- static_cast<unsigned>(RenderSubtreeFlags::kSkipActivation);
- }
- bool RenderSubtreeSkipViewportActivation() const {
- return static_cast<unsigned>(RenderSubtree()) &
- static_cast<unsigned>(RenderSubtreeFlags::kSkipViewportActivation);
+ bool GeneratesMarkerImage() const {
+ return Display() == EDisplay::kListItem && ListStyleImage() &&
+ !ListStyleImage()->ErrorOccurred();
}
private:
@@ -2639,6 +2684,7 @@ class ComputedStyle : public ComputedStyleBase,
display == EDisplay::kInlineFlex ||
display == EDisplay::kInlineTable ||
display == EDisplay::kInlineGrid ||
+ display == EDisplay::kInlineMath ||
display == EDisplay::kInlineLayoutCustom;
}
@@ -2820,13 +2866,12 @@ class ComputedStyle : public ComputedStyleBase,
bool DiffNeedsFullLayoutForLayoutCustomChild(
const Document&,
const ComputedStyle& other) const;
- bool DiffNeedsPaintInvalidationSubtree(const ComputedStyle& other) const;
- void AdjustDiffForNeedsPaintInvalidationObject(const ComputedStyle& other,
- StyleDifference&,
- const Document&) const;
- bool DiffNeedsPaintInvalidationObjectForPaintImage(const StyleImage&,
- const ComputedStyle& other,
- const Document&) const;
+ void AdjustDiffForNeedsPaintInvalidation(const ComputedStyle& other,
+ StyleDifference&,
+ const Document&) const;
+ bool DiffNeedsPaintInvalidationForPaintImage(const StyleImage&,
+ const ComputedStyle& other,
+ const Document&) const;
bool DiffNeedsVisualRectUpdate(const ComputedStyle& other) const;
CORE_EXPORT void UpdatePropertySpecificDifferences(const ComputedStyle& other,
StyleDifference&) const;
@@ -2923,16 +2968,6 @@ class ComputedStyle : public ComputedStyleBase,
FRIEND_TEST_ALL_PREFIXES(ComputedStyleTest, CustomPropertiesEqual_Data);
};
-inline bool ComputedStyle::SetEffectiveZoom(float f) {
- // Clamp the effective zoom value to a smaller (but hopeful still large
- // enough) range, to avoid overflow in derived computations.
- float clamped_effective_zoom = clampTo<float>(f, 1e-6, 1e6);
- if (EffectiveZoom() == clamped_effective_zoom)
- return false;
- SetInternalEffectiveZoom(clamped_effective_zoom);
- return true;
-}
-
inline float ComputedStyle::EffectiveZoom() const {
return InternalEffectiveZoom();
}
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 ab01fcddd94..d7a8d8cafc8 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
@@ -29,6 +29,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_COMPUTED_STYLE_CONSTANTS_H_
#include <cstddef>
+#include <cstdint>
#include "third_party/blink/renderer/core/style/computed_style_base_constants.h"
namespace blink {
@@ -50,7 +51,7 @@ inline bool EnumHasFlags(Enum v, Enum mask) {
enum class BoxSide : unsigned { kTop, kRight, kBottom, kLeft };
// Static pseudo styles. Dynamic ones are produced on the fly.
-enum PseudoId {
+enum PseudoId : uint8_t {
// The order must be NOP ID, public IDs, and then internal IDs.
// If you add or remove a public ID, you must update the field_size of
// "PseudoBits" in computed_style_extra_fields.json5.
@@ -76,10 +77,6 @@ enum PseudoId {
kAfterLastInternalPseudoId,
kFirstPublicPseudoId = kPseudoIdFirstLine,
kFirstInternalPseudoId = kPseudoIdFirstLineInherited,
- kElementPseudoIdMask = (1 << (kPseudoIdBefore - kFirstPublicPseudoId)) |
- (1 << (kPseudoIdAfter - kFirstPublicPseudoId)) |
- (1 << (kPseudoIdMarker - kFirstPublicPseudoId)) |
- (1 << (kPseudoIdBackdrop - kFirstPublicPseudoId))
};
enum class OutlineIsAuto : bool { kOff = false, kOn = true };
@@ -155,14 +152,14 @@ enum InternalGridAutoFlowDirection {
};
enum GridAutoFlow {
- kAutoFlowRow =
- kInternalAutoFlowAlgorithmSparse | kInternalAutoFlowDirectionRow,
- kAutoFlowColumn =
- kInternalAutoFlowAlgorithmSparse | kInternalAutoFlowDirectionColumn,
+ kAutoFlowRow = int(kInternalAutoFlowAlgorithmSparse) |
+ int(kInternalAutoFlowDirectionRow),
+ kAutoFlowColumn = int(kInternalAutoFlowAlgorithmSparse) |
+ int(kInternalAutoFlowDirectionColumn),
kAutoFlowRowDense =
- kInternalAutoFlowAlgorithmDense | kInternalAutoFlowDirectionRow,
- kAutoFlowColumnDense =
- kInternalAutoFlowAlgorithmDense | kInternalAutoFlowDirectionColumn
+ int(kInternalAutoFlowAlgorithmDense) | int(kInternalAutoFlowDirectionRow),
+ kAutoFlowColumnDense = int(kInternalAutoFlowAlgorithmDense) |
+ int(kInternalAutoFlowDirectionColumn)
};
static const size_t kContainmentBits = 4;
@@ -182,12 +179,13 @@ inline Containment& operator|=(Containment& a, Containment b) {
return a = a | b;
}
-static const size_t kTextUnderlinePositionBits = 3;
+static const size_t kTextUnderlinePositionBits = 4;
enum TextUnderlinePosition {
kTextUnderlinePositionAuto = 0x0,
- kTextUnderlinePositionUnder = 0x1,
- kTextUnderlinePositionLeft = 0x2,
- kTextUnderlinePositionRight = 0x4
+ kTextUnderlinePositionFromFont = 0x1,
+ kTextUnderlinePositionUnder = 0x2,
+ kTextUnderlinePositionLeft = 0x4,
+ kTextUnderlinePositionRight = 0x8
};
inline TextUnderlinePosition operator|(TextUnderlinePosition a,
TextUnderlinePosition b) {
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 0c9105a18b6..cd6337fead7 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
@@ -35,7 +35,7 @@
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",
- "intrinsic-width", "intrinsic-height"],
+ "contain-intrinsic-size"],
methods_to_diff: [
{
method: "GetPosition()",
@@ -81,9 +81,7 @@
{
name: "DiffNeedsFullLayoutAndPaintInvalidation",
fields_to_diff: ["padding-top", "padding-left", "padding-right",
- "padding-bottom", "-webkit-appearance",
- "-webkit-margin-before-collapse",
- "-webkit-margin-after-collapse", "-webkit-line-clamp",
+ "padding-bottom", "-webkit-appearance", "-webkit-line-clamp",
"text-overflow", "shape-margin", "order", "-webkit-highlight",
"text-indent", "text-align-last", "TextIndentLine", "-internal-effective-zoom",
"word-break", "overflow-wrap", "-webkit-line-break",
@@ -100,7 +98,8 @@
"NamedGridColumnLines", "NamedGridRowLines", "OrderedNamedGridColumnLines",
"OrderedNamedGridRowLines", "AutoRepeatNamedGridColumnLines",
"AutoRepeatNamedGridRowLines", "AutoRepeatOrderedNamedGridColumnLines",
- "AutoRepeatOrderedNamedGridRowLines", "NamedGridArea", "grid-auto-rows",
+ "AutoRepeatOrderedNamedGridRowLines", "ImplicitNamedGridColumnLines",
+ "ImplicitNamedGridRowLines", "NamedGridArea", "grid-auto-rows",
"grid-template-rows", "grid-template-columns", "grid-auto-columns", "row-gap",
"NamedGridAreaRowCount", "NamedGridAreaColumnCount",
"GridAutoRepeatColumns", "GridAutoRepeatRows", "GridAutoRepeatColumnsInsertionPoint",
@@ -233,7 +232,7 @@
fields_to_diff: ["width", "min-width", "max-width", "height", "min-height",
"max-height", "VerticalAlignLength", "box-sizing", "align-content",
"align-items", "align-self", "justify-content", "justify-items",
- "justify-self", "contain", "intrinsic-width", "intrinsic-height"],
+ "justify-self", "contain", "contain-intrinsic-size", "aspect-ratio"],
methods_to_diff: [
{
method: "VerticalAlign()",
@@ -246,13 +245,10 @@
]
},
{
- name: "DiffNeedsPaintInvalidationSubtree",
- fields_to_diff: ["mix-blend-mode", "isolation", "Mask", "MaskBoxImage"],
- },
- {
- name: "DiffNeedsPaintInvalidationObject",
+ name: "DiffNeedsPaintInvalidation",
fields_to_diff: ["-webkit-user-modify", "user-select", "image-rendering",
- "-webkit-user-drag", "object-fit", "object-position"],
+ "-webkit-user-drag", "object-fit", "object-position",
+ "mix-blend-mode", "isolation", "Mask", "MaskBoxImage"],
methods_to_diff: [
{
method: "Visibility()",
@@ -390,7 +386,7 @@
fields_to_diff: ["Mask", "MaskBoxImage"],
},
{
- name: "UpdatePropertySpecificDifferencesNeedsRecomputeOverflow",
+ name: "UpdatePropertySpecificDifferencesNeedsRecomputeVisualOverflow",
predicates_to_test: [
{
predicate: "a.BoxShadowDataEquivalent(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 42efd588e66..9327fd02612 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
@@ -190,6 +190,12 @@
default_value: "false",
custom_compare: true,
},
+ {
+ name: "HasEmUnits",
+ field_template: "monotonic_flag",
+ default_value: "false",
+ custom_compare: true,
+ },
// Whether we used a length unit that must be resolved against the measure
// of a certain glyph in some font.
{
@@ -501,7 +507,7 @@
include_paths: ["third_party/blink/renderer/platform/graphics/touch_action.h"],
type_name: "TouchAction",
field_size: 6,
- default_value: "TouchAction::kTouchActionAuto",
+ default_value: "TouchAction::kAuto",
field_group: "*",
computed_style_custom_functions: ["getter", "setter"],
},
@@ -657,10 +663,12 @@
},
{
name: "PageSizeType",
- field_template: "keyword",
- keywords: ["auto", "landscape", "portrait", "resolved"],
+ field_template: "primitive",
field_group: "*",
- default_value: "auto",
+ type_name: "PageSizeType",
+ field_size: 2,
+ default_value: "PageSizeType::kAuto",
+ include_paths: ["third_party/blink/public/common/css/page_size_type.h"],
},
{
name: "HasCurrentOpacityAnimation",
@@ -879,6 +887,22 @@
include_paths: ["third_party/blink/renderer/core/style/ordered_named_grid_lines.h"],
},
{
+ name: "ImplicitNamedGridColumnLines",
+ field_template: "external",
+ type_name: "NamedGridLinesMap",
+ field_group: "*->grid",
+ default_value: "NamedGridLinesMap()",
+ include_paths: ["third_party/blink/renderer/core/style/named_grid_lines_map.h"],
+ },
+ {
+ name: "ImplicitNamedGridRowLines",
+ field_template: "external",
+ type_name: "NamedGridLinesMap",
+ field_group: "*->grid",
+ default_value: "NamedGridLinesMap()",
+ include_paths: ["third_party/blink/renderer/core/style/named_grid_lines_map.h"],
+ },
+ {
name: "NamedGridArea",
field_template: "external",
type_name: "NamedGridAreaMap",
@@ -978,14 +1002,6 @@
inherited: true,
},
{
- name: "IsColorInternalText",
- inherited: true,
- field_template: "primitive",
- type_name: "bool",
- field_group: "inherited",
- default_value: "false",
- },
- {
name: "IsInBlockifyingDisplay",
field_template: "monotonic_flag",
default_value: "false",
@@ -1036,5 +1052,41 @@
custom_compare: true,
inherited: true,
},
+ {
+ name: "IsInsideListElement",
+ field_template: "monotonic_flag",
+ default_value: "false",
+ custom_compare: true,
+ inherited: true,
+ },
+
+ // This field disables the 'overflow' check in |LayoutBlock::
+ // InlineBlockBaseline()|. For 'inline-block', CSS says that the baseline
+ // is the bottom margin edge if 'overflow' is not visible. But some
+ // elements want to ignore this condition.
+ {
+ name: "ShouldIgnoreOverflowPropertyForInlineBlockBaseline",
+ field_template: "monotonic_flag",
+ default_value: "false",
+ inherited: false,
+ },
+ {
+ name: "MathBaseline",
+ field_template: "external",
+ default_value: "Length()",
+ include_paths: ["third_party/blink/renderer/platform/geometry/length.h"],
+ type_name: "Length",
+ field_group: "*",
+ getter: "GetMathBaseline",
+ },
+ {
+ name: "MathFractionBarThickness",
+ field_template: "external",
+ default_value: "Length()",
+ include_paths: ["third_party/blink/renderer/platform/geometry/length.h"],
+ type_name: "Length",
+ field_group: "*",
+ getter: "GetMathFractionBarThickness",
+ },
],
}
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 954b2cb3629..f20076456e0 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
@@ -9,6 +9,8 @@
#include "third_party/blink/renderer/core/css/css_font_selector.h"
#include "third_party/blink/renderer/core/css/css_gradient_value.h"
#include "third_party/blink/renderer/core/css/css_identifier_value.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_test_helpers.h"
#include "third_party/blink/renderer/core/css/css_value_list.h"
@@ -27,6 +29,7 @@
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
+#include "ui/base/ui_base_features.h"
namespace blink {
@@ -69,24 +72,32 @@ TEST(ComputedStyleTest, ClipPathEqual) {
TEST(ComputedStyleTest, FocusRingWidth) {
scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
- style->SetEffectiveZoom(3.5);
- style->SetOutlineStyle(EBorderStyle::kSolid);
+ if (::features::IsFormControlsRefreshEnabled()) {
+ style->SetOutlineStyleIsAuto(static_cast<bool>(OutlineIsAuto::kOn));
+ EXPECT_EQ(3, style->GetOutlineStrokeWidthForFocusRing());
+ style->SetEffectiveZoom(3.5);
+ style->SetOutlineWidth(4);
+ EXPECT_EQ(3.5, style->GetOutlineStrokeWidthForFocusRing());
+ } else {
+ style->SetEffectiveZoom(3.5);
+ style->SetOutlineStyle(EBorderStyle::kSolid);
#if defined(OS_MACOSX)
- EXPECT_EQ(3, style->GetOutlineStrokeWidthForFocusRing());
+ EXPECT_EQ(3, style->GetOutlineStrokeWidthForFocusRing());
#else
- style->SetOutlineStyleIsAuto(static_cast<bool>(OutlineIsAuto::kOn));
- static uint16_t outline_width = 4;
- style->SetOutlineWidth(outline_width);
-
- double expected_width =
- LayoutTheme::GetTheme().IsFocusRingOutset() ? outline_width : 3.5;
- EXPECT_EQ(expected_width, style->GetOutlineStrokeWidthForFocusRing());
-
- expected_width =
- LayoutTheme::GetTheme().IsFocusRingOutset() ? outline_width : 1.0;
- style->SetEffectiveZoom(0.5);
- EXPECT_EQ(expected_width, style->GetOutlineStrokeWidthForFocusRing());
+ style->SetOutlineStyleIsAuto(static_cast<bool>(OutlineIsAuto::kOn));
+ static uint16_t outline_width = 4;
+ style->SetOutlineWidth(outline_width);
+
+ double expected_width =
+ LayoutTheme::GetTheme().IsFocusRingOutset() ? outline_width : 3.5;
+ EXPECT_EQ(expected_width, style->GetOutlineStrokeWidthForFocusRing());
+
+ expected_width =
+ LayoutTheme::GetTheme().IsFocusRingOutset() ? outline_width : 1.0;
+ style->SetEffectiveZoom(0.5);
+ EXPECT_EQ(expected_width, style->GetOutlineStrokeWidthForFocusRing());
#endif
+ }
}
TEST(ComputedStyleTest, FocusRingOutset) {
@@ -94,11 +105,17 @@ TEST(ComputedStyleTest, FocusRingOutset) {
style->SetOutlineStyle(EBorderStyle::kSolid);
style->SetOutlineStyleIsAuto(static_cast<bool>(OutlineIsAuto::kOn));
style->SetEffectiveZoom(4.75);
+ if (::features::IsFormControlsRefreshEnabled()) {
+ EXPECT_EQ(4, style->OutlineOutsetExtent());
+ style->SetEffectiveAppearance(kRadioPart);
+ EXPECT_EQ(6, style->OutlineOutsetExtent());
+ } else {
#if defined(OS_MACOSX)
- EXPECT_EQ(4, style->OutlineOutsetExtent());
+ EXPECT_EQ(4, style->OutlineOutsetExtent());
#else
- EXPECT_EQ(3, style->OutlineOutsetExtent());
+ EXPECT_EQ(3, style->OutlineOutsetExtent());
#endif
+ }
}
TEST(ComputedStyleTest, SVGStackingContext) {
@@ -449,9 +466,9 @@ TEST(ComputedStyleTest, AnimationFlags) {
}
TEST(ComputedStyleTest, CustomPropertiesEqual_Values) {
- auto* document = MakeGarbageCollected<Document>();
- css_test_helpers::RegisterProperty(*document, "--x", "<length>", "0px",
- false);
+ auto dummy = std::make_unique<DummyPageHolder>(IntSize(0, 0));
+ css_test_helpers::RegisterProperty(dummy->GetDocument(), "--x", "<length>",
+ "0px", false);
scoped_refptr<ComputedStyle> style1 = ComputedStyle::Create();
scoped_refptr<ComputedStyle> style2 = ComputedStyle::Create();
@@ -479,9 +496,9 @@ TEST(ComputedStyleTest, CustomPropertiesEqual_Values) {
}
TEST(ComputedStyleTest, CustomPropertiesEqual_Data) {
- auto* document = MakeGarbageCollected<Document>();
- css_test_helpers::RegisterProperty(*document, "--x", "<length>", "0px",
- false);
+ auto dummy = std::make_unique<DummyPageHolder>(IntSize(0, 0));
+ css_test_helpers::RegisterProperty(dummy->GetDocument(), "--x", "<length>",
+ "0px", false);
scoped_refptr<ComputedStyle> style1 = ComputedStyle::Create();
scoped_refptr<ComputedStyle> style2 = ComputedStyle::Create();
@@ -508,14 +525,14 @@ TEST(ComputedStyleTest, CustomPropertiesEqual_Data) {
TEST(ComputedStyleTest, ApplyColorSchemeLightOnDark) {
ScopedCSSColorSchemeForTest scoped_property_enabled(true);
+ ScopedCSSColorSchemeUARenderingForTest scoped_ua_enabled(true);
std::unique_ptr<DummyPageHolder> dummy_page_holder_ =
std::make_unique<DummyPageHolder>(IntSize(0, 0), nullptr);
const ComputedStyle* initial = &ComputedStyle::InitialStyle();
- ColorSchemeHelper color_scheme_helper;
- color_scheme_helper.SetPreferredColorScheme(dummy_page_holder_->GetDocument(),
- PreferredColorScheme::kDark);
+ ColorSchemeHelper color_scheme_helper(dummy_page_holder_->GetDocument());
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kDark);
StyleResolverState state(dummy_page_holder_->GetDocument(),
*dummy_page_holder_->GetDocument().documentElement(),
initial, initial);
@@ -539,7 +556,10 @@ TEST(ComputedStyleTest, ApplyColorSchemeLightOnDark) {
}
TEST(ComputedStyleTest, ApplyInternalLightDarkColor) {
+ using css_test_helpers::ParseDeclarationBlock;
+
ScopedCSSColorSchemeForTest scoped_property_enabled(true);
+ ScopedCSSColorSchemeUARenderingForTest scoped_ua_enabled(true);
std::unique_ptr<DummyPageHolder> dummy_page_holder_ =
std::make_unique<DummyPageHolder>(IntSize(0, 0), nullptr);
@@ -551,9 +571,8 @@ TEST(ComputedStyleTest, ApplyInternalLightDarkColor) {
CSSPropertyID::kColor, "-internal-light-dark-color(black, white)",
ua_context);
- ColorSchemeHelper color_scheme_helper;
- color_scheme_helper.SetPreferredColorScheme(dummy_page_holder_->GetDocument(),
- PreferredColorScheme::kDark);
+ ColorSchemeHelper color_scheme_helper(dummy_page_holder_->GetDocument());
+ color_scheme_helper.SetPreferredColorScheme(PreferredColorScheme::kDark);
StyleResolverState state(dummy_page_holder_->GetDocument(),
*dummy_page_holder_->GetDocument().documentElement(),
initial, initial);
@@ -570,22 +589,77 @@ TEST(ComputedStyleTest, ApplyInternalLightDarkColor) {
CSSValueList* light_value = CSSValueList::CreateSpaceSeparated();
light_value->Append(*CSSIdentifierValue::Create(CSSValueID::kLight));
- CSSPropertyRef scheme_property("color-scheme", state.GetDocument());
- CSSPropertyRef color_property("color", state.GetDocument());
+ {
+ ScopedCSSCascadeForTest scoped_cascade_enabled(false);
- To<Longhand>(color_property.GetProperty())
- .ApplyValue(state, *internal_light_dark);
- To<Longhand>(scheme_property.GetProperty()).ApplyValue(state, *dark_value);
- if (!RuntimeEnabledFeatures::CSSCascadeEnabled())
+ To<Longhand>(GetCSSPropertyColor()).ApplyValue(state, *internal_light_dark);
+ To<Longhand>(GetCSSPropertyColorScheme()).ApplyValue(state, *dark_value);
resolver.ApplyCascadedColorValue(state);
- EXPECT_EQ(Color::kWhite, style->VisitedDependentColor(GetCSSPropertyColor()));
+ EXPECT_EQ(Color::kWhite,
+ style->VisitedDependentColor(GetCSSPropertyColor()));
- To<Longhand>(color_property.GetProperty())
- .ApplyValue(state, *internal_light_dark);
- To<Longhand>(scheme_property.GetProperty()).ApplyValue(state, *light_value);
- if (!RuntimeEnabledFeatures::CSSCascadeEnabled())
+ To<Longhand>(GetCSSPropertyColor()).ApplyValue(state, *internal_light_dark);
+ To<Longhand>(GetCSSPropertyColorScheme()).ApplyValue(state, *light_value);
resolver.ApplyCascadedColorValue(state);
- EXPECT_EQ(Color::kBlack, style->VisitedDependentColor(GetCSSPropertyColor()));
+ EXPECT_EQ(Color::kBlack,
+ style->VisitedDependentColor(GetCSSPropertyColor()));
+ }
+
+ {
+ ScopedCSSCascadeForTest scoped_cascade_enabled(true);
+
+ auto* color_declaration =
+ ParseDeclarationBlock("color:-internal-light-dark-color(black, white)");
+ auto* dark_declaration = ParseDeclarationBlock("color-scheme:dark");
+ auto* light_declaration = ParseDeclarationBlock("color-scheme:light");
+
+ StyleCascade cascade1(state);
+ cascade1.MutableMatchResult().AddMatchedProperties(color_declaration);
+ cascade1.MutableMatchResult().AddMatchedProperties(dark_declaration);
+ cascade1.Apply();
+ EXPECT_EQ(Color::kWhite,
+ style->VisitedDependentColor(GetCSSPropertyColor()));
+
+ StyleCascade cascade2(state);
+ cascade2.MutableMatchResult().AddMatchedProperties(color_declaration);
+ cascade2.MutableMatchResult().AddMatchedProperties(light_declaration);
+ cascade2.Apply();
+ EXPECT_EQ(Color::kBlack,
+ style->VisitedDependentColor(GetCSSPropertyColor()));
+ }
+}
+
+TEST(ComputedStyleTest, StrokeWidthZoomAndCalc) {
+ std::unique_ptr<DummyPageHolder> dummy_page_holder_ =
+ std::make_unique<DummyPageHolder>(IntSize(0, 0), nullptr);
+
+ const ComputedStyle* initial = &ComputedStyle::InitialStyle();
+
+ StyleResolverState state(dummy_page_holder_->GetDocument(),
+ *dummy_page_holder_->GetDocument().documentElement(),
+ initial, initial);
+
+ scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
+ style->SetEffectiveZoom(1.5);
+ state.SetStyle(style);
+
+ auto* calc_value =
+ CSSMathFunctionValue::Create(CSSMathExpressionNumericLiteral::Create(
+ CSSNumericLiteralValue::Create(10,
+ CSSPrimitiveValue::UnitType::kNumber),
+ true));
+
+ To<Longhand>(GetCSSPropertyStrokeWidth()).ApplyValue(state, *calc_value);
+ auto* computed_value =
+ To<Longhand>(GetCSSPropertyStrokeWidth())
+ .CSSValueFromComputedStyleInternal(*style, style->SvgStyle(),
+ nullptr /* layout_object */,
+ false /* allow_visited_style */);
+ ASSERT_TRUE(computed_value);
+ auto* numeric_value = DynamicTo<CSSNumericLiteralValue>(computed_value);
+ ASSERT_TRUE(numeric_value);
+ EXPECT_TRUE(numeric_value->IsPx());
+ EXPECT_EQ(10, numeric_value->DoubleValue());
}
} // namespace blink
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 549b833cc1d..3ef58f358b1 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(blink::Visitor* visitor) {
+void ContentData::Trace(Visitor* visitor) {
visitor->Trace(next_);
}
@@ -67,7 +67,7 @@ LayoutObject* ImageContentData::CreateLayoutObject(
return image;
}
-void ImageContentData::Trace(blink::Visitor* visitor) {
+void ImageContentData::Trace(Visitor* visitor) {
visitor->Trace(image_);
ContentData::Trace(visitor);
}
@@ -110,4 +110,12 @@ LayoutObject* QuoteContentData::CreateLayoutObject(
return layout_object;
}
+LayoutObject* NoneContentData::CreateLayoutObject(
+ PseudoElement& pseudo,
+ const ComputedStyle& pseudo_style,
+ LegacyLayout) const {
+ NOTREACHED();
+ return nullptr;
+}
+
} // namespace blink
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 60ec585b86c..c381a50dbbe 100644
--- a/chromium/third_party/blink/renderer/core/style/content_data.h
+++ b/chromium/third_party/blink/renderer/core/style/content_data.h
@@ -50,6 +50,7 @@ class ContentData : public GarbageCollected<ContentData> {
virtual bool IsQuote() const { return false; }
virtual bool IsText() const { return false; }
virtual bool IsAltText() const { return false; }
+ virtual bool IsNone() const { return false; }
virtual LayoutObject* CreateLayoutObject(PseudoElement&,
const ComputedStyle&,
@@ -58,11 +59,15 @@ class ContentData : public GarbageCollected<ContentData> {
virtual ContentData* Clone() const;
ContentData* Next() const { return next_.Get(); }
- void SetNext(ContentData* next) { next_ = next; }
+ void SetNext(ContentData* next) {
+ DCHECK(!IsNone());
+ DCHECK(!next || !next->IsNone());
+ next_ = next;
+ }
virtual bool Equals(const ContentData&) const = 0;
- virtual void Trace(blink::Visitor*);
+ virtual void Trace(Visitor*);
private:
virtual ContentData* CloneInternal() const = 0;
@@ -97,7 +102,7 @@ class ImageContentData final : public ContentData {
*GetImage();
}
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
ContentData* CloneInternal() const override {
@@ -258,6 +263,30 @@ struct DowncastTraits<QuoteContentData> {
}
};
+class NoneContentData final : public ContentData {
+ friend class ContentData;
+
+ public:
+ explicit NoneContentData() {}
+
+ bool IsNone() const override { return true; }
+ LayoutObject* CreateLayoutObject(PseudoElement&,
+ const ComputedStyle&,
+ LegacyLayout) const override;
+
+ bool Equals(const ContentData& data) const override { return data.IsNone(); }
+
+ private:
+ ContentData* CloneInternal() const override {
+ return MakeGarbageCollected<NoneContentData>();
+ }
+};
+
+template <>
+struct DowncastTraits<NoneContentData> {
+ static bool AllowFrom(const ContentData& content) { return content.IsNone(); }
+};
+
inline bool operator==(const ContentData& a, const ContentData& b) {
const ContentData* ptr_a = &a;
const ContentData* ptr_b = &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 6556ff5ba2d..fcd07de43d6 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(blink::Visitor* visitor) { visitor->Trace(image_); }
+ void Trace(Visitor* visitor) { 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 55f513f1e4b..1b0c37c0e6f 100644
--- a/chromium/third_party/blink/renderer/core/style/fill_layer.cc
+++ b/chromium/third_party/blink/renderer/core/style/fill_layer.cc
@@ -395,8 +395,12 @@ bool FillLayer::ImageIsOpaque(const Document& document,
const ComputedStyle& style) const {
// Returns whether we have an image that will cover the content below it when
// composite_ == CompositeSourceOver && blend_mode_ == BlendMode::kNormal.
+ // Note that it doesn't matter what orientation we use because we are only
+ // checking for IsEmpty.
return image_->KnownToBeOpaque(document, style) &&
- !image_->ImageSize(document, style.EffectiveZoom(), LayoutSize())
+ !image_
+ ->ImageSize(document, style.EffectiveZoom(), LayoutSize(),
+ kRespectImageOrientation)
.IsEmpty();
}
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 9c90369ed50..a3c22480f25 100644
--- a/chromium/third_party/blink/renderer/core/style/filter_operation.cc
+++ b/chromium/third_party/blink/renderer/core/style/filter_operation.cc
@@ -44,7 +44,7 @@ FilterOperation* FilterOperation::Blend(const FilterOperation* from,
return from->Blend(nullptr, 1 - progress);
}
-void ReferenceFilterOperation::Trace(blink::Visitor* visitor) {
+void ReferenceFilterOperation::Trace(Visitor* visitor) {
visitor->Trace(resource_);
visitor->Trace(filter_);
FilterOperation::Trace(visitor);
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 a5360d94eda..78dace4e737 100644
--- a/chromium/third_party/blink/renderer/core/style/filter_operation.h
+++ b/chromium/third_party/blink/renderer/core/style/filter_operation.h
@@ -87,7 +87,7 @@ class CORE_EXPORT FilterOperation : public GarbageCollected<FilterOperation> {
}
virtual ~FilterOperation() = default;
- virtual void Trace(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
static FilterOperation* Blend(const FilterOperation* from,
const FilterOperation* to,
@@ -140,7 +140,7 @@ class CORE_EXPORT ReferenceFilterOperation : public FilterOperation {
void AddClient(SVGResourceClient&);
void RemoveClient(SVGResourceClient&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
FilterOperation* Blend(const FilterOperation* from,
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 719d99447cc..e0f03d3a438 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(blink::Visitor* visitor) {
+void FilterOperations::Trace(Visitor* visitor) {
visitor->Trace(operations_);
}
@@ -70,16 +70,6 @@ bool FilterOperations::CanInterpolateWith(const FilterOperations& other) const {
return true;
}
-bool FilterOperations::HasBlurOrReferenceFilter() const {
- for (const auto& operation : operations_) {
- FilterOperation::OperationType type = operation->GetType();
- if (type == FilterOperation::BLUR || type == FilterOperation::REFERENCE) {
- return true;
- }
- }
- return false;
-}
-
FloatRect FilterOperations::MapRect(const FloatRect& rect) const {
auto accumulate_mapped_rect = [](const FloatRect& rect,
const Member<FilterOperation>& op) {
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 6b90e1beffa..7e1f4f20a02 100644
--- a/chromium/third_party/blink/renderer/core/style/filter_operations.h
+++ b/chromium/third_party/blink/renderer/core/style/filter_operations.h
@@ -70,12 +70,10 @@ class CORE_EXPORT FilterOperations {
bool HasFilterThatAffectsOpacity() const;
bool HasFilterThatMovesPixels() const;
- bool HasBlurOrReferenceFilter() const;
-
void AddClient(SVGResourceClient&) const;
void RemoveClient(SVGResourceClient&) const;
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
FilterOperationVector operations_;
@@ -91,7 +89,7 @@ class FilterOperationsWrapper
const FilterOperations& Operations() const { return operations_; }
- void Trace(blink::Visitor* visitor) { visitor->Trace(operations_); }
+ void Trace(Visitor* visitor) { visitor->Trace(operations_); }
private:
FilterOperations operations_;
diff --git a/chromium/third_party/blink/renderer/core/style/grid_positions_resolver.cc b/chromium/third_party/blink/renderer/core/style/grid_positions_resolver.cc
index 2d95286bbff..5b373f59ad4 100644
--- a/chromium/third_party/blink/renderer/core/style/grid_positions_resolver.cc
+++ b/chromium/third_party/blink/renderer/core/style/grid_positions_resolver.cc
@@ -38,6 +38,9 @@ NamedLineCollection::NamedLineCollection(
const NamedGridLinesMap& auto_repeat_grid_line_names =
is_row_axis ? grid_container_style.AutoRepeatNamedGridColumnLines()
: grid_container_style.AutoRepeatNamedGridRowLines();
+ const NamedGridLinesMap& implicit_grid_line_names =
+ is_row_axis ? grid_container_style.ImplicitNamedGridColumnLines()
+ : grid_container_style.ImplicitNamedGridRowLines();
if (!grid_line_names.IsEmpty()) {
auto it = grid_line_names.find(named_line);
@@ -50,6 +53,12 @@ NamedLineCollection::NamedLineCollection(
it == auto_repeat_grid_line_names.end() ? nullptr : &it->value;
}
+ if (!implicit_grid_line_names.IsEmpty()) {
+ auto it = implicit_grid_line_names.find(named_line);
+ implicit_named_lines_indexes_ =
+ it == implicit_grid_line_names.end() ? nullptr : &it->value;
+ }
+
insertion_point_ =
is_row_axis ? grid_container_style.GridAutoRepeatColumnsInsertionPoint()
: grid_container_style.GridAutoRepeatRowsInsertionPoint();
@@ -59,74 +68,88 @@ NamedLineCollection::NamedLineCollection(
: grid_container_style.GridAutoRepeatRows().size();
}
-bool NamedLineCollection::HasNamedLines() {
+bool NamedLineCollection::HasExplicitNamedLines() {
return named_lines_indexes_ || auto_repeat_named_lines_indexes_;
}
-size_t NamedLineCollection::Find(size_t line) {
- if (line > last_line_)
- return kNotFound;
-
- if (!auto_repeat_named_lines_indexes_ || line < insertion_point_)
- return named_lines_indexes_ ? named_lines_indexes_->Find(line) : kNotFound;
-
- if (line <= (insertion_point_ + auto_repeat_total_tracks_)) {
- size_t local_index = line - insertion_point_;
-
- size_t index_in_first_repetition =
- local_index % auto_repeat_track_list_length_;
- if (index_in_first_repetition)
- return auto_repeat_named_lines_indexes_->Find(index_in_first_repetition);
-
- // The line names defined in the last line are also present in the first
- // line of the next repetition (if any). Same for the line names defined in
- // the first line.
- if (local_index == auto_repeat_total_tracks_)
- return auto_repeat_named_lines_indexes_->Find(
- auto_repeat_track_list_length_);
- size_t position =
- auto_repeat_named_lines_indexes_->Find(static_cast<size_t>(0));
- if (position != kNotFound)
- return position;
- return local_index == 0 ? kNotFound
- : auto_repeat_named_lines_indexes_->Find(
- auto_repeat_track_list_length_);
- }
-
- return named_lines_indexes_ ? named_lines_indexes_->Find(
- line - (auto_repeat_total_tracks_ - 1))
- : kNotFound;
+bool NamedLineCollection::HasNamedLines() {
+ return HasExplicitNamedLines() || implicit_named_lines_indexes_;
}
bool NamedLineCollection::Contains(size_t line) {
CHECK(HasNamedLines());
- return Find(line) != kNotFound;
+
+ if (line > last_line_)
+ return false;
+
+ auto find = [](const Vector<size_t>* indexes, size_t line) {
+ return indexes && indexes->Find(line) != kNotFound;
+ };
+
+ if (find(implicit_named_lines_indexes_, line))
+ return true;
+
+ if (auto_repeat_track_list_length_ == 0LU || line < insertion_point_)
+ return find(named_lines_indexes_, line);
+
+ DCHECK(auto_repeat_total_tracks_);
+
+ if (line > insertion_point_ + auto_repeat_total_tracks_)
+ return find(named_lines_indexes_, line - (auto_repeat_total_tracks_ - 1));
+
+ if (line == insertion_point_) {
+ return find(named_lines_indexes_, line) ||
+ find(auto_repeat_named_lines_indexes_, 0);
+ }
+
+ if (line == insertion_point_ + auto_repeat_total_tracks_) {
+ return find(auto_repeat_named_lines_indexes_,
+ auto_repeat_track_list_length_) ||
+ find(named_lines_indexes_, insertion_point_ + 1);
+ }
+
+ size_t auto_repeat_index_in_first_repetition =
+ (line - insertion_point_) % auto_repeat_track_list_length_;
+ if (!auto_repeat_index_in_first_repetition &&
+ find(auto_repeat_named_lines_indexes_, auto_repeat_track_list_length_))
+ return true;
+ return find(auto_repeat_named_lines_indexes_,
+ auto_repeat_index_in_first_repetition);
}
-size_t NamedLineCollection::FirstPosition() {
- CHECK(HasNamedLines());
+size_t NamedLineCollection::FirstExplicitPosition() {
+ DCHECK(HasExplicitNamedLines());
size_t first_line = 0;
- if (!auto_repeat_named_lines_indexes_) {
- if (insertion_point_ == 0 ||
- insertion_point_ < named_lines_indexes_->at(first_line))
- return named_lines_indexes_->at(first_line) +
- (auto_repeat_total_tracks_ ? auto_repeat_total_tracks_ - 1 : 0);
+ // If there is no auto repeat(), there must be some named line outside, return
+ // the 1st one. Also return it if it precedes the auto-repeat().
+ if (auto_repeat_track_list_length_ == 0 ||
+ (named_lines_indexes_ &&
+ named_lines_indexes_->at(first_line) <= insertion_point_))
return named_lines_indexes_->at(first_line);
- }
- if (!named_lines_indexes_)
+ // Return the 1st named line inside the auto repeat(), if any.
+ if (auto_repeat_named_lines_indexes_)
return auto_repeat_named_lines_indexes_->at(first_line) + insertion_point_;
- if (insertion_point_ == 0)
- return std::min(
- named_lines_indexes_->at(first_line) + auto_repeat_total_tracks_,
- auto_repeat_named_lines_indexes_->at(first_line));
+ // The 1st named line must be after the auto repeat().
+ return named_lines_indexes_->at(first_line) + auto_repeat_total_tracks_ - 1;
+}
+
+size_t NamedLineCollection::FirstPosition() {
+ CHECK(HasNamedLines());
+
+ size_t first_line = 0;
+
+ if (!implicit_named_lines_indexes_)
+ return FirstExplicitPosition();
+
+ if (!HasExplicitNamedLines())
+ return implicit_named_lines_indexes_->at(first_line);
- return std::min(
- named_lines_indexes_->at(first_line),
- auto_repeat_named_lines_indexes_->at(first_line) + insertion_point_);
+ return std::min(FirstExplicitPosition(),
+ implicit_named_lines_indexes_->at(first_line));
}
GridPositionSide GridPositionsResolver::InitialPositionSide(
diff --git a/chromium/third_party/blink/renderer/core/style/grid_positions_resolver.h b/chromium/third_party/blink/renderer/core/style/grid_positions_resolver.h
index 475819da7a5..bf672440c84 100644
--- a/chromium/third_party/blink/renderer/core/style/grid_positions_resolver.h
+++ b/chromium/third_party/blink/renderer/core/style/grid_positions_resolver.h
@@ -38,9 +38,11 @@ class NamedLineCollection {
bool Contains(size_t line);
private:
- size_t Find(size_t line);
+ bool HasExplicitNamedLines();
+ size_t FirstExplicitPosition();
const Vector<size_t>* named_lines_indexes_ = nullptr;
const Vector<size_t>* auto_repeat_named_lines_indexes_ = nullptr;
+ const Vector<size_t>* implicit_named_lines_indexes_ = nullptr;
size_t insertion_point_;
size_t last_line_;
diff --git a/chromium/third_party/blink/renderer/core/style/intrinsic_length.h b/chromium/third_party/blink/renderer/core/style/intrinsic_length.h
deleted file mode 100644
index db8844aff52..00000000000
--- a/chromium/third_party/blink/renderer/core/style/intrinsic_length.h
+++ /dev/null
@@ -1,58 +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_STYLE_INTRINSIC_LENGTH_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_INTRINSIC_LENGTH_H_
-
-#include "third_party/blink/renderer/platform/geometry/length.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-
-class IntrinsicLength {
- DISALLOW_NEW();
-
- enum LengthType { kAuto, kLegacy, kSpecified };
-
- public:
- IntrinsicLength() : IntrinsicLength(kLegacy) {}
-
- static IntrinsicLength MakeAuto() { return IntrinsicLength(kAuto); }
- static IntrinsicLength MakeLegacy() { return IntrinsicLength(kLegacy); }
- static IntrinsicLength Make(const Length& length) {
- return IntrinsicLength(kSpecified, length);
- }
-
- bool IsAuto() const { return type_ == kAuto; }
- bool IsLegacy() const { return type_ == kLegacy; }
- const Length& GetLength() const {
- // We may still need to get the length for auto, so we only guard against
- // legacy.
- DCHECK(!IsLegacy());
- return length_;
- }
-
- bool operator==(const IntrinsicLength& other) const {
- return type_ == other.type_ && length_ == other.length_;
- }
- bool operator!=(const IntrinsicLength& other) const {
- return !(*this == other);
- }
-
- private:
- IntrinsicLength(LengthType type, const Length& length = Length())
- : type_(type), length_(length) {
- // If the type is specified, then length has to be fixed.
- // Otherwise, the length has to be the default value.
- DCHECK(type != kSpecified || length.IsFixed());
- DCHECK(type == kSpecified || length == Length());
- }
-
- LengthType type_;
- Length length_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_INTRINSIC_LENGTH_H_
diff --git a/chromium/third_party/blink/renderer/core/style/nine_piece_image.cc b/chromium/third_party/blink/renderer/core/style/nine_piece_image.cc
index 07c6317bd6f..4e5fdbeb5e2 100644
--- a/chromium/third_party/blink/renderer/core/style/nine_piece_image.cc
+++ b/chromium/third_party/blink/renderer/core/style/nine_piece_image.cc
@@ -64,10 +64,7 @@ NinePieceImageData::NinePieceImageData()
Length::Percent(100),
Length::Percent(100)),
border_slices(1.0, 1.0, 1.0, 1.0),
- outset(Length::Fixed(0),
- Length::Fixed(0),
- Length::Fixed(0),
- Length::Fixed(0)) {}
+ outset(0, 0, 0, 0) {}
bool NinePieceImageData::operator==(const NinePieceImageData& other) const {
return DataEquivalent(image, other.image) &&
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 a7be50827f1..c416b4bd49c 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(blink::Visitor* visitor) { visitor->Trace(image_); }
+ virtual void Trace(Visitor* visitor) { 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 49ef5c451b9..76f510c2a30 100644
--- a/chromium/third_party/blink/renderer/core/style/style_difference.cc
+++ b/chromium/third_party/blink/renderer/core/style/style_difference.cc
@@ -26,24 +26,8 @@ std::ostream& operator<<(std::ostream& out, const StyleDifference& diff) {
out << ", collectInlines=" << diff.needs_collect_inlines_;
out << ", reshape=" << diff.needs_reshape_;
-
- out << ", paintInvalidationType=";
- switch (diff.paint_invalidation_type_) {
- case StyleDifference::kNoPaintInvalidation:
- out << "NoPaintInvalidation";
- break;
- case StyleDifference::kPaintInvalidationObject:
- out << "PaintInvalidationObject";
- break;
- case StyleDifference::kPaintInvalidationSubtree:
- out << "PaintInvalidationSubtree";
- break;
- default:
- NOTREACHED();
- break;
- }
-
- out << ", recomputeOverflow=" << diff.recompute_overflow_;
+ out << ", paintInvalidation=" << diff.needs_paint_invalidation_;
+ out << ", recomputeVisualOverflow=" << diff.recompute_visual_overflow_;
out << ", visualRectUpdate=" << diff.visual_rect_update_;
out << ", propertySpecificDifferences=";
diff --git a/chromium/third_party/blink/renderer/core/style/style_difference.h b/chromium/third_party/blink/renderer/core/style/style_difference.h
index 517fbb8f5a7..14e468cfb60 100644
--- a/chromium/third_party/blink/renderer/core/style/style_difference.h
+++ b/chromium/third_party/blink/renderer/core/style/style_difference.h
@@ -36,23 +36,22 @@ class StyleDifference {
};
StyleDifference()
- : paint_invalidation_type_(kNoPaintInvalidation),
+ : needs_paint_invalidation_(false),
layout_type_(kNoLayout),
needs_collect_inlines_(false),
needs_reshape_(false),
- recompute_overflow_(false),
+ recompute_visual_overflow_(false),
visual_rect_update_(false),
property_specific_differences_(0),
scroll_anchor_disabling_property_changed_(false),
compositing_reasons_changed_(false) {}
void Merge(StyleDifference other) {
- paint_invalidation_type_ =
- std::max(paint_invalidation_type_, other.paint_invalidation_type_);
+ needs_paint_invalidation_ |= other.needs_paint_invalidation_;
layout_type_ = std::max(layout_type_, other.layout_type_);
needs_collect_inlines_ |= other.needs_collect_inlines_;
needs_reshape_ |= other.needs_reshape_;
- recompute_overflow_ |= other.recompute_overflow_;
+ recompute_visual_overflow_ |= other.recompute_visual_overflow_;
visual_rect_update_ |= other.visual_rect_update_;
property_specific_differences_ |= other.property_specific_differences_;
scroll_anchor_disabling_property_changed_ |=
@@ -61,39 +60,21 @@ class StyleDifference {
}
bool HasDifference() const {
- return paint_invalidation_type_ || layout_type_ || needs_collect_inlines_ ||
- needs_reshape_ || property_specific_differences_ ||
- recompute_overflow_ || visual_rect_update_ ||
- scroll_anchor_disabling_property_changed_ ||
+ return needs_paint_invalidation_ || layout_type_ ||
+ needs_collect_inlines_ || needs_reshape_ ||
+ property_specific_differences_ || recompute_visual_overflow_ ||
+ visual_rect_update_ || scroll_anchor_disabling_property_changed_ ||
compositing_reasons_changed_;
}
bool HasAtMostPropertySpecificDifferences(
unsigned property_differences) const {
- return !paint_invalidation_type_ && !layout_type_ &&
+ return !needs_paint_invalidation_ && !layout_type_ &&
!(property_specific_differences_ & ~property_differences);
}
- bool NeedsFullPaintInvalidation() const {
- return paint_invalidation_type_ != kNoPaintInvalidation;
- }
-
- // The object just needs to issue paint invalidations.
- bool NeedsPaintInvalidationObject() const {
- return paint_invalidation_type_ == kPaintInvalidationObject;
- }
- void SetNeedsPaintInvalidationObject() {
- DCHECK(!NeedsPaintInvalidationSubtree());
- paint_invalidation_type_ = kPaintInvalidationObject;
- }
-
- // The object and its descendants need to issue paint invalidations.
- bool NeedsPaintInvalidationSubtree() const {
- return paint_invalidation_type_ == kPaintInvalidationSubtree;
- }
- void SetNeedsPaintInvalidationSubtree() {
- paint_invalidation_type_ = kPaintInvalidationSubtree;
- }
+ bool NeedsPaintInvalidation() const { return needs_paint_invalidation_; }
+ void SetNeedsPaintInvalidation() { needs_paint_invalidation_ = true; }
bool NeedsLayout() const { return layout_type_ != kNoLayout; }
void ClearNeedsLayout() { layout_type_ = kNoLayout; }
@@ -116,8 +97,10 @@ class StyleDifference {
bool NeedsReshape() const { return needs_reshape_; }
void SetNeedsReshape() { needs_reshape_ = true; }
- bool NeedsRecomputeOverflow() const { return recompute_overflow_; }
- void SetNeedsRecomputeOverflow() { recompute_overflow_ = true; }
+ bool NeedsRecomputeVisualOverflow() const {
+ return recompute_visual_overflow_;
+ }
+ void SetNeedsRecomputeVisualOverflow() { recompute_visual_overflow_ = true; }
bool NeedsVisualRectUpdate() const { return visual_rect_update_; }
void SetNeedsVisualRectUpdate() { visual_rect_update_ = true; }
@@ -203,18 +186,13 @@ class StyleDifference {
friend CORE_EXPORT std::ostream& operator<<(std::ostream&,
const StyleDifference&);
- enum PaintInvalidationType {
- kNoPaintInvalidation,
- kPaintInvalidationObject,
- kPaintInvalidationSubtree,
- };
- unsigned paint_invalidation_type_ : 2;
+ unsigned needs_paint_invalidation_ : 1;
enum LayoutType { kNoLayout = 0, kPositionedMovement, kFullLayout };
unsigned layout_type_ : 2;
unsigned needs_collect_inlines_ : 1;
unsigned needs_reshape_ : 1;
- unsigned recompute_overflow_ : 1;
+ unsigned recompute_visual_overflow_ : 1;
unsigned visual_rect_update_ : 1;
unsigned property_specific_differences_ : kPropertyDifferenceCount;
unsigned scroll_anchor_disabling_property_changed_ : 1;
diff --git a/chromium/third_party/blink/renderer/core/style/style_difference_test.cc b/chromium/third_party/blink/renderer/core/style/style_difference_test.cc
index f45ae9b835e..d1e28065dc8 100644
--- a/chromium/third_party/blink/renderer/core/style/style_difference_test.cc
+++ b/chromium/third_party/blink/renderer/core/style/style_difference_test.cc
@@ -16,7 +16,7 @@ TEST(StyleDifferenceTest, StreamOutputDefault) {
EXPECT_EQ(
"StyleDifference{layoutType=NoLayout, "
"collectInlines=0, reshape=0, "
- "paintInvalidationType=NoPaintInvalidation, recomputeOverflow=0, "
+ "paintInvalidation=0, recomputeVisualOverflow=0, "
"visualRectUpdate=0, propertySpecificDifferences=, "
"scrollAnchorDisablingPropertyChanged=0}",
string_stream.str());
@@ -25,20 +25,20 @@ TEST(StyleDifferenceTest, StreamOutputDefault) {
TEST(StyleDifferenceTest, StreamOutputAllFieldsMutated) {
std::stringstream string_stream;
StyleDifference diff;
- diff.SetNeedsPaintInvalidationObject();
+ diff.SetNeedsPaintInvalidation();
diff.SetNeedsPositionedMovementLayout();
diff.SetNeedsReshape();
diff.SetNeedsCollectInlines();
- diff.SetNeedsRecomputeOverflow();
+ diff.SetNeedsRecomputeVisualOverflow();
diff.SetNeedsVisualRectUpdate();
diff.SetTransformChanged();
diff.SetScrollAnchorDisablingPropertyChanged();
string_stream << diff;
EXPECT_EQ(
"StyleDifference{layoutType=PositionedMovement, "
- "collectInlines=1, reshape=1, "
- "paintInvalidationType=PaintInvalidationObject, recomputeOverflow=1, "
- "visualRectUpdate=1, propertySpecificDifferences=TransformChanged, "
+ "collectInlines=1, reshape=1, paintInvalidation=1, "
+ "recomputeVisualOverflow=1, visualRectUpdate=1, "
+ "propertySpecificDifferences=TransformChanged, "
"scrollAnchorDisablingPropertyChanged=1}",
string_stream.str());
}
@@ -57,9 +57,8 @@ TEST(StyleDifferenceTest, StreamOutputSetAllProperties) {
string_stream << diff;
EXPECT_EQ(
"StyleDifference{layoutType=NoLayout, "
- "collectInlines=0, reshape=0, "
- "paintInvalidationType=NoPaintInvalidation, recomputeOverflow=0, "
- "visualRectUpdate=0, "
+ "collectInlines=0, reshape=0, paintInvalidation=0, "
+ "recomputeVisualOverflow=0, visualRectUpdate=0, "
"propertySpecificDifferences=TransformChanged|OpacityChanged|"
"ZIndexChanged|FilterChanged|BackdropFilterChanged|CSSClipChanged|"
"TextDecorationOrColorChanged|BlendModeChanged, "
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 ff6a1ab7489..fc358725ebc 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
@@ -35,6 +35,7 @@
#include "third_party/blink/renderer/core/svg/graphics/svg_image.h"
#include "third_party/blink/renderer/core/svg/graphics/svg_image_for_container.h"
#include "third_party/blink/renderer/platform/geometry/layout_size.h"
+#include "third_party/blink/renderer/platform/graphics/bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/placeholder_image.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -81,8 +82,9 @@ ImageResourceContent* StyleFetchedImage::CachedImage() const {
}
CSSValue* StyleFetchedImage::CssValue() const {
- return CSSImageValue::Create(
- url_, origin_clean_ ? OriginClean::kTrue : OriginClean::kFalse,
+ return MakeGarbageCollected<CSSImageValue>(
+ AtomicString(url_.GetString()), url_, Referrer(),
+ origin_clean_ ? OriginClean::kTrue : OriginClean::kFalse,
const_cast<StyleFetchedImage*>(this));
}
@@ -106,21 +108,17 @@ bool StyleFetchedImage::ErrorOccurred() const {
FloatSize StyleFetchedImage::ImageSize(
const Document&,
float multiplier,
- const LayoutSize& default_object_size) const {
+ const LayoutSize& default_object_size,
+ RespectImageOrientationEnum respect_orientation) const {
Image* image = image_->GetImage();
if (image_->HasDevicePixelRatioHeaderValue()) {
multiplier /= image_->DevicePixelRatioHeaderValue();
}
- if (image->IsSVGImage()) {
- return ImageSizeForSVGImage(ToSVGImage(image), multiplier,
- default_object_size);
+ if (auto* svg_image = DynamicTo<SVGImage>(image)) {
+ return ImageSizeForSVGImage(svg_image, multiplier, default_object_size);
}
- // Image orientation should only be respected for content images,
- // not decorative images such as StyleImage (backgrounds,
- // border-image, etc.)
- //
- // https://drafts.csswg.org/css-images-3/#the-image-orientation
- FloatSize size(image->Size());
+
+ FloatSize size(image->Size(respect_orientation));
return ApplyZoom(size, multiplier);
}
@@ -140,8 +138,9 @@ void StyleFetchedImage::ImageNotifyFinished(ImageResourceContent*) {
if (image_ && image_->HasImage()) {
Image& image = *image_->GetImage();
- if (document_ && image.IsSVGImage())
- ToSVGImage(image).UpdateUseCounters(*document_);
+ auto* svg_image = DynamicTo<SVGImage>(image);
+ if (document_ && svg_image)
+ svg_image->UpdateUseCounters(*document_);
}
if (document_) {
@@ -164,9 +163,10 @@ scoped_refptr<Image> StyleFetchedImage::GetImage(
style.EffectiveZoom());
}
- if (!image->IsSVGImage())
+ auto* svg_image = DynamicTo<SVGImage>(image);
+ if (!svg_image)
return image;
- return SVGImageForContainer::Create(ToSVGImage(image), target_size,
+ return SVGImageForContainer::Create(svg_image, target_size,
style.EffectiveZoom(), url_);
}
@@ -194,7 +194,7 @@ bool StyleFetchedImage::GetImageAnimationPolicy(ImageAnimationPolicy& policy) {
return true;
}
-void StyleFetchedImage::Trace(blink::Visitor* visitor) {
+void StyleFetchedImage::Trace(Visitor* visitor) {
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 f8abe6869c3..d579633c07e 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
@@ -57,7 +57,8 @@ class StyleFetchedImage final : public StyleImage,
bool ErrorOccurred() const override;
FloatSize ImageSize(const Document&,
float multiplier,
- const LayoutSize& default_object_size) const override;
+ const LayoutSize& default_object_size,
+ RespectImageOrientationEnum) const override;
bool HasIntrinsicSize() const override;
void AddClient(ImageResourceObserver*) override;
void RemoveClient(ImageResourceObserver*) override;
@@ -73,7 +74,7 @@ class StyleFetchedImage final : public StyleImage,
void LoadDeferredImage(const Document& document);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 7d44404b841..187b447aa94 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
@@ -29,6 +29,7 @@
#include "third_party/blink/renderer/core/loader/resource/image_resource_content.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/svg/graphics/svg_image_for_container.h"
+#include "third_party/blink/renderer/platform/graphics/bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/placeholder_image.h"
namespace blink {
@@ -95,18 +96,13 @@ bool StyleFetchedImageSet::ErrorOccurred() const {
FloatSize StyleFetchedImageSet::ImageSize(
const Document&,
float multiplier,
- const LayoutSize& default_object_size) const {
+ const LayoutSize& default_object_size,
+ RespectImageOrientationEnum respect_orientation) const {
Image* image = best_fit_image_->GetImage();
- if (image->IsSVGImage()) {
- return ImageSizeForSVGImage(ToSVGImage(image), multiplier,
- default_object_size);
+ if (auto* svg_image = DynamicTo<SVGImage>(image)) {
+ return ImageSizeForSVGImage(svg_image, multiplier, default_object_size);
}
- // Image orientation should only be respected for content images,
- // not decorative ones such as StyleImage (backgrounds,
- // border-image, etc.)
- //
- // https://drafts.csswg.org/css-images-3/#the-image-orientation
- FloatSize natural_size(image->Size());
+ FloatSize natural_size(image->Size(respect_orientation));
FloatSize scaled_image_size(ApplyZoom(natural_size, multiplier));
scaled_image_size.Scale(1 / image_scale_factor_);
return scaled_image_size;
@@ -135,9 +131,10 @@ scoped_refptr<Image> StyleFetchedImageSet::GetImage(
style.EffectiveZoom());
}
- if (!image->IsSVGImage())
+ auto* svg_image = DynamicTo<SVGImage>(image);
+ if (!svg_image)
return image;
- return SVGImageForContainer::Create(ToSVGImage(image), target_size,
+ return SVGImageForContainer::Create(svg_image, target_size,
style.EffectiveZoom(), url_);
}
@@ -146,7 +143,7 @@ bool StyleFetchedImageSet::KnownToBeOpaque(const Document&,
return best_fit_image_->GetImage()->CurrentFrameKnownToBeOpaque();
}
-void StyleFetchedImageSet::Trace(blink::Visitor* visitor) {
+void StyleFetchedImageSet::Trace(Visitor* visitor) {
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 99055c04962..4b9b9275ae3 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
@@ -67,7 +67,8 @@ class StyleFetchedImageSet final : public StyleImage,
bool ErrorOccurred() const override;
FloatSize ImageSize(const Document&,
float multiplier,
- const LayoutSize& default_object_size) const override;
+ const LayoutSize& default_object_size,
+ RespectImageOrientationEnum) const override;
bool HasIntrinsicSize() const override;
void AddClient(ImageResourceObserver*) override;
void RemoveClient(ImageResourceObserver*) override;
@@ -79,7 +80,7 @@ class StyleFetchedImageSet final : public StyleImage,
bool KnownToBeOpaque(const Document&, const ComputedStyle&) const override;
ImageResourceContent* CachedImage() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 cf416fe053d..7c441074556 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(blink::Visitor* visitor) { visitor->Trace(operations_); }
+ void Trace(Visitor* visitor) { 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 dda3c293924..28764bd5896 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
@@ -55,10 +55,10 @@ CSSValue* StyleGeneratedImage::ComputedCSSValue(
return image_generator_value_->ComputedCSSValue(style, allow_visited_style);
}
-FloatSize StyleGeneratedImage::ImageSize(
- const Document& document,
- float multiplier,
- const LayoutSize& default_object_size) const {
+FloatSize StyleGeneratedImage::ImageSize(const Document& document,
+ float multiplier,
+ const LayoutSize& default_object_size,
+ RespectImageOrientationEnum) const {
if (fixed_size_) {
FloatSize unzoomed_default_object_size(default_object_size);
unzoomed_default_object_size.Scale(1 / multiplier);
@@ -99,7 +99,7 @@ bool StyleGeneratedImage::KnownToBeOpaque(const Document& document,
return image_generator_value_->KnownToBeOpaque(document, style);
}
-void StyleGeneratedImage::Trace(blink::Visitor* visitor) {
+void StyleGeneratedImage::Trace(Visitor* visitor) {
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 24fc4bb0ad8..2cfdc6e236f 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
@@ -49,7 +49,8 @@ class CORE_EXPORT StyleGeneratedImage final : public StyleImage {
FloatSize ImageSize(const Document&,
float multiplier,
- const LayoutSize& default_object_size) const override;
+ const LayoutSize& default_object_size,
+ RespectImageOrientationEnum) const override;
bool HasIntrinsicSize() const override { return fixed_size_; }
void AddClient(ImageResourceObserver*) override;
void RemoveClient(ImageResourceObserver*) override;
@@ -63,7 +64,7 @@ class CORE_EXPORT StyleGeneratedImage final : public StyleImage {
bool IsUsingCustomProperty(const AtomicString& custom_property_name,
const Document&) const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 ddf24cf7428..6c25142c4d2 100644
--- a/chromium/third_party/blink/renderer/core/style/style_image.h
+++ b/chromium/third_party/blink/renderer/core/style/style_image.h
@@ -25,6 +25,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_IMAGE_H_
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/graphics/image_orientation.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -86,9 +87,13 @@ class CORE_EXPORT StyleImage : public GarbageCollected<StyleImage> {
// not zoomed. Note that the |default_object_size| has already been snapped
// to LayoutUnit resolution because it represents the target painted size of
// a container.
+ //
+ // The size will respect the image orientation if requested and if the image
+ // supports it.
virtual FloatSize ImageSize(const Document&,
float multiplier,
- const LayoutSize& default_object_size) const = 0;
+ const LayoutSize& default_object_size,
+ RespectImageOrientationEnum) const = 0;
// The <image> has intrinsic dimensions.
//
@@ -141,7 +146,7 @@ class CORE_EXPORT StyleImage : public GarbageCollected<StyleImage> {
return is_lazyload_possibly_deferred_;
}
- virtual void Trace(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
protected:
StyleImage()
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 d31e0e0342e..5d15580d62e 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
@@ -74,7 +74,8 @@ class StylePendingImage final : public StyleImage {
FloatSize ImageSize(const Document&,
float /*multiplier*/,
- const LayoutSize& /*defaultObjectSize*/) const override {
+ const LayoutSize& /*defaultObjectSize*/,
+ RespectImageOrientationEnum) const override {
return FloatSize();
}
bool HasIntrinsicSize() const override { return true; }
@@ -91,7 +92,7 @@ class StylePendingImage final : public StyleImage {
return false;
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(value_);
StyleImage::Trace(visitor);
}
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 14fb36caf2e..de38223180b 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
@@ -120,9 +120,9 @@ StyleDifference SVGComputedStyle::Diff(const SVGComputedStyle& other) const {
if (DiffNeedsLayoutAndPaintInvalidation(other)) {
style_difference.SetNeedsFullLayout();
- style_difference.SetNeedsPaintInvalidationObject();
+ style_difference.SetNeedsPaintInvalidation();
} else if (DiffNeedsPaintInvalidation(other)) {
- style_difference.SetNeedsPaintInvalidationObject();
+ style_difference.SetNeedsPaintInvalidation();
}
return style_difference;
diff --git a/chromium/third_party/blink/renderer/core/svg/BUILD.gn b/chromium/third_party/blink/renderer/core/svg/BUILD.gn
index 785be87b9c8..d69850b5ec9 100644
--- a/chromium/third_party/blink/renderer/core/svg/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/svg/BUILD.gn
@@ -99,8 +99,6 @@ blink_core_sources("svg") {
"svg_defs_element.h",
"svg_desc_element.cc",
"svg_desc_element.h",
- "svg_discard_element.cc",
- "svg_discard_element.h",
"svg_document_extensions.cc",
"svg_document_extensions.h",
"svg_element.cc",
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 e0689f43684..2efc2b2b522 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(blink::Visitor* visitor) {
+void SMILAnimationSandwich::Trace(Visitor* visitor) {
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 c31ffb29647..7c0f5d26ec8 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(blink::Visitor*);
+ void Trace(Visitor*);
private:
// Results are accumulated to the first animation element that animates and
diff --git a/chromium/third_party/blink/renderer/core/svg/animation/smil_time.h b/chromium/third_party/blink/renderer/core/svg/animation/smil_time.h
index 7433a3a1c85..10286c62091 100644
--- a/chromium/third_party/blink/renderer/core/svg/animation/smil_time.h
+++ b/chromium/third_party/blink/renderer/core/svg/animation/smil_time.h
@@ -30,6 +30,7 @@
#include <ostream>
#include "base/time/time.h"
+#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/hash_traits.h"
@@ -136,7 +137,7 @@ class SMILTime {
base::TimeDelta time_;
};
-std::ostream& operator<<(std::ostream& os, SMILTime time);
+CORE_EXPORT std::ostream& operator<<(std::ostream& os, SMILTime time);
// What generated a SMILTime.
enum class SMILTimeOrigin {
@@ -208,4 +209,14 @@ inline bool operator!=(const SMILInterval& a, const SMILInterval& b) {
} // namespace blink
+namespace WTF {
+template <>
+struct HashTraits<blink::SMILInterval>
+ : GenericHashTraits<blink::SMILInterval> {
+ static blink::SMILInterval EmptyValue() {
+ return blink::SMILInterval::Unresolved();
+ }
+};
+} // namespace WTF
+
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SVG_ANIMATION_SMIL_TIME_H_
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 eeac5fd38aa..ad245c6aec1 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
@@ -26,7 +26,6 @@
#include "third_party/blink/renderer/core/svg/animation/smil_time_container.h"
#include <algorithm>
-#include "third_party/blink/renderer/core/animation/animation_clock.h"
#include "third_party/blink/renderer/core/animation/document_timeline.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
@@ -35,6 +34,7 @@
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/svg/animation/element_smil_animations.h"
#include "third_party/blink/renderer/core/svg/animation/svg_smil_element.h"
+#include "third_party/blink/renderer/core/svg/graphics/svg_image.h"
#include "third_party/blink/renderer/core/svg/svg_svg_element.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
@@ -57,28 +57,115 @@ class AnimationTargetsMutationsForbidden {
#endif
};
-static constexpr base::TimeDelta kAnimationPolicyOnceDuration =
- base::TimeDelta::FromSeconds(3);
+class SMILTimeContainer::TimingUpdate {
+ STACK_ALLOCATED();
+
+ public:
+ // The policy used when performing the timing update.
+ enum MovePolicy {
+ // Used for regular updates, i.e when time is running. All events will be
+ // dispatched.
+ kNormal,
+ // Used for seeking updates, i.e when time is explicitly
+ // set/changed. Events are not dispatched for skipped intervals, and no
+ // repeats are generated.
+ kSeek,
+ };
+ TimingUpdate(SMILTimeContainer& time_container,
+ SMILTime target_time,
+ MovePolicy policy)
+ : target_time_(target_time),
+ policy_(policy),
+ time_container_(&time_container) {
+ DCHECK_LE(target_time_, time_container_->max_presentation_time_);
+ }
+ ~TimingUpdate();
+
+ const SMILTime& Time() const { return time_container_->latest_update_time_; }
+ bool TryAdvanceTime(SMILTime next_time) {
+ if (time_container_->latest_update_time_ >= target_time_)
+ return false;
+ if (next_time > target_time_) {
+ time_container_->latest_update_time_ = target_time_;
+ return false;
+ }
+ time_container_->latest_update_time_ = next_time;
+ return true;
+ }
+ void RewindTimeToZero() { time_container_->latest_update_time_ = SMILTime(); }
+ const SMILTime& TargetTime() const { return target_time_; }
+ bool IsSeek() const { return policy_ == kSeek; }
+ void AddActiveElement(SVGSMILElement*, const SMILInterval&);
+ void HandleEvents(SVGSMILElement*, SVGSMILElement::EventDispatchMask);
+ bool ShouldDispatchEvents() const {
+ return time_container_->should_dispatch_events_;
+ }
+
+ using UpdatedElementsMap = HeapHashMap<Member<SVGSMILElement>, SMILInterval>;
+ UpdatedElementsMap& UpdatedElements() { return updated_elements_; }
+
+ TimingUpdate(const TimingUpdate&) = delete;
+ TimingUpdate& operator=(const TimingUpdate&) = delete;
+
+ private:
+ SMILTime target_time_;
+ MovePolicy policy_;
+ SMILTimeContainer* time_container_;
+ UpdatedElementsMap updated_elements_;
+};
+
+SMILTimeContainer::TimingUpdate::~TimingUpdate() {
+ if (!ShouldDispatchEvents())
+ return;
+ DCHECK(IsSeek() || updated_elements_.IsEmpty());
+ for (const auto& entry : updated_elements_) {
+ SVGSMILElement* element = entry.key;
+ if (auto events_to_dispatch = element->ComputeSeekEvents(entry.value))
+ element->DispatchEvents(events_to_dispatch);
+ }
+}
+
+void SMILTimeContainer::TimingUpdate::AddActiveElement(
+ SVGSMILElement* element,
+ const SMILInterval& interval) {
+ DCHECK(IsSeek());
+ DCHECK(ShouldDispatchEvents());
+ updated_elements_.insert(element, interval);
+}
+
+void SMILTimeContainer::TimingUpdate::HandleEvents(
+ SVGSMILElement* element,
+ SVGSMILElement::EventDispatchMask events_to_dispatch) {
+ if (!IsSeek()) {
+ if (ShouldDispatchEvents() && events_to_dispatch)
+ element->DispatchEvents(events_to_dispatch);
+ return;
+ }
+ // Even if no events will be dispatched, we still need to track the elements
+ // that has been updated so that we can adjust their next interval time when
+ // we're done. (If we tracked active elements separately this would not be
+ // necessary.)
+ updated_elements_.insert(element, SMILInterval::Unresolved());
+}
SMILTimeContainer::SMILTimeContainer(SVGSVGElement& owner)
: frame_scheduling_state_(kIdle),
started_(false),
paused_(false),
+ should_dispatch_events_(!SVGImage::IsInSVGImage(&owner)),
document_order_indexes_dirty_(false),
is_updating_intervals_(false),
wakeup_timer_(
owner.GetDocument().GetTaskRunner(TaskType::kInternalDefault),
this,
&SMILTimeContainer::WakeupTimerFired),
- animation_policy_once_timer_(
- owner.GetDocument().GetTaskRunner(TaskType::kInternalDefault),
- this,
- &SMILTimeContainer::AnimationPolicyTimerFired),
- owner_svg_element_(&owner) {}
+ owner_svg_element_(&owner) {
+ // Update the max presentation time based on the animation policy in effect.
+ SetPresentationTime(presentation_time_);
+}
SMILTimeContainer::~SMILTimeContainer() {
CancelAnimationFrame();
- CancelAnimationPolicyTimer();
DCHECK(!wakeup_timer_.IsActive());
DCHECK(AnimationTargetsMutationsAllowed());
}
@@ -101,7 +188,6 @@ void SMILTimeContainer::Unschedule(SVGSMILElement* animation) {
DCHECK(animated_targets_.Contains(animation->targetElement()));
animated_targets_.erase(animation->targetElement());
- pending_discards_.erase(animation);
priority_queue_.Remove(animation);
}
@@ -145,14 +231,14 @@ SMILTime SMILTimeContainer::Elapsed() const {
return presentation_time_;
base::TimeDelta time_offset =
- GetDocument().Timeline().CurrentTimeInternal().value_or(
+ GetDocument().Timeline().CurrentPhaseAndTime().time.value_or(
base::TimeDelta()) -
reference_time_;
DCHECK_GE(time_offset, base::TimeDelta());
SMILTime elapsed = presentation_time_ +
SMILTime::FromMicroseconds(time_offset.InMicroseconds());
DCHECK_GE(elapsed, SMILTime());
- return elapsed;
+ return ClampPresentationTime(elapsed);
}
void SMILTimeContainer::ResetDocumentTime() {
@@ -174,13 +260,14 @@ SMILTime SMILTimeContainer::LatestUpdatePresentationTime() const {
}
void SMILTimeContainer::SynchronizeToDocumentTimeline() {
- reference_time_ = GetDocument().Timeline().CurrentTimeInternal().value_or(
- base::TimeDelta());
+ reference_time_ =
+ GetDocument().Timeline().CurrentPhaseAndTime().time.value_or(
+ base::TimeDelta());
}
bool SMILTimeContainer::IsPaused() const {
// If animation policy is "none", the timeline is always paused.
- return paused_ || AnimationPolicy() == kImageAnimationPolicyNoAnimation;
+ return paused_ || AnimationsDisabled();
}
bool SMILTimeContainer::IsStarted() const {
@@ -194,10 +281,7 @@ bool SMILTimeContainer::IsTimelineRunning() const {
void SMILTimeContainer::Start() {
CHECK(!IsStarted());
- if (!GetDocument().IsActive())
- return;
-
- if (!HandleAnimationPolicy(kRestartOnceTimerIfNotPaused))
+ if (AnimationsDisabled())
return;
// Sample the document timeline to get a time reference for the "presentation
@@ -205,24 +289,26 @@ void SMILTimeContainer::Start() {
SynchronizeToDocumentTimeline();
started_ = true;
- UpdateAnimationsAndScheduleFrameIfNeeded(presentation_time_);
+ TimingUpdate update(*this, presentation_time_, TimingUpdate::kSeek);
+ UpdateAnimationsAndScheduleFrameIfNeeded(update);
}
void SMILTimeContainer::Pause() {
- if (!HandleAnimationPolicy(kCancelOnceTimer))
+ if (AnimationsDisabled())
return;
DCHECK(!IsPaused());
if (IsStarted()) {
- presentation_time_ = Elapsed();
+ SetPresentationTime(Elapsed());
CancelAnimationFrame();
}
+
// Update the flag after sampling elapsed().
paused_ = true;
}
void SMILTimeContainer::Unpause() {
- if (!HandleAnimationPolicy(kRestartOnceTimer))
+ if (AnimationsDisabled())
return;
DCHECK(IsPaused());
@@ -235,10 +321,31 @@ void SMILTimeContainer::Unpause() {
ScheduleWakeUp(base::TimeDelta(), kSynchronizeAnimations);
}
+void SMILTimeContainer::SetPresentationTime(SMILTime new_presentation_time) {
+ // Start by resetting the max presentation time, because if the
+ // animation-policy is "once" we'll set a new limit below regardless, and for
+ // the other cases it's the right thing to do.
+ //
+ // We can't seek beyond this time, because at Latest() any additions will
+ // yield the same value.
+ max_presentation_time_ = SMILTime::Latest() - SMILTime::Epsilon();
+ presentation_time_ = ClampPresentationTime(new_presentation_time);
+ if (AnimationPolicy() != kImageAnimationPolicyAnimateOnce)
+ return;
+ const SMILTime kAnimationPolicyOnceDuration = SMILTime::FromSecondsD(3);
+ max_presentation_time_ =
+ ClampPresentationTime(presentation_time_ + kAnimationPolicyOnceDuration);
+}
+
+SMILTime SMILTimeContainer::ClampPresentationTime(
+ SMILTime presentation_time) const {
+ return std::min(presentation_time, max_presentation_time_);
+}
+
void SMILTimeContainer::SetElapsed(SMILTime elapsed) {
- presentation_time_ = elapsed;
+ SetPresentationTime(elapsed);
- if (!GetDocument().IsActive())
+ if (AnimationsDisabled())
return;
// If the document hasn't finished loading, |presentation_time_| will be
@@ -246,22 +353,14 @@ void SMILTimeContainer::SetElapsed(SMILTime elapsed) {
if (!IsStarted())
return;
- if (!HandleAnimationPolicy(kRestartOnceTimerIfNotPaused))
- return;
-
CancelAnimationFrame();
if (!IsPaused())
SynchronizeToDocumentTimeline();
- // If we are rewinding the timeline, we need to start from 0 and then move
- // forward to the new presentation time. If we're moving forward we can just
- // perform the update in the normal fashion.
- if (elapsed < latest_update_time_) {
- ResetIntervals();
- latest_update_time_ = SMILTime();
- }
- UpdateAnimationsAndScheduleFrameIfNeeded(elapsed);
+ TimingUpdate update(*this, presentation_time_, TimingUpdate::kSeek);
+ PrepareSeek(update);
+ UpdateAnimationsAndScheduleFrameIfNeeded(update);
}
void SMILTimeContainer::ScheduleAnimationFrame(base::TimeDelta delay_time) {
@@ -306,62 +405,20 @@ void SMILTimeContainer::WakeupTimerFired(TimerBase*) {
DCHECK(IsTimelineRunning());
ServiceOnNextFrame();
} else {
- UpdateAnimationsAndScheduleFrameIfNeeded(Elapsed());
+ TimingUpdate update(*this, Elapsed(), TimingUpdate::kNormal);
+ UpdateAnimationsAndScheduleFrameIfNeeded(update);
}
}
-void SMILTimeContainer::ScheduleAnimationPolicyTimer() {
- animation_policy_once_timer_.StartOneShot(kAnimationPolicyOnceDuration,
- FROM_HERE);
-}
-
-void SMILTimeContainer::CancelAnimationPolicyTimer() {
- animation_policy_once_timer_.Stop();
-}
-
-void SMILTimeContainer::AnimationPolicyTimerFired(TimerBase*) {
- Pause();
+ImageAnimationPolicy SMILTimeContainer::AnimationPolicy() const {
+ const Settings* settings = GetDocument().GetSettings();
+ return settings ? settings->GetImageAnimationPolicy()
+ : kImageAnimationPolicyAllowed;
}
-ImageAnimationPolicy SMILTimeContainer::AnimationPolicy() const {
- Settings* settings = GetDocument().GetSettings();
- if (!settings)
- return kImageAnimationPolicyAllowed;
-
- return settings->GetImageAnimationPolicy();
-}
-
-bool SMILTimeContainer::HandleAnimationPolicy(
- AnimationPolicyOnceAction once_action) {
- ImageAnimationPolicy policy = AnimationPolicy();
- // If the animation policy is "none", control is not allowed.
- // returns false to exit flow.
- if (policy == kImageAnimationPolicyNoAnimation)
- return false;
- // If the animation policy is "once",
- if (policy == kImageAnimationPolicyAnimateOnce) {
- switch (once_action) {
- case kRestartOnceTimerIfNotPaused:
- if (IsPaused())
- break;
- FALLTHROUGH;
- case kRestartOnceTimer:
- ScheduleAnimationPolicyTimer();
- break;
- case kCancelOnceTimer:
- CancelAnimationPolicyTimer();
- break;
- }
- }
- if (policy == kImageAnimationPolicyAllowed) {
- // When the SVG owner element becomes detached from its document,
- // the policy defaults to ImageAnimationPolicyAllowed; there's
- // no way back. If the policy had been "once" prior to that,
- // ensure cancellation of its timer.
- if (once_action == kCancelOnceTimer)
- CancelAnimationPolicyTimer();
- }
- return true;
+bool SMILTimeContainer::AnimationsDisabled() const {
+ return !GetDocument().IsActive() ||
+ AnimationPolicy() == kImageAnimationPolicyNoAnimation;
}
void SMILTimeContainer::UpdateDocumentOrderIndexes() {
@@ -395,39 +452,38 @@ void SMILTimeContainer::ServiceAnimations() {
// document, so this should be turned into a DCHECK.
if (!GetDocument().IsActive())
return;
- UpdateAnimationsAndScheduleFrameIfNeeded(Elapsed());
-}
-
-bool SMILTimeContainer::CanScheduleFrame(SMILTime earliest_fire_time) const {
- // If there's synchronization pending (most likely due to syncbases), then
- // let that complete first before attempting to schedule a frame.
- if (HasPendingSynchronization())
- return false;
- if (!IsTimelineRunning())
- return false;
- return earliest_fire_time.IsFinite();
+ TimingUpdate update(*this, Elapsed(), TimingUpdate::kNormal);
+ UpdateAnimationsAndScheduleFrameIfNeeded(update);
}
void SMILTimeContainer::UpdateAnimationsAndScheduleFrameIfNeeded(
- SMILTime elapsed) {
+ TimingUpdate& update) {
DCHECK(GetDocument().IsActive());
DCHECK(!wakeup_timer_.IsActive());
-
- UpdateAnimationTimings(elapsed);
- ApplyTimedEffects(elapsed);
-
- SMILTime next_progress_time = NextProgressTime(elapsed);
+ // If the priority queue is empty, there are no timed elements to process and
+ // no animations to apply, so we are done.
+ if (priority_queue_.IsEmpty())
+ return;
+ AnimationTargetsMutationsForbidden scope(this);
+ UpdateTimedElements(update);
+ ApplyTimedEffects(update.TargetTime());
DCHECK(!wakeup_timer_.IsActive());
+ DCHECK(!HasPendingSynchronization());
- if (!CanScheduleFrame(next_progress_time))
+ if (!IsTimelineRunning())
+ return;
+ SMILTime next_progress_time = NextProgressTime(update.TargetTime());
+ if (!next_progress_time.IsFinite())
return;
- SMILTime delay_time = next_progress_time - elapsed;
+ SMILTime delay_time = next_progress_time - update.TargetTime();
DCHECK(delay_time.IsFinite());
ScheduleAnimationFrame(
base::TimeDelta::FromMicroseconds(delay_time.InMicroseconds()));
}
SMILTime SMILTimeContainer::NextProgressTime(SMILTime presentation_time) const {
+ if (presentation_time == max_presentation_time_)
+ return SMILTime::Unresolved();
SMILTime next_progress_time = SMILTime::Unresolved();
for (const auto& entry : priority_queue_) {
next_progress_time = std::min(
@@ -438,6 +494,32 @@ SMILTime SMILTimeContainer::NextProgressTime(SMILTime presentation_time) const {
return next_progress_time;
}
+void SMILTimeContainer::PrepareSeek(TimingUpdate& update) {
+ DCHECK(update.IsSeek());
+ if (update.ShouldDispatchEvents()) {
+ // Record which elements are active at the current time so that we can
+ // correctly determine the transitions when the seek finishes.
+ // TODO(fs): Maybe keep track of the set of active timed elements and use
+ // that here (and in NextProgressTime).
+ for (auto& entry : priority_queue_) {
+ SVGSMILElement* element = entry.second;
+ const SMILInterval& active_interval =
+ element->GetActiveInterval(update.Time());
+ if (!active_interval.Contains(update.Time()))
+ continue;
+ update.AddActiveElement(element, active_interval);
+ }
+ }
+ // If we are rewinding the timeline, we need to start from 0 and then move
+ // forward to the new presentation time. If we're moving forward we can just
+ // perform the update in the normal fashion.
+ if (update.TargetTime() < update.Time()) {
+ ResetIntervals();
+ // TODO(fs): Clear resolved end times.
+ update.RewindTimeToZero();
+ }
+}
+
void SMILTimeContainer::ResetIntervals() {
base::AutoReset<bool> updating_intervals_scope(&is_updating_intervals_, true);
AnimationTargetsMutationsForbidden scope(this);
@@ -449,7 +531,8 @@ void SMILTimeContainer::ResetIntervals() {
priority_queue_.ResetAllPriorities(SMILTime::Earliest());
}
-void SMILTimeContainer::UpdateIntervals(SMILTime document_time) {
+void SMILTimeContainer::UpdateIntervals(TimingUpdate& update) {
+ const SMILTime document_time = update.Time();
DCHECK(document_time.IsFinite());
DCHECK_GE(document_time, SMILTime());
DCHECK(!priority_queue_.IsEmpty());
@@ -457,111 +540,66 @@ void SMILTimeContainer::UpdateIntervals(SMILTime document_time) {
const size_t kMaxIterations = std::max(priority_queue_.size() * 16, 1000000u);
size_t current_iteration = 0;
+ SVGSMILElement::IncludeRepeats repeat_handling =
+ update.IsSeek() ? SVGSMILElement::kExcludeRepeats
+ : SVGSMILElement::kIncludeRepeats;
+
base::AutoReset<bool> updating_intervals_scope(&is_updating_intervals_, true);
while (priority_queue_.Min() <= document_time) {
SVGSMILElement* element = priority_queue_.MinElement();
element->UpdateInterval(document_time);
- element->UpdateActiveState(document_time);
+ auto events_to_dispatch =
+ element->UpdateActiveState(document_time, update.IsSeek());
+ update.HandleEvents(element, events_to_dispatch);
SMILTime next_interval_time =
- element->ComputeNextIntervalTime(document_time);
+ element->ComputeNextIntervalTime(document_time, repeat_handling);
priority_queue_.Update(next_interval_time, element);
// Debugging signal for crbug.com/1021630.
CHECK_LT(current_iteration++, kMaxIterations);
}
}
-void SMILTimeContainer::UpdateAnimationTimings(SMILTime presentation_time) {
- DCHECK(GetDocument().IsActive());
-
- AnimationTargetsMutationsForbidden scope(this);
-
- if (document_order_indexes_dirty_)
- UpdateDocumentOrderIndexes();
+void SMILTimeContainer::UpdateTimedElements(TimingUpdate& update) {
+ // Flush any "late" interval updates.
+ UpdateIntervals(update);
- if (priority_queue_.IsEmpty())
- return;
+ while (update.TryAdvanceTime(priority_queue_.Min()))
+ UpdateIntervals(update);
- // Flush any "late" interval updates.
- UpdateIntervals(latest_update_time_);
-
- while (latest_update_time_ < presentation_time) {
- const SMILTime interval_time = priority_queue_.Min();
- if (interval_time <= presentation_time) {
- latest_update_time_ = interval_time;
- UpdateIntervals(latest_update_time_);
- } else {
- latest_update_time_ = presentation_time;
- }
+ // Update the next interval time for all affected elements to compensate for
+ // any ignored repeats.
+ const SMILTime presentation_time = update.TargetTime();
+ for (const auto& element : update.UpdatedElements().Keys()) {
+ SMILTime next_interval_time = element->ComputeNextIntervalTime(
+ presentation_time, SVGSMILElement::kIncludeRepeats);
+ priority_queue_.Update(next_interval_time, element);
}
}
void SMILTimeContainer::ApplyTimedEffects(SMILTime elapsed) {
+ if (document_order_indexes_dirty_)
+ UpdateDocumentOrderIndexes();
+
bool did_apply_effects = false;
- {
- AnimationTargetsMutationsForbidden scope(this);
- for (auto& entry : animated_targets_) {
- ElementSMILAnimations* animations = entry.key->GetSMILAnimations();
- if (animations && animations->Apply(elapsed))
- did_apply_effects = true;
- }
+ for (auto& entry : animated_targets_) {
+ ElementSMILAnimations* animations = entry.key->GetSMILAnimations();
+ if (animations && animations->Apply(elapsed))
+ did_apply_effects = true;
}
- if (PerformDiscards())
- did_apply_effects = true;
-
if (did_apply_effects) {
UseCounter::Count(&GetDocument(),
WebFeature::kSVGSMILAnimationAppliedEffect);
}
}
-void SMILTimeContainer::QueueDiscard(SVGSMILElement* discard_element) {
- DCHECK(discard_element->IsSVGDiscardElement());
- pending_discards_.insert(discard_element);
-}
-
-bool SMILTimeContainer::PerformDiscards() {
- if (pending_discards_.IsEmpty())
- return false;
-
- HeapVector<Member<SVGSMILElement>> discards;
- CopyToVector(pending_discards_, discards);
- pending_discards_.clear();
-
- // Sort by location in the document. (Should be based on the target rather
- // than the timed element, but often enough they will order the same.)
- std::sort(
- discards.begin(), discards.end(),
- [](const Member<SVGSMILElement>& a, const Member<SVGSMILElement>& b) {
- return a->DocumentOrderIndex() < b->DocumentOrderIndex();
- });
-
- for (SVGSMILElement* discard_element : discards) {
- if (!discard_element->isConnected())
- continue;
- SVGElement* target_element = discard_element->targetElement();
- if (target_element && target_element->isConnected()) {
- UseCounter::Count(&GetDocument(),
- WebFeature::kSVGSMILDiscardElementTriggered);
- target_element->remove(IGNORE_EXCEPTION_FOR_TESTING);
- DCHECK(!target_element->isConnected());
- }
- if (discard_element->isConnected()) {
- discard_element->remove(IGNORE_EXCEPTION_FOR_TESTING);
- DCHECK(!discard_element->isConnected());
- }
- }
- return true;
-}
-
void SMILTimeContainer::AdvanceFrameForTesting() {
const SMILTime kFrameDuration = SMILTime::FromSecondsD(0.025);
SetElapsed(Elapsed() + kFrameDuration);
}
-void SMILTimeContainer::Trace(blink::Visitor* visitor) {
+void SMILTimeContainer::Trace(Visitor* visitor) {
visitor->Trace(animated_targets_);
- visitor->Trace(pending_discards_);
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 aaa513c066d..a7201b8dea7 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
@@ -27,6 +27,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_ANIMATION_SMIL_TIME_CONTAINER_H_
#include "base/time/time.h"
+#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/svg/animation/priority_queue.h"
#include "third_party/blink/renderer/core/svg/animation/smil_time.h"
#include "third_party/blink/renderer/platform/graphics/image_animation_policy.h"
@@ -41,7 +42,8 @@ class SVGElement;
class SVGSMILElement;
class SVGSVGElement;
-class SMILTimeContainer final : public GarbageCollected<SMILTimeContainer> {
+class CORE_EXPORT SMILTimeContainer final
+ : public GarbageCollected<SMILTimeContainer> {
public:
explicit SMILTimeContainer(SVGSVGElement& owner);
~SMILTimeContainer();
@@ -70,12 +72,11 @@ class SMILTimeContainer final : public GarbageCollected<SMILTimeContainer> {
void ResetDocumentTime();
void SetDocumentOrderIndexesDirty() { document_order_indexes_dirty_ = true; }
- void QueueDiscard(SVGSMILElement* discard_element);
-
// Advance the animation timeline a single frame.
void AdvanceFrameForTesting();
+ bool EventsDisabled() const { return !should_dispatch_events_; }
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
enum FrameSchedulingState {
@@ -89,36 +90,26 @@ class SMILTimeContainer final : public GarbageCollected<SMILTimeContainer> {
kAnimationFrame
};
- enum AnimationPolicyOnceAction {
- // Restart OnceTimer if the timeline is not paused.
- kRestartOnceTimerIfNotPaused,
- // Restart OnceTimer.
- kRestartOnceTimer,
- // Cancel OnceTimer.
- kCancelOnceTimer
- };
-
bool IsTimelineRunning() const;
void SynchronizeToDocumentTimeline();
void ScheduleAnimationFrame(base::TimeDelta delay_time);
void CancelAnimationFrame();
void WakeupTimerFired(TimerBase*);
- void ScheduleAnimationPolicyTimer();
- void CancelAnimationPolicyTimer();
- void AnimationPolicyTimerFired(TimerBase*);
ImageAnimationPolicy AnimationPolicy() const;
- bool HandleAnimationPolicy(AnimationPolicyOnceAction);
- bool CanScheduleFrame(SMILTime earliest_fire_time) const;
- void UpdateAnimationsAndScheduleFrameIfNeeded(SMILTime elapsed);
+ bool AnimationsDisabled() const;
+ class TimingUpdate;
+ void UpdateAnimationsAndScheduleFrameIfNeeded(TimingUpdate&);
+ void PrepareSeek(TimingUpdate&);
void ResetIntervals();
- void UpdateIntervals(SMILTime presentation_time);
- void UpdateAnimationTimings(SMILTime elapsed);
+ void UpdateIntervals(TimingUpdate&);
+ void UpdateTimedElements(TimingUpdate&);
void ApplyTimedEffects(SMILTime elapsed);
- bool PerformDiscards();
SMILTime NextProgressTime(SMILTime presentation_time) const;
void ServiceOnNextFrame();
void ScheduleWakeUp(base::TimeDelta delay_time, FrameSchedulingState);
bool HasPendingSynchronization() const;
+ void SetPresentationTime(SMILTime new_presentation_time);
+ SMILTime ClampPresentationTime(SMILTime presentation_time) const;
void UpdateDocumentOrderIndexes();
@@ -128,6 +119,9 @@ class SMILTimeContainer final : public GarbageCollected<SMILTimeContainer> {
// The latest "restart" time for the time container's timeline. If the
// timeline has not been manipulated (seeked, paused) this will be zero.
SMILTime presentation_time_;
+ // The maximum possible presentation time. When this time is reached
+ // animations will stop.
+ SMILTime max_presentation_time_;
// The state all SVGSMILElements should be at.
SMILTime latest_update_time_;
// The time on the document timeline corresponding to |presentation_time_|.
@@ -137,15 +131,14 @@ class SMILTimeContainer final : public GarbageCollected<SMILTimeContainer> {
bool started_ : 1; // The timeline has been started.
bool paused_ : 1; // The timeline is paused.
+ const bool should_dispatch_events_ : 1;
bool document_order_indexes_dirty_ : 1;
bool is_updating_intervals_;
TaskRunnerTimer<SMILTimeContainer> wakeup_timer_;
- TaskRunnerTimer<SMILTimeContainer> animation_policy_once_timer_;
using AnimatedTargets = HeapHashCountedSet<WeakMember<SVGElement>>;
AnimatedTargets animated_targets_;
- HeapHashSet<Member<SVGSMILElement>> pending_discards_;
PriorityQueue<SMILTime, SVGSMILElement> priority_queue_;
diff --git a/chromium/third_party/blink/renderer/core/svg/animation/smil_time_container_test.cc b/chromium/third_party/blink/renderer/core/svg/animation/smil_time_container_test.cc
new file mode 100644
index 00000000000..7af0c153fe3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/svg/animation/smil_time_container_test.cc
@@ -0,0 +1,533 @@
+// 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/svg/animation/smil_time_container.h"
+
+#include "third_party/blink/renderer/core/animation/document_timeline.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/dom/element_traversal.h"
+#include "third_party/blink/renderer/core/dom/events/native_event_listener.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/svg/svg_document_extensions.h"
+#include "third_party/blink/renderer/core/svg/svg_length.h"
+#include "third_party/blink/renderer/core/svg/svg_length_context.h"
+#include "third_party/blink/renderer/core/svg/svg_rect_element.h"
+#include "third_party/blink/renderer/core/svg/svg_svg_element.h"
+#include "third_party/blink/renderer/core/testing/page_test_base.h"
+#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
+
+namespace blink {
+namespace {
+
+class ContentLoadedEventListener final : public NativeEventListener {
+ public:
+ using CallbackType = base::OnceCallback<void(Document&)>;
+ explicit ContentLoadedEventListener(CallbackType callback)
+ : callback_(std::move(callback)) {}
+
+ void Invoke(ExecutionContext* execution_context, Event*) override {
+ std::move(callback_).Run(*Document::From(execution_context));
+ }
+
+ private:
+ CallbackType callback_;
+};
+
+class SMILTimeContainerAnimationPolicyOnceTest : public PageTestBase {
+ public:
+ void SetUp() override {
+ EnablePlatform();
+ platform()->SetAutoAdvanceNowToPendingTasks(false);
+ PageTestBase::SetupPageWithClients(nullptr, nullptr, &OverrideSettings);
+ }
+
+ void Load(base::span<const char> data) {
+ auto params = WebNavigationParams::CreateWithHTMLString(
+ data, KURL("http://example.com"));
+ GetFrame().Loader().CommitNavigation(std::move(params),
+ nullptr /* extra_data */);
+ GetAnimationClock().ResetTimeForTesting();
+ GetAnimationClock().SetAllowedToDynamicallyUpdateTime(false);
+ GetDocument().Timeline().ResetForTesting();
+ }
+
+ void StepTime(base::TimeDelta delta) {
+ platform()->RunForPeriod(delta);
+ current_time_ += delta;
+ GetAnimationClock().UpdateTime(current_time_);
+ SVGDocumentExtensions::ServiceOnAnimationFrame(GetDocument());
+ }
+
+ void OnContentLoaded(base::OnceCallback<void(Document&)> callback) {
+ GetFrame().DomWindow()->addEventListener(
+ event_type_names::kDOMContentLoaded,
+ MakeGarbageCollected<ContentLoadedEventListener>(std::move(callback)));
+ }
+
+ private:
+ static void OverrideSettings(Settings& settings) {
+ settings.SetImageAnimationPolicy(kImageAnimationPolicyAnimateOnce);
+ }
+
+ base::TimeTicks current_time_;
+};
+
+TEST_F(SMILTimeContainerAnimationPolicyOnceTest, NoAction) {
+ Load(R"HTML(
+ <svg id="container">
+ <rect width="100" height="0" fill="green">
+ <animate begin="0s" dur="3s" repeatCount="indefinite"
+ attributeName="height" values="30;50;100" calcMode="discrete"/>
+ </rect>
+ </svg>
+ )HTML");
+ platform()->RunUntilIdle();
+
+ auto* svg_root = To<SVGSVGElement>(GetElementById("container"));
+ ASSERT_TRUE(svg_root);
+ auto* rect = Traversal<SVGRectElement>::FirstChild(*svg_root);
+ ASSERT_TRUE(rect);
+ SVGLengthContext length_context(rect);
+
+ SMILTimeContainer* time_container = svg_root->TimeContainer();
+ EXPECT_TRUE(time_container->IsStarted());
+ EXPECT_FALSE(time_container->IsPaused());
+ EXPECT_EQ(30, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(2500));
+ EXPECT_EQ(100, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(500));
+ EXPECT_EQ(30, rect->height()->CurrentValue()->Value(length_context));
+ EXPECT_EQ(SMILTime::FromSecondsD(3), time_container->Elapsed());
+}
+
+TEST_F(SMILTimeContainerAnimationPolicyOnceTest, SetElapsedAfterStart) {
+ Load(R"HTML(
+ <svg id="container">
+ <rect width="100" height="0" fill="green">
+ <animate begin="0s" dur="3s" repeatCount="indefinite"
+ attributeName="height" values="30;50;100" calcMode="discrete"/>
+ </rect>
+ </svg>
+ )HTML");
+ platform()->RunUntilIdle();
+
+ auto* svg_root = To<SVGSVGElement>(GetElementById("container"));
+ ASSERT_TRUE(svg_root);
+ auto* rect = Traversal<SVGRectElement>::FirstChild(*svg_root);
+ ASSERT_TRUE(rect);
+ SVGLengthContext length_context(rect);
+
+ SMILTimeContainer* time_container = svg_root->TimeContainer();
+ EXPECT_TRUE(time_container->IsStarted());
+ EXPECT_FALSE(time_container->IsPaused());
+ time_container->SetElapsed(SMILTime::FromSecondsD(5.5));
+ EXPECT_EQ(SMILTime::FromSecondsD(5.5), time_container->Elapsed());
+ EXPECT_EQ(100, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(2000));
+ EXPECT_EQ(50, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(1000));
+ EXPECT_EQ(100, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(1000));
+ EXPECT_EQ(100, rect->height()->CurrentValue()->Value(length_context));
+ EXPECT_EQ(SMILTime::FromSecondsD(8.5), time_container->Elapsed());
+}
+
+TEST_F(SMILTimeContainerAnimationPolicyOnceTest, SetElapsedBeforeStart) {
+ Load(R"HTML(
+ <svg id="container">
+ <rect width="100" height="0" fill="green">
+ <animate begin="0s" dur="3s" repeatCount="indefinite"
+ attributeName="height" values="30;50;100" calcMode="discrete"/>
+ </rect>
+ </svg>
+ )HTML");
+ OnContentLoaded(WTF::Bind([](Document& document) {
+ auto* svg_root = To<SVGSVGElement>(document.getElementById("container"));
+ ASSERT_TRUE(svg_root);
+ auto* rect = Traversal<SVGRectElement>::FirstChild(*svg_root);
+ ASSERT_TRUE(rect);
+ SVGLengthContext length_context(rect);
+
+ SMILTimeContainer* time_container = svg_root->TimeContainer();
+ EXPECT_FALSE(time_container->IsStarted());
+ EXPECT_FALSE(time_container->IsPaused());
+ time_container->SetElapsed(SMILTime::FromSecondsD(5.5));
+ EXPECT_EQ(0, rect->height()->CurrentValue()->Value(length_context));
+ }));
+ platform()->RunUntilIdle();
+
+ auto* svg_root = To<SVGSVGElement>(GetElementById("container"));
+ ASSERT_TRUE(svg_root);
+ auto* rect = Traversal<SVGRectElement>::FirstChild(*svg_root);
+ ASSERT_TRUE(rect);
+ SVGLengthContext length_context(rect);
+
+ SMILTimeContainer* time_container = svg_root->TimeContainer();
+ EXPECT_TRUE(time_container->IsStarted());
+ EXPECT_FALSE(time_container->IsPaused());
+ EXPECT_EQ(SMILTime::FromSecondsD(5.5), time_container->Elapsed());
+ EXPECT_EQ(100, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(2000));
+ EXPECT_EQ(50, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(1000));
+ EXPECT_EQ(100, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(1000));
+ EXPECT_EQ(100, rect->height()->CurrentValue()->Value(length_context));
+ EXPECT_EQ(SMILTime::FromSecondsD(8.5), time_container->Elapsed());
+}
+
+TEST_F(SMILTimeContainerAnimationPolicyOnceTest, PauseAfterStart) {
+ Load(R"HTML(
+ <svg id="container">
+ <rect width="100" height="0" fill="green">
+ <animate begin="0s" dur="3s" repeatCount="indefinite"
+ attributeName="height" values="30;50;100" calcMode="discrete"/>
+ </rect>
+ </svg>
+ )HTML");
+ platform()->RunUntilIdle();
+
+ auto* svg_root = To<SVGSVGElement>(GetElementById("container"));
+ ASSERT_TRUE(svg_root);
+ auto* rect = Traversal<SVGRectElement>::FirstChild(*svg_root);
+ ASSERT_TRUE(rect);
+ SVGLengthContext length_context(rect);
+
+ SMILTimeContainer* time_container = svg_root->TimeContainer();
+ EXPECT_TRUE(time_container->IsStarted());
+ EXPECT_FALSE(time_container->IsPaused());
+ EXPECT_EQ(30, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(1500));
+ EXPECT_EQ(50, rect->height()->CurrentValue()->Value(length_context));
+
+ time_container->Pause();
+ EXPECT_TRUE(time_container->IsPaused());
+ EXPECT_EQ(SMILTime::FromSecondsD(1.5), time_container->Elapsed());
+
+ time_container->Unpause();
+ EXPECT_FALSE(time_container->IsPaused());
+ EXPECT_EQ(SMILTime::FromSecondsD(1.5), time_container->Elapsed());
+
+ StepTime(base::TimeDelta::FromMilliseconds(4000));
+ EXPECT_EQ(50, rect->height()->CurrentValue()->Value(length_context));
+ EXPECT_EQ(SMILTime::FromSecondsD(4.5), time_container->Elapsed());
+}
+
+TEST_F(SMILTimeContainerAnimationPolicyOnceTest, PauseBeforeStart) {
+ Load(R"HTML(
+ <svg id="container">
+ <rect width="100" height="0" fill="green">
+ <animate begin="0s" dur="3s" repeatCount="indefinite"
+ attributeName="height" values="30;50;100" calcMode="discrete"/>
+ </rect>
+ </svg>
+ )HTML");
+ OnContentLoaded(WTF::Bind([](Document& document) {
+ auto* svg_root = To<SVGSVGElement>(document.getElementById("container"));
+ ASSERT_TRUE(svg_root);
+ auto* rect = Traversal<SVGRectElement>::FirstChild(*svg_root);
+ ASSERT_TRUE(rect);
+ SVGLengthContext length_context(rect);
+
+ SMILTimeContainer* time_container = svg_root->TimeContainer();
+ EXPECT_FALSE(time_container->IsStarted());
+ EXPECT_FALSE(time_container->IsPaused());
+ time_container->Pause();
+ EXPECT_TRUE(time_container->IsPaused());
+ EXPECT_EQ(0, rect->height()->CurrentValue()->Value(length_context));
+ }));
+ platform()->RunUntilIdle();
+
+ auto* svg_root = To<SVGSVGElement>(GetElementById("container"));
+ ASSERT_TRUE(svg_root);
+ auto* rect = Traversal<SVGRectElement>::FirstChild(*svg_root);
+ ASSERT_TRUE(rect);
+ SVGLengthContext length_context(rect);
+
+ SMILTimeContainer* time_container = svg_root->TimeContainer();
+ EXPECT_TRUE(time_container->IsStarted());
+ EXPECT_TRUE(time_container->IsPaused());
+ EXPECT_EQ(30, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(1500));
+ EXPECT_EQ(SMILTime::FromSecondsD(0), time_container->Elapsed());
+ EXPECT_EQ(30, rect->height()->CurrentValue()->Value(length_context));
+
+ time_container->Unpause();
+ EXPECT_FALSE(time_container->IsPaused());
+ EXPECT_EQ(SMILTime::FromSecondsD(0), time_container->Elapsed());
+
+ StepTime(base::TimeDelta::FromMilliseconds(1500));
+ EXPECT_EQ(50, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(2500));
+ EXPECT_EQ(30, rect->height()->CurrentValue()->Value(length_context));
+ EXPECT_EQ(SMILTime::FromSecondsD(3), time_container->Elapsed());
+}
+
+TEST_F(SMILTimeContainerAnimationPolicyOnceTest, PauseAndSetElapsedAfterStart) {
+ Load(R"HTML(
+ <svg id="container">
+ <rect width="100" height="0" fill="green">
+ <animate begin="0s" dur="3s" repeatCount="indefinite"
+ attributeName="height" values="30;50;100" calcMode="discrete"/>
+ </rect>
+ </svg>
+ )HTML");
+ platform()->RunUntilIdle();
+
+ auto* svg_root = To<SVGSVGElement>(GetElementById("container"));
+ ASSERT_TRUE(svg_root);
+ auto* rect = Traversal<SVGRectElement>::FirstChild(*svg_root);
+ ASSERT_TRUE(rect);
+ SVGLengthContext length_context(rect);
+
+ SMILTimeContainer* time_container = svg_root->TimeContainer();
+ EXPECT_TRUE(time_container->IsStarted());
+ EXPECT_FALSE(time_container->IsPaused());
+ EXPECT_EQ(30, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(1500));
+ EXPECT_EQ(50, rect->height()->CurrentValue()->Value(length_context));
+
+ time_container->Pause();
+ EXPECT_TRUE(time_container->IsPaused());
+ EXPECT_EQ(SMILTime::FromSecondsD(1.5), time_container->Elapsed());
+
+ time_container->SetElapsed(SMILTime::FromSecondsD(0.5));
+ EXPECT_EQ(SMILTime::FromSecondsD(0.5), time_container->Elapsed());
+
+ time_container->Unpause();
+ EXPECT_FALSE(time_container->IsPaused());
+ EXPECT_EQ(SMILTime::FromSecondsD(0.5), time_container->Elapsed());
+
+ StepTime(base::TimeDelta::FromMilliseconds(4000));
+ EXPECT_EQ(30, rect->height()->CurrentValue()->Value(length_context));
+ EXPECT_EQ(SMILTime::FromSecondsD(3.5), time_container->Elapsed());
+}
+
+TEST_F(SMILTimeContainerAnimationPolicyOnceTest,
+ PauseAndSetElapsedBeforeStart) {
+ Load(R"HTML(
+ <svg id="container">
+ <rect width="100" height="0" fill="green">
+ <animate begin="0s" dur="3s" repeatCount="indefinite"
+ attributeName="height" values="30;50;100" calcMode="discrete"/>
+ </rect>
+ </svg>
+ )HTML");
+ OnContentLoaded(WTF::Bind([](Document& document) {
+ auto* svg_root = To<SVGSVGElement>(document.getElementById("container"));
+ ASSERT_TRUE(svg_root);
+ auto* rect = Traversal<SVGRectElement>::FirstChild(*svg_root);
+ ASSERT_TRUE(rect);
+ SVGLengthContext length_context(rect);
+
+ SMILTimeContainer* time_container = svg_root->TimeContainer();
+ EXPECT_FALSE(time_container->IsStarted());
+ EXPECT_FALSE(time_container->IsPaused());
+ time_container->Pause();
+ EXPECT_TRUE(time_container->IsPaused());
+ time_container->SetElapsed(SMILTime::FromSecondsD(1.5));
+ EXPECT_TRUE(time_container->IsPaused());
+ EXPECT_EQ(0, rect->height()->CurrentValue()->Value(length_context));
+ }));
+ platform()->RunUntilIdle();
+
+ auto* svg_root = To<SVGSVGElement>(GetElementById("container"));
+ ASSERT_TRUE(svg_root);
+ auto* rect = Traversal<SVGRectElement>::FirstChild(*svg_root);
+ ASSERT_TRUE(rect);
+ SVGLengthContext length_context(rect);
+
+ SMILTimeContainer* time_container = svg_root->TimeContainer();
+ EXPECT_TRUE(time_container->IsStarted());
+ EXPECT_TRUE(time_container->IsPaused());
+ EXPECT_EQ(SMILTime::FromSecondsD(1.5), time_container->Elapsed());
+ EXPECT_EQ(50, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(1500));
+ EXPECT_EQ(SMILTime::FromSecondsD(1.5), time_container->Elapsed());
+ EXPECT_EQ(50, rect->height()->CurrentValue()->Value(length_context));
+
+ time_container->Unpause();
+ EXPECT_FALSE(time_container->IsPaused());
+ EXPECT_EQ(SMILTime::FromSecondsD(1.5), time_container->Elapsed());
+
+ StepTime(base::TimeDelta::FromMilliseconds(2000));
+ EXPECT_EQ(30, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(2000));
+ EXPECT_EQ(50, rect->height()->CurrentValue()->Value(length_context));
+ EXPECT_EQ(SMILTime::FromSecondsD(4.5), time_container->Elapsed());
+}
+
+TEST_F(SMILTimeContainerAnimationPolicyOnceTest, PauseAndResumeBeforeStart) {
+ Load(R"HTML(
+ <svg id="container">
+ <rect width="100" height="0" fill="green">
+ <animate begin="0s" dur="3s" repeatCount="indefinite"
+ attributeName="height" values="30;50;100" calcMode="discrete"/>
+ </rect>
+ </svg>
+ )HTML");
+ OnContentLoaded(WTF::Bind([](Document& document) {
+ auto* svg_root = To<SVGSVGElement>(document.getElementById("container"));
+ ASSERT_TRUE(svg_root);
+ auto* rect = Traversal<SVGRectElement>::FirstChild(*svg_root);
+ ASSERT_TRUE(rect);
+ SVGLengthContext length_context(rect);
+
+ SMILTimeContainer* time_container = svg_root->TimeContainer();
+ EXPECT_FALSE(time_container->IsStarted());
+ EXPECT_FALSE(time_container->IsPaused());
+ time_container->Pause();
+ EXPECT_TRUE(time_container->IsPaused());
+ time_container->Unpause();
+ EXPECT_FALSE(time_container->IsPaused());
+ EXPECT_EQ(0, rect->height()->CurrentValue()->Value(length_context));
+ }));
+ platform()->RunUntilIdle();
+
+ auto* svg_root = To<SVGSVGElement>(GetElementById("container"));
+ ASSERT_TRUE(svg_root);
+ auto* rect = Traversal<SVGRectElement>::FirstChild(*svg_root);
+ ASSERT_TRUE(rect);
+ SVGLengthContext length_context(rect);
+
+ SMILTimeContainer* time_container = svg_root->TimeContainer();
+ EXPECT_TRUE(time_container->IsStarted());
+ EXPECT_FALSE(time_container->IsPaused());
+ EXPECT_EQ(30, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(2500));
+ EXPECT_EQ(100, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(500));
+ EXPECT_EQ(30, rect->height()->CurrentValue()->Value(length_context));
+ EXPECT_EQ(SMILTime::FromSecondsD(3), time_container->Elapsed());
+}
+
+TEST_F(SMILTimeContainerAnimationPolicyOnceTest, PauseAndResumeAfterSuspended) {
+ Load(R"HTML(
+ <svg id="container">
+ <rect width="100" height="0" fill="green">
+ <animate begin="0s" dur="3s" repeatCount="indefinite"
+ attributeName="height" values="30;50;100" calcMode="discrete"/>
+ </rect>
+ </svg>
+ )HTML");
+ platform()->RunUntilIdle();
+
+ auto* svg_root = To<SVGSVGElement>(GetElementById("container"));
+ ASSERT_TRUE(svg_root);
+ auto* rect = Traversal<SVGRectElement>::FirstChild(*svg_root);
+ ASSERT_TRUE(rect);
+ SVGLengthContext length_context(rect);
+
+ SMILTimeContainer* time_container = svg_root->TimeContainer();
+ EXPECT_TRUE(time_container->IsStarted());
+ EXPECT_FALSE(time_container->IsPaused());
+ EXPECT_EQ(SMILTime::FromSecondsD(0), time_container->Elapsed());
+ EXPECT_EQ(30, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(1000));
+ EXPECT_EQ(SMILTime::FromSecondsD(1.0), time_container->Elapsed());
+ EXPECT_EQ(50, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(1000));
+ EXPECT_EQ(SMILTime::FromSecondsD(2.0), time_container->Elapsed());
+ EXPECT_EQ(100, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(1500));
+ EXPECT_EQ(SMILTime::FromSecondsD(3.0), time_container->Elapsed());
+ EXPECT_EQ(30, rect->height()->CurrentValue()->Value(length_context));
+
+ time_container->Pause();
+ EXPECT_TRUE(time_container->IsPaused());
+ EXPECT_EQ(SMILTime::FromSecondsD(3.0), time_container->Elapsed());
+
+ time_container->Unpause();
+ EXPECT_FALSE(time_container->IsPaused());
+ EXPECT_EQ(SMILTime::FromSecondsD(3.0), time_container->Elapsed());
+
+ StepTime(base::TimeDelta::FromMilliseconds(1000));
+ EXPECT_EQ(SMILTime::FromSecondsD(4.0), time_container->Elapsed());
+ EXPECT_EQ(50, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(1000));
+ EXPECT_EQ(SMILTime::FromSecondsD(5.0), time_container->Elapsed());
+ EXPECT_EQ(100, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(1500));
+ EXPECT_EQ(30, rect->height()->CurrentValue()->Value(length_context));
+ EXPECT_EQ(SMILTime::FromSecondsD(6.0), time_container->Elapsed());
+}
+
+TEST_F(SMILTimeContainerAnimationPolicyOnceTest, SetElapsedAfterSuspended) {
+ Load(R"HTML(
+ <svg id="container">
+ <rect width="100" height="0" fill="green">
+ <animate begin="0s" dur="3s" repeatCount="indefinite"
+ attributeName="height" values="30;50;100" calcMode="discrete"/>
+ </rect>
+ </svg>
+ )HTML");
+ platform()->RunUntilIdle();
+
+ auto* svg_root = To<SVGSVGElement>(GetElementById("container"));
+ ASSERT_TRUE(svg_root);
+ auto* rect = Traversal<SVGRectElement>::FirstChild(*svg_root);
+ ASSERT_TRUE(rect);
+ SVGLengthContext length_context(rect);
+
+ SMILTimeContainer* time_container = svg_root->TimeContainer();
+ EXPECT_TRUE(time_container->IsStarted());
+ EXPECT_FALSE(time_container->IsPaused());
+ EXPECT_EQ(SMILTime::FromSecondsD(0), time_container->Elapsed());
+ EXPECT_EQ(30, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(1000));
+ EXPECT_EQ(SMILTime::FromSecondsD(1.0), time_container->Elapsed());
+ EXPECT_EQ(50, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(1000));
+ EXPECT_EQ(SMILTime::FromSecondsD(2.0), time_container->Elapsed());
+ EXPECT_EQ(100, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(1500));
+ EXPECT_EQ(SMILTime::FromSecondsD(3.0), time_container->Elapsed());
+ EXPECT_EQ(30, rect->height()->CurrentValue()->Value(length_context));
+
+ time_container->SetElapsed(SMILTime::FromSecondsD(5.5));
+ EXPECT_FALSE(time_container->IsPaused());
+ EXPECT_EQ(SMILTime::FromSecondsD(5.5), time_container->Elapsed());
+ EXPECT_EQ(100, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(1000));
+ EXPECT_EQ(SMILTime::FromSecondsD(6.5), time_container->Elapsed());
+ EXPECT_EQ(30, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(1000));
+ EXPECT_EQ(SMILTime::FromSecondsD(7.5), time_container->Elapsed());
+ EXPECT_EQ(50, rect->height()->CurrentValue()->Value(length_context));
+
+ StepTime(base::TimeDelta::FromMilliseconds(1500));
+ EXPECT_EQ(100, rect->height()->CurrentValue()->Value(length_context));
+ EXPECT_EQ(SMILTime::FromSecondsD(8.5), time_container->Elapsed());
+}
+
+} // namespace
+} // namespace blink
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 697d4c9b703..016afbac7c9 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
@@ -65,6 +65,57 @@ SMILTime ComputeNextRepeatTime(SMILTime interval_begin,
} // namespace
+void SMILInstanceTimeList::Append(SMILTime time, SMILTimeOrigin origin) {
+ instance_times_.push_back(SMILTimeWithOrigin(time, origin));
+ AddOrigin(origin);
+}
+
+void SMILInstanceTimeList::InsertSortedAndUnique(SMILTime time,
+ SMILTimeOrigin origin) {
+ SMILTimeWithOrigin time_with_origin(time, origin);
+ auto* position = std::lower_bound(instance_times_.begin(),
+ instance_times_.end(), time_with_origin);
+ // Don't add it if we already have one of those.
+ for (auto* it = position; it != instance_times_.end(); ++it) {
+ if (position->Time() != time)
+ break;
+ // If they share both time and origin, we don't need to add it,
+ // we just need to react.
+ if (position->Origin() == origin)
+ return;
+ }
+ instance_times_.insert(position - instance_times_.begin(), time_with_origin);
+ AddOrigin(origin);
+}
+
+void SMILInstanceTimeList::RemoveWithOrigin(SMILTimeOrigin origin) {
+ if (!HasOrigin(origin))
+ return;
+ auto* tail =
+ std::remove_if(instance_times_.begin(), instance_times_.end(),
+ [origin](const SMILTimeWithOrigin& instance_time) {
+ return instance_time.Origin() == origin;
+ });
+ instance_times_.Shrink(tail - instance_times_.begin());
+ ClearOrigin(origin);
+}
+
+void SMILInstanceTimeList::Sort() {
+ std::sort(instance_times_.begin(), instance_times_.end());
+}
+
+SMILTime SMILInstanceTimeList::NextAfter(SMILTime time) const {
+ // Find the value in |list| that is strictly greater than |time|.
+ auto* next_item = std::lower_bound(
+ instance_times_.begin(), instance_times_.end(), time,
+ [](const SMILTimeWithOrigin& instance_time, const SMILTime& time) {
+ return instance_time.Time() <= time;
+ });
+ if (next_item == instance_times_.end())
+ return SMILTime::Unresolved();
+ return next_item->Time();
+}
+
// This is used for duration type time values that can't be negative.
static constexpr SMILTime kInvalidCachedTime = SMILTime::Earliest();
@@ -84,7 +135,7 @@ class ConditionEventListener final : public NativeEventListener {
animation_->Elapsed() + condition_->Offset(), SMILTimeOrigin::kEvent);
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(animation_);
visitor->Trace(condition_);
NativeEventListener::Trace(visitor);
@@ -110,7 +161,7 @@ SVGSMILElement::Condition::Condition(Type type,
SVGSMILElement::Condition::~Condition() = default;
-void SVGSMILElement::Condition::Trace(blink::Visitor* visitor) {
+void SVGSMILElement::Condition::Trace(Visitor* visitor) {
visitor->Trace(base_element_);
visitor->Trace(base_id_observer_);
visitor->Trace(event_listener_);
@@ -241,15 +292,6 @@ void SVGSMILElement::BuildPendingResource() {
ConnectConditions();
}
-static inline void RemoveInstanceTimesWithOrigin(
- Vector<SMILTimeWithOrigin>& time_list,
- SMILTimeOrigin origin) {
- for (int i = time_list.size() - 1; i >= 0; --i) {
- if (time_list[i].Origin() == origin)
- time_list.EraseAt(i);
- }
-}
-
void SVGSMILElement::Reset() {
active_state_ = kInactive;
is_waiting_for_first_interval_ = true;
@@ -281,10 +323,8 @@ Node::InsertionNotificationRequest SVGSMILElement::InsertedInto(
// "If no attribute is present, the default begin value (an offset-value of 0)
// must be evaluated."
- if (!FastHasAttribute(svg_names::kBeginAttr) && begin_times_.IsEmpty()) {
- begin_times_.push_back(
- SMILTimeWithOrigin(SMILTime(), SMILTimeOrigin::kAttribute));
- }
+ if (!FastHasAttribute(svg_names::kBeginAttr) && begin_times_.IsEmpty())
+ begin_times_.Append(SMILTime(), SMILTimeOrigin::kAttribute);
BuildPendingResource();
return kInsertionDone;
@@ -431,34 +471,30 @@ bool SVGSMILElement::ParseCondition(const String& value,
void SVGSMILElement::ParseBeginOrEnd(const String& parse_string,
BeginOrEnd begin_or_end) {
- Vector<SMILTimeWithOrigin>& time_list =
- begin_or_end == kBegin ? begin_times_ : end_times_;
+ auto& time_list = begin_or_end == kBegin ? begin_times_ : end_times_;
if (begin_or_end == kEnd)
has_end_event_conditions_ = false;
// Remove any previously added offset-values.
// TODO(fs): Ought to remove instance times originating from sync-bases,
// events etc. as well if those conditions are no longer in the attribute.
- RemoveInstanceTimesWithOrigin(time_list, SMILTimeOrigin::kAttribute);
+ time_list.RemoveWithOrigin(SMILTimeOrigin::kAttribute);
Vector<String> split_string;
parse_string.Split(';', split_string);
for (const auto& item : split_string) {
SMILTime value = ParseClockValue(item);
- if (value.IsUnresolved()) {
+ if (value.IsUnresolved())
ParseCondition(item, begin_or_end);
- } else {
- time_list.push_back(
- SMILTimeWithOrigin(value, SMILTimeOrigin::kAttribute));
- }
+ else
+ time_list.Append(value, SMILTimeOrigin::kAttribute);
}
// "If no attribute is present, the default begin value (an offset-value of 0)
// must be evaluated."
- if (begin_or_end == kBegin && parse_string.IsNull()) {
- begin_times_.push_back(
- SMILTimeWithOrigin(SMILTime(), SMILTimeOrigin::kAttribute));
- }
- std::sort(time_list.begin(), time_list.end());
+ if (begin_or_end == kBegin && parse_string.IsNull())
+ begin_times_.Append(SMILTime(), SMILTimeOrigin::kAttribute);
+
+ time_list.Sort();
}
void SVGSMILElement::ParseAttribute(const AttributeModificationParams& params) {
@@ -530,6 +566,14 @@ void SVGSMILElement::SvgAttributeChanged(const QualifiedName& attr_name) {
SVGElement::SvgAttributeChanged(attr_name);
}
+bool SVGSMILElement::IsPresentationAttribute(
+ const QualifiedName& attr_name) const {
+ // Don't map 'fill' to the 'fill' property for animation elements.
+ if (attr_name == svg_names::kFillAttr)
+ return false;
+ return SVGElement::IsPresentationAttribute(attr_name);
+}
+
void SVGSMILElement::ConnectConditions() {
if (conditions_connected_)
DisconnectConditions();
@@ -655,27 +699,11 @@ SMILTime SVGSMILElement::SimpleDuration() const {
return std::min(Dur(), SMILTime::Indefinite());
}
-static void InsertSortedAndUnique(Vector<SMILTimeWithOrigin>& list,
- SMILTimeWithOrigin time) {
- auto* position = std::lower_bound(list.begin(), list.end(), time);
- // Don't add it if we already have one of those.
- for (auto* it = position; it < list.end(); ++it) {
- if (position->Time() != time.Time())
- break;
- // If they share both time and origin, we don't need to add it,
- // we just need to react.
- if (position->Origin() == time.Origin())
- return;
- }
- list.insert(position - list.begin(), time);
-}
-
void SVGSMILElement::AddInstanceTime(BeginOrEnd begin_or_end,
SMILTime time,
SMILTimeOrigin origin) {
- Vector<SMILTimeWithOrigin>& list =
- begin_or_end == kBegin ? begin_times_ : end_times_;
- InsertSortedAndUnique(list, SMILTimeWithOrigin(time, origin));
+ auto& list = begin_or_end == kBegin ? begin_times_ : end_times_;
+ list.InsertSortedAndUnique(time, origin);
instance_lists_have_changed_ = true;
}
@@ -691,30 +719,6 @@ void SVGSMILElement::AddInstanceTimeAndUpdate(BeginOrEnd begin_or_end,
InstanceListChanged();
}
-SMILTime SVGSMILElement::NextAfter(BeginOrEnd begin_or_end,
- SMILTime time) const {
- const Vector<SMILTimeWithOrigin>& list =
- begin_or_end == kBegin ? begin_times_ : end_times_;
- if (list.IsEmpty()) {
- return begin_or_end == kBegin ? SMILTime::Unresolved()
- : SMILTime::Indefinite();
- }
- // Find the value in |list| that is strictly greater than |time|.
- auto* next_item = std::lower_bound(
- list.begin(), list.end(), time,
- [](const SMILTimeWithOrigin& instance_time, const SMILTime& time) {
- return instance_time.Time() <= time;
- });
- if (next_item == list.end())
- return SMILTime::Unresolved();
- SMILTime next = next_item->Time();
- // The special value "indefinite" does not yield an instance time in the
- // begin list.
- if (begin_or_end == kBegin && next.IsIndefinite())
- return SMILTime::Unresolved();
- return next;
-}
-
SMILTime SVGSMILElement::RepeatingDuration() const {
// Computing the active duration
// http://www.w3.org/TR/SMIL2/smil-timing.html#Timing-ComputingActiveDur
@@ -732,11 +736,16 @@ SMILTime SVGSMILElement::RepeatingDuration() const {
}
SMILTime SVGSMILElement::ResolveActiveEnd(SMILTime resolved_begin) const {
- SMILTime resolved_end = NextAfter(kEnd, resolved_begin);
- if (resolved_end.IsUnresolved()) {
- // If we have no pending end conditions, don't generate a new interval.
- if (!end_times_.IsEmpty() && !has_end_event_conditions_)
- return SMILTime::Unresolved();
+ SMILTime resolved_end = SMILTime::Indefinite();
+ if (!end_times_.IsEmpty()) {
+ SMILTime next_end = end_times_.NextAfter(resolved_begin);
+ if (next_end.IsUnresolved()) {
+ // If we have no pending end conditions, don't generate a new interval.
+ if (!has_end_event_conditions_)
+ return SMILTime::Unresolved();
+ } else {
+ resolved_end = next_end;
+ }
}
// Computing the active duration
// http://www.w3.org/TR/SMIL2/smil-timing.html#Timing-ComputingActiveDur
@@ -809,12 +818,14 @@ void SVGSMILElement::SetNewIntervalEnd(SMILTime new_end) {
}
SMILTime SVGSMILElement::ComputeNextIntervalTime(
- SMILTime presentation_time) const {
+ SMILTime presentation_time,
+ IncludeRepeats include_repeats) const {
SMILTime next_interval_time = SMILTime::Unresolved();
if (interval_.BeginsAfter(presentation_time)) {
next_interval_time = interval_.begin;
} else if (interval_.EndsAfter(presentation_time)) {
- if (SMILTime simple_duration = SimpleDuration()) {
+ SMILTime simple_duration = SimpleDuration();
+ if (include_repeats == kIncludeRepeats && simple_duration) {
SMILTime next_repeat_time = ComputeNextRepeatTime(
interval_.begin, simple_duration, presentation_time);
DCHECK(next_repeat_time.IsFinite());
@@ -823,7 +834,12 @@ SMILTime SVGSMILElement::ComputeNextIntervalTime(
next_interval_time = interval_.end;
}
}
- return std::min(next_interval_time, NextAfter(kBegin, presentation_time));
+ SMILTime next_begin = begin_times_.NextAfter(presentation_time);
+ // The special value "indefinite" does not yield an instance time in the
+ // begin list, so only consider finite values here.
+ if (next_begin.IsFinite())
+ next_interval_time = std::min(next_interval_time, next_begin);
+ return next_interval_time;
}
void SVGSMILElement::InstanceListChanged() {
@@ -852,10 +868,12 @@ void SVGSMILElement::InstanceListChanged() {
// If we switched interval and the previous interval did not end yet, we
// need to consider it when computing the next interval time.
if (previous_interval_.IsResolved() &&
- previous_interval_.EndsAfter(previous_presentation_time))
+ previous_interval_.EndsAfter(previous_presentation_time)) {
next_interval_time = previous_interval_.end;
- else
- next_interval_time = ComputeNextIntervalTime(previous_presentation_time);
+ } else {
+ next_interval_time =
+ ComputeNextIntervalTime(previous_presentation_time, kIncludeRepeats);
+ }
time_container_->Reschedule(this, next_interval_time);
}
}
@@ -895,7 +913,7 @@ bool SVGSMILElement::HandleIntervalRestart(SMILTime presentation_time) {
if (!interval_.IsResolved() || interval_.EndsBefore(presentation_time))
return true;
if (restart == kRestartAlways) {
- SMILTime next_begin = NextAfter(kBegin, interval_.begin);
+ SMILTime next_begin = begin_times_.NextAfter(interval_.begin);
if (interval_.EndsAfter(next_begin)) {
SetNewIntervalEnd(next_begin);
return interval_.EndsBefore(presentation_time);
@@ -904,6 +922,23 @@ bool SVGSMILElement::HandleIntervalRestart(SMILTime presentation_time) {
return false;
}
+SMILTime SVGSMILElement::LastIntervalEndTime() const {
+ // If we're still waiting for the first interval we lack a time reference.
+ if (!is_waiting_for_first_interval_) {
+ // If we have a current interval (which likely just ended or restarted) use
+ // the end of that.
+ if (interval_.IsResolved())
+ return interval_.end;
+ // If we don't have a current interval (maybe because it got discarded for
+ // not having started yet) but we have a previous interval, then use the
+ // end of that.
+ if (previous_interval_.IsResolved())
+ return previous_interval_.end;
+ }
+ // We have to start from the beginning.
+ return SMILTime::Earliest();
+}
+
void SVGSMILElement::UpdateInterval(SMILTime presentation_time) {
if (instance_lists_have_changed_) {
instance_lists_have_changed_ = false;
@@ -911,10 +946,7 @@ void SVGSMILElement::UpdateInterval(SMILTime presentation_time) {
}
if (!HandleIntervalRestart(presentation_time))
return;
- SMILTime begin_after =
- !is_waiting_for_first_interval_ && interval_.IsResolved()
- ? interval_.end
- : SMILTime::Earliest();
+ SMILTime begin_after = LastIntervalEndTime();
SMILInterval next_interval = ResolveInterval(begin_after, presentation_time);
// It's the same interval that we resolved before. Do nothing.
if (next_interval == interval_)
@@ -943,7 +975,8 @@ void SVGSMILElement::AddedToTimeContainer() {
current_presentation_time - SMILTime::Epsilon();
active_state_ = DetermineActiveState(interval_, previous_presentation_time);
time_container_->Reschedule(
- this, ComputeNextIntervalTime(previous_presentation_time));
+ this,
+ ComputeNextIntervalTime(previous_presentation_time, kIncludeRepeats));
// If there's an active interval, then revalidate the animation value.
if (GetActiveState() != kInactive)
@@ -1056,32 +1089,85 @@ bool SVGSMILElement::IsContributing(SMILTime elapsed) const {
GetActiveState() == kFrozen;
}
-void SVGSMILElement::UpdateActiveState(SMILTime elapsed) {
+SVGSMILElement::EventDispatchMask SVGSMILElement::UpdateActiveState(
+ SMILTime presentation_time,
+ bool skip_repeat) {
const bool was_active = GetActiveState() == kActive;
- active_state_ = DetermineActiveState(interval_, elapsed);
+ active_state_ = DetermineActiveState(interval_, presentation_time);
const bool is_active = GetActiveState() == kActive;
const bool interval_restart =
interval_has_changed_ && previous_interval_.end == interval_.begin;
interval_has_changed_ = false;
+ unsigned events_to_dispatch = kDispatchNoEvent;
if ((was_active && !is_active) || interval_restart) {
- ScheduleEvent(event_type_names::kEndEvent);
+ events_to_dispatch |= kDispatchEndEvent;
EndedActiveInterval();
}
- if (IsContributing(elapsed)) {
- if (!was_active || interval_restart) {
- ScheduleEvent(event_type_names::kBeginEvent);
+ if (IsContributing(presentation_time)) {
+ if ((!was_active && is_active) || interval_restart) {
+ events_to_dispatch |= kDispatchBeginEvent;
StartedActiveInterval();
}
- ProgressState progress_state = CalculateProgressState(elapsed);
- if (progress_state.repeat &&
- progress_state.repeat != last_progress_.repeat) {
- NotifyDependentsOnRepeat(progress_state.repeat, elapsed);
- ScheduleRepeatEvents();
+ if (!skip_repeat) {
+ // TODO(fs): This is a bit fragile. Convert to be time-based (rather than
+ // based on |last_progress_|) and thus (at least more) idempotent.
+ ProgressState progress_state = CalculateProgressState(presentation_time);
+ if (progress_state.repeat &&
+ progress_state.repeat != last_progress_.repeat) {
+ NotifyDependentsOnRepeat(progress_state.repeat, presentation_time);
+ events_to_dispatch |= kDispatchRepeatEvent;
+ }
+ last_progress_ = progress_state;
}
- last_progress_ = progress_state;
+ }
+ return static_cast<EventDispatchMask>(events_to_dispatch);
+}
+
+SVGSMILElement::EventDispatchMask SVGSMILElement::ComputeSeekEvents(
+ const SMILInterval& starting_interval) const {
+ // Is the element active at the seeked-to time?
+ if (GetActiveState() != SVGSMILElement::kActive) {
+ // Was the element active at the previous time?
+ if (!starting_interval.IsResolved())
+ return kDispatchNoEvent;
+ // Dispatch an 'endEvent' for ending |starting_interval|.
+ return kDispatchEndEvent;
+ }
+ // Was the element active at the previous time?
+ if (starting_interval.IsResolved()) {
+ // The same interval?
+ if (interval_ == starting_interval)
+ return kDispatchNoEvent;
+ // Dispatch an 'endEvent' for ending |starting_interval| and a 'beginEvent'
+ // for beginning the current interval.
+ unsigned to_dispatch = kDispatchBeginEvent | kDispatchEndEvent;
+ return static_cast<EventDispatchMask>(to_dispatch);
+ }
+ // Was not active at the previous time. Dispatch a 'beginEvent' for beginning
+ // the current interval.
+ return kDispatchBeginEvent;
+}
+
+void SVGSMILElement::DispatchEvents(EventDispatchMask events_to_dispatch) {
+ // The ordering is based on the usual order in which these events should be
+ // dispatched (and should match the order the flags are set in
+ // UpdateActiveState().
+ if (events_to_dispatch & kDispatchEndEvent) {
+ EnqueueEvent(*Event::Create(event_type_names::kEndEvent),
+ TaskType::kDOMManipulation);
+ }
+ if (events_to_dispatch & kDispatchBeginEvent) {
+ EnqueueEvent(*Event::Create(event_type_names::kBeginEvent),
+ TaskType::kDOMManipulation);
+ }
+ if (events_to_dispatch & kDispatchRepeatEvent) {
+ EnqueueEvent(*Event::Create(event_type_names::kRepeatEvent),
+ TaskType::kDOMManipulation);
+ EnqueueEvent(*Event::Create(AtomicString("repeatn")),
+ TaskType::kDOMManipulation);
}
}
@@ -1198,21 +1284,8 @@ void SVGSMILElement::StartedActiveInterval() {
}
void SVGSMILElement::EndedActiveInterval() {
- RemoveInstanceTimesWithOrigin(begin_times_, SMILTimeOrigin::kScript);
- RemoveInstanceTimesWithOrigin(end_times_, SMILTimeOrigin::kScript);
-}
-
-void SVGSMILElement::ScheduleRepeatEvents() {
- ScheduleEvent(event_type_names::kRepeatEvent);
- ScheduleEvent(AtomicString("repeatn"));
-}
-
-void SVGSMILElement::ScheduleEvent(const AtomicString& event_type) {
- DCHECK(event_type == event_type_names::kEndEvent ||
- event_type == event_type_names::kBeginEvent ||
- event_type == event_type_names::kRepeatEvent ||
- event_type == "repeatn");
- EnqueueEvent(*Event::Create(event_type), TaskType::kDOMManipulation);
+ begin_times_.RemoveWithOrigin(SMILTimeOrigin::kScript);
+ end_times_.RemoveWithOrigin(SMILTimeOrigin::kScript);
}
bool SVGSMILElement::HasValidTarget() const {
@@ -1238,12 +1311,7 @@ void SVGSMILElement::DidChangeAnimationTarget() {
is_scheduled_ = true;
}
-void SVGSMILElement::QueueDiscard() {
- if (time_container_)
- time_container_->QueueDiscard(this);
-}
-
-void SVGSMILElement::Trace(blink::Visitor* visitor) {
+void SVGSMILElement::Trace(Visitor* visitor) {
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 457a1d31020..436c4979bb6 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
@@ -33,7 +33,7 @@
#include "third_party/blink/renderer/core/svg/svg_tests.h"
#include "third_party/blink/renderer/core/svg_names.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/wtf/hash_map.h"
+#include "third_party/blink/renderer/platform/wtf/hash_set.h"
namespace blink {
@@ -42,6 +42,39 @@ class SMILTimeContainer;
class IdTargetObserver;
class SVGSMILElement;
+class CORE_EXPORT SMILInstanceTimeList {
+ public:
+ void Append(SMILTime, SMILTimeOrigin);
+ void InsertSortedAndUnique(SMILTime, SMILTimeOrigin);
+ void RemoveWithOrigin(SMILTimeOrigin);
+ void Sort();
+ SMILTime NextAfter(SMILTime) const;
+
+ wtf_size_t size() const { return instance_times_.size(); }
+ bool IsEmpty() const { return instance_times_.IsEmpty(); }
+
+ using const_iterator = typename Vector<SMILTimeWithOrigin>::const_iterator;
+ const_iterator begin() const { return instance_times_.begin(); }
+ const_iterator end() const { return instance_times_.end(); }
+
+ private:
+ static unsigned OriginToMask(SMILTimeOrigin origin) {
+ return 1u << static_cast<unsigned>(origin);
+ }
+ void AddOrigin(SMILTimeOrigin origin) {
+ time_origin_mask_ |= OriginToMask(origin);
+ }
+ void ClearOrigin(SMILTimeOrigin origin) {
+ time_origin_mask_ &= ~OriginToMask(origin);
+ }
+ bool HasOrigin(SMILTimeOrigin origin) const {
+ return (time_origin_mask_ & OriginToMask(origin)) != 0;
+ }
+
+ Vector<SMILTimeWithOrigin> instance_times_;
+ unsigned time_origin_mask_ = 0;
+};
+
// This class implements SMIL interval timing model as needed for SVG animation.
class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests {
USING_GARBAGE_COLLECTED_MIXIN(SVGSMILElement);
@@ -82,12 +115,24 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests {
SMILTime SimpleDuration() const;
void UpdateInterval(SMILTime presentation_time);
- void UpdateActiveState(SMILTime elapsed);
+ enum EventDispatchMask {
+ kDispatchNoEvent = 0,
+ kDispatchBeginEvent = 1u << 0,
+ kDispatchRepeatEvent = 1u << 1,
+ kDispatchEndEvent = 1u << 2,
+ };
+ EventDispatchMask UpdateActiveState(SMILTime presentation_time,
+ bool skip_repeat);
+ EventDispatchMask ComputeSeekEvents(
+ const SMILInterval& starting_interval) const;
+ void DispatchEvents(EventDispatchMask);
void UpdateProgressState(SMILTime presentation_time);
bool IsHigherPriorityThan(const SVGSMILElement* other,
SMILTime presentation_time) const;
- SMILTime ComputeNextIntervalTime(SMILTime presentation_time) const;
+ enum IncludeRepeats { kIncludeRepeats, kExcludeRepeats };
+ SMILTime ComputeNextIntervalTime(SMILTime presentation_time,
+ IncludeRepeats) const;
SMILTime NextProgressTime(SMILTime elapsed) const;
void Reset();
@@ -96,18 +141,14 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests {
static SMILTime ParseOffsetValue(const String&);
bool IsContributing(SMILTime elapsed) const;
+ const SMILInterval& GetActiveInterval(SMILTime presentation_time) const;
unsigned DocumentOrderIndex() const { return document_order_index_; }
void SetDocumentOrderIndex(unsigned index) { document_order_index_ = index; }
wtf_size_t& PriorityQueueHandle() { return queue_handle_; }
- void ScheduleEvent(const AtomicString& event_type);
- void ScheduleRepeatEvents();
-
- virtual bool IsSVGDiscardElement() const { return false; }
-
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
enum BeginOrEnd { kBegin, kEnd };
@@ -120,9 +161,6 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests {
virtual void WillChangeAnimationTarget();
virtual void DidChangeAnimationTarget();
- virtual void StartedActiveInterval();
- void QueueDiscard();
-
struct ProgressState {
float progress;
unsigned repeat;
@@ -130,10 +168,13 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests {
const ProgressState& GetProgressState() const { return last_progress_; }
private:
+ bool IsPresentationAttribute(const QualifiedName&) const override;
+
void BuildPendingResource() override;
void ClearResourceAndEventBaseReferences();
void ClearConditions();
+ void StartedActiveInterval();
void EndedActiveInterval();
bool LayoutObjectIsNeeded(const ComputedStyle&) const override {
@@ -151,7 +192,6 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests {
void DiscardOrRevalidateCurrentInterval(SMILTime presentation_time);
SMILTime ResolveActiveEnd(SMILTime resolved_begin) const;
SMILTime RepeatingDuration() const;
- const SMILInterval& GetActiveInterval(SMILTime elapsed) const;
void SetNewInterval(const SMILInterval&);
void SetNewIntervalEnd(SMILTime new_end);
@@ -175,7 +215,7 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests {
unsigned repeat);
~Condition();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
Type GetType() const { return type_; }
BeginOrEnd GetBeginOrEnd() const { return begin_or_end_; }
@@ -232,6 +272,8 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests {
ProgressState CalculateProgressState(SMILTime presentation_time) const;
+ SMILTime LastIntervalEndTime() const;
+
Member<SVGElement> target_element_;
Member<IdTargetObserver> target_id_observer_;
@@ -246,8 +288,8 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests {
TimeDependentSet sync_base_dependents_;
// Instance time lists
- Vector<SMILTimeWithOrigin> begin_times_;
- Vector<SMILTimeWithOrigin> end_times_;
+ SMILInstanceTimeList begin_times_;
+ SMILInstanceTimeList end_times_;
// This is the upcoming or current interval
SMILInterval interval_;
@@ -277,23 +319,24 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests {
friend class ConditionEventListener;
};
-inline bool IsSVGSMILElement(const SVGElement& element) {
- return element.HasTagName(svg_names::kSetTag) ||
- element.HasTagName(svg_names::kAnimateTag) ||
- element.HasTagName(svg_names::kAnimateMotionTag) ||
- element.HasTagName(svg_names::kAnimateTransformTag) ||
- element.HasTagName((svg_names::kDiscardTag));
+template <>
+inline bool IsElementOfType<const SVGSMILElement>(const Node& node) {
+ return IsA<SVGSMILElement>(node);
}
-
template <>
struct DowncastTraits<SVGSMILElement> {
static bool AllowFrom(const Node& node) {
auto* svg_element = DynamicTo<SVGElement>(node);
- return svg_element && IsSVGSMILElement(*svg_element);
+ return svg_element && AllowFrom(*svg_element);
+ }
+ static bool AllowFrom(const SVGElement& svg_element) {
+ return svg_element.HasTagName(svg_names::kSetTag) ||
+ svg_element.HasTagName(svg_names::kAnimateTag) ||
+ svg_element.HasTagName(svg_names::kAnimateMotionTag) ||
+ svg_element.HasTagName(svg_names::kAnimateTransformTag);
}
};
-DEFINE_SVGELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGSMILElement);
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SVG_ANIMATION_SVG_SMIL_ELEMENT_H_
diff --git a/chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element_test.cc b/chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element_test.cc
new file mode 100644
index 00000000000..1681ce8979e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element_test.cc
@@ -0,0 +1,121 @@
+// 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/svg/animation/svg_smil_element.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace blink {
+
+namespace {
+
+Vector<std::pair<SMILTime, SMILTimeOrigin>> ExtractListContents(
+ const SMILInstanceTimeList& list) {
+ Vector<std::pair<SMILTime, SMILTimeOrigin>> times;
+ for (const auto& item : list)
+ times.push_back(std::make_pair(item.Time(), item.Origin()));
+ return times;
+}
+
+TEST(SMILInstanceTimeListTest, Sort) {
+ SMILInstanceTimeList list;
+ list.Append(SMILTime::FromSecondsD(1), SMILTimeOrigin::kAttribute);
+ list.Append(SMILTime::FromSecondsD(5), SMILTimeOrigin::kAttribute);
+ list.Append(SMILTime::FromSecondsD(4), SMILTimeOrigin::kAttribute);
+ list.Append(SMILTime::FromSecondsD(2), SMILTimeOrigin::kAttribute);
+ list.Append(SMILTime::FromSecondsD(3), SMILTimeOrigin::kAttribute);
+ ASSERT_EQ(list.size(), 5u);
+ list.Sort();
+
+ Vector<std::pair<SMILTime, SMILTimeOrigin>> expected_times(
+ {{SMILTime::FromSecondsD(1), SMILTimeOrigin::kAttribute},
+ {SMILTime::FromSecondsD(2), SMILTimeOrigin::kAttribute},
+ {SMILTime::FromSecondsD(3), SMILTimeOrigin::kAttribute},
+ {SMILTime::FromSecondsD(4), SMILTimeOrigin::kAttribute},
+ {SMILTime::FromSecondsD(5), SMILTimeOrigin::kAttribute}});
+ ASSERT_EQ(ExtractListContents(list), expected_times);
+}
+
+TEST(SMILInstanceTimeListTest, InsertSortedAndUnique) {
+ SMILInstanceTimeList list;
+ list.Append(SMILTime::FromSecondsD(1), SMILTimeOrigin::kAttribute);
+ list.Append(SMILTime::FromSecondsD(2), SMILTimeOrigin::kScript);
+ list.Append(SMILTime::FromSecondsD(3), SMILTimeOrigin::kAttribute);
+ ASSERT_EQ(list.size(), 3u);
+
+ // Unique time/item.
+ list.InsertSortedAndUnique(SMILTime::FromSecondsD(4),
+ SMILTimeOrigin::kScript);
+ ASSERT_EQ(list.size(), 4u);
+ Vector<std::pair<SMILTime, SMILTimeOrigin>> expected_times1(
+ {{SMILTime::FromSecondsD(1), SMILTimeOrigin::kAttribute},
+ {SMILTime::FromSecondsD(2), SMILTimeOrigin::kScript},
+ {SMILTime::FromSecondsD(3), SMILTimeOrigin::kAttribute},
+ {SMILTime::FromSecondsD(4), SMILTimeOrigin::kScript}});
+ ASSERT_EQ(ExtractListContents(list), expected_times1);
+
+ // Non-unique item.
+ list.InsertSortedAndUnique(SMILTime::FromSecondsD(2),
+ SMILTimeOrigin::kScript);
+ ASSERT_EQ(list.size(), 4u);
+ ASSERT_EQ(ExtractListContents(list), expected_times1);
+
+ // Same time but different origin.
+ list.InsertSortedAndUnique(SMILTime::FromSecondsD(2),
+ SMILTimeOrigin::kAttribute);
+ ASSERT_EQ(list.size(), 5u);
+ Vector<std::pair<SMILTime, SMILTimeOrigin>> expected_times2(
+ {{SMILTime::FromSecondsD(1), SMILTimeOrigin::kAttribute},
+ {SMILTime::FromSecondsD(2), SMILTimeOrigin::kAttribute},
+ {SMILTime::FromSecondsD(2), SMILTimeOrigin::kScript},
+ {SMILTime::FromSecondsD(3), SMILTimeOrigin::kAttribute},
+ {SMILTime::FromSecondsD(4), SMILTimeOrigin::kScript}});
+ ASSERT_EQ(ExtractListContents(list), expected_times2);
+}
+
+TEST(SMILInstanceTimeListTest, RemoveWithOrigin) {
+ SMILInstanceTimeList list;
+ list.Append(SMILTime::FromSecondsD(1), SMILTimeOrigin::kScript);
+ list.Append(SMILTime::FromSecondsD(2), SMILTimeOrigin::kAttribute);
+ list.Append(SMILTime::FromSecondsD(3), SMILTimeOrigin::kAttribute);
+ list.Append(SMILTime::FromSecondsD(4), SMILTimeOrigin::kScript);
+ list.Append(SMILTime::FromSecondsD(5), SMILTimeOrigin::kAttribute);
+ ASSERT_EQ(list.size(), 5u);
+
+ list.RemoveWithOrigin(SMILTimeOrigin::kScript);
+ ASSERT_EQ(list.size(), 3u);
+ Vector<std::pair<SMILTime, SMILTimeOrigin>> expected_times(
+ {{SMILTime::FromSecondsD(2), SMILTimeOrigin::kAttribute},
+ {SMILTime::FromSecondsD(3), SMILTimeOrigin::kAttribute},
+ {SMILTime::FromSecondsD(5), SMILTimeOrigin::kAttribute}});
+ ASSERT_EQ(ExtractListContents(list), expected_times);
+}
+
+TEST(SMILInstanceTimeListTest, NextAfter) {
+ SMILInstanceTimeList list;
+ list.Append(SMILTime::FromSecondsD(1), SMILTimeOrigin::kScript);
+ list.Append(SMILTime::FromSecondsD(2), SMILTimeOrigin::kAttribute);
+ list.Append(SMILTime::FromSecondsD(3), SMILTimeOrigin::kAttribute);
+ list.Append(SMILTime::FromSecondsD(4), SMILTimeOrigin::kScript);
+ list.Append(SMILTime::FromSecondsD(5), SMILTimeOrigin::kAttribute);
+ ASSERT_EQ(list.size(), 5u);
+
+ // Just before an entry in the list.
+ EXPECT_EQ(list.NextAfter(SMILTime::FromSecondsD(2) - SMILTime::Epsilon()),
+ SMILTime::FromSecondsD(2));
+ // Equal to an entry in the list.
+ EXPECT_EQ(list.NextAfter(SMILTime::FromSecondsD(2)),
+ SMILTime::FromSecondsD(3));
+ // Just after an entry in the list.
+ EXPECT_EQ(list.NextAfter(SMILTime::FromSecondsD(2) + SMILTime::Epsilon()),
+ SMILTime::FromSecondsD(3));
+ // Equal to the last entry in the the list.
+ EXPECT_EQ(list.NextAfter(SMILTime::FromSecondsD(5)), SMILTime::Unresolved());
+ // After the last entry in the the list.
+ EXPECT_EQ(list.NextAfter(SMILTime::FromSecondsD(6)), SMILTime::Unresolved());
+}
+
+} // namespace
+
+} // namespace blink
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 3a1f782a139..cf6c426f47f 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
@@ -27,12 +27,12 @@
#include "third_party/blink/renderer/core/paint/svg_object_painter.h"
#include "third_party/blink/renderer/core/svg/svg_element.h"
#include "third_party/blink/renderer/core/svg/svg_length_context.h"
-#include "third_party/blink/renderer/core/svg/svg_uri_reference.h"
+#include "third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio.h"
#include "third_party/blink/renderer/platform/graphics/filters/filter.h"
-#include "third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h"
-#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_record.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h"
+#include "third_party/blink/renderer/platform/graphics/paint/paint_recorder.h"
+#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
#include "third_party/blink/renderer/platform/transforms/affine_transform.h"
#include "third_party/blink/renderer/platform/wtf/text/text_stream.h"
@@ -40,38 +40,35 @@ namespace blink {
FEImage::FEImage(Filter* filter,
scoped_refptr<Image> image,
- SVGPreserveAspectRatio* preserve_aspect_ratio)
+ const SVGPreserveAspectRatio* preserve_aspect_ratio)
: FilterEffect(filter),
image_(std::move(image)),
- tree_scope_(nullptr),
preserve_aspect_ratio_(preserve_aspect_ratio) {
FilterEffect::SetOperatingInterpolationSpace(kInterpolationSpaceSRGB);
}
FEImage::FEImage(Filter* filter,
- TreeScope& tree_scope,
- const String& href,
- SVGPreserveAspectRatio* preserve_aspect_ratio)
+ const SVGElement* element,
+ const SVGPreserveAspectRatio* preserve_aspect_ratio)
: FilterEffect(filter),
- tree_scope_(&tree_scope),
- href_(href),
+ element_(element),
preserve_aspect_ratio_(preserve_aspect_ratio) {
FilterEffect::SetOperatingInterpolationSpace(kInterpolationSpaceSRGB);
}
-void FEImage::Trace(blink::Visitor* visitor) {
- visitor->Trace(tree_scope_);
+void FEImage::Trace(Visitor* visitor) {
+ visitor->Trace(element_);
visitor->Trace(preserve_aspect_ratio_);
FilterEffect::Trace(visitor);
}
-static FloatRect GetLayoutObjectRepaintRect(LayoutObject* layout_object) {
+static FloatRect GetLayoutObjectRepaintRect(const LayoutObject* layout_object) {
return layout_object->LocalToSVGParentTransform().MapRect(
layout_object->VisualRectInLocalSVGCoordinates());
}
-AffineTransform MakeMapBetweenRects(const FloatRect& source,
- const FloatRect& dest) {
+static AffineTransform MakeMapBetweenRects(const FloatRect& source,
+ const FloatRect& dest) {
AffineTransform transform;
transform.Translate(dest.X() - source.X(), dest.Y() - source.Y());
transform.Scale(dest.Width() / source.Width(),
@@ -79,48 +76,52 @@ AffineTransform MakeMapBetweenRects(const FloatRect& source,
return transform;
}
-FloatRect FEImage::MapInputs(const FloatRect&) const {
- LayoutObject* layout_object = ReferencedLayoutObject();
- if (!image_ && !layout_object)
- return FloatRect();
+static base::Optional<AffineTransform> ComputeViewportAdjustmentTransform(
+ const SVGElement* element,
+ const FloatRect& target_rect) {
+ // If we're referencing an element with percentage units, eg. <rect
+ // with="30%"> those values were resolved against the viewport. Build up a
+ // transformation that maps from the viewport space to the filter primitive
+ // subregion.
+ // TODO(crbug/260709): This fixes relative lengths but breaks non-relative
+ // ones.
+ SVGLengthContext length_context(element);
+ FloatSize viewport_size;
+ if (!length_context.DetermineViewport(viewport_size))
+ return base::nullopt;
+ return MakeMapBetweenRects(FloatRect(FloatPoint(), viewport_size),
+ target_rect);
+}
+FloatRect FEImage::MapInputs(const FloatRect&) const {
FloatRect dest_rect =
GetFilter()->MapLocalRectToAbsoluteRect(FilterPrimitiveSubregion());
- FloatRect src_rect;
- if (layout_object) {
- src_rect = GetLayoutObjectRepaintRect(layout_object);
- auto* context_node = To<SVGElement>(layout_object->GetNode());
-
- if (context_node->HasRelativeLengths()) {
- // FIXME: This fixes relative lengths but breaks non-relative ones (see
- // crbug/260709).
- SVGLengthContext length_context(context_node);
- FloatSize viewport_size;
- if (length_context.DetermineViewport(viewport_size)) {
- src_rect = MakeMapBetweenRects(FloatRect(FloatPoint(), viewport_size),
- dest_rect)
- .MapRect(src_rect);
- }
+ if (const LayoutObject* layout_object = ReferencedLayoutObject()) {
+ FloatRect src_rect = GetLayoutObjectRepaintRect(layout_object);
+ if (element_->HasRelativeLengths()) {
+ auto viewport_transform =
+ ComputeViewportAdjustmentTransform(element_, dest_rect);
+ if (viewport_transform)
+ src_rect = viewport_transform->MapRect(src_rect);
} else {
src_rect = GetFilter()->MapLocalRectToAbsoluteRect(src_rect);
src_rect.Move(dest_rect.X(), dest_rect.Y());
}
dest_rect.Intersect(src_rect);
- } else {
- src_rect = FloatRect(FloatPoint(), FloatSize(image_->Size()));
+ return dest_rect;
+ }
+ if (image_) {
+ FloatRect src_rect = FloatRect(FloatPoint(), FloatSize(image_->Size()));
preserve_aspect_ratio_->TransformRect(dest_rect, src_rect);
+ return dest_rect;
}
- return dest_rect;
+ return FloatRect();
}
-LayoutObject* FEImage::ReferencedLayoutObject() const {
- if (!tree_scope_)
- return nullptr;
- Element* href_element =
- SVGURIReference::TargetElementFromIRIString(href_, *tree_scope_);
- if (!href_element || !href_element->IsSVGElement())
+const LayoutObject* FEImage::ReferencedLayoutObject() const {
+ if (!element_)
return nullptr;
- return href_element->GetLayoutObject();
+ return element_->GetLayoutObject();
}
WTF::TextStream& FEImage::ExternalRepresentation(WTF::TextStream& ts,
@@ -128,7 +129,7 @@ WTF::TextStream& FEImage::ExternalRepresentation(WTF::TextStream& ts,
IntSize image_size;
if (image_) {
image_size = image_->Size();
- } else if (LayoutObject* layout_object = ReferencedLayoutObject()) {
+ } else if (const LayoutObject* layout_object = ReferencedLayoutObject()) {
image_size =
EnclosingIntRect(GetLayoutObjectRepaintRect(layout_object)).Size();
}
@@ -143,59 +144,49 @@ WTF::TextStream& FEImage::ExternalRepresentation(WTF::TextStream& ts,
sk_sp<PaintFilter> FEImage::CreateImageFilterForLayoutObject(
const LayoutObject& layout_object) {
- FloatRect dst_rect = FilterPrimitiveSubregion();
+ FloatRect dst_rect =
+ GetFilter()->MapLocalRectToAbsoluteRect(FilterPrimitiveSubregion());
AffineTransform transform;
- auto* context_node = To<SVGElement>(layout_object.GetNode());
-
- if (context_node->HasRelativeLengths()) {
- SVGLengthContext length_context(context_node);
- FloatSize viewport_size;
-
- // If we're referencing an element with percentage units, eg. <rect
- // with="30%"> those values were resolved against the viewport. Build up a
- // transformation that maps from the viewport space to the filter primitive
- // subregion.
- if (length_context.DetermineViewport(viewport_size))
- transform =
- MakeMapBetweenRects(FloatRect(FloatPoint(), viewport_size), dst_rect);
+ if (element_->HasRelativeLengths()) {
+ auto viewport_transform =
+ ComputeViewportAdjustmentTransform(element_, dst_rect);
+ if (viewport_transform)
+ transform = *viewport_transform;
} else {
transform.Translate(dst_rect.X(), dst_rect.Y());
}
- PaintRecordBuilder builder;
- SVGObjectPainter(layout_object).PaintResourceSubtree(builder.Context());
-
PaintRecorder paint_recorder;
cc::PaintCanvas* canvas = paint_recorder.beginRecording(dst_rect);
canvas->concat(AffineTransformToSkMatrix(transform));
- builder.EndRecording(*canvas);
-
+ {
+ PaintRecordBuilder builder;
+ SVGObjectPainter(layout_object).PaintResourceSubtree(builder.Context());
+ builder.EndRecording(*canvas);
+ }
return sk_make_sp<RecordPaintFilter>(
paint_recorder.finishRecordingAsPicture(), dst_rect);
}
sk_sp<PaintFilter> FEImage::CreateImageFilter() {
- if (auto* layout_object = ReferencedLayoutObject())
+ if (const auto* layout_object = ReferencedLayoutObject())
return CreateImageFilterForLayoutObject(*layout_object);
- PaintImage image =
- image_ ? image_->PaintImageForCurrentFrame() : PaintImage();
- if (!image) {
- // "A href reference that is an empty image (zero width or zero height),
- // that fails to download, is non-existent, or that cannot be displayed
- // (e.g. because it is not in a supported image format) fills the filter
- // primitive subregion with transparent black."
- return CreateTransparentBlack();
+ if (PaintImage image =
+ image_ ? image_->PaintImageForCurrentFrame() : PaintImage()) {
+ FloatRect src_rect = FloatRect(FloatPoint(), FloatSize(image_->Size()));
+ FloatRect dst_rect =
+ GetFilter()->MapLocalRectToAbsoluteRect(FilterPrimitiveSubregion());
+ preserve_aspect_ratio_->TransformRect(dst_rect, src_rect);
+ return sk_make_sp<ImagePaintFilter>(std::move(image), src_rect, dst_rect,
+ kHigh_SkFilterQuality);
}
-
- FloatRect src_rect = FloatRect(FloatPoint(), FloatSize(image_->Size()));
- FloatRect dst_rect = FilterPrimitiveSubregion();
-
- preserve_aspect_ratio_->TransformRect(dst_rect, src_rect);
-
- return sk_make_sp<ImagePaintFilter>(std::move(image), src_rect, dst_rect,
- kHigh_SkFilterQuality);
+ // "A href reference that is an empty image (zero width or zero height),
+ // that fails to download, is non-existent, or that cannot be displayed
+ // (e.g. because it is not in a supported image format) fills the filter
+ // primitive subregion with transparent black."
+ return CreateTransparentBlack();
}
} // namespace blink
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 05c641a0a6e..fd0be877c6b 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
@@ -24,19 +24,19 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SVG_GRAPHICS_FILTERS_SVG_FE_IMAGE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_GRAPHICS_FILTERS_SVG_FE_IMAGE_H_
-#include "third_party/blink/renderer/core/dom/tree_scope.h"
-#include "third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio.h"
#include "third_party/blink/renderer/platform/graphics/filters/filter_effect.h"
namespace blink {
class Image;
class LayoutObject;
+class SVGElement;
+class SVGPreserveAspectRatio;
class FEImage final : public FilterEffect {
public:
- FEImage(Filter*, scoped_refptr<Image>, SVGPreserveAspectRatio*);
- FEImage(Filter*, TreeScope&, const String&, SVGPreserveAspectRatio*);
+ FEImage(Filter*, scoped_refptr<Image>, const SVGPreserveAspectRatio*);
+ FEImage(Filter*, const SVGElement*, const SVGPreserveAspectRatio*);
// feImage does not perform color interpolation of any kind, so doesn't
// depend on the value of color-interpolation-filters.
@@ -45,11 +45,11 @@ class FEImage final : public FilterEffect {
WTF::TextStream& ExternalRepresentation(WTF::TextStream&,
int indention) const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
~FEImage() override = default;
- LayoutObject* ReferencedLayoutObject() const;
+ const LayoutObject* ReferencedLayoutObject() const;
FilterEffectType GetFilterEffectType() const override {
return kFilterEffectTypeImage;
@@ -61,12 +61,8 @@ class FEImage final : public FilterEffect {
sk_sp<PaintFilter> CreateImageFilterForLayoutObject(const LayoutObject&);
scoped_refptr<Image> image_;
-
- // m_treeScope will never be a dangling reference. See
- // https://bugs.webkit.org/show_bug.cgi?id=99243
- Member<TreeScope> tree_scope_;
- String href_;
- Member<SVGPreserveAspectRatio> preserve_aspect_ratio_;
+ Member<const SVGElement> element_;
+ Member<const SVGPreserveAspectRatio> preserve_aspect_ratio_;
};
} // namespace blink
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 751dc6ba66e..10bad549ae3 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
@@ -27,6 +27,7 @@
#include "third_party/blink/renderer/core/svg/svg_filter_element.h"
#include "third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.h"
#include "third_party/blink/renderer/platform/graphics/filters/filter.h"
+#include "third_party/blink/renderer/platform/graphics/filters/filter_effect.h"
#include "third_party/blink/renderer/platform/graphics/filters/paint_filter_effect.h"
#include "third_party/blink/renderer/platform/graphics/filters/source_alpha.h"
#include "third_party/blink/renderer/platform/graphics/filters/source_graphic.h"
@@ -68,26 +69,21 @@ void SVGFilterGraphNodeMap::AddBuiltinEffect(FilterEffect* effect) {
effect_references_.insert(effect, FilterEffectSet());
}
-void SVGFilterGraphNodeMap::AddPrimitive(LayoutObject* object,
- FilterEffect* effect) {
+void SVGFilterGraphNodeMap::AddPrimitive(
+ SVGFilterPrimitiveStandardAttributes& primitive,
+ FilterEffect* effect) {
// The effect must be a newly created filter effect.
DCHECK(!effect_references_.Contains(effect));
- DCHECK(!object || !effect_renderer_.Contains(object));
+ DCHECK(!effect_element_.Contains(&primitive));
effect_references_.insert(effect, FilterEffectSet());
- unsigned number_of_input_effects = effect->InputEffects().size();
-
// Add references from the inputs of this effect to the effect itself, to
// allow determining what effects needs to be invalidated when a certain
// effect changes.
- for (unsigned i = 0; i < number_of_input_effects; ++i)
- EffectReferences(effect->InputEffect(i)).insert(effect);
-
- // If object is null, that means the element isn't attached for some
- // reason, which in turn mean that certain types of invalidation will not
- // work (the LayoutObject -> FilterEffect mapping will not be defined).
- if (object)
- effect_renderer_.insert(object, effect);
+ for (FilterEffect* input : effect->InputEffects())
+ EffectReferences(input).insert(effect);
+
+ effect_element_.insert(&primitive, effect);
}
void SVGFilterGraphNodeMap::InvalidateDependentEffects(FilterEffect* effect) {
@@ -101,8 +97,8 @@ void SVGFilterGraphNodeMap::InvalidateDependentEffects(FilterEffect* effect) {
InvalidateDependentEffects(effect_reference);
}
-void SVGFilterGraphNodeMap::Trace(blink::Visitor* visitor) {
- visitor->Trace(effect_renderer_);
+void SVGFilterGraphNodeMap::Trace(Visitor* visitor) {
+ visitor->Trace(effect_element_);
visitor->Trace(effect_references_);
}
@@ -111,22 +107,19 @@ SVGFilterBuilder::SVGFilterBuilder(FilterEffect* source_graphic,
const PaintFlags* fill_flags,
const PaintFlags* stroke_flags)
: node_map_(node_map) {
- FilterEffect* source_graphic_ref = source_graphic;
builtin_effects_.insert(FilterInputKeywords::GetSourceGraphic(),
- source_graphic_ref);
- builtin_effects_.insert(
- FilterInputKeywords::SourceAlpha(),
- MakeGarbageCollected<SourceAlpha>(source_graphic_ref));
+ source_graphic);
+ builtin_effects_.insert(FilterInputKeywords::SourceAlpha(),
+ MakeGarbageCollected<SourceAlpha>(source_graphic));
if (fill_flags) {
builtin_effects_.insert(FilterInputKeywords::FillPaint(),
MakeGarbageCollected<PaintFilterEffect>(
- source_graphic_ref->GetFilter(), *fill_flags));
+ source_graphic->GetFilter(), *fill_flags));
}
if (stroke_flags) {
- builtin_effects_.insert(
- FilterInputKeywords::StrokePaint(),
- MakeGarbageCollected<PaintFilterEffect>(source_graphic_ref->GetFilter(),
- *stroke_flags));
+ builtin_effects_.insert(FilterInputKeywords::StrokePaint(),
+ MakeGarbageCollected<PaintFilterEffect>(
+ source_graphic->GetFilter(), *stroke_flags));
}
AddBuiltinEffects();
}
@@ -185,7 +178,7 @@ void SVGFilterBuilder::BuildGraph(Filter* filter,
continue;
if (node_map_)
- node_map_->AddPrimitive(effect_element.GetLayoutObject(), effect);
+ node_map_->AddPrimitive(effect_element, effect);
effect_element.SetStandardAttributes(effect, primitive_units,
reference_box);
@@ -223,7 +216,7 @@ FilterEffect* SVGFilterBuilder::GetEffectById(const AtomicString& id) const {
}
if (last_effect_)
- return last_effect_.Get();
+ return last_effect_;
return builtin_effects_.at(FilterInputKeywords::GetSourceGraphic());
}
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 e532659f094..5aa68df7966 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
@@ -22,7 +22,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_GRAPHICS_FILTERS_SVG_FILTER_BUILDER_H_
#include "third_party/blink/renderer/core/style/svg_computed_style_defs.h"
-#include "third_party/blink/renderer/platform/graphics/filters/filter_effect.h"
+#include "third_party/blink/renderer/platform/graphics/interpolation_space.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_flags.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
@@ -32,13 +32,15 @@
namespace blink {
+class Filter;
+class FilterEffect;
class FloatRect;
-class LayoutObject;
class SVGFilterElement;
+class SVGFilterPrimitiveStandardAttributes;
-// A map from LayoutObject -> FilterEffect and FilterEffect -> dependent
-// (downstream) FilterEffects ("reverse DAG"). Used during invalidations from
-// changes to the primitives (graph nodes).
+// A map from SVGFilterPrimitiveStandardAttributes -> FilterEffect and
+// FilterEffect -> dependent (downstream) FilterEffects ("reverse DAG"). Used
+// during invalidations for changes to the primitives (graph nodes).
class SVGFilterGraphNodeMap final
: public GarbageCollected<SVGFilterGraphNodeMap> {
public:
@@ -47,29 +49,32 @@ class SVGFilterGraphNodeMap final
typedef HeapHashSet<Member<FilterEffect>> FilterEffectSet;
void AddBuiltinEffect(FilterEffect*);
- void AddPrimitive(LayoutObject*, FilterEffect*);
-
- inline FilterEffectSet& EffectReferences(FilterEffect* effect) {
- // Only allowed for effects belongs to this builder.
- DCHECK(effect_references_.Contains(effect));
- return effect_references_.find(effect)->value;
- }
+ void AddPrimitive(SVGFilterPrimitiveStandardAttributes&, FilterEffect*);
// Required to change the attributes of a filter during an
- // svgAttributeChanged.
- inline FilterEffect* EffectByRenderer(LayoutObject* object) {
- return effect_renderer_.at(object);
+ // SvgAttributeChanged.
+ FilterEffect* EffectForElement(
+ SVGFilterPrimitiveStandardAttributes& primitive) {
+ return effect_element_.at(&primitive);
}
void InvalidateDependentEffects(FilterEffect*);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
- // The value is a list, which contains those filter effects,
- // which depends on the key filter effect.
+ FilterEffectSet& EffectReferences(FilterEffect* effect) {
+ // Only allowed for effects that are part of this node map.
+ DCHECK(effect_references_.Contains(effect));
+ return effect_references_.find(effect)->value;
+ }
+
+ // The value is the set of filter effects that depend on the key
+ // filter effect.
HeapHashMap<Member<FilterEffect>, FilterEffectSet> effect_references_;
- HeapHashMap<LayoutObject*, Member<FilterEffect>> effect_renderer_;
+ HeapHashMap<WeakMember<SVGFilterPrimitiveStandardAttributes>,
+ Member<FilterEffect>>
+ effect_element_;
};
class SVGFilterBuilder {
@@ -84,7 +89,7 @@ class SVGFilterBuilder {
void BuildGraph(Filter*, SVGFilterElement&, const FloatRect&);
FilterEffect* GetEffectById(const AtomicString& id) const;
- FilterEffect* LastEffect() const { return last_effect_.Get(); }
+ FilterEffect* LastEffect() const { return last_effect_; }
static InterpolationSpace ResolveInterpolationSpace(EColorInterpolation);
@@ -97,8 +102,8 @@ class SVGFilterBuilder {
NamedFilterEffectMap builtin_effects_;
NamedFilterEffectMap named_effects_;
- Member<FilterEffect> last_effect_;
- Member<SVGFilterGraphNodeMap> node_map_;
+ FilterEffect* last_effect_ = nullptr;
+ SVGFilterGraphNodeMap* node_map_;
};
} // namespace blink
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 8fd0092e1eb..c67810593dd 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
@@ -28,6 +28,11 @@
#include "third_party/blink/renderer/core/svg/graphics/svg_image.h"
#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
+#include "third_party/blink/public/platform/web_url.h"
+#include "third_party/blink/public/platform/web_url_loader.h"
+#include "third_party/blink/public/platform/web_url_loader_client.h"
+#include "third_party/blink/public/platform/web_url_loader_factory.h"
#include "third_party/blink/renderer/core/animation/document_animations.h"
#include "third_party/blink/renderer/core/animation/document_timeline.h"
#include "third_party/blink/renderer/core/dom/document_parser.h"
@@ -69,6 +74,65 @@
namespace blink {
+namespace {
+
+using TaskRunnerHandle = scheduler::WebResourceLoadingTaskRunnerHandle;
+
+class FailingLoader final : public WebURLLoader {
+ public:
+ explicit FailingLoader(std::unique_ptr<TaskRunnerHandle> task_runner_handle)
+ : task_runner_handle_(std::move(task_runner_handle)) {}
+ ~FailingLoader() override = default;
+
+ // WebURLLoader implementation:
+ void LoadSynchronously(
+ std::unique_ptr<network::ResourceRequest> request,
+ scoped_refptr<WebURLRequest::ExtraData> request_extra_data,
+ int requestor_id,
+ bool download_to_network_cache_only,
+ bool pass_response_pipe_to_client,
+ bool no_mime_sniffing,
+ base::TimeDelta timeout_interval,
+ WebURLLoaderClient*,
+ WebURLResponse&,
+ base::Optional<WebURLError>& error,
+ WebData&,
+ int64_t& encoded_data_length,
+ int64_t& encoded_body_length,
+ WebBlobInfo& downloaded_blob) override {
+ NOTREACHED();
+ }
+ void LoadAsynchronously(
+ std::unique_ptr<network::ResourceRequest> request,
+ scoped_refptr<WebURLRequest::ExtraData> request_extra_data,
+ int requestor_id,
+ bool download_to_network_cache_only,
+ bool no_mime_sniffing,
+ WebURLLoaderClient* client) override {
+ NOTREACHED();
+ }
+ void SetDefersLoading(bool) override {}
+ void DidChangePriority(WebURLRequest::Priority, int) override {}
+ scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() override {
+ return task_runner_handle_->GetTaskRunner();
+ }
+
+ private:
+ const std::unique_ptr<TaskRunnerHandle> task_runner_handle_;
+};
+
+class FailingLoaderFactory final : public WebURLLoaderFactory {
+ public:
+ // WebURLLoaderFactory implementation:
+ std::unique_ptr<WebURLLoader> CreateURLLoader(
+ const WebURLRequest&,
+ std::unique_ptr<TaskRunnerHandle> task_runner_handle) override {
+ return std::make_unique<FailingLoader>(std::move(task_runner_handle));
+ }
+};
+
+} // namespace
+
// SVGImageLocalFrameClient is used to wait until SVG document's load event
// in the case where there are subresources asynchronously loaded.
//
@@ -82,7 +146,9 @@ class SVGImage::SVGImageLocalFrameClient : public EmptyLocalFrameClient {
private:
std::unique_ptr<WebURLLoaderFactory> CreateURLLoaderFactory() override {
- return Platform::Current()->CreateDefaultURLLoaderFactory();
+ // SVG Images have unique security rules that prevent all subresource
+ // requests except for data urls.
+ return std::make_unique<FailingLoaderFactory>();
}
void DispatchDidHandleOnloadEvents() override {
@@ -107,6 +173,11 @@ SVGImage::~SVGImage() {
frame_client_->ClearImage();
if (page_) {
+ // It is safe to allow UA events within this scope, because event
+ // dispatching inside the SVG image's document doesn't trigger JavaScript
+ // execution. All script execution is forbidden when an SVG is loaded as an
+ // image subresource - see SetScriptEnabled in SVGImage::DataChanged().
+ EventDispatchForbiddenScope::AllowUserAgentEvents allow_events;
// Store m_page in a local variable, clearing m_page, so that
// SVGImageChromeClient knows we're destructed.
Page* current_page = page_.Release();
@@ -178,18 +249,18 @@ static SVGSVGElement* SvgRootElement(Page* page) {
return frame->GetDocument()->AccessSVGExtensions().rootElement();
}
-IntSize SVGImage::ContainerSize() const {
+LayoutSize SVGImage::ContainerSize() const {
SVGSVGElement* root_element = SvgRootElement(page_.Get());
if (!root_element)
- return IntSize();
+ return LayoutSize();
LayoutSVGRoot* layout_object =
ToLayoutSVGRoot(root_element->GetLayoutObject());
if (!layout_object)
- return IntSize();
+ return LayoutSize();
// If a container size is available it has precedence.
- IntSize container_size = layout_object->ContainerSize();
+ LayoutSize container_size = layout_object->ContainerSize();
if (!container_size.IsEmpty())
return container_size;
@@ -200,6 +271,10 @@ IntSize SVGImage::ContainerSize() const {
return intrinsic_size_;
}
+IntSize SVGImage::Size() const {
+ return RoundedIntSize(intrinsic_size_);
+}
+
static float ResolveWidthForRatio(float height,
const FloatSize& intrinsic_ratio) {
return height * intrinsic_ratio.Width() / intrinsic_ratio.Height();
@@ -298,7 +373,7 @@ void SVGImage::ForContainer(const FloatSize& container_size, Func&& func) {
// re-laying out the image.
ImageObserverDisabler image_observer_disabler(this);
- IntSize rounded_container_size = RoundedIntSize(container_size);
+ LayoutSize rounded_container_size = RoundedLayoutSize(container_size);
if (SVGSVGElement* root_element = SvgRootElement(page_.Get())) {
if (LayoutSVGRoot* layout_object =
@@ -326,8 +401,8 @@ void SVGImage::DrawForContainer(cc::PaintCanvas* canvas,
adjusted_src_size.Scale(residual_scale.Width(), residual_scale.Height());
scaled_src.SetSize(adjusted_src_size);
- DrawInternal(canvas, flags, dst_rect, scaled_src,
- kDoNotRespectImageOrientation, kClampImageToSourceRect, url);
+ DrawInternal(canvas, flags, dst_rect, scaled_src, kRespectImageOrientation,
+ kClampImageToSourceRect, url);
});
}
@@ -443,12 +518,11 @@ static bool DrawNeedsLayer(const PaintFlags& flags) {
bool SVGImage::ApplyShaderInternal(PaintFlags& flags,
const SkMatrix& local_matrix,
const KURL& url) {
- const IntSize size(ContainerSize());
+ const FloatSize size(ContainerSize());
if (size.IsEmpty())
return false;
- IntRect bounds(IntPoint(), size);
-
+ FloatRect bounds(FloatPoint(), size);
flags.setShader(PaintShader::MakePaintRecord(
PaintRecordForCurrentFrame(url), bounds, SkTileMode::kRepeat,
SkTileMode::kRepeat, &local_matrix));
@@ -500,8 +574,9 @@ void SVGImage::Draw(
sk_sp<PaintRecord> SVGImage::PaintRecordForCurrentFrame(const KURL& url) {
DCHECK(page_);
LocalFrameView* view = To<LocalFrame>(page_->MainFrame())->View();
- view->Resize(ContainerSize());
- page_->GetVisualViewport().SetSize(ContainerSize());
+ IntSize rounded_container_size = RoundedIntSize(ContainerSize());
+ view->Resize(rounded_container_size);
+ page_->GetVisualViewport().SetSize(rounded_container_size);
// Always call processUrlFragment, even if the url is empty, because
// there may have been a previous url/fragment that needs to be reset.
@@ -515,12 +590,11 @@ sk_sp<PaintRecord> SVGImage::PaintRecordForCurrentFrame(const KURL& url) {
FlushPendingTimelineRewind();
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
- view->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kOther);
+ view->UpdateAllLifecyclePhases(DocumentUpdateReason::kSVGImage);
return view->GetPaintRecord();
}
- view->UpdateAllLifecyclePhasesExceptPaint();
+ view->UpdateAllLifecyclePhasesExceptPaint(DocumentUpdateReason::kSVGImage);
PaintRecordBuilder builder(nullptr, nullptr, paint_controller_.get());
view->PaintOutsideOfLifecycle(builder.Context(), kGlobalPaintNormalPhase);
return builder.EndRecording();
@@ -542,18 +616,10 @@ void SVGImage::DrawInternal(cc::PaintCanvas* canvas,
// We can only draw the entire frame, clipped to the rect we want. So
// compute where the top left of the image would be if we were drawing
// without clipping, and translate accordingly.
- FloatSize scale(dst_rect.Width() / src_rect.Width(),
- dst_rect.Height() / src_rect.Height());
- FloatSize top_left_offset(src_rect.Location().X() * scale.Width(),
- src_rect.Location().Y() * scale.Height());
- FloatPoint dest_offset = dst_rect.Location() - top_left_offset;
- AffineTransform transform =
- AffineTransform::Translation(dest_offset.X(), dest_offset.Y());
- transform.Scale(scale.Width(), scale.Height());
-
canvas->save();
canvas->clipRect(EnclosingIntRect(dst_rect));
- canvas->concat(AffineTransformToSkMatrix(transform));
+ canvas->concat(SkMatrix::MakeRectToRect(src_rect, dst_rect,
+ SkMatrix::kFill_ScaleToFit));
canvas->drawPicture(PaintRecordForCurrentFrame(url));
canvas->restore();
}
@@ -653,16 +719,18 @@ void SVGImage::ServiceAnimations(
// but to preserve correct coherence of the cache of the output with
// the needsRepaint bits of the PaintLayers in the image.
LocalFrameView* frame_view = To<LocalFrame>(page_->MainFrame())->View();
- frame_view->UpdateAllLifecyclePhasesExceptPaint();
+ frame_view->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kSVGImage);
// We run UpdateAnimations after the paint phase, but per the above comment,
// we don't want to run lifecycle through to paint for SVG images. Since we
// know SVG images never have composited animations, we can update animations
// directly without worrying about including PaintArtifactCompositor's
// analysis of whether animations should be composited.
- DocumentAnimations::UpdateAnimations(
- frame_view->GetLayoutView()->GetDocument(),
- DocumentLifecycle::kLayoutClean, nullptr);
+ frame_view->GetLayoutView()
+ ->GetDocument()
+ .GetDocumentAnimations()
+ .UpdateAnimations(DocumentLifecycle::kLayoutClean, nullptr);
}
void SVGImage::AdvanceAnimationForTesting() {
@@ -785,6 +853,11 @@ Image::SizeAvailability SVGImage::DataChanged(bool all_data_received) {
default_settings.GetDefaultFontSize());
page->GetSettings().SetDefaultFixedFontSize(
default_settings.GetDefaultFixedFontSize());
+
+ // Also copy the preferred-color-scheme to ensure a responsiveness to
+ // dark/light color schemes.
+ page->GetSettings().SetPreferredColorScheme(
+ default_settings.GetPreferredColorScheme());
}
}
@@ -800,7 +873,7 @@ Image::SizeAvailability SVGImage::DataChanged(bool all_data_received) {
}
FrameLoader& loader = frame->Loader();
- loader.ForceSandboxFlags(WebSandboxFlags::kAll);
+ loader.ForceSandboxFlags(mojom::blink::WebSandboxFlags::kAll);
// SVG Images will always synthesize a viewBox, if it's not available, and
// thus never see scrollbars.
@@ -819,7 +892,7 @@ Image::SizeAvailability SVGImage::DataChanged(bool all_data_received) {
frame->GetDocument()->UpdateStyleAndLayoutTree();
// Set the concrete object size before a container size is available.
- intrinsic_size_ = RoundedIntSize(ConcreteObjectSize(FloatSize(
+ intrinsic_size_ = RoundedLayoutSize(ConcreteObjectSize(FloatSize(
LayoutReplaced::kDefaultWidth, LayoutReplaced::kDefaultHeight)));
DCHECK(page_);
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 8dd7b4acf3e..3841f0e2120 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
@@ -29,11 +29,13 @@
#include "base/macros.h"
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/geometry/layout_size.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_record.h"
#include "third_party/blink/renderer/platform/heap/handle.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/casting.h"
#include "third_party/skia/include/core/SkRefCnt.h"
namespace blink {
@@ -66,7 +68,7 @@ class CORE_EXPORT SVGImage final : public Image {
static bool IsInSVGImage(const Node*);
bool IsSVGImage() const override { return true; }
- IntSize Size() const override { return intrinsic_size_; }
+ IntSize Size() const override;
void CheckLoaded() const;
bool CurrentFrameHasSingleSecurityOrigin() const override;
@@ -144,7 +146,7 @@ class CORE_EXPORT SVGImage final : public Image {
String FilenameExtension() const override;
- IntSize ContainerSize() const;
+ LayoutSize ContainerSize() const;
SizeAvailability DataChanged(bool all_data_received) override;
@@ -227,7 +229,7 @@ class CORE_EXPORT SVGImage final : public Image {
// belong to multiple containers so the final image size can't be known in
// SVGImage. SVGImageForContainer carries the final image size, also called
// the "concrete object size". For more, see: SVGImageForContainer.h
- IntSize intrinsic_size_;
+ LayoutSize intrinsic_size_;
bool has_pending_timeline_rewind_;
enum LoadState {
@@ -246,9 +248,13 @@ class CORE_EXPORT SVGImage final : public Image {
FRIEND_TEST_ALL_PREFIXES(SVGImageTest, LayoutShiftTrackerDisabled);
FRIEND_TEST_ALL_PREFIXES(SVGImageTest, SetSizeOnVisualViewport);
FRIEND_TEST_ALL_PREFIXES(SVGImageTest, IsSizeAvailable);
+ FRIEND_TEST_ALL_PREFIXES(SVGImageTest, DisablesSMILEvents);
};
-DEFINE_IMAGE_TYPE_CASTS(SVGImage);
+template <>
+struct DowncastTraits<SVGImage> {
+ static bool AllowFrom(const Image& image) { return image.IsSVGImage(); }
+};
class ImageObserverDisabler {
STACK_ALLOCATED();
diff --git a/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_chrome_client.h b/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_chrome_client.h
index 6460951775f..69506e85d6c 100644
--- a/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_chrome_client.h
+++ b/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_chrome_client.h
@@ -34,6 +34,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/loader/empty_clients.h"
#include "third_party/blink/renderer/platform/timer.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -76,11 +77,12 @@ class CORE_EXPORT SVGImageChromeClient final : public EmptyChromeClient {
FRIEND_TEST_ALL_PREFIXES(SVGImageSimTest, PageVisibilityHiddenToVisible);
};
-DEFINE_TYPE_CASTS(SVGImageChromeClient,
- ChromeClient,
- client,
- client->IsSVGImageChromeClient(),
- client.IsSVGImageChromeClient());
+template <>
+struct DowncastTraits<SVGImageChromeClient> {
+ static bool AllowFrom(const ChromeClient& client) {
+ return client.IsSVGImageChromeClient();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_for_container.cc b/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_for_container.cc
index 9745ea45053..6e701174f98 100644
--- a/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_for_container.cc
+++ b/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_for_container.cc
@@ -28,9 +28,15 @@
namespace blink {
IntSize SVGImageForContainer::Size() const {
+ // The image orientation is irrelevant because there is not concept of
+ // orientation for SVG images.
+ return RoundedIntSize(SizeAsFloat(kRespectImageOrientation));
+}
+
+FloatSize SVGImageForContainer::SizeAsFloat(RespectImageOrientationEnum) const {
FloatSize scaled_container_size(container_size_);
scaled_container_size.Scale(zoom_);
- return RoundedIntSize(scaled_container_size);
+ return scaled_container_size;
}
void SVGImageForContainer::Draw(cc::PaintCanvas* canvas,
@@ -50,7 +56,8 @@ void SVGImageForContainer::DrawPattern(GraphicsContext& context,
const FloatPoint& phase,
SkBlendMode op,
const FloatRect& dst_rect,
- const FloatSize& repeat_spacing) {
+ const FloatSize& repeat_spacing,
+ RespectImageOrientationEnum) {
image_->DrawPatternForContainer(context, container_size_, zoom_, src_rect,
scale, phase, op, dst_rect, repeat_spacing,
url_);
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 1e617991b62..3a59c9578a4 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
@@ -70,6 +70,7 @@ class SVGImageForContainer final : public Image {
}
IntSize Size() const override;
+ FloatSize SizeAsFloat(RespectImageOrientationEnum) const override;
bool HasIntrinsicSize() const override { return image_->HasIntrinsicSize(); }
@@ -102,7 +103,8 @@ class SVGImageForContainer final : public Image {
const FloatPoint&,
SkBlendMode,
const FloatRect&,
- const FloatSize& repeat_spacing) override;
+ const FloatSize& repeat_spacing,
+ RespectImageOrientationEnum) override;
private:
SVGImageForContainer(SVGImage* image,
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 25523b191cf..59944100bb6 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
@@ -15,7 +15,9 @@
#include "third_party/blink/renderer/core/layout/layout_shift_tracker.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/svg/animation/smil_time_container.h"
#include "third_party/blink/renderer/core/svg/graphics/svg_image_chrome_client.h"
+#include "third_party/blink/renderer/core/svg/svg_svg_element.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/geometry/float_rect.h"
@@ -36,7 +38,7 @@ const float kEpsilon = 0.00001;
} // namespace
-class SVGImageTest : public testing::Test {
+class SVGImageTest : public testing::Test, private ScopedMockOverlayScrollbars {
public:
SVGImage& GetImage() { return *image_; }
@@ -44,6 +46,7 @@ class SVGImageTest : public testing::Test {
observer_ = MakeGarbageCollected<PauseControlImageObserver>(should_pause);
image_ = SVGImage::Create(observer_);
image_->SetData(SharedBuffer::Create(data, strlen(data)), true);
+ test::RunPendingTasks();
}
void LoadUsingFileName(const String& file_name) {
@@ -54,6 +57,7 @@ class SVGImageTest : public testing::Test {
observer_ = MakeGarbageCollected<PauseControlImageObserver>(true);
image_ = SVGImage::Create(observer_);
image_->SetData(image_data, true);
+ test::RunPendingTasks();
}
void PumpFrame() {
@@ -63,8 +67,8 @@ class SVGImageTest : public testing::Test {
PaintFlags flags;
FloatRect dummy_rect(0, 0, 100, 100);
image->Draw(&canvas, flags, dummy_rect, dummy_rect,
- kDoNotRespectImageOrientation,
- Image::kDoNotClampImageToSourceRect, Image::kSyncDecode);
+ kRespectImageOrientation, Image::kDoNotClampImageToSourceRect,
+ Image::kSyncDecode);
}
// Loads the image from |file_name|, computes features into |features|,
@@ -109,9 +113,7 @@ class SVGImageTest : public testing::Test {
void AsyncLoadCompleted(const blink::Image*) override {}
- void Trace(blink::Visitor* visitor) override {
- ImageObserver::Trace(visitor);
- }
+ void Trace(Visitor* visitor) override { ImageObserver::Trace(visitor); }
private:
bool should_pause_;
@@ -252,6 +254,18 @@ TEST_F(SVGImageTest, IsSizeAvailable) {
EXPECT_FALSE(GetImage().IsSizeAvailable());
}
+TEST_F(SVGImageTest, DisablesSMILEvents) {
+ const bool kShouldPause = true;
+ Load(kAnimatedDocument, kShouldPause);
+ LocalFrame* local_frame =
+ To<LocalFrame>(GetImage().GetPageForTesting()->MainFrame());
+ EXPECT_TRUE(local_frame->GetDocument()->IsSVGDocument());
+ SMILTimeContainer* time_container =
+ To<SVGSVGElement>(local_frame->GetDocument()->documentElement())
+ ->TimeContainer();
+ EXPECT_TRUE(time_container->EventsDisabled());
+}
+
TEST_F(SVGImageTest, DarkModeClassification) {
DarkModeImageClassifier::Features features;
@@ -316,7 +330,7 @@ TEST_F(SVGImageTest, DarkModeClassification) {
EXPECT_NEAR(0.11f, features.background_ratio, kEpsilon);
}
-class SVGImageSimTest : public SimTest {};
+class SVGImageSimTest : public SimTest, private ScopedMockOverlayScrollbars {};
TEST_F(SVGImageSimTest, PageVisibilityHiddenToVisible) {
SimRequest main_resource("https://example.com/", "text/html");
@@ -338,9 +352,9 @@ TEST_F(SVGImageSimTest, PageVisibilityHiddenToVisible) {
ASSERT_TRUE(image_content->IsLoaded());
ASSERT_TRUE(image_content->HasImage());
Image* image = image_content->GetImage();
- ASSERT_TRUE(image->IsSVGImage());
+ ASSERT_TRUE(IsA<SVGImage>(image));
SVGImageChromeClient& svg_image_chrome_client =
- ToSVGImage(*image).ChromeClientForTesting();
+ To<SVGImage>(*image).ChromeClientForTesting();
TimerBase* timer = svg_image_chrome_client.GetTimerForTesting();
// Wait for the next animation frame to be triggered, and then trigger a new
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 0669fbb991d..aa759fa71bf 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(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
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(blink::Visitor* visitor) { visitor->Trace(attributes_); }
+ void Trace(Visitor* visitor) { 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 9f17ae8c23b..7aef7ddd25b 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(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
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(blink::Visitor* visitor) { visitor->Trace(attributes_); }
+ void Trace(Visitor* visitor) { visitor->Trace(attributes_); }
private:
PatternAttributes attributes_;
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 3dd5b4a38f5..7bcf423b221 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
@@ -101,7 +101,7 @@ class SVGAnimatedPropertyBase : public GarbageCollectedMixin {
private:
static_assert(kNumberOfAnimatedPropertyTypes <= (1u << 5),
"enough bits for AnimatedPropertyType (type_)");
- static constexpr int kCssPropertyBits = 9;
+ static constexpr int kCssPropertyBits = 10;
static_assert((1u << kCssPropertyBits) - 1 >= kIntLastCSSProperty,
"enough bits for CSS property ids");
@@ -161,7 +161,7 @@ class SVGAnimatedPropertyCommon : public SVGAnimatedPropertyBase {
SVGAnimatedPropertyBase::AnimationEnded();
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(base_value_);
visitor->Trace(current_value_);
SVGAnimatedPropertyBase::Trace(visitor);
@@ -273,7 +273,7 @@ class SVGAnimatedProperty<Property, TearOffType, void>
return anim_val_tear_off_;
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 251ea844c15..dfea5e8c7b6 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
@@ -124,7 +124,7 @@ class SVGListPropertyHelper : public SVGPropertyHelper<Derived> {
ItemPropertyType* AppendItem(ItemPropertyType*);
ItemPropertyType* ReplaceItem(ItemPropertyType*, uint32_t, ExceptionState&);
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(values_);
SVGPropertyHelper<Derived>::Trace(visitor);
}
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 6435cba39b1..a98b0cc5e5b 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
@@ -32,6 +32,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_PROPERTIES_SVG_LIST_PROPERTY_TEAR_OFF_HELPER_H_
#include "third_party/blink/renderer/core/svg/properties/svg_property_tear_off.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/wtf/type_traits.h"
@@ -141,11 +142,12 @@ class SVGListPropertyTearOffHelper : public SVGPropertyTearOff<ListProperty> {
return CreateItemTearOff(value);
}
- bool AnonymousIndexedSetter(uint32_t index,
- ItemTearOffType* item,
- ExceptionState& exception_state) {
+ IndexedPropertySetterResult AnonymousIndexedSetter(
+ uint32_t index,
+ ItemTearOffType* item,
+ ExceptionState& exception_state) {
replaceItem(item, index, exception_state);
- return true;
+ return IndexedPropertySetterResult::kIntercepted;
}
ItemTearOffType* removeItem(uint32_t index, ExceptionState& exception_state) {
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 752f1581be0..a58d5a8ea62 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(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
protected:
SVGPropertyBase() : owner_list_(nullptr) {}
@@ -99,11 +99,6 @@ class SVGPropertyBase : public GarbageCollected<SVGPropertyBase> {
DISALLOW_COPY_AND_ASSIGN(SVGPropertyBase);
};
-#define DEFINE_SVG_PROPERTY_TYPE_CASTS(thisType) \
- DEFINE_TYPE_CASTS(thisType, SVGPropertyBase, value, \
- value->GetType() == thisType::ClassType(), \
- value.GetType() == thisType::ClassType())
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SVG_PROPERTIES_SVG_PROPERTY_H_
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 d8edb8847f3..a2c2a97d1c9 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
@@ -90,7 +90,7 @@ class SVGPropertyTearOff : public SVGPropertyTearOffBase {
void SetTarget(Property* target) { target_ = target; }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 3947fe58940..9143d140e19 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(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
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(blink::Visitor* visitor) { visitor->Trace(attributes_); }
+ void Trace(Visitor* visitor) { 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 0626fca4b42..b27a8885972 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
@@ -22,6 +22,7 @@
#include "third_party/blink/renderer/core/svg/svg_a_element.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/attr.h"
#include "third_party/blink/renderer/core/dom/attribute.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -57,7 +58,7 @@ SVGAElement::SVGAElement(Document& document)
AddToPropertyMap(svg_target_);
}
-void SVGAElement::Trace(blink::Visitor* visitor) {
+void SVGAElement::Trace(Visitor* visitor) {
visitor->Trace(svg_target_);
SVGGraphicsElement::Trace(visitor);
SVGURIReference::Trace(visitor);
@@ -175,7 +176,7 @@ bool SVGAElement::SupportsFocus() const {
}
bool SVGAElement::ShouldHaveFocusAppearance() const {
- return (GetDocument().LastFocusType() != kWebFocusTypeMouse) ||
+ return (GetDocument().LastFocusType() != mojom::blink::FocusType::kMouse) ||
SVGGraphicsElement::SupportsFocus();
}
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 795ec7e21e5..79e0722aa83 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 37936c945bf..87d2ce53ce4 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_angle.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_angle.cc
@@ -47,7 +47,7 @@ SVGMarkerOrientEnumeration::SVGMarkerOrientEnumeration(SVGAngle* angle)
SVGMarkerOrientEnumeration::~SVGMarkerOrientEnumeration() = default;
-void SVGMarkerOrientEnumeration::Trace(blink::Visitor* visitor) {
+void SVGMarkerOrientEnumeration::Trace(Visitor* visitor) {
visitor->Trace(angle_);
SVGEnumeration<SVGMarkerOrientType>::Trace(visitor);
}
@@ -98,7 +98,7 @@ SVGAngle::SVGAngle(SVGAngleType unit_type,
SVGAngle::~SVGAngle() = default;
-void SVGAngle::Trace(blink::Visitor* visitor) {
+void SVGAngle::Trace(Visitor* visitor) {
visitor->Trace(orient_type_);
SVGPropertyHelper<SVGAngle>::Trace(visitor);
}
@@ -362,7 +362,7 @@ void SVGAngle::ConvertToSpecifiedUnits(SVGAngleType unit_type) {
}
void SVGAngle::Add(SVGPropertyBase* other, SVGElement*) {
- SVGAngle* other_angle = ToSVGAngle(other);
+ auto* other_angle = To<SVGAngle>(other);
// Only respect by animations, if from and by are both specified in angles
// (and not, for example, 'auto').
@@ -391,8 +391,8 @@ void SVGAngle::CalculateAnimatedValue(
SVGPropertyBase* to,
SVGPropertyBase* to_at_end_of_duration,
SVGElement*) {
- SVGAngle* from_angle = ToSVGAngle(from);
- SVGAngle* to_angle = ToSVGAngle(to);
+ 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();
@@ -407,13 +407,13 @@ void SVGAngle::CalculateAnimatedValue(
float animated_value = Value();
animation_element.AnimateAdditiveNumber(
percentage, repeat_count, from_angle->Value(), to_angle->Value(),
- ToSVGAngle(to_at_end_of_duration)->Value(), animated_value);
+ To<SVGAngle>(to_at_end_of_duration)->Value(), animated_value);
OrientType()->SetEnumValue(kSVGMarkerOrientAngle);
SetValue(animated_value);
}
float SVGAngle::CalculateDistance(SVGPropertyBase* other, SVGElement*) {
- return fabsf(Value() - ToSVGAngle(other)->Value());
+ return fabsf(Value() - To<SVGAngle>(other)->Value());
}
void SVGAngle::OrientTypeChanged() {
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 0544951fc90..4ec7825fb0a 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_angle.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_angle.h
@@ -26,6 +26,7 @@
#include "third_party/blink/renderer/core/svg/svg_enumeration.h"
#include "third_party/blink/renderer/core/svg/svg_parsing_error.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -56,7 +57,7 @@ class SVGMarkerOrientEnumeration final
SVGElement*) override;
float CalculateDistance(SVGPropertyBase*, SVGElement*) override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void NotifyChange() override;
@@ -130,7 +131,7 @@ class SVGAngle final : public SVGPropertyHelper<SVGAngle> {
static AnimatedPropertyType ClassType() { return kAnimatedAngle; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void Assign(const SVGAngle&);
@@ -140,7 +141,12 @@ class SVGAngle final : public SVGPropertyHelper<SVGAngle> {
Member<SVGMarkerOrientEnumeration> orient_type_;
};
-DEFINE_SVG_PROPERTY_TYPE_CASTS(SVGAngle);
+template <>
+struct DowncastTraits<SVGAngle> {
+ static bool AllowFrom(const SVGPropertyBase& value) {
+ return value.GetType() == SVGAngle::ClassType();
+ }
+};
} // namespace blink
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 326e8c2e901..16e66af4305 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
@@ -24,6 +24,7 @@
#include "third_party/blink/renderer/core/css/css_computed_style_declaration.h"
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
+#include "third_party/blink/renderer/core/css/css_style_sheet.h"
#include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/qualified_name.h"
@@ -180,9 +181,11 @@ void SVGAnimateElement::ResolveTargetProperty() {
}
} else {
type_ = SVGElement::AnimatedPropertyTypeForCSSAttribute(AttributeName());
- css_property_id_ = type_ != kAnimatedUnknown
- ? cssPropertyID(AttributeName().LocalName())
- : CSSPropertyID::kInvalid;
+ css_property_id_ =
+ type_ != kAnimatedUnknown
+ ? cssPropertyID(targetElement()->GetDocument().ToExecutionContext(),
+ AttributeName().LocalName())
+ : CSSPropertyID::kInvalid;
}
// Blacklist <script> targets here for now to prevent unpleasantries. This
// also disallows the perfectly "valid" animation of 'className' on said
@@ -486,11 +489,10 @@ void SVGAnimateElement::ApplyResultsToTarget() {
MutableCSSPropertyValueSet* properties =
target_element->EnsureAnimatedSMILStyleProperties();
auto animated_value_string = animated_value_->ValueAsString();
- auto secure_context_mode =
- target_element->GetDocument().GetSecureContextMode();
- auto set_result =
- properties->SetProperty(css_property_id_, animated_value_string, false,
- secure_context_mode, nullptr);
+ auto& document = target_element->GetDocument();
+ auto set_result = properties->SetProperty(
+ css_property_id_, animated_value_string, false,
+ document.GetSecureContextMode(), document.ElementSheet().Contents());
if (set_result.did_change) {
target_element->SetNeedsStyleRecalc(
kLocalStyleChange,
@@ -584,7 +586,7 @@ void SVGAnimateElement::SetAttributeType(
AnimationAttributeChanged();
}
-void SVGAnimateElement::Trace(blink::Visitor* visitor) {
+void SVGAnimateElement::Trace(Visitor* visitor) {
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 367d1150063..4411ec1b9c5 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
bool IsSVGAnimationAttributeSettingJavaScriptURL(
const Attribute&) const override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animate_motion_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_animate_motion_element.cc
index 4f9af01003f..6f5f39e60cb 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animate_motion_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animate_motion_element.cc
@@ -39,7 +39,7 @@ namespace {
bool TargetCanHaveMotionTransform(const SVGElement& target) {
// We don't have a special attribute name to verify the animation type. Check
// the element name instead.
- if (!target.IsSVGGraphicsElement())
+ if (!IsA<SVGGraphicsElement>(target))
return false;
// Spec: SVG 1.1 section 19.2.15
// FIXME: svgTag is missing. Needs to be checked, if transforming <svg> could
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 fbff94c5b50..e1044af8017 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(blink::Visitor* visitor) {
+void SVGAnimatedAngle::Trace(Visitor* visitor) {
visitor->Trace(orient_type_);
SVGAnimatedProperty<SVGAngle>::Trace(visitor);
ScriptWrappable::Trace(visitor);
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 ae5b0bdd051..4702d1e66b8 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 f657aaa0e28..1a1d4bd3619 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 3386504b0c9..355977b9ff7 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
@@ -60,7 +60,7 @@ void SVGColorProperty::Add(SVGPropertyBase* other,
Color fallback_color = FallbackColorForCurrentColor(context_element);
Color from_color =
- ToSVGColorProperty(other)->style_color_.Resolve(fallback_color);
+ To<SVGColorProperty>(other)->style_color_.Resolve(fallback_color);
Color to_color = style_color_.Resolve(fallback_color);
style_color_ = StyleColor(ColorDistance::AddColors(from_color, to_color));
}
@@ -73,10 +73,10 @@ void SVGColorProperty::CalculateAnimatedValue(
SVGPropertyBase* to_value,
SVGPropertyBase* to_at_end_of_duration_value,
SVGElement* context_element) {
- StyleColor from_style_color = ToSVGColorProperty(from_value)->style_color_;
- StyleColor to_style_color = ToSVGColorProperty(to_value)->style_color_;
+ StyleColor from_style_color = To<SVGColorProperty>(from_value)->style_color_;
+ StyleColor to_style_color = To<SVGColorProperty>(to_value)->style_color_;
StyleColor to_at_end_of_duration_style_color =
- ToSVGColorProperty(to_at_end_of_duration_value)->style_color_;
+ To<SVGColorProperty>(to_at_end_of_duration_value)->style_color_;
// Apply currentColor rules.
DCHECK(context_element);
@@ -119,7 +119,7 @@ float SVGColorProperty::CalculateDistance(SVGPropertyBase* to_value,
Color from_color = style_color_.Resolve(fallback_color);
Color to_color =
- ToSVGColorProperty(to_value)->style_color_.Resolve(fallback_color);
+ To<SVGColorProperty>(to_value)->style_color_.Resolve(fallback_color);
return ColorDistance::Distance(from_color, to_color);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_color.h b/chromium/third_party/blink/renderer/core/svg/svg_animated_color.h
index 4a277f7c014..18ea4d13162 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_animated_color.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_color.h
@@ -33,6 +33,7 @@
#include "third_party/blink/renderer/core/css/style_color.h"
#include "third_party/blink/renderer/core/svg/properties/svg_property.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -63,7 +64,12 @@ class SVGColorProperty final : public SVGPropertyBase {
StyleColor style_color_;
};
-DEFINE_SVG_PROPERTY_TYPE_CASTS(SVGColorProperty);
+template <>
+struct DowncastTraits<SVGColorProperty> {
+ static bool AllowFrom(const SVGPropertyBase& value) {
+ return value.GetType() == SVGColorProperty::ClassType();
+ }
+};
} // 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 99e99ffb5b0..6ed348fb8a5 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
@@ -48,7 +48,7 @@ class SVGAnimatedEnumerationBase
void setBaseVal(uint16_t, ExceptionState&);
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
SVGAnimatedProperty<SVGEnumerationBase>::Trace(visitor);
ScriptWrappable::Trace(visitor);
}
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 dbe66f415b2..9d0bce7ecb3 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,7 @@
namespace blink {
-void SVGAnimatedHref::Trace(blink::Visitor* visitor) {
+void SVGAnimatedHref::Trace(Visitor* visitor) {
visitor->Trace(xlink_href_);
SVGAnimatedString::Trace(visitor);
}
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 77bb26bb19a..807f6145b48 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
@@ -35,7 +35,7 @@ class SVGAnimatedHref final : public SVGAnimatedString {
static bool IsKnownAttribute(const QualifiedName&);
void AddToPropertyMap(SVGElement*);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 1b311097ddb..14c630b5ada 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(blink::Visitor* visitor) {
+void SVGAnimatedInteger::Trace(Visitor* visitor) {
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 0f35ecc2bb1..ce95e61066c 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 47a129e46fe..4e13a4a7be1 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(blink::Visitor* visitor) {
+void SVGAnimatedIntegerOptionalInteger::Trace(Visitor* visitor) {
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 c637a4f1a08..2378c5ded90 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 72f7c264bda..bb89af577ec 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(blink::Visitor* visitor) {
+void SVGAnimatedLength::Trace(Visitor* visitor) {
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 2c134fe3f2a..f2fb5351fc6 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 56960d00991..e65babb3577 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 04abbd92fbb..5224f2b880e 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(blink::Visitor* visitor) {
+void SVGAnimatedNumber::Trace(Visitor* visitor) {
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 6ac22951d51..1f31b2675a4 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 64c96c1b146..ed78b7a454f 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 3a465f15698..4f05129af86 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(blink::Visitor* visitor) {
+void SVGAnimatedNumberOptionalNumber::Trace(Visitor* visitor) {
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 dc7a84f099f..a8b0d462136 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 99ef12fe3d8..b9643d84d78 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 e23c08021e9..da6dffd7fd6 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 8804faf0356..649221ed5a7 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
@@ -19,7 +19,7 @@ String SVGAnimatedString::animVal() {
return SVGAnimatedProperty<SVGString>::animVal();
}
-void SVGAnimatedString::Trace(blink::Visitor* visitor) {
+void SVGAnimatedString::Trace(Visitor* visitor) {
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 cf8f5e489fa..971ef0b4d9c 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
@@ -54,7 +54,7 @@ class SVGAnimatedString : public ScriptWrappable,
virtual void setBaseVal(const String&, ExceptionState&);
virtual String animVal();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
};
} // namespace blink
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 c5cad77f618..5e413bd8ff3 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
SVGAnimatedProperty<SVGTransformList>::Trace(visitor);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_boolean.h b/chromium/third_party/blink/renderer/core/svg/svg_boolean.h
index f463bc03402..62858b532c2 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_boolean.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_boolean.h
@@ -69,8 +69,6 @@ class SVGBoolean final : public SVGPropertyHelper<SVGBoolean> {
bool value_;
};
-DEFINE_SVG_PROPERTY_TYPE_CASTS(SVGBoolean);
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_BOOLEAN_H_
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 56a34701086..6ec31ddde90 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(blink::Visitor* visitor) {
+void SVGCircleElement::Trace(Visitor* visitor) {
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 fcc8e535427..56ef0c7bab8 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 676b342ead2..c48dd93af9a 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(blink::Visitor* visitor) {
+void SVGClipPathElement::Trace(Visitor* visitor) {
visitor->Trace(clip_path_units_);
SVGGraphicsElement::Trace(visitor);
}
@@ -58,7 +58,7 @@ void SVGClipPathElement::SvgAttributeChanged(const QualifiedName& attr_name) {
void SVGClipPathElement::ChildrenChanged(const ChildrenChange& change) {
SVGGraphicsElement::ChildrenChanged(change);
- if (change.by_parser)
+ if (change.ByParser())
return;
if (LayoutObject* object = GetLayoutObject()) {
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 ed32c00bd32..66fb5ba08c4 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 a1d66a35b3a..c4148a8c1e1 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(blink::Visitor* visitor) {
+void SVGComponentTransferFunctionElement::Trace(Visitor* visitor) {
visitor->Trace(table_values_);
visitor->Trace(slope_);
visitor->Trace(intercept_);
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 1d1eeb8162e..bb8c936f776 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
SVGComponentTransferFunctionElement(const QualifiedName&, Document&);
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_discard_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_discard_element.cc
deleted file mode 100644
index f729bdf37b2..00000000000
--- a/chromium/third_party/blink/renderer/core/svg/svg_discard_element.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2014 Samsung Electronics. 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/svg/svg_discard_element.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/svg_names.h"
-
-namespace blink {
-
-SVGDiscardElement::SVGDiscardElement(Document& document)
- : SVGSMILElement(svg_names::kDiscardTag, document) {
- UseCounter::Count(&GetDocument(), WebFeature::kSVGSMILDiscardElementParsed);
-}
-
-void SVGDiscardElement::StartedActiveInterval() {
- SVGSMILElement::StartedActiveInterval();
- QueueDiscard();
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_discard_element.h b/chromium/third_party/blink/renderer/core/svg/svg_discard_element.h
deleted file mode 100644
index 8c9867f8d1a..00000000000
--- a/chromium/third_party/blink/renderer/core/svg/svg_discard_element.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2014 Samsung Electronics. 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.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_DISCARD_ELEMENT_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_DISCARD_ELEMENT_H_
-
-#include "third_party/blink/renderer/core/svg/animation/svg_smil_element.h"
-
-namespace blink {
-
-class SVGDiscardElement final : public SVGSMILElement {
- DEFINE_WRAPPERTYPEINFO();
-
- public:
- explicit SVGDiscardElement(Document&);
-
- bool IsSVGDiscardElement() const override { return true; }
-
- private:
- void StartedActiveInterval() override;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_DISCARD_ELEMENT_H_
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_discard_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_discard_element.idl
deleted file mode 100644
index be85d164920..00000000000
--- a/chromium/third_party/blink/renderer/core/svg/svg_discard_element.idl
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2014 Samsung Electronics. 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.
- */
-
-// https://svgwg.org/specs/animations/#InterfaceSVGDiscardElement
-
-interface SVGDiscardElement : SVGElement {
-};
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 ebd83a85d12..28834f7ccdd 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(blink::Visitor* visitor) {
+void SVGDocumentExtensions::Trace(Visitor* visitor) {
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 abce5e913f8..cf22eaa6011 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
@@ -22,6 +22,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_DOCUMENT_EXTENSIONS_H_
#include "base/macros.h"
+#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/svg/svg_resources_cache.h"
#include "third_party/blink/renderer/platform/geometry/float_point.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -35,7 +36,7 @@ class SVGElement;
class SVGSVGElement;
class SubtreeLayoutScope;
-class SVGDocumentExtensions final
+class CORE_EXPORT SVGDocumentExtensions final
: public GarbageCollected<SVGDocumentExtensions> {
public:
explicit SVGDocumentExtensions(Document*);
@@ -70,7 +71,7 @@ class SVGDocumentExtensions final
static SVGSVGElement* rootElement(const Document&);
SVGSVGElement* rootElement() const;
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
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 899109d37d5..71de49ebb40 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_element.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_element.cc
@@ -38,6 +38,7 @@
#include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
+#include "third_party/blink/renderer/core/dom/events/add_event_listener_options_resolved.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
@@ -88,13 +89,6 @@ void SVGElement::DetachLayoutTree(bool performing_reattach) {
SvgRareData()->ClearOverriddenComputedStyle();
}
-TreeScope& SVGElement::TreeScopeForIdResolution() const {
- const SVGElement* tree_scope_element = this;
- if (const SVGElement* element = CorrespondingUseElement())
- tree_scope_element = element;
- return tree_scope_element->GetTreeScope();
-}
-
void SVGElement::WillRecalcStyle(const StyleRecalcChange change) {
if (!HasSVGRareData())
return;
@@ -145,10 +139,10 @@ void SVGElement::ReportAttributeParsingError(SVGParsingError error,
// Don't report any errors on attribute removal.
if (value.IsNull())
return;
- GetDocument().AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kRendering,
- mojom::ConsoleMessageLevel::kError,
- "Error: " + error.Format(tagName(), name, value)));
+ GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kRendering,
+ mojom::ConsoleMessageLevel::kError,
+ "Error: " + error.Format(tagName(), name, value)));
}
String SVGElement::title() const {
@@ -186,7 +180,7 @@ void SVGElement::SetInstanceUpdatesBlocked(bool value) {
void SVGElement::SetWebAnimationsPending() {
GetDocument().AccessSVGExtensions().AddWebAnimationsPendingSVGElement(*this);
EnsureSVGRareData()->SetWebAnimatedAttributesDirty(true);
- EnsureUniqueElementData().animated_svg_attributes_are_dirty_ = true;
+ EnsureUniqueElementData().SetAnimatedSvgAttributesAreDirty(true);
}
static bool IsSVGAttributeHandle(const PropertyHandle& property_handle) {
@@ -302,28 +296,23 @@ AffineTransform SVGElement::CalculateTransform(
Node::InsertionNotificationRequest SVGElement::InsertedInto(
ContainerNode& root_parent) {
Element::InsertedInto(root_parent);
+ HideNonce();
UpdateRelativeLengthsInformation();
-
- const AtomicString& nonce_value = FastGetAttribute(html_names::kNonceAttr);
- if (!nonce_value.IsEmpty()) {
- setNonce(nonce_value);
- if (InActiveDocument() &&
- GetDocument().GetContentSecurityPolicy()->HasHeaderDeliveredPolicy()) {
- setAttribute(html_names::kNonceAttr, g_empty_atom);
- }
- }
return kInsertionDone;
}
void SVGElement::RemovedFrom(ContainerNode& root_parent) {
bool was_in_document = root_parent.isConnected();
- auto* root_parent_svg_element = DynamicTo<SVGElement>(root_parent);
+ auto* root_parent_svg_element = DynamicTo<SVGElement>(
+ root_parent.IsShadowRoot() ? root_parent.ParentOrShadowHostElement()
+ : &root_parent);
+
if (was_in_document && HasRelativeLengths()) {
// The root of the subtree being removed should take itself out from its
// parent's relative length set. For the other nodes in the subtree we don't
// need to do anything: they will get their own removedFrom() notification
// and just clear their sets.
- if (root_parent_svg_element && !parentNode()) {
+ if (root_parent_svg_element && !ParentOrShadowHostElement()) {
DCHECK(root_parent_svg_element->elements_with_relative_lengths_.Contains(
this));
root_parent_svg_element->UpdateRelativeLengthsInformation(false, this);
@@ -332,13 +321,15 @@ void SVGElement::RemovedFrom(ContainerNode& root_parent) {
elements_with_relative_lengths_.clear();
}
- SECURITY_DCHECK(
+ DCHECK(
!root_parent_svg_element ||
!root_parent_svg_element->elements_with_relative_lengths_.Contains(this));
Element::RemovedFrom(root_parent);
if (was_in_document) {
+ if (HasSVGRareData() && SvgRareData()->CorrespondingElement())
+ SvgRareData()->CorrespondingElement()->RemoveInstanceMapping(this);
RebuildAllIncomingReferences();
RemoveAllIncomingReferences();
}
@@ -354,6 +345,7 @@ void SVGElement::ChildrenChanged(const ChildrenChange& change) {
}
CSSPropertyID SVGElement::CssPropertyIdForSVGAttributeName(
+ const ExecutionContext* execution_context,
const QualifiedName& attr_name) {
if (!attr_name.NamespaceURI().IsNull())
return CSSPropertyID::kInvalid;
@@ -424,7 +416,8 @@ CSSPropertyID SVGElement::CssPropertyIdForSVGAttributeName(
&svg_names::kWritingModeAttr,
};
for (size_t i = 0; i < base::size(attr_names); i++) {
- CSSPropertyID property_id = cssPropertyID(attr_names[i]->LocalName());
+ CSSPropertyID property_id =
+ cssPropertyID(execution_context, attr_names[i]->LocalName());
DCHECK_GT(property_id, CSSPropertyID::kInvalid);
property_name_to_id_map->Set(attr_names[i]->LocalName().Impl(),
property_id);
@@ -446,8 +439,9 @@ void SVGElement::UpdateRelativeLengthsInformation(
// disconnected.
// If we're not yet in a document, this function will be called again from
// insertedInto(). Do nothing now.
- for (Node& current_node : NodeTraversal::InclusiveAncestorsOf(*this)) {
- if (!current_node.isConnected())
+ for (Node* current_node = this; current_node;
+ current_node = current_node->ParentOrShadowHostNode()) {
+ if (!current_node->isConnected())
return;
}
@@ -455,10 +449,12 @@ void SVGElement::UpdateRelativeLengthsInformation(
// Register it in the relative length map, and register us in the parent
// relative length map. Register the parent in the grandparents map, etc.
// Repeat procedure until the root of the SVG tree.
- for (Node& current_node : NodeTraversal::InclusiveAncestorsOf(*this)) {
+ for (Element* current_node = this; current_node;
+ current_node = current_node->ParentOrShadowHostElement()) {
auto* current_element = DynamicTo<SVGElement>(current_node);
if (!current_element)
break;
+
#if DCHECK_IS_ON()
DCHECK(!current_element->in_relative_length_clients_invalidation_);
#endif
@@ -558,10 +554,8 @@ void SVGElement::MapInstanceToElement(SVGElement* instance) {
void SVGElement::RemoveInstanceMapping(SVGElement* instance) {
DCHECK(instance);
- DCHECK(instance->InUseShadowTree());
-
- if (!HasSVGRareData())
- return;
+ // Called during instance->RemovedFrom() after removal from shadow tree
+ DCHECK(!instance->isConnected());
HeapHashSet<WeakMember<SVGElement>>& instances =
SvgRareData()->ElementInstances();
@@ -589,7 +583,7 @@ SVGElement* SVGElement::CorrespondingElement() const {
return HasSVGRareData() ? SvgRareData()->CorrespondingElement() : nullptr;
}
-SVGUseElement* SVGElement::CorrespondingUseElement() const {
+SVGUseElement* SVGElement::GeneratingUseElement() const {
if (ShadowRoot* root = ContainingShadowRoot()) {
return DynamicTo<SVGUseElement>(root->host());
}
@@ -601,7 +595,7 @@ void SVGElement::SetCorrespondingElement(SVGElement* corresponding_element) {
}
bool SVGElement::InUseShadowTree() const {
- return CorrespondingUseElement();
+ return GeneratingUseElement();
}
void SVGElement::ParseAttribute(const AttributeModificationParams& params) {
@@ -618,6 +612,12 @@ void SVGElement::ParseAttribute(const AttributeModificationParams& params) {
return;
}
+ // SVGElement and HTMLElement are handling "nonce" the same way.
+ if (params.name == html_names::kNonceAttr) {
+ if (params.new_value != g_empty_atom)
+ setNonce(params.new_value);
+ }
+
const AtomicString& event_name =
HTMLElement::EventNameForAttributeName(params.name);
if (!event_name.IsNull()) {
@@ -735,14 +735,16 @@ bool SVGElement::IsAnimatableCSSProperty(const QualifiedName& attr_name) {
bool SVGElement::IsPresentationAttribute(const QualifiedName& name) const {
if (const SVGAnimatedPropertyBase* property = PropertyFromAttribute(name))
return property->HasPresentationAttributeMapping();
- return CssPropertyIdForSVGAttributeName(name) > CSSPropertyID::kInvalid;
+ return CssPropertyIdForSVGAttributeName(GetDocument().ToExecutionContext(),
+ name) > CSSPropertyID::kInvalid;
}
void SVGElement::CollectStyleForPresentationAttribute(
const QualifiedName& name,
const AtomicString& value,
MutableCSSPropertyValueSet* style) {
- CSSPropertyID property_id = CssPropertyIdForSVGAttributeName(name);
+ CSSPropertyID property_id = CssPropertyIdForSVGAttributeName(
+ GetDocument().ToExecutionContext(), name);
if (property_id > CSSPropertyID::kInvalid)
AddPropertyToPresentationAttributeStyle(style, property_id, value);
}
@@ -875,8 +877,8 @@ void SVGElement::AttributeChanged(const AttributeModificationParams& params) {
}
void SVGElement::SvgAttributeChanged(const QualifiedName& attr_name) {
- CSSPropertyID prop_id =
- SVGElement::CssPropertyIdForSVGAttributeName(attr_name);
+ CSSPropertyID prop_id = SVGElement::CssPropertyIdForSVGAttributeName(
+ GetDocument().ToExecutionContext(), attr_name);
if (prop_id > CSSPropertyID::kInvalid) {
InvalidateInstances();
return;
@@ -898,7 +900,7 @@ void SVGElement::SvgAttributeBaseValChanged(const QualifiedName& attribute) {
// TODO(alancutter): Only mark attributes as dirty if their animation depends
// on the underlying value.
SvgRareData()->SetWebAnimatedAttributesDirty(true);
- GetElementData()->animated_svg_attributes_are_dirty_ = true;
+ GetElementData()->SetAnimatedSvgAttributesAreDirty(true);
}
void SVGElement::EnsureAttributeAnimValUpdated() {
@@ -907,8 +909,8 @@ void SVGElement::EnsureAttributeAnimValUpdated() {
if ((HasSVGRareData() && SvgRareData()->WebAnimatedAttributesDirty()) ||
(GetElementAnimations() &&
- DocumentAnimations::NeedsAnimationTimingUpdate(GetDocument()))) {
- DocumentAnimations::UpdateAnimationTimingIfNeeded(GetDocument());
+ GetDocument().GetDocumentAnimations().NeedsAnimationTimingUpdate())) {
+ GetDocument().GetDocumentAnimations().UpdateAnimationTimingIfNeeded();
ApplyActiveWebAnimations();
}
}
@@ -916,7 +918,7 @@ void SVGElement::EnsureAttributeAnimValUpdated() {
void SVGElement::SynchronizeAnimatedSVGAttribute(
const QualifiedName& name) const {
if (!GetElementData() ||
- !GetElementData()->animated_svg_attributes_are_dirty_)
+ !GetElementData()->animated_svg_attributes_are_dirty())
return;
// We const_cast here because we have deferred baseVal mutation animation
@@ -933,7 +935,7 @@ void SVGElement::SynchronizeAnimatedSVGAttribute(
(*it)->SynchronizeAttribute();
}
- GetElementData()->animated_svg_attributes_are_dirty_ = false;
+ GetElementData()->SetAnimatedSvgAttributesAreDirty(false);
} else {
SVGAnimatedPropertyBase* property = attribute_to_property_map_.at(name);
if (property && property->NeedsSynchronizeAttribute())
@@ -1015,9 +1017,9 @@ void SVGElement::InvalidateInstances() {
for (SVGElement* instance : set) {
instance->SetCorrespondingElement(nullptr);
- if (SVGUseElement* element = instance->CorrespondingUseElement()) {
- if (element->isConnected())
- element->InvalidateShadowTree();
+ if (SVGUseElement* element = instance->GeneratingUseElement()) {
+ DCHECK(element->isConnected());
+ element->InvalidateShadowTree();
}
}
@@ -1218,17 +1220,17 @@ void SVGElement::RemoveAllOutgoingReferences() {
outgoing_references.clear();
}
-SVGResourceClient* SVGElement::GetSVGResourceClient() {
+SVGElementResourceClient* SVGElement::GetSVGResourceClient() {
if (!HasSVGRareData())
return nullptr;
return SvgRareData()->GetSVGResourceClient();
}
-SVGResourceClient& SVGElement::EnsureSVGResourceClient() {
+SVGElementResourceClient& SVGElement::EnsureSVGResourceClient() {
return EnsureSVGRareData()->EnsureSVGResourceClient(this);
}
-void SVGElement::Trace(blink::Visitor* visitor) {
+void SVGElement::Trace(Visitor* visitor) {
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 fd280a1383b..c11a50ffb0d 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_element.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_element.h
@@ -38,13 +38,14 @@ namespace blink {
class AffineTransform;
class Document;
class ElementSMILAnimations;
+class ExecutionContext;
class SVGAnimatedPropertyBase;
class SubtreeLayoutScope;
class SVGAnimatedString;
class SVGElement;
class SVGElementRareData;
+class SVGElementResourceClient;
class SVGPropertyBase;
-class SVGResourceClient;
class SVGSVGElement;
class SVGUseElement;
@@ -58,10 +59,6 @@ class CORE_EXPORT SVGElement : public Element {
bool SupportsFocus() const override { return false; }
- // The TreeScope this element should resolve id's against. This differs from
- // the regular Node::treeScope() by taking <use> into account.
- TreeScope& TreeScopeForIdResolution() const;
-
bool IsOutermostSVGSVGElement() const;
bool HasTagName(const SVGQualifiedName& name) const {
@@ -135,10 +132,10 @@ class CORE_EXPORT SVGElement : public Element {
virtual AffineTransform* AnimateMotionTransform() { return nullptr; }
void InvalidateSVGAttributes() {
- EnsureUniqueElementData().animated_svg_attributes_are_dirty_ = true;
+ EnsureUniqueElementData().SetAnimatedSvgAttributesAreDirty(true);
}
void InvalidateSVGPresentationAttributeStyle() {
- EnsureUniqueElementData().presentation_attribute_style_is_dirty_ = true;
+ EnsureUniqueElementData().SetPresentationAttributeStyleIsDirty(true);
}
const HeapHashSet<WeakMember<SVGElement>>& InstancesForElement() const;
@@ -147,7 +144,7 @@ class CORE_EXPORT SVGElement : public Element {
SVGElement* CorrespondingElement() const;
void SetCorrespondingElement(SVGElement*);
- SVGUseElement* CorrespondingUseElement() const;
+ SVGUseElement* GeneratingUseElement() const;
void SynchronizeAnimatedSVGAttribute(const QualifiedName&) const;
@@ -179,8 +176,8 @@ class CORE_EXPORT SVGElement : public Element {
void RemoveAllIncomingReferences();
void RemoveAllOutgoingReferences();
- SVGResourceClient* GetSVGResourceClient();
- SVGResourceClient& EnsureSVGResourceClient();
+ SVGElementResourceClient* GetSVGResourceClient();
+ SVGElementResourceClient& EnsureSVGResourceClient();
class InvalidationGuard {
STACK_ALLOCATED();
@@ -190,7 +187,7 @@ class CORE_EXPORT SVGElement : public Element {
~InvalidationGuard() { element_->InvalidateInstances(); }
private:
- Member<SVGElement> element_;
+ SVGElement* element_;
DISALLOW_COPY_AND_ASSIGN(InvalidationGuard);
};
@@ -202,7 +199,7 @@ class CORE_EXPORT SVGElement : public Element {
~InstanceUpdateBlocker();
private:
- Member<SVGElement> target_element_;
+ SVGElement* target_element_;
DISALLOW_COPY_AND_ASSIGN(InstanceUpdateBlocker);
};
@@ -210,7 +207,7 @@ class CORE_EXPORT SVGElement : public Element {
void SetNeedsStyleRecalcForInstances(StyleChangeType,
const StyleChangeReasonForTracing&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
static const AtomicString& EventParameterName();
@@ -237,7 +234,8 @@ class CORE_EXPORT SVGElement : public Element {
void DetachLayoutTree(bool performing_reattach) override;
- static CSSPropertyID CssPropertyIdForSVGAttributeName(const QualifiedName&);
+ static CSSPropertyID CssPropertyIdForSVGAttributeName(const ExecutionContext*,
+ const QualifiedName&);
void UpdateRelativeLengthsInformation() {
UpdateRelativeLengthsInformation(SelfHasRelativeLengths(), this);
}
@@ -334,49 +332,25 @@ struct SVGAttributeHashTranslator {
}
};
-DEFINE_ELEMENT_TYPE_CASTS(SVGElement, IsSVGElement());
-
-template <>
-struct DowncastTraits<SVGElement> {
- static bool AllowFrom(const Node& node) { return node.IsSVGElement(); }
-};
-
template <typename T>
bool IsElementOfType(const SVGElement&);
template <>
inline bool IsElementOfType<const SVGElement>(const SVGElement&) {
return true;
}
-
+template <>
+inline bool IsElementOfType<const SVGElement>(const Node& node) {
+ return IsA<SVGElement>(node);
+}
+template <>
+struct DowncastTraits<SVGElement> {
+ static bool AllowFrom(const Node& node) { return node.IsSVGElement(); }
+};
inline bool Node::HasTagName(const SVGQualifiedName& name) const {
auto* svg_element = DynamicTo<SVGElement>(this);
return svg_element && svg_element->HasTagName(name);
}
-// This requires IsSVG*Element(const SVGElement&).
-#define DEFINE_SVGELEMENT_TYPE_CASTS_WITH_FUNCTION(thisType) \
- inline bool Is##thisType(const thisType* element); \
- inline bool Is##thisType(const thisType& element); \
- inline bool Is##thisType(const SVGElement* element) { \
- return element && Is##thisType(*element); \
- } \
- inline bool Is##thisType(const Node& node) { \
- auto* svg_element = DynamicTo<SVGElement>(node); \
- return svg_element && Is##thisType(svg_element); \
- } \
- inline bool Is##thisType(const Node* node) { \
- return node && Is##thisType(*node); \
- } \
- template <typename T> \
- inline bool Is##thisType(const Member<T>& node) { \
- return Is##thisType(node.Get()); \
- } \
- template <> \
- inline bool IsElementOfType<const thisType>(const SVGElement& element) { \
- return Is##thisType(element); \
- } \
- DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(thisType)
-
} // namespace blink
#include "third_party/blink/renderer/core/svg_element_type_helpers.h"
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 6232b3291b3..7e01c8db53f 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
@@ -50,14 +50,14 @@ void SVGElementRareData::ClearOverriddenComputedStyle() {
override_computed_style_ = nullptr;
}
-SVGResourceClient& SVGElementRareData::EnsureSVGResourceClient(
+SVGElementResourceClient& SVGElementRareData::EnsureSVGResourceClient(
SVGElement* element) {
if (!resource_client_)
resource_client_ = MakeGarbageCollected<SVGElementResourceClient>(element);
return *resource_client_;
}
-void SVGElementRareData::Trace(blink::Visitor* visitor) {
+void SVGElementRareData::Trace(Visitor* visitor) {
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 79a801d5289..f68e1069979 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
@@ -30,7 +30,7 @@
namespace blink {
class ElementSMILAnimations;
-class SVGResourceClient;
+class SVGElementResourceClient;
class SVGElementRareData final : public GarbageCollected<SVGElementRareData> {
public:
@@ -99,19 +99,19 @@ class SVGElementRareData final : public GarbageCollected<SVGElementRareData> {
needs_override_computed_style_update_ = true;
}
- SVGResourceClient* GetSVGResourceClient() { return resource_client_; }
- SVGResourceClient& EnsureSVGResourceClient(SVGElement*);
+ SVGElementResourceClient* GetSVGResourceClient() { return resource_client_; }
+ SVGElementResourceClient& EnsureSVGResourceClient(SVGElement*);
AffineTransform* AnimateMotionTransform();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
SVGElementSet outgoing_references_;
SVGElementSet incoming_references_;
HeapHashSet<WeakMember<SVGElement>> element_instances_;
Member<SVGElement> corresponding_element_;
- Member<SVGResourceClient> resource_client_;
+ Member<SVGElementResourceClient> resource_client_;
Member<ElementSMILAnimations> smil_animations_;
bool instances_updates_blocked_ : 1;
bool use_override_computed_style_ : 1;
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 a677606e52e..83220afa1a5 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(blink::Visitor* visitor) {
+void SVGEllipseElement::Trace(Visitor* visitor) {
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 82546aef9b9..7ba0af3f1db 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 6bb6c45c39e..3a7a398bf39 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_enumeration.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_enumeration.cc
@@ -34,8 +34,6 @@
namespace blink {
-DEFINE_SVG_PROPERTY_TYPE_CASTS(SVGEnumerationBase);
-
SVGEnumerationBase::~SVGEnumerationBase() = default;
SVGPropertyBase* SVGEnumerationBase::CloneForAnimation(
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 f54e33a9ead..996a30cc855 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(blink::Visitor* visitor) {
+void SVGFEBlendElement::Trace(Visitor* visitor) {
visitor->Trace(in1_);
visitor->Trace(in2_);
visitor->Trace(mode_);
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 04f23d4b581..4fd2ea96ca0 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 7f330c52c83..0a4651ec757 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(blink::Visitor* visitor) {
+void SVGFEColorMatrixElement::Trace(Visitor* visitor) {
visitor->Trace(values_);
visitor->Trace(in1_);
visitor->Trace(type_);
@@ -100,9 +100,8 @@ FilterEffect* SVGFEColorMatrixElement::Build(SVGFilterBuilder* filter_builder,
DCHECK(input1);
ColorMatrixType filter_type = type_->CurrentValue()->EnumValue();
- Vector<float> filter_values = values_->CurrentValue()->ToFloatVector();
- auto* effect =
- MakeGarbageCollected<FEColorMatrix>(filter, filter_type, filter_values);
+ auto* effect = MakeGarbageCollected<FEColorMatrix>(
+ filter, filter_type, values_->CurrentValue()->ToFloatVector());
effect->InputEffects().push_back(input1);
return effect;
}
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 4485776b8e3..aedf2140077 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 484d848481d..1464024dc7c 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(blink::Visitor* visitor) {
+void SVGFEComponentTransferElement::Trace(Visitor* visitor) {
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 bde46e74aa6..2c2f3ed758c 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 f5111a66c41..0613666c59d 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(blink::Visitor* visitor) {
+void SVGFECompositeElement::Trace(Visitor* visitor) {
visitor->Trace(k1_);
visitor->Trace(k2_);
visitor->Trace(k3_);
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 e00672c92a3..63cac0f631b 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 c1037941375..d37f9815c99 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(blink::Visitor* visitor) {
+void SVGFEConvolveMatrixElement::Trace(Visitor* visitor) {
visitor->Trace(bias_);
visitor->Trace(divisor_);
visitor->Trace(in1_);
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 8653b5d5c35..c5916541436 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 40ef837d9c2..58e58653468 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(blink::Visitor* visitor) {
+void SVGFEDiffuseLightingElement::Trace(Visitor* visitor) {
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 840cbaf862c..d93cf6520e8 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 429abf4d94a..bfd5b1e2997 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(blink::Visitor* visitor) {
+void SVGFEDisplacementMapElement::Trace(Visitor* visitor) {
visitor->Trace(scale_);
visitor->Trace(in1_);
visitor->Trace(in2_);
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 c29316a6023..0dafd29b177 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 abe97601a32..7cced8f4409 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(blink::Visitor* visitor) {
+void SVGFEDropShadowElement::Trace(Visitor* visitor) {
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 8607927519a..ce229e782b2 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 a7d0e0571cd..51933a73a5f 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(blink::Visitor* visitor) {
+void SVGFEGaussianBlurElement::Trace(Visitor* visitor) {
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 3096ffcf616..9dc19929d39 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 3668936a8eb..e56a87a6e2f 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(blink::Visitor* visitor) {
+void SVGFEImageElement::Trace(Visitor* visitor) {
visitor->Trace(preserve_aspect_ratio_);
visitor->Trace(cached_image_);
visitor->Trace(target_id_observer_);
@@ -158,8 +158,9 @@ FilterEffect* SVGFEImageElement::Build(SVGFilterBuilder*, Filter* filter) {
return MakeGarbageCollected<FEImage>(
filter, image, preserve_aspect_ratio_->CurrentValue());
}
-
- return MakeGarbageCollected<FEImage>(filter, GetTreeScope(), HrefString(),
+ const SVGElement* target = DynamicTo<SVGElement>(
+ TargetElementFromIRIString(HrefString(), GetTreeScope()));
+ return MakeGarbageCollected<FEImage>(filter, target,
preserve_aspect_ratio_->CurrentValue());
}
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 9d38de5e87e..ce245c2c170 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
@@ -50,7 +50,7 @@ class SVGFEImageElement final : public SVGFilterPrimitiveStandardAttributes,
void Dispose();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 32407fb7b3e..80aa829c848 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(blink::Visitor* visitor) {
+void SVGFELightElement::Trace(Visitor* visitor) {
visitor->Trace(azimuth_);
visitor->Trace(elevation_);
visitor->Trace(x_);
@@ -127,7 +127,7 @@ void SVGFELightElement::SvgAttributeChanged(const QualifiedName& attr_name) {
return;
LayoutObject* layout_object = parent->GetLayoutObject();
- if (!layout_object || !layout_object->IsSVGResourceFilterPrimitive())
+ if (!layout_object || !layout_object->IsSVGFilterPrimitive())
return;
SVGElement::InvalidationGuard invalidation_guard(this);
@@ -145,10 +145,10 @@ void SVGFELightElement::SvgAttributeChanged(const QualifiedName& attr_name) {
void SVGFELightElement::ChildrenChanged(const ChildrenChange& change) {
SVGElement::ChildrenChanged(change);
- if (!change.by_parser) {
+ if (!change.ByParser()) {
if (ContainerNode* parent = parentNode()) {
LayoutObject* layout_object = parent->GetLayoutObject();
- if (layout_object && layout_object->IsSVGResourceFilterPrimitive())
+ if (layout_object && layout_object->IsSVGFilterPrimitive())
MarkForLayoutAndParentResourceInvalidation(*layout_object);
}
}
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 aad4aad8f38..d416833aa04 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
SVGFELightElement(const QualifiedName&, Document&);
@@ -90,13 +90,22 @@ class SVGFELightElement : public SVGElement {
Member<SVGAnimatedNumber> limiting_cone_angle_;
};
-inline bool IsSVGFELightElement(const SVGElement& element) {
- return element.HasTagName(svg_names::kFEDistantLightTag) ||
- element.HasTagName(svg_names::kFEPointLightTag) ||
- element.HasTagName(svg_names::kFESpotLightTag);
+template <>
+inline bool IsElementOfType<const SVGFELightElement>(const Node& node) {
+ return IsA<SVGFELightElement>(node);
}
-
-DEFINE_SVGELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGFELightElement);
+template <>
+struct DowncastTraits<SVGFELightElement> {
+ static bool AllowFrom(const Node& node) {
+ auto* svg_element = DynamicTo<SVGElement>(node);
+ return svg_element && AllowFrom(*svg_element);
+ }
+ static bool AllowFrom(const SVGElement& svg_element) {
+ return svg_element.HasTagName(svg_names::kFEDistantLightTag) ||
+ svg_element.HasTagName(svg_names::kFEPointLightTag) ||
+ svg_element.HasTagName(svg_names::kFESpotLightTag);
+ }
+};
} // namespace blink
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 c1c49c5ede1..6df184e02c3 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(blink::Visitor* visitor) {
+void SVGFEMergeNodeElement::Trace(Visitor* visitor) {
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 0a6ebe120be..c6491784fb4 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 b833298ff83..5ee79e507d3 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(blink::Visitor* visitor) {
+void SVGFEMorphologyElement::Trace(Visitor* visitor) {
visitor->Trace(radius_);
visitor->Trace(in1_);
visitor->Trace(svg_operator_);
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 198840c3450..80ab5105480 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 17df70ad967..b08be255166 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(blink::Visitor* visitor) {
+void SVGFEOffsetElement::Trace(Visitor* visitor) {
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 4fd07aaa4b4..908adbda57e 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 d334feb951c..e857938b3fb 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(blink::Visitor* visitor) {
+void SVGFESpecularLightingElement::Trace(Visitor* visitor) {
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 e653aca0f5e..64d75d05b10 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 bb89fb4853b..220b8e03787 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(blink::Visitor* visitor) {
+void SVGFETileElement::Trace(Visitor* visitor) {
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 c2583c33367..b22f758db17 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 704eb3a68f2..1136c829f3f 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(blink::Visitor* visitor) {
+void SVGFETurbulenceElement::Trace(Visitor* visitor) {
visitor->Trace(base_frequency_);
visitor->Trace(seed_);
visitor->Trace(stitch_tiles_);
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 d3a6e6094eb..39c953c95cd 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 bf723f0fb77..510b134064c 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(blink::Visitor* visitor) {
+void SVGFilterElement::Trace(Visitor* visitor) {
visitor->Trace(x_);
visitor->Trace(y_);
visitor->Trace(width_);
@@ -113,18 +113,12 @@ LocalSVGResource* SVGFilterElement::AssociatedResource() const {
void SVGFilterElement::PrimitiveAttributeChanged(
SVGFilterPrimitiveStandardAttributes& primitive,
const QualifiedName& attribute) {
- if (LayoutObject* layout_object = GetLayoutObject()) {
- ToLayoutSVGResourceFilter(layout_object)
- ->PrimitiveAttributeChanged(primitive, attribute);
- } else if (LocalSVGResource* resource = AssociatedResource()) {
- resource->NotifyContentChanged(SVGResourceClient::kPaintInvalidation);
- }
+ if (LocalSVGResource* resource = AssociatedResource())
+ resource->NotifyFilterPrimitiveChanged(primitive, attribute);
}
void SVGFilterElement::InvalidateFilterChain() {
- if (LayoutObject* layout_object = GetLayoutObject()) {
- ToLayoutSVGResourceFilter(layout_object)->RemoveAllClientsFromCache();
- } else if (LocalSVGResource* resource = AssociatedResource()) {
+ if (LocalSVGResource* resource = AssociatedResource()) {
resource->NotifyContentChanged(SVGResourceClient::kLayoutInvalidation |
SVGResourceClient::kBoundariesInvalidation);
}
@@ -133,7 +127,7 @@ void SVGFilterElement::InvalidateFilterChain() {
void SVGFilterElement::ChildrenChanged(const ChildrenChange& change) {
SVGElement::ChildrenChanged(change);
- if (change.by_parser)
+ if (change.ByParser())
return;
if (LayoutObject* object = GetLayoutObject()) {
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 02c1c251f3d..39d2c615efb 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 a45e80ac4ca..5654af88baf 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
@@ -21,7 +21,7 @@
#include "third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.h"
-#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter_primitive.h"
+#include "third_party/blink/renderer/core/layout/svg/layout_svg_filter_primitive.h"
#include "third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.h"
#include "third_party/blink/renderer/core/svg/svg_filter_element.h"
#include "third_party/blink/renderer/core/svg/svg_length.h"
@@ -69,7 +69,7 @@ SVGFilterPrimitiveStandardAttributes::SVGFilterPrimitiveStandardAttributes(
AddToPropertyMap(result_);
}
-void SVGFilterPrimitiveStandardAttributes::Trace(blink::Visitor* visitor) {
+void SVGFilterPrimitiveStandardAttributes::Trace(Visitor* visitor) {
visitor->Trace(x_);
visitor->Trace(y_);
visitor->Trace(width_);
@@ -111,7 +111,7 @@ void SVGFilterPrimitiveStandardAttributes::ChildrenChanged(
const ChildrenChange& change) {
SVGElement::ChildrenChanged(change);
- if (!change.by_parser)
+ if (!change.ByParser())
Invalidate();
}
@@ -167,7 +167,7 @@ void SVGFilterPrimitiveStandardAttributes::SetStandardAttributes(
LayoutObject* SVGFilterPrimitiveStandardAttributes::CreateLayoutObject(
const ComputedStyle&,
LegacyLayout) {
- return new LayoutSVGResourceFilterPrimitive(this);
+ return new LayoutSVGFilterPrimitive(this);
}
bool SVGFilterPrimitiveStandardAttributes::LayoutObjectIsNeeded(
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 b0271c5fe3b..50aba21ab89 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void PrimitiveAttributeChanged(const QualifiedName&);
void Invalidate();
@@ -81,15 +81,11 @@ class SVGFilterPrimitiveStandardAttributes : public SVGElement {
void InvalidateFilterPrimitiveParent(SVGElement&);
-inline bool IsSVGFilterPrimitiveStandardAttributes(const SVGElement& element) {
- return element.IsFilterEffect();
-}
-
template <>
struct DowncastTraits<SVGFilterPrimitiveStandardAttributes> {
static bool AllowFrom(const Node& node) {
auto* element = DynamicTo<SVGElement>(node);
- return element && IsSVGFilterPrimitiveStandardAttributes(*element);
+ return element && element->IsFilterEffect();
}
};
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 5c76ecdbf11..2284b380fae 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(blink::Visitor* visitor) {
+void SVGFitToViewBox::Trace(Visitor* visitor) {
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 58d6af310fa..54d922bee5a 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 676129d2787..e570ca8bc8e 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(blink::Visitor* visitor) {
+void SVGForeignObjectElement::Trace(Visitor* visitor) {
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 94edd3e2e9b..b9559036a59 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void CollectStyleForPresentationAttribute(
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_foreign_object_element_test.cc b/chromium/third_party/blink/renderer/core/svg/svg_foreign_object_element_test.cc
index 42d0805ac57..d3b93064f85 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_foreign_object_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_foreign_object_element_test.cc
@@ -14,7 +14,7 @@ namespace blink {
class SVGForeignObjectElementTest : public PageTestBase {};
TEST_F(SVGForeignObjectElementTest, NoLayoutObjectInNonRendered) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<svg>
<pattern>
<foreignObject id="fo"></foreignObject>
@@ -34,7 +34,7 @@ TEST_F(SVGForeignObjectElementTest, NoLayoutObjectInNonRendered) {
}
TEST_F(SVGForeignObjectElementTest, ReferenceForeignObjectInNonRenderedCrash) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style>
div { writing-mode: vertical-rl; }
div > svg { float: right; }
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 3323dceb48d..78f2dbdb9d6 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,13 +75,14 @@ void SVGGeometryElement::SvgAttributeChanged(const QualifiedName& attr_name) {
SVGGraphicsElement::SvgAttributeChanged(attr_name);
}
-void SVGGeometryElement::Trace(blink::Visitor* visitor) {
+void SVGGeometryElement::Trace(Visitor* visitor) {
visitor->Trace(path_length_);
SVGGraphicsElement::Trace(visitor);
}
bool SVGGeometryElement::isPointInFill(SVGPointTearOff* point) const {
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
// FIXME: Eventually we should support isPointInFill for display:none
// elements.
@@ -95,7 +96,8 @@ bool SVGGeometryElement::isPointInFill(SVGPointTearOff* point) const {
}
bool SVGGeometryElement::isPointInStroke(SVGPointTearOff* point) const {
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
// FIXME: Eventually we should support isPointInStroke for display:none
// elements.
@@ -132,7 +134,8 @@ Path SVGGeometryElement::ToClipPath() const {
}
float SVGGeometryElement::getTotalLength(ExceptionState& exception_state) {
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
if (!GetLayoutObject()) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
@@ -144,7 +147,8 @@ float SVGGeometryElement::getTotalLength(ExceptionState& exception_state) {
}
SVGPointTearOff* SVGGeometryElement::getPointAtLength(float length) {
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
FloatPoint point;
if (GetLayoutObject()) {
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 6688c04c816..c6de7fb18db 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
SVGGeometryElement(const QualifiedName&,
@@ -79,11 +79,20 @@ class SVGGeometryElement : public SVGGraphicsElement {
Member<SVGAnimatedNumber> path_length_;
};
-inline bool IsSVGGeometryElement(const SVGElement& element) {
- return element.IsSVGGeometryElement();
+template <>
+inline bool IsElementOfType<const SVGGeometryElement>(const Node& node) {
+ return IsA<SVGGeometryElement>(node);
}
-
-DEFINE_SVGELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGGeometryElement);
+template <>
+struct DowncastTraits<SVGGeometryElement> {
+ static bool AllowFrom(const Node& node) {
+ auto* svg_element = DynamicTo<SVGElement>(node);
+ return svg_element && AllowFrom(*svg_element);
+ }
+ static bool AllowFrom(const SVGElement& svg_element) {
+ return svg_element.IsSVGGeometryElement();
+ }
+};
} // namespace blink
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 c05a4394725..749dcbdcbcc 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(blink::Visitor* visitor) {
+void SVGGradientElement::Trace(Visitor* visitor) {
visitor->Trace(gradient_transform_);
visitor->Trace(spread_method_);
visitor->Trace(gradient_units_);
@@ -146,10 +146,8 @@ void SVGGradientElement::RemovedFrom(ContainerNode& root_parent) {
void SVGGradientElement::ChildrenChanged(const ChildrenChange& change) {
SVGElement::ChildrenChanged(change);
- if (change.by_parser)
- return;
-
- InvalidateGradient(layout_invalidation_reason::kChildChanged);
+ if (!change.ByParser())
+ InvalidateGradient(layout_invalidation_reason::kChildChanged);
}
void SVGGradientElement::InvalidateGradient(
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 bd9f7a365b8..4e8cf91995a 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 67275151c23..37d3f45a698 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(blink::Visitor* visitor) {
+void SVGGraphicsElement::Trace(Visitor* visitor) {
visitor->Trace(transform_);
SVGElement::Trace(visitor);
SVGTests::Trace(visitor);
@@ -90,14 +90,16 @@ AffineTransform SVGGraphicsElement::ComputeCTM(
}
SVGMatrixTearOff* SVGGraphicsElement::getCTM() {
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
return MakeGarbageCollected<SVGMatrixTearOff>(
ComputeCTM(kNearestViewportScope));
}
SVGMatrixTearOff* SVGGraphicsElement::getScreenCTM() {
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
return MakeGarbageCollected<SVGMatrixTearOff>(ComputeCTM(kScreenScope));
}
@@ -171,7 +173,7 @@ FloatRect SVGGraphicsElement::GetBBox() {
}
SVGRectTearOff* SVGGraphicsElement::getBBoxFromJavascript() {
- GetDocument().UpdateStyleAndLayout();
+ GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript);
// FIXME: Eventually we should support getBBox for detached elements.
FloatRect boundingBox;
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 2b602085711..5fbcc82e5e2 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
SVGGraphicsElement(const QualifiedName&,
@@ -87,20 +87,21 @@ class CORE_EXPORT SVGGraphicsElement : public SVGElement, public SVGTests {
bool IsSVGGraphicsElement() const final { return true; }
};
-inline bool IsSVGGraphicsElement(const SVGElement& element) {
- return element.IsSVGGraphicsElement();
+template <>
+inline bool IsElementOfType<const SVGGraphicsElement>(const Node& node) {
+ return IsA<SVGGraphicsElement>(node);
}
-
template <>
struct DowncastTraits<SVGGraphicsElement> {
static bool AllowFrom(const Node& node) {
auto* svg_element = DynamicTo<SVGElement>(node);
- return svg_element && IsSVGGraphicsElement(*svg_element);
+ return svg_element && AllowFrom(*svg_element);
+ }
+ static bool AllowFrom(const SVGElement& svg_element) {
+ return svg_element.IsSVGGraphicsElement();
}
};
-DEFINE_SVGELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGGraphicsElement);
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_GRAPHICS_ELEMENT_H_
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 2cf3d0214b3..4ab1768f3a5 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
@@ -25,9 +25,7 @@
#include "third_party/blink/renderer/core/css/css_property_names.h"
#include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
-#include "third_party/blink/renderer/core/html/media/media_element_parser_helpers.h"
#include "third_party/blink/renderer/core/layout/layout_image_resource.h"
-#include "third_party/blink/renderer/core/layout/layout_replaced.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_image.h"
#include "third_party/blink/renderer/core/svg_names.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
@@ -38,7 +36,8 @@ namespace blink {
SVGImageElement::SVGImageElement(Document& document)
: SVGGraphicsElement(svg_names::kImageTag, document),
SVGURIReference(this),
- is_default_overridden_intrinsic_size_(false),
+ is_default_overridden_intrinsic_size_(!document.IsFeatureEnabled(
+ mojom::blink::DocumentPolicyFeature::kUnsizedMedia)),
x_(MakeGarbageCollected<SVGAnimatedLength>(
this,
svg_names::kXAttr,
@@ -73,16 +72,9 @@ SVGImageElement::SVGImageElement(Document& document)
AddToPropertyMap(width_);
AddToPropertyMap(height_);
AddToPropertyMap(preserve_aspect_ratio_);
-
- if (media_element_parser_helpers::IsMediaElement(this) &&
- !document.IsFeatureEnabled(mojom::FeaturePolicyFeature::kUnsizedMedia)) {
- is_default_overridden_intrinsic_size_ = true;
- overridden_intrinsic_size_ =
- IntSize(LayoutReplaced::kDefaultWidth, LayoutReplaced::kDefaultHeight);
- }
}
-void SVGImageElement::Trace(blink::Visitor* visitor) {
+void SVGImageElement::Trace(Visitor* visitor) {
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 7c7c3ee084d..049e9c7ab63 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
bool CurrentFrameHasSingleSecurityOrigin() const;
@@ -55,10 +55,6 @@ class CORE_EXPORT SVGImageElement final
return preserve_aspect_ratio_.Get();
}
- IntSize GetOverriddenIntrinsicSize() const {
- return overridden_intrinsic_size_;
- }
-
bool HasPendingActivity() const final {
return GetImageLoader().HasPendingActivity();
}
@@ -104,7 +100,6 @@ class CORE_EXPORT SVGImageElement final
void DidMoveToNewDocument(Document& old_document) override;
SVGImageLoader& GetImageLoader() const override { return *image_loader_; }
- IntSize overridden_intrinsic_size_;
bool is_default_overridden_intrinsic_size_;
Member<SVGAnimatedLength> x_;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_integer.cc b/chromium/third_party/blink/renderer/core/svg/svg_integer.cc
index 68592578b51..d39b494b67c 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_integer.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_integer.cc
@@ -59,7 +59,7 @@ SVGParsingError SVGInteger::SetValueAsString(const String& string) {
}
void SVGInteger::Add(SVGPropertyBase* other, SVGElement*) {
- SetValue(value_ + ToSVGInteger(other)->Value());
+ SetValue(value_ + To<SVGInteger>(other)->Value());
}
void SVGInteger::CalculateAnimatedValue(
@@ -70,10 +70,9 @@ void SVGInteger::CalculateAnimatedValue(
SVGPropertyBase* to,
SVGPropertyBase* to_at_end_of_duration,
SVGElement*) {
- SVGInteger* from_integer = ToSVGInteger(from);
- SVGInteger* to_integer = ToSVGInteger(to);
- SVGInteger* to_at_end_of_duration_integer =
- ToSVGInteger(to_at_end_of_duration);
+ auto* from_integer = To<SVGInteger>(from);
+ auto* to_integer = To<SVGInteger>(to);
+ auto* to_at_end_of_duration_integer = To<SVGInteger>(to_at_end_of_duration);
float animated_float = value_;
animation_element.AnimateAdditiveNumber(
@@ -83,7 +82,7 @@ void SVGInteger::CalculateAnimatedValue(
}
float SVGInteger::CalculateDistance(SVGPropertyBase* other, SVGElement*) {
- return abs(value_ - ToSVGInteger(other)->Value());
+ return abs(value_ - To<SVGInteger>(other)->Value());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_integer.h b/chromium/third_party/blink/renderer/core/svg/svg_integer.h
index d1c2ab43402..90924b8d760 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_integer.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_integer.h
@@ -33,6 +33,7 @@
#include "third_party/blink/renderer/core/svg/properties/svg_property_helper.h"
#include "third_party/blink/renderer/core/svg/svg_parsing_error.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -71,7 +72,12 @@ class SVGInteger final : public SVGPropertyHelper<SVGInteger> {
int value_;
};
-DEFINE_SVG_PROPERTY_TYPE_CASTS(SVGInteger);
+template <>
+struct DowncastTraits<SVGInteger> {
+ static bool AllowFrom(const SVGPropertyBase& value) {
+ return value.GetType() == SVGInteger::ClassType();
+ }
+};
} // namespace blink
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 467bcf2c436..2c9a363c780 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(blink::Visitor* visitor) {
+void SVGIntegerOptionalInteger::Trace(Visitor* visitor) {
visitor->Trace(first_integer_);
visitor->Trace(second_integer_);
SVGPropertyBase::Trace(visitor);
@@ -89,7 +89,7 @@ void SVGIntegerOptionalInteger::SetInitial(unsigned value) {
void SVGIntegerOptionalInteger::Add(SVGPropertyBase* other,
SVGElement* context_element) {
- auto* other_integer_optional_integer = ToSVGIntegerOptionalInteger(other);
+ auto* other_integer_optional_integer = To<SVGIntegerOptionalInteger>(other);
first_integer_->Add(other_integer_optional_integer->FirstInteger(),
context_element);
second_integer_->Add(other_integer_optional_integer->SecondInteger(),
@@ -104,10 +104,10 @@ void SVGIntegerOptionalInteger::CalculateAnimatedValue(
SVGPropertyBase* to,
SVGPropertyBase* to_at_end_of_duration,
SVGElement* context_element) {
- auto* from_integer = ToSVGIntegerOptionalInteger(from);
- auto* to_integer = ToSVGIntegerOptionalInteger(to);
+ auto* from_integer = To<SVGIntegerOptionalInteger>(from);
+ auto* to_integer = To<SVGIntegerOptionalInteger>(to);
auto* to_at_end_of_duration_integer =
- ToSVGIntegerOptionalInteger(to_at_end_of_duration);
+ To<SVGIntegerOptionalInteger>(to_at_end_of_duration);
first_integer_->CalculateAnimatedValue(
animation_element, percentage, repeat_count, from_integer->FirstInteger(),
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 69b587a82b0..334fef29f01 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
@@ -34,6 +34,7 @@
#include "third_party/blink/renderer/core/svg/svg_integer.h"
#include "third_party/blink/renderer/core/svg/svg_parsing_error.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -73,14 +74,19 @@ class SVGIntegerOptionalInteger final : public SVGPropertyBase {
SVGInteger* FirstInteger() const { return first_integer_; }
SVGInteger* SecondInteger() const { return second_integer_; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
Member<SVGInteger> first_integer_;
Member<SVGInteger> second_integer_;
};
-DEFINE_SVG_PROPERTY_TYPE_CASTS(SVGIntegerOptionalInteger);
+template <>
+struct DowncastTraits<SVGIntegerOptionalInteger> {
+ static bool AllowFrom(const SVGPropertyBase& value) {
+ return value.GetType() == SVGIntegerOptionalInteger::ClassType();
+ }
+};
} // namespace blink
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 7533e316fb9..9a0108d1c29 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_length.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_length.cc
@@ -88,7 +88,7 @@ SVGLength::SVGLength(const CSSPrimitiveValue& value, SVGLengthMode mode)
SVGLength::SVGLength(const SVGLength& o)
: value_(o.value_), unit_mode_(o.unit_mode_) {}
-void SVGLength::Trace(blink::Visitor* visitor) {
+void SVGLength::Trace(Visitor* visitor) {
visitor->Trace(value_);
SVGPropertyBase::Trace(visitor);
}
@@ -326,7 +326,7 @@ bool SVGLength::NegativeValuesForbiddenForAnimatedLengthAttribute(
void SVGLength::Add(SVGPropertyBase* other, SVGElement* context_element) {
SVGLengthContext length_context(context_element);
- SetValue(Value(length_context) + ToSVGLength(other)->Value(length_context),
+ SetValue(Value(length_context) + To<SVGLength>(other)->Value(length_context),
length_context);
}
@@ -338,10 +338,10 @@ void SVGLength::CalculateAnimatedValue(
SVGPropertyBase* to_value,
SVGPropertyBase* to_at_end_of_duration_value,
SVGElement* context_element) {
- SVGLength* from_length = ToSVGLength(from_value);
- SVGLength* to_length = ToSVGLength(to_value);
- SVGLength* to_at_end_of_duration_length =
- ToSVGLength(to_at_end_of_duration_value);
+ auto* from_length = To<SVGLength>(from_value);
+ auto* to_length = To<SVGLength>(to_value);
+ auto* to_at_end_of_duration_length =
+ To<SVGLength>(to_at_end_of_duration_value);
SVGLengthContext length_context(context_element);
float animated_number = Value(length_context);
@@ -374,7 +374,7 @@ void SVGLength::CalculateAnimatedValue(
float SVGLength::CalculateDistance(SVGPropertyBase* to_value,
SVGElement* context_element) {
SVGLengthContext length_context(context_element);
- SVGLength* to_length = ToSVGLength(to_value);
+ auto* to_length = To<SVGLength>(to_value);
return fabsf(to_length->Value(length_context) - Value(length_context));
}
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 3c286d3292c..4b883d10f98 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_length.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_length.h
@@ -21,12 +21,14 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_LENGTH_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_LENGTH_H_
+#include "third_party/blink/renderer/core/core_export.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/svg/properties/svg_property.h"
#include "third_party/blink/renderer/core/svg/svg_length_context.h"
#include "third_party/blink/renderer/core/svg/svg_parsing_error.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -34,7 +36,7 @@ class QualifiedName;
class SVGLengthTearOff;
-class SVGLength final : public SVGPropertyBase {
+class CORE_EXPORT SVGLength final : public SVGPropertyBase {
public:
typedef SVGLengthTearOff TearOffType;
@@ -60,7 +62,7 @@ class SVGLength final : public SVGPropertyBase {
void SetInitial(unsigned);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
SVGLength* Clone() const;
SVGPropertyBase* CloneForAnimation(const String&) const override;
@@ -144,7 +146,12 @@ class SVGLength final : public SVGPropertyBase {
unsigned unit_mode_ : 2;
};
-DEFINE_SVG_PROPERTY_TYPE_CASTS(SVGLength);
+template <>
+struct DowncastTraits<SVGLength> {
+ static bool AllowFrom(const SVGPropertyBase& value) {
+ return value.GetType() == SVGLength::ClassType();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_length_context.cc b/chromium/third_party/blink/renderer/core/svg/svg_length_context.cc
index c2ea541dfcb..fb59b03afc3 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_length_context.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_length_context.cc
@@ -450,7 +450,7 @@ bool SVGLengthContext::DetermineViewport(FloatSize& viewport_size) const {
// Root <svg> element lengths are resolved against the top level viewport.
if (context_->IsOutermostSVGSVGElement()) {
- viewport_size = To<SVGSVGElement>(context_.Get())->CurrentViewportSize();
+ viewport_size = To<SVGSVGElement>(context_)->CurrentViewportSize();
return true;
}
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_length_context.h b/chromium/third_party/blink/renderer/core/svg/svg_length_context.h
index ba97426dd50..e98e74dc8ff 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_length_context.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_length_context.h
@@ -20,6 +20,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_LENGTH_CONTEXT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_LENGTH_CONTEXT_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/core/svg/svg_unit_types.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
@@ -34,7 +35,7 @@ class UnzoomedLength;
enum class SVGLengthMode { kWidth, kHeight, kOther };
-class SVGLengthContext {
+class CORE_EXPORT SVGLengthContext {
STACK_ALLOCATED();
public:
@@ -97,7 +98,7 @@ class SVGLengthContext {
float ConvertValueFromUserUnitsToCHS(float value) const;
float ConvertValueFromCHSToUserUnits(float value) const;
- Member<const SVGElement> context_;
+ const SVGElement* context_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_length_list.cc b/chromium/third_party/blink/renderer/core/svg/svg_length_list.cc
index c6d952c5933..795fac45775 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_length_list.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_length_list.cc
@@ -90,7 +90,7 @@ SVGParsingError SVGLengthList::SetValueAsString(const String& value) {
}
void SVGLengthList::Add(SVGPropertyBase* other, SVGElement* context_element) {
- SVGLengthList* other_list = ToSVGLengthList(other);
+ auto* other_list = To<SVGLengthList>(other);
if (length() != other_list->length())
return;
@@ -114,10 +114,10 @@ void SVGLengthList::CalculateAnimatedValue(
SVGPropertyBase* to_value,
SVGPropertyBase* to_at_end_of_duration_value,
SVGElement* context_element) {
- SVGLengthList* from_list = ToSVGLengthList(from_value);
- SVGLengthList* to_list = ToSVGLengthList(to_value);
- SVGLengthList* to_at_end_of_duration_list =
- ToSVGLengthList(to_at_end_of_duration_value);
+ auto* from_list = To<SVGLengthList>(from_value);
+ auto* to_list = To<SVGLengthList>(to_value);
+ auto* to_at_end_of_duration_list =
+ To<SVGLengthList>(to_at_end_of_duration_value);
SVGLengthContext length_context(context_element);
DCHECK_EQ(mode_, SVGLength::LengthModeForAnimatedLengthAttribute(
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_length_list.h b/chromium/third_party/blink/renderer/core/svg/svg_length_list.h
index 680a373748b..dea9d6740ce 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_length_list.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_length_list.h
@@ -34,6 +34,7 @@
#include "third_party/blink/renderer/core/svg/properties/svg_list_property_helper.h"
#include "third_party/blink/renderer/core/svg/svg_length.h"
#include "third_party/blink/renderer/core/svg/svg_parsing_error.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -79,7 +80,12 @@ class SVGLengthList final
SVGLengthMode mode_;
};
-DEFINE_SVG_PROPERTY_TYPE_CASTS(SVGLengthList);
+template <>
+struct DowncastTraits<SVGLengthList> {
+ static bool AllowFrom(const SVGPropertyBase& value) {
+ return value.GetType() == SVGLengthList::ClassType();
+ }
+};
} // namespace blink
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 7d3911a280b..988db51b0dc 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(blink::Visitor* visitor) {
+void SVGLineElement::Trace(Visitor* visitor) {
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 ce6fcf16a6f..04acb82a98f 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 df26f2e700c..9c0c7072b12 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(blink::Visitor* visitor) {
+void SVGLinearGradientElement::Trace(Visitor* visitor) {
visitor->Trace(x1_);
visitor->Trace(y1_);
visitor->Trace(x2_);
@@ -91,7 +91,6 @@ LayoutObject* SVGLinearGradientElement::CreateLayoutObject(const ComputedStyle&,
static void SetGradientAttributes(const SVGGradientElement& element,
LinearGradientAttributes& attributes,
bool is_linear) {
- element.SynchronizeAnimatedSVGAttribute(AnyQName());
element.CollectCommonAttributes(attributes);
if (!is_linear)
@@ -111,8 +110,8 @@ static void SetGradientAttributes(const SVGGradientElement& element,
attributes.SetY2(linear.y2()->CurrentValue());
}
-bool SVGLinearGradientElement::CollectGradientAttributes(
- LinearGradientAttributes& attributes) {
+void SVGLinearGradientElement::CollectGradientAttributes(
+ LinearGradientAttributes& attributes) const {
DCHECK(GetLayoutObject());
VisitedSet visited;
@@ -124,12 +123,14 @@ bool SVGLinearGradientElement::CollectGradientAttributes(
visited.insert(current);
current = current->ReferencedElement();
- if (!current || visited.Contains(current))
+
+ // Ignore the referenced gradient element if it is not attached.
+ if (!current || !current->GetLayoutObject())
+ break;
+ // Cycle detection.
+ if (visited.Contains(current))
break;
- if (!current->GetLayoutObject())
- return false;
}
- return true;
}
bool SVGLinearGradientElement::SelfHasRelativeLengths() const {
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 9ba60cc3cec..1b1b218d836 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
@@ -35,14 +35,14 @@ class SVGLinearGradientElement final : public SVGGradientElement {
public:
explicit SVGLinearGradientElement(Document&);
- bool CollectGradientAttributes(LinearGradientAttributes&);
+ void CollectGradientAttributes(LinearGradientAttributes&) const;
SVGAnimatedLength* x1() const { return x1_.Get(); }
SVGAnimatedLength* y1() const { return y1_.Get(); }
SVGAnimatedLength* x2() const { return x2_.Get(); }
SVGAnimatedLength* y2() const { return y2_.Get(); }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 287c2586c99..4920b8ba495 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(blink::Visitor* visitor) {
+void SVGMarkerElement::Trace(Visitor* visitor) {
visitor->Trace(ref_x_);
visitor->Trace(ref_y_);
visitor->Trace(marker_width_);
@@ -129,7 +129,7 @@ void SVGMarkerElement::SvgAttributeChanged(const QualifiedName& attr_name) {
void SVGMarkerElement::ChildrenChanged(const ChildrenChange& change) {
SVGElement::ChildrenChanged(change);
- if (change.by_parser)
+ if (change.ByParser())
return;
if (LayoutObject* object = GetLayoutObject()) {
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 316b517b61e..542d5ba1bd5 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 e194b0fe21f..db873b16b0e 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(blink::Visitor* visitor) {
+void SVGMaskElement::Trace(Visitor* visitor) {
visitor->Trace(x_);
visitor->Trace(y_);
visitor->Trace(width_);
@@ -143,7 +143,7 @@ void SVGMaskElement::SvgAttributeChanged(const QualifiedName& attr_name) {
void SVGMaskElement::ChildrenChanged(const ChildrenChange& change) {
SVGElement::ChildrenChanged(change);
- if (change.by_parser)
+ if (change.ByParser())
return;
if (LayoutObject* object = GetLayoutObject()) {
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 ebb6a52b3fc..d45cdf20e87 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 07357ec83a8..e7db4ffa088 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(blink::Visitor* visitor) {
+void SVGMatrixTearOff::Trace(Visitor* visitor) {
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 e36d716323c..3b8bf2fa439 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 1f7f3c502d8..65eb8f47ce1 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(blink::Visitor* visitor) {
+void SVGMPathElement::Trace(Visitor* visitor) {
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 ee6fa88384b..89ed7cca9c5 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void BuildPendingResource() override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_number.cc b/chromium/third_party/blink/renderer/core/svg/svg_number.cc
index 438ea1cb5e3..10e6f1a80a4 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_number.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_number.cc
@@ -75,7 +75,7 @@ SVGParsingError SVGNumber::SetValueAsString(const String& string) {
}
void SVGNumber::Add(SVGPropertyBase* other, SVGElement*) {
- SetValue(value_ + ToSVGNumber(other)->Value());
+ SetValue(value_ + To<SVGNumber>(other)->Value());
}
void SVGNumber::CalculateAnimatedValue(
@@ -86,9 +86,9 @@ void SVGNumber::CalculateAnimatedValue(
SVGPropertyBase* to,
SVGPropertyBase* to_at_end_of_duration,
SVGElement*) {
- SVGNumber* from_number = ToSVGNumber(from);
- SVGNumber* to_number = ToSVGNumber(to);
- SVGNumber* to_at_end_of_duration_number = ToSVGNumber(to_at_end_of_duration);
+ auto* from_number = To<SVGNumber>(from);
+ auto* to_number = To<SVGNumber>(to);
+ auto* to_at_end_of_duration_number = To<SVGNumber>(to_at_end_of_duration);
animation_element.AnimateAdditiveNumber(
percentage, repeat_count, from_number->Value(), to_number->Value(),
@@ -96,7 +96,7 @@ void SVGNumber::CalculateAnimatedValue(
}
float SVGNumber::CalculateDistance(SVGPropertyBase* other, SVGElement*) {
- return fabsf(value_ - ToSVGNumber(other)->Value());
+ return fabsf(value_ - To<SVGNumber>(other)->Value());
}
SVGNumber* SVGNumberAcceptPercentage::Clone() const {
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_number.h b/chromium/third_party/blink/renderer/core/svg/svg_number.h
index ec583810351..d081ee5c42f 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_number.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_number.h
@@ -33,6 +33,7 @@
#include "third_party/blink/renderer/core/svg/properties/svg_property_helper.h"
#include "third_party/blink/renderer/core/svg/svg_parsing_error.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -77,7 +78,12 @@ class SVGNumber : public SVGPropertyHelper<SVGNumber> {
float value_;
};
-DEFINE_SVG_PROPERTY_TYPE_CASTS(SVGNumber);
+template <>
+struct DowncastTraits<SVGNumber> {
+ static bool AllowFrom(const SVGPropertyBase& value) {
+ return value.GetType() == SVGNumber::ClassType();
+ }
+};
// SVGNumber which also accepts percentage as its value.
// This is used for <stop> "offset"
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_number_list.cc b/chromium/third_party/blink/renderer/core/svg/svg_number_list.cc
index e2002e79e5d..615df5ca93c 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_number_list.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_number_list.cc
@@ -69,7 +69,7 @@ SVGParsingError SVGNumberList::SetValueAsString(const String& value) {
}
void SVGNumberList::Add(SVGPropertyBase* other, SVGElement* context_element) {
- SVGNumberList* other_list = ToSVGNumberList(other);
+ auto* other_list = To<SVGNumberList>(other);
if (length() != other_list->length())
return;
@@ -86,10 +86,10 @@ void SVGNumberList::CalculateAnimatedValue(
SVGPropertyBase* to_value,
SVGPropertyBase* to_at_end_of_duration_value,
SVGElement* context_element) {
- SVGNumberList* from_list = ToSVGNumberList(from_value);
- SVGNumberList* to_list = ToSVGNumberList(to_value);
- SVGNumberList* to_at_end_of_duration_list =
- ToSVGNumberList(to_at_end_of_duration_value);
+ auto* from_list = To<SVGNumberList>(from_value);
+ auto* to_list = To<SVGNumberList>(to_value);
+ auto* to_at_end_of_duration_list =
+ To<SVGNumberList>(to_at_end_of_duration_value);
uint32_t from_list_size = from_list->length();
uint32_t to_list_size = to_list->length();
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_number_list.h b/chromium/third_party/blink/renderer/core/svg/svg_number_list.h
index 89eb0affe06..860f379edbe 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_number_list.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_number_list.h
@@ -34,6 +34,7 @@
#include "third_party/blink/renderer/core/svg/properties/svg_list_property_helper.h"
#include "third_party/blink/renderer/core/svg/svg_number.h"
#include "third_party/blink/renderer/core/svg/svg_parsing_error.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -72,7 +73,12 @@ class SVGNumberList final
SVGParsingError Parse(const CharType*& ptr, const CharType* end);
};
-DEFINE_SVG_PROPERTY_TYPE_CASTS(SVGNumberList);
+template <>
+struct DowncastTraits<SVGNumberList> {
+ static bool AllowFrom(const SVGPropertyBase& value) {
+ return value.GetType() == SVGNumberList::ClassType();
+ }
+};
} // namespace blink
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 cd154d4c343..a1477bae1c3 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(blink::Visitor* visitor) {
+void SVGNumberOptionalNumber::Trace(Visitor* visitor) {
visitor->Trace(first_number_);
visitor->Trace(second_number_);
SVGPropertyBase::Trace(visitor);
@@ -91,7 +91,7 @@ void SVGNumberOptionalNumber::SetInitial(unsigned value) {
void SVGNumberOptionalNumber::Add(SVGPropertyBase* other,
SVGElement* context_element) {
- auto* other_number_optional_number = ToSVGNumberOptionalNumber(other);
+ auto* other_number_optional_number = To<SVGNumberOptionalNumber>(other);
first_number_->Add(other_number_optional_number->FirstNumber(),
context_element);
second_number_->Add(other_number_optional_number->SecondNumber(),
@@ -106,10 +106,10 @@ void SVGNumberOptionalNumber::CalculateAnimatedValue(
SVGPropertyBase* to,
SVGPropertyBase* to_at_end_of_duration,
SVGElement* context_element) {
- auto* from_number = ToSVGNumberOptionalNumber(from);
- auto* to_number = ToSVGNumberOptionalNumber(to);
+ auto* from_number = To<SVGNumberOptionalNumber>(from);
+ auto* to_number = To<SVGNumberOptionalNumber>(to);
auto* to_at_end_of_duration_number =
- ToSVGNumberOptionalNumber(to_at_end_of_duration);
+ To<SVGNumberOptionalNumber>(to_at_end_of_duration);
first_number_->CalculateAnimatedValue(
animation_element, percentage, repeat_count, from_number->FirstNumber(),
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 06f48ff8d7a..6f5f810cca4 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
@@ -34,6 +34,7 @@
#include "third_party/blink/renderer/core/svg/svg_number.h"
#include "third_party/blink/renderer/core/svg/svg_parsing_error.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -72,14 +73,19 @@ class SVGNumberOptionalNumber final : public SVGPropertyBase {
SVGNumber* FirstNumber() const { return first_number_; }
SVGNumber* SecondNumber() const { return second_number_; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
Member<SVGNumber> first_number_;
Member<SVGNumber> second_number_;
};
-DEFINE_SVG_PROPERTY_TYPE_CASTS(SVGNumberOptionalNumber);
+template <>
+struct DowncastTraits<SVGNumberOptionalNumber> {
+ static bool AllowFrom(const SVGPropertyBase& value) {
+ return value.GetType() == SVGNumberOptionalNumber::ClassType();
+ }
+};
} // namespace blink
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 d13e8ec8c8b..393b6f1d592 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_path.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_path.cc
@@ -114,8 +114,7 @@ SVGPropertyBase* SVGPath::CloneForAnimation(const String& value) const {
}
void SVGPath::Add(SVGPropertyBase* other, SVGElement*) {
- const SVGPathByteStream& other_path_byte_stream =
- ToSVGPath(other)->ByteStream();
+ const auto& other_path_byte_stream = To<SVGPath>(other)->ByteStream();
if (ByteStream().size() != other_path_byte_stream.size() ||
ByteStream().IsEmpty() || other_path_byte_stream.IsEmpty())
return;
@@ -134,14 +133,14 @@ void SVGPath::CalculateAnimatedValue(
SVGElement*) {
bool is_to_animation = animation_element.GetAnimationMode() == kToAnimation;
- const SVGPath& to = ToSVGPath(*to_value);
+ const auto& to = To<SVGPath>(*to_value);
const SVGPathByteStream& to_stream = to.ByteStream();
// If no 'to' value is given, nothing to animate.
if (!to_stream.size())
return;
- const SVGPath& from = ToSVGPath(*from_value);
+ const auto& from = To<SVGPath>(*from_value);
const SVGPathByteStream* from_stream = &from.ByteStream();
std::unique_ptr<SVGPathByteStream> copy;
@@ -178,7 +177,7 @@ void SVGPath::CalculateAnimatedValue(
if (repeat_count && animation_element.IsAccumulated()) {
new_stream = ConditionallyAddPathByteStreams(
std::move(new_stream),
- ToSVGPath(to_at_end_of_duration_value)->ByteStream(), repeat_count);
+ To<SVGPath>(to_at_end_of_duration_value)->ByteStream(), repeat_count);
}
}
path_value_ = MakeGarbageCollected<CSSPathValue>(std::move(new_stream));
@@ -189,7 +188,7 @@ float SVGPath::CalculateDistance(SVGPropertyBase* to, SVGElement*) {
return -1;
}
-void SVGPath::Trace(blink::Visitor* visitor) {
+void SVGPath::Trace(Visitor* visitor) {
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 c8351b23db5..b6376e5d1e3 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_path.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_path.h
@@ -35,6 +35,7 @@
#include "third_party/blink/renderer/core/svg/properties/svg_property.h"
#include "third_party/blink/renderer/core/svg/svg_parsing_error.h"
#include "third_party/blink/renderer/core/svg/svg_path_byte_stream.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -71,13 +72,18 @@ class SVGPath final : public SVGPropertyBase {
static AnimatedPropertyType ClassType() { return kAnimatedPath; }
AnimatedPropertyType GetType() const override { return ClassType(); }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<cssvalue::CSSPathValue> path_value_;
};
-DEFINE_SVG_PROPERTY_TYPE_CASTS(SVGPath);
+template <>
+struct DowncastTraits<SVGPath> {
+ static bool AllowFrom(const SVGPropertyBase& value) {
+ return value.GetType() == SVGPath::ClassType();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_path_data.h b/chromium/third_party/blink/renderer/core/svg/svg_path_data.h
index c58d9fd1610..0167d0824bf 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_path_data.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_path_data.h
@@ -62,7 +62,7 @@ static inline bool IsAbsolutePathSegType(const SVGPathSegType type) {
}
struct PathSegmentData {
- STACK_ALLOCATED();
+ DISALLOW_NEW();
public:
PathSegmentData()
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 04f61a23f1c..c57638d1bb9 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(blink::Visitor* visitor) {
+void SVGPathElement::Trace(Visitor* visitor) {
visitor->Trace(path_);
SVGGeometryElement::Trace(visitor);
}
@@ -65,12 +65,14 @@ Path SVGPathElement::AsPath() const {
}
float SVGPathElement::getTotalLength(ExceptionState& exception_state) {
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
return SVGPathQuery(PathByteStream()).GetTotalLength();
}
SVGPointTearOff* SVGPathElement::getPointAtLength(float length) {
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
SVGPathQuery path_query(PathByteStream());
if (length < 0) {
length = 0;
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 925d99b32b8..2b1540003fd 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
const StylePath* GetStylePath() const;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_path_parser.h b/chromium/third_party/blink/renderer/core/svg/svg_path_parser.h
index 32191f188d1..a0a65565e85 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_path_parser.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_path_parser.h
@@ -60,7 +60,7 @@ class SVGPathNormalizer {
void EmitSegment(const PathSegmentData&);
- private:
+ protected:
bool DecomposeArcToCubic(const FloatPoint& current_point,
const PathSegmentData&);
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 9a481809915..cf4523d4a8d 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
@@ -25,6 +25,7 @@
#include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.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/svg/pattern_attributes.h"
#include "third_party/blink/renderer/core/svg/svg_resource.h"
@@ -82,7 +83,7 @@ SVGPatternElement::SVGPatternElement(Document& document)
AddToPropertyMap(pattern_content_units_);
}
-void SVGPatternElement::Trace(blink::Visitor* visitor) {
+void SVGPatternElement::Trace(Visitor* visitor) {
visitor->Trace(x_);
visitor->Trace(y_);
visitor->Trace(width_);
@@ -185,10 +186,8 @@ void SVGPatternElement::RemovedFrom(ContainerNode& root_parent) {
void SVGPatternElement::ChildrenChanged(const ChildrenChange& change) {
SVGElement::ChildrenChanged(change);
- if (change.by_parser)
- return;
-
- InvalidatePattern(layout_invalidation_reason::kChildChanged);
+ if (!change.ByParser())
+ InvalidatePattern(layout_invalidation_reason::kChildChanged);
}
void SVGPatternElement::InvalidatePattern(
@@ -204,8 +203,6 @@ LayoutObject* SVGPatternElement::CreateLayoutObject(const ComputedStyle&,
static void SetPatternAttributes(const SVGPatternElement& element,
PatternAttributes& attributes) {
- element.SynchronizeAnimatedSVGAttribute(AnyQName());
-
if (!attributes.HasX() && element.x()->IsSpecified())
attributes.SetX(element.x()->CurrentValue());
@@ -267,10 +264,10 @@ void SVGPatternElement::CollectPatternAttributes(
// from that element to override values this pattern didn't set.
current = current->ReferencedElement();
- // Only consider attached SVG pattern elements.
+ // Ignore the referenced pattern element if it is not attached.
if (!current || !current->GetLayoutObject())
break;
- // Cycle detection
+ // Cycle detection.
if (processed_patterns.Contains(current))
break;
}
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 45b7af10525..8df0c30ad06 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
bool IsValid() const override { return SVGTests::IsValid(); }
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_point.h b/chromium/third_party/blink/renderer/core/svg/svg_point.h
index d7614c0f8a2..9f7d8d9c660 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_point.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_point.h
@@ -82,8 +82,6 @@ class SVGPoint final : public SVGPropertyHelper<SVGPoint> {
FloatPoint value_;
};
-DEFINE_SVG_PROPERTY_TYPE_CASTS(SVGPoint);
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_POINT_H_
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_point_list.cc b/chromium/third_party/blink/renderer/core/svg/svg_point_list.cc
index 842eb8fbf83..04ef9ffb647 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_point_list.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_point_list.cc
@@ -83,7 +83,7 @@ SVGParsingError SVGPointList::SetValueAsString(const String& value) {
}
void SVGPointList::Add(SVGPropertyBase* other, SVGElement* context_element) {
- SVGPointList* other_list = ToSVGPointList(other);
+ auto* other_list = To<SVGPointList>(other);
if (length() != other_list->length())
return;
@@ -100,10 +100,10 @@ void SVGPointList::CalculateAnimatedValue(
SVGPropertyBase* to_value,
SVGPropertyBase* to_at_end_of_duration_value,
SVGElement* context_element) {
- SVGPointList* from_list = ToSVGPointList(from_value);
- SVGPointList* to_list = ToSVGPointList(to_value);
- SVGPointList* to_at_end_of_duration_list =
- ToSVGPointList(to_at_end_of_duration_value);
+ auto* from_list = To<SVGPointList>(from_value);
+ auto* to_list = To<SVGPointList>(to_value);
+ auto* to_at_end_of_duration_list =
+ To<SVGPointList>(to_at_end_of_duration_value);
uint32_t from_point_list_size = from_list->length();
uint32_t to_point_list_size = to_list->length();
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_point_list.h b/chromium/third_party/blink/renderer/core/svg/svg_point_list.h
index 4a4ff6171a1..ce06e5e5ac0 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_point_list.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_point_list.h
@@ -34,6 +34,7 @@
#include "third_party/blink/renderer/core/svg/properties/svg_list_property_helper.h"
#include "third_party/blink/renderer/core/svg/svg_parsing_error.h"
#include "third_party/blink/renderer/core/svg/svg_point.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -70,7 +71,12 @@ class SVGPointList final
SVGParsingError Parse(const CharType*& ptr, const CharType* end);
};
-DEFINE_SVG_PROPERTY_TYPE_CASTS(SVGPointList);
+template <>
+struct DowncastTraits<SVGPointList> {
+ static bool AllowFrom(const SVGPropertyBase& value) {
+ return value.GetType() == SVGPointList::ClassType();
+ }
+};
} // namespace blink
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 6996f199b44..741dda2047e 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(blink::Visitor* visitor) {
+void SVGPolyElement::Trace(Visitor* visitor) {
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 87a146ced44..dd9c67e8a31 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
SVGPolyElement(const QualifiedName&, Document&);
@@ -49,12 +49,21 @@ class SVGPolyElement : public SVGGeometryElement {
Member<SVGAnimatedPointList> points_;
};
-inline bool IsSVGPolyElement(const SVGElement& element) {
- return element.HasTagName(svg_names::kPolygonTag) ||
- element.HasTagName(svg_names::kPolylineTag);
+template <>
+inline bool IsElementOfType<const SVGPolyElement>(const Node& node) {
+ return IsA<SVGPolyElement>(node);
}
-
-DEFINE_SVGELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGPolyElement);
+template <>
+struct DowncastTraits<SVGPolyElement> {
+ static bool AllowFrom(const Node& node) {
+ auto* svg_element = DynamicTo<SVGElement>(node);
+ return svg_element && AllowFrom(*svg_element);
+ }
+ static bool AllowFrom(const SVGElement& svg_element) {
+ return svg_element.HasTagName(svg_names::kPolygonTag) ||
+ svg_element.HasTagName(svg_names::kPolylineTag);
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio.cc b/chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio.cc
index cf760eed072..dcad08c5391 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio.cc
@@ -186,7 +186,7 @@ bool SVGPreserveAspectRatio::Parse(const UChar*& ptr,
}
void SVGPreserveAspectRatio::TransformRect(FloatRect& dest_rect,
- FloatRect& src_rect) {
+ FloatRect& src_rect) const {
if (align_ == kSvgPreserveaspectratioNone)
return;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio.h b/chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio.h
index eaed2f3563a..aa90dba2e9e 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio.h
@@ -72,7 +72,7 @@ class SVGPreserveAspectRatio final
}
SVGMeetOrSliceType MeetOrSlice() const { return meet_or_slice_; }
- void TransformRect(FloatRect& dest_rect, FloatRect& src_rect);
+ void TransformRect(FloatRect& dest_rect, FloatRect& src_rect) const;
AffineTransform ComputeTransform(float logical_x,
float logical_y,
@@ -113,8 +113,6 @@ class SVGPreserveAspectRatio final
SVGMeetOrSliceType meet_or_slice_;
};
-DEFINE_SVG_PROPERTY_TYPE_CASTS(SVGPreserveAspectRatio);
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_PRESERVE_ASPECT_RATIO_H_
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 96045735027..3c96ac2b33e 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(blink::Visitor* visitor) {
+void SVGRadialGradientElement::Trace(Visitor* visitor) {
visitor->Trace(cx_);
visitor->Trace(cy_);
visitor->Trace(r_);
@@ -105,7 +105,6 @@ LayoutObject* SVGRadialGradientElement::CreateLayoutObject(const ComputedStyle&,
static void SetGradientAttributes(const SVGGradientElement& element,
RadialGradientAttributes& attributes,
bool is_radial) {
- element.SynchronizeAnimatedSVGAttribute(AnyQName());
element.CollectCommonAttributes(attributes);
if (!is_radial)
@@ -131,8 +130,8 @@ static void SetGradientAttributes(const SVGGradientElement& element,
attributes.SetFr(radial.fr()->CurrentValue());
}
-bool SVGRadialGradientElement::CollectGradientAttributes(
- RadialGradientAttributes& attributes) {
+void SVGRadialGradientElement::CollectGradientAttributes(
+ RadialGradientAttributes& attributes) const {
DCHECK(GetLayoutObject());
VisitedSet visited;
@@ -144,10 +143,12 @@ bool SVGRadialGradientElement::CollectGradientAttributes(
visited.insert(current);
current = current->ReferencedElement();
- if (!current || visited.Contains(current))
+ // Ignore the referenced gradient element if it is not attached.
+ if (!current || !current->GetLayoutObject())
+ break;
+ // Cycle detection.
+ if (visited.Contains(current))
break;
- if (!current->GetLayoutObject())
- return false;
}
// Handle default values for fx/fy
@@ -156,8 +157,6 @@ bool SVGRadialGradientElement::CollectGradientAttributes(
if (!attributes.HasFy())
attributes.SetFy(attributes.Cy());
-
- return true;
}
bool SVGRadialGradientElement::SelfHasRelativeLengths() const {
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 b37d292595c..5aa965d0768 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
@@ -35,7 +35,7 @@ class SVGRadialGradientElement final : public SVGGradientElement {
public:
explicit SVGRadialGradientElement(Document&);
- bool CollectGradientAttributes(RadialGradientAttributes&);
+ void CollectGradientAttributes(RadialGradientAttributes&) const;
SVGAnimatedLength* cx() const { return cx_.Get(); }
SVGAnimatedLength* cy() const { return cy_.Get(); }
@@ -44,7 +44,7 @@ class SVGRadialGradientElement final : public SVGGradientElement {
SVGAnimatedLength* fy() const { return fy_.Get(); }
SVGAnimatedLength* fr() const { return fr_.Get(); }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 0e494da0967..096bd566ec8 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_rect.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_rect.cc
@@ -91,7 +91,7 @@ String SVGRect::ValueAsString() const {
}
void SVGRect::Add(SVGPropertyBase* other, SVGElement*) {
- value_ += ToSVGRect(other)->Value();
+ value_ += To<SVGRect>(other)->Value();
}
void SVGRect::CalculateAnimatedValue(
@@ -102,9 +102,9 @@ void SVGRect::CalculateAnimatedValue(
SVGPropertyBase* to_value,
SVGPropertyBase* to_at_end_of_duration_value,
SVGElement*) {
- SVGRect* from_rect = ToSVGRect(from_value);
- SVGRect* to_rect = ToSVGRect(to_value);
- SVGRect* to_at_end_of_duration_rect = ToSVGRect(to_at_end_of_duration_value);
+ auto* from_rect = To<SVGRect>(from_value);
+ auto* to_rect = To<SVGRect>(to_value);
+ auto* to_at_end_of_duration_rect = To<SVGRect>(to_at_end_of_duration_value);
float animated_x = X();
float animated_y = Y();
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_rect.h b/chromium/third_party/blink/renderer/core/svg/svg_rect.h
index a3de5c7f0dc..e36f4c99ff2 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_rect.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_rect.h
@@ -24,6 +24,7 @@
#include "third_party/blink/renderer/core/svg/svg_parsing_error.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -83,7 +84,12 @@ class SVGRect final : public SVGPropertyHelper<SVGRect> {
FloatRect value_;
};
-DEFINE_SVG_PROPERTY_TYPE_CASTS(SVGRect);
+template <>
+struct DowncastTraits<SVGRect> {
+ static bool AllowFrom(const SVGPropertyBase& value) {
+ return value.GetType() == SVGRect::ClassType();
+ }
+};
} // namespace blink
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 d8be687b603..d3386c383ee 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(blink::Visitor* visitor) {
+void SVGRectElement::Trace(Visitor* visitor) {
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 1de73b696ea..15a81e7ef33 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 9421f732db6..110d32b4748 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_resource.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_resource.cc
@@ -81,6 +81,16 @@ void LocalSVGResource::NotifyContentChanged(
client->ResourceContentChanged(invalidation_mask);
}
+void LocalSVGResource::NotifyFilterPrimitiveChanged(
+ SVGFilterPrimitiveStandardAttributes& primitive,
+ const QualifiedName& attribute) {
+ HeapVector<Member<SVGResourceClient>> clients;
+ CopyToVector(clients_, clients);
+
+ for (SVGResourceClient* client : clients)
+ client->FilterPrimitiveChanged(primitive, attribute);
+}
+
void LocalSVGResource::NotifyResourceAttached(
LayoutSVGResourceContainer& attached_resource) {
// Checking the element here because
@@ -129,9 +139,24 @@ void ExternalSVGResource::Load(const Document& document) {
options.initiator_info.name = fetch_initiator_type_names::kCSS;
FetchParameters params(ResourceRequest(url_), options);
params.MutableResourceRequest().SetMode(
- network::mojom::RequestMode::kSameOrigin);
+ network::mojom::blink::RequestMode::kSameOrigin);
+ resource_document_ =
+ DocumentResource::FetchSVGDocument(params, document, this);
+ target_ = ResolveTarget();
+}
+
+void ExternalSVGResource::LoadWithoutCSP(const Document& document) {
+ if (resource_document_)
+ return;
+ ResourceLoaderOptions options;
+ options.initiator_info.name = fetch_initiator_type_names::kCSS;
+ FetchParameters params(ResourceRequest(url_), options);
+ params.SetContentSecurityCheck(
+ network::mojom::blink::CSPDisposition::DO_NOT_CHECK);
+ params.MutableResourceRequest().SetMode(
+ network::mojom::blink::RequestMode::kSameOrigin);
resource_document_ =
- DocumentResource::FetchSVGDocument(params, document.Fetcher(), this);
+ DocumentResource::FetchSVGDocument(params, document, this);
target_ = ResolveTarget();
}
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 21c8ca6a5ca..aab5fd2da1a 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_resource.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_resource.h
@@ -64,6 +64,7 @@ class SVGResource : public GarbageCollected<SVGResource> {
virtual ~SVGResource();
virtual void Load(const Document&) {}
+ virtual void LoadWithoutCSP(const Document&) {}
Element* Target() const { return target_; }
LayoutSVGResourceContainer* ResourceContainer() const;
@@ -71,8 +72,6 @@ class SVGResource : public GarbageCollected<SVGResource> {
void AddClient(SVGResourceClient&);
void RemoveClient(SVGResourceClient&);
- bool HasClients() const { return !clients_.IsEmpty(); }
-
virtual void Trace(Visitor*);
protected:
@@ -95,6 +94,9 @@ class LocalSVGResource final : public SVGResource {
void Unregister();
void NotifyContentChanged(InvalidationModeMask);
+ void NotifyFilterPrimitiveChanged(
+ SVGFilterPrimitiveStandardAttributes& primitive,
+ const QualifiedName& attribute);
void NotifyResourceAttached(LayoutSVGResourceContainer&);
void NotifyResourceDestroyed(LayoutSVGResourceContainer&);
@@ -116,6 +118,7 @@ class ExternalSVGResource final : public SVGResource, private ResourceClient {
explicit ExternalSVGResource(const KURL&);
void Load(const Document&) override;
+ void LoadWithoutCSP(const Document&) override;
void Trace(Visitor*) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_resource_client.h b/chromium/third_party/blink/renderer/core/svg/svg_resource_client.h
index d63b3b53308..1b5a5876982 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_resource_client.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_resource_client.h
@@ -11,6 +11,8 @@
namespace blink {
class LayoutSVGResourceContainer;
+class QualifiedName;
+class SVGFilterPrimitiveStandardAttributes;
typedef unsigned InvalidationModeMask;
@@ -24,13 +26,17 @@ class CORE_EXPORT SVGResourceClient : public GarbageCollectedMixin {
kLayoutInvalidation = 1 << 0,
kBoundariesInvalidation = 1 << 1,
kPaintInvalidation = 1 << 2,
- kParentOnlyInvalidation = 1 << 3,
- kSkipAncestorInvalidation = 1 << 4,
};
virtual void ResourceContentChanged(InvalidationModeMask) = 0;
virtual void ResourceElementChanged() = 0;
virtual void ResourceDestroyed(LayoutSVGResourceContainer*) {}
+ virtual void FilterPrimitiveChanged(
+ SVGFilterPrimitiveStandardAttributes& primitive,
+ const QualifiedName& attribute) {
+ ResourceContentChanged(kPaintInvalidation);
+ }
+
protected:
SVGResourceClient() = default;
};
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 0147e9dfdef..4efb5d34b65 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
@@ -93,6 +93,8 @@ bool SVGScriptElement::IsURLAttribute(const Attribute& attribute) const {
void SVGScriptElement::FinishParsingChildren() {
SVGElement::FinishParsingChildren();
have_fired_load_ = true;
+ DCHECK(!script_text_internal_slot_.length());
+ script_text_internal_slot_ = ParkableString(TextFromChildren().Impl());
}
bool SVGScriptElement::HaveLoadedRequiredResources() {
@@ -107,8 +109,12 @@ String SVGScriptElement::TypeAttributeValue() const {
return getAttribute(svg_names::kTypeAttr).GetString();
}
-String SVGScriptElement::TextFromChildren() {
- return Element::TextFromChildren();
+String SVGScriptElement::ChildTextContent() {
+ return TextFromChildren();
+}
+
+String SVGScriptElement::ScriptTextInternalSlot() const {
+ return script_text_internal_slot_.ToString();
}
bool SVGScriptElement::HasSourceAttribute() const {
@@ -164,6 +170,10 @@ void SVGScriptElement::SetScriptElementForBinding(
element.SetSVGScriptElement(this);
}
+ScriptElementBase::Type SVGScriptElement::GetScriptElementType() {
+ return ScriptElementBase::Type::kSVGScriptElement;
+}
+
#if DCHECK_IS_ON()
bool SVGScriptElement::IsAnimatableAttribute(const QualifiedName& name) const {
if (name == svg_names::kTypeAttr || name == svg_names::kHrefAttr ||
@@ -175,15 +185,15 @@ bool SVGScriptElement::IsAnimatableAttribute(const QualifiedName& name) const {
const AttrNameToTrustedType& SVGScriptElement::GetCheckedAttributeTypes()
const {
- DEFINE_STATIC_LOCAL(AttrNameToTrustedType, attribute_map,
- ({
- {svg_names::kHrefAttr.LocalName(),
- SpecificTrustedType::kTrustedScriptURL},
- }));
+ DEFINE_STATIC_LOCAL(
+ AttrNameToTrustedType, attribute_map,
+ ({
+ {svg_names::kHrefAttr.LocalName(), SpecificTrustedType::kScriptURL},
+ }));
return attribute_map;
}
-void SVGScriptElement::Trace(blink::Visitor* visitor) {
+void SVGScriptElement::Trace(Visitor* visitor) {
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 cb4b1763331..91c98f76fb0 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
@@ -26,6 +26,7 @@
#include "third_party/blink/renderer/core/svg/svg_element.h"
#include "third_party/blink/renderer/core/svg/svg_uri_reference.h"
#include "third_party/blink/renderer/core/svg_names.h"
+#include "third_party/blink/renderer/platform/bindings/parkable_string.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
@@ -51,7 +52,7 @@ class SVGScriptElement final : public SVGElement,
const AttrNameToTrustedType& GetCheckedAttributeTypes() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void ParseAttribute(const AttributeModificationParams&) override;
@@ -81,7 +82,8 @@ class SVGScriptElement final : public SVGElement,
bool NomoduleAttributeValue() const override { return false; }
String SourceAttributeValue() const override;
String TypeAttributeValue() const override;
- String TextFromChildren() override;
+ String ChildTextContent() override;
+ String ScriptTextInternalSlot() const override;
bool HasSourceAttribute() const override;
bool IsConnected() const override;
bool HasChildren() const override;
@@ -98,6 +100,8 @@ class SVGScriptElement final : public SVGElement,
void SetScriptElementForBinding(
HTMLScriptElementOrSVGScriptElement&) override;
+ Type GetScriptElementType() override;
+
Element& CloneWithoutAttributesAndChildren(Document&) const override;
bool LayoutObjectIsNeeded(const ComputedStyle&) const override {
return false;
@@ -105,6 +109,8 @@ class SVGScriptElement final : public SVGElement,
bool have_fired_load_ = false;
+ ParkableString script_text_internal_slot_;
+
Member<ScriptLoader> loader_;
};
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 3efc7dc42f5..9f39bfd8f40 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(blink::Visitor* visitor) {
+void SVGStaticStringList::Trace(Visitor* visitor) {
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 81beaf48b07..55547c440ed 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
@@ -74,7 +74,7 @@ class SVGStaticStringList final : public GarbageCollected<SVGStaticStringList>,
SVGStringListBase* Value() { return value_.Get(); }
SVGStringListTearOff* TearOff();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 557ce8d9706..53d12cfe254 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(blink::Visitor* visitor) {
+void SVGStopElement::Trace(Visitor* visitor) {
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 b8e3f0f26ad..32364f286ce 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
void DidRecalcStyle(const StyleRecalcChange) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_string.h b/chromium/third_party/blink/renderer/core/svg/svg_string.h
index ce240ba99f8..9125d80beca 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_string.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_string.h
@@ -77,8 +77,6 @@ class SVGString final : public SVGPropertyBase {
String value_;
};
-DEFINE_SVG_PROPERTY_TYPE_CASTS(SVGString);
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_STRING_H_
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_string_list_tear_off.h b/chromium/third_party/blink/renderer/core/svg/svg_string_list_tear_off.h
index f941d7cbf72..bbc7d879b0e 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_string_list_tear_off.h
+++ b/chromium/third_party/blink/renderer/core/svg/svg_string_list_tear_off.h
@@ -33,6 +33,7 @@
#include "third_party/blink/renderer/core/svg/properties/svg_property_tear_off.h"
#include "third_party/blink/renderer/core/svg/svg_string_list.h"
+#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
namespace blink {
@@ -96,11 +97,12 @@ class SVGStringListTearOff : public SVGPropertyTearOff<SVGStringListBase> {
return item;
}
- bool AnonymousIndexedSetter(uint32_t index,
- const String& item,
- ExceptionState& exception_state) {
+ IndexedPropertySetterResult AnonymousIndexedSetter(
+ uint32_t index,
+ const String& item,
+ ExceptionState& exception_state) {
replaceItem(item, index, exception_state);
- return true;
+ return IndexedPropertySetterResult::kIntercepted;
}
String removeItem(uint32_t index, ExceptionState& exception_state) {
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 78852ecd570..09fd3f44911 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(blink::Visitor* visitor) {
+void SVGStyleElement::Trace(Visitor* visitor) {
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 1c540a0484c..d00ea8a36f5 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 84514df2368..78b88fee9ab 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
@@ -29,6 +29,7 @@
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/dom/events/event_listener.h"
#include "third_party/blink/renderer/core/dom/static_node_list.h"
+#include "third_party/blink/renderer/core/dom/xml_document.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -372,7 +373,8 @@ StaticNodeList* SVGSVGElement::CollectIntersectionOrEnclosureList(
StaticNodeList* SVGSVGElement::getIntersectionList(
SVGRectTearOff* rect,
SVGElement* reference_element) const {
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
return CollectIntersectionOrEnclosureList(
rect->Target()->Value(), reference_element, kCheckIntersection);
@@ -381,7 +383,8 @@ StaticNodeList* SVGSVGElement::getIntersectionList(
StaticNodeList* SVGSVGElement::getEnclosureList(
SVGRectTearOff* rect,
SVGElement* reference_element) const {
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
return CollectIntersectionOrEnclosureList(rect->Target()->Value(),
reference_element, kCheckEnclosure);
@@ -390,7 +393,8 @@ StaticNodeList* SVGSVGElement::getEnclosureList(
bool SVGSVGElement::checkIntersection(SVGElement* element,
SVGRectTearOff* rect) const {
DCHECK(element);
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
return CheckIntersectionOrEnclosure(*element, rect->Target()->Value(),
kCheckIntersection);
@@ -399,7 +403,8 @@ bool SVGSVGElement::checkIntersection(SVGElement* element,
bool SVGSVGElement::checkEnclosure(SVGElement* element,
SVGRectTearOff* rect) const {
DCHECK(element);
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
return CheckIntersectionOrEnclosure(*element, rect->Target()->Value(),
kCheckEnclosure);
@@ -511,7 +516,7 @@ Node::InsertionNotificationRequest SVGSVGElement::InsertedInto(
ContainerNode& root_parent) {
if (root_parent.isConnected()) {
UseCounter::Count(GetDocument(), WebFeature::kSVGSVGElementInDocument);
- if (root_parent.GetDocument().IsXMLDocument())
+ if (IsA<XMLDocument>(root_parent.GetDocument()))
UseCounter::Count(GetDocument(), WebFeature::kSVGSVGElementInXMLDocument);
GetDocument().AccessSVGExtensions().AddTimeContainer(this);
@@ -729,7 +734,7 @@ void SVGSVGElement::FinishParsingChildren() {
SendSVGLoadEventIfPossible();
}
-void SVGSVGElement::Trace(blink::Visitor* visitor) {
+void SVGSVGElement::Trace(Visitor* visitor) {
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 de276f257ed..d153b348082 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 1b8ebcd60e0..7341f491adb 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(blink::Visitor* visitor) {
+void SVGSymbolElement::Trace(Visitor* visitor) {
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 580a3b5cec7..f54c16d8535 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void SvgAttributeChanged(const QualifiedName&) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_tag_names.json5 b/chromium/third_party/blink/renderer/core/svg/svg_tag_names.json5
index 53fc167c31b..59e6598d2c5 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_tag_names.json5
+++ b/chromium/third_party/blink/renderer/core/svg/svg_tag_names.json5
@@ -26,7 +26,6 @@
"clipPath",
"defs",
"desc",
- "discard",
"ellipse",
"feBlend",
"feColorMatrix",
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 dbbc2e9e5e7..fff3d4a17f9 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_tests.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_tests.cc
@@ -20,12 +20,14 @@
#include "third_party/blink/renderer/core/svg/svg_tests.h"
+#include "third_party/blink/renderer/core/mathml_names.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/svg/svg_element.h"
#include "third_party/blink/renderer/core/svg/svg_static_string_list.h"
#include "third_party/blink/renderer/core/svg_names.h"
#include "third_party/blink/renderer/platform/language.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
@@ -42,7 +44,7 @@ SVGTests::SVGTests(SVGElement* context_element)
context_element->AddToPropertyMap(system_language_);
}
-void SVGTests::Trace(blink::Visitor* visitor) {
+void SVGTests::Trace(Visitor* visitor) {
visitor->Trace(required_extensions_);
visitor->Trace(system_language_);
}
@@ -91,9 +93,19 @@ bool SVGTests::IsValid() const {
return false;
}
- if (!required_extensions_->Value()->Values().IsEmpty())
- return false;
-
+ if (required_extensions_->IsSpecified()) {
+ const Vector<String>& extensions = required_extensions_->Value()->Values();
+ // 'If a null string or empty string value is given to attribute
+ // 'requiredExtensions', the attribute evaluates to "false".'
+ if (extensions.IsEmpty())
+ return false;
+ for (const auto& extension : extensions) {
+ if (extension != html_names::xhtmlNamespaceURI &&
+ (!RuntimeEnabledFeatures::MathMLCoreEnabled() ||
+ extension != mathml_names::kNamespaceURI))
+ return false;
+ }
+ }
return true;
}
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 fa58e7f1bff..ed920cf8899 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 f81f3d4bf3b..542db849b2a 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,19 +85,21 @@ SVGTextContentElement::SVGTextContentElement(const QualifiedName& tag_name,
AddToPropertyMap(length_adjust_);
}
-void SVGTextContentElement::Trace(blink::Visitor* visitor) {
+void SVGTextContentElement::Trace(Visitor* visitor) {
visitor->Trace(text_length_);
visitor->Trace(length_adjust_);
SVGGraphicsElement::Trace(visitor);
}
unsigned SVGTextContentElement::getNumberOfChars() {
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
return SVGTextQuery(GetLayoutObject()).NumberOfCharacters();
}
float SVGTextContentElement::getComputedTextLength() {
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
return SVGTextQuery(GetLayoutObject()).TextLength();
}
@@ -105,7 +107,8 @@ float SVGTextContentElement::getSubStringLength(
unsigned charnum,
unsigned nchars,
ExceptionState& exception_state) {
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
unsigned number_of_chars = getNumberOfChars();
if (charnum >= number_of_chars) {
@@ -125,7 +128,8 @@ float SVGTextContentElement::getSubStringLength(
SVGPointTearOff* SVGTextContentElement::getStartPositionOfChar(
unsigned charnum,
ExceptionState& exception_state) {
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
if (charnum >= getNumberOfChars()) {
exception_state.ThrowDOMException(
@@ -143,7 +147,8 @@ SVGPointTearOff* SVGTextContentElement::getStartPositionOfChar(
SVGPointTearOff* SVGTextContentElement::getEndPositionOfChar(
unsigned charnum,
ExceptionState& exception_state) {
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
if (charnum >= getNumberOfChars()) {
exception_state.ThrowDOMException(
@@ -161,7 +166,8 @@ SVGPointTearOff* SVGTextContentElement::getEndPositionOfChar(
SVGRectTearOff* SVGTextContentElement::getExtentOfChar(
unsigned charnum,
ExceptionState& exception_state) {
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
if (charnum >= getNumberOfChars()) {
exception_state.ThrowDOMException(
@@ -178,7 +184,8 @@ SVGRectTearOff* SVGTextContentElement::getExtentOfChar(
float SVGTextContentElement::getRotationOfChar(
unsigned charnum,
ExceptionState& exception_state) {
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
if (charnum >= getNumberOfChars()) {
exception_state.ThrowDOMException(
@@ -194,7 +201,8 @@ float SVGTextContentElement::getRotationOfChar(
int SVGTextContentElement::getCharNumAtPosition(
SVGPointTearOff* point,
ExceptionState& exception_state) {
- GetDocument().UpdateStyleAndLayoutForNode(this);
+ GetDocument().UpdateStyleAndLayoutForNode(this,
+ DocumentUpdateReason::kJavaScript);
return SVGTextQuery(GetLayoutObject())
.CharacterNumberAtPosition(point->Target()->Value());
}
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 2538750acae..8f55e3b9d2a 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 b40655e04a2..392c4cb6fa8 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(blink::Visitor* visitor) {
+void SVGTextPathElement::Trace(Visitor* visitor) {
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 05766023ca6..497cd084d99 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 58b7eeabb77..a0cb80821d1 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(blink::Visitor* visitor) {
+void SVGTextPositioningElement::Trace(Visitor* visitor) {
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 fd26dff2e08..ab1f9a77ef1 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 10495982c46..91b88dab777 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
@@ -435,7 +435,7 @@ void SVGTransformList::Add(SVGPropertyBase* other,
if (IsEmpty())
return;
- SVGTransformList* other_list = ToSVGTransformList(other);
+ auto* other_list = To<SVGTransformList>(other);
if (length() != other_list->length())
return;
@@ -462,10 +462,10 @@ void SVGTransformList::CalculateAnimatedValue(
// post-multiplied. As a consequence, in SVG 1.1 the behavior of to animations
// for 'animateTransform' is undefined.
// FIXME: This is not taken into account yet.
- SVGTransformList* from_list = ToSVGTransformList(from_value);
- SVGTransformList* to_list = ToSVGTransformList(to_value);
- SVGTransformList* to_at_end_of_duration_list =
- ToSVGTransformList(to_at_end_of_duration_value);
+ auto* from_list = To<SVGTransformList>(from_value);
+ auto* to_list = To<SVGTransformList>(to_value);
+ auto* to_at_end_of_duration_list =
+ To<SVGTransformList>(to_at_end_of_duration_value);
size_t to_list_size = to_list->length();
if (!to_list_size)
@@ -517,7 +517,7 @@ float SVGTransformList::CalculateDistance(SVGPropertyBase* to_value,
// component (translate x and y for example) is paced separately. To implement
// this we need to treat each component as individual animation everywhere.
- SVGTransformList* to_list = ToSVGTransformList(to_value);
+ auto* to_list = To<SVGTransformList>(to_value);
if (IsEmpty() || length() != to_list->length())
return -1;
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 084bf850540..28930b5d87d 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
@@ -34,6 +34,7 @@
#include "third_party/blink/renderer/core/svg/properties/svg_list_property_helper.h"
#include "third_party/blink/renderer/core/svg/svg_parsing_error.h"
#include "third_party/blink/renderer/core/svg/svg_transform.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -80,7 +81,12 @@ class SVGTransformList final
SVGParsingError ParseInternal(const CharType*& ptr, const CharType* end);
};
-DEFINE_SVG_PROPERTY_TYPE_CASTS(SVGTransformList);
+template <>
+struct DowncastTraits<SVGTransformList> {
+ static bool AllowFrom(const SVGPropertyBase& value) {
+ return value.GetType() == SVGTransformList::ClassType();
+ }
+};
SVGTransformType ParseTransformType(const String&);
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 d147771a4d8..fb466b1f1e8 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(blink::Visitor* visitor) {
+void SVGTransformTearOff::Trace(Visitor* visitor) {
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 7d79e107e62..3fc02bc4a8c 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 aa90abbf069..277bb59b4bd 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
@@ -14,8 +14,6 @@ namespace blink {
SVGTreeScopeResources::SVGTreeScopeResources(TreeScope* tree_scope)
: tree_scope_(tree_scope) {}
-SVGTreeScopeResources::~SVGTreeScopeResources() = default;
-
LocalSVGResource* SVGTreeScopeResources::ResourceForId(const AtomicString& id) {
if (id.IsEmpty())
return nullptr;
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 6cde6465c34..f0273986798 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
@@ -22,7 +22,6 @@ class SVGTreeScopeResources final
: public GarbageCollected<SVGTreeScopeResources> {
public:
explicit SVGTreeScopeResources(TreeScope*);
- ~SVGTreeScopeResources();
LocalSVGResource* ResourceForId(const AtomicString& id);
LocalSVGResource* ExistingResourceForId(const AtomicString& id) const;
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 99471e10c92..4a3bb14b8d0 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(blink::Visitor* visitor) {
+void SVGURIReference::Trace(Visitor* visitor) {
visitor->Trace(href_);
}
@@ -124,7 +124,7 @@ Element* SVGURIReference::ObserveTarget(Member<IdTargetObserver>& observer,
Element* SVGURIReference::ObserveTarget(Member<IdTargetObserver>& observer,
SVGElement& context_element,
const String& href_string) {
- TreeScope& tree_scope = context_element.GetTreeScope();
+ TreeScope& tree_scope = context_element.OriginatingTreeScope();
AtomicString id = FragmentIdentifierFromIRIString(href_string, tree_scope);
return ObserveTarget(
observer, tree_scope, id,
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 6d3347ac51f..d36385c2700 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
explicit SVGURIReference(SVGElement*);
@@ -104,7 +104,7 @@ class SVGURLReferenceResolver {
private:
const String& relative_url_;
- Member<const Document> document_;
+ const Document* document_;
mutable KURL absolute_url_;
bool is_local_;
};
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 af673fe75f7..8cd5633c98c 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
@@ -25,7 +25,6 @@
#include "third_party/blink/renderer/core/svg/svg_use_element.h"
-#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -33,6 +32,7 @@
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/id_target_observer.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
+#include "third_party/blink/renderer/core/dom/xml_document.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_transformable_container.h"
#include "third_party/blink/renderer/core/svg/svg_g_element.h"
#include "third_party/blink/renderer/core/svg/svg_length_context.h"
@@ -94,7 +94,7 @@ void SVGUseElement::Dispose() {
ClearResource();
}
-void SVGUseElement::Trace(blink::Visitor* visitor) {
+void SVGUseElement::Trace(Visitor* visitor) {
visitor->Trace(x_);
visitor->Trace(y_);
visitor->Trace(width_);
@@ -107,7 +107,7 @@ void SVGUseElement::Trace(blink::Visitor* visitor) {
#if DCHECK_IS_ON()
static inline bool IsWellFormedDocument(const Document& document) {
- if (document.IsXMLDocument())
+ if (IsA<XMLDocument>(document))
return static_cast<XMLDocumentParser*>(document.Parser())->WellFormed();
return true;
}
@@ -204,10 +204,8 @@ void SVGUseElement::UpdateTargetReference() {
FetchParameters params(ResourceRequest(element_url_), options);
params.MutableResourceRequest().SetMode(
network::mojom::RequestMode::kSameOrigin);
- ResourceFetcher* fetcher = GetDocument().Fetcher();
- if (base::FeatureList::IsEnabled(
- features::kHtmlImportsRequestInitiatorLock) &&
- GetDocument().ImportsController()) {
+ auto* context_document = &GetDocument();
+ if (GetDocument().ImportsController()) {
// For @imports from HTML imported Documents, we use the
// context document for getting origin and ResourceFetcher to use the
// main Document's origin, while using the element document for
@@ -216,9 +214,9 @@ void SVGUseElement::UpdateTargetReference() {
ClearResource();
return;
}
- fetcher = GetDocument().ContextDocument()->Fetcher();
+ context_document = GetDocument().ContextDocument();
}
- DocumentResource::FetchSVGDocument(params, fetcher, this);
+ DocumentResource::FetchSVGDocument(params, *context_document, this);
}
void SVGUseElement::SvgAttributeChanged(const QualifiedName& attr_name) {
@@ -284,8 +282,6 @@ static bool IsDisallowedElement(const Element& element) {
}
void SVGUseElement::ScheduleShadowTreeRecreation() {
- if (InUseShadowTree())
- return;
needs_shadow_tree_recreation_ = true;
GetDocument().ScheduleUseShadowTreeUpdate(*this);
}
@@ -300,22 +296,27 @@ void SVGUseElement::ClearResourceReference() {
RemoveAllOutgoingReferences();
}
-Element* SVGUseElement::ResolveTargetElement(ObserveBehavior observe_behavior) {
+Element* SVGUseElement::ResolveTargetElement() {
if (!element_url_.HasFragmentIdentifier())
return nullptr;
AtomicString element_identifier(DecodeURLEscapeSequences(
element_url_.FragmentIdentifier(), DecodeURLMode::kUTF8OrIsomorphic));
+
if (!IsStructurallyExternal()) {
- if (observe_behavior == kDontAddObserver)
- return GetTreeScope().getElementById(element_identifier);
- return ObserveTarget(
- target_id_observer_, GetTreeScope(), element_identifier,
- WTF::BindRepeating(&SVGUseElement::InvalidateShadowTree,
- WrapWeakPersistent(this)));
+ // Only create observers for non-instance use elements.
+ // Instances will be updated by their corresponding elements.
+ if (InUseShadowTree()) {
+ return OriginatingTreeScope().getElementById(element_identifier);
+ } else {
+ return ObserveTarget(
+ target_id_observer_, OriginatingTreeScope(), element_identifier,
+ WTF::BindRepeating(&SVGUseElement::InvalidateTargetReference,
+ WrapWeakPersistent(this)));
+ }
}
if (!ResourceIsValid())
return nullptr;
- return ToDocumentResource(GetResource())
+ return To<DocumentResource>(GetResource())
->GetDocument()
->getElementById(element_identifier);
}
@@ -327,20 +328,24 @@ SVGElement* SVGUseElement::InstanceRoot() const {
}
void SVGUseElement::BuildPendingResource() {
- // This runs just before computed style is updated, so this SVGUseElement
- // should always be connected to the Document. It should also not be an
- // SVGUseElement that is part of a shadow tree, since we should never
- // schedule shadow tree updates for those.
- DCHECK(!InUseShadowTree());
- DCHECK(isConnected());
+ if (!isConnected()) {
+ DCHECK(!needs_shadow_tree_recreation_);
+ return; // Already replaced by rebuilding ancestor.
+ }
+ CancelShadowTreeRecreation();
+
+ // Check if this element is scheduled (by an ancestor) to be replaced.
+ SVGUseElement* ancestor = GeneratingUseElement();
+ while (ancestor) {
+ if (ancestor->needs_shadow_tree_recreation_)
+ return;
+ ancestor = ancestor->GeneratingUseElement();
+ }
DetachShadowTree();
ClearResourceReference();
- CancelShadowTreeRecreation();
- DCHECK(isConnected());
- auto* target = DynamicTo<SVGElement>(ResolveTargetElement(kAddObserver));
- if (target) {
+ if (auto* target = DynamicTo<SVGElement>(ResolveTargetElement())) {
DCHECK(target->isConnected());
AttachShadowTree(*target);
}
@@ -438,7 +443,6 @@ SVGElement* SVGUseElement::CreateInstanceTree(SVGElement& target_root) const {
void SVGUseElement::AttachShadowTree(SVGElement& target) {
DCHECK(!InstanceRoot());
DCHECK(!needs_shadow_tree_recreation_);
- DCHECK(!InUseShadowTree());
// Do not allow self-referencing.
if (IsDisallowedElement(target) || HasCycleUseReferencing(*this, target))
@@ -449,17 +453,11 @@ void SVGUseElement::AttachShadowTree(SVGElement& target) {
// <symbol> yet.
UseShadowRoot().AppendChild(CreateInstanceTree(target));
- AddReferencesToFirstDegreeNestedUseElements(target);
-
// Assure shadow tree building was successful.
DCHECK(InstanceRoot());
- DCHECK_EQ(InstanceRoot()->CorrespondingUseElement(), this);
+ DCHECK_EQ(InstanceRoot()->GeneratingUseElement(), this);
DCHECK_EQ(InstanceRoot()->CorrespondingElement(), &target);
- // Expand all <use> elements in the shadow tree.
- // Expand means: replace the actual <use> element by what it references.
- ExpandUseElementsInShadowTree();
-
for (SVGElement& instance :
Traversal<SVGElement>::DescendantsOf(UseShadowRoot())) {
SVGElement* corresponding_element = instance.CorrespondingElement();
@@ -472,22 +470,10 @@ void SVGUseElement::AttachShadowTree(SVGElement& target) {
// instance.
corresponding_element->MapInstanceToElement(&instance);
}
-
- // Update relative length information.
- UpdateRelativeLengthsInformation();
}
void SVGUseElement::DetachShadowTree() {
ShadowRoot& shadow_root = UseShadowRoot();
- // Tear down the mapping from the corresponding (original) element back to
- // the instance.
- for (SVGElement& instance :
- Traversal<SVGElement>::DescendantsOf(shadow_root)) {
- // When the instances of an element are invalidated the corresponding
- // element is cleared, so it can be null here.
- if (SVGElement* corresponding_element = instance.CorrespondingElement())
- corresponding_element->RemoveInstanceMapping(&instance);
- }
// FIXME: We should try to optimize this, to at least allow partial reclones.
shadow_root.RemoveChildren(kOmitSubtreeModifiedEvent);
}
@@ -506,11 +492,12 @@ static bool IsDirectReference(const SVGElement& element) {
Path SVGUseElement::ToClipPath() const {
const SVGGraphicsElement* element = VisibleTargetGraphicsElementForClipping();
- if (!element || !element->IsSVGGeometryElement())
+ auto* geometry_element = DynamicTo<SVGGeometryElement>(element);
+ if (!geometry_element)
return Path();
DCHECK(GetLayoutObject());
- Path path = ToSVGGeometryElement(*element).ToClipPath();
+ Path path = geometry_element->ToClipPath();
AffineTransform transform = GetLayoutObject()->LocalSVGTransform();
if (!transform.IsIdentity())
path.Transform(transform);
@@ -535,24 +522,6 @@ SVGGraphicsElement* SVGUseElement::VisibleTargetGraphicsElementForClipping()
return svg_graphics_element;
}
-void SVGUseElement::AddReferencesToFirstDegreeNestedUseElements(
- SVGElement& target) {
- // Don't track references to external documents.
- if (IsStructurallyExternal())
- return;
- // We only need to track first degree <use> dependencies. Indirect
- // references are handled as the invalidation bubbles up the dependency
- // chain.
- SVGUseElement* use_element =
- IsA<SVGUseElement>(target)
- ? To<SVGUseElement>(&target)
- : Traversal<SVGUseElement>::FirstWithin(target);
- for (; use_element;
- use_element = Traversal<SVGUseElement>::NextSkippingChildren(
- *use_element, &target))
- AddReferenceTo(use_element);
-}
-
bool SVGUseElement::HasCycleUseReferencing(const ContainerNode& target_instance,
const SVGElement& target) const {
// Shortcut for self-references
@@ -571,61 +540,6 @@ bool SVGUseElement::HasCycleUseReferencing(const ContainerNode& target_instance,
return false;
}
-// Spec: In the generated content, the 'use' will be replaced by 'g', where all
-// attributes from the 'use' element except for x, y, width, height and
-// xlink:href are transferred to the generated 'g' element.
-static void RemoveAttributesFromReplacementElement(
- SVGElement& replacement_element) {
- replacement_element.removeAttribute(svg_names::kXAttr);
- replacement_element.removeAttribute(svg_names::kYAttr);
- replacement_element.removeAttribute(svg_names::kWidthAttr);
- replacement_element.removeAttribute(svg_names::kHeightAttr);
- replacement_element.removeAttribute(svg_names::kHrefAttr);
- replacement_element.removeAttribute(xlink_names::kHrefAttr);
-}
-
-void SVGUseElement::ExpandUseElementsInShadowTree() {
- // Why expand the <use> elements in the shadow tree here, and not just
- // do this directly in buildShadowTree, if we encounter a <use> element?
- //
- // Short answer: Because we may miss to expand some elements. For example, if
- // a <symbol> contains <use> tags, we'd miss them. So once we're done with
- // setting up the actual shadow tree (after the special case modification for
- // svg/symbol) we have to walk it completely and expand all <use> elements.
- ShadowRoot& shadow_root = UseShadowRoot();
- for (SVGUseElement* use = Traversal<SVGUseElement>::FirstWithin(shadow_root);
- use;) {
- auto& original_use = To<SVGUseElement>(*use->CorrespondingElement());
- auto* target = DynamicTo<SVGElement>(
- original_use.ResolveTargetElement(kDontAddObserver));
- if (target) {
- if (IsDisallowedElement(*target) || HasCycleUseReferencing(*use, *target))
- return;
- }
-
- // Don't DCHECK(target) here, it may be "pending", too.
- // Setup sub-shadow tree root node
- auto* clone_parent =
- MakeGarbageCollected<SVGGElement>(original_use.GetDocument());
- // Transfer all data (attributes, etc.) from <use> to the new <g> element.
- clone_parent->CloneAttributesFrom(*use);
- clone_parent->SetCorrespondingElement(&original_use);
-
- RemoveAttributesFromReplacementElement(*clone_parent);
-
- // Move already cloned elements to the new <g> element.
- MoveChildrenToReplacementElement(*use, *clone_parent);
-
- if (target)
- clone_parent->AppendChild(use->CreateInstanceTree(*target));
-
- // Replace <use> with referenced content.
- use->parentNode()->ReplaceChild(clone_parent, use);
-
- use = Traversal<SVGUseElement>::Next(*clone_parent, &shadow_root);
- }
-}
-
bool SVGUseElement::ShadowTreeRebuildPending() const {
// The shadow tree is torn down lazily, so check if there's a pending rebuild
// or if we're disconnected from the document.
@@ -636,30 +550,18 @@ void SVGUseElement::InvalidateShadowTree() {
if (ShadowTreeRebuildPending())
return;
ScheduleShadowTreeRecreation();
- InvalidateDependentShadowTrees();
-}
-
-void SVGUseElement::InvalidateDependentShadowTrees() {
- // Recursively invalidate dependent <use> shadow trees
- const HeapHashSet<WeakMember<SVGElement>>& raw_instances =
- InstancesForElement();
- HeapVector<Member<SVGElement>> instances;
- instances.AppendRange(raw_instances.begin(), raw_instances.end());
- for (auto& instance : instances) {
- if (SVGUseElement* element = instance->CorrespondingUseElement()) {
- DCHECK(element->isConnected());
- element->InvalidateShadowTree();
- }
- }
+}
+
+void SVGUseElement::InvalidateTargetReference() {
+ InvalidateShadowTree();
+ for (SVGElement* instance : InstancesForElement())
+ To<SVGUseElement>(instance)->InvalidateShadowTree();
}
bool SVGUseElement::SelfHasRelativeLengths() const {
- if (x_->CurrentValue()->IsRelative() || y_->CurrentValue()->IsRelative() ||
- width_->CurrentValue()->IsRelative() ||
- height_->CurrentValue()->IsRelative())
- return true;
- SVGElement* instance_root = InstanceRoot();
- return instance_root && instance_root->HasRelativeLengths();
+ return x_->CurrentValue()->IsRelative() || y_->CurrentValue()->IsRelative() ||
+ width_->CurrentValue()->IsRelative() ||
+ height_->CurrentValue()->IsRelative();
}
FloatRect SVGUseElement::GetBBox() {
@@ -723,7 +625,7 @@ bool SVGUseElement::ResourceIsValid() const {
// TODO(fs): Handle revalidations that return a new/different resource.
if (!resource->IsLoaded() && !resource->IsCacheValidator())
return false;
- return ToDocumentResource(resource)->GetDocument();
+ return To<DocumentResource>(resource)->GetDocument();
}
} // namespace blink
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 3209a63904a..6d20db0dd8d 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
@@ -45,6 +45,7 @@ class SVGUseElement final : public SVGGraphicsElement,
~SVGUseElement() override;
void InvalidateShadowTree();
+ void InvalidateTargetReference();
// Return the element that should be used for clipping,
// or null if a valid clip element is not directly referenced.
@@ -61,7 +62,7 @@ class SVGUseElement final : public SVGGraphicsElement,
void DispatchPendingEvent();
Path ToClipPath() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void Dispose();
@@ -96,12 +97,7 @@ class SVGUseElement final : public SVGGraphicsElement,
return *ClosedShadowRoot();
}
- // Instance tree handling
- enum ObserveBehavior {
- kAddObserver,
- kDontAddObserver,
- };
- Element* ResolveTargetElement(ObserveBehavior);
+ Element* ResolveTargetElement();
void AttachShadowTree(SVGElement& target);
void DetachShadowTree();
CORE_EXPORT SVGElement* InstanceRoot() const;
@@ -109,10 +105,6 @@ class SVGUseElement final : public SVGGraphicsElement,
void ClearResourceReference();
bool HasCycleUseReferencing(const ContainerNode& target_instance,
const SVGElement& new_target) const;
- void ExpandUseElementsInShadowTree();
- void AddReferencesToFirstDegreeNestedUseElements(SVGElement& target);
-
- void InvalidateDependentShadowTrees();
bool ResourceIsValid() const;
void NotifyFinished(Resource*) override;
diff --git a/chromium/third_party/blink/renderer/core/svg/svg_use_element_test.cc b/chromium/third_party/blink/renderer/core/svg/svg_use_element_test.cc
index 8d06d595899..e26665fc54a 100644
--- a/chromium/third_party/blink/renderer/core/svg/svg_use_element_test.cc
+++ b/chromium/third_party/blink/renderer/core/svg/svg_use_element_test.cc
@@ -12,12 +12,12 @@
namespace blink {
-using LifecycleUpdateReason = DocumentLifecycle::LifecycleUpdateReason;
+using LifecycleUpdateReason = DocumentUpdateReason;
class SVGUseElementTest : public PageTestBase {};
TEST_F(SVGUseElementTest, InstanceInvalidatedWhenNonAttachedTargetRemoved) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<style></style>
<svg>
<unknown>
@@ -47,7 +47,7 @@ TEST_F(SVGUseElementTest, InstanceInvalidatedWhenNonAttachedTargetRemoved) {
TEST_F(SVGUseElementTest,
InstanceInvalidatedWhenNonAttachedTargetMovedInDocument) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<svg>
<use id="use" href="#path"/>
<textPath id="path">
@@ -76,7 +76,7 @@ TEST_F(SVGUseElementTest,
}
TEST_F(SVGUseElementTest, NullInstanceRootWhenNotConnectedToDocument) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<svg>
<defs>
<rect id="r" width="100" height="100" fill="blue"/>
@@ -96,7 +96,7 @@ TEST_F(SVGUseElementTest, NullInstanceRootWhenNotConnectedToDocument) {
}
TEST_F(SVGUseElementTest, NullInstanceRootWhenConnectedToInactiveDocument) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<svg>
<defs>
<rect id="r" width="100" height="100" fill="blue"/>
@@ -118,7 +118,7 @@ TEST_F(SVGUseElementTest, NullInstanceRootWhenConnectedToInactiveDocument) {
}
TEST_F(SVGUseElementTest, NullInstanceRootWhenShadowTreePendingRebuild) {
- GetDocument().body()->SetInnerHTMLFromString(R"HTML(
+ GetDocument().body()->setInnerHTML(R"HTML(
<svg>
<defs>
<rect id="r" width="100" height="100" fill="blue"/>
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 6fb063483e0..ac872c18cd3 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(blink::Visitor* visitor) {
+void SVGViewElement::Trace(Visitor* visitor) {
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 bdde4bf5682..f42c137721c 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void ParseAttribute(const AttributeModificationParams&) override;
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 20a4843225a..f34d987083d 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
@@ -7,6 +7,7 @@
#include <memory>
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/renderer/core/clipboard/system_clipboard.h"
#include "third_party/blink/renderer/core/dom/qualified_name.h"
#include "third_party/blink/renderer/core/editing/editor.h"
@@ -20,10 +21,11 @@
#include "third_party/blink/renderer/core/svg/properties/svg_property_info.h"
#include "third_party/blink/renderer/core/svg/svg_a_element.h"
#include "third_party/blink/renderer/core/svg/svg_animate_element.h"
-#include "third_party/blink/renderer/core/svg/svg_discard_element.h"
#include "third_party/blink/renderer/core/svg/svg_set_element.h"
#include "third_party/blink/renderer/core/svg_names.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
+#include "third_party/blink/renderer/core/testing/mock_clipboard_host.h"
+#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/core/xlink_names.h"
#include "third_party/blink/renderer/platform/geometry/int_size.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
@@ -46,7 +48,6 @@
// The following SVG elements, although related to animation, cannot
// set JavaScript URLs:
//
-// - 'discard' can only remove elements, not set their attributes
// - 'animateMotion' does not use attribute name and produces floats
// - 'animateTransform' can only animate transform lists
@@ -57,12 +58,17 @@ namespace blink {
String ContentAfterPastingHTML(DummyPageHolder* page_holder,
const char* html_to_paste) {
LocalFrame& frame = page_holder->GetFrame();
+
+ // Setup a mock clipboard host.
+ PageTestBase::MockClipboardHostProvider mock_clipboard_host_provider(
+ frame.GetBrowserInterfaceBroker());
+
HTMLElement* body = page_holder->GetDocument().body();
// Make the body editable, and put the caret in it.
body->setAttribute(html_names::kContenteditableAttr, "true");
body->focus();
- frame.GetDocument()->UpdateStyleAndLayout();
+ frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kTest);
frame.Selection().SetSelectionAndEndTyping(
SelectionInDOMTree::Builder().SelectAllChildren(*body).Build());
EXPECT_TRUE(frame.Selection().ComputeVisibleSelectionInDOMTree().IsCaret());
@@ -70,15 +76,15 @@ String ContentAfterPastingHTML(DummyPageHolder* page_holder,
frame.Selection().ComputeVisibleSelectionInDOMTree().IsContentEditable())
<< "We should be pasting into something editable.";
- SystemClipboard::GetInstance().WriteHTML(
- html_to_paste, BlankURL(), "", SystemClipboard::kCannotSmartReplace);
- SystemClipboard::GetInstance().CommitWrite();
+ frame.GetSystemClipboard()->WriteHTML(html_to_paste, BlankURL(), "",
+ SystemClipboard::kCannotSmartReplace);
+ frame.GetSystemClipboard()->CommitWrite();
// Run all tasks in a message loop to allow asynchronous clipboard writing
// to happen before reading from it synchronously.
test::RunPendingTasks();
EXPECT_TRUE(frame.GetEditor().ExecuteCommand("Paste"));
- return body->InnerHTMLAsString();
+ return body->innerHTML();
}
// Integration tests.
diff --git a/chromium/third_party/blink/renderer/core/testing/DEPS b/chromium/third_party/blink/renderer/core/testing/DEPS
index a8194e3a82b..fecfd9308ce 100644
--- a/chromium/third_party/blink/renderer/core/testing/DEPS
+++ b/chromium/third_party/blink/renderer/core/testing/DEPS
@@ -7,6 +7,7 @@ include_rules = [
"+content/renderer/compositor",
"+content/test",
"+gpu/command_buffer/client/gles2_interface.h",
+ "+ui/events/blink/blink_event_util.h"
]
specific_include_rules = {
diff --git a/chromium/third_party/blink/renderer/core/testing/color_scheme_helper.cc b/chromium/third_party/blink/renderer/core/testing/color_scheme_helper.cc
index f673819b907..2101c0cb70d 100644
--- a/chromium/third_party/blink/renderer/core/testing/color_scheme_helper.cc
+++ b/chromium/third_party/blink/renderer/core/testing/color_scheme_helper.cc
@@ -7,35 +7,36 @@
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_theme_engine.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/page/page.h"
namespace blink {
-ColorSchemeHelper::ColorSchemeHelper() {
+ColorSchemeHelper::ColorSchemeHelper(Document& document)
+ : settings_(*document.GetSettings()) {
DCHECK(Platform::Current() && Platform::Current()->ThemeEngine());
web_theme_engine_ = Platform::Current()->ThemeEngine();
- default_preferred_color_scheme_ = web_theme_engine_->PreferredColorScheme();
+ default_preferred_color_scheme_ = settings_.GetPreferredColorScheme();
+ default_forced_colors_ = web_theme_engine_->GetForcedColors();
+}
+
+ColorSchemeHelper::ColorSchemeHelper(Page& page)
+ : settings_(page.GetSettings()) {
+ DCHECK(Platform::Current() && Platform::Current()->ThemeEngine());
+ web_theme_engine_ = Platform::Current()->ThemeEngine();
+ default_preferred_color_scheme_ = settings_.GetPreferredColorScheme();
default_forced_colors_ = web_theme_engine_->GetForcedColors();
}
ColorSchemeHelper::~ColorSchemeHelper() {
// Reset preferred color scheme and forced colors to their original values.
- web_theme_engine_->SetPreferredColorScheme(default_preferred_color_scheme_);
+ settings_.SetPreferredColorScheme(default_preferred_color_scheme_);
web_theme_engine_->SetForcedColors(default_forced_colors_);
}
void ColorSchemeHelper::SetPreferredColorScheme(
- Document& document,
const PreferredColorScheme preferred_color_scheme) {
- web_theme_engine_->SetPreferredColorScheme(preferred_color_scheme);
- document.ColorSchemeChanged();
-}
-
-void ColorSchemeHelper::SetPreferredColorScheme(
- Page& page,
- const PreferredColorScheme preferred_color_scheme) {
- web_theme_engine_->SetPreferredColorScheme(preferred_color_scheme);
- page.ColorSchemeChanged();
+ settings_.SetPreferredColorScheme(preferred_color_scheme);
}
void ColorSchemeHelper::SetForcedColors(Document& document,
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 3059873dc7e..25df460ecb4 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
@@ -12,6 +12,7 @@ namespace blink {
class Document;
class Page;
+class Settings;
class WebThemeEngine;
// ColorSchemeHelper is used to update the values of PreferredColorScheme and
@@ -19,20 +20,18 @@ class WebThemeEngine;
// and ForcedColors back to their default values upon deconstruction.
class ColorSchemeHelper {
public:
- ColorSchemeHelper();
+ ColorSchemeHelper(Document& document);
+ ColorSchemeHelper(Page& page);
~ColorSchemeHelper();
void SetPreferredColorScheme(
- Document& document,
- const PreferredColorScheme preferred_color_scheme);
- void SetPreferredColorScheme(
- Page& page,
const PreferredColorScheme preferred_color_scheme);
void SetForcedColors(Document& document, const ForcedColors forced_colors);
void SetForcedColors(Page& page, const ForcedColors forced_colors);
private:
WebThemeEngine* web_theme_engine_ = nullptr;
+ Settings& settings_;
PreferredColorScheme default_preferred_color_scheme_ =
PreferredColorScheme::kNoPreference;
ForcedColors default_forced_colors_ = ForcedColors::kNone;
diff --git a/chromium/third_party/blink/renderer/core/testing/core_unit_test_helper.cc b/chromium/third_party/blink/renderer/core/testing/core_unit_test_helper.cc
index d43b8c66c40..6a4181ec261 100644
--- a/chromium/third_party/blink/renderer/core/testing/core_unit_test_helper.cc
+++ b/chromium/third_party/blink/renderer/core/testing/core_unit_test_helper.cc
@@ -6,11 +6,13 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/core/html/html_iframe_element.h"
+#include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
+#include "ui/events/blink/blink_event_util.h"
namespace blink {
@@ -36,6 +38,27 @@ void LocalFrameClientWithParent::Detached(FrameDetachType) {
->DidDetachChild();
}
+void RenderingTestChromeClient::InjectGestureScrollEvent(
+ LocalFrame& local_frame,
+ WebGestureDevice device,
+ const gfx::Vector2dF& delta,
+ ScrollGranularity granularity,
+ CompositorElementId scrollable_area_element_id,
+ WebInputEvent::Type injected_type) {
+ // Directly handle injected gesture scroll events. In a real browser, these
+ // would be added to the event queue and handled asynchronously but immediate
+ // handling is sufficient to test scrollbar dragging.
+ std::unique_ptr<WebGestureEvent> gesture_event =
+ ui::GenerateInjectedScrollGesture(injected_type, base::TimeTicks::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();
+ }
+ local_frame.GetEventHandler().HandleGestureEvent(*gesture_event);
+}
+
RenderingTestChromeClient& RenderingTest::GetChromeClient() const {
DEFINE_STATIC_LOCAL(Persistent<RenderingTestChromeClient>, client,
(MakeGarbageCollected<RenderingTestChromeClient>()));
@@ -99,7 +122,7 @@ void RenderingTest::TearDown() {
void RenderingTest::SetChildFrameHTML(const String& html) {
ChildDocument().SetBaseURLOverride(KURL("http://test.com"));
- ChildDocument().body()->SetInnerHTMLFromString(html, ASSERT_NO_EXCEPTION);
+ ChildDocument().body()->setInnerHTML(html, ASSERT_NO_EXCEPTION);
// Setting HTML implies the frame loads contents, so we need to advance the
// state machine to leave the initial empty document state.
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 c2ddac1e81a..61444e22c95 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(parent_);
EmptyLocalFrameClient::Trace(visitor);
}
@@ -97,6 +97,13 @@ class RenderingTestChromeClient : public EmptyChromeClient {
return device_emulation_transform_;
}
+ void InjectGestureScrollEvent(LocalFrame& local_frame,
+ WebGestureDevice device,
+ const gfx::Vector2dF& delta,
+ ScrollGranularity granularity,
+ CompositorElementId scrollable_area_element_id,
+ WebInputEvent::Type injected_type) override;
+
private:
std::unique_ptr<LayerTreeHostEmbedder> layer_tree_;
TransformationMatrix device_emulation_transform_;
diff --git a/chromium/third_party/blink/renderer/core/testing/data/Ahem.woff2 b/chromium/third_party/blink/renderer/core/testing/data/Ahem.woff2
new file mode 100644
index 00000000000..bf3cc7736e2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/testing/data/Ahem.woff2
Binary files differ
diff --git a/chromium/third_party/blink/renderer/core/testing/data/test_touch_link_highlight.html b/chromium/third_party/blink/renderer/core/testing/data/test_touch_link_highlight.html
index b559dea797b..093a98525f4 100644
--- a/chromium/third_party/blink/renderer/core/testing/data/test_touch_link_highlight.html
+++ b/chromium/third_party/blink/renderer/core/testing/data/test_touch_link_highlight.html
@@ -39,5 +39,8 @@
<div style="display: inline-block; width: 200px; height: 25px">Link part 3</div>
</a>
</div>
+ <div style="position: absolute; left: 20px; top: 400px">
+ <div id="display-contents" style="display: contents; cursor: pointer">Contents</div>
+ <div>
</body>
</html>
diff --git a/chromium/third_party/blink/renderer/core/testing/data/touch-action-on-inline.html b/chromium/third_party/blink/renderer/core/testing/data/touch-action-on-inline.html
index b6a923fe9fb..4ebc395c1f4 100644
--- a/chromium/third_party/blink/renderer/core/testing/data/touch-action-on-inline.html
+++ b/chromium/third_party/blink/renderer/core/testing/data/touch-action-on-inline.html
@@ -2,4 +2,4 @@
<style>
div { width: 10px; height: 50px; touch-action: none; font: 10px Ahem; }
</style>
-<div>aaaaaaaa</div>
+<div>aaaa<span>aaaaaaaa</span></div>
diff --git a/chromium/third_party/blink/renderer/core/testing/data/touch-action-on-text.html b/chromium/third_party/blink/renderer/core/testing/data/touch-action-on-text.html
new file mode 100644
index 00000000000..ff9a54b0192
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/testing/data/touch-action-on-text.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<style>
+ div { width: 10px; height: 20px; touch-action: none; font: 10px Ahem; }
+</style>
+<div>aaaaaaaa<br>aaaa<br>aaaaaaaaaaaaaaaa</div>
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 6f19681f7f1..2666aa5bf80 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
@@ -43,10 +43,6 @@ class DeathAwareScriptWrappable : public ScriptWrappable {
public:
typedef Member<DeathAwareScriptWrappable> Wrapper;
- static DeathAwareScriptWrappable* Create() {
- return MakeGarbageCollected<DeathAwareScriptWrappable>();
- }
-
static bool HasDied() { return has_died_; }
static void ObserveDeathsOf(DeathAwareScriptWrappable* instance) {
has_died_ = false;
@@ -60,7 +56,7 @@ class DeathAwareScriptWrappable : public ScriptWrappable {
}
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 b0a6c81d268..b8abbf50eef 100644
--- a/chromium/third_party/blink/renderer/core/testing/dictionary_test.cc
+++ b/chromium/third_party/blink/renderer/core/testing/dictionary_test.cc
@@ -5,35 +5,15 @@
#include "third_party/blink/renderer/core/testing/dictionary_test.h"
#include "third_party/blink/renderer/bindings/core/v8/script_iterator.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_internal_dictionary.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_internal_dictionary_derived.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_internal_dictionary_derived_derived.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
-#include "third_party/blink/renderer/core/testing/internal_dictionary.h"
-#include "third_party/blink/renderer/core/testing/internal_dictionary_derived.h"
-#include "third_party/blink/renderer/core/testing/internal_dictionary_derived_derived.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
namespace blink {
-namespace {
-ScriptIterator GetIterator(const Dictionary& iterable,
- ExecutionContext* execution_context) {
- v8::Local<v8::Value> iterator_getter;
- v8::Isolate* isolate = iterable.GetIsolate();
- if (!iterable.Get(v8::Symbol::GetIterator(isolate), iterator_getter) ||
- !iterator_getter->IsFunction()) {
- return ScriptIterator();
- }
- v8::Local<v8::Value> iterator;
- if (!V8ScriptRunner::CallFunction(
- v8::Local<v8::Function>::Cast(iterator_getter), execution_context,
- iterable.V8Value(), 0, nullptr, isolate)
- .ToLocal(&iterator))
- return ScriptIterator();
- if (!iterator->IsObject())
- return ScriptIterator();
- return ScriptIterator(isolate, v8::Local<v8::Object>::Cast(iterator));
-}
-} // namespace
DictionaryTest::DictionaryTest() : required_boolean_member_(false) {}
@@ -95,12 +75,6 @@ void DictionaryTest::set(const InternalDictionary* testing_dictionary) {
testing_dictionary->doubleOrStringSequenceMember();
}
event_target_or_null_member_ = testing_dictionary->eventTargetOrNullMember();
- if (testing_dictionary->hasDictionaryMember()) {
- NonThrowableExceptionState exception_state;
- dictionary_member_properties_ =
- testing_dictionary->dictionaryMember().GetOwnPropertiesAsStringHashMap(
- exception_state);
- }
if (testing_dictionary->hasInternalEnumOrInternalEnumSequenceMember()) {
internal_enum_or_internal_enum_sequence_ =
testing_dictionary->internalEnumOrInternalEnumSequenceMember();
@@ -115,18 +89,6 @@ InternalDictionary* DictionaryTest::get() {
return result;
}
-ScriptValue DictionaryTest::getDictionaryMemberProperties(
- ScriptState* script_state) {
- if (!dictionary_member_properties_)
- return ScriptValue();
- V8ObjectBuilder builder(script_state);
- HashMap<String, String> properties = dictionary_member_properties_.value();
- for (HashMap<String, String>::iterator it = properties.begin();
- it != properties.end(); ++it)
- builder.AddString(it->key, it->value);
- return builder.GetScriptValue();
-}
-
void DictionaryTest::setDerived(const InternalDictionaryDerived* derived) {
DCHECK(derived->hasRequiredBooleanMember());
set(derived);
@@ -157,36 +119,6 @@ InternalDictionaryDerivedDerived* DictionaryTest::getDerivedDerived() {
return result;
}
-String DictionaryTest::stringFromIterable(
- ScriptState* script_state,
- Dictionary iterable,
- ExceptionState& exception_state) const {
- StringBuilder result;
- ExecutionContext* execution_context = ExecutionContext::From(script_state);
- ScriptIterator iterator = GetIterator(iterable, execution_context);
- if (iterator.IsNull())
- return g_empty_string;
-
- bool first_loop = true;
- while (iterator.Next(execution_context, exception_state)) {
- if (exception_state.HadException())
- return g_empty_string;
-
- if (first_loop)
- first_loop = false;
- else
- result.Append(',');
-
- v8::Local<v8::Value> value;
- if (iterator.GetValue().ToLocal(&value)) {
- result.Append(ToCoreString(
- value->ToString(script_state->GetContext()).ToLocalChecked()));
- }
- }
-
- return result.ToString();
-}
-
void DictionaryTest::Reset() {
long_member_ = base::nullopt;
long_member_with_clamp_ = base::nullopt;
@@ -294,7 +226,7 @@ void DictionaryTest::GetDerivedDerivedInternals(
dict->setDerivedDerivedStringMember(derived_derived_string_member_);
}
-void DictionaryTest::Trace(blink::Visitor* visitor) {
+void DictionaryTest::Trace(Visitor* visitor) {
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 33bb414d57f..af0516d5b24 100644
--- a/chromium/third_party/blink/renderer/core/testing/dictionary_test.h
+++ b/chromium/third_party/blink/renderer/core/testing/dictionary_test.h
@@ -21,7 +21,6 @@ namespace blink {
class InternalDictionary;
class InternalDictionaryDerived;
class InternalDictionaryDerivedDerived;
-class ScriptState;
class DictionaryTest : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
@@ -34,9 +33,6 @@ class DictionaryTest : public ScriptWrappable {
void set(const InternalDictionary*);
// Sets each member of the given TestDictionary from fields
InternalDictionary* get();
- // Returns properties of the latest |dictionaryMember| which was set via
- // set().
- ScriptValue getDictionaryMemberProperties(ScriptState*);
void setDerived(const InternalDictionaryDerived*);
InternalDictionaryDerived* getDerived();
@@ -44,11 +40,7 @@ class DictionaryTest : public ScriptWrappable {
void setDerivedDerived(const InternalDictionaryDerivedDerived*);
InternalDictionaryDerivedDerived* getDerivedDerived();
- String stringFromIterable(ScriptState*,
- Dictionary iterable,
- ExceptionState&) const;
-
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void Reset();
diff --git a/chromium/third_party/blink/renderer/core/testing/dictionary_test.idl b/chromium/third_party/blink/renderer/core/testing/dictionary_test.idl
index e1cddf7ce3f..e759f144450 100644
--- a/chromium/third_party/blink/renderer/core/testing/dictionary_test.idl
+++ b/chromium/third_party/blink/renderer/core/testing/dictionary_test.idl
@@ -3,15 +3,12 @@
// found in the LICENSE file.
interface DictionaryTest {
- void set(optional InternalDictionary testingDictionary);
+ void set(optional InternalDictionary testingDictionary = {});
InternalDictionary get();
- [CallWith=ScriptState] object getDictionaryMemberProperties();
void setDerived(InternalDictionaryDerived derived);
InternalDictionaryDerived getDerived();
void setDerivedDerived(InternalDictionaryDerivedDerived derived);
InternalDictionaryDerivedDerived getDerivedDerived();
-
- [CallWith=ScriptState, RaisesException] DOMString stringFromIterable(Dictionary iterableDictionary);
};
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 c9db16d8f17..b0556a8ac93 100644
--- a/chromium/third_party/blink/renderer/core/testing/dummy_modulator.cc
+++ b/chromium/third_party/blink/renderer/core/testing/dummy_modulator.cc
@@ -41,7 +41,7 @@ DummyModulator::DummyModulator()
DummyModulator::~DummyModulator() = default;
-void DummyModulator::Trace(blink::Visitor* visitor) {
+void DummyModulator::Trace(Visitor* visitor) {
visitor->Trace(resolver_);
Modulator::Trace(visitor);
}
@@ -63,16 +63,6 @@ bool DummyModulator::ImportMapsEnabled() const {
return false;
}
-bool DummyModulator::BuiltInModuleInfraEnabled() const {
- return false;
-}
-
-bool DummyModulator::BuiltInModuleEnabled(blink::layered_api::Module) const {
- return false;
-}
-
-void DummyModulator::BuiltInModuleUseCount(blink::layered_api::Module) const {}
-
ModuleRecordResolver* DummyModulator::GetModuleRecordResolver() {
return resolver_.Get();
}
@@ -85,6 +75,7 @@ base::SingleThreadTaskRunner* DummyModulator::TaskRunner() {
void DummyModulator::FetchTree(const KURL&,
ResourceFetcher*,
mojom::RequestContextType,
+ network::mojom::RequestDestination,
const ScriptFetchOptions&,
ModuleScriptCustomFetchType,
ModuleTreeClient*) {
@@ -99,10 +90,12 @@ void DummyModulator::FetchSingle(const ModuleScriptFetchRequest&,
NOTREACHED();
}
-void DummyModulator::FetchDescendantsForInlineScript(ModuleScript*,
- ResourceFetcher*,
- mojom::RequestContextType,
- ModuleTreeClient*) {
+void DummyModulator::FetchDescendantsForInlineScript(
+ ModuleScript*,
+ ResourceFetcher*,
+ mojom::RequestContextType,
+ network::mojom::RequestDestination,
+ ModuleTreeClient*) {
NOTREACHED();
}
@@ -181,7 +174,8 @@ ScriptValue DummyModulator::ExecuteModule(ModuleScript*, CaptureEvalErrorFlag) {
}
ModuleScriptFetcher* DummyModulator::CreateModuleScriptFetcher(
- ModuleScriptCustomFetchType) {
+ ModuleScriptCustomFetchType,
+ util::PassKey<ModuleScriptLoader> pass_key) {
NOTREACHED();
return nullptr;
}
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 8b862e3eb36..3b4646c107f 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
ModuleRecordResolver* GetModuleRecordResolver() override;
base::SingleThreadTaskRunner* TaskRunner() override;
@@ -36,13 +36,11 @@ class DummyModulator : public Modulator {
bool IsScriptingDisabled() const override;
bool ImportMapsEnabled() const override;
- bool BuiltInModuleInfraEnabled() const override;
- bool BuiltInModuleEnabled(blink::layered_api::Module) const override;
- void BuiltInModuleUseCount(blink::layered_api::Module) const override;
void FetchTree(const KURL&,
ResourceFetcher*,
- mojom::RequestContextType destination,
+ mojom::RequestContextType context_type,
+ network::mojom::RequestDestination destination,
const ScriptFetchOptions&,
ModuleScriptCustomFetchType,
ModuleTreeClient*) override;
@@ -51,10 +49,12 @@ class DummyModulator : public Modulator {
ModuleGraphLevel,
ModuleScriptCustomFetchType,
SingleModuleClient*) override;
- void FetchDescendantsForInlineScript(ModuleScript*,
- ResourceFetcher*,
- mojom::RequestContextType destination,
- ModuleTreeClient*) override;
+ void FetchDescendantsForInlineScript(
+ ModuleScript*,
+ ResourceFetcher*,
+ mojom::RequestContextType context_type,
+ network::mojom::RequestDestination destination,
+ ModuleTreeClient*) override;
ModuleScript* GetFetchedModuleScript(const KURL&) override;
KURL ResolveModuleSpecifier(const String&, const KURL&, String*) override;
bool HasValidContext() override;
@@ -76,7 +76,8 @@ class DummyModulator : public Modulator {
v8::Local<v8::Module>) override;
ScriptValue ExecuteModule(ModuleScript*, CaptureEvalErrorFlag) override;
ModuleScriptFetcher* CreateModuleScriptFetcher(
- ModuleScriptCustomFetchType) override;
+ ModuleScriptCustomFetchType,
+ util::PassKey<ModuleScriptLoader>) override;
Member<ModuleRecordResolver> resolver_;
};
diff --git a/chromium/third_party/blink/renderer/core/testing/dummy_page_holder.cc b/chromium/third_party/blink/renderer/core/testing/dummy_page_holder.cc
index 7ab8fb379f3..e9a7b07b0ba 100644
--- a/chromium/third_party/blink/renderer/core/testing/dummy_page_holder.cc
+++ b/chromium/third_party/blink/renderer/core/testing/dummy_page_holder.cc
@@ -64,7 +64,8 @@ DummyPageHolder::DummyPageHolder(
Page::PageClients* page_clients_argument,
LocalFrameClient* local_frame_client,
base::OnceCallback<void(Settings&)> setting_overrider,
- const base::TickClock* clock) {
+ const base::TickClock* clock)
+ : enable_mock_scrollbars_(true) {
Page::PageClients page_clients;
if (!page_clients_argument)
FillWithEmptyClients(page_clients);
diff --git a/chromium/third_party/blink/renderer/core/testing/dummy_page_holder.h b/chromium/third_party/blink/renderer/core/testing/dummy_page_holder.h
index 67e784504f4..9b64a9bcec8 100644
--- a/chromium/third_party/blink/renderer/core/testing/dummy_page_holder.h
+++ b/chromium/third_party/blink/renderer/core/testing/dummy_page_holder.h
@@ -33,11 +33,13 @@
#include <memory>
+#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/macros.h"
#include "base/time/default_tick_clock.h"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/page/page.h"
+#include "third_party/blink/renderer/core/testing/scoped_mock_overlay_scrollbars.h"
#include "third_party/blink/renderer/platform/geometry/int_size.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -84,6 +86,11 @@ class DummyPageHolder {
private:
Persistent<Page> page_;
+ // Unit tests need to run with a mock theme enabled. This is necessitated
+ // particularly by Android on which unit tests run without a platform theme
+ // engine.
+ ScopedMockOverlayScrollbars enable_mock_scrollbars_;
+
// The LocalFrame is accessed from worker threads by unit tests
// (ThreadableLoaderTest), hence we need to allow cross-thread
// usage of |m_frame|.
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 8a48f10d5cb..45b6becfab6 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
@@ -6,6 +6,7 @@
#include "skia/public/mojom/skcolor.mojom-blink.h"
#include "third_party/blink/public/mojom/frame/fullscreen.mojom-blink.h"
+#include "third_party/blink/public/mojom/timing/resource_timing.mojom-blink.h"
namespace blink {
@@ -17,7 +18,10 @@ void FakeLocalFrameHost::Init(blink::AssociatedInterfaceProvider* provider) {
}
void FakeLocalFrameHost::EnterFullscreen(
- mojom::blink::FullscreenOptionsPtr options) {}
+ mojom::blink::FullscreenOptionsPtr options,
+ EnterFullscreenCallback callback) {
+ std::move(callback).Run(true);
+}
void FakeLocalFrameHost::ExitFullscreen() {}
@@ -34,8 +38,13 @@ void FakeLocalFrameHost::UnregisterProtocolHandler(const WTF::String& scheme,
void FakeLocalFrameHost::DidDisplayInsecureContent() {}
+void FakeLocalFrameHost::DidAddContentSecurityPolicies(
+ WTF::Vector<::network::mojom::blink::ContentSecurityPolicyPtr>) {}
void FakeLocalFrameHost::DidContainInsecureFormAction() {}
+void FakeLocalFrameHost::DocumentAvailableInMainFrame(
+ bool uses_temporary_zoom_level) {}
+
void FakeLocalFrameHost::SetNeedsOcclusionTracking(bool needs_tracking) {}
void FakeLocalFrameHost::LifecycleStateChanged(
@@ -49,9 +58,13 @@ void FakeLocalFrameHost::VisibilityChanged(
void FakeLocalFrameHost::DidChangeThemeColor(
const base::Optional<::SkColor>& theme_color) {}
+void FakeLocalFrameHost::DidFailLoadWithError(const ::blink::KURL& url,
+ int32_t error_code) {}
+
void FakeLocalFrameHost::DidFocusFrame() {}
-void FakeLocalFrameHost::EnforceInsecureRequestPolicy(uint8_t policy_bitmap) {}
+void FakeLocalFrameHost::EnforceInsecureRequestPolicy(
+ mojom::InsecureRequestPolicy policy_bitmap) {}
void FakeLocalFrameHost::EnforceInsecureNavigationsSet(
const WTF::Vector<uint32_t>& set) {}
@@ -63,6 +76,93 @@ void FakeLocalFrameHost::SuddenTerminationDisablerChanged(
bool present,
blink::mojom::SuddenTerminationDisablerType disabler_type) {}
+void FakeLocalFrameHost::HadStickyUserActivationBeforeNavigationChanged(
+ bool value) {}
+
+void FakeLocalFrameHost::ScrollRectToVisibleInParentFrame(
+ const gfx::Rect& rect_to_scroll,
+ blink::mojom::blink::ScrollIntoViewParamsPtr params) {}
+
+void FakeLocalFrameHost::BubbleLogicalScrollInParentFrame(
+ blink::mojom::blink::ScrollDirection direction,
+ ui::ScrollGranularity granularity) {}
+
+void FakeLocalFrameHost::DidAccessInitialDocument() {}
+
+void FakeLocalFrameHost::DidBlockNavigation(
+ const KURL& blocked_url,
+ const KURL& initiator_url,
+ mojom::NavigationBlockedReason reason) {}
+
+void FakeLocalFrameHost::DidChangeLoadProgress(double load_progress) {}
+
+void FakeLocalFrameHost::DidFinishLoad(const KURL& validated_url) {}
+
+void FakeLocalFrameHost::DispatchLoad() {}
+
+void FakeLocalFrameHost::GoToEntryAtOffset(int32_t offset,
+ bool has_user_gesture) {}
+
+void FakeLocalFrameHost::RenderFallbackContentInParentProcess() {}
+
+void FakeLocalFrameHost::UpdateTitle(
+ const WTF::String& title,
+ mojo_base::mojom::blink::TextDirection title_direction) {}
+
+void FakeLocalFrameHost::UpdateUserActivationState(
+ mojom::blink::UserActivationUpdateType update_type) {}
+
+void FakeLocalFrameHost::HandleAccessibilityFindInPageResult(
+ mojom::blink::FindInPageResultAXParamsPtr params) {}
+
+void FakeLocalFrameHost::HandleAccessibilityFindInPageTermination() {}
+
+void FakeLocalFrameHost::DocumentOnLoadCompleted() {}
+
+void FakeLocalFrameHost::ForwardResourceTimingToParent(
+ mojom::blink::ResourceTimingInfoPtr timing) {}
+
+void FakeLocalFrameHost::DidFinishDocumentLoad() {}
+
+void FakeLocalFrameHost::RunModalAlertDialog(
+ const WTF::String& alert_message,
+ RunModalAlertDialogCallback callback) {
+ std::move(callback).Run();
+}
+
+void FakeLocalFrameHost::RunModalConfirmDialog(
+ const WTF::String& alert_message,
+ RunModalConfirmDialogCallback callback) {
+ std::move(callback).Run(true);
+}
+
+void FakeLocalFrameHost::RunModalPromptDialog(
+ const WTF::String& alert_message,
+ const WTF::String& default_value,
+ RunModalPromptDialogCallback callback) {
+ std::move(callback).Run(true, g_empty_string);
+}
+
+void FakeLocalFrameHost::RunBeforeUnloadConfirm(
+ bool is_reload,
+ RunBeforeUnloadConfirmCallback callback) {
+ 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) {}
+
+void FakeLocalFrameHost::DownloadURL(
+ mojom::blink::DownloadURLParamsPtr params) {}
+
+void FakeLocalFrameHost::FocusedElementChanged(
+ bool is_editable_element,
+ const gfx::Rect& bounds_in_frame_widget) {}
+
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 dd1c3efca0f..350d80505f2 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
@@ -8,7 +8,9 @@
#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/favicon/favicon_url.mojom-blink.h"
#include "third_party/blink/public/mojom/frame/frame.mojom-blink.h"
+#include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink.h"
namespace blink {
@@ -21,7 +23,8 @@ class FakeLocalFrameHost : public mojom::blink::LocalFrameHost {
FakeLocalFrameHost() = default;
void Init(blink::AssociatedInterfaceProvider* provider);
- void EnterFullscreen(mojom::blink::FullscreenOptionsPtr options) override;
+ void EnterFullscreen(mojom::blink::FullscreenOptionsPtr options,
+ EnterFullscreenCallback callback) override;
void ExitFullscreen() override;
void FullscreenStateChanged(bool is_fullscreen) override;
void RegisterProtocolHandler(const WTF::String& scheme,
@@ -32,20 +35,69 @@ class FakeLocalFrameHost : public mojom::blink::LocalFrameHost {
const ::blink::KURL& url,
bool user_gesture) override;
void DidDisplayInsecureContent() override;
+ void DidAddContentSecurityPolicies(
+ WTF::Vector<::network::mojom::blink::ContentSecurityPolicyPtr>) override;
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 EvictFromBackForwardCache() override;
void VisibilityChanged(mojom::blink::FrameVisibility visibility) override;
void DidChangeThemeColor(
const base::Optional<::SkColor>& theme_color) override;
+ void DidFailLoadWithError(const ::blink::KURL& url,
+ int32_t error_code) override;
void DidFocusFrame() override;
- void EnforceInsecureRequestPolicy(uint8_t policy_bitmap) override;
+ void EnforceInsecureRequestPolicy(
+ mojom::InsecureRequestPolicy policy_bitmap) override;
void EnforceInsecureNavigationsSet(const WTF::Vector<uint32_t>& set) override;
void DidChangeActiveSchedulerTrackedFeatures(uint64_t features_mask) override;
void SuddenTerminationDisablerChanged(
bool present,
blink::mojom::SuddenTerminationDisablerType disabler_type) override;
+ void HadStickyUserActivationBeforeNavigationChanged(bool value) override;
+ void ScrollRectToVisibleInParentFrame(
+ const gfx::Rect& rect_to_scroll,
+ blink::mojom::blink::ScrollIntoViewParamsPtr params) override;
+ void BubbleLogicalScrollInParentFrame(
+ blink::mojom::blink::ScrollDirection direction,
+ ui::ScrollGranularity granularity) override;
+ void DidAccessInitialDocument() override;
+ void DidBlockNavigation(const KURL& blocked_url,
+ const KURL& initiator_url,
+ mojom::NavigationBlockedReason reason) override;
+ void DidChangeLoadProgress(double load_progress) override;
+ void DidFinishLoad(const KURL& validated_url) override;
+ 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 UpdateUserActivationState(
+ mojom::blink::UserActivationUpdateType update_type) override;
+ void HandleAccessibilityFindInPageResult(
+ mojom::blink::FindInPageResultAXParamsPtr params) override;
+ void HandleAccessibilityFindInPageTermination() override;
+ void DocumentOnLoadCompleted() override;
+ void ForwardResourceTimingToParent(
+ mojom::blink::ResourceTimingInfoPtr timing) override;
+ void DidFinishDocumentLoad() override;
+ void RunModalAlertDialog(const WTF::String& alert_message,
+ RunModalAlertDialogCallback callback) override;
+ void RunModalConfirmDialog(const WTF::String& alert_message,
+ RunModalConfirmDialogCallback callback) override;
+ void RunModalPromptDialog(const WTF::String& alert_message,
+ const WTF::String& default_value,
+ 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;
+ void FocusedElementChanged(bool is_editable_element,
+ const gfx::Rect& bounds_in_frame_widget) 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 7096fe2849b..aec12d3a732 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
@@ -16,11 +16,23 @@ void FakeRemoteFrameHost::Init(blink::AssociatedInterfaceProvider* provider) {
void FakeRemoteFrameHost::SetInheritedEffectiveTouchAction(
cc::TouchAction touch_action) {}
+void FakeRemoteFrameHost::UpdateRenderThrottlingStatus(bool is_throttled,
+ bool subtree_throttled) {
+}
+
void FakeRemoteFrameHost::VisibilityChanged(
mojom::blink::FrameVisibility visibility) {}
void FakeRemoteFrameHost::DidFocusFrame() {}
+void FakeRemoteFrameHost::CheckCompleted() {}
+
+void FakeRemoteFrameHost::CapturePaintPreviewOfCrossProcessSubframe(
+ const gfx::Rect& clip_rect,
+ const base::UnguessableToken& guid) {}
+
+void FakeRemoteFrameHost::SetIsInert(bool inert) {}
+
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 9cb83cd543b..cf0189c9e78 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
@@ -22,8 +22,15 @@ class FakeRemoteFrameHost : public mojom::blink::RemoteFrameHost {
void Init(blink::AssociatedInterfaceProvider* provider);
void SetInheritedEffectiveTouchAction(cc::TouchAction touch_action) override;
+ void UpdateRenderThrottlingStatus(bool is_throttled,
+ bool subtree_throttled) override;
void VisibilityChanged(mojom::blink::FrameVisibility visibility) override;
void DidFocusFrame() override;
+ void CheckCompleted() override;
+ void CapturePaintPreviewOfCrossProcessSubframe(
+ const gfx::Rect& clip_rect,
+ const base::UnguessableToken& guid) override;
+ void SetIsInert(bool inert) override;
private:
void BindFrameHostReceiver(mojo::ScopedInterfaceEndpointHandle handle);
diff --git a/chromium/third_party/blink/renderer/core/testing/fake_web_plugin.h b/chromium/third_party/blink/renderer/core/testing/fake_web_plugin.h
index 9866bd5ab1c..08042bf5c45 100644
--- a/chromium/third_party/blink/renderer/core/testing/fake_web_plugin.h
+++ b/chromium/third_party/blink/renderer/core/testing/fake_web_plugin.h
@@ -31,6 +31,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_FAKE_WEB_PLUGIN_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_FAKE_WEB_PLUGIN_H_
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
#include "third_party/blink/public/web/web_plugin.h"
namespace cc {
@@ -53,23 +54,23 @@ class FakeWebPlugin : public WebPlugin {
bool Initialize(WebPluginContainer*) override;
void Destroy() override;
bool CanProcessDrag() const override { return false; }
- void UpdateAllLifecyclePhases(WebWidget::LifecycleUpdateReason) override {}
+ void UpdateAllLifecyclePhases(blink::DocumentUpdateReason) override {}
void Paint(cc::PaintCanvas*, const WebRect&) override {}
void UpdateGeometry(const WebRect& client_rect,
const WebRect& clip_rect,
const WebRect& window_clip_rect,
bool is_visible) override {}
- void UpdateFocus(bool, WebFocusType) override {}
+ void UpdateFocus(bool, mojom::blink::FocusType) override {}
void UpdateVisibility(bool) override {}
WebInputEventResult HandleInputEvent(const WebCoalescedInputEvent&,
- WebCursorInfo&) override {
+ ui::Cursor*) override {
return WebInputEventResult::kNotHandled;
}
bool HandleDragStatusUpdate(WebDragStatus,
const WebDragData&,
WebDragOperationsMask,
- const WebFloatPoint& position,
- const WebFloatPoint& screen_position) override {
+ const gfx::PointF& position,
+ const gfx::PointF& screen_position) override {
return false;
}
void DidReceiveResponse(const WebURLResponse&) override {}
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 e0780895080..88b85fcf25f 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 a67ab6917e1..8e94a1d49e2 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(blink::Visitor* visitor) {
+void HitTestLayerRectList::Trace(Visitor* visitor) {
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 ae53932951a..d5f2ef265be 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
HeapVector<Member<HitTestLayerRect>> list_;
diff --git a/chromium/third_party/blink/renderer/core/testing/internal_dictionary.idl b/chromium/third_party/blink/renderer/core/testing/internal_dictionary.idl
index 6a87abda00d..34878f2a21e 100644
--- a/chromium/third_party/blink/renderer/core/testing/internal_dictionary.idl
+++ b/chromium/third_party/blink/renderer/core/testing/internal_dictionary.idl
@@ -8,8 +8,6 @@ dictionary InternalDictionary {
long longMember;
[Clamp] long longMemberWithClamp;
[EnforceRange] long longMemberWithEnforceRange;
- // We don't want to add a UseCounter feature for testing, so using PrefixedStorageInfo.
- [DeprecateAs=PrefixedStorageInfo, ImplementedAs=longMember] long deprecateLongMember;
long longMemberWithDefault = 42;
long? longOrNullMember;
long? longOrNullMemberWithDefault = null;
@@ -33,7 +31,6 @@ dictionary InternalDictionary {
(double or DOMString) doubleOrStringMember;
sequence<(double or DOMString)> doubleOrStringSequenceMember;
EventTarget? eventTargetOrNullMember = null;
- Dictionary dictionaryMember;
(InternalEnum or sequence<InternalEnum>) internalEnumOrInternalEnumSequenceMember;
any anyMember;
TestCallback callbackFunctionMember;
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 2363d2b0bbf..65ed71e7d7c 100644
--- a/chromium/third_party/blink/renderer/core/testing/internal_settings.cc
+++ b/chromium/third_party/blink/renderer/core/testing/internal_settings.cc
@@ -166,11 +166,11 @@ void InternalSettings::setViewportMetaEnabled(bool enabled,
void InternalSettings::setViewportStyle(const String& style,
ExceptionState& exception_state) {
InternalSettingsGuardForSettings();
- if (DeprecatedEqualIgnoringCase(style, "default"))
+ if (EqualIgnoringASCIICase(style, "default"))
GetSettings()->SetViewportStyle(WebViewportStyle::kDefault);
- else if (DeprecatedEqualIgnoringCase(style, "mobile"))
+ else if (EqualIgnoringASCIICase(style, "mobile"))
GetSettings()->SetViewportStyle(WebViewportStyle::kMobile);
- else if (DeprecatedEqualIgnoringCase(style, "television"))
+ else if (EqualIgnoringASCIICase(style, "television"))
GetSettings()->SetViewportStyle(WebViewportStyle::kTelevision);
else
exception_state.ThrowDOMException(
@@ -314,13 +314,13 @@ void InternalSettings::setAccessibilityFontScaleFactor(
void InternalSettings::setEditingBehavior(const String& editing_behavior,
ExceptionState& exception_state) {
InternalSettingsGuardForSettings();
- if (DeprecatedEqualIgnoringCase(editing_behavior, "win"))
+ if (EqualIgnoringASCIICase(editing_behavior, "win"))
GetSettings()->SetEditingBehaviorType(kEditingWindowsBehavior);
- else if (DeprecatedEqualIgnoringCase(editing_behavior, "mac"))
+ else if (EqualIgnoringASCIICase(editing_behavior, "mac"))
GetSettings()->SetEditingBehaviorType(kEditingMacBehavior);
- else if (DeprecatedEqualIgnoringCase(editing_behavior, "unix"))
+ else if (EqualIgnoringASCIICase(editing_behavior, "unix"))
GetSettings()->SetEditingBehaviorType(kEditingUnixBehavior);
- else if (DeprecatedEqualIgnoringCase(editing_behavior, "android"))
+ else if (EqualIgnoringASCIICase(editing_behavior, "android"))
GetSettings()->SetEditingBehaviorType(kEditingAndroidBehavior);
else
exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
@@ -345,7 +345,7 @@ void InternalSettings::setDefaultVideoPosterURL(
GetSettings()->SetDefaultVideoPosterURL(url);
}
-void InternalSettings::Trace(blink::Visitor* visitor) {
+void InternalSettings::Trace(Visitor* visitor) {
InternalSettingsGenerated::Trace(visitor);
Supplement<Page>::Trace(visitor);
}
@@ -478,11 +478,11 @@ void InternalSettings::setImageAnimationPolicy(
const String& policy,
ExceptionState& exception_state) {
InternalSettingsGuardForSettings();
- if (DeprecatedEqualIgnoringCase(policy, "allowed")) {
+ if (EqualIgnoringASCIICase(policy, "allowed")) {
GetSettings()->SetImageAnimationPolicy(kImageAnimationPolicyAllowed);
- } else if (DeprecatedEqualIgnoringCase(policy, "once")) {
+ } else if (EqualIgnoringASCIICase(policy, "once")) {
GetSettings()->SetImageAnimationPolicy(kImageAnimationPolicyAnimateOnce);
- } else if (DeprecatedEqualIgnoringCase(policy, "none")) {
+ } else if (EqualIgnoringASCIICase(policy, "none")) {
GetSettings()->SetImageAnimationPolicy(kImageAnimationPolicyNoAnimation);
} else {
exception_state.ThrowDOMException(
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 1c289ab7e30..a89f2c3da96 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 7570b3a32be..01b71d85969 100644
--- a/chromium/third_party/blink/renderer/core/testing/internals.cc
+++ b/chromium/third_party/blink/renderer/core/testing/internals.cc
@@ -32,6 +32,9 @@
#include "base/optional.h"
#include "cc/layers/picture_layer.h"
#include "gpu/command_buffer/client/gles2_interface.h"
+#include "third_party/blink/public/mojom/devtools/inspector_issue.mojom-blink.h"
+#include "third_party/blink/public/mojom/favicon/favicon_url.mojom-blink.h"
+#include "third_party/blink/public/mojom/input/focus_type.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/public/web/web_device_emulation_params.h"
@@ -83,7 +86,10 @@
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/performance_monitor.h"
#include "third_party/blink/renderer/core/frame/remote_dom_window.h"
+#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/settings.h"
+#include "third_party/blink/renderer/core/frame/test_report_body.h"
#include "third_party/blink/renderer/core/frame/visual_viewport.h"
#include "third_party/blink/renderer/core/geometry/dom_point.h"
#include "third_party/blink/renderer/core/geometry/dom_rect.h"
@@ -106,9 +112,9 @@
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/input/keyboard_event_manager.h"
+#include "third_party/blink/renderer/core/inspector/inspector_issue.h"
#include "third_party/blink/renderer/core/inspector/main_thread_debugger.h"
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer.h"
-#include "third_party/blink/renderer/core/layout/layout_menu_list.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/layout_tree_as_text.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
@@ -154,12 +160,12 @@
#include "third_party/blink/renderer/core/testing/static_selection.h"
#include "third_party/blink/renderer/core/testing/type_conversions.h"
#include "third_party/blink/renderer/core/testing/union_types_test.h"
+#include "third_party/blink/renderer/core/timezone/timezone_controller.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/core/workers/worker_thread.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_throw_exception.h"
-#include "third_party/blink/renderer/platform/cursor.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
#include "third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h"
@@ -182,11 +188,15 @@
#include "third_party/blink/renderer/platform/wtf/dtoa.h"
#include "third_party/blink/renderer/platform/wtf/text/string_buffer.h"
#include "third_party/blink/renderer/platform/wtf/text/text_encoding_registry.h"
+#include "ui/base/cursor/cursor.h"
+#include "ui/base/mojom/cursor_type.mojom-blink.h"
+#include "ui/base/ui_base_features.h"
#include "v8/include/v8.h"
namespace blink {
using ui::mojom::ImeTextSpanThickness;
+using ui::mojom::ImeTextSpanUnderlineStyle;
namespace {
@@ -203,7 +213,7 @@ class UseCounterHelperObserverImpl final : public UseCounterHelper::Observer {
return true;
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
UseCounterHelper::Observer::Trace(visitor);
visitor->Trace(resolver_);
}
@@ -218,24 +228,24 @@ class UseCounterHelperObserverImpl final : public UseCounterHelper::Observer {
static base::Optional<DocumentMarker::MarkerType> MarkerTypeFrom(
const String& marker_type) {
- if (DeprecatedEqualIgnoringCase(marker_type, "Spelling"))
+ if (EqualIgnoringASCIICase(marker_type, "Spelling"))
return DocumentMarker::kSpelling;
- if (DeprecatedEqualIgnoringCase(marker_type, "Grammar"))
+ if (EqualIgnoringASCIICase(marker_type, "Grammar"))
return DocumentMarker::kGrammar;
- if (DeprecatedEqualIgnoringCase(marker_type, "TextMatch"))
+ if (EqualIgnoringASCIICase(marker_type, "TextMatch"))
return DocumentMarker::kTextMatch;
- if (DeprecatedEqualIgnoringCase(marker_type, "Composition"))
+ if (EqualIgnoringASCIICase(marker_type, "Composition"))
return DocumentMarker::kComposition;
- if (DeprecatedEqualIgnoringCase(marker_type, "ActiveSuggestion"))
+ if (EqualIgnoringASCIICase(marker_type, "ActiveSuggestion"))
return DocumentMarker::kActiveSuggestion;
- if (DeprecatedEqualIgnoringCase(marker_type, "Suggestion"))
+ if (EqualIgnoringASCIICase(marker_type, "Suggestion"))
return DocumentMarker::kSuggestion;
return base::nullopt;
}
static base::Optional<DocumentMarker::MarkerTypes> MarkerTypesFrom(
const String& marker_type) {
- if (marker_type.IsEmpty() || DeprecatedEqualIgnoringCase(marker_type, "all"))
+ if (marker_type.IsEmpty() || EqualIgnoringASCIICase(marker_type, "all"))
return DocumentMarker::MarkerTypes::All();
base::Optional<DocumentMarker::MarkerType> type = MarkerTypeFrom(marker_type);
if (!type)
@@ -287,8 +297,8 @@ void Internals::ResetToConsistentState(Page* page) {
}
LocalFrame* frame = page->DeprecatedLocalMainFrame();
- frame->View()->LayoutViewport()->SetScrollOffset(ScrollOffset(),
- kProgrammaticScroll);
+ frame->View()->LayoutViewport()->SetScrollOffset(
+ ScrollOffset(), mojom::blink::ScrollType::kProgrammatic);
OverrideUserPreferredLanguagesForTesting(Vector<AtomicString>());
if (page->DeprecatedLocalMainFrame()->GetEditor().IsOverwriteModeEnabled())
page->DeprecatedLocalMainFrame()->GetEditor().ToggleOverwriteModeEnabled();
@@ -307,7 +317,7 @@ void Internals::ResetToConsistentState(Page* page) {
Internals::Internals(ExecutionContext* context)
: runtime_flags_(InternalRuntimeFlags::create()),
- document_(To<Document>(context)) {
+ document_(To<LocalDOMWindow>(context)->document()) {
document_->Fetcher()->EnableIsPreloadedForTest();
}
@@ -334,6 +344,10 @@ unsigned Internals::workerThreadCount() const {
return WorkerThread::WorkerThreadCount();
}
+bool Internals::isFormControlsRefreshEnabled() const {
+ return ::features::IsFormControlsRefreshEnabled();
+}
+
GCObservation* Internals::observeGC(ScriptValue script_value) {
v8::Local<v8::Value> observed_value = script_value.V8Value();
DCHECK(!observed_value.IsEmpty());
@@ -588,8 +602,7 @@ void Internals::pauseAnimations(double pause_time,
if (!GetFrame())
return;
- GetFrame()->View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetFrame()->View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
GetFrame()->GetDocument()->Timeline().PauseAnimationsForTesting(pause_time);
}
@@ -601,10 +614,6 @@ void Internals::disableCompositedAnimation(Animation* animation) {
animation->DisableCompositedAnimationForTesting();
}
-void Internals::disableCSSAdditiveAnimations() {
- RuntimeEnabledFeatures::SetCSSAdditiveAnimationsEnabled(false);
-}
-
void Internals::advanceImageAnimation(Element* image,
ExceptionState& exception_state) {
DCHECK(image);
@@ -730,7 +739,7 @@ String Internals::elementLayoutTreeAsText(Element* element,
ExceptionState& exception_state) {
DCHECK(element);
element->GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
String representation = ExternalRepresentation(element);
if (representation.IsEmpty()) {
@@ -846,7 +855,7 @@ void Internals::selectColorInColorChooser(Element* element,
void Internals::endColorChooser(Element* element) {
DCHECK(element);
if (auto* input = DynamicTo<HTMLInputElement>(*element))
- input->EndColorChooser();
+ input->EndColorChooserForTesting();
}
bool Internals::hasAutofocusRequest(Document* document) {
@@ -906,7 +915,7 @@ DOMRectReadOnly* Internals::absoluteCaretBounds(
return nullptr;
}
- document_->UpdateStyleAndLayout();
+ document_->UpdateStyleAndLayout(DocumentUpdateReason::kTest);
return DOMRectReadOnly::FromIntRect(
GetFrame()->Selection().AbsoluteCaretBounds());
}
@@ -927,7 +936,7 @@ String Internals::textAffinity() {
DOMRectReadOnly* Internals::boundingBox(Element* element) {
DCHECK(element);
- element->GetDocument().UpdateStyleAndLayout();
+ element->GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
LayoutObject* layout_object = element->GetLayoutObject();
if (!layout_object)
return DOMRectReadOnly::Create(0, 0, 0, 0);
@@ -961,7 +970,7 @@ void Internals::setMarker(Document* document,
return;
}
- document->UpdateStyleAndLayout();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kTest);
if (type == DocumentMarker::kSpelling)
document->Markers().AddSpellingMarker(EphemeralRange(range));
else
@@ -1096,7 +1105,7 @@ void Internals::addTextMatchMarker(const Range* range,
return;
}
- range->OwnerDocument().UpdateStyleAndLayout();
+ range->OwnerDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
range->OwnerDocument().Markers().AddTextMatchMarker(
EphemeralRange(range), match_status_enum.value());
@@ -1128,19 +1137,38 @@ static base::Optional<ImeTextSpanThickness> ThicknessFrom(
return base::nullopt;
}
+static base::Optional<ImeTextSpanUnderlineStyle> UnderlineStyleFrom(
+ const String& underline_style) {
+ if (EqualIgnoringASCIICase(underline_style, "none"))
+ return ImeTextSpanUnderlineStyle::kNone;
+ if (EqualIgnoringASCIICase(underline_style, "solid"))
+ return ImeTextSpanUnderlineStyle::kSolid;
+ if (EqualIgnoringASCIICase(underline_style, "dot"))
+ return ImeTextSpanUnderlineStyle::kDot;
+ if (EqualIgnoringASCIICase(underline_style, "dash"))
+ return ImeTextSpanUnderlineStyle::kDash;
+ if (EqualIgnoringASCIICase(underline_style, "squiggle"))
+ return ImeTextSpanUnderlineStyle::kSquiggle;
+ return base::nullopt;
+}
+
namespace {
-void addStyleableMarkerHelper(
- const Range* range,
- const String& underline_color_value,
- const String& thickness_value,
- const String& background_color_value,
- ExceptionState& exception_state,
- std::function<
- void(const EphemeralRange&, Color, ImeTextSpanThickness, Color)>
- create_marker) {
+void addStyleableMarkerHelper(const Range* range,
+ const String& underline_color_value,
+ const String& thickness_value,
+ const String& underline_style_value,
+ const String& text_color_value,
+ const String& background_color_value,
+ ExceptionState& exception_state,
+ std::function<void(const EphemeralRange&,
+ Color,
+ ImeTextSpanThickness,
+ ImeTextSpanUnderlineStyle,
+ Color,
+ Color)> create_marker) {
DCHECK(range);
- range->OwnerDocument().UpdateStyleAndLayout();
+ range->OwnerDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
base::Optional<ImeTextSpanThickness> thickness =
ThicknessFrom(thickness_value);
@@ -1151,14 +1179,27 @@ void addStyleableMarkerHelper(
return;
}
+ base::Optional<ImeTextSpanUnderlineStyle> underline_style =
+ UnderlineStyleFrom(underline_style_value);
+ if (!underline_style_value) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
+ "The underline style provided ('" +
+ underline_style_value +
+ "') is invalid.");
+ return;
+ }
+
Color underline_color;
Color background_color;
+ Color text_color;
if (ParseColor(underline_color_value, underline_color, exception_state,
"Invalid underline color.") &&
+ ParseColor(text_color_value, text_color, exception_state,
+ "Invalid text color.") &&
ParseColor(background_color_value, background_color, exception_state,
"Invalid background color.")) {
create_marker(EphemeralRange(range), underline_color, thickness.value(),
- background_color);
+ underline_style.value(), text_color, background_color);
}
}
@@ -1167,18 +1208,23 @@ void addStyleableMarkerHelper(
void Internals::addCompositionMarker(const Range* range,
const String& underline_color_value,
const String& thickness_value,
+ const String& underline_style_value,
+ const String& text_color_value,
const String& background_color_value,
ExceptionState& exception_state) {
DocumentMarkerController& document_marker_controller =
range->OwnerDocument().Markers();
addStyleableMarkerHelper(
- range, underline_color_value, thickness_value, background_color_value,
- exception_state,
- [&document_marker_controller](
- const EphemeralRange& range, Color underline_color,
- ImeTextSpanThickness thickness, Color background_color) {
+ range, underline_color_value, thickness_value, underline_style_value,
+ text_color_value, background_color_value, exception_state,
+ [&document_marker_controller](const EphemeralRange& range,
+ Color underline_color,
+ ImeTextSpanThickness thickness,
+ ImeTextSpanUnderlineStyle underline_style,
+ Color text_color, Color background_color) {
document_marker_controller.AddCompositionMarker(
- range, underline_color, thickness, background_color);
+ range, underline_color, thickness, underline_style, text_color,
+ background_color);
});
}
@@ -1187,16 +1233,23 @@ void Internals::addActiveSuggestionMarker(const Range* range,
const String& thickness_value,
const String& background_color_value,
ExceptionState& exception_state) {
+ // Underline style and text color aren't really supported for suggestions so
+ // providing default values for now.
+ String underline_style_value = "solid";
+ String text_color_value = "transparent";
DocumentMarkerController& document_marker_controller =
range->OwnerDocument().Markers();
addStyleableMarkerHelper(
- range, underline_color_value, thickness_value, background_color_value,
- exception_state,
- [&document_marker_controller](
- const EphemeralRange& range, Color underline_color,
- ImeTextSpanThickness thickness, Color background_color) {
+ range, underline_color_value, thickness_value, underline_style_value,
+ text_color_value, background_color_value, exception_state,
+ [&document_marker_controller](const EphemeralRange& range,
+ Color underline_color,
+ ImeTextSpanThickness thickness,
+ ImeTextSpanUnderlineStyle underline_style,
+ Color text_color, Color background_color) {
document_marker_controller.AddActiveSuggestionMarker(
- range, underline_color, thickness, background_color);
+ range, underline_color, thickness, underline_style, text_color,
+ background_color);
});
}
@@ -1208,6 +1261,10 @@ void Internals::addSuggestionMarker(
const String& thickness_value,
const String& background_color_value,
ExceptionState& exception_state) {
+ // Underline style and text color aren't really supported for suggestions so
+ // providing default values for now.
+ String underline_style_value = "solid";
+ String text_color_value = "transparent";
Color suggestion_highlight_color;
if (!ParseColor(suggestion_highlight_color_value, suggestion_highlight_color,
exception_state, "Invalid suggestion highlight color."))
@@ -1216,11 +1273,13 @@ void Internals::addSuggestionMarker(
DocumentMarkerController& document_marker_controller =
range->OwnerDocument().Markers();
addStyleableMarkerHelper(
- range, underline_color_value, thickness_value, background_color_value,
- exception_state,
+ range, underline_color_value, thickness_value, underline_style_value,
+ text_color_value, background_color_value, exception_state,
[&document_marker_controller, &suggestions, &suggestion_highlight_color](
const EphemeralRange& range, Color underline_color,
- ImeTextSpanThickness thickness, Color background_color) {
+ ImeTextSpanThickness thickness,
+ ImeTextSpanUnderlineStyle underline_style, Color text_color,
+ Color background_color) {
document_marker_controller.AddSuggestionMarker(
range,
SuggestionMarkerProperties::Builder()
@@ -1229,6 +1288,8 @@ void Internals::addSuggestionMarker(
.SetHighlightColor(suggestion_highlight_color)
.SetUnderlineColor(underline_color)
.SetThickness(thickness)
+ .SetUnderlineStyle(underline_style)
+ .SetTextColor(text_color)
.SetBackgroundColor(background_color)
.Build());
});
@@ -1264,7 +1325,7 @@ String Internals::viewportAsText(Document* document,
return String();
}
- document->UpdateStyleAndLayout();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kTest);
Page* page = document->GetPage();
@@ -1424,7 +1485,7 @@ Range* Internals::rangeFromLocationAndLength(Element* scope,
DCHECK(scope);
// TextIterator depends on Layout information, make sure layout it up to date.
- scope->GetDocument().UpdateStyleAndLayout();
+ scope->GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
return CreateRange(
PlainTextRange(range_location, range_location + range_length)
@@ -1435,7 +1496,7 @@ unsigned Internals::locationFromRange(Element* scope, const Range* range) {
DCHECK(scope && range);
// PlainTextRange depends on Layout information, make sure layout it up to
// date.
- scope->GetDocument().UpdateStyleAndLayout();
+ scope->GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
return PlainTextRange::Create(*scope, *range).Start();
}
@@ -1444,7 +1505,7 @@ unsigned Internals::lengthFromRange(Element* scope, const Range* range) {
DCHECK(scope && range);
// PlainTextRange depends on Layout information, make sure layout it up to
// date.
- scope->GetDocument().UpdateStyleAndLayout();
+ scope->GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
return PlainTextRange::Create(*scope, *range).length();
}
@@ -1452,7 +1513,7 @@ unsigned Internals::lengthFromRange(Element* scope, const Range* range) {
String Internals::rangeAsText(const Range* range) {
DCHECK(range);
// Clean layout is required by plain text extraction.
- range->OwnerDocument().UpdateStyleAndLayout();
+ range->OwnerDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest);
return range->GetText();
}
@@ -1467,7 +1528,7 @@ void Internals::HitTestRect(HitTestLocation& location,
int width,
int height,
Document* document) {
- document->UpdateStyleAndLayout();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kTest);
EventHandler& event_handler = document->GetFrame()->GetEventHandler();
PhysicalRect rect{LayoutUnit(x), LayoutUnit(y), LayoutUnit(width),
LayoutUnit(height)};
@@ -1681,6 +1742,10 @@ void Internals::setUserPreferredLanguages(const Vector<String>& languages) {
OverrideUserPreferredLanguagesForTesting(atomic_languages);
}
+void Internals::setSystemTimeZone(const String& timezone) {
+ blink::TimeZoneController::ChangeTimeZoneForTesting(timezone);
+}
+
unsigned Internals::mediaKeysCount() {
return InstanceCounters::CounterValue(InstanceCounters::kMediaKeysCounter);
}
@@ -1690,12 +1755,6 @@ unsigned Internals::mediaKeySessionCount() {
InstanceCounters::kMediaKeySessionCounter);
}
-unsigned Internals::contextLifecycleStateObserverObjectCount(
- Document* document) {
- DCHECK(document);
- return document->ContextLifecycleStateObserverCount();
-}
-
static unsigned EventHandlerCount(
Document& document,
EventHandlerRegistry::EventHandlerClass handler_class) {
@@ -1838,8 +1897,7 @@ HitTestLayerRectList* Internals::touchEventTargetLayerRects(
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
auto* pac = document->View()->GetPaintArtifactCompositor();
- document->View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ document->View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
auto* hit_test_rects = MakeGarbageCollected<HitTestLayerRectList>();
for (const auto& layer : pac->RootLayer()->children()) {
@@ -1908,6 +1966,15 @@ bool Internals::executeCommand(Document* document,
return frame->GetEditor().ExecuteCommand(name, value);
}
+void Internals::triggerTestInspectorIssue(Document* document) {
+ DCHECK(document);
+ auto info = mojom::blink::InspectorIssueInfo::New(
+ mojom::InspectorIssueCode::kSameSiteCookieIssue,
+ mojom::blink::InspectorIssueDetails::New(),
+ mojom::blink::AffectedResources::New());
+ document->AddInspectorIssue(InspectorIssue::Create(std::move(info)));
+}
+
AtomicString Internals::htmlNamespace() {
return html_names::xhtmlNamespaceURI;
}
@@ -1987,7 +2054,7 @@ bool Internals::hasSpellingMarker(Document* document,
return false;
}
- document->UpdateStyleAndLayout();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kTest);
return document->GetFrame()->GetSpellChecker().SelectionStartHasMarkerFor(
DocumentMarker::kSpelling, from, length);
}
@@ -2002,7 +2069,7 @@ void Internals::replaceMisspelled(Document* document,
return;
}
- document->UpdateStyleAndLayout();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kTest);
document->GetFrame()->GetSpellChecker().ReplaceMisspelledRange(replacement);
}
@@ -2051,7 +2118,7 @@ bool Internals::hasGrammarMarker(Document* document,
return false;
}
- document->UpdateStyleAndLayout();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kTest);
return document->GetFrame()->GetSpellChecker().SelectionStartHasMarkerFor(
DocumentMarker::kGrammar, from, length);
}
@@ -2101,7 +2168,7 @@ bool Internals::scrollsWithRespectTo(Element* element1,
ExceptionState& exception_state) {
DCHECK(element1 && element2);
element1->GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
LayoutObject* layout_object1 = element1->GetLayoutObject();
LayoutObject* layout_object2 = element2->GetLayoutObject();
@@ -2146,8 +2213,7 @@ String Internals::layerTreeAsText(Document* document,
return String();
}
- document->View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ document->View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
return document->GetFrame()->GetLayerTreeAsTextForTesting(flags);
}
@@ -2167,7 +2233,7 @@ String Internals::mainThreadScrollingReasons(
}
document->GetFrame()->View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
return document->GetFrame()->View()->MainThreadScrollingReasonsAsText();
}
@@ -2197,8 +2263,7 @@ DOMRectList* Internals::nonFastScrollableRects(
// ScrollingCoordinator::UpdateAfterPaint, which computes the non-fast
// scrollable region. For CompositeAfterPaint, this includes running
// PaintArtifactCompositor which updates the non-fast regions.
- frame->View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ frame->View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
auto* pac = document->View()->GetPaintArtifactCompositor();
auto* layer_tree_host = pac->RootLayer()->layer_tree_host();
@@ -2225,7 +2290,7 @@ DOMRectList* Internals::nonFastScrollableRects(
}
}
- return DOMRectList::Create(layer_non_fast_scrollable_rects);
+ return MakeGarbageCollected<DOMRectList>(layer_non_fast_scrollable_rects);
}
void Internals::evictAllResources() const {
@@ -2268,11 +2333,18 @@ Vector<String> Internals::IconURLs(Document* document,
}
Vector<String> Internals::shortcutIconURLs(Document* document) const {
- return IconURLs(document, kFavicon);
+ int icon_types_mask =
+ 1 << static_cast<int>(mojom::blink::FaviconIconType::kFavicon);
+ return IconURLs(document, icon_types_mask);
}
Vector<String> Internals::allIconURLs(Document* document) const {
- return IconURLs(document, kFavicon | kTouchIcon | kTouchPrecomposedIcon);
+ int icon_types_mask =
+ 1 << static_cast<int>(mojom::blink::FaviconIconType::kFavicon) |
+ 1 << static_cast<int>(mojom::blink::FaviconIconType::kTouchIcon) |
+ 1 << static_cast<int>(
+ mojom::blink::FaviconIconType::kTouchPrecomposedIcon);
+ return IconURLs(document, icon_types_mask);
}
int Internals::numberOfPages(float page_width,
@@ -2510,8 +2582,7 @@ void Internals::startTrackingRepaints(Document* document,
}
LocalFrameView* frame_view = document->View();
- frame_view->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ frame_view->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
frame_view->SetTracksRasterInvalidations(true);
}
@@ -2525,8 +2596,7 @@ void Internals::stopTrackingRepaints(Document* document,
}
LocalFrameView* frame_view = document->View();
- frame_view->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ frame_view->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
frame_view->SetTracksRasterInvalidations(false);
}
@@ -2547,7 +2617,7 @@ void Internals::updateLayoutAndRunPostLayoutTasks(
"The node provided is neither a document nor an IFrame.");
return;
}
- document->UpdateStyleAndLayout();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kTest);
if (auto* view = document->View())
view->FlushAnyPendingPostLayoutTasks();
}
@@ -2583,10 +2653,10 @@ DOMRectList* Internals::AnnotatedRegions(Document* document,
if (!document->View()) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidAccessError,
"The document provided is invalid.");
- return DOMRectList::Create();
+ return MakeGarbageCollected<DOMRectList>();
}
- document->UpdateStyleAndLayout();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kTest);
document->View()->UpdateDocumentAnnotatedRegions();
Vector<AnnotatedRegionValue> regions = document->AnnotatedRegions();
@@ -2595,112 +2665,113 @@ DOMRectList* Internals::AnnotatedRegions(Document* document,
if (region.draggable == draggable)
quads.push_back(FloatQuad(FloatRect(region.bounds)));
}
- return DOMRectList::Create(quads);
+ return MakeGarbageCollected<DOMRectList>(quads);
}
-static const char* CursorTypeToString(ui::CursorType cursor_type) {
+static const char* CursorTypeToString(
+ ui::mojom::blink::CursorType cursor_type) {
switch (cursor_type) {
- case ui::CursorType::kPointer:
+ case ui::mojom::blink::CursorType::kPointer:
return "Pointer";
- case ui::CursorType::kCross:
+ case ui::mojom::blink::CursorType::kCross:
return "Cross";
- case ui::CursorType::kHand:
+ case ui::mojom::blink::CursorType::kHand:
return "Hand";
- case ui::CursorType::kIBeam:
+ case ui::mojom::blink::CursorType::kIBeam:
return "IBeam";
- case ui::CursorType::kWait:
+ case ui::mojom::blink::CursorType::kWait:
return "Wait";
- case ui::CursorType::kHelp:
+ case ui::mojom::blink::CursorType::kHelp:
return "Help";
- case ui::CursorType::kEastResize:
+ case ui::mojom::blink::CursorType::kEastResize:
return "EastResize";
- case ui::CursorType::kNorthResize:
+ case ui::mojom::blink::CursorType::kNorthResize:
return "NorthResize";
- case ui::CursorType::kNorthEastResize:
+ case ui::mojom::blink::CursorType::kNorthEastResize:
return "NorthEastResize";
- case ui::CursorType::kNorthWestResize:
+ case ui::mojom::blink::CursorType::kNorthWestResize:
return "NorthWestResize";
- case ui::CursorType::kSouthResize:
+ case ui::mojom::blink::CursorType::kSouthResize:
return "SouthResize";
- case ui::CursorType::kSouthEastResize:
+ case ui::mojom::blink::CursorType::kSouthEastResize:
return "SouthEastResize";
- case ui::CursorType::kSouthWestResize:
+ case ui::mojom::blink::CursorType::kSouthWestResize:
return "SouthWestResize";
- case ui::CursorType::kWestResize:
+ case ui::mojom::blink::CursorType::kWestResize:
return "WestResize";
- case ui::CursorType::kNorthSouthResize:
+ case ui::mojom::blink::CursorType::kNorthSouthResize:
return "NorthSouthResize";
- case ui::CursorType::kEastWestResize:
+ case ui::mojom::blink::CursorType::kEastWestResize:
return "EastWestResize";
- case ui::CursorType::kNorthEastSouthWestResize:
+ case ui::mojom::blink::CursorType::kNorthEastSouthWestResize:
return "NorthEastSouthWestResize";
- case ui::CursorType::kNorthWestSouthEastResize:
+ case ui::mojom::blink::CursorType::kNorthWestSouthEastResize:
return "NorthWestSouthEastResize";
- case ui::CursorType::kColumnResize:
+ case ui::mojom::blink::CursorType::kColumnResize:
return "ColumnResize";
- case ui::CursorType::kRowResize:
+ case ui::mojom::blink::CursorType::kRowResize:
return "RowResize";
- case ui::CursorType::kMiddlePanning:
+ case ui::mojom::blink::CursorType::kMiddlePanning:
return "MiddlePanning";
- case ui::CursorType::kMiddlePanningVertical:
+ case ui::mojom::blink::CursorType::kMiddlePanningVertical:
return "MiddlePanningVertical";
- case ui::CursorType::kMiddlePanningHorizontal:
+ case ui::mojom::blink::CursorType::kMiddlePanningHorizontal:
return "MiddlePanningHorizontal";
- case ui::CursorType::kEastPanning:
+ case ui::mojom::blink::CursorType::kEastPanning:
return "EastPanning";
- case ui::CursorType::kNorthPanning:
+ case ui::mojom::blink::CursorType::kNorthPanning:
return "NorthPanning";
- case ui::CursorType::kNorthEastPanning:
+ case ui::mojom::blink::CursorType::kNorthEastPanning:
return "NorthEastPanning";
- case ui::CursorType::kNorthWestPanning:
+ case ui::mojom::blink::CursorType::kNorthWestPanning:
return "NorthWestPanning";
- case ui::CursorType::kSouthPanning:
+ case ui::mojom::blink::CursorType::kSouthPanning:
return "SouthPanning";
- case ui::CursorType::kSouthEastPanning:
+ case ui::mojom::blink::CursorType::kSouthEastPanning:
return "SouthEastPanning";
- case ui::CursorType::kSouthWestPanning:
+ case ui::mojom::blink::CursorType::kSouthWestPanning:
return "SouthWestPanning";
- case ui::CursorType::kWestPanning:
+ case ui::mojom::blink::CursorType::kWestPanning:
return "WestPanning";
- case ui::CursorType::kMove:
+ case ui::mojom::blink::CursorType::kMove:
return "Move";
- case ui::CursorType::kVerticalText:
+ case ui::mojom::blink::CursorType::kVerticalText:
return "VerticalText";
- case ui::CursorType::kCell:
+ case ui::mojom::blink::CursorType::kCell:
return "Cell";
- case ui::CursorType::kContextMenu:
+ case ui::mojom::blink::CursorType::kContextMenu:
return "ContextMenu";
- case ui::CursorType::kAlias:
+ case ui::mojom::blink::CursorType::kAlias:
return "Alias";
- case ui::CursorType::kProgress:
+ case ui::mojom::blink::CursorType::kProgress:
return "Progress";
- case ui::CursorType::kNoDrop:
+ case ui::mojom::blink::CursorType::kNoDrop:
return "NoDrop";
- case ui::CursorType::kCopy:
+ case ui::mojom::blink::CursorType::kCopy:
return "Copy";
- case ui::CursorType::kNone:
+ case ui::mojom::blink::CursorType::kNone:
return "None";
- case ui::CursorType::kNotAllowed:
+ case ui::mojom::blink::CursorType::kNotAllowed:
return "NotAllowed";
- case ui::CursorType::kZoomIn:
+ case ui::mojom::blink::CursorType::kZoomIn:
return "ZoomIn";
- case ui::CursorType::kZoomOut:
+ case ui::mojom::blink::CursorType::kZoomOut:
return "ZoomOut";
- case ui::CursorType::kGrab:
+ case ui::mojom::blink::CursorType::kGrab:
return "Grab";
- case ui::CursorType::kGrabbing:
+ case ui::mojom::blink::CursorType::kGrabbing:
return "Grabbing";
- case ui::CursorType::kCustom:
+ case ui::mojom::blink::CursorType::kCustom:
return "Custom";
- case ui::CursorType::kNull:
+ case ui::mojom::blink::CursorType::kNull:
return "Null";
- case ui::CursorType::kDndNone:
+ case ui::mojom::blink::CursorType::kDndNone:
return "DragAndDropNone";
- case ui::CursorType::kDndMove:
+ case ui::mojom::blink::CursorType::kDndMove:
return "DragAndDropMove";
- case ui::CursorType::kDndCopy:
+ case ui::mojom::blink::CursorType::kDndCopy:
return "DragAndDropCopy";
- case ui::CursorType::kDndLink:
+ case ui::mojom::blink::CursorType::kDndLink:
return "DragAndDropLink";
}
@@ -2712,26 +2783,28 @@ String Internals::getCurrentCursorInfo() {
if (!GetFrame())
return String();
- Cursor cursor =
+ ui::Cursor cursor =
GetFrame()->GetPage()->GetChromeClient().LastSetCursorForTesting();
StringBuilder result;
result.Append("type=");
- result.Append(CursorTypeToString(cursor.GetType()));
- result.Append(" hotSpot=");
- result.AppendNumber(cursor.HotSpot().X());
- result.Append(',');
- result.AppendNumber(cursor.HotSpot().Y());
- if (cursor.GetImage()) {
- IntSize size = cursor.GetImage()->Size();
+ result.Append(CursorTypeToString(cursor.type()));
+ if (cursor.type() == ui::mojom::blink::CursorType::kCustom) {
+ result.Append(" hotSpot=");
+ result.AppendNumber(cursor.custom_hotspot().x());
+ result.Append(',');
+ result.AppendNumber(cursor.custom_hotspot().y());
+
+ SkBitmap bitmap = cursor.custom_bitmap();
+ DCHECK(!bitmap.isNull());
result.Append(" image=");
- result.AppendNumber(size.Width());
+ result.AppendNumber(bitmap.width());
result.Append('x');
- result.AppendNumber(size.Height());
+ result.AppendNumber(bitmap.height());
}
- if (cursor.ImageScaleFactor() != 1) {
+ if (cursor.image_scale_factor() != 1) {
result.Append(" scale=");
- result.AppendNumber(cursor.ImageScaleFactor(), 8);
+ result.AppendNumber(cursor.image_scale_factor(), 8);
}
return result.ToString();
@@ -2744,16 +2817,20 @@ bool Internals::cursorUpdatePending() const {
return GetFrame()->GetEventHandler().CursorUpdatePending();
}
-bool Internals::fakeMouseMovePending() const {
- if (!GetFrame())
- return false;
-
- return GetFrame()->GetEventHandler().FakeMouseMovePending();
-}
-
DOMArrayBuffer* Internals::serializeObject(
- scoped_refptr<SerializedScriptValue> value) const {
- base::span<const uint8_t> span = value->GetWireData();
+ v8::Isolate* isolate,
+ const ScriptValue& value,
+ ExceptionState& exception_state) const {
+ scoped_refptr<SerializedScriptValue> serialized_value =
+ SerializedScriptValue::Serialize(
+ isolate, value.V8Value(),
+ SerializedScriptValue::SerializeOptions(
+ SerializedScriptValue::kNotForStorage),
+ exception_state);
+ if (exception_state.HadException())
+ return nullptr;
+
+ base::span<const uint8_t> span = serialized_value->GetWireData();
DOMArrayBuffer* buffer = DOMArrayBuffer::CreateUninitializedOrNull(
SafeCast<uint32_t>(span.size()), sizeof(uint8_t));
if (buffer)
@@ -2761,34 +2838,12 @@ DOMArrayBuffer* Internals::serializeObject(
return buffer;
}
-scoped_refptr<SerializedScriptValue> Internals::deserializeBuffer(
- DOMArrayBuffer* buffer) const {
- return SerializedScriptValue::Create(static_cast<const char*>(buffer->Data()),
- buffer->ByteLengthAsSizeT());
-}
-
-DOMArrayBuffer* Internals::serializeWithInlineWasm(ScriptValue value) const {
- v8::Isolate* isolate = value.GetIsolate();
- ExceptionState exception_state(isolate, ExceptionState::kExecutionContext,
- "Internals", "serializeWithInlineWasm");
- v8::Local<v8::Value> v8_value = value.V8Value();
- SerializedScriptValue::SerializeOptions options;
- options.wasm_policy = SerializedScriptValue::SerializeOptions::kSerialize;
- scoped_refptr<SerializedScriptValue> obj = SerializedScriptValue::Serialize(
- isolate, v8_value, options, exception_state);
- if (exception_state.HadException())
- return nullptr;
- return serializeObject(obj);
-}
-
-ScriptValue Internals::deserializeBufferContainingWasm(
- ScriptState* state,
- DOMArrayBuffer* buffer) const {
- DummyExceptionStateForTesting exception_state;
- SerializedScriptValue::DeserializeOptions options;
- options.read_wasm_from_stream = true;
- return ScriptValue::From(state, deserializeBuffer(buffer)->Deserialize(
- state->GetIsolate(), options));
+ScriptValue Internals::deserializeBuffer(v8::Isolate* isolate,
+ DOMArrayBuffer* buffer) const {
+ scoped_refptr<SerializedScriptValue> serialized_value =
+ SerializedScriptValue::Create(static_cast<const char*>(buffer->Data()),
+ buffer->ByteLengthAsSizeT());
+ return ScriptValue(isolate, serialized_value->Deserialize(isolate));
}
void Internals::forceReload(bool bypass_cache) {
@@ -2900,12 +2955,9 @@ void Internals::forceImageReload(Element* element,
String Internals::selectMenuListText(HTMLSelectElement* select) {
DCHECK(select);
- LayoutObject* layout_object = select->GetLayoutObject();
- if (!layout_object || !layout_object->IsMenuList())
+ if (!select->UsesMenuList())
return String();
-
- LayoutMenuList* menu_list = ToLayoutMenuList(layout_object);
- return menu_list->GetText();
+ return select->InnerElement().innerText();
}
bool Internals::isSelectPopupVisible(Node* node) {
@@ -2977,7 +3029,7 @@ void Internals::forceCompositingUpdate(Document* document,
}
document->GetFrame()->View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
}
void Internals::setShouldRevealPassword(Element* element,
@@ -3091,7 +3143,7 @@ ScriptPromise Internals::promiseCheckOverload(ScriptState* script_state,
V8String(script_state->GetIsolate(), "done"));
}
-void Internals::Trace(blink::Visitor* visitor) {
+void Internals::Trace(Visitor* visitor) {
visitor->Trace(runtime_flags_);
visitor->Trace(document_);
ScriptWrappable::Trace(visitor);
@@ -3115,7 +3167,8 @@ void Internals::setInitialFocus(bool reverse) {
GetFrame()->GetDocument()->ClearFocusedElement();
GetFrame()->GetPage()->GetFocusController().SetInitialFocus(
- reverse ? kWebFocusTypeBackward : kWebFocusTypeForward);
+ reverse ? mojom::blink::FocusType::kBackward
+ : mojom::blink::FocusType::kForward);
}
Element* Internals::interestedElement() {
@@ -3135,10 +3188,6 @@ Element* Internals::interestedElement() {
.GetInterestedElement();
}
-unsigned Internals::countHitRegions(CanvasRenderingContext* context) {
- return context->HitRegionsCount();
-}
-
bool Internals::isInCanvasFontCache(Document* document,
const String& font_string) {
return document->GetCanvasFontCache()->IsInCache(font_string);
@@ -3166,7 +3215,7 @@ String Internals::selectedHTMLForClipboard() {
return String();
// Selection normalization and markup generation require clean layout.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kTest);
return GetFrame()->Selection().SelectedHTMLForClipboard();
}
@@ -3176,7 +3225,7 @@ String Internals::selectedTextForClipboard() {
return String();
// Clean layout is required for extracting plain text from selection.
- GetFrame()->GetDocument()->UpdateStyleAndLayout();
+ GetFrame()->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kTest);
return GetFrame()->Selection().SelectedTextForClipboard();
}
@@ -3196,13 +3245,14 @@ bool Internals::isUseCounted(Document* document, uint32_t feature) {
bool Internals::isCSSPropertyUseCounted(Document* document,
const String& property_name) {
- return document->IsPropertyCounted(unresolvedCSSPropertyID(property_name));
+ return document->IsPropertyCounted(
+ unresolvedCSSPropertyID(document->GetExecutionContext(), property_name));
}
bool Internals::isAnimatedCSSPropertyUseCounted(Document* document,
const String& property_name) {
return document->IsAnimatedPropertyCounted(
- unresolvedCSSPropertyID(property_name));
+ unresolvedCSSPropertyID(document->GetExecutionContext(), property_name));
}
void Internals::clearUseCounter(Document* document, uint32_t feature) {
@@ -3298,7 +3348,7 @@ void Internals::setPseudoClassState(Element* element,
bool Internals::setScrollbarVisibilityInScrollableArea(Node* node,
bool visible) {
if (ScrollableArea* scrollable_area = ScrollableAreaForNode(node)) {
- scrollable_area->SetScrollbarsHiddenIfOverlay(!visible);
+ scrollable_area->SetScrollbarsHiddenForTesting(!visible);
scrollable_area->GetScrollAnimator().SetScrollbarsVisibleForTesting(
visible);
return scrollable_area->GetPageScrollbarTheme().UsesOverlayScrollbars();
@@ -3460,12 +3510,16 @@ void Internals::ResolveResourcePriority(ScriptPromiseResolver* resolver,
resolver->Resolve(resource_load_priority);
}
-String Internals::getDocumentAgentId(Document* document) {
+String Internals::getAgentId(DOMWindow* window) {
+ if (!window->IsLocalDOMWindow())
+ return String();
+
// Sounds like there's no notion of "process ID" in Blink, but the main
// thread's thread ID serves for that purpose.
PlatformThreadId process_id = Thread::MainThread()->ThreadId();
- uintptr_t agent_address = reinterpret_cast<uintptr_t>(document->GetAgent());
+ uintptr_t agent_address =
+ reinterpret_cast<uintptr_t>(To<LocalDOMWindow>(window)->GetAgent());
// This serializes a pointer as a decimal number, which is a bit ugly, but
// it works. Is there any utility to dump a number in a hexadecimal form?
@@ -3481,4 +3535,14 @@ bool Internals::overlayScrollbarsEnabled() const {
return ScrollbarThemeSettings::OverlayScrollbarsEnabled();
}
+void Internals::generateTestReport(const String& message) {
+ // Construct the test report.
+ TestReportBody* body = MakeGarbageCollected<TestReportBody>(message);
+ Report* report =
+ MakeGarbageCollected<Report>("test", document_->Url().GetString(), body);
+
+ // Send the test report to any ReportingObservers.
+ ReportingContext::From(document_->ExecutingWindow())->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 ccd5b2bb44d..75155f08ab6 100644
--- a/chromium/third_party/blink/renderer/core/testing/internals.h
+++ b/chromium/third_party/blink/renderer/core/testing/internals.h
@@ -42,7 +42,6 @@ namespace blink {
class Animation;
class CallbackFunctionTest;
-class CanvasRenderingContext;
class DOMArrayBuffer;
class DOMPoint;
class DOMRect;
@@ -77,14 +76,14 @@ class RecordTest;
class ScriptPromiseResolver;
class ScrollState;
class SequenceTest;
-class SerializedScriptValue;
class ShadowRoot;
-template <typename NodeType>
-class StaticNodeTypeList;
class StaticSelection;
class TypeConversions;
class UnionTypesTest;
+template <typename NodeType>
+class StaticNodeTypeList;
+
using StaticNodeList = StaticNodeTypeList<Node>;
class Internals final : public ScriptWrappable {
@@ -204,6 +203,8 @@ class Internals final : public ScriptWrappable {
void addCompositionMarker(const Range*,
const String& underline_color_value,
const String& thickness_value,
+ const String& underline_style_value,
+ const String& text_color_value,
const String& background_color_value,
ExceptionState&);
void addActiveSuggestionMarker(const Range*,
@@ -277,10 +278,10 @@ class Internals final : public ScriptWrappable {
Vector<AtomicString> userPreferredLanguages() const;
void setUserPreferredLanguages(const Vector<String>&);
+ void setSystemTimeZone(const String&);
unsigned mediaKeysCount();
unsigned mediaKeySessionCount();
- unsigned contextLifecycleStateObserverObjectCount(Document*);
unsigned wheelEventHandlerCount(Document*) const;
unsigned scrollEventHandlerCount(Document*) const;
unsigned touchStartOrMoveEventHandlerCount(Document*) const;
@@ -294,6 +295,8 @@ class Internals final : public ScriptWrappable {
const String& value,
ExceptionState&);
+ void triggerTestInspectorIssue(Document*);
+
AtomicString htmlNamespace();
Vector<AtomicString> htmlTags();
AtomicString svgNamespace();
@@ -328,6 +331,8 @@ class Internals final : public ScriptWrappable {
InternalRuntimeFlags* runtimeFlags() const;
unsigned workerThreadCount() const;
+ bool isFormControlsRefreshEnabled() const;
+
String resolveModuleSpecifier(const String& specifier,
const String& base_url_string,
Document*,
@@ -423,19 +428,15 @@ class Internals final : public ScriptWrappable {
DOMRectList* draggableRegions(Document*, ExceptionState&);
DOMRectList* nonDraggableRegions(Document*, ExceptionState&);
- DOMArrayBuffer* serializeObject(scoped_refptr<SerializedScriptValue>) const;
- scoped_refptr<SerializedScriptValue> deserializeBuffer(DOMArrayBuffer*) const;
-
- DOMArrayBuffer* serializeWithInlineWasm(ScriptValue) const;
- ScriptValue deserializeBufferContainingWasm(ScriptState*,
- DOMArrayBuffer*) const;
+ DOMArrayBuffer* serializeObject(v8::Isolate* isolate,
+ const ScriptValue&,
+ ExceptionState& exception_state) const;
+ ScriptValue deserializeBuffer(v8::Isolate* isolate, DOMArrayBuffer*) const;
String getCurrentCursorInfo();
bool cursorUpdatePending() const;
- bool fakeMouseMovePending() const;
-
String markerTextForListItem(Element*);
void forceReload(bool bypass_cache);
@@ -483,7 +484,7 @@ class Internals final : public ScriptWrappable {
ScriptPromise promiseCheckOverload(ScriptState*, Document*);
ScriptPromise promiseCheckOverload(ScriptState*, Location*, int32_t, int32_t);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void setValueForUser(HTMLInputElement*, const String&);
@@ -492,8 +493,6 @@ class Internals final : public ScriptWrappable {
Element* interestedElement();
- unsigned countHitRegions(CanvasRenderingContext*);
-
bool isInCanvasFontCache(Document*, const String&);
unsigned canvasFontCacheMaxFonts();
@@ -595,11 +594,13 @@ class Internals final : public ScriptWrappable {
void setDeviceEmulationScale(float scale, ExceptionState&);
- String getDocumentAgentId(Document*);
+ String getAgentId(DOMWindow*);
void useMockOverlayScrollbars();
bool overlayScrollbarsEnabled() const;
+ void generateTestReport(const String& message);
+
private:
Document* ContextDocument() const;
Vector<String> IconURLs(Document*, int icon_types_mask) const;
diff --git a/chromium/third_party/blink/renderer/core/testing/internals.idl b/chromium/third_party/blink/renderer/core/testing/internals.idl
index 6961b399375..1862cf93cb4 100644
--- a/chromium/third_party/blink/renderer/core/testing/internals.idl
+++ b/chromium/third_party/blink/renderer/core/testing/internals.idl
@@ -78,7 +78,6 @@
[RaisesException] void pauseAnimations(double pauseTime);
boolean isCompositedAnimation(Animation animation);
void disableCompositedAnimation(Animation animation);
- void disableCSSAdditiveAnimations();
// Advances an animated image. For BitmapImage (e.g., animated gifs) this
// will advance to the next frame. For SVGImage, this will trigger an
@@ -114,7 +113,7 @@
[RaisesException] unsigned long markerBackgroundColorForNode(Node node, DOMString markerType, unsigned long index);
[RaisesException] unsigned long markerUnderlineColorForNode(Node node, DOMString markerType, unsigned long index);
[RaisesException] void addTextMatchMarker(Range range, DOMString matchStatus);
- [RaisesException] void addCompositionMarker(Range range, DOMString underlineColorValue, DOMString thicknessValue, DOMString backgroundColorValue);
+ [RaisesException] void addCompositionMarker(Range range, DOMString underlineColorValue, DOMString thicknessValue, DOMString underlineStyleValue, DOMString textColorValue, DOMString backgroundColorValue);
[RaisesException] void addActiveSuggestionMarker(Range range, DOMString underlineColorValue, DOMString thicknessValue, DOMString backgroundColorValue);
[RaisesException] void addSuggestionMarker(Range range, sequence<DOMString> suggestions, DOMString suggestionHighlightColorValue, DOMString underlineColorValue, DOMString thicknessValue, DOMString backgroundColorValue);
void setTextMatchMarkersActive(Node node, unsigned long startOffset, unsigned long endOffset, boolean active);
@@ -150,10 +149,10 @@
sequence<DOMString> userPreferredLanguages();
void setUserPreferredLanguages(sequence<DOMString> languages);
+ void setSystemTimeZone(DOMString timezone);
unsigned long mediaKeysCount();
unsigned long mediaKeySessionCount();
- unsigned long contextLifecycleStateObserverObjectCount(Document document);
unsigned long wheelEventHandlerCount(Document document);
unsigned long scrollEventHandlerCount(Document document);
unsigned long touchStartOrMoveEventHandlerCount(Document document);
@@ -163,6 +162,8 @@
[RaisesException] boolean executeCommand(Document document, DOMString name, DOMString value);
+ void triggerTestInspectorIssue(Document document);
+
DOMString htmlNamespace();
sequence<DOMString> htmlTags();
DOMString svgNamespace();
@@ -189,11 +190,13 @@
readonly attribute InternalSettings settings;
readonly attribute InternalRuntimeFlags runtimeFlags;
readonly attribute unsigned long workerThreadCount;
+ readonly attribute boolean isFormControlsRefreshEnabled;
- // Flag for layerTreeAsText.
- // The value must be kept in sync with the value of LayerTreeFlags in layers_as_json.h.
+ // Flag for layerTreeAsText. The value must be kept in sync with the value
+ // of LayerTreeFlags in layers_as_json.h.
// Other flags in LayerTreeFlags are not supported in internals API.
- const unsigned short LAYER_TREE_INCLUDES_PAINT_INVALIDATIONS = 2;
+ const unsigned short LAYER_TREE_INCLUDES_INVALIDATIONS = 2;
+ const unsigned short LAYER_TREE_INCLUDES_DETAILED_INVALIDATIONS = 4;
[RaisesException] DOMString layerTreeAsText(Document document, optional unsigned short flags);
@@ -260,16 +263,11 @@
DOMString getCurrentCursorInfo();
readonly attribute boolean cursorUpdatePending;
- readonly attribute boolean fakeMouseMovePending;
DOMString markerTextForListItem(Element element);
- SerializedScriptValue deserializeBuffer(ArrayBuffer buffer);
- ArrayBuffer serializeObject(SerializedScriptValue obj);
-
- [CallWith=ScriptState] any deserializeBufferContainingWasm(ArrayBuffer buffer);
- ArrayBuffer serializeWithInlineWasm(any obj);
-
+ [CallWith=Isolate, RaisesException] ArrayBuffer serializeObject(any obj);
+ [CallWith=Isolate] any deserializeBuffer(ArrayBuffer buffer);
void forceReload(boolean endToEnd);
@@ -319,9 +317,6 @@
// attribute returns the currently interested element on the page.
readonly attribute Element? interestedElement;
- // This function is for testing HitRegions on Canvas2D.
- unsigned long countHitRegions(CanvasRenderingContext2D context);
-
boolean isInCanvasFontCache(Document document, DOMString fontString);
unsigned long canvasFontCacheMaxFonts();
@@ -429,12 +424,15 @@
// Sets the scale for devtools device emulation.
[RaisesException] void setDeviceEmulationScale(float scale);
- // Return a string that identifies |document|'s WindowAgent. You can use it
+ // Return a string that identifies |window|'s WindowAgent. You can use it
// to distinguish different Agent instances (perhaps in a remote process).
// The returned string is composed of the process ID and the memory address
// of the Agent object.
- DOMString getDocumentAgentId(Document document);
+ DOMString getAgentId(Window window);
void useMockOverlayScrollbars();
readonly attribute boolean overlayScrollbarsEnabled;
+
+ // Request generation of a Reporting report.
+ void generateTestReport(DOMString message);
};
diff --git a/chromium/third_party/blink/renderer/core/testing/mock_clipboard_host.cc b/chromium/third_party/blink/renderer/core/testing/mock_clipboard_host.cc
new file mode 100644
index 00000000000..4235e6f74d6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/testing/mock_clipboard_host.cc
@@ -0,0 +1,146 @@
+// 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/core/testing/mock_clipboard_host.h"
+
+#include "build/build_config.h"
+
+namespace blink {
+
+MockClipboardHost::MockClipboardHost() = default;
+
+MockClipboardHost::~MockClipboardHost() = default;
+
+void MockClipboardHost::Bind(
+ mojo::PendingReceiver<mojom::blink::ClipboardHost> receiver) {
+ receivers_.Add(this, std::move(receiver));
+}
+
+void MockClipboardHost::Reset() {
+ plain_text_ = g_empty_string;
+ html_text_ = g_empty_string;
+ url_ = KURL();
+ image_.reset();
+ custom_data_.clear();
+ write_smart_paste_ = false;
+ needs_reset_ = false;
+}
+
+void MockClipboardHost::GetSequenceNumber(
+ mojom::ClipboardBuffer clipboard_buffer,
+ GetSequenceNumberCallback callback) {
+ std::move(callback).Run(sequence_number_);
+}
+
+void MockClipboardHost::ReadAvailableTypes(
+ mojom::ClipboardBuffer clipboard_buffer,
+ ReadAvailableTypesCallback callback) {
+ Vector<String> types;
+ if (!plain_text_.IsEmpty())
+ types.push_back("text/plain");
+ if (!html_text_.IsEmpty())
+ types.push_back("text/html");
+ if (!image_.isNull())
+ types.push_back("image/png");
+ for (auto& it : custom_data_) {
+ CHECK(!base::Contains(types, it.key));
+ types.push_back(it.key);
+ }
+ std::move(callback).Run(types, false);
+}
+
+void MockClipboardHost::IsFormatAvailable(
+ mojom::ClipboardFormat format,
+ mojom::ClipboardBuffer clipboard_buffer,
+ IsFormatAvailableCallback callback) {
+ bool result = false;
+ switch (format) {
+ case mojom::ClipboardFormat::kPlaintext:
+ result = !plain_text_.IsEmpty();
+ break;
+ case mojom::ClipboardFormat::kHtml:
+ result = !html_text_.IsEmpty();
+ break;
+ case mojom::ClipboardFormat::kSmartPaste:
+ result = write_smart_paste_;
+ break;
+ case mojom::ClipboardFormat::kBookmark:
+ result = false;
+ break;
+ }
+ std::move(callback).Run(result);
+}
+
+void MockClipboardHost::ReadText(mojom::ClipboardBuffer clipboard_buffer,
+ ReadTextCallback callback) {
+ std::move(callback).Run(plain_text_);
+}
+
+void MockClipboardHost::ReadHtml(mojom::ClipboardBuffer clipboard_buffer,
+ ReadHtmlCallback callback) {
+ std::move(callback).Run(html_text_, url_, 0, html_text_.length());
+}
+
+void MockClipboardHost::ReadRtf(mojom::ClipboardBuffer clipboard_buffer,
+ ReadRtfCallback callback) {
+ std::move(callback).Run(g_empty_string);
+}
+
+void MockClipboardHost::ReadImage(mojom::ClipboardBuffer clipboard_buffer,
+ ReadImageCallback callback) {
+ std::move(callback).Run(image_);
+}
+
+void MockClipboardHost::ReadCustomData(mojom::ClipboardBuffer clipboard_buffer,
+ const String& type,
+ ReadCustomDataCallback callback) {
+ auto it = custom_data_.find(type);
+ std::move(callback).Run(it != custom_data_.end() ? it->value
+ : g_empty_string);
+}
+
+void MockClipboardHost::WriteText(const String& text) {
+ if (needs_reset_)
+ Reset();
+ plain_text_ = text;
+}
+
+void MockClipboardHost::WriteHtml(const String& markup, const KURL& url) {
+ if (needs_reset_)
+ Reset();
+ html_text_ = markup;
+ url_ = url;
+}
+
+void MockClipboardHost::WriteSmartPasteMarker() {
+ if (needs_reset_)
+ Reset();
+ write_smart_paste_ = true;
+}
+
+void MockClipboardHost::WriteCustomData(const HashMap<String, String>& data) {
+ if (needs_reset_)
+ Reset();
+ for (auto& it : data)
+ custom_data_.Set(it.key, it.value);
+}
+
+void MockClipboardHost::WriteBookmark(const String& url, const String& title) {}
+
+void MockClipboardHost::WriteImage(const SkBitmap& bitmap) {
+ if (needs_reset_)
+ Reset();
+ image_ = bitmap;
+}
+
+void MockClipboardHost::CommitWrite() {
+ ++sequence_number_;
+ needs_reset_ = true;
+}
+
+#if defined(OS_MACOSX)
+void MockClipboardHost::WriteStringToFindPboard(const String& text) {}
+#endif
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/testing/mock_clipboard_host.h b/chromium/third_party/blink/renderer/core/testing/mock_clipboard_host.h
new file mode 100644
index 00000000000..d380b83af26
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/testing/mock_clipboard_host.h
@@ -0,0 +1,72 @@
+// 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_TESTING_MOCK_CLIPBOARD_HOST_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_MOCK_CLIPBOARD_HOST_H_
+
+#include <map>
+
+#include "build/build_config.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
+#include "third_party/blink/public/common/common_export.h"
+#include "third_party/blink/public/mojom/clipboard/clipboard.mojom-blink.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+
+namespace blink {
+
+class MockClipboardHost : public mojom::blink::ClipboardHost {
+ public:
+ MockClipboardHost();
+ ~MockClipboardHost() override;
+
+ void Bind(mojo::PendingReceiver<mojom::blink::ClipboardHost> receiver);
+ void Reset();
+
+ private:
+ // mojom::ClipboardHost
+ void GetSequenceNumber(mojom::ClipboardBuffer clipboard_buffer,
+ GetSequenceNumberCallback callback) override;
+ void IsFormatAvailable(mojom::ClipboardFormat format,
+ mojom::ClipboardBuffer clipboard_buffer,
+ IsFormatAvailableCallback callback) override;
+ void ReadAvailableTypes(mojom::ClipboardBuffer clipboard_buffer,
+ ReadAvailableTypesCallback callback) override;
+ void ReadText(mojom::ClipboardBuffer clipboard_buffer,
+ ReadTextCallback callback) override;
+ void ReadHtml(mojom::ClipboardBuffer clipboard_buffer,
+ ReadHtmlCallback callback) override;
+ void ReadRtf(mojom::ClipboardBuffer clipboard_buffer,
+ ReadRtfCallback callback) override;
+ void ReadImage(mojom::ClipboardBuffer clipboard_buffer,
+ ReadImageCallback callback) override;
+ void ReadCustomData(mojom::ClipboardBuffer clipboard_buffer,
+ const String& type,
+ ReadCustomDataCallback callback) override;
+ void WriteText(const String& text) override;
+ void WriteHtml(const String& markup, const KURL& url) override;
+ void WriteSmartPasteMarker() override;
+ void WriteCustomData(const HashMap<String, String>& data) override;
+ void WriteBookmark(const String& url, const String& title) override;
+ void WriteImage(const SkBitmap& bitmap) override;
+ void CommitWrite() override;
+#if defined(OS_MACOSX)
+ void WriteStringToFindPboard(const String& text) override;
+#endif
+
+ mojo::ReceiverSet<mojom::blink::ClipboardHost> receivers_;
+ uint64_t sequence_number_ = 0;
+ String plain_text_ = g_empty_string;
+ String html_text_ = g_empty_string;
+ KURL url_;
+ SkBitmap image_;
+ HashMap<String, String> custom_data_;
+ bool write_smart_paste_ = false;
+ bool needs_reset_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(MockClipboardHost);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_MOCK_CLIPBOARD_HOST_H_
diff --git a/chromium/third_party/blink/renderer/core/testing/module_test_base.cc b/chromium/third_party/blink/renderer/core/testing/module_test_base.cc
new file mode 100644
index 00000000000..2894ed4002c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/testing/module_test_base.cc
@@ -0,0 +1,31 @@
+// 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/testing/module_test_base.h"
+
+namespace blink {
+
+void ParametrizedModuleTest::SetUp() {
+ if (UseTopLevelAwait()) {
+ feature_list_.InitAndEnableFeature(features::kTopLevelAwait);
+ } else {
+ feature_list_.InitAndDisableFeature(features::kTopLevelAwait);
+ }
+ SetV8Flags(UseTopLevelAwait());
+}
+
+void ParametrizedModuleTest::TearDown() {
+ feature_list_.Reset();
+ SetV8Flags(base::FeatureList::IsEnabled(features::kTopLevelAwait));
+}
+
+void ParametrizedModuleTest::SetV8Flags(bool use_top_level_await) {
+ if (use_top_level_await) {
+ v8::V8::SetFlagsFromString("--harmony-top-level-await");
+ } else {
+ v8::V8::SetFlagsFromString("--no-harmony-top-level-await");
+ }
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/testing/module_test_base.h b/chromium/third_party/blink/renderer/core/testing/module_test_base.h
new file mode 100644
index 00000000000..11c7035795c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/testing/module_test_base.h
@@ -0,0 +1,38 @@
+// 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_TESTING_MODULE_TEST_BASE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_MODULE_TEST_BASE_H_
+
+#include <gtest/gtest.h>
+#include "base/test/scoped_feature_list.h"
+#include "third_party/blink/public/common/features.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+// Helper used to enable or disable top-level await in parametrized tests.
+class ParametrizedModuleTest : public testing::WithParamInterface<bool> {
+ protected:
+ void SetUp();
+ void TearDown();
+
+ bool UseTopLevelAwait() { return GetParam(); }
+ base::test::ScopedFeatureList feature_list_;
+
+ private:
+ void SetV8Flags(bool use_top_level_await);
+};
+
+// Used in INSTANTIATE_TEST_SUITE_P for returning more readable test names.
+struct ParametrizedModuleTestParamName {
+ std::string operator()(
+ const testing::TestParamInfo<ParametrizedModuleTest::ParamType>& info) {
+ return info.param ? "TopLevelAwait" : "noTopLevelAwait";
+ }
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_MODULE_TEST_BASE_H_
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 083abc5d58a..59cc8380b89 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
@@ -8,8 +8,10 @@
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/core/dom/events/event.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/frame/dom_timer.h"
+#include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h"
#include "third_party/blink/renderer/platform/scheduler/public/dummy_schedulers.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
@@ -18,32 +20,27 @@ namespace blink {
NullExecutionContext::NullExecutionContext(
OriginTrialContext* origin_trial_context)
- : ExecutionContext(
- v8::Isolate::GetCurrent(),
- MakeGarbageCollected<Agent>(v8::Isolate::GetCurrent(),
- base::UnguessableToken::Null()),
- origin_trial_context),
- tasks_need_pause_(false),
- is_secure_context_(true),
- scheduler_(scheduler::CreateDummyFrameScheduler()) {}
-
-NullExecutionContext::~NullExecutionContext() {}
-
-void NullExecutionContext::SetIsSecureContext(bool is_secure_context) {
- is_secure_context_ = is_secure_context;
+ : ExecutionContext(v8::Isolate::GetCurrent()),
+ security_context_(
+ SecurityContextInit(
+ nullptr /* origin */,
+ origin_trial_context,
+ MakeGarbageCollected<Agent>(v8::Isolate::GetCurrent(),
+ base::UnguessableToken::Null())),
+ SecurityContext::kLocal),
+ scheduler_(scheduler::CreateDummyFrameScheduler()) {
+ if (origin_trial_context)
+ origin_trial_context->BindExecutionContext(this);
}
-bool NullExecutionContext::IsSecureContext(String& error_message) const {
- if (!is_secure_context_)
- error_message = "A secure context is required";
- return is_secure_context_;
-}
+NullExecutionContext::~NullExecutionContext() {}
-void NullExecutionContext::SetUpSecurityContext() {
+void NullExecutionContext::SetUpSecurityContextForTesting() {
auto* policy = MakeGarbageCollected<ContentSecurityPolicy>();
- SecurityContext::SetSecurityOrigin(SecurityOrigin::Create(url_));
+ GetSecurityContext().SetSecurityOriginForTesting(
+ SecurityOrigin::Create(url_));
policy->BindToDelegate(GetContentSecurityPolicyDelegate());
- SecurityContext::SetContentSecurityPolicy(policy);
+ GetSecurityContext().SetContentSecurityPolicy(policy);
}
FrameOrWorkerScheduler* NullExecutionContext::GetScheduler() {
@@ -59,4 +56,9 @@ BrowserInterfaceBrokerProxy& NullExecutionContext::GetBrowserInterfaceBroker() {
return GetEmptyBrowserInterfaceBroker();
}
+void NullExecutionContext::Trace(Visitor* visitor) {
+ visitor->Trace(security_context_);
+ ExecutionContext::Trace(visitor);
+}
+
} // namespace blink
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 eb053ae85f1..6fc27a4bead 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
@@ -17,7 +17,6 @@
namespace blink {
class NullExecutionContext : public GarbageCollected<NullExecutionContext>,
- public SecurityContext,
public ExecutionContext {
USING_GARBAGE_COLLECTED_MIXIN(NullExecutionContext);
@@ -40,20 +39,11 @@ class NullExecutionContext : public GarbageCollected<NullExecutionContext>,
EventTarget* ErrorEventTarget() override { return nullptr; }
- bool TasksNeedPause() override { return tasks_need_pause_; }
- void SetTasksNeedPause(bool flag) { tasks_need_pause_ = flag; }
-
- SecurityContext& GetSecurityContext() final { return *this; }
- const SecurityContext& GetSecurityContext() const final { return *this; }
-
void AddConsoleMessageImpl(ConsoleMessage*,
bool discard_duplicates) override {}
void ExceptionThrown(ErrorEvent*) override {}
- void SetIsSecureContext(bool);
- bool IsSecureContext(String& error_message) const override;
-
- void SetUpSecurityContext();
+ void SetUpSecurityContextForTesting();
ResourceFetcher* Fetcher() const override { return nullptr; }
@@ -63,24 +53,20 @@ class NullExecutionContext : public GarbageCollected<NullExecutionContext>,
void CountUse(mojom::WebFeature) override {}
void CountDeprecation(mojom::WebFeature) override {}
- void SetSandboxFlags(WebSandboxFlags flags) { sandbox_flags_ = flags; }
-
- using SecurityContext::GetSecurityOrigin;
- using SecurityContext::GetContentSecurityPolicy;
+ BrowserInterfaceBrokerProxy& GetBrowserInterfaceBroker() override;
- void Trace(blink::Visitor* visitor) override {
- SecurityContext::Trace(visitor);
- ExecutionContext::Trace(visitor);
+ SecurityContext& GetSecurityContext() override { return security_context_; }
+ const SecurityContext& GetSecurityContext() const override {
+ return security_context_;
}
- BrowserInterfaceBrokerProxy& GetBrowserInterfaceBroker() override;
+ void Trace(Visitor*) override;
private:
- bool tasks_need_pause_;
- bool is_secure_context_;
-
KURL url_;
+ SecurityContext security_context_;
+
// A dummy scheduler to ensure that the callers of
// ExecutionContext::GetScheduler don't have to check for whether it's null or
// not.
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 703e5a7c8cf..b9abd4f8bf9 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
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_ORIGIN_TRIALS_TEST_H_
#include "third_party/blink/renderer/bindings/core/v8/idl_dictionary_base.h"
-#include "third_party/blink/renderer/core/testing/origin_trials_test_dictionary.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_origin_trials_test_dictionary.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
diff --git a/chromium/third_party/blink/renderer/core/testing/page_test_base.cc b/chromium/third_party/blink/renderer/core/testing/page_test_base.cc
index 40d7b51cbc1..3dee0055e43 100644
--- a/chromium/third_party/blink/renderer/core/testing/page_test_base.cc
+++ b/chromium/third_party/blink/renderer/core/testing/page_test_base.cc
@@ -4,10 +4,12 @@
#include "third_party/blink/renderer/core/testing/page_test_base.h"
+#include "base/callback.h"
#include "base/test/bind_test_util.h"
#include "base/time/default_tick_clock.h"
+#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_array_buffer_or_array_buffer_view.h"
-#include "third_party/blink/renderer/core/css/font_face_descriptors.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_font_face_descriptors.h"
#include "third_party/blink/renderer/core/css/font_face_set_document.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -34,6 +36,36 @@ Element* GetOrCreateElement(ContainerNode* parent,
} // namespace
+PageTestBase::MockClipboardHostProvider::MockClipboardHostProvider(
+ blink::BrowserInterfaceBrokerProxy& interface_broker) {
+ Install(interface_broker);
+}
+
+PageTestBase::MockClipboardHostProvider::MockClipboardHostProvider() = default;
+
+PageTestBase::MockClipboardHostProvider::~MockClipboardHostProvider() {
+ if (interface_broker_) {
+ interface_broker_->SetBinderForTesting(
+ blink::mojom::blink::ClipboardHost::Name_, {});
+ }
+}
+
+void PageTestBase::MockClipboardHostProvider::Install(
+ blink::BrowserInterfaceBrokerProxy& interface_broker) {
+ interface_broker_ = &interface_broker;
+ interface_broker_->SetBinderForTesting(
+ blink::mojom::blink::ClipboardHost::Name_,
+ base::BindRepeating(
+ &PageTestBase::MockClipboardHostProvider::BindClipboardHost,
+ base::Unretained(this)));
+}
+
+void PageTestBase::MockClipboardHostProvider::BindClipboardHost(
+ mojo::ScopedMessagePipeHandle handle) {
+ host_.Bind(mojo::PendingReceiver<blink::mojom::blink::ClipboardHost>(
+ std::move(handle)));
+}
+
PageTestBase::PageTestBase() = default;
PageTestBase::~PageTestBase() = default;
@@ -53,6 +85,10 @@ void PageTestBase::SetUp() {
dummy_page_holder_ = std::make_unique<DummyPageHolder>(
IntSize(800, 600), nullptr, nullptr, std::move(setter), GetTickClock());
+ // Mock out clipboard calls so that tests don't mess
+ // with each other's copies/pastes when running in parallel.
+ mock_clipboard_host_provider_.Install(GetFrame().GetBrowserInterfaceBroker());
+
// Use no-quirks (ake "strict") mode by default.
GetDocument().SetCompatibilityMode(Document::kNoQuirksMode);
@@ -129,7 +165,7 @@ void PageTestBase::LoadAhem(LocalFrame& frame) {
StringOrArrayBufferOrArrayBufferView buffer =
StringOrArrayBufferOrArrayBufferView::FromArrayBuffer(
DOMArrayBuffer::Create(shared_buffer));
- FontFace* ahem = FontFace::Create(&document, "Ahem", buffer,
+ FontFace* ahem = FontFace::Create(frame.DomWindow(), "Ahem", buffer,
FontFaceDescriptors::Create());
ScriptState* script_state = ToScriptStateForMainWorld(&frame);
@@ -140,8 +176,7 @@ void PageTestBase::LoadAhem(LocalFrame& frame) {
// Both sets the inner html and runs the document lifecycle.
void PageTestBase::SetBodyInnerHTML(const String& body_content) {
- GetDocument().body()->SetInnerHTMLFromString(body_content,
- ASSERT_NO_EXCEPTION);
+ GetDocument().body()->setInnerHTML(body_content, ASSERT_NO_EXCEPTION);
UpdateAllLifecyclePhasesForTest();
}
@@ -150,8 +185,7 @@ void PageTestBase::SetBodyContent(const std::string& body_content) {
}
void PageTestBase::SetHtmlInnerHTML(const std::string& html_content) {
- GetDocument().documentElement()->SetInnerHTMLFromString(
- String::FromUTF8(html_content));
+ GetDocument().documentElement()->setInnerHTML(String::FromUTF8(html_content));
UpdateAllLifecyclePhasesForTest();
}
@@ -166,18 +200,13 @@ void PageTestBase::InsertStyleElement(const std::string& style_rules) {
}
void PageTestBase::NavigateTo(const KURL& url,
- const String& feature_policy_header,
- const String& csp_header) {
+ const WTF::HashMap<String, String>& headers) {
auto params =
WebNavigationParams::CreateWithHTMLBuffer(SharedBuffer::Create(), url);
- if (!feature_policy_header.IsEmpty()) {
- params->response.SetHttpHeaderField(http_names::kFeaturePolicy,
- feature_policy_header);
- }
- if (!csp_header.IsEmpty()) {
- params->response.SetHttpHeaderField(http_names::kContentSecurityPolicy,
- csp_header);
- }
+
+ for (const auto& header : headers)
+ params->response.SetHttpHeaderField(header.key, header.value);
+
GetFrame().Loader().CommitNavigation(std::move(params),
nullptr /* extra_data */);
@@ -186,8 +215,7 @@ void PageTestBase::NavigateTo(const KURL& url,
}
void PageTestBase::UpdateAllLifecyclePhasesForTest() {
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
GetDocument().View()->RunPostLifecycleSteps();
}
diff --git a/chromium/third_party/blink/renderer/core/testing/page_test_base.h b/chromium/third_party/blink/renderer/core/testing/page_test_base.h
index 14aef4e9d1b..e226f6ec9a9 100644
--- a/chromium/third_party/blink/renderer/core/testing/page_test_base.h
+++ b/chromium/third_party/blink/renderer/core/testing/page_test_base.h
@@ -5,10 +5,15 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_PAGE_TEST_BASE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_PAGE_TEST_BASE_H_
+#include <memory>
+
#include <gtest/gtest.h>
+#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
+#include "third_party/blink/renderer/core/testing/mock_clipboard_host.h"
#include "third_party/blink/renderer/core/testing/scoped_mock_overlay_scrollbars.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
+#include "third_party/blink/renderer/platform/wtf/hash_map.h"
namespace base {
class TickClock;
@@ -16,6 +21,7 @@ class TickClock;
namespace blink {
+class BrowserInterfaceBrokerProxy;
class Document;
class LocalFrame;
@@ -23,6 +29,26 @@ class PageTestBase : public testing::Test, public ScopedMockOverlayScrollbars {
USING_FAST_MALLOC(PageTestBase);
public:
+ // Helper class to provide a mock clipboard host for a LocalFrame.
+ class MockClipboardHostProvider {
+ public:
+ explicit MockClipboardHostProvider(
+ blink::BrowserInterfaceBrokerProxy& interface_broker);
+ MockClipboardHostProvider();
+ ~MockClipboardHostProvider();
+
+ // Installs a mock clipboard in the given interface provider.
+ // This is called automatically from the ctor that takes an
+ // |interface_broker| argument.
+ void Install(blink::BrowserInterfaceBrokerProxy& interface_broker);
+
+ private:
+ void BindClipboardHost(mojo::ScopedMessagePipeHandle handle);
+
+ blink::BrowserInterfaceBrokerProxy* interface_broker_ = nullptr;
+ MockClipboardHost host_;
+ };
+
PageTestBase();
~PageTestBase() override;
@@ -49,8 +75,7 @@ class PageTestBase : public testing::Test, public ScopedMockOverlayScrollbars {
// Navigate to |url| providing an empty response but
// URL and security origin of the Document will be set to |url|.
void NavigateTo(const KURL& url,
- const String& feature_policy_header = String(),
- const String& csp_header = String());
+ const WTF::HashMap<String, String>& headers = {});
Document& GetDocument() const;
Page& GetPage() const;
@@ -95,6 +120,8 @@ class PageTestBase : public testing::Test, public ScopedMockOverlayScrollbars {
platform_;
std::unique_ptr<DummyPageHolder> dummy_page_holder_;
bool enable_compositing_ = false;
+
+ MockClipboardHostProvider mock_clipboard_host_provider_;
};
} // namespace blink
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 7b91201bde8..14db635b94a 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(blink::Visitor* visitor) {
+void RecordTest::Trace(Visitor* visitor) {
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 58bab2ab56e..63a6883859f 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 63593ce006e..50db90ddeac 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(blink::Visitor* visitor) {
+void SequenceTest::Trace(Visitor* visitor) {
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 2d558bdfa01..83609c8d23c 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 a1f386cf115..6b7fa60a754 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
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/testing/sim/sim_compositor.h"
#include "cc/test/fake_layer_tree_frame_sink.h"
+#include "cc/trees/render_frame_metadata_observer.h"
#include "third_party/blink/public/platform/web_rect.h"
#include "third_party/blink/renderer/core/exported/web_view_impl.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -28,32 +29,28 @@ SimCompositor::~SimCompositor() = default;
void SimCompositor::SetWebView(
WebViewImpl& web_view,
- cc::LayerTreeHost& layer_tree_host,
- frame_test_helpers::TestWebViewClient& view_client,
- frame_test_helpers::TestWebWidgetClient& widget_client) {
+ frame_test_helpers::TestWebViewClient& view_client) {
web_view_ = &web_view;
- layer_tree_host_ = &layer_tree_host;
test_web_view_client_ = &view_client;
- test_web_widget_client_ = &widget_client;
}
SimCanvas::Commands SimCompositor::BeginFrame(double time_delta_in_seconds) {
DCHECK(web_view_);
- DCHECK(!layer_tree_host_->defer_main_frame_update());
+ DCHECK(!layer_tree_host()->defer_main_frame_update());
// Verify that the need for a BeginMainFrame has been registered, and would
// have caused the compositor to schedule one if we were using its scheduler.
DCHECK(NeedsBeginFrame());
DCHECK_GT(time_delta_in_seconds, 0);
- test_web_widget_client_->ClearAnimationScheduled();
+ ClearAnimationScheduled();
last_frame_time_ += base::TimeDelta::FromSecondsD(time_delta_in_seconds);
SimCanvas::Commands commands;
paint_commands_ = &commands;
- layer_tree_host_->Composite(last_frame_time_,
- /*raster=*/false);
+ layer_tree_host()->Composite(last_frame_time_,
+ /*raster=*/false);
paint_commands_ = nullptr;
return commands;
@@ -65,7 +62,7 @@ SimCanvas::Commands SimCompositor::PaintFrame() {
auto* frame = web_view_->MainFrameImpl()->GetFrame();
DocumentLifecycle::AllowThrottlingScope throttling_scope(
frame->GetDocument()->Lifecycle());
- frame->View()->UpdateAllLifecyclePhases(DocumentLifecycle::kTest);
+ frame->View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
PaintRecordBuilder builder;
frame->View()->PaintOutsideOfLifecycle(builder.Context(),
kGlobalPaintFlattenCompositingLayers);
@@ -76,23 +73,8 @@ SimCanvas::Commands SimCompositor::PaintFrame() {
return canvas.GetCommands();
}
-void SimCompositor::ApplyViewportChanges(const ApplyViewportChangesArgs& args) {
- web_view_->MainFrameWidget()->ApplyViewportChanges(args);
-}
-
-void SimCompositor::RequestNewLayerTreeFrameSink(
- LayerTreeFrameSinkCallback callback) {
- // Make a valid LayerTreeFrameSink so the compositor will generate begin main
- // frames.
- std::move(callback).Run(cc::FakeLayerTreeFrameSink::Create3d());
-}
-
-void SimCompositor::BeginMainFrame(base::TimeTicks frame_time) {
- // There is no WebWidget like RenderWidget would have..? So go right to the
- // WebViewImpl.
- web_view_->MainFrameWidget()->BeginFrame(last_frame_time_, false);
- web_view_->MainFrameWidget()->UpdateAllLifecyclePhases(
- WebWidget::LifecycleUpdateReason::kTest);
+void SimCompositor::UpdateVisualState() {
+ TestWebWidgetClient::UpdateVisualState();
*paint_commands_ = PaintFrame();
}
diff --git a/chromium/third_party/blink/renderer/core/testing/sim/sim_compositor.h b/chromium/third_party/blink/renderer/core/testing/sim/sim_compositor.h
index 3f60923634a..a2f3614a7c7 100644
--- a/chromium/third_party/blink/renderer/core/testing/sim/sim_compositor.h
+++ b/chromium/third_party/blink/renderer/core/testing/sim/sim_compositor.h
@@ -25,14 +25,11 @@ class WebViewImpl;
// only part of the layer was invalid.
//
// Note: This also does not support compositor driven animations.
-class SimCompositor final : public content::StubLayerTreeViewDelegate {
+class SimCompositor final : public frame_test_helpers::TestWebWidgetClient {
public:
SimCompositor();
~SimCompositor() override;
- // This compositor should be given to the WebViewImpl passed to SetWebView.
- cc::LayerTreeHost& layer_tree_host() { return *layer_tree_host_; }
-
// When the compositor asks for a main frame, this WebViewImpl will have its
// lifecycle updated and be painted.
// The WebWidget client is overridden (via the WebViewClient) to control
@@ -41,10 +38,7 @@ class SimCompositor final : public content::StubLayerTreeViewDelegate {
// expectations around this scheduling, so receives the WebViewClient. We
// pass it here explicitly to provide type safety, though it is the client
// available on the WebViewImpl as well.
- void SetWebView(WebViewImpl&,
- cc::LayerTreeHost&,
- frame_test_helpers::TestWebViewClient&,
- frame_test_helpers::TestWebWidgetClient&);
+ void SetWebView(WebViewImpl&, frame_test_helpers::TestWebViewClient&);
// Executes the BeginMainFrame processing steps, an approximation of what
// cc::ThreadProxy::BeginMainFrame would do.
@@ -66,36 +60,30 @@ class SimCompositor final : public content::StubLayerTreeViewDelegate {
// requet for BeginFrame() was made, vs an implicit one by making changes
// to the compositor's state.
bool NeedsBeginFrame() const {
- return test_web_widget_client_->AnimationScheduled() ||
- layer_tree_host_->RequestedMainFramePendingForTesting();
+ return AnimationScheduled() ||
+ layer_tree_host()->RequestedMainFramePendingForTesting();
}
// Returns true if commits are deferred in the compositor. Since these tests
// use synchronous compositing through BeginFrame(), the deferred state has no
// real effect.
bool DeferMainFrameUpdate() const {
- return layer_tree_host_->defer_main_frame_update();
+ return layer_tree_host()->defer_main_frame_update();
}
// Returns true if a selection is set on the compositor.
bool HasSelection() const {
- return layer_tree_host_->selection() != cc::LayerSelection();
+ return layer_tree_host()->selection() != cc::LayerSelection();
}
// Returns the background color set on the compositor.
- SkColor background_color() { return layer_tree_host_->background_color(); }
+ SkColor background_color() { return layer_tree_host()->background_color(); }
base::TimeTicks LastFrameTime() const { return last_frame_time_; }
private:
// content::LayerTreeViewDelegate implementation.
- void ApplyViewportChanges(const ApplyViewportChangesArgs& args) override;
- void RequestNewLayerTreeFrameSink(
- LayerTreeFrameSinkCallback callback) override;
- void BeginMainFrame(base::TimeTicks frame_time) override;
- void DidBeginMainFrame() override { web_view_->DidBeginFrame(); }
+ void UpdateVisualState() override;
WebViewImpl* web_view_ = nullptr;
- cc::LayerTreeHost* layer_tree_host_ = nullptr;
frame_test_helpers::TestWebViewClient* test_web_view_client_ = nullptr;
- frame_test_helpers::TestWebWidgetClient* test_web_widget_client_ = nullptr;
base::TimeTicks last_frame_time_;
diff --git a/chromium/third_party/blink/renderer/core/testing/sim/sim_request.cc b/chromium/third_party/blink/renderer/core/testing/sim/sim_request.cc
index 1716513f08d..dd397737b83 100644
--- a/chromium/third_party/blink/renderer/core/testing/sim/sim_request.cc
+++ b/chromium/third_party/blink/renderer/core/testing/sim/sim_request.cc
@@ -84,7 +84,7 @@ void SimRequestBase::WriteInternal(base::span<const char> data) {
client_->DidReceiveData(data.data(), data.size());
}
-void SimRequestBase::Finish() {
+void SimRequestBase::Finish(bool body_loader_finished) {
if (!started_)
ServePending();
DCHECK(started_);
@@ -94,7 +94,8 @@ void SimRequestBase::Finish() {
total_encoded_data_length_, total_encoded_data_length_);
} else {
if (navigation_body_loader_) {
- navigation_body_loader_->Finish();
+ if (!body_loader_finished)
+ navigation_body_loader_->Finish();
} else {
// TODO(esprehn): Is claiming a request time of 0 okay for tests?
client_->DidFinishLoading(base::TimeTicks(), total_encoded_data_length_,
diff --git a/chromium/third_party/blink/renderer/core/testing/sim/sim_request.h b/chromium/third_party/blink/renderer/core/testing/sim/sim_request.h
index cd2083569c1..1400a2a0c55 100644
--- a/chromium/third_party/blink/renderer/core/testing/sim/sim_request.h
+++ b/chromium/third_party/blink/renderer/core/testing/sim/sim_request.h
@@ -46,7 +46,8 @@ class SimRequestBase {
void Write(const Vector<char>& data);
// Finish the response, this is as if the server closed the connection.
- void Finish();
+ // If |navigation_body_loader| already finished, skip calling Finish on it.
+ void Finish(bool body_loader_finished = false);
// Shorthand to complete a request (start/write/finish) sequence in order.
void Complete(const String& data = String());
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 0497ae3ba01..cb62837a51e 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
@@ -44,17 +44,13 @@ void SimTest::SetUp() {
compositor_ = std::make_unique<SimCompositor>();
web_frame_client_ =
std::make_unique<frame_test_helpers::TestWebFrameClient>();
- web_widget_client_ =
- std::make_unique<frame_test_helpers::TestWebWidgetClient>(
- compositor_.get());
web_view_client_ = std::make_unique<frame_test_helpers::TestWebViewClient>();
page_ = std::make_unique<SimPage>();
web_view_helper_ = std::make_unique<frame_test_helpers::WebViewHelper>();
web_view_helper_->Initialize(web_frame_client_.get(), web_view_client_.get(),
- web_widget_client_.get());
- compositor_->SetWebView(WebView(), *web_widget_client_->layer_tree_host(),
- *web_view_client_, *web_widget_client_);
+ compositor_.get());
+ compositor_->SetWebView(WebView(), *web_view_client_);
page_->SetPage(WebView().GetPage());
}
@@ -67,7 +63,6 @@ void SimTest::TearDown() {
web_view_helper_.reset();
page_.reset();
web_view_client_.reset();
- web_widget_client_.reset();
web_frame_client_.reset();
compositor_.reset();
network_.reset();
@@ -109,7 +104,7 @@ frame_test_helpers::TestWebViewClient& SimTest::WebViewClient() {
}
frame_test_helpers::TestWebWidgetClient& SimTest::WebWidgetClient() {
- return *web_widget_client_;
+ return *compositor_;
}
frame_test_helpers::TestWebFrameClient& SimTest::WebFrameClient() {
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 b235acbaa2f..b7393990433 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
@@ -51,7 +51,6 @@ class SimTest : public testing::Test {
std::unique_ptr<SimNetwork> network_;
std::unique_ptr<SimCompositor> compositor_;
std::unique_ptr<frame_test_helpers::TestWebFrameClient> web_frame_client_;
- std::unique_ptr<frame_test_helpers::TestWebWidgetClient> web_widget_client_;
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_;
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 cabd8d7f17e..8110a6e75d2 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(blink::Visitor* visitor) {
+void StaticSelection::Trace(Visitor* visitor) {
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 e52cd7a3011..2d17e1a3e94 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
const Member<Node> anchor_node_;
diff --git a/chromium/third_party/blink/renderer/core/testing/type_conversions.h b/chromium/third_party/blink/renderer/core/testing/type_conversions.h
index 515a3980f51..50f8fc87f65 100644
--- a/chromium/third_party/blink/renderer/core/testing/type_conversions.h
+++ b/chromium/third_party/blink/renderer/core/testing/type_conversions.h
@@ -28,6 +28,7 @@
#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/wtf/text/wtf_string.h"
namespace blink {
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 7e52d358690..24f92480788 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
@@ -29,6 +29,7 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_origin_trials_test.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/testing/internal_settings.h"
#include "third_party/blink/renderer/core/testing/internals.h"
@@ -128,10 +129,8 @@ void ResetInternalsObject(v8::Local<v8::Context> context) {
ScriptState* script_state = ScriptState::From(context);
ScriptState::Scope scope(script_state);
- Document* document = To<Document>(ExecutionContext::From(script_state));
- DCHECK(document);
- LocalFrame* frame = document->GetFrame();
- // Should the document have been detached, the page is assumed being destroyed
+ LocalFrame* frame = LocalDOMWindow::From(script_state)->GetFrame();
+ // Should the frame have been detached, the page is assumed being destroyed
// (=> no reset required.)
if (!frame)
return;
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 a8f528111f3..d4a2da07d86 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
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/core/testing/wait_for_event.h"
+#include "third_party/blink/renderer/platform/heap/thread_state_scopes.h"
#include "third_party/blink/renderer/core/dom/element.h"
@@ -11,6 +12,7 @@ namespace blink {
WaitForEvent::WaitForEvent(Element* element, const AtomicString& name)
: element_(element), event_name_(name) {
element_->addEventListener(event_name_, this);
+ ThreadState::HeapPointersOnStackScope scan_stack(ThreadState::Current());
run_loop_.Run();
}
diff --git a/chromium/third_party/blink/renderer/core/timezone/DEPS b/chromium/third_party/blink/renderer/core/timezone/DEPS
index 3fcb405abb2..c4ef22c4263 100644
--- a/chromium/third_party/blink/renderer/core/timezone/DEPS
+++ b/chromium/third_party/blink/renderer/core/timezone/DEPS
@@ -1,7 +1,5 @@
include_rules = [
- "+mojo/public/cpp/bindings/binding.h",
"+services/device/public/mojom/time_zone_monitor.mojom-blink.h",
- "+services/device/public/mojom/constants.mojom-blink.h",
"+third_party/icu/source/common/unicode/char16ptr.h",
"+third_party/icu/source/i18n/unicode/timezone.h",
]
diff --git a/chromium/third_party/blink/renderer/core/timezone/timezone_controller.cc b/chromium/third_party/blink/renderer/core/timezone/timezone_controller.cc
index a03e0b81391..1600d8e07c6 100644
--- a/chromium/third_party/blink/renderer/core/timezone/timezone_controller.cc
+++ b/chromium/third_party/blink/renderer/core/timezone/timezone_controller.cc
@@ -6,16 +6,21 @@
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
-#include "services/device/public/mojom/constants.mojom-blink.h"
#include "services/service_manager/public/cpp/connector.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/task_type.h"
+#include "third_party/blink/public/web/web_local_frame.h"
+#include "third_party/blink/renderer/core/frame/frame.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/page.h"
#include "third_party/blink/renderer/core/workers/worker_backing_thread.h"
#include "third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h"
#include "third_party/blink/renderer/core/workers/worker_thread.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
#include "third_party/blink/renderer/platform/mojo/mojo_helper.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/icu/source/common/unicode/char16ptr.h"
#include "third_party/icu/source/i18n/unicode/timezone.h"
#include "v8/include/v8.h"
@@ -33,6 +38,11 @@ void NotifyTimezoneChangeToV8(v8::Isolate* isolate) {
void NotifyTimezoneChangeOnWorkerThread(WorkerThread* worker_thread) {
DCHECK(worker_thread->IsCurrentThread());
NotifyTimezoneChangeToV8(worker_thread->GlobalScope()->GetIsolate());
+ if (RuntimeEnabledFeatures::TimeZoneChangeEventEnabled() &&
+ worker_thread->GlobalScope()->IsWorkerGlobalScope()) {
+ worker_thread->GlobalScope()->DispatchEvent(
+ *Event::Create(event_type_names::kTimezonechange));
+ }
}
String GetTimezoneId(const icu::TimeZone& timezone) {
@@ -48,6 +58,21 @@ String GetCurrentTimezoneId() {
return GetTimezoneId(*timezone.get());
}
+void DispatchTimeZoneChangeEventToFrames() {
+ if (!RuntimeEnabledFeatures::TimeZoneChangeEventEnabled())
+ return;
+
+ for (const Page* page : Page::OrdinaryPages()) {
+ for (Frame* frame = page->MainFrame(); frame;
+ frame = frame->Tree().TraverseNext()) {
+ if (auto* main_local_frame = DynamicTo<LocalFrame>(frame)) {
+ main_local_frame->DomWindow()->DispatchEvent(
+ *Event::Create(event_type_names::kTimezonechange));
+ }
+ }
+ }
+}
+
bool SetIcuTimeZoneAndNotifyV8(const String& timezone_id) {
DCHECK(!timezone_id.IsEmpty());
std::unique_ptr<icu::TimeZone> timezone(icu::TimeZone::createTimeZone(
@@ -62,6 +87,7 @@ bool SetIcuTimeZoneAndNotifyV8(const String& timezone_id) {
NotifyTimezoneChangeToV8(V8PerIsolateData::MainThreadIsolate());
WorkerThread::CallOnAllWorkerThreads(&NotifyTimezoneChangeOnWorkerThread,
TaskType::kInternalDefault);
+ DispatchTimeZoneChangeEventToFrames();
return true;
}
@@ -76,12 +102,16 @@ TimeZoneController::~TimeZoneController() = default;
// static
void TimeZoneController::Init() {
- // Some unit tests may have no message loop ready, so we can't initialize the
- // mojo stuff here. They can initialize those mojo stuff they're interested in
- // later after they got a message loop ready.
+ // TODO(crbug.com/660274): The unit tests should not require this exception.
+ // Currently some unit tests have no message loop ready, so we can't
+ // initialize the mojo stuff here. They can initialize those mojo stuff
+ // they're interested in later after they got a message loop ready.
if (!CanInitializeMojo())
return;
+ // monitor must not use HeapMojoRemote. TimeZoneController is not managed by
+ // Oilpan. monitor is only used to bind receiver_ here and never used
+ // again.
mojo::Remote<device::mojom::blink::TimeZoneMonitor> monitor;
Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
monitor.BindNewPipeAndPassReceiver());
@@ -107,7 +137,6 @@ TimeZoneController::SetTimeZoneOverride(const String& timezone_id) {
VLOG(1) << "Invalid override timezone id: " << timezone_id;
return nullptr;
}
-
instance().has_timezone_id_override_ = true;
return std::unique_ptr<TimeZoneOverride>(new TimeZoneOverride());
@@ -139,4 +168,9 @@ void TimeZoneController::OnTimeZoneChange(const String& timezone_id) {
SetIcuTimeZoneAndNotifyV8(timezone_id);
}
+// static
+void TimeZoneController::ChangeTimeZoneForTesting(const String& timezone) {
+ instance().OnTimeZoneChange(timezone);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/timezone/timezone_controller.h b/chromium/third_party/blink/renderer/core/timezone/timezone_controller.h
index 89978bdf38c..3de7c232cd1 100644
--- a/chromium/third_party/blink/renderer/core/timezone/timezone_controller.h
+++ b/chromium/third_party/blink/renderer/core/timezone/timezone_controller.h
@@ -43,6 +43,8 @@ class CORE_EXPORT TimeZoneController final
static bool HasTimeZoneOverride();
+ static void ChangeTimeZoneForTesting(const String&);
+
private:
TimeZoneController();
static TimeZoneController& instance();
@@ -51,6 +53,8 @@ class CORE_EXPORT TimeZoneController final
// device::mojom::blink::TimeZoneMonitorClient:
void OnTimeZoneChange(const String& timezone_id) override;
+ // receiver_ must not use HeapMojoReceiver. TimeZoneController is not managed
+ // by Oilpan.
mojo::Receiver<device::mojom::blink::TimeZoneMonitorClient> receiver_{this};
String host_timezone_id_;
diff --git a/chromium/third_party/blink/renderer/core/timing/BUILD.gn b/chromium/third_party/blink/renderer/core/timing/BUILD.gn
index eb2242f6d90..05dde8fa2da 100644
--- a/chromium/third_party/blink/renderer/core/timing/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/timing/BUILD.gn
@@ -14,6 +14,8 @@ blink_core_sources("timing") {
"largest_contentful_paint.h",
"layout_shift.cc",
"layout_shift.h",
+ "measure_memory/measure_memory_delegate.cc",
+ "measure_memory/measure_memory_delegate.h",
"memory_info.cc",
"memory_info.h",
"performance.cc",
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 e156972b1a2..38bbebce582 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(blink::Visitor* visitor) {
+void DOMWindowPerformance::Trace(Visitor* visitor) {
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 af829ec524e..54d282f254e 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
WindowPerformance* performance();
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 f45a5a3c10c..693a61a0140 100644
--- a/chromium/third_party/blink/renderer/core/timing/event_timing.cc
+++ b/chromium/third_party/blink/renderer/core/timing/event_timing.cc
@@ -6,7 +6,10 @@
#include "base/time/tick_clock.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/events/keyboard_event.h"
#include "third_party/blink/renderer/core/events/pointer_event.h"
+#include "third_party/blink/renderer/core/events/touch_event.h"
+#include "third_party/blink/renderer/core/events/wheel_event.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/loader/interactive_detector.h"
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
@@ -33,9 +36,9 @@ bool ShouldLogEvent(const Event& event) {
}
bool IsEventTypeForEventTiming(const Event& event) {
- return (event.IsMouseEvent() || event.IsPointerEvent() ||
- event.IsTouchEvent() || event.IsKeyboardEvent() ||
- event.IsWheelEvent() || event.IsInputEvent() ||
+ return (IsA<MouseEvent>(event) || IsA<PointerEvent>(event) ||
+ IsA<TouchEvent>(event) || IsA<KeyboardEvent>(event) ||
+ IsA<WheelEvent>(event) || event.IsInputEvent() ||
event.IsCompositionEvent()) &&
event.isTrusted();
}
@@ -72,14 +75,15 @@ std::unique_ptr<EventTiming> EventTiming::Create(LocalDOMWindow* window,
if (!should_report_for_event_timing && !should_log_event)
return nullptr;
+ auto* pointer_event = DynamicTo<PointerEvent>(&event);
base::TimeTicks event_timestamp =
- event.IsPointerEvent() ? ToPointerEvent(&event)->OldestPlatformTimeStamp()
- : event.PlatformTimeStamp();
+ pointer_event ? pointer_event->OldestPlatformTimeStamp()
+ : event.PlatformTimeStamp();
base::TimeTicks processing_start = Now();
if (should_log_event) {
Document* document =
- DynamicTo<Document>(performance->GetExecutionContext());
+ Document::DynamicFrom(performance->GetExecutionContext());
InteractiveDetector* interactive_detector =
InteractiveDetector::From(*document);
if (interactive_detector) {
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 a9fb62cdc70..59dc537a024 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(blink::Visitor* visitor) {
+void LargestContentfulPaint::Trace(Visitor* visitor) {
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 ae34beaeaa8..1c0e66fd233 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
@@ -36,7 +36,7 @@ class CORE_EXPORT LargestContentfulPaint final : public PerformanceEntry {
const String& url() const { return url_; }
Element* element() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 fd228888103..419dcb34c44 100644
--- a/chromium/third_party/blink/renderer/core/timing/layout_shift.cc
+++ b/chromium/third_party/blink/renderer/core/timing/layout_shift.cc
@@ -36,7 +36,7 @@ void LayoutShift::BuildJSONValue(V8ObjectBuilder& builder) const {
builder.Add("lastInputTime", most_recent_input_timestamp_);
}
-void LayoutShift::Trace(blink::Visitor* visitor) {
+void LayoutShift::Trace(Visitor* visitor) {
PerformanceEntry::Trace(visitor);
}
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 d9dc5a0aa9a..65479493b8b 100644
--- a/chromium/third_party/blink/renderer/core/timing/layout_shift.h
+++ b/chromium/third_party/blink/renderer/core/timing/layout_shift.h
@@ -30,7 +30,7 @@ class CORE_EXPORT LayoutShift final : public PerformanceEntry {
bool hadRecentInput() const { return had_recent_input_; }
double lastInputTime() const { return most_recent_input_timestamp_; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void BuildJSONValue(V8ObjectBuilder&) const override;
diff --git a/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory.idl b/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory.idl
index c2b4a4be92f..d319cef8df4 100644
--- a/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory.idl
+++ b/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory.idl
@@ -2,11 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://github.com/ulan/javascript-agent-memory/blob/master/explainer.md
+// https://github.com/WICG/performance-measure-memory
// The result of performance.measureMemory().
dictionary MeasureMemory {
- required MeasureMemoryEntry total;
- MeasureMemoryEntry current;
- sequence<MeasureMemoryEntry> other;
+ required unsigned long long bytes;
+ required sequence<MeasureMemoryBreakdown> breakdown;
};
diff --git a/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_breakdown.idl b/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_breakdown.idl
new file mode 100644
index 00000000000..e90820e6bda
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_breakdown.idl
@@ -0,0 +1,12 @@
+// 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/ulan/performance-measure-memory.
+
+// A single entry of performance.measureMemory() result.
+dictionary MeasureMemoryBreakdown {
+ unsigned long long bytes;
+ sequence<DOMString> attribution;
+ sequence<DOMString> userAgentSpecificTypes;
+};
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
new file mode 100644
index 00000000000..dab967eed09
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.cc
@@ -0,0 +1,224 @@
+// 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/timing/measure_memory/measure_memory_delegate.h"
+
+#include "third_party/blink/public/platform/platform.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/local_frame.h"
+#include "third_party/blink/renderer/core/page/frame_tree.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"
+
+namespace blink {
+
+MeasureMemoryDelegate::MeasureMemoryDelegate(
+ v8::Isolate* isolate,
+ v8::Local<v8::Context> context,
+ v8::Local<v8::Promise::Resolver> promise_resolver)
+ : isolate_(isolate),
+ context_(isolate, context),
+ promise_resolver_(isolate, promise_resolver) {
+ context_.SetPhantom();
+ // TODO(ulan): Currently we keep a strong reference to the promise resolver.
+ // This may prolong the lifetime of the context by one more GC in the worst
+ // case as JSPromise keeps its context alive.
+ // To avoid that we should store the promise resolver in V8PerContextData.
+}
+
+// Returns true if the given context should be included in the current memory
+// measurement. Currently it is very conservative and allows only the same
+// origin contexts that belong to the same JavaScript origin.
+// With COOP/COEP we will be able to relax this restriction for the contexts
+// that opt-in into memory measurement.
+bool MeasureMemoryDelegate::ShouldMeasure(v8::Local<v8::Context> context) {
+ if (context_.IsEmpty()) {
+ // The original context was garbage collected in the meantime.
+ return false;
+ }
+ v8::Local<v8::Context> original_context = context_.NewLocal(isolate_);
+ ExecutionContext* original_execution_context =
+ ExecutionContext::From(original_context);
+ ExecutionContext* execution_context = ExecutionContext::From(context);
+ if (!original_execution_context || !execution_context) {
+ // One of the contexts is detached or is created by DevTools.
+ return false;
+ }
+ if (original_execution_context->GetAgent() != execution_context->GetAgent()) {
+ // Context do not belong to the same JavaScript agent.
+ return false;
+ }
+ if (ScriptState::From(context)->World().IsIsolatedWorld()) {
+ // Context belongs to an extension. Skip it.
+ return false;
+ }
+ const SecurityOrigin* original_security_origin =
+ original_execution_context->GetSecurityContext().GetSecurityOrigin();
+ const SecurityOrigin* security_origin =
+ execution_context->GetSecurityContext().GetSecurityOrigin();
+ if (!original_security_origin->IsSameOriginWith(security_origin)) {
+ // TODO(ulan): Check for COOP/COEP and allow cross-origin contexts that
+ // opted in for memory measurement.
+ // Until then we allow cross-origin measurement only for site-isolated
+ // web pages.
+ return Platform::Current()->IsLockedToSite();
+ }
+ return true;
+}
+
+namespace {
+// Helper functions for constructing a memory measurement result.
+
+const LocalFrame* GetFrame(v8::Local<v8::Context> context) {
+ ExecutionContext* execution_context = ExecutionContext::From(context);
+ if (!execution_context) {
+ // The context was detached. Ignore it.
+ return nullptr;
+ }
+ DCHECK(execution_context->IsDocument());
+ return Document::From(execution_context)->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();
+}
+
+// To avoid information leaks cross-origin iframes are considered opaque for
+// the purposes of attribution. This means the memory of all iframes nested
+// 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.
+//
+// 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())
+ result = frame;
+ frame = To<LocalFrame>(frame->Tree().Parent());
+ }
+ 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;
+ for (const auto& context_size : context_sizes) {
+ const LocalFrame* frame =
+ GetAttributionFrame(main_frame, context_size.first);
+ if (!frame) {
+ // The context was detached. Ignore it.
+ continue;
+ }
+ auto it = per_frame.find(frame);
+ if (it == per_frame.end()) {
+ per_frame.insert(frame, context_size.second);
+ } else {
+ it->value += context_size.second;
+ }
+ }
+ return per_frame;
+}
+
+MeasureMemoryBreakdown* CreateMeasureMemoryBreakdown(
+ size_t bytes,
+ const Vector<String>& types,
+ const String& url) {
+ MeasureMemoryBreakdown* result = MeasureMemoryBreakdown::Create();
+ result->setBytes(bytes);
+ result->setUserAgentSpecificTypes(types);
+ result->setAttribution(url.length() ? Vector<String>{url} : Vector<String>());
+ return result;
+}
+
+} // anonymous namespace
+
+// Constructs a memory measurement result based on the given list of (context,
+// size) pairs and resolves the promise.
+void MeasureMemoryDelegate::MeasurementComplete(
+ const std::vector<std::pair<v8::Local<v8::Context>, size_t>>& context_sizes,
+ size_t unattributed_size) {
+ if (context_.IsEmpty()) {
+ // The context was garbage collected in the meantime.
+ return;
+ }
+ v8::Local<v8::Context> context = context_.NewLocal(isolate_);
+ const LocalFrame* frame = GetFrame(context);
+ if (!frame) {
+ // The context was detached in the meantime.
+ return;
+ }
+ DCHECK(frame->IsMainFrame());
+ v8::Context::Scope context_scope(context);
+ size_t total_size = 0;
+ for (const auto& context_size : context_sizes) {
+ total_size += context_size.second;
+ }
+ 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 attributed_size = 0;
+ const String kWindow("Window");
+ const String kJS("JS");
+ for (const auto& it : per_frame) {
+ attributed_size += it.value;
+ 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}, ""));
+ result->setBreakdown(breakdown);
+ v8::Local<v8::Promise::Resolver> promise_resolver =
+ promise_resolver_.NewLocal(isolate_);
+ promise_resolver->Resolve(context, ToV8(result, promise_resolver, isolate_))
+ .ToChecked();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.h b/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.h
new file mode 100644
index 00000000000..8a1be304877
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.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_TIMING_MEASURE_MEMORY_MEASURE_MEMORY_DELEGATE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_MEASURE_MEMORY_MEASURE_MEMORY_DELEGATE_H_
+
+#include "third_party/blink/renderer/platform/bindings/scoped_persistent.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+// Specifies V8 contexts to be measured and resolves the promise once V8
+// completes the memory measurement.
+class MeasureMemoryDelegate : public v8::MeasureMemoryDelegate {
+ public:
+ MeasureMemoryDelegate(v8::Isolate* isolate,
+ v8::Local<v8::Context> context,
+ v8::Local<v8::Promise::Resolver> promise_resolver);
+
+ // v8::MeasureMemoryDelegate overrides.
+ bool ShouldMeasure(v8::Local<v8::Context> context) override;
+ void MeasurementComplete(
+ const std::vector<std::pair<v8::Local<v8::Context>, size_t>>&
+ context_sizes,
+ size_t unattributed_size) override;
+
+ private:
+ v8::Isolate* isolate_;
+ ScopedPersistent<v8::Context> context_;
+ ScopedPersistent<v8::Promise::Resolver> promise_resolver_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_MEASURE_MEMORY_MEASURE_MEMORY_DELEGATE_H_
diff --git a/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_entry.idl b/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_entry.idl
deleted file mode 100644
index cc49ed29f66..00000000000
--- a/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_entry.idl
+++ /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.
-
-// https://github.com/ulan/javascript-agent-memory/blob/master/explainer.md
-
-// A single entry of performance.measureMemory() result.
-dictionary MeasureMemoryEntry {
- unsigned long long jsMemoryEstimate;
- sequence<unsigned long long> jsMemoryRange;
-};
diff --git a/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_options.idl b/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_options.idl
deleted file mode 100644
index d4ed317aff5..00000000000
--- a/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_options.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.
-
-// https://github.com/ulan/javascript-agent-memory/blob/master/explainer.md
-
-// Options for performance.measureMemory().
-dictionary MeasureMemoryOptions {
- boolean detailed;
-};
diff --git a/chromium/third_party/blink/renderer/core/timing/performance.cc b/chromium/third_party/blink/renderer/core/timing/performance.cc
index 658840e79c4..90e1f4a4d68 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance.cc
@@ -32,6 +32,7 @@
#include "third_party/blink/renderer/core/timing/performance.h"
#include <algorithm>
+
#include "base/metrics/histogram_macros.h"
#include "base/time/default_clock.h"
#include "base/time/default_tick_clock.h"
@@ -41,6 +42,9 @@
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_performance_measure_options.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_performance_mark_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_performance_measure_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_profiler_init_options.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_exception.h"
@@ -52,21 +56,19 @@
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/timing/largest_contentful_paint.h"
#include "third_party/blink/renderer/core/timing/layout_shift.h"
-#include "third_party/blink/renderer/core/timing/measure_memory/measure_memory_options.h"
+#include "third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.h"
#include "third_party/blink/renderer/core/timing/performance_element_timing.h"
#include "third_party/blink/renderer/core/timing/performance_event_timing.h"
#include "third_party/blink/renderer/core/timing/performance_long_task_timing.h"
#include "third_party/blink/renderer/core/timing/performance_mark.h"
-#include "third_party/blink/renderer/core/timing/performance_mark_options.h"
#include "third_party/blink/renderer/core/timing/performance_measure.h"
-#include "third_party/blink/renderer/core/timing/performance_measure_options.h"
#include "third_party/blink/renderer/core/timing/performance_observer.h"
#include "third_party/blink/renderer/core/timing/performance_resource_timing.h"
#include "third_party/blink/renderer/core/timing/performance_user_timing.h"
#include "third_party/blink/renderer/core/timing/profiler.h"
#include "third_party/blink/renderer/core/timing/profiler_group.h"
-#include "third_party/blink/renderer/core/timing/profiler_init_options.h"
#include "third_party/blink/renderer/core/timing/time_clamper.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/resource_load_timing.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
@@ -107,6 +109,7 @@ constexpr size_t kDefaultEventTimingBufferSize = 150;
constexpr size_t kDefaultElementTimingBufferSize = 150;
constexpr size_t kDefaultLayoutShiftBufferSize = 150;
constexpr size_t kDefaultLargestContenfulPaintSize = 150;
+constexpr size_t kDefaultLongTaskBufferSize = 200;
Performance::Performance(
base::TimeTicks time_origin,
@@ -145,19 +148,56 @@ MemoryInfo* Performance::memory() const {
return nullptr;
}
-ScriptPromise Performance::measureMemory(ScriptState* script_state,
- MeasureMemoryOptions* options) const {
+namespace {
+
+bool IsMeasureMemoryAvailable(ScriptState* script_state) {
+ // TODO(ulan): We should check for window.crossOriginIsolated when it ships.
+ // Until then we enable the API only for processes locked to a site
+ // similar to the precise mode of the legacy performance.memory API.
+ if (!Platform::Current()->IsLockedToSite()) {
+ return false;
+ }
+ // The window.crossOriginIsolated will be true only for the top-level frame.
+ // Until the flag is available we check for the top-level condition manually.
+ ExecutionContext* execution_context = ExecutionContext::From(script_state);
+ if (!execution_context->IsDocument()) {
+ return false;
+ }
+ LocalFrame* local_frame = Document::From(execution_context)->GetFrame();
+ if (!local_frame || !local_frame->IsMainFrame()) {
+ return false;
+ }
+ return true;
+}
+
+} // anonymous namespace
+
+ScriptPromise Performance::measureMemory(
+ ScriptState* script_state,
+ ExceptionState& exception_state) const {
+ if (!IsMeasureMemoryAvailable(script_state)) {
+ exception_state.ThrowSecurityError(
+ "performance.measureMemory is not available in this context");
+ return ScriptPromise();
+ }
v8::Isolate* isolate = script_state->GetIsolate();
+ v8::TryCatch try_catch(isolate);
v8::Local<v8::Context> context = script_state->GetContext();
- v8::Local<v8::Promise> promise;
- v8::MaybeLocal<v8::Promise> maybe_promise = isolate->MeasureMemory(
- context, options && options->hasDetailed() && options->detailed()
- ? v8::MeasureMemoryMode::kDetailed
- : v8::MeasureMemoryMode::kSummary);
- if (!maybe_promise.ToLocal(&promise)) {
+ v8::Local<v8::Promise::Resolver> promise_resolver;
+ if (!v8::Promise::Resolver::New(context).ToLocal(&promise_resolver)) {
+ exception_state.RethrowV8Exception(try_catch.Exception());
return ScriptPromise();
}
- return ScriptPromise(script_state, promise);
+ v8::MeasureMemoryExecution execution =
+ RuntimeEnabledFeatures::ForceEagerMeasureMemoryEnabled(
+ ExecutionContext::From(script_state))
+ ? v8::MeasureMemoryExecution::kEager
+ : v8::MeasureMemoryExecution::kDefault;
+
+ isolate->MeasureMemory(std::make_unique<MeasureMemoryDelegate>(
+ isolate, context, promise_resolver),
+ execution);
+ return ScriptPromise(script_state, promise_resolver->GetPromise());
}
DOMHighResTimeStamp Performance::timeOrigin() const {
@@ -209,8 +249,9 @@ PerformanceEntryVector Performance::getEntriesByType(
PerformanceEntryVector empty_entries;
String message = "Deprecated API for given entry type.";
GetExecutionContext()->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning, message));
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning, message));
return empty_entries;
}
return getEntriesByTypeInternal(type);
@@ -262,11 +303,11 @@ PerformanceEntryVector Performance::getEntriesByTypeInternal(
if (first_contentful_paint_timing_)
entries.push_back(first_contentful_paint_timing_);
break;
- // Unsupported for LongTask, TaskAttribution.
- // Per the spec, these entries can only be accessed via
- // Performance Observer. No separate buffer is maintained.
case PerformanceEntry::kLongTask:
+ for (const auto& entry : longtask_buffer_)
+ entries.push_back(entry);
break;
+ // TaskAttribution entries are only associated to longtask entries.
case PerformanceEntry::kTaskAttribution:
break;
case PerformanceEntry::kLayoutShift:
@@ -296,8 +337,9 @@ PerformanceEntryVector Performance::getEntriesByName(
!PerformanceEntry::IsValidTimelineEntryType(type)) {
String message = "Deprecated API for given entry type.";
GetExecutionContext()->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning, message));
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning, message));
return entries;
}
@@ -460,32 +502,41 @@ void Performance::GenerateAndAddResourceTiming(
info.TakeWorkerTimingReceiver());
}
-WebResourceTimingInfo Performance::GenerateResourceTiming(
+mojom::blink::ResourceTimingInfoPtr Performance::GenerateResourceTiming(
const SecurityOrigin& destination_origin,
const ResourceTimingInfo& info,
ExecutionContext& context_for_use_counter) {
// TODO(dcheng): It would be nicer if the performance entries simply held this
// data internally, rather than requiring it be marshalled back and forth.
const ResourceResponse& final_response = info.FinalResponse();
- WebResourceTimingInfo result;
- result.name = info.InitialURL().GetString();
- result.start_time = info.InitialTime();
- result.alpn_negotiated_protocol = final_response.AlpnNegotiatedProtocol();
- result.connection_info = final_response.ConnectionInfoString();
- result.timing = final_response.GetResourceLoadTiming();
- result.response_end = info.LoadResponseEnd();
- result.context_type = info.ContextType();
+ mojom::blink::ResourceTimingInfoPtr result =
+ mojom::blink::ResourceTimingInfo::New();
+ result->name = info.InitialURL().GetString();
+ result->start_time = info.InitialTime();
+ result->alpn_negotiated_protocol =
+ final_response.AlpnNegotiatedProtocol().IsNull()
+ ? g_empty_string
+ : final_response.AlpnNegotiatedProtocol();
+ result->connection_info = final_response.ConnectionInfoString().IsNull()
+ ? g_empty_string
+ : final_response.ConnectionInfoString();
+ result->timing = final_response.GetResourceLoadTiming()
+ ? final_response.GetResourceLoadTiming()->ToMojo()
+ : nullptr;
+ result->response_end = info.LoadResponseEnd();
+ result->context_type = info.ContextType();
+ result->request_destination = info.RequestDestination();
bool response_tainting_not_basic = false;
bool tainted_origin_flag = false;
- result.allow_timing_details = PassesTimingAllowCheck(
+ result->allow_timing_details = PassesTimingAllowCheck(
final_response, final_response, destination_origin,
&context_for_use_counter, &response_tainting_not_basic,
&tainted_origin_flag);
const Vector<ResourceResponse>& redirect_chain = info.RedirectChain();
if (!redirect_chain.IsEmpty()) {
- result.allow_redirect_details =
+ result->allow_redirect_details =
AllowsTimingRedirect(redirect_chain, final_response, destination_origin,
&context_for_use_counter);
@@ -493,38 +544,39 @@ WebResourceTimingInfo Performance::GenerateResourceTiming(
// or is this if statement reasonable?
if (ResourceLoadTiming* last_chained_timing =
redirect_chain.back().GetResourceLoadTiming()) {
- result.last_redirect_end_time = last_chained_timing->ReceiveHeadersEnd();
+ result->last_redirect_end_time = last_chained_timing->ReceiveHeadersEnd();
} else {
- result.allow_redirect_details = false;
- result.last_redirect_end_time = base::TimeTicks();
+ result->allow_redirect_details = false;
+ result->last_redirect_end_time = base::TimeTicks();
}
- if (!result.allow_redirect_details) {
+ if (!result->allow_redirect_details) {
// TODO(https://crbug.com/817691): There was previously a DCHECK that
// |final_timing| is non-null. However, it clearly can be null: removing
// this check caused https://crbug.com/803811. Figure out how this can
// happen so test coverage can be added.
if (ResourceLoadTiming* final_timing =
final_response.GetResourceLoadTiming()) {
- result.start_time = final_timing->RequestTime();
+ result->start_time = final_timing->RequestTime();
}
}
} else {
- result.allow_redirect_details = false;
- result.last_redirect_end_time = base::TimeTicks();
+ result->allow_redirect_details = false;
+ result->last_redirect_end_time = base::TimeTicks();
}
- result.transfer_size = info.TransferSize();
- result.encoded_body_size = final_response.EncodedBodyLength();
- result.decoded_body_size = final_response.DecodedBodyLength();
- result.did_reuse_connection = final_response.ConnectionReused();
- result.is_secure_context =
+ result->transfer_size = info.TransferSize();
+ result->encoded_body_size = final_response.EncodedBodyLength();
+ result->decoded_body_size = final_response.DecodedBodyLength();
+ result->did_reuse_connection = final_response.ConnectionReused();
+ result->is_secure_context =
SecurityOrigin::IsSecure(final_response.ResponseUrl());
- result.allow_negative_values = info.NegativeAllowed();
+ result->allow_negative_values = info.NegativeAllowed();
- if (result.allow_timing_details) {
- result.server_timing = PerformanceServerTiming::ParseServerTiming(info);
+ if (result->allow_timing_details) {
+ result->server_timing =
+ PerformanceServerTiming::ParseServerTimingToMojo(info);
}
- if (!result.server_timing.empty()) {
+ if (!result->server_timing.IsEmpty()) {
UseCounter::Count(&context_for_use_counter,
WebFeature::kPerformanceServerTiming);
}
@@ -533,12 +585,12 @@ WebResourceTimingInfo Performance::GenerateResourceTiming(
}
void Performance::AddResourceTiming(
- const WebResourceTimingInfo& info,
+ mojom::blink::ResourceTimingInfoPtr info,
const AtomicString& initiator_type,
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
worker_timing_receiver) {
auto* entry = MakeGarbageCollected<PerformanceResourceTiming>(
- info, time_origin_, initiator_type, std::move(worker_timing_receiver));
+ *info, time_origin_, initiator_type, std::move(worker_timing_receiver));
NotifyObserversOfEntry(*entry);
// https://w3c.github.io/resource-timing/#dfn-add-a-performanceresourcetiming-entry
if (CanAddResourceTimingEntry() &&
@@ -660,10 +712,16 @@ void Performance::AddLongTaskTiming(base::TimeTicks start_time,
if (!HasObserverFor(PerformanceEntry::kLongTask))
return;
+ UseCounter::Count(GetExecutionContext(), WebFeature::kLongTaskObserver);
auto* entry = MakeGarbageCollected<PerformanceLongTaskTiming>(
MonotonicTimeToDOMHighResTimeStamp(start_time),
MonotonicTimeToDOMHighResTimeStamp(end_time), name, container_type,
container_src, container_id, container_name);
+ if (longtask_buffer_.size() < kDefaultLongTaskBufferSize) {
+ longtask_buffer_.push_back(entry);
+ } else {
+ UseCounter::Count(GetExecutionContext(), WebFeature::kLongTaskBufferFull);
+ }
NotifyObserversOfEntry(*entry);
}
@@ -853,14 +911,12 @@ ScriptPromise Performance::profile(ScriptState* script_state,
void Performance::RegisterPerformanceObserver(PerformanceObserver& observer) {
observer_filter_options_ |= observer.FilterOptions();
observers_.insert(&observer);
- UpdateLongTaskInstrumentation();
}
void Performance::UnregisterPerformanceObserver(
PerformanceObserver& old_observer) {
observers_.erase(&old_observer);
UpdatePerformanceObserverFilterOptions();
- UpdateLongTaskInstrumentation();
}
void Performance::UpdatePerformanceObserverFilterOptions() {
@@ -868,7 +924,6 @@ void Performance::UpdatePerformanceObserverFilterOptions() {
for (const auto& observer : observers_) {
observer_filter_options_ |= observer->FilterOptions();
}
- UpdateLongTaskInstrumentation();
}
void Performance::NotifyObserversOfEntry(PerformanceEntry& entry) const {
@@ -885,12 +940,6 @@ void Performance::NotifyObserversOfEntry(PerformanceEntry& entry) const {
UseCounter::Count(GetExecutionContext(), WebFeature::kPaintTimingObserved);
}
-void Performance::NotifyObserversOfEntries(PerformanceEntryVector& entries) {
- for (const auto& entry : entries) {
- NotifyObserversOfEntry(*entry.Get());
- }
-}
-
bool Performance::HasObserverFor(
PerformanceEntry::EntryType filter_type) const {
return observer_filter_options_ & filter_type;
@@ -900,32 +949,24 @@ void Performance::ActivateObserver(PerformanceObserver& observer) {
if (active_observers_.IsEmpty())
deliver_observations_timer_.StartOneShot(base::TimeDelta(), FROM_HERE);
+ if (suspended_observers_.Contains(&observer))
+ suspended_observers_.erase(&observer);
active_observers_.insert(&observer);
}
-void Performance::ResumeSuspendedObservers() {
- if (suspended_observers_.IsEmpty())
+void Performance::SuspendObserver(PerformanceObserver& observer) {
+ DCHECK(!suspended_observers_.Contains(&observer));
+ if (!active_observers_.Contains(&observer))
return;
-
- PerformanceObserverVector suspended;
- CopyToVector(suspended_observers_, suspended);
- for (wtf_size_t i = 0; i < suspended.size(); ++i) {
- if (!suspended[i]->ShouldBeSuspended()) {
- suspended_observers_.erase(suspended[i]);
- ActivateObserver(*suspended[i]);
- }
- }
+ active_observers_.erase(&observer);
+ suspended_observers_.insert(&observer);
}
void Performance::DeliverObservationsTimerFired(TimerBase*) {
decltype(active_observers_) observers;
active_observers_.Swap(observers);
- for (const auto& observer : observers) {
- if (observer->ShouldBeSuspended())
- suspended_observers_.insert(observer);
- else
- observer->Deliver();
- }
+ for (const auto& observer : observers)
+ observer->Deliver();
}
// static
@@ -972,13 +1013,14 @@ void Performance::BuildJSONValue(V8ObjectBuilder& builder) const {
// |memory| is not part of the spec, omitted.
}
-void Performance::Trace(blink::Visitor* visitor) {
+void Performance::Trace(Visitor* visitor) {
visitor->Trace(resource_timing_buffer_);
visitor->Trace(resource_timing_secondary_buffer_);
visitor->Trace(element_timing_buffer_);
visitor->Trace(event_timing_buffer_);
visitor->Trace(layout_shift_buffer_);
visitor->Trace(largest_contentful_paint_buffer_);
+ visitor->Trace(longtask_buffer_);
visitor->Trace(navigation_timing_);
visitor->Trace(user_timing_);
visitor->Trace(first_paint_timing_);
diff --git a/chromium/third_party/blink/renderer/core/timing/performance.h b/chromium/third_party/blink/renderer/core/timing/performance.h
index 3625ed0ab33..865d975beeb 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance.h
@@ -33,7 +33,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_PERFORMANCE_H_
#include "base/single_thread_task_runner.h"
-#include "third_party/blink/public/platform/web_resource_timing_info.h"
+#include "third_party/blink/public/mojom/timing/resource_timing.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_double.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/dom_high_res_time_stamp.h"
@@ -61,7 +61,6 @@ class PerformanceMarkOptions;
class ExceptionState;
class LargestContentfulPaint;
class LayoutShift;
-class MeasureMemoryOptions;
class MemoryInfo;
class PerformanceElementTiming;
class PerformanceEventTiming;
@@ -97,9 +96,7 @@ class CORE_EXPORT Performance : public EventTargetWithInlineData {
virtual PerformanceNavigation* navigation() const;
virtual MemoryInfo* memory() const;
virtual ScriptPromise measureMemory(ScriptState*,
- MeasureMemoryOptions*) const;
-
- virtual void UpdateLongTaskInstrumentation() {}
+ ExceptionState& exception_state) const;
// Reduce the resolution to prevent timing attacks. See:
// http://www.w3.org/TR/hr-time-2/#privacy-security
@@ -161,12 +158,12 @@ class CORE_EXPORT Performance : public EventTargetWithInlineData {
// Generates timing info suitable for appending to the performance entries of
// a context with |origin|. This should be rarely used; most callsites should
// prefer the convenience method |GenerateAndAddResourceTiming()|.
- static WebResourceTimingInfo GenerateResourceTiming(
+ static mojom::blink::ResourceTimingInfoPtr GenerateResourceTiming(
const SecurityOrigin& destination_origin,
const ResourceTimingInfo&,
ExecutionContext& context_for_use_counter);
void AddResourceTiming(
- const WebResourceTimingInfo&,
+ mojom::blink::ResourceTimingInfoPtr,
const AtomicString& initiator_type,
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
worker_timing_receiver);
@@ -261,7 +258,7 @@ class CORE_EXPORT Performance : public EventTargetWithInlineData {
void RegisterPerformanceObserver(PerformanceObserver&);
void UpdatePerformanceObserverFilterOptions();
void ActivateObserver(PerformanceObserver&);
- void ResumeSuspendedObservers();
+ void SuspendObserver(PerformanceObserver&);
bool HasObserverFor(PerformanceEntry::EntryType) const;
@@ -290,7 +287,7 @@ class CORE_EXPORT Performance : public EventTargetWithInlineData {
ScriptValue toJSONForBinding(ScriptState*) const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
class UnifiedClock {
public:
@@ -346,7 +343,6 @@ class CORE_EXPORT Performance : public EventTargetWithInlineData {
void FireResourceTimingBufferFull(TimerBase*);
void NotifyObserversOfEntry(PerformanceEntry&) const;
- void NotifyObserversOfEntries(PerformanceEntryVector&);
void DeliverObservationsTimerFired(TimerBase*);
@@ -366,6 +362,7 @@ class CORE_EXPORT Performance : public EventTargetWithInlineData {
unsigned element_timing_buffer_max_size_;
PerformanceEntryVector layout_shift_buffer_;
PerformanceEntryVector largest_contentful_paint_buffer_;
+ PerformanceEntryVector longtask_buffer_;
Member<PerformanceEntry> navigation_timing_;
Member<UserTiming> user_timing_;
Member<PerformanceEntry> first_paint_timing_;
diff --git a/chromium/third_party/blink/renderer/core/timing/performance.idl b/chromium/third_party/blink/renderer/core/timing/performance.idl
index 644afd13b71..aaf65a0cc3d 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance.idl
+++ b/chromium/third_party/blink/renderer/core/timing/performance.idl
@@ -60,18 +60,18 @@ interface Performance : EventTarget {
// https://w3c.github.io/user-timing/#extensions-performance-interface
// TODO(https://crbug.com/996275): Once our IDL parser supports it, we need
// to supply a default-value of '{}' to markOptions.
- [MeasureAs=UserTiming, CallWith=ScriptState, RaisesException] PerformanceMark mark(DOMString markName, optional PerformanceMarkOptions markOptions);
+ [MeasureAs=UserTiming, CallWith=ScriptState, RaisesException] PerformanceMark mark(DOMString markName, optional PerformanceMarkOptions markOptions = {});
[MeasureAs=UserTiming] void clearMarks(optional DOMString markName);
// TODO(https://crbug.com/996275): Once our IDL parser supports it, we need
// to supply a default-value of '{}' to startOrOptions.
- [MeasureAs=UserTiming, CallWith=ScriptState, RaisesException] PerformanceMeasure measure(DOMString measureName, optional (DOMString or PerformanceMeasureOptions) startOrOptions, optional DOMString end);
+ [MeasureAs=UserTiming, CallWith=ScriptState, RaisesException] PerformanceMeasure measure(DOMString measureName, optional (DOMString or PerformanceMeasureOptions) startOrMeasureOptions = {}, optional DOMString endMark);
[MeasureAs=UserTiming] void clearMeasures(optional DOMString measureName);
// TODO(foolip): There is no spec for the Memory Info API, see blink-dev:
// https://groups.google.com/a/chromium.org/d/msg/blink-dev/g5YRCGpC9vs/b4OJz71NmPwJ
[Exposed=Window, Measure] readonly attribute MemoryInfo memory;
- [Exposed=(Window,Worker), CallWith=ScriptState, RuntimeEnabled=MeasureMemory] Promise<MeasureMemory> measureMemory(optional MeasureMemoryOptions options);
+ [MeasureAs=MeasureMemory, Exposed=Window, CallWith=ScriptState, RuntimeEnabled=MeasureMemory, RaisesException] Promise<MeasureMemory> measureMemory();
// JS Self-Profiling API
// https://github.com/WICG/js-self-profiling/
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 fb13112d563..69794a614e2 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
@@ -91,7 +91,7 @@ void PerformanceElementTiming::BuildJSONValue(V8ObjectBuilder& builder) const {
builder.Add("url", url_);
}
-void PerformanceElementTiming::Trace(blink::Visitor* visitor) {
+void PerformanceElementTiming::Trace(Visitor* visitor) {
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 ad6a994b896..682165c2441 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 0fcd3902d96..fa09ed52a68 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
@@ -78,7 +78,7 @@ void PerformanceEventTiming::BuildJSONValue(V8ObjectBuilder& builder) const {
builder.AddBoolean("cancelable", cancelable_);
}
-void PerformanceEventTiming::Trace(blink::Visitor* visitor) {
+void PerformanceEventTiming::Trace(Visitor* visitor) {
PerformanceEntry::Trace(visitor);
}
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 8680dc92b51..4ef864526ee 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
@@ -45,7 +45,7 @@ class CORE_EXPORT PerformanceEventTiming final : public PerformanceEntry {
void BuildJSONValue(V8ObjectBuilder&) const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 9c4a1b1476b..92f48fb5a25 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
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/frame/dom_window.h"
#include "third_party/blink/renderer/core/performance_entry_names.h"
#include "third_party/blink/renderer/core/timing/task_attribution_timing.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
@@ -21,7 +22,7 @@ PerformanceLongTaskTiming::PerformanceLongTaskTiming(
const String& culprit_id,
const String& culprit_name)
: PerformanceEntry(name, start_time, end_time) {
- TaskAttributionTiming* attribution_entry = TaskAttributionTiming::Create(
+ auto* attribution_entry = MakeGarbageCollected<TaskAttributionTiming>(
"unknown", culprit_type, culprit_src, culprit_id, culprit_name);
attribution_.push_back(*attribution_entry);
}
@@ -42,15 +43,12 @@ TaskAttributionVector PerformanceLongTaskTiming::attribution() const {
void PerformanceLongTaskTiming::BuildJSONValue(V8ObjectBuilder& builder) const {
PerformanceEntry::BuildJSONValue(builder);
- HeapVector<ScriptValue> attribution;
- for (unsigned i = 0; i < attribution_.size(); i++) {
- attribution.push_back(
- attribution_[i]->toJSONForBinding(builder.GetScriptState()));
- }
- builder.Add("attribution", attribution);
+ ScriptState* script_state = builder.GetScriptState();
+ builder.Add("attribution", FreezeV8Object(ToV8(attribution_, script_state),
+ script_state->GetIsolate()));
}
-void PerformanceLongTaskTiming::Trace(blink::Visitor* visitor) {
+void PerformanceLongTaskTiming::Trace(Visitor* visitor) {
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 2a97124ddea..e5abb1bb37c 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 534888b0251..f6eed565a79 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_mark.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_mark.cc
@@ -6,12 +6,11 @@
#include "third_party/blink/public/mojom/timing/performance_mark_or_measure.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_performance_mark_options.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/performance_entry_names.h"
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/core/timing/performance.h"
-#include "third_party/blink/renderer/core/timing/performance_mark_options.h"
-#include "third_party/blink/renderer/core/timing/performance_user_timing.h"
#include "third_party/blink/renderer/core/timing/worker_global_scope_performance.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
@@ -27,46 +26,61 @@ PerformanceMark::PerformanceMark(
// static
PerformanceMark* PerformanceMark::Create(ScriptState* script_state,
- const AtomicString& name,
- double start_time,
- const ScriptValue& detail,
- ExceptionState& exception_state) {
- 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;
- }
- return MakeGarbageCollected<PerformanceMark>(
- name, start_time, std::move(serialized_detail), exception_state);
-}
-
-// static
-PerformanceMark* PerformanceMark::Create(ScriptState* script_state,
const AtomicString& mark_name,
PerformanceMarkOptions* mark_options,
ExceptionState& exception_state) {
Performance* performance = nullptr;
+ bool is_worker_global_scope = false;
if (LocalDOMWindow* window = LocalDOMWindow::From(script_state)) {
performance = DOMWindowPerformance::performance(*window);
- DCHECK(performance);
} else if (auto* scope = DynamicTo<WorkerGlobalScope>(
ExecutionContext::From(script_state))) {
performance = WorkerGlobalScopePerformance::performance(*scope);
- DCHECK(performance);
+ is_worker_global_scope = true;
}
+ DCHECK(performance);
- if (performance) {
- return performance->GetUserTiming().CreatePerformanceMark(
- script_state, mark_name, mark_options, exception_state);
+ DOMHighResTimeStamp start = 0.0;
+ ScriptValue detail = ScriptValue::CreateNull(script_state->GetIsolate());
+ if (mark_options) {
+ if (mark_options->hasStartTime()) {
+ start = mark_options->startTime();
+ if (start < 0.0) {
+ exception_state.ThrowTypeError("'" + mark_name +
+ "' cannot have a negative start time.");
+ return nullptr;
+ }
+ } else {
+ start = performance->now();
+ }
+
+ detail = mark_options->detail();
+ } else {
+ start = performance->now();
+ }
+
+ if (!is_worker_global_scope &&
+ PerformanceTiming::GetAttributeMapping().Contains(mark_name)) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kSyntaxError,
+ "'" + mark_name +
+ "' is part of the PerformanceTiming interface, and "
+ "cannot be used as a mark name.");
+ 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;
}
- exception_state.ThrowTypeError(
- "PerformanceMark: no 'worker' or 'window' in current context.");
- return nullptr;
+ return MakeGarbageCollected<PerformanceMark>(
+ mark_name, start, std::move(serialized_detail), exception_state);
}
AtomicString PerformanceMark::entryType() const {
@@ -100,7 +114,7 @@ ScriptValue PerformanceMark::detail(ScriptState* script_state) {
return ScriptValue(isolate, value);
}
-void PerformanceMark::Trace(blink::Visitor* visitor) {
+void PerformanceMark::Trace(Visitor* visitor) {
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 1c4eec642a3..b4d4b5e2633 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_mark.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_mark.h
@@ -43,18 +43,17 @@ class CORE_EXPORT PerformanceMark final : public PerformanceEntry {
DEFINE_WRAPPERTYPEINFO();
public:
- static PerformanceMark* Create(ScriptState* script_state,
- const AtomicString& name,
- double start_time,
- const ScriptValue& detail,
- ExceptionState& exception_state);
-
- // This method is required by the constructor defined in performance_mark.idl.
+ // This method corresponds to the PerformanceMark constructor defined in the
+ // User Timing L3 spec
+ // (https://w3c.github.io/user-timing/#the-performancemark-constructor). It
+ // gets called as a subroutine of the `performance.mark` method as well as
+ // whenever script runs `new PerformanceMark(..)`.
static PerformanceMark* Create(ScriptState*,
const AtomicString& mark_name,
PerformanceMarkOptions*,
ExceptionState&);
+ // This constructor is only public so that MakeGarbageCollected can call it.
PerformanceMark(const AtomicString& name,
double start_time,
scoped_refptr<SerializedScriptValue>,
@@ -67,7 +66,7 @@ class CORE_EXPORT PerformanceMark final : public PerformanceEntry {
ScriptValue detail(ScriptState*);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
~PerformanceMark() override = default;
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_mark.idl b/chromium/third_party/blink/renderer/core/timing/performance_mark.idl
index b13216c38c4..c37a355b2a5 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_mark.idl
+++ b/chromium/third_party/blink/renderer/core/timing/performance_mark.idl
@@ -25,10 +25,9 @@
// https://w3c.github.io/user-timing/#performancemark
-[Exposed=(Window,Worker),
- Constructor(DOMString markName, optional PerformanceMarkOptions markOptions),
- ConstructorCallWith=ScriptState,
- RaisesException=Constructor]
-interface PerformanceMark : PerformanceEntry {
+[
+Exposed=(Window,Worker)
+] interface PerformanceMark : PerformanceEntry {
+ [MeasureAs=UserTimingL3, CallWith=ScriptState, RaisesException] constructor(DOMString markName, optional PerformanceMarkOptions markOptions = {});
[CallWith=ScriptState] readonly attribute any detail;
};
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_mark_test.cc b/chromium/third_party/blink/renderer/core/timing/performance_mark_test.cc
index 00521bbccd6..bf8ecf79c85 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_mark_test.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_mark_test.cc
@@ -7,33 +7,13 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_performance_mark_options.h"
#include "third_party/blink/renderer/core/performance_entry_names.h"
-#include "third_party/blink/renderer/core/timing/performance_mark_options.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
namespace blink {
-TEST(PerformanceMarkTest, CreateWithScriptValue) {
- V8TestingScope scope;
-
- ExceptionState& exception_state = scope.GetExceptionState();
- ScriptState* script_state = scope.GetScriptState();
- v8::Isolate* isolate = scope.GetIsolate();
- scoped_refptr<SerializedScriptValue> payload_string =
- SerializedScriptValue::Create(String("some-payload"));
- ScriptValue script_value(isolate, payload_string->Deserialize(isolate));
-
- PerformanceMark* pm = PerformanceMark::Create(script_state, "mark-name",
- /*start_time=*/0.0,
- script_value, exception_state);
-
- ASSERT_EQ(pm->entryType(), performance_entry_names::kMark);
- ASSERT_EQ(pm->EntryTypeEnum(), PerformanceEntry::EntryType::kMark);
- ASSERT_EQ(payload_string->Deserialize(isolate),
- pm->detail(script_state).V8Value());
-}
-
TEST(PerformanceMarkTest, CreateWithOptions) {
V8TestingScope scope;
@@ -49,7 +29,6 @@ TEST(PerformanceMarkTest, CreateWithOptions) {
PerformanceMark* pm = PerformanceMark::Create(script_state, "mark-name",
options, exception_state);
-
ASSERT_EQ(pm->entryType(), performance_entry_names::kMark);
ASSERT_EQ(pm->EntryTypeEnum(), PerformanceEntry::EntryType::kMark);
ASSERT_EQ(payload_string->Deserialize(isolate),
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 adb307d38f6..85a7d5b7036 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(blink::Visitor* visitor) {
+void PerformanceMeasure::Trace(Visitor* visitor) {
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 e4d7e99159e..087585d8bed 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(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) 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 c310f99320a..815fbd5ba74 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(blink::Visitor* visitor) {
+void PerformanceNavigation::Trace(Visitor* visitor) {
ScriptWrappable::Trace(visitor);
DOMWindowClient::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 730046215a4..6a7367a39d8 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_navigation.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_navigation.h
@@ -32,7 +32,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_PERFORMANCE_NAVIGATION_H_
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -63,7 +63,7 @@ class CORE_EXPORT PerformanceNavigation final : public ScriptWrappable,
ScriptValue toJSONForBinding(ScriptState*) const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 2713096d2f4..634f5451f58 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
@@ -49,15 +49,15 @@ PerformanceNavigationTiming::PerformanceNavigationTiming(
LocalFrame* frame,
ResourceTimingInfo* info,
base::TimeTicks time_origin,
- const WebVector<WebServerTimingInfo>& server_timing)
+ HeapVector<Member<PerformanceServerTiming>> server_timing)
: PerformanceResourceTiming(
info ? AtomicString(
info->FinalResponse().CurrentRequestUrl().GetString())
: g_empty_atom,
time_origin,
SecurityOrigin::IsSecure(frame->GetDocument()->Url()),
- server_timing),
- ContextClient(frame),
+ std::move(server_timing)),
+ ExecutionContextClient(frame),
resource_timing_info_(info) {
DCHECK(frame);
DCHECK(frame->GetDocument());
@@ -74,8 +74,8 @@ PerformanceEntryType PerformanceNavigationTiming::EntryTypeEnum() const {
return PerformanceEntry::EntryType::kNavigation;
}
-void PerformanceNavigationTiming::Trace(blink::Visitor* visitor) {
- ContextClient::Trace(visitor);
+void PerformanceNavigationTiming::Trace(Visitor* visitor) {
+ ExecutionContextClient::Trace(visitor);
PerformanceResourceTiming::Trace(visitor);
}
@@ -151,7 +151,7 @@ AtomicString PerformanceNavigationTiming::initiatorType() const {
bool PerformanceNavigationTiming::GetAllowRedirectDetails() const {
blink::ExecutionContext* context =
- GetFrame() ? GetFrame()->GetDocument() : nullptr;
+ GetFrame() ? GetFrame()->GetDocument()->ToExecutionContext() : nullptr;
const blink::SecurityOrigin* security_origin = nullptr;
if (context)
security_origin = context->GetSecurityOrigin();
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 8a9488eacb7..36a2dc17259 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
@@ -5,10 +5,11 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_PERFORMANCE_NAVIGATION_TIMING_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_PERFORMANCE_NAVIGATION_TIMING_H_
+#include "third_party/blink/public/mojom/timing/resource_timing.mojom-blink.h"
#include "third_party/blink/public/web/web_navigation_type.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/dom_high_res_time_stamp.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/loader/frame_loader_types.h"
#include "third_party/blink/renderer/core/timing/performance_resource_timing.h"
@@ -25,7 +26,7 @@ class ResourceLoadTiming;
class CORE_EXPORT PerformanceNavigationTiming final
: public PerformanceResourceTiming,
- public ContextClient {
+ public ExecutionContextClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(PerformanceNavigationTiming);
friend class PerformanceNavigationTimingTest;
@@ -34,9 +35,9 @@ class CORE_EXPORT PerformanceNavigationTiming final
PerformanceNavigationTiming(LocalFrame*,
ResourceTimingInfo*,
base::TimeTicks time_origin,
- const WebVector<WebServerTimingInfo>&);
+ HeapVector<Member<PerformanceServerTiming>>);
- // Attributes inheritted from PerformanceEntry.
+ // Attributes inherited from PerformanceEntry.
DOMHighResTimeStamp duration() const override;
AtomicString entryType() const override;
PerformanceEntryType EntryTypeEnum() const override;
@@ -61,7 +62,7 @@ class CORE_EXPORT PerformanceNavigationTiming final
DOMHighResTimeStamp redirectEnd() const override;
DOMHighResTimeStamp responseEnd() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 1113d681553..2031f3cd699 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_observer.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_observer.cc
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_performance_observer_callback.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_performance_observer_init.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/inspector/console_message.h"
@@ -15,12 +16,12 @@
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/core/timing/performance_entry.h"
#include "third_party/blink/renderer/core/timing/performance_observer_entry_list.h"
-#include "third_party/blink/renderer/core/timing/performance_observer_init.h"
#include "third_party/blink/renderer/core/timing/window_performance.h"
#include "third_party/blink/renderer/core/timing/worker_global_scope_performance.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.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/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/timer.h"
@@ -80,14 +81,14 @@ PerformanceObserver::PerformanceObserver(
ExecutionContext* execution_context,
Performance* performance,
V8PerformanceObserverCallback* callback)
- : ContextClient(execution_context),
- execution_context_(execution_context),
+ : ExecutionContextLifecycleStateObserver(execution_context),
callback_(callback),
performance_(performance),
filter_options_(PerformanceEntry::kInvalid),
type_(PerformanceObserverType::kUnknown),
is_registered_(false) {
DCHECK(performance_);
+ UpdateStateIfNeeded();
}
void PerformanceObserver::observe(const PerformanceObserverInit* observer_init,
@@ -123,23 +124,24 @@ void PerformanceObserver::observe(const PerformanceObserverInit* observer_init,
if (entry_type == PerformanceEntry::kInvalid) {
String message = "The entry type '" + entry_type_string +
"' does not exist or isn't supported.";
- GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning, message));
+ GetExecutionContext()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning, message));
}
entry_types |= entry_type;
}
if (entry_types == PerformanceEntry::kInvalid) {
return;
}
- if (RuntimeEnabledFeatures::PerformanceObserverBufferedFlagEnabled() &&
- observer_init->buffered()) {
+ if (observer_init->buffered()) {
String message =
"The PerformanceObserver does not support buffered flag with "
"the entryTypes argument.";
- GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning, message));
+ GetExecutionContext()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning, message));
}
filter_options_ = entry_types;
} else {
@@ -162,39 +164,20 @@ void PerformanceObserver::observe(const PerformanceObserverInit* observer_init,
if (entry_type == PerformanceEntry::kInvalid) {
String message = "The entry type '" + observer_init->type() +
"' does not exist or isn't supported.";
- GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning, message));
+ GetExecutionContext()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning, message));
return;
}
- if (filter_options_ & entry_type) {
- String message =
- "The PerformanceObserver has already been called with the entry type "
- "'" +
- observer_init->type() + "'.";
- GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning, message));
- return;
- }
- if (RuntimeEnabledFeatures::PerformanceObserverBufferedFlagEnabled() &&
- observer_init->buffered()) {
- if (entry_type == PerformanceEntry::kLongTask) {
- String message =
- "Buffered flag does not support the 'longtask' entry type.";
- GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning, message));
- } else {
- // Append all entries of this type to the current performance_entries_
- // to be returned on the next callback.
- performance_entries_.AppendVector(
- performance_->getBufferedEntriesByType(
- AtomicString(observer_init->type())));
- std::sort(performance_entries_.begin(), performance_entries_.end(),
- PerformanceEntry::StartTimeCompareLessThan);
- is_buffered = true;
- }
+ if (observer_init->buffered()) {
+ // Append all entries of this type to the current performance_entries_
+ // to be returned on the next callback.
+ performance_entries_.AppendVector(performance_->getBufferedEntriesByType(
+ AtomicString(observer_init->type())));
+ std::sort(performance_entries_.begin(), performance_entries_.end(),
+ PerformanceEntry::StartTimeCompareLessThan);
+ is_buffered = true;
}
filter_options_ |= entry_type;
}
@@ -227,6 +210,7 @@ void PerformanceObserver::disconnect() {
if (performance_)
performance_->UnregisterPerformanceObserver(*this);
is_registered_ = false;
+ filter_options_ = PerformanceEntry::kInvalid;
}
PerformanceEntryVector PerformanceObserver::takeRecords() {
@@ -245,15 +229,10 @@ bool PerformanceObserver::HasPendingActivity() const {
return is_registered_;
}
-bool PerformanceObserver::ShouldBeSuspended() const {
- return execution_context_->IsContextPaused();
-}
-
void PerformanceObserver::Deliver() {
- DCHECK(!ShouldBeSuspended());
-
if (!GetExecutionContext())
return;
+ DCHECK(!GetExecutionContext()->IsContextPaused());
if (performance_entries_.IsEmpty())
return;
@@ -265,13 +244,20 @@ void PerformanceObserver::Deliver() {
callback_->InvokeAndReportException(this, entry_list, this);
}
-void PerformanceObserver::Trace(blink::Visitor* visitor) {
- visitor->Trace(execution_context_);
+void PerformanceObserver::ContextLifecycleStateChanged(
+ mojom::FrameLifecycleState state) {
+ if (state == mojom::FrameLifecycleState::kRunning)
+ performance_->ActivateObserver(*this);
+ else
+ performance_->SuspendObserver(*this);
+}
+
+void PerformanceObserver::Trace(Visitor* visitor) {
visitor->Trace(callback_);
visitor->Trace(performance_);
visitor->Trace(performance_entries_);
ScriptWrappable::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextLifecycleStateObserver::Trace(visitor);
}
} // namespace blink
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 ea29670f6a8..390dc410f61 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_observer.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_observer.h
@@ -7,7 +7,7 @@
#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/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h"
#include "third_party/blink/renderer/core/timing/performance_entry.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -26,7 +26,7 @@ using PerformanceEntryVector = HeapVector<Member<PerformanceEntry>>;
class CORE_EXPORT PerformanceObserver final
: public ScriptWrappable,
public ActiveScriptWrappable<PerformanceObserver>,
- public ContextClient {
+ public ExecutionContextLifecycleStateObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(PerformanceObserver);
friend class Performance;
@@ -51,7 +51,10 @@ class CORE_EXPORT PerformanceObserver final
// ScriptWrappable
bool HasPendingActivity() const final;
- void Trace(blink::Visitor*) override;
+ void ContextLifecycleStateChanged(mojom::FrameLifecycleState) final;
+ void ContextDestroyed() final {}
+
+ void Trace(Visitor*) override;
private:
// This describes the types of parameters that an observer can have in its
@@ -67,9 +70,7 @@ class CORE_EXPORT PerformanceObserver final
kUnknown,
};
void Deliver();
- bool ShouldBeSuspended() const;
- Member<ExecutionContext> execution_context_;
Member<V8PerformanceObserverCallback> callback_;
WeakMember<Performance> performance_;
PerformanceEntryVector performance_entries_;
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_observer.idl b/chromium/third_party/blink/renderer/core/timing/performance_observer.idl
index 8d28a314517..83fa192bda9 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_observer.idl
+++ b/chromium/third_party/blink/renderer/core/timing/performance_observer.idl
@@ -8,11 +8,10 @@ callback PerformanceObserverCallback = void (PerformanceObserverEntryList entrie
// https://w3c.github.io/performance-timeline/#the-performanceobserver-interface
[
ActiveScriptWrappable,
- Constructor(PerformanceObserverCallback callback),
- ConstructorCallWith=ScriptState,
Exposed=(Window,Worker)
] interface PerformanceObserver {
- [RaisesException] void observe(optional PerformanceObserverInit options);
+ [CallWith=ScriptState] constructor(PerformanceObserverCallback callback);
+ [RaisesException] void observe(optional PerformanceObserverInit options = {});
void disconnect();
PerformanceEntryList takeRecords();
[SameObject, SaveSameObject, CallWith=ScriptState] static readonly attribute FrozenArray<DOMString> supportedEntryTypes;
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 61a622316c3..3e36caf2277 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(blink::Visitor* visitor) {
+void PerformanceObserverEntryList::Trace(Visitor* visitor) {
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 1ea4d913ca6..f2a5628b6ed 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
PerformanceEntryVector performance_entries_;
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_observer_init.idl b/chromium/third_party/blink/renderer/core/timing/performance_observer_init.idl
index 2feff6ddd49..78a74f70a6d 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_observer_init.idl
+++ b/chromium/third_party/blink/renderer/core/timing/performance_observer_init.idl
@@ -7,5 +7,5 @@
dictionary PerformanceObserverInit {
sequence<DOMString> entryTypes;
DOMString type;
- [RuntimeEnabled=PerformanceObserverBufferedFlag] boolean buffered = false;
+ boolean buffered = false;
};
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_observer_test.cc b/chromium/third_party/blink/renderer/core/timing/performance_observer_test.cc
index d7607e53281..cc57dcdf9be 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_observer_test.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_observer_test.cc
@@ -7,12 +7,13 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_performance_mark_options.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_performance_observer_callback.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_performance_observer_init.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/timing/layout_shift.h"
#include "third_party/blink/renderer/core/timing/performance.h"
#include "third_party/blink/renderer/core/timing/performance_mark.h"
-#include "third_party/blink/renderer/core/timing/performance_observer_init.h"
#include "third_party/blink/renderer/core/timing/window_performance.h"
namespace blink {
@@ -88,9 +89,10 @@ TEST_F(PerformanceObserverTest, Enqueue) {
NonThrowableExceptionState exception_state;
Initialize(scope.GetScriptState());
- ScriptValue empty_value;
+ PerformanceMarkOptions* options = PerformanceMarkOptions::Create();
+ options->setStartTime(1234);
Persistent<PerformanceEntry> entry = PerformanceMark::Create(
- scope.GetScriptState(), "m", 1234, empty_value, exception_state);
+ scope.GetScriptState(), "m", options, exception_state);
EXPECT_EQ(0, NumPerformanceEntries());
observer_->EnqueuePerformanceEntry(*entry);
@@ -102,9 +104,10 @@ TEST_F(PerformanceObserverTest, Deliver) {
NonThrowableExceptionState exception_state;
Initialize(scope.GetScriptState());
- ScriptValue empty_value;
+ PerformanceMarkOptions* options = PerformanceMarkOptions::Create();
+ options->setStartTime(1234);
Persistent<PerformanceEntry> entry = PerformanceMark::Create(
- scope.GetScriptState(), "m", 1234, empty_value, exception_state);
+ scope.GetScriptState(), "m", options, exception_state);
EXPECT_EQ(0, NumPerformanceEntries());
observer_->EnqueuePerformanceEntry(*entry);
@@ -119,9 +122,10 @@ TEST_F(PerformanceObserverTest, Disconnect) {
NonThrowableExceptionState exception_state;
Initialize(scope.GetScriptState());
- ScriptValue empty_value;
+ PerformanceMarkOptions* options = PerformanceMarkOptions::Create();
+ options->setStartTime(1234);
Persistent<PerformanceEntry> entry = PerformanceMark::Create(
- scope.GetScriptState(), "m", 1234, empty_value, exception_state);
+ scope.GetScriptState(), "m", options, exception_state);
EXPECT_EQ(0, NumPerformanceEntries());
observer_->EnqueuePerformanceEntry(*entry);
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 62f23d88911..d1265f389b6 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
@@ -32,7 +32,6 @@
#include "third_party/blink/renderer/core/timing/performance_resource_timing.h"
#include "third_party/blink/public/mojom/timing/performance_mark_or_measure.mojom-blink.h"
-#include "third_party/blink/public/platform/web_resource_timing_info.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
#include "third_party/blink/renderer/core/performance_entry_names.h"
#include "third_party/blink/renderer/core/timing/performance.h"
@@ -48,12 +47,12 @@
namespace blink {
PerformanceResourceTiming::PerformanceResourceTiming(
- const WebResourceTimingInfo& info,
+ const mojom::blink::ResourceTimingInfo& info,
base::TimeTicks time_origin,
const AtomicString& initiator_type,
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
worker_timing_receiver)
- : PerformanceEntry(info.name,
+ : PerformanceEntry(AtomicString(info.name),
Performance::MonotonicTimeToDOMHighResTimeStamp(
time_origin,
info.start_time,
@@ -69,10 +68,11 @@ PerformanceResourceTiming::PerformanceResourceTiming(
static_cast<String>(info.alpn_negotiated_protocol)),
connection_info_(static_cast<String>(info.connection_info)),
time_origin_(time_origin),
- timing_(info.timing),
+ timing_(ResourceLoadTiming::FromMojo(info.timing.get())),
last_redirect_end_time_(info.last_redirect_end_time),
response_end_(info.response_end),
context_type_(info.context_type),
+ request_destination_(info.request_destination),
transfer_size_(info.transfer_size),
encoded_body_size_(info.encoded_body_size),
decoded_body_size_(info.decoded_body_size),
@@ -93,13 +93,13 @@ PerformanceResourceTiming::PerformanceResourceTiming(
const AtomicString& name,
base::TimeTicks time_origin,
bool is_secure_context,
- const WebVector<WebServerTimingInfo>& server_timing)
+ HeapVector<Member<PerformanceServerTiming>> server_timing)
: 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_(
- PerformanceServerTiming::FromParsedServerTiming(server_timing)),
+ server_timing_(std::move(server_timing)),
worker_timing_receiver_(this, mojo::NullReceiver()) {}
PerformanceResourceTiming::~PerformanceResourceTiming() = default;
@@ -148,16 +148,32 @@ AtomicString PerformanceResourceTiming::ConnectionInfo() const {
return connection_info_;
}
+namespace {
+bool IsDocumentDestination(mojom::blink::RequestContextType context_type) {
+ // TODO(crbug.com/889751) : Need to change using RequestDestination
+ return context_type == mojom::blink::RequestContextType::IFRAME ||
+ context_type == mojom::blink::RequestContextType::FRAME ||
+ context_type == mojom::blink::RequestContextType::FORM ||
+ context_type == mojom::blink::RequestContextType::HYPERLINK;
+}
+
+} // namespace
+
AtomicString PerformanceResourceTiming::GetNextHopProtocol(
const AtomicString& alpn_negotiated_protocol,
- const AtomicString& connection_info) {
+ const AtomicString& connection_info) const {
// Fallback to connection_info when alpn_negotiated_protocol is unknown.
AtomicString returnedProtocol = (alpn_negotiated_protocol == "unknown")
? connection_info
: alpn_negotiated_protocol;
- // If connection_info is also unknown, return empty string.
- // (https://github.com/w3c/navigation-timing/issues/71)
- returnedProtocol = (returnedProtocol == "unknown") ? "" : returnedProtocol;
+ // If connection_info is unknown, or if this is a `document` destination and
+ // TAO didn't pass, return the empty string.
+ // https://github.com/w3c/navigation-timing/issues/71
+ // https://github.com/w3c/resource-timing/pull/224
+ if (returnedProtocol == "unknown" ||
+ (!AllowTimingDetails() && IsDocumentDestination(context_type_))) {
+ returnedProtocol = "";
+ }
return returnedProtocol;
}
@@ -167,16 +183,6 @@ AtomicString PerformanceResourceTiming::nextHopProtocol() const {
ConnectionInfo());
}
-namespace {
-bool IsDocumentDestination(mojom::RequestContextType context_type) {
- return context_type == mojom::RequestContextType::IFRAME ||
- context_type == mojom::RequestContextType::FRAME ||
- context_type == mojom::RequestContextType::FORM ||
- context_type == mojom::RequestContextType::HYPERLINK;
-}
-
-} // namespace
-
DOMHighResTimeStamp PerformanceResourceTiming::workerStart() const {
ResourceLoadTiming* timing = GetResourceLoadTiming();
if (!timing || timing->WorkerStart().is_null() ||
@@ -388,19 +394,11 @@ void PerformanceResourceTiming::BuildJSONValue(V8ObjectBuilder& builder) const {
builder.AddNumber("encodedBodySize", encodedBodySize());
builder.AddNumber("decodedBodySize", decodedBodySize());
- HeapVector<ScriptValue> server_timing;
- server_timing.ReserveCapacity(server_timing_.size());
- for (const auto& timing : server_timing_) {
- server_timing.push_back(timing->toJSONForBinding(builder.GetScriptState()));
- }
- builder.Add("serverTiming", server_timing);
-
- HeapVector<ScriptValue> worker_timing;
- worker_timing.ReserveCapacity(worker_timing_.size());
- for (const auto& timing : worker_timing_) {
- worker_timing.push_back(timing->toJSONForBinding(builder.GetScriptState()));
- }
- builder.Add("workerTiming", worker_timing);
+ ScriptState* script_state = builder.GetScriptState();
+ builder.Add("serverTiming", FreezeV8Object(ToV8(serverTiming(), script_state),
+ script_state->GetIsolate()));
+ builder.Add("workerTiming", FreezeV8Object(ToV8(workerTiming(), script_state),
+ script_state->GetIsolate()));
}
void PerformanceResourceTiming::AddPerformanceEntry(
@@ -441,7 +439,7 @@ void PerformanceResourceTiming::AddPerformanceEntry(
}
}
-void PerformanceResourceTiming::Trace(blink::Visitor* visitor) {
+void PerformanceResourceTiming::Trace(Visitor* visitor) {
visitor->Trace(server_timing_);
visitor->Trace(worker_timing_);
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 9078dd4513d..373c111901b 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
@@ -35,6 +35,7 @@
#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/timing/performance_entry.h"
@@ -45,7 +46,6 @@
namespace blink {
class ResourceLoadTiming;
-struct WebResourceTimingInfo;
class CORE_EXPORT PerformanceResourceTiming
: public PerformanceEntry,
@@ -56,12 +56,13 @@ class CORE_EXPORT PerformanceResourceTiming
public:
// This constructor is for PerformanceNavigationTiming.
// Related doc: https://goo.gl/uNecAj.
- PerformanceResourceTiming(const AtomicString& name,
- base::TimeTicks time_origin,
- bool is_secure_context,
- const WebVector<WebServerTimingInfo>&);
PerformanceResourceTiming(
- const WebResourceTimingInfo&,
+ const AtomicString& name,
+ base::TimeTicks time_origin,
+ bool is_secure_context,
+ HeapVector<Member<PerformanceServerTiming>> server_timing);
+ PerformanceResourceTiming(
+ const mojom::blink::ResourceTimingInfo&,
base::TimeTicks time_origin,
const AtomicString& initiator_type,
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
@@ -95,7 +96,7 @@ class CORE_EXPORT PerformanceResourceTiming
// Implements blink::mojom::blink::WorkerTimingContainer
void AddPerformanceEntry(
mojom::blink::PerformanceMarkOrMeasurePtr entry) override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
void BuildJSONValue(V8ObjectBuilder&) const override;
@@ -106,9 +107,8 @@ class CORE_EXPORT PerformanceResourceTiming
base::TimeTicks TimeOrigin() const { return time_origin_; }
private:
- static AtomicString GetNextHopProtocol(
- const AtomicString& alpn_negotiated_protocol,
- const AtomicString& connection_info);
+ AtomicString GetNextHopProtocol(const AtomicString& alpn_negotiated_protocol,
+ const AtomicString& connection_info) const;
double WorkerReady() const;
@@ -128,6 +128,8 @@ class CORE_EXPORT PerformanceResourceTiming
base::TimeTicks response_end_;
mojom::RequestContextType context_type_ =
mojom::RequestContextType::UNSPECIFIED;
+ network::mojom::RequestDestination request_destination_ =
+ network::mojom::RequestDestination::kEmpty;
uint64_t transfer_size_ = 0;
uint64_t encoded_body_size_ = 0;
uint64_t decoded_body_size_ = 0;
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 8bae894337f..ee04f6b4a30 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
@@ -12,8 +12,12 @@ class PerformanceResourceTimingTest : public testing::Test {
protected:
AtomicString GetNextHopProtocol(const AtomicString& alpn_negotiated_protocol,
const AtomicString& connection_info) {
- return PerformanceResourceTiming::GetNextHopProtocol(
- alpn_negotiated_protocol, 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);
}
};
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_server_timing.cc b/chromium/third_party/blink/renderer/core/timing/performance_server_timing.cc
index 291804f767c..9bafffe1152 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_server_timing.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_server_timing.cc
@@ -26,27 +26,42 @@ ScriptValue PerformanceServerTiming::toJSONForBinding(
return builder.GetScriptValue();
}
-WebVector<WebServerTimingInfo> PerformanceServerTiming::ParseServerTiming(
+Vector<mojom::blink::ServerTimingInfoPtr>
+PerformanceServerTiming::ParseServerTimingToMojo(
const ResourceTimingInfo& info) {
- WebVector<WebServerTimingInfo> result;
+ Vector<mojom::blink::ServerTimingInfoPtr> result;
const ResourceResponse& response = info.FinalResponse();
std::unique_ptr<ServerTimingHeaderVector> headers = ParseServerTimingHeader(
response.HttpHeaderField(http_names::kServerTiming));
- result.reserve(headers->size());
+ result.ReserveCapacity(headers->size());
for (const auto& header : *headers) {
- result.emplace_back(header->Name(), header->Duration(),
- header->Description());
+ result.emplace_back(mojom::blink::ServerTimingInfo::New(
+ header->Name(), header->Duration(), header->Description()));
+ }
+ return result;
+}
+
+HeapVector<Member<PerformanceServerTiming>>
+PerformanceServerTiming::ParseServerTiming(const ResourceTimingInfo& info) {
+ HeapVector<Member<PerformanceServerTiming>> result;
+ const ResourceResponse& response = info.FinalResponse();
+ std::unique_ptr<ServerTimingHeaderVector> headers = ParseServerTimingHeader(
+ response.HttpHeaderField(http_names::kServerTiming));
+ result.ReserveCapacity(headers->size());
+ for (const auto& header : *headers) {
+ result.push_back(MakeGarbageCollected<PerformanceServerTiming>(
+ header->Name(), header->Duration(), header->Description()));
}
return result;
}
HeapVector<Member<PerformanceServerTiming>>
PerformanceServerTiming::FromParsedServerTiming(
- const WebVector<WebServerTimingInfo>& entries) {
+ const Vector<mojom::blink::ServerTimingInfoPtr>& entries) {
HeapVector<Member<PerformanceServerTiming>> result;
for (const auto& entry : entries) {
result.push_back(MakeGarbageCollected<PerformanceServerTiming>(
- entry.name, entry.duration, entry.description));
+ entry->name, entry->duration, entry->description));
}
return result;
}
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_server_timing.h b/chromium/third_party/blink/renderer/core/timing/performance_server_timing.h
index d32262a3b03..f0930174df1 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_server_timing.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_server_timing.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_PERFORMANCE_SERVER_TIMING_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_PERFORMANCE_SERVER_TIMING_H_
-#include "third_party/blink/public/platform/web_resource_timing_info.h"
+#include "third_party/blink/public/mojom/timing/resource_timing.mojom-blink.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -29,10 +29,12 @@ class CORE_EXPORT PerformanceServerTiming final : public ScriptWrappable {
double duration() const { return duration_; }
const String& description() const { return description_; }
- static WebVector<WebServerTimingInfo> ParseServerTiming(
+ static Vector<mojom::blink::ServerTimingInfoPtr> ParseServerTimingToMojo(
+ const ResourceTimingInfo&);
+ static HeapVector<Member<PerformanceServerTiming>> ParseServerTiming(
const ResourceTimingInfo&);
static HeapVector<Member<PerformanceServerTiming>> FromParsedServerTiming(
- const WebVector<WebServerTimingInfo>&);
+ const Vector<mojom::blink::ServerTimingInfoPtr>&);
ScriptValue toJSONForBinding(ScriptState*) const;
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 bda7ed2b55b..f048933eda6 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_test.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_test.cc
@@ -11,13 +11,13 @@
#include "third_party/blink/renderer/bindings/core/v8/string_or_performance_measure_options.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_performance_observer_callback.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_performance_observer_init.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/testing/null_execution_context.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/core/timing/performance.h"
#include "third_party/blink/renderer/core/timing/performance_long_task_timing.h"
#include "third_party/blink/renderer/core/timing/performance_observer.h"
-#include "third_party/blink/renderer/core/timing/performance_observer_init.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
namespace blink {
@@ -40,7 +40,7 @@ class TestPerformance : public Performance {
return HasObserverFor(entry_type);
}
- void Trace(blink::Visitor* visitor) override { Performance::Trace(visitor); }
+ void Trace(Visitor* visitor) 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 8bc7afee91a..a661f3f6e6c 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_timing.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_timing.cc
@@ -55,6 +55,8 @@ namespace blink {
static uint64_t ToIntegerMilliseconds(base::TimeDelta duration) {
// TODO(npm): add histograms to understand when/why |duration| is sometimes
// negative.
+ // TODO(crbug.com/1063989): stop clamping when it is not needed (i.e. for
+ // methods which do not expose the timestamp to a web perf API).
double clamped_seconds =
Performance::ClampTimeResolution(duration.InSecondsF());
return static_cast<uint64_t>(clamped_seconds * 1000.0);
@@ -311,12 +313,12 @@ uint64_t PerformanceTiming::loadEventEnd() const {
return MonotonicTimeToIntegerMilliseconds(timing->LoadEventEnd());
}
-uint64_t PerformanceTiming::FirstLayout() const {
- const DocumentTiming* timing = GetDocumentTiming();
+base::TimeTicks PerformanceTiming::NavigationStartAsMonotonicTime() const {
+ DocumentLoadTiming* timing = GetDocumentLoadTiming();
if (!timing)
- return 0;
+ return base::TimeTicks();
- return MonotonicTimeToIntegerMilliseconds(timing->FirstLayout());
+ return timing->NavigationStart();
}
uint64_t PerformanceTiming::FirstPaint() const {
@@ -343,6 +345,14 @@ uint64_t PerformanceTiming::FirstContentfulPaint() const {
return MonotonicTimeToIntegerMilliseconds(timing->FirstContentfulPaint());
}
+base::TimeTicks PerformanceTiming::FirstContentfulPaintAsMonotonicTime() const {
+ const PaintTiming* timing = GetPaintTiming();
+ if (!timing)
+ return base::TimeTicks();
+
+ return timing->FirstContentfulPaint();
+}
+
uint64_t PerformanceTiming::FirstMeaningfulPaint() const {
const PaintTiming* timing = GetPaintTiming();
if (!timing)
@@ -394,64 +404,47 @@ uint64_t PerformanceTiming::LargestTextPaintSize() const {
return paint_timing_detector->LargestTextPaintSize();
}
-uint64_t PerformanceTiming::PageInteractive() const {
- InteractiveDetector* interactive_detector = GetInteractiveDetector();
- if (!interactive_detector)
- return 0;
-
- return MonotonicTimeToIntegerMilliseconds(
- interactive_detector->GetInteractiveTime());
-}
-
-uint64_t PerformanceTiming::PageInteractiveDetection() const {
- InteractiveDetector* interactive_detector = GetInteractiveDetector();
- if (!interactive_detector)
- return 0;
-
- return MonotonicTimeToIntegerMilliseconds(
- interactive_detector->GetInteractiveDetectionTime());
-}
-
-uint64_t PerformanceTiming::FirstInputInvalidatingInteractive() const {
- InteractiveDetector* interactive_detector = GetInteractiveDetector();
- if (!interactive_detector)
+uint64_t PerformanceTiming::FirstInputOrScrollNotifiedTimestamp() const {
+ PaintTimingDetector* paint_timing_detector = GetPaintTimingDetector();
+ if (!paint_timing_detector)
return 0;
return MonotonicTimeToIntegerMilliseconds(
- interactive_detector->GetFirstInvalidatingInputTime());
+ paint_timing_detector->FirstInputOrScrollNotifiedTimestamp());
}
-uint64_t PerformanceTiming::FirstInputDelay() const {
+base::Optional<base::TimeDelta> PerformanceTiming::FirstInputDelay() const {
const InteractiveDetector* interactive_detector = GetInteractiveDetector();
if (!interactive_detector)
- return 0;
+ return base::nullopt;
- return ToIntegerMilliseconds(interactive_detector->GetFirstInputDelay());
+ return interactive_detector->GetFirstInputDelay();
}
-uint64_t PerformanceTiming::FirstInputTimestamp() const {
+base::Optional<base::TimeDelta> PerformanceTiming::FirstInputTimestamp() const {
const InteractiveDetector* interactive_detector = GetInteractiveDetector();
if (!interactive_detector)
- return 0;
+ return base::nullopt;
- return MonotonicTimeToIntegerMilliseconds(
+ return MonotonicTimeToPseudoWallTime(
interactive_detector->GetFirstInputTimestamp());
}
-uint64_t PerformanceTiming::LongestInputDelay() const {
+base::Optional<base::TimeDelta> PerformanceTiming::LongestInputDelay() const {
const InteractiveDetector* interactive_detector = GetInteractiveDetector();
if (!interactive_detector)
- return 0;
+ return base::nullopt;
- return ToIntegerMilliseconds(interactive_detector->GetLongestInputDelay());
+ return interactive_detector->GetLongestInputDelay();
}
-uint64_t PerformanceTiming::LongestInputTimestamp() const {
+base::Optional<base::TimeDelta> PerformanceTiming::LongestInputTimestamp()
+ const {
const InteractiveDetector* interactive_detector = GetInteractiveDetector();
if (!interactive_detector)
- return 0;
+ return base::nullopt;
- return MonotonicTimeToIntegerMilliseconds(
+ return MonotonicTimeToPseudoWallTime(
interactive_detector->GetLongestInputTimestamp());
}
@@ -587,6 +580,19 @@ PaintTimingDetector* PerformanceTiming::GetPaintTimingDetector() const {
return &view->GetPaintTimingDetector();
}
+base::Optional<base::TimeDelta>
+PerformanceTiming::MonotonicTimeToPseudoWallTime(
+ const base::Optional<base::TimeTicks>& time) const {
+ if (!time.has_value())
+ return base::nullopt;
+
+ const DocumentLoadTiming* timing = GetDocumentLoadTiming();
+ if (!timing)
+ return base::nullopt;
+
+ return timing->MonotonicTimeToPseudoWallTime(*time);
+}
+
std::unique_ptr<TracedValue> PerformanceTiming::GetNavigationTracingData() {
auto data = std::make_unique<TracedValue>();
data->SetString("navigationId",
@@ -594,30 +600,47 @@ std::unique_ptr<TracedValue> PerformanceTiming::GetNavigationTracingData() {
return data;
}
+// static
+const PerformanceTiming::NameToAttributeMap&
+PerformanceTiming::GetAttributeMapping() {
+ DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<NameToAttributeMap>, map, ());
+ if (!map.IsSet()) {
+ *map = {
+ {"navigationStart", &PerformanceTiming::navigationStart},
+ {"unloadEventStart", &PerformanceTiming::unloadEventStart},
+ {"unloadEventEnd", &PerformanceTiming::unloadEventEnd},
+ {"redirectStart", &PerformanceTiming::redirectStart},
+ {"redirectEnd", &PerformanceTiming::redirectEnd},
+ {"fetchStart", &PerformanceTiming::fetchStart},
+ {"domainLookupStart", &PerformanceTiming::domainLookupStart},
+ {"domainLookupEnd", &PerformanceTiming::domainLookupEnd},
+ {"connectStart", &PerformanceTiming::connectStart},
+ {"connectEnd", &PerformanceTiming::connectEnd},
+ {"secureConnectionStart", &PerformanceTiming::secureConnectionStart},
+ {"requestStart", &PerformanceTiming::requestStart},
+ {"responseStart", &PerformanceTiming::responseStart},
+ {"responseEnd", &PerformanceTiming::responseEnd},
+ {"domLoading", &PerformanceTiming::domLoading},
+ {"domInteractive", &PerformanceTiming::domInteractive},
+ {"domContentLoadedEventStart",
+ &PerformanceTiming::domContentLoadedEventStart},
+ {"domContentLoadedEventEnd",
+ &PerformanceTiming::domContentLoadedEventEnd},
+ {"domComplete", &PerformanceTiming::domComplete},
+ {"loadEventStart", &PerformanceTiming::loadEventStart},
+ {"loadEventEnd", &PerformanceTiming::loadEventEnd},
+ };
+ }
+ return *map;
+}
+
ScriptValue PerformanceTiming::toJSONForBinding(
ScriptState* script_state) const {
V8ObjectBuilder result(script_state);
- result.AddNumber("navigationStart", navigationStart());
- result.AddNumber("unloadEventStart", unloadEventStart());
- result.AddNumber("unloadEventEnd", unloadEventEnd());
- result.AddNumber("redirectStart", redirectStart());
- result.AddNumber("redirectEnd", redirectEnd());
- result.AddNumber("fetchStart", fetchStart());
- result.AddNumber("domainLookupStart", domainLookupStart());
- result.AddNumber("domainLookupEnd", domainLookupEnd());
- result.AddNumber("connectStart", connectStart());
- result.AddNumber("connectEnd", connectEnd());
- result.AddNumber("secureConnectionStart", secureConnectionStart());
- result.AddNumber("requestStart", requestStart());
- result.AddNumber("responseStart", responseStart());
- result.AddNumber("responseEnd", responseEnd());
- result.AddNumber("domLoading", domLoading());
- result.AddNumber("domInteractive", domInteractive());
- result.AddNumber("domContentLoadedEventStart", domContentLoadedEventStart());
- result.AddNumber("domContentLoadedEventEnd", domContentLoadedEventEnd());
- result.AddNumber("domComplete", domComplete());
- result.AddNumber("loadEventStart", loadEventStart());
- result.AddNumber("loadEventEnd", loadEventEnd());
+ for (const auto& name_attribute_pair : GetAttributeMapping()) {
+ result.AddNumber(name_attribute_pair.key,
+ (this->*(name_attribute_pair.value))());
+ }
return result.GetScriptValue();
}
@@ -630,7 +653,7 @@ uint64_t PerformanceTiming::MonotonicTimeToIntegerMilliseconds(
return ToIntegerMilliseconds(timing->MonotonicTimeToPseudoWallTime(time));
}
-void PerformanceTiming::Trace(blink::Visitor* visitor) {
+void PerformanceTiming::Trace(Visitor* visitor) {
ScriptWrappable::Trace(visitor);
DOMWindowClient::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 00491fa8d83..29ce0e4dd48 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_timing.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_timing.h
@@ -31,8 +31,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_PERFORMANCE_TIMING_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_PERFORMANCE_TIMING_H_
+#include "base/time/time.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/instrumentation/tracing/traced_value.h"
@@ -86,8 +87,11 @@ class CORE_EXPORT PerformanceTiming final : public ScriptWrappable,
// The below are non-spec timings, for Page Load UMA metrics.
- // The time the first document layout is performed.
- uint64_t FirstLayout() const;
+ // The time immediately after the user agent finishes prompting to unload the
+ // previous document, or if there is no previous document, the same value as
+ // fetchStart. Intended to be used for correlation with other events internal
+ // to blink. Not to be exposed to JavaScript.
+ base::TimeTicks NavigationStartAsMonotonicTime() const;
// The time the first paint operation was performed.
uint64_t FirstPaint() const;
// The time the first paint operation for image was performed.
@@ -95,6 +99,10 @@ class CORE_EXPORT PerformanceTiming final : public ScriptWrappable,
// The time of the first 'contentful' paint. A contentful paint is a paint
// that includes content of some kind (for example, text or image content).
uint64_t FirstContentfulPaint() const;
+ // The first 'contentful' paint as full-resolution monotonic time. Intended to
+ // be used for correlation with other events internal to blink. Not to be
+ // exposed to JavaScript.
+ base::TimeTicks FirstContentfulPaintAsMonotonicTime() const;
// The time of the first 'meaningful' paint, A meaningful paint is a paint
// where the page's primary content is visible.
uint64_t FirstMeaningfulPaint() const;
@@ -116,27 +124,21 @@ class CORE_EXPORT PerformanceTiming final : public ScriptWrappable,
// are the time and size of it.
uint64_t LargestTextPaint() const;
uint64_t LargestTextPaintSize() const;
- // The first time the page is considered 'interactive'. This is determined
- // using heuristics based on main thread and network activity.
- uint64_t PageInteractive() const;
- // The time of when we detect the page is interactive. There is a delay
- // between when the page was interactive and when we were able to detect it.
- uint64_t PageInteractiveDetection() const;
- // The time of when a significant input event happened that may cause
- // observers to discard the value of Time to Interactive.
- uint64_t FirstInputInvalidatingInteractive() 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;
// The duration between the hardware timestamp and being queued on the main
// thread for the first click, tap, key press, cancellable touchstart, or
// pointer down followed by a pointer up.
- uint64_t FirstInputDelay() const;
+ base::Optional<base::TimeDelta> FirstInputDelay() const;
// The timestamp of the event whose delay is reported by FirstInputDelay().
- uint64_t FirstInputTimestamp() const;
+ base::Optional<base::TimeDelta> FirstInputTimestamp() const;
// The longest duration between the hardware timestamp and being queued on the
// main thread for the click, tap, key press, cancellable touchstart, or
// pointer down followed by a pointer up.
- uint64_t LongestInputDelay() const;
+ base::Optional<base::TimeDelta> LongestInputDelay() const;
// The timestamp of the event whose delay is reported by LongestInputDelay().
- uint64_t LongestInputTimestamp() const;
+ base::Optional<base::TimeDelta> LongestInputTimestamp() const;
uint64_t ParseStart() const;
uint64_t ParseStop() const;
@@ -145,9 +147,13 @@ class CORE_EXPORT PerformanceTiming final : public ScriptWrappable,
uint64_t ParseBlockedOnScriptExecutionDuration() const;
uint64_t ParseBlockedOnScriptExecutionFromDocumentWriteDuration() const;
+ typedef uint64_t (PerformanceTiming::*PerformanceTimingGetter)() const;
+ using NameToAttributeMap = HashMap<AtomicString, PerformanceTimingGetter>;
+ static const NameToAttributeMap& GetAttributeMapping();
+
ScriptValue toJSONForBinding(ScriptState*) const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
uint64_t MonotonicTimeToIntegerMilliseconds(base::TimeTicks) const;
@@ -163,6 +169,8 @@ class CORE_EXPORT PerformanceTiming final : public ScriptWrappable,
DocumentLoadTiming* GetDocumentLoadTiming() const;
ResourceLoadTiming* GetResourceLoadTiming() const;
InteractiveDetector* GetInteractiveDetector() const;
+ base::Optional<base::TimeDelta> MonotonicTimeToPseudoWallTime(
+ const base::Optional<base::TimeTicks>&) const;
};
} // namespace blink
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 597cd102ca1..e7fe5a559f5 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
@@ -25,8 +25,9 @@
#include "third_party/blink/renderer/core/timing/performance_user_timing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_performance_mark_options.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/timing/performance_mark.h"
-#include "third_party/blink/renderer/core/timing/performance_mark_options.h"
#include "third_party/blink/renderer/core/timing/performance_measure.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
@@ -34,45 +35,6 @@
namespace blink {
-namespace {
-
-typedef uint64_t (PerformanceTiming::*NavigationTimingFunction)() const;
-using RestrictedKeyMap = HashMap<AtomicString, NavigationTimingFunction>;
-
-const RestrictedKeyMap& GetRestrictedKeyMap() {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<RestrictedKeyMap>, map, ());
- if (!map.IsSet()) {
- *map = {
- {"navigationStart", &PerformanceTiming::navigationStart},
- {"unloadEventStart", &PerformanceTiming::unloadEventStart},
- {"unloadEventEnd", &PerformanceTiming::unloadEventEnd},
- {"redirectStart", &PerformanceTiming::redirectStart},
- {"redirectEnd", &PerformanceTiming::redirectEnd},
- {"fetchStart", &PerformanceTiming::fetchStart},
- {"domainLookupStart", &PerformanceTiming::domainLookupStart},
- {"domainLookupEnd", &PerformanceTiming::domainLookupEnd},
- {"connectStart", &PerformanceTiming::connectStart},
- {"connectEnd", &PerformanceTiming::connectEnd},
- {"secureConnectionStart", &PerformanceTiming::secureConnectionStart},
- {"requestStart", &PerformanceTiming::requestStart},
- {"responseStart", &PerformanceTiming::responseStart},
- {"responseEnd", &PerformanceTiming::responseEnd},
- {"domLoading", &PerformanceTiming::domLoading},
- {"domInteractive", &PerformanceTiming::domInteractive},
- {"domContentLoadedEventStart",
- &PerformanceTiming::domContentLoadedEventStart},
- {"domContentLoadedEventEnd",
- &PerformanceTiming::domContentLoadedEventEnd},
- {"domComplete", &PerformanceTiming::domComplete},
- {"loadEventStart", &PerformanceTiming::loadEventStart},
- {"loadEventEnd", &PerformanceTiming::loadEventEnd},
- };
- }
- return *map;
-}
-
-} // namespace
-
UserTiming::UserTiming(Performance& performance) : performance_(&performance) {}
static void InsertPerformanceEntry(PerformanceEntryMap& performance_entry_map,
@@ -103,35 +65,7 @@ PerformanceMark* UserTiming::CreatePerformanceMark(
const AtomicString& mark_name,
PerformanceMarkOptions* mark_options,
ExceptionState& exception_state) {
- DOMHighResTimeStamp start = 0.0;
- if (mark_options && mark_options->hasStartTime()) {
- start = mark_options->startTime();
- if (start < 0.0) {
- exception_state.ThrowTypeError("'" + mark_name +
- "' cannot have a negative start time.");
- return nullptr;
- }
- } else {
- start = performance_->now();
- }
-
- ScriptValue detail = ScriptValue::CreateNull(script_state->GetIsolate());
- if (mark_options)
- detail = mark_options->detail();
-
- bool is_worker_global_scope =
- performance_->GetExecutionContext() &&
- performance_->GetExecutionContext()->IsWorkerGlobalScope();
- if (!is_worker_global_scope && GetRestrictedKeyMap().Contains(mark_name)) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kSyntaxError,
- "'" + mark_name +
- "' is part of the PerformanceTiming interface, and "
- "cannot be used as a mark name.");
- return nullptr;
- }
-
- return PerformanceMark::Create(script_state, mark_name, start, detail,
+ return PerformanceMark::Create(script_state, mark_name, mark_options,
exception_state);
}
@@ -152,11 +86,14 @@ void UserTiming::ClearMarks(const AtomicString& mark_name) {
double UserTiming::FindExistingMarkStartTime(const AtomicString& mark_name,
ExceptionState& exception_state) {
- if (marks_map_.Contains(mark_name))
- return marks_map_.at(mark_name).back()->startTime();
+ PerformanceEntryMap::const_iterator existing_marks =
+ marks_map_.find(mark_name);
+ if (existing_marks != marks_map_.end()) {
+ return existing_marks->value.back()->startTime();
+ }
- NavigationTimingFunction timing_function =
- GetRestrictedKeyMap().at(mark_name);
+ PerformanceTiming::PerformanceTimingGetter timing_function =
+ PerformanceTiming::GetAttributeMapping().at(mark_name);
if (!timing_function) {
exception_state.ThrowDOMException(
DOMExceptionCode::kSyntaxError,
@@ -306,7 +243,7 @@ PerformanceEntryVector UserTiming::GetMeasures(const AtomicString& name) const {
return GetEntrySequenceByName(measures_map_, name);
}
-void UserTiming::Trace(blink::Visitor* visitor) {
+void UserTiming::Trace(Visitor* visitor) {
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 5ab9ff8b49c..3c2377900b6 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
@@ -65,7 +65,7 @@ class UserTiming final : public GarbageCollected<UserTiming> {
PerformanceEntryVector GetMarks(const AtomicString& name) const;
PerformanceEntryVector GetMeasures(const AtomicString& name) const;
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
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 2ba79c8b1e9..795eb9d7fe0 100644
--- a/chromium/third_party/blink/renderer/core/timing/profiler.cc
+++ b/chromium/third_party/blink/renderer/core/timing/profiler.cc
@@ -13,7 +13,7 @@ Profiler::~Profiler() {
Dispose();
}
-void Profiler::Trace(blink::Visitor* visitor) {
+void Profiler::Trace(Visitor* visitor) {
visitor->Trace(profiler_group_);
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 f724d994b38..b9de2f198c1 100644
--- a/chromium/third_party/blink/renderer/core/timing/profiler.h
+++ b/chromium/third_party/blink/renderer/core/timing/profiler.h
@@ -39,7 +39,7 @@ class CORE_EXPORT Profiler final : public ScriptWrappable {
~Profiler() override;
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
void Dispose();
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 5f02a0a8c3b..98fe86e0a4a 100644
--- a/chromium/third_party/blink/renderer/core/timing/profiler_group.cc
+++ b/chromium/third_party/blink/renderer/core/timing/profiler_group.cc
@@ -7,10 +7,10 @@
#include "base/time/time.h"
#include "build/build_config.h"
#include "third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_profiler_init_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_profiler_trace.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/timing/profiler.h"
-#include "third_party/blink/renderer/core/timing/profiler_init_options.h"
-#include "third_party/blink/renderer/core/timing/profiler_trace.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/runtime_enabled_features.h"
@@ -133,7 +133,7 @@ void ProfilerGroup::WillBeDestroyed() {
TeardownV8Profiler();
}
-void ProfilerGroup::Trace(blink::Visitor* visitor) {
+void ProfilerGroup::Trace(Visitor* visitor) {
visitor->Trace(profilers_);
V8PerIsolateData::GarbageCollectedData::Trace(visitor);
}
@@ -173,7 +173,8 @@ void ProfilerGroup::StopProfiler(ScriptState* script_state,
script_state, profile, profiler->SourceOrigin(), profiler->TimeOrigin());
resolver->Resolve(trace);
- profile->Delete();
+ if (profile)
+ profile->Delete();
if (--num_active_profilers_ == 0)
TeardownV8Profiler();
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 8a74fdc75e6..93374ec33bd 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
friend class Profiler;
diff --git a/chromium/third_party/blink/renderer/core/timing/profiler_group_test.cc b/chromium/third_party/blink/renderer/core/timing/profiler_group_test.cc
index c54cdfe288c..bc014b47071 100644
--- a/chromium/third_party/blink/renderer/core/timing/profiler_group_test.cc
+++ b/chromium/third_party/blink/renderer/core/timing/profiler_group_test.cc
@@ -6,11 +6,17 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_profiler_init_options.h"
#include "third_party/blink/renderer/core/timing/profiler.h"
-#include "third_party/blink/renderer/core/timing/profiler_init_options.h"
namespace blink {
+namespace {
+
+static constexpr int kLargeProfilerCount = 128;
+
+} // namespace
+
// Tests that a leaked profiler doesn't crash the isolate on heap teardown.
TEST(ProfilerGroupTest, LeakProfiler) {
V8TestingScope scope;
@@ -144,4 +150,28 @@ TEST(ProfilerGroupTest, OverflowSamplingInterval) {
EXPECT_TRUE(scope.GetExceptionState().HadException());
}
+// Tests behaviour when exceeding the maximum number of concurrent profiles
+// supported by the V8 profiling API (https://crbug.com/1052341).
+TEST(ProfilerGroupTest, V8ProfileLimit) {
+ V8TestingScope scope;
+
+ ProfilerGroup* profiler_group = ProfilerGroup::From(scope.GetIsolate());
+
+ ProfilerInitOptions* init_options = ProfilerInitOptions::Create();
+ init_options->setSampleInterval(0);
+
+ HeapVector<Member<Profiler>> profilers;
+ for (auto i = 0; i < kLargeProfilerCount; i++) {
+ // TODO(acomminos): The V8 public API should likely be changed to expose
+ // exceeding the profile limit during creation. This would enable
+ // instantiation of profiles to cause a promise rejection instead.
+ profilers.push_back(profiler_group->CreateProfiler(
+ scope.GetScriptState(), *init_options, base::TimeTicks(),
+ scope.GetExceptionState()));
+ }
+ for (auto profiler : profilers) {
+ profiler->stop(scope.GetScriptState());
+ }
+}
+
} // namespace blink
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 fbd8c2d6a8a..2c5833fb697 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(blink::Visitor* visitor) {
+void TaskAttributionTiming::Trace(Visitor* visitor) {
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 1e9a4cd7687..f5e72b9e8ec 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
@@ -16,15 +16,6 @@ class TaskAttributionTiming final : public PerformanceEntry {
DEFINE_WRAPPERTYPEINFO();
public:
- static TaskAttributionTiming* Create(const AtomicString& type,
- const AtomicString& container_type,
- const String& container_src,
- const String& container_id,
- const String& container_name) {
- return MakeGarbageCollected<TaskAttributionTiming>(
- type, container_type, container_src, container_id, container_name);
- }
-
AtomicString entryType() const override;
PerformanceEntryType EntryTypeEnum() const override;
@@ -33,7 +24,7 @@ class TaskAttributionTiming final : public PerformanceEntry {
String containerId() const;
String containerName() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 112e390b537..3725580274d 100644
--- a/chromium/third_party/blink/renderer/core/timing/window_performance.cc
+++ b/chromium/third_party/blink/renderer/core/timing/window_performance.cc
@@ -158,14 +158,19 @@ WindowPerformance::WindowPerformance(LocalDOMWindow* window)
: Performance(
ToTimeOrigin(window),
window->document()->GetTaskRunner(TaskType::kPerformanceTimeline)),
- DOMWindowClient(window) {}
+ DOMWindowClient(window) {
+ DCHECK(GetFrame());
+ DCHECK(GetFrame()->GetPerformanceMonitor());
+ GetFrame()->GetPerformanceMonitor()->Subscribe(
+ PerformanceMonitor::kLongTask, kLongTaskObserverThreshold, this);
+}
WindowPerformance::~WindowPerformance() = default;
ExecutionContext* WindowPerformance::GetExecutionContext() const {
if (!GetFrame())
return nullptr;
- return GetFrame()->GetDocument();
+ return GetFrame()->GetDocument()->ToExecutionContext();
}
PerformanceTiming* WindowPerformance::timing() const {
@@ -204,36 +209,22 @@ WindowPerformance::CreateNavigationTimingInstance() {
ResourceTimingInfo* info = document_loader->GetNavigationTimingInfo();
if (!info)
return nullptr;
- WebVector<WebServerTimingInfo> server_timing =
+ HeapVector<Member<PerformanceServerTiming>> server_timing =
PerformanceServerTiming::ParseServerTiming(*info);
- if (!server_timing.empty())
+ if (!server_timing.IsEmpty())
document_loader->CountUse(WebFeature::kPerformanceServerTiming);
return MakeGarbageCollected<PerformanceNavigationTiming>(
- GetFrame(), info, time_origin_, server_timing);
-}
-
-void WindowPerformance::UpdateLongTaskInstrumentation() {
- if (!GetFrame() || !GetFrame()->GetDocument())
- return;
-
- if (HasObserverFor(PerformanceEntry::kLongTask)) {
- UseCounter::Count(GetFrame()->GetDocument(), WebFeature::kLongTaskObserver);
- GetFrame()->GetPerformanceMonitor()->Subscribe(
- PerformanceMonitor::kLongTask, kLongTaskObserverThreshold, this);
- } else {
- GetFrame()->GetPerformanceMonitor()->UnsubscribeAll(this);
- }
+ GetFrame(), info, time_origin_, std::move(server_timing));
}
void WindowPerformance::BuildJSONValue(V8ObjectBuilder& builder) const {
Performance::BuildJSONValue(builder);
- builder.Add("timing", timing()->toJSONForBinding(builder.GetScriptState()));
- builder.Add("navigation",
- navigation()->toJSONForBinding(builder.GetScriptState()));
+ builder.Add("timing", timing());
+ builder.Add("navigation", navigation());
}
-void WindowPerformance::Trace(blink::Visitor* visitor) {
+void WindowPerformance::Trace(Visitor* visitor) {
visitor->Trace(event_timings_);
visitor->Trace(first_pointer_down_event_timing_);
visitor->Trace(navigation_);
@@ -268,7 +259,7 @@ std::pair<AtomicString, DOMWindow*> WindowPerformance::SanitizedAttribution(
return std::make_pair(kAmbiguousAttribution, nullptr);
}
- Document* document = DynamicTo<Document>(task_context);
+ Document* document = Document::DynamicFrom(task_context);
if (!document || !document->GetFrame()) {
// Unable to attribute as no script was involved.
DEFINE_STATIC_LOCAL(const AtomicString, kUnknownAttribution, ("unknown"));
@@ -367,7 +358,7 @@ void WindowPerformance::RegisterEventTiming(const AtomicString& event_type,
}
}
-void WindowPerformance::ReportEventTimings(WebWidgetClient::SwapResult result,
+void WindowPerformance::ReportEventTimings(WebSwapResult result,
base::TimeTicks timestamp) {
DOMHighResTimeStamp end_time = MonotonicTimeToDOMHighResTimeStamp(timestamp);
bool event_timing_enabled =
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 dbae52e14ac..891cab42ced 100644
--- a/chromium/third_party/blink/renderer/core/timing/window_performance.h
+++ b/chromium/third_party/blink/renderer/core/timing/window_performance.h
@@ -32,9 +32,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_WINDOW_PERFORMANCE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_WINDOW_PERFORMANCE_H_
-#include "third_party/blink/public/web/web_widget_client.h"
+#include "third_party/blink/public/web/web_swap_result.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/frame/performance_monitor.h"
#include "third_party/blink/renderer/core/timing/memory_info.h"
#include "third_party/blink/renderer/core/timing/performance.h"
@@ -61,8 +61,6 @@ class CORE_EXPORT WindowPerformance final : public Performance,
MemoryInfo* memory() const override;
- void UpdateLongTaskInstrumentation() override;
-
bool FirstInputDetected() const { return !!first_input_timing_; }
// This method creates a PerformanceEventTiming and if needed creates a swap
@@ -95,7 +93,7 @@ class CORE_EXPORT WindowPerformance final : public Performance,
const String& url,
Element*);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
PerformanceNavigationTiming* CreateNavigationTimingInstance() override;
@@ -115,8 +113,7 @@ 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(WebWidgetClient::SwapResult result,
- base::TimeTicks timestamp);
+ void ReportEventTimings(WebSwapResult result, base::TimeTicks timestamp);
void DispatchFirstInputTiming(PerformanceEventTiming* entry);
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 0571ec24913..6c08be70d09 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
@@ -10,6 +10,7 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/core/dom/document_init.h"
+#include "third_party/blink/renderer/core/execution_context/security_context_init.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/performance_monitor.h"
#include "third_party/blink/renderer/core/loader/document_load_timing.h"
@@ -34,10 +35,6 @@ class WindowPerformanceTest : public testing::Test {
void SetUp() override {
test_task_runner_ = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
ResetPerformance();
-
- // Create another dummy page holder and pretend this is the iframe.
- another_page_holder_ = std::make_unique<DummyPageHolder>(IntSize(400, 300));
- another_page_holder_->GetDocument().SetURL(KURL("https://iframed.com/bar"));
}
bool ObservingLongTasks() {
@@ -58,27 +55,20 @@ class WindowPerformanceTest : public testing::Test {
void SimulateDidProcessLongTask() {
auto* monitor = GetFrame()->GetPerformanceMonitor();
- monitor->WillExecuteScript(GetDocument());
+ monitor->WillExecuteScript(GetDocument()->ToExecutionContext());
monitor->DidExecuteScript();
monitor->DidProcessTask(
base::TimeTicks(), base::TimeTicks() + base::TimeDelta::FromSeconds(1));
}
void SimulateSwapPromise(base::TimeTicks timestamp) {
- performance_->ReportEventTimings(WebWidgetClient::SwapResult::kDidSwap,
- timestamp);
+ performance_->ReportEventTimings(WebSwapResult::kDidSwap, timestamp);
}
LocalFrame* GetFrame() const { return &page_holder_->GetFrame(); }
Document* GetDocument() const { return &page_holder_->GetDocument(); }
- LocalFrame* AnotherFrame() const { return &another_page_holder_->GetFrame(); }
-
- Document* AnotherDocument() const {
- return &another_page_holder_->GetDocument();
- }
-
String SanitizedAttribution(ExecutionContext* context,
bool has_multiple_contexts,
LocalFrame* observer_frame) {
@@ -88,10 +78,12 @@ class WindowPerformanceTest : public testing::Test {
}
void ResetPerformance() {
+ page_holder_ = nullptr;
page_holder_ = std::make_unique<DummyPageHolder>(IntSize(800, 600));
page_holder_->GetDocument().SetURL(KURL("https://example.com"));
- performance_ = MakeGarbageCollected<WindowPerformance>(
- page_holder_->GetDocument().domWindow());
+
+ LocalDOMWindow* window = LocalDOMWindow::From(GetScriptState());
+ performance_ = DOMWindowPerformance::performance(*window);
unified_clock_ = std::make_unique<Performance::UnifiedClock>(
test_task_runner_->GetMockClock(),
test_task_runner_->GetMockTickClock());
@@ -99,26 +91,28 @@ class WindowPerformanceTest : public testing::Test {
performance_->time_origin_ = GetTimeOrigin();
}
+ ScriptState* GetScriptState() const {
+ return ToScriptStateForMainWorld(page_holder_->GetDocument().GetFrame());
+ }
+
Persistent<WindowPerformance> performance_;
std::unique_ptr<DummyPageHolder> page_holder_;
- std::unique_ptr<DummyPageHolder> another_page_holder_;
scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner_;
std::unique_ptr<Performance::UnifiedClock> unified_clock_;
};
TEST_F(WindowPerformanceTest, LongTaskObserverInstrumentation) {
- performance_->UpdateLongTaskInstrumentation();
- EXPECT_FALSE(ObservingLongTasks());
+ // Check that we're always observing longtasks
+ EXPECT_TRUE(ObservingLongTasks());
- // Adding LongTask observer (with filer option) enables instrumentation.
+ // Adding LongTask observer.
AddLongTaskObserver();
- performance_->UpdateLongTaskInstrumentation();
EXPECT_TRUE(ObservingLongTasks());
- // Removing LongTask observer disables instrumentation.
+ // Removing LongTask observer doeos not cause us to stop observing. We still
+ // observe because entries should still be added to the longtasks buffer.
RemoveLongTaskObserver();
- performance_->UpdateLongTaskInstrumentation();
- EXPECT_FALSE(ObservingLongTasks());
+ EXPECT_TRUE(ObservingLongTasks());
}
TEST_F(WindowPerformanceTest, SanitizedLongTaskName) {
@@ -126,20 +120,28 @@ TEST_F(WindowPerformanceTest, SanitizedLongTaskName) {
EXPECT_EQ("unknown", SanitizedAttribution(nullptr, false, GetFrame()));
// Attribute for same context (and same origin).
- EXPECT_EQ("self", SanitizedAttribution(GetDocument(), false, GetFrame()));
+ EXPECT_EQ("self", SanitizedAttribution(GetDocument()->ToExecutionContext(),
+ false, GetFrame()));
// Unable to attribute, when multiple script execution contents are involved.
EXPECT_EQ("multiple-contexts",
- SanitizedAttribution(GetDocument(), true, GetFrame()));
+ SanitizedAttribution(GetDocument()->ToExecutionContext(), true,
+ GetFrame()));
}
TEST_F(WindowPerformanceTest, SanitizedLongTaskName_CrossOrigin) {
+ // Create another dummy page holder and pretend it is an iframe.
+ DummyPageHolder another_page(IntSize(400, 300));
+ another_page.GetDocument().SetURL(KURL("https://iframed.com/bar"));
+
// Unable to attribute, when no execution contents are available.
EXPECT_EQ("unknown", SanitizedAttribution(nullptr, false, GetFrame()));
// Attribute for same context (and same origin).
- EXPECT_EQ("cross-origin-unreachable",
- SanitizedAttribution(AnotherDocument(), false, GetFrame()));
+ EXPECT_EQ(
+ "cross-origin-unreachable",
+ SanitizedAttribution(another_page.GetDocument().ToExecutionContext(),
+ false, GetFrame()));
}
// https://crbug.com/706798: Checks that after navigation that have replaced the
@@ -147,15 +149,10 @@ TEST_F(WindowPerformanceTest, SanitizedLongTaskName_CrossOrigin) {
// to the old window do not cause a crash.
TEST_F(WindowPerformanceTest, NavigateAway) {
AddLongTaskObserver();
- performance_->UpdateLongTaskInstrumentation();
EXPECT_TRUE(ObservingLongTasks());
// Simulate navigation commit.
- DocumentInit init = DocumentInit::Create().WithDocumentLoader(
- GetFrame()->Loader().GetDocumentLoader());
- GetDocument()->Shutdown();
- GetFrame()->SetDOMWindow(MakeGarbageCollected<LocalDOMWindow>(*GetFrame()));
- GetFrame()->DomWindow()->InstallNewDocument(AtomicString(), init, false);
+ GetFrame()->DomWindow()->FrameDestroyed();
// m_performance is still alive, and should not crash when notified.
SimulateDidProcessLongTask();
@@ -184,8 +181,10 @@ TEST(PerformanceLifetimeTest, SurviveContextSwitch) {
// Simulate changing the document while keeping the window.
page_holder->GetDocument().Shutdown();
page_holder->GetFrame().DomWindow()->InstallNewDocument(
- AtomicString(),
- DocumentInit::Create().WithDocumentLoader(document_loader), false);
+ DocumentInit::Create()
+ .WithDocumentLoader(document_loader)
+ .WithTypeFrom("text/html"),
+ false);
EXPECT_EQ(perf, DOMWindowPerformance::performance(
*page_holder->GetFrame().DomWindow()));
@@ -198,7 +197,10 @@ TEST(PerformanceLifetimeTest, SurviveContextSwitch) {
// Make sure the output entries with the same timestamps follow the insertion
// order. (http://crbug.com/767560)
TEST_F(WindowPerformanceTest, EnsureEntryListOrder) {
- V8TestingScope scope;
+ // Need to have an active V8 context for ScriptValues to operate.
+ v8::HandleScope handle_scope(GetScriptState()->GetIsolate());
+ v8::Local<v8::Context> context = GetScriptState()->GetContext();
+ v8::Context::Scope context_scope(context);
auto initial_offset =
test_task_runner_->NowTicks().since_origin().InSecondsF();
test_task_runner_->FastForwardBy(GetTimeOrigin() - base::TimeTicks());
@@ -206,12 +208,12 @@ TEST_F(WindowPerformanceTest, EnsureEntryListOrder) {
DummyExceptionStateForTesting exception_state;
test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(2));
for (int i = 0; i < 8; i++) {
- performance_->mark(scope.GetScriptState(), AtomicString::Number(i), nullptr,
+ performance_->mark(GetScriptState(), AtomicString::Number(i), nullptr,
exception_state);
}
test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(2));
for (int i = 8; i < 17; i++) {
- performance_->mark(scope.GetScriptState(), AtomicString::Number(i), nullptr,
+ performance_->mark(GetScriptState(), AtomicString::Number(i), nullptr,
exception_state);
}
PerformanceEntryVector entries = performance_->getEntries();
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 bf5f6e0a9d4..ddde8497264 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(blink::Visitor* visitor) {
+void WorkerGlobalScopePerformance::Trace(Visitor* visitor) {
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 78af0fe015e..9a81ae19b62 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 f2c355119c8..d84e83462b5 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(blink::Visitor* visitor) {
+void WorkerPerformance::Trace(Visitor* visitor) {
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 666528973ab..42e6fa055b0 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<ExecutionContext> execution_context_;
diff --git a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_html.idl b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_html.idl
index 995d8149198..6db167e3b1d 100644
--- a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_html.idl
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_html.idl
@@ -4,11 +4,12 @@
// https://github.com/wicg/trusted-types
-typedef (DOMString or TrustedHTML) HTMLString;
+typedef [StringContext=TrustedHTML] DOMString HTMLString;
[
Exposed=Window,
- RuntimeEnabled=TrustedDOMTypes
+ RuntimeEnabled=TrustedDOMTypes,
+ SecureContext
] interface TrustedHTML {
stringifier;
};
diff --git a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_script.idl b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_script.idl
index a8f86e4e2a5..34f29afa302 100644
--- a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_script.idl
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_script.idl
@@ -4,11 +4,12 @@
// https://github.com/wicg/trusted-types
-typedef (DOMString or TrustedScript) ScriptString;
+typedef [StringContext=TrustedScript] DOMString ScriptString;
[
Exposed=Window,
- RuntimeEnabled=TrustedDOMTypes
+ RuntimeEnabled=TrustedDOMTypes,
+ SecureContext
] interface TrustedScript {
stringifier;
};
diff --git a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_script_url.idl b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_script_url.idl
index 3a4faeeaf2f..84695e2cfa6 100644
--- a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_script_url.idl
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_script_url.idl
@@ -4,11 +4,12 @@
// https://github.com/wicg/trusted-types
-typedef (DOMString or TrustedScriptURL) ScriptURLString;
+typedef [StringContext=TrustedScriptURL] USVString ScriptURLString;
[
Exposed=Window,
- RuntimeEnabled=TrustedDOMTypes
+ RuntimeEnabled=TrustedDOMTypes,
+ SecureContext
] interface TrustedScriptURL {
stringifier;
};
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 cc197c65c3c..2ffbaa90a0c 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
@@ -19,26 +19,31 @@ TrustedTypePolicy::TrustedTypePolicy(const String& policy_name,
TrustedHTML* TrustedTypePolicy::createHTML(ScriptState* script_state,
const String& input,
+ const HeapVector<ScriptValue>& args,
ExceptionState& exception_state) {
- return CreateHTML(script_state->GetIsolate(), input, exception_state);
+ return CreateHTML(script_state->GetIsolate(), input, args, exception_state);
}
TrustedScript* TrustedTypePolicy::createScript(
ScriptState* script_state,
const String& input,
+ const HeapVector<ScriptValue>& args,
ExceptionState& exception_state) {
- return CreateScript(script_state->GetIsolate(), input, exception_state);
+ return CreateScript(script_state->GetIsolate(), input, args, exception_state);
}
TrustedScriptURL* TrustedTypePolicy::createScriptURL(
ScriptState* script_state,
const String& input,
+ const HeapVector<ScriptValue>& args,
ExceptionState& exception_state) {
- return CreateScriptURL(script_state->GetIsolate(), input, exception_state);
+ return CreateScriptURL(script_state->GetIsolate(), input, args,
+ exception_state);
}
TrustedHTML* TrustedTypePolicy::CreateHTML(v8::Isolate* isolate,
const String& input,
+ const HeapVector<ScriptValue>& args,
ExceptionState& exception_state) {
if (!policy_options_->createHTML()) {
exception_state.ThrowTypeError(
@@ -48,7 +53,7 @@ TrustedHTML* TrustedTypePolicy::CreateHTML(v8::Isolate* isolate,
}
v8::TryCatch try_catch(isolate);
String html;
- if (!policy_options_->createHTML()->Invoke(nullptr, input).To(&html)) {
+ if (!policy_options_->createHTML()->Invoke(nullptr, input, args).To(&html)) {
DCHECK(try_catch.HasCaught());
exception_state.RethrowV8Exception(try_catch.Exception());
return nullptr;
@@ -59,6 +64,7 @@ TrustedHTML* TrustedTypePolicy::CreateHTML(v8::Isolate* isolate,
TrustedScript* TrustedTypePolicy::CreateScript(
v8::Isolate* isolate,
const String& input,
+ const HeapVector<ScriptValue>& args,
ExceptionState& exception_state) {
if (!policy_options_->createScript()) {
exception_state.ThrowTypeError(
@@ -68,7 +74,9 @@ TrustedScript* TrustedTypePolicy::CreateScript(
}
v8::TryCatch try_catch(isolate);
String script;
- if (!policy_options_->createScript()->Invoke(nullptr, input).To(&script)) {
+ if (!policy_options_->createScript()
+ ->Invoke(nullptr, input, args)
+ .To(&script)) {
DCHECK(try_catch.HasCaught());
exception_state.RethrowV8Exception(try_catch.Exception());
return nullptr;
@@ -79,6 +87,7 @@ TrustedScript* TrustedTypePolicy::CreateScript(
TrustedScriptURL* TrustedTypePolicy::CreateScriptURL(
v8::Isolate* isolate,
const String& input,
+ const HeapVector<ScriptValue>& args,
ExceptionState& exception_state) {
if (!policy_options_->createScriptURL()) {
exception_state.ThrowTypeError("Policy " + name_ +
@@ -89,7 +98,7 @@ TrustedScriptURL* TrustedTypePolicy::CreateScriptURL(
v8::TryCatch try_catch(isolate);
String script_url;
if (!policy_options_->createScriptURL()
- ->Invoke(nullptr, input)
+ ->Invoke(nullptr, input, args)
.To(&script_url)) {
DCHECK(try_catch.HasCaught());
exception_state.RethrowV8Exception(try_catch.Exception());
@@ -98,11 +107,23 @@ TrustedScriptURL* TrustedTypePolicy::CreateScriptURL(
return MakeGarbageCollected<TrustedScriptURL>(script_url);
}
+bool TrustedTypePolicy::HasCreateHTML() {
+ return policy_options_->createHTML();
+}
+
+bool TrustedTypePolicy::HasCreateScript() {
+ return policy_options_->createScript();
+}
+
+bool TrustedTypePolicy::HasCreateScriptURL() {
+ return policy_options_->createScriptURL();
+}
+
String TrustedTypePolicy::name() const {
return name_;
}
-void TrustedTypePolicy::Trace(blink::Visitor* visitor) {
+void TrustedTypePolicy::Trace(Visitor* visitor) {
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 dff1663bcfa..07382f6c8e2 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
@@ -5,8 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TRUSTEDTYPES_TRUSTED_TYPE_POLICY_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_TRUSTEDTYPES_TRUSTED_TYPE_POLICY_H_
+#include "third_party/blink/renderer/bindings/core/v8/v8_trusted_type_policy_options.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/trustedtypes/trusted_type_policy_options.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "v8/include/v8.h"
@@ -24,23 +24,41 @@ class CORE_EXPORT TrustedTypePolicy final : public ScriptWrappable {
public:
TrustedTypePolicy(const String& policy_name, TrustedTypePolicyOptions*);
- TrustedHTML* CreateHTML(v8::Isolate*, const String&, ExceptionState&);
- TrustedScript* CreateScript(v8::Isolate*, const String&, ExceptionState&);
+ TrustedHTML* CreateHTML(v8::Isolate*,
+ const String&,
+ const HeapVector<ScriptValue>&,
+ ExceptionState&);
+ TrustedScript* CreateScript(v8::Isolate*,
+ const String&,
+ const HeapVector<ScriptValue>&,
+ ExceptionState&);
TrustedScriptURL* CreateScriptURL(v8::Isolate*,
const String&,
+ const HeapVector<ScriptValue>&,
ExceptionState&);
// IDL generates calls with ScriptState*, which contains the Isolate*.
// These methods all call the Isolate* variant.
- TrustedHTML* createHTML(ScriptState*, const String&, ExceptionState&);
- TrustedScript* createScript(ScriptState*, const String&, ExceptionState&);
+ TrustedHTML* createHTML(ScriptState*,
+ const String&,
+ const HeapVector<ScriptValue>&,
+ ExceptionState&);
+ TrustedScript* createScript(ScriptState*,
+ const String&,
+ const HeapVector<ScriptValue>&,
+ ExceptionState&);
TrustedScriptURL* createScriptURL(ScriptState*,
const String&,
+ const HeapVector<ScriptValue>&,
ExceptionState&);
+ bool HasCreateHTML();
+ bool HasCreateScript();
+ bool HasCreateScriptURL();
+
String name() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
String name_;
diff --git a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.idl b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.idl
index f1767d89173..32798ed1e83 100644
--- a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.idl
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.idl
@@ -8,10 +8,11 @@ typedef (DOMString or TrustedHTML or TrustedScript or TrustedScriptURL) TrustedS
[
Exposed=Window,
- RuntimeEnabled=TrustedDOMTypes
+ RuntimeEnabled=TrustedDOMTypes,
+ SecureContext
] interface TrustedTypePolicy {
- [Unforgeable] readonly attribute DOMString name;
- [CallWith=ScriptState, RaisesException, Unforgeable] TrustedHTML createHTML(DOMString input);
- [CallWith=ScriptState, RaisesException, Unforgeable] TrustedScript createScript(DOMString input);
- [CallWith=ScriptState, RaisesException, Unforgeable] TrustedScriptURL createScriptURL(DOMString input);
+ readonly attribute DOMString name;
+ [CallWith=ScriptState, RaisesException] TrustedHTML createHTML(DOMString input, any... args);
+ [CallWith=ScriptState, RaisesException] TrustedScript createScript(DOMString input, any... args);
+ [CallWith=ScriptState, RaisesException] TrustedScriptURL createScriptURL(DOMString input, any... args);
};
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 9d450b114eb..aa29f891a4f 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
@@ -15,6 +15,7 @@
#include "third_party/blink/renderer/core/trustedtypes/trusted_type_policy.h"
#include "third_party/blink/renderer/core/trustedtypes/trusted_types_util.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/bindings/v8_dom_wrapper.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
@@ -70,19 +71,9 @@ TrustedTypePolicy* TrustedTypePolicyFactory::defaultPolicy() const {
}
TrustedTypePolicyFactory::TrustedTypePolicyFactory(ExecutionContext* context)
- : ContextClient(context),
+ : ExecutionContextClient(context),
empty_html_(MakeGarbageCollected<TrustedHTML>("")),
- empty_script_(MakeGarbageCollected<TrustedScript>("")) {
- UseCounter::Count(context, WebFeature::kTrustedTypesEnabled);
-}
-
-Vector<String> TrustedTypePolicyFactory::getPolicyNames() const {
- Vector<String> policyNames;
- for (const String name : policy_map_.Keys()) {
- policyNames.push_back(name);
- }
- return policyNames;
-}
+ empty_script_(MakeGarbageCollected<TrustedScript>("")) {}
const WrapperTypeInfo*
TrustedTypePolicyFactory::GetWrapperTypeInfoFromScriptValue(
@@ -141,20 +132,18 @@ const struct {
bool is_not_property : 1;
bool is_not_attribute : 1;
} kTypeTable[] = {
- {"embed", "src", nullptr, SpecificTrustedType::kTrustedScriptURL},
- {"iframe", "srcdoc", nullptr, SpecificTrustedType::kTrustedHTML},
- {"object", "codeBase", nullptr, SpecificTrustedType::kTrustedScriptURL},
- {"object", "data", nullptr, SpecificTrustedType::kTrustedScriptURL},
- {"script", "innerText", nullptr, SpecificTrustedType::kTrustedScript, false,
- true},
- {"script", "src", nullptr, SpecificTrustedType::kTrustedScriptURL},
- {"script", "text", nullptr, SpecificTrustedType::kTrustedScript, false,
+ {"embed", "src", nullptr, SpecificTrustedType::kScriptURL},
+ {"iframe", "srcdoc", nullptr, SpecificTrustedType::kHTML},
+ {"object", "codeBase", nullptr, SpecificTrustedType::kScriptURL},
+ {"object", "data", nullptr, SpecificTrustedType::kScriptURL},
+ {"script", "innerText", nullptr, SpecificTrustedType::kScript, false, true},
+ {"script", "src", nullptr, SpecificTrustedType::kScriptURL},
+ {"script", "text", nullptr, SpecificTrustedType::kScript, false, true},
+ {"script", "textContent", nullptr, SpecificTrustedType::kScript, false,
true},
- {"script", "textContent", nullptr, SpecificTrustedType::kTrustedScript,
- false, true},
- {"*", "innerHTML", nullptr, SpecificTrustedType::kTrustedHTML, false, true},
- {"*", "outerHTML", nullptr, SpecificTrustedType::kTrustedHTML, false, true},
- {"*", "on*", nullptr, SpecificTrustedType::kTrustedScript, true, false},
+ {"*", "innerHTML", nullptr, SpecificTrustedType::kHTML, false, true},
+ {"*", "outerHTML", nullptr, SpecificTrustedType::kHTML, false, true},
+ {"*", "on*", nullptr, SpecificTrustedType::kScript, true, false},
};
// Does a type table entry match a property?
@@ -186,11 +175,11 @@ bool EqualsAttribute(decltype(*kTypeTable)& left,
String getTrustedTypeName(SpecificTrustedType type) {
switch (type) {
- case SpecificTrustedType::kTrustedHTML:
+ case SpecificTrustedType::kHTML:
return "TrustedHTML";
- case SpecificTrustedType::kTrustedScript:
+ case SpecificTrustedType::kScript:
return "TrustedScript";
- case SpecificTrustedType::kTrustedScriptURL:
+ case SpecificTrustedType::kScriptURL:
return "TrustedScriptURL";
case SpecificTrustedType::kNone:
return String();
@@ -317,9 +306,9 @@ void TrustedTypePolicyFactory::CountTrustedTypeAssignmentError() {
}
}
-void TrustedTypePolicyFactory::Trace(blink::Visitor* visitor) {
+void TrustedTypePolicyFactory::Trace(Visitor* visitor) {
ScriptWrappable::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
visitor->Trace(empty_html_);
visitor->Trace(empty_script_);
visitor->Trace(policy_map_);
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 29f32ae78ed..cc2a11fb888 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
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_TRUSTEDTYPES_TRUSTED_TYPE_POLICY_FACTORY_H_
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -21,8 +21,9 @@ class TrustedScript;
class TrustedTypePolicy;
class TrustedTypePolicyOptions;
-class CORE_EXPORT TrustedTypePolicyFactory final : public ScriptWrappable,
- public ContextClient {
+class CORE_EXPORT TrustedTypePolicyFactory final
+ : public ScriptWrappable,
+ public ExecutionContextClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(TrustedTypePolicyFactory);
@@ -36,8 +37,6 @@ class CORE_EXPORT TrustedTypePolicyFactory final : public ScriptWrappable,
TrustedTypePolicy* defaultPolicy() const;
- Vector<String> getPolicyNames() const;
-
bool isHTML(ScriptState*, const ScriptValue&);
bool isScript(ScriptState*, const ScriptValue&);
bool isScriptURL(ScriptState*, const ScriptValue&);
@@ -69,7 +68,7 @@ class CORE_EXPORT TrustedTypePolicyFactory final : public ScriptWrappable,
// relate it to the total number of TT enabled documents.)
void CountTrustedTypeAssignmentError();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
const WrapperTypeInfo* GetWrapperTypeInfoFromScriptValue(ScriptState*,
diff --git a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.idl b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.idl
index 96fb881de3a..02fbefc46ff 100644
--- a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.idl
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.idl
@@ -6,17 +6,17 @@
[
Exposed=(Window, Worker),
- RuntimeEnabled=TrustedDOMTypes
+ RuntimeEnabled=TrustedDOMTypes,
+ SecureContext
] interface TrustedTypePolicyFactory {
- [RaisesException, Unforgeable] TrustedTypePolicy createPolicy(DOMString policyName, TrustedTypePolicyOptions policyOptions);
- [Unforgeable] readonly attribute TrustedTypePolicy defaultPolicy;
+ [RaisesException] TrustedTypePolicy createPolicy(DOMString policyName, TrustedTypePolicyOptions policyOptions);
+ readonly attribute TrustedTypePolicy defaultPolicy;
// All the policy object names that have been created
- [Affects=Nothing, Unforgeable] sequence<DOMString> getPolicyNames();
- [CallWith=ScriptState, Unforgeable] boolean isHTML(any checkedObject);
- [CallWith=ScriptState, Unforgeable] boolean isScript(any checkedObject);
- [CallWith=ScriptState, Unforgeable] boolean isScriptURL(any checkedObject);
- [Unforgeable] readonly attribute TrustedHTML emptyHTML;
- [Unforgeable] readonly attribute TrustedScript emptyScript;
+ [CallWith=ScriptState] boolean isHTML(any checkedObject);
+ [CallWith=ScriptState] boolean isScript(any checkedObject);
+ [CallWith=ScriptState] boolean isScriptURL(any checkedObject);
+ readonly attribute TrustedHTML emptyHTML;
+ readonly attribute TrustedScript emptyScript;
// Trusted Types metadata, following the proposal in:
// https://github.com/WICG/trusted-types/pull/149/commits/ecd9ab0b6993674951bfc7b44a04530fce7468a7
diff --git a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_options.idl b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_options.idl
index bec526d7cb9..e43366bd5f9 100644
--- a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_options.idl
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_options.idl
@@ -8,9 +8,8 @@ dictionary TrustedTypePolicyOptions {
CreateHTMLCallback createHTML;
CreateScriptCallback createScript;
CreateURLCallback createScriptURL;
- CreateURLCallback createURL;
};
-callback CreateHTMLCallback = DOMString? (DOMString input);
-callback CreateScriptCallback = DOMString? (DOMString input);
-callback CreateURLCallback = USVString? (DOMString input);
+callback CreateHTMLCallback = DOMString? (DOMString input, any... args);
+callback CreateScriptCallback = DOMString? (DOMString input, any... args);
+callback CreateURLCallback = USVString? (DOMString input, any... args);
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 315b81d4eb3..23103e70b68 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
@@ -6,22 +6,21 @@
#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/string_or_trusted_html.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_html_or_trusted_script_or_trusted_script_url.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script.h"
-#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script_url.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h"
-#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/dom/node.h"
-#include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/local_frame.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"
#include "third_party/blink/renderer/core/trustedtypes/trusted_script_url.h"
#include "third_party/blink/renderer/core/trustedtypes/trusted_type_policy.h"
#include "third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.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/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
@@ -29,28 +28,24 @@ namespace blink {
namespace {
-// This value is derived from the Trusted Types spec (draft), and determines the
-// maximum length of the sample value in the violation reports.
-const unsigned kReportedValueMaximumLength = 40;
-
enum TrustedTypeViolationKind {
- kAnyTrustedTypeAssignment,
kTrustedHTMLAssignment,
kTrustedScriptAssignment,
kTrustedScriptURLAssignment,
kTrustedHTMLAssignmentAndDefaultPolicyFailed,
+ kTrustedHTMLAssignmentAndNoDefaultPolicyExisted,
kTrustedScriptAssignmentAndDefaultPolicyFailed,
+ kTrustedScriptAssignmentAndNoDefaultPolicyExisted,
kTrustedScriptURLAssignmentAndDefaultPolicyFailed,
- kTextNodeScriptAssignment,
- kTextNodeScriptAssignmentAndDefaultPolicyFailed,
+ kTrustedScriptURLAssignmentAndNoDefaultPolicyExisted,
kNavigateToJavascriptURL,
kNavigateToJavascriptURLAndDefaultPolicyFailed,
+ kScriptExecution,
+ kScriptExecutionAndDefaultPolicyFailed,
};
const char* GetMessage(TrustedTypeViolationKind kind) {
switch (kind) {
- case kAnyTrustedTypeAssignment:
- return "This document requires any trusted type assignment.";
case kTrustedHTMLAssignment:
return "This document requires 'TrustedHTML' assignment.";
case kTrustedScriptAssignment:
@@ -60,21 +55,21 @@ const char* GetMessage(TrustedTypeViolationKind kind) {
case kTrustedHTMLAssignmentAndDefaultPolicyFailed:
return "This document requires 'TrustedHTML' assignment and the "
"'default' policy failed to execute.";
+ case kTrustedHTMLAssignmentAndNoDefaultPolicyExisted:
+ return "This document requires 'TrustedHTML' assignment and no "
+ "'default' policy for 'TrustedHTML' has been defined.";
case kTrustedScriptAssignmentAndDefaultPolicyFailed:
return "This document requires 'TrustedScript' assignment and the "
"'default' policy failed to execute.";
+ case kTrustedScriptAssignmentAndNoDefaultPolicyExisted:
+ return "This document requires 'TrustedScript' assignment and no "
+ "'default' policy for 'TrustedScript' has been defined.";
case kTrustedScriptURLAssignmentAndDefaultPolicyFailed:
return "This document requires 'TrustedScriptURL' assignment and the "
"'default' policy failed to execute.";
- case kTextNodeScriptAssignment:
- return "This document requires 'TrustedScript' assignment, "
- "and inserting a text node into a script element is equivalent to "
- "a 'TrustedScript' assignment.";
- case kTextNodeScriptAssignmentAndDefaultPolicyFailed:
- return "This document requires 'TrustedScript' assignment. "
- "Inserting a text node into a script element is equivalent to "
- "a 'TrustedScript' assignment and the default policy failed to "
- "execute.";
+ case kTrustedScriptURLAssignmentAndNoDefaultPolicyExisted:
+ return "This document requires 'TrustedScriptURL' assignment and no "
+ "'default' policy for 'TrustedScriptURL' has been defined.";
case kNavigateToJavascriptURL:
return "This document requires 'TrustedScript' assignment. "
"Navigating to a javascript:-URL is equivalent to a "
@@ -82,36 +77,60 @@ const char* GetMessage(TrustedTypeViolationKind kind) {
case kNavigateToJavascriptURLAndDefaultPolicyFailed:
return "This document requires 'TrustedScript' assignment. "
"Navigating to a javascript:-URL is equivalent to a "
- "'TrustedScript' assignment and the default policy failed to"
+ "'TrustedScript' assignment and the 'default' policy failed to"
"execute.";
+ case kScriptExecution:
+ return "This document requires 'TrustedScript' assignment. "
+ "This script element was modified without use of TrustedScript "
+ "assignment.";
+ case kScriptExecutionAndDefaultPolicyFailed:
+ return "This document requires 'TrustedScript' assignment. "
+ "This script element was modified without use of TrustedScript "
+ "assignment and the 'default' policy failed to execute.";
}
NOTREACHED();
return "";
}
-std::pair<String, String> GetMessageAndSample(
- TrustedTypeViolationKind kind,
- const ExceptionState& exception_state,
- const String& value) {
+String GetSamplePrefix(const ExceptionState& exception_state) {
const char* interface_name = exception_state.InterfaceName();
const char* property_name = exception_state.PropertyName();
// We have two sample formats, one for eval and one for assignment.
// If we don't have the required values being passed in, just leave the
// sample empty.
- StringBuilder sample;
+ StringBuilder sample_prefix;
if (interface_name && strcmp("eval", interface_name) == 0) {
- sample.Append("eval");
+ sample_prefix.Append("eval");
} else if (interface_name && property_name) {
- sample.Append(interface_name);
- sample.Append(".");
- sample.Append(property_name);
+ sample_prefix.Append(interface_name);
+ sample_prefix.Append(" ");
+ sample_prefix.Append(property_name);
}
- if (!sample.IsEmpty()) {
- sample.Append(" ");
- sample.Append(value.Left(kReportedValueMaximumLength));
+ return sample_prefix.ToString();
+}
+
+const char* GetElementName(const ScriptElementBase::Type type) {
+ switch (type) {
+ case ScriptElementBase::Type::kHTMLScriptElement:
+ return "HTMLScriptElement";
+ case ScriptElementBase::Type::kSVGScriptElement:
+ return "SVGScriptElement";
}
- return std::make_pair<String, String>(GetMessage(kind), sample.ToString());
+ NOTREACHED();
+ return "";
+}
+
+HeapVector<ScriptValue> GetDefaultCallbackArgs(
+ v8::Isolate* isolate,
+ const char* type,
+ const ExceptionState& exception_state) {
+ ScriptState* script_state = ScriptState::Current(isolate);
+ HeapVector<ScriptValue> args;
+ args.push_back(ScriptValue::From(script_state, type));
+ args.push_back(
+ ScriptValue::From(script_state, GetSamplePrefix(exception_state)));
+ return args;
}
// Handle failure of a Trusted Type assignment.
@@ -134,14 +153,13 @@ bool TrustedTypeFail(TrustedTypeViolationKind kind,
if (execution_context->GetTrustedTypes())
execution_context->GetTrustedTypes()->CountTrustedTypeAssignmentError();
- String message;
- String sample;
- std::tie(message, sample) = GetMessageAndSample(kind, exception_state, value);
- bool allow = execution_context->GetSecurityContext()
- .GetContentSecurityPolicy()
- ->AllowTrustedTypeAssignmentFailure(message, sample);
+ bool allow =
+ execution_context->GetSecurityContext()
+ .GetContentSecurityPolicy()
+ ->AllowTrustedTypeAssignmentFailure(GetMessage(kind), value,
+ GetSamplePrefix(exception_state));
if (!allow) {
- exception_state.ThrowTypeError(message);
+ exception_state.ThrowTypeError(GetMessage(kind));
}
return !allow;
}
@@ -153,199 +171,174 @@ TrustedTypePolicy* GetDefaultPolicy(const ExecutionContext* execution_context) {
: nullptr;
}
-} // namespace
-
-bool RequireTrustedTypesCheck(const ExecutionContext* execution_context) {
- return execution_context && execution_context->RequireTrustedTypes() &&
- !ContentSecurityPolicy::ShouldBypassMainWorld(execution_context);
-}
+// Functionally identical to TrustedTypesCheckForScript(const String&, ..), but
+// to be called outside of regular script execution. This is required for both
+// GetStringForScriptExecution & TrustedTypesCheckForJavascriptURLinNavigation,
+// and has a number of additional parameters to enable proper error reporting
+// for each case.
+String GetStringFromScriptHelper(
+ const String& script,
+ Document* doc,
+
+ // Parameters to customize error messages:
+ const char* element_name_for_exception,
+ const char* attribute_name_for_exception,
+ TrustedTypeViolationKind violation_kind,
+ TrustedTypeViolationKind violation_kind_when_default_policy_failed) {
+ if (!doc)
+ return script;
+ bool require_trusted_type =
+ RequireTrustedTypesCheck(doc->ToExecutionContext());
+ if (!require_trusted_type)
+ return script;
-String GetStringFromTrustedType(
- const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&
- string_or_trusted_type,
- const ExecutionContext* execution_context,
- ExceptionState& exception_state) {
- DCHECK(!string_or_trusted_type.IsNull());
+ // Set up JS context & friends.
+ //
+ // All other functions in here are expected to be called during JS execution,
+ // where naturally everything is properly set up for more JS execution.
+ // This one is called during navigation, and thus needs to do a bit more
+ // work. We need two JavaScript-ish things:
+ // - TrustedTypeFail expects an ExceptionState, which it will use to throw
+ // an exception. In our case, we will always clear the exception (as there
+ // is no user script to pass it to), and we only use this as a signalling
+ // mechanism.
+ // - If the default policy applies, we need to execute the JS callback.
+ // Unlike the various ScriptController::Execute* and ..::Eval* methods,
+ // we are not executing a source String, but an already compiled callback
+ // function.
+ v8::HandleScope handle_scope(doc->GetIsolate());
+ ScriptState::Scope script_state_scope(
+ ScriptState::From(static_cast<LocalWindowProxyManager*>(
+ doc->GetFrame()->GetWindowProxyManager())
+ ->MainWorldProxy()
+ ->ContextIfInitialized()));
+ ExceptionState exception_state(
+ doc->GetIsolate(), ExceptionState::kUnknownContext,
+ element_name_for_exception, attribute_name_for_exception);
- if (string_or_trusted_type.IsString() &&
- RequireTrustedTypesCheck(execution_context)) {
- TrustedTypeFail(
- kAnyTrustedTypeAssignment, execution_context, exception_state,
- GetStringFromTrustedTypeWithoutCheck(string_or_trusted_type));
- return g_empty_string;
+ TrustedTypePolicy* default_policy =
+ GetDefaultPolicy(doc->ToExecutionContext());
+ if (!default_policy) {
+ if (TrustedTypeFail(violation_kind, doc->ToExecutionContext(),
+ exception_state, script)) {
+ exception_state.ClearException();
+ return String();
+ }
+ return script;
}
- if (string_or_trusted_type.IsTrustedHTML())
- return string_or_trusted_type.GetAsTrustedHTML()->toString();
- if (string_or_trusted_type.IsTrustedScript())
- return string_or_trusted_type.GetAsTrustedScript()->toString();
- if (string_or_trusted_type.IsTrustedScriptURL())
- return string_or_trusted_type.GetAsTrustedScriptURL()->toString();
-
- return string_or_trusted_type.GetAsString();
-}
-
-String GetStringFromTrustedTypeWithoutCheck(
- const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&
- string_or_trusted_type) {
- if (string_or_trusted_type.IsTrustedHTML())
- return string_or_trusted_type.GetAsTrustedHTML()->toString();
- if (string_or_trusted_type.IsTrustedScript())
- return string_or_trusted_type.GetAsTrustedScript()->toString();
- if (string_or_trusted_type.IsTrustedScriptURL())
- return string_or_trusted_type.GetAsTrustedScriptURL()->toString();
- if (string_or_trusted_type.IsString())
- return string_or_trusted_type.GetAsString();
-
- return g_empty_string;
-}
+ TrustedScript* result = default_policy->CreateScript(
+ doc->GetIsolate(), script,
+ GetDefaultCallbackArgs(doc->GetIsolate(), "TrustedScript",
+ exception_state),
+ exception_state);
+ if (exception_state.HadException()) {
+ exception_state.ClearException();
+ return String();
+ }
-String GetStringFromSpecificTrustedType(
- const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&
- string_or_trusted_type,
- SpecificTrustedType specific_trusted_type,
- const ExecutionContext* execution_context,
- ExceptionState& exception_state) {
- switch (specific_trusted_type) {
- case SpecificTrustedType::kNone:
- return GetStringFromTrustedTypeWithoutCheck(string_or_trusted_type);
- case SpecificTrustedType::kTrustedHTML: {
- StringOrTrustedHTML string_or_trusted_html =
- string_or_trusted_type.IsTrustedHTML()
- ? StringOrTrustedHTML::FromTrustedHTML(
- string_or_trusted_type.GetAsTrustedHTML())
- : StringOrTrustedHTML::FromString(
- GetStringFromTrustedTypeWithoutCheck(
- string_or_trusted_type));
- return GetStringFromTrustedHTML(string_or_trusted_html, execution_context,
- exception_state);
- }
- case SpecificTrustedType::kTrustedScript: {
- StringOrTrustedScript string_or_trusted_script =
- string_or_trusted_type.IsTrustedScript()
- ? StringOrTrustedScript::FromTrustedScript(
- string_or_trusted_type.GetAsTrustedScript())
- : StringOrTrustedScript::FromString(
- GetStringFromTrustedTypeWithoutCheck(
- string_or_trusted_type));
- return GetStringFromTrustedScript(string_or_trusted_script,
- execution_context, exception_state);
- }
- case SpecificTrustedType::kTrustedScriptURL: {
- StringOrTrustedScriptURL string_or_trusted_script_url =
- string_or_trusted_type.IsTrustedScriptURL()
- ? StringOrTrustedScriptURL::FromTrustedScriptURL(
- string_or_trusted_type.GetAsTrustedScriptURL())
- : StringOrTrustedScriptURL::FromString(
- GetStringFromTrustedTypeWithoutCheck(
- string_or_trusted_type));
- return GetStringFromTrustedScriptURL(string_or_trusted_script_url,
- execution_context, exception_state);
+ if (result->toString().IsNull()) {
+ if (TrustedTypeFail(violation_kind_when_default_policy_failed,
+ doc->ToExecutionContext(), exception_state, script)) {
+ exception_state.ClearException();
+ return String();
}
+ return script;
}
+ return result->toString();
}
-String GetStringFromSpecificTrustedType(
- const String& string,
- SpecificTrustedType specific_trusted_type,
- const ExecutionContext* execution_context,
- ExceptionState& exception_state) {
- if (specific_trusted_type == SpecificTrustedType::kNone)
- return string;
- return GetStringFromSpecificTrustedType(
- StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL::FromString(string),
- specific_trusted_type, execution_context, exception_state);
-}
-
-String GetStringFromTrustedHTML(StringOrTrustedHTML string_or_trusted_html,
- const ExecutionContext* execution_context,
- ExceptionState& exception_state) {
- DCHECK(!string_or_trusted_html.IsNull());
-
- if (string_or_trusted_html.IsTrustedHTML()) {
- return string_or_trusted_html.GetAsTrustedHTML()->toString();
- }
+} // namespace
- return GetStringFromTrustedHTML(string_or_trusted_html.GetAsString(),
- execution_context, exception_state);
+bool RequireTrustedTypesCheck(const ExecutionContext* execution_context) {
+ return execution_context && execution_context->RequireTrustedTypes() &&
+ !ContentSecurityPolicy::ShouldBypassMainWorld(execution_context);
}
-String GetStringFromTrustedHTML(const String& string,
+String TrustedTypesCheckForHTML(const String& html,
const ExecutionContext* execution_context,
ExceptionState& exception_state) {
bool require_trusted_type = RequireTrustedTypesCheck(execution_context);
if (!require_trusted_type) {
- return string;
+ return html;
}
TrustedTypePolicy* default_policy = GetDefaultPolicy(execution_context);
if (!default_policy) {
if (TrustedTypeFail(kTrustedHTMLAssignment, execution_context,
- exception_state, string)) {
+ exception_state, html)) {
return g_empty_string;
}
- return string;
+ return html;
}
+ if (!default_policy->HasCreateHTML()) {
+ if (TrustedTypeFail(kTrustedHTMLAssignmentAndNoDefaultPolicyExisted,
+ execution_context, exception_state, html)) {
+ return g_empty_string;
+ } else {
+ return html;
+ }
+ }
TrustedHTML* result = default_policy->CreateHTML(
- execution_context->GetIsolate(), string, exception_state);
+ execution_context->GetIsolate(), html,
+ GetDefaultCallbackArgs(execution_context->GetIsolate(), "TrustedHTML",
+ exception_state),
+ exception_state);
if (exception_state.HadException()) {
return g_empty_string;
}
if (result->toString().IsNull()) {
if (TrustedTypeFail(kTrustedHTMLAssignmentAndDefaultPolicyFailed,
- execution_context, exception_state, string)) {
+ execution_context, exception_state, html)) {
return g_empty_string;
} else {
- return string;
+ return html;
}
}
return result->toString();
}
-String GetStringFromTrustedScript(
- StringOrTrustedScript string_or_trusted_script,
- const ExecutionContext* execution_context,
- ExceptionState& exception_state) {
- // To remain compatible with legacy behaviour, HTMLElement uses extended IDL
- // attributes to allow for nullable union of (DOMString or TrustedScript).
- // Thus, this method is required to handle the case where
- // string_or_trusted_script.IsNull(), unlike the various similar methods in
- // this file.
-
- if (string_or_trusted_script.IsTrustedScript()) {
- return string_or_trusted_script.GetAsTrustedScript()->toString();
- }
-
- if (string_or_trusted_script.IsNull()) {
- string_or_trusted_script =
- StringOrTrustedScript::FromString(g_empty_string);
- }
- return GetStringFromTrustedScript(string_or_trusted_script.GetAsString(),
- execution_context, exception_state);
+String TrustedTypesCheckForHTML(const String& html,
+ const Document* document,
+ ExceptionState& exception_state) {
+ return TrustedTypesCheckForHTML(
+ html, document ? document->GetExecutionContext() : nullptr,
+ exception_state);
}
-String GetStringFromTrustedScript(const String& potential_script,
+String TrustedTypesCheckForScript(const String& script,
const ExecutionContext* execution_context,
ExceptionState& exception_state) {
bool require_trusted_type = RequireTrustedTypesCheck(execution_context);
if (!require_trusted_type) {
- return potential_script;
+ return script;
}
TrustedTypePolicy* default_policy = GetDefaultPolicy(execution_context);
if (!default_policy) {
if (TrustedTypeFail(kTrustedScriptAssignment, execution_context,
- exception_state, potential_script)) {
+ exception_state, script)) {
return g_empty_string;
}
- return potential_script;
+ return script;
}
+ if (!default_policy->HasCreateScript()) {
+ if (TrustedTypeFail(kTrustedScriptAssignmentAndNoDefaultPolicyExisted,
+ execution_context, exception_state, script)) {
+ return g_empty_string;
+ } else {
+ return script;
+ }
+ }
TrustedScript* result = default_policy->CreateScript(
- execution_context->GetIsolate(), potential_script, exception_state);
+ execution_context->GetIsolate(), script,
+ GetDefaultCallbackArgs(execution_context->GetIsolate(), "TrustedScript",
+ exception_state),
+ exception_state);
DCHECK_EQ(!result, exception_state.HadException());
if (exception_state.HadException()) {
return g_empty_string;
@@ -353,46 +346,48 @@ String GetStringFromTrustedScript(const String& potential_script,
if (result->toString().IsNull()) {
if (TrustedTypeFail(kTrustedScriptAssignmentAndDefaultPolicyFailed,
- execution_context, exception_state, potential_script)) {
+ execution_context, exception_state, script)) {
return g_empty_string;
} else {
- return potential_script;
+ return script;
}
}
return result->toString();
}
-String GetStringFromTrustedScriptURL(
- StringOrTrustedScriptURL string_or_trusted_script_url,
- const ExecutionContext* execution_context,
- ExceptionState& exception_state) {
- DCHECK(!string_or_trusted_script_url.IsNull());
- if (string_or_trusted_script_url.IsTrustedScriptURL()) {
- return string_or_trusted_script_url.GetAsTrustedScriptURL()->toString();
- }
-
- DCHECK(string_or_trusted_script_url.IsString());
- String string = string_or_trusted_script_url.GetAsString();
-
+String TrustedTypesCheckForScriptURL(const String& script_url,
+ const ExecutionContext* execution_context,
+ ExceptionState& exception_state) {
bool require_trusted_type =
RequireTrustedTypesCheck(execution_context) &&
RuntimeEnabledFeatures::TrustedDOMTypesEnabled(execution_context);
if (!require_trusted_type) {
- return string;
+ return script_url;
}
TrustedTypePolicy* default_policy = GetDefaultPolicy(execution_context);
if (!default_policy) {
if (TrustedTypeFail(kTrustedScriptURLAssignment, execution_context,
- exception_state, string)) {
+ exception_state, script_url)) {
return g_empty_string;
}
- return string;
+ return script_url;
}
+ if (!default_policy->HasCreateScriptURL()) {
+ if (TrustedTypeFail(kTrustedScriptURLAssignmentAndNoDefaultPolicyExisted,
+ execution_context, exception_state, script_url)) {
+ return g_empty_string;
+ } else {
+ return script_url;
+ }
+ }
TrustedScriptURL* result = default_policy->CreateScriptURL(
- execution_context->GetIsolate(), string, exception_state);
+ execution_context->GetIsolate(), script_url,
+ GetDefaultCallbackArgs(execution_context->GetIsolate(),
+ "TrustedScriptURL", exception_state),
+ exception_state);
if (exception_state.HadException()) {
return g_empty_string;
@@ -400,105 +395,100 @@ String GetStringFromTrustedScriptURL(
if (result->toString().IsNull()) {
if (TrustedTypeFail(kTrustedScriptURLAssignmentAndDefaultPolicyFailed,
- execution_context, exception_state, string)) {
+ execution_context, exception_state, script_url)) {
return g_empty_string;
} else {
- return string;
+ return script_url;
}
}
return result->toString();
}
-Node* TrustedTypesCheckForHTMLScriptElement(Node* child,
- Document* doc,
- ExceptionState& exception_state) {
- bool require_trusted_type = RequireTrustedTypesCheck(doc);
- if (!require_trusted_type)
- return child;
-
- TrustedTypePolicy* default_policy = GetDefaultPolicy(doc);
- if (!default_policy) {
- return TrustedTypeFail(kTextNodeScriptAssignment, doc, exception_state,
- child->textContent())
- ? nullptr
- : child;
+String TrustedTypesCheckFor(
+ SpecificTrustedType type,
+ const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL& trusted,
+ const ExecutionContext* execution_context,
+ ExceptionState& exception_state) {
+ // Whatever happens below, we will need the string value:
+ String value;
+ if (trusted.IsTrustedHTML()) {
+ value = trusted.GetAsTrustedHTML()->toString();
+ } else if (trusted.IsTrustedScript()) {
+ value = trusted.GetAsTrustedScript()->toString();
+ } else if (trusted.IsTrustedScriptURL()) {
+ value = trusted.GetAsTrustedScriptURL()->toString();
+ } else if (trusted.IsString()) {
+ value = trusted.GetAsString();
+ } // else: trusted.IsNull(). But we don't have anything to do in that case.
+
+ // The check passes if we have the proper trusted type:
+ if (type == SpecificTrustedType::kNone ||
+ (trusted.IsTrustedHTML() && type == SpecificTrustedType::kHTML) ||
+ (trusted.IsTrustedScript() && type == SpecificTrustedType::kScript) ||
+ (trusted.IsTrustedScriptURL() &&
+ type == SpecificTrustedType::kScriptURL)) {
+ return value;
}
- TrustedScript* result = default_policy->CreateScript(
- doc->GetIsolate(), child->textContent(), exception_state);
- if (exception_state.HadException()) {
- return nullptr;
+ // In all other cases: run the full check against the string value.
+ return TrustedTypesCheckFor(type, value, execution_context, exception_state);
+}
+
+String TrustedTypesCheckForScript(StringOrTrustedScript trusted,
+ const ExecutionContext* execution_context,
+ ExceptionState& exception_state) {
+ // To remain compatible with legacy behaviour, HTMLElement uses extended IDL
+ // attributes to allow for nullable union of (DOMString or TrustedScript).
+ // Thus, this method is required to handle the case where
+ // string_or_trusted_script.IsNull(), unlike the various similar methods in
+ // this file.
+ if (trusted.IsTrustedScript()) {
+ return trusted.GetAsTrustedScript()->toString();
}
+ if (trusted.IsNull()) {
+ trusted = StringOrTrustedScript::FromString(g_empty_string);
+ }
+ return TrustedTypesCheckForScript(trusted.GetAsString(), execution_context,
+ exception_state);
+}
- if (result->toString().IsNull()) {
- return TrustedTypeFail(kTextNodeScriptAssignmentAndDefaultPolicyFailed, doc,
- exception_state, child->textContent())
- ? nullptr
- : child;
+String TrustedTypesCheckFor(SpecificTrustedType type,
+ const String& trusted,
+ const ExecutionContext* execution_context,
+ ExceptionState& exception_state) {
+ switch (type) {
+ case SpecificTrustedType::kHTML:
+ return TrustedTypesCheckForHTML(trusted, execution_context,
+ exception_state);
+ case SpecificTrustedType::kScript:
+ return TrustedTypesCheckForScript(trusted, execution_context,
+ exception_state);
+ case SpecificTrustedType::kScriptURL:
+ return TrustedTypesCheckForScriptURL(trusted, execution_context,
+ exception_state);
+ case SpecificTrustedType::kNone:
+ return trusted;
}
+ NOTREACHED();
+ return "";
+}
- return Text::Create(*doc, result->toString());
+String CORE_EXPORT
+GetStringForScriptExecution(const String& script,
+ const ScriptElementBase::Type type,
+ Document* doc) {
+ return GetStringFromScriptHelper(script, doc, GetElementName(type), "text",
+ kScriptExecution,
+ kScriptExecutionAndDefaultPolicyFailed);
}
String TrustedTypesCheckForJavascriptURLinNavigation(
const String& javascript_url,
Document* doc) {
- bool require_trusted_type = RequireTrustedTypesCheck(doc);
- if (!require_trusted_type)
- return javascript_url;
-
- // Set up JS context & friends.
- //
- // All other functions in here are expected to be called during JS execution,
- // where naturally everything is propertly set up for more JS execution.
- // This one is called during navigation, and thus needs to do a bit more
- // work. We need two JavaScript-ish things:
- // - TrustedTypeFail expects an ExceptionState, which it will use to throw
- // an exception. In our case, we will always clear the exception (as there
- // is no user script to pass it to), and we only use this as a signalling
- // mechanism.
- // - If the default policy applies, we need to execute the JS callback.
- // Unlike the various ScriptController::Execute* and ..::Eval* methods,
- // we are not executing a source String, but an already compiled callback
- // function.
- v8::HandleScope handle_scope(doc->GetIsolate());
- ScriptState::Scope script_state_scope(
- ScriptState::From(static_cast<LocalWindowProxyManager*>(
- doc->GetFrame()->GetWindowProxyManager())
- ->MainWorldProxy()
- ->ContextIfInitialized()));
- ExceptionState exception_state(
- doc->GetIsolate(), ExceptionState::kUnknownContext, "Location", "href");
-
- TrustedTypePolicy* default_policy = GetDefaultPolicy(doc);
- if (!default_policy) {
- if (TrustedTypeFail(kNavigateToJavascriptURL, doc, exception_state,
- javascript_url)) {
- exception_state.ClearException();
- return String();
- }
- return javascript_url;
- }
-
- TrustedScript* result = default_policy->CreateScript(
- doc->GetIsolate(), javascript_url, exception_state);
- if (exception_state.HadException()) {
- exception_state.ClearException();
- return String();
- }
-
- if (result->toString().IsNull()) {
- if (TrustedTypeFail(kNavigateToJavascriptURLAndDefaultPolicyFailed, doc,
- exception_state, javascript_url)) {
- exception_state.ClearException();
- return String();
- }
- return javascript_url;
- }
- // TODO(vogelheim): Figure out whether we need to check whether this string
- // parses as a URL, and whether we need to do this here.
- return result->toString();
+ return GetStringFromScriptHelper(
+ javascript_url, doc, "Location", "href", kNavigateToJavascriptURL,
+ kNavigateToJavascriptURLAndDefaultPolicyFailed);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_types_util.h b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_types_util.h
index c4eb1122397..2169c32ba87 100644
--- a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_types_util.h
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_types_util.h
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_TRUSTEDTYPES_TRUSTED_TYPES_UTIL_H_
#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/script/script_element_base.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -13,69 +14,61 @@ namespace blink {
class Document;
class ExecutionContext;
class ExceptionState;
-class Node;
-class StringOrTrustedHTML;
class StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL;
class StringOrTrustedScript;
-class StringOrTrustedScriptURL;
enum class SpecificTrustedType {
kNone,
- kTrustedHTML,
- kTrustedScript,
- kTrustedScriptURL,
+ kHTML,
+ kScript,
+ kScriptURL,
};
-String CORE_EXPORT GetStringFromTrustedType(
- const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&,
- const ExecutionContext*,
- ExceptionState&);
-
-String CORE_EXPORT GetStringFromTrustedTypeWithoutCheck(
- const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&);
+// TODO(crbug.com/1029822): Temporary helpers to ease migrating ExecutionContext
+// to LocalDOMWindow.
+CORE_EXPORT String TrustedTypesCheckForHTML(const String&,
+ const Document*,
+ ExceptionState&);
-String CORE_EXPORT GetStringFromSpecificTrustedType(
- const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&,
+// Perform Trusted Type checks, with the IDL union types as input. All of these
+// will call String& versions below to do the heavy lifting.
+CORE_EXPORT String TrustedTypesCheckFor(
SpecificTrustedType,
+ const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&,
const ExecutionContext*,
- ExceptionState&);
-
-String CORE_EXPORT GetStringFromSpecificTrustedType(const String&,
- SpecificTrustedType,
- const ExecutionContext*,
- ExceptionState&);
-
-String CORE_EXPORT GetStringFromTrustedHTML(StringOrTrustedHTML,
+ ExceptionState&) WARN_UNUSED_RESULT;
+CORE_EXPORT String TrustedTypesCheckForScript(StringOrTrustedScript,
+ const ExecutionContext*,
+ ExceptionState&)
+ WARN_UNUSED_RESULT;
+
+// Perform Trusted Type checks, for a dynamically or statically determined
+// type.
+// Returns the effective value (which may have been modified by the "default"
+// policy. We use WARN_UNUSED_RESULT to prevent erroneous usage.
+String TrustedTypesCheckFor(SpecificTrustedType,
+ const String&,
+ const ExecutionContext*,
+ ExceptionState&) WARN_UNUSED_RESULT;
+CORE_EXPORT String TrustedTypesCheckForHTML(const String&,
const ExecutionContext*,
- ExceptionState&);
-
-String GetStringFromTrustedHTML(const String&,
- const ExecutionContext*,
- ExceptionState&);
-
-String CORE_EXPORT GetStringFromTrustedScript(StringOrTrustedScript,
+ ExceptionState&) WARN_UNUSED_RESULT;
+CORE_EXPORT String TrustedTypesCheckForScript(const String&,
const ExecutionContext*,
- ExceptionState&);
-
-String GetStringFromTrustedScript(const String&,
- const ExecutionContext*,
- ExceptionState&);
-
-String CORE_EXPORT GetStringFromTrustedScriptURL(StringOrTrustedScriptURL,
+ ExceptionState&)
+ WARN_UNUSED_RESULT;
+CORE_EXPORT String TrustedTypesCheckForScriptURL(const String&,
const ExecutionContext*,
- ExceptionState&);
-
-// For <script> elements, we need to treat insertion of DOM text nodes
-// as equivalent to string assignment. This checks the child-node to be
-// inserted and runs all of the Trusted Types checks if it's a text node.
-//
-// Returns nullptr if the check failed, or the node to use (possibly child)
-// if they succeeded.
-Node* TrustedTypesCheckForHTMLScriptElement(Node* child,
- Document*,
- ExceptionState&);
+ ExceptionState&)
+ WARN_UNUSED_RESULT;
+// Functionally equivalent to TrustedTypesCheckForScript(const String&, ...),
+// but with setup & error handling suitable for the asynchronous execution
+// cases.
String TrustedTypesCheckForJavascriptURLinNavigation(const String&, Document*);
+CORE_EXPORT String GetStringForScriptExecution(const String&,
+ ScriptElementBase::Type,
+ Document*);
// Determine whether a Trusted Types check is needed in this execution context.
//
@@ -84,7 +77,7 @@ String TrustedTypesCheckForJavascriptURLinNavigation(const String&, Document*);
// immediately imply "okay" this method can be used.
// Example: To determine whether 'eval' may pass, one needs to also take CSP
// into account.
-bool CORE_EXPORT RequireTrustedTypesCheck(const ExecutionContext*);
+CORE_EXPORT bool RequireTrustedTypesCheck(const ExecutionContext*);
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_types_util_test.cc b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_types_util_test.cc
index 29619bd41da..a484b9688c1 100644
--- a/chromium/third_party/blink/renderer/core/trustedtypes/trusted_types_util_test.cc
+++ b/chromium/third_party/blink/renderer/core/trustedtypes/trusted_types_util_test.cc
@@ -6,10 +6,8 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_html.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_html_or_trusted_script_or_trusted_script_url.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script.h"
-#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script_url.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/frame/csp/content_security_policy.h"
@@ -19,264 +17,123 @@
#include "third_party/blink/renderer/core/trustedtypes/trusted_script_url.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/testing/unit_test_helpers.h"
namespace blink {
-// Functions for checking throwing cases.
-void GetStringFromTrustedTypeThrows(
- const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&
- string_or_trusted_type) {
- auto* document = MakeGarbageCollected<Document>();
- document->GetContentSecurityPolicy()->DidReceiveHeader(
- "trusted-types *", kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceMeta);
- DummyExceptionStateForTesting exception_state;
- ASSERT_FALSE(exception_state.HadException());
- String s = GetStringFromTrustedType(string_or_trusted_type, document,
- exception_state);
- EXPECT_TRUE(exception_state.HadException());
- EXPECT_EQ(ESErrorType::kTypeError, exception_state.CodeAs<ESErrorType>());
- exception_state.ClearException();
-}
-
-void GetStringFromTrustedHTMLThrows(
- const StringOrTrustedHTML& string_or_trusted_html) {
+void TrustedTypesCheckForHTMLThrows(const String& string) {
auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
+ KURL url("https://example.site");
+ dummy_page_holder->GetFrame().Loader().CommitNavigation(
+ WebNavigationParams::CreateWithHTMLBuffer(SharedBuffer::Create(), url),
+ nullptr /* extra_data */);
+ blink::test::RunPendingTasks();
+
Document& document = dummy_page_holder->GetDocument();
- document.GetContentSecurityPolicy()->DidReceiveHeader(
- "trusted-types *", kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceMeta);
V8TestingScope scope;
DummyExceptionStateForTesting exception_state;
ASSERT_FALSE(exception_state.HadException());
- String s = GetStringFromTrustedHTML(string_or_trusted_html, &document,
- exception_state);
+ String s = TrustedTypesCheckForHTML(string, &document, exception_state);
+ EXPECT_FALSE(exception_state.HadException());
+
+ document.GetContentSecurityPolicy()->DidReceiveHeader(
+ "require-trusted-types-for 'script'",
+ network::mojom::ContentSecurityPolicyType::kEnforce,
+ network::mojom::ContentSecurityPolicySource::kMeta);
+ ASSERT_FALSE(exception_state.HadException());
+ String s1 = TrustedTypesCheckForHTML(string, &document, exception_state);
EXPECT_TRUE(exception_state.HadException());
EXPECT_EQ(ESErrorType::kTypeError, exception_state.CodeAs<ESErrorType>());
exception_state.ClearException();
}
-void GetStringFromTrustedScriptThrows(
- const StringOrTrustedScript& string_or_trusted_script) {
+void TrustedTypesCheckForScriptThrows(const String& string) {
auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
+ KURL url("https://example.site");
+ dummy_page_holder->GetFrame().Loader().CommitNavigation(
+ WebNavigationParams::CreateWithHTMLBuffer(SharedBuffer::Create(), url),
+ nullptr /* extra_data */);
+ blink::test::RunPendingTasks();
+
Document& document = dummy_page_holder->GetDocument();
- document.GetContentSecurityPolicy()->DidReceiveHeader(
- "trusted-types *", kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceMeta);
V8TestingScope scope;
DummyExceptionStateForTesting exception_state;
ASSERT_FALSE(exception_state.HadException());
- String s = GetStringFromTrustedScript(string_or_trusted_script, &document,
+ String s = TrustedTypesCheckForScript(string, document.ToExecutionContext(),
exception_state);
- EXPECT_TRUE(exception_state.HadException());
- EXPECT_EQ(ESErrorType::kTypeError, exception_state.CodeAs<ESErrorType>());
- exception_state.ClearException();
-}
+ EXPECT_FALSE(exception_state.HadException());
-void GetStringFromTrustedScriptURLThrows(
- const StringOrTrustedScriptURL& string_or_trusted_script_url) {
- auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
- Document& document = dummy_page_holder->GetDocument();
document.GetContentSecurityPolicy()->DidReceiveHeader(
- "trusted-types *", kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceMeta);
- V8TestingScope scope;
- DummyExceptionStateForTesting exception_state;
+ "require-trusted-types-for 'script'",
+ network::mojom::ContentSecurityPolicyType::kEnforce,
+ network::mojom::ContentSecurityPolicySource::kMeta);
ASSERT_FALSE(exception_state.HadException());
- String s = GetStringFromTrustedScriptURL(string_or_trusted_script_url,
- &document, exception_state);
+ String s1 = TrustedTypesCheckForScript(string, document.ToExecutionContext(),
+ exception_state);
EXPECT_TRUE(exception_state.HadException());
EXPECT_EQ(ESErrorType::kTypeError, exception_state.CodeAs<ESErrorType>());
exception_state.ClearException();
}
-// Functions for checking non-throwing cases.
-void GetStringFromTrustedTypeWorks(
- const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&
- string_or_trusted_type,
- String expected) {
- auto* document = MakeGarbageCollected<Document>();
- document->GetContentSecurityPolicy()->DidReceiveHeader(
- "trusted-types *", kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceMeta);
- DummyExceptionStateForTesting exception_state;
- String s = GetStringFromTrustedType(string_or_trusted_type, document,
- exception_state);
- ASSERT_EQ(s, expected);
-}
-
-void GetStringFromTrustedHTMLWorks(
- const StringOrTrustedHTML& string_or_trusted_html,
- String expected) {
+void TrustedTypesCheckForScriptURLThrows(const String& string) {
auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
+ KURL url("https://example.site");
+ dummy_page_holder->GetFrame().Loader().CommitNavigation(
+ WebNavigationParams::CreateWithHTMLBuffer(SharedBuffer::Create(), url),
+ nullptr /* extra_data */);
+ blink::test::RunPendingTasks();
+
Document& document = dummy_page_holder->GetDocument();
- document.GetContentSecurityPolicy()->DidReceiveHeader(
- "trusted-types *", kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceMeta);
V8TestingScope scope;
DummyExceptionStateForTesting exception_state;
- String s = GetStringFromTrustedHTML(string_or_trusted_html, &document,
- exception_state);
- ASSERT_EQ(s, expected);
-}
+ ASSERT_FALSE(exception_state.HadException());
+ String s = TrustedTypesCheckForScriptURL(
+ string, document.ToExecutionContext(), exception_state);
+ EXPECT_FALSE(exception_state.HadException());
-void GetStringFromTrustedScriptWorks(
- const StringOrTrustedScript& string_or_trusted_script,
- String expected) {
- auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
- Document& document = dummy_page_holder->GetDocument();
document.GetContentSecurityPolicy()->DidReceiveHeader(
- "trusted-types *", kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceMeta);
- V8TestingScope scope;
- DummyExceptionStateForTesting exception_state;
- String s = GetStringFromTrustedScript(string_or_trusted_script, &document,
- exception_state);
- ASSERT_EQ(s, expected);
+ "require-trusted-types-for 'script'",
+ network::mojom::ContentSecurityPolicyType::kEnforce,
+ network::mojom::ContentSecurityPolicySource::kMeta);
+ ASSERT_FALSE(exception_state.HadException());
+ String s1 = TrustedTypesCheckForScriptURL(
+ string, document.ToExecutionContext(), exception_state);
+ EXPECT_TRUE(exception_state.HadException());
+ EXPECT_EQ(ESErrorType::kTypeError, exception_state.CodeAs<ESErrorType>());
+ exception_state.ClearException();
}
-void GetStringFromTrustedScriptURLWorks(
- const StringOrTrustedScriptURL& string_or_trusted_script_url,
+void TrustedTypesCheckForScriptWorks(
+ const StringOrTrustedScript& string_or_trusted_script,
String expected) {
auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
Document& document = dummy_page_holder->GetDocument();
- document.GetContentSecurityPolicy()->DidReceiveHeader(
- "trusted-types *", kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceMeta);
V8TestingScope scope;
DummyExceptionStateForTesting exception_state;
- String s = GetStringFromTrustedScriptURL(string_or_trusted_script_url,
- &document, exception_state);
+ String s = TrustedTypesCheckForScript(
+ string_or_trusted_script, document.ToExecutionContext(), exception_state);
ASSERT_EQ(s, expected);
}
-// GetStringFromTrustedType() tests
-TEST(TrustedTypesUtilTest, GetStringFromTrustedType_TrustedHTML) {
- auto* html = MakeGarbageCollected<TrustedHTML>("A string");
- StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL trusted_value =
- StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL::FromTrustedHTML(
- html);
- GetStringFromTrustedTypeWorks(trusted_value, "A string");
-}
-
-TEST(TrustedTypesUtilTest, GetStringFromTrustedType_TrustedScript) {
- auto* script = MakeGarbageCollected<TrustedScript>("A string");
- StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL trusted_value =
- StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL::FromTrustedScript(
- script);
- GetStringFromTrustedTypeWorks(trusted_value, "A string");
-}
-
-TEST(TrustedTypesUtilTest, GetStringFromTrustedType_TrustedScriptURL) {
- String url_address = "http://www.example.com/";
- auto* script_url = MakeGarbageCollected<TrustedScriptURL>(url_address);
- StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL trusted_value =
- StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL::
- FromTrustedScriptURL(script_url);
- GetStringFromTrustedTypeWorks(trusted_value, "http://www.example.com/");
-}
-
-TEST(TrustedTypesUtilTest, GetStringFromTrustedType_TrustedScriptURL_Relative) {
- String url_address = "relative/url.html";
- auto* script_url = MakeGarbageCollected<TrustedScriptURL>(url_address);
- StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL trusted_value =
- StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL::
- FromTrustedScriptURL(script_url);
- GetStringFromTrustedTypeWorks(trusted_value, "relative/url.html");
-}
-
-TEST(TrustedTypesUtilTest, GetStringFromTrustedType_String) {
- StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL string_value =
- StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL::FromString(
- "A string");
- GetStringFromTrustedTypeThrows(string_value);
-}
-
-// GetStringFromTrustedTypeWithoutCheck() tests
-TEST(TrustedTypesUtilTest, GetStringFromTrustedTypeWithoutCheck_TrustedHTML) {
- auto* html = MakeGarbageCollected<TrustedHTML>("A string");
- StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL trusted_value =
- StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL::FromTrustedHTML(
- html);
- String s = GetStringFromTrustedTypeWithoutCheck(trusted_value);
- ASSERT_EQ(s, "A string");
-}
-
-TEST(TrustedTypesUtilTest, GetStringFromTrustedTypeWithoutCheck_TrustedScript) {
- auto* script = MakeGarbageCollected<TrustedScript>("A string");
- StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL trusted_value =
- StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL::FromTrustedScript(
- script);
- String s = GetStringFromTrustedTypeWithoutCheck(trusted_value);
- ASSERT_EQ(s, "A string");
-}
-
-TEST(TrustedTypesUtilTest,
- GetStringFromTrustedTypeWithoutCheck_TrustedScriptURL) {
- String url_address = "http://www.example.com/";
- auto* script_url = MakeGarbageCollected<TrustedScriptURL>(url_address);
- StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL trusted_value =
- StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL::
- FromTrustedScriptURL(script_url);
- String s = GetStringFromTrustedTypeWithoutCheck(trusted_value);
- ASSERT_EQ(s, "http://www.example.com/");
-}
-
-TEST(TrustedTypesUtilTest, GetStringFromTrustedTypeWithoutCheck_String) {
- StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL string_value =
- StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL::FromString(
- "A string");
- String s = GetStringFromTrustedTypeWithoutCheck(string_value);
- ASSERT_EQ(s, "A string");
-}
-
-TEST(TrustedTypesUtilTest, GetStringFromTrustedTypeWithoutCheck_Null) {
- StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL null_value =
- StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL();
- String s = GetStringFromTrustedTypeWithoutCheck(null_value);
- ASSERT_EQ(s, "");
-}
-
-// GetStringFromTrustedHTML tests
-TEST(TrustedTypesUtilTest, GetStringFromTrustedHTML_TrustedHTML) {
- auto* html = MakeGarbageCollected<TrustedHTML>("A string");
- StringOrTrustedHTML trusted_value =
- StringOrTrustedHTML::FromTrustedHTML(html);
- GetStringFromTrustedHTMLWorks(trusted_value, "A string");
+// TrustedTypesCheckForHTML tests
+TEST(TrustedTypesUtilTest, TrustedTypesCheckForHTML_String) {
+ TrustedTypesCheckForHTMLThrows("A string");
}
-TEST(TrustedTypesUtilTest, GetStringFromTrustedHTML_String) {
- StringOrTrustedHTML string_value =
- StringOrTrustedHTML::FromString("A string");
- GetStringFromTrustedHTMLThrows(string_value);
-}
-
-// GetStringFromTrustedScript tests
-TEST(TrustedTypesUtilTest, GetStringFromTrustedScript_TrustedScript) {
+// TrustedTypesCheckForScript tests
+TEST(TrustedTypesUtilTest, TrustedTypesCheckForScript_TrustedScript) {
auto* script = MakeGarbageCollected<TrustedScript>("A string");
StringOrTrustedScript trusted_value =
StringOrTrustedScript::FromTrustedScript(script);
- GetStringFromTrustedScriptWorks(trusted_value, "A string");
-}
-
-TEST(TrustedTypesUtilTest, GetStringFromTrustedScript_String) {
- StringOrTrustedScript string_value =
- StringOrTrustedScript::FromString("A string");
- GetStringFromTrustedScriptThrows(string_value);
+ TrustedTypesCheckForScriptWorks(trusted_value, "A string");
}
-// GetStringFromTrustedScriptURL tests
-TEST(TrustedTypesUtilTest, GetStringFromTrustedScriptURL_TrustedScriptURL) {
- String url_address = "http://www.example.com/";
- auto* script_url = MakeGarbageCollected<TrustedScriptURL>(url_address);
- StringOrTrustedScriptURL trusted_value =
- StringOrTrustedScriptURL::FromTrustedScriptURL(script_url);
- GetStringFromTrustedScriptURLWorks(trusted_value, "http://www.example.com/");
+TEST(TrustedTypesUtilTest, TrustedTypesCheckForScript_String) {
+ TrustedTypesCheckForScriptThrows("A string");
}
-TEST(TrustedTypesUtilTest, GetStringFromTrustedScriptURL_String) {
- StringOrTrustedScriptURL string_value =
- StringOrTrustedScriptURL::FromString("A string");
- GetStringFromTrustedScriptURLThrows(string_value);
+// TrustedTypesCheckForScriptURL tests
+TEST(TrustedTypesUtilTest, TrustedTypesCheckForScriptURL_String) {
+ TrustedTypesCheckForScriptURLThrows("A string");
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/BUILD.gn b/chromium/third_party/blink/renderer/core/typed_arrays/BUILD.gn
index 760dd95702e..4823bc8e45a 100644
--- a/chromium/third_party/blink/renderer/core/typed_arrays/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/typed_arrays/BUILD.gn
@@ -6,15 +6,8 @@ import("//third_party/blink/renderer/core/core.gni")
blink_core_sources("typed_arrays") {
sources = [
- "array_buffer/array_buffer.cc",
- "array_buffer/array_buffer.h",
"array_buffer/array_buffer_contents.cc",
"array_buffer/array_buffer_contents.h",
- "array_buffer/array_buffer_view.cc",
- "array_buffer/array_buffer_view.h",
- "array_buffer/array_piece.cc",
- "array_buffer/array_piece.h",
- "array_buffer/typed_array.h",
"array_buffer_view_helpers.h",
"dom_array_buffer.cc",
"dom_array_buffer.h",
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.cc b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.cc
deleted file mode 100644
index b35dac95a1e..00000000000
--- a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2009 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.
- */
-
-#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h"
-
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h"
-
-namespace blink {
-
-bool ArrayBuffer::Transfer(ArrayBufferContents& result) {
- DCHECK(!IsShared());
- scoped_refptr<ArrayBuffer> keep_alive(this);
-
- if (is_detached_) {
- result.Detach();
- return false;
- }
-
- if (!contents_.Data()) {
- // We transfer an empty ArrayBuffer, we can just allocate an empty content.
- result = ArrayBufferContents(contents_.BackingStore());
- return true;
- }
-
- bool all_views_are_detachable = true;
- for (ArrayBufferView* i = first_view_; i; i = i->next_view_) {
- if (!i->IsDetachable())
- all_views_are_detachable = false;
- }
-
- if (all_views_are_detachable) {
- contents_.Transfer(result);
-
- while (first_view_) {
- ArrayBufferView* current = first_view_;
- RemoveView(current);
- current->Detach();
- }
-
- is_detached_ = true;
- } else {
- // TODO(https://crbug.com/763038): See original bug at
- // https://crbug.com/254728. Copying the buffer instead of transferring is
- // not spec compliant but was added for a WebAudio bug fix. The only time
- // this branch is taken is when attempting to transfer an AudioBuffer's
- // channel data ArrayBuffer.
- contents_.CopyTo(result);
- if (!result.Data())
- return false;
- }
-
- return true;
-}
-
-bool ArrayBuffer::ShareContentsWith(ArrayBufferContents& result) {
- DCHECK(IsShared());
- scoped_refptr<ArrayBuffer> keep_alive(this);
-
- if (!contents_.BackingStore()) {
- result.Detach();
- return false;
- }
-
- contents_.ShareWith(result);
- return true;
-}
-
-bool ArrayBuffer::ShareNonSharedForInternalUse(ArrayBufferContents& result) {
- DCHECK(!IsShared());
- scoped_refptr<ArrayBuffer> keep_alive(this);
-
- if (!contents_.BackingStore()) {
- result.Detach();
- return false;
- }
-
- contents_.ShareNonSharedForInternalUse(result);
- return true;
-}
-
-void ArrayBuffer::AddView(ArrayBufferView* view) {
- view->buffer_ = this;
- view->prev_view_ = nullptr;
- view->next_view_ = first_view_;
- if (first_view_)
- first_view_->prev_view_ = view;
- first_view_ = view;
-}
-
-void ArrayBuffer::RemoveView(ArrayBufferView* view) {
- DCHECK_EQ(this, view->buffer_.get());
- if (view->next_view_)
- view->next_view_->prev_view_ = view->prev_view_;
- if (view->prev_view_)
- view->prev_view_->next_view_ = view->next_view_;
- if (first_view_ == view)
- first_view_ = view->next_view_;
- view->prev_view_ = view->next_view_ = nullptr;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h
deleted file mode 100644
index ca488c6ca95..00000000000
--- a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Copyright (C) 2009 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_CORE_TYPED_ARRAYS_ARRAY_BUFFER_ARRAY_BUFFER_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_ARRAY_BUFFER_H_
-
-#include "base/allocator/partition_allocator/oom.h"
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/assertions.h"
-#include "third_party/blink/renderer/platform/wtf/hash_set.h"
-#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
-
-namespace blink {
-
-class ArrayBuffer;
-class ArrayBufferView;
-
-class CORE_EXPORT ArrayBuffer : public RefCounted<ArrayBuffer> {
- USING_FAST_MALLOC(ArrayBuffer);
-
- public:
- static inline scoped_refptr<ArrayBuffer> Create(size_t num_elements,
- size_t element_byte_size);
- static inline scoped_refptr<ArrayBuffer> Create(ArrayBuffer*);
- static inline scoped_refptr<ArrayBuffer> Create(const void* source,
- size_t byte_length);
- static inline scoped_refptr<ArrayBuffer> Create(ArrayBufferContents&);
-
- static inline scoped_refptr<ArrayBuffer> CreateOrNull(
- size_t num_elements,
- size_t element_byte_size);
-
- // Only for use by DOMArrayBuffer::CreateUninitializedOrNull().
- static inline scoped_refptr<ArrayBuffer> CreateUninitializedOrNull(
- size_t num_elements,
- size_t element_byte_size);
-
- static inline scoped_refptr<ArrayBuffer> CreateShared(
- size_t num_elements,
- size_t element_byte_size);
- static inline scoped_refptr<ArrayBuffer> CreateShared(const void* source,
- size_t byte_length);
-
- inline void* Data();
- inline const void* Data() const;
- inline void* DataShared();
- inline const void* DataShared() const;
- inline void* DataMaybeShared();
- inline const void* DataMaybeShared() const;
- inline size_t ByteLengthAsSizeT() const;
- // This function is deprecated and should not be used. Use {ByteLengthAsSizeT}
- // instead.
- inline unsigned ByteLengthAsUnsigned() const;
-
- void AddView(ArrayBufferView*);
- void RemoveView(ArrayBufferView*);
-
- bool Transfer(ArrayBufferContents&);
- bool ShareContentsWith(ArrayBufferContents&);
- // Documentation see DOMArrayBuffer.
- bool ShareNonSharedForInternalUse(ArrayBufferContents&);
- bool IsDetached() const { return is_detached_; }
- bool IsShared() const { return contents_.IsShared(); }
- ArrayBufferContents* Content() { return &contents_; }
- ~ArrayBuffer() = default;
-
- protected:
- inline explicit ArrayBuffer(ArrayBufferContents&);
-
- private:
- static inline scoped_refptr<ArrayBuffer> Create(
- size_t num_elements,
- size_t element_byte_size,
- ArrayBufferContents::InitializationPolicy);
- static inline scoped_refptr<ArrayBuffer> CreateOrNull(
- size_t num_elements,
- size_t element_byte_size,
- ArrayBufferContents::InitializationPolicy);
- static inline scoped_refptr<ArrayBuffer> CreateShared(
- size_t num_elements,
- size_t element_byte_size,
- ArrayBufferContents::InitializationPolicy);
-
- ArrayBufferContents contents_;
- ArrayBufferView* first_view_;
- bool is_detached_;
-};
-
-scoped_refptr<ArrayBuffer> ArrayBuffer::Create(size_t num_elements,
- size_t element_byte_size) {
- return Create(num_elements, element_byte_size,
- ArrayBufferContents::kZeroInitialize);
-}
-
-scoped_refptr<ArrayBuffer> ArrayBuffer::Create(ArrayBuffer* other) {
- // TODO(binji): support creating a SharedArrayBuffer by copying another
- // ArrayBuffer?
- DCHECK(!other->IsShared());
- return ArrayBuffer::Create(other->Data(), other->ByteLengthAsSizeT());
-}
-
-scoped_refptr<ArrayBuffer> ArrayBuffer::Create(const void* source,
- size_t byte_length) {
- ArrayBufferContents contents(byte_length, 1, ArrayBufferContents::kNotShared,
- ArrayBufferContents::kDontInitialize);
- if (UNLIKELY(!contents.Data()))
- OOM_CRASH();
- scoped_refptr<ArrayBuffer> buffer = base::AdoptRef(new ArrayBuffer(contents));
- memcpy(buffer->Data(), source, byte_length);
- return buffer;
-}
-
-scoped_refptr<ArrayBuffer> ArrayBuffer::Create(ArrayBufferContents& contents) {
- CHECK(contents.DataLength() == 0 || contents.DataMaybeShared());
- return base::AdoptRef(new ArrayBuffer(contents));
-}
-
-scoped_refptr<ArrayBuffer> ArrayBuffer::CreateOrNull(size_t num_elements,
- size_t element_byte_size) {
- return CreateOrNull(num_elements, element_byte_size,
- ArrayBufferContents::kZeroInitialize);
-}
-
-scoped_refptr<ArrayBuffer> ArrayBuffer::CreateUninitializedOrNull(
- size_t num_elements,
- size_t element_byte_size) {
- return CreateOrNull(num_elements, element_byte_size,
- ArrayBufferContents::kDontInitialize);
-}
-
-scoped_refptr<ArrayBuffer> ArrayBuffer::Create(
- size_t num_elements,
- size_t element_byte_size,
- ArrayBufferContents::InitializationPolicy policy) {
- ArrayBufferContents contents(num_elements, element_byte_size,
- ArrayBufferContents::kNotShared, policy);
- if (UNLIKELY(!contents.Data()))
- OOM_CRASH();
- return base::AdoptRef(new ArrayBuffer(contents));
-}
-
-scoped_refptr<ArrayBuffer> ArrayBuffer::CreateOrNull(
- size_t num_elements,
- size_t element_byte_size,
- ArrayBufferContents::InitializationPolicy policy) {
- ArrayBufferContents contents(num_elements, element_byte_size,
- ArrayBufferContents::kNotShared, policy);
- if (!contents.Data())
- return nullptr;
- return base::AdoptRef(new ArrayBuffer(contents));
-}
-
-scoped_refptr<ArrayBuffer> ArrayBuffer::CreateShared(size_t num_elements,
- size_t element_byte_size) {
- return CreateShared(num_elements, element_byte_size,
- ArrayBufferContents::kZeroInitialize);
-}
-
-scoped_refptr<ArrayBuffer> ArrayBuffer::CreateShared(const void* source,
- size_t byte_length) {
- ArrayBufferContents contents(byte_length, 1, ArrayBufferContents::kShared,
- ArrayBufferContents::kDontInitialize);
- CHECK(contents.DataShared());
- scoped_refptr<ArrayBuffer> buffer = base::AdoptRef(new ArrayBuffer(contents));
- memcpy(buffer->DataShared(), source, byte_length);
- return buffer;
-}
-
-scoped_refptr<ArrayBuffer> ArrayBuffer::CreateShared(
- size_t num_elements,
- size_t element_byte_size,
- ArrayBufferContents::InitializationPolicy policy) {
- ArrayBufferContents contents(num_elements, element_byte_size,
- ArrayBufferContents::kShared, policy);
- CHECK(contents.DataShared());
- return base::AdoptRef(new ArrayBuffer(contents));
-}
-
-ArrayBuffer::ArrayBuffer(ArrayBufferContents& contents)
- : first_view_(nullptr), is_detached_(false) {
- if (contents.IsShared())
- contents.ShareWith(contents_);
- else
- contents.Transfer(contents_);
-}
-
-void* ArrayBuffer::Data() {
- return contents_.Data();
-}
-
-const void* ArrayBuffer::Data() const {
- return contents_.Data();
-}
-
-void* ArrayBuffer::DataShared() {
- return contents_.DataShared();
-}
-
-const void* ArrayBuffer::DataShared() const {
- return contents_.DataShared();
-}
-
-void* ArrayBuffer::DataMaybeShared() {
- return contents_.DataMaybeShared();
-}
-
-const void* ArrayBuffer::DataMaybeShared() const {
- return contents_.DataMaybeShared();
-}
-
-size_t ArrayBuffer::ByteLengthAsSizeT() const {
- return contents_.DataLength();
-}
-
-// This function is deprecated and should not be used. Use {ByteLengthAsSizeT}
-// instead.
-unsigned ArrayBuffer::ByteLengthAsUnsigned() const {
- // TODO(dtapuska): Revisit this cast. ArrayBufferContents
- // uses size_t for storing data. Whereas ArrayBuffer IDL is
- // only uint32_t based.
- return base::checked_cast<unsigned>(contents_.DataLength());
-}
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_ARRAY_BUFFER_H_
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h
index 2e871b20c1e..cce802e4fc9 100644
--- a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h
+++ b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h
@@ -65,11 +65,13 @@ class CORE_EXPORT ArrayBufferContents {
InitializationPolicy);
ArrayBufferContents(void* data, size_t length, DataDeleter deleter);
ArrayBufferContents(ArrayBufferContents&&) = default;
+ ArrayBufferContents(const ArrayBufferContents&) = default;
explicit ArrayBufferContents(std::shared_ptr<v8::BackingStore> backing_store)
: backing_store_(std::move(backing_store)) {}
~ArrayBufferContents();
+ ArrayBufferContents& operator=(const ArrayBufferContents&) = default;
ArrayBufferContents& operator=(ArrayBufferContents&&) = default;
void Detach();
@@ -112,8 +114,6 @@ class CORE_EXPORT ArrayBufferContents {
static void* AllocateMemoryWithFlags(size_t, InitializationPolicy, int);
std::shared_ptr<v8::BackingStore> backing_store_;
-
- DISALLOW_COPY_AND_ASSIGN(ArrayBufferContents);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents_test.cc b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents_test.cc
index c7fd17dd203..3ce5bfe15b8 100644
--- a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents_test.cc
+++ b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents_test.cc
@@ -10,7 +10,15 @@ namespace blink {
class ArrayBufferContentsTest : public testing::Test {};
-TEST_F(ArrayBufferContentsTest, AllocationFail) {
+#if defined(ADDRESS_SANITIZER)
+#define DISABLE_ON_ASAN(test_name) DISABLED_##test_name
+#else
+#define DISABLE_ON_ASAN(test_name) test_name
+#endif // defined(ADDRESS_SANITIZER)
+
+// Disable on ASAN to avoid crashing on failed allocations, see
+// https://crbug.com/1038741.
+TEST_F(ArrayBufferContentsTest, DISABLE_ON_ASAN(AllocationFail)) {
// This should be an amount of memory that cannot be allocated.
size_t length = sizeof(size_t) == 4 ? 0x4fffffff : 0x8000000000;
size_t element_byte_size = 1;
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.cc b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.cc
deleted file mode 100644
index eee63083591..00000000000
--- a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.cc
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2009 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.
- */
-
-#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h"
-
-#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h"
-
-namespace blink {
-
-ArrayBufferView::ArrayBufferView(scoped_refptr<ArrayBuffer> buffer,
- size_t byte_offset)
- : byte_offset_(byte_offset),
- is_detachable_(true),
- buffer_(std::move(buffer)),
- prev_view_(nullptr),
- next_view_(nullptr) {
- base_address_ =
- buffer_ ? (static_cast<char*>(buffer_->DataMaybeShared()) + byte_offset_)
- : nullptr;
- if (buffer_)
- buffer_->AddView(this);
-}
-
-ArrayBufferView::~ArrayBufferView() {
- if (buffer_)
- buffer_->RemoveView(this);
-}
-
-void ArrayBufferView::Detach() {
- buffer_ = nullptr;
- base_address_ = nullptr;
- byte_offset_ = 0;
-}
-
-const char* ArrayBufferView::TypeName() {
- switch (GetType()) {
- case kTypeInt8:
- return "Int8";
- break;
- case kTypeUint8:
- return "UInt8";
- break;
- case kTypeUint8Clamped:
- return "UInt8Clamped";
- break;
- case kTypeInt16:
- return "Int16";
- break;
- case kTypeUint16:
- return "UInt16";
- break;
- case kTypeInt32:
- return "Int32";
- break;
- case kTypeUint32:
- return "Uint32";
- break;
- case kTypeBigInt64:
- return "BigInt64";
- break;
- case kTypeBigUint64:
- return "BigUint64";
- break;
- case kTypeFloat32:
- return "Float32";
- break;
- case kTypeFloat64:
- return "Float64";
- break;
- case kTypeDataView:
- return "DataView";
- break;
- }
- NOTREACHED();
- return "Unknown";
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h
deleted file mode 100644
index bd9f580236a..00000000000
--- a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2009 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_CORE_TYPED_ARRAYS_ARRAY_BUFFER_ARRAY_BUFFER_VIEW_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_ARRAY_BUFFER_VIEW_H_
-
-#include <limits.h>
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
-
-namespace blink {
-
-class CORE_EXPORT ArrayBufferView : public RefCounted<ArrayBufferView> {
- USING_FAST_MALLOC(ArrayBuffer);
-
- public:
- enum ViewType {
- kTypeInt8,
- kTypeUint8,
- kTypeUint8Clamped,
- kTypeInt16,
- kTypeUint16,
- kTypeInt32,
- kTypeUint32,
- kTypeFloat32,
- kTypeFloat64,
- kTypeBigInt64,
- kTypeBigUint64,
- kTypeDataView
- };
- virtual ViewType GetType() const = 0;
- const char* TypeName();
-
- ArrayBuffer* Buffer() const { return buffer_.get(); }
-
- void* BaseAddress() const {
- DCHECK(!IsShared());
- return base_address_;
- }
- void* BaseAddressMaybeShared() const { return base_address_; }
-
- size_t ByteOffset() const { return byte_offset_; }
-
- virtual size_t ByteLengthAsSizeT() const = 0;
- virtual unsigned TypeSize() const = 0;
-
- void SetDetachable(bool flag) { is_detachable_ = flag; }
- bool IsDetachable() const { return is_detachable_; }
- bool IsShared() const { return buffer_ ? buffer_->IsShared() : false; }
-
- virtual ~ArrayBufferView();
-
- protected:
- ArrayBufferView(scoped_refptr<ArrayBuffer>, size_t byte_offset);
-
- virtual void Detach();
-
- // This is the address of the ArrayBuffer's storage, plus the byte offset.
- void* base_address_;
-
- size_t byte_offset_;
- bool is_detachable_;
-
- private:
- friend class ArrayBuffer;
- scoped_refptr<ArrayBuffer> buffer_;
- ArrayBufferView* prev_view_;
- ArrayBufferView* next_view_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_ARRAY_BUFFER_VIEW_H_
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.cc b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.cc
deleted file mode 100644
index abfaeadf6c1..00000000000
--- a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2014 The Chromium 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/typed_arrays/array_buffer/array_piece.h"
-
-#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h"
-#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h"
-#include "third_party/blink/renderer/platform/wtf/assertions.h"
-#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
-
-namespace blink {
-
-ArrayPiece::ArrayPiece() {
- InitNull();
-}
-
-ArrayPiece::ArrayPiece(ArrayBuffer* buffer) {
- InitWithArrayBuffer(buffer);
-}
-
-ArrayPiece::ArrayPiece(ArrayBufferView* buffer) {
- InitWithArrayBufferView(buffer);
-}
-
-bool ArrayPiece::IsNull() const {
- return is_null_;
-}
-
-bool ArrayPiece::IsDetached() const {
- return is_detached_;
-}
-
-void* ArrayPiece::Data() const {
- DCHECK(!IsNull());
- return data_;
-}
-
-unsigned char* ArrayPiece::Bytes() const {
- return static_cast<unsigned char*>(Data());
-}
-
-size_t ArrayPiece::ByteLengthAsSizeT() const {
- DCHECK(!IsNull());
- return byte_length_;
-}
-
-void ArrayPiece::InitWithArrayBuffer(ArrayBuffer* buffer) {
- if (buffer) {
- InitWithData(buffer->Data(), buffer->ByteLengthAsSizeT());
- is_detached_ = buffer->IsDetached();
- } else {
- InitNull();
- }
-}
-
-void ArrayPiece::InitWithArrayBufferView(ArrayBufferView* buffer) {
- if (buffer) {
- InitWithData(buffer->BaseAddress(), buffer->ByteLengthAsSizeT());
- is_detached_ = buffer->Buffer() ? buffer->Buffer()->IsDetached() : true;
- } else {
- InitNull();
- }
-}
-
-void ArrayPiece::InitWithData(void* data, size_t byte_length) {
- byte_length_ = byte_length;
- data_ = data;
- is_null_ = false;
- is_detached_ = false;
-}
-
-void ArrayPiece::InitNull() {
- byte_length_ = 0;
- data_ = nullptr;
- is_null_ = true;
- is_detached_ = false;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.h b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.h
deleted file mode 100644
index 6a542ba716b..00000000000
--- a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2014 The Chromium 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_TYPED_ARRAYS_ARRAY_BUFFER_ARRAY_PIECE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_ARRAY_PIECE_H_
-
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-
-class ArrayBuffer;
-class ArrayBufferView;
-
-// This class is for passing around un-owned bytes as a pointer + length.
-// It supports implicit conversion from several other data types.
-//
-// ArrayPiece has the concept of being "null". This is different from an empty
-// byte range. It is invalid to call methods other than isNull() on such
-// instances.
-//
-// IMPORTANT: The data contained by ArrayPiece is NOT OWNED, so caution must be
-// taken to ensure it is kept alive.
-class CORE_EXPORT ArrayPiece {
- DISALLOW_NEW();
-
- public:
- // Constructs a "null" ArrayPiece object.
- ArrayPiece();
-
- // Constructs an ArrayPiece from the given ArrayBuffer. If the input is a
- // nullptr, then the constructed instance will be isNull().
- ArrayPiece(ArrayBuffer*);
- ArrayPiece(ArrayBufferView*);
-
- bool IsNull() const;
- bool IsDetached() const;
- void* Data() const;
- unsigned char* Bytes() const;
- size_t ByteLengthAsSizeT() const;
-
- protected:
- void InitWithArrayBuffer(ArrayBuffer*);
- void InitWithArrayBufferView(ArrayBufferView*);
- void InitWithData(void* data, size_t byte_length);
-
- private:
- void InitNull();
-
- void* data_;
- size_t byte_length_;
- bool is_null_;
- bool is_detached_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_ARRAY_PIECE_H_
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/typed_array.h b/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/typed_array.h
deleted file mode 100644
index e44982bdd9e..00000000000
--- a/chromium/third_party/blink/renderer/core/typed_arrays/array_buffer/typed_array.h
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
- * Copyright (c) 2010, 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.
- *
- * 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_CORE_TYPED_ARRAYS_ARRAY_BUFFER_TYPED_ARRAY_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_TYPED_ARRAY_H_
-
-#include <limits>
-#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h"
-#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h"
-#include "third_party/blink/renderer/platform/wtf/math_extras.h"
-
-namespace blink {
-
-template <typename T, bool clamped = false>
-class TypedArray : public ArrayBufferView {
- public:
- typedef T ValueType;
-
- static inline scoped_refptr<TypedArray<T, clamped>> Create(size_t length);
- static inline scoped_refptr<TypedArray<T, clamped>> Create(const T* array,
- size_t length);
- static inline scoped_refptr<TypedArray<T, clamped>>
- Create(scoped_refptr<ArrayBuffer>, size_t byte_offset, size_t length);
-
- T* Data() const { return static_cast<T*>(BaseAddress()); }
-
- T* DataMaybeShared() const {
- return static_cast<T*>(BaseAddressMaybeShared());
- }
-
- size_t length() const { return length_; }
-
- size_t ByteLengthAsSizeT() const final { return length_ * sizeof(T); }
-
- unsigned TypeSize() const final { return sizeof(T); }
-
- inline void Set(size_t index, double value);
-
- inline void Set(size_t index, uint64_t value);
-
- ArrayBufferView::ViewType GetType() const override;
-
- TypedArray(scoped_refptr<ArrayBuffer> buffer,
- size_t byte_offset,
- size_t length)
- : ArrayBufferView(std::move(buffer), byte_offset), length_(length) {}
-
- // Invoked by the indexed getter. Does not perform range checks; caller
- // is responsible for doing so and returning undefined as necessary.
- T Item(size_t index) const {
- SECURITY_DCHECK(index < length_);
- return Data()[index];
- }
-
- private:
- void Detach() final {
- ArrayBufferView::Detach();
- length_ = 0;
- }
-
- size_t length_;
-};
-
-template <typename T, bool clamped>
-scoped_refptr<TypedArray<T, clamped>> TypedArray<T, clamped>::Create(
- size_t length) {
- scoped_refptr<ArrayBuffer> buffer = ArrayBuffer::Create(length, sizeof(T));
- return Create(std::move(buffer), 0, length);
-}
-
-template <typename T, bool clamped>
-scoped_refptr<TypedArray<T, clamped>> TypedArray<T, clamped>::Create(
- const T* array,
- size_t length) {
- auto a = Create(length);
- if (a) {
- std::memcpy(a->Data(), array, a->ByteLengthAsSizeT());
- }
- return a;
-}
-
-namespace {
-// Helper to verify that a given sub-range of an ArrayBuffer is within range.
-template <typename T>
-bool VerifySubRange(const ArrayBuffer* buffer,
- size_t byte_offset,
- size_t num_elements) {
- if (!buffer)
- return false;
- if (sizeof(T) > 1 && byte_offset % sizeof(T))
- return false;
- if (byte_offset > buffer->ByteLengthAsSizeT())
- return false;
- size_t remaining_elements =
- (buffer->ByteLengthAsSizeT() - byte_offset) / sizeof(T);
- if (num_elements > remaining_elements)
- return false;
- return true;
-}
-} // namespace
-
-template <typename T, bool clamped>
-scoped_refptr<TypedArray<T, clamped>> TypedArray<T, clamped>::Create(
- scoped_refptr<ArrayBuffer> buffer,
- size_t byte_offset,
- size_t length) {
- CHECK(VerifySubRange<T>(buffer.get(), byte_offset, length));
- return base::AdoptRef(
- new TypedArray<T, clamped>(std::move(buffer), byte_offset, length));
-}
-
-template <typename T, bool clamped>
-inline void TypedArray<T, clamped>::Set(size_t index, double value) {
- if (index >= length_)
- return;
- if (std::isnan(value)) // Clamp NaN to 0
- value = 0;
- // The double cast is necessary to get the correct wrapping
- // for out-of-range values with Int32Array and Uint32Array.
- Data()[index] = static_cast<T>(static_cast<int64_t>(value));
-}
-
-template <>
-inline void TypedArray<uint8_t, true>::Set(size_t index, double value) {
- if (index >= length_) {
- return;
- }
- if (std::isnan(value) || value < 0) {
- value = 0;
- } else if (value > 255) {
- value = 255;
- }
-
- Data()[index] = static_cast<unsigned char>(lrint(value));
-}
-
-template <>
-inline void TypedArray<float, false>::Set(size_t index, double value) {
- if (index >= length_)
- return;
- Data()[index] = static_cast<float>(value);
-}
-
-template <>
-inline void TypedArray<double, false>::Set(size_t index, double value) {
- if (index >= length_)
- return;
- Data()[index] = value;
-}
-
-template <>
-inline void TypedArray<int64_t, false>::Set(size_t index, uint64_t value) {
- if (index >= length_)
- return;
- Data()[index] = static_cast<int64_t>(value);
-}
-
-template <>
-inline void TypedArray<uint64_t, false>::Set(size_t index, uint64_t value) {
- if (index >= length_)
- return;
- Data()[index] = value;
-}
-
-template <>
-inline void TypedArray<int64_t, false>::Set(size_t index, double value) {
- // This version of {Set} is not supposed to be used for a TypedArray of type
- // int64_t.
- NOTREACHED();
-}
-
-template <>
-inline void TypedArray<uint64_t, false>::Set(size_t index, double value) {
- // This version of {Set} is not supposed to be used for a TypedArray of type
- // uint64_t.
- NOTREACHED();
-}
-
-template <typename T, bool clamped>
-inline void TypedArray<T, clamped>::Set(size_t index, uint64_t value) {
- // This version of {Set} is only supposed to be used for a TypedArrays of type
- // int64_t or uint64_t.
- NOTREACHED();
-}
-
-#define FOREACH_VIEW_TYPE(V) \
- V(int8_t, kTypeInt8) \
- V(int16_t, kTypeInt16) \
- V(int32_t, kTypeInt32) \
- V(uint8_t, kTypeUint8) \
- V(uint16_t, kTypeUint16) \
- V(uint32_t, kTypeUint32) \
- V(float, kTypeFloat32) \
- V(double, kTypeFloat64) \
- V(int64_t, kTypeBigInt64) \
- V(uint64_t, kTypeBigUint64)
-
-#define GET_TYPE(c_type, view_type) \
- template <> \
- inline ArrayBufferView::ViewType TypedArray<c_type, false>::GetType() \
- const { \
- return ArrayBufferView::view_type; \
- }
-
-FOREACH_VIEW_TYPE(GET_TYPE)
-
-#undef GET_TYPE
-#undef FOREACH_VIEW_TYPE
-
-template <>
-inline ArrayBufferView::ViewType TypedArray<uint8_t, true>::GetType() const {
- return ArrayBufferView::kTypeUint8Clamped;
-}
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_TYPED_ARRAY_H_
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 e6bcd90342b..5fa03cb3550 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
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_ARRAY_BUFFER_VIEW_HELPERS_H_
#include <type_traits>
+
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/type_traits.h"
@@ -13,105 +14,119 @@
namespace blink {
// A wrapper template type that is used to ensure that a TypedArray is not
-// backed by a SharedArrayBuffer.
-//
-// Typically this is used as an annotation on C++ functions that are called by
-// the bindings layer, e.g.:
+// backed by a SharedArrayBuffer. It is usable like a smart pointer.
//
// void Foo(NotShared<DOMUint32Array> param) {
-// DOMUint32Array* array = param.View();
+// size_t length = param->lengthAsSizeT();
// ...
// }
template <typename T>
class NotShared {
+ DISALLOW_NEW();
static_assert(WTF::IsSubclass<typename std::remove_const<T>::type,
DOMArrayBufferView>::value,
"NotShared<T> must have T as subclass of DOMArrayBufferView");
- STACK_ALLOCATED();
public:
using TypedArrayType = T;
NotShared() = default;
-
- explicit NotShared(T* typedArray) : typed_array_(typedArray) {
- DCHECK(!(typedArray && typedArray->View()->IsShared()));
+ NotShared(const NotShared<T>& other) = default;
+ // Allow implicit upcasts if U inherits from T.
+ template <typename U, std::enable_if_t<std::is_base_of<T, U>::value, int> = 0>
+ NotShared(const NotShared<U>& other) : typed_array_(other.Get()) {}
+
+ explicit NotShared(std::nullptr_t) {}
+ explicit NotShared(T* typed_array) : typed_array_(typed_array) {
+ DCHECK(!typed_array || !typed_array->IsShared());
}
- NotShared(const NotShared& other) = default;
- template <typename U>
- NotShared(const NotShared<U>& other) : typed_array_(other.View()) {}
template <typename U>
- NotShared(const Member<U>& other) {
- DCHECK(!other->View()->IsShared());
- typed_array_ = other.Get();
+ explicit NotShared(const Member<U>& other) : typed_array_(other.Get()) {
+ DCHECK(!other || !other->IsShared());
}
NotShared& operator=(const NotShared& other) = default;
template <typename U>
NotShared& operator=(const NotShared<U>& other) {
- typed_array_ = other.View();
+ typed_array_ = static_cast<T*>(other.Get());
return *this;
}
- T* View() const { return typed_array_.Get(); }
+ // |View()| is a legacy API and deprecated. Use Get() instead.
+ T* View() const { return GetRaw(); }
+ T* Get() const { return GetRaw(); }
+ void Clear() { typed_array_ = nullptr; }
- bool operator!() const { return !typed_array_; }
- explicit operator bool() const { return !!typed_array_; }
+ // Returns true if this object represents IDL null.
+ bool IsNull() const { return !GetRaw(); }
+
+ explicit operator bool() const { return GetRaw(); }
+ T* operator->() const { return GetRaw(); }
+ T& operator*() const { return *GetRaw(); }
+
+ void Trace(Visitor* visitor) { visitor->Trace(typed_array_); }
private:
- // Must use an untraced member here since this object may be constructed on a
- // thread without a ThreadState (e.g. an Audio worklet). It is safe in that
- // case because the pointed-to ArrayBuffer is being kept alive another way
- // (e.g. CrossThreadPersistent).
- //
- // TODO(binji): update to using Member, see crbug.com/710295.
- UntracedMember<T> typed_array_;
+ T* GetRaw() const { return typed_array_; }
+
+ Member<T> typed_array_;
};
-// A wrapper template type that specifies that a TypedArray may be backed by a
-// SharedArrayBuffer.
-//
-// Typically this is used as an annotation on C++ functions that are called by
-// the bindings layer, e.g.:
+// A wrapper template type that specifies that a TypedArray *may* be backed by
+// a SharedArrayBuffer. It is usable like a smart pointer.
//
// void Foo(MaybeShared<DOMUint32Array> param) {
-// DOMUint32Array* array = param.View();
+// DOMArrayBuffer* buffer = param->buffer();
// ...
// }
template <typename T>
class MaybeShared {
+ DISALLOW_NEW();
static_assert(WTF::IsSubclass<typename std::remove_const<T>::type,
DOMArrayBufferView>::value,
"MaybeShared<T> must have T as subclass of DOMArrayBufferView");
- STACK_ALLOCATED();
public:
using TypedArrayType = T;
MaybeShared() = default;
-
- explicit MaybeShared(T* typedArray) : typed_array_(typedArray) {}
MaybeShared(const MaybeShared& other) = default;
+ // Allow implicit upcasts if U inherits from T.
+ template <typename U, std::enable_if_t<std::is_base_of<T, U>::value, int> = 0>
+ MaybeShared(const MaybeShared<U>& other) : typed_array_(other.Get()) {}
+
+ explicit MaybeShared(std::nullptr_t) {}
+ // [AllowShared] array buffer view may be a view of non-shared array buffer,
+ // so we don't check if the buffer is SharedArrayBuffer or not.
+ // https://heycam.github.io/webidl/#AllowShared
+ explicit MaybeShared(T* typed_array) : typed_array_(typed_array) {}
template <typename U>
- MaybeShared(const MaybeShared<U>& other) : typed_array_(other.View()) {}
- template <typename U>
- MaybeShared(const Member<U>& other) {
- typed_array_ = other.Get();
- }
+ explicit MaybeShared(const Member<U>& other) : typed_array_(other.Get()) {}
MaybeShared& operator=(const MaybeShared& other) = default;
template <typename U>
MaybeShared& operator=(const MaybeShared<U>& other) {
- typed_array_ = other.View();
+ typed_array_ = static_cast<T*>(other.Get());
return *this;
}
- T* View() const { return typed_array_.Get(); }
+ // |View()| is a legacy API and deprecated. Use Get() instead.
+ T* View() const { return GetRaw(); }
+ T* Get() const { return GetRaw(); }
+ void Clear() { typed_array_ = nullptr; }
- bool operator!() const { return !typed_array_; }
- explicit operator bool() const { return !!typed_array_; }
+ // Returns true if this object represents IDL null.
+ bool IsNull() const { return !GetRaw(); }
+
+ explicit operator bool() const { return GetRaw(); }
+ T* operator->() const { return GetRaw(); }
+ T& operator*() const { return *GetRaw(); }
+
+ void Trace(Visitor* visitor) { visitor->Trace(typed_array_); }
private:
+ T* GetRaw() const { return typed_array_; }
+
Member<T> typed_array_;
};
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc
index bbd0fe285f5..17fcf0f9034 100644
--- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc
+++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc
@@ -44,11 +44,21 @@ bool DOMArrayBuffer::Transfer(v8::Isolate* isolate,
DOMArrayBuffer* to_transfer = this;
if (!IsDetachable(isolate)) {
to_transfer =
- DOMArrayBuffer::Create(Buffer()->Data(), Buffer()->ByteLengthAsSizeT());
+ DOMArrayBuffer::Create(Content()->Data(), ByteLengthAsSizeT());
}
- if (!to_transfer->Buffer()->Transfer(result))
+ if (IsDetached()) {
+ result.Detach();
return false;
+ }
+
+ if (!Content()->Data()) {
+ // We transfer an empty ArrayBuffer, we can just allocate an empty content.
+ result = ArrayBufferContents(Content()->BackingStore());
+ } else {
+ Content()->Transfer(result);
+ Detach();
+ }
Vector<v8::Local<v8::ArrayBuffer>, 4> buffer_handles;
v8::HandleScope handle_scope(isolate);
@@ -60,17 +70,30 @@ bool DOMArrayBuffer::Transfer(v8::Isolate* isolate,
return true;
}
+DOMArrayBuffer* DOMArrayBuffer::CreateOrNull(size_t num_elements,
+ size_t element_byte_size) {
+ ArrayBufferContents contents(num_elements, element_byte_size,
+ ArrayBufferContents::kNotShared,
+ ArrayBufferContents::kZeroInitialize);
+ if (!contents.Data()) {
+ return nullptr;
+ }
+ return Create(std::move(contents));
+}
+
DOMArrayBuffer* DOMArrayBuffer::CreateUninitializedOrNull(
size_t num_elements,
size_t element_byte_size) {
- scoped_refptr<ArrayBuffer> buffer =
- ArrayBuffer::CreateUninitializedOrNull(num_elements, element_byte_size);
- if (!buffer)
+ ArrayBufferContents contents(num_elements, element_byte_size,
+ ArrayBufferContents::kNotShared,
+ ArrayBufferContents::kDontInitialize);
+ if (!contents.Data()) {
return nullptr;
- return Create(std::move(buffer));
+ }
+ return Create(std::move(contents));
}
-v8::Local<v8::Object> DOMArrayBuffer::Wrap(
+v8::Local<v8::Value> DOMArrayBuffer::Wrap(
v8::Isolate* isolate,
v8::Local<v8::Object> creation_context) {
DCHECK(!DOMDataStore::ContainsWrapper(this, isolate));
@@ -80,10 +103,9 @@ v8::Local<v8::Object> DOMArrayBuffer::Wrap(
v8::Local<v8::ArrayBuffer> wrapper;
{
v8::Context::Scope context_scope(creation_context->CreationContext());
- wrapper =
- v8::ArrayBuffer::New(isolate, Buffer()->Content()->BackingStore());
+ wrapper = v8::ArrayBuffer::New(isolate, Content()->BackingStore());
- wrapper->Externalize(Buffer()->Content()->BackingStore());
+ wrapper->Externalize(Content()->BackingStore());
}
return AssociateWithWrapper(isolate, wrapper_type_info, wrapper);
@@ -96,14 +118,14 @@ DOMArrayBuffer* DOMArrayBuffer::Create(
ArrayBufferContents::kDontInitialize);
uint8_t* data = static_cast<uint8_t*>(contents.Data());
if (UNLIKELY(!data))
- OOM_CRASH();
+ OOM_CRASH(shared_buffer->size());
for (const auto& span : *shared_buffer) {
memcpy(data, span.data(), span.size());
data += span.size();
}
- return Create(ArrayBuffer::Create(contents));
+ return Create(std::move(contents));
}
DOMArrayBuffer* DOMArrayBuffer::Create(
@@ -116,14 +138,14 @@ DOMArrayBuffer* DOMArrayBuffer::Create(
ArrayBufferContents::kDontInitialize);
uint8_t* ptr = static_cast<uint8_t*>(contents.Data());
if (UNLIKELY(!ptr))
- OOM_CRASH();
+ OOM_CRASH(size);
for (const auto& span : data) {
memcpy(ptr, span.data(), span.size());
ptr += span.size();
}
- return Create(ArrayBuffer::Create(contents));
+ return Create(std::move(contents));
}
DOMArrayBuffer* DOMArrayBuffer::Slice(size_t begin, size_t end) const {
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h
index 9ba70628af2..00ba385dafc 100644
--- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h
+++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h
@@ -5,9 +5,10 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_ARRAY_BUFFER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_ARRAY_BUFFER_H_
+#include "base/allocator/partition_allocator/oom.h"
#include "base/containers/span.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h"
+#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -17,29 +18,43 @@ class CORE_EXPORT DOMArrayBuffer final : public DOMArrayBufferBase {
DEFINE_WRAPPERTYPEINFO();
public:
- static DOMArrayBuffer* Create(scoped_refptr<ArrayBuffer> buffer) {
- return MakeGarbageCollected<DOMArrayBuffer>(std::move(buffer));
+ static DOMArrayBuffer* Create(ArrayBufferContents contents) {
+ return MakeGarbageCollected<DOMArrayBuffer>(std::move(contents));
}
static DOMArrayBuffer* Create(size_t num_elements, size_t element_byte_size) {
- return Create(ArrayBuffer::Create(num_elements, element_byte_size));
+ ArrayBufferContents contents(num_elements, element_byte_size,
+ ArrayBufferContents::kNotShared,
+ ArrayBufferContents::kZeroInitialize);
+ if (UNLIKELY(!contents.Data())) {
+ OOM_CRASH(num_elements * element_byte_size);
+ }
+ return Create(std::move(contents));
}
static DOMArrayBuffer* Create(const void* source, size_t byte_length) {
- return Create(ArrayBuffer::Create(source, byte_length));
- }
- static DOMArrayBuffer* Create(ArrayBufferContents& contents) {
- return Create(ArrayBuffer::Create(contents));
+ ArrayBufferContents contents(byte_length, 1,
+ ArrayBufferContents::kNotShared,
+ ArrayBufferContents::kDontInitialize);
+ if (UNLIKELY(!contents.Data())) {
+ OOM_CRASH(byte_length);
+ }
+ memcpy(contents.Data(), source, byte_length);
+ return Create(std::move(contents));
}
+
static DOMArrayBuffer* Create(scoped_refptr<SharedBuffer>);
static DOMArrayBuffer* Create(const Vector<base::span<const char>>&);
+ static DOMArrayBuffer* CreateOrNull(size_t num_elements,
+ size_t element_byte_size);
+
// Only for use by XMLHttpRequest::responseArrayBuffer,
// Internals::serializeObject, and
// FetchDataLoaderAsArrayBuffer::OnStateChange.
static DOMArrayBuffer* CreateUninitializedOrNull(size_t num_elements,
size_t element_byte_size);
- explicit DOMArrayBuffer(scoped_refptr<ArrayBuffer> buffer)
- : DOMArrayBufferBase(std::move(buffer)) {}
+ explicit DOMArrayBuffer(ArrayBufferContents contents)
+ : DOMArrayBufferBase(std::move(contents)) {}
DOMArrayBuffer* Slice(size_t begin, size_t end) const;
@@ -53,11 +68,16 @@ class CORE_EXPORT DOMArrayBuffer final : public DOMArrayBufferBase {
// for e.g. WebAudio which uses a separate thread for processing the
// ArrayBuffer while at the same time exposing a NonShared Float32Array.
bool ShareNonSharedForInternalUse(ArrayBufferContents& result) {
- return Buffer()->ShareNonSharedForInternalUse(result);
+ if (!Content()->BackingStore()) {
+ result.Detach();
+ return false;
+ }
+ Content()->ShareNonSharedForInternalUse(result);
+ return true;
}
- v8::Local<v8::Object> Wrap(v8::Isolate*,
- v8::Local<v8::Object> creation_context) override;
+ v8::Local<v8::Value> Wrap(v8::Isolate*,
+ v8::Local<v8::Object> creation_context) override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h
index 150510b93c2..e99cce60dd7 100644
--- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h
+++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_ARRAY_BUFFER_BASE_H_
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h"
+#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -16,38 +16,41 @@ class CORE_EXPORT DOMArrayBufferBase : public ScriptWrappable {
public:
~DOMArrayBufferBase() override = default;
- const ArrayBuffer* Buffer() const { return buffer_.get(); }
- ArrayBuffer* Buffer() { return buffer_.get(); }
+ const ArrayBufferContents* Content() const { return &contents_; }
+ ArrayBufferContents* Content() { return &contents_; }
- const void* Data() const { return Buffer()->Data(); }
- void* Data() { return Buffer()->Data(); }
+ const void* Data() const { return contents_.Data(); }
+ void* Data() { return contents_.Data(); }
- size_t ByteLengthAsSizeT() const { return Buffer()->ByteLengthAsSizeT(); }
+ const void* DataMaybeShared() const { return contents_.DataMaybeShared(); }
+ void* DataMaybeShared() { return contents_.DataMaybeShared(); }
+
+ size_t ByteLengthAsSizeT() const { return contents_.DataLength(); }
// This function is deprecated and should not be used. Use {ByteLengthAsSizeT}
// instead.
unsigned DeprecatedByteLengthAsUnsigned() const {
- size_t size = ByteLengthAsSizeT();
- CHECK_LE(size, static_cast<size_t>(std::numeric_limits<unsigned>::max()));
- return static_cast<unsigned>(size);
+ return base::checked_cast<unsigned>(contents_.DataLength());
}
- bool IsDetached() const { return Buffer()->IsDetached(); }
- bool IsShared() const { return Buffer()->IsShared(); }
+ bool IsDetached() const { return is_detached_; }
+
+ void Detach() { is_detached_ = true; }
- v8::Local<v8::Object> Wrap(v8::Isolate*,
- v8::Local<v8::Object> creation_context) override {
+ bool IsShared() const { return contents_.IsShared(); }
+
+ v8::Local<v8::Value> Wrap(v8::Isolate*,
+ v8::Local<v8::Object> creation_context) override {
NOTREACHED();
return v8::Local<v8::Object>();
}
protected:
- explicit DOMArrayBufferBase(scoped_refptr<ArrayBuffer> buffer)
- : buffer_(std::move(buffer)) {
- DCHECK(buffer_);
- }
+ explicit DOMArrayBufferBase(ArrayBufferContents contents)
+ : contents_(std::move(contents)) {}
- scoped_refptr<ArrayBuffer> buffer_;
+ ArrayBufferContents contents_;
+ bool is_detached_ = false;
};
} // namespace blink
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 132367b7cfa..3b863d46da5 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
@@ -6,7 +6,6 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_ARRAY_BUFFER_VIEW_H_
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -17,33 +16,32 @@ class CORE_EXPORT DOMArrayBufferView : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- typedef ArrayBufferView::ViewType ViewType;
- static const ViewType kTypeInt8 = ArrayBufferView::kTypeInt8;
- static const ViewType kTypeUint8 = ArrayBufferView::kTypeUint8;
- static const ViewType kTypeUint8Clamped = ArrayBufferView::kTypeUint8Clamped;
- static const ViewType kTypeInt16 = ArrayBufferView::kTypeInt16;
- static const ViewType kTypeUint16 = ArrayBufferView::kTypeUint16;
- static const ViewType kTypeInt32 = ArrayBufferView::kTypeInt32;
- static const ViewType kTypeUint32 = ArrayBufferView::kTypeUint32;
- static const ViewType kTypeFloat32 = ArrayBufferView::kTypeFloat32;
- static const ViewType kTypeFloat64 = ArrayBufferView::kTypeFloat64;
- static const ViewType kTypeDataView = ArrayBufferView::kTypeDataView;
+ enum ViewType {
+ kTypeInt8,
+ kTypeUint8,
+ kTypeUint8Clamped,
+ kTypeInt16,
+ kTypeUint16,
+ kTypeInt32,
+ kTypeUint32,
+ kTypeFloat32,
+ kTypeFloat64,
+ kTypeBigInt64,
+ kTypeBigUint64,
+ kTypeDataView
+ };
~DOMArrayBufferView() override = default;
DOMArrayBuffer* buffer() const {
DCHECK(!IsShared());
- if (!dom_array_buffer_)
- dom_array_buffer_ = DOMArrayBuffer::Create(View()->Buffer());
-
+ DCHECK(dom_array_buffer_);
return static_cast<DOMArrayBuffer*>(dom_array_buffer_.Get());
}
DOMSharedArrayBuffer* BufferShared() const {
DCHECK(IsShared());
- if (!dom_array_buffer_)
- dom_array_buffer_ = DOMSharedArrayBuffer::Create(View()->Buffer());
-
+ DCHECK(dom_array_buffer_);
return static_cast<DOMSharedArrayBuffer*>(dom_array_buffer_.Get());
}
@@ -54,59 +52,102 @@ class CORE_EXPORT DOMArrayBufferView : public ScriptWrappable {
return buffer();
}
- const ArrayBufferView* View() const { return buffer_view_.get(); }
- ArrayBufferView* View() { return buffer_view_.get(); }
+ virtual ViewType GetType() const = 0;
+
+ const char* TypeName() {
+ switch (GetType()) {
+ case kTypeInt8:
+ return "Int8";
+ break;
+ case kTypeUint8:
+ return "UInt8";
+ break;
+ case kTypeUint8Clamped:
+ return "UInt8Clamped";
+ break;
+ case kTypeInt16:
+ return "Int16";
+ break;
+ case kTypeUint16:
+ return "UInt16";
+ break;
+ case kTypeInt32:
+ return "Int32";
+ break;
+ case kTypeUint32:
+ return "Uint32";
+ break;
+ case kTypeBigInt64:
+ return "BigInt64";
+ break;
+ case kTypeBigUint64:
+ return "BigUint64";
+ break;
+ case kTypeFloat32:
+ return "Float32";
+ break;
+ case kTypeFloat64:
+ return "Float64";
+ break;
+ case kTypeDataView:
+ return "DataView";
+ break;
+ }
+ }
+
+ void* BaseAddress() const {
+ DCHECK(!IsShared());
+ return BaseAddressMaybeShared();
+ }
- ViewType GetType() const { return View()->GetType(); }
- const char* TypeName() { return View()->TypeName(); }
- void* BaseAddress() const { return View()->BaseAddress(); }
- size_t byteOffsetAsSizeT() const { return View()->ByteOffset(); }
+ size_t byteOffsetAsSizeT() const {
+ return !IsDetached() ? raw_byte_offset_ : 0;
+ }
// This function is deprecated and should not be used. Use {byteOffsetAsSizeT}
// instead.
unsigned deprecatedByteOffsetAsUnsigned() const {
- return base::checked_cast<unsigned>(View()->ByteOffset());
+ return base::checked_cast<unsigned>(byteOffsetAsSizeT());
}
- size_t byteLengthAsSizeT() const { return View()->ByteLengthAsSizeT(); }
+ virtual size_t byteLengthAsSizeT() const = 0;
// This function is deprecated and should not be used. Use {byteLengthAsSizeT}
// instead.
unsigned deprecatedByteLengthAsUnsigned() const {
- return base::checked_cast<unsigned>(View()->ByteLengthAsSizeT());
+ return base::checked_cast<unsigned>(byteLengthAsSizeT());
}
- unsigned TypeSize() const { return View()->TypeSize(); }
- void SetDetachable(bool flag) { return View()->SetDetachable(flag); }
- bool IsShared() const { return View()->IsShared(); }
+ virtual unsigned TypeSize() const = 0;
+ bool IsShared() const { return dom_array_buffer_->IsShared(); }
void* BaseAddressMaybeShared() const {
- return View()->BaseAddressMaybeShared();
+ return !IsDetached() ? raw_base_address_ : nullptr;
}
- v8::Local<v8::Object> Wrap(v8::Isolate*,
- v8::Local<v8::Object> creation_context) override {
+ v8::Local<v8::Value> Wrap(v8::Isolate*,
+ v8::Local<v8::Object> creation_context) override {
NOTREACHED();
return v8::Local<v8::Object>();
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(dom_array_buffer_);
ScriptWrappable::Trace(visitor);
}
protected:
- explicit DOMArrayBufferView(scoped_refptr<ArrayBufferView> buffer_view)
- : buffer_view_(std::move(buffer_view)) {
- DCHECK(buffer_view_);
- }
- DOMArrayBufferView(scoped_refptr<ArrayBufferView> buffer_view,
- DOMArrayBufferBase* dom_array_buffer)
- : buffer_view_(std::move(buffer_view)),
- dom_array_buffer_(dom_array_buffer) {
- DCHECK(buffer_view_);
+ DOMArrayBufferView(DOMArrayBufferBase* dom_array_buffer, size_t byte_offset)
+ : raw_byte_offset_(byte_offset), dom_array_buffer_(dom_array_buffer) {
DCHECK(dom_array_buffer_);
- DCHECK_EQ(dom_array_buffer_->Buffer(), buffer_view_->Buffer());
+ raw_base_address_ =
+ static_cast<char*>(dom_array_buffer_->DataMaybeShared()) + byte_offset;
}
+ bool IsDetached() const { return dom_array_buffer_->IsDetached(); }
+
private:
- scoped_refptr<ArrayBufferView> buffer_view_;
+ // The raw_* fields may be stale after Detach. Use getters instead.
+ // This is the address of the ArrayBuffer's storage, plus the byte offset.
+ void* raw_base_address_;
+ size_t raw_byte_offset_;
+
mutable Member<DOMArrayBufferBase> dom_array_buffer_;
};
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_piece.cc b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_piece.cc
index 3118f4ab3cf..6e47cd45906 100644
--- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_piece.cc
+++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_piece.cc
@@ -9,19 +9,81 @@
namespace blink {
DOMArrayPiece::DOMArrayPiece(
- const ArrayBufferOrArrayBufferView& array_buffer_or_view,
- InitWithUnionOption option) {
+ const ArrayBufferOrArrayBufferView& array_buffer_or_view) {
if (array_buffer_or_view.IsArrayBuffer()) {
DOMArrayBuffer* array_buffer = array_buffer_or_view.GetAsArrayBuffer();
- InitWithArrayBuffer(array_buffer->Buffer());
+ InitWithArrayBuffer(array_buffer);
} else if (array_buffer_or_view.IsArrayBufferView()) {
DOMArrayBufferView* array_buffer_view =
array_buffer_or_view.GetAsArrayBufferView().View();
- InitWithArrayBufferView(array_buffer_view->View());
- } else if (array_buffer_or_view.IsNull() &&
- option == kAllowNullPointToNullWithZeroSize) {
- InitWithData(nullptr, 0);
- } // Otherwise, leave the obejct as null.
+ InitWithArrayBufferView(array_buffer_view);
+ }
+}
+///////////////////////////////////////////////////////
+DOMArrayPiece::DOMArrayPiece() {
+ InitNull();
+}
+
+DOMArrayPiece::DOMArrayPiece(DOMArrayBuffer* buffer) {
+ InitWithArrayBuffer(buffer);
+}
+
+DOMArrayPiece::DOMArrayPiece(DOMArrayBufferView* buffer) {
+ InitWithArrayBufferView(buffer);
+}
+
+bool DOMArrayPiece::IsNull() const {
+ return is_null_;
+}
+
+bool DOMArrayPiece::IsDetached() const {
+ return is_detached_;
+}
+
+void* DOMArrayPiece::Data() const {
+ DCHECK(!IsNull());
+ return data_;
+}
+
+unsigned char* DOMArrayPiece::Bytes() const {
+ return static_cast<unsigned char*>(Data());
+}
+
+size_t DOMArrayPiece::ByteLengthAsSizeT() const {
+ DCHECK(!IsNull());
+ return byte_length_;
+}
+
+void DOMArrayPiece::InitWithArrayBuffer(DOMArrayBuffer* buffer) {
+ if (buffer) {
+ InitWithData(buffer->Data(), buffer->ByteLengthAsSizeT());
+ is_detached_ = buffer->IsDetached();
+ } else {
+ InitNull();
+ }
+}
+
+void DOMArrayPiece::InitWithArrayBufferView(DOMArrayBufferView* buffer) {
+ if (buffer) {
+ InitWithData(buffer->BaseAddress(), buffer->byteLengthAsSizeT());
+ is_detached_ = buffer->buffer() ? buffer->buffer()->IsDetached() : true;
+ } else {
+ InitNull();
+ }
+}
+
+void DOMArrayPiece::InitWithData(void* data, size_t byte_length) {
+ byte_length_ = byte_length;
+ data_ = data;
+ is_null_ = false;
+ is_detached_ = false;
+}
+
+void DOMArrayPiece::InitNull() {
+ byte_length_ = 0;
+ data_ = nullptr;
+ is_null_ = true;
+ is_detached_ = false;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_piece.h b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_piece.h
index 41d75f19b25..a1752b68a8b 100644
--- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_piece.h
+++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_array_piece.h
@@ -5,51 +5,54 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_ARRAY_PIECE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_ARRAY_PIECE_H_
-#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.h"
+#include "third_party/blink/renderer/core/core_export.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"
namespace blink {
class ArrayBufferOrArrayBufferView;
+class DOMArrayBufferView;
// This class is for passing around un-owned bytes as a pointer + length.
// It supports implicit conversion from several other data types.
//
-// ArrayPiece has the concept of being "null". This is different from an empty
-// byte range. It is invalid to call methods other than isNull() on such
+// DOMArrayPiece has the concept of being "null". This is different from an
+// empty byte range. It is invalid to call methods other than isNull() on such
// instances.
//
-// IMPORTANT: The data contained by ArrayPiece is NOT OWNED, so caution must be
-// taken to ensure it is kept alive.
-class CORE_EXPORT DOMArrayPiece : public ArrayPiece {
+// IMPORTANT: The data contained by DOMArrayPiece is NOT OWNED, so caution must
+// be taken to ensure it is kept alive.
+class CORE_EXPORT DOMArrayPiece {
DISALLOW_NEW();
public:
- enum InitWithUnionOption {
- // Initialize this object as "null" when initialized with an union which
- // holds null.
- kTreatNullAsNull,
- // Initialize this object so this points to null pointer with zero size
- // when initialized with an union which holds null.
- kAllowNullPointToNullWithZeroSize,
- };
-
- DOMArrayPiece() = default;
- DOMArrayPiece(DOMArrayBuffer* buffer) : ArrayPiece(buffer->Buffer()) {}
- DOMArrayPiece(DOMArrayBufferView* view) : ArrayPiece(view->View()) {}
- DOMArrayPiece(const ArrayBufferOrArrayBufferView&,
- InitWithUnionOption = kTreatNullAsNull);
+ DOMArrayPiece();
+ DOMArrayPiece(DOMArrayBuffer* buffer);
+ DOMArrayPiece(DOMArrayBufferView* view);
+ DOMArrayPiece(const ArrayBufferOrArrayBufferView&);
bool operator==(const DOMArrayBuffer& other) const {
return ByteLengthAsSizeT() == other.ByteLengthAsSizeT() &&
memcmp(Data(), other.Data(), ByteLengthAsSizeT()) == 0;
}
- bool operator==(const DOMArrayBufferView& other) const {
- return ByteLengthAsSizeT() == other.byteLengthAsSizeT() &&
- memcmp(Data(), other.BaseAddress(), ByteLengthAsSizeT()) == 0;
- }
+ bool IsNull() const;
+ bool IsDetached() const;
+ void* Data() const;
+ unsigned char* Bytes() const;
+ size_t ByteLengthAsSizeT() const;
+
+ private:
+ void InitWithArrayBuffer(DOMArrayBuffer*);
+ void InitWithArrayBufferView(DOMArrayBufferView*);
+ void InitWithData(void* data, size_t byte_length);
+
+ void InitNull();
+
+ void* data_;
+ size_t byte_length_;
+ bool is_null_;
+ bool is_detached_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_data_view.cc b/chromium/third_party/blink/renderer/core/typed_arrays/dom_data_view.cc
index 0530327a8d6..50e4017caef 100644
--- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_data_view.cc
+++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_data_view.cc
@@ -6,54 +6,21 @@
#include "base/numerics/checked_math.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer.h"
-#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h"
#include "third_party/blink/renderer/platform/bindings/dom_data_store.h"
namespace blink {
-namespace {
-
-class DataView final : public ArrayBufferView {
- public:
- static scoped_refptr<DataView> Create(ArrayBuffer* buffer,
- unsigned byte_offset,
- size_t byte_length) {
- base::CheckedNumeric<uint32_t> checked_max = byte_offset;
- checked_max += byte_length;
- CHECK_LE(checked_max.ValueOrDie(), buffer->ByteLengthAsUnsigned());
- return base::AdoptRef(new DataView(buffer, byte_offset, byte_length));
- }
-
- size_t ByteLengthAsSizeT() const override { return byte_length_; }
- ViewType GetType() const override { return kTypeDataView; }
- unsigned TypeSize() const override { return 1; }
-
- protected:
- void Detach() override {
- ArrayBufferView::Detach();
- byte_length_ = 0;
- }
-
- private:
- DataView(ArrayBuffer* buffer, unsigned byte_offset, size_t byte_length)
- : ArrayBufferView(buffer, byte_offset), byte_length_(byte_length) {}
-
- size_t byte_length_;
-};
-
-} // anonymous namespace
-
DOMDataView* DOMDataView::Create(DOMArrayBufferBase* buffer,
- unsigned byte_offset,
- unsigned byte_length) {
- scoped_refptr<DataView> data_view =
- DataView::Create(buffer->Buffer(), byte_offset, byte_length);
- return MakeGarbageCollected<DOMDataView>(data_view, buffer);
+ size_t byte_offset,
+ size_t byte_length) {
+ base::CheckedNumeric<size_t> checked_max = byte_offset;
+ checked_max += byte_length;
+ CHECK_LE(checked_max.ValueOrDie(), buffer->ByteLengthAsSizeT());
+ return MakeGarbageCollected<DOMDataView>(buffer, byte_offset, byte_length);
}
-v8::Local<v8::Object> DOMDataView::Wrap(
- v8::Isolate* isolate,
- v8::Local<v8::Object> creation_context) {
+v8::Local<v8::Value> DOMDataView::Wrap(v8::Isolate* isolate,
+ v8::Local<v8::Object> creation_context) {
DCHECK(!DOMDataStore::ContainsWrapper(this, isolate));
const WrapperTypeInfo* wrapper_type_info = this->GetWrapperTypeInfo();
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_data_view.h b/chromium/third_party/blink/renderer/core/typed_arrays/dom_data_view.h
index caf0986e44f..e3618412f6d 100644
--- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_data_view.h
+++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_data_view.h
@@ -17,15 +17,30 @@ class CORE_EXPORT DOMDataView final : public DOMArrayBufferView {
typedef char ValueType;
static DOMDataView* Create(DOMArrayBufferBase*,
- unsigned byte_offset,
- unsigned byte_length);
+ size_t byte_offset,
+ size_t byte_length);
- DOMDataView(scoped_refptr<ArrayBufferView> data_view,
- DOMArrayBufferBase* dom_array_buffer)
- : DOMArrayBufferView(std::move(data_view), dom_array_buffer) {}
+ DOMDataView(DOMArrayBufferBase* dom_array_buffer,
+ size_t byte_offset,
+ size_t byte_length)
+ : DOMArrayBufferView(dom_array_buffer, byte_offset),
+ raw_byte_length_(byte_length) {}
- v8::Local<v8::Object> Wrap(v8::Isolate*,
- v8::Local<v8::Object> creation_context) override;
+ v8::Local<v8::Value> Wrap(v8::Isolate*,
+ v8::Local<v8::Object> creation_context) override;
+
+ size_t byteLengthAsSizeT() const final {
+ return !IsDetached() ? raw_byte_length_ : 0;
+ }
+
+ // DOMDataView is a byte array, therefore each field has size 1.
+ unsigned TypeSize() const final { return 1; }
+
+ DOMArrayBufferView::ViewType GetType() const final { return kTypeDataView; }
+
+ private:
+ // It may be stale after Detach. Use ByteLengthAsSizeT instead.
+ size_t raw_byte_length_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.cc b/chromium/third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.cc
index a2fabac3409..720f112b53d 100644
--- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.cc
+++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.cc
@@ -8,15 +8,15 @@
namespace blink {
-v8::Local<v8::Object> DOMSharedArrayBuffer::Wrap(
+v8::Local<v8::Value> DOMSharedArrayBuffer::Wrap(
v8::Isolate* isolate,
v8::Local<v8::Object> creation_context) {
DCHECK(!DOMDataStore::ContainsWrapper(this, isolate));
const WrapperTypeInfo* wrapper_type_info = this->GetWrapperTypeInfo();
v8::Local<v8::SharedArrayBuffer> wrapper =
- v8::SharedArrayBuffer::New(isolate, Buffer()->Content()->BackingStore());
- wrapper->Externalize(Buffer()->Content()->BackingStore());
+ v8::SharedArrayBuffer::New(isolate, Content()->BackingStore());
+ wrapper->Externalize(Content()->BackingStore());
return AssociateWithWrapper(isolate, wrapper_type_info, wrapper);
}
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.h b/chromium/third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.h
index 3a05a54c204..a504cf95640 100644
--- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.h
+++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.h
@@ -5,8 +5,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_SHARED_ARRAY_BUFFER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_SHARED_ARRAY_BUFFER_H_
+#include "base/allocator/partition_allocator/oom.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h"
+#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h"
namespace blink {
@@ -15,32 +16,47 @@ class CORE_EXPORT DOMSharedArrayBuffer final : public DOMArrayBufferBase {
DEFINE_WRAPPERTYPEINFO();
public:
- static DOMSharedArrayBuffer* Create(scoped_refptr<ArrayBuffer> buffer) {
- DCHECK(buffer->IsShared());
- return MakeGarbageCollected<DOMSharedArrayBuffer>(std::move(buffer));
+ static DOMSharedArrayBuffer* Create(ArrayBufferContents contents) {
+ DCHECK(contents.IsShared());
+ return MakeGarbageCollected<DOMSharedArrayBuffer>(std::move(contents));
}
+
static DOMSharedArrayBuffer* Create(unsigned num_elements,
unsigned element_byte_size) {
- return Create(ArrayBuffer::CreateShared(num_elements, element_byte_size));
+ ArrayBufferContents contents(num_elements, element_byte_size,
+ ArrayBufferContents::kShared,
+ ArrayBufferContents::kZeroInitialize);
+ if (UNLIKELY(!contents.DataShared())) {
+ OOM_CRASH(num_elements * element_byte_size);
+ }
+ return Create(std::move(contents));
}
+
static DOMSharedArrayBuffer* Create(const void* source,
unsigned byte_length) {
- return Create(ArrayBuffer::CreateShared(source, byte_length));
- }
- static DOMSharedArrayBuffer* Create(ArrayBufferContents& contents) {
- DCHECK(contents.IsShared());
- return Create(ArrayBuffer::Create(contents));
+ ArrayBufferContents contents(byte_length, 1, ArrayBufferContents::kShared,
+ ArrayBufferContents::kDontInitialize);
+ if (UNLIKELY(!contents.DataShared())) {
+ OOM_CRASH(byte_length);
+ }
+ memcpy(contents.DataShared(), source, byte_length);
+ return Create(std::move(contents));
}
- explicit DOMSharedArrayBuffer(scoped_refptr<ArrayBuffer> buffer)
- : DOMArrayBufferBase(std::move(buffer)) {}
+ explicit DOMSharedArrayBuffer(ArrayBufferContents contents)
+ : DOMArrayBufferBase(std::move(contents)) {}
bool ShareContentsWith(ArrayBufferContents& result) {
- return Buffer()->ShareContentsWith(result);
+ if (!Content()->BackingStore()) {
+ result.Detach();
+ return false;
+ }
+ Content()->ShareWith(result);
+ return true;
}
- v8::Local<v8::Object> Wrap(v8::Isolate*,
- v8::Local<v8::Object> creation_context) override;
+ v8::Local<v8::Value> Wrap(v8::Isolate*,
+ v8::Local<v8::Object> creation_context) override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_typed_array.cc b/chromium/third_party/blink/renderer/core/typed_arrays/dom_typed_array.cc
index 83efea3440d..6f76592e633 100644
--- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_typed_array.cc
+++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_typed_array.cc
@@ -20,8 +20,8 @@
namespace blink {
-template <typename TypedArray, typename V8TypedArray>
-v8::Local<v8::Object> DOMTypedArray<TypedArray, V8TypedArray>::Wrap(
+template <typename T, typename V8TypedArray, bool clamped>
+v8::Local<v8::Value> DOMTypedArray<T, V8TypedArray, clamped>::Wrap(
v8::Isolate* isolate,
v8::Local<v8::Object> creation_context) {
DCHECK(!DOMDataStore::ContainsWrapper(this, isolate));
@@ -68,34 +68,24 @@ DEFINE_DOMTYPEDARRAY_TRAITS(DOMBigUint64Array, V8BigUint64Array);
DEFINE_DOMTYPEDARRAY_TRAITS(DOMFloat32Array, V8Float32Array);
DEFINE_DOMTYPEDARRAY_TRAITS(DOMFloat64Array, V8Float64Array);
-template <typename TypedArray, typename V8TypedArray>
+template <typename T, typename V8TypedArray, bool clamped>
const WrapperTypeInfo*
-DOMTypedArray<TypedArray, V8TypedArray>::GetWrapperTypeInfo() const {
+DOMTypedArray<T, V8TypedArray, clamped>::GetWrapperTypeInfo() const {
return DOMTypedArrayTraits<
- DOMTypedArray<TypedArray, V8TypedArray>>::Type::GetWrapperTypeInfo();
+ DOMTypedArray<T, V8TypedArray, clamped>>::Type::GetWrapperTypeInfo();
}
+template class CORE_TEMPLATE_EXPORT DOMTypedArray<int8_t, v8::Int8Array>;
+template class CORE_TEMPLATE_EXPORT DOMTypedArray<int16_t, v8::Int16Array>;
+template class CORE_TEMPLATE_EXPORT DOMTypedArray<int32_t, v8::Int32Array>;
+template class CORE_TEMPLATE_EXPORT DOMTypedArray<uint8_t, v8::Uint8Array>;
template class CORE_TEMPLATE_EXPORT
- DOMTypedArray<TypedArray<int8_t>, v8::Int8Array>;
-template class CORE_TEMPLATE_EXPORT
- DOMTypedArray<TypedArray<int16_t>, v8::Int16Array>;
-template class CORE_TEMPLATE_EXPORT
- DOMTypedArray<TypedArray<int32_t>, v8::Int32Array>;
-template class CORE_TEMPLATE_EXPORT
- DOMTypedArray<TypedArray<uint8_t>, v8::Uint8Array>;
-template class CORE_TEMPLATE_EXPORT
- DOMTypedArray<TypedArray<uint8_t, /*clamped=*/true>, v8::Uint8ClampedArray>;
-template class CORE_TEMPLATE_EXPORT
- DOMTypedArray<TypedArray<uint16_t>, v8::Uint16Array>;
-template class CORE_TEMPLATE_EXPORT
- DOMTypedArray<TypedArray<uint32_t>, v8::Uint32Array>;
-template class CORE_TEMPLATE_EXPORT
- DOMTypedArray<TypedArray<int64_t>, v8::BigInt64Array>;
-template class CORE_TEMPLATE_EXPORT
- DOMTypedArray<TypedArray<uint64_t>, v8::BigUint64Array>;
-template class CORE_TEMPLATE_EXPORT
- DOMTypedArray<TypedArray<float>, v8::Float32Array>;
-template class CORE_TEMPLATE_EXPORT
- DOMTypedArray<TypedArray<double>, v8::Float64Array>;
+ DOMTypedArray<uint8_t, v8::Uint8ClampedArray, /*clamped=*/true>;
+template class CORE_TEMPLATE_EXPORT DOMTypedArray<uint16_t, v8::Uint16Array>;
+template class CORE_TEMPLATE_EXPORT DOMTypedArray<uint32_t, v8::Uint32Array>;
+template class CORE_TEMPLATE_EXPORT DOMTypedArray<int64_t, v8::BigInt64Array>;
+template class CORE_TEMPLATE_EXPORT DOMTypedArray<uint64_t, v8::BigUint64Array>;
+template class CORE_TEMPLATE_EXPORT DOMTypedArray<float, v8::Float32Array>;
+template class CORE_TEMPLATE_EXPORT DOMTypedArray<double, v8::Float64Array>;
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/dom_typed_array.h b/chromium/third_party/blink/renderer/core/typed_arrays/dom_typed_array.h
index a52b5a5f7f2..8ca51f82b14 100644
--- a/chromium/third_party/blink/renderer/core/typed_arrays/dom_typed_array.h
+++ b/chromium/third_party/blink/renderer/core/typed_arrays/dom_typed_array.h
@@ -6,7 +6,6 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_DOM_TYPED_ARRAY_H_
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/typed_arrays/array_buffer/typed_array.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -14,114 +13,165 @@
namespace blink {
-template <typename TypedArray, typename V8TypedArray>
+namespace {
+// Helper to verify that a given sub-range of an ArrayBuffer is within range.
+template <typename T>
+bool VerifySubRange(const DOMArrayBufferBase* buffer,
+ size_t byte_offset,
+ size_t num_elements) {
+ if (!buffer)
+ return false;
+ if (sizeof(T) > 1 && byte_offset % sizeof(T))
+ return false;
+ if (byte_offset > buffer->ByteLengthAsSizeT())
+ return false;
+ size_t remaining_elements =
+ (buffer->ByteLengthAsSizeT() - byte_offset) / sizeof(T);
+ if (num_elements > remaining_elements)
+ return false;
+ return true;
+}
+} // namespace
+
+template <typename T, typename V8TypedArray, bool clamped = false>
class DOMTypedArray final : public DOMArrayBufferView {
- typedef DOMTypedArray<TypedArray, V8TypedArray> ThisType;
+ typedef DOMTypedArray<T, V8TypedArray, clamped> ThisType;
DECLARE_WRAPPERTYPEINFO();
public:
- typedef typename TypedArray::ValueType ValueType;
-
- static ThisType* Create(scoped_refptr<TypedArray> buffer_view) {
- return MakeGarbageCollected<ThisType>(std::move(buffer_view));
+ typedef T ValueType;
+ static ThisType* Create(DOMArrayBufferBase* buffer,
+ size_t byte_offset,
+ size_t length) {
+ CHECK(VerifySubRange<ValueType>(buffer, byte_offset, length));
+ return MakeGarbageCollected<ThisType>(buffer, byte_offset, length);
}
+
static ThisType* Create(size_t length) {
- return Create(TypedArray::Create(length));
+ DOMArrayBuffer* buffer = DOMArrayBuffer::Create(length, sizeof(ValueType));
+ return Create(buffer, 0, length);
}
+
static ThisType* Create(const ValueType* array, size_t length) {
- return Create(TypedArray::Create(array, length));
- }
- static ThisType* Create(scoped_refptr<ArrayBuffer> buffer,
- size_t byte_offset,
- size_t length) {
- return Create(TypedArray::Create(std::move(buffer), byte_offset, length));
- }
- static ThisType* Create(DOMArrayBufferBase* buffer,
- size_t byte_offset,
- size_t length) {
- scoped_refptr<TypedArray> buffer_view =
- TypedArray::Create(buffer->Buffer(), byte_offset, length);
- return MakeGarbageCollected<ThisType>(std::move(buffer_view), buffer);
+ DOMArrayBuffer* buffer =
+ DOMArrayBuffer::Create(array, length * sizeof(ValueType));
+ return Create(buffer, 0, length);
}
static ThisType* CreateOrNull(size_t length) {
- scoped_refptr<ArrayBuffer> buffer =
- ArrayBuffer::CreateOrNull(length, sizeof(ValueType));
+ DOMArrayBuffer* buffer =
+ DOMArrayBuffer::CreateOrNull(length, sizeof(ValueType));
return buffer ? Create(std::move(buffer), 0, length) : nullptr;
}
static ThisType* CreateUninitializedOrNull(size_t length) {
- scoped_refptr<ArrayBuffer> buffer =
- ArrayBuffer::CreateOrNull(length, sizeof(ValueType));
- return buffer ? Create(std::move(buffer), 0, length) : nullptr;
+ DOMArrayBuffer* buffer =
+ DOMArrayBuffer::CreateUninitializedOrNull(length, sizeof(ValueType));
+ return buffer ? Create(buffer, 0, length) : nullptr;
}
- explicit DOMTypedArray(scoped_refptr<TypedArray> buffer_view)
- : DOMArrayBufferView(std::move(buffer_view)) {}
- DOMTypedArray(scoped_refptr<TypedArray> buffer_view,
- DOMArrayBufferBase* dom_array_buffer)
- : DOMArrayBufferView(std::move(buffer_view), dom_array_buffer) {}
+ DOMTypedArray(DOMArrayBufferBase* dom_array_buffer,
+ size_t byte_offset,
+ size_t length)
+ : DOMArrayBufferView(dom_array_buffer, byte_offset),
+ raw_length_(length) {}
- const TypedArray* View() const {
- return static_cast<const TypedArray*>(DOMArrayBufferView::View());
- }
- TypedArray* View() {
- return static_cast<TypedArray*>(DOMArrayBufferView::View());
+ ValueType* Data() const { return static_cast<ValueType*>(BaseAddress()); }
+
+ ValueType* DataMaybeShared() const {
+ return reinterpret_cast<ValueType*>(BaseAddressMaybeShared());
}
- ValueType* Data() const { return View()->Data(); }
- ValueType* DataMaybeShared() const { return View()->DataMaybeShared(); }
- size_t lengthAsSizeT() const { return View()->length(); }
- // This function is deprecated and should not be used. Use {lengthAsSizeT}
- // instead.
- unsigned deprecatedLengthAsUnsigned() const {
- return base::checked_cast<unsigned>(View()->length());
+ size_t lengthAsSizeT() const { return !IsDetached() ? raw_length_ : 0; }
+
+ size_t byteLengthAsSizeT() const final {
+ return lengthAsSizeT() * sizeof(ValueType);
}
+
+ unsigned TypeSize() const final { return sizeof(ValueType); }
+
+ DOMArrayBufferView::ViewType GetType() const override;
+
// Invoked by the indexed getter. Does not perform range checks; caller
// is responsible for doing so and returning undefined as necessary.
- ValueType Item(size_t index) const { return View()->Item(index); }
+ ValueType Item(size_t index) const {
+ SECURITY_DCHECK(index < lengthAsSizeT());
+ return Data()[index];
+ }
- v8::Local<v8::Object> Wrap(v8::Isolate*,
- v8::Local<v8::Object> creation_context) override;
+ v8::Local<v8::Value> Wrap(v8::Isolate*,
+ v8::Local<v8::Object> creation_context) override;
+
+ private:
+ // It may be stale after Detach. Use lengthAsSizeT() instead.
+ size_t raw_length_;
};
+#define FOREACH_VIEW_TYPE(V) \
+ V(int8_t, v8::Int8Array, kTypeInt8) \
+ V(int16_t, v8::Int16Array, kTypeInt16) \
+ V(int32_t, v8::Int32Array, kTypeInt32) \
+ V(uint8_t, v8::Uint8Array, kTypeUint8) \
+ V(uint16_t, v8::Uint16Array, kTypeUint16) \
+ V(uint32_t, v8::Uint32Array, kTypeUint32) \
+ V(float, v8::Float32Array, kTypeFloat32) \
+ V(double, v8::Float64Array, kTypeFloat64) \
+ V(int64_t, v8::BigInt64Array, kTypeBigInt64) \
+ V(uint64_t, v8::BigUint64Array, kTypeBigUint64)
+
+#define GET_TYPE(c_type, v8_type, view_type) \
+ template <> \
+ inline DOMArrayBufferView::ViewType \
+ DOMTypedArray<c_type, v8_type, false>::GetType() const { \
+ return DOMArrayBufferView::view_type; \
+ }
+
+FOREACH_VIEW_TYPE(GET_TYPE)
+
+#undef GET_TYPE
+#undef FOREACH_VIEW_TYPE
+
+template <>
+inline DOMArrayBufferView::ViewType
+DOMTypedArray<uint8_t, v8::Uint8ClampedArray, true>::GetType() const {
+ return DOMArrayBufferView::kTypeUint8Clamped;
+}
+
extern template class CORE_EXTERN_TEMPLATE_EXPORT
- DOMTypedArray<TypedArray<int8_t>, v8::Int8Array>;
+ DOMTypedArray<int8_t, v8::Int8Array>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT
- DOMTypedArray<TypedArray<int16_t>, v8::Int16Array>;
+ DOMTypedArray<int16_t, v8::Int16Array>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT
- DOMTypedArray<TypedArray<int32_t>, v8::Int32Array>;
+ DOMTypedArray<int32_t, v8::Int32Array>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT
- DOMTypedArray<TypedArray<uint8_t>, v8::Uint8Array>;
+ DOMTypedArray<uint8_t, v8::Uint8Array>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT
- DOMTypedArray<TypedArray<uint8_t, /*clamped=*/true>, v8::Uint8ClampedArray>;
+ DOMTypedArray<uint8_t, v8::Uint8ClampedArray, /*clamped=*/true>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT
- DOMTypedArray<TypedArray<uint16_t>, v8::Uint16Array>;
+ DOMTypedArray<uint16_t, v8::Uint16Array>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT
- DOMTypedArray<TypedArray<uint32_t>, v8::Uint32Array>;
+ DOMTypedArray<uint32_t, v8::Uint32Array>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT
- DOMTypedArray<TypedArray<int64_t>, v8::BigInt64Array>;
+ DOMTypedArray<int64_t, v8::BigInt64Array>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT
- DOMTypedArray<TypedArray<uint64_t>, v8::BigUint64Array>;
+ DOMTypedArray<uint64_t, v8::BigUint64Array>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT
- DOMTypedArray<TypedArray<float>, v8::Float32Array>;
+ DOMTypedArray<float, v8::Float32Array>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT
- DOMTypedArray<TypedArray<double>, v8::Float64Array>;
-
-typedef DOMTypedArray<TypedArray<int8_t>, v8::Int8Array> DOMInt8Array;
-typedef DOMTypedArray<TypedArray<int16_t>, v8::Int16Array> DOMInt16Array;
-typedef DOMTypedArray<TypedArray<int32_t>, v8::Int32Array> DOMInt32Array;
-typedef DOMTypedArray<TypedArray<uint8_t>, v8::Uint8Array> DOMUint8Array;
-typedef DOMTypedArray<TypedArray<uint8_t, /*clamped=*/true>,
- v8::Uint8ClampedArray>
+ DOMTypedArray<double, v8::Float64Array>;
+
+typedef DOMTypedArray<int8_t, v8::Int8Array> DOMInt8Array;
+typedef DOMTypedArray<int16_t, v8::Int16Array> DOMInt16Array;
+typedef DOMTypedArray<int32_t, v8::Int32Array> DOMInt32Array;
+typedef DOMTypedArray<uint8_t, v8::Uint8Array> DOMUint8Array;
+typedef DOMTypedArray<uint8_t, v8::Uint8ClampedArray, /*clamped=*/true>
DOMUint8ClampedArray;
-typedef DOMTypedArray<TypedArray<uint16_t>, v8::Uint16Array> DOMUint16Array;
-typedef DOMTypedArray<TypedArray<uint32_t>, v8::Uint32Array> DOMUint32Array;
-typedef DOMTypedArray<TypedArray<int64_t>, v8::BigInt64Array> DOMBigInt64Array;
-typedef DOMTypedArray<TypedArray<uint64_t>, v8::BigUint64Array>
- DOMBigUint64Array;
-typedef DOMTypedArray<TypedArray<float>, v8::Float32Array> DOMFloat32Array;
-typedef DOMTypedArray<TypedArray<double>, v8::Float64Array> DOMFloat64Array;
+typedef DOMTypedArray<uint16_t, v8::Uint16Array> DOMUint16Array;
+typedef DOMTypedArray<uint32_t, v8::Uint32Array> DOMUint32Array;
+typedef DOMTypedArray<int64_t, v8::BigInt64Array> DOMBigInt64Array;
+typedef DOMTypedArray<uint64_t, v8::BigUint64Array> DOMBigUint64Array;
+typedef DOMTypedArray<float, v8::Float32Array> DOMFloat32Array;
+typedef DOMTypedArray<double, v8::Float64Array> DOMFloat64Array;
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/flexible_array_buffer_view.h b/chromium/third_party/blink/renderer/core/typed_arrays/flexible_array_buffer_view.h
index de71e231b1e..6bcd117e894 100644
--- a/chromium/third_party/blink/renderer/core/typed_arrays/flexible_array_buffer_view.h
+++ b/chromium/third_party/blink/renderer/core/typed_arrays/flexible_array_buffer_view.h
@@ -6,23 +6,31 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_FLEXIBLE_ARRAY_BUFFER_VIEW_H_
#include "base/macros.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer_view.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
+// FlexibleArrayBufferView is a performance hack to avoid overhead to
+// instantiate DOMArrayBufferView and DOMArrayBuffer when the contents are
+// very small. Otherwise, FlexibleArrayBufferView is a thin wrapper to
+// DOMArrayBufferView.
class CORE_EXPORT FlexibleArrayBufferView {
STACK_ALLOCATED();
public:
- FlexibleArrayBufferView() : small_data_(nullptr), small_length_(0) {}
-
- void SetFull(DOMArrayBufferView* full) { full_ = full; }
- void SetSmall(void* data, uint32_t length) {
- small_data_ = data;
- small_length_ = length;
+ FlexibleArrayBufferView() = default;
+ FlexibleArrayBufferView(const FlexibleArrayBufferView&) = default;
+ FlexibleArrayBufferView(FlexibleArrayBufferView&&) = default;
+ FlexibleArrayBufferView(v8::Local<v8::ArrayBufferView> array_buffer_view) {
+ SetContents(array_buffer_view);
}
+ ~FlexibleArrayBufferView() = default;
+
+ FlexibleArrayBufferView& operator=(const FlexibleArrayBufferView&) = delete;
+ FlexibleArrayBufferView& operator=(FlexibleArrayBufferView&&) = delete;
void Clear() {
full_ = nullptr;
@@ -30,7 +38,21 @@ class CORE_EXPORT FlexibleArrayBufferView {
small_length_ = 0;
}
- bool IsEmpty() const { return !full_ && !small_data_; }
+ void SetContents(v8::Local<v8::ArrayBufferView> array_buffer_view) {
+ DCHECK(IsNull());
+ size_t size = array_buffer_view->ByteLength();
+ if (size <= sizeof small_buffer_) {
+ array_buffer_view->CopyContents(small_buffer_, size);
+ small_data_ = small_buffer_;
+ small_length_ = size;
+ } else {
+ full_ = V8ArrayBufferView::ToImpl(array_buffer_view);
+ }
+ }
+
+ // Returns true if this object represents IDL null.
+ bool IsNull() const { return !full_ && !small_data_; }
+
bool IsFull() const { return full_; }
DOMArrayBufferView* Full() const {
@@ -42,28 +64,35 @@ class CORE_EXPORT FlexibleArrayBufferView {
// temporary storage that is only valid during the life-time of the
// FlexibleArrayBufferView object.
void* BaseAddressMaybeOnStack() const {
- DCHECK(!IsEmpty());
+ DCHECK(!IsNull());
return IsFull() ? full_->BaseAddressMaybeShared() : small_data_;
}
- unsigned ByteOffset() const {
- DCHECK(!IsEmpty());
- return IsFull() ? full_->deprecatedByteOffsetAsUnsigned() : 0;
+ size_t ByteLengthAsSizeT() const {
+ DCHECK(!IsNull());
+ return IsFull() ? full_->byteLengthAsSizeT() : small_length_;
}
- unsigned ByteLength() const {
- DCHECK(!IsEmpty());
- return IsFull() ? full_->deprecatedByteLengthAsUnsigned() : small_length_;
+ unsigned DeprecatedByteLengthAsUnsigned() const {
+ DCHECK(!IsNull());
+ return IsFull() ? base::checked_cast<unsigned>(full_->byteLengthAsSizeT())
+ : base::checked_cast<unsigned>(small_length_);
}
- operator bool() const { return !IsEmpty(); }
+ // TODO(crbug.com/1050474): Remove this cast operator and make the callsites
+ // explicitly call IsNull().
+ operator bool() const { return !IsNull(); }
private:
- Member<DOMArrayBufferView> full_;
-
- void* small_data_;
- uint32_t small_length_;
- DISALLOW_COPY_AND_ASSIGN(FlexibleArrayBufferView);
+ DOMArrayBufferView* full_ = nullptr;
+
+ // If the contents of the given v8::ArrayBufferView are small enough to fit
+ // within |small_buffer_|, the contents are directly copied into
+ // |small_buffer_| to which accesses are much faster than to a maybe-shared
+ // buffer in a DOMArrayBufferView.
+ void* small_data_ = nullptr; // Non null iff |small_buffer_| is used
+ size_t small_length_ = 0; // The size actually used of |small_buffer_|
+ uint8_t small_buffer_[64];
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/typed_arrays/typed_flexible_array_buffer_view.h b/chromium/third_party/blink/renderer/core/typed_arrays/typed_flexible_array_buffer_view.h
index cad257296ac..bafb6f282a1 100644
--- a/chromium/third_party/blink/renderer/core/typed_arrays/typed_flexible_array_buffer_view.h
+++ b/chromium/third_party/blink/renderer/core/typed_arrays/typed_flexible_array_buffer_view.h
@@ -6,40 +6,43 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_TYPED_ARRAYS_TYPED_FLEXIBLE_ARRAY_BUFFER_VIEW_H_
#include "base/macros.h"
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/typed_arrays/array_buffer/typed_array.h"
#include "third_party/blink/renderer/core/typed_arrays/flexible_array_buffer_view.h"
namespace blink {
-template <typename TypedArray>
+template <typename ValueType, bool clamped = false>
class TypedFlexibleArrayBufferView final : public FlexibleArrayBufferView {
STACK_ALLOCATED();
public:
- using ValueType = typename TypedArray::ValueType;
-
- TypedFlexibleArrayBufferView() : FlexibleArrayBufferView() {}
+ TypedFlexibleArrayBufferView() = default;
+ TypedFlexibleArrayBufferView(const TypedFlexibleArrayBufferView&) = default;
+ TypedFlexibleArrayBufferView(TypedFlexibleArrayBufferView&&) = default;
+ TypedFlexibleArrayBufferView(v8::Local<v8::ArrayBufferView> array_buffer_view)
+ : FlexibleArrayBufferView(array_buffer_view) {}
+ ~TypedFlexibleArrayBufferView() = default;
ValueType* DataMaybeOnStack() const {
return static_cast<ValueType*>(BaseAddressMaybeOnStack());
}
- unsigned length() const {
- DCHECK_EQ(ByteLength() % sizeof(ValueType), 0u);
- return ByteLength() / sizeof(ValueType);
+ size_t lengthAsSizeT() const {
+ DCHECK_EQ(ByteLengthAsSizeT() % sizeof(ValueType), 0u);
+ return ByteLengthAsSizeT() / sizeof(ValueType);
}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(TypedFlexibleArrayBufferView);
};
-using FlexibleFloat32ArrayView =
- TypedFlexibleArrayBufferView<TypedArray<float>>;
-using FlexibleInt32ArrayView =
- TypedFlexibleArrayBufferView<TypedArray<int32_t>>;
-using FlexibleUint32ArrayView =
- TypedFlexibleArrayBufferView<TypedArray<uint32_t>>;
+using FlexibleInt8Array = TypedFlexibleArrayBufferView<int8_t>;
+using FlexibleInt16Array = TypedFlexibleArrayBufferView<int16_t>;
+using FlexibleInt32Array = TypedFlexibleArrayBufferView<int32_t>;
+using FlexibleUint8Array = TypedFlexibleArrayBufferView<uint8_t>;
+using FlexibleUint8ClampedArray = TypedFlexibleArrayBufferView<uint8_t, true>;
+using FlexibleUint16Array = TypedFlexibleArrayBufferView<uint16_t>;
+using FlexibleUint32Array = TypedFlexibleArrayBufferView<uint32_t>;
+using FlexibleBigInt64Array = TypedFlexibleArrayBufferView<int64_t>;
+using FlexibleBigUint64Array = TypedFlexibleArrayBufferView<uint64_t>;
+using FlexibleFloat32Array = TypedFlexibleArrayBufferView<float>;
+using FlexibleFloat64Array = TypedFlexibleArrayBufferView<double>;
} // namespace blink
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 5b000ded31c..1c13f28e14f 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(blink::Visitor* visitor) {
+void DOMURL::Trace(Visitor* visitor) {
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 13432a8511a..3cfc0845119 100644
--- a/chromium/third_party/blink/renderer/core/url/dom_url.h
+++ b/chromium/third_party/blink/renderer/core/url/dom_url.h
@@ -41,7 +41,7 @@ class ExecutionContext;
class URLRegistrable;
class URLSearchParams;
-class DOMURL final : public ScriptWrappable, public DOMURLUtils {
+class CORE_EXPORT DOMURL final : public ScriptWrappable, public DOMURLUtils {
DEFINE_WRAPPERTYPEINFO();
public:
@@ -59,7 +59,7 @@ class DOMURL final : public ScriptWrappable, public DOMURLUtils {
DOMURL(const String& url, const KURL& base, ExceptionState&);
~DOMURL() override;
- CORE_EXPORT static String CreatePublicURL(ExecutionContext*, URLRegistrable*);
+ static String CreatePublicURL(ExecutionContext*, URLRegistrable*);
KURL Url() const override { return url_; }
void SetURL(const KURL& url) override { url_ = url; }
@@ -73,7 +73,7 @@ class DOMURL final : public ScriptWrappable, public DOMURLUtils {
String toJSON() { return href(); }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
friend class URLSearchParams;
diff --git a/chromium/third_party/blink/renderer/core/url/url.idl b/chromium/third_party/blink/renderer/core/url/url.idl
index 58fd2eba88a..71451416ee1 100644
--- a/chromium/third_party/blink/renderer/core/url/url.idl
+++ b/chromium/third_party/blink/renderer/core/url/url.idl
@@ -27,11 +27,11 @@
// https://url.spec.whatwg.org/#url
[
- Constructor(USVString url, optional USVString base),
Exposed=(Window,Worker),
ImplementedAs=DOMURL,
- RaisesException=Constructor
+ LegacyWindowAlias=webkitURL
] interface URL {
+ [RaisesException] constructor(USVString url, optional USVString base);
stringifier attribute USVString href;
readonly attribute USVString origin;
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 65db947ce84..69a7d532f83 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(params_);
PairIterable<String, String>::IterationSource::Trace(visitor);
}
@@ -111,7 +111,7 @@ URLSearchParams* URLSearchParams::Create(
URLSearchParams::~URLSearchParams() = default;
-void URLSearchParams::Trace(blink::Visitor* visitor) {
+void URLSearchParams::Trace(Visitor* visitor) {
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 9a60514708b..ab27f7cf5a9 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
FRIEND_TEST_ALL_PREFIXES(URLSearchParamsTest, EncodedFormData);
diff --git a/chromium/third_party/blink/renderer/core/url/url_search_params.idl b/chromium/third_party/blink/renderer/core/url/url_search_params.idl
index c9148aaba41..31c36948cda 100644
--- a/chromium/third_party/blink/renderer/core/url/url_search_params.idl
+++ b/chromium/third_party/blink/renderer/core/url/url_search_params.idl
@@ -5,10 +5,9 @@
// https://url.spec.whatwg.org/#interface-urlsearchparams
[
- Constructor(optional (sequence<sequence<USVString>> or record<USVString, USVString> or USVString) init = ""),
- Exposed=(Window,Worker),
- RaisesException=Constructor
+ Exposed=(Window,Worker)
] interface URLSearchParams {
+ [RaisesException] constructor(optional (sequence<sequence<USVString>> or record<USVString, USVString> or USVString) init = "");
void append(USVString name, USVString value);
[ImplementedAs=deleteAllWithName] void delete(USVString name);
USVString? get(USVString name);
diff --git a/chromium/third_party/blink/renderer/core/workers/README.md b/chromium/third_party/blink/renderer/core/workers/README.md
index 3ea34fe4abc..9d1ea093c51 100644
--- a/chromium/third_party/blink/renderer/core/workers/README.md
+++ b/chromium/third_party/blink/renderer/core/workers/README.md
@@ -120,6 +120,10 @@ There are some fundamental metrics.
: Counts of `new DedicatedWorker()` calls in `DedicatedWorkerGlobalScope`.
- [SharedWorkerStart](https://www.chromestatus.com/metrics/feature/timeline/popularity/5)
: Counts of `new SharedWorker()` calls in `Document`.
+- [ClassicSharedWorker](https://www.chromestatus.com/metrics/feature/timeline/popularity/3148)
+: Counts of new SharedWorker() calls with `{ type: 'classic' }` or without `WorkerOptions#type` argument.
+- [ModuleSharedWorker](https://www.chromestatus.com/metrics/feature/timeline/popularity/3149)
+: Counts of new SharedWorker() calls with `{ type: 'module' }`.
- [WorkletAddModule](https://www.chromestatus.com/metrics/feature/timeline/popularity/2364)
: Counts of `Worklet#addModule()` calls in `Document`. This includes all worklet
types. Each worklet type has its own counter, too.
@@ -174,6 +178,8 @@ in the following files and directories to avoid breakage.
# References
+- [ES Modules for Shared Workers](https://docs.google.com/document/d/1sSdYdSOLd5zvnNGeVNlBqfTZs_VRPIrrigV3SlMnWjg/edit?usp=sharing) (Feb 19, 2020)
- [WorkerGlobalScope Initialization](https://docs.google.com/document/d/1JCv8TD2nPLNC2iRCp_D1OM4I3uTS0HoEobuTymaMqgw/edit?usp=sharing) (April 1, 2019)
- [Worker / Worklet Internals](https://docs.google.com/presentation/d/1GZJ3VnLIO_Pw0jr9nRw6_-trg68ol-AkliMxJ6jo6Bo/edit?usp=sharing) (April 19, 2018)
+- [ES Modules for Dedicated Workers](https://docs.google.com/document/d/1IMGWAK7Wq37mLehwkbysNRBBnhQBo3z2MbYyMkViEnY/edit?usp=sharing) (Mar 8, 2018)
- [Design of UseCounter for workers](https://docs.google.com/document/d/1VyYZnhjBdk-MzCRAcX37TM5-yjwTY40U_J9rWnEAo8c/edit?usp=sharing) (Feb 14, 2017)
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 a9ff2721e15..eb5eef37994 100644
--- a/chromium/third_party/blink/renderer/core/workers/abstract_worker.cc
+++ b/chromium/third_party/blink/renderer/core/workers/abstract_worker.cc
@@ -38,7 +38,7 @@
namespace blink {
AbstractWorker::AbstractWorker(ExecutionContext* context)
- : ContextLifecycleStateObserver(context) {}
+ : ExecutionContextLifecycleStateObserver(context) {}
AbstractWorker::~AbstractWorker() = default;
@@ -79,9 +79,9 @@ KURL AbstractWorker::ResolveURL(ExecutionContext* execution_context,
return script_url;
}
-void AbstractWorker::Trace(blink::Visitor* visitor) {
+void AbstractWorker::Trace(Visitor* visitor) {
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 aa6cd7d6d24..96ffa1dbe0f 100644
--- a/chromium/third_party/blink/renderer/core/workers/abstract_worker.h
+++ b/chromium/third_party/blink/renderer/core/workers/abstract_worker.h
@@ -35,7 +35,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/events/event_listener.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -47,22 +47,25 @@ class ExecutionContext;
// Implementation of the AbstractWorker interface defined in the WebWorker HTML
// spec: https://html.spec.whatwg.org/C/#abstractworker
-class CORE_EXPORT AbstractWorker : public EventTargetWithInlineData,
- public ContextLifecycleStateObserver {
+class CORE_EXPORT AbstractWorker
+ : public EventTargetWithInlineData,
+ public ExecutionContextLifecycleStateObserver {
USING_GARBAGE_COLLECTED_MIXIN(AbstractWorker);
public:
// EventTarget APIs
ExecutionContext* GetExecutionContext() const final {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
+ void ContextDestroyed() override {}
+
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(error, kError)
AbstractWorker(ExecutionContext*);
~AbstractWorker() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
// Helper function that converts a URL to an absolute URL and checks the
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 19da6821016..86f200fecc0 100644
--- a/chromium/third_party/blink/renderer/core/workers/dedicated_worker.cc
+++ b/chromium/third_party/blink/renderer/core/workers/dedicated_worker.cc
@@ -5,7 +5,9 @@
#include "third_party/blink/renderer/core/workers/dedicated_worker.h"
#include <utility>
+
#include "base/feature_list.h"
+#include "base/optional.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "services/network/public/mojom/fetch_api.mojom-blink.h"
#include "third_party/blink/public/common/blob/blob_utils.h"
@@ -15,7 +17,9 @@
#include "third_party/blink/public/mojom/worker/dedicated_worker_host_factory.mojom-blink.h"
#include "third_party/blink/public/platform/web_content_settings_client.h"
#include "third_party/blink/public/platform/web_fetch_client_settings_object.h"
+#include "third_party/blink/public/web/web_widget_client.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_post_message_options.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/execution_context/execution_context.h"
@@ -30,7 +34,6 @@
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/loader/frame_loader.h"
#include "third_party/blink/renderer/core/loader/worker_fetch_context.h"
-#include "third_party/blink/renderer/core/messaging/post_message_options.h"
#include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
@@ -41,7 +44,6 @@
#include "third_party/blink/renderer/core/workers/worker_global_scope.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/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h"
@@ -49,50 +51,6 @@
namespace blink {
-namespace {
-
-// Indicates whether the origin of worker top-level script's request URL is
-// same-origin as the parent execution context's origin or not.
-// This is used for UMA and thus the existing values should not be changed.
-enum class WorkerTopLevelScriptOriginType {
- kSameOrigin = 0,
- kDataUrl = 1,
-
- // Cross-origin worker request URL (e.g. https://example.com/worker.js)
- // from an chrome-extension: page.
- kCrossOriginFromExtension = 2,
-
- // Cross-origin worker request URL from a non chrome-extension: page.
- // There are no known cases for this, and we investigate whether there are
- // really no occurrences.
- kCrossOriginOthers = 3,
-
- kMaxValue = kCrossOriginOthers
-};
-
-void CountTopLevelScriptRequestUrlOriginType(
- const SecurityOrigin& context_origin,
- const KURL& request_url) {
- WorkerTopLevelScriptOriginType origin_type;
- if (request_url.ProtocolIsData()) {
- origin_type = WorkerTopLevelScriptOriginType::kDataUrl;
- } else if (context_origin.IsSameOriginWith(
- SecurityOrigin::Create(request_url).get())) {
- origin_type = WorkerTopLevelScriptOriginType::kSameOrigin;
- } else if (context_origin.Protocol() == "chrome-extension") {
- // Note: using "chrome-extension" scheme check here is a layering
- // violation. Do not use this except for UMA purpose.
- origin_type = WorkerTopLevelScriptOriginType::kCrossOriginFromExtension;
- } else {
- origin_type = WorkerTopLevelScriptOriginType::kCrossOriginOthers;
- }
- UMA_HISTOGRAM_ENUMERATION(
- "Worker.TopLevelScript.OriginType.RequestUrl.DedicatedWorker",
- origin_type);
-}
-
-} // namespace
-
DedicatedWorker* DedicatedWorker::Create(ExecutionContext* context,
const String& url,
const WorkerOptions* options,
@@ -113,17 +71,6 @@ DedicatedWorker* DedicatedWorker::Create(ExecutionContext* context,
return nullptr;
}
- // TODO(nhiroki): Remove this flag check once module loading for
- // DedicatedWorker is enabled by default (https://crbug.com/680046).
- if (options->type() == "module" &&
- !RuntimeEnabledFeatures::ModuleDedicatedWorkerEnabled()) {
- exception_state.ThrowTypeError(
- "Module scripts are not supported on DedicatedWorker yet. You can try "
- "the feature with '--enable-experimental-web-platform-features' flag "
- "(see https://crbug.com/680046)");
- return nullptr;
- }
-
if (context->IsWorkerGlobalScope())
UseCounter::Count(context, WebFeature::kNestedDedicatedWorker);
@@ -233,9 +180,10 @@ void DedicatedWorker::Start() {
// https://html.spec.whatwg.org/C/#workeroptions
auto credentials_mode = network::mojom::CredentialsMode::kSameOrigin;
if (options_->type() == "module") {
- bool result = Request::ParseCredentialsMode(options_->credentials(),
- &credentials_mode);
+ base::Optional<network::mojom::CredentialsMode> result =
+ Request::ParseCredentialsMode(options_->credentials());
DCHECK(result);
+ credentials_mode = result.value();
}
mojo::PendingRemote<mojom::blink::BlobURLToken> blob_url_token;
@@ -253,8 +201,26 @@ void DedicatedWorker::Start() {
return;
}
- factory_client_->CreateWorkerHostDeprecated();
+ mojo::PendingRemote<network::mojom::blink::URLLoaderFactory>
+ blob_url_loader_factory;
+ if (script_request_url_.ProtocolIs("blob")) {
+ GetExecutionContext()->GetPublicURLManager().Resolve(
+ script_request_url_,
+ blob_url_loader_factory.InitWithNewPipeAndPassReceiver());
+ }
+ factory_client_->CreateWorkerHostDeprecated(
+ WTF::Bind(&DedicatedWorker::OnHostCreated, WrapWeakPersistent(this),
+ std::move(blob_url_loader_factory)));
+}
+void DedicatedWorker::OnHostCreated(
+ mojo::PendingRemote<network::mojom::blink::URLLoaderFactory>
+ blob_url_loader_factory,
+ const network::CrossOriginEmbedderPolicy& parent_coep) {
+ DCHECK(!base::FeatureList::IsEnabled(features::kPlzDedicatedWorker));
+ const RejectCoepUnsafeNone reject_coep_unsafe_none(
+ parent_coep.value ==
+ network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp);
if (options_->type() == "classic") {
// Legacy code path (to be deprecated, see https://crbug.com/835717):
// A worker thread will start after scripts are fetched on the current
@@ -263,19 +229,20 @@ void DedicatedWorker::Start() {
classic_script_loader_->LoadTopLevelScriptAsynchronously(
*GetExecutionContext(), GetExecutionContext()->Fetcher(),
script_request_url_, mojom::RequestContextType::WORKER,
+ network::mojom::RequestDestination::kWorker,
network::mojom::RequestMode::kSameOrigin,
network::mojom::CredentialsMode::kSameOrigin,
WTF::Bind(&DedicatedWorker::OnResponse, WrapPersistent(this)),
- WTF::Bind(&DedicatedWorker::OnFinished, WrapPersistent(this)));
+ WTF::Bind(&DedicatedWorker::OnFinished, WrapPersistent(this)),
+ reject_coep_unsafe_none, std::move(blob_url_loader_factory));
return;
}
if (options_->type() == "module") {
// Specify empty source code here because scripts will be fetched on the
// worker thread.
- ContinueStart(
- script_request_url_, OffMainThreadWorkerScriptFetchOption::kEnabled,
- network::mojom::ReferrerPolicy::kDefault,
- base::nullopt /* response_address_space */, String() /* source_code */);
+ ContinueStart(script_request_url_, network::mojom::ReferrerPolicy::kDefault,
+ base::nullopt /* response_address_space */,
+ String() /* source_code */, reject_coep_unsafe_none);
return;
}
NOTREACHED() << "Invalid type: " << options_->type();
@@ -292,7 +259,7 @@ BeginFrameProviderParams DedicatedWorker::CreateBeginFrameProviderParams() {
// won't be initialized. If that's the case, the Worker will initialize it by
// itself later.
BeginFrameProviderParams begin_frame_provider_params;
- if (auto* document = DynamicTo<Document>(GetExecutionContext())) {
+ if (auto* document = Document::DynamicFrom(GetExecutionContext())) {
LocalFrame* frame = document->GetFrame();
if (frame) {
WebFrameWidgetBase* widget =
@@ -307,7 +274,7 @@ BeginFrameProviderParams DedicatedWorker::CreateBeginFrameProviderParams() {
return begin_frame_provider_params;
}
-void DedicatedWorker::ContextDestroyed(ExecutionContext*) {
+void DedicatedWorker::ContextDestroyed() {
DCHECK(GetExecutionContext()->IsContextThread());
if (classic_script_loader_)
classic_script_loader_->Cancel();
@@ -335,10 +302,9 @@ void DedicatedWorker::OnScriptLoadStarted() {
DCHECK(base::FeatureList::IsEnabled(features::kPlzDedicatedWorker));
// Specify empty source code here because scripts will be fetched on the
// worker thread.
- ContinueStart(
- script_request_url_, OffMainThreadWorkerScriptFetchOption::kEnabled,
- network::mojom::ReferrerPolicy::kDefault,
- base::nullopt /* response_address_space */, String() /* source_code */);
+ ContinueStart(script_request_url_, network::mojom::ReferrerPolicy::kDefault,
+ base::nullopt /* response_address_space */,
+ String() /* source_code */, RejectCoepUnsafeNone(false));
}
void DedicatedWorker::OnScriptLoadStartFailed() {
@@ -356,7 +322,7 @@ void DedicatedWorker::DispatchErrorEventForScriptFetchFailure() {
std::unique_ptr<WebContentSettingsClient>
DedicatedWorker::CreateWebContentSettingsClient() {
std::unique_ptr<WebContentSettingsClient> content_settings_client;
- if (auto* document = DynamicTo<Document>(GetExecutionContext())) {
+ if (auto* document = Document::DynamicFrom(GetExecutionContext())) {
LocalFrame* frame = document->GetFrame();
return frame->Client()->CreateWorkerContentSettingsClient();
} else if (GetExecutionContext()->IsWorkerGlobalScope()) {
@@ -381,9 +347,6 @@ void DedicatedWorker::OnFinished() {
} else if (classic_script_loader_->Failed()) {
context_proxy_->DidFailToFetchScript();
} else {
- CountTopLevelScriptRequestUrlOriginType(
- *GetExecutionContext()->GetSecurityOrigin(), script_request_url_);
-
network::mojom::ReferrerPolicy referrer_policy =
network::mojom::ReferrerPolicy::kDefault;
if (!classic_script_loader_->GetReferrerPolicy().IsNull()) {
@@ -395,10 +358,10 @@ void DedicatedWorker::OnFinished() {
DCHECK(script_request_url_ == script_response_url ||
SecurityOrigin::AreSameOrigin(script_request_url_,
script_response_url));
- ContinueStart(
- script_response_url, OffMainThreadWorkerScriptFetchOption::kDisabled,
- referrer_policy, classic_script_loader_->ResponseAddressSpace(),
- classic_script_loader_->SourceText());
+ ContinueStart(script_response_url, referrer_policy,
+ classic_script_loader_->ResponseAddressSpace(),
+ classic_script_loader_->SourceText(),
+ RejectCoepUnsafeNone(false));
probe::ScriptImported(GetExecutionContext(),
classic_script_loader_->Identifier(),
classic_script_loader_->SourceText());
@@ -408,34 +371,39 @@ void DedicatedWorker::OnFinished() {
void DedicatedWorker::ContinueStart(
const KURL& script_url,
- OffMainThreadWorkerScriptFetchOption off_main_thread_fetch_option,
network::mojom::ReferrerPolicy referrer_policy,
base::Optional<network::mojom::IPAddressSpace> response_address_space,
- const String& source_code) {
+ const String& source_code,
+ RejectCoepUnsafeNone reject_coep_unsafe_none) {
context_proxy_->StartWorkerGlobalScope(
- CreateGlobalScopeCreationParams(script_url, off_main_thread_fetch_option,
- referrer_policy, response_address_space),
+ CreateGlobalScopeCreationParams(script_url, referrer_policy,
+ response_address_space),
options_, script_url, *outside_fetch_client_settings_object_,
- v8_stack_trace_id_, source_code);
+ v8_stack_trace_id_, source_code, reject_coep_unsafe_none);
}
std::unique_ptr<GlobalScopeCreationParams>
DedicatedWorker::CreateGlobalScopeCreationParams(
const KURL& script_url,
- OffMainThreadWorkerScriptFetchOption off_main_thread_fetch_option,
network::mojom::ReferrerPolicy referrer_policy,
base::Optional<network::mojom::IPAddressSpace> response_address_space) {
base::UnguessableToken parent_devtools_token;
std::unique_ptr<WorkerSettings> settings;
- if (auto* document = DynamicTo<Document>(GetExecutionContext())) {
- if (document->GetFrame())
- parent_devtools_token = document->GetFrame()->GetDevToolsFrameToken();
+ UserAgentMetadata ua_metadata;
+ if (auto* document = Document::DynamicFrom(GetExecutionContext())) {
+ auto* frame = document->GetFrame();
+ if (frame) {
+ parent_devtools_token = frame->GetDevToolsFrameToken();
+ ua_metadata = frame->Loader().UserAgentMetadata().value_or(
+ blink::UserAgentMetadata());
+ }
settings = std::make_unique<WorkerSettings>(document->GetSettings());
} else {
WorkerGlobalScope* worker_global_scope =
To<WorkerGlobalScope>(GetExecutionContext());
parent_devtools_token =
worker_global_scope->GetThread()->GetDevToolsWorkerToken();
+ ua_metadata = worker_global_scope->GetUserAgentMetadata();
settings = WorkerSettings::Copy(worker_global_scope->GetWorkerSettings());
}
@@ -444,8 +412,9 @@ DedicatedWorker::CreateGlobalScopeCreationParams(
: mojom::ScriptType::kModule;
return std::make_unique<GlobalScopeCreationParams>(
- script_url, script_type, off_main_thread_fetch_option, options_->name(),
- GetExecutionContext()->UserAgent(), CreateWebWorkerFetchContext(),
+ script_url, script_type, options_->name(),
+ GetExecutionContext()->UserAgent(), ua_metadata,
+ CreateWebWorkerFetchContext(),
GetExecutionContext()->GetContentSecurityPolicy()->Headers(),
referrer_policy, GetExecutionContext()->GetSecurityOrigin(),
GetExecutionContext()->IsSecureContext(),
@@ -463,7 +432,7 @@ DedicatedWorker::CreateGlobalScopeCreationParams(
scoped_refptr<WebWorkerFetchContext>
DedicatedWorker::CreateWebWorkerFetchContext() {
// This worker is being created by the document.
- if (auto* document = DynamicTo<Document>(GetExecutionContext())) {
+ if (auto* document = Document::DynamicFrom(GetExecutionContext())) {
scoped_refptr<WebWorkerFetchContext> web_worker_fetch_context;
LocalFrame* frame = document->GetFrame();
if (base::FeatureList::IsEnabled(features::kPlzDedicatedWorker)) {
@@ -517,7 +486,7 @@ void DedicatedWorker::ContextLifecycleStateChanged(
}
}
-void DedicatedWorker::Trace(blink::Visitor* visitor) {
+void DedicatedWorker::Trace(Visitor* visitor) {
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 c5680c3edf2..2f5e6109697 100644
--- a/chromium/third_party/blink/renderer/core/workers/dedicated_worker.h
+++ b/chromium/third_party/blink/renderer/core/workers/dedicated_worker.h
@@ -8,17 +8,18 @@
#include <memory>
#include "base/memory/scoped_refptr.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "services/network/public/mojom/url_loader_factory.mojom-blink.h"
#include "third_party/blink/public/mojom/browser_interface_broker.mojom-blink-forward.h"
#include "third_party/blink/public/platform/web_dedicated_worker.h"
#include "third_party/blink/public/platform/web_dedicated_worker_host_factory_client.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_worker_options.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/events/event_listener.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/messaging/message_port.h"
#include "third_party/blink/renderer/core/workers/abstract_worker.h"
#include "third_party/blink/renderer/core/workers/global_scope_creation_params.h"
-#include "third_party/blink/renderer/core/workers/worker_options.h"
#include "third_party/blink/renderer/platform/graphics/begin_frame_provider.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -75,8 +76,8 @@ class CORE_EXPORT DedicatedWorker final
void terminate();
BeginFrameProviderParams CreateBeginFrameProviderParams();
- // Implements ContextLifecycleObserver (via AbstractWorker).
- void ContextDestroyed(ExecutionContext*) override;
+ // Implements ExecutionContextLifecycleObserver (via AbstractWorker).
+ void ContextDestroyed() override;
// Implements ScriptWrappable
// (via AbstractWorker -> EventTargetWithInlineData -> EventTarget).
@@ -94,26 +95,30 @@ class CORE_EXPORT DedicatedWorker final
DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage)
void ContextLifecycleStateChanged(mojom::FrameLifecycleState state) override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
// Starts the worker.
void Start();
void ContinueStart(
const KURL& script_url,
- OffMainThreadWorkerScriptFetchOption,
network::mojom::ReferrerPolicy,
base::Optional<network::mojom::IPAddressSpace> response_address_space,
- const String& source_code);
+ const String& source_code,
+ RejectCoepUnsafeNone reject_coep_unsafe_none);
std::unique_ptr<GlobalScopeCreationParams> CreateGlobalScopeCreationParams(
const KURL& script_url,
- OffMainThreadWorkerScriptFetchOption,
network::mojom::ReferrerPolicy,
base::Optional<network::mojom::IPAddressSpace> response_address_space);
scoped_refptr<WebWorkerFetchContext> CreateWebWorkerFetchContext();
// May return nullptr.
std::unique_ptr<WebContentSettingsClient> CreateWebContentSettingsClient();
+ void OnHostCreated(
+ mojo::PendingRemote<network::mojom::blink::URLLoaderFactory>
+ blob_url_loader_factory,
+ const network::CrossOriginEmbedderPolicy& parent_coep);
+
// Callbacks for |classic_script_loader_|.
void OnResponse();
void OnFinished();
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 a0fafea19ea..d57ebc459c9 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
@@ -36,12 +36,13 @@
#include "third_party/blink/public/mojom/appcache/appcache.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_post_message_options.h"
#include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h"
#include "third_party/blink/renderer/core/core_initializer.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/worker_thread_debugger.h"
-#include "third_party/blink/renderer/core/messaging/post_message_options.h"
+#include "third_party/blink/renderer/core/messaging/blink_transferable_message.h"
#include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.h"
@@ -67,35 +68,34 @@ DedicatedWorkerGlobalScope* DedicatedWorkerGlobalScope::Create(
BeginFrameProviderParams begin_frame_provider_params =
creation_params->begin_frame_provider_params;
- // Off-the-main-thread worker script fetch:
- // Initialize() is called after script fetch.
- if (creation_params->off_main_thread_fetch_option ==
- OffMainThreadWorkerScriptFetchOption::kEnabled) {
- return MakeGarbageCollected<DedicatedWorkerGlobalScope>(
- std::move(creation_params), thread, time_origin,
- std::move(outside_origin_trial_tokens), begin_frame_provider_params);
- }
-
- // Legacy on-the-main-thread worker script fetch (to be removed):
KURL response_script_url = creation_params->script_url;
network::mojom::ReferrerPolicy response_referrer_policy =
creation_params->referrer_policy;
- network::mojom::IPAddressSpace response_address_space =
- *creation_params->response_address_space;
+ base::Optional<network::mojom::IPAddressSpace> response_address_space =
+ creation_params->response_address_space;
+
auto* global_scope = MakeGarbageCollected<DedicatedWorkerGlobalScope>(
std::move(creation_params), thread, time_origin,
std::move(outside_origin_trial_tokens), begin_frame_provider_params);
- // Pass dummy CSP headers here as it is superseded by outside's CSP headers in
- // Initialize().
- // Pass dummy origin trial tokens here as it is already set to outside's
- // origin trial tokens in DedicatedWorkerGlobalScope's constructor.
- // Pass kAppCacheNoCacheId here as on-the-main-thread script fetch doesn't
- // have its own appcache and instead depends on the parent frame's one.
- global_scope->Initialize(response_script_url, response_referrer_policy,
- response_address_space, Vector<CSPHeaderAndType>(),
- nullptr /* response_origin_trial_tokens */,
- mojom::blink::kAppCacheNoCacheId);
- return global_scope;
+
+ if (global_scope->IsOffMainThreadScriptFetchDisabled()) {
+ // Legacy on-the-main-thread worker script fetch (to be removed):
+ // Pass dummy CSP headers here as it is superseded by outside's CSP headers
+ // in Initialize().
+ // Pass dummy origin trial tokens here as it is already set to outside's
+ // origin trial tokens in DedicatedWorkerGlobalScope's constructor.
+ // Pass kAppCacheNoCacheId here as on-the-main-thread script fetch doesn't
+ // have its own appcache and instead depends on the parent frame's one.
+ global_scope->Initialize(
+ response_script_url, response_referrer_policy, *response_address_space,
+ Vector<CSPHeaderAndType>(), nullptr /* response_origin_trial_tokens */,
+ mojom::blink::kAppCacheNoCacheId);
+ return global_scope;
+ } else {
+ // Off-the-main-thread worker script fetch:
+ // Initialize() is called after script fetch.
+ return global_scope;
+ }
}
DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope(
@@ -143,7 +143,7 @@ void DedicatedWorkerGlobalScope::Initialize(
SetReferrerPolicy(response_referrer_policy);
// https://wicg.github.io/cors-rfc1918/#integration-html
- SetAddressSpace(response_address_space);
+ GetSecurityContext().SetAddressSpace(response_address_space);
// Step 12.6. "Execute the Initialize a global object's CSP list algorithm
// on worker global scope and response. [CSP]"
@@ -175,7 +175,9 @@ void DedicatedWorkerGlobalScope::FetchAndRunClassicScript(
// Step 12. "Fetch a classic worker script given url, outside settings,
// destination, and inside settings."
- auto destination = mojom::RequestContextType::WORKER;
+ mojom::RequestContextType context_type = mojom::RequestContextType::WORKER;
+ network::mojom::RequestDestination destination =
+ network::mojom::RequestDestination::kWorker;
// Step 12.1. "Set request's reserved client to inside settings."
// The browesr process takes care of this.
@@ -188,7 +190,8 @@ void DedicatedWorkerGlobalScope::FetchAndRunClassicScript(
*this,
CreateOutsideSettingsFetcher(outside_settings_object,
outside_resource_timing_notifier),
- script_url, destination, network::mojom::RequestMode::kSameOrigin,
+ script_url, context_type, destination,
+ network::mojom::RequestMode::kSameOrigin,
network::mojom::CredentialsMode::kSameOrigin,
WTF::Bind(&DedicatedWorkerGlobalScope::DidReceiveResponseForClassicScript,
WrapWeakPersistent(this),
@@ -203,22 +206,36 @@ void DedicatedWorkerGlobalScope::FetchAndRunModuleScript(
const KURL& module_url_record,
const FetchClientSettingsObjectSnapshot& outside_settings_object,
WorkerResourceTimingNotifier& outside_resource_timing_notifier,
- network::mojom::CredentialsMode credentials_mode) {
+ network::mojom::CredentialsMode credentials_mode,
+ RejectCoepUnsafeNone reject_coep_unsafe_none) {
+ reject_coep_unsafe_none_ = reject_coep_unsafe_none;
// Step 12: "Let destination be "sharedworker" if is shared is true, and
// "worker" otherwise."
- mojom::RequestContextType destination = mojom::RequestContextType::WORKER;
+ mojom::RequestContextType context_type = mojom::RequestContextType::WORKER;
+ network::mojom::RequestDestination destination =
+ network::mojom::RequestDestination::kWorker;
// Step 13: "... Fetch a module worker script graph given url, outside
// settings, destination, the value of the credentials member of options, and
// inside settings."
FetchModuleScript(module_url_record, outside_settings_object,
- outside_resource_timing_notifier, destination,
+ outside_resource_timing_notifier, context_type, destination,
credentials_mode,
ModuleScriptCustomFetchType::kWorkerConstructor,
MakeGarbageCollected<WorkerModuleTreeClient>(
ScriptController()->GetScriptState()));
}
+bool DedicatedWorkerGlobalScope::IsOffMainThreadScriptFetchDisabled() {
+ // The top-level dedicated worker script is loaded on the main thread when the
+ // script type is classic and PlzDedicatedWorker (off-the-main-thread script
+ // fetch) is disabled.
+ // TODO(https://crbug.com/835717): Remove this function after dedicated
+ // workers support off-the-main-thread script fetch by default.
+ return GetScriptType() == mojom::blink::ScriptType::kClassic &&
+ !base::FeatureList::IsEnabled(features::kPlzDedicatedWorker);
+}
+
const String DedicatedWorkerGlobalScope::name() const {
return Name();
}
@@ -350,7 +367,7 @@ DedicatedWorkerObjectProxy& DedicatedWorkerGlobalScope::WorkerObjectProxy()
return static_cast<DedicatedWorkerThread*>(GetThread())->WorkerObjectProxy();
}
-void DedicatedWorkerGlobalScope::Trace(blink::Visitor* visitor) {
+void DedicatedWorkerGlobalScope::Trace(Visitor* visitor) {
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 c75483c4874..eda1c4f4ee7 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
@@ -100,7 +100,9 @@ class CORE_EXPORT DedicatedWorkerGlobalScope final : public WorkerGlobalScope {
const KURL& module_url_record,
const FetchClientSettingsObjectSnapshot& outside_settings_object,
WorkerResourceTimingNotifier& outside_resource_timing_notifier,
- network::mojom::CredentialsMode) override;
+ network::mojom::CredentialsMode,
+ RejectCoepUnsafeNone reject_coep_unsafe_none) override;
+ bool IsOffMainThreadScriptFetchDisabled() override;
// Called by the bindings (dedicated_worker_global_scope.idl).
const String name() const;
@@ -115,8 +117,13 @@ class CORE_EXPORT DedicatedWorkerGlobalScope final : public WorkerGlobalScope {
DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage)
DEFINE_ATTRIBUTE_EVENT_LISTENER(messageerror, kMessageerror)
+ RejectCoepUnsafeNone ShouldRejectCoepUnsafeNoneTopModuleScript()
+ const override {
+ return reject_coep_unsafe_none_;
+ }
+
// Called by the Oilpan.
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void DidReceiveResponseForClassicScript(
@@ -127,6 +134,7 @@ class CORE_EXPORT DedicatedWorkerGlobalScope final : public WorkerGlobalScope {
DedicatedWorkerObjectProxy& WorkerObjectProxy() const;
Member<WorkerAnimationFrameProvider> animation_frame_provider_;
+ RejectCoepUnsafeNone reject_coep_unsafe_none_ = RejectCoepUnsafeNone(false);
};
template <>
diff --git a/chromium/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.idl b/chromium/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.idl
index 034a5e4790b..aa7f68f24da 100644
--- a/chromium/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.idl
+++ b/chromium/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.idl
@@ -37,7 +37,7 @@
[Replaceable] readonly attribute DOMString name;
[CallWith=ScriptState, RaisesException] void postMessage(any message, sequence<object> transfer);
- [CallWith=ScriptState, RaisesException] void postMessage(any message, optional PostMessageOptions options);
+ [CallWith=ScriptState, RaisesException] void postMessage(any message, optional PostMessageOptions options = {});
void close();
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 665e741fdb7..448d1a2c71c 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
@@ -5,10 +5,14 @@
#include "third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.h"
#include <memory>
+#include "base/feature_list.h"
+#include "base/optional.h"
#include "services/network/public/mojom/fetch_api.mojom-blink.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/sanitize_script_errors.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_cache_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_worker_options.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/events/error_event.h"
#include "third_party/blink/renderer/core/events/message_event.h"
@@ -20,7 +24,6 @@
#include "third_party/blink/renderer/core/workers/dedicated_worker.h"
#include "third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.h"
#include "third_party/blink/renderer/core/workers/dedicated_worker_thread.h"
-#include "third_party/blink/renderer/core/workers/worker_options.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/wtf.h"
@@ -44,7 +47,8 @@ void DedicatedWorkerMessagingProxy::StartWorkerGlobalScope(
const KURL& script_url,
const FetchClientSettingsObjectSnapshot& outside_settings_object,
const v8_inspector::V8StackTraceId& stack_id,
- const String& source_code) {
+ const String& source_code,
+ RejectCoepUnsafeNone reject_coep_unsafe_none) {
DCHECK(IsParentContextThread());
if (AskedToTerminate()) {
// Worker.terminate() could be called from JS before the thread was
@@ -52,9 +56,6 @@ void DedicatedWorkerMessagingProxy::StartWorkerGlobalScope(
return;
}
- OffMainThreadWorkerScriptFetchOption off_main_thread_fetch_option =
- creation_params->off_main_thread_fetch_option;
-
InitializeWorkerThread(
std::move(creation_params),
CreateBackingThreadStartupData(GetExecutionContext()->GetIsolate()));
@@ -66,40 +67,34 @@ void DedicatedWorkerMessagingProxy::StartWorkerGlobalScope(
// destination, and inside settings."
UseCounter::Count(GetExecutionContext(),
WebFeature::kClassicDedicatedWorker);
- switch (off_main_thread_fetch_option) {
- case OffMainThreadWorkerScriptFetchOption::kEnabled: {
- auto* resource_timing_notifier =
- WorkerResourceTimingNotifierImpl::CreateForOutsideResourceFetcher(
- *GetExecutionContext());
- GetWorkerThread()->FetchAndRunClassicScript(
- script_url, outside_settings_object.CopyData(),
- resource_timing_notifier, stack_id);
- break;
- }
- case OffMainThreadWorkerScriptFetchOption::kDisabled:
- // Legacy code path (to be deprecated, see https://crbug.com/835717):
- GetWorkerThread()->EvaluateClassicScript(
- script_url, source_code, nullptr /* cached_meta_data */, stack_id);
- break;
+ if (base::FeatureList::IsEnabled(features::kPlzDedicatedWorker)) {
+ auto* resource_timing_notifier =
+ WorkerResourceTimingNotifierImpl::CreateForOutsideResourceFetcher(
+ *GetExecutionContext());
+ GetWorkerThread()->FetchAndRunClassicScript(
+ script_url, outside_settings_object.CopyData(),
+ resource_timing_notifier, stack_id);
+ } else {
+ // Legacy code path (to be deprecated, see https://crbug.com/835717):
+ GetWorkerThread()->EvaluateClassicScript(
+ script_url, source_code, nullptr /* cached_meta_data */, stack_id);
}
} else if (options->type() == "module") {
- DCHECK_EQ(off_main_thread_fetch_option,
- OffMainThreadWorkerScriptFetchOption::kEnabled);
// "module: Fetch a module worker script graph given url, outside settings,
// destination, the value of the credentials member of options, and inside
// settings."
UseCounter::Count(GetExecutionContext(),
WebFeature::kModuleDedicatedWorker);
- network::mojom::CredentialsMode credentials_mode;
- bool result = Request::ParseCredentialsMode(options->credentials(),
- &credentials_mode);
- DCHECK(result);
+ base::Optional<network::mojom::CredentialsMode> credentials_mode =
+ Request::ParseCredentialsMode(options->credentials());
+ DCHECK(credentials_mode);
+
auto* resource_timing_notifier =
WorkerResourceTimingNotifierImpl::CreateForOutsideResourceFetcher(
*GetExecutionContext());
GetWorkerThread()->FetchAndRunModuleScript(
script_url, outside_settings_object.CopyData(),
- resource_timing_notifier, credentials_mode);
+ resource_timing_notifier, *credentials_mode, reject_coep_unsafe_none);
} else {
NOTREACHED();
}
@@ -237,7 +232,7 @@ void DedicatedWorkerMessagingProxy::DispatchErrorEvent(
GetExecutionContext()->DispatchErrorEvent(event, mute_script_errors);
}
-void DedicatedWorkerMessagingProxy::Trace(blink::Visitor* visitor) {
+void DedicatedWorkerMessagingProxy::Trace(Visitor* visitor) {
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 c43b26d59c8..dad2f2ab86a 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
@@ -41,7 +41,8 @@ class CORE_EXPORT DedicatedWorkerMessagingProxy
const KURL& script_url,
const FetchClientSettingsObjectSnapshot& outside_settings_object,
const v8_inspector::V8StackTraceId&,
- const String& source_code);
+ const String& source_code,
+ RejectCoepUnsafeNone reject_coep_unsafe_none);
void PostMessageToWorkerGlobalScope(BlinkTransferableMessage);
bool HasPendingActivity() const;
@@ -66,7 +67,7 @@ class CORE_EXPORT DedicatedWorkerMessagingProxy
return *worker_object_proxy_.get();
}
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
friend class DedicatedWorkerMessagingProxyForTest;
diff --git a/chromium/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.cc b/chromium/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.cc
index 7f30a4732f4..9c7311816f4 100644
--- a/chromium/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.cc
+++ b/chromium/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.cc
@@ -43,6 +43,7 @@
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/user_activation.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
+#include "third_party/blink/renderer/core/messaging/blink_transferable_message.h"
#include "third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.h"
#include "third_party/blink/renderer/core/workers/parent_execution_context_task_runners.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
diff --git a/chromium/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.h b/chromium/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.h
index 39eb28cbcae..93485ba1a54 100644
--- a/chromium/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.h
+++ b/chromium/third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.h
@@ -35,7 +35,6 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/messaging/blink_transferable_message.h"
#include "third_party/blink/renderer/core/messaging/message_port.h"
#include "third_party/blink/renderer/core/workers/threaded_object_proxy_base.h"
#include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h"
@@ -43,6 +42,7 @@
namespace blink {
+struct BlinkTransferableMessage;
class DedicatedWorkerMessagingProxy;
class ParentExecutionContextTaskRunners;
class ThreadedMessagingProxyBase;
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 9cf493ac246..f505b02d1c2 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
@@ -125,14 +125,14 @@ class DedicatedWorkerMessagingProxyForTest
KURL script_url("http://fake.url/");
security_origin_ = SecurityOrigin::Create(script_url);
Vector<CSPHeaderAndType> headers{
- {"contentSecurityPolicy", kContentSecurityPolicyHeaderTypeReport}};
+ {"contentSecurityPolicy",
+ network::mojom::ContentSecurityPolicyType::kReport}};
auto worker_settings = std::make_unique<WorkerSettings>(
- To<Document>(GetExecutionContext())->GetSettings());
+ Document::From(GetExecutionContext())->GetSettings());
InitializeWorkerThread(
std::make_unique<GlobalScopeCreationParams>(
- script_url, mojom::ScriptType::kClassic,
- OffMainThreadWorkerScriptFetchOption::kDisabled,
- "fake global scope name", "fake user agent",
+ script_url, mojom::ScriptType::kClassic, "fake global scope name",
+ "fake user agent", UserAgentMetadata(),
nullptr /* web_worker_fetch_context */, headers,
network::mojom::ReferrerPolicy::kDefault, security_origin_.get(),
false /* starter_secure_context */,
@@ -154,7 +154,7 @@ class DedicatedWorkerMessagingProxyForTest
return static_cast<DedicatedWorkerThreadForTest*>(GetWorkerThread());
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
DedicatedWorkerMessagingProxy::Trace(visitor);
}
@@ -175,7 +175,7 @@ class DedicatedWorkerTest : public PageTestBase {
PageTestBase::SetUp(IntSize());
worker_messaging_proxy_ =
MakeGarbageCollected<DedicatedWorkerMessagingProxyForTest>(
- &GetDocument());
+ GetDocument().ToExecutionContext());
}
void TearDown() override {
diff --git a/chromium/third_party/blink/renderer/core/workers/global_scope_creation_params.cc b/chromium/third_party/blink/renderer/core/workers/global_scope_creation_params.cc
index 7635d07b0c9..8b1e05f9cd5 100644
--- a/chromium/third_party/blink/renderer/core/workers/global_scope_creation_params.cc
+++ b/chromium/third_party/blink/renderer/core/workers/global_scope_creation_params.cc
@@ -16,9 +16,9 @@ namespace blink {
GlobalScopeCreationParams::GlobalScopeCreationParams(
const KURL& script_url,
mojom::ScriptType script_type,
- OffMainThreadWorkerScriptFetchOption off_main_thread_fetch_option,
const String& global_scope_name,
const String& user_agent,
+ const base::Optional<UserAgentMetadata>& ua_metadata,
scoped_refptr<WebWorkerFetchContext> web_worker_fetch_context,
const Vector<CSPHeaderAndType>& outside_content_security_policy_headers,
network::mojom::ReferrerPolicy referrer_policy,
@@ -40,9 +40,9 @@ GlobalScopeCreationParams::GlobalScopeCreationParams(
base::UnguessableToken agent_cluster_id)
: script_url(script_url.Copy()),
script_type(script_type),
- off_main_thread_fetch_option(off_main_thread_fetch_option),
global_scope_name(global_scope_name.IsolatedCopy()),
user_agent(user_agent.IsolatedCopy()),
+ ua_metadata(ua_metadata.value_or(blink::UserAgentMetadata())),
web_worker_fetch_context(std::move(web_worker_fetch_context)),
referrer_policy(referrer_policy),
starter_origin(starter_origin ? starter_origin->IsolatedCopy() : nullptr),
@@ -64,15 +64,6 @@ GlobalScopeCreationParams::GlobalScopeCreationParams(
ParsedFeaturePolicy() /* container_policy */,
starter_origin->ToUrlOrigin())),
agent_cluster_id(agent_cluster_id) {
- switch (this->script_type) {
- case mojom::ScriptType::kClassic:
- break;
- case mojom::ScriptType::kModule:
- DCHECK_EQ(this->off_main_thread_fetch_option,
- OffMainThreadWorkerScriptFetchOption::kEnabled);
- break;
- }
-
this->outside_content_security_policy_headers.ReserveInitialCapacity(
outside_content_security_policy_headers.size());
for (const auto& header : outside_content_security_policy_headers) {
diff --git a/chromium/third_party/blink/renderer/core/workers/global_scope_creation_params.h b/chromium/third_party/blink/renderer/core/workers/global_scope_creation_params.h
index bd99d935332..164a1f117a5 100644
--- a/chromium/third_party/blink/renderer/core/workers/global_scope_creation_params.h
+++ b/chromium/third_party/blink/renderer/core/workers/global_scope_creation_params.h
@@ -13,6 +13,7 @@
#include "services/network/public/mojom/ip_address_space.mojom-blink-forward.h"
#include "services/network/public/mojom/referrer_policy.mojom-blink-forward.h"
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
+#include "third_party/blink/public/common/user_agent/user_agent_metadata.h"
#include "third_party/blink/public/mojom/browser_interface_broker.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/script/script_type.mojom-blink-forward.h"
#include "third_party/blink/public/platform/web_content_settings_client.h"
@@ -32,10 +33,6 @@ namespace blink {
class WorkerClients;
-// TODO(nhiroki): Remove this option after off-the-main-thread worker script
-// fetch is enabled for all worker types (https://crbug.com/835717).
-enum class OffMainThreadWorkerScriptFetchOption { kDisabled, kEnabled };
-
// GlobalScopeCreationParams contains parameters for initializing
// WorkerGlobalScope or WorkletGlobalScope.
struct CORE_EXPORT GlobalScopeCreationParams final {
@@ -45,9 +42,9 @@ struct CORE_EXPORT GlobalScopeCreationParams final {
GlobalScopeCreationParams(
const KURL& script_url,
mojom::ScriptType script_type,
- OffMainThreadWorkerScriptFetchOption,
const String& global_scope_name,
const String& user_agent,
+ const base::Optional<UserAgentMetadata>& ua_metadata,
scoped_refptr<WebWorkerFetchContext>,
const Vector<CSPHeaderAndType>& outside_content_security_policy_headers,
network::mojom::ReferrerPolicy referrer_policy,
@@ -85,10 +82,10 @@ struct CORE_EXPORT GlobalScopeCreationParams final {
KURL script_url;
mojom::ScriptType script_type;
- OffMainThreadWorkerScriptFetchOption off_main_thread_fetch_option;
String global_scope_name;
String user_agent;
+ UserAgentMetadata ua_metadata;
scoped_refptr<WebWorkerFetchContext> web_worker_fetch_context;
diff --git a/chromium/third_party/blink/renderer/core/workers/installed_scripts_manager.cc b/chromium/third_party/blink/renderer/core/workers/installed_scripts_manager.cc
index 39256203da2..c63721e4a30 100644
--- a/chromium/third_party/blink/renderer/core/workers/installed_scripts_manager.cc
+++ b/chromium/third_party/blink/renderer/core/workers/installed_scripts_manager.cc
@@ -47,6 +47,10 @@ String InstalledScriptsManager::ScriptData::GetReferrerPolicy() {
return headers_.Get(http_names::kReferrerPolicy);
}
+String InstalledScriptsManager::ScriptData::GetHttpContentType() {
+ return headers_.Get(http_names::kContentType);
+}
+
std::unique_ptr<Vector<String>>
InstalledScriptsManager::ScriptData::CreateOriginTrialTokens() {
return OriginTrialContext::ParseHeaderValue(
diff --git a/chromium/third_party/blink/renderer/core/workers/installed_scripts_manager.h b/chromium/third_party/blink/renderer/core/workers/installed_scripts_manager.h
index bdb32e3d1c6..5d27f5521fe 100644
--- a/chromium/third_party/blink/renderer/core/workers/installed_scripts_manager.h
+++ b/chromium/third_party/blink/renderer/core/workers/installed_scripts_manager.h
@@ -44,6 +44,7 @@ class InstalledScriptsManager {
ContentSecurityPolicyResponseHeaders
GetContentSecurityPolicyResponseHeaders();
String GetReferrerPolicy();
+ String GetHttpContentType();
network::mojom::IPAddressSpace GetResponseAddressSpace() const {
return response_address_space_;
}
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 3a0646bd213..02ea3808611 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
@@ -57,21 +57,24 @@ class MainThreadWorkletTest : public PageTestBase {
// Set up the CSP for Document before starting MainThreadWorklet because
// MainThreadWorklet inherits the owner Document's CSP.
auto* csp = MakeGarbageCollected<ContentSecurityPolicy>();
- csp->DidReceiveHeader(csp_header, kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ csp->DidReceiveHeader(csp_header,
+ network::mojom::ContentSecurityPolicyType::kEnforce,
+ network::mojom::ContentSecurityPolicySource::kHTTP);
document->InitContentSecurityPolicy(csp);
reporting_proxy_ =
std::make_unique<MainThreadWorkletReportingProxyForTest>(document);
auto creation_params = std::make_unique<GlobalScopeCreationParams>(
- document->Url(), mojom::ScriptType::kModule,
- OffMainThreadWorkerScriptFetchOption::kEnabled, "MainThreadWorklet",
- document->UserAgent(), nullptr /* web_worker_fetch_context */,
+ document->Url(), mojom::ScriptType::kModule, "MainThreadWorklet",
+ document->UserAgent(),
+ document->GetFrame()->Loader().UserAgentMetadata(),
+ nullptr /* web_worker_fetch_context */,
document->GetContentSecurityPolicy()->Headers(),
document->GetReferrerPolicy(), document->GetSecurityOrigin(),
document->IsSecureContext(), document->GetHttpsState(),
nullptr /* worker_clients */, nullptr /* content_settings_client */,
- document->AddressSpace(), OriginTrialContext::GetTokens(document).get(),
+ document->GetSecurityContext().AddressSpace(),
+ OriginTrialContext::GetTokens(document->ToExecutionContext()).get(),
base::UnguessableToken::Create(), nullptr /* worker_settings */,
kV8CacheOptionsDefault,
MakeGarbageCollected<WorkletModuleResponsesMap>());
@@ -160,7 +163,7 @@ TEST_F(MainThreadWorkletInvalidCSPTest, InvalidContentSecurityPolicy) {
// At this point check that the CSP that was set is indeed invalid.
EXPECT_EQ(1ul, csp->Headers().size());
EXPECT_EQ("invalid-csp", csp->Headers().at(0).first);
- EXPECT_EQ(kContentSecurityPolicyHeaderTypeEnforce,
+ EXPECT_EQ(network::mojom::ContentSecurityPolicyType::kEnforce,
csp->Headers().at(0).second);
}
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 2c7024a4eea..ac1fc8b5900 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
@@ -26,7 +26,7 @@ ParentExecutionContextTaskRunners* ParentExecutionContextTaskRunners::Create() {
ParentExecutionContextTaskRunners::ParentExecutionContextTaskRunners(
ExecutionContext* context)
- : ContextLifecycleObserver(context) {
+ : ExecutionContextLifecycleObserver(context) {
// For now we only support very limited task types. Sort in the TaskType enum
// value order.
for (auto type : {TaskType::kNetworking, TaskType::kPostedMessage,
@@ -45,11 +45,11 @@ ParentExecutionContextTaskRunners::Get(TaskType type) {
return task_runners_.at(type);
}
-void ParentExecutionContextTaskRunners::Trace(blink::Visitor* visitor) {
- ContextLifecycleObserver::Trace(visitor);
+void ParentExecutionContextTaskRunners::Trace(Visitor* visitor) {
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
-void ParentExecutionContextTaskRunners::ContextDestroyed(ExecutionContext*) {
+void ParentExecutionContextTaskRunners::ContextDestroyed() {
MutexLocker lock(mutex_);
for (auto& entry : task_runners_)
entry.value = Thread::Current()->GetTaskRunner();
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 eab3581aa94..0a910eabebd 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
@@ -11,7 +11,7 @@
#include "base/thread_annotations.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/task_type_traits.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -21,7 +21,7 @@ namespace blink {
// task runners for the current thread if no execution context is available.
class CORE_EXPORT ParentExecutionContextTaskRunners final
: public GarbageCollected<ParentExecutionContextTaskRunners>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(ParentExecutionContextTaskRunners);
public:
@@ -44,7 +44,7 @@ class CORE_EXPORT ParentExecutionContextTaskRunners final
scoped_refptr<base::SingleThreadTaskRunner> Get(TaskType)
LOCKS_EXCLUDED(mutex_);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
using TaskRunnerHashMap = HashMap<TaskType,
@@ -52,7 +52,7 @@ class CORE_EXPORT ParentExecutionContextTaskRunners final
WTF::IntHash<TaskType>,
TaskTypeTraits>;
- void ContextDestroyed(ExecutionContext*) LOCKS_EXCLUDED(mutex_) override;
+ void ContextDestroyed() LOCKS_EXCLUDED(mutex_) override;
Mutex mutex_;
TaskRunnerHashMap task_runners_ GUARDED_BY(mutex_);
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 9b69f968620..87f09b78782 100644
--- a/chromium/third_party/blink/renderer/core/workers/shared_worker.cc
+++ b/chromium/third_party/blink/renderer/core/workers/shared_worker.cc
@@ -31,14 +31,19 @@
#include "third_party/blink/renderer/core/workers/shared_worker.h"
+#include "base/optional.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "third_party/blink/public/common/blob/blob_utils.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
+#include "third_party/blink/public/mojom/worker/shared_worker_info.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_worker_options.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/fetch/request.h"
#include "third_party/blink/renderer/core/fileapi/public_url_manager.h"
#include "third_party/blink/renderer/core/messaging/message_channel.h"
#include "third_party/blink/renderer/core/messaging/message_port.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
+#include "third_party/blink/renderer/core/script/script.h"
#include "third_party/blink/renderer/core/workers/shared_worker_client_holder.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
@@ -52,14 +57,8 @@ namespace {
void RecordSharedWorkerUsage(Document* document) {
UseCounter::Count(document, WebFeature::kSharedWorkerStart);
- // Don't record the use counter if the frame is same-origin to the top frame,
- // or if we can't tell whether the frame was ever cross-origin or not.
- if (!document->TopFrameOrigin() ||
- document->TopFrameOrigin()->CanAccess(document->GetSecurityOrigin())) {
- return;
- }
-
- UseCounter::Count(document, WebFeature::kThirdPartySharedWorker);
+ if (document->IsCrossSiteSubframe())
+ UseCounter::Count(document, WebFeature::kThirdPartySharedWorker);
}
} // namespace
@@ -73,13 +72,13 @@ SharedWorker::SharedWorker(ExecutionContext* context)
SharedWorker* SharedWorker::Create(ExecutionContext* context,
const String& url,
- const String& name,
+ const StringOrWorkerOptions& name_or_options,
ExceptionState& exception_state) {
DCHECK(IsMainThread());
// We don't currently support nested workers, so workers can only be created
// from documents.
- Document* document = To<Document>(context);
+ Document* document = Document::From(context);
DCHECK(document);
RecordSharedWorkerUsage(document);
@@ -111,18 +110,39 @@ SharedWorker* SharedWorker::Create(ExecutionContext* context,
script_url, blob_url_token.InitWithNewPipeAndPassReceiver());
}
- // |name| should not be null according to the HTML spec, but the current impl
- // wrongly allows it when |name| is omitted. See TODO comment in
- // shared_worker.idl.
- // TODO(nhiroki): Stop assigning null to |name| as a default value, and remove
- // this hack.
- String worker_name = "";
- if (!name.IsNull())
- worker_name = name;
+ auto options = mojom::blink::WorkerOptions::New();
+ if (name_or_options.IsString()) {
+ options->name = name_or_options.GetAsString();
+ } else if (name_or_options.IsWorkerOptions()) {
+ WorkerOptions* worker_options = name_or_options.GetAsWorkerOptions();
+ if (worker_options->type() == "module" &&
+ !RuntimeEnabledFeatures::ModuleSharedWorkerEnabled()) {
+ exception_state.ThrowTypeError(
+ "Module scripts are not supported on SharedWorker yet. "
+ "(see https://crbug.com/824646)");
+ return nullptr;
+ }
+ options->name = worker_options->name();
+ base::Optional<mojom::ScriptType> type_result =
+ Script::ParseScriptType(worker_options->type());
+ DCHECK(type_result);
+ options->type = type_result.value();
+ base::Optional<network::mojom::CredentialsMode> credentials_result =
+ Request::ParseCredentialsMode(worker_options->credentials());
+ DCHECK(credentials_result);
+ options->credentials = credentials_result.value();
+ } else {
+ NOTREACHED();
+ }
+ DCHECK(!options->name.IsNull());
+ if (options->type == mojom::blink::ScriptType::kClassic)
+ UseCounter::Count(document, WebFeature::kClassicSharedWorker);
+ else if (options->type == mojom::blink::ScriptType::kModule)
+ UseCounter::Count(document, WebFeature::kModuleSharedWorker);
SharedWorkerClientHolder::From(*document)->Connect(
worker, std::move(remote_port), script_url, std::move(blob_url_token),
- worker_name);
+ std::move(options));
return worker;
}
@@ -140,7 +160,7 @@ bool SharedWorker::HasPendingActivity() const {
void SharedWorker::ContextLifecycleStateChanged(
mojom::FrameLifecycleState state) {}
-void SharedWorker::Trace(blink::Visitor* visitor) {
+void SharedWorker::Trace(Visitor* visitor) {
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 75d750959d2..4b3c3433978 100644
--- a/chromium/third_party/blink/renderer/core/workers/shared_worker.h
+++ b/chromium/third_party/blink/renderer/core/workers/shared_worker.h
@@ -33,6 +33,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_WORKERS_SHARED_WORKER_H_
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
+#include "third_party/blink/renderer/bindings/core/v8/string_or_worker_options.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/workers/abstract_worker.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -53,7 +54,7 @@ class CORE_EXPORT SharedWorker final
public:
static SharedWorker* Create(ExecutionContext*,
const String& url,
- const String& name,
+ const StringOrWorkerOptions&,
ExceptionState&);
explicit SharedWorker(ExecutionContext*);
@@ -69,7 +70,7 @@ class CORE_EXPORT SharedWorker final
bool HasPendingActivity() const final;
void ContextLifecycleStateChanged(mojom::FrameLifecycleState state) override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<MessagePort> port_;
diff --git a/chromium/third_party/blink/renderer/core/workers/shared_worker.idl b/chromium/third_party/blink/renderer/core/workers/shared_worker.idl
index 74008ed7735..36051236e4b 100644
--- a/chromium/third_party/blink/renderer/core/workers/shared_worker.idl
+++ b/chromium/third_party/blink/renderer/core/workers/shared_worker.idl
@@ -33,14 +33,10 @@
[
ActiveScriptWrappable,
- // TODO(nhiroki): The second argument should be |optional (DOMString or
- // WorkerOptions) options)|.
- Constructor(DOMString scriptURL, optional DOMString name = null),
- ConstructorCallWith=ExecutionContext,
// TODO(foolip): Exposed=(Window,Worker),
- RaisesException=Constructor,
RuntimeEnabled=SharedWorker
] interface SharedWorker : EventTarget {
+ [CallWith=ExecutionContext, RaisesException] constructor(ScriptURLString scriptURL, optional (DOMString or WorkerOptions) options = {});
readonly attribute MessagePort port;
};
diff --git a/chromium/third_party/blink/renderer/core/workers/shared_worker_client.cc b/chromium/third_party/blink/renderer/core/workers/shared_worker_client.cc
index 5ee80a7a11a..77f05a17e2f 100644
--- a/chromium/third_party/blink/renderer/core/workers/shared_worker_client.cc
+++ b/chromium/third_party/blink/renderer/core/workers/shared_worker_client.cc
@@ -7,6 +7,7 @@
#include "base/logging.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/workers/shared_worker.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
@@ -41,8 +42,14 @@ void SharedWorkerClient::OnConnected(
OnFeatureUsed(feature);
}
-void SharedWorkerClient::OnScriptLoadFailed() {
+void SharedWorkerClient::OnScriptLoadFailed(const String& error_message) {
worker_->SetIsBeingConnected(false);
+ if (!error_message.IsEmpty()) {
+ worker_->GetExecutionContext()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kWorker,
+ mojom::blink::ConsoleMessageLevel::kError, error_message));
+ }
worker_->DispatchEvent(*Event::CreateCancelable(event_type_names::kError));
// |this| can be destroyed at this point, for example, when a frame hosting
// this shared worker is detached in the error handler, and closes mojo's
diff --git a/chromium/third_party/blink/renderer/core/workers/shared_worker_client.h b/chromium/third_party/blink/renderer/core/workers/shared_worker_client.h
index c9404f21950..edc82614c5c 100644
--- a/chromium/third_party/blink/renderer/core/workers/shared_worker_client.h
+++ b/chromium/third_party/blink/renderer/core/workers/shared_worker_client.h
@@ -25,7 +25,7 @@ class SharedWorkerClient final : public mojom::blink::SharedWorkerClient {
// mojom::blink::SharedWorkerClient overrides.
void OnCreated(mojom::SharedWorkerCreationContextType) override;
void OnConnected(const Vector<mojom::WebFeature>& features_used) override;
- void OnScriptLoadFailed() override;
+ void OnScriptLoadFailed(const String& error_message) override;
void OnFeatureUsed(mojom::WebFeature feature) override;
private:
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 c6a70f67e39..99bbd31f3fa 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
@@ -36,16 +36,19 @@
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/common/messaging/message_port_channel.h"
+#include "third_party/blink/public/common/security_context/insecure_request_policy.h"
#include "third_party/blink/public/mojom/blob/blob_url_store.mojom-blink.h"
#include "third_party/blink/public/mojom/loader/fetch_client_settings_object.mojom-blink.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
#include "third_party/blink/public/mojom/worker/shared_worker_info.mojom-blink.h"
-#include "third_party/blink/public/platform/web_content_security_policy.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/public/web/blink.h"
#include "third_party/blink/public/web/web_shared_worker.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/fetch/request.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
+#include "third_party/blink/renderer/core/script/script.h"
#include "third_party/blink/renderer/core/workers/shared_worker.h"
#include "third_party/blink/renderer/core/workers/shared_worker_client.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h"
@@ -69,7 +72,8 @@ SharedWorkerClientHolder* SharedWorkerClientHolder::From(Document& document) {
}
SharedWorkerClientHolder::SharedWorkerClientHolder(Document& document)
- : ContextLifecycleObserver(&document),
+ : connector_(document.ToExecutionContext()),
+ client_receivers_(document.ToExecutionContext()),
task_runner_(document.GetTaskRunner(blink::TaskType::kDOMManipulation)) {
DCHECK(IsMainThread());
document.GetBrowserInterfaceBroker().GetInterface(
@@ -81,9 +85,9 @@ void SharedWorkerClientHolder::Connect(
MessagePortChannel port,
const KURL& url,
mojo::PendingRemote<mojom::blink::BlobURLToken> blob_url_token,
- const String& name) {
+ mojom::blink::WorkerOptionsPtr options) {
DCHECK(IsMainThread());
- DCHECK(!name.IsNull());
+ DCHECK(options);
// TODO(estark): this is broken, as it only uses the first header
// when multiple might have been sent. Fix by making the
@@ -99,10 +103,6 @@ void SharedWorkerClientHolder::Connect(
headers[0].second);
}
- mojom::blink::SharedWorkerInfoPtr info(mojom::blink::SharedWorkerInfo::New(
- url, name, header, header_type,
- worker->GetExecutionContext()->GetSecurityContext().AddressSpace()));
-
mojo::PendingRemote<mojom::blink::SharedWorkerClient> client;
client_receivers_.Add(std::make_unique<SharedWorkerClient>(worker),
client.InitWithNewPipeAndPassReceiver(), task_runner_);
@@ -115,18 +115,22 @@ void SharedWorkerClientHolder::Connect(
.GetFetchClientSettingsObject());
mojom::InsecureRequestsPolicy insecure_requests_policy =
- outside_fetch_client_settings_object->GetInsecureRequestsPolicy() &
- kUpgradeInsecureRequests
+ (outside_fetch_client_settings_object->GetInsecureRequestsPolicy() &
+ mojom::blink::InsecureRequestPolicy::kUpgradeInsecureRequests) !=
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone
? mojom::InsecureRequestsPolicy::kUpgrade
: mojom::InsecureRequestsPolicy::kDoNotUpgrade;
- connector_->Connect(
- std::move(info),
+ auto info = mojom::blink::SharedWorkerInfo::New(
+ url, std::move(options), header, header_type,
+ worker->GetExecutionContext()->GetSecurityContext().AddressSpace(),
mojom::blink::FetchClientSettingsObject::New(
outside_fetch_client_settings_object->GetReferrerPolicy(),
KURL(outside_fetch_client_settings_object->GetOutgoingReferrer()),
- insecure_requests_policy),
- std::move(client),
+ insecure_requests_policy));
+
+ connector_->Connect(
+ std::move(info), std::move(client),
worker->GetExecutionContext()->IsSecureContext()
? mojom::SharedWorkerCreationContextType::kSecure
: mojom::SharedWorkerCreationContextType::kNonsecure,
@@ -135,16 +139,10 @@ void SharedWorkerClientHolder::Connect(
blob_url_token.PassPipe(), mojom::blink::BlobURLToken::Version_));
}
-void SharedWorkerClientHolder::ContextDestroyed(ExecutionContext*) {
- DCHECK(IsMainThread());
- // Close mojo connections which will signal disinterest in the associated
- // shared worker.
- client_receivers_.Clear();
-}
-
void SharedWorkerClientHolder::Trace(Visitor* visitor) {
+ visitor->Trace(connector_);
+ visitor->Trace(client_receivers_);
Supplement<Document>::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 af9da612a49..c573cd93ab7 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
@@ -36,15 +36,16 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
-#include "mojo/public/cpp/bindings/remote.h"
-#include "mojo/public/cpp/bindings/unique_receiver_set.h"
#include "third_party/blink/public/mojom/blob/blob_url_store.mojom-blink-forward.h"
-#include "third_party/blink/public/mojom/worker/shared_worker_client.mojom-blink-forward.h"
+#include "third_party/blink/public/mojom/worker/shared_worker_client.mojom-blink.h"
#include "third_party/blink/public/mojom/worker/shared_worker_connector.mojom-blink.h"
+#include "third_party/blink/public/mojom/worker/shared_worker_info.mojom-blink.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/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.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/wtf/forward.h"
namespace blink {
@@ -62,8 +63,7 @@ class SharedWorker;
// Supplement<Document>.
class CORE_EXPORT SharedWorkerClientHolder final
: public GarbageCollected<SharedWorkerClientHolder>,
- public Supplement<Document>,
- public ContextLifecycleObserver {
+ public Supplement<Document> {
USING_GARBAGE_COLLECTED_MIXIN(SharedWorkerClientHolder);
public:
@@ -78,16 +78,13 @@ class CORE_EXPORT SharedWorkerClientHolder final
MessagePortChannel,
const KURL&,
mojo::PendingRemote<mojom::blink::BlobURLToken>,
- const String& name);
-
- // Overrides ContextLifecycleObserver.
- void ContextDestroyed(ExecutionContext*) override;
+ mojom::blink::WorkerOptionsPtr options);
void Trace(Visitor* visitor) override;
private:
- mojo::Remote<mojom::blink::SharedWorkerConnector> connector_;
- mojo::UniqueReceiverSet<mojom::blink::SharedWorkerClient> client_receivers_;
+ HeapMojoRemote<mojom::blink::SharedWorkerConnector> connector_;
+ HeapMojoUniqueReceiverSet<mojom::blink::SharedWorkerClient> client_receivers_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
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 008ff1ba127..7290eabda66 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
@@ -45,6 +45,7 @@
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/workers/shared_worker_thread.h"
#include "third_party/blink/renderer/core/workers/worker_classic_script_loader.h"
+#include "third_party/blink/renderer/core/workers/worker_module_tree_client.h"
#include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h"
#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
@@ -90,13 +91,25 @@ void SharedWorkerGlobalScope::Initialize(
SetReferrerPolicy(response_referrer_policy);
// https://wicg.github.io/cors-rfc1918/#integration-html
- SetAddressSpace(response_address_space);
+ GetSecurityContext().SetAddressSpace(response_address_space);
// Step 12.6. "Execute the Initialize a global object's CSP list algorithm
// on worker global scope and response. [CSP]"
+ // SharedWorkerGlobalScope inherits the outside's CSP instead of the response
+ // CSP headers when the response's url's scheme is a local scheme. Otherwise,
+ // use the response CSP headers. Here a local scheme is defined as follows:
+ // "A local scheme is a scheme that is "about", "blob", or "data"."
+ // https://fetch.spec.whatwg.org/#local-scheme
+ //
+ // https://w3c.github.io/webappsec-csp/#initialize-global-object-csp
// These should be called after SetAddressSpace() to correctly override the
// address space by the "treat-as-public-address" CSP directive.
- InitContentSecurityPolicyFromVector(response_csp_headers);
+ Vector<CSPHeaderAndType> csp_headers =
+ response_url.ProtocolIsAbout() || response_url.ProtocolIsData() ||
+ response_url.ProtocolIs("blob")
+ ? OutsideContentSecurityPolicyHeaders()
+ : response_csp_headers;
+ InitContentSecurityPolicyFromVector(csp_headers);
BindContentSecurityPolicyToExecutionContext();
OriginTrialContext::AddTokens(this, response_origin_trial_tokens);
@@ -121,7 +134,9 @@ void SharedWorkerGlobalScope::FetchAndRunClassicScript(
// Step 12. "Fetch a classic worker script given url, outside settings,
// destination, and inside settings."
- auto destination = mojom::RequestContextType::SHARED_WORKER;
+ auto context_type = mojom::RequestContextType::SHARED_WORKER;
+ network::mojom::RequestDestination destination =
+ network::mojom::RequestDestination::kSharedWorker;
// Step 12.1. "Set request's reserved client to inside settings."
// The browesr process takes care of this.
@@ -134,7 +149,8 @@ void SharedWorkerGlobalScope::FetchAndRunClassicScript(
*this,
CreateOutsideSettingsFetcher(outside_settings_object,
outside_resource_timing_notifier),
- script_url, destination, network::mojom::RequestMode::kSameOrigin,
+ script_url, context_type, destination,
+ network::mojom::RequestMode::kSameOrigin,
network::mojom::CredentialsMode::kSameOrigin,
WTF::Bind(&SharedWorkerGlobalScope::DidReceiveResponseForClassicScript,
WrapWeakPersistent(this),
@@ -149,17 +165,23 @@ void SharedWorkerGlobalScope::FetchAndRunModuleScript(
const KURL& module_url_record,
const FetchClientSettingsObjectSnapshot& outside_settings_object,
WorkerResourceTimingNotifier& outside_resource_timing_notifier,
- network::mojom::CredentialsMode credentials_mode) {
+ network::mojom::CredentialsMode credentials_mode,
+ RejectCoepUnsafeNone reject_coep_unsafe_none) {
+ DCHECK(!reject_coep_unsafe_none);
// Step 12: "Let destination be "sharedworker" if is shared is true, and
// "worker" otherwise."
+ auto context_type = mojom::RequestContextType::SHARED_WORKER;
+ auto destination = network::mojom::RequestDestination::kSharedWorker;
// Step 13: "... Fetch a module worker script graph given url, outside
// settings, destination, the value of the credentials member of options, and
// inside settings."
-
- // TODO(nhiroki): Implement module loading for shared workers.
- // (https://crbug.com/824646)
- NOTREACHED();
+ FetchModuleScript(module_url_record, outside_settings_object,
+ outside_resource_timing_notifier, context_type, destination,
+ credentials_mode,
+ ModuleScriptCustomFetchType::kWorkerConstructor,
+ MakeGarbageCollected<WorkerModuleTreeClient>(
+ ScriptController()->GetScriptState()));
}
const String SharedWorkerGlobalScope::name() const {
@@ -194,7 +216,15 @@ void SharedWorkerGlobalScope::DidFetchClassicScript(
const v8_inspector::V8StackTraceId& stack_id) {
DCHECK(IsContextThread());
- // Step 12. "If the algorithm asynchronously completes with null, then:"
+ // Step 12. "If the algorithm asynchronously completes with null or with
+ // script whose error to rethrow is non-null, then:"
+ //
+ // The case |error to rethrow| is non-null indicates the parse error.
+ // Parsing the script should be done during fetching according to the spec
+ // but it is done in EvaluateClassicScript() for classic scripts.
+ // Therefore, we cannot catch parse error events here.
+ // TODO(https://crbug.com/1058259) Catch parse error events for classic
+ // shared workers.
if (classic_script_loader->Failed()) {
// Step 12.1. "Queue a task to fire an event named error at worker."
// Step 12.2. "Run the environment discarding steps for inside settings."
@@ -236,7 +266,7 @@ void SharedWorkerGlobalScope::ExceptionThrown(ErrorEvent* event) {
debugger->ExceptionThrown(GetThread(), event);
}
-void SharedWorkerGlobalScope::Trace(blink::Visitor* visitor) {
+void SharedWorkerGlobalScope::Trace(Visitor* visitor) {
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 e3048d89168..9ebf4afa07f 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
@@ -76,7 +76,8 @@ class CORE_EXPORT SharedWorkerGlobalScope final : public WorkerGlobalScope {
const KURL& module_url_record,
const FetchClientSettingsObjectSnapshot& outside_settings_object,
WorkerResourceTimingNotifier& outside_resource_timing_notifier,
- network::mojom::CredentialsMode) override;
+ network::mojom::CredentialsMode,
+ RejectCoepUnsafeNone reject_coep_unsafe_none) override;
// shared_worker_global_scope.idl
const String name() const;
@@ -86,7 +87,7 @@ class CORE_EXPORT SharedWorkerGlobalScope final : public WorkerGlobalScope {
void OnAppCacheSelected();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 996257ff1bd..df1750cee6d 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
@@ -77,9 +77,11 @@ void SharedWorkerReportingProxy::DidFailToFetchClassicScript() {
void SharedWorkerReportingProxy::DidFailToFetchModuleScript() {
DCHECK(!IsMainThread());
- // TODO(nhiroki): Implement module scripts for shared workers.
- // (https://crbug.com/824646)
- NOTIMPLEMENTED();
+ PostCrossThreadTask(
+ *parent_execution_context_task_runners_->Get(TaskType::kInternalDefault),
+ FROM_HERE,
+ CrossThreadBindOnce(&WebSharedWorkerImpl::DidFailToFetchModuleScript,
+ CrossThreadUnretained(worker_)));
}
void SharedWorkerReportingProxy::DidEvaluateClassicScript(bool success) {
@@ -93,9 +95,11 @@ void SharedWorkerReportingProxy::DidEvaluateClassicScript(bool success) {
void SharedWorkerReportingProxy::DidEvaluateModuleScript(bool success) {
DCHECK(!IsMainThread());
- // TODO(nhiroki): Implement module scripts for shared workers.
- // (https://crbug.com/824646)
- NOTIMPLEMENTED();
+ PostCrossThreadTask(
+ *parent_execution_context_task_runners_->Get(TaskType::kInternalDefault),
+ FROM_HERE,
+ CrossThreadBindOnce(&WebSharedWorkerImpl::DidEvaluateModuleScript,
+ CrossThreadUnretained(worker_), success));
}
void SharedWorkerReportingProxy::DidCloseWorkerGlobalScope() {
@@ -116,7 +120,7 @@ void SharedWorkerReportingProxy::DidTerminateWorkerThread() {
CrossThreadUnretained(worker_)));
}
-void SharedWorkerReportingProxy::Trace(blink::Visitor* visitor) {
+void SharedWorkerReportingProxy::Trace(Visitor* visitor) {
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 1a8f0f9a527..d07ed43fc37 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(blink::Visitor*);
+ void Trace(Visitor*);
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 f9803096ddd..4e4eb537c81 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
@@ -16,6 +16,7 @@
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/workers/global_scope_creation_params.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
namespace blink {
@@ -52,7 +53,7 @@ int ThreadedMessagingProxyBase::ProxyCount() {
return g_live_messaging_proxy_count;
}
-void ThreadedMessagingProxyBase::Trace(blink::Visitor* visitor) {
+void ThreadedMessagingProxyBase::Trace(Visitor* visitor) {
visitor->Trace(execution_context_);
}
@@ -100,7 +101,7 @@ void ThreadedMessagingProxyBase::ReportConsoleMessage(
DCHECK(IsParentContextThread());
if (asked_to_terminate_)
return;
- execution_context_->AddConsoleMessage(ConsoleMessage::CreateFromWorker(
+ execution_context_->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
level, message, std::move(location), worker_thread_.get()));
}
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 a6136d72b52..d565596d50c 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(blink::Visitor*);
+ virtual void Trace(Visitor*);
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 9f896bf755d..21dfe9270a8 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
@@ -51,28 +51,28 @@ void ThreadedWorkletMessagingProxy::Initialize(
// LayoutWorklet and PaintWorklet.
const String global_scope_name = g_empty_string;
- Document* document = To<Document>(GetExecutionContext());
+ Document* document = Document::From(GetExecutionContext());
ContentSecurityPolicy* csp = document->GetContentSecurityPolicy();
DCHECK(csp);
auto global_scope_creation_params =
std::make_unique<GlobalScopeCreationParams>(
- document->Url(), mojom::ScriptType::kModule,
- OffMainThreadWorkerScriptFetchOption::kEnabled, global_scope_name,
+ document->Url(), mojom::blink::ScriptType::kModule, global_scope_name,
document->UserAgent(),
+ document->GetFrame()->Client()->UserAgentMetadata(),
document->GetFrame()->Client()->CreateWorkerFetchContext(),
csp->Headers(), document->GetReferrerPolicy(),
document->GetSecurityOrigin(), document->IsSecureContext(),
document->GetHttpsState(), worker_clients,
document->GetFrame()->Client()->CreateWorkerContentSettingsClient(),
- document->AddressSpace(),
- OriginTrialContext::GetTokens(document).get(),
+ document->GetSecurityContext().AddressSpace(),
+ OriginTrialContext::GetTokens(document->ToExecutionContext()).get(),
base::UnguessableToken::Create(),
std::make_unique<WorkerSettings>(document->GetSettings()),
kV8CacheOptionsDefault, module_responses_map,
mojo::NullRemote() /* browser_interface_broker */,
BeginFrameProviderParams(), nullptr /* parent_feature_policy */,
- document->GetAgentClusterID());
+ document->ToExecutionContext()->GetAgentClusterID());
// Worklets share the pre-initialized backing thread so that we don't have to
// specify the backing thread startup data.
@@ -80,7 +80,7 @@ void ThreadedWorkletMessagingProxy::Initialize(
thread_startup_data);
}
-void ThreadedWorkletMessagingProxy::Trace(blink::Visitor* visitor) {
+void ThreadedWorkletMessagingProxy::Trace(Visitor* visitor) {
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 6fb7f94b37d..fa8a05799f6 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
explicit ThreadedWorkletMessagingProxy(ExecutionContext*);
diff --git a/chromium/third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.h b/chromium/third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.h
index ee717bdec49..00bd5d73c70 100644
--- a/chromium/third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.h
+++ b/chromium/third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.h
@@ -10,8 +10,10 @@
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/workers/threaded_object_proxy_base.h"
+#include "third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.h"
#include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
namespace blink {
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 19baded39f3..e3b14213e1f 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
@@ -124,7 +124,7 @@ class ThreadedWorkletThreadForTest : public WorkerThread {
ContentSecurityPolicy* csp = GlobalScope()->GetContentSecurityPolicy();
EXPECT_EQ(1ul, csp->Headers().size());
EXPECT_EQ("invalid-csp", csp->Headers().at(0).first);
- EXPECT_EQ(kContentSecurityPolicyHeaderTypeEnforce,
+ EXPECT_EQ(network::mojom::ContentSecurityPolicyType::kEnforce,
csp->Headers().at(0).second);
PostCrossThreadTask(*GetParentTaskRunnerForTesting(), FROM_HERE,
@@ -192,21 +192,22 @@ class ThreadedWorkletMessagingProxyForTest
~ThreadedWorkletMessagingProxyForTest() override = default;
void Start() {
- Document* document = To<Document>(GetExecutionContext());
+ Document* document = Document::From(GetExecutionContext());
std::unique_ptr<Vector<char>> cached_meta_data = nullptr;
WorkerClients* worker_clients = nullptr;
std::unique_ptr<WorkerSettings> worker_settings = nullptr;
InitializeWorkerThread(
std::make_unique<GlobalScopeCreationParams>(
- document->Url(), mojom::ScriptType::kModule,
- OffMainThreadWorkerScriptFetchOption::kEnabled, "threaded_worklet",
- document->UserAgent(), nullptr /* web_worker_fetch_context */,
+ document->Url(), mojom::blink::ScriptType::kModule,
+ "threaded_worklet", document->UserAgent(),
+ document->GetFrame()->Loader().UserAgentMetadata(),
+ nullptr /* web_worker_fetch_context */,
document->GetContentSecurityPolicy()->Headers(),
document->GetReferrerPolicy(), document->GetSecurityOrigin(),
document->IsSecureContext(), document->GetHttpsState(),
worker_clients, nullptr /* content_settings_client */,
- document->AddressSpace(),
- OriginTrialContext::GetTokens(document).get(),
+ document->GetSecurityContext().AddressSpace(),
+ OriginTrialContext::GetTokens(document->ToExecutionContext()).get(),
base::UnguessableToken::Create(), std::move(worker_settings),
kV8CacheOptionsDefault,
MakeGarbageCollected<WorkletModuleResponsesMap>()),
@@ -234,7 +235,7 @@ class ThreadedWorkletTest : public testing::Test {
messaging_proxy_ =
MakeGarbageCollected<ThreadedWorkletMessagingProxyForTest>(
- &page_->GetDocument());
+ page_->GetDocument().ToExecutionContext());
ThreadedWorkletThreadForTest::EnsureSharedBackingThread();
}
@@ -277,8 +278,8 @@ TEST_F(ThreadedWorkletTest, ContentSecurityPolicy) {
// ThreadedWorklet inherits the owner Document's CSP.
auto* csp = MakeGarbageCollected<ContentSecurityPolicy>();
csp->DidReceiveHeader("script-src 'self' https://allowed.example.com",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ network::mojom::ContentSecurityPolicyType::kEnforce,
+ network::mojom::ContentSecurityPolicySource::kHTTP);
GetDocument().InitContentSecurityPolicy(csp);
MessagingProxy()->Start();
@@ -293,8 +294,9 @@ TEST_F(ThreadedWorkletTest, ContentSecurityPolicy) {
TEST_F(ThreadedWorkletTest, InvalidContentSecurityPolicy) {
auto* csp = MakeGarbageCollected<ContentSecurityPolicy>();
- csp->DidReceiveHeader("invalid-csp", kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ csp->DidReceiveHeader("invalid-csp",
+ network::mojom::ContentSecurityPolicyType::kEnforce,
+ network::mojom::ContentSecurityPolicySource::kHTTP);
GetDocument().InitContentSecurityPolicy(csp);
MessagingProxy()->Start();
diff --git a/chromium/third_party/blink/renderer/core/workers/worker.idl b/chromium/third_party/blink/renderer/core/workers/worker.idl
index a0e36b36e2a..f7c33042177 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker.idl
+++ b/chromium/third_party/blink/renderer/core/workers/worker.idl
@@ -29,16 +29,14 @@
[
ActiveScriptWrappable,
- Constructor(DOMString scriptURL, optional WorkerOptions options),
- ConstructorCallWith=ExecutionContext,
Exposed=(Window,DedicatedWorker),
- RaisesException=Constructor,
ImplementedAs=DedicatedWorker
] interface Worker : EventTarget {
+ [CallWith=ExecutionContext, RaisesException] constructor(ScriptURLString scriptURL, optional WorkerOptions options = {});
void terminate();
[CallWith=ScriptState, RaisesException] void postMessage(any message, sequence<object> transfer);
- [CallWith=ScriptState, RaisesException] void postMessage(any message, optional PostMessageOptions options);
+ [CallWith=ScriptState, RaisesException] void postMessage(any message, optional PostMessageOptions options = {});
attribute EventHandler onmessage;
};
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_backing_thread.cc b/chromium/third_party/blink/renderer/core/workers/worker_backing_thread.cc
index d18082b586f..d0313a3e8de 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_backing_thread.cc
+++ b/chromium/third_party/blink/renderer/core/workers/worker_backing_thread.cc
@@ -7,6 +7,7 @@
#include <memory>
#include "base/location.h"
+#include "third_party/blink/public/common/features.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/v8_binding_for_core.h"
@@ -83,8 +84,14 @@ void WorkerBackingThread::InitializeOnBackingThread(
V8PerIsolateData::From(isolate_)->SetThreadDebugger(
std::make_unique<WorkerThreadDebugger>(isolate_));
- // Optimize for memory usage instead of latency for the worker isolate.
- isolate_->IsolateInBackgroundNotification();
+ if (!base::FeatureList::IsEnabled(
+ features::kV8OptimizeWorkersForPerformance)) {
+ // Optimize for memory usage instead of latency for the worker isolate.
+ // Service Workers that have the fetch event handler run with the Isolate
+ // in foreground notification regardless of this configuration.
+ // See ServiceWorkerGlobalScope::SetFetchHandlerExistence().
+ isolate_->IsolateInBackgroundNotification();
+ }
if (startup_data.heap_limit_mode ==
WorkerBackingThreadStartupData::HeapLimitMode::kIncreasedForDebugging) {
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 1f8273a782a..e15412a8780 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
@@ -103,7 +103,8 @@ void WorkerClassicScriptLoader::LoadSynchronously(
ExecutionContext& execution_context,
ResourceFetcher* fetch_client_settings_object_fetcher,
const KURL& url,
- mojom::RequestContextType request_context) {
+ mojom::RequestContextType request_context,
+ network::mojom::RequestDestination destination) {
DCHECK(fetch_client_settings_object_fetcher);
url_ = url;
fetch_client_settings_object_fetcher_ = fetch_client_settings_object_fetcher;
@@ -115,6 +116,7 @@ void WorkerClassicScriptLoader::LoadSynchronously(
.GetFetchClientSettingsObject()
.GetAddressSpace());
request.SetRequestContext(request_context);
+ request.SetRequestDestination(destination);
SECURITY_DCHECK(execution_context.IsWorkerGlobalScope());
@@ -134,10 +136,14 @@ void WorkerClassicScriptLoader::LoadTopLevelScriptAsynchronously(
ResourceFetcher* fetch_client_settings_object_fetcher,
const KURL& url,
mojom::RequestContextType request_context,
+ network::mojom::RequestDestination destination,
network::mojom::RequestMode request_mode,
network::mojom::CredentialsMode credentials_mode,
base::OnceClosure response_callback,
- base::OnceClosure finished_callback) {
+ base::OnceClosure finished_callback,
+ RejectCoepUnsafeNone reject_coep_unsafe_none,
+ mojo::PendingRemote<network::mojom::blink::URLLoaderFactory>
+ blob_url_loader_factory) {
DCHECK(fetch_client_settings_object_fetcher);
DCHECK(response_callback || finished_callback);
response_callback_ = std::move(response_callback);
@@ -153,12 +159,21 @@ void WorkerClassicScriptLoader::LoadTopLevelScriptAsynchronously(
.GetFetchClientSettingsObject()
.GetAddressSpace());
request.SetRequestContext(request_context);
+ request.SetRequestDestination(destination);
request.SetMode(request_mode);
request.SetCredentialsMode(credentials_mode);
need_to_cancel_ = true;
+ ResourceLoaderOptions resource_loader_options;
+ resource_loader_options.reject_coep_unsafe_none = reject_coep_unsafe_none;
+ if (blob_url_loader_factory) {
+ resource_loader_options.url_loader_factory =
+ base::MakeRefCounted<base::RefCountedData<
+ mojo::PendingRemote<network::mojom::blink::URLLoaderFactory>>>(
+ std::move(blob_url_loader_factory));
+ }
threadable_loader_ = MakeGarbageCollected<ThreadableLoader>(
- execution_context, this, ResourceLoaderOptions(),
+ execution_context, this, resource_loader_options,
fetch_client_settings_object_fetcher);
threadable_loader_->Start(request);
if (failed_)
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 7574f3054ed..bbdf03d7a41 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
@@ -30,13 +30,16 @@
#include <memory>
#include "base/memory/scoped_refptr.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
#include "services/network/public/mojom/fetch_api.mojom-blink-forward.h"
#include "services/network/public/mojom/ip_address_space.mojom-blink-forward.h"
+#include "services/network/public/mojom/url_loader_factory.mojom-blink.h"
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/loader/threadable_loader.h"
#include "third_party/blink/renderer/core/loader/threadable_loader_client.h"
#include "third_party/blink/renderer/platform/loader/allowed_by_nosniff.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/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -64,22 +67,30 @@ class CORE_EXPORT WorkerClassicScriptLoader final
void LoadSynchronously(ExecutionContext&,
ResourceFetcher* fetch_client_settings_object_fetcher,
const KURL&,
- mojom::RequestContextType);
+ mojom::RequestContextType,
+ network::mojom::RequestDestination);
// Note that callbacks could be invoked before
// LoadTopLevelScriptAsynchronously() returns.
//
// |fetch_client_settings_object_fetcher| is different from
// ExecutionContext::Fetcher() in off-the-main-thread fetch.
+ // TODO(crbug.com/1064920): Remove |reject_coep_unsafe_none| and
+ // |blob_url_loader_factory| when PlzDedicatedWorker ships.
void LoadTopLevelScriptAsynchronously(
ExecutionContext&,
ResourceFetcher* fetch_client_settings_object_fetcher,
const KURL&,
mojom::RequestContextType,
+ network::mojom::RequestDestination,
network::mojom::RequestMode,
network::mojom::CredentialsMode,
base::OnceClosure response_callback,
- base::OnceClosure finished_callback);
+ base::OnceClosure finished_callback,
+ RejectCoepUnsafeNone reject_coep_unsafe_none =
+ RejectCoepUnsafeNone(false),
+ mojo::PendingRemote<network::mojom::blink::URLLoaderFactory>
+ blob_url_loader_factory = {});
// This will immediately invoke |finishedCallback| if
// LoadTopLevelScriptAsynchronously() is in progress.
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 009b7b68cec..479d2cf40a4 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 b476e7490aa..ee2b239577f 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
@@ -33,7 +33,6 @@
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
-#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script_url.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_void_function.h"
#include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h"
#include "third_party/blink/renderer/core/css/font_face_set_worker.h"
@@ -42,7 +41,6 @@
#include "third_party/blink/renderer/core/events/error_event.h"
#include "third_party/blink/renderer/core/events/message_event.h"
#include "third_party/blink/renderer/core/execution_context/agent.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_notifier.h"
#include "third_party/blink/renderer/core/frame/dom_timer_coordinator.h"
#include "third_party/blink/renderer/core/frame/user_activation.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
@@ -50,6 +48,7 @@
#include "third_party/blink/renderer/core/inspector/worker_inspector_controller.h"
#include "third_party/blink/renderer/core/inspector/worker_thread_debugger.h"
#include "third_party/blink/renderer/core/loader/threadable_loader.h"
+#include "third_party/blink/renderer/core/messaging/blink_transferable_message.h"
#include "third_party/blink/renderer/core/messaging/message_port.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/script/classic_script.h"
@@ -64,6 +63,7 @@
#include "third_party/blink/renderer/core/workers/worker_thread.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.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/instance_counters.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h"
#include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
@@ -86,9 +86,49 @@ void RemoveURLFromMemoryCacheInternal(const KURL& url) {
}
scoped_refptr<SecurityOrigin> CreateSecurityOrigin(
- GlobalScopeCreationParams* creation_params) {
- scoped_refptr<SecurityOrigin> security_origin =
- SecurityOrigin::Create(creation_params->script_url);
+ GlobalScopeCreationParams* creation_params,
+ ExecutionContext* execution_context) {
+ // A worker environment settings object's origin must be set as follows:
+ //
+ // - DedicatedWorkers and SharedWorkers
+ // https://html.spec.whatwg.org/C/#set-up-a-worker-environment-settings-object
+ // Step 2: Let inherited origin be outside settings's origin.
+ // Step 6: Let settings object be a new environment settings object whose
+ // algorithms are defined as follows:
+ // The origin -> Return a unique opaque origin if worker global scope's url's
+ // scheme is "data", and inherited origin otherwise. [spec text]
+ //
+ // - ServiceWorkers
+ // https://w3c.github.io/ServiceWorker/#run-service-worker-algorithm
+ // Step 7.4: Let settingsObject be a new environment settings object whose
+ // algorithms are defined as follows:
+ // The origin -> Return its registering service worker client's origin.
+ // [spec text]
+ //
+ // The algorithm in ServiceWorkers differ from DedicatedWorkers and
+ // SharedWorkers when worker global scope's url's scheme is "data", but
+ // "data" url script is not allowed for ServiceWorkers, so all workers' origin
+ // can be calculated in the same way.
+ // https://w3c.github.io/ServiceWorker/#start-register
+ // Step 3: If scriptURL’s scheme is not one of "http" and "https", reject
+ // promise with a TypeError and abort these steps. [spec text]
+ DCHECK(!execution_context->IsServiceWorkerGlobalScope() ||
+ !KURL(creation_params->script_url).ProtocolIsData());
+
+ // TODO(https://crbug.com/1058305) Inherit |agent_cluster_id_| for dedicated
+ // workers. DO NOT inherit for shared workers and service workers.
+ //
+ // Create a new SecurityOrigin via CreateFromUrlOrigin() so that worker's
+ // origin can avoid inheriting unnecessary capabilities from the starter
+ // origin, while the worker's origin inherits url:Origin's internal nonce.
+ scoped_refptr<SecurityOrigin> security_origin;
+ if (KURL(creation_params->script_url).ProtocolIsData()) {
+ security_origin = SecurityOrigin::CreateUniqueOpaque();
+ } else {
+ security_origin = SecurityOrigin::CreateFromUrlOrigin(
+ creation_params->starter_origin->ToUrlOrigin());
+ }
+
if (creation_params->starter_origin) {
security_origin->TransferPrivilegesFrom(
creation_params->starter_origin->CreatePrivilegeData());
@@ -153,8 +193,8 @@ WorkerLocation* WorkerGlobalScope::location() const {
WorkerNavigator* WorkerGlobalScope::navigator() const {
if (!navigator_) {
- navigator_ = MakeGarbageCollected<WorkerNavigator>(user_agent_,
- GetExecutionContext());
+ navigator_ = MakeGarbageCollected<WorkerNavigator>(
+ user_agent_, ua_metadata_, GetExecutionContext());
}
return navigator_.Get();
}
@@ -169,18 +209,9 @@ String WorkerGlobalScope::origin() const {
return GetSecurityOrigin()->ToString();
}
-void WorkerGlobalScope::importScripts(
- const HeapVector<StringOrTrustedScriptURL>& urls,
- ExceptionState& exception_state) {
- Vector<String> string_urls;
- for (const StringOrTrustedScriptURL& stringOrUrl : urls) {
- String string_url = GetStringFromTrustedScriptURL(
- stringOrUrl, GetExecutionContext(), exception_state);
- if (exception_state.HadException())
- return;
- string_urls.push_back(string_url);
- }
- ImportScriptsInternal(string_urls, exception_state);
+void WorkerGlobalScope::importScripts(const Vector<String>& urls,
+ ExceptionState& exception_state) {
+ ImportScriptsInternal(urls, exception_state);
}
// Implementation of the "import scripts into worker global scope" algorithm:
@@ -287,9 +318,10 @@ bool WorkerGlobalScope::FetchClassicImportedScript(
WorkerClassicScriptLoader* classic_script_loader =
MakeGarbageCollected<WorkerClassicScriptLoader>();
EnsureFetcher();
- classic_script_loader->LoadSynchronously(*execution_context, Fetcher(),
- script_url,
- mojom::RequestContextType::SCRIPT);
+ classic_script_loader->LoadSynchronously(
+ *execution_context, Fetcher(), script_url,
+ mojom::RequestContextType::SCRIPT,
+ network::mojom::RequestDestination::kScript);
if (classic_script_loader->Failed())
return false;
*out_response_url = classic_script_loader->ResponseURL();
@@ -323,19 +355,6 @@ CoreProbeSink* WorkerGlobalScope::GetProbeSink() {
return nullptr;
}
-bool WorkerGlobalScope::IsSecureContext(String& error_message) const {
- // Until there are APIs that are available in workers and that
- // require a privileged context test that checks ancestors, just do
- // a simple check here. Once we have a need for a real
- // |isSecureContext| check here, we can check the responsible
- // document for a privileged context at worker creation time, pass
- // it in via WorkerThreadStartupData, and check it here.
- if (GetSecurityOrigin()->IsPotentiallyTrustworthy())
- return true;
- error_message = GetSecurityOrigin()->IsPotentiallyTrustworthyErrorMessage();
- return false;
-}
-
BrowserInterfaceBrokerProxy& WorkerGlobalScope::GetBrowserInterfaceBroker() {
return browser_interface_broker_proxy_;
}
@@ -397,9 +416,11 @@ void WorkerGlobalScope::ReadyToRunWorkerScript() {
void WorkerGlobalScope::RunWorkerScript() {
DCHECK(IsContextThread());
DCHECK(!IsContextPaused());
+ CHECK(GetExecutionContext()) << "crbug.com/1045818: attempted to evaluate "
+ "script but no execution context";
CHECK(!GetExecutionContext()->IsContextDestroyed())
- << "https://crbug.com/930618: worker global scope was destroyed before "
- "evaluating classic script";
+ << "crbug.com/1045818: attempted to evaluate script but worker global "
+ "scope was already destroyed";
DCHECK(worker_script_);
DCHECK_EQ(script_eval_state_, ScriptEvalState::kReadyToEvaluate);
@@ -445,13 +466,12 @@ WorkerGlobalScope::WorkerGlobalScope(
base::TimeTicks time_origin)
: WorkerOrWorkletGlobalScope(
thread->GetIsolate(),
- CreateSecurityOrigin(creation_params.get()),
- Agent::CreateForWorkerOrWorklet(
+ CreateSecurityOrigin(creation_params.get(), GetExecutionContext()),
+ MakeGarbageCollected<Agent>(
thread->GetIsolate(),
(creation_params->agent_cluster_id.is_empty()
? base::UnguessableToken::Create()
: creation_params->agent_cluster_id)),
- creation_params->off_main_thread_fetch_option,
creation_params->global_scope_name,
creation_params->parent_devtools_token,
creation_params->v8_cache_options,
@@ -461,6 +481,7 @@ WorkerGlobalScope::WorkerGlobalScope(
thread->GetWorkerReportingProxy()),
script_type_(creation_params->script_type),
user_agent_(creation_params->user_agent),
+ ua_metadata_(creation_params->ua_metadata),
thread_(thread),
time_origin_(time_origin),
font_selector_(MakeGarbageCollected<OffscreenFontSelector>(this)),
@@ -491,7 +512,8 @@ WorkerGlobalScope::WorkerGlobalScope(
// A FeaturePolicy is created by FeaturePolicy::CreateFromParentPolicy, even
// if the parent policy is null.
DCHECK(creation_params->worker_feature_policy);
- SetFeaturePolicy(std::move(creation_params->worker_feature_policy));
+ GetSecurityContext().SetFeaturePolicy(
+ std::move(creation_params->worker_feature_policy));
}
void WorkerGlobalScope::ExceptionThrown(ErrorEvent* event) {
@@ -514,8 +536,7 @@ NOINLINE void WorkerGlobalScope::InitializeURL(const KURL& url) {
if (GetSecurityOrigin()->IsOpaque()) {
DCHECK(SecurityOrigin::Create(url)->IsOpaque());
} else {
- DCHECK(GetSecurityOrigin()->IsSameOriginWith(
- SecurityOrigin::Create(url).get()));
+ DCHECK(GetSecurityOrigin()->CanReadContent(url));
}
url_ = url;
}
@@ -542,7 +563,7 @@ TrustedTypePolicyFactory* WorkerGlobalScope::GetTrustedTypes() const {
return trusted_types_.Get();
}
-void WorkerGlobalScope::Trace(blink::Visitor* visitor) {
+void WorkerGlobalScope::Trace(Visitor* visitor) {
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 8be896dafb9..ca49b8c6c14 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
@@ -37,9 +37,9 @@
#include "third_party/blink/renderer/core/dom/frame_request_callback_collection.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/messaging/blink_transferable_message.h"
#include "third_party/blink/renderer/core/script/script.h"
#include "third_party/blink/renderer/core/workers/global_scope_creation_params.h"
+#include "third_party/blink/renderer/core/workers/worker_classic_script_loader.h"
#include "third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h"
#include "third_party/blink/renderer/core/workers/worker_settings.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -48,6 +48,7 @@
namespace blink {
+struct BlinkTransferableMessage;
class ConsoleMessage;
class ExceptionState;
class FetchClientSettingsObjectSnapshot;
@@ -55,7 +56,6 @@ class FontFaceSet;
class InstalledScriptsManager;
class OffscreenFontSelector;
class WorkerResourceTimingNotifier;
-class StringOrTrustedScriptURL;
class TrustedTypePolicyFactory;
class V8VoidFunction;
class WorkerLocation;
@@ -100,11 +100,11 @@ class CORE_EXPORT WorkerGlobalScope
DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
DEFINE_ATTRIBUTE_EVENT_LISTENER(languagechange, kLanguagechange)
DEFINE_ATTRIBUTE_EVENT_LISTENER(rejectionhandled, kRejectionhandled)
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(timezonechange, kTimezonechange)
DEFINE_ATTRIBUTE_EVENT_LISTENER(unhandledrejection, kUnhandledrejection)
// WorkerUtils
- virtual void importScripts(const HeapVector<StringOrTrustedScriptURL>& urls,
- ExceptionState&);
+ virtual void importScripts(const Vector<String>& urls, ExceptionState&);
// ExecutionContext
const KURL& Url() const final;
@@ -113,13 +113,11 @@ class CORE_EXPORT WorkerGlobalScope
bool IsContextThread() const final;
const KURL& BaseURL() const final;
String UserAgent() const final { return user_agent_; }
+ const UserAgentMetadata& GetUserAgentMetadata() const { return ua_metadata_; }
HttpsState GetHttpsState() const override { return https_state_; }
scheduler::WorkerScheduler* GetScheduler() final;
- SecurityContext& GetSecurityContext() final { return *this; }
- const SecurityContext& GetSecurityContext() const final { return *this; }
void AddConsoleMessageImpl(ConsoleMessage*, bool discard_duplicates) final;
- bool IsSecureContext(String& error_message) const override;
BrowserInterfaceBrokerProxy& GetBrowserInterfaceBroker() final;
OffscreenFontSelector* GetFontSelector() { return font_selector_; }
@@ -174,13 +172,14 @@ class CORE_EXPORT WorkerGlobalScope
const KURL& module_url_record,
const FetchClientSettingsObjectSnapshot& outside_settings_object,
WorkerResourceTimingNotifier& outside_resource_timing_notifier,
- network::mojom::CredentialsMode) = 0;
+ network::mojom::CredentialsMode,
+ RejectCoepUnsafeNone reject_coep_unsafe_none) = 0;
void ReceiveMessage(BlinkTransferableMessage);
base::TimeTicks TimeOrigin() const { return time_origin_; }
WorkerSettings* GetWorkerSettings() const { return worker_settings_.get(); }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
virtual InstalledScriptsManager* GetInstalledScriptsManager() {
return nullptr;
@@ -196,6 +195,10 @@ class CORE_EXPORT WorkerGlobalScope
TrustedTypePolicyFactory* GetTrustedTypes() const override;
TrustedTypePolicyFactory* trustedTypes() const { return GetTrustedTypes(); }
+ // TODO(https://crbug.com/835717): Remove this function after dedicated
+ // workers support off-the-main-thread script fetch by default.
+ virtual bool IsOffMainThreadScriptFetchDisabled() { return false; }
+
protected:
WorkerGlobalScope(std::unique_ptr<GlobalScopeCreationParams>,
WorkerThread*,
@@ -234,6 +237,7 @@ class CORE_EXPORT WorkerGlobalScope
KURL url_;
const mojom::ScriptType script_type_;
const String user_agent_;
+ const UserAgentMetadata ua_metadata_;
std::unique_ptr<WorkerSettings> worker_settings_;
mutable Member<WorkerLocation> location_;
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_global_scope.idl b/chromium/third_party/blink/renderer/core/workers/worker_global_scope.idl
index a6d5607ff13..616a02c4ac2 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_global_scope.idl
+++ b/chromium/third_party/blink/renderer/core/workers/worker_global_scope.idl
@@ -37,6 +37,7 @@
// TODO(foolip): onerror should be an OnErrorEventHandler.
attribute EventHandler onerror;
attribute EventHandler onlanguagechange;
+ [RuntimeEnabled=TimeZoneChangeEvent] attribute EventHandler ontimezonechange;
// attribute EventHandler onoffline;
// attribute EventHandler ononline;
@@ -74,7 +75,7 @@
readonly attribute FontFaceSet fonts;
// TrustedTypes API: http://github.com/wicg/trusted-types
- [RuntimeEnabled=TrustedDOMTypes, Unforgeable] readonly attribute TrustedTypePolicyFactory trustedTypes;
+ [RuntimeEnabled=TrustedDOMTypes] readonly attribute TrustedTypePolicyFactory trustedTypes;
};
WorkerGlobalScope includes WindowOrWorkerGlobalScope;
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 8c75b65c884..fd24be11440 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
@@ -25,8 +25,9 @@ void WorkerModuleTreeClient::NotifyModuleTreeLoadFinished(
blink::WorkerReportingProxy& worker_reporting_proxy =
worker_global_scope->ReportingProxy();
- // Step 12. "If the algorithm asynchronously completes with null, then:"
- if (!module_script) {
+ // Step 12. "If the algorithm asynchronously completes with null or with
+ // script whose error to rethrow is non-null, then:"
+ if (!module_script || module_script->HasErrorToRethrow()) {
// Step 12.1. "Queue a task to fire an event named error at worker."
// DidFailToFetchModuleScript() will asynchronously fire the event.
worker_reporting_proxy.DidFailToFetchModuleScript();
@@ -50,7 +51,7 @@ void WorkerModuleTreeClient::NotifyModuleTreeLoadFinished(
*module_script, base::nullopt /* v8_inspector::V8StackTraceId */);
}
-void WorkerModuleTreeClient::Trace(blink::Visitor* visitor) {
+void WorkerModuleTreeClient::Trace(Visitor* visitor) {
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 e96559501b5..14d27127640 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 9b39e909841..99f3efbc7f1 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_navigator.cc
+++ b/chromium/third_party/blink/renderer/core/workers/worker_navigator.cc
@@ -37,10 +37,12 @@
namespace blink {
WorkerNavigator::WorkerNavigator(const String& user_agent,
+ const UserAgentMetadata& ua_metadata,
ExecutionContext* execution_context)
- : ContextClient(execution_context),
+ : ExecutionContextClient(execution_context),
NavigatorLanguage(execution_context),
- user_agent_(user_agent) {}
+ user_agent_(user_agent),
+ ua_metadata_(ua_metadata) {}
WorkerNavigator::~WorkerNavigator() = default;
@@ -66,9 +68,9 @@ void WorkerNavigator::NotifyUpdate() {
*Event::Create(event_type_names::kLanguagechange));
}
-void WorkerNavigator::Trace(blink::Visitor* visitor) {
+void WorkerNavigator::Trace(Visitor* visitor) {
ScriptWrappable::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
NavigatorLanguage::Trace(visitor);
Supplementable<WorkerNavigator>::Trace(visitor);
}
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 280abb27b4a..553fb13d783 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_navigator.h
+++ b/chromium/third_party/blink/renderer/core/workers/worker_navigator.h
@@ -28,12 +28,13 @@
#include "third_party/blink/public/platform/web_worker_fetch_context.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/frame/navigator_concurrent_hardware.h"
#include "third_party/blink/renderer/core/frame/navigator_device_memory.h"
#include "third_party/blink/renderer/core/frame/navigator_id.h"
#include "third_party/blink/renderer/core/frame/navigator_language.h"
#include "third_party/blink/renderer/core/frame/navigator_on_line.h"
+#include "third_party/blink/renderer/core/frame/navigator_ua.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"
@@ -44,18 +45,21 @@ namespace blink {
class CORE_EXPORT WorkerNavigator final
: public ScriptWrappable,
public AcceptLanguagesWatcher,
- public ContextClient,
+ public ExecutionContextClient,
public NavigatorConcurrentHardware,
public NavigatorDeviceMemory,
public NavigatorID,
public NavigatorLanguage,
public NavigatorOnLine,
+ public NavigatorUA,
public Supplementable<WorkerNavigator> {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(WorkerNavigator);
public:
- explicit WorkerNavigator(const String&, ExecutionContext* execution_context);
+ WorkerNavigator(const String& user_agent,
+ const UserAgentMetadata&,
+ ExecutionContext* execution_context);
~WorkerNavigator() override;
// NavigatorID override
@@ -67,10 +71,19 @@ class CORE_EXPORT WorkerNavigator final
// AcceptLanguagesWatcher override
void NotifyUpdate() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
+
+ protected:
+ UserAgentMetadata GetUserAgentMetadata() const override {
+ return ua_metadata_;
+ }
+ ExecutionContext* GetUAExecutionContext() const override {
+ return GetExecutionContext();
+ }
private:
String user_agent_;
+ UserAgentMetadata ua_metadata_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_navigator.idl b/chromium/third_party/blink/renderer/core/workers/worker_navigator.idl
index a0fe35b486f..a03e978d14e 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_navigator.idl
+++ b/chromium/third_party/blink/renderer/core/workers/worker_navigator.idl
@@ -38,3 +38,4 @@ WorkerNavigator includes NavigatorDeviceMemory;
WorkerNavigator includes NavigatorID;
WorkerNavigator includes NavigatorLanguage;
WorkerNavigator includes NavigatorOnLine;
+WorkerNavigator includes NavigatorUA;
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 539f44a9456..141b1d06dda 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
@@ -4,11 +4,14 @@
#include "third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h"
+#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_worker_fetch_context.h"
#include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h"
#include "third_party/blink/renderer/core/dom/events/event_queue.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/deprecation.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/loader/loader_factory_for_worker.h"
@@ -24,6 +27,7 @@
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h"
#include "third_party/blink/renderer/core/workers/worker_thread.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/loader/fetch/detachable_use_counter.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h"
#include "third_party/blink/renderer/platform/loader/fetch/null_resource_fetcher_properties.h"
@@ -59,7 +63,7 @@ class OutsideSettingsCSPDelegate final
DCHECK(global_scope_for_logging_->IsContextThread());
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(global_scope_for_logging_);
visitor->Trace(outside_settings_object_);
}
@@ -74,6 +78,19 @@ class OutsideSettingsCSPDelegate final
return outside_settings_object_->GetSecurityOrigin();
}
+ SecureContextMode GetSecureContextMode() override {
+ DCHECK(global_scope_for_logging_->IsContextThread());
+ // TODO(mkwst): This doesn't handle nested workers correctly; we ought to
+ // be reading the SecureContextMode from the relevant SecurityContext, but
+ // we don't have it here. This code simply checks the worker's origin, which
+ // generally works, but would incorrectly consider a secure worker nested in
+ // a non-secure worker as a "secure context".
+ return outside_settings_object_->GetSecurityOrigin()
+ ->IsPotentiallyTrustworthy()
+ ? SecureContextMode::kSecureContext
+ : SecureContextMode::kInsecureContext;
+ }
+
// We don't have to do anything here, as we don't want to update
// SecurityContext of either parent context or WorkerOrWorkletGlobalScope.
// TODO(hiroshige): Revisit the relationship of ContentSecurityPolicy,
@@ -82,7 +99,7 @@ class OutsideSettingsCSPDelegate final
// https://crbug.com/924041 https://crbug.com/924043
void SetSandboxFlags(SandboxFlags) override {}
void SetRequireTrustedTypes() override {}
- void AddInsecureRequestPolicy(WebInsecureRequestPolicy) override {}
+ void AddInsecureRequestPolicy(mojom::blink::InsecureRequestPolicy) override {}
void DisableEval(const String& error_message) override {}
std::unique_ptr<SourceLocation> GetSourceLocation() override {
@@ -146,7 +163,7 @@ class OutsideSettingsCSPDelegate final
}
void DidAddContentSecurityPolicies(
- const blink::WebVector<WebContentSecurityPolicy>&) override {
+ WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr>) override {
DCHECK(global_scope_for_logging_->IsContextThread());
// We do nothing here, because if the added policies should be reported to
// LocalFrameClient, then they are already reported on the parent
@@ -169,7 +186,6 @@ WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope(
v8::Isolate* isolate,
scoped_refptr<SecurityOrigin> origin,
Agent* agent,
- OffMainThreadWorkerScriptFetchOption off_main_thread_fetch_option,
const String& name,
const base::UnguessableToken& parent_devtools_token,
V8CacheOptions v8_cache_options,
@@ -177,11 +193,12 @@ WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope(
std::unique_ptr<WebContentSettingsClient> content_settings_client,
scoped_refptr<WebWorkerFetchContext> web_worker_fetch_context,
WorkerReportingProxy& reporting_proxy)
- : ExecutionContext(isolate,
- agent,
- MakeGarbageCollected<OriginTrialContext>()),
- SecurityContext(std::move(origin), WebSandboxFlags::kNone, nullptr),
- off_main_thread_fetch_option_(off_main_thread_fetch_option),
+ : ExecutionContext(isolate),
+ security_context_(
+ SecurityContextInit(origin,
+ MakeGarbageCollected<OriginTrialContext>(),
+ agent),
+ SecurityContext::kLocal),
name_(name),
parent_devtools_token_(parent_devtools_token),
worker_clients_(worker_clients),
@@ -191,6 +208,7 @@ WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope(
MakeGarbageCollected<WorkerOrWorkletScriptController>(this, isolate)),
v8_cache_options_(v8_cache_options),
reporting_proxy_(reporting_proxy) {
+ GetSecurityContext().GetOriginTrialContext()->BindExecutionContext(this);
if (worker_clients_)
worker_clients_->ReattachThread();
}
@@ -204,7 +222,7 @@ const AtomicString& WorkerOrWorkletGlobalScope::InterfaceName() const {
return g_null_atom;
}
-v8::Local<v8::Object> WorkerOrWorkletGlobalScope::Wrap(
+v8::Local<v8::Value> WorkerOrWorkletGlobalScope::Wrap(
v8::Isolate*,
v8::Local<v8::Object> creation_context) {
LOG(FATAL) << "WorkerOrWorkletGlobalScope must never be wrapped with wrap "
@@ -249,10 +267,10 @@ void WorkerOrWorkletGlobalScope::CountDeprecation(WebFeature feature) {
// Adds a deprecation message to the console.
DCHECK(!Deprecation::DeprecationMessage(feature).IsEmpty());
- AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kDeprecation,
- mojom::ConsoleMessageLevel::kWarning,
- Deprecation::DeprecationMessage(feature)));
+ AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kDeprecation,
+ mojom::ConsoleMessageLevel::kWarning,
+ Deprecation::DeprecationMessage(feature)));
ReportingProxy().CountDeprecation(feature);
}
@@ -270,7 +288,7 @@ void WorkerOrWorkletGlobalScope::InitializeWebFetchContextIfNeeded() {
web_worker_fetch_context_->TakeSubresourceFilter();
if (web_filter) {
subresource_filter_ =
- SubresourceFilter::Create(*this, std::move(web_filter));
+ MakeGarbageCollected<SubresourceFilter>(this, std::move(web_filter));
}
}
@@ -355,7 +373,7 @@ ResourceFetcher* WorkerOrWorkletGlobalScope::CreateOutsideSettingsFetcher(
for (const auto& policy_and_type : outside_content_security_policy_headers_) {
content_security_policy->DidReceiveHeader(
policy_and_type.first, policy_and_type.second,
- kContentSecurityPolicyHeaderSourceHTTP);
+ network::mojom::ContentSecurityPolicySource::kHTTP);
}
OutsideSettingsCSPDelegate* csp_delegate =
@@ -406,10 +424,11 @@ WorkerOrWorkletGlobalScope::GetTaskRunner(TaskType type) {
}
void WorkerOrWorkletGlobalScope::ApplySandboxFlags(SandboxFlags mask) {
- sandbox_flags_ |= mask;
- if (IsSandboxed(WebSandboxFlags::kOrigin) &&
+ GetSecurityContext().ApplySandboxFlags(mask);
+ if (IsSandboxed(mojom::blink::WebSandboxFlags::kOrigin) &&
!GetSecurityOrigin()->IsOpaque()) {
- SetSecurityOrigin(GetSecurityOrigin()->DeriveNewOpaqueOrigin());
+ GetSecurityContext().SetSecurityOrigin(
+ GetSecurityOrigin()->DeriveNewOpaqueOrigin());
}
}
@@ -422,12 +441,12 @@ void WorkerOrWorkletGlobalScope::InitContentSecurityPolicyFromVector(
const Vector<CSPHeaderAndType>& headers) {
if (!GetContentSecurityPolicy()) {
auto* csp = MakeGarbageCollected<ContentSecurityPolicy>();
- SetContentSecurityPolicy(csp);
+ GetSecurityContext().SetContentSecurityPolicy(csp);
}
for (const auto& policy_and_type : headers) {
GetContentSecurityPolicy()->DidReceiveHeader(
policy_and_type.first, policy_and_type.second,
- kContentSecurityPolicyHeaderSourceHTTP);
+ network::mojom::ContentSecurityPolicySource::kHTTP);
}
}
@@ -444,7 +463,8 @@ void WorkerOrWorkletGlobalScope::FetchModuleScript(
const KURL& module_url_record,
const FetchClientSettingsObjectSnapshot& fetch_client_settings_object,
WorkerResourceTimingNotifier& resource_timing_notifier,
- mojom::RequestContextType destination,
+ mojom::RequestContextType context_type,
+ network::mojom::RequestDestination destination,
network::mojom::CredentialsMode credentials_mode,
ModuleScriptCustomFetchType custom_fetch_type,
ModuleTreeClient* client) {
@@ -455,6 +475,14 @@ void WorkerOrWorkletGlobalScope::FetchModuleScript(
String integrity_attribute;
// parser metadata is "not-parser-inserted,
ParserDisposition parser_state = kNotParserInserted;
+
+ RejectCoepUnsafeNone reject_coep_unsafe_none(false);
+ if (ShouldRejectCoepUnsafeNoneTopModuleScript() &&
+ destination == network::mojom::RequestDestination::kWorker) {
+ DCHECK(!base::FeatureList::IsEnabled(features::kPlzDedicatedWorker));
+ reject_coep_unsafe_none = RejectCoepUnsafeNone(true);
+ }
+
// credentials mode is credentials mode, and referrer policy is the empty
// string."
// TODO(domfarolino): Module worker scripts are fetched with kImportanceAuto.
@@ -462,10 +490,10 @@ void WorkerOrWorkletGlobalScope::FetchModuleScript(
// worker script tree" sets the script fetch options struct's "importance" to
// "auto". See https://github.com/whatwg/html/issues/3670 and
// https://crbug.com/821464.
- ScriptFetchOptions options(nonce, IntegrityMetadataSet(), integrity_attribute,
- parser_state, credentials_mode,
- network::mojom::ReferrerPolicy::kDefault,
- mojom::FetchImportanceMode::kImportanceAuto);
+ ScriptFetchOptions options(
+ nonce, IntegrityMetadataSet(), integrity_attribute, parser_state,
+ credentials_mode, network::mojom::ReferrerPolicy::kDefault,
+ mojom::FetchImportanceMode::kImportanceAuto, reject_coep_unsafe_none);
Modulator* modulator = Modulator::From(ScriptController()->GetScriptState());
// Step 3. "Perform the internal module script graph fetching procedure ..."
@@ -473,7 +501,7 @@ void WorkerOrWorkletGlobalScope::FetchModuleScript(
module_url_record,
CreateOutsideSettingsFetcher(fetch_client_settings_object,
resource_timing_notifier),
- destination, options, custom_fetch_type, client);
+ context_type, destination, options, custom_fetch_type, client);
}
void WorkerOrWorkletGlobalScope::SetDefersLoadingForResourceFetchers(
@@ -482,7 +510,8 @@ void WorkerOrWorkletGlobalScope::SetDefersLoadingForResourceFetchers(
resource_fetcher->SetDefersLoading(defers);
}
-void WorkerOrWorkletGlobalScope::Trace(blink::Visitor* visitor) {
+void WorkerOrWorkletGlobalScope::Trace(Visitor* visitor) {
+ visitor->Trace(security_context_);
visitor->Trace(inside_settings_resource_fetcher_);
visitor->Trace(resource_fetchers_);
visitor->Trace(subresource_filter_);
@@ -490,7 +519,6 @@ void WorkerOrWorkletGlobalScope::Trace(blink::Visitor* visitor) {
visitor->Trace(modulator_);
EventTargetWithInlineData::Trace(visitor);
ExecutionContext::Trace(visitor);
- SecurityContext::Trace(visitor);
}
} // namespace blink
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 9ae98db96e2..5b8588e87fa 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
@@ -13,13 +13,13 @@
#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.h"
-#include "third_party/blink/renderer/core/execution_context/security_context.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/web_feature_forward.h"
#include "third_party/blink/renderer/core/script/modulator.h"
#include "third_party/blink/renderer/core/workers/global_scope_creation_params.h"
#include "third_party/blink/renderer/core/workers/worker_clients.h"
#include "third_party/blink/renderer/core/workers/worker_navigator.h"
+#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
#include "third_party/blink/renderer/platform/scheduler/public/worker_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
@@ -38,17 +38,12 @@ class WorkerReportingProxy;
class WorkerThread;
class CORE_EXPORT WorkerOrWorkletGlobalScope : public EventTargetWithInlineData,
- public ExecutionContext,
- public SecurityContext {
+ public ExecutionContext {
public:
- using SecurityContext::GetSecurityOrigin;
- using SecurityContext::GetContentSecurityPolicy;
-
WorkerOrWorkletGlobalScope(
v8::Isolate*,
scoped_refptr<SecurityOrigin> origin,
Agent* agent,
- OffMainThreadWorkerScriptFetchOption,
const String& name,
const base::UnguessableToken& parent_devtools_token,
V8CacheOptions,
@@ -62,8 +57,8 @@ class CORE_EXPORT WorkerOrWorkletGlobalScope : public EventTargetWithInlineData,
const AtomicString& InterfaceName() const override;
// ScriptWrappable
- v8::Local<v8::Object> Wrap(v8::Isolate*,
- v8::Local<v8::Object> creation_context) final;
+ v8::Local<v8::Value> Wrap(v8::Isolate*,
+ v8::Local<v8::Object> creation_context) final;
v8::Local<v8::Object> AssociateWithWrapper(
v8::Isolate*,
const WrapperTypeInfo*,
@@ -76,6 +71,11 @@ class CORE_EXPORT WorkerOrWorkletGlobalScope : public EventTargetWithInlineData,
void DisableEval(const String& error_message) final;
bool CanExecuteScripts(ReasonForCallingCanExecuteScripts) final;
+ SecurityContext& GetSecurityContext() final { return security_context_; }
+ const SecurityContext& GetSecurityContext() const final {
+ return security_context_;
+ }
+
// Returns true when the WorkerOrWorkletGlobalScope is closing (e.g. via
// WorkerGlobalScope#close() method). If this returns true, the worker is
// going to be shutdown after the current task execution. Globals that
@@ -103,6 +103,14 @@ class CORE_EXPORT WorkerOrWorkletGlobalScope : public EventTargetWithInlineData,
// Returns nullptr if this global scope is a WorkletGlobalScope
virtual WorkerNavigator* navigator() const { return nullptr; }
+ // Returns true when we should reject a response without
+ // cross-origin-embedder-policy: require-corp.
+ // TODO(crbug.com/1064920): Remove this once PlzDedicatedWorker ships.
+ virtual RejectCoepUnsafeNone ShouldRejectCoepUnsafeNoneTopModuleScript()
+ const {
+ return RejectCoepUnsafeNone(false);
+ }
+
// Returns the resource fetcher for subresources (a.k.a. inside settings
// resource fetcher). See core/workers/README.md for details.
ResourceFetcher* Fetcher() const override;
@@ -140,15 +148,10 @@ class CORE_EXPORT WorkerOrWorkletGlobalScope : public EventTargetWithInlineData,
WorkerReportingProxy& ReportingProxy() { return reporting_proxy_; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(TaskType) override;
- OffMainThreadWorkerScriptFetchOption GetOffMainThreadWorkerScriptFetchOption()
- const {
- return off_main_thread_fetch_option_;
- }
-
void ApplySandboxFlags(SandboxFlags mask);
void SetDefersLoadingForResourceFetchers(bool defers);
@@ -165,7 +168,8 @@ class CORE_EXPORT WorkerOrWorkletGlobalScope : public EventTargetWithInlineData,
void FetchModuleScript(const KURL& module_url_record,
const FetchClientSettingsObjectSnapshot&,
WorkerResourceTimingNotifier&,
- mojom::RequestContextType destination,
+ mojom::RequestContextType context_type,
+ network::mojom::RequestDestination destination,
network::mojom::CredentialsMode,
ModuleScriptCustomFetchType,
ModuleTreeClient*);
@@ -174,6 +178,15 @@ class CORE_EXPORT WorkerOrWorkletGlobalScope : public EventTargetWithInlineData,
return outside_content_security_policy_headers_;
}
+ void SetIsOfflineMode(bool is_offline_mode) {
+ DCHECK(web_worker_fetch_context_);
+ web_worker_fetch_context_->SetIsOfflineMode(is_offline_mode);
+ }
+
+ WebWorkerFetchContext* web_worker_fetch_context() const {
+ return web_worker_fetch_context_.get();
+ }
+
private:
void InitializeWebFetchContextIfNeeded();
ResourceFetcher* CreateFetcherInternal(const FetchClientSettingsObject&,
@@ -182,7 +195,8 @@ class CORE_EXPORT WorkerOrWorkletGlobalScope : public EventTargetWithInlineData,
bool web_fetch_context_initialized_ = false;
- const OffMainThreadWorkerScriptFetchOption off_main_thread_fetch_option_;
+ SecurityContext security_context_;
+
const String name_;
const base::UnguessableToken parent_devtools_token_;
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 e579547da62..d11b948c6de 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_thread.cc
+++ b/chromium/third_party/blink/renderer/core/workers/worker_thread.cc
@@ -127,7 +127,7 @@ class WorkerThread::RefCountedWaitableEvent
// A class that is passed into V8 Interrupt and via a PostTask. Once both have
// run this object will be destroyed in
// PauseOrFreezeWithInterruptDataOnWorkerThread. The V8 API only takes a raw ptr
-// otherwise this could have been done with base::Bind and ref counted objects.
+// otherwise this could have been done with WTF::Bind and ref counted objects.
class WorkerThread::InterruptData {
public:
InterruptData(WorkerThread* worker_thread, mojom::FrameLifecycleState state)
@@ -231,7 +231,8 @@ void WorkerThread::FetchAndRunModuleScript(
std::unique_ptr<CrossThreadFetchClientSettingsObjectData>
outside_settings_object_data,
WorkerResourceTimingNotifier* outside_resource_timing_notifier,
- network::mojom::CredentialsMode credentials_mode) {
+ network::mojom::CredentialsMode credentials_mode,
+ RejectCoepUnsafeNone reject_coep_unsafe_none) {
DCHECK_CALLED_ON_VALID_THREAD(parent_thread_checker_);
PostCrossThreadTask(
*GetTaskRunner(TaskType::kDOMManipulation), FROM_HERE,
@@ -240,7 +241,7 @@ void WorkerThread::FetchAndRunModuleScript(
CrossThreadUnretained(this), script_url,
WTF::Passed(std::move(outside_settings_object_data)),
WrapCrossThreadPersistent(outside_resource_timing_notifier),
- credentials_mode));
+ credentials_mode, reject_coep_unsafe_none.value()));
}
void WorkerThread::Pause() {
@@ -338,7 +339,14 @@ void WorkerThread::DidProcessTask(const base::PendingTask& pending_task) {
// This WorkerThread will eventually be requested to terminate.
GetWorkerReportingProxy().DidCloseWorkerGlobalScope();
- // Stop further worker tasks to run after this point.
+ // Stop further worker tasks to run after this point based on the spec:
+ // https://html.spec.whatwg.org/C/#close-a-worker
+ //
+ // "To close a worker, given a workerGlobal, run these steps:"
+ // Step 1: "Discard any tasks that have been added to workerGlobal's event
+ // loop's task queues."
+ // Step 2: "Set workerGlobal's closing flag to true. (This prevents any
+ // further tasks from being queued.)"
PrepareForShutdownOnWorkerThread();
} else if (IsForciblyTerminated()) {
// The script has been terminated forcibly, which means we need to
@@ -650,7 +658,8 @@ void WorkerThread::FetchAndRunModuleScriptOnWorkerThread(
std::unique_ptr<CrossThreadFetchClientSettingsObjectData>
outside_settings_object,
WorkerResourceTimingNotifier* outside_resource_timing_notifier,
- network::mojom::CredentialsMode credentials_mode) {
+ network::mojom::CredentialsMode credentials_mode,
+ bool reject_coep_unsafe_none) {
if (!outside_resource_timing_notifier) {
outside_resource_timing_notifier =
MakeGarbageCollected<NullWorkerResourceTimingNotifier>();
@@ -663,7 +672,8 @@ void WorkerThread::FetchAndRunModuleScriptOnWorkerThread(
script_url,
*MakeGarbageCollected<FetchClientSettingsObjectSnapshot>(
std::move(outside_settings_object)),
- *outside_resource_timing_notifier, credentials_mode);
+ *outside_resource_timing_notifier, credentials_mode,
+ RejectCoepUnsafeNone(reject_coep_unsafe_none));
}
void WorkerThread::PrepareForShutdownOnWorkerThread() {
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_thread.h b/chromium/third_party/blink/renderer/core/workers/worker_thread.h
index 1817fd49db0..6dbb1009c9e 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_thread.h
+++ b/chromium/third_party/blink/renderer/core/workers/worker_thread.h
@@ -41,6 +41,7 @@
#include "third_party/blink/renderer/core/workers/parent_execution_context_task_runners.h"
#include "third_party/blink/renderer/core/workers/worker_backing_thread_startup_data.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
@@ -128,7 +129,9 @@ class CORE_EXPORT WorkerThread : public Thread::TaskObserver {
std::unique_ptr<CrossThreadFetchClientSettingsObjectData>
outside_settings_object_data,
WorkerResourceTimingNotifier* outside_resource_timing_notifier,
- network::mojom::CredentialsMode);
+ network::mojom::CredentialsMode,
+ RejectCoepUnsafeNone reject_coep_unsafe_none =
+ RejectCoepUnsafeNone(false));
// Posts a task to the worker thread to close the global scope and terminate
// the underlying thread. This task may be blocked by JavaScript execution on
@@ -341,9 +344,38 @@ class CORE_EXPORT WorkerThread : public Thread::TaskObserver {
std::unique_ptr<CrossThreadFetchClientSettingsObjectData>
outside_settings_object,
WorkerResourceTimingNotifier* outside_resource_timing_notifier,
- network::mojom::CredentialsMode);
-
- // These are called in this order during worker thread termination.
+ network::mojom::CredentialsMode,
+ bool reject_coep_unsafe_none);
+
+ // PrepareForShutdownOnWorkerThread() notifies that the context will be
+ // destroyed, discards queued tasks to prevent running further tasks, and
+ // initiates termination of nested workers. It runs on the worker thread. It
+ // can be called due to the parent thread posting a task to run it on the
+ // worker thread, or the worker thread calling it itself synchronously.
+ //
+ // PerformShutdownOnWorkerThread() destroys the global scope, and notifies the
+ // parent thread of completion of worker shutdown. A call of this function can
+ // be postponed until all nested workers are terminated. It runs on the worker
+ // thread. It can be called due to the parent thread posting a task to run it
+ // on the worker thread, or the worker thread calling it itself synchronously
+ // after all nested workers are terminated.
+ //
+ // These are called in this order during worker shutdown.
+ //
+ // The reason why worker shutdown is separated into these 2 functions:
+ // Workers can simultaneously be requested to terminate for various reasons.
+ // To serialize the termination requests, worker shutdown is supposed to be
+ // initiated from the parent thread (i.e., Terminate()). On the other hand,
+ // queued tasks etc must be discarded as soon as possible after shutdown is
+ // requested to prevent running further tasks. To be specific, when close() is
+ // called on the worker global scope, queued tasks must be discarded soon
+ // before worker shutdown is formally requested via the parent thread. The
+ // HTML spec defines this behavior (see spec comments in DidProcessTask()).
+ // To achieve this, the worker thread runs PrepareForShutdownOnWorkerThread()
+ // immediately after the task that called close() (see DidProcessTask()), and
+ // then posts a task to the parent thread to request termination. In addition
+ // to that, separate functions are useful for waiting until all nested workers
+ // are terminated before the parent thread shut down.
void PrepareForShutdownOnWorkerThread() LOCKS_EXCLUDED(mutex_);
void PerformShutdownOnWorkerThread() LOCKS_EXCLUDED(mutex_);
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_thread_test.cc b/chromium/third_party/blink/renderer/core/workers/worker_thread_test.cc
index 2023f78d5ba..a0da94e16c1 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_thread_test.cc
+++ b/chromium/third_party/blink/renderer/core/workers/worker_thread_test.cc
@@ -381,13 +381,13 @@ TEST_F(WorkerThreadTest, Terminate_WhileDebuggerTaskIsRunningOnInitialization) {
EXPECT_CALL(*reporting_proxy_, DidTerminateWorkerThread()).Times(1);
Vector<CSPHeaderAndType> headers{
- {"contentSecurityPolicy", kContentSecurityPolicyHeaderTypeReport}};
+ {"contentSecurityPolicy",
+ network::mojom::ContentSecurityPolicyType::kReport}};
auto global_scope_creation_params =
std::make_unique<GlobalScopeCreationParams>(
- KURL("http://fake.url/"), mojom::ScriptType::kClassic,
- OffMainThreadWorkerScriptFetchOption::kDisabled,
- "fake global scope name", "fake user agent",
+ KURL("http://fake.url/"), mojom::blink::ScriptType::kClassic,
+ "fake global scope name", "fake user agent", UserAgentMetadata(),
nullptr /* web_worker_fetch_context */, headers,
network::mojom::ReferrerPolicy::kDefault, security_origin_.get(),
false /* starter_secure_context */,
@@ -492,8 +492,7 @@ TEST_F(WorkerThreadTest, Terminate_WhileDebuggerTaskIsRunning) {
EXPECT_EQ(ExitCode::kGracefullyTerminated, GetExitCode());
}
-// Disabled due to flakiness: https://crbug.com/935231
-TEST_F(WorkerThreadTest, DISABLED_TerminateWorkerWhileChildIsLoading) {
+TEST_F(WorkerThreadTest, TerminateWorkerWhileChildIsLoading) {
ExpectReportingCalls();
Start();
worker_thread_->WaitForInit();
diff --git a/chromium/third_party/blink/renderer/core/workers/worker_thread_test_helper.h b/chromium/third_party/blink/renderer/core/workers/worker_thread_test_helper.h
index 520769414d6..a378d77a933 100644
--- a/chromium/third_party/blink/renderer/core/workers/worker_thread_test_helper.h
+++ b/chromium/third_party/blink/renderer/core/workers/worker_thread_test_helper.h
@@ -69,7 +69,7 @@ class FakeWorkerGlobalScope : public WorkerGlobalScope {
int64_t appcache_id) override {
InitializeURL(response_url);
SetReferrerPolicy(response_referrer_policy);
- SetAddressSpace(response_address_space);
+ GetSecurityContext().SetAddressSpace(response_address_space);
// These should be called after SetAddressSpace() to correctly override the
// address space by the "treat-as-public-address" CSP directive.
@@ -93,9 +93,11 @@ class FakeWorkerGlobalScope : public WorkerGlobalScope {
const KURL& module_url_record,
const FetchClientSettingsObjectSnapshot& outside_settings_object,
WorkerResourceTimingNotifier& outside_resource_timing_notifier,
- network::mojom::CredentialsMode) override {
+ network::mojom::CredentialsMode,
+ RejectCoepUnsafeNone reject_coep_unsafe_none) override {
NOTREACHED();
}
+ bool IsOffMainThreadScriptFetchDisabled() override { return true; }
void ExceptionThrown(ErrorEvent*) override {}
};
@@ -121,11 +123,11 @@ class WorkerThreadForTest : public WorkerThread {
const KURL& script_url = KURL("http://fake.url/"),
WorkerClients* worker_clients = nullptr) {
Vector<CSPHeaderAndType> headers{
- {"contentSecurityPolicy", kContentSecurityPolicyHeaderTypeReport}};
+ {"contentSecurityPolicy",
+ network::mojom::ContentSecurityPolicyType::kReport}};
auto creation_params = std::make_unique<GlobalScopeCreationParams>(
- script_url, mojom::ScriptType::kClassic,
- OffMainThreadWorkerScriptFetchOption::kDisabled,
- "fake global scope name", "fake user agent",
+ script_url, mojom::blink::ScriptType::kClassic,
+ "fake global scope name", "fake user agent", UserAgentMetadata(),
nullptr /* web_worker_fetch_context */, headers,
network::mojom::ReferrerPolicy::kDefault, security_origin,
false /* starter_secure_context */,
diff --git a/chromium/third_party/blink/renderer/core/workers/worklet.cc b/chromium/third_party/blink/renderer/core/workers/worklet.cc
index 1195b520b15..0659d33f6c2 100644
--- a/chromium/third_party/blink/renderer/core/workers/worklet.cc
+++ b/chromium/third_party/blink/renderer/core/workers/worklet.cc
@@ -4,12 +4,14 @@
#include "third_party/blink/renderer/core/workers/worklet.h"
+#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "services/network/public/mojom/fetch_api.mojom-blink.h"
#include "third_party/blink/public/mojom/web_feature/web_feature.mojom-blink.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_worklet_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/fetch/request.h"
@@ -25,7 +27,7 @@
namespace blink {
Worklet::Worklet(Document* document)
- : ContextLifecycleObserver(document),
+ : ExecutionContextLifecycleObserver(document),
module_responses_map_(MakeGarbageCollected<WorkletModuleResponsesMap>()) {
DCHECK(IsMainThread());
}
@@ -92,7 +94,7 @@ ScriptPromise Worklet::addModule(ScriptState* script_state,
return promise;
}
-void Worklet::ContextDestroyed(ExecutionContext* execution_context) {
+void Worklet::ContextDestroyed() {
DCHECK(IsMainThread());
module_responses_map_->Dispose();
for (const auto& proxy : proxies_)
@@ -125,9 +127,9 @@ void Worklet::FetchAndInvokeScript(const KURL& module_url_record,
return;
// Step 6: "Let credentialOptions be the credentials member of options."
- network::mojom::CredentialsMode credentials_mode;
- bool result = Request::ParseCredentialsMode(credentials, &credentials_mode);
- DCHECK(result);
+ base::Optional<network::mojom::CredentialsMode> credentials_mode =
+ Request::ParseCredentialsMode(credentials);
+ DCHECK(credentials_mode);
// Step 7: "Let outsideSettings be the relevant settings object of this."
auto* outside_settings_object =
@@ -175,7 +177,7 @@ void Worklet::FetchAndInvokeScript(const KURL& module_url_record,
// moduleResponsesMap is already passed via CreateGlobalScope().
// TODO(nhiroki): Queue a task instead of executing this here.
for (const auto& proxy : proxies_) {
- proxy->FetchAndInvokeScript(module_url_record, credentials_mode,
+ proxy->FetchAndInvokeScript(module_url_record, *credentials_mode,
*outside_settings_object,
*outside_resource_timing_notifier,
outside_settings_task_runner, pending_tasks);
@@ -187,12 +189,12 @@ wtf_size_t Worklet::SelectGlobalScope() {
return 0u;
}
-void Worklet::Trace(blink::Visitor* visitor) {
+void Worklet::Trace(Visitor* visitor) {
visitor->Trace(proxies_);
visitor->Trace(module_responses_map_);
visitor->Trace(pending_tasks_set_);
ScriptWrappable::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/workers/worklet.h b/chromium/third_party/blink/renderer/core/workers/worklet.h
index e37bb631ef5..ecf4340a6c4 100644
--- a/chromium/third_party/blink/renderer/core/workers/worklet.h
+++ b/chromium/third_party/blink/renderer/core/workers/worklet.h
@@ -8,23 +8,23 @@
#include "base/macros.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/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/workers/worklet_global_scope_proxy.h"
#include "third_party/blink/renderer/core/workers/worklet_module_responses_map.h"
-#include "third_party/blink/renderer/core/workers/worklet_options.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
class Document;
+class WorkletOptions;
// This is the base implementation of Worklet interface defined in the spec:
// https://drafts.css-houdini.org/worklets/#worklet
// Although some worklets run off the main thread, this must be created and
// destroyed on the main thread.
class CORE_EXPORT Worklet : public ScriptWrappable,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(Worklet);
USING_PRE_FINALIZER(Worklet, Dispose);
@@ -41,8 +41,8 @@ class CORE_EXPORT Worklet : public ScriptWrappable,
const WorkletOptions*,
ExceptionState&);
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
// Returns true if there is ongoing module loading tasks. BaseAudioContext
// uses this check to keep itself alive until pending tasks are resolved.
@@ -51,7 +51,7 @@ class CORE_EXPORT Worklet : public ScriptWrappable,
// Called by WorkletPendingTasks to notify the Worklet.
void FinishPendingTasks(WorkletPendingTasks*);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
explicit Worklet(Document*);
diff --git a/chromium/third_party/blink/renderer/core/workers/worklet.idl b/chromium/third_party/blink/renderer/core/workers/worklet.idl
index 91fe709474d..cb4571e9baf 100644
--- a/chromium/third_party/blink/renderer/core/workers/worklet.idl
+++ b/chromium/third_party/blink/renderer/core/workers/worklet.idl
@@ -7,5 +7,5 @@
[
SecureContext
] interface Worklet {
- [CallWith=ScriptState, RaisesException] Promise<void> addModule(USVString moduleURL, optional WorkletOptions options);
+ [CallWith=ScriptState, RaisesException] Promise<void> addModule(USVString moduleURL, optional WorkletOptions options = {});
};
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 8076e3c4162..6e760135057 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
@@ -71,7 +71,6 @@ WorkletGlobalScope::WorkletGlobalScope(
// TODO(tzik): Assign an Agent for Worklets after
// NonMainThreadScheduler gets ready to run microtasks.
agent,
- creation_params->off_main_thread_fetch_option,
creation_params->global_scope_name,
creation_params->parent_devtools_token,
creation_params->v8_cache_options,
@@ -134,16 +133,6 @@ ExecutionContext* WorkletGlobalScope::GetExecutionContext() const {
return const_cast<WorkletGlobalScope*>(this);
}
-bool WorkletGlobalScope::IsSecureContext(String& error_message) const {
- // Until there are APIs that are available in worklets and that
- // require a privileged context test that checks ancestors, just do
- // a simple check here.
- if (GetSecurityOrigin()->IsPotentiallyTrustworthy())
- return true;
- error_message = GetSecurityOrigin()->IsPotentiallyTrustworthyErrorMessage();
- return false;
-}
-
bool WorkletGlobalScope::IsContextThread() const {
if (IsMainThreadWorkletGlobalScope())
return IsMainThread();
@@ -240,6 +229,7 @@ void WorkletGlobalScope::FetchAndInvokeScript(
auto destination = mojom::RequestContextType::SCRIPT;
FetchModuleScript(module_url_record, outside_settings_object,
outside_resource_timing_notifier, destination,
+ network::mojom::RequestDestination::kScript,
credentials_mode,
ModuleScriptCustomFetchType::kWorkletAddModule, client);
}
@@ -268,7 +258,7 @@ void WorkletGlobalScope::BindContentSecurityPolicyToExecutionContext() {
GetContentSecurityPolicy()->SetupSelf(*document_security_origin_);
}
-void WorkletGlobalScope::Trace(blink::Visitor* visitor) {
+void WorkletGlobalScope::Trace(Visitor* visitor) {
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 89ab386c637..55db96228c7 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
@@ -57,9 +57,6 @@ class CORE_EXPORT WorkletGlobalScope
const KURL& BaseURL() const final { return url_; }
KURL CompleteURL(const String&) const final;
String UserAgent() const final { return user_agent_; }
- SecurityContext& GetSecurityContext() final { return *this; }
- const SecurityContext& GetSecurityContext() const final { return *this; }
- bool IsSecureContext(String& error_message) const final;
bool IsContextThread() const final;
void AddConsoleMessageImpl(ConsoleMessage*, bool discard_duplicates) final;
void ExceptionThrown(ErrorEvent*) final;
@@ -115,7 +112,7 @@ class CORE_EXPORT WorkletGlobalScope
// document.
bool DocumentSecureContext() const { return document_secure_context_; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 12f66911dc9..f217ebf92cb 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(blink::Visitor*) {}
+ void Trace(Visitor*) {}
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 5e981e9fcbb..6e33782257a 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
@@ -8,8 +8,10 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
#include "third_party/blink/renderer/core/loader/modulescript/module_script_creation_params.h"
+#include "third_party/blink/renderer/core/loader/modulescript/module_script_loader.h"
#include "third_party/blink/renderer/core/loader/modulescript/worklet_module_script_fetcher.h"
#include "third_party/blink/renderer/core/script/modulator.h"
+#include "third_party/blink/renderer/core/testing/dummy_modulator.h"
#include "third_party/blink/renderer/platform/loader/testing/fetch_testing_platform_support.h"
#include "third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h"
#include "third_party/blink/renderer/platform/loader/testing/test_loader_factory.h"
@@ -69,11 +71,11 @@ class WorkletModuleResponsesMapTest : public testing::Test {
// TODO(nhiroki): Specify worklet-specific request context (e.g.,
// "paintworklet").
resource_request.SetRequestContext(mojom::RequestContextType::SCRIPT);
- FetchParameters fetch_params(resource_request);
+ FetchParameters fetch_params(std::move(resource_request));
WorkletModuleScriptFetcher* module_fetcher =
- MakeGarbageCollected<WorkletModuleScriptFetcher>(map_.Get());
+ MakeGarbageCollected<WorkletModuleScriptFetcher>(
+ map_.Get(), ModuleScriptLoader::CreatePassKeyForTests());
module_fetcher->Fetch(fetch_params, fetcher_.Get(),
- nullptr /* modulator_for_built_in_modules */,
ModuleGraphLevel::kTopLevelModuleFetch, client);
}
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 00c0eaf8334..6478a7a6a86 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(blink::Visitor* visitor) {
+void WorkletModuleTreeClient::Trace(Visitor* visitor) {
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 deb69727b20..47eb608031f 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 2b967c9669e..4c41608d98e 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(blink::Visitor* visitor) {
+void WorkletPendingTasks::Trace(Visitor* visitor) {
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 8fcfa797ef8..d70936fc7ed 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(blink::Visitor*);
+ virtual void Trace(Visitor*);
private:
// The number of pending tasks. -1 indicates these tasks are aborted and
diff --git a/chromium/third_party/blink/renderer/core/xml/BUILD.gn b/chromium/third_party/blink/renderer/core/xml/BUILD.gn
index 9adae5bcdde..d7d5fcf3e28 100644
--- a/chromium/third_party/blink/renderer/core/xml/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/xml/BUILD.gn
@@ -5,6 +5,7 @@
import("//third_party/blink/renderer/core/core.gni")
blink_core_sources("xml") {
+ deps = [ ":xpath_generated" ]
sources = [
"document_xml_tree_viewer.cc",
"document_xml_tree_viewer.h",
@@ -38,7 +39,6 @@ blink_core_sources("xml") {
"xpath_node_set.cc",
"xpath_node_set.h",
"xpath_ns_resolver.h",
- "xpath_parser.cc",
"xpath_parser.h",
"xpath_path.cc",
"xpath_path.h",
@@ -64,11 +64,17 @@ blink_core_sources("xml") {
"xslt_unicode_sort.cc",
"xslt_unicode_sort.h",
]
+}
- # XCode's ancient bison (v2.3 from 2006) prevents us from updating a
- # deprecated bison directive. This will silence the warning.
- # See https://crbug.com/1028421.
- if (!is_mac) {
- cflags = [ "-Wno-deprecated" ]
+# Chromium-style plugin produces an error for xpath_grammar_generated.h.
+# Disable the plugin for sources including xpath_grammar_generated.h.
+blink_core_sources("xpath_generated") {
+ sources = [
+ "xpath_grammar_generated.cc",
+ "xpath_grammar_generated.h",
+ "xpath_parser.cc",
+ ]
+ if (is_clang) {
+ configs -= [ "//build/config/clang:find_bad_constructs" ]
}
}
diff --git a/chromium/third_party/blink/renderer/core/xml/DocumentXMLTreeViewer.css b/chromium/third_party/blink/renderer/core/xml/DocumentXMLTreeViewer.css
index 6e0a0d9fdb6..3f4cc214aae 100644
--- a/chromium/third_party/blink/renderer/core/xml/DocumentXMLTreeViewer.css
+++ b/chromium/third_party/blink/renderer/core/xml/DocumentXMLTreeViewer.css
@@ -9,7 +9,11 @@ div.header {
margin: 10px;
}
-div.collapsible > div.hidden {
+div.folder > div.hidden {
+ display:none;
+}
+
+div.folder > span.hidden {
display:none;
}
@@ -24,14 +28,15 @@ div.collapsible > div.hidden {
display: none;
}
-.collapsible-content {
+.opened {
margin-left: 1em;
}
+
.comment {
white-space: pre;
}
-.button {
+.folder-button {
-webkit-user-select: none;
cursor: pointer;
display: inline-block;
@@ -42,12 +47,12 @@ div.collapsible > div.hidden {
vertical-align: bottom;
}
-.collapse-button {
+.fold {
background: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='%23909090' width='10' height='10'><path d='M0 0 L8 0 L4 7 Z'/></svg>");
height: 10px;
}
-.expand-button {
+.open {
background: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='%23909090' width='10' height='10'><path d='M0 0 L0 8 L7 4 Z'/></svg>");
height: 10px;
}
diff --git a/chromium/third_party/blink/renderer/core/xml/DocumentXMLTreeViewer.js b/chromium/third_party/blink/renderer/core/xml/DocumentXMLTreeViewer.js
index f821003fb08..ee14e829ccf 100644
--- a/chromium/third_party/blink/renderer/core/xml/DocumentXMLTreeViewer.js
+++ b/chromium/third_party/blink/renderer/core/xml/DocumentXMLTreeViewer.js
@@ -4,374 +4,312 @@
"use strict";
-var nodeParentPairs = [];
var tree;
function prepareWebKitXMLViewer()
{
- var html = createHTMLElement('html');
- var head = createHTMLElement('head');
- html.appendChild(head);
- var style = createHTMLElement('style');
- style.id = 'xml-viewer-style';
- head.appendChild(style);
- var body = createHTMLElement('body');
- html.appendChild(body);
- var sourceXML = createHTMLElement('div');
- sourceXML.id = 'webkit-xml-viewer-source-xml';
- body.appendChild(sourceXML);
-
- var child;
- while (child = document.firstChild) {
- document.removeChild(child);
- if (child.nodeType != Node.DOCUMENT_TYPE_NODE)
- sourceXML.appendChild(child);
- }
- document.appendChild(html);
-
- var header = createHTMLElement('div');
- body.appendChild(header);
- header.classList.add('header');
- var headerSpan = createHTMLElement('span');
- header.appendChild(headerSpan);
- headerSpan.textContent = "This XML file does not appear to have any style information " +
- "associated with it. The document tree is shown below.";
- header.appendChild(createHTMLElement('br'));
-
- tree = createHTMLElement('div');
- body.appendChild(tree);
- tree.classList.add('pretty-print');
- window.onload = sourceXMLLoaded;
+ var html = createHTMLElement('html');
+ var head = createHTMLElement('head');
+ html.appendChild(head);
+ var style = createHTMLElement('style');
+ style.id = 'xml-viewer-style';
+ head.appendChild(style);
+ var body = createHTMLElement('body');
+ html.appendChild(body);
+ var sourceXML = createHTMLElement('div');
+ sourceXML.id = 'webkit-xml-viewer-source-xml';
+ body.appendChild(sourceXML);
+
+ var child;
+ while (child = document.firstChild) {
+ document.removeChild(child);
+ if (child.nodeType != Node.DOCUMENT_TYPE_NODE)
+ sourceXML.appendChild(child);
+ }
+ document.appendChild(html);
+
+ var header = createHTMLElement('div');
+ body.appendChild(header);
+ header.classList.add('header');
+ var headerSpan = createHTMLElement('span');
+ header.appendChild(headerSpan);
+ headerSpan.textContent =
+ 'This XML file does not appear to have any style information ' +
+ 'associated with it. The document tree is shown below.';
+ header.appendChild(createHTMLElement('br'));
+
+ tree = createHTMLElement('div');
+ body.appendChild(tree);
+ tree.classList.add('pretty-print');
+ window.onload = sourceXMLLoaded;
}
function sourceXMLLoaded()
{
- var sourceXML = document.getElementById('webkit-xml-viewer-source-xml');
- if (!sourceXML)
- return; // Stop if some XML tree extension is already processing this document
-
- for (var child = sourceXML.firstChild; child; child = child.nextSibling)
- nodeParentPairs.push({parentElement: tree, node: child});
+ var sourceXML = document.getElementById('webkit-xml-viewer-source-xml');
+ if (!sourceXML)
+ return; // Stop if some XML tree extension is already processing this
+ // document
- for (var i = 0; i < nodeParentPairs.length; i++)
- processNode(nodeParentPairs[i].parentElement, nodeParentPairs[i].node);
+ for (var child = sourceXML.firstChild; child; child = child.nextSibling)
+ processNode(tree, child);
- initButtons();
+ initButtons();
- return false;
+ return false;
}
// Tree processing.
function processNode(parentElement, node)
{
- var map = processNode.processorsMap;
- if (!map) {
- map = {};
- processNode.processorsMap = map;
- map[Node.PROCESSING_INSTRUCTION_NODE] = processProcessingInstruction;
- map[Node.ELEMENT_NODE] = processElement;
- map[Node.COMMENT_NODE] = processComment;
- map[Node.TEXT_NODE] = processText;
- map[Node.CDATA_SECTION_NODE] = processCDATA;
- }
- if (processNode.processorsMap[node.nodeType])
- processNode.processorsMap[node.nodeType].call(this, parentElement, node);
+ switch (node.nodeType) {
+ case Node.PROCESSING_INSTRUCTION_NODE:
+ processProcessingInstruction(parentElement, node);
+ break;
+ case Node.ELEMENT_NODE:
+ processElement(parentElement, node);
+ break;
+ case Node.COMMENT_NODE:
+ processComment(parentElement, node);
+ break;
+ case Node.TEXT_NODE:
+ processText(parentElement, node);
+ break;
+ case Node.CDATA_SECTION_NODE:
+ processCDATA(parentElement, node);
+ break;
+ default:
+ // No-op for unsupported node types e.g. Node.DOCUMENT_FRAGMENT_NODE.
+ }
}
function processElement(parentElement, node)
{
- if (!node.firstChild)
- processEmptyElement(parentElement, node);
- else {
- var child = node.firstChild;
- if (child.nodeType == Node.TEXT_NODE && isShort(child.nodeValue) && !child.nextSibling)
- processShortTextOnlyElement(parentElement, node);
- else
- processComplexElement(parentElement, node);
- }
+ if (!node.firstChild)
+ processEmptyElement(parentElement, node);
+ else {
+ var child = node.firstChild;
+ if (child.nodeType == Node.TEXT_NODE && !child.nextSibling)
+ processShortTextOnlyElement(parentElement, node);
+ else
+ processComplexElement(parentElement, node);
+ }
}
function processEmptyElement(parentElement, node)
{
- var line = createLine();
- line.appendChild(createTag(node, false, true));
- parentElement.appendChild(line);
+ var line = createLine();
+ line.appendChild(createTag(node, false, true));
+ parentElement.appendChild(line);
}
function processShortTextOnlyElement(parentElement, node)
{
- var line = createLine();
- line.appendChild(createTag(node, false, false));
- for (var child = node.firstChild; child; child = child.nextSibling)
- line.appendChild(createText(child.nodeValue));
- line.appendChild(createTag(node, true, false));
- parentElement.appendChild(line);
+ var line = createLine();
+ line.appendChild(createTag(node, false, false));
+ for (var child = node.firstChild; child; child = child.nextSibling)
+ line.appendChild(createText(child.nodeValue));
+ line.appendChild(createTag(node, true, false));
+ parentElement.appendChild(line);
}
function processComplexElement(parentElement, node)
{
- var collapsible = createCollapsible();
+ var folder = createFolder();
+ folder.start.appendChild(createTag(node, false, false));
+
+ for (var child = node.firstChild; child; child = child.nextSibling)
+ processNode(folder.openedContent, child);
- collapsible.expanded.start.appendChild(createTag(node, false, false));
- for (var child = node.firstChild; child; child = child.nextSibling)
- nodeParentPairs.push({parentElement: collapsible.expanded.content, node: child});
- collapsible.expanded.end.appendChild(createTag(node, true, false));
+ folder.end.appendChild(createTag(node, true, false));
- collapsible.collapsed.content.appendChild(createTag(node, false, false));
- collapsible.collapsed.content.appendChild(createText('...'));
- collapsible.collapsed.content.appendChild(createTag(node, true, false));
- parentElement.appendChild(collapsible);
+ parentElement.appendChild(folder);
}
function processComment(parentElement, node)
{
- if (isShort(node.nodeValue)) {
- var line = createLine();
- line.appendChild(createComment('<!-- ' + node.nodeValue + ' -->'));
- parentElement.appendChild(line);
- } else {
- var collapsible = createCollapsible();
-
- collapsible.expanded.start.appendChild(createComment('<!--'));
- collapsible.expanded.content.appendChild(createComment(node.nodeValue));
- collapsible.expanded.end.appendChild(createComment('-->'));
-
- collapsible.collapsed.content.appendChild(createComment('<!--'));
- collapsible.collapsed.content.appendChild(createComment('...'));
- collapsible.collapsed.content.appendChild(createComment('-->'));
- parentElement.appendChild(collapsible);
- }
+ var line = createLine();
+ line.appendChild(createComment('<!-- ' + node.nodeValue + ' -->'));
+ parentElement.appendChild(line);
}
function processCDATA(parentElement, node)
{
- if (isShort(node.nodeValue)) {
- var line = createLine();
- line.appendChild(createText('<![CDATA[ ' + node.nodeValue + ' ]]>'));
- parentElement.appendChild(line);
- } else {
- var collapsible = createCollapsible();
-
- collapsible.expanded.start.appendChild(createText('<![CDATA['));
- collapsible.expanded.content.appendChild(createText(node.nodeValue));
- collapsible.expanded.end.appendChild(createText(']]>'));
-
- collapsible.collapsed.content.appendChild(createText('<![CDATA['));
- collapsible.collapsed.content.appendChild(createText('...'));
- collapsible.collapsed.content.appendChild(createText(']]>'));
- parentElement.appendChild(collapsible);
- }
+ var line = createLine();
+ line.appendChild(createText('<![CDATA[ ' + node.nodeValue + ' ]]>'));
+ parentElement.appendChild(line);
}
function processProcessingInstruction(parentElement, node)
{
- if (isShort(node.nodeValue)) {
- var line = createLine();
- line.appendChild(createComment('<?' + node.nodeName + ' ' + node.nodeValue + '?>'));
- parentElement.appendChild(line);
- } else {
- var collapsible = createCollapsible();
-
- collapsible.expanded.start.appendChild(createComment('<?' + node.nodeName));
- collapsible.expanded.content.appendChild(createComment(node.nodeValue));
- collapsible.expanded.end.appendChild(createComment('?>'));
-
- collapsible.collapsed.content.appendChild(createComment('<?' + node.nodeName));
- collapsible.collapsed.content.appendChild(createComment('...'));
- collapsible.collapsed.content.appendChild(createComment('?>'));
- parentElement.appendChild(collapsible);
- }
+ var line = createLine();
+ line.appendChild(
+ createComment('<?' + node.nodeName + ' ' + node.nodeValue + '?>'));
+ parentElement.appendChild(line);
}
function processText(parentElement, node)
{
- parentElement.appendChild(createText(node.nodeValue));
+ parentElement.appendChild(createText(node.nodeValue));
}
-// Processing utils.
+// Tree rendering.
-function trim(value)
+function createHTMLElement(elementName)
{
- return value.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+ return document.createElementNS('http://www.w3.org/1999/xhtml', elementName)
}
-function isShort(value)
+function createFolder()
{
- return trim(value).length <= 50;
-}
+ var folder = createHTMLElement('div');
+ folder.classList.add('folder');
-// Tree rendering.
+ folder.start = createLine();
+ folder.start.appendChild(createFolderButton());
+ folder.appendChild(folder.start);
-function createHTMLElement(elementName)
-{
- return document.createElementNS('http://www.w3.org/1999/xhtml', elementName)
-}
+ folder.openedContent = createHTMLElement('div');
+ folder.openedContent.classList.add('opened');
+ folder.appendChild(folder.openedContent);
-function createCollapsible()
-{
- var collapsible = createHTMLElement('div');
- collapsible.classList.add('collapsible');
- collapsible.expanded = createHTMLElement('div');
- collapsible.expanded.classList.add('expanded');
- collapsible.appendChild(collapsible.expanded);
-
- collapsible.expanded.start = createLine();
- collapsible.expanded.start.appendChild(createCollapseButton());
- collapsible.expanded.appendChild(collapsible.expanded.start);
-
- collapsible.expanded.content = createHTMLElement('div');
- collapsible.expanded.content.classList.add('collapsible-content');
- collapsible.expanded.appendChild(collapsible.expanded.content);
-
- collapsible.expanded.end = createLine();
- collapsible.expanded.appendChild(collapsible.expanded.end);
-
- collapsible.collapsed = createHTMLElement('div');
- collapsible.collapsed.classList.add('collapsed');
- collapsible.collapsed.classList.add('hidden');
- collapsible.appendChild(collapsible.collapsed);
- collapsible.collapsed.content = createLine();
- collapsible.collapsed.content.appendChild(createExpandButton());
- collapsible.collapsed.appendChild(collapsible.collapsed.content);
-
- return collapsible;
-}
+ // Folded content.
+ folder.foldedContent = createText('...');
+ folder.foldedContent.classList.add('folded');
+ folder.foldedContent.classList.add('hidden');
+ folder.appendChild(folder.foldedContent);
-function createButton()
-{
- var button = createHTMLElement('span');
- button.classList.add('button');
- return button;
-}
+ folder.end = createLine();
+ folder.appendChild(folder.end);
-function createCollapseButton(str)
-{
- var button = createButton();
- button.classList.add('collapse-button');
- return button;
+ return folder;
}
-function createExpandButton(str)
-{
- var button = createButton();
- button.classList.add('expand-button');
- return button;
+function createFolderButton(str) {
+ var button = createHTMLElement('span');
+ button.classList.add('folder-button');
+ button.classList.add('fold');
+ return button;
}
function createComment(commentString)
{
- var comment = createHTMLElement('span');
- comment.classList.add('comment');
- comment.classList.add('html-comment');
- comment.textContent = commentString;
- return comment;
+ var comment = createHTMLElement('span');
+ comment.classList.add('comment');
+ comment.classList.add('html-comment');
+ comment.textContent = commentString;
+ return comment;
}
function createText(value)
{
- var text = createHTMLElement('span');
- text.textContent = value;
- text.classList.add('text');
- return text;
+ var text = createHTMLElement('span');
+ text.textContent = value;
+ return text;
}
function createLine()
{
- var line = createHTMLElement('div');
- line.classList.add('line');
- return line;
+ var line = createHTMLElement('div');
+ line.classList.add('line');
+ return line;
}
function createTag(node, isClosing, isEmpty)
{
- var tag = createHTMLElement('span');
- tag.classList.add('html-tag');
-
- var stringBeforeAttrs = '<';
- if (isClosing)
- stringBeforeAttrs += '/';
- stringBeforeAttrs += node.nodeName;
- var textBeforeAttrs = document.createTextNode(stringBeforeAttrs);
- tag.appendChild(textBeforeAttrs);
-
- if (!isClosing) {
- for (var i = 0; i < node.attributes.length; i++)
- tag.appendChild(createAttribute(node.attributes[i]));
- }
-
- var stringAfterAttrs = '';
- if (isEmpty)
- stringAfterAttrs += '/';
- stringAfterAttrs += '>';
- var textAfterAttrs = document.createTextNode(stringAfterAttrs);
- tag.appendChild(textAfterAttrs);
-
- return tag;
+ var tag = createHTMLElement('span');
+ tag.classList.add('html-tag');
+
+ var stringBeforeAttrs = '<';
+ if (isClosing)
+ stringBeforeAttrs += '/';
+ stringBeforeAttrs += node.nodeName;
+ var textBeforeAttrs = document.createTextNode(stringBeforeAttrs);
+ tag.appendChild(textBeforeAttrs);
+
+ if (!isClosing) {
+ for (var i = 0; i < node.attributes.length; i++)
+ tag.appendChild(createAttribute(node.attributes[i]));
+ }
+
+ var stringAfterAttrs = '';
+ if (isEmpty)
+ stringAfterAttrs += '/';
+ stringAfterAttrs += '>';
+ var textAfterAttrs = document.createTextNode(stringAfterAttrs);
+ tag.appendChild(textAfterAttrs);
+
+ return tag;
}
function createAttribute(attributeNode)
{
- var attribute = createHTMLElement('span');
- attribute.classList.add('html-attribute');
+ var attribute = createHTMLElement('span');
+ attribute.classList.add('html-attribute');
- var attributeName = createHTMLElement('span');
- attributeName.classList.add('html-attribute-name');
- attributeName.textContent = attributeNode.name;
+ var attributeName = createHTMLElement('span');
+ attributeName.classList.add('html-attribute-name');
+ attributeName.textContent = attributeNode.name;
- var textBefore = document.createTextNode(' ');
- var textBetween = document.createTextNode('="');
+ var textBefore = document.createTextNode(' ');
+ var textBetween = document.createTextNode('="');
- var attributeValue = createHTMLElement('span');
- attributeValue.classList.add('html-attribute-value');
- attributeValue.textContent = attributeNode.value;
+ var attributeValue = createHTMLElement('span');
+ attributeValue.classList.add('html-attribute-value');
+ attributeValue.textContent = attributeNode.value;
- var textAfter = document.createTextNode('"');
+ var textAfter = document.createTextNode('"');
- attribute.appendChild(textBefore);
- attribute.appendChild(attributeName);
- attribute.appendChild(textBetween);
- attribute.appendChild(attributeValue);
- attribute.appendChild(textAfter);
- return attribute;
+ attribute.appendChild(textBefore);
+ attribute.appendChild(attributeName);
+ attribute.appendChild(textBetween);
+ attribute.appendChild(attributeValue);
+ attribute.appendChild(textAfter);
+ return attribute;
}
-function expandFunction(sectionId)
-{
- return function()
- {
- document.querySelector('#' + sectionId + ' > .expanded').className = 'expanded';
- document.querySelector('#' + sectionId + ' > .collapsed').className = 'collapsed hidden';
- };
-}
+function toggleFunction(sectionId) {
+ return function() {
+ var foldedContent = document.querySelector('#' + sectionId + ' > .folded');
+ var openedContent = document.querySelector('#' + sectionId + ' > .opened');
+ var folderButton =
+ document.querySelector('#' + sectionId + ' > .line > .folder-button');
+
+ if (foldedContent) {
+ if (foldedContent.className.includes('hidden'))
+ foldedContent.className = 'folded';
+ else
+ foldedContent.className = 'folded hidden';
+ }
-function collapseFunction(sectionId)
-{
- return function()
- {
- document.querySelector('#' + sectionId + ' > .expanded').className = 'expanded hidden';
- document.querySelector('#' + sectionId + ' > .collapsed').className = 'collapsed';
- };
+ if (openedContent) {
+ if (openedContent.className.includes('hidden'))
+ openedContent.className = 'opened';
+ else
+ openedContent.className = 'opened hidden';
+ }
+
+ if (folderButton) {
+ if (folderButton.className.includes('open'))
+ folderButton.className = 'folder-button fold';
+ else
+ folderButton.className = 'folder-button open';
+ }
+ };
}
function initButtons()
{
- var sections = document.querySelectorAll('.collapsible');
- for (var i = 0; i < sections.length; i++) {
- var sectionId = 'collapsible' + i;
- sections[i].id = sectionId;
-
- var expandedPart = sections[i].querySelector('#' + sectionId + ' > .expanded');
- var collapseButton = expandedPart.querySelector('.collapse-button');
- collapseButton.onclick = collapseFunction(sectionId);
- collapseButton.onmousedown = handleButtonMouseDown;
-
- var collapsedPart = sections[i].querySelector('#' + sectionId + ' > .collapsed');
- var expandButton = collapsedPart.querySelector('.expand-button');
- expandButton.onclick = expandFunction(sectionId);
- expandButton.onmousedown = handleButtonMouseDown;
- }
-
+ var sections = document.querySelectorAll('.folder');
+ for (var i = 0; i < sections.length; i++) {
+ var sectionId = 'folder' + i;
+ sections[i].id = sectionId;
+
+ var folderButton = sections[i].querySelector('.folder-button');
+ folderButton.onclick = toggleFunction(sectionId);
+ folderButton.onmousedown = handleButtonMouseDown;
+ }
}
function handleButtonMouseDown(e)
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 d884cf77c1a..7d520cd9662 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(blink::Visitor* visitor) {
+void DocumentXPathEvaluator::Trace(Visitor* visitor) {
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 dd3895d0f87..2ec9d4603c4 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
@@ -36,7 +36,7 @@ class ExceptionState;
class XPathExpression;
class XPathResult;
-class DocumentXPathEvaluator final
+class CORE_EXPORT DocumentXPathEvaluator final
: public GarbageCollected<DocumentXPathEvaluator>,
public Supplement<Document> {
USING_GARBAGE_COLLECTED_MIXIN(DocumentXPathEvaluator);
@@ -60,7 +60,7 @@ class DocumentXPathEvaluator final
ExceptionState&);
explicit DocumentXPathEvaluator(Document&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 80f672af461..ba5a7c1d995 100644
--- a/chromium/third_party/blink/renderer/core/xml/document_xslt.cc
+++ b/chromium/third_party/blink/renderer/core/xml/document_xslt.cc
@@ -34,7 +34,7 @@ class DOMContentLoadedListener final
DCHECK(RuntimeEnabledFeatures::XSLTEnabled());
DCHECK_EQ(event->type(), "DOMContentLoaded");
- Document& document = *To<Document>(execution_context);
+ Document& document = *Document::From(execution_context);
DCHECK(!document.Parsing());
// Processing instruction (XML documents only).
@@ -54,7 +54,7 @@ class DOMContentLoadedListener final
EventListener* ToEventListener() override { return this; }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(processing_instruction_);
NativeEventListener::Trace(visitor);
ProcessingInstruction::DetachableEventListener::Trace(visitor);
@@ -75,7 +75,7 @@ void DocumentXSLT::ApplyXSLTransform(Document& document,
DCHECK(!pi->IsLoading());
UseCounter::Count(document, WebFeature::kXSLProcessingInstruction);
XSLTProcessor* processor = XSLTProcessor::Create(document);
- processor->SetXSLStyleSheet(ToXSLStyleSheet(pi->sheet()));
+ processor->SetXSLStyleSheet(To<XSLStyleSheet>(pi->sheet()));
String result_mime_type;
String new_source;
String result_encoding;
@@ -164,7 +164,7 @@ DocumentXSLT& DocumentXSLT::From(Document& document) {
return *supplement;
}
-void DocumentXSLT::Trace(blink::Visitor* visitor) {
+void DocumentXSLT::Trace(Visitor* visitor) {
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 8f9c2eac7db..1b9fe11caf8 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 996234e7538..c03568e633e 100644
--- a/chromium/third_party/blink/renderer/core/xml/dom_parser.cc
+++ b/chromium/third_party/blink/renderer/core/xml/dom_parser.cc
@@ -18,36 +18,22 @@
*/
#include "third_party/blink/renderer/core/xml/dom_parser.h"
-#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_html.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/trustedtypes/trusted_types_util.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
-Document* DOMParser::parseFromString(const StringOrTrustedHTML& stringOrHTML,
- const String& type,
- ExceptionState& exception_state) {
- String value = GetStringFromTrustedHTML(stringOrHTML, context_document_,
- exception_state);
- if (!exception_state.HadException()) {
- return parseFromStringInternal(value, type);
- }
- return nullptr;
-}
-
-Document* DOMParser::parseFromStringInternal(const String& str,
- const String& type) {
+Document* DOMParser::parseFromString(const String& str, const String& type) {
Document* doc = DOMImplementation::createDocument(
- type,
DocumentInit::Create()
+ .WithTypeFrom(type)
.WithContextDocument(context_document_)
- .WithOwnerDocument(context_document_),
- false);
+ .WithOwnerDocument(context_document_)
+ .WithContentSecurityPolicyFromContextDoc());
doc->SetContent(str);
doc->SetMimeType(AtomicString(type));
if (context_document_) {
@@ -59,9 +45,13 @@ Document* DOMParser::parseFromStringInternal(const String& str,
DOMParser::DOMParser(Document& document)
: context_document_(document.ContextDocument()) {}
-void DOMParser::Trace(blink::Visitor* visitor) {
+void DOMParser::Trace(Visitor* visitor) {
visitor->Trace(context_document_);
ScriptWrappable::Trace(visitor);
}
+Document* DOMParser::GetDocument() const {
+ return context_document_.Get();
+}
+
} // namespace blink
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 3e08eb90dff..058ee51a3c0 100644
--- a/chromium/third_party/blink/renderer/core/xml/dom_parser.h
+++ b/chromium/third_party/blink/renderer/core/xml/dom_parser.h
@@ -27,8 +27,6 @@
namespace blink {
class Document;
-class StringOrTrustedHTML;
-class ExceptionState;
class DOMParser final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
@@ -40,16 +38,13 @@ class DOMParser final : public ScriptWrappable {
explicit DOMParser(Document&);
- Document* parseFromString(const StringOrTrustedHTML&,
- const String& type,
- ExceptionState& exception_state);
- Document* parseFromString(const StringOrTrustedHTML&, const String& type);
+ Document* parseFromString(const String&, const String& type);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
- private:
- Document* parseFromStringInternal(const String&, const String& type);
+ Document* GetDocument() const;
+ private:
WeakMember<Document> context_document_;
};
diff --git a/chromium/third_party/blink/renderer/core/xml/dom_parser.idl b/chromium/third_party/blink/renderer/core/xml/dom_parser.idl
index 5f9b2abe8bf..26dbfd80754 100644
--- a/chromium/third_party/blink/renderer/core/xml/dom_parser.idl
+++ b/chromium/third_party/blink/renderer/core/xml/dom_parser.idl
@@ -28,9 +28,8 @@ enum SupportedType {
};
[
- Constructor,
- ConstructorCallWith=Document,
Exposed=Window
] interface DOMParser {
- [NewObject, RaisesException] Document parseFromString(HTMLString str, SupportedType type);
+ [CallWith=Document] constructor();
+ [NewObject] Document parseFromString(HTMLString str, SupportedType type);
};
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 49c4723b17b..3dadcfffe3d 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(blink::Visitor* visitor) {
+void NativeXPathNSResolver::Trace(Visitor* visitor) {
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 442dcfbf2c1..0898d698bd8 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 2398ecd6441..5de26fc1d9e 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
@@ -47,6 +47,7 @@
#include "third_party/blink/renderer/core/dom/document_type.h"
#include "third_party/blink/renderer/core/dom/processing_instruction.h"
#include "third_party/blink/renderer/core/dom/transform_source.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/frame/web_feature.h"
#include "third_party/blink/renderer/core/html/html_html_element.h"
@@ -129,8 +130,10 @@ class PendingStartElementNSCallback final
const xmlChar** namespaces,
int attribute_count,
int defaulted_count,
- const xmlChar** attributes)
- : local_name_(local_name),
+ const xmlChar** attributes,
+ TextPosition text_position)
+ : PendingCallback(text_position),
+ local_name_(local_name),
prefix_(prefix),
uri_(uri),
namespace_count_(namespace_count),
@@ -185,8 +188,10 @@ class PendingStartElementNSCallback final
class PendingEndElementNSCallback final
: public XMLDocumentParser::PendingCallback {
public:
- explicit PendingEndElementNSCallback(TextPosition script_start_position)
- : script_start_position_(script_start_position) {}
+ explicit PendingEndElementNSCallback(TextPosition script_start_position,
+ TextPosition text_position)
+ : PendingCallback(text_position),
+ script_start_position_(script_start_position) {}
void Call(XMLDocumentParser* parser) override {
parser->SetScriptStartPosition(script_start_position_);
@@ -200,8 +205,12 @@ class PendingEndElementNSCallback final
class PendingCharactersCallback final
: public XMLDocumentParser::PendingCallback {
public:
- PendingCharactersCallback(const xmlChar* chars, int length)
- : chars_(xmlStrndup(chars, length)), length_(length) {}
+ PendingCharactersCallback(const xmlChar* chars,
+ int length,
+ TextPosition text_position)
+ : PendingCallback(text_position),
+ chars_(xmlStrndup(chars, length)),
+ length_(length) {}
~PendingCharactersCallback() override { xmlFree(chars_); }
@@ -217,8 +226,10 @@ class PendingCharactersCallback final
class PendingProcessingInstructionCallback final
: public XMLDocumentParser::PendingCallback {
public:
- PendingProcessingInstructionCallback(const String& target, const String& data)
- : target_(target), data_(data) {}
+ PendingProcessingInstructionCallback(const String& target,
+ const String& data,
+ TextPosition text_position)
+ : PendingCallback(text_position), target_(target), data_(data) {}
void Call(XMLDocumentParser* parser) override {
parser->GetProcessingInstruction(target_, data_);
@@ -232,7 +243,9 @@ class PendingProcessingInstructionCallback final
class PendingCDATABlockCallback final
: public XMLDocumentParser::PendingCallback {
public:
- explicit PendingCDATABlockCallback(const String& text) : text_(text) {}
+ explicit PendingCDATABlockCallback(const String& text,
+ TextPosition text_position)
+ : PendingCallback(text_position), text_(text) {}
void Call(XMLDocumentParser* parser) override { parser->CdataBlock(text_); }
@@ -242,7 +255,9 @@ class PendingCDATABlockCallback final
class PendingCommentCallback final : public XMLDocumentParser::PendingCallback {
public:
- explicit PendingCommentCallback(const String& text) : text_(text) {}
+ explicit PendingCommentCallback(const String& text,
+ TextPosition text_position)
+ : PendingCallback(text_position), text_(text) {}
void Call(XMLDocumentParser* parser) override { parser->Comment(text_); }
@@ -255,8 +270,12 @@ class PendingInternalSubsetCallback final
public:
PendingInternalSubsetCallback(const String& name,
const String& external_id,
- const String& system_id)
- : name_(name), external_id_(external_id), system_id_(system_id) {}
+ const String& system_id,
+ TextPosition text_position)
+ : PendingCallback(text_position),
+ name_(name),
+ external_id_(external_id),
+ system_id_(system_id) {}
void Call(XMLDocumentParser* parser) override {
parser->InternalSubset(name_, external_id_, system_id_);
@@ -272,25 +291,21 @@ class PendingErrorCallback final : public XMLDocumentParser::PendingCallback {
public:
PendingErrorCallback(XMLErrors::ErrorType type,
const xmlChar* message,
- OrdinalNumber line_number,
- OrdinalNumber column_number)
- : type_(type),
- message_(xmlStrdup(message)),
- line_number_(line_number),
- column_number_(column_number) {}
+ TextPosition text_position)
+ : PendingCallback(text_position),
+ type_(type),
+ message_(xmlStrdup(message)) {}
~PendingErrorCallback() override { xmlFree(message_); }
void Call(XMLDocumentParser* parser) override {
parser->HandleError(type_, reinterpret_cast<char*>(message_),
- TextPosition(line_number_, column_number_));
+ GetTextPosition());
}
private:
XMLErrors::ErrorType type_;
xmlChar* message_;
- OrdinalNumber line_number_;
- OrdinalNumber column_number_;
};
void XMLDocumentParser::PushCurrentNode(ContainerNode* n) {
@@ -362,7 +377,7 @@ bool XMLDocumentParser::UpdateLeafTextNode() {
if (!leaf_text_node_)
return true;
- leaf_text_node_->appendData(
+ leaf_text_node_->ParserAppendData(
ToString(buffered_text_.data(), buffered_text_.size()));
buffered_text_.clear();
leaf_text_node_ = nullptr;
@@ -401,10 +416,14 @@ void XMLDocumentParser::end() {
// StopParsing() calls InsertErrorMessageBlock() if there was a parsing
// error. Avoid showing the error message block twice.
// TODO(crbug.com/898775): Rationalize this.
- if (saw_error_ && !IsStopped())
+ if (saw_error_ && !IsStopped()) {
InsertErrorMessageBlock();
- else
+ // InsertErrorMessageBlock() may detach the document
+ if (IsDetached())
+ return;
+ } else {
UpdateLeafTextNode();
+ }
if (IsParsing())
PrepareToStopParsing();
@@ -577,8 +596,9 @@ static bool ShouldAllowExternalLoad(const KURL& url) {
XMLDocumentParserScope::current_document_->Url().ElidedString() +
". Domains, protocols and ports must match.\n";
XMLDocumentParserScope::current_document_->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kError, message));
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kSecurity,
+ mojom::ConsoleMessageLevel::kError, message));
}
return false;
}
@@ -743,7 +763,7 @@ XMLDocumentParser::XMLDocumentParser(Document& document,
script_start_position_(TextPosition::BelowRangePosition()),
parsing_fragment_(false) {
// This is XML being used as a document resource.
- if (frame_view && document.IsXMLDocument())
+ if (frame_view && IsA<XMLDocument>(document))
UseCounter::Count(document, WebFeature::kXMLDocument);
}
@@ -807,7 +827,7 @@ XMLParserContext::~XMLParserContext() {
XMLDocumentParser::~XMLDocumentParser() = default;
-void XMLDocumentParser::Trace(blink::Visitor* visitor) {
+void XMLDocumentParser::Trace(Visitor* visitor) {
visitor->Trace(current_node_);
visitor->Trace(current_node_stack_);
visitor->Trace(leaf_text_node_);
@@ -948,7 +968,8 @@ void XMLDocumentParser::StartElementNs(const AtomicString& local_name,
pending_callbacks_.push_back(
std::make_unique<PendingStartElementNSCallback>(
local_name, prefix, uri, nb_namespaces, libxml_namespaces,
- nb_attributes, nb_defaulted, libxml_attributes));
+ nb_attributes, nb_defaulted, libxml_attributes,
+ script_start_position_));
return;
}
@@ -1041,8 +1062,8 @@ void XMLDocumentParser::EndElementNs() {
return;
if (parser_paused_) {
- pending_callbacks_.push_back(
- std::make_unique<PendingEndElementNSCallback>(script_start_position_));
+ pending_callbacks_.push_back(std::make_unique<PendingEndElementNSCallback>(
+ script_start_position_, GetTextPosition()));
return;
}
@@ -1057,6 +1078,9 @@ void XMLDocumentParser::EndElementNs() {
}
element->FinishParsingChildren();
+
+ CheckIfBlockingStyleSheetAdded();
+
if (element->IsScriptElement() &&
!ScriptingContentIsAllowed(GetParserContentPolicy())) {
PopCurrentNode();
@@ -1108,8 +1132,8 @@ void XMLDocumentParser::Characters(const xmlChar* chars, int length) {
return;
if (parser_paused_) {
- pending_callbacks_.push_back(
- std::make_unique<PendingCharactersCallback>(chars, length));
+ pending_callbacks_.push_back(std::make_unique<PendingCharactersCallback>(
+ chars, length, GetTextPosition()));
return;
}
@@ -1128,8 +1152,8 @@ void XMLDocumentParser::GetError(XMLErrors::ErrorType type,
if (parser_paused_) {
pending_callbacks_.push_back(std::make_unique<PendingErrorCallback>(
- type, reinterpret_cast<const xmlChar*>(formatted_message), LineNumber(),
- ColumnNumber()));
+ type, reinterpret_cast<const xmlChar*>(formatted_message),
+ GetTextPosition()));
return;
}
@@ -1143,7 +1167,8 @@ void XMLDocumentParser::GetProcessingInstruction(const String& target,
if (parser_paused_) {
pending_callbacks_.push_back(
- std::make_unique<PendingProcessingInstructionCallback>(target, data));
+ std::make_unique<PendingProcessingInstructionCallback>(
+ target, data, GetTextPosition()));
return;
}
@@ -1163,6 +1188,8 @@ void XMLDocumentParser::GetProcessingInstruction(const String& target,
if (pi->IsCSS())
saw_css_ = true;
+ CheckIfBlockingStyleSheetAdded();
+
if (!RuntimeEnabledFeatures::XSLTEnabled())
return;
@@ -1185,7 +1212,7 @@ void XMLDocumentParser::CdataBlock(const String& text) {
if (parser_paused_) {
pending_callbacks_.push_back(
- std::make_unique<PendingCDATABlockCallback>(text));
+ std::make_unique<PendingCDATABlockCallback>(text, GetTextPosition()));
return;
}
@@ -1202,7 +1229,7 @@ void XMLDocumentParser::Comment(const String& text) {
if (parser_paused_) {
pending_callbacks_.push_back(
- std::make_unique<PendingCommentCallback>(text));
+ std::make_unique<PendingCommentCallback>(text, GetTextPosition()));
return;
}
@@ -1258,8 +1285,8 @@ void XMLDocumentParser::InternalSubset(const String& name,
if (parser_paused_) {
pending_callbacks_.push_back(
- std::make_unique<PendingInternalSubsetCallback>(name, external_id,
- system_id));
+ std::make_unique<PendingInternalSubsetCallback>(
+ name, external_id, system_id, GetTextPosition()));
return;
}
@@ -1569,19 +1596,19 @@ xmlDocPtr XmlDocPtrForString(Document* document,
}
OrdinalNumber XMLDocumentParser::LineNumber() const {
+ if (callback_)
+ return callback_->LineNumber();
return OrdinalNumber::FromOneBasedInt(Context() ? Context()->input->line : 1);
}
OrdinalNumber XMLDocumentParser::ColumnNumber() const {
+ if (callback_)
+ return callback_->ColumnNumber();
return OrdinalNumber::FromOneBasedInt(Context() ? Context()->input->col : 1);
}
TextPosition XMLDocumentParser::GetTextPosition() const {
- xmlParserCtxtPtr context = this->Context();
- if (!context)
- return TextPosition::MinimumPosition();
- return TextPosition(OrdinalNumber::FromOneBasedInt(context->input->line),
- OrdinalNumber::FromOneBasedInt(context->input->col));
+ return TextPosition(LineNumber(), ColumnNumber());
}
void XMLDocumentParser::StopParsing() {
@@ -1601,13 +1628,16 @@ void XMLDocumentParser::ResumeParsing() {
// First, execute any pending callbacks
while (!pending_callbacks_.IsEmpty()) {
- std::unique_ptr<PendingCallback> callback = pending_callbacks_.TakeFirst();
- callback->Call(this);
+ callback_ = pending_callbacks_.TakeFirst();
+ callback_->Call(this);
// A callback paused the parser
- if (parser_paused_)
+ if (parser_paused_) {
+ callback_.reset();
return;
+ }
}
+ callback_.reset();
// Then, write any pending data
SegmentedString rest = pending_src_;
@@ -1662,6 +1692,32 @@ bool XMLDocumentParser::AppendFragmentSource(const String& chunk) {
return Context()->wellFormed || !xmlCtxtGetLastError(Context());
}
+void XMLDocumentParser::DidAddPendingParserBlockingStylesheet() {
+ if (!context_)
+ return;
+ added_pending_parser_blocking_stylesheet_ = true;
+}
+
+void XMLDocumentParser::DidLoadAllPendingParserBlockingStylesheets() {
+ added_pending_parser_blocking_stylesheet_ = false;
+ waiting_for_stylesheets_ = false;
+}
+
+void XMLDocumentParser::CheckIfBlockingStyleSheetAdded() {
+ if (!added_pending_parser_blocking_stylesheet_)
+ return;
+ added_pending_parser_blocking_stylesheet_ = false;
+ waiting_for_stylesheets_ = true;
+ PauseParsing();
+}
+
+void XMLDocumentParser::ExecuteScriptsWaitingForResources() {
+ if (!IsWaitingForScripts() && !waiting_for_stylesheets_ && parser_paused_ &&
+ IsParsing()) {
+ ResumeParsing();
+ }
+}
+
// --------------------------------
struct AttributeParseState {
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 823977256d3..e832a3e7657 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// Exposed for callbacks:
void HandleError(XMLErrors::ErrorType, const char* message, TextPosition);
@@ -108,6 +108,17 @@ class XMLDocumentParser final : public ScriptableDocumentParser,
public:
virtual ~PendingCallback() = default;
virtual void Call(XMLDocumentParser*) = 0;
+
+ TextPosition GetTextPosition() const { return text_position_; }
+ OrdinalNumber LineNumber() const { return text_position_.line_; }
+ OrdinalNumber ColumnNumber() const { return text_position_.column_; }
+
+ protected:
+ PendingCallback(TextPosition text_position)
+ : text_position_(text_position) {}
+
+ private:
+ TextPosition text_position_;
};
void SetScriptStartPosition(TextPosition);
@@ -117,11 +128,14 @@ class XMLDocumentParser final : public ScriptableDocumentParser,
void insert(const String&) override { NOTREACHED(); }
void Append(const String&) override;
void Finish() override;
+ void ExecuteScriptsWaitingForResources() final;
bool IsWaitingForScripts() const override;
void StopParsing() override;
void Detach() override;
OrdinalNumber LineNumber() const override;
OrdinalNumber ColumnNumber() const;
+ void DidAddPendingParserBlockingStylesheet() final;
+ void DidLoadAllPendingParserBlockingStylesheets() final;
// XMLParserScriptRunnerHost
void NotifyScriptExecuted() override;
@@ -173,6 +187,8 @@ class XMLDocumentParser final : public ScriptableDocumentParser,
void DoWrite(const String&);
void DoEnd();
+ void CheckIfBlockingStyleSheetAdded();
+
SegmentedString original_source_for_transform_;
xmlParserCtxtPtr Context() const {
@@ -180,6 +196,7 @@ class XMLDocumentParser final : public ScriptableDocumentParser,
}
scoped_refptr<XMLParserContext> context_;
Deque<std::unique_ptr<PendingCallback>> pending_callbacks_;
+ std::unique_ptr<PendingCallback> callback_;
Vector<xmlChar> buffered_text_;
Member<ContainerNode> current_node_;
@@ -196,6 +213,8 @@ class XMLDocumentParser final : public ScriptableDocumentParser,
bool parser_paused_;
bool requesting_script_;
bool finish_called_;
+ bool waiting_for_stylesheets_ = false;
+ bool added_pending_parser_blocking_stylesheet_ = false;
XMLErrors xml_errors_;
diff --git a/chromium/third_party/blink/renderer/core/xml/parser/xml_document_parser_scope.h b/chromium/third_party/blink/renderer/core/xml/parser/xml_document_parser_scope.h
index 01ff89d7614..8f5f07f0184 100644
--- a/chromium/third_party/blink/renderer/core/xml/parser/xml_document_parser_scope.h
+++ b/chromium/third_party/blink/renderer/core/xml/parser/xml_document_parser_scope.h
@@ -48,7 +48,7 @@ class XMLDocumentParserScope {
static Document* current_document_;
private:
- Member<Document> old_document_;
+ Document* old_document_;
xmlGenericErrorFunc old_generic_error_func_;
xmlStructuredErrorFunc old_structured_error_func_;
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 ece2d1877de..56452f12b27 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(blink::Visitor* visitor) {
+void XMLErrors::Trace(Visitor* visitor) {
visitor->Trace(document_);
}
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 5932d4fa605..7a0adf16219 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(blink::Visitor*);
+ void Trace(Visitor*);
// Exposed for callbacks:
enum ErrorType { kErrorTypeWarning, kErrorTypeNonFatal, kErrorTypeFatal };
diff --git a/chromium/third_party/blink/renderer/core/xml/xml_serializer.cc b/chromium/third_party/blink/renderer/core/xml/xml_serializer.cc
index 3cd00f2d678..3b17e5bc349 100644
--- a/chromium/third_party/blink/renderer/core/xml/xml_serializer.cc
+++ b/chromium/third_party/blink/renderer/core/xml/xml_serializer.cc
@@ -28,7 +28,8 @@ namespace blink {
String XMLSerializer::serializeToString(Node* root) {
DCHECK(root);
- MarkupAccumulator accumulator(kDoNotResolveURLs, SerializationType::kXML);
+ MarkupAccumulator accumulator(kDoNotResolveURLs, SerializationType::kXML,
+ kNoShadowRoots);
return accumulator.SerializeNodes<EditingStrategy>(*root, kIncludeNode);
}
diff --git a/chromium/third_party/blink/renderer/core/xml/xml_serializer.idl b/chromium/third_party/blink/renderer/core/xml/xml_serializer.idl
index 3724948d5df..489d4335ab5 100644
--- a/chromium/third_party/blink/renderer/core/xml/xml_serializer.idl
+++ b/chromium/third_party/blink/renderer/core/xml/xml_serializer.idl
@@ -21,8 +21,8 @@
// https://w3c.github.io/DOM-Parsing/#the-xmlserializer-interface
[
- Constructor,
Exposed=Window
] interface XMLSerializer {
+ constructor();
DOMString serializeToString(Node root);
};
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_evaluator.idl b/chromium/third_party/blink/renderer/core/xml/xpath_evaluator.idl
index f9f735e1546..595ed6610dd 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_evaluator.idl
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_evaluator.idl
@@ -25,10 +25,8 @@
// Blink, Gecko, Presto, WebKit and all have these APIs on both Document and the
// constructable XPathEvaluator interface.
-[
- Constructor,
- Measure
-] interface XPathEvaluator {
+interface XPathEvaluator {
+ [Measure] constructor();
[Measure, RaisesException] XPathExpression createExpression(DOMString expression, optional XPathNSResolver? resolver = null);
[Measure] XPathNSResolver createNSResolver(Node nodeResolver);
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 0b39fb06968..0b112519a93 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(blink::Visitor* visitor) {
+void XPathExpression::Trace(Visitor* visitor) {
visitor->Trace(top_expression_);
ScriptWrappable::Trace(visitor);
}
@@ -70,11 +70,13 @@ XPathResult* XPathExpression::evaluate(Node* context_node,
return nullptr;
}
- xpath::EvaluationContext evaluation_context(*context_node);
+ bool had_type_conversion_error = false;
+ xpath::EvaluationContext evaluation_context(*context_node,
+ had_type_conversion_error);
auto* result = MakeGarbageCollected<XPathResult>(
evaluation_context, top_expression_->Evaluate(evaluation_context));
- if (evaluation_context.had_type_conversion_error) {
+ if (had_type_conversion_error) {
// It is not specified what to do if type conversion fails while evaluating
// an expression.
exception_state.ThrowDOMException(
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 be7c60ac558..76036cfd96d 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 5b11857e162..02b43ac7e5b 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
@@ -31,11 +31,12 @@
namespace blink {
namespace xpath {
-EvaluationContext::EvaluationContext(Node& context_node)
- : node(context_node),
+EvaluationContext::EvaluationContext(Node& context_node,
+ bool& had_type_conversion_error)
+ : node(&context_node),
size(1),
position(1),
- had_type_conversion_error(false) {}
+ had_type_conversion_error(had_type_conversion_error) {}
Expression::Expression()
: is_context_node_sensitive_(false),
@@ -44,7 +45,7 @@ Expression::Expression()
Expression::~Expression() = default;
-void Expression::Trace(blink::Visitor* visitor) {
+void Expression::Trace(Visitor* visitor) {
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 2a6e70e49f0..e587ea4c224 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
@@ -43,27 +43,29 @@ struct CORE_EXPORT EvaluationContext {
STACK_ALLOCATED();
public:
- explicit EvaluationContext(Node&);
+ // |had_type_conversion_error| must be a reference to a variable of
+ // which lifetime is same as this object, or longer than this object.
+ EvaluationContext(Node&, bool& had_type_conversion_error);
- Member<Node> node;
+ Node* node;
wtf_size_t size;
wtf_size_t position;
HashMap<String, String> variable_bindings;
- bool had_type_conversion_error;
+ bool& had_type_conversion_error;
};
class CORE_EXPORT ParseNode : public GarbageCollected<ParseNode> {
public:
virtual ~ParseNode() = default;
- virtual void Trace(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
};
class CORE_EXPORT Expression : public ParseNode {
public:
Expression();
~Expression() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
virtual Value Evaluate(EvaluationContext&) const = 0;
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_functions.cc b/chromium/third_party/blink/renderer/core/xml/xpath_functions.cc
index c16650bffe2..671000a1ab4 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_functions.cc
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_functions.cc
@@ -431,7 +431,7 @@ Value FunLocalName::Evaluate(EvaluationContext& context) const {
return node ? ExpandedNameLocalPart(node) : "";
}
- return ExpandedNameLocalPart(context.node.Get());
+ return ExpandedNameLocalPart(context.node);
}
Value FunNamespaceURI::Evaluate(EvaluationContext& context) const {
@@ -444,7 +444,7 @@ Value FunNamespaceURI::Evaluate(EvaluationContext& context) const {
return node ? ExpandedNamespaceURI(node) : "";
}
- return ExpandedNamespaceURI(context.node.Get());
+ return ExpandedNamespaceURI(context.node);
}
Value FunName::Evaluate(EvaluationContext& context) const {
@@ -457,7 +457,7 @@ Value FunName::Evaluate(EvaluationContext& context) const {
return node ? ExpandedName(node) : "";
}
- return ExpandedName(context.node.Get());
+ return ExpandedName(context.node);
}
Value FunCount::Evaluate(EvaluationContext& context) const {
@@ -468,7 +468,7 @@ Value FunCount::Evaluate(EvaluationContext& context) const {
Value FunString::Evaluate(EvaluationContext& context) const {
if (!ArgCount())
- return Value(context.node.Get()).ToString();
+ return Value(context.node).ToString();
return Arg(0)->Evaluate(context).ToString();
}
@@ -478,16 +478,17 @@ Value FunConcat::Evaluate(EvaluationContext& context) const {
unsigned count = ArgCount();
for (unsigned i = 0; i < count; ++i) {
- String str(Arg(i)->Evaluate(context).ToString());
- result.Append(str);
+ EvaluationContext cloned_context(context);
+ result.Append(Arg(i)->Evaluate(cloned_context).ToString());
}
return result.ToString();
}
Value FunStartsWith::Evaluate(EvaluationContext& context) const {
+ EvaluationContext cloned_context(context);
String s1 = Arg(0)->Evaluate(context).ToString();
- String s2 = Arg(1)->Evaluate(context).ToString();
+ String s2 = Arg(1)->Evaluate(cloned_context).ToString();
if (s2.IsEmpty())
return true;
@@ -496,8 +497,9 @@ Value FunStartsWith::Evaluate(EvaluationContext& context) const {
}
Value FunContains::Evaluate(EvaluationContext& context) const {
+ EvaluationContext cloned_context(context);
String s1 = Arg(0)->Evaluate(context).ToString();
- String s2 = Arg(1)->Evaluate(context).ToString();
+ String s2 = Arg(1)->Evaluate(cloned_context).ToString();
if (s2.IsEmpty())
return true;
@@ -506,8 +508,9 @@ Value FunContains::Evaluate(EvaluationContext& context) const {
}
Value FunSubstringBefore::Evaluate(EvaluationContext& context) const {
+ EvaluationContext cloned_context(context);
String s1 = Arg(0)->Evaluate(context).ToString();
- String s2 = Arg(1)->Evaluate(context).ToString();
+ String s2 = Arg(1)->Evaluate(cloned_context).ToString();
if (s2.IsEmpty())
return "";
@@ -521,8 +524,9 @@ Value FunSubstringBefore::Evaluate(EvaluationContext& context) const {
}
Value FunSubstringAfter::Evaluate(EvaluationContext& context) const {
+ EvaluationContext cloned_context(context);
String s1 = Arg(0)->Evaluate(context).ToString();
- String s2 = Arg(1)->Evaluate(context).ToString();
+ String s2 = Arg(1)->Evaluate(cloned_context).ToString();
wtf_size_t i = s1.Find(s2);
if (i == kNotFound)
@@ -563,11 +567,15 @@ static std::pair<unsigned, unsigned> ComputeSubstringStartEnd(double start,
//
// <https://www.w3.org/TR/xpath/#function-substring>
Value FunSubstring::Evaluate(EvaluationContext& context) const {
+ EvaluationContext cloned_context1(context);
+ EvaluationContext cloned_context2(context);
String source_string = Arg(0)->Evaluate(context).ToString();
- const double pos = FunRound::Round(Arg(1)->Evaluate(context).ToNumber());
- const double len = ArgCount() == 3
- ? FunRound::Round(Arg(2)->Evaluate(context).ToNumber())
- : std::numeric_limits<double>::infinity();
+ const double pos =
+ FunRound::Round(Arg(1)->Evaluate(cloned_context1).ToNumber());
+ const double len =
+ ArgCount() == 3
+ ? FunRound::Round(Arg(2)->Evaluate(cloned_context2).ToNumber())
+ : std::numeric_limits<double>::infinity();
const auto bounds =
ComputeSubstringStartEnd(pos, len, source_string.length());
if (bounds.second <= bounds.first)
@@ -578,24 +586,23 @@ Value FunSubstring::Evaluate(EvaluationContext& context) const {
Value FunStringLength::Evaluate(EvaluationContext& context) const {
if (!ArgCount())
- return Value(context.node.Get()).ToString().length();
+ return Value(context.node).ToString().length();
return Arg(0)->Evaluate(context).ToString().length();
}
Value FunNormalizeSpace::Evaluate(EvaluationContext& context) const {
- if (!ArgCount()) {
- String s = Value(context.node.Get()).ToString();
- return s.SimplifyWhiteSpace();
- }
-
- String s = Arg(0)->Evaluate(context).ToString();
- return s.SimplifyWhiteSpace();
+ // https://www.w3.org/TR/1999/REC-xpath-19991116/#function-normalize-space
+ String s = (ArgCount() == 0 ? Value(context.node) : Arg(0)->Evaluate(context))
+ .ToString();
+ return s.SimplifyWhiteSpace(IsXMLSpace);
}
Value FunTranslate::Evaluate(EvaluationContext& context) const {
+ EvaluationContext cloned_context1(context);
+ EvaluationContext cloned_context2(context);
String s1 = Arg(0)->Evaluate(context).ToString();
- String s2 = Arg(1)->Evaluate(context).ToString();
- String s3 = Arg(2)->Evaluate(context).ToString();
+ String s2 = Arg(1)->Evaluate(cloned_context1).ToString();
+ String s3 = Arg(2)->Evaluate(cloned_context2).ToString();
StringBuilder result;
for (unsigned i1 = 0; i1 < s1.length(); ++i1) {
@@ -627,7 +634,7 @@ Value FunLang::Evaluate(EvaluationContext& context) const {
String lang = Arg(0)->Evaluate(context).ToString();
const Attribute* language_attribute = nullptr;
- Node* node = context.node.Get();
+ Node* node = context.node;
while (node) {
if (auto* element = DynamicTo<Element>(node))
language_attribute = element->Attributes().Find(xml_names::kLangAttr);
@@ -661,7 +668,7 @@ Value FunFalse::Evaluate(EvaluationContext&) const {
Value FunNumber::Evaluate(EvaluationContext& context) const {
if (!ArgCount())
- return Value(context.node.Get()).ToNumber();
+ return Value(context.node).ToNumber();
return Arg(0)->Evaluate(context).ToNumber();
}
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 575ff415c52..dfed2c080b9 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,13 +25,15 @@ class XPathContext {
public:
XPathContext()
- : document_(MakeGarbageCollected<Document>()), context_(*document_) {}
+ : document_(MakeGarbageCollected<Document>()),
+ context_(*document_, had_type_conversion_error_) {}
xpath::EvaluationContext& Context() { return context_; }
Document& GetDocument() { return *document_; }
private:
- const Member<Document> document_;
+ Document* const document_;
+ bool had_type_conversion_error_ = false;
xpath::EvaluationContext context_;
};
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_grammar.y b/chromium/third_party/blink/renderer/core/xml/xpath_grammar.y
index cf0208370a0..a88d822f1ec 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_grammar.y
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_grammar.y
@@ -25,6 +25,30 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/* === NOTA BENE ===
+ * If you modify this file, you must run bison to regenerate the corresponding
+ * .cc and .h files. From chromium's root directory, run the following command
+ * on a system with a modern version of bison (>= 3.4.1):
+ *
+ * $ third_party/blink/renderer/build/scripts/rule_bison.py \
+ * third_party/blink/renderer/core/xml/xpath_grammar.y \
+ * third_party/blink/renderer/core/xml/ \
+ * bison
+ *
+ * This process is not automated because newer bison releases have diverged from
+ * (1) the version included with Xcode and (2) the Windows binary checked into
+ * //third_party/bison. See https://crbug.com/1028421.
+ */
+
+%require "3.4"
+%language "c++"
+
+%code requires {
+
+#include "third_party/blink/renderer/platform/heap/persistent.h"
+
+}
+
%{
#include "third_party/blink/renderer/core/xml/xpath_functions.h"
@@ -35,101 +59,89 @@
#include "third_party/blink/renderer/core/xml/xpath_step.h"
#include "third_party/blink/renderer/core/xml/xpath_variable_reference.h"
-// The union below must be located on the stack because it contains raw
-// pointers to Oilpan objects. crbug.com/961413
-#define YYSTACK_USE_ALLOCA 1
-// Bison's bug? YYSTACK_ALLOC is not defined if _MSC_VER.
-#if defined(_MSC_VER)
-#define YYSTACK_ALLOC _alloca
-#endif
-
#define YYENABLE_NLS 0
-#define YYLTYPE_IS_TRIVIAL 1
+#define YY_EXCEPTIONS 0
#define YYDEBUG 0
-#define YYMAXDEPTH 10000
using blink::xpath::Step;
%}
-%pure-parser
-%parse-param { blink::xpath::Parser* parser }
-
-%union
-{
- blink::xpath::Step::Axis axis;
- blink::xpath::Step::NodeTest* node_test;
- blink::xpath::NumericOp::Opcode num_op;
- blink::xpath::EqTestOp::Opcode eq_op;
- String* str;
- blink::xpath::Expression* expr;
- blink::HeapVector<blink::Member<blink::xpath::Predicate>>* pred_list;
- blink::HeapVector<blink::Member<blink::xpath::Expression>>* arg_list;
- blink::xpath::Step* step;
- blink::xpath::LocationPath* location_path;
+%define api.namespace {xpathyy}
+%define api.parser.class {YyParser}
+%parse-param { blink::xpath::Parser* parser_ }
+
+%define api.value.type variant
+
+%left <blink::xpath::NumericOp::Opcode> kMulOp
+%left <blink::xpath::EqTestOp::Opcode> kEqOp kRelOp
+%left kPlus kMinus
+%left kOr kAnd
+%token <blink::xpath::Step::Axis> kAxisName
+%token <String> kNodeType kPI kFunctionName kLiteral
+%token <String> kVariableReference kNumber
+%token kDotDot kSlashSlash
+%token <String> kNameTest
+%token kXPathError
+
+%type <blink::Persistent<blink::xpath::LocationPath>> LocationPath
+%type <blink::Persistent<blink::xpath::LocationPath>> AbsoluteLocationPath
+%type <blink::Persistent<blink::xpath::LocationPath>> RelativeLocationPath
+%type <blink::Persistent<blink::xpath::Step>> Step
+%type <blink::xpath::Step::Axis> AxisSpecifier
+%type <blink::Persistent<blink::xpath::Step>> DescendantOrSelf
+%type <blink::Persistent<blink::xpath::Step::NodeTest>> NodeTest
+%type <blink::Persistent<blink::xpath::Expression>> Predicate
+%type <blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>>> OptionalPredicateList
+%type <blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>>> PredicateList
+%type <blink::Persistent<blink::xpath::Step>> AbbreviatedStep
+%type <blink::Persistent<blink::xpath::Expression>> Expr
+%type <blink::Persistent<blink::xpath::Expression>> PrimaryExpr
+%type <blink::Persistent<blink::xpath::Expression>> FunctionCall
+%type <blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>>> ArgumentList
+%type <blink::Persistent<blink::xpath::Expression>> Argument
+%type <blink::Persistent<blink::xpath::Expression>> UnionExpr
+%type <blink::Persistent<blink::xpath::Expression>> PathExpr
+%type <blink::Persistent<blink::xpath::Expression>> FilterExpr
+%type <blink::Persistent<blink::xpath::Expression>> OrExpr
+%type <blink::Persistent<blink::xpath::Expression>> AndExpr
+%type <blink::Persistent<blink::xpath::Expression>> EqualityExpr
+%type <blink::Persistent<blink::xpath::Expression>> RelationalExpr
+%type <blink::Persistent<blink::xpath::Expression>> AdditiveExpr
+%type <blink::Persistent<blink::xpath::Expression>> MultiplicativeExpr
+%type <blink::Persistent<blink::xpath::Expression>> UnaryExpr
+
+%code {
+
+static int yylex(xpathyy::YyParser::semantic_type* yylval) {
+ return blink::xpath::Parser::Current()->Lex(yylval);
}
-%{
-
-static int xpathyylex(YYSTYPE* yylval) { return blink::xpath::Parser::Current()->Lex(yylval); }
-static void xpathyyerror(void*, const char*) { }
-
-%}
+namespace xpathyy {
+void YyParser::error(const std::string&) { }
+}
-%left <num_op> MULOP
-%left <eq_op> EQOP RELOP
-%left PLUS MINUS
-%left OR AND
-%token <axis> AXISNAME
-%token <str> NODETYPE PI FUNCTIONNAME LITERAL
-%token <str> VARIABLEREFERENCE NUMBER
-%token DOTDOT SLASHSLASH
-%token <str> NAMETEST
-%token XPATH_ERROR
-
-%type <location_path> LocationPath
-%type <location_path> AbsoluteLocationPath
-%type <location_path> RelativeLocationPath
-%type <step> Step
-%type <axis> AxisSpecifier
-%type <step> DescendantOrSelf
-%type <node_test> NodeTest
-%type <expr> Predicate
-%type <pred_list> OptionalPredicateList
-%type <pred_list> PredicateList
-%type <step> AbbreviatedStep
-%type <expr> Expr
-%type <expr> PrimaryExpr
-%type <expr> FunctionCall
-%type <arg_list> ArgumentList
-%type <expr> Argument
-%type <expr> UnionExpr
-%type <expr> PathExpr
-%type <expr> FilterExpr
-%type <expr> OrExpr
-%type <expr> AndExpr
-%type <expr> EqualityExpr
-%type <expr> RelationalExpr
-%type <expr> AdditiveExpr
-%type <expr> MultiplicativeExpr
-%type <expr> UnaryExpr
+}
%%
Expr:
OrExpr
{
- parser->top_expr_ = $1;
+ parser_->top_expr_ = $1;
+ $$ = $1;
}
;
LocationPath:
RelativeLocationPath
{
+ $$ = $1;
$$->SetAbsolute(false);
}
|
AbsoluteLocationPath
{
+ $$ = $1;
$$->SetAbsolute(true);
}
;
@@ -161,11 +173,13 @@ RelativeLocationPath:
|
RelativeLocationPath '/' Step
{
+ $$ = $1;
$$->AppendStep($3);
}
|
RelativeLocationPath DescendantOrSelf Step
{
+ $$ = $1;
$$->AppendStep($2);
$$->AppendStep($3);
}
@@ -180,12 +194,12 @@ Step:
$$ = blink::MakeGarbageCollected<Step>(Step::kChildAxis, *$1);
}
|
- NAMETEST OptionalPredicateList
+ kNameTest OptionalPredicateList
{
AtomicString local_name;
AtomicString namespace_uri;
- if (!parser->ExpandQName(*$1, local_name, namespace_uri)) {
- parser->got_namespace_error_ = true;
+ if (!parser_->ExpandQName($1, local_name, namespace_uri)) {
+ parser_->got_namespace_error_ = true;
YYABORT;
}
@@ -193,7 +207,6 @@ Step:
$$ = blink::MakeGarbageCollected<Step>(Step::kChildAxis, Step::NodeTest(Step::NodeTest::kNameTest, local_name, namespace_uri), *$2);
else
$$ = blink::MakeGarbageCollected<Step>(Step::kChildAxis, Step::NodeTest(Step::NodeTest::kNameTest, local_name, namespace_uri));
- parser->DeleteString($1);
}
|
AxisSpecifier NodeTest OptionalPredicateList
@@ -204,12 +217,12 @@ Step:
$$ = blink::MakeGarbageCollected<Step>($1, *$2);
}
|
- AxisSpecifier NAMETEST OptionalPredicateList
+ AxisSpecifier kNameTest OptionalPredicateList
{
AtomicString local_name;
AtomicString namespace_uri;
- if (!parser->ExpandQName(*$2, local_name, namespace_uri)) {
- parser->got_namespace_error_ = true;
+ if (!parser_->ExpandQName($2, local_name, namespace_uri)) {
+ parser_->got_namespace_error_ = true;
YYABORT;
}
@@ -217,14 +230,13 @@ Step:
$$ = blink::MakeGarbageCollected<Step>($1, Step::NodeTest(Step::NodeTest::kNameTest, local_name, namespace_uri), *$3);
else
$$ = blink::MakeGarbageCollected<Step>($1, Step::NodeTest(Step::NodeTest::kNameTest, local_name, namespace_uri));
- parser->DeleteString($2);
}
|
AbbreviatedStep
;
AxisSpecifier:
- AXISNAME
+ kAxisName
|
'@'
{
@@ -233,29 +245,24 @@ AxisSpecifier:
;
NodeTest:
- NODETYPE '(' ')'
+ kNodeType '(' ')'
{
- if (*$1 == "node")
+ if ($1 == "node")
$$ = blink::MakeGarbageCollected<Step::NodeTest>(Step::NodeTest::kAnyNodeTest);
- else if (*$1 == "text")
+ else if ($1 == "text")
$$ = blink::MakeGarbageCollected<Step::NodeTest>(Step::NodeTest::kTextNodeTest);
- else if (*$1 == "comment")
+ else if ($1 == "comment")
$$ = blink::MakeGarbageCollected<Step::NodeTest>(Step::NodeTest::kCommentNodeTest);
-
- parser->DeleteString($1);
}
|
- PI '(' ')'
+ kPI '(' ')'
{
$$ = blink::MakeGarbageCollected<Step::NodeTest>(Step::NodeTest::kProcessingInstructionNodeTest);
- parser->DeleteString($1);
}
|
- PI '(' LITERAL ')'
+ kPI '(' kLiteral ')'
{
- $$ = blink::MakeGarbageCollected<Step::NodeTest>(Step::NodeTest::kProcessingInstructionNodeTest, $3->StripWhiteSpace());
- parser->DeleteString($1);
- parser->DeleteString($3);
+ $$ = blink::MakeGarbageCollected<Step::NodeTest>(Step::NodeTest::kProcessingInstructionNodeTest, $3.StripWhiteSpace());
}
;
@@ -266,6 +273,9 @@ OptionalPredicateList:
}
|
PredicateList
+ {
+ $$ = $1;
+ }
;
PredicateList:
@@ -277,6 +287,7 @@ PredicateList:
|
PredicateList Predicate
{
+ $$ = $1;
$$->push_back(blink::MakeGarbageCollected<blink::xpath::Predicate>($2));
}
;
@@ -289,7 +300,7 @@ Predicate:
;
DescendantOrSelf:
- SLASHSLASH
+ kSlashSlash
{
$$ = blink::MakeGarbageCollected<Step>(Step::kDescendantOrSelfAxis, Step::NodeTest(Step::NodeTest::kAnyNodeTest));
}
@@ -301,17 +312,16 @@ AbbreviatedStep:
$$ = blink::MakeGarbageCollected<Step>(Step::kSelfAxis, Step::NodeTest(Step::NodeTest::kAnyNodeTest));
}
|
- DOTDOT
+ kDotDot
{
$$ = blink::MakeGarbageCollected<Step>(Step::kParentAxis, Step::NodeTest(Step::NodeTest::kAnyNodeTest));
}
;
PrimaryExpr:
- VARIABLEREFERENCE
+ kVariableReference
{
- $$ = blink::MakeGarbageCollected<blink::xpath::VariableReference>(*$1);
- parser->DeleteString($1);
+ $$ = blink::MakeGarbageCollected<blink::xpath::VariableReference>($1);
}
|
'(' Expr ')'
@@ -319,36 +329,32 @@ PrimaryExpr:
$$ = $2;
}
|
- LITERAL
+ kLiteral
{
- $$ = blink::MakeGarbageCollected<blink::xpath::StringExpression>(*$1);
- parser->DeleteString($1);
+ $$ = blink::MakeGarbageCollected<blink::xpath::StringExpression>($1);
}
|
- NUMBER
+ kNumber
{
- $$ = blink::MakeGarbageCollected<blink::xpath::Number>($1->ToDouble());
- parser->DeleteString($1);
+ $$ = blink::MakeGarbageCollected<blink::xpath::Number>($1.ToDouble());
}
|
FunctionCall
;
FunctionCall:
- FUNCTIONNAME '(' ')'
+ kFunctionName '(' ')'
{
- $$ = blink::xpath::CreateFunction(*$1);
+ $$ = blink::xpath::CreateFunction($1);
if (!$$)
YYABORT;
- parser->DeleteString($1);
}
|
- FUNCTIONNAME '(' ArgumentList ')'
+ kFunctionName '(' ArgumentList ')'
{
- $$ = blink::xpath::CreateFunction(*$1, *$3);
+ $$ = blink::xpath::CreateFunction($1, *$3);
if (!$$)
YYABORT;
- parser->DeleteString($1);
}
;
@@ -361,6 +367,7 @@ ArgumentList:
|
ArgumentList ',' Argument
{
+ $$ = $1;
$$->push_back($3);
}
;
@@ -414,7 +421,7 @@ FilterExpr:
OrExpr:
AndExpr
|
- OrExpr OR AndExpr
+ OrExpr kOr AndExpr
{
$$ = blink::MakeGarbageCollected<blink::xpath::LogicalOp>(blink::xpath::LogicalOp::kOP_Or, $1, $3);
}
@@ -423,7 +430,7 @@ OrExpr:
AndExpr:
EqualityExpr
|
- AndExpr AND EqualityExpr
+ AndExpr kAnd EqualityExpr
{
$$ = blink::MakeGarbageCollected<blink::xpath::LogicalOp>(blink::xpath::LogicalOp::kOP_And, $1, $3);
}
@@ -432,7 +439,7 @@ AndExpr:
EqualityExpr:
RelationalExpr
|
- EqualityExpr EQOP RelationalExpr
+ EqualityExpr kEqOp RelationalExpr
{
$$ = blink::MakeGarbageCollected<blink::xpath::EqTestOp>($2, $1, $3);
}
@@ -441,7 +448,7 @@ EqualityExpr:
RelationalExpr:
AdditiveExpr
|
- RelationalExpr RELOP AdditiveExpr
+ RelationalExpr kRelOp AdditiveExpr
{
$$ = blink::MakeGarbageCollected<blink::xpath::EqTestOp>($2, $1, $3);
}
@@ -450,12 +457,12 @@ RelationalExpr:
AdditiveExpr:
MultiplicativeExpr
|
- AdditiveExpr PLUS MultiplicativeExpr
+ AdditiveExpr kPlus MultiplicativeExpr
{
$$ = blink::MakeGarbageCollected<blink::xpath::NumericOp>(blink::xpath::NumericOp::kOP_Add, $1, $3);
}
|
- AdditiveExpr MINUS MultiplicativeExpr
+ AdditiveExpr kMinus MultiplicativeExpr
{
$$ = blink::MakeGarbageCollected<blink::xpath::NumericOp>(blink::xpath::NumericOp::kOP_Sub, $1, $3);
}
@@ -464,7 +471,7 @@ AdditiveExpr:
MultiplicativeExpr:
UnaryExpr
|
- MultiplicativeExpr MULOP UnaryExpr
+ MultiplicativeExpr kMulOp UnaryExpr
{
$$ = blink::MakeGarbageCollected<blink::xpath::NumericOp>($2, $1, $3);
}
@@ -473,7 +480,7 @@ MultiplicativeExpr:
UnaryExpr:
UnionExpr
|
- MINUS UnaryExpr
+ kMinus UnaryExpr
{
$$ = blink::MakeGarbageCollected<blink::xpath::Negative>();
$$->AddSubExpression($2);
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_grammar_generated.cc b/chromium/third_party/blink/renderer/core/xml/xpath_grammar_generated.cc
new file mode 100644
index 00000000000..1934f5aa7d9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_grammar_generated.cc
@@ -0,0 +1,1987 @@
+// clang-format off
+// A Bison parser, made by GNU Bison 3.4.2.
+
+// Skeleton implementation for Bison LALR(1) parsers in C++
+
+// Copyright (C) 2002-2015, 2018-2019 Free Software Foundation, Inc.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+// As a special exception, you may create a larger work that contains
+// part or all of the Bison parser skeleton and distribute that work
+// under terms of your choice, so long as that work isn't itself a
+// parser generator using the skeleton or a modified version thereof
+// as a parser skeleton. Alternatively, if you modify or redistribute
+// the parser skeleton itself, you may (at your option) remove this
+// special exception, which will cause the skeleton and the resulting
+// Bison output files to be licensed under the GNU General Public
+// License without this special exception.
+
+// This special exception was added by the Free Software Foundation in
+// version 2.2 of Bison.
+
+// Undocumented macros, especially those whose name start with YY_,
+// are private implementation details. Do not rely on them.
+
+
+
+// First part of user prologue.
+#line 52 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+
+
+#include "third_party/blink/renderer/core/xml/xpath_functions.h"
+#include "third_party/blink/renderer/core/xml/xpath_ns_resolver.h"
+#include "third_party/blink/renderer/core/xml/xpath_parser.h"
+#include "third_party/blink/renderer/core/xml/xpath_path.h"
+#include "third_party/blink/renderer/core/xml/xpath_predicate.h"
+#include "third_party/blink/renderer/core/xml/xpath_step.h"
+#include "third_party/blink/renderer/core/xml/xpath_variable_reference.h"
+
+#define YYENABLE_NLS 0
+#define YY_EXCEPTIONS 0
+#define YYDEBUG 0
+
+using blink::xpath::Step;
+
+#line 57 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+
+
+#include "xpath_grammar_generated.h"
+
+
+// Unqualified %code blocks.
+#line 113 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+
+
+static int yylex(xpathyy::YyParser::semantic_type* yylval) {
+ return blink::xpath::Parser::Current()->Lex(yylval);
+}
+
+namespace xpathyy {
+void YyParser::error(const std::string&) { }
+}
+
+
+#line 76 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> // FIXME: INFRINGES ON USER NAME SPACE.
+# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(msgid) msgid
+# endif
+#endif
+
+// Whether we are compiled with exception support.
+#ifndef YY_EXCEPTIONS
+# if defined __GNUC__ && !defined __EXCEPTIONS
+# define YY_EXCEPTIONS 0
+# else
+# define YY_EXCEPTIONS 1
+# endif
+#endif
+
+
+
+// Enable debugging if requested.
+#if YYDEBUG
+
+// A pseudo ostream that takes yydebug_ into account.
+# define YYCDEBUG if (yydebug_) (*yycdebug_)
+
+# define YY_SYMBOL_PRINT(Title, Symbol) \
+ do { \
+ if (yydebug_) \
+ { \
+ *yycdebug_ << Title << ' '; \
+ yy_print_ (*yycdebug_, Symbol); \
+ *yycdebug_ << '\n'; \
+ } \
+ } while (false)
+
+# define YY_REDUCE_PRINT(Rule) \
+ do { \
+ if (yydebug_) \
+ yy_reduce_print_ (Rule); \
+ } while (false)
+
+# define YY_STACK_PRINT() \
+ do { \
+ if (yydebug_) \
+ yystack_print_ (); \
+ } while (false)
+
+#else // !YYDEBUG
+
+# define YYCDEBUG if (false) std::cerr
+# define YY_SYMBOL_PRINT(Title, Symbol) YYUSE (Symbol)
+# define YY_REDUCE_PRINT(Rule) static_cast<void> (0)
+# define YY_STACK_PRINT() static_cast<void> (0)
+
+#endif // !YYDEBUG
+
+#define yyerrok (yyerrstatus_ = 0)
+#define yyclearin (yyla.clear ())
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+#define YYRECOVERING() (!!yyerrstatus_)
+
+#line 69 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+namespace xpathyy {
+#line 149 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+
+
+ /// Build a parser object.
+ YyParser::YyParser (blink::xpath::Parser* parser__yyarg)
+ :
+#if YYDEBUG
+ yydebug_ (false),
+ yycdebug_ (&std::cerr),
+#endif
+ parser_ (parser__yyarg)
+ {}
+
+ YyParser::~YyParser ()
+ {}
+
+ YyParser::syntax_error::~syntax_error () YY_NOEXCEPT YY_NOTHROW
+ {}
+
+ /*---------------.
+ | Symbol types. |
+ `---------------*/
+
+ // basic_symbol.
+#if 201103L <= YY_CPLUSPLUS
+ template <typename Base>
+ YyParser::basic_symbol<Base>::basic_symbol (basic_symbol&& that)
+ : Base (std::move (that))
+ , value ()
+ {
+ switch (this->type_get ())
+ {
+ case 11: // kNodeType
+ case 12: // kPI
+ case 13: // kFunctionName
+ case 14: // kLiteral
+ case 15: // kVariableReference
+ case 16: // kNumber
+ case 19: // kNameTest
+ value.move< String > (std::move (that.value));
+ break;
+
+ case 45: // ArgumentList
+ value.move< blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>> > (std::move (that.value));
+ break;
+
+ case 38: // OptionalPredicateList
+ case 39: // PredicateList
+ value.move< blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > (std::move (that.value));
+ break;
+
+ case 31: // Expr
+ case 40: // Predicate
+ case 43: // PrimaryExpr
+ case 44: // FunctionCall
+ case 46: // Argument
+ case 47: // UnionExpr
+ case 48: // PathExpr
+ case 49: // FilterExpr
+ case 50: // OrExpr
+ case 51: // AndExpr
+ case 52: // EqualityExpr
+ case 53: // RelationalExpr
+ case 54: // AdditiveExpr
+ case 55: // MultiplicativeExpr
+ case 56: // UnaryExpr
+ value.move< blink::Persistent<blink::xpath::Expression> > (std::move (that.value));
+ break;
+
+ case 32: // LocationPath
+ case 33: // AbsoluteLocationPath
+ case 34: // RelativeLocationPath
+ value.move< blink::Persistent<blink::xpath::LocationPath> > (std::move (that.value));
+ break;
+
+ case 37: // NodeTest
+ value.move< blink::Persistent<blink::xpath::Step::NodeTest> > (std::move (that.value));
+ break;
+
+ case 35: // Step
+ case 41: // DescendantOrSelf
+ case 42: // AbbreviatedStep
+ value.move< blink::Persistent<blink::xpath::Step> > (std::move (that.value));
+ break;
+
+ case 4: // kEqOp
+ case 5: // kRelOp
+ value.move< blink::xpath::EqTestOp::Opcode > (std::move (that.value));
+ break;
+
+ case 3: // kMulOp
+ value.move< blink::xpath::NumericOp::Opcode > (std::move (that.value));
+ break;
+
+ case 10: // kAxisName
+ case 36: // AxisSpecifier
+ value.move< blink::xpath::Step::Axis > (std::move (that.value));
+ break;
+
+ default:
+ break;
+ }
+
+ }
+#endif
+
+ template <typename Base>
+ YyParser::basic_symbol<Base>::basic_symbol (const basic_symbol& that)
+ : Base (that)
+ , value ()
+ {
+ switch (this->type_get ())
+ {
+ case 11: // kNodeType
+ case 12: // kPI
+ case 13: // kFunctionName
+ case 14: // kLiteral
+ case 15: // kVariableReference
+ case 16: // kNumber
+ case 19: // kNameTest
+ value.copy< String > (YY_MOVE (that.value));
+ break;
+
+ case 45: // ArgumentList
+ value.copy< blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>> > (YY_MOVE (that.value));
+ break;
+
+ case 38: // OptionalPredicateList
+ case 39: // PredicateList
+ value.copy< blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > (YY_MOVE (that.value));
+ break;
+
+ case 31: // Expr
+ case 40: // Predicate
+ case 43: // PrimaryExpr
+ case 44: // FunctionCall
+ case 46: // Argument
+ case 47: // UnionExpr
+ case 48: // PathExpr
+ case 49: // FilterExpr
+ case 50: // OrExpr
+ case 51: // AndExpr
+ case 52: // EqualityExpr
+ case 53: // RelationalExpr
+ case 54: // AdditiveExpr
+ case 55: // MultiplicativeExpr
+ case 56: // UnaryExpr
+ value.copy< blink::Persistent<blink::xpath::Expression> > (YY_MOVE (that.value));
+ break;
+
+ case 32: // LocationPath
+ case 33: // AbsoluteLocationPath
+ case 34: // RelativeLocationPath
+ value.copy< blink::Persistent<blink::xpath::LocationPath> > (YY_MOVE (that.value));
+ break;
+
+ case 37: // NodeTest
+ value.copy< blink::Persistent<blink::xpath::Step::NodeTest> > (YY_MOVE (that.value));
+ break;
+
+ case 35: // Step
+ case 41: // DescendantOrSelf
+ case 42: // AbbreviatedStep
+ value.copy< blink::Persistent<blink::xpath::Step> > (YY_MOVE (that.value));
+ break;
+
+ case 4: // kEqOp
+ case 5: // kRelOp
+ value.copy< blink::xpath::EqTestOp::Opcode > (YY_MOVE (that.value));
+ break;
+
+ case 3: // kMulOp
+ value.copy< blink::xpath::NumericOp::Opcode > (YY_MOVE (that.value));
+ break;
+
+ case 10: // kAxisName
+ case 36: // AxisSpecifier
+ value.copy< blink::xpath::Step::Axis > (YY_MOVE (that.value));
+ break;
+
+ default:
+ break;
+ }
+
+ }
+
+
+
+ template <typename Base>
+ bool
+ YyParser::basic_symbol<Base>::empty () const YY_NOEXCEPT
+ {
+ return Base::type_get () == empty_symbol;
+ }
+
+ template <typename Base>
+ void
+ YyParser::basic_symbol<Base>::move (basic_symbol& s)
+ {
+ super_type::move (s);
+ switch (this->type_get ())
+ {
+ case 11: // kNodeType
+ case 12: // kPI
+ case 13: // kFunctionName
+ case 14: // kLiteral
+ case 15: // kVariableReference
+ case 16: // kNumber
+ case 19: // kNameTest
+ value.move< String > (YY_MOVE (s.value));
+ break;
+
+ case 45: // ArgumentList
+ value.move< blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>> > (YY_MOVE (s.value));
+ break;
+
+ case 38: // OptionalPredicateList
+ case 39: // PredicateList
+ value.move< blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > (YY_MOVE (s.value));
+ break;
+
+ case 31: // Expr
+ case 40: // Predicate
+ case 43: // PrimaryExpr
+ case 44: // FunctionCall
+ case 46: // Argument
+ case 47: // UnionExpr
+ case 48: // PathExpr
+ case 49: // FilterExpr
+ case 50: // OrExpr
+ case 51: // AndExpr
+ case 52: // EqualityExpr
+ case 53: // RelationalExpr
+ case 54: // AdditiveExpr
+ case 55: // MultiplicativeExpr
+ case 56: // UnaryExpr
+ value.move< blink::Persistent<blink::xpath::Expression> > (YY_MOVE (s.value));
+ break;
+
+ case 32: // LocationPath
+ case 33: // AbsoluteLocationPath
+ case 34: // RelativeLocationPath
+ value.move< blink::Persistent<blink::xpath::LocationPath> > (YY_MOVE (s.value));
+ break;
+
+ case 37: // NodeTest
+ value.move< blink::Persistent<blink::xpath::Step::NodeTest> > (YY_MOVE (s.value));
+ break;
+
+ case 35: // Step
+ case 41: // DescendantOrSelf
+ case 42: // AbbreviatedStep
+ value.move< blink::Persistent<blink::xpath::Step> > (YY_MOVE (s.value));
+ break;
+
+ case 4: // kEqOp
+ case 5: // kRelOp
+ value.move< blink::xpath::EqTestOp::Opcode > (YY_MOVE (s.value));
+ break;
+
+ case 3: // kMulOp
+ value.move< blink::xpath::NumericOp::Opcode > (YY_MOVE (s.value));
+ break;
+
+ case 10: // kAxisName
+ case 36: // AxisSpecifier
+ value.move< blink::xpath::Step::Axis > (YY_MOVE (s.value));
+ break;
+
+ default:
+ break;
+ }
+
+ }
+
+ // by_type.
+ YyParser::by_type::by_type ()
+ : type (empty_symbol)
+ {}
+
+#if 201103L <= YY_CPLUSPLUS
+ YyParser::by_type::by_type (by_type&& that)
+ : type (that.type)
+ {
+ that.clear ();
+ }
+#endif
+
+ YyParser::by_type::by_type (const by_type& that)
+ : type (that.type)
+ {}
+
+ YyParser::by_type::by_type (token_type t)
+ : type (yytranslate_ (t))
+ {}
+
+ void
+ YyParser::by_type::clear ()
+ {
+ type = empty_symbol;
+ }
+
+ void
+ YyParser::by_type::move (by_type& that)
+ {
+ type = that.type;
+ that.clear ();
+ }
+
+ int
+ YyParser::by_type::type_get () const YY_NOEXCEPT
+ {
+ return type;
+ }
+
+
+ // by_state.
+ YyParser::by_state::by_state () YY_NOEXCEPT
+ : state (empty_state)
+ {}
+
+ YyParser::by_state::by_state (const by_state& that) YY_NOEXCEPT
+ : state (that.state)
+ {}
+
+ void
+ YyParser::by_state::clear () YY_NOEXCEPT
+ {
+ state = empty_state;
+ }
+
+ void
+ YyParser::by_state::move (by_state& that)
+ {
+ state = that.state;
+ that.clear ();
+ }
+
+ YyParser::by_state::by_state (state_type s) YY_NOEXCEPT
+ : state (s)
+ {}
+
+ YyParser::symbol_number_type
+ YyParser::by_state::type_get () const YY_NOEXCEPT
+ {
+ if (state == empty_state)
+ return empty_symbol;
+ else
+ return yystos_[state];
+ }
+
+ YyParser::stack_symbol_type::stack_symbol_type ()
+ {}
+
+ YyParser::stack_symbol_type::stack_symbol_type (YY_RVREF (stack_symbol_type) that)
+ : super_type (YY_MOVE (that.state))
+ {
+ switch (that.type_get ())
+ {
+ case 11: // kNodeType
+ case 12: // kPI
+ case 13: // kFunctionName
+ case 14: // kLiteral
+ case 15: // kVariableReference
+ case 16: // kNumber
+ case 19: // kNameTest
+ value.YY_MOVE_OR_COPY< String > (YY_MOVE (that.value));
+ break;
+
+ case 45: // ArgumentList
+ value.YY_MOVE_OR_COPY< blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>> > (YY_MOVE (that.value));
+ break;
+
+ case 38: // OptionalPredicateList
+ case 39: // PredicateList
+ value.YY_MOVE_OR_COPY< blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > (YY_MOVE (that.value));
+ break;
+
+ case 31: // Expr
+ case 40: // Predicate
+ case 43: // PrimaryExpr
+ case 44: // FunctionCall
+ case 46: // Argument
+ case 47: // UnionExpr
+ case 48: // PathExpr
+ case 49: // FilterExpr
+ case 50: // OrExpr
+ case 51: // AndExpr
+ case 52: // EqualityExpr
+ case 53: // RelationalExpr
+ case 54: // AdditiveExpr
+ case 55: // MultiplicativeExpr
+ case 56: // UnaryExpr
+ value.YY_MOVE_OR_COPY< blink::Persistent<blink::xpath::Expression> > (YY_MOVE (that.value));
+ break;
+
+ case 32: // LocationPath
+ case 33: // AbsoluteLocationPath
+ case 34: // RelativeLocationPath
+ value.YY_MOVE_OR_COPY< blink::Persistent<blink::xpath::LocationPath> > (YY_MOVE (that.value));
+ break;
+
+ case 37: // NodeTest
+ value.YY_MOVE_OR_COPY< blink::Persistent<blink::xpath::Step::NodeTest> > (YY_MOVE (that.value));
+ break;
+
+ case 35: // Step
+ case 41: // DescendantOrSelf
+ case 42: // AbbreviatedStep
+ value.YY_MOVE_OR_COPY< blink::Persistent<blink::xpath::Step> > (YY_MOVE (that.value));
+ break;
+
+ case 4: // kEqOp
+ case 5: // kRelOp
+ value.YY_MOVE_OR_COPY< blink::xpath::EqTestOp::Opcode > (YY_MOVE (that.value));
+ break;
+
+ case 3: // kMulOp
+ value.YY_MOVE_OR_COPY< blink::xpath::NumericOp::Opcode > (YY_MOVE (that.value));
+ break;
+
+ case 10: // kAxisName
+ case 36: // AxisSpecifier
+ value.YY_MOVE_OR_COPY< blink::xpath::Step::Axis > (YY_MOVE (that.value));
+ break;
+
+ default:
+ break;
+ }
+
+#if 201103L <= YY_CPLUSPLUS
+ // that is emptied.
+ that.state = empty_state;
+#endif
+ }
+
+ YyParser::stack_symbol_type::stack_symbol_type (state_type s, YY_MOVE_REF (symbol_type) that)
+ : super_type (s)
+ {
+ switch (that.type_get ())
+ {
+ case 11: // kNodeType
+ case 12: // kPI
+ case 13: // kFunctionName
+ case 14: // kLiteral
+ case 15: // kVariableReference
+ case 16: // kNumber
+ case 19: // kNameTest
+ value.move< String > (YY_MOVE (that.value));
+ break;
+
+ case 45: // ArgumentList
+ value.move< blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>> > (YY_MOVE (that.value));
+ break;
+
+ case 38: // OptionalPredicateList
+ case 39: // PredicateList
+ value.move< blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > (YY_MOVE (that.value));
+ break;
+
+ case 31: // Expr
+ case 40: // Predicate
+ case 43: // PrimaryExpr
+ case 44: // FunctionCall
+ case 46: // Argument
+ case 47: // UnionExpr
+ case 48: // PathExpr
+ case 49: // FilterExpr
+ case 50: // OrExpr
+ case 51: // AndExpr
+ case 52: // EqualityExpr
+ case 53: // RelationalExpr
+ case 54: // AdditiveExpr
+ case 55: // MultiplicativeExpr
+ case 56: // UnaryExpr
+ value.move< blink::Persistent<blink::xpath::Expression> > (YY_MOVE (that.value));
+ break;
+
+ case 32: // LocationPath
+ case 33: // AbsoluteLocationPath
+ case 34: // RelativeLocationPath
+ value.move< blink::Persistent<blink::xpath::LocationPath> > (YY_MOVE (that.value));
+ break;
+
+ case 37: // NodeTest
+ value.move< blink::Persistent<blink::xpath::Step::NodeTest> > (YY_MOVE (that.value));
+ break;
+
+ case 35: // Step
+ case 41: // DescendantOrSelf
+ case 42: // AbbreviatedStep
+ value.move< blink::Persistent<blink::xpath::Step> > (YY_MOVE (that.value));
+ break;
+
+ case 4: // kEqOp
+ case 5: // kRelOp
+ value.move< blink::xpath::EqTestOp::Opcode > (YY_MOVE (that.value));
+ break;
+
+ case 3: // kMulOp
+ value.move< blink::xpath::NumericOp::Opcode > (YY_MOVE (that.value));
+ break;
+
+ case 10: // kAxisName
+ case 36: // AxisSpecifier
+ value.move< blink::xpath::Step::Axis > (YY_MOVE (that.value));
+ break;
+
+ default:
+ break;
+ }
+
+ // that is emptied.
+ that.type = empty_symbol;
+ }
+
+#if YY_CPLUSPLUS < 201103L
+ YyParser::stack_symbol_type&
+ YyParser::stack_symbol_type::operator= (stack_symbol_type& that)
+ {
+ state = that.state;
+ switch (that.type_get ())
+ {
+ case 11: // kNodeType
+ case 12: // kPI
+ case 13: // kFunctionName
+ case 14: // kLiteral
+ case 15: // kVariableReference
+ case 16: // kNumber
+ case 19: // kNameTest
+ value.move< String > (that.value);
+ break;
+
+ case 45: // ArgumentList
+ value.move< blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>> > (that.value);
+ break;
+
+ case 38: // OptionalPredicateList
+ case 39: // PredicateList
+ value.move< blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > (that.value);
+ break;
+
+ case 31: // Expr
+ case 40: // Predicate
+ case 43: // PrimaryExpr
+ case 44: // FunctionCall
+ case 46: // Argument
+ case 47: // UnionExpr
+ case 48: // PathExpr
+ case 49: // FilterExpr
+ case 50: // OrExpr
+ case 51: // AndExpr
+ case 52: // EqualityExpr
+ case 53: // RelationalExpr
+ case 54: // AdditiveExpr
+ case 55: // MultiplicativeExpr
+ case 56: // UnaryExpr
+ value.move< blink::Persistent<blink::xpath::Expression> > (that.value);
+ break;
+
+ case 32: // LocationPath
+ case 33: // AbsoluteLocationPath
+ case 34: // RelativeLocationPath
+ value.move< blink::Persistent<blink::xpath::LocationPath> > (that.value);
+ break;
+
+ case 37: // NodeTest
+ value.move< blink::Persistent<blink::xpath::Step::NodeTest> > (that.value);
+ break;
+
+ case 35: // Step
+ case 41: // DescendantOrSelf
+ case 42: // AbbreviatedStep
+ value.move< blink::Persistent<blink::xpath::Step> > (that.value);
+ break;
+
+ case 4: // kEqOp
+ case 5: // kRelOp
+ value.move< blink::xpath::EqTestOp::Opcode > (that.value);
+ break;
+
+ case 3: // kMulOp
+ value.move< blink::xpath::NumericOp::Opcode > (that.value);
+ break;
+
+ case 10: // kAxisName
+ case 36: // AxisSpecifier
+ value.move< blink::xpath::Step::Axis > (that.value);
+ break;
+
+ default:
+ break;
+ }
+
+ // that is emptied.
+ that.state = empty_state;
+ return *this;
+ }
+#endif
+
+ template <typename Base>
+ void
+ YyParser::yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const
+ {
+ if (yymsg)
+ YY_SYMBOL_PRINT (yymsg, yysym);
+ }
+
+#if YYDEBUG
+ template <typename Base>
+ void
+ YyParser::yy_print_ (std::ostream& yyo,
+ const basic_symbol<Base>& yysym) const
+ {
+ std::ostream& yyoutput = yyo;
+ YYUSE (yyoutput);
+ symbol_number_type yytype = yysym.type_get ();
+#if defined __GNUC__ && ! defined __clang__ && ! defined __ICC && __GNUC__ * 100 + __GNUC_MINOR__ <= 408
+ // Avoid a (spurious) G++ 4.8 warning about "array subscript is
+ // below array bounds".
+ if (yysym.empty ())
+ std::abort ();
+#endif
+ yyo << (yytype < yyntokens_ ? "token" : "nterm")
+ << ' ' << yytname_[yytype] << " (";
+ YYUSE (yytype);
+ yyo << ')';
+ }
+#endif
+
+ void
+ YyParser::yypush_ (const char* m, YY_MOVE_REF (stack_symbol_type) sym)
+ {
+ if (m)
+ YY_SYMBOL_PRINT (m, sym);
+ yystack_.push (YY_MOVE (sym));
+ }
+
+ void
+ YyParser::yypush_ (const char* m, state_type s, YY_MOVE_REF (symbol_type) sym)
+ {
+#if 201103L <= YY_CPLUSPLUS
+ yypush_ (m, stack_symbol_type (s, std::move (sym)));
+#else
+ stack_symbol_type ss (s, sym);
+ yypush_ (m, ss);
+#endif
+ }
+
+ void
+ YyParser::yypop_ (int n)
+ {
+ yystack_.pop (n);
+ }
+
+#if YYDEBUG
+ std::ostream&
+ YyParser::debug_stream () const
+ {
+ return *yycdebug_;
+ }
+
+ void
+ YyParser::set_debug_stream (std::ostream& o)
+ {
+ yycdebug_ = &o;
+ }
+
+
+ YyParser::debug_level_type
+ YyParser::debug_level () const
+ {
+ return yydebug_;
+ }
+
+ void
+ YyParser::set_debug_level (debug_level_type l)
+ {
+ yydebug_ = l;
+ }
+#endif // YYDEBUG
+
+ YyParser::state_type
+ YyParser::yy_lr_goto_state_ (state_type yystate, int yysym)
+ {
+ int yyr = yypgoto_[yysym - yyntokens_] + yystate;
+ if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
+ return yytable_[yyr];
+ else
+ return yydefgoto_[yysym - yyntokens_];
+ }
+
+ bool
+ YyParser::yy_pact_value_is_default_ (int yyvalue)
+ {
+ return yyvalue == yypact_ninf_;
+ }
+
+ bool
+ YyParser::yy_table_value_is_error_ (int yyvalue)
+ {
+ return yyvalue == yytable_ninf_;
+ }
+
+ int
+ YyParser::operator() ()
+ {
+ return parse ();
+ }
+
+ int
+ YyParser::parse ()
+ {
+ // State.
+ int yyn;
+ /// Length of the RHS of the rule being reduced.
+ int yylen = 0;
+
+ // Error handling.
+ int yynerrs_ = 0;
+ int yyerrstatus_ = 0;
+
+ /// The lookahead symbol.
+ symbol_type yyla;
+
+ /// The return value of parse ().
+ int yyresult;
+
+#if YY_EXCEPTIONS
+ try
+#endif // YY_EXCEPTIONS
+ {
+ YYCDEBUG << "Starting parse\n";
+
+
+ /* Initialize the stack. The initial state will be set in
+ yynewstate, since the latter expects the semantical and the
+ location values to have been already stored, initialize these
+ stacks with a primary value. */
+ yystack_.clear ();
+ yypush_ (YY_NULLPTR, 0, YY_MOVE (yyla));
+
+ /*-----------------------------------------------.
+ | yynewstate -- push a new symbol on the stack. |
+ `-----------------------------------------------*/
+ yynewstate:
+ YYCDEBUG << "Entering state " << yystack_[0].state << '\n';
+
+ // Accept?
+ if (yystack_[0].state == yyfinal_)
+ YYACCEPT;
+
+ goto yybackup;
+
+
+ /*-----------.
+ | yybackup. |
+ `-----------*/
+ yybackup:
+ // Try to take a decision without lookahead.
+ yyn = yypact_[yystack_[0].state];
+ if (yy_pact_value_is_default_ (yyn))
+ goto yydefault;
+
+ // Read a lookahead token.
+ if (yyla.empty ())
+ {
+ YYCDEBUG << "Reading a token: ";
+#if YY_EXCEPTIONS
+ try
+#endif // YY_EXCEPTIONS
+ {
+ yyla.type = yytranslate_ (yylex (&yyla.value));
+ }
+#if YY_EXCEPTIONS
+ catch (const syntax_error& yyexc)
+ {
+ YYCDEBUG << "Caught exception: " << yyexc.what() << '\n';
+ error (yyexc);
+ goto yyerrlab1;
+ }
+#endif // YY_EXCEPTIONS
+ }
+ YY_SYMBOL_PRINT ("Next token is", yyla);
+
+ /* If the proper action on seeing token YYLA.TYPE is to reduce or
+ to detect an error, take that action. */
+ yyn += yyla.type_get ();
+ if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yyla.type_get ())
+ goto yydefault;
+
+ // Reduce or error.
+ yyn = yytable_[yyn];
+ if (yyn <= 0)
+ {
+ if (yy_table_value_is_error_ (yyn))
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ // Count tokens shifted since error; after three, turn off error status.
+ if (yyerrstatus_)
+ --yyerrstatus_;
+
+ // Shift the lookahead token.
+ yypush_ ("Shifting", yyn, YY_MOVE (yyla));
+ goto yynewstate;
+
+
+ /*-----------------------------------------------------------.
+ | yydefault -- do the default action for the current state. |
+ `-----------------------------------------------------------*/
+ yydefault:
+ yyn = yydefact_[yystack_[0].state];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+ /*-----------------------------.
+ | yyreduce -- do a reduction. |
+ `-----------------------------*/
+ yyreduce:
+ yylen = yyr2_[yyn];
+ {
+ stack_symbol_type yylhs;
+ yylhs.state = yy_lr_goto_state_ (yystack_[yylen].state, yyr1_[yyn]);
+ /* Variants are always initialized to an empty instance of the
+ correct type. The default '$$ = $1' action is NOT applied
+ when using variants. */
+ switch (yyr1_[yyn])
+ {
+ case 11: // kNodeType
+ case 12: // kPI
+ case 13: // kFunctionName
+ case 14: // kLiteral
+ case 15: // kVariableReference
+ case 16: // kNumber
+ case 19: // kNameTest
+ yylhs.value.emplace< String > ();
+ break;
+
+ case 45: // ArgumentList
+ yylhs.value.emplace< blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>> > ();
+ break;
+
+ case 38: // OptionalPredicateList
+ case 39: // PredicateList
+ yylhs.value.emplace< blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ();
+ break;
+
+ case 31: // Expr
+ case 40: // Predicate
+ case 43: // PrimaryExpr
+ case 44: // FunctionCall
+ case 46: // Argument
+ case 47: // UnionExpr
+ case 48: // PathExpr
+ case 49: // FilterExpr
+ case 50: // OrExpr
+ case 51: // AndExpr
+ case 52: // EqualityExpr
+ case 53: // RelationalExpr
+ case 54: // AdditiveExpr
+ case 55: // MultiplicativeExpr
+ case 56: // UnaryExpr
+ yylhs.value.emplace< blink::Persistent<blink::xpath::Expression> > ();
+ break;
+
+ case 32: // LocationPath
+ case 33: // AbsoluteLocationPath
+ case 34: // RelativeLocationPath
+ yylhs.value.emplace< blink::Persistent<blink::xpath::LocationPath> > ();
+ break;
+
+ case 37: // NodeTest
+ yylhs.value.emplace< blink::Persistent<blink::xpath::Step::NodeTest> > ();
+ break;
+
+ case 35: // Step
+ case 41: // DescendantOrSelf
+ case 42: // AbbreviatedStep
+ yylhs.value.emplace< blink::Persistent<blink::xpath::Step> > ();
+ break;
+
+ case 4: // kEqOp
+ case 5: // kRelOp
+ yylhs.value.emplace< blink::xpath::EqTestOp::Opcode > ();
+ break;
+
+ case 3: // kMulOp
+ yylhs.value.emplace< blink::xpath::NumericOp::Opcode > ();
+ break;
+
+ case 10: // kAxisName
+ case 36: // AxisSpecifier
+ yylhs.value.emplace< blink::xpath::Step::Axis > ();
+ break;
+
+ default:
+ break;
+ }
+
+
+
+ // Perform the reduction.
+ YY_REDUCE_PRINT (yyn);
+#if YY_EXCEPTIONS
+ try
+#endif // YY_EXCEPTIONS
+ {
+ switch (yyn)
+ {
+ case 2:
+#line 129 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ parser_->top_expr_ = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ();
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ();
+ }
+#line 1069 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 3:
+#line 137 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::LocationPath> > ();
+ yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > ()->SetAbsolute(false);
+ }
+#line 1078 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 4:
+#line 143 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::LocationPath> > ();
+ yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > ()->SetAbsolute(true);
+ }
+#line 1087 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 5:
+#line 151 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > () = blink::MakeGarbageCollected<blink::xpath::LocationPath>();
+ }
+#line 1095 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 6:
+#line 156 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::LocationPath> > ();
+ }
+#line 1103 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 7:
+#line 161 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::LocationPath> > ();
+ yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > ()->InsertFirstStep(yystack_[1].value.as < blink::Persistent<blink::xpath::Step> > ());
+ }
+#line 1112 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 8:
+#line 169 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > () = blink::MakeGarbageCollected<blink::xpath::LocationPath>();
+ yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > ()->AppendStep(yystack_[0].value.as < blink::Persistent<blink::xpath::Step> > ());
+ }
+#line 1121 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 9:
+#line 175 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > () = yystack_[2].value.as < blink::Persistent<blink::xpath::LocationPath> > ();
+ yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > ()->AppendStep(yystack_[0].value.as < blink::Persistent<blink::xpath::Step> > ());
+ }
+#line 1130 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 10:
+#line 181 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > () = yystack_[2].value.as < blink::Persistent<blink::xpath::LocationPath> > ();
+ yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > ()->AppendStep(yystack_[1].value.as < blink::Persistent<blink::xpath::Step> > ());
+ yylhs.value.as < blink::Persistent<blink::xpath::LocationPath> > ()->AppendStep(yystack_[0].value.as < blink::Persistent<blink::xpath::Step> > ());
+ }
+#line 1140 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 11:
+#line 190 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ if (yystack_[0].value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ())
+ yylhs.value.as < blink::Persistent<blink::xpath::Step> > () = blink::MakeGarbageCollected<Step>(Step::kChildAxis, *yystack_[1].value.as < blink::Persistent<blink::xpath::Step::NodeTest> > (), *yystack_[0].value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ());
+ else
+ yylhs.value.as < blink::Persistent<blink::xpath::Step> > () = blink::MakeGarbageCollected<Step>(Step::kChildAxis, *yystack_[1].value.as < blink::Persistent<blink::xpath::Step::NodeTest> > ());
+ }
+#line 1151 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 12:
+#line 198 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ AtomicString local_name;
+ AtomicString namespace_uri;
+ if (!parser_->ExpandQName(yystack_[1].value.as < String > (), local_name, namespace_uri)) {
+ parser_->got_namespace_error_ = true;
+ YYABORT;
+ }
+
+ if (yystack_[0].value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ())
+ yylhs.value.as < blink::Persistent<blink::xpath::Step> > () = blink::MakeGarbageCollected<Step>(Step::kChildAxis, Step::NodeTest(Step::NodeTest::kNameTest, local_name, namespace_uri), *yystack_[0].value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ());
+ else
+ yylhs.value.as < blink::Persistent<blink::xpath::Step> > () = blink::MakeGarbageCollected<Step>(Step::kChildAxis, Step::NodeTest(Step::NodeTest::kNameTest, local_name, namespace_uri));
+ }
+#line 1169 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 13:
+#line 213 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ if (yystack_[0].value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ())
+ yylhs.value.as < blink::Persistent<blink::xpath::Step> > () = blink::MakeGarbageCollected<Step>(yystack_[2].value.as < blink::xpath::Step::Axis > (), *yystack_[1].value.as < blink::Persistent<blink::xpath::Step::NodeTest> > (), *yystack_[0].value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ());
+ else
+ yylhs.value.as < blink::Persistent<blink::xpath::Step> > () = blink::MakeGarbageCollected<Step>(yystack_[2].value.as < blink::xpath::Step::Axis > (), *yystack_[1].value.as < blink::Persistent<blink::xpath::Step::NodeTest> > ());
+ }
+#line 1180 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 14:
+#line 221 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ AtomicString local_name;
+ AtomicString namespace_uri;
+ if (!parser_->ExpandQName(yystack_[1].value.as < String > (), local_name, namespace_uri)) {
+ parser_->got_namespace_error_ = true;
+ YYABORT;
+ }
+
+ if (yystack_[0].value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ())
+ yylhs.value.as < blink::Persistent<blink::xpath::Step> > () = blink::MakeGarbageCollected<Step>(yystack_[2].value.as < blink::xpath::Step::Axis > (), Step::NodeTest(Step::NodeTest::kNameTest, local_name, namespace_uri), *yystack_[0].value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ());
+ else
+ yylhs.value.as < blink::Persistent<blink::xpath::Step> > () = blink::MakeGarbageCollected<Step>(yystack_[2].value.as < blink::xpath::Step::Axis > (), Step::NodeTest(Step::NodeTest::kNameTest, local_name, namespace_uri));
+ }
+#line 1198 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 15:
+#line 235 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ { yylhs.value.as < blink::Persistent<blink::xpath::Step> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Step> > (); }
+#line 1204 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 16:
+#line 239 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ { yylhs.value.as < blink::xpath::Step::Axis > () = yystack_[0].value.as < blink::xpath::Step::Axis > (); }
+#line 1210 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 17:
+#line 242 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::xpath::Step::Axis > () = Step::kAttributeAxis;
+ }
+#line 1218 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 18:
+#line 249 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ if (yystack_[2].value.as < String > () == "node")
+ yylhs.value.as < blink::Persistent<blink::xpath::Step::NodeTest> > () = blink::MakeGarbageCollected<Step::NodeTest>(Step::NodeTest::kAnyNodeTest);
+ else if (yystack_[2].value.as < String > () == "text")
+ yylhs.value.as < blink::Persistent<blink::xpath::Step::NodeTest> > () = blink::MakeGarbageCollected<Step::NodeTest>(Step::NodeTest::kTextNodeTest);
+ else if (yystack_[2].value.as < String > () == "comment")
+ yylhs.value.as < blink::Persistent<blink::xpath::Step::NodeTest> > () = blink::MakeGarbageCollected<Step::NodeTest>(Step::NodeTest::kCommentNodeTest);
+ }
+#line 1231 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 19:
+#line 259 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::Step::NodeTest> > () = blink::MakeGarbageCollected<Step::NodeTest>(Step::NodeTest::kProcessingInstructionNodeTest);
+ }
+#line 1239 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 20:
+#line 264 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::Step::NodeTest> > () = blink::MakeGarbageCollected<Step::NodeTest>(Step::NodeTest::kProcessingInstructionNodeTest, yystack_[1].value.as < String > ().StripWhiteSpace());
+ }
+#line 1247 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 21:
+#line 271 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > () = 0;
+ }
+#line 1255 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 22:
+#line 276 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > () = yystack_[0].value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ();
+ }
+#line 1263 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 23:
+#line 283 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > () = blink::MakeGarbageCollected<blink::HeapVector<blink::Member<blink::xpath::Predicate>>>();
+ yylhs.value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ()->push_back(blink::MakeGarbageCollected<blink::xpath::Predicate>(yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ()));
+ }
+#line 1272 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 24:
+#line 289 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > () = yystack_[1].value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ();
+ yylhs.value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ()->push_back(blink::MakeGarbageCollected<blink::xpath::Predicate>(yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ()));
+ }
+#line 1281 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 25:
+#line 297 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[1].value.as < blink::Persistent<blink::xpath::Expression> > ();
+ }
+#line 1289 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 26:
+#line 304 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::Step> > () = blink::MakeGarbageCollected<Step>(Step::kDescendantOrSelfAxis, Step::NodeTest(Step::NodeTest::kAnyNodeTest));
+ }
+#line 1297 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 27:
+#line 311 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::Step> > () = blink::MakeGarbageCollected<Step>(Step::kSelfAxis, Step::NodeTest(Step::NodeTest::kAnyNodeTest));
+ }
+#line 1305 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 28:
+#line 316 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::Step> > () = blink::MakeGarbageCollected<Step>(Step::kParentAxis, Step::NodeTest(Step::NodeTest::kAnyNodeTest));
+ }
+#line 1313 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 29:
+#line 323 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::VariableReference>(yystack_[0].value.as < String > ());
+ }
+#line 1321 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 30:
+#line 328 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[1].value.as < blink::Persistent<blink::xpath::Expression> > ();
+ }
+#line 1329 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 31:
+#line 333 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::StringExpression>(yystack_[0].value.as < String > ());
+ }
+#line 1337 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 32:
+#line 338 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::Number>(yystack_[0].value.as < String > ().ToDouble());
+ }
+#line 1345 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 33:
+#line 342 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
+#line 1351 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 34:
+#line 347 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::xpath::CreateFunction(yystack_[2].value.as < String > ());
+ if (!yylhs.value.as < blink::Persistent<blink::xpath::Expression> > ())
+ YYABORT;
+ }
+#line 1361 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 35:
+#line 354 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::xpath::CreateFunction(yystack_[3].value.as < String > (), *yystack_[1].value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>> > ());
+ if (!yylhs.value.as < blink::Persistent<blink::xpath::Expression> > ())
+ YYABORT;
+ }
+#line 1371 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 36:
+#line 363 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>> > () = blink::MakeGarbageCollected<blink::HeapVector<blink::Member<blink::xpath::Expression>>>();
+ yylhs.value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>> > ()->push_back(yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ());
+ }
+#line 1380 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 37:
+#line 369 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>> > () = yystack_[2].value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>> > ();
+ yylhs.value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>> > ()->push_back(yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ());
+ }
+#line 1389 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 38:
+#line 376 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
+#line 1395 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 39:
+#line 380 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
+#line 1401 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 40:
+#line 383 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::Union>();
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > ()->AddSubExpression(yystack_[2].value.as < blink::Persistent<blink::xpath::Expression> > ());
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > ()->AddSubExpression(yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ());
+ }
+#line 1411 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 41:
+#line 392 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::LocationPath> > ();
+ }
+#line 1419 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 42:
+#line 396 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
+#line 1425 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 43:
+#line 399 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yystack_[0].value.as < blink::Persistent<blink::xpath::LocationPath> > ()->SetAbsolute(true);
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::Path>(yystack_[2].value.as < blink::Persistent<blink::xpath::Expression> > (), yystack_[0].value.as < blink::Persistent<blink::xpath::LocationPath> > ());
+ }
+#line 1434 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 44:
+#line 405 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yystack_[0].value.as < blink::Persistent<blink::xpath::LocationPath> > ()->InsertFirstStep(yystack_[1].value.as < blink::Persistent<blink::xpath::Step> > ());
+ yystack_[0].value.as < blink::Persistent<blink::xpath::LocationPath> > ()->SetAbsolute(true);
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::Path>(yystack_[2].value.as < blink::Persistent<blink::xpath::Expression> > (), yystack_[0].value.as < blink::Persistent<blink::xpath::LocationPath> > ());
+ }
+#line 1444 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 45:
+#line 413 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
+#line 1450 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 46:
+#line 416 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::Filter>(yystack_[1].value.as < blink::Persistent<blink::xpath::Expression> > (), *yystack_[0].value.as < blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ());
+ }
+#line 1458 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 47:
+#line 422 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
+#line 1464 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 48:
+#line 425 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::LogicalOp>(blink::xpath::LogicalOp::kOP_Or, yystack_[2].value.as < blink::Persistent<blink::xpath::Expression> > (), yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ());
+ }
+#line 1472 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 49:
+#line 431 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
+#line 1478 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 50:
+#line 434 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::LogicalOp>(blink::xpath::LogicalOp::kOP_And, yystack_[2].value.as < blink::Persistent<blink::xpath::Expression> > (), yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ());
+ }
+#line 1486 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 51:
+#line 440 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
+#line 1492 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 52:
+#line 443 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::EqTestOp>(yystack_[1].value.as < blink::xpath::EqTestOp::Opcode > (), yystack_[2].value.as < blink::Persistent<blink::xpath::Expression> > (), yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ());
+ }
+#line 1500 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 53:
+#line 449 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
+#line 1506 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 54:
+#line 452 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::EqTestOp>(yystack_[1].value.as < blink::xpath::EqTestOp::Opcode > (), yystack_[2].value.as < blink::Persistent<blink::xpath::Expression> > (), yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ());
+ }
+#line 1514 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 55:
+#line 458 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
+#line 1520 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 56:
+#line 461 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::NumericOp>(blink::xpath::NumericOp::kOP_Add, yystack_[2].value.as < blink::Persistent<blink::xpath::Expression> > (), yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ());
+ }
+#line 1528 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 57:
+#line 466 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::NumericOp>(blink::xpath::NumericOp::kOP_Sub, yystack_[2].value.as < blink::Persistent<blink::xpath::Expression> > (), yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ());
+ }
+#line 1536 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 58:
+#line 472 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
+#line 1542 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 59:
+#line 475 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::NumericOp>(yystack_[1].value.as < blink::xpath::NumericOp::Opcode > (), yystack_[2].value.as < blink::Persistent<blink::xpath::Expression> > (), yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ());
+ }
+#line 1550 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 60:
+#line 481 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ { yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > (); }
+#line 1556 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+ case 61:
+#line 484 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+ {
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > () = blink::MakeGarbageCollected<blink::xpath::Negative>();
+ yylhs.value.as < blink::Persistent<blink::xpath::Expression> > ()->AddSubExpression(yystack_[0].value.as < blink::Persistent<blink::xpath::Expression> > ());
+ }
+#line 1565 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+ break;
+
+
+#line 1569 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+
+ default:
+ break;
+ }
+ }
+#if YY_EXCEPTIONS
+ catch (const syntax_error& yyexc)
+ {
+ YYCDEBUG << "Caught exception: " << yyexc.what() << '\n';
+ error (yyexc);
+ YYERROR;
+ }
+#endif // YY_EXCEPTIONS
+ YY_SYMBOL_PRINT ("-> $$ =", yylhs);
+ yypop_ (yylen);
+ yylen = 0;
+ YY_STACK_PRINT ();
+
+ // Shift the result of the reduction.
+ yypush_ (YY_NULLPTR, YY_MOVE (yylhs));
+ }
+ goto yynewstate;
+
+
+ /*--------------------------------------.
+ | yyerrlab -- here on detecting error. |
+ `--------------------------------------*/
+ yyerrlab:
+ // If not already recovering from an error, report this error.
+ if (!yyerrstatus_)
+ {
+ ++yynerrs_;
+ error (yysyntax_error_ (yystack_[0].state, yyla));
+ }
+
+
+ if (yyerrstatus_ == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ // Return failure if at end of input.
+ if (yyla.type_get () == yyeof_)
+ YYABORT;
+ else if (!yyla.empty ())
+ {
+ yy_destroy_ ("Error: discarding", yyla);
+ yyla.clear ();
+ }
+ }
+
+ // Else will try to reuse lookahead token after shifting the error token.
+ goto yyerrlab1;
+
+
+ /*---------------------------------------------------.
+ | yyerrorlab -- error raised explicitly by YYERROR. |
+ `---------------------------------------------------*/
+ yyerrorlab:
+ /* Pacify compilers when the user code never invokes YYERROR and
+ the label yyerrorlab therefore never appears in user code. */
+ if (false)
+ YYERROR;
+
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYERROR. */
+ yypop_ (yylen);
+ yylen = 0;
+ goto yyerrlab1;
+
+
+ /*-------------------------------------------------------------.
+ | yyerrlab1 -- common code for both syntax error and YYERROR. |
+ `-------------------------------------------------------------*/
+ yyerrlab1:
+ yyerrstatus_ = 3; // Each real token shifted decrements this.
+ {
+ stack_symbol_type error_token;
+ for (;;)
+ {
+ yyn = yypact_[yystack_[0].state];
+ if (!yy_pact_value_is_default_ (yyn))
+ {
+ yyn += yyterror_;
+ if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_)
+ {
+ yyn = yytable_[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ // Pop the current state because it cannot handle the error token.
+ if (yystack_.size () == 1)
+ YYABORT;
+
+ yy_destroy_ ("Error: popping", yystack_[0]);
+ yypop_ ();
+ YY_STACK_PRINT ();
+ }
+
+
+ // Shift the error token.
+ error_token.state = yyn;
+ yypush_ ("Shifting", YY_MOVE (error_token));
+ }
+ goto yynewstate;
+
+
+ /*-------------------------------------.
+ | yyacceptlab -- YYACCEPT comes here. |
+ `-------------------------------------*/
+ yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+
+ /*-----------------------------------.
+ | yyabortlab -- YYABORT comes here. |
+ `-----------------------------------*/
+ yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+
+ /*-----------------------------------------------------.
+ | yyreturn -- parsing is finished, return the result. |
+ `-----------------------------------------------------*/
+ yyreturn:
+ if (!yyla.empty ())
+ yy_destroy_ ("Cleanup: discarding lookahead", yyla);
+
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYABORT or YYACCEPT. */
+ yypop_ (yylen);
+ while (1 < yystack_.size ())
+ {
+ yy_destroy_ ("Cleanup: popping", yystack_[0]);
+ yypop_ ();
+ }
+
+ return yyresult;
+ }
+#if YY_EXCEPTIONS
+ catch (...)
+ {
+ YYCDEBUG << "Exception caught: cleaning lookahead and stack\n";
+ // Do not try to display the values of the reclaimed symbols,
+ // as their printers might throw an exception.
+ if (!yyla.empty ())
+ yy_destroy_ (YY_NULLPTR, yyla);
+
+ while (1 < yystack_.size ())
+ {
+ yy_destroy_ (YY_NULLPTR, yystack_[0]);
+ yypop_ ();
+ }
+ throw;
+ }
+#endif // YY_EXCEPTIONS
+ }
+
+ void
+ YyParser::error (const syntax_error& yyexc)
+ {
+ error (yyexc.what ());
+ }
+
+ // Generate an error message.
+ std::string
+ YyParser::yysyntax_error_ (state_type, const symbol_type&) const
+ {
+ return YY_("syntax error");
+ }
+
+
+ const signed char YyParser::yypact_ninf_ = -44;
+
+ const signed char YyParser::yytable_ninf_ = -1;
+
+ const signed char
+ YyParser::yypact_[] =
+ {
+ 77, 77, -44, -9, -4, 18, -44, -44, -44, -44,
+ -44, 19, -2, -44, 77, -44, 36, -44, -44, 13,
+ -44, 11, 19, -2, -44, 19, -44, 21, -44, 17,
+ 34, 38, 44, 46, 20, 49, -44, -44, 25, -3,
+ 59, 77, -44, 19, -44, 13, 29, -44, -2, -2,
+ 19, 19, -44, 13, 19, 95, -2, -2, 77, 77,
+ 77, 77, 77, 77, 77, -44, 30, -44, -44, -44,
+ 0, -44, 31, -44, -44, -44, -44, -44, -44, -44,
+ 13, 13, 38, 44, 46, 20, 49, 49, -44, -44,
+ -44, 77, -44, -44
+ };
+
+ const unsigned char
+ YyParser::yydefact_[] =
+ {
+ 0, 0, 16, 0, 0, 0, 31, 29, 32, 28,
+ 26, 21, 5, 17, 0, 27, 0, 41, 4, 3,
+ 8, 0, 21, 0, 15, 45, 33, 60, 39, 42,
+ 2, 47, 49, 51, 53, 55, 58, 61, 0, 0,
+ 0, 0, 12, 22, 23, 6, 0, 1, 0, 0,
+ 21, 21, 11, 7, 46, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 18, 0, 19, 34, 38,
+ 0, 36, 0, 24, 30, 9, 10, 14, 13, 40,
+ 43, 44, 48, 50, 52, 54, 56, 57, 59, 20,
+ 35, 0, 25, 37
+ };
+
+ const signed char
+ YyParser::yypgoto_[] =
+ {
+ -44, 2, -44, -44, -11, -43, -44, 35, -18, 33,
+ -36, -16, -44, -44, -44, -44, -32, -44, 5, -44,
+ -44, 3, 8, -5, 1, -23, -1
+ };
+
+ const signed char
+ YyParser::yydefgoto_[] =
+ {
+ -1, 69, 17, 18, 19, 20, 21, 22, 42, 43,
+ 44, 23, 24, 25, 26, 70, 71, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36
+ };
+
+ const unsigned char
+ YyParser::yytable_[] =
+ {
+ 37, 45, 16, 49, 52, 75, 76, 73, 2, 3,
+ 4, 66, 53, 57, 38, 9, 46, 11, 73, 39,
+ 13, 67, 3, 4, 90, 15, 62, 63, 91, 49,
+ 50, 10, 77, 78, 48, 10, 47, 49, 56, 86,
+ 87, 40, 58, 72, 41, 80, 81, 59, 60, 65,
+ 55, 61, 64, 74, 89, 84, 51, 92, 54, 93,
+ 79, 82, 85, 88, 49, 49, 1, 83, 0, 2,
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 0,
+ 12, 13, 14, 68, 1, 0, 15, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 0, 12, 13,
+ 14, 0, 0, 0, 15, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 0, 12, 13, 14, 0,
+ 0, 0, 15
+ };
+
+ const signed char
+ YyParser::yycheck_[] =
+ {
+ 1, 12, 0, 19, 22, 48, 49, 43, 10, 11,
+ 12, 14, 23, 29, 23, 17, 14, 19, 54, 23,
+ 22, 24, 11, 12, 24, 27, 6, 7, 28, 45,
+ 19, 18, 50, 51, 21, 18, 0, 53, 21, 62,
+ 63, 23, 8, 41, 25, 56, 57, 9, 4, 24,
+ 29, 5, 3, 24, 24, 60, 21, 26, 25, 91,
+ 55, 58, 61, 64, 80, 81, 7, 59, -1, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, -1,
+ 21, 22, 23, 24, 7, -1, 27, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, -1, 21, 22,
+ 23, -1, -1, -1, 27, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, -1, 21, 22, 23, -1,
+ -1, -1, 27
+ };
+
+ const unsigned char
+ YyParser::yystos_[] =
+ {
+ 0, 7, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 21, 22, 23, 27, 31, 32, 33, 34,
+ 35, 36, 37, 41, 42, 43, 44, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 56, 23, 23,
+ 23, 25, 38, 39, 40, 34, 31, 0, 21, 41,
+ 19, 37, 38, 34, 39, 29, 21, 41, 8, 9,
+ 4, 5, 6, 7, 3, 24, 14, 24, 24, 31,
+ 45, 46, 31, 40, 24, 35, 35, 38, 38, 48,
+ 34, 34, 51, 52, 53, 54, 55, 55, 56, 24,
+ 24, 28, 26, 46
+ };
+
+ const unsigned char
+ YyParser::yyr1_[] =
+ {
+ 0, 30, 31, 32, 32, 33, 33, 33, 34, 34,
+ 34, 35, 35, 35, 35, 35, 36, 36, 37, 37,
+ 37, 38, 38, 39, 39, 40, 41, 42, 42, 43,
+ 43, 43, 43, 43, 44, 44, 45, 45, 46, 47,
+ 47, 48, 48, 48, 48, 49, 49, 50, 50, 51,
+ 51, 52, 52, 53, 53, 54, 54, 54, 55, 55,
+ 56, 56
+ };
+
+ const unsigned char
+ YyParser::yyr2_[] =
+ {
+ 0, 2, 1, 1, 1, 1, 2, 2, 1, 3,
+ 3, 2, 2, 3, 3, 1, 1, 1, 3, 3,
+ 4, 0, 1, 1, 2, 3, 1, 1, 1, 1,
+ 3, 1, 1, 1, 3, 4, 1, 3, 1, 1,
+ 3, 1, 1, 3, 3, 1, 2, 1, 3, 1,
+ 3, 1, 3, 1, 3, 1, 3, 3, 1, 3,
+ 1, 2
+ };
+
+
+#if YYDEBUG
+ // YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ // First, the terminals, then, starting at \a yyntokens_, nonterminals.
+ const char*
+ const YyParser::yytname_[] =
+ {
+ "$end", "error", "$undefined", "kMulOp", "kEqOp", "kRelOp", "kPlus",
+ "kMinus", "kOr", "kAnd", "kAxisName", "kNodeType", "kPI",
+ "kFunctionName", "kLiteral", "kVariableReference", "kNumber", "kDotDot",
+ "kSlashSlash", "kNameTest", "kXPathError", "'/'", "'@'", "'('", "')'",
+ "'['", "']'", "'.'", "','", "'|'", "$accept", "Expr", "LocationPath",
+ "AbsoluteLocationPath", "RelativeLocationPath", "Step", "AxisSpecifier",
+ "NodeTest", "OptionalPredicateList", "PredicateList", "Predicate",
+ "DescendantOrSelf", "AbbreviatedStep", "PrimaryExpr", "FunctionCall",
+ "ArgumentList", "Argument", "UnionExpr", "PathExpr", "FilterExpr",
+ "OrExpr", "AndExpr", "EqualityExpr", "RelationalExpr", "AdditiveExpr",
+ "MultiplicativeExpr", "UnaryExpr", YY_NULLPTR
+ };
+
+
+ const unsigned short
+ YyParser::yyrline_[] =
+ {
+ 0, 128, 128, 136, 142, 150, 155, 160, 168, 174,
+ 180, 189, 197, 212, 220, 235, 239, 241, 248, 258,
+ 263, 271, 275, 282, 288, 296, 303, 310, 315, 322,
+ 327, 332, 337, 342, 346, 353, 362, 368, 376, 380,
+ 382, 391, 396, 398, 404, 413, 415, 422, 424, 431,
+ 433, 440, 442, 449, 451, 458, 460, 465, 472, 474,
+ 481, 483
+ };
+
+ // Print the state stack on the debug stream.
+ void
+ YyParser::yystack_print_ ()
+ {
+ *yycdebug_ << "Stack now";
+ for (stack_type::const_iterator
+ i = yystack_.begin (),
+ i_end = yystack_.end ();
+ i != i_end; ++i)
+ *yycdebug_ << ' ' << i->state;
+ *yycdebug_ << '\n';
+ }
+
+ // Report on the debug stream that the rule \a yyrule is going to be reduced.
+ void
+ YyParser::yy_reduce_print_ (int yyrule)
+ {
+ unsigned yylno = yyrline_[yyrule];
+ int yynrhs = yyr2_[yyrule];
+ // Print the symbols being reduced, and their result.
+ *yycdebug_ << "Reducing stack by rule " << yyrule - 1
+ << " (line " << yylno << "):\n";
+ // The symbols being reduced.
+ for (int yyi = 0; yyi < yynrhs; yyi++)
+ YY_SYMBOL_PRINT (" $" << yyi + 1 << " =",
+ yystack_[(yynrhs) - (yyi + 1)]);
+ }
+#endif // YYDEBUG
+
+ YyParser::token_number_type
+ YyParser::yytranslate_ (int t)
+ {
+ // YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to
+ // TOKEN-NUM as returned by yylex.
+ static
+ const token_number_type
+ translate_table[] =
+ {
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 23, 24, 2, 2, 28, 2, 27, 21, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 22, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 25, 2, 26, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 29, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20
+ };
+ const unsigned user_token_number_max_ = 275;
+ const token_number_type undef_token_ = 2;
+
+ if (static_cast<int> (t) <= yyeof_)
+ return yyeof_;
+ else if (static_cast<unsigned> (t) <= user_token_number_max_)
+ return translate_table[t];
+ else
+ return undef_token_;
+ }
+
+#line 69 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+} // xpathyy
+#line 1984 "third_party/blink/renderer/core/xml/xpath_grammar_generated.cc"
+
+#line 490 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_grammar_generated.h b/chromium/third_party/blink/renderer/core/xml/xpath_grammar_generated.h
new file mode 100644
index 00000000000..b8469fb1d05
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_grammar_generated.h
@@ -0,0 +1,1485 @@
+// clang-format off
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_XML_XPATH_GRAMMAR_GENERATED_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_XML_XPATH_GRAMMAR_GENERATED_H_
+// A Bison parser, made by GNU Bison 3.4.2.
+
+// Skeleton interface for Bison LALR(1) parsers in C++
+
+// Copyright (C) 2002-2015, 2018-2019 Free Software Foundation, Inc.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+// As a special exception, you may create a larger work that contains
+// part or all of the Bison parser skeleton and distribute that work
+// under terms of your choice, so long as that work isn't itself a
+// parser generator using the skeleton or a modified version thereof
+// as a parser skeleton. Alternatively, if you modify or redistribute
+// the parser skeleton itself, you may (at your option) remove this
+// special exception, which will cause the skeleton and the resulting
+// Bison output files to be licensed under the GNU General Public
+// License without this special exception.
+
+// This special exception was added by the Free Software Foundation in
+// version 2.2 of Bison.
+
+
+/**
+ ** \file third_party/blink/renderer/core/xml/xpath_grammar_generated.h
+ ** Define the xpathyy::parser class.
+ */
+
+// C++ LALR(1) parser skeleton written by Akim Demaille.
+
+// Undocumented macros, especially those whose name start with YY_,
+// are private implementation details. Do not rely on them.
+
+#ifndef YY_YY_THIRD_PARTY_BLINK_RENDERER_CORE_XML_XPATH_GRAMMAR_GENERATED_HH_INCLUDED
+# define YY_YY_THIRD_PARTY_BLINK_RENDERER_CORE_XML_XPATH_GRAMMAR_GENERATED_HH_INCLUDED
+// // "%code requires" blocks.
+#line 46 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+
+
+#include "third_party/blink/renderer/platform/heap/persistent.h"
+
+
+#line 54 "third_party/blink/renderer/core/xml/xpath_grammar_generated.h"
+
+
+# include <cstdlib> // std::abort
+# include <iostream>
+# include <stdexcept>
+# include <string>
+# include <vector>
+
+#if defined __cplusplus
+# define YY_CPLUSPLUS __cplusplus
+#else
+# define YY_CPLUSPLUS 199711L
+#endif
+
+// Support move semantics when possible.
+#if 201103L <= YY_CPLUSPLUS
+# define YY_MOVE std::move
+# define YY_MOVE_OR_COPY move
+# define YY_MOVE_REF(Type) Type&&
+# define YY_RVREF(Type) Type&&
+# define YY_COPY(Type) Type
+#else
+# define YY_MOVE
+# define YY_MOVE_OR_COPY copy
+# define YY_MOVE_REF(Type) Type&
+# define YY_RVREF(Type) const Type&
+# define YY_COPY(Type) const Type&
+#endif
+
+// Support noexcept when possible.
+#if 201103L <= YY_CPLUSPLUS
+# define YY_NOEXCEPT noexcept
+# define YY_NOTHROW
+#else
+# define YY_NOEXCEPT
+# define YY_NOTHROW throw ()
+#endif
+
+// Support constexpr when possible.
+#if 201703 <= YY_CPLUSPLUS
+# define YY_CONSTEXPR constexpr
+#else
+# define YY_CONSTEXPR
+#endif
+
+
+#ifndef YYASSERT
+# include <cassert>
+# define YYASSERT assert
+#endif
+
+
+#ifndef YY_ATTRIBUTE
+# if (defined __GNUC__ \
+ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
+ || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
+# define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+# else
+# define YY_ATTRIBUTE(Spec) /* empty */
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(E) ((void) (E))
+#else
+# define YYUSE(E) /* empty */
+#endif
+
+#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized. */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+ _Pragma ("GCC diagnostic pop")
+#else
+# define YY_INITIAL_VALUE(Value) Value
+#endif
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+# ifndef YY_NULLPTR
+# if defined __cplusplus
+# if 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
+# else
+# define YY_NULLPTR ((void*)0)
+# endif
+# endif
+
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+#line 69 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+namespace xpathyy {
+#line 170 "third_party/blink/renderer/core/xml/xpath_grammar_generated.h"
+
+
+
+
+ /// A Bison parser.
+ class YyParser
+ {
+ public:
+#ifndef YYSTYPE
+ /// A buffer to store and retrieve objects.
+ ///
+ /// Sort of a variant, but does not keep track of the nature
+ /// of the stored data, since that knowledge is available
+ /// via the current parser state.
+ class semantic_type
+ {
+ public:
+ /// Type of *this.
+ typedef semantic_type self_type;
+
+ /// Empty construction.
+ semantic_type () YY_NOEXCEPT
+ : yybuffer_ ()
+ {}
+
+ /// Construct and fill.
+ template <typename T>
+ semantic_type (YY_RVREF (T) t)
+ {
+ YYASSERT (sizeof (T) <= size);
+ new (yyas_<T> ()) T (YY_MOVE (t));
+ }
+
+ /// Destruction, allowed only if empty.
+ ~semantic_type () YY_NOEXCEPT
+ {}
+
+# if 201103L <= YY_CPLUSPLUS
+ /// Instantiate a \a T in here from \a t.
+ template <typename T, typename... U>
+ T&
+ emplace (U&&... u)
+ {
+ return *new (yyas_<T> ()) T (std::forward <U>(u)...);
+ }
+# else
+ /// Instantiate an empty \a T in here.
+ template <typename T>
+ T&
+ emplace ()
+ {
+ return *new (yyas_<T> ()) T ();
+ }
+
+ /// Instantiate a \a T in here from \a t.
+ template <typename T>
+ T&
+ emplace (const T& t)
+ {
+ return *new (yyas_<T> ()) T (t);
+ }
+# endif
+
+ /// Instantiate an empty \a T in here.
+ /// Obsolete, use emplace.
+ template <typename T>
+ T&
+ build ()
+ {
+ return emplace<T> ();
+ }
+
+ /// Instantiate a \a T in here from \a t.
+ /// Obsolete, use emplace.
+ template <typename T>
+ T&
+ build (const T& t)
+ {
+ return emplace<T> (t);
+ }
+
+ /// Accessor to a built \a T.
+ template <typename T>
+ T&
+ as () YY_NOEXCEPT
+ {
+ return *yyas_<T> ();
+ }
+
+ /// Const accessor to a built \a T (for %printer).
+ template <typename T>
+ const T&
+ as () const YY_NOEXCEPT
+ {
+ return *yyas_<T> ();
+ }
+
+ /// Swap the content with \a that, of same type.
+ ///
+ /// Both variants must be built beforehand, because swapping the actual
+ /// data requires reading it (with as()), and this is not possible on
+ /// unconstructed variants: it would require some dynamic testing, which
+ /// should not be the variant's responsibility.
+ /// Swapping between built and (possibly) non-built is done with
+ /// self_type::move ().
+ template <typename T>
+ void
+ swap (self_type& that) YY_NOEXCEPT
+ {
+ std::swap (as<T> (), that.as<T> ());
+ }
+
+ /// Move the content of \a that to this.
+ ///
+ /// Destroys \a that.
+ template <typename T>
+ void
+ move (self_type& that)
+ {
+# if 201103L <= YY_CPLUSPLUS
+ emplace<T> (std::move (that.as<T> ()));
+# else
+ emplace<T> ();
+ swap<T> (that);
+# endif
+ that.destroy<T> ();
+ }
+
+# if 201103L <= YY_CPLUSPLUS
+ /// Move the content of \a that to this.
+ template <typename T>
+ void
+ move (self_type&& that)
+ {
+ emplace<T> (std::move (that.as<T> ()));
+ that.destroy<T> ();
+ }
+#endif
+
+ /// Copy the content of \a that to this.
+ template <typename T>
+ void
+ copy (const self_type& that)
+ {
+ emplace<T> (that.as<T> ());
+ }
+
+ /// Destroy the stored \a T.
+ template <typename T>
+ void
+ destroy ()
+ {
+ as<T> ().~T ();
+ }
+
+ private:
+ /// Prohibit blind copies.
+ self_type& operator= (const self_type&);
+ semantic_type (const self_type&);
+
+ /// Accessor to raw memory as \a T.
+ template <typename T>
+ T*
+ yyas_ () YY_NOEXCEPT
+ {
+ void *yyp = yybuffer_.yyraw;
+ return static_cast<T*> (yyp);
+ }
+
+ /// Const accessor to raw memory as \a T.
+ template <typename T>
+ const T*
+ yyas_ () const YY_NOEXCEPT
+ {
+ const void *yyp = yybuffer_.yyraw;
+ return static_cast<const T*> (yyp);
+ }
+
+ /// An auxiliary type to compute the largest semantic type.
+ union union_type
+ {
+ // kNodeType
+ // kPI
+ // kFunctionName
+ // kLiteral
+ // kVariableReference
+ // kNumber
+ // kNameTest
+ char dummy1[sizeof (String)];
+
+ // ArgumentList
+ char dummy2[sizeof (blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>>)];
+
+ // OptionalPredicateList
+ // PredicateList
+ char dummy3[sizeof (blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>>)];
+
+ // Expr
+ // Predicate
+ // PrimaryExpr
+ // FunctionCall
+ // Argument
+ // UnionExpr
+ // PathExpr
+ // FilterExpr
+ // OrExpr
+ // AndExpr
+ // EqualityExpr
+ // RelationalExpr
+ // AdditiveExpr
+ // MultiplicativeExpr
+ // UnaryExpr
+ char dummy4[sizeof (blink::Persistent<blink::xpath::Expression>)];
+
+ // LocationPath
+ // AbsoluteLocationPath
+ // RelativeLocationPath
+ char dummy5[sizeof (blink::Persistent<blink::xpath::LocationPath>)];
+
+ // NodeTest
+ char dummy6[sizeof (blink::Persistent<blink::xpath::Step::NodeTest>)];
+
+ // Step
+ // DescendantOrSelf
+ // AbbreviatedStep
+ char dummy7[sizeof (blink::Persistent<blink::xpath::Step>)];
+
+ // kEqOp
+ // kRelOp
+ char dummy8[sizeof (blink::xpath::EqTestOp::Opcode)];
+
+ // kMulOp
+ char dummy9[sizeof (blink::xpath::NumericOp::Opcode)];
+
+ // kAxisName
+ // AxisSpecifier
+ char dummy10[sizeof (blink::xpath::Step::Axis)];
+ };
+
+ /// The size of the largest semantic type.
+ enum { size = sizeof (union_type) };
+
+ /// A buffer to store semantic values.
+ union
+ {
+ /// Strongest alignment constraints.
+ long double yyalign_me;
+ /// A buffer large enough to store any of the semantic values.
+ char yyraw[size];
+ } yybuffer_;
+ };
+
+#else
+ typedef YYSTYPE semantic_type;
+#endif
+
+ /// Syntax errors thrown from user actions.
+ struct syntax_error : std::runtime_error
+ {
+ syntax_error (const std::string& m)
+ : std::runtime_error (m)
+ {}
+
+ syntax_error (const syntax_error& s)
+ : std::runtime_error (s.what ())
+ {}
+
+ ~syntax_error () YY_NOEXCEPT YY_NOTHROW;
+ };
+
+ /// Tokens.
+ struct token
+ {
+ enum yytokentype
+ {
+ kMulOp = 258,
+ kEqOp = 259,
+ kRelOp = 260,
+ kPlus = 261,
+ kMinus = 262,
+ kOr = 263,
+ kAnd = 264,
+ kAxisName = 265,
+ kNodeType = 266,
+ kPI = 267,
+ kFunctionName = 268,
+ kLiteral = 269,
+ kVariableReference = 270,
+ kNumber = 271,
+ kDotDot = 272,
+ kSlashSlash = 273,
+ kNameTest = 274,
+ kXPathError = 275
+ };
+ };
+
+ /// (External) token type, as returned by yylex.
+ typedef token::yytokentype token_type;
+
+ /// Symbol type: an internal symbol number.
+ typedef int symbol_number_type;
+
+ /// The symbol type number to denote an empty symbol.
+ enum { empty_symbol = -2 };
+
+ /// Internal symbol number for tokens (subsumed by symbol_number_type).
+ typedef unsigned char token_number_type;
+
+ /// A complete symbol.
+ ///
+ /// Expects its Base type to provide access to the symbol type
+ /// via type_get ().
+ ///
+ /// Provide access to semantic value.
+ template <typename Base>
+ struct basic_symbol : Base
+ {
+ /// Alias to Base.
+ typedef Base super_type;
+
+ /// Default constructor.
+ basic_symbol ()
+ : value ()
+ {}
+
+#if 201103L <= YY_CPLUSPLUS
+ /// Move constructor.
+ basic_symbol (basic_symbol&& that);
+#endif
+
+ /// Copy constructor.
+ basic_symbol (const basic_symbol& that);
+
+ /// Constructor for valueless symbols, and symbols from each type.
+#if 201103L <= YY_CPLUSPLUS
+ basic_symbol (typename Base::kind_type t)
+ : Base (t)
+ {}
+#else
+ basic_symbol (typename Base::kind_type t)
+ : Base (t)
+ {}
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ basic_symbol (typename Base::kind_type t, String&& v)
+ : Base (t)
+ , value (std::move (v))
+ {}
+#else
+ basic_symbol (typename Base::kind_type t, const String& v)
+ : Base (t)
+ , value (v)
+ {}
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ basic_symbol (typename Base::kind_type t, blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>>&& v)
+ : Base (t)
+ , value (std::move (v))
+ {}
+#else
+ basic_symbol (typename Base::kind_type t, const blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>>& v)
+ : Base (t)
+ , value (v)
+ {}
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ basic_symbol (typename Base::kind_type t, blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>>&& v)
+ : Base (t)
+ , value (std::move (v))
+ {}
+#else
+ basic_symbol (typename Base::kind_type t, const blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>>& v)
+ : Base (t)
+ , value (v)
+ {}
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ basic_symbol (typename Base::kind_type t, blink::Persistent<blink::xpath::Expression>&& v)
+ : Base (t)
+ , value (std::move (v))
+ {}
+#else
+ basic_symbol (typename Base::kind_type t, const blink::Persistent<blink::xpath::Expression>& v)
+ : Base (t)
+ , value (v)
+ {}
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ basic_symbol (typename Base::kind_type t, blink::Persistent<blink::xpath::LocationPath>&& v)
+ : Base (t)
+ , value (std::move (v))
+ {}
+#else
+ basic_symbol (typename Base::kind_type t, const blink::Persistent<blink::xpath::LocationPath>& v)
+ : Base (t)
+ , value (v)
+ {}
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ basic_symbol (typename Base::kind_type t, blink::Persistent<blink::xpath::Step::NodeTest>&& v)
+ : Base (t)
+ , value (std::move (v))
+ {}
+#else
+ basic_symbol (typename Base::kind_type t, const blink::Persistent<blink::xpath::Step::NodeTest>& v)
+ : Base (t)
+ , value (v)
+ {}
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ basic_symbol (typename Base::kind_type t, blink::Persistent<blink::xpath::Step>&& v)
+ : Base (t)
+ , value (std::move (v))
+ {}
+#else
+ basic_symbol (typename Base::kind_type t, const blink::Persistent<blink::xpath::Step>& v)
+ : Base (t)
+ , value (v)
+ {}
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ basic_symbol (typename Base::kind_type t, blink::xpath::EqTestOp::Opcode&& v)
+ : Base (t)
+ , value (std::move (v))
+ {}
+#else
+ basic_symbol (typename Base::kind_type t, const blink::xpath::EqTestOp::Opcode& v)
+ : Base (t)
+ , value (v)
+ {}
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ basic_symbol (typename Base::kind_type t, blink::xpath::NumericOp::Opcode&& v)
+ : Base (t)
+ , value (std::move (v))
+ {}
+#else
+ basic_symbol (typename Base::kind_type t, const blink::xpath::NumericOp::Opcode& v)
+ : Base (t)
+ , value (v)
+ {}
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ basic_symbol (typename Base::kind_type t, blink::xpath::Step::Axis&& v)
+ : Base (t)
+ , value (std::move (v))
+ {}
+#else
+ basic_symbol (typename Base::kind_type t, const blink::xpath::Step::Axis& v)
+ : Base (t)
+ , value (v)
+ {}
+#endif
+
+ /// Destroy the symbol.
+ ~basic_symbol ()
+ {
+ clear ();
+ }
+
+ /// Destroy contents, and record that is empty.
+ void clear ()
+ {
+ // User destructor.
+ symbol_number_type yytype = this->type_get ();
+ basic_symbol<Base>& yysym = *this;
+ (void) yysym;
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+
+ // Type destructor.
+switch (yytype)
+ {
+ case 11: // kNodeType
+ case 12: // kPI
+ case 13: // kFunctionName
+ case 14: // kLiteral
+ case 15: // kVariableReference
+ case 16: // kNumber
+ case 19: // kNameTest
+ value.template destroy< String > ();
+ break;
+
+ case 45: // ArgumentList
+ value.template destroy< blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Expression>>> > ();
+ break;
+
+ case 38: // OptionalPredicateList
+ case 39: // PredicateList
+ value.template destroy< blink::Persistent<blink::HeapVector<blink::Member<blink::xpath::Predicate>>> > ();
+ break;
+
+ case 31: // Expr
+ case 40: // Predicate
+ case 43: // PrimaryExpr
+ case 44: // FunctionCall
+ case 46: // Argument
+ case 47: // UnionExpr
+ case 48: // PathExpr
+ case 49: // FilterExpr
+ case 50: // OrExpr
+ case 51: // AndExpr
+ case 52: // EqualityExpr
+ case 53: // RelationalExpr
+ case 54: // AdditiveExpr
+ case 55: // MultiplicativeExpr
+ case 56: // UnaryExpr
+ value.template destroy< blink::Persistent<blink::xpath::Expression> > ();
+ break;
+
+ case 32: // LocationPath
+ case 33: // AbsoluteLocationPath
+ case 34: // RelativeLocationPath
+ value.template destroy< blink::Persistent<blink::xpath::LocationPath> > ();
+ break;
+
+ case 37: // NodeTest
+ value.template destroy< blink::Persistent<blink::xpath::Step::NodeTest> > ();
+ break;
+
+ case 35: // Step
+ case 41: // DescendantOrSelf
+ case 42: // AbbreviatedStep
+ value.template destroy< blink::Persistent<blink::xpath::Step> > ();
+ break;
+
+ case 4: // kEqOp
+ case 5: // kRelOp
+ value.template destroy< blink::xpath::EqTestOp::Opcode > ();
+ break;
+
+ case 3: // kMulOp
+ value.template destroy< blink::xpath::NumericOp::Opcode > ();
+ break;
+
+ case 10: // kAxisName
+ case 36: // AxisSpecifier
+ value.template destroy< blink::xpath::Step::Axis > ();
+ break;
+
+ default:
+ break;
+ }
+
+ Base::clear ();
+ }
+
+ /// Whether empty.
+ bool empty () const YY_NOEXCEPT;
+
+ /// Destructive move, \a s is emptied into this.
+ void move (basic_symbol& s);
+
+ /// The semantic value.
+ semantic_type value;
+
+ private:
+#if YY_CPLUSPLUS < 201103L
+ /// Assignment operator.
+ basic_symbol& operator= (const basic_symbol& that);
+#endif
+ };
+
+ /// Type access provider for token (enum) based symbols.
+ struct by_type
+ {
+ /// Default constructor.
+ by_type ();
+
+#if 201103L <= YY_CPLUSPLUS
+ /// Move constructor.
+ by_type (by_type&& that);
+#endif
+
+ /// Copy constructor.
+ by_type (const by_type& that);
+
+ /// The symbol type as needed by the constructor.
+ typedef token_type kind_type;
+
+ /// Constructor from (external) token numbers.
+ by_type (kind_type t);
+
+ /// Record that this symbol is empty.
+ void clear ();
+
+ /// Steal the symbol type from \a that.
+ void move (by_type& that);
+
+ /// The (internal) type number (corresponding to \a type).
+ /// \a empty when empty.
+ symbol_number_type type_get () const YY_NOEXCEPT;
+
+ /// The token.
+ token_type token () const YY_NOEXCEPT;
+
+ /// The symbol type.
+ /// \a empty_symbol when empty.
+ /// An int, not token_number_type, to be able to store empty_symbol.
+ int type;
+ };
+
+ /// "External" symbols: returned by the scanner.
+ struct symbol_type : basic_symbol<by_type>
+ {
+ /// Superclass.
+ typedef basic_symbol<by_type> super_type;
+
+ /// Empty symbol.
+ symbol_type () {}
+
+ /// Constructor for valueless symbols, and symbols from each type.
+#if 201103L <= YY_CPLUSPLUS
+ symbol_type (int tok)
+ : super_type(token_type (tok))
+ {
+ YYASSERT (tok == 0 || tok == token::kPlus || tok == token::kMinus || tok == token::kOr || tok == token::kAnd || tok == token::kDotDot || tok == token::kSlashSlash || tok == token::kXPathError || tok == 47 || tok == 64 || tok == 40 || tok == 41 || tok == 91 || tok == 93 || tok == 46 || tok == 44 || tok == 124);
+ }
+#else
+ symbol_type (int tok)
+ : super_type(token_type (tok))
+ {
+ YYASSERT (tok == 0 || tok == token::kPlus || tok == token::kMinus || tok == token::kOr || tok == token::kAnd || tok == token::kDotDot || tok == token::kSlashSlash || tok == token::kXPathError || tok == 47 || tok == 64 || tok == 40 || tok == 41 || tok == 91 || tok == 93 || tok == 46 || tok == 44 || tok == 124);
+ }
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ symbol_type (int tok, String v)
+ : super_type(token_type (tok), std::move (v))
+ {
+ YYASSERT (tok == token::kNodeType || tok == token::kPI || tok == token::kFunctionName || tok == token::kLiteral || tok == token::kVariableReference || tok == token::kNumber || tok == token::kNameTest);
+ }
+#else
+ symbol_type (int tok, const String& v)
+ : super_type(token_type (tok), v)
+ {
+ YYASSERT (tok == token::kNodeType || tok == token::kPI || tok == token::kFunctionName || tok == token::kLiteral || tok == token::kVariableReference || tok == token::kNumber || tok == token::kNameTest);
+ }
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ symbol_type (int tok, blink::xpath::EqTestOp::Opcode v)
+ : super_type(token_type (tok), std::move (v))
+ {
+ YYASSERT (tok == token::kEqOp || tok == token::kRelOp);
+ }
+#else
+ symbol_type (int tok, const blink::xpath::EqTestOp::Opcode& v)
+ : super_type(token_type (tok), v)
+ {
+ YYASSERT (tok == token::kEqOp || tok == token::kRelOp);
+ }
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ symbol_type (int tok, blink::xpath::NumericOp::Opcode v)
+ : super_type(token_type (tok), std::move (v))
+ {
+ YYASSERT (tok == token::kMulOp);
+ }
+#else
+ symbol_type (int tok, const blink::xpath::NumericOp::Opcode& v)
+ : super_type(token_type (tok), v)
+ {
+ YYASSERT (tok == token::kMulOp);
+ }
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ symbol_type (int tok, blink::xpath::Step::Axis v)
+ : super_type(token_type (tok), std::move (v))
+ {
+ YYASSERT (tok == token::kAxisName);
+ }
+#else
+ symbol_type (int tok, const blink::xpath::Step::Axis& v)
+ : super_type(token_type (tok), v)
+ {
+ YYASSERT (tok == token::kAxisName);
+ }
+#endif
+ };
+
+ /// Build a parser object.
+ YyParser (blink::xpath::Parser* parser__yyarg);
+ virtual ~YyParser ();
+
+ /// Parse. An alias for parse ().
+ /// \returns 0 iff parsing succeeded.
+ int operator() ();
+
+ /// Parse.
+ /// \returns 0 iff parsing succeeded.
+ virtual int parse ();
+
+#if YYDEBUG
+ /// The current debugging stream.
+ std::ostream& debug_stream () const YY_ATTRIBUTE_PURE;
+ /// Set the current debugging stream.
+ void set_debug_stream (std::ostream &);
+
+ /// Type for debugging levels.
+ typedef int debug_level_type;
+ /// The current debugging level.
+ debug_level_type debug_level () const YY_ATTRIBUTE_PURE;
+ /// Set the current debugging level.
+ void set_debug_level (debug_level_type l);
+#endif
+
+ /// Report a syntax error.
+ /// \param msg a description of the syntax error.
+ virtual void error (const std::string& msg);
+
+ /// Report a syntax error.
+ void error (const syntax_error& err);
+
+ // Implementation of make_symbol for each symbol type.
+#if 201103L <= YY_CPLUSPLUS
+ static
+ symbol_type
+ make_kMulOp (blink::xpath::NumericOp::Opcode v)
+ {
+ return symbol_type (token::kMulOp, std::move (v));
+ }
+#else
+ static
+ symbol_type
+ make_kMulOp (const blink::xpath::NumericOp::Opcode& v)
+ {
+ return symbol_type (token::kMulOp, v);
+ }
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ static
+ symbol_type
+ make_kEqOp (blink::xpath::EqTestOp::Opcode v)
+ {
+ return symbol_type (token::kEqOp, std::move (v));
+ }
+#else
+ static
+ symbol_type
+ make_kEqOp (const blink::xpath::EqTestOp::Opcode& v)
+ {
+ return symbol_type (token::kEqOp, v);
+ }
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ static
+ symbol_type
+ make_kRelOp (blink::xpath::EqTestOp::Opcode v)
+ {
+ return symbol_type (token::kRelOp, std::move (v));
+ }
+#else
+ static
+ symbol_type
+ make_kRelOp (const blink::xpath::EqTestOp::Opcode& v)
+ {
+ return symbol_type (token::kRelOp, v);
+ }
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ static
+ symbol_type
+ make_kPlus ()
+ {
+ return symbol_type (token::kPlus);
+ }
+#else
+ static
+ symbol_type
+ make_kPlus ()
+ {
+ return symbol_type (token::kPlus);
+ }
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ static
+ symbol_type
+ make_kMinus ()
+ {
+ return symbol_type (token::kMinus);
+ }
+#else
+ static
+ symbol_type
+ make_kMinus ()
+ {
+ return symbol_type (token::kMinus);
+ }
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ static
+ symbol_type
+ make_kOr ()
+ {
+ return symbol_type (token::kOr);
+ }
+#else
+ static
+ symbol_type
+ make_kOr ()
+ {
+ return symbol_type (token::kOr);
+ }
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ static
+ symbol_type
+ make_kAnd ()
+ {
+ return symbol_type (token::kAnd);
+ }
+#else
+ static
+ symbol_type
+ make_kAnd ()
+ {
+ return symbol_type (token::kAnd);
+ }
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ static
+ symbol_type
+ make_kAxisName (blink::xpath::Step::Axis v)
+ {
+ return symbol_type (token::kAxisName, std::move (v));
+ }
+#else
+ static
+ symbol_type
+ make_kAxisName (const blink::xpath::Step::Axis& v)
+ {
+ return symbol_type (token::kAxisName, v);
+ }
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ static
+ symbol_type
+ make_kNodeType (String v)
+ {
+ return symbol_type (token::kNodeType, std::move (v));
+ }
+#else
+ static
+ symbol_type
+ make_kNodeType (const String& v)
+ {
+ return symbol_type (token::kNodeType, v);
+ }
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ static
+ symbol_type
+ make_kPI (String v)
+ {
+ return symbol_type (token::kPI, std::move (v));
+ }
+#else
+ static
+ symbol_type
+ make_kPI (const String& v)
+ {
+ return symbol_type (token::kPI, v);
+ }
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ static
+ symbol_type
+ make_kFunctionName (String v)
+ {
+ return symbol_type (token::kFunctionName, std::move (v));
+ }
+#else
+ static
+ symbol_type
+ make_kFunctionName (const String& v)
+ {
+ return symbol_type (token::kFunctionName, v);
+ }
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ static
+ symbol_type
+ make_kLiteral (String v)
+ {
+ return symbol_type (token::kLiteral, std::move (v));
+ }
+#else
+ static
+ symbol_type
+ make_kLiteral (const String& v)
+ {
+ return symbol_type (token::kLiteral, v);
+ }
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ static
+ symbol_type
+ make_kVariableReference (String v)
+ {
+ return symbol_type (token::kVariableReference, std::move (v));
+ }
+#else
+ static
+ symbol_type
+ make_kVariableReference (const String& v)
+ {
+ return symbol_type (token::kVariableReference, v);
+ }
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ static
+ symbol_type
+ make_kNumber (String v)
+ {
+ return symbol_type (token::kNumber, std::move (v));
+ }
+#else
+ static
+ symbol_type
+ make_kNumber (const String& v)
+ {
+ return symbol_type (token::kNumber, v);
+ }
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ static
+ symbol_type
+ make_kDotDot ()
+ {
+ return symbol_type (token::kDotDot);
+ }
+#else
+ static
+ symbol_type
+ make_kDotDot ()
+ {
+ return symbol_type (token::kDotDot);
+ }
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ static
+ symbol_type
+ make_kSlashSlash ()
+ {
+ return symbol_type (token::kSlashSlash);
+ }
+#else
+ static
+ symbol_type
+ make_kSlashSlash ()
+ {
+ return symbol_type (token::kSlashSlash);
+ }
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ static
+ symbol_type
+ make_kNameTest (String v)
+ {
+ return symbol_type (token::kNameTest, std::move (v));
+ }
+#else
+ static
+ symbol_type
+ make_kNameTest (const String& v)
+ {
+ return symbol_type (token::kNameTest, v);
+ }
+#endif
+#if 201103L <= YY_CPLUSPLUS
+ static
+ symbol_type
+ make_kXPathError ()
+ {
+ return symbol_type (token::kXPathError);
+ }
+#else
+ static
+ symbol_type
+ make_kXPathError ()
+ {
+ return symbol_type (token::kXPathError);
+ }
+#endif
+
+
+ private:
+ /// This class is not copyable.
+ YyParser (const YyParser&);
+ YyParser& operator= (const YyParser&);
+
+ /// State numbers.
+ typedef int state_type;
+
+ /// Generate an error message.
+ /// \param yystate the state where the error occurred.
+ /// \param yyla the lookahead token.
+ virtual std::string yysyntax_error_ (state_type yystate,
+ const symbol_type& yyla) const;
+
+ /// Compute post-reduction state.
+ /// \param yystate the current state
+ /// \param yysym the nonterminal to push on the stack
+ state_type yy_lr_goto_state_ (state_type yystate, int yysym);
+
+ /// Whether the given \c yypact_ value indicates a defaulted state.
+ /// \param yyvalue the value to check
+ static bool yy_pact_value_is_default_ (int yyvalue);
+
+ /// Whether the given \c yytable_ value indicates a syntax error.
+ /// \param yyvalue the value to check
+ static bool yy_table_value_is_error_ (int yyvalue);
+
+ static const signed char yypact_ninf_;
+ static const signed char yytable_ninf_;
+
+ /// Convert a scanner token number \a t to a symbol number.
+ static token_number_type yytranslate_ (int t);
+
+ // Tables.
+ // YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ // STATE-NUM.
+ static const signed char yypact_[];
+
+ // YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+ // Performed when YYTABLE does not specify something else to do. Zero
+ // means the default is an error.
+ static const unsigned char yydefact_[];
+
+ // YYPGOTO[NTERM-NUM].
+ static const signed char yypgoto_[];
+
+ // YYDEFGOTO[NTERM-NUM].
+ static const signed char yydefgoto_[];
+
+ // YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
+ // positive, shift that token. If negative, reduce the rule whose
+ // number is the opposite. If YYTABLE_NINF, syntax error.
+ static const unsigned char yytable_[];
+
+ static const signed char yycheck_[];
+
+ // YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ // symbol of state STATE-NUM.
+ static const unsigned char yystos_[];
+
+ // YYR1[YYN] -- Symbol number of symbol that rule YYN derives.
+ static const unsigned char yyr1_[];
+
+ // YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.
+ static const unsigned char yyr2_[];
+
+
+#if YYDEBUG
+ /// For a symbol, its name in clear.
+ static const char* const yytname_[];
+
+ // YYRLINE[YYN] -- Source line where rule number YYN was defined.
+ static const unsigned short yyrline_[];
+ /// Report on the debug stream that the rule \a r is going to be reduced.
+ virtual void yy_reduce_print_ (int r);
+ /// Print the state stack on the debug stream.
+ virtual void yystack_print_ ();
+
+ /// Debugging level.
+ int yydebug_;
+ /// Debug stream.
+ std::ostream* yycdebug_;
+
+ /// \brief Display a symbol type, value and location.
+ /// \param yyo The output stream.
+ /// \param yysym The symbol.
+ template <typename Base>
+ void yy_print_ (std::ostream& yyo, const basic_symbol<Base>& yysym) const;
+#endif
+
+ /// \brief Reclaim the memory associated to a symbol.
+ /// \param yymsg Why this token is reclaimed.
+ /// If null, print nothing.
+ /// \param yysym The symbol.
+ template <typename Base>
+ void yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const;
+
+ private:
+ /// Type access provider for state based symbols.
+ struct by_state
+ {
+ /// Default constructor.
+ by_state () YY_NOEXCEPT;
+
+ /// The symbol type as needed by the constructor.
+ typedef state_type kind_type;
+
+ /// Constructor.
+ by_state (kind_type s) YY_NOEXCEPT;
+
+ /// Copy constructor.
+ by_state (const by_state& that) YY_NOEXCEPT;
+
+ /// Record that this symbol is empty.
+ void clear () YY_NOEXCEPT;
+
+ /// Steal the symbol type from \a that.
+ void move (by_state& that);
+
+ /// The (internal) type number (corresponding to \a state).
+ /// \a empty_symbol when empty.
+ symbol_number_type type_get () const YY_NOEXCEPT;
+
+ /// The state number used to denote an empty symbol.
+ enum { empty_state = -1 };
+
+ /// The state.
+ /// \a empty when empty.
+ state_type state;
+ };
+
+ /// "Internal" symbol: element of the stack.
+ struct stack_symbol_type : basic_symbol<by_state>
+ {
+ /// Superclass.
+ typedef basic_symbol<by_state> super_type;
+ /// Construct an empty symbol.
+ stack_symbol_type ();
+ /// Move or copy construction.
+ stack_symbol_type (YY_RVREF (stack_symbol_type) that);
+ /// Steal the contents from \a sym to build this.
+ stack_symbol_type (state_type s, YY_MOVE_REF (symbol_type) sym);
+#if YY_CPLUSPLUS < 201103L
+ /// Assignment, needed by push_back by some old implementations.
+ /// Moves the contents of that.
+ stack_symbol_type& operator= (stack_symbol_type& that);
+#endif
+ };
+
+ /// A stack with random access from its top.
+ template <typename T, typename S = std::vector<T> >
+ class stack
+ {
+ public:
+ // Hide our reversed order.
+ typedef typename S::reverse_iterator iterator;
+ typedef typename S::const_reverse_iterator const_iterator;
+ typedef typename S::size_type size_type;
+
+ stack (size_type n = 200)
+ : seq_ (n)
+ {}
+
+ /// Random access.
+ ///
+ /// Index 0 returns the topmost element.
+ T&
+ operator[] (size_type i)
+ {
+ return seq_[size () - 1 - i];
+ }
+
+ /// Random access.
+ ///
+ /// Index 0 returns the topmost element.
+ T&
+ operator[] (int i)
+ {
+ return operator[] (size_type (i));
+ }
+
+ /// Random access.
+ ///
+ /// Index 0 returns the topmost element.
+ const T&
+ operator[] (size_type i) const
+ {
+ return seq_[size () - 1 - i];
+ }
+
+ /// Random access.
+ ///
+ /// Index 0 returns the topmost element.
+ const T&
+ operator[] (int i) const
+ {
+ return operator[] (size_type (i));
+ }
+
+ /// Steal the contents of \a t.
+ ///
+ /// Close to move-semantics.
+ void
+ push (YY_MOVE_REF (T) t)
+ {
+ seq_.push_back (T ());
+ operator[] (0).move (t);
+ }
+
+ /// Pop elements from the stack.
+ void
+ pop (int n = 1) YY_NOEXCEPT
+ {
+ for (; 0 < n; --n)
+ seq_.pop_back ();
+ }
+
+ /// Pop all elements from the stack.
+ void
+ clear () YY_NOEXCEPT
+ {
+ seq_.clear ();
+ }
+
+ /// Number of elements on the stack.
+ size_type
+ size () const YY_NOEXCEPT
+ {
+ return seq_.size ();
+ }
+
+ /// Iterator on top of the stack (going downwards).
+ const_iterator
+ begin () const YY_NOEXCEPT
+ {
+ return seq_.rbegin ();
+ }
+
+ /// Bottom of the stack.
+ const_iterator
+ end () const YY_NOEXCEPT
+ {
+ return seq_.rend ();
+ }
+
+ /// Present a slice of the top of a stack.
+ class slice
+ {
+ public:
+ slice (const stack& stack, int range)
+ : stack_ (stack)
+ , range_ (range)
+ {}
+
+ const T&
+ operator[] (int i) const
+ {
+ return stack_[range_ - i];
+ }
+
+ private:
+ const stack& stack_;
+ int range_;
+ };
+
+ private:
+ stack (const stack&);
+ stack& operator= (const stack&);
+ /// The wrapped container.
+ S seq_;
+ };
+
+
+ /// Stack type.
+ typedef stack<stack_symbol_type> stack_type;
+
+ /// The stack.
+ stack_type yystack_;
+
+ /// Push a new state on the stack.
+ /// \param m a debug message to display
+ /// if null, no trace is output.
+ /// \param sym the symbol
+ /// \warning the contents of \a s.value is stolen.
+ void yypush_ (const char* m, YY_MOVE_REF (stack_symbol_type) sym);
+
+ /// Push a new look ahead token on the state on the stack.
+ /// \param m a debug message to display
+ /// if null, no trace is output.
+ /// \param s the state
+ /// \param sym the symbol (for its value and location).
+ /// \warning the contents of \a sym.value is stolen.
+ void yypush_ (const char* m, state_type s, YY_MOVE_REF (symbol_type) sym);
+
+ /// Pop \a n symbols from the stack.
+ void yypop_ (int n = 1);
+
+ /// Constants.
+ enum
+ {
+ yyeof_ = 0,
+ yylast_ = 122, ///< Last index in yytable_.
+ yynnts_ = 27, ///< Number of nonterminal symbols.
+ yyfinal_ = 47, ///< Termination state number.
+ yyterror_ = 1,
+ yyerrcode_ = 256,
+ yyntokens_ = 30 ///< Number of tokens.
+ };
+
+
+ // User arguments.
+ blink::xpath::Parser* parser_;
+ };
+
+
+#line 69 "third_party/blink/renderer/core/xml/xpath_grammar.y"
+} // xpathyy
+#line 1476 "third_party/blink/renderer/core/xml/xpath_grammar_generated.h"
+
+
+
+
+
+#endif // !YY_YY_THIRD_PARTY_BLINK_RENDERER_CORE_XML_XPATH_GRAMMAR_GENERATED_HH_INCLUDED
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_XML_XPATH_GRAMMAR_GENERATED_H_
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 9fbd1ba1c00..7ce4c803945 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(blink::Visitor* visitor) { visitor->Trace(nodes_); }
+ void Trace(Visitor* visitor) { 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_ns_resolver.h b/chromium/third_party/blink/renderer/core/xml/xpath_ns_resolver.h
index f93f852c1a8..fbf6657cdf2 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_ns_resolver.h
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_ns_resolver.h
@@ -27,12 +27,13 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_XML_XPATH_NS_RESOLVER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_XML_XPATH_NS_RESOLVER_H_
+#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
namespace blink {
-class XPathNSResolver : public ScriptWrappable {
+class CORE_EXPORT XPathNSResolver : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_ns_resolver.idl b/chromium/third_party/blink/renderer/core/xml/xpath_ns_resolver.idl
index 5d2a030e180..077d62b5539 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_ns_resolver.idl
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_ns_resolver.idl
@@ -28,5 +28,5 @@
[
NoInterfaceObject
] interface XPathNSResolver {
- DOMString? lookupNamespaceURI([DefaultValue=Undefined] optional DOMString prefix);
+ DOMString? lookupNamespaceURI(optional DOMString prefix = "undefined");
};
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_parser.cc b/chromium/third_party/blink/renderer/core/xml/xpath_parser.cc
index b2efc8a9c66..39fe46eee6b 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_parser.cc
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_parser.cc
@@ -29,9 +29,10 @@
#include "base/memory/ptr_util.h"
#include "third_party/blink/renderer/core/xml/xpath_evaluator.h"
+#include "third_party/blink/renderer/core/xml/xpath_grammar_generated.h"
#include "third_party/blink/renderer/core/xml/xpath_ns_resolver.h"
#include "third_party/blink/renderer/core/xml/xpath_path.h"
-#include "third_party/blink/renderer/core/xpath_grammar.h"
+#include "third_party/blink/renderer/core/xml/xpath_util.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
@@ -39,6 +40,9 @@
namespace blink {
namespace xpath {
+using xpathyy::YyParser;
+using TokenType = xpathyy::YyParser::token;
+
Parser* Parser::current_parser_ = nullptr;
enum XMLCat { kNameStart, kNameCont, kNotPartOfName };
@@ -119,28 +123,29 @@ bool Parser::IsBinaryOperatorContext() const {
switch (last_token_type_) {
case 0:
case '@':
- case AXISNAME:
+ case TokenType::kAxisName:
case '(':
case '[':
case ',':
- case AND:
- case OR:
- case MULOP:
+ case TokenType::kAnd:
+ case TokenType::kOr:
+ case TokenType::kMulOp:
case '/':
- case SLASHSLASH:
+ case TokenType::kSlashSlash:
case '|':
- case PLUS:
- case MINUS:
- case EQOP:
- case RELOP:
+ case TokenType::kPlus:
+ case TokenType::kMinus:
+ case TokenType::kEqOp:
+ case TokenType::kRelOp:
return false;
default:
return true;
}
}
+// See https://www.w3.org/TR/1999/REC-xpath-19991116/#NT-ExprWhitespace .
void Parser::SkipWS() {
- while (next_pos_ < data_.length() && IsSpaceOrNewline(data_[next_pos_]))
+ while (next_pos_ < data_.length() && IsXMLSpace(data_[next_pos_]))
++next_pos_;
}
@@ -190,12 +195,12 @@ Token Parser::LexString() {
if (value.IsNull())
value = "";
++next_pos_; // Consume the char.
- return Token(LITERAL, value);
+ return Token(TokenType::kLiteral, value);
}
}
// Ouch, went off the end -- report error.
- return Token(XPATH_ERROR);
+ return Token(TokenType::kXPathError);
}
Token Parser::LexNumber() {
@@ -216,7 +221,8 @@ Token Parser::LexNumber() {
}
}
- return Token(NUMBER, data_.Substring(start_pos, next_pos_ - start_pos));
+ return Token(TokenType::kNumber,
+ data_.Substring(start_pos, next_pos_ - start_pos));
}
bool Parser::LexNCName(String& name) {
@@ -292,62 +298,69 @@ Token Parser::NextTokenInternal() {
case '.': {
char next = PeekAheadHelper();
if (next == '.')
- return MakeTokenAndAdvance(DOTDOT, 2);
+ return MakeTokenAndAdvance(TokenType::kDotDot, 2);
if (next >= '0' && next <= '9')
return LexNumber();
return MakeTokenAndAdvance('.');
}
case '/':
if (PeekAheadHelper() == '/')
- return MakeTokenAndAdvance(SLASHSLASH, 2);
+ return MakeTokenAndAdvance(TokenType::kSlashSlash, 2);
return MakeTokenAndAdvance('/');
case '+':
- return MakeTokenAndAdvance(PLUS);
+ return MakeTokenAndAdvance(TokenType::kPlus);
case '-':
- return MakeTokenAndAdvance(MINUS);
+ return MakeTokenAndAdvance(TokenType::kMinus);
case '=':
- return MakeTokenAndAdvance(EQOP, EqTestOp::kOpcodeEqual);
+ return MakeTokenAndAdvance(TokenType::kEqOp, EqTestOp::kOpcodeEqual);
case '!':
- if (PeekAheadHelper() == '=')
- return MakeTokenAndAdvance(EQOP, EqTestOp::kOpcodeNotEqual, 2);
- return Token(XPATH_ERROR);
+ if (PeekAheadHelper() == '=') {
+ return MakeTokenAndAdvance(TokenType::kEqOp, EqTestOp::kOpcodeNotEqual,
+ 2);
+ }
+ return Token(TokenType::kXPathError);
case '<':
- if (PeekAheadHelper() == '=')
- return MakeTokenAndAdvance(RELOP, EqTestOp::kOpcodeLessOrEqual, 2);
- return MakeTokenAndAdvance(RELOP, EqTestOp::kOpcodeLessThan);
+ if (PeekAheadHelper() == '=') {
+ return MakeTokenAndAdvance(TokenType::kRelOp,
+ EqTestOp::kOpcodeLessOrEqual, 2);
+ }
+ return MakeTokenAndAdvance(TokenType::kRelOp, EqTestOp::kOpcodeLessThan);
case '>':
- if (PeekAheadHelper() == '=')
- return MakeTokenAndAdvance(RELOP, EqTestOp::kOpcodeGreaterOrEqual, 2);
- return MakeTokenAndAdvance(RELOP, EqTestOp::kOpcodeGreaterThan);
+ if (PeekAheadHelper() == '=') {
+ return MakeTokenAndAdvance(TokenType::kRelOp,
+ EqTestOp::kOpcodeGreaterOrEqual, 2);
+ }
+ return MakeTokenAndAdvance(TokenType::kRelOp,
+ EqTestOp::kOpcodeGreaterThan);
case '*':
if (IsBinaryOperatorContext())
- return MakeTokenAndAdvance(MULOP, NumericOp::kOP_Mul);
+ return MakeTokenAndAdvance(TokenType::kMulOp, NumericOp::kOP_Mul);
++next_pos_;
- return Token(NAMETEST, "*");
+ return Token(TokenType::kNameTest, "*");
case '$': { // $ QName
next_pos_++;
String name;
if (!LexQName(name))
- return Token(XPATH_ERROR);
- return Token(VARIABLEREFERENCE, name);
+ return Token(TokenType::kXPathError);
+ return Token(TokenType::kVariableReference, name);
}
}
String name;
if (!LexNCName(name))
- return Token(XPATH_ERROR);
+ return Token(TokenType::kXPathError);
SkipWS();
// If we're in an operator context, check for any operator names
if (IsBinaryOperatorContext()) {
if (name == "and") // ### hash?
- return Token(AND);
+ return Token(TokenType::kAnd);
if (name == "or")
- return Token(OR);
+ return Token(TokenType::kOr);
if (name == "mod")
- return Token(MULOP, NumericOp::kOP_Mod);
+ return Token(TokenType::kMulOp, NumericOp::kOP_Mod);
if (name == "div")
- return Token(MULOP, NumericOp::kOP_Div);
+ return Token(TokenType::kMulOp, NumericOp::kOP_Div);
}
// See whether we are at a :
@@ -360,9 +373,9 @@ Token Parser::NextTokenInternal() {
// It might be an axis name.
Step::Axis axis;
if (IsAxisName(name, axis))
- return Token(AXISNAME, axis);
+ return Token(TokenType::kAxisName, axis);
// Ugh, :: is only valid in axis names -> error
- return Token(XPATH_ERROR);
+ return Token(TokenType::kXPathError);
}
// Seems like this is a fully qualified qname, or perhaps the * modified
@@ -370,13 +383,13 @@ Token Parser::NextTokenInternal() {
SkipWS();
if (PeekCurHelper() == '*') {
next_pos_++;
- return Token(NAMETEST, name + ":*");
+ return Token(TokenType::kNameTest, name + ":*");
}
// Make a full qname.
String n2;
if (!LexNCName(n2))
- return Token(XPATH_ERROR);
+ return Token(TokenType::kXPathError);
name = name + ":" + n2;
}
@@ -388,16 +401,16 @@ Token Parser::NextTokenInternal() {
// Either node type of function name
if (IsNodeTypeName(name)) {
if (name == "processing-instruction")
- return Token(PI, name);
+ return Token(TokenType::kPI, name);
- return Token(NODETYPE, name);
+ return Token(TokenType::kNodeType, name);
}
// Must be a function name.
- return Token(FUNCTIONNAME, name);
+ return Token(TokenType::kFunctionName, name);
}
// At this point, it must be NAMETEST.
- return Token(NAMETEST, name);
+ return Token(TokenType::kNameTest, name);
}
Token Parser::NextToken() {
@@ -422,29 +435,28 @@ void Parser::Reset(const String& data) {
}
int Parser::Lex(void* data) {
- YYSTYPE* yylval = static_cast<YYSTYPE*>(data);
+ auto* yylval = static_cast<YyParser::semantic_type*>(data);
Token tok = NextToken();
switch (tok.type) {
- case AXISNAME:
- yylval->axis = tok.axis;
+ case TokenType::kAxisName:
+ yylval->build<Step::Axis>() = tok.axis;
break;
- case MULOP:
- yylval->num_op = tok.numop;
+ case TokenType::kMulOp:
+ yylval->build<NumericOp::Opcode>() = tok.numop;
break;
- case RELOP:
- case EQOP:
- yylval->eq_op = tok.eqop;
+ case TokenType::kRelOp:
+ case TokenType::kEqOp:
+ yylval->build<EqTestOp::Opcode>() = tok.eqop;
break;
- case NODETYPE:
- case PI:
- case FUNCTIONNAME:
- case LITERAL:
- case VARIABLEREFERENCE:
- case NUMBER:
- case NAMETEST:
- yylval->str = new String(tok.str);
- RegisterString(yylval->str);
+ case TokenType::kNodeType:
+ case TokenType::kPI:
+ case TokenType::kFunctionName:
+ case TokenType::kLiteral:
+ case TokenType::kVariableReference:
+ case TokenType::kNumber:
+ case TokenType::kNameTest:
+ yylval->build<String>() = String(tok.str);
break;
}
@@ -478,12 +490,10 @@ Expression* Parser::ParseStatement(const String& statement,
Parser* old_parser = current_parser_;
current_parser_ = this;
- int parse_error = xpathyyparse(this);
+ int parse_error = YyParser(this).parse();
current_parser_ = old_parser;
if (parse_error) {
- strings_.clear();
-
top_expr_ = nullptr;
if (got_namespace_error_)
@@ -496,28 +506,11 @@ Expression* Parser::ParseStatement(const String& statement,
"The string '" + statement + "' is not a valid XPath expression.");
return nullptr;
}
- DCHECK_EQ(strings_.size(), 0u);
Expression* result = top_expr_;
top_expr_ = nullptr;
return result;
}
-void Parser::RegisterString(String* s) {
- if (!s)
- return;
-
- DCHECK(!strings_.Contains(s));
- strings_.insert(base::WrapUnique(s));
-}
-
-void Parser::DeleteString(String* s) {
- if (!s)
- return;
-
- DCHECK(strings_.Contains(s));
- strings_.erase(s);
-}
-
} // namespace xpath
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_parser.h b/chromium/third_party/blink/renderer/core/xml/xpath_parser.h
index 5c05b54579f..f67d7cf8e38 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_parser.h
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_parser.h
@@ -68,7 +68,7 @@ class Parser {
Parser();
~Parser();
- XPathNSResolver* Resolver() const { return resolver_.Get(); }
+ XPathNSResolver* Resolver() const { return resolver_; }
bool ExpandQName(const String& q_name,
AtomicString& local_name,
AtomicString& namespace_uri);
@@ -81,12 +81,9 @@ class Parser {
int Lex(void* yylval);
- Member<Expression> top_expr_;
+ Expression* top_expr_;
bool got_namespace_error_;
- void RegisterString(String*);
- void DeleteString(String*);
-
private:
bool IsBinaryOperatorContext() const;
@@ -112,9 +109,8 @@ class Parser {
unsigned next_pos_;
String data_;
int last_token_type_;
- Member<XPathNSResolver> resolver_;
+ XPathNSResolver* resolver_ = nullptr;
- HashSet<std::unique_ptr<String>> strings_;
DISALLOW_COPY_AND_ASSIGN(Parser);
};
@@ -122,5 +118,4 @@ class Parser {
} // namespace blink
-int xpathyyparse(blink::xpath::Parser*);
#endif
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 fd910fc3d2c..a62d43336ea 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(blink::Visitor* visitor) {
+void Filter::Trace(Visitor* visitor) {
visitor->Trace(expr_);
visitor->Trace(predicates_);
Expression::Trace(visitor);
@@ -82,7 +82,7 @@ LocationPath::LocationPath() : absolute_(false) {
LocationPath::~LocationPath() = default;
-void LocationPath::Trace(blink::Visitor* visitor) {
+void LocationPath::Trace(Visitor* visitor) {
visitor->Trace(steps_);
Expression::Trace(visitor);
}
@@ -99,7 +99,7 @@ Value LocationPath::Evaluate(EvaluationContext& evaluation_context) const {
// the spec and treat / as the root node of the detached tree.
// This is for compatibility with Firefox, and also seems like a more
// logical treatment of where you would expect the "root" to be.
- Node* context = evaluation_context.node.Get();
+ Node* context = evaluation_context.node;
if (absolute_ && context->getNodeType() != Node::kDocumentNode) {
if (context->isConnected())
context = context->ownerDocument();
@@ -183,7 +183,7 @@ Path::Path(Expression* filter, LocationPath* path)
Path::~Path() = default;
-void Path::Trace(blink::Visitor* visitor) {
+void Path::Trace(Visitor* visitor) {
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 034e077291c..f0c6c089d59 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
Value Evaluate(EvaluationContext&) const override;
@@ -56,7 +56,7 @@ class LocationPath final : public Expression {
public:
LocationPath();
~LocationPath() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 fc0c0fb0e84..51eb97f7250 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(blink::Visitor* visitor) {
+void Number::Trace(Visitor* visitor) {
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(blink::Visitor* visitor) {
+void StringExpression::Trace(Visitor* visitor) {
visitor->Trace(value_);
Expression::Trace(visitor);
}
@@ -70,8 +70,9 @@ NumericOp::NumericOp(Opcode opcode, Expression* lhs, Expression* rhs)
}
Value NumericOp::Evaluate(EvaluationContext& context) const {
+ EvaluationContext cloned_context(context);
Value lhs(SubExpr(0)->Evaluate(context));
- Value rhs(SubExpr(1)->Evaluate(context));
+ Value rhs(SubExpr(1)->Evaluate(cloned_context));
double left_val = lhs.ToNumber();
double right_val = rhs.ToNumber();
@@ -203,8 +204,9 @@ bool EqTestOp::Compare(EvaluationContext& context,
}
Value EqTestOp::Evaluate(EvaluationContext& context) const {
+ EvaluationContext cloned_context(context);
Value lhs(SubExpr(0)->Evaluate(context));
- Value rhs(SubExpr(1)->Evaluate(context));
+ Value rhs(SubExpr(1)->Evaluate(cloned_context));
return Compare(context, lhs, rhs);
}
@@ -220,6 +222,7 @@ bool LogicalOp::ShortCircuitOn() const {
}
Value LogicalOp::Evaluate(EvaluationContext& context) const {
+ EvaluationContext cloned_context(context);
Value lhs(SubExpr(0)->Evaluate(context));
// This is not only an optimization, http://www.w3.org/TR/xpath
@@ -228,15 +231,18 @@ Value LogicalOp::Evaluate(EvaluationContext& context) const {
if (lhs_bool == ShortCircuitOn())
return lhs_bool;
- return SubExpr(1)->Evaluate(context).ToBoolean();
+ return SubExpr(1)->Evaluate(cloned_context).ToBoolean();
}
Value Union::Evaluate(EvaluationContext& context) const {
+ // SubExpr(0)->Evaluate() can change the context node, but SubExpr(1) should
+ // start with the current context node.
+ EvaluationContext cloned_context = context;
Value lhs_result = SubExpr(0)->Evaluate(context);
- Value rhs = SubExpr(1)->Evaluate(context);
+ Value rhs = SubExpr(1)->Evaluate(cloned_context);
NodeSet& result_set = lhs_result.ModifiableNodeSet(context);
- const NodeSet& rhs_nodes = rhs.ToNodeSet(&context);
+ const NodeSet& rhs_nodes = rhs.ToNodeSet(&cloned_context);
HeapHashSet<Member<Node>> nodes;
for (const auto& node : result_set)
@@ -256,14 +262,17 @@ Value Union::Evaluate(EvaluationContext& context) const {
Predicate::Predicate(Expression* expr) : expr_(expr) {}
-void Predicate::Trace(blink::Visitor* visitor) {
+void Predicate::Trace(Visitor* visitor) {
visitor->Trace(expr_);
}
bool Predicate::Evaluate(EvaluationContext& context) const {
DCHECK(expr_);
- Value result(expr_->Evaluate(context));
+ // Apply a cloned context because position() requires the current
+ // context node.
+ EvaluationContext cloned_context = context;
+ Value result(expr_->Evaluate(cloned_context));
// foo[3] means foo[position()=3]
if (result.IsNumber())
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 ac0fd980358..a9846d6646b 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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(blink::Visitor*);
+ void Trace(Visitor*);
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 97c0122ccdb..659e8d30604 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(blink::Visitor* visitor) {
+void XPathResult::Trace(Visitor* visitor) {
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 59a06470d59..5d8de537cd2 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 9cd60e7d3c4..1c816c3bab0 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_step.cc
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_step.cc
@@ -31,6 +31,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/dom/node_traversal.h"
+#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/xml/xpath_parser.h"
#include "third_party/blink/renderer/core/xml/xpath_util.h"
#include "third_party/blink/renderer/core/xmlns_names.h"
@@ -50,7 +51,7 @@ Step::Step(Axis axis,
Step::~Step() = default;
-void Step::Trace(blink::Visitor* visitor) {
+void Step::Trace(Visitor* visitor) {
visitor->Trace(node_test_);
visitor->Trace(predicates_);
ParseNode::Trace(visitor);
@@ -192,6 +193,11 @@ static inline bool NodeMatchesBasicTest(Node* node,
return namespace_uri.IsEmpty() ||
attr->namespaceURI() == namespace_uri;
+ if (attr->GetDocument().IsHTMLDocument() && attr->ownerElement() &&
+ attr->ownerElement()->IsHTMLElement() && namespace_uri.IsNull() &&
+ attr->namespaceURI().IsNull())
+ return EqualIgnoringASCIICase(attr->localName(), name);
+
return attr->localName() == name &&
attr->namespaceURI() == namespace_uri;
}
@@ -213,7 +219,7 @@ static inline bool NodeMatchesBasicTest(Node* node,
namespace_uri == element->namespaceURI();
}
- if (element->GetDocument().IsHTMLDocument()) {
+ if (IsA<HTMLDocument>(element->GetDocument())) {
if (element->IsHTMLElement()) {
// Paths without namespaces should match HTML elements in HTML
// documents despite those having an XHTML namespace. Names are
@@ -385,8 +391,15 @@ void Step::NodesInAxis(EvaluationContext& evaluation_context,
// need anyway.
if (GetNodeTest().GetKind() == NodeTest::kNameTest &&
GetNodeTest().Data() != g_star_atom) {
- Attr* attr = context_element->getAttributeNodeNS(
- GetNodeTest().NamespaceURI(), GetNodeTest().Data());
+ Attr* attr;
+ // We need this branch because getAttributeNodeNS() doesn't do
+ // ignore-case matching even for an HTML element in an HTML document.
+ if (GetNodeTest().NamespaceURI().IsNull()) {
+ attr = context_element->getAttributeNode(GetNodeTest().Data());
+ } else {
+ attr = context_element->getAttributeNodeNS(
+ GetNodeTest().NamespaceURI(), GetNodeTest().Data());
+ }
// In XPath land, namespace nodes are not accessible on the attribute
// axis.
if (attr && attr->namespaceURI() != xmlns_names::kNamespaceURI) {
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 5883c899481..44c844188db 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(blink::Visitor* visitor) { visitor->Trace(merged_predicates_); }
+ void Trace(Visitor* visitor) { 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void Optimize();
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_util.cc b/chromium/third_party/blink/renderer/core/xml/xpath_util.cc
index 7b51773168d..7b93a1360bb 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_util.cc
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_util.cc
@@ -84,5 +84,9 @@ bool IsValidContextNode(Node* node) {
return false;
}
+bool IsXMLSpace(UChar ch) {
+ return ch <= 0x20 && (ch == 0x20 || ch == 0x09 || ch == 0x0D || ch == 0x0A);
+}
+
} // namespace xpath
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_util.h b/chromium/third_party/blink/renderer/core/xml/xpath_util.h
index ddf04f5e6e5..2013cc4ec82 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_util.h
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_util.h
@@ -28,6 +28,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_XML_XPATH_UTIL_H_
#include "third_party/blink/renderer/platform/wtf/forward.h"
+#include "third_party/blink/renderer/platform/wtf/text/unicode.h"
namespace blink {
@@ -45,6 +46,9 @@ String StringValue(Node*);
// @return whether the given node is a valid context node
bool IsValidContextNode(Node*);
+// https://www.w3.org/TR/REC-xml/#NT-S
+bool IsXMLSpace(UChar ch);
+
} // namespace xpath
} // namespace blink
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 491c3427fc6..cafef7929f8 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(blink::Visitor* visitor) {
+void ValueData::Trace(Visitor* visitor) {
visitor->Trace(node_set_);
}
-void Value::Trace(blink::Visitor* visitor) {
+void Value::Trace(Visitor* visitor) {
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 a416d3ca875..b10c629adce 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(blink::Visitor*);
+ void Trace(Visitor*);
NodeSet& GetNodeSet() { return *node_set_; }
String string_;
@@ -89,7 +89,7 @@ class CORE_EXPORT Value {
data_(MakeGarbageCollected<ValueData>()) {
data_->GetNodeSet().Append(value);
}
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
// This is needed to safely implement constructing from bool - with normal
// function overloading, any pointer type would match.
@@ -112,7 +112,7 @@ class CORE_EXPORT Value {
bool IsString() const { return type_ == kStringValue; }
// If this is called during XPathExpression::evaluate(), EvaluationContext
- // should be passed.
+ // should be passed to record type conversion error.
const NodeSet& ToNodeSet(EvaluationContext*) const;
NodeSet& ModifiableNodeSet(EvaluationContext&);
bool ToBoolean() const;
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 d59872e69d1..18da053f9c2 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
@@ -29,41 +29,19 @@
#include "third_party/blink/renderer/core/css/style_sheet.h"
#include "third_party/blink/renderer/core/dom/processing_instruction.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
class XSLStyleSheet final : public StyleSheet {
public:
- static XSLStyleSheet* Create(ProcessingInstruction* parent_node,
- const String& original_url,
- const KURL& final_url) {
- DCHECK(RuntimeEnabledFeatures::XSLTEnabled());
- return MakeGarbageCollected<XSLStyleSheet>(parent_node, original_url,
- final_url, false);
- }
- static XSLStyleSheet* CreateEmbedded(ProcessingInstruction* parent_node,
- const KURL& final_url) {
- DCHECK(RuntimeEnabledFeatures::XSLTEnabled());
- return MakeGarbageCollected<XSLStyleSheet>(
- parent_node, final_url.GetString(), final_url, true);
- }
-
- // Taking an arbitrary node is unsafe, because owner node pointer can become
- // stale. XSLTProcessor ensures that the stylesheet doesn't outlive its
- // parent, in part by not exposing it to JavaScript.
- static XSLStyleSheet* CreateForXSLTProcessor(Document* document,
- Node* stylesheet_root_node,
- const String& original_url,
- const KURL& final_url) {
- DCHECK(RuntimeEnabledFeatures::XSLTEnabled());
- return MakeGarbageCollected<XSLStyleSheet>(document, stylesheet_root_node,
- original_url, final_url, false);
- }
-
XSLStyleSheet(Node* parent_node,
const String& original_url,
const KURL& final_url,
bool embedded);
+ // Taking an arbitrary node is unsafe, because owner node pointer can become
+ // stale. XSLTProcessor ensures that the stylesheet doesn't outlive its
+ // parent, in part by not exposing it to JavaScript.
XSLStyleSheet(Document* owner_document,
Node* style_sheet_root_node,
const String& original_url,
@@ -104,7 +82,7 @@ class XSLStyleSheet final : public StyleSheet {
KURL BaseURL() const override { return final_url_; }
bool IsLoading() const override { return false; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void LoadChildSheets();
@@ -128,11 +106,12 @@ class XSLStyleSheet final : public StyleSheet {
Member<Document> owner_document_;
};
-DEFINE_TYPE_CASTS(XSLStyleSheet,
- StyleSheet,
- sheet,
- !sheet->IsCSSStyleSheet(),
- !sheet.IsCSSStyleSheet());
+template <>
+struct DowncastTraits<XSLStyleSheet> {
+ static bool AllowFrom(const StyleSheet& sheet) {
+ return !sheet.IsCSSStyleSheet();
+ }
+};
} // namespace blink
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 40f5bb28189..23f535941d8 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
@@ -52,7 +52,9 @@ XSLStyleSheet::XSLStyleSheet(XSLStyleSheet* parent_style_sheet,
stylesheet_doc_taken_(false),
compilation_failed_(false),
parent_style_sheet_(parent_style_sheet),
- owner_document_(nullptr) {}
+ owner_document_(nullptr) {
+ DCHECK(RuntimeEnabledFeatures::XSLTEnabled());
+}
XSLStyleSheet::XSLStyleSheet(Node* parent_node,
const String& original_url,
@@ -68,7 +70,9 @@ XSLStyleSheet::XSLStyleSheet(Node* parent_node,
stylesheet_doc_taken_(false),
compilation_failed_(false),
parent_style_sheet_(nullptr),
- owner_document_(nullptr) {}
+ owner_document_(nullptr) {
+ DCHECK(RuntimeEnabledFeatures::XSLTEnabled());
+}
XSLStyleSheet::XSLStyleSheet(Document* owner_document,
Node* style_sheet_root_node,
@@ -85,7 +89,9 @@ XSLStyleSheet::XSLStyleSheet(Document* owner_document,
stylesheet_doc_taken_(false),
compilation_failed_(false),
parent_style_sheet_(nullptr),
- owner_document_(owner_document) {}
+ owner_document_(owner_document) {
+ DCHECK(RuntimeEnabledFeatures::XSLTEnabled());
+}
XSLStyleSheet::~XSLStyleSheet() {
if (!stylesheet_doc_taken_)
@@ -315,7 +321,7 @@ void XSLStyleSheet::MarkAsProcessed() {
stylesheet_doc_taken_ = true;
}
-void XSLStyleSheet::Trace(blink::Visitor* visitor) {
+void XSLStyleSheet::Trace(Visitor* visitor) {
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 1a2ebe4eee7..575ec97aeb5 100644
--- a/chromium/third_party/blink/renderer/core/xml/xslt_processor.cc
+++ b/chromium/third_party/blink/renderer/core/xml/xslt_processor.cc
@@ -33,6 +33,7 @@
#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/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/xml/document_xslt.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -76,7 +77,8 @@ Document* XSLTProcessor::CreateDocumentFromSource(
DocumentInit::Create()
.WithDocumentLoader(frame ? frame->Loader().GetDocumentLoader()
: nullptr)
- .WithURL(url);
+ .WithURL(url)
+ .WithTypeFrom(source_mime_type);
String document_source = source_string;
bool force_xhtml = source_mime_type == "text/plain";
@@ -107,8 +109,7 @@ Document* XSLTProcessor::CreateDocumentFromSource(
// Re-create the LocalFrameView if needed.
if (has_view)
frame->Client()->TransitionToCommittedForNewPage();
- result = frame->DomWindow()->InstallNewDocument(source_mime_type, init,
- force_xhtml);
+ result = frame->DomWindow()->InstallNewDocument(init, force_xhtml);
if (old_document) {
DocumentXSLT::From(*result).SetTransformSourceDocument(old_document);
@@ -119,8 +120,8 @@ Document* XSLTProcessor::CreateDocumentFromSource(
result->InitContentSecurityPolicy(csp);
}
} else {
- result =
- LocalDOMWindow::CreateDocument(source_mime_type, init, force_xhtml);
+ init = init.WithContextDocument(owner_document->ContextDocument());
+ result = LocalDOMWindow::CreateDocument(init, force_xhtml);
}
DocumentEncodingData data;
@@ -151,7 +152,7 @@ DocumentFragment* XSLTProcessor::transformToFragment(Node* source_node,
String result_encoding;
// If the output document is HTML, default to HTML method.
- if (output_doc->IsHTMLDocument())
+ if (IsA<HTMLDocument>(output_doc))
result_mime_type = "text/html";
if (!TransformToString(source_node, result_mime_type, result_string,
@@ -188,7 +189,7 @@ void XSLTProcessor::reset() {
parameters_.clear();
}
-void XSLTProcessor::Trace(blink::Visitor* visitor) {
+void XSLTProcessor::Trace(Visitor* visitor) {
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 acfaf8ca974..2030e632e54 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<XSLStyleSheet> stylesheet_;
diff --git a/chromium/third_party/blink/renderer/core/xml/xslt_processor.idl b/chromium/third_party/blink/renderer/core/xml/xslt_processor.idl
index ba796f26d94..f6ea356cfd1 100644
--- a/chromium/third_party/blink/renderer/core/xml/xslt_processor.idl
+++ b/chromium/third_party/blink/renderer/core/xml/xslt_processor.idl
@@ -31,11 +31,9 @@
// https://hg.mozilla.org/mozilla-central/file/012853bd80b7/dom/webidl/XSLTProcessor.webidl
[
- Constructor,
- ConstructorCallWith=Document,
- RuntimeEnabled=XSLT,
- MeasureAs=XSLTProcessor
+ RuntimeEnabled=XSLT
] interface XSLTProcessor {
+ [CallWith=Document, MeasureAs=XSLTProcessor] constructor();
void importStylesheet(Node style);
// TODO(foolip): In Gecko, the transformTo*() methods throw an exception in
diff --git a/chromium/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc b/chromium/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc
index 16bd92426b3..7ce25a518de 100644
--- a/chromium/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc
+++ b/chromium/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc
@@ -38,6 +38,7 @@
#include "third_party/blink/renderer/core/xml/xsl_style_sheet.h"
#include "third_party/blink/renderer/core/xml/xslt_extensions.h"
#include "third_party/blink/renderer/core/xml/xslt_unicode_sort.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h"
#include "third_party/blink/renderer/platform/loader/fetch/raw_resource.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource.h"
@@ -79,7 +80,7 @@ void XSLTProcessor::ParseErrorFunc(void* user_data, xmlError* error) {
break;
}
- console->AddMessage(ConsoleMessage::Create(
+ console->AddMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kXml, level, error->message,
std::make_unique<SourceLocation>(error->file, error->line, 0, nullptr)));
}
@@ -274,14 +275,14 @@ static xsltStylesheetPtr XsltStylesheetPointer(
if (!cached_stylesheet && stylesheet_root_node) {
// When using importStylesheet, we will use the given document as the
// imported stylesheet's owner.
- cached_stylesheet = XSLStyleSheet::CreateForXSLTProcessor(
+ cached_stylesheet = MakeGarbageCollected<XSLStyleSheet>(
stylesheet_root_node->parentNode()
? &stylesheet_root_node->parentNode()->GetDocument()
: document,
stylesheet_root_node,
stylesheet_root_node->GetDocument().Url().GetString(),
- stylesheet_root_node->GetDocument()
- .Url()); // FIXME: Should we use baseURL here?
+ stylesheet_root_node->GetDocument().Url(),
+ false); // FIXME: Should we use baseURL here?
// According to Mozilla documentation, the node must be a Document node,
// an xsl:stylesheet or xsl:transform element. But we just use text
diff --git a/chromium/third_party/blink/renderer/core/xmlhttprequest/BUILD.gn b/chromium/third_party/blink/renderer/core/xmlhttprequest/BUILD.gn
index a547ba0e989..973876b484f 100644
--- a/chromium/third_party/blink/renderer/core/xmlhttprequest/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/xmlhttprequest/BUILD.gn
@@ -6,6 +6,8 @@ import("//third_party/blink/renderer/core/core.gni")
blink_core_sources("xmlhttprequest") {
sources = [
+ "main_thread_disallow_synchronous_xhr_scope.cc",
+ "main_thread_disallow_synchronous_xhr_scope.h",
"xml_http_request.cc",
"xml_http_request.h",
"xml_http_request_event_target.h",
diff --git a/chromium/third_party/blink/renderer/core/xmlhttprequest/main_thread_disallow_synchronous_xhr_scope.cc b/chromium/third_party/blink/renderer/core/xmlhttprequest/main_thread_disallow_synchronous_xhr_scope.cc
new file mode 100644
index 00000000000..677a775e9b3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/xmlhttprequest/main_thread_disallow_synchronous_xhr_scope.cc
@@ -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.
+
+#include "third_party/blink/renderer/core/xmlhttprequest/main_thread_disallow_synchronous_xhr_scope.h"
+
+#include "base/logging.h"
+#include "third_party/blink/renderer/platform/wtf/wtf.h"
+
+namespace blink {
+
+static unsigned g_disallow_synchronous_xhr_count = 0;
+
+MainThreadDisallowSynchronousXHRScope::MainThreadDisallowSynchronousXHRScope() {
+ DCHECK(IsMainThread());
+ ++g_disallow_synchronous_xhr_count;
+}
+
+MainThreadDisallowSynchronousXHRScope::
+ ~MainThreadDisallowSynchronousXHRScope() {
+ DCHECK(IsMainThread());
+ --g_disallow_synchronous_xhr_count;
+}
+
+bool MainThreadDisallowSynchronousXHRScope::ShouldDisallowSynchronousXHR() {
+ DCHECK(IsMainThread());
+ return g_disallow_synchronous_xhr_count > 0;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/xmlhttprequest/main_thread_disallow_synchronous_xhr_scope.h b/chromium/third_party/blink/renderer/core/xmlhttprequest/main_thread_disallow_synchronous_xhr_scope.h
new file mode 100644
index 00000000000..1c0eaf7826f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/xmlhttprequest/main_thread_disallow_synchronous_xhr_scope.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_XMLHTTPREQUEST_MAIN_THREAD_DISALLOW_SYNCHRONOUS_XHR_SCOPE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_XMLHTTPREQUEST_MAIN_THREAD_DISALLOW_SYNCHRONOUS_XHR_SCOPE_H_
+
+#include "base/macros.h"
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+
+namespace blink {
+
+class CORE_EXPORT MainThreadDisallowSynchronousXHRScope final {
+ STACK_ALLOCATED();
+
+ public:
+ MainThreadDisallowSynchronousXHRScope();
+ ~MainThreadDisallowSynchronousXHRScope();
+
+ static bool ShouldDisallowSynchronousXHR();
+
+ DISALLOW_COPY_AND_ASSIGN(MainThreadDisallowSynchronousXHRScope);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_XMLHTTPREQUEST_MAIN_THREAD_DISALLOW_SYNCHRONOUS_XHR_SCOPE_H_
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 de51aab22e8..721fc7b15f8 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
@@ -32,6 +32,7 @@
#include "base/time/time.h"
#include "third_party/blink/public/common/blob/blob_utils.h"
#include "third_party/blink/public/common/features.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.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"
@@ -46,6 +47,7 @@
#include "third_party/blink/renderer/core/editing/serializers/serialization.h"
#include "third_party/blink/renderer/core/events/progress_event.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/fetch/trust_token_to_mojom.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
#include "third_party/blink/renderer/core/fileapi/file.h"
#include "third_party/blink/renderer/core/fileapi/file_reader_loader.h"
@@ -68,6 +70,7 @@
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
#include "third_party/blink/renderer/core/url/url_search_params.h"
+#include "third_party/blink/renderer/core/xmlhttprequest/main_thread_disallow_synchronous_xhr_scope.h"
#include "third_party/blink/renderer/core/xmlhttprequest/xml_http_request_upload.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -200,9 +203,9 @@ void LogConsoleError(ExecutionContext* context, const String& message) {
// FIXME: It's not good to report the bad usage without indicating what source
// line it came from. We should pass additional parameters so we can tell the
// console where the mistake occurred.
- ConsoleMessage* console_message =
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kError, message);
+ auto* console_message = MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kError, message);
context->AddConsoleMessage(console_message);
}
@@ -258,7 +261,7 @@ class XMLHttpRequest::BlobLoader final
void Cancel() { loader_->Cancel(); }
- void Trace(blink::Visitor* visitor) { visitor->Trace(xhr_); }
+ void Trace(Visitor* visitor) { visitor->Trace(xhr_); }
private:
Member<XMLHttpRequest> xhr_;
@@ -289,7 +292,7 @@ XMLHttpRequest::XMLHttpRequest(
v8::Isolate* isolate,
bool is_isolated_world,
scoped_refptr<SecurityOrigin> isolated_world_security_origin)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
progress_event_throttle_(
MakeGarbageCollected<XMLHttpRequestProgressEventThrottle>(this)),
isolate_(isolate),
@@ -304,7 +307,7 @@ XMLHttpRequest::~XMLHttpRequest() {
}
Document* XMLHttpRequest::GetDocument() const {
- return To<Document>(GetExecutionContext());
+ return Document::From(GetExecutionContext());
}
XMLHttpRequest::State XMLHttpRequest::readyState() const {
@@ -736,7 +739,7 @@ bool XMLHttpRequest::InitSend(ExceptionState& exception_state) {
if (!async_) {
if (GetExecutionContext()->IsDocument() &&
!GetDocument()->IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kSyncXHR,
+ mojom::blink::FeaturePolicyFeature::kSyncXHR,
ReportOptions::kReportOnFailure,
"Synchronous requests are disabled by Feature Policy.")) {
HandleNetworkError();
@@ -816,9 +819,9 @@ void XMLHttpRequest::send(Document* document, ExceptionState& exception_state) {
scoped_refptr<EncodedFormData> http_body;
if (AreMethodAndURLValidForSend()) {
- if (document->IsHTMLDocument())
+ if (IsA<HTMLDocument>(document))
UpdateContentTypeAndCharset("text/html;charset=UTF-8", "UTF-8");
- else if (document->IsXMLDocument())
+ else if (IsA<XMLDocument>(document))
UpdateContentTypeAndCharset("application/xml;charset=UTF-8", "UTF-8");
String body = CreateMarkup(document);
@@ -869,7 +872,7 @@ void XMLHttpRequest::send(Blob* body, ExceptionState& exception_state) {
if (body->HasBackingFile()) {
auto* file = To<File>(body);
if (!file->GetPath().IsEmpty())
- http_body->AppendFile(file->GetPath());
+ http_body->AppendFile(file->GetPath(), file->LastModifiedTime());
else
NOTREACHED();
} else {
@@ -1060,8 +1063,10 @@ void XMLHttpRequest::CreateRequest(scoped_refptr<EncodedFormData> http_body,
request.SetSkipServiceWorker(is_isolated_world_);
request.SetExternalRequestStateFromRequestorAddressSpace(
execution_context.GetSecurityContext().AddressSpace());
+ if (trust_token_params_)
+ request.SetTrustTokenParams(*trust_token_params_);
- probe::WillLoadXHR(&execution_context, method_, url_, async_, http_body.get(),
+ probe::WillLoadXHR(&execution_context, method_, url_, async_,
request_headers_, with_credentials_);
if (http_body) {
@@ -1100,18 +1105,6 @@ void XMLHttpRequest::CreateRequest(scoped_refptr<EncodedFormData> http_body,
if (async_) {
UseCounter::Count(&execution_context,
WebFeature::kXMLHttpRequestAsynchronous);
- if (execution_context.IsDocument()) {
- // Update histogram for usage of async xhr within pagedismissal.
- auto pagedismissal = GetDocument()->PageDismissalEventBeingDispatched();
- if (pagedismissal != Document::kNoDismissal) {
- UseCounter::Count(&execution_context,
- WebFeature::kAsyncXhrInPageDismissal);
- DEFINE_STATIC_LOCAL(EnumerationHistogram,
- asyncxhr_pagedismissal_histogram,
- ("XHR.Async.PageDismissal", 5));
- asyncxhr_pagedismissal_histogram.Count(pagedismissal);
- }
- }
if (upload_)
request.SetReportUploadProgress(true);
@@ -1126,7 +1119,7 @@ void XMLHttpRequest::CreateRequest(scoped_refptr<EncodedFormData> http_body,
if (frame->IsMainFrame()) {
UseCounter::Count(&execution_context,
WebFeature::kXMLHttpRequestSynchronousInMainFrame);
- } else if (frame->IsCrossOriginSubframe()) {
+ } else if (frame->IsCrossOriginToMainFrame()) {
UseCounter::Count(
&execution_context,
WebFeature::kXMLHttpRequestSynchronousInCrossOriginSubframe);
@@ -1136,33 +1129,16 @@ void XMLHttpRequest::CreateRequest(scoped_refptr<EncodedFormData> http_body,
WebFeature::kXMLHttpRequestSynchronousInSameOriginSubframe);
}
}
- // Update histogram for usage of sync xhr within pagedismissal.
- auto pagedismissal = GetDocument()->PageDismissalEventBeingDispatched();
- if (pagedismissal != Document::kNoDismissal) {
- // Disallow synchronous requests on page dismissal unless enabled by
- // origin trial or enterprise policy.
- if (!RuntimeEnabledFeatures::AllowSyncXHRInPageDismissalEnabled(
- &execution_context)) {
- UseCounter::Count(&execution_context,
- WebFeature::kForbiddenSyncXhrInPageDismissal);
- DEFINE_STATIC_LOCAL(EnumerationHistogram,
- forbidden_syncxhr_pagedismissal_histogram,
- ("XHR.Sync.PageDismissal_forbidden", 5));
- forbidden_syncxhr_pagedismissal_histogram.Count(pagedismissal);
- HandleNetworkError();
- ThrowForLoadFailureIfNeeded(exception_state,
- "Synchronous XHR in page dismissal. See "
- "https://www.chromestatus.com/feature/"
- "4664843055398912 for more details.");
- return;
- } else {
- UseCounter::Count(&execution_context,
- WebFeature::kSyncXhrInPageDismissal);
- DEFINE_STATIC_LOCAL(EnumerationHistogram,
- syncxhr_pagedismissal_histogram,
- ("XHR.Sync.PageDismissal", 5));
- syncxhr_pagedismissal_histogram.Count(pagedismissal);
- }
+ if (MainThreadDisallowSynchronousXHRScope::
+ ShouldDisallowSynchronousXHR() &&
+ !RuntimeEnabledFeatures::AllowSyncXHRInPageDismissalEnabled(
+ &execution_context)) {
+ HandleNetworkError();
+ ThrowForLoadFailureIfNeeded(exception_state,
+ "Synchronous XHR in page dismissal. See "
+ "https://www.chromestatus.com/feature/"
+ "4664843055398912 for more details.");
+ return;
}
} else {
DCHECK(execution_context.IsWorkerGlobalScope());
@@ -1468,6 +1444,38 @@ void XMLHttpRequest::SetRequestHeaderInternal(const AtomicString& name,
}
}
+void XMLHttpRequest::setTrustToken(const TrustToken* trust_token,
+ ExceptionState& exception_state) {
+ // These precondition checks are copied from |setRequestHeader|.
+ if (state_ != kOpened || send_flag_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "The object's state must be OPENED.");
+ return;
+ }
+
+ auto params = network::mojom::blink::TrustTokenParams::New();
+ if (!ConvertTrustTokenToMojom(*trust_token, &exception_state, params.get())) {
+ DCHECK(exception_state.HadException());
+ return;
+ }
+
+ bool operation_requires_feature_policy =
+ params->type ==
+ network::mojom::blink::TrustTokenOperationType::kRedemption ||
+ params->type == network::mojom::blink::TrustTokenOperationType::kSigning;
+ if (operation_requires_feature_policy &&
+ !GetExecutionContext()->IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kTrustTokenRedemption)) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotAllowedError,
+ "Trust Tokens redemption and signing require the "
+ "trust-token-redemption Feature Policy feature.");
+ return;
+ }
+
+ trust_token_params_ = std::move(params);
+}
+
bool XMLHttpRequest::HasContentTypeRequestHeader() const {
return request_headers_.Find(http_names::kContentType) !=
request_headers_.end();
@@ -1479,7 +1487,7 @@ String XMLHttpRequest::getAllResponseHeaders() const {
StringBuilder string_builder;
- WebHTTPHeaderSet access_control_expose_header_set =
+ HTTPHeaderSet access_control_expose_header_set =
cors::ExtractCorsExposedHeaderNamesList(
with_credentials_ ? network::mojom::CredentialsMode::kInclude
: network::mojom::CredentialsMode::kSameOrigin,
@@ -1543,7 +1551,7 @@ const AtomicString& XMLHttpRequest::getResponseHeader(
return g_null_atom;
}
- WebHTTPHeaderSet access_control_expose_header_set =
+ HTTPHeaderSet access_control_expose_header_set =
cors::ExtractCorsExposedHeaderNamesList(
with_credentials_ ? network::mojom::CredentialsMode::kInclude
: network::mojom::CredentialsMode::kSameOrigin,
@@ -2019,7 +2027,7 @@ void XMLHttpRequest::HandleDidTimeout() {
expected_length);
}
-void XMLHttpRequest::ContextDestroyed(ExecutionContext*) {
+void XMLHttpRequest::ContextDestroyed() {
Dispose();
// In case we are in the middle of send() function, unset the send flag to
@@ -2044,7 +2052,7 @@ const AtomicString& XMLHttpRequest::InterfaceName() const {
}
ExecutionContext* XMLHttpRequest::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
void XMLHttpRequest::ReportMemoryUsageToV8() {
@@ -2064,7 +2072,7 @@ void XMLHttpRequest::ReportMemoryUsageToV8() {
isolate_->AdjustAmountOfExternalAllocatedMemory(diff);
}
-void XMLHttpRequest::Trace(blink::Visitor* visitor) {
+void XMLHttpRequest::Trace(Visitor* visitor) {
visitor->Trace(response_blob_);
visitor->Trace(loader_);
visitor->Trace(response_document_);
@@ -2077,7 +2085,7 @@ void XMLHttpRequest::Trace(blink::Visitor* visitor) {
XMLHttpRequestEventTarget::Trace(visitor);
ThreadableLoaderClient::Trace(visitor);
DocumentParserClient::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
std::ostream& operator<<(std::ostream& ostream, const XMLHttpRequest* xhr) {
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 3208c78a41a..438c6da55f3 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
@@ -27,10 +27,12 @@
#include "base/memory/scoped_refptr.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "services/network/public/mojom/trust_tokens.mojom-blink.h"
#include "services/network/public/mojom/url_loader_factory.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/core/dom/document_parser_client.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/fetch/trust_token.h"
#include "third_party/blink/renderer/core/loader/threadable_loader_client.h"
#include "third_party/blink/renderer/core/probe/async_task_id.h"
#include "third_party/blink/renderer/core/xmlhttprequest/xml_http_request_event_target.h"
@@ -72,7 +74,7 @@ class XMLHttpRequest final : public XMLHttpRequestEventTarget,
public ThreadableLoaderClient,
public DocumentParserClient,
public ActiveScriptWrappable<XMLHttpRequest>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(XMLHttpRequest);
@@ -104,8 +106,8 @@ class XMLHttpRequest final : public XMLHttpRequestEventTarget,
kResponseTypeArrayBuffer,
};
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
ExecutionContext* GetExecutionContext() const override;
// ScriptWrappable
@@ -140,6 +142,7 @@ class XMLHttpRequest final : public XMLHttpRequestEventTarget,
void setRequestHeader(const AtomicString& name,
const AtomicString& value,
ExceptionState&);
+ void setTrustToken(const TrustToken*, ExceptionState&);
void overrideMimeType(const AtomicString& override, ExceptionState&);
String getAllResponseHeaders() const;
const AtomicString& getResponseHeader(const AtomicString&) const;
@@ -168,7 +171,7 @@ class XMLHttpRequest final : public XMLHttpRequestEventTarget,
DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange, kReadystatechange)
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
const char* NameInHeapSnapshot() const override { return "XMLHttpRequest"; }
private:
@@ -299,6 +302,7 @@ class XMLHttpRequest final : public XMLHttpRequestEventTarget,
blob_url_loader_factory_;
AtomicString method_;
HTTPHeaderMap request_headers_;
+ network::mojom::blink::TrustTokenParamsPtr trust_token_params_;
// Not converted to ASCII lowercase. Must be lowered later or compared
// using case insensitive comparison functions if needed.
AtomicString mime_type_override_;
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 55e87a7b04c..a17a33b0793 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
@@ -39,10 +39,9 @@ enum XMLHttpRequestResponseType {
[
ActiveScriptWrappable,
- Constructor,
- ConstructorCallWith=ScriptState,
Exposed=(Window,DedicatedWorker,SharedWorker)
] interface XMLHttpRequest : XMLHttpRequestEventTarget {
+ [CallWith=ScriptState] constructor();
// event handler
attribute EventHandler onreadystatechange;
@@ -58,6 +57,7 @@ enum XMLHttpRequestResponseType {
[RaisesException] void open(ByteString method, USVString url);
[RaisesException] void open(ByteString method, USVString url, boolean async, optional USVString? username = null, optional USVString? password = null);
[RaisesException] void setRequestHeader(ByteString name, ByteString value);
+ [RaisesException, RuntimeEnabled=TrustTokens, SecureContext] void setTrustToken(TrustToken trustToken);
[RaisesException=Setter] attribute unsigned long timeout;
[RaisesException=Setter] attribute boolean withCredentials;
readonly attribute XMLHttpRequestUpload upload;
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 65b488033dc..f200afc4acb 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(blink::Visitor* visitor) {
+void XMLHttpRequestProgressEventThrottle::Trace(Visitor* visitor) {
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 906a2463029..08ccd907b1d 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(blink::Visitor*);
+ void Trace(Visitor*);
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 1ee0eb42530..017449dcadc 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(blink::Visitor* visitor) {
+void XMLHttpRequestUpload::Trace(Visitor* visitor) {
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 9c08914f05a..ee159c79338 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 0f0b26ea466..762f66ac938 100644
--- a/chromium/third_party/blink/renderer/modules/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/BUILD.gn
@@ -93,6 +93,7 @@ jumbo_component("modules") {
"//third_party/blink/renderer/modules/eventsource",
"//third_party/blink/renderer/modules/exported",
"//third_party/blink/renderer/modules/filesystem",
+ "//third_party/blink/renderer/modules/font_access",
"//third_party/blink/renderer/modules/gamepad",
"//third_party/blink/renderer/modules/geolocation",
"//third_party/blink/renderer/modules/hid",
@@ -116,6 +117,7 @@ jumbo_component("modules") {
"//third_party/blink/renderer/modules/media",
"//third_party/blink/renderer/modules/webrtc",
"//third_party/blink/renderer/modules/native_file_system",
+ "//third_party/blink/renderer/modules/native_io",
"//third_party/blink/renderer/modules/navigatorcontentutils",
"//third_party/blink/renderer/modules/netinfo",
"//third_party/blink/renderer/modules/nfc",
@@ -135,14 +137,14 @@ jumbo_component("modules") {
"//third_party/blink/renderer/modules/sensor",
"//third_party/blink/renderer/modules/service_worker",
"//third_party/blink/renderer/modules/shapedetection",
- "//third_party/blink/renderer/modules/sms",
"//third_party/blink/renderer/modules/speech",
"//third_party/blink/renderer/modules/srcobject",
"//third_party/blink/renderer/modules/storage",
"//third_party/blink/renderer/modules/vibration",
- "//third_party/blink/renderer/modules/video_raf",
+ "//third_party/blink/renderer/modules/video_rvfc",
"//third_party/blink/renderer/modules/wake_lock",
"//third_party/blink/renderer/modules/webaudio",
+ "//third_party/blink/renderer/modules/webcodecs",
"//third_party/blink/renderer/modules/webdatabase",
"//third_party/blink/renderer/modules/webgl",
"//third_party/blink/renderer/modules/webgpu",
@@ -155,6 +157,10 @@ jumbo_component("modules") {
"//third_party/blink/renderer/modules/xr",
]
+ if (is_android) {
+ sub_modules += [ "//third_party/blink/renderer/modules/remote_objects" ]
+ }
+
deps = [
":make_modules_generated",
":module_names",
@@ -163,6 +169,7 @@ jumbo_component("modules") {
"//third_party/blink/renderer/bindings/modules:generated",
"//third_party/blink/renderer/bindings/modules/v8:bindings_modules_impl",
"//third_party/blink/renderer/bindings/modules/v8:bindings_modules_origin_trial_features",
+ "//third_party/blink/renderer/bindings/modules/v8:generated",
"//third_party/blink/renderer/core",
"//third_party/icu",
"//third_party/webrtc_overrides:webrtc_component",
@@ -177,7 +184,8 @@ jumbo_component("modules") {
}
if (is_win) {
- cflags = [ "/wd4334" ] # Result of 32-bit shift implicitly converted to 64 bits.
+ cflags =
+ [ "/wd4334" ] # Result of 32-bit shift implicitly converted to 64 bits.
}
configs -= [ "//build/config/compiler:default_symbols" ]
@@ -190,6 +198,8 @@ jumbo_source_set("modules_testing") {
"$bindings_modules_v8_output_dir/v8_internals_partial.h",
"accessibility/testing/internals_accessibility.cc",
"accessibility/testing/internals_accessibility.h",
+ "canvas/canvas2d/testing/internals_canvas_rendering_context_2d.cc",
+ "canvas/canvas2d/testing/internals_canvas_rendering_context_2d.h",
"mediastream/testing/internals_media_stream.cc",
"mediastream/testing/internals_media_stream.h",
"netinfo/testing/internals_net_info.cc",
@@ -206,6 +216,8 @@ jumbo_source_set("modules_testing") {
"peerconnection/testing/internals_rtc_certificate.h",
"peerconnection/testing/internals_rtc_peer_connection.cc",
"peerconnection/testing/internals_rtc_peer_connection.h",
+ "permissions/testing/internals_permission.cc",
+ "permissions/testing/internals_permission.h",
"service_worker/testing/internals_service_worker.cc",
"service_worker/testing/internals_service_worker.h",
"speech/testing/internals_speech_synthesis.cc",
@@ -243,6 +255,7 @@ jumbo_source_set("unit_tests") {
sources = [
"accessibility/accessibility_object_model_test.cc",
+ "accessibility/ax_layout_object_test.cc",
"accessibility/ax_object_cache_test.cc",
"accessibility/ax_object_test.cc",
"accessibility/ax_position_test.cc",
@@ -272,7 +285,7 @@ jumbo_source_set("unit_tests") {
"csspaint/paint_worklet_test.cc",
"device_orientation/device_motion_event_pump_unittest.cc",
"device_orientation/device_orientation_event_pump_unittest.cc",
- "document_metadata/copyless_paste_extractor_test.cc",
+ "document_metadata/document_metadata_extractor_test.cc",
"eventsource/event_source_parser_test.cc",
"filesystem/dom_file_system_base_test.cc",
"filesystem/file_writer_test.cc",
@@ -298,6 +311,7 @@ jumbo_source_set("unit_tests") {
"manifest/manifest_parser_unittest.cc",
"manifest/manifest_type_converters_unittest.cc",
"media/webmediaplayer_util_unittest.cc",
+ "media_capabilities/media_capabilities_test.cc",
"media_controls/elements/media_control_animated_arrow_container_element_test.cc",
"media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc",
"media_controls/elements/media_control_input_element_test.cc",
@@ -316,6 +330,8 @@ jumbo_source_set("unit_tests") {
"mediarecorder/audio_track_recorder_unittest.cc",
"mediarecorder/fake_encoded_video_frame.h",
"mediarecorder/media_recorder_handler_unittest.cc",
+ "mediarecorder/media_recorder_unittest.cc",
+ "mediarecorder/track_recorder_unittest.cc",
"mediarecorder/video_track_recorder_unittest.cc",
"mediasession/media_session_test.cc",
"mediastream/media_constraints_test.cc",
@@ -366,6 +382,10 @@ jumbo_source_set("unit_tests") {
"peerconnection/peer_connection_dependency_factory_test.cc",
"peerconnection/peer_connection_tracker_test.cc",
"peerconnection/rtc_data_channel_test.cc",
+ "peerconnection/rtc_encoded_audio_underlying_sink_test.cc",
+ "peerconnection/rtc_encoded_audio_underlying_source_test.cc",
+ "peerconnection/rtc_encoded_video_underlying_sink_test.cc",
+ "peerconnection/rtc_encoded_video_underlying_source_test.cc",
"peerconnection/rtc_ice_transport_test.cc",
"peerconnection/rtc_ice_transport_test.h",
"peerconnection/rtc_peer_connection_handler_test.cc",
@@ -401,7 +421,8 @@ jumbo_source_set("unit_tests") {
"service_worker/service_worker_installed_scripts_manager_test.cc",
"service_worker/thread_safe_script_container_test.cc",
"service_worker/web_embedded_worker_impl_test.cc",
- "video_raf/video_frame_request_callback_collection_test.cc",
+ "video_rvfc/video_frame_callback_requester_impl_test.cc",
+ "video_rvfc/video_frame_request_callback_collection_test.cc",
"wake_lock/wake_lock_manager_test.cc",
"wake_lock/wake_lock_sentinel_test.cc",
"wake_lock/wake_lock_test.cc",
@@ -447,19 +468,26 @@ jumbo_source_set("unit_tests") {
deps = [
":modules",
":modules_testing",
+ "//base",
+ "//base/test:test_support",
+ "//build:chromecast_buildflags",
+ "//components/schema_org/common:mojom_blink",
"//media:test_support",
+ "//media/mojo/mojom",
+ "//mojo/public/cpp/bindings",
"//net:quic_test_tools",
"//services/device/public/cpp:test_support",
- "//services/viz/public/mojom:mojom_blink",
"//skia",
"//testing/gmock",
"//testing/gtest",
"//third_party/blink/public:blink_headers",
"//third_party/blink/renderer/core",
+ "//third_party/blink/renderer/core:unit_test_support",
"//third_party/blink/renderer/modules/gamepad:unit_tests",
"//third_party/blink/renderer/modules/hid:unit_tests",
"//third_party/blink/renderer/modules/native_file_system:unit_tests",
"//third_party/blink/renderer/modules/storage:unit_tests",
+ "//third_party/blink/renderer/modules/webcodecs:unit_tests",
"//third_party/blink/renderer/modules/webtransport:unit_tests",
"//third_party/blink/renderer/platform",
"//third_party/blink/renderer/platform/wtf",
@@ -475,21 +503,15 @@ jumbo_source_set("unit_tests") {
}
group("accessibility_unittests_data") {
- data = [
- "accessibility/testing/data/",
- ]
+ data = [ "accessibility/testing/data/" ]
}
group("mediastream_unittests_data") {
- data = [
- "//media/test/data/",
- ]
+ data = [ "//media/test/data/" ]
}
fuzzer_test("web_app_manifest_fuzzer") {
- sources = [
- "manifest/manifest_fuzzer.cc",
- ]
+ sources = [ "manifest/manifest_fuzzer.cc" ]
dict = "manifest/manifest_fuzzer.dict"
seed_corpus = "manifest/fuzzer_seed_corpus"
@@ -502,9 +524,7 @@ fuzzer_test("web_app_manifest_fuzzer") {
if (use_libfuzzer) {
fuzzer_test("media_capabilities_fuzzer") {
- sources = [
- "media_capabilities/media_capabilities_fuzzer.cc",
- ]
+ sources = [ "media_capabilities/media_capabilities_fuzzer.cc" ]
seed_corpus = "media_capabilities/fuzzer_seed_corpus"
diff --git a/chromium/third_party/blink/renderer/modules/DEPS b/chromium/third_party/blink/renderer/modules/DEPS
index 7ecc3900ec1..374cb59f335 100644
--- a/chromium/third_party/blink/renderer/modules/DEPS
+++ b/chromium/third_party/blink/renderer/modules/DEPS
@@ -3,9 +3,8 @@ include_rules = [
"+base/memory/scoped_refptr.h",
"+base/strings/char_traits.h",
"+mojo/public/cpp/bindings",
+ "+mojo/public/cpp/system",
"+services/network/public/cpp/shared_url_loader_factory.h",
- "+services/service_manager/public/mojom/interface_provider.mojom-blink.h",
- "+services/service_manager/public/mojom/interface_provider.mojom-blink-forward.h",
"+services/viz/public/mojom/hit_test/hit_test_region_list.mojom-blink.h",
"+third_party/blink/public/common",
"+third_party/blink/public/web",
@@ -18,6 +17,7 @@ include_rules = [
"!third_party/blink/renderer/core/frame/web_local_frame_impl.h",
"!third_party/blink/renderer/core/frame/web_remote_frame_impl.h",
"+third_party/blink/renderer/modules",
+ "+ui/gfx/geometry",
"-web",
]
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/BUILD.gn b/chromium/third_party/blink/renderer/modules/accessibility/BUILD.gn
index e8c8f4c5af7..db282c1d7c3 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/accessibility/BUILD.gn
@@ -64,9 +64,7 @@ blink_modules_sources("accessibility") {
"inspector_type_builder_helper.h",
]
- deps = [
- "//ui/accessibility:ax_enums_mojo_blink",
- ]
+ deps = [ "//ui/accessibility:ax_enums_mojo_blink" ]
# The modules/accessibility/ depends closely on core/ --
# include the core pch for faster Windows compilation times.
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/DEPS b/chromium/third_party/blink/renderer/modules/accessibility/DEPS
index 7f78b77b1af..d4f670c0dbc 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/DEPS
+++ b/chromium/third_party/blink/renderer/modules/accessibility/DEPS
@@ -1,5 +1,4 @@
include_rules = [
- "+mojo/public/cpp/bindings/binding.h",
"+ui/accessibility/ax_enums.mojom-blink.h",
"+ui/accessibility/ax_enums.mojom-blink-forward.h",
"-third_party/blink/renderer/modules",
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/accessibility_object_model_test.cc b/chromium/third_party/blink/renderer/modules/accessibility/accessibility_object_model_test.cc
index 509ffe5ae0a..adcdfe96ac1 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/accessibility_object_model_test.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/accessibility_object_model_test.cc
@@ -66,7 +66,8 @@ TEST_F(AccessibilityObjectModelTest, SetAccessibleNodeRole) {
button->accessibleNode()->setRole("slider");
EXPECT_EQ("slider", button->accessibleNode()->role());
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
axButton = cache->GetOrCreate(button);
// No change in the AXObject role should be observed.
@@ -120,7 +121,8 @@ TEST_F(AccessibilityObjectModelTest, AOMPropertiesCanBeCleared) {
// Assert that the AX object was affected by ARIA attributes.
auto* cache = AXObjectCache();
ASSERT_NE(nullptr, cache);
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
auto* axButton = cache->GetOrCreate(button);
EXPECT_EQ(ax::mojom::Role::kCheckBox, axButton->RoleValue());
ax::mojom::NameFrom name_from;
@@ -132,7 +134,8 @@ TEST_F(AccessibilityObjectModelTest, AOMPropertiesCanBeCleared) {
button->accessibleNode()->setRole("radio");
button->accessibleNode()->setLabel("Radio");
button->accessibleNode()->setDisabled(false, false);
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
// Assert that AOM does not affect the AXObject.
axButton = cache->GetOrCreate(button);
@@ -144,7 +147,8 @@ TEST_F(AccessibilityObjectModelTest, AOMPropertiesCanBeCleared) {
button->accessibleNode()->setRole(g_null_atom);
button->accessibleNode()->setLabel(g_null_atom);
button->accessibleNode()->setDisabled(false, true);
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
// The AX Object should now revert to ARIA.
axButton = cache->GetOrCreate(button);
@@ -167,7 +171,8 @@ TEST_F(AccessibilityObjectModelTest, RangeProperties) {
auto* cache = AXObjectCache();
ASSERT_NE(nullptr, cache);
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToLayoutClean(
+ DocumentUpdateReason::kTest);
auto* ax_slider = cache->GetOrCreate(slider);
float value = 0.0f;
EXPECT_TRUE(ax_slider->MinValueForRange(&value));
@@ -346,10 +351,10 @@ TEST_F(AccessibilityObjectModelTest, SparseAttributes) {
sparse_attributes.object_attributes
.at(AXObjectAttribute::kAriaActiveDescendant)
->RoleValue());
- ASSERT_EQ(
- ax::mojom::Role::kContentInfo,
- sparse_attributes.object_attributes.at(AXObjectAttribute::kAriaDetails)
- ->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kContentInfo,
+ sparse_attributes.object_vector_attributes
+ .at(AXObjectVectorAttribute::kAriaDetails)[0]
+ ->RoleValue());
ASSERT_EQ(ax::mojom::Role::kArticle,
sparse_attributes.object_attributes
.at(AXObjectAttribute::kAriaErrorMessage)
@@ -359,8 +364,11 @@ TEST_F(AccessibilityObjectModelTest, SparseAttributes) {
target->accessibleNode()->setRoleDescription("Object");
target->accessibleNode()->setActiveDescendant(
GetDocument().getElementById("active2")->accessibleNode());
- target->accessibleNode()->setDetails(
+ AccessibleNodeList* details_node_list =
+ MakeGarbageCollected<AccessibleNodeList>();
+ details_node_list->add(
GetDocument().getElementById("details2")->accessibleNode());
+ target->accessibleNode()->setDetails(details_node_list);
target->accessibleNode()->setErrorMessage(
GetDocument().getElementById("error2")->accessibleNode());
@@ -375,10 +383,10 @@ TEST_F(AccessibilityObjectModelTest, SparseAttributes) {
sparse_attributes2.object_attributes
.at(AXObjectAttribute::kAriaActiveDescendant)
->RoleValue());
- ASSERT_EQ(
- ax::mojom::Role::kContentInfo,
- sparse_attributes2.object_attributes.at(AXObjectAttribute::kAriaDetails)
- ->RoleValue());
+ ASSERT_EQ(ax::mojom::Role::kContentInfo,
+ sparse_attributes2.object_vector_attributes
+ .at(AXObjectVectorAttribute::kAriaDetails)[0]
+ ->RoleValue());
ASSERT_EQ(ax::mojom::Role::kArticle,
sparse_attributes2.object_attributes
.at(AXObjectAttribute::kAriaErrorMessage)
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_enums.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_enums.cc
index d1a3eeed414..0fc39a7c5fe 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_enums.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_enums.cc
@@ -33,8 +33,8 @@ STATIC_ASSERT_ENUM(WebAXObjectAttribute::kAriaErrorMessage,
AXObjectAttribute::kAriaErrorMessage);
STATIC_ASSERT_ENUM(WebAXObjectVectorAttribute::kAriaControls,
AXObjectVectorAttribute::kAriaControls);
-STATIC_ASSERT_ENUM(WebAXObjectAttribute::kAriaDetails,
- AXObjectAttribute::kAriaDetails);
+STATIC_ASSERT_ENUM(WebAXObjectVectorAttribute::kAriaDetails,
+ AXObjectVectorAttribute::kAriaDetails);
STATIC_ASSERT_ENUM(WebAXObjectVectorAttribute::kAriaFlowTo,
AXObjectVectorAttribute::kAriaFlowTo);
} // namespace blink
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 81335f95136..8230d0ba787 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_enums.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_enums.h
@@ -63,12 +63,12 @@ enum class AXStringAttribute {
enum class AXObjectAttribute {
kAriaActiveDescendant,
- kAriaDetails,
kAriaErrorMessage,
};
enum class AXObjectVectorAttribute {
kAriaControls,
+ kAriaDetails,
kAriaFlowTo,
};
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 9d9bdfed8be..69a773b18bb 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
@@ -67,6 +67,12 @@ ax::mojom::Role AXImageMapLink::RoleValue() const {
if (!aria_role.IsEmpty())
return AXObject::AriaRoleToWebCoreRole(aria_role);
+ // https://www.w3.org/TR/html-aam-1.0/#html-element-role-mappings
+ // <area> tags without an href should be treated as static text.
+ KURL url = Url();
+ if (url.IsNull() || url.IsEmpty())
+ return ax::mojom::Role::kStaticText;
+
return ax::mojom::Role::kLink;
}
@@ -104,8 +110,8 @@ void AXImageMapLink::GetRelativeBounds(AXObject** out_container,
return;
LayoutObject* layout_object;
- if (parent_ && parent_->IsAXLayoutObject())
- layout_object = ToAXLayoutObject(parent_)->GetLayoutObject();
+ if (auto* ax_object = DynamicTo<AXLayoutObject>(parent_.Get()))
+ layout_object = ax_object->GetLayoutObject();
else
layout_object = map->GetLayoutObject();
@@ -116,7 +122,7 @@ void AXImageMapLink::GetRelativeBounds(AXObject** out_container,
*out_container = AXObjectCache().GetOrCreate(layout_object);
}
-void AXImageMapLink::Trace(blink::Visitor* visitor) {
+void AXImageMapLink::Trace(Visitor* visitor) {
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 b6f795e3ea6..2b3c07a8374 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
HTMLAreaElement* AreaElement() const {
return To<HTMLAreaElement>(GetNode());
@@ -70,7 +70,12 @@ class AXImageMapLink final : public AXNodeObject {
DISALLOW_COPY_AND_ASSIGN(AXImageMapLink);
};
-DEFINE_AX_OBJECT_TYPE_CASTS(AXImageMapLink, IsImageMapLink());
+template <>
+struct DowncastTraits<AXImageMapLink> {
+ static bool AllowFrom(const AXObject& object) {
+ return object.IsImageMapLink();
+ }
+};
} // namespace blink
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 1b78c7ab11b..f24e9272c4f 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
@@ -28,6 +28,7 @@
#include "third_party/blink/renderer/modules/accessibility/ax_layout_object.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/css/css_property_names.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
@@ -55,7 +56,6 @@
#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/imagebitmap/image_bitmap_options.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"
@@ -65,9 +65,7 @@
#include "third_party/blink/renderer/core/layout/layout_html_canvas.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_list_item.h"
#include "third_party/blink/renderer/core/layout/layout_list_marker.h"
-#include "third_party/blink/renderer/core/layout/layout_menu_list.h"
#include "third_party/blink/renderer/core/layout/layout_replaced.h"
#include "third_party/blink/renderer/core/layout/layout_table.h"
#include "third_party/blink/renderer/core/layout/layout_table_cell.h"
@@ -78,8 +76,6 @@
#include "third_party/blink/renderer/core/layout/layout_view.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/layout/ng/list/layout_ng_list_marker.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"
@@ -185,7 +181,7 @@ ax::mojom::Role AXLayoutObject::NativeRoleIgnoringAria() const {
if ((css_box && css_box->IsListItem()) || IsA<HTMLLIElement>(node))
return ax::mojom::Role::kListItem;
- if (layout_object_->IsListMarkerIncludingNGInside())
+ if (layout_object_->IsListMarkerIncludingNGOutsideAndInside())
return ax::mojom::Role::kListMarker;
if (layout_object_->IsBR())
return ax::mojom::Role::kLineBreak;
@@ -219,7 +215,7 @@ ax::mojom::Role AXLayoutObject::NativeRoleIgnoringAria() const {
if (IsA<HTMLCanvasElement>(node))
return ax::mojom::Role::kCanvas;
- if (css_box && css_box->IsLayoutView())
+ if (IsA<LayoutView>(css_box))
return ax::mojom::Role::kRootWebArea;
if (layout_object_->IsSVGImage())
@@ -266,18 +262,17 @@ Node* AXLayoutObject::GetNodeOrContainingBlockNode() const {
if (IsDetached())
return nullptr;
- if (layout_object_->IsListMarker())
- return ToLayoutListMarker(layout_object_)->ListItem()->GetNode();
-
- if (layout_object_->IsLayoutNGListMarkerIncludingInside()) {
- if (LayoutNGListItem* list_item =
- LayoutNGListItem::FromMarker(*layout_object_))
- return list_item->GetNode();
- return nullptr;
+ if (layout_object_->IsListMarker()) {
+ // Return the originating list item node.
+ return layout_object_->GetNode()->parentNode();
}
- if (layout_object_->IsAnonymous() && layout_object_->ContainingBlock()) {
- return layout_object_->ContainingBlock()->GetNode();
+ if (layout_object_->IsAnonymous()) {
+ if (LayoutBlock* layout_block =
+ LayoutObject::FindNonAnonymousContainingBlock(layout_object_)) {
+ return layout_block->GetNode();
+ }
+ return nullptr;
}
return GetNode();
@@ -299,6 +294,14 @@ void AXLayoutObject::Detach() {
layout_object_ = nullptr;
}
+bool AXLayoutObject::IsDetached() const {
+ return !layout_object_ || AXObject::IsDetached();
+}
+
+bool AXLayoutObject::IsAXLayoutObject() const {
+ return true;
+}
+
//
// Check object role or purpose.
//
@@ -337,21 +340,9 @@ bool AXLayoutObject::IsEditable() const {
if (!node)
return false;
- // TODO(accessibility) pursue standards track so that aria-goog-editable
- // becomes aria-editable. At that time, create ariaEditableAttr in
- // html_element.cc. The current version of the editable attribute does not
- // inherit, in order to match the automatic Gecko implementation, but
- // hopefully the standardized version will, in which case a more performant
- // implementation will be required, e.g. cache it or only expose on ancestor,
- // having browser-side propagate it.
const auto* elem = DynamicTo<Element>(node);
if (!elem)
elem = FlatTreeTraversal::ParentElement(*node);
- if (elem && elem->hasAttribute("aria-goog-editable")) {
- auto editable = elem->getAttribute("aria-goog-editable");
- return !EqualIgnoringASCIICase("false", editable);
- }
-
if (GetLayoutObject()->IsTextControl())
return true;
@@ -385,20 +376,9 @@ bool AXLayoutObject::IsRichlyEditable() const {
if (!node)
return false;
- // TODO(accessibility) pursue standards track so that aria-goog-editable
- // becomes aria-editable. At that time, create ariaEditableAttr in
- // html_element.cc. The current version of the editable attribute does not
- // inherit, in order to match the automatic Gecko implementation, but
- // hopefully the standardized version will, in which case a more performant
- // implementation will be required, e.g. cache it or only expose on ancestor,
- // having browser-side propagate it.
const Element* elem = DynamicTo<Element>(node);
if (!elem)
elem = FlatTreeTraversal::ParentElement(*node);
- if (elem && elem->hasAttribute("aria-goog-editable")) {
- auto editable = elem->getAttribute("aria-goog-editable");
- return !EqualIgnoringASCIICase("false", editable);
- }
// Contrary to Firefox, we mark richly editable all auto-generated content,
// such as list bullets and soft line breaks, that are contained within a
@@ -478,7 +458,7 @@ bool AXLayoutObject::IsFocused() const {
if (!focused_element)
return false;
AXObject* focused_object = AXObjectCache().GetOrCreate(focused_element);
- if (!focused_object || !focused_object->IsAXLayoutObject())
+ if (!IsA<AXLayoutObject>(focused_object))
return false;
// A web area is represented by the Document node in the DOM tree, which isn't
@@ -505,23 +485,34 @@ AccessibilitySelectedState AXLayoutObject::IsSelected() const {
if (!GetLayoutObject() || !GetNode() || !CanSetSelectedAttribute())
return kSelectedStateUndefined;
- // aria-selected overrides automatic behaviors
+ // The aria-selected attribute overrides automatic behaviors.
bool is_selected;
if (HasAOMPropertyOrARIAAttribute(AOMBooleanProperty::kSelected, is_selected))
return is_selected ? kSelectedStateTrue : kSelectedStateFalse;
- // Tab item with focus in the associated tab
- if (IsTabItem() && IsTabItemSelected())
- return kSelectedStateTrue;
+ // The selection should only follow the focus when the aria-selected attribute
+ // is marked as required or implied for this element in the ARIA specs.
+ // If this object can't follow the focus, then we can't say that it's selected
+ // nor that it's not.
+ if (!SelectionShouldFollowFocus())
+ return kSelectedStateUndefined;
- // Selection follows focus, but ONLY in single selection containers,
- // and only if aria-selected was not present to override
+ // Selection follows focus, but ONLY in single selection containers, and only
+ // if aria-selected was not present to override.
return IsSelectedFromFocus() ? kSelectedStateTrue : kSelectedStateFalse;
}
// In single selection containers, selection follows focus unless aria_selected
-// is set to false.
+// is set to false. This is only valid for a subset of elements.
bool AXLayoutObject::IsSelectedFromFocus() const {
+ if (!SelectionShouldFollowFocus())
+ return false;
+
+ // A tab item can also be selected if it is associated to a focused tabpanel
+ // via the aria-labelledby attribute.
+ if (IsTabItem() && IsTabItemSelected())
+ return kSelectedStateTrue;
+
// If not a single selection container, selection does not follow focus.
AXObject* container = ContainerWidget();
if (!container || container->IsMultiSelectable())
@@ -541,6 +532,20 @@ bool AXLayoutObject::IsSelectedFromFocus() const {
is_selected);
}
+// Returns true if the node's aria-selected attribute should be set to true
+// 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:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
//
// Whether objects are ignored, i.e. not included in the tree.
//
@@ -583,11 +588,11 @@ bool AXLayoutObject::IsPlaceholder() const {
return false;
LayoutObject* parent_layout_object = parent_object->GetLayoutObject();
- if (!parent_layout_object || !parent_layout_object->IsTextControl())
+ auto* layout_text_control =
+ DynamicTo<LayoutTextControl>(parent_layout_object);
+ if (!layout_text_control)
return false;
- LayoutTextControl* layout_text_control =
- ToLayoutTextControl(parent_layout_object);
DCHECK(layout_text_control);
TextControlElement* text_control_element =
@@ -611,6 +616,9 @@ bool AXLayoutObject::ComputeAccessibilityIsIgnored(
if (role_ == ax::mojom::Role::kRootWebArea)
return false;
+ if (IsA<HTMLHtmlElement>(GetNode()))
+ return true;
+
if (!layout_object_) {
if (ignored_reasons)
ignored_reasons->push_back(IgnoredReason(kAXNotRendered));
@@ -698,7 +706,7 @@ bool AXLayoutObject::ComputeAccessibilityIsIgnored(
if (alt_text)
return alt_text->IsEmpty();
- if (IsWebArea() || layout_object_->IsListMarkerIncludingNGInside())
+ if (IsWebArea() || layout_object_->IsListMarkerIncludingNGOutsideAndInside())
return false;
// Positioned elements and scrollable containers are important for
@@ -720,7 +728,7 @@ bool AXLayoutObject::ComputeAccessibilityIsIgnored(
// are usually dummy layout objects that pad out the tree, but there are
// some exceptions below.
auto* block_flow = DynamicTo<LayoutBlockFlow>(*layout_object_);
- if (block_flow && block_flow->ChildrenInline() && !CanSetFocusAttribute()) {
+ if (block_flow && block_flow->ChildrenInline()) {
// If the layout object has any plain text in it, that text will be
// inside a LineBox, so the layout object will have a first LineBox.
bool has_any_text = HasLineBox(*block_flow);
@@ -733,6 +741,7 @@ bool AXLayoutObject::ComputeAccessibilityIsIgnored(
ignored_reasons->push_back(IgnoredReason(kAXUninteresting));
return true;
}
+
// By default, objects should be ignored so that the AX hierarchy is not
// filled with unnecessary items.
if (ignored_reasons)
@@ -961,14 +970,14 @@ String AXLayoutObject::ImageDataUrl(const IntSize& max_size) const {
ImageBitmap* image_bitmap = nullptr;
Document* document = &node->GetDocument();
if (auto* image = DynamicTo<HTMLImageElement>(node)) {
- image_bitmap = ImageBitmap::Create(image, base::Optional<IntRect>(),
- document, options);
+ image_bitmap = MakeGarbageCollected<ImageBitmap>(
+ image, base::Optional<IntRect>(), document, options);
} else if (auto* canvas = DynamicTo<HTMLCanvasElement>(node)) {
- image_bitmap =
- ImageBitmap::Create(canvas, base::Optional<IntRect>(), options);
+ image_bitmap = MakeGarbageCollected<ImageBitmap>(
+ canvas, base::Optional<IntRect>(), options);
} else if (auto* video = DynamicTo<HTMLVideoElement>(node)) {
- image_bitmap = ImageBitmap::Create(video, base::Optional<IntRect>(),
- document, options);
+ image_bitmap = MakeGarbageCollected<ImageBitmap>(
+ video, base::Optional<IntRect>(), document, options);
}
if (!image_bitmap)
return String();
@@ -1222,25 +1231,6 @@ AXLayoutObject::TextDecorationStyleToAXTextDecorationStyle(
return ax::mojom::TextDecorationStyle::kNone;
}
-//
-// Inline text boxes.
-//
-
-void AXLayoutObject::LoadInlineTextBoxes() {
- if (!GetLayoutObject())
- return;
-
- if (GetLayoutObject()->IsText()) {
- ClearChildren();
- AddInlineTextBoxChildren(true);
- return;
- }
-
- for (const auto& child : children_) {
- child->LoadInlineTextBoxes();
- }
-}
-
static bool ShouldUseLayoutNG(const LayoutObject& layout_object) {
return (layout_object.IsInline() || layout_object.IsLayoutInline() ||
layout_object.IsText()) &&
@@ -1256,7 +1246,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.IsListMarkerIncludingNG() ||
+ if (layout_object.IsListMarkerIncludingNGOutside() ||
!layout_object.IsInLayoutNGInlineFormattingContext())
return nullptr;
NGInlineCursor cursor;
@@ -1280,15 +1270,24 @@ static AXObject* NextOnLineInternalNG(const AXObject& ax_object) {
}
AXObject* AXLayoutObject::NextOnLine() const {
- if (!GetLayoutObject())
+ // If this is the last object on the line, nullptr is returned. Otherwise, all
+ // AXLayoutObjects, regardless of role and tree depth, are connected to the
+ // next inline text box on the same line. If there is no inline text box, they
+ // are connected to the next leaf AXObject.
+ if (IsDetached())
return nullptr;
AXObject* result = nullptr;
- if (GetLayoutObject()->IsListMarkerIncludingNG()) {
- AXObject* next_sibling = RawNextSibling();
- if (!next_sibling || !next_sibling->Children().size())
- return nullptr;
- result = next_sibling->Children()[0].Get();
+ if (GetLayoutObject()->IsListMarkerIncludingNGOutside()) {
+ // 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.
+ //
+ // For example, <li><button aria-label="button"></button></li>.
+ //
+ // This AXLayoutObject might not be included in the accessibility tree at
+ // all, so "RawNextSibling" needs to be used to walk the layout tree.
+ result = RawNextSibling();
} else if (ShouldUseLayoutNG(*GetLayoutObject())) {
result = NextOnLineInternalNG(*this);
} else {
@@ -1296,7 +1295,12 @@ AXObject* AXLayoutObject::NextOnLine() const {
if (GetLayoutObject()->IsBox()) {
inline_box = ToLayoutBox(GetLayoutObject())->InlineBoxWrapper();
} else if (GetLayoutObject()->IsLayoutInline()) {
- inline_box = ToLayoutInline(GetLayoutObject())->LastLineBox();
+ // For performance and memory consumption, LayoutInline may ignore some
+ // inline-boxes during line layout because they don't actually impact
+ // layout. This is known as "culled inline". We have to recursively look
+ // to the LayoutInline's children via "LastLineBoxIncludingCulling".
+ inline_box =
+ ToLayoutInline(GetLayoutObject())->LastLineBoxIncludingCulling();
} else if (GetLayoutObject()->IsText()) {
inline_box = ToLayoutText(GetLayoutObject())->LastTextBox();
}
@@ -1314,17 +1318,40 @@ AXObject* AXLayoutObject::NextOnLine() const {
}
if (!result) {
- AXObject* computed_parent = ComputeParent();
- if (computed_parent)
- result = computed_parent->NextOnLine();
+ AXObject* parent = ParentObject();
+ // Our parent object could have been created based on an ignored inline or
+ // inline block spanning multiple lines. We need to ensure that we are
+ // really at the end of our parent before attempting to connect to the
+ // next AXObject that is on the same line as its last line.
+ //
+ // For example, look at the following layout tree:
+ // LayoutBlockFlow
+ // ++LayoutInline
+ // ++++LayoutText "Beginning of line one "
+ // ++++AnonymousLayoutInline
+ // ++++++LayoutText "end of line one"
+ // ++++++LayoutBR
+ // ++++++LayoutText "Beginning of line two "
+ // ++++LayoutText "End of line two"
+ //
+ // If we are on kStaticText "End of line one", and retrieve the parent
+ // AXObject, it will be the anonymous layout inline which actually ends
+ // somewhere in the second line, not the first line. Its "NextOnLine"
+ // AXObject will be kStaticText "End of line two", which is obviously
+ // wrong.
+ //
+ // Note that we can't use AXObject::IndexInParent() to do this, because
+ // for performance reasons we don't define it on objects that are not
+ // included in the accessibility tree at all.
+ if (parent && !RawNextSibling())
+ result = parent->NextOnLine();
}
}
// For consistency between the forward and backward directions, try to always
// return leaf nodes.
- while (result && result->Children().size())
- result = result->Children()[0].Get();
-
+ if (result && result->ChildCount())
+ return result->DeepestFirstChild();
return result;
}
@@ -1337,9 +1364,10 @@ 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.IsListMarkerIncludingNG() ||
- !layout_object.IsInLayoutNGInlineFormattingContext())
+ if (layout_object.IsListMarkerIncludingNGOutside() ||
+ !layout_object.IsInLayoutNGInlineFormattingContext()) {
return nullptr;
+ }
NGInlineCursor cursor;
cursor.MoveTo(layout_object);
if (!cursor)
@@ -1350,8 +1378,9 @@ static AXObject* PreviousOnLineInlineNG(const AXObject& ax_object) {
break;
LayoutObject* earlier_layout_object = cursor.CurrentMutableLayoutObject();
if (AXObject* result =
- ax_object.AXObjectCache().GetOrCreate(earlier_layout_object))
+ ax_object.AXObjectCache().GetOrCreate(earlier_layout_object)) {
return result;
+ }
}
if (!ax_object.ParentObject())
return nullptr;
@@ -1361,7 +1390,11 @@ static AXObject* PreviousOnLineInlineNG(const AXObject& ax_object) {
}
AXObject* AXLayoutObject::PreviousOnLine() const {
- if (!GetLayoutObject())
+ // If this is the first object on the line, nullptr is returned. Otherwise,
+ // all AXLayoutObjects, regardless of role and tree depth, are connected to
+ // the previous inline text box on the same line. If there is no inline text
+ // box, they are connected to the previous leaf AXObject.
+ if (IsDetached())
return nullptr;
AXObject* result = nullptr;
@@ -1369,10 +1402,9 @@ AXObject* AXLayoutObject::PreviousOnLine() const {
? PreviousSiblingIncludingIgnored()
: nullptr;
if (previous_sibling && previous_sibling->GetLayoutObject() &&
- previous_sibling->GetLayoutObject()->IsLayoutNGListMarker()) {
- if (!previous_sibling->Children().size())
- return nullptr;
- result = previous_sibling->LastChild();
+ previous_sibling->GetLayoutObject()->IsLayoutNGOutsideListMarker()) {
+ // A list item should be proceeded by a list marker on the same line.
+ result = previous_sibling;
} else if (ShouldUseLayoutNG(*GetLayoutObject())) {
result = PreviousOnLineInlineNG(*this);
} else {
@@ -1380,7 +1412,12 @@ AXObject* AXLayoutObject::PreviousOnLine() const {
if (GetLayoutObject()->IsBox()) {
inline_box = ToLayoutBox(GetLayoutObject())->InlineBoxWrapper();
} else if (GetLayoutObject()->IsLayoutInline()) {
- inline_box = ToLayoutInline(GetLayoutObject())->FirstLineBox();
+ // For performance and memory consumption, LayoutInline may ignore some
+ // inline-boxes during line layout because they don't actually impact
+ // layout. This is known as "culled inline". We have to recursively look
+ // to the LayoutInline's children via "FirstLineBoxIncludingCulling".
+ inline_box =
+ ToLayoutInline(GetLayoutObject())->FirstLineBoxIncludingCulling();
} else if (GetLayoutObject()->IsText()) {
inline_box = ToLayoutText(GetLayoutObject())->FirstTextBox();
}
@@ -1398,17 +1435,38 @@ AXObject* AXLayoutObject::PreviousOnLine() const {
}
if (!result) {
- AXObject* computed_parent = ComputeParent();
- if (computed_parent)
- result = computed_parent->PreviousOnLine();
+ AXObject* parent = ParentObject();
+ // Our parent object could have been created based on an ignored inline or
+ // inline block spanning multiple lines. We need to ensure that we are
+ // really at the start of our parent before attempting to connect to the
+ // previous AXObject that is on the same line as its first line.
+ //
+ // For example, fook at the following layout tree:
+ // LayoutBlockFlow
+ // ++LayoutInline
+ // ++++LayoutText "Beginning of line one "
+ // ++++AnonymousLayoutInline
+ // ++++++LayoutText "end of line one"
+ // ++++++LayoutBR
+ // ++++++LayoutText "Line two"
+ //
+ // If we are on kStaticText "Line two", and retrieve the parent AXObject,
+ // it will be the anonymous layout inline which actually started somewhere
+ // in the first line, not the second line. Its "PreviousOnLine" AXObject
+ // will be kStaticText "Start of line one", which is obviously wrong.
+ //
+ // Note that we can't use AXObject::IndexInParent() to do this, because
+ // for performance reasons we don't define it on objects that are not
+ // included in the accessibility tree at all.
+ if (parent && parent->RawFirstChild() == this)
+ result = parent->PreviousOnLine();
}
}
// For consistency between the forward and backward directions, try to always
// return leaf nodes.
- while (result && result->Children().size())
- result = result->Children()[result->Children().size() - 1].Get();
-
+ if (result && result->ChildCount())
+ return result->DeepestLastChild();
return result;
}
@@ -1422,11 +1480,12 @@ String AXLayoutObject::StringValue() const {
LayoutBoxModelObject* css_box = GetLayoutBoxModelObject();
- if (css_box && css_box->IsMenuList()) {
+ auto* select_element =
+ DynamicTo<HTMLSelectElement>(layout_object_->GetNode());
+ if (css_box && select_element && select_element->UsesMenuList()) {
// LayoutMenuList will go straight to the text() of its selected item.
// This has to be overridden in the case where the selected item has an ARIA
// label.
- auto* select_element = To<HTMLSelectElement>(layout_object_->GetNode());
int selected_index = select_element->SelectedListIndex();
const HeapVector<Member<HTMLElement>>& list_items =
select_element->GetListItems();
@@ -1438,7 +1497,7 @@ String AXLayoutObject::StringValue() const {
if (!overridden_description.IsNull())
return overridden_description;
}
- return ToLayoutMenuList(layout_object_)->GetText();
+ return select_element->InnerElement().innerText();
}
if (IsWebArea()) {
@@ -1462,6 +1521,8 @@ String AXLayoutObject::StringValue() const {
// buttons which will return their name.
// https://html.spec.whatwg.org/C/#dom-input-value
if (const auto* input = DynamicTo<HTMLInputElement>(GetNode())) {
+ if (input->type() == input_type_names::kFile)
+ return input->FileStatusText();
if (input->type() != input_type_names::kButton &&
input->type() != input_type_names::kCheckbox &&
input->type() != input_type_names::kImage &&
@@ -1524,10 +1585,11 @@ String AXLayoutObject::TextAlternative(bool recursive,
} else if (layout_object_->IsListMarker() && !recursive) {
text_alternative = ToLayoutListMarker(layout_object_)->TextAlternative();
found_text_alternative = true;
- } else if (layout_object_->IsLayoutNGListMarkerIncludingInside() &&
- !recursive) {
- text_alternative = LayoutNGListItem::TextAlternative(*layout_object_);
- found_text_alternative = true;
+ } else if (!recursive) {
+ if (ListMarker* marker = ListMarker::Get(layout_object_)) {
+ text_alternative = marker->TextAlternative(*layout_object_);
+ found_text_alternative = true;
+ }
}
if (found_text_alternative) {
@@ -1639,10 +1701,6 @@ ax::mojom::Dropeffect AXLayoutObject::ParseDropeffect(
return ax::mojom::Dropeffect::kNone;
}
-bool AXLayoutObject::SupportsARIAFlowTo() const {
- return !GetAttribute(html_names::kAriaFlowtoAttr).IsEmpty();
-}
-
bool AXLayoutObject::SupportsARIAOwns() const {
if (!layout_object_)
return false;
@@ -1706,7 +1764,8 @@ AXObject* AXLayoutObject::AccessibilityHitTest(const IntPoint& point) const {
return nullptr;
auto* frame_view = DocumentFrameView();
- if (!frame_view || !frame_view->UpdateAllLifecyclePhasesExceptPaint())
+ if (!frame_view || !frame_view->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kAccessibility))
return nullptr;
PaintLayer* layer = ToLayoutBox(layout_object_)->Layer();
@@ -1732,6 +1791,13 @@ AXObject* AXLayoutObject::AccessibilityHitTest(const IntPoint& point) const {
}
LayoutObject* obj = node->GetLayoutObject();
+
+ // Retarget to respect https://dom.spec.whatwg.org/#retarget.
+ if (auto* elem = DynamicTo<Element>(node)) {
+ Element* element = &(GetDocument()->Retarget(*elem));
+ obj = element->GetLayoutObject();
+ }
+
if (!obj)
return nullptr;
@@ -1744,9 +1810,9 @@ AXObject* AXLayoutObject::AccessibilityHitTest(const IntPoint& point) const {
if (result && result->AccessibilityIsIgnored()) {
// If this element is the label of a control, a hit test should return the
// control.
- if (result->IsAXLayoutObject()) {
+ if (auto* ax_object = DynamicTo<AXLayoutObject>(result)) {
AXObject* control_object =
- ToAXLayoutObject(result)->CorrespondingControlForLabelElement();
+ ax_object->CorrespondingControlAXObjectForLabelElement();
if (control_object && control_object->NameFromLabelElement())
return control_object;
}
@@ -2064,59 +2130,6 @@ AXObject* AXLayoutObject::ComputeParentIfExists() const {
return nullptr;
}
-void AXLayoutObject::AddChildren() {
- if (IsDetached())
- return;
-
- // Avoid calling AXNodeObject logic for continuations.
- bool is_continuation = layout_object_->IsElementContinuation();
-
- if (auto* element = DynamicTo<Element>(GetNode())) {
- if (!is_continuation &&
- !IsA<HTMLMapElement>(
- *element) && // Handled in AddImageMapChildren (img)
- !IsA<HTMLRubyElement>(*element) && // Special layout handling
- !IsA<HTMLTableElement>(*element) && // thead/tfoot move around
- !element->IsPseudoElement()) { // Not visited in layout traversal
- AXNodeObject::AddChildren();
- return;
- }
- }
-
- // If the need to add more children in addition to existing children arises,
- // childrenChanged should have been called, leaving the object with no
- // children.
- DCHECK(!have_children_);
- have_children_ = true;
-
- AXObjectVector owned_children;
- ComputeAriaOwnsChildren(owned_children);
-
- for (AXObject* obj = RawFirstChild(); obj; obj = obj->RawNextSibling()) {
- if (!AXObjectCache().IsAriaOwned(obj))
- AddChild(obj);
- }
-
- AddHiddenChildren();
- AddPopupChildren();
- AddRemoteSVGChildren();
- AddTableChildren();
- AddInlineTextBoxChildren(false);
- AddValidationMessageChild();
- AddAccessibleNodeChildren();
-
- for (const auto& child : children_) {
- if (!is_continuation && !child->CachedParentObject()) {
- // Never set continuations as a parent object. The first layout object
- // in the chain must be used instead.
- child->SetParent(this);
- }
- }
-
- for (const auto& owned_child : owned_children)
- AddChild(owned_child);
-}
-
bool AXLayoutObject::CanHaveChildren() const {
if (!layout_object_)
return false;
@@ -2367,44 +2380,6 @@ void AXLayoutObject::TextChanged() {
AXNodeObject::TextChanged();
}
-void AXLayoutObject::AddInlineTextBoxChildren(bool force) {
- Document* document = GetDocument();
- if (!document)
- return;
-
- Settings* settings = document->GetSettings();
- if (!force &&
- (!settings || !settings->GetInlineTextBoxAccessibilityEnabled()))
- return;
-
- if (!GetLayoutObject() || !GetLayoutObject()->IsText())
- return;
-
- if (GetLayoutObject()->NeedsLayout()) {
- // If a LayoutText needs layout, its inline text boxes are either
- // nonexistent or invalid, so defer until the layout happens and
- // the layoutObject calls AXObjectCacheImpl::inlineTextBoxesUpdated.
- return;
- }
-
- LayoutText* layout_text = ToLayoutText(GetLayoutObject());
- for (scoped_refptr<AbstractInlineTextBox> box =
- layout_text->FirstAbstractInlineTextBox();
- box.get(); box = box->NextInlineTextBox()) {
- AXObject* ax_object = AXObjectCache().GetOrCreate(box.get());
- if (ax_object->AccessibilityIsIncludedInTree())
- children_.push_back(ax_object);
- }
-}
-
-void AXLayoutObject::AddValidationMessageChild() {
- if (!IsWebArea())
- return;
- AXObject* ax_object = AXObjectCache().ValidationMessageObjectIfInvalid();
- if (ax_object)
- children_.push_back(ax_object);
-}
-
AXObject* AXLayoutObject::ErrorMessage() const {
// Check for aria-errormessage.
Element* existing_error_message =
@@ -2433,27 +2408,17 @@ bool AXLayoutObject::IsDataTable() const {
if (HasAOMPropertyOrARIAAttribute(AOMStringProperty::kRole, role))
return true;
- if (!layout_object_->IsTable())
- return false;
-
// When a section of the document is contentEditable, all tables should be
// treated as data tables, otherwise users may not be able to work with rich
// text editors that allow creating and editing tables.
if (GetNode() && HasEditableStyle(*GetNode()))
return true;
- // If there's no node, it's definitely a layout table. This happens
- // when table CSS styles are used without a complete table DOM structure.
- LayoutNGTableInterface* table =
- ToInterface<LayoutNGTableInterface>(layout_object_);
- table->RecalcSectionsIfNeeded();
- Node* table_node = layout_object_->GetNode();
-
// This employs a heuristic to determine if this table should appear.
// Only "data" tables should be exposed as tables.
// Unfortunately, there is no good way to determine the difference
// between a "layout" table and a "data" table.
- auto* table_element = DynamicTo<HTMLTableElement>(table_node);
+ auto* table_element = DynamicTo<HTMLTableElement>(GetNode());
if (!table_element)
return false;
@@ -2471,30 +2436,29 @@ bool AXLayoutObject::IsDataTable() const {
if (Traversal<HTMLTableColElement>::FirstChild(*table_element))
return true;
- // go through the cell's and check for tell-tale signs of "data" table status
- // cells have borders, or use attributes like headers, abbr, scope or axis
- table->RecalcSectionsIfNeeded();
- LayoutNGTableSectionInterface* first_body = table->FirstBodyInterface();
- if (!first_body)
+ // If there are at least 20 rows, we'll call it a data table.
+ HTMLTableRowsCollection* rows = table_element->rows();
+ int num_rows = rows->length();
+ if (num_rows >= 20)
+ return true;
+ if (num_rows <= 0)
return false;
- int num_cols_in_first_body = first_body->NumEffectiveColumns();
- int num_rows = first_body->NumRows();
+ int num_cols_in_first_body = rows->Item(0)->cells()->length();
// If there's only one cell, it's not a good AXTable candidate.
if (num_rows == 1 && num_cols_in_first_body == 1)
return false;
- // If there are at least 20 rows, we'll call it a data table.
- if (num_rows >= 20)
- return true;
-
// Store the background color of the table to check against cell's background
// colors.
- const ComputedStyle* table_style = table->ToLayoutObject()->Style();
+ const ComputedStyle* table_style = layout_object_->Style();
if (!table_style)
return false;
+
Color table_bg_color =
table_style->VisitedDependentColor(GetCSSPropertyBackgroundColor());
+ bool has_cell_spacing = table_style->HorizontalBorderSpacing() &&
+ table_style->VerticalBorderSpacing();
// check enough of the cells to find if the table matches our criteria
// Criteria:
@@ -2513,38 +2477,37 @@ bool AXLayoutObject::IsDataTable() const {
Color alternating_row_colors[5];
int alternating_row_color_count = 0;
for (int row = 0; row < num_rows; ++row) {
- int n_cols = first_body->NumCols(row);
+ HTMLTableRowElement* row_element = rows->Item(row);
+ int n_cols = row_element->cells()->length();
for (int col = 0; col < n_cols; ++col) {
- const LayoutNGTableCellInterface* cell =
- first_body->PrimaryCellInterfaceAt(row, col);
+ const Element* cell = row_element->cells()->item(col);
if (!cell)
continue;
- const LayoutBlock* cell_layout_block =
- To<LayoutBlock>(cell->ToLayoutObject());
- Node* cell_node = cell_layout_block->GetNode();
- if (!cell_node)
+ // Any <th> tag -> treat as data table.
+ if (cell->HasTagName(html_names::kThTag))
+ return true;
+
+ // Check for an explicitly assigned a "data" table attribute.
+ auto* cell_elem = DynamicTo<HTMLTableCellElement>(*cell);
+ if (cell_elem) {
+ if (!cell_elem->Headers().IsEmpty() || !cell_elem->Abbr().IsEmpty() ||
+ !cell_elem->Axis().IsEmpty() ||
+ !cell_elem->FastGetAttribute(html_names::kScopeAttr).IsEmpty())
+ return true;
+ }
+
+ LayoutObject* cell_layout_object = cell->GetLayoutObject();
+ if (!cell_layout_object || !cell_layout_object->IsLayoutBlock())
continue;
+ const LayoutBlock* cell_layout_block =
+ To<LayoutBlock>(cell_layout_object);
if (cell_layout_block->Size().Width() < 1 ||
cell_layout_block->Size().Height() < 1)
continue;
valid_cell_count++;
- // Any <th> tag -> treat as data table.
- if (cell_node->HasTagName(html_names::kThTag))
- return true;
-
- // In this case, the developer explicitly assigned a "data" table
- // attribute.
- if (IsHTMLTableCellElement(*cell_node)) {
- HTMLTableCellElement& cell_element = ToHTMLTableCellElement(*cell_node);
- if (!cell_element.Headers().IsEmpty() ||
- !cell_element.Abbr().IsEmpty() || !cell_element.Axis().IsEmpty() ||
- !cell_element.FastGetAttribute(html_names::kScopeAttr).IsEmpty())
- return true;
- }
-
const ComputedStyle* computed_style = cell_layout_block->Style();
if (!computed_style)
continue;
@@ -2576,8 +2539,8 @@ bool AXLayoutObject::IsDataTable() const {
// the place of borders).
Color cell_color = computed_style->VisitedDependentColor(
GetCSSPropertyBackgroundColor());
- if (table->HBorderSpacing() > 0 && table->VBorderSpacing() > 0 &&
- table_bg_color != cell_color && cell_color.Alpha() != 1)
+ if (has_cell_spacing && table_bg_color != cell_color &&
+ cell_color.Alpha() != 1)
background_difference_cell_count++;
// If we've found 10 "good" cells, we don't need to keep searching.
@@ -2961,22 +2924,11 @@ AXObject* AXLayoutObject::AccessibilityImageMapHitTest(
return nullptr;
}
-bool AXLayoutObject::IsSVGImage() const {
- return RemoteSVGRootElement();
-}
-
void AXLayoutObject::DetachRemoteSVGRoot() {
if (AXSVGRoot* root = RemoteSVGRootElement())
root->SetParent(nullptr);
}
-AXSVGRoot* AXLayoutObject::RemoteSVGRootElement() const {
- // FIXME(dmazzoni): none of this code properly handled multiple references to
- // the same remote SVG document. I'm disabling this support until it can be
- // fixed properly.
- return nullptr;
-}
-
AXObject* AXLayoutObject::RemoteSVGElementHitTest(const IntPoint& point) const {
AXObject* remote = RemoteSVGRootElement();
if (!remote)
@@ -3002,145 +2954,4 @@ void AXLayoutObject::OffsetBoundingBoxForRemoteSVGElement(
}
}
-// Hidden children are those that are not laid out or visible, but are
-// specifically marked as aria-hidden=false,
-// meaning that they should be exposed to the AX hierarchy.
-void AXLayoutObject::AddHiddenChildren() {
- Node* node = this->GetNode();
- if (!node)
- return;
-
- // First do a quick run through to determine if we have any hidden nodes (most
- // often we will not). If we do have hidden nodes, we need to determine where
- // to insert them so they match DOM order as close as possible.
- bool should_insert_hidden_nodes = false;
- for (Node& child : NodeTraversal::ChildrenOf(*node)) {
- if (!child.GetLayoutObject() && IsNodeAriaVisible(&child)) {
- should_insert_hidden_nodes = true;
- break;
- }
- }
-
- if (!should_insert_hidden_nodes)
- return;
-
- // Iterate through all of the children, including those that may have already
- // been added, and try to insert hidden nodes in the correct place in the DOM
- // order.
- unsigned insertion_index = 0;
- for (Node& child : NodeTraversal::ChildrenOf(*node)) {
- if (child.GetLayoutObject()) {
- // Find out where the last layout sibling is located within m_children.
- if (AXObject* child_object =
- AXObjectCache().Get(child.GetLayoutObject())) {
- if (!child_object->AccessibilityIsIncludedInTree()) {
- const auto& children = child_object->Children();
- child_object = children.size() ? children.back().Get() : nullptr;
- }
- if (child_object)
- insertion_index = children_.Find(child_object) + 1;
- continue;
- }
- }
-
- if (!IsNodeAriaVisible(&child))
- continue;
-
- unsigned previous_size = children_.size();
- if (insertion_index > previous_size)
- insertion_index = previous_size;
-
- InsertChild(AXObjectCache().GetOrCreate(&child), insertion_index);
- insertion_index += (children_.size() - previous_size);
- }
-}
-
-void AXLayoutObject::AddImageMapChildren() {
- LayoutBoxModelObject* css_box = GetLayoutBoxModelObject();
- if (!css_box || !css_box->IsLayoutImage())
- return;
-
- HTMLMapElement* map = ToLayoutImage(css_box)->ImageMap();
- if (!map)
- return;
-
- for (HTMLAreaElement& area :
- Traversal<HTMLAreaElement>::DescendantsOf(*map)) {
- // add an <area> element for this child if it has a link
- AXObject* obj = AXObjectCache().GetOrCreate(&area);
- if (obj) {
- AXImageMapLink* area_object = ToAXImageMapLink(obj);
- area_object->SetParent(this);
- DCHECK_NE(area_object->AXObjectID(), 0U);
- if (area_object->AccessibilityIsIncludedInTree())
- children_.push_back(area_object);
- else
- AXObjectCache().Remove(area_object->AXObjectID());
- }
- }
-}
-
-void AXLayoutObject::AddListMarker() {
- if (!CanHaveChildren() || !GetLayoutObject() || AccessibilityIsIgnored() ||
- !GetLayoutObject()->IsListItemIncludingNG()) {
- return;
- }
- if (GetLayoutObject()->IsLayoutNGListItem()) {
- LayoutNGListItem* list_item = ToLayoutNGListItem(GetLayoutObject());
- LayoutObject* list_marker = list_item->Marker();
- AXObject* list_marker_obj = AXObjectCache().GetOrCreate(list_marker);
- if (list_marker_obj)
- children_.push_back(list_marker_obj);
- return;
- }
- LayoutListItem* list_item = ToLayoutListItem(GetLayoutObject());
- LayoutObject* list_marker = list_item->Marker();
- AXObject* list_marker_obj = AXObjectCache().GetOrCreate(list_marker);
- if (list_marker_obj)
- children_.push_back(list_marker_obj);
-}
-
-void AXLayoutObject::AddPopupChildren() {
- auto* html_input_element = DynamicTo<HTMLInputElement>(GetNode());
- if (!html_input_element)
- return;
- if (AXObject* ax_popup = html_input_element->PopupRootAXObject())
- children_.push_back(ax_popup);
-}
-
-void AXLayoutObject::AddRemoteSVGChildren() {
- AXSVGRoot* root = RemoteSVGRootElement();
- if (!root)
- return;
-
- root->SetParent(this);
-
- if (!root->AccessibilityIsIncludedInTree()) {
- for (const auto& child : root->Children())
- children_.push_back(child);
- } else {
- children_.push_back(root);
- }
-}
-
-void AXLayoutObject::AddTableChildren() {
- if (!IsTableLikeRole())
- return;
-
- AXObjectCacheImpl& ax_cache = AXObjectCache();
- if (layout_object_->IsTable()) {
- LayoutNGTableInterface* table =
- ToInterface<LayoutNGTableInterface>(layout_object_);
- table->RecalcSectionsIfNeeded();
- Node* table_node = table->ToLayoutObject()->GetNode();
- if (auto* html_table_element = DynamicTo<HTMLTableElement>(table_node)) {
- if (HTMLTableCaptionElement* caption = html_table_element->caption()) {
- AXObject* caption_object = ax_cache.GetOrCreate(caption);
- if (caption_object && caption_object->AccessibilityIsIncludedInTree())
- children_.push_front(caption_object);
- }
- }
- }
-}
-
} // namespace blink
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 4021c56a7fa..93ee3aa680c 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
@@ -37,7 +37,6 @@
namespace blink {
class AXObjectCacheImpl;
-class AXSVGRoot;
class Element;
class HTMLAreaElement;
class IntPoint;
@@ -51,7 +50,6 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
// Public, overridden from AXObject.
LayoutObject* GetLayoutObject() const final { return layout_object_; }
- LayoutBoxModelObject* GetLayoutBoxModelObject() const;
ScrollableArea* GetScrollableAreaIfScrollable() const final;
ax::mojom::Role DetermineAccessibilityRole() override;
ax::mojom::Role NativeRoleIgnoringAria() const override;
@@ -63,6 +61,8 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
protected:
LayoutObject* layout_object_;
+ LayoutBoxModelObject* GetLayoutBoxModelObject() const override;
+
LayoutObject* LayoutObjectForRelativeBounds() const override {
return layout_object_;
}
@@ -73,8 +73,8 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
void Init() override;
void Detach() override;
- bool IsDetached() const override { return !layout_object_; }
- bool IsAXLayoutObject() const override { return true; }
+ bool IsDetached() const override;
+ bool IsAXLayoutObject() const final;
// Check object role or purpose.
bool IsAutofillAvailable() const override;
@@ -120,7 +120,6 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
ax::mojom::TextDecorationStyle* text_underline_style) const final;
// Inline text boxes.
- void LoadInlineTextBoxes() override;
AXObject* NextOnLine() const override;
AXObject* PreviousOnLine() const override;
@@ -134,7 +133,6 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
ax::mojom::HasPopup HasPopup() const override;
bool SupportsARIADragging() const override;
void Dropeffects(Vector<ax::mojom::Dropeffect>& dropeffects) const override;
- bool SupportsARIAFlowTo() const override;
bool SupportsARIAOwns() const override;
// ARIA live-region features.
@@ -165,12 +163,6 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
// accessibility module.
AXObject* RawFirstChild() const override;
AXObject* RawNextSibling() const override;
- void AddChildren() override;
- void AddListMarker() override;
- void AddInlineTextBoxChildren(bool force) override;
- void AddImageMapChildren() override;
- void AddHiddenChildren() override;
- void AddPopupChildren() override;
bool CanHaveChildren() const override;
// Properties of the object's owning document or page.
@@ -216,14 +208,9 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
bool IsTabItemSelected() const;
AXObject* AccessibilityImageMapHitTest(HTMLAreaElement*,
const IntPoint&) const;
- bool IsSVGImage() const;
void DetachRemoteSVGRoot();
- AXSVGRoot* RemoteSVGRootElement() const;
AXObject* RemoteSVGElementHitTest(const IntPoint&) const;
void OffsetBoundingBoxForRemoteSVGElement(LayoutRect&) const;
- void AddRemoteSVGChildren();
- void AddTableChildren();
- void AddValidationMessageChild();
bool FindAllTableCellsWithRole(ax::mojom::Role, AXObjectVector&) const;
LayoutRect ComputeElementRect() const;
@@ -232,6 +219,7 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
bool HasAriaCellRole(Element*) const;
bool IsPlaceholder() const;
ax::mojom::Dropeffect ParseDropeffect(String& dropeffect) const;
+ bool SelectionShouldFollowFocus() const;
static ax::mojom::TextDecorationStyle
TextDecorationStyleToAXTextDecorationStyle(
@@ -240,7 +228,12 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject {
DISALLOW_COPY_AND_ASSIGN(AXLayoutObject);
};
-DEFINE_AX_OBJECT_TYPE_CASTS(AXLayoutObject, IsAXLayoutObject());
+template <>
+struct DowncastTraits<AXLayoutObject> {
+ static bool AllowFrom(const AXObject& object) {
+ return object.IsAXLayoutObject();
+ }
+};
} // namespace blink
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
new file mode 100644
index 00000000000..045b6a62742
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object_test.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/accessibility/ax_layout_object.h"
+
+#include "third_party/blink/renderer/modules/accessibility/testing/accessibility_test.h"
+
+namespace blink {
+
+class AXLayoutObjectTest : public test::AccessibilityTest {};
+
+TEST_F(AXLayoutObjectTest, StringValueTextTransform) {
+ SetBodyInnerHTML(
+ "<select id='t' style='text-transform:uppercase'>"
+ "<option>abc</select>");
+ const AXObject* ax_select = GetAXObjectByElementId("t");
+ ASSERT_NE(nullptr, ax_select);
+ EXPECT_TRUE(IsA<AXLayoutObject>(ax_select));
+ EXPECT_EQ("ABC", ax_select->StringValue());
+}
+
+TEST_F(AXLayoutObjectTest, StringValueTextSecurity) {
+ SetBodyInnerHTML(
+ "<select id='t' style='-webkit-text-security:disc'>"
+ "<option>abc</select>");
+ const AXObject* ax_select = GetAXObjectByElementId("t");
+ ASSERT_NE(nullptr, ax_select);
+ EXPECT_TRUE(IsA<AXLayoutObject>(ax_select));
+ // U+2022 -> \xE2\x80\xA2 in UTF-8
+ EXPECT_EQ("\xE2\x80\xA2\xE2\x80\xA2\xE2\x80\xA2",
+ ax_select->StringValue().Utf8());
+}
+
+// Test if AX takes 'Retarget' described from
+// https://dom.spec.whatwg.org/#retarget after hit-testing.
+TEST_F(AXLayoutObjectTest, AccessibilityHitTest) {
+ SetBodyInnerHTML(
+ "<style>\
+ .A{display:flex;flex:100%;margin-top:-37px;height:34px}\
+ .B{display:flex;flex:1;flex-wrap:wrap}\
+ .C{flex:100%;height:34px}\
+ </style>\
+ <div class='B'>\
+ <div class='C'></div>\
+ <input class='A' aria-label='Search' role='combobox'>\
+ </div>");
+ const AXObject* ax_root = GetAXRootObject();
+ ASSERT_NE(nullptr, ax_root);
+ const IntPoint position(8, 5);
+ AXObject* hit_test_result = ax_root->AccessibilityHitTest(position);
+ EXPECT_NE(nullptr, hit_test_result);
+ EXPECT_EQ(hit_test_result->RoleValue(),
+ ax::mojom::Role::kTextFieldWithComboBox);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box.h
index e23f9f81b13..06df5567723 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box.h
@@ -53,7 +53,10 @@ class AXListBox final : public AXLayoutObject {
DISALLOW_COPY_AND_ASSIGN(AXListBox);
};
-DEFINE_AX_OBJECT_TYPE_CASTS(AXListBox, IsAXListBox());
+template <>
+struct DowncastTraits<AXListBox> {
+ static bool AllowFrom(const AXObject& object) { return object.IsAXListBox(); }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box_option.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box_option.cc
index 7161e3ab512..3e085606814 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box_option.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box_option.cc
@@ -66,7 +66,7 @@ bool AXListBoxOption::IsParentPresentationalRole() const {
if (!parent)
return false;
- if (parent_layout_object->IsListBox() &&
+ if (IsListBox(parent_layout_object) &&
parent->HasInheritedPresentationalRole())
return true;
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 7dc749bc0a4..1f2409fe475 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
@@ -26,15 +26,17 @@
#include "third_party/blink/renderer/modules/accessibility/ax_menu_list.h"
#include "third_party/blink/renderer/core/html/forms/html_select_element.h"
-#include "third_party/blink/renderer/core/layout/layout_menu_list.h"
+#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.h"
#include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h"
namespace blink {
-AXMenuList::AXMenuList(LayoutMenuList* layout_object,
+AXMenuList::AXMenuList(LayoutObject* layout_object,
AXObjectCacheImpl& ax_object_cache)
- : AXLayoutObject(layout_object, ax_object_cache) {}
+ : AXLayoutObject(layout_object, ax_object_cache) {
+ DCHECK(IsA<HTMLSelectElement>(layout_object->GetNode()));
+}
ax::mojom::Role AXMenuList::DetermineAccessibilityRole() {
if ((aria_role_ = DetermineAriaRoleAttribute()) != ax::mojom::Role::kUnknown)
@@ -47,7 +49,7 @@ bool AXMenuList::OnNativeClickAction() {
if (!layout_object_)
return false;
- HTMLSelectElement* select = ToLayoutMenuList(layout_object_)->SelectElement();
+ HTMLSelectElement* select = To<HTMLSelectElement>(GetNode());
if (select->PopupIsVisible())
select->HidePopup();
else
@@ -77,7 +79,7 @@ void AXMenuList::AddChildren() {
if (!popup)
return;
- ToAXMockObject(popup)->SetParent(this);
+ To<AXMockObject>(popup)->SetParent(this);
if (!popup->AccessibilityIsIncludedInTree()) {
cache.Remove(popup->AXObjectID());
return;
@@ -94,7 +96,7 @@ bool AXMenuList::IsCollapsed() const {
if (!layout_object_)
return true;
- return !ToLayoutMenuList(layout_object_)->SelectElement()->PopupIsVisible();
+ return !To<HTMLSelectElement>(GetNode())->PopupIsVisible();
}
AccessibilityExpanded AXMenuList::IsExpanded() const {
@@ -112,12 +114,10 @@ void AXMenuList::DidUpdateActiveOption(int option_index) {
const auto& child_objects = Children();
if (!child_objects.IsEmpty()) {
DCHECK_EQ(child_objects.size(), 1ul);
- DCHECK(child_objects[0]->IsMenuListPopup());
+ DCHECK(IsA<AXMenuListPopup>(child_objects[0].Get()));
- if (child_objects[0]->IsMenuListPopup()) {
- if (AXMenuListPopup* popup = ToAXMenuListPopup(child_objects[0].Get()))
- popup->DidUpdateActiveOption(option_index, !suppress_notifications);
- }
+ if (auto* popup = DynamicTo<AXMenuListPopup>(child_objects[0].Get()))
+ popup->DidUpdateActiveOption(option_index, !suppress_notifications);
}
}
@@ -129,7 +129,7 @@ void AXMenuList::DidShowPopup() {
if (Children().size() != 1)
return;
- AXMenuListPopup* popup = ToAXMenuListPopup(Children()[0].Get());
+ auto* popup = To<AXMenuListPopup>(Children()[0].Get());
popup->DidShow();
}
@@ -137,7 +137,7 @@ void AXMenuList::DidHidePopup() {
if (Children().size() != 1)
return;
- AXMenuListPopup* popup = ToAXMenuListPopup(Children()[0].Get());
+ auto* popup = To<AXMenuListPopup>(Children()[0].Get());
popup->DidHide();
if (GetNode() && GetNode()->IsFocused())
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.h
index 2fe4dc2377d..6a10c075125 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.h
@@ -32,11 +32,10 @@
namespace blink {
class AXObjectCacheImpl;
-class LayoutMenuList;
class AXMenuList final : public AXLayoutObject {
public:
- AXMenuList(LayoutMenuList*, AXObjectCacheImpl&);
+ AXMenuList(LayoutObject*, AXObjectCacheImpl&);
AccessibilityExpanded IsExpanded() const final;
bool OnNativeClickAction() override;
@@ -59,7 +58,10 @@ class AXMenuList final : public AXLayoutObject {
DISALLOW_COPY_AND_ASSIGN(AXMenuList);
};
-DEFINE_AX_OBJECT_TYPE_CASTS(AXMenuList, IsMenuList());
+template <>
+struct DowncastTraits<AXMenuList> {
+ static bool AllowFrom(const AXObject& object) { return object.IsMenuList(); }
+};
} // namespace blink
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 47d04bfc266..9489ed52acf 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
@@ -36,7 +36,7 @@ namespace blink {
AXMenuListOption::AXMenuListOption(HTMLOptionElement* element,
AXObjectCacheImpl& ax_object_cache)
- : AXMockObject(ax_object_cache), element_(element) {}
+ : AXNodeObject(element, ax_object_cache), element_(element) {}
AXMenuListOption::~AXMenuListOption() {
DCHECK(!element_);
@@ -44,7 +44,7 @@ AXMenuListOption::~AXMenuListOption() {
void AXMenuListOption::Detach() {
element_ = nullptr;
- AXMockObject::Detach();
+ AXNodeObject::Detach();
}
LocalFrameView* AXMenuListOption::DocumentFrameView() const {
@@ -81,17 +81,17 @@ AXObject* AXMenuListOption::ComputeParent() const {
return nullptr;
// This happens if the <select> is not rendered. Return it and move on.
- if (!select_ax_object->IsMenuList())
+ auto* menu_list = DynamicTo<AXMenuList>(select_ax_object);
+ if (!menu_list)
return select_ax_object;
- AXMenuList* menu_list = ToAXMenuList(select_ax_object);
if (menu_list->HasChildren()) {
const auto& child_objects = menu_list->Children();
if (child_objects.IsEmpty())
return nullptr;
DCHECK_EQ(child_objects.size(), 1UL);
- DCHECK(child_objects[0]->IsMenuListPopup());
- ToAXMenuListPopup(child_objects[0].Get())->UpdateChildrenIfNecessary();
+ DCHECK(IsA<AXMenuListPopup>(child_objects[0].Get()));
+ To<AXMenuListPopup>(child_objects[0].Get())->UpdateChildrenIfNecessary();
} else {
menu_list->UpdateChildrenIfNecessary();
}
@@ -141,6 +141,22 @@ AccessibilitySelectedState AXMenuListOption::IsSelected() const {
: kSelectedStateFalse);
}
+bool AXMenuListOption::OnNativeClickAction() {
+ if (!element_)
+ return false;
+
+ // Clicking on an option within a menu list should first select that item,
+ // then toggle whether the menu list is showing.
+ element_->SetSelected(true);
+
+ // Calling OnNativeClickAction on the parent select element will toggle
+ // it open or closed.
+ if (IsA<AXMenuListPopup>(ParentObject()))
+ return ParentObject()->OnNativeClickAction();
+
+ return AXNodeObject::OnNativeClickAction();
+}
+
bool AXMenuListOption::OnNativeSetSelectedAction(bool b) {
if (!element_ || !CanSetSelectedAttribute())
return false;
@@ -165,7 +181,7 @@ void AXMenuListOption::GetRelativeBounds(AXObject** out_container,
AXObject* parent = ParentObject();
if (!parent)
return;
- DCHECK(parent->IsMenuListPopup());
+ DCHECK(IsA<AXMenuListPopup>(parent));
AXObject* grandparent = parent->ParentObject();
if (!grandparent)
@@ -218,9 +234,9 @@ HTMLSelectElement* AXMenuListOption::ParentSelectNode() const {
return nullptr;
}
-void AXMenuListOption::Trace(blink::Visitor* visitor) {
+void AXMenuListOption::Trace(Visitor* visitor) {
visitor->Trace(element_);
- AXMockObject::Trace(visitor);
+ AXNodeObject::Trace(visitor);
}
} // namespace blink
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 accd60a05ad..14f0d76bb17 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
@@ -28,13 +28,13 @@
#include "base/macros.h"
#include "third_party/blink/renderer/core/html/forms/html_option_element.h"
-#include "third_party/blink/renderer/modules/accessibility/ax_mock_object.h"
+#include "third_party/blink/renderer/modules/accessibility/ax_node_object.h"
namespace blink {
class AXObjectCacheImpl;
-class AXMenuListOption final : public AXMockObject {
+class AXMenuListOption final : public AXNodeObject {
public:
AXMenuListOption(HTMLOptionElement*, AXObjectCacheImpl&);
~AXMenuListOption() override;
@@ -43,7 +43,7 @@ class AXMenuListOption final : public AXMockObject {
int SetSize() const override;
private:
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
bool IsMenuListOption() const override { return true; }
@@ -59,6 +59,7 @@ class AXMenuListOption final : public AXMockObject {
bool IsVisible() const override;
bool IsOffScreen() const override;
AccessibilitySelectedState IsSelected() const override;
+ bool OnNativeClickAction() override;
bool OnNativeSetSelectedAction(bool) override;
void GetRelativeBounds(AXObject** out_container,
@@ -79,7 +80,12 @@ class AXMenuListOption final : public AXMockObject {
DISALLOW_COPY_AND_ASSIGN(AXMenuListOption);
};
-DEFINE_AX_OBJECT_TYPE_CASTS(AXMenuListOption, IsMenuListOption());
+template <>
+struct DowncastTraits<AXMenuListOption> {
+ static bool AllowFrom(const AXObject& object) {
+ return object.IsMenuListOption();
+ }
+};
} // namespace blink
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 47a28a72ca4..5598635a495 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
@@ -62,11 +62,12 @@ AXMenuListOption* AXMenuListPopup::MenuListOptionAXObject(
if (!IsA<HTMLOptionElement>(*element))
return nullptr;
- AXObject* object = AXObjectCache().GetOrCreate(element);
- if (!object || !object->IsMenuListOption())
+ auto* ax_object =
+ DynamicTo<AXMenuListOption>(AXObjectCache().GetOrCreate(element));
+ if (!ax_object)
return nullptr;
- return ToAXMenuListOption(object);
+ return ax_object;
}
int AXMenuListPopup::GetSelectedIndex() const {
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.h
index 5347a4c86bd..a2d74177e23 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.h
@@ -69,7 +69,12 @@ class AXMenuListPopup final : public AXMockObject {
DISALLOW_COPY_AND_ASSIGN(AXMenuListPopup);
};
-DEFINE_AX_OBJECT_TYPE_CASTS(AXMenuListPopup, IsMenuListPopup());
+template <>
+struct DowncastTraits<AXMenuListPopup> {
+ static bool AllowFrom(const AXObject& object) {
+ return object.IsMenuListPopup();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_mock_object.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_mock_object.h
index ffc9510b863..5e409c075a9 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_mock_object.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_mock_object.h
@@ -52,7 +52,12 @@ class MODULES_EXPORT AXMockObject : public AXObject {
DISALLOW_COPY_AND_ASSIGN(AXMockObject);
};
-DEFINE_AX_OBJECT_TYPE_CASTS(AXMockObject, IsMockObject());
+template <>
+struct DowncastTraits<AXMockObject> {
+ static bool AllowFrom(const AXObject& object) {
+ return object.IsMockObject();
+ }
+};
} // namespace blink
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 e200c6e85a4..1806def4726 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
@@ -45,6 +45,7 @@
#include "third_party/blink/renderer/core/editing/markers/document_marker_controller.h"
#include "third_party/blink/renderer/core/editing/position.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/html/canvas/html_canvas_element.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"
@@ -70,13 +71,25 @@
#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/parser/html_parser_idioms.h"
+#include "third_party/blink/renderer/core/html/portal/html_portal_element.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"
+#include "third_party/blink/renderer/core/layout/layout_image.h"
#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/page/focus_controller.h"
+#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/svg/svg_element.h"
+#include "third_party/blink/renderer/core/svg/svg_svg_element.h"
+#include "third_party/blink/renderer/modules/accessibility/ax_image_map_link.h"
+#include "third_party/blink/renderer/modules/accessibility/ax_inline_text_box.h"
+#include "third_party/blink/renderer/modules/accessibility/ax_layout_object.h"
#include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h"
#include "third_party/blink/renderer/modules/accessibility/ax_position.h"
#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/text/platform_locale.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -123,7 +136,8 @@ void AXNodeObject::AlterSliderOrSpinButtonValue(bool increase) {
return;
float step;
- StepValueForRange(&step);
+ if (!StepValueForRange(&step))
+ return;
value += increase ? step : -step;
@@ -145,20 +159,6 @@ AXObject* AXNodeObject::ActiveDescendant() {
return ax_descendant;
}
-bool HasAriaAttribute(Element* element) {
- if (!element)
- return false;
-
- AttributeCollection attributes = element->AttributesWithoutUpdate();
- for (const Attribute& attr : attributes) {
- // Attributes cache their uppercase names.
- if (attr.GetName().LocalNameUpper().StartsWith("ARIA-"))
- return true;
- }
-
- return false;
-}
-
AXObjectInclusion AXNodeObject::ShouldIncludeBasedOnSemantics(
IgnoredReasons* ignored_reasons) const {
// If this element is within a parent that cannot have children, it should not
@@ -192,26 +192,29 @@ AXObjectInclusion AXNodeObject::ShouldIncludeBasedOnSemantics(
if (IsTableLikeRole() || IsTableRowLikeRole() || IsTableCellLikeRole())
return kIncludeObject;
- // Ignore labels that are already referenced by a control.
- AXObject* control_object = CorrespondingControlForLabelElement();
- HTMLLabelElement* label = LabelElementContainer();
- if (control_object && control_object->IsCheckboxOrRadio() &&
- control_object->NameFromLabelElement() &&
+ // Ignore labels that are already referenced by a control but are not set to
+ // be focusable.
+ AXObject* control_ax_object = CorrespondingControlAXObjectForLabelElement();
+ if (control_ax_object && control_ax_object->IsCheckboxOrRadio() &&
+ control_ax_object->NameFromLabelElement() &&
AccessibleNode::GetPropertyOrARIAAttribute(
- label, AOMStringProperty::kRole) == g_null_atom) {
+ LabelElementContainer(), AOMStringProperty::kRole) == g_null_atom) {
+ AXObject* label_ax_object = CorrespondingLabelAXObject();
+ // If the label is set to be focusable, we should expose it.
+ if (label_ax_object && label_ax_object->CanSetFocusAttribute())
+ return kIncludeObject;
+
if (ignored_reasons) {
- if (label && label != GetNode()) {
- AXObject* label_ax_object = AXObjectCache().GetOrCreate(label);
+ if (label_ax_object && label_ax_object != this)
ignored_reasons->push_back(
IgnoredReason(kAXLabelContainer, label_ax_object));
- }
- ignored_reasons->push_back(IgnoredReason(kAXLabelFor, control_object));
+ ignored_reasons->push_back(IgnoredReason(kAXLabelFor, control_ax_object));
}
return kIgnoreObject;
}
- if (CanSetFocusAttribute() && GetNode() && !IsA<HTMLBodyElement>(GetNode()))
+ if (GetNode() && !IsA<HTMLBodyElement>(GetNode()) && CanSetFocusAttribute())
return kIncludeObject;
if (IsLink() || IsInPageLinkTarget())
@@ -303,7 +306,7 @@ AXObjectInclusion AXNodeObject::ShouldIncludeBasedOnSemantics(
// These checks are simplified in the interest of execution speed;
// for example, any element having an alt attribute will make it
// not ignored, rather than just images.
- if (HasAriaAttribute(GetElement()) || !GetAttribute(kTitleAttr).IsEmpty() ||
+ if (HasAriaAttribute() || !GetAttribute(kTitleAttr).IsEmpty() ||
has_non_empty_alt_attribute)
return kIncludeObject;
@@ -321,7 +324,7 @@ AXObjectInclusion AXNodeObject::ShouldIncludeBasedOnSemantics(
base::Optional<String> AXNodeObject::GetCSSAltText(Node* node) {
if (!node || !node->GetComputedStyle() ||
- !node->GetComputedStyle()->GetContentData()) {
+ node->GetComputedStyle()->ContentBehavesAsNormal()) {
return base::nullopt;
}
@@ -370,7 +373,8 @@ bool AXNodeObject::ComputeAccessibilityIsIgnored(
}
if (DisplayLockUtilities::NearestLockedExclusiveAncestor(*GetNode())) {
- if (DisplayLockUtilities::IsInNonActivatableLockedSubtree(*GetNode())) {
+ if (DisplayLockUtilities::ShouldIgnoreNodeDueToDisplayLock(
+ *GetNode(), DisplayLockActivationReason::kAccessibility)) {
if (ignored_reasons)
ignored_reasons->push_back(IgnoredReason(kAXNotRendered));
return true;
@@ -425,7 +429,7 @@ static bool IsRequiredOwnedElement(AXObject* parent,
if (!current_element)
return false;
- if (IsHTMLTableCellElement(*current_element))
+ if (IsA<HTMLTableCellElement>(*current_element))
return IsA<HTMLTableRowElement>(*parent_node);
if (IsA<HTMLTableRowElement>(*current_element))
return IsA<HTMLTableSectionElement>(parent_html_element);
@@ -527,7 +531,7 @@ static ax::mojom::Role DecideRoleFromSiblings(Element* cell) {
IsNonEmptyNonHeaderCell(previous_cell))
return ax::mojom::Role::kRowHeader;
- const Element* row = ToElement(cell->parentNode());
+ const auto* row = To<Element>(cell->parentNode());
if (!row || !row->HasTagName(html_names::kTrTag))
return ax::mojom::Role::kColumnHeader;
@@ -627,8 +631,12 @@ ax::mojom::Role AXNodeObject::NativeRoleIgnoringAria() const {
: ax::mojom::Role::kLink;
}
+ if (IsA<HTMLPortalElement>(*GetNode())) {
+ return ax::mojom::Role::kPortal;
+ }
+
if (IsA<HTMLAnchorElement>(*GetNode())) {
- // We assume that an anchor element is LinkRole if it has event listners
+ // 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;
@@ -658,10 +666,10 @@ ax::mojom::Role AXNodeObject::NativeRoleIgnoringAria() const {
}
if (IsA<HTMLTableRowElement>(*GetNode()))
return DetermineTableRowRole();
- if (IsHTMLTableCellElement(*GetNode()))
+ if (IsA<HTMLTableCellElement>(*GetNode()))
return DetermineTableCellRole();
if (IsA<HTMLTableSectionElement>(*GetNode()))
- return DetermineTableCellRole();
+ return DetermineTableSectionRole();
if (const auto* input = DynamicTo<HTMLInputElement>(*GetNode())) {
const AtomicString& type = input->type();
@@ -829,10 +837,9 @@ ax::mojom::Role AXNodeObject::NativeRoleIgnoringAria() const {
if (IsA<HTMLDialogElement>(*GetNode()))
return ax::mojom::Role::kDialog;
- // The HTML element should not be exposed as an element. That's what the
- // LayoutView element does.
+ // The HTML element.
if (IsA<HTMLHtmlElement>(GetNode()))
- return ax::mojom::Role::kIgnored;
+ return ax::mojom::Role::kGenericContainer;
// Treat <iframe> and <frame> the same.
if (IsA<HTMLIFrameElement>(*GetNode()) || IsA<HTMLFrameElement>(*GetNode())) {
@@ -873,8 +880,11 @@ ax::mojom::Role AXNodeObject::NativeRoleIgnoringAria() const {
if (GetNode()->nodeName() == "TIME")
return ax::mojom::Role::kTime;
- if (IsEmbeddedObject())
- return ax::mojom::Role::kEmbeddedObject;
+ if (IsA<HTMLPlugInElement>(GetNode())) {
+ if (IsA<HTMLEmbedElement>(GetNode()))
+ return ax::mojom::Role::kEmbeddedObject;
+ return ax::mojom::Role::kPluginObject;
+ }
if (IsA<HTMLHRElement>(*GetNode()))
return ax::mojom::Role::kSplitter;
@@ -1016,7 +1026,7 @@ AXObject* AXNodeObject::MenuButtonForMenuIfExists() const {
}
static Element* SiblingWithAriaRole(String role, Node* node) {
- Node* parent = node->parentNode();
+ Node* parent = LayoutTreeBuilderTraversal::Parent(*node);
if (!parent)
return nullptr;
@@ -1079,6 +1089,14 @@ void AXNodeObject::Detach() {
node_ = nullptr;
}
+bool AXNodeObject::IsDetached() const {
+ return !node_ || AXObject::IsDetached();
+}
+
+bool AXNodeObject::IsAXNodeObject() const {
+ return true;
+}
+
bool AXNodeObject::IsAnchor() const {
return !IsNativeImage() && IsLink();
}
@@ -1117,10 +1135,6 @@ bool AXNodeObject::ComputeIsEditableRoot() const {
return false;
}
-bool AXNodeObject::IsEmbeddedObject() const {
- return IsHTMLPlugInElement(GetNode());
-}
-
bool AXNodeObject::IsFieldset() const {
return IsA<HTMLFieldSetElement>(GetNode());
}
@@ -1238,10 +1252,7 @@ bool AXNodeObject::IsNativeImage() const {
if (!node)
return false;
- if (IsA<HTMLImageElement>(*node))
- return true;
-
- if (IsHTMLPlugInElement(*node))
+ if (IsA<HTMLImageElement>(*node) || IsA<HTMLPlugInElement>(*node))
return true;
if (const auto* input = DynamicTo<HTMLInputElement>(*node))
@@ -1516,23 +1527,50 @@ unsigned AXNodeObject::HierarchicalLevel() const {
return level;
}
- // Only tree item will calculate its level through the DOM currently.
- if (RoleValue() != ax::mojom::Role::kTreeItem)
- return 0;
+ // 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) {
+ int level = initial_level;
+ for (AXObject* parent = ParentObject(); parent;
+ parent = parent->ParentObject()) {
+ if (parent->RoleValue() == target_role)
+ level++;
+ }
+ return level;
+ };
- // 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)
- level++;
- else if (parent_role == ax::mojom::Role::kTree)
- break;
+ switch (RoleValue()) {
+ case ax::mojom::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);
+ // 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: {
+ // 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)
+ level++;
+ else if (parent_role == ax::mojom::Role::kTree)
+ break;
+ }
+ return level;
+ }
+ default:
+ return 0;
}
- return level;
+ return 0;
}
String AXNodeObject::AutoComplete() const {
@@ -2117,6 +2155,25 @@ ax::mojom::Role AXNodeObject::AriaRoleAttribute() const {
return aria_role_;
}
+bool AXNodeObject::HasAriaAttribute() const {
+ Element* element = GetElement();
+ if (!element)
+ return false;
+
+ // Explicit ARIA role should be considered an aria attribute.
+ if (AriaRoleAttribute() != ax::mojom::Role::kUnknown)
+ return true;
+
+ AttributeCollection attributes = element->AttributesWithoutUpdate();
+ for (const Attribute& attr : attributes) {
+ // Attributes cache their uppercase names.
+ if (attr.GetName().LocalNameUpper().StartsWith("ARIA-"))
+ return true;
+ }
+
+ return false;
+}
+
// Returns the nearest block-level LayoutBlockFlow ancestor
static LayoutBlockFlow* NonInlineBlockFlow(LayoutObject* object) {
LayoutObject* current = object;
@@ -2178,6 +2235,19 @@ String AXNodeObject::TextAlternative(bool recursive,
if (!GetNode() && !GetLayoutObject())
return String();
+ // Exclude offscreen objects inside a portal.
+ // NOTE: If an object is found to be offscreen, this also omits its children,
+ // which may not be offscreen in some cases.
+ Page* page = GetNode() ? GetNode()->GetDocument().GetPage() : nullptr;
+ if (page && page->InsidePortal()) {
+ LayoutRect bounds = GetBoundsInFrameCoordinates();
+ IntSize document_size =
+ GetNode()->GetDocument().GetLayoutView()->GetLayoutSize();
+ bool is_visible = bounds.Intersects(LayoutRect(IntPoint(), document_size));
+ if (!is_visible)
+ return String();
+ }
+
String text_alternative = AriaTextAlternative(
recursive, in_aria_labelled_by_traversal, visited, name_from,
related_objects, name_sources, &found_text_alternative);
@@ -2373,6 +2443,9 @@ String AXNodeObject::TextFromDescendants(AXObjectSet& visited,
children.push_back(owned_child);
for (AXObject* child : children) {
+ constexpr size_t kMaxDescendantsForTextAlternativeComputation = 100;
+ if (visited.size() > kMaxDescendantsForTextAlternativeComputation + 1)
+ break; // Need to add 1 because the root naming node is in the list.
// If a child is a continuation, we should ignore attributes like
// hidden and presentational. See LAYOUT TREE WALKING ALGORITHM in
// ax_layout_object.cc for more information on continuations.
@@ -2441,10 +2514,16 @@ bool AXNodeObject::NameFromLabelElement() const {
return false;
// Step 2B from: http://www.w3.org/TR/accname-aam-1.1
- HeapVector<Member<Element>> elements;
+ // Try both spellings, but prefer aria-labelledby, which is the official spec.
+ const QualifiedName& attr =
+ HasAttribute(html_names::kAriaLabeledbyAttr) &&
+ !HasAttribute(html_names::kAriaLabelledbyAttr)
+ ? html_names::kAriaLabeledbyAttr
+ : html_names::kAriaLabelledbyAttr;
+ HeapVector<Member<Element>> elements_from_attribute;
Vector<String> ids;
- AriaLabelledbyElementVector(elements, ids);
- if (ids.size() > 0)
+ ElementsFromAttribute(elements_from_attribute, attr, ids);
+ if (elements_from_attribute.size() > 0)
return false;
// Step 2C from: http://www.w3.org/TR/accname-aam-1.1
@@ -2525,7 +2604,7 @@ void AXNodeObject::GetRelativeBounds(AXObject** out_container,
// line of text, so that it's clear the object is a child of the parent.
for (AXObject* position_provider = ParentObject(); position_provider;
position_provider = position_provider->ParentObject()) {
- if (position_provider->IsAXLayoutObject()) {
+ if (IsA<AXLayoutObject>(position_provider)) {
position_provider->GetRelativeBounds(
out_container, out_bounds_in_container, out_container_transform,
clips_children);
@@ -2583,6 +2662,222 @@ AXObject* AXNodeObject::RawNextSibling() const {
return AXObjectCache().GetOrCreate(next_sibling);
}
+void AXNodeObject::AddTableChildren() {
+ if (!IsTableLikeRole() || !GetLayoutObject() || !GetLayoutObject()->IsTable())
+ return;
+
+ AXObjectCacheImpl& ax_cache = AXObjectCache();
+ LayoutNGTableInterface* table =
+ ToInterface<LayoutNGTableInterface>(GetLayoutObject());
+ if (table)
+ table->RecalcSectionsIfNeeded();
+ Node* table_node = GetNode();
+ if (auto* html_table_element = DynamicTo<HTMLTableElement>(table_node)) {
+ if (HTMLTableCaptionElement* caption = html_table_element->caption()) {
+ AXObject* caption_object = ax_cache.GetOrCreate(caption);
+ if (caption_object && caption_object->AccessibilityIsIncludedInTree())
+ children_.push_front(caption_object);
+ }
+ }
+}
+
+//
+// Inline text boxes.
+//
+
+void AXNodeObject::LoadInlineTextBoxes() {
+ if (!GetLayoutObject())
+ return;
+
+ if (GetLayoutObject()->IsText()) {
+ ClearChildren();
+ AddInlineTextBoxChildren(true);
+ return;
+ }
+
+ for (const auto& child : children_) {
+ child->LoadInlineTextBoxes();
+ }
+}
+
+void AXNodeObject::AddInlineTextBoxChildren(bool force) {
+ Document* document = GetDocument();
+ if (!document)
+ return;
+
+ Settings* settings = document->GetSettings();
+ if (!force &&
+ (!settings || !settings->GetInlineTextBoxAccessibilityEnabled()))
+ return;
+
+ if (!GetLayoutObject() || !GetLayoutObject()->IsText())
+ return;
+
+ if (GetLayoutObject()->NeedsLayout()) {
+ // If a LayoutText needs layout, its inline text boxes are either
+ // nonexistent or invalid, so defer until the layout happens and
+ // the layoutObject calls AXObjectCacheImpl::inlineTextBoxesUpdated.
+ return;
+ }
+
+ LayoutText* layout_text = ToLayoutText(GetLayoutObject());
+ for (scoped_refptr<AbstractInlineTextBox> box =
+ layout_text->FirstAbstractInlineTextBox();
+ box.get(); box = box->NextInlineTextBox()) {
+ AXObject* ax_object = AXObjectCache().GetOrCreate(box.get());
+ if (ax_object->AccessibilityIsIncludedInTree())
+ children_.push_back(ax_object);
+ }
+}
+
+void AXNodeObject::AddValidationMessageChild() {
+ if (!IsWebArea())
+ return;
+ AXObject* ax_object = AXObjectCache().ValidationMessageObjectIfInvalid();
+ if (ax_object)
+ children_.push_back(ax_object);
+}
+
+// Hidden children are those that are not laid out or visible, but are
+// specifically marked as aria-hidden=false,
+// meaning that they should be exposed to the AX hierarchy.
+void AXNodeObject::AddHiddenChildren() {
+ Node* node = this->GetNode();
+ if (!node)
+ return;
+
+ // First do a quick run through to determine if we have any hidden nodes (most
+ // often we will not). If we do have hidden nodes, we need to determine where
+ // to insert them so they match DOM order as close as possible.
+ bool should_insert_hidden_nodes = false;
+ for (Node& child : NodeTraversal::ChildrenOf(*node)) {
+ if (!child.GetLayoutObject() && IsNodeAriaVisible(&child)) {
+ should_insert_hidden_nodes = true;
+ break;
+ }
+ }
+
+ if (!should_insert_hidden_nodes)
+ return;
+
+ // Iterate through all of the children, including those that may have already
+ // been added, and try to insert hidden nodes in the correct place in the DOM
+ // order.
+ unsigned insertion_index = 0;
+ for (Node& child : NodeTraversal::ChildrenOf(*node)) {
+ if (child.GetLayoutObject()) {
+ // Find out where the last layout sibling is located within children_.
+ if (AXObject* child_object =
+ AXObjectCache().Get(child.GetLayoutObject())) {
+ if (!child_object->AccessibilityIsIncludedInTree()) {
+ const auto& children = child_object->Children();
+ child_object = children.size() ? children.back().Get() : nullptr;
+ }
+ if (child_object)
+ insertion_index = children_.Find(child_object) + 1;
+ continue;
+ }
+ }
+
+ if (!IsNodeAriaVisible(&child))
+ continue;
+
+ unsigned previous_size = children_.size();
+ if (insertion_index > previous_size)
+ insertion_index = previous_size;
+
+ InsertChild(AXObjectCache().GetOrCreate(&child), insertion_index);
+ insertion_index += (children_.size() - previous_size);
+ }
+}
+
+void AXNodeObject::AddImageMapChildren() {
+ LayoutBoxModelObject* css_box = GetLayoutBoxModelObject();
+ if (!css_box || !css_box->IsLayoutImage())
+ return;
+
+ HTMLMapElement* map = ToLayoutImage(css_box)->ImageMap();
+ if (!map)
+ return;
+
+ for (HTMLAreaElement& area :
+ Traversal<HTMLAreaElement>::DescendantsOf(*map)) {
+ // add an <area> element for this child if it has a link
+ AXObject* obj = AXObjectCache().GetOrCreate(&area);
+ if (obj) {
+ auto* area_object = To<AXImageMapLink>(obj);
+ area_object->SetParent(this);
+ DCHECK_NE(area_object->AXObjectID(), 0U);
+ if (area_object->AccessibilityIsIncludedInTree())
+ children_.push_back(area_object);
+ else
+ AXObjectCache().Remove(area_object->AXObjectID());
+ }
+ }
+}
+
+void AXNodeObject::AddPopupChildren() {
+ auto* html_input_element = DynamicTo<HTMLInputElement>(GetNode());
+ if (!html_input_element)
+ return;
+ if (AXObject* ax_popup = html_input_element->PopupRootAXObject())
+ children_.push_back(ax_popup);
+}
+
+AXSVGRoot* AXNodeObject::RemoteSVGRootElement() const {
+ // FIXME(dmazzoni): none of this code properly handled multiple references to
+ // the same remote SVG document. I'm disabling this support until it can be
+ // fixed properly.
+ return nullptr;
+}
+
+void AXNodeObject::AddRemoteSVGChildren() {
+ AXSVGRoot* root = RemoteSVGRootElement();
+ if (!root)
+ return;
+
+ root->SetParent(this);
+
+ if (!root->AccessibilityIsIncludedInTree()) {
+ for (const auto& child : root->Children())
+ children_.push_back(child);
+ } else {
+ children_.push_back(root);
+ }
+}
+
+bool AXNodeObject::ShouldUseLayoutBuilderTraversal() const {
+ // TODO(accessibility) Look into having one method of traversal, otherwise
+ // it's possible for the same object to become a child of 2 different nodes,
+ // e.g. if it has a different layout parent and DOM parent.
+
+ // Avoid calling AXNodeObject logic for continuations.
+ if (GetLayoutObject() && GetLayoutObject()->IsElementContinuation())
+ return false;
+
+ Node* node = GetNode();
+ if (!node)
+ return false;
+
+ // <ruby>: special layout handling
+ if (IsA<HTMLRubyElement>(*node))
+ return false;
+
+ // <table>: a thead/tfoot in the middle are bumped to the top/bottom in
+ // the layout representation.
+ if (IsA<HTMLTableElement>(*node))
+ return false;
+
+ // Pseudo elements often have text children that are not
+ // visited by the LayoutTreeBuilderTraversal class used in DOM traversal.
+ // Without this condition, list bullets would not have static text children.
+ Element* element = GetElement();
+ if (element && element->IsPseudoElement())
+ return false;
+
+ return true;
+}
+
void AXNodeObject::AddChildren() {
if (IsDetached())
return;
@@ -2596,27 +2891,42 @@ void AXNodeObject::AddChildren() {
AXObjectVector owned_children;
ComputeAriaOwnsChildren(owned_children);
- AddListMarker();
-
- for (Node* child = LayoutTreeBuilderTraversal::FirstChild(*node_); child;
- child = LayoutTreeBuilderTraversal::NextSibling(*child)) {
- AXObject* child_obj = AXObjectCache().GetOrCreate(child);
- if (child_obj && !AXObjectCache().IsAriaOwned(child_obj))
- AddChild(child_obj);
+ if (ShouldUseLayoutBuilderTraversal()) {
+ for (Node* child = LayoutTreeBuilderTraversal::FirstChild(*node_); child;
+ child = LayoutTreeBuilderTraversal::NextSibling(*child)) {
+ if (child->IsMarkerPseudoElement() && AccessibilityIsIgnored())
+ continue;
+ AXObject* child_obj = AXObjectCache().GetOrCreate(child);
+ if (child_obj && !AXObjectCache().IsAriaOwned(child_obj))
+ AddChild(child_obj);
+ }
+ } else {
+ for (AXObject* obj = RawFirstChild(); obj; obj = obj->RawNextSibling()) {
+ if (!AXObjectCache().IsAriaOwned(obj))
+ AddChild(obj);
+ }
}
AddHiddenChildren();
AddPopupChildren();
+ AddRemoteSVGChildren();
AddImageMapChildren();
+ AddTableChildren();
AddInlineTextBoxChildren(false);
+ AddValidationMessageChild();
AddAccessibleNodeChildren();
for (const auto& owned_child : owned_children)
AddChild(owned_child);
+ bool is_continuation =
+ GetLayoutObject() && GetLayoutObject()->IsElementContinuation();
for (const auto& child : children_) {
- if (!child->CachedParentObject())
+ if (!is_continuation && !child->CachedParentObject()) {
+ // Never set continuations as a parent object. The first layout object
+ // in the chain must be used instead.
child->SetParent(this);
+ }
}
}
@@ -2662,6 +2972,12 @@ bool AXNodeObject::CanHaveChildren() const {
if (GetNode() && IsA<HTMLMapElement>(GetNode()))
return false; // Does not have a role, so check here
+ // The AXTree of a portal should only have one node: the root document node.
+ if (GetNode() && GetNode()->IsDocumentNode() &&
+ GetNode()->GetDocument().GetPage() &&
+ GetNode()->GetDocument().GetPage()->InsidePortal())
+ return false;
+
switch (native_role_) {
case ax::mojom::Role::kCheckBox:
case ax::mojom::Role::kImage:
@@ -2777,7 +3093,7 @@ void AXNodeObject::SetNode(Node* node) {
node_ = node;
}
-AXObject* AXNodeObject::CorrespondingControlForLabelElement() const {
+AXObject* AXNodeObject::CorrespondingControlAXObjectForLabelElement() const {
HTMLLabelElement* label_element = LabelElementContainer();
if (!label_element)
return nullptr;
@@ -2795,6 +3111,14 @@ AXObject* AXNodeObject::CorrespondingControlForLabelElement() const {
return AXObjectCache().GetOrCreate(corresponding_control);
}
+AXObject* AXNodeObject::CorrespondingLabelAXObject() const {
+ HTMLLabelElement* label_element = LabelElementContainer();
+ if (!label_element)
+ return nullptr;
+
+ return AXObjectCache().GetOrCreate(label_element);
+}
+
HTMLLabelElement* AXNodeObject::LabelElementContainer() const {
if (!GetNode())
return nullptr;
@@ -2817,7 +3141,21 @@ bool AXNodeObject::OnNativeFocusAction() {
Document* document = GetDocument();
if (IsWebArea()) {
- document->ClearFocusedElement();
+ // If another Frame has focused content (e.g. nested iframe), then we
+ // need to clear focus for the other Document Frame.
+ // Here we set the focused element via the FocusController so that the
+ // other Frame loses focus, and the target Document Element gains focus.
+ // This fixes a scenario with Narrator Item Navigation when the user
+ // navigates from the outer UI to the document when the last focused
+ // element was within a nested iframe before leaving the document frame.
+ Page* page = document->GetPage();
+ // Elements inside a portal should not be focusable.
+ if (page && !page->InsidePortal()) {
+ page->GetFocusController().SetFocusedElement(document->documentElement(),
+ document->GetFrame());
+ } else {
+ document->ClearFocusedElement();
+ }
return true;
}
@@ -2842,8 +3180,7 @@ bool AXNodeObject::OnNativeFocusAction() {
// using AOM. To be extra safe, exclude objects that are clickable themselves.
// This won't prevent anyone from having a click handler on the object's
// container.
- if (!IsClickable() && element->FastHasAttribute(html_names::kIdAttr) &&
- CanBeActiveDescendant()) {
+ if (!IsClickable() && CanBeActiveDescendant()) {
return OnNativeClickAction();
}
@@ -3043,6 +3380,21 @@ void AXNodeObject::ComputeAriaOwnsChildren(
return;
}
+ // We first check if the element has an explicitly set aria-owns association.
+ // Explicitly set elements are validated on setting time (that they are in a
+ // valid scope etc). The content attribute can contain ids that are not
+ // legally ownable.
+ Element* element = GetElement();
+ if (element && element->HasExplicitlySetAttrAssociatedElements(
+ html_names::kAriaOwnsAttr)) {
+ bool is_null = false;
+ AXObjectCache().UpdateAriaOwnsFromAttrAssociatedElements(
+ this,
+ element->GetElementArrayAttribute(html_names::kAriaOwnsAttr, is_null),
+ owned_children);
+ return;
+ }
+
// Case 2: aria-owns attribute
TokenVectorFromAttribute(id_vector, html_names::kAriaOwnsAttr);
AXObjectCache().UpdateAriaOwns(this, id_vector, owned_children);
@@ -3610,14 +3962,30 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from,
// aria-describedby overrides any other accessible description, from:
// http://rawgit.com/w3c/aria/master/html-aam/html-aam.html
- const AtomicString& aria_describedby =
- GetAttribute(html_names::kAriaDescribedbyAttr);
- if (!aria_describedby.IsNull()) {
- if (description_sources)
- description_sources->back().attribute_value = aria_describedby;
-
- Vector<String> ids;
- description = TextFromAriaDescribedby(related_objects, ids);
+ Element* element = GetElement();
+ if (!element)
+ return String();
+
+ Vector<String> ids;
+ HeapVector<Member<Element>> elements_from_attribute;
+ ElementsFromAttribute(elements_from_attribute,
+ html_names::kAriaDescribedbyAttr, ids);
+ if (!elements_from_attribute.IsEmpty()) {
+ // TODO(meredithl): Determine description sources when |aria_describedby| is
+ // the empty string, in order to make devtools work with attr-associated
+ // elements.
+ if (description_sources) {
+ description_sources->back().attribute_value =
+ GetAttribute(html_names::kAriaDescribedbyAttr);
+ }
+ AXObjectSet visited;
+ description = TextFromElements(true, visited, elements_from_attribute,
+ related_objects);
+
+ for (auto& element : elements_from_attribute)
+ ids.push_back(element->GetIdAttribute());
+
+ TokenVectorFromAttribute(ids, html_names::kAriaDescribedbyAttr);
AXObjectCache().UpdateReverseRelations(this, ids);
if (!description.IsNull()) {
@@ -3679,7 +4047,7 @@ 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>(GetNode());
+ auto* table_element = DynamicTo<HTMLTableElement>(element);
if (name_from != ax::mojom::NameFrom::kCaption && table_element) {
description_from = ax::mojom::DescriptionFrom::kRelatedElement;
if (description_sources) {
@@ -3757,26 +4125,6 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from,
}
}
- // aria-help.
- // FIXME: this is not part of the official standard, but it's needed because
- // the built-in date/time controls use it.
- description_from = ax::mojom::DescriptionFrom::kAttribute;
- if (description_sources) {
- description_sources->push_back(
- DescriptionSource(found_description, html_names::kAriaHelpAttr));
- description_sources->back().type = description_from;
- }
- const AtomicString& help = GetAttribute(html_names::kAriaHelpAttr);
- if (!help.IsEmpty()) {
- description = help;
- if (description_sources) {
- found_description = true;
- description_sources->back().text = description;
- } else {
- return description;
- }
- }
-
description_from = ax::mojom::DescriptionFrom::kUninitialized;
if (found_description) {
@@ -3833,7 +4181,7 @@ String AXNodeObject::PlaceholderFromNativeAttribute() const {
return ToTextControl(node)->StrippedPlaceholder();
}
-void AXNodeObject::Trace(blink::Visitor* visitor) {
+void AXNodeObject::Trace(Visitor* visitor) {
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 132d4ff0b17..00d1ba0ce70 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
@@ -36,6 +36,7 @@
namespace blink {
class AXObjectCacheImpl;
+class AXSVGRoot;
class Element;
class HTMLLabelElement;
class Node;
@@ -44,7 +45,7 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
public:
AXNodeObject(Node*, AXObjectCacheImpl&);
~AXNodeObject() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
bool children_dirty_;
@@ -79,7 +80,8 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
Element* MouseButtonListener() const;
bool IsNativeCheckboxOrRadio() const;
void SetNode(Node*);
- AXObject* CorrespondingControlForLabelElement() const;
+ AXObject* CorrespondingControlAXObjectForLabelElement() const;
+ AXObject* CorrespondingLabelAXObject() const;
HTMLLabelElement* LabelElementContainer() const;
//
@@ -88,8 +90,8 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
void Init() override;
void Detach() override;
- bool IsDetached() const override { return !node_; }
- bool IsAXNodeObject() const final { return true; }
+ bool IsDetached() const override;
+ bool IsAXNodeObject() const final;
// Check object role or purpose.
bool IsAnchor() const final;
@@ -97,7 +99,6 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
bool IsMultiline() const override;
bool IsEditable() const override { return IsNativeTextControl(); }
bool ComputeIsEditableRoot() const override;
- bool IsEmbeddedObject() const final;
bool IsFieldset() const final;
bool IsHeading() const final;
bool IsHovered() const final;
@@ -161,6 +162,7 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
// ARIA attributes.
ax::mojom::Role AriaRoleAttribute() const final;
+ bool HasAriaAttribute() const override;
// AX name calculation.
String GetName(ax::mojom::NameFrom&,
@@ -196,11 +198,6 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
AXObject* RawFirstChild() const override;
AXObject* RawNextSibling() const override;
void AddChildren() override;
- virtual void AddListMarker() {}
- virtual void AddInlineTextBoxChildren(bool force) {}
- virtual void AddImageMapChildren() {}
- virtual void AddHiddenChildren() {}
- virtual void AddPopupChildren() {}
bool CanHaveChildren() const override;
void AddChild(AXObject*);
@@ -236,6 +233,17 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
void ComputeAriaOwnsChildren(
HeapVector<Member<AXObject>>& owned_children) const;
+ // Inline text boxes.
+ void LoadInlineTextBoxes() override;
+
+ // SVG.
+ bool IsSVGImage() const { return RemoteSVGRootElement(); }
+ AXSVGRoot* RemoteSVGRootElement() const;
+
+ virtual LayoutBoxModelObject* GetLayoutBoxModelObject() const {
+ return nullptr;
+ }
+
FRIEND_TEST_ALL_PREFIXES(AccessibilityTest, SetNeedsToUpdateChildren);
FRIEND_TEST_ALL_PREFIXES(AccessibilityTest, UpdateChildrenIfNecessary);
@@ -253,6 +261,16 @@ class MODULES_EXPORT AXNodeObject : public AXObject {
bool IsDescendantOfElementType(HashSet<QualifiedName>& tag_names) const;
String PlaceholderFromNativeAttribute() const;
+ void AddInlineTextBoxChildren(bool force);
+ void AddImageMapChildren();
+ void AddHiddenChildren();
+ void AddPopupChildren();
+ void AddRemoteSVGChildren();
+ void AddTableChildren();
+ void AddValidationMessageChild();
+ // For some nodes, only LayoutBuilderTraversal visits the necessary children.
+ bool ShouldUseLayoutBuilderTraversal() 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 5f2dadc3b7d..698a7916792 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -29,15 +29,17 @@
#include "third_party/blink/renderer/modules/accessibility/ax_object.h"
#include "third_party/blink/public/common/features.h"
-#include "third_party/blink/public/platform/web_scroll_into_view_params.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/renderer/core/aom/accessible_node.h"
#include "third_party/blink/renderer/core/aom/accessible_node_list.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
+#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
#include "third_party/blink/renderer/core/dom/element_traversal.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"
+#include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
#include "third_party/blink/renderer/core/html/custom/element_internals.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/forms/html_select_element.h"
@@ -53,6 +55,10 @@
#include "third_party/blink/renderer/core/page/chrome_client.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/scrolling/top_document_root_scroller_controller.h"
+#include "third_party/blink/renderer/modules/accessibility/ax_menu_list.h"
+#include "third_party/blink/renderer/modules/accessibility/ax_menu_list_option.h"
+#include "third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.h"
#include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h"
#include "third_party/blink/renderer/modules/accessibility/ax_range.h"
#include "third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.h"
@@ -102,7 +108,6 @@ const RoleEntry kRoles[] = {
{"columnheader", ax::mojom::Role::kColumnHeader},
{"combobox", ax::mojom::Role::kComboBoxGrouping},
{"comment", ax::mojom::Role::kComment},
- {"commentsection", ax::mojom::Role::kCommentSection},
{"complementary", ax::mojom::Role::kComplementary},
{"contentinfo", ax::mojom::Role::kContentInfo},
{"definition", ax::mojom::Role::kDefinition},
@@ -200,7 +205,6 @@ const RoleEntry kRoles[] = {
// TODO(accessibility) region should only be mapped
// if name present. See http://crbug.com/840819.
{"region", ax::mojom::Role::kRegion},
- {"revision", ax::mojom::Role::kRevision},
{"row", ax::mojom::Role::kRow},
{"rowgroup", ax::mojom::Role::kRowGroup},
{"rowheader", ax::mojom::Role::kRowHeader},
@@ -241,7 +245,6 @@ const InternalRoleEntry kInternalRoles[] = {
{ax::mojom::Role::kAlert, "Alert"},
{ax::mojom::Role::kAnchor, "Anchor"},
{ax::mojom::Role::kComment, "Comment"},
- {ax::mojom::Role::kComment, "CommentSection"},
{ax::mojom::Role::kApplication, "Application"},
{ax::mojom::Role::kArticle, "Article"},
{ax::mojom::Role::kAudio, "Audio"},
@@ -353,7 +356,6 @@ const InternalRoleEntry kInternalRoles[] = {
{ax::mojom::Role::kLabelText, "Label"},
{ax::mojom::Role::kLayoutTable, "LayoutTable"},
{ax::mojom::Role::kLayoutTableCell, "LayoutCellTable"},
- {ax::mojom::Role::kLayoutTableColumn, "LayoutColumnTable"},
{ax::mojom::Role::kLayoutTableRow, "LayoutRowTable"},
{ax::mojom::Role::kLegend, "Legend"},
{ax::mojom::Role::kLink, "Link"},
@@ -382,14 +384,16 @@ const InternalRoleEntry kInternalRoles[] = {
{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::kRevision, "Revision"},
{ax::mojom::Role::kRootWebArea, "WebArea"},
{ax::mojom::Role::kRow, "Row"},
{ax::mojom::Role::kRowGroup, "RowGroup"},
@@ -984,7 +988,7 @@ bool AXObject::AccessibilityIsIgnoredByDefault(
}
AXObjectInclusion AXObject::AccessibilityPlatformIncludesObject() const {
- if (IsMenuListPopup() || IsMenuListOption())
+ if (IsA<AXMenuListPopup>(this) || IsA<AXMenuListOption>(this))
return kIncludeObject;
return kDefaultBehavior;
@@ -1063,7 +1067,7 @@ bool AXObject::ComputeIsInertOrAriaHidden(
}
bool AXObject::IsVisible() const {
- return !IsInertOrAriaHidden() && !IsHiddenForTextAlternativeCalculation();
+ return !IsInertOrAriaHidden() && !IsHiddenViaStyle();
}
bool AXObject::IsDescendantOfLeafNode() const {
@@ -1218,6 +1222,13 @@ bool AXObject::ComputeAccessibilityIsIgnoredButIncludedInTree() const {
if (!GetNode())
return false;
+ // Use a flag to control whether or not the <html> element is included
+ // in the accessibility tree. Either way it's always marked as "ignored",
+ // but eventually we want to always include it in the tree to simplify
+ // some logic.
+ if (GetNode() && IsA<HTMLHtmlElement>(GetNode()))
+ return RuntimeEnabledFeatures::AccessibilityExposeHTMLElementEnabled();
+
// 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.
@@ -1239,7 +1250,7 @@ bool AXObject::ComputeAccessibilityIsIgnoredButIncludedInTree() const {
if (RuntimeEnabledFeatures::AccessibilityExposeDisplayNoneEnabled()) {
if (Element* element = GetElement()) {
if (element->FastHasAttribute(html_names::kIdAttr) &&
- IsHiddenForTextAlternativeCalculation()) {
+ IsHiddenViaStyle()) {
return true;
}
}
@@ -1311,20 +1322,6 @@ bool AXObject::HasInheritedPresentationalRole() const {
return cached_has_inherited_presentational_role_;
}
-bool AXObject::CanReceiveAccessibilityFocus() const {
- const Element* elem = GetElement();
- if (!elem)
- return false;
-
- // Focusable, and not forwarding the focus somewhere else
- if (elem->IsFocusable() &&
- !GetAOMPropertyOrARIAAttribute(AOMRelationProperty::kActiveDescendant))
- return true;
-
- // aria-activedescendant focus
- return elem->FastHasAttribute(html_names::kIdAttr) && CanBeActiveDescendant();
-}
-
bool AXObject::CanSetValueAttribute() const {
switch (RoleValue()) {
case ax::mojom::Role::kColorWell:
@@ -1336,7 +1333,6 @@ bool AXObject::CanSetValueAttribute() const {
case ax::mojom::Role::kSplitter:
case ax::mojom::Role::kTextField:
case ax::mojom::Role::kTextFieldWithComboBox:
- case ax::mojom::Role::kTime:
case ax::mojom::Role::kSearchBox:
return Restriction() == kRestrictionNone;
default:
@@ -1345,37 +1341,95 @@ bool AXObject::CanSetValueAttribute() const {
return false;
}
+// This does not use Element::IsFocusable(), as that can sometimes recalculate
+// styles because of IsFocusableStyle() check, resetting the document lifecycle.
bool AXObject::CanSetFocusAttribute() const {
- Node* node = GetNode();
- if (!node)
+ if (IsDetached())
+ return false;
+
+ // NOT focusable: anything inside a <portal> (the portal element itself is).
+ if (GetDocument() && GetDocument()->GetPage() &&
+ GetDocument()->GetPage()->InsidePortal()) {
return false;
+ }
+ // Focusable: web area -- this is the only focusable non-element.
if (IsWebArea())
return true;
- // Children of elements with an aria-activedescendant attribute should be
- // focusable if they have a (non-presentational) ARIA role.
- if (!IsPresentational() && AriaRoleAttribute() != ax::mojom::Role::kUnknown &&
- CanBeActiveDescendant()) {
+ // NOT focusable: objects with no DOM node, e.g. extra layout blocks inserted
+ // as filler, or objects where the node is not an element, such as a text
+ // node or an HTML comment.
+ Element* elem = GetElement();
+ if (!elem)
+ return false;
+
+ // NOT focusable: inert elements.
+ if (elem->IsInert())
+ return false;
+
+ // NOT focusable: disabled form controls.
+ if (IsDisabledFormControl(elem))
+ return false;
+
+ // Focusable: options in a combobox or listbox.
+ // Even though they are not treated as supporting focus by Blink (the parent
+ // widget is), they are considered focusable in the accessibility sense,
+ // 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)
return true;
+
+ // NOT focusable: hidden elements.
+ // This is imperfect, because the only way to really know whether something
+ // is hidden via style is to EnsureComputedStyle(). The method
+ // AXObject::IsHiddenViaStyle() does this, but it relies on
+ // EnsureComputedStyle() which could cause instability in callers.
+ // This code assumes that a canvas descendant has the same visibility as
+ // the canvas itself.
+ // TODO(aleventhal) Consider caching visibility when it's safe to compute.
+ if (!IsA<HTMLAreaElement>(elem)) {
+ if (!GetLayoutObject()) {
+ if (!elem->IsInCanvasSubtree())
+ return false;
+ const HTMLCanvasElement* canvas =
+ Traversal<HTMLCanvasElement>::FirstAncestorOrSelf(*elem);
+ if (!canvas->GetLayoutObject() ||
+ canvas->GetLayoutObject()->Style()->Visibility() !=
+ EVisibility::kVisible) {
+ return false;
+ }
+ } else if (GetLayoutObject()->Style()->Visibility() !=
+ EVisibility::kVisible) {
+ return false;
+ }
}
- // NOTE: It would be more accurate to ask the document whether
- // setFocusedNode() would do anything. For example, setFocusedNode() will do
- // nothing if the current focused node will not relinquish the focus.
- if (IsDisabledFormControl(node))
- return false;
+ // 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)
+ return true;
- // Check for options here because AXListBoxOption and AXMenuListOption
- // don't help when the <option> is canvas fallback, and because
- // a common case for aria-owns from a textbox that points to a list
- // does not change the hierarchy (textboxes don't support children)
- if (RoleValue() == ax::mojom::Role::kListBoxOption ||
- RoleValue() == ax::mojom::Role::kMenuListOption)
+ // Focusable: element supports focus.
+ if (elem->SupportsFocus())
return true;
- auto* element = DynamicTo<Element>(node);
- return element && element->SupportsFocus();
+ // TODO(accessibility) Focusable: scrollable with the keyboard.
+ // Keyboard-focusable scroll containers feature:
+ // https://www.chromestatus.com/feature/5231964663578624
+ // When adding here, remove similar check from ::NameFromContents().
+ // if (RuntimeEnabledFeatures::KeyboardFocusableScrollersEnabled() &&
+ // IsUserScrollable()) {
+ // return true;
+ // }
+
+ // Focusable: can be an active descendant.
+ if (CanBeActiveDescendant())
+ return true;
+
+ // NOT focusable: everything else.
+ return false;
}
// From ARIA 1.1.
@@ -1388,6 +1442,25 @@ bool AXObject::CanSetFocusAttribute() const {
// textbox or is a logical descendant of that controlled element as indicated by
// the aria-owns attribute.
bool AXObject::CanBeActiveDescendant() const {
+ // Require an element with an id attribute.
+ // TODO(accessibility): this code currently requires both an id and role
+ // attribute, as well as an ancestor or controlling aria-activedescendant.
+ // However, with element reflection it may be possible to set an active
+ // descendant without an id, so at some point we may need to remove the
+ // requirement for an id attribute.
+ if (!GetElement() || !GetElement()->FastHasAttribute(html_names::kIdAttr))
+ return false;
+
+ // Does not make sense to use aria-activedescendant to point to a
+ // presentational object.
+ if (IsPresentational())
+ return false;
+
+ // 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)
+ return false;
+
return IsARIAControlledByTextboxWithActiveDescendant() ||
AncestorExposesActiveDescendant();
}
@@ -1414,6 +1487,9 @@ void AXObject::UpdateDistributionForFlatTreeTraversal() const {
}
bool AXObject::IsARIAControlledByTextboxWithActiveDescendant() const {
+ if (IsDetached())
+ return false;
+
// This situation should mostly arise when using an active descendant on a
// textbox inside an ARIA 1.1 combo box widget, which points to the selected
// option in a list. In such situations, the active descendant is useful only
@@ -1519,6 +1595,7 @@ bool AXObject::IsSubWidget() const {
bool AXObject::SupportsARIASetSizeAndPosInSet() const {
switch (RoleValue()) {
case ax::mojom::Role::kArticle:
+ case ax::mojom::Role::kComment:
case ax::mojom::Role::kListBoxOption:
case ax::mojom::Role::kListItem:
case ax::mojom::Role::kMenuItem:
@@ -1625,12 +1702,41 @@ String AXObject::RecursiveTextAlternative(const AXObject& ax_obj,
name_from, nullptr, nullptr);
}
+bool AXObject::IsHiddenViaStyle() const {
+ if (GetLayoutObject())
+ return GetLayoutObject()->Style()->Visibility() != EVisibility::kVisible;
+ if (Node* node = GetNode()) {
+ if (node->isConnected()) {
+ bool is_first_loop = true;
+ auto* element = DynamicTo<Element>(node);
+ while (element && !element->GetLayoutObject()) {
+ const ComputedStyle* style = element->EnsureComputedStyle();
+ if (is_first_loop && style->Visibility() != EVisibility::kVisible)
+ return true;
+ // CSS Display:
+ // - does not inherit
+ // - display: none affects entire subtrees regardless of descendants
+ // attempting to override it
+ // - causes elements to have no associated layout object
+ // Therefore, check each consecutive parent without a layout object.
+ if (style->Display() == EDisplay::kNone)
+ return true;
+ element = element->parentElement();
+ is_first_loop = false;
+ }
+ }
+ }
+ return false;
+}
+
bool AXObject::IsHiddenForTextAlternativeCalculation() const {
if (AOMPropertyOrARIAAttributeIsFalse(AOMBooleanProperty::kHidden))
return false;
if (GetLayoutObject())
return GetLayoutObject()->Style()->Visibility() != EVisibility::kVisible;
+ else if (GetNode() && IsA<HTMLNoScriptElement>(GetNode()))
+ return true;
// This is an obscure corner case: if a node has no LayoutObject, that means
// it's not rendered, but we still may be exploring it as part of a text
@@ -1688,33 +1794,40 @@ String AXObject::AriaTextAlternative(bool recursive,
name_sources->back().type = name_from;
}
- const AtomicString& aria_labelledby = GetAttribute(attr);
- if (!aria_labelledby.IsNull()) {
- if (name_sources)
- name_sources->back().attribute_value = aria_labelledby;
-
- // Operate on a copy of |visited| so that if |nameSources| is not null,
- // the set of visited objects is preserved unmodified for future
- // calculations.
- AXObjectSet visited_copy = visited;
+ Element* element = GetElement();
+ if (element) {
+ HeapVector<Member<Element>> elements_from_attribute;
Vector<String> ids;
- text_alternative =
- TextFromAriaLabelledby(visited_copy, related_objects, ids);
- if (!ids.IsEmpty())
- AXObjectCache().UpdateReverseRelations(this, ids);
- if (!text_alternative.IsNull()) {
- if (name_sources) {
- NameSource& source = name_sources->back();
- source.type = name_from;
- source.related_objects = *related_objects;
- source.text = text_alternative;
- *found_text_alternative = true;
- } else {
- *found_text_alternative = true;
- return text_alternative;
+ ElementsFromAttribute(elements_from_attribute, attr, ids);
+
+ const AtomicString& aria_labelledby = GetAttribute(attr);
+
+ if (!aria_labelledby.IsNull()) {
+ if (name_sources)
+ name_sources->back().attribute_value = aria_labelledby;
+
+ // Operate on a copy of |visited| so that if |name_sources| is not
+ // null, the set of visited objects is preserved unmodified for future
+ // calculations.
+ AXObjectSet visited_copy = visited;
+ text_alternative = TextFromElements(
+ true, visited, elements_from_attribute, related_objects);
+ if (!ids.IsEmpty())
+ AXObjectCache().UpdateReverseRelations(this, ids);
+ if (!text_alternative.IsNull()) {
+ if (name_sources) {
+ NameSource& source = name_sources->back();
+ source.type = name_from;
+ source.related_objects = *related_objects;
+ source.text = text_alternative;
+ *found_text_alternative = true;
+ } else {
+ *found_text_alternative = true;
+ return text_alternative;
+ }
+ } else if (name_sources) {
+ name_sources->back().invalid = true;
}
- } else if (name_sources) {
- name_sources->back().invalid = true;
}
}
}
@@ -1796,15 +1909,22 @@ void AXObject::TokenVectorFromAttribute(Vector<String>& tokens,
void AXObject::ElementsFromAttribute(HeapVector<Member<Element>>& elements,
const QualifiedName& attribute,
Vector<String>& ids) const {
+ // We compute the attr-associated elements, which are either explicitly set
+ // element references set via the IDL, or computed from the content attribute.
TokenVectorFromAttribute(ids, attribute);
- if (ids.IsEmpty())
+ Element* element = GetElement();
+ if (!element)
return;
- TreeScope& scope = GetNode()->GetTreeScope();
- for (const auto& id : ids) {
- if (Element* id_element = scope.getElementById(AtomicString(id)))
- elements.push_back(id_element);
- }
+ bool attr_associated_elements_are_null = true;
+ HeapVector<Member<Element>> attr_associated_elements =
+ element->GetElementArrayAttribute(attribute,
+ attr_associated_elements_are_null);
+ if (attr_associated_elements_are_null)
+ return;
+
+ for (const auto& element : attr_associated_elements)
+ elements.push_back(element);
}
void AXObject::AriaLabelledbyElementVector(
@@ -1866,6 +1986,15 @@ ax::mojom::DefaultActionVerb AXObject::Action() const {
: ax::mojom::DefaultActionVerb::kUncheck;
}
+ // If this object cannot receive focus and has a button role, use click as
+ // the default action. On the AuraLinux platform, the press action is a
+ // signal to users that they can trigger the action using the keyboard, while
+ // 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;
+
switch (RoleValue()) {
case ax::mojom::Role::kButton:
case ax::mojom::Role::kDisclosureTriangle:
@@ -2043,7 +2172,7 @@ AXRestriction AXObject::Restriction() const {
if (is_disabled)
return kRestrictionDisabled;
} else if (CanSetFocusAttribute() && IsDescendantOfDisabledNode()) {
- // No aria-disabled, but other markup says it's disabled.
+ // aria-disabled on an ancestor propagates to focusable descendants.
return kRestrictionDisabled;
}
@@ -2079,9 +2208,7 @@ ax::mojom::Role AXObject::DetermineAriaRoleAttribute() const {
switch (role) {
case ax::mojom::Role::kComment:
- case ax::mojom::Role::kCommentSection:
case ax::mojom::Role::kMark:
- case ax::mojom::Role::kRevision:
case ax::mojom::Role::kSuggestion:
UseCounter::Count(GetDocument(), WebFeature::kARIAAnnotations);
if (!RuntimeEnabledFeatures::AccessibilityExposeARIAAnnotationsEnabled(
@@ -2621,6 +2748,21 @@ Document* AXObject::GetDocument() const {
return frame_view->GetFrame().GetDocument();
}
+AXObject* AXObject::RootScroller() const {
+ Node* global_root_scroller = GetDocument()
+ ->GetPage()
+ ->GlobalRootScrollerController()
+ .GlobalRootScroller();
+ if (!global_root_scroller)
+ return nullptr;
+
+ // Only return the root scroller if it's part of the same document.
+ if (global_root_scroller->GetDocument() != GetDocument())
+ return nullptr;
+
+ return AXObjectCache().GetOrCreate(global_root_scroller);
+}
+
LocalFrameView* AXObject::DocumentFrameView() const {
const AXObject* object = this;
while (object && !object->IsAXLayoutObject())
@@ -2721,6 +2863,25 @@ bool AXObject::IsScrollableContainer() const {
return !!GetScrollableAreaIfScrollable();
}
+bool AXObject::IsUserScrollable() const {
+ // TODO(accessibility) Actually expose correct info on whether a doc is
+ // is scrollable or not. Unfortunately IsScrollableContainer() always returns
+ // true anyway. For now, just expose as scrollable unless overflow is hidden.
+ if (IsWebArea()) {
+ if (!GetScrollableAreaIfScrollable() || !GetLayoutObject())
+ return false;
+
+ const ComputedStyle* style = GetLayoutObject()->Style();
+ if (!style)
+ return false;
+
+ return style->ScrollsOverflowY() || style->ScrollsOverflowX();
+ }
+
+ return GetLayoutObject() && GetLayoutObject()->IsBox() &&
+ ToLayoutBox(GetLayoutObject())->CanBeScrolledAndHasScrollableArea();
+}
+
IntPoint AXObject::GetScrollOffset() const {
ScrollableArea* area = GetScrollableAreaIfScrollable();
if (!area)
@@ -2755,7 +2916,7 @@ void AXObject::SetScrollOffset(const IntPoint& offset) const {
// TODO(bokan): This should potentially be a UserScroll.
area->SetScrollOffset(ScrollOffset(offset.X(), offset.Y()),
- kProgrammaticScroll);
+ mojom::blink::ScrollType::kProgrammatic);
}
bool AXObject::IsTableLikeRole() const {
@@ -2978,6 +3139,13 @@ const AXObject* AXObject::TableParent() const {
return table;
}
+int AXObject::GetDOMNodeId() const {
+ Node* node = GetNode();
+ if (node)
+ return DOMNodeIds::IdForNode(node);
+ return 0;
+}
+
void AXObject::GetRelativeBounds(AXObject** out_container,
FloatRect& out_bounds_in_container,
SkMatrix44& out_container_transform,
@@ -3163,8 +3331,8 @@ bool AXObject::OnNativeClickAction() {
if (page) {
page->GetFocusController().SetFocusedElement(
element, GetDocument()->GetFrame(),
- FocusParams(SelectionBehaviorOnFocus::kNone, kWebFocusTypeMouse,
- nullptr));
+ FocusParams(SelectionBehaviorOnFocus::kNone,
+ mojom::blink::FocusType::kMouse, nullptr));
}
}
@@ -3212,8 +3380,8 @@ bool AXObject::RequestScrollToMakeVisibleAction() {
bool AXObject::RequestScrollToMakeVisibleWithSubFocusAction(
const IntRect& subfocus,
- blink::ScrollAlignment horizontal_scroll_alignment,
- blink::ScrollAlignment vertical_scroll_alignment) {
+ blink::mojom::blink::ScrollAlignment horizontal_scroll_alignment,
+ blink::mojom::blink::ScrollAlignment vertical_scroll_alignment) {
return OnNativeScrollToMakeVisibleWithSubFocusAction(
subfocus, horizontal_scroll_alignment, vertical_scroll_alignment);
}
@@ -3249,22 +3417,25 @@ bool AXObject::InternalSetAccessibilityFocusAction() {
bool AXObject::OnNativeScrollToMakeVisibleAction() const {
Node* node = GetNode();
- if (!node)
+ if (!node || !node->isConnected())
return false;
- if (Element* locked_ancestor =
- DisplayLockUtilities::NearestLockedInclusiveAncestor(*node)) {
- locked_ancestor->ActivateDisplayLockIfNeeded(
- DisplayLockActivationReason::kAccessibility);
- }
+
+ // Node might not have a LayoutObject due to the fact that it is in a locked
+ // subtree. Force the update to create the LayoutObject (and update position
+ // information) for this node.
+ DisplayLockUtilities::ScopedChainForcedUpdate scoped_force_update(node);
+ GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kDisplayLock);
+
LayoutObject* layout_object = node->GetLayoutObject();
- if (!layout_object || !node->isConnected())
+ if (!layout_object)
return false;
PhysicalRect target_rect(layout_object->AbsoluteBoundingBoxRect());
layout_object->ScrollRectToVisible(
target_rect,
- WebScrollIntoViewParams(ScrollAlignment::kAlignCenterIfNeeded,
- ScrollAlignment::kAlignCenterIfNeeded,
- kProgrammaticScroll, false, kScrollBehaviorAuto));
+ ScrollAlignment::CreateScrollIntoViewParams(
+ ScrollAlignment::CenterIfNeeded(), ScrollAlignment::CenterIfNeeded(),
+ mojom::blink::ScrollType::kProgrammatic, false,
+ mojom::blink::ScrollBehavior::kAuto));
AXObjectCache().PostNotification(
AXObjectCache().GetOrCreate(GetDocument()->GetLayoutView()),
ax::mojom::Event::kLocationChanged);
@@ -3273,8 +3444,8 @@ bool AXObject::OnNativeScrollToMakeVisibleAction() const {
bool AXObject::OnNativeScrollToMakeVisibleWithSubFocusAction(
const IntRect& rect,
- blink::ScrollAlignment horizontal_scroll_alignment,
- blink::ScrollAlignment vertical_scroll_alignment) const {
+ blink::mojom::blink::ScrollAlignment horizontal_scroll_alignment,
+ blink::mojom::blink::ScrollAlignment vertical_scroll_alignment) const {
Node* node = GetNode();
LayoutObject* layout_object = node ? node->GetLayoutObject() : nullptr;
if (!layout_object || !node->isConnected())
@@ -3282,11 +3453,11 @@ bool AXObject::OnNativeScrollToMakeVisibleWithSubFocusAction(
PhysicalRect target_rect =
layout_object->LocalToAbsoluteRect(PhysicalRect(rect));
layout_object->ScrollRectToVisible(
- target_rect,
- WebScrollIntoViewParams(horizontal_scroll_alignment,
- vertical_scroll_alignment, kProgrammaticScroll,
- false /* make_visible_in_visual_viewport */,
- kScrollBehaviorAuto));
+ target_rect, ScrollAlignment::CreateScrollIntoViewParams(
+ horizontal_scroll_alignment, vertical_scroll_alignment,
+ mojom::blink::ScrollType::kProgrammatic,
+ false /* make_visible_in_visual_viewport */,
+ mojom::blink::ScrollBehavior::kAuto));
AXObjectCache().PostNotification(
AXObjectCache().GetOrCreate(GetDocument()->GetLayoutView()),
ax::mojom::Event::kLocationChanged);
@@ -3303,9 +3474,10 @@ bool AXObject::OnNativeScrollToGlobalPointAction(
target_rect.Move(-PhysicalOffset(global_point));
layout_object->ScrollRectToVisible(
target_rect,
- WebScrollIntoViewParams(ScrollAlignment::kAlignLeftAlways,
- ScrollAlignment::kAlignTopAlways,
- kProgrammaticScroll, false, kScrollBehaviorAuto));
+ ScrollAlignment::CreateScrollIntoViewParams(
+ ScrollAlignment::LeftAlways(), ScrollAlignment::TopAlways(),
+ mojom::blink::ScrollType::kProgrammatic, false,
+ mojom::blink::ScrollBehavior::kAuto));
AXObjectCache().PostNotification(
AXObjectCache().GetOrCreate(GetDocument()->GetLayoutView()),
ax::mojom::Event::kLocationChanged);
@@ -3442,6 +3614,7 @@ bool AXObject::NameFromContents(bool recursive) const {
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:
@@ -3464,18 +3637,15 @@ bool AXObject::NameFromContents(bool recursive) const {
case ax::mojom::Role::kBanner:
case ax::mojom::Role::kBlockquote:
case ax::mojom::Role::kCaret:
- case ax::mojom::Role::kCode:
case ax::mojom::Role::kClient:
case ax::mojom::Role::kColorWell:
case ax::mojom::Role::kColumn:
case ax::mojom::Role::kComboBoxGrouping:
case ax::mojom::Role::kComment:
- case ax::mojom::Role::kCommentSection:
case ax::mojom::Role::kComplementary:
case ax::mojom::Role::kContentInfo:
case ax::mojom::Role::kDate:
case ax::mojom::Role::kDateTime:
- case ax::mojom::Role::kDefinition:
case ax::mojom::Role::kDesktop:
case ax::mojom::Role::kDialog:
case ax::mojom::Role::kDirectory:
@@ -3516,7 +3686,6 @@ bool AXObject::NameFromContents(bool recursive) const {
case ax::mojom::Role::kDocToc:
case ax::mojom::Role::kDocument:
case ax::mojom::Role::kEmbeddedObject:
- case ax::mojom::Role::kEmphasis:
case ax::mojom::Role::kFeed:
case ax::mojom::Role::kFigure:
case ax::mojom::Role::kForm:
@@ -3544,10 +3713,9 @@ bool AXObject::NameFromContents(bool recursive) const {
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::kRevision:
- case ax::mojom::Role::kRootWebArea:
case ax::mojom::Role::kRowGroup:
case ax::mojom::Role::kScrollBar:
case ax::mojom::Role::kScrollView:
@@ -3558,7 +3726,6 @@ bool AXObject::NameFromContents(bool recursive) const {
case ax::mojom::Role::kSpinButton:
case ax::mojom::Role::kStatus:
case ax::mojom::Role::kSliderThumb:
- case ax::mojom::Role::kStrong:
case ax::mojom::Role::kSuggestion:
case ax::mojom::Role::kSvgRoot:
case ax::mojom::Role::kTable:
@@ -3569,7 +3736,6 @@ bool AXObject::NameFromContents(bool recursive) const {
case ax::mojom::Role::kTextField:
case ax::mojom::Role::kTextFieldWithComboBox:
case ax::mojom::Role::kTitleBar:
- case ax::mojom::Role::kTime:
case ax::mojom::Role::kTimer:
case ax::mojom::Role::kToolbar:
case ax::mojom::Role::kTree:
@@ -3586,12 +3752,15 @@ bool AXObject::NameFromContents(bool recursive) const {
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:
@@ -3602,7 +3771,6 @@ bool AXObject::NameFromContents(bool recursive) const {
case ax::mojom::Role::kInlineTextBox:
case ax::mojom::Role::kLabelText:
case ax::mojom::Role::kLayoutTable:
- case ax::mojom::Role::kLayoutTableColumn:
case ax::mojom::Role::kLayoutTableRow:
case ax::mojom::Role::kLegend:
case ax::mojom::Role::kList:
@@ -3621,9 +3789,54 @@ bool AXObject::NameFromContents(bool recursive) const {
case ax::mojom::Role::kRuby:
case ax::mojom::Role::kRubyAnnotation:
case ax::mojom::Role::kSection:
- result = recursive || (CanReceiveAccessibilityFocus() && !IsEditable());
+ case ax::mojom::Role::kStrong:
+ case ax::mojom::Role::kTime:
+ if (recursive) {
+ // Use contents if part of a recursive name computation.
+ result = true;
+ } else {
+ // Use contents if focusable, so that there is a name in the case
+ // where the author mistakenly forgot to provide one.
+ // Exceptions:
+ // 1.Elements with contenteditable, where using the contents as a name
+ // 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
+ // KeyboardFocusableScrollersEnabled is permanently enabled.
+ // Note: this uses the same scrollable check that element.cc uses.
+ bool is_focusable_scrollable =
+ RuntimeEnabledFeatures::KeyboardFocusableScrollersEnabled() &&
+ IsUserScrollable();
+ bool is_focusable = is_focusable_scrollable || CanSetFocusAttribute();
+ result = is_focusable && !IsEditable() &&
+ !GetAOMPropertyOrARIAAttribute(
+ AOMRelationProperty::kActiveDescendant);
+ }
+ break;
+
+ case ax::mojom::Role::kPdfActionableHighlight:
+ LOG(ERROR) << "PDF specific highlight role, Blink shouldn't generate "
+ "this role type";
+ NOTREACHED();
break;
+ // A root web area normally only computes its name from the document title,
+ // 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: {
+ DCHECK(GetNode());
+ const Document& document = GetNode()->GetDocument();
+ bool is_main_frame =
+ document.GetFrame() && document.GetFrame()->IsMainFrame();
+ bool is_inside_portal =
+ document.GetPage() && document.GetPage()->InsidePortal();
+ return is_inside_portal && is_main_frame;
+ }
+
case ax::mojom::Role::kUnknown:
case ax::mojom::Role::kMaxValue:
LOG(ERROR) << "ax::mojom::Role::kUnknown for " << GetNode();
@@ -3799,7 +4012,7 @@ std::ostream& operator<<(std::ostream& stream, const AXObject& obj) {
return stream << obj.ToString().Utf8();
}
-void AXObject::Trace(blink::Visitor* visitor) {
+void AXObject::Trace(Visitor* visitor) {
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 da4f4d18953..1b9c136b1d9 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -99,7 +99,7 @@ class IgnoredReason {
IgnoredReason(AXIgnoredReason r, const AXObject* obj)
: reason(r), related_object(obj) {}
- void Trace(blink::Visitor* visitor) { visitor->Trace(related_object); }
+ void Trace(Visitor* visitor) { visitor->Trace(related_object); }
};
class NameSourceRelatedObject final
@@ -111,7 +111,7 @@ class NameSourceRelatedObject final
NameSourceRelatedObject(AXObject* object, String text)
: object(object), text(text) {}
- void Trace(blink::Visitor* visitor) { visitor->Trace(object); }
+ void Trace(Visitor* visitor) { visitor->Trace(object); }
DISALLOW_COPY_AND_ASSIGN(NameSourceRelatedObject);
};
@@ -136,7 +136,7 @@ class NameSource {
explicit NameSource(bool superseded)
: superseded(superseded), attribute(QualifiedName::Null()) {}
- void Trace(blink::Visitor* visitor) { visitor->Trace(related_objects); }
+ void Trace(Visitor* visitor) { visitor->Trace(related_objects); }
};
class DescriptionSource {
@@ -158,7 +158,7 @@ class DescriptionSource {
explicit DescriptionSource(bool superseded)
: superseded(superseded), attribute(QualifiedName::Null()) {}
- void Trace(blink::Visitor* visitor) { visitor->Trace(related_objects); }
+ void Trace(Visitor* visitor) { visitor->Trace(related_objects); }
};
} // namespace blink
@@ -227,7 +227,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
return static_cast<AXObject*>(current_);
}
- void Trace(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
visitor->Trace(current_);
visitor->Trace(previous_);
}
@@ -302,7 +302,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
return static_cast<AXObject*>(current_);
}
- void Trace(blink::Visitor* visitor) { visitor->Trace(current_); }
+ void Trace(Visitor* visitor) { visitor->Trace(current_); }
MODULES_EXPORT friend void swap(AncestorsIterator& left,
AncestorsIterator& right) {
@@ -335,7 +335,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
public:
virtual ~AXObject();
- virtual void Trace(blink::Visitor*);
+ virtual void Trace(Visitor*);
static unsigned NumberOfLiveAXObjects() { return number_of_live_ax_objects_; }
@@ -409,7 +409,6 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
}
virtual bool IsControl() const { return false; }
virtual bool IsDefault() const { return false; }
- virtual bool IsEmbeddedObject() const { return false; }
virtual bool IsFieldset() const { return false; }
virtual bool IsHeading() const { return false; }
virtual bool IsImage() const { return false; }
@@ -497,10 +496,12 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
virtual bool IsVisible() const;
virtual bool IsVisited() const { return false; }
- // Check whether certain properties can be modified.
- bool CanSetFocusAttribute() const;
+ // Check whether value can be modified.
bool CanSetValueAttribute() const;
+ // Is the element focusable?
+ bool CanSetFocusAttribute() const;
+
// Whether objects are ignored, i.e. hidden from the AT.
bool AccessibilityIsIgnored() const;
// Whether objects are ignored but included in the tree.
@@ -716,6 +717,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
virtual ax::mojom::Role DetermineAccessibilityRole();
ax::mojom::Role DetermineAriaRoleAttribute() const;
virtual ax::mojom::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 {}
@@ -735,7 +737,6 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
bool SupportsARIAExpanded() const;
virtual bool SupportsARIADragging() const { return false; }
virtual void Dropeffects(Vector<ax::mojom::Dropeffect>& dropeffects) const {}
- virtual bool SupportsARIAFlowTo() const { return false; }
virtual bool SupportsARIAOwns() const { return false; }
bool SupportsRangeValue() const;
bool SupportsARIAReadOnly() const;
@@ -899,6 +900,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
// Properties of the object's owning document or page.
virtual double EstimatedLoadingProgress() const { return 0; }
+ virtual AXObject* RootScroller() const;
// DOM and layout tree access.
virtual Node* GetNode() const { return nullptr; }
@@ -914,6 +916,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
// Scrollable containers.
bool IsScrollableContainer() const;
+ bool IsUserScrollable() const; // Only true if actual scrollbars are present.
IntPoint GetScrollOffset() const;
IntPoint MinimumScrollOffset() const;
IntPoint MaximumScrollOffset() const;
@@ -972,8 +975,8 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
bool RequestScrollToMakeVisibleAction();
bool RequestScrollToMakeVisibleWithSubFocusAction(
const IntRect&,
- blink::ScrollAlignment horizontal_scroll_alignment,
- blink::ScrollAlignment vertical_scroll_alignment);
+ blink::mojom::blink::ScrollAlignment horizontal_scroll_alignment,
+ blink::mojom::blink::ScrollAlignment vertical_scroll_alignment);
bool RequestSetSelectedAction(bool);
bool RequestSetSequentialFocusNavigationStartingPointAction();
bool RequestSetValueAction(const String&);
@@ -996,8 +999,8 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
bool OnNativeScrollToMakeVisibleAction() const;
bool OnNativeScrollToMakeVisibleWithSubFocusAction(
const IntRect&,
- blink::ScrollAlignment horizontal_scroll_alignment,
- blink::ScrollAlignment vertical_scroll_alignment) const;
+ blink::mojom::blink::ScrollAlignment horizontal_scroll_alignment,
+ blink::mojom::blink::ScrollAlignment vertical_scroll_alignment) const;
virtual bool OnNativeSetSelectedAction(bool);
virtual bool OnNativeSetSequentialFocusNavigationStartingPointAction();
virtual bool OnNativeSetValueAction(const String&);
@@ -1031,6 +1034,9 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
int* index_in_ancestor1,
int* index_in_ancestor2);
+ // Blink-internal DOM Node ID. Currently used for PDF exporting.
+ int GetDOMNodeId() const;
+
// Returns a string representation of this object.
String ToString() const;
@@ -1080,7 +1086,6 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
return nullptr;
}
- bool CanReceiveAccessibilityFocus() const;
bool NameFromContents(bool recursive) const;
bool NameFromSelectedOption(bool recursive) const;
@@ -1144,6 +1149,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> {
bool HasInternalsAttribute(Element&, const QualifiedName&) const;
const AtomicString& GetInternalsAttribute(Element&,
const QualifiedName&) const;
+ bool IsHiddenViaStyle() const;
static unsigned number_of_live_ax_objects_;
@@ -1158,10 +1164,6 @@ MODULES_EXPORT bool operator>(const AXObject& first, const AXObject& second);
MODULES_EXPORT bool operator>=(const AXObject& first, const AXObject& second);
MODULES_EXPORT std::ostream& operator<<(std::ostream&, const AXObject&);
-#define DEFINE_AX_OBJECT_TYPE_CASTS(thisType, predicate) \
- DEFINE_TYPE_CASTS(thisType, AXObject, object, object->predicate, \
- object.predicate)
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_OBJECT_H_
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 83ff396913a..0495fe4951c 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
@@ -37,6 +37,7 @@
#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/document.h"
+#include "third_party/blink/renderer/core/dom/document_lifecycle.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
@@ -57,8 +58,6 @@
#include "third_party/blink/renderer/core/html_names.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/layout_list_box.h"
-#include "third_party/blink/renderer/core/layout/layout_menu_list.h"
#include "third_party/blink/renderer/core/layout/layout_progress.h"
#include "third_party/blink/renderer/core/layout/layout_slider.h"
#include "third_party/blink/renderer/core/layout/layout_table.h"
@@ -93,6 +92,7 @@
namespace blink {
namespace {
+
// Return a node for the current layout object or ancestor layout object.
Node* GetClosestNodeForLayoutObject(LayoutObject* layout_object) {
if (!layout_object)
@@ -101,6 +101,27 @@ Node* GetClosestNodeForLayoutObject(LayoutObject* layout_object) {
return node ? node : GetClosestNodeForLayoutObject(layout_object->Parent());
}
+bool IsAttributeImportantForAccessibility(const QualifiedName& attribute_name,
+ const Element& element) {
+ // Generally important attributes.
+ if (attribute_name == html_names::kRoleAttr ||
+ attribute_name == html_names::kTypeAttr ||
+ attribute_name == html_names::kSizeAttr ||
+ attribute_name == html_names::kAltAttr ||
+ attribute_name == html_names::kTitleAttr ||
+ attribute_name == html_names::kIdAttr ||
+ attribute_name == html_names::kTabindexAttr ||
+ attribute_name == html_names::kDisabledAttr)
+ return true;
+
+ // <label for>.
+ if (attribute_name == html_names::kForAttr && IsA<HTMLLabelElement>(element))
+ return true;
+
+ // Any ARIA attribute.
+ return attribute_name.LocalName().StartsWith("aria-");
+}
+
} // namespace
// static
@@ -109,16 +130,16 @@ AXObjectCache* AXObjectCacheImpl::Create(Document& document) {
}
AXObjectCacheImpl::AXObjectCacheImpl(Document& document)
- : AXObjectCacheBase(document),
- document_(document),
+ : document_(document),
modification_count_(0),
validation_message_axid_(0),
relation_cache_(std::make_unique<AXRelationCache>(this)),
- accessibility_event_permission_(mojom::PermissionStatus::ASK) {
+ accessibility_event_permission_(mojom::blink::PermissionStatus::ASK),
+ permission_service_(document.ToExecutionContext()),
+ permission_observer_receiver_(this, document.ToExecutionContext()) {
if (document_->LoadEventFinished())
AddPermissionStatusListener();
documents_.insert(&document);
- document.View()->RegisterForLifecycleNotifications(this);
relation_cache_->Init();
}
@@ -135,12 +156,6 @@ void AXObjectCacheImpl::Dispose() {
RemoveAXID(obj);
}
- for (auto document : documents_) {
- if (!document || !document->View())
- continue;
- document->View()->UnregisterFromLifecycleNotifications(this);
- }
-
permission_observer_receiver_.reset();
#if DCHECK_IS_ON()
@@ -153,18 +168,16 @@ AXObject* AXObjectCacheImpl::Root() {
}
void AXObjectCacheImpl::InitializePopup(Document* document) {
- if (!document || documents_.Contains(document) || document->View())
+ if (!document || documents_.Contains(document) || !document->View())
return;
documents_.insert(document);
- document->View()->RegisterForLifecycleNotifications(this);
}
void AXObjectCacheImpl::DisposePopup(Document* document) {
- if (documents_.Contains(document) || document->View())
+ if (!documents_.Contains(document) || !document->View())
return;
- document->View()->UnregisterFromLifecycleNotifications(this);
documents_.erase(document);
}
@@ -226,10 +239,11 @@ AXObject* AXObjectCacheImpl::FocusedImageMapUIElement(
unsigned count = image_children.size();
for (unsigned k = 0; k < count; ++k) {
AXObject* child = image_children[k];
- if (!child->IsImageMapLink())
+ auto* ax_object = DynamicTo<AXImageMapLink>(child);
+ if (!ax_object)
continue;
- if (ToAXImageMapLink(child)->AreaElement() == area_element)
+ if (ax_object->AreaElement() == area_element)
return child;
}
@@ -275,10 +289,9 @@ static bool IsMenuListOption(const Node* node) {
if (!option_element)
return false;
const HTMLSelectElement* select = option_element->OwnerSelectElement();
- if (!select)
+ if (!select || !select->UsesMenuList())
return false;
- const LayoutObject* layout_object = select->GetLayoutObject();
- return layout_object && layout_object->IsMenuList();
+ return select->GetLayoutObject();
}
AXObject* AXObjectCacheImpl::Get(const Node* node) {
@@ -424,10 +437,11 @@ AXObject* AXObjectCacheImpl::CreateFromRenderer(LayoutObject* layout_object) {
if (layout_object->IsBoxModelObject()) {
LayoutBoxModelObject* css_box = ToLayoutBoxModelObject(layout_object);
- if (css_box->IsListBox())
- return MakeGarbageCollected<AXListBox>(ToLayoutListBox(css_box), *this);
- if (css_box->IsMenuList())
- return MakeGarbageCollected<AXMenuList>(ToLayoutMenuList(css_box), *this);
+ if (auto* select_element = DynamicTo<HTMLSelectElement>(node)) {
+ if (select_element->UsesMenuList())
+ return MakeGarbageCollected<AXMenuList>(css_box, *this);
+ return MakeGarbageCollected<AXListBox>(css_box, *this);
+ }
// progress bar
if (css_box->IsProgress()) {
@@ -436,8 +450,8 @@ AXObject* AXObjectCacheImpl::CreateFromRenderer(LayoutObject* layout_object) {
}
// input type=range
- if (css_box->IsSlider())
- return MakeGarbageCollected<AXSlider>(ToLayoutSlider(css_box), *this);
+ if (auto* slider = DynamicTo<LayoutSlider>(css_box))
+ return MakeGarbageCollected<AXSlider>(slider, *this);
}
return MakeGarbageCollected<AXLayoutObject>(layout_object, *this);
@@ -531,8 +545,27 @@ AXObject* AXObjectCacheImpl::GetOrCreate(LayoutObject* layout_object) {
if (node && (IsMenuListOption(node) || IsA<HTMLAreaElement>(node)))
return nullptr;
- if (node && DisplayLockUtilities::NearestLockedExclusiveAncestor(*node))
+ // Prefer creating AXNodeObjects over AXLayoutObjects in locked subtrees
+ // (e.g. subtree-visibility: auto), even if a LayoutObject is available,
+ // because the LayoutObject is not guaranteed to be up-to-date (it might come
+ // from a previous layout update), or even it is up-to-date, it may not remain
+ // up-to-date. Blink doesn't update style/layout for nodes in locked
+ // subtrees, so creating a matching AXLayoutObjects could lead to the use of
+ // old information. Note that Blink will recreate the AX objects as
+ // AXLayoutObjects when a locked element is activated, aka it becomes visible.
+ // Visit https://wicg.github.io/display-locking/#accessibility for more info.
+ if (DisplayLockUtilities::NearestLockedExclusiveAncestor(*layout_object)) {
+ if (!node) {
+ // Nodeless objects such as anonymous blocks do not get accessible objects
+ // in a locked subtree. Anonymous blocks are added to help layout when
+ // a block and inline are siblings.
+ // This prevents an odd mixture of ax objects in a locked subtree, e.g.
+ // AXNodeObjects when there is a node, and AXLayoutObjects
+ // when there isn't. The locked subtree should not have AXLayoutObjects.
+ return nullptr;
+ }
return GetOrCreate(layout_object->GetNode());
+ }
AXObject* new_obj = CreateFromRenderer(layout_object);
@@ -616,7 +649,7 @@ void AXObjectCacheImpl::ContainingTableRowsOrColsMaybeChanged(Node* node) {
// removal of a <tr> or <td>.
// Get parent table from DOM, because AXObject/layout tree are incomplete.
ContainerNode* containing_table = nullptr;
- if (IsHTMLTableCellElement(node) || IsA<HTMLTableRowElement>(node))
+ if (IsA<HTMLTableCellElement>(node) || IsA<HTMLTableRowElement>(node))
containing_table = FindParentTable(node);
if (containing_table) {
@@ -774,8 +807,22 @@ AXObject::InOrderTraversalIterator AXObjectCacheImpl::InOrderTraversalEnd() {
void AXObjectCacheImpl::DeferTreeUpdateInternal(Node* node,
base::OnceClosure callback) {
+ if (GetDocument().IsDetached())
+ return;
+
+ DCHECK(!node->GetDocument().GetPage()->Animator().IsServicingAnimations() ||
+ (node->GetDocument().Lifecycle().GetState() <
+ DocumentLifecycle::kInAccessibility ||
+ node->GetDocument().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(), std::move(callback)));
+
+ // These events are fired during DocumentLifecycle::kInAccessibility,
+ // ensure there is a document lifecycle update scheduled.
+ ScheduleVisualUpdate();
}
void AXObjectCacheImpl::DeferTreeUpdate(
@@ -893,10 +940,6 @@ void AXObjectCacheImpl::FocusableChangedWithCleanLayout(Element* element) {
void AXObjectCacheImpl::DocumentTitleChanged() {
PostNotification(Root(), ax::mojom::Event::kDocumentTitleChanged);
- // If title changes at a point where paint is clean, send notification
- // immediately.
- if (document_->Lifecycle().GetState() >= DocumentLifecycle::kPaintClean)
- PostNotificationsAfterLayout(document_);
}
void AXObjectCacheImpl::UpdateCacheAfterNodeIsAttached(Node* node) {
@@ -979,15 +1022,28 @@ void AXObjectCacheImpl::ChildrenChanged(AXObject* obj, Node* optional_node) {
}
}
-void AXObjectCacheImpl::ProcessUpdatesAfterLayout(Document& document) {
- if (document.Lifecycle().GetState() < DocumentLifecycle::kLayoutClean)
+void AXObjectCacheImpl::ProcessDeferredAccessibilityEvents(Document& document) {
+ if (document.Lifecycle().GetState() != DocumentLifecycle::kInAccessibility) {
+ DCHECK(false) << "Deferred events should only be processed during the "
+ "accessibility document lifecycle";
return;
+ }
+
+ ProcessUpdates(document);
+ PostNotifications(document);
+}
+
+void AXObjectCacheImpl::ProcessUpdates(Document& document) {
+ // None of the updates should alter the document lifecycle.
+ DocumentLifecycle::DisallowTransitionScope disallow(document.Lifecycle());
+
TreeUpdateCallbackQueue old_tree_update_callback_queue;
tree_update_callback_queue_.swap(old_tree_update_callback_queue);
for (auto& tree_update : old_tree_update_callback_queue) {
Node* node = tree_update->node;
if (!node)
continue;
+
base::OnceClosure& callback = tree_update->callback;
if (node->GetDocument() != document) {
tree_update_callback_queue_.push_back(
@@ -995,15 +1051,13 @@ void AXObjectCacheImpl::ProcessUpdatesAfterLayout(Document& document) {
std::move(callback)));
continue;
}
- bool saved_is_handling_action = is_handling_action_;
- if (tree_update->event_from == ax::mojom::EventFrom::kAction)
- is_handling_action_ = true;
- std::move(callback).Run();
- is_handling_action_ = saved_is_handling_action;
+
+ FireTreeUpdatedEventImmediately(node, std::move(callback),
+ tree_update->event_from);
}
}
-void AXObjectCacheImpl::PostNotificationsAfterLayout(Document* document) {
+void AXObjectCacheImpl::PostNotifications(Document& document) {
HeapVector<Member<AXEventParams>> old_notifications_to_post;
notifications_to_post_.swap(old_notifications_to_post);
for (auto& params : old_notifications_to_post) {
@@ -1017,29 +1071,13 @@ void AXObjectCacheImpl::PostNotificationsAfterLayout(Document* document) {
ax::mojom::Event event_type = params->event_type;
ax::mojom::EventFrom event_from = params->event_from;
- if (obj->GetDocument() != document) {
+ if (obj->GetDocument() != &document) {
notifications_to_post_.push_back(
MakeGarbageCollected<AXEventParams>(obj, event_type, event_from));
continue;
}
-#if DCHECK_IS_ON()
- // Make sure none of the layout views are in the process of being layed out.
- // Notifications should only be sent after the layoutObject has finished
- if (obj->IsAXLayoutObject()) {
- AXLayoutObject* layout_obj = ToAXLayoutObject(obj);
- LayoutObject* layout_object = layout_obj->GetLayoutObject();
- if (layout_object && layout_object->View())
- DCHECK(!layout_object->View()->GetLayoutState());
- }
-#endif
-
- PostPlatformNotification(obj, event_type, event_from);
-
- if (event_type == ax::mojom::Event::kChildrenChanged &&
- obj->CachedParentObject() &&
- obj->LastKnownIsIgnoredValue() != obj->AccessibilityIsIgnored())
- ChildrenChanged(obj->CachedParentObject());
+ FireAXEventImmediately(obj, event_type, event_from);
}
}
@@ -1059,12 +1097,90 @@ void AXObjectCacheImpl::PostNotification(Node* node,
void AXObjectCacheImpl::PostNotification(AXObject* object,
ax::mojom::Event notification) {
- if (!object)
+ if (!object || !object->AXObjectID() || object->IsDetached())
return;
modification_count_++;
+
+ // It's possible for FireAXEventImmediately to post another notification.
+ // If we're still in the accessibility document lifecycle, fire these events
+ // immediately rather than deferring them.
+ if (object->GetDocument()->Lifecycle().GetState() ==
+ DocumentLifecycle::kInAccessibility) {
+ FireAXEventImmediately(object, notification, ComputeEventFrom());
+ return;
+ }
+
notifications_to_post_.push_back(MakeGarbageCollected<AXEventParams>(
object, notification, ComputeEventFrom()));
+
+ // These events are fired during DocumentLifecycle::kInAccessibility,
+ // ensure there is a visual update scheduled.
+ ScheduleVisualUpdate();
+}
+
+void AXObjectCacheImpl::ScheduleVisualUpdate() {
+ // Scheduling visual updates before the document is finished loading can
+ // interfere with event ordering.
+ if (!GetDocument().IsLoadCompleted())
+ return;
+
+ // If there was a document change that doesn't trigger a lifecycle update on
+ // its own, (e.g. because it doesn't make layout dirty), make sure we run
+ // lifecycle phases to update the computed accessibility tree.
+ auto* view = GetDocument().View();
+ auto* page = GetDocument().GetPage();
+ if (!view || !page)
+ return;
+ if (!view->CanThrottleRendering())
+ page->Animator().ScheduleVisualUpdate(GetDocument().GetFrame());
+}
+
+void AXObjectCacheImpl::FireTreeUpdatedEventImmediately(
+ Node* node,
+ base::OnceClosure callback,
+ ax::mojom::EventFrom event_from) {
+ DCHECK_EQ(node->GetDocument().Lifecycle().GetState(),
+ DocumentLifecycle::kInAccessibility);
+ bool saved_is_handling_action = is_handling_action_;
+ if (event_from == ax::mojom::EventFrom::kAction)
+ is_handling_action_ = true;
+ std::move(callback).Run();
+ is_handling_action_ = saved_is_handling_action;
+}
+
+void AXObjectCacheImpl::FireAXEventImmediately(
+ AXObject* obj,
+ ax::mojom::Event event_type,
+ ax::mojom::EventFrom event_from) {
+ DCHECK_EQ(obj->GetDocument()->Lifecycle().GetState(),
+ DocumentLifecycle::kInAccessibility);
+
+#if DCHECK_IS_ON()
+ // Make sure none of the layout views are in the process of being laid out.
+ // Notifications should only be sent after the layoutObject has finished
+ auto* layout_obj = DynamicTo<AXLayoutObject>(obj);
+ if (layout_obj) {
+ LayoutObject* layout_object = layout_obj->GetLayoutObject();
+ if (layout_object && layout_object->View())
+ DCHECK(!layout_object->View()->GetLayoutState());
+ }
+#endif
+
+ PostPlatformNotification(obj, event_type, event_from);
+
+ if (event_type == ax::mojom::Event::kChildrenChanged &&
+ obj->CachedParentObject()) {
+ const bool was_ignored = obj->LastKnownIsIgnoredValue();
+ const bool was_ignored_but_included_in_tree =
+ obj->LastKnownIsIgnoredButIncludedInTreeValue();
+ bool is_ignored_changed =
+ was_ignored != obj->AccessibilityIsIgnored() ||
+ was_ignored_but_included_in_tree !=
+ obj->AccessibilityIsIgnoredButIncludedInTree();
+ if (is_ignored_changed)
+ ChildrenChanged(obj->CachedParentObject());
+ }
}
bool AXObjectCacheImpl::IsAriaOwned(const AXObject* object) const {
@@ -1082,6 +1198,14 @@ void AXObjectCacheImpl::UpdateAriaOwns(
relation_cache_->UpdateAriaOwns(owner, id_vector, owned_children);
}
+void AXObjectCacheImpl::UpdateAriaOwnsFromAttrAssociatedElements(
+ const AXObject* owner,
+ const HeapVector<Member<Element>>& attr_associated_elements,
+ HeapVector<Member<AXObject>>& owned_children) {
+ relation_cache_->UpdateAriaOwnsFromAttrAssociatedElements(
+ owner, attr_associated_elements, owned_children);
+}
+
bool AXObjectCacheImpl::MayHaveHTMLLabel(const HTMLElement& elem) {
// Return false if this type of element will not accept a <label for> label.
if (!elem.IsLabelable())
@@ -1109,11 +1233,11 @@ void AXObjectCacheImpl::ListboxSelectedChildrenChanged(
}
void AXObjectCacheImpl::ListboxActiveIndexChanged(HTMLSelectElement* select) {
- AXObject* obj = Get(select);
- if (!obj || !obj->IsAXListBox())
+ auto* ax_object = DynamicTo<AXListBox>(Get(select));
+ if (!ax_object)
return;
- ToAXListBox(obj)->ActiveIndexChanged();
+ ax_object->ActiveIndexChanged();
}
void AXObjectCacheImpl::LocationChanged(LayoutObject* layout_object) {
@@ -1122,21 +1246,21 @@ void AXObjectCacheImpl::LocationChanged(LayoutObject* layout_object) {
void AXObjectCacheImpl::RadiobuttonRemovedFromGroup(
HTMLInputElement* group_member) {
- AXObject* obj = Get(group_member);
- if (!obj || !obj->IsAXRadioInput())
+ auto* ax_object = DynamicTo<AXRadioInput>(Get(group_member));
+ if (!ax_object)
return;
// The 'posInSet' and 'setSize' attributes should be updated from the first
// node, as the removed node is already detached from tree.
- HTMLInputElement* first_radio =
- ToAXRadioInput(obj)->FindFirstRadioButtonInGroup(group_member);
+ auto* first_radio = ax_object->FindFirstRadioButtonInGroup(group_member);
AXObject* first_obj = Get(first_radio);
- if (!first_obj || !first_obj->IsAXRadioInput())
+ auto* ax_first_obj = DynamicTo<AXRadioInput>(first_obj);
+ if (!ax_first_obj)
return;
- ToAXRadioInput(first_obj)->UpdatePosAndSetSize(1);
+ ax_first_obj->UpdatePosAndSetSize(1);
PostNotification(first_obj, ax::mojom::Event::kAriaAttributeChanged);
- ToAXRadioInput(first_obj)->RequestUpdateToNextNode(true);
+ ax_first_obj->RequestUpdateToNextNode(true);
}
void AXObjectCacheImpl::ImageLoaded(LayoutObject* layout_object) {
@@ -1323,33 +1447,8 @@ bool AXObjectCacheImpl::HandleAttributeChanged(const QualifiedName& attr_name,
DeferTreeUpdate(&AXObjectCacheImpl::HandleAttributeChangedWithCleanLayout,
attr_name, element);
- if (attr_name != html_names::kRoleAttr &&
- attr_name != html_names::kTypeAttr &&
- attr_name != html_names::kSizeAttr && attr_name != html_names::kAltAttr &&
- attr_name != html_names::kTitleAttr &&
- (attr_name != html_names::kForAttr && !IsA<HTMLLabelElement>(*element)) &&
- attr_name != html_names::kIdAttr &&
- attr_name != html_names::kTabindexAttr &&
- attr_name != html_names::kDisabledAttr &&
- !attr_name.LocalName().StartsWith("aria-")) {
+ if (!IsAttributeImportantForAccessibility(attr_name, *element))
return false;
- }
-
- // If this attribute is interesting for accessibility (e.g. `role` or
- // `alt`), but doesn't trigger a lifecycle update on its own
- // (e.g. because it doesn't make layout dirty), make sure we run
- // lifecycle phases to update the computed accessibility tree.
- auto* view = element->GetDocument().View();
- auto* page = element->GetDocument().GetPage();
- if (!view || !page)
- return true;
- if (!view->CanThrottleRendering()) {
- page->Animator().ScheduleVisualUpdate(GetDocument().GetFrame());
- }
-
- // TODO(aboxhall): add a lifecycle phase for accessibility updates.
- GetDocument().Lifecycle().EnsureStateAtMost(
- DocumentLifecycle::kVisualUpdatePending);
return true;
}
@@ -1704,37 +1803,33 @@ void AXObjectCacheImpl::HandleValueChanged(Node* node) {
PostNotification(node, ax::mojom::Event::kValueChanged);
}
-void AXObjectCacheImpl::HandleUpdateActiveMenuOption(LayoutMenuList* menu_list,
+void AXObjectCacheImpl::HandleUpdateActiveMenuOption(LayoutObject* menu_list,
int option_index) {
- AXObject* obj = Get(menu_list);
- if (!obj || !obj->IsMenuList())
+ auto* ax_object = DynamicTo<AXMenuList>(Get(menu_list));
+ if (!ax_object)
return;
- ToAXMenuList(obj)->DidUpdateActiveOption(option_index);
+ ax_object->DidUpdateActiveOption(option_index);
}
-void AXObjectCacheImpl::DidShowMenuListPopup(LayoutMenuList* menu_list) {
- AXObject* obj = Get(menu_list);
- if (!obj || !obj->IsMenuList())
+void AXObjectCacheImpl::DidShowMenuListPopup(LayoutObject* menu_list) {
+ auto* ax_object = DynamicTo<AXMenuList>(Get(menu_list));
+ if (!ax_object)
return;
- ToAXMenuList(obj)->DidShowPopup();
+ ax_object->DidShowPopup();
}
-void AXObjectCacheImpl::DidHideMenuListPopup(LayoutMenuList* menu_list) {
- AXObject* obj = Get(menu_list);
- if (!obj || !obj->IsMenuList())
+void AXObjectCacheImpl::DidHideMenuListPopup(LayoutObject* menu_list) {
+ auto* ax_object = DynamicTo<AXMenuList>(Get(menu_list));
+ if (!ax_object)
return;
- ToAXMenuList(obj)->DidHidePopup();
+ ax_object->DidHidePopup();
}
void AXObjectCacheImpl::HandleLoadComplete(Document* document) {
PostNotification(GetOrCreate(document), ax::mojom::Event::kLoadComplete);
- // If load complete comes through after the lifecycle has finished,
- // send notification immediately.
- if (document->Lifecycle().GetState() >= DocumentLifecycle::kPaintClean)
- PostNotificationsAfterLayout(document);
AddPermissionStatusListener();
}
@@ -1832,14 +1927,18 @@ void AXObjectCacheImpl::AddPermissionStatusListener() {
if (permission_service_.is_bound())
permission_service_.reset();
- ConnectToPermissionService(document_->GetExecutionContext(),
- permission_service_.BindNewPipeAndPassReceiver());
+ ConnectToPermissionService(
+ document_->GetExecutionContext(),
+ permission_service_.BindNewPipeAndPassReceiver(
+ document_->GetTaskRunner(TaskType::kUserInteraction)));
if (permission_observer_receiver_.is_bound())
permission_observer_receiver_.reset();
mojo::PendingRemote<mojom::blink::PermissionObserver> observer;
- permission_observer_receiver_.Bind(observer.InitWithNewPipeAndPassReceiver());
+ permission_observer_receiver_.Bind(
+ observer.InitWithNewPipeAndPassReceiver(),
+ document_->GetTaskRunner(TaskType::kUserInteraction));
permission_service_->AddPermissionObserver(
CreatePermissionDescriptor(
mojom::blink::PermissionName::ACCESSIBILITY_EVENTS),
@@ -1859,7 +1958,7 @@ void AXObjectCacheImpl::RequestAOMEventListenerPermission() {
if (accessibility_event_permission_ != mojom::PermissionStatus::ASK)
return;
- if (!permission_service_)
+ if (!permission_service_.is_bound())
return;
permission_service_->RequestPermission(
@@ -1870,28 +1969,15 @@ void AXObjectCacheImpl::RequestAOMEventListenerPermission() {
WrapPersistent(this)));
}
-void AXObjectCacheImpl::WillStartLifecycleUpdate(const LocalFrameView&) {}
-
-void AXObjectCacheImpl::DidFinishLifecycleUpdate(const LocalFrameView& view) {
- Document* document = view.GetFrame().GetDocument();
- if (document) {
- ProcessUpdatesAfterLayout(*document);
- PostNotificationsAfterLayout(document);
- }
-}
-
-void AXObjectCacheImpl::ContextDestroyed(ExecutionContext*) {
- permission_service_.reset();
- permission_observer_receiver_.reset();
-}
-
-void AXObjectCacheImpl::Trace(blink::Visitor* visitor) {
+void AXObjectCacheImpl::Trace(Visitor* visitor) {
visitor->Trace(document_);
visitor->Trace(accessible_node_mapping_);
visitor->Trace(node_object_mapping_);
visitor->Trace(objects_);
visitor->Trace(notifications_to_post_);
+ visitor->Trace(permission_service_);
+ visitor->Trace(permission_observer_receiver_);
visitor->Trace(documents_);
visitor->Trace(tree_update_callback_queue_);
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 99e3fe4e931..48ba4f10774 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
@@ -33,17 +33,17 @@
#include <utility>
#include "base/macros.h"
-#include "mojo/public/cpp/bindings/receiver.h"
-#include "mojo/public/cpp/bindings/remote.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"
#include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink.h"
#include "third_party/blink/public/web/web_ax_enums.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache_base.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/modules/accessibility/ax_object.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/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -59,16 +59,13 @@ class LocalFrameView;
// This class should only be used from inside the accessibility directory.
class MODULES_EXPORT AXObjectCacheImpl
: public AXObjectCacheBase,
- public mojom::blink::PermissionObserver,
- public LocalFrameView::LifecycleNotificationObserver {
- USING_GARBAGE_COLLECTED_MIXIN(AXObjectCacheImpl);
-
+ public mojom::blink::PermissionObserver {
public:
static AXObjectCache* Create(Document&);
explicit AXObjectCacheImpl(Document&);
~AXObjectCacheImpl() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
Document& GetDocument() { return *document_; }
AXObject* FocusedObject();
@@ -130,9 +127,9 @@ class MODULES_EXPORT AXObjectCacheImpl
void HandleScaleAndLocationChanged(Document*) override;
void HandleTextMarkerDataAdded(Node* start, Node* end) override;
void HandleValueChanged(Node*) override;
- void HandleUpdateActiveMenuOption(LayoutMenuList*, int option_index) override;
- void DidShowMenuListPopup(LayoutMenuList*) override;
- void DidHideMenuListPopup(LayoutMenuList*) override;
+ void HandleUpdateActiveMenuOption(LayoutObject*, int option_index) override;
+ void DidShowMenuListPopup(LayoutObject*) override;
+ void DidHideMenuListPopup(LayoutObject*) override;
void HandleLoadComplete(Document*) override;
void HandleLayoutComplete(Document*) override;
void HandleClicked(Node*) override;
@@ -144,7 +141,7 @@ class MODULES_EXPORT AXObjectCacheImpl
const LayoutRect&) override;
void InlineTextBoxesUpdated(LineLayoutItem) override;
- void ProcessUpdatesAfterLayout(Document&) override;
+ void ProcessDeferredAccessibilityEvents(Document&) override;
// Called when the scroll offset changes.
void HandleScrollPositionChanged(LocalFrameView*) override;
@@ -239,6 +236,16 @@ class MODULES_EXPORT AXObjectCacheImpl
const Vector<String>& id_vector,
HeapVector<Member<AXObject>>& owned_children);
+ // Given an object that has explicitly set elements for aria-owns, update the
+ // internal state to reflect the new set of children owned by this object.
+ // Note that |owned_children| will be the AXObjects corresponding to the
+ // elements in |attr_associated_elements|. These elements are validated -
+ // exist in the DOM, and are a descendant of a shadow including ancestor.
+ void UpdateAriaOwnsFromAttrAssociatedElements(
+ const AXObject* owner,
+ const HeapVector<Member<Element>>& attr_associated_elements,
+ HeapVector<Member<AXObject>>& owned_children);
+
bool MayHaveHTMLLabel(const HTMLElement& elem);
// Synchronously returns whether or not we currently have permission to
@@ -254,10 +261,6 @@ class MODULES_EXPORT AXObjectCacheImpl
// For built-in HTML form validation messages.
AXObject* ValidationMessageObjectIfInvalid();
- // LifecycleNotificationObserver overrides.
- void WillStartLifecycleUpdate(const LocalFrameView&) override;
- void DidFinishLifecycleUpdate(const LocalFrameView&) override;
-
void set_is_handling_action(bool value) { is_handling_action_ = value; }
WebAXAutofillState GetAutofillState(AXID id) const;
@@ -327,10 +330,9 @@ class MODULES_EXPORT AXObjectCacheImpl
#endif
HeapVector<Member<AXEventParams>> notifications_to_post_;
- void PostNotificationsAfterLayout(Document*);
- // ContextLifecycleObserver overrides.
- void ContextDestroyed(ExecutionContext*) override;
+ void ProcessUpdates(Document&);
+ void PostNotifications(Document&);
// Get the currently focused Node element.
Node* FocusedElement();
@@ -386,14 +388,22 @@ class MODULES_EXPORT AXObjectCacheImpl
void HandleAttributeChangedWithCleanLayout(const QualifiedName& attr_name,
Element* element);
+ void ScheduleVisualUpdate();
+ void FireTreeUpdatedEventImmediately(Node* node,
+ base::OnceClosure callback,
+ ax::mojom::EventFrom event_from);
+ void FireAXEventImmediately(AXObject* obj,
+ ax::mojom::Event event_type,
+ ax::mojom::EventFrom event_from);
+
// Whether the user has granted permission for the user to install event
// listeners for accessibility events using the AOM.
mojom::PermissionStatus accessibility_event_permission_;
// The permission service, enabling us to check for event listener
// permission.
- mojo::Remote<mojom::blink::PermissionService> permission_service_;
- mojo::Receiver<mojom::blink::PermissionObserver>
- permission_observer_receiver_{this};
+ HeapMojoRemote<mojom::blink::PermissionService> permission_service_;
+ HeapMojoReceiver<mojom::blink::PermissionObserver>
+ permission_observer_receiver_;
// The main document, plus any page popups.
HeapHashSet<WeakMember<Document>> documents_;
@@ -409,7 +419,10 @@ class MODULES_EXPORT AXObjectCacheImpl
};
// This is the only subclass of AXObjectCache.
-DEFINE_TYPE_CASTS(AXObjectCacheImpl, AXObjectCache, cache, true, true);
+template <>
+struct DowncastTraits<AXObjectCacheImpl> {
+ static bool AllowFrom(const AXObjectCache& cache) { return true; }
+};
// This will let you know if aria-hidden was explicitly set to false.
bool IsNodeAriaVisible(Node*);
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 aaf1003ba34..ad4aa1ca4d9 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
@@ -19,7 +19,9 @@ class AccessibilityLayoutTest : public testing::WithParamInterface<bool>,
AccessibilityLayoutTest() : ScopedLayoutNGForTest(GetParam()) {}
protected:
- bool LayoutNGEnabled() const { return GetParam(); }
+ bool LayoutNGEnabled() const {
+ return RuntimeEnabledFeatures::LayoutNGEnabled();
+ }
};
INSTANTIATE_TEST_SUITE_P(AccessibilityTest,
@@ -431,10 +433,10 @@ TEST_F(AccessibilityTest, InitRelationCache) {
const AXObject* input_b = GetAXObjectByElementId("b");
ASSERT_NE(nullptr, input_b);
- EXPECT_TRUE(
- GetAXObjectCache().MayHaveHTMLLabel(ToHTMLElement(*input_a->GetNode())));
- EXPECT_FALSE(
- GetAXObjectCache().MayHaveHTMLLabel(ToHTMLElement(*input_b->GetNode())));
+ EXPECT_TRUE(GetAXObjectCache().MayHaveHTMLLabel(
+ To<HTMLElement>(*input_a->GetNode())));
+ EXPECT_FALSE(GetAXObjectCache().MayHaveHTMLLabel(
+ To<HTMLElement>(*input_b->GetNode())));
// Note: retrieve the LI first and check that its parent is not
// the paragraph element. If we were to retrieve the UL element,
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 745e15941bd..f0b73cc3d6f 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_position.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_position.cc
@@ -696,13 +696,16 @@ const AXPosition AXPosition::AsValidDOMPosition(
DCHECK(container);
const AXObject* child = ChildAfterTreePosition();
const AXObject* last_child = container->LastChild();
- if ((IsTextPosition() && !container->GetNode()) ||
+ if ((IsTextPosition() && (!container->GetNode() ||
+ container->GetNode()->IsMarkerPseudoElement())) ||
container->IsMockObject() || container->IsVirtualObject() ||
(!child && last_child &&
- (!last_child->GetNode() || last_child->IsMockObject() ||
- last_child->IsVirtualObject())) ||
- (child && (!child->GetNode() || child->IsMockObject() ||
- child->IsVirtualObject()))) {
+ (!last_child->GetNode() ||
+ last_child->GetNode()->IsMarkerPseudoElement() ||
+ last_child->IsMockObject() || last_child->IsVirtualObject())) ||
+ (child &&
+ (!child->GetNode() || child->GetNode()->IsMarkerPseudoElement() ||
+ child->IsMockObject() || child->IsVirtualObject()))) {
switch (adjustment_behavior) {
case AXPositionAdjustmentBehavior::kMoveRight:
return CreateNextPosition().AsValidDOMPosition(adjustment_behavior);
@@ -713,14 +716,14 @@ const AXPosition AXPosition::AsValidDOMPosition(
// At this point, if a DOM node is associated with our container, then the
// corresponding DOM position should be valid.
- if (container->GetNode())
+ if (container->GetNode() && !container->GetNode()->IsMarkerPseudoElement())
return *this;
- DCHECK(container->IsAXLayoutObject())
+ DCHECK(IsA<AXLayoutObject>(container))
<< "Non virtual and non mock AX objects that are not associated to a DOM "
"node should have an associated layout object.";
const Node* container_node =
- ToAXLayoutObject(container)->GetNodeOrContainingBlockNode();
+ To<AXLayoutObject>(container)->GetNodeOrContainingBlockNode();
DCHECK(container_node) << "All anonymous layout objects and list markers "
"should have a containing block element.";
DCHECK(!container->IsDetached());
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_radio_input.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_radio_input.cc
index b4f99932a30..18e5c357fdc 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_radio_input.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_radio_input.cc
@@ -34,7 +34,8 @@ void AXRadioInput::RequestUpdateToNextNode(bool forward) {
HTMLInputElement* next_element =
RadioInputType::NextRadioButtonInGroup(GetInputElement(), forward);
AXObject* next_axobject = AXObjectCache().Get(next_element);
- if (!next_axobject || !next_axobject->IsAXRadioInput())
+ auto* ax_radio_input = DynamicTo<AXRadioInput>(next_axobject);
+ if (!ax_radio_input)
return;
int position = 0;
@@ -44,10 +45,10 @@ void AXRadioInput::RequestUpdateToNextNode(bool forward) {
// previous objects. updatePosAndSetSize() is called with '0' and it doesn't
// modify m_posInSet and updates m_setSize as size is increased.
- ToAXRadioInput(next_axobject)->UpdatePosAndSetSize(position);
+ ax_radio_input->UpdatePosAndSetSize(position);
AXObjectCache().PostNotification(next_axobject,
ax::mojom::Event::kAriaAttributeChanged);
- ToAXRadioInput(next_axobject)->RequestUpdateToNextNode(forward);
+ ax_radio_input->RequestUpdateToNextNode(forward);
}
HTMLInputElement* AXRadioInput::FindFirstRadioButtonInGroup(
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_radio_input.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_radio_input.h
index 4253a0aee33..e171357281e 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_radio_input.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_radio_input.h
@@ -39,7 +39,12 @@ class AXRadioInput final : public AXLayoutObject {
DISALLOW_COPY_AND_ASSIGN(AXRadioInput);
};
-DEFINE_AX_OBJECT_TYPE_CASTS(AXRadioInput, IsAXRadioInput());
+template <>
+struct DowncastTraits<AXRadioInput> {
+ static bool AllowFrom(const AXObject& object) {
+ return object.IsAXRadioInput();
+ }
+};
} // namespace blink
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 a55484a6f43..9e78c2cdf4a 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
@@ -143,6 +143,32 @@ void AXRelationCache::MapOwnedChildren(const AXObject* owner,
}
}
+void AXRelationCache::UpdateAriaOwnsFromAttrAssociatedElements(
+ const AXObject* owner,
+ const HeapVector<Member<Element>>& attr_associated_elements,
+ HeapVector<Member<AXObject>>& validated_owned_children_result) {
+ // attr-associated elements have already had their scope validated, but they
+ // need to be further validated to determine if they introduce a cycle or are
+ // already owned by another element.
+ Vector<String> owned_id_vector;
+ for (const auto& element : attr_associated_elements) {
+ AXObject* child = GetOrCreate(element);
+
+ // TODO(meredithl): Determine how to update reverse relations for elements
+ // without an id.
+ if (element->GetIdAttribute())
+ owned_id_vector.push_back(element->GetIdAttribute());
+ if (IsValidOwnsRelation(const_cast<AXObject*>(owner), child))
+ validated_owned_children_result.push_back(GetOrCreate(element));
+ }
+
+ // Track reverse relations for future tree updates.
+ UpdateReverseRelations(owner, owned_id_vector);
+
+ // Update the internal mappings of owned children.
+ UpdateAriaOwnerToChildrenMapping(owner, validated_owned_children_result);
+}
+
void AXRelationCache::UpdateAriaOwns(
const AXObject* owner,
const Vector<String>& owned_id_vector,
@@ -150,7 +176,6 @@ void AXRelationCache::UpdateAriaOwns(
// Track reverse relations for future tree updates.
UpdateReverseRelations(owner, owned_id_vector);
- //
// Figure out the ids that actually correspond to children that exist
// and that we can legally own (not cyclical, not already owned, etc.) and
// update the maps and |validated_owned_children_result| based on that.
@@ -167,12 +192,21 @@ void AXRelationCache::UpdateAriaOwns(
for (const String& id_name : owned_id_vector) {
Element* element = scope.getElementById(AtomicString(id_name));
AXObject* child = GetOrCreate(element);
- if (IsValidOwnsRelation(const_cast<AXObject*>(owner), child)) {
- validated_owned_child_axids.push_back(child->AXObjectID());
+ if (IsValidOwnsRelation(const_cast<AXObject*>(owner), child))
validated_owned_children_result.push_back(child);
- }
}
+ // Update the internal validated mapping of owned children.
+ UpdateAriaOwnerToChildrenMapping(owner, validated_owned_children_result);
+}
+
+void AXRelationCache::UpdateAriaOwnerToChildrenMapping(
+ const AXObject* owner,
+ HeapVector<Member<AXObject>>& validated_owned_children_result) {
+ Vector<AXID> validated_owned_child_axids;
+ for (auto& child : validated_owned_children_result)
+ validated_owned_child_axids.push_back(child->AXObjectID());
+
// Compare this to the current list of owned children, and exit early if
// there are no changes.
Vector<AXID> current_child_axids =
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h
index 2dec5cfb6d0..591ffc9d965 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h
@@ -41,6 +41,16 @@ class AXRelationCache {
const Vector<String>& id_vector,
HeapVector<Member<AXObject>>& owned_children);
+ // Given an object that has explicitly set elements for aria-owns, update the
+ // internal state to reflect the new set of children owned by this object.
+ // Note that |owned_children| will be the AXObjects corresponding to the
+ // elements in |attr_associated_elements|. These elements are validated -
+ // exist in the DOM, and are a descendant of a shadow including ancestor.
+ void UpdateAriaOwnsFromAttrAssociatedElements(
+ const AXObject* owner,
+ const HeapVector<Member<Element>>& attr_associated_elements,
+ HeapVector<Member<AXObject>>& owned_children);
+
// Return true if any label ever pointed to the element via the for attribute.
bool MayHaveHTMLLabelViaForAttribute(const HTMLElement&);
@@ -72,6 +82,12 @@ class AXRelationCache {
void MapOwnedChildren(const AXObject* owner, Vector<AXID>);
void GetReverseRelated(Node*, HeapVector<Member<AXObject>>& sources);
+ // Updates |aria_owner_to_children_mapping_| after calling UpdateAriaOwns for
+ // either the content attribute or the attr associated elements.
+ void UpdateAriaOwnerToChildrenMapping(
+ const AXObject* owner,
+ HeapVector<Member<AXObject>>& validated_owned_children_result);
+
WeakPersistent<AXObjectCacheImpl> object_cache_;
// Map from the AXID of the owner to the AXIDs of the children.
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 50c15be22a0..40c0cb5eba5 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
@@ -493,7 +493,7 @@ TEST_F(AccessibilitySelectionTest, SetSelectionInDisplayNone) {
// endpoints.
//
-TEST_F(AccessibilitySelectionTest, SetSelectionAroundListBullet) {
+TEST_P(ParameterizedAccessibilitySelectionTest, SetSelectionAroundListBullet) {
SetBodyInnerHTML(R"HTML(
<div role="main">
<ul>
@@ -565,21 +565,36 @@ TEST_F(AccessibilitySelectionTest, SetSelectionAroundListBullet) {
EXPECT_EQ(text_2, extended_selection.Extent().AnchorNode());
EXPECT_EQ(7, extended_selection.Extent().OffsetInContainerNode());
+ std::string expectations;
+ if (LayoutNGEnabled()) {
+ expectations =
+ "++<GenericContainer>\n"
+ "++++<Main>\n"
+ "++++++<List>\n"
+ "++++++++<ListItem>\n"
+ "++++++++++<ListMarker: \xE2\x80\xA2 >\n"
+ "^++++++++++++<StaticText: ^\xE2\x80\xA2 >\n"
+ "++++++++++<StaticText: Item 1.>\n"
+ "++++++++<ListItem>\n"
+ "++++++++++<ListMarker: \xE2\x80\xA2 >\n"
+ "++++++++++++<StaticText: \xE2\x80\xA2 >\n"
+ "++++++++++<StaticText: Item 2.|>\n";
+ } else {
+ expectations =
+ "++<GenericContainer>\n"
+ "++++<Main>\n"
+ "++++++<List>\n"
+ "++++++++<ListItem>\n"
+ "++++++++++<ListMarker: \xE2\x80\xA2 >\n"
+ "^++++++++++<StaticText: Item 1.>\n"
+ "++++++++<ListItem>\n"
+ "++++++++++<ListMarker: \xE2\x80\xA2 >\n"
+ "++++++++++<StaticText: Item 2.|>\n";
+ }
+
// The |AXSelection| should remain unaffected by any shrinking and should
// include both list bullets.
- EXPECT_EQ(
- "++<GenericContainer>\n"
- "++++<Main>\n"
- "++++++<List>\n"
- "++++++++<ListItem>\n"
- "++++++++++<ListMarker: \xE2\x80\xA2 >\n"
- "^++++++++++++<StaticText: ^\xE2\x80\xA2 >\n"
- "++++++++++<StaticText: Item 1.>\n"
- "++++++++<ListItem>\n"
- "++++++++++<ListMarker: \xE2\x80\xA2 >\n"
- "++++++++++++<StaticText: \xE2\x80\xA2 >\n"
- "++++++++++<StaticText: Item 2.|>\n",
- GetSelectionText(ax_selection));
+ EXPECT_EQ(expectations, GetSelectionText(ax_selection));
}
//
@@ -1731,8 +1746,8 @@ TEST_F(AccessibilitySelectionTest, ARIAHidden) {
RunSelectionTest("aria-hidden");
}
-TEST_F(AccessibilitySelectionTest, List) {
- RunSelectionTest("list");
+TEST_P(ParameterizedAccessibilitySelectionTest, List) {
+ ParameterizedAccessibilitySelectionTest::RunSelectionTest("list");
}
TEST_F(AccessibilitySelectionTest, SVG) {
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.cc
index 0999dae6fe0..bfc50ab1dee 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.cc
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.h"
+#include "third_party/blink/renderer/core/dom/qualified_name.h"
#include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h"
namespace blink {
@@ -74,16 +75,29 @@ class ObjectAttributeSetter : public AXSparseAttributeSetter {
private:
AXObjectAttribute attribute_;
+ QualifiedName GetAttributeQualifiedName() {
+ switch (attribute_) {
+ case AXObjectAttribute::kAriaActiveDescendant:
+ return html_names::kAriaActivedescendantAttr;
+ case AXObjectAttribute::kAriaErrorMessage:
+ return html_names::kAriaErrormessageAttr;
+ default:
+ NOTREACHED();
+ }
+ return g_null_name;
+ }
+
void Run(const AXObject& obj,
AXSparseAttributeClient& attribute_map,
const AtomicString& value) override {
- if (value.IsNull() || value.IsEmpty())
+ if (value.IsNull())
return;
- auto* element = DynamicTo<Element>(obj.GetNode());
+ Element* element = obj.GetElement();
if (!element)
return;
- Element* target = element->GetTreeScope().getElementById(value);
+ const QualifiedName& q_name = GetAttributeQualifiedName();
+ Element* target = element->GetElementAttribute(q_name);
if (!target)
return;
AXObject* ax_target = obj.AXObjectCache().GetOrCreate(target);
@@ -100,36 +114,43 @@ class ObjectVectorAttributeSetter : public AXSparseAttributeSetter {
private:
AXObjectVectorAttribute attribute_;
+ QualifiedName GetAttributeQualifiedName() {
+ switch (attribute_) {
+ case AXObjectVectorAttribute::kAriaControls:
+ return html_names::kAriaControlsAttr;
+ case AXObjectVectorAttribute::kAriaDetails:
+ return html_names::kAriaDetailsAttr;
+ case AXObjectVectorAttribute::kAriaFlowTo:
+ return html_names::kAriaFlowtoAttr;
+ default:
+ NOTREACHED();
+ }
+ return g_null_name;
+ }
+
void Run(const AXObject& obj,
AXSparseAttributeClient& attribute_map,
const AtomicString& value) override {
- Node* node = obj.GetNode();
- if (!node || !node->IsElementNode())
- return;
-
- String attribute_value = value.GetString();
- if (attribute_value.IsEmpty())
+ Element* element = obj.GetElement();
+ if (!element)
return;
- Vector<String> ids;
- attribute_value.Split(' ', ids);
- if (ids.IsEmpty())
+ bool is_null = false;
+ HeapVector<Member<Element>> attr_associated_elements =
+ element->GetElementArrayAttribute(GetAttributeQualifiedName(), is_null);
+ if (is_null)
return;
-
HeapVector<Member<AXObject>> objects;
- TreeScope& scope = node->GetTreeScope();
- for (const auto& id : ids) {
- if (Element* id_element = scope.getElementById(AtomicString(id))) {
- AXObject* ax_id_element = obj.AXObjectCache().GetOrCreate(id_element);
- if (!ax_id_element)
- continue;
- if (AXObject* parent = ax_id_element->ParentObject())
- parent->UpdateChildrenIfNecessary();
- if (!ax_id_element->AccessibilityIsIgnored())
- objects.push_back(ax_id_element);
- }
+ for (const auto& associated_element : attr_associated_elements) {
+ AXObject* ax_element =
+ obj.AXObjectCache().GetOrCreate(associated_element);
+ if (!ax_element)
+ continue;
+ if (AXObject* parent = ax_element->ParentObject())
+ parent->UpdateChildrenIfNecessary();
+ if (!ax_element->AccessibilityIsIgnored())
+ objects.push_back(ax_element);
}
-
attribute_map.AddObjectVectorAttribute(attribute_, objects);
}
};
@@ -154,7 +175,7 @@ AXSparseAttributeSetterMap& GetSparseAttributeSetterMap() {
new ObjectVectorAttributeSetter(AXObjectVectorAttribute::kAriaFlowTo));
ax_sparse_attribute_setter_map.Set(
html_names::kAriaDetailsAttr,
- new ObjectAttributeSetter(AXObjectAttribute::kAriaDetails));
+ new ObjectVectorAttributeSetter(AXObjectVectorAttribute::kAriaDetails));
ax_sparse_attribute_setter_map.Set(
html_names::kAriaErrormessageAttr,
new ObjectAttributeSetter(AXObjectAttribute::kAriaErrorMessage));
@@ -239,9 +260,6 @@ void AXSparseAttributeAOMPropertyClient::AddRelationProperty(
case AOMRelationProperty::kActiveDescendant:
attribute = AXObjectAttribute::kAriaActiveDescendant;
break;
- case AOMRelationProperty::kDetails:
- attribute = AXObjectAttribute::kAriaDetails;
- break;
case AOMRelationProperty::kErrorMessage:
attribute = AXObjectAttribute::kAriaErrorMessage;
break;
@@ -263,6 +281,9 @@ void AXSparseAttributeAOMPropertyClient::AddRelationListProperty(
case AOMRelationListProperty::kControls:
attribute = AXObjectVectorAttribute::kAriaControls;
break;
+ case AOMRelationListProperty::kDetails:
+ attribute = AXObjectVectorAttribute::kAriaDetails;
+ break;
case AOMRelationListProperty::kFlowTo:
attribute = AXObjectVectorAttribute::kAriaFlowTo;
break;
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_validation_message.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_validation_message.h
index cec168092da..fd9abe4e67f 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/ax_validation_message.h
+++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_validation_message.h
@@ -49,8 +49,6 @@ class AXValidationMessage final : public AXMockObject {
DISALLOW_COPY_AND_ASSIGN(AXValidationMessage);
};
-DEFINE_AX_OBJECT_TYPE_CASTS(AXValidationMessage, IsValidationMessage());
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_VALIDATION_MESSAGE_H_
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 7719f9641e4..c01361ba478 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(blink::Visitor* visitor) {
+void AXVirtualObject::Trace(Visitor* visitor) {
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 c571d96f34b..8d9b398efec 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// AXObject overrides.
void Detach() override;
@@ -43,8 +43,6 @@ class MODULES_EXPORT AXVirtualObject : public AXObject {
Member<AccessibleNode> accessible_node_;
};
-DEFINE_AX_OBJECT_TYPE_CASTS(AXVirtualObject, IsVirtualObject());
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_VIRTUAL_OBJECT_H_
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/idls.gni b/chromium/third_party/blink/renderer/modules/accessibility/idls.gni
new file mode 100644
index 00000000000..34bfc1ef92e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/accessibility/idls.gni
@@ -0,0 +1,5 @@
+# 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_testing_dependency_idl_files = [ "testing/internals_accessibility.idl" ]
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 349c28b88cb..7e0c653dad0 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
@@ -388,7 +388,7 @@ class SparseAttributeAXPropertyAdapter
protocol::Array<AXProperty>& properties)
: ax_object_(&ax_object), properties_(properties) {}
- void Trace(blink::Visitor* visitor) { visitor->Trace(ax_object_); }
+ void Trace(Visitor* visitor) { visitor->Trace(ax_object_); }
private:
Member<AXObject> ax_object_;
@@ -432,10 +432,6 @@ class SparseAttributeAXPropertyAdapter
CreateProperty(AXPropertyNameEnum::Activedescendant,
CreateRelatedNodeListValue(object)));
break;
- case AXObjectAttribute::kAriaDetails:
- properties_.emplace_back(CreateProperty(
- AXPropertyNameEnum::Details, CreateRelatedNodeListValue(object)));
- break;
case AXObjectAttribute::kAriaErrorMessage:
properties_.emplace_back(
CreateProperty(AXPropertyNameEnum::Errormessage,
@@ -453,6 +449,11 @@ class SparseAttributeAXPropertyAdapter
AXPropertyNameEnum::Controls, objects,
html_names::kAriaControlsAttr, *ax_object_));
break;
+ case AXObjectVectorAttribute::kAriaDetails:
+ properties_.emplace_back(CreateRelatedNodeListProperty(
+ AXPropertyNameEnum::Details, objects, html_names::kAriaDetailsAttr,
+ *ax_object_));
+ break;
case AXObjectVectorAttribute::kAriaFlowTo:
properties_.emplace_back(CreateRelatedNodeListProperty(
AXPropertyNameEnum::Flowto, objects, html_names::kAriaFlowtoAttr,
@@ -522,18 +523,18 @@ Response InspectorAccessibilityAgent::getPartialAXTree(
Node* dom_node = nullptr;
Response response =
dom_agent_->AssertNode(dom_node_id, backend_node_id, object_id, dom_node);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
Document& document = dom_node->GetDocument();
- document.UpdateStyleAndLayout();
+ document.UpdateStyleAndLayout(DocumentUpdateReason::kInspector);
DocumentLifecycle::DisallowTransitionScope disallow_transition(
document.Lifecycle());
LocalFrame* local_frame = document.GetFrame();
if (!local_frame)
- return Response::Error("Frame is detached.");
+ return Response::ServerError("Frame is detached.");
AXContext ax_context(document);
- AXObjectCacheImpl& cache = ToAXObjectCacheImpl(ax_context.GetAXObjectCache());
+ auto& cache = To<AXObjectCacheImpl>(ax_context.GetAXObjectCache());
AXObject* inspected_ax_object = cache.GetOrCreate(dom_node);
*nodes = std::make_unique<protocol::Array<protocol::Accessibility::AXNode>>();
@@ -541,7 +542,7 @@ Response InspectorAccessibilityAgent::getPartialAXTree(
(*nodes)->emplace_back(BuildObjectForIgnoredNode(
dom_node, inspected_ax_object, fetch_relatives.fromMaybe(true), *nodes,
cache));
- return Response::OK();
+ return Response::Success();
} else {
(*nodes)->emplace_back(
BuildProtocolAXObject(*inspected_ax_object, inspected_ax_object,
@@ -549,16 +550,16 @@ Response InspectorAccessibilityAgent::getPartialAXTree(
}
if (!inspected_ax_object)
- return Response::OK();
+ return Response::Success();
AXObject* parent = inspected_ax_object->ParentObjectUnignored();
if (!parent)
- return Response::OK();
+ return Response::Success();
if (fetch_relatives.fromMaybe(true))
AddAncestors(*parent, inspected_ax_object, *nodes, cache);
- return Response::OK();
+ return Response::Success();
}
void InspectorAccessibilityAgent::AddAncestors(
@@ -717,12 +718,12 @@ Response InspectorAccessibilityAgent::getFullAXTree(
std::unique_ptr<protocol::Array<AXNode>>* nodes) {
Document* document = inspected_frames_->Root()->GetDocument();
if (!document)
- return Response::Error("No document.");
+ return Response::ServerError("No document.");
if (document->View()->NeedsLayout() || document->NeedsLayoutTreeUpdate())
- document->UpdateStyleAndLayout();
+ document->UpdateStyleAndLayout(DocumentUpdateReason::kInspector);
*nodes = std::make_unique<protocol::Array<protocol::Accessibility::AXNode>>();
AXContext ax_context(*document);
- AXObjectCacheImpl& cache = ToAXObjectCacheImpl(ax_context.GetAXObjectCache());
+ auto& cache = To<AXObjectCacheImpl>(ax_context.GetAXObjectCache());
Deque<AXID> ids;
ids.emplace_back(cache.Root()->AXObjectID());
while (!ids.empty()) {
@@ -742,7 +743,7 @@ Response InspectorAccessibilityAgent::getFullAXTree(
node->setChildIds(std::move(child_ids));
(*nodes)->emplace_back(std::move(node));
}
- return Response::OK();
+ return Response::Success();
}
void InspectorAccessibilityAgent::FillCoreProperties(
@@ -852,12 +853,12 @@ void InspectorAccessibilityAgent::EnableAndReset() {
protocol::Response InspectorAccessibilityAgent::enable() {
if (!enabled_.Get())
EnableAndReset();
- return Response::OK();
+ return Response::Success();
}
protocol::Response InspectorAccessibilityAgent::disable() {
if (!enabled_.Get())
- return Response::OK();
+ return Response::Success();
enabled_.Set(false);
context_ = nullptr;
LocalFrame* frame = inspected_frames_->Root();
@@ -866,7 +867,7 @@ protocol::Response InspectorAccessibilityAgent::disable() {
it->value.erase(this);
if (it->value.IsEmpty())
EnabledAgents().erase(frame);
- return Response::OK();
+ return Response::Success();
}
void InspectorAccessibilityAgent::Restore() {
@@ -887,7 +888,7 @@ void InspectorAccessibilityAgent::CreateAXContext() {
context_ = std::make_unique<AXContext>(*document);
}
-void InspectorAccessibilityAgent::Trace(blink::Visitor* visitor) {
+void InspectorAccessibilityAgent::Trace(Visitor* visitor) {
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 09049685842..231229e4129 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void Restore() override;
// Protocol methods.
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 63ed1428d28..9056487393e 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
@@ -34,6 +34,8 @@ namespace {
constexpr char kSelectionTestsRelativePath[] = "selection/";
constexpr char kTestFileSuffix[] = ".html";
+constexpr char kLayoutNGSuffix[] = "-ax-layout-ng.txt";
+constexpr char kLayoutNGDisabledSuffix[] = "-ax-layout-ng-disabled.txt";
constexpr char kAXTestExpectationSuffix[] = "-ax.txt";
// Serialize accessibility subtree to selection text.
@@ -205,9 +207,9 @@ class AXSelectionDeserializer final {
// parts of the tree indicated by the selection markers in the snippet.
const Vector<AXSelection> Deserialize(const std::string& html_snippet,
HTMLElement& element) {
- element.SetInnerHTMLFromString(String::FromUTF8(html_snippet));
+ element.setInnerHTML(String::FromUTF8(html_snippet));
element.GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
AXObject* root = ax_object_cache_->GetOrCreate(&element);
if (!root || root->IsDetached())
return {};
@@ -281,7 +283,7 @@ class AXSelectionDeserializer final {
// is re-serialized.
node->setData(builder.ToString());
node->GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
//
// Non-text selection.
@@ -390,7 +392,8 @@ AXSelection AccessibilitySelectionTest::SetSelectionText(
}
void AccessibilitySelectionTest::RunSelectionTest(
- const std::string& test_name) const {
+ const std::string& test_name,
+ const std::string& suffix) const {
static const std::string separator_line = '\n' + std::string(80, '=') + '\n';
const String relative_path = String::FromUTF8(kSelectionTestsRelativePath) +
String::FromUTF8(test_name);
@@ -407,7 +410,9 @@ void AccessibilitySelectionTest::RunSelectionTest(
<< test_file.Utf8()
<< "\nDid you forget to add a data dependency to the BUILD file?";
- const String ax_file = test_path + String::FromUTF8(kAXTestExpectationSuffix);
+ const String ax_file =
+ test_path +
+ String::FromUTF8(suffix.empty() ? kAXTestExpectationSuffix : suffix);
scoped_refptr<SharedBuffer> ax_file_buffer = ReadFromFile(ax_file);
auto ax_file_chars = ax_file_buffer->CopyAs<Vector<char>>();
std::string ax_file_contents;
@@ -436,5 +441,18 @@ void AccessibilitySelectionTest::RunSelectionTest(
EXPECT_EQ(ax_file_contents, actual_ax_file_contents);
}
+ParameterizedAccessibilitySelectionTest::
+ ParameterizedAccessibilitySelectionTest(
+ LocalFrameClient* local_frame_client)
+ : ScopedLayoutNGForTest(GetParam()),
+ AccessibilitySelectionTest(local_frame_client) {}
+
+void ParameterizedAccessibilitySelectionTest::RunSelectionTest(
+ const std::string& test_name) const {
+ std::string suffix =
+ LayoutNGEnabled() ? kLayoutNGSuffix : kLayoutNGDisabledSuffix;
+ 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 8d605e07a13..c4c75fc1a1c 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
@@ -55,11 +55,34 @@ class AccessibilitySelectionTest : public AccessibilityTest {
// Compares two HTML files containing a DOM selection and the equivalent
// accessibility selection.
- void RunSelectionTest(const std::string& test_name) const;
+ void RunSelectionTest(const std::string& test_name,
+ const std::string& suffix = std::string()) const;
private:
};
+class ParameterizedAccessibilitySelectionTest
+ : public testing::WithParamInterface<bool>,
+ private ScopedLayoutNGForTest,
+ public AccessibilitySelectionTest {
+ public:
+ ParameterizedAccessibilitySelectionTest(
+ LocalFrameClient* local_frame_client = nullptr);
+
+ protected:
+ // Compares two HTML files containing a DOM selection and the equivalent
+ // accessibility selection.
+ void RunSelectionTest(const std::string& test_name) const;
+
+ bool LayoutNGEnabled() const {
+ return RuntimeEnabledFeatures::LayoutNGEnabled();
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(All,
+ ParameterizedAccessibilitySelectionTest,
+ testing::Bool());
+
} // namespace test
} // namespace blink
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 088088fa299..6f8bb3a27d5 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
@@ -11,6 +11,7 @@
#include "third_party/blink/renderer/core/layout/layout_view.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/platform/runtime_enabled_features.h"
namespace blink {
namespace test {
@@ -20,12 +21,13 @@ AccessibilityTest::AccessibilityTest(LocalFrameClient* local_frame_client)
void AccessibilityTest::SetUp() {
RenderingTest::SetUp();
+ RuntimeEnabledFeatures::SetAccessibilityExposeHTMLElementEnabled(false);
ax_context_.reset(new AXContext(GetDocument()));
}
AXObjectCacheImpl& AccessibilityTest::GetAXObjectCache() const {
auto* ax_object_cache =
- ToAXObjectCacheImpl(GetDocument().ExistingAXObjectCache());
+ To<AXObjectCacheImpl>(GetDocument().ExistingAXObjectCache());
DCHECK(ax_object_cache);
return *ax_object_cache;
}
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 872004e8d7b..8b2ab7a994e 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
@@ -60,7 +60,9 @@ class ParameterizedAccessibilityTest : public testing::WithParamInterface<bool>,
ParameterizedAccessibilityTest() : ScopedLayoutNGForTest(GetParam()) {}
protected:
- bool LayoutNGEnabled() const { return GetParam(); }
+ bool LayoutNGEnabled() const {
+ return RuntimeEnabledFeatures::LayoutNGEnabled();
+ }
};
INSTANTIATE_TEST_SUITE_P(All, ParameterizedAccessibilityTest, testing::Bool());
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/list-ax-layout-ng-disabled.txt b/chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/list-ax-layout-ng-disabled.txt
new file mode 100644
index 00000000000..2d576b50a04
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/list-ax-layout-ng-disabled.txt
@@ -0,0 +1,49 @@
+
+================================================================================
+AXSelection from AX object anchored position in "List": "", 1 to AX object anchored position in "List": "", 3
+================================================================================
+++<GenericContainer>
+++++<List>
+++++++<ListItem>
+++++++++<ListMarker: 1. >
+++++++++<StaticText: tic>
+^++++++<ListItem>
+++++++++<ListMarker: 2. >
+++++++++<StaticText: tac>
+++++++<ListItem>
+++++++++<ListMarker: 3. >
+++++++++<StaticText: toe>
+|++++<List>
+++++++<ListItem>
+++++++++<StaticText: tic>
+++++++<StaticText: >
+++++++<ListItem>
+++++++++<StaticText: tac>
+++++++<StaticText: >
+++++++<ListItem>
+++++++++<StaticText: toe>
+
+================================================================================
+AXSelection from AX object anchored position in "GenericContainer": "", 1 to AX object anchored position in "GenericContainer": "", 2
+================================================================================
+++<GenericContainer>
+++++<List>
+++++++<ListItem>
+++++++++<ListMarker: 1. >
+++++++++<StaticText: tic>
+++++++<ListItem>
+++++++++<ListMarker: 2. >
+++++++++<StaticText: tac>
+++++++<ListItem>
+++++++++<ListMarker: 3. >
+++++++++<StaticText: toe>
+^++++<List>
+++++++<ListItem>
+++++++++<StaticText: tic>
+++++++<StaticText: >
+++++++<ListItem>
+++++++++<StaticText: tac>
+++++++<StaticText: >
+++++++<ListItem>
+++++++++<StaticText: toe>
+| \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/list-ax.txt b/chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/list-ax-layout-ng.txt
index e8758ea0143..e8758ea0143 100644
--- a/chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/list-ax.txt
+++ b/chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/list-ax-layout-ng.txt
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 6e95e414eed..92306d44e69 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.cc
@@ -41,7 +41,7 @@ WorkletGlobalScopeProxy* AnimationWorklet::CreateGlobalScope() {
// initialization can move to the constructor. Currently, initialization
// in the constructor leads to test failures as the document frame has not
// been initialized at the time of the constructor call.
- Document* document = To<Document>(GetExecutionContext());
+ Document* document = Document::From(GetExecutionContext());
proxy_client_ =
AnimationWorkletProxyClient::FromDocument(document, worklet_id_);
}
@@ -62,7 +62,7 @@ WorkletAnimationId AnimationWorklet::NextWorkletAnimationId() {
return WorkletAnimationId(worklet_id_, ++last_animation_id_);
}
-void AnimationWorklet::Trace(blink::Visitor* visitor) {
+void AnimationWorklet::Trace(Visitor* visitor) {
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 0d02d29e045..2fcdf53ecfb 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 73cb238a07c..be7439f7da2 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(blink::Visitor* visitor) {
+void AnimationWorkletGlobalScope::Trace(Visitor* visitor) {
visitor->Trace(animator_definitions_);
visitor->Trace(animators_);
WorkletGlobalScope::Trace(visitor);
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 f03f90ea0ca..441e1dedbc5 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 f7f6ff6a8c2..ec81d0effa3 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(blink::Visitor* visitor) {
+void AnimationWorkletMessagingProxy::Trace(Visitor* visitor) {
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 a13f3627e5b..aed2d8a1dea 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 5587526e0f1..ab6bcd69778 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(blink::Visitor* visitor) {
+void AnimationWorkletProxyClient::Trace(Visitor* visitor) {
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 31fe8c68fcb..d9401b03d45 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 1956a7c19ef..ed94ad4a3e3 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(blink::Visitor* visitor) {
+void Animator::Trace(Visitor* visitor) {
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 bfafe9739cb..01678af53c9 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(blink::Visitor*);
+ void Trace(Visitor*);
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 a19cd4da65d..24e01f70b3c 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.cc
@@ -19,8 +19,6 @@ AnimatorDefinition::AnimatorDefinition(V8AnimatorConstructor* constructor,
DCHECK(animate_);
}
-AnimatorDefinition::~AnimatorDefinition() = default;
-
void AnimatorDefinition::Trace(Visitor* visitor) {
visitor->Trace(constructor_);
visitor->Trace(animate_);
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 09bf9c6d352..4a2e8dcb5e2 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.h
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.h
@@ -27,8 +27,7 @@ class MODULES_EXPORT AnimatorDefinition final
explicit AnimatorDefinition(V8AnimatorConstructor* constructor,
V8AnimateCallback* animate,
V8StateCallback* state);
- ~AnimatorDefinition();
- virtual void Trace(blink::Visitor* visitor);
+ virtual void Trace(Visitor* visitor);
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 c86f7630566..ef57f5dfab0 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
@@ -30,14 +30,14 @@ AnimationWorklet* CSSAnimationWorklet::animationWorklet(
// => ThreadedWorkletMessagingProxy
// => Document
// => ... => window
-void CSSAnimationWorklet::ContextDestroyed(ExecutionContext*) {
+void CSSAnimationWorklet::ContextDestroyed() {
animation_worklet_ = nullptr;
}
-void CSSAnimationWorklet::Trace(blink::Visitor* visitor) {
+void CSSAnimationWorklet::Trace(Visitor* visitor) {
visitor->Trace(animation_worklet_);
Supplement<LocalDOMWindow>::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
// static
@@ -53,7 +53,7 @@ CSSAnimationWorklet& CSSAnimationWorklet::From(LocalDOMWindow& window) {
}
CSSAnimationWorklet::CSSAnimationWorklet(Document* document)
- : ContextLifecycleObserver(document),
+ : ExecutionContextLifecycleObserver(document),
animation_worklet_(MakeGarbageCollected<AnimationWorklet>(document)) {
DCHECK(GetExecutionContext());
}
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 cb1583f5655..79f662672bd 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
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_ANIMATIONWORKLET_CSS_ANIMATION_WORKLET_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_ANIMATIONWORKLET_CSS_ANIMATION_WORKLET_H_
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/modules/animationworklet/animation_worklet.h"
#include "third_party/blink/renderer/modules/modules_export.h"
@@ -19,7 +19,7 @@ class Document;
class MODULES_EXPORT CSSAnimationWorklet final
: public GarbageCollected<CSSAnimationWorklet>,
public Supplement<LocalDOMWindow>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(CSSAnimationWorklet);
public:
@@ -29,9 +29,9 @@ class MODULES_EXPORT CSSAnimationWorklet final
explicit CSSAnimationWorklet(Document*);
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
static CSSAnimationWorklet& From(LocalDOMWindow&);
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/idls.gni b/chromium/third_party/blink/renderer/modules/animationworklet/idls.gni
new file mode 100644
index 00000000000..ea4eccf0cb6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/idls.gni
@@ -0,0 +1,12 @@
+# 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 = [
+ "animation_worklet_global_scope.idl",
+ "worklet_animation_effect.idl",
+ "worklet_animation.idl",
+ "worklet_group_effect.idl",
+]
+
+modules_dependency_idl_files = [ "css_animation_worklet.idl" ]
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 beb3bf5ebad..31ed4222b5f 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
@@ -6,8 +6,10 @@
#include "base/optional.h"
#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/bindings/core/v8/double_or_scroll_timeline_auto_keyword.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
#include "third_party/blink/renderer/bindings/modules/v8/animation_effect_or_animation_effect_sequence.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/animation/keyframe_effect_model.h"
#include "third_party/blink/renderer/core/animation/scroll_timeline.h"
@@ -21,6 +23,8 @@
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/modules/animationworklet/css_animation_worklet.h"
+#include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -37,21 +41,23 @@ bool ConvertAnimationEffects(
// Currently we only support KeyframeEffect.
if (effects.IsAnimationEffect()) {
auto* const effect = effects.GetAsAnimationEffect();
- if (!effect->IsKeyframeEffect()) {
+ auto* key_frame = DynamicTo<KeyframeEffect>(effect);
+ if (!key_frame) {
error_string = "Effect must be a KeyframeEffect object";
return false;
}
- keyframe_effects.push_back(ToKeyframeEffect(effect));
+ keyframe_effects.push_back(key_frame);
} else {
const HeapVector<Member<AnimationEffect>>& effect_sequence =
effects.GetAsAnimationEffectSequence();
keyframe_effects.ReserveInitialCapacity(effect_sequence.size());
for (const auto& effect : effect_sequence) {
- if (!effect->IsKeyframeEffect()) {
+ auto* key_frame = DynamicTo<KeyframeEffect>(*effect);
+ if (!key_frame) {
error_string = "Effects must all be KeyframeEffect objects";
return false;
}
- keyframe_effects.push_back(ToKeyframeEffect(effect));
+ keyframe_effects.push_back(key_frame);
}
}
@@ -118,14 +124,13 @@ bool CheckElementComposited(const Node& target) {
void StartEffectOnCompositor(CompositorAnimation* animation,
KeyframeEffect* effect) {
DCHECK(effect);
- DCHECK(effect->target());
- Element& target = *effect->target();
+ DCHECK(effect->EffectTarget());
+ Element& target = *effect->EffectTarget();
effect->Model()->SnapshotAllCompositorKeyframesIfNecessary(
target, target.ComputedStyleRef(), target.ParentComputedStyle());
int group = 0;
base::Optional<double> start_time = base::nullopt;
- double time_offset = 0;
// Normally the playback rate of a blink animation gets translated into
// equivalent playback rate of cc::KeyframeModels.
@@ -139,7 +144,7 @@ void StartEffectOnCompositor(CompositorAnimation* animation,
// it on animation. https://crbug.com/925373.
double playback_rate = 1;
- effect->StartAnimationOnCompositor(group, start_time, time_offset,
+ effect->StartAnimationOnCompositor(group, start_time, base::TimeDelta(),
playback_rate, animation);
}
@@ -173,7 +178,8 @@ WorkletAnimation* WorkletAnimation::Create(
const AnimationEffectOrAnimationEffectSequence& effects,
ExceptionState& exception_state) {
return Create(script_state, animator_name, effects,
- DocumentTimelineOrScrollTimeline(), nullptr, exception_state);
+ DocumentTimelineOrScrollTimeline(), ScriptValue(),
+ exception_state);
}
WorkletAnimation* WorkletAnimation::Create(
@@ -182,7 +188,7 @@ WorkletAnimation* WorkletAnimation::Create(
const AnimationEffectOrAnimationEffectSequence& effects,
DocumentTimelineOrScrollTimeline timeline,
ExceptionState& exception_state) {
- return Create(script_state, animator_name, effects, timeline, nullptr,
+ return Create(script_state, animator_name, effects, timeline, ScriptValue(),
exception_state);
}
WorkletAnimation* WorkletAnimation::Create(
@@ -190,7 +196,7 @@ WorkletAnimation* WorkletAnimation::Create(
String animator_name,
const AnimationEffectOrAnimationEffectSequence& effects,
DocumentTimelineOrScrollTimeline timeline,
- scoped_refptr<SerializedScriptValue> options,
+ const ScriptValue& options,
ExceptionState& exception_state) {
DCHECK(IsMainThread());
@@ -208,7 +214,7 @@ WorkletAnimation* WorkletAnimation::Create(
return nullptr;
}
- Document& document = *To<Document>(ExecutionContext::From(script_state));
+ Document& document = *Document::From(ExecutionContext::From(script_state));
if (!document.GetWorkletAnimationController().IsAnimatorRegistered(
animator_name)) {
exception_state.ThrowDOMException(
@@ -225,9 +231,20 @@ WorkletAnimation* WorkletAnimation::Create(
AnimationTimeline* animation_timeline =
ConvertAnimationTimeline(document, timeline);
+ scoped_refptr<SerializedScriptValue> animation_options;
+ if (!options.IsEmpty()) {
+ animation_options = SerializedScriptValue::Serialize(
+ script_state->GetIsolate(), options.V8Value(),
+ SerializedScriptValue::SerializeOptions(
+ SerializedScriptValue::kNotForStorage),
+ exception_state);
+ if (exception_state.HadException())
+ return nullptr;
+ }
+
WorkletAnimation* animation = MakeGarbageCollected<WorkletAnimation>(
id, animator_name, document, keyframe_effects, animation_timeline,
- std::move(options));
+ std::move(animation_options));
return animation;
}
@@ -266,7 +283,7 @@ WorkletAnimation::WorkletAnimation(
effect_timings_ = std::make_unique<WorkletAnimationEffectTimings>(timings);
if (timeline_->IsScrollTimeline())
- timeline_->AnimationAttached(nullptr);
+ To<ScrollTimeline>(*timeline_).WorkletAnimationAttached();
}
String WorkletAnimation::playState() {
@@ -306,7 +323,7 @@ void WorkletAnimation::play(ExceptionState& exception_state) {
has_started_ = true;
for (auto& effect : effects_) {
- Element* target = effect->target();
+ Element* target = effect->EffectTarget();
if (!target)
continue;
@@ -320,6 +337,22 @@ void WorkletAnimation::play(ExceptionState& exception_state) {
}
}
+base::Optional<double> WorkletAnimation::currentTime() {
+ base::Optional<base::TimeDelta> current_time = CurrentTime();
+ if (!current_time)
+ return base::nullopt;
+ return ToMilliseconds(current_time.value());
+}
+
+base::Optional<double> WorkletAnimation::startTime() {
+ // The timeline may have become newly active or inactive, which then can cause
+ // the start time to change.
+ UpdateCurrentTimeIfNeeded();
+ if (!start_time_)
+ return base::nullopt;
+ return ToMilliseconds(start_time_.value());
+}
+
double WorkletAnimation::currentTime(bool& is_null) {
base::Optional<base::TimeDelta> current_time = CurrentTime();
is_null = !current_time.has_value();
@@ -379,7 +412,7 @@ void WorkletAnimation::cancel() {
SetCurrentTime(base::nullopt);
for (auto& effect : effects_) {
- Element* target = effect->target();
+ Element* target = effect->EffectTarget();
if (!target)
continue;
// TODO(yigu): Currently we have to keep a set of worklet animations in
@@ -416,10 +449,11 @@ void WorkletAnimation::setPlaybackRate(ScriptState* script_state,
if (!playback_rate) {
if (document_->GetFrame() && ExecutionContext::From(script_state)) {
document_->GetFrame()->Console().AddMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning,
- "WorkletAnimation currently does not support "
- "playback rate of Zero."));
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning,
+ "WorkletAnimation currently does not support "
+ "playback rate of Zero."));
}
return;
}
@@ -545,10 +579,10 @@ bool WorkletAnimation::CanStartOnCompositor() {
return false;
}
- if (!GetEffect()->target())
+ if (!GetEffect()->EffectTarget())
return false;
- Element& target = *GetEffect()->target();
+ Element& target = *GetEffect()->EffectTarget();
// TODO(crbug.com/836393): This should not be possible but it is currently
// happening and needs to be investigated/fixed.
@@ -573,7 +607,7 @@ bool WorkletAnimation::CanStartOnCompositor() {
// If the scroll source is not composited, fall back to main thread.
if (timeline_->IsScrollTimeline() &&
!CheckElementComposited(
- *ToScrollTimeline(timeline_)->ResolvedScrollSource())) {
+ *To<ScrollTimeline>(*timeline_).ResolvedScrollSource())) {
return false;
}
@@ -600,18 +634,21 @@ bool WorkletAnimation::StartOnCompositor() {
// offset information.
compositor_animation_ = CompositorAnimation::CreateWorkletAnimation(
id_, animator_name_, playback_rate_,
- scroll_timeline_util::ToCompositorScrollTimeline(timeline_),
std::move(options_), std::move(effect_timings_));
compositor_animation_->SetAnimationDelegate(this);
}
// Register ourselves on the compositor timeline. This will cause our cc-side
// animation animation to be registered.
- if (CompositorAnimationTimeline* compositor_timeline =
- document_->Timeline().CompositorTimeline())
+ CompositorAnimationTimeline* compositor_timeline =
+ timeline_ ? timeline_->EnsureCompositorTimeline() : nullptr;
+ if (compositor_timeline) {
compositor_timeline->AnimationAttached(*this);
+ if (compositor_timeline->GetAnimationTimeline()->IsScrollTimeline())
+ document_->AttachCompositorTimeline(compositor_timeline);
+ }
- CompositorAnimations::AttachCompositedLayers(*GetEffect()->target(),
+ CompositorAnimations::AttachCompositedLayers(*GetEffect()->EffectTarget(),
compositor_animation_.get());
// TODO(smcgruer): We need to start all of the effects, not just the first.
@@ -644,7 +681,7 @@ bool WorkletAnimation::UpdateOnCompositor() {
}
if (timeline_->IsScrollTimeline()) {
- Node* scroll_source = ToScrollTimeline(timeline_)->ResolvedScrollSource();
+ Node* scroll_source = To<ScrollTimeline>(*timeline_).ResolvedScrollSource();
LayoutBox* box = scroll_source ? scroll_source->GetLayoutBox() : nullptr;
base::Optional<double> start_scroll_offset;
@@ -652,14 +689,15 @@ bool WorkletAnimation::UpdateOnCompositor() {
if (box) {
double current_offset;
double max_offset;
- ToScrollTimeline(timeline_)->GetCurrentAndMaxOffset(box, current_offset,
- max_offset);
+ To<ScrollTimeline>(*timeline_)
+ .GetCurrentAndMaxOffset(box, current_offset, max_offset);
double resolved_start_scroll_offset = 0;
double resolved_end_scroll_offset = max_offset;
- ToScrollTimeline(timeline_)->ResolveScrollStartAndEnd(
- box, max_offset, resolved_start_scroll_offset,
- resolved_end_scroll_offset);
+ To<ScrollTimeline>(*timeline_)
+ .ResolveScrollStartAndEnd(box, max_offset,
+ resolved_start_scroll_offset,
+ resolved_end_scroll_offset);
start_scroll_offset = resolved_start_scroll_offset;
end_scroll_offset = resolved_end_scroll_offset;
}
@@ -675,11 +713,17 @@ void WorkletAnimation::DestroyCompositorAnimation() {
if (compositor_animation_ && compositor_animation_->IsElementAttached())
compositor_animation_->DetachElement();
- if (CompositorAnimationTimeline* compositor_timeline =
- document_->Timeline().CompositorTimeline())
+ CompositorAnimationTimeline* compositor_timeline =
+ timeline_ ? timeline_->CompositorTimeline() : nullptr;
+ if (compositor_timeline)
compositor_timeline->AnimationDestroyed(*this);
if (compositor_animation_) {
+ if (compositor_timeline &&
+ compositor_timeline->GetAnimationTimeline()->IsScrollTimeline()) {
+ document_->DetachCompositorTimeline(compositor_timeline);
+ }
+
compositor_animation_->SetAnimationDelegate(nullptr);
compositor_animation_ = nullptr;
}
@@ -734,8 +778,6 @@ base::Optional<base::TimeDelta> WorkletAnimation::InitialCurrentTime() const {
}
void WorkletAnimation::UpdateCurrentTimeIfNeeded() {
- DCHECK(play_state_ != Animation::kIdle && play_state_ != Animation::kUnset);
-
bool is_timeline_active = IsTimelineActive();
if (is_timeline_active != was_timeline_active_) {
if (is_timeline_active) {
@@ -852,11 +894,11 @@ void WorkletAnimation::NotifyLocalTimeUpdated(
void WorkletAnimation::Dispose() {
DCHECK(IsMainThread());
if (timeline_->IsScrollTimeline())
- timeline_->AnimationDetached(nullptr);
+ To<ScrollTimeline>(*timeline_).WorkletAnimationDetached();
DestroyCompositorAnimation();
}
-void WorkletAnimation::Trace(blink::Visitor* visitor) {
+void WorkletAnimation::Trace(Visitor* visitor) {
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 6b0cf233d50..e23055fa45f 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.h
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.h
@@ -22,6 +22,7 @@
namespace blink {
class AnimationEffectOrAnimationEffectSequence;
+class ScriptValue;
class SerializedScriptValue;
// The main-thread controller for a single AnimationWorklet animator instance.
@@ -60,7 +61,7 @@ class MODULES_EXPORT WorkletAnimation : public WorkletAnimationBase,
String animator_name,
const AnimationEffectOrAnimationEffectSequence&,
DocumentTimelineOrScrollTimeline,
- scoped_refptr<SerializedScriptValue>,
+ const ScriptValue& options,
ExceptionState&);
WorkletAnimation(WorkletAnimationId id,
@@ -68,15 +69,18 @@ class MODULES_EXPORT WorkletAnimation : public WorkletAnimationBase,
Document&,
const HeapVector<Member<KeyframeEffect>>&,
AnimationTimeline*,
- scoped_refptr<SerializedScriptValue>);
+ scoped_refptr<SerializedScriptValue> options);
~WorkletAnimation() override = default;
String animatorName() { return animator_name_; }
AnimationEffect* effect() { return GetEffect(); }
AnimationTimeline* timeline() { return timeline_; }
String playState();
- double currentTime(bool& is_null);
- double startTime(bool& is_null);
+ base::Optional<double> currentTime();
+ base::Optional<double> startTime();
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ double currentTime(bool& is_null); // DEPRECATED
+ double startTime(bool& is_null); // DEPRECATED
double playbackRate(ScriptState* script_state) const;
void setPlaybackRate(ScriptState* script_state, double playback_rate);
@@ -91,9 +95,13 @@ class MODULES_EXPORT WorkletAnimation : public WorkletAnimationBase,
// relevant to CSS animations which means it does not have any material effect
// on worklet animations either way.
bool IsEventDispatchAllowed() const override { return true; }
- // Effect supression is used by devtool's animation inspection machinery which
- // is not currently supported by worklet animations.
+ // Effect suppression is used by devtool's animation inspection machinery
+ // which is not currently supported by worklet animations.
bool EffectSuppressed() const override { return false; }
+ // Worklet animations are not currently replaceable.
+ // TODO(crbug.com/833846): Make replaceable once a proper subclass of
+ // Animation.
+ bool ReplaceStateRemoved() const override { return false; }
void EffectInvalidated() override;
void UpdateIfNecessary() override;
@@ -135,7 +143,7 @@ class MODULES_EXPORT WorkletAnimation : public WorkletAnimationBase,
running_on_main_thread_ = running_on_main_thread;
}
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void Dispose();
private:
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.idl b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.idl
index f4be44451ab..b706b5ea625 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.idl
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.idl
@@ -7,15 +7,13 @@
// TODO(840383): Accodring to the specification |effects| is optional and
// defaults to null. Match that here.
[
- Constructor(DOMString animatorName,
- (AnimationEffect or sequence<AnimationEffect>) effects,
- optional (DocumentTimeline or ScrollTimeline) timeline,
- optional SerializedScriptValue options),
- RaisesException=Constructor,
- ConstructorCallWith=ScriptState,
- MeasureAs=WorkletAnimationConstructor,
RuntimeEnabled=AnimationWorklet
] interface WorkletAnimation {
+ [CallWith=ScriptState, RaisesException, MeasureAs=WorkletAnimationConstructor]
+ constructor(DOMString animatorName,
+ (AnimationEffect or sequence<AnimationEffect>) effects,
+ optional (DocumentTimeline or ScrollTimeline) timeline,
+ optional any options);
readonly attribute DOMString animatorName;
readonly attribute AnimationEffect? effect;
readonly attribute AnimationTimeline? timeline;
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 887b0a31ede..0257585c584 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
@@ -3,7 +3,7 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.h"
-#include "third_party/blink/renderer/core/animation/computed_effect_timing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_computed_effect_timing.h"
#include "third_party/blink/renderer/core/animation/timing_calculations.h"
namespace blink {
@@ -44,6 +44,31 @@ ComputedEffectTiming* WorkletAnimationEffect::getComputedTiming() const {
/*is_keyframe_effect*/ false);
}
+base::Optional<double> WorkletAnimationEffect::localTime() const {
+ if (!local_time_)
+ return base::nullopt;
+ return local_time_.value().InMillisecondsF();
+}
+
+void WorkletAnimationEffect::setLocalTime(base::Optional<double> time_ms) {
+ if (!time_ms) {
+ local_time_.reset();
+ return;
+ }
+ DCHECK(!std::isnan(time_ms.value()));
+ // Convert double to base::TimeDelta because cc/animation expects
+ // base::TimeDelta.
+ //
+ // Note on precision loss: base::TimeDelta has microseconds precision which is
+ // also the precision recommended by the web animation specification as well
+ // [1]. If the input time value has a bigger precision then the conversion
+ // causes precision loss. Doing the conversion here ensures that reading the
+ // value back provides the actual value we use in further computation which
+ // is the least surprising path.
+ // [1] https://drafts.csswg.org/web-animations/#precision-of-time-values
+ local_time_ = base::TimeDelta::FromMillisecondsD(time_ms.value());
+}
+
void WorkletAnimationEffect::setLocalTime(double time_ms, bool is_null) {
if (is_null) {
local_time_.reset();
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.h b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.h
index a04fee47a96..0c4b990fa7f 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.h
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.h
@@ -30,8 +30,11 @@ class MODULES_EXPORT WorkletAnimationEffect : public ScriptWrappable {
EffectTiming* getTiming() const;
ComputedEffectTiming* getComputedTiming() const;
- void setLocalTime(double time_ms, bool is_null);
- double localTime(bool& is_null) const;
+ base::Optional<double> localTime() const;
+ void setLocalTime(base::Optional<double> time_ms);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ void setLocalTime(double time_ms, bool is_null); // DEPRECATED
+ double localTime(bool& is_null) const; // DEPRECATED
base::Optional<base::TimeDelta> local_time() const;
private:
diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc
index 4f652345ad0..975b17ff2fb 100644
--- a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc
+++ b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc
@@ -8,8 +8,11 @@
#include <utility>
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/core/v8/double_or_scroll_timeline_auto_keyword.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_scroll_timeline_options.h"
#include "third_party/blink/renderer/bindings/modules/v8/animation_effect_or_animation_effect_sequence.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/animation/keyframe_effect.h"
#include "third_party/blink/renderer/core/animation/keyframe_effect_model.h"
@@ -67,12 +70,11 @@ WorkletAnimation* CreateWorkletAnimation(
DocumentTimelineOrScrollTimeline timeline;
if (scroll_timeline)
timeline.SetScrollTimeline(scroll_timeline);
- scoped_refptr<SerializedScriptValue> options;
+ ScriptValue options;
ScriptState::Scope scope(script_state);
return WorkletAnimation::Create(script_state, animator_name, effects,
- timeline, std::move(options),
- ASSERT_NO_EXCEPTION);
+ timeline, options, ASSERT_NO_EXCEPTION);
}
base::TimeDelta ToTimeDelta(double milliseconds) {
@@ -179,7 +181,8 @@ TEST_F(WorkletAnimationTest,
ASSERT_TRUE(scroller->HasOverflowClip());
PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea();
ASSERT_TRUE(scrollable_area);
- scrollable_area->SetScrollOffset(ScrollOffset(0, 20), kProgrammaticScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 20),
+ mojom::blink::ScrollType::kProgrammatic);
ScrollTimelineOptions* options = ScrollTimelineOptions::Create();
DoubleOrScrollTimelineAutoKeyword time_range =
DoubleOrScrollTimelineAutoKeyword::FromDouble(100);
@@ -193,12 +196,18 @@ TEST_F(WorkletAnimationTest,
worklet_animation->play(ASSERT_NO_EXCEPTION);
worklet_animation->UpdateCompositingState();
- scrollable_area->SetScrollOffset(ScrollOffset(0, 40), kProgrammaticScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 40),
+ mojom::blink::ScrollType::kProgrammatic);
+ // Simulate a new animation frame which allows the timeline to compute new
+ // current time.
+ GetPage().Animator().ServiceScriptedAnimations(base::TimeTicks::Now());
bool is_null;
EXPECT_TIME_NEAR(40, worklet_animation->currentTime(is_null));
- scrollable_area->SetScrollOffset(ScrollOffset(0, 70), kProgrammaticScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 70),
+ mojom::blink::ScrollType::kProgrammatic);
+ GetPage().Animator().ServiceScriptedAnimations(base::TimeTicks::Now());
EXPECT_TIME_NEAR(70, worklet_animation->currentTime(is_null));
}
@@ -288,7 +297,8 @@ TEST_F(WorkletAnimationTest, ScrollTimelineSetPlaybackRate) {
ASSERT_TRUE(scroller->HasOverflowClip());
PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea();
ASSERT_TRUE(scrollable_area);
- scrollable_area->SetScrollOffset(ScrollOffset(0, 20), kProgrammaticScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 20),
+ mojom::blink::ScrollType::kProgrammatic);
ScrollTimelineOptions* options = ScrollTimelineOptions::Create();
DoubleOrScrollTimelineAutoKeyword time_range =
DoubleOrScrollTimelineAutoKeyword::FromDouble(100);
@@ -312,8 +322,11 @@ TEST_F(WorkletAnimationTest, ScrollTimelineSetPlaybackRate) {
EXPECT_TIME_NEAR(40, worklet_animation->currentTime(is_null));
// Update scroll offset.
- scrollable_area->SetScrollOffset(ScrollOffset(0, 40), kProgrammaticScroll);
-
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 40),
+ mojom::blink::ScrollType::kProgrammatic);
+ // Simulate a new animation frame which allows the timeline to compute new
+ // current time.
+ GetPage().Animator().ServiceScriptedAnimations(base::TimeTicks::Now());
// Verify that the current time is updated playback_rate faster than the
// timeline time.
EXPECT_TIME_NEAR(40 + 20 * playback_rate,
@@ -357,11 +370,17 @@ TEST_F(WorkletAnimationTest, ScrollTimelineSetPlaybackRateWhilePlaying) {
worklet_animation->UpdateCompositingState();
// Update scroll offset and playback rate.
- scrollable_area->SetScrollOffset(ScrollOffset(0, 40), kProgrammaticScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 40),
+ mojom::blink::ScrollType::kProgrammatic);
+ // Simulate a new animation frame which allows the timeline to compute new
+ // current time.
+ GetPage().Animator().ServiceScriptedAnimations(base::TimeTicks::Now());
worklet_animation->setPlaybackRate(GetScriptState(), playback_rate);
// Verify the current time after another scroll offset update.
- scrollable_area->SetScrollOffset(ScrollOffset(0, 80), kProgrammaticScroll);
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 80),
+ mojom::blink::ScrollType::kProgrammatic);
+ GetPage().Animator().ServiceScriptedAnimations(base::TimeTicks::Now());
bool is_null;
EXPECT_TIME_NEAR(40 + 40 * playback_rate,
worklet_animation->currentTime(is_null));
@@ -412,6 +431,9 @@ TEST_F(WorkletAnimationTest, ScrollTimelineNewlyActive) {
scroller_element->setAttribute(html_names::kStyleAttr,
"overflow:scroll;width:100px;height:100px;");
UpdateAllLifecyclePhasesForTest();
+ // Simulate a new animation frame which allows the timeline to compute new
+ // current time.
+ GetPage().Animator().ServiceScriptedAnimations(base::TimeTicks::Now());
ASSERT_TRUE(scroll_timeline->IsActive());
// As the timeline becomes newly active, start and current time must be
@@ -454,8 +476,11 @@ TEST_F(WorkletAnimationTest, ScrollTimelineNewlyInactive) {
ASSERT_TRUE(scroller->HasOverflowClip());
PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea();
ASSERT_TRUE(scrollable_area);
- scrollable_area->SetScrollOffset(ScrollOffset(0, 40), kProgrammaticScroll);
-
+ scrollable_area->SetScrollOffset(ScrollOffset(0, 40),
+ mojom::blink::ScrollType::kProgrammatic);
+ // Simulate a new animation frame which allows the timeline to compute new
+ // current time.
+ GetPage().Animator().ServiceScriptedAnimations(base::TimeTicks::Now());
WorkletAnimation* worklet_animation = CreateWorkletAnimation(
GetScriptState(), element_, animator_name_, scroll_timeline);
@@ -478,6 +503,7 @@ TEST_F(WorkletAnimationTest, ScrollTimelineNewlyInactive) {
scroller_element->setAttribute(html_names::kStyleAttr,
"overflow:visible;width:100px;height:100px;");
UpdateAllLifecyclePhasesForTest();
+ GetPage().Animator().ServiceScriptedAnimations(base::TimeTicks::Now());
ASSERT_FALSE(scroll_timeline->IsActive());
// As the timeline becomes newly inactive, start time must be unresolved and
@@ -492,6 +518,7 @@ TEST_F(WorkletAnimationTest, ScrollTimelineNewlyInactive) {
scroller_element->setAttribute(html_names::kStyleAttr,
"overflow:scroll;width:100px;height:100px;");
UpdateAllLifecyclePhasesForTest();
+ GetPage().Animator().ServiceScriptedAnimations(base::TimeTicks::Now());
ASSERT_TRUE(scroll_timeline->IsActive());
// As the timeline becomes newly active, start time must be recalculated and
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 fc42f92dda7..5ed3e613a84 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(blink::Visitor* visitor) {
+void WorkletGroupEffect::Trace(Visitor* visitor) {
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 e1f205f9ac8..1158288db5c 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
HeapVector<Member<WorkletAnimationEffect>> effects_;
diff --git a/chromium/third_party/blink/renderer/modules/app_banner/DEPS b/chromium/third_party/blink/renderer/modules/app_banner/DEPS
deleted file mode 100644
index f7f67cd78e0..00000000000
--- a/chromium/third_party/blink/renderer/modules/app_banner/DEPS
+++ /dev/null
@@ -1,4 +0,0 @@
-include_rules = [
- "+mojo/public/cpp/bindings/binding.h",
- "+mojo/public/cpp/bindings/strong_binding.h",
-]
diff --git a/chromium/third_party/blink/renderer/modules/app_banner/OWNERS b/chromium/third_party/blink/renderer/modules/app_banner/OWNERS
index d5bee6b2c8e..a49cda5f559 100644
--- a/chromium/third_party/blink/renderer/modules/app_banner/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/app_banner/OWNERS
@@ -1,4 +1,4 @@
dominickn@chromium.org
mlamouri@chromium.org
-# COMPONENT: Content>WebApps
+# COMPONENT: UI>Browser>WebAppInstalls
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 386af6a6abc..358d21b99d0 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
@@ -4,11 +4,12 @@
#include "third_party/blink/renderer/modules/app_banner/before_install_prompt_event.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_before_install_prompt_event_init.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/web_feature.h"
-#include "third_party/blink/renderer/modules/app_banner/before_install_prompt_event_init.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/instrumentation/use_counter.h"
@@ -21,16 +22,14 @@ BeforeInstallPromptEvent::BeforeInstallPromptEvent(
mojo::PendingReceiver<mojom::blink::AppBannerEvent> event_receiver,
const Vector<String>& platforms)
: Event(name, Bubbles::kNo, Cancelable::kYes),
- ContextClient(&frame),
+ ExecutionContextClient(&frame),
banner_service_remote_(std::move(service_remote)),
receiver_(this,
std::move(event_receiver),
frame.GetTaskRunner(TaskType::kApplicationLifeCycle)),
platforms_(platforms),
user_choice_(MakeGarbageCollected<UserChoiceProperty>(
- frame.GetDocument(),
- this,
- UserChoiceProperty::kUserChoice)) {
+ frame.GetDocument()->ToExecutionContext())) {
DCHECK(banner_service_remote_);
DCHECK(receiver_.is_bound());
UseCounter::Count(frame.GetDocument(), WebFeature::kBeforeInstallPromptEvent);
@@ -40,7 +39,7 @@ BeforeInstallPromptEvent::BeforeInstallPromptEvent(
ExecutionContext* execution_context,
const AtomicString& name,
const BeforeInstallPromptEventInit* init)
- : Event(name, init), ContextClient(execution_context) {
+ : Event(name, init), ExecutionContextClient(execution_context) {
if (init->hasPlatforms())
platforms_ = init->platforms();
}
@@ -56,39 +55,41 @@ Vector<String> BeforeInstallPromptEvent::platforms() const {
return platforms_;
}
-ScriptPromise BeforeInstallPromptEvent::userChoice(ScriptState* script_state) {
+ScriptPromise BeforeInstallPromptEvent::userChoice(
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
UseCounter::Count(ExecutionContext::From(script_state),
WebFeature::kBeforeInstallPromptEventUserChoice);
// |m_binding| must be bound to allow the AppBannerService to resolve the
// userChoice promise.
if (user_choice_ && receiver_.is_bound())
return user_choice_->Promise(script_state->World());
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "userChoice cannot be accessed on this event."));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "userChoice cannot be accessed on this event.");
+ return ScriptPromise();
}
-ScriptPromise BeforeInstallPromptEvent::prompt(ScriptState* script_state) {
+ScriptPromise BeforeInstallPromptEvent::prompt(
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
// |m_bannerService| must be bound to allow us to inform the AppBannerService
// to display the banner now.
if (!banner_service_remote_.is_bound()) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "The prompt() method cannot be called."));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "The prompt() method cannot be called.");
+ return ScriptPromise();
}
ExecutionContext* context = ExecutionContext::From(script_state);
- Document* doc = To<Document>(context);
+ Document* doc = Document::From(context);
if (!LocalFrame::ConsumeTransientUserActivation(doc ? doc->GetFrame()
: nullptr)) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotAllowedError,
- "The prompt() method must be called with a user gesture"));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotAllowedError,
+ "The prompt() method must be called with a user gesture");
+ return ScriptPromise();
}
UseCounter::Count(context, WebFeature::kBeforeInstallPromptEventPrompt);
@@ -110,7 +111,7 @@ void BeforeInstallPromptEvent::preventDefault() {
bool BeforeInstallPromptEvent::HasPendingActivity() const {
return user_choice_ &&
- user_choice_->GetState() == ScriptPromisePropertyBase::kPending;
+ user_choice_->GetState() == UserChoiceProperty::kPending;
}
void BeforeInstallPromptEvent::BannerAccepted(const String& platform) {
@@ -127,10 +128,10 @@ void BeforeInstallPromptEvent::BannerDismissed() {
user_choice_->Resolve(result);
}
-void BeforeInstallPromptEvent::Trace(blink::Visitor* visitor) {
+void BeforeInstallPromptEvent::Trace(Visitor* visitor) {
visitor->Trace(user_choice_);
Event::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 80a681fd178..842a40dd0d5 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
@@ -12,26 +12,25 @@
#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/core/v8/script_promise_property.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_app_banner_prompt_result.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
-#include "third_party/blink/renderer/modules/app_banner/app_banner_prompt_result.h"
#include "third_party/blink/renderer/modules/event_modules.h"
namespace blink {
class BeforeInstallPromptEvent;
class BeforeInstallPromptEventInit;
+class ExceptionState;
-using UserChoiceProperty =
- ScriptPromiseProperty<Member<BeforeInstallPromptEvent>,
- Member<AppBannerPromptResult>,
- ToV8UndefinedGenerator>;
+using UserChoiceProperty = ScriptPromiseProperty<Member<AppBannerPromptResult>,
+ ToV8UndefinedGenerator>;
class BeforeInstallPromptEvent final
: public Event,
public mojom::blink::AppBannerEvent,
public ActiveScriptWrappable<BeforeInstallPromptEvent>,
- public ContextClient {
+ public ExecutionContextClient {
DEFINE_WRAPPERTYPEINFO();
USING_PRE_FINALIZER(BeforeInstallPromptEvent, Dispose);
USING_GARBAGE_COLLECTED_MIXIN(BeforeInstallPromptEvent);
@@ -69,8 +68,8 @@ class BeforeInstallPromptEvent final
void Dispose();
Vector<String> platforms() const;
- ScriptPromise userChoice(ScriptState*);
- ScriptPromise prompt(ScriptState*);
+ ScriptPromise userChoice(ScriptState*, ExceptionState&);
+ ScriptPromise prompt(ScriptState*, ExceptionState&);
const AtomicString& InterfaceName() const override;
void preventDefault() override;
@@ -78,7 +77,7 @@ class BeforeInstallPromptEvent final
// ScriptWrappable
bool HasPendingActivity() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
// mojom::blink::AppBannerEvent methods:
@@ -91,14 +90,6 @@ class BeforeInstallPromptEvent final
Member<UserChoiceProperty> user_choice_;
};
-DEFINE_TYPE_CASTS(BeforeInstallPromptEvent,
- Event,
- event,
- event->InterfaceName() ==
- event_interface_names::kBeforeInstallPromptEvent,
- event.InterfaceName() ==
- event_interface_names::kBeforeInstallPromptEvent);
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_APP_BANNER_BEFORE_INSTALL_PROMPT_EVENT_H_
diff --git a/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.idl b/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.idl
index 2111f2e3863..73d24267bb3 100644
--- a/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.idl
+++ b/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.idl
@@ -3,11 +3,10 @@
// found in the LICENSE file.
[
- ActiveScriptWrappable,
- Constructor(DOMString type, optional BeforeInstallPromptEventInit eventInitDict),
- ConstructorCallWith=ExecutionContext
+ ActiveScriptWrappable
] interface BeforeInstallPromptEvent : Event {
+ [CallWith=ExecutionContext] constructor(DOMString type, optional BeforeInstallPromptEventInit eventInitDict = {});
readonly attribute FrozenArray<DOMString> platforms;
- [CallWith=ScriptState] readonly attribute Promise<AppBannerPromptResult> userChoice;
- [CallWith=ScriptState] Promise<void> prompt();
+ [CallWith=ScriptState, RaisesException] readonly attribute Promise<AppBannerPromptResult> userChoice;
+ [CallWith=ScriptState, RaisesException] Promise<void> prompt();
};
diff --git a/chromium/third_party/blink/renderer/modules/app_banner/idls.gni b/chromium/third_party/blink/renderer/modules/app_banner/idls.gni
new file mode 100644
index 00000000000..e89d9712f90
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/app_banner/idls.gni
@@ -0,0 +1,12 @@
+# 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 = [ "before_install_prompt_event.idl" ]
+
+modules_dictionary_idl_files = [
+ "app_banner_prompt_result.idl",
+ "before_install_prompt_event_init.idl",
+]
+
+modules_dependency_idl_files = [ "window_installation.idl" ]
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 500e08eb998..93112054cdb 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void DoSetSinkId();
@@ -117,7 +117,7 @@ void SetSinkIdResolver::DoSetSinkId() {
}
// This is associated with an HTML element, so the context must be a Document.
- auto& document = To<Document>(*context);
+ auto& document = Document::From(*context);
WebLocalFrameImpl* web_frame =
WebLocalFrameImpl::FromFrame(document.GetFrame());
if (web_frame && web_frame->Client()) {
@@ -147,7 +147,7 @@ void SetSinkIdResolver::OnSetSinkIdComplete(
Resolve();
}
-void SetSinkIdResolver::Trace(blink::Visitor* visitor) {
+void SetSinkIdResolver::Trace(Visitor* visitor) {
visitor->Trace(element_);
ScriptPromiseResolver::Trace(visitor);
}
@@ -196,7 +196,7 @@ HTMLMediaElementAudioOutputDevice& HTMLMediaElementAudioOutputDevice::From(
return *supplement;
}
-void HTMLMediaElementAudioOutputDevice::Trace(blink::Visitor* visitor) {
+void HTMLMediaElementAudioOutputDevice::Trace(Visitor* visitor) {
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 f974bc49147..22f7bfb8aa7 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
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_AUDIO_OUTPUT_DEVICES_HTML_MEDIA_ELEMENT_AUDIO_OUTPUT_DEVICE_H_
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -27,7 +27,7 @@ class MODULES_EXPORT HTMLMediaElementAudioOutputDevice final
HTMLMediaElementAudioOutputDevice();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
static String sinkId(HTMLMediaElement&);
static ScriptPromise setSinkId(ScriptState*,
HTMLMediaElement&,
diff --git a/chromium/third_party/blink/renderer/modules/audio_output_devices/idls.gni b/chromium/third_party/blink/renderer/modules/audio_output_devices/idls.gni
new file mode 100644
index 00000000000..4af27b2c208
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/audio_output_devices/idls.gni
@@ -0,0 +1,5 @@
+# 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_dependency_idl_files = [ "html_media_element_audio_output_device.idl" ]
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/BUILD.gn b/chromium/third_party/blink/renderer/modules/background_fetch/BUILD.gn
index b186dbfab09..27e1392cb28 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/BUILD.gn
@@ -27,7 +27,5 @@ blink_modules_sources("background_fetch") {
"service_worker_registration_background_fetch.h",
]
- public_deps = [
- "//third_party/blink/renderer/modules/service_worker",
- ]
+ public_deps = [ "//third_party/blink/renderer/modules/service_worker" ]
}
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 d4bbd67a010..16a7f5e5a38 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
@@ -6,12 +6,11 @@
#include <utility>
-#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
-#include "third_party/blink/renderer/modules/background_fetch/background_fetch_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_background_fetch_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_image_resource.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.h"
-#include "third_party/blink/renderer/modules/manifest/image_resource.h"
namespace blink {
@@ -38,10 +37,16 @@ const char BackgroundFetchBridge::kSupplementName[] = "BackgroundFetchBridge";
BackgroundFetchBridge::BackgroundFetchBridge(
ServiceWorkerRegistration& registration)
- : Supplement<ServiceWorkerRegistration>(registration) {}
+ : Supplement<ServiceWorkerRegistration>(registration),
+ background_fetch_service_(registration.GetExecutionContext()) {}
BackgroundFetchBridge::~BackgroundFetchBridge() = default;
+void BackgroundFetchBridge::Trace(Visitor* visitor) {
+ visitor->Trace(background_fetch_service_);
+ Supplement::Trace(visitor);
+}
+
void BackgroundFetchBridge::GetIconDisplaySize(
GetIconDisplaySizeCallback callback) {
GetService()->GetIconDisplaySize(std::move(callback));
@@ -93,7 +98,7 @@ void BackgroundFetchBridge::GetDeveloperIds(GetDeveloperIdsCallback callback) {
}
mojom::blink::BackgroundFetchService* BackgroundFetchBridge::GetService() {
- if (!background_fetch_service_) {
+ if (!background_fetch_service_.is_bound()) {
auto receiver = background_fetch_service_.BindNewPipeAndPassReceiver(
GetSupplementable()->GetExecutionContext()->GetTaskRunner(
TaskType::kBackgroundFetch));
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 dd17dd1a725..76a75654405 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
@@ -8,10 +8,10 @@
#include <memory>
#include "base/macros.h"
-#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/background_fetch/background_fetch.mojom-blink.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_registration.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/supplementable.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -38,12 +38,13 @@ class BackgroundFetchBridge final
using RegistrationCallback =
base::OnceCallback<void(mojom::blink::BackgroundFetchError,
BackgroundFetchRegistration*)>;
- using GetIconDisplaySizeCallback = base::OnceCallback<void(const WebSize&)>;
+ using GetIconDisplaySizeCallback = base::OnceCallback<void(const gfx::Size&)>;
static BackgroundFetchBridge* From(ServiceWorkerRegistration* registration);
explicit BackgroundFetchBridge(ServiceWorkerRegistration& registration);
virtual ~BackgroundFetchBridge();
+ void Trace(Visitor* visitor) override;
// Creates a new Background Fetch registration identified by |developer_id|
// for the sequence of |requests|. The |callback| will be invoked when the
@@ -80,7 +81,8 @@ class BackgroundFetchBridge final
mojom::blink::BackgroundFetchError error,
mojom::blink::BackgroundFetchRegistrationPtr registration_ptr);
- mojo::Remote<mojom::blink::BackgroundFetchService> background_fetch_service_;
+ HeapMojoRemote<mojom::blink::BackgroundFetchService>
+ background_fetch_service_;
DISALLOW_COPY_AND_ASSIGN(BackgroundFetchBridge);
};
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 a6e899abb96..e35a0cea225 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
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_event.h"
-#include "third_party/blink/renderer/modules/background_fetch/background_fetch_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_background_fetch_event_init.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h"
#include "third_party/blink/renderer/modules/event_interface_modules_names.h"
@@ -27,7 +27,7 @@ const AtomicString& BackgroundFetchEvent::InterfaceName() const {
return event_interface_names::kBackgroundFetchEvent;
}
-void BackgroundFetchEvent::Trace(blink::Visitor* visitor) {
+void BackgroundFetchEvent::Trace(Visitor* visitor) {
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 d41ace1757b..40897e54024 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(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
protected:
// Corresponds to the 'registration' attribute in the idl.
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.idl
index e4c633e4e3c..a2f27767964 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.idl
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.idl
@@ -5,9 +5,9 @@
// https://wicg.github.io/background-fetch/#background-fetch-event
[
- Constructor(DOMString type, BackgroundFetchEventInit init),
Exposed=ServiceWorker,
RuntimeEnabled=BackgroundFetch
] interface BackgroundFetchEvent : ExtendableEvent {
+ constructor(DOMString type, BackgroundFetchEventInit init);
readonly attribute BackgroundFetchRegistration registration;
};
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 ec554b76fd1..cfa4a24909e 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
@@ -8,9 +8,9 @@
#include "third_party/blink/public/common/manifest/manifest_icon_selector.h"
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/public/platform/web_url_request.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_image_resource.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h"
-#include "third_party/blink/renderer/modules/manifest/image_resource.h"
#include "third_party/blink/renderer/modules/manifest/image_resource_type_converters.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
@@ -49,7 +49,7 @@ void BackgroundFetchIconLoader::Start(
void BackgroundFetchIconLoader::DidGetIconDisplaySizeIfSoLoadIcon(
ExecutionContext* execution_context,
IconCallback icon_callback,
- const WebSize& icon_display_size_pixels) {
+ const gfx::Size& icon_display_size_pixels) {
// If |icon_display_size_pixels| is empty then no image will be displayed by
// the UI powering Background Fetch. Bail out immediately.
if (icon_display_size_pixels.IsEmpty()) {
@@ -58,8 +58,8 @@ void BackgroundFetchIconLoader::DidGetIconDisplaySizeIfSoLoadIcon(
return;
}
- KURL best_icon_url = PickBestIconForDisplay(execution_context,
- icon_display_size_pixels.height);
+ KURL best_icon_url = PickBestIconForDisplay(
+ execution_context, icon_display_size_pixels.height());
if (best_icon_url.IsEmpty()) {
// None of the icons provided was suitable.
std::move(icon_callback)
@@ -71,6 +71,8 @@ void BackgroundFetchIconLoader::DidGetIconDisplaySizeIfSoLoadIcon(
ResourceRequest resource_request(best_icon_url);
resource_request.SetRequestContext(mojom::RequestContextType::IMAGE);
+ resource_request.SetRequestDestination(
+ network::mojom::RequestDestination::kImage);
resource_request.SetPriority(ResourceLoadPriority::kMedium);
resource_request.SetKeepalive(true);
resource_request.SetMode(network::mojom::RequestMode::kNoCors);
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 3b425340c30..fa78b04eb76 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
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_ICON_LOADER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_ICON_LOADER_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_image_resource.h"
#include "third_party/blink/renderer/core/loader/threaded_icon_loader.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.h"
#include "third_party/blink/renderer/modules/modules_export.h"
@@ -44,7 +45,7 @@ class MODULES_EXPORT BackgroundFetchIconLoader final
void DidGetIconDisplaySizeIfSoLoadIcon(
ExecutionContext* execution_context,
IconCallback callback,
- const WebSize& icon_display_size_pixels);
+ const gfx::Size& icon_display_size_pixels);
void DidGetIcon(SkBitmap icon, double resize_scale);
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 c9a1a02a3c3..f9dbc8fae74 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
@@ -8,9 +8,9 @@
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_image_resource.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
-#include "third_party/blink/renderer/modules/manifest/image_resource.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
@@ -97,7 +97,7 @@ class BackgroundFetchIconLoaderTest : public PageTestBase {
}
void LoadIcon(const KURL& url,
- const WebSize& maximum_size,
+ const gfx::Size& maximum_size,
base::OnceClosure quit_closure,
const String& sizes = "500x500",
const String& purpose = "ANY") {
@@ -115,7 +115,9 @@ class BackgroundFetchIconLoaderTest : public PageTestBase {
maximum_size);
}
- ExecutionContext* GetContext() const { return &GetDocument(); }
+ ExecutionContext* GetContext() const {
+ return GetDocument().ToExecutionContext();
+ }
protected:
ScopedTestingPlatformSupport<TestingPlatformSupport> platform_;
@@ -129,7 +131,7 @@ class BackgroundFetchIconLoaderTest : public PageTestBase {
TEST_F(BackgroundFetchIconLoaderTest, SuccessTest) {
base::RunLoop run_loop;
- WebSize maximum_size{192, 168};
+ gfx::Size maximum_size{192, 168};
LoadIcon(KURL(kBackgroundFetchImageLoaderIcon500x500FullPath), maximum_size,
run_loop.QuitClosure());
@@ -189,7 +191,7 @@ TEST_F(BackgroundFetchIconLoaderTest, PickRightIcon) {
TEST_F(BackgroundFetchIconLoaderTest, EmptySizes) {
base::RunLoop run_loop;
- WebSize maximum_size{192, 168};
+ gfx::Size maximum_size{192, 168};
LoadIcon(KURL(kBackgroundFetchImageLoaderIcon500x500FullPath), maximum_size,
run_loop.QuitClosure(), "", "ANY");
@@ -204,7 +206,7 @@ TEST_F(BackgroundFetchIconLoaderTest, EmptySizes) {
TEST_F(BackgroundFetchIconLoaderTest, EmptyPurpose) {
base::RunLoop run_loop;
- WebSize maximum_size{192, 168};
+ gfx::Size maximum_size{192, 168};
LoadIcon(KURL(kBackgroundFetchImageLoaderIcon500x500FullPath), maximum_size,
run_loop.QuitClosure(), "500X500", "");
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 a8439c230c6..474808db4cd 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
@@ -12,6 +12,8 @@
#include "third_party/blink/renderer/bindings/core/v8/request_or_usv_string.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/modules/v8/request_or_usv_string_or_request_or_usv_string_sequence.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_background_fetch_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_image_resource.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/fetch/body.h"
#include "third_party/blink/renderer/core/fetch/body_stream_buffer.h"
@@ -20,12 +22,11 @@
#include "third_party/blink/renderer/core/frame/deprecation.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.h"
-#include "third_party/blink/renderer/modules/background_fetch/background_fetch_options.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.h"
-#include "third_party/blink/renderer/modules/manifest/image_resource.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_registration.h"
#include "third_party/blink/renderer/platform/bindings/exception_code.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/v8_throw_exception.h"
#include "third_party/blink/renderer/platform/blob/blob_data.h"
@@ -54,12 +55,12 @@ const char kNullRequestErrorMessage[] = "Requests must not be null.";
ScriptPromise RejectWithTypeError(ScriptState* script_state,
const KURL& request_url,
- const String& reason) {
- return ScriptPromise::Reject(
- script_state, V8ThrowException::CreateTypeError(
- script_state->GetIsolate(),
- "Refused to fetch '" + request_url.ElidedString() +
- "' because " + reason + "."));
+ const String& reason,
+ ExceptionState& exception_state) {
+ exception_state.ThrowTypeError("Refused to fetch '" +
+ request_url.ElidedString() + "' because " +
+ reason + ".");
+ return ScriptPromise();
}
// Returns whether the |request_url| should be blocked by the CSP. Must be
@@ -158,7 +159,7 @@ scoped_refptr<BlobDataHandle> ExtractBlobHandle(
BackgroundFetchManager::BackgroundFetchManager(
ServiceWorkerRegistration* registration)
- : ContextLifecycleObserver(registration->GetExecutionContext()),
+ : ExecutionContextLifecycleObserver(registration->GetExecutionContext()),
registration_(registration) {
DCHECK(registration);
bridge_ = BackgroundFetchBridge::From(registration_);
@@ -171,11 +172,9 @@ ScriptPromise BackgroundFetchManager::fetch(
const BackgroundFetchOptions* options,
ExceptionState& exception_state) {
if (!registration_->active()) {
- return ScriptPromise::Reject(
- script_state,
- V8ThrowException::CreateTypeError(script_state->GetIsolate(),
- "No active registration available on "
- "the ServiceWorkerRegistration."));
+ exception_state.ThrowTypeError(
+ "No active registration available on the ServiceWorkerRegistration.");
+ return ScriptPromise();
}
bool has_requests_with_body;
@@ -205,7 +204,7 @@ ScriptPromise BackgroundFetchManager::fetch(
if (!request_url.IsValid()) {
return RejectWithTypeError(script_state, request_url,
- "that URL is invalid");
+ "that URL is invalid", exception_state);
}
// https://wicg.github.io/background-fetch/#dom-backgroundfetchmanager-fetch
@@ -213,41 +212,47 @@ ScriptPromise BackgroundFetchManager::fetch(
// rejected with a TypeError.""
if (request->mode == network::mojom::RequestMode::kNoCors) {
return RejectWithTypeError(script_state, request_url,
- "the request mode must not be no-cors");
+ "the request mode must not be no-cors",
+ exception_state);
}
// Check this before mixed content, so that if mixed content is blocked by
// CSP they get a CSP warning rather than a mixed content failure.
if (ShouldBlockDueToCSP(execution_context, request_url)) {
return RejectWithTypeError(script_state, request_url,
- "it violates the Content Security Policy");
+ "it violates the Content Security Policy",
+ exception_state);
}
if (ShouldBlockPort(request_url)) {
return RejectWithTypeError(script_state, request_url,
- "that port is not allowed");
+ "that port is not allowed", exception_state);
}
if (ShouldBlockCredentials(execution_context, request_url)) {
return RejectWithTypeError(script_state, request_url,
- "that URL contains a username/password");
+ "that URL contains a username/password",
+ exception_state);
}
if (ShouldBlockScheme(request_url)) {
return RejectWithTypeError(script_state, request_url,
"only the https: scheme is allowed, or http: "
- "for loopback IPs");
+ "for loopback IPs",
+ exception_state);
}
if (ShouldBlockDanglingMarkup(request_url)) {
return RejectWithTypeError(script_state, request_url,
- "it contains dangling markup");
+ "it contains dangling markup",
+ exception_state);
}
if (ShouldBlockGateWayAttacks(execution_context, request_url)) {
return RejectWithTypeError(script_state, request_url,
"Requestor IP address space doesn't match the "
- "target address space.");
+ "target address space.",
+ exception_state);
}
kurls.insert(request_url);
@@ -358,7 +363,8 @@ void BackgroundFetchManager::DidFetch(
}
ScriptPromise BackgroundFetchManager::get(ScriptState* script_state,
- const String& id) {
+ const String& id,
+ ExceptionState& exception_state) {
// Creating a Background Fetch registration requires an activated worker, so
// if |registration_| has not been activated we can skip the Mojo roundtrip.
if (!registration_->active())
@@ -367,10 +373,8 @@ ScriptPromise BackgroundFetchManager::get(ScriptState* script_state,
ScriptState::Scope scope(script_state);
if (id.IsEmpty()) {
- return ScriptPromise::Reject(
- script_state,
- V8ThrowException::CreateTypeError(script_state->GetIsolate(),
- "The provided id is invalid."));
+ exception_state.ThrowTypeError("The provided id is invalid.");
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -555,15 +559,15 @@ void BackgroundFetchManager::DidGetDeveloperIds(
NOTREACHED();
}
-void BackgroundFetchManager::Trace(blink::Visitor* visitor) {
+void BackgroundFetchManager::Trace(Visitor* visitor) {
visitor->Trace(registration_);
visitor->Trace(bridge_);
visitor->Trace(loaders_);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
ScriptWrappable::Trace(visitor);
}
-void BackgroundFetchManager::ContextDestroyed(ExecutionContext* context) {
+void BackgroundFetchManager::ContextDestroyed() {
for (const auto& loader : loaders_) {
if (loader)
loader->Stop();
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 f792dc5dac1..792de6c5d9b 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
@@ -8,7 +8,7 @@
#include "base/time/time.h"
#include "third_party/blink/public/mojom/background_fetch/background_fetch.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/heap/garbage_collected.h"
@@ -23,7 +23,6 @@ class BackgroundFetchIconLoader;
class BackgroundFetchOptions;
class BackgroundFetchRegistration;
class ExceptionState;
-class ExecutionContext;
class RequestOrUSVStringOrRequestOrUSVStringSequence;
class ScriptPromiseResolver;
class ScriptState;
@@ -33,7 +32,7 @@ class ServiceWorkerRegistration;
// by developers through ServiceWorkerRegistration.backgroundFetch.
class MODULES_EXPORT BackgroundFetchManager final
: public ScriptWrappable,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(BackgroundFetchManager);
DEFINE_WRAPPERTYPEINFO();
@@ -41,11 +40,6 @@ class MODULES_EXPORT BackgroundFetchManager final
explicit BackgroundFetchManager(ServiceWorkerRegistration* registration);
~BackgroundFetchManager() override = default;
- static BackgroundFetchManager* Create(
- ServiceWorkerRegistration* registration) {
- return MakeGarbageCollected<BackgroundFetchManager>(registration);
- }
-
// Web Exposed methods defined in the IDL file.
ScriptPromise fetch(
ScriptState* script_state,
@@ -53,13 +47,15 @@ class MODULES_EXPORT BackgroundFetchManager final
const RequestOrUSVStringOrRequestOrUSVStringSequence& requests,
const BackgroundFetchOptions* options,
ExceptionState& exception_state);
- ScriptPromise get(ScriptState* script_state, const String& id);
+ ScriptPromise get(ScriptState* script_state,
+ const String& id,
+ ExceptionState& exception_state);
ScriptPromise getIds(ScriptState* script_state);
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
- // ContextLifecycleObserver interface
- void ContextDestroyed(ExecutionContext* context) override;
+ // ExecutionContextLifecycleObserver interface
+ void ContextDestroyed() override;
private:
friend class BackgroundFetchManagerTest;
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.idl
index d62cedaf4ba..18e2ce7da33 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.idl
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.idl
@@ -8,7 +8,7 @@
Exposed=(Window,Worker),
RuntimeEnabled=BackgroundFetch
] interface BackgroundFetchManager {
- [CallWith=ScriptState, RaisesException, MeasureAs=BackgroundFetchManagerFetch] Promise<BackgroundFetchRegistration> fetch(DOMString id, (RequestInfo or sequence<RequestInfo>) requests, optional BackgroundFetchOptions options);
- [CallWith=ScriptState, MeasureAs=BackgroundFetchManagerGet] Promise<BackgroundFetchRegistration?> get(DOMString id);
+ [CallWith=ScriptState, RaisesException, MeasureAs=BackgroundFetchManagerFetch] Promise<BackgroundFetchRegistration> fetch(DOMString id, (RequestInfo or sequence<RequestInfo>) requests, optional BackgroundFetchOptions options = {});
+ [CallWith=ScriptState, RaisesException, MeasureAs=BackgroundFetchManagerGet] Promise<BackgroundFetchRegistration?> get(DOMString id);
[CallWith=ScriptState, MeasureAs=BackgroundFetchManagerGetIds] Promise<FrozenArray<DOMString>> getIds();
};
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager_test.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager_test.cc
index 49cd93c6a56..e3ef1be2c14 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager_test.cc
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager_test.cc
@@ -8,9 +8,9 @@
#include "third_party/blink/renderer/bindings/core/v8/request_or_usv_string.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_request_init.h"
#include "third_party/blink/renderer/bindings/modules/v8/request_or_usv_string_or_request_or_usv_string_sequence.h"
#include "third_party/blink/renderer/core/fetch/request.h"
-#include "third_party/blink/renderer/core/fetch/request_init.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/blob/blob_data.h"
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 20a31fef33e..2b90ccf72dd 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
@@ -17,15 +17,14 @@ BackgroundFetchRecord::BackgroundFetchRecord(Request* request,
DCHECK(script_state_);
response_ready_property_ = MakeGarbageCollected<ResponseReadyProperty>(
- ExecutionContext::From(script_state), this,
- ResponseReadyProperty::kResponseReady);
+ ExecutionContext::From(script_state));
}
BackgroundFetchRecord::~BackgroundFetchRecord() = default;
void BackgroundFetchRecord::ResolveResponseReadyProperty(Response* response) {
if (response_ready_property_->GetState() !=
- ScriptPromisePropertyBase::State::kPending) {
+ ResponseReadyProperty::State::kPending) {
return;
}
@@ -104,7 +103,7 @@ const KURL& BackgroundFetchRecord::ObservedUrl() const {
return request_->url();
}
-void BackgroundFetchRecord::Trace(blink::Visitor* visitor) {
+void BackgroundFetchRecord::Trace(Visitor* visitor) {
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 d150009b428..8465caa13da 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,16 +48,14 @@ class MODULES_EXPORT BackgroundFetchRecord final : public ScriptWrappable {
void SetResponseAndUpdateState(mojom::blink::FetchAPIResponsePtr& response);
bool IsRecordPending();
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
void OnRequestCompleted(mojom::blink::FetchAPIResponsePtr response);
const KURL& ObservedUrl() const;
private:
using ResponseReadyProperty =
- ScriptPromiseProperty<Member<BackgroundFetchRecord>,
- Member<Response>,
- Member<DOMException>>;
+ ScriptPromiseProperty<Member<Response>, Member<DOMException>>;
// Resolves a pending |response_ready_property_| with |response|, if it's not
// null.
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 08cb59a00ea..bf465a29082 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
@@ -9,6 +9,8 @@
#include "base/metrics/histogram_macros.h"
#include "base/optional.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_cache_query_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_image_resource.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/fetch/request.h"
@@ -16,10 +18,9 @@
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_record.h"
#include "third_party/blink/renderer/modules/cache_storage/cache.h"
-#include "third_party/blink/renderer/modules/cache_storage/cache_query_options.h"
#include "third_party/blink/renderer/modules/event_target_modules_names.h"
-#include "third_party/blink/renderer/modules/manifest/image_resource.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_registration.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/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
@@ -210,12 +211,11 @@ ScriptPromise BackgroundFetchRegistration::MatchImpl(
result_ == mojom::BackgroundFetchResult::UNSET);
if (!records_available_) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "The records associated with this background fetch are no longer "
- "available."));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "The records associated with this background fetch are no longer "
+ "available.");
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
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 6addfd183a4..8a553329888 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
@@ -20,6 +20,7 @@ namespace blink {
class BackgroundFetchRecord;
class CacheQueryOptions;
+class ExceptionState;
class ScriptPromiseResolver;
class ScriptState;
class ServiceWorkerRegistration;
@@ -105,7 +106,7 @@ class BackgroundFetchRegistration final
void Dispose();
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) 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_registration.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.idl
index fa906d70698..58adaf1d1ea 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.idl
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.idl
@@ -20,8 +20,8 @@
attribute EventHandler onprogress;
[CallWith=ScriptState, MeasureAs=BackgroundFetchRegistrationAbort] Promise<boolean> abort();
- [CallWith=ScriptState, RaisesException, MeasureAs=BackgroundFetchRegistrationMatch] Promise<BackgroundFetchRecord> match(RequestInfo request, optional CacheQueryOptions options);
- [CallWith=ScriptState, RaisesException, MeasureAs=BackgroundFetchRegistrationMatchAll] Promise<sequence<BackgroundFetchRecord>> matchAll(optional RequestInfo request, optional CacheQueryOptions options);
+ [CallWith=ScriptState, RaisesException, MeasureAs=BackgroundFetchRegistrationMatch] Promise<BackgroundFetchRecord> match(RequestInfo request, optional CacheQueryOptions options = {});
+ [CallWith=ScriptState, RaisesException, MeasureAs=BackgroundFetchRegistrationMatchAll] Promise<sequence<BackgroundFetchRecord>> matchAll(optional RequestInfo request, optional CacheQueryOptions options = {});
};
enum BackgroundFetchResult { "", "success", "failure" };
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.cc
index 2f83215d90c..f31b64030de 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.cc
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.cc
@@ -5,6 +5,8 @@
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.h"
#include <utility>
+
+#include "third_party/blink/renderer/bindings/modules/v8/v8_background_fetch_options.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h"
#include "third_party/blink/renderer/modules/manifest/image_resource_type_converters.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.h
index 3d64bbc6d29..2efcf8a30ba 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.h
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.h
@@ -6,10 +6,10 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_TYPE_CONVERTERS_H_
#include "third_party/blink/public/mojom/background_fetch/background_fetch.mojom-blink.h"
-#include "third_party/blink/renderer/modules/background_fetch/background_fetch_options.h"
namespace blink {
class BackgroundFetchRegistration;
+class BackgroundFetchOptions;
}
namespace mojo {
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 edf815e65eb..3233b0c57a4 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
@@ -5,18 +5,19 @@
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_background_fetch_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_background_fetch_ui_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_image_resource.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/fetch/request.h"
#include "third_party/blink/renderer/core/fetch/response.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h"
-#include "third_party/blink/renderer/modules/background_fetch/background_fetch_event_init.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h"
-#include "third_party/blink/renderer/modules/background_fetch/background_fetch_ui_options.h"
#include "third_party/blink/renderer/modules/event_interface_modules_names.h"
-#include "third_party/blink/renderer/modules/manifest/image_resource.h"
#include "third_party/blink/renderer/modules/service_worker/wait_until_observer.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/heap/heap.h"
@@ -37,7 +38,7 @@ BackgroundFetchUpdateUIEvent::BackgroundFetchUpdateUIEvent(
BackgroundFetchUpdateUIEvent::~BackgroundFetchUpdateUIEvent() = default;
-void BackgroundFetchUpdateUIEvent::Trace(blink::Visitor* visitor) {
+void BackgroundFetchUpdateUIEvent::Trace(Visitor* visitor) {
visitor->Trace(service_worker_registration_);
visitor->Trace(loader_);
BackgroundFetchEvent::Trace(visitor);
@@ -45,20 +46,19 @@ void BackgroundFetchUpdateUIEvent::Trace(blink::Visitor* visitor) {
ScriptPromise BackgroundFetchUpdateUIEvent::updateUI(
ScriptState* script_state,
- const BackgroundFetchUIOptions* ui_options) {
+ const BackgroundFetchUIOptions* ui_options,
+ ExceptionState& exception_state) {
if (observer_ && !observer_->IsEventActive()) {
// Return a rejected promise as the event is no longer active.
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "ExtendableEvent is no longer active."));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "ExtendableEvent is no longer active.");
+ return ScriptPromise();
}
if (update_ui_called_) {
// Return a rejected promise as this method should only be called once.
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "updateUI may only be called once."));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "updateUI may only be called once.");
+ return ScriptPromise();
}
update_ui_called_ = true;
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 8a491c15e9e..88f5b3e1d82 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
@@ -18,6 +18,7 @@ namespace blink {
class BackgroundFetchEvent;
class BackgroundFetchIconLoader;
class BackgroundFetchUIOptions;
+class ExceptionState;
class ScriptPromiseResolver;
class WaitUntilObserver;
@@ -53,9 +54,10 @@ class MODULES_EXPORT BackgroundFetchUpdateUIEvent final
// Web Exposed method defined in the IDL file.
ScriptPromise updateUI(ScriptState* script_state,
- const BackgroundFetchUIOptions* ui_options);
+ const BackgroundFetchUIOptions* ui_options,
+ ExceptionState&);
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
void DidGetIcon(ScriptPromiseResolver* resolver,
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.idl b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.idl
index ab7b6e5eb61..d6ba20039b8 100644
--- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.idl
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.idl
@@ -5,9 +5,9 @@
// https://wicg.github.io/background-fetch/#background-fetch-update-ui-event
[
- Constructor(DOMString type, BackgroundFetchEventInit init),
Exposed=ServiceWorker,
RuntimeEnabled=BackgroundFetch
] interface BackgroundFetchUpdateUIEvent : BackgroundFetchEvent {
- [CallWith=ScriptState] Promise<void> updateUI(optional BackgroundFetchUIOptions options);
-}; \ No newline at end of file
+ constructor(DOMString type, BackgroundFetchEventInit init);
+ [CallWith=ScriptState, RaisesException] Promise<void> updateUI(optional BackgroundFetchUIOptions options = {});
+};
diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/idls.gni b/chromium/third_party/blink/renderer/modules/background_fetch/idls.gni
new file mode 100644
index 00000000000..959d9ff3aaa
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/background_fetch/idls.gni
@@ -0,0 +1,22 @@
+# 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 = [
+ "background_fetch_event.idl",
+ "background_fetch_manager.idl",
+ "background_fetch_record.idl",
+ "background_fetch_registration.idl",
+ "background_fetch_update_ui_event.idl",
+]
+
+modules_dictionary_idl_files = [
+ "background_fetch_event_init.idl",
+ "background_fetch_options.idl",
+ "background_fetch_ui_options.idl",
+]
+
+modules_dependency_idl_files = [
+ "service_worker_global_scope_background_fetch.idl",
+ "service_worker_registration_background_fetch.idl",
+]
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 802173ff1ea..d09a081ffdc 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
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
@@ -44,13 +45,15 @@ ServiceWorkerRegistrationBackgroundFetch::backgroundFetch(
BackgroundFetchManager*
ServiceWorkerRegistrationBackgroundFetch::backgroundFetch() {
- if (!background_fetch_manager_)
- background_fetch_manager_ = BackgroundFetchManager::Create(registration_);
+ if (!background_fetch_manager_) {
+ background_fetch_manager_ =
+ MakeGarbageCollected<BackgroundFetchManager>(registration_);
+ }
return background_fetch_manager_.Get();
}
-void ServiceWorkerRegistrationBackgroundFetch::Trace(blink::Visitor* visitor) {
+void ServiceWorkerRegistrationBackgroundFetch::Trace(Visitor* visitor) {
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 abd4ce489da..157ad997312 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(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
Member<ServiceWorkerRegistration> registration_;
diff --git a/chromium/third_party/blink/renderer/modules/background_sync/idls.gni b/chromium/third_party/blink/renderer/modules/background_sync/idls.gni
new file mode 100644
index 00000000000..a42a23a6f52
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/background_sync/idls.gni
@@ -0,0 +1,21 @@
+# 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 = [
+ "sync_event.idl",
+ "periodic_sync_event.idl",
+ "periodic_sync_manager.idl",
+ "sync_manager.idl",
+]
+
+modules_dictionary_idl_files = [
+ "background_sync_options.idl",
+ "sync_event_init.idl",
+ "periodic_sync_event_init.idl",
+]
+
+modules_dependency_idl_files = [
+ "service_worker_global_scope_sync.idl",
+ "service_worker_registration_sync.idl",
+]
diff --git a/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_event.cc b/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_event.cc
index b1eef2acca2..e35c36da04d 100644
--- a/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_event.cc
+++ b/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_event.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/modules/background_sync/periodic_sync_event.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_periodic_sync_event_init.h"
+
namespace blink {
PeriodicSyncEvent::PeriodicSyncEvent(const AtomicString& type,
diff --git a/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_event.h b/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_event.h
index 56e57912b92..1a540203b8d 100644
--- a/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_event.h
+++ b/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_event.h
@@ -5,7 +5,6 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_SYNC_PERIODIC_SYNC_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_SYNC_PERIODIC_SYNC_EVENT_H_
-#include "third_party/blink/renderer/modules/background_sync/periodic_sync_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/service_worker/extendable_event.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -14,6 +13,8 @@
namespace blink {
+class PeriodicSyncEventInit;
+
class MODULES_EXPORT PeriodicSyncEvent final : public ExtendableEvent {
DEFINE_WRAPPERTYPEINFO();
diff --git a/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_event.idl b/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_event.idl
index caefac4c574..b3d8fa6239d 100644
--- a/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_event.idl
+++ b/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_event.idl
@@ -5,9 +5,9 @@
// TODO(crbug.com/925297): Link to spec.
[
- Constructor(DOMString type, PeriodicSyncEventInit init),
Exposed=ServiceWorker,
RuntimeEnabled=PeriodicBackgroundSync
] interface PeriodicSyncEvent : ExtendableEvent {
+ constructor(DOMString type, PeriodicSyncEventInit init);
readonly attribute DOMString tag;
};
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 307c79d5517..097ab0c09ea 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
@@ -4,14 +4,15 @@
#include "third_party/blink/renderer/modules/background_sync/periodic_sync_manager.h"
-#include "third_party/blink/public/platform/interface_provider.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/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_background_sync_options.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/modules/background_sync/background_sync_options.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_registration.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
namespace blink {
@@ -25,12 +26,13 @@ PeriodicSyncManager::PeriodicSyncManager(
ScriptPromise PeriodicSyncManager::registerPeriodicSync(
ScriptState* script_state,
const String& tag,
- const BackgroundSyncOptions* options) {
+ const BackgroundSyncOptions* options,
+ ExceptionState& exception_state) {
if (!registration_->active()) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "Registration failed - no active Service Worker"));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "Registration failed - no active Service Worker");
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -90,7 +92,7 @@ ScriptPromise PeriodicSyncManager::unregister(ScriptState* script_state,
const mojo::Remote<mojom::blink::PeriodicBackgroundSyncService>&
PeriodicSyncManager::GetBackgroundSyncServiceRemote() {
if (!background_sync_service_.is_bound()) {
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
background_sync_service_.BindNewPipeAndPassReceiver());
}
return background_sync_service_;
@@ -182,7 +184,7 @@ void PeriodicSyncManager::UnregisterCallback(
}
}
-void PeriodicSyncManager::Trace(blink::Visitor* visitor) {
+void PeriodicSyncManager::Trace(Visitor* visitor) {
visitor->Trace(registration_);
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 3f2e990250b..b76e055d06b 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
@@ -15,6 +15,7 @@
namespace blink {
class BackgroundSyncOptions;
+class ExceptionState;
class ScriptPromise;
class ScriptPromiseResolver;
class ScriptState;
@@ -24,24 +25,18 @@ class PeriodicSyncManager final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- static PeriodicSyncManager* Create(
- ServiceWorkerRegistration* registration,
- scoped_refptr<base::SequencedTaskRunner> task_runner) {
- return MakeGarbageCollected<PeriodicSyncManager>(registration,
- std::move(task_runner));
- }
-
PeriodicSyncManager(ServiceWorkerRegistration* registration,
scoped_refptr<base::SequencedTaskRunner> task_runner);
// IDL exposed interface
ScriptPromise registerPeriodicSync(ScriptState* script_state,
const String& tag,
- const BackgroundSyncOptions* options);
+ const BackgroundSyncOptions* options,
+ ExceptionState& exception_state);
ScriptPromise getTags(ScriptState* script_state);
ScriptPromise unregister(ScriptState* script_state, const String& tag);
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
// Returns an initialized
diff --git a/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.idl b/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.idl
index 153c4c53117..443c2a60fec 100644
--- a/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.idl
+++ b/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.idl
@@ -9,7 +9,7 @@
Exposed=(Window,Worker),
RuntimeEnabled=PeriodicBackgroundSync
] interface PeriodicSyncManager {
- [MeasureAs=PeriodicBackgroundSyncRegister,CallWith=ScriptState,ImplementedAs=registerPeriodicSync] Promise<void> register(DOMString tag, optional BackgroundSyncOptions options);
+ [MeasureAs=PeriodicBackgroundSyncRegister,CallWith=ScriptState,RaisesException,ImplementedAs=registerPeriodicSync] Promise<void> register(DOMString tag, optional BackgroundSyncOptions options = {});
[MeasureAs=PeriodicBackgroundSyncGetTags, CallWith=ScriptState] Promise<sequence<DOMString>> getTags();
[MeasureAs=PeriodicBackgroundSyncUnregister,CallWith=ScriptState] Promise<void> unregister(DOMString tag);
};
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 2490ca3e5ab..33197156d73 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
@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/modules/background_sync/periodic_sync_manager.h"
#include "third_party/blink/renderer/modules/background_sync/sync_manager.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_registration.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
@@ -41,7 +42,7 @@ SyncManager* ServiceWorkerRegistrationSync::sync() {
if (!sync_manager_) {
ExecutionContext* execution_context = registration_->GetExecutionContext();
// TODO(falken): Consider defining a task source in the spec for this event.
- sync_manager_ = SyncManager::Create(
+ sync_manager_ = MakeGarbageCollected<SyncManager>(
registration_,
execution_context->GetTaskRunner(TaskType::kMiscPlatformAPI));
}
@@ -57,14 +58,14 @@ PeriodicSyncManager* ServiceWorkerRegistrationSync::periodicSync() {
if (!periodic_sync_manager_) {
ExecutionContext* execution_context = registration_->GetExecutionContext();
// TODO(falken): Consider defining a task source in the spec for this event.
- periodic_sync_manager_ = PeriodicSyncManager::Create(
+ periodic_sync_manager_ = MakeGarbageCollected<PeriodicSyncManager>(
registration_,
execution_context->GetTaskRunner(TaskType::kMiscPlatformAPI));
}
return periodic_sync_manager_.Get();
}
-void ServiceWorkerRegistrationSync::Trace(blink::Visitor* visitor) {
+void ServiceWorkerRegistrationSync::Trace(Visitor* visitor) {
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 ba2920e3d98..71bb2aefcae 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<ServiceWorkerRegistration> registration_;
diff --git a/chromium/third_party/blink/renderer/modules/background_sync/sync_event.cc b/chromium/third_party/blink/renderer/modules/background_sync/sync_event.cc
index 390b3317259..2b1de6724b3 100644
--- a/chromium/third_party/blink/renderer/modules/background_sync/sync_event.cc
+++ b/chromium/third_party/blink/renderer/modules/background_sync/sync_event.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/modules/background_sync/sync_event.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_sync_event_init.h"
+
namespace blink {
SyncEvent::SyncEvent(const AtomicString& type,
diff --git a/chromium/third_party/blink/renderer/modules/background_sync/sync_event.h b/chromium/third_party/blink/renderer/modules/background_sync/sync_event.h
index f336c1f4516..3e96e7f3e7e 100644
--- a/chromium/third_party/blink/renderer/modules/background_sync/sync_event.h
+++ b/chromium/third_party/blink/renderer/modules/background_sync/sync_event.h
@@ -5,7 +5,6 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_SYNC_SYNC_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_SYNC_SYNC_EVENT_H_
-#include "third_party/blink/renderer/modules/background_sync/sync_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/service_worker/extendable_event.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -14,6 +13,8 @@
namespace blink {
+class SyncEventInit;
+
class MODULES_EXPORT SyncEvent final : public ExtendableEvent {
DEFINE_WRAPPERTYPEINFO();
diff --git a/chromium/third_party/blink/renderer/modules/background_sync/sync_event.idl b/chromium/third_party/blink/renderer/modules/background_sync/sync_event.idl
index 7a80e3f04af..68134c21cce 100644
--- a/chromium/third_party/blink/renderer/modules/background_sync/sync_event.idl
+++ b/chromium/third_party/blink/renderer/modules/background_sync/sync_event.idl
@@ -5,9 +5,9 @@
// https://wicg.github.io/BackgroundSync/spec/#sync-event
[
- Constructor(DOMString type, SyncEventInit init),
Exposed=ServiceWorker
] interface SyncEvent : ExtendableEvent {
+ constructor(DOMString type, SyncEventInit init);
readonly attribute DOMString tag;
readonly attribute boolean lastChance;
};
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 977a41d5966..f2ae27fc830 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
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/modules/background_sync/sync_manager.h"
-#include "third_party/blink/public/platform/interface_provider.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/renderer/bindings/core/v8/callback_promise_adapter.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
@@ -12,6 +12,7 @@
#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/modules/service_worker/service_worker_registration.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/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
@@ -26,12 +27,13 @@ SyncManager::SyncManager(ServiceWorkerRegistration* registration,
}
ScriptPromise SyncManager::registerFunction(ScriptState* script_state,
- const String& tag) {
+ const String& tag,
+ ExceptionState& exception_state) {
if (!registration_->active()) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "Registration failed - no active Service Worker"));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "Registration failed - no active Service Worker");
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -64,7 +66,7 @@ ScriptPromise SyncManager::getTags(ScriptState* script_state) {
const mojo::Remote<mojom::blink::OneShotBackgroundSyncService>&
SyncManager::GetBackgroundSyncServiceRemote() {
if (!background_sync_service_.is_bound()) {
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
background_sync_service_.BindNewPipeAndPassReceiver(task_runner_));
}
return background_sync_service_;
@@ -148,7 +150,7 @@ void SyncManager::GetRegistrationsCallback(
}
}
-void SyncManager::Trace(blink::Visitor* visitor) {
+void SyncManager::Trace(Visitor* visitor) {
visitor->Trace(registration_);
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 cab4e06d268..a05b519b6af 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
@@ -13,6 +13,7 @@
namespace blink {
+class ExceptionState;
class ScriptPromise;
class ScriptPromiseResolver;
class ScriptState;
@@ -22,20 +23,15 @@ class SyncManager final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- static SyncManager* Create(
- ServiceWorkerRegistration* registration,
- scoped_refptr<base::SequencedTaskRunner> task_runner) {
- return MakeGarbageCollected<SyncManager>(registration,
- std::move(task_runner));
- }
-
SyncManager(ServiceWorkerRegistration*,
scoped_refptr<base::SequencedTaskRunner>);
- ScriptPromise registerFunction(ScriptState*, const String& tag);
+ ScriptPromise registerFunction(ScriptState*,
+ const String& tag,
+ ExceptionState& exception_state);
ScriptPromise getTags(ScriptState*);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
enum { kUnregisteredSyncID = -1 };
diff --git a/chromium/third_party/blink/renderer/modules/background_sync/sync_manager.idl b/chromium/third_party/blink/renderer/modules/background_sync/sync_manager.idl
index d3d1ad0c62a..18a380dc640 100644
--- a/chromium/third_party/blink/renderer/modules/background_sync/sync_manager.idl
+++ b/chromium/third_party/blink/renderer/modules/background_sync/sync_manager.idl
@@ -7,6 +7,6 @@
[
Exposed=(Window,Worker)
] interface SyncManager {
- [MeasureAs=BackgroundSyncRegister,CallWith=ScriptState,ImplementedAs=registerFunction] Promise<void> register(DOMString tag);
+ [MeasureAs=BackgroundSyncRegister,CallWith=ScriptState,RaisesException,ImplementedAs=registerFunction] Promise<void> register(DOMString tag);
[CallWith=ScriptState] Promise<sequence<DOMString>> getTags();
};
diff --git a/chromium/third_party/blink/renderer/modules/badging/OWNERS b/chromium/third_party/blink/renderer/modules/badging/OWNERS
index d9d061fbb24..06628a10549 100644
--- a/chromium/third_party/blink/renderer/modules/badging/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/badging/OWNERS
@@ -1,6 +1,3 @@
-estevenson@chromium.org
-mgiuca@chromium.org
-harrisjay@chromium.org
+file://chrome/browser/badging/OWNERS
-# TEAM: apps-dev@chromium.org
-# COMPONENT: Platform>Apps
+# COMPONENT: UI>Browser>WebAppInstalls
diff --git a/chromium/third_party/blink/renderer/modules/badging/README.md b/chromium/third_party/blink/renderer/modules/badging/README.md
index 69de88b73cb..d9055b122f3 100644
--- a/chromium/third_party/blink/renderer/modules/badging/README.md
+++ b/chromium/third_party/blink/renderer/modules/badging/README.md
@@ -1,24 +1,31 @@
# Badging
-This module contains the implementation of the [Badging API]. The implementation
-is under [active development].
+This module contains the implementation of the [Badging API].
[Badging API]: https://github.com/WICG/badging
[active development]: https://crbug.com/719176
### API
-See the [explainer] for details. The Badge interface is a member on Window
-and exposes two static methods:
+See the [explainer] for details. The NavigatorBadge mixin interface is
+included by Navigator and WorkerNavigator, which exposes two methods:
+setAppBadge() and clearAppBadge().
[explainer]: https://github.com/WICG/badging/blob/master/explainer.md
-* `set(contents)`: Sets the associated app's badge as a "flag" (the argument
- is ignored).
-* `clear()`: Sets the associated app's badge to nothing.
+* `setAppBadge(optional [EnforceRange] unsigned long long contents)`: Sets the
+associated app's badge to |contents|.
+ * When |contents| is omitted, sets the associated app's badge to "flag".
+ * When |contents| is 0, sets the associated app's badge to nothing.
+* `clearAppBadge()`: Sets the associated app's badge to nothing.
### Testing
`web_tests/badging/*.html` tests that the API accepts/rejects the appropriate
-inputs (with a mock Mojo service). Testing at other layers will be added
-during implementation.
+inputs (with a mock Mojo service that verifies that the interface sends the
+correct Mojo messages". These tests duplicate some of the tests from WPT (below)
+but with internal verification.
+
+`web_tests/external/wpt/badging/*.html` tests that the API accepts/rejects the
+appropriate inputs. These tests do not test the internal state of the badge
+(because they have no visibility into it), only success/failure.
diff --git a/chromium/third_party/blink/renderer/modules/badging/idls.gni b/chromium/third_party/blink/renderer/modules/badging/idls.gni
new file mode 100644
index 00000000000..7e5cf65e37b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/badging/idls.gni
@@ -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.
+
+modules_dependency_idl_files = [
+ "navigator_badge.idl",
+ "worker_navigator_badge.idl",
+]
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 a6f540dcc9b..fe45efcad80 100644
--- a/chromium/third_party/blink/renderer/modules/badging/navigator_badge.cc
+++ b/chromium/third_party/blink/renderer/modules/badging/navigator_badge.cc
@@ -4,10 +4,13 @@
#include "third_party/blink/renderer/modules/badging/navigator_badge.h"
+#include "build/build_config.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.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/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/frame/navigator.h"
+#include "third_party/blink/renderer/core/workers/worker_navigator.h"
namespace blink {
@@ -25,41 +28,82 @@ NavigatorBadge& NavigatorBadge::From(ScriptState* script_state) {
return *supplement;
}
-NavigatorBadge::NavigatorBadge(ExecutionContext* context) {
- context->GetBrowserInterfaceBroker().GetInterface(
- badge_service_.BindNewPipeAndPassReceiver());
- DCHECK(badge_service_);
-}
+NavigatorBadge::NavigatorBadge(ExecutionContext* context) : context_(context) {}
// static
ScriptPromise NavigatorBadge::setAppBadge(ScriptState* script_state,
Navigator& /*navigator*/) {
- From(script_state)
- .badge_service_->SetBadge(mojom::blink::BadgeValue::NewFlag(0));
- return ScriptPromise::CastUndefined(script_state);
+ return SetAppBadgeHelper(script_state, mojom::blink::BadgeValue::NewFlag(0));
+}
+
+// static
+ScriptPromise NavigatorBadge::setAppBadge(ScriptState* script_state,
+ WorkerNavigator& /*navigator*/) {
+ return SetAppBadgeHelper(script_state, mojom::blink::BadgeValue::NewFlag(0));
}
// static
ScriptPromise NavigatorBadge::setAppBadge(ScriptState* script_state,
- Navigator& navigator,
+ Navigator& /*navigator*/,
uint64_t content) {
- if (content == 0)
- return NavigatorBadge::clearAppBadge(script_state, navigator);
+ return SetAppBadgeHelper(script_state,
+ mojom::blink::BadgeValue::NewNumber(content));
+}
- From(script_state)
- .badge_service_->SetBadge(mojom::blink::BadgeValue::NewNumber(content));
- return ScriptPromise::CastUndefined(script_state);
+// static
+ScriptPromise NavigatorBadge::setAppBadge(ScriptState* script_state,
+ WorkerNavigator& /*navigator*/,
+ uint64_t content) {
+ return SetAppBadgeHelper(script_state,
+ mojom::blink::BadgeValue::NewNumber(content));
}
// static
ScriptPromise NavigatorBadge::clearAppBadge(ScriptState* script_state,
Navigator& /*navigator*/) {
- From(script_state).badge_service_->ClearBadge();
- return ScriptPromise::CastUndefined(script_state);
+ return ClearAppBadgeHelper(script_state);
}
-void NavigatorBadge::Trace(blink::Visitor* visitor) {
+// static
+ScriptPromise NavigatorBadge::clearAppBadge(ScriptState* script_state,
+ WorkerNavigator& /*navigator*/) {
+ return ClearAppBadgeHelper(script_state);
+}
+
+void NavigatorBadge::Trace(Visitor* visitor) {
Supplement<ExecutionContext>::Trace(visitor);
+
+ visitor->Trace(context_);
+}
+
+// static
+ScriptPromise NavigatorBadge::SetAppBadgeHelper(
+ ScriptState* script_state,
+ mojom::blink::BadgeValuePtr badge_value) {
+ if (badge_value->is_number() && badge_value->get_number() == 0)
+ return ClearAppBadgeHelper(script_state);
+
+#if !defined(OS_ANDROID)
+ From(script_state).badge_service()->SetBadge(std::move(badge_value));
+#endif
+ return ScriptPromise::CastUndefined(script_state);
+}
+
+// static
+ScriptPromise NavigatorBadge::ClearAppBadgeHelper(ScriptState* script_state) {
+#if !defined(OS_ANDROID)
+ From(script_state).badge_service()->ClearBadge();
+#endif
+ return ScriptPromise::CastUndefined(script_state);
+}
+
+mojo::Remote<mojom::blink::BadgeService> NavigatorBadge::badge_service() {
+ mojo::Remote<mojom::blink::BadgeService> badge_service;
+ context_->GetBrowserInterfaceBroker().GetInterface(
+ badge_service.BindNewPipeAndPassReceiver());
+ DCHECK(badge_service);
+
+ return badge_service;
}
} // namespace blink
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 e806dce5df3..ed2c5359126 100644
--- a/chromium/third_party/blink/renderer/modules/badging/navigator_badge.h
+++ b/chromium/third_party/blink/renderer/modules/badging/navigator_badge.h
@@ -7,12 +7,14 @@
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/badging/badging.mojom-blink.h"
-#include "third_party/blink/renderer/core/frame/navigator.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/platform/supplementable.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
+class Navigator;
class ScriptPromise;
+class WorkerNavigator;
class NavigatorBadge final : public GarbageCollected<NavigatorBadge>,
public Supplement<ExecutionContext> {
@@ -26,13 +28,27 @@ class NavigatorBadge final : public GarbageCollected<NavigatorBadge>,
// Badge IDL interface.
static ScriptPromise setAppBadge(ScriptState*, Navigator&);
+ static ScriptPromise setAppBadge(ScriptState*, WorkerNavigator&);
+
static ScriptPromise setAppBadge(ScriptState*, Navigator&, uint64_t content);
+ static ScriptPromise setAppBadge(ScriptState*,
+ WorkerNavigator&,
+ uint64_t content);
+
static ScriptPromise clearAppBadge(ScriptState*, Navigator&);
+ static ScriptPromise clearAppBadge(ScriptState*, WorkerNavigator&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
- mojo::Remote<blink::mojom::blink::BadgeService> badge_service_;
+ static ScriptPromise SetAppBadgeHelper(
+ ScriptState* script_state,
+ mojom::blink::BadgeValuePtr badge_value);
+ static ScriptPromise ClearAppBadgeHelper(ScriptState* script_state);
+
+ mojo::Remote<mojom::blink::BadgeService> badge_service();
+
+ Member<ExecutionContext> context_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/badging/navigator_badge.idl b/chromium/third_party/blink/renderer/modules/badging/navigator_badge.idl
index a115a8e06a0..b78be94c9c5 100644
--- a/chromium/third_party/blink/renderer/modules/badging/navigator_badge.idl
+++ b/chromium/third_party/blink/renderer/modules/badging/navigator_badge.idl
@@ -8,9 +8,9 @@
RuntimeEnabled=Badging,
ImplementedAs=NavigatorBadge
] partial interface Navigator {
- [CallWith=ScriptState, MeasureAs=BadgeSet, ImplementedAs=setAppBadge]
- Promise<void> setExperimentalAppBadge(optional [EnforceRange] unsigned long long contents);
+ [CallWith=ScriptState, MeasureAs=BadgeSet]
+ Promise<void> setAppBadge(optional [EnforceRange] unsigned long long contents);
- [CallWith=ScriptState, MeasureAs=BadgeClear, ImplementedAs=clearAppBadge]
- Promise<void> clearExperimentalAppBadge();
+ [CallWith=ScriptState, MeasureAs=BadgeClear]
+ Promise<void> clearAppBadge();
}; \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/badging/worker_navigator_badge.idl b/chromium/third_party/blink/renderer/modules/badging/worker_navigator_badge.idl
new file mode 100644
index 00000000000..f5361629451
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/badging/worker_navigator_badge.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://wicg.github.io/badging/
+[
+ SecureContext,
+ RuntimeEnabled=Badging,
+ ImplementedAs=NavigatorBadge
+] partial interface WorkerNavigator {
+ [Exposed=ServiceWorker, CallWith=ScriptState, MeasureAs=BadgeSet]
+ Promise<void> setAppBadge(optional [EnforceRange] unsigned long long contents);
+
+ [Exposed=ServiceWorker, CallWith=ScriptState, MeasureAs=BadgeClear]
+ Promise<void> clearAppBadge();
+};
diff --git a/chromium/third_party/blink/renderer/modules/battery/BUILD.gn b/chromium/third_party/blink/renderer/modules/battery/BUILD.gn
index 64c9513c20a..26c0a5e697a 100644
--- a/chromium/third_party/blink/renderer/modules/battery/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/battery/BUILD.gn
@@ -15,7 +15,5 @@ blink_modules_sources("battery") {
"navigator_battery.h",
]
- deps = [
- "//services/service_manager/public/cpp",
- ]
+ deps = [ "//services/service_manager/public/cpp" ]
}
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 83c547016a7..4cba33d8750 100644
--- a/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.cc
+++ b/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.cc
@@ -5,7 +5,7 @@
#include "third_party/blink/renderer/modules/battery/battery_dispatcher.h"
#include "services/device/public/mojom/battery_status.mojom-blink.h"
-#include "third_party/blink/public/platform/interface_provider.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/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/platform/mojo/mojo_helper.h"
@@ -47,7 +47,7 @@ void BatteryDispatcher::UpdateBatteryStatus(
void BatteryDispatcher::StartListening(LocalFrame* frame) {
DCHECK(!monitor_.is_bound());
// See https://bit.ly/2S0zRAS for task types.
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
monitor_.BindNewPipeAndPassReceiver(
frame->GetTaskRunner(TaskType::kMiscPlatformAPI)));
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 ca87910880b..cd501889fcc 100644
--- a/chromium/third_party/blink/renderer/modules/battery/battery_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/battery/battery_manager.cc
@@ -24,13 +24,13 @@ BatteryManager* BatteryManager::Create(ExecutionContext* context) {
BatteryManager::~BatteryManager() = default;
BatteryManager::BatteryManager(ExecutionContext* context)
- : ContextLifecycleStateObserver(context),
- PlatformEventController(To<Document>(context)) {}
+ : ExecutionContextLifecycleStateObserver(context),
+ PlatformEventController(Document::From(context)) {}
ScriptPromise BatteryManager::StartRequest(ScriptState* script_state) {
if (!battery_property_) {
battery_property_ = MakeGarbageCollected<BatteryProperty>(
- ExecutionContext::From(script_state), this, BatteryProperty::kReady);
+ ExecutionContext::From(script_state));
// If the context is in a stopped state already, do not start updating.
if (!GetExecutionContext() || GetExecutionContext()->IsContextDestroyed()) {
@@ -66,12 +66,12 @@ void BatteryManager::DidUpdateData() {
BatteryStatus old_status = battery_status_;
battery_status_ = *BatteryDispatcher::Instance().LatestData();
- if (battery_property_->GetState() == ScriptPromisePropertyBase::kPending) {
+ if (battery_property_->GetState() == BatteryProperty::kPending) {
battery_property_->Resolve(this);
return;
}
- Document* document = To<Document>(GetExecutionContext());
+ Document* document = Document::From(GetExecutionContext());
DCHECK(document);
if (document->IsContextPaused() || document->IsContextDestroyed())
return;
@@ -109,7 +109,7 @@ void BatteryManager::ContextLifecycleStateChanged(
}
}
-void BatteryManager::ContextDestroyed(ExecutionContext*) {
+void BatteryManager::ContextDestroyed() {
has_event_listener_ = false;
battery_property_ = nullptr;
StopUpdating();
@@ -120,14 +120,14 @@ bool BatteryManager::HasPendingActivity() const {
// event listeners or pending promises attached to it.
return HasEventListeners() ||
(battery_property_ &&
- battery_property_->GetState() == ScriptPromisePropertyBase::kPending);
+ battery_property_->GetState() == BatteryProperty::kPending);
}
-void BatteryManager::Trace(blink::Visitor* visitor) {
+void BatteryManager::Trace(Visitor* visitor) {
visitor->Trace(battery_property_);
PlatformEventController::Trace(visitor);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleStateObserver::Trace(visitor);
+ ExecutionContextLifecycleStateObserver::Trace(visitor);
}
} // namespace blink
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 66cb8faf344..762d35bbabe 100644
--- a/chromium/third_party/blink/renderer/modules/battery/battery_manager.h
+++ b/chromium/third_party/blink/renderer/modules/battery/battery_manager.h
@@ -8,7 +8,7 @@
#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/core/v8/script_promise_property.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h"
#include "third_party/blink/renderer/core/frame/platform_event_controller.h"
#include "third_party/blink/renderer/modules/battery/battery_status.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
@@ -18,7 +18,7 @@ namespace blink {
class BatteryManager final : public EventTargetWithInlineData,
public ActiveScriptWrappable<BatteryManager>,
- public ContextLifecycleStateObserver,
+ public ExecutionContextLifecycleStateObserver,
public PlatformEventController {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(BatteryManager);
@@ -37,7 +37,7 @@ class BatteryManager final : public EventTargetWithInlineData,
return event_target_names::kBatteryManager;
}
ExecutionContext* GetExecutionContext() const override {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
bool charging();
@@ -58,17 +58,16 @@ class BatteryManager final : public EventTargetWithInlineData,
// ContextLifecycleState implementation.
void ContextLifecycleStateChanged(mojom::FrameLifecycleState) override;
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
// ScriptWrappable implementation.
bool HasPendingActivity() const final;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
- using BatteryProperty = ScriptPromiseProperty<Member<BatteryManager>,
- Member<BatteryManager>,
- Member<DOMException>>;
+ using BatteryProperty =
+ ScriptPromiseProperty<Member<BatteryManager>, Member<DOMException>>;
Member<BatteryProperty> battery_property_;
BatteryStatus battery_status_;
};
diff --git a/chromium/third_party/blink/renderer/modules/battery/idls.gni b/chromium/third_party/blink/renderer/modules/battery/idls.gni
new file mode 100644
index 00000000000..25d6ec90ecb
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/battery/idls.gni
@@ -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.
+
+modules_idl_files = [ "battery_manager.idl" ]
+
+modules_dependency_idl_files = [ "navigator_battery.idl" ]
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 9c5bc07ccf3..032db033a39 100644
--- a/chromium/third_party/blink/renderer/modules/battery/navigator_battery.cc
+++ b/chromium/third_party/blink/renderer/modules/battery/navigator_battery.cc
@@ -25,7 +25,7 @@ ScriptPromise NavigatorBattery::getBattery(ScriptState* script_state) {
// Check to see if this request would be blocked according to the Battery
// Status API specification.
- if (auto* document = To<Document>(context)) {
+ if (auto* document = Document::From(context)) {
LocalFrame* frame = document->GetFrame();
if (frame) {
if (!context->IsSecureContext())
@@ -53,7 +53,7 @@ NavigatorBattery& NavigatorBattery::From(Navigator& navigator) {
return *supplement;
}
-void NavigatorBattery::Trace(blink::Visitor* visitor) {
+void NavigatorBattery::Trace(Visitor* visitor) {
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 e8aa9027444..5c62931ddb3 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<BatteryManager> battery_manager_;
diff --git a/chromium/third_party/blink/renderer/modules/beacon/idls.gni b/chromium/third_party/blink/renderer/modules/beacon/idls.gni
new file mode 100644
index 00000000000..03172bb3a1a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/beacon/idls.gni
@@ -0,0 +1,5 @@
+# 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_dependency_idl_files = [ "navigator_beacon.idl" ]
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 1d1d24458c5..e0457407518 100644
--- a/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.cc
+++ b/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/modules/beacon/navigator_beacon.h"
-#include "third_party/blink/renderer/bindings/modules/v8/array_buffer_view_or_blob_or_string_or_form_data.h"
+#include "third_party/blink/renderer/bindings/modules/v8/array_buffer_view_or_blob_or_string_or_form_data_or_readable_stream.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -17,6 +17,7 @@
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/loader/cors/cors.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
@@ -25,7 +26,7 @@ NavigatorBeacon::NavigatorBeacon(Navigator& navigator)
NavigatorBeacon::~NavigatorBeacon() = default;
-void NavigatorBeacon::Trace(blink::Visitor* visitor) {
+void NavigatorBeacon::Trace(Visitor* visitor) {
Supplement<Navigator>::Trace(visitor);
}
@@ -66,7 +67,7 @@ bool NavigatorBeacon::sendBeacon(
ScriptState* script_state,
Navigator& navigator,
const String& urlstring,
- const ArrayBufferViewOrBlobOrStringOrFormData& data,
+ const ArrayBufferViewOrBlobOrStringOrFormDataOrReadableStream& data,
ExceptionState& exception_state) {
return NavigatorBeacon::From(navigator).SendBeaconImpl(
script_state, urlstring, data, exception_state);
@@ -75,7 +76,7 @@ bool NavigatorBeacon::sendBeacon(
bool NavigatorBeacon::SendBeaconImpl(
ScriptState* script_state,
const String& urlstring,
- const ArrayBufferViewOrBlobOrStringOrFormData& data,
+ const ArrayBufferViewOrBlobOrStringOrFormDataOrReadableStream& data,
ExceptionState& exception_state) {
ExecutionContext* context = ExecutionContext::From(script_state);
KURL url = context->CompleteURL(urlstring);
@@ -99,7 +100,8 @@ bool NavigatorBeacon::SendBeaconImpl(
PingLoader::SendBeacon(GetSupplementable()->GetFrame(), url, data_view);
} else if (data.IsBlob()) {
Blob* blob = data.GetAsBlob();
- if (!cors::IsCorsSafelistedContentType(blob->type())) {
+ if (!RuntimeEnabledFeatures::OutOfBlinkCorsEnabled() &&
+ !cors::IsCorsSafelistedContentType(blob->type())) {
UseCounter::Count(context,
WebFeature::kSendBeaconWithNonSimpleContentType);
if (RuntimeEnabledFeatures::
@@ -119,6 +121,10 @@ bool NavigatorBeacon::SendBeaconImpl(
} else if (data.IsFormData()) {
allowed = PingLoader::SendBeacon(GetSupplementable()->GetFrame(), url,
data.GetAsFormData());
+ } else if (data.IsReadableStream()) {
+ exception_state.ThrowTypeError(
+ "sendBeacon cannot have a ReadableStream body.");
+ return false;
} else {
allowed =
PingLoader::SendBeacon(GetSupplementable()->GetFrame(), url, String());
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 45482512bbd..a21178f7180 100644
--- a/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.h
+++ b/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.h
@@ -14,7 +14,7 @@ namespace blink {
class ScriptState;
class ExceptionState;
class KURL;
-class ArrayBufferViewOrBlobOrStringOrFormData;
+class ArrayBufferViewOrBlobOrStringOrFormDataOrReadableStream;
class NavigatorBeacon final : public GarbageCollected<NavigatorBeacon>,
public Supplement<Navigator> {
@@ -28,19 +28,21 @@ class NavigatorBeacon final : public GarbageCollected<NavigatorBeacon>,
explicit NavigatorBeacon(Navigator&);
virtual ~NavigatorBeacon();
- static bool sendBeacon(ScriptState*,
- Navigator&,
- const String&,
- const ArrayBufferViewOrBlobOrStringOrFormData&,
- ExceptionState&);
+ static bool sendBeacon(
+ ScriptState*,
+ Navigator&,
+ const String&,
+ const ArrayBufferViewOrBlobOrStringOrFormDataOrReadableStream&,
+ ExceptionState&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
- bool SendBeaconImpl(ScriptState*,
- const String&,
- const ArrayBufferViewOrBlobOrStringOrFormData&,
- ExceptionState&);
+ bool SendBeaconImpl(
+ ScriptState*,
+ const String&,
+ const ArrayBufferViewOrBlobOrStringOrFormDataOrReadableStream&,
+ ExceptionState&);
bool CanSendBeacon(ExecutionContext*, const KURL&, ExceptionState&);
};
diff --git a/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.idl b/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.idl
index 372aa13e8f1..72509cb522e 100644
--- a/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.idl
+++ b/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.idl
@@ -7,5 +7,7 @@
[
ImplementedAs=NavigatorBeacon
] partial interface Navigator {
- [CallWith=ScriptState, MeasureAs=SendBeacon, RaisesException] boolean sendBeacon(USVString url, optional (ArrayBufferView or Blob or DOMString or FormData)? data = null);
+ // TODO(ricea): |data| should be BodyInit? when the IDL compiler supports
+ // it.
+ [CallWith=ScriptState, MeasureAs=SendBeacon, RaisesException] boolean sendBeacon(USVString url, optional (ArrayBufferView or Blob or DOMString or FormData or ReadableStream)? data = null);
};
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/BUILD.gn b/chromium/third_party/blink/renderer/modules/bluetooth/BUILD.gn
index eb3b1c8033c..23ac86b9e1e 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/BUILD.gn
@@ -40,7 +40,5 @@ blink_modules_sources("bluetooth") {
"navigator_bluetooth.h",
]
- deps = [
- "//device/bluetooth/public/mojom:mojom_blink",
- ]
+ deps = [ "//device/bluetooth/public/mojom:mojom_blink" ]
}
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
index b8a3e33dd30..6f7a4dd6799 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "build/build_config.h"
#include "mojo/public/cpp/bindings/associated_receiver_set.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
@@ -14,6 +15,9 @@
#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink.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_bluetooth_advertising_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_le_scan_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_request_device_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/dom/events/event.h"
@@ -22,16 +26,14 @@
#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_advertising_event_init.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"
-#include "third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan_options.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.h"
-#include "third_party/blink/renderer/modules/bluetooth/request_device_options.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"
@@ -45,8 +47,25 @@ const size_t kMaxDeviceNameLength = 248;
const char kDeviceNameTooLong[] =
"A device name can't be longer than 248 bytes.";
const char kInactiveDocumentError[] = "Document not active";
+const char kHandleGestureForPermissionRequest[] =
+ "Must be handling a user gesture to show a permission request.";
} // namespace
+// Remind developers when they are using Web Bluetooth on unsupported platforms.
+// TODO(https://crbug.com/570344): Remove this method when all platforms are
+// supported.
+void AddUnsupportedPlatformConsoleMessage(ExecutionContext* context) {
+#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) && !defined(OS_MACOSX) && \
+ !defined(OS_WIN)
+ context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kJavaScript,
+ mojom::blink::ConsoleMessageLevel::kInfo,
+ "Web Bluetooth is experimental on this platform. See "
+ "https://github.com/WebBluetoothCG/web-bluetooth/blob/gh-pages/"
+ "implementation-status.md"));
+#endif
+}
+
static void CanonicalizeFilter(
const BluetoothLEScanFilterInit* filter,
mojom::blink::WebBluetoothLeScanFilterPtr& canonicalized_filter,
@@ -144,12 +163,12 @@ static void ConvertRequestDeviceOptions(
}
}
-ScriptPromise Bluetooth::getAvailability(ScriptState* script_state) {
+ScriptPromise Bluetooth::getAvailability(ScriptState* script_state,
+ ExceptionState& exception_state) {
ExecutionContext* context = GetExecutionContext();
if (!context || context->IsContextDestroyed()) {
- return ScriptPromise::Reject(
- script_state, V8ThrowException::CreateTypeError(
- script_state->GetIsolate(), kInactiveDocumentError));
+ exception_state.ThrowTypeError(kInactiveDocumentError);
+ return ScriptPromise();
}
CHECK(context->IsSecureContext());
@@ -165,6 +184,23 @@ ScriptPromise Bluetooth::getAvailability(ScriptState* script_state) {
return promise;
}
+void Bluetooth::GetDevicesCallback(
+ ScriptPromiseResolver* resolver,
+ Vector<mojom::blink::WebBluetoothDevicePtr> devices) {
+ if (!resolver->GetExecutionContext() ||
+ resolver->GetExecutionContext()->IsContextDestroyed()) {
+ return;
+ }
+
+ HeapVector<Member<BluetoothDevice>> bluetooth_devices;
+ for (auto& device : devices) {
+ BluetoothDevice* bluetooth_device = GetBluetoothDeviceRepresentingDevice(
+ std::move(device), resolver->GetExecutionContext());
+ bluetooth_devices.push_back(*bluetooth_device);
+ }
+ resolver->Resolve(bluetooth_devices);
+}
+
void Bluetooth::RequestDeviceCallback(
ScriptPromiseResolver* resolver,
mojom::blink::WebBluetoothResult result,
@@ -183,46 +219,52 @@ void Bluetooth::RequestDeviceCallback(
}
}
+ScriptPromise Bluetooth::getDevices(ScriptState* script_state,
+ ExceptionState& exception_state) {
+ ExecutionContext* context = GetExecutionContext();
+ if (!context) {
+ exception_state.ThrowTypeError(kInactiveDocumentError);
+ return ScriptPromise();
+ }
+
+ AddUnsupportedPlatformConsoleMessage(context);
+ CHECK(context->IsSecureContext());
+
+ EnsureServiceConnection(context);
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ ScriptPromise promise = resolver->Promise();
+
+ service_->GetDevices(WTF::Bind(&Bluetooth::GetDevicesCallback,
+ WrapPersistent(this),
+ WrapPersistent(resolver)));
+ return promise;
+}
+
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice
ScriptPromise Bluetooth::requestDevice(ScriptState* script_state,
const RequestDeviceOptions* options,
ExceptionState& exception_state) {
ExecutionContext* context = GetExecutionContext();
if (!context) {
- return ScriptPromise::Reject(
- script_state, V8ThrowException::CreateTypeError(
- script_state->GetIsolate(), kInactiveDocumentError));
+ exception_state.ThrowTypeError(kInactiveDocumentError);
+ return ScriptPromise();
}
-// Remind developers when they are using Web Bluetooth on unsupported platforms.
-#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) && !defined(OS_MACOSX) && \
- !defined(OS_WIN)
- context->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kInfo,
- "Web Bluetooth is experimental on this platform. See "
- "https://github.com/WebBluetoothCG/web-bluetooth/blob/gh-pages/"
- "implementation-status.md"));
-#endif
-
+ AddUnsupportedPlatformConsoleMessage(context);
CHECK(context->IsSecureContext());
// If the algorithm is not allowed to show a popup, reject promise with a
// SecurityError and abort these steps.
- auto& doc = *To<Document>(context);
+ auto& doc = *Document::From(context);
auto* frame = doc.GetFrame();
if (!frame) {
- return ScriptPromise::Reject(
- script_state, V8ThrowException::CreateTypeError(
- script_state->GetIsolate(), kInactiveDocumentError));
+ exception_state.ThrowTypeError(kInactiveDocumentError);
+ return ScriptPromise();
}
if (!LocalFrame::HasTransientUserActivation(frame)) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kSecurityError,
- "Must be handling a user gesture to show a permission request."));
+ exception_state.ThrowSecurityError(kHandleGestureForPermissionRequest);
+ return ScriptPromise();
}
EnsureServiceConnection(context);
@@ -308,14 +350,13 @@ ScriptPromise Bluetooth::requestLEScan(ScriptState* script_state,
ExceptionState& exception_state) {
ExecutionContext* context = GetExecutionContext();
if (!context) {
- return ScriptPromise::Reject(
- script_state, V8ThrowException::CreateTypeError(
- script_state->GetIsolate(), kInactiveDocumentError));
+ exception_state.ThrowTypeError(kInactiveDocumentError);
+ return ScriptPromise();
}
// Remind developers when they are using Web Bluetooth on unsupported
// platforms.
- context->AddConsoleMessage(ConsoleMessage::Create(
+ context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kInfo,
"Web Bluetooth Scanning is experimental on this platform. See "
@@ -326,20 +367,16 @@ ScriptPromise Bluetooth::requestLEScan(ScriptState* script_state,
// If the algorithm is not allowed to show a popup, reject promise with a
// SecurityError and abort these steps.
- auto& doc = *To<Document>(context);
+ auto& doc = *Document::From(context);
auto* frame = doc.GetFrame();
if (!frame) {
- return ScriptPromise::Reject(
- script_state, V8ThrowException::CreateTypeError(
- script_state->GetIsolate(), kInactiveDocumentError));
+ exception_state.ThrowTypeError(kInactiveDocumentError);
+ return ScriptPromise();
}
if (!LocalFrame::HasTransientUserActivation(frame)) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kSecurityError,
- "Must be handling a user gesture to show a permission request."));
+ exception_state.ThrowSecurityError(kHandleGestureForPermissionRequest);
+ return ScriptPromise();
}
EnsureServiceConnection(context);
@@ -369,7 +406,8 @@ ScriptPromise Bluetooth::requestLEScan(ScriptState* script_state,
}
void Bluetooth::ScanEvent(mojom::blink::WebBluetoothScanResultPtr result) {
- ExecutionContext* context = ContextLifecycleObserver::GetExecutionContext();
+ ExecutionContext* context =
+ ExecutionContextLifecycleObserver::GetExecutionContext();
DCHECK(context);
BluetoothDevice* bluetooth_device =
@@ -422,23 +460,23 @@ const WTF::AtomicString& Bluetooth::InterfaceName() const {
}
ExecutionContext* Bluetooth::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
-void Bluetooth::ContextDestroyed(ExecutionContext*) {
+void Bluetooth::ContextDestroyed() {
client_receivers_.Clear();
}
-void Bluetooth::Trace(blink::Visitor* visitor) {
+void Bluetooth::Trace(Visitor* visitor) {
visitor->Trace(device_instance_map_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
PageVisibilityObserver::Trace(visitor);
}
Bluetooth::Bluetooth(ExecutionContext* context)
- : ContextLifecycleObserver(context),
- PageVisibilityObserver(To<Document>(context)->GetPage()) {}
+ : ExecutionContextLifecycleObserver(context),
+ PageVisibilityObserver(Document::From(context)->GetPage()) {}
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 2162844de66..9c578d524ec 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.h
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.h
@@ -18,12 +18,13 @@
namespace blink {
class BluetoothLEScanOptions;
+class ExceptionState;
class RequestDeviceOptions;
class ScriptPromise;
class ScriptState;
class Bluetooth final : public EventTargetWithInlineData,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public PageVisibilityObserver,
public mojom::blink::WebBluetoothScanClient {
DEFINE_WRAPPERTYPEINFO();
@@ -34,7 +35,8 @@ class Bluetooth final : public EventTargetWithInlineData,
~Bluetooth() override;
// IDL exposed interface:
- ScriptPromise getAvailability(ScriptState*);
+ ScriptPromise getAvailability(ScriptState*, ExceptionState&);
+ ScriptPromise getDevices(ScriptState*, ExceptionState&);
ScriptPromise requestDevice(ScriptState*,
const RequestDeviceOptions*,
ExceptionState&);
@@ -53,10 +55,10 @@ class Bluetooth final : public EventTargetWithInlineData,
ExecutionContext* GetExecutionContext() const override;
// GC
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
DEFINE_ATTRIBUTE_EVENT_LISTENER(advertisementreceived, kAdvertisementreceived)
@@ -71,6 +73,9 @@ class Bluetooth final : public EventTargetWithInlineData,
mojom::blink::WebBluetoothDevicePtr,
ExecutionContext*);
+ void GetDevicesCallback(ScriptPromiseResolver*,
+ Vector<mojom::blink::WebBluetoothDevicePtr>);
+
void RequestDeviceCallback(ScriptPromiseResolver*,
mojom::blink::WebBluetoothResult,
mojom::blink::WebBluetoothDevicePtr);
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.idl b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.idl
index 7afbe0880a6..21b29c9b24e 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.idl
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.idl
@@ -9,12 +9,13 @@
RuntimeEnabled=WebBluetooth,
SecureContext
] interface Bluetooth : EventTarget {
- [CallWith=ScriptState] Promise<boolean> getAvailability();
- [CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRequestDevice] Promise<BluetoothDevice> requestDevice (optional RequestDeviceOptions options);
+ [CallWith=ScriptState, RaisesException] Promise<boolean> getAvailability();
+ [RuntimeEnabled=WebBluetoothGetDevices, CallWith=ScriptState, RaisesException] Promise<sequence<BluetoothDevice>> getDevices();
+ [CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRequestDevice] Promise<BluetoothDevice> requestDevice (optional RequestDeviceOptions options = {});
- // https://webbluetoothcg.github.io/web-bluetooth/scanning.html#dom-bluetooth-requestlescan
+ // https://webbluetoothcg.github.io/web-bluetooth/scanning.html#scanning
[RuntimeEnabled=WebBluetoothScanning, CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRequestScan]
- Promise<BluetoothLEScan> requestLEScan (optional BluetoothLEScanOptions options);
+ Promise<BluetoothLEScan> requestLEScan (optional BluetoothLEScanOptions options = {});
[RuntimeEnabled=WebBluetoothScanning] attribute EventHandler onadvertisementreceived;
};
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 1cc22d576ea..5ebbeee1158 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
@@ -4,9 +4,9 @@
#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"
#include "third_party/blink/renderer/core/event_type_names.h"
-#include "third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event_init.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_device.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.h"
@@ -48,7 +48,7 @@ BluetoothAdvertisingEvent::BluetoothAdvertisingEvent(
BluetoothAdvertisingEvent::~BluetoothAdvertisingEvent() {}
-void BluetoothAdvertisingEvent::Trace(blink::Visitor* visitor) {
+void BluetoothAdvertisingEvent::Trace(Visitor* visitor) {
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 a9e6a8c9237..46340cfa5d7 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
@@ -34,16 +34,20 @@ class BluetoothAdvertisingEvent final : public Event {
~BluetoothAdvertisingEvent() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
const AtomicString& InterfaceName() const override;
BluetoothDevice* device() const;
const String& name() const;
const HeapVector<StringOrUnsignedLong>& uuids() const;
- uint16_t appearance(bool& is_null) const;
- int8_t txPower(bool& is_null) const;
- int8_t rssi(bool& is_null) const;
+ base::Optional<uint16_t> appearance() const { return appearance_; }
+ base::Optional<int8_t> txPower() const { return txPower_; }
+ base::Optional<int8_t> rssi() const { return rssi_; }
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ uint16_t appearance(bool& is_null) const; // DEPRECATED
+ int8_t txPower(bool& is_null) const; // DEPRECATED
+ int8_t rssi(bool& is_null) const; // DEPRECATED
BluetoothManufacturerDataMap* manufacturerData() const;
BluetoothServiceDataMap* serviceData() const;
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 fc8fb490b17..cc83c5b9c8e 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(blink::Visitor* visitor) {
+void BluetoothAttributeInstanceMap::Trace(Visitor* visitor) {
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 93efa9ef2db..eb7a4eaab67 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(blink::Visitor*);
+ virtual void Trace(Visitor*);
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 97f12f87914..33c715ce3d6 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.cc
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.cc
@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.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"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_error.h"
@@ -23,7 +24,7 @@ namespace blink {
BluetoothDevice::BluetoothDevice(ExecutionContext* context,
mojom::blink::WebBluetoothDevicePtr device,
Bluetooth* bluetooth)
- : ContextLifecycleObserver(context),
+ : ExecutionContextClient(context),
attribute_instance_map_(
MakeGarbageCollected<BluetoothAttributeInstanceMap>(this)),
device_(std::move(device)),
@@ -80,15 +81,15 @@ const WTF::AtomicString& BluetoothDevice::InterfaceName() const {
}
ExecutionContext* BluetoothDevice::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextClient::GetExecutionContext();
}
-void BluetoothDevice::Trace(blink::Visitor* visitor) {
+void BluetoothDevice::Trace(Visitor* visitor) {
visitor->Trace(attribute_instance_map_);
visitor->Trace(gatt_);
visitor->Trace(bluetooth_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
void BluetoothDevice::AddedEventListener(
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 8daeae6fd0e..7744c65b658 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h
@@ -7,7 +7,7 @@
#include <memory>
#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink-forward.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.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"
@@ -30,7 +30,7 @@ class BluetoothRemoteGATTService;
// "Interface required by CallbackPromiseAdapter" section and the
// CallbackPromiseAdapter class comments.
class BluetoothDevice final : public EventTargetWithInlineData,
- public ContextLifecycleObserver {
+ public ExecutionContextClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(BluetoothDevice);
@@ -76,7 +76,7 @@ class BluetoothDevice final : public EventTargetWithInlineData,
Bluetooth* GetBluetooth() { return bluetooth_; }
// Interface required by Garbage Collection:
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// IDL exposed interface:
String id() { return device_->id; }
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 842bc68ed05..fec96c7e663 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_error.cc
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_error.cc
@@ -19,7 +19,7 @@ const char kGATTServerNotConnectedBase[] =
} // namespace
// static
-DOMException* BluetoothError::CreateNotConnectedException(
+String BluetoothError::CreateNotConnectedExceptionMessage(
BluetoothOperation operation) {
const char* operation_string = nullptr;
switch (operation) {
@@ -36,10 +36,15 @@ DOMException* BluetoothError::CreateNotConnectedException(
operation_string = "perform GATT operations";
break;
}
+ return String::Format(kGATTServerNotConnectedBase, operation_string);
+}
+// static
+DOMException* BluetoothError::CreateNotConnectedException(
+ BluetoothOperation operation) {
return MakeGarbageCollected<DOMException>(
DOMExceptionCode::kNetworkError,
- String::Format(kGATTServerNotConnectedBase, operation_string));
+ CreateNotConnectedExceptionMessage(operation));
}
// static
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_error.h b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_error.h
index 2a6ba1e1fdf..42418c0e3f9 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_error.h
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_error.h
@@ -37,6 +37,8 @@ class BluetoothError {
STATIC_ONLY(BluetoothError);
public:
+ static String CreateNotConnectedExceptionMessage(
+ BluetoothOperation operation);
static DOMException* CreateNotConnectedException(BluetoothOperation);
static DOMException* CreateDOMException(BluetoothErrorCode,
const String& detailed_message);
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 017c0d3e6ae..b13d92515c6 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(blink::Visitor* visitor) {
+void BluetoothLEScan::Trace(Visitor* visitor) {
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 0fb2bf26b1d..db63ac48bcb 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
@@ -6,8 +6,8 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_LE_SCAN_H_
#include "mojo/public/cpp/bindings/receiver_set.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_le_scan_filter_init.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth.h"
-#include "third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan_filter_init.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -29,7 +29,7 @@ class BluetoothLEScan final : public ScriptWrappable {
bool stop();
// Interface required by garbage collection.
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 42d879d141f..ef3bd30a856 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 d93c89a59e9..abb169f3db1 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
@@ -22,6 +22,7 @@
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_utils.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.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"
@@ -32,7 +33,7 @@ BluetoothRemoteGATTCharacteristic::BluetoothRemoteGATTCharacteristic(
mojom::blink::WebBluetoothRemoteGATTCharacteristicPtr characteristic,
BluetoothRemoteGATTService* service,
BluetoothDevice* device)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
characteristic_(std::move(characteristic)),
service_(service),
device_(device) {
@@ -52,7 +53,7 @@ void BluetoothRemoteGATTCharacteristic::RemoteCharacteristicValueChanged(
DispatchEvent(*Event::Create(event_type_names::kCharacteristicvaluechanged));
}
-void BluetoothRemoteGATTCharacteristic::ContextDestroyed(ExecutionContext*) {
+void BluetoothRemoteGATTCharacteristic::ContextDestroyed() {
Dispose();
}
@@ -67,7 +68,7 @@ const WTF::AtomicString& BluetoothRemoteGATTCharacteristic::InterfaceName()
ExecutionContext* BluetoothRemoteGATTCharacteristic::GetExecutionContext()
const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
bool BluetoothRemoteGATTCharacteristic::HasPendingActivity() const {
@@ -113,17 +114,22 @@ void BluetoothRemoteGATTCharacteristic::ReadValueCallback(
}
ScriptPromise BluetoothRemoteGATTCharacteristic::readValue(
- ScriptState* script_state) {
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
if (!GetGatt()->connected()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- BluetoothError::CreateNotConnectedException(BluetoothOperation::kGATT));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNetworkError,
+ BluetoothError::CreateNotConnectedExceptionMessage(
+ BluetoothOperation::kGATT));
+ return ScriptPromise();
}
if (!GetGatt()->device()->IsValidCharacteristic(
characteristic_->instance_id)) {
- return ScriptPromise::RejectWithDOMException(
- script_state, CreateInvalidCharacteristicError());
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ CreateInvalidCharacteristicErrorMessage());
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -165,24 +171,28 @@ void BluetoothRemoteGATTCharacteristic::WriteValueCallback(
ScriptPromise BluetoothRemoteGATTCharacteristic::writeValue(
ScriptState* script_state,
- const DOMArrayPiece& value) {
+ const DOMArrayPiece& value,
+ ExceptionState& exception_state) {
if (!GetGatt()->connected()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- BluetoothError::CreateNotConnectedException(BluetoothOperation::kGATT));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNetworkError,
+ BluetoothError::CreateNotConnectedExceptionMessage(
+ BluetoothOperation::kGATT));
+ return ScriptPromise();
}
if (!GetGatt()->device()->IsValidCharacteristic(
characteristic_->instance_id)) {
- return ScriptPromise::RejectWithDOMException(
- script_state, CreateInvalidCharacteristicError());
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ CreateInvalidCharacteristicErrorMessage());
+ return ScriptPromise();
}
if (value.IsDetached()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- "Value buffer has been detached."));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Value buffer has been detached.");
+ return ScriptPromise();
}
// Partial implementation of writeValue algorithm:
@@ -192,10 +202,10 @@ ScriptPromise BluetoothRemoteGATTCharacteristic::writeValue(
// value, per Long Attribute Values) return a promise rejected with an
// InvalidModificationError and abort.
if (value.ByteLengthAsSizeT() > 512) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidModificationError,
- "Value can't exceed 512 bytes."));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidModificationError,
+ "Value can't exceed 512 bytes.");
+ return ScriptPromise();
}
// Let valueVector be a copy of the bytes held by value.
@@ -239,17 +249,22 @@ void BluetoothRemoteGATTCharacteristic::NotificationsCallback(
}
ScriptPromise BluetoothRemoteGATTCharacteristic::startNotifications(
- ScriptState* script_state) {
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
if (!GetGatt()->connected()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- BluetoothError::CreateNotConnectedException(BluetoothOperation::kGATT));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNetworkError,
+ BluetoothError::CreateNotConnectedExceptionMessage(
+ BluetoothOperation::kGATT));
+ return ScriptPromise();
}
if (!GetGatt()->device()->IsValidCharacteristic(
characteristic_->instance_id)) {
- return ScriptPromise::RejectWithDOMException(
- script_state, CreateInvalidCharacteristicError());
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ CreateInvalidCharacteristicErrorMessage());
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -274,17 +289,22 @@ ScriptPromise BluetoothRemoteGATTCharacteristic::startNotifications(
}
ScriptPromise BluetoothRemoteGATTCharacteristic::stopNotifications(
- ScriptState* script_state) {
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
if (!GetGatt()->connected()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- BluetoothError::CreateNotConnectedException(BluetoothOperation::kGATT));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNetworkError,
+ BluetoothError::CreateNotConnectedExceptionMessage(
+ BluetoothOperation::kGATT));
+ return ScriptPromise();
}
if (!GetGatt()->device()->IsValidCharacteristic(
characteristic_->instance_id)) {
- return ScriptPromise::RejectWithDOMException(
- script_state, CreateInvalidCharacteristicError());
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ CreateInvalidCharacteristicErrorMessage());
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -310,16 +330,17 @@ ScriptPromise BluetoothRemoteGATTCharacteristic::getDescriptor(
if (exception_state.HadException())
return ScriptPromise();
- return GetDescriptorsImpl(script_state,
+ return GetDescriptorsImpl(script_state, exception_state,
mojom::blink::WebBluetoothGATTQueryQuantity::SINGLE,
descriptor);
}
ScriptPromise BluetoothRemoteGATTCharacteristic::getDescriptors(
ScriptState* script_state,
- ExceptionState&) {
+ ExceptionState& exception_state) {
return GetDescriptorsImpl(
- script_state, mojom::blink::WebBluetoothGATTQueryQuantity::MULTIPLE);
+ script_state, exception_state,
+ mojom::blink::WebBluetoothGATTQueryQuantity::MULTIPLE);
}
ScriptPromise BluetoothRemoteGATTCharacteristic::getDescriptors(
@@ -332,24 +353,29 @@ ScriptPromise BluetoothRemoteGATTCharacteristic::getDescriptors(
return ScriptPromise();
return GetDescriptorsImpl(
- script_state, mojom::blink::WebBluetoothGATTQueryQuantity::MULTIPLE,
- descriptor);
+ script_state, exception_state,
+ mojom::blink::WebBluetoothGATTQueryQuantity::MULTIPLE, descriptor);
}
ScriptPromise BluetoothRemoteGATTCharacteristic::GetDescriptorsImpl(
ScriptState* script_state,
+ ExceptionState& exception_state,
mojom::blink::WebBluetoothGATTQueryQuantity quantity,
const String& descriptors_uuid) {
if (!GetGatt()->connected()) {
- return ScriptPromise::RejectWithDOMException(
- script_state, BluetoothError::CreateNotConnectedException(
- BluetoothOperation::kDescriptorsRetrieval));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNetworkError,
+ BluetoothError::CreateNotConnectedExceptionMessage(
+ BluetoothOperation::kDescriptorsRetrieval));
+ return ScriptPromise();
}
if (!GetGatt()->device()->IsValidCharacteristic(
characteristic_->instance_id)) {
- return ScriptPromise::RejectWithDOMException(
- script_state, CreateInvalidCharacteristicError());
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ CreateInvalidCharacteristicErrorMessage());
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -420,22 +446,20 @@ void BluetoothRemoteGATTCharacteristic::GetDescriptorsCallback(
}
}
-DOMException*
-BluetoothRemoteGATTCharacteristic::CreateInvalidCharacteristicError() {
- return BluetoothError::CreateDOMException(
- BluetoothErrorCode::kInvalidCharacteristic,
- "Characteristic with UUID " + uuid() +
- " is no longer valid. Remember to retrieve the characteristic again "
- "after reconnecting.");
+String
+BluetoothRemoteGATTCharacteristic::CreateInvalidCharacteristicErrorMessage() {
+ return "Characteristic with UUID " + uuid() +
+ " is no longer valid. Remember to retrieve the characteristic again "
+ "after reconnecting.";
}
-void BluetoothRemoteGATTCharacteristic::Trace(blink::Visitor* visitor) {
+void BluetoothRemoteGATTCharacteristic::Trace(Visitor* visitor) {
visitor->Trace(service_);
visitor->Trace(properties_);
visitor->Trace(value_);
visitor->Trace(device_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 fbe7df6c7ce..caa282719ee 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
@@ -8,7 +8,7 @@
#include "mojo/public/cpp/bindings/associated_receiver_set.h"
#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/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_piece.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_data_view.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.h"
@@ -21,7 +21,7 @@ namespace blink {
class BluetoothCharacteristicProperties;
class BluetoothDevice;
-class DOMException;
+class ExceptionState;
class ExecutionContext;
class ScriptPromise;
class ScriptState;
@@ -37,7 +37,7 @@ class ScriptState;
class BluetoothRemoteGATTCharacteristic final
: public EventTargetWithInlineData,
public ActiveScriptWrappable<BluetoothRemoteGATTCharacteristic>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public mojom::blink::WebBluetoothCharacteristicClient {
USING_PRE_FINALIZER(BluetoothRemoteGATTCharacteristic, Dispose);
DEFINE_WRAPPERTYPEINFO();
@@ -57,8 +57,8 @@ class BluetoothRemoteGATTCharacteristic final
void RemoteCharacteristicValueChanged(
const WTF::Vector<uint8_t>& value) override;
- // ContextLifecycleObserver interface.
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver interface.
+ void ContextDestroyed() override;
// USING_PRE_FINALIZER interface.
// Called before the object gets garbage collected.
@@ -72,7 +72,7 @@ class BluetoothRemoteGATTCharacteristic final
bool HasPendingActivity() const override;
// Interface required by garbage collection.
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// IDL exposed interface:
BluetoothRemoteGATTService* service() { return service_; }
@@ -86,10 +86,10 @@ class BluetoothRemoteGATTCharacteristic final
ScriptPromise getDescriptors(ScriptState*,
const StringOrUnsignedLong& descriptor,
ExceptionState&);
- ScriptPromise readValue(ScriptState*);
- ScriptPromise writeValue(ScriptState*, const DOMArrayPiece&);
- ScriptPromise startNotifications(ScriptState*);
- ScriptPromise stopNotifications(ScriptState*);
+ ScriptPromise readValue(ScriptState*, ExceptionState&);
+ ScriptPromise writeValue(ScriptState*, const DOMArrayPiece&, ExceptionState&);
+ ScriptPromise startNotifications(ScriptState*, ExceptionState&);
+ ScriptPromise stopNotifications(ScriptState*, ExceptionState&);
DEFINE_ATTRIBUTE_EVENT_LISTENER(characteristicvaluechanged,
kCharacteristicvaluechanged)
@@ -114,6 +114,7 @@ class BluetoothRemoteGATTCharacteristic final
mojom::blink::WebBluetoothResult);
ScriptPromise GetDescriptorsImpl(ScriptState*,
+ ExceptionState&,
mojom::blink::WebBluetoothGATTQueryQuantity,
const String& descriptor_uuid = String());
@@ -126,7 +127,7 @@ class BluetoothRemoteGATTCharacteristic final
base::Optional<Vector<mojom::blink::WebBluetoothRemoteGATTDescriptorPtr>>
descriptors);
- DOMException* CreateInvalidCharacteristicError();
+ String CreateInvalidCharacteristicErrorMessage();
mojom::blink::WebBluetoothRemoteGATTCharacteristicPtr characteristic_;
Member<BluetoothRemoteGATTService> service_;
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 3b8eb1397cf..532bd69d233 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
@@ -16,10 +16,10 @@
readonly attribute DataView? value;
[RaisesException, CallWith=ScriptState, MeasureAs=WebBluetoothRemoteCharacteristicGetDescriptor] Promise<BluetoothRemoteGATTDescriptor> getDescriptor(BluetoothDescriptorUUID descriptor);
[RaisesException, CallWith=ScriptState, MeasureAs=WebBluetoothRemoteCharacteristicGetDescriptors] Promise<sequence<BluetoothRemoteGATTDescriptor>> getDescriptors(optional BluetoothDescriptorUUID descriptor);
- [CallWith=ScriptState, MeasureAs=WebBluetoothRemoteCharacteristicReadValue] Promise<DataView> readValue();
- [CallWith=ScriptState, MeasureAs=WebBluetoothRemoteCharacteristicWriteValue] Promise<void> writeValue(BufferSource value);
- [CallWith=ScriptState, MeasureAs=WebBluetoothRemoteCharacteristicStartNotifications] Promise<BluetoothRemoteGATTCharacteristic> startNotifications();
- [CallWith=ScriptState, MeasureAs=WebBluetoothRemoteCharacteristicStopNotifications] Promise<BluetoothRemoteGATTCharacteristic> stopNotifications();
+ [CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRemoteCharacteristicReadValue] Promise<DataView> readValue();
+ [CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRemoteCharacteristicWriteValue] Promise<void> writeValue(BufferSource value);
+ [CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRemoteCharacteristicStartNotifications] Promise<BluetoothRemoteGATTCharacteristic> startNotifications();
+ [CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRemoteCharacteristicStopNotifications] Promise<BluetoothRemoteGATTCharacteristic> stopNotifications();
// TODO(ortuno): Move this to CharacteristicEventHandlers.
// http://crbug.com/537459
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 5de7686ffd3..f8408a33a40 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
@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_error.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_utils.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"
@@ -49,16 +50,20 @@ void BluetoothRemoteGATTDescriptor::ReadValueCallback(
}
ScriptPromise BluetoothRemoteGATTDescriptor::readValue(
- ScriptState* script_state) {
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
if (!GetGatt()->connected()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- BluetoothError::CreateNotConnectedException(BluetoothOperation::kGATT));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNetworkError,
+ BluetoothError::CreateNotConnectedExceptionMessage(
+ BluetoothOperation::kGATT));
+ return ScriptPromise();
}
if (!GetGatt()->device()->IsValidDescriptor(descriptor_->instance_id)) {
- return ScriptPromise::RejectWithDOMException(
- script_state, CreateInvalidDescriptorError());
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ CreateInvalidDescriptorErrorMessage());
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -98,23 +103,26 @@ void BluetoothRemoteGATTDescriptor::WriteValueCallback(
ScriptPromise BluetoothRemoteGATTDescriptor::writeValue(
ScriptState* script_state,
- const DOMArrayPiece& value) {
+ const DOMArrayPiece& value,
+ ExceptionState& exception_state) {
if (!GetGatt()->connected()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- BluetoothError::CreateNotConnectedException(BluetoothOperation::kGATT));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNetworkError,
+ BluetoothError::CreateNotConnectedExceptionMessage(
+ BluetoothOperation::kGATT));
+ return ScriptPromise();
}
if (!GetGatt()->device()->IsValidDescriptor(descriptor_->instance_id)) {
- return ScriptPromise::RejectWithDOMException(
- script_state, CreateInvalidDescriptorError());
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ CreateInvalidDescriptorErrorMessage());
+ return ScriptPromise();
}
if (value.IsDetached()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- "Value buffer has been detached."));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Value buffer has been detached.");
+ return ScriptPromise();
}
// Partial implementation of writeValue algorithm:
@@ -124,10 +132,10 @@ ScriptPromise BluetoothRemoteGATTDescriptor::writeValue(
// value, per Long Attribute Values) return a promise rejected with an
// InvalidModificationError and abort.
if (value.ByteLengthAsSizeT() > 512) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidModificationError,
- "Value can't exceed 512 bytes."));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidModificationError,
+ "Value can't exceed 512 bytes.");
+ return ScriptPromise();
}
// Let valueVector be a copy of the bytes held by value.
@@ -146,15 +154,13 @@ ScriptPromise BluetoothRemoteGATTDescriptor::writeValue(
return promise;
}
-DOMException* BluetoothRemoteGATTDescriptor::CreateInvalidDescriptorError() {
- return BluetoothError::CreateDOMException(
- BluetoothErrorCode::kInvalidDescriptor,
- "Descriptor with UUID " + uuid() +
- " is no longer valid. Remember to retrieve the Descriptor again "
- "after reconnecting.");
+String BluetoothRemoteGATTDescriptor::CreateInvalidDescriptorErrorMessage() {
+ return "Descriptor with UUID " + uuid() +
+ " is no longer valid. Remember to retrieve the Descriptor again "
+ "after reconnecting.";
}
-void BluetoothRemoteGATTDescriptor::Trace(blink::Visitor* visitor) {
+void BluetoothRemoteGATTDescriptor::Trace(Visitor* visitor) {
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 ec14d3d12ed..2022babba6d 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
@@ -18,6 +18,7 @@
namespace blink {
+class ExceptionState;
class BluetoothRemoteGATTCharacteristic;
class ScriptPromise;
class ScriptState;
@@ -39,11 +40,11 @@ class BluetoothRemoteGATTDescriptor final : public ScriptWrappable {
}
String uuid() { return descriptor_->uuid; }
DOMDataView* value() const { return value_; }
- ScriptPromise readValue(ScriptState*);
- ScriptPromise writeValue(ScriptState*, const DOMArrayPiece&);
+ ScriptPromise readValue(ScriptState*, ExceptionState&);
+ ScriptPromise writeValue(ScriptState*, const DOMArrayPiece&, ExceptionState&);
// Interface required by garbage collection.
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
friend class DescriptorReadValueCallback;
@@ -61,7 +62,7 @@ class BluetoothRemoteGATTDescriptor final : public ScriptWrappable {
const Vector<uint8_t>&,
mojom::blink::WebBluetoothResult);
- DOMException* CreateInvalidDescriptorError();
+ String CreateInvalidDescriptorErrorMessage();
mojom::blink::WebBluetoothRemoteGATTDescriptorPtr descriptor_;
Member<BluetoothRemoteGATTCharacteristic> characteristic_;
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.idl b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.idl
index 31c55140cc2..14da64f3a1d 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.idl
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.idl
@@ -13,6 +13,6 @@
[SameObject] readonly attribute BluetoothRemoteGATTCharacteristic characteristic;
readonly attribute UUID uuid;
readonly attribute DataView? value;
- [CallWith=ScriptState, MeasureAs=WebBluetoothRemoteDescriptorReadValue] Promise<DataView> readValue();
- [CallWith=ScriptState, MeasureAs=WebBluetoothRemoteDescriptorWriteValue] Promise<void> writeValue(BufferSource value);
+ [CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRemoteDescriptorReadValue] Promise<DataView> readValue();
+ [CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRemoteDescriptorWriteValue] Promise<void> writeValue(BufferSource value);
};
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 a74a57460da..dba1c16a5bf 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
@@ -19,15 +19,18 @@
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_error.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
BluetoothRemoteGATTServer::BluetoothRemoteGATTServer(ExecutionContext* context,
BluetoothDevice* device)
- : ContextLifecycleObserver(context), device_(device), connected_(false) {}
+ : ExecutionContextLifecycleObserver(context),
+ device_(device),
+ connected_(false) {}
-void BluetoothRemoteGATTServer::ContextDestroyed(ExecutionContext*) {
+void BluetoothRemoteGATTServer::ContextDestroyed() {
Dispose();
}
@@ -81,11 +84,11 @@ void BluetoothRemoteGATTServer::Dispose() {
client_receivers_.Clear();
}
-void BluetoothRemoteGATTServer::Trace(blink::Visitor* visitor) {
+void BluetoothRemoteGATTServer::Trace(Visitor* visitor) {
visitor->Trace(active_algorithms_);
visitor->Trace(device_);
ScriptWrappable::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
void BluetoothRemoteGATTServer::ConnectCallback(
@@ -193,8 +196,8 @@ ScriptPromise BluetoothRemoteGATTServer::getPrimaryService(
return ScriptPromise();
return GetPrimaryServicesImpl(
- script_state, mojom::blink::WebBluetoothGATTQueryQuantity::SINGLE,
- service_uuid);
+ script_state, exception_state,
+ mojom::blink::WebBluetoothGATTQueryQuantity::SINGLE, service_uuid);
}
ScriptPromise BluetoothRemoteGATTServer::getPrimaryServices(
@@ -206,25 +209,29 @@ ScriptPromise BluetoothRemoteGATTServer::getPrimaryServices(
return ScriptPromise();
return GetPrimaryServicesImpl(
- script_state, mojom::blink::WebBluetoothGATTQueryQuantity::MULTIPLE,
- service_uuid);
+ script_state, exception_state,
+ mojom::blink::WebBluetoothGATTQueryQuantity::MULTIPLE, service_uuid);
}
ScriptPromise BluetoothRemoteGATTServer::getPrimaryServices(
ScriptState* script_state,
- ExceptionState&) {
+ ExceptionState& exception_state) {
return GetPrimaryServicesImpl(
- script_state, mojom::blink::WebBluetoothGATTQueryQuantity::MULTIPLE);
+ script_state, exception_state,
+ mojom::blink::WebBluetoothGATTQueryQuantity::MULTIPLE);
}
ScriptPromise BluetoothRemoteGATTServer::GetPrimaryServicesImpl(
ScriptState* script_state,
+ ExceptionState& exception_state,
mojom::blink::WebBluetoothGATTQueryQuantity quantity,
String services_uuid) {
if (!connected_) {
- return ScriptPromise::RejectWithDOMException(
- script_state, BluetoothError::CreateNotConnectedException(
- BluetoothOperation::kServicesRetrieval));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNetworkError,
+ BluetoothError::CreateNotConnectedExceptionMessage(
+ BluetoothOperation::kServicesRetrieval));
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
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 73c60c1f90f..52b7f5e799b 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
@@ -8,7 +8,7 @@
#include "mojo/public/cpp/bindings/associated_receiver_set.h"
#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink.h"
#include "third_party/blink/renderer/bindings/modules/v8/string_or_unsigned_long.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/heap.h"
@@ -17,6 +17,7 @@
namespace blink {
class BluetoothDevice;
+class ExceptionState;
class ScriptPromise;
class ScriptPromiseResolver;
class ScriptState;
@@ -25,7 +26,7 @@ class ScriptState;
// bluetooth peripheral.
class BluetoothRemoteGATTServer
: public ScriptWrappable,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public mojom::blink::WebBluetoothServerClient {
USING_PRE_FINALIZER(BluetoothRemoteGATTServer, Dispose);
DEFINE_WRAPPERTYPEINFO();
@@ -34,8 +35,8 @@ class BluetoothRemoteGATTServer
public:
BluetoothRemoteGATTServer(ExecutionContext*, BluetoothDevice*);
- // ContextLifecycleObserver:
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver:
+ void ContextDestroyed() override;
// mojom::blink::WebBluetoothServerClient:
void GATTServerDisconnected() override;
@@ -73,7 +74,7 @@ class BluetoothRemoteGATTServer
void Dispose();
// Interface required by Garbage Collectoin:
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// IDL exposed interface:
BluetoothDevice* device() { return device_; }
@@ -91,6 +92,7 @@ class BluetoothRemoteGATTServer
private:
ScriptPromise GetPrimaryServicesImpl(
ScriptState*,
+ ExceptionState&,
mojom::blink::WebBluetoothGATTQueryQuantity,
String service_uuid = String());
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 3397225e3cd..63f38fe71e8 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
@@ -13,6 +13,7 @@
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_error.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h"
#include "third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
@@ -27,7 +28,7 @@ BluetoothRemoteGATTService::BluetoothRemoteGATTService(
device_instance_id_(device_instance_id),
device_(device) {}
-void BluetoothRemoteGATTService::Trace(blink::Visitor* visitor) {
+void BluetoothRemoteGATTService::Trace(Visitor* visitor) {
visitor->Trace(device_);
ScriptWrappable::Trace(visitor);
}
@@ -96,8 +97,8 @@ ScriptPromise BluetoothRemoteGATTService::getCharacteristic(
return ScriptPromise();
return GetCharacteristicsImpl(
- script_state, mojom::blink::WebBluetoothGATTQueryQuantity::SINGLE,
- characteristic_uuid);
+ script_state, exception_state,
+ mojom::blink::WebBluetoothGATTQueryQuantity::SINGLE, characteristic_uuid);
}
ScriptPromise BluetoothRemoteGATTService::getCharacteristics(
@@ -110,34 +111,39 @@ ScriptPromise BluetoothRemoteGATTService::getCharacteristics(
return ScriptPromise();
return GetCharacteristicsImpl(
- script_state, mojom::blink::WebBluetoothGATTQueryQuantity::MULTIPLE,
+ script_state, exception_state,
+ mojom::blink::WebBluetoothGATTQueryQuantity::MULTIPLE,
characteristic_uuid);
}
ScriptPromise BluetoothRemoteGATTService::getCharacteristics(
ScriptState* script_state,
- ExceptionState&) {
+ ExceptionState& exception_state) {
return GetCharacteristicsImpl(
- script_state, mojom::blink::WebBluetoothGATTQueryQuantity::MULTIPLE);
+ script_state, exception_state,
+ mojom::blink::WebBluetoothGATTQueryQuantity::MULTIPLE);
}
ScriptPromise BluetoothRemoteGATTService::GetCharacteristicsImpl(
ScriptState* script_state,
+ ExceptionState& exception_state,
mojom::blink::WebBluetoothGATTQueryQuantity quantity,
const String& characteristics_uuid) {
if (!device_->gatt()->connected()) {
- return ScriptPromise::RejectWithDOMException(
- script_state, BluetoothError::CreateNotConnectedException(
- BluetoothOperation::kCharacteristicsRetrieval));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNetworkError,
+ BluetoothError::CreateNotConnectedExceptionMessage(
+ BluetoothOperation::kCharacteristicsRetrieval));
+ return ScriptPromise();
}
if (!device_->IsValidService(service_->instance_id)) {
- return ScriptPromise::RejectWithDOMException(
- script_state, BluetoothError::CreateDOMException(
- BluetoothErrorCode::kInvalidService,
- "Service with UUID " + service_->uuid +
- " is no longer valid. Remember to retrieve "
- "the service again after reconnecting."));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "Service with UUID " + service_->uuid +
+ " is no longer valid. Remember to retrieve "
+ "the service again after reconnecting.");
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
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 4b351c0cf85..0ae8905a417 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
@@ -16,6 +16,7 @@
namespace blink {
+class ExceptionState;
class ScriptPromise;
class ScriptState;
@@ -37,7 +38,7 @@ class BluetoothRemoteGATTService final : public ScriptWrappable {
BluetoothDevice*);
// Interface required by garbage collection.
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// IDL exposed interface:
String uuid() { return service_->uuid; }
@@ -64,6 +65,7 @@ class BluetoothRemoteGATTService final : public ScriptWrappable {
ScriptPromise GetCharacteristicsImpl(
ScriptState*,
+ ExceptionState&,
mojom::blink::WebBluetoothGATTQueryQuantity,
const String& characteristic_uuid = String());
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 e0c3feaef68..21221ed557a 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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
new file mode 100644
index 00000000000..22354b698f5
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "bluetooth.idl",
+ "bluetooth_advertising_event.idl",
+ "bluetooth_characteristic_properties.idl",
+ "bluetooth_device.idl",
+ "bluetooth_le_scan.idl",
+ "bluetooth_manufacturer_data_map.idl",
+ "bluetooth_remote_gatt_characteristic.idl",
+ "bluetooth_remote_gatt_descriptor.idl",
+ "bluetooth_remote_gatt_server.idl",
+ "bluetooth_remote_gatt_service.idl",
+ "bluetooth_service_data_map.idl",
+ "bluetooth_uuid.idl",
+]
+
+modules_dictionary_idl_files = [
+ "bluetooth_advertising_event_init.idl",
+ "bluetooth_le_scan_filter_init.idl",
+ "bluetooth_le_scan_options.idl",
+ "request_device_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 3acc1bdbc53..6fe93b68fd3 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.cc
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.cc
@@ -37,7 +37,7 @@ Bluetooth* NavigatorBluetooth::bluetooth() {
return bluetooth_.Get();
}
-void NavigatorBluetooth::Trace(blink::Visitor* visitor) {
+void NavigatorBluetooth::Trace(Visitor* visitor) {
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 83b7518af91..ec611db8500 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<Bluetooth> bluetooth_;
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/PRESUBMIT.py b/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/PRESUBMIT.py
index 39bd8055efd..9c3f101ac51 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/PRESUBMIT.py
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/PRESUBMIT.py
@@ -1,7 +1,6 @@
# 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.
-
"""Script that runs tests before uploading a patch."""
@@ -10,10 +9,7 @@ def _RunTests(input_api, output_api):
cmd_name = 'all_python_tests'
cmd = ['python', '-m', 'unittest', 'discover', '-p', '*test.py']
test_cmd = input_api.Command(
- name=cmd_name,
- cmd=cmd,
- kwargs={},
- message=output_api.PresubmitError)
+ name=cmd_name, cmd=cmd, kwargs={}, message=output_api.PresubmitError)
if input_api.verbose:
print 'Running ' + cmd_name
return input_api.RunTests([test_cmd])
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/constraints.py b/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/constraints.py
index 11c31764dab..01e2f10c39d 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/constraints.py
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/constraints.py
@@ -1,7 +1,6 @@
# 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.
-
"""Module to get random numbers, strings, etc.
The values returned by the various functions can be replaced in
@@ -23,7 +22,6 @@ from resources import fuzzy_types
import gatt_aliases
import wbt_fakes
-
# Strings that are used to generate the beginning of a test. The replacement
# fields are replaced by Get*Base() functions below to generate valid test
# cases.
@@ -102,8 +100,8 @@ def _get_array_of_random_ints(max_length, max_value):
length = utils.UniformExpoInteger(0, math.log(max_length, 2))
exp_max_value = math.log(max_value, 2)
return '[{}]'.format(', '.join(
- str(utils.UniformExpoInteger(0, exp_max_value)) for _ in xrange(length))
- )
+ str(utils.UniformExpoInteger(0, exp_max_value))
+ for _ in xrange(length)))
def _get_typed_array():
@@ -133,10 +131,10 @@ def _get_typed_array():
A string made up of a randomly chosen type and argument type from the
lists above.
"""
- array_type = random.choice(['Int8Array', 'Int16Array', 'Int32Array',
- 'Uint8Array', 'Uint16Array', 'Uint32Array',
- 'Uint8ClampedArray', 'Float32Array',
- 'Float64Array'])
+ array_type = random.choice([
+ 'Int8Array', 'Int16Array', 'Int32Array', 'Uint8Array', 'Uint16Array',
+ 'Uint32Array', 'Uint8ClampedArray', 'Float32Array', 'Float64Array'
+ ])
# Choose an argument type at random.
arguments = random.choice([
@@ -147,13 +145,13 @@ def _get_typed_array():
# typedArray e.g. new Uint8Array([1,2,3])
_get_typed_array,
# object e.g. [1,2,3]
- lambda: _get_array_of_random_ints(max_length=1000, max_value=2 ** 64),
+ lambda: _get_array_of_random_ints(max_length=1000, max_value=2**64),
# buffer e.g. new Uint8Array(10).buffer
lambda: _get_typed_array() + '.buffer',
])
- return 'new {array_type}({arguments})'.format(array_type=array_type,
- arguments=arguments())
+ return 'new {array_type}({arguments})'.format(
+ array_type=array_type, arguments=arguments())
def GetAdvertisedServiceUUIDFromFakes():
@@ -343,8 +341,8 @@ def get_characteristics_retrieved_base():
optional_service_uuid = random.choice(['', service_uuid])
optional_characteristic_uuid = random.choice(['', characteristic_uuid])
- services_base = random.choice([SERVICE_RETRIEVED_BASE,
- SERVICES_RETRIEVED_BASE])
+ services_base = random.choice(
+ [SERVICE_RETRIEVED_BASE, SERVICES_RETRIEVED_BASE])
characteristics_base = services_base + random.choice([
CHARACTERISTIC_RETRIEVED_BASE,
@@ -360,8 +358,10 @@ def get_characteristics_retrieved_base():
def get_get_primary_services_call():
- call = random.choice([u'getPrimaryService({service_uuid})',
- u'getPrimaryServices({optional_service_uuid})'])
+ call = random.choice([
+ u'getPrimaryService({service_uuid})',
+ u'getPrimaryServices({optional_service_uuid})'
+ ])
return call.format(
service_uuid=get_service_uuid(),
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/fuzz_integration_test.py b/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/fuzz_integration_test.py
index 4080b8a2870..9b37e5a1a49 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/fuzz_integration_test.py
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/fuzz_integration_test.py
@@ -1,7 +1,6 @@
# 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.
-
"""Test that the fuzzer works the way ClusterFuzz invokes it."""
import glob
@@ -15,7 +14,6 @@ import setup
class WebBluetoothFuzzerTest(unittest.TestCase):
-
def setUp(self):
self._output_dir = tempfile.mkdtemp()
self._resources_path = setup.RetrieveResources()
@@ -25,9 +23,10 @@ class WebBluetoothFuzzerTest(unittest.TestCase):
shutil.rmtree(self._resources_path)
def testCanGenerate100Files(self):
- sys.argv = ['fuzz_main_run.py', '--no_of_files=100',
- '--input_dir={}'.format(self._output_dir),
- '--output_dir={}'.format(self._output_dir)]
+ sys.argv = [
+ 'fuzz_main_run.py', '--no_of_files=100', '--input_dir={}'.format(
+ self._output_dir), '--output_dir={}'.format(self._output_dir)
+ ]
import fuzz_main_run
fuzz_main_run.main()
@@ -40,5 +39,6 @@ class WebBluetoothFuzzerTest(unittest.TestCase):
for test_case in written_files:
self.assertFalse('TRANSFORM' in open(test_case).read())
+
if __name__ == '__main__':
unittest.main()
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/fuzz_main_run.py b/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/fuzz_main_run.py
index d4f2f055f38..1703291f939 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/fuzz_main_run.py
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/fuzz_main_run.py
@@ -1,7 +1,6 @@
# 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.
-
"""Script to generate Web Bluetooth web tests that can be run in ClusterFuzz.
This script uses templates in the templates/ directory to generate html files
@@ -21,10 +20,10 @@ from fuzzer_helpers import FillInParameter
import parameter_fuzzer
import test_case_fuzzer
-JS_FILES_AND_PARAMETERS = (
- ('testharness.js', 'INCLUDE_TESTHARNESS'),
- ('testharnessreport.js', 'INCLUDE_REPORT'),
- ('bluetooth-helpers.js', 'INCLUDE_BLUETOOTH_HELPERS'))
+JS_FILES_AND_PARAMETERS = (('testharness.js', 'INCLUDE_TESTHARNESS'),
+ ('testharnessreport.js',
+ 'INCLUDE_REPORT'), ('bluetooth-helpers.js',
+ 'INCLUDE_BLUETOOTH_HELPERS'))
SCRIPT_PREFIX = '<script type="text/javascript">\n'
SCRIPT_SUFFIX = '\n</script>\n'
@@ -39,20 +38,30 @@ def _GetArguments():
parser = argparse.ArgumentParser()
# Arguments used by ClusterFuzz:
- parser.add_argument('-n', '--no_of_files', type=int, required=True,
- help='The number of test cases that the fuzzer is '
- 'expected to generate')
- parser.add_argument('-i', '--input_dir',
- help='The directory containing the fuzzer\'s data '
- 'bundle.')
- parser.add_argument('-o', '--output_dir', required=True,
- help='The directory where test case files should be '
- 'written to.')
-
- parser.add_argument('--content_shell_dir',
- help='The directory of content shell. If present the '
- 'program will print a command to run the '
- 'generated test file.')
+ parser.add_argument(
+ '-n',
+ '--no_of_files',
+ type=int,
+ required=True,
+ help='The number of test cases that the fuzzer is '
+ 'expected to generate')
+ parser.add_argument(
+ '-i',
+ '--input_dir',
+ help='The directory containing the fuzzer\'s data '
+ 'bundle.')
+ parser.add_argument(
+ '-o',
+ '--output_dir',
+ required=True,
+ help='The directory where test case files should be '
+ 'written to.')
+
+ parser.add_argument(
+ '--content_shell_dir',
+ help='The directory of content shell. If present the '
+ 'program will print a command to run the '
+ 'generated test file.')
return parser.parse_args()
@@ -93,9 +102,10 @@ def FuzzTemplate(template_path, resources_path):
js_file_data = (SCRIPT_PREFIX + js_file_data + SCRIPT_SUFFIX)
- fuzzed_file_data = FillInParameter(include_parameter,
- lambda data=js_file_data: data,
- fuzzed_file_data)
+ fuzzed_file_data = FillInParameter(
+ include_parameter,
+ lambda data=js_file_data: data,
+ fuzzed_file_data)
return fuzzed_file_data.encode('utf-8')
@@ -113,13 +123,11 @@ def WriteTestFile(test_file_data, test_file_prefix, output_dir):
"""
file_descriptor, file_path = tempfile.mkstemp(
- prefix=test_file_prefix,
- suffix='.html',
- dir=output_dir)
+ prefix=test_file_prefix, suffix='.html', dir=output_dir)
with os.fdopen(file_descriptor, 'wb') as output:
- print 'Writing {} bytes to \'{}\''.format(len(test_file_data),
- file_path)
+ print 'Writing {} bytes to \'{}\''.format(
+ len(test_file_data), file_path)
output.write(test_file_data)
return file_path
@@ -135,9 +143,8 @@ def main():
# Get Templates
current_path = os.path.dirname(os.path.realpath(__file__))
- available_templates = glob.glob(os.path.join(current_path,
- 'templates',
- '*.html'))
+ available_templates = glob.glob(
+ os.path.join(current_path, 'templates', '*.html'))
# Generate Test Files
resources_path = os.path.join(current_path, 'resources')
@@ -149,12 +156,10 @@ def main():
# Get Test File
template_name = os.path.splitext(os.path.basename(template_path))[0]
- test_file_name = 'fuzz-{}-{}-{}'.format(template_name,
- int(start_time),
+ test_file_name = 'fuzz-{}-{}-{}'.format(template_name, int(start_time),
int(file_no))
- test_file_path = WriteTestFile(test_file_data,
- test_file_name,
+ test_file_path = WriteTestFile(test_file_data, test_file_name,
args.output_dir)
if args.content_shell_dir:
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/fuzzer_helpers.py b/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/fuzzer_helpers.py
index 798fe86306d..9b6ccceb254 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/fuzzer_helpers.py
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/fuzzer_helpers.py
@@ -1,7 +1,6 @@
# 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.
-
"""Module that includes classes and functions used by fuzzers."""
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/gatt_aliases.py b/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/gatt_aliases.py
index e28d502d137..86ce0100f75 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/gatt_aliases.py
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/gatt_aliases.py
@@ -1,7 +1,6 @@
# 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.
-
"""Contains Services, Characteristics and Descriptor aliases.
These values are copied from:
@@ -11,7 +10,6 @@ https://www.bluetooth.com/specifications/gatt/services
https://www.bluetooth.com/specifications/gatt/characteristics
"""
-
SERVICES = [
'alert_notification',
'automation_io',
@@ -51,7 +49,6 @@ SERVICES = [
'weight_scale',
]
-
CHARACTERISTICS = [
'aerobic_heart_rate_lower_limit',
'aerobic_heart_rate_upper_limit',
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/parameter_fuzzer.py b/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/parameter_fuzzer.py
index 0c9bdb502e6..cb06b6e7694 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/parameter_fuzzer.py
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/parameter_fuzzer.py
@@ -1,7 +1,6 @@
# 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.
-
"""Module to fuzz parameters of a template."""
import constraints
@@ -23,8 +22,7 @@ def FuzzParameters(test_file_data):
"""
test_file_data = FillInParameter('TRANSFORM_BASIC_BASE',
- constraints.GetBasicBase,
- test_file_data)
+ constraints.GetBasicBase, test_file_data)
test_file_data = FillInParameter('TRANSFORM_DEVICE_DISCOVERY_BASE',
constraints.GetDeviceDiscoveryBase,
@@ -38,9 +36,9 @@ def FuzzParameters(test_file_data):
constraints.get_services_retrieved_base,
test_file_data)
- test_file_data = FillInParameter('TRANSFORM_CHARACTERISTICS_RETRIEVED_BASE',
- constraints.get_characteristics_retrieved_base,
- test_file_data)
+ test_file_data = FillInParameter(
+ 'TRANSFORM_CHARACTERISTICS_RETRIEVED_BASE',
+ constraints.get_characteristics_retrieved_base, test_file_data)
test_file_data = FillInParameter('TRANSFORM_REQUEST_DEVICE_OPTIONS',
constraints.GetRequestDeviceOptions,
@@ -62,12 +60,10 @@ def FuzzParameters(test_file_data):
constraints.get_pick_a_characteristic,
test_file_data)
- test_file_data = FillInParameter('TRANSFORM_VALUE',
- constraints.get_buffer_source,
- test_file_data)
+ test_file_data = FillInParameter(
+ 'TRANSFORM_VALUE', constraints.get_buffer_source, test_file_data)
test_file_data = FillInParameter('TRANSFORM_RELOAD_ID',
- constraints.get_reload_id,
- test_file_data)
+ constraints.get_reload_id, test_file_data)
return test_file_data
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/setup.py b/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/setup.py
index 3805fbc026b..c54da3cfa4c 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/setup.py
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/setup.py
@@ -1,7 +1,6 @@
# 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.
-
"""Script that helps run the fuzzer locally and in ClusterFuzz.
To prepare to run the fuzzer locally, this script copies the necessary
@@ -19,15 +18,15 @@ import shutil
import sys
# src path from this file's path.
-SRC_PATH = os.path.join(
- os.pardir, os.pardir, os.pardir, os.pardir, os.pardir, os.pardir, os.pardir)
-WEB_TESTS_RESOURCES_PATH = os.path.join(
- SRC_PATH, 'third_party', 'blink', 'web_tests', 'resources')
+SRC_PATH = os.path.join(os.pardir, os.pardir, os.pardir, os.pardir, os.pardir,
+ os.pardir, os.pardir)
+WEB_TESTS_RESOURCES_PATH = os.path.join(SRC_PATH, 'third_party', 'blink',
+ 'web_tests', 'resources')
WEB_PLATFORM_TESTS_RESOURCES_PATH = os.path.join(
SRC_PATH, 'third_party', 'blink', 'web_tests', 'external', 'wpt',
'bluetooth', 'resources')
-COMMON_FUZZER_RESOURCES_PATH = os.path.join(
- SRC_PATH, 'testing', 'clusterfuzz', 'common')
+COMMON_FUZZER_RESOURCES_PATH = os.path.join(SRC_PATH, 'testing', 'clusterfuzz',
+ 'common')
RESOURCES = [
os.path.join(WEB_TESTS_RESOURCES_PATH, 'testharness.js'),
os.path.join(WEB_TESTS_RESOURCES_PATH, 'testharnessreport.js'),
@@ -69,13 +68,19 @@ def main():
# Get arguments.
parser = argparse.ArgumentParser()
- parser.add_argument('-c', '--cluster_fuzz', action='store_true',
- help='If present, this script generates tar.bz2 file '
- 'containing the fuzzer. This file can be uploaded '
- 'and run on ClusterFuzz.')
- parser.add_argument('-l', '--local', action='store_true',
- help='If present, this script retrieves the files '
- 'necessary to run the fuzzer locally.')
+ parser.add_argument(
+ '-c',
+ '--cluster_fuzz',
+ action='store_true',
+ help='If present, this script generates tar.bz2 file '
+ 'containing the fuzzer. This file can be uploaded '
+ 'and run on ClusterFuzz.')
+ parser.add_argument(
+ '-l',
+ '--local',
+ action='store_true',
+ help='If present, this script retrieves the files '
+ 'necessary to run the fuzzer locally.')
args = parser.parse_args()
@@ -107,5 +112,6 @@ def main():
base_dir='clusterfuzz')
print 'File wrote to: ' + compressed_file_path + '.tar.bz2'
+
if __name__ == '__main__':
sys.exit(main())
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/test_case_fuzzer.py b/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/test_case_fuzzer.py
index c4932709eef..8e6bb147148 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/test_case_fuzzer.py
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/test_case_fuzzer.py
@@ -1,7 +1,6 @@
# 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.
-
"""Module to generate a test file with random calls to the Web Bluetooth API."""
import random
@@ -27,9 +26,7 @@ TOKENS = [
'.then(() => {',
],
# Request Device Tokens
- [
- ' requestDeviceWithKeyDown(TRANSFORM_REQUEST_DEVICE_OPTIONS);'
- ],
+ [' requestDeviceWithKeyDown(TRANSFORM_REQUEST_DEVICE_OPTIONS);'],
[
' return requestDeviceWithKeyDown(TRANSFORM_REQUEST_DEVICE_OPTIONS);',
'})',
@@ -194,5 +191,4 @@ def GenerateTestFile(template_file_data):
"""
return FillInParameter('TRANSFORM_RANDOM_TOKENS',
- _GenerateSequenceOfRandomTokens,
- template_file_data)
+ _GenerateSequenceOfRandomTokens, template_file_data)
diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/wbt_fakes.py b/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/wbt_fakes.py
index dddb407fe50..1f582aeeda0 100644
--- a/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/wbt_fakes.py
+++ b/chromium/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/wbt_fakes.py
@@ -1,7 +1,6 @@
# 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.
-
"""Module that contains information about Web Bluetooth's Fake Adapters."""
BLOCKLISTED_UUID = '611c954a-263b-4f4a-aab6-01ddb953f985'
@@ -67,13 +66,11 @@ CHARACTERISTICS = [
]
# Tuples of common service uuid and their characteristics uuids.
-GENERIC_ACCESS_SERVICE = (
- 'generic_access', ['gap.device_name', 'gap.peripheral_privacy_flag']
-)
+GENERIC_ACCESS_SERVICE = ('generic_access',
+ ['gap.device_name', 'gap.peripheral_privacy_flag'])
-HEART_RATE_SERVICE = (
- 'heart_rate', ['heart_rate_measurement', 'body_sensor_location']
-)
+HEART_RATE_SERVICE = ('heart_rate',
+ ['heart_rate_measurement', 'body_sensor_location'])
# List of available fake adapters.
ALL_ADAPTERS = [
@@ -123,8 +120,10 @@ ADAPTERS_WITH_DEVICES = [
),
(
'BlocklistTestAdapter',
- [BLOCKLISTED_UUID, 'device_information', 'generic_access',
- 'heart_rate', 'human_interface_device'],
+ [
+ BLOCKLISTED_UUID, 'device_information', 'generic_access',
+ 'heart_rate', 'human_interface_device'
+ ],
),
(
'FailingConnectionsAdapter',
@@ -140,7 +139,9 @@ ADAPTERS_WITH_DEVICES = [
),
(
'DeviceNameLongerThan29BytesAdapter',
- ['a_device_name_that_is_longer_than_29_bytes_but_shorter_than_248_bytes'],
+ [
+ 'a_device_name_that_is_longer_than_29_bytes_but_shorter_than_248_bytes'
+ ],
),
]
@@ -164,17 +165,16 @@ ADAPTERS_WITH_SERVICES = [
),
(
'BlocklistTestAdapter',
- [BLOCKLISTED_UUID, 'device_information', 'generic_access',
- 'heart_rate', 'human_interface_device'],
+ [
+ BLOCKLISTED_UUID, 'device_information', 'generic_access',
+ 'heart_rate', 'human_interface_device'
+ ],
),
(
'FailingGATTOperationsAdapter',
[GATT_ERROR_UUID],
),
- (
- 'DelayedServicesDiscoveryAdapter',
- ['heart_rate']
- ),
+ ('DelayedServicesDiscoveryAdapter', ['heart_rate']),
]
ADAPTERS_WITH_CHARACTERISTICS = [
@@ -186,19 +186,20 @@ ADAPTERS_WITH_CHARACTERISTICS = [
'TwoHeartRateServicesAdapter',
[HEART_RATE_SERVICE],
),
- (
- 'DisconnectingHeartRateAdapter',
- [GENERIC_ACCESS_SERVICE, HEART_RATE_SERVICE,
- (DISCONNECTION_UUID, ['01d7d88a-7451-419f-aeb8-d65e7b9277af'])]
- ),
- (
- 'BlocklistTestAdapter',
- [GENERIC_ACCESS_SERVICE, HEART_RATE_SERVICE, (
- BLOCKLISTED_UUID, ['bad1c9a2-9a5b-4015-8b60-1579bbbf2135'],
+ ('DisconnectingHeartRateAdapter', [
+ GENERIC_ACCESS_SERVICE, HEART_RATE_SERVICE,
+ (DISCONNECTION_UUID, ['01d7d88a-7451-419f-aeb8-d65e7b9277af'])
+ ]),
+ ('BlocklistTestAdapter', [
+ GENERIC_ACCESS_SERVICE, HEART_RATE_SERVICE,
+ (
+ BLOCKLISTED_UUID,
+ ['bad1c9a2-9a5b-4015-8b60-1579bbbf2135'],
), (
- 'device_information', ['serial_number_string'],
- )]
- ),
+ 'device_information',
+ ['serial_number_string'],
+ )
+ ]),
(
'FailingGATTOperationsAdapter',
[(GATT_ERROR_UUID, [
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 9f0b62f12e1..6db865d76e5 100644
--- a/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc
+++ b/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc
@@ -5,8 +5,8 @@
#include "third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.h"
#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/web_feature/web_feature.mojom-shared.h"
-#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -29,7 +29,7 @@ GetThreadSpecificProvider() {
ThreadSpecific<mojo::Remote<mojom::blink::BroadcastChannelProvider>>,
provider, ());
if (!provider.IsSet()) {
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
provider->BindNewPipeAndPassReceiver());
}
return *provider;
@@ -41,14 +41,9 @@ GetThreadSpecificProvider() {
BroadcastChannel* BroadcastChannel::Create(ExecutionContext* execution_context,
const String& name,
ExceptionState& exception_state) {
- // Record BroadcastChannel usage in third party context. Don't record if the
- // frame is same-origin to the top frame, or if we can't tell whether the
- // frame was ever cross-origin or not.
- Document* document = DynamicTo<Document>(execution_context);
- if (document && document->TopFrameOrigin() &&
- !document->TopFrameOrigin()->CanAccess(document->GetSecurityOrigin())) {
+ Document* document = Document::DynamicFrom(execution_context);
+ if (document && document->IsCrossSiteSubframe())
UseCounter::Count(document, WebFeature::kThirdPartyBroadcastChannel);
- }
if (execution_context->GetSecurityOrigin()->IsOpaque()) {
// TODO(mek): Decide what to do here depending on
@@ -102,12 +97,12 @@ bool BroadcastChannel::HasPendingActivity() const {
return receiver_.is_bound() && HasEventListeners(event_type_names::kMessage);
}
-void BroadcastChannel::ContextDestroyed(ExecutionContext*) {
+void BroadcastChannel::ContextDestroyed() {
close();
}
-void BroadcastChannel::Trace(blink::Visitor* visitor) {
- ContextLifecycleObserver::Trace(visitor);
+void BroadcastChannel::Trace(Visitor* visitor) {
+ ExecutionContextLifecycleObserver::Trace(visitor);
EventTargetWithInlineData::Trace(visitor);
}
@@ -141,7 +136,7 @@ void BroadcastChannel::OnError() {
BroadcastChannel::BroadcastChannel(ExecutionContext* execution_context,
const String& name)
- : ContextLifecycleObserver(execution_context),
+ : ExecutionContextLifecycleObserver(execution_context),
origin_(execution_context->GetSecurityOrigin()),
name_(name),
feature_handle_for_scheduler_(
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 b0c2c523194..fcc6b83781c 100644
--- a/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.h
+++ b/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.h
@@ -11,7 +11,7 @@
#include "third_party/blink/public/mojom/broadcastchannel/broadcast_channel.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -21,7 +21,7 @@ class ScriptValue;
class BroadcastChannel final : public EventTargetWithInlineData,
public ActiveScriptWrappable<BroadcastChannel>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public mojom::blink::BroadcastChannelClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(BroadcastChannel);
@@ -46,16 +46,16 @@ class BroadcastChannel final : public EventTargetWithInlineData,
// EventTarget:
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
// ScriptWrappable:
bool HasPendingActivity() const override;
- // ContextLifecycleObserver:
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver:
+ void ContextDestroyed() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
// mojom::blink::BroadcastChannelClient:
diff --git a/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.idl b/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.idl
index 83ca9a2a223..5cde86a2535 100644
--- a/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.idl
+++ b/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.idl
@@ -5,13 +5,10 @@
// https://html.spec.whatwg.org/C/#broadcastchannel
[
- Constructor(DOMString name),
- ConstructorCallWith=ExecutionContext,
- RaisesException=Constructor,
Exposed=(Window,Worker),
- ActiveScriptWrappable,
- Measure
+ ActiveScriptWrappable
] interface BroadcastChannel : EventTarget {
+ [CallWith=ExecutionContext, RaisesException, Measure] constructor(DOMString name);
readonly attribute DOMString name;
[RaisesException, Measure] void postMessage(any message);
diff --git a/chromium/third_party/blink/renderer/modules/broadcastchannel/idls.gni b/chromium/third_party/blink/renderer/modules/broadcastchannel/idls.gni
new file mode 100644
index 00000000000..687c09309a7
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/broadcastchannel/idls.gni
@@ -0,0 +1,5 @@
+# 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 = [ "broadcast_channel.idl" ]
diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/BUILD.gn b/chromium/third_party/blink/renderer/modules/cache_storage/BUILD.gn
index af99e71f534..894123a8cea 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/BUILD.gn
@@ -24,7 +24,5 @@ blink_modules_sources("cache_storage") {
"inspector_cache_storage_agent.h",
]
- public_deps = [
- "//third_party/blink/renderer/platform",
- ]
+ public_deps = [ "//third_party/blink/renderer/platform" ]
}
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 25f87442961..a4c704f9fc0 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/cache.cc
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
+#include "base/metrics/histogram_macros.h"
#include "base/optional.h"
#include "services/network/public/mojom/fetch_api.mojom-blink.h"
#include "third_party/blink/public/common/cache_storage/cache_storage_utils.h"
@@ -19,13 +20,13 @@
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_code_cache.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_request_init.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_response.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/fetch/body_stream_buffer.h"
#include "third_party/blink/renderer/core/fetch/fetch_data_loader.h"
#include "third_party/blink/renderer/core/fetch/request.h"
-#include "third_party/blink/renderer/core/fetch/request_init.h"
#include "third_party/blink/renderer/core/fetch/response.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
#include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h"
@@ -40,7 +41,6 @@
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.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/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h"
#include "third_party/blink/renderer/platform/loader/fetch/cached_metadata.h"
@@ -90,12 +90,12 @@ CodeCachePolicy GetCodeCachePolicy(ExecutionContext* context,
if (!RuntimeEnabledFeatures::CacheStorageCodeCacheHintEnabled(context))
return CodeCachePolicy::kAuto;
- // We should never see an opaque response here. We should have bailed out
- // from generating code cache when we failed to determine its mime type.
// It's important we don't look at the header hint for opaque responses since
// it could leak cross-origin information.
- DCHECK_NE(response->GetResponse()->GetType(),
- network::mojom::FetchResponseType::kOpaque);
+ if (response->GetResponse()->GetType() ==
+ network::mojom::FetchResponseType::kOpaque) {
+ return CodeCachePolicy::kAuto;
+ }
String header_name(
features::kCacheStorageCodeCacheHintHeaderName.Get().data());
@@ -213,7 +213,7 @@ class Cache::FetchResolvedForAdd final : public ScriptFunction {
return ScriptValue(GetScriptState()->GetIsolate(), put_promise.V8Value());
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(cache_);
visitor->Trace(requests_);
ScriptFunction::Trace(visitor);
@@ -298,8 +298,8 @@ class Cache::BarrierCallbackForPut final
message.Append(": ");
message.Append(error->message);
}
- resolver->Reject(CacheStorageError::CreateException(
- error->value, message.ToString()));
+ RejectCacheStorageWithError(resolver, error->value,
+ message.ToString());
}
},
method_name_, WrapPersistent(resolver_.Get()),
@@ -326,7 +326,7 @@ class Cache::BarrierCallbackForPut final
MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError));
}
- virtual void Trace(blink::Visitor* visitor) {
+ virtual void Trace(Visitor* visitor) {
visitor->Trace(cache_);
visitor->Trace(resolver_);
}
@@ -412,7 +412,7 @@ class Cache::BlobHandleCallbackForPut final
void Abort() override { barrier_callback_->Abort(); }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(barrier_callback_);
FetchDataLoader::Client::Trace(visitor);
}
@@ -445,6 +445,10 @@ class Cache::CodeCacheHandleCallbackForPut final
fetch_api_request_ = request->CreateFetchAPIRequest();
fetch_api_response_ = response->PopulateFetchAPIResponse(request->url());
url_ = fetch_api_request_->url;
+ opaque_mode_ = fetch_api_response_->response_type ==
+ network::mojom::FetchResponseType::kOpaque
+ ? V8CodeCache::OpaqueMode::kOpaque
+ : V8CodeCache::OpaqueMode::kNotOpaque;
}
~CodeCacheHandleCallbackForPut() override = default;
@@ -491,7 +495,7 @@ class Cache::CodeCacheHandleCallbackForPut final
void Abort() override { barrier_callback_->Abort(); }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(script_state_);
visitor->Trace(barrier_callback_);
FetchDataLoader::Client::Trace(visitor);
@@ -674,7 +678,7 @@ Cache::Cache(GlobalFetch::ScopedFetcher* fetcher,
cache_remote_.Bind(std::move(cache_pending_remote), std::move(task_runner));
}
-void Cache::Trace(blink::Visitor* visitor) {
+void Cache::Trace(Visitor* visitor) {
visitor->Trace(scoped_fetcher_);
visitor->Trace(blob_client_list_);
ScriptWrappable::Trace(visitor);
@@ -739,8 +743,7 @@ ScriptPromise Cache::MatchImpl(ScriptState* script_state,
resolver->Resolve();
break;
default:
- resolver->Reject(
- CacheStorageError::CreateException(result->get_status()));
+ RejectCacheStorageWithError(resolver, result->get_status());
break;
}
} else {
@@ -820,8 +823,7 @@ ScriptPromise Cache::MatchAllImpl(ScriptState* script_state,
"CacheStorage", "Cache::MatchAllImpl::Callback",
TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN, "status",
CacheStorageTracedValue(result->get_status()));
- resolver->Reject(
- CacheStorageError::CreateException(result->get_status()));
+ RejectCacheStorageWithError(resolver, result->get_status());
} else {
TRACE_EVENT_WITH_FLOW1(
"CacheStorage", "Cache::MatchAllImpl::Callback",
@@ -860,18 +862,15 @@ ScriptPromise Cache::AddAllImpl(ScriptState* script_state,
promises.resize(requests.size());
for (wtf_size_t i = 0; i < requests.size(); ++i) {
if (!requests[i]->url().ProtocolIsInHTTPFamily()) {
- return ScriptPromise::Reject(script_state,
- V8ThrowException::CreateTypeError(
- script_state->GetIsolate(),
- "Add/AddAll does not support schemes "
- "other than \"http\" or \"https\""));
+ exception_state.ThrowTypeError(
+ "Add/AddAll does not support schemes "
+ "other than \"http\" or \"https\"");
+ return ScriptPromise();
}
if (requests[i]->method() != http_names::kGET) {
- return ScriptPromise::Reject(
- script_state,
- V8ThrowException::CreateTypeError(
- script_state->GetIsolate(),
- "Add/AddAll only supports the GET request method."));
+ exception_state.ThrowTypeError(
+ "Add/AddAll only supports the GET request method.");
+ return ScriptPromise();
}
request_infos[i].SetRequest(requests[i]);
@@ -939,8 +938,8 @@ ScriptPromise Cache::DeleteImpl(ScriptState* script_state,
message.Append("Cache.delete(): ");
message.Append(error->message);
}
- resolver->Reject(CacheStorageError::CreateException(
- error->value, message.ToString()));
+ RejectCacheStorageWithError(resolver, error->value,
+ message.ToString());
break;
}
} else {
@@ -1091,8 +1090,7 @@ ScriptPromise Cache::KeysImpl(ScriptState* script_state,
"CacheStorage", "Cache::KeysImpl::Callback",
TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN, "status",
CacheStorageTracedValue(result->get_status()));
- resolver->Reject(
- CacheStorageError::CreateException(result->get_status()));
+ RejectCacheStorageWithError(resolver, result->get_status());
} else {
TRACE_EVENT_WITH_FLOW1(
"CacheStorage", "Cache::KeysImpl::Callback",
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 b386ecdb55a..8dea8b0b6d7 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/cache.h
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache.h
@@ -12,8 +12,8 @@
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_cache_query_options.h"
#include "third_party/blink/renderer/core/fetch/global_fetch.h"
-#include "third_party/blink/renderer/modules/cache_storage/cache_query_options.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/forward.h"
@@ -84,7 +84,7 @@ class MODULES_EXPORT Cache final : public ScriptWrappable {
const CacheQueryOptions*,
ExceptionState&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
class BarrierCallbackForPut;
diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/cache.idl b/chromium/third_party/blink/renderer/modules/cache_storage/cache.idl
index a923cdf3182..fc435128a94 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/cache.idl
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache.idl
@@ -9,11 +9,11 @@
Exposed=(Window,Worker)
] interface Cache {
[CallWith=ScriptState, MeasureAs=CacheStorageRead, RaisesException]
- Promise<any> match(RequestInfo request, optional CacheQueryOptions options);
+ Promise<any> match(RequestInfo request, optional CacheQueryOptions options = {});
[CallWith=ScriptState, MeasureAs=CacheStorageRead, RaisesException]
Promise<sequence<Response>> matchAll(optional RequestInfo request,
- optional CacheQueryOptions options);
+ optional CacheQueryOptions options = {});
[CallWith=ScriptState, MeasureAs=CacheStorageWrite, RaisesException]
Promise<void> add(RequestInfo request);
@@ -30,9 +30,9 @@
MeasureAs=CacheStorageWrite,
RaisesException
] Promise<boolean> delete(RequestInfo request,
- optional CacheQueryOptions options);
+ optional CacheQueryOptions options = {});
[CallWith=ScriptState, MeasureAs=CacheStorageRead, RaisesException]
Promise<sequence<Request>> keys(optional RequestInfo request,
- optional CacheQueryOptions options);
+ optional CacheQueryOptions options = {});
};
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 c0be2e92f6a..76483de910c 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
@@ -13,6 +13,7 @@
#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h"
#include "third_party/blink/public/platform/web_content_settings_client.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_multi_cache_query_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"
@@ -64,7 +65,7 @@ namespace {
bool IsCacheStorageAllowed(ScriptState* script_state) {
ExecutionContext* context = ExecutionContext::From(script_state);
- if (auto* document = DynamicTo<Document>(context)) {
+ if (auto* document = Document::DynamicFrom(context)) {
LocalFrame* frame = document->GetFrame();
if (!frame)
return false;
@@ -137,8 +138,7 @@ ScriptPromise CacheStorage::open(ScriptState* script_state,
resolver->Resolve();
break;
default:
- resolver->Reject(
- CacheStorageError::CreateException(result->get_status()));
+ RejectCacheStorageWithError(resolver, result->get_status());
break;
}
} else {
@@ -210,7 +210,7 @@ ScriptPromise CacheStorage::has(ScriptState* script_state,
resolver->Resolve(false);
break;
default:
- resolver->Reject(CacheStorageError::CreateException(result));
+ RejectCacheStorageWithError(resolver, result);
break;
}
},
@@ -272,7 +272,7 @@ ScriptPromise CacheStorage::Delete(ScriptState* script_state,
resolver->Resolve(false);
break;
default:
- resolver->Reject(CacheStorageError::CreateException(result));
+ RejectCacheStorageWithError(resolver, result);
break;
}
},
@@ -422,8 +422,7 @@ ScriptPromise CacheStorage::MatchImpl(ScriptState* script_state,
resolver->Resolve();
break;
default:
- resolver->Reject(
- CacheStorageError::CreateException(result->get_status()));
+ RejectCacheStorageWithError(resolver, result->get_status());
break;
}
} else {
@@ -458,7 +457,7 @@ ScriptPromise CacheStorage::MatchImpl(ScriptState* script_state,
CacheStorage::CacheStorage(ExecutionContext* context,
GlobalFetch::ScopedFetcher* fetcher)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
scoped_fetcher_(fetcher),
blob_client_list_(MakeGarbageCollected<CacheStorageBlobClientList>()),
ever_used_(false) {
@@ -495,11 +494,11 @@ bool CacheStorage::HasPendingActivity() const {
return ever_used_;
}
-void CacheStorage::Trace(blink::Visitor* visitor) {
+void CacheStorage::Trace(Visitor* visitor) {
visitor->Trace(scoped_fetcher_);
visitor->Trace(blob_client_list_);
ScriptWrappable::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
bool CacheStorage::IsAllowed(ScriptState* script_state) {
@@ -510,7 +509,7 @@ bool CacheStorage::IsAllowed(ScriptState* script_state) {
return allowed_.value();
}
-void CacheStorage::ContextDestroyed(ExecutionContext*) {
+void CacheStorage::ContextDestroyed() {
cache_storage_remote_.reset();
}
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 b545f83665b..87a4563ec9f 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
@@ -12,10 +12,9 @@
#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink-forward.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/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/fetch/global_fetch.h"
#include "third_party/blink/renderer/modules/cache_storage/cache.h"
-#include "third_party/blink/renderer/modules/cache_storage/multi_cache_query_options.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -24,10 +23,11 @@
namespace blink {
class CacheStorageBlobClientList;
+class MultiCacheQueryOptions;
class CacheStorage final : public ScriptWrappable,
public ActiveScriptWrappable<CacheStorage>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(CacheStorage);
@@ -45,8 +45,8 @@ class CacheStorage final : public ScriptWrappable,
ExceptionState&);
bool HasPendingActivity() const override;
- void Trace(blink::Visitor*) override;
- void ContextDestroyed(ExecutionContext*) override;
+ void Trace(Visitor*) override;
+ void ContextDestroyed() override;
private:
ScriptPromise MatchImpl(ScriptState*,
diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.idl b/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.idl
index bc0a0e220af..5bd641784b3 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.idl
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.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://w3c.github.io/ServiceWorker/#cachestorage-interface
+// https://w3c.github.io/ServiceWorker/#cachestorage-interface
[
ActiveScriptWrappable,
SecureContext,
@@ -10,7 +10,7 @@
] interface CacheStorage {
[CallWith=ScriptState, MeasureAs=CacheStorageRead, RaisesException]
Promise<any> match(RequestInfo request,
- optional MultiCacheQueryOptions options);
+ optional MultiCacheQueryOptions options = {});
[CallWith=ScriptState, MeasureAs=CacheStorageRead]
Promise<boolean> has(DOMString cacheName);
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 b46756aa2fd..1314c47f109 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
@@ -41,7 +41,7 @@ class CacheStorageBlobClientList::Client
owner_->RevokeClient(this);
}
- void Trace(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
visitor->Trace(owner_);
visitor->Trace(completion_notifier_);
}
@@ -75,7 +75,7 @@ void CacheStorageBlobClientList::AddClient(
this, std::move(client_pending_receiver), completion_notifier));
}
-void CacheStorageBlobClientList::Trace(blink::Visitor* visitor) {
+void CacheStorageBlobClientList::Trace(Visitor* visitor) {
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 23b0452dadc..398a2e4866a 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
@@ -23,7 +23,7 @@ class CacheStorageBlobClientList
client_pending_receiver,
DataPipeBytesConsumer::CompletionNotifier* completion_notifier);
- void Trace(blink::Visitor* visitor);
+ void Trace(Visitor* visitor);
private:
class Client;
diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_error.cc b/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_error.cc
index dff96f41dcf..e0298ad634e 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_error.cc
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_error.cc
@@ -5,8 +5,10 @@
#include "third_party/blink/renderer/modules/cache_storage/cache_storage_error.h"
#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/modules/cache_storage/cache.h"
+#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
@@ -34,6 +36,8 @@ String GetDefaultMessage(mojom::CacheStorageError web_error) {
return "Method is not implemented.";
case mojom::CacheStorageError::kErrorDuplicateOperation:
return "Duplicate operation.";
+ case mojom::CacheStorageError::kErrorCrossOriginResourcePolicy:
+ return "Failed Cross-Origin-Resource-Policy check.";
}
NOTREACHED();
return String();
@@ -41,42 +45,55 @@ String GetDefaultMessage(mojom::CacheStorageError web_error) {
} // namespace
-DOMException* CacheStorageError::CreateException(
- mojom::CacheStorageError web_error,
- const String& message) {
+void RejectCacheStorageWithError(ScriptPromiseResolver* resolver,
+ mojom::blink::CacheStorageError web_error,
+ const String& message) {
String final_message =
+
!message.IsEmpty() ? message : GetDefaultMessage(web_error);
switch (web_error) {
case mojom::CacheStorageError::kSuccess:
// This function should only be called with an error.
- break;
+ NOTREACHED();
+ return;
case mojom::CacheStorageError::kErrorExists:
- return MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidAccessError, final_message);
+ resolver->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kInvalidAccessError, final_message));
+ return;
case mojom::CacheStorageError::kErrorStorage:
- return MakeGarbageCollected<DOMException>(DOMExceptionCode::kUnknownError,
- final_message);
+ resolver->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kUnknownError, final_message));
+ return;
case mojom::CacheStorageError::kErrorNotFound:
- return MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotFoundError, final_message);
+ resolver->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kNotFoundError, final_message));
+ return;
case mojom::CacheStorageError::kErrorQuotaExceeded:
- return MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kQuotaExceededError, final_message);
+ resolver->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kQuotaExceededError, final_message));
+ return;
case mojom::CacheStorageError::kErrorCacheNameNotFound:
- return MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotFoundError, final_message);
+ resolver->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kNotFoundError, final_message));
+ return;
case mojom::CacheStorageError::kErrorQueryTooLarge:
- return MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError,
- final_message);
+ resolver->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kAbortError, final_message));
+ return;
case mojom::CacheStorageError::kErrorNotImplemented:
- return MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotSupportedError, final_message);
+ resolver->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kNotSupportedError, final_message));
+ return;
case mojom::CacheStorageError::kErrorDuplicateOperation:
- return MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError, final_message);
+ resolver->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kInvalidStateError, final_message));
+ return;
+ case mojom::CacheStorageError::kErrorCrossOriginResourcePolicy:
+ ScriptState::Scope scope(resolver->GetScriptState());
+ resolver->Reject(V8ThrowException::CreateTypeError(
+ resolver->GetScriptState()->GetIsolate(), message));
+ return;
}
- NOTREACHED();
- return nullptr;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_error.h b/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_error.h
index 6d2bb59a484..0e363899774 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_error.h
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_error.h
@@ -10,25 +10,13 @@
namespace blink {
-class DOMException;
class ScriptPromiseResolver;
-class CacheStorageError {
- STATIC_ONLY(CacheStorageError);
-
- public:
- // For CallbackPromiseAdapter. Ownership of a given error is not
- // transferred.
- using WebType = mojom::CacheStorageError;
- static DOMException* Take(ScriptPromiseResolver*,
- mojom::CacheStorageError web_error) {
- return CreateException(web_error);
- }
-
- static DOMException* CreateException(mojom::CacheStorageError web_error,
- const String& message = String());
-};
-
+// Reject the |resolver| with the appropriate error given |web_error|.
+// When no |message| is provided, the standard one is chosen.
+void RejectCacheStorageWithError(ScriptPromiseResolver* resolver,
+ mojom::blink::CacheStorageError web_error,
+ const String& message = String());
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CACHE_STORAGE_CACHE_STORAGE_ERROR_H_
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 c9e0edfa149..85dacd210d6 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
@@ -26,16 +26,16 @@
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_request.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_request_init.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_response.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_response_init.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/fetch/body_stream_buffer.h"
#include "third_party/blink/renderer/core/fetch/form_data_bytes_consumer.h"
#include "third_party/blink/renderer/core/fetch/global_fetch.h"
#include "third_party/blink/renderer/core/fetch/request.h"
-#include "third_party/blink/renderer/core/fetch/request_init.h"
#include "third_party/blink/renderer/core/fetch/response.h"
-#include "third_party/blink/renderer/core/fetch/response_init.h"
#include "third_party/blink/renderer/core/frame/frame.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -62,7 +62,7 @@ class ScopedFetcherForTests final
ScriptPromise Fetch(ScriptState* script_state,
const RequestInfo& request_info,
const RequestInit*,
- ExceptionState&) override {
+ ExceptionState& exception_state) override {
++fetch_count_;
if (expected_url_) {
String fetched_url;
@@ -80,10 +80,9 @@ class ScopedFetcherForTests final
response_ = nullptr;
return promise;
}
- return ScriptPromise::Reject(
- script_state, V8ThrowException::CreateTypeError(
- script_state->GetIsolate(),
- "Unexpected call to fetch, no response available."));
+ exception_state.ThrowTypeError(
+ "Unexpected call to fetch, no response available.");
+ return ScriptPromise();
}
// This does not take ownership of its parameter. The provided sample object
@@ -95,7 +94,7 @@ class ScopedFetcherForTests final
int FetchCount() const { return fetch_count_; }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(response_);
GlobalFetch::ScopedFetcher::Trace(visitor);
}
@@ -730,7 +729,7 @@ TEST_F(CacheStorageTest, Add) {
Request* request = NewRequestFromUrl(url);
Response* response = Response::Create(
GetScriptState(),
- MakeGarbageCollected<BodyStreamBuffer>(
+ BodyStreamBuffer::Create(
GetScriptState(),
MakeGarbageCollected<FormDataBytesConsumer>(content), nullptr),
content_type, ResponseInit::Create(), exception_state);
diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/cache_utils.cc b/chromium/third_party/blink/renderer/modules/cache_storage/cache_utils.cc
index f70202288b4..71add462f6d 100644
--- a/chromium/third_party/blink/renderer/modules/cache_storage/cache_utils.cc
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache_utils.cc
@@ -24,12 +24,12 @@ Response* CreateEagerResponse(ScriptState* script_state,
*response);
DataPipeBytesConsumer::CompletionNotifier* completion_notifier = nullptr;
- fetch_data->ReplaceBodyStreamBuffer(MakeGarbageCollected<BodyStreamBuffer>(
+ fetch_data->ReplaceBodyStreamBuffer(BodyStreamBuffer::Create(
script_state,
MakeGarbageCollected<DataPipeBytesConsumer>(
context->GetTaskRunner(TaskType::kNetworking),
std::move(eager_response->pipe), &completion_notifier),
- nullptr /* AbortSignal */));
+ nullptr /* AbortSignal */, std::move(response->side_data_blob)));
// Create a BlobReaderClient in the provided list. This will track the
// completion of the eagerly read blob and propagate it to the given
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 8d7cb311125..30d6dfc92ab 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
@@ -43,7 +43,8 @@ class GlobalCacheStorageImpl final
CacheStorage* Caches(T& fetching_scope, ExceptionState& exception_state) {
ExecutionContext* context = fetching_scope.GetExecutionContext();
if (!context->GetSecurityOrigin()->CanAccessCacheStorage()) {
- if (context->GetSecurityContext().IsSandboxed(WebSandboxFlags::kOrigin)) {
+ if (context->GetSecurityContext().IsSandboxed(
+ mojom::blink::WebSandboxFlags::kOrigin)) {
exception_state.ThrowSecurityError(
"Cache storage is disabled because the context is sandboxed and "
"lacks the 'allow-same-origin' flag.");
@@ -75,7 +76,7 @@ class GlobalCacheStorageImpl final
return caches_;
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(caches_);
Supplement<T>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/idls.gni b/chromium/third_party/blink/renderer/modules/cache_storage/idls.gni
new file mode 100644
index 00000000000..dd0d4b1633e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/cache_storage/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "cache.idl",
+ "cache_storage.idl",
+]
+
+modules_dictionary_idl_files = [
+ "cache_query_options.idl",
+ "multi_cache_query_options.idl",
+]
+
+modules_dependency_idl_files = [
+ "window_cache_storage.idl",
+ "worker_cache_storage.idl",
+]
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 1509e73f235..a1d2353ff08 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
@@ -37,6 +37,7 @@
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
using blink::protocol::Array;
@@ -78,26 +79,28 @@ ProtocolResponse ParseCacheId(const String& id,
String* cache_name) {
wtf_size_t pipe = id.find('|');
if (pipe == WTF::kNotFound)
- return ProtocolResponse::Error("Invalid cache id.");
+ return ProtocolResponse::ServerError("Invalid cache id.");
*security_origin = id.Substring(0, pipe);
*cache_name = id.Substring(pipe + 1);
- return ProtocolResponse::OK();
+ return ProtocolResponse::Success();
}
ProtocolResponse GetExecutionContext(InspectedFrames* frames,
const String& security_origin,
ExecutionContext** context) {
LocalFrame* frame = frames->FrameWithSecurityOrigin(security_origin);
- if (!frame)
- return ProtocolResponse::Error("No frame with origin " + security_origin);
+ if (!frame) {
+ String msg = "No frame with origin " + security_origin;
+ return ProtocolResponse::ServerError(msg.Utf8());
+ }
blink::Document* document = frame->GetDocument();
if (!document)
- return ProtocolResponse::Error("No execution context found");
+ return ProtocolResponse::ServerError("No execution context found");
- *context = document;
+ *context = document->ToExecutionContext();
- return ProtocolResponse::OK();
+ return ProtocolResponse::Success();
}
ProtocolResponse AssertCacheStorage(
@@ -110,14 +113,14 @@ ProtocolResponse AssertCacheStorage(
// Cache Storage API is restricted to trustworthy origins.
if (!sec_origin->IsPotentiallyTrustworthy()) {
- return ProtocolResponse::Error(
- sec_origin->IsPotentiallyTrustworthyErrorMessage());
+ return ProtocolResponse::ServerError(
+ sec_origin->IsPotentiallyTrustworthyErrorMessage().Utf8());
}
ExecutionContext* context = nullptr;
ProtocolResponse response =
GetExecutionContext(frames, security_origin, &context);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
auto it = caches->find(security_origin);
@@ -132,7 +135,7 @@ ProtocolResponse AssertCacheStorage(
*result = it->value.get();
}
- return ProtocolResponse::OK();
+ return ProtocolResponse::Success();
}
ProtocolResponse AssertCacheStorageAndNameForId(
@@ -144,35 +147,37 @@ ProtocolResponse AssertCacheStorageAndNameForId(
String security_origin;
ProtocolResponse response =
ParseCacheId(cache_id, &security_origin, cache_name);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
return AssertCacheStorage(security_origin, frames, caches, result);
}
-std::string CacheStorageErrorString(mojom::blink::CacheStorageError error) {
+const char* CacheStorageErrorString(mojom::blink::CacheStorageError error) {
switch (error) {
case mojom::blink::CacheStorageError::kErrorNotImplemented:
- return std::string("not implemented.");
+ return "not implemented.";
case mojom::blink::CacheStorageError::kErrorNotFound:
- return std::string("not found.");
+ return "not found.";
case mojom::blink::CacheStorageError::kErrorExists:
- return std::string("cache already exists.");
+ return "cache already exists.";
case mojom::blink::CacheStorageError::kErrorQuotaExceeded:
- return std::string("quota exceeded.");
+ return "quota exceeded.";
case mojom::blink::CacheStorageError::kErrorCacheNameNotFound:
- return std::string("cache not found.");
+ return "cache not found.";
case mojom::blink::CacheStorageError::kErrorQueryTooLarge:
- return std::string("operation too large.");
+ return "operation too large.";
case mojom::blink::CacheStorageError::kErrorStorage:
- return std::string("storage failure.");
+ return "storage failure.";
case mojom::blink::CacheStorageError::kErrorDuplicateOperation:
- return std::string("duplicate operation.");
+ return "duplicate operation.";
+ case mojom::blink::CacheStorageError::kErrorCrossOriginResourcePolicy:
+ return "failed Cross-Origin-Resource-Policy check.";
case mojom::blink::CacheStorageError::kSuccess:
// This function should only be called upon error.
break;
}
NOTREACHED();
- return std::string();
+ return "";
}
CachedResponseType ResponseTypeToString(
@@ -260,9 +265,9 @@ class ResponsesAccumulator : public RefCounted<ResponsesAccumulator> {
DCHECK(!request->blob && !request->body);
auto request_clone_without_body = mojom::blink::FetchAPIRequest::New(
request->mode, request->is_main_resource_load,
- request->request_context_type, request->frame_type, request->url,
- request->method, request->headers, nullptr /* blob */,
- nullptr /* body */, request->referrer.Clone(),
+ request->request_context_type, request->destination,
+ request->frame_type, request->url, request->method, request->headers,
+ nullptr /* blob */, nullptr /* body */, 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,
@@ -348,10 +353,11 @@ class ResponsesAccumulator : public RefCounted<ResponsesAccumulator> {
}
void SendFailure(const mojom::blink::CacheStorageError& error) {
- callback_->sendFailure(ProtocolResponse::Error(
+ callback_->sendFailure(ProtocolResponse::ServerError(
String::Format("Error requesting responses for cache %s : %s",
- params_.cache_name.Utf8().c_str(),
- CacheStorageErrorString(error).data())));
+ params_.cache_name.Latin1().c_str(),
+ CacheStorageErrorString(error))
+ .Utf8()));
}
std::unique_ptr<Array<Header>> SerializeHeaders(
@@ -401,11 +407,12 @@ class GetCacheKeysForRequestData {
std::unique_ptr<GetCacheKeysForRequestData> self,
mojom::blink::CacheKeysResultPtr result) {
if (result->is_status()) {
- self->callback_->sendFailure(
- ProtocolResponse::Error(String::Format(
+ self->callback_->sendFailure(ProtocolResponse::ServerError(
+ String::Format(
"Error requesting requests for cache %s: %s",
- params.cache_name.Utf8().c_str(),
- CacheStorageErrorString(result->get_status()).data())));
+ params.cache_name.Latin1().c_str(),
+ CacheStorageErrorString(result->get_status()))
+ .Utf8()));
} else {
if (result->get_keys().IsEmpty()) {
auto array = std::make_unique<protocol::Array<DataEntry>>();
@@ -452,8 +459,10 @@ class CachedResponseFileReaderLoaderClient final
}
void DidFail(FileErrorCode error) override {
- callback_->sendFailure(ProtocolResponse::Error(String::Format(
- "Unable to read the cached response, error code: %d", error)));
+ callback_->sendFailure(ProtocolResponse::ServerError(
+ String::Format("Unable to read the cached response, error code: %d",
+ error)
+ .Utf8()));
dispose();
}
@@ -495,7 +504,7 @@ InspectorCacheStorageAgent::InspectorCacheStorageAgent(InspectedFrames* frames)
InspectorCacheStorageAgent::~InspectorCacheStorageAgent() = default;
-void InspectorCacheStorageAgent::Trace(blink::Visitor* visitor) {
+void InspectorCacheStorageAgent::Trace(Visitor* visitor) {
visitor->Trace(frames_);
InspectorBaseAgent::Trace(visitor);
}
@@ -523,7 +532,7 @@ void InspectorCacheStorageAgent::requestCacheNames(
ProtocolResponse response =
AssertCacheStorage(security_origin, frames_, &caches_, &cache_storage);
- if (!response.isSuccess()) {
+ if (!response.IsSuccess()) {
callback->sendFailure(response);
return;
}
@@ -563,7 +572,7 @@ void InspectorCacheStorageAgent::requestEntries(
mojom::blink::CacheStorage* cache_storage = nullptr;
ProtocolResponse response = AssertCacheStorageAndNameForId(
cache_id, frames_, &cache_name, &caches_, &cache_storage);
- if (!response.isSuccess()) {
+ if (!response.IsSuccess()) {
callback->sendFailure(response);
return;
}
@@ -580,10 +589,11 @@ void InspectorCacheStorageAgent::requestEntries(
std::unique_ptr<RequestEntriesCallback> callback,
mojom::blink::OpenResultPtr result) {
if (result->is_status()) {
- callback->sendFailure(ProtocolResponse::Error(String::Format(
- "Error requesting cache %s: %s",
- params.cache_name.Utf8().c_str(),
- CacheStorageErrorString(result->get_status()).data())));
+ callback->sendFailure(ProtocolResponse::ServerError(
+ String::Format("Error requesting cache %s: %s",
+ params.cache_name.Latin1().c_str(),
+ CacheStorageErrorString(result->get_status()))
+ .Utf8()));
} else {
auto request = std::make_unique<GetCacheKeysForRequestData>(
params, std::move(result->get_cache()), std::move(callback));
@@ -606,7 +616,7 @@ void InspectorCacheStorageAgent::deleteCache(
mojom::blink::CacheStorage* cache_storage = nullptr;
ProtocolResponse response = AssertCacheStorageAndNameForId(
cache_id, frames_, &cache_name, &caches_, &cache_storage);
- if (!response.isSuccess()) {
+ if (!response.IsSuccess()) {
callback->sendFailure(response);
return;
}
@@ -618,9 +628,10 @@ void InspectorCacheStorageAgent::deleteCache(
if (error == mojom::blink::CacheStorageError::kSuccess) {
callback->sendSuccess();
} else {
- callback->sendFailure(ProtocolResponse::Error(
+ callback->sendFailure(ProtocolResponse::ServerError(
String::Format("Error requesting cache names: %s",
- CacheStorageErrorString(error).data())));
+ CacheStorageErrorString(error))
+ .Utf8()));
}
},
std::move(callback)));
@@ -639,7 +650,7 @@ void InspectorCacheStorageAgent::deleteEntry(
mojom::blink::CacheStorage* cache_storage = nullptr;
ProtocolResponse response = AssertCacheStorageAndNameForId(
cache_id, frames_, &cache_name, &caches_, &cache_storage);
- if (!response.isSuccess()) {
+ if (!response.IsSuccess()) {
callback->sendFailure(response);
return;
}
@@ -650,9 +661,11 @@ void InspectorCacheStorageAgent::deleteEntry(
std::unique_ptr<DeleteEntryCallback> callback,
mojom::blink::OpenResultPtr result) {
if (result->is_status()) {
- callback->sendFailure(ProtocolResponse::Error(String::Format(
- "Error requesting cache %s: %s", cache_name.Utf8().c_str(),
- CacheStorageErrorString(result->get_status()).data())));
+ callback->sendFailure(ProtocolResponse::ServerError(
+ String::Format("Error requesting cache %s: %s",
+ cache_name.Latin1().c_str(),
+ CacheStorageErrorString(result->get_status()))
+ .Utf8()));
} else {
Vector<mojom::blink::BatchOperationPtr> batch_operations;
batch_operations.push_back(mojom::blink::BatchOperation::New());
@@ -675,11 +688,11 @@ void InspectorCacheStorageAgent::deleteEntry(
mojom::blink::CacheStorageVerboseErrorPtr error) {
if (error->value !=
mojom::blink::CacheStorageError::kSuccess) {
- callback->sendFailure(
- ProtocolResponse::Error(String::Format(
+ callback->sendFailure(ProtocolResponse::ServerError(
+ String::Format(
"Error deleting cache entry: %s",
- CacheStorageErrorString(error->value)
- .data())));
+ CacheStorageErrorString(error->value))
+ .Utf8()));
} else {
callback->sendSuccess();
}
@@ -705,7 +718,7 @@ void InspectorCacheStorageAgent::requestCachedResponse(
mojom::blink::CacheStorage* cache_storage = nullptr;
ProtocolResponse response = AssertCacheStorageAndNameForId(
cache_id, frames_, &cache_name, &caches_, &cache_storage);
- if (!response.isSuccess()) {
+ if (!response.IsSuccess()) {
callback->sendFailure(response);
return;
}
@@ -728,9 +741,10 @@ void InspectorCacheStorageAgent::requestCachedResponse(
[](std::unique_ptr<RequestCachedResponseCallback> callback,
mojom::blink::MatchResultPtr result) {
if (result->is_status()) {
- callback->sendFailure(ProtocolResponse::Error(String::Format(
- "Unable to read cached response: %s",
- CacheStorageErrorString(result->get_status()).data())));
+ callback->sendFailure(ProtocolResponse::ServerError(
+ String::Format("Unable to read cached response: %s",
+ CacheStorageErrorString(result->get_status()))
+ .Utf8()));
} else {
std::unique_ptr<protocol::DictionaryValue> headers =
protocol::DictionaryValue::create();
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 467ca84a665..37c2f7ed028 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 7fcd19b31ae..3a4fad46751 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/canvas/BUILD.gn
@@ -42,9 +42,7 @@ blink_modules_sources("canvas") {
}
fuzzer_test("canvas_fuzzer") {
- sources = [
- "canvas_fuzzer.cc",
- ]
+ sources = [ "canvas_fuzzer.cc" ]
seed_corpuses = [ "//third_party/blink/web_tests/fast/canvas" ]
deps = [
"../../platform:blink_fuzzer_test_support",
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 78833214386..5afdc0bb021 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
@@ -21,8 +21,10 @@
#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/path_2d.h"
#include "third_party/blink/renderer/platform/geometry/float_quad.h"
+#include "third_party/blink/renderer/platform/graphics/bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
#include "third_party/blink/renderer/platform/graphics/stroke_data.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
@@ -48,6 +50,11 @@ void BaseRenderingContext2D::RealizeSaves() {
ValidateStateStack();
if (GetState().HasUnrealizedSaves()) {
DCHECK_GE(state_stack_.size(), 1u);
+ // GetOrCreatePaintCanvas() can call RestoreMatrixClipStack which syncs
+ // canvas to state_stack_. Get the canvas before adjusting state_stack_ to
+ // ensure canvas is synced prior to adjusting state_stack_.
+ cc::PaintCanvas* canvas = GetOrCreatePaintCanvas();
+
// Reduce the current state's unrealized count by one now,
// to reflect the fact we are saving one state.
state_stack_.back()->Restore();
@@ -60,7 +67,6 @@ void BaseRenderingContext2D::RealizeSaves() {
// state (in turn necessary to support correct resizing and unwinding of the
// stack).
state_stack_.back()->ResetUnrealizedSaveCount();
- cc::PaintCanvas* canvas = DrawingCanvas();
if (canvas)
canvas->save();
ValidateStateStack();
@@ -68,11 +74,15 @@ void BaseRenderingContext2D::RealizeSaves() {
}
void BaseRenderingContext2D::save() {
+ if (isContextLost())
+ return;
state_stack_.back()->Save();
ValidateStateStack();
}
void BaseRenderingContext2D::restore() {
+ if (isContextLost())
+ return;
ValidateStateStack();
if (GetState().HasUnrealizedSaves()) {
// We never realized the save, so just record that it was unnecessary.
@@ -92,7 +102,7 @@ void BaseRenderingContext2D::restore() {
if (GetState().IsTransformInvertible())
path_.Transform(GetState().Transform().Inverse());
- cc::PaintCanvas* c = DrawingCanvas();
+ cc::PaintCanvas* c = GetOrCreatePaintCanvas();
if (c)
c->restore();
@@ -115,12 +125,12 @@ void BaseRenderingContext2D::RestoreMatrixClipStack(cc::PaintCanvas* c) const {
c->save();
}
c->restore();
- ValidateStateStack();
+ ValidateStateStackWithCanvas(c);
}
void BaseRenderingContext2D::UnwindStateStack() {
if (size_t stack_size = state_stack_.size()) {
- if (cc::PaintCanvas* sk_canvas = ExistingDrawingCanvas()) {
+ if (cc::PaintCanvas* sk_canvas = GetPaintCanvas()) {
while (--stack_size)
sk_canvas->restore();
}
@@ -133,7 +143,7 @@ void BaseRenderingContext2D::Reset() {
state_stack_.resize(1);
state_stack_.front() = MakeGarbageCollected<CanvasRenderingContext2DState>();
path_.Clear();
- if (cc::PaintCanvas* c = ExistingDrawingCanvas()) {
+ if (cc::PaintCanvas* c = GetPaintCanvas()) {
// The canvas should always have an initial/unbalanced save frame, which
// we use to reset the top level matrix and clip here.
DCHECK_EQ(c->getSaveCount(), 2);
@@ -186,16 +196,17 @@ void BaseRenderingContext2D::setStrokeStyle(
ModifiableState().SetUnparsedStrokeColor(color_string);
return;
}
- canvas_style = CanvasStyle::CreateFromRGBA(parsed_color.Rgb());
+ canvas_style = MakeGarbageCollected<CanvasStyle>(parsed_color.Rgb());
} else if (style.IsCanvasGradient()) {
- canvas_style = CanvasStyle::CreateFromGradient(style.GetAsCanvasGradient());
+ canvas_style =
+ MakeGarbageCollected<CanvasStyle>(style.GetAsCanvasGradient());
} else if (style.IsCanvasPattern()) {
CanvasPattern* canvas_pattern = style.GetAsCanvasPattern();
if (!origin_tainted_by_content_ && !canvas_pattern->OriginClean())
SetOriginTaintedByContent();
- canvas_style = CanvasStyle::CreateFromPattern(canvas_pattern);
+ canvas_style = MakeGarbageCollected<CanvasStyle>(canvas_pattern);
}
DCHECK(canvas_style);
@@ -227,16 +238,17 @@ void BaseRenderingContext2D::setFillStyle(
ModifiableState().SetUnparsedFillColor(color_string);
return;
}
- canvas_style = CanvasStyle::CreateFromRGBA(parsed_color.Rgb());
+ canvas_style = MakeGarbageCollected<CanvasStyle>(parsed_color.Rgb());
} else if (style.IsCanvasGradient()) {
- canvas_style = CanvasStyle::CreateFromGradient(style.GetAsCanvasGradient());
+ canvas_style =
+ MakeGarbageCollected<CanvasStyle>(style.GetAsCanvasGradient());
} else if (style.IsCanvasPattern()) {
CanvasPattern* canvas_pattern = style.GetAsCanvasPattern();
if (!origin_tainted_by_content_ && !canvas_pattern->OriginClean()) {
SetOriginTaintedByContent();
}
- canvas_style = CanvasStyle::CreateFromPattern(canvas_pattern);
+ canvas_style = MakeGarbageCollected<CanvasStyle>(canvas_pattern);
}
DCHECK(canvas_style);
@@ -423,7 +435,7 @@ void BaseRenderingContext2D::setFilter(
}
void BaseRenderingContext2D::scale(double sx, double sy) {
- cc::PaintCanvas* c = DrawingCanvas();
+ cc::PaintCanvas* c = GetOrCreatePaintCanvas();
if (!c)
return;
@@ -446,7 +458,7 @@ void BaseRenderingContext2D::scale(double sx, double sy) {
}
void BaseRenderingContext2D::rotate(double angle_in_radians) {
- cc::PaintCanvas* c = DrawingCanvas();
+ cc::PaintCanvas* c = GetOrCreatePaintCanvas();
if (!c)
return;
@@ -466,7 +478,7 @@ void BaseRenderingContext2D::rotate(double angle_in_radians) {
}
void BaseRenderingContext2D::translate(double tx, double ty) {
- cc::PaintCanvas* c = DrawingCanvas();
+ cc::PaintCanvas* c = GetOrCreatePaintCanvas();
if (!c)
return;
if (!GetState().IsTransformInvertible())
@@ -496,7 +508,7 @@ void BaseRenderingContext2D::transform(double m11,
double m22,
double dx,
double dy) {
- cc::PaintCanvas* c = DrawingCanvas();
+ cc::PaintCanvas* c = GetOrCreatePaintCanvas();
if (!c)
return;
@@ -526,7 +538,7 @@ void BaseRenderingContext2D::transform(double m11,
}
void BaseRenderingContext2D::resetTransform() {
- cc::PaintCanvas* c = DrawingCanvas();
+ cc::PaintCanvas* c = GetOrCreatePaintCanvas();
if (!c)
return;
@@ -623,7 +635,7 @@ void BaseRenderingContext2D::DrawPathInternal(
if (paint_type == CanvasRenderingContext2DState::kStrokePaintType)
InflateStrokeRect(bounds);
- if (!DrawingCanvas())
+ if (!GetOrCreatePaintCanvas())
return;
Draw([&sk_path](cc::PaintCanvas* c, const PaintFlags* flags) // draw lambda
@@ -671,7 +683,7 @@ void BaseRenderingContext2D::fillRect(double x,
if (!ValidateRectForCanvas(x, y, width, height))
return;
- if (!DrawingCanvas())
+ if (!GetOrCreatePaintCanvas())
return;
// clamp to float to avoid float cast overflow when used as SkScalar
@@ -721,7 +733,7 @@ void BaseRenderingContext2D::strokeRect(double x,
if (!ValidateRectForCanvas(x, y, width, height))
return;
- if (!DrawingCanvas())
+ if (!GetOrCreatePaintCanvas())
return;
// clamp to float to avoid float cast overflow when used as SkScalar
@@ -748,7 +760,7 @@ void BaseRenderingContext2D::strokeRect(double x,
void BaseRenderingContext2D::ClipInternal(const Path& path,
const String& winding_rule_string) {
- cc::PaintCanvas* c = DrawingCanvas();
+ cc::PaintCanvas* c = GetOrCreatePaintCanvas();
if (!c) {
return;
}
@@ -790,7 +802,7 @@ bool BaseRenderingContext2D::IsPointInPathInternal(
const double x,
const double y,
const String& winding_rule_string) {
- cc::PaintCanvas* c = DrawingCanvas();
+ cc::PaintCanvas* c = GetOrCreatePaintCanvas();
if (!c)
return false;
if (!GetState().IsTransformInvertible())
@@ -819,7 +831,7 @@ bool BaseRenderingContext2D::isPointInStroke(Path2D* dom_path,
bool BaseRenderingContext2D::IsPointInStrokeInternal(const Path& path,
const double x,
const double y) {
- cc::PaintCanvas* c = DrawingCanvas();
+ cc::PaintCanvas* c = GetOrCreatePaintCanvas();
if (!c)
return false;
if (!GetState().IsTransformInvertible())
@@ -847,12 +859,10 @@ void BaseRenderingContext2D::clearRect(double x,
double y,
double width,
double height) {
- usage_counters_.num_clear_rect_calls++;
-
if (!ValidateRectForCanvas(x, y, width, height))
return;
- cc::PaintCanvas* c = DrawingCanvas();
+ cc::PaintCanvas* c = GetOrCreatePaintCanvas();
if (!c)
return;
if (!GetState().IsTransformInvertible())
@@ -877,8 +887,8 @@ void BaseRenderingContext2D::clearRect(double x,
if (RectContainsTransformedRect(rect, clip_bounds)) {
CheckOverdraw(rect, &clear_flags, CanvasRenderingContext2DState::kNoImage,
kClipFill);
- if (DrawingCanvas())
- DrawingCanvas()->drawRect(rect, clear_flags);
+ c = GetPaintCanvas(); // Check overdraw may have swapped the PaintCanvas
+ c->drawRect(rect, clear_flags);
DidDraw(clip_bounds);
} else {
SkIRect dirty_rect;
@@ -987,11 +997,12 @@ void BaseRenderingContext2D::drawImage(
ToImageSourceInternal(image_source, exception_state);
if (!image_source_internal)
return;
+ RespectImageOrientationEnum respect_orientation = RespectImageOrientation();
FloatSize default_object_size(Width(), Height());
- FloatSize source_rect_size =
- image_source_internal->ElementSize(default_object_size);
- FloatSize dest_rect_size =
- image_source_internal->DefaultDestinationSize(default_object_size);
+ FloatSize source_rect_size = image_source_internal->ElementSize(
+ default_object_size, respect_orientation);
+ FloatSize dest_rect_size = image_source_internal->DefaultDestinationSize(
+ default_object_size, respect_orientation);
drawImage(script_state, image_source_internal, 0, 0, source_rect_size.Width(),
source_rect_size.Height(), x, y, dest_rect_size.Width(),
dest_rect_size.Height(), exception_state);
@@ -1010,8 +1021,8 @@ void BaseRenderingContext2D::drawImage(
if (!image_source_internal)
return;
FloatSize default_object_size(this->Width(), this->Height());
- FloatSize source_rect_size =
- image_source_internal->ElementSize(default_object_size);
+ FloatSize source_rect_size = image_source_internal->ElementSize(
+ default_object_size, RespectImageOrientation());
drawImage(script_state, image_source_internal, 0, 0, source_rect_size.Width(),
source_rect_size.Height(), x, y, width, height, exception_state);
}
@@ -1040,7 +1051,7 @@ bool BaseRenderingContext2D::ShouldDrawImageAntialiased(
const FloatRect& dest_rect) const {
if (!GetState().ShouldAntialias())
return false;
- cc::PaintCanvas* c = DrawingCanvas();
+ cc::PaintCanvas* c = GetPaintCanvas();
DCHECK(c);
const SkMatrix& ctm = c->getTotalMatrix();
@@ -1086,10 +1097,19 @@ void BaseRenderingContext2D::DrawImageInternal(cc::PaintCanvas* c,
// crbug.com/504687
return;
}
- c->save();
- c->concat(inv_ctm);
SkRect bounds = dst_rect;
ctm.mapRect(&bounds);
+ if (!bounds.isFinite()) {
+ // There is an earlier check for the correctness of the bounds, but it is
+ // possible that after applying the matrix transformation we get a faulty
+ // set of bounds, so we want to catch this asap and avoid sending a draw
+ // command. crbug.com/1039125
+ // We want to do this before the save command is sent.
+ return;
+ }
+ c->save();
+ c->concat(inv_ctm);
+
PaintFlags layer_flags;
layer_flags.setBlendMode(flags->getBlendMode());
layer_flags.setImageFilter(flags->getImageFilter());
@@ -1101,10 +1121,20 @@ void BaseRenderingContext2D::DrawImageInternal(cc::PaintCanvas* c,
}
if (!image_source->IsVideoElement()) {
+ // We always use the image-orientation property on the canvas element
+ // because the alternative would result in complex rules depending on
+ // the source of the image.
+ RespectImageOrientationEnum respect_orientation = RespectImageOrientation();
+ FloatRect corrected_src_rect = src_rect;
+ if (respect_orientation == kRespectImageOrientation &&
+ !image->HasDefaultOrientation()) {
+ corrected_src_rect = image->CorrectSrcRectForImageOrientation(
+ image->SizeAsFloat(kRespectImageOrientation), src_rect);
+ }
image_flags.setAntiAlias(ShouldDrawImageAntialiased(dst_rect));
- image->Draw(c, image_flags, dst_rect, src_rect,
- kDoNotRespectImageOrientation,
- Image::kDoNotClampImageToSourceRect, Image::kSyncDecode);
+ image->Draw(c, image_flags, dst_rect, corrected_src_rect,
+ respect_orientation, Image::kDoNotClampImageToSourceRect,
+ Image::kSyncDecode);
} else {
c->save();
c->clipRect(dst_rect);
@@ -1140,7 +1170,7 @@ void BaseRenderingContext2D::drawImage(ScriptState* script_state,
double dw,
double dh,
ExceptionState& exception_state) {
- if (!DrawingCanvas())
+ if (!GetOrCreatePaintCanvas())
return;
base::TimeTicks start_time = base::TimeTicks::Now();
@@ -1182,13 +1212,12 @@ void BaseRenderingContext2D::drawImage(ScriptState* script_state,
FloatRect src_rect = NormalizeRect(FloatRect(fsx, fsy, fsw, fsh));
FloatRect dst_rect = NormalizeRect(FloatRect(fdx, fdy, fdw, fdh));
- FloatSize image_size = image_source->ElementSize(default_object_size);
+ FloatSize image_size =
+ image_source->ElementSize(default_object_size, RespectImageOrientation());
ClipRectsToImageRect(FloatRect(FloatPoint(), image_size), &src_rect,
&dst_rect);
- image_source->AdjustDrawRects(&src_rect, &dst_rect);
-
if (src_rect.IsEmpty())
return;
@@ -1276,7 +1305,7 @@ void BaseRenderingContext2D::ClearCanvas() {
FloatRect canvas_rect(0, 0, Width(), Height());
CheckOverdraw(canvas_rect, nullptr, CanvasRenderingContext2DState::kNoImage,
kClipFill);
- cc::PaintCanvas* c = DrawingCanvas();
+ cc::PaintCanvas* c = GetOrCreatePaintCanvas();
if (c)
c->clear(HasAlpha() ? SK_ColorTRANSPARENT : SK_ColorBLACK);
}
@@ -1386,7 +1415,10 @@ CanvasPattern* BaseRenderingContext2D::createPattern(
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidStateError,
String::Format("The canvas %s is 0.",
- image_source->ElementSize(default_object_size).Width()
+ image_source
+ ->ElementSize(default_object_size,
+ RespectImageOrientation())
+ .Width()
? "height"
: "width"));
return nullptr;
@@ -1396,7 +1428,7 @@ CanvasPattern* BaseRenderingContext2D::createPattern(
"Source image is in the 'broken' state.");
return nullptr;
case kInvalidSourceImageStatus:
- image_for_rendering = Image::NullImage();
+ image_for_rendering = BitmapImage::Create();
break;
case kIncompleteSourceImageStatus:
return nullptr;
@@ -1415,7 +1447,8 @@ CanvasPattern* BaseRenderingContext2D::createPattern(
bool BaseRenderingContext2D::ComputeDirtyRect(const FloatRect& local_rect,
SkIRect* dirty_rect) {
SkIRect clip_bounds;
- if (!DrawingCanvas()->getDeviceClipBounds(&clip_bounds))
+ if (!GetOrCreatePaintCanvas() ||
+ !GetPaintCanvas()->getDeviceClipBounds(&clip_bounds))
return false;
return ComputeDirtyRect(local_rect, clip_bounds, dirty_rect);
}
@@ -1529,8 +1562,6 @@ ImageData* BaseRenderingContext2D::getImageData(
base::TimeTicks start_time = base::TimeTicks::Now();
- usage_counters_.num_get_image_data_calls++;
- usage_counters_.area_get_image_data_calls += sw * sh;
if (!OriginClean()) {
exception_state.ThrowSecurityError(
"The canvas has been tainted by cross-origin data.");
@@ -1620,22 +1651,26 @@ ImageData* BaseRenderingContext2D::getImageData(
}
// Convert pixels to proper storage format if needed
- if (PixelFormat() != CanvasPixelFormat::kRGBA8) {
+ if (PixelFormat() != CanvasColorParams::GetNativeCanvasPixelFormat()) {
ImageDataStorageFormat storage_format =
ImageData::GetImageDataStorageFormat(color_settings->storageFormat());
- DOMArrayBufferView* array_buffer_view =
+ NotShared<DOMArrayBufferView> array_buffer_view =
ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat(
contents, PixelFormat(), storage_format);
- return ImageData::Create(image_data_rect.Size(),
- NotShared<DOMArrayBufferView>(array_buffer_view),
+ return ImageData::Create(image_data_rect.Size(), array_buffer_view,
color_settings);
}
- DOMArrayBuffer* array_buffer = DOMArrayBuffer::Create(contents);
+ if (size_in_bytes > std::numeric_limits<unsigned int>::max()) {
+ exception_state.ThrowRangeError(
+ "Buffer size exceeds maximum heap object size.");
+ return nullptr;
+ }
+ DOMArrayBuffer* array_buffer = DOMArrayBuffer::Create(std::move(contents));
ImageData* imageData = ImageData::Create(
image_data_rect.Size(),
NotShared<DOMUint8ClampedArray>(DOMUint8ClampedArray::Create(
- array_buffer, 0, array_buffer->DeprecatedByteLengthAsUnsigned())),
+ array_buffer, 0, static_cast<unsigned int>(size_in_bytes))),
color_settings);
if (!IsPaint2D()) {
@@ -1687,8 +1722,6 @@ void BaseRenderingContext2D::putImageData(ImageData* data,
return;
}
base::TimeTicks start_time = base::TimeTicks::Now();
- usage_counters_.num_put_image_data_calls++;
- usage_counters_.area_put_image_data_calls += dirty_width * dirty_height;
if (data->BufferBase()->IsDetached()) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
@@ -1741,8 +1774,7 @@ void BaseRenderingContext2D::putImageData(ImageData* data,
// additional swizzling is needed.
CanvasColorParams data_color_params = data->GetCanvasColorParams();
CanvasColorParams context_color_params =
- CanvasColorParams(ColorParams().ColorSpace(), PixelFormat(), kNonOpaque,
- CanvasForceRGBA::kNotForced);
+ CanvasColorParams(ColorParams().ColorSpace(), PixelFormat(), kNonOpaque);
if (data_color_params.NeedsColorConversion(context_color_params) ||
PixelFormat() == CanvasPixelFormat::kF16) {
size_t data_length;
@@ -1874,7 +1906,7 @@ void BaseRenderingContext2D::CheckOverdraw(
const PaintFlags* flags,
CanvasRenderingContext2DState::ImageType image_type,
DrawType draw_type) {
- cc::PaintCanvas* c = DrawingCanvas();
+ cc::PaintCanvas* c = GetOrCreatePaintCanvas();
if (!c)
return;
@@ -1964,12 +1996,7 @@ void BaseRenderingContext2D::setTextBaseline(const String& s) {
ModifiableState().SetTextBaseline(baseline);
}
-const BaseRenderingContext2D::UsageCounters&
-BaseRenderingContext2D::GetUsage() {
- return usage_counters_;
-}
-
-void BaseRenderingContext2D::Trace(blink::Visitor* visitor) {
+void BaseRenderingContext2D::Trace(Visitor* visitor) {
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 53c5a939a93..9fd5cb6cb48 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,7 +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/graphics/canvas_heuristic_parameters.h"
+#include "third_party/blink/renderer/platform/graphics/image_orientation.h"
namespace blink {
class CanvasImageSource;
@@ -89,15 +89,15 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
double m22,
double dx,
double dy);
- virtual void setTransform(double m11,
- double m12,
- double m21,
- double m22,
- double dx,
- double dy);
- virtual void setTransform(DOMMatrix2DInit*, ExceptionState&);
- DOMMatrix* getTransform();
- void resetTransform();
+ void setTransform(double m11,
+ double m12,
+ double m21,
+ double m22,
+ double dx,
+ double dy);
+ void setTransform(DOMMatrix2DInit*, ExceptionState&);
+ virtual DOMMatrix* getTransform();
+ virtual void resetTransform();
void beginPath();
@@ -224,11 +224,13 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
}
virtual bool CanCreateCanvas2dResourceProvider() const = 0;
+ virtual RespectImageOrientationEnum RespectImageOrientation() const = 0;
+
virtual bool ParseColorOrCurrentColor(Color&,
const String& color_string) const = 0;
- virtual cc::PaintCanvas* DrawingCanvas() const = 0;
- virtual cc::PaintCanvas* ExistingDrawingCanvas() const = 0;
+ virtual cc::PaintCanvas* GetOrCreatePaintCanvas() = 0;
+ virtual cc::PaintCanvas* GetPaintCanvas() const = 0;
virtual void DidDraw(const SkIRect& dirty_rect) = 0;
@@ -236,7 +238,10 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
virtual sk_sp<PaintFilter> StateGetFilter() = 0;
virtual void SnapshotStateForFilter() = 0;
- virtual void ValidateStateStack() const = 0;
+ void ValidateStateStack() const {
+ ValidateStateStackWithCanvas(GetPaintCanvas());
+ }
+ virtual void ValidateStateStackWithCanvas(const cc::PaintCanvas*) const = 0;
virtual bool HasAlpha() const = 0;
@@ -248,7 +253,7 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
return kSRGBCanvasColorSpaceName;
}
virtual CanvasPixelFormat PixelFormat() const {
- return CanvasPixelFormat::kRGBA8;
+ return CanvasColorParams::GetNativeCanvasPixelFormat();
}
void RestoreMatrixClipStack(cc::PaintCanvas*) const;
@@ -259,7 +264,7 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
String textBaseline() const;
void setTextBaseline(const String&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
enum DrawCallType {
kStrokePath = 0,
@@ -361,8 +366,6 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
HeapVector<Member<CanvasRenderingContext2DState>> state_stack_;
AntiAliasingMode clip_antialiasing_;
- mutable UsageCounters usage_counters_;
-
virtual void FinalizeFrame() {}
float GetFontBaseline(const SimpleFontData&) const;
@@ -377,7 +380,7 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
virtual void DisableAcceleration() {}
virtual bool IsPaint2D() const { return false; }
- virtual void WillOverwriteCanvas() {}
+ virtual void WillOverwriteCanvas() = 0;
private:
void RealizeSaves();
@@ -453,18 +456,19 @@ void BaseRenderingContext2D::Draw(
return;
SkIRect clip_bounds;
- if (!DrawingCanvas() || !DrawingCanvas()->getDeviceClipBounds(&clip_bounds))
+ cc::PaintCanvas* paint_canvas = GetOrCreatePaintCanvas();
+ if (!paint_canvas || !paint_canvas->getDeviceClipBounds(&clip_bounds))
return;
if (IsFullCanvasCompositeMode(GetState().GlobalComposite()) ||
StateHasFilter()) {
- CompositedDraw(draw_func, DrawingCanvas(), paint_type, image_type);
+ CompositedDraw(draw_func, GetPaintCanvas(), paint_type, image_type);
DidDraw(clip_bounds);
} else if (GetState().GlobalComposite() == SkBlendMode::kSrc) {
ClearCanvas(); // takes care of checkOverdraw()
const PaintFlags* flags =
GetState().GetFlags(paint_type, kDrawForegroundOnly, image_type);
- draw_func(DrawingCanvas(), flags);
+ draw_func(GetPaintCanvas(), flags);
DidDraw(clip_bounds);
} else {
SkIRect dirty_rect;
@@ -474,7 +478,7 @@ void BaseRenderingContext2D::Draw(
if (paint_type != CanvasRenderingContext2DState::kStrokePaintType &&
draw_covers_clip_bounds(clip_bounds))
CheckOverdraw(bounds, flags, image_type, kClipFill);
- draw_func(DrawingCanvas(), flags);
+ draw_func(GetPaintCanvas(), flags);
DidDraw(dirty_rect);
}
}
@@ -491,7 +495,7 @@ void BaseRenderingContext2D::CompositedDraw(
SkMatrix ctm = c->getTotalMatrix();
c->setMatrix(SkMatrix::I());
PaintFlags composite_flags;
- composite_flags.setBlendMode((SkBlendMode)GetState().GlobalComposite());
+ composite_flags.setBlendMode(GetState().GlobalComposite());
if (GetState().ShouldDrawShadows()) {
// unroll into two independently composited passes if drawing shadows
PaintFlags shadow_flags =
@@ -501,10 +505,13 @@ void BaseRenderingContext2D::CompositedDraw(
if (filter) {
PaintFlags foreground_flags =
*GetState().GetFlags(paint_type, kDrawForegroundOnly, image_type);
- foreground_flags.setImageFilter(sk_make_sp<ComposePaintFilter>(
+ shadow_flags.setImageFilter(sk_make_sp<ComposePaintFilter>(
sk_make_sp<ComposePaintFilter>(foreground_flags.getImageFilter(),
shadow_flags.getImageFilter()),
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);
c->setMatrix(ctm);
draw_func(c, &foreground_flags);
} else {
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.h
index be45b1d2fff..789c99a2a80 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.h
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.h
@@ -26,7 +26,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_PATTERN_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_PATTERN_H_
-#include "third_party/blink/renderer/core/geometry/dom_matrix_2d_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_2d_init.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/graphics/pattern.h"
#include "third_party/blink/renderer/platform/transforms/affine_transform.h"
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.idl b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.idl
index afb67a419b1..fdab94ab301 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.idl
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.idl
@@ -22,10 +22,13 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
+// https://html.spec.whatwg.org/C/#canvaspattern
+
[
Exposed=(Window,Worker)
] interface CanvasPattern {
- [RaisesException] void setTransform(optional DOMMatrix2DInit transform);
+ [RaisesException] void setTransform(optional DOMMatrix2DInit transform = {});
};
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 41dc3431667..f5947119128 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
@@ -38,7 +38,6 @@
#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/public/platform/web_scroll_into_view_params.h"
#include "third_party/blink/renderer/bindings/modules/v8/rendering_context.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
#include "third_party/blink/renderer/core/css/css_font_selector.h"
@@ -64,8 +63,6 @@
#include "third_party/blink/renderer/platform/fonts/font_cache.h"
#include "third_party/blink/renderer/platform/fonts/text_run_paint_info.h"
#include "third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h"
-#include "third_party/blink/renderer/platform/graphics/canvas_heuristic_parameters.h"
-#include "third_party/blink/renderer/platform/graphics/draw_looper_builder.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/graphics/skia/skia_utils.h"
@@ -97,21 +94,21 @@ class CanvasRenderingContext2DAutoRestoreSkCanvas {
CanvasRenderingContext2D* context)
: context_(context), save_count_(0) {
DCHECK(context_);
- cc::PaintCanvas* c = context_->DrawingCanvas();
+ cc::PaintCanvas* c = context_->GetOrCreatePaintCanvas();
if (c) {
save_count_ = c->getSaveCount();
}
}
~CanvasRenderingContext2DAutoRestoreSkCanvas() {
- cc::PaintCanvas* c = context_->DrawingCanvas();
+ cc::PaintCanvas* c = context_->GetOrCreatePaintCanvas();
if (c)
c->restoreToCount(save_count_);
context_->ValidateStateStack();
}
private:
- Member<CanvasRenderingContext2D> context_;
+ CanvasRenderingContext2D* context_;
int save_count_;
};
@@ -151,15 +148,16 @@ void CanvasRenderingContext2D::SetCanvasGetContextResult(
CanvasRenderingContext2D::~CanvasRenderingContext2D() = default;
-void CanvasRenderingContext2D::ValidateStateStack() const {
+void CanvasRenderingContext2D::ValidateStateStackWithCanvas(
+ const cc::PaintCanvas* canvas) const {
#if DCHECK_IS_ON()
- if (cc::PaintCanvas* sk_canvas = ExistingDrawingCanvas()) {
+ if (canvas) {
// The canvas should always have an initial save frame, to support
// resetting the top level matrix and clip.
- DCHECK_GT(sk_canvas->getSaveCount(), 1);
+ DCHECK_GT(canvas->getSaveCount(), 1);
if (context_lost_mode_ == kNotLostContext) {
- DCHECK_EQ(static_cast<size_t>(sk_canvas->getSaveCount()),
+ DCHECK_EQ(static_cast<size_t>(canvas->getSaveCount()),
state_stack_.size() + 1);
}
}
@@ -225,7 +223,7 @@ void CanvasRenderingContext2D::DidSetSurfaceSize() {
}
}
-void CanvasRenderingContext2D::Trace(blink::Visitor* visitor) {
+void CanvasRenderingContext2D::Trace(Visitor* visitor) {
visitor->Trace(hit_region_manager_);
visitor->Trace(filter_operations_);
CanvasRenderingContext::Trace(visitor);
@@ -346,7 +344,8 @@ void CanvasRenderingContext2D::ScrollPathIntoViewInternal(const Path& path) {
if (!GetState().IsTransformInvertible() || path.IsEmpty())
return;
- canvas()->GetDocument().UpdateStyleAndLayout();
+ canvas()->GetDocument().UpdateStyleAndLayout(
+ DocumentUpdateReason::kJavaScript);
LayoutObject* renderer = canvas()->GetLayoutObject();
LayoutBox* layout_box = canvas()->GetLayoutBox();
@@ -378,9 +377,10 @@ void CanvasRenderingContext2D::ScrollPathIntoViewInternal(const Path& path) {
path_rect.Intersect(canvas_rect);
// Horizontal text is aligned at the top of the screen
- ScrollAlignment horizontal_scroll_mode =
- ScrollAlignment::kAlignToEdgeIfNeeded;
- ScrollAlignment vertical_scroll_mode = ScrollAlignment::kAlignTopAlways;
+ mojom::blink::ScrollAlignment horizontal_scroll_mode =
+ ScrollAlignment::ToEdgeIfNeeded();
+ mojom::blink::ScrollAlignment vertical_scroll_mode =
+ ScrollAlignment::TopAlways();
// Vertical text needs be aligned horizontally on the screen
bool is_horizontal_writing_mode =
@@ -388,15 +388,15 @@ void CanvasRenderingContext2D::ScrollPathIntoViewInternal(const Path& path) {
if (!is_horizontal_writing_mode) {
bool is_right_to_left =
canvas()->EnsureComputedStyle()->IsFlippedBlocksWritingMode();
- horizontal_scroll_mode =
- (is_right_to_left ? ScrollAlignment::kAlignRightAlways
- : ScrollAlignment::kAlignLeftAlways);
- vertical_scroll_mode = ScrollAlignment::kAlignToEdgeIfNeeded;
+ horizontal_scroll_mode = (is_right_to_left ? ScrollAlignment::RightAlways()
+ : ScrollAlignment::LeftAlways());
+ vertical_scroll_mode = ScrollAlignment::ToEdgeIfNeeded();
}
renderer->ScrollRectToVisible(
- path_rect,
- WebScrollIntoViewParams(horizontal_scroll_mode, vertical_scroll_mode,
- kProgrammaticScroll, false, kScrollBehaviorAuto));
+ path_rect, ScrollAlignment::CreateScrollIntoViewParams(
+ horizontal_scroll_mode, vertical_scroll_mode,
+ mojom::blink::ScrollType::kProgrammatic, false,
+ mojom::blink::ScrollBehavior::kAuto));
}
void CanvasRenderingContext2D::clearRect(double x,
@@ -437,19 +437,19 @@ void CanvasRenderingContext2D::SnapshotStateForFilter() {
ModifiableState().SetFontForFilter(AccessFont());
}
-cc::PaintCanvas* CanvasRenderingContext2D::DrawingCanvas() const {
+cc::PaintCanvas* CanvasRenderingContext2D::GetOrCreatePaintCanvas() {
if (isContextLost())
return nullptr;
if (canvas()->GetOrCreateCanvas2DLayerBridge())
- return canvas()->GetCanvas2DLayerBridge()->DrawingCanvas();
+ return canvas()->GetCanvas2DLayerBridge()->GetPaintCanvas();
return nullptr;
}
-cc::PaintCanvas* CanvasRenderingContext2D::ExistingDrawingCanvas() const {
- if (isContextLost())
+cc::PaintCanvas* CanvasRenderingContext2D::GetPaintCanvas() const {
+ if (isContextLost() || !canvas()->GetCanvas2DLayerBridge())
return nullptr;
- if (IsPaintable())
- return canvas()->GetCanvas2DLayerBridge()->DrawingCanvas();
+ if (canvas() && canvas()->GetCanvas2DLayerBridge()->ResourceProvider())
+ return canvas()->GetCanvas2DLayerBridge()->GetPaintCanvas();
return nullptr;
}
@@ -459,8 +459,7 @@ String CanvasRenderingContext2D::font() const {
canvas()->GetDocument().GetCanvasFontCache()->WillUseCurrentFont();
StringBuilder serialized_font;
- const FontDescription& font_description =
- GetState().GetFont().GetFontDescription();
+ const FontDescription& font_description = GetState().GetFontDescription();
if (font_description.Style() == ItalicSlopeValue())
serialized_font.Append("italic ");
@@ -518,8 +517,7 @@ void CanvasRenderingContext2D::setFont(const String& new_font) {
scoped_refptr<ComputedStyle> font_style;
const ComputedStyle* computed_style = canvas()->EnsureComputedStyle();
if (computed_style) {
- HashMap<String, Font>::iterator i =
- fonts_resolved_using_current_style_.find(new_font);
+ auto i = fonts_resolved_using_current_style_.find(new_font);
if (i != fonts_resolved_using_current_style_.end()) {
auto add_result = font_lru_list_.PrependOrMoveToFirst(new_font);
DCHECK(!add_result.is_new_entry);
@@ -540,7 +538,6 @@ void CanvasRenderingContext2D::setFont(const String& new_font) {
element_font_description.SpecifiedSize());
font_style->SetFontDescription(element_font_description);
- font_style->GetFont().Update(font_style->GetFont().GetFontSelector());
canvas()->GetDocument().EnsureStyleResolver().ComputeFont(
*canvas(), font_style.get(), *parsed_style);
@@ -550,14 +547,13 @@ void CanvasRenderingContext2D::setFont(const String& new_font) {
font_style->GetFont().GetFontDescription());
final_description.SetComputedSize(final_description.SpecifiedSize());
final_description.SetAdjustedSize(final_description.SpecifiedSize());
- Font final_font(final_description);
- fonts_resolved_using_current_style_.insert(new_font, final_font);
+ fonts_resolved_using_current_style_.insert(new_font, final_description);
auto add_result = font_lru_list_.PrependOrMoveToFirst(new_font);
DCHECK(add_result.is_new_entry);
PruneLocalFontCache(canvas_font_cache->HardMaxFonts()); // hard limit
should_prune_local_font_cache_ = true; // apply soft limit
- ModifiableState().SetFont(final_font, Host()->GetFontSelector());
+ ModifiableState().SetFont(final_description, Host()->GetFontSelector());
}
} else {
Font resolved_font;
@@ -570,8 +566,7 @@ void CanvasRenderingContext2D::setFont(const String& new_font) {
FontDescription final_description(resolved_font.GetFontDescription());
final_description.SetComputedSize(final_description.SpecifiedSize());
final_description.SetAdjustedSize(final_description.SpecifiedSize());
- Font final_font(final_description);
- ModifiableState().SetFont(final_font, Host()->GetFontSelector());
+ ModifiableState().SetFont(final_description, Host()->GetFontSelector());
}
// The parse succeeded.
@@ -678,7 +673,6 @@ void CanvasRenderingContext2D::FinalizeFrame() {
TRACE_EVENT0("blink", "CanvasRenderingContext2D::FinalizeFrame");
if (IsPaintable())
canvas()->GetCanvas2DLayerBridge()->FinalizeFrame();
- usage_counters_.num_frames_since_reset++;
}
bool CanvasRenderingContext2D::ParseColorOrCurrentColor(
@@ -839,10 +833,10 @@ void CanvasRenderingContext2D::DrawTextInternal(
// accessFont needs the style to be up to date, but updating style can cause
// script to run, (e.g. due to autofocus) which can free the canvas (set size
- // to 0, for example), so update style before grabbing the drawingCanvas.
+ // to 0, for example), so update style before grabbing the PaintCanvas.
canvas()->GetDocument().UpdateStyleAndLayoutTreeForNode(canvas());
- cc::PaintCanvas* c = DrawingCanvas();
+ cc::PaintCanvas* c = GetOrCreatePaintCanvas();
if (!c)
return;
@@ -907,13 +901,13 @@ void CanvasRenderingContext2D::DrawTextInternal(
CanvasRenderingContext2DAutoRestoreSkCanvas state_restorer(this);
if (use_max_width) {
- DrawingCanvas()->save();
- DrawingCanvas()->translate(location.X(), location.Y());
+ c->save();
// We draw when fontWidth is 0 so compositing operations (eg, a "copy" op)
- // still work.
- DrawingCanvas()->scale(
- (font_width > 0 ? clampTo<float>(width / font_width) : 0), 1);
- location = FloatPoint();
+ // still work. As the width of canvas is scaled, so text can be scaled to
+ // match the given maxwidth, update text location so it appears on desired
+ // place.
+ c->scale(clampTo<float>(width / font_width), 1);
+ location.SetX(location.X() / clampTo<float>(width / font_width));
}
Draw(
@@ -933,7 +927,7 @@ const Font& CanvasRenderingContext2D::AccessFont() {
if (!GetState().HasRealizedFont())
setFont(GetState().UnparsedFont());
canvas()->GetDocument().GetCanvasFontCache()->WillUseCurrentFont();
- return GetState().GetFont();
+ return ModifiableState().GetFont();
}
void CanvasRenderingContext2D::SetIsInHiddenPage(bool hidden) {
@@ -1013,15 +1007,13 @@ bool CanvasRenderingContext2D::FocusRingCallIsValid(const Path& path,
}
void CanvasRenderingContext2D::DrawFocusRing(const Path& path) {
- usage_counters_.num_draw_focus_calls++;
- if (!DrawingCanvas())
+ if (!GetOrCreatePaintCanvas())
return;
SkColor color = LayoutTheme::GetTheme().FocusRingColor().Rgb();
const int kFocusRingWidth = 5;
-
- DrawPlatformFocusRing(path.GetSkPath(), DrawingCanvas(), color,
- kFocusRingWidth);
+ DrawPlatformFocusRing(path.GetSkPath(), GetPaintCanvas(), color,
+ /*width=*/kFocusRingWidth, /*radius=*/kFocusRingWidth);
// We need to add focusRingWidth to dirtyRect.
StrokeData stroke_data;
@@ -1036,7 +1028,8 @@ void CanvasRenderingContext2D::DrawFocusRing(const Path& path) {
void CanvasRenderingContext2D::UpdateElementAccessibility(const Path& path,
Element* element) {
- element->GetDocument().UpdateStyleAndLayout();
+ element->GetDocument().UpdateStyleAndLayout(
+ DocumentUpdateReason::kAccessibility);
AXObjectCache* ax_object_cache =
element->GetDocument().ExistingAXObjectCache();
LayoutBoxModelObject* lbmo = canvas()->GetLayoutBoxModelObject();
@@ -1077,7 +1070,7 @@ void CanvasRenderingContext2D::addHitRegion(const HitRegionOptions* options,
Path hit_region_path = options->path() ? options->path()->GetPath() : path_;
- cc::PaintCanvas* c = DrawingCanvas();
+ cc::PaintCanvas* c = GetOrCreatePaintCanvas();
if (hit_region_path.IsEmpty() || !c || !GetState().IsTransformInvertible() ||
c->isClipEmpty()) {
@@ -1147,4 +1140,12 @@ bool CanvasRenderingContext2D::IsCanvas2DBufferValid() const {
return false;
}
+RespectImageOrientationEnum CanvasRenderingContext2D::RespectImageOrientation()
+ const {
+ if (canvas()->RespectImageOrientation() != kRespectImageOrientation) {
+ return kDoNotRespectImageOrientation;
+ }
+ return kRespectImageOrientation;
+}
+
} // namespace blink
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 7efef4f19b4..bda1b439ed3 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,13 +30,13 @@
#include <random>
#include "base/macros.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/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_settings.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -176,10 +176,12 @@ class MODULES_EXPORT CanvasRenderingContext2D final
bool CanCreateCanvas2dResourceProvider() const final;
+ RespectImageOrientationEnum RespectImageOrientation() const final;
+
bool ParseColorOrCurrentColor(Color&, const String& color_string) const final;
- cc::PaintCanvas* DrawingCanvas() const final;
- cc::PaintCanvas* ExistingDrawingCanvas() const final;
+ cc::PaintCanvas* GetOrCreatePaintCanvas() final;
+ cc::PaintCanvas* GetPaintCanvas() const final;
void DidDraw(const SkIRect& dirty_rect) final;
scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) final;
@@ -188,7 +190,7 @@ class MODULES_EXPORT CanvasRenderingContext2D final
sk_sp<PaintFilter> StateGetFilter() final;
void SnapshotStateForFilter() final;
- void ValidateStateStack() const final;
+ void ValidateStateStackWithCanvas(const cc::PaintCanvas*) const final;
void FinalizeFrame() override;
@@ -198,7 +200,7 @@ class MODULES_EXPORT CanvasRenderingContext2D final
void WillDrawImage(CanvasImageSource*) const final;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
CanvasColorParams ColorParamsForTest() const { return ColorParams(); }
@@ -267,7 +269,7 @@ class MODULES_EXPORT CanvasRenderingContext2D final
TaskRunnerTimer<CanvasRenderingContext2D> try_restore_context_event_timer_;
FilterOperations filter_operations_;
- HashMap<String, Font> fonts_resolved_using_current_style_;
+ HashMap<String, FontDescription> fonts_resolved_using_current_style_;
bool should_prune_local_font_cache_;
LinkedHashSet<String> font_lru_list_;
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl
index d2b906ebb71..b4b6ae1e108 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl
@@ -59,7 +59,7 @@ interface CanvasRenderingContext2D {
void translate(unrestricted double x, unrestricted double y);
void transform(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f);
void setTransform(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f);
- [RaisesException] void setTransform(optional DOMMatrix2DInit transform);
+ [RaisesException] void setTransform(optional DOMMatrix2DInit transform = {});
DOMMatrix getTransform();
void resetTransform();
@@ -119,7 +119,7 @@ interface CanvasRenderingContext2D {
[CallWith=ScriptState, RaisesException] void drawImage(CanvasImageSource image, unrestricted double sx, unrestricted double sy, unrestricted double sw, unrestricted double sh, unrestricted double dx, unrestricted double dy, unrestricted double dw, unrestricted double dh);
// hit regions
- [RuntimeEnabled=CanvasHitRegion, RaisesException] void addHitRegion(optional HitRegionOptions options);
+ [RuntimeEnabled=CanvasHitRegion, RaisesException] void addHitRegion(optional HitRegionOptions options = {});
[RuntimeEnabled=CanvasHitRegion] void removeHitRegion(DOMString id);
[RuntimeEnabled=CanvasHitRegion] void clearHitRegions();
@@ -132,7 +132,7 @@ interface CanvasRenderingContext2D {
// https://github.com/WICG/canvas-color-space/blob/master/CanvasColorSpaceProposal.md
[RuntimeEnabled=CanvasColorManagement, RaisesException] ImageData createImageData(unsigned long sw, unsigned long sh, ImageDataColorSettings imageDataColorSettings);
- [RuntimeEnabled=CanvasColorManagement, RaisesException] ImageData createImageData(ImageDataArray data, unsigned long sw, unsigned long sh, optional ImageDataColorSettings imageDataColorSettings);
+ [RuntimeEnabled=CanvasColorManagement, RaisesException] ImageData createImageData(ImageDataArray data, unsigned long sw, unsigned long sh, optional ImageDataColorSettings imageDataColorSettings = {});
// Context state
// Should be merged with WebGL counterpart in CanvasRenderingContext, once no-longer experimental
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 466ff0c1167..79a5ddca35d 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
@@ -7,6 +7,7 @@
#include <memory>
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_hit_region_options.h"
#include "third_party/blink/renderer/core/accessibility/ax_context.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
@@ -19,7 +20,6 @@
#include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_gradient.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.h"
-#include "third_party/blink/renderer/modules/canvas/canvas2d/hit_region_options.h"
#include "third_party/blink/renderer/modules/webgl/webgl_rendering_context.h"
using testing::Mock;
@@ -61,7 +61,7 @@ void CanvasRenderingContext2DAPITest::CreateContext(OpacityMode opacity_mode) {
void CanvasRenderingContext2DAPITest::SetUp() {
PageTestBase::SetUp();
- GetDocument().documentElement()->SetInnerHTMLFromString(
+ GetDocument().documentElement()->setInnerHTML(
"<body><canvas id='c'></canvas></body>");
UpdateAllLifecyclePhasesForTest();
canvas_element_ = To<HTMLCanvasElement>(GetDocument().getElementById("c"));
@@ -305,7 +305,7 @@ TEST_F(CanvasRenderingContext2DAPITest,
}
void ResetCanvasForAccessibilityRectTest(Document& document) {
- document.documentElement()->SetInnerHTMLFromString(R"HTML(
+ document.documentElement()->setInnerHTML(R"HTML(
<canvas id='canvas' style='position:absolute; top:0px; left:0px;
padding:10px; margin:5px;'>
<button id='button'></button></canvas>
@@ -338,8 +338,8 @@ TEST_F(CanvasRenderingContext2DAPITest, AccessibilityRectTestForAddHitRegion) {
context->rect(10, 10, 40, 40);
context->addHitRegion(options, exception_state);
- AXObjectCacheImpl* ax_object_cache =
- ToAXObjectCacheImpl(GetDocument().ExistingAXObjectCache());
+ auto* ax_object_cache =
+ To<AXObjectCacheImpl>(GetDocument().ExistingAXObjectCache());
AXObject* ax_object = ax_object_cache->GetOrCreate(button_element);
LayoutRect ax_bounds = ax_object->GetBoundsInFrameCoordinates();
@@ -365,8 +365,8 @@ TEST_F(CanvasRenderingContext2DAPITest,
context->rect(10, 10, 40, 40);
context->drawFocusIfNeeded(button_element);
- AXObjectCacheImpl* ax_object_cache =
- ToAXObjectCacheImpl(GetDocument().ExistingAXObjectCache());
+ auto* ax_object_cache =
+ To<AXObjectCacheImpl>(GetDocument().ExistingAXObjectCache());
AXObject* ax_object = ax_object_cache->GetOrCreate(button_element);
LayoutRect ax_bounds = ax_object->GetBoundsInFrameCoordinates();
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 b670fe73bca..de05aa36b3b 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
@@ -25,6 +25,7 @@
#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/graphics/skia/skia_utils.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/skia/include/effects/SkDashPathEffect.h"
#include "third_party/skia/include/effects/SkDropShadowImageFilter.h"
@@ -35,8 +36,8 @@ namespace blink {
CanvasRenderingContext2DState::CanvasRenderingContext2DState()
: unrealized_save_count_(0),
- stroke_style_(CanvasStyle::CreateFromRGBA(SK_ColorBLACK)),
- fill_style_(CanvasStyle::CreateFromRGBA(SK_ColorBLACK)),
+ stroke_style_(MakeGarbageCollected<CanvasStyle>(SK_ColorBLACK)),
+ fill_style_(MakeGarbageCollected<CanvasStyle>(SK_ColorBLACK)),
shadow_blur_(0),
shadow_color_(Color::kTransparent),
global_alpha_(1),
@@ -124,13 +125,13 @@ void CanvasRenderingContext2DState::FontsNeedUpdate(
DCHECK_EQ(font_selector, font_.GetFontSelector());
DCHECK(realized_font_);
- font_.Update(font_selector);
+ font_ = Font(font_.GetFontDescription(), font_selector);
// FIXME: We only really need to invalidate the resolved filter if the font
// update above changed anything and the filter uses font-dependent units.
resolved_filter_.reset();
}
-void CanvasRenderingContext2DState::Trace(blink::Visitor* visitor) {
+void CanvasRenderingContext2DState::Trace(Visitor* visitor) {
visitor->Trace(stroke_style_);
visitor->Trace(fill_style_);
visitor->Trace(filter_value_);
@@ -252,20 +253,28 @@ void CanvasRenderingContext2DState::ClipPath(
has_complex_clip_ = true;
}
-void CanvasRenderingContext2DState::SetFont(const Font& font,
- FontSelector* selector) {
- font_ = font;
- font_.Update(selector);
+void CanvasRenderingContext2DState::SetFont(
+ const FontDescription& font_description,
+ FontSelector* selector) {
+ font_ = Font(font_description, selector);
realized_font_ = true;
if (selector)
selector->RegisterForInvalidationCallbacks(this);
}
-const Font& CanvasRenderingContext2DState::GetFont() const {
+const Font& CanvasRenderingContext2DState::GetFont() {
DCHECK(realized_font_);
+ if (!font_.IsFallbackValid())
+ FontsNeedUpdate(font_.GetFontSelector());
return font_;
}
+const FontDescription& CanvasRenderingContext2DState::GetFontDescription()
+ const {
+ DCHECK(realized_font_);
+ return font_.GetFontDescription();
+}
+
void CanvasRenderingContext2DState::SetTransform(
const AffineTransform& transform) {
is_transform_invertible_ = transform.IsInvertible();
@@ -329,7 +338,8 @@ sk_sp<PaintFilter> CanvasRenderingContext2DState::GetFilter(
if (!resolved_filter_) {
// Update the filter value to the proper base URL if needed.
if (filter_value_->MayContainUrl()) {
- style_resolution_host->GetDocument().UpdateStyleAndLayout();
+ style_resolution_host->GetDocument().UpdateStyleAndLayout(
+ DocumentUpdateReason::kCanvas);
filter_value_->ReResolveUrl(style_resolution_host->GetDocument());
}
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 eaf5b21390c..b224ec4c62c 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
enum PaintType {
kFillPaintType,
@@ -45,12 +45,6 @@ class CanvasRenderingContext2DState final
kImagePaintType,
};
- static CanvasRenderingContext2DState* Create(
- const CanvasRenderingContext2DState& other,
- ClipListCopyMode mode) {
- return MakeGarbageCollected<CanvasRenderingContext2DState>(other, mode);
- }
-
// FontSelectorClient implementation
void FontsNeedUpdate(FontSelector*) override;
@@ -84,8 +78,9 @@ class CanvasRenderingContext2DState final
return clip_list_.GetCurrentClipPath();
}
- void SetFont(const Font&, FontSelector*);
- const Font& GetFont() const;
+ void SetFont(const FontDescription&, FontSelector*);
+ const Font& GetFont();
+ const FontDescription& GetFontDescription() const;
bool HasRealizedFont() const { return realized_font_; }
void SetUnparsedFont(const String& font) { unparsed_font_ = font; }
const String& UnparsedFont() const { return unparsed_font_; }
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 4663521456d..4d1e27c05a5 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
@@ -16,6 +16,7 @@
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
@@ -26,7 +27,6 @@
#include "third_party/blink/renderer/core/html/canvas/image_data.h"
#include "third_party/blink/renderer/core/html/html_image_element.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
-#include "third_party/blink/renderer/core/imagebitmap/image_bitmap_options.h"
#include "third_party/blink/renderer/core/layout/layout_box_model_object.h"
#include "third_party/blink/renderer/core/loader/resource/image_resource_content.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
@@ -34,7 +34,6 @@
#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.h"
#include "third_party/blink/renderer/modules/webgl/webgl_rendering_context.h"
#include "third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h"
-#include "third_party/blink/renderer/platform/graphics/canvas_heuristic_parameters.h"
#include "third_party/blink/renderer/platform/graphics/color_correction_test_utils.h"
#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
@@ -70,7 +69,8 @@ class FakeImageSource : public CanvasImageSource {
const FloatSize&) override;
bool WouldTaintOrigin() const override { return false; }
- FloatSize ElementSize(const FloatSize&) const override {
+ FloatSize ElementSize(const FloatSize&,
+ const RespectImageOrientationEnum) const override {
return FloatSize(size_);
}
bool IsOpaque() const override { return is_opaque_; }
@@ -155,8 +155,7 @@ class CanvasRenderingContext2DTest : public ::testing::Test {
}
void UpdateAllLifecyclePhasesForTest() {
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
GetDocument().View()->RunPostLifecycleSteps();
}
@@ -169,7 +168,7 @@ class CanvasRenderingContext2DTest : public ::testing::Test {
class WrapGradients final : public GarbageCollected<WrapGradients> {
public:
- void Trace(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
visitor->Trace(opaque_gradient_);
visitor->Trace(alpha_gradient_);
}
@@ -220,7 +219,7 @@ void CanvasRenderingContext2DTest::SetUp() {
web_view_helper_ = std::make_unique<frame_test_helpers::WebViewHelper>();
web_view_helper_->Initialize();
- GetDocument().documentElement()->SetInnerHTMLFromString(String::FromUTF8(
+ GetDocument().documentElement()->setInnerHTML(String::FromUTF8(
"<body><canvas id='c'></canvas><canvas id='d'></canvas></body>"));
UpdateAllLifecyclePhasesForTest();
@@ -330,8 +329,9 @@ class FakeCanvasResourceProvider : public CanvasResourceProvider {
sk_sp<SkSurface> CreateSkSurface() const override {
return sk_sp<SkSurface>();
}
- scoped_refptr<StaticBitmapImage> Snapshot() override {
- return SnapshotInternal();
+ scoped_refptr<StaticBitmapImage> Snapshot(
+ const ImageOrientation& orientation) override {
+ return SnapshotInternal(orientation);
}
private:
@@ -586,13 +586,13 @@ TEST_F(CanvasRenderingContext2DTest, ImageResourceLifetime) {
const ImageBitmapOptions* default_options = ImageBitmapOptions::Create();
base::Optional<IntRect> crop_rect =
IntRect(0, 0, canvas->width(), canvas->height());
- ImageBitmap* image_bitmap_from_canvas =
- ImageBitmap::Create(canvas, crop_rect, default_options);
+ auto* image_bitmap_from_canvas =
+ MakeGarbageCollected<ImageBitmap>(canvas, crop_rect, default_options);
ASSERT_TRUE(image_bitmap_from_canvas);
crop_rect = IntRect(0, 0, 20, 20);
- image_bitmap_derived = ImageBitmap::Create(image_bitmap_from_canvas,
- crop_rect, default_options);
+ image_bitmap_derived = MakeGarbageCollected<ImageBitmap>(
+ image_bitmap_from_canvas, crop_rect, default_options);
ASSERT_TRUE(image_bitmap_derived);
}
CanvasContextCreationAttributesCore attributes;
@@ -736,13 +736,10 @@ TEST_F(CanvasRenderingContext2DTest,
size, CanvasColorParams(), kPreferNoAcceleration);
fake_deaccelerate_surface->SetCanvasResourceHost(&host);
- cc::PaintCanvas* paint_canvas_ptr =
- fake_deaccelerate_surface->DrawingCanvas();
FakeCanvas2DLayerBridge* surface_ptr = fake_deaccelerate_surface.get();
EXPECT_CALL(*fake_deaccelerate_surface, DrawFullImage(_)).Times(1);
- EXPECT_CALL(*fake_deaccelerate_surface,
- DidRestoreCanvasMatrixClipStack(paint_canvas_ptr))
+ EXPECT_CALL(*fake_deaccelerate_surface, DidRestoreCanvasMatrixClipStack(_))
.Times(1);
EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated());
@@ -895,7 +892,8 @@ TEST_F(CanvasRenderingContext2DTest, ImageBitmapColorSpaceConversion) {
options->setColorSpaceConversion(
ColorCorrectionTestUtils::ColorSpaceConversionToString(
static_cast<ColorSpaceConversion>(conversion_iterator)));
- ImageBitmap* image_bitmap = ImageBitmap::Create(canvas, crop_rect, options);
+ ImageBitmap* image_bitmap =
+ MakeGarbageCollected<ImageBitmap>(canvas, crop_rect, options);
ASSERT_TRUE(image_bitmap);
sk_sp<SkImage> converted_image =
image_bitmap->BitmapImage()->PaintImageForCurrentFrame().GetSkImage();
@@ -995,28 +993,28 @@ void TestPutImageDataOnCanvasWithColorSpaceSettings(
0, 0, 0, 0, // Transparent
255, 192, 128, 64, // Decreasing values
93, 117, 205, 41}; // Random values
- unsigned data_length = 16;
+ size_t data_length = 16;
uint16_t* u16_pixels = new uint16_t[data_length];
- for (unsigned i = 0; i < data_length; i++)
+ for (size_t i = 0; i < data_length; i++)
u16_pixels[i] = u8_pixels[i] * 257;
float* f32_pixels = new float[data_length];
- for (unsigned i = 0; i < data_length; i++)
+ for (size_t i = 0; i < data_length; i++)
f32_pixels[i] = u8_pixels[i] / 255.0;
- DOMArrayBufferView* data_array = nullptr;
-
- DOMUint8ClampedArray* data_u8 =
- DOMUint8ClampedArray::Create(u8_pixels, data_length);
+ NotShared<DOMUint8ClampedArray> data_u8(
+ DOMUint8ClampedArray::Create(u8_pixels, data_length));
DCHECK(data_u8);
- EXPECT_EQ(data_length, data_u8->deprecatedLengthAsUnsigned());
- DOMUint16Array* data_u16 = DOMUint16Array::Create(u16_pixels, data_length);
+ EXPECT_EQ(data_length, data_u8->lengthAsSizeT());
+ NotShared<DOMUint16Array> data_u16(
+ DOMUint16Array::Create(u16_pixels, data_length));
DCHECK(data_u16);
- EXPECT_EQ(data_length, data_u16->deprecatedLengthAsUnsigned());
- DOMFloat32Array* data_f32 = DOMFloat32Array::Create(f32_pixels, data_length);
+ EXPECT_EQ(data_length, data_u16->lengthAsSizeT());
+ NotShared<DOMFloat32Array> data_f32(
+ DOMFloat32Array::Create(f32_pixels, data_length));
DCHECK(data_f32);
- EXPECT_EQ(data_length, data_f32->deprecatedLengthAsUnsigned());
+ EXPECT_EQ(data_length, data_f32->lengthAsSizeT());
ImageData* image_data = nullptr;
ImageDataColorSettings* color_settings = ImageDataColorSettings::Create();
@@ -1033,17 +1031,18 @@ void TestPutImageDataOnCanvasWithColorSpaceSettings(
ImageData::CanvasColorSpaceName(image_data_color_spaces[i]));
for (unsigned j = 0; j < num_image_data_storage_formats; j++) {
+ NotShared<DOMArrayBufferView> data_array;
switch (image_data_storage_formats[j]) {
case kUint8ClampedArrayStorageFormat:
- data_array = static_cast<DOMArrayBufferView*>(data_u8);
+ data_array = data_u8;
color_settings->setStorageFormat(kUint8ClampedArrayStorageFormatName);
break;
case kUint16ArrayStorageFormat:
- data_array = static_cast<DOMArrayBufferView*>(data_u16);
+ data_array = data_u16;
color_settings->setStorageFormat(kUint16ArrayStorageFormatName);
break;
case kFloat32ArrayStorageFormat:
- data_array = static_cast<DOMArrayBufferView*>(data_f32);
+ data_array = data_f32;
color_settings->setStorageFormat(kFloat32ArrayStorageFormatName);
break;
default:
@@ -1142,11 +1141,14 @@ TEST_F(CanvasRenderingContext2DTestAccelerated,
CreateContext(kNonOpaque);
IntSize size(300, 300);
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(size, Canvas2DLayerBridge::kEnableAcceleration);
+ std::make_unique<Canvas2DLayerBridge>(
+ size, Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams());
// Force hibernatation to occur in an immediate task.
bridge->DontUseIdleSchedulingForTesting();
CanvasElement().SetResourceProviderForTesting(nullptr, std::move(bridge),
size);
+ CanvasElement().GetCanvas2DLayerBridge()->SetCanvasResourceHost(
+ canvas_element_);
EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated());
// Take a snapshot to trigger lazy resource provider creation
@@ -1171,7 +1173,8 @@ TEST_F(CanvasRenderingContext2DTestAccelerated,
// The page is hidden so it doesn't make sense to paint, and doing so will
// DCHECK. Update all other lifecycle phases.
- GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint(
+ DocumentUpdateReason::kTest);
EXPECT_FALSE(layer->NeedsCompositingInputsUpdate());
// Wake up again, which should request a compositing update synchronously.
@@ -1186,12 +1189,14 @@ TEST_F(CanvasRenderingContext2DTestAccelerated,
CreateContext(kNonOpaque);
IntSize size(300, 300);
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(size, Canvas2DLayerBridge::kEnableAcceleration);
+ std::make_unique<Canvas2DLayerBridge>(
+ size, Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams());
// Force hibernatation to occur in an immediate task.
bridge->DontUseIdleSchedulingForTesting();
CanvasElement().SetResourceProviderForTesting(nullptr, std::move(bridge),
size);
-
+ CanvasElement().GetCanvas2DLayerBridge()->SetCanvasResourceHost(
+ canvas_element_);
EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated());
EXPECT_TRUE(CanvasElement().GetLayoutBoxModelObject());
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 96540a18a01..db362e3bd6f 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
@@ -53,7 +53,7 @@ enum ColorParseResult {
static ColorParseResult ParseColor(Color& parsed_color,
const String& color_string,
WebColorScheme color_scheme) {
- if (DeprecatedEqualIgnoringCase(color_string, "currentcolor"))
+ if (EqualIgnoringASCIICase(color_string, "currentcolor"))
return kParsedCurrentColor;
const bool kUseStrictParsing = true;
if (CSSParser::ParseColor(parsed_color, color_string, kUseStrictParsing))
@@ -109,16 +109,6 @@ CanvasStyle::CanvasStyle(CanvasGradient* gradient)
CanvasStyle::CanvasStyle(CanvasPattern* pattern)
: type_(kImagePattern), pattern_(pattern) {}
-CanvasStyle* CanvasStyle::CreateFromGradient(CanvasGradient* gradient) {
- DCHECK(gradient);
- return MakeGarbageCollected<CanvasStyle>(gradient);
-}
-
-CanvasStyle* CanvasStyle::CreateFromPattern(CanvasPattern* pattern) {
- DCHECK(pattern);
- return MakeGarbageCollected<CanvasStyle>(pattern);
-}
-
void CanvasStyle::ApplyToFlags(PaintFlags& flags) const {
switch (type_) {
case kColorRGBA:
@@ -143,7 +133,7 @@ RGBA32 CanvasStyle::PaintColor() const {
return Color::kBlack;
}
-void CanvasStyle::Trace(blink::Visitor* visitor) {
+void CanvasStyle::Trace(Visitor* visitor) {
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 c5c55670009..fca9d07f187 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
@@ -41,15 +41,9 @@ class HTMLCanvasElement;
class CanvasStyle final : public GarbageCollected<CanvasStyle> {
public:
- static CanvasStyle* CreateFromRGBA(RGBA32 rgba) {
- return MakeGarbageCollected<CanvasStyle>(rgba);
- }
- static CanvasStyle* CreateFromGradient(CanvasGradient*);
- static CanvasStyle* CreateFromPattern(CanvasPattern*);
-
- CanvasStyle(RGBA32);
- CanvasStyle(CanvasGradient*);
- CanvasStyle(CanvasPattern*);
+ explicit CanvasStyle(RGBA32);
+ explicit CanvasStyle(CanvasGradient*);
+ explicit CanvasStyle(CanvasPattern*);
String GetColor() const {
DCHECK_EQ(type_, kColorRGBA);
@@ -65,7 +59,7 @@ class CanvasStyle final : public GarbageCollected<CanvasStyle> {
return type_ == kColorRGBA && rgba_ == rgba;
}
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
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 fc1ba5beebd..ab288595cb0 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(blink::Visitor* visitor) {
+void HitRegion::Trace(Visitor* visitor) {
visitor->Trace(control_);
}
@@ -118,7 +118,7 @@ unsigned HitRegionManager::GetHitRegionsCount() const {
return hit_region_list_.size();
}
-void HitRegionManager::Trace(blink::Visitor* visitor) {
+void HitRegionManager::Trace(Visitor* visitor) {
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 909768d929b..968009a8535 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
@@ -7,8 +7,8 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_hit_region_options.h"
#include "third_party/blink/renderer/core/dom/element.h"
-#include "third_party/blink/renderer/modules/canvas/canvas2d/hit_region_options.h"
#include "third_party/blink/renderer/platform/graphics/path.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/linked_hash_set.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(blink::Visitor*);
+ void Trace(Visitor*);
private:
String id_;
@@ -56,7 +56,7 @@ class HitRegionManager final : public GarbageCollected<HitRegionManager> {
unsigned GetHitRegionsCount() const;
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
typedef HeapLinkedHashSet<Member<HitRegion>> HitRegionList;
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.h
index d03101cb9b4..e5905ff6049 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.h
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.h
@@ -29,9 +29,9 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_PATH_2D_H_
#include "base/macros.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_2d_init.h"
#include "third_party/blink/renderer/bindings/modules/v8/path_2d_or_string.h"
#include "third_party/blink/renderer/core/geometry/dom_matrix.h"
-#include "third_party/blink/renderer/core/geometry/dom_matrix_2d_init.h"
#include "third_party/blink/renderer/core/svg/svg_path_utilities.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.idl b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.idl
index ab9862676cb..c9049fc14f0 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.idl
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.idl
@@ -29,10 +29,10 @@
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#path2d
[
- Constructor(optional (Path2D or DOMString) path),
Exposed=(PaintWorklet,Window,Worker)
] interface Path2D {
- [RaisesException] void addPath(Path2D path, optional DOMMatrix2DInit transform);
+ constructor(optional (Path2D or DOMString) path);
+ [RaisesException] void addPath(Path2D path, optional DOMMatrix2DInit transform = {});
};
Path2D includes CanvasPath;
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/testing/internals_canvas_rendering_context_2d.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/testing/internals_canvas_rendering_context_2d.cc
new file mode 100644
index 00000000000..7e2e0c295e4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/testing/internals_canvas_rendering_context_2d.cc
@@ -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.
+
+#include "third_party/blink/renderer/modules/canvas/canvas2d/testing/internals_canvas_rendering_context_2d.h"
+
+#include "third_party/blink/renderer/core/testing/internals.h"
+#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h"
+
+namespace blink {
+
+uint32_t InternalsCanvasRenderingContext2D::countHitRegions(
+ Internals&,
+ CanvasRenderingContext2D* context) {
+ return context->HitRegionsCount();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/testing/internals_canvas_rendering_context_2d.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/testing/internals_canvas_rendering_context_2d.h
new file mode 100644
index 00000000000..180c2ffcdde
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/testing/internals_canvas_rendering_context_2d.h
@@ -0,0 +1,24 @@
+// 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_TESTING_INTERNALS_CANVAS_RENDERING_CONTEXT_2D_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_TESTING_INTERNALS_CANVAS_RENDERING_CONTEXT_2D_H_
+
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+
+namespace blink {
+
+class CanvasRenderingContext2D;
+class Internals;
+
+class InternalsCanvasRenderingContext2D {
+ STATIC_ONLY(InternalsCanvasRenderingContext2D);
+
+ public:
+ static uint32_t countHitRegions(Internals&, CanvasRenderingContext2D*);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_TESTING_INTERNALS_CANVAS_RENDERING_CONTEXT_2D_H_
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/testing/internals_canvas_rendering_context_2d.idl b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/testing/internals_canvas_rendering_context_2d.idl
new file mode 100644
index 00000000000..cbe0cac6524
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/testing/internals_canvas_rendering_context_2d.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.
+
+[
+ ImplementedAs=InternalsCanvasRenderingContext2D
+] partial interface Internals {
+ unsigned long countHitRegions(CanvasRenderingContext2D context);
+};
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas_fuzzer.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas_fuzzer.cc
index fd870c40e1b..0ac852367fd 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas_fuzzer.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas_fuzzer.cc
@@ -44,14 +44,13 @@ class PageHelper {
void SetBodyContentFromFuzzer(const uint8_t* data, size_t size) {
FuzzedDataProvider provider(data, size);
std::string body_content = provider.ConsumeBytesAsString(size);
- GetDocument().documentElement()->SetInnerHTMLFromString(
+ GetDocument().documentElement()->setInnerHTML(
String::FromUTF8(body_content));
UpdateAllLifecyclePhasesForTest();
}
void UpdateAllLifecyclePhasesForTest() {
- GetDocument().View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
GetDocument().View()->RunPostLifecycleSteps();
}
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 a8756b35373..29e9fbb4961 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
@@ -4,8 +4,8 @@
#include "third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.h"
#include "build/build_config.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_canvas_context_creation_attributes_module.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h"
-#include "third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.cc b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.cc
index 3593258deb0..a696431a6d0 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.cc
@@ -4,13 +4,12 @@
#include "third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.h"
+#include "base/metrics/histogram_functions.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_canvas_context_creation_attributes_module.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/canvas/canvas_rendering_context.h"
#include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h"
#include "third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.h"
-#include "third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
namespace blink {
@@ -18,8 +17,8 @@ void HTMLCanvasElementModule::getContext(
HTMLCanvasElement& canvas,
const String& type,
const CanvasContextCreationAttributesModule* attributes,
- ExceptionState& exception_state,
- RenderingContext& result) {
+ RenderingContext& result,
+ ExceptionState& exception_state) {
if (canvas.SurfaceLayerBridge() && !canvas.LowLatencyEnabled()) {
// The existence of canvas surfaceLayerBridge indicates that
// HTMLCanvasElement.transferControlToOffscreen() has been called.
@@ -51,8 +50,8 @@ OffscreenCanvas* HTMLCanvasElementModule::transferControlToOffscreen(
execution_context, canvas, exception_state);
}
- UMA_HISTOGRAM_BOOLEAN("Blink.OffscreenCanvas.TransferControlToOffscreen",
- bool(offscreen_canvas));
+ base::UmaHistogramBoolean("Blink.OffscreenCanvas.TransferControlToOffscreen",
+ !!offscreen_canvas);
return offscreen_canvas;
}
@@ -70,12 +69,6 @@ OffscreenCanvas* HTMLCanvasElementModule::TransferControlToOffscreenInternal(
execution_context, canvas.width(), canvas.height());
offscreen_canvas->SetFilterQuality(canvas.FilterQuality());
- // If this canvas is cross-origin, then the associated offscreen canvas
- // should prefer using the low-power GPU.
- LocalFrame* frame = canvas.GetDocument().GetFrame();
- if (!(frame && frame->IsCrossOriginSubframe()))
- offscreen_canvas->AllowHighPerformancePowerPreference();
-
DOMNodeId canvas_id = DOMNodeIds::IdForNode(&canvas);
canvas.RegisterPlaceholderCanvas(static_cast<int>(canvas_id));
offscreen_canvas->SetPlaceholderCanvasId(canvas_id);
diff --git a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.h b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.h
index 85dff7093da..e8c0e6d202a 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.h
+++ b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.h
@@ -24,8 +24,8 @@ class MODULES_EXPORT HTMLCanvasElementModule {
static void getContext(HTMLCanvasElement&,
const String&,
const CanvasContextCreationAttributesModule*,
- ExceptionState&,
- RenderingContext&);
+ RenderingContext&,
+ ExceptionState&);
static OffscreenCanvas* transferControlToOffscreen(ExecutionContext*,
HTMLCanvasElement&,
ExceptionState&);
diff --git a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_support_webgl2_compute.idl b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_support_webgl2_compute.idl
index 3ca7190541e..8df9faac92a 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_support_webgl2_compute.idl
+++ b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_support_webgl2_compute.idl
@@ -23,6 +23,6 @@ typedef (CanvasRenderingContext2D or
// requires throwing TypeError if the incoming argument is not an object type
// (and is not undefined or null). The binding must ignore this.
// Related spec issue: https://github.com/whatwg/html/issues/595
- [RaisesException] RenderingContext? getContext(DOMString contextId, [PermissiveDictionaryConversion] optional CanvasContextCreationAttributesModule attributes);
+ [RaisesException] RenderingContext? getContext(DOMString contextId, [PermissiveDictionaryConversion] optional CanvasContextCreationAttributesModule attributes = {});
[CallWith=ExecutionContext, RaisesException, MeasureAs=OffscreenCanvas, RuntimeEnabled=SurfaceEmbeddingFeatures] OffscreenCanvas transferControlToOffscreen();
};
diff --git a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc
index 348cd5009df..d20b64e71bf 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc
@@ -60,7 +60,7 @@ class HTMLCanvasElementModuleTest : public ::testing::Test,
protected:
void SetUp() override {
web_view_helper_.Initialize();
- GetDocument().documentElement()->SetInnerHTMLFromString(
+ GetDocument().documentElement()->setInnerHTML(
String::FromUTF8("<body><canvas id='c'></canvas></body>"));
canvas_element_ = To<HTMLCanvasElement>(GetDocument().getElementById("c"));
}
@@ -76,7 +76,7 @@ class HTMLCanvasElementModuleTest : public ::testing::Test,
HTMLCanvasElement& canvas_element() const { return *canvas_element_; }
OffscreenCanvas* TransferControlToOffscreen(ExceptionState& exception_state) {
return HTMLCanvasElementModule::TransferControlToOffscreenInternal(
- &GetDocument(), canvas_element(), exception_state);
+ GetDocument().ToExecutionContext(), canvas_element(), exception_state);
}
frame_test_helpers::WebViewHelper web_view_helper_;
@@ -96,11 +96,8 @@ TEST_F(HTMLCanvasElementModuleTest, TransferControlToOffscreen) {
// Verifies that a desynchronized canvas has the appropriate opacity/blending
// information sent to the CompositorFrameSink.
TEST_P(HTMLCanvasElementModuleTest, LowLatencyCanvasCompositorFrameOpacity) {
-#if defined(OS_MACOSX)
// TODO(crbug.com/922218): enable desynchronized on Mac.
- return;
-#endif
-
+#if !defined(OS_MACOSX)
// This test relies on GpuMemoryBuffers being supported and enabled for low
// latency canvas. The latter is true only on ChromeOS in production.
ScopedTestingPlatformSupport<LowLatencyTestPlatform> platform;
@@ -165,6 +162,7 @@ TEST_P(HTMLCanvasElementModuleTest, LowLatencyCanvasCompositorFrameOpacity) {
platform->RunUntilIdle();
SharedGpuContext::ResetForTesting();
+#endif
}
INSTANTIATE_TEST_SUITE_P(All, HTMLCanvasElementModuleTest, Values(true, false));
diff --git a/chromium/third_party/blink/renderer/modules/canvas/idls.gni b/chromium/third_party/blink/renderer/modules/canvas/idls.gni
new file mode 100644
index 00000000000..bb4d2f14fdf
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/canvas/idls.gni
@@ -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.
+
+import("//third_party/blink/renderer/config.gni")
+
+modules_idl_files = [
+ "canvas2d/canvas_gradient.idl",
+ "canvas2d/canvas_pattern.idl",
+ "canvas2d/canvas_rendering_context_2d.idl",
+ "canvas2d/path_2d.idl",
+ "imagebitmap/image_bitmap_rendering_context.idl",
+ "offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl",
+]
+
+modules_dictionary_idl_files = [
+ "canvas2d/canvas_rendering_context_2d_settings.idl",
+ "canvas2d/hit_region_options.idl",
+ "htmlcanvas/canvas_context_creation_attributes_module.idl",
+]
+
+modules_dependency_idl_files = [ "canvas2d/canvas_path.idl" ]
+
+if (support_webgl2_compute_context) {
+ modules_dependency_idl_files += [
+ "htmlcanvas/html_canvas_element_module_support_webgl2_compute.idl",
+ "offscreencanvas/offscreen_canvas_module_support_webgl2_compute.idl",
+ ]
+} else {
+ modules_dependency_idl_files += [
+ "htmlcanvas/html_canvas_element_module.idl",
+ "offscreencanvas/offscreen_canvas_module.idl",
+ ]
+}
+
+modules_testing_dependency_idl_files =
+ [ "canvas2d/testing/internals_canvas_rendering_context_2d.idl" ]
diff --git a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.cc b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.cc
index 90bcad5e210..d6cd4077d11 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.cc
@@ -52,7 +52,7 @@ ImageBitmap* ImageBitmapRenderingContext::TransferToImageBitmap(ScriptState*) {
return nullptr;
image->Transfer();
- return ImageBitmap::Create(std::move(image));
+ return MakeGarbageCollected<ImageBitmap>(std::move(image));
}
CanvasRenderingContext* ImageBitmapRenderingContext::Factory::Create(
diff --git a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.h b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.h
index 016be9b4c0c..5e0f291de67 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.h
+++ b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.h
@@ -55,14 +55,6 @@ class MODULES_EXPORT ImageBitmapRenderingContext final
~ImageBitmapRenderingContext() override;
};
-DEFINE_TYPE_CASTS(ImageBitmapRenderingContext,
- CanvasRenderingContext,
- context,
- context->GetContextType() ==
- CanvasRenderingContext::kContextImageBitmap,
- context.GetContextType() ==
- CanvasRenderingContext::kContextImageBitmap);
-
} // namespace blink
#endif
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 e149b1aee29..2f2752c5f07 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
@@ -84,7 +84,7 @@ bool ImageBitmapRenderingContextBase::IsPaintable() const {
return !!image_layer_bridge_->GetImage();
}
-void ImageBitmapRenderingContextBase::Trace(blink::Visitor* visitor) {
+void ImageBitmapRenderingContextBase::Trace(Visitor* visitor) {
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 b8524aef4b0..d5d8150fbe6 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// TODO(juanmihd): Remove this method crbug.com/941579
HTMLCanvasElement* canvas() const {
diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.cc b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.cc
index b9646e38983..e365ea77f13 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.cc
@@ -4,10 +4,10 @@
#include "third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_canvas_context_creation_attributes_module.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h"
#include "third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.h"
-#include "third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.h"
#include "third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h"
namespace blink {
@@ -17,8 +17,8 @@ void OffscreenCanvasModule::getContext(
OffscreenCanvas& offscreen_canvas,
const String& id,
const CanvasContextCreationAttributesModule* attributes,
- ExceptionState& exception_state,
- OffscreenRenderingContext& result) {
+ OffscreenRenderingContext& result,
+ ExceptionState& exception_state) {
if (offscreen_canvas.IsNeutered()) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
"OffscreenCanvas object is detached");
diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.h b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.h
index 145092b47af..ba2d44f6f48 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.h
+++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.h
@@ -24,8 +24,8 @@ class MODULES_EXPORT OffscreenCanvasModule {
OffscreenCanvas&,
const String&,
const CanvasContextCreationAttributesModule*,
- ExceptionState&,
- OffscreenRenderingContext&);
+ OffscreenRenderingContext&,
+ ExceptionState&);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module_support_webgl2_compute.idl b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module_support_webgl2_compute.idl
index b98939eb85f..a3728a2af1c 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module_support_webgl2_compute.idl
+++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module_support_webgl2_compute.idl
@@ -14,5 +14,5 @@ enum OffscreenRenderingContextType { "2d", "webgl", "webgl2", "webgl2-compute",
[
ImplementedAs=OffscreenCanvasModule
] partial interface OffscreenCanvas {
- [CallWith=ExecutionContext, RaisesException] OffscreenRenderingContext? getContext(OffscreenRenderingContextType contextType, optional CanvasContextCreationAttributesModule attributes);
+ [CallWith=ExecutionContext, RaisesException] OffscreenRenderingContext? getContext(OffscreenRenderingContextType contextType, optional CanvasContextCreationAttributesModule attributes = {});
};
diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc
index 2b813ccd28d..3c98743511b 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc
@@ -84,7 +84,7 @@ void OffscreenCanvasTest::SetUp() {
web_view_helper_.Initialize();
- GetDocument().documentElement()->SetInnerHTMLFromString(
+ GetDocument().documentElement()->setInnerHTML(
String::FromUTF8("<body><canvas id='c'></canvas></body>"));
auto* canvas_element =
@@ -92,7 +92,7 @@ void OffscreenCanvasTest::SetUp() {
DummyExceptionStateForTesting exception_state;
offscreen_canvas_ = HTMLCanvasElementModule::transferControlToOffscreen(
- &GetDocument(), *canvas_element, exception_state);
+ GetDocument().ToExecutionContext(), *canvas_element, exception_state);
// |offscreen_canvas_| should inherit the FrameSinkId from |canvas_element|s
// SurfaceLayerBridge, but in tests this id is zero; fill it up by hand.
offscreen_canvas_->SetFrameSinkId(kClientId, kSinkId);
@@ -103,8 +103,8 @@ void OffscreenCanvasTest::SetUp() {
attrs.desynchronized = GetParam().desynchronized;
}
context_ = static_cast<OffscreenCanvasRenderingContext2D*>(
- offscreen_canvas_->GetCanvasRenderingContext(&GetDocument(), String("2d"),
- attrs));
+ offscreen_canvas_->GetCanvasRenderingContext(
+ GetDocument().ToExecutionContext(), String("2d"), attrs));
}
void OffscreenCanvasTest::TearDown() {
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 057eab1e0ac..bc2b60c9771 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
@@ -42,15 +42,15 @@ class OffscreenFontCache {
}
}
- void AddFont(String name, blink::Font font) {
+ void AddFont(String name, blink::FontDescription font) {
fonts_resolved_.insert(name, font);
auto add_result = font_lru_list_.PrependOrMoveToFirst(name);
DCHECK(add_result.is_new_entry);
PruneLocalFontCache(kHardMaxCachedFonts);
}
- blink::Font* GetFont(String name) {
- HashMap<String, blink::Font>::iterator i = fonts_resolved_.find(name);
+ blink::FontDescription* GetFont(String name) {
+ auto i = fonts_resolved_.find(name);
if (i != fonts_resolved_.end()) {
auto add_result = font_lru_list_.PrependOrMoveToFirst(name);
DCHECK(!add_result.is_new_entry);
@@ -60,7 +60,7 @@ class OffscreenFontCache {
}
private:
- HashMap<String, blink::Font> fonts_resolved_;
+ HashMap<String, blink::FontDescription> fonts_resolved_;
LinkedHashSet<String> font_lru_list_;
};
@@ -85,20 +85,14 @@ OffscreenCanvasRenderingContext2D::OffscreenCanvasRenderingContext2D(
bernoulli_distribution_(kUMASampleProbability) {
is_valid_size_ = IsValidImageSize(Host()->Size());
- StartRecording();
-
- // Clear the background transparent or opaque. Similar code at
- // CanvasResourceProvider::Clear().
+ // Clear the background transparent or opaque.
if (IsCanvas2DBufferValid()) {
- DCHECK(recorder_);
- recorder_->getRecordingCanvas()->clear(
- ColorParams().GetOpacityMode() == kOpaque ? SK_ColorBLACK
- : SK_ColorTRANSPARENT);
+ GetCanvasResourceProvider()->Clear();
DidDraw();
}
ExecutionContext* execution_context = canvas->GetTopExecutionContext();
- if (auto* document = DynamicTo<Document>(execution_context)) {
+ if (auto* document = Document::DynamicFrom(execution_context)) {
Settings* settings = document->GetSettings();
if (settings && settings->GetDisableReadingFromCanvas())
canvas->SetDisableReadingFromCanvasTrue();
@@ -111,7 +105,7 @@ OffscreenCanvasRenderingContext2D::OffscreenCanvasRenderingContext2D(
canvas->SetDisableReadingFromCanvasTrue();
}
-void OffscreenCanvasRenderingContext2D::Trace(blink::Visitor* visitor) {
+void OffscreenCanvasRenderingContext2D::Trace(Visitor* visitor) {
CanvasRenderingContext::Trace(visitor);
BaseRenderingContext2D::Trace(visitor);
}
@@ -125,31 +119,13 @@ void OffscreenCanvasRenderingContext2D::commit() {
GetOffscreenFontCache().PruneLocalFontCache(kMaxCachedFonts);
}
-void OffscreenCanvasRenderingContext2D::StartRecording() {
- recorder_ = std::make_unique<PaintRecorder>();
-
- cc::PaintCanvas* canvas = recorder_->beginRecording(Width(), Height());
- // Always save an initial frame, to support resetting the top level matrix
- // and clip.
- canvas->save();
-
- RestoreMatrixClipStack(canvas);
-}
-
void OffscreenCanvasRenderingContext2D::FlushRecording() {
- if (!have_recorded_draw_commands_)
+ if (!GetCanvasResourceProvider() ||
+ !GetCanvasResourceProvider()->HasRecordedDrawOps())
return;
- { // Make a new scope so that PaintRecord gets deleted and that gets timed
- CanvasResourceProvider* resource_provider = GetCanvasResourceProvider();
- cc::PaintCanvas* canvas = resource_provider->Canvas();
- canvas->drawPicture(recorder_->finishRecordingAsPicture());
- resource_provider->FlushSkia();
- }
+ GetCanvasResourceProvider()->FlushCanvas();
GetCanvasResourceProvider()->ReleaseLockedImages();
-
- StartRecording();
- have_recorded_draw_commands_ = false;
}
void OffscreenCanvasRenderingContext2D::FinalizeFrame() {
@@ -204,7 +180,6 @@ OffscreenCanvasRenderingContext2D::GetCanvasResourceProvider() const {
void OffscreenCanvasRenderingContext2D::Reset() {
Host()->DiscardResourceProvider();
BaseRenderingContext2D::Reset();
- StartRecording();
// Because the host may have changed to a zero size
is_valid_size_ = IsValidImageSize(Host()->Size());
}
@@ -256,13 +231,9 @@ ImageBitmap* OffscreenCanvasRenderingContext2D::TransferToImageBitmap(
return nullptr;
}
}
-
- // "Transfer" means no retained buffer. Matrix transformations need to be
- // preserved though.
Host()->DiscardResourceProvider();
- RestoreMatrixClipStack(recorder_->getRecordingCanvas());
- return ImageBitmap::Create(std::move(image));
+ return MakeGarbageCollected<ImageBitmap>(std::move(image));
}
scoped_refptr<StaticBitmapImage> OffscreenCanvasRenderingContext2D::GetImage(
@@ -287,29 +258,30 @@ bool OffscreenCanvasRenderingContext2D::ParseColorOrCurrentColor(
return ::blink::ParseColorOrCurrentColor(color, color_string, nullptr);
}
-cc::PaintCanvas* OffscreenCanvasRenderingContext2D::DrawingCanvas() const {
- if (!is_valid_size_)
+cc::PaintCanvas* OffscreenCanvasRenderingContext2D::GetOrCreatePaintCanvas() {
+ if (!is_valid_size_ || !GetOrCreateCanvasResourceProvider())
return nullptr;
- return recorder_->getRecordingCanvas();
+ return GetPaintCanvas();
}
-cc::PaintCanvas* OffscreenCanvasRenderingContext2D::ExistingDrawingCanvas()
- const {
- if (!is_valid_size_)
+cc::PaintCanvas* OffscreenCanvasRenderingContext2D::GetPaintCanvas() const {
+ if (!is_valid_size_ || !GetCanvasResourceProvider())
return nullptr;
- return recorder_->getRecordingCanvas();
+ return GetCanvasResourceProvider()->Canvas();
}
void OffscreenCanvasRenderingContext2D::DidDraw() {
- have_recorded_draw_commands_ = true;
- Host()->DidDraw();
dirty_rect_for_commit_.setWH(Width(), Height());
+ Host()->DidDraw();
+ if (GetCanvasResourceProvider() && GetCanvasResourceProvider()->needs_flush())
+ FinalizeFrame();
}
void OffscreenCanvasRenderingContext2D::DidDraw(const SkIRect& dirty_rect) {
- have_recorded_draw_commands_ = true;
dirty_rect_for_commit_.join(dirty_rect);
Host()->DidDraw(SkRect::Make(dirty_rect_for_commit_));
+ if (GetCanvasResourceProvider() && GetCanvasResourceProvider()->needs_flush())
+ FinalizeFrame();
}
bool OffscreenCanvasRenderingContext2D::StateHasFilter() {
@@ -324,10 +296,11 @@ void OffscreenCanvasRenderingContext2D::SnapshotStateForFilter() {
ModifiableState().SetFontForFilter(AccessFont());
}
-void OffscreenCanvasRenderingContext2D::ValidateStateStack() const {
+void OffscreenCanvasRenderingContext2D::ValidateStateStackWithCanvas(
+ const cc::PaintCanvas* canvas) const {
#if DCHECK_IS_ON()
- if (cc::PaintCanvas* sk_canvas = ExistingDrawingCanvas()) {
- DCHECK_EQ(static_cast<size_t>(sk_canvas->getSaveCount()),
+ if (canvas) {
+ DCHECK_EQ(static_cast<size_t>(canvas->getSaveCount()),
state_stack_.size() + 1);
}
#endif
@@ -364,14 +337,6 @@ bool OffscreenCanvasRenderingContext2D::WritePixels(
DCHECK(IsPaintable());
FinalizeFrame();
- have_recorded_draw_commands_ = false;
- // Add a save to initialize the transform/clip stack and then restore it after
- // the draw. This is needed because each recording initializes and the resets
- // this state after every flush.
- cc::PaintCanvas* canvas = GetCanvasResourceProvider()->Canvas();
- PaintCanvasAutoRestore auto_restore(canvas, true);
- if (GetOrCreateCanvasResourceProvider())
- RestoreMatrixClipStack(canvas);
return offscreenCanvasForBinding()->ResourceProvider()->WritePixels(
orig_info, pixels, row_bytes, x, y);
@@ -381,13 +346,16 @@ bool OffscreenCanvasRenderingContext2D::IsAccelerated() const {
return IsPaintable() && GetCanvasResourceProvider()->IsAccelerated();
}
+void OffscreenCanvasRenderingContext2D::WillOverwriteCanvas() {
+ GetCanvasResourceProvider()->SkipQueuedDrawCommands();
+}
+
String OffscreenCanvasRenderingContext2D::font() const {
if (!GetState().HasRealizedFont())
return kDefaultFont;
StringBuilder serialized_font;
- const FontDescription& font_description =
- GetState().GetFont().GetFontDescription();
+ const FontDescription& font_description = GetState().GetFontDescription();
if (font_description.Style() == ItalicSlopeValue())
serialized_font.Append("italic ");
@@ -427,7 +395,7 @@ void OffscreenCanvasRenderingContext2D::setFont(const String& new_font) {
base::TimeTicks start_time = base::TimeTicks::Now();
OffscreenFontCache& font_cache = GetOffscreenFontCache();
- Font* cached_font = font_cache.GetFont(new_font);
+ FontDescription* cached_font = font_cache.GetFont(new_font);
if (cached_font) {
ModifiableState().SetFont(*cached_font, Host()->GetFontSelector());
} else {
@@ -451,10 +419,8 @@ void OffscreenCanvasRenderingContext2D::setFont(const String& new_font) {
FontDescription desc =
FontStyleResolver::ComputeFont(*style, Host()->GetFontSelector());
- Font font = Font(desc);
-
- font_cache.AddFont(new_font, font);
- ModifiableState().SetFont(font, Host()->GetFontSelector());
+ font_cache.AddFont(new_font, desc);
+ ModifiableState().SetFont(desc, Host()->GetFontSelector());
}
ModifiableState().SetUnparsedFont(new_font);
if (bernoulli_distribution_(random_generator_)) {
@@ -534,8 +500,8 @@ void OffscreenCanvasRenderingContext2D::DrawTextInternal(
double y,
CanvasRenderingContext2DState::PaintType paint_type,
double* max_width) {
- cc::PaintCanvas* c = DrawingCanvas();
- if (!c)
+ cc::PaintCanvas* paint_canvas = GetOrCreatePaintCanvas();
+ if (!paint_canvas)
return;
if (!std::isfinite(x) || !std::isfinite(y))
@@ -591,27 +557,28 @@ void OffscreenCanvasRenderingContext2D::DrawTextInternal(
if (paint_type == CanvasRenderingContext2DState::kStrokePaintType)
InflateStrokeRect(bounds);
- int save_count = c->getSaveCount();
+ int save_count = paint_canvas->getSaveCount();
if (use_max_width) {
- DrawingCanvas()->save();
- DrawingCanvas()->translate(location.X(), location.Y());
+ paint_canvas->save();
+ paint_canvas->translate(location.X(), location.Y());
// We draw when fontWidth is 0 so compositing operations (eg, a "copy" op)
// still work.
- DrawingCanvas()->scale((font_width > 0 ? (width / font_width) : 0), 1);
+ paint_canvas->scale((font_width > 0 ? (width / font_width) : 0), 1);
location = FloatPoint();
}
Draw(
[&font, &text_run_paint_info, &location](
- cc::PaintCanvas* c, const PaintFlags* flags) /* draw lambda */ {
- font.DrawBidiText(c, text_run_paint_info, location,
+ cc::PaintCanvas* paint_canvas,
+ const PaintFlags* flags) /* draw lambda */ {
+ font.DrawBidiText(paint_canvas, text_run_paint_info, location,
Font::kUseFallbackIfFontNotReady, kCDeviceScaleFactor,
*flags);
},
[](const SkIRect& rect) // overdraw test lambda
{ return false; },
bounds, paint_type);
- c->restoreToCount(save_count);
+ paint_canvas->restoreToCount(save_count);
ValidateStateStack();
}
@@ -634,7 +601,7 @@ TextMetrics* OffscreenCanvasRenderingContext2D::measureText(
const Font& OffscreenCanvasRenderingContext2D::AccessFont() {
if (!GetState().HasRealizedFont())
setFont(GetState().UnparsedFont());
- return GetState().GetFont();
+ return ModifiableState().GetFont();
}
bool OffscreenCanvasRenderingContext2D::IsCanvas2DBufferValid() const {
@@ -642,4 +609,5 @@ bool OffscreenCanvasRenderingContext2D::IsCanvas2DBufferValid() const {
return GetCanvasResourceProvider()->IsValid();
return false;
}
+
} // namespace blink
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 5aeed7f7c18..bd98a0a7acf 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,7 +12,6 @@
#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/platform/graphics/paint/paint_recorder.h"
namespace blink {
@@ -100,10 +99,15 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final
CanvasResourceProvider* GetOrCreateCanvasResourceProvider() const;
CanvasResourceProvider* GetCanvasResourceProvider() const;
+ // Offscreen canvas doesn't have any notion of image orientation.
+ RespectImageOrientationEnum RespectImageOrientation() const final {
+ return kRespectImageOrientation;
+ }
+
bool ParseColorOrCurrentColor(Color&, const String& color_string) const final;
- cc::PaintCanvas* DrawingCanvas() const final;
- cc::PaintCanvas* ExistingDrawingCanvas() const final;
+ cc::PaintCanvas* GetOrCreatePaintCanvas() final;
+ cc::PaintCanvas* GetPaintCanvas() const final;
void DidDraw() final;
void DidDraw(const SkIRect& dirty_rect) final;
@@ -112,19 +116,17 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final
sk_sp<PaintFilter> StateGetFilter() final;
void SnapshotStateForFilter() final;
- void ValidateStateStack() const final;
+ void ValidateStateStackWithCanvas(const cc::PaintCanvas*) const final;
bool HasAlpha() const final { return CreationAttributes().alpha; }
bool isContextLost() const override;
ImageBitmap* TransferToImageBitmap(ScriptState*) final;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
bool PushFrame() override;
- bool HasRecordedDrawCommands() { return have_recorded_draw_commands_; }
-
protected:
CanvasColorParams ColorParams() const override;
bool WritePixels(const SkImageInfo& orig_info,
@@ -132,11 +134,9 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final
size_t row_bytes,
int x,
int y) override;
+ void WillOverwriteCanvas() override;
private:
- void StartRecording();
- std::unique_ptr<PaintRecorder> recorder_;
- bool have_recorded_draw_commands_;
void FinalizeFrame() final;
void FlushRecording();
@@ -162,12 +162,6 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final
std::bernoulli_distribution bernoulli_distribution_;
};
-DEFINE_TYPE_CASTS(OffscreenCanvasRenderingContext2D,
- CanvasRenderingContext,
- context,
- context->Is2d() && context->Host(),
- context.Is2d() && context.Host());
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_OFFSCREENCANVAS2D_OFFSCREEN_CANVAS_RENDERING_CONTEXT_2D_H_
diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl
index 6555d4c604c..4371777bcd6 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl
+++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl
@@ -23,7 +23,7 @@
void translate(unrestricted double x, unrestricted double y);
void transform(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f);
void setTransform(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f);
- [RaisesException] void setTransform(optional DOMMatrix2DInit transform);
+ [RaisesException] void setTransform(optional DOMMatrix2DInit transform = {});
DOMMatrix getTransform();
void resetTransform();
diff --git a/chromium/third_party/blink/renderer/modules/clipboard/BUILD.gn b/chromium/third_party/blink/renderer/modules/clipboard/BUILD.gn
index 0b6047879dd..26666e410b4 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/clipboard/BUILD.gn
@@ -19,7 +19,5 @@ blink_modules_sources("clipboard") {
"navigator_clipboard.cc",
"navigator_clipboard.h",
]
- deps = [
- "//third_party/blink/public:blink_headers",
- ]
+ deps = [ "//third_party/blink/public:blink_headers" ]
}
diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard.cc b/chromium/third_party/blink/renderer/modules/clipboard/clipboard.cc
index 6963936310d..60418c17b3b 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard.cc
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard.cc
@@ -6,29 +6,35 @@
#include <utility>
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/clipboard/clipboard_promise.h"
namespace blink {
Clipboard::Clipboard(ExecutionContext* context)
- : ContextLifecycleObserver(context) {}
+ : ExecutionContextClient(context) {
+ DCHECK(context);
+}
ScriptPromise Clipboard::read(ScriptState* script_state) {
- return ClipboardPromise::CreateForRead(script_state);
+ return ClipboardPromise::CreateForRead(GetExecutionContext(), script_state);
}
ScriptPromise Clipboard::readText(ScriptState* script_state) {
- return ClipboardPromise::CreateForReadText(script_state);
+ return ClipboardPromise::CreateForReadText(GetExecutionContext(),
+ script_state);
}
ScriptPromise Clipboard::write(ScriptState* script_state,
const HeapVector<Member<ClipboardItem>>& data) {
- return ClipboardPromise::CreateForWrite(script_state, std::move(data));
+ return ClipboardPromise::CreateForWrite(GetExecutionContext(), script_state,
+ std::move(data));
}
ScriptPromise Clipboard::writeText(ScriptState* script_state,
const String& data) {
- return ClipboardPromise::CreateForWriteText(script_state, data);
+ return ClipboardPromise::CreateForWriteText(GetExecutionContext(),
+ script_state, data);
}
const AtomicString& Clipboard::InterfaceName() const {
@@ -36,12 +42,12 @@ const AtomicString& Clipboard::InterfaceName() const {
}
ExecutionContext* Clipboard::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextClient::GetExecutionContext();
}
-void Clipboard::Trace(blink::Visitor* visitor) {
+void Clipboard::Trace(Visitor* visitor) {
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard.h b/chromium/third_party/blink/renderer/modules/clipboard/clipboard.h
index c74a672639a..d7bdb3bd7e6 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard.h
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard.h
@@ -10,7 +10,7 @@
#include "base/macros.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
#include "third_party/blink/renderer/modules/clipboard/clipboard_item.h"
@@ -19,12 +19,12 @@ namespace blink {
class ScriptState;
class Clipboard : public EventTargetWithInlineData,
- public ContextLifecycleObserver {
+ public ExecutionContextClient {
USING_GARBAGE_COLLECTED_MIXIN(Clipboard);
DEFINE_WRAPPERTYPEINFO();
public:
- explicit Clipboard(ExecutionContext*);
+ explicit Clipboard(ExecutionContext* execution_context);
ScriptPromise read(ScriptState*);
ScriptPromise readText(ScriptState*);
@@ -36,7 +36,7 @@ class Clipboard : public EventTargetWithInlineData,
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
DISALLOW_COPY_AND_ASSIGN(Clipboard);
diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard.idl b/chromium/third_party/blink/renderer/modules/clipboard/clipboard.idl
index ceefcbf8609..0f90bb02756 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard.idl
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard.idl
@@ -9,8 +9,7 @@
Exposed=Window
] interface Clipboard : EventTarget {
[MeasureAs=AsyncClipboardAPIRead,
- CallWith=ScriptState,
- RuntimeEnabled=AsyncClipboard
+ CallWith=ScriptState
] Promise<sequence<ClipboardItem>> read();
[MeasureAs=AsyncClipboardAPIReadText,
@@ -19,8 +18,7 @@
[MeasureAs=AsyncClipboardAPIWrite,
- CallWith=ScriptState,
- RuntimeEnabled=AsyncClipboard
+ CallWith=ScriptState
] Promise<void> write(sequence<ClipboardItem> data);
[MeasureAs=AsyncClipboardAPIWriteText,
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 d032f794c75..b352746a38b 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.cc
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/modules/clipboard/clipboard_item.h"
+#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_clipboard_item_options.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
@@ -13,7 +15,9 @@ namespace blink {
// static
ClipboardItem* ClipboardItem::Create(
const HeapVector<std::pair<String, Member<Blob>>>& items,
+ const ClipboardItemOptions* options,
ExceptionState& exception_state) {
+ DCHECK(options);
// Check that incoming dictionary isn't empty. If it is, it's possible that
// Javascript bindings implicitly converted an Object (like a Blob) into {},
// an empty dictionary.
@@ -21,12 +25,17 @@ ClipboardItem* ClipboardItem::Create(
exception_state.ThrowTypeError("Empty dictionary argument");
return nullptr;
}
- return MakeGarbageCollected<ClipboardItem>(items);
+ return MakeGarbageCollected<ClipboardItem>(items, options);
}
ClipboardItem::ClipboardItem(
- const HeapVector<std::pair<String, Member<Blob>>>& items)
- : items_(items) {}
+ const HeapVector<std::pair<String, Member<Blob>>>& items,
+ const ClipboardItemOptions* options)
+ : items_(items),
+ is_raw_(base::FeatureList::IsEnabled(features::kRawClipboard) &&
+ options->raw()) {
+ DCHECK(items_.size());
+}
Vector<String> ClipboardItem::types() const {
Vector<String> types;
@@ -37,6 +46,10 @@ Vector<String> ClipboardItem::types() const {
return types;
}
+bool ClipboardItem::raw() const {
+ return is_raw_;
+}
+
ScriptPromise ClipboardItem::getType(ScriptState* script_state,
const String& type) const {
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -54,7 +67,7 @@ ScriptPromise ClipboardItem::getType(ScriptState* script_state,
return promise;
}
-void ClipboardItem::Trace(blink::Visitor* visitor) {
+void ClipboardItem::Trace(Visitor* visitor) {
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 10e71ede581..e38ddd84cb0 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.h
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.h
@@ -13,6 +13,7 @@
namespace blink {
class ScriptState;
+class ClipboardItemOptions;
class ClipboardItem final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
@@ -20,20 +21,25 @@ class ClipboardItem final : public ScriptWrappable {
public:
static ClipboardItem* Create(
const HeapVector<std::pair<String, Member<Blob>>>& items,
+ const ClipboardItemOptions* options,
ExceptionState& exception_state);
+
explicit ClipboardItem(
- const HeapVector<std::pair<String, Member<Blob>>>& items);
+ const HeapVector<std::pair<String, Member<Blob>>>& items,
+ const ClipboardItemOptions* options);
Vector<String> types() const;
+ bool raw() const;
ScriptPromise getType(ScriptState* script_state, const String& type) const;
const HeapVector<std::pair<String, Member<Blob>>>& GetItems() const {
return items_;
}
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
HeapVector<std::pair<String, Member<Blob>>> items_;
+ const bool is_raw_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.idl b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.idl
index 63a4e9c6c49..1024f684599 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.idl
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.idl
@@ -5,14 +5,16 @@
// https://w3c.github.io/clipboard-apis/#clipboard-interface
[
- Constructor(record<DOMString, Blob> items),
- RaisesException=Constructor,
- Exposed=Window,
- RuntimeEnabled=AsyncClipboard
+ Exposed=Window
] interface ClipboardItem {
+ [RaisesException] constructor(record<DOMString, Blob> items,
+ optional ClipboardItemOptions options = {});
readonly attribute FrozenArray<DOMString> types;
+ [RuntimeEnabled=RawClipboard]
+ readonly attribute boolean raw;
+
[
CallWith=ScriptState
] Promise<Blob> getType(DOMString type);
-}; \ No newline at end of file
+};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_extensions.idl b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item_options.idl
index a96d92f4f99..eefa3ed4c54 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_extensions.idl
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item_options.idl
@@ -2,8 +2,8 @@
// 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/
+// https://w3c.github.io/clipboard-apis/#clipboard-interface
-dictionary GPUExtensions {
- boolean textureCompressionBC = false;
-};
+dictionary ClipboardItemOptions {
+ boolean raw = false;
+}; \ No newline at end of file
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 a7791bfb840..47bd085c92f 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
@@ -9,9 +9,13 @@
#include "base/single_thread_task_runner.h"
#include "base/task/post_task.h"
+#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_clipboard_item_options.h"
#include "third_party/blink/renderer/core/clipboard/clipboard_mime_types.h"
+#include "third_party/blink/renderer/core/clipboard/raw_system_clipboard.h"
#include "third_party/blink/renderer/core/clipboard/system_clipboard.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
@@ -28,9 +32,9 @@
// * clipboard-write
// See https://w3c.github.io/clipboard-apis/#clipboard-permissions
//
-// Write access is granted by default, whereas read access is gated behind a
-// permission prompt. Both read and write require the tab to be focused (and
-// Chrome must be the foreground app) for the operation to be allowed.
+// These permissions map to these ContentSettings:
+// * CLIPBOARD_READ_WRITE, for sanitized read, and unsanitized read/write.
+// * CLIPBOARD_SANITIZED_WRITE, for sanitized write only.
namespace blink {
@@ -38,9 +42,12 @@ using mojom::blink::PermissionStatus;
using mojom::blink::PermissionService;
// static
-ScriptPromise ClipboardPromise::CreateForRead(ScriptState* script_state) {
+ScriptPromise ClipboardPromise::CreateForRead(ExecutionContext* context,
+ ScriptState* script_state) {
+ if (!script_state->ContextIsValid())
+ return ScriptPromise();
ClipboardPromise* clipboard_promise =
- MakeGarbageCollected<ClipboardPromise>(script_state);
+ MakeGarbageCollected<ClipboardPromise>(context, script_state);
clipboard_promise->GetTaskRunner()->PostTask(
FROM_HERE, WTF::Bind(&ClipboardPromise::HandleRead,
WrapPersistent(clipboard_promise)));
@@ -48,9 +55,12 @@ ScriptPromise ClipboardPromise::CreateForRead(ScriptState* script_state) {
}
// static
-ScriptPromise ClipboardPromise::CreateForReadText(ScriptState* script_state) {
+ScriptPromise ClipboardPromise::CreateForReadText(ExecutionContext* context,
+ ScriptState* script_state) {
+ if (!script_state->ContextIsValid())
+ return ScriptPromise();
ClipboardPromise* clipboard_promise =
- MakeGarbageCollected<ClipboardPromise>(script_state);
+ MakeGarbageCollected<ClipboardPromise>(context, script_state);
clipboard_promise->GetTaskRunner()->PostTask(
FROM_HERE, WTF::Bind(&ClipboardPromise::HandleReadText,
WrapPersistent(clipboard_promise)));
@@ -59,10 +69,13 @@ ScriptPromise ClipboardPromise::CreateForReadText(ScriptState* script_state) {
// static
ScriptPromise ClipboardPromise::CreateForWrite(
+ ExecutionContext* context,
ScriptState* script_state,
const HeapVector<Member<ClipboardItem>>& items) {
+ if (!script_state->ContextIsValid())
+ return ScriptPromise();
ClipboardPromise* clipboard_promise =
- MakeGarbageCollected<ClipboardPromise>(script_state);
+ MakeGarbageCollected<ClipboardPromise>(context, script_state);
HeapVector<Member<ClipboardItem>>* items_copy =
MakeGarbageCollected<HeapVector<Member<ClipboardItem>>>(items);
clipboard_promise->GetTaskRunner()->PostTask(
@@ -73,18 +86,22 @@ ScriptPromise ClipboardPromise::CreateForWrite(
}
// static
-ScriptPromise ClipboardPromise::CreateForWriteText(ScriptState* script_state,
+ScriptPromise ClipboardPromise::CreateForWriteText(ExecutionContext* context,
+ ScriptState* script_state,
const String& data) {
+ if (!script_state->ContextIsValid())
+ return ScriptPromise();
ClipboardPromise* clipboard_promise =
- MakeGarbageCollected<ClipboardPromise>(script_state);
+ MakeGarbageCollected<ClipboardPromise>(context, script_state);
clipboard_promise->GetTaskRunner()->PostTask(
FROM_HERE, WTF::Bind(&ClipboardPromise::HandleWriteText,
WrapPersistent(clipboard_promise), data));
return clipboard_promise->script_promise_resolver_->Promise();
}
-ClipboardPromise::ClipboardPromise(ScriptState* script_state)
- : ContextLifecycleObserver(blink::ExecutionContext::From(script_state)),
+ClipboardPromise::ClipboardPromise(ExecutionContext* context,
+ ScriptState* script_state)
+ : ExecutionContextClient(context),
script_state_(script_state),
script_promise_resolver_(
MakeGarbageCollected<ScriptPromiseResolver>(script_state)),
@@ -94,18 +111,24 @@ ClipboardPromise::~ClipboardPromise() = default;
void ClipboardPromise::CompleteWriteRepresentation() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- clipboard_writer_.reset(); // The previous write is done.
+ clipboard_writer_.Clear(); // The previous write is done.
++clipboard_representation_index_;
StartWriteRepresentation();
}
void ClipboardPromise::StartWriteRepresentation() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!GetExecutionContext())
+ return;
+ LocalFrame* local_frame = GetLocalFrame();
// Commit to system clipboard when all representations are written.
// This is in the start flow so that a |clipboard_item_data_| with 0 items
// will still commit gracefully.
if (clipboard_representation_index_ == clipboard_item_data_.size()) {
- SystemClipboard::GetInstance().CommitWrite();
+ if (is_raw_)
+ local_frame->GetRawSystemClipboard()->CommitWrite();
+ else
+ local_frame->GetSystemClipboard()->CommitWrite();
script_promise_resolver_->Resolve();
return;
}
@@ -115,12 +138,21 @@ void ClipboardPromise::StartWriteRepresentation() {
clipboard_item_data_[clipboard_representation_index_].second;
DCHECK(!clipboard_writer_);
- clipboard_writer_ = ClipboardWriter::Create(type, this);
+ if (is_raw_) {
+ clipboard_writer_ = ClipboardWriter::Create(
+ local_frame->GetRawSystemClipboard(), type, this);
+ } else {
+ clipboard_writer_ =
+ ClipboardWriter::Create(local_frame->GetSystemClipboard(), type, this);
+ }
+
clipboard_writer_->WriteToSystem(blob);
}
void ClipboardPromise::RejectFromReadOrDecodeFailure() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!GetExecutionContext())
+ return;
script_promise_resolver_->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kDataError,
"Failed to read or decode Blob for clipboard item type " +
@@ -129,14 +161,14 @@ void ClipboardPromise::RejectFromReadOrDecodeFailure() {
void ClipboardPromise::HandleRead() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- RequestPermission(mojom::blink::PermissionName::CLIPBOARD_READ,
+ RequestPermission(mojom::blink::PermissionName::CLIPBOARD_READ, false,
WTF::Bind(&ClipboardPromise::HandleReadWithPermission,
WrapPersistent(this)));
}
void ClipboardPromise::HandleReadText() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- RequestPermission(mojom::blink::PermissionName::CLIPBOARD_READ,
+ RequestPermission(mojom::blink::PermissionName::CLIPBOARD_READ, false,
WTF::Bind(&ClipboardPromise::HandleReadTextWithPermission,
WrapPersistent(this)));
}
@@ -145,6 +177,8 @@ void ClipboardPromise::HandleWrite(
HeapVector<Member<ClipboardItem>>* clipboard_items) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(clipboard_items);
+ if (!GetExecutionContext())
+ return;
if (clipboard_items->size() > 1) {
script_promise_resolver_->Reject(MakeGarbageCollected<DOMException>(
@@ -161,8 +195,11 @@ void ClipboardPromise::HandleWrite(
// For now, we only process the first ClipboardItem.
ClipboardItem* clipboard_item = (*clipboard_items)[0];
clipboard_item_data_ = clipboard_item->GetItems();
+ is_raw_ = clipboard_item->raw();
+
+ DCHECK(base::FeatureList::IsEnabled(features::kRawClipboard) || !is_raw_);
- RequestPermission(mojom::blink::PermissionName::CLIPBOARD_WRITE,
+ RequestPermission(mojom::blink::PermissionName::CLIPBOARD_WRITE, is_raw_,
WTF::Bind(&ClipboardPromise::HandleWriteWithPermission,
WrapPersistent(this)));
}
@@ -170,26 +207,28 @@ void ClipboardPromise::HandleWrite(
void ClipboardPromise::HandleWriteText(const String& data) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
plain_text_ = data;
- RequestPermission(mojom::blink::PermissionName::CLIPBOARD_WRITE,
+ RequestPermission(mojom::blink::PermissionName::CLIPBOARD_WRITE, false,
WTF::Bind(&ClipboardPromise::HandleWriteTextWithPermission,
WrapPersistent(this)));
}
void ClipboardPromise::HandleReadWithPermission(PermissionStatus status) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!GetExecutionContext())
+ return;
if (status != PermissionStatus::GRANTED) {
script_promise_resolver_->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kNotAllowedError, "Read permission denied."));
return;
}
- Vector<String> available_types =
- SystemClipboard::GetInstance().ReadAvailableTypes();
+ SystemClipboard* system_clipboard = GetLocalFrame()->GetSystemClipboard();
+ Vector<String> available_types = system_clipboard->ReadAvailableTypes();
HeapVector<std::pair<String, Member<Blob>>> items;
items.ReserveInitialCapacity(available_types.size());
for (String& type_to_read : available_types) {
- std::unique_ptr<ClipboardReader> reader =
- ClipboardReader::Create(type_to_read);
+ ClipboardReader* reader =
+ ClipboardReader::Create(system_clipboard, type_to_read);
if (reader)
items.emplace_back(std::move(type_to_read), reader->ReadFromSystem());
}
@@ -200,25 +239,33 @@ void ClipboardPromise::HandleReadWithPermission(PermissionStatus status) {
return;
}
+ ClipboardItemOptions* options = ClipboardItemOptions::Create();
+ options->setRaw(false);
+
HeapVector<Member<ClipboardItem>> clipboard_items = {
- MakeGarbageCollected<ClipboardItem>(items)};
+ MakeGarbageCollected<ClipboardItem>(items, options)};
script_promise_resolver_->Resolve(clipboard_items);
}
void ClipboardPromise::HandleReadTextWithPermission(PermissionStatus status) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!GetExecutionContext())
+ return;
if (status != PermissionStatus::GRANTED) {
script_promise_resolver_->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kNotAllowedError, "Read permission denied."));
return;
}
- String text = SystemClipboard::GetInstance().ReadPlainText(
- mojom::ClipboardBuffer::kStandard);
+ String text = GetLocalFrame()->GetSystemClipboard()->ReadPlainText(
+ mojom::blink::ClipboardBuffer::kStandard);
script_promise_resolver_->Resolve(text);
}
void ClipboardPromise::HandleWriteWithPermission(PermissionStatus status) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!GetExecutionContext())
+ return;
if (status != PermissionStatus::GRANTED) {
script_promise_resolver_->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kNotAllowedError, "Write permission denied."));
@@ -232,10 +279,10 @@ void ClipboardPromise::HandleWriteWithPermission(PermissionStatus status) {
for (const auto& type_and_blob : clipboard_item_data_) {
String type = type_and_blob.first;
String type_with_args = type_and_blob.second->type();
- if (!ClipboardWriter::IsValidType(type)) {
+ if (!is_raw_ && !ClipboardWriter::IsValidType(type)) {
script_promise_resolver_->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kNotAllowedError,
- "Write type " + type + " not supported."));
+ "Sanitized MIME type " + type + " not supported on write."));
return;
}
if (!type_with_args.Contains(type)) {
@@ -253,38 +300,44 @@ void ClipboardPromise::HandleWriteWithPermission(PermissionStatus status) {
void ClipboardPromise::HandleWriteTextWithPermission(PermissionStatus status) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!GetExecutionContext())
+ return;
if (status != PermissionStatus::GRANTED) {
script_promise_resolver_->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kNotAllowedError, "Write permission denied."));
return;
}
- SystemClipboard::GetInstance().WritePlainText(plain_text_);
- SystemClipboard::GetInstance().CommitWrite();
+ SystemClipboard* system_clipboard = GetLocalFrame()->GetSystemClipboard();
+ system_clipboard->WritePlainText(plain_text_);
+ system_clipboard->CommitWrite();
script_promise_resolver_->Resolve();
}
PermissionService* ClipboardPromise::GetPermissionService() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ ExecutionContext* context = GetExecutionContext();
+ DCHECK(context);
if (!permission_service_) {
ConnectToPermissionService(
- ExecutionContext::From(script_state_),
- permission_service_.BindNewPipeAndPassReceiver());
+ context, permission_service_.BindNewPipeAndPassReceiver());
}
return permission_service_.get();
}
void ClipboardPromise::RequestPermission(
mojom::blink::PermissionName permission,
+ bool allow_without_sanitization,
base::OnceCallback<void(::blink::mojom::PermissionStatus)> callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(script_promise_resolver_);
DCHECK(permission == mojom::blink::PermissionName::CLIPBOARD_READ ||
permission == mojom::blink::PermissionName::CLIPBOARD_WRITE);
- ExecutionContext* context = ExecutionContext::From(script_state_);
- DCHECK(context);
- const Document& document = *To<Document>(context);
+ ExecutionContext* context = GetExecutionContext();
+ if (!context)
+ return;
+ const Document& document = *Document::From(context);
DCHECK(document.IsSecureContext()); // [SecureContext] in IDL
if (!document.hasFocus()) {
@@ -292,6 +345,19 @@ void ClipboardPromise::RequestPermission(
DOMExceptionCode::kNotAllowedError, "Document is not focused."));
return;
}
+
+ if (!document.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.")) {
+ script_promise_resolver_->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kNotAllowedError,
+ "Disabled in this document by Feature Policy."));
+ return;
+ }
+
if (!GetPermissionService()) {
script_promise_resolver_->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kNotAllowedError,
@@ -299,9 +365,10 @@ void ClipboardPromise::RequestPermission(
return;
}
- auto permission_descriptor =
- CreateClipboardPermissionDescriptor(permission, false);
- if (permission == mojom::blink::PermissionName::CLIPBOARD_WRITE) {
+ auto permission_descriptor = CreateClipboardPermissionDescriptor(
+ permission, false, allow_without_sanitization);
+ if (permission == mojom::blink::PermissionName::CLIPBOARD_WRITE &&
+ !allow_without_sanitization) {
// Check permission (but do not query the user).
// See crbug.com/795929 for moving this check into the Browser process.
permission_service_->HasPermission(std::move(permission_descriptor),
@@ -314,6 +381,14 @@ void ClipboardPromise::RequestPermission(
false, std::move(callback));
}
+LocalFrame* ClipboardPromise::GetLocalFrame() const {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ ExecutionContext* context = GetExecutionContext();
+ DCHECK(context);
+ LocalFrame* local_frame = Document::From(context)->GetFrame();
+ return local_frame;
+}
+
scoped_refptr<base::SingleThreadTaskRunner> ClipboardPromise::GetTaskRunner() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// Get the User Interaction task runner, as Async Clipboard API calls require
@@ -321,11 +396,12 @@ scoped_refptr<base::SingleThreadTaskRunner> ClipboardPromise::GetTaskRunner() {
return GetExecutionContext()->GetTaskRunner(TaskType::kUserInteraction);
}
-void ClipboardPromise::Trace(blink::Visitor* visitor) {
+void ClipboardPromise::Trace(Visitor* visitor) {
visitor->Trace(script_state_);
visitor->Trace(script_promise_resolver_);
+ visitor->Trace(clipboard_writer_);
visitor->Trace(clipboard_item_data_);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 842d17d0a57..c2c72861492 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
@@ -12,7 +12,7 @@
#include "mojo/public/cpp/bindings/remote.h"
#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/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
#include "third_party/blink/renderer/modules/clipboard/clipboard_item.h"
#include "third_party/blink/renderer/modules/clipboard/clipboard_writer.h"
@@ -20,20 +20,25 @@
namespace blink {
class ScriptPromiseResolver;
+class LocalFrame;
+class ExecutionContext;
class ClipboardPromise final : public GarbageCollected<ClipboardPromise>,
- public ContextLifecycleObserver {
+ public ExecutionContextClient {
USING_GARBAGE_COLLECTED_MIXIN(ClipboardPromise);
public:
// Creates promise to execute Clipboard API functions off the main thread.
- static ScriptPromise CreateForRead(ScriptState*);
- static ScriptPromise CreateForReadText(ScriptState*);
- static ScriptPromise CreateForWrite(ScriptState*,
+ static ScriptPromise CreateForRead(ExecutionContext*, ScriptState*);
+ static ScriptPromise CreateForReadText(ExecutionContext*, ScriptState*);
+ static ScriptPromise CreateForWrite(ExecutionContext*,
+ ScriptState*,
const HeapVector<Member<ClipboardItem>>&);
- static ScriptPromise CreateForWriteText(ScriptState*, const String&);
+ static ScriptPromise CreateForWriteText(ExecutionContext*,
+ ScriptState*,
+ const String&);
- explicit ClipboardPromise(ScriptState*);
+ ClipboardPromise(ExecutionContext*, ScriptState*);
virtual ~ClipboardPromise();
// Completes current write and starts next write.
@@ -41,7 +46,7 @@ class ClipboardPromise final : public GarbageCollected<ClipboardPromise>,
// For rejections originating from ClipboardWriter.
void RejectFromReadOrDecodeFailure();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
// Called to begin writing a type.
@@ -63,20 +68,23 @@ class ClipboardPromise final : public GarbageCollected<ClipboardPromise>,
mojom::blink::PermissionService* GetPermissionService();
void RequestPermission(
mojom::blink::PermissionName permission,
+ bool allow_without_sanitization,
base::OnceCallback<void(::blink::mojom::PermissionStatus)> callback);
+ LocalFrame* GetLocalFrame() const;
scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner();
Member<ScriptState> script_state_;
Member<ScriptPromiseResolver> script_promise_resolver_;
- std::unique_ptr<ClipboardWriter> clipboard_writer_;
+ Member<ClipboardWriter> clipboard_writer_;
// Checks for Read and Write permission.
mojo::Remote<mojom::blink::PermissionService> permission_service_;
// Only for use in writeText().
String plain_text_;
HeapVector<std::pair<String, Member<Blob>>> clipboard_item_data_;
+ bool is_raw_; // Corresponds to allowWithoutSanitization in ClipboardItem.
// Index of clipboard representation currently being processed.
wtf_size_t clipboard_representation_index_;
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 496ad215663..0d115febf2b 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc
@@ -20,12 +20,13 @@ namespace { // anonymous namespace for ClipboardReader's derived classes.
// Reads an image from the System Clipboard as a blob with image/png content.
class ClipboardImageReader final : public ClipboardReader {
public:
- ClipboardImageReader() = default;
+ ClipboardImageReader(SystemClipboard* system_clipboard)
+ : ClipboardReader(system_clipboard) {}
~ClipboardImageReader() override = default;
Blob* ReadFromSystem() override {
- SkBitmap bitmap = SystemClipboard::GetInstance().ReadImage(
- mojom::ClipboardBuffer::kStandard);
+ SkBitmap bitmap =
+ system_clipboard()->ReadImage(mojom::ClipboardBuffer::kStandard);
// Encode bitmap to Vector<uint8_t> on the main thread.
SkPixmap pixmap;
@@ -47,12 +48,13 @@ class ClipboardImageReader final : public ClipboardReader {
// Reads an image from the System Clipboard as a blob with text/plain content.
class ClipboardTextReader final : public ClipboardReader {
public:
- ClipboardTextReader() = default;
+ ClipboardTextReader(SystemClipboard* system_clipboard)
+ : ClipboardReader(system_clipboard) {}
~ClipboardTextReader() override = default;
Blob* ReadFromSystem() override {
- String plain_text = SystemClipboard::GetInstance().ReadPlainText(
- mojom::ClipboardBuffer::kStandard);
+ String plain_text =
+ system_clipboard()->ReadPlainText(mojom::ClipboardBuffer::kStandard);
// Encode WTF String to UTF-8, the standard text format for blobs.
StringUTF8Adaptor utf_text(plain_text);
@@ -66,18 +68,24 @@ class ClipboardTextReader final : public ClipboardReader {
// ClipboardReader functions.
// static
-std::unique_ptr<ClipboardReader> ClipboardReader::Create(
- const String& mime_type) {
+ClipboardReader* ClipboardReader::Create(SystemClipboard* system_clipboard,
+ const String& mime_type) {
if (mime_type == kMimeTypeImagePng)
- return std::make_unique<ClipboardImageReader>();
+ return MakeGarbageCollected<ClipboardImageReader>(system_clipboard);
if (mime_type == kMimeTypeTextPlain)
- return std::make_unique<ClipboardTextReader>();
+ return MakeGarbageCollected<ClipboardTextReader>(system_clipboard);
// The MIME type is not supported.
return nullptr;
}
-ClipboardReader::ClipboardReader() = default;
+ClipboardReader::ClipboardReader(SystemClipboard* system_clipboard)
+ : system_clipboard_(system_clipboard) {}
+
ClipboardReader::~ClipboardReader() = default;
+void ClipboardReader::Trace(Visitor* visitor) {
+ visitor->Trace(system_clipboard_);
+}
+
} // namespace blink
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 8e53077714e..7e57c105463 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.h
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.h
@@ -6,9 +6,12 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_CLIPBOARD_CLIPBOARD_READER_H_
#include "third_party/blink/renderer/core/fileapi/blob.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
+class SystemClipboard;
+
// Interface for reading async-clipboard-compatible types from the System
// Clipboard as a Blob.
//
@@ -16,15 +19,24 @@ namespace blink {
// (1) Reading the item from the system clipboard.
// (2) Encoding the blob's contents.
// (3) Writing the contents to a blob.
-class ClipboardReader {
+class ClipboardReader : public GarbageCollected<ClipboardReader> {
public:
- static std::unique_ptr<ClipboardReader> Create(const String& mime_type);
+ static ClipboardReader* Create(SystemClipboard* system_clipboard,
+ const String& mime_type);
virtual ~ClipboardReader();
virtual Blob* ReadFromSystem() = 0;
+ void Trace(Visitor* visitor);
+
protected:
- ClipboardReader();
+ explicit ClipboardReader(SystemClipboard* system_clipboard);
+
+ SystemClipboard* system_clipboard() { return system_clipboard_; }
+
+ private:
+ // Access to the global system clipboard.
+ Member<SystemClipboard> system_clipboard_;
};
} // namespace blink
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 6244ac50ecd..625934d39c6 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
@@ -4,8 +4,10 @@
#include "third_party/blink/renderer/modules/clipboard/clipboard_writer.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/clipboard/clipboard.mojom-blink.h"
#include "third_party/blink/renderer/core/clipboard/clipboard_mime_types.h"
+#include "third_party/blink/renderer/core/clipboard/raw_system_clipboard.h"
#include "third_party/blink/renderer/core/clipboard/system_clipboard.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/fileapi/file_reader_loader.h"
@@ -24,7 +26,9 @@ namespace { // anonymous namespace for ClipboardWriter's derived classes.
// Writes a blob with image/png content to the System Clipboard.
class ClipboardImageWriter final : public ClipboardWriter {
public:
- ClipboardImageWriter(ClipboardPromise* promise) : ClipboardWriter(promise) {}
+ ClipboardImageWriter(SystemClipboard* system_clipboard,
+ ClipboardPromise* promise)
+ : ClipboardWriter(system_clipboard, promise) {}
~ClipboardImageWriter() override = default;
private:
@@ -36,7 +40,7 @@ class ClipboardImageWriter final : public ClipboardWriter {
SegmentReader::CreateFromSkData(SkData::MakeWithoutCopy(
png_data->Data(), png_data->ByteLengthAsSizeT())),
true, ImageDecoder::kAlphaPremultiplied, ImageDecoder::kDefaultBitDepth,
- ColorBehavior::Tag());
+ ColorBehavior::Tag(), ImageDecoder::OverrideAllowDecodeToYuv::kDeny);
sk_sp<SkImage> image = nullptr;
// |decoder| is nullptr if |png_data| doesn't begin with the PNG signature.
if (decoder)
@@ -44,11 +48,8 @@ class ClipboardImageWriter final : public ClipboardWriter {
PostCrossThreadTask(
*task_runner, FROM_HERE,
- CrossThreadBindOnce(
- &ClipboardImageWriter::Write,
- /* This unretained is safe because the ClipboardImageWriter must
- remain alive when returning to its main thread. */
- CrossThreadUnretained(this), std::move(image)));
+ CrossThreadBindOnce(&ClipboardImageWriter::Write,
+ WrapCrossThreadPersistent(this), std::move(image)));
}
void Write(sk_sp<SkImage> image) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -58,7 +59,7 @@ class ClipboardImageWriter final : public ClipboardWriter {
}
SkBitmap bitmap;
image->asLegacyBitmap(&bitmap);
- SystemClipboard::GetInstance().WriteImage(std::move(bitmap));
+ system_clipboard()->WriteImage(std::move(bitmap));
promise_->CompleteWriteRepresentation();
}
};
@@ -66,7 +67,9 @@ class ClipboardImageWriter final : public ClipboardWriter {
// Writes a blob with text/plain content to the System Clipboard.
class ClipboardTextWriter final : public ClipboardWriter {
public:
- ClipboardTextWriter(ClipboardPromise* promise) : ClipboardWriter(promise) {}
+ ClipboardTextWriter(SystemClipboard* system_clipboard,
+ ClipboardPromise* promise)
+ : ClipboardWriter(system_clipboard, promise) {}
~ClipboardTextWriter() override = default;
private:
@@ -79,20 +82,56 @@ class ClipboardTextWriter final : public ClipboardWriter {
String::FromUTF8(reinterpret_cast<const LChar*>(raw_data->Data()),
raw_data->ByteLengthAsSizeT());
DCHECK(wtf_string.IsSafeToSendToAnotherThread());
+ PostCrossThreadTask(*task_runner, FROM_HERE,
+ CrossThreadBindOnce(&ClipboardTextWriter::Write,
+ WrapCrossThreadPersistent(this),
+ std::move(wtf_string)));
+ }
+ void Write(const String& text) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ system_clipboard()->WritePlainText(text);
+
+ promise_->CompleteWriteRepresentation();
+ }
+};
+
+// Writes a blob with arbitrary, unsanitized content to the System Clipboard.
+class ClipboardRawDataWriter final : public ClipboardWriter {
+ public:
+ ClipboardRawDataWriter(RawSystemClipboard* raw_system_clipboard,
+ ClipboardPromise* promise,
+ String mime_type)
+ : ClipboardWriter(raw_system_clipboard, promise), mime_type_(mime_type) {}
+ ~ClipboardRawDataWriter() override = default;
+
+ private:
+ // Unfortunately, in order to use the same ClipboardWriter base,
+ // ClipboardRawDataWriter does need to have these extra 2 thread hops.
+ void DecodeOnBackgroundThread(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ DOMArrayBuffer* raw_data) override {
+ DCHECK(!IsMainThread());
+
PostCrossThreadTask(
*task_runner, FROM_HERE,
- CrossThreadBindOnce(
- &ClipboardTextWriter::Write,
- /* This unretained is safe because the ClipboardTextWriter
- must remain alive when returning to its main thread. */
- CrossThreadUnretained(this), std::move(wtf_string)));
+ CrossThreadBindOnce(&ClipboardRawDataWriter::Write,
+ WrapCrossThreadPersistent(this),
+ WrapCrossThreadPersistent(raw_data)));
}
- void Write(const String& text) {
+
+ void Write(DOMArrayBuffer* raw_data) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- SystemClipboard::GetInstance().WritePlainText(text);
+
+ uint8_t* raw_data_pointer = static_cast<uint8_t*>(raw_data->Data());
+ mojo_base::BigBuffer buffer(std::vector<uint8_t>(
+ raw_data_pointer, raw_data_pointer + raw_data->ByteLengthAsSizeT()));
+
+ raw_system_clipboard()->Write(mime_type_, std::move(buffer));
promise_->CompleteWriteRepresentation();
}
+
+ String mime_type_;
};
} // anonymous namespace
@@ -100,24 +139,49 @@ class ClipboardTextWriter final : public ClipboardWriter {
// ClipboardWriter functions.
// static
-std::unique_ptr<ClipboardWriter> ClipboardWriter::Create(
- const String& mime_type,
- ClipboardPromise* promise) {
- if (mime_type == kMimeTypeImagePng)
- return std::make_unique<ClipboardImageWriter>(promise);
+ClipboardWriter* ClipboardWriter::Create(SystemClipboard* system_clipboard,
+ const String& mime_type,
+ ClipboardPromise* promise) {
+ if (mime_type == kMimeTypeImagePng) {
+ return MakeGarbageCollected<ClipboardImageWriter>(system_clipboard,
+ promise);
+ }
if (mime_type == kMimeTypeTextPlain)
- return std::make_unique<ClipboardTextWriter>(promise);
+ return MakeGarbageCollected<ClipboardTextWriter>(system_clipboard, promise);
NOTREACHED() << "Type " << mime_type << " was not implemented";
return nullptr;
}
-ClipboardWriter::ClipboardWriter(ClipboardPromise* promise)
+// static
+ClipboardWriter* ClipboardWriter::Create(
+ RawSystemClipboard* raw_system_clipboard,
+ const String& mime_type,
+ ClipboardPromise* promise) {
+ DCHECK(base::FeatureList::IsEnabled(features::kRawClipboard));
+
+ return MakeGarbageCollected<ClipboardRawDataWriter>(raw_system_clipboard,
+ promise, mime_type);
+}
+
+ClipboardWriter::ClipboardWriter(SystemClipboard* system_clipboard,
+ ClipboardPromise* promise)
+ : ClipboardWriter(system_clipboard, nullptr, promise) {}
+
+ClipboardWriter::ClipboardWriter(RawSystemClipboard* raw_system_clipboard,
+ ClipboardPromise* promise)
+ : ClipboardWriter(nullptr, raw_system_clipboard, promise) {}
+
+ClipboardWriter::ClipboardWriter(SystemClipboard* system_clipboard,
+ RawSystemClipboard* raw_system_clipboard,
+ ClipboardPromise* promise)
: promise_(promise),
clipboard_task_runner_(promise->GetExecutionContext()->GetTaskRunner(
TaskType::kUserInteraction)),
file_reading_task_runner_(promise->GetExecutionContext()->GetTaskRunner(
- TaskType::kFileReading)) {}
+ TaskType::kFileReading)),
+ system_clipboard_(system_clipboard),
+ raw_system_clipboard_(raw_system_clipboard) {}
ClipboardWriter::~ClipboardWriter() = default;
@@ -148,17 +212,20 @@ void ClipboardWriter::DidFinishLoading() {
file_reader_.reset();
worker_pool::PostTask(
- FROM_HERE,
- CrossThreadBindOnce(&ClipboardWriter::DecodeOnBackgroundThread,
- /* This unretained is safe because the ClipboardWriter
- will wait for Decode to finish and return back to
- this thread before deallocating. */
- CrossThreadUnretained(this), clipboard_task_runner_,
- WrapCrossThreadPersistent(array_buffer)));
+ FROM_HERE, CrossThreadBindOnce(&ClipboardWriter::DecodeOnBackgroundThread,
+ WrapCrossThreadPersistent(this),
+ clipboard_task_runner_,
+ WrapCrossThreadPersistent(array_buffer)));
}
void ClipboardWriter::DidFail(FileErrorCode error_code) {
promise_->RejectFromReadOrDecodeFailure();
}
+void ClipboardWriter::Trace(Visitor* visitor) {
+ visitor->Trace(promise_);
+ visitor->Trace(system_clipboard_);
+ visitor->Trace(raw_system_clipboard_);
+}
+
} // namespace blink
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 475e182b4cc..45eb4bd91c0 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.h
+++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.h
@@ -6,14 +6,18 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_CLIPBOARD_CLIPBOARD_WRITER_H_
#include "base/sequence_checker.h"
+#include "third_party/blink/renderer/core/clipboard/raw_system_clipboard.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
#include "third_party/blink/renderer/core/fileapi/file_reader_loader_client.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/skia/include/core/SkImage.h"
namespace blink {
class ClipboardPromise;
class FileReaderLoader;
+class SystemClipboard;
+class RawSystemClipboard;
// Interface for writing async-clipboard-compatible types as a Blob to the
// System Clipboard, asynchronously.
@@ -23,10 +27,16 @@ class FileReaderLoader;
// (2) Decoding the blob's contents to avoid RCE in native applications that may
// take advantage of vulnerabilities in their decoders.
// (3) Writing the blob's decoded contents to the system clipboard.
-class ClipboardWriter : public FileReaderLoaderClient {
+class ClipboardWriter : public GarbageCollected<ClipboardWriter>,
+ public FileReaderLoaderClient {
public:
- static std::unique_ptr<ClipboardWriter> Create(const String& mime_type,
- ClipboardPromise* promise);
+ static ClipboardWriter* Create(SystemClipboard* system_clipboard,
+ const String& mime_type,
+ ClipboardPromise* promise);
+ static ClipboardWriter* Create(RawSystemClipboard* raw_system_clipboard,
+ const String& mime_type,
+ ClipboardPromise* promise);
+
~ClipboardWriter() override;
static bool IsValidType(const String& type);
@@ -38,24 +48,38 @@ class ClipboardWriter : public FileReaderLoaderClient {
void DidFinishLoading() override;
void DidFail(FileErrorCode) override;
+ void Trace(Visitor*);
+
protected:
- explicit ClipboardWriter(ClipboardPromise* promise);
+ ClipboardWriter(SystemClipboard* system_clipboard, ClipboardPromise* promise);
+ ClipboardWriter(RawSystemClipboard* raw_system_clipboard,
+ ClipboardPromise* promise);
virtual void DecodeOnBackgroundThread(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
DOMArrayBuffer* raw_data) = 0;
// This ClipboardPromise owns this.
- Persistent<ClipboardPromise> promise_;
+ Member<ClipboardPromise> promise_;
// Ensure that System Clipboard operations occur on the main thread.
SEQUENCE_CHECKER(sequence_checker_);
+ SystemClipboard* system_clipboard() { return system_clipboard_; }
+ RawSystemClipboard* raw_system_clipboard() { return raw_system_clipboard_; }
+
private:
+ ClipboardWriter(SystemClipboard* system_clipboard,
+ RawSystemClipboard* raw_system_clipboard,
+ ClipboardPromise* promise);
// TaskRunner for interacting with the system clipboard.
const scoped_refptr<base::SingleThreadTaskRunner> clipboard_task_runner_;
// TaskRunner for reading files.
const scoped_refptr<base::SingleThreadTaskRunner> file_reading_task_runner_;
// This FileReaderLoader will load the Blob.
std::unique_ptr<FileReaderLoader> file_reader_;
+ // Access to the global sanitized system clipboard.
+ Member<SystemClipboard> system_clipboard_;
+ // Access to the global unsanitized system clipboard.
+ Member<RawSystemClipboard> raw_system_clipboard_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/clipboard/idls.gni b/chromium/third_party/blink/renderer/modules/clipboard/idls.gni
new file mode 100644
index 00000000000..433867112b5
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/clipboard/idls.gni
@@ -0,0 +1,12 @@
+# 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 = [
+ "clipboard.idl",
+ "clipboard_item.idl",
+]
+
+modules_dictionary_idl_files = [ "clipboard_item_options.idl" ]
+
+modules_dependency_idl_files = [ "navigator_clipboard.idl" ]
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 6042a93e35f..1e292b0a297 100644
--- a/chromium/third_party/blink/renderer/modules/clipboard/navigator_clipboard.cc
+++ b/chromium/third_party/blink/renderer/modules/clipboard/navigator_clipboard.cc
@@ -22,20 +22,26 @@ Clipboard* NavigatorClipboard::clipboard(ScriptState* script_state,
ProvideTo(navigator, supplement);
}
+ if (!supplement->GetSupplementable()->GetFrame())
+ return nullptr;
+
return supplement->clipboard_;
}
-void NavigatorClipboard::Trace(blink::Visitor* visitor) {
+void NavigatorClipboard::Trace(Visitor* visitor) {
visitor->Trace(clipboard_);
Supplement<Navigator>::Trace(visitor);
}
NavigatorClipboard::NavigatorClipboard(Navigator& navigator)
: Supplement<Navigator>(navigator) {
+ // TODO(crbug.com/1028591): Figure out how navigator.clipboard is supposed to
+ // behave in a detached execution context.
+ if (!GetSupplementable()->GetFrame())
+ return;
+
clipboard_ = MakeGarbageCollected<Clipboard>(
- GetSupplementable()->GetFrame()
- ? GetSupplementable()->GetFrame()->GetDocument()
- : nullptr);
+ GetSupplementable()->GetFrame()->GetDocument()->ToExecutionContext());
}
} // namespace blink
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 521b38c698d..9ec7666160e 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<Clipboard> clipboard_;
diff --git a/chromium/third_party/blink/renderer/modules/compression/compression_stream.idl b/chromium/third_party/blink/renderer/modules/compression/compression_stream.idl
index 66f492f366a..dd74ace8f62 100644
--- a/chromium/third_party/blink/renderer/modules/compression/compression_stream.idl
+++ b/chromium/third_party/blink/renderer/modules/compression/compression_stream.idl
@@ -1,10 +1,7 @@
[
- Exposed=(Window,Worker),
- Constructor(DOMString format),
- ConstructorCallWith=ScriptState,
- RaisesException=Constructor,
- MeasureAs=CompressionStreamConstructor
+ Exposed=(Window,Worker)
] interface CompressionStream {
+ [CallWith=ScriptState, RaisesException, MeasureAs=CompressionStreamConstructor] constructor(DOMString format);
readonly attribute ReadableStream readable;
readonly attribute WritableStream writable;
};
diff --git a/chromium/third_party/blink/renderer/modules/compression/decompression_stream.idl b/chromium/third_party/blink/renderer/modules/compression/decompression_stream.idl
index b13d56aa0b7..281d1dc5f1e 100644
--- a/chromium/third_party/blink/renderer/modules/compression/decompression_stream.idl
+++ b/chromium/third_party/blink/renderer/modules/compression/decompression_stream.idl
@@ -1,10 +1,7 @@
[
- Exposed=(Window,Worker),
- Constructor(DOMString format),
- ConstructorCallWith=ScriptState,
- RaisesException=Constructor,
- MeasureAs=DecompressionStreamConstructor
+ Exposed=(Window,Worker)
] interface DecompressionStream {
+ [CallWith=ScriptState, RaisesException, MeasureAs=DecompressionStreamConstructor] constructor(DOMString format);
readonly attribute ReadableStream readable;
readonly attribute WritableStream writable;
};
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 6f07bd96294..4ee5a115ba8 100644
--- a/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.cc
+++ b/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.cc
@@ -66,15 +66,27 @@ ScriptPromise DeflateTransformer::Transform(
if (buffer_source.IsArrayBufferView()) {
const auto* view = buffer_source.GetAsArrayBufferView().View();
const uint8_t* start = static_cast<const uint8_t*>(view->BaseAddress());
- wtf_size_t length = view->deprecatedByteLengthAsUnsigned();
- Deflate(start, length, IsFinished(false), controller, exception_state);
+ size_t length = view->byteLengthAsSizeT();
+ if (length > std::numeric_limits<wtf_size_t>::max()) {
+ exception_state.ThrowRangeError(
+ "Buffer size exceeds maximum heap object size.");
+ return ScriptPromise();
+ }
+ Deflate(start, static_cast<wtf_size_t>(length), IsFinished(false),
+ controller, exception_state);
return ScriptPromise::CastUndefined(script_state_);
}
DCHECK(buffer_source.IsArrayBuffer());
const auto* array_buffer = buffer_source.GetAsArrayBuffer();
const uint8_t* start = static_cast<const uint8_t*>(array_buffer->Data());
- wtf_size_t length = array_buffer->DeprecatedByteLengthAsUnsigned();
- Deflate(start, length, IsFinished(false), controller, exception_state);
+ size_t length = array_buffer->ByteLengthAsSizeT();
+ if (length > std::numeric_limits<wtf_size_t>::max()) {
+ exception_state.ThrowRangeError(
+ "Buffer size exceeds maximum heap object size.");
+ return ScriptPromise();
+ }
+ Deflate(start, static_cast<wtf_size_t>(length), IsFinished(false), controller,
+ exception_state);
return ScriptPromise::CastUndefined(script_state_);
}
diff --git a/chromium/third_party/blink/renderer/modules/compression/idls.gni b/chromium/third_party/blink/renderer/modules/compression/idls.gni
new file mode 100644
index 00000000000..d986709dc5d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/compression/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "compression_stream.idl",
+ "decompression_stream.idl",
+]
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 5c70327e83b..414b126ac21 100644
--- a/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.cc
+++ b/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.cc
@@ -64,15 +64,27 @@ ScriptPromise InflateTransformer::Transform(
if (buffer_source.IsArrayBufferView()) {
const auto* view = buffer_source.GetAsArrayBufferView().View();
const uint8_t* start = static_cast<const uint8_t*>(view->BaseAddress());
- wtf_size_t length = view->deprecatedByteLengthAsUnsigned();
- Inflate(start, length, IsFinished(false), controller, exception_state);
+ size_t length = view->byteLengthAsSizeT();
+ if (length > std::numeric_limits<wtf_size_t>::max()) {
+ exception_state.ThrowRangeError(
+ "Buffer size exceeds maximum heap object size.");
+ return ScriptPromise();
+ }
+ Inflate(start, static_cast<wtf_size_t>(length), IsFinished(false),
+ controller, exception_state);
return ScriptPromise::CastUndefined(script_state_);
}
DCHECK(buffer_source.IsArrayBuffer());
const auto* array_buffer = buffer_source.GetAsArrayBuffer();
const uint8_t* start = static_cast<const uint8_t*>(array_buffer->Data());
- wtf_size_t length = array_buffer->DeprecatedByteLengthAsUnsigned();
- Inflate(start, length, IsFinished(false), controller, exception_state);
+ size_t length = array_buffer->ByteLengthAsSizeT();
+ if (length > std::numeric_limits<wtf_size_t>::max()) {
+ exception_state.ThrowRangeError(
+ "Buffer size exceeds maximum heap object size.");
+ return ScriptPromise();
+ }
+ Inflate(start, static_cast<wtf_size_t>(length), IsFinished(false), controller,
+ exception_state);
return ScriptPromise::CastUndefined(script_state_);
}
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 89497080de8..eb83ef48ce3 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
@@ -7,13 +7,14 @@
#include "base/stl_util.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_contact_info.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/fileapi/blob.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/modules/contacts_picker/contact_address.h"
-#include "third_party/blink/renderer/modules/contacts_picker/contact_info.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/heap/visitor.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -129,37 +130,33 @@ const Vector<String>& ContactsManager::GetProperties(
ScriptPromise ContactsManager::select(ScriptState* script_state,
const Vector<String>& properties,
- ContactsSelectOptions* options) {
- Document* document = To<Document>(ExecutionContext::From(script_state));
+ ContactsSelectOptions* options,
+ ExceptionState& exception_state) {
+ Document* document = Document::From(ExecutionContext::From(script_state));
if (document->ParentDocument()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "The contacts API can only be used in the top frame"));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "The contacts API can only be used in the top frame");
+ return ScriptPromise();
}
if (!LocalFrame::HasTransientUserActivation(document ? document->GetFrame()
: nullptr)) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kSecurityError,
- "A user gesture is required to call this method"));
+ exception_state.ThrowSecurityError(
+ "A user gesture is required to call this method");
+ return ScriptPromise();
}
if (properties.IsEmpty()) {
- return ScriptPromise::Reject(script_state,
- V8ThrowException::CreateTypeError(
- script_state->GetIsolate(),
- "At least one property must be provided"));
+ exception_state.ThrowTypeError("At least one property must be provided");
+ return ScriptPromise();
}
if (contact_picker_in_use_) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "Contacts Picker is already in use."));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Contacts Picker is already in use.");
+ return ScriptPromise();
}
bool include_names = false;
@@ -170,12 +167,10 @@ ScriptPromise ContactsManager::select(ScriptState* script_state,
for (const String& property : properties) {
if (!base::Contains(GetProperties(script_state), property)) {
- return ScriptPromise::Reject(
- script_state,
- V8ThrowException::CreateTypeError(
- script_state->GetIsolate(),
- "The provided value '" + property +
- "' is not a valid enum value of type ContactProperty"));
+ exception_state.ThrowTypeError(
+ "The provided value '" + property +
+ "' is not a valid enum value of type ContactProperty");
+ return ScriptPromise();
}
if (property == kName)
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 329ad0db2b0..22a18363cef 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,13 +8,14 @@
#include "mojo/public/cpp/bindings/remote.h"
#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/modules/contacts_picker/contacts_select_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_contacts_select_options.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/wtf/vector.h"
namespace blink {
+class ExceptionState;
class ScriptPromiseResolver;
class ScriptState;
@@ -29,7 +30,8 @@ class ContactsManager final : public ScriptWrappable {
// Web-exposed function defined in the IDL file.
ScriptPromise select(ScriptState* script_state,
const Vector<String>& properties,
- ContactsSelectOptions* options);
+ ContactsSelectOptions* options,
+ ExceptionState& exception_state);
ScriptPromise getProperties(ScriptState* script_state);
private:
diff --git a/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.idl b/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.idl
index 697fa3a34a1..30f2b65b76d 100644
--- a/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.idl
+++ b/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.idl
@@ -10,5 +10,5 @@
RuntimeEnabled=ContactsManager
] interface ContactsManager {
[CallWith=ScriptState, MeasureAs=ContactsManagerGetProperties] Promise<sequence<ContactProperty>> getProperties();
- [CallWith=ScriptState, MeasureAs=ContactsManagerSelect] Promise<sequence<ContactInfo>> select(sequence<ContactProperty> properties, optional ContactsSelectOptions options);
+ [CallWith=ScriptState, RaisesException, MeasureAs=ContactsManagerSelect] Promise<sequence<ContactInfo>> select(sequence<ContactProperty> properties, optional ContactsSelectOptions options = {});
};
diff --git a/chromium/third_party/blink/renderer/modules/contacts_picker/idls.gni b/chromium/third_party/blink/renderer/modules/contacts_picker/idls.gni
new file mode 100644
index 00000000000..af35464b6be
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/contacts_picker/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "contact_address.idl",
+ "contacts_manager.idl",
+]
+
+modules_dictionary_idl_files = [
+ "contact_info.idl",
+ "contacts_select_options.idl",
+]
+
+modules_dependency_idl_files = [ "navigator_contacts.idl" ]
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 debf6e50079..cbf40e6a8ce 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
@@ -5,7 +5,7 @@
#include "third_party/blink/renderer/modules/content_index/content_description_type_converter.h"
#include "third_party/blink/public/mojom/content_index/content_index.mojom-blink.h"
-#include "third_party/blink/renderer/modules/content_index/content_icon_definition.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_content_icon_definition.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
diff --git a/chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter.h b/chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter.h
index 8552d8f5b1c..da76c761479 100644
--- a/chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter.h
+++ b/chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter.h
@@ -7,7 +7,7 @@
#include "mojo/public/cpp/bindings/type_converter.h"
#include "third_party/blink/public/mojom/content_index/content_index.mojom-blink-forward.h"
-#include "third_party/blink/renderer/modules/content_index/content_description.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_content_description.h"
#include "third_party/blink/renderer/modules/modules_export.h"
namespace mojo {
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 e3e3de0f386..5a3733c1d5f 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
@@ -6,8 +6,8 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/content_index/content_index.mojom-blink.h"
-#include "third_party/blink/renderer/modules/content_index/content_description.h"
-#include "third_party/blink/renderer/modules/content_index/content_icon_definition.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_content_description.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_content_icon_definition.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
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 929c5965d65..7d77fb47c2f 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
@@ -8,12 +8,13 @@
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_content_icon_definition.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/modules/content_index/content_description_type_converter.h"
-#include "third_party/blink/renderer/modules/content_index/content_icon_definition.h"
#include "third_party/blink/renderer/modules/content_index/content_index_icon_loader.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_registration.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -73,21 +74,19 @@ ContentIndex::ContentIndex(ServiceWorkerRegistration* registration,
ContentIndex::~ContentIndex() = default;
ScriptPromise ContentIndex::add(ScriptState* script_state,
- const ContentDescription* description) {
+ const ContentDescription* description,
+ ExceptionState& exception_state) {
if (!registration_->active()) {
- return ScriptPromise::Reject(
- script_state,
- V8ThrowException::CreateTypeError(script_state->GetIsolate(),
- "No active registration available on "
- "the ServiceWorkerRegistration."));
+ exception_state.ThrowTypeError(
+ "No active registration available on the ServiceWorkerRegistration.");
+ return ScriptPromise();
}
WTF::String description_error =
ValidateDescription(*description, registration_.Get());
if (!description_error.IsNull()) {
- return ScriptPromise::Reject(
- script_state, V8ThrowException::CreateTypeError(
- script_state->GetIsolate(), description_error));
+ exception_state.ThrowTypeError(description_error);
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -106,7 +105,7 @@ ScriptPromise ContentIndex::add(ScriptState* script_state,
void ContentIndex::DidGetIconSizes(
ScriptPromiseResolver* resolver,
mojom::blink::ContentDescriptionPtr description,
- const Vector<WebSize>& icon_sizes) {
+ const Vector<gfx::Size>& icon_sizes) {
if (!icon_sizes.IsEmpty() && description->icons.IsEmpty()) {
ScriptState* script_state = resolver->GetScriptState();
ScriptState::Scope scope(script_state);
@@ -176,13 +175,12 @@ void ContentIndex::DidAdd(ScriptPromiseResolver* resolver,
}
ScriptPromise ContentIndex::deleteDescription(ScriptState* script_state,
- const String& id) {
+ const String& id,
+ ExceptionState& exception_state) {
if (!registration_->active()) {
- return ScriptPromise::Reject(
- script_state,
- V8ThrowException::CreateTypeError(script_state->GetIsolate(),
- "No active registration available on "
- "the ServiceWorkerRegistration."));
+ exception_state.ThrowTypeError(
+ "No active registration available on the ServiceWorkerRegistration.");
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -221,13 +219,12 @@ void ContentIndex::DidDeleteDescription(ScriptPromiseResolver* resolver,
}
}
-ScriptPromise ContentIndex::getDescriptions(ScriptState* script_state) {
+ScriptPromise ContentIndex::getDescriptions(ScriptState* script_state,
+ ExceptionState& exception_state) {
if (!registration_->active()) {
- return ScriptPromise::Reject(
- script_state,
- V8ThrowException::CreateTypeError(script_state->GetIsolate(),
- "No active registration available on "
- "the ServiceWorkerRegistration."));
+ exception_state.ThrowTypeError(
+ "No active registration available on the ServiceWorkerRegistration.");
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -273,7 +270,7 @@ void ContentIndex::DidGetDescriptions(
}
}
-void ContentIndex::Trace(blink::Visitor* visitor) {
+void ContentIndex::Trace(Visitor* visitor) {
visitor->Trace(registration_);
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 49e2ff85628..1394dc2d710 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
@@ -16,6 +16,7 @@
namespace blink {
class ContentDescription;
+class ExceptionState;
class ScriptPromiseResolver;
class ScriptState;
class ServiceWorkerRegistration;
@@ -30,11 +31,15 @@ class ContentIndex final : public ScriptWrappable {
// Web-exposed function defined in the IDL file.
ScriptPromise add(ScriptState* script_state,
- const ContentDescription* description);
- ScriptPromise deleteDescription(ScriptState* script_state, const String& id);
- ScriptPromise getDescriptions(ScriptState* script_state);
+ const ContentDescription* description,
+ ExceptionState& exception_state);
+ ScriptPromise deleteDescription(ScriptState* script_state,
+ const String& id,
+ ExceptionState& exception_state);
+ ScriptPromise getDescriptions(ScriptState* script_state,
+ ExceptionState& exception_state);
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
mojom::blink::ContentIndexService* GetService();
@@ -42,7 +47,7 @@ class ContentIndex final : public ScriptWrappable {
// Callbacks.
void DidGetIconSizes(ScriptPromiseResolver* resolver,
mojom::blink::ContentDescriptionPtr description,
- const Vector<WebSize>& icon_sizes);
+ const Vector<gfx::Size>& icon_sizes);
void DidGetIcons(ScriptPromiseResolver* resolver,
mojom::blink::ContentDescriptionPtr description,
Vector<SkBitmap> icons);
diff --git a/chromium/third_party/blink/renderer/modules/content_index/content_index.idl b/chromium/third_party/blink/renderer/modules/content_index/content_index.idl
index 8a116d02860..fa954d14963 100644
--- a/chromium/third_party/blink/renderer/modules/content_index/content_index.idl
+++ b/chromium/third_party/blink/renderer/modules/content_index/content_index.idl
@@ -8,7 +8,7 @@
Exposed=(Window,Worker),
RuntimeEnabled=ContentIndex
] interface ContentIndex {
- [CallWith=ScriptState, MeasureAs=ContentIndexAdd] Promise<void> add(ContentDescription description);
- [CallWith=ScriptState, MeasureAs=ContentIndexDelete, ImplementedAs=deleteDescription] Promise<void> delete(DOMString id);
- [CallWith=ScriptState, MeasureAs=ContentIndexGet, ImplementedAs=getDescriptions] Promise<sequence<ContentDescription>> getAll();
-}; \ No newline at end of file
+ [CallWith=ScriptState, RaisesException, MeasureAs=ContentIndexAdd] Promise<void> add(ContentDescription description);
+ [CallWith=ScriptState, RaisesException, MeasureAs=ContentIndexDelete, ImplementedAs=deleteDescription] Promise<void> delete(DOMString id);
+ [CallWith=ScriptState, RaisesException, MeasureAs=ContentIndexGet, ImplementedAs=getDescriptions] Promise<sequence<ContentDescription>> getAll();
+};
diff --git a/chromium/third_party/blink/renderer/modules/content_index/content_index_event.cc b/chromium/third_party/blink/renderer/modules/content_index/content_index_event.cc
index 6e5595e7f25..4c38fcb84e4 100644
--- a/chromium/third_party/blink/renderer/modules/content_index/content_index_event.cc
+++ b/chromium/third_party/blink/renderer/modules/content_index/content_index_event.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/modules/content_index/content_index_event.h"
-#include "third_party/blink/renderer/modules/service_worker/extendable_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_extendable_event_init.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/content_index/content_index_event.h b/chromium/third_party/blink/renderer/modules/content_index/content_index_event.h
index 53d277df2fc..912389ab49e 100644
--- a/chromium/third_party/blink/renderer/modules/content_index/content_index_event.h
+++ b/chromium/third_party/blink/renderer/modules/content_index/content_index_event.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CONTENT_INDEX_CONTENT_INDEX_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_CONTENT_INDEX_CONTENT_INDEX_EVENT_H_
-#include "third_party/blink/renderer/modules/content_index/content_index_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_content_index_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/service_worker/extendable_event.h"
diff --git a/chromium/third_party/blink/renderer/modules/content_index/content_index_event.idl b/chromium/third_party/blink/renderer/modules/content_index/content_index_event.idl
index a7cb4834573..33aa9bffc86 100644
--- a/chromium/third_party/blink/renderer/modules/content_index/content_index_event.idl
+++ b/chromium/third_party/blink/renderer/modules/content_index/content_index_event.idl
@@ -5,9 +5,9 @@
// https://github.com/rknoll/content-index
[
- Constructor(DOMString type, ContentIndexEventInit init),
Exposed=ServiceWorker,
RuntimeEnabled=ContentIndex
] interface ContentIndexEvent : ExtendableEvent {
+ constructor(DOMString type, ContentIndexEventInit init);
readonly attribute DOMString id;
};
diff --git a/chromium/third_party/blink/renderer/modules/content_index/content_index_icon_loader.cc b/chromium/third_party/blink/renderer/modules/content_index/content_index_icon_loader.cc
index cd1ea626f1d..aa477aa0e6c 100644
--- a/chromium/third_party/blink/renderer/modules/content_index/content_index_icon_loader.cc
+++ b/chromium/third_party/blink/renderer/modules/content_index/content_index_icon_loader.cc
@@ -25,10 +25,12 @@ constexpr base::TimeDelta kIconFetchTimeout = base::TimeDelta::FromSeconds(30);
void FetchIcon(ExecutionContext* execution_context,
const KURL& icon_url,
- const WebSize& icon_size,
+ const gfx::Size& icon_size,
ThreadedIconLoader::IconCallback callback) {
ResourceRequest resource_request(icon_url);
resource_request.SetRequestContext(mojom::RequestContextType::IMAGE);
+ resource_request.SetRequestDestination(
+ network::mojom::RequestDestination::kImage);
resource_request.SetPriority(ResourceLoadPriority::kMedium);
resource_request.SetTimeoutInterval(kIconFetchTimeout);
@@ -47,7 +49,7 @@ WebVector<Manifest::ImageResource> ToImageResource(
image_resource.type = WebString(icon_definition->type).Utf16();
for (const auto& size :
WebIconSizesParser::ParseIconSizes(icon_definition->sizes)) {
- image_resource.sizes.emplace_back(size.width, size.height);
+ image_resource.sizes.emplace_back(size);
}
if (image_resource.sizes.empty())
image_resource.sizes.emplace_back(0, 0);
@@ -58,13 +60,13 @@ WebVector<Manifest::ImageResource> ToImageResource(
}
KURL FindBestIcon(WebVector<Manifest::ImageResource> image_resources,
- const WebSize& icon_size) {
+ const gfx::Size& icon_size) {
return KURL(ManifestIconSelector::FindBestMatchingIcon(
image_resources.ReleaseVector(),
- /* ideal_icon_height_in_px= */ icon_size.height,
+ /* ideal_icon_height_in_px= */ icon_size.height(),
/* minimum_icon_size_in_px= */ 0,
- /* max_width_to_height_ratio= */ icon_size.width * 1.0f /
- icon_size.height,
+ /* max_width_to_height_ratio= */ icon_size.width() * 1.0f /
+ icon_size.height(),
Manifest::ImageResource::Purpose::ANY));
}
@@ -75,7 +77,7 @@ ContentIndexIconLoader::ContentIndexIconLoader() = default;
void ContentIndexIconLoader::Start(
ExecutionContext* execution_context,
mojom::blink::ContentDescriptionPtr description,
- const Vector<WebSize>& icon_sizes,
+ const Vector<gfx::Size>& icon_sizes,
IconsCallback callback) {
DCHECK(!description->icons.IsEmpty());
DCHECK(!icon_sizes.IsEmpty());
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 2643f0666ca..da933d03295 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
@@ -27,7 +27,7 @@ class MODULES_EXPORT ContentIndexIconLoader final
void Start(ExecutionContext* execution_context,
mojom::blink::ContentDescriptionPtr description,
- const Vector<WebSize>& icon_sizes,
+ const Vector<gfx::Size>& icon_sizes,
IconsCallback callback);
void Trace(Visitor* visitor) {}
diff --git a/chromium/third_party/blink/renderer/modules/content_index/idls.gni b/chromium/third_party/blink/renderer/modules/content_index/idls.gni
new file mode 100644
index 00000000000..ecd395aa12d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/content_index/idls.gni
@@ -0,0 +1,19 @@
+# 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 = [
+ "content_index.idl",
+ "content_index_event.idl",
+]
+
+modules_dictionary_idl_files = [
+ "content_description.idl",
+ "content_icon_definition.idl",
+ "content_index_event_init.idl",
+]
+
+modules_dependency_idl_files = [
+ "service_worker_global_scope_content_index.idl",
+ "service_worker_registration_content_index.idl",
+]
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 8cd1fbbd845..e2ebdceb869 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(blink::Visitor* visitor) {
+void ServiceWorkerRegistrationContentIndex::Trace(Visitor* visitor) {
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 7852ebacc0f..49e3a83c829 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(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
Member<ServiceWorkerRegistration> registration_;
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/BUILD.gn b/chromium/third_party/blink/renderer/modules/cookie_store/BUILD.gn
index ae9519242f4..412a1c44643 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/BUILD.gn
@@ -20,7 +20,5 @@ blink_modules_sources("cookie_store") {
"service_worker_registration_cookies.h",
]
- deps = [
- "//third_party/blink/renderer/platform",
- ]
+ deps = [ "//third_party/blink/renderer/platform" ]
}
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/DEPS b/chromium/third_party/blink/renderer/modules/cookie_store/DEPS
deleted file mode 100644
index 74bc32f09ab..00000000000
--- a/chromium/third_party/blink/renderer/modules/cookie_store/DEPS
+++ /dev/null
@@ -1,3 +0,0 @@
-include_rules = [
- "+mojo/public/cpp/bindings/binding.h",
-]
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/README.md b/chromium/third_party/blink/renderer/modules/cookie_store/README.md
index 372fd43cf76..1052f8881d6 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/README.md
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/README.md
@@ -1,4 +1,4 @@
This module implements the
-[Async Cookies API](https://github.com/WICG/async-cookies-api). The
+[Cookie Store API](https://github.com/WICG/cookie-store). The
implementation is under active development, and its progress is tracked in
-[this OWP Launch bug](https://crbug.com/729800
+[this OWP Launch bug](https://crbug.com/729800)
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 ef45a4932d1..f02bb75b83f 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
@@ -7,9 +7,9 @@
#include <utility>
#include "services/network/public/mojom/cookie_manager.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_cookie_change_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_cookie_list_item.h"
#include "third_party/blink/renderer/core/dom/dom_time_stamp.h"
-#include "third_party/blink/renderer/modules/cookie_store/cookie_change_event_init.h"
-#include "third_party/blink/renderer/modules/cookie_store/cookie_list_item.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/platform/cookie/canonical_cookie.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -23,7 +23,7 @@ const AtomicString& CookieChangeEvent::InterfaceName() const {
return event_interface_names::kCookieChangeEvent;
}
-void CookieChangeEvent::Trace(blink::Visitor* visitor) {
+void CookieChangeEvent::Trace(Visitor* visitor) {
Event::Trace(visitor);
visitor->Trace(changed_);
visitor->Trace(deleted_);
@@ -56,7 +56,7 @@ String ToCookieListItemSameSite(network::mojom::CookieSameSite same_site) {
case network::mojom::CookieSameSite::LAX_MODE:
return "lax";
case network::mojom::CookieSameSite::NO_RESTRICTION:
- return "unrestricted";
+ return "none";
case network::mojom::CookieSameSite::UNSPECIFIED:
return "unspecified";
}
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 c2c6f460af9..43b6f74e7a0 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
@@ -8,7 +8,7 @@
#include <utility>
#include "services/network/public/mojom/cookie_manager.mojom-blink-forward.h"
-#include "third_party/blink/renderer/modules/cookie_store/cookie_list_item.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_cookie_list_item.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
@@ -59,7 +59,7 @@ class CookieChangeEvent final : public Event {
const AtomicString& InterfaceName() const override;
// GarbageCollected
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
static CookieListItem* ToCookieListItem(
const CanonicalCookie& canonical_cookie,
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.idl b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.idl
index 4024c9a61cc..1946df4904f 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.idl
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.idl
@@ -10,10 +10,10 @@
[
Exposed=Window,
- RuntimeEnabled=CookieStore,
- SecureContext,
- Constructor(DOMString type, optional CookieChangeEventInit eventInitDict)
+ RuntimeEnabled=CookieStoreDocument,
+ SecureContext
] interface CookieChangeEvent : Event {
+ constructor(DOMString type, optional CookieChangeEventInit eventInitDict = {});
[MeasureAs=CookieStoreAPI] readonly attribute CookieList changed;
[MeasureAs=CookieStoreAPI] readonly attribute CookieList deleted;
};
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 1e156856d35..97b6c8d4785 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
@@ -9,18 +9,20 @@
#include "base/optional.h"
#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_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/modules/cookie_store/cookie_change_event.h"
-#include "third_party/blink/renderer/modules/cookie_store/cookie_list_item.h"
-#include "third_party/blink/renderer/modules/cookie_store/cookie_store_delete_options.h"
-#include "third_party/blink/renderer/modules/cookie_store/cookie_store_get_options.h"
-#include "third_party/blink/renderer/modules/cookie_store/cookie_store_set_extra_options.h"
-#include "third_party/blink/renderer/modules/cookie_store/cookie_store_set_options.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_registration.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/cookie/canonical_cookie.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -41,8 +43,6 @@ network::mojom::blink::CookieManagerGetOptionsPtr ToBackendOptions(
ExceptionState& exception_state) {
auto backend_options = network::mojom::blink::CookieManagerGetOptions::New();
- // TODO(crbug.com/729800): Handle the url option.
-
if (options->matchType() == "starts-with") {
backend_options->match_type =
network::mojom::blink::CookieMatchType::STARTS_WITH;
@@ -105,6 +105,17 @@ base::Optional<CanonicalCookie> ToCanonicalCookie(
domain = cookie_url_host;
}
+ String path = options->path();
+ if (!path.IsEmpty()) {
+ if (!path.StartsWith("/")) {
+ exception_state.ThrowTypeError("Cookie path must start with \"/\"");
+ return base::nullopt;
+ }
+ if (!path.EndsWith("/")) {
+ path = path + String("/");
+ }
+ }
+
// Although the Cookie Store API spec always defaults the "secure" cookie
// attribute to true, we only default to true on cryptographically secure
// origins, where only secure cookies may be written, and to false otherwise,
@@ -140,41 +151,76 @@ base::Optional<CanonicalCookie> ToCanonicalCookie(
} else if (options->sameSite() == "lax") {
same_site = network::mojom::CookieSameSite::LAX_MODE;
} else {
- DCHECK_EQ(options->sameSite(), "unrestricted");
+ DCHECK_EQ(options->sameSite(), "none");
same_site = network::mojom::CookieSameSite::NO_RESTRICTION;
}
return CanonicalCookie::Create(
- name, value, domain, options->path(), base::Time() /*creation*/, expires,
+ name, value, domain, path, base::Time() /*creation*/, expires,
base::Time() /*last_access*/, secure, false /*http_only*/, same_site,
CanonicalCookie::kDefaultPriority, source_scheme_enum);
}
-const KURL& DefaultCookieURL(ExecutionContext* execution_context) {
+const KURL DefaultCookieURL(ExecutionContext* execution_context) {
DCHECK(execution_context);
- if (auto* document = DynamicTo<Document>(execution_context))
+ if (auto* document = Document::DynamicFrom(execution_context))
return document->CookieURL();
- auto* scope = To<ServiceWorkerGlobalScope>(execution_context);
- return scope->Url();
+ return KURL(To<ServiceWorkerGlobalScope>(execution_context)
+ ->serviceWorker()
+ ->scriptURL());
+}
+
+// Return empty KURL if and only if an exception is thrown.
+KURL CookieUrlForRead(const CookieStoreGetOptions* options,
+ const KURL& default_cookie_url,
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
+ ExecutionContext* context = ExecutionContext::From(script_state);
+
+ if (!options->hasUrl())
+ return default_cookie_url;
+
+ KURL cookie_url = KURL(default_cookie_url, options->url());
+
+ if (context->IsDocument()) {
+ DCHECK_EQ(default_cookie_url, Document::From(context)->CookieURL());
+
+ if (cookie_url.GetString() != default_cookie_url.GetString()) {
+ exception_state.ThrowTypeError("URL must match the document URL");
+ return KURL();
+ }
+ } else {
+ DCHECK(context->IsServiceWorkerGlobalScope());
+ DCHECK_EQ(
+ default_cookie_url.GetString(),
+ To<ServiceWorkerGlobalScope>(context)->serviceWorker()->scriptURL());
+
+ if (!cookie_url.GetString().StartsWith(default_cookie_url.GetString())) {
+ exception_state.ThrowTypeError("URL must be within Service Worker scope");
+ return KURL();
+ }
+ }
+
+ return cookie_url;
}
-KURL DefaultSiteForCookies(ExecutionContext* execution_context) {
+net::SiteForCookies DefaultSiteForCookies(ExecutionContext* execution_context) {
DCHECK(execution_context);
- if (auto* document = DynamicTo<Document>(execution_context))
+ if (auto* document = Document::DynamicFrom(execution_context))
return document->SiteForCookies();
auto* scope = To<ServiceWorkerGlobalScope>(execution_context);
- return scope->Url();
+ return net::SiteForCookies::FromUrl(scope->Url());
}
scoped_refptr<SecurityOrigin> DefaultTopFrameOrigin(
ExecutionContext* execution_context) {
DCHECK(execution_context);
- if (auto* document = DynamicTo<Document>(execution_context)) {
+ if (auto* document = Document::DynamicFrom(execution_context)) {
// Can we avoid the copy? TopFrameOrigin is returned as const& but we need
// a scoped_refptr.
return document->TopFrameOrigin()->IsolatedCopy();
@@ -189,8 +235,9 @@ scoped_refptr<SecurityOrigin> DefaultTopFrameOrigin(
CookieStore::CookieStore(
ExecutionContext* execution_context,
mojo::Remote<network::mojom::blink::RestrictedCookieManager> backend)
- : ContextLifecycleObserver(execution_context),
+ : ExecutionContextLifecycleObserver(execution_context),
backend_(std::move(backend)),
+ change_listener_receiver_(this, execution_context),
default_cookie_url_(DefaultCookieURL(execution_context)),
default_site_for_cookies_(DefaultSiteForCookies(execution_context)),
default_top_frame_origin_(DefaultTopFrameOrigin(execution_context)) {
@@ -291,13 +338,13 @@ ScriptPromise CookieStore::Delete(ScriptState* script_state,
return DoWrite(script_state, set_options, exception_state);
}
-void CookieStore::Trace(blink::Visitor* visitor) {
+void CookieStore::Trace(Visitor* visitor) {
+ visitor->Trace(change_listener_receiver_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
-void CookieStore::ContextDestroyed(ExecutionContext* execution_context) {
- StopObserving();
+void CookieStore::ContextDestroyed() {
backend_.reset();
}
@@ -306,7 +353,7 @@ const AtomicString& CookieStore::InterfaceName() const {
}
ExecutionContext* CookieStore::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
void CookieStore::RemoveAllEventListeners() {
@@ -352,7 +399,9 @@ ScriptPromise CookieStore::DoRead(
ExceptionState& exception_state) {
network::mojom::blink::CookieManagerGetOptionsPtr backend_options =
ToBackendOptions(options, exception_state);
- if (backend_options.is_null()) {
+ KURL cookie_url = CookieUrlForRead(options, default_cookie_url_, script_state,
+ exception_state);
+ if (backend_options.is_null() || cookie_url.IsNull()) {
DCHECK(exception_state.HadException());
return ScriptPromise();
}
@@ -365,7 +414,7 @@ ScriptPromise CookieStore::DoRead(
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
backend_->GetAllForUrl(
- default_cookie_url_, default_site_for_cookies_, default_top_frame_origin_,
+ cookie_url, default_site_for_cookies_, default_top_frame_origin_,
std::move(backend_options),
WTF::Bind(backend_result_converter, WrapPersistent(resolver)));
return resolver->Promise();
@@ -378,6 +427,7 @@ void CookieStore::GetAllForUrlToGetAllResult(
ScriptState* script_state = resolver->GetScriptState();
if (!script_state->ContextIsValid())
return;
+ ScriptState::Scope scope(script_state);
HeapVector<Member<CookieListItem>> cookies;
cookies.ReserveInitialCapacity(backend_cookies.size());
@@ -396,6 +446,7 @@ void CookieStore::GetAllForUrlToGetResult(
ScriptState* script_state = resolver->GetScriptState();
if (!script_state->ContextIsValid())
return;
+ ScriptState::Scope scope(script_state);
if (backend_cookies.IsEmpty()) {
resolver->Resolve(v8::Null(script_state->GetIsolate()));
@@ -439,10 +490,11 @@ void CookieStore::OnSetCanonicalCookieResult(ScriptPromiseResolver* resolver,
ScriptState* script_state = resolver->GetScriptState();
if (!script_state->ContextIsValid())
return;
+ ScriptState::Scope scope(script_state);
if (!backend_success) {
- resolver->Reject(MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kUnknownError,
+ resolver->Reject(V8ThrowDOMException::CreateOrEmpty(
+ script_state->GetIsolate(), DOMExceptionCode::kUnknownError,
"An unknown error occured while writing the cookie."));
return;
}
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 419f5d84a61..4d3c596161c 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
@@ -5,16 +5,17 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_COOKIE_STORE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_COOKIE_STORE_H_
-#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
+#include "net/cookies/site_for_cookies.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"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
-#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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_receiver.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -25,11 +26,12 @@ class CookieStoreDeleteOptions;
class CookieStoreGetOptions;
class CookieStoreSetOptions;
class CookieStoreSetExtraOptions;
+class ExceptionState;
class ScriptPromiseResolver;
class ScriptState;
class CookieStore final : public EventTargetWithInlineData,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public network::mojom::blink::CookieChangeListener {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(CookieStore);
@@ -65,10 +67,10 @@ class CookieStore final : public EventTargetWithInlineData,
ExceptionState&);
// GarbageCollected
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
// EventTargetWithInlineData
DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange)
@@ -138,8 +140,8 @@ class CookieStore final : public EventTargetWithInlineData,
// This receiver is set up on-demand, when the cookie store has at least one
// change event listener. If all the listeners are unregistered, the receiver
// is torn down.
- mojo::Receiver<network::mojom::blink::CookieChangeListener>
- change_listener_receiver_{this};
+ HeapMojoReceiver<network::mojom::blink::CookieChangeListener>
+ change_listener_receiver_;
// Default for cookie_url in CookieStoreGetOptions.
//
@@ -149,7 +151,7 @@ class CookieStore final : public EventTargetWithInlineData,
const KURL default_cookie_url_;
// The RFC 6265bis "site for cookies" for this store's ExecutionContext.
- const KURL default_site_for_cookies_;
+ const net::SiteForCookies default_site_for_cookies_;
// The context in which cookies are accessed.
const scoped_refptr<SecurityOrigin> default_top_frame_origin_;
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 a216eba7960..7d4b6beb7a8 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
@@ -6,22 +6,22 @@
[
Exposed=(ServiceWorker,Window),
- RuntimeEnabled=CookieStore,
+ RuntimeEnabled=CookieStoreDocument,
SecureContext
] interface CookieStore : EventTarget {
// https://wicg.github.io/cookie-store/explainer.html#the-query-api
[CallWith=ScriptState, Measure, RaisesException] Promise<CookieListItem?> get(
USVString name);
[CallWith=ScriptState, Measure, RaisesException] Promise<CookieListItem?> get(
- optional CookieStoreGetOptions options);
+ optional CookieStoreGetOptions options = {});
[CallWith=ScriptState, Measure, RaisesException] Promise<CookieList> getAll(
USVString name);
[CallWith=ScriptState, Measure, RaisesException] Promise<CookieList> getAll(
- optional CookieStoreGetOptions options);
+ optional CookieStoreGetOptions options = {});
// 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, optional CookieStoreSetOptions options = {});
[CallWith=ScriptState, Measure, RaisesException] Promise<void> set(
CookieStoreSetExtraOptions options);
[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 915a9e35803..fae25831951 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
@@ -9,14 +9,16 @@
#include "base/optional.h"
#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_list_item.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_cookie_store_get_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/modules/cookie_store/cookie_change_event.h"
-#include "third_party/blink/renderer/modules/cookie_store/cookie_list_item.h"
-#include "third_party/blink/renderer/modules/cookie_store/cookie_store_get_options.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_registration.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/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
@@ -36,9 +38,13 @@ mojom::blink::CookieChangeSubscriptionPtr ToBackendSubscription(
ExceptionState& exception_state) {
auto backend_subscription = mojom::blink::CookieChangeSubscription::New();
- if (subscription->hasURL()) {
+ if (subscription->hasUrl()) {
KURL subscription_url(default_cookie_url, subscription->url());
- // TODO(crbug.com/729800): Check that the URL is under default_cookie_url.
+ if (!subscription_url.GetString().StartsWith(
+ default_cookie_url.GetString())) {
+ exception_state.ThrowTypeError("URL must be within ServiceWorker scope");
+ return nullptr;
+ }
backend_subscription->url = subscription_url;
} else {
backend_subscription->url = default_cookie_url;
@@ -69,7 +75,7 @@ mojom::blink::CookieChangeSubscriptionPtr ToBackendSubscription(
CookieStoreGetOptions* ToCookieChangeSubscription(
const mojom::blink::CookieChangeSubscription& backend_subscription) {
CookieStoreGetOptions* subscription = CookieStoreGetOptions::Create();
- subscription->setURL(backend_subscription.url);
+ subscription->setUrl(backend_subscription.url);
if (backend_subscription.match_type !=
network::mojom::blink::CookieMatchType::STARTS_WITH ||
@@ -175,16 +181,21 @@ ScriptPromise CookieStoreManager::getSubscriptions(
return resolver->Promise();
}
-void CookieStoreManager::Trace(blink::Visitor* visitor) {
+void CookieStoreManager::Trace(Visitor* visitor) {
visitor->Trace(registration_);
ScriptWrappable::Trace(visitor);
}
void CookieStoreManager::OnSubscribeResult(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(MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kUnknownError,
+ resolver->Reject(V8ThrowDOMException::CreateOrEmpty(
+ script_state->GetIsolate(), DOMExceptionCode::kUnknownError,
"An unknown error occured while subscribing to cookie changes."));
return;
}
@@ -195,10 +206,15 @@ void CookieStoreManager::OnGetSubscriptionsResult(
ScriptPromiseResolver* resolver,
Vector<mojom::blink::CookieChangeSubscriptionPtr> backend_result,
bool backend_success) {
+ ScriptState* script_state = resolver->GetScriptState();
+ if (!script_state->ContextIsValid())
+ return;
+ ScriptState::Scope scope(script_state);
+
if (!backend_success) {
- resolver->Reject(MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kUnknownError,
- "An unknown error occured while reading cookie change subscriptions."));
+ resolver->Reject(V8ThrowDOMException::CreateOrEmpty(
+ script_state->GetIsolate(), DOMExceptionCode::kUnknownError,
+ "An unknown error occured while subscribing to cookie changes."));
return;
}
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 4b3219692b7..ed2f718dd8d 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
@@ -9,14 +9,15 @@
#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/exception_state.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/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
class CookieStoreGetOptions;
+class ExceptionState;
class ScriptPromiseResolver;
class ScriptState;
@@ -42,7 +43,7 @@ class CookieStoreManager final : public ScriptWrappable {
ExceptionState& exception_state);
// GarbageCollected
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
// The non-static callbacks keep CookieStoreManager alive during mojo calls.
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 bf047b7c0f0..36568e386b3 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
@@ -6,7 +6,7 @@
[
Exposed=(ServiceWorker,Window),
- RuntimeEnabled=CookieStore,
+ RuntimeEnabled=CookieStoreWorker,
SecureContext
] interface CookieStoreManager {
[CallWith=ScriptState, MeasureAs=CookieStoreAPI, RaisesException]
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_store_set_options.idl
index c9d2cafc212..61ce683779b 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_store_set_options.idl
@@ -7,7 +7,7 @@
enum CookieSameSite {
"strict",
"lax",
- "unrestricted"
+ "none"
};
dictionary CookieStoreSetOptions {
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 98eba76c95d..868003337a0 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
@@ -5,10 +5,10 @@
#include "third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.h"
#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/renderer/modules/cookie_store/cookie_list_item.h"
-#include "third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_cookie_list_item.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_extendable_cookie_change_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_extendable_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
-#include "third_party/blink/renderer/modules/service_worker/extendable_event_init.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -20,7 +20,7 @@ const AtomicString& ExtendableCookieChangeEvent::InterfaceName() const {
return event_interface_names::kExtendableCookieChangeEvent;
}
-void ExtendableCookieChangeEvent::Trace(blink::Visitor* visitor) {
+void ExtendableCookieChangeEvent::Trace(Visitor* visitor) {
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 2fe473392b8..db303f001bc 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
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_EXTENDABLE_COOKIE_CHANGE_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_EXTENDABLE_COOKIE_CHANGE_EVENT_H_
-#include "third_party/blink/renderer/modules/cookie_store/cookie_list_item.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_cookie_list_item.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/service_worker/extendable_event.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -57,7 +57,7 @@ class ExtendableCookieChangeEvent final : public ExtendableEvent {
const AtomicString& InterfaceName() const override;
// GarbageCollected
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.idl b/chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.idl
index 3c8d1b09c7e..15a32f41d44 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.idl
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.idl
@@ -9,9 +9,9 @@
[
Exposed=ServiceWorker,
- RuntimeEnabled=CookieStore,
- Constructor(DOMString type, optional ExtendableCookieChangeEventInit eventInitDict)
+ RuntimeEnabled=CookieStoreWorker
] interface ExtendableCookieChangeEvent : ExtendableEvent {
+ constructor(DOMString type, optional ExtendableCookieChangeEventInit eventInitDict = {});
[MeasureAs=CookieStoreAPI] readonly attribute CookieList changed;
[MeasureAs=CookieStoreAPI] readonly attribute CookieList deleted;
};
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 68909f435aa..cdb5ad25cc5 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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
new file mode 100644
index 00000000000..bda748d3c21
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "cookie_change_event.idl",
+ "cookie_store.idl",
+ "cookie_store_manager.idl",
+ "extendable_cookie_change_event.idl",
+]
+
+modules_dictionary_idl_files = [
+ "cookie_change_event_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",
+]
+
+modules_dependency_idl_files = [
+ "service_worker_global_scope_cookie_store.idl",
+ "service_worker_registration_cookies.idl",
+ "window_cookie_store.idl",
+]
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/service_worker_global_scope_cookie_store.idl b/chromium/third_party/blink/renderer/modules/cookie_store/service_worker_global_scope_cookie_store.idl
index 06149d9dcea..66ea991cc73 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/service_worker_global_scope_cookie_store.idl
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/service_worker_global_scope_cookie_store.idl
@@ -5,7 +5,7 @@
// https://github.com/WICG/async-cookies-api/blob/gh-pages/explainer.md
[
- RuntimeEnabled=CookieStore,
+ RuntimeEnabled=CookieStoreWorker,
ImplementedAs=GlobalCookieStore
] partial interface ServiceWorkerGlobalScope {
[Replaceable, SameObject] readonly attribute CookieStore cookieStore;
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 d569307d279..01cc88350b3 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
@@ -4,7 +4,6 @@
#include "third_party/blink/renderer/modules/cookie_store/service_worker_registration_cookies.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
#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"
@@ -58,7 +57,7 @@ class ServiceWorkerRegistrationCookiesImpl final
return cookie_store_manager_.Get();
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(registration_);
visitor->Trace(cookie_store_manager_);
Supplement<ServiceWorkerRegistration>::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/service_worker_registration_cookies.idl b/chromium/third_party/blink/renderer/modules/cookie_store/service_worker_registration_cookies.idl
index 7d1f00fd046..0af7b91d5d3 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/service_worker_registration_cookies.idl
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/service_worker_registration_cookies.idl
@@ -4,7 +4,7 @@
[
Exposed=(ServiceWorker,Window),
- RuntimeEnabled=CookieStore,
+ RuntimeEnabled=CookieStoreWorker,
ImplementedAs=ServiceWorkerRegistrationCookies
] partial interface ServiceWorkerRegistration {
readonly attribute CookieStoreManager cookies;
diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/window_cookie_store.idl b/chromium/third_party/blink/renderer/modules/cookie_store/window_cookie_store.idl
index 47afee29e42..47cbbbe1d78 100644
--- a/chromium/third_party/blink/renderer/modules/cookie_store/window_cookie_store.idl
+++ b/chromium/third_party/blink/renderer/modules/cookie_store/window_cookie_store.idl
@@ -5,7 +5,7 @@
// https://github.com/WICG/async-cookies-api/blob/gh-pages/explainer.md
[
- RuntimeEnabled=CookieStore,
+ RuntimeEnabled=CookieStoreDocument,
ImplementedAs=GlobalCookieStore,
SecureContext
] partial interface Window {
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/BUILD.gn b/chromium/third_party/blink/renderer/modules/credentialmanager/BUILD.gn
index 92c07988a6f..6a25b790767 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/BUILD.gn
@@ -18,12 +18,16 @@ blink_modules_sources("credentialmanager") {
"credential_manager_proxy.h",
"credential_manager_type_converters.cc",
"credential_manager_type_converters.h",
+ "credential_metrics.cc",
+ "credential_metrics.h",
"credentials_container.cc",
"credentials_container.h",
"federated_credential.cc",
"federated_credential.h",
"navigator_credentials.cc",
"navigator_credentials.h",
+ "otp_credential.cc",
+ "otp_credential.h",
"password_credential.cc",
"password_credential.h",
"public_key_credential.cc",
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/DEPS b/chromium/third_party/blink/renderer/modules/credentialmanager/DEPS
index cd1e025c534..685004288b2 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/DEPS
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/DEPS
@@ -1,5 +1,7 @@
include_rules = [
"+mojo/public",
+ "+services/metrics/public/cpp/ukm_builders.h",
+ "+services/metrics/public/cpp/ukm_source_id.h",
"-third_party/blink/renderer/modules",
"+third_party/blink/renderer/modules/credentialmanager",
"+third_party/blink/renderer/modules/modules_export.h",
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 2b4ce393df7..ecb2b851b7b 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(blink::Visitor* visitor) {
+void AuthenticatorAssertionResponse::Trace(Visitor* visitor) {
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 54c386f7bec..099a9d15603 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 39091997393..a75213c62af 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
@@ -27,7 +27,7 @@ Vector<String> AuthenticatorAttestationResponse::getTransports() const {
return ret;
}
-void AuthenticatorAttestationResponse::Trace(blink::Visitor* visitor) {
+void AuthenticatorAttestationResponse::Trace(Visitor* visitor) {
visitor->Trace(attestation_object_);
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 31c8c8349b0..ea39ef90979 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
@@ -32,7 +32,7 @@ class MODULES_EXPORT AuthenticatorAttestationResponse final
Vector<String> getTransports() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
const Member<DOMArrayBuffer> attestation_object_;
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 15d0941f1b6..03851da82c4 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(blink::Visitor* visitor) {
+void AuthenticatorResponse::Trace(Visitor* visitor) {
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 4eb949e85b0..3679e4cde14 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 b8ca2e39656..c25ae851e48 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/credential.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential.cc
@@ -8,11 +8,15 @@
namespace blink {
+namespace {
+constexpr char kOtpCredentialType[] = "otp";
+}
+
Credential::~Credential() = default;
Credential::Credential(const String& id, const String& type)
: id_(id), type_(type) {
- DCHECK(!id_.IsEmpty());
+ DCHECK(!id_.IsEmpty() || type == kOtpCredentialType);
DCHECK(!type_.IsEmpty());
}
@@ -28,7 +32,7 @@ KURL Credential::ParseStringAsURLOrThrow(const String& url,
return parsed_url;
}
-void Credential::Trace(blink::Visitor* visitor) {
+void Credential::Trace(Visitor* visitor) {
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 23e6c7cb257..15b93a6b005 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/credential.h
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential.h
@@ -20,11 +20,12 @@ class MODULES_EXPORT Credential : public ScriptWrappable {
public:
~Credential() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
virtual bool IsPasswordCredential() const { return false; }
virtual bool IsFederatedCredential() const { return false; }
virtual bool IsPublicKeyCredential() const { return false; }
+ virtual bool IsOTPCredential() const { return false; }
// Credential.idl
const String& id() const { return 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 0824e842905..b51442ab5e0 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,8 +12,9 @@
namespace blink {
-CredentialManagerProxy::CredentialManagerProxy(Document& document) {
- LocalFrame* frame = document.GetFrame();
+CredentialManagerProxy::CredentialManagerProxy(Document& document)
+ : document_(document) {
+ LocalFrame* frame = document_->GetFrame();
DCHECK(frame);
frame->GetBrowserInterfaceBroker().GetInterface(
credential_manager_.BindNewPipeAndPassReceiver(
@@ -23,7 +24,18 @@ CredentialManagerProxy::CredentialManagerProxy(Document& document) {
frame->GetTaskRunner(TaskType::kUserInteraction)));
}
-CredentialManagerProxy::~CredentialManagerProxy() {}
+CredentialManagerProxy::~CredentialManagerProxy() = default;
+
+mojom::blink::SmsReceiver* CredentialManagerProxy::SmsReceiver() {
+ if (!sms_receiver_) {
+ LocalFrame* frame = document_->GetFrame();
+ DCHECK(frame);
+ frame->GetBrowserInterfaceBroker().GetInterface(
+ sms_receiver_.BindNewPipeAndPassReceiver(
+ frame->GetTaskRunner(TaskType::kMiscPlatformAPI)));
+ }
+ return sms_receiver_.get();
+}
// static
CredentialManagerProxy* CredentialManagerProxy::From(Document& document) {
@@ -40,7 +52,12 @@ CredentialManagerProxy* CredentialManagerProxy::From(Document& document) {
CredentialManagerProxy* CredentialManagerProxy::From(
ScriptState* script_state) {
DCHECK(script_state->ContextIsValid());
- return From(To<Document>(*ExecutionContext::From(script_state)));
+ return From(Document::From(*ExecutionContext::From(script_state)));
+}
+
+void CredentialManagerProxy::Trace(Visitor* visitor) {
+ visitor->Trace(document_);
+ Supplement<Document>::Trace(visitor);
}
// static
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 25f046d64dc..41a3b031189 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
@@ -7,6 +7,7 @@
#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/dom/document.h"
#include "third_party/blink/renderer/modules/modules_export.h"
@@ -45,10 +46,14 @@ class MODULES_EXPORT CredentialManagerProxy
mojom::blink::Authenticator* Authenticator() { return authenticator_.get(); }
+ mojom::blink::SmsReceiver* SmsReceiver();
+
void FlushCredentialManagerConnectionForTesting() {
credential_manager_.FlushForTesting();
}
+ void Trace(Visitor* visitor) override;
+
// Both flavors must be called only with arguments representing a valid
// context corresponding to an attached Document.
static CredentialManagerProxy* From(ScriptState*);
@@ -57,6 +62,9 @@ class MODULES_EXPORT CredentialManagerProxy
private:
mojo::Remote<mojom::blink::Authenticator> authenticator_;
mojo::Remote<mojom::blink::CredentialManager> credential_manager_;
+ mojo::Remote<mojom::blink::SmsReceiver> sms_receiver_;
+
+ Member<Document> document_;
};
} // 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 fc95287df6c..7f33a9faad8 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
@@ -10,35 +10,20 @@
#include "build/build_config.h"
#include "third_party/blink/public/mojom/webauthn/authenticator.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h"
-#include "third_party/blink/renderer/modules/credentialmanager/authentication_extensions_client_inputs.h"
-#include "third_party/blink/renderer/modules/credentialmanager/authenticator_selection_criteria.h"
-#include "third_party/blink/renderer/modules/credentialmanager/cable_authentication_data.h"
-#include "third_party/blink/renderer/modules/credentialmanager/cable_registration_data.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_client_inputs.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_authenticator_selection_criteria.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_cable_authentication_data.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_cable_registration_data.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_creation_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_parameters.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_request_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_rp_entity.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_user_entity.h"
#include "third_party/blink/renderer/modules/credentialmanager/credential.h"
#include "third_party/blink/renderer/modules/credentialmanager/federated_credential.h"
#include "third_party/blink/renderer/modules/credentialmanager/password_credential.h"
#include "third_party/blink/renderer/modules/credentialmanager/public_key_credential.h"
-#include "third_party/blink/renderer/modules/credentialmanager/public_key_credential_creation_options.h"
-#include "third_party/blink/renderer/modules/credentialmanager/public_key_credential_descriptor.h"
-#include "third_party/blink/renderer/modules/credentialmanager/public_key_credential_parameters.h"
-#include "third_party/blink/renderer/modules/credentialmanager/public_key_credential_request_options.h"
-#include "third_party/blink/renderer/modules/credentialmanager/public_key_credential_rp_entity.h"
-#include "third_party/blink/renderer/modules/credentialmanager/public_key_credential_user_entity.h"
-
-namespace {
-// Time to wait for an authenticator to successfully complete an operation.
-constexpr base::TimeDelta kAdjustedTimeoutLower =
- base::TimeDelta::FromSeconds(10);
-constexpr base::TimeDelta kAdjustedTimeoutUpper =
- base::TimeDelta::FromMinutes(10);
-
-base::TimeDelta AdjustTimeout(uint32_t timeout) {
- base::TimeDelta adjusted_timeout;
- adjusted_timeout = base::TimeDelta::FromMilliseconds(timeout);
- return std::max(kAdjustedTimeoutLower,
- std::min(kAdjustedTimeoutUpper, adjusted_timeout));
-}
-} // namespace
namespace mojo {
@@ -69,6 +54,20 @@ using blink::mojom::blink::PublicKeyCredentialRequestOptionsPtr;
using blink::mojom::blink::PublicKeyCredentialType;
using blink::mojom::blink::UserVerificationRequirement;
+namespace {
+
+static constexpr int kCoseEs256 = -7;
+static constexpr int kCoseRs256 = -257;
+
+PublicKeyCredentialParametersPtr CreatePublicKeyCredentialParameter(int alg) {
+ auto mojo_parameter = PublicKeyCredentialParameters::New();
+ mojo_parameter->type = PublicKeyCredentialType::PUBLIC_KEY;
+ mojo_parameter->algorithm_identifier = alg;
+ return mojo_parameter;
+}
+
+} // namespace
+
// static
CredentialInfoPtr TypeConverter<CredentialInfoPtr, blink::Credential*>::Convert(
blink::Credential* credential) {
@@ -174,13 +173,12 @@ Vector<uint8_t> ConvertFixedSizeArray(
const blink::ArrayBufferOrArrayBufferView& buffer,
unsigned length) {
if (buffer.IsArrayBuffer() &&
- (buffer.GetAsArrayBuffer()->DeprecatedByteLengthAsUnsigned() != length)) {
+ (buffer.GetAsArrayBuffer()->ByteLengthAsSizeT() != length)) {
return Vector<uint8_t>();
}
if (buffer.IsArrayBufferView() &&
- buffer.GetAsArrayBufferView().View()->deprecatedByteLengthAsUnsigned() !=
- length) {
+ buffer.GetAsArrayBufferView().View()->byteLengthAsSizeT() != length) {
return Vector<uint8_t>();
}
@@ -407,26 +405,27 @@ TypeConverter<PublicKeyCredentialCreationOptionsPtr,
}
mojo_options->challenge = ConvertTo<Vector<uint8_t>>(options->challenge());
- // Step 4 of https://w3c.github.io/webauthn/#createCredential
if (options->hasTimeout()) {
- mojo_options->adjusted_timeout = AdjustTimeout(options->timeout());
- } else {
- mojo_options->adjusted_timeout = kAdjustedTimeoutUpper;
+ mojo_options->timeout =
+ base::TimeDelta::FromMilliseconds(options->timeout());
}
- // Steps 8 and 9 of
- // https://www.w3.org/TR/2017/WD-webauthn-20170505/#createCredential
+ // Steps 7 and 8 of https://w3c.github.io/webauthn/#sctn-createCredential
Vector<PublicKeyCredentialParametersPtr> parameters;
- for (auto& parameter : options->pubKeyCredParams()) {
- PublicKeyCredentialParametersPtr normalized_parameter =
- PublicKeyCredentialParameters::From(parameter.Get());
- if (normalized_parameter) {
- parameters.push_back(std::move(normalized_parameter));
+ if (options->pubKeyCredParams().size() == 0) {
+ parameters.push_back(CreatePublicKeyCredentialParameter(kCoseEs256));
+ parameters.push_back(CreatePublicKeyCredentialParameter(kCoseRs256));
+ } else {
+ for (auto& parameter : options->pubKeyCredParams()) {
+ PublicKeyCredentialParametersPtr normalized_parameter =
+ PublicKeyCredentialParameters::From(parameter.Get());
+ if (normalized_parameter) {
+ parameters.push_back(std::move(normalized_parameter));
+ }
+ }
+ if (parameters.IsEmpty()) {
+ return nullptr;
}
- }
-
- if (parameters.IsEmpty() && options->hasPubKeyCredParams()) {
- return nullptr;
}
mojo_options->public_key_parameters = std::move(parameters);
@@ -553,9 +552,8 @@ TypeConverter<PublicKeyCredentialRequestOptionsPtr,
mojo_options->challenge = ConvertTo<Vector<uint8_t>>(options->challenge());
if (options->hasTimeout()) {
- mojo_options->adjusted_timeout = AdjustTimeout(options->timeout());
- } else {
- mojo_options->adjusted_timeout = kAdjustedTimeoutUpper;
+ mojo_options->timeout =
+ base::TimeDelta::FromMilliseconds(options->timeout());
}
mojo_options->relying_party_id = options->rpId();
diff --git a/chromium/third_party/blink/renderer/modules/sms/sms_metrics.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_metrics.cc
index 2c966476e8c..2fc79e0c3f5 100644
--- a/chromium/third_party/blink/renderer/modules/sms/sms_metrics.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_metrics.cc
@@ -1,15 +1,15 @@
-// Copyright 2019 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/sms/sms_metrics.h"
+#include "third_party/blink/renderer/modules/credentialmanager/credential_metrics.h"
#include "base/metrics/histogram_macros.h"
#include "services/metrics/public/cpp/ukm_builders.h"
namespace blink {
-void RecordSMSOutcome(SMSReceiverOutcome outcome,
+void RecordSmsOutcome(SMSReceiverOutcome outcome,
ukm::SourceId source_id,
ukm::UkmRecorder* ukm_recorder) {
DCHECK_NE(source_id, ukm::kInvalidSourceId);
@@ -22,11 +22,11 @@ void RecordSMSOutcome(SMSReceiverOutcome outcome,
UMA_HISTOGRAM_ENUMERATION("Blink.Sms.Receive.Outcome", outcome);
}
-void RecordSMSSuccessTime(base::TimeDelta duration) {
+void RecordSmsSuccessTime(base::TimeDelta duration) {
UMA_HISTOGRAM_MEDIUM_TIMES("Blink.Sms.Receive.TimeSuccess", duration);
}
-void RecordSMSCancelTime(base::TimeDelta duration) {
+void RecordSmsCancelTime(base::TimeDelta duration) {
UMA_HISTOGRAM_MEDIUM_TIMES("Blink.Sms.Receive.TimeCancel", duration);
}
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_metrics.h b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_metrics.h
new file mode 100644
index 00000000000..3ad0b5eade9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_metrics.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_MODULES_CREDENTIALMANAGER_CREDENTIAL_METRICS_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_CREDENTIALMANAGER_CREDENTIAL_METRICS_H_
+
+#include <stdint.h>
+
+#include "base/time/time.h"
+#include "services/metrics/public/cpp/ukm_source_id.h"
+#include "third_party/blink/public/common/sms/sms_receiver_outcome.h"
+
+namespace ukm {
+class UkmRecorder;
+} // namespace ukm
+
+namespace blink {
+
+// Records the result of a call to navigator.credentials.get({otp}) using
+// the same histogram as SmsReceiver API to provide continuity with previous
+// iterations of the API.
+void RecordSmsOutcome(SMSReceiverOutcome outcome,
+ ukm::SourceId source_id,
+ ukm::UkmRecorder* ukm_recorder);
+
+// Records the time from when the API is called to when the user successfully
+// receives the SMS and presses verify to move on with the verification flow.
+// This uses the same histogram as SmsReceiver API to provide continuity with
+// previous iterations of the API.
+void RecordSmsSuccessTime(base::TimeDelta duration);
+
+// Records the time from when the API is called to when the user dismisses the
+// infobar to abort SMS retrieval. This uses the same histogram as SmsReceiver
+// API to provide continuity with previous iterations of the API.
+void RecordSmsCancelTime(base::TimeDelta duration);
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CREDENTIALMANAGER_CREDENTIAL_METRICS_H_
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_request_options.idl b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_request_options.idl
index 7f501f685dd..4665db51d54 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_request_options.idl
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_request_options.idl
@@ -16,6 +16,8 @@ dictionary CredentialRequestOptions {
boolean password = false;
CredentialMediationRequirement mediation = "optional";
+ [RuntimeEnabled=SmsReceiver] OTPCredentialRequestOptions otp;
+
PublicKeyCredentialRequestOptions publicKey;
AbortSignal signal;
};
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 ebe7f9bba61..506b0abba56 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc
@@ -8,10 +8,20 @@
#include <utility>
#include "build/build_config.h"
+#include "third_party/blink/public/common/sms/sms_receiver_outcome.h"
#include "third_party/blink/public/mojom/credentialmanager/credential_manager.mojom-blink.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
+#include "third_party/blink/public/mojom/sms/sms_receiver.mojom-blink.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_authentication_extensions_client_inputs.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_authenticator_selection_criteria.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_credential_creation_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_credential_request_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_federated_credential_request_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_otp_credential_request_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_creation_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_request_options.h"
#include "third_party/blink/renderer/core/dom/abort_signal.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
@@ -23,21 +33,16 @@
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/page/frame_tree.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
-#include "third_party/blink/renderer/modules/credentialmanager/authentication_extensions_client_inputs.h"
#include "third_party/blink/renderer/modules/credentialmanager/authenticator_assertion_response.h"
#include "third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.h"
-#include "third_party/blink/renderer/modules/credentialmanager/authenticator_selection_criteria.h"
#include "third_party/blink/renderer/modules/credentialmanager/credential.h"
-#include "third_party/blink/renderer/modules/credentialmanager/credential_creation_options.h"
#include "third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.h"
#include "third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h"
-#include "third_party/blink/renderer/modules/credentialmanager/credential_request_options.h"
+#include "third_party/blink/renderer/modules/credentialmanager/credential_metrics.h"
#include "third_party/blink/renderer/modules/credentialmanager/federated_credential.h"
-#include "third_party/blink/renderer/modules/credentialmanager/federated_credential_request_options.h"
+#include "third_party/blink/renderer/modules/credentialmanager/otp_credential.h"
#include "third_party/blink/renderer/modules/credentialmanager/password_credential.h"
#include "third_party/blink/renderer/modules/credentialmanager/public_key_credential.h"
-#include "third_party/blink/renderer/modules/credentialmanager/public_key_credential_creation_options.h"
-#include "third_party/blink/renderer/modules/credentialmanager/public_key_credential_request_options.h"
#include "third_party/blink/renderer/modules/credentialmanager/scoped_promise_resolver.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
@@ -47,18 +52,18 @@
#include "third_party/blink/renderer/platform/wtf/functional.h"
#if defined(OS_ANDROID)
-#include "third_party/blink/renderer/modules/credentialmanager/public_key_credential_rp_entity.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_rp_entity.h"
#endif
namespace blink {
namespace {
-using mojom::blink::CredentialManagerError;
+using mojom::blink::AuthenticatorStatus;
using mojom::blink::CredentialInfo;
using mojom::blink::CredentialInfoPtr;
+using mojom::blink::CredentialManagerError;
using mojom::blink::CredentialMediationRequirement;
-using mojom::blink::AuthenticatorStatus;
using MojoPublicKeyCredentialCreationOptions =
mojom::blink::PublicKeyCredentialCreationOptions;
using mojom::blink::MakeCredentialAuthenticatorResponsePtr;
@@ -139,7 +144,7 @@ bool CheckSecurityRequirementsBeforeRequest(
// which means the webauthn feature is allowed by default in same-origin
// child browsing contexts.
if (!resolver->GetFrame()->GetSecurityContext()->IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kPublicKeyCredentials)) {
+ mojom::blink::FeaturePolicyFeature::kPublicKeyCredentials)) {
resolver->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kNotAllowedError,
"The 'publickey-credentials' feature is not enabled in this "
@@ -177,93 +182,11 @@ void AssertSecurityRequirementsBeforeResponse(
case RequiredOriginType::kSecureAndPermittedByFeaturePolicy:
SECURITY_CHECK(
resolver->GetFrame()->GetSecurityContext()->IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kPublicKeyCredentials));
+ mojom::blink::FeaturePolicyFeature::kPublicKeyCredentials));
break;
}
}
-#if defined(OS_ANDROID)
-bool CheckPublicKeySecurityRequirements(ScriptPromiseResolver* resolver,
- const String& relying_party_id) {
- const SecurityOrigin* origin =
- resolver->GetFrame()->GetSecurityContext()->GetSecurityOrigin();
-
- if (origin->IsOpaque()) {
- String error_message =
- "The origin ' " + origin->ToRawString() +
- "' is an opaque origin and hence not allowed to access " +
- "'PublicKeyCredential' objects.";
- resolver->Reject(MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotAllowedError, error_message));
- return false;
- }
-
- auto cryptotoken_origin = SecurityOrigin::Create(KURL(kCryptotokenOrigin));
- if (cryptotoken_origin->IsSameOriginWith(origin)) {
- // Allow CryptoToken U2F extension to assert any origin, as cryptotoken
- // handles origin checking separately.
- return true;
- }
-
- if (origin->Protocol() != url::kHttpScheme &&
- origin->Protocol() != url::kHttpsScheme) {
- resolver->Reject(MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotAllowedError,
- "Public-key credentials are only available to HTTPS origin or "
- "HTTP origins that fall under 'localhost'. See "
- "https://crbug.com/824383"));
- return false;
- }
-
- DCHECK_NE(origin->Protocol(), url::kAboutScheme);
- DCHECK_NE(origin->Protocol(), url::kFileScheme);
-
- // Validate the effective domain.
- // For step 6 of both
- // https://w3c.github.io/webauthn/#createCredential and
- // https://w3c.github.io/webauthn/#discover-from-external-source.
- String effective_domain = origin->Domain();
-
- // TODO(crbug.com/803077): Avoid constructing an OriginAccessEntry just
- // for the IP address check. See also crbug.com/827542.
- bool reject_because_invalid_domain = effective_domain.IsEmpty();
- if (!reject_because_invalid_domain) {
- OriginAccessEntry access_entry(
- *origin, network::mojom::CorsDomainMatchMode::kAllowSubdomains);
- reject_because_invalid_domain = access_entry.HostIsIPAddress();
- }
- if (reject_because_invalid_domain) {
- resolver->Reject(MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kSecurityError,
- "Effective domain is not a valid domain."));
- return false;
- }
-
- // For the steps detailed in
- // https://w3c.github.io/webauthn/#CreateCred-DetermineRpId and
- // https://w3c.github.io/webauthn/#GetAssn-DetermineRpId.
- if (!relying_party_id.IsNull()) {
- scoped_refptr<SecurityOrigin> relaying_party_origin =
- origin->IsolatedCopy();
- relaying_party_origin->SetDomainFromDOM(relying_party_id);
- OriginAccessEntry access_entry(
- *relaying_party_origin,
- network::mojom::CorsDomainMatchMode::kAllowSubdomains);
- if (relying_party_id.IsEmpty() ||
- access_entry.MatchesDomain(*origin) !=
- network::cors::OriginAccessEntry::kMatchesOrigin) {
- resolver->Reject(MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kSecurityError,
- "The relying party ID '" + relying_party_id +
- "' is not a registrable domain suffix of, nor equal to '" +
- origin->ToRawString() + "'."));
- return false;
- }
- }
- return true;
-}
-#endif // defined(OS_ANDROID)
-
// Checks if the icon URL is an a-priori authenticated URL.
// https://w3c.github.io/webappsec-credential-management/#dom-credentialuserdata-iconurl
bool IsIconURLNullOrSecure(const KURL& url) {
@@ -386,7 +309,7 @@ DOMException* CredentialManagerErrorToDOMException(
}
// Abort an ongoing PublicKeyCredential create() or get() operation.
-void Abort(ScriptState* script_state) {
+void AbortPublicKeyRequest(ScriptState* script_state) {
if (!script_state->ContextIsValid())
return;
@@ -395,6 +318,16 @@ void Abort(ScriptState* script_state) {
authenticator->Cancel();
}
+// Abort an ongoing OtpCredential get() operation.
+void AbortOtpRequest(ScriptState* script_state) {
+ if (!script_state->ContextIsValid())
+ return;
+
+ auto* sms_receiver =
+ CredentialManagerProxy::From(script_state)->SmsReceiver();
+ sms_receiver->Abort();
+}
+
void OnStoreComplete(std::unique_ptr<ScopedPromiseResolver> scoped_resolver) {
auto* resolver = scoped_resolver->Release();
AssertSecurityRequirementsBeforeResponse(
@@ -543,6 +476,39 @@ void OnGetAssertionComplete(
}
}
+void OnSmsReceive(ScriptPromiseResolver* resolver,
+ base::TimeTicks start_time,
+ mojom::blink::SmsStatus status,
+ const WTF::String& otp) {
+ AssertSecurityRequirementsBeforeResponse(
+ resolver, RequiredOriginType::kSecureAndSameWithAncestors);
+ auto& document =
+ Document::From(*ExecutionContext::From(resolver->GetScriptState()));
+ ukm::SourceId source_id = document.UkmSourceID();
+ ukm::UkmRecorder* recorder = document.UkmRecorder();
+
+ if (status == mojom::blink::SmsStatus::kTimeout) {
+ RecordSmsOutcome(SMSReceiverOutcome::kTimeout, source_id, recorder);
+ resolver->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kTimeoutError, "OTP retrieval timed out."));
+ return;
+ } else if (status == mojom::blink::SmsStatus::kAborted) {
+ RecordSmsOutcome(SMSReceiverOutcome::kAborted, source_id, recorder);
+ resolver->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kAbortError, "OTP retrieval was aborted."));
+ return;
+ } else if (status == mojom::blink::SmsStatus::kCancelled) {
+ RecordSmsOutcome(SMSReceiverOutcome::kCancelled, source_id, recorder);
+ RecordSmsCancelTime(base::TimeTicks::Now() - start_time);
+ resolver->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kAbortError, "OTP retrieval was cancelled."));
+ return;
+ }
+ RecordSmsSuccessTime(base::TimeTicks::Now() - start_time);
+ RecordSmsOutcome(SMSReceiverOutcome::kSuccess, source_id, recorder);
+ resolver->Resolve(MakeGarbageCollected<OTPCredential>(otp));
+}
+
} // namespace
CredentialsContainer::CredentialsContainer() = default;
@@ -565,11 +531,10 @@ ScriptPromise CredentialsContainer::get(
if (options->hasPublicKey()) {
auto cryptotoken_origin = SecurityOrigin::Create(KURL(kCryptotokenOrigin));
- if (cryptotoken_origin->IsSameOriginWith(
+ if (!cryptotoken_origin->IsSameOriginWith(
resolver->GetFrame()->GetSecurityContext()->GetSecurityOrigin())) {
- UseCounter::Count(resolver->GetExecutionContext(),
- WebFeature::kU2FCryptotokenSign);
- } else {
+ // Cryptotoken requests are recorded as kU2FCryptotokenSign from within
+ // the extension.
UseCounter::Count(resolver->GetExecutionContext(),
WebFeature::kCredentialManagerGetPublicKeyCredential);
}
@@ -581,16 +546,6 @@ ScriptPromise CredentialsContainer::get(
}
#endif
-#if defined(OS_ANDROID)
- // TODO(kenrb): Remove this for Android when we can plumb the security
- // failure error codes from GMSCore. Until then, this has to be here so
- // informative console messages can appear on security check failures.
- // https://crbug.com/827542.
- const String& relying_party_id = options->publicKey()->rpId();
- if (!CheckPublicKeySecurityRequirements(resolver, relying_party_id))
- return promise;
-#endif
-
if (options->publicKey()->hasExtensions()) {
if (options->publicKey()->extensions()->hasAppid()) {
const auto& appid = options->publicKey()->extensions()->appid();
@@ -615,7 +570,8 @@ ScriptPromise CredentialsContainer::get(
}
if (!options->publicKey()->hasUserVerification()) {
- resolver->GetFrame()->Console().AddMessage(ConsoleMessage::Create(
+ resolver->GetFrame()->Console().AddMessage(MakeGarbageCollected<
+ ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning,
"publicKey.userVerification was not set to any value in Web "
@@ -633,7 +589,7 @@ ScriptPromise CredentialsContainer::get(
return promise;
}
options->signal()->AddAlgorithm(
- WTF::Bind(&Abort, WTF::Passed(WrapPersistent(script_state))));
+ WTF::Bind(&AbortPublicKeyRequest, WrapPersistent(script_state)));
}
auto mojo_options =
@@ -660,6 +616,36 @@ ScriptPromise CredentialsContainer::get(
return promise;
}
+ if (options->hasOtp() && options->otp()->hasTransport()) {
+ if (!options->otp()->transport().Contains("sms")) {
+ resolver->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kNotSupportedError,
+ "Unsupported transport type for OTP Credentials"));
+ return promise;
+ }
+
+ if (options->hasSignal()) {
+ if (options->signal()->aborted()) {
+ resolver->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kAbortError, "Request has been aborted."));
+ return promise;
+ }
+ options->signal()->AddAlgorithm(
+ WTF::Bind(&AbortOtpRequest, WrapPersistent(script_state)));
+ }
+
+ if (!CheckSecurityRequirementsBeforeRequest(
+ resolver, RequiredOriginType::kSecureAndSameWithAncestors)) {
+ return promise;
+ }
+
+ auto* sms_receiver =
+ CredentialManagerProxy::From(script_state)->SmsReceiver();
+ sms_receiver->Receive(WTF::Bind(&OnSmsReceive, WrapPersistent(resolver),
+ base::TimeTicks::Now()));
+ return promise;
+ }
+
Vector<KURL> providers;
if (options->hasFederated() && options->federated()->hasProviders()) {
for (const auto& string : options->federated()->providers()) {
@@ -777,26 +763,15 @@ ScriptPromise CredentialsContainer::create(
} else {
DCHECK(options->hasPublicKey());
auto cryptotoken_origin = SecurityOrigin::Create(KURL(kCryptotokenOrigin));
- if (cryptotoken_origin->IsSameOriginWith(
+ if (!cryptotoken_origin->IsSameOriginWith(
resolver->GetFrame()->GetSecurityContext()->GetSecurityOrigin())) {
- UseCounter::Count(resolver->GetExecutionContext(),
- WebFeature::kU2FCryptotokenRegister);
- } else {
+ // Cryptotoken requests are recorded as kU2FCryptotokenRegister from
+ // within the extension.
UseCounter::Count(
resolver->GetExecutionContext(),
WebFeature::kCredentialManagerCreatePublicKeyCredential);
}
-#if defined(OS_ANDROID)
- // TODO(kenrb): Remove this for Android when we can plumb the security
- // failure error codes from GMSCore. Until then, this has to be here so
- // informative console messages can appear on security check failures.
- // https://crbug.com/827542
- const String& relying_party_id = options->publicKey()->rp()->id();
- if (!CheckPublicKeySecurityRequirements(resolver, relying_party_id))
- return promise;
-#endif
-
if (options->publicKey()->hasExtensions()) {
if (options->publicKey()->extensions()->hasAppid()) {
resolver->Reject(MakeGarbageCollected<DOMException>(
@@ -836,14 +811,15 @@ ScriptPromise CredentialsContainer::create(
return promise;
}
options->signal()->AddAlgorithm(
- WTF::Bind(&Abort, WTF::Passed(WrapPersistent(script_state))));
+ WTF::Bind(&AbortPublicKeyRequest, WrapPersistent(script_state)));
}
if (options->publicKey()->hasAuthenticatorSelection() &&
!options->publicKey()
->authenticatorSelection()
->hasUserVerification()) {
- resolver->GetFrame()->Console().AddMessage(ConsoleMessage::Create(
+ resolver->GetFrame()->Console().AddMessage(MakeGarbageCollected<
+ ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning,
"publicKey.authenticatorSelection.userVerification was not set to "
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.idl b/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.idl
index 1ff690c2b7e..c7ee625b1bf 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.idl
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.idl
@@ -6,8 +6,8 @@
[Exposed=Window, SecureContext]
interface CredentialsContainer {
- [CallWith=ScriptState, MeasureAs=CredentialManagerGet] Promise<Credential?> get(optional CredentialRequestOptions options);
+ [CallWith=ScriptState, MeasureAs=CredentialManagerGet] Promise<Credential?> get(optional CredentialRequestOptions options = {});
[CallWith=ScriptState, MeasureAs=CredentialManagerStore] Promise<Credential> store(Credential credential);
- [CallWith=ScriptState, RaisesException, MeasureAs=CredentialManagerCreate] Promise<Credential?> create(optional CredentialCreationOptions options);
+ [CallWith=ScriptState, RaisesException, MeasureAs=CredentialManagerCreate] Promise<Credential?> create(optional CredentialCreationOptions options = {});
[CallWith=ScriptState, MeasureAs=CredentialManagerPreventSilentAccess] Promise<void> preventSilentAccess();
};
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container_test.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container_test.cc
index 53c8948a86c..9b3c7c8a03b 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container_test.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container_test.cc
@@ -11,28 +11,28 @@
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/credentialmanager/credential_manager.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_credential_creation_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_credential_request_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_creation_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_parameters.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_rp_entity.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_user_entity.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/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/testing/gc_object_liveness_observer.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/modules/credentialmanager/credential.h"
-#include "third_party/blink/renderer/modules/credentialmanager/credential_creation_options.h"
#include "third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.h"
-#include "third_party/blink/renderer/modules/credentialmanager/credential_request_options.h"
#include "third_party/blink/renderer/modules/credentialmanager/federated_credential.h"
#include "third_party/blink/renderer/modules/credentialmanager/password_credential.h"
-#include "third_party/blink/renderer/modules/credentialmanager/public_key_credential_creation_options.h"
-#include "third_party/blink/renderer/modules/credentialmanager/public_key_credential_parameters.h"
-#include "third_party/blink/renderer/modules/credentialmanager/public_key_credential_rp_entity.h"
-#include "third_party/blink/renderer/modules/credentialmanager/public_key_credential_user_entity.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/wrapper_type_info.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
@@ -107,8 +107,8 @@ class CredentialManagerTestingContext {
CredentialManagerTestingContext(
MockCredentialManager* mock_credential_manager)
: dummy_context_(KURL("https://example.test")) {
- dummy_context_.GetDocument().SetSecureContextStateForTesting(
- SecureContextState::kSecure);
+ dummy_context_.GetDocument().SetSecureContextModeForTesting(
+ SecureContextMode::kSecureContext);
dummy_context_.GetFrame().GetBrowserInterfaceBroker().SetBinderForTesting(
::blink::mojom::blink::CredentialManager::Name_,
@@ -182,7 +182,7 @@ TEST(CredentialsContainerTest,
context.GetScriptState(), CredentialRequestOptions::Create());
mock_credential_manager.WaitForCallToGet();
- context.GetDocument()->Shutdown();
+ context.Frame()->DomWindow()->FrameDestroyed();
mock_credential_manager.InvokeGetCallback();
proxy->FlushCredentialManagerConnectionForTesting();
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 090e50bd295..64bbd1385d2 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/federated_credential.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/federated_credential.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/modules/credentialmanager/federated_credential.h"
-#include "third_party/blink/renderer/modules/credentialmanager/federated_credential_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_federated_credential_init.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/federated_credential.idl b/chromium/third_party/blink/renderer/modules/credentialmanager/federated_credential.idl
index ac5d3021c09..b043d5e89d7 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/federated_credential.idl
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/federated_credential.idl
@@ -5,11 +5,10 @@
// https://w3c.github.io/webappsec-credential-management/#federatedcredential
[
- RaisesException=Constructor,
- Constructor(FederatedCredentialInit data),
Exposed=Window,
SecureContext
] interface FederatedCredential : Credential {
+ [RaisesException] constructor(FederatedCredentialInit data);
readonly attribute USVString provider;
// TODO(mkwst): We don't really support this yet; it always returns ''.
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/idls.gni b/chromium/third_party/blink/renderer/modules/credentialmanager/idls.gni
new file mode 100644
index 00000000000..336d2f2b93e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "authenticator_assertion_response.idl",
+ "authenticator_attestation_response.idl",
+ "authenticator_response.idl",
+ "credential.idl",
+ "credentials_container.idl",
+ "federated_credential.idl",
+ "otp_credential.idl",
+ "password_credential.idl",
+ "public_key_credential.idl",
+]
+
+modules_dictionary_idl_files = [
+ "authentication_extensions_client_inputs.idl",
+ "authentication_extensions_client_outputs.idl",
+ "authenticator_selection_criteria.idl",
+ "cable_authentication_data.idl",
+ "cable_registration_data.idl",
+ "collected_client_data.idl",
+ "credential_creation_options.idl",
+ "credential_data.idl",
+ "credential_request_options.idl",
+ "federated_credential_init.idl",
+ "federated_credential_request_options.idl",
+ "otp_credential_request_options.idl",
+ "password_credential_data.idl",
+ "public_key_credential_creation_options.idl",
+ "public_key_credential_descriptor.idl",
+ "public_key_credential_entity.idl",
+ "public_key_credential_parameters.idl",
+ "public_key_credential_request_options.idl",
+ "public_key_credential_rp_entity.idl",
+ "public_key_credential_user_entity.idl",
+]
+
+modules_dependency_idl_files = [
+ "credential_user_data.idl",
+ "navigator_credentials.idl",
+]
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 c026ec2198b..b1f1bf0aedb 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(blink::Visitor* visitor) {
+void NavigatorCredentials::Trace(Visitor* visitor) {
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 00d267b425c..a852ffe3d3a 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
CredentialsContainer* credentials();
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/otp_credential.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/otp_credential.cc
new file mode 100644
index 00000000000..cd021b57ae4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/otp_credential.cc
@@ -0,0 +1,23 @@
+// 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/credentialmanager/otp_credential.h"
+
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+
+namespace blink {
+
+namespace {
+constexpr char kOtpCredentialType[] = "otp";
+}
+
+OTPCredential::OTPCredential(const String& code)
+ : Credential(String(), kOtpCredentialType), code_(code) {}
+
+bool OTPCredential::IsOTPCredential() const {
+ return true;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/otp_credential.h b/chromium/third_party/blink/renderer/modules/credentialmanager/otp_credential.h
new file mode 100644
index 00000000000..199d1b3190e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/otp_credential.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_CREDENTIALMANAGER_OTP_CREDENTIAL_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_CREDENTIALMANAGER_OTP_CREDENTIAL_H_
+
+#include "third_party/blink/renderer/modules/credentialmanager/credential.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+
+namespace blink {
+
+// OtpCredentials represents credentials for when the otp is requested
+// through the credential manager. It stores the one-time-passcode (otp) that
+// is retrieved from SMS by the browser.
+class MODULES_EXPORT OTPCredential final : public Credential {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ explicit OTPCredential(const String& code);
+
+ // Credential:
+ bool IsOTPCredential() const override;
+
+ // OTPCredential.idl
+ const String& code() const { return code_; }
+
+ private:
+ String code_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CREDENTIALMANAGER_OTP_CREDENTIAL_H_
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/otp_credential.idl b/chromium/third_party/blink/renderer/modules/credentialmanager/otp_credential.idl
new file mode 100644
index 00000000000..de32073a5b1
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/otp_credential.idl
@@ -0,0 +1,12 @@
+// 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/samuelgoto/WebOTP
+[
+ RuntimeEnabled=SmsReceiver,
+ Exposed=Window,
+ SecureContext
+] interface OTPCredential : Credential {
+ readonly attribute DOMString code;
+};
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/otp_credential_request_options.idl b/chromium/third_party/blink/renderer/modules/credentialmanager/otp_credential_request_options.idl
new file mode 100644
index 00000000000..31f8c447ed6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/otp_credential_request_options.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/samuelgoto/WebOTP
+
+enum OTPCredentialTransportType {
+ "sms"
+};
+
+dictionary OTPCredentialRequestOptions {
+ sequence<OTPCredentialTransportType> transport = [];
+};
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 ea4b0fab633..22dbd5bd338 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/password_credential.cc
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/password_credential.cc
@@ -4,12 +4,12 @@
#include "third_party/blink/renderer/modules/credentialmanager/password_credential.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_password_credential_data.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/html/forms/form_data.h"
#include "third_party/blink/renderer/core/html/forms/html_form_element.h"
#include "third_party/blink/renderer/core/html/forms/listed_element.h"
#include "third_party/blink/renderer/core/html_names.h"
-#include "third_party/blink/renderer/modules/credentialmanager/password_credential_data.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/password_credential.idl b/chromium/third_party/blink/renderer/modules/credentialmanager/password_credential.idl
index 4838796d276..6f16a641400 100644
--- a/chromium/third_party/blink/renderer/modules/credentialmanager/password_credential.idl
+++ b/chromium/third_party/blink/renderer/modules/credentialmanager/password_credential.idl
@@ -4,12 +4,11 @@
// https://w3c.github.io/webappsec-credential-management/#passwordcredential
[
- RaisesException=Constructor,
- Constructor(PasswordCredentialData data),
- Constructor(HTMLFormElement form),
Exposed=Window,
SecureContext
] interface PasswordCredential : Credential {
+ [RaisesException] constructor(PasswordCredentialData data);
+ [RaisesException] constructor(HTMLFormElement form);
readonly attribute DOMString password;
};
PasswordCredential includes CredentialUserData;
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 0910e59e238..37a360e53fc 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(blink::Visitor* visitor) {
+void PublicKeyCredential::Trace(Visitor* visitor) {
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 90ec10610dd..333d4797ee0 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
@@ -5,8 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CREDENTIALMANAGER_PUBLIC_KEY_CREDENTIAL_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_CREDENTIALMANAGER_PUBLIC_KEY_CREDENTIAL_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_authentication_extensions_client_outputs.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
-#include "third_party/blink/renderer/modules/credentialmanager/authentication_extensions_client_outputs.h"
#include "third_party/blink/renderer/modules/credentialmanager/authenticator_response.h"
#include "third_party/blink/renderer/modules/credentialmanager/credential.h"
#include "third_party/blink/renderer/modules/modules_export.h"
@@ -35,7 +35,7 @@ class MODULES_EXPORT PublicKeyCredential final : public Credential {
AuthenticationExtensionsClientOutputs* getClientExtensionResults() const;
// Credential:
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
bool IsPublicKeyCredential() const override;
private:
diff --git a/chromium/third_party/blink/renderer/modules/crypto/BUILD.gn b/chromium/third_party/blink/renderer/modules/crypto/BUILD.gn
index c51ffb43a07..c6158fa9dd4 100644
--- a/chromium/third_party/blink/renderer/modules/crypto/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/crypto/BUILD.gn
@@ -25,7 +25,5 @@ blink_modules_sources("crypto") {
"worker_global_scope_crypto.h",
]
- deps = [
- "//crypto",
- ]
+ deps = [ "//crypto" ]
}
diff --git a/chromium/third_party/blink/renderer/modules/crypto/crypto.cc b/chromium/third_party/blink/renderer/modules/crypto/crypto.cc
index 79266abcfb4..54e21405652 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(blink::Visitor* visitor) {
+void Crypto::Trace(Visitor* visitor) {
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 e65387dc0cd..dadf713e160 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<SubtleCrypto> subtle_crypto_;
diff --git a/chromium/third_party/blink/renderer/modules/crypto/crypto_histograms.cc b/chromium/third_party/blink/renderer/modules/crypto/crypto_histograms.cc
index 611c2b3bd43..c3fe37e7be4 100644
--- a/chromium/third_party/blink/renderer/modules/crypto/crypto_histograms.cc
+++ b/chromium/third_party/blink/renderer/modules/crypto/crypto_histograms.cc
@@ -48,6 +48,10 @@ static WebFeature AlgorithmIdToFeature(WebCryptoAlgorithmId id) {
return WebFeature::kCryptoAlgorithmHkdf;
case kWebCryptoAlgorithmIdPbkdf2:
return WebFeature::kCryptoAlgorithmPbkdf2;
+ case kWebCryptoAlgorithmIdX25519:
+ return WebFeature::kCryptoAlgorithmX25519;
+ case kWebCryptoAlgorithmIdEd25519:
+ return WebFeature::kCryptoAlgorithmEd25519;
}
NOTREACHED();
@@ -100,6 +104,8 @@ void HistogramAlgorithm(ExecutionContext* context,
case kWebCryptoAlgorithmParamsTypeEcKeyGenParams:
case kWebCryptoAlgorithmParamsTypeEcKeyImportParams:
case kWebCryptoAlgorithmParamsTypeAesDerivedKeyParams:
+ case kWebCryptoAlgorithmParamsTypeEd25519Params:
+ case kWebCryptoAlgorithmParamsTypeX25519KeyDeriveParams:
break;
}
}
diff --git a/chromium/third_party/blink/renderer/modules/crypto/crypto_key.idl b/chromium/third_party/blink/renderer/modules/crypto/crypto_key.idl
index 4063752430f..3b71cd670a9 100644
--- a/chromium/third_party/blink/renderer/modules/crypto/crypto_key.idl
+++ b/chromium/third_party/blink/renderer/modules/crypto/crypto_key.idl
@@ -31,6 +31,7 @@
// https://w3c.github.io/webcrypto/Overview.html#cryptokey-interface
[
+ SecureContext,
Exposed=(Window,Worker)
] interface CryptoKey {
readonly attribute DOMString type;
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 8749a73453c..43449672ac6 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
@@ -39,8 +39,8 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_crypto_key.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/modules/crypto/crypto_key.h"
#include "third_party/blink/renderer/modules/crypto/normalize_algorithm.h"
@@ -74,13 +74,13 @@ class CryptoResultImpl::Resolver final : public ScriptPromiseResolver {
Resolver(ScriptState* script_state, CryptoResultImpl* result)
: ScriptPromiseResolver(script_state), result_(result) {}
- void ContextDestroyed(ExecutionContext* destroyed_context) override {
+ void ContextDestroyed() override {
result_->Cancel();
result_ = nullptr;
- ScriptPromiseResolver::ContextDestroyed(destroyed_context);
+ ScriptPromiseResolver::ContextDestroyed();
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(result_);
ScriptPromiseResolver::Trace(visitor);
}
@@ -121,7 +121,7 @@ CryptoResultImpl::~CryptoResultImpl() {
DCHECK(!resolver_);
}
-void CryptoResultImpl::Trace(blink::Visitor* visitor) {
+void CryptoResultImpl::Trace(Visitor* visitor) {
visitor->Trace(resolver_);
CryptoResult::Trace(visitor);
}
@@ -223,6 +223,14 @@ void CryptoResultImpl::CompleteWithKeyPair(const WebCryptoKey& public_key,
ClearResolver();
}
+void CryptoResultImpl::CompleteWithError(ExceptionState& exception_state) {
+ if (!resolver_)
+ return;
+
+ resolver_->Reject(exception_state);
+ ClearResolver();
+}
+
void CryptoResultImpl::Cancel() {
DCHECK(cancel_);
cancel_->Cancel();
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 0a059cdc78c..777632416c9 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
@@ -51,8 +51,8 @@ MODULES_EXPORT ExceptionCode WebCryptoErrorToExceptionCode(WebCryptoErrorType);
// * All methods of the CryptoResult implementation must be called from
// the origin thread. The exception is that destruction may happen on
// another thread.
-// * One of the completeWith***() functions must be called, or the
-// m_resolver will be leaked until the ExecutionContext is destroyed.
+// * One of the CompleteWith***() functions must be called, or the
+// |resolver_| will be leaked until the ExecutionContext is destroyed.
class MODULES_EXPORT CryptoResultImpl final : public CryptoResult {
public:
explicit CryptoResultImpl(ScriptState*);
@@ -66,13 +66,15 @@ class MODULES_EXPORT CryptoResultImpl final : public CryptoResult {
void CompleteWithKeyPair(const WebCryptoKey& public_key,
const WebCryptoKey& private_key) override;
+ void CompleteWithError(ExceptionState&);
+
// If called after completion (including cancellation) will return an empty
// ScriptPromise.
ScriptPromise Promise();
WebCryptoResult Result() { return WebCryptoResult(this, cancel_.get()); }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 97b16247215..bfc95b03985 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(blink::Visitor* visitor) {
+void DOMWindowCrypto::Trace(Visitor* visitor) {
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 1aa1433523b..24aaa2670dd 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
mutable Member<Crypto> crypto_;
diff --git a/chromium/third_party/blink/renderer/modules/crypto/idls.gni b/chromium/third_party/blink/renderer/modules/crypto/idls.gni
new file mode 100644
index 00000000000..3e3e2433ea8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/crypto/idls.gni
@@ -0,0 +1,19 @@
+# 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 = [
+ "crypto.idl",
+ "crypto_key.idl",
+ "subtle_crypto.idl",
+]
+
+modules_dictionary_idl_files = [
+ "json_web_key.idl",
+ "rsa_other_primes_info.idl",
+]
+
+modules_dependency_idl_files = [
+ "window_crypto.idl",
+ "worker_global_scope_crypto.idl",
+]
diff --git a/chromium/third_party/blink/renderer/modules/crypto/json_web_key.idl b/chromium/third_party/blink/renderer/modules/crypto/json_web_key.idl
new file mode 100644
index 00000000000..343481ee325
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/crypto/json_web_key.idl
@@ -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.
+
+// https://w3c.github.io/webcrypto/#JsonWebKey-dictionary
+
+dictionary JsonWebKey {
+ DOMString kty;
+ DOMString use;
+ sequence<DOMString> key_ops;
+ DOMString alg;
+
+ boolean ext;
+
+ DOMString crv;
+ DOMString x;
+ DOMString y;
+ DOMString d;
+ DOMString n;
+ DOMString e;
+ DOMString p;
+ DOMString q;
+ DOMString dp;
+ DOMString dq;
+ DOMString qi;
+ sequence<RsaOtherPrimesInfo> oth;
+ DOMString k;
+};
diff --git a/chromium/third_party/blink/renderer/modules/crypto/normalize_algorithm.cc b/chromium/third_party/blink/renderer/modules/crypto/normalize_algorithm.cc
index c691635c012..8b90235ba9f 100644
--- a/chromium/third_party/blink/renderer/modules/crypto/normalize_algorithm.cc
+++ b/chromium/third_party/blink/renderer/modules/crypto/normalize_algorithm.cc
@@ -75,10 +75,12 @@ const AlgorithmNameMapping kAlgorithmNameMappings[] = {
{"SHA-1", 5, kWebCryptoAlgorithmIdSha1},
{"ECDSA", 5, kWebCryptoAlgorithmIdEcdsa},
{"PBKDF2", 6, kWebCryptoAlgorithmIdPbkdf2},
+ {"X25519", 6, kWebCryptoAlgorithmIdX25519},
{"AES-KW", 6, kWebCryptoAlgorithmIdAesKw},
{"SHA-512", 7, kWebCryptoAlgorithmIdSha512},
{"SHA-384", 7, kWebCryptoAlgorithmIdSha384},
{"SHA-256", 7, kWebCryptoAlgorithmIdSha256},
+ {"ED25519", 7, kWebCryptoAlgorithmIdEd25519},
{"AES-CBC", 7, kWebCryptoAlgorithmIdAesCbc},
{"AES-GCM", 7, kWebCryptoAlgorithmIdAesGcm},
{"AES-CTR", 7, kWebCryptoAlgorithmIdAesCtr},
@@ -203,17 +205,25 @@ bool LookupAlgorithmIdByName(const String& algorithm_name,
return false;
id = it->algorithm_id;
+ // TODO(crbug.com/1032821): X25519 and Ed25519 are currently introduced behind
+ // a flag.
+ if (!RuntimeEnabledFeatures::WebCryptoCurve25519Enabled() &&
+ (id == kWebCryptoAlgorithmIdEd25519 ||
+ id == kWebCryptoAlgorithmIdX25519)) {
+ return false;
+ }
+
return true;
}
-void SetTypeError(const String& message, AlgorithmError* error) {
- error->error_type = kWebCryptoErrorTypeType;
- error->error_details = message;
+void SetTypeError(const String& message, ExceptionState& exception_state) {
+ exception_state.ThrowTypeError(message);
}
-void SetNotSupportedError(const String& message, AlgorithmError* error) {
- error->error_type = kWebCryptoErrorTypeNotSupported;
- error->error_details = message;
+void SetNotSupportedError(const String& message,
+ ExceptionState& exception_state) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
+ message);
}
// ErrorContext holds a stack of string literals which describe what was
@@ -281,7 +291,7 @@ bool GetOptionalBufferSource(const Dictionary& raw,
bool& has_property,
WebVector<uint8_t>& bytes,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
has_property = false;
v8::Local<v8::Value> v8_value;
if (!raw.Get(property_name, v8_value))
@@ -301,7 +311,8 @@ bool GetOptionalBufferSource(const Dictionary& raw,
}
if (has_property) {
- SetTypeError(context.ToString(property_name, "Not a BufferSource"), error);
+ SetTypeError(context.ToString(property_name, "Not a BufferSource"),
+ exception_state);
return false;
}
return true;
@@ -311,13 +322,13 @@ bool GetBufferSource(const Dictionary& raw,
const char* property_name,
WebVector<uint8_t>& bytes,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
bool has_property;
bool ok = GetOptionalBufferSource(raw, property_name, has_property, bytes,
- context, error);
+ context, exception_state);
if (!has_property) {
SetTypeError(context.ToString(property_name, "Missing required property"),
- error);
+ exception_state);
return false;
}
return ok;
@@ -327,11 +338,11 @@ bool GetUint8Array(const Dictionary& raw,
const char* property_name,
WebVector<uint8_t>& bytes,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
DOMUint8Array* array = nullptr;
if (!DictionaryHelper::Get(raw, property_name, array) || !array) {
SetTypeError(context.ToString(property_name, "Missing or not a Uint8Array"),
- error);
+ exception_state);
return false;
}
bytes = CopyBytes(array);
@@ -345,8 +356,8 @@ bool GetBigInteger(const Dictionary& raw,
const char* property_name,
WebVector<uint8_t>& bytes,
const ErrorContext& context,
- AlgorithmError* error) {
- if (!GetUint8Array(raw, property_name, bytes, context, error))
+ ExceptionState& exception_state) {
+ if (!GetUint8Array(raw, property_name, bytes, context, exception_state))
return false;
if (bytes.empty()) {
@@ -366,7 +377,7 @@ bool GetOptionalInteger(const Dictionary& raw,
double min_value,
double max_value,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
v8::Local<v8::Value> v8_value;
if (!raw.Get(property_name, v8_value)) {
has_property = false;
@@ -378,7 +389,8 @@ bool GetOptionalInteger(const Dictionary& raw,
bool ok = v8_value->NumberValue(raw.V8Context()).To(&number);
if (!ok || std::isnan(number)) {
- SetTypeError(context.ToString(property_name, "Is not a number"), error);
+ SetTypeError(context.ToString(property_name, "Is not a number"),
+ exception_state);
return false;
}
@@ -386,7 +398,7 @@ bool GetOptionalInteger(const Dictionary& raw,
if (std::isinf(number) || number < min_value || number > max_value) {
SetTypeError(context.ToString(property_name, "Outside of numeric range"),
- error);
+ exception_state);
return false;
}
@@ -400,15 +412,15 @@ bool GetInteger(const Dictionary& raw,
double min_value,
double max_value,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
bool has_property;
if (!GetOptionalInteger(raw, property_name, has_property, value, min_value,
- max_value, context, error))
+ max_value, context, exception_state))
return false;
if (!has_property) {
SetTypeError(context.ToString(property_name, "Missing required property"),
- error);
+ exception_state);
return false;
}
@@ -419,9 +431,10 @@ bool GetUint32(const Dictionary& raw,
const char* property_name,
uint32_t& value,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
double number;
- if (!GetInteger(raw, property_name, number, 0, 0xFFFFFFFF, context, error))
+ if (!GetInteger(raw, property_name, number, 0, 0xFFFFFFFF, context,
+ exception_state))
return false;
value = number;
return true;
@@ -431,9 +444,10 @@ bool GetUint16(const Dictionary& raw,
const char* property_name,
uint16_t& value,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
double number;
- if (!GetInteger(raw, property_name, number, 0, 0xFFFF, context, error))
+ if (!GetInteger(raw, property_name, number, 0, 0xFFFF, context,
+ exception_state))
return false;
value = number;
return true;
@@ -443,9 +457,10 @@ bool GetUint8(const Dictionary& raw,
const char* property_name,
uint8_t& value,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
double number;
- if (!GetInteger(raw, property_name, number, 0, 0xFF, context, error))
+ if (!GetInteger(raw, property_name, number, 0, 0xFF, context,
+ exception_state))
return false;
value = number;
return true;
@@ -456,10 +471,10 @@ bool GetOptionalUint32(const Dictionary& raw,
bool& has_value,
uint32_t& value,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
double number;
if (!GetOptionalInteger(raw, property_name, has_value, number, 0, 0xFFFFFFFF,
- context, error))
+ context, exception_state))
return false;
if (has_value)
value = number;
@@ -471,30 +486,30 @@ bool GetOptionalUint8(const Dictionary& raw,
bool& has_value,
uint8_t& value,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
double number;
if (!GetOptionalInteger(raw, property_name, has_value, number, 0, 0xFF,
- context, error))
+ context, exception_state))
return false;
if (has_value)
value = number;
return true;
}
-bool GetAlgorithmIdentifier(const Dictionary& raw,
+bool GetAlgorithmIdentifier(v8::Isolate* isolate,
+ const Dictionary& raw,
const char* property_name,
AlgorithmIdentifier& value,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
// FIXME: This is not correct: http://crbug.com/438060
// (1) It may retrieve the property twice from the dictionary, whereas it
// should be reading the v8 value once to avoid issues with getters.
// (2) The value is stringified (whereas the spec says it should be an
// instance of DOMString).
Dictionary dictionary;
- if (DictionaryHelper::Get(raw, property_name, dictionary) &&
- !dictionary.IsUndefinedOrNull()) {
- value.SetDictionary(dictionary);
+ if (raw.Get(property_name, dictionary) && dictionary.IsObject()) {
+ value.SetObject(ScriptValue(isolate, dictionary.V8Value()));
return true;
}
@@ -502,7 +517,7 @@ bool GetAlgorithmIdentifier(const Dictionary& raw,
if (!DictionaryHelper::Get(raw, property_name, algorithm_name)) {
SetTypeError(context.ToString(property_name,
"Missing or not an AlgorithmIdentifier"),
- error);
+ exception_state);
return false;
}
@@ -518,9 +533,9 @@ bool GetAlgorithmIdentifier(const Dictionary& raw,
bool ParseAesCbcParams(const Dictionary& raw,
std::unique_ptr<WebCryptoAlgorithmParams>& params,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
WebVector<uint8_t> iv;
- if (!GetBufferSource(raw, "iv", iv, context, error))
+ if (!GetBufferSource(raw, "iv", iv, context, exception_state))
return false;
params = std::make_unique<WebCryptoAesCbcParams>(std::move(iv));
@@ -535,32 +550,35 @@ bool ParseAesCbcParams(const Dictionary& raw,
bool ParseAesKeyGenParams(const Dictionary& raw,
std::unique_ptr<WebCryptoAlgorithmParams>& params,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
uint16_t length;
- if (!GetUint16(raw, "length", length, context, error))
+ if (!GetUint16(raw, "length", length, context, exception_state))
return false;
params = std::make_unique<WebCryptoAesKeyGenParams>(length);
return true;
}
-bool ParseAlgorithmIdentifier(const AlgorithmIdentifier&,
+bool ParseAlgorithmIdentifier(v8::Isolate*,
+ const AlgorithmIdentifier&,
WebCryptoOperation,
WebCryptoAlgorithm&,
ErrorContext,
- AlgorithmError*);
+ ExceptionState&);
-bool ParseHash(const Dictionary& raw,
+bool ParseHash(v8::Isolate* isolate,
+ const Dictionary& raw,
WebCryptoAlgorithm& hash,
ErrorContext context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
AlgorithmIdentifier raw_hash;
- if (!GetAlgorithmIdentifier(raw, "hash", raw_hash, context, error))
+ if (!GetAlgorithmIdentifier(isolate, raw, "hash", raw_hash, context,
+ exception_state))
return false;
context.Add("hash");
- return ParseAlgorithmIdentifier(raw_hash, kWebCryptoOperationDigest, hash,
- context, error);
+ return ParseAlgorithmIdentifier(isolate, raw_hash, kWebCryptoOperationDigest,
+ hash, context, exception_state);
}
// Defined by the WebCrypto spec as:
@@ -569,17 +587,19 @@ bool ParseHash(const Dictionary& raw,
// required HashAlgorithmIdentifier hash;
// [EnforceRange] unsigned long length;
// };
-bool ParseHmacImportParams(const Dictionary& raw,
+bool ParseHmacImportParams(v8::Isolate* isolate,
+ const Dictionary& raw,
std::unique_ptr<WebCryptoAlgorithmParams>& params,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
WebCryptoAlgorithm hash;
- if (!ParseHash(raw, hash, context, error))
+ if (!ParseHash(isolate, raw, hash, context, exception_state))
return false;
bool has_length;
uint32_t length = 0;
- if (!GetOptionalUint32(raw, "length", has_length, length, context, error))
+ if (!GetOptionalUint32(raw, "length", has_length, length, context,
+ exception_state))
return false;
params =
@@ -593,17 +613,19 @@ bool ParseHmacImportParams(const Dictionary& raw,
// required HashAlgorithmIdentifier hash;
// [EnforceRange] unsigned long length;
// };
-bool ParseHmacKeyGenParams(const Dictionary& raw,
+bool ParseHmacKeyGenParams(v8::Isolate* isolate,
+ const Dictionary& raw,
std::unique_ptr<WebCryptoAlgorithmParams>& params,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
WebCryptoAlgorithm hash;
- if (!ParseHash(raw, hash, context, error))
+ if (!ParseHash(isolate, raw, hash, context, exception_state))
return false;
bool has_length;
uint32_t length = 0;
- if (!GetOptionalUint32(raw, "length", has_length, length, context, error))
+ if (!GetOptionalUint32(raw, "length", has_length, length, context,
+ exception_state))
return false;
params =
@@ -617,12 +639,13 @@ bool ParseHmacKeyGenParams(const Dictionary& raw,
// required HashAlgorithmIdentifier hash;
// };
bool ParseRsaHashedImportParams(
+ v8::Isolate* isolate,
const Dictionary& raw,
std::unique_ptr<WebCryptoAlgorithmParams>& params,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
WebCryptoAlgorithm hash;
- if (!ParseHash(raw, hash, context, error))
+ if (!ParseHash(isolate, raw, hash, context, exception_state))
return false;
params = std::make_unique<WebCryptoRsaHashedImportParams>(hash);
@@ -640,20 +663,23 @@ bool ParseRsaHashedImportParams(
// required HashAlgorithmIdentifier hash;
// };
bool ParseRsaHashedKeyGenParams(
+ v8::Isolate* isolate,
const Dictionary& raw,
std::unique_ptr<WebCryptoAlgorithmParams>& params,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
uint32_t modulus_length;
- if (!GetUint32(raw, "modulusLength", modulus_length, context, error))
+ if (!GetUint32(raw, "modulusLength", modulus_length, context,
+ exception_state))
return false;
WebVector<uint8_t> public_exponent;
- if (!GetBigInteger(raw, "publicExponent", public_exponent, context, error))
+ if (!GetBigInteger(raw, "publicExponent", public_exponent, context,
+ exception_state))
return false;
WebCryptoAlgorithm hash;
- if (!ParseHash(raw, hash, context, error))
+ if (!ParseHash(isolate, raw, hash, context, exception_state))
return false;
params = std::make_unique<WebCryptoRsaHashedKeyGenParams>(
@@ -670,13 +696,13 @@ bool ParseRsaHashedKeyGenParams(
bool ParseAesCtrParams(const Dictionary& raw,
std::unique_ptr<WebCryptoAlgorithmParams>& params,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
WebVector<uint8_t> counter;
- if (!GetBufferSource(raw, "counter", counter, context, error))
+ if (!GetBufferSource(raw, "counter", counter, context, exception_state))
return false;
uint8_t length;
- if (!GetUint8(raw, "length", length, context, error))
+ if (!GetUint8(raw, "length", length, context, exception_state))
return false;
params = std::make_unique<WebCryptoAesCtrParams>(length, std::move(counter));
@@ -693,21 +719,21 @@ bool ParseAesCtrParams(const Dictionary& raw,
bool ParseAesGcmParams(const Dictionary& raw,
std::unique_ptr<WebCryptoAlgorithmParams>& params,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
WebVector<uint8_t> iv;
- if (!GetBufferSource(raw, "iv", iv, context, error))
+ if (!GetBufferSource(raw, "iv", iv, context, exception_state))
return false;
bool has_additional_data;
WebVector<uint8_t> additional_data;
if (!GetOptionalBufferSource(raw, "additionalData", has_additional_data,
- additional_data, context, error))
+ additional_data, context, exception_state))
return false;
uint8_t tag_length = 0;
bool has_tag_length;
if (!GetOptionalUint8(raw, "tagLength", has_tag_length, tag_length, context,
- error))
+ exception_state))
return false;
params = std::make_unique<WebCryptoAesGcmParams>(
@@ -724,10 +750,11 @@ bool ParseAesGcmParams(const Dictionary& raw,
bool ParseRsaOaepParams(const Dictionary& raw,
std::unique_ptr<WebCryptoAlgorithmParams>& params,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
bool has_label;
WebVector<uint8_t> label;
- if (!GetOptionalBufferSource(raw, "label", has_label, label, context, error))
+ if (!GetOptionalBufferSource(raw, "label", has_label, label, context,
+ exception_state))
return false;
params =
@@ -743,9 +770,10 @@ bool ParseRsaOaepParams(const Dictionary& raw,
bool ParseRsaPssParams(const Dictionary& raw,
std::unique_ptr<WebCryptoAlgorithmParams>& params,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
uint32_t salt_length_bytes;
- if (!GetUint32(raw, "saltLength", salt_length_bytes, context, error))
+ if (!GetUint32(raw, "saltLength", salt_length_bytes, context,
+ exception_state))
return false;
params = std::make_unique<WebCryptoRsaPssParams>(salt_length_bytes);
@@ -757,12 +785,13 @@ bool ParseRsaPssParams(const Dictionary& raw,
// dictionary EcdsaParams : Algorithm {
// required HashAlgorithmIdentifier hash;
// };
-bool ParseEcdsaParams(const Dictionary& raw,
+bool ParseEcdsaParams(v8::Isolate* isolate,
+ const Dictionary& raw,
std::unique_ptr<WebCryptoAlgorithmParams>& params,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
WebCryptoAlgorithm hash;
- if (!ParseHash(raw, hash, context, error))
+ if (!ParseHash(isolate, raw, hash, context, exception_state))
return false;
params = std::make_unique<WebCryptoEcdsaParams>(hash);
@@ -786,11 +815,11 @@ static_assert(kWebCryptoNamedCurveLast + 1 == base::size(kCurveNameMappings),
bool ParseNamedCurve(const Dictionary& raw,
WebCryptoNamedCurve& named_curve,
ErrorContext context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
String named_curve_string;
if (!DictionaryHelper::Get(raw, "namedCurve", named_curve_string)) {
SetTypeError(context.ToString("namedCurve", "Missing or not a string"),
- error);
+ exception_state);
return false;
}
@@ -801,7 +830,8 @@ bool ParseNamedCurve(const Dictionary& raw,
}
}
- SetNotSupportedError(context.ToString("Unrecognized namedCurve"), error);
+ SetNotSupportedError(context.ToString("Unrecognized namedCurve"),
+ exception_state);
return false;
}
@@ -813,9 +843,9 @@ bool ParseNamedCurve(const Dictionary& raw,
bool ParseEcKeyGenParams(const Dictionary& raw,
std::unique_ptr<WebCryptoAlgorithmParams>& params,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
WebCryptoNamedCurve named_curve;
- if (!ParseNamedCurve(raw, named_curve, context, error))
+ if (!ParseNamedCurve(raw, named_curve, context, exception_state))
return false;
params = std::make_unique<WebCryptoEcKeyGenParams>(named_curve);
@@ -830,39 +860,53 @@ bool ParseEcKeyGenParams(const Dictionary& raw,
bool ParseEcKeyImportParams(const Dictionary& raw,
std::unique_ptr<WebCryptoAlgorithmParams>& params,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
WebCryptoNamedCurve named_curve;
- if (!ParseNamedCurve(raw, named_curve, context, error))
+ if (!ParseNamedCurve(raw, named_curve, context, exception_state))
return false;
params = std::make_unique<WebCryptoEcKeyImportParams>(named_curve);
return true;
}
-// Defined by the WebCrypto spec as:
-//
-// dictionary EcdhKeyDeriveParams : Algorithm {
-// required CryptoKey public;
-// };
-bool ParseEcdhKeyDeriveParams(const Dictionary& raw,
- std::unique_ptr<WebCryptoAlgorithmParams>& params,
- const ErrorContext& context,
- AlgorithmError* error) {
+bool GetPeerPublicKey(const Dictionary& raw,
+ const ErrorContext& context,
+ WebCryptoKey* peer_public_key,
+ ExceptionState& exception_state) {
v8::Local<v8::Value> v8_value;
if (!raw.Get("public", v8_value)) {
SetTypeError(context.ToString("public", "Missing required property"),
- error);
+ exception_state);
return false;
}
CryptoKey* crypto_key =
V8CryptoKey::ToImplWithTypeCheck(raw.GetIsolate(), v8_value);
if (!crypto_key) {
- SetTypeError(context.ToString("public", "Must be a CryptoKey"), error);
+ SetTypeError(context.ToString("public", "Must be a CryptoKey"),
+ exception_state);
return false;
}
- params = std::make_unique<WebCryptoEcdhKeyDeriveParams>(crypto_key->Key());
+ *peer_public_key = crypto_key->Key();
+ return true;
+}
+
+// Defined by the WebCrypto spec as:
+//
+// dictionary EcdhKeyDeriveParams : Algorithm {
+// required CryptoKey public;
+// };
+bool ParseEcdhKeyDeriveParams(const Dictionary& raw,
+ std::unique_ptr<WebCryptoAlgorithmParams>& params,
+ const ErrorContext& context,
+ ExceptionState& exception_state) {
+ WebCryptoKey peer_public_key;
+ if (!GetPeerPublicKey(raw, context, &peer_public_key, exception_state))
+ return false;
+
+ DCHECK(!peer_public_key.IsNull());
+ params = std::make_unique<WebCryptoEcdhKeyDeriveParams>(peer_public_key);
return true;
}
@@ -873,20 +917,21 @@ bool ParseEcdhKeyDeriveParams(const Dictionary& raw,
// [EnforceRange] required unsigned long iterations;
// required HashAlgorithmIdentifier hash;
// };
-bool ParsePbkdf2Params(const Dictionary& raw,
+bool ParsePbkdf2Params(v8::Isolate* isolate,
+ const Dictionary& raw,
std::unique_ptr<WebCryptoAlgorithmParams>& params,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
WebVector<uint8_t> salt;
- if (!GetBufferSource(raw, "salt", salt, context, error))
+ if (!GetBufferSource(raw, "salt", salt, context, exception_state))
return false;
uint32_t iterations;
- if (!GetUint32(raw, "iterations", iterations, context, error))
+ if (!GetUint32(raw, "iterations", iterations, context, exception_state))
return false;
WebCryptoAlgorithm hash;
- if (!ParseHash(raw, hash, context, error))
+ if (!ParseHash(isolate, raw, hash, context, exception_state))
return false;
params = std::make_unique<WebCryptoPbkdf2Params>(hash, std::move(salt),
iterations);
@@ -901,9 +946,9 @@ bool ParsePbkdf2Params(const Dictionary& raw,
bool ParseAesDerivedKeyParams(const Dictionary& raw,
std::unique_ptr<WebCryptoAlgorithmParams>& params,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
uint16_t length;
- if (!GetUint16(raw, "length", length, context, error))
+ if (!GetUint16(raw, "length", length, context, exception_state))
return false;
params = std::make_unique<WebCryptoAesDerivedKeyParams>(length);
@@ -917,18 +962,19 @@ bool ParseAesDerivedKeyParams(const Dictionary& raw,
// required BufferSource salt;
// required BufferSource info;
// };
-bool ParseHkdfParams(const Dictionary& raw,
+bool ParseHkdfParams(v8::Isolate* isolate,
+ const Dictionary& raw,
std::unique_ptr<WebCryptoAlgorithmParams>& params,
const ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
WebCryptoAlgorithm hash;
- if (!ParseHash(raw, hash, context, error))
+ if (!ParseHash(isolate, raw, hash, context, exception_state))
return false;
WebVector<uint8_t> salt;
- if (!GetBufferSource(raw, "salt", salt, context, error))
+ if (!GetBufferSource(raw, "salt", salt, context, exception_state))
return false;
WebVector<uint8_t> info;
- if (!GetBufferSource(raw, "info", info, context, error))
+ if (!GetBufferSource(raw, "info", info, context, exception_state))
return false;
params = std::make_unique<WebCryptoHkdfParams>(hash, std::move(salt),
@@ -936,65 +982,118 @@ bool ParseHkdfParams(const Dictionary& raw,
return true;
}
-bool ParseAlgorithmParams(const Dictionary& raw,
+// TODO(crbug.com/1032821): The implementation of Curve25519 algorithms is
+// experimental. See also the status on
+// https://chromestatus.com/feature/4913922408710144.
+//
+// Ed25519Params in the prototype assumes the same structure as EcdsaParams:
+//
+// dictionary Ed25519Params : Algorithm {
+// required HashAlgorithmIdentifier hash;
+// };
+bool ParseEd25519Params(v8::Isolate* isolate,
+ const Dictionary& raw,
+ std::unique_ptr<WebCryptoAlgorithmParams>& params,
+ const ErrorContext& context,
+ ExceptionState& exception_state) {
+ WebCryptoAlgorithm hash;
+ if (!ParseHash(isolate, raw, hash, context, exception_state))
+ return false;
+
+ params = std::make_unique<WebCryptoEd25519Params>(hash);
+ return true;
+}
+
+// TODO(crbug.com/1032821): X25519KeyDeriveParams in the prototype assumes the
+// same structure as EcdhKeyDeriveParams:
+//
+// dictionary X25519KeyDeriveParams : Algorithm {
+// required CryptoKey public;
+// };
+bool ParseX25519KeyDeriveParams(
+ const Dictionary& raw,
+ std::unique_ptr<WebCryptoAlgorithmParams>& params,
+ const ErrorContext& context,
+ ExceptionState& exception_state) {
+ WebCryptoKey peer_public_key;
+ if (!GetPeerPublicKey(raw, context, &peer_public_key, exception_state))
+ return false;
+
+ DCHECK(!peer_public_key.IsNull());
+ params = std::make_unique<WebCryptoX25519KeyDeriveParams>(peer_public_key);
+ return true;
+}
+
+bool ParseAlgorithmParams(v8::Isolate* isolate,
+ const Dictionary& raw,
WebCryptoAlgorithmParamsType type,
std::unique_ptr<WebCryptoAlgorithmParams>& params,
ErrorContext& context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
switch (type) {
case kWebCryptoAlgorithmParamsTypeNone:
return true;
case kWebCryptoAlgorithmParamsTypeAesCbcParams:
context.Add("AesCbcParams");
- return ParseAesCbcParams(raw, params, context, error);
+ return ParseAesCbcParams(raw, params, context, exception_state);
case kWebCryptoAlgorithmParamsTypeAesKeyGenParams:
context.Add("AesKeyGenParams");
- return ParseAesKeyGenParams(raw, params, context, error);
+ return ParseAesKeyGenParams(raw, params, context, exception_state);
case kWebCryptoAlgorithmParamsTypeHmacImportParams:
context.Add("HmacImportParams");
- return ParseHmacImportParams(raw, params, context, error);
+ return ParseHmacImportParams(isolate, raw, params, context,
+ exception_state);
case kWebCryptoAlgorithmParamsTypeHmacKeyGenParams:
context.Add("HmacKeyGenParams");
- return ParseHmacKeyGenParams(raw, params, context, error);
+ return ParseHmacKeyGenParams(isolate, raw, params, context,
+ exception_state);
case kWebCryptoAlgorithmParamsTypeRsaHashedKeyGenParams:
context.Add("RsaHashedKeyGenParams");
- return ParseRsaHashedKeyGenParams(raw, params, context, error);
+ return ParseRsaHashedKeyGenParams(isolate, raw, params, context,
+ exception_state);
case kWebCryptoAlgorithmParamsTypeRsaHashedImportParams:
context.Add("RsaHashedImportParams");
- return ParseRsaHashedImportParams(raw, params, context, error);
+ return ParseRsaHashedImportParams(isolate, raw, params, context,
+ exception_state);
case kWebCryptoAlgorithmParamsTypeAesCtrParams:
context.Add("AesCtrParams");
- return ParseAesCtrParams(raw, params, context, error);
+ return ParseAesCtrParams(raw, params, context, exception_state);
case kWebCryptoAlgorithmParamsTypeAesGcmParams:
context.Add("AesGcmParams");
- return ParseAesGcmParams(raw, params, context, error);
+ return ParseAesGcmParams(raw, params, context, exception_state);
case kWebCryptoAlgorithmParamsTypeRsaOaepParams:
context.Add("RsaOaepParams");
- return ParseRsaOaepParams(raw, params, context, error);
+ return ParseRsaOaepParams(raw, params, context, exception_state);
case kWebCryptoAlgorithmParamsTypeRsaPssParams:
context.Add("RsaPssParams");
- return ParseRsaPssParams(raw, params, context, error);
+ return ParseRsaPssParams(raw, params, context, exception_state);
case kWebCryptoAlgorithmParamsTypeEcdsaParams:
context.Add("EcdsaParams");
- return ParseEcdsaParams(raw, params, context, error);
+ return ParseEcdsaParams(isolate, raw, params, context, exception_state);
case kWebCryptoAlgorithmParamsTypeEcKeyGenParams:
context.Add("EcKeyGenParams");
- return ParseEcKeyGenParams(raw, params, context, error);
+ return ParseEcKeyGenParams(raw, params, context, exception_state);
case kWebCryptoAlgorithmParamsTypeEcKeyImportParams:
context.Add("EcKeyImportParams");
- return ParseEcKeyImportParams(raw, params, context, error);
+ return ParseEcKeyImportParams(raw, params, context, exception_state);
case kWebCryptoAlgorithmParamsTypeEcdhKeyDeriveParams:
context.Add("EcdhKeyDeriveParams");
- return ParseEcdhKeyDeriveParams(raw, params, context, error);
+ return ParseEcdhKeyDeriveParams(raw, params, context, exception_state);
case kWebCryptoAlgorithmParamsTypeAesDerivedKeyParams:
context.Add("AesDerivedKeyParams");
- return ParseAesDerivedKeyParams(raw, params, context, error);
+ return ParseAesDerivedKeyParams(raw, params, context, exception_state);
case kWebCryptoAlgorithmParamsTypeHkdfParams:
context.Add("HkdfParams");
- return ParseHkdfParams(raw, params, context, error);
+ return ParseHkdfParams(isolate, raw, params, context, exception_state);
case kWebCryptoAlgorithmParamsTypePbkdf2Params:
context.Add("Pbkdf2Params");
- return ParsePbkdf2Params(raw, params, context, error);
+ return ParsePbkdf2Params(isolate, raw, params, context, exception_state);
+ case kWebCryptoAlgorithmParamsTypeEd25519Params:
+ context.Add("Ed25519Params");
+ return ParseEd25519Params(isolate, raw, params, context, exception_state);
+ case kWebCryptoAlgorithmParamsTypeX25519KeyDeriveParams:
+ context.Add("X25519KeyDeriveParams");
+ return ParseX25519KeyDeriveParams(raw, params, context, exception_state);
}
NOTREACHED();
return false;
@@ -1028,15 +1127,17 @@ const char* OperationToString(WebCryptoOperation op) {
return nullptr;
}
-bool ParseAlgorithmDictionary(const String& algorithm_name,
+bool ParseAlgorithmDictionary(v8::Isolate* isolate,
+ const String& algorithm_name,
const Dictionary& raw,
WebCryptoOperation op,
WebCryptoAlgorithm& algorithm,
ErrorContext context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
WebCryptoAlgorithmId algorithm_id;
if (!LookupAlgorithmIdByName(algorithm_name, algorithm_id)) {
- SetNotSupportedError(context.ToString("Unrecognized name"), error);
+ SetNotSupportedError(context.ToString("Unrecognized name"),
+ exception_state);
return false;
}
@@ -1051,7 +1152,7 @@ bool ParseAlgorithmDictionary(const String& algorithm_name,
context.Add(algorithm_info->name);
SetNotSupportedError(
context.ToString("Unsupported operation", OperationToString(op)),
- error);
+ exception_state);
return false;
}
@@ -1060,52 +1161,54 @@ bool ParseAlgorithmDictionary(const String& algorithm_name,
algorithm_info->operation_to_params_type[op]);
std::unique_ptr<WebCryptoAlgorithmParams> params;
- if (!ParseAlgorithmParams(raw, params_type, params, context, error))
+ if (!ParseAlgorithmParams(isolate, raw, params_type, params, context,
+ exception_state))
return false;
algorithm = WebCryptoAlgorithm(algorithm_id, std::move(params));
return true;
}
-bool ParseAlgorithmIdentifier(const AlgorithmIdentifier& raw,
+bool ParseAlgorithmIdentifier(v8::Isolate* isolate,
+ const AlgorithmIdentifier& raw,
WebCryptoOperation op,
WebCryptoAlgorithm& algorithm,
ErrorContext context,
- AlgorithmError* error) {
+ ExceptionState& exception_state) {
context.Add("Algorithm");
// If the AlgorithmIdentifier is a String, treat it the same as a Dictionary
// with a "name" attribute and nothing else.
if (raw.IsString()) {
- return ParseAlgorithmDictionary(raw.GetAsString(), Dictionary(), op,
- algorithm, context, error);
+ return ParseAlgorithmDictionary(isolate, raw.GetAsString(), Dictionary(),
+ op, algorithm, context, exception_state);
}
- Dictionary params = raw.GetAsDictionary();
-
// Get the name of the algorithm from the AlgorithmIdentifier.
- if (!params.IsObject()) {
- SetTypeError(context.ToString("Not an object"), error);
+ Dictionary params(isolate, raw.GetAsObject().V8Value(), exception_state);
+ if (exception_state.HadException())
return false;
- }
String algorithm_name;
if (!DictionaryHelper::Get(params, "name", algorithm_name)) {
- SetTypeError(context.ToString("name", "Missing or not a string"), error);
+ SetTypeError(context.ToString("name", "Missing or not a string"),
+ exception_state);
return false;
}
- return ParseAlgorithmDictionary(algorithm_name, params, op, algorithm,
- context, error);
+ return ParseAlgorithmDictionary(isolate, algorithm_name, params, op,
+ algorithm, context, exception_state);
}
} // namespace
-bool NormalizeAlgorithm(const AlgorithmIdentifier& raw,
+bool NormalizeAlgorithm(v8::Isolate* isolate,
+ const AlgorithmIdentifier& raw,
WebCryptoOperation op,
WebCryptoAlgorithm& algorithm,
- AlgorithmError* error) {
- return ParseAlgorithmIdentifier(raw, op, algorithm, ErrorContext(), error);
+ ExceptionState& exception_state) {
+ return ParseAlgorithmIdentifier(isolate, raw, op, algorithm, ErrorContext(),
+ exception_state);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/crypto/normalize_algorithm.h b/chromium/third_party/blink/renderer/modules/crypto/normalize_algorithm.h
index 72529592f8d..9de506078d3 100644
--- a/chromium/third_party/blink/renderer/modules/crypto/normalize_algorithm.h
+++ b/chromium/third_party/blink/renderer/modules/crypto/normalize_algorithm.h
@@ -34,23 +34,16 @@
#include "third_party/blink/public/platform/web_crypto.h"
#include "third_party/blink/public/platform/web_crypto_algorithm.h"
#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/renderer/bindings/modules/v8/dictionary_or_string.h"
+#include "third_party/blink/renderer/bindings/modules/v8/object_or_string.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
+#include "v8/include/v8.h"
namespace blink {
-struct AlgorithmError {
- STACK_ALLOCATED();
-
- public:
- WebCryptoErrorType error_type;
- WebString error_details;
-};
-
-typedef DictionaryOrString AlgorithmIdentifier;
+using AlgorithmIdentifier = ObjectOrString;
// Converts a javascript AlgorithmIdentifier to a WebCryptoAlgorithm object.
//
@@ -59,15 +52,17 @@ typedef DictionaryOrString AlgorithmIdentifier;
//
// On success returns true and sets the WebCryptoAlgorithm.
//
-// On failure normalizeAlgorithm returns false and sets the AlgorithmError with
-// a error type and a (non-localized) debug string.
+// On failure NormalizeAlgorithm returns false and throws an exception in the
+// ExceptionState.
//
-// [1] http://www.w3.org/TR/WebCryptoAPI/#algorithm-normalizing-rules
+// [1]
+// https://w3c.github.io/webcrypto/#algorithm-normalization-normalize-an-algorithm
MODULES_EXPORT WARN_UNUSED_RESULT bool NormalizeAlgorithm(
+ v8::Isolate*,
const AlgorithmIdentifier&,
WebCryptoOperation,
WebCryptoAlgorithm&,
- AlgorithmError*);
+ ExceptionState&);
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/crypto/rsa_other_primes_info.idl b/chromium/third_party/blink/renderer/modules/crypto/rsa_other_primes_info.idl
new file mode 100644
index 00000000000..46d8b55e6fe
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/crypto/rsa_other_primes_info.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://w3c.github.io/webcrypto/#dfn-RsaOtherPrimesInfo
+
+dictionary RsaOtherPrimesInfo {
+ DOMString r;
+ DOMString d;
+ DOMString t;
+};
diff --git a/chromium/third_party/blink/renderer/modules/crypto/subtle_crypto.cc b/chromium/third_party/blink/renderer/modules/crypto/subtle_crypto.cc
index 4e6de702f4f..893cf784b8f 100644
--- a/chromium/third_party/blink/renderer/modules/crypto/subtle_crypto.cc
+++ b/chromium/third_party/blink/renderer/modules/crypto/subtle_crypto.cc
@@ -36,7 +36,9 @@
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_crypto.h"
#include "third_party/blink/public/platform/web_crypto_algorithm.h"
+#include "third_party/blink/public/platform/web_crypto_algorithm_params.h"
#include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
+#include "third_party/blink/renderer/bindings/modules/v8/array_buffer_or_array_buffer_view_or_json_web_key.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
@@ -48,43 +50,10 @@
#include "third_party/blink/renderer/modules/crypto/crypto_utilities.h"
#include "third_party/blink/renderer/modules/crypto/normalize_algorithm.h"
#include "third_party/blink/renderer/platform/json/json_values.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
-static bool ParseAlgorithm(const AlgorithmIdentifier& raw,
- WebCryptoOperation op,
- WebCryptoAlgorithm& algorithm,
- CryptoResult* result) {
- AlgorithmError error;
- bool success = NormalizeAlgorithm(raw, op, algorithm, &error);
- if (!success)
- result->CompleteWithError(error.error_type, error.error_details);
- return success;
-}
-
-static bool CopyStringProperty(const char* property,
- const Dictionary& source,
- JSONObject* destination) {
- String value;
- if (!DictionaryHelper::Get(source, property, value))
- return false;
- destination->SetString(property, value);
- return true;
-}
-
-static bool CopySequenceOfStringProperty(const char* property,
- const Dictionary& source,
- JSONObject* destination) {
- Vector<String> value;
- if (!DictionaryHelper::Get(source, property, value))
- return false;
- auto json_array = std::make_unique<JSONArray>();
- for (unsigned i = 0; i < value.size(); ++i)
- json_array->PushString(value[i]);
- destination->SetArray(property, std::move(json_array));
- return true;
-}
-
// Parses a JsonWebKey dictionary. On success writes the result to
// |jsonUtf8| as a UTF8-encoded JSON octet string and returns true.
// On failure sets an error on |result| and returns false.
@@ -92,66 +61,51 @@ static bool CopySequenceOfStringProperty(const char* property,
// Note: The choice of output as an octet string is to facilitate interop
// with the non-JWK formats, but does mean there is a second parsing step.
// This design choice should be revisited after crbug.com/614385).
-//
-// Defined by the WebCrypto spec as:
-//
-// dictionary JsonWebKey {
-// DOMString kty;
-// DOMString use;
-// sequence<DOMString> key_ops;
-// DOMString alg;
-//
-// boolean ext;
-//
-// DOMString crv;
-// DOMString x;
-// DOMString y;
-// DOMString d;
-// DOMString n;
-// DOMString e;
-// DOMString p;
-// DOMString q;
-// DOMString dp;
-// DOMString dq;
-// DOMString qi;
-// sequence<RsaOtherPrimesInfo> oth;
-// DOMString k;
-// };
-//
-// dictionary RsaOtherPrimesInfo {
-// DOMString r;
-// DOMString d;
-// DOMString t;
-// };
-static bool ParseJsonWebKey(const Dictionary& dict,
+static bool ParseJsonWebKey(const JsonWebKey& key,
WebVector<uint8_t>& json_utf8,
CryptoResult* result) {
- // TODO(eroman): This implementation is incomplete and not spec compliant:
- // * Properties need to be read in the definition order above
- // * Preserve the type of optional parameters (crbug.com/385376)
- // * Parse "oth" (crbug.com/441396)
- // * Fail with TypeError (not DataError) if the input does not conform
- // to a JsonWebKey
auto json_object = std::make_unique<JSONObject>();
- if (!CopyStringProperty("kty", dict, json_object.get())) {
- result->CompleteWithError(kWebCryptoErrorTypeData,
- "The required JWK member \"kty\" was missing");
- return false;
+ if (key.hasKty())
+ json_object->SetString("kty", key.kty());
+ if (key.hasUse())
+ json_object->SetString("use", key.use());
+ if (key.hasKeyOps()) {
+ auto json_array = std::make_unique<JSONArray>();
+ for (auto&& value : key.keyOps())
+ json_array->PushString(value);
+ json_object->SetArray("key_ops", std::move(json_array));
}
-
- CopyStringProperty("use", dict, json_object.get());
- CopySequenceOfStringProperty("key_ops", dict, json_object.get());
- CopyStringProperty("alg", dict, json_object.get());
-
- bool ext;
- if (DictionaryHelper::Get(dict, "ext", ext))
- json_object->SetBoolean("ext", ext);
-
- const char* const kPropertyNames[] = {"d", "n", "e", "p", "q", "dp",
- "dq", "qi", "k", "crv", "x", "y"};
- for (unsigned i = 0; i < base::size(kPropertyNames); ++i)
- CopyStringProperty(kPropertyNames[i], dict, json_object.get());
+ if (key.hasAlg())
+ json_object->SetString("alg", key.alg());
+ if (key.hasExt())
+ json_object->SetBoolean("ext", key.ext());
+
+ if (key.hasCrv())
+ json_object->SetString("crv", key.crv());
+ if (key.hasX())
+ json_object->SetString("x", key.x());
+ if (key.hasY())
+ json_object->SetString("y", key.y());
+ if (key.hasD())
+ json_object->SetString("d", key.d());
+ if (key.hasN())
+ json_object->SetString("n", key.n());
+ if (key.hasE())
+ json_object->SetString("e", key.e());
+ if (key.hasP())
+ json_object->SetString("p", key.p());
+ if (key.hasQ())
+ json_object->SetString("q", key.q());
+ if (key.hasDp())
+ json_object->SetString("dp", key.dp());
+ if (key.hasDq())
+ json_object->SetString("dq", key.dq());
+ if (key.hasQi())
+ json_object->SetString("qi", key.qi());
+ // TODO(eroman): Parse "oth" (crbug.com/441396)
+ if (key.hasK())
+ json_object->SetString("k", key.k());
String json = json_object->ToJSONString();
json_utf8 = WebVector<uint8_t>(json.Utf8().c_str(), json.Utf8().length());
@@ -163,13 +117,11 @@ SubtleCrypto::SubtleCrypto() = default;
ScriptPromise SubtleCrypto::encrypt(ScriptState* script_state,
const AlgorithmIdentifier& raw_algorithm,
CryptoKey* key,
- const BufferSource& raw_data) {
+ const BufferSource& raw_data,
+ ExceptionState& exception_state) {
// Method described by:
// https://w3c.github.io/webcrypto/Overview.html#dfn-SubtleCrypto-method-encrypt
- auto* result = MakeGarbageCollected<CryptoResultImpl>(script_state);
- ScriptPromise promise = result->Promise();
-
// 14.3.1.2: Let data be the result of getting a copy of the bytes held by
// the data parameter passed to the encrypt method.
WebVector<uint8_t> data = CopyBytes(raw_data);
@@ -177,9 +129,13 @@ ScriptPromise SubtleCrypto::encrypt(ScriptState* script_state,
// 14.3.1.3: Let normalizedAlgorithm be the result of normalizing an
// algorithm, with alg set to algorithm and op set to "encrypt".
WebCryptoAlgorithm normalized_algorithm;
- if (!ParseAlgorithm(raw_algorithm, kWebCryptoOperationEncrypt,
- normalized_algorithm, result))
- return promise;
+ if (!NormalizeAlgorithm(script_state->GetIsolate(), raw_algorithm,
+ kWebCryptoOperationEncrypt, normalized_algorithm,
+ exception_state))
+ return ScriptPromise();
+
+ auto* result = MakeGarbageCollected<CryptoResultImpl>(script_state);
+ ScriptPromise promise = result->Promise();
// 14.3.1.8: If the name member of normalizedAlgorithm is not equal to the
// name attribute of the [[algorithm]] internal slot of key then
@@ -205,13 +161,11 @@ ScriptPromise SubtleCrypto::encrypt(ScriptState* script_state,
ScriptPromise SubtleCrypto::decrypt(ScriptState* script_state,
const AlgorithmIdentifier& raw_algorithm,
CryptoKey* key,
- const BufferSource& raw_data) {
+ const BufferSource& raw_data,
+ ExceptionState& exception_state) {
// Method described by:
// https://w3c.github.io/webcrypto/Overview.html#dfn-SubtleCrypto-method-decrypt
- auto* result = MakeGarbageCollected<CryptoResultImpl>(script_state);
- ScriptPromise promise = result->Promise();
-
// 14.3.2.2: Let data be the result of getting a copy of the bytes held by
// the data parameter passed to the decrypt method.
WebVector<uint8_t> data = CopyBytes(raw_data);
@@ -219,9 +173,13 @@ ScriptPromise SubtleCrypto::decrypt(ScriptState* script_state,
// 14.3.2.3: Let normalizedAlgorithm be the result of normalizing an
// algorithm, with alg set to algorithm and op set to "decrypt".
WebCryptoAlgorithm normalized_algorithm;
- if (!ParseAlgorithm(raw_algorithm, kWebCryptoOperationDecrypt,
- normalized_algorithm, result))
- return promise;
+ if (!NormalizeAlgorithm(script_state->GetIsolate(), raw_algorithm,
+ kWebCryptoOperationDecrypt, normalized_algorithm,
+ exception_state))
+ return ScriptPromise();
+
+ auto* result = MakeGarbageCollected<CryptoResultImpl>(script_state);
+ ScriptPromise promise = result->Promise();
// 14.3.2.8: If the name member of normalizedAlgorithm is not equal to the
// name attribute of the [[algorithm]] internal slot of key then
@@ -247,13 +205,11 @@ ScriptPromise SubtleCrypto::decrypt(ScriptState* script_state,
ScriptPromise SubtleCrypto::sign(ScriptState* script_state,
const AlgorithmIdentifier& raw_algorithm,
CryptoKey* key,
- const BufferSource& raw_data) {
+ const BufferSource& raw_data,
+ ExceptionState& exception_state) {
// Method described by:
// https://w3c.github.io/webcrypto/Overview.html#dfn-SubtleCrypto-method-sign
- auto* result = MakeGarbageCollected<CryptoResultImpl>(script_state);
- ScriptPromise promise = result->Promise();
-
// 14.3.3.2: Let data be the result of getting a copy of the bytes held by
// the data parameter passed to the sign method.
WebVector<uint8_t> data = CopyBytes(raw_data);
@@ -261,9 +217,13 @@ ScriptPromise SubtleCrypto::sign(ScriptState* script_state,
// 14.3.3.3: Let normalizedAlgorithm be the result of normalizing an
// algorithm, with alg set to algorithm and op set to "sign".
WebCryptoAlgorithm normalized_algorithm;
- if (!ParseAlgorithm(raw_algorithm, kWebCryptoOperationSign,
- normalized_algorithm, result))
- return promise;
+ if (!NormalizeAlgorithm(script_state->GetIsolate(), raw_algorithm,
+ kWebCryptoOperationSign, normalized_algorithm,
+ exception_state))
+ return ScriptPromise();
+
+ auto* result = MakeGarbageCollected<CryptoResultImpl>(script_state);
+ ScriptPromise promise = result->Promise();
// 14.3.3.8: If the name member of normalizedAlgorithm is not equal to the
// name attribute of the [[algorithm]] internal slot of key then
@@ -291,13 +251,11 @@ ScriptPromise SubtleCrypto::verifySignature(
const AlgorithmIdentifier& raw_algorithm,
CryptoKey* key,
const BufferSource& raw_signature,
- const BufferSource& raw_data) {
+ const BufferSource& raw_data,
+ ExceptionState& exception_state) {
// Method described by:
// https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-verify
- auto* result = MakeGarbageCollected<CryptoResultImpl>(script_state);
- ScriptPromise promise = result->Promise();
-
// 14.3.4.2: Let signature be the result of getting a copy of the bytes
// held by the signature parameter passed to the verify method.
WebVector<uint8_t> signature = CopyBytes(raw_signature);
@@ -309,9 +267,13 @@ ScriptPromise SubtleCrypto::verifySignature(
// 14.3.4.4: Let normalizedAlgorithm be the result of normalizing an
// algorithm, with alg set to algorithm and op set to "verify".
WebCryptoAlgorithm normalized_algorithm;
- if (!ParseAlgorithm(raw_algorithm, kWebCryptoOperationVerify,
- normalized_algorithm, result))
- return promise;
+ if (!NormalizeAlgorithm(script_state->GetIsolate(), raw_algorithm,
+ kWebCryptoOperationVerify, normalized_algorithm,
+ exception_state))
+ return ScriptPromise();
+
+ auto* result = MakeGarbageCollected<CryptoResultImpl>(script_state);
+ ScriptPromise promise = result->Promise();
// 14.3.4.9: If the name member of normalizedAlgorithm is not equal to the
// name attribute of the [[algorithm]] internal slot of key then
@@ -336,13 +298,11 @@ ScriptPromise SubtleCrypto::verifySignature(
ScriptPromise SubtleCrypto::digest(ScriptState* script_state,
const AlgorithmIdentifier& raw_algorithm,
- const BufferSource& raw_data) {
+ const BufferSource& raw_data,
+ ExceptionState& exception_state) {
// Method described by:
// https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-digest
- auto* result = MakeGarbageCollected<CryptoResultImpl>(script_state);
- ScriptPromise promise = result->Promise();
-
// 14.3.5.2: Let data be the result of getting a copy of the bytes held
// by the data parameter passed to the digest method.
WebVector<uint8_t> data = CopyBytes(raw_data);
@@ -350,10 +310,12 @@ ScriptPromise SubtleCrypto::digest(ScriptState* script_state,
// 14.3.5.3: Let normalizedAlgorithm be the result of normalizing an
// algorithm, with alg set to algorithm and op set to "digest".
WebCryptoAlgorithm normalized_algorithm;
- if (!ParseAlgorithm(raw_algorithm, kWebCryptoOperationDigest,
- normalized_algorithm, result))
- return promise;
+ if (!NormalizeAlgorithm(script_state->GetIsolate(), raw_algorithm,
+ kWebCryptoOperationDigest, normalized_algorithm,
+ exception_state))
+ return ScriptPromise();
+ auto* result = MakeGarbageCollected<CryptoResultImpl>(script_state);
HistogramAlgorithm(ExecutionContext::From(script_state),
normalized_algorithm);
scoped_refptr<base::SingleThreadTaskRunner> task_runner =
@@ -362,14 +324,15 @@ ScriptPromise SubtleCrypto::digest(ScriptState* script_state,
Platform::Current()->Crypto()->Digest(normalized_algorithm, std::move(data),
result->Result(),
std::move(task_runner));
- return promise;
+ return result->Promise();
}
ScriptPromise SubtleCrypto::generateKey(
ScriptState* script_state,
const AlgorithmIdentifier& raw_algorithm,
bool extractable,
- const Vector<String>& raw_key_usages) {
+ const Vector<String>& raw_key_usages,
+ ExceptionState& exception_state) {
// Method described by:
// https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-generateKey
@@ -384,9 +347,10 @@ ScriptPromise SubtleCrypto::generateKey(
// algorithm, with alg set to algorithm and op set to
// "generateKey".
WebCryptoAlgorithm normalized_algorithm;
- if (!ParseAlgorithm(raw_algorithm, kWebCryptoOperationGenerateKey,
- normalized_algorithm, result))
- return promise;
+ if (!NormalizeAlgorithm(script_state->GetIsolate(), raw_algorithm,
+ kWebCryptoOperationGenerateKey, normalized_algorithm,
+ exception_state))
+ return ScriptPromise();
// NOTE: Steps (8) and (9) disallow empty usages on secret and private
// keys. This normative requirement is enforced by the platform
@@ -406,10 +370,11 @@ ScriptPromise SubtleCrypto::generateKey(
ScriptPromise SubtleCrypto::importKey(
ScriptState* script_state,
const String& raw_format,
- const ArrayBufferOrArrayBufferViewOrDictionary& raw_key_data,
+ const ArrayBufferOrArrayBufferViewOrJsonWebKey& raw_key_data,
const AlgorithmIdentifier& raw_algorithm,
bool extractable,
- const Vector<String>& raw_key_usages) {
+ const Vector<String>& raw_key_usages,
+ ExceptionState& exception_state) {
// Method described by:
// https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-importKey
@@ -458,11 +423,8 @@ ScriptPromise SubtleCrypto::importKey(
// (2) Let keyData be the keyData parameter passed to the importKey
// method.
case kWebCryptoKeyFormatJwk:
- if (raw_key_data.IsDictionary()) {
- // TODO(eroman): To match the spec error order, parsing of the
- // JsonWebKey should be done earlier (at the WebIDL layer of
- // parameter checking), regardless of the format being "jwk".
- if (!ParseJsonWebKey(raw_key_data.GetAsDictionary(), key_data, result))
+ if (raw_key_data.IsJsonWebKey()) {
+ if (!ParseJsonWebKey(*raw_key_data.GetAsJsonWebKey(), key_data, result))
return promise;
} else {
result->CompleteWithError(kWebCryptoErrorTypeType,
@@ -476,9 +438,10 @@ ScriptPromise SubtleCrypto::importKey(
// algorithm, with alg set to algorithm and op set to
// "importKey".
WebCryptoAlgorithm normalized_algorithm;
- if (!ParseAlgorithm(raw_algorithm, kWebCryptoOperationImportKey,
- normalized_algorithm, result))
- return promise;
+ if (!NormalizeAlgorithm(script_state->GetIsolate(), raw_algorithm,
+ kWebCryptoOperationImportKey, normalized_algorithm,
+ exception_state))
+ return ScriptPromise();
HistogramAlgorithm(ExecutionContext::From(script_state),
normalized_algorithm);
@@ -526,7 +489,8 @@ ScriptPromise SubtleCrypto::wrapKey(
const String& raw_format,
CryptoKey* key,
CryptoKey* wrapping_key,
- const AlgorithmIdentifier& raw_wrap_algorithm) {
+ const AlgorithmIdentifier& raw_wrap_algorithm,
+ ExceptionState& exception_state) {
// Method described by:
// https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-wrapKey
@@ -544,9 +508,10 @@ ScriptPromise SubtleCrypto::wrapKey(
// of normalizing an algorithm, with alg set to algorithm and op
// set to "encrypt".
WebCryptoAlgorithm normalized_algorithm;
- if (!ParseAlgorithm(raw_wrap_algorithm, kWebCryptoOperationWrapKey,
- normalized_algorithm, result))
- return promise;
+ if (!NormalizeAlgorithm(script_state->GetIsolate(), raw_wrap_algorithm,
+ kWebCryptoOperationWrapKey, normalized_algorithm,
+ exception_state))
+ return ScriptPromise();
// 14.3.11.9: If the name member of normalizedAlgorithm is not equal to the
// name attribute of the [[algorithm]] internal slot of
@@ -591,7 +556,8 @@ ScriptPromise SubtleCrypto::unwrapKey(
const AlgorithmIdentifier& raw_unwrap_algorithm,
const AlgorithmIdentifier& raw_unwrapped_key_algorithm,
bool extractable,
- const Vector<String>& raw_key_usages) {
+ const Vector<String>& raw_key_usages,
+ ExceptionState& exception_state) {
// Method described by:
// https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-unwrapKey
@@ -619,17 +585,20 @@ ScriptPromise SubtleCrypto::unwrapKey(
// of normalizing an algorithm, with alg set to algorithm and op
// set to "decrypt".
WebCryptoAlgorithm normalized_algorithm;
- if (!ParseAlgorithm(raw_unwrap_algorithm, kWebCryptoOperationUnwrapKey,
- normalized_algorithm, result))
- return promise;
+ if (!NormalizeAlgorithm(script_state->GetIsolate(), raw_unwrap_algorithm,
+ kWebCryptoOperationUnwrapKey, normalized_algorithm,
+ exception_state))
+ return ScriptPromise();
// 14.3.12.6: Let normalizedKeyAlgorithm be the result of normalizing an
// algorithm, with alg set to unwrappedKeyAlgorithm and op set
// to "importKey".
WebCryptoAlgorithm normalized_key_algorithm;
- if (!ParseAlgorithm(raw_unwrapped_key_algorithm, kWebCryptoOperationImportKey,
- normalized_key_algorithm, result))
- return promise;
+ if (!NormalizeAlgorithm(script_state->GetIsolate(),
+ raw_unwrapped_key_algorithm,
+ kWebCryptoOperationImportKey,
+ normalized_key_algorithm, exception_state))
+ return ScriptPromise();
// 14.3.12.11: If the name member of normalizedAlgorithm is not equal to
// the name attribute of the [[algorithm]] internal slot of
@@ -663,20 +632,19 @@ ScriptPromise SubtleCrypto::unwrapKey(
ScriptPromise SubtleCrypto::deriveBits(ScriptState* script_state,
const AlgorithmIdentifier& raw_algorithm,
CryptoKey* base_key,
- unsigned length_bits) {
+ unsigned length_bits,
+ ExceptionState& exception_state) {
// Method described by:
// https://w3c.github.io/webcrypto/Overview.html#dfn-SubtleCrypto-method-deriveBits
- auto* result = MakeGarbageCollected<CryptoResultImpl>(script_state);
- ScriptPromise promise = result->Promise();
-
// 14.3.8.2: Let normalizedAlgorithm be the result of normalizing an
// algorithm, with alg set to algorithm and op set to
// "deriveBits".
WebCryptoAlgorithm normalized_algorithm;
- if (!ParseAlgorithm(raw_algorithm, kWebCryptoOperationDeriveBits,
- normalized_algorithm, result))
- return promise;
+ if (!NormalizeAlgorithm(script_state->GetIsolate(), raw_algorithm,
+ kWebCryptoOperationDeriveBits, normalized_algorithm,
+ exception_state))
+ return ScriptPromise();
// 14.3.8.7: If the name member of normalizedAlgorithm is not equal to the
// name attribute of the [[algorithm]] internal slot of baseKey
@@ -684,6 +652,9 @@ ScriptPromise SubtleCrypto::deriveBits(ScriptState* script_state,
//
// 14.3.8.8: If the [[usages]] internal slot of baseKey does not contain an
// entry that is "deriveBits", then throw an InvalidAccessError.
+ auto* result = MakeGarbageCollected<CryptoResultImpl>(script_state);
+ ScriptPromise promise = result->Promise();
+
if (!base_key->CanBeUsedForAlgorithm(normalized_algorithm,
kWebCryptoKeyUsageDeriveBits, result))
return promise;
@@ -705,7 +676,8 @@ ScriptPromise SubtleCrypto::deriveKey(
CryptoKey* base_key,
const AlgorithmIdentifier& raw_derived_key_type,
bool extractable,
- const Vector<String>& raw_key_usages) {
+ const Vector<String>& raw_key_usages,
+ ExceptionState& exception_state) {
// Method described by:
// https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-deriveKey
@@ -720,17 +692,19 @@ ScriptPromise SubtleCrypto::deriveKey(
// algorithm, with alg set to algorithm and op set to
// "deriveBits".
WebCryptoAlgorithm normalized_algorithm;
- if (!ParseAlgorithm(raw_algorithm, kWebCryptoOperationDeriveBits,
- normalized_algorithm, result))
- return promise;
+ if (!NormalizeAlgorithm(script_state->GetIsolate(), raw_algorithm,
+ kWebCryptoOperationDeriveBits, normalized_algorithm,
+ exception_state))
+ return ScriptPromise();
// 14.3.7.4: Let normalizedDerivedKeyAlgorithm be the result of normalizing
// an algorithm, with alg set to derivedKeyType and op set to
// "importKey".
WebCryptoAlgorithm normalized_derived_key_algorithm;
- if (!ParseAlgorithm(raw_derived_key_type, kWebCryptoOperationImportKey,
- normalized_derived_key_algorithm, result))
- return promise;
+ if (!NormalizeAlgorithm(script_state->GetIsolate(), raw_derived_key_type,
+ kWebCryptoOperationImportKey,
+ normalized_derived_key_algorithm, exception_state))
+ return ScriptPromise();
// TODO(eroman): The description in the spec needs to be updated as
// it doesn't describe algorithm normalization for the Get Key
@@ -741,9 +715,10 @@ ScriptPromise SubtleCrypto::deriveKey(
// identify a registered algorithm that supports the get key length
// operation, then throw a NotSupportedError.
WebCryptoAlgorithm key_length_algorithm;
- if (!ParseAlgorithm(raw_derived_key_type, kWebCryptoOperationGetKeyLength,
- key_length_algorithm, result))
- return promise;
+ if (!NormalizeAlgorithm(script_state->GetIsolate(), raw_derived_key_type,
+ kWebCryptoOperationGetKeyLength, key_length_algorithm,
+ exception_state))
+ return ScriptPromise();
// 14.3.7.11: If the name member of normalizedAlgorithm is not equal to the
// name attribute of the [[algorithm]] internal slot of baseKey
diff --git a/chromium/third_party/blink/renderer/modules/crypto/subtle_crypto.h b/chromium/third_party/blink/renderer/modules/crypto/subtle_crypto.h
index e112079f66c..8e9d8154617 100644
--- a/chromium/third_party/blink/renderer/modules/crypto/subtle_crypto.h
+++ b/chromium/third_party/blink/renderer/modules/crypto/subtle_crypto.h
@@ -33,18 +33,17 @@
#include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
-#include "third_party/blink/renderer/bindings/modules/v8/array_buffer_or_array_buffer_view_or_dictionary.h"
-#include "third_party/blink/renderer/bindings/modules/v8/dictionary_or_string.h"
+#include "third_party/blink/renderer/modules/crypto/normalize_algorithm.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/wtf/forward.h"
namespace blink {
+class ArrayBufferOrArrayBufferViewOrJsonWebKey;
class CryptoKey;
-typedef ArrayBufferOrArrayBufferView BufferSource;
-typedef DictionaryOrString AlgorithmIdentifier;
+using BufferSource = ArrayBufferOrArrayBufferView;
class SubtleCrypto final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
@@ -55,43 +54,51 @@ class SubtleCrypto final : public ScriptWrappable {
ScriptPromise encrypt(ScriptState*,
const AlgorithmIdentifier&,
CryptoKey*,
- const BufferSource&);
+ const BufferSource&,
+ ExceptionState&);
ScriptPromise decrypt(ScriptState*,
const AlgorithmIdentifier&,
CryptoKey*,
- const BufferSource&);
+ const BufferSource&,
+ ExceptionState&);
ScriptPromise sign(ScriptState*,
const AlgorithmIdentifier&,
CryptoKey*,
- const BufferSource&);
+ const BufferSource&,
+ ExceptionState&);
// Note that this is not named "verify" because when compiling on Mac that
// expands to a macro and breaks.
ScriptPromise verifySignature(ScriptState*,
const AlgorithmIdentifier&,
CryptoKey*,
const BufferSource& signature,
- const BufferSource& data);
+ const BufferSource& data,
+ ExceptionState&);
ScriptPromise digest(ScriptState*,
const AlgorithmIdentifier&,
- const BufferSource& data);
+ const BufferSource& data,
+ ExceptionState&);
ScriptPromise generateKey(ScriptState*,
const AlgorithmIdentifier&,
bool extractable,
- const Vector<String>& key_usages);
+ const Vector<String>& key_usages,
+ ExceptionState&);
ScriptPromise importKey(ScriptState*,
const String&,
- const ArrayBufferOrArrayBufferViewOrDictionary&,
+ const ArrayBufferOrArrayBufferViewOrJsonWebKey&,
const AlgorithmIdentifier&,
bool extractable,
- const Vector<String>& key_usages);
+ const Vector<String>& key_usages,
+ ExceptionState&);
ScriptPromise exportKey(ScriptState*, const String&, CryptoKey*);
ScriptPromise wrapKey(ScriptState*,
const String&,
CryptoKey*,
CryptoKey*,
- const AlgorithmIdentifier&);
+ const AlgorithmIdentifier&,
+ ExceptionState&);
ScriptPromise unwrapKey(ScriptState*,
const String&,
const BufferSource&,
@@ -99,18 +106,21 @@ class SubtleCrypto final : public ScriptWrappable {
const AlgorithmIdentifier&,
const AlgorithmIdentifier&,
bool,
- const Vector<String>&);
+ const Vector<String>&,
+ ExceptionState&);
ScriptPromise deriveBits(ScriptState*,
const AlgorithmIdentifier&,
CryptoKey*,
- unsigned);
+ unsigned,
+ ExceptionState&);
ScriptPromise deriveKey(ScriptState*,
const AlgorithmIdentifier&,
CryptoKey*,
const AlgorithmIdentifier&,
bool extractable,
- const Vector<String>&);
+ const Vector<String>&,
+ ExceptionState&);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/crypto/subtle_crypto.idl b/chromium/third_party/blink/renderer/modules/crypto/subtle_crypto.idl
index e7287cba725..f7f0c8f0c28 100644
--- a/chromium/third_party/blink/renderer/modules/crypto/subtle_crypto.idl
+++ b/chromium/third_party/blink/renderer/modules/crypto/subtle_crypto.idl
@@ -32,24 +32,25 @@
typedef DOMString KeyFormat;
typedef DOMString KeyUsage;
-typedef (Dictionary or DOMString) AlgorithmIdentifier;
+typedef (object or DOMString) AlgorithmIdentifier;
[
+ SecureContext,
Exposed=(Window,Worker)
] interface SubtleCrypto {
- [CallWith=ScriptState, MeasureAs=SubtleCryptoEncrypt] Promise<any> encrypt(AlgorithmIdentifier algorithm, CryptoKey key, BufferSource data);
- [CallWith=ScriptState, MeasureAs=SubtleCryptoDecrypt] Promise<any> decrypt(AlgorithmIdentifier algorithm, CryptoKey key, BufferSource data);
- [CallWith=ScriptState, MeasureAs=SubtleCryptoSign] Promise<any> sign(AlgorithmIdentifier algorithm, CryptoKey key, BufferSource data);
- [CallWith=ScriptState, ImplementedAs=verifySignature, MeasureAs=SubtleCryptoVerify] Promise<any> verify(AlgorithmIdentifier algorithm, CryptoKey key, BufferSource signature, BufferSource data);
- [CallWith=ScriptState, MeasureAs=SubtleCryptoDigest] Promise<any> digest(AlgorithmIdentifier algorithm, BufferSource data);
+ [CallWith=ScriptState, MeasureAs=SubtleCryptoEncrypt, RaisesException] Promise<any> encrypt(AlgorithmIdentifier algorithm, CryptoKey key, BufferSource data);
+ [CallWith=ScriptState, MeasureAs=SubtleCryptoDecrypt, RaisesException] Promise<any> decrypt(AlgorithmIdentifier algorithm, CryptoKey key, BufferSource data);
+ [CallWith=ScriptState, MeasureAs=SubtleCryptoSign, RaisesException] Promise<any> sign(AlgorithmIdentifier algorithm, CryptoKey key, BufferSource data);
+ [CallWith=ScriptState, ImplementedAs=verifySignature, MeasureAs=SubtleCryptoVerify, RaisesException] Promise<any> verify(AlgorithmIdentifier algorithm, CryptoKey key, BufferSource signature, BufferSource data);
+ [CallWith=ScriptState, MeasureAs=SubtleCryptoDigest, RaisesException] Promise<any> digest(AlgorithmIdentifier algorithm, BufferSource data);
- [CallWith=ScriptState, MeasureAs=SubtleCryptoGenerateKey] Promise<any> generateKey(AlgorithmIdentifier algorithm, boolean extractable, sequence<KeyUsage> keyUsages);
- [CallWith=ScriptState, MeasureAs=SubtleCryptoDeriveKey] Promise<any> deriveKey(AlgorithmIdentifier algorithm, CryptoKey baseKey, AlgorithmIdentifier derivedKeyType, boolean extractable, sequence<KeyUsage> keyUsages);
- [CallWith=ScriptState, MeasureAs=SubtleCryptoDeriveBits] Promise<ArrayBuffer> deriveBits(AlgorithmIdentifier algorithm, CryptoKey baseKey, unsigned long length);
+ [CallWith=ScriptState, MeasureAs=SubtleCryptoGenerateKey, RaisesException] Promise<any> generateKey(AlgorithmIdentifier algorithm, boolean extractable, sequence<KeyUsage> keyUsages);
+ [CallWith=ScriptState, MeasureAs=SubtleCryptoDeriveKey, RaisesException] Promise<any> deriveKey(AlgorithmIdentifier algorithm, CryptoKey baseKey, AlgorithmIdentifier derivedKeyType, boolean extractable, sequence<KeyUsage> keyUsages);
+ [CallWith=ScriptState, MeasureAs=SubtleCryptoDeriveBits, RaisesException] Promise<ArrayBuffer> deriveBits(AlgorithmIdentifier algorithm, CryptoKey baseKey, unsigned long length);
- [CallWith=ScriptState, MeasureAs=SubtleCryptoImportKey] Promise<CryptoKey> importKey(KeyFormat format, (ArrayBuffer or ArrayBufferView or Dictionary) keyData, AlgorithmIdentifier algorithm, boolean extractable, sequence<KeyUsage> keyUsages);
+ [CallWith=ScriptState, MeasureAs=SubtleCryptoImportKey, RaisesException] Promise<CryptoKey> importKey(KeyFormat format, (BufferSource or JsonWebKey) keyData, AlgorithmIdentifier algorithm, boolean extractable, sequence<KeyUsage> keyUsages);
[CallWith=ScriptState, MeasureAs=SubtleCryptoExportKey] Promise<any> exportKey(KeyFormat format, CryptoKey key);
- [CallWith=ScriptState, MeasureAs=SubtleCryptoWrapKey] Promise<any> wrapKey(KeyFormat format, CryptoKey key, CryptoKey wrappingKey, AlgorithmIdentifier wrapAlgorithm);
- [CallWith=ScriptState, MeasureAs=SubtleCryptoUnwrapKey] Promise<CryptoKey> unwrapKey(KeyFormat format, BufferSource wrappedKey, CryptoKey unwrappingKey, AlgorithmIdentifier unwrapAlgorithm, AlgorithmIdentifier unwrappedKeyAlgorithm, boolean extractable, sequence<KeyUsage> keyUsages);
+ [CallWith=ScriptState, MeasureAs=SubtleCryptoWrapKey, RaisesException] Promise<any> wrapKey(KeyFormat format, CryptoKey key, CryptoKey wrappingKey, AlgorithmIdentifier wrapAlgorithm);
+ [CallWith=ScriptState, MeasureAs=SubtleCryptoUnwrapKey, RaisesException] Promise<CryptoKey> unwrapKey(KeyFormat format, BufferSource wrappedKey, CryptoKey unwrappingKey, AlgorithmIdentifier unwrapAlgorithm, AlgorithmIdentifier unwrappedKeyAlgorithm, boolean extractable, sequence<KeyUsage> keyUsages);
};
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 5f0b33f0e9a..edcbb9ae64a 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(blink::Visitor* visitor) {
+void WorkerGlobalScopeCrypto::Trace(Visitor* visitor) {
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 a18c59312e3..fceb0c09941 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
mutable Member<Crypto> crypto_;
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 d885536893d..5e0a3168f8c 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
@@ -5,10 +5,10 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CSSPAINT_CSS_PAINT_DEFINITION_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_CSSPAINT_CSS_PAINT_DEFINITION_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_paint_rendering_context_2d_settings.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/cssom/css_style_value.h"
-#include "third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d_settings.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -72,7 +72,7 @@ class MODULES_EXPORT CSSPaintDefinition final
ScriptState* GetScriptState() const { return script_state_; }
- virtual void Trace(blink::Visitor* visitor);
+ virtual void Trace(Visitor* visitor);
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 1e118044105..2df94870e00 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(blink::Visitor* visitor) {
+void CSSPaintImageGeneratorImpl::Trace(Visitor* visitor) {
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 4fd137f9ca0..ab77c331d57 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
// Used for main-thread CSS Paint.
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/idls.gni b/chromium/third_party/blink/renderer/modules/csspaint/idls.gni
new file mode 100644
index 00000000000..2395e7fef58
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/csspaint/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "paint_rendering_context_2d.idl",
+ "paint_size.idl",
+ "paint_worklet_global_scope.idl",
+]
+
+modules_dictionary_idl_files = [ "paint_rendering_context_2d_settings.idl" ]
+
+modules_dependency_idl_files = [ "css_paint_worklet.idl" ]
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.cc b/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.cc
index f29a220fa01..ed797d28801 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.cc
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.cc
@@ -23,8 +23,8 @@ PaintRenderingContext2D::PaintRenderingContext2D(
clip_antialiasing_ = kAntiAliased;
ModifiableState().SetShouldAntialias(true);
- Canvas()->clear(context_settings->alpha() ? SK_ColorTRANSPARENT
- : SK_ColorBLACK);
+ GetPaintCanvas()->clear(context_settings->alpha() ? SK_ColorTRANSPARENT
+ : SK_ColorBLACK);
did_record_draw_commands_in_paint_recorder_ = true;
}
@@ -45,12 +45,6 @@ void PaintRenderingContext2D::InitializePaintRecorder() {
did_record_draw_commands_in_paint_recorder_ = false;
}
-cc::PaintCanvas* PaintRenderingContext2D::Canvas() const {
- DCHECK(paint_recorder_);
- DCHECK(paint_recorder_->getRecordingCanvas());
- return paint_recorder_->getRecordingCanvas();
-}
-
void PaintRenderingContext2D::DidDraw(const SkIRect&) {
did_record_draw_commands_in_paint_recorder_ = true;
}
@@ -102,18 +96,17 @@ void PaintRenderingContext2D::setShadowOffsetY(double y) {
BaseRenderingContext2D::setShadowOffsetY(y * effective_zoom_);
}
-cc::PaintCanvas* PaintRenderingContext2D::DrawingCanvas() const {
- return Canvas();
-}
-
-cc::PaintCanvas* PaintRenderingContext2D::ExistingDrawingCanvas() const {
- return Canvas();
+cc::PaintCanvas* PaintRenderingContext2D::GetPaintCanvas() const {
+ DCHECK(paint_recorder_);
+ DCHECK(paint_recorder_->getRecordingCanvas());
+ return paint_recorder_->getRecordingCanvas();
}
-void PaintRenderingContext2D::ValidateStateStack() const {
+void PaintRenderingContext2D::ValidateStateStackWithCanvas(
+ const cc::PaintCanvas* canvas) const {
#if DCHECK_IS_ON()
- if (cc::PaintCanvas* sk_canvas = ExistingDrawingCanvas()) {
- DCHECK_EQ(static_cast<size_t>(sk_canvas->getSaveCount()),
+ if (canvas) {
+ DCHECK_EQ(static_cast<size_t>(canvas->getSaveCount()),
state_stack_.size() + 1);
}
#endif
@@ -138,26 +131,30 @@ void PaintRenderingContext2D::WillOverwriteCanvas() {
}
}
+DOMMatrix* PaintRenderingContext2D::getTransform() {
+ const AffineTransform& t = GetState().Transform();
+ DOMMatrix* m = DOMMatrix::Create();
+ m->setA(t.A() / effective_zoom_);
+ m->setB(t.B() / effective_zoom_);
+ m->setC(t.C() / effective_zoom_);
+ m->setD(t.D() / effective_zoom_);
+ m->setE(t.E() / effective_zoom_);
+ m->setF(t.F() / effective_zoom_);
+ return m;
+}
+
// On a platform where zoom_for_dsf is not enabled, the recording canvas has its
// logic to account for the device scale factor. Therefore, when the transform
-// of the canvas happen, we must divide the transformation matrix by the device
-// scale factor such that the recording canvas would have the correct behavior.
-void PaintRenderingContext2D::setTransform(double m11,
- double m12,
- double m21,
- double m22,
- double dx,
- double dy) {
- BaseRenderingContext2D::setTransform(
- m11 * effective_zoom_, m12 * effective_zoom_, m21 * effective_zoom_,
- m22 * effective_zoom_, dx * effective_zoom_, dy * effective_zoom_);
-}
-
-void PaintRenderingContext2D::setTransform(DOMMatrix2DInit* transform,
- ExceptionState& exception_state) {
- // The PaintRenderingContext2D APIs are running on worklet thread, therefore
- // it is not possible to construct a DOMMatrix.
- NOTREACHED();
+// of the canvas happen, we must account for the effective_zoom_ such that the
+// recording canvas would have the correct behavior.
+//
+// The BaseRenderingContext2D::setTransform calls resetTransform, so integrating
+// the effective_zoom_ in here instead of setTransform, to avoid integrating it
+// twice if we have resetTransform and setTransform API calls.
+void PaintRenderingContext2D::resetTransform() {
+ BaseRenderingContext2D::resetTransform();
+ BaseRenderingContext2D::transform(effective_zoom_, 0, 0, effective_zoom_, 0,
+ 0);
}
sk_sp<PaintRecord> PaintRenderingContext2D::GetRecord() {
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 bfad30a9ef5..47ccf6cf3f7 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
@@ -8,8 +8,8 @@
#include <memory>
#include "base/macros.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_paint_rendering_context_2d_settings.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h"
-#include "third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d_settings.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/graphics/paint/paint_record.h"
@@ -37,7 +37,7 @@ class MODULES_EXPORT PaintRenderingContext2D : public ScriptWrappable,
float zoom,
float device_scale_factor);
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(context_settings_);
ScriptWrappable::Trace(visitor);
BaseRenderingContext2D::Trace(visitor);
@@ -54,8 +54,8 @@ class MODULES_EXPORT PaintRenderingContext2D : public ScriptWrappable,
bool ParseColorOrCurrentColor(Color&, const String& color_string) const final;
- cc::PaintCanvas* DrawingCanvas() const final;
- cc::PaintCanvas* ExistingDrawingCanvas() const final;
+ cc::PaintCanvas* GetOrCreatePaintCanvas() final { return GetPaintCanvas(); }
+ cc::PaintCanvas* GetPaintCanvas() const final;
void DidDraw(const SkIRect&) final;
@@ -72,7 +72,7 @@ class MODULES_EXPORT PaintRenderingContext2D : public ScriptWrappable,
sk_sp<PaintFilter> StateGetFilter() final;
void SnapshotStateForFilter() final {}
- void ValidateStateStack() const final;
+ void ValidateStateStackWithCanvas(const cc::PaintCanvas*) const final;
bool HasAlpha() const final { return context_settings_->alpha(); }
@@ -84,13 +84,13 @@ class MODULES_EXPORT PaintRenderingContext2D : public ScriptWrappable,
bool CanCreateCanvas2dResourceProvider() const final { return false; }
bool IsAccelerated() const final { return false; }
- void setTransform(double m11,
- double m12,
- double m21,
- double m22,
- double dx,
- double dy) final;
- void setTransform(DOMMatrix2DInit*, ExceptionState&) final;
+ // CSS Paint doesn't have any notion of image orientation.
+ RespectImageOrientationEnum RespectImageOrientation() const final {
+ return kRespectImageOrientation;
+ }
+
+ DOMMatrix* getTransform() final;
+ void resetTransform() final;
sk_sp<PaintRecord> GetRecord();
@@ -100,7 +100,6 @@ class MODULES_EXPORT PaintRenderingContext2D : public ScriptWrappable,
private:
void InitializePaintRecorder();
- cc::PaintCanvas* Canvas() const;
std::unique_ptr<PaintRecorder> paint_recorder_;
sk_sp<PaintRecord> previous_frame_;
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl b/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl
index 0f225228984..94d6d465805 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl
@@ -18,7 +18,7 @@
void transform(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f);
void setTransform(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f);
void resetTransform();
- [RaisesException] void setTransform(optional DOMMatrix2DInit transform);
+ [RaisesException] void setTransform(optional DOMMatrix2DInit transform = {});
DOMMatrix getTransform();
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 e3ce253683b..4be9be6bf83 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.cc
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.cc
@@ -49,7 +49,10 @@ PaintWorklet::PaintWorklet(LocalFrame* frame)
Supplement<LocalDOMWindow>(*frame->DomWindow()),
pending_generator_registry_(
MakeGarbageCollected<PaintWorkletPendingGeneratorRegistry>()),
- worklet_id_(NextId()) {}
+ worklet_id_(NextId()),
+ is_paint_off_thread_(
+ RuntimeEnabledFeatures::OffMainThreadCSSPaintEnabled() &&
+ Thread::CompositorThread()) {}
PaintWorklet::~PaintWorklet() = default;
@@ -58,6 +61,10 @@ void PaintWorklet::AddPendingGenerator(const String& name,
pending_generator_registry_->AddPendingGenerator(name, generator);
}
+void PaintWorklet::ResetIsPaintOffThreadForTesting() {
+ is_paint_off_thread_ = RuntimeEnabledFeatures::OffMainThreadCSSPaintEnabled();
+}
+
// We start with a random global scope when a new frame starts. Then within this
// frame, we switch to the other global scope after certain amount of paint
// calls (rand(kMaxPaintCountToSwitch)).
@@ -137,7 +144,7 @@ scoped_refptr<Image> PaintWorklet::Paint(const String& name,
// static
const char PaintWorklet::kSupplementName[] = "PaintWorklet";
-void PaintWorklet::Trace(blink::Visitor* visitor) {
+void PaintWorklet::Trace(Visitor* visitor) {
visitor->Trace(pending_generator_registry_);
visitor->Trace(proxy_client_);
Worklet::Trace(visitor);
@@ -169,10 +176,9 @@ void PaintWorklet::RegisterCSSPaintDefinition(const String& name,
// regiserered from RegisterCSSPaintDefinition and one extra definition from
// RegisterMainThreadDocumentPaintDefinition if OffMainThreadCSSPaintEnabled
// is true.
- unsigned required_registered_count =
- RuntimeEnabledFeatures::OffMainThreadCSSPaintEnabled()
- ? kNumGlobalScopesPerThread + 1
- : kNumGlobalScopesPerThread;
+ unsigned required_registered_count = is_paint_off_thread_
+ ? kNumGlobalScopesPerThread + 1
+ : kNumGlobalScopesPerThread;
if (existing_document_definition->GetRegisteredDefinitionCount() ==
required_registered_count)
pending_generator_registry_->NotifyGeneratorReady(name);
@@ -229,7 +235,7 @@ void PaintWorklet::RegisterMainThreadDocumentPaintDefinition(
bool PaintWorklet::NeedsToCreateGlobalScope() {
wtf_size_t num_scopes_needed = kNumGlobalScopesPerThread;
// If we are running off main thread, we will need twice as many global scopes
- if (RuntimeEnabledFeatures::OffMainThreadCSSPaintEnabled())
+ if (is_paint_off_thread_)
num_scopes_needed *= 2;
return GetNumberOfGlobalScopes() < num_scopes_needed;
}
@@ -241,16 +247,16 @@ WorkletGlobalScopeProxy* PaintWorklet::CreateGlobalScope() {
// scopes from the beginning of the vector. If this code is changed to put
// the main thread global scopes at the end, then SelectNewGlobalScope must
// also be changed.
- if (!RuntimeEnabledFeatures::OffMainThreadCSSPaintEnabled() ||
+ if (!is_paint_off_thread_ ||
GetNumberOfGlobalScopes() < kNumGlobalScopesPerThread) {
return MakeGarbageCollected<PaintWorkletGlobalScopeProxy>(
- To<Document>(GetExecutionContext())->GetFrame(), ModuleResponsesMap(),
+ Document::From(GetExecutionContext())->GetFrame(), ModuleResponsesMap(),
GetNumberOfGlobalScopes() + 1);
}
if (!proxy_client_) {
proxy_client_ = PaintWorkletProxyClient::Create(
- To<Document>(GetExecutionContext()), worklet_id_);
+ Document::From(GetExecutionContext()), worklet_id_);
}
auto* worker_clients = MakeGarbageCollected<WorkerClients>();
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 dd0ef31e14a..8cd5c5d713f 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// The DocumentDefinitionMap tracks definitions registered via
// registerProperty; definitions are only considered valid once all global
@@ -89,6 +89,8 @@ class MODULES_EXPORT PaintWorklet : public Worklet,
proxy_client_ = proxy_client;
}
+ void ResetIsPaintOffThreadForTesting();
+
protected:
// Since paint worklet has more than one global scope, we MUST override this
// function and provide our own selection logic.
@@ -140,6 +142,12 @@ class MODULES_EXPORT PaintWorklet : public Worklet,
// to ensure that all global scopes get the same proxy client.
Member<PaintWorkletProxyClient> proxy_client_;
+ // When running layout test, paint worklet has to be on the main thread
+ // because "enable-threaded-compositing" is off by default. However, some unit
+ // tests may be testing the functionality of the APIs when the paint worklet
+ // is off the main thread.
+ bool is_paint_off_thread_;
+
DISALLOW_COPY_AND_ASSIGN(PaintWorklet);
};
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 128562b68ac..197c37c57fa 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
@@ -146,7 +146,8 @@ void PaintWorkletGlobalScope::Dispose() {
WorkletGlobalScope::Dispose();
}
-void PaintWorkletGlobalScope::registerPaint(const String& name,
+void PaintWorkletGlobalScope::registerPaint(const ScriptState* script_state,
+ const String& name,
V8NoArgumentConstructor* paint_ctor,
ExceptionState& exception_state) {
// https://drafts.css-houdini.org/css-paint-api/#dom-paintworkletglobalscope-registerpaint
@@ -178,8 +179,11 @@ void PaintWorkletGlobalScope::registerPaint(const String& name,
Vector<CSSPropertyID> native_invalidation_properties;
Vector<AtomicString> custom_invalidation_properties;
+ const ExecutionContext* execution_context =
+ ExecutionContext::From(script_state);
+
if (!V8ObjectParser::ParseCSSPropertyList(
- context, v8_paint_ctor, "inputProperties",
+ context, execution_context, v8_paint_ctor, "inputProperties",
&native_invalidation_properties, &custom_invalidation_properties,
&exception_state))
return;
@@ -238,7 +242,7 @@ double PaintWorkletGlobalScope::devicePixelRatio() const {
: PaintWorkletProxyClient::From(Clients())->DevicePixelRatio();
}
-void PaintWorkletGlobalScope::Trace(blink::Visitor* visitor) {
+void PaintWorkletGlobalScope::Trace(Visitor* visitor) {
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 0c1e72c5398..c444623ff4a 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
@@ -16,6 +16,7 @@ namespace blink {
class CSSPaintDefinition;
class ExceptionState;
+class ScriptState;
class V8NoArgumentConstructor;
class WorkerReportingProxy;
@@ -44,14 +45,15 @@ class MODULES_EXPORT PaintWorkletGlobalScope final : public WorkletGlobalScope {
void Dispose() final;
bool IsPaintWorkletGlobalScope() const final { return true; }
- void registerPaint(const String& name,
+ void registerPaint(const ScriptState* script_state,
+ const String& name,
V8NoArgumentConstructor* paint_ctor,
ExceptionState&);
CSSPaintDefinition* FindDefinition(const String& name);
double devicePixelRatio() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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.idl b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.idl
index bc86a89667a..21bfbf3b990 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.idl
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.idl
@@ -9,7 +9,7 @@
Global=(Worklet,PaintWorklet)
] interface PaintWorkletGlobalScope : WorkletGlobalScope {
[Measure] readonly attribute unrestricted double devicePixelRatio;
- [Measure, RaisesException] void registerPaint(DOMString name, NoArgumentConstructor paintCtor);
+ [Measure, RaisesException, CallWith=ScriptState] void registerPaint(DOMString name, NoArgumentConstructor paintCtor);
};
// Blink-specific type for paint function
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 93a3243767c..7066b64651c 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
@@ -39,15 +39,16 @@ PaintWorkletGlobalScopeProxy::PaintWorkletGlobalScopeProxy(
StringView("PaintWorklet #") + String::Number(global_scope_number);
auto creation_params = std::make_unique<GlobalScopeCreationParams>(
- document->Url(), mojom::ScriptType::kModule,
- OffMainThreadWorkerScriptFetchOption::kEnabled, global_scope_name,
- document->UserAgent(), frame->Client()->CreateWorkerFetchContext(),
+ document->Url(), mojom::blink::ScriptType::kModule, global_scope_name,
+ document->UserAgent(), frame->Client()->UserAgentMetadata(),
+ frame->Client()->CreateWorkerFetchContext(),
document->GetContentSecurityPolicy()->Headers(),
document->GetReferrerPolicy(), document->GetSecurityOrigin(),
document->IsSecureContext(), document->GetHttpsState(),
nullptr /* worker_clients */,
frame->Client()->CreateWorkerContentSettingsClient(),
- document->AddressSpace(), OriginTrialContext::GetTokens(document).get(),
+ document->GetSecurityContext().AddressSpace(),
+ OriginTrialContext::GetTokens(document->ToExecutionContext()).get(),
base::UnguessableToken::Create(), nullptr /* worker_settings */,
kV8CacheOptionsDefault, module_responses_map,
mojo::NullRemote() /* browser_interface_broker */,
@@ -90,7 +91,7 @@ CSSPaintDefinition* PaintWorkletGlobalScopeProxy::FindDefinition(
return global_scope_->FindDefinition(name);
}
-void PaintWorkletGlobalScopeProxy::Trace(blink::Visitor* visitor) {
+void PaintWorkletGlobalScopeProxy::Trace(Visitor* visitor) {
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 8182e1f023f..7206214aa94 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 17c2f4c6907..ec955943eb2 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(blink::Visitor* visitor) {
+void PaintWorkletMessagingProxy::Trace(Visitor* visitor) {
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 7ffb584f2d5..8a745086ca5 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 0243f55a685..0865d7dc2ef 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(blink::Visitor* visitor) {
+void PaintWorkletPendingGeneratorRegistry::Trace(Visitor* visitor) {
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 c1008cc18b8..e65c2c60ff7 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(blink::Visitor*);
+ void Trace(Visitor*);
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 4257b5f86d6..4788e65ede4 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(blink::Visitor* visitor) {
+void PaintWorkletProxyClient::Trace(Visitor* visitor) {
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 8c5f1bc76f1..9df03e61ca3 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// Hooks for testing.
const Vector<CrossThreadPersistent<PaintWorkletGlobalScope>>&
diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_test.cc b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_test.cc
index 4d6f3ad9170..c0e15834492 100644
--- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_test.cc
+++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_test.cc
@@ -26,7 +26,9 @@
namespace blink {
class TestPaintWorklet : public PaintWorklet {
public:
- explicit TestPaintWorklet(LocalFrame* frame) : PaintWorklet(frame) {}
+ explicit TestPaintWorklet(LocalFrame* frame) : PaintWorklet(frame) {
+ ResetIsPaintOffThreadForTesting();
+ }
void SetPaintsToSwitch(int num) { paints_to_switch_ = num; }
@@ -75,7 +77,7 @@ class PaintWorkletTest : public PageTestBase {
size_t expected_num_paints_before_switch,
TestPaintWorklet* paint_worklet_to_test) {
paint_worklet_to_test->GetFrame()->View()->UpdateAllLifecyclePhases(
- DocumentLifecycle::LifecycleUpdateReason::kTest);
+ DocumentUpdateReason::kTest);
paint_worklet_to_test->SetPaintsToSwitch(paint_cnt_to_switch);
size_t previously_selected_global_scope =
paint_worklet_to_test->GetActiveGlobalScope();
@@ -158,8 +160,14 @@ TEST_F(PaintWorkletTest, SinglyRegisteredDocumentDefinitionNotUsed) {
EXPECT_TRUE(generator);
EXPECT_EQ(generator->GetRegisteredDefinitionCountForTesting(), 1u);
DocumentPaintDefinition* definition;
- EXPECT_FALSE(generator->GetValidDocumentDefinitionForTesting(definition));
- EXPECT_FALSE(definition);
+ // Please refer to CSSPaintImageGeneratorImpl::GetValidDocumentDefinition for
+ // the logic.
+ if (RuntimeEnabledFeatures::OffMainThreadCSSPaintEnabled()) {
+ EXPECT_TRUE(generator->GetValidDocumentDefinitionForTesting(definition));
+ } else {
+ EXPECT_FALSE(generator->GetValidDocumentDefinitionForTesting(definition));
+ EXPECT_FALSE(definition);
+ }
}
// In this test, we set a list of "paints_to_switch" numbers, and in each frame,
@@ -225,6 +233,7 @@ class MockObserver final : public CSSPaintImageGenerator::Observer {
TEST_P(MainOrOffThreadPaintWorkletTest, ConsistentGlobalScopeOnMainThread) {
PaintWorklet* paint_worklet_to_test =
PaintWorklet::From(*GetFrame().GetDocument()->domWindow());
+ paint_worklet_to_test->ResetIsPaintOffThreadForTesting();
MockObserver* observer = MakeGarbageCollected<MockObserver>();
CSSPaintImageGeneratorImpl* generator_foo =
@@ -296,6 +305,7 @@ TEST_P(MainOrOffThreadPaintWorkletTest, ConsistentGlobalScopeOnMainThread) {
TEST_P(MainOrOffThreadPaintWorkletTest, AllGlobalScopesMustBeCreated) {
PaintWorklet* paint_worklet_to_test =
MakeGarbageCollected<PaintWorklet>(&GetFrame());
+ paint_worklet_to_test->ResetIsPaintOffThreadForTesting();
EXPECT_TRUE(paint_worklet_to_test->GetGlobalScopesForTesting().IsEmpty());
@@ -323,6 +333,7 @@ TEST_F(PaintWorkletTest, ConsistentGlobalScopeCrossThread) {
ScopedOffMainThreadCSSPaintForTest off_main_thread_css_paint(true);
PaintWorklet* paint_worklet_to_test =
PaintWorklet::From(*GetFrame().GetDocument()->domWindow());
+ paint_worklet_to_test->ResetIsPaintOffThreadForTesting();
MockObserver* observer = MakeGarbageCollected<MockObserver>();
CSSPaintImageGeneratorImpl* generator_foo =
@@ -492,6 +503,7 @@ TEST_F(PaintWorkletTest, GeneratorNotifiedAfterAllRegistrations) {
ScopedOffMainThreadCSSPaintForTest off_main_thread_css_paint(true);
PaintWorklet* paint_worklet_to_test =
PaintWorklet::From(*GetFrame().GetDocument()->domWindow());
+ paint_worklet_to_test->ResetIsPaintOffThreadForTesting();
MockObserver* observer = MakeGarbageCollected<MockObserver>();
CSSPaintImageGeneratorImpl* generator =
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/BUILD.gn b/chromium/third_party/blink/renderer/modules/device_orientation/BUILD.gn
index 3a8e13dc44b..667b4328156 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/BUILD.gn
@@ -37,7 +37,5 @@ blink_modules_sources("device_orientation") {
"dom_window_device_motion.h",
"dom_window_device_orientation.h",
]
- deps = [
- "//services/device/public/mojom:generic_sensor",
- ]
+ deps = [ "//services/device/public/mojom:generic_sensor" ]
}
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/DEPS b/chromium/third_party/blink/renderer/modules/device_orientation/DEPS
index 5538e5bdbd2..e43ee27b34d 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/DEPS
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/DEPS
@@ -1,6 +1,5 @@
include_rules = [
"+base/run_loop.h",
- "+mojo/public/cpp/bindings/binding.h",
"+services/device/public/mojom/sensor.mojom-blink.h",
"+services/device/public/mojom/sensor.mojom-blink-forward.h",
"+services/device/public/mojom/sensor_provider.mojom-blink.h",
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 5bbdf2ebb53..8f0070d208e 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
@@ -8,7 +8,6 @@
#include "third_party/blink/public/platform/platform.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/hosts_using_features.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/modules/device_orientation/device_motion_data.h"
#include "third_party/blink/renderer/modules/device_orientation/device_motion_event.h"
@@ -62,13 +61,9 @@ void DeviceMotionController::DidAddEventListener(
UseCounter::Count(GetDocument(), WebFeature::kDeviceMotionSecureOrigin);
if (!has_event_listener_) {
- if (!IsSameSecurityOriginAsMainFrame()) {
- Platform::Current()->RecordRapporURL(
- "DeviceSensors.DeviceMotionCrossOrigin", WebURL(GetDocument().Url()));
- }
-
- if (!CheckPolicyFeatures({mojom::FeaturePolicyFeature::kAccelerometer,
- mojom::FeaturePolicyFeature::kGyroscope})) {
+ if (!CheckPolicyFeatures(
+ {mojom::blink::FeaturePolicyFeature::kAccelerometer,
+ mojom::blink::FeaturePolicyFeature::kGyroscope})) {
DeviceOrientationController::LogToConsolePolicyFeaturesDisabled(
GetDocument().GetFrame(), EventTypeName());
return;
@@ -110,7 +105,7 @@ Event* DeviceMotionController::LastEvent() const {
}
bool DeviceMotionController::IsNullEvent(Event* event) const {
- DeviceMotionEvent* motion_event = ToDeviceMotionEvent(event);
+ auto* motion_event = To<DeviceMotionEvent>(event);
return !motion_event->GetDeviceMotionData()->CanProvideEventData();
}
@@ -118,7 +113,7 @@ const AtomicString& DeviceMotionController::EventTypeName() const {
return event_type_names::kDevicemotion;
}
-void DeviceMotionController::Trace(blink::Visitor* visitor) {
+void DeviceMotionController::Trace(Visitor* visitor) {
DeviceSingleWindowEventController::Trace(visitor);
visitor->Trace(motion_event_pump_);
Supplement<Document>::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 003d47e399a..dc1274f3fbf 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 6a894f1a561..7ece6d0b274 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
@@ -24,8 +24,8 @@
*/
#include "third_party/blink/renderer/modules/device_orientation/device_motion_data.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_device_motion_event_init.h"
#include "third_party/blink/renderer/modules/device_orientation/device_motion_event_acceleration.h"
-#include "third_party/blink/renderer/modules/device_orientation/device_motion_event_init.h"
#include "third_party/blink/renderer/modules/device_orientation/device_motion_event_rotation_rate.h"
namespace blink {
@@ -70,7 +70,7 @@ DeviceMotionData::DeviceMotionData(
rotation_rate_(rotation_rate),
interval_(interval) {}
-void DeviceMotionData::Trace(blink::Visitor* visitor) {
+void DeviceMotionData::Trace(Visitor* visitor) {
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 2977b282839..0c0cb798b31 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(blink::Visitor*);
+ void Trace(Visitor*);
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 136cf412030..9620836278e 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
@@ -25,9 +25,9 @@
#include "third_party/blink/renderer/modules/device_orientation/device_motion_event.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_device_motion_event_init.h"
#include "third_party/blink/renderer/modules/device_orientation/device_motion_data.h"
#include "third_party/blink/renderer/modules/device_orientation/device_motion_event_acceleration.h"
-#include "third_party/blink/renderer/modules/device_orientation/device_motion_event_init.h"
#include "third_party/blink/renderer/modules/device_orientation/device_motion_event_rotation_rate.h"
namespace blink {
@@ -68,7 +68,7 @@ const AtomicString& DeviceMotionEvent::InterfaceName() const {
return event_interface_names::kDeviceMotionEvent;
}
-void DeviceMotionEvent::Trace(blink::Visitor* visitor) {
+void DeviceMotionEvent::Trace(Visitor* visitor) {
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 9ef6ccd842e..cc05253b058 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
@@ -28,6 +28,7 @@
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -69,19 +70,18 @@ class DeviceMotionEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<const DeviceMotionData> device_motion_data_;
};
-DEFINE_TYPE_CASTS(DeviceMotionEvent,
- Event,
- event,
- event->InterfaceName() ==
- event_interface_names::kDeviceMotionEvent,
- event.InterfaceName() ==
- event_interface_names::kDeviceMotionEvent);
+template <>
+struct DowncastTraits<DeviceMotionEvent> {
+ static bool AllowFrom(const Event& event) {
+ return event.InterfaceName() == event_interface_names::kDeviceMotionEvent;
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.idl b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.idl
index cb204f8b2e0..02ab1141019 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.idl
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.idl
@@ -26,9 +26,9 @@
// https://w3c.github.io/deviceorientation/spec-source-orientation.html#devicemotion
[
- Constructor(DOMString type, optional DeviceMotionEventInit eventInitDict),
Exposed=Window, SecureContext
] interface DeviceMotionEvent : Event {
+ constructor(DOMString type, optional DeviceMotionEventInit eventInitDict = {});
readonly attribute DeviceMotionEventAcceleration? acceleration;
readonly attribute DeviceMotionEventAcceleration? accelerationIncludingGravity;
readonly attribute DeviceMotionEventRotationRate? rotationRate;
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 a72b9ac93bd..50c933175ae 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
@@ -24,7 +24,7 @@
*/
#include "third_party/blink/renderer/modules/device_orientation/device_motion_event_acceleration.h"
-#include "third_party/blink/renderer/modules/device_orientation/device_motion_event_acceleration_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_device_motion_event_acceleration_init.h"
namespace blink {
@@ -51,6 +51,24 @@ bool DeviceMotionEventAcceleration::HasAccelerationData() const {
return !std::isnan(x_) || !std::isnan(y_) || !std::isnan(z_);
}
+base::Optional<double> DeviceMotionEventAcceleration::x() const {
+ if (std::isnan(x_))
+ return base::nullopt;
+ return x_;
+}
+
+base::Optional<double> DeviceMotionEventAcceleration::y() const {
+ if (std::isnan(y_))
+ return base::nullopt;
+ return y_;
+}
+
+base::Optional<double> DeviceMotionEventAcceleration::z() const {
+ if (std::isnan(z_))
+ return base::nullopt;
+ return z_;
+}
+
double DeviceMotionEventAcceleration::x(bool& is_null) const {
is_null = std::isnan(x_);
return x_;
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_acceleration.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_acceleration.h
index 1282e28bcfb..2d6a06fbaab 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_acceleration.h
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_acceleration.h
@@ -46,9 +46,13 @@ class MODULES_EXPORT DeviceMotionEventAcceleration final
bool HasAccelerationData() const;
- double x(bool& is_null) const;
- double y(bool& is_null) const;
- double z(bool& is_null) const;
+ base::Optional<double> x() const;
+ base::Optional<double> y() const;
+ base::Optional<double> z() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ double x(bool& is_null) const; // DEPRECATED
+ double y(bool& is_null) const; // DEPRECATED
+ double z(bool& is_null) const; // DEPRECATED
private:
const double x_;
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 9a020ad4632..f87264f9cbd 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
@@ -61,7 +61,7 @@ DeviceMotionData* DeviceMotionEventPump::LatestDeviceMotionData() {
return data_.Get();
}
-void DeviceMotionEventPump::Trace(blink::Visitor* visitor) {
+void DeviceMotionEventPump::Trace(Visitor* visitor) {
visitor->Trace(accelerometer_);
visitor->Trace(linear_acceleration_sensor_);
visitor->Trace(gyroscope_);
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 caec1ea5b21..e2e1a3d9431 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
@@ -31,7 +31,7 @@ class MODULES_EXPORT DeviceMotionEventPump
// Note that the returned object is owned by this class.
DeviceMotionData* LatestDeviceMotionData();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// DeviceSensorEventPump:
void SendStartMessage(LocalFrame* frame) override;
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 4ce1039690f..19a396e66b4 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
@@ -24,7 +24,7 @@
*/
#include "third_party/blink/renderer/modules/device_orientation/device_motion_event_rotation_rate.h"
-#include "third_party/blink/renderer/modules/device_orientation/device_motion_event_rotation_rate_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_device_motion_event_rotation_rate_init.h"
namespace blink {
@@ -51,6 +51,24 @@ bool DeviceMotionEventRotationRate::HasRotationData() const {
return !std::isnan(alpha_) || !std::isnan(beta_) || !std::isnan(gamma_);
}
+base::Optional<double> DeviceMotionEventRotationRate::alpha() const {
+ if (std::isnan(alpha_))
+ return base::nullopt;
+ return alpha_;
+}
+
+base::Optional<double> DeviceMotionEventRotationRate::beta() const {
+ if (std::isnan(beta_))
+ return base::nullopt;
+ return beta_;
+}
+
+base::Optional<double> DeviceMotionEventRotationRate::gamma() const {
+ if (std::isnan(gamma_))
+ return base::nullopt;
+ return gamma_;
+}
+
double DeviceMotionEventRotationRate::alpha(bool& is_null) const {
is_null = std::isnan(alpha_);
return alpha_;
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_rotation_rate.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_rotation_rate.h
index 2639e0c3bc3..6a91dd46e81 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_rotation_rate.h
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_rotation_rate.h
@@ -48,9 +48,13 @@ class MODULES_EXPORT DeviceMotionEventRotationRate final
bool HasRotationData() const;
- double alpha(bool& is_null) const;
- double beta(bool& is_null) const;
- double gamma(bool& is_null) const;
+ base::Optional<double> alpha() const;
+ base::Optional<double> beta() const;
+ base::Optional<double> gamma() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ double alpha(bool& is_null) const; // DEPRECATED
+ double beta(bool& is_null) const; // DEPRECATED
+ double gamma(bool& is_null) const; // DEPRECATED
private:
const double alpha_;
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 8175847221c..759b391f1e5 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
@@ -61,9 +61,10 @@ void DeviceOrientationAbsoluteController::DidAddEventListener(
if (!has_event_listener_) {
// TODO: add rappor url logging as in DeviceOrientationController.
- if (!CheckPolicyFeatures({mojom::FeaturePolicyFeature::kAccelerometer,
- mojom::FeaturePolicyFeature::kGyroscope,
- mojom::FeaturePolicyFeature::kMagnetometer})) {
+ if (!CheckPolicyFeatures(
+ {mojom::blink::FeaturePolicyFeature::kAccelerometer,
+ mojom::blink::FeaturePolicyFeature::kGyroscope,
+ mojom::blink::FeaturePolicyFeature::kMagnetometer})) {
LogToConsolePolicyFeaturesDisabled(GetDocument().GetFrame(),
EventTypeName());
return;
@@ -77,7 +78,7 @@ const AtomicString& DeviceOrientationAbsoluteController::EventTypeName() const {
return event_type_names::kDeviceorientationabsolute;
}
-void DeviceOrientationAbsoluteController::Trace(blink::Visitor* visitor) {
+void DeviceOrientationAbsoluteController::Trace(Visitor* visitor) {
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 a717cc6ddbc..4661eb8c840 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 876aacbfcee..1d4f829fad4 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
@@ -9,13 +9,13 @@
#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/frame_console.h"
-#include "third_party/blink/renderer/core/frame/hosts_using_features.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/modules/device_orientation/device_orientation_data.h"
#include "third_party/blink/renderer/modules/device_orientation/device_orientation_event.h"
#include "third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.h"
#include "third_party/blink/renderer/modules/event_modules.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
@@ -72,14 +72,9 @@ void DeviceOrientationController::DidAddEventListener(
UseCounter::Count(GetDocument(), WebFeature::kDeviceOrientationSecureOrigin);
if (!has_event_listener_) {
- if (!IsSameSecurityOriginAsMainFrame()) {
- Platform::Current()->RecordRapporURL(
- "DeviceSensors.DeviceOrientationCrossOrigin",
- WebURL(GetDocument().Url()));
- }
-
- if (!CheckPolicyFeatures({mojom::FeaturePolicyFeature::kAccelerometer,
- mojom::FeaturePolicyFeature::kGyroscope})) {
+ if (!CheckPolicyFeatures(
+ {mojom::blink::FeaturePolicyFeature::kAccelerometer,
+ mojom::blink::FeaturePolicyFeature::kGyroscope})) {
LogToConsolePolicyFeaturesDisabled(GetDocument().GetFrame(),
EventTypeName());
return;
@@ -115,7 +110,7 @@ Event* DeviceOrientationController::LastEvent() const {
}
bool DeviceOrientationController::IsNullEvent(Event* event) const {
- DeviceOrientationEvent* orientation_event = ToDeviceOrientationEvent(event);
+ auto* orientation_event = To<DeviceOrientationEvent>(event);
return !orientation_event->Orientation()->CanProvideEventData();
}
@@ -138,7 +133,7 @@ void DeviceOrientationController::ClearOverride() {
DidUpdateData();
}
-void DeviceOrientationController::Trace(blink::Visitor* visitor) {
+void DeviceOrientationController::Trace(Visitor* visitor) {
visitor->Trace(override_orientation_data_);
visitor->Trace(orientation_event_pump_);
DeviceSingleWindowEventController::Trace(visitor);
@@ -173,7 +168,7 @@ void DeviceOrientationController::LogToConsolePolicyFeaturesDisabled(
"https://github.com/WICG/feature-policy/blob/master/"
"features.md#sensor-features",
event_name.Ascii().c_str());
- ConsoleMessage* console_message = ConsoleMessage::Create(
+ auto* console_message = MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning, std::move(message));
frame->Console().AddMessage(console_message);
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 33384b290e4..617e82b7452 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,7 +36,7 @@ class MODULES_EXPORT DeviceOrientationController
void SetOverride(DeviceOrientationData*);
void ClearOverride();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
static void LogToConsolePolicyFeaturesDisabled(
LocalFrame*,
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_data.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_data.cc
index 0040a58a4c1..e9624e8dbe2 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_data.cc
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_data.cc
@@ -25,7 +25,7 @@
#include "third_party/blink/renderer/modules/device_orientation/device_orientation_data.h"
-#include "third_party/blink/renderer/modules/device_orientation/device_orientation_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_device_orientation_event_init.h"
namespace blink {
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 bb591ef1727..6dd83bc084d 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(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
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 acdb49f7df7..85809bff6da 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
@@ -25,8 +25,8 @@
#include "third_party/blink/renderer/modules/device_orientation/device_orientation_event.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_device_orientation_event_init.h"
#include "third_party/blink/renderer/modules/device_orientation/device_orientation_data.h"
-#include "third_party/blink/renderer/modules/device_orientation/device_orientation_event_init.h"
namespace blink {
@@ -47,6 +47,24 @@ DeviceOrientationEvent::DeviceOrientationEvent(
: Event(event_type, Bubbles::kNo, Cancelable::kNo),
orientation_(orientation) {}
+base::Optional<double> DeviceOrientationEvent::alpha() const {
+ if (orientation_->CanProvideAlpha())
+ return orientation_->Alpha();
+ return base::nullopt;
+}
+
+base::Optional<double> DeviceOrientationEvent::beta() const {
+ if (orientation_->CanProvideBeta())
+ return orientation_->Beta();
+ return base::nullopt;
+}
+
+base::Optional<double> DeviceOrientationEvent::gamma() const {
+ if (orientation_->CanProvideGamma())
+ return orientation_->Gamma();
+ return base::nullopt;
+}
+
double DeviceOrientationEvent::alpha(bool& is_null) const {
if (orientation_->CanProvideAlpha())
return orientation_->Alpha();
@@ -79,7 +97,7 @@ const AtomicString& DeviceOrientationEvent::InterfaceName() const {
return event_interface_names::kDeviceOrientationEvent;
}
-void DeviceOrientationEvent::Trace(blink::Visitor* visitor) {
+void DeviceOrientationEvent::Trace(Visitor* visitor) {
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 43a95fd1897..44291e363e5 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
@@ -28,6 +28,7 @@
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -62,26 +63,30 @@ class DeviceOrientationEvent final : public Event {
DeviceOrientationData* Orientation() const { return orientation_.Get(); }
- double alpha(bool& is_null) const;
- double beta(bool& is_null) const;
- double gamma(bool& is_null) const;
+ base::Optional<double> alpha() const;
+ base::Optional<double> beta() const;
+ base::Optional<double> gamma() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ double alpha(bool& is_null) const; // DEPRECATED
+ double beta(bool& is_null) const; // DEPRECATED
+ double gamma(bool& is_null) const; // DEPRECATED
bool absolute() const;
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<DeviceOrientationData> orientation_;
};
-DEFINE_TYPE_CASTS(DeviceOrientationEvent,
- Event,
- event,
- event->InterfaceName() ==
- event_interface_names::kDeviceOrientationEvent,
- event.InterfaceName() ==
- event_interface_names::kDeviceOrientationEvent);
+template <>
+struct DowncastTraits<DeviceOrientationEvent> {
+ static bool AllowFrom(const Event& event) {
+ return event.InterfaceName() ==
+ event_interface_names::kDeviceOrientationEvent;
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.idl b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.idl
index 1a94e101cbd..b623b70e2f0 100644
--- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.idl
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.idl
@@ -26,9 +26,9 @@
// https://w3c.github.io/deviceorientation/spec-source-orientation.html#deviceorientation
[
- Constructor(DOMString type, optional DeviceOrientationEventInit eventInitDict),
Exposed=Window, SecureContext
] interface DeviceOrientationEvent : Event {
+ constructor(DOMString type, optional DeviceOrientationEventInit eventInitDict = {});
readonly attribute double? alpha;
readonly attribute double? beta;
readonly attribute double? gamma;
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 1d253dd5ece..b348403f428 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
@@ -79,7 +79,7 @@ DeviceOrientationEventPump::LatestDeviceOrientationData() {
return data_.Get();
}
-void DeviceOrientationEventPump::Trace(blink::Visitor* visitor) {
+void DeviceOrientationEventPump::Trace(Visitor* visitor) {
visitor->Trace(relative_orientation_sensor_);
visitor->Trace(absolute_orientation_sensor_);
visitor->Trace(data_);
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 e76252ccc5d..f75b7598cb8 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
@@ -37,7 +37,7 @@ class MODULES_EXPORT DeviceOrientationEventPump
// Note that the returned object is owned by this class.
DeviceOrientationData* LatestDeviceOrientationData();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// DeviceSensorEventPump:
void SendStartMessage(LocalFrame* frame) override;
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 03708151def..2c9599353c9 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(blink::Visitor* visitor) {
+void DeviceOrientationInspectorAgent::Trace(Visitor* visitor) {
visitor->Trace(inspected_frames_);
visitor->Trace(sensor_agent_);
InspectorBaseAgent::Trace(visitor);
@@ -51,7 +51,7 @@ Response DeviceOrientationInspectorAgent::setDeviceOrientationOverride(
DeviceOrientationData::Create(alpha, beta, gamma, false));
}
sensor_agent_->SetOrientationSensorOverride(alpha, beta, gamma);
- return Response::OK();
+ return Response::Success();
}
Response DeviceOrientationInspectorAgent::clearDeviceOrientationOverride() {
@@ -63,7 +63,7 @@ Response DeviceOrientationInspectorAgent::disable() {
if (Controller())
Controller()->ClearOverride();
sensor_agent_->Disable();
- return Response::OK();
+ return Response::Success();
}
void DeviceOrientationInspectorAgent::Restore() {
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 e9d4bb27b00..94c9436b2ba 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// Protocol methods.
protocol::Response setDeviceOrientationOverride(double,
diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/idls.gni b/chromium/third_party/blink/renderer/modules/device_orientation/idls.gni
new file mode 100644
index 00000000000..10da5c80d8a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/device_orientation/idls.gni
@@ -0,0 +1,22 @@
+# 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 = [
+ "device_motion_event.idl",
+ "device_motion_event_acceleration.idl",
+ "device_motion_event_rotation_rate.idl",
+ "device_orientation_event.idl",
+]
+
+modules_dictionary_idl_files = [
+ "device_motion_event_acceleration_init.idl",
+ "device_motion_event_init.idl",
+ "device_motion_event_rotation_rate_init.idl",
+ "device_orientation_event_init.idl",
+]
+
+modules_dependency_idl_files = [
+ "window_device_motion.idl",
+ "window_device_orientation.idl",
+]
diff --git a/chromium/third_party/blink/renderer/modules/document_metadata/BUILD.gn b/chromium/third_party/blink/renderer/modules/document_metadata/BUILD.gn
index d87ad107f30..18f812cec23 100644
--- a/chromium/third_party/blink/renderer/modules/document_metadata/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/document_metadata/BUILD.gn
@@ -1,4 +1,4 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
+# 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.
@@ -6,11 +6,11 @@ import("//third_party/blink/renderer/modules/modules.gni")
blink_modules_sources("document_metadata") {
sources = [
- "copyless_paste_extractor.cc",
- "copyless_paste_extractor.h",
- "copyless_paste_server.cc",
- "copyless_paste_server.h",
+ "document_metadata_extractor.cc",
+ "document_metadata_extractor.h",
+ "document_metadata_server.cc",
+ "document_metadata_server.h",
]
- deps = []
+ deps = [ "//components/schema_org/common:mojom_blink" ]
}
diff --git a/chromium/third_party/blink/renderer/modules/document_metadata/DEPS b/chromium/third_party/blink/renderer/modules/document_metadata/DEPS
index f7f67cd78e0..76aab5ffe6d 100644
--- a/chromium/third_party/blink/renderer/modules/document_metadata/DEPS
+++ b/chromium/third_party/blink/renderer/modules/document_metadata/DEPS
@@ -1,4 +1,3 @@
include_rules = [
- "+mojo/public/cpp/bindings/binding.h",
- "+mojo/public/cpp/bindings/strong_binding.h",
+ "+components/schema_org/common",
]
diff --git a/chromium/third_party/blink/renderer/modules/document_metadata/OWNERS b/chromium/third_party/blink/renderer/modules/document_metadata/OWNERS
new file mode 100644
index 00000000000..f8798d39411
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/document_metadata/OWNERS
@@ -0,0 +1,6 @@
+beccahughes@chromium.org
+steimel@chromium.org
+sgbowen@google.com
+
+# COMPONENT: Blink>Media>Session
+# TEAM: media-dev@chromium.org
diff --git a/chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.h b/chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.h
deleted file mode 100644
index ccdd46729a9..00000000000
--- a/chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.h
+++ /dev/null
@@ -1,28 +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_MODULES_DOCUMENT_METADATA_COPYLESS_PASTE_EXTRACTOR_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_DOCUMENT_METADATA_COPYLESS_PASTE_EXTRACTOR_H_
-
-#include "third_party/blink/public/mojom/document_metadata/copyless_paste.mojom-blink-forward.h"
-#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-
-class Document;
-
-// Extract structured metadata (currently schema.org in JSON-LD) for the
-// Copyless Paste feature. The extraction must be done after the document
-// has finished parsing.
-class MODULES_EXPORT CopylessPasteExtractor final {
- STATIC_ONLY(CopylessPasteExtractor);
-
- public:
- static mojom::document_metadata::blink::WebPagePtr Extract(const Document&);
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_DOCUMENT_METADATA_COPYLESS_PASTE_EXTRACTOR_H_
diff --git a/chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.cc b/chromium/third_party/blink/renderer/modules/document_metadata/document_metadata_extractor.cc
index bc164ebd551..7c0dd79353f 100644
--- a/chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.cc
+++ b/chromium/third_party/blink/renderer/modules/document_metadata/document_metadata_extractor.cc
@@ -2,19 +2,20 @@
// 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/document_metadata/copyless_paste_extractor.h"
+#include "third_party/blink/renderer/modules/document_metadata/document_metadata_extractor.h"
#include <algorithm>
#include <memory>
#include <utility>
-#include "third_party/blink/public/mojom/document_metadata/copyless_paste.mojom-blink.h"
+#include "base/metrics/histogram_functions.h"
+#include "components/schema_org/common/metadata.mojom-blink.h"
+#include "third_party/blink/public/mojom/document_metadata/document_metadata.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/html_names.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/json/json_parser.h"
#include "third_party/blink/renderer/platform/json/json_values.h"
@@ -26,14 +27,14 @@ namespace blink {
namespace {
-using mojom::document_metadata::blink::Entity;
-using mojom::document_metadata::blink::EntityPtr;
-using mojom::document_metadata::blink::Property;
-using mojom::document_metadata::blink::PropertyPtr;
-using mojom::document_metadata::blink::Values;
-using mojom::document_metadata::blink::ValuesPtr;
-using mojom::document_metadata::blink::WebPage;
-using mojom::document_metadata::blink::WebPagePtr;
+using mojom::blink::WebPage;
+using mojom::blink::WebPagePtr;
+using schema_org::mojom::blink::Entity;
+using schema_org::mojom::blink::EntityPtr;
+using schema_org::mojom::blink::Property;
+using schema_org::mojom::blink::PropertyPtr;
+using schema_org::mojom::blink::Values;
+using schema_org::mojom::blink::ValuesPtr;
// App Indexing enforces a max nesting depth of 5. Our top level message
// corresponds to the WebPage, so this only leaves 4 more levels. We will parse
@@ -248,9 +249,15 @@ void ExtractEntityFromTopLevelObject(const JSONObject& val,
ExtractTopLevelEntity(val, entities);
}
-// ExtractionStatus is used in UMA, hence is append-only.
-// kCount must be the last entry.
-enum ExtractionStatus { kOK, kEmpty, kParseFailure, kWrongType, kCount };
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum ExtractionStatus {
+ kOK,
+ kEmpty,
+ kParseFailure,
+ kWrongType,
+ kMaxValue = kWrongType,
+};
ExtractionStatus ExtractMetadata(const Element& root,
Vector<EntityPtr>& entities) {
@@ -261,7 +268,7 @@ ExtractionStatus ExtractMetadata(const Element& root,
std::unique_ptr<JSONValue> json = ParseJSON(element.textContent());
if (!json) {
LOG(ERROR) << "Failed to parse json.";
- return kParseFailure;
+ return ExtractionStatus::kParseFailure;
}
switch (json->GetType()) {
case JSONValue::ValueType::kTypeArray:
@@ -272,20 +279,20 @@ ExtractionStatus ExtractMetadata(const Element& root,
entities);
break;
default:
- return kWrongType;
+ return ExtractionStatus::kWrongType;
}
}
}
if (entities.IsEmpty()) {
- return kEmpty;
+ return ExtractionStatus::kEmpty;
}
- return kOK;
+ return ExtractionStatus::kOK;
}
} // namespace
-WebPagePtr CopylessPasteExtractor::Extract(const Document& document) {
- TRACE_EVENT0("blink", "CopylessPasteExtractor::Extract");
+WebPagePtr DocumentMetadataExtractor::Extract(const Document& document) {
+ TRACE_EVENT0("blink", "DocumentMetadataExtractor::Extract");
if (!document.GetFrame() || !document.GetFrame()->IsMainFrame())
return nullptr;
@@ -301,20 +308,19 @@ WebPagePtr CopylessPasteExtractor::Extract(const Document& document) {
ExtractionStatus status = ExtractMetadata(*html, page->entities);
base::TimeDelta elapsed_time = base::TimeTicks::Now() - start_time;
- DEFINE_STATIC_LOCAL(EnumerationHistogram, status_histogram,
- ("CopylessPaste.ExtractionStatus", kCount));
- status_histogram.Count(status);
+ base::UmaHistogramEnumeration("CopylessPaste.ExtractionStatus", status);
- if (status != kOK) {
- DEFINE_STATIC_LOCAL(
- CustomCountHistogram, extraction_histogram,
- ("CopylessPaste.ExtractionFailedUs", 1, 1000 * 1000, 50));
- extraction_histogram.CountMicroseconds(elapsed_time);
+ if (status != ExtractionStatus::kOK) {
+ base::UmaHistogramCustomMicrosecondsTimes(
+ "CopylessPaste.ExtractionFailedUs", elapsed_time,
+ base::TimeDelta::FromMicroseconds(1), base::TimeDelta::FromSeconds(1),
+ 50);
return nullptr;
}
- DEFINE_STATIC_LOCAL(CustomCountHistogram, extraction_histogram,
- ("CopylessPaste.ExtractionUs", 1, 1000 * 1000, 50));
- extraction_histogram.CountMicroseconds(elapsed_time);
+ base::UmaHistogramCustomMicrosecondsTimes(
+ "CopylessPaste.ExtractionUs", elapsed_time,
+ base::TimeDelta::FromMicroseconds(1), base::TimeDelta::FromSeconds(1),
+ 50);
page->url = document.Url();
page->title = document.title();
diff --git a/chromium/third_party/blink/renderer/modules/document_metadata/document_metadata_extractor.h b/chromium/third_party/blink/renderer/modules/document_metadata/document_metadata_extractor.h
new file mode 100644
index 00000000000..d09d16354bb
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/document_metadata/document_metadata_extractor.h
@@ -0,0 +1,28 @@
+// 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_MODULES_DOCUMENT_METADATA_DOCUMENT_METADATA_EXTRACTOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_DOCUMENT_METADATA_DOCUMENT_METADATA_EXTRACTOR_H_
+
+#include "components/schema_org/common/metadata.mojom-blink-forward.h"
+#include "third_party/blink/public/mojom/document_metadata/document_metadata.mojom-blink-forward.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+
+namespace blink {
+
+class Document;
+
+// Extract structured metadata (currently schema.org in JSON-LD). The extraction
+// must be done after the document has finished parsing.
+class MODULES_EXPORT DocumentMetadataExtractor final {
+ STATIC_ONLY(DocumentMetadataExtractor);
+
+ public:
+ static mojom::blink::WebPagePtr Extract(const Document&);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_DOCUMENT_METADATA_DOCUMENT_METADATA_EXTRACTOR_H_
diff --git a/chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor_test.cc b/chromium/third_party/blink/renderer/modules/document_metadata/document_metadata_extractor_test.cc
index 001f9e9a301..d0962fa1f8a 100644
--- a/chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor_test.cc
+++ b/chromium/third_party/blink/renderer/modules/document_metadata/document_metadata_extractor_test.cc
@@ -2,13 +2,14 @@
// 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/document_metadata/copyless_paste_extractor.h"
+#include "third_party/blink/renderer/modules/document_metadata/document_metadata_extractor.h"
#include <memory>
#include <utility>
+#include "components/schema_org/common/metadata.mojom-blink.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/mojom/document_metadata/copyless_paste.mojom-blink.h"
+#include "third_party/blink/public/mojom/document_metadata/document_metadata.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/platform/json/json_values.h"
@@ -18,18 +19,18 @@ namespace blink {
namespace {
-using mojom::document_metadata::blink::Entity;
-using mojom::document_metadata::blink::EntityPtr;
-using mojom::document_metadata::blink::Property;
-using mojom::document_metadata::blink::PropertyPtr;
-using mojom::document_metadata::blink::Values;
-using mojom::document_metadata::blink::ValuesPtr;
-using mojom::document_metadata::blink::WebPage;
-using mojom::document_metadata::blink::WebPagePtr;
+using mojom::blink::WebPage;
+using mojom::blink::WebPagePtr;
+using schema_org::mojom::blink::Entity;
+using schema_org::mojom::blink::EntityPtr;
+using schema_org::mojom::blink::Property;
+using schema_org::mojom::blink::PropertyPtr;
+using schema_org::mojom::blink::Values;
+using schema_org::mojom::blink::ValuesPtr;
-class CopylessPasteExtractorTest : public PageTestBase {
+class DocumentMetadataExtractorTest : public PageTestBase {
public:
- CopylessPasteExtractorTest() = default;
+ DocumentMetadataExtractorTest() = default;
protected:
void TearDown() override {
@@ -37,7 +38,7 @@ class CopylessPasteExtractorTest : public PageTestBase {
}
WebPagePtr Extract() {
- return CopylessPasteExtractor::Extract(GetDocument());
+ return DocumentMetadataExtractor::Extract(GetDocument());
}
void SetHTMLInnerHTML(const String&);
@@ -57,19 +58,20 @@ class CopylessPasteExtractorTest : public PageTestBase {
WebPagePtr CreateWebPage(const String& url, const String& title);
};
-void CopylessPasteExtractorTest::SetHTMLInnerHTML(const String& html_content) {
- GetDocument().documentElement()->SetInnerHTMLFromString((html_content));
+void DocumentMetadataExtractorTest::SetHTMLInnerHTML(
+ const String& html_content) {
+ GetDocument().documentElement()->setInnerHTML((html_content));
}
-void CopylessPasteExtractorTest::SetURL(const String& url) {
+void DocumentMetadataExtractorTest::SetURL(const String& url) {
GetDocument().SetURL(blink::KURL(url));
}
-void CopylessPasteExtractorTest::SetTitle(const String& title) {
+void DocumentMetadataExtractorTest::SetTitle(const String& title) {
GetDocument().setTitle(title);
}
-PropertyPtr CopylessPasteExtractorTest::CreateStringProperty(
+PropertyPtr DocumentMetadataExtractorTest::CreateStringProperty(
const String& name,
const String& value) {
PropertyPtr property = Property::New();
@@ -79,7 +81,7 @@ PropertyPtr CopylessPasteExtractorTest::CreateStringProperty(
return property;
}
-PropertyPtr CopylessPasteExtractorTest::CreateBooleanProperty(
+PropertyPtr DocumentMetadataExtractorTest::CreateBooleanProperty(
const String& name,
const bool& value) {
PropertyPtr property = Property::New();
@@ -89,7 +91,7 @@ PropertyPtr CopylessPasteExtractorTest::CreateBooleanProperty(
return property;
}
-PropertyPtr CopylessPasteExtractorTest::CreateLongProperty(
+PropertyPtr DocumentMetadataExtractorTest::CreateLongProperty(
const String& name,
const int64_t& value) {
PropertyPtr property = Property::New();
@@ -99,8 +101,9 @@ PropertyPtr CopylessPasteExtractorTest::CreateLongProperty(
return property;
}
-PropertyPtr CopylessPasteExtractorTest::CreateEntityProperty(const String& name,
- EntityPtr value) {
+PropertyPtr DocumentMetadataExtractorTest::CreateEntityProperty(
+ const String& name,
+ EntityPtr value) {
PropertyPtr property = Property::New();
property->name = name;
property->values = Values::New();
@@ -109,19 +112,19 @@ PropertyPtr CopylessPasteExtractorTest::CreateEntityProperty(const String& name,
return property;
}
-WebPagePtr CopylessPasteExtractorTest::CreateWebPage(const String& url,
- const String& title) {
+WebPagePtr DocumentMetadataExtractorTest::CreateWebPage(const String& url,
+ const String& title) {
WebPagePtr page = WebPage::New();
page->url = blink::KURL(url);
page->title = title;
return page;
}
-TEST_F(CopylessPasteExtractorTest, empty) {
+TEST_F(DocumentMetadataExtractorTest, empty) {
ASSERT_TRUE(Extract().is_null());
}
-TEST_F(CopylessPasteExtractorTest, basic) {
+TEST_F(DocumentMetadataExtractorTest, basic) {
SetHTMLInnerHTML(
"<body>"
"<script type=\"application/ld+json\">"
@@ -151,7 +154,7 @@ TEST_F(CopylessPasteExtractorTest, basic) {
EXPECT_EQ(expected, extracted);
}
-TEST_F(CopylessPasteExtractorTest, header) {
+TEST_F(DocumentMetadataExtractorTest, header) {
SetHTMLInnerHTML(
"<head>"
"<script type=\"application/ld+json\">"
@@ -182,7 +185,7 @@ TEST_F(CopylessPasteExtractorTest, header) {
EXPECT_EQ(expected, extracted);
}
-TEST_F(CopylessPasteExtractorTest, booleanValue) {
+TEST_F(DocumentMetadataExtractorTest, booleanValue) {
SetHTMLInnerHTML(
"<body>"
"<script type=\"application/ld+json\">"
@@ -211,7 +214,7 @@ TEST_F(CopylessPasteExtractorTest, booleanValue) {
EXPECT_EQ(expected, extracted);
}
-TEST_F(CopylessPasteExtractorTest, longValue) {
+TEST_F(DocumentMetadataExtractorTest, longValue) {
SetHTMLInnerHTML(
"<body>"
"<script type=\"application/ld+json\">"
@@ -240,7 +243,7 @@ TEST_F(CopylessPasteExtractorTest, longValue) {
EXPECT_EQ(expected, extracted);
}
-TEST_F(CopylessPasteExtractorTest, doubleValue) {
+TEST_F(DocumentMetadataExtractorTest, doubleValue) {
SetHTMLInnerHTML(
"<body>"
"<script type=\"application/ld+json\">"
@@ -269,7 +272,7 @@ TEST_F(CopylessPasteExtractorTest, doubleValue) {
EXPECT_EQ(expected, extracted);
}
-TEST_F(CopylessPasteExtractorTest, multiple) {
+TEST_F(DocumentMetadataExtractorTest, multiple) {
SetHTMLInnerHTML(
"<head>"
"<script type=\"application/ld+json\">"
@@ -320,7 +323,7 @@ TEST_F(CopylessPasteExtractorTest, multiple) {
EXPECT_EQ(expected, extracted);
}
-TEST_F(CopylessPasteExtractorTest, nested) {
+TEST_F(DocumentMetadataExtractorTest, nested) {
SetHTMLInnerHTML(
"<body>"
"<script type=\"application/ld+json\">"
@@ -365,7 +368,7 @@ TEST_F(CopylessPasteExtractorTest, nested) {
EXPECT_EQ(expected, extracted);
}
-TEST_F(CopylessPasteExtractorTest, repeated) {
+TEST_F(DocumentMetadataExtractorTest, repeated) {
SetHTMLInnerHTML(
"<body>"
"<script type=\"application/ld+json\">"
@@ -404,7 +407,7 @@ TEST_F(CopylessPasteExtractorTest, repeated) {
EXPECT_EQ(expected, extracted);
}
-TEST_F(CopylessPasteExtractorTest, repeatedObject) {
+TEST_F(DocumentMetadataExtractorTest, repeatedObject) {
SetHTMLInnerHTML(
"<body>"
"<script type=\"application/ld+json\">"
@@ -460,7 +463,7 @@ TEST_F(CopylessPasteExtractorTest, repeatedObject) {
EXPECT_EQ(expected, extracted);
}
-TEST_F(CopylessPasteExtractorTest, truncateLongString) {
+TEST_F(DocumentMetadataExtractorTest, truncateLongString) {
StringBuilder maxLengthString;
for (int i = 0; i < 200; ++i) {
maxLengthString.Append("a");
@@ -499,7 +502,7 @@ TEST_F(CopylessPasteExtractorTest, truncateLongString) {
EXPECT_EQ(expected, extracted);
}
-TEST_F(CopylessPasteExtractorTest, enforceTypeExists) {
+TEST_F(DocumentMetadataExtractorTest, enforceTypeExists) {
SetHTMLInnerHTML(
"<body>"
"<script type=\"application/ld+json\">"
@@ -517,7 +520,7 @@ TEST_F(CopylessPasteExtractorTest, enforceTypeExists) {
ASSERT_TRUE(extracted.is_null());
}
-TEST_F(CopylessPasteExtractorTest, UnhandledTypeIgnored) {
+TEST_F(DocumentMetadataExtractorTest, UnhandledTypeIgnored) {
SetHTMLInnerHTML(
"<body>"
"<script type=\"application/ld+json\">"
@@ -536,7 +539,7 @@ TEST_F(CopylessPasteExtractorTest, UnhandledTypeIgnored) {
ASSERT_TRUE(extracted.is_null());
}
-TEST_F(CopylessPasteExtractorTest, truncateTooManyValuesInField) {
+TEST_F(DocumentMetadataExtractorTest, truncateTooManyValuesInField) {
StringBuilder largeRepeatedField;
largeRepeatedField.Append("[");
for (int i = 0; i < 101; ++i) {
@@ -586,7 +589,7 @@ TEST_F(CopylessPasteExtractorTest, truncateTooManyValuesInField) {
EXPECT_EQ(expected, extracted);
}
-TEST_F(CopylessPasteExtractorTest, truncateTooManyFields) {
+TEST_F(DocumentMetadataExtractorTest, truncateTooManyFields) {
StringBuilder tooManyFields;
for (int i = 0; i < 20; ++i) {
tooManyFields.AppendFormat("\"%d\": \"a\"", i);
@@ -626,7 +629,7 @@ TEST_F(CopylessPasteExtractorTest, truncateTooManyFields) {
EXPECT_EQ(expected, extracted);
}
-TEST_F(CopylessPasteExtractorTest, ignorePropertyWithEmptyArray) {
+TEST_F(DocumentMetadataExtractorTest, ignorePropertyWithEmptyArray) {
SetHTMLInnerHTML(
"<body>"
"<script type=\"application/ld+json\">"
@@ -655,7 +658,7 @@ TEST_F(CopylessPasteExtractorTest, ignorePropertyWithEmptyArray) {
EXPECT_EQ(expected, extracted);
}
-TEST_F(CopylessPasteExtractorTest, ignorePropertyWithMixedTypes) {
+TEST_F(DocumentMetadataExtractorTest, ignorePropertyWithMixedTypes) {
SetHTMLInnerHTML(
"<body>"
"<script type=\"application/ld+json\">"
@@ -684,7 +687,7 @@ TEST_F(CopylessPasteExtractorTest, ignorePropertyWithMixedTypes) {
EXPECT_EQ(expected, extracted);
}
-TEST_F(CopylessPasteExtractorTest, ignorePropertyWithNestedArray) {
+TEST_F(DocumentMetadataExtractorTest, ignorePropertyWithNestedArray) {
SetHTMLInnerHTML(
"<body>"
"<script type=\"application/ld+json\">"
@@ -713,7 +716,7 @@ TEST_F(CopylessPasteExtractorTest, ignorePropertyWithNestedArray) {
EXPECT_EQ(expected, extracted);
}
-TEST_F(CopylessPasteExtractorTest, enforceMaxNestingDepth) {
+TEST_F(DocumentMetadataExtractorTest, enforceMaxNestingDepth) {
SetHTMLInnerHTML(
"<body>"
"<script type=\"application/ld+json\">"
@@ -768,7 +771,7 @@ TEST_F(CopylessPasteExtractorTest, enforceMaxNestingDepth) {
EXPECT_EQ(expected, extracted);
}
-TEST_F(CopylessPasteExtractorTest, maxNestingDepthWithTerminalProperty) {
+TEST_F(DocumentMetadataExtractorTest, maxNestingDepthWithTerminalProperty) {
SetHTMLInnerHTML(
"<body>"
"<script type=\"application/ld+json\">"
diff --git a/chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_server.cc b/chromium/third_party/blink/renderer/modules/document_metadata/document_metadata_server.cc
index a7d9dd295a6..d5f96165b60 100644
--- a/chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_server.cc
+++ b/chromium/third_party/blink/renderer/modules/document_metadata/document_metadata_server.cc
@@ -2,38 +2,38 @@
// 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/document_metadata/copyless_paste_server.h"
+#include "third_party/blink/renderer/modules/document_metadata/document_metadata_server.h"
#include <memory>
#include <utility>
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
-#include "third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.h"
+#include "third_party/blink/renderer/modules/document_metadata/document_metadata_extractor.h"
namespace blink {
-CopylessPasteServer::CopylessPasteServer(LocalFrame& frame) : frame_(frame) {}
+DocumentMetadataServer::DocumentMetadataServer(LocalFrame& frame)
+ : frame_(frame) {}
-void CopylessPasteServer::BindMojoReceiver(
+void DocumentMetadataServer::BindMojoReceiver(
LocalFrame* frame,
- mojo::PendingReceiver<mojom::document_metadata::blink::CopylessPaste>
- receiver) {
+ mojo::PendingReceiver<mojom::blink::DocumentMetadata> receiver) {
DCHECK(frame);
// TODO(wychen): remove BindMojoReceiver pattern, and make this a service
// associated with frame lifetime.
- mojo::MakeSelfOwnedReceiver(std::make_unique<CopylessPasteServer>(*frame),
+ mojo::MakeSelfOwnedReceiver(std::make_unique<DocumentMetadataServer>(*frame),
std::move(receiver));
}
-void CopylessPasteServer::GetEntities(GetEntitiesCallback callback) {
+void DocumentMetadataServer::GetEntities(GetEntitiesCallback callback) {
if (!frame_ || !frame_->GetDocument()) {
std::move(callback).Run(nullptr);
return;
}
std::move(callback).Run(
- CopylessPasteExtractor::Extract(*frame_->GetDocument()));
+ DocumentMetadataExtractor::Extract(*frame_->GetDocument()));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_server.h b/chromium/third_party/blink/renderer/modules/document_metadata/document_metadata_server.h
index db626b831df..7575d9aa9ce 100644
--- a/chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_server.h
+++ b/chromium/third_party/blink/renderer/modules/document_metadata/document_metadata_server.h
@@ -2,11 +2,11 @@
// 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_DOCUMENT_METADATA_COPYLESS_PASTE_SERVER_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_DOCUMENT_METADATA_COPYLESS_PASTE_SERVER_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_DOCUMENT_METADATA_DOCUMENT_METADATA_SERVER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_DOCUMENT_METADATA_DOCUMENT_METADATA_SERVER_H_
#include "mojo/public/cpp/bindings/pending_receiver.h"
-#include "third_party/blink/public/mojom/document_metadata/copyless_paste.mojom-blink.h"
+#include "third_party/blink/public/mojom/document_metadata/document_metadata.mojom-blink.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
@@ -15,14 +15,14 @@ namespace blink {
class LocalFrame;
// Mojo interface to return extracted metadata for AppIndexing.
-class MODULES_EXPORT CopylessPasteServer final
- : public mojom::document_metadata::blink::CopylessPaste {
+class MODULES_EXPORT DocumentMetadataServer final
+ : public mojom::blink::DocumentMetadata {
public:
- explicit CopylessPasteServer(LocalFrame&);
+ explicit DocumentMetadataServer(LocalFrame&);
static void BindMojoReceiver(
LocalFrame*,
- mojo::PendingReceiver<mojom::document_metadata::blink::CopylessPaste>);
+ mojo::PendingReceiver<mojom::blink::DocumentMetadata>);
void GetEntities(GetEntitiesCallback) override;
@@ -32,4 +32,4 @@ class MODULES_EXPORT CopylessPasteServer final
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_DOCUMENT_METADATA_COPYLESS_PASTE_SERVER_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_DOCUMENT_METADATA_DOCUMENT_METADATA_SERVER_H_
diff --git a/chromium/third_party/blink/renderer/modules/donottrack/idls.gni b/chromium/third_party/blink/renderer/modules/donottrack/idls.gni
new file mode 100644
index 00000000000..5687a466323
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/donottrack/idls.gni
@@ -0,0 +1,5 @@
+# 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_dependency_idl_files = [ "navigator_do_not_track.idl" ]
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 5885674aee4..26e258b726a 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(blink::Visitor* visitor) {
+void NavigatorDoNotTrack::Trace(Visitor* visitor) {
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 832bd96b95a..3c849c94a07 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/encoding/idls.gni b/chromium/third_party/blink/renderer/modules/encoding/idls.gni
new file mode 100644
index 00000000000..a6ce5aa1743
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/encoding/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "text_decoder.idl",
+ "text_decoder_stream.idl",
+ "text_encoder.idl",
+ "text_encoder_stream.idl",
+]
+
+modules_dictionary_idl_files = [
+ "text_decode_options.idl",
+ "text_decoder_options.idl",
+ "text_encoder_encode_into_result.idl",
+]
diff --git a/chromium/third_party/blink/renderer/modules/encoding/text_decoder.cc b/chromium/third_party/blink/renderer/modules/encoding/text_decoder.cc
index 89570527c44..3aeed930ada 100644
--- a/chromium/third_party/blink/renderer/modules/encoding/text_decoder.cc
+++ b/chromium/third_party/blink/renderer/modules/encoding/text_decoder.cc
@@ -85,15 +85,25 @@ String TextDecoder::decode(const BufferSource& input,
if (input.IsArrayBufferView()) {
const char* start = static_cast<const char*>(
input.GetAsArrayBufferView().View()->BaseAddress());
- uint32_t length =
- input.GetAsArrayBufferView().View()->deprecatedByteLengthAsUnsigned();
- return decode(start, length, options, exception_state);
+ size_t length = input.GetAsArrayBufferView().View()->byteLengthAsSizeT();
+ if (length > std::numeric_limits<uint32_t>::max()) {
+ exception_state.ThrowRangeError(
+ "Buffer size exceeds maximum heap object size.");
+ return String();
+ }
+ return decode(start, static_cast<uint32_t>(length), options,
+ exception_state);
}
DCHECK(input.IsArrayBuffer());
const char* start =
static_cast<const char*>(input.GetAsArrayBuffer()->Data());
- uint32_t length = input.GetAsArrayBuffer()->DeprecatedByteLengthAsUnsigned();
- return decode(start, length, options, exception_state);
+ size_t length = input.GetAsArrayBuffer()->ByteLengthAsSizeT();
+ if (length > std::numeric_limits<uint32_t>::max()) {
+ exception_state.ThrowRangeError(
+ "Buffer size exceeds maximum heap object size.");
+ return String();
+ }
+ return decode(start, static_cast<uint32_t>(length), options, exception_state);
}
String TextDecoder::decode(const char* start,
diff --git a/chromium/third_party/blink/renderer/modules/encoding/text_decoder.h b/chromium/third_party/blink/renderer/modules/encoding/text_decoder.h
index f4637fb2b94..0036e21d947 100644
--- a/chromium/third_party/blink/renderer/modules/encoding/text_decoder.h
+++ b/chromium/third_party/blink/renderer/modules/encoding/text_decoder.h
@@ -33,8 +33,8 @@
#include <memory>
#include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h"
-#include "third_party/blink/renderer/modules/encoding/text_decode_options.h"
-#include "third_party/blink/renderer/modules/encoding/text_decoder_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_text_decode_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_text_decoder_options.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/wtf/text/text_codec.h"
diff --git a/chromium/third_party/blink/renderer/modules/encoding/text_decoder.idl b/chromium/third_party/blink/renderer/modules/encoding/text_decoder.idl
index 9e1a9b6e18d..96ea4713cbe 100644
--- a/chromium/third_party/blink/renderer/modules/encoding/text_decoder.idl
+++ b/chromium/third_party/blink/renderer/modules/encoding/text_decoder.idl
@@ -28,14 +28,14 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// https://encoding.spec.whatwg.org/#textdecoder
+
[
- Exposed=(Window,Worker),
- Constructor(optional DOMString label = "utf-8", optional TextDecoderOptions options),
- RaisesException=Constructor,
- MeasureAs=TextDecoderConstructor
+ Exposed=(Window,Worker)
] interface TextDecoder {
+ [RaisesException, MeasureAs=TextDecoderConstructor] constructor(optional DOMString label = "utf-8", optional TextDecoderOptions options = {});
readonly attribute DOMString encoding;
readonly attribute boolean fatal;
readonly attribute boolean ignoreBOM;
- [RaisesException, MeasureAs=TextDecoderDecode] DOMString decode(optional BufferSource input, optional TextDecodeOptions options);
+ [RaisesException, MeasureAs=TextDecoderDecode] DOMString decode(optional BufferSource input, optional TextDecodeOptions options = {});
};
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 6e440da228a..716c221d6e0 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
@@ -10,11 +10,11 @@
#include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_text_decoder_options.h"
#include "third_party/blink/renderer/core/streams/transform_stream_default_controller.h"
#include "third_party/blink/renderer/core/streams/transform_stream_transformer.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
#include "third_party/blink/renderer/modules/encoding/encoding.h"
-#include "third_party/blink/renderer/modules/encoding/text_decoder_options.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/to_v8.h"
@@ -54,16 +54,28 @@ class TextDecoderStream::Transformer final : public TransformStreamTransformer {
if (bufferSource.IsArrayBufferView()) {
const auto* view = bufferSource.GetAsArrayBufferView().View();
const char* start = static_cast<const char*>(view->BaseAddress());
- uint32_t length = view->deprecatedByteLengthAsUnsigned();
- DecodeAndEnqueue(start, length, WTF::FlushBehavior::kDoNotFlush,
- controller, exception_state);
+ size_t length = view->byteLengthAsSizeT();
+ if (length > std::numeric_limits<uint32_t>::max()) {
+ exception_state.ThrowRangeError(
+ "Buffer size exceeds maximum heap object size.");
+ return ScriptPromise();
+ }
+ DecodeAndEnqueue(start, static_cast<uint32_t>(length),
+ WTF::FlushBehavior::kDoNotFlush, controller,
+ exception_state);
return ScriptPromise::CastUndefined(script_state_);
}
DCHECK(bufferSource.IsArrayBuffer());
const auto* array_buffer = bufferSource.GetAsArrayBuffer();
const char* start = static_cast<const char*>(array_buffer->Data());
- uint32_t length = array_buffer->DeprecatedByteLengthAsUnsigned();
- DecodeAndEnqueue(start, length, WTF::FlushBehavior::kDoNotFlush, controller,
+ size_t length = array_buffer->ByteLengthAsSizeT();
+ if (length > std::numeric_limits<uint32_t>::max()) {
+ exception_state.ThrowRangeError(
+ "Buffer size exceeds maximum heap object size.");
+ return ScriptPromise();
+ }
+ DecodeAndEnqueue(start, static_cast<uint32_t>(length),
+ WTF::FlushBehavior::kDoNotFlush, controller,
exception_state);
return ScriptPromise::CastUndefined(script_state_);
diff --git a/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.idl b/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.idl
index 286489d726e..427c971373b 100644
--- a/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.idl
+++ b/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.idl
@@ -4,12 +4,9 @@
// https://encoding.spec.whatwg.org/#interface-textdecoderstream
[
- Exposed=(Window,Worker),
- Constructor(optional DOMString label = "utf-8", optional TextDecoderOptions options),
- ConstructorCallWith=ScriptState,
- RaisesException=Constructor,
- MeasureAs=TextDecoderStreamConstructor
+ Exposed=(Window,Worker)
] interface TextDecoderStream {
+ [CallWith=ScriptState, RaisesException, MeasureAs=TextDecoderStreamConstructor] constructor(optional DOMString label = "utf-8", optional TextDecoderOptions options = {});
readonly attribute DOMString encoding;
readonly attribute boolean fatal;
readonly attribute boolean ignoreBOM;
diff --git a/chromium/third_party/blink/renderer/modules/encoding/text_encoder.cc b/chromium/third_party/blink/renderer/modules/encoding/text_encoder.cc
index 0e2da7a6b1a..068f614dbf4 100644
--- a/chromium/third_party/blink/renderer/modules/encoding/text_encoder.cc
+++ b/chromium/third_party/blink/renderer/modules/encoding/text_encoder.cc
@@ -30,9 +30,9 @@
#include "third_party/blink/renderer/modules/encoding/text_encoder.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_text_encoder_encode_into_result.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/encoding/encoding.h"
-#include "third_party/blink/renderer/modules/encoding/text_encoder_encode_into_result.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/wtf/text/text_encoding_registry.h"
@@ -88,15 +88,15 @@ TextEncoderEncodeIntoResult* TextEncoder::encodeInto(
TextEncoderEncodeIntoResult::Create();
TextCodec::EncodeIntoResult encode_into_result_data;
- unsigned char* destination_buffer = destination.View()->View()->Data();
+ unsigned char* destination_buffer = destination.View()->Data();
if (source.Is8Bit()) {
encode_into_result_data = codec_->EncodeInto(
source.Characters8(), source.length(), destination_buffer,
- destination.View()->deprecatedLengthAsUnsigned());
+ destination.View()->lengthAsSizeT());
} else {
encode_into_result_data = codec_->EncodeInto(
source.Characters16(), source.length(), destination_buffer,
- destination.View()->deprecatedLengthAsUnsigned());
+ destination.View()->lengthAsSizeT());
}
encode_into_result->setRead(encode_into_result_data.code_units_read);
diff --git a/chromium/third_party/blink/renderer/modules/encoding/text_encoder.idl b/chromium/third_party/blink/renderer/modules/encoding/text_encoder.idl
index e94f2398dcb..b9af61c1bfc 100644
--- a/chromium/third_party/blink/renderer/modules/encoding/text_encoder.idl
+++ b/chromium/third_party/blink/renderer/modules/encoding/text_encoder.idl
@@ -29,12 +29,9 @@
*/
[
- Exposed=(Window,Worker),
- Constructor(),
- ConstructorCallWith=ExecutionContext,
- RaisesException=Constructor,
- MeasureAs=TextEncoderConstructor
+ Exposed=(Window,Worker)
] interface TextEncoder {
+ [CallWith=ExecutionContext, RaisesException, MeasureAs=TextEncoderConstructor] constructor();
readonly attribute DOMString encoding;
[MeasureAs=TextEncoderEncode] Uint8Array encode(optional USVString input = "");
[MeasureAs=TextEncoderEncodeInto] TextEncoderEncodeIntoResult encodeInto(USVString source, Uint8Array destination);
diff --git a/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.idl b/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.idl
index b28dd76acab..e1829b6ef12 100644
--- a/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.idl
+++ b/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.idl
@@ -4,12 +4,9 @@
// https://encoding.spec.whatwg.org/#interface-textencoderstream
[
- Exposed=(Window,Worker),
- Constructor(),
- ConstructorCallWith=ScriptState,
- RaisesException=Constructor,
- MeasureAs=TextEncoderStreamConstructor
+ Exposed=(Window,Worker)
] interface TextEncoderStream {
+ [CallWith=ScriptState, RaisesException, MeasureAs=TextEncoderStreamConstructor] constructor();
readonly attribute DOMString encoding;
readonly attribute ReadableStream readable;
readonly attribute WritableStream writable;
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 c08b7b77f61..d9869b87c90 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
@@ -131,7 +131,7 @@ bool ContentDecryptionModuleResultPromise::IsValidToFulfillPromise() {
return GetExecutionContext() && !GetExecutionContext()->IsContextDestroyed();
}
-void ContentDecryptionModuleResultPromise::Trace(blink::Visitor* visitor) {
+void ContentDecryptionModuleResultPromise::Trace(Visitor* visitor) {
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 1ffcebe664b..135c66761e8 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
@@ -49,7 +49,7 @@ class ContentDecryptionModuleResultPromise
// It is only valid to call this before completion.
ScriptPromise Promise();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 639d2806d6d..ce81c63d4e2 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void TimerFired(TimerBase*);
@@ -320,7 +320,7 @@ void SetMediaKeysHandler::SetFailed(ExceptionCode code,
Fail(code, error_message);
}
-void SetMediaKeysHandler::Trace(blink::Visitor* visitor) {
+void SetMediaKeysHandler::Trace(Visitor* visitor) {
visitor->Trace(element_);
visitor->Trace(new_media_keys_);
ScriptPromiseResolver::Trace(visitor);
@@ -362,7 +362,8 @@ MediaKeys* HTMLMediaElementEncryptedMedia::mediaKeys(
ScriptPromise HTMLMediaElementEncryptedMedia::setMediaKeys(
ScriptState* script_state,
HTMLMediaElement& element,
- MediaKeys* media_keys) {
+ MediaKeys* media_keys,
+ ExceptionState& exception_state) {
HTMLMediaElementEncryptedMedia& this_element =
HTMLMediaElementEncryptedMedia::From(element);
DVLOG(EME_LOG_LEVEL) << __func__ << ": current("
@@ -374,10 +375,9 @@ ScriptPromise HTMLMediaElementEncryptedMedia::setMediaKeys(
// 1. If this object's attaching media keys value is true, return a
// promise rejected with an InvalidStateError.
if (this_element.is_attaching_media_keys_) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- "Another request is in progress."));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Another request is in progress.");
+ return ScriptPromise();
}
// 2. If mediaKeys and the mediaKeys attribute are the same object,
@@ -421,13 +421,14 @@ void HTMLMediaElementEncryptedMedia::Encrypted(
// so don't return the initData. However, they still get an event.
event = CreateEncryptedEvent(media::EmeInitDataType::UNKNOWN, nullptr, 0);
media_element_->GetExecutionContext()->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning,
- "Media element must be CORS-same-origin with "
- "the embedding page. If cross-origin, you "
- "should use the `crossorigin` attribute and "
- "make sure CORS headers on the media data "
- "response are CORS-same-origin."));
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning,
+ "Media element must be CORS-same-origin with "
+ "the embedding page. If cross-origin, you "
+ "should use the `crossorigin` attribute and "
+ "make sure CORS headers on the media data "
+ "response are CORS-same-origin."));
}
event->SetTarget(media_element_);
@@ -472,7 +473,7 @@ HTMLMediaElementEncryptedMedia::ContentDecryptionModule() {
return media_keys_ ? media_keys_->ContentDecryptionModule() : nullptr;
}
-void HTMLMediaElementEncryptedMedia::Trace(blink::Visitor* visitor) {
+void HTMLMediaElementEncryptedMedia::Trace(Visitor* visitor) {
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 fb687dfde63..f1176cbc7a3 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
@@ -20,6 +20,7 @@ enum class EmeInitDataType;
namespace blink {
+class ExceptionState;
class HTMLMediaElement;
class MediaKeys;
class ScriptPromise;
@@ -38,7 +39,8 @@ class MODULES_EXPORT HTMLMediaElementEncryptedMedia final
static MediaKeys* mediaKeys(HTMLMediaElement&);
static ScriptPromise setMediaKeys(ScriptState*,
HTMLMediaElement&,
- MediaKeys*);
+ MediaKeys*,
+ ExceptionState&);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(encrypted, kEncrypted)
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(waitingforkey, kWaitingforkey)
@@ -55,7 +57,7 @@ class MODULES_EXPORT HTMLMediaElementEncryptedMedia final
HTMLMediaElementEncryptedMedia(HTMLMediaElement&);
~HTMLMediaElementEncryptedMedia();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
friend class SetMediaKeysHandler;
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.idl b/chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.idl
index 8c1a02583ed..ff89800abcd 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.idl
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.idl
@@ -7,7 +7,7 @@
ImplementedAs=HTMLMediaElementEncryptedMedia
] partial interface HTMLMediaElement {
[SecureContext] readonly attribute MediaKeys mediaKeys;
- [SecureContext, CallWith=ScriptState] Promise<void> setMediaKeys(MediaKeys? mediaKeys);
+ [SecureContext, CallWith=ScriptState, RaisesException] Promise<void> setMediaKeys(MediaKeys? mediaKeys);
attribute EventHandler onencrypted;
attribute EventHandler onwaitingforkey;
};
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/idls.gni b/chromium/third_party/blink/renderer/modules/encryptedmedia/idls.gni
new file mode 100644
index 00000000000..fa457ba6dec
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "media_encrypted_event.idl",
+ "media_key_message_event.idl",
+ "media_key_session.idl",
+ "media_key_status_map.idl",
+ "media_key_system_access.idl",
+ "media_keys.idl",
+]
+
+modules_dictionary_idl_files = [
+ "media_encrypted_event_init.idl",
+ "media_key_message_event_init.idl",
+ "media_key_system_configuration.idl",
+ "media_key_system_media_capability.idl",
+ "media_keys_policy.idl",
+]
+
+modules_dependency_idl_files = [
+ "html_media_element_encrypted_media.idl",
+ "media_keys_get_status_for_policy.idl",
+ "navigator_request_media_key_system_access.idl",
+]
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 95f874b2561..e3ce0669138 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(blink::Visitor* visitor) {
+void MediaEncryptedEvent::Trace(Visitor* visitor) {
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 86e897c5e02..43d7e59a575 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
@@ -26,7 +26,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_ENCRYPTEDMEDIA_MEDIA_ENCRYPTED_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_ENCRYPTEDMEDIA_MEDIA_ENCRYPTED_EVENT_H_
-#include "third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_encrypted_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
namespace blink {
@@ -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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
String init_data_type_;
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.idl b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.idl
index 0a33ee8331d..d24d4a1866d 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.idl
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.idl
@@ -26,9 +26,9 @@
// https://w3c.github.io/encrypted-media/#mediaencryptedevent
[
- Exposed=Window,
- Constructor(DOMString type, optional MediaEncryptedEventInit eventInitDict)
+ Exposed=Window
] interface MediaEncryptedEvent : Event {
+ constructor(DOMString type, optional MediaEncryptedEventInit eventInitDict = {});
readonly attribute DOMString initDataType;
readonly attribute ArrayBuffer? initData;
};
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 17d630d79ac..fd806f81d1e 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(blink::Visitor* visitor) {
+void MediaKeyMessageEvent::Trace(Visitor* visitor) {
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 95540f07f2f..4e112adb4e0 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
@@ -27,7 +27,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_ENCRYPTEDMEDIA_MEDIA_KEY_MESSAGE_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_ENCRYPTEDMEDIA_MEDIA_KEY_MESSAGE_EVENT_H_
-#include "third_party/blink/renderer/modules/encryptedmedia/media_key_message_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_key_message_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
namespace blink {
@@ -58,7 +58,7 @@ class MediaKeyMessageEvent final : public Event {
String messageType() const { return message_type_; }
DOMArrayBuffer* message() const { return message_.Get(); }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
String message_type_;
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.idl b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.idl
index d80b5207e55..602cd657a94 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.idl
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.idl
@@ -34,9 +34,9 @@ enum MediaKeyMessageType {
[
Exposed=Window,
- Constructor(DOMString type, MediaKeyMessageEventInit eventInitDict),
SecureContext
] interface MediaKeyMessageEvent : Event {
+ constructor(DOMString type, MediaKeyMessageEventInit eventInitDict);
readonly attribute MediaKeyMessageType messageType;
readonly attribute ArrayBuffer message;
};
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 87f3fd20d49..0ac13920b1b 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
@@ -48,6 +48,7 @@
#include "third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.h"
#include "third_party/blink/renderer/modules/encryptedmedia/media_keys.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.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/v8_throw_exception.h"
#include "third_party/blink/renderer/platform/content_decryption_module_result.h"
@@ -108,27 +109,24 @@ static bool IsPersistentSessionType(WebEncryptedMediaSessionType session_type) {
}
static ScriptPromise CreateRejectedPromiseNotCallable(
- ScriptState* script_state) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- "The session is not callable."));
+ ExceptionState& exception_state) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "The session is not callable.");
+ return ScriptPromise();
}
static ScriptPromise CreateRejectedPromiseAlreadyClosed(
- ScriptState* script_state) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- "The session is already closed."));
+ ExceptionState& exception_state) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "The session is already closed.");
+ return ScriptPromise();
}
static ScriptPromise CreateRejectedPromiseAlreadyInitialized(
- ScriptState* script_state) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "The session is already initialized."));
+ ExceptionState& exception_state) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "The session is already initialized.");
+ return ScriptPromise();
}
// A class holding a pending action.
@@ -209,7 +207,7 @@ class MediaKeySession::PendingAction final
string_data_(string_data) {}
~PendingAction() = default;
- void Trace(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
visitor->Trace(result_);
visitor->Trace(data_);
}
@@ -251,7 +249,7 @@ class NewSessionResultPromise : public ContentDecryptionModuleResultPromise {
Resolve();
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(session_);
ContentDecryptionModuleResultPromise::Trace(visitor);
}
@@ -294,7 +292,7 @@ class LoadSessionResultPromise : public ContentDecryptionModuleResultPromise {
Resolve(true);
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(session_);
ContentDecryptionModuleResultPromise::Trace(visitor);
}
@@ -328,7 +326,7 @@ class SimpleResultPromise : public ContentDecryptionModuleResultPromise {
Resolve();
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(session_);
ContentDecryptionModuleResultPromise::Trace(visitor);
}
@@ -342,7 +340,7 @@ class SimpleResultPromise : public ContentDecryptionModuleResultPromise {
MediaKeySession::MediaKeySession(ScriptState* script_state,
MediaKeys* media_keys,
WebEncryptedMediaSessionType session_type)
- : ContextLifecycleObserver(ExecutionContext::From(script_state)),
+ : ExecutionContextLifecycleObserver(ExecutionContext::From(script_state)),
async_event_queue_(
MakeGarbageCollected<EventQueue>(GetExecutionContext(),
TaskType::kMediaElementEvent)),
@@ -354,9 +352,7 @@ MediaKeySession::MediaKeySession(ScriptState* script_state,
is_callable_(false),
is_closing_or_closed_(false),
closed_promise_(MakeGarbageCollected<ClosedPromise>(
- ExecutionContext::From(script_state),
- this,
- ClosedPromise::kClosed)),
+ ExecutionContext::From(script_state))),
action_timer_(ExecutionContext::From(script_state)
->GetTaskRunner(TaskType::kMiscPlatformAPI),
this,
@@ -428,7 +424,8 @@ MediaKeyStatusMap* MediaKeySession::keyStatuses() {
ScriptPromise MediaKeySession::generateRequest(
ScriptState* script_state,
const String& init_data_type_string,
- const DOMArrayPiece& init_data) {
+ const DOMArrayPiece& init_data,
+ ExceptionState& exception_state) {
DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL)
<< __func__ << "(" << this << ") " << init_data_type_string;
@@ -439,12 +436,13 @@ ScriptPromise MediaKeySession::generateRequest(
// 1. If this object's closing or closed value is true, return a promise
// rejected with an InvalidStateError.
if (is_closing_or_closed_)
- return CreateRejectedPromiseAlreadyClosed(script_state);
+ return CreateRejectedPromiseAlreadyClosed(exception_state);
// 2. If this object's uninitialized value is false, return a promise
// rejected with an InvalidStateError.
- if (!is_uninitialized_)
- return CreateRejectedPromiseAlreadyInitialized(script_state);
+ if (!is_uninitialized_) {
+ return CreateRejectedPromiseAlreadyInitialized(exception_state);
+ }
// 3. Let this object's uninitialized be false.
is_uninitialized_ = false;
@@ -452,19 +450,15 @@ ScriptPromise MediaKeySession::generateRequest(
// 4. If initDataType is the empty string, return a promise rejected
// with a newly created TypeError.
if (init_data_type_string.IsEmpty()) {
- return ScriptPromise::Reject(script_state,
- V8ThrowException::CreateTypeError(
- script_state->GetIsolate(),
- "The initDataType parameter is empty."));
+ exception_state.ThrowTypeError("The initDataType parameter is empty.");
+ return ScriptPromise();
}
// 5. If initData is an empty array, return a promise rejected with a
// newly created TypeError.
if (!init_data.ByteLengthAsSizeT()) {
- return ScriptPromise::Reject(
- script_state,
- V8ThrowException::CreateTypeError(script_state->GetIsolate(),
- "The initData parameter is empty."));
+ exception_state.ThrowTypeError("The initData parameter is empty.");
+ return ScriptPromise();
}
// 6. If the Key System implementation represented by this object's cdm
@@ -478,11 +472,11 @@ ScriptPromise MediaKeySession::generateRequest(
media::EmeInitDataType init_data_type =
EncryptedMediaUtils::ConvertToInitDataType(init_data_type_string);
if (init_data_type == media::EmeInitDataType::UNKNOWN) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotSupportedError,
- "The initialization data type '" +
- init_data_type_string + "' is not supported."));
+ exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
+ "The initialization data type '" +
+ init_data_type_string +
+ "' is not supported.");
+ return ScriptPromise();
}
// 7. Let init data be a copy of the contents of the initData parameter.
@@ -545,7 +539,8 @@ void MediaKeySession::FinishGenerateRequest() {
}
ScriptPromise MediaKeySession::load(ScriptState* script_state,
- const String& session_id) {
+ const String& session_id,
+ ExceptionState& exception_state) {
DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL)
<< __func__ << "(" << this << ") " << session_id;
@@ -556,12 +551,13 @@ ScriptPromise MediaKeySession::load(ScriptState* script_state,
// 1. If this object's closing or closed value is true, return a promise
// rejected with an InvalidStateError.
if (is_closing_or_closed_)
- return CreateRejectedPromiseAlreadyClosed(script_state);
+ return CreateRejectedPromiseAlreadyClosed(exception_state);
// 2. If this object's uninitialized value is false, return a promise
// rejected with an InvalidStateError.
- if (!is_uninitialized_)
- return CreateRejectedPromiseAlreadyInitialized(script_state);
+ if (!is_uninitialized_) {
+ return CreateRejectedPromiseAlreadyInitialized(exception_state);
+ }
// 3. Let this object's uninitialized value be false.
is_uninitialized_ = false;
@@ -569,20 +565,16 @@ ScriptPromise MediaKeySession::load(ScriptState* script_state,
// 4. If sessionId is the empty string, return a promise rejected with
// a newly created TypeError.
if (session_id.IsEmpty()) {
- return ScriptPromise::Reject(
- script_state,
- V8ThrowException::CreateTypeError(script_state->GetIsolate(),
- "The sessionId parameter is empty."));
+ exception_state.ThrowTypeError("The sessionId parameter is empty.");
+ return ScriptPromise();
}
// 5. If the result of running the "Is persistent session type?" algorithm
// on this object's session type is false, return a promise rejected
// with a newly created TypeError.
if (!IsPersistentSessionType(session_type_)) {
- return ScriptPromise::Reject(
- script_state,
- V8ThrowException::CreateTypeError(
- script_state->GetIsolate(), "The session type is not persistent."));
+ exception_state.ThrowTypeError("The session type is not persistent.");
+ return ScriptPromise();
}
// 6. Let origin be the origin of this object's Document.
@@ -680,7 +672,8 @@ void MediaKeySession::FinishLoad() {
}
ScriptPromise MediaKeySession::update(ScriptState* script_state,
- const DOMArrayPiece& response) {
+ const DOMArrayPiece& response,
+ ExceptionState& exception_state) {
DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ")";
// From https://w3c.github.io/encrypted-media/#update:
@@ -690,20 +683,18 @@ ScriptPromise MediaKeySession::update(ScriptState* script_state,
// 1. If this object's closing or closed value is true, return a promise
// rejected with an InvalidStateError.
if (is_closing_or_closed_)
- return CreateRejectedPromiseAlreadyClosed(script_state);
+ return CreateRejectedPromiseAlreadyClosed(exception_state);
// 2. If this object's callable value is false, return a promise
// rejected with an InvalidStateError.
if (!is_callable_)
- return CreateRejectedPromiseNotCallable(script_state);
+ return CreateRejectedPromiseNotCallable(exception_state);
// 3. If response is an empty array, return a promise rejected with a
// newly created TypeError.
if (!response.ByteLengthAsSizeT()) {
- return ScriptPromise::Reject(
- script_state,
- V8ThrowException::CreateTypeError(script_state->GetIsolate(),
- "The response parameter is empty."));
+ exception_state.ThrowTypeError("The response parameter is empty.");
+ return ScriptPromise();
}
// 4. Let response copy be a copy of the contents of the response parameter.
@@ -737,7 +728,8 @@ void MediaKeySession::UpdateTask(ContentDecryptionModuleResult* result,
// Last step (6.8.2 Resolve promise) will be done when |result| is resolved.
}
-ScriptPromise MediaKeySession::close(ScriptState* script_state) {
+ScriptPromise MediaKeySession::close(ScriptState* script_state,
+ ExceptionState& exception_state) {
DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ")";
// From https://w3c.github.io/encrypted-media/#close:
@@ -754,7 +746,7 @@ ScriptPromise MediaKeySession::close(ScriptState* script_state) {
// 2. If this object's callable value is false, return a promise rejected
// with an InvalidStateError.
if (!is_callable_)
- return CreateRejectedPromiseNotCallable(script_state);
+ return CreateRejectedPromiseNotCallable(exception_state);
// 3. Let promise be a new promise.
SimpleResultPromise* result = MakeGarbageCollected<SimpleResultPromise>(
@@ -783,7 +775,8 @@ void MediaKeySession::CloseTask(ContentDecryptionModuleResult* result) {
// Last step (5.3.2 Resolve promise) will be done when |result| is resolved.
}
-ScriptPromise MediaKeySession::remove(ScriptState* script_state) {
+ScriptPromise MediaKeySession::remove(ScriptState* script_state,
+ ExceptionState& exception_state) {
DVLOG(MEDIA_KEY_SESSION_LOG_LEVEL) << __func__ << "(" << this << ")";
// From https://w3c.github.io/encrypted-media/#remove:
@@ -793,12 +786,12 @@ ScriptPromise MediaKeySession::remove(ScriptState* script_state) {
// 1. If this object's closing or closed value is true, return a promise
// rejected with an InvalidStateError.
if (is_closing_or_closed_)
- return CreateRejectedPromiseAlreadyClosed(script_state);
+ return CreateRejectedPromiseAlreadyClosed(exception_state);
// 2. If this object's callable value is false, return a promise rejected
// with an InvalidStateError.
if (!is_callable_)
- return CreateRejectedPromiseNotCallable(script_state);
+ return CreateRejectedPromiseNotCallable(exception_state);
// 3. Let promise be a new promise.
SimpleResultPromise* result = MakeGarbageCollected<SimpleResultPromise>(
@@ -918,7 +911,7 @@ void MediaKeySession::Close() {
// 1. Let session be the associated MediaKeySession object.
// 2. Let promise be the session's closed attribute.
// 3. If promise is resolved, abort these steps.
- if (closed_promise_->GetState() == ScriptPromisePropertyBase::kResolved)
+ if (closed_promise_->GetState() == ClosedPromise::kResolved)
return;
// 4. Set the session's closing or closed value to true.
@@ -1018,7 +1011,7 @@ const AtomicString& MediaKeySession::InterfaceName() const {
}
ExecutionContext* MediaKeySession::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
bool MediaKeySession::HasPendingActivity() const {
@@ -1039,7 +1032,7 @@ bool MediaKeySession::HasPendingActivity() const {
(media_keys_ && !is_closing_or_closed_);
}
-void MediaKeySession::ContextDestroyed(ExecutionContext*) {
+void MediaKeySession::ContextDestroyed() {
// Stop the CDM from firing any more events for this session.
session_.reset();
is_closing_or_closed_ = true;
@@ -1047,14 +1040,14 @@ void MediaKeySession::ContextDestroyed(ExecutionContext*) {
pending_actions_.clear();
}
-void MediaKeySession::Trace(blink::Visitor* visitor) {
+void MediaKeySession::Trace(Visitor* visitor) {
visitor->Trace(async_event_queue_);
visitor->Trace(pending_actions_);
visitor->Trace(media_keys_);
visitor->Trace(key_statuses_map_);
visitor->Trace(closed_promise_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 6a0027cc825..1265494e9de 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
@@ -31,7 +31,7 @@
#include "third_party/blink/public/platform/web_encrypted_media_types.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_property.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_piece.h"
#include "third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
@@ -46,6 +46,7 @@ namespace blink {
class DOMException;
class EventQueue;
+class ExceptionState;
class MediaKeys;
// References are held by JS only. However, even if all JS references are
@@ -68,7 +69,7 @@ class MediaKeys;
class MediaKeySession final
: public EventTargetWithInlineData,
public ActiveScriptWrappable<MediaKeySession>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
private WebContentDecryptionModuleSession::Client {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(MediaKeySession);
@@ -87,11 +88,14 @@ class MediaKeySession final
ScriptPromise generateRequest(ScriptState*,
const String& init_data_type,
- const DOMArrayPiece& init_data);
- ScriptPromise load(ScriptState*, const String& session_id);
- ScriptPromise update(ScriptState*, const DOMArrayPiece& response);
- ScriptPromise close(ScriptState*);
- ScriptPromise remove(ScriptState*);
+ const DOMArrayPiece& init_data,
+ ExceptionState&);
+ ScriptPromise load(ScriptState*, const String& session_id, ExceptionState&);
+ ScriptPromise update(ScriptState*,
+ const DOMArrayPiece& response,
+ ExceptionState&);
+ ScriptPromise close(ScriptState*, ExceptionState&);
+ ScriptPromise remove(ScriptState*, ExceptionState&);
// EventTarget
const AtomicString& InterfaceName() const override;
@@ -100,10 +104,10 @@ class MediaKeySession final
// ScriptWrappable
bool HasPendingActivity() const final;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
class PendingAction;
@@ -153,9 +157,7 @@ class MediaKeySession final
bool is_closing_or_closed_;
// Keep track of the closed promise.
- typedef ScriptPromiseProperty<Member<MediaKeySession>,
- ToV8UndefinedGenerator,
- Member<DOMException>>
+ typedef ScriptPromiseProperty<ToV8UndefinedGenerator, Member<DOMException>>
ClosedPromise;
Member<ClosedPromise> closed_promise_;
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.idl b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.idl
index df6764a426d..58481d00b49 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.idl
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.idl
@@ -39,11 +39,11 @@
attribute EventHandler onmessage;
// session initialization
- [CallWith=ScriptState] Promise<void> generateRequest(DOMString initDataType, BufferSource initData);
- [CallWith=ScriptState] Promise<boolean> load(DOMString sessionId);
+ [CallWith=ScriptState, RaisesException] Promise<void> generateRequest(DOMString initDataType, BufferSource initData);
+ [CallWith=ScriptState, RaisesException] Promise<boolean> load(DOMString sessionId);
// session operations
- [CallWith=ScriptState] Promise<void> update(BufferSource response);
- [CallWith=ScriptState] Promise<void> close();
- [CallWith=ScriptState] Promise<void> remove();
+ [CallWith=ScriptState, RaisesException] Promise<void> update(BufferSource response);
+ [CallWith=ScriptState, RaisesException] Promise<void> close();
+ [CallWith=ScriptState, RaisesException] Promise<void> remove();
};
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 a81720dfb6d..7d481b963b6 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(blink::Visitor* visitor) { visitor->Trace(key_id_); }
+ virtual void Trace(Visitor* visitor) { visitor->Trace(key_id_); }
private:
const Member<DOMArrayBuffer> key_id_;
@@ -85,7 +85,7 @@ class MapIterationSource final
return true;
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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(blink::Visitor* visitor) {
+void MediaKeyStatusMap::Trace(Visitor* visitor) {
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 345c5f2f8e9..318fc6f2738 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
// PairIterable<> implementation.
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.cc
index 4b2c93a62a4..1bd3ef9a103 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.cc
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.cc
@@ -13,11 +13,11 @@
#include "third_party/blink/public/platform/web_encrypted_media_types.h"
#include "third_party/blink/public/platform/web_media_key_system_configuration.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_key_system_media_capability.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.h"
#include "third_party/blink/renderer/modules/encryptedmedia/encrypted_media_utils.h"
#include "third_party/blink/renderer/modules/encryptedmedia/media_key_session.h"
-#include "third_party/blink/renderer/modules/encryptedmedia/media_key_system_media_capability.h"
#include "third_party/blink/renderer/modules/encryptedmedia/media_keys.h"
#include "third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
@@ -93,7 +93,12 @@ static HeapVector<Member<MediaKeySystemMediaCapability>> ConvertCapabilities(
switch (capabilities[i].encryption_scheme) {
case WebMediaKeySystemMediaCapability::EncryptionScheme::kNotSpecified:
- capability->setEncryptionSchemeToNull();
+ // https://w3c.github.io/encrypted-media/#dom-mediakeysystemaccess-getconfiguration
+ // "If encryptionScheme was not given by the application, the
+ // accumulated configuration MUST still contain a encryptionScheme
+ // field with a value of null, so that polyfills can detect the user
+ // agent's support for the field without specifying specific values."
+ capability->setEncryptionScheme(String());
break;
case WebMediaKeySystemMediaCapability::EncryptionScheme::kCenc:
capability->setEncryptionScheme("cenc");
@@ -101,6 +106,13 @@ static HeapVector<Member<MediaKeySystemMediaCapability>> ConvertCapabilities(
case WebMediaKeySystemMediaCapability::EncryptionScheme::kCbcs:
capability->setEncryptionScheme("cbcs");
break;
+ case WebMediaKeySystemMediaCapability::EncryptionScheme::kCbcs_1_9:
+ capability->setEncryptionScheme("cbcs-1-9");
+ break;
+ case WebMediaKeySystemMediaCapability::EncryptionScheme::kUnrecognized:
+ NOTREACHED()
+ << "Unrecognized encryption scheme should never be returned.";
+ break;
}
result[i] = capability;
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.h
index 83f3e341da7..9de06de9b3c 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.h
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.h
@@ -8,7 +8,7 @@
#include <memory>
#include "third_party/blink/public/platform/web_content_decryption_module_access.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
-#include "third_party/blink/renderer/modules/encryptedmedia/media_key_system_configuration.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_key_system_configuration.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
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 b899dfac859..3b7d06f65e6 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
@@ -4,14 +4,15 @@
#include "third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.h"
+#include "base/metrics/histogram_functions.h"
#include "media/base/eme_constants.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_key_system_media_capability.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/modules/encryptedmedia/encrypted_media_utils.h"
-#include "third_party/blink/renderer/modules/encryptedmedia/media_key_system_media_capability.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/network/parsed_content_type.h"
#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
@@ -33,9 +34,11 @@ ConvertEncryptionScheme(const String& encryption_scheme) {
return WebMediaKeySystemMediaCapability::EncryptionScheme::kCenc;
if (encryption_scheme == "cbcs")
return WebMediaKeySystemMediaCapability::EncryptionScheme::kCbcs;
+ if (encryption_scheme == "cbcs-1-9")
+ return WebMediaKeySystemMediaCapability::EncryptionScheme::kCbcs_1_9;
- NOTREACHED();
- return WebMediaKeySystemMediaCapability::EncryptionScheme::kNotSpecified;
+ // Any other strings are not recognized (and therefore not supported).
+ return WebMediaKeySystemMediaCapability::EncryptionScheme::kUnrecognized;
}
static WebVector<WebMediaKeySystemMediaCapability> ConvertCapabilities(
@@ -57,14 +60,8 @@ static WebVector<WebMediaKeySystemMediaCapability> ConvertCapabilities(
if (type.GetParameters().ParameterCount() == 1u)
result[i].codecs = type.ParameterValueForName("codecs");
}
- result[i].robustness = capabilities[i]->robustness();
- // From
- // https://github.com/WICG/encrypted-media-encryption-scheme/blob/master/explainer.md
- // "Asking for "any" encryption scheme is unrealistic. Defining null as
- // "any scheme" is convenient for backward compatibility, though.
- // Applications which ignore this feature by leaving encryptionScheme null
- // get the same user agent behavior they did before this feature existed."
+ result[i].robustness = capabilities[i]->robustness();
result[i].encryption_scheme =
capabilities[i]->hasEncryptionScheme()
? ConvertEncryptionScheme(capabilities[i]->encryptionScheme())
@@ -88,7 +85,7 @@ MediaKeySystemAccessInitializerBase::MediaKeySystemAccessInitializerBase(
const String& key_system,
const HeapVector<Member<MediaKeySystemConfiguration>>&
supported_configurations)
- : ContextLifecycleObserver(ExecutionContext::From((script_state))),
+ : ExecutionContextClient(ExecutionContext::From((script_state))),
resolver_(MakeGarbageCollected<ScriptPromiseResolver>(script_state)),
key_system_(key_system),
supported_configurations_(supported_configurations.size()) {
@@ -149,10 +146,10 @@ ScriptPromise MediaKeySystemAccessInitializerBase::Promise() {
return resolver_->Promise();
}
-void MediaKeySystemAccessInitializerBase::Trace(blink::Visitor* visitor) {
+void MediaKeySystemAccessInitializerBase::Trace(Visitor* visitor) {
visitor->Trace(resolver_);
EncryptedMediaRequest::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
bool MediaKeySystemAccessInitializerBase::IsExecutionContextValid() const {
@@ -201,28 +198,28 @@ void MediaKeySystemAccessInitializerBase::CheckVideoCapabilityRobustness()
}
if (has_video_capabilities) {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- EnumerationHistogram, empty_robustness_histogram,
- ("Media.EME.Widevine.VideoCapability.HasEmptyRobustness", 2));
- empty_robustness_histogram.Count(has_empty_robustness);
+ base::UmaHistogramBoolean(
+ "Media.EME.Widevine.VideoCapability.HasEmptyRobustness",
+ has_empty_robustness);
}
if (has_empty_robustness) {
// TODO(xhwang): Write a best practice doc explaining details about risks of
// using an empty robustness here, and provide the link to the doc in this
// message. See http://crbug.com/720013
- GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning,
- "It is recommended that a robustness level be specified. Not "
- "specifying the robustness level could result in unexpected "
- "behavior."));
+ GetExecutionContext()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning,
+ "It is recommended that a robustness level be specified. Not "
+ "specifying the robustness level could result in unexpected "
+ "behavior."));
}
if (!IsExecutionContextValid())
return;
- Document* document = To<Document>(GetExecutionContext());
+ Document* document = Document::From(GetExecutionContext());
if (!document)
return;
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 a801ec18df8..aec82d333db 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
@@ -8,8 +8,8 @@
#include "third_party/blink/public/platform/web_media_key_system_configuration.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
-#include "third_party/blink/renderer/modules/encryptedmedia/media_key_system_configuration.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_key_system_configuration.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/encrypted_media_request.h"
#include "third_party/blink/renderer/platform/heap/member.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -17,7 +17,7 @@
namespace blink {
class MediaKeySystemAccessInitializerBase : public EncryptedMediaRequest,
- public ContextLifecycleObserver {
+ public ExecutionContextClient {
USING_GARBAGE_COLLECTED_MIXIN(MediaKeySystemAccessInitializerBase);
public:
@@ -41,7 +41,7 @@ class MediaKeySystemAccessInitializerBase : public EncryptedMediaRequest,
// Promise() in script_promise_resolver.h
ScriptPromise Promise();
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
protected:
// Returns true if the ExecutionContext is valid, false otherwise.
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_media_capability.idl b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_media_capability.idl
index 2f28129e003..f475a843f5b 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_media_capability.idl
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_media_capability.idl
@@ -2,12 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://w3c.github.io/encrypted-media/#idl-def-MediaKeySystemMediaCapability
-
-enum EncryptionScheme { "cenc", "cbcs" };
+// https://w3c.github.io/encrypted-media/#mediakeysystemmediacapability-dictionary
dictionary MediaKeySystemMediaCapability {
DOMString contentType = "";
DOMString robustness = "";
- [RuntimeEnabled=EncryptedMediaEncryptionSchemeQuery] EncryptionScheme? encryptionScheme = null;
+ [RuntimeEnabled=EncryptedMediaEncryptionSchemeQuery] DOMString? encryptionScheme = null;
};
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 e6c90316474..82a2c622ebe 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc
@@ -32,6 +32,7 @@
#include "third_party/blink/public/platform/web_content_decryption_module.h"
#include "third_party/blink/public/platform/web_encrypted_media_key_information.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_keys_policy.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/html/media/html_media_element.h"
@@ -39,7 +40,7 @@
#include "third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.h"
#include "third_party/blink/renderer/modules/encryptedmedia/encrypted_media_utils.h"
#include "third_party/blink/renderer/modules/encryptedmedia/media_key_session.h"
-#include "third_party/blink/renderer/modules/encryptedmedia/media_keys_policy.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/v8_throw_exception.h"
#include "third_party/blink/renderer/platform/instrumentation/instance_counters.h"
@@ -95,7 +96,7 @@ class MediaKeys::PendingAction final
const String& string_data)
: type_(type), result_(result), data_(data), string_data_(string_data) {}
- void Trace(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
visitor->Trace(result_);
visitor->Trace(data_);
}
@@ -153,7 +154,7 @@ class SetCertificateResultPromise
exception_code, system_code, error_message);
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(media_keys_);
ContentDecryptionModuleResultPromise::Trace(visitor);
}
@@ -189,7 +190,7 @@ class GetStatusForPolicyResultPromise
Resolve(EncryptedMediaUtils::ConvertKeyStatusToString(key_status));
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(media_keys_);
ContentDecryptionModuleResultPromise::Trace(visitor);
}
@@ -204,7 +205,7 @@ MediaKeys::MediaKeys(
ExecutionContext* context,
const WebVector<WebEncryptedMediaSessionType>& supported_session_types,
std::unique_ptr<WebContentDecryptionModule> cdm)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
supported_session_types_(supported_session_types),
cdm_(std::move(cdm)),
media_element_(nullptr),
@@ -271,7 +272,8 @@ MediaKeySession* MediaKeys::createSession(ScriptState* script_state,
ScriptPromise MediaKeys::setServerCertificate(
ScriptState* script_state,
- const DOMArrayPiece& server_certificate) {
+ const DOMArrayPiece& server_certificate,
+ ExceptionState& exception_state) {
// 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.
@@ -285,10 +287,8 @@ ScriptPromise MediaKeys::setServerCertificate(
// 2. If serverCertificate is an empty array, return a promise rejected
// with a new a newly created TypeError.
if (!server_certificate.ByteLengthAsSizeT()) {
- return ScriptPromise::Reject(
- script_state, V8ThrowException::CreateTypeError(
- script_state->GetIsolate(),
- "The serverCertificate parameter is empty."));
+ exception_state.ThrowTypeError("The serverCertificate parameter is empty.");
+ return ScriptPromise();
}
// 3. Let certificate be a copy of the contents of the serverCertificate
@@ -423,19 +423,19 @@ WebContentDecryptionModule* MediaKeys::ContentDecryptionModule() {
return cdm_.get();
}
-void MediaKeys::Trace(blink::Visitor* visitor) {
+void MediaKeys::Trace(Visitor* visitor) {
visitor->Trace(pending_actions_);
visitor->Trace(media_element_);
ScriptWrappable::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
-void MediaKeys::ContextDestroyed(ExecutionContext*) {
+void MediaKeys::ContextDestroyed() {
timer_.Stop();
pending_actions_.clear();
// We don't need the CDM anymore. Only destroyed after all related
- // ContextLifecycleObservers have been stopped.
+ // ExecutionContextLifecycleObservers have been stopped.
cdm_.reset();
}
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 542e066ab44..ba2d0093ba8 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.h
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.h
@@ -33,7 +33,7 @@
#include "third_party/blink/public/platform/web_vector.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/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_piece.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/timer.h"
@@ -54,7 +54,7 @@ class WebContentDecryptionModule;
// The WebContentDecryptionModule has the same lifetime as this object.
class MediaKeys : public ScriptWrappable,
public ActiveScriptWrappable<MediaKeys>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(MediaKeys);
DEFINE_WRAPPERTYPEINFO();
@@ -70,7 +70,8 @@ class MediaKeys : public ScriptWrappable,
ExceptionState&);
ScriptPromise setServerCertificate(ScriptState*,
- const DOMArrayPiece& server_certificate);
+ const DOMArrayPiece& server_certificate,
+ ExceptionState& exception_state);
ScriptPromise getStatusForPolicy(ScriptState*, const MediaKeysPolicy*);
@@ -92,12 +93,12 @@ class MediaKeys : public ScriptWrappable,
WebContentDecryptionModule* ContentDecryptionModule();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
- // ContextLifecycleObserver implementation.
- // FIXME: This class could derive from ContextLifecycleObserver
+ // ExecutionContextLifecycleObserver implementation.
+ // FIXME: This class could derive from ExecutionContextLifecycleObserver
// again (http://crbug.com/483722).
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
// ScriptWrappable implementation.
bool HasPendingActivity() const final;
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.idl b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.idl
index eb0c8fddc20..48939bff469 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.idl
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.idl
@@ -38,5 +38,5 @@ enum MediaKeySessionType {
] interface MediaKeys {
[CallWith=ScriptState, RaisesException] MediaKeySession createSession(optional MediaKeySessionType sessionType = "temporary");
- [CallWith=ScriptState] Promise<boolean> setServerCertificate(BufferSource serverCertificate);
+ [CallWith=ScriptState, RaisesException] Promise<boolean> setServerCertificate(BufferSource serverCertificate);
};
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.cc
index db835f6bb53..ebb5fee5b46 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.cc
@@ -18,7 +18,7 @@ MediaKeysController::MediaKeysController() = default;
WebEncryptedMediaClient* MediaKeysController::EncryptedMediaClient(
ExecutionContext* context) {
- Document* document = To<Document>(context);
+ Document* document = Document::From(context);
WebLocalFrameImpl* web_frame =
WebLocalFrameImpl::FromFrame(document->GetFrame());
return web_frame->Client()->EncryptedMediaClient();
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 84679be99f3..e53eb2c7fd3 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,9 +30,7 @@ class MODULES_EXPORT MediaKeysController final
MediaKeysController();
- void Trace(blink::Visitor* visitor) override {
- Supplement<Page>::Trace(visitor);
- }
+ void Trace(Visitor* visitor) 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 c948f26aebc..0b12f4d3a03 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
@@ -5,8 +5,8 @@
#include "third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_keys_policy.h"
#include "third_party/blink/renderer/modules/encryptedmedia/media_keys.h"
-#include "third_party/blink/renderer/modules/encryptedmedia/media_keys_policy.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
namespace blink {
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 12f7156bcc8..e4b71e783c2 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
@@ -27,6 +27,7 @@
#include "third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.h"
#include "third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.h"
#include "third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.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/v8_throw_exception.h"
#include "third_party/blink/renderer/platform/encrypted_media_request.h"
@@ -58,7 +59,7 @@ class MediaKeySystemAccessInitializer final
std::unique_ptr<WebContentDecryptionModuleAccess>) override;
void RequestNotSupported(const WebString& error_message) override;
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
MediaKeySystemAccessInitializerBase::Trace(visitor);
}
@@ -106,25 +107,25 @@ ScriptPromise NavigatorRequestMediaKeySystemAccess::requestMediaKeySystemAccess(
Navigator& navigator,
const String& key_system,
const HeapVector<Member<MediaKeySystemConfiguration>>&
- supported_configurations) {
+ supported_configurations,
+ ExceptionState& exception_state) {
DVLOG(3) << __func__;
ExecutionContext* execution_context = ExecutionContext::From(script_state);
- Document* document = To<Document>(execution_context);
+ Document* document = Document::From(execution_context);
- if (!document->IsFeatureEnabled(mojom::FeaturePolicyFeature::kEncryptedMedia,
- ReportOptions::kReportOnFailure)) {
+ if (!document->IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kEncryptedMedia,
+ ReportOptions::kReportOnFailure)) {
UseCounter::Count(document,
WebFeature::kEncryptedMediaDisabledByFeaturePolicy);
- document->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning,
- kEncryptedMediaFeaturePolicyConsoleWarning));
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kSecurityError,
- "requestMediaKeySystemAccess is disabled by feature policy."));
+ document->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning,
+ kEncryptedMediaFeaturePolicyConsoleWarning));
+ exception_state.ThrowSecurityError(
+ "requestMediaKeySystemAccess is disabled by feature policy.");
+ return ScriptPromise();
}
// From https://w3c.github.io/encrypted-media/#requestMediaKeySystemAccess
@@ -132,29 +133,25 @@ ScriptPromise NavigatorRequestMediaKeySystemAccess::requestMediaKeySystemAccess(
// 1. If keySystem is the empty string, return a promise rejected with a
// newly created TypeError.
if (key_system.IsEmpty()) {
- return ScriptPromise::Reject(
- script_state,
- V8ThrowException::CreateTypeError(script_state->GetIsolate(),
- "The keySystem parameter is empty."));
+ exception_state.ThrowTypeError("The keySystem parameter is empty.");
+ return ScriptPromise();
}
// 2. If supportedConfigurations is empty, return a promise rejected with
// a newly created TypeError.
if (!supported_configurations.size()) {
- return ScriptPromise::Reject(
- script_state, V8ThrowException::CreateTypeError(
- script_state->GetIsolate(),
- "The supportedConfigurations parameter is empty."));
+ exception_state.ThrowTypeError(
+ "The supportedConfigurations parameter is empty.");
+ return ScriptPromise();
}
// 3. Let document be the calling context's Document.
// (Done at the begining of this function.)
if (!document->GetPage()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "The context provided is not associated with a page."));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "The context provided is not associated with a page.");
+ return ScriptPromise();
}
UseCounter::Count(*document, WebFeature::kEncryptedMediaSecureOrigin);
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.h
index cce5d48f045..cb598d46810 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.h
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.h
@@ -8,12 +8,13 @@
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_media_key_system_configuration.h"
#include "third_party/blink/renderer/core/frame/navigator.h"
-#include "third_party/blink/renderer/modules/encryptedmedia/media_key_system_configuration.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
namespace blink {
+class ExceptionState;
+
class NavigatorRequestMediaKeySystemAccess {
STATIC_ONLY(NavigatorRequestMediaKeySystemAccess);
@@ -23,7 +24,8 @@ class NavigatorRequestMediaKeySystemAccess {
Navigator&,
const String& key_system,
const HeapVector<Member<MediaKeySystemConfiguration>>&
- supported_configurations);
+ supported_configurations,
+ ExceptionState&);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.idl b/chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.idl
index a71acbeed9b..e1a19bb5faf 100644
--- a/chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.idl
+++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.idl
@@ -7,5 +7,5 @@
[
ImplementedAs=NavigatorRequestMediaKeySystemAccess
] partial interface Navigator {
- [SecureContext, CallWith=ScriptState] Promise<MediaKeySystemAccess> requestMediaKeySystemAccess(DOMString keySystem, sequence<MediaKeySystemConfiguration> supportedConfigurations);
+ [SecureContext, CallWith=ScriptState, RaisesException] Promise<MediaKeySystemAccess> requestMediaKeySystemAccess(DOMString keySystem, sequence<MediaKeySystemConfiguration> supportedConfigurations);
};
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 631acfc8425..e951fd1268f 100644
--- a/chromium/third_party/blink/renderer/modules/eventsource/event_source.cc
+++ b/chromium/third_party/blink/renderer/modules/eventsource/event_source.cc
@@ -33,11 +33,13 @@
#include "third_party/blink/renderer/modules/eventsource/event_source.h"
#include <memory>
+
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/renderer/bindings/core/v8/script_controller.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/modules/v8/v8_event_source_init.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/events/message_event.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -47,8 +49,8 @@
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/loader/threadable_loader.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
-#include "third_party/blink/renderer/modules/eventsource/event_source_init.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/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_error.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
@@ -65,7 +67,7 @@ const uint64_t EventSource::kDefaultReconnectDelay = 3000;
inline EventSource::EventSource(ExecutionContext* context,
const KURL& url,
const EventSourceInit* event_source_init)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
url_(url),
current_url_(url),
with_credentials_(event_source_init->withCredentials()),
@@ -79,7 +81,7 @@ EventSource* EventSource::Create(ExecutionContext* context,
const String& url,
const EventSourceInit* event_source_init,
ExceptionState& exception_state) {
- UseCounter::Count(context, IsA<Document>(context)
+ UseCounter::Count(context, context->IsDocument()
? WebFeature::kEventSourceDocument
: WebFeature::kEventSourceWorker);
@@ -216,7 +218,7 @@ const AtomicString& EventSource::InterfaceName() const {
}
ExecutionContext* EventSource::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
void EventSource::DidReceiveResponse(uint64_t identifier,
@@ -235,16 +237,17 @@ void EventSource::DidReceiveResponse(uint64_t identifier,
const String& charset = response.TextEncodingName();
// If we have a charset, the only allowed value is UTF-8 (case-insensitive).
response_is_valid =
- charset.IsEmpty() || DeprecatedEqualIgnoringCase(charset, "UTF-8");
+ charset.IsEmpty() || EqualIgnoringASCIICase(charset, "UTF-8");
if (!response_is_valid) {
StringBuilder message;
message.Append("EventSource's response has a charset (\"");
message.Append(charset);
message.Append("\") that is not UTF-8. Aborting the connection.");
// FIXME: We are missing the source line.
- GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kError, message.ToString()));
+ GetExecutionContext()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kError, message.ToString()));
}
} else {
// To keep the signal-to-noise ratio low, we only log 200-response with an
@@ -256,9 +259,10 @@ void EventSource::DidReceiveResponse(uint64_t identifier,
message.Append(
"\") that is not \"text/event-stream\". Aborting the connection.");
// FIXME: We are missing the source line.
- GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kError, message.ToString()));
+ GetExecutionContext()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kError, message.ToString()));
}
}
@@ -347,7 +351,7 @@ void EventSource::AbortConnectionAttempt() {
DispatchEvent(*Event::Create(event_type_names::kError));
}
-void EventSource::ContextDestroyed(ExecutionContext*) {
+void EventSource::ContextDestroyed() {
close();
}
@@ -355,12 +359,12 @@ bool EventSource::HasPendingActivity() const {
return state_ != kClosed;
}
-void EventSource::Trace(blink::Visitor* visitor) {
+void EventSource::Trace(Visitor* visitor) {
visitor->Trace(parser_);
visitor->Trace(loader_);
EventTargetWithInlineData::Trace(visitor);
ThreadableLoaderClient::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
EventSourceParser::Client::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 c462a4dd129..28c28d52645 100644
--- a/chromium/third_party/blink/renderer/modules/eventsource/event_source.h
+++ b/chromium/third_party/blink/renderer/modules/eventsource/event_source.h
@@ -35,7 +35,7 @@
#include <memory>
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/loader/threadable_loader.h"
#include "third_party/blink/renderer/core/loader/threadable_loader_client.h"
#include "third_party/blink/renderer/modules/eventsource/event_source_parser.h"
@@ -55,7 +55,7 @@ class MODULES_EXPORT EventSource final
: public EventTargetWithInlineData,
public ThreadableLoaderClient,
public ActiveScriptWrappable<EventSource>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public EventSourceParser::Client {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(EventSource);
@@ -87,19 +87,18 @@ class MODULES_EXPORT EventSource final
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
- // ContextLifecycleObserver
+ // ExecutionContextLifecycleObserver
//
- // Note: We don't need to inherit from ContextLifecycleStateObserver since
- // ScopedPageLoadDeferrer calls Page::setDefersLoading() and
- // it defers delivery of events from the loader, and therefore
- // the methods of this class for receiving asynchronous events
- // from the loader won't be invoked.
- void ContextDestroyed(ExecutionContext*) override;
+ // Note: We don't need to inherit from ExecutionContextLifecycleStateObserver
+ // since ScopedPageLoadDeferrer calls Page::setDefersLoading() and it defers
+ // delivery of events from the loader, and therefore the methods of this class
+ // for receiving asynchronous events from the loader won't be invoked.
+ void ContextDestroyed() override;
// ScriptWrappable
bool HasPendingActivity() const final;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void DidReceiveResponse(uint64_t, const ResourceResponse&) override;
diff --git a/chromium/third_party/blink/renderer/modules/eventsource/event_source.idl b/chromium/third_party/blink/renderer/modules/eventsource/event_source.idl
index 900568acde1..a6c134482c8 100644
--- a/chromium/third_party/blink/renderer/modules/eventsource/event_source.idl
+++ b/chromium/third_party/blink/renderer/modules/eventsource/event_source.idl
@@ -33,11 +33,9 @@
[
ActiveScriptWrappable,
- Constructor(USVString url, optional EventSourceInit eventSourceInitDict),
- ConstructorCallWith=ExecutionContext,
- Exposed=(Window,Worker),
- RaisesException=Constructor
+ Exposed=(Window,Worker)
] interface EventSource : EventTarget {
+ [CallWith=ExecutionContext, RaisesException] constructor(USVString url, optional EventSourceInit eventSourceInitDict = {});
readonly attribute USVString url;
readonly attribute boolean withCredentials;
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 95a6664ebbd..461a09b3565 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(blink::Visitor* visitor) {
+void EventSourceParser::Trace(Visitor* visitor) {
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 e2b79059674..4291b23a5c7 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(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) 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(blink::Visitor*);
+ void Trace(Visitor*);
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 d36aed3595a..90acf6ba628 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(parser_);
EventSourceParser::Client::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/eventsource/idls.gni b/chromium/third_party/blink/renderer/modules/eventsource/idls.gni
new file mode 100644
index 00000000000..e50a5c4b1ce
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/eventsource/idls.gni
@@ -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.
+
+modules_idl_files = [ "event_source.idl" ]
+
+modules_dictionary_idl_files = [ "event_source_init.idl" ]
diff --git a/chromium/third_party/blink/renderer/modules/exported/BUILD.gn b/chromium/third_party/blink/renderer/modules/exported/BUILD.gn
index bcd3ab535ae..e1bb5924f2e 100644
--- a/chromium/third_party/blink/renderer/modules/exported/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/exported/BUILD.gn
@@ -12,14 +12,11 @@ blink_modules_sources("exported") {
"web_dom_media_stream_track.cc",
"web_embedded_worker_impl.cc",
"web_embedded_worker_impl.h",
- "web_user_media_request.cc",
]
defines = [ "BLINK_MODULES_IMPLEMENTATION=1" ]
- deps = [
- "//ui/accessibility:ax_enums_mojo_blink",
- ]
+ deps = [ "//ui/accessibility:ax_enums_mojo_blink" ]
}
static_library("test_support") {
@@ -33,9 +30,7 @@ static_library("test_support") {
"//v8",
]
- sources = [
- "web_testing_support.cc",
- ]
+ sources = [ "web_testing_support.cc" ]
configs += [
"//third_party/blink/renderer:config",
diff --git a/chromium/third_party/blink/renderer/modules/exported/OWNERS b/chromium/third_party/blink/renderer/modules/exported/OWNERS
index 6cb3ea72efb..d0ff0ac2d72 100644
--- a/chromium/third_party/blink/renderer/modules/exported/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/exported/OWNERS
@@ -3,3 +3,7 @@ kinuko@chromium.org
# Workers
per-file web_embedded_worker_impl.h=file://content/browser/service_worker/OWNERS
per-file web_embedded_worker_impl.cc=file://content/browser/service_worker/OWNERS
+
+# Accessibility
+per-file web_ax_object.h=file://third_party/blink/renderer/modules/accessibility/OWNERS
+per-file web_ax_object.cc=file://third_party/blink/renderer/modules/accessibility/OWNERS
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 8e4a75ab03b..6db5a589ad6 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
@@ -31,7 +31,6 @@
#include "third_party/blink/public/web/web_ax_object.h"
#include "third_party/blink/public/platform/web_float_rect.h"
-#include "third_party/blink/public/platform/web_point.h"
#include "third_party/blink/public/platform/web_rect.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_url.h"
@@ -65,23 +64,23 @@
namespace blink {
namespace {
-blink::ScrollAlignmentBehavior ToBlinkScrollAlignmentBehavior(
+mojom::blink::ScrollAlignment::Behavior ToBlinkScrollAlignmentBehavior(
ax::mojom::ScrollAlignment alignment) {
switch (alignment) {
case ax::mojom::ScrollAlignment::kNone:
- return blink::kScrollAlignmentNoScroll;
+ return mojom::blink::ScrollAlignment::Behavior::kNoScroll;
case ax::mojom::ScrollAlignment::kScrollAlignmentCenter:
- return blink::kScrollAlignmentCenter;
+ return mojom::blink::ScrollAlignment::Behavior::kCenter;
case ax::mojom::ScrollAlignment::kScrollAlignmentTop:
- return blink::kScrollAlignmentTop;
+ return mojom::blink::ScrollAlignment::Behavior::kTop;
case ax::mojom::ScrollAlignment::kScrollAlignmentBottom:
- return blink::kScrollAlignmentBottom;
+ return mojom::blink::ScrollAlignment::Behavior::kBottom;
case ax::mojom::ScrollAlignment::kScrollAlignmentLeft:
- return blink::kScrollAlignmentLeft;
+ return mojom::blink::ScrollAlignment::Behavior::kLeft;
case ax::mojom::ScrollAlignment::kScrollAlignmentRight:
- return blink::kScrollAlignmentRight;
+ return mojom::blink::ScrollAlignment::Behavior::kRight;
case ax::mojom::ScrollAlignment::kScrollAlignmentClosestEdge:
- return blink::kScrollAlignmentClosestEdge;
+ return mojom::blink::ScrollAlignment::Behavior::kClosestEdge;
}
NOTREACHED() << alignment;
}
@@ -195,9 +194,8 @@ bool WebAXObject::UpdateLayoutAndCheckValidity() {
Document* document = private_->GetDocument();
if (!document || !document->View())
return false;
- if (IsLayoutClean(document))
- return true;
- if (!document->View()->UpdateLifecycleToCompositingCleanPlusScrolling())
+ if (!document->View()->UpdateLifecycleToCompositingCleanPlusScrolling(
+ DocumentUpdateReason::kAccessibility))
return false;
}
@@ -255,7 +253,7 @@ WebAXObject WebAXObject::ParentObject() const {
if (IsDetached())
return WebAXObject();
- return WebAXObject(private_->ParentObject());
+ return WebAXObject(private_->ParentObjectIncludedInTree());
}
void WebAXObject::GetSparseAXAttributes(
@@ -372,13 +370,6 @@ bool WebAXObject::IsLinked() const {
return private_->IsLinked();
}
-bool WebAXObject::IsLoaded() const {
- if (IsDetached())
- return false;
-
- return private_->IsLoaded();
-}
-
bool WebAXObject::IsModal() const {
if (IsDetached())
return false;
@@ -442,6 +433,13 @@ bool WebAXObject::IsVisited() const {
return private_->IsVisited();
}
+bool WebAXObject::HasAriaAttribute() const {
+ if (IsDetached())
+ return false;
+
+ return private_->HasAriaAttribute();
+}
+
WebString WebAXObject::AccessKey() const {
if (IsDetached())
return WebString();
@@ -673,13 +671,6 @@ WebString WebAXObject::AriaInvalidValue() const {
return private_->AriaInvalidValue();
}
-double WebAXObject::EstimatedLoadingProgress() const {
- if (IsDetached())
- return 0.0;
-
- return private_->EstimatedLoadingProgress();
-}
-
int WebAXObject::HeadingLevel() const {
if (IsDetached())
return 0;
@@ -698,14 +689,14 @@ int WebAXObject::HierarchicalLevel() const {
// that (0, 0) is the top left of the visual viewport. In other words, the
// point has the VisualViewport scale applied, but not the VisualViewport
// offset. crbug.com/459591.
-WebAXObject WebAXObject::HitTest(const WebPoint& point) const {
+WebAXObject WebAXObject::HitTest(const gfx::Point& point) const {
if (IsDetached())
return WebAXObject();
ScopedActionAnnotator annotater(private_.Get());
IntPoint contents_point =
private_->DocumentFrameView()->SoonToBeRemovedUnscaledViewportToContents(
- point);
+ IntPoint(point));
AXObject* hit = private_->AccessibilityHitTest(contents_point);
if (hit)
@@ -835,6 +826,27 @@ static ax::mojom::TextAffinity ToAXAffinity(TextAffinity affinity) {
}
}
+bool WebAXObject::IsLoaded() const {
+ if (IsDetached())
+ return false;
+
+ return private_->IsLoaded();
+}
+
+double WebAXObject::EstimatedLoadingProgress() const {
+ if (IsDetached())
+ return 0.0;
+
+ return private_->EstimatedLoadingProgress();
+}
+
+WebAXObject WebAXObject::RootScroller() const {
+ if (IsDetached())
+ return WebAXObject();
+
+ return WebAXObject(private_->RootScroller());
+}
+
void WebAXObject::Selection(bool& is_selection_backward,
WebAXObject& anchor_object,
int& anchor_offset,
@@ -1206,28 +1218,11 @@ WebDocument WebAXObject::GetDocument() const {
return WebDocument(document);
}
-bool WebAXObject::HasComputedStyle() const {
- if (IsDetached())
- return false;
-
- Document* document = private_->GetDocument();
- if (document)
- document->UpdateStyleAndLayoutTree();
-
- Node* node = private_->GetNode();
- if (!node || node->IsDocumentNode())
- return false;
-
- return node->GetComputedStyle();
-}
-
WebString WebAXObject::ComputedStyleDisplay() const {
if (IsDetached())
return WebString();
- Document* document = private_->GetDocument();
- if (document)
- document->UpdateStyleAndLayoutTree();
+ DCHECK(IsLayoutClean(private_->GetDocument()));
Node* node = private_->GetNode();
if (!node || node->IsDocumentNode())
@@ -1521,32 +1516,38 @@ bool WebAXObject::IsScrollableContainer() const {
return private_->IsScrollableContainer();
}
-WebPoint WebAXObject::GetScrollOffset() const {
+bool WebAXObject::IsUserScrollable() const {
if (IsDetached())
- return WebPoint();
+ return false;
+
+ return private_->IsUserScrollable();
+}
+gfx::Point WebAXObject::GetScrollOffset() const {
+ if (IsDetached())
+ return gfx::Point();
return private_->GetScrollOffset();
}
-WebPoint WebAXObject::MinimumScrollOffset() const {
+gfx::Point WebAXObject::MinimumScrollOffset() const {
if (IsDetached())
- return WebPoint();
+ return gfx::Point();
return private_->MinimumScrollOffset();
}
-WebPoint WebAXObject::MaximumScrollOffset() const {
+gfx::Point WebAXObject::MaximumScrollOffset() const {
if (IsDetached())
- return WebPoint();
+ return gfx::Point();
return private_->MaximumScrollOffset();
}
-void WebAXObject::SetScrollOffset(const WebPoint& offset) const {
+void WebAXObject::SetScrollOffset(const gfx::Point& offset) const {
if (IsDetached())
return;
- private_->SetScrollOffset(offset);
+ private_->SetScrollOffset(IntPoint(offset));
}
void WebAXObject::Dropeffects(
@@ -1571,9 +1572,7 @@ void WebAXObject::GetRelativeBounds(WebAXObject& offset_container,
if (IsDetached())
return;
-#if DCHECK_IS_ON()
DCHECK(IsLayoutClean(private_->GetDocument()));
-#endif
AXObject* container = nullptr;
FloatRect bounds;
@@ -1605,30 +1604,30 @@ bool WebAXObject::ScrollToMakeVisibleWithSubFocus(
auto vertical_behavior =
ToBlinkScrollAlignmentBehavior(vertical_scroll_alignment);
- blink::ScrollAlignmentBehavior visible_horizontal_behavior =
+ mojom::blink::ScrollAlignment::Behavior visible_horizontal_behavior =
scroll_behavior == ax::mojom::ScrollBehavior::kScrollIfVisible
? horizontal_behavior
- : kScrollAlignmentNoScroll;
- blink::ScrollAlignmentBehavior visible_vertical_behavior =
+ : mojom::blink::ScrollAlignment::Behavior::kNoScroll;
+ mojom::blink::ScrollAlignment::Behavior visible_vertical_behavior =
scroll_behavior == ax::mojom::ScrollBehavior::kScrollIfVisible
? vertical_behavior
- : kScrollAlignmentNoScroll;
+ : mojom::blink::ScrollAlignment::Behavior::kNoScroll;
- blink::ScrollAlignment blink_horizontal_scroll_alignment = {
+ blink::mojom::blink::ScrollAlignment blink_horizontal_scroll_alignment = {
visible_horizontal_behavior, horizontal_behavior, horizontal_behavior};
- blink::ScrollAlignment blink_vertical_scroll_alignment = {
+ blink::mojom::blink::ScrollAlignment blink_vertical_scroll_alignment = {
visible_vertical_behavior, vertical_behavior, vertical_behavior};
return private_->RequestScrollToMakeVisibleWithSubFocusAction(
subfocus, blink_horizontal_scroll_alignment,
blink_vertical_scroll_alignment);
}
-bool WebAXObject::ScrollToGlobalPoint(const WebPoint& point) const {
+bool WebAXObject::ScrollToGlobalPoint(const gfx::Point& point) const {
if (IsDetached())
return false;
ScopedActionAnnotator annotater(private_.Get());
- return private_->RequestScrollToGlobalPointAction(point);
+ return private_->RequestScrollToGlobalPointAction(IntPoint(point));
}
void WebAXObject::Swap(WebAXObject& other) {
@@ -1649,6 +1648,13 @@ void WebAXObject::HandleAutofillStateChanged(
private_->HandleAutofillStateChanged(state);
}
+int WebAXObject::GetDOMNodeId() const {
+ if (IsDetached())
+ return 0;
+
+ return private_->GetDOMNodeId();
+}
+
WebString WebAXObject::ToString() const {
if (IsDetached())
return WebString();
@@ -1707,7 +1713,7 @@ WebAXObject::operator AXObject*() const {
WebAXObject WebAXObject::FromWebNode(const WebNode& web_node) {
WebDocument web_document = web_node.GetDocument();
const Document* doc = web_document.ConstUnwrap<Document>();
- AXObjectCacheImpl* cache = ToAXObjectCacheImpl(doc->ExistingAXObjectCache());
+ auto* cache = To<AXObjectCacheImpl>(doc->ExistingAXObjectCache());
const Node* node = web_node.ConstUnwrap<Node>();
return cache ? WebAXObject(cache->Get(node)) : WebAXObject();
}
@@ -1715,8 +1721,7 @@ WebAXObject WebAXObject::FromWebNode(const WebNode& web_node) {
// static
WebAXObject WebAXObject::FromWebDocument(const WebDocument& web_document) {
const Document* document = web_document.ConstUnwrap<Document>();
- AXObjectCacheImpl* cache =
- ToAXObjectCacheImpl(document->ExistingAXObjectCache());
+ auto* cache = To<AXObjectCacheImpl>(document->ExistingAXObjectCache());
return cache ? WebAXObject(cache->GetOrCreate(document->GetLayoutView()))
: WebAXObject();
}
@@ -1725,8 +1730,7 @@ WebAXObject WebAXObject::FromWebDocument(const WebDocument& web_document) {
WebAXObject WebAXObject::FromWebDocumentByID(const WebDocument& web_document,
int ax_id) {
const Document* document = web_document.ConstUnwrap<Document>();
- AXObjectCacheImpl* cache =
- ToAXObjectCacheImpl(document->ExistingAXObjectCache());
+ auto* cache = To<AXObjectCacheImpl>(document->ExistingAXObjectCache());
return cache ? WebAXObject(cache->ObjectFromAXID(ax_id)) : WebAXObject();
}
@@ -1734,8 +1738,7 @@ WebAXObject WebAXObject::FromWebDocumentByID(const WebDocument& web_document,
WebAXObject WebAXObject::FromWebDocumentFocused(
const WebDocument& web_document) {
const Document* document = web_document.ConstUnwrap<Document>();
- AXObjectCacheImpl* cache =
- ToAXObjectCacheImpl(document->ExistingAXObjectCache());
+ auto* cache = To<AXObjectCacheImpl>(document->ExistingAXObjectCache());
return cache ? WebAXObject(cache->FocusedObject()) : WebAXObject();
}
diff --git a/chromium/third_party/blink/renderer/modules/exported/web_crypto_normalize.cc b/chromium/third_party/blink/renderer/modules/exported/web_crypto_normalize.cc
index a880a03ec46..01967978baa 100644
--- a/chromium/third_party/blink/renderer/modules/exported/web_crypto_normalize.cc
+++ b/chromium/third_party/blink/renderer/modules/exported/web_crypto_normalize.cc
@@ -46,19 +46,18 @@ WebCryptoAlgorithm NormalizeCryptoAlgorithm(
int* exception_code,
WebString* error_details,
v8::Isolate* isolate) {
- // FIXME: Avoid using NonThrowableExceptionState.
- NonThrowableExceptionState exception_state;
- Dictionary algorithm_dictionary(isolate, algorithm_object, exception_state);
- if (!algorithm_dictionary.IsUndefinedOrNull() &&
- !algorithm_dictionary.IsObject())
- return WebCryptoAlgorithm();
- WebCryptoAlgorithm algorithm;
- AlgorithmError error;
+ ExceptionState exception_state(isolate, ExceptionState::kQueryContext,
+ "WebCryptoAlgorithm", "NormalizeAlgorithm");
+
AlgorithmIdentifier algorithm_identifier;
- algorithm_identifier.SetDictionary(algorithm_dictionary);
- if (!NormalizeAlgorithm(algorithm_identifier, operation, algorithm, &error)) {
- *exception_code = WebCryptoErrorToExceptionCode(error.error_type);
- *error_details = error.error_details;
+ algorithm_identifier.SetObject(ScriptValue(isolate, algorithm_object));
+
+ WebCryptoAlgorithm algorithm;
+ if (!NormalizeAlgorithm(isolate, algorithm_identifier, operation, algorithm,
+ exception_state)) {
+ *exception_code = exception_state.Code();
+ *error_details = exception_state.Message();
+ exception_state.ClearException();
return WebCryptoAlgorithm();
}
diff --git a/chromium/third_party/blink/renderer/modules/exported/web_dom_file_system.cc b/chromium/third_party/blink/renderer/modules/exported/web_dom_file_system.cc
index 7b274f0f1c9..f03025e15a5 100644
--- a/chromium/third_party/blink/renderer/modules/exported/web_dom_file_system.cc
+++ b/chromium/third_party/blink/renderer/modules/exported/web_dom_file_system.cc
@@ -33,6 +33,7 @@
#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_directory_entry.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_dom_file_system.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_entry.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_file_entry.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -70,8 +71,11 @@ WebDOMFileSystem WebDOMFileSystem::Create(WebLocalFrame* frame,
DCHECK(frame);
DCHECK(To<WebLocalFrameImpl>(frame)->GetFrame());
auto* dom_file_system = MakeGarbageCollected<DOMFileSystem>(
- To<WebLocalFrameImpl>(frame)->GetFrame()->GetDocument(), name,
- static_cast<mojom::blink::FileSystemType>(type), root_url);
+ To<WebLocalFrameImpl>(frame)
+ ->GetFrame()
+ ->GetDocument()
+ ->ToExecutionContext(),
+ name, static_cast<mojom::blink::FileSystemType>(type), root_url);
if (serializable_type == kSerializableTypeSerializable)
dom_file_system->MakeClonable();
return WebDOMFileSystem(dom_file_system);
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 c2fb5de1626..f88e7058c05 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
@@ -37,6 +37,7 @@
#include "services/network/public/mojom/referrer_policy.mojom-blink.h"
#include "third_party/blink/public/mojom/browser_interface_broker.mojom-blink.h"
#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom-blink.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider.h"
@@ -158,11 +159,6 @@ void WebEmbeddedWorkerImpl::TerminateWorkerContext() {
worker_thread_->Terminate();
}
-void WebEmbeddedWorkerImpl::ResumeAfterDownload() {
- // TODO(bashi): Remove this method. This does nothing anymore.
- DCHECK(!asked_to_terminate_);
-}
-
void WebEmbeddedWorkerImpl::StartWorkerThread(
std::unique_ptr<WebEmbeddedWorkerStartData> worker_start_data,
std::unique_ptr<ServiceWorkerInstalledScriptsManager>
@@ -216,8 +212,8 @@ void WebEmbeddedWorkerImpl::StartWorkerThread(
// worker thread.
global_scope_creation_params = std::make_unique<GlobalScopeCreationParams>(
worker_start_data->script_url, worker_start_data->script_type,
- OffMainThreadWorkerScriptFetchOption::kEnabled, global_scope_name,
- worker_start_data->user_agent, std::move(web_worker_fetch_context),
+ global_scope_name, worker_start_data->user_agent,
+ worker_start_data->ua_metadata, std::move(web_worker_fetch_context),
Vector<CSPHeaderAndType>(), network::mojom::ReferrerPolicy::kDefault,
starter_origin.get(), starter_secure_context, starter_https_state,
nullptr /* worker_clients */, std::move(content_settings_proxy),
@@ -308,11 +304,11 @@ WebEmbeddedWorkerImpl::CreateFetchClientSettingsObjectData(
// case, it should be the Document that called update(). For soft update case,
// it seems to be 'null' document.
- WebInsecureRequestPolicy insecure_requests_policy =
+ mojom::blink::InsecureRequestPolicy insecure_requests_policy =
passed_settings_object.insecure_requests_policy ==
mojom::InsecureRequestsPolicy::kUpgrade
- ? kUpgradeInsecureRequests
- : kBlockAllMixedContent;
+ ? mojom::blink::InsecureRequestPolicy::kUpgradeInsecureRequests
+ : mojom::blink::InsecureRequestPolicy::kBlockAllMixedContent;
return std::make_unique<CrossThreadFetchClientSettingsObjectData>(
script_url.Copy() /* global_object_url */,
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 13f9eba078a..7ca19eefdb1 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
@@ -72,7 +72,6 @@ class MODULES_EXPORT WebEmbeddedWorkerImpl final : public WebEmbeddedWorker {
scoped_refptr<base::SingleThreadTaskRunner> initiator_thread_task_runner)
override;
void TerminateWorkerContext() override;
- void ResumeAfterDownload() override;
void WaitForShutdownForTesting();
diff --git a/chromium/third_party/blink/renderer/modules/exported/web_testing_support.cc b/chromium/third_party/blink/renderer/modules/exported/web_testing_support.cc
index 458c765300e..dfaee5f4b78 100644
--- a/chromium/third_party/blink/renderer/modules/exported/web_testing_support.cc
+++ b/chromium/third_party/blink/renderer/modules/exported/web_testing_support.cc
@@ -27,11 +27,18 @@
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_internals_partial.h"
+#include "third_party/blink/renderer/core/testing/scoped_mock_overlay_scrollbars.h"
#include "third_party/blink/renderer/core/testing/v8/web_core_test_support.h"
#include "v8/include/v8.h"
namespace blink {
+WebTestingSupport::WebScopedMockScrollbars::WebScopedMockScrollbars()
+ : use_mock_scrollbars_(new ScopedMockOverlayScrollbars) {}
+
+WebTestingSupport::WebScopedMockScrollbars::~WebScopedMockScrollbars() =
+ default;
+
void WebTestingSupport::InjectInternalsObject(WebLocalFrame* frame) {
V8InternalsPartial::Initialize();
v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
diff --git a/chromium/third_party/blink/renderer/modules/exported/web_user_media_request.cc b/chromium/third_party/blink/renderer/modules/exported/web_user_media_request.cc
deleted file mode 100644
index 20f62db2e54..00000000000
--- a/chromium/third_party/blink/renderer/modules/exported/web_user_media_request.cc
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2011 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/public/web/web_user_media_request.h"
-
-#include "third_party/blink/public/platform/web_media_constraints.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_security_origin.h"
-#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/public/web/web_document.h"
-#include "third_party/blink/renderer/modules/mediastream/user_media_request.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/weborigin/security_origin.h"
-
-namespace blink {
-
-WebUserMediaRequest::WebUserMediaRequest(UserMediaRequest* request)
- : private_(request) {}
-
-WebUserMediaRequest WebUserMediaRequest::CreateForTesting(
- const WebMediaConstraints& audio,
- const WebMediaConstraints& video) {
- UserMediaRequest* request = UserMediaRequest::CreateForTesting(audio, video);
- return WebUserMediaRequest(request);
-}
-
-void WebUserMediaRequest::Reset() {
- private_.Reset();
-}
-
-WebUserMediaRequest::MediaType WebUserMediaRequest::MediaRequestType() const {
- DCHECK(!IsNull());
- return private_->MediaRequestType();
-}
-
-bool WebUserMediaRequest::Audio() const {
- DCHECK(!IsNull());
- return private_->Audio();
-}
-
-bool WebUserMediaRequest::Video() const {
- DCHECK(!IsNull());
- return private_->Video();
-}
-
-WebMediaConstraints WebUserMediaRequest::AudioConstraints() const {
- DCHECK(!IsNull());
- return private_->AudioConstraints();
-}
-
-WebMediaConstraints WebUserMediaRequest::VideoConstraints() const {
- DCHECK(!IsNull());
- return private_->VideoConstraints();
-}
-
-bool WebUserMediaRequest::ShouldDisableHardwareNoiseSuppression() const {
- DCHECK(!IsNull());
- return private_->ShouldDisableHardwareNoiseSuppression();
-}
-
-WebSecurityOrigin WebUserMediaRequest::GetSecurityOrigin() const {
- DCHECK(!IsNull());
- if (!private_->GetExecutionContext())
- return WebSecurityOrigin::CreateFromString("test://test");
- return WebSecurityOrigin(
- private_->GetExecutionContext()->GetSecurityOrigin());
-}
-
-WebDocument WebUserMediaRequest::OwnerDocument() const {
- DCHECK(!IsNull());
- return WebDocument(private_->OwnerDocument());
-}
-
-void WebUserMediaRequest::RequestSucceeded(
- const WebMediaStream& stream_descriptor) {
- DCHECK(!IsNull());
- DCHECK(!stream_descriptor.IsNull());
- private_->Succeed(stream_descriptor);
-}
-
-void WebUserMediaRequest::RequestFailedConstraint(
- const WebString& constraint_name,
- const WebString& description) {
- DCHECK(!IsNull());
- private_->FailConstraint(constraint_name, description);
-}
-
-void WebUserMediaRequest::RequestFailed(Error name,
- const WebString& description) {
- DCHECK(!IsNull());
- private_->Fail(name, description);
-}
-
-bool WebUserMediaRequest::Equals(const WebUserMediaRequest& other) const {
- if (IsNull() || other.IsNull())
- return false;
- return private_.Get() == other.private_.Get();
-}
-
-void WebUserMediaRequest::Assign(const WebUserMediaRequest& other) {
- private_ = other.private_;
-}
-
-WebUserMediaRequest::operator UserMediaRequest*() const {
- return private_.Get();
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dedicated_worker_global_scope_file_system.idl b/chromium/third_party/blink/renderer/modules/filesystem/dedicated_worker_global_scope_file_system.idl
index 4b2703ffa30..b58cbcd83c5 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/dedicated_worker_global_scope_file_system.idl
+++ b/chromium/third_party/blink/renderer/modules/filesystem/dedicated_worker_global_scope_file_system.idl
@@ -32,9 +32,9 @@ partial interface DedicatedWorkerGlobalScope {
// TODO(crbug.com/841185): |successCallback| and |errorCallback| are not
// nullable in the spec.
- [RuntimeEnabled=FileSystem, MeasureAs=RequestFileSystemWorker] void webkitRequestFileSystem(unsigned short type, long long size, optional FileSystemCallback? successCallback, optional ErrorCallback? errorCallback);
+ [RuntimeEnabled=FileSystem, MeasureAs=RequestFileSystemWorker] void webkitRequestFileSystem(unsigned short type, long long size, optional FileSystemCallback? successCallback = null, optional ErrorCallback? errorCallback = null);
[RuntimeEnabled=FileSystem, RaisesException, MeasureAs=RequestFileSystemSyncWorker] DOMFileSystemSync webkitRequestFileSystemSync(unsigned short type, long long size);
// TODO(crbug.com/841185): |errorCallback| is not nullable in the spec.
- [RuntimeEnabled=FileSystem] void webkitResolveLocalFileSystemURL(DOMString url, EntryCallback successCallback, optional ErrorCallback? errorCallback);
+ [RuntimeEnabled=FileSystem] void webkitResolveLocalFileSystemURL(DOMString url, EntryCallback successCallback, optional ErrorCallback? errorCallback = null);
[RuntimeEnabled=FileSystem, RaisesException] EntrySync webkitResolveLocalFileSystemSyncURL(DOMString url);
};
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dev_tools_host_file_system.cc b/chromium/third_party/blink/renderer/modules/filesystem/dev_tools_host_file_system.cc
index c01ac1ac91a..e78923d1230 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/dev_tools_host_file_system.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/dev_tools_host_file_system.cc
@@ -18,7 +18,8 @@ DOMFileSystem* DevToolsHostFileSystem::isolatedFileSystem(
DevToolsHost& host,
const String& file_system_name,
const String& root_url) {
- ExecutionContext* context = host.FrontendFrame()->GetDocument();
+ ExecutionContext* context =
+ host.FrontendFrame()->GetDocument()->ToExecutionContext();
return MakeGarbageCollected<DOMFileSystem>(
context, file_system_name, mojom::blink::FileSystemType::kIsolated,
KURL(root_url));
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 a9d874c3357..e4078f96006 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.cc
@@ -30,11 +30,11 @@
#include "third_party/blink/renderer/modules/filesystem/directory_entry.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_file_system_flags.h"
#include "third_party/blink/renderer/core/fileapi/file_error.h"
#include "third_party/blink/renderer/modules/filesystem/async_callback_helper.h"
#include "third_party/blink/renderer/modules/filesystem/directory_reader.h"
#include "third_party/blink/renderer/modules/filesystem/file_system_callbacks.h"
-#include "third_party/blink/renderer/modules/filesystem/file_system_flags.h"
namespace blink {
@@ -85,7 +85,7 @@ void DirectoryEntry::removeRecursively(V8VoidCallback* success_callback,
std::move(error_callback_wrapper));
}
-void DirectoryEntry::Trace(blink::Visitor* visitor) {
+void DirectoryEntry::Trace(Visitor* visitor) {
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 f04de9bba39..fa00c74c684 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.h
@@ -65,15 +65,9 @@ class MODULES_EXPORT DirectoryEntry final : public Entry {
void removeRecursively(V8VoidCallback* success_callback = nullptr,
V8ErrorCallback* = nullptr) const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
};
-DEFINE_TYPE_CASTS(DirectoryEntry,
- Entry,
- entry,
- entry->isDirectory(),
- entry.isDirectory());
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_DIRECTORY_ENTRY_H_
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.idl b/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.idl
index 84f7c97ecec..25846d52640 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.idl
+++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.idl
@@ -28,7 +28,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// https://www.w3.org/TR/2012/WD-file-system-api-20120417/#idl-def-DirectoryEntry
+// https://wicg.github.io/entries-api/#api-directoryentry
[
NoInterfaceObject
] interface DirectoryEntry : Entry {
@@ -37,14 +37,14 @@
// TODO(crbug.com/841185): |successCallback| and |errorCallback| are not
// nullable in the spec.
void getFile(DOMString? path,
- optional FileSystemFlags options,
+ optional FileSystemFlags options = {},
optional EntryCallback? successCallback,
optional ErrorCallback? errorCallback);
// TODO(crbug.com/841185): |successCallback| and |errorCallback| are not
// nullable in the spec.
void getDirectory(DOMString? path,
- optional FileSystemFlags options,
+ optional FileSystemFlags options = {},
optional EntryCallback? successCallback,
optional ErrorCallback? errorCallback);
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 2fbea76343f..1519b81c804 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
@@ -30,12 +30,13 @@
#include "third_party/blink/renderer/modules/filesystem/directory_entry_sync.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_file_system_flags.h"
#include "third_party/blink/renderer/modules/filesystem/directory_reader_sync.h"
#include "third_party/blink/renderer/modules/filesystem/entry.h"
#include "third_party/blink/renderer/modules/filesystem/file_entry_sync.h"
-#include "third_party/blink/renderer/modules/filesystem/file_system_flags.h"
#include "third_party/blink/renderer/modules/filesystem/sync_callback_helper.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -62,7 +63,7 @@ FileEntrySync* DirectoryEntrySync::getFile(const String& path,
this, path, options, std::move(success_callback_wrapper),
std::move(error_callback_wrapper), DOMFileSystemBase::kSynchronous);
Entry* entry = sync_helper->GetResultOrThrow(exception_state);
- return entry ? ToFileEntrySync(EntrySync::Create(entry)) : nullptr;
+ return entry ? To<FileEntrySync>(EntrySync::Create(entry)) : nullptr;
}
DirectoryEntrySync* DirectoryEntrySync::getDirectory(
@@ -82,7 +83,7 @@ DirectoryEntrySync* DirectoryEntrySync::getDirectory(
std::move(error_callback_wrapper), DOMFileSystemBase::kSynchronous);
Entry* entry = sync_helper->GetResultOrThrow(exception_state);
- return entry ? ToDirectoryEntrySync(EntrySync::Create(entry)) : nullptr;
+ return entry ? To<DirectoryEntrySync>(EntrySync::Create(entry)) : nullptr;
}
void DirectoryEntrySync::removeRecursively(ExceptionState& exception_state) {
@@ -97,7 +98,7 @@ void DirectoryEntrySync::removeRecursively(ExceptionState& exception_state) {
sync_helper->GetResultOrThrow(exception_state);
}
-void DirectoryEntrySync::Trace(blink::Visitor* visitor) {
+void DirectoryEntrySync::Trace(Visitor* visitor) {
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 74439362774..2acad4d90fd 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
@@ -32,6 +32,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_DIRECTORY_ENTRY_SYNC_H_
#include "third_party/blink/renderer/modules/filesystem/entry_sync.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -58,14 +59,13 @@ class DirectoryEntrySync final : public EntrySync {
ExceptionState&);
void removeRecursively(ExceptionState&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
};
-DEFINE_TYPE_CASTS(DirectoryEntrySync,
- EntrySync,
- entry,
- entry->isDirectory(),
- entry.isDirectory());
+template <>
+struct DowncastTraits<DirectoryEntrySync> {
+ static bool AllowFrom(const EntrySync& entry) { return entry.isDirectory(); }
+};
} // namespace blink
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 9599edcf44b..45c6f38858e 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.cc
@@ -51,6 +51,20 @@ DirectoryReader::DirectoryReader(DOMFileSystemBase* file_system,
void DirectoryReader::readEntries(V8EntriesCallback* entries_callback,
V8ErrorCallback* error_callback) {
+ if (entries_callback_) {
+ // Non-null entries_callback_ means multiple readEntries() calls are made
+ // concurrently. We don't allow doing it.
+ Filesystem()->ReportError(
+ WTF::Bind(
+ [](V8ErrorCallback* error_callback, base::File::Error error) {
+ error_callback->InvokeAndReportException(
+ nullptr, file_error::CreateDOMException(error));
+ },
+ WrapPersistent(error_callback)),
+ base::File::FILE_ERROR_FAILED);
+ return;
+ }
+
auto success_callback_wrapper = WTF::BindRepeating(
[](DirectoryReader* persistent_reader, EntryHeapVector* entries) {
persistent_reader->AddEntries(*entries);
@@ -71,15 +85,6 @@ void DirectoryReader::readEntries(V8EntriesCallback* entries_callback,
return;
}
- if (entries_callback_) {
- // Non-null entries_callback_ means multiple readEntries() calls are made
- // concurrently. We don't allow doing it.
- Filesystem()->ReportError(
- WTF::Bind(&DirectoryReader::OnError, WrapPersistentIfNeeded(this)),
- base::File::FILE_ERROR_FAILED);
- return;
- }
-
if (!has_more_entries_ || !entries_.IsEmpty()) {
EntryHeapVector* entries =
MakeGarbageCollected<EntryHeapVector>(std::move(entries_));
@@ -113,7 +118,7 @@ void DirectoryReader::OnError(base::File::Error error) {
}
}
-void DirectoryReader::Trace(blink::Visitor* visitor) {
+void DirectoryReader::Trace(Visitor* visitor) {
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 d515d6f5681..fbe53440fdb 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 30722805844..992ff2e051f 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 1d9579d3036..ffd3430f3d3 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(blink::Visitor* visitor) {
+void DirectoryReaderSync::Trace(Visitor* visitor) {
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 2b251e4ef86..9f92b6daeab 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 54ff95f6544..1e5a4b8ff85 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
@@ -96,7 +96,7 @@ DOMFileSystem::DOMFileSystem(ExecutionContext* context,
mojom::blink::FileSystemType type,
const KURL& root_url)
: DOMFileSystemBase(context, name, type, root_url),
- ContextClient(context),
+ ExecutionContextClient(context),
number_of_pending_callbacks_(0),
root_entry_(
MakeGarbageCollected<DirectoryEntry>(this, DOMFilePath::kRoot)) {}
@@ -178,10 +178,10 @@ void DOMFileSystem::ScheduleCallback(ExecutionContext* execution_context,
WTF::Passed(std::move(identifier))));
}
-void DOMFileSystem::Trace(blink::Visitor* visitor) {
+void DOMFileSystem::Trace(Visitor* visitor) {
visitor->Trace(root_entry_);
DOMFileSystemBase::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 f15410ae034..58b7ed31393 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
@@ -34,8 +34,8 @@
#include "base/location.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/filesystem/dom_file_system_base.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -48,7 +48,7 @@ class FileEntry;
class MODULES_EXPORT DOMFileSystem final
: public DOMFileSystemBase,
public ActiveScriptWrappable<DOMFileSystem>,
- public ContextClient {
+ public ExecutionContextClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(DOMFileSystem);
@@ -88,7 +88,7 @@ class MODULES_EXPORT DOMFileSystem final
static void ScheduleCallback(ExecutionContext* execution_context,
base::OnceClosure task);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 f1ad8171cc2..86fe8b8cb2d 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(blink::Visitor* visitor) {
+void DOMFileSystemBase::Trace(Visitor* visitor) {
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 f6be95c7e85..2132b9d63dd 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
@@ -32,9 +32,9 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_DOM_FILE_SYSTEM_BASE_H_
#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink-forward.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_file_system_flags.h"
#include "third_party/blink/renderer/core/fileapi/file_error.h"
#include "third_party/blink/renderer/modules/filesystem/file_system_callbacks.h"
-#include "third_party/blink/renderer/modules/filesystem/file_system_flags.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/heap/handle.h"
@@ -152,7 +152,7 @@ class MODULES_EXPORT DOMFileSystemBase : public ScriptWrappable {
EntriesCallbacks::ErrorCallback,
SynchronousType = kAsynchronous);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 0df71c0ebee..bb505a269f4 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(blink::Visitor* visitor) { visitor->Trace(file_); }
+ void Trace(Visitor* visitor) { visitor->Trace(file_); }
};
static std::unique_ptr<SnapshotFileCallbackBase> Create(
@@ -109,15 +109,7 @@ class CreateFileHelper final : public SnapshotFileCallbackBase {
~CreateFileHelper() override = default;
- void DidCreateSnapshotFile(const FileMetadata& metadata,
- scoped_refptr<BlobDataHandle> snapshot) override {
- // We can't directly use the snapshot blob data handle because the content
- // type on it hasn't been set. The |snapshot| param is here to provide a a
- // chain of custody thru thread bridging that is held onto until *after*
- // we've coined a File with a new handle that has the correct type set on
- // it. This allows the blob storage system to track when a temp file can and
- // can't be safely deleted.
-
+ void DidCreateSnapshotFile(const FileMetadata& metadata) override {
result_->file_ =
DOMFileSystemBase::CreateFile(metadata, url_, type_, name_);
}
@@ -181,7 +173,7 @@ FileWriterSync* DOMFileSystemSync::CreateWriter(
return success ? file_writer : nullptr;
}
-void DOMFileSystemSync::Trace(blink::Visitor* visitor) {
+void DOMFileSystemSync::Trace(Visitor* visitor) {
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 bc72b114a4f..cf2dbd1f9e8 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<DirectoryEntrySync> root_entry_;
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_window_file_system.cc b/chromium/third_party/blink/renderer/modules/filesystem/dom_window_file_system.cc
index 7bf4589c23e..56897b5b930 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/dom_window_file_system.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_window_file_system.cc
@@ -64,7 +64,8 @@ void DOMWindowFileSystem::webkitRequestFileSystem(
UseCounter::Count(document, WebFeature::kRequestFileSystemNonWebbyOrigin);
if (!document->GetSecurityOrigin()->CanAccessFileSystem()) {
- DOMFileSystem::ReportError(document, std::move(error_callback_wrapper),
+ DOMFileSystem::ReportError(document->ToExecutionContext(),
+ std::move(error_callback_wrapper),
base::File::FILE_ERROR_SECURITY);
return;
} else if (document->GetSecurityOrigin()->IsLocal()) {
@@ -74,7 +75,8 @@ void DOMWindowFileSystem::webkitRequestFileSystem(
mojom::blink::FileSystemType file_system_type =
static_cast<mojom::blink::FileSystemType>(type);
if (!DOMFileSystemBase::IsValidType(file_system_type)) {
- DOMFileSystem::ReportError(document, std::move(error_callback_wrapper),
+ DOMFileSystem::ReportError(document->ToExecutionContext(),
+ std::move(error_callback_wrapper),
base::File::FILE_ERROR_INVALID_OPERATION);
return;
}
@@ -88,12 +90,14 @@ void DOMWindowFileSystem::webkitRequestFileSystem(
auto success_callback_wrapper =
AsyncCallbackHelper::SuccessCallback<DOMFileSystem>(success_callback);
- LocalFileSystem::From(*document)->RequestFileSystem(
- document, file_system_type, size,
- std::make_unique<FileSystemCallbacks>(std::move(success_callback_wrapper),
- std::move(error_callback_wrapper),
- document, file_system_type),
- LocalFileSystem::kAsynchronous);
+ LocalFileSystem::From(*document->ToExecutionContext())
+ ->RequestFileSystem(document->ToExecutionContext(), file_system_type,
+ size,
+ std::make_unique<FileSystemCallbacks>(
+ std::move(success_callback_wrapper),
+ std::move(error_callback_wrapper),
+ document->ToExecutionContext(), file_system_type),
+ LocalFileSystem::kAsynchronous);
}
void DOMWindowFileSystem::webkitResolveLocalFileSystemURL(
@@ -115,7 +119,8 @@ void DOMWindowFileSystem::webkitResolveLocalFileSystemURL(
KURL completed_url = document->CompleteURL(url);
if (!security_origin->CanAccessFileSystem() ||
!security_origin->CanRequest(completed_url)) {
- DOMFileSystem::ReportError(document, std::move(error_callback_wrapper),
+ DOMFileSystem::ReportError(document->ToExecutionContext(),
+ std::move(error_callback_wrapper),
base::File::FILE_ERROR_SECURITY);
return;
} else if (document->GetSecurityOrigin()->IsLocal()) {
@@ -123,7 +128,8 @@ void DOMWindowFileSystem::webkitResolveLocalFileSystemURL(
}
if (!completed_url.IsValid()) {
- DOMFileSystem::ReportError(document, std::move(error_callback_wrapper),
+ DOMFileSystem::ReportError(document->ToExecutionContext(),
+ std::move(error_callback_wrapper),
base::File::FILE_ERROR_INVALID_URL);
return;
}
@@ -131,12 +137,13 @@ void DOMWindowFileSystem::webkitResolveLocalFileSystemURL(
auto success_callback_wrapper =
AsyncCallbackHelper::SuccessCallback<Entry>(success_callback);
- LocalFileSystem::From(*document)->ResolveURL(
- document, completed_url,
- std::make_unique<ResolveURICallbacks>(std::move(success_callback_wrapper),
- std::move(error_callback_wrapper),
- document),
- LocalFileSystem::kAsynchronous);
+ LocalFileSystem::From(*document->ToExecutionContext())
+ ->ResolveURL(document->ToExecutionContext(), completed_url,
+ std::make_unique<ResolveURICallbacks>(
+ std::move(success_callback_wrapper),
+ std::move(error_callback_wrapper),
+ document->ToExecutionContext()),
+ LocalFileSystem::kAsynchronous);
}
static_assert(
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 5add202946d..dd4a6028b18 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(blink::Visitor* visitor) {
+void DraggedIsolatedFileSystemImpl::Trace(Visitor* visitor) {
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 e5f7dbb3a96..57803e73f90 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 1b3e6eb79f1..18051936981 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(blink::Visitor* visitor) {
+void Entry::Trace(Visitor* visitor) {
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 4f2dc22f711..63be093dc40 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 55e813d49de..38d25b459fd 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(blink::Visitor* visitor) {
+void EntryBase::Trace(Visitor* visitor) {
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 1bf84f5edfe..a6d315101fa 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 3ca79f7a169..e63accd6df2 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(blink::Visitor* visitor) {
+void EntrySync::Trace(Visitor* visitor) {
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 5f3b7768a12..0768db2cb8a 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 ca7101c571e..cc5e1a1dd4b 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(blink::Visitor* visitor) {
+void FileEntry::Trace(Visitor* visitor) {
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 5d4368ca98e..d1d33f9596e 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_entry.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_entry.h
@@ -52,11 +52,9 @@ class MODULES_EXPORT FileEntry final : public Entry {
bool isFile() const override { return true; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
};
-DEFINE_TYPE_CASTS(FileEntry, Entry, entry, entry->isFile(), entry.isFile());
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_ENTRY_H_
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 7081923ee00..4e2a86d3633 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(blink::Visitor* visitor) {
+void FileEntrySync::Trace(Visitor* visitor) {
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 e0f3f748f1c..de881ebe3b5 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
@@ -33,6 +33,7 @@
#include "third_party/blink/renderer/modules/filesystem/entry_sync.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -52,14 +53,13 @@ class FileEntrySync final : public EntrySync {
File* file(ExceptionState&);
FileWriterSync* createWriter(ExceptionState&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
};
-DEFINE_TYPE_CASTS(FileEntrySync,
- EntrySync,
- entry,
- entry->isFile(),
- entry.isFile());
+template <>
+struct DowncastTraits<FileEntrySync> {
+ static bool AllowFrom(const EntrySync& entry) { return entry.isFile(); }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.cc
index e32d409141f..b00ec0114cc 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.cc
@@ -290,18 +290,10 @@ SnapshotFileCallback::SnapshotFileCallback(DOMFileSystemBase* filesystem,
success_callback_(std::move(success_callback)),
error_callback_(std::move(error_callback)) {}
-void SnapshotFileCallback::DidCreateSnapshotFile(
- const FileMetadata& metadata,
- scoped_refptr<BlobDataHandle> snapshot) {
+void SnapshotFileCallback::DidCreateSnapshotFile(const FileMetadata& metadata) {
if (!success_callback_)
return;
- // We can't directly use the snapshot blob data handle because the content
- // type on it hasn't been set. The |snapshot| param is here to provide a
- // chain of custody thru thread bridging that is held onto until *after* we've
- // coined a File with a new handle that has the correct type set on it. This
- // allows the blob storage system to track when a temp file can and can't be
- // safely deleted.
std::move(success_callback_)
.Run(DOMFileSystemBase::CreateFile(metadata, url_,
file_system_->GetType(), name_));
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.h b/chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.h
index f671b4b4ea2..b78aa7b1afc 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.h
@@ -80,9 +80,7 @@ class SnapshotFileCallbackBase {
virtual ~SnapshotFileCallbackBase() = default;
// Called when a snapshot file is created successfully.
- virtual void DidCreateSnapshotFile(
- const FileMetadata&,
- scoped_refptr<BlobDataHandle> snapshot) = 0;
+ virtual void DidCreateSnapshotFile(const FileMetadata&) = 0;
virtual void DidFail(base::File::Error error) = 0;
};
@@ -245,8 +243,7 @@ class SnapshotFileCallback final : public SnapshotFileCallbackBase,
ExecutionContext*);
// Called when a snapshot file is created successfully.
- void DidCreateSnapshotFile(const FileMetadata&,
- scoped_refptr<BlobDataHandle> snapshot) override;
+ void DidCreateSnapshotFile(const FileMetadata&) override;
// Called when a request operation has failed.
void DidFail(base::File::Error error) override;
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 d07ad41e9dc..a8a7293fcc4 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
@@ -8,7 +8,6 @@
#include "build/build_config.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/platform/file_path_conversion.h"
#include "third_party/blink/public/platform/platform.h"
@@ -573,13 +572,7 @@ void FileSystemDispatcher::DidCreateSnapshotFile(
FileMetadata file_metadata = FileMetadata::From(file_info);
file_metadata.platform_path = FilePathToWebString(platform_path);
- auto blob_data = std::make_unique<BlobData>();
- blob_data->AppendFile(file_metadata.platform_path, 0, file_metadata.length,
- base::nullopt);
- scoped_refptr<BlobDataHandle> snapshot_blob =
- BlobDataHandle::Create(std::move(blob_data), file_metadata.length);
-
- callbacks->DidCreateSnapshotFile(file_metadata, snapshot_blob);
+ callbacks->DidCreateSnapshotFile(file_metadata);
if (listener) {
mojo::Remote<mojom::blink::ReceivedSnapshotListener>(std::move(listener))
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 f2653a03622..28815e50d9e 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_writer.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_writer.cc
@@ -48,7 +48,7 @@ static constexpr uint64_t kMaxTruncateLength =
std::numeric_limits<uint64_t>::max();
FileWriter::FileWriter(ExecutionContext* context)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
ready_state_(kInit),
operation_in_progress_(kOperationNone),
queued_operation_(kOperationNone),
@@ -67,7 +67,7 @@ const AtomicString& FileWriter::InterfaceName() const {
return event_target_names::kFileWriter;
}
-void FileWriter::ContextDestroyed(ExecutionContext*) {
+void FileWriter::ContextDestroyed() {
Dispose();
}
@@ -335,12 +335,12 @@ void FileWriter::Dispose() {
queued_operation_ = kOperationNone;
}
-void FileWriter::Trace(blink::Visitor* visitor) {
+void FileWriter::Trace(Visitor* visitor) {
visitor->Trace(error_);
visitor->Trace(blob_being_written_);
EventTargetWithInlineData::Trace(visitor);
FileWriterBase::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 9fc4c134c93..e80ca27017f 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/file_writer.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/file_writer.h
@@ -32,8 +32,8 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_WRITER_H_
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/probe/async_task_id.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/filesystem/file_writer_base.h"
@@ -50,7 +50,7 @@ enum class FileErrorCode;
class FileWriter final : public EventTargetWithInlineData,
public FileWriterBase,
public ActiveScriptWrappable<FileWriter>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(FileWriter);
USING_PRE_FINALIZER(FileWriter, Dispose);
@@ -78,8 +78,8 @@ class FileWriter final : public EventTargetWithInlineData,
int64_t offset) override;
void DoCancel() override;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
// ScriptWrappable
bool HasPendingActivity() const final;
@@ -87,7 +87,7 @@ class FileWriter final : public EventTargetWithInlineData,
// EventTarget
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
DEFINE_ATTRIBUTE_EVENT_LISTENER(writestart, kWritestart)
@@ -97,7 +97,7 @@ class FileWriter final : public EventTargetWithInlineData,
DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
DEFINE_ATTRIBUTE_EVENT_LISTENER(writeend, kWriteend)
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 d8d36331ab1..c996b53a05f 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(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) 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 d3f2530a47e..c61757182c5 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
@@ -124,7 +124,9 @@ void FileWriterSync::DoCancel() {
}
FileWriterSync::FileWriterSync(ExecutionContext* context)
- : ContextClient(context), error_(base::File::FILE_OK), complete_(true) {}
+ : ExecutionContextClient(context),
+ error_(base::File::FILE_OK),
+ complete_(true) {}
void FileWriterSync::PrepareForWrite() {
DCHECK(complete_);
@@ -134,10 +136,10 @@ void FileWriterSync::PrepareForWrite() {
FileWriterSync::~FileWriterSync() = default;
-void FileWriterSync::Trace(blink::Visitor* visitor) {
+void FileWriterSync::Trace(Visitor* visitor) {
ScriptWrappable::Trace(visitor);
FileWriterBase::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 533249bb66b..ba48e6d46c7 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
@@ -31,7 +31,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_WRITER_SYNC_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_WRITER_SYNC_H_
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/fileapi/file_error.h"
#include "third_party/blink/renderer/modules/filesystem/file_writer_base.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -44,14 +44,14 @@ class ExceptionState;
class FileWriterSync final : public ScriptWrappable,
public FileWriterBase,
- public ContextClient {
+ public ExecutionContextClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(FileWriterSync);
public:
explicit FileWriterSync(ExecutionContext* context);
~FileWriterSync() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void write(Blob*, ExceptionState&);
void seek(int64_t position, ExceptionState&);
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/idls.gni b/chromium/third_party/blink/renderer/modules/filesystem/idls.gni
new file mode 100644
index 00000000000..80a222d8908
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/filesystem/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "directory_entry.idl",
+ "directory_entry_sync.idl",
+ "directory_reader.idl",
+ "directory_reader_sync.idl",
+ "dom_file_system.idl",
+ "dom_file_system_sync.idl",
+ "entries_callback.idl",
+ "entry.idl",
+ "entry_callback.idl",
+ "entry_sync.idl",
+ "error_callback.idl",
+ "file_callback.idl",
+ "file_entry.idl",
+ "file_entry_sync.idl",
+ "file_system_callback.idl",
+ "file_writer.idl",
+ "file_writer_callback.idl",
+ "file_writer_sync.idl",
+ "metadata.idl",
+ "metadata_callback.idl",
+]
+
+modules_dictionary_idl_files = [ "file_system_flags.idl" ]
+
+modules_dependency_idl_files = [
+ "data_transfer_item_file_system.idl",
+ "dedicated_worker_global_scope_file_system.idl",
+ "dev_tools_host_file_system.idl",
+ "html_input_element_file_system.idl",
+ "shared_worker_global_scope_file_system.idl",
+ "window_file_system.idl",
+]
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.cc b/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.cc
index 05f3ba3ab2c..641c5bee9ae 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.cc
+++ b/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.cc
@@ -47,13 +47,13 @@
#include "third_party/blink/renderer/modules/filesystem/dom_file_system.h"
#include "third_party/blink/renderer/modules/filesystem/file_system_callbacks.h"
#include "third_party/blink/renderer/modules/filesystem/file_system_dispatcher.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/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
namespace blink {
-LocalFileSystem::~LocalFileSystem() = default;
-
void LocalFileSystem::ResolveURL(ExecutionContext* context,
const KURL& file_system_url,
std::unique_ptr<ResolveURICallbacks> callbacks,
@@ -90,6 +90,9 @@ void LocalFileSystem::RequestFileSystem(
WTF::Bind(&LocalFileSystem::RequestFileSystemCallback,
WrapCrossThreadPersistent(this), WrapPersistent(context), type,
std::move(callbacks), sync_type));
+ context->GetScheduler()->RegisterStickyFeature(
+ blink::SchedulingPolicy::Feature::kWebFileSystem,
+ {blink::SchedulingPolicy::RecordMetricsForBackForwardCache()});
}
void LocalFileSystem::RequestFileSystemCallback(
@@ -110,7 +113,7 @@ void LocalFileSystem::RequestFileSystemAccessInternal(
base::OnceCallback<void(bool)> callback) {
if (context->IsDocument()) {
auto* client =
- To<Document>(context)->GetFrame()->GetContentSettingsClient();
+ Document::From(context)->GetFrame()->GetContentSettingsClient();
if (!client) {
std::move(callback).Run(true);
} else {
@@ -182,7 +185,7 @@ LocalFileSystem::LocalFileSystem(LocalFrame& frame)
LocalFileSystem::LocalFileSystem(WorkerGlobalScope& worker_global_scope)
: Supplement<WorkerGlobalScope>(worker_global_scope) {}
-void LocalFileSystem::Trace(blink::Visitor* visitor) {
+void LocalFileSystem::Trace(Visitor* visitor) {
Supplement<LocalFrame>::Trace(visitor);
Supplement<WorkerGlobalScope>::Trace(visitor);
}
@@ -190,7 +193,7 @@ void LocalFileSystem::Trace(blink::Visitor* visitor) {
const char LocalFileSystem::kSupplementName[] = "LocalFileSystem";
LocalFileSystem* LocalFileSystem::From(ExecutionContext& context) {
- if (auto* document = DynamicTo<Document>(context)) {
+ if (auto* document = Document::DynamicFrom(context)) {
LocalFileSystem* file_system =
Supplement<LocalFrame>::From<LocalFileSystem>(document->GetFrame());
DCHECK(file_system);
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.h b/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.h
index 48d8734cd72..f564150d7ba 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.h
+++ b/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.h
@@ -64,7 +64,6 @@ class LocalFileSystem final : public GarbageCollected<LocalFileSystem>,
explicit LocalFileSystem(LocalFrame&);
explicit LocalFileSystem(WorkerGlobalScope&);
- ~LocalFileSystem();
void ResolveURL(ExecutionContext*,
const KURL&,
@@ -78,7 +77,7 @@ class LocalFileSystem final : public GarbageCollected<LocalFileSystem>,
static LocalFileSystem* From(ExecutionContext&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
const char* NameInHeapSnapshot() const override { return "LocalFileSystem"; }
private:
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/shared_worker_global_scope_file_system.idl b/chromium/third_party/blink/renderer/modules/filesystem/shared_worker_global_scope_file_system.idl
index 247544bf3fc..310df94afe6 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/shared_worker_global_scope_file_system.idl
+++ b/chromium/third_party/blink/renderer/modules/filesystem/shared_worker_global_scope_file_system.idl
@@ -32,9 +32,9 @@ partial interface SharedWorkerGlobalScope {
// TODO(crbug.com/841185): |successCallback| and |errorCallback| are not
// nullable in the spec.
- [RuntimeEnabled=FileSystem, MeasureAs=RequestFileSystemWorker] void webkitRequestFileSystem(unsigned short type, long long size, optional FileSystemCallback? successCallback, optional ErrorCallback? errorCallback);
+ [RuntimeEnabled=FileSystem, MeasureAs=RequestFileSystemWorker] void webkitRequestFileSystem(unsigned short type, long long size, optional FileSystemCallback? successCallback = null, optional ErrorCallback? errorCallback = null);
[RuntimeEnabled=FileSystem, RaisesException, MeasureAs=RequestFileSystemSyncWorker] DOMFileSystemSync webkitRequestFileSystemSync(unsigned short type, long long size);
// TODO(crbug.com/841185): |errorCallback| is not nullable in the spec.
- [RuntimeEnabled=FileSystem] void webkitResolveLocalFileSystemURL(DOMString url, EntryCallback successCallback, optional ErrorCallback? errorCallback);
+ [RuntimeEnabled=FileSystem] void webkitResolveLocalFileSystemURL(DOMString url, EntryCallback successCallback, optional ErrorCallback? errorCallback = null);
[RuntimeEnabled=FileSystem, RaisesException] EntrySync webkitResolveLocalFileSystemSyncURL(DOMString url);
};
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 d05ea9196d0..a902d7c622c 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(blink::Visitor* visitor) { visitor->Trace(result_); }
+ void Trace(Visitor* visitor) { visitor->Trace(result_); }
// Simple/new success and error callback wrappers.
void OnSuccess(CallbackArg* arg) {
diff --git a/chromium/third_party/blink/renderer/modules/filesystem/window_file_system.idl b/chromium/third_party/blink/renderer/modules/filesystem/window_file_system.idl
index 1781b22b2c8..b97fbfda142 100644
--- a/chromium/third_party/blink/renderer/modules/filesystem/window_file_system.idl
+++ b/chromium/third_party/blink/renderer/modules/filesystem/window_file_system.idl
@@ -33,8 +33,8 @@
// TODO(crbug.com/841185): |errorCallback| is not nullable in the spec.
[RuntimeEnabled=FileSystem, MeasureAs=RequestFileSystem] void webkitRequestFileSystem(unsigned short type, long long size,
- FileSystemCallback successCallback, optional ErrorCallback? errorCallback);
+ FileSystemCallback successCallback, optional ErrorCallback? errorCallback = null);
// TODO(crbug.com/841185): |errorCallback| is not nullable in the spec.
[RuntimeEnabled=FileSystem] void webkitResolveLocalFileSystemURL(DOMString url,
- EntryCallback successCallback, optional ErrorCallback? errorCallback);
+ EntryCallback successCallback, optional ErrorCallback? errorCallback = null);
};
diff --git a/chromium/third_party/blink/renderer/modules/font_access/BUILD.gn b/chromium/third_party/blink/renderer/modules/font_access/BUILD.gn
new file mode 100644
index 00000000000..061a5b808d2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/font_access/BUILD.gn
@@ -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.
+
+import("//third_party/blink/renderer/modules/modules.gni")
+
+blink_modules_sources("font_access") {
+ sources = [
+ "font_iterator.cc",
+ "font_iterator.h",
+ "font_manager.cc",
+ "font_manager.h",
+ "font_metadata.cc",
+ "font_metadata.h",
+ "navigator_fonts.cc",
+ "navigator_fonts.h",
+ ]
+
+ deps = [ "//third_party/blink/renderer/platform" ]
+}
diff --git a/chromium/third_party/blink/renderer/modules/font_access/DEPS b/chromium/third_party/blink/renderer/modules/font_access/DEPS
new file mode 100644
index 00000000000..12a5b6ac796
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/font_access/DEPS
@@ -0,0 +1,6 @@
+include_rules = [
+ "-third_party/blink/renderer/modules",
+ "+third_party/blink/renderer/modules/event_target_modules.h",
+ "+third_party/blink/renderer/modules/font_access",
+ "+third_party/blink/renderer/modules/modules_export.h",
+]
diff --git a/chromium/third_party/blink/renderer/modules/font_access/OWNERS b/chromium/third_party/blink/renderer/modules/font_access/OWNERS
new file mode 100644
index 00000000000..e19788b7a03
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/font_access/OWNERS
@@ -0,0 +1,6 @@
+drott@chromium.org
+jsbell@chromium.org
+oyiptong@chromium.org
+
+# TEAM: storage-dev@chromium.org
+# COMPONENT: Blink>Storage
diff --git a/chromium/third_party/blink/renderer/modules/font_access/README.md b/chromium/third_party/blink/renderer/modules/font_access/README.md
new file mode 100644
index 00000000000..0bb6b47a998
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/font_access/README.md
@@ -0,0 +1,28 @@
+# Font Access API
+
+This directory contains the implementation of the Font Access API.
+
+## Related directories
+
+[`//third_party/blink/renderer/platform/fonts`](../../modules/font_access)
+contains the platform implementation.
+
+## APIs In this directory
+
+This directory contains the implementation of the new and still under
+development [Font Access API](https://github.com/inexorabletash/font-enumeration/blob/master/README.md).
+
+It consists of the following parts:
+
+ * `FontMetadata`: Metadata about a font installed on the system. Provides
+ information that uniquely identifies a font, as well as text to present to
+ users in their system-configured locale.
+
+ * `FontIterator`, `FontIteratorEntry`: Mechanism providing the ability to
+ enumerate system-installed fonts using an asynchronous iterator.
+
+ * `FontManager`: An object that exposes operations to access fonts. In the
+ future, this may be extended to add more capabilities.
+
+ * `NavigatorFonts`: An entry point, available in documents and workers on
+ `navigator`, that lets a website enumerate locally installed system fonts.
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
new file mode 100644
index 00000000000..97cb193ae7b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/font_access/font_iterator.cc
@@ -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.
+
+#include "third_party/blink/renderer/modules/font_access/font_iterator.h"
+
+#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/core/v8/string_or_array_buffer_or_array_buffer_view.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_font_iterator_entry.h"
+#include "third_party/blink/renderer/modules/font_access/font_metadata.h"
+#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/wtf/functional.h"
+
+namespace blink {
+
+FontIterator::FontIterator(const std::vector<FontEnumerationEntry>& entries) {
+ for (auto entry : entries) {
+ entries_.push_back(FontMetadata::Create(entry));
+ }
+}
+
+ScriptPromise FontIterator::next(ScriptState* script_state) {
+ if (!entries_.IsEmpty()) {
+ FontMetadata* entry = entries_.TakeFirst();
+ auto* result = FontIteratorEntry::Create();
+ result->setValue(entry);
+ return ScriptPromise::Cast(script_state, ToV8(result, script_state));
+ }
+
+ auto* result = FontIteratorEntry::Create();
+ result->setDone(true);
+ return ScriptPromise::Cast(script_state, ToV8(result, script_state));
+}
+
+void FontIterator::Trace(Visitor* visitor) {
+ ScriptWrappable::Trace(visitor);
+ visitor->Trace(entries_);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..3d8e72bc10f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/font_access/font_iterator.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_FONT_ACCESS_FONT_ITERATOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_FONT_ACCESS_FONT_ITERATOR_H_
+
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+
+namespace blink {
+
+class ScriptPromise;
+class ScriptState;
+class FontMetadata;
+struct FontEnumerationEntry;
+
+class FontIterator final : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ // Using std::vector, because at the boundary with platform code.
+ explicit FontIterator(const std::vector<FontEnumerationEntry>& entries);
+
+ ScriptPromise next(ScriptState*);
+
+ void Trace(Visitor*) override;
+
+ private:
+ HeapDeque<Member<FontMetadata>> entries_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_FONT_ACCESS_FONT_ITERATOR_H_
diff --git a/chromium/third_party/blink/renderer/modules/font_access/font_iterator.idl b/chromium/third_party/blink/renderer/modules/font_access/font_iterator.idl
new file mode 100644
index 00000000000..5155dc83ed5
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/font_access/font_iterator.idl
@@ -0,0 +1,14 @@
+// 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(https://crbug.com/1062425): Determine if async iterator performance cost is worthwhile.
+// Async iterator returned by FontManager.query().
+// https://inexorabletash.github.io/font-enumeration/
+// https://www.ecma-international.org/ecma-262/9.0/index.html#sec-asynciterator-interface
+[
+ NoInterfaceObject,
+ RuntimeEnabled=FontAccess
+] interface FontIterator {
+ [CallWith=ScriptState] Promise<any> next();
+};
diff --git a/chromium/third_party/blink/renderer/modules/font_access/font_iterator_entry.idl b/chromium/third_party/blink/renderer/modules/font_access/font_iterator_entry.idl
new file mode 100644
index 00000000000..b8d3a97d5c9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/font_access/font_iterator_entry.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.
+
+// Used by FontIterator to represents results of next() calls.
+// https://inexorabletash.github.io/font-enumeration/
+// https://www.ecma-international.org/ecma-262/9.0/index.html#sec-iteratorresult-interface
+dictionary FontIteratorEntry {
+ FontMetadata value;
+ boolean done = false;
+};
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
new file mode 100644
index 00000000000..d4996562e56
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/font_access/font_manager.cc
@@ -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.
+
+#include "third_party/blink/renderer/modules/font_access/font_manager.h"
+
+#include <algorithm>
+
+#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/modules/font_access/font_iterator.h"
+#include "third_party/blink/renderer/platform/bindings/script_state.h"
+#include "third_party/blink/renderer/platform/fonts/font_cache.h"
+
+namespace blink {
+
+namespace {
+
+void ReturnDataFunction(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ V8SetReturnValue(info, info.Data());
+}
+
+} // namespace
+
+ScriptValue FontManager::query(ScriptState* script_state) {
+ FontCache* font_cache = FontCache::GetFontCache();
+
+ auto* iterator =
+ MakeGarbageCollected<FontIterator>(font_cache->EnumerateAvailableFonts());
+ auto* isolate = script_state->GetIsolate();
+ auto context = script_state->GetContext();
+
+ v8::Local<v8::Object> result = v8::Object::New(isolate);
+ if (!result
+ ->Set(context, v8::Symbol::GetAsyncIterator(isolate),
+ v8::Function::New(context, &ReturnDataFunction,
+ ToV8(iterator, script_state))
+ .ToLocalChecked())
+ .ToChecked()) {
+ return ScriptValue();
+ }
+ return ScriptValue(script_state->GetIsolate(), result);
+}
+
+void FontManager::Trace(blink::Visitor* visitor) {
+ ScriptWrappable::Trace(visitor);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..49044cc52a2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/font_access/font_manager.h
@@ -0,0 +1,31 @@
+// 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_FONT_ACCESS_FONT_MANAGER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_FONT_ACCESS_FONT_MANAGER_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/heap/heap_allocator.h"
+
+namespace blink {
+
+class ScriptState;
+class ScriptValue;
+
+class FontManager final : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ FontManager() = default;
+ ScriptValue query(ScriptState*);
+
+ DISALLOW_COPY_AND_ASSIGN(FontManager);
+ void Trace(blink::Visitor*) override;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_FONT_ACCESS_FONT_MANAGER_H_
diff --git a/chromium/third_party/blink/renderer/modules/font_access/font_manager.idl b/chromium/third_party/blink/renderer/modules/font_access/font_manager.idl
new file mode 100644
index 00000000000..f3c80f8fbd3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/font_access/font_manager.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(https://crbug.com/1062766): Update spec documents with objects as implemented.
+// https://inexorabletash.github.io/font-enumeration/
+[
+ Exposed=(Window,Worker),
+ SecureContext,
+ RuntimeEnabled=FontAccess
+] interface FontManager {
+ [CallWith=ScriptState] object query();
+};
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
new file mode 100644
index 00000000000..ff7f2f0b7b2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/font_access/font_metadata.cc
@@ -0,0 +1,24 @@
+// 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/font_access/font_metadata.h"
+
+#include "third_party/blink/renderer/platform/fonts/font_cache.h"
+
+namespace blink {
+
+FontMetadata::FontMetadata(const FontEnumerationEntry& entry)
+ : postscriptName_(entry.postscript_name),
+ fullName_(entry.full_name),
+ family_(entry.family) {}
+
+FontMetadata* FontMetadata::Create(const FontEnumerationEntry& entry) {
+ return MakeGarbageCollected<FontMetadata>(entry);
+}
+
+void FontMetadata::Trace(blink::Visitor* visitor) {
+ ScriptWrappable::Trace(visitor);
+}
+
+} // 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
new file mode 100644
index 00000000000..0c1941e66cd
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/font_access/font_metadata.h
@@ -0,0 +1,53 @@
+// 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_FONT_ACCESS_FONT_METADATA_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_FONT_ACCESS_FONT_METADATA_H_
+
+#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+
+namespace blink {
+
+struct FontEnumerationEntry;
+
+class FontMetadata final : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ explicit FontMetadata(const FontEnumerationEntry& entry);
+
+ static FontMetadata* Create(const FontEnumerationEntry& entry);
+
+ // The table below represents the properties made available via the API, the
+ // name table entries those properties map to, and their localization status
+ // as returned by the API.
+ // The localized properties are in the system's configured locale.
+ //
+ // For more about name table entries, go to:
+ // https://docs.microsoft.com/en-us/typography/opentype/spec/name#name-ids
+ //
+ // +----------------+---------+-----------+
+ // | Property | name ID | Localized |
+ // +----------------+---------+-----------+
+ // | postscriptName | 6 | No |
+ // | fullName | 4 | Yes |
+ // | family | 1 | Yes |
+ // +----------------+---------+-----------+
+
+ String postscriptName() const { return postscriptName_; }
+ String fullName() const { return fullName_; }
+ String family() const { return family_; }
+
+ void Trace(Visitor*) override;
+
+ private:
+ String postscriptName_;
+ String fullName_;
+ String family_;
+};
+
+} // namespace blink
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_FONT_ACCESS_FONT_METADATA_H_
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
new file mode 100644
index 00000000000..169440a55bc
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/font_access/font_metadata.idl
@@ -0,0 +1,14 @@
+// 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.
+
+// Returned by the async iterator FontIterator as the entry value.
+// https://inexorabletash.github.io/font-enumeration/
+[
+ NoInterfaceObject,
+ RuntimeEnabled=FontAccess
+] interface FontMetadata {
+ readonly attribute DOMString postscriptName;
+ readonly attribute DOMString fullName;
+ readonly attribute DOMString family;
+};
diff --git a/chromium/third_party/blink/renderer/modules/font_access/idls.gni b/chromium/third_party/blink/renderer/modules/font_access/idls.gni
new file mode 100644
index 00000000000..1f7320b0105
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/font_access/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "font_iterator.idl",
+ "font_metadata.idl",
+ "font_manager.idl",
+]
+
+modules_dictionary_idl_files = [ "font_iterator_entry.idl" ]
+
+modules_dependency_idl_files = [
+ "navigator_fonts.idl",
+ "worker_navigator_fonts.idl",
+]
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
new file mode 100644
index 00000000000..e576fc113da
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/font_access/navigator_fonts.cc
@@ -0,0 +1,83 @@
+// 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/font_access/navigator_fonts.h"
+
+#include "third_party/blink/renderer/core/execution_context/security_context.h"
+#include "third_party/blink/renderer/core/frame/navigator.h"
+#include "third_party/blink/renderer/core/workers/worker_navigator.h"
+#include "third_party/blink/renderer/modules/font_access/font_manager.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/bindings/name_client.h"
+#include "third_party/blink/renderer/platform/bindings/script_state.h"
+#include "third_party/blink/renderer/platform/supplementable.h"
+
+namespace blink {
+
+namespace {
+
+template <typename T>
+class NavigatorFontsImpl final : public GarbageCollected<NavigatorFontsImpl<T>>,
+ public Supplement<T>,
+ public NameClient {
+ USING_GARBAGE_COLLECTED_MIXIN(NavigatorFontsImpl);
+
+ public:
+ static const char kSupplementName[];
+
+ static NavigatorFontsImpl& From(T& navigator) {
+ NavigatorFontsImpl* supplement = static_cast<NavigatorFontsImpl*>(
+ Supplement<T>::template From<NavigatorFontsImpl>(navigator));
+ if (!supplement) {
+ supplement = MakeGarbageCollected<NavigatorFontsImpl>(navigator);
+ Supplement<T>::ProvideTo(navigator, supplement);
+ }
+ return *supplement;
+ }
+
+ explicit NavigatorFontsImpl(T& navigator) : Supplement<T>(navigator) {}
+
+ FontManager* GetFontManager() const {
+ if (!font_manager_) {
+ font_manager_ = MakeGarbageCollected<FontManager>();
+ }
+ return font_manager_.Get();
+ }
+
+ void Trace(blink::Visitor* visitor) override {
+ visitor->Trace(font_manager_);
+ Supplement<T>::Trace(visitor);
+ }
+
+ const char* NameInHeapSnapshot() const override {
+ return "NavigatorFontsImpl";
+ }
+
+ private:
+ mutable Member<FontManager> font_manager_;
+};
+
+// static
+template <typename T>
+const char NavigatorFontsImpl<T>::kSupplementName[] = "NavigatorFontsImpl";
+
+} // namespace
+
+FontManager* NavigatorFonts::fonts(ScriptState* script_state,
+ Navigator& navigator,
+ ExceptionState& exception_state) {
+ DCHECK(ExecutionContext::From(script_state)->IsContextThread());
+ return NavigatorFontsImpl<Navigator>::From(navigator).GetFontManager();
+}
+
+FontManager* NavigatorFonts::fonts(ScriptState* script_state,
+ WorkerNavigator& navigator,
+ ExceptionState& exception_state) {
+ DCHECK(ExecutionContext::From(script_state)->IsContextThread());
+ // TODO(https://crbug.com/1043348): Support FeaturePolicy when it's ready for
+ // workers.
+ return NavigatorFontsImpl<WorkerNavigator>::From(navigator).GetFontManager();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/font_access/navigator_fonts.h b/chromium/third_party/blink/renderer/modules/font_access/navigator_fonts.h
new file mode 100644
index 00000000000..dc44c0c69bc
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/font_access/navigator_fonts.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_MODULES_FONT_ACCESS_NAVIGATOR_FONTS_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_FONT_ACCESS_NAVIGATOR_FONTS_H_
+
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+
+namespace blink {
+
+class ExceptionState;
+class FontManager;
+class Navigator;
+class WorkerNavigator;
+class ScriptState;
+
+class NavigatorFonts final {
+ STATIC_ONLY(NavigatorFonts);
+
+ public:
+ static FontManager* fonts(ScriptState*, Navigator&, ExceptionState&);
+ static FontManager* fonts(ScriptState*, WorkerNavigator&, ExceptionState&);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_FONT_ACCESS_NAVIGATOR_FONTS_H_
diff --git a/chromium/third_party/blink/renderer/modules/font_access/navigator_fonts.idl b/chromium/third_party/blink/renderer/modules/font_access/navigator_fonts.idl
new file mode 100644
index 00000000000..0c6b3fcf71f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/font_access/navigator_fonts.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.
+
+// Entrypoint to the font enumeration API.
+// https://inexorabletash.github.io/font-enumeration/
+[
+ Exposed=Window,
+ SecureContext,
+ ImplementedAs=NavigatorFonts
+] partial interface Navigator {
+ [CallWith=ScriptState, RaisesException, RuntimeEnabled=FontAccess] readonly attribute FontManager fonts;
+};
diff --git a/chromium/third_party/blink/renderer/modules/font_access/worker_navigator_fonts.idl b/chromium/third_party/blink/renderer/modules/font_access/worker_navigator_fonts.idl
new file mode 100644
index 00000000000..326ad7bf2a0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/font_access/worker_navigator_fonts.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.
+
+// Entrypoint to the font enumeration API for workers.
+// https://inexorabletash.github.io/font-enumeration/
+[
+ Exposed=Worker,
+ SecureContext,
+ ImplementedAs=NavigatorFonts
+] partial interface WorkerNavigator {
+ [CallWith=ScriptState, RaisesException, RuntimeEnabled=FontAccess] readonly attribute FontManager fonts;
+};
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/BUILD.gn b/chromium/third_party/blink/renderer/modules/gamepad/BUILD.gn
index bd02b6f3376..fd468519e7f 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/gamepad/BUILD.gn
@@ -40,9 +40,7 @@ blink_modules_sources("gamepad") {
jumbo_source_set("unit_tests") {
testonly = true
- sources = [
- "gamepad_comparisons_test.cc",
- ]
+ sources = [ "gamepad_comparisons_test.cc" ]
configs += [
"//third_party/blink/renderer:config",
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/DEPS b/chromium/third_party/blink/renderer/modules/gamepad/DEPS
index 856ad767222..a62b0413e19 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/DEPS
+++ b/chromium/third_party/blink/renderer/modules/gamepad/DEPS
@@ -8,7 +8,6 @@ include_rules = [
"+device/gamepad/public/mojom/gamepad.mojom-blink.h",
"+device/gamepad/public/mojom/gamepad.mojom-blink-forward.h",
"+device/gamepad/public/mojom/gamepad_hardware_buffer.h",
- "+mojo/public/cpp/bindings/binding.h",
"+mojo/public/cpp/system/buffer.h",
"-third_party/blink/renderer/modules",
"+third_party/blink/renderer/modules/event_modules.h",
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad.cc b/chromium/third_party/blink/renderer/modules/gamepad/gamepad.cc
index c27bd3f0e86..c14806f6edb 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(blink::Visitor* visitor) {
+void Gamepad::Trace(Visitor* visitor) {
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 2f6db63635b..9bd4a0bd64a 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void SetTimestamp(const device::Gamepad& device_gamepad);
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_axis_event.h b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_axis_event.h
index d97b0aaf8d5..d4959a1b40d 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_axis_event.h
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_axis_event.h
@@ -5,8 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_GAMEPAD_GAMEPAD_AXIS_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_GAMEPAD_GAMEPAD_AXIS_EVENT_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gamepad_axis_event_init.h"
#include "third_party/blink/renderer/modules/gamepad/gamepad.h"
-#include "third_party/blink/renderer/modules/gamepad/gamepad_axis_event_init.h"
#include "third_party/blink/renderer/modules/gamepad/gamepad_event.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_axis_event.idl b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_axis_event.idl
index 044b4b8e73e..b8f091d1aec 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_axis_event.idl
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_axis_event.idl
@@ -6,9 +6,9 @@
// https://docs.google.com/document/d/1rnQ1gU0iwPXbO7OvKS6KO9gyfpSdSQvKhK9_OkzUuKE
[
- RuntimeEnabled=GamepadButtonAxisEvents,
- Constructor(DOMString type, optional GamepadAxisEventInit eventInitDict)
+ RuntimeEnabled=GamepadButtonAxisEvents
] interface GamepadAxisEvent : GamepadEvent {
+ constructor(DOMString type, optional GamepadAxisEventInit eventInitDict = {});
[ImplementedAs=getAxis] readonly attribute unsigned long axis;
[ImplementedAs=getValue] readonly attribute double value;
};
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_button_event.h b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_button_event.h
index 60efaf6955d..106abcc4e19 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_button_event.h
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_button_event.h
@@ -5,9 +5,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_GAMEPAD_GAMEPAD_BUTTON_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_GAMEPAD_GAMEPAD_BUTTON_EVENT_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gamepad_button_event_init.h"
#include "third_party/blink/renderer/modules/gamepad/gamepad.h"
#include "third_party/blink/renderer/modules/gamepad/gamepad_button.h"
-#include "third_party/blink/renderer/modules/gamepad/gamepad_button_event_init.h"
#include "third_party/blink/renderer/modules/gamepad/gamepad_event.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_button_event.idl b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_button_event.idl
index 21ac8cf4c1a..5138a3b178d 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_button_event.idl
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_button_event.idl
@@ -6,9 +6,9 @@
// https://docs.google.com/document/d/1rnQ1gU0iwPXbO7OvKS6KO9gyfpSdSQvKhK9_OkzUuKE
[
- RuntimeEnabled=GamepadButtonAxisEvents,
- Constructor(DOMString type, optional GamepadButtonEventInit eventInitDict)
+ RuntimeEnabled=GamepadButtonAxisEvents
] interface GamepadButtonEvent : GamepadEvent {
+ constructor(DOMString type, optional GamepadButtonEventInit eventInitDict = {});
[ImplementedAs=getButton] readonly attribute unsigned long button;
[ImplementedAs=getValue] readonly attribute double value;
};
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 aefdddfb5db..5182e71c777 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc
@@ -2,10 +2,12 @@
// 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/modules/gamepad/gamepad_dispatcher.h"
#include "device/gamepad/public/cpp/gamepads.h"
-#include "third_party/blink/public/platform/interface_provider.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/renderer/modules/gamepad/gamepad_shared_memory_reader.h"
#include "third_party/blink/renderer/modules/gamepad/navigator_gamepad.h"
@@ -16,7 +18,7 @@ using device::mojom::blink::GamepadHapticsManager;
void GamepadDispatcher::SampleGamepads(device::Gamepads& gamepads) {
if (reader_) {
- reader_->SampleGamepads(gamepads);
+ reader_->SampleGamepads(&gamepads);
}
}
@@ -46,13 +48,14 @@ GamepadDispatcher::~GamepadDispatcher() = default;
void GamepadDispatcher::InitializeHaptics() {
if (!gamepad_haptics_manager_remote_) {
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
gamepad_haptics_manager_remote_.BindNewPipeAndPassReceiver(
task_runner_));
}
}
-void GamepadDispatcher::Trace(blink::Visitor* visitor) {
+void GamepadDispatcher::Trace(Visitor* visitor) {
+ visitor->Trace(reader_);
PlatformEventDispatcher::Trace(visitor);
}
@@ -85,7 +88,7 @@ void GamepadDispatcher::DispatchDidConnectOrDisconnectGamepad(
void GamepadDispatcher::StartListening(LocalFrame* frame) {
if (!reader_) {
DCHECK(frame);
- reader_ = std::make_unique<GamepadSharedMemoryReader>(*frame);
+ reader_ = MakeGarbageCollected<GamepadSharedMemoryReader>(*frame);
}
reader_->Start(this);
}
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 27ca6462bf1..a853c7661b2 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.h
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.h
@@ -43,7 +43,7 @@ class GamepadDispatcher final : public GarbageCollected<GamepadDispatcher>,
device::mojom::blink::GamepadHapticsManager::
ResetVibrationActuatorCallback);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void InitializeHaptics();
@@ -62,7 +62,7 @@ class GamepadDispatcher final : public GarbageCollected<GamepadDispatcher>,
bool connected);
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
- std::unique_ptr<GamepadSharedMemoryReader> reader_;
+ Member<GamepadSharedMemoryReader> reader_;
mojo::Remote<device::mojom::blink::GamepadHapticsManager>
gamepad_haptics_manager_remote_;
};
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 2c304003c39..3a6971b4579 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(blink::Visitor* visitor) {
+void GamepadEvent::Trace(Visitor* visitor) {
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 e581f005fd8..ed42ca0c95b 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.h
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.h
@@ -5,9 +5,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_GAMEPAD_GAMEPAD_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_GAMEPAD_GAMEPAD_EVENT_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gamepad_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/gamepad/gamepad.h"
-#include "third_party/blink/renderer/modules/gamepad/gamepad_event_init.h"
namespace blink {
@@ -35,7 +35,7 @@ class GamepadEvent : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<Gamepad> gamepad_;
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.idl b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.idl
index e38ef381bf4..6e5d20526ee 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.idl
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.idl
@@ -4,8 +4,7 @@
// https://w3c.github.io/gamepad/#gamepadevent-interface
-[
- Constructor(DOMString type, optional GamepadEventInit eventInitDict)
-] interface GamepadEvent : Event {
+interface GamepadEvent : Event {
+ constructor(DOMString type, optional GamepadEventInit eventInitDict = {});
[ImplementedAs=getGamepad] readonly attribute 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 0b1c45c2899..0fd45ca7dda 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
@@ -9,8 +9,8 @@
#include "third_party/blink/public/platform/task_type.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_gamepad_effect_parameters.h"
#include "third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.h"
-#include "third_party/blink/renderer/modules/gamepad/gamepad_effect_parameters.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -68,7 +68,7 @@ GamepadHapticActuator::GamepadHapticActuator(
ExecutionContext* context,
int pad_index,
device::GamepadHapticActuatorType type)
- : ContextClient(context),
+ : ExecutionContextClient(context),
pad_index_(pad_index),
// See https://bit.ly/2S0zRAS for task types
gamepad_dispatcher_(MakeGarbageCollected<GamepadDispatcher>(
@@ -187,10 +187,10 @@ void GamepadHapticActuator::OnResetCompleted(
resolver->Resolve(ResultToString(result));
}
-void GamepadHapticActuator::Trace(blink::Visitor* visitor) {
+void GamepadHapticActuator::Trace(Visitor* visitor) {
visitor->Trace(gamepad_dispatcher_);
ScriptWrappable::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 a0433c3c44f..51a19f32680 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
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_GAMEPAD_GAMEPAD_HAPTIC_ACTUATOR_H_
#include "device/gamepad/public/mojom/gamepad.mojom-blink-forward.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/member.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -21,7 +21,7 @@ class ScriptPromise;
class ScriptPromiseResolver;
class GamepadHapticActuator final : public ScriptWrappable,
- public ContextClient {
+ public ExecutionContextClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(GamepadHapticActuator);
@@ -43,7 +43,7 @@ class GamepadHapticActuator final : public ScriptWrappable,
ScriptPromise reset(ScriptState*);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 849602c1470..1a02569388e 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(blink::Visitor* visitor) {
+void GamepadList::Trace(Visitor* visitor) {
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 b4a203c7d88..858d7936ae4 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<Gamepad> items_[device::Gamepads::kItemsLengthCap];
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_list.idl b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_list.idl
index 1298e544e36..24343d47bff 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_list.idl
+++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_list.idl
@@ -27,6 +27,6 @@
NoInterfaceObject
] interface GamepadList {
readonly attribute unsigned long length;
- Gamepad item([DefaultValue=Undefined] optional unsigned long index);
+ Gamepad item(optional unsigned long index = 0);
[NotEnumerable, ImplementedAs=item] getter Gamepad (unsigned long index);
};
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 ecfd71d110c..4ac0b8ffb1f 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
@@ -10,13 +10,14 @@
#include "device/gamepad/public/mojom/gamepad_hardware_buffer.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
-#include "third_party/blink/public/platform/interface_provider.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/gamepad/gamepad_listener.h"
namespace blink {
-GamepadSharedMemoryReader::GamepadSharedMemoryReader(LocalFrame& frame) {
+GamepadSharedMemoryReader::GamepadSharedMemoryReader(LocalFrame& frame)
+ : receiver_(this, frame.DomWindow()) {
frame.GetBrowserInterfaceBroker().GetInterface(
gamepad_monitor_remote_.BindNewPipeAndPassReceiver());
// See https://bit.ly/2S0zRAS for task types
@@ -26,6 +27,10 @@ GamepadSharedMemoryReader::GamepadSharedMemoryReader(LocalFrame& frame) {
receiver_.BindNewPipeAndPassRemote(task_runner));
}
+void GamepadSharedMemoryReader::Trace(Visitor* visitor) {
+ visitor->Trace(receiver_);
+}
+
void GamepadSharedMemoryReader::SendStartMessage() {
if (gamepad_monitor_remote_) {
gamepad_monitor_remote_->GamepadStartPolling(
@@ -71,7 +76,7 @@ void GamepadSharedMemoryReader::Stop() {
SendStopMessage();
}
-void GamepadSharedMemoryReader::SampleGamepads(device::Gamepads& gamepads) {
+void GamepadSharedMemoryReader::SampleGamepads(device::Gamepads* gamepads) {
// Blink should have started observing at this point.
CHECK(listener_);
@@ -111,15 +116,16 @@ void GamepadSharedMemoryReader::SampleGamepads(device::Gamepads& gamepads) {
}
// New data was read successfully, copy it into the output buffer.
- memcpy(&gamepads, &read_into, sizeof(gamepads));
+ memcpy(gamepads, &read_into, sizeof(*gamepads));
if (!ever_interacted_with_) {
// Clear the connected flag if the user hasn't interacted with any of the
// gamepads to prevent fingerprinting. The actual data is not cleared.
// WebKit will only copy out data into the JS buffers for connected
// gamepads so this is sufficient.
- for (size_t i = 0; i < device::Gamepads::kItemsLengthCap; i++)
- gamepads.items[i].connected = false;
+ for (auto& item : gamepads->items) {
+ item.connected = false;
+ }
}
}
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 e621cb5dbb3..1248ecef1fa 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
@@ -10,9 +10,11 @@
#include "base/macros.h"
#include "device/gamepad/public/mojom/gamepad.mojom-blink.h"
#include "device/gamepad/public/mojom/gamepad_hardware_buffer.h"
-#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/system/buffer.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_wrapper_mode.h"
namespace base {
class ReadOnlySharedMemoryRegion;
@@ -28,15 +30,22 @@ namespace blink {
class GamepadListener;
class LocalFrame;
-class GamepadSharedMemoryReader : public device::mojom::blink::GamepadObserver {
+class GamepadSharedMemoryReader
+ : public GarbageCollected<GamepadSharedMemoryReader>,
+ public device::mojom::blink::GamepadObserver {
public:
explicit GamepadSharedMemoryReader(LocalFrame& frame);
~GamepadSharedMemoryReader() override;
+ void Trace(Visitor*);
- void SampleGamepads(device::Gamepads& gamepads);
+ void SampleGamepads(device::Gamepads* gamepads);
void Start(blink::GamepadListener* listener);
void Stop();
+ GamepadSharedMemoryReader(const GamepadSharedMemoryReader&) = delete;
+ GamepadSharedMemoryReader& operator=(const GamepadSharedMemoryReader&) =
+ delete;
+
protected:
void SendStartMessage();
void SendStopMessage();
@@ -56,11 +65,11 @@ class GamepadSharedMemoryReader : public device::mojom::blink::GamepadObserver {
bool ever_interacted_with_ = false;
- mojo::Receiver<device::mojom::blink::GamepadObserver> receiver_{this};
+ HeapMojoReceiver<device::mojom::blink::GamepadObserver,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ receiver_;
mojo::Remote<device::mojom::blink::GamepadMonitor> gamepad_monitor_remote_;
blink::GamepadListener* listener_ = nullptr;
-
- DISALLOW_COPY_AND_ASSIGN(GamepadSharedMemoryReader);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/gamepad/idls.gni b/chromium/third_party/blink/renderer/modules/gamepad/idls.gni
new file mode 100644
index 00000000000..9e7a155f720
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/gamepad/idls.gni
@@ -0,0 +1,22 @@
+# 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 = [
+ "gamepad.idl",
+ "gamepad_axis_event.idl",
+ "gamepad_button.idl",
+ "gamepad_button_event.idl",
+ "gamepad_event.idl",
+ "gamepad_haptic_actuator.idl",
+ "gamepad_list.idl",
+]
+
+modules_dictionary_idl_files = [
+ "gamepad_axis_event_init.idl",
+ "gamepad_button_event_init.idl",
+ "gamepad_effect_parameters.idl",
+ "gamepad_event_init.idl",
+]
+
+modules_dependency_idl_files = [ "navigator_gamepad.idl" ]
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 751c2ae612e..412744fee76 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc
+++ b/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc
@@ -101,7 +101,7 @@ GamepadList* NavigatorGamepad::Gamepads() {
ExecutionContext* context =
DomWindow() ? DomWindow()->GetExecutionContext() : nullptr;
- if (GetFrame() && GetFrame()->IsCrossOriginSubframe()) {
+ if (GetFrame() && GetFrame()->IsCrossOriginToMainFrame()) {
UseCounter::Count(context, WebFeature::kGetGamepadsFromCrossOriginSubframe);
}
@@ -159,7 +159,7 @@ GamepadHapticActuator* NavigatorGamepad::GetVibrationActuatorForGamepad(
return vibration_actuators_[pad_index].Get();
}
-void NavigatorGamepad::Trace(blink::Visitor* visitor) {
+void NavigatorGamepad::Trace(Visitor* visitor) {
visitor->Trace(gamepads_);
visitor->Trace(gamepads_back_);
visitor->Trace(vibration_actuators_);
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 145d0ee0bdc..7306de8965f 100644
--- a/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.h
+++ b/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.h
@@ -27,7 +27,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_GAMEPAD_NAVIGATOR_GAMEPAD_H_
#include "third_party/blink/renderer/core/dom/dom_high_res_time_stamp.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/core/frame/platform_event_controller.h"
@@ -70,7 +70,7 @@ class MODULES_EXPORT NavigatorGamepad final
static GamepadList* getGamepads(Navigator&);
GamepadList* Gamepads();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 578ab161b9d..a433521dd3b 100644
--- a/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.cc
+++ b/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.cc
@@ -4,12 +4,12 @@
#include "third_party/blink/renderer/modules/geolocation/geo_notifier.h"
+#include "base/metrics/histogram_functions.h"
#include "third_party/blink/public/platform/task_type.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_position_options.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/modules/geolocation/geolocation.h"
#include "third_party/blink/renderer/modules/geolocation/geolocation_position_error.h"
-#include "third_party/blink/renderer/modules/geolocation/position_options.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
namespace blink {
@@ -30,13 +30,14 @@ GeoNotifier::GeoNotifier(Geolocation* geolocation,
DCHECK(geolocation_);
DCHECK(success_callback_);
- DEFINE_STATIC_LOCAL(CustomCountHistogram, timeout_histogram,
- ("Geolocation.Timeout", 0,
- 1000 * 60 * 10 /* 10 minute max */, 20 /* buckets */));
- timeout_histogram.Count(options_->timeout());
+ base::UmaHistogramCustomTimes(
+ "Geolocation.Timeout",
+ base::TimeDelta::FromMilliseconds(options_->timeout()),
+ base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10),
+ /* buckets = */ 20);
}
-void GeoNotifier::Trace(blink::Visitor* visitor) {
+void GeoNotifier::Trace(Visitor* visitor) {
visitor->Trace(geolocation_);
visitor->Trace(options_);
visitor->Trace(success_callback_);
@@ -85,7 +86,7 @@ bool GeoNotifier::IsTimerActive() const {
return timer_->IsActive();
}
-void GeoNotifier::Timer::Trace(blink::Visitor* visitor) {
+void GeoNotifier::Timer::Trace(Visitor* visitor) {
visitor->Trace(notifier_);
}
@@ -136,10 +137,11 @@ void GeoNotifier::TimerFired(TimerBase*) {
GeolocationPositionError::kTimeout, "Timeout expired"));
}
- DEFINE_STATIC_LOCAL(CustomCountHistogram, timeout_expired_histogram,
- ("Geolocation.TimeoutExpired", 0,
- 1000 * 60 * 10 /* 10 minute max */, 20 /* buckets */));
- timeout_expired_histogram.Count(options_->timeout());
+ base::UmaHistogramCustomTimes(
+ "Geolocation.TimeoutExpired",
+ base::TimeDelta::FromMilliseconds(options_->timeout()),
+ base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10),
+ /* buckets = */ 20);
geolocation_->RequestTimedOut(this);
}
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 887699311e3..21322392da7 100644
--- a/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.h
+++ b/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.h
@@ -8,7 +8,7 @@
#include "base/single_thread_task_runner.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_position_callback.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_position_error_callback.h"
-#include "third_party/blink/renderer/modules/geolocation/position_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_position_options.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/timer.h"
@@ -27,7 +27,7 @@ class GeoNotifier final : public GarbageCollected<GeoNotifier>,
V8PositionErrorCallback*,
const PositionOptions*);
~GeoNotifier() = default;
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
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(blink::Visitor*);
+ void Trace(Visitor*);
// 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 1ccff0471e7..fc4db61f119 100644
--- a/chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc
+++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc
@@ -34,10 +34,10 @@
#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/hosts_using_features.h"
#include "third_party/blink/renderer/core/frame/performance_monitor.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
+#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/modules/geolocation/geolocation_coordinates.h"
#include "third_party/blink/renderer/modules/geolocation/geolocation_error.h"
@@ -92,7 +92,7 @@ static void ReportGeolocationViolation(Document* doc) {
if (!LocalFrame::HasTransientUserActivation(doc ? doc->GetFrame()
: nullptr)) {
PerformanceMonitor::ReportGenericViolation(
- doc, PerformanceMonitor::kDiscouragedAPIUse,
+ doc->ToExecutionContext(), PerformanceMonitor::kDiscouragedAPIUse,
"Only request geolocation information in response to a user gesture.",
base::TimeDelta(), nullptr);
}
@@ -105,32 +105,32 @@ Geolocation* Geolocation::Create(ExecutionContext* context) {
}
Geolocation::Geolocation(ExecutionContext* context)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
PageVisibilityObserver(GetDocument()->GetPage()),
watchers_(MakeGarbageCollected<GeolocationWatchers>()) {}
Geolocation::~Geolocation() = default;
-void Geolocation::Trace(blink::Visitor* visitor) {
+void Geolocation::Trace(Visitor* visitor) {
visitor->Trace(one_shots_);
visitor->Trace(watchers_);
visitor->Trace(one_shots_being_invoked_);
visitor->Trace(watchers_being_invoked_);
visitor->Trace(last_position_);
ScriptWrappable::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
PageVisibilityObserver::Trace(visitor);
}
Document* Geolocation::GetDocument() const {
- return To<Document>(GetExecutionContext());
+ return Document::From(GetExecutionContext());
}
LocalFrame* Geolocation::GetFrame() const {
return GetDocument() ? GetDocument()->GetFrame() : nullptr;
}
-void Geolocation::ContextDestroyed(ExecutionContext*) {
+void Geolocation::ContextDestroyed() {
StopTimers();
one_shots_.clear();
watchers_->Clear();
@@ -158,24 +158,18 @@ void Geolocation::RecordOriginTypeAccess() const {
} else if (GetFrame()
->GetSettings()
->GetAllowGeolocationOnInsecureOrigins()) {
- // TODO(jww): This should be removed after WebView is fixed so that it
- // disallows geolocation in insecure contexts.
- //
- // See https://crbug.com/603574.
+ // Android WebView allows geolocation in secure contexts for legacy apps.
+ // See https://crbug.com/603574 for details.
Deprecation::CountDeprecation(
document, WebFeature::kGeolocationInsecureOriginDeprecatedNotRemoved);
Deprecation::CountDeprecationCrossOriginIframe(
*document,
WebFeature::kGeolocationInsecureOriginIframeDeprecatedNotRemoved);
- HostsUsingFeatures::CountAnyWorld(
- *document, HostsUsingFeatures::Feature::kGeolocationInsecureHost);
} else {
Deprecation::CountDeprecation(document,
WebFeature::kGeolocationInsecureOrigin);
Deprecation::CountDeprecationCrossOriginIframe(
*document, WebFeature::kGeolocationInsecureOriginIframe);
- HostsUsingFeatures::CountAnyWorld(
- *document, HostsUsingFeatures::Feature::kGeolocationInsecureHost);
}
}
@@ -185,7 +179,8 @@ void Geolocation::getCurrentPosition(V8PositionCallback* success_callback,
if (!GetFrame())
return;
- probe::BreakableLocation(GetDocument(), "Geolocation.getCurrentPosition");
+ probe::BreakableLocation(GetDocument()->ToExecutionContext(),
+ "Geolocation.getCurrentPosition");
auto* notifier = MakeGarbageCollected<GeoNotifier>(this, success_callback,
error_callback, options);
@@ -201,7 +196,8 @@ int Geolocation::watchPosition(V8PositionCallback* success_callback,
if (!GetFrame())
return 0;
- probe::BreakableLocation(GetDocument(), "Geolocation.watchPosition");
+ probe::BreakableLocation(GetDocument()->ToExecutionContext(),
+ "Geolocation.watchPosition");
auto* notifier = MakeGarbageCollected<GeoNotifier>(this, success_callback,
error_callback, options);
@@ -229,7 +225,7 @@ void Geolocation::StartRequest(GeoNotifier* notifier) {
}
if (!GetDocument()->IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kGeolocation,
+ mojom::blink::FeaturePolicyFeature::kGeolocation,
ReportOptions::kReportOnFailure, kFeaturePolicyConsoleWarning)) {
UseCounter::Count(GetDocument(),
WebFeature::kGeolocationDisabledByFeaturePolicy);
diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geolocation.h b/chromium/third_party/blink/renderer/modules/geolocation/geolocation.h
index 65f8b6709ee..eac61f5cd74 100644
--- a/chromium/third_party/blink/renderer/modules/geolocation/geolocation.h
+++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation.h
@@ -33,13 +33,13 @@
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_position_callback.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_position_error_callback.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_position_options.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/page/page_visibility_observer.h"
#include "third_party/blink/renderer/modules/geolocation/geo_notifier.h"
#include "third_party/blink/renderer/modules/geolocation/geolocation_position_error.h"
#include "third_party/blink/renderer/modules/geolocation/geolocation_watchers.h"
#include "third_party/blink/renderer/modules/geolocation/geoposition.h"
-#include "third_party/blink/renderer/modules/geolocation/position_options.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/heap/handle.h"
@@ -58,7 +58,7 @@ class ExecutionContext;
class MODULES_EXPORT Geolocation final
: public ScriptWrappable,
public ActiveScriptWrappable<Geolocation>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public PageVisibilityObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(Geolocation);
@@ -68,10 +68,11 @@ class MODULES_EXPORT Geolocation final
explicit Geolocation(ExecutionContext*);
~Geolocation() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
- // Inherited from ContextLifecycleObserver and PageVisibilityObserver.
- void ContextDestroyed(ExecutionContext*) override;
+ // Inherited from ExecutionContextLifecycleObserver and
+ // PageVisibilityObserver.
+ void ContextDestroyed() override;
Document* GetDocument() const;
LocalFrame* GetFrame() const;
diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geolocation.idl b/chromium/third_party/blink/renderer/modules/geolocation/geolocation.idl
index 93301976d3c..55e55abe96e 100644
--- a/chromium/third_party/blink/renderer/modules/geolocation/geolocation.idl
+++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation.idl
@@ -23,7 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// https://www.w3.org/TR/geolocation-API/#geolocation_interface
+// https://w3c.github.io/geolocation-api/#geolocation_interface
[
ActiveScriptWrappable,
Exposed=Window
@@ -35,7 +35,7 @@
PositionCallback successCallback,
// TODO(crbug.com/841185): |errorCallback| is not nullable in the spec.
optional PositionErrorCallback? errorCallback,
- optional PositionOptions options);
+ optional PositionOptions options = {});
[
LogActivity,
@@ -44,7 +44,7 @@
PositionCallback successCallback,
// TODO(crbug.com/841185): |errorCallback| is not nullable in the spec.
optional PositionErrorCallback? errorCallback,
- optional PositionOptions options);
+ optional PositionOptions options = {});
void clearWatch(long watchID);
};
diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.cc b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.cc
index dab1c87a20c..305a42766c3 100644
--- a/chromium/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.cc
+++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.cc
@@ -27,6 +27,30 @@
namespace blink {
+base::Optional<double> GeolocationCoordinates::altitude() const {
+ if (can_provide_altitude_)
+ return altitude_;
+ return base::nullopt;
+}
+
+base::Optional<double> GeolocationCoordinates::altitudeAccuracy() const {
+ if (can_provide_altitude_accuracy_)
+ return altitude_accuracy_;
+ return base::nullopt;
+}
+
+base::Optional<double> GeolocationCoordinates::heading() const {
+ if (can_provide_heading_)
+ return heading_;
+ return base::nullopt;
+}
+
+base::Optional<double> GeolocationCoordinates::speed() const {
+ if (can_provide_speed_)
+ return speed_;
+ return base::nullopt;
+}
+
double GeolocationCoordinates::altitude(bool& is_null) const {
if (can_provide_altitude_)
return altitude_;
diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.h b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.h
index beefc9278b7..c6d7a5459f8 100644
--- a/chromium/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.h
+++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.h
@@ -61,11 +61,17 @@ class GeolocationCoordinates : public ScriptWrappable {
double latitude() const { return latitude_; }
double longitude() const { return longitude_; }
- double altitude(bool& is_null) const;
+ base::Optional<double> altitude() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ double altitude(bool& is_null) const; // DEPRECATED
double accuracy() const { return accuracy_; }
- double altitudeAccuracy(bool& is_null) const;
- double heading(bool& is_null) const;
- double speed(bool& is_null) const;
+ base::Optional<double> altitudeAccuracy() const;
+ base::Optional<double> heading() const;
+ base::Optional<double> speed() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ double altitudeAccuracy(bool& is_null) const; // DEPRECATED
+ double heading(bool& is_null) const; // DEPRECATED
+ double speed(bool& is_null) const; // DEPRECATED
private:
double latitude_;
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 b1a40f07464..a48a02b863d 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(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
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 32f4dcfa16d..8a97ec70a93 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(blink::Visitor* visitor) {
+void GeolocationWatchers::Trace(Visitor* visitor) {
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 0ea8abcb70a..6d6efc9c97d 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(blink::Visitor*);
+ void Trace(Visitor*);
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 0559846b928..c34b1c44112 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(coordinates_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/geolocation/idls.gni b/chromium/third_party/blink/renderer/modules/geolocation/idls.gni
new file mode 100644
index 00000000000..f3a1927d3c6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/geolocation/idls.gni
@@ -0,0 +1,14 @@
+# 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 = [
+ "geolocation.idl",
+ "geolocation_coordinates.idl",
+ "geolocation_position.idl",
+ "geolocation_position_error.idl",
+]
+
+modules_dictionary_idl_files = [ "position_options.idl" ]
+
+modules_dependency_idl_files = [ "navigator_geolocation.idl" ]
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 6804f3a4e39..e50008d1b44 100644
--- a/chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.cc
+++ b/chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.cc
@@ -52,13 +52,13 @@ Geolocation* NavigatorGeolocation::geolocation(Navigator& navigator) {
Geolocation* NavigatorGeolocation::geolocation() {
if (!geolocation_ && GetSupplementable()->GetFrame()) {
- geolocation_ =
- Geolocation::Create(GetSupplementable()->GetFrame()->GetDocument());
+ geolocation_ = Geolocation::Create(
+ GetSupplementable()->GetFrame()->GetDocument()->ToExecutionContext());
}
return geolocation_;
}
-void NavigatorGeolocation::Trace(blink::Visitor* visitor) {
+void NavigatorGeolocation::Trace(Visitor* visitor) {
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 c4c69848608..91c5cb1308f 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
const char* NameInHeapSnapshot() const override {
return "NavigatorGeolocation";
}
diff --git a/chromium/third_party/blink/renderer/modules/hid/BUILD.gn b/chromium/third_party/blink/renderer/modules/hid/BUILD.gn
index 67e6cfec9e5..bd73c1936a8 100644
--- a/chromium/third_party/blink/renderer/modules/hid/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/hid/BUILD.gn
@@ -27,9 +27,7 @@ blink_modules_sources("hid") {
jumbo_source_set("unit_tests") {
testonly = true
- sources = [
- "hid_report_item_test.cc",
- ]
+ sources = [ "hid_report_item_test.cc" ]
configs += [
"//third_party/blink/renderer:config",
diff --git a/chromium/third_party/blink/renderer/modules/hid/hid.cc b/chromium/third_party/blink/renderer/modules/hid/hid.cc
index 425461ffe13..85f0683fede 100644
--- a/chromium/third_party/blink/renderer/modules/hid/hid.cc
+++ b/chromium/third_party/blink/renderer/modules/hid/hid.cc
@@ -8,6 +8,8 @@
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.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_hid_device_filter.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_hid_device_request_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"
@@ -15,8 +17,6 @@
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/hid/hid_connection_event.h"
#include "third_party/blink/renderer/modules/hid/hid_device.h"
-#include "third_party/blink/renderer/modules/hid/hid_device_filter.h"
-#include "third_party/blink/renderer/modules/hid/hid_device_request_options.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
@@ -26,7 +26,6 @@ namespace {
const char kContextGone[] = "Script context has shut down.";
const char kFeaturePolicyBlocked[] =
"Access to the feature \"hid\" is disallowed by feature policy.";
-const char kNoDeviceSelected[] = "No device selected.";
void RejectWithTypeError(const String& message,
ScriptPromiseResolver* resolver) {
@@ -81,7 +80,11 @@ mojom::blink::HidDeviceFilterPtr ConvertDeviceFilter(
} // namespace
-HID::HID(ExecutionContext& context) : ContextLifecycleObserver(&context) {}
+HID::HID(ExecutionContext& context)
+ : ExecutionContextClient(&context),
+ feature_handle_for_scheduler_(context.GetScheduler()->RegisterFeature(
+ SchedulingPolicy::Feature::kWebHID,
+ {SchedulingPolicy::RecordMetricsForBackForwardCache()})) {}
HID::~HID() {
DCHECK(get_devices_promises_.IsEmpty());
@@ -89,7 +92,7 @@ HID::~HID() {
}
ExecutionContext* HID::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextClient::GetExecutionContext();
}
const AtomicString& HID::InterfaceName() const {
@@ -112,8 +115,8 @@ ScriptPromise HID::getDevices(ScriptState* script_state,
return ScriptPromise();
}
- if (!context->GetSecurityContext().IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kHid, ReportOptions::kReportOnFailure)) {
+ if (!context->IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kHid,
+ ReportOptions::kReportOnFailure)) {
exception_state.ThrowSecurityError(kFeaturePolicyBlocked);
return ScriptPromise();
}
@@ -138,7 +141,8 @@ ScriptPromise HID::requestDevice(ScriptState* script_state,
}
if (!frame->GetDocument()->IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kHid, ReportOptions::kReportOnFailure)) {
+ mojom::blink::FeaturePolicyFeature::kHid,
+ ReportOptions::kReportOnFailure)) {
exception_state.ThrowSecurityError(kFeaturePolicyBlocked);
return ScriptPromise();
}
@@ -207,17 +211,15 @@ void HID::FinishGetDevices(
void HID::FinishRequestDevice(
ScriptPromiseResolver* resolver,
- device::mojom::blink::HidDeviceInfoPtr device_info) {
+ Vector<device::mojom::blink::HidDeviceInfoPtr> device_infos) {
DCHECK(request_device_promises_.Contains(resolver));
request_device_promises_.erase(resolver);
- if (device_info) {
- resolver->Resolve(GetOrCreateDevice(std::move(device_info)));
- } else {
- resolver->Reject(MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotFoundError, kNoDeviceSelected));
- }
- request_device_promises_.erase(resolver);
+ HeapVector<Member<HIDDevice>> devices;
+ for (auto& device_info : device_infos)
+ devices.push_back(GetOrCreateDevice(std::move(device_info)));
+
+ resolver->Resolve(devices);
}
void HID::EnsureServiceConnection() {
@@ -246,18 +248,16 @@ void HID::OnServiceConnectionError() {
HeapHashSet<Member<ScriptPromiseResolver>> request_device_promises;
request_device_promises_.swap(request_device_promises);
- for (ScriptPromiseResolver* resolver : request_device_promises) {
- resolver->Reject(MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotFoundError, kNoDeviceSelected));
- }
+ for (ScriptPromiseResolver* resolver : request_device_promises)
+ resolver->Resolve(HeapVector<Member<HIDDevice>>());
}
-void HID::Trace(blink::Visitor* visitor) {
+void HID::Trace(Visitor* visitor) {
visitor->Trace(get_devices_promises_);
visitor->Trace(request_device_promises_);
visitor->Trace(device_cache_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/hid/hid.h b/chromium/third_party/blink/renderer/modules/hid/hid.h
index 8bc43fa1baf..34123c2b8a0 100644
--- a/chromium/third_party/blink/renderer/modules/hid/hid.h
+++ b/chromium/third_party/blink/renderer/modules/hid/hid.h
@@ -10,9 +10,10 @@
#include "third_party/blink/public/mojom/hid/hid.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/scheduler/public/frame_or_worker_scheduler.h"
namespace blink {
@@ -22,7 +23,7 @@ class HIDDeviceRequestOptions;
class ScriptPromiseResolver;
class ScriptState;
-class HID : public EventTargetWithInlineData, public ContextLifecycleObserver {
+class HID : public EventTargetWithInlineData, public ExecutionContextClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(HID);
@@ -47,7 +48,7 @@ class HID : public EventTargetWithInlineData, public ContextLifecycleObserver {
connection_client,
device::mojom::blink::HidManager::ConnectCallback callback);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
// EventTarget:
@@ -66,12 +67,14 @@ class HID : public EventTargetWithInlineData, public ContextLifecycleObserver {
void FinishGetDevices(ScriptPromiseResolver*,
Vector<device::mojom::blink::HidDeviceInfoPtr>);
void FinishRequestDevice(ScriptPromiseResolver*,
- device::mojom::blink::HidDeviceInfoPtr);
+ Vector<device::mojom::blink::HidDeviceInfoPtr>);
mojo::Remote<mojom::blink::HidService> service_;
HeapHashSet<Member<ScriptPromiseResolver>> get_devices_promises_;
HeapHashSet<Member<ScriptPromiseResolver>> request_device_promises_;
HeapHashMap<String, WeakMember<HIDDevice>> device_cache_;
+ FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle
+ feature_handle_for_scheduler_;
};
} // namespace blink
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 e46dd0e4c49..901da6a0c37 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(blink::Visitor* visitor) {
+void HIDCollectionInfo::Trace(Visitor* visitor) {
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 aada3a674d0..60b13edc0d7 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(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) 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 88dc0452da7..f99b723eed3 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
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/modules/hid/hid_connection_event.h"
-#include "third_party/blink/renderer/modules/hid/hid_connection_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_hid_connection_event_init.h"
#include "third_party/blink/renderer/modules/hid/hid_device.h"
namespace blink {
@@ -29,7 +29,7 @@ HIDConnectionEvent::HIDConnectionEvent(const AtomicString& type,
HIDDevice* device)
: Event(type, Bubbles::kNo, Cancelable::kNo) {}
-void HIDConnectionEvent::Trace(blink::Visitor* visitor) {
+void HIDConnectionEvent::Trace(Visitor* visitor) {
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 41c78ec19e1..134826a65c1 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
@@ -26,7 +26,7 @@ class HIDConnectionEvent final : public Event {
HIDDevice* device() const { return nullptr; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/hid/hid_connection_event.idl b/chromium/third_party/blink/renderer/modules/hid/hid_connection_event.idl
index 72ede44a318..c61dbe2826c 100644
--- a/chromium/third_party/blink/renderer/modules/hid/hid_connection_event.idl
+++ b/chromium/third_party/blink/renderer/modules/hid/hid_connection_event.idl
@@ -6,10 +6,10 @@
// https://wicg.github.io/webhid/index.html#events
[
- Constructor(DOMString type, HIDConnectionEventInit eventInitDict),
Exposed(Window WebHID),
SecureContext
] interface HIDConnectionEvent : Event {
+ constructor(DOMString type, HIDConnectionEventInit eventInitDict);
// The connected or disconnected device.
[SameObject] readonly attribute HIDDevice device;
};
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 49735f7d39e..8c84f51240d 100644
--- a/chromium/third_party/blink/renderer/modules/hid/hid_device.cc
+++ b/chromium/third_party/blink/renderer/modules/hid/hid_device.cc
@@ -30,6 +30,8 @@ const char kSendFeatureReportFailed[] = "Failed to write the feature report.";
const char kReceiveFeatureReportFailed[] =
"Failed to receive the feature report.";
const char kUnexpectedClose[] = "The device was closed unexpectedly.";
+const char kArrayBufferTooBig[] =
+ "The provided ArrayBuffer exceeds the maximum allowed size.";
Vector<uint8_t> ConvertBufferSource(
const ArrayBufferOrArrayBufferView& buffer) {
@@ -37,12 +39,14 @@ Vector<uint8_t> ConvertBufferSource(
Vector<uint8_t> vector;
if (buffer.IsArrayBuffer()) {
vector.Append(static_cast<uint8_t*>(buffer.GetAsArrayBuffer()->Data()),
- buffer.GetAsArrayBuffer()->DeprecatedByteLengthAsUnsigned());
+ base::checked_cast<wtf_size_t>(
+ buffer.GetAsArrayBuffer()->ByteLengthAsSizeT()));
} else {
vector.Append(
static_cast<uint8_t*>(
buffer.GetAsArrayBufferView().View()->BaseAddress()),
- buffer.GetAsArrayBufferView().View()->deprecatedByteLengthAsUnsigned());
+ base::checked_cast<wtf_size_t>(
+ buffer.GetAsArrayBufferView().View()->byteLengthAsSizeT()));
}
return vector;
}
@@ -86,7 +90,7 @@ bool IsProtected(
HIDDevice::HIDDevice(HID* parent,
device::mojom::blink::HidDeviceInfoPtr info,
ExecutionContext* context)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
parent_(parent),
device_info_(std::move(info)) {
DCHECK(device_info_);
@@ -104,7 +108,7 @@ HIDDevice::~HIDDevice() {
}
ExecutionContext* HIDDevice::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
const AtomicString& HIDDevice::InterfaceName() const {
@@ -188,6 +192,17 @@ ScriptPromise HIDDevice::sendReport(ScriptState* script_state,
return promise;
}
+ size_t data_size =
+ data.IsArrayBuffer()
+ ? data.GetAsArrayBuffer()->ByteLengthAsSizeT()
+ : data.GetAsArrayBufferView().View()->byteLengthAsSizeT();
+
+ if (!base::CheckedNumeric<wtf_size_t>(data_size).IsValid()) {
+ resolver->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kNotSupportedError, kArrayBufferTooBig));
+ return promise;
+ }
+
device_requests_.insert(resolver);
connection_->Write(report_id, ConvertBufferSource(data),
WTF::Bind(&HIDDevice::FinishSendReport,
@@ -211,6 +226,17 @@ ScriptPromise HIDDevice::sendFeatureReport(
return promise;
}
+ size_t data_size =
+ data.IsArrayBuffer()
+ ? data.GetAsArrayBuffer()->ByteLengthAsSizeT()
+ : data.GetAsArrayBufferView().View()->byteLengthAsSizeT();
+
+ if (!base::CheckedNumeric<wtf_size_t>(data_size).IsValid()) {
+ resolver->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kNotSupportedError, kArrayBufferTooBig));
+ return promise;
+ }
+
device_requests_.insert(resolver);
connection_->SendFeatureReport(
report_id, ConvertBufferSource(data),
@@ -240,19 +266,19 @@ ScriptPromise HIDDevice::receiveFeatureReport(ScriptState* script_state,
return promise;
}
-void HIDDevice::ContextDestroyed(ExecutionContext*) {
+void HIDDevice::ContextDestroyed() {
connection_.reset();
device_requests_.clear();
receiver_.reset();
}
-void HIDDevice::Trace(blink::Visitor* visitor) {
+void HIDDevice::Trace(Visitor* visitor) {
visitor->Trace(parent_);
visitor->Trace(device_requests_);
visitor->Trace(collections_);
EventTargetWithInlineData::Trace(visitor);
ScriptWrappable::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
void HIDDevice::Dispose() {
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 3c6eaf79ca4..d4126a559f9 100644
--- a/chromium/third_party/blink/renderer/modules/hid/hid_device.h
+++ b/chromium/third_party/blink/renderer/modules/hid/hid_device.h
@@ -13,7 +13,7 @@
#include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/heap/heap_allocator.h"
@@ -31,7 +31,7 @@ class ScriptState;
class MODULES_EXPORT HIDDevice
: public EventTargetWithInlineData,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public device::mojom::blink::HidConnectionClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(HIDDevice);
@@ -69,8 +69,8 @@ class MODULES_EXPORT HIDDevice
const ArrayBufferOrArrayBufferView& data);
ScriptPromise receiveFeatureReport(ScriptState*, uint8_t report_id);
- // ContextLifecycleObserver:
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver:
+ void ContextDestroyed() override;
void Trace(Visitor*) override;
void Dispose();
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 f28f06be7c2..a6a9bf6c687 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(blink::Visitor* visitor) {
+void HIDInputReportEvent::Trace(Visitor* visitor) {
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 57c99507358..bd5ce902d37 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 672a73ca0b7..a54ee2a8fe6 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(blink::Visitor* visitor) {
+void HIDReportInfo::Trace(Visitor* visitor) {
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 05e8847ee02..7384a8d9289 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(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
uint8_t report_id_;
diff --git a/chromium/third_party/blink/renderer/modules/hid/idls.gni b/chromium/third_party/blink/renderer/modules/hid/idls.gni
new file mode 100644
index 00000000000..2291d2fff3e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/hid/idls.gni
@@ -0,0 +1,21 @@
+# 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 = [
+ "hid.idl",
+ "hid_collection_info.idl",
+ "hid_connection_event.idl",
+ "hid_device.idl",
+ "hid_input_report_event.idl",
+ "hid_report_info.idl",
+ "hid_report_item.idl",
+]
+
+modules_dictionary_idl_files = [
+ "hid_connection_event_init.idl",
+ "hid_device_filter.idl",
+ "hid_device_request_options.idl",
+]
+
+modules_dependency_idl_files = [ "navigator_hid.idl" ]
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 91618598171..226b01e7969 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(blink::Visitor* visitor) {
+void NavigatorHID::Trace(Visitor* visitor) {
visitor->Trace(hid_);
Supplement<Navigator>::Trace(visitor);
}
@@ -37,7 +37,8 @@ void NavigatorHID::Trace(blink::Visitor* visitor) {
NavigatorHID::NavigatorHID(Navigator& navigator) {
if (navigator.GetFrame()) {
DCHECK(navigator.GetFrame()->GetDocument());
- hid_ = MakeGarbageCollected<HID>(*navigator.GetFrame()->GetDocument());
+ hid_ = MakeGarbageCollected<HID>(
+ *navigator.GetFrame()->GetDocument()->ToExecutionContext());
}
}
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 c7f56f33b7b..2f6979e53bf 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
explicit NavigatorHID(Navigator&);
diff --git a/chromium/third_party/blink/renderer/modules/idle/DEPS b/chromium/third_party/blink/renderer/modules/idle/DEPS
index 6d1e8c355ef..e9d07a53c45 100644
--- a/chromium/third_party/blink/renderer/modules/idle/DEPS
+++ b/chromium/third_party/blink/renderer/modules/idle/DEPS
@@ -1,5 +1,4 @@
include_rules = [
- "+mojo/public/cpp/bindings/binding.h",
"-third_party/blink/renderer/modules",
"+third_party/blink/renderer/modules/event_modules.h",
"+third_party/blink/renderer/modules/event_target_modules.h",
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 8e6fda105cd..f0a415b274d 100644
--- a/chromium/third_party/blink/renderer/modules/idle/idle_detector.cc
+++ b/chromium/third_party/blink/renderer/modules/idle/idle_detector.cc
@@ -10,9 +10,10 @@
#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/idle/idle_manager.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_idle_options.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/execution_context/security_context.h"
-#include "third_party/blink/renderer/modules/idle/idle_options.h"
#include "third_party/blink/renderer/modules/idle/idle_state.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
@@ -56,7 +57,7 @@ IdleDetector* IdleDetector::Create(ScriptState* script_state,
}
IdleDetector::IdleDetector(ExecutionContext* context, base::TimeDelta threshold)
- : ContextClient(context), threshold_(threshold), receiver_(this) {}
+ : ExecutionContextClient(context), threshold_(threshold), receiver_(this) {}
IdleDetector::~IdleDetector() = default;
@@ -69,7 +70,7 @@ const AtomicString& IdleDetector::InterfaceName() const {
}
ExecutionContext* IdleDetector::GetExecutionContext() const {
- return ContextClient::GetExecutionContext();
+ return ExecutionContextClient::GetExecutionContext();
}
bool IdleDetector::HasPendingActivity() const {
@@ -78,18 +79,17 @@ bool IdleDetector::HasPendingActivity() const {
return GetExecutionContext() && HasEventListeners();
}
-ScriptPromise IdleDetector::start(ScriptState* script_state) {
+ScriptPromise IdleDetector::start(ScriptState* script_state,
+ ExceptionState& exception_state) {
// Validate options.
ExecutionContext* context = ExecutionContext::From(script_state);
DCHECK(context->IsContextThread());
- if (!context->GetSecurityContext().IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kIdleDetection,
+ if (!context->IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kIdleDetection,
ReportOptions::kReportOnFailure)) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kSecurityError,
- kFeaturePolicyBlocked));
+ exception_state.ThrowSecurityError(kFeaturePolicyBlocked);
+ return ScriptPromise();
}
StartMonitoring();
@@ -149,10 +149,10 @@ void IdleDetector::Update(mojom::blink::IdleStatePtr state) {
DispatchEvent(*Event::Create(event_type_names::kChange));
}
-void IdleDetector::Trace(blink::Visitor* visitor) {
+void IdleDetector::Trace(Visitor* visitor) {
visitor->Trace(state_);
EventTargetWithInlineData::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
ActiveScriptWrappable::Trace(visitor);
}
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 5ad49150618..92b3b2760f7 100644
--- a/chromium/third_party/blink/renderer/modules/idle/idle_detector.h
+++ b/chromium/third_party/blink/renderer/modules/idle/idle_detector.h
@@ -11,20 +11,22 @@
#include "third_party/blink/public/mojom/idle/idle_manager.mojom-blink-forward.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_idle_options.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
-#include "third_party/blink/renderer/modules/idle/idle_options.h"
#include "third_party/blink/renderer/modules/idle/idle_state.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
+class ExceptionState;
+
class IdleDetector final : public EventTargetWithInlineData,
public ActiveScriptWrappable<IdleDetector>,
- public ContextClient,
+ public ExecutionContextClient,
public mojom::blink::IdleMonitor {
USING_GARBAGE_COLLECTED_MIXIN(IdleDetector);
DEFINE_WRAPPERTYPEINFO();
@@ -50,7 +52,7 @@ class IdleDetector final : public EventTargetWithInlineData,
bool HasPendingActivity() const final;
// IdleDetector IDL interface.
- ScriptPromise start(ScriptState*);
+ ScriptPromise start(ScriptState*, ExceptionState&);
void stop();
blink::IdleState* state() const;
DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange)
@@ -61,7 +63,7 @@ class IdleDetector final : public EventTargetWithInlineData,
// causes an event to be dispatched.
void Update(mojom::blink::IdleStatePtr state) override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<blink::IdleState> state_;
diff --git a/chromium/third_party/blink/renderer/modules/idle/idle_detector.idl b/chromium/third_party/blink/renderer/modules/idle/idle_detector.idl
index 05926b07f6a..9daf79ec7aa 100644
--- a/chromium/third_party/blink/renderer/modules/idle/idle_detector.idl
+++ b/chromium/third_party/blink/renderer/modules/idle/idle_detector.idl
@@ -4,18 +4,15 @@
// https://github.com/samuelgoto/idle-detection
-
[
SecureContext,
Exposed=(Window,DedicatedWorker),
ActiveScriptWrappable,
- Constructor(optional IdleOptions options),
- ConstructorCallWith=ScriptState,
- RaisesException=Constructor,
RuntimeEnabled=IdleDetection
] interface IdleDetector : EventTarget {
+ [CallWith=ScriptState, RaisesException] constructor(optional IdleOptions options = {});
readonly attribute IdleState state;
attribute EventHandler onchange;
- [CallWith=ScriptState, MeasureAs=IdleDetectionStart] Promise<void> start();
+ [CallWith=ScriptState, RaisesException, MeasureAs=IdleDetectionStart] Promise<void> start();
void stop();
};
diff --git a/chromium/third_party/blink/renderer/modules/idle/idle_state.cc b/chromium/third_party/blink/renderer/modules/idle/idle_state.cc
index d8f8fa1a6f7..eb1495922c6 100644
--- a/chromium/third_party/blink/renderer/modules/idle/idle_state.cc
+++ b/chromium/third_party/blink/renderer/modules/idle/idle_state.cc
@@ -4,7 +4,6 @@
#include "third_party/blink/renderer/modules/idle/idle_state.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
diff --git a/chromium/third_party/blink/renderer/modules/idle/idle_state.h b/chromium/third_party/blink/renderer/modules/idle/idle_state.h
index f5d7ad1ced3..b721fb64647 100644
--- a/chromium/third_party/blink/renderer/modules/idle/idle_state.h
+++ b/chromium/third_party/blink/renderer/modules/idle/idle_state.h
@@ -6,7 +6,6 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_IDLE_IDLE_STATE_H_
#include "base/macros.h"
-#include "mojo/public/cpp/bindings/binding.h"
#include "third_party/blink/public/mojom/idle/idle_manager.mojom-blink.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
diff --git a/chromium/third_party/blink/renderer/modules/idle/idls.gni b/chromium/third_party/blink/renderer/modules/idle/idls.gni
new file mode 100644
index 00000000000..90fa2fdad6b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/idle/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "idle_detector.idl",
+ "idle_state.idl",
+]
+
+modules_dictionary_idl_files = [ "idle_options.idl" ]
diff --git a/chromium/third_party/blink/renderer/modules/image_downloader/DEPS b/chromium/third_party/blink/renderer/modules/image_downloader/DEPS
index e0a2061a0eb..655b3ce8a6c 100644
--- a/chromium/third_party/blink/renderer/modules/image_downloader/DEPS
+++ b/chromium/third_party/blink/renderer/modules/image_downloader/DEPS
@@ -1,4 +1,5 @@
include_rules = [
+ "+services/network/public/cpp/request_destination.h",
"+skia/ext/image_operations.h",
"+ui/gfx/geometry/size.h",
]
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 d7a324a5cd7..ae4593165a6 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
@@ -84,7 +84,7 @@ void FilterAndResizeImagesForMaximalSize(
const WTF::Vector<SkBitmap>& unfiltered,
uint32_t max_image_size,
WTF::Vector<SkBitmap>* images,
- WTF::Vector<blink::WebSize>* original_image_sizes) {
+ WTF::Vector<gfx::Size>* original_image_sizes) {
images->clear();
original_image_sizes->clear();
@@ -147,7 +147,8 @@ void ImageDownloaderImpl::ProvideTo(LocalFrame& frame) {
ImageDownloaderImpl::ImageDownloaderImpl(LocalFrame& frame)
: Supplement<LocalFrame>(frame),
- ContextLifecycleObserver(frame.GetDocument()->GetExecutionContext()) {
+ ExecutionContextLifecycleObserver(
+ frame.GetDocument()->GetExecutionContext()) {
frame.GetInterfaceRegistry()->AddInterface(WTF::BindRepeating(
&ImageDownloaderImpl::CreateMojoService, WrapWeakPersistent(this)));
}
@@ -196,7 +197,7 @@ void ImageDownloaderImpl::DidDownloadImage(
int32_t http_status_code,
const WTF::Vector<SkBitmap>& images) {
WTF::Vector<SkBitmap> result_images;
- WTF::Vector<WebSize> result_original_image_sizes;
+ WTF::Vector<gfx::Size> result_original_image_sizes;
FilterAndResizeImagesForMaximalSize(images, max_image_size, &result_images,
&result_original_image_sizes);
@@ -253,10 +254,10 @@ void ImageDownloaderImpl::DidFetchImage(
void ImageDownloaderImpl::Trace(Visitor* visitor) {
Supplement<LocalFrame>::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
-void ImageDownloaderImpl::ContextDestroyed(ExecutionContext*) {
+void ImageDownloaderImpl::ContextDestroyed() {
for (const auto& fetcher : image_fetchers_) {
// Will run callbacks with an empty image vector.
fetcher->Dispose();
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 233522255ec..19e25edcd10 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
@@ -7,7 +7,7 @@
#include "mojo/public/cpp/bindings/receiver.h"
#include "third_party/blink/public/mojom/image_downloader/image_downloader.mojom-blink.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/supplementable.h"
namespace blink {
@@ -21,7 +21,7 @@ struct WebSize;
class ImageDownloaderImpl final : public GarbageCollected<ImageDownloaderImpl>,
public Supplement<LocalFrame>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public mojom::blink::ImageDownloader {
USING_PRE_FINALIZER(ImageDownloaderImpl, Dispose);
USING_GARBAGE_COLLECTED_MIXIN(ImageDownloaderImpl);
@@ -41,8 +41,8 @@ class ImageDownloaderImpl final : public GarbageCollected<ImageDownloaderImpl>,
void Trace(Visitor*) override;
- // OverContextLifecycleObserver overrides.
- void ContextDestroyed(ExecutionContext*) override;
+ // OverExecutionContextLifecycleObserver overrides.
+ void ContextDestroyed() override;
private:
// ImageDownloader implementation. Request to asynchronously download an
diff --git a/chromium/third_party/blink/renderer/modules/image_downloader/multi_resolution_image_resource_fetcher.cc b/chromium/third_party/blink/renderer/modules/image_downloader/multi_resolution_image_resource_fetcher.cc
index 689c426e491..d1d6f4d21f4 100644
--- a/chromium/third_party/blink/renderer/modules/image_downloader/multi_resolution_image_resource_fetcher.cc
+++ b/chromium/third_party/blink/renderer/modules/image_downloader/multi_resolution_image_resource_fetcher.cc
@@ -209,6 +209,7 @@ void MultiResolutionImageResourceFetcher::Start(
request_.SetSiteForCookies(frame->GetDocument()->SiteForCookies());
request_.SetMode(request_mode);
request_.SetCredentialsMode(credentials_mode);
+ request_.SetRequestDestination(network::mojom::RequestDestination::kImage);
client_ = std::make_unique<ClientImpl>(std::move(callback));
diff --git a/chromium/third_party/blink/renderer/modules/image_downloader/multi_resolution_image_resource_fetcher.h b/chromium/third_party/blink/renderer/modules/image_downloader/multi_resolution_image_resource_fetcher.h
index a092e5b6fc1..eaf5c752f73 100644
--- a/chromium/third_party/blink/renderer/modules/image_downloader/multi_resolution_image_resource_fetcher.h
+++ b/chromium/third_party/blink/renderer/modules/image_downloader/multi_resolution_image_resource_fetcher.h
@@ -13,7 +13,7 @@
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink-forward.h"
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/public/web/web_associated_url_loader_options.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/idls.gni b/chromium/third_party/blink/renderer/modules/imagecapture/idls.gni
new file mode 100644
index 00000000000..f43e97793aa
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/imagecapture/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "image_capture.idl",
+ "media_settings_range.idl",
+ "photo_capabilities.idl",
+]
+
+modules_dictionary_idl_files = [
+ "constrain_point_2d_parameters.idl",
+ "photo_settings.idl",
+ "point_2d.idl",
+]
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 08eeae358e3..ef476ef9818 100644
--- a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc
+++ b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc
@@ -12,6 +12,8 @@
#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"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_constraints.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -21,8 +23,6 @@
#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/mediastream/media_track_capabilities.h"
-#include "third_party/blink/renderer/modules/mediastream/media_track_constraints.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/mojo/mojo_helper.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -109,14 +109,14 @@ const AtomicString& ImageCapture::InterfaceName() const {
}
ExecutionContext* ImageCapture::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
bool ImageCapture::HasPendingActivity() const {
return GetExecutionContext() && HasEventListeners();
}
-void ImageCapture::ContextDestroyed(ExecutionContext*) {
+void ImageCapture::ContextDestroyed() {
RemoveAllEventListeners();
service_requests_.clear();
DCHECK(!HasEventListeners());
@@ -689,7 +689,7 @@ void ImageCapture::GetMediaTrackSettings(MediaTrackSettings* settings) const {
}
ImageCapture::ImageCapture(ExecutionContext* context, MediaStreamTrack* track)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
stream_track_(track),
capabilities_(MediaTrackCapabilities::Create()),
settings_(MediaTrackSettings::Create()),
@@ -955,7 +955,7 @@ void ImageCapture::ResolveWithPhotoCapabilities(
resolver->Resolve(photo_capabilities_);
}
-void ImageCapture::Trace(blink::Visitor* visitor) {
+void ImageCapture::Trace(Visitor* visitor) {
visitor->Trace(stream_track_);
visitor->Trace(capabilities_);
visitor->Trace(settings_);
@@ -964,7 +964,7 @@ void ImageCapture::Trace(blink::Visitor* visitor) {
visitor->Trace(photo_capabilities_);
visitor->Trace(service_requests_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 34e4577d81a..ba19865ed56 100644
--- a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.h
+++ b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.h
@@ -10,13 +10,13 @@
#include "mojo/public/cpp/bindings/remote.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"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_constraint_set.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_settings.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_photo_settings.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#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/imagecapture/photo_settings.h"
-#include "third_party/blink/renderer/modules/mediastream/media_track_capabilities.h"
-#include "third_party/blink/renderer/modules/mediastream/media_track_constraint_set.h"
-#include "third_party/blink/renderer/modules/mediastream/media_track_settings.h"
#include "third_party/blink/renderer/modules/modules_export.h"
namespace blink {
@@ -32,7 +32,7 @@ class ScriptPromiseResolver;
class MODULES_EXPORT ImageCapture final
: public EventTargetWithInlineData,
public ActiveScriptWrappable<ImageCapture>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(ImageCapture);
DEFINE_WRAPPERTYPEINFO();
@@ -51,8 +51,8 @@ class MODULES_EXPORT ImageCapture final
// ScriptWrappable implementation.
bool HasPendingActivity() const final;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
MediaStreamTrack* videoStreamTrack() const { return stream_track_.Get(); }
@@ -76,7 +76,7 @@ class MODULES_EXPORT ImageCapture final
void ClearMediaTrackConstraints();
void GetMediaTrackSettings(MediaTrackSettings*) const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
using PromiseResolverFunction =
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 b38692c43bf..d27b2659a99 100644
--- a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.idl
+++ b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.idl
@@ -6,12 +6,9 @@
[
ActiveScriptWrappable,
- ConstructorCallWith=ExecutionContext,
- Constructor(MediaStreamTrack track),
- MeasureAs=ImageCaptureConstructor,
- RaisesException=Constructor,
Exposed=Window
] interface ImageCapture {
+ [CallWith=ExecutionContext, RaisesException, MeasureAs=ImageCaptureConstructor] constructor(MediaStreamTrack track);
[ImplementedAs=videoStreamTrack] readonly attribute MediaStreamTrack track;
[CallWith=ScriptState] Promise<PhotoCapabilities> getPhotoCapabilities();
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 c0b3f881b0e..dfc36212876 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
@@ -107,9 +107,11 @@ void ImageCaptureFrameGrabber::SingleShotFrameHandler::OnVideoFrameOnIOThread(
return;
}
- const uint32_t destination_pixel_format =
- (kN32_SkColorType == kRGBA_8888_SkColorType) ? libyuv::FOURCC_ABGR
- : libyuv::FOURCC_ARGB;
+#if SK_PMCOLOR_BYTE_ORDER(R, G, B, A)
+ const uint32_t destination_pixel_format = libyuv::FOURCC_ABGR;
+#else
+ const uint32_t destination_pixel_format = libyuv::FOURCC_ARGB;
+#endif
uint8_t* destination_plane = static_cast<uint8_t*>(pixmap.writable_addr());
int destination_stride = pixmap.width() * 4;
int destination_width = pixmap.width();
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 4c2beb930ac..04cea46c1d5 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(blink::Visitor* visitor) {
+void PhotoCapabilities::Trace(Visitor* visitor) {
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 314509c5f9b..273ec23828b 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<MediaSettingsRange> image_height_;
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/BUILD.gn b/chromium/third_party/blink/renderer/modules/indexeddb/BUILD.gn
index 1728725a3bf..593b29a7949 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/BUILD.gn
@@ -88,7 +88,5 @@ blink_modules_sources("indexeddb") {
"web_idb_transaction_impl.h",
]
- public_deps = [
- "//third_party/blink/public/mojom:mojom_modules_blink",
- ]
+ public_deps = [ "//third_party/blink/public/mojom:mojom_modules_blink" ]
}
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 2bfd37384f0..4989637cd4c 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 777f8d0a6f7..aa1a275705a 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_any.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_any.cc
@@ -35,14 +35,6 @@
namespace blink {
-IDBAny* IDBAny::CreateUndefined() {
- return MakeGarbageCollected<IDBAny>(kUndefinedType);
-}
-
-IDBAny* IDBAny::CreateNull() {
- return MakeGarbageCollected<IDBAny>(kNullType);
-}
-
IDBAny::IDBAny(Type type) : type_(type) {
DCHECK(type == kUndefinedType || type == kNullType);
}
@@ -67,8 +59,8 @@ IDBCursor* IDBAny::IdbCursor() const {
IDBCursorWithValue* IDBAny::IdbCursorWithValue() const {
DCHECK_EQ(type_, kIDBCursorWithValueType);
- SECURITY_DCHECK(idb_cursor_->IsCursorWithValue());
- return ToIDBCursorWithValue(idb_cursor_.Get());
+ SECURITY_DCHECK(IsA<IDBCursorWithValue>(idb_cursor_.Get()));
+ return To<IDBCursorWithValue>(idb_cursor_.Get());
}
IDBDatabase* IDBAny::IdbDatabase() const {
@@ -101,8 +93,8 @@ IDBAny::IDBAny(DOMStringList* value)
: type_(kDOMStringListType), dom_string_list_(value) {}
IDBAny::IDBAny(IDBCursor* value)
- : type_(value->IsCursorWithValue() ? kIDBCursorWithValueType
- : kIDBCursorType),
+ : type_(IsA<IDBCursorWithValue>(value) ? kIDBCursorWithValueType
+ : kIDBCursorType),
idb_cursor_(value) {}
IDBAny::IDBAny(IDBDatabase* value)
@@ -119,7 +111,7 @@ IDBAny::IDBAny(std::unique_ptr<IDBKey> key)
IDBAny::IDBAny(int64_t value) : type_(kIntegerType), integer_(value) {}
-void IDBAny::Trace(blink::Visitor* visitor) {
+void IDBAny::Trace(Visitor* visitor) {
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 a5ca81642ff..825eeae6ffa 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_any.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_any.h
@@ -55,9 +55,6 @@ class IDBObjectStore;
class MODULES_EXPORT IDBAny final : public GarbageCollected<IDBAny> {
public:
- static IDBAny* CreateUndefined();
- static IDBAny* CreateNull();
-
enum Type {
kUndefinedType = 0,
kNullType,
@@ -81,7 +78,7 @@ class MODULES_EXPORT IDBAny final : public GarbageCollected<IDBAny> {
explicit IDBAny(int64_t);
~IDBAny();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
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 782f3a05223..b0552bc3e58 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc
@@ -32,6 +32,7 @@
#include "third_party/blink/renderer/bindings/modules/v8/v8_idb_request.h"
#include "third_party/blink/renderer/modules/indexed_db_names.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_any.h"
+#include "third_party/blink/renderer/modules/indexeddb/idb_cursor_with_value.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_database.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_object_store.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_tracing.h"
@@ -41,6 +42,7 @@
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/v8_private_property.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -62,7 +64,7 @@ IDBCursor::IDBCursor(std::unique_ptr<WebIDBCursor> backend,
IDBCursor::~IDBCursor() = default;
-void IDBCursor::Trace(blink::Visitor* visitor) {
+void IDBCursor::Trace(Visitor* visitor) {
visitor->Trace(request_);
visitor->Trace(source_);
visitor->Trace(transaction_);
@@ -392,7 +394,7 @@ ScriptValue IDBCursor::primaryKey(ScriptState* script_state) {
}
ScriptValue IDBCursor::value(ScriptState* script_state) {
- DCHECK(IsCursorWithValue());
+ DCHECK(IsA<IDBCursorWithValue>(this));
IDBAny* value;
if (value_) {
@@ -407,7 +409,7 @@ ScriptValue IDBCursor::value(ScriptState* script_state) {
#endif // DCHECK_IS_ON()
} else {
- value = IDBAny::CreateUndefined();
+ value = MakeGarbageCollected<IDBAny>(IDBAny::kUndefinedType);
}
value_dirty_ = false;
@@ -430,7 +432,7 @@ void IDBCursor::SetValueReady(std::unique_ptr<IDBKey> key,
got_value_ = true;
- if (!IsCursorWithValue())
+ if (!IsA<IDBCursorWithValue>(this))
return;
value_dirty_ = true;
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 c3292558d28..86ca472dff3 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void ContextWillBeDestroyed() { backend_.reset(); }
WARN_UNUSED_RESULT v8::Local<v8::Object> AssociateWithWrapper(
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.idl b/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.idl
index 2ac7fa5dd93..21e8813eb40 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.idl
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.idl
@@ -47,7 +47,7 @@ enum IDBCursorDirection {
[RaisesException] void advance([EnforceRange] unsigned long count);
[CallWith=ScriptState, ImplementedAs=Continue, RaisesException]
- void continue([DefaultValue=Undefined] optional any key);
+ void continue(optional any key = null);
[CallWith=ScriptState, RaisesException]
void continuePrimaryKey(any key, any primaryKey);
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor_with_value.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor_with_value.h
index 559640e80dc..26b35f268d7 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor_with_value.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor_with_value.h
@@ -31,6 +31,7 @@
#include "third_party/blink/renderer/modules/indexeddb/idb_cursor.h"
#include "third_party/blink/renderer/modules/indexeddb/indexed_db.h"
#include "third_party/blink/renderer/modules/indexeddb/web_idb_cursor.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -56,11 +57,12 @@ class IDBCursorWithValue final : public IDBCursor {
bool IsCursorWithValue() const override { return true; }
};
-DEFINE_TYPE_CASTS(IDBCursorWithValue,
- IDBCursor,
- cursor,
- cursor->IsCursorWithValue(),
- cursor.IsCursorWithValue());
+template <>
+struct DowncastTraits<IDBCursorWithValue> {
+ static bool AllowFrom(const IDBCursor& cursor) {
+ return cursor.IsCursorWithValue();
+ }
+};
} // namespace blink
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 97f5b505fab..3f2764199a4 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc
@@ -30,6 +30,7 @@
#include "base/atomic_sequence_num.h"
#include "base/optional.h"
+#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
@@ -93,12 +94,15 @@ const char IDBDatabase::kTransactionReadOnlyErrorMessage[] =
const char IDBDatabase::kDatabaseClosedErrorMessage[] =
"The database connection is closed.";
-IDBDatabase::IDBDatabase(ExecutionContext* context,
- std::unique_ptr<WebIDBDatabase> backend,
- IDBDatabaseCallbacks* callbacks,
- v8::Isolate* isolate)
- : ContextLifecycleObserver(context),
+IDBDatabase::IDBDatabase(
+ ExecutionContext* context,
+ std::unique_ptr<WebIDBDatabase> backend,
+ IDBDatabaseCallbacks* callbacks,
+ v8::Isolate* isolate,
+ mojo::PendingRemote<mojom::blink::ObservedFeature> connection_lifetime)
+ : ExecutionContextLifecycleObserver(context),
backend_(std::move(backend)),
+ connection_lifetime_(std::move(connection_lifetime)),
event_queue_(
MakeGarbageCollected<EventQueue>(context, TaskType::kDatabaseAccess)),
database_callbacks_(callbacks),
@@ -117,14 +121,14 @@ IDBDatabase::~IDBDatabase() {
backend_->Close();
}
-void IDBDatabase::Trace(blink::Visitor* visitor) {
+void IDBDatabase::Trace(Visitor* visitor) {
visitor->Trace(version_change_transaction_);
visitor->Trace(transactions_);
visitor->Trace(observers_);
visitor->Trace(event_queue_);
visitor->Trace(database_callbacks_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
int64_t IDBDatabase::NextTransactionId() {
@@ -463,6 +467,7 @@ void IDBDatabase::close() {
if (close_pending_)
return;
+ connection_lifetime_.reset();
close_pending_ = true;
feature_handle_for_scheduler_.reset();
@@ -521,11 +526,18 @@ void IDBDatabase::EnqueueEvent(Event* event) {
DispatchEventResult IDBDatabase::DispatchEventInternal(Event& event) {
IDB_TRACE("IDBDatabase::dispatchEvent");
- if (!GetExecutionContext())
- return DispatchEventResult::kCanceledBeforeDispatch;
+
+ event.SetTarget(this);
+
+ // If this event originated from script, it should have no side effects.
+ if (!event.isTrusted())
+ return EventTarget::DispatchEventInternal(event);
DCHECK(event.type() == event_type_names::kVersionchange ||
event.type() == event_type_names::kClose);
+ if (!GetExecutionContext())
+ return DispatchEventResult::kCanceledBeforeDispatch;
+
DispatchEventResult dispatch_result =
EventTarget::DispatchEventInternal(event);
if (event.type() == event_type_names::kVersionchange && !close_pending_ &&
@@ -593,7 +605,7 @@ bool IDBDatabase::HasPendingActivity() const {
return !close_pending_ && GetExecutionContext() && HasEventListeners();
}
-void IDBDatabase::ContextDestroyed(ExecutionContext*) {
+void IDBDatabase::ContextDestroyed() {
// Immediately close the connection to the back end. Don't attempt a
// normal close() since that may wait on transactions which require a
// round trip to the back-end to abort.
@@ -602,6 +614,8 @@ void IDBDatabase::ContextDestroyed(ExecutionContext*) {
backend_.reset();
}
+ connection_lifetime_.reset();
+
if (database_callbacks_)
database_callbacks_->DetachWebCallbacks();
}
@@ -611,7 +625,7 @@ const AtomicString& IDBDatabase::InterfaceName() const {
}
ExecutionContext* IDBDatabase::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
STATIC_ASSERT_ENUM(mojom::blink::IDBException::kNoError,
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 74452627150..6eef002a162 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.h
@@ -29,18 +29,19 @@
#include <memory>
#include "base/memory/scoped_refptr.h"
+#include "third_party/blink/public/mojom/feature_observer/feature_observer.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_string_sequence.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_idb_object_store_parameters.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_idb_transaction_options.h"
#include "third_party/blink/renderer/core/dom/dom_string_list.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_metadata.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_object_store.h"
-#include "third_party/blink/renderer/modules/indexeddb/idb_object_store_parameters.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_transaction.h"
-#include "third_party/blink/renderer/modules/indexeddb/idb_transaction_options.h"
#include "third_party/blink/renderer/modules/indexeddb/indexed_db.h"
#include "third_party/blink/renderer/modules/indexeddb/web_idb_database.h"
#include "third_party/blink/renderer/modules/indexeddb/web_idb_database_callbacks.h"
@@ -60,18 +61,20 @@ class IDBObserver;
class MODULES_EXPORT IDBDatabase final
: public EventTargetWithInlineData,
public ActiveScriptWrappable<IDBDatabase>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(IDBDatabase);
DEFINE_WRAPPERTYPEINFO();
public:
- IDBDatabase(ExecutionContext*,
- std::unique_ptr<WebIDBDatabase>,
- IDBDatabaseCallbacks*,
- v8::Isolate*);
+ IDBDatabase(
+ ExecutionContext*,
+ std::unique_ptr<WebIDBDatabase>,
+ IDBDatabaseCallbacks*,
+ v8::Isolate*,
+ mojo::PendingRemote<mojom::blink::ObservedFeature> connection_lifetime);
~IDBDatabase() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// Overwrites the database metadata, including object store and index
// metadata. Used to pass metadata to the database when it is opened.
@@ -130,8 +133,8 @@ class MODULES_EXPORT IDBDatabase final
// ScriptWrappable
bool HasPendingActivity() const final;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
// EventTarget
const AtomicString& InterfaceName() const override;
@@ -192,6 +195,9 @@ class MODULES_EXPORT IDBDatabase final
Member<IDBTransaction> version_change_transaction_;
HeapHashMap<int64_t, Member<IDBTransaction>> transactions_;
HeapHashMap<int32_t, Member<IDBObserver>> observers_;
+ // No interface here, so no need to bind it. This is only for
+ // lifetime observation of the use of IndexedDB from the browser.
+ mojo::PendingRemote<mojom::blink::ObservedFeature> connection_lifetime_;
bool close_pending_ = false;
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.idl b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.idl
index 938b6b4fae9..2b5273199f9 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.idl
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.idl
@@ -24,7 +24,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// https://w3c.github.io/IndexedDB/#idl-def-IDBDatabase
+// https://w3c.github.io/IndexedDB/#database-interface
[
ActiveScriptWrappable,
@@ -45,7 +45,7 @@
[MeasureAs=IndexedDBWrite, NewObject, RaisesException]
IDBObjectStore createObjectStore(DOMString name,
- optional IDBObjectStoreParameters options);
+ optional IDBObjectStoreParameters options = {});
[MeasureAs=IndexedDBWrite, RaisesException]
void deleteObjectStore(DOMString name);
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 cf324f4fac5..14e8037e5a2 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(blink::Visitor* visitor) {
+void IDBDatabaseCallbacks::Trace(Visitor* visitor) {
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 7591e448bf9..76c09201024 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(blink::Visitor*);
+ void Trace(Visitor*);
// IDBDatabaseCallbacks
virtual void OnForcedClose();
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.cc
index c7b06b4c851..46c5b343293 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.cc
@@ -33,15 +33,15 @@
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
+#include "third_party/blink/public/mojom/feature_observer/feature_observer.mojom-blink.h"
#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h"
-#include "third_party/blink/public/platform/interface_provider.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_content_settings_client.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_idb_database_info.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"
@@ -51,7 +51,6 @@
#include "third_party/blink/renderer/modules/indexed_db_names.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_database.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.h"
-#include "third_party/blink/renderer/modules/indexeddb/idb_database_info.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_key.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_name_and_version.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_tracing.h"
@@ -205,8 +204,8 @@ IDBFactory::IDBFactory(std::unique_ptr<WebIDBFactory> web_idb_factory)
: web_idb_factory_(std::move(web_idb_factory)) {}
static bool IsContextValid(ExecutionContext* context) {
- DCHECK(IsA<Document>(context) || context->IsWorkerGlobalScope());
- if (auto* document = DynamicTo<Document>(context))
+ DCHECK(context->IsDocument() || context->IsWorkerGlobalScope());
+ if (auto* document = Document::DynamicFrom(context))
return document->GetFrame() && document->GetPage();
return true;
}
@@ -216,8 +215,13 @@ WebIDBFactory* IDBFactory::GetFactory(ExecutionContext* execution_context) {
mojo::PendingRemote<mojom::blink::IDBFactory> web_idb_factory_host_remote;
execution_context->GetBrowserInterfaceBroker().GetInterface(
web_idb_factory_host_remote.InitWithNewPipeAndPassReceiver());
+
+ mojo::PendingRemote<mojom::blink::FeatureObserver> feature_observer;
+ execution_context->GetBrowserInterfaceBroker().GetInterface(
+ feature_observer.InitWithNewPipeAndPassReceiver());
+
web_idb_factory_ = std::make_unique<WebIDBFactoryImpl>(
- std::move(web_idb_factory_host_remote),
+ std::move(web_idb_factory_host_remote), std::move(feature_observer),
execution_context->GetTaskRunner(TaskType::kDatabaseAccess));
}
return web_idb_factory_.get();
@@ -340,6 +344,13 @@ IDBOpenDBRequest* IDBFactory::OpenInternal(ScriptState* script_state,
auto* database_callbacks = MakeGarbageCollected<IDBDatabaseCallbacks>();
int64_t transaction_id = IDBDatabase::NextTransactionId();
+ ExecutionContext* execution_context = ExecutionContext::From(script_state);
+ WebIDBFactory* factory = GetFactory(execution_context);
+ if (!factory) {
+ exception_state.ThrowSecurityError("An internal error occurred.");
+ return nullptr;
+ }
+
auto transaction_backend = std::make_unique<WebIDBTransactionImpl>(
ExecutionContext::From(script_state)
->GetTaskRunner(TaskType::kDatabaseAccess),
@@ -348,7 +359,8 @@ IDBOpenDBRequest* IDBFactory::OpenInternal(ScriptState* script_state,
transaction_receiver = transaction_backend->CreateReceiver();
auto* request = MakeGarbageCollected<IDBOpenDBRequest>(
script_state, database_callbacks, std::move(transaction_backend),
- transaction_id, version, std::move(metrics));
+ transaction_id, version, std::move(metrics),
+ factory->GetObservedFeature());
if (!CachedAllowIndexedDB(script_state)) {
request->HandleResponse(MakeGarbageCollected<DOMException>(
@@ -356,12 +368,6 @@ IDBOpenDBRequest* IDBFactory::OpenInternal(ScriptState* script_state,
return request;
}
- ExecutionContext* execution_context = ExecutionContext::From(script_state);
- WebIDBFactory* factory = GetFactory(execution_context);
- if (!factory) {
- exception_state.ThrowSecurityError("An internal error occurred.");
- return nullptr;
- }
factory->Open(name, version, std::move(transaction_receiver), transaction_id,
request->CreateWebCallbacks(),
database_callbacks->CreateWebCallbacks());
@@ -413,9 +419,17 @@ IDBOpenDBRequest* IDBFactory::DeleteDatabaseInternal(
WebFeature::kFileAccessedDatabase);
}
+ ExecutionContext* execution_context = ExecutionContext::From(script_state);
+ WebIDBFactory* factory = GetFactory(execution_context);
+ if (!factory) {
+ exception_state.ThrowSecurityError("An internal error occurred.");
+ return nullptr;
+ }
+
auto* request = MakeGarbageCollected<IDBOpenDBRequest>(
script_state, nullptr, /*IDBTransactionAssociatedPtr=*/nullptr, 0,
- IDBDatabaseMetadata::kDefaultVersion, std::move(metrics));
+ IDBDatabaseMetadata::kDefaultVersion, std::move(metrics),
+ factory->GetObservedFeature());
if (!CachedAllowIndexedDB(script_state)) {
request->HandleResponse(MakeGarbageCollected<DOMException>(
@@ -423,12 +437,6 @@ IDBOpenDBRequest* IDBFactory::DeleteDatabaseInternal(
return request;
}
- ExecutionContext* execution_context = ExecutionContext::From(script_state);
- WebIDBFactory* factory = GetFactory(execution_context);
- if (!factory) {
- exception_state.ThrowSecurityError("An internal error occurred.");
- return nullptr;
- }
factory->DeleteDatabase(name, request->CreateWebCallbacks(), force_close);
return request;
}
@@ -469,7 +477,7 @@ bool IDBFactory::AllowIndexedDB(ScriptState* script_state) {
DCHECK(execution_context->IsContextThread());
SECURITY_DCHECK(execution_context->IsDocument() ||
execution_context->IsWorkerGlobalScope());
- if (auto* document = DynamicTo<Document>(execution_context)) {
+ if (auto* document = Document::DynamicFrom(execution_context)) {
LocalFrame* frame = document->GetFrame();
if (!frame)
return false;
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 dce0cab4d1e..a17ecbae88c 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(blink::Visitor* visitor) {
+void IDBIndex::Trace(Visitor* visitor) {
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 0d628fc767c..8bb99e9366f 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// Implement the IDL
const String& name() const { return Metadata().name; }
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.idl b/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.idl
index ebd480e4003..e644cdb658d 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.idl
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.idl
@@ -36,14 +36,14 @@
[NewObject, CallWith=ScriptState, RaisesException] IDBRequest get(any key);
[NewObject, CallWith=ScriptState, RaisesException] IDBRequest getKey(any key);
- [NewObject, CallWith=ScriptState, RaisesException] IDBRequest getAll([DefaultValue=Undefined] optional any query,
+ [NewObject, CallWith=ScriptState, RaisesException] IDBRequest getAll(optional any query = null,
optional [EnforceRange] unsigned long count);
- [NewObject, CallWith=ScriptState, RaisesException] IDBRequest getAllKeys([DefaultValue=Undefined] optional any query,
+ [NewObject, CallWith=ScriptState, RaisesException] IDBRequest getAllKeys(optional any query = null,
optional [EnforceRange] unsigned long count);
- [NewObject, CallWith=ScriptState, RaisesException] IDBRequest count([DefaultValue=Undefined] optional any key);
+ [NewObject, CallWith=ScriptState, RaisesException] IDBRequest count(optional any key = null);
- [NewObject, CallWith=ScriptState, RaisesException] IDBRequest openCursor([DefaultValue=Undefined] optional any range,
+ [NewObject, CallWith=ScriptState, RaisesException] IDBRequest openCursor(optional any range = null,
optional IDBCursorDirection direction = "next");
- [NewObject, CallWith=ScriptState, RaisesException] IDBRequest openKeyCursor([DefaultValue=Undefined] optional any range,
+ [NewObject, CallWith=ScriptState, RaisesException] IDBRequest openKeyCursor(optional any range = null,
optional IDBCursorDirection direction = "next");
};
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 80fb9535737..55311ab0e86 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,9 +76,7 @@ class MODULES_EXPORT IDBKeyRange final : public ScriptWrappable {
const ScriptValue&,
ExceptionState&);
- void Trace(blink::Visitor* visitor) override {
- ScriptWrappable::Trace(visitor);
- }
+ void Trace(Visitor* visitor) 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 460ba8896ce..471ac159cef 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
@@ -28,7 +28,9 @@
#include <memory>
#include "base/feature_list.h"
+#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
+#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
#include "third_party/blink/public/platform/web_blob_info.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_factory.h"
@@ -48,7 +50,6 @@
#include "third_party/blink/renderer/modules/indexeddb/web_idb_database.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/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
#include "v8/include/v8.h"
@@ -61,7 +62,7 @@ IDBObjectStore::IDBObjectStore(scoped_refptr<IDBObjectStoreMetadata> metadata,
DCHECK(metadata_.get());
}
-void IDBObjectStore::Trace(blink::Visitor* visitor) {
+void IDBObjectStore::Trace(Visitor* visitor) {
visitor->Trace(transaction_);
visitor->Trace(index_map_);
ScriptWrappable::Trace(visitor);
@@ -339,6 +340,14 @@ static Vector<std::unique_ptr<IDBKey>> GenerateIndexKeysForValue(
IDBRequest* IDBObjectStore::add(ScriptState* script_state,
const ScriptValue& value,
+ ExceptionState& exception_state) {
+ v8::Isolate* isolate = script_state->GetIsolate();
+ return add(script_state, value, ScriptValue(isolate, v8::Undefined(isolate)),
+ exception_state);
+}
+
+IDBRequest* IDBObjectStore::add(ScriptState* script_state,
+ const ScriptValue& value,
const ScriptValue& key,
ExceptionState& exception_state) {
IDB_TRACE1("IDBObjectStore::addRequestSetup", "store_name",
@@ -349,6 +358,14 @@ IDBRequest* IDBObjectStore::add(ScriptState* script_state,
IDBRequest* IDBObjectStore::put(ScriptState* script_state,
const ScriptValue& value,
+ ExceptionState& exception_state) {
+ v8::Isolate* isolate = script_state->GetIsolate();
+ return put(script_state, value, ScriptValue(isolate, v8::Undefined(isolate)),
+ exception_state);
+}
+
+IDBRequest* IDBObjectStore::put(ScriptState* script_state,
+ const ScriptValue& value,
const ScriptValue& key,
ExceptionState& exception_state) {
IDB_TRACE1("IDBObjectStore::putRequestSetup", "store_name",
@@ -571,8 +588,9 @@ IDBRequest* IDBObjectStore::DoPut(ScriptState* script_state,
if (base::FeatureList::IsEnabled(kIndexedDBLargeValueWrapping))
value_wrapper.WrapIfBiggerThan(IDBValueWrapper::kWrapThreshold);
- auto idb_value = std::make_unique<IDBValue>(value_wrapper.TakeWireBytes(),
- value_wrapper.TakeBlobInfo());
+ auto idb_value = std::make_unique<IDBValue>(
+ value_wrapper.TakeWireBytes(), value_wrapper.TakeBlobInfo(),
+ value_wrapper.TakeNativeFileSystemTransferTokens());
request->transit_blob_handles() = value_wrapper.TakeBlobDataHandles();
transaction_->transaction_backend()->Put(
@@ -708,7 +726,7 @@ class IndexPopulator final : public NativeEventListener {
DCHECK(index_metadata_.get());
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 c742dbdf8be..79819338c46 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
@@ -29,9 +29,9 @@
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_idb_index_parameters.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_cursor.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_index.h"
-#include "third_party/blink/renderer/modules/indexeddb/idb_index_parameters.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_key.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_key_range.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_metadata.h"
@@ -54,7 +54,7 @@ class MODULES_EXPORT IDBObjectStore final : public ScriptWrappable {
IDBObjectStore(scoped_refptr<IDBObjectStoreMetadata>, IDBTransaction*);
~IDBObjectStore() override = default;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
const IDBObjectStoreMetadata& Metadata() const { return *metadata_; }
const IDBKeyPath& IdbKeyPath() const { return Metadata().key_path; }
@@ -96,12 +96,14 @@ class MODULES_EXPORT IDBObjectStore final : public ScriptWrappable {
IDBRequest* getAllKeys(ScriptState*,
const ScriptValue& range,
ExceptionState&);
+ IDBRequest* add(ScriptState*, const ScriptValue& value, ExceptionState&);
IDBRequest* add(ScriptState*,
- const ScriptValue&,
+ const ScriptValue& value,
const ScriptValue& key,
ExceptionState&);
+ IDBRequest* put(ScriptState*, const ScriptValue& value, ExceptionState&);
IDBRequest* put(ScriptState*,
- const ScriptValue&,
+ const ScriptValue& value,
const ScriptValue& key,
ExceptionState&);
IDBRequest* Delete(ScriptState*, const ScriptValue& key, ExceptionState&);
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.idl b/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.idl
index 3218ac74f71..c8b9a30009c 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.idl
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.idl
@@ -23,7 +23,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// https://w3c.github.io/IndexedDB/#idl-def-IDBObjectStore
+// https://w3c.github.io/IndexedDB/#object-store-interface
[
Exposed=(Window,Worker)
@@ -35,10 +35,10 @@
readonly attribute boolean autoIncrement;
[CallWith=ScriptState, MeasureAs=IndexedDBWrite, NewObject, RaisesException]
- IDBRequest put(any value, [DefaultValue=Undefined] optional any key);
+ IDBRequest put(any value, optional any key);
[CallWith=ScriptState, MeasureAs=IndexedDBWrite, NewObject, RaisesException]
- IDBRequest add(any value, [DefaultValue=Undefined] optional any key);
+ IDBRequest add(any value, optional any key);
[
CallWith=ScriptState,
@@ -58,22 +58,22 @@
IDBRequest getKey(any key);
[CallWith=ScriptState, MeasureAs=IndexedDBRead, NewObject, RaisesException]
- IDBRequest getAll([DefaultValue=Undefined] optional any query,
+ IDBRequest getAll(optional any query = null,
optional [EnforceRange] unsigned long count);
[CallWith=ScriptState, MeasureAs=IndexedDBRead, NewObject, RaisesException]
- IDBRequest getAllKeys([DefaultValue=Undefined] optional any query,
+ IDBRequest getAllKeys(optional any query = null,
optional [EnforceRange] unsigned long count);
[CallWith=ScriptState, MeasureAs=IndexedDBRead, NewObject, RaisesException]
- IDBRequest count([DefaultValue=Undefined] optional any key);
+ IDBRequest count(optional any key = null);
[CallWith=ScriptState, MeasureAs=IndexedDBRead, NewObject, RaisesException]
- IDBRequest openCursor([DefaultValue=Undefined] optional any range,
+ IDBRequest openCursor(optional any range = null,
optional IDBCursorDirection direction = "next");
[CallWith=ScriptState, MeasureAs=IndexedDBRead, NewObject, RaisesException]
- IDBRequest openKeyCursor([DefaultValue=Undefined] optional any range,
+ IDBRequest openKeyCursor(optional any range = null,
optional IDBCursorDirection direction = "next");
[MeasureAs=IndexedDBRead, RaisesException] IDBIndex index(DOMString name);
@@ -81,7 +81,7 @@
[CallWith=ScriptState, MeasureAs=IndexedDBWrite, NewObject, RaisesException]
IDBIndex createIndex(DOMString name,
(DOMString or sequence<DOMString>) keyPath,
- optional IDBIndexParameters options);
+ optional IDBIndexParameters options = {});
[MeasureAs=IndexedDBWrite, RaisesException]
void deleteIndex(DOMString name);
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 4b05d8b8e3b..923dc0f01c8 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(blink::Visitor* visitor) {
+void IDBObservation::Trace(Visitor* visitor) {
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 bc668d0ea16..11d3d59a04b 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 fb4c0617684..b4caa0796f3 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.cc
@@ -9,10 +9,10 @@
#include "third_party/blink/renderer/bindings/modules/v8/to_v8_for_modules.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_idb_observer_callback.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_idb_observer_init.h"
#include "third_party/blink/renderer/modules/indexed_db_names.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_database.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_observer_changes.h"
-#include "third_party/blink/renderer/modules/indexeddb/idb_observer_init.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_transaction.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -98,7 +98,7 @@ void IDBObserver::unobserve(IDBDatabase* database,
database->RemoveObservers(observer_ids_to_remove);
}
-void IDBObserver::Trace(blink::Visitor* visitor) {
+void IDBObserver::Trace(Visitor* visitor) {
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 84133685682..6ac5fa3d26c 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<V8IDBObserverCallback> callback_;
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.idl b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.idl
index 258c4904246..a56142de3f6 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.idl
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.idl
@@ -8,9 +8,9 @@ callback IDBObserverCallback = void (IDBObserverChanges changes);
[
Exposed=(Window,Worker),
- Constructor(IDBObserverCallback callback),
RuntimeEnabled=IDBObserver
] interface IDBObserver {
+ constructor(IDBObserverCallback callback);
[RaisesException, Measure] void observe(IDBDatabase db, IDBTransaction tx, IDBObserverInit options);
[RaisesException, Measure] void unobserve(IDBDatabase db);
};
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 f8b1e48c15d..28c5ffe1c79 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(blink::Visitor* visitor) {
+void IDBObserverChanges::Trace(Visitor* visitor) {
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 874589dd8ff..d4c6ecd12fb 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 8c3850c312d..8bae0d1d458 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
@@ -28,6 +28,7 @@
#include <memory>
#include <utility>
+#include "base/metrics/histogram_macros.h"
#include "base/optional.h"
#include "third_party/blink/renderer/bindings/modules/v8/idb_object_store_or_idb_index_or_idb_cursor.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
@@ -37,7 +38,6 @@
#include "third_party/blink/renderer/modules/indexeddb/idb_tracing.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_version_change_event.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
namespace blink {
@@ -47,7 +47,8 @@ IDBOpenDBRequest::IDBOpenDBRequest(
std::unique_ptr<WebIDBTransaction> transaction_backend,
int64_t transaction_id,
int64_t version,
- IDBRequest::AsyncTraceState metrics)
+ IDBRequest::AsyncTraceState metrics,
+ mojo::PendingRemote<mojom::blink::ObservedFeature> connection_lifetime)
: IDBRequest(script_state,
IDBRequest::Source(),
nullptr,
@@ -56,19 +57,20 @@ IDBOpenDBRequest::IDBOpenDBRequest(
transaction_backend_(std::move(transaction_backend)),
transaction_id_(transaction_id),
version_(version),
+ connection_lifetime_(std::move(connection_lifetime)),
start_time_(base::Time::Now()) {
DCHECK(!ResultAsAny());
}
IDBOpenDBRequest::~IDBOpenDBRequest() = default;
-void IDBOpenDBRequest::Trace(blink::Visitor* visitor) {
+void IDBOpenDBRequest::Trace(Visitor* visitor) {
visitor->Trace(database_callbacks_);
IDBRequest::Trace(visitor);
}
-void IDBOpenDBRequest::ContextDestroyed(ExecutionContext* destroyed_context) {
- IDBRequest::ContextDestroyed(destroyed_context);
+void IDBOpenDBRequest::ContextDestroyed() {
+ IDBRequest::ContextDestroyed();
if (database_callbacks_)
database_callbacks_->DetachWebCallbacks();
}
@@ -105,7 +107,7 @@ void IDBOpenDBRequest::EnqueueUpgradeNeeded(
auto* idb_database = MakeGarbageCollected<IDBDatabase>(
GetExecutionContext(), std::move(backend), database_callbacks_.Release(),
- isolate_);
+ isolate_, std::move(connection_lifetime_));
idb_database->SetMetadata(metadata);
if (old_version == IDBDatabaseMetadata::kNoVersion) {
@@ -148,7 +150,8 @@ void IDBOpenDBRequest::EnqueueResponse(std::unique_ptr<WebIDBDatabase> backend,
DCHECK(database_callbacks_);
idb_database = MakeGarbageCollected<IDBDatabase>(
GetExecutionContext(), std::move(backend),
- database_callbacks_.Release(), isolate_);
+ database_callbacks_.Release(), isolate_,
+ std::move(connection_lifetime_));
SetResult(MakeGarbageCollected<IDBAny>(idb_database));
}
idb_database->SetMetadata(metadata);
@@ -165,7 +168,7 @@ void IDBOpenDBRequest::EnqueueResponse(int64_t old_version) {
// This database hasn't had an integer version before.
old_version = IDBDatabaseMetadata::kDefaultVersion;
}
- SetResult(IDBAny::CreateUndefined());
+ SetResult(MakeGarbageCollected<IDBAny>(IDBAny::kUndefinedType));
EnqueueEvent(MakeGarbageCollected<IDBVersionChangeEvent>(
event_type_names::kSuccess, old_version, base::nullopt));
}
@@ -180,6 +183,15 @@ bool IDBOpenDBRequest::ShouldEnqueueEvent() const {
}
DispatchEventResult IDBOpenDBRequest::DispatchEventInternal(Event& event) {
+ // If this event originated from script, it should have no side effects.
+ if (!event.isTrusted())
+ return IDBRequest::DispatchEventInternal(event);
+ DCHECK(event.type() == event_type_names::kSuccess ||
+ event.type() == event_type_names::kError ||
+ event.type() == event_type_names::kBlocked ||
+ event.type() == event_type_names::kUpgradeneeded)
+ << "event type was " << event.type();
+
// If the connection closed between onUpgradeNeeded and the delivery of the
// "success" event, an "error" event should be fired instead.
if (event.type() == event_type_names::kSuccess &&
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 5266f1dc833..45282c00a41 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
@@ -28,6 +28,7 @@
#include <memory>
+#include "third_party/blink/public/mojom/feature_observer/feature_observer.mojom-blink.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_request.h"
#include "third_party/blink/renderer/modules/indexeddb/web_idb_database.h"
#include "third_party/blink/renderer/modules/modules_export.h"
@@ -40,15 +41,17 @@ class MODULES_EXPORT IDBOpenDBRequest final : public IDBRequest {
DEFINE_WRAPPERTYPEINFO();
public:
- IDBOpenDBRequest(ScriptState*,
- IDBDatabaseCallbacks*,
- std::unique_ptr<WebIDBTransaction> transaction_backend,
- int64_t transaction_id,
- int64_t version,
- IDBRequest::AsyncTraceState metrics);
+ IDBOpenDBRequest(
+ ScriptState*,
+ IDBDatabaseCallbacks*,
+ std::unique_ptr<WebIDBTransaction> transaction_backend,
+ int64_t transaction_id,
+ int64_t version,
+ IDBRequest::AsyncTraceState metrics,
+ mojo::PendingRemote<mojom::blink::ObservedFeature> connection_lifetime);
~IDBOpenDBRequest() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void EnqueueBlocked(int64_t existing_version) override;
void EnqueueUpgradeNeeded(int64_t old_version,
@@ -59,8 +62,8 @@ class MODULES_EXPORT IDBOpenDBRequest final : public IDBRequest {
void EnqueueResponse(std::unique_ptr<WebIDBDatabase>,
const IDBDatabaseMetadata&) override;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) final;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() final;
// EventTarget
const AtomicString& InterfaceName() const override;
@@ -82,6 +85,9 @@ class MODULES_EXPORT IDBOpenDBRequest final : public IDBRequest {
const int64_t transaction_id_;
int64_t version_;
+ // Passed to the IDBDatabase when created.
+ mojo::PendingRemote<mojom::blink::ObservedFeature> connection_lifetime_;
+
base::Time start_time_;
bool open_time_recorded_ = false;
};
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 a0f2288d1e1..96b9daef25a 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.cc
@@ -62,21 +62,25 @@ IDBRequest::AsyncTraceState::AsyncTraceState(const char* trace_event_name)
// If PopulateForNewEvent is called, it sets trace_event_name_ to
// trace_event_name. Otherwise, trace_event_name_ is nullptr, so this instance
// is considered empty. This roundabout initialization lets us avoid calling
- // TRACE_EVENT_ASYNC_END0 with an uninitalized ID.
- TRACE_EVENT_ASYNC_BEGIN0("IndexedDB", trace_event_name,
- PopulateForNewEvent(trace_event_name));
+ // TRACE_EVENT_NESTABLE_ASYNC_END0 with an uninitalized ID.
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(
+ "IndexedDB", trace_event_name,
+ TRACE_ID_LOCAL(PopulateForNewEvent(trace_event_name)));
}
void IDBRequest::AsyncTraceState::RecordAndReset() {
if (trace_event_name_) {
- TRACE_EVENT_ASYNC_END0("IndexedDB", trace_event_name_, id_);
+ TRACE_EVENT_NESTABLE_ASYNC_END0("IndexedDB", trace_event_name_,
+ TRACE_ID_LOCAL(id_));
trace_event_name_ = nullptr;
}
}
IDBRequest::AsyncTraceState::~AsyncTraceState() {
- if (trace_event_name_)
- TRACE_EVENT_ASYNC_END0("IndexedDB", trace_event_name_, id_);
+ if (trace_event_name_) {
+ TRACE_EVENT_NESTABLE_ASYNC_END0("IndexedDB", trace_event_name_,
+ TRACE_ID_LOCAL(id_));
+ }
}
size_t IDBRequest::AsyncTraceState::PopulateForNewEvent(
@@ -131,7 +135,7 @@ IDBRequest::IDBRequest(ScriptState* script_state,
const Source& source,
IDBTransaction* transaction,
AsyncTraceState metrics)
- : ContextLifecycleObserver(ExecutionContext::From(script_state)),
+ : ExecutionContextLifecycleObserver(ExecutionContext::From(script_state)),
transaction_(transaction),
isolate_(script_state->GetIsolate()),
metrics_(std::move(metrics)),
@@ -145,7 +149,7 @@ IDBRequest::~IDBRequest() {
ready_state_ == kEarlyDeath || !GetExecutionContext());
}
-void IDBRequest::Trace(blink::Visitor* visitor) {
+void IDBRequest::Trace(Visitor* visitor) {
visitor->Trace(transaction_);
visitor->Trace(source_);
visitor->Trace(result_);
@@ -153,7 +157,7 @@ void IDBRequest::Trace(blink::Visitor* visitor) {
visitor->Trace(event_queue_);
visitor->Trace(pending_cursor_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
ScriptValue IDBRequest::result(ScriptState* script_state,
@@ -413,7 +417,7 @@ void IDBRequest::EnqueueResponse(DOMException* error) {
}
error_ = error;
- SetResult(IDBAny::CreateUndefined());
+ SetResult(MakeGarbageCollected<IDBAny>(IDBAny::kUndefinedType));
pending_cursor_.Clear();
EnqueueEvent(Event::CreateCancelableBubble(event_type_names::kError));
}
@@ -482,7 +486,7 @@ void IDBRequest::EnqueueResponse(std::unique_ptr<IDBKey> idb_key) {
if (idb_key && idb_key->IsValid())
EnqueueResultInternal(MakeGarbageCollected<IDBAny>(std::move(idb_key)));
else
- EnqueueResultInternal(IDBAny::CreateUndefined());
+ EnqueueResultInternal(MakeGarbageCollected<IDBAny>(IDBAny::kUndefinedType));
}
namespace {
@@ -556,7 +560,7 @@ void IDBRequest::EnqueueResponse() {
metrics_.RecordAndReset();
return;
}
- EnqueueResultInternal(IDBAny::CreateUndefined());
+ EnqueueResultInternal(MakeGarbageCollected<IDBAny>(IDBAny::kUndefinedType));
}
void IDBRequest::EnqueueResultInternal(IDBAny* result) {
@@ -594,7 +598,7 @@ bool IDBRequest::HasPendingActivity() const {
return has_pending_activity_ && GetExecutionContext();
}
-void IDBRequest::ContextDestroyed(ExecutionContext*) {
+void IDBRequest::ContextDestroyed() {
if (ready_state_ == PENDING) {
ready_state_ = kEarlyDeath;
if (queue_item_)
@@ -620,31 +624,43 @@ const AtomicString& IDBRequest::InterfaceName() const {
}
ExecutionContext* IDBRequest::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
DispatchEventResult IDBRequest::DispatchEventInternal(Event& event) {
IDB_TRACE("IDBRequest::dispatchEvent");
- if (!GetExecutionContext())
- return DispatchEventResult::kCanceledBeforeDispatch;
- DCHECK_EQ(ready_state_, PENDING);
- DCHECK(has_pending_activity_);
- DCHECK_EQ(event.target(), this);
- if (event.type() != event_type_names::kBlocked)
- ready_state_ = DONE;
+ event.SetTarget(this);
HeapVector<Member<EventTarget>> targets;
targets.push_back(this);
if (transaction_ && !prevent_propagation_) {
+ // Per spec: "A request's get the parent algorithm returns the request’s
+ // transaction."
targets.push_back(transaction_);
- // If there ever are events that are associated with a database but
- // that do not have a transaction, then this will not work and we need
- // this object to actually hold a reference to the database (to ensure
- // it stays alive).
+ // Per spec: "A transaction's get the parent algorithm returns the
+ // transaction’s connection."
targets.push_back(transaction_->db());
}
+ // If this event originated from script, it should have no side effects.
+ if (!event.isTrusted())
+ return IDBEventDispatcher::Dispatch(event, targets);
+ DCHECK(event.type() == event_type_names::kSuccess ||
+ event.type() == event_type_names::kError ||
+ event.type() == event_type_names::kBlocked ||
+ event.type() == event_type_names::kUpgradeneeded)
+ << "event type was " << event.type();
+
+ if (!GetExecutionContext())
+ return DispatchEventResult::kCanceledBeforeDispatch;
+ DCHECK_EQ(ready_state_, PENDING);
+ DCHECK(has_pending_activity_);
+ DCHECK_EQ(event.target(), this);
+
+ if (event.type() != event_type_names::kBlocked)
+ ready_state_ = DONE;
+
// Cursor properties should not be updated until the success event is being
// dispatched.
IDBCursor* cursor_to_notify = nullptr;
@@ -662,13 +678,6 @@ DispatchEventResult IDBRequest::DispatchEventInternal(Event& event) {
did_fire_upgrade_needed_event_ = true;
}
- // FIXME: When we allow custom event dispatching, this will probably need to
- // change.
- DCHECK(event.type() == event_type_names::kSuccess ||
- event.type() == event_type_names::kError ||
- event.type() == event_type_names::kBlocked ||
- event.type() == event_type_names::kUpgradeneeded)
- << "event type was " << event.type();
const bool set_transaction_active =
transaction_ &&
(event.type() == event_type_names::kSuccess ||
@@ -692,7 +701,6 @@ DispatchEventResult IDBRequest::DispatchEventInternal(Event& event) {
// has completed.
metrics_.RecordAndReset();
- event.SetTarget(this);
DispatchEventResult dispatch_result =
IDBEventDispatcher::Dispatch(event, targets);
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 48a337ead33..ed3bf8e446c 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.h
@@ -44,7 +44,7 @@
#include "third_party/blink/renderer/core/dom/events/event_listener.h"
#include "third_party/blink/renderer/core/dom/events/event_queue.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_any.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_transaction.h"
@@ -66,7 +66,7 @@ class IDBValue;
class MODULES_EXPORT IDBRequest : public EventTargetWithInlineData,
public ActiveScriptWrappable<IDBRequest>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(IDBRequest);
@@ -74,20 +74,21 @@ class MODULES_EXPORT IDBRequest : public EventTargetWithInlineData,
using Source = IDBObjectStoreOrIDBIndexOrIDBCursor;
// Container for async tracing state.
//
- // The documentation for TRACE_EVENT_ASYNC_{BEGIN,END} suggests identifying
- // trace events by using pointers or a counter that is always incremented on
- // the same thread. This is not viable for IndexedDB, because the same object
- // can result in multiple trace events (requests associated with cursors), and
- // IndexedDB can be used from multiple threads in the same renderer (workers).
- // Furthermore, we want to record the beginning event of an async trace right
- // when we start serving an IDB API call, before the IDBRequest object is
- // created, so we can't rely on information in an IDBRequest.
+ // The documentation for TRACE_EVENT_NESTABLE_ASYNC_{BEGIN,END} suggests
+ // identifying trace events by using pointers or a counter that is always
+ // incremented on the same thread. This is not viable for IndexedDB, because
+ // the same object can result in multiple trace events (requests associated
+ // with cursors), and IndexedDB can be used from multiple threads in the same
+ // renderer (workers). Furthermore, we want to record the beginning event of
+ // an async trace right when we start serving an IDB API call, before the
+ // IDBRequest object is created, so we can't rely on information in an
+ // IDBRequest.
//
// This class solves the ID uniqueness problem by relying on an atomic counter
// to generating unique IDs in a threadsafe manner. The atomic machinery is
// used when tracing is enabled. The recording problem is solved by having
// instances of this class store the information needed to record async trace
- // end events (via TRACE_EVENT_ASYNC_END).
+ // end events (via TRACE_EVENT_NESTABLE_ASYNC_END).
//
// From a mechanical perspective, creating an AsyncTraceState instance records
// the beginning event of an async trace. The instance is then moved into an
@@ -179,7 +180,7 @@ class MODULES_EXPORT IDBRequest : public EventTargetWithInlineData,
IDBRequest(ScriptState*, const Source&, IDBTransaction*, AsyncTraceState);
~IDBRequest() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
v8::Isolate* GetIsolate() const { return isolate_; }
ScriptValue result(ScriptState*, ExceptionState&);
@@ -291,8 +292,8 @@ class MODULES_EXPORT IDBRequest : public EventTargetWithInlineData,
// ScriptWrappable
bool HasPendingActivity() const final;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
// EventTarget
const AtomicString& InterfaceName() const override;
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc
index fced38c2ed5..1eadb10238c 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/modules/indexeddb/idb_request_loader.h"
+#include "base/metrics/histogram_functions.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -13,7 +14,6 @@
#include "third_party/blink/renderer/modules/indexeddb/idb_value.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.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_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
@@ -129,11 +129,8 @@ void IDBRequestLoader::DidFail(FileErrorCode) {
file_reader_loading_ = false;
#endif // DCHECK_IS_ON()
- DEFINE_THREAD_SAFE_STATIC_LOCAL(SparseHistogram,
- idb_request_loader_read_errors_histogram,
- ("Storage.Blob.IDBRequestLoader.ReadError"));
- idb_request_loader_read_errors_histogram.Sample(
- std::max(0, -loader_->GetNetError()));
+ base::UmaHistogramSparse("Storage.Blob.IDBRequestLoader.ReadError",
+ std::max(0, -loader_->GetNetError()));
ReportError();
}
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 f5cfb941f37..e4c632f56cc 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
@@ -192,7 +192,8 @@ class IDBRequestTest : public testing::Test {
std::unique_ptr<MockWebIDBTransaction> transaction_backend) {
db_ = MakeGarbageCollected<IDBDatabase>(
scope.GetExecutionContext(), std::move(database_backend),
- MakeGarbageCollected<IDBDatabaseCallbacks>(), scope.GetIsolate());
+ MakeGarbageCollected<IDBDatabaseCallbacks>(), scope.GetIsolate(),
+ mojo::NullRemote());
HashSet<String> transaction_scope = {"store"};
transaction_ = IDBTransaction::CreateNonVersionChange(
@@ -319,7 +320,17 @@ TEST_F(IDBRequestTest, EventsAfterEarlyDeathStopWithQueuedResult) {
EnsureIDBCallbacksDontThrow(request, scope.GetExceptionState());
}
-TEST_F(IDBRequestTest, EventsAfterEarlyDeathStopWithTwoQueuedResults) {
+// This test is flaky on Marshmallow 64 bit Tester because the test is
+// crashing. See <http://crbug.com/1068057>.
+#if defined(OS_ANDROID)
+#define MAYBE_EventsAfterEarlyDeathStopWithTwoQueuedResults \
+ DISABLED_EventsAfterEarlyDeathStopWithTwoQueuedResults
+#else
+#define MAYBE_EventsAfterEarlyDeathStopWithTwoQueuedResults \
+ EventsAfterEarlyDeathStopWithTwoQueuedResults
+#endif
+
+TEST_F(IDBRequestTest, MAYBE_EventsAfterEarlyDeathStopWithTwoQueuedResults) {
V8TestingScope scope;
const int64_t kTransactionId = 1234;
auto database_backend = std::make_unique<MockWebIDBDatabase>();
@@ -356,7 +367,17 @@ TEST_F(IDBRequestTest, EventsAfterEarlyDeathStopWithTwoQueuedResults) {
EnsureIDBCallbacksDontThrow(request2, scope.GetExceptionState());
}
-TEST_F(IDBRequestTest, AbortErrorAfterAbort) {
+// This test is flaky on Marshmallow 64 bit Tester because the test is
+// crashing. See <http://crbug.com/1068057>.
+#if defined(OS_ANDROID)
+#define MAYBE_AbortErrorAfterAbort \
+ DISABLED_AbortErrorAfterAbort
+#else
+#define MAYBE_AbortErrorAfterAbort \
+ AbortErrorAfterAbort
+#endif
+
+TEST_F(IDBRequestTest, MAYBE_AbortErrorAfterAbort) {
V8TestingScope scope;
IDBTransaction* transaction = nullptr;
IDBRequest* request =
@@ -399,7 +420,8 @@ TEST_F(IDBRequestTest, ConnectionsAfterStopping) {
kTransactionId);
auto* request = MakeGarbageCollected<IDBOpenDBRequest>(
scope.GetScriptState(), callbacks, std::move(transaction_backend),
- kTransactionId, kVersion, IDBRequest::AsyncTraceState());
+ kTransactionId, kVersion, IDBRequest::AsyncTraceState(),
+ mojo::NullRemote());
EXPECT_EQ(request->readyState(), "pending");
std::unique_ptr<WebIDBCallbacks> callbacks = request->CreateWebCallbacks();
@@ -421,7 +443,8 @@ TEST_F(IDBRequestTest, ConnectionsAfterStopping) {
kTransactionId);
auto* request = MakeGarbageCollected<IDBOpenDBRequest>(
scope.GetScriptState(), callbacks, std::move(transaction_backend),
- kTransactionId, kVersion, IDBRequest::AsyncTraceState());
+ kTransactionId, kVersion, IDBRequest::AsyncTraceState(),
+ mojo::NullRemote());
EXPECT_EQ(request->readyState(), "pending");
std::unique_ptr<WebIDBCallbacks> callbacks = request->CreateWebCallbacks();
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 28bf2cc0c2b..8a6c2696438 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc
@@ -82,7 +82,7 @@ IDBTransaction::IDBTransaction(
mojom::IDBTransactionMode mode,
mojom::IDBTransactionDurability durability,
IDBDatabase* db)
- : ContextLifecycleObserver(ExecutionContext::From(script_state)),
+ : ExecutionContextLifecycleObserver(ExecutionContext::From(script_state)),
transaction_backend_(std::move(transaction_backend)),
id_(id),
database_(db),
@@ -120,7 +120,7 @@ IDBTransaction::IDBTransaction(
IDBDatabase* db,
IDBOpenDBRequest* open_db_request,
const IDBDatabaseMetadata& old_metadata)
- : ContextLifecycleObserver(execution_context),
+ : ExecutionContextLifecycleObserver(execution_context),
transaction_backend_(std::move(transaction_backend)),
id_(id),
database_(db),
@@ -140,14 +140,14 @@ IDBTransaction::IDBTransaction(
}
IDBTransaction::~IDBTransaction() {
- // Note: IDBTransaction is a ContextLifecycleObserver (rather than
+ // Note: IDBTransaction is a ExecutionContextLifecycleObserver (rather than
// ContextClient) only in order to be able call upon GetExecutionContext()
// during this destructor.
DCHECK(state_ == kFinished || !GetExecutionContext());
DCHECK(request_list_.IsEmpty() || !GetExecutionContext());
}
-void IDBTransaction::Trace(blink::Visitor* visitor) {
+void IDBTransaction::Trace(Visitor* visitor) {
visitor->Trace(database_);
visitor->Trace(open_db_request_);
visitor->Trace(error_);
@@ -157,7 +157,7 @@ void IDBTransaction::Trace(blink::Visitor* visitor) {
visitor->Trace(deleted_indexes_);
visitor->Trace(event_queue_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
void IDBTransaction::SetError(DOMException* error) {
@@ -543,7 +543,7 @@ const AtomicString& IDBTransaction::InterfaceName() const {
}
ExecutionContext* IDBTransaction::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
const char* IDBTransaction::InactiveErrorMessage() const {
@@ -564,6 +564,21 @@ const char* IDBTransaction::InactiveErrorMessage() const {
DispatchEventResult IDBTransaction::DispatchEventInternal(Event& event) {
IDB_TRACE1("IDBTransaction::dispatchEvent", "txn.id", id_);
+
+ event.SetTarget(this);
+
+ // Per spec: "A transaction's get the parent algorithm returns the
+ // transaction’s connection."
+ HeapVector<Member<EventTarget>> targets;
+ targets.push_back(this);
+ targets.push_back(db());
+
+ // If this event originated from script, it should have no side effects.
+ if (!event.isTrusted())
+ return IDBEventDispatcher::Dispatch(event, targets);
+ DCHECK(event.type() == event_type_names::kComplete ||
+ event.type() == event_type_names::kAbort);
+
if (!GetExecutionContext()) {
state_ = kFinished;
return DispatchEventResult::kCanceledBeforeDispatch;
@@ -574,14 +589,6 @@ DispatchEventResult IDBTransaction::DispatchEventInternal(Event& event) {
DCHECK_EQ(event.target(), this);
state_ = kFinished;
- HeapVector<Member<EventTarget>> targets;
- targets.push_back(this);
- targets.push_back(db());
-
- // FIXME: When we allow custom event dispatching, this will probably need to
- // change.
- DCHECK(event.type() == event_type_names::kComplete ||
- event.type() == event_type_names::kAbort);
DispatchEventResult dispatch_result =
IDBEventDispatcher::Dispatch(event, targets);
// FIXME: Try to construct a test where |this| outlives openDBRequest and we
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 108f9dfe58c..298c182f981 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.h
@@ -33,7 +33,7 @@
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/core/dom/dom_string_list.h"
#include "third_party/blink/renderer/core/dom/events/event_listener.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_metadata.h"
@@ -64,7 +64,7 @@ class ScriptState;
class MODULES_EXPORT IDBTransaction final
: public EventTargetWithInlineData,
public ActiveScriptWrappable<IDBTransaction>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(IDBTransaction);
DEFINE_WRAPPERTYPEINFO();
@@ -102,7 +102,7 @@ class MODULES_EXPORT IDBTransaction final
const IDBDatabaseMetadata&);
~IDBTransaction() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
static mojom::IDBTransactionMode StringToMode(const String&);
@@ -195,6 +195,8 @@ class MODULES_EXPORT IDBTransaction final
return transaction_backend_.get();
}
+ void ContextDestroyed() override {}
+
protected:
// EventTarget
DispatchEventResult DispatchEventInternal(Event&) override;
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 f71d72e1c45..0dfa392fae3 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
@@ -41,6 +41,7 @@
#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/events/event_queue.h"
+#include "third_party/blink/renderer/core/testing/scoped_mock_overlay_scrollbars.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_database.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_key.h"
@@ -73,7 +74,8 @@ class FakeIDBDatabaseCallbacks final : public IDBDatabaseCallbacks {
void OnComplete(int64_t transaction_id) override {}
};
-class IDBTransactionTest : public testing::Test {
+class IDBTransactionTest : public testing::Test,
+ public ScopedMockOverlayScrollbars {
protected:
void SetUp() override {
url_loader_mock_factory_ = platform_->GetURLLoaderMockFactory();
@@ -93,7 +95,8 @@ class IDBTransactionTest : public testing::Test {
std::unique_ptr<MockWebIDBTransaction> transaction_backend) {
db_ = MakeGarbageCollected<IDBDatabase>(
scope.GetExecutionContext(), std::move(database_backend),
- MakeGarbageCollected<FakeIDBDatabaseCallbacks>(), scope.GetIsolate());
+ MakeGarbageCollected<FakeIDBDatabaseCallbacks>(), scope.GetIsolate(),
+ mojo::NullRemote());
HashSet<String> transaction_scope = {"store"};
transaction_ = IDBTransaction::CreateNonVersionChange(
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_value.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_value.cc
index 026313c9c66..0e98861bc23 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_value.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_value.cc
@@ -17,9 +17,14 @@
namespace blink {
-IDBValue::IDBValue(scoped_refptr<SharedBuffer> data,
- Vector<WebBlobInfo> blob_info)
- : data_(std::move(data)), blob_info_(std::move(blob_info)) {}
+IDBValue::IDBValue(
+ scoped_refptr<SharedBuffer> data,
+ Vector<WebBlobInfo> blob_info,
+ Vector<mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken>>
+ native_file_system_tokens)
+ : data_(std::move(data)),
+ blob_info_(std::move(blob_info)),
+ native_file_system_tokens_(std::move(native_file_system_tokens)) {}
IDBValue::~IDBValue() {
if (isolate_ && external_allocated_size_)
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_value.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_value.h
index 8bf8eac62bf..e5c6842de82 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_value.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_value.h
@@ -9,6 +9,7 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
+#include "third_party/blink/public/mojom/native_file_system/native_file_system_transfer_token.mojom-blink-forward.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_key.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_key_path.h"
#include "third_party/blink/renderer/modules/modules_export.h"
@@ -36,7 +37,11 @@ class WebBlobInfo;
// the values before returning them to the user.
class MODULES_EXPORT IDBValue final {
public:
- IDBValue(scoped_refptr<SharedBuffer>, Vector<WebBlobInfo>);
+ IDBValue(
+ scoped_refptr<SharedBuffer>,
+ Vector<WebBlobInfo>,
+ Vector<mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken>> =
+ {});
~IDBValue();
size_t DataSize() const { return data_ ? data_->size() : 0; }
@@ -48,6 +53,11 @@ class MODULES_EXPORT IDBValue final {
const IDBKey* PrimaryKey() const { return primary_key_.get(); }
const IDBKeyPath& KeyPath() const { return key_path_; }
+ Vector<mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken>>&
+ NativeFileSystemTokens() {
+ return native_file_system_tokens_;
+ }
+
// Injects a primary key into a value coming from the backend.
void SetInjectedPrimaryKey(std::unique_ptr<IDBKey> primary_key,
IDBKeyPath primary_key_path) {
@@ -89,6 +99,9 @@ class MODULES_EXPORT IDBValue final {
Vector<WebBlobInfo> blob_info_;
+ Vector<mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken>>
+ native_file_system_tokens_;
+
std::unique_ptr<IDBKey> primary_key_;
IDBKeyPath key_path_;
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.cc
index 74b7c5a1763..bd07795b99a 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.cc
@@ -87,12 +87,8 @@ void IDBValueWrapper::Clone(ScriptState* script_state, ScriptValue* clone) {
DCHECK(!done_cloning_) << __func__ << " called after DoneCloning()";
#endif // DCHECK_IS_ON()
- bool read_wasm_from_stream = true;
- // It is safe to unconditionally enable WASM module decoding because the
- // relevant checks were already performed in SerializedScriptValue::Serialize,
- // called by the IDBValueWrapper constructor.
*clone = DeserializeScriptValue(script_state, serialized_value_.get(),
- &blob_info_, read_wasm_from_stream);
+ &blob_info_);
}
// static
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.h
index 28a88bcdb3a..d8cca97c034 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.h
@@ -157,6 +157,16 @@ class MODULES_EXPORT IDBValueWrapper {
return std::move(blob_info_);
}
+ Vector<mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken>>
+ TakeNativeFileSystemTransferTokens() {
+#if DCHECK_IS_ON()
+ DCHECK(done_cloning_) << __func__ << " called before DoneCloning()";
+ DCHECK(owns_file_system_handles_) << __func__ << " called twice";
+ owns_file_system_handles_ = false;
+#endif // DCHECK_IS_ON()
+ return std::move(serialized_value_->NativeFileSystemTokens());
+ }
+
size_t DataLengthBeforeWrapInBytes() { return original_data_length_; }
// Default threshold for WrapIfBiggerThan().
@@ -199,6 +209,7 @@ class MODULES_EXPORT IDBValueWrapper {
bool owns_blob_handles_ = true;
bool owns_blob_info_ = true;
bool owns_wire_bytes_ = true;
+ bool owns_file_system_handles_ = true;
#endif // DCHECK_IS_ON()
};
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 4eeaa231768..a83ad44913a 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
@@ -71,7 +71,7 @@ const AtomicString& IDBVersionChangeEvent::InterfaceName() const {
return event_interface_names::kIDBVersionChangeEvent;
}
-void IDBVersionChangeEvent::Trace(blink::Visitor* visitor) {
+void IDBVersionChangeEvent::Trace(Visitor* visitor) {
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 3d404a5aaf8..60bc00915ec 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
@@ -30,10 +30,10 @@
#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink-forward.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_idb_version_change_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_any.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_request.h"
-#include "third_party/blink/renderer/modules/indexeddb/idb_version_change_event_init.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -61,14 +61,16 @@ class IDBVersionChangeEvent final : public Event {
const IDBVersionChangeEventInit*);
uint64_t oldVersion() const { return old_version_; }
- uint64_t newVersion(bool& is_null) const;
+ base::Optional<uint64_t> newVersion() const { return new_version_; }
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ uint64_t newVersion(bool& is_null) const; // DEPRECATED
const AtomicString& dataLoss() const;
const String& dataLossMessage() const { return data_loss_message_; }
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
uint64_t old_version_;
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.idl b/chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.idl
index b3bdfbb41d9..47a8172f4a6 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.idl
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.idl
@@ -29,9 +29,9 @@
enum IDBDataLossAmount { "none", "total" };
[
- Exposed=(Window,Worker),
- Constructor(DOMString type, optional IDBVersionChangeEventInit eventInitDict)
+ Exposed=(Window,Worker)
] interface IDBVersionChangeEvent : Event {
+ constructor(DOMString type, optional IDBVersionChangeEventInit eventInitDict = {});
readonly attribute unsigned long long oldVersion;
readonly attribute unsigned long long? newVersion;
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idls.gni b/chromium/third_party/blink/renderer/modules/indexeddb/idls.gni
new file mode 100644
index 00000000000..9c8b7d8bbef
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "idb_cursor.idl",
+ "idb_cursor_with_value.idl",
+ "idb_database.idl",
+ "idb_factory.idl",
+ "idb_index.idl",
+ "idb_key_range.idl",
+ "idb_object_store.idl",
+ "idb_observation.idl",
+ "idb_observer.idl",
+ "idb_observer_changes.idl",
+ "idb_open_db_request.idl",
+ "idb_request.idl",
+ "idb_transaction.idl",
+ "idb_version_change_event.idl",
+]
+
+modules_dictionary_idl_files = [
+ "idb_database_info.idl",
+ "idb_index_parameters.idl",
+ "idb_object_store_parameters.idl",
+ "idb_observer_init.idl",
+ "idb_transaction_options.idl",
+ "idb_version_change_event_init.idl",
+]
+
+modules_dependency_idl_files = [
+ "window_indexed_database.idl",
+ "worker_global_scope_indexed_database.idl",
+]
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 340121d34fe..5c0ec1f2105 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
@@ -7,7 +7,6 @@
#include "base/stl_util.h"
#include "mojo/public/cpp/bindings/array_traits_wtf_vector.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
-#include "third_party/blink/public/platform/file_path_conversion.h"
#include "third_party/blink/public/platform/web_blob_info.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_key_range.h"
#include "third_party/blink/renderer/platform/file_metadata.h"
@@ -185,16 +184,16 @@ StructTraits<blink::mojom::IDBValueDataView, std::unique_ptr<blink::IDBValue>>::
}
// static
-Vector<blink::mojom::blink::IDBBlobInfoPtr>
+Vector<blink::mojom::blink::IDBExternalObjectPtr>
StructTraits<blink::mojom::IDBValueDataView, std::unique_ptr<blink::IDBValue>>::
- blob_or_file_info(const std::unique_ptr<blink::IDBValue>& input) {
- Vector<blink::mojom::blink::IDBBlobInfoPtr> blob_or_file_info;
- blob_or_file_info.ReserveInitialCapacity(input->BlobInfo().size());
+ external_objects(const std::unique_ptr<blink::IDBValue>& input) {
+ Vector<blink::mojom::blink::IDBExternalObjectPtr> external_objects;
+ external_objects.ReserveInitialCapacity(
+ input->BlobInfo().size() + input->NativeFileSystemTokens().size());
for (const blink::WebBlobInfo& info : input->BlobInfo()) {
auto blob_info = blink::mojom::blink::IDBBlobInfo::New();
if (info.IsFile()) {
blob_info->file = blink::mojom::blink::IDBFileInfo::New();
- blob_info->file->path = blink::WebStringToFilePath(info.FilePath());
String name = info.FileName();
if (name.IsNull())
name = g_empty_string;
@@ -211,9 +210,16 @@ StructTraits<blink::mojom::IDBValueDataView, std::unique_ptr<blink::IDBValue>>::
blob_info->mime_type = mime_type;
blob_info->blob = mojo::PendingRemote<blink::mojom::blink::Blob>(
info.CloneBlobHandle(), blink::mojom::blink::Blob::Version_);
- blob_or_file_info.push_back(std::move(blob_info));
+ external_objects.push_back(
+ blink::mojom::blink::IDBExternalObject::NewBlobOrFile(
+ std::move(blob_info)));
}
- return blob_or_file_info;
+ for (auto& token : input->NativeFileSystemTokens()) {
+ external_objects.push_back(
+ blink::mojom::blink::IDBExternalObject::NewNativeFileSystemToken(
+ std::move(token)));
+ }
+ return external_objects;
}
// static
@@ -226,35 +232,49 @@ bool StructTraits<blink::mojom::IDBValueDataView,
return false;
if (value_bits.IsEmpty()) {
- *out = std::make_unique<blink::IDBValue>(
- scoped_refptr<SharedBuffer>(), Vector<blink::WebBlobInfo>());
+ *out = std::make_unique<blink::IDBValue>(scoped_refptr<SharedBuffer>(),
+ Vector<blink::WebBlobInfo>());
return true;
}
scoped_refptr<SharedBuffer> value_buffer = SharedBuffer::Create(
reinterpret_cast<const char*>(value_bits.data()), value_bits.size());
- Vector<blink::mojom::blink::IDBBlobInfoPtr> blob_or_file_info;
- if (!data.ReadBlobOrFileInfo(&blob_or_file_info))
+ Vector<blink::mojom::blink::IDBExternalObjectPtr> external_objects;
+ if (!data.ReadExternalObjects(&external_objects))
return false;
Vector<blink::WebBlobInfo> value_blob_info;
- value_blob_info.ReserveInitialCapacity(blob_or_file_info.size());
- for (const auto& info : blob_or_file_info) {
- if (info->file) {
- value_blob_info.emplace_back(
- info->uuid, blink::FilePathToWebString(info->file->path),
- info->file->name, info->mime_type,
- blink::NullableTimeToOptionalTime(info->file->last_modified),
- info->size, info->blob.PassPipe());
- } else {
- value_blob_info.emplace_back(info->uuid, info->mime_type, info->size,
- info->blob.PassPipe());
+ Vector<
+ mojo::PendingRemote<blink::mojom::blink::NativeFileSystemTransferToken>>
+ native_file_system_tokens;
+
+ for (const auto& object : external_objects) {
+ switch (object->which()) {
+ case blink::mojom::blink::IDBExternalObject::Tag::BLOB_OR_FILE: {
+ auto& info = object->get_blob_or_file();
+ if (info->file) {
+ value_blob_info.emplace_back(
+ info->uuid, info->file->name, info->mime_type,
+ blink::NullableTimeToOptionalTime(info->file->last_modified),
+ info->size, info->blob.PassPipe());
+ } else {
+ value_blob_info.emplace_back(info->uuid, info->mime_type, info->size,
+ info->blob.PassPipe());
+ }
+ break;
+ }
+ case blink::mojom::blink::IDBExternalObject::Tag::
+ NATIVE_FILE_SYSTEM_TOKEN:
+ native_file_system_tokens.push_back(
+ std::move(object->get_native_file_system_token()));
+ break;
}
}
- *out = std::make_unique<blink::IDBValue>(std::move(value_buffer),
- std::move(value_blob_info));
+ *out = std::make_unique<blink::IDBValue>(
+ std::move(value_buffer), std::move(value_blob_info),
+ std::move(native_file_system_tokens));
return true;
}
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.h b/chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.h
index 5a94ff7159d..4019374a826 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.h
@@ -128,7 +128,7 @@ template <>
struct MODULES_EXPORT StructTraits<blink::mojom::IDBValueDataView,
std::unique_ptr<blink::IDBValue>> {
static Vector<uint8_t> bits(const std::unique_ptr<blink::IDBValue>& input);
- static Vector<blink::mojom::blink::IDBBlobInfoPtr> blob_or_file_info(
+ static Vector<blink::mojom::blink::IDBExternalObjectPtr> external_objects(
const std::unique_ptr<blink::IDBValue>& input);
static bool Read(blink::mojom::IDBValueDataView data,
std::unique_ptr<blink::IDBValue>* out);
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 e278a24906d..6c8b3f073f0 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
@@ -36,6 +36,7 @@
#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
#include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_idb_transaction_options.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_string_list.h"
#include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
@@ -58,7 +59,6 @@
#include "third_party/blink/renderer/modules/indexeddb/idb_open_db_request.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_request.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_transaction.h"
-#include "third_party/blink/renderer/modules/indexeddb/idb_transaction_options.h"
#include "third_party/blink/renderer/modules/indexeddb/web_idb_cursor.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
@@ -101,13 +101,13 @@ const char kNoDocumentError[] = "No document for given frame found";
Response AssertIDBFactory(Document* document, IDBFactory*& result) {
LocalDOMWindow* dom_window = document->domWindow();
if (!dom_window)
- return Response::Error("No IndexedDB factory for given frame found");
+ return Response::ServerError("No IndexedDB factory for given frame found");
IDBFactory* idb_factory = GlobalIndexedDB::indexedDB(*dom_window);
if (!idb_factory)
- return Response::Error("No IndexedDB factory for given frame found");
+ return Response::ServerError("No IndexedDB factory for given frame found");
result = idb_factory;
- return Response::OK();
+ return Response::Success();
}
class GetDatabaseNamesCallback final : public NativeEventListener {
@@ -121,7 +121,8 @@ class GetDatabaseNamesCallback final : public NativeEventListener {
void Invoke(ExecutionContext*, Event* event) override {
if (event->type() != event_type_names::kSuccess) {
- request_callback_->sendFailure(Response::Error("Unexpected event type."));
+ request_callback_->sendFailure(
+ Response::ServerError("Unexpected event type."));
return;
}
@@ -129,7 +130,7 @@ class GetDatabaseNamesCallback final : public NativeEventListener {
IDBAny* request_result = idb_request->ResultAsAny();
if (request_result->GetType() != IDBAny::kDOMStringListType) {
request_callback_->sendFailure(
- Response::Error("Unexpected result type."));
+ Response::ServerError("Unexpected result type."));
return;
}
@@ -156,7 +157,7 @@ class DeleteCallback final : public NativeEventListener {
void Invoke(ExecutionContext*, Event* event) override {
if (event->type() != event_type_names::kSuccess) {
request_callback_->sendFailure(
- Response::Error("Failed to delete database."));
+ Response::ServerError("Failed to delete database."));
return;
}
request_callback_->sendSuccess();
@@ -182,12 +183,12 @@ class ExecutableWithDatabase
void Start(LocalFrame* frame, const String& database_name) {
Document* document = frame ? frame->GetDocument() : nullptr;
if (!document) {
- SendFailure(Response::Error(kNoDocumentError));
+ SendFailure(Response::ServerError(kNoDocumentError));
return;
}
IDBFactory* idb_factory = nullptr;
Response response = AssertIDBFactory(document, idb_factory);
- if (!response.isSuccess()) {
+ if (!response.IsSuccess()) {
SendFailure(response);
return;
}
@@ -216,7 +217,7 @@ class ExecutableWithDatabase
IDBOpenDBRequest* idb_open_db_request =
idb_factory->open(script_state, database_name, exception_state);
if (exception_state.HadException()) {
- SendFailure(Response::Error("Could not open database."));
+ SendFailure(Response::ServerError("Could not open database."));
return;
}
idb_open_db_request->addEventListener(event_type_names::kUpgradeneeded,
@@ -250,7 +251,7 @@ class OpenDatabaseCallback final : public NativeEventListener {
void Invoke(ExecutionContext* context, Event* event) override {
if (event->type() != event_type_names::kSuccess) {
executable_with_database_->GetRequestCallback()->sendFailure(
- Response::Error("Unexpected event type."));
+ Response::ServerError("Unexpected event type."));
return;
}
@@ -259,7 +260,7 @@ class OpenDatabaseCallback final : public NativeEventListener {
IDBAny* request_result = idb_open_db_request->ResultAsAny();
if (request_result->GetType() != IDBAny::kIDBDatabaseType) {
executable_with_database_->GetRequestCallback()->sendFailure(
- Response::Error("Unexpected result type."));
+ Response::ServerError("Unexpected result type."));
return;
}
@@ -269,7 +270,7 @@ class OpenDatabaseCallback final : public NativeEventListener {
idb_database->close();
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(script_state_);
NativeEventListener::Trace(visitor);
}
@@ -297,7 +298,7 @@ class UpgradeDatabaseCallback final : public NativeEventListener {
void Invoke(ExecutionContext* context, Event* event) override {
if (event->type() != event_type_names::kUpgradeneeded) {
executable_with_database_->GetRequestCallback()->sendFailure(
- Response::Error("Unexpected event type."));
+ Response::ServerError("Unexpected event type."));
return;
}
@@ -309,7 +310,7 @@ class UpgradeDatabaseCallback final : public NativeEventListener {
NonThrowableExceptionState exception_state;
idb_open_db_request->transaction()->abort(exception_state);
executable_with_database_->GetRequestCallback()->sendFailure(
- Response::Error("Aborted upgrade."));
+ Response::ServerError("Aborted upgrade."));
}
private:
@@ -537,7 +538,8 @@ class OpenCursorCallback final : public NativeEventListener {
void Invoke(ExecutionContext*, Event* event) override {
if (event->type() != event_type_names::kSuccess) {
- request_callback_->sendFailure(Response::Error("Unexpected event type."));
+ request_callback_->sendFailure(
+ Response::ServerError("Unexpected event type."));
return;
}
@@ -549,7 +551,7 @@ class OpenCursorCallback final : public NativeEventListener {
}
if (request_result->GetType() != IDBAny::kIDBCursorWithValueType) {
request_callback_->sendFailure(
- Response::Error("Unexpected result type."));
+ Response::ServerError("Unexpected result type."));
return;
}
@@ -560,7 +562,7 @@ class OpenCursorCallback final : public NativeEventListener {
idb_cursor->advance(skip_count_, exception_state);
if (exception_state.HadException()) {
request_callback_->sendFailure(
- Response::Error("Could not advance cursor."));
+ Response::ServerError("Could not advance cursor."));
}
skip_count_ = 0;
return;
@@ -578,11 +580,11 @@ class OpenCursorCallback final : public NativeEventListener {
exception_state);
if (exception_state.HadException()) {
request_callback_->sendFailure(
- Response::Error("Could not continue cursor."));
+ Response::ServerError("Could not continue cursor."));
return;
}
- Document* document = To<Document>(ExecutionContext::From(script_state_));
+ Document* document = Document::From(ExecutionContext::From(script_state_));
if (!document)
return;
ScriptState::Scope scope(script_state_);
@@ -608,7 +610,7 @@ class OpenCursorCallback final : public NativeEventListener {
request_callback_->sendSuccess(std::move(result_), has_more);
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(script_state_);
NativeEventListener::Trace(visitor);
}
@@ -644,14 +646,14 @@ class DataLoader final : public ExecutableWithDatabase<RequestDataCallback> {
TransactionForDatabase(script_state, idb_database, object_store_name_);
if (!idb_transaction) {
request_callback_->sendFailure(
- Response::Error("Could not get transaction"));
+ Response::ServerError("Could not get transaction"));
return;
}
IDBObjectStore* idb_object_store =
ObjectStoreForTransaction(idb_transaction, object_store_name_);
if (!idb_object_store) {
request_callback_->sendFailure(
- Response::Error("Could not get object store"));
+ Response::ServerError("Could not get object store"));
return;
}
@@ -659,7 +661,8 @@ class DataLoader final : public ExecutableWithDatabase<RequestDataCallback> {
if (!index_name_.IsEmpty()) {
IDBIndex* idb_index = IndexForObjectStore(idb_object_store, index_name_);
if (!idb_index) {
- request_callback_->sendFailure(Response::Error("Could not get index"));
+ request_callback_->sendFailure(
+ Response::ServerError("Could not get index"));
return;
}
@@ -729,14 +732,14 @@ void InspectorIndexedDBAgent::DidCommitLoadForLocalFrame(LocalFrame* frame) {
Response InspectorIndexedDBAgent::enable() {
enabled_.Set(true);
- return Response::OK();
+ return Response::Success();
}
Response InspectorIndexedDBAgent::disable() {
enabled_.Clear();
v8_session_->releaseObjectGroup(
ToV8InspectorStringView(kIndexedDBObjectGroup));
- return Response::OK();
+ return Response::Success();
}
void InspectorIndexedDBAgent::requestDatabaseNames(
@@ -746,12 +749,12 @@ void InspectorIndexedDBAgent::requestDatabaseNames(
inspected_frames_->FrameWithSecurityOrigin(security_origin);
Document* document = frame ? frame->GetDocument() : nullptr;
if (!document) {
- request_callback->sendFailure(Response::Error(kNoDocumentError));
+ request_callback->sendFailure(Response::ServerError(kNoDocumentError));
return;
}
IDBFactory* idb_factory = nullptr;
Response response = AssertIDBFactory(document, idb_factory);
- if (!response.isSuccess()) {
+ if (!response.IsSuccess()) {
request_callback->sendFailure(response);
return;
}
@@ -767,7 +770,7 @@ void InspectorIndexedDBAgent::requestDatabaseNames(
idb_factory->GetDatabaseNames(script_state, exception_state);
if (exception_state.HadException()) {
request_callback->sendFailure(
- Response::Error("Could not obtain database names."));
+ Response::ServerError("Could not obtain database names."));
return;
}
idb_request->addEventListener(
@@ -802,7 +805,8 @@ void InspectorIndexedDBAgent::requestData(
key_range.isJust() ? IdbKeyRangeFromKeyRange(key_range.fromJust())
: nullptr;
if (key_range.isJust() && !idb_key_range) {
- request_callback->sendFailure(Response::Error("Can not parse key range."));
+ request_callback->sendFailure(
+ Response::ServerError("Can not parse key range."));
return;
}
@@ -857,7 +861,7 @@ class GetMetadata final : public ExecutableWithDatabase<GetMetadataCallback> {
void NotifySubtaskDone(const String& error) {
if (!error.IsNull()) {
- request_callback_->sendFailure(Response::Error(error));
+ request_callback_->sendFailure(Response::ServerError(error.Utf8()));
return;
}
if (--subtask_pending_ == 0) {
@@ -881,14 +885,14 @@ class GetMetadata final : public ExecutableWithDatabase<GetMetadataCallback> {
indexed_db_names::kReadonly);
if (!idb_transaction) {
request_callback_->sendFailure(
- Response::Error("Could not get transaction"));
+ Response::ServerError("Could not get transaction"));
return;
}
IDBObjectStore* idb_object_store =
ObjectStoreForTransaction(idb_transaction, object_store_name_);
if (!idb_object_store) {
request_callback_->sendFailure(
- Response::Error("Could not get object store"));
+ Response::ServerError("Could not get object store"));
return;
}
@@ -901,9 +905,10 @@ class GetMetadata final : public ExecutableWithDatabase<GetMetadataCallback> {
DCHECK(!exception_state.HadException());
if (exception_state.HadException()) {
ExceptionCode ec = exception_state.Code();
- request_callback_->sendFailure(Response::Error(
+ request_callback_->sendFailure(Response::ServerError(
String::Format("Could not count entries in object store '%s': %d",
- object_store_name_.Utf8().c_str(), ec)));
+ object_store_name_.Latin1().c_str(), ec)
+ .Utf8()));
return;
}
GetMetadataListener* listener_get_entries_count =
@@ -964,7 +969,7 @@ class DeleteObjectStoreEntriesListener final : public NativeEventListener {
void Invoke(ExecutionContext*, Event* event) override {
if (event->type() != event_type_names::kSuccess) {
request_callback_->sendFailure(
- Response::Error("Failed to delete specified entries"));
+ Response::ServerError("Failed to delete specified entries"));
return;
}
@@ -1000,14 +1005,14 @@ class DeleteObjectStoreEntries final
indexed_db_names::kReadwrite);
if (!idb_transaction) {
request_callback_->sendFailure(
- Response::Error("Could not get transaction"));
+ Response::ServerError("Could not get transaction"));
return;
}
IDBObjectStore* idb_object_store =
ObjectStoreForTransaction(idb_transaction, object_store_name_);
if (!idb_object_store) {
request_callback_->sendFailure(
- Response::Error("Could not get object store"));
+ Response::ServerError("Could not get object store"));
return;
}
@@ -1038,7 +1043,8 @@ void InspectorIndexedDBAgent::deleteObjectStoreEntries(
std::unique_ptr<DeleteObjectStoreEntriesCallback> request_callback) {
IDBKeyRange* idb_key_range = IdbKeyRangeFromKeyRange(key_range.get());
if (!idb_key_range) {
- request_callback->sendFailure(Response::Error("Can not parse key range"));
+ request_callback->sendFailure(
+ Response::ServerError("Can not parse key range"));
return;
}
scoped_refptr<DeleteObjectStoreEntries> delete_object_store_entries =
@@ -1058,7 +1064,8 @@ class ClearObjectStoreListener final : public NativeEventListener {
void Invoke(ExecutionContext*, Event* event) override {
if (event->type() != event_type_names::kComplete) {
- request_callback_->sendFailure(Response::Error("Unexpected event type."));
+ request_callback_->sendFailure(
+ Response::ServerError("Unexpected event type."));
return;
}
@@ -1090,14 +1097,14 @@ class ClearObjectStore final
indexed_db_names::kReadwrite);
if (!idb_transaction) {
request_callback_->sendFailure(
- Response::Error("Could not get transaction"));
+ Response::ServerError("Could not get transaction"));
return;
}
IDBObjectStore* idb_object_store =
ObjectStoreForTransaction(idb_transaction, object_store_name_);
if (!idb_object_store) {
request_callback_->sendFailure(
- Response::Error("Could not get object store"));
+ Response::ServerError("Could not get object store"));
return;
}
@@ -1106,9 +1113,10 @@ class ClearObjectStore final
DCHECK(!exception_state.HadException());
if (exception_state.HadException()) {
ExceptionCode ec = exception_state.Code();
- request_callback_->sendFailure(Response::Error(
+ request_callback_->sendFailure(Response::ServerError(
String::Format("Could not clear object store '%s': %d",
- object_store_name_.Utf8().c_str(), ec)));
+ object_store_name_.Latin1().c_str(), ec)
+ .Utf8()));
return;
}
idb_transaction->addEventListener(
@@ -1147,12 +1155,12 @@ void InspectorIndexedDBAgent::deleteDatabase(
inspected_frames_->FrameWithSecurityOrigin(security_origin);
Document* document = frame ? frame->GetDocument() : nullptr;
if (!document) {
- request_callback->sendFailure(Response::Error(kNoDocumentError));
+ request_callback->sendFailure(Response::ServerError(kNoDocumentError));
return;
}
IDBFactory* idb_factory = nullptr;
Response response = AssertIDBFactory(document, idb_factory);
- if (!response.isSuccess()) {
+ if (!response.IsSuccess()) {
request_callback->sendFailure(response);
return;
}
@@ -1168,7 +1176,7 @@ void InspectorIndexedDBAgent::deleteDatabase(
script_state, database_name, exception_state);
if (exception_state.HadException()) {
request_callback->sendFailure(
- Response::Error("Could not delete database."));
+ Response::ServerError("Could not delete database."));
return;
}
idb_request->addEventListener(
@@ -1179,7 +1187,7 @@ void InspectorIndexedDBAgent::deleteDatabase(
false);
}
-void InspectorIndexedDBAgent::Trace(blink::Visitor* visitor) {
+void InspectorIndexedDBAgent::Trace(Visitor* visitor) {
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 c4fa599841b..f584276e2f8 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void Restore() override;
void DidCommitLoadForLocalFrame(LocalFrame*) override;
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/mock_web_idb_factory.h b/chromium/third_party/blink/renderer/modules/indexeddb/mock_web_idb_factory.h
index e2bd1dfba07..1d52aab774b 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/mock_web_idb_factory.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/mock_web_idb_factory.h
@@ -40,6 +40,8 @@ class MockWebIDBFactory : public testing::StrictMock<blink::WebIDBFactory> {
void(const WTF::String& name,
std::unique_ptr<WebIDBCallbacks>,
bool force_close));
+ MOCK_METHOD0(GetObservedFeature,
+ mojo::PendingRemote<mojom::blink::ObservedFeature>());
void SetCallbacksPointer(std::unique_ptr<WebIDBCallbacks>* callbacks);
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.cc b/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.cc
index b99decb0155..0ac1b13d05f 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.h"
#include "base/format_macros.h"
+#include "base/memory/ptr_util.h"
#include "mojo/public/cpp/bindings/self_owned_associated_receiver.h"
#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_database_error.h"
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_factory.h b/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_factory.h
index 07fc9bffed8..42ef51b2612 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_factory.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_factory.h
@@ -30,6 +30,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_WEB_IDB_FACTORY_H_
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
+#include "third_party/blink/public/mojom/feature_observer/feature_observer.mojom-blink.h"
#include "third_party/blink/renderer/modules/modules_export.h"
namespace WTF {
@@ -58,6 +59,8 @@ class MODULES_EXPORT WebIDBFactory {
virtual void DeleteDatabase(const WTF::String& name,
std::unique_ptr<WebIDBCallbacks>,
bool force_close) = 0;
+ virtual mojo::PendingRemote<mojom::blink::ObservedFeature>
+ GetObservedFeature() = 0;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_factory_impl.cc b/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_factory_impl.cc
index 875fb3037f2..ebd78224b09 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_factory_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_factory_impl.cc
@@ -15,13 +15,24 @@ namespace blink {
WebIDBFactoryImpl::WebIDBFactoryImpl(
mojo::PendingRemote<mojom::blink::IDBFactory> pending_factory,
+ mojo::PendingRemote<mojom::blink::FeatureObserver> feature_observer,
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
: task_runner_(std::move(task_runner)) {
factory_.Bind(std::move(pending_factory), task_runner_);
+ feature_observer_.Bind(std::move(feature_observer), task_runner_);
}
WebIDBFactoryImpl::~WebIDBFactoryImpl() = default;
+mojo::PendingRemote<mojom::blink::ObservedFeature>
+WebIDBFactoryImpl::GetObservedFeature() {
+ mojo::PendingRemote<mojom::blink::ObservedFeature> feature;
+ feature_observer_->Register(
+ feature.InitWithNewPipeAndPassReceiver(),
+ mojom::blink::ObservedFeatureType::kIndexedDBConnection);
+ return feature;
+}
+
void WebIDBFactoryImpl::GetDatabaseInfo(
std::unique_ptr<WebIDBCallbacks> callbacks) {
callbacks->SetState(nullptr, WebIDBCallbacksImpl::kNoTransaction);
diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_factory_impl.h b/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_factory_impl.h
index aaec596aa00..4a761c34404 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_factory_impl.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_factory_impl.h
@@ -26,6 +26,7 @@ class WebIDBFactoryImpl : public WebIDBFactory {
public:
explicit WebIDBFactoryImpl(
mojo::PendingRemote<mojom::blink::IDBFactory> pending_factory,
+ mojo::PendingRemote<mojom::blink::FeatureObserver> feature_observer,
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
~WebIDBFactoryImpl() override;
@@ -43,6 +44,8 @@ class WebIDBFactoryImpl : public WebIDBFactory {
void DeleteDatabase(const WTF::String& name,
std::unique_ptr<WebIDBCallbacks> callbacks,
bool force_close) override;
+ mojo::PendingRemote<mojom::blink::ObservedFeature> GetObservedFeature()
+ override;
private:
mojo::PendingAssociatedRemote<mojom::blink::IDBCallbacks> GetCallbacksProxy(
@@ -52,6 +55,7 @@ class WebIDBFactoryImpl : public WebIDBFactory {
std::unique_ptr<IndexedDBDatabaseCallbacksImpl> callbacks);
mojo::Remote<mojom::blink::IDBFactory> factory_;
+ mojo::Remote<mojom::blink::FeatureObserver> feature_observer_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
};
diff --git a/chromium/third_party/blink/renderer/modules/installation/DEPS b/chromium/third_party/blink/renderer/modules/installation/DEPS
deleted file mode 100644
index 1c4339f90e8..00000000000
--- a/chromium/third_party/blink/renderer/modules/installation/DEPS
+++ /dev/null
@@ -1,3 +0,0 @@
-include_rules = [
- "+mojo/public/cpp/bindings/strong_binding.h",
-]
diff --git a/chromium/third_party/blink/renderer/modules/installedapp/idls.gni b/chromium/third_party/blink/renderer/modules/installedapp/idls.gni
new file mode 100644
index 00000000000..4e38e2b809b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/installedapp/idls.gni
@@ -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.
+
+modules_dependency_idl_files = [ "navigator_installed_app.idl" ]
+
+modules_dictionary_idl_files = [ "related_application.idl" ]
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 64d7dba3b61..f31d3bac7e3 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
@@ -54,15 +54,15 @@ const char InstalledAppController::kSupplementName[] = "InstalledAppController";
InstalledAppController::InstalledAppController(LocalFrame& frame)
: Supplement<LocalFrame>(frame),
- ContextLifecycleObserver(frame.GetDocument()) {}
+ ExecutionContextLifecycleObserver(frame.GetDocument()) {}
-void InstalledAppController::ContextDestroyed(ExecutionContext*) {
+void InstalledAppController::ContextDestroyed() {
provider_.reset();
}
void InstalledAppController::OnGetManifestForRelatedApps(
std::unique_ptr<AppInstalledCallbacks> callbacks,
- const KURL& /*url*/,
+ const KURL& url,
mojom::blink::ManifestPtr manifest) {
Vector<mojom::blink::RelatedApplicationPtr> mojo_related_apps;
for (const auto& related_application : manifest->related_applications) {
@@ -86,7 +86,7 @@ void InstalledAppController::OnGetManifestForRelatedApps(
}
provider_->FilterInstalledApps(
- std::move(mojo_related_apps),
+ std::move(mojo_related_apps), url,
WTF::Bind(&InstalledAppController::OnFilterInstalledApps,
WrapPersistent(this), WTF::Passed(std::move(callbacks))));
}
@@ -98,7 +98,7 @@ void InstalledAppController::OnFilterInstalledApps(
for (const auto& res : result) {
auto* app = MakeGarbageCollected<RelatedApplication>();
app->setPlatform(res->platform);
- app->setURL(res->url);
+ app->setUrl(res->url);
app->setId(res->id);
app->setVersion(res->version);
applications.push_back(app);
@@ -108,7 +108,7 @@ void InstalledAppController::OnFilterInstalledApps(
void InstalledAppController::Trace(Visitor* visitor) {
Supplement<LocalFrame>::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 5d1ff418360..f4574f826a8 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
@@ -14,9 +14,9 @@
#include "third_party/blink/public/mojom/installedapp/related_application.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/manifest/manifest.mojom-blink-forward.h"
#include "third_party/blink/renderer/bindings/core/v8/callback_promise_adapter.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_related_application.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
-#include "third_party/blink/renderer/modules/installedapp/related_application.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/heap/member.h"
@@ -31,7 +31,7 @@ using AppInstalledCallbacks =
class MODULES_EXPORT InstalledAppController final
: public GarbageCollected<InstalledAppController>,
public Supplement<LocalFrame>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(InstalledAppController);
public:
@@ -60,8 +60,8 @@ class MODULES_EXPORT InstalledAppController final
const KURL& url,
mojom::blink::ManifestPtr manifest);
- // Inherited from ContextLifecycleObserver.
- void ContextDestroyed(ExecutionContext*) override;
+ // Inherited from ExecutionContextLifecycleObserver.
+ void ContextDestroyed() override;
// Callback from the InstalledAppProvider mojo service.
void OnFilterInstalledApps(std::unique_ptr<AppInstalledCallbacks>,
diff --git a/chromium/third_party/blink/renderer/modules/installedapp/navigator_installed_app.cc b/chromium/third_party/blink/renderer/modules/installedapp/navigator_installed_app.cc
index 1e59bd2e57d..a05443e36dc 100644
--- a/chromium/third_party/blink/renderer/modules/installedapp/navigator_installed_app.cc
+++ b/chromium/third_party/blink/renderer/modules/installedapp/navigator_installed_app.cc
@@ -9,6 +9,7 @@
#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/modules/v8/v8_related_application.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"
@@ -16,7 +17,6 @@
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/navigator.h"
#include "third_party/blink/renderer/modules/installedapp/installed_app_controller.h"
-#include "third_party/blink/renderer/modules/installedapp/related_application.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
@@ -90,7 +90,7 @@ InstalledAppController* NavigatorInstalledApp::Controller() {
const char NavigatorInstalledApp::kSupplementName[] = "NavigatorInstalledApp";
-void NavigatorInstalledApp::Trace(blink::Visitor* visitor) {
+void NavigatorInstalledApp::Trace(Visitor* visitor) {
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/installedapp/navigator_installed_app.h b/chromium/third_party/blink/renderer/modules/installedapp/navigator_installed_app.h
index fe19fd26a74..d4da6fbd912 100644
--- a/chromium/third_party/blink/renderer/modules/installedapp/navigator_installed_app.h
+++ b/chromium/third_party/blink/renderer/modules/installedapp/navigator_installed_app.h
@@ -36,7 +36,7 @@ class NavigatorInstalledApp final
explicit NavigatorInstalledApp(Navigator&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/keyboard/idls.gni b/chromium/third_party/blink/renderer/modules/keyboard/idls.gni
new file mode 100644
index 00000000000..3c1e3e9d96e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/keyboard/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "keyboard.idl",
+ "keyboard_layout_map.idl",
+]
+
+modules_dependency_idl_files = [ "navigator_keyboard.idl" ]
diff --git a/chromium/third_party/blink/renderer/modules/keyboard/keyboard.cc b/chromium/third_party/blink/renderer/modules/keyboard/keyboard.cc
index 758cfde37da..02fdf05b106 100644
--- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard.cc
+++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard.cc
@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/keyboard/keyboard_layout.h"
#include "third_party/blink/renderer/modules/keyboard/keyboard_lock.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
namespace blink {
@@ -18,19 +19,21 @@ Keyboard::Keyboard(ExecutionContext* context)
Keyboard::~Keyboard() = default;
ScriptPromise Keyboard::lock(ScriptState* state,
- const Vector<String>& keycodes) {
- return keyboard_lock_->lock(state, keycodes);
+ const Vector<String>& keycodes,
+ ExceptionState& exception_state) {
+ return keyboard_lock_->lock(state, keycodes, exception_state);
}
void Keyboard::unlock(ScriptState* state) {
keyboard_lock_->unlock(state);
}
-ScriptPromise Keyboard::getLayoutMap(ScriptState* state) {
- return keyboard_layout_->GetKeyboardLayoutMap(state);
+ScriptPromise Keyboard::getLayoutMap(ScriptState* state,
+ ExceptionState& exception_state) {
+ return keyboard_layout_->GetKeyboardLayoutMap(state, exception_state);
}
-void Keyboard::Trace(blink::Visitor* visitor) {
+void Keyboard::Trace(Visitor* visitor) {
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 2abb1ea399f..c1e9a3fecb4 100644
--- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard.h
+++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard.h
@@ -11,6 +11,7 @@
namespace blink {
+class ExceptionState;
class ExecutionContext;
class KeyboardLayout;
class KeyboardLock;
@@ -24,13 +25,13 @@ class Keyboard final : public ScriptWrappable {
~Keyboard() override;
// KeyboardLock API: https://w3c.github.io/keyboard-lock/
- ScriptPromise lock(ScriptState*, const Vector<String>&);
+ ScriptPromise lock(ScriptState*, const Vector<String>&, ExceptionState&);
void unlock(ScriptState*);
- ScriptPromise getLayoutMap(ScriptState*);
+ ScriptPromise getLayoutMap(ScriptState*, ExceptionState&);
// ScriptWrappable override.
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<KeyboardLock> keyboard_lock_;
diff --git a/chromium/third_party/blink/renderer/modules/keyboard/keyboard.idl b/chromium/third_party/blink/renderer/modules/keyboard/keyboard.idl
index 6e2bb694f71..70c53c1b4b2 100644
--- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard.idl
+++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard.idl
@@ -8,6 +8,7 @@
] interface Keyboard {
// Keyboard Lock specification: https://w3c.github.io/keyboard-lock/
[CallWith=ScriptState,
+ RaisesException,
MeasureAs=KeyboardApiLock
] Promise<void> lock(optional sequence<DOMString> keyCodes = []);
@@ -17,6 +18,7 @@
// Keyboard Map specification: https://wicg.github.io/keyboard-map/
[CallWith=ScriptState,
+ RaisesException,
HighEntropy,
MeasureAs=KeyboardApiGetLayoutMap
] Promise<KeyboardLayoutMap> getLayoutMap();
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 f787a3140df..6d2c8842157 100644
--- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.cc
+++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.cc
@@ -11,6 +11,7 @@
#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/local_frame.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"
@@ -30,9 +31,11 @@ constexpr char kKeyboardMapRequestFailedErrorMsg[] =
} // namespace
KeyboardLayout::KeyboardLayout(ExecutionContext* context)
- : ContextLifecycleObserver(context) {}
+ : ExecutionContextClient(context) {}
-ScriptPromise KeyboardLayout::GetKeyboardLayoutMap(ScriptState* script_state) {
+ScriptPromise KeyboardLayout::GetKeyboardLayoutMap(
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
DCHECK(script_state);
if (script_promise_resolver_) {
@@ -40,24 +43,21 @@ ScriptPromise KeyboardLayout::GetKeyboardLayoutMap(ScriptState* script_state) {
}
if (!IsLocalFrameAttached()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- kKeyboardMapFrameDetachedErrorMsg));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ kKeyboardMapFrameDetachedErrorMsg);
+ return ScriptPromise();
}
if (!CalledFromSupportedContext(ExecutionContext::From(script_state))) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- kKeyboardMapChildFrameErrorMsg));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ kKeyboardMapChildFrameErrorMsg);
+ return ScriptPromise();
}
if (!EnsureServiceConnected()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- kKeyboardMapRequestFailedErrorMsg));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ kKeyboardMapRequestFailedErrorMsg);
+ return ScriptPromise();
}
script_promise_resolver_ =
@@ -114,9 +114,9 @@ void KeyboardLayout::GotKeyboardLayoutMap(
script_promise_resolver_ = nullptr;
}
-void KeyboardLayout::Trace(blink::Visitor* visitor) {
+void KeyboardLayout::Trace(Visitor* visitor) {
visitor->Trace(script_promise_resolver_);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 c607f439b1f..4307f835b15 100644
--- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.h
+++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.h
@@ -10,25 +10,25 @@
#include "third_party/blink/public/mojom/keyboard_lock/keyboard_lock.mojom-blink.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/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/keyboard/keyboard_layout_map.h"
namespace blink {
+class ExceptionState;
class ScriptPromiseResolver;
class KeyboardLayout final : public GarbageCollected<KeyboardLayout>,
- public ContextLifecycleObserver {
+ public ExecutionContextClient {
USING_GARBAGE_COLLECTED_MIXIN(KeyboardLayout);
public:
explicit KeyboardLayout(ExecutionContext*);
virtual ~KeyboardLayout() = default;
- ScriptPromise GetKeyboardLayoutMap(ScriptState*);
+ ScriptPromise GetKeyboardLayoutMap(ScriptState*, ExceptionState&);
- // ContextLifecycleObserver override.
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 65911926ef3..bac1738b672 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 d6980c28019..007bda236b3 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,9 +25,7 @@ class KeyboardLayoutMap final : public ScriptWrappable,
// IDL attributes / methods
uint32_t size() const { return layout_map_.size(); }
- void Trace(blink::Visitor* visitor) override {
- ScriptWrappable::Trace(visitor);
- }
+ void Trace(Visitor* visitor) 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 575c8b87ecf..f07d057ebc3 100644
--- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.cc
+++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.cc
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.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/heap/persistent.h"
@@ -37,33 +38,31 @@ constexpr char kKeyboardLockRequestFailedErrorMsg[] =
} // namespace
KeyboardLock::KeyboardLock(ExecutionContext* context)
- : ContextLifecycleObserver(context) {}
+ : ExecutionContextClient(context) {}
KeyboardLock::~KeyboardLock() = default;
ScriptPromise KeyboardLock::lock(ScriptState* state,
- const Vector<String>& keycodes) {
+ const Vector<String>& keycodes,
+ ExceptionState& exception_state) {
DCHECK(state);
if (!IsLocalFrameAttached()) {
- return ScriptPromise::RejectWithDOMException(
- state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- kKeyboardLockFrameDetachedErrorMsg));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ kKeyboardLockFrameDetachedErrorMsg);
+ return ScriptPromise();
}
if (!CalledFromSupportedContext(ExecutionContext::From(state))) {
- return ScriptPromise::RejectWithDOMException(
- state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- kKeyboardLockChildFrameErrorMsg));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ kKeyboardLockChildFrameErrorMsg);
+ return ScriptPromise();
}
if (!EnsureServiceConnected()) {
- return ScriptPromise::RejectWithDOMException(
- state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- kKeyboardLockRequestFailedErrorMsg));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ kKeyboardLockRequestFailedErrorMsg);
+ return ScriptPromise();
}
request_keylock_resolver_ =
@@ -156,9 +155,9 @@ void KeyboardLock::LockRequestFinished(
request_keylock_resolver_ = nullptr;
}
-void KeyboardLock::Trace(blink::Visitor* visitor) {
+void KeyboardLock::Trace(Visitor* visitor) {
visitor->Trace(request_keylock_resolver_);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 ffee4473d70..34dfc20353f 100644
--- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.h
+++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.h
@@ -10,26 +10,26 @@
#include "third_party/blink/public/mojom/keyboard_lock/keyboard_lock.mojom-blink.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/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/member.h"
namespace blink {
+class ExceptionState;
class ScriptPromiseResolver;
class KeyboardLock final : public GarbageCollected<KeyboardLock>,
- public ContextLifecycleObserver {
+ public ExecutionContextClient {
USING_GARBAGE_COLLECTED_MIXIN(KeyboardLock);
public:
explicit KeyboardLock(ExecutionContext*);
~KeyboardLock();
- ScriptPromise lock(ScriptState*, const Vector<String>&);
+ ScriptPromise lock(ScriptState*, const Vector<String>&, ExceptionState&);
void unlock(ScriptState*);
- // ContextLifecycleObserver override.
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 55a9073870d..c0cc87c10d5 100644
--- a/chromium/third_party/blink/renderer/modules/keyboard/navigator_keyboard.cc
+++ b/chromium/third_party/blink/renderer/modules/keyboard/navigator_keyboard.cc
@@ -16,10 +16,12 @@ const char NavigatorKeyboard::kSupplementName[] = "NavigatorKeyboard";
NavigatorKeyboard::NavigatorKeyboard(Navigator& navigator)
: Supplement<Navigator>(navigator),
- keyboard_(MakeGarbageCollected<Keyboard>(
- GetSupplementable()->GetFrame()
- ? GetSupplementable()->GetFrame()->GetDocument()
- : nullptr)) {}
+ keyboard_(MakeGarbageCollected<Keyboard>(GetSupplementable()->GetFrame()
+ ? GetSupplementable()
+ ->GetFrame()
+ ->GetDocument()
+ ->ToExecutionContext()
+ : nullptr)) {}
// static
Keyboard* NavigatorKeyboard::keyboard(Navigator& navigator) {
@@ -32,7 +34,7 @@ Keyboard* NavigatorKeyboard::keyboard(Navigator& navigator) {
return supplement->keyboard_;
}
-void NavigatorKeyboard::Trace(blink::Visitor* visitor) {
+void NavigatorKeyboard::Trace(Visitor* visitor) {
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 428f662455f..332b0d24f38 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<Keyboard> keyboard_;
diff --git a/chromium/third_party/blink/renderer/modules/launch/BUILD.gn b/chromium/third_party/blink/renderer/modules/launch/BUILD.gn
index 86215df8940..a2bb71cae10 100644
--- a/chromium/third_party/blink/renderer/modules/launch/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/launch/BUILD.gn
@@ -8,6 +8,8 @@ blink_modules_sources("launch") {
sources = [
"dom_window_launch_queue.cc",
"dom_window_launch_queue.h",
+ "file_handling_expiry_impl.cc",
+ "file_handling_expiry_impl.h",
"launch_params.cc",
"launch_params.h",
"launch_queue.cc",
@@ -16,7 +18,5 @@ blink_modules_sources("launch") {
"web_launch_service_impl.h",
]
- deps = [
- "//third_party/blink/renderer/modules/filesystem",
- ]
+ deps = [ "//third_party/blink/renderer/modules/filesystem" ]
}
diff --git a/chromium/third_party/blink/renderer/modules/launch/OWNERS b/chromium/third_party/blink/renderer/modules/launch/OWNERS
index 83bfca70e9c..acce5878b91 100644
--- a/chromium/third_party/blink/renderer/modules/launch/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/launch/OWNERS
@@ -1,5 +1,5 @@
-harrisjay@chromium.org
-raymes@chromium.org
+dmurph@chromium.org
+mgiuca@chromium.org
# TEAM: web-apps-platform-team@chromium.org
-# COMPONENT: UI->Browser->WebAppInstalls \ No newline at end of file
+# COMPONENT: UI>Browser>WebAppInstalls
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 a7ef74a9ad0..03084803c8e 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
@@ -17,7 +17,6 @@ const char DOMWindowLaunchQueue::kSupplementName[] = "DOMWindowLaunchQueue";
DOMWindowLaunchQueue::DOMWindowLaunchQueue()
: launch_queue_(MakeGarbageCollected<LaunchQueue>()) {}
-DOMWindowLaunchQueue::~DOMWindowLaunchQueue() = default;
Member<LaunchQueue> DOMWindowLaunchQueue::launchQueue(LocalDOMWindow& window) {
return FromState(&window)->launch_queue_;
@@ -30,7 +29,7 @@ void DOMWindowLaunchQueue::UpdateLaunchFiles(
MakeGarbageCollected<LaunchParams>(std::move(files)));
}
-void DOMWindowLaunchQueue::Trace(blink::Visitor* visitor) {
+void DOMWindowLaunchQueue::Trace(Visitor* visitor) {
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 4990a78e758..1df758fedc9 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
@@ -29,7 +29,6 @@ class DOMWindowLaunchQueue final
static const char kSupplementName[];
explicit DOMWindowLaunchQueue();
- ~DOMWindowLaunchQueue();
// IDL Interface.
static Member<LaunchQueue> launchQueue(LocalDOMWindow&);
@@ -37,7 +36,7 @@ class DOMWindowLaunchQueue final
static void UpdateLaunchFiles(LocalDOMWindow*,
HeapVector<Member<NativeFileSystemHandle>>);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
static DOMWindowLaunchQueue* FromState(LocalDOMWindow* window);
diff --git a/chromium/third_party/blink/renderer/modules/launch/file_handling_expiry_impl.cc b/chromium/third_party/blink/renderer/modules/launch/file_handling_expiry_impl.cc
new file mode 100644
index 00000000000..bc06aee39ea
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/launch/file_handling_expiry_impl.cc
@@ -0,0 +1,50 @@
+// 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/launch/file_handling_expiry_impl.h"
+
+#include <memory>
+
+#include "mojo/public/cpp/bindings/self_owned_associated_receiver.h"
+#include "third_party/blink/public/mojom/native_file_system/native_file_system_directory_handle.mojom-blink.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/origin_trials/origin_trial_context.h"
+#include "third_party/blink/renderer/core/script/script.h"
+#include "third_party/blink/renderer/modules/launch/dom_window_launch_queue.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/wtf/text/string_utf8_adaptor.h"
+
+namespace blink {
+
+void FileHandlingExpiryImpl::Create(
+ LocalFrame* frame,
+ mojo::PendingAssociatedReceiver<mojom::blink::FileHandlingExpiry>
+ receiver) {
+ DCHECK(frame);
+
+ mojo::MakeSelfOwnedAssociatedReceiver(
+ std::make_unique<FileHandlingExpiryImpl>(*frame->DomWindow()),
+ std::move(receiver));
+}
+
+FileHandlingExpiryImpl::FileHandlingExpiryImpl(LocalDOMWindow& window)
+ : window_(window) {}
+
+FileHandlingExpiryImpl::~FileHandlingExpiryImpl() = default;
+
+void FileHandlingExpiryImpl::RequestOriginTrialExpiryTime(
+ RequestOriginTrialExpiryTimeCallback callback) {
+ if (!window_)
+ return;
+
+ auto* origin_trials = window_->GetExecutionContext()->GetOriginTrialContext();
+
+ base::Time expiry_time =
+ origin_trials->GetFeatureExpiry(OriginTrialFeature::kFileHandling);
+ std::move(callback).Run(expiry_time);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/launch/file_handling_expiry_impl.h b/chromium/third_party/blink/renderer/modules/launch/file_handling_expiry_impl.h
new file mode 100644
index 00000000000..0f6c7b63113
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/launch/file_handling_expiry_impl.h
@@ -0,0 +1,41 @@
+// 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_LAUNCH_FILE_HANDLING_EXPIRY_IMPL_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_LAUNCH_FILE_HANDLING_EXPIRY_IMPL_H_
+
+#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
+#include "third_party/blink/public/mojom/web_launch/file_handling_expiry.mojom-blink.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace blink {
+
+class LocalFrame;
+class LocalDOMWindow;
+
+// Implementation of FileHandlingExpiry service, to allow the browser to query
+// the expiry time of the file handling origin trial for a Document.
+class MODULES_EXPORT FileHandlingExpiryImpl final
+ : public mojom::blink::FileHandlingExpiry {
+ public:
+ static void Create(
+ LocalFrame* frame,
+ mojo::PendingAssociatedReceiver<mojom::blink::FileHandlingExpiry>);
+ explicit FileHandlingExpiryImpl(LocalDOMWindow& frame);
+ ~FileHandlingExpiryImpl() override;
+
+ // blink::mojom::FileHandlingExpiry:
+ void RequestOriginTrialExpiryTime(
+ RequestOriginTrialExpiryTimeCallback callback) override;
+
+ private:
+ WeakPersistent<LocalDOMWindow> window_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_LAUNCH_FILE_HANDLING_EXPIRY_IMPL_H_
diff --git a/chromium/third_party/blink/renderer/modules/launch/idls.gni b/chromium/third_party/blink/renderer/modules/launch/idls.gni
new file mode 100644
index 00000000000..0719af46060
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/launch/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "launch_params.idl",
+ "launch_queue.idl",
+]
+
+modules_dependency_idl_files = [ "dom_window_launch_queue.idl" ]
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 280f67a9deb..e90b0d00099 100644
--- a/chromium/third_party/blink/renderer/modules/launch/launch_params.cc
+++ b/chromium/third_party/blink/renderer/modules/launch/launch_params.cc
@@ -4,9 +4,6 @@
#include "third_party/blink/renderer/modules/launch/launch_params.h"
-#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
-#include "third_party/blink/renderer/core/fetch/fetch_request_data.h"
-#include "third_party/blink/renderer/core/fetch/request.h"
#include "third_party/blink/renderer/modules/native_file_system/native_file_system_handle.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
@@ -17,22 +14,8 @@ LaunchParams::LaunchParams(HeapVector<Member<NativeFileSystemHandle>> files)
LaunchParams::~LaunchParams() = default;
-Request* LaunchParams::request(ScriptState* script_state) {
- if (!fetch_request_)
- return nullptr;
-
- if (!request_) {
- request_ =
- Request::Create(script_state, *fetch_request_.get(),
- FetchRequestData::ForServiceWorkerFetchEvent::kFalse);
- }
-
- return request_;
-}
-
-void LaunchParams::Trace(blink::Visitor* visitor) {
+void LaunchParams::Trace(Visitor* visitor) {
visitor->Trace(files_);
- visitor->Trace(request_);
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 7e958c12be7..44c12302404 100644
--- a/chromium/third_party/blink/renderer/modules/launch/launch_params.h
+++ b/chromium/third_party/blink/renderer/modules/launch/launch_params.h
@@ -5,17 +5,13 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_LAUNCH_LAUNCH_PARAMS_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_LAUNCH_LAUNCH_PARAMS_H_
-#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/renderer/modules/native_file_system/native_file_system_handle.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/heap/heap_allocator.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
-class Request;
-class ScriptState;
class Visitor;
class LaunchParams final : public ScriptWrappable {
@@ -27,14 +23,11 @@ class LaunchParams final : public ScriptWrappable {
// LaunchParams IDL interface.
const HeapVector<Member<NativeFileSystemHandle>>& files() { return files_; }
- Request* request(ScriptState* script_state);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
HeapVector<Member<NativeFileSystemHandle>> files_;
- Member<Request> request_;
- mojom::blink::FetchAPIRequestPtr fetch_request_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/launch/launch_params.idl b/chromium/third_party/blink/renderer/modules/launch/launch_params.idl
index 71027b12d90..2d98f3efeb1 100644
--- a/chromium/third_party/blink/renderer/modules/launch/launch_params.idl
+++ b/chromium/third_party/blink/renderer/modules/launch/launch_params.idl
@@ -7,7 +7,4 @@
[RuntimeEnabled=FileHandling] interface LaunchParams {
readonly attribute FrozenArray<FileSystemHandle> files;
-
- [CallWith=ScriptState]
- readonly attribute Request request;
};
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 b4037793f11..b683f1e21d1 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(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
HeapVector<Member<LaunchParams>> unconsumed_launch_params_;
diff --git a/chromium/third_party/blink/renderer/modules/locks/idls.gni b/chromium/third_party/blink/renderer/modules/locks/idls.gni
new file mode 100644
index 00000000000..7c94c5f9329
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/locks/idls.gni
@@ -0,0 +1,19 @@
+# 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 = [
+ "lock.idl",
+ "lock_manager.idl",
+]
+
+modules_dictionary_idl_files = [
+ "lock_info.idl",
+ "lock_manager_snapshot.idl",
+ "lock_options.idl",
+]
+
+modules_dependency_idl_files = [
+ "navigator_locks.idl",
+ "worker_navigator_locks.idl",
+]
diff --git a/chromium/third_party/blink/renderer/modules/locks/lock.cc b/chromium/third_party/blink/renderer/modules/locks/lock.cc
index 34943772aa2..2a9a884d8ed 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(lock_);
ScriptFunction::Trace(visitor);
}
@@ -61,26 +61,17 @@ class Lock::ThenFunction final : public ScriptFunction {
ResolveType resolve_type_;
};
-// static
-Lock* Lock::Create(
- ScriptState* script_state,
- const String& name,
- mojom::blink::LockMode mode,
- mojo::PendingAssociatedRemote<mojom::blink::LockHandle> handle,
- LockManager* manager) {
- return MakeGarbageCollected<Lock>(script_state, name, mode, std::move(handle),
- manager);
-}
-
Lock::Lock(ScriptState* script_state,
const String& name,
mojom::blink::LockMode mode,
mojo::PendingAssociatedRemote<mojom::blink::LockHandle> handle,
+ mojo::PendingRemote<mojom::blink::ObservedFeature> lock_lifetime,
LockManager* manager)
- : ContextLifecycleObserver(ExecutionContext::From(script_state)),
+ : ExecutionContextLifecycleObserver(ExecutionContext::From(script_state)),
name_(name),
mode_(mode),
handle_(std::move(handle)),
+ lock_lifetime_(std::move(lock_lifetime)),
manager_(manager) {
handle_.set_disconnect_handler(
WTF::Bind(&Lock::OnConnectionError, WrapWeakPersistent(this)));
@@ -129,12 +120,12 @@ String Lock::ModeToString(mojom::blink::LockMode mode) {
return g_empty_string;
}
-void Lock::ContextDestroyed(ExecutionContext* context) {
+void Lock::ContextDestroyed() {
ReleaseIfHeld();
}
-void Lock::Trace(blink::Visitor* visitor) {
- ContextLifecycleObserver::Trace(visitor);
+void Lock::Trace(Visitor* visitor) {
+ ExecutionContextLifecycleObserver::Trace(visitor);
ScriptWrappable::Trace(visitor);
visitor->Trace(resolver_);
visitor->Trace(manager_);
@@ -145,12 +136,15 @@ void Lock::ReleaseIfHeld() {
// Drop the mojo pipe; this releases the lock on the back end.
handle_.reset();
+ lock_lifetime_.reset();
+
// Let the lock manager know that this instance can be collected.
manager_->OnLockReleased(this);
}
}
void Lock::OnConnectionError() {
+ ReleaseIfHeld();
resolver_->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kAbortError,
"Lock broken by another request with the 'steal' option."));
diff --git a/chromium/third_party/blink/renderer/modules/locks/lock.h b/chromium/third_party/blink/renderer/modules/locks/lock.h
index 9578c2d894c..6851d710382 100644
--- a/chromium/third_party/blink/renderer/modules/locks/lock.h
+++ b/chromium/third_party/blink/renderer/modules/locks/lock.h
@@ -6,8 +6,10 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_LOCKS_LOCK_H_
#include "mojo/public/cpp/bindings/associated_remote.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/blink/public/mojom/feature_observer/feature_observer.mojom-blink.h"
#include "third_party/blink/public/mojom/locks/lock_manager.mojom-blink.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/wtf/text/wtf_string.h"
@@ -20,25 +22,21 @@ class ScriptPromise;
class ScriptPromiseResolver;
class ScriptState;
-class Lock final : public ScriptWrappable, public ContextLifecycleObserver {
+class Lock final : public ScriptWrappable,
+ public ExecutionContextLifecycleObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(Lock);
USING_PRE_FINALIZER(Lock, Dispose);
public:
- static Lock* Create(ScriptState*,
- const String& name,
- mojom::blink::LockMode,
- mojo::PendingAssociatedRemote<mojom::blink::LockHandle>,
- LockManager*);
-
Lock(ScriptState*,
const String& name,
mojom::blink::LockMode,
mojo::PendingAssociatedRemote<mojom::blink::LockHandle>,
+ mojo::PendingRemote<mojom::blink::ObservedFeature>,
LockManager*);
~Lock() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void Dispose();
@@ -46,8 +44,8 @@ class Lock final : public ScriptWrappable, public ContextLifecycleObserver {
String name() const { return name_; }
String mode() const;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
// The lock is held until the passed promise resolves. When it is released,
// the passed resolver is invoked with the promise's result.
@@ -72,6 +70,8 @@ class Lock final : public ScriptWrappable, public ContextLifecycleObserver {
// the lock is released by the back end.
mojo::AssociatedRemote<mojom::blink::LockHandle> handle_;
+ mojo::Remote<mojom::blink::ObservedFeature> lock_lifetime_;
+
// LockManager::OnLockReleased() is called when this lock is released, to
// stop artificially keeping this instance alive. It is necessary in the
// case where the resolver's promise could potentially be GC'd.
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 defb5afde20..badfb8ee249 100644
--- a/chromium/third_party/blink/renderer/modules/locks/lock_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/locks/lock_manager.cc
@@ -13,6 +13,8 @@
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_lock_granted_callback.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_lock_info.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_lock_manager_snapshot.h"
#include "third_party/blink/renderer/core/dom/abort_signal.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
@@ -20,8 +22,6 @@
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/modules/locks/lock.h"
-#include "third_party/blink/renderer/modules/locks/lock_info.h"
-#include "third_party/blink/renderer/modules/locks/lock_manager_snapshot.h"
#include "third_party/blink/renderer/platform/bindings/microtask.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
@@ -43,7 +43,6 @@ constexpr char kRequestAbortedMessage[] = "The request was aborted.";
LockInfo* ToLockInfo(const mojom::blink::LockInfoPtr& record) {
LockInfo* info = LockInfo::Create();
- ;
info->setMode(Lock::ModeToString(record->mode));
info->setName(record->name);
info->setClientId(record->client_id);
@@ -74,6 +73,7 @@ class LockManager::LockRequestImpl final
const String& name,
mojom::blink::LockMode mode,
mojo::PendingAssociatedReceiver<mojom::blink::LockRequest> receiver,
+ mojo::PendingRemote<mojom::blink::ObservedFeature> lock_lifetime,
LockManager* manager)
: callback_(callback),
resolver_(resolver),
@@ -83,6 +83,7 @@ class LockManager::LockRequestImpl final
this,
std::move(receiver),
manager->GetExecutionContext()->GetTaskRunner(TaskType::kWebLocks)),
+ lock_lifetime_(std::move(lock_lifetime)),
manager_(manager) {}
~LockRequestImpl() override = default;
@@ -93,7 +94,7 @@ class LockManager::LockRequestImpl final
receiver_.reset();
}
- void Trace(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
visitor->Trace(resolver_);
visitor->Trace(manager_);
visitor->Trace(callback_);
@@ -159,8 +160,9 @@ class LockManager::LockRequestImpl final
return;
}
- Lock* lock = Lock::Create(script_state, name_, mode_,
- std::move(handle_remote), manager_);
+ Lock* lock = MakeGarbageCollected<Lock>(
+ script_state, name_, mode_, std::move(handle_remote),
+ std::move(lock_lifetime_), manager_);
manager_->held_locks_.insert(lock);
ScriptState::Scope scope(script_state);
@@ -192,6 +194,10 @@ class LockManager::LockRequestImpl final
mojo::AssociatedReceiver<mojom::blink::LockRequest> receiver_;
+ // Held to pass into the Lock if granted, to inform the browser that
+ // WebLocks are being used by this frame.
+ mojo::PendingRemote<mojom::blink::ObservedFeature> lock_lifetime_;
+
// The |manager_| keeps |this| alive until a response comes in and this is
// registered. If the context is destroyed then |manager_| will dispose of
// |this| which terminates the request on the service side.
@@ -201,7 +207,9 @@ class LockManager::LockRequestImpl final
};
LockManager::LockManager(ExecutionContext* context)
- : ContextLifecycleObserver(context) {}
+ : ExecutionContextLifecycleObserver(context),
+ service_(context),
+ observer_(context) {}
ScriptPromise LockManager::request(ScriptState* script_state,
const String& name,
@@ -249,6 +257,11 @@ ScriptPromise LockManager::request(ScriptState* script_state,
return ScriptPromise();
}
}
+ if (!observer_.is_bound()) {
+ context->GetBrowserInterfaceBroker().GetInterface(
+ observer_.BindNewPipeAndPassReceiver(
+ context->GetTaskRunner(TaskType::kMiscPlatformAPI)));
+ }
mojom::blink::LockMode mode = Lock::StringToMode(options->mode());
@@ -314,6 +327,10 @@ ScriptPromise LockManager::request(ScriptState* script_state,
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
+ mojo::PendingRemote<mojom::blink::ObservedFeature> lock_lifetime;
+ observer_->Register(lock_lifetime.InitWithNewPipeAndPassReceiver(),
+ mojom::blink::ObservedFeatureType::kWebLock);
+
mojo::PendingAssociatedRemote<mojom::blink::LockRequest> request_remote;
// 11.1. Let request be the result of running the steps to request a lock with
// promise, the current agent, environment’s id, origin, callback, name,
@@ -321,7 +338,8 @@ ScriptPromise LockManager::request(ScriptState* script_state,
// and options’ steal dictionary member.
LockRequestImpl* request = MakeGarbageCollected<LockRequestImpl>(
callback, resolver, name, mode,
- request_remote.InitWithNewEndpointAndPassReceiver(), this);
+ request_remote.InitWithNewEndpointAndPassReceiver(),
+ std::move(lock_lifetime), this);
AddPendingRequest(request);
// 11.2. If options’ signal dictionary member is present, then add the
@@ -400,14 +418,16 @@ bool LockManager::IsPendingRequest(LockRequestImpl* request) {
return pending_requests_.Contains(request);
}
-void LockManager::Trace(blink::Visitor* visitor) {
+void LockManager::Trace(Visitor* visitor) {
ScriptWrappable::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
visitor->Trace(pending_requests_);
visitor->Trace(held_locks_);
+ visitor->Trace(service_);
+ visitor->Trace(observer_);
}
-void LockManager::ContextDestroyed(ExecutionContext*) {
+void LockManager::ContextDestroyed() {
for (auto request : pending_requests_)
request->Cancel();
pending_requests_.clear();
@@ -426,7 +446,7 @@ bool LockManager::AllowLocks(ScriptState* script_state) {
DCHECK(execution_context->IsContextThread());
SECURITY_DCHECK(execution_context->IsDocument() ||
execution_context->IsWorkerGlobalScope());
- if (auto* document = DynamicTo<Document>(execution_context)) {
+ if (auto* document = Document::DynamicFrom(execution_context)) {
LocalFrame* frame = document->GetFrame();
if (!frame) {
cached_allowed_ = false;
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 cd16cc41252..98e86bbbb7b 100644
--- a/chromium/third_party/blink/renderer/modules/locks/lock_manager.h
+++ b/chromium/third_party/blink/renderer/modules/locks/lock_manager.h
@@ -7,14 +7,16 @@
#include "base/macros.h"
#include "base/optional.h"
-#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/blink/public/mojom/feature_observer/feature_observer.mojom-blink.h"
#include "third_party/blink/public/mojom/locks/lock_manager.mojom-blink-forward.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_string_sequence.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_lock_options.h"
#include "third_party/blink/renderer/modules/locks/lock.h"
-#include "third_party/blink/renderer/modules/locks/lock_options.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/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"
namespace blink {
@@ -23,7 +25,7 @@ class ScriptState;
class V8LockGrantedCallback;
class LockManager final : public ScriptWrappable,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(LockManager);
@@ -42,11 +44,11 @@ class LockManager final : public ScriptWrappable,
ScriptPromise query(ScriptState*, ExceptionState&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// Terminate all outstanding requests when the context is destroyed, since
// this can unblock requests by other contexts.
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
// Called by a lock when it is released. The lock is dropped from the
// |held_locks_| list. Held locks are tracked until explicitly released (or
@@ -73,7 +75,12 @@ class LockManager final : public ScriptWrappable,
HeapHashSet<Member<LockRequestImpl>> pending_requests_;
HeapHashSet<Member<Lock>> held_locks_;
- mojo::Remote<mojom::blink::LockManager> service_;
+ HeapMojoRemote<mojom::blink::LockManager,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ service_;
+ HeapMojoRemote<mojom::blink::FeatureObserver,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ observer_;
base::Optional<bool> cached_allowed_;
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 52b745c9feb..f7e7d1f91a3 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(lock_manager_);
Supplement<T>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/manifest/OWNERS b/chromium/third_party/blink/renderer/modules/manifest/OWNERS
index a7f05af7429..5275d5cf7ce 100644
--- a/chromium/third_party/blink/renderer/modules/manifest/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/manifest/OWNERS
@@ -5,4 +5,4 @@ mlamouri@chromium.org
per-file *_type_converter*.*=set noparent
per-file *_type_converter*.*=file://ipc/SECURITY_OWNERS
-# COMPONENT: Manifest
+# Component: Blink>AppManifest
diff --git a/chromium/third_party/blink/renderer/modules/manifest/idls.gni b/chromium/third_party/blink/renderer/modules/manifest/idls.gni
new file mode 100644
index 00000000000..21793946376
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/manifest/idls.gni
@@ -0,0 +1,5 @@
+# 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_dictionary_idl_files = [ "image_resource.idl" ]
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 9dcb4d6fb6c..1fe95c562e8 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
@@ -10,7 +10,7 @@
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_vector.h"
-#include "third_party/blink/renderer/modules/manifest/image_resource.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_image_resource.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -26,18 +26,18 @@ using blink::WebString;
using blink::WebVector;
// https://w3c.github.io/manifest/#sizes-member.
-WTF::Vector<WebSize> ParseSizes(const WTF::String& sizes) {
- WebVector<WebSize> parsed_sizes = blink::WebIconSizesParser::ParseIconSizes(
+WTF::Vector<gfx::Size> ParseSizes(const WTF::String& sizes) {
+ WebVector<gfx::Size> parsed_sizes = blink::WebIconSizesParser::ParseIconSizes(
WebString::FromASCII(sizes.Ascii()));
WTF::HashSet<std::pair<int, int>, WTF::PairHash<int, int>,
WTF::PairHashTraits<WTF::UnsignedWithZeroKeyHashTraits<int>,
WTF::UnsignedWithZeroKeyHashTraits<int>>>
unique_sizes;
- WTF::Vector<WebSize> results;
+ WTF::Vector<gfx::Size> results;
for (const auto& size : parsed_sizes) {
auto add_result =
- unique_sizes.insert(std::make_pair(size.width, size.height));
+ unique_sizes.insert(std::make_pair(size.width(), size.height()));
if (add_result.is_new_entry) {
results.push_back(size);
}
@@ -138,9 +138,9 @@ Manifest::ImageResource ConvertManifestImageResource(
}
}
// Parse 'sizes'.
- WTF::Vector<WebSize> sizes = mojo::ParseSizes(icon->sizes());
+ WTF::Vector<gfx::Size> sizes = mojo::ParseSizes(icon->sizes());
for (const auto& size : sizes) {
- manifest_icon.sizes.emplace_back(gfx::Size(size.height, size.width));
+ manifest_icon.sizes.emplace_back(size);
}
return manifest_icon;
diff --git a/chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters_test.cc b/chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters_test.cc
index 53c9a706844..03198a47151 100644
--- a/chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters_test.cc
+++ b/chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters_test.cc
@@ -8,7 +8,7 @@
#include "third_party/blink/public/mojom/manifest/manifest.mojom-blink.h"
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/renderer/modules/manifest/image_resource.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_image_resource.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -19,7 +19,6 @@ namespace {
using Purpose = blink::mojom::blink::ManifestImageResource::Purpose;
using blink::mojom::blink::ManifestImageResource;
using blink::mojom::blink::ManifestImageResourcePtr;
-using blink::WebSize;
TEST(ImageResourceConverter, EmptySizesTest) {
blink::ManifestImageResource* resource =
@@ -41,40 +40,40 @@ TEST(ImageResourceConverter, ValidSizesTest) {
resource->setSizes("2x3");
ManifestImageResourcePtr converted = ManifestImageResource::From(resource);
ASSERT_EQ(converted->sizes.size(), 1u);
- EXPECT_EQ(converted->sizes.front(), WebSize(2, 3));
+ EXPECT_EQ(converted->sizes.front(), gfx::Size(2, 3));
resource->setSizes("42X24");
converted = ManifestImageResource::From(resource);
ASSERT_EQ(converted->sizes.size(), 1u);
- EXPECT_EQ(converted->sizes.front(), WebSize(42, 24));
+ EXPECT_EQ(converted->sizes.front(), gfx::Size(42, 24));
resource->setSizes("any");
converted = ManifestImageResource::From(resource);
ASSERT_EQ(converted->sizes.size(), 1u);
- EXPECT_EQ(converted->sizes.front(), WebSize(0, 0));
+ EXPECT_EQ(converted->sizes.front(), gfx::Size(0, 0));
resource->setSizes("ANY");
converted = ManifestImageResource::From(resource);
ASSERT_EQ(converted->sizes.size(), 1u);
- EXPECT_EQ(converted->sizes.front(), WebSize(0, 0));
+ EXPECT_EQ(converted->sizes.front(), gfx::Size(0, 0));
resource->setSizes("2x2 4x4");
converted = ManifestImageResource::From(resource);
ASSERT_EQ(converted->sizes.size(), 2u);
- EXPECT_EQ(converted->sizes.front(), WebSize(2, 2));
- EXPECT_EQ(converted->sizes.back(), WebSize(4, 4));
+ EXPECT_EQ(converted->sizes.front(), gfx::Size(2, 2));
+ EXPECT_EQ(converted->sizes.back(), gfx::Size(4, 4));
resource->setSizes("2x2 4x4 2x2");
converted = ManifestImageResource::From(resource);
ASSERT_EQ(2u, converted->sizes.size());
- EXPECT_EQ(WebSize(2, 2), converted->sizes.front());
- EXPECT_EQ(WebSize(4, 4), converted->sizes.back());
+ EXPECT_EQ(gfx::Size(2, 2), converted->sizes.front());
+ EXPECT_EQ(gfx::Size(4, 4), converted->sizes.back());
resource->setSizes(" 2x2 any");
converted = ManifestImageResource::From(resource);
ASSERT_EQ(2u, converted->sizes.size());
- EXPECT_EQ(WebSize(2, 2), converted->sizes.front());
- EXPECT_EQ(WebSize(0, 0), converted->sizes.back());
+ EXPECT_EQ(gfx::Size(2, 2), converted->sizes.front());
+ EXPECT_EQ(gfx::Size(0, 0), converted->sizes.back());
}
TEST(ImageResourceConverter, InvalidSizesTest) {
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 770cb163f05..a280ca3c472 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(LocalFrame& frame);
virtual ~ManifestChangeNotifier();
- virtual void Trace(blink::Visitor*);
+ virtual void Trace(Visitor*);
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 f38899dd5c0..c5c6ed6d974 100644
--- a/chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc
+++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc
@@ -33,8 +33,8 @@ void ManifestFetcher::Start(Document& document,
ResourceLoaderOptions resource_loader_options;
resource_loader_options.data_buffering_policy = kDoNotBufferData;
- loader_ = MakeGarbageCollected<ThreadableLoader>(document, this,
- resource_loader_options);
+ loader_ = MakeGarbageCollected<ThreadableLoader>(
+ *document.ToExecutionContext(), this, resource_loader_options);
loader_->Start(request);
}
@@ -88,7 +88,7 @@ void ManifestFetcher::DidFailRedirectCheck() {
DidFail(ResourceError::Failure(NullURL()));
}
-void ManifestFetcher::Trace(blink::Visitor* visitor) {
+void ManifestFetcher::Trace(Visitor* visitor) {
visitor->Trace(loader_);
ThreadableLoaderClient::Trace(visitor);
}
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 6284ad9b0c8..db4f04f3e34 100644
--- a/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.cc
@@ -19,6 +19,7 @@
#include "third_party/blink/renderer/modules/manifest/manifest_parser.h"
#include "third_party/blink/renderer/modules/manifest/manifest_type_converters.h"
#include "third_party/blink/renderer/modules/manifest/manifest_uma_util.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
namespace blink {
@@ -49,9 +50,10 @@ void ManifestManager::ProvideTo(LocalFrame& frame) {
ManifestManager::ManifestManager(LocalFrame& frame)
: Supplement<LocalFrame>(frame),
- ContextLifecycleObserver(frame.GetDocument()),
+ ExecutionContextLifecycleObserver(frame.GetDocument()),
may_have_manifest_(false),
- manifest_dirty_(true) {
+ manifest_dirty_(true),
+ receivers_(GetExecutionContext()) {
if (frame.IsMainFrame()) {
manifest_change_notifier_ =
MakeGarbageCollected<ManifestChangeNotifier>(frame);
@@ -81,6 +83,9 @@ void ManifestManager::RequestManifestDebugInfo(
const mojom::blink::ManifestPtr& manifest,
const mojom::blink::ManifestDebugInfo* debug_info) {
std::move(callback).Run(manifest_url,
+ manifest.is_null()
+ ? mojom::blink::Manifest::New()
+ : manifest->Clone(),
debug_info ? debug_info->Clone() : nullptr);
},
std::move(callback)));
@@ -191,11 +196,12 @@ void ManifestManager::OnManifestFetchComplete(const KURL& document_url,
auto location = std::make_unique<SourceLocation>(
ManifestURL().GetString(), error->line, error->column, nullptr, 0);
- GetSupplementable()->Console().AddMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kOther,
- error->critical ? mojom::ConsoleMessageLevel::kError
- : mojom::ConsoleMessageLevel::kWarning,
- "Manifest: " + error->message, std::move(location)));
+ GetSupplementable()->Console().AddMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kOther,
+ error->critical ? mojom::ConsoleMessageLevel::kError
+ : mojom::ConsoleMessageLevel::kWarning,
+ "Manifest: " + error->message, std::move(location)));
}
// Having errors while parsing the manifest doesn't mean the manifest parsing
@@ -251,10 +257,13 @@ bool ManifestManager::ManifestUseCredentials() const {
void ManifestManager::BindReceiver(
mojo::PendingReceiver<mojom::blink::ManifestManager> receiver) {
- receivers_.Add(this, std::move(receiver));
+ receivers_.Add(
+ this, std::move(receiver),
+ GetSupplementable()->GetDocument()->ToExecutionContext()->GetTaskRunner(
+ TaskType::kNetworking));
}
-void ManifestManager::ContextDestroyed(ExecutionContext*) {
+void ManifestManager::ContextDestroyed() {
if (fetcher_)
fetcher_->Cancel();
@@ -262,19 +271,14 @@ void ManifestManager::ContextDestroyed(ExecutionContext*) {
// will be aware of the RenderFrame dying and should act on that. Consumers
// in the renderer process should be correctly notified.
ResolveCallbacks(ResolveStateFailure);
-
- receivers_.Clear();
-}
-
-void ManifestManager::Prefinalize() {
- receivers_.Clear();
}
-void ManifestManager::Trace(blink::Visitor* visitor) {
+void ManifestManager::Trace(Visitor* visitor) {
visitor->Trace(fetcher_);
visitor->Trace(manifest_change_notifier_);
+ visitor->Trace(receivers_);
Supplement<LocalFrame>::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 9f40633d078..7aee0af26e7 100644
--- a/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.h
+++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.h
@@ -12,10 +12,11 @@
#include "third_party/blink/public/mojom/manifest/manifest.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/manifest/manifest_manager.mojom-blink.h"
#include "third_party/blink/public/web/web_manifest_manager.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/heap/member.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set.h"
#include "third_party/blink/renderer/platform/supplementable.h"
namespace blink {
@@ -30,12 +31,12 @@ class ResourceResponse;
// the ManifestParser in order to do so.
//
// Consumers should use the mojo ManifestManager interface to use this class.
-class MODULES_EXPORT ManifestManager : public GarbageCollected<ManifestManager>,
- public Supplement<LocalFrame>,
- public mojom::blink::ManifestManager,
- public ContextLifecycleObserver {
+class MODULES_EXPORT ManifestManager
+ : public GarbageCollected<ManifestManager>,
+ public Supplement<LocalFrame>,
+ public mojom::blink::ManifestManager,
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(ManifestManager);
- USING_PRE_FINALIZER(ManifestManager, Prefinalize);
public:
static const char kSupplementName[];
@@ -61,7 +62,7 @@ class MODULES_EXPORT ManifestManager : public GarbageCollected<ManifestManager>,
void RequestManifestDebugInfo(
RequestManifestDebugInfoCallback callback) override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
enum ResolveState { ResolveStateSuccess, ResolveStateFailure };
@@ -71,8 +72,8 @@ class MODULES_EXPORT ManifestManager : public GarbageCollected<ManifestManager>,
const mojom::blink::ManifestPtr&,
const mojom::blink::ManifestDebugInfo*)>;
- // From ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // From ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
void RequestManifestImpl(InternalRequestManifestCallback callback);
@@ -85,8 +86,6 @@ class MODULES_EXPORT ManifestManager : public GarbageCollected<ManifestManager>,
void BindReceiver(
mojo::PendingReceiver<mojom::blink::ManifestManager> receiver);
- void Prefinalize();
-
friend class ManifestManagerTest;
Member<ManifestFetcher> fetcher_;
@@ -112,7 +111,7 @@ class MODULES_EXPORT ManifestManager : public GarbageCollected<ManifestManager>,
Vector<InternalRequestManifestCallback> pending_callbacks_;
- mojo::ReceiverSet<mojom::blink::ManifestManager> receivers_;
+ HeapMojoReceiverSet<mojom::blink::ManifestManager> receivers_;
DISALLOW_COPY_AND_ASSIGN(ManifestManager);
};
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 1a168633ffb..ecd54713a6d 100644
--- a/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.cc
+++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.cc
@@ -99,6 +99,7 @@ void ManifestParser::Parse() {
manifest_->background_color = *background_color;
manifest_->gcm_sender_id = ParseGCMSenderID(root_object.get());
+ manifest_->shortcuts = ParseShortcuts(root_object.get());
ManifestUmaUtil::ParseSucceeded(manifest_);
}
@@ -151,6 +152,41 @@ base::Optional<String> ManifestParser::ParseString(const JSONObject* object,
return value;
}
+base::Optional<String> ManifestParser::ParseStringForMember(
+ const JSONObject* object,
+ const String& member_name,
+ const String& key,
+ bool required,
+ TrimType trim) {
+ JSONValue* json_value = object->Get(key);
+ if (!json_value) {
+ if (required) {
+ AddErrorInfo("property '" + key + "' of '" + member_name +
+ "' not present.");
+ }
+
+ return base::nullopt;
+ }
+
+ String value;
+ if (!json_value->AsString(&value)) {
+ AddErrorInfo("property '" + key + "' of '" + member_name +
+ "' ignored, type string expected.");
+ return base::nullopt;
+ }
+ if (trim == TrimType::Trim)
+ value = value.StripWhiteSpace();
+
+ if (value == "") {
+ AddErrorInfo("property '" + key + "' of '" + member_name +
+ "' is an empty string.");
+ if (required)
+ return base::nullopt;
+ }
+
+ return value;
+}
+
base::Optional<RGBA32> ManifestParser::ParseColor(const JSONObject* object,
const String& key) {
base::Optional<String> parsed_color = ParseString(object, key, Trim);
@@ -274,14 +310,14 @@ String ManifestParser::ParseIconType(const JSONObject* icon) {
return type.has_value() ? *type : String("");
}
-Vector<WebSize> ManifestParser::ParseIconSizes(const JSONObject* icon) {
+Vector<gfx::Size> ManifestParser::ParseIconSizes(const JSONObject* icon) {
base::Optional<String> sizes_str = ParseString(icon, "sizes", NoTrim);
if (!sizes_str.has_value())
- return Vector<WebSize>();
+ return Vector<gfx::Size>();
- WebVector<WebSize> web_sizes =
+ WebVector<gfx::Size> web_sizes =
WebIconSizesParser::ParseIconSizes(WebString(*sizes_str));
- Vector<WebSize> sizes;
+ Vector<gfx::Size> sizes;
for (auto& size : web_sizes)
sizes.push_back(size);
@@ -383,6 +419,81 @@ Vector<mojom::blink::ManifestImageResourcePtr> ManifestParser::ParseIcons(
return icons;
}
+String ManifestParser::ParseShortcutName(const JSONObject* shortcut) {
+ base::Optional<String> name =
+ ParseStringForMember(shortcut, "shortcut", "name", true, Trim);
+ return name.has_value() ? *name : String();
+}
+
+String ManifestParser::ParseShortcutShortName(const JSONObject* shortcut) {
+ base::Optional<String> short_name =
+ ParseStringForMember(shortcut, "shortcut", "short_name", false, Trim);
+ return short_name.has_value() ? *short_name : String();
+}
+
+String ManifestParser::ParseShortcutDescription(const JSONObject* shortcut) {
+ base::Optional<String> description =
+ ParseStringForMember(shortcut, "shortcut", "description", false, Trim);
+ return description.has_value() ? *description : String();
+}
+
+KURL ManifestParser::ParseShortcutUrl(const JSONObject* shortcut) {
+ KURL shortcut_url = ParseURL(shortcut, "url", manifest_url_,
+ ParseURLOriginRestrictions::kSameOriginOnly);
+ if (shortcut_url.IsNull()) {
+ AddErrorInfo("property 'url' of 'shortcut' not present.");
+ } else if (!shortcut_url.GetString().StartsWith(
+ manifest_->scope.GetString())) {
+ AddErrorInfo(
+ "property 'url' of 'shortcut' ignored. url should be within scope of "
+ "the manifest.");
+ return KURL();
+ }
+
+ return shortcut_url;
+}
+
+Vector<mojom::blink::ManifestShortcutItemPtr> ManifestParser::ParseShortcuts(
+ const JSONObject* object) {
+ Vector<mojom::blink::ManifestShortcutItemPtr> shortcuts;
+ JSONValue* json_value = object->Get("shortcuts");
+ if (!json_value)
+ return shortcuts;
+
+ JSONArray* shortcuts_list = object->GetArray("shortcuts");
+ if (!shortcuts_list) {
+ AddErrorInfo("property 'shortcuts' ignored, type array expected.");
+ return shortcuts;
+ }
+
+ for (wtf_size_t i = 0; i < shortcuts_list->size(); ++i) {
+ JSONObject* shortcut_object = JSONObject::Cast(shortcuts_list->at(i));
+ if (!shortcut_object)
+ continue;
+
+ auto shortcut = mojom::blink::ManifestShortcutItem::New();
+ shortcut->url = ParseShortcutUrl(shortcut_object);
+ // A shortcut MUST have a valid url. If it does not, it MUST be ignored.
+ if (!shortcut->url.IsValid())
+ continue;
+
+ // A shortcut MUST have a valid name. If it does not, it MUST be ignored.
+ shortcut->name = ParseShortcutName(shortcut_object);
+ if (shortcut->name == String())
+ continue;
+
+ shortcut->short_name = ParseShortcutShortName(shortcut_object);
+ shortcut->description = ParseShortcutDescription(shortcut_object);
+ auto icons = ParseIcons(shortcut_object);
+ if (!icons.IsEmpty())
+ shortcut->icons = std::move(icons);
+
+ shortcuts.push_back(std::move(shortcut));
+ }
+
+ return shortcuts;
+}
+
String ManifestParser::ParseFileFilterName(const JSONObject* file) {
if (!file->Get("name")) {
AddErrorInfo("property 'name' missing.");
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 821858652b3..ff29cd4c72c 100644
--- a/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.h
+++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.h
@@ -20,6 +20,10 @@
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
+namespace gfx {
+class Size;
+} // namespace gfx
+
namespace blink {
class KURL;
@@ -67,6 +71,19 @@ class MODULES_EXPORT ManifestParser {
const String& key,
TrimType trim);
+ // Helper function to parse strings present in a member that itself is
+ // a dictionary like 'shortcut' as defined in:
+ // https://w3c.github.io/manifest/#shortcutitem-and-its-members Each strings
+ // will identifiable by its |key|. This helper includes the member_name in any
+ // ManifestError added while parsing. This helps disambiguate member property
+ // names from top level member names. Returns the parsed string if any, a null
+ // optional if the parsing failed.
+ base::Optional<String> ParseStringForMember(const JSONObject* object,
+ const String& member_name,
+ const String& key,
+ bool required,
+ TrimType trim);
+
// Helper function to parse colors present on a given |dictionary| in a given
// field identified by its |key|. Returns a null optional if the value is not
// present or is not a valid color.
@@ -131,8 +148,8 @@ class MODULES_EXPORT ManifestParser {
// https://w3c.github.io/manifest/#dfn-steps-for-processing-a-sizes-member-of-an-image
// Returns a vector of WebSize with the successfully parsed sizes, if any.
// An empty vector if the field was not present or empty. "Any" is represented
- // by WebSize(0, 0).
- Vector<WebSize> ParseIconSizes(const JSONObject* icon);
+ // by gfx::Size(0, 0).
+ Vector<gfx::Size> ParseIconSizes(const JSONObject* icon);
// Parses the 'purpose' field of an icon, as defined in:
// https://w3c.github.io/manifest/#dfn-steps-for-processing-a-purpose-member-of-an-image
@@ -148,6 +165,33 @@ class MODULES_EXPORT ManifestParser {
Vector<mojom::blink::ManifestImageResourcePtr> ParseIcons(
const JSONObject* object);
+ // Parses the 'name' field of a shortcut, as defined in:
+ // https://w3c.github.io/manifest/#shortcuts-member
+ // Returns the parsed string if any, a null string if the parsing failed.
+ String ParseShortcutName(const JSONObject* shortcut);
+
+ // Parses the 'short_name' field of a shortcut, as defined in:
+ // https://w3c.github.io/manifest/#shortcuts-member
+ // Returns the parsed string if any, a null string if the parsing failed.
+ String ParseShortcutShortName(const JSONObject* shortcut);
+
+ // Parses the 'description' field of a shortcut, as defined in:
+ // https://w3c.github.io/manifest/#shortcuts-member
+ // Returns the parsed string if any, a null string if the parsing failed.
+ String ParseShortcutDescription(const JSONObject* shortcut);
+
+ // Parses the 'url' field of an icon, as defined in:
+ // https://w3c.github.io/manifest/#shortcuts-member
+ // Returns the parsed KURL if any, an empty KURL if the parsing failed.
+ KURL ParseShortcutUrl(const JSONObject* shortcut);
+
+ // Parses the 'shortcuts' field of a Manifest, as defined in:
+ // https://w3c.github.io/manifest/#shortcuts-member
+ // Returns a vector of ManifestShortcutPtr with the successfully parsed
+ // shortcuts, if any. An empty vector if the field was not present or empty.
+ Vector<mojom::blink::ManifestShortcutItemPtr> ParseShortcuts(
+ const JSONObject* object);
+
// Parses the name field of a share target file, as defined in:
// https://wicg.github.io/web-share-target/level-2/#sharetargetfiles-and-its-members
// Returns the parsed string if any, an empty 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 6852eeb1b30..62738df4543 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
@@ -105,6 +105,7 @@ TEST_F(ManifestParserTest, ValidNoContentParses) {
ASSERT_FALSE(manifest->has_background_color);
ASSERT_TRUE(manifest->gcm_sender_id.IsNull());
ASSERT_EQ(DefaultDocumentUrl().BaseAsString(), manifest->scope.GetString());
+ ASSERT_TRUE(manifest->shortcuts.IsEmpty());
}
TEST_F(ManifestParserTest, MultipleErrorsReporting) {
@@ -112,10 +113,10 @@ TEST_F(ManifestParserTest, MultipleErrorsReporting) {
"{ \"name\": 42, \"short_name\": 4,"
"\"orientation\": {}, \"display\": \"foo\","
"\"start_url\": null, \"icons\": {}, \"theme_color\": 42,"
- "\"background_color\": 42 }");
+ "\"background_color\": 42, \"shortcuts\": {} }");
ASSERT_FALSE(IsManifestEmpty(manifest));
- EXPECT_EQ(8u, GetErrorCount());
+ EXPECT_EQ(9u, GetErrorCount());
EXPECT_EQ("property 'name' ignored, type string expected.", errors()[0]);
EXPECT_EQ("property 'short_name' ignored, type string expected.",
@@ -129,6 +130,7 @@ TEST_F(ManifestParserTest, MultipleErrorsReporting) {
errors()[6]);
EXPECT_EQ("property 'background_color' ignored, type string expected.",
errors()[7]);
+ EXPECT_EQ("property 'shortcuts' ignored, type array expected.", errors()[8]);
}
TEST_F(ManifestParserTest, NameParseRules) {
@@ -827,8 +829,8 @@ TEST_F(ManifestParserTest, IconSizesParseRules) {
EXPECT_FALSE(manifest->icons.IsEmpty());
auto& icons = manifest->icons;
- EXPECT_EQ(icons[0]->sizes[0], WebSize(42, 42));
- EXPECT_EQ(icons[0]->sizes[1], WebSize(48, 48));
+ EXPECT_EQ(icons[0]->sizes[0], gfx::Size(42, 42));
+ EXPECT_EQ(icons[0]->sizes[1], gfx::Size(48, 48));
EXPECT_EQ(0u, GetErrorCount());
}
@@ -840,8 +842,8 @@ TEST_F(ManifestParserTest, IconSizesParseRules) {
EXPECT_FALSE(manifest->icons.IsEmpty());
auto& icons = manifest->icons;
- EXPECT_EQ(icons[0]->sizes[0], WebSize(42, 42));
- EXPECT_EQ(icons[0]->sizes[1], WebSize(48, 48));
+ EXPECT_EQ(icons[0]->sizes[0], gfx::Size(42, 42));
+ EXPECT_EQ(icons[0]->sizes[1], gfx::Size(48, 48));
EXPECT_EQ(0u, GetErrorCount());
}
@@ -853,8 +855,8 @@ TEST_F(ManifestParserTest, IconSizesParseRules) {
EXPECT_FALSE(manifest->icons.IsEmpty());
auto& icons = manifest->icons;
- EXPECT_EQ(icons[0]->sizes[0], WebSize(42, 42));
- EXPECT_EQ(icons[0]->sizes[1], WebSize(42, 42));
+ EXPECT_EQ(icons[0]->sizes[0], gfx::Size(42, 42));
+ EXPECT_EQ(icons[0]->sizes[1], gfx::Size(42, 42));
EXPECT_EQ(0u, GetErrorCount());
}
@@ -880,12 +882,12 @@ TEST_F(ManifestParserTest, IconSizesParseRules) {
EXPECT_EQ("found icon with no valid size.", errors()[0]);
}
- // 'any' is correctly parsed and transformed to WebSize(0,0).
+ // 'any' is correctly parsed and transformed to gfx::Size(0,0).
{
auto& manifest = ParseManifest(
"{ \"icons\": [ {\"src\": \"\","
"\"sizes\": \"any AnY ANY aNy\" } ] }");
- WebSize any = WebSize(0, 0);
+ gfx::Size any = gfx::Size(0, 0);
EXPECT_FALSE(manifest->icons.IsEmpty());
auto& icons = manifest->icons;
@@ -1074,6 +1076,423 @@ TEST_F(ManifestParserTest, IconPurposeParseRules) {
}
}
+TEST_F(ManifestParserTest, ShortcutsParseRules) {
+ // Smoke test: if no shortcut, no value.
+ {
+ auto& manifest = ParseManifest("{ \"shortcuts\": [] }");
+ EXPECT_TRUE(manifest->shortcuts.IsEmpty());
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Smoke test: if empty shortcut, no value.
+ {
+ auto& manifest = ParseManifest("{ \"shortcuts\": [ {} ] }");
+ EXPECT_TRUE(manifest->icons.IsEmpty());
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ("property 'url' of 'shortcut' not present.", errors()[0]);
+ }
+
+ // Smoke test: shortcut with invalid name and url, it will not be present in
+ // the list.
+ {
+ auto& manifest =
+ ParseManifest("{ \"shortcuts\": [ { \"shortcuts\": [] } ] }");
+ EXPECT_TRUE(manifest->icons.IsEmpty());
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ("property 'url' of 'shortcut' not present.", errors()[0]);
+ }
+
+ // Smoke test: shortcut with no name, it will not be present in the list.
+ {
+ auto& manifest = ParseManifest("{ \"shortcuts\": [ { \"url\": \"\" } ] }");
+ EXPECT_TRUE(manifest->shortcuts.IsEmpty());
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ("property 'name' of 'shortcut' not present.", errors()[0]);
+ }
+
+ // Smoke test: shortcut with no url, it will not be present in the list.
+ {
+ auto& manifest = ParseManifest("{ \"shortcuts\": [ { \"name\": \"\" } ] }");
+ EXPECT_TRUE(manifest->shortcuts.IsEmpty());
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ("property 'url' of 'shortcut' not present.", errors()[0]);
+ }
+
+ // Smoke test: shortcut with empty name, and empty src, will not be present in
+ // the list.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ { \"name\": \"\", \"url\": \"\" } ] }");
+ EXPECT_TRUE(manifest->shortcuts.IsEmpty());
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ("property 'name' of 'shortcut' is an empty string.", errors()[0]);
+ }
+
+ // Smoke test: shortcut with valid (non-empty) name and src, will be present
+ // in the list.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [{ \"name\": \"New Post\", \"url\": \"compose\" }] "
+ "}");
+ EXPECT_FALSE(manifest->shortcuts.IsEmpty());
+
+ auto& shortcuts = manifest->shortcuts;
+ EXPECT_EQ(shortcuts.size(), 1u);
+ EXPECT_EQ(shortcuts[0]->name, "New Post");
+ EXPECT_EQ(shortcuts[0]->url.GetString(), "http://foo.com/compose");
+ EXPECT_FALSE(IsManifestEmpty(manifest));
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+}
+
+TEST_F(ManifestParserTest, ShortcutNameParseRules) {
+ // Smoke test.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": \"foo\", \"url\": \"NameParseTest\" } ] "
+ "}");
+ EXPECT_FALSE(manifest->shortcuts.IsEmpty());
+ EXPECT_EQ(manifest->shortcuts[0]->name, "foo");
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Trim whitespaces.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": \" foo \", \"url\": \"NameParseTest\" "
+ "} ] }");
+ ASSERT_EQ(manifest->shortcuts[0]->name, "foo");
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Don't parse if shortcut->name isn't present.
+ {
+ auto& manifest =
+ ParseManifest("{ \"shortcuts\": [ {\"url\": \"NameParseTest\" } ] }");
+ EXPECT_TRUE(manifest->shortcuts.IsEmpty());
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ("property 'name' of 'shortcut' not present.", errors()[0]);
+ }
+
+ // Don't parse if shortcut->name isn't a string.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": {}, \"url\": \"NameParseTest\" } ] }");
+ EXPECT_TRUE(manifest->shortcuts.IsEmpty());
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ("property 'name' of 'shortcut' ignored, type string expected.",
+ errors()[0]);
+ }
+
+ // Don't parse if shortcut->name isn't a string.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": 42, \"url\": \"NameParseTest\" } ] }");
+ EXPECT_TRUE(manifest->shortcuts.IsEmpty());
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ("property 'name' of 'shortcut' ignored, type string expected.",
+ errors()[0]);
+ }
+
+ // Don't parse if shortcut->name is an empty string.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": \"\", \"url\": \"NameParseTest\" } ] }");
+ EXPECT_TRUE(manifest->shortcuts.IsEmpty());
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ("property 'name' of 'shortcut' is an empty string.", errors()[0]);
+ }
+}
+
+TEST_F(ManifestParserTest, ShortcutShortNameParseRules) {
+ // Smoke test.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": \"ShortNameParseTest\", \"short_name\": "
+ "\"foo\", \"url\": \"ShortNameParseTest\" } ] }");
+ ASSERT_EQ(manifest->shortcuts[0]->short_name, "foo");
+ ASSERT_FALSE(IsManifestEmpty(manifest));
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Shortcut member is parsed when no short_name is present
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": \"ShortNameParseTest\", \"url\": "
+ "\"ShortNameParseTest\" } ] }");
+ ASSERT_TRUE(manifest->shortcuts[0]->short_name.IsNull());
+ ASSERT_FALSE(IsManifestEmpty(manifest));
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Trim whitespaces.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": \"ShortNameParseTest\", \"short_name\": "
+ "\" foo \", \"url\": \"ShortNameParseTest\" } ] }");
+ ASSERT_EQ(manifest->shortcuts[0]->short_name, "foo");
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Don't parse short_name if it isn't a string.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": \"ShortNameParseTest\", \"short_name\": "
+ "{}, \"url\": \"ShortNameParseTest\" } ] }");
+ ASSERT_TRUE(manifest->shortcuts[0]->short_name.IsNull());
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ(
+ "property 'short_name' of 'shortcut' ignored, type string expected.",
+ errors()[0]);
+ }
+
+ // Don't parse short_name if it isn't a string.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": \"ShortNameParseTest\", \"short_name\": "
+ "42, \"url\": \"ShortNameParseTest\" } ] }");
+ ASSERT_TRUE(manifest->shortcuts[0]->short_name.IsNull());
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ(
+ "property 'short_name' of 'shortcut' ignored, type string expected.",
+ errors()[0]);
+ }
+}
+
+TEST_F(ManifestParserTest, ShortcutDescriptionParseRules) {
+ // Smoke test.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": \"DescriptionParseTest\", "
+ "\"description\": "
+ "\"foo\", \"url\": \"DescriptionParseTest\" } ] }");
+ ASSERT_EQ(manifest->shortcuts[0]->description, "foo");
+ ASSERT_FALSE(IsManifestEmpty(manifest));
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Shortcut member is parsed when no description is present
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": \"DescriptionParseTest\", \"url\": "
+ "\"DescriptionParseTest\" } ] }");
+ ASSERT_TRUE(manifest->shortcuts[0]->description.IsNull());
+ ASSERT_FALSE(IsManifestEmpty(manifest));
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Trim whitespaces.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": \"DescriptionParseTest\", "
+ "\"description\": "
+ "\" foo \", \"url\": \"DescriptionParseTest\" } ] }");
+ ASSERT_EQ(manifest->shortcuts[0]->description, "foo");
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Don't parse description if it isn't a string.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": \"DescriptionParseTest\", "
+ "\"description\": "
+ "{}, \"url\": \"DescriptionParseTest\" } ] }");
+ ASSERT_TRUE(manifest->shortcuts[0]->description.IsNull());
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ(
+ "property 'description' of 'shortcut' ignored, type string expected.",
+ errors()[0]);
+ }
+
+ // Don't parse description if it isn't a string.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": \"DescriptionParseTest\", "
+ "\"description\": "
+ "42, \"url\": \"DescriptionParseTest\" } ] }");
+ ASSERT_TRUE(manifest->shortcuts[0]->description.IsNull());
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ(
+ "property 'description' of 'shortcut' ignored, type string expected.",
+ errors()[0]);
+ }
+}
+
+TEST_F(ManifestParserTest, ShortcutUrlParseRules) {
+ // Smoke test.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": \"UrlParseTest\", \"url\": \"foo\" } ] "
+ "}");
+ EXPECT_FALSE(manifest->shortcuts.IsEmpty());
+ EXPECT_EQ(manifest->shortcuts[0]->url, KURL(DefaultDocumentUrl(), "foo"));
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Smoke test. Don't parse (with an error) when url is not present.
+ {
+ auto& manifest = ParseManifest("{ \"shortcuts\": [ { \"name\": \"\" } ] }");
+ EXPECT_TRUE(manifest->shortcuts.IsEmpty());
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ("property 'url' of 'shortcut' not present.", errors()[0]);
+ }
+
+ // Whitespaces.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": \"UrlParseTest\", \"url\": \" foo "
+ "\" } ] }");
+ EXPECT_FALSE(manifest->shortcuts.IsEmpty());
+ EXPECT_EQ(manifest->shortcuts[0]->url, KURL(DefaultDocumentUrl(), "foo"));
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Don't parse if url isn't a string.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": \"UrlParseTest\", \"url\": {} } ] }");
+ EXPECT_TRUE(manifest->shortcuts.IsEmpty());
+ EXPECT_EQ(2u, GetErrorCount());
+ EXPECT_EQ("property 'url' ignored, type string expected.", errors()[0]);
+ EXPECT_EQ("property 'url' of 'shortcut' not present.", errors()[1]);
+ }
+
+ // Don't parse if url isn't a string.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": \"UrlParseTest\", \"url\": 42 } ] }");
+ EXPECT_TRUE(manifest->shortcuts.IsEmpty());
+ EXPECT_EQ(2u, GetErrorCount());
+ EXPECT_EQ("property 'url' ignored, type string expected.", errors()[0]);
+ EXPECT_EQ("property 'url' of 'shortcut' not present.", errors()[1]);
+ }
+
+ // Resolving has to happen based on the manifest_url.
+ {
+ auto& manifest = ParseManifestWithURLs(
+ "{ \"shortcuts\": [ {\"name\": \"UrlParseTest\", \"url\": \"foo\" } ] "
+ "}",
+ KURL("http://foo.com/landing/manifest.json"), DefaultDocumentUrl());
+ EXPECT_FALSE(manifest->shortcuts.IsEmpty());
+ EXPECT_EQ(manifest->shortcuts[0]->url.GetString(),
+ "http://foo.com/landing/foo");
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Shortcut url should have same origin as the document url.
+ {
+ auto& manifest = ParseManifestWithURLs(
+ "{ \"shortcuts\": [ {\"name\": \"UrlParseTest\", \"url\": "
+ "\"http://bar.com/landing\" } ] "
+ "}",
+ KURL("http://foo.com/landing/manifest.json"), DefaultDocumentUrl());
+ EXPECT_TRUE(manifest->shortcuts.IsEmpty());
+ EXPECT_EQ(2u, GetErrorCount());
+ EXPECT_EQ("property 'url' ignored, should be same origin as document.",
+ errors()[0]);
+ EXPECT_EQ("property 'url' of 'shortcut' not present.", errors()[1]);
+ }
+
+ // Shortcut url should be within the manifest scope.
+ // The scope will be http://foo.com/landing.
+ // The shortcut_url will be http://foo.com/shortcut which is in not in scope.
+ {
+ auto& manifest = ParseManifestWithURLs(
+ "{ \"scope\": \"http://foo.com/landing\", \"shortcuts\": [ {\"name\": "
+ "\"UrlParseTest\", \"url\": \"shortcut\" } ] }",
+ KURL("http://foo.com/manifest.json"),
+ KURL("http://foo.com/landing/index.html"));
+ EXPECT_TRUE(manifest->shortcuts.IsEmpty());
+ ASSERT_EQ(manifest->scope.GetString(), "http://foo.com/landing");
+ EXPECT_EQ(1u, GetErrorCount());
+ EXPECT_EQ(
+ "property 'url' of 'shortcut' ignored. url should be within scope of "
+ "the manifest.",
+ errors()[0]);
+ }
+
+ // Shortcut url should be within the manifest scope.
+ // The scope will be http://foo.com/land.
+ // The shortcut_url will be http://foo.com/land/shortcut which is in scope.
+ {
+ auto& manifest = ParseManifestWithURLs(
+ "{ \"scope\": \"http://foo.com/land\", \"start_url\": "
+ "\"http://foo.com/land/landing.html\", \"shortcuts\": [ {\"name\": "
+ "\"UrlParseTest\", \"url\": \"shortcut\" } ] }",
+ KURL("http://foo.com/land/manifest.json"),
+ KURL("http://foo.com/index.html"));
+ EXPECT_FALSE(manifest->shortcuts.IsEmpty());
+ ASSERT_EQ(manifest->scope.GetString(), "http://foo.com/land");
+ EXPECT_EQ(manifest->shortcuts[0]->url.GetString(),
+ "http://foo.com/land/shortcut");
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+}
+
+TEST_F(ManifestParserTest, ShortcutIconsParseRules) {
+ // Smoke test: if no icons, shortcut->icons has no value.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": \"IconParseTest\", \"url\": \"foo\", "
+ "\"icons\": [] } ] }");
+ EXPECT_FALSE(IsManifestEmpty(manifest));
+ EXPECT_FALSE(manifest->shortcuts.IsEmpty());
+ EXPECT_TRUE(manifest->shortcuts[0]->icons.IsEmpty());
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Smoke test: if empty icon, shortcut->icons has no value.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": \"IconParseTest\", \"url\": \"foo\", "
+ "\"icons\": [{}] } ] }");
+ EXPECT_FALSE(IsManifestEmpty(manifest));
+ EXPECT_FALSE(manifest->shortcuts.IsEmpty());
+ EXPECT_TRUE(manifest->shortcuts[0]->icons.IsEmpty());
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Smoke test: icon with invalid src, shortcut->icons has no value.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": \"IconParseTest\", \"url\": \"foo\", "
+ "\"icons\": [{ \"icons\": [] }] } ] }");
+ EXPECT_FALSE(IsManifestEmpty(manifest));
+ EXPECT_FALSE(manifest->shortcuts.IsEmpty());
+ EXPECT_TRUE(manifest->shortcuts[0]->icons.IsEmpty());
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Smoke test: if icon with empty src, it will be present in shortcut->icons.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": \"IconParseTest\", \"url\": \"foo\", "
+ "\"icons\": [ { \"src\": \"\" } ] } ] }");
+ EXPECT_FALSE(IsManifestEmpty(manifest));
+ EXPECT_FALSE(manifest->shortcuts.IsEmpty());
+ EXPECT_FALSE(manifest->shortcuts[0]->icons.IsEmpty());
+
+ auto& icons = manifest->shortcuts[0]->icons;
+ EXPECT_EQ(icons.size(), 1u);
+ EXPECT_EQ(icons[0]->src.GetString(), "http://foo.com/manifest.json");
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+
+ // Smoke test: if one icon with valid src, it will be present in
+ // shortcut->icons.
+ {
+ auto& manifest = ParseManifest(
+ "{ \"shortcuts\": [ {\"name\": \"IconParseTest\", \"url\": \"foo\", "
+ "\"icons\": [ { \"src\": \"foo.jpg\" } ] } ] }");
+ EXPECT_FALSE(IsManifestEmpty(manifest));
+ EXPECT_FALSE(manifest->shortcuts.IsEmpty());
+ EXPECT_FALSE(manifest->shortcuts[0]->icons.IsEmpty());
+ auto& icons = manifest->shortcuts[0]->icons;
+ EXPECT_EQ(icons.size(), 1u);
+ EXPECT_EQ(icons[0]->src.GetString(), "http://foo.com/foo.jpg");
+ EXPECT_EQ(0u, GetErrorCount());
+ }
+}
TEST_F(ManifestParserTest, FileHandlerParseRules) {
// Does not contain file_handlers field.
{
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 19c1db945af..54496503116 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
@@ -40,6 +40,9 @@ TypeConverter<blink::Manifest, blink::mojom::blink::ManifestPtr>::Convert(
for (auto& icon : input->icons)
output.icons.push_back(icon.To<blink::Manifest::ImageResource>());
+ for (auto& shortcut : input->shortcuts)
+ output.shortcuts.push_back(shortcut.To<blink::Manifest::ShortcutItem>());
+
if (!input->share_target.is_null()) {
output.share_target =
input->share_target.To<blink::Manifest::ShareTarget>();
@@ -100,6 +103,34 @@ TypeConverter<blink::Manifest::ImageResource,
return output;
}
+blink::Manifest::ShortcutItem
+TypeConverter<blink::Manifest::ShortcutItem,
+ blink::mojom::blink::ManifestShortcutItemPtr>::
+ Convert(const blink::mojom::blink::ManifestShortcutItemPtr& input) {
+ blink::Manifest::ShortcutItem output;
+ if (input.is_null())
+ return output;
+
+ output.name = blink::WebString(input->name).Utf16();
+
+ if (!input->short_name.IsEmpty()) {
+ output.short_name =
+ base::NullableString16(blink::WebString(input->short_name).Utf16());
+ }
+
+ if (!input->description.IsEmpty()) {
+ output.description =
+ base::NullableString16(blink::WebString(input->description).Utf16());
+ }
+
+ output.url = input->url;
+
+ for (auto& icon : input->icons)
+ output.icons.push_back(icon.To<::blink::Manifest::ImageResource>());
+
+ return output;
+}
+
blink::Manifest::ShareTarget
TypeConverter<blink::Manifest::ShareTarget,
blink::mojom::blink::ManifestShareTargetPtr>::
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 58cca5994a1..ffb17b076c2 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
@@ -32,6 +32,13 @@ struct TypeConverter<blink::Manifest::ImageResource,
};
template <>
+struct TypeConverter<blink::Manifest::ShortcutItem,
+ blink::mojom::blink::ManifestShortcutItemPtr> {
+ static blink::Manifest::ShortcutItem Convert(
+ const blink::mojom::blink::ManifestShortcutItemPtr& input);
+};
+
+template <>
struct TypeConverter<blink::Manifest::ShareTarget,
blink::mojom::blink::ManifestShareTargetPtr> {
static blink::Manifest::ShareTarget Convert(
diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters_unittest.cc b/chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters_unittest.cc
index 4d94590a166..6bcb873bd5e 100644
--- a/chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters_unittest.cc
+++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters_unittest.cc
@@ -71,4 +71,44 @@ TEST_F(ManifestTypeConvertersTest, BasicFileHandlerIsCorrectlyConverted) {
EXPECT_TRUE(
base::EqualsASCII(manifest.file_handlers[0].accept[mime][0], ".png"));
}
+
+TEST_F(ManifestTypeConvertersTest, NoShortcutsDoesNotConvert) {
+ const String json = "{\"start_url\": \"/\"}";
+ const mojom::blink::ManifestPtr& mojo_manifest = Load(json);
+
+ auto manifest = mojo_manifest.To<blink::Manifest>();
+ EXPECT_TRUE(manifest.shortcuts.empty());
+}
+
+TEST_F(ManifestTypeConvertersTest, BasicShortcutIsCorrectlyConverted) {
+ const mojom::blink::ManifestPtr& mojo_manifest = Load(
+ "{"
+ " \"shortcuts\": ["
+ " {"
+ " \"name\": \"name\", "
+ " \"short_name\": \"short_name\","
+ " \"url\": \"url\", "
+ " \"icons\": ["
+ " {"
+ " \"src\": \"image.jpg\""
+ " }"
+ " ] "
+ " }"
+ " ] "
+ "}");
+
+ auto manifest = mojo_manifest.To<blink::Manifest>();
+ ASSERT_FALSE(manifest.shortcuts.empty());
+
+ ASSERT_EQ(manifest.shortcuts.size(), 1u);
+ EXPECT_TRUE(base::EqualsASCII(manifest.shortcuts[0].name, "name"));
+ EXPECT_TRUE(base::EqualsASCII(manifest.shortcuts[0].short_name.string(),
+ "short_name"));
+ EXPECT_EQ(manifest.shortcuts[0].url.spec(), "http://example.com/url");
+
+ ASSERT_EQ(manifest.shortcuts[0].icons.size(), 1u);
+ ASSERT_EQ(manifest.shortcuts[0].icons[0].src.spec(),
+ "http://example.com/image.jpg");
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/media/BUILD.gn b/chromium/third_party/blink/renderer/modules/media/BUILD.gn
index eba7d9e6553..3de62ab229d 100644
--- a/chromium/third_party/blink/renderer/modules/media/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/media/BUILD.gn
@@ -6,7 +6,5 @@ import("//build/config/jumbo.gni")
import("//third_party/blink/renderer/modules/modules.gni")
blink_modules_sources("media") {
- sources = [
- "webmediaplayer_util.cc",
- ]
+ sources = [ "webmediaplayer_util.cc" ]
}
diff --git a/chromium/third_party/blink/renderer/modules/media_capabilities/BUILD.gn b/chromium/third_party/blink/renderer/modules/media_capabilities/BUILD.gn
index 61c308cffd0..e2f52506dc6 100644
--- a/chromium/third_party/blink/renderer/modules/media_capabilities/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/media_capabilities/BUILD.gn
@@ -16,12 +16,12 @@ blink_modules_sources("media_capabilities") {
"worker_navigator_media_capabilities.h",
]
deps = [
+ "//media",
+ "//media/learning/mojo:impl",
"//third_party/blink/renderer/modules/mediarecorder",
]
}
fuzzable_proto_library("fuzzer_media_configuration_proto") {
- sources = [
- "fuzzer_media_configuration.proto",
- ]
+ sources = [ "fuzzer_media_configuration.proto" ]
}
diff --git a/chromium/third_party/blink/renderer/modules/media_capabilities/DEPS b/chromium/third_party/blink/renderer/modules/media_capabilities/DEPS
index 35cf7adf634..02607e024ed 100644
--- a/chromium/third_party/blink/renderer/modules/media_capabilities/DEPS
+++ b/chromium/third_party/blink/renderer/modules/media_capabilities/DEPS
@@ -1,13 +1,24 @@
include_rules = [
- "+media/base/mime_util.h",
- "+media/base/supported_types.h",
- "+media/base/video_codecs.h",
+ "+media/base",
"+media/filters/stream_parser_factory.h",
+ "+media/learning/common",
+ "+media/learning/mojo/public/cpp/mojo_learning_task_controller.h",
+ "+media/learning/mojo/public/mojom/learning_task_controller.mojom-blink.h",
"+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",
"-third_party/blink/renderer/modules",
"+third_party/blink/renderer/modules/encryptedmedia",
"+third_party/blink/renderer/modules/media_capabilities",
"+third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h",
"+third_party/blink/renderer/modules/modules_export.h",
]
+
+specific_include_rules = {
+ "media_capabilities_test\.cc": [
+ "+base/run_loop.h",
+ "+base/strings/string_number_conversions.h",
+ "+base/test/bind_test_util.h",
+ "+media/mojo/mojom/watch_time_recorder.mojom-blink.h",
+ ],
+} \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/media_capabilities/idls.gni b/chromium/third_party/blink/renderer/modules/media_capabilities/idls.gni
new file mode 100644
index 00000000000..0ebd31bef06
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/media_capabilities/idls.gni
@@ -0,0 +1,22 @@
+# 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 = [ "media_capabilities.idl" ]
+
+modules_dictionary_idl_files = [
+ "audio_configuration.idl",
+ "key_system_track_configuration.idl",
+ "media_configuration.idl",
+ "media_capabilities_decoding_info.idl",
+ "media_capabilities_info.idl",
+ "media_capabilities_key_system_configuration.idl",
+ "media_decoding_configuration.idl",
+ "media_encoding_configuration.idl",
+ "video_configuration.idl",
+]
+
+modules_dependency_idl_files = [
+ "navigator_media_capabilities.idl",
+ "worker_navigator_media_capabilities.idl",
+]
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 3a3a2cd256b..717318e8d68 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
@@ -5,12 +5,20 @@
#include "third_party/blink/renderer/modules/media_capabilities/media_capabilities.h"
#include <memory>
+#include <sstream>
#include <utility>
+#include "base/feature_list.h"
+#include "base/metrics/field_trial_params.h"
#include "base/optional.h"
+#include "media/base/media_switches.h"
#include "media/base/mime_util.h"
#include "media/base/supported_types.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 "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
@@ -20,6 +28,16 @@
#include "third_party/blink/public/platform/web_encrypted_media_request.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_audio_configuration.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_key_system_track_configuration.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_capabilities_decoding_info.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_capabilities_info.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_capabilities_key_system_configuration.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_media_encoding_configuration.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_key_system_configuration.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_key_system_media_capability.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"
@@ -28,18 +46,9 @@
#include "third_party/blink/renderer/modules/encryptedmedia/encrypted_media_utils.h"
#include "third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.h"
#include "third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.h"
-#include "third_party/blink/renderer/modules/encryptedmedia/media_key_system_configuration.h"
-#include "third_party/blink/renderer/modules/encryptedmedia/media_key_system_media_capability.h"
#include "third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.h"
-#include "third_party/blink/renderer/modules/media_capabilities/audio_configuration.h"
-#include "third_party/blink/renderer/modules/media_capabilities/key_system_track_configuration.h"
-#include "third_party/blink/renderer/modules/media_capabilities/media_capabilities_decoding_info.h"
-#include "third_party/blink/renderer/modules/media_capabilities/media_capabilities_info.h"
-#include "third_party/blink/renderer/modules/media_capabilities/media_capabilities_key_system_configuration.h"
-#include "third_party/blink/renderer/modules/media_capabilities/media_configuration.h"
-#include "third_party/blink/renderer/modules/media_capabilities/media_decoding_configuration.h"
-#include "third_party/blink/renderer/modules/media_capabilities/media_encoding_configuration.h"
#include "third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.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/bindings/v8_throw_exception.h"
@@ -58,11 +67,34 @@ namespace blink {
namespace {
+const double kLearningBadWindowThresholdDefault = 2;
+const double kLearningNnrThresholdDefault = 3;
+
constexpr const char* kApplicationMimeTypePrefix = "application/";
constexpr const char* kAudioMimeTypePrefix = "audio/";
constexpr const char* kVideoMimeTypePrefix = "video/";
constexpr const char* kCodecsMimeTypeParam = "codecs";
+// Gets parameters for kMediaLearningSmoothnessExperiment field trial. Will
+// provide sane defaults when field trial not enabled. Values of -1 indicate
+// predictions from a given task should be ignored.
+
+// static
+double GetLearningBadWindowThreshold() {
+ return base::GetFieldTrialParamByFeatureAsDouble(
+ media::kMediaLearningSmoothnessExperiment,
+ MediaCapabilities::kLearningBadWindowThresholdParamName,
+ kLearningBadWindowThresholdDefault);
+}
+
+// static
+double GetLearningNnrThreshold() {
+ return base::GetFieldTrialParamByFeatureAsDouble(
+ media::kMediaLearningSmoothnessExperiment,
+ MediaCapabilities::kLearningNnrThresholdParamName,
+ kLearningNnrThresholdDefault);
+}
+
// Utility function that will create a MediaCapabilitiesDecodingInfo object with
// all the values set to either true or false.
MediaCapabilitiesDecodingInfo* CreateDecodingInfoWith(bool value) {
@@ -110,7 +142,7 @@ class MediaCapabilitiesKeySystemAccessInitializer final
// Query the client for smoothness and power efficiency of the video. It
// will resolve the promise.
std::move(get_perf_callback_)
- .Run(std::move(resolver_),
+ .Run(resolver_.Get(),
MakeGarbageCollected<MediaKeySystemAccess>(std::move(access)));
}
@@ -126,7 +158,7 @@ class MediaCapabilitiesKeySystemAccessInitializer final
resolver_->Resolve(info);
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
MediaKeySystemAccessInitializerBase::Trace(visitor);
}
@@ -362,16 +394,17 @@ bool IsAudioCodecValid(const String& mime_type,
// console.
bool IsVideoCodecValid(const String& mime_type,
const String& codec,
+ media::VideoCodec* out_video_codec,
media::VideoCodecProfile* out_video_profile,
String* console_warning) {
- media::VideoCodec video_codec = media::kUnknownVideoCodec;
uint8_t video_level = 0;
media::VideoColorSpace video_color_space;
bool is_video_codec_ambiguous = true;
- if (!media::ParseVideoCodecString(
- mime_type.Ascii(), codec.Ascii(), &is_video_codec_ambiguous,
- &video_codec, out_video_profile, &video_level, &video_color_space)) {
+ if (!media::ParseVideoCodecString(mime_type.Ascii(), codec.Ascii(),
+ &is_video_codec_ambiguous, out_video_codec,
+ out_video_profile, &video_level,
+ &video_color_space)) {
*console_warning = StringView("Failed to parse video contentType: ") +
String{mime_type} + StringView("; codecs=") +
String{codec};
@@ -395,6 +428,7 @@ bool IsAudioConfigurationSupported(
const String& mime_type,
const String& codec) {
media::AudioCodec audio_codec = media::kUnknownAudioCodec;
+ media::AudioCodecProfile audio_profile = media::AudioCodecProfile::kUnknown;
bool is_audio_codec_ambiguous = true;
bool is_spatial_rendering = false;
@@ -407,7 +441,8 @@ bool IsAudioConfigurationSupported(
if (audio_config->hasSpatialRendering())
is_spatial_rendering = audio_config->spatialRendering();
- return media::IsSupportedAudioType({audio_codec, is_spatial_rendering});
+ return media::IsSupportedAudioType(
+ {audio_codec, audio_profile, is_spatial_rendering});
}
// Returns whether the VideoConfiguration is supported.
@@ -468,11 +503,33 @@ bool ParseContentType(const String& content_type,
} // anonymous namespace
+const char MediaCapabilities::kLearningBadWindowThresholdParamName[] =
+ "bad_window_threshold";
+
+const char MediaCapabilities::kLearningNnrThresholdParamName[] =
+ "nnr_threshold";
+
MediaCapabilities::MediaCapabilities() = default;
+void MediaCapabilities::Trace(blink::Visitor* visitor) {
+ visitor->Trace(pending_cb_map_);
+ ScriptWrappable::Trace(visitor);
+}
+
+MediaCapabilities::PendingCallbackState::PendingCallbackState(
+ ScriptPromiseResolver* resolver,
+ MediaKeySystemAccess* access)
+ : resolver(resolver), key_system_access(access) {}
+
+void MediaCapabilities::PendingCallbackState::Trace(blink::Visitor* visitor) {
+ visitor->Trace(key_system_access);
+ visitor->Trace(resolver);
+}
+
ScriptPromise MediaCapabilities::decodingInfo(
ScriptState* script_state,
- const MediaDecodingConfiguration* config) {
+ const MediaDecodingConfiguration* config,
+ ExceptionState& exception_state) {
if (config->hasKeySystemConfiguration()) {
UseCounter::Count(
ExecutionContext::From(script_state),
@@ -481,43 +538,40 @@ ScriptPromise MediaCapabilities::decodingInfo(
String message;
if (!IsValidMediaDecodingConfiguration(config, &message)) {
- return ScriptPromise::Reject(
- script_state,
- V8ThrowException::CreateTypeError(script_state->GetIsolate(), message));
+ exception_state.ThrowTypeError(message);
+ return ScriptPromise();
}
if (config->hasVideo() && !IsValidVideoConfiguration(config->video())) {
- return ScriptPromise::Reject(
- script_state, V8ThrowException::CreateTypeError(
- script_state->GetIsolate(),
- "The video configuration dictionary is not valid."));
+ exception_state.ThrowTypeError(
+ "The video configuration dictionary is not valid.");
+ return ScriptPromise();
}
if (config->hasAudio() && !IsValidAudioConfiguration(config->audio())) {
- return ScriptPromise::Reject(
- script_state, V8ThrowException::CreateTypeError(
- script_state->GetIsolate(),
- "The audio configuration dictionary is not valid."));
+ exception_state.ThrowTypeError(
+ "The audio configuration dictionary is not valid.");
+ return ScriptPromise();
}
// Validation errors should return above.
DCHECK(message.IsEmpty());
- String audio_mime;
- String audio_codec;
+ String audio_mime_str;
+ String audio_codec_str;
if (config->hasAudio()) {
DCHECK(config->audio()->hasContentType());
- bool valid_content_type = ParseContentType(config->audio()->contentType(),
- &audio_mime, &audio_codec);
+ bool valid_content_type = ParseContentType(
+ config->audio()->contentType(), &audio_mime_str, &audio_codec_str);
DCHECK(valid_content_type);
}
- String video_mime;
- String video_codec;
+ String video_mime_str;
+ String video_codec_str;
if (config->hasVideo()) {
DCHECK(config->video()->hasContentType());
- bool valid_content_type = ParseContentType(config->video()->contentType(),
- &video_mime, &video_codec);
+ bool valid_content_type = ParseContentType(
+ config->video()->contentType(), &video_mime_str, &video_codec_str);
DCHECK(valid_content_type);
}
@@ -525,8 +579,10 @@ ScriptPromise MediaCapabilities::decodingInfo(
// that MSE support is not implied by EME support, so do it irrespective of
// whether we have a KeySystem configuration.
if (config->type() == "media-source") {
- if ((config->hasAudio() && !CheckMseSupport(audio_mime, audio_codec)) ||
- (config->hasVideo() && !CheckMseSupport(video_mime, video_codec))) {
+ if ((config->hasAudio() &&
+ !CheckMseSupport(audio_mime_str, audio_codec_str)) ||
+ (config->hasVideo() &&
+ !CheckMseSupport(video_mime_str, video_codec_str))) {
// Unsupported EME queries should resolve with a null
// MediaKeySystemAccess.
return ScriptPromise::Cast(
@@ -535,12 +591,14 @@ ScriptPromise MediaCapabilities::decodingInfo(
}
}
+ media::VideoCodec video_codec = media::kUnknownVideoCodec;
media::VideoCodecProfile video_profile = media::VIDEO_CODEC_PROFILE_UNKNOWN;
if ((config->hasAudio() &&
- !IsAudioCodecValid(audio_mime, audio_codec, &message)) ||
+ !IsAudioCodecValid(audio_mime_str, audio_codec_str, &message)) ||
(config->hasVideo() &&
- !IsVideoCodecValid(video_mime, video_codec, &video_profile, &message))) {
+ !IsVideoCodecValid(video_mime_str, video_codec_str, &video_codec,
+ &video_profile, &message))) {
DCHECK(!message.IsEmpty());
if (ExecutionContext* execution_context =
ExecutionContext::From(script_state)) {
@@ -559,14 +617,15 @@ ScriptPromise MediaCapabilities::decodingInfo(
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_profile, config);
+ return GetEmeSupport(script_state, video_codec, video_profile, config,
+ exception_state);
}
bool audio_supported = true;
if (config->hasAudio()) {
- audio_supported =
- IsAudioConfigurationSupported(config->audio(), audio_mime, audio_codec);
+ audio_supported = IsAudioConfigurationSupported(
+ config->audio(), audio_mime_str, audio_codec_str);
}
// No need to check video capabilities if video not included in configuration
@@ -581,8 +640,8 @@ ScriptPromise MediaCapabilities::decodingInfo(
DCHECK(config->hasVideo());
// Return early for unsupported configurations.
- if (!IsVideoConfigurationSupported(config->video(), video_mime,
- video_codec)) {
+ if (!IsVideoConfigurationSupported(config->video(), video_mime_str,
+ video_codec_str)) {
return ScriptPromise::Cast(
script_state, ToV8(CreateDecodingInfoWith(false), script_state));
}
@@ -594,7 +653,8 @@ ScriptPromise MediaCapabilities::decodingInfo(
// undefined. See comment above Promise() in script_promise_resolver.h
ScriptPromise promise = resolver->Promise();
- GetPerfInfo(video_profile, config->video(), resolver, nullptr /* access */);
+ GetPerfInfo(video_codec, video_profile, config->video(), resolver,
+ nullptr /* access */);
return promise;
}
@@ -668,7 +728,49 @@ ScriptPromise MediaCapabilities::encodingInfo(
return promise;
}
-bool MediaCapabilities::EnsureService(ExecutionContext* execution_context) {
+bool MediaCapabilities::EnsureLearningPredictors(
+ ExecutionContext* execution_context) {
+ DCHECK(execution_context && !execution_context->IsContextDestroyed());
+
+ // One or both of these will have been bound in an earlier pass.
+ if (bad_window_predictor_ || nnr_predictor_)
+ return true;
+
+ // MediaMetricsProvider currently only exposed via render frame.
+ // TODO(chcunningham): Expose in worker contexts pending outcome of
+ // media-learning experiments.
+ if (execution_context->IsWorkerGlobalScope())
+ return false;
+
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ execution_context->GetTaskRunner(TaskType::kMediaElementEvent);
+
+ mojo::Remote<media::mojom::blink::MediaMetricsProvider> metrics_provider;
+ execution_context->GetBrowserInterfaceBroker().GetInterface(
+ metrics_provider.BindNewPipeAndPassReceiver(task_runner));
+
+ if (!metrics_provider)
+ return false;
+
+ if (GetLearningBadWindowThreshold() != -1.0) {
+ DCHECK_GE(GetLearningBadWindowThreshold(), 0);
+ metrics_provider->AcquireLearningTaskController(
+ media::learning::tasknames::kConsecutiveBadWindows,
+ bad_window_predictor_.BindNewPipeAndPassReceiver());
+ }
+
+ if (GetLearningNnrThreshold() != -1.0) {
+ DCHECK_GE(GetLearningNnrThreshold(), 0);
+ metrics_provider->AcquireLearningTaskController(
+ media::learning::tasknames::kConsecutiveNNRs,
+ nnr_predictor_.BindNewPipeAndPassReceiver());
+ }
+
+ return bad_window_predictor_ || nnr_predictor_;
+}
+
+bool MediaCapabilities::EnsurePerfHistoryService(
+ ExecutionContext* execution_context) {
if (decode_history_service_)
return true;
@@ -685,66 +787,63 @@ bool MediaCapabilities::EnsureService(ExecutionContext* execution_context) {
ScriptPromise MediaCapabilities::GetEmeSupport(
ScriptState* script_state,
+ media::VideoCodec video_codec,
media::VideoCodecProfile video_profile,
- const MediaDecodingConfiguration* configuration) {
+ const MediaDecodingConfiguration* configuration,
+ ExceptionState& exception_state) {
DVLOG(3) << __func__;
DCHECK(configuration->hasKeySystemConfiguration());
ExecutionContext* execution_context = ExecutionContext::From(script_state);
DCHECK(execution_context);
- Document* document = To<Document>(execution_context);
+ Document* document = Document::From(execution_context);
// See context here:
// https://sites.google.com/a/chromium.org/dev/Home/chromium-security/deprecating-permissions-in-cross-origin-iframes
- if (!document->IsFeatureEnabled(mojom::FeaturePolicyFeature::kEncryptedMedia,
- ReportOptions::kReportOnFailure)) {
+ if (!document->IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kEncryptedMedia,
+ ReportOptions::kReportOnFailure)) {
UseCounter::Count(document,
WebFeature::kEncryptedMediaDisabledByFeaturePolicy);
- document->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning,
- kEncryptedMediaFeaturePolicyConsoleWarning));
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kSecurityError,
- "decodingInfo(): Creating MediaKeySystemAccess is "
- "disabled by feature policy."));
+ document->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning,
+ kEncryptedMediaFeaturePolicyConsoleWarning));
+ exception_state.ThrowSecurityError(
+ "decodingInfo(): Creating MediaKeySystemAccess is disabled by feature "
+ "policy.");
+ return ScriptPromise();
}
// Calling context must have a real Document bound to a Page. This check is
// ported from rMKSA (see http://crbug.com/456720).
if (!document->GetPage()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "The context provided is not associated with a page."));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "The context provided is not associated with a page.");
+ return ScriptPromise();
}
if (execution_context->IsWorkerGlobalScope()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "Encrypted Media decoding info not available in Worker context."));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "Encrypted Media decoding info not available in Worker context.");
+ return ScriptPromise();
}
if (!execution_context->IsSecureContext()) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kSecurityError,
- "Encrypted Media decoding info can only be "
- "queried in a secure context."));
+ exception_state.ThrowSecurityError(
+ "Encrypted Media decoding info can only be queried in a secure"
+ " context.");
+ return ScriptPromise();
}
MediaCapabilitiesKeySystemConfiguration* key_system_config =
configuration->keySystemConfiguration();
if (!key_system_config->hasKeySystem() ||
key_system_config->keySystem().IsEmpty()) {
- return ScriptPromise::Reject(
- script_state,
- V8ThrowException::CreateTypeError(
- script_state->GetIsolate(), "The key system String is not valid."));
+ exception_state.ThrowTypeError("The key system String is not valid.");
+ return ScriptPromise();
}
MediaKeySystemConfiguration* eme_config =
@@ -814,7 +913,8 @@ ScriptPromise MediaCapabilities::GetEmeSupport(
MakeGarbageCollected<MediaCapabilitiesKeySystemAccessInitializer>(
script_state, key_system_config->keySystem(), config_vector,
WTF::Bind(&MediaCapabilities::GetPerfInfo, WrapPersistent(this),
- video_profile, WrapPersistent(configuration->video())));
+ video_codec, video_profile,
+ WrapPersistent(configuration->video())));
// IMPORTANT: Acquire the promise before potentially synchronously resolving
// it in the code that follows. Otherwise the promise returned to JS will be
@@ -828,7 +928,8 @@ ScriptPromise MediaCapabilities::GetEmeSupport(
return promise;
}
-void MediaCapabilities::GetPerfInfo(media::VideoCodecProfile video_profile,
+void MediaCapabilities::GetPerfInfo(media::VideoCodec video_codec,
+ media::VideoCodecProfile video_profile,
const VideoConfiguration* video_config,
ScriptPromiseResolver* resolver,
MediaKeySystemAccess* access) {
@@ -852,40 +953,176 @@ void MediaCapabilities::GetPerfInfo(media::VideoCodecProfile video_profile,
use_hw_secure_codecs = access->UseHardwareSecureCodecs();
}
- if (!EnsureService(execution_context)) {
- resolver->Resolve(WrapPersistent(CreateDecodingInfoWith(false)));
+ if (!EnsurePerfHistoryService(execution_context)) {
+ resolver->Resolve(WrapPersistent(CreateDecodingInfoWith(true)));
return;
}
+ const int callback_id = CreateCallbackId();
+ pending_cb_map_.insert(
+ callback_id,
+ MakeGarbageCollected<MediaCapabilities::PendingCallbackState>(resolver,
+ access));
+
+ if (base::FeatureList::IsEnabled(media::kMediaLearningSmoothnessExperiment)) {
+ GetPerfInfo_ML(execution_context, callback_id, video_codec, video_profile,
+ video_config->width(), video_config->framerate());
+ }
+
media::mojom::blink::PredictionFeaturesPtr features =
media::mojom::blink::PredictionFeatures::New(
static_cast<media::mojom::blink::VideoCodecProfile>(video_profile),
- WebSize(video_config->width(), video_config->height()),
+ gfx::Size(video_config->width(), video_config->height()),
video_config->framerate(), key_system, use_hw_secure_codecs);
decode_history_service_->GetPerfInfo(
- std::move(features),
- WTF::Bind(&MediaCapabilities::OnPerfInfo, WrapPersistent(this),
- WrapPersistent(resolver), WrapPersistent(access)));
+ std::move(features), WTF::Bind(&MediaCapabilities::OnPerfHistoryInfo,
+ WrapPersistent(this), callback_id));
}
-void MediaCapabilities::OnPerfInfo(ScriptPromiseResolver* resolver,
- MediaKeySystemAccess* access,
- bool is_smooth,
- bool is_power_efficient) {
- if (!resolver->GetExecutionContext() ||
- resolver->GetExecutionContext()->IsContextDestroyed()) {
+void MediaCapabilities::GetPerfInfo_ML(ExecutionContext* execution_context,
+ int callback_id,
+ media::VideoCodec video_codec,
+ media::VideoCodecProfile video_profile,
+ int width,
+ double framerate) {
+ DCHECK(execution_context && !execution_context->IsContextDestroyed());
+ DCHECK(pending_cb_map_.Contains(callback_id));
+
+ if (!EnsureLearningPredictors(execution_context)) {
+ return;
+ }
+
+ // FRAGILE: Order here MUST match order in
+ // WebMediaPlayerImpl::UpdateSmoothnessHelper().
+ // TODO(chcunningham): refactor into something more robust.
+ Vector<media::learning::FeatureValue> ml_features(
+ {media::learning::FeatureValue(video_codec),
+ media::learning::FeatureValue(video_profile),
+ media::learning::FeatureValue(width),
+ media::learning::FeatureValue(framerate)});
+
+ if (bad_window_predictor_) {
+ bad_window_predictor_->PredictDistribution(
+ ml_features, WTF::Bind(&MediaCapabilities::OnBadWindowPrediction,
+ WrapPersistent(this), callback_id));
+ }
+
+ if (nnr_predictor_) {
+ nnr_predictor_->PredictDistribution(
+ ml_features, WTF::Bind(&MediaCapabilities::OnNnrPrediction,
+ WrapPersistent(this), callback_id));
+ }
+}
+
+void MediaCapabilities::ResolveCallbackIfReady(int callback_id) {
+ DCHECK(pending_cb_map_.Contains(callback_id));
+ PendingCallbackState* pending_cb = pending_cb_map_.at(callback_id);
+
+ 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());
+
+ if (nnr_predictor_ && !pending_cb->is_nnr_prediction_smooth.has_value())
+ return;
+
+ if (bad_window_predictor_ &&
+ !pending_cb->is_bad_window_prediction_smooth.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
+ // to erase the entry in the map.
+ pending_cb_map_.erase(callback_id);
return;
}
Persistent<MediaCapabilitiesDecodingInfo> info(
MediaCapabilitiesDecodingInfo::Create());
info->setSupported(true);
- info->setSmooth(is_smooth);
- info->setPowerEfficient(is_power_efficient);
- info->setKeySystemAccess(access);
+ info->setKeySystemAccess(pending_cb->key_system_access);
+ 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() ||
+ pending_cb->is_nnr_prediction_smooth.has_value()) {
+ info->setSmooth(
+ pending_cb->is_bad_window_prediction_smooth.value_or(true) &&
+ pending_cb->is_nnr_prediction_smooth.value_or(true));
+ } else {
+ // Use DB when ML experiment not running.
+ info->setSmooth(*pending_cb->db_is_smooth);
+ }
- resolver->Resolve(std::move(info));
+ pending_cb->resolver->Resolve(std::move(info));
+ pending_cb_map_.erase(callback_id);
+}
+
+void MediaCapabilities::OnBadWindowPrediction(
+ int callback_id,
+ const base::Optional<::media::learning::TargetHistogram>& histogram) {
+ DCHECK(pending_cb_map_.Contains(callback_id));
+ PendingCallbackState* pending_cb = pending_cb_map_.at(callback_id);
+
+ std::stringstream histogram_log;
+ if (!histogram) {
+ // No data, so optimistically assume zero bad windows.
+ pending_cb->is_bad_window_prediction_smooth = true;
+ histogram_log << "none";
+ } else {
+ double histogram_average = histogram->Average();
+ pending_cb->is_bad_window_prediction_smooth =
+ histogram_average <= GetLearningBadWindowThreshold();
+ histogram_log << histogram_average;
+ }
+
+ DVLOG(2) << __func__ << " bad_win_avg:" << histogram_log.str()
+ << " smooth_threshold (<=):" << GetLearningBadWindowThreshold();
+
+ ResolveCallbackIfReady(callback_id);
+}
+
+void MediaCapabilities::OnNnrPrediction(
+ int callback_id,
+ const base::Optional<::media::learning::TargetHistogram>& histogram) {
+ DCHECK(pending_cb_map_.Contains(callback_id));
+ PendingCallbackState* pending_cb = pending_cb_map_.at(callback_id);
+
+ std::stringstream histogram_log;
+ if (!histogram) {
+ // No data, so optimistically assume zero NNRs
+ pending_cb->is_nnr_prediction_smooth = true;
+ histogram_log << "none";
+ } else {
+ double histogram_average = histogram->Average();
+ pending_cb->is_nnr_prediction_smooth =
+ histogram_average <= GetLearningNnrThreshold();
+ histogram_log << histogram_average;
+ }
+
+ DVLOG(2) << __func__ << " nnr_avg:" << histogram_log.str()
+ << " smooth_threshold (<=):" << GetLearningNnrThreshold();
+
+ ResolveCallbackIfReady(callback_id);
+}
+
+void MediaCapabilities::OnPerfHistoryInfo(int callback_id,
+ bool is_smooth,
+ bool is_power_efficient) {
+ DCHECK(pending_cb_map_.Contains(callback_id));
+ PendingCallbackState* pending_cb = pending_cb_map_.at(callback_id);
+
+ pending_cb->db_is_smooth = is_smooth;
+ pending_cb->db_is_power_efficient = is_power_efficient;
+
+ ResolveCallbackIfReady(callback_id);
+}
+
+int MediaCapabilities::CreateCallbackId() {
+ ++last_callback_id_;
+ return last_callback_id_;
}
} // namespace blink
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 425842e12aa..cfb0b12b792 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
@@ -6,15 +6,19 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CAPABILITIES_MEDIA_CAPABILITIES_H_
#include "media/base/video_codecs.h" // for media::VideoCodecProfile
+#include "media/learning/mojo/public/cpp/mojo_learning_task_controller.h"
+#include "media/learning/mojo/public/mojom/learning_task_controller.mojom-blink.h"
#include "media/mojo/mojom/video_decode_perf_history.mojom-blink.h"
#include "mojo/public/cpp/bindings/remote.h"
-#include "third_party/blink/renderer/modules/media_capabilities/video_configuration.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_video_configuration.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/heap/visitor.h"
+#include "third_party/blink/renderer/platform/wtf/hash_map.h"
namespace blink {
+class ExceptionState;
class ExecutionContext;
class MediaDecodingConfiguration;
class MediaEncodingConfiguration;
@@ -27,31 +31,108 @@ class MODULES_EXPORT MediaCapabilities final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
+ static const char kLearningBadWindowThresholdParamName[];
+ static const char kLearningNnrThresholdParamName[];
+
MediaCapabilities();
- ScriptPromise decodingInfo(ScriptState*, const MediaDecodingConfiguration*);
+ void Trace(blink::Visitor* visitor) override;
+
+ ScriptPromise decodingInfo(ScriptState*,
+ const MediaDecodingConfiguration*,
+ ExceptionState&);
ScriptPromise encodingInfo(ScriptState*, const MediaEncodingConfiguration*);
private:
- // Binds to the VideoDecodePerfHistory service. Returns whether it was
+ // Stores pending callback state from and intermediate prediction values while
+ // we wait for all predictions to arrive.
+ class PendingCallbackState : public GarbageCollected<PendingCallbackState> {
+ public:
+ PendingCallbackState(ScriptPromiseResolver* resolver,
+ MediaKeySystemAccess* access);
+ virtual void Trace(blink::Visitor* visitor);
+
+ Member<ScriptPromiseResolver> resolver;
+ Member<MediaKeySystemAccess> key_system_access;
+ base::Optional<bool> is_bad_window_prediction_smooth;
+ base::Optional<bool> is_nnr_prediction_smooth;
+ base::Optional<bool> db_is_smooth;
+ base::Optional<bool> db_is_power_efficient;
+ };
+
+ // Lazily binds remote LearningTaskControllers for ML smoothness predictions
+ // and returns whether binding succeeds. Returns true if it was already bound.
+ bool EnsureLearningPredictors(ExecutionContext*);
+
+ // Lazily binds to the VideoDecodePerfHistory service. Returns whether it was
// successful. Returns true if it was already bound.
- bool EnsureService(ExecutionContext*);
+ bool EnsurePerfHistoryService(ExecutionContext*);
ScriptPromise GetEmeSupport(ScriptState*,
+ media::VideoCodec,
media::VideoCodecProfile,
- const MediaDecodingConfiguration*);
- void GetPerfInfo(media::VideoCodecProfile,
+ const MediaDecodingConfiguration*,
+ 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*,
ScriptPromiseResolver*,
MediaKeySystemAccess*);
- void OnPerfInfo(ScriptPromiseResolver*,
- MediaKeySystemAccess*,
- bool is_smooth,
- bool is_power_efficient);
+ // Gets ML perf predictions from remote LearingTaskControllers.
+ void GetPerfInfo_ML(ExecutionContext* execution_context,
+ int callback_id,
+ media::VideoCodec video_codec,
+ media::VideoCodecProfile video_profile,
+ int width,
+ double framerate);
+
+ // Callback for perf info from the VideoDecodePerfHistory service.
+ void OnPerfHistoryInfo(int callback_id,
+ bool is_smooth,
+ bool is_power_efficient);
+
+ // Callback for predictions from |bad_window_predictor_|.
+ void OnBadWindowPrediction(
+ int callback_id,
+ const base::Optional<::media::learning::TargetHistogram>& histogram);
+
+ // Callback for predictions from |nnr_predictor_|.
+ void OnNnrPrediction(
+ int callback_id,
+ const base::Optional<::media::learning::TargetHistogram>& histogram);
+
+ // Resolves the callback with associated |callback_id| and removes it from the
+ // |pending_callback_map_|.
+ void ResolveCallbackIfReady(int callback_id);
+
+ // Creates a new (incremented) callback ID from |last_callback_id_| for
+ // mapping in |pending_cb_map_|.
+ int CreateCallbackId();
mojo::Remote<media::mojom::blink::VideoDecodePerfHistory>
decode_history_service_;
+
+ // Connection to a browser-process LearningTaskController for predicting the
+ // number of consecutive "bad" dropped frame windows during a playback. See
+ // media::SmoothnessHelper.
+ mojo::Remote<media::learning::mojom::blink::LearningTaskController>
+ bad_window_predictor_;
+
+ // Connects to a browser-process LearningTaskController for predicting the
+ // number of consecutive non-network re-buffers (NNRs). See
+ // media::SmoothnessHelper.
+ mojo::Remote<media::learning::mojom::blink::LearningTaskController>
+ nnr_predictor_;
+
+ // Holds the last key for callbacks in the map below. Incremented for each
+ // usage.
+ int last_callback_id_ = 0;
+
+ // Maps a callback ID to state for pending callbacks.
+ HeapHashMap<int, Member<PendingCallbackState>> pending_cb_map_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.idl b/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.idl
index 84997077776..04d433224de 100644
--- a/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.idl
+++ b/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.idl
@@ -6,7 +6,7 @@
[Exposed=(Window,Worker)]
interface MediaCapabilities {
- [CallWith=ScriptState, Measure] Promise<MediaCapabilitiesDecodingInfo> decodingInfo(MediaDecodingConfiguration configuration);
+ [CallWith=ScriptState, RaisesException, Measure] Promise<MediaCapabilitiesDecodingInfo> decodingInfo(MediaDecodingConfiguration configuration);
[CallWith=ScriptState, Measure, RuntimeEnabled=MediaCapabilitiesEncodingInfo] Promise<MediaCapabilitiesInfo> encodingInfo(
MediaEncodingConfiguration configuration);
};
diff --git a/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities_fuzzer.cc b/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities_fuzzer.cc
index ad066d87993..ad6f454d451 100644
--- a/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities_fuzzer.cc
+++ b/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities_fuzzer.cc
@@ -4,14 +4,15 @@
#include "testing/libfuzzer/proto/lpm_interface.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_audio_configuration.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_key_system_track_configuration.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_capabilities_key_system_configuration.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_decoding_configuration.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
-#include "third_party/blink/renderer/modules/media_capabilities/audio_configuration.h"
#include "third_party/blink/renderer/modules/media_capabilities/fuzzer_media_configuration.pb.h"
-#include "third_party/blink/renderer/modules/media_capabilities/key_system_track_configuration.h"
#include "third_party/blink/renderer/modules/media_capabilities/media_capabilities.h"
-#include "third_party/blink/renderer/modules/media_capabilities/media_capabilities_key_system_configuration.h"
-#include "third_party/blink/renderer/modules/media_capabilities/media_decoding_configuration.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/v8_per_isolate_data.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
@@ -141,7 +142,8 @@ DEFINE_TEXT_PROTO_FUZZER(const mc_fuzzer::MediaDecodingConfigProto& proto) {
ScriptState::Scope scope(script_state);
auto* media_capabilities = MakeGarbageCollected<MediaCapabilities>();
- media_capabilities->decodingInfo(script_state, config);
+ media_capabilities->decodingInfo(script_state, config,
+ IGNORE_EXCEPTION_FOR_TESTING);
// Request a V8 GC. Oilpan will be invoked by the GC epilogue.
//
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
new file mode 100644
index 00000000000..a1799958847
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities_test.cc
@@ -0,0 +1,813 @@
+// 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/media_capabilities/media_capabilities.h"
+
+#include <math.h>
+
+#include <algorithm>
+
+#include "base/strings/string_number_conversions.h"
+#include "base/test/bind_test_util.h"
+#include "base/test/scoped_feature_list.h"
+#include "media/base/media_switches.h"
+#include "media/base/video_codecs.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/mojo/mojom/video_decode_perf_history.mojom-blink.h"
+#include "media/mojo/mojom/watch_time_recorder.mojom-blink.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
+#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_media_capabilities_info.h"
+#include "third_party/blink/renderer/core/testing/page_test_base.h"
+#include "third_party/blink/renderer/modules/media_capabilities/media_capabilities_info.h"
+#include "third_party/blink/renderer/modules/media_capabilities/media_configuration.h"
+#include "third_party/blink/renderer/modules/media_capabilities/media_decoding_configuration.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.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"
+#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
+#include "third_party/googletest/src/googlemock/include/gmock/gmock-actions.h"
+#include "ui/gfx/geometry/size.h"
+
+using ::media::learning::FeatureValue;
+using ::media::learning::ObservationCompletion;
+using ::media::learning::TargetValue;
+using ::testing::_;
+using ::testing::Invoke;
+using ::testing::Unused;
+
+namespace blink {
+
+namespace {
+
+// Simulating the browser-side service.
+class MockPerfHistoryService
+ : public media::mojom::blink::VideoDecodePerfHistory {
+ public:
+ void BindRequest(mojo::ScopedMessagePipeHandle handle) {
+ receiver_.Bind(
+ mojo::PendingReceiver<media::mojom::blink::VideoDecodePerfHistory>(
+ std::move(handle)));
+ receiver_.set_disconnect_handler(base::BindRepeating(
+ &MockPerfHistoryService::OnConnectionError, base::Unretained(this)));
+ }
+
+ void OnConnectionError() { receiver_.reset(); }
+
+ // media::mojom::blink::VideoDecodePerfHistory implementation:
+ MOCK_METHOD2(GetPerfInfo,
+ void(media::mojom::blink::PredictionFeaturesPtr features,
+ GetPerfInfoCallback got_info_cb));
+
+ private:
+ mojo::Receiver<media::mojom::blink::VideoDecodePerfHistory> receiver_{this};
+};
+
+class MockLearningTaskControllerService
+ : public media::learning::mojom::blink::LearningTaskController {
+ public:
+ void BindRequest(mojo::PendingReceiver<
+ media::learning::mojom::blink::LearningTaskController>
+ pending_receiver) {
+ receiver_.Bind(std::move(pending_receiver));
+ receiver_.set_disconnect_handler(base::BindRepeating(
+ &MockLearningTaskControllerService::OnConnectionError,
+ base::Unretained(this)));
+ }
+
+ void OnConnectionError() { receiver_.reset(); }
+
+ bool is_bound() const { return receiver_.is_bound(); }
+
+ // media::mojom::blink::LearningTaskController implementation:
+ MOCK_METHOD3(BeginObservation,
+ void(const base::UnguessableToken& id,
+ const WTF::Vector<FeatureValue>& features,
+ const base::Optional<TargetValue>& default_target));
+ MOCK_METHOD2(CompleteObservation,
+ void(const base::UnguessableToken& id,
+ const ObservationCompletion& completion));
+ MOCK_METHOD1(CancelObservation, void(const base::UnguessableToken& id));
+ MOCK_METHOD2(UpdateDefaultTarget,
+ void(const base::UnguessableToken& id,
+ const base::Optional<TargetValue>& default_target));
+ MOCK_METHOD2(PredictDistribution,
+ void(const WTF::Vector<FeatureValue>& features,
+ PredictDistributionCallback callback));
+
+ private:
+ mojo::Receiver<media::learning::mojom::blink::LearningTaskController>
+ receiver_{this};
+};
+
+class FakeMediaMetricsProvider
+ : public media::mojom::blink::MediaMetricsProvider {
+ public:
+ // Raw pointers to services owned by the test.
+ FakeMediaMetricsProvider(
+ MockLearningTaskControllerService* bad_window_service,
+ MockLearningTaskControllerService* nnr_service)
+ : bad_window_service_(bad_window_service), nnr_service_(nnr_service) {}
+
+ ~FakeMediaMetricsProvider() override = default;
+
+ void BindRequest(mojo::ScopedMessagePipeHandle handle) {
+ receiver_.Bind(
+ mojo::PendingReceiver<media::mojom::blink::MediaMetricsProvider>(
+ std::move(handle)));
+ receiver_.set_disconnect_handler(base::BindRepeating(
+ &FakeMediaMetricsProvider::OnConnectionError, base::Unretained(this)));
+ }
+
+ void OnConnectionError() { receiver_.reset(); }
+
+ // mojom::WatchTimeRecorderProvider implementation:
+ void AcquireWatchTimeRecorder(
+ media::mojom::blink::PlaybackPropertiesPtr properties,
+ mojo::PendingReceiver<media::mojom::blink::WatchTimeRecorder> receiver)
+ override {
+ FAIL();
+ }
+ void AcquireVideoDecodeStatsRecorder(
+ mojo::PendingReceiver<media::mojom::blink::VideoDecodeStatsRecorder>
+ receiver) override {
+ FAIL();
+ }
+ void AcquireLearningTaskController(
+ const WTF::String& taskName,
+ mojo::PendingReceiver<
+ media::learning::mojom::blink::LearningTaskController>
+ pending_receiver) override {
+ if (taskName == media::learning::tasknames::kConsecutiveBadWindows) {
+ bad_window_service_->BindRequest(std::move(pending_receiver));
+ return;
+ }
+
+ if (taskName == media::learning::tasknames::kConsecutiveNNRs) {
+ nnr_service_->BindRequest(std::move(pending_receiver));
+ return;
+ }
+ FAIL();
+ }
+ void Initialize(bool is_mse,
+ media::mojom::MediaURLScheme url_scheme) override {}
+ void OnError(media::mojom::PipelineStatus status) override {}
+ void SetIsEME() override {}
+ void SetTimeToMetadata(base::TimeDelta elapsed) override {}
+ void SetTimeToFirstFrame(base::TimeDelta elapsed) override {}
+ void SetTimeToPlayReady(base::TimeDelta elapsed) override {}
+ void SetContainerName(
+ media::mojom::blink::MediaContainerName container_name) override {}
+ void SetHasPlayed() override {}
+ void SetHaveEnough() override {}
+ void SetHasAudio(media::mojom::AudioCodec audio_codec) override {}
+ void SetHasVideo(media::mojom::VideoCodec video_codec) override {}
+ void SetVideoPipelineInfo(
+ media::mojom::blink::PipelineDecoderInfoPtr info) override {}
+ void SetAudioPipelineInfo(
+ media::mojom::blink::PipelineDecoderInfoPtr info) override {}
+
+ private:
+ mojo::Receiver<media::mojom::blink::MediaMetricsProvider> receiver_{this};
+ MockLearningTaskControllerService* bad_window_service_;
+ MockLearningTaskControllerService* nnr_service_;
+};
+
+// Simple helper for saving back-end callbacks for pending decodingInfo() calls.
+// Callers can then manually fire the callbacks, gaining fine-grain control of
+// the timing and order of their arrival.
+class CallbackSaver {
+ public:
+ void SavePerfHistoryCallback(
+ media::mojom::blink::PredictionFeaturesPtr features,
+ MockPerfHistoryService::GetPerfInfoCallback got_info_cb) {
+ perf_history_cb_ = std::move(got_info_cb);
+ }
+
+ void SaveBadWindowCallback(
+ Vector<media::learning::FeatureValue> features,
+ MockLearningTaskControllerService::PredictDistributionCallback
+ predict_cb) {
+ bad_window_cb_ = std::move(predict_cb);
+ }
+
+ void SaveNnrCallback(
+ Vector<media::learning::FeatureValue> features,
+ MockLearningTaskControllerService::PredictDistributionCallback
+ predict_cb) {
+ nnr_cb_ = std::move(predict_cb);
+ }
+
+ MockPerfHistoryService::GetPerfInfoCallback& perf_history_cb() {
+ return perf_history_cb_;
+ }
+
+ MockLearningTaskControllerService::PredictDistributionCallback&
+ bad_window_cb() {
+ return bad_window_cb_;
+ }
+
+ MockLearningTaskControllerService::PredictDistributionCallback& nnr_cb() {
+ return nnr_cb_;
+ }
+
+ private:
+ MockPerfHistoryService::GetPerfInfoCallback perf_history_cb_;
+ MockLearningTaskControllerService::PredictDistributionCallback bad_window_cb_;
+ MockLearningTaskControllerService::PredictDistributionCallback nnr_cb_;
+};
+
+// This would typically be a test fixture, but we need it to be
+// STACK_ALLOCATED() in order to use V8TestingScope, and we can't force that on
+// whatever gtest class instantiates the fixture.
+class MediaCapabilitiesTestContext {
+ STACK_ALLOCATED();
+
+ public:
+ MediaCapabilitiesTestContext() {
+ perf_history_service_ = std::make_unique<MockPerfHistoryService>();
+ bad_window_service_ = std::make_unique<MockLearningTaskControllerService>();
+ nnr_service_ = std::make_unique<MockLearningTaskControllerService>();
+ fake_metrics_provider_ = std::make_unique<FakeMediaMetricsProvider>(
+ bad_window_service_.get(), nnr_service_.get());
+
+ CHECK(
+ v8_scope_.GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting(
+ media::mojom::blink::MediaMetricsProvider::Name_,
+ base::BindRepeating(
+ &FakeMediaMetricsProvider::BindRequest,
+ base::Unretained(fake_metrics_provider_.get()))));
+
+ CHECK(
+ v8_scope_.GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting(
+ media::mojom::blink::VideoDecodePerfHistory::Name_,
+ base::BindRepeating(
+ &MockPerfHistoryService::BindRequest,
+ base::Unretained(perf_history_service_.get()))));
+
+ media_capabilities_ = MakeGarbageCollected<MediaCapabilities>();
+ }
+
+ ~MediaCapabilitiesTestContext() {
+ CHECK(
+ v8_scope_.GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting(
+ media::mojom::blink::MediaMetricsProvider::Name_, {}));
+
+ CHECK(
+ v8_scope_.GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting(
+ media::mojom::blink::VideoDecodePerfHistory::Name_, {}));
+ }
+
+ ExceptionState& GetExceptionState() { return v8_scope_.GetExceptionState(); }
+
+ ScriptState* GetScriptState() const { return v8_scope_.GetScriptState(); }
+
+ v8::Isolate* GetIsolate() const { return GetScriptState()->GetIsolate(); }
+
+ MediaCapabilities* GetMediaCapabilities() const {
+ return media_capabilities_.Get();
+ }
+
+ MockPerfHistoryService* GetPerfHistoryService() const {
+ return perf_history_service_.get();
+ }
+
+ MockLearningTaskControllerService* GetBadWindowService() const {
+ return bad_window_service_.get();
+ }
+
+ MockLearningTaskControllerService* GetNnrService() const {
+ return nnr_service_.get();
+ }
+
+ void VerifyAndClearMockExpectations() {
+ testing::Mock::VerifyAndClearExpectations(GetPerfHistoryService());
+ testing::Mock::VerifyAndClearExpectations(GetNnrService());
+ testing::Mock::VerifyAndClearExpectations(GetBadWindowService());
+ }
+
+ private:
+ V8TestingScope v8_scope_;
+ std::unique_ptr<MockPerfHistoryService> perf_history_service_;
+ std::unique_ptr<FakeMediaMetricsProvider> fake_metrics_provider_;
+ Persistent<MediaCapabilities> media_capabilities_;
+ std::unique_ptr<MockLearningTaskControllerService> bad_window_service_;
+ std::unique_ptr<MockLearningTaskControllerService> nnr_service_;
+};
+
+// |kContentType|, |kCodec|, and |kCodecProfile| must match.
+const char kContentType[] = "video/webm; codecs=\"vp09.00.10.08\"";
+const media::VideoCodecProfile kCodecProfile = media::VP9PROFILE_PROFILE0;
+const media::VideoCodec kCodec = media::kCodecVP9;
+const double kFramerate = 20.5;
+const int kWidth = 3840;
+const int kHeight = 2160;
+const int kBitrate = 2391000;
+
+// Construct VideoConfig using the constants above.
+MediaDecodingConfiguration* CreateDecodingConfig() {
+ auto* video_config = MakeGarbageCollected<VideoConfiguration>();
+ video_config->setFramerate(kFramerate);
+ video_config->setContentType(kContentType);
+ video_config->setWidth(kWidth);
+ video_config->setHeight(kHeight);
+ video_config->setBitrate(kBitrate);
+ auto* decoding_config = MakeGarbageCollected<MediaDecodingConfiguration>();
+ decoding_config->setType("media-source");
+ decoding_config->setVideo(video_config);
+ return decoding_config;
+}
+
+// Construct PredicitonFeatures matching the CreateDecodingConfig, using the
+// constants above.
+media::mojom::blink::PredictionFeatures CreateFeatures() {
+ media::mojom::blink::PredictionFeatures features;
+ features.profile =
+ static_cast<media::mojom::blink::VideoCodecProfile>(kCodecProfile);
+ features.video_size = gfx::Size(kWidth, kHeight);
+ features.frames_per_sec = kFramerate;
+
+ // Not set by any tests so far. Choosing sane defaults to mirror production
+ // code.
+ features.key_system = "";
+ features.use_hw_secure_codecs = false;
+
+ return features;
+}
+
+Vector<media::learning::FeatureValue> CreateFeaturesML() {
+ media::mojom::blink::PredictionFeatures features = CreateFeatures();
+
+ // FRAGILE: Order here MUST match order in
+ // WebMediaPlayerImpl::UpdateSmoothnessHelper().
+ // TODO(chcunningham): refactor into something more robust.
+ Vector<media::learning::FeatureValue> ml_features(
+ {media::learning::FeatureValue(kCodec),
+ media::learning::FeatureValue(kCodecProfile),
+ media::learning::FeatureValue(kWidth),
+ media::learning::FeatureValue(kFramerate)});
+
+ return ml_features;
+}
+
+// Types of smoothness predictions.
+enum class PredictionType {
+ kDB,
+ kBadWindow,
+ kNnr,
+};
+
+// Makes a TargetHistogram with single count at |target_value|.
+media::learning::TargetHistogram MakeHistogram(double target_value) {
+ media::learning::TargetHistogram histogram;
+ histogram += media::learning::TargetValue(target_value);
+ return histogram;
+}
+
+// Makes DB (PerfHistoryService) callback for use with gtest WillOnce().
+// Callback will verify |features| matches |expected_features| and run with
+// provided values for |is_smooth| and |is_power_efficient|.
+testing::Action<void(media::mojom::blink::PredictionFeaturesPtr,
+ MockPerfHistoryService::GetPerfInfoCallback)>
+DbCallback(const media::mojom::blink::PredictionFeatures& expected_features,
+ bool is_smooth,
+ bool is_power_efficient) {
+ return [=](media::mojom::blink::PredictionFeaturesPtr features,
+ MockPerfHistoryService::GetPerfInfoCallback got_info_cb) {
+ EXPECT_TRUE(features->Equals(expected_features));
+ std::move(got_info_cb).Run(is_smooth, is_power_efficient);
+ };
+}
+
+// Makes ML (LearningTaskControllerService) callback for use with gtest
+// WillOnce(). Callback will verify |features| matches |expected_features| and
+// run a TargetHistogram containing a single count for |histogram_target|.
+testing::Action<void(
+ const Vector<media::learning::FeatureValue>&,
+ MockLearningTaskControllerService::PredictDistributionCallback predict_cb)>
+MlCallback(const Vector<media::learning::FeatureValue>& expected_features,
+ double histogram_target) {
+ return [=](const Vector<media::learning::FeatureValue>& features,
+ MockLearningTaskControllerService::PredictDistributionCallback
+ predict_cb) {
+ EXPECT_EQ(features, expected_features);
+ std::move(predict_cb).Run(MakeHistogram(histogram_target));
+ };
+}
+
+// Helper to constructs field trial params with given ML prediction thresholds.
+base::FieldTrialParams MakeMlParams(double bad_window_threshold,
+ double nnr_threshold) {
+ base::FieldTrialParams params;
+ params[MediaCapabilities::kLearningBadWindowThresholdParamName] =
+ base::NumberToString(bad_window_threshold);
+ params[MediaCapabilities::kLearningNnrThresholdParamName] =
+ base::NumberToString(nnr_threshold);
+ return params;
+}
+
+// Wrapping deocdingInfo() call for readability. Await resolution of the promise
+// and return its info.
+MediaCapabilitiesInfo* DecodingInfo(
+ const MediaDecodingConfiguration* decoding_config,
+ MediaCapabilitiesTestContext* context) {
+ ScriptPromise promise = context->GetMediaCapabilities()->decodingInfo(
+ context->GetScriptState(), decoding_config, context->GetExceptionState());
+
+ ScriptPromiseTester tester(context->GetScriptState(), promise);
+ tester.WaitUntilSettled();
+
+ CHECK(!tester.IsRejected()) << " Cant get info from rejected promise.";
+
+ return NativeValueTraits<MediaCapabilitiesInfo>::NativeValue(
+ context->GetIsolate(), tester.Value().V8Value(),
+ context->GetExceptionState());
+}
+
+} // namespace
+
+// Other tests will assume these match. Test to be sure they stay in sync.
+TEST(MediaCapabilitiesTests, ConfigMatchesFeatures) {
+ const MediaDecodingConfiguration* kDecodingConfig = CreateDecodingConfig();
+ const media::mojom::blink::PredictionFeatures kFeatures = CreateFeatures();
+
+ EXPECT_TRUE(kDecodingConfig->video()->contentType().Contains("vp09.00"));
+ EXPECT_EQ(static_cast<media::VideoCodecProfile>(kFeatures.profile),
+ media::VP9PROFILE_PROFILE0);
+ EXPECT_EQ(kCodecProfile, media::VP9PROFILE_PROFILE0);
+
+ EXPECT_EQ(kDecodingConfig->video()->framerate(), kFeatures.frames_per_sec);
+ EXPECT_EQ(kDecodingConfig->video()->width(),
+ static_cast<uint32_t>(kFeatures.video_size.width()));
+ EXPECT_EQ(kDecodingConfig->video()->height(),
+ static_cast<uint32_t>(kFeatures.video_size.height()));
+}
+
+// Test that non-integer framerate isn't truncated by IPC.
+// https://crbug.com/1024399
+TEST(MediaCapabilitiesTests, NonIntegerFramerate) {
+ MediaCapabilitiesTestContext context;
+
+ const auto* kDecodingConfig = CreateDecodingConfig();
+ const media::mojom::blink::PredictionFeatures kFeatures = CreateFeatures();
+
+ // FPS for this test must not be a whole number. Assert to ensure the default
+ // config meets that condition.
+ ASSERT_NE(fmod(kDecodingConfig->video()->framerate(), 1), 0);
+
+ EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _))
+ .WillOnce([&](media::mojom::blink::PredictionFeaturesPtr features,
+ MockPerfHistoryService::GetPerfInfoCallback got_info_cb) {
+ // Explicitly check for frames_per_sec equality.
+ // PredictionFeatures::Equals() will not catch loss of precision if
+ // frames_per_sec is made to be int (currently a double).
+ EXPECT_EQ(features->frames_per_sec, kFramerate);
+
+ // Check that other things match as well.
+ EXPECT_TRUE(features->Equals(kFeatures));
+
+ std::move(got_info_cb).Run(/*smooth*/ true, /*power_efficient*/ true);
+ });
+
+ MediaCapabilitiesInfo* info = DecodingInfo(kDecodingConfig, &context);
+ EXPECT_TRUE(info->smooth());
+ EXPECT_TRUE(info->powerEfficient());
+}
+
+// Test smoothness predictions from DB (PerfHistoryService).
+TEST(MediaCapabilitiesTests, PredictWithJustDB) {
+ // Disable ML predictions (may/may not be disabled by default).
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndDisableFeature(
+ media::kMediaLearningSmoothnessExperiment);
+
+ MediaCapabilitiesTestContext context;
+ const auto* kDecodingConfig = CreateDecodingConfig();
+ const media::mojom::blink::PredictionFeatures kFeatures = CreateFeatures();
+
+ // ML services should not be called for prediction.
+ EXPECT_CALL(*context.GetBadWindowService(), PredictDistribution(_, _))
+ .Times(0);
+ EXPECT_CALL(*context.GetNnrService(), PredictDistribution(_, _)).Times(0);
+
+ // DB alone (PerfHistoryService) should be called. Signal smooth=true and
+ // power_efficient = false.
+ EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _))
+ .WillOnce(DbCallback(kFeatures, /*smooth*/ true, /*power_eff*/ false));
+ MediaCapabilitiesInfo* info = DecodingInfo(kDecodingConfig, &context);
+ EXPECT_TRUE(info->smooth());
+ EXPECT_FALSE(info->powerEfficient());
+
+ // Verify DB call was made. ML services should not even be bound.
+ testing::Mock::VerifyAndClearExpectations(context.GetPerfHistoryService());
+ EXPECT_FALSE(context.GetBadWindowService()->is_bound());
+ EXPECT_FALSE(context.GetNnrService()->is_bound());
+
+ // Repeat test with inverted smooth and power_efficient results.
+ EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _))
+ .WillOnce(DbCallback(kFeatures, /*smooth*/ false, /*power_eff*/ true));
+ info = DecodingInfo(kDecodingConfig, &context);
+ EXPECT_FALSE(info->smooth());
+ EXPECT_TRUE(info->powerEfficient());
+}
+
+// Test with smoothness predictions coming solely from "bad window" ML service.
+TEST(MediaCapabilitiesTests, PredictWithBadWindowMLService) {
+ // Enable ML predictions with thresholds. -1 disables the NNR predictor.
+ const double kBadWindowThreshold = 2;
+ const double kNnrThreshold = -1;
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndEnableFeatureWithParameters(
+ media::kMediaLearningSmoothnessExperiment,
+ MakeMlParams(kBadWindowThreshold, kNnrThreshold));
+
+ MediaCapabilitiesTestContext context;
+ const auto* kDecodingConfig = CreateDecodingConfig();
+ const media::mojom::blink::PredictionFeatures kFeatures = CreateFeatures();
+ const Vector<media::learning::FeatureValue> kFeaturesML = CreateFeaturesML();
+
+ // 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.
+ EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _))
+ .WillOnce(DbCallback(kFeatures, /*smooth*/ true, /*efficient*/ false));
+ EXPECT_CALL(*context.GetBadWindowService(), PredictDistribution(_, _))
+ .WillOnce(MlCallback(kFeaturesML, kBadWindowThreshold + 0.5));
+ EXPECT_CALL(*context.GetNnrService(), PredictDistribution(_, _)).Times(0);
+ MediaCapabilitiesInfo* info = DecodingInfo(kDecodingConfig, &context);
+ EXPECT_FALSE(info->smooth());
+ EXPECT_FALSE(info->powerEfficient());
+ // NNR service should not be bound when NNR predictions disabled.
+ EXPECT_FALSE(context.GetNnrService()->is_bound());
+ context.VerifyAndClearMockExpectations();
+
+ // Same as above, but invert all signals. Expect smooth=true because bad
+ // window prediction is now = its threshold.
+ EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _))
+ .WillOnce(DbCallback(kFeatures, /*smooth*/ false, /*efficient*/ true));
+ EXPECT_CALL(*context.GetBadWindowService(), PredictDistribution(_, _))
+ .WillOnce(MlCallback(kFeaturesML, kBadWindowThreshold));
+ EXPECT_CALL(*context.GetNnrService(), PredictDistribution(_, _)).Times(0);
+ info = DecodingInfo(kDecodingConfig, &context);
+ EXPECT_TRUE(info->smooth());
+ EXPECT_TRUE(info->powerEfficient());
+ EXPECT_FALSE(context.GetNnrService()->is_bound());
+ context.VerifyAndClearMockExpectations();
+
+ // Same as above, but predict zero bad windows. Expect smooth=true because
+ // zero is below the threshold.
+ EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _))
+ .WillOnce(DbCallback(kFeatures, /*smooth*/ false, /*efficient*/ true));
+ EXPECT_CALL(*context.GetBadWindowService(), PredictDistribution(_, _))
+ .WillOnce(MlCallback(kFeaturesML, /* bad windows */ 0));
+ EXPECT_CALL(*context.GetNnrService(), PredictDistribution(_, _)).Times(0);
+ info = DecodingInfo(kDecodingConfig, &context);
+ EXPECT_TRUE(info->smooth());
+ EXPECT_TRUE(info->powerEfficient());
+ EXPECT_FALSE(context.GetNnrService()->is_bound());
+ context.VerifyAndClearMockExpectations();
+}
+
+// Test with smoothness predictions coming solely from "NNR" ML service.
+TEST(MediaCapabilitiesTests, PredictWithNnrMLService) {
+ // Enable ML predictions with thresholds. -1 disables the bad window
+ // predictor.
+ const double kBadWindowThreshold = -1;
+ const double kNnrThreshold = 5;
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndEnableFeatureWithParameters(
+ media::kMediaLearningSmoothnessExperiment,
+ MakeMlParams(kBadWindowThreshold, kNnrThreshold));
+
+ MediaCapabilitiesTestContext context;
+ const auto* kDecodingConfig = CreateDecodingConfig();
+ const media::mojom::blink::PredictionFeatures kFeatures = CreateFeatures();
+ const Vector<media::learning::FeatureValue> kFeaturesML = CreateFeaturesML();
+
+ // 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.
+ 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));
+ MediaCapabilitiesInfo* info = DecodingInfo(kDecodingConfig, &context);
+ EXPECT_FALSE(info->smooth());
+ EXPECT_FALSE(info->powerEfficient());
+ // Bad window service should not be bound when NNR predictions disabled.
+ EXPECT_FALSE(context.GetBadWindowService()->is_bound());
+ context.VerifyAndClearMockExpectations();
+
+ // Same as above, but invert all signals. Expect smooth=true because NNR
+ // prediction is now = 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));
+ info = DecodingInfo(kDecodingConfig, &context);
+ EXPECT_TRUE(info->smooth());
+ EXPECT_TRUE(info->powerEfficient());
+ EXPECT_FALSE(context.GetBadWindowService()->is_bound());
+ context.VerifyAndClearMockExpectations();
+
+ // Same as above, but predict zero NNRs. Expect smooth=true because zero is
+ // below the 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, /* NNRs */ 0));
+ info = DecodingInfo(kDecodingConfig, &context);
+ EXPECT_TRUE(info->smooth());
+ EXPECT_TRUE(info->powerEfficient());
+ EXPECT_FALSE(context.GetBadWindowService()->is_bound());
+ context.VerifyAndClearMockExpectations();
+}
+
+// Test with combined smoothness predictions from both ML services.
+TEST(MediaCapabilitiesTests, PredictWithBothMLServices) {
+ // Enable ML predictions with thresholds.
+ const double kBadWindowThreshold = 2;
+ const double kNnrThreshold = 1;
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndEnableFeatureWithParameters(
+ media::kMediaLearningSmoothnessExperiment,
+ MakeMlParams(kBadWindowThreshold, kNnrThreshold));
+
+ MediaCapabilitiesTestContext context;
+ const auto* kDecodingConfig = CreateDecodingConfig();
+ const media::mojom::blink::PredictionFeatures kFeatures = CreateFeatures();
+ const Vector<media::learning::FeatureValue> kFeaturesML = CreateFeaturesML();
+
+ // ML is enabled, but DB should still be called for power efficiency (false).
+ // Its smoothness value (true) should be ignored in favor of ML predictions.
+ // Both ML services should be called for prediction. In both cases we exceed
+ // the threshold, such that smooth=false.
+ EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _))
+ .WillOnce(DbCallback(kFeatures, /*smooth*/ true, /*efficient*/ false));
+ EXPECT_CALL(*context.GetBadWindowService(), PredictDistribution(_, _))
+ .WillOnce(MlCallback(kFeaturesML, kBadWindowThreshold + 0.5));
+ EXPECT_CALL(*context.GetNnrService(), PredictDistribution(_, _))
+ .WillOnce(MlCallback(kFeaturesML, kNnrThreshold + 0.5));
+ MediaCapabilitiesInfo* info = DecodingInfo(kDecodingConfig, &context);
+ EXPECT_FALSE(info->smooth());
+ EXPECT_FALSE(info->powerEfficient());
+ context.VerifyAndClearMockExpectations();
+
+ // Make another call to DecodingInfo with one "bad window" prediction
+ // indicating smooth=false, while nnr prediction indicates smooth=true. Verify
+ // resulting info predicts false, as the logic should OR the false signals.
+ EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _))
+ .WillOnce(DbCallback(kFeatures, /*smooth*/ true, /*efficient*/ false));
+ EXPECT_CALL(*context.GetBadWindowService(), PredictDistribution(_, _))
+ .WillOnce(MlCallback(kFeaturesML, kBadWindowThreshold + 0.5));
+ EXPECT_CALL(*context.GetNnrService(), PredictDistribution(_, _))
+ .WillOnce(MlCallback(kFeaturesML, kNnrThreshold / 2));
+ info = DecodingInfo(kDecodingConfig, &context);
+ EXPECT_FALSE(info->smooth());
+ EXPECT_FALSE(info->powerEfficient());
+ context.VerifyAndClearMockExpectations();
+
+ // Same as above, but invert predictions from ML services. Outcome should
+ // still be smooth=false (logic is ORed).
+ EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _))
+ .WillOnce(DbCallback(kFeatures, /*smooth*/ true, /*efficient*/ false));
+ EXPECT_CALL(*context.GetBadWindowService(), PredictDistribution(_, _))
+ .WillOnce(MlCallback(kFeaturesML, kBadWindowThreshold / 2));
+ EXPECT_CALL(*context.GetNnrService(), PredictDistribution(_, _))
+ .WillOnce(MlCallback(kFeaturesML, kNnrThreshold + 0.5));
+ info = DecodingInfo(kDecodingConfig, &context);
+ EXPECT_FALSE(info->smooth());
+ EXPECT_FALSE(info->powerEfficient());
+ context.VerifyAndClearMockExpectations();
+
+ // This time both ML services agree smooth=true while DB predicts
+ // smooth=false. Expect info->smooth() = true, as only ML predictions matter
+ // when ML experiment enabled.
+ EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _))
+ .WillOnce(DbCallback(kFeatures, /*smooth*/ false, /*efficient*/ true));
+ EXPECT_CALL(*context.GetBadWindowService(), PredictDistribution(_, _))
+ .WillOnce(MlCallback(kFeaturesML, kBadWindowThreshold / 2));
+ EXPECT_CALL(*context.GetNnrService(), PredictDistribution(_, _))
+ .WillOnce(MlCallback(kFeaturesML, kNnrThreshold / 2));
+ info = DecodingInfo(kDecodingConfig, &context);
+ EXPECT_TRUE(info->smooth());
+ EXPECT_TRUE(info->powerEfficient());
+ 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.
+ EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _))
+ .WillOnce(DbCallback(kFeatures, /*smooth*/ false, /*efficient*/ true));
+ EXPECT_CALL(*context.GetBadWindowService(), PredictDistribution(_, _))
+ .WillOnce(MlCallback(kFeaturesML, kBadWindowThreshold / 2));
+ EXPECT_CALL(*context.GetNnrService(), PredictDistribution(_, _))
+ .WillOnce(MlCallback(kFeaturesML, kNnrThreshold / 2));
+ info = DecodingInfo(kDecodingConfig, &context);
+ EXPECT_TRUE(info->smooth());
+ EXPECT_TRUE(info->powerEfficient());
+ context.VerifyAndClearMockExpectations();
+}
+
+// Simulate a call to DecodingInfo with smoothness predictions arriving in the
+// specified |callback_order|. Ensure that promise resolves correctly only after
+// all callbacks have arrived.
+void RunCallbackPermutationTest(std::vector<PredictionType> callback_order) {
+ // Enable ML predictions with thresholds.
+ const double kBadWindowThreshold = 2;
+ const double kNnrThreshold = 3;
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndEnableFeatureWithParameters(
+ media::kMediaLearningSmoothnessExperiment,
+ MakeMlParams(kBadWindowThreshold, kNnrThreshold));
+
+ MediaCapabilitiesTestContext context;
+ const auto* kDecodingConfig = CreateDecodingConfig();
+
+ // DB and both ML services should be called. Save their callbacks.
+ CallbackSaver cb_saver;
+ EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _))
+ .WillOnce(Invoke(&cb_saver, &CallbackSaver::SavePerfHistoryCallback));
+ EXPECT_CALL(*context.GetBadWindowService(), PredictDistribution(_, _))
+ .WillOnce(Invoke(&cb_saver, &CallbackSaver::SaveBadWindowCallback));
+ EXPECT_CALL(*context.GetNnrService(), PredictDistribution(_, _))
+ .WillOnce(Invoke(&cb_saver, &CallbackSaver::SaveNnrCallback));
+
+ // Call decodingInfo() to kick off the calls to prediction services.
+ ScriptPromise promise = context.GetMediaCapabilities()->decodingInfo(
+ context.GetScriptState(), kDecodingConfig, context.GetExceptionState());
+ ScriptPromiseTester tester(context.GetScriptState(), promise);
+
+ // 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());
+
+ // Complete callbacks in whatever order.
+ for (size_t i = 0; i < callback_order.size(); ++i) {
+ switch (callback_order[i]) {
+ case PredictionType::kDB:
+ std::move(cb_saver.perf_history_cb()).Run(true, true);
+ break;
+ case PredictionType::kBadWindow:
+ std::move(cb_saver.bad_window_cb())
+ .Run(MakeHistogram(kBadWindowThreshold - 0.25));
+ break;
+ case PredictionType::kNnr:
+ std::move(cb_saver.nnr_cb()).Run(MakeHistogram(kNnrThreshold + 0.5));
+ break;
+ }
+
+ // Give mojo callbacks a chance to run.
+ test::RunPendingTasks();
+
+ // Promise should only be resolved once the final callback has run.
+ if (i < callback_order.size() - 1) {
+ ASSERT_FALSE(tester.IsFulfilled());
+ } else {
+ ASSERT_TRUE(tester.IsFulfilled());
+ }
+ }
+
+ ASSERT_FALSE(tester.IsRejected()) << " Cant get info from rejected promise.";
+ MediaCapabilitiesInfo* info =
+ NativeValueTraits<MediaCapabilitiesInfo>::NativeValue(
+ context.GetIsolate(), tester.Value().V8Value(),
+ context.GetExceptionState());
+
+ // Smooth=false because NNR prediction exceeds threshold.
+ EXPECT_FALSE(info->smooth());
+ // DB predicted power_efficient = true.
+ EXPECT_TRUE(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});
+ do {
+ RunCallbackPermutationTest(callback_order);
+ } while (std::next_permutation(callback_order.begin(), callback_order.end()));
+}
+
+} // namespace blink
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 211a47bc8f2..1cb2c91fa9f 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
@@ -22,7 +22,7 @@ MediaCapabilities* NavigatorMediaCapabilities::mediaCapabilities(
return self.capabilities_.Get();
}
-void NavigatorMediaCapabilities::Trace(blink::Visitor* visitor) {
+void NavigatorMediaCapabilities::Trace(Visitor* visitor) {
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 e5bdd820f13..a29e325682f 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 1994a3a31d2..afa60e1bb75 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
@@ -23,7 +23,7 @@ MediaCapabilities* WorkerNavigatorMediaCapabilities::mediaCapabilities(
return self.capabilities_.Get();
}
-void WorkerNavigatorMediaCapabilities::Trace(blink::Visitor* visitor) {
+void WorkerNavigatorMediaCapabilities::Trace(Visitor* visitor) {
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 13a450d7407..e16daef0396 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 2079c2ae1bd..69e49fac537 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
@@ -36,7 +36,7 @@ void MediaControlAnimatedArrowContainerElement::AnimatedArrow::ShowInternal() {
return;
}
- SetInnerHTMLFromString(MediaControlsResourceLoader::GetJumpSVGImage());
+ setInnerHTML(MediaControlsResourceLoader::GetJumpSVGImage());
last_arrow_ = getElementById("arrow-3");
svg_container_ = getElementById("jump");
@@ -121,7 +121,7 @@ void MediaControlAnimatedArrowContainerElement::ShowArrowAnimation(
}
}
-void MediaControlAnimatedArrowContainerElement::Trace(blink::Visitor* visitor) {
+void MediaControlAnimatedArrowContainerElement::Trace(Visitor* visitor) {
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 b4dd2163755..33503c4618d 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
friend class MediaControlAnimatedArrowContainerElementTest;
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 36088f32903..bd20a520d5c 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,7 +40,7 @@ class MODULES_EXPORT MediaControlAnimationEventListener final
// This is the element to watch for animation events.
virtual Element& WatchedAnimationElement() const = 0;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
};
explicit MediaControlAnimationEventListener(Observer*);
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc
index 40c812837c1..f912bf66252 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc
@@ -6,6 +6,7 @@
#include "third_party/blink/public/mojom/page/display_cutout.mojom-blink.h"
#include "third_party/blink/public/strings/grit/blink_strings.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_touch_event_init.h"
#include "third_party/blink/renderer/core/events/touch_event.h"
#include "third_party/blink/renderer/core/frame/viewport_data.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
@@ -27,8 +28,11 @@ namespace {
class MockDisplayCutoutChromeClient : public EmptyChromeClient {
public:
// ChromeClient overrides:
- void EnterFullscreen(LocalFrame& frame, const FullscreenOptions*) override {
- Fullscreen::DidEnterFullscreen(*frame.GetDocument());
+ void EnterFullscreen(LocalFrame& frame,
+ const FullscreenOptions*,
+ bool for_cross_process_descendant) override {
+ Fullscreen::DidResolveEnterFullscreenRequest(*frame.GetDocument(),
+ true /* granted */);
}
void ExitFullscreen(LocalFrame& frame) override {
Fullscreen::DidExitFullscreen(*frame.GetDocument());
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 3f6cd801e3e..a75489c055d 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(blink::Visitor* visitor) {
+void MediaControlDivElement::Trace(Visitor* visitor) {
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 7c78a7c7ebc..621041cd56a 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 26e648a0df6..4500a9e8e4e 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
@@ -6,12 +6,12 @@
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/strings/grit/blink_strings.h"
+#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/core/html/media/html_media_element_controls_list.h"
-#include "third_party/blink/renderer/core/html/media/html_media_source.h"
#include "third_party/blink/renderer/core/input_type_names.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h"
@@ -59,7 +59,7 @@ bool MediaControlDownloadButtonElement::IsControlPanelButton() const {
return true;
}
-void MediaControlDownloadButtonElement::Trace(blink::Visitor* visitor) {
+void MediaControlDownloadButtonElement::Trace(Visitor* visitor) {
MediaControlInputElement::Trace(visitor);
}
@@ -77,9 +77,9 @@ void MediaControlDownloadButtonElement::DefaultEventHandler(Event& event) {
ResourceRequest request(url);
request.SetSuggestedFilename(MediaElement().title());
request.SetRequestContext(mojom::RequestContextType::DOWNLOAD);
- request.SetRequestorOrigin(SecurityOrigin::Create(GetDocument().Url()));
- GetDocument().GetFrame()->Client()->DownloadURL(
- request, network::mojom::RedirectMode::kError);
+ request.SetRequestorOrigin(GetDocument().GetSecurityOrigin());
+ GetDocument().GetFrame()->DownloadURL(
+ request, network::mojom::blink::RedirectMode::kError);
}
MediaControlInputElement::DefaultEventHandler(event);
}
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 93334801f6e..3ed835dabaf 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 11a526eb5c8..e9b2cc02ccb 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(blink::Visitor* visitor) {
+void MediaControlElementBase::Trace(Visitor* visitor) {
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 334248fb8df..57e232f89a6 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
MediaControlElementBase(MediaControlsImpl&,
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.cc
index aff62323cd4..db764b7a747 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.cc
@@ -6,9 +6,10 @@
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/events/keyboard_event.h"
+#include "third_party/blink/renderer/core/events/touch_event.h"
#include "third_party/blink/renderer/core/html/html_div_element.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
-#include "third_party/blink/renderer/core/layout/layout_slider.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_div_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.h"
@@ -26,8 +27,8 @@ bool MediaControlElementsHelper::IsUserInteractionEvent(const Event& event) {
type == event_type_names::kMouseup ||
type == event_type_names::kClick ||
type == event_type_names::kDblclick ||
- type == event_type_names::kGesturetap || event.IsKeyboardEvent() ||
- event.IsTouchEvent();
+ type == event_type_names::kGesturetap || IsA<KeyboardEvent>(event) ||
+ IsA<TouchEvent>(event);
}
// static
@@ -41,12 +42,14 @@ bool MediaControlElementsHelper::IsUserInteractionEventForSlider(
return true;
// Some events are only captured during a slider drag.
- const LayoutSlider* slider = ToLayoutSlider(layout_object);
- // TODO(crbug.com/695459#c1): LayoutSliderItem::inDragMode is incorrectly
+ const HTMLInputElement* slider = nullptr;
+ if (layout_object)
+ slider = DynamicTo<HTMLInputElement>(layout_object->GetNode());
+ // TODO(crbug.com/695459#c1): HTMLInputElement::IsDraggedSlider is incorrectly
// false for drags that start from the track instead of the thumb.
- // Use SliderThumbElement::m_inDragMode and
- // SliderContainerElement::m_touchStarted instead.
- if (slider && !slider->InDragMode())
+ // Use SliderThumbElement::in_drag_mode_ and
+ // SliderContainerElement::touch_started_ instead.
+ if (slider && !slider->IsDraggedSlider())
return false;
const AtomicString& type = event.type();
@@ -67,8 +70,7 @@ const HTMLMediaElement* MediaControlElementsHelper::ToParentMediaElement(
if (!shadow_host)
return nullptr;
- return IsHTMLMediaElement(shadow_host) ? ToHTMLMediaElement(shadow_host)
- : nullptr;
+ return DynamicTo<HTMLMediaElement>(shadow_host);
}
// static
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 6be5a7ee768..57636c51a67 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
@@ -4,12 +4,15 @@
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.h"
+#include "base/metrics/histogram_functions.h"
+#include "base/strings/strcat.h"
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/public/strings/grit/blink_strings.h"
#include "third_party/blink/renderer/core/css/css_property_names.h"
#include "third_party/blink/renderer/core/css_value_keywords.h"
#include "third_party/blink/renderer/core/dom/dom_token_list.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/events/gesture_event.h"
#include "third_party/blink/renderer/core/html/forms/html_label_element.h"
#include "third_party/blink/renderer/core/html/html_div_element.h"
#include "third_party/blink/renderer/core/html/html_span_element.h"
@@ -17,7 +20,6 @@
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_impl.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/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/text/platform_locale.h"
@@ -222,7 +224,7 @@ void MediaControlInputElement::DefaultEventHandler(Event& event) {
// Unhover the element if the hover is triggered by a tap on
// a touch screen device to avoid showing hover circle indefinitely.
- if (event.IsGestureEvent() && IsHovered())
+ if (IsA<GestureEvent>(event) && IsHovered())
SetHovered(false);
HTMLInputElement::DefaultEventHandler(event);
@@ -264,11 +266,8 @@ String MediaControlInputElement::GetOverflowMenuSubtitleString() const {
}
void MediaControlInputElement::RecordCTREvent(CTREvent event) {
- String histogram_name =
- StringView("Media.Controls.CTR.") + GetNameForHistograms();
- EnumerationHistogram ctr_histogram(histogram_name.Ascii().c_str(),
- static_cast<int>(CTREvent::kCount));
- ctr_histogram.Count(static_cast<int>(event));
+ base::UmaHistogramEnumeration(
+ base::StrCat({"Media.Controls.CTR.", GetNameForHistograms()}), event);
}
void MediaControlInputElement::SetClass(const AtomicString& class_name,
@@ -296,7 +295,7 @@ bool MediaControlInputElement::IsDisabled() const {
return FastHasAttribute(html_names::kDisabledAttr);
}
-void MediaControlInputElement::Trace(blink::Visitor* visitor) {
+void MediaControlInputElement::Trace(Visitor* visitor) {
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 8f39a187026..a6ea2d28f72 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
MediaControlInputElement* OverflowElementForTests() const {
return overflow_element_;
@@ -106,7 +106,7 @@ class MODULES_EXPORT MediaControlInputElement : public HTMLInputElement,
enum class CTREvent {
kDisplayed = 0,
kInteracted,
- kCount,
+ kMaxValue = kInteracted,
};
// Records the CTR event.
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 f6fa3ce832f..73c1684aee2 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 8950bbed67e..c5468bebcdf 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
@@ -21,7 +21,6 @@
namespace {
-static const char kAnimationIterationCountName[] = "animation-iteration-count";
static const char kInfinite[] = "infinite";
bool IsInLoadingState(blink::MediaControlsImpl& controls) {
@@ -138,12 +137,14 @@ void MediaControlLoadingPanelElement::CleanupShadowDOM() {
void MediaControlLoadingPanelElement::SetAnimationIterationCount(
const String& count_value) {
- mask1_background_->style()->setProperty(&GetDocument(),
- kAnimationIterationCountName,
- count_value, "", ASSERT_NO_EXCEPTION);
- mask2_background_->style()->setProperty(&GetDocument(),
- kAnimationIterationCountName,
- count_value, "", ASSERT_NO_EXCEPTION);
+ if (mask1_background_) {
+ mask1_background_->SetInlineStyleProperty(
+ CSSPropertyID::kAnimationIterationCount, count_value);
+ }
+ if (mask2_background_) {
+ mask2_background_->SetInlineStyleProperty(
+ CSSPropertyID::kAnimationIterationCount, count_value);
+ }
}
void MediaControlLoadingPanelElement::UpdateDisplayState() {
@@ -225,7 +226,7 @@ Element& MediaControlLoadingPanelElement::WatchedAnimationElement() const {
return *mask1_background_;
}
-void MediaControlLoadingPanelElement::Trace(blink::Visitor* visitor) {
+void MediaControlLoadingPanelElement::Trace(Visitor* visitor) {
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_overlay_play_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.cc
index a06074cf44c..d8c82d51874 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(blink::Visitor* visitor) {
+void MediaControlOverlayPlayButtonElement::Trace(Visitor* visitor) {
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 e7ef4575925..7ed95c22939 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 7c760e40558..246c9188059 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(blink::Visitor* visitor) {
+void MediaControlPanelElement::Trace(Visitor* visitor) {
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 e0db53fdea0..ef7fade2a71 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
friend class MediaControlPanelElementTest;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_picture_in_picture_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_picture_in_picture_button_element.cc
index c748e5b4554..bcaafaf24bb 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_picture_in_picture_button_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_picture_in_picture_button_element.cc
@@ -8,7 +8,6 @@
#include "third_party/blink/public/strings/grit/blink_strings.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
-#include "third_party/blink/renderer/core/html/media/html_media_source.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/core/input_type_names.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h"
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 0fc856889f3..322e5907642 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,16 +55,15 @@ class MediaControlPopupMenuElement::EventListener final
}
}
- void Trace(blink::Visitor* visitor) final {
+ void Trace(Visitor* visitor) final {
NativeEventListener::Trace(visitor);
visitor->Trace(popup_menu_);
}
private:
void Invoke(ExecutionContext*, Event* event) final {
- if (event->type() == event_type_names::kKeydown &&
- event->IsKeyboardEvent()) {
- KeyboardEvent* keyboard_event = ToKeyboardEvent(event);
+ auto* keyboard_event = DynamicTo<KeyboardEvent>(event);
+ if (event->type() == event_type_names::kKeydown && keyboard_event) {
bool handled = true;
switch (keyboard_event->keyCode()) {
@@ -166,7 +165,7 @@ void MediaControlPopupMenuElement::RemovedFrom(ContainerNode& container) {
MediaControlDivElement::RemovedFrom(container);
}
-void MediaControlPopupMenuElement::Trace(blink::Visitor* visitor) {
+void MediaControlPopupMenuElement::Trace(Visitor* visitor) {
MediaControlDivElement::Trace(visitor);
visitor->Trace(event_listener_);
visitor->Trace(last_focused_element_);
@@ -199,10 +198,10 @@ void MediaControlPopupMenuElement::SetPosition() {
bounding_client_rect->right() + kPopupMenuMarginPx) +
kPx;
- style()->setProperty(&GetDocument(), "bottom", bottom_str_value, kImportant,
- ASSERT_NO_EXCEPTION);
- style()->setProperty(&GetDocument(), "right", right_str_value, kImportant,
- ASSERT_NO_EXCEPTION);
+ style()->setProperty(GetDocument().ToExecutionContext(), "bottom",
+ bottom_str_value, kImportant, ASSERT_NO_EXCEPTION);
+ style()->setProperty(GetDocument().ToExecutionContext(), "right",
+ right_str_value, kImportant, ASSERT_NO_EXCEPTION);
}
Element* MediaControlPopupMenuElement::PopupAnchor() const {
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 b70b3685703..97e0fdd4f30 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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_scrubbing_message_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_scrubbing_message_element.cc
index d9e9c8f2ce5..84d56ac51ef 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_scrubbing_message_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_scrubbing_message_element.cc
@@ -47,16 +47,16 @@ void MediaControlScrubbingMessageElement::PopulateChildren() {
HTMLDivElement* arrow_right_div2 =
MediaControlElementsHelper::CreateDivWithId("arrow-right2", shadow_root);
- arrow_left_div1->SetInnerHTMLFromString(
+ arrow_left_div1->setInnerHTML(
MediaControlsResourceLoader::GetArrowLeftSVGImage());
- arrow_left_div2->SetInnerHTMLFromString(
+ arrow_left_div2->setInnerHTML(
MediaControlsResourceLoader::GetArrowLeftSVGImage());
message_div->setInnerText(
MediaElement().GetLocale().QueryString(IDS_MEDIA_SCRUBBING_MESSAGE_TEXT),
ASSERT_NO_EXCEPTION);
- arrow_right_div1->SetInnerHTMLFromString(
+ arrow_right_div1->setInnerHTML(
MediaControlsResourceLoader::GetArrowRightSVGImage());
- arrow_right_div2->SetInnerHTMLFromString(
+ arrow_right_div2->setInnerHTML(
MediaControlsResourceLoader::GetArrowRightSVGImage());
}
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 4b8272c5b3f..523475920b9 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(element_);
ResizeObserver::Delegate::Trace(visitor);
}
@@ -163,7 +163,7 @@ void MediaControlSliderElement::NotifyElementSizeChanged() {
TrackWidth(), ZoomFactor());
}
-void MediaControlSliderElement::Trace(blink::Visitor* visitor) {
+void MediaControlSliderElement::Trace(Visitor* visitor) {
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 a2fbc9559e0..195b27fa0a3 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 f6d8f6a9f81..5f9f0e47d12 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
@@ -9,6 +9,7 @@
#include "third_party/blink/public/strings/grit/blink_strings.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/shadow_root.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/pointer_event.h"
#include "third_party/blink/renderer/core/events/touch_event.h"
@@ -38,8 +39,8 @@ const int kThumbRadius = 6;
// Only respond to main button of primary pointer(s).
bool IsValidPointerEvent(const blink::Event& event) {
- DCHECK(event.IsPointerEvent());
- const blink::PointerEvent& pointer_event = ToPointerEvent(event);
+ DCHECK(blink::IsA<blink::PointerEvent>(event));
+ const auto& pointer_event = blink::To<blink::PointerEvent>(event);
return pointer_event.isPrimary() &&
pointer_event.button() ==
static_cast<int16_t>(blink::WebPointerProperties::Button::kLeft);
@@ -64,8 +65,7 @@ bool MediaControlTimelineElement::WillRespondToMouseClickEvents() {
return isConnected() && GetDocument().IsActive();
}
-void MediaControlTimelineElement::SetPosition(double current_time) {
- setValue(String::Number(current_time));
+void MediaControlTimelineElement::UpdateAria() {
String aria_label =
GetLocale().QueryString(IsA<HTMLVideoElement>(MediaElement())
? IDS_AX_MEDIA_VIDEO_SLIDER_HELP
@@ -78,6 +78,15 @@ void MediaControlTimelineElement::SetPosition(double current_time) {
AtomicString(GetLocale().QueryString(
IDS_AX_MEDIA_CURRENT_TIME_DISPLAY,
GetMediaControls().CurrentTimeDisplay().textContent(true))));
+}
+
+void MediaControlTimelineElement::SetPosition(double current_time,
+ bool suppress_aria) {
+ setValue(String::Number(current_time));
+
+ if (!suppress_aria)
+ UpdateAria();
+
RenderBarSegments();
}
@@ -112,23 +121,26 @@ void MediaControlTimelineElement::DefaultEventHandler(Event& event) {
metrics_.RecordEndGesture(TrackWidth(), MediaElement().duration());
}
- if (event.type() == event_type_names::kKeydown) {
+ if (event.type() == event_type_names::kFocus)
+ UpdateAria();
+
+ if (event.type() == event_type_names::kKeydown)
metrics_.StartKey();
- }
- if (event.type() == event_type_names::kKeyup && event.IsKeyboardEvent()) {
- metrics_.RecordEndKey(TrackWidth(), ToKeyboardEvent(event).keyCode());
- }
+
+ auto* keyboard_event = DynamicTo<KeyboardEvent>(event);
+ if (event.type() == event_type_names::kKeyup && keyboard_event)
+ metrics_.RecordEndKey(TrackWidth(), keyboard_event->keyCode());
MediaControlInputElement::DefaultEventHandler(event);
- if (event.IsMouseEvent() || event.IsKeyboardEvent() ||
- event.IsGestureEvent() || event.IsPointerEvent()) {
+ if (IsA<MouseEvent>(event) || keyboard_event || IsA<GestureEvent>(event) ||
+ IsA<PointerEvent>(event)) {
MaybeRecordInteracted();
}
// Update the value based on the touchmove event.
if (is_touching_ && event.type() == event_type_names::kTouchmove) {
- auto& touch_event = ToTouchEvent(event);
+ auto& touch_event = To<TouchEvent>(event);
if (touch_event.touches()->length() != 1)
return;
@@ -224,7 +236,7 @@ void MediaControlTimelineElement::RenderBarSegments() {
SetAfterSegmentPosition(after_segment);
}
-void MediaControlTimelineElement::Trace(blink::Visitor* visitor) {
+void MediaControlTimelineElement::Trace(Visitor* visitor) {
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 fe7ce278c61..ba1d15b0f45 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
@@ -24,7 +24,7 @@ class MediaControlTimelineElement : public MediaControlSliderElement {
// FIXME: An "earliest possible position" will be needed once that concept
// is supported by HTMLMediaElement, see https://crbug.com/137275
- void SetPosition(double);
+ void SetPosition(double, bool suppress_aria = false);
void SetDuration(double);
void OnMediaKeyboardEvent(Event* event) { DefaultEventHandler(*event); }
@@ -35,7 +35,7 @@ class MediaControlTimelineElement : public MediaControlSliderElement {
void OnControlsShown();
void OnControlsHidden();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
const char* GetNameForHistograms() const override;
@@ -51,6 +51,8 @@ class MediaControlTimelineElement : public MediaControlSliderElement {
bool BeginScrubbingEvent(Event&);
bool EndScrubbingEvent(Event&);
+ void UpdateAria();
+
MediaControlTimelineMetrics metrics_;
bool is_touching_ = false;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element_test.cc
index 5b3122d6516..47eea39857b 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element_test.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element_test.cc
@@ -4,11 +4,11 @@
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.h"
-#include "third_party/blink/public/platform/web_pointer_properties.h"
+#include "third_party/blink/public/common/input/web_pointer_properties.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_pointer_event_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_touch_event_init.h"
#include "third_party/blink/renderer/core/events/pointer_event.h"
-#include "third_party/blink/renderer/core/events/pointer_event_init.h"
#include "third_party/blink/renderer/core/events/touch_event.h"
-#include "third_party/blink/renderer/core/events/touch_event_init.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h"
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 f91b0819d4c..53dadc860c1 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
@@ -10,6 +10,7 @@
#include "base/numerics/safe_conversions.h"
#include "base/stl_util.h"
+#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/keyboard_codes.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_metrics.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_metrics.h
index 86d7e2e218c..ec5fe371826 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_metrics.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_metrics.h
@@ -5,8 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_ELEMENTS_MEDIA_CONTROL_TIMELINE_METRICS_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_ELEMENTS_MEDIA_CONTROL_TIMELINE_METRICS_H_
+#include "base/time/time.h"
#include "third_party/blink/public/common/screen_orientation/web_screen_orientation_type.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.cc
index f88138e7f94..9e8ae36b107 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.cc
@@ -7,6 +7,10 @@
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/core/dom/dom_token_list.h"
#include "third_party/blink/renderer/core/dom/events/event.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"
+#include "third_party/blink/renderer/core/events/pointer_event.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_object.h"
@@ -69,8 +73,8 @@ void MediaControlVolumeSliderElement::DefaultEventHandler(Event& event) {
MediaControlInputElement::DefaultEventHandler(event);
- if (event.IsMouseEvent() || event.IsKeyboardEvent() ||
- event.IsGestureEvent() || event.IsPointerEvent()) {
+ if (IsA<MouseEvent>(event) || IsA<KeyboardEvent>(event) ||
+ IsA<GestureEvent>(event) || IsA<PointerEvent>(event)) {
MaybeRecordInteracted();
}
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 f0a85449aa3..e382f47898f 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
@@ -4,7 +4,6 @@
#include "third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.h"
-#include "third_party/blink/public/platform/web_point.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/events/touch_event.h"
#include "third_party/blink/renderer/core/frame/viewport_data.h"
@@ -18,13 +17,13 @@ namespace blink {
namespace {
-WebPoint ExtractWebPoint(Touch* touch) {
- return WebPoint(touch->pageX(), touch->pageY());
+gfx::Point ExtractTouchPoint(Touch* touch) {
+ return gfx::Point(touch->pageX(), touch->pageY());
}
-double CalculateDistance(WebPoint first, WebPoint second) {
- double dx = first.x - second.x;
- double dy = first.y - second.y;
+double CalculateDistance(gfx::Point first, gfx::Point second) {
+ double dx = first.x() - second.x();
+ double dy = first.y() - second.y();
return sqrt(dx * dx + dy * dy);
}
@@ -58,7 +57,7 @@ void MediaControlsDisplayCutoutDelegate::Detach() {
this, true);
}
-void MediaControlsDisplayCutoutDelegate::Trace(blink::Visitor* visitor) {
+void MediaControlsDisplayCutoutDelegate::Trace(Visitor* visitor) {
NativeEventListener::Trace(visitor);
visitor->Trace(video_element_);
}
@@ -84,8 +83,8 @@ void MediaControlsDisplayCutoutDelegate::DidExitFullscreen() {
void MediaControlsDisplayCutoutDelegate::Invoke(
ExecutionContext* execution_context,
Event* event) {
- if (event->IsTouchEvent()) {
- HandleTouchEvent(ToTouchEvent(event));
+ if (auto* touch_event = DynamicTo<TouchEvent>(event)) {
+ HandleTouchEvent(touch_event);
return;
}
if (event->type() == event_type_names::kFullscreenchange ||
@@ -120,8 +119,8 @@ void MediaControlsDisplayCutoutDelegate::HandleTouchEvent(TouchEvent* event) {
previous_.reset();
// Extract the two touch points and calculate the distance.
- WebPoint first = ExtractWebPoint(event->touches()->item(0));
- WebPoint second = ExtractWebPoint(event->touches()->item(1));
+ gfx::Point first = ExtractTouchPoint(event->touches()->item(0));
+ gfx::Point second = ExtractTouchPoint(event->touches()->item(1));
double distance = CalculateDistance(first, second);
Direction direction = Direction::kUnknown;
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 345d8f15992..3ea9997debc 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 f58ec975431..14b02f3f852 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
@@ -15,7 +15,6 @@
#include "third_party/blink/renderer/core/loader/empty_clients.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_impl.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"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
@@ -28,8 +27,11 @@ namespace {
class DisplayCutoutMockChromeClient : public EmptyChromeClient {
public:
// ChromeClient overrides:
- void EnterFullscreen(LocalFrame& frame, const FullscreenOptions*) override {
- Fullscreen::DidEnterFullscreen(*frame.GetDocument());
+ void EnterFullscreen(LocalFrame& frame,
+ const FullscreenOptions*,
+ bool for_cross_process_descendant) override {
+ Fullscreen::DidResolveEnterFullscreenRequest(*frame.GetDocument(),
+ true /* granted */);
}
void ExitFullscreen(LocalFrame& frame) override {
Fullscreen::DidExitFullscreen(*frame.GetDocument());
@@ -131,13 +133,13 @@ class MediaControlsDisplayCutoutDelegateTest
}
TouchList* CreateTouchListWithOnePoint(int x, int y) {
- auto* list = MakeGarbageCollected<TouchList>();
+ TouchList* list = TouchList::Create();
list->Append(CreateTouchAtPoint(x, y));
return list;
}
TouchList* CreateTouchListWithTwoPoints(int x1, int y1, int x2, int y2) {
- auto* list = MakeGarbageCollected<TouchList>();
+ TouchList* list = TouchList::Create();
list->Append(CreateTouchAtPoint(x1, y1));
list->Append(CreateTouchAtPoint(x2, y2));
return list;
@@ -152,9 +154,9 @@ class MediaControlsDisplayCutoutDelegateTest
}
Touch* CreateTouchAtPoint(int x, int y) {
- return MakeGarbageCollected<Touch>(
- GetDocument().GetFrame(), &GetVideoElement(), 1 /* identifier */,
- FloatPoint(x, y), FloatPoint(x, y), FloatSize(1, 1), 90, 0, "test");
+ return Touch::Create(GetDocument().GetFrame(), &GetVideoElement(),
+ 1 /* identifier */, FloatPoint(x, y), FloatPoint(x, y),
+ FloatSize(1, 1), 90, 0, "test");
}
mojom::ViewportFit CurrentViewportFit() const {
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 2988db0b986..83de0f73bee 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
@@ -29,16 +29,17 @@
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_size.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_mutation_observer_init.h"
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h"
#include "third_party/blink/renderer/core/dom/mutation_observer.h"
-#include "third_party/blink/renderer/core/dom/mutation_observer_init.h"
#include "third_party/blink/renderer/core/dom/mutation_record.h"
#include "third_party/blink/renderer/core/dom/shadow_root.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/pointer_event.h"
+#include "third_party/blink/renderer/core/events/touch_event.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/frame/web_feature.h"
@@ -211,7 +212,7 @@ class MediaControlsImpl::BatchedControlUpdate {
}
private:
- Member<MediaControlsImpl> controls_;
+ MediaControlsImpl* controls_;
static int batch_depth_;
DISALLOW_COPY_AND_ASSIGN(BatchedControlUpdate);
@@ -236,7 +237,7 @@ class MediaControlsImpl::MediaControlsResizeObserverDelegate final
controls_->NotifyElementSizeChanged(entries[0]->contentRect());
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(controls_);
ResizeObserver::Delegate::Trace(visitor);
}
@@ -262,7 +263,7 @@ class MediaControlsImpl::MediaElementMutationCallback
}
ExecutionContext* GetExecutionContext() const override {
- return &controls_->GetDocument();
+ return controls_->GetDocument().ToExecutionContext();
}
void Deliver(const MutationRecordVector& records,
@@ -296,7 +297,7 @@ class MediaControlsImpl::MediaElementMutationCallback
void Disconnect() { observer_->disconnect(); }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(controls_);
visitor->Trace(observer_);
MutationObserver::Delegate::Trace(visitor);
@@ -308,8 +309,9 @@ class MediaControlsImpl::MediaElementMutationCallback
};
bool MediaControlsImpl::IsTouchEvent(Event* event) {
- return event->IsTouchEvent() || event->IsGestureEvent() ||
- (event->IsMouseEvent() && ToMouseEvent(event)->FromTouch());
+ auto* mouse_event = DynamicTo<MouseEvent>(event);
+ return IsA<TouchEvent>(event) || IsA<GestureEvent>(event) ||
+ (mouse_event && mouse_event->FromTouch());
}
MediaControlsImpl::MediaControlsImpl(HTMLMediaElement& media_element)
@@ -601,9 +603,9 @@ void MediaControlsImpl::InitializeControls() {
void MediaControlsImpl::PopulatePanel() {
// Clear the panels.
- panel_->SetInnerHTMLFromString("");
+ panel_->setInnerHTML("");
if (media_button_panel_)
- media_button_panel_->SetInnerHTMLFromString("");
+ media_button_panel_->setInnerHTML("");
Element* button_panel = panel_;
if (ShouldShowVideoControls()) {
@@ -873,8 +875,8 @@ void MediaControlsImpl::Reset() {
OnControlsListUpdated();
}
-void MediaControlsImpl::UpdateTimeIndicators() {
- timeline_->SetPosition(MediaElement().currentTime());
+void MediaControlsImpl::UpdateTimeIndicators(bool suppress_aria) {
+ timeline_->SetPosition(MediaElement().currentTime(), suppress_aria);
UpdateCurrentTimeDisplay();
}
@@ -1465,10 +1467,11 @@ void MediaControlsImpl::DefaultEventHandler(Event& event) {
ResetHideMediaControlsTimer();
}
- if (event.IsKeyboardEvent() && !event.defaultPrevented() &&
+ auto* keyboard_event = DynamicTo<KeyboardEvent>(event);
+ if (keyboard_event && !event.defaultPrevented() &&
!IsSpatialNavigationEnabled(GetDocument().GetFrame())) {
- const String& key = ToKeyboardEvent(event).key();
- if (key == "Enter" || ToKeyboardEvent(event).keyCode() == ' ') {
+ const String& key = keyboard_event->key();
+ if (key == "Enter" || keyboard_event->keyCode() == ' ') {
if (overlay_play_button_) {
overlay_play_button_->OnMediaKeyboardEvent(&event);
} else {
@@ -1613,10 +1616,11 @@ void MediaControlsImpl::MaybeJump(int seconds) {
}
bool MediaControlsImpl::IsOnLeftSide(Event* event) {
- if (!event->IsGestureEvent())
+ auto* gesture_event = DynamicTo<GestureEvent>(event);
+ if (!gesture_event)
return false;
- float tap_x = ToGestureEvent(event)->NativeEvent().PositionInWidget().x;
+ float tap_x = gesture_event->NativeEvent().PositionInWidget().x();
DOMRect* rect = getBoundingClientRect();
double middle = rect->x() + (rect->width() / 2);
@@ -1694,9 +1698,10 @@ void MediaControlsImpl::ShowCursor() {
}
bool MediaControlsImpl::ContainsRelatedTarget(Event* event) {
- if (!event->IsPointerEvent())
+ auto* pointer_event = DynamicTo<PointerEvent>(event);
+ if (!pointer_event)
return false;
- EventTarget* related_target = ToPointerEvent(event)->relatedTarget();
+ EventTarget* related_target = pointer_event->relatedTarget();
if (!related_target)
return false;
return contains(related_target->ToNode());
@@ -1738,7 +1743,7 @@ void MediaControlsImpl::OnFocusIn() {
}
void MediaControlsImpl::OnTimeUpdate() {
- UpdateTimeIndicators();
+ UpdateTimeIndicators(true /* suppress_aria */);
// 'timeupdate' might be called in a paused state. The controls should not
// become transparent in that case.
@@ -2123,7 +2128,7 @@ HTMLVideoElement& MediaControlsImpl::VideoElement() {
return *To<HTMLVideoElement>(&MediaElement());
}
-void MediaControlsImpl::Trace(blink::Visitor* visitor) {
+void MediaControlsImpl::Trace(Visitor* visitor) {
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 eb976bb28cf..b7595eb9cd2 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// Track the state of the controls.
enum ControlsState {
@@ -280,7 +280,7 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement,
void ElementSizeChangedTimerFired(TimerBase*);
// Update any visible indicators of the current time.
- void UpdateTimeIndicators();
+ void UpdateTimeIndicators(bool suppress_aria = false);
// Hide elements that don't fit, and show those things that we want which
// do fit. This requires that m_effectiveWidth and m_effectiveHeight are
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
index 1960b698b37..830606866aa 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
@@ -9,8 +9,9 @@
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/input/web_mouse_event.h"
+#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/public/platform/modules/remoteplayback/web_remote_playback_client.h"
-#include "third_party/blink/public/platform/web_mouse_event.h"
#include "third_party/blink/public/platform/web_screen_info.h"
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h"
@@ -273,12 +274,12 @@ class MediaControlsImplTest : public PageTestBase,
HTMLMediaElement::kHaveEnoughData);
}
- void MouseDownAt(WebFloatPoint pos);
- void MouseMoveTo(WebFloatPoint pos);
- void MouseUpAt(WebFloatPoint pos);
+ void MouseDownAt(gfx::PointF pos);
+ void MouseMoveTo(gfx::PointF pos);
+ void MouseUpAt(gfx::PointF pos);
- void GestureTapAt(WebFloatPoint pos);
- void GestureDoubleTapAt(WebFloatPoint pos);
+ void GestureTapAt(gfx::PointF pos);
+ void GestureDoubleTapAt(gfx::PointF pos);
bool HasAvailabilityCallbacks(RemotePlayback& remote_playback) {
return !remote_playback.availability_callbacks_.IsEmpty();
@@ -311,7 +312,7 @@ class MediaControlsImplTest : public PageTestBase,
HistogramTester histogram_tester_;
};
-void MediaControlsImplTest::MouseDownAt(WebFloatPoint pos) {
+void MediaControlsImplTest::MouseDownAt(gfx::PointF pos) {
WebMouseEvent mouse_down_event(WebInputEvent::kMouseDown,
pos /* client pos */, pos /* screen pos */,
WebPointerProperties::Button::kLeft, 1,
@@ -322,7 +323,7 @@ void MediaControlsImplTest::MouseDownAt(WebFloatPoint pos) {
mouse_down_event);
}
-void MediaControlsImplTest::MouseMoveTo(WebFloatPoint pos) {
+void MediaControlsImplTest::MouseMoveTo(gfx::PointF pos) {
WebMouseEvent mouse_move_event(WebInputEvent::kMouseMove,
pos /* client pos */, pos /* screen pos */,
WebPointerProperties::Button::kLeft, 1,
@@ -333,7 +334,7 @@ void MediaControlsImplTest::MouseMoveTo(WebFloatPoint pos) {
mouse_move_event, {}, {});
}
-void MediaControlsImplTest::MouseUpAt(WebFloatPoint pos) {
+void MediaControlsImplTest::MouseUpAt(gfx::PointF pos) {
WebMouseEvent mouse_up_event(
WebMouseEvent::kMouseUp, pos /* client pos */, pos /* screen pos */,
WebPointerProperties::Button::kLeft, 1, WebInputEvent::kNoModifiers,
@@ -343,7 +344,7 @@ void MediaControlsImplTest::MouseUpAt(WebFloatPoint pos) {
mouse_up_event);
}
-void MediaControlsImplTest::GestureTapAt(WebFloatPoint pos) {
+void MediaControlsImplTest::GestureTapAt(gfx::PointF pos) {
WebGestureEvent gesture_tap_event(
WebInputEvent::kGestureTap, WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests());
@@ -351,8 +352,7 @@ void MediaControlsImplTest::GestureTapAt(WebFloatPoint pos) {
// Adjust |pos| by current frame scale.
float frame_scale = GetDocument().GetFrame()->PageZoomFactor();
gesture_tap_event.SetFrameScale(frame_scale);
- pos.x = pos.x * frame_scale;
- pos.y = pos.y * frame_scale;
+ pos.Scale(frame_scale);
gesture_tap_event.SetPositionInWidget(pos);
// Fire the event.
@@ -360,7 +360,7 @@ void MediaControlsImplTest::GestureTapAt(WebFloatPoint pos) {
gesture_tap_event);
}
-void MediaControlsImplTest::GestureDoubleTapAt(WebFloatPoint pos) {
+void MediaControlsImplTest::GestureDoubleTapAt(gfx::PointF pos) {
GestureTapAt(pos);
GestureTapAt(pos);
}
@@ -689,8 +689,8 @@ TEST_F(MediaControlsImplTest, TimelineMetricsClick) {
EXPECT_EQ(0, MediaControls().MediaElement().currentTime());
- WebFloatPoint trackCenter(timelineRect->left() + timelineRect->width() / 2,
- timelineRect->top() + timelineRect->height() / 2);
+ gfx::PointF trackCenter(timelineRect->left() + timelineRect->width() / 2,
+ timelineRect->top() + timelineRect->height() / 2);
MouseDownAt(trackCenter);
MouseUpAt(trackCenter);
test::RunPendingTasks();
@@ -727,11 +727,11 @@ TEST_F(MediaControlsImplTest, TimelineMetricsDragFromCurrentPosition) {
->UserAgentShadowRoot()
->getElementById(shadow_element_names::SliderThumb())
->getBoundingClientRect();
- WebFloatPoint thumb(thumb_rect->x() + (thumb_rect->width() / 2),
- thumb_rect->y() + 1);
+ gfx::PointF thumb(thumb_rect->x() + (thumb_rect->width() / 2),
+ thumb_rect->y() + 1);
float y = timeline_rect->top() + timeline_rect->height() / 2;
- WebFloatPoint track_two_thirds(
+ gfx::PointF track_two_thirds(
timeline_rect->left() + timeline_rect->width() * 2 / 3, y);
MouseDownAt(thumb);
MouseMoveTo(track_two_thirds);
@@ -766,9 +766,9 @@ TEST_F(MediaControlsImplTest, TimelineMetricsDragFromElsewhere) {
EXPECT_EQ(0, MediaControls().MediaElement().currentTime());
float y = timelineRect->top() + timelineRect->height() / 2;
- WebFloatPoint trackOneThird(
+ gfx::PointF trackOneThird(
timelineRect->left() + timelineRect->width() * 1 / 3, y);
- WebFloatPoint trackTwoThirds(
+ gfx::PointF trackTwoThirds(
timelineRect->left() + timelineRect->width() * 2 / 3, y);
MouseDownAt(trackOneThird);
MouseMoveTo(trackTwoThirds);
@@ -803,10 +803,10 @@ TEST_F(MediaControlsImplTest, TimelineMetricsDragBackAndForth) {
EXPECT_EQ(0, MediaControls().MediaElement().currentTime());
float y = timelineRect->top() + timelineRect->height() / 2;
- WebFloatPoint trackTwoThirds(
+ gfx::PointF trackTwoThirds(
timelineRect->left() + timelineRect->width() * 2 / 3, y);
- WebFloatPoint trackEnd(timelineRect->left() + timelineRect->width(), y);
- WebFloatPoint trackOneThird(
+ gfx::PointF trackEnd(timelineRect->left() + timelineRect->width(), y);
+ gfx::PointF trackOneThird(
timelineRect->left() + timelineRect->width() * 1 / 3, y);
MouseDownAt(trackTwoThirds);
MouseMoveTo(trackEnd);
@@ -987,7 +987,7 @@ TEST_F(MediaControlsImplTestWithMockScheduler,
// Mouse move while focused
MediaControls().DispatchEvent(*Event::Create("focusin"));
MediaControls().MediaElement().SetFocused(true,
- WebFocusType::kWebFocusTypeNone);
+ mojom::blink::FocusType::kNone);
MediaControls().DispatchEvent(*Event::Create("pointermove"));
// Controls should remain visible
@@ -1014,7 +1014,7 @@ TEST_F(MediaControlsImplTestWithMockScheduler,
// Mouse move out while focused, controls should hide
MediaControls().DispatchEvent(*Event::Create("focusin"));
MediaControls().MediaElement().SetFocused(true,
- WebFocusType::kWebFocusTypeNone);
+ mojom::blink::FocusType::kNone);
MediaControls().DispatchEvent(*Event::Create("pointerout"));
EXPECT_FALSE(IsElementVisible(*panel));
}
@@ -1088,7 +1088,7 @@ TEST_F(MediaControlsImplTest,
WeakPersistent<HTMLMediaElement> weak_persistent_video = element;
{
Persistent<HTMLMediaElement> persistent_video = element;
- page_holder->GetDocument().body()->SetInnerHTMLFromString("");
+ page_holder->GetDocument().body()->setInnerHTML("");
// When removed from the document, the event listeners should have been
// dropped.
@@ -1207,10 +1207,10 @@ TEST_F(MediaControlsImplTestWithMockScheduler,
EXPECT_TRUE(volume_slider->classList().contains("closed"));
DOMRect* mute_btn_rect = mute_btn->getBoundingClientRect();
- WebFloatPoint mute_btn_center(
+ gfx::PointF mute_btn_center(
mute_btn_rect->left() + mute_btn_rect->width() / 2,
mute_btn_rect->top() + mute_btn_rect->height() / 2);
- WebFloatPoint edge(0, 0);
+ gfx::PointF edge(0, 0);
// Hover on mute button and stay
MouseMoveTo(mute_btn_center);
@@ -1248,7 +1248,7 @@ TEST_F(MediaControlsImplTestWithMockScheduler,
EXPECT_TRUE(volume_slider->classList().contains("closed"));
// Tab focus should open volume slider immediately.
- volume_slider->SetFocused(true, WebFocusType::kWebFocusTypeNone);
+ volume_slider->SetFocused(true, mojom::blink::FocusType::kNone);
volume_slider->DispatchEvent(*Event::Create("focus"));
EXPECT_FALSE(volume_slider->classList().contains("closed"));
@@ -1393,10 +1393,10 @@ TEST_F(MediaControlsImplTest, DoubleTouchChangesTime) {
DOMRect* videoRect = MediaControls().MediaElement().getBoundingClientRect();
ASSERT_LT(0, videoRect->width());
- WebFloatPoint leftOfCenter(videoRect->left() + (videoRect->width() / 2) - 5,
- videoRect->top() + 5);
- WebFloatPoint rightOfCenter(videoRect->left() + (videoRect->width() / 2) + 5,
- videoRect->top() + 5);
+ gfx::PointF leftOfCenter(videoRect->left() + (videoRect->width() / 2) - 5,
+ videoRect->top() + 5);
+ gfx::PointF rightOfCenter(videoRect->left() + (videoRect->width() / 2) + 5,
+ videoRect->top() + 5);
// Double-tapping left of center should shift the time backwards by 10
// seconds.
@@ -1423,10 +1423,10 @@ TEST_F(MediaControlsImplTest, DoubleTouchChangesTimeWhenZoomed) {
DOMRect* videoRect = MediaControls().MediaElement().getBoundingClientRect();
ASSERT_LT(0, videoRect->width());
- WebFloatPoint leftOfCenter(videoRect->left() + (videoRect->width() / 2) - 5,
- videoRect->top() + 10);
- WebFloatPoint rightOfCenter(videoRect->left() + (videoRect->width() / 2) + 5,
- videoRect->top() + 10);
+ gfx::PointF leftOfCenter(videoRect->left() + (videoRect->width() / 2) - 5,
+ videoRect->top() + 10);
+ gfx::PointF rightOfCenter(videoRect->left() + (videoRect->width() / 2) + 5,
+ videoRect->top() + 10);
// Add a zoom factor and ensure that it's properly handled.
MediaControls().GetDocument().GetFrame()->SetPageZoomFactor(2);
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 53ef493f010..0ffea25cc10 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(blink::Visitor* visitor) {
+void MediaControlsMediaEventListener::Trace(Visitor* visitor) {
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 15b691ef2ed..89a7ec4a942 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 f9512120dfc..cbcc72c3eb8 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,6 +6,7 @@
#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"
@@ -21,7 +22,6 @@
#include "third_party/blink/renderer/modules/screen_orientation/screen_orientation.h"
#include "third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.h"
#include "third_party/blink/renderer/modules/screen_orientation/web_lock_orientation_callback.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
@@ -39,29 +39,20 @@ namespace blink {
namespace {
-// These values are used for histograms. Do not reorder.
+// 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.
- kMax = 3
+ kMaxValue = kReceived,
};
void RecordMetadataAvailability(MetadataAvailabilityMetrics metrics) {
- DEFINE_STATIC_LOCAL(
- EnumerationHistogram, metadata_histogram,
- ("Media.Video.FullscreenOrientationLock.MetadataAvailability",
- static_cast<int>(MetadataAvailabilityMetrics::kMax)));
- metadata_histogram.Count(static_cast<int>(metrics));
-}
-
-void RecordAutoRotateEnabled(bool enabled) {
- DEFINE_STATIC_LOCAL(
- BooleanHistogram, auto_rotate_histogram,
- ("Media.Video.FullscreenOrientationLock.AutoRotateEnabled"));
- auto_rotate_histogram.Count(enabled);
+ base::UmaHistogramEnumeration(
+ "Media.Video.FullscreenOrientationLock.MetadataAvailability", metrics);
}
// WebLockOrientationCallback implementation that will not react to a success
@@ -209,8 +200,6 @@ void MediaControlsOrientationLockDelegate::GotIsAutoRotateEnabledByUser(
bool enabled) {
monitor_.reset();
- RecordAutoRotateEnabled(enabled);
-
if (!enabled) {
// Since the user has locked their screen orientation, prevent
// MediaControlsRotateToFullscreenDelegate from exiting fullscreen by not
@@ -267,7 +256,7 @@ void MediaControlsOrientationLockDelegate::Invoke(
event->InterfaceName() ==
event_interface_names::kDeviceOrientationEvent) {
MaybeLockToAnyIfDeviceOrientationMatchesVideo(
- ToDeviceOrientationEvent(event));
+ To<DeviceOrientationEvent>(event));
}
return;
@@ -447,7 +436,7 @@ void MediaControlsOrientationLockDelegate::
kLockToAnyDelay);
}
-void MediaControlsOrientationLockDelegate::Trace(blink::Visitor* visitor) {
+void MediaControlsOrientationLockDelegate::Trace(Visitor* visitor) {
NativeEventListener::Trace(visitor);
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 ea7b2388ab5..efcfb125c30 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
friend class MediaControlsOrientationLockDelegateTest;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc
index d834177dab2..25dafab6853 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc
@@ -57,7 +57,7 @@ class MockWebMediaPlayerForOrientationLockDelegate final
public:
bool HasVideo() const override { return true; }
- MOCK_CONST_METHOD0(NaturalSize, WebSize());
+ MOCK_CONST_METHOD0(NaturalSize, gfx::Size());
};
class MockScreenOrientation final
@@ -92,7 +92,7 @@ class MockScreenOrientation final
void DidEnterFullscreen(Document* document) {
DCHECK(document);
- Fullscreen::DidEnterFullscreen(*document);
+ Fullscreen::DidResolveEnterFullscreenRequest(*document, true /* granted */);
document->ServiceScriptedAnimations(base::TimeTicks::Now());
}
@@ -119,7 +119,9 @@ class MockChromeClientForOrientationLockDelegate final
}
// The real ChromeClient::EnterFullscreen/ExitFullscreen implementation is
// async due to IPC, emulate that by posting tasks:
- void EnterFullscreen(LocalFrame& frame, const FullscreenOptions*) override {
+ void EnterFullscreen(LocalFrame& frame,
+ const FullscreenOptions*,
+ bool for_cross_process_descendant) override {
Thread::Current()->GetTaskRunner()->PostTask(
FROM_HERE,
WTF::Bind(DidEnterFullscreen, WrapPersistent(frame.GetDocument())));
@@ -394,7 +396,7 @@ class MediaControlsOrientationLockAndRotateToFullscreenDelegateTest
// Set video size.
EXPECT_CALL(MockWebMediaPlayer(), NaturalSize())
- .WillRepeatedly(Return(WebSize(video_width, video_height)));
+ .WillRepeatedly(Return(gfx::Size(video_width, video_height)));
// Dispatch an arbitrary Device Orientation event to satisfy
// MediaControlsRotateToFullscreenDelegate's requirement that the device
@@ -569,11 +571,11 @@ TEST_F(MediaControlsOrientationLockDelegateTest, ComputeOrientationLock) {
EXPECT_CALL(MockWebMediaPlayer(), NaturalSize())
.Times(14) // Each `computeOrientationLock` calls the method twice.
- .WillOnce(Return(WebSize(100, 50)))
- .WillOnce(Return(WebSize(100, 50)))
- .WillOnce(Return(WebSize(50, 100)))
- .WillOnce(Return(WebSize(50, 100)))
- .WillRepeatedly(Return(WebSize(100, 100)));
+ .WillOnce(Return(gfx::Size(100, 50)))
+ .WillOnce(Return(gfx::Size(100, 50)))
+ .WillOnce(Return(gfx::Size(50, 100)))
+ .WillOnce(Return(gfx::Size(50, 100)))
+ .WillRepeatedly(Return(gfx::Size(100, 100)));
// 100x50
EXPECT_EQ(kWebScreenOrientationLockLandscape, ComputeOrientationLock());
@@ -1474,10 +1476,9 @@ TEST_F(MediaControlsOrientationLockAndRotateToFullscreenDelegateTest,
// And immediately detach the document by synchronously navigating.
// One easy way to do this is to replace the document with a JavaScript URL.
GetFrame().GetSettings()->SetScriptEnabled(true);
- GetFrame().Navigate(
- FrameLoadRequest(&GetDocument(),
- ResourceRequest("javascript:'Hello, world!'")),
- WebFrameLoadType::kStandard);
+ FrameLoadRequest request(&GetDocument(),
+ ResourceRequest("javascript:'Hello, world!'"));
+ GetFrame().Navigate(request, WebFrameLoadType::kStandard);
// We should not crash after the unlock delay.
test::RunDelayedTasks(GetUnlockDelay());
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 96eef5b01fc..b29bff47259 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
@@ -111,7 +111,7 @@ void MediaControlsRotateToFullscreenDelegate::Invoke(
if (event->isTrusted() &&
event->InterfaceName() ==
event_interface_names::kDeviceOrientationEvent) {
- OnDeviceOrientationAvailable(ToDeviceOrientationEvent(event));
+ OnDeviceOrientationAvailable(To<DeviceOrientationEvent>(event));
}
return;
}
@@ -286,7 +286,7 @@ MediaControlsRotateToFullscreenDelegate::ComputeScreenOrientation() const {
return SimpleOrientation::kUnknown;
}
-void MediaControlsRotateToFullscreenDelegate::Trace(blink::Visitor* visitor) {
+void MediaControlsRotateToFullscreenDelegate::Trace(Visitor* visitor) {
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 41138d4ab1a..299ccbf56cc 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
friend class MediaControlsRotateToFullscreenDelegateTest;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc
index db1307c89f7..e4c96e458f2 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc
@@ -46,7 +46,7 @@ class MockVideoWebMediaPlayer : public EmptyWebMediaPlayer {
// EmptyWebMediaPlayer overrides:
bool HasVideo() const override { return true; }
- MOCK_CONST_METHOD0(NaturalSize, WebSize());
+ MOCK_CONST_METHOD0(NaturalSize, gfx::Size());
};
class MockChromeClient : public EmptyChromeClient {
@@ -63,8 +63,11 @@ class MockChromeClient : public EmptyChromeClient {
->SetScreenOrientationAssociatedRemoteForTests(
std::move(screen_orientation));
}
- void EnterFullscreen(LocalFrame& frame, const FullscreenOptions*) override {
- Fullscreen::DidEnterFullscreen(*frame.GetDocument());
+ void EnterFullscreen(LocalFrame& frame,
+ const FullscreenOptions*,
+ bool for_cross_process_descendant) override {
+ Fullscreen::DidResolveEnterFullscreenRequest(*frame.GetDocument(),
+ true /* granted */);
}
void ExitFullscreen(LocalFrame& frame) override {
Fullscreen::DidExitFullscreen(*frame.GetDocument());
@@ -153,7 +156,7 @@ class MediaControlsRotateToFullscreenDelegateTest
}
void InitScreenAndVideo(WebScreenOrientationType initial_screen_orientation,
- WebSize video_size,
+ gfx::Size video_size,
bool with_device_orientation = true);
void PlayVideo();
@@ -184,7 +187,7 @@ class MediaControlsRotateToFullscreenDelegateTest
void MediaControlsRotateToFullscreenDelegateTest::InitScreenAndVideo(
WebScreenOrientationType initial_screen_orientation,
- WebSize video_size,
+ gfx::Size video_size,
bool with_device_orientation /* = true */) {
// Set initial screen orientation (called by `Attach` during `AppendChild`).
WebScreenInfo screen_info;
@@ -262,18 +265,18 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest, ComputeVideoOrientation) {
// one where the video is not yet ready.
EXPECT_CALL(GetWebMediaPlayer(), NaturalSize())
.Times(12)
- .WillOnce(Return(WebSize(400, 400)))
- .WillOnce(Return(WebSize(400, 400)))
- .WillOnce(Return(WebSize(300, 200)))
- .WillOnce(Return(WebSize(300, 200)))
- .WillOnce(Return(WebSize(200, 300)))
- .WillOnce(Return(WebSize(200, 300)))
- .WillOnce(Return(WebSize(300, 199)))
- .WillOnce(Return(WebSize(300, 199)))
- .WillOnce(Return(WebSize(199, 300)))
- .WillOnce(Return(WebSize(199, 300)))
- .WillOnce(Return(WebSize(0, 0)))
- .WillOnce(Return(WebSize(0, 0)));
+ .WillOnce(Return(gfx::Size(400, 400)))
+ .WillOnce(Return(gfx::Size(400, 400)))
+ .WillOnce(Return(gfx::Size(300, 200)))
+ .WillOnce(Return(gfx::Size(300, 200)))
+ .WillOnce(Return(gfx::Size(200, 300)))
+ .WillOnce(Return(gfx::Size(200, 300)))
+ .WillOnce(Return(gfx::Size(300, 199)))
+ .WillOnce(Return(gfx::Size(300, 199)))
+ .WillOnce(Return(gfx::Size(199, 300)))
+ .WillOnce(Return(gfx::Size(199, 300)))
+ .WillOnce(Return(gfx::Size(0, 0)))
+ .WillOnce(Return(gfx::Size(0, 0)));
// Video is not yet ready.
EXPECT_EQ(SimpleOrientation::kUnknown, ComputeVideoOrientation());
@@ -334,7 +337,7 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest,
TEST_F(MediaControlsRotateToFullscreenDelegateTest,
EnterSuccessPortraitToLandscape) {
// Portrait screen, landscape video.
- InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, WebSize(640, 480));
+ InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, gfx::Size(640, 480));
EXPECT_EQ(SimpleOrientation::kPortrait, ObservedScreenOrientation());
EXPECT_EQ(SimpleOrientation::kLandscape, ComputeVideoOrientation());
@@ -355,7 +358,8 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest,
TEST_F(MediaControlsRotateToFullscreenDelegateTest,
EnterSuccessLandscapeToPortrait) {
// Landscape screen, portrait video.
- InitScreenAndVideo(kWebScreenOrientationLandscapePrimary, WebSize(480, 640));
+ InitScreenAndVideo(kWebScreenOrientationLandscapePrimary,
+ gfx::Size(480, 640));
EXPECT_EQ(SimpleOrientation::kLandscape, ObservedScreenOrientation());
EXPECT_EQ(SimpleOrientation::kPortrait, ComputeVideoOrientation());
@@ -376,7 +380,7 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest,
TEST_F(MediaControlsRotateToFullscreenDelegateTest,
EnterSuccessSquarePortraitToLandscape) {
// Portrait screen, square video.
- InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, WebSize(400, 400));
+ InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, gfx::Size(400, 400));
EXPECT_EQ(SimpleOrientation::kPortrait, ObservedScreenOrientation());
EXPECT_EQ(SimpleOrientation::kLandscape, ComputeVideoOrientation());
@@ -397,7 +401,8 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest,
TEST_F(MediaControlsRotateToFullscreenDelegateTest, EnterFailWrongOrientation) {
// Landscape screen, landscape video.
- InitScreenAndVideo(kWebScreenOrientationLandscapePrimary, WebSize(640, 480));
+ InitScreenAndVideo(kWebScreenOrientationLandscapePrimary,
+ gfx::Size(640, 480));
EXPECT_EQ(SimpleOrientation::kLandscape, ObservedScreenOrientation());
EXPECT_EQ(SimpleOrientation::kLandscape, ComputeVideoOrientation());
@@ -418,7 +423,8 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest, EnterFailWrongOrientation) {
TEST_F(MediaControlsRotateToFullscreenDelegateTest,
EnterFailSquareWrongOrientation) {
// Landscape screen, square video.
- InitScreenAndVideo(kWebScreenOrientationLandscapePrimary, WebSize(400, 400));
+ InitScreenAndVideo(kWebScreenOrientationLandscapePrimary,
+ gfx::Size(400, 400));
EXPECT_EQ(SimpleOrientation::kLandscape, ObservedScreenOrientation());
EXPECT_EQ(SimpleOrientation::kLandscape, ComputeVideoOrientation());
@@ -440,7 +446,7 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest, EnterFailNoControls) {
DisableControls();
// Portrait screen, landscape video.
- InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, WebSize(640, 480));
+ InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, gfx::Size(640, 480));
EXPECT_EQ(SimpleOrientation::kPortrait, ObservedScreenOrientation());
EXPECT_EQ(SimpleOrientation::kLandscape, ComputeVideoOrientation());
@@ -460,7 +466,7 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest, EnterFailNoControls) {
TEST_F(MediaControlsRotateToFullscreenDelegateTest,
EnterFailNoDeviceOrientation) {
// Portrait screen, landscape video.
- InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, WebSize(640, 480),
+ InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, gfx::Size(640, 480),
false /* with_device_orientation */);
EXPECT_EQ(SimpleOrientation::kPortrait, ObservedScreenOrientation());
EXPECT_EQ(SimpleOrientation::kLandscape, ComputeVideoOrientation());
@@ -487,7 +493,7 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest,
TEST_F(MediaControlsRotateToFullscreenDelegateTest,
EnterFailZeroDeviceOrientation) {
// Portrait screen, landscape video.
- InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, WebSize(640, 480),
+ InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, gfx::Size(640, 480),
false /* with_device_orientation */);
EXPECT_EQ(SimpleOrientation::kPortrait, ObservedScreenOrientation());
EXPECT_EQ(SimpleOrientation::kLandscape, ComputeVideoOrientation());
@@ -516,7 +522,7 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest,
TEST_F(MediaControlsRotateToFullscreenDelegateTest, EnterFailPaused) {
// Portrait screen, landscape video.
- InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, WebSize(640, 480));
+ InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, gfx::Size(640, 480));
EXPECT_EQ(SimpleOrientation::kPortrait, ObservedScreenOrientation());
EXPECT_EQ(SimpleOrientation::kLandscape, ComputeVideoOrientation());
@@ -535,7 +541,7 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest, EnterFailPaused) {
TEST_F(MediaControlsRotateToFullscreenDelegateTest, EnterFailHidden) {
// Portrait screen, landscape video.
- InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, WebSize(640, 480));
+ InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, gfx::Size(640, 480));
EXPECT_EQ(SimpleOrientation::kPortrait, ObservedScreenOrientation());
EXPECT_EQ(SimpleOrientation::kLandscape, ComputeVideoOrientation());
@@ -546,8 +552,9 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest, EnterFailHidden) {
EXPECT_TRUE(ObservedVisibility());
// Move video offscreen.
- GetDocument().body()->style()->setProperty(&GetDocument(), "margin-top",
- "-999px", "", ASSERT_NO_EXCEPTION);
+ GetDocument().body()->style()->setProperty(GetDocument().ToExecutionContext(),
+ "margin-top", "-999px", "",
+ ASSERT_NO_EXCEPTION);
UpdateVisibilityObserver();
@@ -564,7 +571,7 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest,
EnterFail180DegreeRotation) {
// Landscape screen, landscape video.
InitScreenAndVideo(kWebScreenOrientationLandscapeSecondary,
- WebSize(640, 480));
+ gfx::Size(640, 480));
EXPECT_EQ(SimpleOrientation::kLandscape, ObservedScreenOrientation());
EXPECT_EQ(SimpleOrientation::kLandscape, ComputeVideoOrientation());
@@ -584,7 +591,7 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest,
TEST_F(MediaControlsRotateToFullscreenDelegateTest, EnterFailSmall) {
// Portrait screen, small landscape video.
- InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, WebSize(300, 199));
+ InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, gfx::Size(300, 199));
EXPECT_EQ(SimpleOrientation::kPortrait, ObservedScreenOrientation());
EXPECT_EQ(SimpleOrientation::kUnknown, ComputeVideoOrientation());
@@ -604,7 +611,7 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest, EnterFailSmall) {
TEST_F(MediaControlsRotateToFullscreenDelegateTest,
EnterFailDocumentFullscreen) {
// Portrait screen, landscape video.
- InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, WebSize(640, 480));
+ InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, gfx::Size(640, 480));
EXPECT_EQ(SimpleOrientation::kPortrait, ObservedScreenOrientation());
EXPECT_EQ(SimpleOrientation::kLandscape, ComputeVideoOrientation());
@@ -633,7 +640,8 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest,
TEST_F(MediaControlsRotateToFullscreenDelegateTest,
ExitSuccessLandscapeFullscreenToPortraitInline) {
// Landscape screen, landscape video.
- InitScreenAndVideo(kWebScreenOrientationLandscapePrimary, WebSize(640, 480));
+ InitScreenAndVideo(kWebScreenOrientationLandscapePrimary,
+ gfx::Size(640, 480));
EXPECT_EQ(SimpleOrientation::kLandscape, ObservedScreenOrientation());
EXPECT_EQ(SimpleOrientation::kLandscape, ComputeVideoOrientation());
@@ -661,7 +669,7 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest,
TEST_F(MediaControlsRotateToFullscreenDelegateTest,
ExitSuccessPortraitFullscreenToLandscapeInline) {
// Portrait screen, portrait video.
- InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, WebSize(480, 640));
+ InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, gfx::Size(480, 640));
EXPECT_EQ(SimpleOrientation::kPortrait, ObservedScreenOrientation());
EXPECT_EQ(SimpleOrientation::kPortrait, ComputeVideoOrientation());
@@ -689,7 +697,8 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest,
TEST_F(MediaControlsRotateToFullscreenDelegateTest,
ExitFailDocumentFullscreen) {
// Landscape screen, landscape video.
- InitScreenAndVideo(kWebScreenOrientationLandscapePrimary, WebSize(640, 480));
+ InitScreenAndVideo(kWebScreenOrientationLandscapePrimary,
+ gfx::Size(640, 480));
EXPECT_EQ(SimpleOrientation::kLandscape, ObservedScreenOrientation());
EXPECT_EQ(SimpleOrientation::kLandscape, ComputeVideoOrientation());
@@ -716,7 +725,7 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest,
TEST_F(MediaControlsRotateToFullscreenDelegateTest,
EnterFailControlsListNoFullscreen) {
// Portrait screen, landscape video.
- InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, WebSize(640, 480));
+ InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, gfx::Size(640, 480));
EXPECT_EQ(SimpleOrientation::kPortrait, ObservedScreenOrientation());
EXPECT_EQ(SimpleOrientation::kLandscape, ComputeVideoOrientation());
@@ -739,7 +748,7 @@ TEST_F(MediaControlsRotateToFullscreenDelegateTest,
TEST_F(MediaControlsRotateToFullscreenDelegateTest,
EnterSuccessControlsListNoDownload) {
// Portrait screen, landscape video.
- InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, WebSize(640, 480));
+ InitScreenAndVideo(kWebScreenOrientationPortraitPrimary, gfx::Size(640, 480));
EXPECT_EQ(SimpleOrientation::kPortrait, ObservedScreenOrientation());
EXPECT_EQ(SimpleOrientation::kLandscape, ComputeVideoOrientation());
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 82c0ab64c82..255a451ef8d 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(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
bool attached_ = false;
diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/DEPS b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/DEPS
index 725f02f25ef..66bc57c916a 100644
--- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/DEPS
+++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/DEPS
@@ -24,4 +24,7 @@ specific_include_rules = {
"html_audio_element_capturer_source_unittest.cc" : [
"+media/audio/null_audio_sink.h",
],
+ "canvas_capture_handler.cc": [
+ "+gpu/command_buffer/client/raster_interface.h",
+ ],
}
diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/auto_canvas_draw_listener.cc b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/auto_canvas_draw_listener.cc
index cc92feb0861..1ceacb96ae1 100644
--- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/auto_canvas_draw_listener.cc
+++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/auto_canvas_draw_listener.cc
@@ -16,7 +16,7 @@ AutoCanvasDrawListener::AutoCanvasDrawListener(
: handler_(std::move(handler)), frame_capture_requested_(true) {}
void AutoCanvasDrawListener::SendNewFrame(
- sk_sp<SkImage> image,
+ scoped_refptr<StaticBitmapImage> image,
base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider) {
handler_->SendNewFrame(image, context_provider);
}
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 c3a22e22085..771b8ea19c2 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
@@ -21,12 +21,12 @@ class AutoCanvasDrawListener : public GarbageCollected<AutoCanvasDrawListener>,
~AutoCanvasDrawListener() override = default;
void SendNewFrame(
- sk_sp<SkImage>,
+ scoped_refptr<StaticBitmapImage>,
base::WeakPtr<WebGraphicsContext3DProviderWrapper>) override;
bool NeedsNewFrame() const final;
void RequestFrame() final;
- void Trace(blink::Visitor*) override {}
+ void Trace(Visitor*) 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 e08e0ebc66e..ddd73e34730 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
@@ -9,8 +9,9 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "base/rand_util.h"
-#include "components/viz/common/gl_helper.h"
+#include "gpu/command_buffer/client/raster_interface.h"
#include "media/base/limits.h"
#include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
#include "third_party/blink/public/platform/web_media_stream_source.h"
@@ -20,6 +21,7 @@
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.h"
#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/webrtc_uma_histograms.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -37,7 +39,7 @@ namespace {
// Return the gfx::ColorSpace that the pixels resulting from calling
// ConvertToYUVFrame on |image| will be in.
-gfx::ColorSpace GetImageYUVColorSpace(sk_sp<SkImage> image) {
+gfx::ColorSpace GetImageYUVColorSpace(scoped_refptr<StaticBitmapImage> image) {
// TODO: Determine the ColorSpace::MatrixID and ColorSpace::RangeID that the
// calls to libyuv are assuming.
return gfx::ColorSpace();
@@ -171,7 +173,7 @@ CanvasCaptureHandler::CreateCanvasCaptureHandler(
}
void CanvasCaptureHandler::SendNewFrame(
- sk_sp<SkImage> image,
+ scoped_refptr<StaticBitmapImage> image,
base::WeakPtr<blink::WebGraphicsContext3DProviderWrapper>
context_provider) {
DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_);
@@ -179,25 +181,26 @@ void CanvasCaptureHandler::SendNewFrame(
if (!image)
return;
- // Initially try accessing pixels directly if they are in memory.
- SkPixmap pixmap;
- if (image->peekPixels(&pixmap) &&
- (pixmap.colorType() == kRGBA_8888_SkColorType ||
- pixmap.colorType() == kBGRA_8888_SkColorType) &&
- (pixmap.alphaType() == kUnpremul_SkAlphaType || image->isOpaque())) {
- const base::TimeTicks timestamp = base::TimeTicks::Now();
- SendFrame(ConvertToYUVFrame(image->isOpaque(), false,
- static_cast<const uint8_t*>(pixmap.addr(0, 0)),
- gfx::Size(pixmap.width(), pixmap.height()),
- static_cast<int>(pixmap.rowBytes()),
- pixmap.colorType()),
- timestamp, GetImageYUVColorSpace(image));
- return;
- }
+ if (!image->IsTextureBacked()) {
+ // Initially try accessing pixels directly if they are in memory.
+ sk_sp<SkImage> sk_image = image->PaintImageForCurrentFrame().GetSkImage();
+ SkPixmap pixmap;
+ if (sk_image->peekPixels(&pixmap) &&
+ (pixmap.colorType() == kRGBA_8888_SkColorType ||
+ pixmap.colorType() == kBGRA_8888_SkColorType) &&
+ (pixmap.alphaType() == kUnpremul_SkAlphaType || sk_image->isOpaque())) {
+ const base::TimeTicks timestamp = base::TimeTicks::Now();
+ SendFrame(ConvertToYUVFrame(
+ sk_image->isOpaque(), false,
+ static_cast<const uint8_t*>(pixmap.addr(0, 0)),
+ gfx::Size(pixmap.width(), pixmap.height()),
+ static_cast<int>(pixmap.rowBytes()), pixmap.colorType()),
+ timestamp, GetImageYUVColorSpace(image));
+ return;
+ }
- // Copy the pixels into memory synchronously. This call may block the main
- // render thread.
- if (!image->isTextureBacked()) {
+ // Copy the pixels into memory synchronously. This call may block the main
+ // render thread.
ReadARGBPixelsSync(image);
return;
}
@@ -207,8 +210,8 @@ void CanvasCaptureHandler::SendNewFrame(
return;
}
- // Try async reading SkImage if it is texture backed.
- if (image->isOpaque()) {
+ // Try async reading if image is texture backed.
+ if (image->CurrentFrameKnownToBeOpaque()) {
ReadYUVPixelsAsync(image, context_provider);
} else {
ReadARGBPixelsAsync(image, context_provider->ContextProvider());
@@ -240,12 +243,15 @@ void CanvasCaptureHandler::RequestRefreshFrame() {
DVLOG(3) << __func__;
DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_);
if (last_frame_ && delegate_) {
- io_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&CanvasCaptureHandler::CanvasCaptureHandlerDelegate::
- SendNewFrameOnIOThread,
- delegate_->GetWeakPtrForIOThread(), last_frame_,
- base::TimeTicks::Now()));
+ // If we're currently reading out pixels from GL memory, we risk
+ // emitting frames with non-incrementally increasing timestamps.
+ // Defer sending the refresh frame until we have completed those async
+ // reads.
+ if (num_ongoing_async_pixel_readouts_ > 0) {
+ deferred_request_refresh_frame_ = true;
+ return;
+ }
+ SendRefreshFrame();
}
}
@@ -256,11 +262,13 @@ void CanvasCaptureHandler::StopVideoCapture() {
io_task_runner_->DeleteSoon(FROM_HERE, delegate_.release());
}
-void CanvasCaptureHandler::ReadARGBPixelsSync(sk_sp<SkImage> image) {
+void CanvasCaptureHandler::ReadARGBPixelsSync(
+ scoped_refptr<StaticBitmapImage> image) {
DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_);
+ sk_sp<SkImage> sk_image = image->PaintImageForCurrentFrame().GetSkImage();
const base::TimeTicks timestamp = base::TimeTicks::Now();
- const gfx::Size image_size(image->width(), image->height());
+ const gfx::Size image_size(sk_image->width(), sk_image->height());
scoped_refptr<VideoFrame> temp_argb_frame = frame_pool_.CreateFrame(
media::PIXEL_FORMAT_ARGB, image_size, gfx::Rect(image_size), image_size,
base::TimeDelta());
@@ -268,14 +276,14 @@ void CanvasCaptureHandler::ReadARGBPixelsSync(sk_sp<SkImage> image) {
DLOG(ERROR) << "Couldn't allocate video frame";
return;
}
- const bool is_opaque = image->isOpaque();
+ const bool is_opaque = sk_image->isOpaque();
SkImageInfo image_info = SkImageInfo::MakeN32(
image_size.width(), image_size.height(),
is_opaque ? kPremul_SkAlphaType : kUnpremul_SkAlphaType);
- if (!image->readPixels(image_info,
- temp_argb_frame->visible_data(VideoFrame::kARGBPlane),
- temp_argb_frame->stride(VideoFrame::kARGBPlane),
- 0 /*srcX*/, 0 /*srcY*/)) {
+ if (!sk_image->readPixels(
+ image_info, temp_argb_frame->visible_data(VideoFrame::kARGBPlane),
+ temp_argb_frame->stride(VideoFrame::kARGBPlane), 0 /*srcX*/,
+ 0 /*srcY*/)) {
DLOG(ERROR) << "Couldn't read SkImage using readPixels()";
return;
}
@@ -288,7 +296,7 @@ void CanvasCaptureHandler::ReadARGBPixelsSync(sk_sp<SkImage> image) {
}
void CanvasCaptureHandler::ReadARGBPixelsAsync(
- sk_sp<SkImage> image,
+ scoped_refptr<StaticBitmapImage> image,
blink::WebGraphicsContext3DProvider* context_provider) {
DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_);
DCHECK(context_provider);
@@ -302,24 +310,31 @@ void CanvasCaptureHandler::ReadARGBPixelsAsync(
DLOG(ERROR) << "Couldn't allocate video frame";
return;
}
- GrSurfaceOrigin surface_origin = kTopLeft_GrSurfaceOrigin;
- GrBackendTexture backend_texture =
- image->getBackendTexture(true, &surface_origin);
- DCHECK(backend_texture.isValid());
- GrGLTextureInfo texture_info;
- const bool result = backend_texture.getGLTextureInfo(&texture_info);
- DCHECK(result);
- DCHECK(context_provider->GetGLHelper());
- context_provider->GetGLHelper()->ReadbackTextureAsync(
- texture_info.fID, texture_info.fTarget, image_size,
- temp_argb_frame->visible_data(VideoFrame::kARGBPlane), kN32_SkColorType,
+
+ static_assert(kN32_SkColorType == kRGBA_8888_SkColorType ||
+ kN32_SkColorType == kBGRA_8888_SkColorType,
+ "CanvasCaptureHandler::ReadARGBPixelsAsync supports only "
+ "kRGBA_8888_SkColorType and kBGRA_8888_SkColorType.");
+ GLenum format;
+ if (kN32_SkColorType == kRGBA_8888_SkColorType)
+ format = GL_RGBA;
+ else
+ format = GL_BGRA_EXT;
+
+ IncrementOngoingAsyncPixelReadouts();
+ gpu::MailboxHolder mailbox_holder = image->GetMailboxHolder();
+ context_provider->RasterInterface()->WaitSyncTokenCHROMIUM(
+ mailbox_holder.sync_token.GetConstData());
+ context_provider->RasterInterface()->ReadbackARGBPixelsAsync(
+ mailbox_holder.mailbox, mailbox_holder.texture_target, image_size,
+ temp_argb_frame->visible_data(VideoFrame::kARGBPlane), format,
WTF::Bind(&CanvasCaptureHandler::OnARGBPixelsReadAsync,
weak_ptr_factory_.GetWeakPtr(), image, temp_argb_frame,
- timestamp, surface_origin != kTopLeft_GrSurfaceOrigin));
+ timestamp, !image->IsOriginTopLeft()));
}
void CanvasCaptureHandler::ReadYUVPixelsAsync(
- sk_sp<SkImage> image,
+ scoped_refptr<StaticBitmapImage> image,
base::WeakPtr<blink::WebGraphicsContext3DProviderWrapper>
context_provider) {
DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_);
@@ -335,61 +350,35 @@ void CanvasCaptureHandler::ReadYUVPixelsAsync(
return;
}
- GrSurfaceOrigin surface_origin = kTopLeft_GrSurfaceOrigin;
- GrBackendTexture backend_texture =
- image->getBackendTexture(true, &surface_origin);
- DCHECK(backend_texture.isValid());
- GrGLTextureInfo texture_info;
- const bool result = backend_texture.getGLTextureInfo(&texture_info);
- DCHECK(result);
-
- // The YUV readback path only works for 2D textures.
- GLuint texture_for_readback = texture_info.fID;
- GLuint copy_texture = 0;
- if (texture_info.fTarget != GL_TEXTURE_2D) {
- auto* gl = context_provider->ContextProvider()->ContextGL();
- int width = image->imageInfo().width();
- int height = image->imageInfo().height();
-
- gl->GenTextures(1, &copy_texture);
- gl->BindTexture(GL_TEXTURE_2D, copy_texture);
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, nullptr);
- gl->CopyTextureCHROMIUM(texture_info.fID, 0, GL_TEXTURE_2D, copy_texture, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, 0, 0, 0);
- image = nullptr;
- texture_for_readback = copy_texture;
- }
-
- DCHECK(context_provider->ContextProvider()->GetGLHelper());
- viz::ReadbackYUVInterface* const yuv_reader =
- context_provider->ContextProvider()
- ->GetGLHelper()
- ->GetReadbackPipelineYUV(surface_origin != kTopLeft_GrSurfaceOrigin);
- yuv_reader->ReadbackYUV(
- texture_for_readback, image_size, gfx::Rect(image_size),
- output_frame->stride(media::VideoFrame::kYPlane),
- output_frame->visible_data(media::VideoFrame::kYPlane),
- output_frame->stride(media::VideoFrame::kUPlane),
- output_frame->visible_data(media::VideoFrame::kUPlane),
- output_frame->stride(media::VideoFrame::kVPlane),
- output_frame->visible_data(media::VideoFrame::kVPlane), gfx::Point(0, 0),
- WTF::Bind(&CanvasCaptureHandler::OnYUVPixelsReadAsync,
- weak_ptr_factory_.GetWeakPtr(), image, copy_texture,
- context_provider, output_frame, timestamp));
+ gpu::MailboxHolder mailbox_holder = image->GetMailboxHolder();
+ context_provider->ContextProvider()->RasterInterface()->WaitSyncTokenCHROMIUM(
+ mailbox_holder.sync_token.GetConstData());
+ context_provider->ContextProvider()
+ ->RasterInterface()
+ ->ReadbackYUVPixelsAsync(
+ mailbox_holder.mailbox, mailbox_holder.texture_target, image_size,
+ gfx::Rect(image_size), !image->IsOriginTopLeft(),
+ output_frame->stride(media::VideoFrame::kYPlane),
+ output_frame->visible_data(media::VideoFrame::kYPlane),
+ output_frame->stride(media::VideoFrame::kUPlane),
+ output_frame->visible_data(media::VideoFrame::kUPlane),
+ output_frame->stride(media::VideoFrame::kVPlane),
+ output_frame->visible_data(media::VideoFrame::kVPlane),
+ gfx::Point(0, 0),
+ WTF::Bind(&CanvasCaptureHandler::OnReleaseMailbox,
+ weak_ptr_factory_.GetWeakPtr(), image),
+ WTF::Bind(&CanvasCaptureHandler::OnYUVPixelsReadAsync,
+ weak_ptr_factory_.GetWeakPtr(), output_frame, timestamp));
}
void CanvasCaptureHandler::OnARGBPixelsReadAsync(
- sk_sp<SkImage> image,
+ scoped_refptr<StaticBitmapImage> image,
scoped_refptr<media::VideoFrame> temp_argb_frame,
base::TimeTicks this_frame_ticks,
bool flip,
bool success) {
DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_);
+ DecrementOngoingAsyncPixelReadouts();
if (!success) {
DLOG(ERROR) << "Couldn't read SkImage using async callback";
// Async reading is not supported on some platforms, see
@@ -398,9 +387,8 @@ void CanvasCaptureHandler::OnARGBPixelsReadAsync(
return;
}
// Let |image| fall out of scope after we are done reading.
- const bool is_opaque = image->isOpaque();
+ const bool is_opaque = image->CurrentFrameKnownToBeOpaque();
const auto color_space = GetImageYUVColorSpace(image);
- image = nullptr;
SendFrame(
ConvertToYUVFrame(is_opaque, flip,
@@ -409,26 +397,27 @@ void CanvasCaptureHandler::OnARGBPixelsReadAsync(
temp_argb_frame->stride(VideoFrame::kARGBPlane),
kN32_SkColorType),
this_frame_ticks, color_space);
+ if (num_ongoing_async_pixel_readouts_ == 0 && deferred_request_refresh_frame_)
+ SendRefreshFrame();
}
void CanvasCaptureHandler::OnYUVPixelsReadAsync(
- sk_sp<SkImage> image,
- GLuint copy_texture,
- base::WeakPtr<blink::WebGraphicsContext3DProviderWrapper> context_provider,
scoped_refptr<media::VideoFrame> yuv_frame,
base::TimeTicks this_frame_ticks,
bool success) {
DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_);
- if (copy_texture && context_provider) {
- context_provider->ContextProvider()->ContextGL()->DeleteTextures(
- 1, &copy_texture);
- }
if (!success) {
DLOG(ERROR) << "Couldn't read SkImage using async callback";
return;
}
- SendFrame(yuv_frame, this_frame_ticks, GetImageYUVColorSpace(image));
+ SendFrame(yuv_frame, this_frame_ticks, gfx::ColorSpace());
+}
+
+void CanvasCaptureHandler::OnReleaseMailbox(
+ scoped_refptr<StaticBitmapImage> image) {
+ // All shared image operations have been completed, stop holding the ref.
+ image = nullptr;
}
scoped_refptr<media::VideoFrame> CanvasCaptureHandler::ConvertToYUVFrame(
@@ -542,4 +531,29 @@ void CanvasCaptureHandler::AddVideoCapturerSourceToVideoTrack(
blink::MediaStreamVideoSource::ConstraintsOnceCallback(), true));
}
+void CanvasCaptureHandler::IncrementOngoingAsyncPixelReadouts() {
+ DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_);
+ ++num_ongoing_async_pixel_readouts_;
+}
+
+void CanvasCaptureHandler::DecrementOngoingAsyncPixelReadouts() {
+ DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_);
+ --num_ongoing_async_pixel_readouts_;
+ DCHECK_GE(num_ongoing_async_pixel_readouts_, 0);
+}
+
+void CanvasCaptureHandler::SendRefreshFrame() {
+ DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_);
+ DCHECK_EQ(num_ongoing_async_pixel_readouts_, 0);
+ if (last_frame_ && delegate_) {
+ io_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&CanvasCaptureHandler::CanvasCaptureHandlerDelegate::
+ SendNewFrameOnIOThread,
+ delegate_->GetWeakPtrForIOThread(), last_frame_,
+ base::TimeTicks::Now()));
+ }
+ deferred_request_refresh_frame_ = false;
+}
+
} // namespace blink
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 e685d093040..ba2d60a1810 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
@@ -28,6 +28,7 @@ class SkImage;
namespace blink {
class LocalFrame;
+class StaticBitmapImage;
class WebGraphicsContext3DProvider;
class WebGraphicsContext3DProviderWrapper;
@@ -52,7 +53,7 @@ class MODULES_EXPORT CanvasCaptureHandler {
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
blink::WebMediaStreamTrack* track);
- void SendNewFrame(sk_sp<SkImage> image,
+ void SendNewFrame(scoped_refptr<StaticBitmapImage> image,
base::WeakPtr<blink::WebGraphicsContext3DProviderWrapper>
context_provider);
bool NeedsNewFrame() const;
@@ -79,27 +80,23 @@ class MODULES_EXPORT CanvasCaptureHandler {
blink::WebMediaStreamTrack* track);
// Helper functions to read pixel content.
- void ReadARGBPixelsSync(sk_sp<SkImage> image);
+ void ReadARGBPixelsSync(scoped_refptr<StaticBitmapImage> image);
void ReadARGBPixelsAsync(
- sk_sp<SkImage> image,
+ scoped_refptr<StaticBitmapImage> image,
blink::WebGraphicsContext3DProvider* context_provider);
void ReadYUVPixelsAsync(
- sk_sp<SkImage> image,
+ scoped_refptr<StaticBitmapImage> image,
base::WeakPtr<blink::WebGraphicsContext3DProviderWrapper>
context_provider);
- void OnARGBPixelsReadAsync(sk_sp<SkImage> image,
+ void OnARGBPixelsReadAsync(scoped_refptr<StaticBitmapImage> image,
scoped_refptr<media::VideoFrame> temp_argb_frame,
base::TimeTicks this_frame_ticks,
bool flip,
bool success);
- void OnYUVPixelsReadAsync(
- sk_sp<SkImage> image,
- GLuint copy_texture,
- base::WeakPtr<blink::WebGraphicsContext3DProviderWrapper>
- context_provider,
- scoped_refptr<media::VideoFrame> yuv_frame,
- base::TimeTicks this_frame_ticks,
- bool success);
+ void OnYUVPixelsReadAsync(scoped_refptr<media::VideoFrame> yuv_frame,
+ base::TimeTicks this_frame_ticks,
+ bool success);
+ void OnReleaseMailbox(scoped_refptr<StaticBitmapImage> image);
scoped_refptr<media::VideoFrame> ConvertToYUVFrame(
bool is_opaque,
@@ -117,6 +114,14 @@ class MODULES_EXPORT CanvasCaptureHandler {
std::unique_ptr<media::VideoCapturerSource> source,
blink::WebMediaStreamTrack* web_track);
+ // Helper methods to increment/decrement the number of ongoing async pixel
+ // readouts currently happening.
+ void IncrementOngoingAsyncPixelReadouts();
+ void DecrementOngoingAsyncPixelReadouts();
+
+ // Send a refresh frame.
+ void SendRefreshFrame();
+
// Object that does all the work of running |new_frame_callback_|.
// Destroyed on |frame_callback_task_runner_| after the class is destroyed.
class CanvasCaptureHandlerDelegate;
@@ -127,6 +132,11 @@ class MODULES_EXPORT CanvasCaptureHandler {
base::Optional<base::TimeTicks> first_frame_ticks_;
scoped_refptr<media::VideoFrame> last_frame_;
+ // The following attributes ensure that CanvasCaptureHandler emits
+ // frames with monotonically increasing timestamps.
+ bool deferred_request_refresh_frame_ = false;
+ int num_ongoing_async_pixel_readouts_ = 0;
+
const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
std::unique_ptr<CanvasCaptureHandlerDelegate> delegate_;
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 06ed0077d1f..bec1d7931b1 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
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/run_loop.h"
+#include "base/test/gmock_callback_support.h"
#include "media/base/limits.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -15,10 +16,12 @@
#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/testing/io_task_runner_testing_platform_support.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkRefCnt.h"
+using base::test::RunOnceClosure;
using ::testing::_;
using ::testing::InSequence;
using ::testing::Mock;
@@ -39,10 +42,6 @@ static const int kTestCanvasCaptureFrameOddSize = 3;
static const int kTestCanvasCaptureFrameColorErrorTolerance = 2;
static const int kTestAlphaValue = 175;
-ACTION_P(RunClosure, closure) {
- closure.Run();
-}
-
} // namespace
class CanvasCaptureHandlerTest
@@ -79,14 +78,17 @@ class CanvasCaptureHandlerTest
void OnRunning(bool state) { DoOnRunning(state); }
// Verify returned frames.
- static sk_sp<SkImage> GenerateTestImage(bool opaque, int width, int height) {
+ static scoped_refptr<StaticBitmapImage> GenerateTestImage(bool opaque,
+ int width,
+ int height) {
SkImageInfo info = SkImageInfo::MakeN32(
width, height, opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType,
SkColorSpace::MakeSRGB());
SkBitmap testBitmap;
testBitmap.allocPixels(info);
testBitmap.eraseARGB(opaque ? 255 : kTestAlphaValue, 30, 60, 200);
- return SkImage::MakeFromBitmap(testBitmap);
+ return UnacceleratedStaticBitmapImage::Create(
+ SkImage::MakeFromBitmap(testBitmap));
}
void OnVerifyDeliveredFrame(bool opaque,
@@ -178,7 +180,7 @@ TEST_P(CanvasCaptureHandlerTest, GetFormatsStartAndStop) {
EXPECT_CALL(*this, DoOnRunning(true)).Times(1);
EXPECT_CALL(*this, DoOnDeliverFrame(_, _))
.Times(1)
- .WillOnce(RunClosure(std::move(quit_closure)));
+ .WillOnce(RunOnceClosure(std::move(quit_closure)));
source->StartCapture(
params,
base::BindRepeating(&CanvasCaptureHandlerTest::OnDeliverFrame,
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 dc70afc31d1..ce10ffb1f97 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(blink::Visitor* visitor) {
+void CanvasCaptureMediaStreamTrack::Trace(Visitor* visitor) {
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 451cd997254..88ff785c474 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 0d8917bab47..db18d7463e5 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
@@ -12,12 +12,12 @@
#include "media/base/media_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.h"
#include "third_party/blink/public/platform/modules/mediastream/web_media_stream_audio_sink.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/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"
namespace blink {
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 a24f912ad07..03ba68236c5 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
@@ -4,12 +4,14 @@
#include "third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.h"
+#include "base/memory/ptr_util.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_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"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
@@ -138,7 +140,7 @@ class MediaElementEventListener final : public NativeEventListener {
MediaElementEventListener(HTMLMediaElement*, MediaStream*);
void UpdateSources(ExecutionContext*);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// EventListener implementation.
void Invoke(ExecutionContext*, Event*) override;
@@ -200,14 +202,14 @@ void MediaElementEventListener::Invoke(ExecutionContext* context,
if (media_element_->HasVideo()) {
CreateHTMLVideoElementCapturer(
- To<Document>(context)->GetFrame(), &web_stream,
+ Document::From(context)->GetFrame(), &web_stream,
media_element_->GetWebMediaPlayer(),
media_element_->GetExecutionContext()->GetTaskRunner(
TaskType::kInternalMediaRealTime));
}
if (media_element_->HasAudio()) {
CreateHTMLAudioElementCapturer(
- To<Document>(context)->GetFrame(), &web_stream,
+ Document::From(context)->GetFrame(), &web_stream,
media_element_->GetWebMediaPlayer(),
media_element_->GetExecutionContext()->GetTaskRunner(
TaskType::kInternalMediaRealTime));
@@ -247,7 +249,7 @@ void MediaElementEventListener::UpdateSources(ExecutionContext* context) {
}
}
-void MediaElementEventListener::Trace(blink::Visitor* visitor) {
+void MediaElementEventListener::Trace(Visitor* visitor) {
visitor->Trace(media_element_);
visitor->Trace(media_stream_);
visitor->Trace(sources_);
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 6c8d4dc8ba4..900d4534bc2 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
@@ -160,9 +160,11 @@ void HtmlVideoElementCapturerSource::sendNewFrame() {
natural_size_, gfx::Rect(natural_size_), natural_size_,
current_time - start_capture_time_);
- const uint32_t source_pixel_format =
- (kN32_SkColorType == kRGBA_8888_SkColorType) ? libyuv::FOURCC_ABGR
- : libyuv::FOURCC_ARGB;
+#if SK_PMCOLOR_BYTE_ORDER(R, G, B, A)
+ const uint32_t source_pixel_format = libyuv::FOURCC_ABGR;
+#else
+ const uint32_t source_pixel_format = libyuv::FOURCC_ARGB;
+#endif
if (frame &&
libyuv::ConvertToI420(
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 26c87156f92..4d24f214880 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
@@ -11,6 +11,7 @@
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/test/gmock_callback_support.h"
#include "cc/paint/paint_canvas.h"
#include "cc/paint/paint_flags.h"
#include "media/base/limits.h"
@@ -22,6 +23,7 @@
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
+using base::test::RunOnceClosure;
using ::testing::_;
using ::testing::InSequence;
using ::testing::Mock;
@@ -31,12 +33,6 @@ namespace blink {
namespace {
-// This is named |RunClosure2| not to collide with the same construction
-// in canvas_capture_handler_unittest.cc on jumbo builds.
-ACTION_P(RunClosure2, closure) {
- closure.Run();
-}
-
// An almost empty WebMediaPlayer to override paint() method.
class MockWebMediaPlayer : public WebMediaPlayer {
public:
@@ -53,18 +49,20 @@ class MockWebMediaPlayer : public WebMediaPlayer {
void SetVolume(double) override {}
void SetLatencyHint(double) override {}
void OnRequestPictureInPicture() override {}
+ void OnPictureInPictureAvailabilityChanged(bool available) override {}
WebTimeRanges Buffered() const override { return WebTimeRanges(); }
WebTimeRanges Seekable() const override { return WebTimeRanges(); }
void SetSinkId(const WebString& sinkId,
WebSetSinkIdCompleteCallback) override {}
bool HasVideo() const override { return true; }
bool HasAudio() const override { return false; }
- WebSize NaturalSize() const override { return size_; }
- WebSize VisibleRect() const override { return size_; }
+ gfx::Size NaturalSize() const override { return size_; }
+ gfx::Size VisibleSize() const override { return size_; }
bool Paused() const override { return false; }
bool Seeking() const override { return false; }
double Duration() const override { return 0.0; }
double CurrentTime() const override { return 0.0; }
+ bool IsEnded() const override { return false; }
NetworkState GetNetworkState() const override { return kNetworkStateEmpty; }
ReadyState GetReadyState() const override { return kReadyStateHaveNothing; }
SurfaceLayerMode GetVideoSurfaceLayerMode() const override {
@@ -99,7 +97,7 @@ class MockWebMediaPlayer : public WebMediaPlayer {
}
bool is_video_opaque_ = true;
- WebSize size_ = WebSize(16, 10);
+ gfx::Size size_ = gfx::Size(16, 10);
base::WeakPtrFactory<MockWebMediaPlayer> weak_factory_{this};
};
@@ -130,7 +128,9 @@ class HTMLVideoElementCapturerSourceTest : public testing::TestWithParam<bool> {
web_media_player_->is_video_opaque_ = opacity;
}
- void SetVideoPlayerSize(WebSize size) { web_media_player_->size_ = size; }
+ void SetVideoPlayerSize(const gfx::Size& size) {
+ web_media_player_->size_ = size;
+ }
protected:
std::unique_ptr<MockWebMediaPlayer> web_media_player_;
@@ -149,10 +149,7 @@ TEST_P(HTMLVideoElementCapturerSourceTest, GetFormatsAndStartAndStop) {
media::VideoCaptureFormats formats =
html_video_capturer_->GetPreferredFormats();
ASSERT_EQ(1u, formats.size());
- EXPECT_EQ(web_media_player_->NaturalSize().width,
- formats[0].frame_size.width());
- EXPECT_EQ(web_media_player_->NaturalSize().height,
- formats[0].frame_size.height());
+ EXPECT_EQ(web_media_player_->NaturalSize(), formats[0].frame_size);
media::VideoCaptureParams params;
params.requested_format = formats[0];
@@ -170,7 +167,7 @@ TEST_P(HTMLVideoElementCapturerSourceTest, GetFormatsAndStartAndStop) {
EXPECT_CALL(*this, DoOnDeliverFrame(_, _))
.Times(1)
.WillOnce(DoAll(SaveArg<0>(&second_frame),
- RunClosure2(std::move(quit_closure))));
+ RunOnceClosure(std::move(quit_closure))));
html_video_capturer_->StartCapture(
params,
@@ -205,10 +202,7 @@ TEST_F(HTMLVideoElementCapturerSourceTest,
media::VideoCaptureFormats formats =
html_video_capturer_->GetPreferredFormats();
ASSERT_EQ(1u, formats.size());
- EXPECT_EQ(web_media_player_->NaturalSize().width,
- formats[0].frame_size.width());
- EXPECT_EQ(web_media_player_->NaturalSize().height,
- formats[0].frame_size.height());
+ EXPECT_EQ(web_media_player_->NaturalSize(), formats[0].frame_size);
media::VideoCaptureParams params;
params.requested_format = formats[0];
@@ -246,7 +240,7 @@ TEST_F(HTMLVideoElementCapturerSourceTest, AlphaAndNot) {
EXPECT_CALL(*this, DoOnRunning(true)).Times(1);
EXPECT_CALL(*this, DoOnDeliverFrame(_, _))
.WillOnce(
- DoAll(SaveArg<0>(&frame), RunClosure2(std::move(quit_closure))));
+ DoAll(SaveArg<0>(&frame), RunOnceClosure(std::move(quit_closure))));
html_video_capturer_->StartCapture(
params,
WTF::BindRepeating(&HTMLVideoElementCapturerSourceTest::OnDeliverFrame,
@@ -265,7 +259,7 @@ TEST_F(HTMLVideoElementCapturerSourceTest, AlphaAndNot) {
scoped_refptr<media::VideoFrame> frame;
EXPECT_CALL(*this, DoOnDeliverFrame(_, _))
.WillOnce(
- DoAll(SaveArg<0>(&frame), RunClosure2(std::move(quit_closure))));
+ DoAll(SaveArg<0>(&frame), RunOnceClosure(std::move(quit_closure))));
run_loop.Run();
EXPECT_EQ(media::PIXEL_FORMAT_I420, frame->format());
@@ -278,7 +272,7 @@ TEST_F(HTMLVideoElementCapturerSourceTest, AlphaAndNot) {
scoped_refptr<media::VideoFrame> frame;
EXPECT_CALL(*this, DoOnDeliverFrame(_, _))
.WillOnce(
- DoAll(SaveArg<0>(&frame), RunClosure2(std::move(quit_closure))));
+ DoAll(SaveArg<0>(&frame), RunOnceClosure(std::move(quit_closure))));
run_loop.Run();
EXPECT_EQ(media::PIXEL_FORMAT_I420A, frame->format());
@@ -299,7 +293,7 @@ TEST_F(HTMLVideoElementCapturerSourceTest, SizeChange) {
params.requested_format = formats[0];
{
- SetVideoPlayerSize(WebSize(16, 10));
+ SetVideoPlayerSize(gfx::Size(16, 10));
base::RunLoop run_loop;
base::RepeatingClosure quit_closure = run_loop.QuitClosure();
@@ -307,7 +301,7 @@ TEST_F(HTMLVideoElementCapturerSourceTest, SizeChange) {
EXPECT_CALL(*this, DoOnRunning(true)).Times(1);
EXPECT_CALL(*this, DoOnDeliverFrame(_, _))
.WillOnce(
- DoAll(SaveArg<0>(&frame), RunClosure2(std::move(quit_closure))));
+ DoAll(SaveArg<0>(&frame), RunOnceClosure(std::move(quit_closure))));
html_video_capturer_->StartCapture(
params,
WTF::BindRepeating(&HTMLVideoElementCapturerSourceTest::OnDeliverFrame,
@@ -317,14 +311,14 @@ TEST_F(HTMLVideoElementCapturerSourceTest, SizeChange) {
run_loop.Run();
}
{
- SetVideoPlayerSize(WebSize(32, 20));
+ SetVideoPlayerSize(gfx::Size(32, 20));
base::RunLoop run_loop;
base::RepeatingClosure quit_closure = run_loop.QuitClosure();
scoped_refptr<media::VideoFrame> frame;
EXPECT_CALL(*this, DoOnDeliverFrame(_, _))
.WillOnce(
- DoAll(SaveArg<0>(&frame), RunClosure2(std::move(quit_closure))));
+ DoAll(SaveArg<0>(&frame), RunOnceClosure(std::move(quit_closure))));
run_loop.Run();
}
diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/idls.gni b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/idls.gni
new file mode 100644
index 00000000000..669ac6e20f6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/idls.gni
@@ -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.
+
+modules_idl_files = [ "canvas_capture_media_stream_track.idl" ]
+
+modules_dependency_idl_files = [
+ "html_canvas_element_capture.idl",
+ "html_media_element_capture.idl",
+]
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 4b2d3329a6d..57f87898277 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
@@ -15,13 +15,13 @@ OnRequestCanvasDrawListener::OnRequestCanvasDrawListener(
OnRequestCanvasDrawListener::~OnRequestCanvasDrawListener() = default;
void OnRequestCanvasDrawListener::SendNewFrame(
- sk_sp<SkImage> image,
+ scoped_refptr<StaticBitmapImage> image,
base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider) {
frame_capture_requested_ = false;
AutoCanvasDrawListener::SendNewFrame(image, context_provider);
}
-void OnRequestCanvasDrawListener::Trace(blink::Visitor* visitor) {
+void OnRequestCanvasDrawListener::Trace(Visitor* visitor) {
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 7507ac61486..57fe0066d74 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
@@ -19,10 +19,10 @@ class OnRequestCanvasDrawListener : public AutoCanvasDrawListener {
explicit OnRequestCanvasDrawListener(std::unique_ptr<CanvasCaptureHandler>);
~OnRequestCanvasDrawListener() override;
- void SendNewFrame(sk_sp<SkImage>,
+ void SendNewFrame(scoped_refptr<StaticBitmapImage>,
base::WeakPtr<WebGraphicsContext3DProviderWrapper>) final;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 9db62d86774..83d2f40d27b 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(blink::Visitor* visitor) {
+void TimedCanvasDrawListener::Trace(Visitor* visitor) {
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 58d2d6fa717..6c3e58ae758 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
// Implementation of TimerFiredFunction.
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/BUILD.gn b/chromium/third_party/blink/renderer/modules/mediarecorder/BUILD.gn
index 832d69768b5..20cf6b7eca2 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/BUILD.gn
@@ -27,6 +27,7 @@ blink_modules_sources("mediarecorder") {
"media_recorder.h",
"media_recorder_handler.cc",
"media_recorder_handler.h",
+ "track_recorder.h",
"vea_encoder.cc",
"vea_encoder.h",
"video_track_recorder.cc",
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/OWNERS b/chromium/third_party/blink/renderer/modules/mediarecorder/OWNERS
index a14da19f558..f320e875e84 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/OWNERS
@@ -1,5 +1,6 @@
-peter@chromium.org
guidou@chromium.org
+handellm@google.com
+peter@chromium.org
# Original (legacy) owner.
emircan@chromium.org
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_opus_encoder.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_opus_encoder.cc
index 4523697b3b2..626259cc6aa 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_opus_encoder.cc
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_opus_encoder.cc
@@ -27,7 +27,7 @@ enum : int {
// Maximum buffer multiplier for the AudioEncoders' AudioFifo. Recording is
// not real time, hence a certain buffering is allowed.
- kMaxNumberOfFifoBuffers = 2,
+ kMaxNumberOfFifoBuffers = 3,
};
// The amount of Frames in a 60 ms buffer @ 48000 samples/second.
@@ -164,8 +164,10 @@ void AudioTrackOpusEncoder::EncodeAudio(
// output and they are multiples.
fifo_->Push(input_bus.get());
- // Wait to have enough |input_bus|s to guarantee a satisfactory conversion.
- while (fifo_->frames() >= input_params_.frames_per_buffer()) {
+ // Wait to have enough |input_bus|s to guarantee a satisfactory conversion,
+ // accounting for multiple calls to ProvideInput().
+ while (fifo_->frames() >= converter_->GetMaxInputFramesRequested(
+ kOpusPreferredFramesPerBuffer)) {
std::unique_ptr<media::AudioBus> audio_bus = media::AudioBus::Create(
converted_params_.channels(), kOpusPreferredFramesPerBuffer);
converter_->Convert(audio_bus.get());
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder.cc
index ced6d2f368b..f96f4c97800 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder.cc
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder.cc
@@ -8,10 +8,10 @@
#include "media/base/audio_bus.h"
#include "media/base/audio_parameters.h"
#include "media/base/bind_to_current_loop.h"
-#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.h"
#include "third_party/blink/renderer/modules/mediarecorder/audio_track_encoder.h"
#include "third_party/blink/renderer/modules/mediarecorder/audio_track_opus_encoder.h"
#include "third_party/blink/renderer/modules/mediarecorder/audio_track_pcm_encoder.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"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
@@ -43,11 +43,14 @@ AudioTrackRecorder::CodecId AudioTrackRecorder::GetPreferredCodecId() {
return CodecId::OPUS;
}
-AudioTrackRecorder::AudioTrackRecorder(CodecId codec,
- MediaStreamComponent* track,
- OnEncodedAudioCB on_encoded_audio_cb,
- int32_t bits_per_second)
- : track_(track),
+AudioTrackRecorder::AudioTrackRecorder(
+ CodecId codec,
+ MediaStreamComponent* track,
+ OnEncodedAudioCB on_encoded_audio_cb,
+ base::OnceClosure on_track_source_ended_cb,
+ int32_t bits_per_second)
+ : TrackRecorder(std::move(on_track_source_ended_cb)),
+ track_(track),
encoder_(CreateAudioEncoder(codec,
std::move(on_encoded_audio_cb),
bits_per_second)),
@@ -62,7 +65,10 @@ AudioTrackRecorder::AudioTrackRecorder(CodecId codec,
ConnectToTrack();
}
-AudioTrackRecorder::~AudioTrackRecorder() = default;
+AudioTrackRecorder::~AudioTrackRecorder() {
+ DCHECK(IsMainThread());
+ DisconnectFromTrack();
+}
// Creates an audio encoder from the codec. Returns nullptr if the codec is
// invalid.
@@ -135,16 +141,4 @@ void AudioTrackRecorder::DisconnectFromTrack() {
audio_track->RemoveSink(this);
}
-void AudioTrackRecorder::Trace(blink::Visitor* visitor) {
- visitor->Trace(track_);
-}
-
-void AudioTrackRecorder::Prefinalize() {
- // TODO(crbug.com/704136) : Remove this method when moving
- // MediaStreamAudioTrack to Oilpan's heap.
- DCHECK(IsMainThread());
- DisconnectFromTrack();
- track_ = nullptr;
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder.h b/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder.h
index 48ff1e9cbd9..e0e16ac3b27 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder.h
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder.h
@@ -11,6 +11,7 @@
#include "base/threading/thread_checker.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/modules/mediarecorder/track_recorder.h"
#include "third_party/blink/renderer/modules/modules_export.h"
namespace media {
@@ -32,10 +33,7 @@ class Thread;
// which lives an AudioTrackEncoder with its own threading subtleties, see the
// implementation file.
class MODULES_EXPORT AudioTrackRecorder
- : public GarbageCollected<AudioTrackRecorder>,
- public WebMediaStreamAudioSink {
- USING_PRE_FINALIZER(AudioTrackRecorder, Prefinalize);
-
+ : public TrackRecorder<WebMediaStreamAudioSink> {
public:
enum class CodecId {
// Do not change the order of codecs. Add new ones right before LAST.
@@ -54,6 +52,7 @@ class MODULES_EXPORT AudioTrackRecorder
AudioTrackRecorder(CodecId codec,
MediaStreamComponent* track,
OnEncodedAudioCB on_encoded_audio_cb,
+ base::OnceClosure on_track_source_ended_cb,
int32_t bits_per_second);
~AudioTrackRecorder() override;
@@ -65,8 +64,6 @@ class MODULES_EXPORT AudioTrackRecorder
void Pause();
void Resume();
- void Trace(blink::Visitor*);
-
private:
// Creates an audio encoder from |codec|. Returns nullptr if the codec is
// invalid.
@@ -85,7 +82,7 @@ class MODULES_EXPORT AudioTrackRecorder
THREAD_CHECKER(capture_thread_checker_);
// We need to hold on to the Blink track to remove ourselves on destruction.
- Member<MediaStreamComponent> track_;
+ Persistent<MediaStreamComponent> track_;
// Thin wrapper around OpusEncoder.
// |encoder_| should be initialized before |encoder_thread_| such that
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 b9b9a38e0f2..ef217eb2a52 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
@@ -10,6 +10,7 @@
#include "base/macros.h"
#include "base/run_loop.h"
+#include "base/test/gmock_callback_support.h"
#include "media/audio/simple_sources.h"
#include "media/base/audio_sample_types.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -18,11 +19,13 @@
#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/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/opus/src/include/opus.h"
using base::TimeTicks;
+using base::test::RunOnceClosure;
using ::testing::_;
namespace {
@@ -44,12 +47,6 @@ const int kFramesPerBuffer = kOpusBufferDurationMs * kDefaultSampleRate / 1000;
namespace blink {
-// Using RunClosure3 instead of RunClosure to avoid symbol collisions in jumbo
-// builds.
-ACTION_P(RunClosure3, closure) {
- closure.Run();
-}
-
struct ATRTestParams {
const media::AudioParameters::Format input_format;
const media::ChannelLayout channel_layout;
@@ -109,10 +106,11 @@ class AudioTrackRecorderTest : public testing::TestWithParam<ATRTestParams> {
first_source_cache_pos_(0) {
ResetDecoder(first_params_);
PrepareBlinkTrack();
- audio_track_recorder_ = MakeGarbageCollected<AudioTrackRecorder>(
+ audio_track_recorder_ = std::make_unique<AudioTrackRecorder>(
codec_, blink_track_,
WTF::BindRepeating(&AudioTrackRecorderTest::OnEncodedAudio,
WTF::Unretained(this)),
+ ConvertToBaseOnceCallback(CrossThreadBindOnce([] {})),
0 /* bits_per_second */);
}
@@ -121,7 +119,7 @@ class AudioTrackRecorderTest : public testing::TestWithParam<ATRTestParams> {
opus_decoder_ = nullptr;
blink_track_.Reset();
WebHeap::CollectAllGarbageForTesting();
- audio_track_recorder_ = nullptr;
+ audio_track_recorder_.reset();
// Let the message loop run to finish destroying the recorder properly.
base::RunLoop().RunUntilIdle();
}
@@ -207,7 +205,7 @@ class AudioTrackRecorderTest : public testing::TestWithParam<ATRTestParams> {
}
// ATR and WebMediaStreamTrack for fooling it.
- Persistent<AudioTrackRecorder> audio_track_recorder_;
+ std::unique_ptr<AudioTrackRecorder> audio_track_recorder_;
WebMediaStreamTrack blink_track_;
// The codec we'll use for compression the audio.
@@ -274,9 +272,9 @@ TEST_P(AudioTrackRecorderTest, OnDataOpus) {
EXPECT_CALL(*this, DoOnEncodedAudio(_, _, _))
.Times(1)
// Only reset the decoder once we've heard back:
- .WillOnce(RunClosure3(
- WTF::BindRepeating(&AudioTrackRecorderTest::ResetDecoder,
- WTF::Unretained(this), second_params_)));
+ .WillOnce(
+ RunOnceClosure(WTF::Bind(&AudioTrackRecorderTest::ResetDecoder,
+ WTF::Unretained(this), second_params_)));
audio_track_recorder_->OnData(*GetFirstSourceAudioBus(),
base::TimeTicks::Now());
for (int i = 0; i < kRatioInputToOutputFrames - 1; ++i) {
@@ -297,7 +295,7 @@ TEST_P(AudioTrackRecorderTest, OnDataOpus) {
// Send audio with different params.
EXPECT_CALL(*this, DoOnEncodedAudio(_, _, _))
.Times(1)
- .WillOnce(RunClosure3(std::move(quit_closure)));
+ .WillOnce(RunOnceClosure(std::move(quit_closure)));
audio_track_recorder_->OnData(*GetSecondSourceAudioBus(),
base::TimeTicks::Now());
for (int i = 0; i < kRatioInputToOutputFrames - 1; ++i) {
@@ -321,7 +319,7 @@ TEST_P(AudioTrackRecorderTest, OnDataPcm) {
EXPECT_CALL(*this, DoOnEncodedAudio(_, _, _)).Times(5);
EXPECT_CALL(*this, DoOnEncodedAudio(_, _, _))
- .WillOnce(RunClosure3(std::move(quit_closure)));
+ .WillOnce(RunOnceClosure(std::move(quit_closure)));
audio_track_recorder_->OnData(*GetFirstSourceAudioBus(),
base::TimeTicks::Now());
@@ -357,7 +355,7 @@ TEST_P(AudioTrackRecorderTest, PauseResume) {
audio_track_recorder_->Resume();
EXPECT_CALL(*this, DoOnEncodedAudio(_, _, _))
.Times(1)
- .WillOnce(RunClosure3(std::move(quit_closure)));
+ .WillOnce(RunOnceClosure(std::move(quit_closure)));
audio_track_recorder_->OnData(*GetFirstSourceAudioBus(),
base::TimeTicks::Now());
for (int i = 0; i < kRatioInputToOutputFrames - 1; ++i) {
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 5429d3973d9..ed34cf77b0f 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.cc
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.cc
@@ -6,7 +6,7 @@
#include <cmath>
-#include "third_party/blink/renderer/modules/mediarecorder/blob_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_blob_event_init.h"
namespace blink {
@@ -20,7 +20,7 @@ const AtomicString& BlobEvent::InterfaceName() const {
return event_interface_names::kBlobEvent;
}
-void BlobEvent::Trace(blink::Visitor* visitor) {
+void BlobEvent::Trace(Visitor* visitor) {
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 9cd044a4d0a..c02118390bb 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(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
Member<Blob> blob_;
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.idl b/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.idl
index 6e778eefabc..6d0d5395b96 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.idl
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.idl
@@ -5,9 +5,9 @@
// https://w3c.github.io/mediacapture-record/#blob-event
[
- Exposed=Window,
- Constructor(DOMString type, BlobEventInit eventInitDict)
-] interface BlobEvent : Event {
+ Exposed=Window
+] interface BlobEvent : Event {
+ constructor(DOMString type, BlobEventInit eventInitDict);
[SameObject] readonly attribute Blob data;
readonly attribute DOMHighResTimeStamp timecode;
};
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc
index add1b5c9aad..401e696e886 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc
@@ -35,12 +35,10 @@ void H264Encoder::ShutdownEncoder(std::unique_ptr<Thread> encoding_thread,
}
H264Encoder::H264Encoder(
- const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback,
+ const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_cb,
int32_t bits_per_second,
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : Encoder(on_encoded_video_callback,
- bits_per_second,
- std::move(task_runner)) {
+ : Encoder(on_encoded_video_cb, bits_per_second, std::move(task_runner)) {
DCHECK(encoding_thread_);
}
@@ -112,7 +110,7 @@ void H264Encoder::EncodeOnEncodingTaskRunner(
*origin_task_runner_.get(), FROM_HERE,
CrossThreadBindOnce(
OnFrameEncodeCompleted,
- WTF::Passed(CrossThreadBindRepeating(on_encoded_video_callback_)),
+ WTF::Passed(CrossThreadBindRepeating(on_encoded_video_cb_)),
video_params, std::move(data), std::string(), capture_timestamp,
is_key_frame));
}
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/h264_encoder.h b/chromium/third_party/blink/renderer/modules/mediarecorder/h264_encoder.h
index 2ac951a0fdb..ecc0688ed2c 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/h264_encoder.h
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/h264_encoder.h
@@ -29,10 +29,9 @@ class H264Encoder final : public VideoTrackRecorder::Encoder {
static void ShutdownEncoder(std::unique_ptr<Thread> encoding_thread,
ScopedISVCEncoderPtr encoder);
- H264Encoder(
- const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback,
- int32_t bits_per_second,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+ H264Encoder(const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_cb,
+ int32_t bits_per_second,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner);
private:
// VideoTrackRecorder::Encoder implementation.
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/idls.gni b/chromium/third_party/blink/renderer/modules/mediarecorder/idls.gni
new file mode 100644
index 00000000000..b7495f219b1
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "blob_event.idl",
+ "media_recorder.idl",
+]
+
+modules_dictionary_idl_files = [
+ "blob_event_init.idl",
+ "media_recorder_options.idl",
+]
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 bf8c6c7216f..47da141fed3 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc
@@ -87,7 +87,7 @@ void AllocateVideoAndAudioBitrates(ExceptionState& exception_state,
// Limit audio bitrate values if set explicitly or calculated.
if (options->hasAudioBitsPerSecond() || options->hasBitsPerSecond()) {
if (audio_bps > kLargestAutoAllocatedOpusBitRate) {
- context->AddConsoleMessage(ConsoleMessage::Create(
+ context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning,
"Clamping calculated audio bitrate (" + String::Number(audio_bps) +
@@ -97,7 +97,7 @@ void AllocateVideoAndAudioBitrates(ExceptionState& exception_state,
}
if (audio_bps < kSmallestPossibleOpusBitRate) {
- context->AddConsoleMessage(ConsoleMessage::Create(
+ context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning,
"Clamping calculated audio bitrate (" + String::Number(audio_bps) +
@@ -118,7 +118,7 @@ void AllocateVideoAndAudioBitrates(ExceptionState& exception_state,
// explicitly.
if (options->hasVideoBitsPerSecond() || options->hasBitsPerSecond()) {
if (video_bps < kSmallestPossibleVpxBitRate) {
- context->AddConsoleMessage(ConsoleMessage::Create(
+ context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning,
"Clamping calculated video bitrate (" + String::Number(video_bps) +
@@ -157,7 +157,7 @@ MediaRecorder::MediaRecorder(ExecutionContext* context,
MediaStream* stream,
const MediaRecorderOptions* options,
ExceptionState& exception_state)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
stream_(stream),
mime_type_(options->mimeType()),
stopped_(true),
@@ -193,12 +193,6 @@ MediaRecorder::MediaRecorder(ExecutionContext* context,
mime_type_ + ") is not supported.");
return;
}
- // If the user requested no mimeType, query |recorder_handler_|.
- if (options->mimeType().IsEmpty()) {
- const String actual_mime_type = recorder_handler_->ActualMimeType();
- if (!actual_mime_type.IsEmpty())
- mime_type_ = actual_mime_type;
- }
stopped_ = false;
}
@@ -241,7 +235,6 @@ void MediaRecorder::start(int time_slice, ExceptionState& exception_state) {
"There was an error starting the MediaRecorder.");
return;
}
- ScheduleDispatchEvent(Event::Create(event_type_names::kStart));
}
void MediaRecorder::stop(ExceptionState& exception_state) {
@@ -341,10 +334,10 @@ const AtomicString& MediaRecorder::InterfaceName() const {
}
ExecutionContext* MediaRecorder::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
-void MediaRecorder::ContextDestroyed(ExecutionContext*) {
+void MediaRecorder::ContextDestroyed() {
if (stopped_)
return;
@@ -361,9 +354,20 @@ void MediaRecorder::WriteData(const char* data,
size_t length,
bool last_in_slice,
double timecode) {
+ // Update mime_type_ when "onstart" is sent by the MediaRecorder. This method
+ // is used also from StopRecording, with a zero length. If we never wrote
+ // anything we don't want to send start or associated actions (update the mime
+ // type in that case).
+ if (!first_write_received_ && length) {
+ mime_type_ = recorder_handler_->ActualMimeType();
+ }
if (stopped_ && !last_in_slice) {
stopped_ = false;
ScheduleDispatchEvent(Event::Create(event_type_names::kStart));
+ first_write_received_ = true;
+ } else if (!first_write_received_ && length) {
+ ScheduleDispatchEvent(Event::Create(event_type_names::kStart));
+ first_write_received_ = true;
}
if (!blob_data_) {
@@ -389,13 +393,29 @@ void MediaRecorder::OnError(const String& message) {
ScheduleDispatchEvent(Event::Create(event_type_names::kError));
}
+void MediaRecorder::OnAllTracksEnded() {
+ StopRecording();
+}
+
void MediaRecorder::CreateBlobEvent(Blob* blob, double timecode) {
ScheduleDispatchEvent(MakeGarbageCollected<BlobEvent>(
event_type_names::kDataavailable, blob, timecode));
}
void MediaRecorder::StopRecording() {
- DCHECK(state_ != State::kInactive);
+ if (state_ == State::kInactive) {
+ // This may happen if all tracks have ended and recording has stopped or
+ // never started.
+ return;
+ }
+ if (!recorder_handler_) {
+ // This may happen when ContextDestroyed has executed, but the
+ // MediaRecorderHandler still exists and all tracks
+ // have ended leading to a call to OnAllTracksEnded.
+ return;
+ }
+ // Make sure that starting the recorder again yields an onstart event.
+ first_write_received_ = false;
state_ = State::kInactive;
recorder_handler_->Stop();
@@ -428,12 +448,12 @@ void MediaRecorder::DispatchScheduledEvent() {
DispatchEvent(*event);
}
-void MediaRecorder::Trace(blink::Visitor* visitor) {
+void MediaRecorder::Trace(Visitor* visitor) {
visitor->Trace(stream_);
visitor->Trace(recorder_handler_);
visitor->Trace(scheduled_events_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 3afcaa12600..f6194eed0f1 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.h
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.h
@@ -7,11 +7,11 @@
#include <memory>
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_recorder_options.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#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/mediarecorder/media_recorder_handler.h"
-#include "third_party/blink/renderer/modules/mediarecorder/media_recorder_options.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
#include "third_party/blink/renderer/modules/modules_export.h"
@@ -24,7 +24,7 @@ class ExceptionState;
class MODULES_EXPORT MediaRecorder
: public EventTargetWithInlineData,
public ActiveScriptWrappable<MediaRecorder>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(MediaRecorder);
DEFINE_WRAPPERTYPEINFO();
@@ -71,8 +71,8 @@ class MODULES_EXPORT MediaRecorder
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext* context) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
// ScriptWrappable
bool HasPendingActivity() const final { return !stopped_; }
@@ -83,7 +83,11 @@ class MODULES_EXPORT MediaRecorder
double timecode);
virtual void OnError(const String& message);
- void Trace(blink::Visitor* visitor) override;
+ // Causes recording to be stopped, remaining data to be written, and onstop to
+ // be sent, unless recording isn't active in which case nothing happens.
+ void OnAllTracksEnded();
+
+ void Trace(Visitor* visitor) override;
private:
void CreateBlobEvent(Blob* blob, double timecode);
@@ -99,11 +103,9 @@ class MODULES_EXPORT MediaRecorder
int video_bits_per_second_;
State state_;
-
+ bool first_write_received_ = false;
std::unique_ptr<BlobData> blob_data_;
-
Member<MediaRecorderHandler> recorder_handler_;
-
HeapVector<Member<Event>> scheduled_events_;
};
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.idl b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.idl
index 13fb24d6d7c..f5c141fdc08 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.idl
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.idl
@@ -8,11 +8,9 @@ enum RecordingState { "inactive", "recording", "paused" };
[
ActiveScriptWrappable,
- ConstructorCallWith=ExecutionContext,
- Constructor(MediaStream stream, optional MediaRecorderOptions options),
- RaisesException=Constructor,
Exposed=Window
] interface MediaRecorder : EventTarget {
+ [CallWith=ExecutionContext, RaisesException] constructor(MediaStream stream, optional MediaRecorderOptions options = {});
readonly attribute MediaStream stream;
readonly attribute DOMString mimeType;
readonly attribute RecordingState state;
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 75520ab9cdd..d364f59852a 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
@@ -239,6 +239,8 @@ bool MediaRecorderHandler::Start(int timeslice) {
DCHECK(timeslice_.is_zero());
DCHECK(!webm_muxer_);
+ invalidated_ = false;
+
timeslice_ = base::TimeDelta::FromMilliseconds(timeslice);
slice_origin_timestamp_ = base::TimeTicks::Now();
@@ -282,6 +284,9 @@ bool MediaRecorderHandler::Start(int timeslice) {
static_cast<MediaStreamVideoTrack*>(
video_tracks_[0]->GetPlatformTrack());
DCHECK(video_track->source());
+ base::OnceClosure on_track_source_changed_cb = media::BindToCurrentLoop(
+ WTF::Bind(&MediaRecorderHandler::OnSourceReadyStateChanged,
+ WrapWeakPersistent(this)));
const bool use_encoded_source_output =
video_track->source()->SupportsEncodedOutput();
if (passthrough_enabled_ && use_encoded_source_output) {
@@ -290,16 +295,17 @@ bool MediaRecorderHandler::Start(int timeslice) {
WTF::BindRepeating(&MediaRecorderHandler::OnPassthroughVideo,
WrapWeakPersistent(this)));
video_recorders_.emplace_back(
- MakeGarbageCollected<VideoTrackRecorderPassthrough>(
- video_tracks_[0], on_passthrough_video_cb, task_runner_));
+ std::make_unique<VideoTrackRecorderPassthrough>(
+ video_tracks_[0], std::move(on_passthrough_video_cb),
+ std::move(on_track_source_changed_cb), task_runner_));
} else {
const VideoTrackRecorder::OnEncodedVideoCB on_encoded_video_cb =
media::BindToCurrentLoop(WTF::BindRepeating(
&MediaRecorderHandler::OnEncodedVideo, WrapWeakPersistent(this)));
- video_recorders_.emplace_back(
- MakeGarbageCollected<VideoTrackRecorderImpl>(
- video_codec_id_, video_tracks_[0], on_encoded_video_cb,
- video_bits_per_second_, task_runner_));
+ video_recorders_.emplace_back(std::make_unique<VideoTrackRecorderImpl>(
+ video_codec_id_, video_tracks_[0], std::move(on_encoded_video_cb),
+ std::move(on_track_source_changed_cb), video_bits_per_second_,
+ task_runner_));
}
}
@@ -313,12 +319,14 @@ bool MediaRecorderHandler::Start(int timeslice) {
return false;
const AudioTrackRecorder::OnEncodedAudioCB on_encoded_audio_cb =
- media::BindToCurrentLoop(base::Bind(
+ media::BindToCurrentLoop(WTF::BindRepeating(
&MediaRecorderHandler::OnEncodedAudio, WrapWeakPersistent(this)));
-
- audio_recorders_.emplace_back(MakeGarbageCollected<AudioTrackRecorder>(
+ base::OnceClosure on_track_source_changed_cb = media::BindToCurrentLoop(
+ WTF::Bind(&MediaRecorderHandler::OnSourceReadyStateChanged,
+ WrapWeakPersistent(this)));
+ audio_recorders_.emplace_back(std::make_unique<AudioTrackRecorder>(
audio_codec_id_, audio_tracks_[0], std::move(on_encoded_audio_cb),
- audio_bits_per_second_));
+ std::move(on_track_source_changed_cb), audio_bits_per_second_));
}
recording_ = true;
@@ -329,8 +337,7 @@ void MediaRecorderHandler::Stop() {
DCHECK(IsMainThread());
// Don't check |recording_| since we can go directly from pause() to stop().
- if (recording_)
- Pause();
+ invalidated_ = true;
recording_ = false;
timeslice_ = base::TimeDelta::FromMilliseconds(0);
@@ -490,6 +497,10 @@ void MediaRecorderHandler::OnEncodedVideo(
base::TimeTicks timestamp,
bool is_key_frame) {
DCHECK(IsMainThread());
+
+ if (invalidated_)
+ return;
+
auto params_with_codec = params;
params_with_codec.codec = MediaVideoCodecFromCodecId(video_codec_id_);
HandleEncodedVideo(params_with_codec, std::move(encoded_data),
@@ -518,13 +529,21 @@ void MediaRecorderHandler::HandleEncodedVideo(
bool is_key_frame) {
DCHECK(IsMainThread());
- if (video_recorders_.IsEmpty())
- return;
-
if (UpdateTracksAndCheckIfChanged()) {
recorder_->OnError("Amount of tracks in MediaStream has changed.");
return;
}
+
+ if (!last_seen_codec_.has_value())
+ last_seen_codec_ = params.codec;
+ if (*last_seen_codec_ != params.codec) {
+ recorder_->OnError(
+ String::Format("Video codec changed from %s to %s",
+ media::GetCodecName(*last_seen_codec_).c_str(),
+ media::GetCodecName(params.codec).c_str()));
+ return;
+ }
+
if (!webm_muxer_)
return;
if (!webm_muxer_->OnEncodedVideo(params, std::move(encoded_data),
@@ -540,7 +559,7 @@ void MediaRecorderHandler::OnEncodedAudio(const media::AudioParameters& params,
base::TimeTicks timestamp) {
DCHECK(IsMainThread());
- if (audio_recorders_.IsEmpty())
+ if (invalidated_)
return;
if (UpdateTracksAndCheckIfChanged()) {
@@ -559,7 +578,7 @@ void MediaRecorderHandler::OnEncodedAudio(const media::AudioParameters& params,
void MediaRecorderHandler::WriteData(base::StringPiece data) {
DCHECK(IsMainThread());
- if (!recording_)
+ if (invalidated_)
return;
const base::TimeTicks now = base::TimeTicks::Now();
@@ -613,6 +632,26 @@ bool MediaRecorderHandler::UpdateTracksAndCheckIfChanged() {
return video_tracks_changed || audio_tracks_changed;
}
+void MediaRecorderHandler::OnSourceReadyStateChanged() {
+ for (const auto& track : video_tracks_) {
+ DCHECK(track->Source());
+ if (track->Source()->GetReadyState() !=
+ MediaStreamSource::kReadyStateEnded) {
+ return;
+ }
+ }
+ for (const auto& track : audio_tracks_) {
+ DCHECK(track->Source());
+ if (track->Source()->GetReadyState() !=
+ MediaStreamSource::kReadyStateEnded) {
+ return;
+ }
+ }
+ // All tracks are ended, so stop the recorder in accordance with
+ // https://www.w3.org/TR/mediastream-recording/#mediarecorder-methods.
+ recorder_->OnAllTracksEnded();
+}
+
void MediaRecorderHandler::OnVideoFrameForTesting(
scoped_refptr<media::VideoFrame> frame,
const TimeTicks& timestamp) {
@@ -640,13 +679,11 @@ void MediaRecorderHandler::SetAudioFormatForTesting(
recorder->OnSetFormat(params);
}
-void MediaRecorderHandler::Trace(blink::Visitor* visitor) {
+void MediaRecorderHandler::Trace(Visitor* visitor) {
visitor->Trace(media_stream_);
visitor->Trace(video_tracks_);
visitor->Trace(audio_tracks_);
visitor->Trace(recorder_);
- visitor->Trace(video_recorders_);
- visitor->Trace(audio_recorders_);
}
} // namespace blink
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 696ff098d97..34bc943424c 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(blink::Visitor*);
+ void Trace(Visitor*);
private:
friend class MediaRecorderHandlerTest;
@@ -109,6 +109,9 @@ class MODULES_EXPORT MediaRecorderHandler final
// Updates |video_tracks_|,|audio_tracks_| and returns true if any changed.
bool UpdateTracksAndCheckIfChanged();
+ // Stops recording if all sources are ended
+ void OnSourceReadyStateChanged();
+
void OnVideoFrameForTesting(scoped_refptr<media::VideoFrame> frame,
const base::TimeTicks& timestamp);
void OnEncodedVideoFrameForTesting(scoped_refptr<EncodedVideoFrame> frame,
@@ -138,6 +141,10 @@ class MODULES_EXPORT MediaRecorderHandler final
base::TimeDelta timeslice_;
base::TimeTicks slice_origin_timestamp_;
+ // The last seen video codec of the last received encoded video frame.
+ base::Optional<media::VideoCodec> last_seen_codec_;
+
+ bool invalidated_ = false;
bool recording_;
// The MediaStream being recorded.
Member<MediaStreamDescriptor> media_stream_;
@@ -146,8 +153,8 @@ class MODULES_EXPORT MediaRecorderHandler final
Member<MediaRecorder> recorder_;
- HeapVector<Member<VideoTrackRecorder>> video_recorders_;
- HeapVector<Member<AudioTrackRecorder>> audio_recorders_;
+ Vector<std::unique_ptr<VideoTrackRecorder>> video_recorders_;
+ Vector<std::unique_ptr<AudioTrackRecorder>> audio_recorders_;
// Worker class doing the actual Webm Muxing work.
std::unique_ptr<media::WebmMuxer> webm_muxer_;
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 3720768c1ff..98c6416cc43 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
@@ -8,6 +8,7 @@
#include "base/macros.h"
#include "base/run_loop.h"
+#include "base/test/gmock_callback_support.h"
#include "base/time/time.h"
#include "media/audio/simple_sources.h"
#include "media/base/audio_bus.h"
@@ -16,7 +17,9 @@
#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/web/web_heap.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/core/testing/scoped_mock_overlay_scrollbars.h"
#include "third_party/blink/renderer/modules/mediarecorder/fake_encoded_video_frame.h"
#include "third_party/blink/renderer/modules/mediarecorder/media_recorder.h"
#include "third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h"
@@ -28,11 +31,13 @@
#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
+using base::test::RunOnceClosure;
using ::testing::_;
using ::testing::AtLeast;
using ::testing::Ge;
using ::testing::Gt;
using ::testing::InSequence;
+using ::testing::Invoke;
using ::testing::Lt;
using ::testing::Mock;
using ::testing::Return;
@@ -41,12 +46,6 @@ using ::testing::ValuesIn;
namespace blink {
-// Using RunClosure5 instead of RunClosure to avoid symbol collisions in jumbo
-// builds.
-ACTION_P(RunClosure5, closure) {
- closure.Run();
-}
-
static const std::string kTestVideoTrackId = "video_track_id";
static const std::string kTestAudioTrackId = "audio_track_id";
static const int kTestAudioChannels = 2;
@@ -84,8 +83,8 @@ MediaStream* CreateMediaStream(V8TestingScope& scope) {
auto* component =
MakeGarbageCollected<MediaStreamComponent>("audioTrack", source);
- auto* track =
- MediaStreamTrack::Create(scope.GetExecutionContext(), component);
+ auto* track = MakeGarbageCollected<MediaStreamTrack>(
+ scope.GetExecutionContext(), component);
HeapVector<Member<MediaStreamTrack>> tracks;
tracks.push_back(track);
@@ -109,7 +108,8 @@ class MockMediaRecorder : public MediaRecorder {
MOCK_METHOD1(OnError, void(const String& message));
};
-class MediaRecorderHandlerTest : public TestWithParam<MediaRecorderTestParams> {
+class MediaRecorderHandlerTest : public TestWithParam<MediaRecorderTestParams>,
+ public ScopedMockOverlayScrollbars {
public:
MediaRecorderHandlerTest()
: media_recorder_handler_(MakeGarbageCollected<MediaRecorderHandler>(
@@ -139,6 +139,16 @@ class MediaRecorderHandlerTest : public TestWithParam<MediaRecorderTestParams> {
media_recorder_handler_->OnVideoFrameForTesting(std::move(frame),
base::TimeTicks::Now());
}
+
+ void OnEncodedVideoForTesting(const media::WebmMuxer::VideoParameters& params,
+ std::string encoded_data,
+ std::string encoded_alpha,
+ base::TimeTicks timestamp,
+ bool is_key_frame) {
+ media_recorder_handler_->OnEncodedVideo(params, encoded_data, encoded_alpha,
+ timestamp, is_key_frame);
+ }
+
void OnAudioBusForTesting(const media::AudioBus& audio_bus) {
media_recorder_handler_->OnAudioBusForTesting(audio_bus,
base::TimeTicks::Now());
@@ -294,14 +304,13 @@ TEST_P(MediaRecorderHandlerTest, EncodeVideoFrames) {
{
const size_t kEncodedSizeThreshold = 16;
base::RunLoop run_loop;
- base::RepeatingClosure quit_closure = run_loop.QuitClosure();
// writeData() is pinged a number of times as the WebM header is written;
// the last time it is called it has the encoded data.
EXPECT_CALL(*recorder, WriteData(_, Lt(kEncodedSizeThreshold), _, _))
.Times(AtLeast(1));
EXPECT_CALL(*recorder, WriteData(_, Gt(kEncodedSizeThreshold), _, _))
.Times(1)
- .WillOnce(RunClosure5(std::move(quit_closure)));
+ .WillOnce(RunOnceClosure(run_loop.QuitClosure()));
OnVideoFrameForTesting(video_frame);
run_loop.Run();
@@ -311,14 +320,13 @@ TEST_P(MediaRecorderHandlerTest, EncodeVideoFrames) {
{
const size_t kEncodedSizeThreshold = 12;
base::RunLoop run_loop;
- base::RepeatingClosure quit_closure = run_loop.QuitClosure();
// The second time around writeData() is called a number of times to write
// the WebM frame header, and then is pinged with the encoded data.
EXPECT_CALL(*recorder, WriteData(_, Lt(kEncodedSizeThreshold), _, _))
.Times(AtLeast(1));
EXPECT_CALL(*recorder, WriteData(_, Gt(kEncodedSizeThreshold), _, _))
.Times(1)
- .WillOnce(RunClosure5(std::move(quit_closure)));
+ .WillOnce(RunOnceClosure(run_loop.QuitClosure()));
OnVideoFrameForTesting(video_frame);
run_loop.Run();
@@ -331,20 +339,19 @@ TEST_P(MediaRecorderHandlerTest, EncodeVideoFrames) {
const size_t kEncodedSizeThreshold = 16;
EXPECT_EQ(4u, media::VideoFrame::NumPlanes(alpha_frame->format()));
base::RunLoop run_loop;
- base::RepeatingClosure quit_closure = run_loop.QuitClosure();
// The second time around writeData() is called a number of times to write
// the WebM frame header, and then is pinged with the encoded data.
EXPECT_CALL(*recorder, WriteData(_, Lt(kEncodedSizeThreshold), _, _))
.Times(AtLeast(1));
EXPECT_CALL(*recorder, WriteData(_, Gt(kEncodedSizeThreshold), _, _))
.Times(1)
- .WillOnce(RunClosure5(quit_closure));
+ .WillOnce(RunOnceClosure(run_loop.QuitClosure()));
if (GetParam().encoder_supports_alpha) {
EXPECT_CALL(*recorder, WriteData(_, Lt(kEncodedSizeThreshold), _, _))
.Times(AtLeast(1));
EXPECT_CALL(*recorder, WriteData(_, Gt(kEncodedSizeThreshold), _, _))
.Times(1)
- .WillOnce(RunClosure5(std::move(quit_closure)));
+ .WillOnce(RunOnceClosure(run_loop.QuitClosure()));
}
OnVideoFrameForTesting(alpha_frame);
@@ -393,14 +400,13 @@ TEST_P(MediaRecorderHandlerTest, OpusEncodeAudioFrames) {
const size_t kEncodedSizeThreshold = 24;
{
base::RunLoop run_loop;
- base::RepeatingClosure quit_closure = run_loop.QuitClosure();
// writeData() is pinged a number of times as the WebM header is written;
// the last time it is called it has the encoded data.
EXPECT_CALL(*recorder, WriteData(_, Lt(kEncodedSizeThreshold), _, _))
.Times(AtLeast(1));
EXPECT_CALL(*recorder, WriteData(_, Gt(kEncodedSizeThreshold), _, _))
.Times(1)
- .WillOnce(RunClosure5(std::move(quit_closure)));
+ .WillOnce(RunOnceClosure(run_loop.QuitClosure()));
for (int i = 0; i < kRatioOpusToTestAudioBuffers; ++i)
OnAudioBusForTesting(*audio_bus1);
@@ -410,14 +416,13 @@ TEST_P(MediaRecorderHandlerTest, OpusEncodeAudioFrames) {
{
base::RunLoop run_loop;
- base::RepeatingClosure quit_closure = run_loop.QuitClosure();
// The second time around writeData() is called a number of times to write
// the WebM frame header, and then is pinged with the encoded data.
EXPECT_CALL(*recorder, WriteData(_, Lt(kEncodedSizeThreshold), _, _))
.Times(AtLeast(1));
EXPECT_CALL(*recorder, WriteData(_, Gt(kEncodedSizeThreshold), _, _))
.Times(1)
- .WillOnce(RunClosure5(std::move(quit_closure)));
+ .WillOnce(RunOnceClosure(run_loop.QuitClosure()));
for (int i = 0; i < kRatioOpusToTestAudioBuffers; ++i)
OnAudioBusForTesting(*audio_bus2);
@@ -455,11 +460,10 @@ TEST_P(MediaRecorderHandlerTest, WebmMuxerErrorWhileEncoding) {
{
const size_t kEncodedSizeThreshold = 16;
base::RunLoop run_loop;
- base::RepeatingClosure quit_closure = run_loop.QuitClosure();
EXPECT_CALL(*recorder, WriteData(_, _, _, _)).Times(AtLeast(1));
EXPECT_CALL(*recorder, WriteData(_, Gt(kEncodedSizeThreshold), _, _))
.Times(1)
- .WillOnce(RunClosure5(std::move(quit_closure)));
+ .WillOnce(RunOnceClosure(run_loop.QuitClosure()));
OnVideoFrameForTesting(video_frame);
run_loop.Run();
@@ -469,11 +473,10 @@ TEST_P(MediaRecorderHandlerTest, WebmMuxerErrorWhileEncoding) {
{
base::RunLoop run_loop;
- base::RepeatingClosure quit_closure = run_loop.QuitClosure();
EXPECT_CALL(*recorder, WriteData(_, _, _, _)).Times(0);
EXPECT_CALL(*recorder, OnError(_))
.Times(1)
- .WillOnce(RunClosure5(std::move(quit_closure)));
+ .WillOnce(RunOnceClosure(run_loop.QuitClosure()));
OnVideoFrameForTesting(video_frame);
run_loop.Run();
@@ -514,6 +517,69 @@ TEST_P(MediaRecorderHandlerTest, ActualMimeType) {
media_recorder_handler_ = nullptr;
}
+TEST_P(MediaRecorderHandlerTest, PauseRecorderForVideo) {
+ // Video-only test: Audio would be very similar.
+ if (GetParam().has_audio)
+ return;
+
+ AddTracks();
+
+ V8TestingScope scope;
+ auto* recorder = MakeGarbageCollected<MockMediaRecorder>(scope);
+
+ const String mime_type(GetParam().mime_type);
+ const String codecs(GetParam().codecs);
+
+ EXPECT_TRUE(media_recorder_handler_->Initialize(
+ recorder, registry_.test_stream(), mime_type, codecs, 0, 0));
+ EXPECT_TRUE(media_recorder_handler_->Start(0));
+
+ Mock::VerifyAndClearExpectations(recorder);
+ media_recorder_handler_->Pause();
+
+ EXPECT_CALL(*recorder, WriteData).Times(AtLeast(1));
+ media::WebmMuxer::VideoParameters params(gfx::Size(), 1, media::kCodecVP9,
+ gfx::ColorSpace());
+ OnEncodedVideoForTesting(params, "vp9 frame", "", base::TimeTicks::Now(),
+ true);
+
+ // Expect a last call on destruction.
+ EXPECT_CALL(*recorder, WriteData(_, _, true, _)).Times(1);
+ media_recorder_handler_ = nullptr;
+}
+
+TEST_P(MediaRecorderHandlerTest, StartStopStartRecorderForVideo) {
+ // Video-only test: Audio would be very similar.
+ if (GetParam().has_audio)
+ return;
+
+ AddTracks();
+
+ V8TestingScope scope;
+ auto* recorder = MakeGarbageCollected<MockMediaRecorder>(scope);
+
+ const String mime_type(GetParam().mime_type);
+ const String codecs(GetParam().codecs);
+
+ EXPECT_TRUE(media_recorder_handler_->Initialize(
+ recorder, registry_.test_stream(), mime_type, codecs, 0, 0));
+ EXPECT_TRUE(media_recorder_handler_->Start(0));
+ media_recorder_handler_->Stop();
+
+ Mock::VerifyAndClearExpectations(recorder);
+ EXPECT_TRUE(media_recorder_handler_->Start(0));
+
+ EXPECT_CALL(*recorder, WriteData).Times(AtLeast(1));
+ media::WebmMuxer::VideoParameters params(gfx::Size(), 1, media::kCodecVP9,
+ gfx::ColorSpace());
+ OnEncodedVideoForTesting(params, "vp9 frame", "", base::TimeTicks::Now(),
+ true);
+
+ // Expect a last call on destruction.
+ EXPECT_CALL(*recorder, WriteData(_, _, true, _)).Times(1);
+ media_recorder_handler_ = nullptr;
+}
+
struct MediaRecorderPassthroughTestParams {
const char* mime_type;
media::VideoCodec codec;
@@ -529,7 +595,8 @@ static const MediaRecorderPassthroughTestParams
};
class MediaRecorderHandlerPassthroughTest
- : public TestWithParam<MediaRecorderPassthroughTestParams> {
+ : public TestWithParam<MediaRecorderPassthroughTestParams>,
+ public ScopedMockOverlayScrollbars {
public:
MediaRecorderHandlerPassthroughTest() {
registry_.Init();
@@ -542,7 +609,8 @@ class MediaRecorderHandlerPassthroughTest
~MediaRecorderHandlerPassthroughTest() {
registry_.reset();
- ThreadState::Current()->CollectAllGarbageForTesting();
+ media_recorder_handler_ = nullptr;
+ WebHeap::CollectAllGarbageForTesting();
}
void OnVideoFrameForTesting(scoped_refptr<EncodedVideoFrame> frame) {
@@ -552,7 +620,7 @@ class MediaRecorderHandlerPassthroughTest
ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_;
MockMediaStreamRegistry registry_;
- MockMediaStreamVideoSource* video_source_ = 0;
+ MockMediaStreamVideoSource* video_source_ = nullptr;
Persistent<MediaRecorderHandler> media_recorder_handler_;
private:
@@ -578,11 +646,10 @@ TEST_P(MediaRecorderHandlerPassthroughTest, PassesThrough) {
.BuildRefPtr();
{
base::RunLoop run_loop;
- base::Closure quit_closure = run_loop.QuitClosure();
EXPECT_CALL(*recorder, WriteData(_, _, _, _)).Times(AtLeast(1));
EXPECT_CALL(*recorder, WriteData(_, Ge(kFrameSize), _, _))
.Times(1)
- .WillOnce(RunClosure5(std::move(quit_closure)));
+ .WillOnce(RunOnceClosure(run_loop.QuitClosure()));
OnVideoFrameForTesting(frame);
run_loop.Run();
}
@@ -596,7 +663,47 @@ TEST_P(MediaRecorderHandlerPassthroughTest, PassesThrough) {
media_recorder_handler_ = nullptr;
}
-INSTANTIATE_TEST_SUITE_P(,
+TEST_F(MediaRecorderHandlerPassthroughTest, ErrorsOutOnCodecSwitch) {
+ V8TestingScope scope;
+ auto* recorder = MakeGarbageCollected<MockMediaRecorder>(scope);
+ EXPECT_TRUE(media_recorder_handler_->Initialize(
+ recorder, registry_.test_stream(), "", "", 0, 0));
+ EXPECT_TRUE(media_recorder_handler_->Start(0));
+
+ // NOTE, Asan: the prototype of WriteData which has a const char* as data
+ // ptr plays badly with gmock which tries to interpret it as a null-terminated
+ // string. However, it points to binary data which causes gmock to overrun the
+ // bounds of buffers and this manifests as an ASAN crash.
+ // The expectation here works around this issue.
+ EXPECT_CALL(*recorder, WriteData).Times(AtLeast(1));
+
+ EXPECT_CALL(*recorder, OnError).WillOnce(Invoke([&](const String&) {
+ // Simulate MediaRecorder behavior which is to Stop() the handler on error.
+ media_recorder_handler_->Stop();
+ }));
+ OnVideoFrameForTesting(FakeEncodedVideoFrame::Builder()
+ .WithKeyFrame(true)
+ .WithCodec(media::kCodecVP8)
+ .WithData(std::string("vp8 frame"))
+ .BuildRefPtr());
+ // Switch to VP9 frames. This is expected to cause the call to OnError
+ // above.
+ OnVideoFrameForTesting(FakeEncodedVideoFrame::Builder()
+ .WithKeyFrame(true)
+ .WithCodec(media::kCodecVP9)
+ .WithData(std::string("vp9 frame"))
+ .BuildRefPtr());
+ // Send one more frame to verify that continued frame of different codec
+ // transfer doesn't crash the media recorder.
+ OnVideoFrameForTesting(FakeEncodedVideoFrame::Builder()
+ .WithKeyFrame(true)
+ .WithCodec(media::kCodecVP8)
+ .WithData(std::string("vp8 frame"))
+ .BuildRefPtr());
+ platform_->RunUntilIdle();
+}
+
+INSTANTIATE_TEST_SUITE_P(All,
MediaRecorderHandlerPassthroughTest,
ValuesIn(kMediaRecorderPassthroughTestParams));
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_unittest.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_unittest.cc
new file mode 100644
index 00000000000..078487d67e0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_unittest.cc
@@ -0,0 +1,57 @@
+// 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/mediarecorder/media_recorder.h"
+
+#include <memory>
+
+#include "testing/gmock/include/gmock/gmock.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/bindings/core/v8/v8_binding_for_testing.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_audio_source.h"
+#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h"
+
+namespace blink {
+namespace {
+
+MediaStream* CreateMediaStream(V8TestingScope* scope) {
+ WebMediaStreamSource blink_source;
+ blink_source.Initialize("video source id", WebMediaStreamSource::kTypeVideo,
+ "video source name", false /* remote */);
+ auto native_source = std::make_unique<MockMediaStreamVideoSource>();
+ MockMediaStreamVideoSource* native_source_ptr = native_source.get();
+ blink_source.SetPlatformSource(std::move(native_source));
+ auto* component = MakeGarbageCollected<MediaStreamComponent>(blink_source);
+ component->SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>(
+ native_source_ptr, MediaStreamVideoSource::ConstraintsOnceCallback(),
+ true /* enabled */));
+ auto* track = MakeGarbageCollected<MediaStreamTrack>(
+ scope->GetExecutionContext(), component);
+ return MediaStream::Create(scope->GetExecutionContext(),
+ MediaStreamTrackVector{track});
+}
+} // namespace
+
+// This is a regression test for crbug.com/1999203
+TEST(MediaRecorderTest,
+ AcceptsAllTracksEndedEventWhenExecutionContextDestroyed) {
+ ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform;
+ {
+ V8TestingScope scope;
+ MediaStream* stream = CreateMediaStream(&scope);
+ MediaRecorder* recorder = MakeGarbageCollected<MediaRecorder>(
+ scope.GetExecutionContext(), stream, MediaRecorderOptions::Create(),
+ scope.GetExceptionState());
+ recorder->start(scope.GetExceptionState());
+ for (const auto& track : stream->getTracks())
+ track->Component()->GetPlatformTrack()->Stop();
+ }
+ platform->RunUntilIdle();
+ WebHeap::CollectAllGarbageForTesting();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/track_recorder.h b/chromium/third_party/blink/renderer/modules/mediarecorder/track_recorder.h
new file mode 100644
index 00000000000..bd13d24f5ba
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/track_recorder.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_MODULES_MEDIARECORDER_TRACK_RECORDER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIARECORDER_TRACK_RECORDER_H_
+
+#include "third_party/blink/public/platform/modules/mediastream/web_media_stream_sink.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+
+namespace blink {
+
+// This class exists to give MediaRecorder support for behavior related to
+// all tracks ending.
+// It's a template because VideoTrackRecorder and AudioTrackRecorder inherit
+// from different base classes.
+// Note: this class supports instantiation with classes that inherit from
+// WebMediaStreamSink.
+template <class MediaStreamSink>
+class TrackRecorder : public MediaStreamSink {
+ public:
+ explicit TrackRecorder(base::OnceClosure track_ended_cb);
+ ~TrackRecorder() override = default;
+
+ // WebMediaStreamSink
+ void OnReadyStateChanged(WebMediaStreamSource::ReadyState state) override;
+
+ private:
+ base::OnceClosure track_ended_cb_;
+};
+
+template <class MediaStreamSink>
+TrackRecorder<MediaStreamSink>::TrackRecorder(base::OnceClosure track_ended_cb)
+ : track_ended_cb_(std::move(track_ended_cb)) {}
+
+template <class MediaStreamSink>
+void TrackRecorder<MediaStreamSink>::OnReadyStateChanged(
+ WebMediaStreamSource::ReadyState state) {
+ if (state == WebMediaStreamSource::kReadyStateEnded)
+ std::move(track_ended_cb_).Run();
+}
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIARECORDER_TRACK_RECORDER_H_
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/track_recorder_unittest.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/track_recorder_unittest.cc
new file mode 100644
index 00000000000..8dcf91d0011
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/track_recorder_unittest.cc
@@ -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.
+
+#include "third_party/blink/renderer/modules/mediarecorder/track_recorder.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
+
+namespace blink {
+
+namespace {
+using ::testing::MockFunction;
+
+void CallMockFunction(MockFunction<void()>* function) {
+ function->Call();
+}
+
+TEST(TrackRecorderTest, CallsOutOnSourceStateEnded) {
+ MockFunction<void()> callback;
+ EXPECT_CALL(callback, Call);
+
+ TrackRecorder<WebMediaStreamSink> recorder(
+ base::BindOnce(&CallMockFunction, base::Unretained(&callback)));
+ recorder.OnReadyStateChanged(WebMediaStreamSource::kReadyStateEnded);
+}
+
+TEST(TrackRecorderTest, DoesNotCallOutOnAnythingButStateEnded) {
+ MockFunction<void()> callback;
+ EXPECT_CALL(callback, Call).Times(0);
+
+ TrackRecorder<WebMediaStreamSink> recorder(
+ base::BindOnce(&CallMockFunction, base::Unretained(&callback)));
+ recorder.OnReadyStateChanged(WebMediaStreamSource::kReadyStateLive);
+ recorder.OnReadyStateChanged(WebMediaStreamSource::kReadyStateMuted);
+}
+} // namespace
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/vea_encoder.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/vea_encoder.cc
index 6bea5a08209..baa57866f1a 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/vea_encoder.cc
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/vea_encoder.cc
@@ -36,16 +36,16 @@ const uint32_t kMaxKeyframeInterval = 100;
} // anonymous namespace
scoped_refptr<VEAEncoder> VEAEncoder::Create(
- const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback,
- const VideoTrackRecorder::OnErrorCB& on_error_callback,
+ const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_cb,
+ const VideoTrackRecorder::OnErrorCB& on_error_cb,
int32_t bits_per_second,
media::VideoCodecProfile codec,
const gfx::Size& size,
bool use_native_input,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- auto encoder = base::AdoptRef(
- new VEAEncoder(on_encoded_video_callback, on_error_callback,
- bits_per_second, codec, size, std::move(task_runner)));
+ auto encoder = base::AdoptRef(new VEAEncoder(on_encoded_video_cb, on_error_cb,
+ bits_per_second, codec, size,
+ std::move(task_runner)));
PostCrossThreadTask(
*encoder->encoding_task_runner_.get(), FROM_HERE,
CrossThreadBindOnce(&VEAEncoder::ConfigureEncoderOnEncodingTaskRunner,
@@ -58,13 +58,13 @@ bool VEAEncoder::OutputBuffer::IsValid() {
}
VEAEncoder::VEAEncoder(
- const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback,
- const VideoTrackRecorder::OnErrorCB& on_error_callback,
+ const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_cb,
+ const VideoTrackRecorder::OnErrorCB& on_error_cb,
int32_t bits_per_second,
media::VideoCodecProfile codec,
const gfx::Size& size,
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : Encoder(on_encoded_video_callback,
+ : Encoder(on_encoded_video_cb,
bits_per_second > 0 ? bits_per_second
: size.GetArea() * kVEADefaultBitratePerPixel,
std::move(task_runner),
@@ -74,7 +74,7 @@ VEAEncoder::VEAEncoder(
error_notified_(false),
num_frames_after_keyframe_(0),
force_next_frame_to_be_keyframe_(false),
- on_error_callback_(on_error_callback) {
+ on_error_cb_(on_error_cb) {
DCHECK(gpu_factories_);
DCHECK_GE(size.width(), kVEAEncoderMinResolutionWidth);
DCHECK_GE(size.height(), kVEAEncoderMinResolutionHeight);
@@ -152,7 +152,7 @@ void VEAEncoder::BitstreamBufferReady(
*origin_task_runner_.get(), FROM_HERE,
CrossThreadBindOnce(
OnFrameEncodeCompleted,
- WTF::Passed(CrossThreadBindRepeating(on_encoded_video_callback_)),
+ WTF::Passed(CrossThreadBindRepeating(on_encoded_video_cb_)),
front_frame.first, std::move(data), std::string(), front_frame.second,
metadata.key_frame));
@@ -164,7 +164,7 @@ void VEAEncoder::NotifyError(media::VideoEncodeAccelerator::Error error) {
DCHECK(encoding_task_runner_->BelongsToCurrentThread());
UMA_HISTOGRAM_ENUMERATION("Media.MediaRecorder.VEAError", error,
media::VideoEncodeAccelerator::kErrorMax + 1);
- on_error_callback_.Run();
+ on_error_cb_.Run();
error_notified_ = true;
}
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/vea_encoder.h b/chromium/third_party/blink/renderer/modules/mediarecorder/vea_encoder.h
index 141a4925211..35ea80aa490 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/vea_encoder.h
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/vea_encoder.h
@@ -30,8 +30,8 @@ class VEAEncoder final : public VideoTrackRecorder::Encoder,
public media::VideoEncodeAccelerator::Client {
public:
static scoped_refptr<VEAEncoder> Create(
- const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback,
- const VideoTrackRecorder::OnErrorCB& on_error_callback,
+ const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_cb,
+ const VideoTrackRecorder::OnErrorCB& on_error_cb,
int32_t bits_per_second,
media::VideoCodecProfile codec,
const gfx::Size& size,
@@ -65,13 +65,12 @@ class VEAEncoder final : public VideoTrackRecorder::Encoder,
bool IsValid();
};
- VEAEncoder(
- const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback,
- const VideoTrackRecorder::OnErrorCB& on_error_callback,
- int32_t bits_per_second,
- media::VideoCodecProfile codec,
- const gfx::Size& size,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+ VEAEncoder(const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_cb,
+ const VideoTrackRecorder::OnErrorCB& on_error_cb,
+ int32_t bits_per_second,
+ media::VideoCodecProfile codec,
+ const gfx::Size& size,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner);
void UseOutputBitstreamBufferId(int32_t bitstream_buffer_id);
void FrameFinished(std::unique_ptr<InputBuffer> shm);
@@ -123,7 +122,7 @@ class VEAEncoder final : public VideoTrackRecorder::Encoder,
bool force_next_frame_to_be_keyframe_;
// This callback can be exercised on any thread.
- const VideoTrackRecorder::OnErrorCB on_error_callback_;
+ const VideoTrackRecorder::OnErrorCB on_error_cb_;
};
} // namespace blink
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 b9ecb5749f7..95e749732cd 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
@@ -98,7 +98,8 @@ media::VideoEncodeAccelerator::SupportedProfiles GetVEASupportedProfiles() {
DVLOG(2) << "Couldn't initialize GpuVideoAcceleratorFactories";
return media::VideoEncodeAccelerator::SupportedProfiles();
}
- return gpu_factories->GetVideoEncodeAcceleratorSupportedProfiles();
+ return gpu_factories->GetVideoEncodeAcceleratorSupportedProfiles().value_or(
+ media::VideoEncodeAccelerator::SupportedProfiles());
}
VideoTrackRecorderImpl::CodecEnumerator* GetCodecEnumerator() {
@@ -109,6 +110,10 @@ VideoTrackRecorderImpl::CodecEnumerator* GetCodecEnumerator() {
} // anonymous namespace
+VideoTrackRecorder::VideoTrackRecorder(
+ base::OnceClosure on_track_source_ended_cb)
+ : TrackRecorder(std::move(on_track_source_ended_cb)) {}
+
VideoTrackRecorderImpl::CodecEnumerator::CodecEnumerator(
const media::VideoEncodeAccelerator::SupportedProfiles&
vea_supported_profiles) {
@@ -194,18 +199,18 @@ VideoTrackRecorderImpl::Counter::GetWeakPtr() {
}
VideoTrackRecorderImpl::Encoder::Encoder(
- const OnEncodedVideoCB& on_encoded_video_callback,
+ const OnEncodedVideoCB& on_encoded_video_cb,
int32_t bits_per_second,
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> encoding_task_runner)
: main_task_runner_(std::move(main_task_runner)),
encoding_task_runner_(encoding_task_runner),
paused_(false),
- on_encoded_video_callback_(on_encoded_video_callback),
+ on_encoded_video_cb_(on_encoded_video_cb),
bits_per_second_(bits_per_second),
num_frames_in_encode_(
std::make_unique<VideoTrackRecorderImpl::Counter>()) {
- DCHECK(!on_encoded_video_callback_.is_null());
+ DCHECK(!on_encoded_video_cb_.is_null());
if (encoding_task_runner_)
return;
@@ -236,6 +241,7 @@ void VideoTrackRecorderImpl::Encoder::StartFrameEncode(
if (!(video_frame->format() == media::PIXEL_FORMAT_I420 ||
video_frame->format() == media::PIXEL_FORMAT_ARGB ||
+ video_frame->format() == media::PIXEL_FORMAT_ABGR ||
video_frame->format() == media::PIXEL_FORMAT_I420A ||
video_frame->format() == media::PIXEL_FORMAT_NV12 ||
video_frame->format() == media::PIXEL_FORMAT_XRGB)) {
@@ -308,6 +314,7 @@ void VideoTrackRecorderImpl::Encoder::RetrieveFrameOnMainThread(
// TODO(crbug/1023390): Add browsertest for these.
DCHECK(video_frame->HasTextures());
DCHECK(video_frame->format() == media::PIXEL_FORMAT_ARGB ||
+ video_frame->format() == media::PIXEL_FORMAT_ABGR ||
video_frame->format() == media::PIXEL_FORMAT_XRGB);
const gfx::Size& old_visible_size = video_frame->visible_rect().size();
@@ -348,9 +355,11 @@ void VideoTrackRecorderImpl::Encoder::RetrieveFrameOnMainThread(
return;
}
- const uint32_t source_pixel_format =
- (kN32_SkColorType == kRGBA_8888_SkColorType) ? libyuv::FOURCC_ABGR
- : libyuv::FOURCC_ARGB;
+#if SK_PMCOLOR_BYTE_ORDER(R, G, B, A)
+ const uint32_t source_pixel_format = libyuv::FOURCC_ABGR;
+#else
+ const uint32_t source_pixel_format = libyuv::FOURCC_ARGB;
+#endif
if (libyuv::ConvertToI420(static_cast<uint8_t*>(pixmap.writable_addr()),
pixmap.computeByteSize(),
frame->visible_data(media::VideoFrame::kYPlane),
@@ -477,26 +486,31 @@ bool VideoTrackRecorderImpl::CanUseAcceleratedEncoder(CodecId codec,
VideoTrackRecorderImpl::VideoTrackRecorderImpl(
CodecId codec,
MediaStreamComponent* track,
- const OnEncodedVideoCB& on_encoded_video_callback,
+ OnEncodedVideoCB on_encoded_video_cb,
+ base::OnceClosure on_track_source_ended_cb,
int32_t bits_per_second,
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner)
- : track_(track),
+ : VideoTrackRecorder(std::move(on_track_source_ended_cb)),
+ track_(track),
should_pause_encoder_on_initialization_(false),
main_task_runner_(std::move(main_task_runner)) {
DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
DCHECK(track_);
DCHECK(track_->Source()->GetType() == MediaStreamSource::kTypeVideo);
- initialize_encoder_callback_ = WTF::BindRepeating(
- &VideoTrackRecorderImpl::InitializeEncoder, WrapWeakPersistent(this),
- codec, on_encoded_video_callback, bits_per_second);
+ initialize_encoder_cb_ = WTF::BindRepeating(
+ &VideoTrackRecorderImpl::InitializeEncoder, weak_factory_.GetWeakPtr(),
+ codec, std::move(on_encoded_video_cb), bits_per_second);
// InitializeEncoder() will be called on Render Main thread.
ConnectToTrack(media::BindToCurrentLoop(WTF::BindRepeating(
- initialize_encoder_callback_, true /* allow_vea_encoder */)));
+ initialize_encoder_cb_, true /* allow_vea_encoder */)));
}
-VideoTrackRecorderImpl::~VideoTrackRecorderImpl() = default;
+VideoTrackRecorderImpl::~VideoTrackRecorderImpl() {
+ DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
+ DisconnectFromTrack();
+}
void VideoTrackRecorderImpl::Pause() {
DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
@@ -520,9 +534,8 @@ void VideoTrackRecorderImpl::OnVideoFrameForTesting(
DVLOG(3) << __func__;
if (!encoder_) {
- DCHECK(!initialize_encoder_callback_.is_null());
- initialize_encoder_callback_.Run(true /* allow_vea_encoder */, frame,
- timestamp);
+ DCHECK(!initialize_encoder_cb_.is_null());
+ initialize_encoder_cb_.Run(true /* allow_vea_encoder */, frame, timestamp);
}
encoder_->StartFrameEncode(std::move(frame), timestamp);
@@ -530,7 +543,7 @@ void VideoTrackRecorderImpl::OnVideoFrameForTesting(
void VideoTrackRecorderImpl::InitializeEncoder(
CodecId codec,
- const OnEncodedVideoCB& on_encoded_video_callback,
+ const OnEncodedVideoCB& on_encoded_video_cb,
int32_t bits_per_second,
bool allow_vea_encoder,
scoped_refptr<media::VideoFrame> frame,
@@ -554,9 +567,9 @@ void VideoTrackRecorderImpl::InitializeEncoder(
bool use_import_mode =
frame->storage_type() == media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER;
encoder_ = VEAEncoder::Create(
- on_encoded_video_callback,
+ on_encoded_video_cb,
media::BindToCurrentLoop(WTF::BindRepeating(
- &VideoTrackRecorderImpl::OnError, WrapWeakPersistent(this))),
+ &VideoTrackRecorderImpl::OnError, weak_factory_.GetWeakPtr())),
bits_per_second, vea_profile, input_size, use_import_mode,
main_task_runner_);
} else {
@@ -565,13 +578,13 @@ void VideoTrackRecorderImpl::InitializeEncoder(
#if BUILDFLAG(RTC_USE_H264)
case CodecId::H264:
encoder_ = base::MakeRefCounted<H264Encoder>(
- on_encoded_video_callback, bits_per_second, main_task_runner_);
+ on_encoded_video_cb, bits_per_second, main_task_runner_);
break;
#endif
case CodecId::VP8:
case CodecId::VP9:
encoder_ = base::MakeRefCounted<VpxEncoder>(
- codec == CodecId::VP9, on_encoded_video_callback, bits_per_second,
+ codec == CodecId::VP9, on_encoded_video_cb, bits_per_second,
main_task_runner_);
break;
default:
@@ -595,8 +608,8 @@ void VideoTrackRecorderImpl::OnError() {
// thread.
DisconnectFromTrack();
encoder_ = nullptr;
- ConnectToTrack(media::BindToCurrentLoop(WTF::BindRepeating(
- initialize_encoder_callback_, false /*allow_vea_encoder*/)));
+ ConnectToTrack(media::BindToCurrentLoop(
+ WTF::BindRepeating(initialize_encoder_cb_, false /*allow_vea_encoder*/)));
}
void VideoTrackRecorderImpl::ConnectToTrack(
@@ -612,38 +625,30 @@ void VideoTrackRecorderImpl::DisconnectFromTrack() {
video_track->RemoveSink(this);
}
-void VideoTrackRecorderImpl::Trace(blink::Visitor* visitor) {
- visitor->Trace(track_);
-}
-
-void VideoTrackRecorderImpl::Prefinalize() {
- // TODO(crbug.com/704136) : Remove this method when moving
- // MediaStreamVideoTrack to Oilpan's heap.
- DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
- DisconnectFromTrack();
- track_ = nullptr;
-}
-
VideoTrackRecorderPassthrough::VideoTrackRecorderPassthrough(
MediaStreamComponent* track,
- OnEncodedVideoCB on_encoded_video_callback,
+ OnEncodedVideoCB on_encoded_video_cb,
+ base::OnceClosure on_track_source_ended_cb,
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner)
- : track_(track),
+ : VideoTrackRecorder(std::move(on_track_source_ended_cb)),
+ track_(track),
state_(KeyFrameState::kWaitingForKeyFrame),
main_task_runner_(main_task_runner),
- callback_(std::move(on_encoded_video_callback)) {
+ callback_(std::move(on_encoded_video_cb)) {
DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
- auto* video_track =
- static_cast<MediaStreamVideoTrack*>(track_->GetPlatformTrack());
- DCHECK(video_track);
-
// HandleEncodedVideoFrame() will be called on Render Main thread.
// Note: Adding an encoded sink internally generates a new key frame
// request, no need to RequestRefreshFrame().
- video_track->AddEncodedSink(
- this, media::BindToCurrentLoop(WTF::BindRepeating(
- &VideoTrackRecorderPassthrough::HandleEncodedVideoFrame,
- WrapWeakPersistent(this))));
+ ConnectEncodedToTrack(
+ WebMediaStreamTrack(track_),
+ media::BindToCurrentLoop(WTF::BindRepeating(
+ &VideoTrackRecorderPassthrough::HandleEncodedVideoFrame,
+ weak_factory_.GetWeakPtr())));
+}
+
+VideoTrackRecorderPassthrough::~VideoTrackRecorderPassthrough() {
+ DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
+ DisconnectFromTrack();
}
void VideoTrackRecorderPassthrough::Pause() {
@@ -663,10 +668,6 @@ void VideoTrackRecorderPassthrough::OnEncodedVideoFrameForTesting(
HandleEncodedVideoFrame(frame, capture_time);
}
-void VideoTrackRecorderPassthrough::Trace(blink::Visitor* visitor) {
- visitor->Trace(track_);
-}
-
void VideoTrackRecorderPassthrough::RequestRefreshFrame() {
auto* video_track =
static_cast<MediaStreamVideoTrack*>(track_->GetPlatformTrack());
@@ -678,9 +679,7 @@ void VideoTrackRecorderPassthrough::DisconnectFromTrack() {
// TODO(crbug.com/704136) : Remove this method when moving
// MediaStreamVideoTrack to Oilpan's heap.
DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
- auto* video_track =
- static_cast<MediaStreamVideoTrack*>(track_->GetPlatformTrack());
- video_track->RemoveEncodedSink(this);
+ DisconnectEncodedFromTrack();
}
void VideoTrackRecorderPassthrough::HandleEncodedVideoFrame(
@@ -697,12 +696,16 @@ void VideoTrackRecorderPassthrough::HandleEncodedVideoFrame(
}
state_ = KeyFrameState::kKeyFrameReceivedOK;
+ base::Optional<gfx::ColorSpace> color_space;
+ if (encoded_frame->ColorSpace())
+ color_space = encoded_frame->ColorSpace()->ToGfxColorSpace();
auto span = encoded_frame->Data();
const char* span_begin = reinterpret_cast<const char*>(span.data());
std::string data(span_begin, span_begin + span.size());
media::WebmMuxer::VideoParameters params(encoded_frame->Resolution(),
/*framerate=*/0.0f,
- /*codec=*/encoded_frame->Codec());
+ /*codec=*/encoded_frame->Codec(),
+ color_space);
callback_.Run(params, std::move(data), {}, estimated_capture_time,
encoded_frame->IsKeyFrame());
}
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.h b/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.h
index 08034998a5e..7243be874f4 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.h
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.h
@@ -17,12 +17,12 @@
#include "media/muxers/webm_muxer.h"
#include "media/video/video_encode_accelerator.h"
#include "third_party/blink/public/common/media/video_capture.h"
-#include "third_party/blink/public/platform/modules/mediastream/web_media_stream_sink.h"
#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/public/web/modules/mediastream/encoded_video_frame.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_sink.h"
#include "third_party/blink/renderer/modules/mediarecorder/buildflags.h"
+#include "third_party/blink/renderer/modules/mediarecorder/track_recorder.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/thread_state.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -71,8 +71,7 @@ class Thread;
// Base class serving as interface for eventually saving encoded frames stemming
// from media from a source.
-class VideoTrackRecorder : public GarbageCollectedMixin,
- public WebMediaStreamSink {
+class VideoTrackRecorder : public TrackRecorder<MediaStreamVideoSink> {
public:
// Do not change the order of codecs; add new ones right before LAST.
enum class CodecId {
@@ -124,14 +123,13 @@ class VideoTrackRecorder : public GarbageCollectedMixin,
// passed, a new encoding thread is created and used.
class Encoder : public WTF::ThreadSafeRefCounted<Encoder> {
public:
- Encoder(
- const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback,
- int32_t bits_per_second,
- scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
- scoped_refptr<base::SingleThreadTaskRunner> encoding_task_runner =
- nullptr);
-
- // Start encoding |frame|, returning via |on_encoded_video_callback_|. This
+ Encoder(const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_cb,
+ int32_t bits_per_second,
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> encoding_task_runner =
+ nullptr);
+
+ // Start encoding |frame|, returning via |on_encoded_video_cb_|. This
// call will also trigger an encode configuration upon first frame arrival
// or parameter change, and an EncodeOnEncodingTaskRunner() to actually
// encode the frame. If the |frame|'s data is not directly available (e.g.
@@ -206,7 +204,7 @@ class VideoTrackRecorder : public GarbageCollectedMixin,
std::atomic_bool paused_;
// This callback should be exercised on IO thread.
- const OnEncodedVideoCB on_encoded_video_callback_;
+ const OnEncodedVideoCB on_encoded_video_cb_;
// Target bitrate for video encoding. If 0, a standard bitrate is used.
const int32_t bits_per_second_;
@@ -256,6 +254,8 @@ class VideoTrackRecorder : public GarbageCollectedMixin,
DISALLOW_COPY_AND_ASSIGN(CodecEnumerator);
};
+ explicit VideoTrackRecorder(base::OnceClosure on_track_source_ended_cb);
+
virtual void Pause() = 0;
virtual void Resume() = 0;
virtual void OnVideoFrameForTesting(scoped_refptr<media::VideoFrame> frame,
@@ -271,12 +271,7 @@ class VideoTrackRecorder : public GarbageCollectedMixin,
// other MediaStreamVideo* classes that are constructed/configured on Main
// Render thread but that pass frames on Render IO thread. It has an internal
// Encoder with its own threading subtleties, see the implementation file.
-class MODULES_EXPORT VideoTrackRecorderImpl
- : public GarbageCollected<VideoTrackRecorderImpl>,
- public VideoTrackRecorder {
- USING_PRE_FINALIZER(VideoTrackRecorderImpl, Prefinalize);
- USING_GARBAGE_COLLECTED_MIXIN(VideoTrackRecorderImpl);
-
+class MODULES_EXPORT VideoTrackRecorderImpl : public VideoTrackRecorder {
public:
static CodecId GetPreferredCodecId();
@@ -292,7 +287,8 @@ class MODULES_EXPORT VideoTrackRecorderImpl
VideoTrackRecorderImpl(
CodecId codec,
MediaStreamComponent* track,
- const OnEncodedVideoCB& on_encoded_video_cb,
+ OnEncodedVideoCB on_encoded_video_cb,
+ base::OnceClosure on_track_source_ended_cb,
int32_t bits_per_second,
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner);
~VideoTrackRecorderImpl() override;
@@ -302,12 +298,10 @@ class MODULES_EXPORT VideoTrackRecorderImpl
void OnVideoFrameForTesting(scoped_refptr<media::VideoFrame> frame,
base::TimeTicks capture_time) override;
- void Trace(blink::Visitor*) override;
-
private:
friend class VideoTrackRecorderTest;
void InitializeEncoder(CodecId codec,
- const OnEncodedVideoCB& on_encoded_video_callback,
+ const OnEncodedVideoCB& on_encoded_video_cb,
int32_t bits_per_second,
bool allow_vea_encoder,
scoped_refptr<media::VideoFrame> frame,
@@ -317,13 +311,11 @@ class MODULES_EXPORT VideoTrackRecorderImpl
void ConnectToTrack(const VideoCaptureDeliverFrameCB& callback);
void DisconnectFromTrack();
- void Prefinalize();
-
// Used to check that we are destroyed on the same thread we were created.
THREAD_CHECKER(main_thread_checker_);
// We need to hold on to the Blink track to remove ourselves on dtor.
- Member<MediaStreamComponent> track_;
+ Persistent<MediaStreamComponent> track_;
// Inner class to encode using whichever codec is configured.
scoped_refptr<Encoder> encoder_;
@@ -331,28 +323,26 @@ class MODULES_EXPORT VideoTrackRecorderImpl
base::RepeatingCallback<void(bool allow_vea_encoder,
scoped_refptr<media::VideoFrame> frame,
base::TimeTicks capture_time)>
- initialize_encoder_callback_;
+ initialize_encoder_cb_;
bool should_pause_encoder_on_initialization_;
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ base::WeakPtrFactory<VideoTrackRecorderImpl> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(VideoTrackRecorderImpl);
};
// VideoTrackRecorderPassthrough uses the inherited WebMediaStreamSink to
// dispatch EncodedVideoFrame content received from a MediaStreamVideoTrack.
-class MODULES_EXPORT VideoTrackRecorderPassthrough
- : public GarbageCollected<VideoTrackRecorderPassthrough>,
- public VideoTrackRecorder {
- USING_PRE_FINALIZER(VideoTrackRecorderPassthrough, DisconnectFromTrack);
- USING_GARBAGE_COLLECTED_MIXIN(VideoTrackRecorderPassthrough);
-
+class MODULES_EXPORT VideoTrackRecorderPassthrough : public VideoTrackRecorder {
public:
VideoTrackRecorderPassthrough(
MediaStreamComponent* track,
- OnEncodedVideoCB on_encoded_video_callback,
+ OnEncodedVideoCB on_encoded_video_cb,
+ base::OnceClosure on_track_source_ended_cb,
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner);
+ ~VideoTrackRecorderPassthrough() override;
// VideoTrackRecorderBase
void Pause() override;
@@ -360,8 +350,6 @@ class MODULES_EXPORT VideoTrackRecorderPassthrough
void OnEncodedVideoFrameForTesting(scoped_refptr<EncodedVideoFrame> frame,
base::TimeTicks capture_time) override;
- void Trace(blink::Visitor*) override;
-
private:
void RequestRefreshFrame();
void DisconnectFromTrack();
@@ -373,7 +361,7 @@ class MODULES_EXPORT VideoTrackRecorderPassthrough
// This enum class tracks encoded frame waiting and dispatching state. This
// is needed to guarantee we're dispatching decodable content to
- // |on_encoded_video_callback|. Examples of times where this is needed is
+ // |on_encoded_video_cb|. Examples of times where this is needed is
// startup and Pause/Resume.
enum class KeyFrameState {
kWaitingForKeyFrame,
@@ -382,10 +370,11 @@ class MODULES_EXPORT VideoTrackRecorderPassthrough
};
// We need to hold on to the Blink track to remove ourselves on dtor.
- const Member<MediaStreamComponent> track_;
+ const Persistent<MediaStreamComponent> track_;
KeyFrameState state_;
const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
const OnEncodedVideoCB callback_;
+ base::WeakPtrFactory<VideoTrackRecorderPassthrough> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(VideoTrackRecorderPassthrough);
};
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 2996191ac3e..4d441913456 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
@@ -6,6 +6,7 @@
#include "base/location.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "media/base/video_codecs.h"
#include "media/base/video_frame.h"
@@ -112,15 +113,20 @@ class VideoTrackRecorderTest
}
void InitializeRecorder(VideoTrackRecorder::CodecId codec) {
- video_track_recorder_ = MakeGarbageCollected<VideoTrackRecorderImpl>(
+ video_track_recorder_ = std::make_unique<VideoTrackRecorderImpl>(
codec, blink_track_,
ConvertToBaseRepeatingCallback(
CrossThreadBindRepeating(&VideoTrackRecorderTest::OnEncodedVideo,
CrossThreadUnretained(this))),
+ ConvertToBaseOnceCallback(CrossThreadBindOnce(
+ &VideoTrackRecorderTest::OnSourceReadyStateEnded,
+ CrossThreadUnretained(this))),
0 /* bits_per_second */,
scheduler::GetSingleThreadTaskRunnerForTesting());
}
+ MOCK_METHOD0(OnSourceReadyStateEnded, void());
+
MOCK_METHOD5(OnEncodedVideo,
void(const media::WebmMuxer::VideoParameters& params,
std::string encoded_data,
@@ -156,7 +162,7 @@ class VideoTrackRecorderTest
MediaStreamVideoTrack* track_;
WebMediaStreamTrack blink_track_;
- Persistent<VideoTrackRecorderImpl> video_track_recorder_;
+ std::unique_ptr<VideoTrackRecorderImpl> video_track_recorder_;
private:
DISALLOW_COPY_AND_ASSIGN(VideoTrackRecorderTest);
@@ -168,6 +174,12 @@ TEST_P(VideoTrackRecorderTest, ConstructAndDestruct) {
InitializeRecorder(testing::get<0>(GetParam()));
}
+TEST_F(VideoTrackRecorderTest, RelaysReadyStateEnded) {
+ InitializeRecorder(VideoTrackRecorder::CodecId::VP8);
+ EXPECT_CALL(*this, OnSourceReadyStateEnded);
+ mock_source_->StopSource();
+}
+
// Creates the encoder and encodes 2 frames of the same size; the encoder
// should be initialised and produce a keyframe, then a non-keyframe. Finally
// a frame of larger size is sent and is expected to be encoded as a keyframe.
@@ -316,7 +328,6 @@ TEST_P(VideoTrackRecorderTest, EncodeFrameWithPaddedCodedSize) {
}
base::RunLoop run_loop;
- base::RepeatingClosure quit_closure = run_loop.QuitClosure();
EXPECT_CALL(*this, OnEncodedVideo(_, _, _, _, true))
.Times(1)
.WillOnce(RunClosure(run_loop.QuitClosure()));
@@ -384,7 +395,6 @@ TEST_F(VideoTrackRecorderTest, HandlesOnError) {
EXPECT_FALSE(HasEncoderInstance());
base::RunLoop run_loop;
- base::RepeatingClosure quit_closure = run_loop.QuitClosure();
EXPECT_CALL(*this, OnEncodedVideo(_, _, _, _, true))
.Times(1)
.WillOnce(RunClosure(run_loop.QuitClosure()));
@@ -454,16 +464,17 @@ class VideoTrackRecorderPassthroughTest
~VideoTrackRecorderPassthroughTest() {
blink_track_.Reset();
blink_source_.Reset();
- video_track_recorder_ = nullptr;
+ video_track_recorder_.reset();
WebHeap::CollectAllGarbageForTesting();
}
void InitializeRecorder() {
- video_track_recorder_ = MakeGarbageCollected<VideoTrackRecorderPassthrough>(
+ video_track_recorder_ = std::make_unique<VideoTrackRecorderPassthrough>(
blink_track_,
ConvertToBaseRepeatingCallback(CrossThreadBindRepeating(
&VideoTrackRecorderPassthroughTest::OnEncodedVideo,
CrossThreadUnretained(this))),
+ ConvertToBaseOnceCallback(CrossThreadBindOnce([] {})),
scheduler::GetSingleThreadTaskRunnerForTesting());
}
@@ -483,7 +494,7 @@ class VideoTrackRecorderPassthroughTest
MediaStreamVideoTrack* track_;
WebMediaStreamTrack blink_track_;
- Persistent<VideoTrackRecorderPassthrough> video_track_recorder_;
+ std::unique_ptr<VideoTrackRecorderPassthrough> video_track_recorder_;
};
scoped_refptr<FakeEncodedVideoFrame> CreateFrame(
@@ -557,9 +568,9 @@ TEST_F(VideoTrackRecorderPassthroughTest, DoesntForwardDeltaFrameFirst) {
// Frame 3 (deltaframe) - forwarded
base::RunLoop run_loop;
- base::Closure quit_closure = run_loop.QuitClosure();
frame = CreateFrame(/*is_key_frame=*/false, VideoTrackRecorder::CodecId::VP9);
- EXPECT_CALL(*this, OnEncodedVideo).WillOnce(RunClosure(quit_closure));
+ EXPECT_CALL(*this, OnEncodedVideo)
+ .WillOnce(RunClosure(run_loop.QuitClosure()));
video_track_recorder_->OnEncodedVideoFrameForTesting(frame,
base::TimeTicks::Now());
run_loop.Run();
@@ -604,7 +615,7 @@ TEST_F(VideoTrackRecorderPassthroughTest, PausesAndResumes) {
base::TimeTicks::Now());
}
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
VideoTrackRecorderPassthroughTest,
ValuesIn(kTrackRecorderTestCodec));
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 57fca1b3a68..74807bfacc9 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.cc
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.cc
@@ -44,10 +44,10 @@ void VpxEncoder::ShutdownEncoder(std::unique_ptr<Thread> encoding_thread,
VpxEncoder::VpxEncoder(
bool use_vp9,
- const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback,
+ const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_cb,
int32_t bits_per_second,
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner)
- : VideoTrackRecorder::Encoder(on_encoded_video_callback,
+ : VideoTrackRecorder::Encoder(on_encoded_video_cb,
bits_per_second,
std::move(main_task_runner)),
use_vp9_(use_vp9) {
@@ -139,7 +139,7 @@ void VpxEncoder::EncodeOnEncodingTaskRunner(scoped_refptr<VideoFrame> frame,
*origin_task_runner_.get(), FROM_HERE,
CrossThreadBindOnce(
OnFrameEncodeCompleted,
- WTF::Passed(CrossThreadBindRepeating(on_encoded_video_callback_)),
+ WTF::Passed(CrossThreadBindRepeating(on_encoded_video_cb_)),
video_params, std::move(data), std::move(alpha_data),
capture_timestamp, keyframe));
}
diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.h b/chromium/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.h
index 27579e6bdef..48d569d3420 100644
--- a/chromium/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.h
+++ b/chromium/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.h
@@ -28,11 +28,10 @@ class VpxEncoder final : public VideoTrackRecorder::Encoder {
static void ShutdownEncoder(std::unique_ptr<Thread> encoding_thread,
ScopedVpxCodecCtxPtr encoder);
- VpxEncoder(
- bool use_vp9,
- const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_callback,
- int32_t bits_per_second,
- scoped_refptr<base::SingleThreadTaskRunner> main_task_runner);
+ VpxEncoder(bool use_vp9,
+ const VideoTrackRecorder::OnEncodedVideoCB& on_encoded_video_cb,
+ int32_t bits_per_second,
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner);
private:
// VideoTrackRecorder::Encoder implementation.
diff --git a/chromium/third_party/blink/renderer/modules/mediasession/DEPS b/chromium/third_party/blink/renderer/modules/mediasession/DEPS
index 4704ab16dae..51bf8235873 100644
--- a/chromium/third_party/blink/renderer/modules/mediasession/DEPS
+++ b/chromium/third_party/blink/renderer/modules/mediasession/DEPS
@@ -1,5 +1,5 @@
include_rules = [
- "+mojo/public/cpp/bindings/binding.h",
+ "+base/test/simple_test_tick_clock.h",
"+services/media_session/public/mojom",
"-third_party/blink/renderer/modules",
"+third_party/blink/renderer/modules/event_target_modules.h",
diff --git a/chromium/third_party/blink/renderer/modules/mediasession/OWNERS b/chromium/third_party/blink/renderer/modules/mediasession/OWNERS
index 6b7ed4ae7ba..12bd2f3d66b 100644
--- a/chromium/third_party/blink/renderer/modules/mediasession/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/mediasession/OWNERS
@@ -1,3 +1,4 @@
+beccahughes@chromium.org
foolip@chromium.org
mlamouri@chromium.org
diff --git a/chromium/third_party/blink/renderer/modules/mediasession/idls.gni b/chromium/third_party/blink/renderer/modules/mediasession/idls.gni
new file mode 100644
index 00000000000..57915a56a55
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/mediasession/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "media_metadata.idl",
+ "media_session.idl",
+]
+
+modules_dictionary_idl_files = [
+ "media_image.idl",
+ "media_metadata_init.idl",
+ "media_position_state.idl",
+ "media_session_action_details.idl",
+ "media_session_seek_to_action_details.idl",
+]
+
+modules_dependency_idl_files = [ "navigator_media_session.idl" ]
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 2b99171a987..902dc6d739b 100644
--- a/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.cc
+++ b/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.cc
@@ -7,8 +7,8 @@
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_metadata_init.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
-#include "third_party/blink/renderer/modules/mediasession/media_metadata_init.h"
#include "third_party/blink/renderer/modules/mediasession/media_session.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
@@ -122,7 +122,7 @@ void MediaMetadata::SetArtworkInternal(
artwork_.swap(processed_artwork);
}
-void MediaMetadata::Trace(blink::Visitor* visitor) {
+void MediaMetadata::Trace(Visitor* visitor) {
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 13055d4ab53..591a9fffc12 100644
--- a/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.h
+++ b/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASESSION_MEDIA_METADATA_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASESSION_MEDIA_METADATA_H_
-#include "third_party/blink/renderer/modules/mediasession/media_image.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_image.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/heap/handle.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(blink::Visitor*) override;
+ void Trace(Visitor*) 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_metadata.idl b/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.idl
index ea374ffd1bd..5a09a8ae3f7 100644
--- a/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.idl
+++ b/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.idl
@@ -6,11 +6,9 @@
[
Exposed=Window,
- ConstructorCallWith=ScriptState,
- Constructor(optional MediaMetadataInit metadata),
- RaisesException=Constructor,
RuntimeEnabled=MediaSession
] interface MediaMetadata {
+ [CallWith=ScriptState, RaisesException] constructor(optional MediaMetadataInit init = {});
attribute DOMString title;
attribute DOMString artist;
attribute DOMString album;
diff --git a/chromium/third_party/blink/renderer/modules/mediasession/media_metadata_sanitizer.cc b/chromium/third_party/blink/renderer/modules/mediasession/media_metadata_sanitizer.cc
index 999d75d511c..e26746221cf 100644
--- a/chromium/third_party/blink/renderer/modules/mediasession/media_metadata_sanitizer.cc
+++ b/chromium/third_party/blink/renderer/modules/mediasession/media_metadata_sanitizer.cc
@@ -8,10 +8,11 @@
#include "third_party/blink/public/platform/web_icon_sizes_parser.h"
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_image.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
-#include "third_party/blink/renderer/modules/mediasession/media_image.h"
#include "third_party/blink/renderer/modules/mediasession/media_metadata.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/wtf/text/string_operators.h"
#include "url/url_constants.h"
@@ -41,7 +42,7 @@ bool CheckMediaImageSrcSanity(const KURL& src, ExecutionContext* context) {
if (!src.ProtocolIs(url::kHttpScheme) && !src.ProtocolIs(url::kHttpsScheme) &&
!src.ProtocolIs(url::kDataScheme) && !src.ProtocolIs(url::kBlobScheme)) {
- context->AddConsoleMessage(ConsoleMessage::Create(
+ context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning,
"MediaImage src can only be of http/https/data/blob scheme: " +
@@ -51,7 +52,7 @@ bool CheckMediaImageSrcSanity(const KURL& src, ExecutionContext* context) {
DCHECK(src.GetString().Is8Bit());
if (src.GetString().length() > url::kMaxURLChars) {
- context->AddConsoleMessage(ConsoleMessage::Create(
+ context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning,
"MediaImage src exceeds maximum URL length: " + src.GetString()));
@@ -78,7 +79,7 @@ media_session::mojom::blink::MediaImagePtr SanitizeMediaImageAndConvertToMojo(
WebIconSizesParser::ParseIconSizes(image->sizes())) {
mojo_image->sizes.push_back(web_size);
if (mojo_image->sizes.size() == kMaxNumberOfImageSizes) {
- context->AddConsoleMessage(ConsoleMessage::Create(
+ context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning,
"The number of MediaImage sizes exceeds the upper limit. "
@@ -110,7 +111,7 @@ MediaMetadataSanitizer::SanitizeAndConvertToMojo(const MediaMetadata* metadata,
if (!mojo_image.is_null())
mojo_metadata->artwork.push_back(std::move(mojo_image));
if (mojo_metadata->artwork.size() == kMaxNumberOfMediaImages) {
- context->AddConsoleMessage(ConsoleMessage::Create(
+ context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning,
"The number of MediaImage sizes exceeds the upper limit. "
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 d5a9a79fef5..58f2207102c 100644
--- a/chromium/third_party/blink/renderer/modules/mediasession/media_session.cc
+++ b/chromium/third_party/blink/renderer/modules/mediasession/media_session.cc
@@ -5,18 +5,20 @@
#include "third_party/blink/renderer/modules/mediasession/media_session.h"
#include <memory>
+
#include "base/optional.h"
+#include "base/time/default_tick_clock.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_position_state.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_session_action_details.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_media_session_action_handler.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_session_seek_to_action_details.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_frame.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/modules/mediasession/media_metadata.h"
#include "third_party/blink/renderer/modules/mediasession/media_metadata_sanitizer.h"
-#include "third_party/blink/renderer/modules/mediasession/media_position_state.h"
-#include "third_party/blink/renderer/modules/mediasession/media_session_action_details.h"
-#include "third_party/blink/renderer/modules/mediasession/media_session_seek_to_action_details.h"
#include "third_party/blink/renderer/modules/mediasession/type_converters.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
@@ -124,17 +126,15 @@ mojom::blink::MediaSessionPlaybackState StringToMediaSessionPlaybackState(
} // anonymous namespace
MediaSession::MediaSession(ExecutionContext* execution_context)
- : ContextClient(execution_context),
- playback_state_(mojom::blink::MediaSessionPlaybackState::NONE) {}
-
-void MediaSession::Dispose() {
- client_receiver_.reset();
-}
+ : ExecutionContextClient(execution_context),
+ clock_(base::DefaultTickClock::GetInstance()),
+ playback_state_(mojom::blink::MediaSessionPlaybackState::NONE),
+ client_receiver_(this, execution_context) {}
void MediaSession::setPlaybackState(const String& playback_state) {
playback_state_ = StringToMediaSessionPlaybackState(playback_state);
- RecalculatePositionState(false /* notify */);
+ RecalculatePositionState(/*was_set=*/false);
mojom::blink::MediaSessionService* service = GetService();
if (service)
@@ -263,7 +263,7 @@ void MediaSession::setPositionState(MediaPositionState* position_state,
declared_playback_rate_ = position_state_->playback_rate;
- RecalculatePositionState(true /* notify */);
+ RecalculatePositionState(/*was_set=*/true);
}
void MediaSession::NotifyActionChange(const String& action,
@@ -285,7 +285,25 @@ void MediaSession::NotifyActionChange(const String& action,
}
}
-void MediaSession::RecalculatePositionState(bool notify) {
+base::TimeDelta MediaSession::GetPositionNow() const {
+ const base::TimeTicks now = clock_->NowTicks();
+
+ const base::TimeDelta elapsed_time =
+ position_state_->playback_rate *
+ (now - position_state_->last_updated_time);
+ const base::TimeDelta updated_position =
+ position_state_->position + elapsed_time;
+ const base::TimeDelta start = base::TimeDelta::FromSeconds(0);
+
+ if (updated_position <= start)
+ return start;
+ else if (updated_position >= position_state_->duration)
+ return position_state_->duration;
+ else
+ return updated_position;
+}
+
+void MediaSession::RecalculatePositionState(bool was_set) {
if (!position_state_)
return;
@@ -294,12 +312,18 @@ void MediaSession::RecalculatePositionState(bool notify) {
? 0.0
: declared_playback_rate_;
- notify = notify || new_playback_rate != position_state_->playback_rate;
- position_state_->playback_rate = new_playback_rate;
-
- if (!notify)
+ if (!was_set && new_playback_rate == position_state_->playback_rate)
return;
+ // If we updated the position state because of the playback rate then we
+ // should update the time.
+ if (!was_set) {
+ position_state_->position = GetPositionNow();
+ }
+
+ position_state_->playback_rate = new_playback_rate;
+ position_state_->last_updated_time = clock_->NowTicks();
+
if (auto* service = GetService())
service->SetPositionState(position_state_.Clone());
}
@@ -310,7 +334,7 @@ mojom::blink::MediaSessionService* MediaSession::GetService() {
if (!GetExecutionContext())
return nullptr;
- Document* document = To<Document>(GetExecutionContext());
+ Document* document = Document::From(GetExecutionContext());
LocalFrame* frame = document->GetFrame();
if (!frame)
return nullptr;
@@ -329,7 +353,7 @@ mojom::blink::MediaSessionService* MediaSession::GetService() {
void MediaSession::DidReceiveAction(
media_session::mojom::blink::MediaSessionAction action,
mojom::blink::MediaSessionActionDetailsPtr details) {
- Document* document = To<Document>(GetExecutionContext());
+ Document* document = Document::From(GetExecutionContext());
LocalFrame::NotifyUserActivation(document ? document->GetFrame() : nullptr);
auto& name = MojomActionToActionName(action);
@@ -346,11 +370,12 @@ void MediaSession::DidReceiveAction(
iter->value->InvokeAndReportException(this, blink_details);
}
-void MediaSession::Trace(blink::Visitor* visitor) {
+void MediaSession::Trace(Visitor* visitor) {
+ visitor->Trace(client_receiver_);
visitor->Trace(metadata_);
visitor->Trace(action_handlers_);
ScriptWrappable::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 f1193dbd7bb..6031551c62f 100644
--- a/chromium/third_party/blink/renderer/modules/mediasession/media_session.h
+++ b/chromium/third_party/blink/renderer/modules/mediasession/media_session.h
@@ -6,15 +6,20 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASESSION_MEDIA_SESSION_H_
#include <memory>
-#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/mediasession/media_session.mojom-blink.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/heap/handle.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+namespace base {
+class TickClock;
+} // namespace base
+
namespace blink {
class ExecutionContext;
@@ -25,17 +30,14 @@ class V8MediaSessionActionHandler;
class MODULES_EXPORT MediaSession final
: public ScriptWrappable,
- public ContextClient,
+ public ExecutionContextClient,
blink::mojom::blink::MediaSessionClient {
USING_GARBAGE_COLLECTED_MIXIN(MediaSession);
DEFINE_WRAPPERTYPEINFO();
- USING_PRE_FINALIZER(MediaSession, Dispose);
public:
explicit MediaSession(ExecutionContext*);
- void Dispose();
-
void setPlaybackState(const String&);
String playbackState();
@@ -52,7 +54,7 @@ class MODULES_EXPORT MediaSession final
// internally when a new MediaMetadata object is set.
void OnMetadataChanged();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
friend class V8MediaSession;
@@ -65,7 +67,9 @@ class MODULES_EXPORT MediaSession final
void NotifyActionChange(const String& action, ActionChangeType);
- void RecalculatePositionState(bool notify);
+ base::TimeDelta GetPositionNow() const;
+
+ void RecalculatePositionState(bool was_set);
// blink::mojom::blink::MediaSessionClient implementation.
void DidReceiveAction(media_session::mojom::blink::MediaSessionAction,
@@ -74,14 +78,17 @@ class MODULES_EXPORT MediaSession final
// Returns null when the ExecutionContext is not document.
mojom::blink::MediaSessionService* GetService();
+ const base::TickClock* clock_ = nullptr;
+
mojom::blink::MediaSessionPlaybackState playback_state_;
media_session::mojom::blink::MediaPositionPtr position_state_;
double declared_playback_rate_ = 0.0;
Member<MediaMetadata> metadata_;
HeapHashMap<String, Member<V8MediaSessionActionHandler>> action_handlers_;
mojo::Remote<mojom::blink::MediaSessionService> service_;
- mojo::Receiver<blink::mojom::blink::MediaSessionClient> client_receiver_{
- this};
+ HeapMojoReceiver<blink::mojom::blink::MediaSessionClient,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ client_receiver_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/mediasession/media_session_test.cc b/chromium/third_party/blink/renderer/modules/mediasession/media_session_test.cc
index 303865ea1af..523db2280c5 100644
--- a/chromium/third_party/blink/renderer/modules/mediasession/media_session_test.cc
+++ b/chromium/third_party/blink/renderer/modules/mediasession/media_session_test.cc
@@ -5,11 +5,12 @@
#include "third_party/blink/renderer/modules/mediasession/media_session.h"
#include "base/macros.h"
+#include "base/test/simple_test_tick_clock.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "testing/gmock/include/gmock/gmock.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_position_state.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
-#include "third_party/blink/renderer/modules/mediasession/media_position_state.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
namespace blink {
@@ -54,8 +55,10 @@ class MediaSessionTest : public PageTestBase {
mock_service_ = std::make_unique<MockMediaSessionService>();
- media_session_ = MakeGarbageCollected<MediaSession>(&GetDocument());
+ media_session_ =
+ MakeGarbageCollected<MediaSession>(GetDocument().ToExecutionContext());
media_session_->service_ = mock_service_->CreateRemoteAndBind();
+ media_session_->clock_ = &test_clock_;
}
void SetPositionState(double duration,
@@ -82,7 +85,11 @@ class MediaSessionTest : public PageTestBase {
MockMediaSessionService& service() { return *mock_service_.get(); }
+ base::SimpleTestTickClock& clock() { return test_clock_; }
+
private:
+ base::SimpleTestTickClock test_clock_;
+
std::unique_ptr<MockMediaSessionService> mock_service_;
Persistent<MediaSession> media_session_;
@@ -97,6 +104,7 @@ TEST_F(MediaSessionTest, PlaybackPositionState_None) {
EXPECT_EQ(base::TimeDelta::FromSeconds(10), position_state->duration);
EXPECT_EQ(base::TimeDelta::FromSeconds(5), position_state->position);
EXPECT_EQ(1.0, position_state->playback_rate);
+ EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
@@ -113,6 +121,7 @@ TEST_F(MediaSessionTest, PlaybackPositionState_Paused) {
EXPECT_EQ(base::TimeDelta::FromSeconds(10), position_state->duration);
EXPECT_EQ(base::TimeDelta::FromSeconds(5), position_state->position);
EXPECT_EQ(0.0, position_state->playback_rate);
+ EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
@@ -129,6 +138,7 @@ TEST_F(MediaSessionTest, PlaybackPositionState_Playing) {
EXPECT_EQ(base::TimeDelta::FromSeconds(10), position_state->duration);
EXPECT_EQ(base::TimeDelta::FromSeconds(5), position_state->position);
EXPECT_EQ(1.0, position_state->playback_rate);
+ EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
@@ -146,6 +156,7 @@ TEST_F(MediaSessionTest, PlaybackPositionState_Paused_Clear) {
EXPECT_EQ(base::TimeDelta::FromSeconds(10), position_state->duration);
EXPECT_EQ(base::TimeDelta::FromSeconds(5), position_state->position);
EXPECT_EQ(0.0, position_state->playback_rate);
+ EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
@@ -175,6 +186,7 @@ TEST_F(MediaSessionTest, PositionPlaybackState_None) {
EXPECT_EQ(base::TimeDelta::FromSeconds(10), position_state->duration);
EXPECT_EQ(base::TimeDelta::FromSeconds(5), position_state->position);
EXPECT_EQ(1.0, position_state->playback_rate);
+ EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
@@ -189,24 +201,28 @@ TEST_F(MediaSessionTest, PositionPlaybackState_Paused_None) {
base::RunLoop loop;
EXPECT_CALL(service(), SetPositionState(_))
.WillOnce(testing::Invoke([&](auto position_state) {
- EXPECT_EQ(base::TimeDelta::FromSeconds(10), position_state->duration);
- EXPECT_EQ(base::TimeDelta::FromSeconds(5), position_state->position);
+ EXPECT_EQ(base::TimeDelta::FromMinutes(10), position_state->duration);
+ EXPECT_EQ(base::TimeDelta::FromMinutes(1), position_state->position);
EXPECT_EQ(1.0, position_state->playback_rate);
+ EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
- SetPositionState(10, 5, 1.0);
+ SetPositionState(600, 60, 1.0);
loop.Run();
}
+ clock().Advance(base::TimeDelta::FromMinutes(1));
+
{
base::RunLoop loop;
EXPECT_CALL(service(), SetPositionState(_))
.WillOnce(testing::Invoke([&](auto position_state) {
- EXPECT_EQ(base::TimeDelta::FromSeconds(10), position_state->duration);
- EXPECT_EQ(base::TimeDelta::FromSeconds(5), position_state->position);
+ EXPECT_EQ(base::TimeDelta::FromMinutes(10), position_state->duration);
+ EXPECT_EQ(base::TimeDelta::FromMinutes(2), position_state->position);
EXPECT_EQ(0.0, position_state->playback_rate);
+ EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
@@ -215,13 +231,16 @@ TEST_F(MediaSessionTest, PositionPlaybackState_Paused_None) {
loop.Run();
}
+ clock().Advance(base::TimeDelta::FromMinutes(1));
+
{
base::RunLoop loop;
EXPECT_CALL(service(), SetPositionState(_))
.WillOnce(testing::Invoke([&](auto position_state) {
- EXPECT_EQ(base::TimeDelta::FromSeconds(10), position_state->duration);
- EXPECT_EQ(base::TimeDelta::FromSeconds(5), position_state->position);
+ EXPECT_EQ(base::TimeDelta::FromMinutes(10), position_state->duration);
+ EXPECT_EQ(base::TimeDelta::FromMinutes(2), position_state->position);
EXPECT_EQ(1.0, position_state->playback_rate);
+ EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
@@ -236,24 +255,28 @@ TEST_F(MediaSessionTest, PositionPlaybackState_Paused_Playing) {
base::RunLoop loop;
EXPECT_CALL(service(), SetPositionState(_))
.WillOnce(testing::Invoke([&](auto position_state) {
- EXPECT_EQ(base::TimeDelta::FromSeconds(10), position_state->duration);
- EXPECT_EQ(base::TimeDelta::FromSeconds(5), position_state->position);
+ EXPECT_EQ(base::TimeDelta::FromMinutes(10), position_state->duration);
+ EXPECT_EQ(base::TimeDelta::FromMinutes(1), position_state->position);
EXPECT_EQ(1.0, position_state->playback_rate);
+ EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
- SetPositionState(10, 5, 1.0);
+ SetPositionState(600, 60, 1.0);
loop.Run();
}
+ clock().Advance(base::TimeDelta::FromMinutes(1));
+
{
base::RunLoop loop;
EXPECT_CALL(service(), SetPositionState(_))
.WillOnce(testing::Invoke([&](auto position_state) {
- EXPECT_EQ(base::TimeDelta::FromSeconds(10), position_state->duration);
- EXPECT_EQ(base::TimeDelta::FromSeconds(5), position_state->position);
+ EXPECT_EQ(base::TimeDelta::FromMinutes(10), position_state->duration);
+ EXPECT_EQ(base::TimeDelta::FromMinutes(2), position_state->position);
EXPECT_EQ(0.0, position_state->playback_rate);
+ EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
@@ -262,13 +285,16 @@ TEST_F(MediaSessionTest, PositionPlaybackState_Paused_Playing) {
loop.Run();
}
+ clock().Advance(base::TimeDelta::FromMinutes(1));
+
{
base::RunLoop loop;
EXPECT_CALL(service(), SetPositionState(_))
.WillOnce(testing::Invoke([&](auto position_state) {
- EXPECT_EQ(base::TimeDelta::FromSeconds(10), position_state->duration);
- EXPECT_EQ(base::TimeDelta::FromSeconds(5), position_state->position);
+ EXPECT_EQ(base::TimeDelta::FromMinutes(10), position_state->duration);
+ EXPECT_EQ(base::TimeDelta::FromMinutes(2), position_state->position);
EXPECT_EQ(1.0, position_state->playback_rate);
+ EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
@@ -285,6 +311,7 @@ TEST_F(MediaSessionTest, PositionPlaybackState_Playing) {
EXPECT_EQ(base::TimeDelta::FromSeconds(10), position_state->duration);
EXPECT_EQ(base::TimeDelta::FromSeconds(5), position_state->position);
EXPECT_EQ(1.0, position_state->playback_rate);
+ EXPECT_EQ(clock().NowTicks(), position_state->last_updated_time);
loop.Quit();
}));
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 54c7ea56d3c..cc4d23cbf92 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(blink::Visitor* visitor) {
+void NavigatorMediaSession::Trace(Visitor* visitor) {
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 5b630718e47..f55d6874f7a 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
// The MediaSession instance of this Navigator.
diff --git a/chromium/third_party/blink/renderer/modules/mediasession/type_converters.h b/chromium/third_party/blink/renderer/modules/mediasession/type_converters.h
index cb5903cfec2..85c86d615b3 100644
--- a/chromium/third_party/blink/renderer/modules/mediasession/type_converters.h
+++ b/chromium/third_party/blink/renderer/modules/mediasession/type_converters.h
@@ -6,9 +6,9 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASESSION_TYPE_CONVERTERS_H_
#include "third_party/blink/public/mojom/mediasession/media_session.mojom-blink.h"
-#include "third_party/blink/renderer/modules/mediasession/media_position_state.h"
-#include "third_party/blink/renderer/modules/mediasession/media_session_action_details.h"
-#include "third_party/blink/renderer/modules/mediasession/media_session_seek_to_action_details.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_position_state.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_session_action_details.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_session_seek_to_action_details.h"
namespace mojo {
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/BUILD.gn b/chromium/third_party/blink/renderer/modules/mediasource/BUILD.gn
index 4ee775d673d..bf3ad2072ef 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/mediasource/BUILD.gn
@@ -8,8 +8,8 @@ blink_modules_sources("mediasource") {
sources = [
"html_video_element_media_source.cc",
"html_video_element_media_source.h",
- "media_source.cc",
- "media_source.h",
+ "media_source_impl.cc",
+ "media_source_impl.h",
"media_source_registry.cc",
"media_source_registry.h",
"source_buffer.cc",
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/idls.gni b/chromium/third_party/blink/renderer/modules/mediasource/idls.gni
new file mode 100644
index 00000000000..5ebc2d32982
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/mediasource/idls.gni
@@ -0,0 +1,19 @@
+# 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 = [
+ "media_source.idl",
+ "source_buffer.idl",
+ "source_buffer_list.idl",
+ "track_default.idl",
+ "track_default_list.idl",
+ "video_playback_quality.idl",
+]
+
+modules_dependency_idl_files = [
+ "audio_track_source_buffer.idl",
+ "html_video_element_media_source.idl",
+ "url_media_source.idl",
+ "video_track_source_buffer.idl",
+]
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/media_source.idl b/chromium/third_party/blink/renderer/modules/mediasource/media_source.idl
index 76a2b9b7764..fa3e8267e5f 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/media_source.idl
+++ b/chromium/third_party/blink/renderer/modules/mediasource/media_source.idl
@@ -36,11 +36,11 @@ enum EndOfStreamError {
};
[
+ ImplementedAs=MediaSourceImpl,
ActiveScriptWrappable,
- Constructor,
- ConstructorCallWith=ExecutionContext,
- Exposed(Window MediaSourceStable, DedicatedWorker MediaSourceInWorkers, SharedWorker MediaSourceInWorkers)
+ Exposed(Window MediaSourceStable, DedicatedWorker MediaSourceInWorkers)
] interface MediaSource : EventTarget {
+ [CallWith=ExecutionContext] constructor();
// All the source buffers created by this object.
readonly attribute SourceBufferList sourceBuffers;
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/media_source.cc b/chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.cc
index 9e24dab598b..2f8b01af3d1 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/media_source.cc
+++ b/chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.cc
@@ -28,11 +28,12 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "third_party/blink/renderer/modules/mediasource/media_source.h"
+#include "third_party/blink/renderer/modules/mediasource/media_source_impl.h"
#include <memory>
#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_functions.h"
#include "media/base/logging_override_if_enabled.h"
#include "third_party/blink/public/platform/web_media_source.h"
#include "third_party/blink/public/platform/web_source_buffer.h"
@@ -47,7 +48,6 @@
#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/heap/heap.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.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/network/mime/content_type.h"
@@ -64,16 +64,22 @@ namespace {
// ones must never be renumbered or deleted and reused.
enum class MseExecutionContext {
kWindow = 0,
+
+ // TODO(wolenetz): Support MSE usage in dedicated workers. See
+ // https://crbug.com/878133.
kDedicatedWorker = 1,
+
+ // TODO(wolenetz): Consider supporting MSE usage in SharedWorkers. See
+ // https://crbug.com/1054566.
kSharedWorker = 2,
- kMax = kSharedWorker
+ kMaxValue = kSharedWorker
};
} // namespace
static bool ThrowExceptionIfClosed(bool is_open,
ExceptionState& exception_state) {
if (!is_open) {
- MediaSource::LogAndThrowDOMException(
+ MediaSourceImpl::LogAndThrowDOMException(
exception_state, DOMExceptionCode::kInvalidStateError,
"The MediaSource's readyState is not 'open'.");
return true;
@@ -89,38 +95,37 @@ static bool ThrowExceptionIfClosedOrUpdating(bool is_open,
return true;
if (is_updating) {
- MediaSource::LogAndThrowDOMException(exception_state,
- DOMExceptionCode::kInvalidStateError,
- "The 'updating' attribute is true on "
- "one or more of this MediaSource's "
- "SourceBuffers.");
+ MediaSourceImpl::LogAndThrowDOMException(
+ exception_state, DOMExceptionCode::kInvalidStateError,
+ "The 'updating' attribute is true on one or more of this MediaSource's "
+ "SourceBuffers.");
return true;
}
return false;
}
-const AtomicString& MediaSource::OpenKeyword() {
+const AtomicString& MediaSourceImpl::OpenKeyword() {
DEFINE_STATIC_LOCAL(const AtomicString, open, ("open"));
return open;
}
-const AtomicString& MediaSource::ClosedKeyword() {
+const AtomicString& MediaSourceImpl::ClosedKeyword() {
DEFINE_STATIC_LOCAL(const AtomicString, closed, ("closed"));
return closed;
}
-const AtomicString& MediaSource::EndedKeyword() {
+const AtomicString& MediaSourceImpl::EndedKeyword() {
DEFINE_STATIC_LOCAL(const AtomicString, ended, ("ended"));
return ended;
}
-MediaSource* MediaSource::Create(ExecutionContext* context) {
- return MakeGarbageCollected<MediaSource>(context);
+MediaSourceImpl* MediaSourceImpl::Create(ExecutionContext* context) {
+ return MakeGarbageCollected<MediaSourceImpl>(context);
}
-MediaSource::MediaSource(ExecutionContext* context)
- : ContextLifecycleObserver(context),
+MediaSourceImpl::MediaSourceImpl(ExecutionContext* context)
+ : ExecutionContextLifecycleObserver(context),
ready_state_(ClosedKeyword()),
async_event_queue_(
MakeGarbageCollected<EventQueue>(context,
@@ -148,38 +153,37 @@ MediaSource::MediaSource(ExecutionContext* context)
else
CHECK(false) << "Invalid execution context for MSE usage";
}
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- EnumerationHistogram, mse_execution_context_histogram,
- ("Media.MSE.ExecutionContext",
- static_cast<int>(MseExecutionContext::kMax) + 1));
- mse_execution_context_histogram.Count(static_cast<int>(type));
-
- // TODO(wolenetz): Actually enable experimental usage of MediaSource from
- // dedicated and shared worker contexts. See https://crbug.com/878133.
+ base::UmaHistogramEnumeration("Media.MSE.ExecutionContext", type);
+
+ // TODO(wolenetz): Actually enable experimental usage of MediaSource API from
+ // dedicated worker contexts. See https://crbug.com/878133.
+ // TODO(wolenetz): Also consider supporting experimental usage of MediaSource
+ // API from shared worker contexts. See https://crbug.com/1054566.
CHECK(type == MseExecutionContext::kWindow)
<< "MSE is not yet supported from workers";
}
-MediaSource::~MediaSource() {
+MediaSourceImpl::~MediaSourceImpl() {
DVLOG(1) << __func__ << " this=" << this;
}
-void MediaSource::LogAndThrowDOMException(ExceptionState& exception_state,
- DOMExceptionCode error,
- const String& message) {
+void MediaSourceImpl::LogAndThrowDOMException(ExceptionState& exception_state,
+ DOMExceptionCode error,
+ const String& message) {
DVLOG(1) << __func__ << " (error=" << ToExceptionCode(error)
<< ", message=" << message << ")";
exception_state.ThrowDOMException(error, message);
}
-void MediaSource::LogAndThrowTypeError(ExceptionState& exception_state,
- const String& message) {
+void MediaSourceImpl::LogAndThrowTypeError(ExceptionState& exception_state,
+ const String& message) {
DVLOG(1) << __func__ << " (message=" << message << ")";
exception_state.ThrowTypeError(message);
}
-SourceBuffer* MediaSource::addSourceBuffer(const String& type,
- ExceptionState& exception_state) {
+SourceBuffer* MediaSourceImpl::addSourceBuffer(
+ const String& type,
+ ExceptionState& exception_state) {
DVLOG(2) << __func__ << " this=" << this << " type=" << type;
// 2.2
@@ -236,8 +240,8 @@ SourceBuffer* MediaSource::addSourceBuffer(const String& type,
bool generate_timestamps_flag =
web_source_buffer->GetGenerateTimestampsFlag();
- SourceBuffer* buffer = SourceBuffer::Create(std::move(web_source_buffer),
- this, async_event_queue_.Get());
+ auto* buffer = MakeGarbageCollected<SourceBuffer>(
+ std::move(web_source_buffer), this, async_event_queue_.Get());
// 8. Add the new object to sourceBuffers and queue a simple task to fire a
// simple event named addsourcebuffer at sourceBuffers.
source_buffers_->Add(buffer);
@@ -259,8 +263,8 @@ SourceBuffer* MediaSource::addSourceBuffer(const String& type,
return buffer;
}
-void MediaSource::removeSourceBuffer(SourceBuffer* buffer,
- ExceptionState& exception_state) {
+void MediaSourceImpl::removeSourceBuffer(SourceBuffer* buffer,
+ ExceptionState& exception_state) {
DVLOG(2) << __func__ << " this=" << this << " buffer=" << buffer;
// 2.2
@@ -291,8 +295,8 @@ void MediaSource::removeSourceBuffer(SourceBuffer* buffer,
// SourceBuffer::removedFromMediaSource (steps 2-8) above.
}
-void MediaSource::OnReadyStateChange(const AtomicString& old_state,
- const AtomicString& new_state) {
+void MediaSourceImpl::OnReadyStateChange(const AtomicString& old_state,
+ const AtomicString& new_state) {
if (IsOpen()) {
ScheduleEvent(event_type_names::kSourceopen);
return;
@@ -317,7 +321,7 @@ void MediaSource::OnReadyStateChange(const AtomicString& old_state,
ScheduleEvent(event_type_names::kSourceclose);
}
-bool MediaSource::IsUpdating() const {
+bool MediaSourceImpl::IsUpdating() const {
// Return true if any member of |m_sourceBuffers| is updating.
for (unsigned i = 0; i < source_buffers_->length(); ++i) {
if (source_buffers_->item(i)->updating())
@@ -327,7 +331,8 @@ bool MediaSource::IsUpdating() const {
return false;
}
-bool MediaSource::isTypeSupported(const String& type) {
+// static
+bool MediaSourceImpl::isTypeSupported(const String& type) {
// Section 2.2 isTypeSupported() method steps.
// https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#widl-MediaSource-isTypeSupported-boolean-DOMString-type
// 1. If type is an empty string, then return false.
@@ -378,27 +383,29 @@ bool MediaSource::isTypeSupported(const String& type) {
return result;
}
-const AtomicString& MediaSource::InterfaceName() const {
+const AtomicString& MediaSourceImpl::InterfaceName() const {
return event_target_names::kMediaSource;
}
-ExecutionContext* MediaSource::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ExecutionContext* MediaSourceImpl::GetExecutionContext() const {
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
-void MediaSource::Trace(blink::Visitor* visitor) {
+void MediaSourceImpl::Trace(Visitor* visitor) {
visitor->Trace(async_event_queue_);
visitor->Trace(attached_element_);
visitor->Trace(source_buffers_);
visitor->Trace(active_source_buffers_);
visitor->Trace(live_seekable_range_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
-void MediaSource::SetWebMediaSourceAndOpen(
+void MediaSourceImpl::CompleteAttachingToMediaElement(
std::unique_ptr<WebMediaSource> web_media_source) {
- TRACE_EVENT_ASYNC_END0("media", "MediaSource::attachToElement", this);
+ TRACE_EVENT_NESTABLE_ASYNC_END0(
+ "media", "MediaSourceImpl::StartAttachingToMediaElement",
+ TRACE_ID_LOCAL(this));
DCHECK(web_media_source);
DCHECK(!web_media_source_);
DCHECK(attached_element_);
@@ -406,23 +413,23 @@ void MediaSource::SetWebMediaSourceAndOpen(
SetReadyState(OpenKeyword());
}
-void MediaSource::AddedToRegistry() {
+void MediaSourceImpl::AddedToRegistry() {
++added_to_registry_counter_;
// Ensure there's no counter overflow.
CHECK_GT(added_to_registry_counter_, 0);
}
-void MediaSource::RemovedFromRegistry() {
+void MediaSourceImpl::RemovedFromRegistry() {
DCHECK_GT(added_to_registry_counter_, 0);
--added_to_registry_counter_;
}
-double MediaSource::duration() const {
+double MediaSourceImpl::duration() const {
return IsClosed() ? std::numeric_limits<float>::quiet_NaN()
: web_media_source_->Duration();
}
-WebTimeRanges MediaSource::BufferedInternal() const {
+WebTimeRanges MediaSourceImpl::BufferedInternal() const {
// Implements MediaSource algorithm for HTMLMediaElement.buffered.
// https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#htmlmediaelement-extensions
Vector<WebTimeRanges> ranges(active_source_buffers_->length());
@@ -474,11 +481,11 @@ WebTimeRanges MediaSource::BufferedInternal() const {
return intersection_ranges;
}
-TimeRanges* MediaSource::Buffered() const {
+TimeRanges* MediaSourceImpl::Buffered() const {
return MakeGarbageCollected<TimeRanges>(BufferedInternal());
}
-WebTimeRanges MediaSource::SeekableInternal() const {
+WebTimeRanges MediaSourceImpl::SeekableInternal() const {
DCHECK(attached_element_)
<< "Seekable should only be used when attached to HTMLMediaElement";
@@ -533,7 +540,7 @@ WebTimeRanges MediaSource::SeekableInternal() const {
return ranges;
}
-void MediaSource::OnTrackChanged(TrackBase* track) {
+void MediaSourceImpl::OnTrackChanged(TrackBase* track) {
DCHECK(HTMLMediaElement::MediaTracksEnabledInternally());
SourceBuffer* source_buffer =
SourceBufferTrackBaseSupplement::sourceBuffer(*track);
@@ -554,8 +561,8 @@ void MediaSource::OnTrackChanged(TrackBase* track) {
SetSourceBufferActive(source_buffer, is_active);
}
-void MediaSource::setDuration(double duration,
- ExceptionState& exception_state) {
+void MediaSourceImpl::setDuration(double duration,
+ ExceptionState& exception_state) {
DVLOG(3) << __func__ << " this=" << this << " : duration=" << duration;
// 2.1 https://www.w3.org/TR/media-source/#widl-MediaSource-duration
@@ -586,8 +593,8 @@ void MediaSource::setDuration(double duration,
DurationChangeAlgorithm(duration, exception_state);
}
-void MediaSource::DurationChangeAlgorithm(double new_duration,
- ExceptionState& exception_state) {
+void MediaSourceImpl::DurationChangeAlgorithm(double new_duration,
+ ExceptionState& exception_state) {
// http://w3c.github.io/media-source/#duration-change-algorithm
// 1. If the current value of duration is equal to new duration, then return.
if (new_duration == duration())
@@ -654,7 +661,7 @@ void MediaSource::DurationChangeAlgorithm(double new_duration,
attached_element_->DurationChanged(new_duration, request_seek);
}
-void MediaSource::SetReadyState(const AtomicString& state) {
+void MediaSourceImpl::SetReadyState(const AtomicString& state) {
DCHECK(state == OpenKeyword() || state == ClosedKeyword() ||
state == EndedKeyword());
@@ -674,8 +681,8 @@ void MediaSource::SetReadyState(const AtomicString& state) {
OnReadyStateChange(old_state, state);
}
-void MediaSource::endOfStream(const AtomicString& error,
- ExceptionState& exception_state) {
+void MediaSourceImpl::endOfStream(const AtomicString& error,
+ ExceptionState& exception_state) {
DEFINE_STATIC_LOCAL(const AtomicString, network, ("network"));
DEFINE_STATIC_LOCAL(const AtomicString, decode, ("decode"));
@@ -699,13 +706,13 @@ void MediaSource::endOfStream(const AtomicString& error,
EndOfStreamAlgorithm(WebMediaSource::kEndOfStreamStatusNoError);
}
-void MediaSource::endOfStream(ExceptionState& exception_state) {
+void MediaSourceImpl::endOfStream(ExceptionState& exception_state) {
endOfStream("", exception_state);
}
-void MediaSource::setLiveSeekableRange(double start,
- double end,
- ExceptionState& exception_state) {
+void MediaSourceImpl::setLiveSeekableRange(double start,
+ double end,
+ ExceptionState& exception_state) {
DVLOG(3) << __func__ << " this=" << this << " : start=" << start
<< ", end=" << end;
@@ -737,7 +744,7 @@ void MediaSource::setLiveSeekableRange(double start,
live_seekable_range_ = MakeGarbageCollected<TimeRanges>(start, end);
}
-void MediaSource::clearLiveSeekableRange(ExceptionState& exception_state) {
+void MediaSourceImpl::clearLiveSeekableRange(ExceptionState& exception_state) {
DVLOG(3) << __func__ << " this=" << this;
// http://w3c.github.io/media-source/#widl-MediaSource-clearLiveSeekableRange-void
@@ -757,12 +764,12 @@ void MediaSource::clearLiveSeekableRange(ExceptionState& exception_state) {
live_seekable_range_ = MakeGarbageCollected<TimeRanges>();
}
-bool MediaSource::IsOpen() const {
+bool MediaSourceImpl::IsOpen() const {
return readyState() == OpenKeyword();
}
-void MediaSource::SetSourceBufferActive(SourceBuffer* source_buffer,
- bool is_active) {
+void MediaSourceImpl::SetSourceBufferActive(SourceBuffer* source_buffer,
+ bool is_active) {
if (!is_active) {
DCHECK(active_source_buffers_->Contains(source_buffer));
active_source_buffers_->Remove(source_buffer);
@@ -791,11 +798,11 @@ void MediaSource::SetSourceBufferActive(SourceBuffer* source_buffer,
active_source_buffers_->insert(insert_position, source_buffer);
}
-HTMLMediaElement* MediaSource::MediaElement() const {
+HTMLMediaElement* MediaSourceImpl::MediaElement() const {
return attached_element_.Get();
}
-void MediaSource::EndOfStreamAlgorithm(
+void MediaSourceImpl::EndOfStreamAlgorithm(
const WebMediaSource::EndOfStreamStatus eos_status) {
// https://www.w3.org/TR/media-source/#end-of-stream-algorithm
// 1. Change the readyState attribute value to "ended".
@@ -829,26 +836,28 @@ void MediaSource::EndOfStreamAlgorithm(
}
}
-bool MediaSource::IsClosed() const {
+bool MediaSourceImpl::IsClosed() const {
return readyState() == ClosedKeyword();
}
-void MediaSource::Close() {
+void MediaSourceImpl::Close() {
SetReadyState(ClosedKeyword());
}
-bool MediaSource::AttachToElement(HTMLMediaElement* element) {
+bool MediaSourceImpl::StartAttachingToMediaElement(HTMLMediaElement* element) {
if (attached_element_)
return false;
DCHECK(IsClosed());
- TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSource::attachToElement", this);
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(
+ "media", "MediaSourceImpl::StartAttachingToMediaElement",
+ TRACE_ID_LOCAL(this));
attached_element_ = element;
return true;
}
-void MediaSource::OpenIfInEndedState() {
+void MediaSourceImpl::OpenIfInEndedState() {
if (ready_state_ != EndedKeyword())
return;
@@ -856,7 +865,7 @@ void MediaSource::OpenIfInEndedState() {
web_media_source_->UnmarkEndOfStream();
}
-bool MediaSource::HasPendingActivity() const {
+bool MediaSourceImpl::HasPendingActivity() const {
// Note that an unrevoked MediaSource objectUrl for an otherwise inactive,
// unreferenced HTMLME with MSE still attached will prevent GC of the whole
// group of objects. This is unfortunate, because it's conceivable that the
@@ -869,13 +878,13 @@ bool MediaSource::HasPendingActivity() const {
added_to_registry_counter_ > 0;
}
-void MediaSource::ContextDestroyed(ExecutionContext*) {
+void MediaSourceImpl::ContextDestroyed() {
if (!IsClosed())
SetReadyState(ClosedKeyword());
web_media_source_.reset();
}
-std::unique_ptr<WebSourceBuffer> MediaSource::CreateWebSourceBuffer(
+std::unique_ptr<WebSourceBuffer> MediaSourceImpl::CreateWebSourceBuffer(
const String& type,
const String& codecs,
ExceptionState& exception_state) {
@@ -914,7 +923,7 @@ std::unique_ptr<WebSourceBuffer> MediaSource::CreateWebSourceBuffer(
return nullptr;
}
-void MediaSource::ScheduleEvent(const AtomicString& event_name) {
+void MediaSourceImpl::ScheduleEvent(const AtomicString& event_name) {
DCHECK(async_event_queue_);
Event* event = Event::Create(event_name);
@@ -923,7 +932,7 @@ void MediaSource::ScheduleEvent(const AtomicString& event_name) {
async_event_queue_->EnqueueEvent(FROM_HERE, *event);
}
-URLRegistry& MediaSource::Registry() const {
+URLRegistry& MediaSourceImpl::Registry() const {
return MediaSourceRegistry::Registry();
}
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/media_source.h b/chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.h
index de8973e436c..af950d136c8 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/media_source.h
+++ b/chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.h
@@ -28,16 +28,16 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASOURCE_MEDIA_SOURCE_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASOURCE_MEDIA_SOURCE_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASOURCE_MEDIA_SOURCE_IMPL_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASOURCE_MEDIA_SOURCE_IMPL_H_
#include <memory>
#include "third_party/blink/public/platform/web_media_source.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/fileapi/url_registry.h"
-#include "third_party/blink/renderer/core/html/media/html_media_source.h"
+#include "third_party/blink/renderer/core/html/media/media_source.h"
#include "third_party/blink/renderer/core/html/time_ranges.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/mediasource/source_buffer.h"
@@ -50,22 +50,22 @@ class EventQueue;
class ExceptionState;
class WebSourceBuffer;
-class MediaSource final : public EventTargetWithInlineData,
- public HTMLMediaSource,
- public ActiveScriptWrappable<MediaSource>,
- public ContextLifecycleObserver {
+class MediaSourceImpl final : public EventTargetWithInlineData,
+ public MediaSource,
+ public ActiveScriptWrappable<MediaSourceImpl>,
+ public ExecutionContextLifecycleObserver {
DEFINE_WRAPPERTYPEINFO();
- USING_GARBAGE_COLLECTED_MIXIN(MediaSource);
+ USING_GARBAGE_COLLECTED_MIXIN(MediaSourceImpl);
public:
static const AtomicString& OpenKeyword();
static const AtomicString& ClosedKeyword();
static const AtomicString& EndedKeyword();
- static MediaSource* Create(ExecutionContext*);
+ static MediaSourceImpl* Create(ExecutionContext*);
- explicit MediaSource(ExecutionContext*);
- ~MediaSource() override;
+ explicit MediaSourceImpl(ExecutionContext*);
+ ~MediaSourceImpl() override;
static void LogAndThrowDOMException(ExceptionState&,
DOMExceptionCode error,
@@ -93,9 +93,10 @@ class MediaSource final : public EventTargetWithInlineData,
static bool isTypeSupported(const String& type);
- // HTMLMediaSource
- bool AttachToElement(HTMLMediaElement*) override;
- void SetWebMediaSourceAndOpen(std::unique_ptr<WebMediaSource>) override;
+ // html/media/MediaSource interface implementation
+ bool StartAttachingToMediaElement(HTMLMediaElement*) override;
+ void CompleteAttachingToMediaElement(
+ std::unique_ptr<WebMediaSource>) override;
void Close() override;
bool IsClosed() const override;
double duration() const override;
@@ -111,8 +112,8 @@ class MediaSource final : public EventTargetWithInlineData,
// ScriptWrappable
bool HasPendingActivity() const final;
- // ContextLifecycleObserver interface
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver interface
+ void ContextDestroyed() override;
// URLRegistrable interface
URLRegistry& Registry() const override;
@@ -128,7 +129,7 @@ class MediaSource final : public EventTargetWithInlineData,
void AddedToRegistry();
void RemovedFromRegistry();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void SetReadyState(const AtomicString&);
@@ -152,8 +153,8 @@ class MediaSource final : public EventTargetWithInlineData,
// Here, using Member, instead of Member, to keep
// |attached_element_|, |source_buffers_|, |active_source_buffers_|, and their
// wrappers from being collected if we are alive or traceable from a GC root.
- // Activity by this MediaSource or on references to objects returned by
- // exercising this MediaSource (such as an app manipulating a SourceBuffer
+ // Activity by this MediaSourceImpl or on references to objects returned by
+ // exercising this MediaSourceImpl (such as an app manipulating a SourceBuffer
// retrieved via activeSourceBuffers()) may cause events to be dispatched by
// these other objects.
Member<HTMLMediaElement> attached_element_;
@@ -167,4 +168,4 @@ class MediaSource final : public EventTargetWithInlineData,
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASOURCE_MEDIA_SOURCE_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASOURCE_MEDIA_SOURCE_IMPL_H_
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/media_source_registry.cc b/chromium/third_party/blink/renderer/modules/mediasource/media_source_registry.cc
index 62a3c7b4742..fb3386b5fcc 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/media_source_registry.cc
+++ b/chromium/third_party/blink/renderer/modules/mediasource/media_source_registry.cc
@@ -30,7 +30,7 @@
#include "third_party/blink/renderer/modules/mediasource/media_source_registry.h"
-#include "third_party/blink/renderer/modules/mediasource/media_source.h"
+#include "third_party/blink/renderer/modules/mediasource/media_source_impl.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
namespace blink {
@@ -47,19 +47,19 @@ void MediaSourceRegistry::RegisterURL(SecurityOrigin*,
DCHECK_EQ(&registrable->Registry(), this);
DCHECK(IsMainThread());
- MediaSource* source = static_cast<MediaSource*>(registrable);
+ MediaSourceImpl* source = static_cast<MediaSourceImpl*>(registrable);
source->AddedToRegistry();
media_sources_->Set(url.GetString(), source);
}
void MediaSourceRegistry::UnregisterURL(const KURL& url) {
DCHECK(IsMainThread());
- HeapHashMap<String, Member<MediaSource>>::iterator iter =
+ HeapHashMap<String, Member<MediaSourceImpl>>::iterator iter =
media_sources_->find(url.GetString());
if (iter == media_sources_->end())
return;
- MediaSource* source = iter->value;
+ MediaSourceImpl* source = iter->value;
media_sources_->erase(iter);
source->RemovedFromRegistry();
}
@@ -70,9 +70,9 @@ URLRegistrable* MediaSourceRegistry::Lookup(const String& url) {
}
MediaSourceRegistry::MediaSourceRegistry()
- : media_sources_(
- MakeGarbageCollected<HeapHashMap<String, Member<MediaSource>>>()) {
- HTMLMediaSource::SetRegistry(this);
+ : media_sources_(MakeGarbageCollected<
+ HeapHashMap<String, Member<MediaSourceImpl>>>()) {
+ MediaSource::SetRegistry(this);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/media_source_registry.h b/chromium/third_party/blink/renderer/modules/mediasource/media_source_registry.h
index 84b1ec57e34..db254c0a86f 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/media_source_registry.h
+++ b/chromium/third_party/blink/renderer/modules/mediasource/media_source_registry.h
@@ -41,7 +41,7 @@
namespace blink {
class KURL;
-class MediaSource;
+class MediaSourceImpl;
class MediaSourceRegistry final : public URLRegistry {
public:
@@ -55,7 +55,7 @@ class MediaSourceRegistry final : public URLRegistry {
private:
MediaSourceRegistry();
- Persistent<HeapHashMap<String, Member<MediaSource>>> media_sources_;
+ Persistent<HeapHashMap<String, Member<MediaSourceImpl>>> media_sources_;
};
} // namespace blink
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 9e0ad25e9d1..623bf778981 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.cc
+++ b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.cc
@@ -50,7 +50,7 @@
#include "third_party/blink/renderer/core/html/track/video_track_list.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/mediasource/media_source.h"
+#include "third_party/blink/renderer/modules/mediasource/media_source_impl.h"
#include "third_party/blink/renderer/modules/mediasource/source_buffer_track_base_supplement.h"
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -72,13 +72,13 @@ static bool ThrowExceptionIfRemovedOrUpdating(bool is_removed,
bool is_updating,
ExceptionState& exception_state) {
if (is_removed) {
- MediaSource::LogAndThrowDOMException(
+ MediaSourceImpl::LogAndThrowDOMException(
exception_state, DOMExceptionCode::kInvalidStateError,
"This SourceBuffer has been removed from the parent media source.");
return true;
}
if (is_updating) {
- MediaSource::LogAndThrowDOMException(
+ MediaSourceImpl::LogAndThrowDOMException(
exception_state, DOMExceptionCode::kInvalidStateError,
"This SourceBuffer is still processing an 'appendBuffer' or "
"'remove' operation.");
@@ -104,18 +104,10 @@ WTF::String WebTimeRangesToString(const WebTimeRanges& ranges) {
} // namespace
-SourceBuffer* SourceBuffer::Create(
- std::unique_ptr<WebSourceBuffer> web_source_buffer,
- MediaSource* source,
- EventQueue* async_event_queue) {
- return MakeGarbageCollected<SourceBuffer>(std::move(web_source_buffer),
- source, async_event_queue);
-}
-
SourceBuffer::SourceBuffer(std::unique_ptr<WebSourceBuffer> web_source_buffer,
- MediaSource* source,
+ MediaSourceImpl* source,
EventQueue* async_event_queue)
- : ContextLifecycleObserver(source->GetExecutionContext()),
+ : ExecutionContextLifecycleObserver(source->GetExecutionContext()),
web_source_buffer_(std::move(web_source_buffer)),
source_(source),
track_defaults_(MakeGarbageCollected<TrackDefaultList>()),
@@ -181,7 +173,7 @@ void SourceBuffer::setMode(const AtomicString& new_mode,
// then throw a TypeError exception and abort these steps.
if (web_source_buffer_->GetGenerateTimestampsFlag() &&
new_mode == SegmentsKeyword()) {
- MediaSource::LogAndThrowTypeError(
+ MediaSourceImpl::LogAndThrowTypeError(
exception_state, "The mode value provided (" + SegmentsKeyword() +
") is invalid for a byte stream format that uses "
"generated timestamps.");
@@ -204,11 +196,10 @@ void SourceBuffer::setMode(const AtomicString& new_mode,
if (new_mode == SequenceKeyword())
append_mode = WebSourceBuffer::kAppendModeSequence;
if (!web_source_buffer_->SetMode(append_mode)) {
- MediaSource::LogAndThrowDOMException(exception_state,
- DOMExceptionCode::kInvalidStateError,
- "The mode may not be set while the "
- "SourceBuffer's append state is "
- "'PARSING_MEDIA_SEGMENT'.");
+ MediaSourceImpl::LogAndThrowDOMException(
+ exception_state, DOMExceptionCode::kInvalidStateError,
+ "The mode may not be set while the SourceBuffer's append state is "
+ "'PARSING_MEDIA_SEGMENT'.");
return;
}
@@ -222,7 +213,7 @@ TimeRanges* SourceBuffer::buffered(ExceptionState& exception_state) const {
// parent media source then throw an InvalidStateError exception and abort
// these steps.
if (IsRemoved()) {
- MediaSource::LogAndThrowDOMException(
+ MediaSourceImpl::LogAndThrowDOMException(
exception_state, DOMExceptionCode::kInvalidStateError,
"This SourceBuffer has been removed from the parent media source.");
return nullptr;
@@ -269,11 +260,10 @@ void SourceBuffer::setTimestampOffset(double offset,
// 6. If the mode attribute equals "sequence", then set the group start
// timestamp to new timestamp offset.
if (!web_source_buffer_->SetTimestampOffset(offset)) {
- MediaSource::LogAndThrowDOMException(exception_state,
- DOMExceptionCode::kInvalidStateError,
- "The timestamp offset may not be set "
- "while the SourceBuffer's append "
- "state is 'PARSING_MEDIA_SEGMENT'.");
+ MediaSourceImpl::LogAndThrowDOMException(
+ exception_state, DOMExceptionCode::kInvalidStateError,
+ "The timestamp offset may not be set while the SourceBuffer's append "
+ "state is 'PARSING_MEDIA_SEGMENT'.");
return;
}
@@ -312,7 +302,7 @@ void SourceBuffer::setAppendWindowStart(double start,
// 3. If the new value is less than 0 or greater than or equal to
// appendWindowEnd then throw a TypeError exception and abort these steps.
if (start < 0 || start >= append_window_end_) {
- MediaSource::LogAndThrowTypeError(
+ MediaSourceImpl::LogAndThrowTypeError(
exception_state,
ExceptionMessages::IndexOutsideRange(
"value", start, 0.0, ExceptionMessages::kExclusiveBound,
@@ -347,14 +337,14 @@ void SourceBuffer::setAppendWindowEnd(double end,
// 3. If the new value equals NaN, then throw a TypeError and abort these
// steps.
if (std::isnan(end)) {
- MediaSource::LogAndThrowTypeError(exception_state,
- ExceptionMessages::NotAFiniteNumber(end));
+ MediaSourceImpl::LogAndThrowTypeError(
+ exception_state, ExceptionMessages::NotAFiniteNumber(end));
return;
}
// 4. If the new value is less than or equal to appendWindowStart then throw a
// TypeError exception and abort these steps.
if (end <= append_window_start_) {
- MediaSource::LogAndThrowTypeError(
+ MediaSourceImpl::LogAndThrowTypeError(
exception_state, ExceptionMessages::IndexExceedsMinimumBound(
"value", end, append_window_start_));
return;
@@ -370,24 +360,24 @@ void SourceBuffer::appendBuffer(DOMArrayBuffer* data,
ExceptionState& exception_state) {
double media_time = GetMediaTime();
DVLOG(2) << __func__ << " this=" << this << " media_time=" << media_time
- << " size=" << data->DeprecatedByteLengthAsUnsigned();
+ << " size=" << data->ByteLengthAsSizeT();
// Section 3.2 appendBuffer()
// https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data
AppendBufferInternal(media_time,
static_cast<const unsigned char*>(data->Data()),
- data->DeprecatedByteLengthAsUnsigned(), exception_state);
+ data->ByteLengthAsSizeT(), exception_state);
}
void SourceBuffer::appendBuffer(NotShared<DOMArrayBufferView> data,
ExceptionState& exception_state) {
double media_time = GetMediaTime();
DVLOG(3) << __func__ << " this=" << this << " media_time=" << media_time
- << " size=" << data.View()->deprecatedByteLengthAsUnsigned();
+ << " size=" << data.View()->byteLengthAsSizeT();
// Section 3.2 appendBuffer()
// https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data
AppendBufferInternal(
media_time, static_cast<const unsigned char*>(data.View()->BaseAddress()),
- data.View()->deprecatedByteLengthAsUnsigned(), exception_state);
+ data.View()->byteLengthAsSizeT(), exception_state);
}
void SourceBuffer::abort(ExceptionState& exception_state) {
@@ -400,13 +390,13 @@ void SourceBuffer::abort(ExceptionState& exception_state) {
// "open" state then throw an InvalidStateError exception and abort these
// steps.
if (IsRemoved()) {
- MediaSource::LogAndThrowDOMException(
+ MediaSourceImpl::LogAndThrowDOMException(
exception_state, DOMExceptionCode::kInvalidStateError,
"This SourceBuffer has been removed from the parent media source.");
return;
}
if (!source_->IsOpen()) {
- MediaSource::LogAndThrowDOMException(
+ MediaSourceImpl::LogAndThrowDOMException(
exception_state, DOMExceptionCode::kInvalidStateError,
"The parent media source's readyState is not 'open'.");
return;
@@ -420,7 +410,7 @@ void SourceBuffer::abort(ExceptionState& exception_state) {
// is implemented behind the MediaSourceNewAbortAndDuration
// RuntimeEnabledFeature.
if (RuntimeEnabledFeatures::MediaSourceNewAbortAndDurationEnabled()) {
- MediaSource::LogAndThrowDOMException(
+ MediaSourceImpl::LogAndThrowDOMException(
exception_state, DOMExceptionCode::kInvalidStateError,
"Aborting asynchronous remove() operation is disallowed.");
return;
@@ -468,7 +458,7 @@ void SourceBuffer::remove(double start,
// exception and abort these steps.
if (start < 0 || std::isnan(source_->duration()) ||
start > source_->duration()) {
- MediaSource::LogAndThrowTypeError(
+ MediaSourceImpl::LogAndThrowTypeError(
exception_state,
ExceptionMessages::IndexOutsideRange(
"start", start, 0.0, ExceptionMessages::kExclusiveBound,
@@ -480,7 +470,7 @@ void SourceBuffer::remove(double start,
// 5. If end is less than or equal to start or end equals NaN, then throw a
// TypeError exception and abort these steps.
if (end <= start || std::isnan(end)) {
- MediaSource::LogAndThrowTypeError(
+ MediaSourceImpl::LogAndThrowTypeError(
exception_state,
"The end value provided (" + String::Number(end) +
") must be greater than the start value provided (" +
@@ -488,7 +478,8 @@ void SourceBuffer::remove(double start,
return;
}
- TRACE_EVENT_ASYNC_BEGIN0("media", "SourceBuffer::remove", this);
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("media", "SourceBuffer::remove",
+ TRACE_ID_LOCAL(this));
// 6. If the readyState attribute of the parent media source is in the "ended"
// state then run the following steps:
@@ -525,8 +516,8 @@ void SourceBuffer::changeType(const String& type,
// 1. If type is an empty string then throw a TypeError exception and abort
// these steps.
if (type.IsEmpty()) {
- MediaSource::LogAndThrowTypeError(exception_state,
- "The type provided is empty");
+ MediaSourceImpl::LogAndThrowTypeError(exception_state,
+ "The type provided is empty");
return;
}
@@ -550,9 +541,9 @@ void SourceBuffer::changeType(const String& type,
// here. As part of that, CanChangeType in Chromium should inherit relaxation
// of impl's StreamParserFactory (since it returns true iff a stream parser
// can be constructed with |type|). See https://crbug.com/535738.
- if (!MediaSource::isTypeSupported(type) ||
+ if (!MediaSourceImpl::isTypeSupported(type) ||
!web_source_buffer_->CanChangeType(content_type.GetType(), codecs)) {
- MediaSource::LogAndThrowDOMException(
+ MediaSourceImpl::LogAndThrowDOMException(
exception_state, DOMExceptionCode::kNotSupportedError,
"Changing to the type provided ('" + type + "') is not supported.");
return;
@@ -617,7 +608,8 @@ void SourceBuffer::CancelRemove() {
ScheduleEvent(event_type_names::kUpdateend);
}
- TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::remove", this);
+ TRACE_EVENT_NESTABLE_ASYNC_END0("media", "SourceBuffer::remove",
+ TRACE_ID_LOCAL(this));
}
void SourceBuffer::AbortIfUpdating() {
@@ -648,7 +640,8 @@ void SourceBuffer::AbortIfUpdating() {
// SourceBuffer object.
ScheduleEvent(event_type_names::kUpdateend);
- TRACE_EVENT_ASYNC_END0("media", trace_event_name, this);
+ TRACE_EVENT_NESTABLE_ASYNC_END0("media", trace_event_name,
+ TRACE_ID_LOCAL(this));
}
void SourceBuffer::RemovedFromMediaSource() {
@@ -1168,14 +1161,14 @@ bool SourceBuffer::HasPendingActivity() const {
(async_event_queue_ && async_event_queue_->HasPendingEvents());
}
-void SourceBuffer::ContextDestroyed(ExecutionContext*) {
+void SourceBuffer::ContextDestroyed() {
append_buffer_async_task_handle_.Cancel();
remove_async_task_handle_.Cancel();
updating_ = false;
}
ExecutionContext* SourceBuffer::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
const AtomicString& SourceBuffer::InterfaceName() const {
@@ -1198,7 +1191,8 @@ void SourceBuffer::ScheduleEvent(const AtomicString& event_name) {
bool SourceBuffer::PrepareAppend(double media_time,
size_t new_data_size,
ExceptionState& exception_state) {
- TRACE_EVENT_ASYNC_BEGIN0("media", "SourceBuffer::prepareAppend", this);
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("media", "SourceBuffer::prepareAppend",
+ TRACE_ID_LOCAL(this));
// http://w3c.github.io/media-source/#sourcebuffer-prepare-append
// 3.5.4 Prepare Append Algorithm
// 1. If the SourceBuffer has been removed from the sourceBuffers attribute of
@@ -1208,7 +1202,8 @@ bool SourceBuffer::PrepareAppend(double media_time,
// exception and abort these steps.
if (ThrowExceptionIfRemovedOrUpdating(IsRemoved(), updating_,
exception_state)) {
- TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::prepareAppend", this);
+ TRACE_EVENT_NESTABLE_ASYNC_END0("media", "SourceBuffer::prepareAppend",
+ TRACE_ID_LOCAL(this));
return false;
}
@@ -1217,10 +1212,11 @@ bool SourceBuffer::PrepareAppend(double media_time,
DCHECK(source_);
DCHECK(source_->MediaElement());
if (source_->MediaElement()->error()) {
- MediaSource::LogAndThrowDOMException(
+ MediaSourceImpl::LogAndThrowDOMException(
exception_state, DOMExceptionCode::kInvalidStateError,
"The HTMLMediaElement.error attribute is not null.");
- TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::prepareAppend", this);
+ TRACE_EVENT_NESTABLE_ASYNC_END0("media", "SourceBuffer::prepareAppend",
+ TRACE_ID_LOCAL(this));
return false;
}
@@ -1232,20 +1228,24 @@ bool SourceBuffer::PrepareAppend(double media_time,
source_->OpenIfInEndedState();
// 5. Run the coded frame eviction algorithm.
- if (!EvictCodedFrames(media_time, new_data_size)) {
+ if (!EvictCodedFrames(media_time, new_data_size) ||
+ !base::CheckedNumeric<wtf_size_t>(new_data_size).IsValid()) {
// 6. If the buffer full flag equals true, then throw a QUOTA_EXCEEDED_ERR
// exception and abort these steps.
+ // If the incoming data exceeds wtf_size_t::max, then our implementation
+ // cannot deal with it, so we also throw a QuotaExceededError.
DVLOG(3) << __func__ << " this=" << this << " -> throw QuotaExceededError";
- MediaSource::LogAndThrowDOMException(exception_state,
- DOMExceptionCode::kQuotaExceededError,
- "The SourceBuffer is full, and cannot "
- "free space to append additional "
- "buffers.");
- TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::prepareAppend", this);
+ MediaSourceImpl::LogAndThrowDOMException(
+ exception_state, DOMExceptionCode::kQuotaExceededError,
+ "The SourceBuffer is full, and cannot free space to append additional "
+ "buffers.");
+ TRACE_EVENT_NESTABLE_ASYNC_END0("media", "SourceBuffer::prepareAppend",
+ TRACE_ID_LOCAL(this));
return false;
}
- TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::prepareAppend", this);
+ TRACE_EVENT_NESTABLE_ASYNC_END0("media", "SourceBuffer::prepareAppend",
+ TRACE_ID_LOCAL(this));
return true;
}
@@ -1271,25 +1271,26 @@ bool SourceBuffer::EvictCodedFrames(double media_time, size_t new_data_size) {
void SourceBuffer::AppendBufferInternal(double media_time,
const unsigned char* data,
- unsigned size,
+ size_t size,
ExceptionState& exception_state) {
- TRACE_EVENT_ASYNC_BEGIN1("media", "SourceBuffer::appendBuffer", this, "size",
- size);
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("media", "SourceBuffer::appendBuffer",
+ TRACE_ID_LOCAL(this), "size", size);
// Section 3.2 appendBuffer()
// https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#widl-SourceBuffer-appendBuffer-void-ArrayBufferView-data
// 1. Run the prepare append algorithm.
if (!PrepareAppend(media_time, size, exception_state)) {
- TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendBuffer", this);
+ TRACE_EVENT_NESTABLE_ASYNC_END0("media", "SourceBuffer::appendBuffer",
+ TRACE_ID_LOCAL(this));
return;
}
- TRACE_EVENT_ASYNC_STEP_INTO0("media", "SourceBuffer::appendBuffer", this,
- "prepareAppend");
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("media", "prepareAppend",
+ TRACE_ID_LOCAL(this));
// 2. Add data to the end of the input buffer.
DCHECK(data || size == 0);
if (data)
- pending_append_data_.Append(data, size);
+ pending_append_data_.Append(data, base::checked_cast<wtf_size_t>(size));
pending_append_data_offset_ = 0;
// 3. Set the updating attribute to true.
@@ -1305,8 +1306,10 @@ void SourceBuffer::AppendBufferInternal(double media_time,
FROM_HERE,
WTF::Bind(&SourceBuffer::AppendBufferAsyncPart, WrapPersistent(this)));
- TRACE_EVENT_ASYNC_STEP_INTO0("media", "SourceBuffer::appendBuffer", this,
- "initialDelay");
+ TRACE_EVENT_NESTABLE_ASYNC_END0("media", "prepareAppend",
+ TRACE_ID_LOCAL(this));
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("media", "delay", TRACE_ID_LOCAL(this),
+ "type", "initialDelay");
}
void SourceBuffer::AppendBufferAsyncPart() {
@@ -1330,8 +1333,9 @@ void SourceBuffer::AppendBufferAsyncPart() {
if (append_size > kMaxAppendSize)
append_size = kMaxAppendSize;
- TRACE_EVENT_ASYNC_STEP_INTO1("media", "SourceBuffer::appendBuffer", this,
- "appending", "appendSize", append_size);
+ TRACE_EVENT_NESTABLE_ASYNC_END0("media", "delay", TRACE_ID_LOCAL(this));
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("media", "appending", TRACE_ID_LOCAL(this),
+ "appendSize", append_size);
// |zero| is used for 0 byte appends so we always have a valid pointer.
// We need to convey all appends, even 0 byte ones to |m_webSourceBuffer|
@@ -1357,8 +1361,10 @@ void SourceBuffer::AppendBufferAsyncPart() {
FROM_HERE,
WTF::Bind(&SourceBuffer::AppendBufferAsyncPart,
WrapPersistent(this)));
- TRACE_EVENT_ASYNC_STEP_INTO0("media", "SourceBuffer::appendBuffer", this,
- "nextPieceDelay");
+ TRACE_EVENT_NESTABLE_ASYNC_END0("media", "appending",
+ TRACE_ID_LOCAL(this));
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("media", "delay", TRACE_ID_LOCAL(this),
+ "type", "nextPieceDelay");
return;
}
@@ -1376,7 +1382,10 @@ void SourceBuffer::AppendBufferAsyncPart() {
ScheduleEvent(event_type_names::kUpdateend);
}
- TRACE_EVENT_ASYNC_END0("media", "SourceBuffer::appendBuffer", this);
+ TRACE_EVENT_NESTABLE_ASYNC_END0("media", "appending", TRACE_ID_LOCAL(this));
+ TRACE_EVENT_NESTABLE_ASYNC_END0("media", "SourceBuffer::appendBuffer",
+ TRACE_ID_LOCAL(this));
+
double media_time = GetMediaTime();
DVLOG(3) << __func__ << " done. this=" << this << " media_time=" << media_time
<< " buffered="
@@ -1433,14 +1442,14 @@ void SourceBuffer::AppendError() {
source_->EndOfStreamAlgorithm(WebMediaSource::kEndOfStreamStatusDecodeError);
}
-void SourceBuffer::Trace(blink::Visitor* visitor) {
+void SourceBuffer::Trace(Visitor* visitor) {
visitor->Trace(source_);
visitor->Trace(track_defaults_);
visitor->Trace(async_event_queue_);
visitor->Trace(audio_tracks_);
visitor->Trace(video_tracks_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 8b8319a4056..086fc82156e 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.h
+++ b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.h
@@ -34,7 +34,7 @@
#include <memory>
#include "third_party/blink/public/platform/web_source_buffer_client.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/mediasource/track_default_list.h"
@@ -49,27 +49,24 @@ class DOMArrayBuffer;
class DOMArrayBufferView;
class EventQueue;
class ExceptionState;
-class MediaSource;
+class MediaSourceImpl;
class TimeRanges;
class VideoTrackList;
class WebSourceBuffer;
class SourceBuffer final : public EventTargetWithInlineData,
public ActiveScriptWrappable<SourceBuffer>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public WebSourceBufferClient {
USING_GARBAGE_COLLECTED_MIXIN(SourceBuffer);
DEFINE_WRAPPERTYPEINFO();
USING_PRE_FINALIZER(SourceBuffer, Dispose);
public:
- static SourceBuffer* Create(std::unique_ptr<WebSourceBuffer>,
- MediaSource*,
- EventQueue*);
static const AtomicString& SegmentsKeyword();
static const AtomicString& SequenceKeyword();
- SourceBuffer(std::unique_ptr<WebSourceBuffer>, MediaSource*, EventQueue*);
+ SourceBuffer(std::unique_ptr<WebSourceBuffer>, MediaSourceImpl*, EventQueue*);
~SourceBuffer() override;
// SourceBuffer.idl methods
@@ -106,8 +103,8 @@ class SourceBuffer final : public EventTargetWithInlineData,
// ScriptWrappable
bool HasPendingActivity() const final;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
// EventTarget interface
ExecutionContext* GetExecutionContext() const override;
@@ -117,7 +114,7 @@ class SourceBuffer final : public EventTargetWithInlineData,
bool InitializationSegmentReceived(const WebVector<MediaTrackInfo>&) override;
void NotifyParseWarning(const ParseWarning) override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void Dispose();
@@ -129,7 +126,7 @@ class SourceBuffer final : public EventTargetWithInlineData,
bool EvictCodedFrames(double media_time, size_t new_data_size);
void AppendBufferInternal(double media_time,
const unsigned char*,
- unsigned,
+ size_t,
ExceptionState&);
void AppendBufferAsyncPart();
void AppendError();
@@ -164,7 +161,7 @@ class SourceBuffer final : public EventTargetWithInlineData,
// need to remain alive at least to successfully dispatch any events enqueued
// by the behavior of the HTMLME+MSE API. It makes those wrappers remain alive
// as long as this SourceBuffer's wrapper is alive.
- Member<MediaSource> source_;
+ Member<MediaSourceImpl> source_;
Member<TrackDefaultList> track_defaults_;
Member<EventQueue> async_event_queue_;
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 0e54d5306d2..fc8f39dd9c3 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
@@ -38,7 +38,7 @@ namespace blink {
SourceBufferList::SourceBufferList(ExecutionContext* context,
EventQueue* async_event_queue)
- : ContextClient(context), async_event_queue_(async_event_queue) {}
+ : ExecutionContextClient(context), async_event_queue_(async_event_queue) {}
SourceBufferList::~SourceBufferList() = default;
@@ -78,11 +78,11 @@ const AtomicString& SourceBufferList::InterfaceName() const {
return event_target_names::kSourceBufferList;
}
-void SourceBufferList::Trace(blink::Visitor* visitor) {
+void SourceBufferList::Trace(Visitor* visitor) {
visitor->Trace(async_event_queue_);
visitor->Trace(list_);
EventTargetWithInlineData::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 f32ac7856ef..f7c05134444 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
@@ -41,7 +41,7 @@ class EventQueue;
class SourceBuffer;
class SourceBufferList final : public EventTargetWithInlineData,
- public ContextClient {
+ public ExecutionContextClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(SourceBufferList);
@@ -70,10 +70,10 @@ class SourceBufferList final : public EventTargetWithInlineData,
// EventTarget interface
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override {
- return ContextClient::GetExecutionContext();
+ return ExecutionContextClient::GetExecutionContext();
}
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 268c82c4e8e..bc9f18752ac 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(blink::Visitor* visitor) {
+void SourceBufferTrackBaseSupplement::Trace(Visitor* visitor) {
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 8b30e0f7759..9f2ca92fa5b 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
static SourceBufferTrackBaseSupplement& From(TrackBase&);
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/track_default.idl b/chromium/third_party/blink/renderer/modules/mediasource/track_default.idl
index 8a8e11a9f46..29f943f85f3 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/track_default.idl
+++ b/chromium/third_party/blink/renderer/modules/mediasource/track_default.idl
@@ -8,10 +8,9 @@
enum TrackDefaultType { "audio", "video", "text" };
[
- Constructor(TrackDefaultType type, DOMString language, DOMString label, sequence<DOMString> kinds, optional DOMString byteStreamTrackID = ""),
- RaisesException=Constructor,
RuntimeEnabled=MediaSourceExperimental
] interface TrackDefault {
+ [RaisesException] constructor(TrackDefaultType type, DOMString language, DOMString label, sequence<DOMString> kinds, optional DOMString byteStreamTrackID = "");
readonly attribute TrackDefaultType type;
readonly attribute DOMString byteStreamTrackID;
readonly attribute DOMString language;
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 dd6a8289672..2c7dd45156d 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(blink::Visitor* visitor) {
+void TrackDefaultList::Trace(Visitor* visitor) {
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 7dd5f0f2ae6..fb727fa01a3 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
const HeapVector<Member<TrackDefault>> track_defaults_;
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/track_default_list.idl b/chromium/third_party/blink/renderer/modules/mediasource/track_default_list.idl
index 9ed51744043..380a9dcabae 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/track_default_list.idl
+++ b/chromium/third_party/blink/renderer/modules/mediasource/track_default_list.idl
@@ -6,10 +6,9 @@
// https://w3c.github.io/media-source/#trackdefaultlist
[
- Constructor(optional sequence<TrackDefault> trackDefaults = []),
- RaisesException=Constructor,
RuntimeEnabled=MediaSourceExperimental
] interface TrackDefaultList {
+ [RaisesException] constructor(optional sequence<TrackDefault> trackDefaults = []);
readonly attribute unsigned long length;
[ImplementedAs=item] getter TrackDefault (unsigned long index);
};
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/url_media_source.cc b/chromium/third_party/blink/renderer/modules/mediasource/url_media_source.cc
index f0e63eb52e5..8e41cffa2b4 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/url_media_source.cc
+++ b/chromium/third_party/blink/renderer/modules/mediasource/url_media_source.cc
@@ -33,16 +33,18 @@
#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/url/dom_url.h"
-#include "third_party/blink/renderer/modules/mediasource/media_source.h"
+#include "third_party/blink/renderer/modules/mediasource/media_source_impl.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
namespace blink {
+// static
String URLMediaSource::createObjectURL(ScriptState* script_state,
- MediaSource* source) {
- // Since WebWorkers cannot obtain MediaSource objects, we should be on the
- // main thread.
+ MediaSourceImpl* source) {
+ // Since WebWorkers cannot obtain MediaSource objects (yet), we should be on
+ // the main thread. TODO(wolenetz): Let DedicatedWorkers create MediaSource
+ // object URLs. See https://crbug.com/878133.
DCHECK(IsMainThread());
ExecutionContext* execution_context = ExecutionContext::From(script_state);
DCHECK(execution_context);
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/url_media_source.h b/chromium/third_party/blink/renderer/modules/mediasource/url_media_source.h
index 24d0f996490..2f2258853c2 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/url_media_source.h
+++ b/chromium/third_party/blink/renderer/modules/mediasource/url_media_source.h
@@ -36,14 +36,14 @@
namespace blink {
-class MediaSource;
+class MediaSourceImpl;
class ScriptState;
class URLMediaSource {
STATIC_ONLY(URLMediaSource);
public:
- static String createObjectURL(ScriptState*, MediaSource*);
+ static String createObjectURL(ScriptState*, MediaSourceImpl*);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/mediasource/video_playback_quality.idl b/chromium/third_party/blink/renderer/modules/mediasource/video_playback_quality.idl
index 2bd802bf335..17743bc17bf 100644
--- a/chromium/third_party/blink/renderer/modules/mediasource/video_playback_quality.idl
+++ b/chromium/third_party/blink/renderer/modules/mediasource/video_playback_quality.idl
@@ -33,5 +33,5 @@
readonly attribute DOMHighResTimeStamp creationTime;
readonly attribute unsigned long totalVideoFrames;
readonly attribute unsigned long droppedVideoFrames;
- readonly attribute unsigned long corruptedVideoFrames;
+ [Measure] readonly attribute unsigned long corruptedVideoFrames;
};
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn b/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn
index 5dde0a38d65..761ba49825b 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn
@@ -95,6 +95,7 @@ blink_modules_sources("mediastream") {
"webmediaplayer_ms_compositor.h",
]
deps = [
+ "//build:chromecast_buildflags",
"//media/capture/mojom:image_capture_blink",
"//media/webrtc",
]
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/DEPS b/chromium/third_party/blink/renderer/modules/mediastream/DEPS
index 6896804120a..fa70065c400 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/DEPS
+++ b/chromium/third_party/blink/renderer/modules/mediastream/DEPS
@@ -39,7 +39,6 @@ include_rules = [
"+media/webrtc/audio_processor_controls.h",
"+media/webrtc/helpers.h",
"+media/webrtc/webrtc_switches.h",
- "+mojo/public/cpp/bindings/binding.h",
"-third_party/blink/renderer/modules",
"+third_party/blink/renderer/modules/event_modules.h",
"+third_party/blink/renderer/modules/event_target_modules.h",
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 090771326b1..f7f6762041e 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
@@ -340,12 +340,12 @@ void ApplyConstraintsProcessor::CannotApplyConstraints(const String& message) {
}
void ApplyConstraintsProcessor::CleanupRequest(
- base::OnceClosure web_request_callback) {
+ base::OnceClosure user_media_request_callback) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(current_request_);
DCHECK(request_completed_cb_);
std::move(request_completed_cb_).Run();
- std::move(web_request_callback).Run();
+ std::move(user_media_request_callback).Run();
current_request_ = nullptr;
video_source_ = nullptr;
}
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 389d7e4dcf7..26ed5c8c207 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
@@ -75,7 +75,7 @@ class MODULES_EXPORT ApplyConstraintsProcessor final
void ApplyConstraintsSucceeded();
void ApplyConstraintsFailed(const char* failed_constraint_name);
void CannotApplyConstraints(const String& message);
- void CleanupRequest(base::OnceClosure web_request_callback);
+ void CleanupRequest(base::OnceClosure user_media_request_callback);
blink::mojom::blink::MediaDevicesDispatcherHost* GetMediaDevicesDispatcher();
// ApplyConstraints requests are processed sequentially. |current_request_|
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 0f685446243..7ae4f625641 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
@@ -13,7 +13,7 @@ namespace blink {
ApplyConstraintsRequest::ApplyConstraintsRequest(
const WebMediaStreamTrack& track,
- const WebMediaConstraints& constraints,
+ const MediaConstraints& constraints,
ScriptPromiseResolver* resolver)
: track_(track), constraints_(constraints), resolver_(resolver) {}
@@ -21,7 +21,7 @@ WebMediaStreamTrack ApplyConstraintsRequest::Track() const {
return track_;
}
-WebMediaConstraints ApplyConstraintsRequest::Constraints() const {
+MediaConstraints ApplyConstraintsRequest::Constraints() const {
return constraints_;
}
@@ -41,7 +41,7 @@ void ApplyConstraintsRequest::RequestFailed(const String& constraint,
track_.Reset();
}
-void ApplyConstraintsRequest::Trace(blink::Visitor* visitor) {
+void ApplyConstraintsRequest::Trace(Visitor* visitor) {
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 9986eea8933..aaeda6f6554 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_constraints.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"
namespace blink {
@@ -19,20 +19,20 @@ class MODULES_EXPORT ApplyConstraintsRequest final
: public GarbageCollected<ApplyConstraintsRequest> {
public:
ApplyConstraintsRequest(const WebMediaStreamTrack&,
- const WebMediaConstraints&,
+ const MediaConstraints&,
ScriptPromiseResolver*);
WebMediaStreamTrack Track() const;
- WebMediaConstraints Constraints() const;
+ MediaConstraints Constraints() const;
void RequestSucceeded();
void RequestFailed(const String& constraint, const String& message);
- virtual void Trace(blink::Visitor*);
+ virtual void Trace(Visitor*);
private:
WebMediaStreamTrack track_;
- WebMediaConstraints constraints_;
+ MediaConstraints constraints_;
Member<ScriptPromiseResolver> resolver_;
};
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/idls.gni b/chromium/third_party/blink/renderer/modules/mediastream/idls.gni
new file mode 100644
index 00000000000..fb73efded54
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/mediastream/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "input_device_info.idl",
+ "media_device_info.idl",
+ "media_devices.idl",
+ "media_stream.idl",
+ "media_stream_event.idl",
+ "media_stream_track.idl",
+ "media_stream_track_event.idl",
+ "overconstrained_error.idl",
+]
+
+modules_dictionary_idl_files = [
+ "constrain_boolean_parameters.idl",
+ "constrain_dom_string_parameters.idl",
+ "constrain_double_range.idl",
+ "constrain_long_range.idl",
+ "double_range.idl",
+ "long_range.idl",
+ "media_stream_constraints.idl",
+ "media_stream_event_init.idl",
+ "media_stream_track_event_init.idl",
+ "media_track_capabilities.idl",
+ "media_track_constraint_set.idl",
+ "media_track_constraints.idl",
+ "media_track_settings.idl",
+ "media_track_supported_constraints.idl",
+]
+
+modules_dependency_idl_files = [
+ "media_stream_track_content_hint.idl",
+ "navigator_media_stream.idl",
+ "navigator_user_media.idl",
+ "window_media_stream.idl",
+]
+
+modules_testing_dependency_idl_files = [ "testing/internals_media_stream.idl" ]
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/input_device_info.cc b/chromium/third_party/blink/renderer/modules/mediastream/input_device_info.cc
index 6feece2af4c..9ec87eb4449 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/input_device_info.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/input_device_info.cc
@@ -10,9 +10,9 @@
#include "media/base/sample_format.h"
#include "third_party/blink/public/mojom/mediastream/media_devices.mojom-blink.h"
#include "third_party/blink/public/platform/web_media_stream_track.h"
-#include "third_party/blink/renderer/modules/mediastream/double_range.h"
-#include "third_party/blink/renderer/modules/mediastream/long_range.h"
-#include "third_party/blink/renderer/modules/mediastream/media_track_capabilities.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_double_range.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_long_range.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_capabilities.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
#include "third_party/webrtc/modules/audio_processing/include/audio_processing.h"
@@ -23,21 +23,19 @@ namespace {
// TODO(c.padhi): Merge this method with ToWebFacingMode() in
// media_stream_constraints_util_video_device.h, see https://crbug.com/821668.
-WebMediaStreamTrack::FacingMode ToWebFacingMode(mojom::FacingMode facing_mode) {
+WebMediaStreamTrack::FacingMode ToWebFacingMode(
+ media::VideoFacingMode facing_mode) {
switch (facing_mode) {
- case mojom::FacingMode::NONE:
+ case media::MEDIA_VIDEO_FACING_NONE:
return WebMediaStreamTrack::FacingMode::kNone;
- case mojom::FacingMode::USER:
+ case media::MEDIA_VIDEO_FACING_USER:
return WebMediaStreamTrack::FacingMode::kUser;
- case mojom::FacingMode::ENVIRONMENT:
+ case media::MEDIA_VIDEO_FACING_ENVIRONMENT:
return WebMediaStreamTrack::FacingMode::kEnvironment;
- case mojom::FacingMode::LEFT:
- return WebMediaStreamTrack::FacingMode::kLeft;
- case mojom::FacingMode::RIGHT:
- return WebMediaStreamTrack::FacingMode::kRight;
+ default:
+ NOTREACHED();
+ return WebMediaStreamTrack::FacingMode::kNone;
}
- NOTREACHED();
- return WebMediaStreamTrack::FacingMode::kNone;
}
} // namespace
@@ -45,7 +43,7 @@ WebMediaStreamTrack::FacingMode ToWebFacingMode(mojom::FacingMode facing_mode) {
InputDeviceInfo::InputDeviceInfo(const String& device_id,
const String& label,
const String& group_id,
- MediaDeviceType device_type)
+ mojom::blink::MediaDeviceType device_type)
: MediaDeviceInfo(device_id, label, group_id, device_type) {}
void InputDeviceInfo::SetVideoInputCapabilities(
@@ -107,7 +105,7 @@ MediaTrackCapabilities* InputDeviceInfo::getCapabilities() const {
capabilities->setDeviceId(deviceId());
capabilities->setGroupId(groupId());
- if (DeviceType() == MediaDeviceType::MEDIA_AUDIO_INPUT) {
+ if (DeviceType() == mojom::blink::MediaDeviceType::MEDIA_AUDIO_INPUT) {
capabilities->setEchoCancellation({true, false});
capabilities->setAutoGainControl({true, false});
capabilities->setNoiseSuppression({true, false});
@@ -141,7 +139,7 @@ MediaTrackCapabilities* InputDeviceInfo::getCapabilities() const {
}
}
- if (DeviceType() == MediaDeviceType::MEDIA_VIDEO_INPUT) {
+ if (DeviceType() == mojom::blink::MediaDeviceType::MEDIA_VIDEO_INPUT) {
if (!platform_capabilities_.width.empty()) {
LongRange* width = LongRange::Create();
width->setMin(platform_capabilities_.width[0]);
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/input_device_info.h b/chromium/third_party/blink/renderer/modules/mediastream/input_device_info.h
index 9c73902bacb..39440d2716e 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/input_device_info.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/input_device_info.h
@@ -19,7 +19,7 @@ class InputDeviceInfo final : public MediaDeviceInfo {
InputDeviceInfo(const String& device_id,
const String& label,
const String& group_id,
- MediaDeviceType);
+ mojom::blink::MediaDeviceType);
void SetVideoInputCapabilities(mojom::blink::VideoInputDeviceCapabilitiesPtr);
void SetAudioInputCapabilities(mojom::blink::AudioInputDeviceCapabilitiesPtr);
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 048e9c7014e..27c3ffabc79 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
@@ -30,13 +30,15 @@
#include "third_party/blink/renderer/modules/mediastream/media_constraints_impl.h"
+#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/renderer/bindings/core/v8/array_value.h"
#include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_constraints.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/inspector/console_message.h"
-#include "third_party/blink/renderer/modules/mediastream/media_track_constraints.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/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
@@ -240,19 +242,16 @@ static bool Parse(const MediaTrackConstraints* constraints_in,
Vector<NameValueStringConstraint>& mandatory) {
Vector<NameValueStringConstraint> mandatory_constraints_vector;
if (constraints_in->hasMandatory()) {
- bool ok = ParseMandatoryConstraintsDictionary(constraints_in->mandatory(),
- mandatory);
+ bool ok = ParseMandatoryConstraintsDictionary(
+ Dictionary(constraints_in->mandatory()), mandatory);
if (!ok)
return false;
}
if (constraints_in->hasOptional()) {
- const Vector<Dictionary>& optional_constraints = constraints_in->optional();
-
- for (const auto& constraint : optional_constraints) {
- if (constraint.IsUndefinedOrNull())
- return false;
- bool ok = ParseOptionalConstraintsVectorElement(constraint, optional);
+ for (const auto& constraint : constraints_in->optional()) {
+ bool ok = ParseOptionalConstraintsVectorElement(Dictionary(constraint),
+ optional);
if (!ok)
return false;
}
@@ -270,7 +269,7 @@ static void ParseOldStyleNames(
ExecutionContext* context,
const Vector<NameValueStringConstraint>& old_names,
bool report_unknown_names,
- WebMediaTrackConstraintSet& result,
+ MediaTrackConstraintSetPlatform& result,
MediaErrorState& error_state) {
for (const NameValueStringConstraint& constraint : old_names) {
if (constraint.name_.Equals(kMinAspectRatio)) {
@@ -417,7 +416,7 @@ static void ParseOldStyleNames(
constraint.name_.Equals(kGoogTypingNoiseDetection)) {
// TODO(crbug.com/856176): Remove the kGoogBeamforming and
// kGoogArrayGeometry special cases.
- context->AddConsoleMessage(ConsoleMessage::Create(
+ context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kDeprecation,
mojom::ConsoleMessageLevel::kWarning,
"Obsolete constraint named " + String(constraint.name_) +
@@ -442,11 +441,11 @@ static void ParseOldStyleNames(
if (report_unknown_names) {
// TODO(hta): UMA stats for unknown constraints passed.
// https://crbug.com/576613
- context->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kDeprecation,
- mojom::ConsoleMessageLevel::kWarning,
- "Unknown constraint named " +
- String(constraint.name_) + " rejected"));
+ context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kDeprecation,
+ mojom::ConsoleMessageLevel::kWarning,
+ "Unknown constraint named " + String(constraint.name_) +
+ " rejected"));
// TODO(crbug.com/856176): Don't throw an error.
error_state.ThrowConstraintError("Unknown name of constraint detected",
constraint.name_);
@@ -455,22 +454,22 @@ static void ParseOldStyleNames(
}
}
-static WebMediaConstraints CreateFromNamedConstraints(
+static MediaConstraints CreateFromNamedConstraints(
ExecutionContext* context,
Vector<NameValueStringConstraint>& mandatory,
const Vector<NameValueStringConstraint>& optional,
MediaErrorState& error_state) {
- WebMediaTrackConstraintSet basic;
- WebMediaTrackConstraintSet advanced;
- WebMediaConstraints constraints;
+ MediaTrackConstraintSetPlatform basic;
+ MediaTrackConstraintSetPlatform advanced;
+ MediaConstraints constraints;
ParseOldStyleNames(context, mandatory, true, basic, error_state);
if (error_state.HadException())
return constraints;
// We ignore unknow names and syntax errors in optional constraints.
MediaErrorState ignored_error_state;
- Vector<WebMediaTrackConstraintSet> advanced_vector;
+ Vector<MediaTrackConstraintSetPlatform> advanced_vector;
for (const auto& optional_constraint : optional) {
- WebMediaTrackConstraintSet advanced_element;
+ MediaTrackConstraintSetPlatform advanced_element;
Vector<NameValueStringConstraint> element_as_list(1, optional_constraint);
ParseOldStyleNames(context, element_as_list, false, advanced_element,
ignored_error_state);
@@ -482,14 +481,14 @@ static WebMediaConstraints CreateFromNamedConstraints(
}
// Deprecated.
-WebMediaConstraints Create(ExecutionContext* context,
- const Dictionary& constraints_dictionary,
- MediaErrorState& error_state) {
+MediaConstraints Create(ExecutionContext* context,
+ const Dictionary& constraints_dictionary,
+ MediaErrorState& error_state) {
Vector<NameValueStringConstraint> optional;
Vector<NameValueStringConstraint> mandatory;
if (!Parse(constraints_dictionary, optional, mandatory)) {
error_state.ThrowTypeError("Malformed constraints object.");
- return WebMediaConstraints();
+ return MediaConstraints();
}
UseCounter::Count(context, WebFeature::kMediaStreamConstraintsFromDictionary);
return CreateFromNamedConstraints(context, mandatory, optional, error_state);
@@ -624,7 +623,7 @@ void CopyBooleanConstraint(
void CopyConstraintSet(const MediaTrackConstraintSet* constraints_in,
NakedValueDisposition naked_treatment,
- WebMediaTrackConstraintSet& constraint_buffer) {
+ MediaTrackConstraintSetPlatform& constraint_buffer) {
if (constraints_in->hasWidth()) {
CopyLongConstraint(constraints_in->width(), naked_treatment,
constraint_buffer.width);
@@ -691,16 +690,16 @@ void CopyConstraintSet(const MediaTrackConstraintSet* constraints_in,
}
}
-WebMediaConstraints ConvertConstraintsToWeb(
+MediaConstraints ConvertTrackConstraintsToMediaConstraints(
const MediaTrackConstraints* constraints_in) {
- WebMediaConstraints constraints;
- WebMediaTrackConstraintSet constraint_buffer;
- Vector<WebMediaTrackConstraintSet> advanced_buffer;
+ MediaConstraints constraints;
+ MediaTrackConstraintSetPlatform constraint_buffer;
+ Vector<MediaTrackConstraintSetPlatform> advanced_buffer;
CopyConstraintSet(constraints_in, NakedValueDisposition::kTreatAsIdeal,
constraint_buffer);
if (constraints_in->hasAdvanced()) {
for (const auto& element : constraints_in->advanced()) {
- WebMediaTrackConstraintSet advanced_element;
+ MediaTrackConstraintSetPlatform advanced_element;
CopyConstraintSet(element, NakedValueDisposition::kTreatAsExact,
advanced_element);
advanced_buffer.push_back(advanced_element);
@@ -710,23 +709,24 @@ WebMediaConstraints ConvertConstraintsToWeb(
return constraints;
}
-WebMediaConstraints Create(ExecutionContext* context,
- const MediaTrackConstraints* constraints_in,
- MediaErrorState& error_state) {
- WebMediaConstraints standard_form = ConvertConstraintsToWeb(constraints_in);
+MediaConstraints Create(ExecutionContext* context,
+ const MediaTrackConstraints* constraints_in,
+ MediaErrorState& error_state) {
+ MediaConstraints standard_form =
+ ConvertTrackConstraintsToMediaConstraints(constraints_in);
if (constraints_in->hasOptional() || constraints_in->hasMandatory()) {
if (!standard_form.IsEmpty()) {
UseCounter::Count(context, WebFeature::kMediaStreamConstraintsOldAndNew);
error_state.ThrowTypeError(
"Malformed constraint: Cannot use both optional/mandatory and "
"specific or advanced constraints.");
- return WebMediaConstraints();
+ return MediaConstraints();
}
Vector<NameValueStringConstraint> optional;
Vector<NameValueStringConstraint> mandatory;
if (!Parse(constraints_in, optional, mandatory)) {
error_state.ThrowTypeError("Malformed constraints object.");
- return WebMediaConstraints();
+ return MediaConstraints();
}
UseCounter::Count(context, WebFeature::kMediaStreamConstraintsNameValue);
return CreateFromNamedConstraints(context, mandatory, optional,
@@ -736,8 +736,8 @@ WebMediaConstraints Create(ExecutionContext* context,
return standard_form;
}
-WebMediaConstraints Create() {
- WebMediaConstraints constraints;
+MediaConstraints Create() {
+ MediaConstraints constraints;
constraints.Initialize();
return constraints;
}
@@ -885,7 +885,7 @@ BooleanOrConstrainBooleanParameters ConvertBoolean(
return output_union;
}
-void ConvertConstraintSet(const WebMediaTrackConstraintSet& input,
+void ConvertConstraintSet(const MediaTrackConstraintSetPlatform& input,
NakedValueDisposition naked_treatment,
MediaTrackConstraintSet* output) {
if (!input.width.IsEmpty())
@@ -931,7 +931,7 @@ void ConvertConstraintSet(const WebMediaTrackConstraintSet& input,
// https://crbug.com/605673
}
-MediaTrackConstraints* ConvertConstraints(const WebMediaConstraints& input) {
+MediaTrackConstraints* ConvertConstraints(const MediaConstraints& input) {
MediaTrackConstraints* output = MediaTrackConstraints::Create();
if (input.IsNull())
return output;
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_impl.h b/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_impl.h
index d5579338879..82ac3531ca1 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_impl.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_impl.h
@@ -31,9 +31,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_MEDIA_CONSTRAINTS_IMPL_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_MEDIA_CONSTRAINTS_IMPL_H_
-#include "third_party/blink/public/platform/web_media_constraints.h"
#include "third_party/blink/renderer/modules/mediastream/media_error_state.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -44,21 +44,19 @@ class MediaTrackConstraints;
namespace media_constraints_impl {
-WebMediaConstraints Create();
-WebMediaConstraints Create(ExecutionContext*,
- const Dictionary&,
- MediaErrorState&);
-WebMediaConstraints Create(ExecutionContext*,
- const MediaTrackConstraints*,
- MediaErrorState&);
+MediaConstraints Create();
+MediaConstraints Create(ExecutionContext*, const Dictionary&, MediaErrorState&);
+MediaConstraints Create(ExecutionContext*,
+ const MediaTrackConstraints*,
+ MediaErrorState&);
// Exported with MODULES_EXPORT for testing
MODULES_EXPORT MediaTrackConstraints* ConvertConstraints(
- const WebMediaConstraints& input);
+ const MediaConstraints& input);
// Exported for testing only.
-MODULES_EXPORT WebMediaConstraints
-ConvertConstraintsToWeb(const MediaTrackConstraints*);
+MODULES_EXPORT MediaConstraints
+ConvertTrackConstraintsToMediaConstraints(const MediaTrackConstraints*);
}
} // namespace blink
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 02c573a3c0d..b7b29c300cf 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
@@ -2,15 +2,15 @@
// 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/mediastream/media_constraints.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/web_media_constraints.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_constraints.h"
#include "third_party/blink/renderer/modules/mediastream/media_constraints_impl.h"
-#include "third_party/blink/renderer/modules/mediastream/media_track_constraints.h"
namespace blink {
// The MediaTrackConstraintsTest group tests the types declared in
-// WebKit/public/platform/WebMediaConstraints.h
+// third_party/blink/renderer/platform/mediastream/media_constraints.h
TEST(MediaTrackConstraintsTest, LongConstraint) {
LongConstraint range_constraint(nullptr);
range_constraint.SetMin(5);
@@ -64,7 +64,7 @@ TEST(MediaTrackConstraintsTest, BooleanConstraint) {
}
TEST(MediaTrackConstraintsTest, ConstraintSetEmpty) {
- WebMediaTrackConstraintSet the_set;
+ MediaTrackConstraintSetPlatform the_set;
EXPECT_TRUE(the_set.IsEmpty());
the_set.echo_cancellation.SetExact(false);
EXPECT_FALSE(the_set.IsEmpty());
@@ -77,8 +77,8 @@ TEST(MediaTrackConstraintsTest, ConstraintName) {
}
TEST(MediaTrackConstraintsTest, MandatoryChecks) {
- WebMediaTrackConstraintSet the_set;
- std::string found_name;
+ MediaTrackConstraintSetPlatform the_set;
+ String found_name;
EXPECT_FALSE(the_set.HasMandatory());
EXPECT_FALSE(the_set.HasMandatoryOutsideSet({"width"}, found_name));
EXPECT_FALSE(the_set.width.HasMandatory());
@@ -94,7 +94,7 @@ TEST(MediaTrackConstraintsTest, MandatoryChecks) {
}
TEST(MediaTrackConstraintsTest, SetToString) {
- WebMediaTrackConstraintSet the_set;
+ MediaTrackConstraintSetPlatform the_set;
EXPECT_EQ("", the_set.ToString());
the_set.width.SetMax(240);
EXPECT_EQ("width: {max: 240}", the_set.ToString().Utf8());
@@ -104,9 +104,9 @@ TEST(MediaTrackConstraintsTest, SetToString) {
}
TEST(MediaTrackConstraintsTest, ConstraintsToString) {
- WebMediaConstraints the_constraints;
- WebMediaTrackConstraintSet basic;
- WebVector<WebMediaTrackConstraintSet> advanced(static_cast<size_t>(1));
+ MediaConstraints the_constraints;
+ MediaTrackConstraintSetPlatform basic;
+ Vector<MediaTrackConstraintSetPlatform> advanced(static_cast<size_t>(1));
basic.width.SetMax(240);
advanced[0].echo_cancellation.SetExact(true);
the_constraints.Initialize(basic, advanced);
@@ -114,24 +114,24 @@ TEST(MediaTrackConstraintsTest, ConstraintsToString) {
"{width: {max: 240}, advanced: [{echoCancellation: {exact: true}}]}",
the_constraints.ToString().Utf8());
- WebMediaConstraints null_constraints;
+ MediaConstraints null_constraints;
EXPECT_EQ("", null_constraints.ToString().Utf8());
}
TEST(MediaTrackConstraintsTest, ConvertWebConstraintsBasic) {
- WebMediaConstraints input;
+ MediaConstraints input;
MediaTrackConstraints* output =
media_constraints_impl::ConvertConstraints(input);
ALLOW_UNUSED_LOCAL(output);
}
TEST(MediaTrackConstraintsTest, ConvertWebSingleStringConstraint) {
- WebMediaConstraints input;
+ MediaConstraints input;
- WebMediaTrackConstraintSet basic;
- WebVector<WebMediaTrackConstraintSet> advanced;
+ MediaTrackConstraintSetPlatform basic;
+ Vector<MediaTrackConstraintSetPlatform> advanced;
- basic.facing_mode.SetIdeal(WebVector<WebString>(&"foo", 1));
+ basic.facing_mode.SetIdeal(Vector<String>({"foo"}));
input.Initialize(basic, advanced);
MediaTrackConstraints* output =
media_constraints_impl::ConvertConstraints(input);
@@ -141,14 +141,14 @@ TEST(MediaTrackConstraintsTest, ConvertWebSingleStringConstraint) {
}
TEST(MediaTrackConstraintsTest, ConvertWebDoubleStringConstraint) {
- WebMediaConstraints input;
+ MediaConstraints input;
- WebVector<WebString> buffer(static_cast<size_t>(2u));
+ Vector<String> buffer(static_cast<size_t>(2u));
buffer[0] = "foo";
buffer[1] = "bar";
- WebMediaTrackConstraintSet basic;
- std::vector<WebMediaTrackConstraintSet> advanced;
+ MediaTrackConstraintSetPlatform basic;
+ Vector<MediaTrackConstraintSetPlatform> advanced;
basic.facing_mode.SetIdeal(buffer);
input.Initialize(basic, advanced);
@@ -163,11 +163,12 @@ TEST(MediaTrackConstraintsTest, ConvertWebDoubleStringConstraint) {
TEST(MediaTrackConstraintsTest, ConvertBlinkStringConstraint) {
MediaTrackConstraints* input = MediaTrackConstraints::Create();
- WebMediaConstraints output;
+ MediaConstraints output;
StringOrStringSequenceOrConstrainDOMStringParameters parameter;
parameter.SetString("foo");
input->setFacingMode(parameter);
- output = media_constraints_impl::ConvertConstraintsToWeb(input);
+ output =
+ media_constraints_impl::ConvertTrackConstraintsToMediaConstraints(input);
ASSERT_TRUE(output.Basic().facing_mode.HasIdeal());
ASSERT_EQ(1U, output.Basic().facing_mode.Ideal().size());
ASSERT_EQ("foo", output.Basic().facing_mode.Ideal()[0]);
@@ -175,7 +176,7 @@ TEST(MediaTrackConstraintsTest, ConvertBlinkStringConstraint) {
TEST(MediaTrackConstraintsTest, ConvertBlinkComplexStringConstraint) {
MediaTrackConstraints* input = MediaTrackConstraints::Create();
- WebMediaConstraints output;
+ MediaConstraints output;
StringOrStringSequenceOrConstrainDOMStringParameters parameter;
ConstrainDOMStringParameters* subparameter =
ConstrainDOMStringParameters::Create();
@@ -184,7 +185,8 @@ TEST(MediaTrackConstraintsTest, ConvertBlinkComplexStringConstraint) {
subparameter->setIdeal(inner_string);
parameter.SetConstrainDOMStringParameters(subparameter);
input->setFacingMode(parameter);
- output = media_constraints_impl::ConvertConstraintsToWeb(input);
+ output =
+ media_constraints_impl::ConvertTrackConstraintsToMediaConstraints(input);
ASSERT_TRUE(output.Basic().facing_mode.HasIdeal());
ASSERT_EQ(1U, output.Basic().facing_mode.Ideal().size());
ASSERT_EQ("foo", output.Basic().facing_mode.Ideal()[0]);
@@ -207,8 +209,8 @@ TEST(MediaTrackConstraintsTest, NakedIsExactInAdvanced) {
advanced[0]->setFacingMode(parameter);
input->setAdvanced(advanced);
- WebMediaConstraints output =
- media_constraints_impl::ConvertConstraintsToWeb(input);
+ MediaConstraints output =
+ media_constraints_impl::ConvertTrackConstraintsToMediaConstraints(input);
ASSERT_TRUE(output.Basic().facing_mode.HasIdeal());
ASSERT_FALSE(output.Basic().facing_mode.HasExact());
ASSERT_EQ(1U, output.Basic().facing_mode.Ideal().size());
@@ -221,18 +223,18 @@ TEST(MediaTrackConstraintsTest, NakedIsExactInAdvanced) {
}
TEST(MediaTrackConstraintsTest, IdealAndExactConvertToNaked) {
- WebMediaConstraints input;
- WebVector<WebString> buffer(static_cast<size_t>(1u));
+ MediaConstraints input;
+ Vector<String> buffer(static_cast<size_t>(1u));
- WebMediaTrackConstraintSet basic;
- WebMediaTrackConstraintSet advanced_element1;
- WebMediaTrackConstraintSet advanced_element2;
+ MediaTrackConstraintSetPlatform basic;
+ MediaTrackConstraintSetPlatform advanced_element1;
+ MediaTrackConstraintSetPlatform advanced_element2;
buffer[0] = "ideal";
basic.facing_mode.SetIdeal(buffer);
advanced_element1.facing_mode.SetIdeal(buffer);
buffer[0] = "exact";
advanced_element2.facing_mode.SetExact(buffer);
- std::vector<WebMediaTrackConstraintSet> advanced;
+ Vector<MediaTrackConstraintSetPlatform> advanced;
advanced.push_back(advanced_element1);
advanced.push_back(advanced_element2);
input.Initialize(basic, advanced);
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_device_info.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_device_info.cc
index fa1f3dd489f..51e67f5767a 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_device_info.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_device_info.cc
@@ -35,7 +35,7 @@ namespace blink {
MediaDeviceInfo::MediaDeviceInfo(const String& device_id,
const String& label,
const String& group_id,
- MediaDeviceType device_type)
+ mojom::blink::MediaDeviceType device_type)
: device_id_(device_id),
label_(label),
group_id_(group_id),
@@ -47,11 +47,11 @@ String MediaDeviceInfo::deviceId() const {
String MediaDeviceInfo::kind() const {
switch (device_type_) {
- case MediaDeviceType::MEDIA_AUDIO_INPUT:
+ case mojom::blink::MediaDeviceType::MEDIA_AUDIO_INPUT:
return "audioinput";
- case MediaDeviceType::MEDIA_AUDIO_OUTPUT:
+ case mojom::blink::MediaDeviceType::MEDIA_AUDIO_OUTPUT:
return "audiooutput";
- case MediaDeviceType::MEDIA_VIDEO_INPUT:
+ case mojom::blink::MediaDeviceType::MEDIA_VIDEO_INPUT:
return "videoinput";
default:
NOTREACHED();
@@ -67,7 +67,7 @@ String MediaDeviceInfo::groupId() const {
return group_id_;
}
-MediaDeviceType MediaDeviceInfo::DeviceType() const {
+mojom::blink::MediaDeviceType MediaDeviceInfo::DeviceType() const {
return device_type_;
}
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_device_info.h b/chromium/third_party/blink/renderer/modules/mediastream/media_device_info.h
index 4b47acf6150..4b2b3ba2a0c 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_device_info.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_device_info.h
@@ -32,8 +32,6 @@
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-using blink::mojom::blink::MediaDeviceType;
-
namespace blink {
class ScriptState;
@@ -46,14 +44,14 @@ class MODULES_EXPORT MediaDeviceInfo : public ScriptWrappable {
MediaDeviceInfo(const String& device_id,
const String& label,
const String& group_id,
- MediaDeviceType);
+ mojom::blink::MediaDeviceType);
String deviceId() const;
String kind() const;
String label() const;
String groupId() const;
- MediaDeviceType DeviceType() const;
+ mojom::blink::MediaDeviceType DeviceType() const;
ScriptValue toJSONForBinding(ScriptState*);
@@ -61,7 +59,7 @@ class MODULES_EXPORT MediaDeviceInfo : public ScriptWrappable {
String device_id_;
String label_;
String group_id_;
- MediaDeviceType device_type_;
+ mojom::blink::MediaDeviceType device_type_;
};
using MediaDeviceInfoVector = HeapVector<Member<MediaDeviceInfo>>;
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 fe48c57e455..1fc3e9ae1c5 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_devices.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_devices.cc
@@ -11,6 +11,8 @@
#include "third_party/blink/public/platform/task_type.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_media_stream_constraints.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_supported_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/events/event.h"
@@ -19,10 +21,9 @@
#include "third_party/blink/renderer/modules/mediastream/input_device_info.h"
#include "third_party/blink/renderer/modules/mediastream/media_error_state.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
-#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints.h"
-#include "third_party/blink/renderer/modules/mediastream/media_track_supported_constraints.h"
#include "third_party/blink/renderer/modules/mediastream/navigator_media_stream.h"
#include "third_party/blink/renderer/modules/mediastream/user_media_controller.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/heap/heap.h"
#include "third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.h"
@@ -47,7 +48,7 @@ class PromiseResolverCallbacks final : public UserMediaRequest::Callbacks {
resolver_->Reject(error);
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(resolver_);
UserMediaRequest::Callbacks::Trace(visitor);
}
@@ -59,19 +60,21 @@ class PromiseResolverCallbacks final : public UserMediaRequest::Callbacks {
} // namespace
MediaDevices::MediaDevices(ExecutionContext* context)
- : ContextLifecycleObserver(context), stopped_(false) {}
+ : ExecutionContextLifecycleObserver(context),
+ stopped_(false),
+ receiver_(this, context) {}
MediaDevices::~MediaDevices() = default;
-ScriptPromise MediaDevices::enumerateDevices(ScriptState* script_state) {
+ScriptPromise MediaDevices::enumerateDevices(ScriptState* script_state,
+ ExceptionState& exception_state) {
UpdateWebRTCMethodCount(RTCAPIName::kEnumerateDevices);
LocalFrame* frame =
- To<Document>(ExecutionContext::From(script_state))->GetFrame();
+ Document::From(ExecutionContext::From(script_state))->GetFrame();
if (!frame) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError,
- "Current frame is detached."));
+ exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
+ "Current frame is detached.");
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -95,32 +98,32 @@ ScriptPromise MediaDevices::getUserMedia(ScriptState* script_state,
const MediaStreamConstraints* options,
ExceptionState& exception_state) {
return SendUserMediaRequest(script_state,
- WebUserMediaRequest::MediaType::kUserMedia,
- options, exception_state);
+ UserMediaRequest::MediaType::kUserMedia, options,
+ exception_state);
}
ScriptPromise MediaDevices::SendUserMediaRequest(
ScriptState* script_state,
- WebUserMediaRequest::MediaType media_type,
+ UserMediaRequest::MediaType media_type,
const MediaStreamConstraints* options,
ExceptionState& exception_state) {
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
auto* callbacks = MakeGarbageCollected<PromiseResolverCallbacks>(resolver);
- Document* document = To<Document>(ExecutionContext::From(script_state));
+ Document* document = Document::From(ExecutionContext::From(script_state));
UserMediaController* user_media =
UserMediaController::From(document->GetFrame());
if (!user_media) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotSupportedError,
- "No media device controller available; is this a "
- "detached window?"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
+ "No media device controller available; "
+ "is this a detached window?");
+ return ScriptPromise();
}
MediaErrorState error_state;
- UserMediaRequest* request = UserMediaRequest::Create(
- document, user_media, media_type, options, callbacks, error_state);
+ UserMediaRequest* request =
+ UserMediaRequest::Create(document->ToExecutionContext(), user_media,
+ media_type, options, callbacks, error_state);
if (!request) {
DCHECK(error_state.HadException());
if (error_state.CanGenerateException()) {
@@ -134,9 +137,9 @@ ScriptPromise MediaDevices::SendUserMediaRequest(
String error_message;
if (!request->IsSecureContextUse(error_message)) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotSupportedError, error_message));
+ exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
+ error_message);
+ return ScriptPromise();
}
auto promise = resolver->Promise();
request->Start();
@@ -148,7 +151,7 @@ ScriptPromise MediaDevices::getDisplayMedia(
const MediaStreamConstraints* options,
ExceptionState& exception_state) {
return SendUserMediaRequest(script_state,
- WebUserMediaRequest::MediaType::kDisplayMedia,
+ UserMediaRequest::MediaType::kDisplayMedia,
options, exception_state);
}
@@ -157,7 +160,7 @@ const AtomicString& MediaDevices::InterfaceName() const {
}
ExecutionContext* MediaDevices::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
void MediaDevices::RemoveAllEventListeners() {
@@ -188,20 +191,19 @@ bool MediaDevices::HasPendingActivity() const {
return receiver_.is_bound();
}
-void MediaDevices::ContextDestroyed(ExecutionContext*) {
+void MediaDevices::ContextDestroyed() {
if (stopped_)
return;
stopped_ = true;
- StopObserving();
requests_.clear();
dispatcher_host_.reset();
}
void MediaDevices::OnDevicesChanged(
- mojom::blink::MediaDeviceType type,
- Vector<mojom::blink::MediaDeviceInfoPtr> device_infos) {
- Document* document = To<Document>(GetExecutionContext());
+ MediaDeviceType type,
+ const Vector<WebMediaDeviceInfo>& device_infos) {
+ Document* document = Document::From(GetExecutionContext());
DCHECK(document);
if (RuntimeEnabledFeatures::OnDeviceChangeEnabled())
@@ -237,14 +239,16 @@ void MediaDevices::StartObserving() {
if (receiver_.is_bound() || stopped_)
return;
- Document* document = To<Document>(GetExecutionContext());
+ Document* document = Document::From(GetExecutionContext());
if (!document || !document->GetFrame())
return;
GetDispatcherHost(document->GetFrame())
->AddMediaDevicesListener(true /* audio input */, true /* video input */,
true /* audio output */,
- receiver_.BindNewPipeAndPassRemote());
+ receiver_.BindNewPipeAndPassRemote(
+ GetExecutionContext()->GetTaskRunner(
+ TaskType::kMediaElementEvent)));
}
void MediaDevices::StopObserving() {
@@ -253,13 +257,9 @@ void MediaDevices::StopObserving() {
receiver_.reset();
}
-void MediaDevices::Dispose() {
- StopObserving();
-}
-
void MediaDevices::DevicesEnumerated(
ScriptPromiseResolver* resolver,
- Vector<Vector<mojom::blink::MediaDeviceInfoPtr>> enumeration,
+ const Vector<Vector<WebMediaDeviceInfo>>& enumeration,
Vector<mojom::blink::VideoInputDeviceCapabilitiesPtr>
video_input_capabilities,
Vector<mojom::blink::AudioInputDeviceCapabilitiesPtr>
@@ -299,14 +299,14 @@ void MediaDevices::DevicesEnumerated(
for (wtf_size_t j = 0; j < enumeration[i].size(); ++j) {
mojom::blink::MediaDeviceType device_type =
static_cast<mojom::blink::MediaDeviceType>(i);
- mojom::blink::MediaDeviceInfoPtr device_info =
- std::move(enumeration[i][j]);
+ WebMediaDeviceInfo device_info = enumeration[i][j];
if (device_type == mojom::blink::MediaDeviceType::MEDIA_AUDIO_INPUT ||
device_type == mojom::blink::MediaDeviceType::MEDIA_VIDEO_INPUT) {
InputDeviceInfo* input_device_info =
MakeGarbageCollected<InputDeviceInfo>(
- device_info->device_id, device_info->label,
- device_info->group_id, device_type);
+ String::FromUTF8(device_info.device_id),
+ String::FromUTF8(device_info.label),
+ String::FromUTF8(device_info.group_id), device_type);
if (device_type == mojom::blink::MediaDeviceType::MEDIA_VIDEO_INPUT &&
!video_input_capabilities.IsEmpty()) {
input_device_info->SetVideoInputCapabilities(
@@ -320,8 +320,9 @@ void MediaDevices::DevicesEnumerated(
media_devices.push_back(input_device_info);
} else {
media_devices.push_back(MakeGarbageCollected<MediaDeviceInfo>(
- device_info->device_id, device_info->label, device_info->group_id,
- device_type));
+ String::FromUTF8(device_info.device_id),
+ String::FromUTF8(device_info.label),
+ String::FromUTF8(device_info.group_id), device_type));
}
}
}
@@ -366,11 +367,12 @@ void MediaDevices::SetDispatcherHostForTesting(
WrapWeakPersistent(this)));
}
-void MediaDevices::Trace(blink::Visitor* visitor) {
+void MediaDevices::Trace(Visitor* visitor) {
+ visitor->Trace(receiver_);
visitor->Trace(scheduled_events_);
visitor->Trace(requests_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 63ccf33d220..4ebba1ade84 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_devices.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_devices.h
@@ -6,21 +6,22 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_MEDIA_DEVICES_H_
#include "base/callback.h"
-#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/mediastream/media_devices.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#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/mediastream/media_device_info.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/heap/heap_allocator.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
namespace blink {
+class ExceptionState;
class LocalFrame;
class MediaStreamConstraints;
class MediaTrackSupportedConstraints;
@@ -31,23 +32,22 @@ class ScriptState;
class MODULES_EXPORT MediaDevices final
: public EventTargetWithInlineData,
public ActiveScriptWrappable<MediaDevices>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public mojom::blink::MediaDevicesListener {
USING_GARBAGE_COLLECTED_MIXIN(MediaDevices);
DEFINE_WRAPPERTYPEINFO();
- USING_PRE_FINALIZER(MediaDevices, Dispose);
public:
explicit MediaDevices(ExecutionContext*);
~MediaDevices() override;
- ScriptPromise enumerateDevices(ScriptState*);
+ ScriptPromise enumerateDevices(ScriptState*, ExceptionState&);
MediaTrackSupportedConstraints* getSupportedConstraints() const;
ScriptPromise getUserMedia(ScriptState*,
const MediaStreamConstraints*,
ExceptionState&);
ScriptPromise SendUserMediaRequest(ScriptState*,
- WebUserMediaRequest::MediaType,
+ UserMediaRequest::MediaType,
const MediaStreamConstraints*,
ExceptionState&);
@@ -63,12 +63,12 @@ class MODULES_EXPORT MediaDevices final
// ScriptWrappable
bool HasPendingActivity() const override;
- // ContextLifecycleObserver overrides.
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver overrides.
+ void ContextDestroyed() override;
// mojom::blink::MediaDevicesListener implementation.
- void OnDevicesChanged(mojom::blink::MediaDeviceType,
- Vector<mojom::blink::MediaDeviceInfoPtr>) override;
+ void OnDevicesChanged(MediaDeviceType,
+ const Vector<WebMediaDeviceInfo>&) override;
// Callback for testing only.
using EnumerateDevicesTestCallback =
@@ -90,7 +90,7 @@ class MODULES_EXPORT MediaDevices final
device_change_test_callback_ = std::move(test_callback);
}
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
DEFINE_ATTRIBUTE_EVENT_LISTENER(devicechange, kDevicechange)
@@ -107,9 +107,8 @@ class MODULES_EXPORT MediaDevices final
void DispatchScheduledEvents();
void StartObserving();
void StopObserving();
- void Dispose();
void DevicesEnumerated(ScriptPromiseResolver*,
- Vector<Vector<mojom::blink::MediaDeviceInfoPtr>>,
+ const Vector<Vector<WebMediaDeviceInfo>>&,
Vector<mojom::blink::VideoInputDeviceCapabilitiesPtr>,
Vector<mojom::blink::AudioInputDeviceCapabilitiesPtr>);
void OnDispatcherHostConnectionError();
@@ -122,7 +121,7 @@ class MODULES_EXPORT MediaDevices final
TaskHandle dispatch_scheduled_events_task_handle_;
HeapVector<Member<Event>> scheduled_events_;
mojo::Remote<mojom::blink::MediaDevicesDispatcherHost> dispatcher_host_;
- mojo::Receiver<mojom::blink::MediaDevicesListener> receiver_{this};
+ HeapMojoReceiver<mojom::blink::MediaDevicesListener> receiver_;
HeapHashSet<Member<ScriptPromiseResolver>> requests_;
EnumerateDevicesTestCallback enumerate_devices_test_callback_;
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_devices.idl b/chromium/third_party/blink/renderer/modules/mediastream/media_devices.idl
index 51d7f54aa2f..4b5e20e564f 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_devices.idl
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_devices.idl
@@ -13,17 +13,19 @@
] interface MediaDevices : EventTarget {
[RuntimeEnabled=OnDeviceChange] attribute EventHandler ondevicechange;
[
- CallWith = ScriptState, HighEntropy, MeasureAs = MediaDevicesEnumerateDevices
+ CallWith = ScriptState, RaisesException, HighEntropy, MeasureAs = MediaDevicesEnumerateDevices
] Promise<sequence<MediaDeviceInfo>>
enumerateDevices();
MediaTrackSupportedConstraints getSupportedConstraints();
[
CallWith = ScriptState, RaisesException, MeasureAs = GetUserMediaPromise
] Promise<MediaStream>
- getUserMedia(optional MediaStreamConstraints constraints);
+ getUserMedia(optional MediaStreamConstraints constraints = {});
+
+ // https://w3c.github.io/mediacapture-screen-share/#dom-mediadevices-getdisplaymedia
[
RuntimeEnabled = GetDisplayMedia, CallWith = ScriptState, RaisesException,
MeasureAs = GetDisplayMedia
] Promise<MediaStream>
- getDisplayMedia(optional MediaStreamConstraints constraints);
+ getDisplayMedia(optional MediaStreamConstraints constraints = {});
};
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_devices_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_devices_test.cc
index 287276312cb..ae8656b91b7 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_devices_test.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_devices_test.cc
@@ -14,8 +14,8 @@
#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_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_stream_constraints.h"
#include "third_party/blink/renderer/core/testing/null_execution_context.h"
-#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints.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/wtf/functional.h"
@@ -43,73 +43,68 @@ class MockMediaDevicesDispatcherHost
bool request_video_input_capabilities,
bool request_audio_input_capabilities,
EnumerateDevicesCallback callback) override {
- Vector<Vector<MediaDeviceInfoPtr>> enumeration(static_cast<size_t>(
+ Vector<Vector<WebMediaDeviceInfo>> enumeration(static_cast<size_t>(
blink::mojom::blink::MediaDeviceType::NUM_MEDIA_DEVICE_TYPES));
Vector<mojom::blink::VideoInputDeviceCapabilitiesPtr>
video_input_capabilities;
Vector<mojom::blink::AudioInputDeviceCapabilitiesPtr>
audio_input_capabilities;
- MediaDeviceInfoPtr device_info;
+ WebMediaDeviceInfo device_info;
if (request_audio_input) {
- device_info = mojom::blink::MediaDeviceInfo::New();
- device_info->device_id = kFakeAudioInputDeviceId1;
- device_info->label = "Fake Audio Input 1";
- device_info->group_id = kFakeCommonGroupId1;
+ device_info.device_id = kFakeAudioInputDeviceId1;
+ device_info.label = "Fake Audio Input 1";
+ device_info.group_id = kFakeCommonGroupId1;
enumeration[static_cast<size_t>(
blink::mojom::blink::MediaDeviceType::MEDIA_AUDIO_INPUT)]
- .push_back(std::move(device_info));
+ .push_back(device_info);
- device_info = mojom::blink::MediaDeviceInfo::New();
- device_info->device_id = kFakeAudioInputDeviceId2;
- device_info->label = "Fake Audio Input 2";
- device_info->group_id = "fake_group 2";
+ device_info.device_id = kFakeAudioInputDeviceId2;
+ device_info.label = "Fake Audio Input 2";
+ device_info.group_id = "fake_group 2";
enumeration[static_cast<size_t>(
blink::mojom::blink::MediaDeviceType::MEDIA_AUDIO_INPUT)]
- .push_back(std::move(device_info));
+ .push_back(device_info);
// TODO(crbug.com/935960): add missing mocked capabilities and related
// tests when media::AudioParameters is visible in this context.
}
if (request_video_input) {
- device_info = mojom::blink::MediaDeviceInfo::New();
- device_info->device_id = kFakeVideoInputDeviceId1;
- device_info->label = "Fake Video Input 1";
- device_info->group_id = kFakeCommonGroupId1;
+ device_info.device_id = kFakeVideoInputDeviceId1;
+ device_info.label = "Fake Video Input 1";
+ device_info.group_id = kFakeCommonGroupId1;
enumeration[static_cast<size_t>(
blink::mojom::blink::MediaDeviceType::MEDIA_VIDEO_INPUT)]
- .push_back(std::move(device_info));
+ .push_back(device_info);
- device_info = mojom::blink::MediaDeviceInfo::New();
- device_info->device_id = kFakeVideoInputDeviceId2;
- device_info->label = "Fake Video Input 2";
- device_info->group_id = kFakeVideoInputGroupId2;
+ device_info.device_id = kFakeVideoInputDeviceId2;
+ device_info.label = "Fake Video Input 2";
+ device_info.group_id = kFakeVideoInputGroupId2;
enumeration[static_cast<size_t>(
blink::mojom::blink::MediaDeviceType::MEDIA_VIDEO_INPUT)]
- .push_back(std::move(device_info));
+ .push_back(device_info);
if (request_video_input_capabilities) {
mojom::blink::VideoInputDeviceCapabilitiesPtr capabilities =
mojom::blink::VideoInputDeviceCapabilities::New();
capabilities->device_id = kFakeVideoInputDeviceId1;
capabilities->group_id = kFakeCommonGroupId1;
- capabilities->facing_mode = blink::mojom::FacingMode::NONE;
+ capabilities->facing_mode = media::MEDIA_VIDEO_FACING_NONE;
video_input_capabilities.push_back(std::move(capabilities));
capabilities = mojom::blink::VideoInputDeviceCapabilities::New();
capabilities->device_id = kFakeVideoInputDeviceId2;
capabilities->group_id = kFakeVideoInputGroupId2;
- capabilities->facing_mode = blink::mojom::FacingMode::USER;
+ capabilities->facing_mode = media::MEDIA_VIDEO_FACING_USER;
video_input_capabilities.push_back(std::move(capabilities));
}
}
if (request_audio_output) {
- device_info = mojom::blink::MediaDeviceInfo::New();
- device_info->device_id = kFakeAudioOutputDeviceId1;
- device_info->label = "Fake Audio Input 1";
- device_info->group_id = kFakeCommonGroupId1;
+ device_info.device_id = kFakeAudioOutputDeviceId1;
+ device_info.label = "Fake Audio Input 1";
+ device_info.group_id = kFakeCommonGroupId1;
enumeration[static_cast<size_t>(
blink::mojom::blink::MediaDeviceType::MEDIA_AUDIO_OUTPUT)]
- .push_back(std::move(device_info));
+ .push_back(device_info);
}
std::move(callback).Run(std::move(enumeration),
std::move(video_input_capabilities),
@@ -163,57 +158,6 @@ class MockMediaDevicesDispatcherHost
mojo::Receiver<mojom::blink::MediaDevicesDispatcherHost> receiver_{this};
};
-class PromiseObserver {
- public:
- PromiseObserver(ScriptState* script_state, ScriptPromise promise)
- : is_rejected_(false), is_fulfilled_(false) {
- v8::Local<v8::Function> on_fulfilled = MyScriptFunction::CreateFunction(
- script_state, &is_fulfilled_, &saved_arg_);
- v8::Local<v8::Function> on_rejected = MyScriptFunction::CreateFunction(
- script_state, &is_rejected_, &saved_arg_);
- promise.Then(on_fulfilled, on_rejected);
- }
-
- bool isDecided() { return is_rejected_ || is_fulfilled_; }
-
- bool isFulfilled() { return is_fulfilled_; }
- bool isRejected() { return is_rejected_; }
- ScriptValue argument() { return saved_arg_; }
- void Trace(blink::Visitor* visitor) { visitor->Trace(saved_arg_); }
-
- private:
- class MyScriptFunction : public ScriptFunction {
- public:
- static v8::Local<v8::Function> CreateFunction(ScriptState* script_state,
- bool* flag_to_set,
- ScriptValue* arg_to_set) {
- MyScriptFunction* self = MakeGarbageCollected<MyScriptFunction>(
- script_state, flag_to_set, arg_to_set);
- return self->BindToV8Function();
- }
-
- MyScriptFunction(ScriptState* script_state,
- bool* flag_to_set,
- ScriptValue* arg_to_set)
- : ScriptFunction(script_state),
- flag_to_set_(flag_to_set),
- arg_to_set_(arg_to_set) {}
- ScriptValue Call(ScriptValue arg) override {
- *flag_to_set_ = true;
- *arg_to_set_ = arg;
- return arg;
- }
-
- private:
- bool* flag_to_set_;
- ScriptValue* arg_to_set_;
- };
-
- bool is_rejected_;
- bool is_fulfilled_;
- ScriptValue saved_arg_;
-};
-
class MediaDevicesTest : public testing::Test {
public:
using MediaDeviceInfos = HeapVector<Member<MediaDeviceInfo>>;
@@ -235,9 +179,8 @@ class MediaDevicesTest : public testing::Test {
void SimulateDeviceChange() {
DCHECK(listener());
- listener()->OnDevicesChanged(
- blink::mojom::blink::MediaDeviceType::MEDIA_AUDIO_INPUT,
- Vector<MediaDeviceInfoPtr>());
+ listener()->OnDevicesChanged(MEDIA_DEVICE_TYPE_AUDIO_INPUT,
+ Vector<WebMediaDeviceInfo>());
}
void DevicesEnumerated(const MediaDeviceInfoVector& device_infos) {
@@ -298,24 +241,13 @@ TEST_F(MediaDevicesTest, GetUserMediaCanBeCalled) {
GetMediaDevices(scope.GetExecutionContext())
->getUserMedia(scope.GetScriptState(), constraints,
scope.GetExceptionState());
- ASSERT_FALSE(promise.IsEmpty());
- PromiseObserver promise_observer(scope.GetScriptState(), promise);
- EXPECT_FALSE(promise_observer.isDecided());
- v8::MicrotasksScope::PerformCheckpoint(scope.GetIsolate());
- EXPECT_TRUE(promise_observer.isDecided());
+ ASSERT_TRUE(promise.IsEmpty());
// In the default test environment, we expect a DOM rejection because
// the script state's execution context's document's frame doesn't
// have an UserMediaController.
- EXPECT_TRUE(promise_observer.isRejected());
- // TODO(hta): Check that the correct error ("not supported") is returned.
- EXPECT_FALSE(promise_observer.argument().IsNull());
- // This log statement is included as a demonstration of how to get the string
- // value of the argument.
- VLOG(1) << "Argument is"
- << ToCoreString(promise_observer.argument()
- .V8Value()
- ->ToString(scope.GetContext())
- .ToLocalChecked());
+ DCHECK_EQ(scope.GetExceptionState().Code(),
+ ToExceptionCode(DOMExceptionCode::kNotSupportedError));
+ VLOG(1) << "Exception message is" << scope.GetExceptionState().Message();
}
TEST_F(MediaDevicesTest, EnumerateDevices) {
@@ -323,8 +255,8 @@ TEST_F(MediaDevicesTest, EnumerateDevices) {
auto* media_devices = GetMediaDevices(scope.GetExecutionContext());
media_devices->SetEnumerateDevicesCallbackForTesting(
WTF::Bind(&MediaDevicesTest::DevicesEnumerated, WTF::Unretained(this)));
- ScriptPromise promise =
- media_devices->enumerateDevices(scope.GetScriptState());
+ ScriptPromise promise = media_devices->enumerateDevices(
+ scope.GetScriptState(), scope.GetExceptionState());
platform()->RunUntilIdle();
ASSERT_FALSE(promise.IsEmpty());
@@ -385,8 +317,8 @@ TEST_F(MediaDevicesTest, EnumerateDevicesAfterConnectionError) {
CloseBinding();
platform()->RunUntilIdle();
- ScriptPromise promise =
- media_devices->enumerateDevices(scope.GetScriptState());
+ ScriptPromise promise = media_devices->enumerateDevices(
+ scope.GetScriptState(), scope.GetExceptionState());
platform()->RunUntilIdle();
ASSERT_FALSE(promise.IsEmpty());
EXPECT_TRUE(dispatcher_host_connection_error());
@@ -403,8 +335,8 @@ TEST_F(MediaDevicesTest, EnumerateDevicesBeforeConnectionError) {
WTF::Unretained(this)));
EXPECT_FALSE(dispatcher_host_connection_error());
- ScriptPromise promise =
- media_devices->enumerateDevices(scope.GetScriptState());
+ ScriptPromise promise = media_devices->enumerateDevices(
+ scope.GetScriptState(), scope.GetExceptionState());
platform()->RunUntilIdle();
ASSERT_FALSE(promise.IsEmpty());
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 1528fea1648..ae185e43611 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream.cc
@@ -56,11 +56,13 @@ MediaStream* MediaStream::Create(ExecutionContext* context) {
MediaStreamTrackVector audio_tracks;
MediaStreamTrackVector video_tracks;
+ DCHECK(context);
return MakeGarbageCollected<MediaStream>(context, audio_tracks, video_tracks);
}
MediaStream* MediaStream::Create(ExecutionContext* context,
MediaStream* stream) {
+ DCHECK(context);
DCHECK(stream);
MediaStreamTrackVector audio_tracks;
@@ -80,6 +82,7 @@ MediaStream* MediaStream::Create(ExecutionContext* context,
MediaStreamTrackVector audio_tracks;
MediaStreamTrackVector video_tracks;
+ DCHECK(context);
for (MediaStreamTrack* track : tracks) {
ProcessTrack(track, track->kind() == "audio" ? audio_tracks : video_tracks);
}
@@ -102,7 +105,7 @@ MediaStream* MediaStream::Create(ExecutionContext* context,
MediaStream::MediaStream(ExecutionContext* context,
MediaStreamDescriptor* stream_descriptor)
- : ContextClient(context),
+ : ExecutionContextClient(context),
descriptor_(stream_descriptor),
scheduled_event_timer_(
context->GetTaskRunner(TaskType::kMediaElementEvent),
@@ -113,8 +116,8 @@ MediaStream::MediaStream(ExecutionContext* context,
uint32_t number_of_audio_tracks = descriptor_->NumberOfAudioComponents();
audio_tracks_.ReserveCapacity(number_of_audio_tracks);
for (uint32_t i = 0; i < number_of_audio_tracks; i++) {
- MediaStreamTrack* new_track =
- MediaStreamTrack::Create(context, descriptor_->AudioComponent(i));
+ auto* new_track = MakeGarbageCollected<MediaStreamTrack>(
+ context, descriptor_->AudioComponent(i));
new_track->RegisterMediaStream(this);
audio_tracks_.push_back(new_track);
}
@@ -122,8 +125,8 @@ MediaStream::MediaStream(ExecutionContext* context,
uint32_t number_of_video_tracks = descriptor_->NumberOfVideoComponents();
video_tracks_.ReserveCapacity(number_of_video_tracks);
for (uint32_t i = 0; i < number_of_video_tracks; i++) {
- MediaStreamTrack* new_track =
- MediaStreamTrack::Create(context, descriptor_->VideoComponent(i));
+ auto* new_track = MakeGarbageCollected<MediaStreamTrack>(
+ context, descriptor_->VideoComponent(i));
new_track->RegisterMediaStream(this);
video_tracks_.push_back(new_track);
}
@@ -137,7 +140,7 @@ MediaStream::MediaStream(ExecutionContext* context,
MediaStreamDescriptor* stream_descriptor,
const MediaStreamTrackVector& audio_tracks,
const MediaStreamTrackVector& video_tracks)
- : ContextClient(context),
+ : ExecutionContextClient(context),
descriptor_(stream_descriptor),
scheduled_event_timer_(
context->GetTaskRunner(TaskType::kMediaElementEvent),
@@ -167,7 +170,7 @@ MediaStream::MediaStream(ExecutionContext* context,
MediaStream::MediaStream(ExecutionContext* context,
const MediaStreamTrackVector& audio_tracks,
const MediaStreamTrackVector& video_tracks)
- : ContextClient(context),
+ : ExecutionContextClient(context),
scheduled_event_timer_(
context->GetTaskRunner(TaskType::kMediaElementEvent),
this,
@@ -402,8 +405,8 @@ void MediaStream::AddTrackByComponentAndFireEvents(
DCHECK(component);
if (!GetExecutionContext())
return;
- MediaStreamTrack* track =
- MediaStreamTrack::Create(GetExecutionContext(), component);
+ auto* track =
+ MakeGarbageCollected<MediaStreamTrack>(GetExecutionContext(), component);
AddTrackAndFireEvents(track);
}
@@ -495,14 +498,14 @@ void MediaStream::ScheduledEventTimerFired(TimerBase*) {
events.clear();
}
-void MediaStream::Trace(blink::Visitor* visitor) {
+void MediaStream::Trace(Visitor* visitor) {
visitor->Trace(audio_tracks_);
visitor->Trace(video_tracks_);
visitor->Trace(descriptor_);
visitor->Trace(observers_);
visitor->Trace(scheduled_events_);
EventTargetWithInlineData::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
MediaStreamDescriptorClient::Trace(visitor);
}
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 136bffdc7c1..00ce4749510 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream.h
@@ -27,7 +27,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_MEDIA_STREAM_H_
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#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/mediastream/media_stream_track.h"
#include "third_party/blink/renderer/modules/modules_export.h"
@@ -49,12 +49,12 @@ class MODULES_EXPORT MediaStreamObserver : public GarbageCollectedMixin {
// Invoked when |MediaStream::removeTrack| is called.
virtual void OnStreamRemoveTrack(MediaStream*, MediaStreamTrack*) = 0;
- void Trace(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) override {}
};
class MODULES_EXPORT MediaStream final
: public EventTargetWithInlineData,
- public ContextClient,
+ public ExecutionContextClient,
public ActiveScriptWrappable<MediaStream>,
public MediaStreamDescriptorClient {
USING_GARBAGE_COLLECTED_MIXIN(MediaStream);
@@ -135,13 +135,13 @@ class MODULES_EXPORT MediaStream final
// EventTarget
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override {
- return ContextClient::GetExecutionContext();
+ return ExecutionContextClient::GetExecutionContext();
}
// ActiveScriptWrappable
bool HasPendingActivity() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
bool AddEventListenerInternal(
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream.idl b/chromium/third_party/blink/renderer/modules/mediastream/media_stream.idl
index 2650f43e33a..61beeab70bb 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream.idl
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream.idl
@@ -26,13 +26,14 @@
// https://w3c.github.io/mediacapture-main/#idl-def-mediastream
[
- Exposed=Window,
ActiveScriptWrappable,
- Constructor,
- Constructor(MediaStream stream),
- Constructor(sequence<MediaStreamTrack> tracks),
- ConstructorCallWith=ExecutionContext
+ Exposed=Window,
+ LegacyWindowAlias=webkitMediaStream,
+ LegacyWindowAlias_Measure
] interface MediaStream : EventTarget {
+ [CallWith=ExecutionContext] constructor();
+ [CallWith=ExecutionContext] constructor(MediaStream stream);
+ [CallWith=ExecutionContext] constructor(sequence<MediaStreamTrack> tracks);
readonly attribute DOMString id;
sequence<MediaStreamTrack> getAudioTracks();
sequence<MediaStreamTrack> getVideoTracks();
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_audio_processor.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_audio_processor.cc
index 390c5e16a28..ea44f0102b2 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_audio_processor.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_audio_processor.cc
@@ -21,6 +21,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
+#include "build/chromecast_buildflags.h"
#include "media/base/audio_fifo.h"
#include "media/base/audio_parameters.h"
#include "media/base/channel_layout.h"
@@ -367,8 +368,7 @@ void MediaStreamAudioProcessor::OnStartDump(base::File dump_file) {
} else {
// Post the file close to avoid blocking the main thread.
worker_pool::PostTask(
- FROM_HERE,
- {base::ThreadPool(), base::TaskPriority::LOWEST, base::MayBlock()},
+ FROM_HERE, {base::TaskPriority::LOWEST, base::MayBlock()},
CrossThreadBindOnce([](base::File) {}, std::move(dump_file)));
}
}
@@ -533,10 +533,10 @@ void MediaStreamAudioProcessor::InitializeAudioProcessingModule(
base::FeatureList::IsEnabled(features::kWebRtcHybridAgc);
config.Set<webrtc::ExperimentalAgc>(experimental_agc);
-#if defined(IS_CHROMECAST)
+#if BUILDFLAG(IS_CHROMECAST)
} else {
config.Set<webrtc::ExperimentalAgc>(new webrtc::ExperimentalAgc(false));
-#endif // defined(IS_CHROMECAST)
+#endif // BUILDFLAG(IS_CHROMECAST)
}
// Create and configure the webrtc::AudioProcessing.
@@ -619,12 +619,12 @@ void MediaStreamAudioProcessor::InitializeCaptureFifo(
// what format it would prefer.
const int output_sample_rate = audio_processing_
?
-#if defined(IS_CHROMECAST)
+#if BUILDFLAG(IS_CHROMECAST)
std::min(blink::kAudioProcessingSampleRate,
input_format.sample_rate())
#else
blink::kAudioProcessingSampleRate
-#endif // defined(IS_CHROMECAST)
+#endif // BUILDFLAG(IS_CHROMECAST)
: input_format.sample_rate();
media::ChannelLayout output_channel_layout;
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_audio_processor_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_audio_processor_test.cc
index 9b05c409690..a5a812af30e 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_audio_processor_test.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_audio_processor_test.cc
@@ -17,16 +17,17 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "build/build_config.h"
+#include "build/chromecast_buildflags.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_parameters.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/mediastream/media_stream_request.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
-#include "third_party/blink/public/platform/web_media_constraints.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_audio_processor.h"
#include "third_party/blink/renderer/modules/mediastream/mock_constraint_factory.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_processor_options.h"
#include "third_party/webrtc/api/media_stream_interface.h"
#include "third_party/webrtc/rtc_base/ref_counted_object.h"
@@ -241,10 +242,10 @@ TEST_F(MediaStreamAudioProcessorTest, MAYBE_TestAllSampleRates) {
32000,
44100,
48000
-#if defined(IS_CHROMECAST)
+#if BUILDFLAG(IS_CHROMECAST)
,
96000
-#endif // defined(IS_CHROMECAST)
+#endif // BUILDFLAG(IS_CHROMECAST)
};
for (size_t i = 0; i < base::size(kSupportedSampleRates); ++i) {
int buffer_size = kSupportedSampleRates[i] / 100;
@@ -255,11 +256,11 @@ TEST_F(MediaStreamAudioProcessorTest, MAYBE_TestAllSampleRates) {
VerifyDefaultComponents(audio_processor.get());
int expected_sample_rate =
-#if defined(IS_CHROMECAST)
+#if BUILDFLAG(IS_CHROMECAST)
std::min(kSupportedSampleRates[i], blink::kAudioProcessingSampleRate);
#else
blink::kAudioProcessingSampleRate;
-#endif // defined(IS_CHROMECAST)
+#endif // BUILDFLAG(IS_CHROMECAST)
ProcessDataAndVerifyFormat(audio_processor.get(), expected_sample_rate,
kAudioProcessingNumberOfChannel,
expected_sample_rate / 100);
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 1538c2f0b2a..fe29538cde1 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
@@ -18,7 +18,7 @@ namespace blink {
namespace {
template <typename P, typename T>
-bool ScanConstraintsForExactValue(const WebMediaConstraints& constraints,
+bool ScanConstraintsForExactValue(const MediaConstraints& constraints,
P picker,
T* value) {
if (constraints.IsNull())
@@ -40,7 +40,7 @@ bool ScanConstraintsForExactValue(const WebMediaConstraints& constraints,
}
template <typename P, typename T>
-bool ScanConstraintsForMaxValue(const WebMediaConstraints& constraints,
+bool ScanConstraintsForMaxValue(const MediaConstraints& constraints,
P picker,
T* value) {
if (constraints.IsNull())
@@ -69,7 +69,7 @@ bool ScanConstraintsForMaxValue(const WebMediaConstraints& constraints,
}
template <typename P, typename T>
-bool ScanConstraintsForMinValue(const WebMediaConstraints& constraints,
+bool ScanConstraintsForMinValue(const MediaConstraints& constraints,
P picker,
T* value) {
if (constraints.IsNull())
@@ -174,42 +174,42 @@ AudioCaptureSettings& AudioCaptureSettings::operator=(
AudioCaptureSettings&& other) = default;
bool GetConstraintValueAsBoolean(
- const WebMediaConstraints& constraints,
- const BooleanConstraint WebMediaTrackConstraintSet::*picker,
+ const MediaConstraints& constraints,
+ const BooleanConstraint MediaTrackConstraintSetPlatform::*picker,
bool* value) {
return ScanConstraintsForExactValue(constraints, picker, value);
}
bool GetConstraintValueAsInteger(
- const WebMediaConstraints& constraints,
- const LongConstraint WebMediaTrackConstraintSet::*picker,
+ const MediaConstraints& constraints,
+ const LongConstraint MediaTrackConstraintSetPlatform::*picker,
int* value) {
return ScanConstraintsForExactValue(constraints, picker, value);
}
bool GetConstraintMinAsInteger(
- const WebMediaConstraints& constraints,
- const LongConstraint WebMediaTrackConstraintSet::*picker,
+ const MediaConstraints& constraints,
+ const LongConstraint MediaTrackConstraintSetPlatform::*picker,
int* value) {
return ScanConstraintsForMinValue(constraints, picker, value);
}
bool GetConstraintMaxAsInteger(
- const WebMediaConstraints& constraints,
- const LongConstraint WebMediaTrackConstraintSet::*picker,
+ const MediaConstraints& constraints,
+ const LongConstraint MediaTrackConstraintSetPlatform::*picker,
int* value) {
return ScanConstraintsForMaxValue(constraints, picker, value);
}
bool GetConstraintValueAsDouble(
- const WebMediaConstraints& constraints,
- const DoubleConstraint WebMediaTrackConstraintSet::*picker,
+ const MediaConstraints& constraints,
+ const DoubleConstraint MediaTrackConstraintSetPlatform::*picker,
double* value) {
return ScanConstraintsForExactValue(constraints, picker, value);
}
VideoTrackAdapterSettings SelectVideoTrackAdapterSettings(
- const WebMediaTrackConstraintSet& basic_constraint_set,
+ const MediaTrackConstraintSetPlatform& basic_constraint_set,
const media_constraints::ResolutionSet& resolution_set,
const media_constraints::NumericRangeSet<double>& frame_rate_set,
const media::VideoCaptureFormat& source_format,
@@ -267,7 +267,9 @@ double StringConstraintFitnessDistance(const WebString& value,
return 0.0;
for (auto& ideal_value : constraint.Ideal()) {
- if (value == ideal_value)
+ // TODO(crbug.com/787254): Remove the explicit conversion to WebString when
+ // this method operates solely over WTF::String.
+ if (value == WebString(ideal_value))
return 0.0;
}
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 80afc2dad78..2424b7a8f45 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
@@ -9,11 +9,11 @@
#include "media/base/video_facing.h"
#include "media/capture/video_capture_types.h"
-#include "third_party/blink/public/platform/web_media_constraints.h"
#include "third_party/blink/public/platform/web_media_stream_source.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.h"
#include "third_party/blink/renderer/modules/mediastream/video_track_adapter_settings.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.h"
namespace blink {
@@ -240,34 +240,34 @@ class MODULES_EXPORT AudioCaptureSettings {
// Returns true if the constraint is specified in either mandatory or optional
// constraints.
MODULES_EXPORT bool GetConstraintValueAsBoolean(
- const blink::WebMediaConstraints& constraints,
- const blink::BooleanConstraint blink::WebMediaTrackConstraintSet::*picker,
+ const MediaConstraints& constraints,
+ const blink::BooleanConstraint MediaTrackConstraintSetPlatform::*picker,
bool* value);
// Method to get int value of constraint with |name| from constraints.
// Returns true if the constraint is specified in either mandatory or Optional
// constraints.
MODULES_EXPORT bool GetConstraintValueAsInteger(
- const blink::WebMediaConstraints& constraints,
- const blink::LongConstraint blink::WebMediaTrackConstraintSet::*picker,
+ const MediaConstraints& constraints,
+ const blink::LongConstraint MediaTrackConstraintSetPlatform::*picker,
int* value);
MODULES_EXPORT bool GetConstraintMinAsInteger(
- const blink::WebMediaConstraints& constraints,
- const blink::LongConstraint blink::WebMediaTrackConstraintSet::*picker,
+ const MediaConstraints& constraints,
+ const blink::LongConstraint MediaTrackConstraintSetPlatform::*picker,
int* value);
MODULES_EXPORT bool GetConstraintMaxAsInteger(
- const blink::WebMediaConstraints& constraints,
- const blink::LongConstraint blink::WebMediaTrackConstraintSet::*picker,
+ const MediaConstraints& constraints,
+ const blink::LongConstraint MediaTrackConstraintSetPlatform::*picker,
int* value);
// Method to get double precision value of constraint with |name| from
// constraints. Returns true if the constraint is specified in either mandatory
// or Optional constraints.
MODULES_EXPORT bool GetConstraintValueAsDouble(
- const blink::WebMediaConstraints& constraints,
- const blink::DoubleConstraint blink::WebMediaTrackConstraintSet::*picker,
+ const MediaConstraints& constraints,
+ const blink::DoubleConstraint MediaTrackConstraintSetPlatform::*picker,
double* value);
// This function selects track settings from a set of candidate resolutions and
@@ -296,7 +296,7 @@ MODULES_EXPORT bool GetConstraintValueAsDouble(
// This function has undefined behavior if any of |resolution_set| or
// |frame_rate_set| are empty.
MODULES_EXPORT VideoTrackAdapterSettings SelectVideoTrackAdapterSettings(
- const blink::WebMediaTrackConstraintSet& basic_constraint_set,
+ const MediaTrackConstraintSetPlatform& basic_constraint_set,
const media_constraints::ResolutionSet& resolution_set,
const media_constraints::NumericRangeSet<double>& frame_rate_set,
const media::VideoCaptureFormat& source_format,
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio.cc
index 089a03e674f..4b596f6db30 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio.cc
@@ -18,11 +18,11 @@
#include "media/base/limits.h"
#include "media/webrtc/webrtc_switches.h"
#include "third_party/blink/public/common/mediastream/media_stream_controls.h"
-#include "third_party/blink/public/platform/web_media_constraints.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/renderer/modules/mediastream/media_stream_constraints_util_sets.h"
#include "third_party/blink/renderer/modules/mediastream/processed_local_audio_source.h"
+#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_source.h"
@@ -32,7 +32,7 @@ namespace blink {
using blink::AudioCaptureSettings;
using blink::AudioProcessingProperties;
-using ConstraintSet = blink::WebMediaTrackConstraintSet;
+using ConstraintSet = MediaTrackConstraintSetPlatform;
using BooleanConstraint = blink::BooleanConstraint;
using EchoCancellationType = AudioProcessingProperties::EchoCancellationType;
using ProcessingType = AudioCaptureSettings::ProcessingType;
@@ -152,7 +152,7 @@ class SourceInfo {
// Container for each independent boolean constrainable property.
class BooleanContainer {
public:
- BooleanContainer(BoolSet allowed_values = BoolSet())
+ explicit BooleanContainer(BoolSet allowed_values = BoolSet())
: allowed_values_(std::move(allowed_values)) {}
const char* ApplyConstraintSet(const BooleanConstraint& constraint) {
@@ -204,7 +204,7 @@ class StringContainer {
std::string default_setting) const {
DCHECK(!IsEmpty());
if (constraint.HasIdeal()) {
- for (const blink::WebString& ideal_candidate : constraint.Ideal()) {
+ for (const WTF::String& ideal_candidate : constraint.Ideal()) {
std::string candidate = ideal_candidate.Utf8();
if (allowed_values_.Contains(candidate))
return std::make_tuple(1.0, candidate);
@@ -390,14 +390,15 @@ class EchoCancellationContainer {
GetDefaultValueForAudioProperties(echo_cancellation_constraint);
properties->goog_auto_gain_control &= default_audio_processing_value;
+ properties->goog_experimental_auto_gain_control &=
+ default_audio_processing_value;
+
properties->goog_experimental_echo_cancellation &=
default_audio_processing_value;
properties->goog_noise_suppression &= default_audio_processing_value;
properties->goog_experimental_noise_suppression &=
default_audio_processing_value;
properties->goog_highpass_filter &= default_audio_processing_value;
- properties->goog_experimental_auto_gain_control &=
- default_audio_processing_value;
}
bool GetDefaultValueForAudioProperties(
@@ -555,6 +556,61 @@ class EchoCancellationContainer {
bool is_device_capture_;
};
+class AutoGainControlContainer {
+ public:
+ explicit AutoGainControlContainer(BoolSet allowed_values = BoolSet())
+ : allowed_values_(std::move(allowed_values)) {}
+
+ const char* ApplyConstraintSet(const ConstraintSet& constraint_set) {
+ BoolSet agc_set = blink::media_constraints::BoolSetFromConstraint(
+ constraint_set.goog_auto_gain_control);
+ BoolSet experimentaL_agc_set =
+ blink::media_constraints::BoolSetFromConstraint(
+ constraint_set.goog_experimental_auto_gain_control);
+
+ // Apply autoGainControl/googAutoGainControl constraint.
+ allowed_values_ = allowed_values_.Intersection(agc_set);
+ if (IsEmpty())
+ return constraint_set.goog_auto_gain_control.GetName();
+ // Apply also googExperimentalAutoGainControl constraint.
+ allowed_values_ = allowed_values_.Intersection(experimentaL_agc_set);
+
+ return IsEmpty()
+ ? constraint_set.goog_experimental_auto_gain_control.GetName()
+ : nullptr;
+ }
+
+ std::tuple<double, bool> SelectSettingsAndScore(
+ const ConstraintSet& constraint_set,
+ bool default_setting) const {
+ BooleanConstraint agc_constraint = constraint_set.goog_auto_gain_control;
+ BooleanConstraint experimental_agc_constraint =
+ constraint_set.goog_experimental_auto_gain_control;
+
+ if (agc_constraint.HasIdeal() || experimental_agc_constraint.HasIdeal()) {
+ bool agc_ideal =
+ agc_constraint.HasIdeal() ? agc_constraint.Ideal() : false;
+ bool experimentaL_agc_ideal = experimental_agc_constraint.HasIdeal()
+ ? experimental_agc_constraint.Ideal()
+ : false;
+
+ bool combined_ideal = agc_ideal || experimentaL_agc_ideal;
+ if (allowed_values_.Contains(combined_ideal))
+ return std::make_tuple(1.0, combined_ideal);
+ }
+
+ if (allowed_values_.is_universal())
+ return std::make_tuple(0.0, default_setting);
+
+ return std::make_tuple(0.0, allowed_values_.FirstElement());
+ }
+
+ bool IsEmpty() const { return allowed_values_.IsEmpty(); }
+
+ private:
+ BoolSet allowed_values_;
+};
+
// This container represents the supported audio settings for a given type of
// audio source. In practice, there are three types of sources: processed using
// APM, processed without APM, and unprocessed.
@@ -569,13 +625,12 @@ class ProcessingBasedContainer {
ProcessingType::kApmProcessed,
{EchoCancellationType::kEchoCancellationAec3,
EchoCancellationType::kEchoCancellationDisabled},
+ BoolSet(), /* auto_gain_control_set */
BoolSet(), /* goog_audio_mirroring_set */
- BoolSet(), /* goog_auto_gain_control_set */
BoolSet(), /* goog_experimental_echo_cancellation_set */
BoolSet(), /* goog_noise_suppression_set */
BoolSet(), /* goog_experimental_noise_suppression_set */
BoolSet(), /* goog_highpass_filter_set */
- BoolSet(), /* goog_experimental_auto_gain_control_set */
IntRangeSet::FromValue(GetSampleSize()), /* sample_size_range */
IntRangeSet::FromValue(
device_parameters.channels()), /* channels_range */
@@ -599,13 +654,12 @@ class ProcessingBasedContainer {
ProcessingType::kApmProcessed,
{EchoCancellationType::kEchoCancellationAec3,
EchoCancellationType::kEchoCancellationDisabled},
+ BoolSet(), /* auto_gain_control_set */
BoolSet(), /* goog_audio_mirroring_set */
- BoolSet(), /* goog_auto_gain_control_set */
BoolSet(), /* goog_experimental_echo_cancellation_set */
BoolSet(), /* goog_noise_suppression_set */
BoolSet(), /* goog_experimental_noise_suppression_set */
BoolSet(), /* goog_highpass_filter_set */
- BoolSet(), /* goog_experimental_auto_gain_control_set */
IntRangeSet::FromValue(GetSampleSize()), /* sample_size_range */
IntRangeSet::FromValue(1), /* channels_range */
IntRangeSet::FromValue(
@@ -627,13 +681,12 @@ class ProcessingBasedContainer {
return ProcessingBasedContainer(
ProcessingType::kNoApmProcessed,
{EchoCancellationType::kEchoCancellationDisabled},
+ BoolSet({false}), /* auto_gain_control_set */
BoolSet(), /* goog_audio_mirroring_set */
- BoolSet({false}), /* goog_auto_gain_control_set */
BoolSet({false}), /* goog_experimental_echo_cancellation_set */
BoolSet({false}), /* goog_noise_suppression_set */
BoolSet({false}), /* goog_experimental_noise_suppression_set */
BoolSet({false}), /* goog_highpass_filter_set */
- BoolSet({false}), /* goog_experimental_auto_gain_control_set */
IntRangeSet::FromValue(GetSampleSize()), /* sample_size_range */
IntRangeSet::FromValue(
device_parameters.channels()), /* channels_range */
@@ -655,13 +708,12 @@ class ProcessingBasedContainer {
return ProcessingBasedContainer(
ProcessingType::kUnprocessed,
{EchoCancellationType::kEchoCancellationDisabled},
+ BoolSet({false}), /* auto_gain_control_set */
BoolSet({false}), /* goog_audio_mirroring_set */
- BoolSet({false}), /* goog_auto_gain_control_set */
BoolSet({false}), /* goog_experimental_echo_cancellation_set */
BoolSet({false}), /* goog_noise_suppression_set */
BoolSet({false}), /* goog_experimental_noise_suppression_set */
BoolSet({false}), /* goog_highpass_filter_set */
- BoolSet({false}), /* goog_experimental_auto_gain_control_set */
IntRangeSet::FromValue(GetSampleSize()), /* sample_size_range */
IntRangeSet::FromValue(
device_parameters.channels()), /* channels_range */
@@ -680,6 +732,11 @@ class ProcessingBasedContainer {
return failed_constraint_name;
failed_constraint_name =
+ auto_gain_control_container_.ApplyConstraintSet(constraint_set);
+ if (failed_constraint_name)
+ return failed_constraint_name;
+
+ failed_constraint_name =
sample_size_container_.ApplyConstraintSet(constraint_set.sample_size);
if (failed_constraint_name)
return failed_constraint_name;
@@ -767,6 +824,18 @@ class ProcessingBasedContainer {
echo_cancellation_container_.UpdateDefaultValues(
constraint_set.echo_cancellation, &properties);
+ std::tie(sub_score, properties.goog_auto_gain_control) =
+ auto_gain_control_container_.SelectSettingsAndScore(
+ constraint_set, properties.goog_auto_gain_control);
+ score += sub_score;
+ // Let goog_experimental_auto_gain_control match the value decided for
+ // goog_auto_gain_control.
+ // TODO(crbug.com/924485): entirely remove
+ // goog_experimental_auto_gain_control in the AudioProcessingProperties
+ // object since no longer needed.
+ properties.goog_experimental_auto_gain_control =
+ properties.goog_auto_gain_control;
+
for (size_t i = 0; i < kNumBooleanContainerIds; ++i) {
auto& info = kBooleanPropertyContainerInfoMap[i];
std::tie(sub_score, properties.*(info.property_member)) =
@@ -791,6 +860,7 @@ class ProcessingBasedContainer {
return true;
}
return echo_cancellation_container_.IsEmpty() ||
+ auto_gain_control_container_.IsEmpty() ||
sample_size_container_.IsEmpty() || channels_container_.IsEmpty() ||
sample_rate_container_.IsEmpty() || latency_container_.IsEmpty();
}
@@ -800,19 +870,17 @@ class ProcessingBasedContainer {
private:
enum BooleanContainerId {
kGoogAudioMirroring,
- kGoogAutoGainControl,
kGoogExperimentalEchoCancellation,
kGoogNoiseSuppression,
kGoogExperimentalNoiseSuppression,
kGoogHighpassFilter,
- kGoogExperimentalAutoGainControl,
kNumBooleanContainerIds
};
// This struct groups related fields or entries from
// AudioProcessingProperties,
// ProcessingBasedContainer::boolean_containers_, and
- // blink::WebMediaTrackConstraintSet.
+ // MediaTrackConstraintSetPlatform.
struct BooleanPropertyContainerInfo {
BooleanContainerId index;
BooleanConstraint ConstraintSet::*constraint_member;
@@ -823,8 +891,6 @@ class ProcessingBasedContainer {
kBooleanPropertyContainerInfoMap[] = {
{kGoogAudioMirroring, &ConstraintSet::goog_audio_mirroring,
&AudioProcessingProperties::goog_audio_mirroring},
- {kGoogAutoGainControl, &ConstraintSet::goog_auto_gain_control,
- &AudioProcessingProperties::goog_auto_gain_control},
{kGoogExperimentalEchoCancellation,
&ConstraintSet::goog_experimental_echo_cancellation,
&AudioProcessingProperties::goog_experimental_echo_cancellation},
@@ -834,10 +900,7 @@ class ProcessingBasedContainer {
&ConstraintSet::goog_experimental_noise_suppression,
&AudioProcessingProperties::goog_experimental_noise_suppression},
{kGoogHighpassFilter, &ConstraintSet::goog_highpass_filter,
- &AudioProcessingProperties::goog_highpass_filter},
- {kGoogExperimentalAutoGainControl,
- &ConstraintSet::goog_experimental_auto_gain_control,
- &AudioProcessingProperties::goog_experimental_auto_gain_control}};
+ &AudioProcessingProperties::goog_highpass_filter}};
// Private constructor intended to instantiate different variants of this
// class based on the initial values provided. The appropriate way to
@@ -848,13 +911,12 @@ class ProcessingBasedContainer {
ProcessingBasedContainer(
ProcessingType processing_type,
std::vector<EchoCancellationType> echo_cancellation_types,
+ BoolSet auto_gain_control_set,
BoolSet goog_audio_mirroring_set,
- BoolSet goog_auto_gain_control_set,
BoolSet goog_experimental_echo_cancellation_set,
BoolSet goog_noise_suppression_set,
BoolSet goog_experimental_noise_suppression_set,
BoolSet goog_highpass_filter_set,
- BoolSet goog_experimental_auto_gain_control_set,
IntRangeSet sample_size_range,
IntRangeSet channels_range,
IntRangeSet sample_rate_range,
@@ -881,10 +943,11 @@ class ProcessingBasedContainer {
is_device_capture, device_parameters, source_info.properties(),
is_reconfiguration_allowed);
+ auto_gain_control_container_ =
+ AutoGainControlContainer(auto_gain_control_set);
+
boolean_containers_[kGoogAudioMirroring] =
BooleanContainer(goog_audio_mirroring_set);
- boolean_containers_[kGoogAutoGainControl] =
- BooleanContainer(goog_auto_gain_control_set);
boolean_containers_[kGoogExperimentalEchoCancellation] =
BooleanContainer(goog_experimental_echo_cancellation_set);
boolean_containers_[kGoogNoiseSuppression] =
@@ -893,12 +956,13 @@ class ProcessingBasedContainer {
BooleanContainer(goog_experimental_noise_suppression_set);
boolean_containers_[kGoogHighpassFilter] =
BooleanContainer(goog_highpass_filter_set);
- boolean_containers_[kGoogExperimentalAutoGainControl] =
- BooleanContainer(goog_experimental_auto_gain_control_set);
if (!source_info.HasActiveSource())
return;
+ auto_gain_control_container_ = AutoGainControlContainer(
+ BoolSet({source_info.properties().goog_auto_gain_control}));
+
for (size_t i = 0; i < kNumBooleanContainerIds; ++i) {
auto& info = kBooleanPropertyContainerInfoMap[i];
boolean_containers_[info.index] = BooleanContainer(
@@ -962,6 +1026,7 @@ class ProcessingBasedContainer {
ProcessingType processing_type_;
std::array<BooleanContainer, kNumBooleanContainerIds> boolean_containers_;
EchoCancellationContainer echo_cancellation_container_;
+ AutoGainControlContainer auto_gain_control_container_;
IntegerContainer sample_size_container_;
IntegerContainer channels_container_;
IntegerContainer sample_rate_container_;
@@ -1177,7 +1242,7 @@ class DeviceContainer {
};
// This struct groups related fields or entries from
- // DeviceContainer::boolean_containers_ and blink::WebMediaTrackConstraintSet.
+ // DeviceContainer::boolean_containers_ and MediaTrackConstraintSetPlatform.
struct BooleanPropertyContainerInfo {
BooleanContainerId index;
BooleanConstraint ConstraintSet::*constraint_member;
@@ -1312,7 +1377,7 @@ class CandidatesContainer {
std::vector<DeviceContainer> devices_;
};
-std::string GetMediaStreamSource(const WebMediaConstraints& constraints) {
+std::string GetMediaStreamSource(const MediaConstraints& constraints) {
std::string source;
if (constraints.Basic().media_stream_source.HasIdeal() &&
constraints.Basic().media_stream_source.Ideal().size() > 0) {
@@ -1364,7 +1429,7 @@ const media::AudioParameters& AudioDeviceCaptureCapability::Parameters() const {
AudioCaptureSettings SelectSettingsAudioCapture(
const AudioDeviceCaptureCapabilities& capabilities,
- const blink::WebMediaConstraints& constraints,
+ const MediaConstraints& constraints,
bool should_disable_hardware_noise_suppression,
bool is_reconfiguration_allowed) {
if (capabilities.IsEmpty())
@@ -1399,13 +1464,16 @@ AudioCaptureSettings SelectSettingsAudioCapture(
constraints.Basic(),
media_stream_source == blink::kMediaStreamSourceDesktop,
should_disable_hardware_noise_suppression);
+ DCHECK_EQ(settings.audio_processing_properties().goog_auto_gain_control,
+ settings.audio_processing_properties()
+ .goog_experimental_auto_gain_control);
return settings;
}
AudioCaptureSettings SelectSettingsAudioCapture(
blink::MediaStreamAudioSource* source,
- const blink::WebMediaConstraints& constraints) {
+ const MediaConstraints& constraints) {
DCHECK(source);
if (source->device().type !=
blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE &&
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio.h b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio.h
index 6cc8a0b819a..bc3a985c398 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio.h
@@ -11,8 +11,8 @@
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
+class MediaConstraints;
class MediaStreamAudioSource;
-class WebMediaConstraints;
} // namespace blink
namespace blink {
@@ -147,7 +147,7 @@ using AudioDeviceCaptureCapabilities = Vector<AudioDeviceCaptureCapability>;
// getUserMedia and applyConstraints code paths allow for reconfiguration.
MODULES_EXPORT blink::AudioCaptureSettings SelectSettingsAudioCapture(
const AudioDeviceCaptureCapabilities& capabilities,
- const blink::WebMediaConstraints& constraints,
+ const MediaConstraints& constraints,
bool should_disable_hardware_noise_suppression,
bool is_reconfiguration_allowed = false);
@@ -160,7 +160,7 @@ MODULES_EXPORT blink::AudioCaptureSettings SelectSettingsAudioCapture(
// TODO(guidou): Allow reconfiguring audio tracks. https://crbug.com/796964
MODULES_EXPORT blink::AudioCaptureSettings SelectSettingsAudioCapture(
blink::MediaStreamAudioSource* source,
- const blink::WebMediaConstraints& constraints);
+ const MediaConstraints& constraints);
// Return a tuple with <min,max> representing the min and max buffer sizes or
// latencies that can be provided by the given AudioParameters. The min and max
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio_test.cc
index c8466fe892c..91400adb23a 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio_test.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio_test.cc
@@ -10,6 +10,7 @@
#include <string>
#include <utility>
+#include "base/bind_helpers.h"
#include "base/stl_util.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
@@ -18,12 +19,12 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
-#include "third_party/blink/public/platform/web_media_constraints.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/renderer/modules/mediastream/local_media_stream_audio_source.h"
#include "third_party/blink/renderer/modules/mediastream/mock_constraint_factory.h"
#include "third_party/blink/renderer/modules/mediastream/processed_local_audio_source.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/testing/io_task_runner_testing_platform_support.h"
#include "third_party/webrtc/rtc_base/ref_counted_object.h"
@@ -41,7 +42,7 @@ using BoolSetFunction = void (blink::BooleanConstraint::*)(bool);
using StringSetFunction =
void (blink::StringConstraint::*)(const blink::WebString&);
using MockFactoryAccessor =
- blink::WebMediaTrackConstraintSet& (blink::MockConstraintFactory::*)();
+ MediaTrackConstraintSetPlatform& (blink::MockConstraintFactory::*)();
const BoolSetFunction kBoolSetFunctions[] = {
&blink::BooleanConstraint::SetExact,
@@ -96,7 +97,7 @@ class MediaStreamConstraintsUtilAudioTestBase {
void ResetFactory() {
constraint_factory_.Reset();
constraint_factory_.basic().media_stream_source.SetExact(
- blink::WebString::FromASCII(GetMediaStreamSource()));
+ String::FromUTF8(GetMediaStreamSource()));
}
// If not overridden, this function will return device capture by default.
@@ -170,8 +171,7 @@ class MediaStreamConstraintsUtilAudioTestBase {
bool is_reconfigurable = false,
base::Optional<AudioDeviceCaptureCapabilities> capabilities =
base::nullopt) {
- blink::WebMediaConstraints constraints =
- constraint_factory_.CreateWebMediaConstraints();
+ MediaConstraints constraints = constraint_factory_.CreateMediaConstraints();
if (capabilities) {
return SelectSettingsAudioCapture(*capabilities, constraints, false,
is_reconfigurable);
@@ -214,7 +214,23 @@ class MediaStreamConstraintsUtilAudioTestBase {
}
if (!Contains(exclude_audio_properties,
&AudioProcessingProperties::goog_auto_gain_control)) {
- EXPECT_TRUE(properties.goog_auto_gain_control);
+ EXPECT_EQ(properties.goog_auto_gain_control,
+ properties.goog_experimental_auto_gain_control);
+ if (!Contains(exclude_audio_properties,
+ &AudioProcessingProperties::
+ goog_experimental_auto_gain_control)) {
+ EXPECT_TRUE(properties.goog_auto_gain_control);
+ }
+ }
+ if (!Contains(
+ exclude_audio_properties,
+ &AudioProcessingProperties::goog_experimental_auto_gain_control)) {
+ EXPECT_EQ(properties.goog_auto_gain_control,
+ properties.goog_experimental_auto_gain_control);
+ if (!Contains(exclude_audio_properties,
+ &AudioProcessingProperties::goog_auto_gain_control)) {
+ EXPECT_TRUE(properties.goog_experimental_auto_gain_control);
+ }
}
if (!Contains(
exclude_audio_properties,
@@ -234,11 +250,6 @@ class MediaStreamConstraintsUtilAudioTestBase {
&AudioProcessingProperties::goog_highpass_filter)) {
EXPECT_TRUE(properties.goog_highpass_filter);
}
- if (!Contains(
- exclude_audio_properties,
- &AudioProcessingProperties::goog_experimental_auto_gain_control)) {
- EXPECT_TRUE(properties.goog_experimental_auto_gain_control);
- }
}
void CheckBoolDefaultsContentCapture(
@@ -262,7 +273,23 @@ class MediaStreamConstraintsUtilAudioTestBase {
}
if (!Contains(exclude_audio_properties,
&AudioProcessingProperties::goog_auto_gain_control)) {
- EXPECT_FALSE(properties.goog_auto_gain_control);
+ EXPECT_EQ(properties.goog_auto_gain_control,
+ properties.goog_experimental_auto_gain_control);
+ if (!Contains(exclude_audio_properties,
+ &AudioProcessingProperties::
+ goog_experimental_auto_gain_control)) {
+ EXPECT_FALSE(properties.goog_auto_gain_control);
+ }
+ }
+ if (!Contains(
+ exclude_audio_properties,
+ &AudioProcessingProperties::goog_experimental_auto_gain_control)) {
+ EXPECT_EQ(properties.goog_auto_gain_control,
+ properties.goog_experimental_auto_gain_control);
+ if (!Contains(exclude_audio_properties,
+ &AudioProcessingProperties::goog_auto_gain_control)) {
+ EXPECT_FALSE(properties.goog_experimental_auto_gain_control);
+ }
}
if (!Contains(
exclude_audio_properties,
@@ -282,11 +309,6 @@ class MediaStreamConstraintsUtilAudioTestBase {
&AudioProcessingProperties::goog_highpass_filter)) {
EXPECT_FALSE(properties.goog_highpass_filter);
}
- if (!Contains(
- exclude_audio_properties,
- &AudioProcessingProperties::goog_experimental_auto_gain_control)) {
- EXPECT_FALSE(properties.goog_experimental_auto_gain_control);
- }
}
void CheckBoolDefaults(
@@ -400,24 +422,21 @@ class MediaStreamConstraintsUtilAudioTestBase {
double min_latency,
double max_latency) {
constraint_factory_.Reset();
- constraint_factory_.basic().device_id.SetExact(
- blink::WebString(device->DeviceID()));
+ constraint_factory_.basic().device_id.SetExact(device->DeviceID());
constraint_factory_.basic().echo_cancellation.SetExact(false);
constraint_factory_.basic().latency.SetExact(0.0);
auto result = SelectSettings();
EXPECT_FALSE(result.HasValue());
constraint_factory_.Reset();
- constraint_factory_.basic().device_id.SetExact(
- blink::WebString(device->DeviceID()));
+ constraint_factory_.basic().device_id.SetExact(device->DeviceID());
constraint_factory_.basic().echo_cancellation.SetExact(false);
constraint_factory_.basic().latency.SetMin(max_latency + 0.001);
result = SelectSettings();
EXPECT_FALSE(result.HasValue());
constraint_factory_.Reset();
- constraint_factory_.basic().device_id.SetExact(
- blink::WebString(device->DeviceID()));
+ constraint_factory_.basic().device_id.SetExact(device->DeviceID());
constraint_factory_.basic().echo_cancellation.SetExact(false);
constraint_factory_.basic().latency.SetMax(min_latency - 0.001);
result = SelectSettings();
@@ -434,8 +453,7 @@ class MediaStreamConstraintsUtilAudioTestBase {
double requested_latency,
int expected_buffer_size) {
constraint_factory_.Reset();
- constraint_factory_.basic().device_id.SetExact(
- blink::WebString(device->DeviceID()));
+ constraint_factory_.basic().device_id.SetExact(device->DeviceID());
constraint_factory_.basic().echo_cancellation.SetExact(false);
constraint_factory_.basic().latency.SetIdeal(requested_latency);
auto result = SelectSettings();
@@ -581,11 +599,10 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, SingleBoolConstraint) {
&AudioCaptureSettings::disable_local_echo,
&AudioCaptureSettings::render_to_associated_sink};
- const std::vector<
- blink::BooleanConstraint blink::WebMediaTrackConstraintSet::*>
+ const std::vector<blink::BooleanConstraint MediaTrackConstraintSetPlatform::*>
kMainBoolConstraints = {
- &blink::WebMediaTrackConstraintSet::disable_local_echo,
- &blink::WebMediaTrackConstraintSet::render_to_associated_sink};
+ &MediaTrackConstraintSetPlatform::disable_local_echo,
+ &MediaTrackConstraintSetPlatform::render_to_associated_sink};
ASSERT_EQ(kMainSettings.size(), kMainBoolConstraints.size());
for (auto set_function : kBoolSetFunctions) {
@@ -612,19 +629,15 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, SingleBoolConstraint) {
}
}
- const std::vector<
- blink::BooleanConstraint blink::WebMediaTrackConstraintSet::*>
+ const std::vector<blink::BooleanConstraint MediaTrackConstraintSetPlatform::*>
kAudioProcessingConstraints = {
- &blink::WebMediaTrackConstraintSet::goog_audio_mirroring,
- &blink::WebMediaTrackConstraintSet::goog_auto_gain_control,
- &blink::WebMediaTrackConstraintSet::
- goog_experimental_echo_cancellation,
- &blink::WebMediaTrackConstraintSet::goog_noise_suppression,
- &blink::WebMediaTrackConstraintSet::
- goog_experimental_noise_suppression,
- &blink::WebMediaTrackConstraintSet::goog_highpass_filter,
- &blink::WebMediaTrackConstraintSet::
- goog_experimental_auto_gain_control,
+ &MediaTrackConstraintSetPlatform::goog_audio_mirroring,
+ &MediaTrackConstraintSetPlatform::goog_auto_gain_control,
+ &MediaTrackConstraintSetPlatform::goog_experimental_echo_cancellation,
+ &MediaTrackConstraintSetPlatform::goog_noise_suppression,
+ &MediaTrackConstraintSetPlatform::goog_experimental_noise_suppression,
+ &MediaTrackConstraintSetPlatform::goog_highpass_filter,
+ &MediaTrackConstraintSetPlatform::goog_experimental_auto_gain_control,
};
ASSERT_EQ(kAudioProcessingProperties.size(),
@@ -820,7 +833,7 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, ChannelsWithSource) {
ResetFactory();
constraint_factory_.basic().channel_count.SetExact(channel_count);
auto result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
if (channel_count == 2)
EXPECT_TRUE(result.HasValue());
else
@@ -938,12 +951,12 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, SampleRateWithSource) {
constraint_factory_.basic().sample_rate.SetExact(
media::AudioParameters::kAudioCDSampleRate);
auto result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
constraint_factory_.basic().sample_rate.SetExact(11111);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_FALSE(result.HasValue());
// Test set min sampleRate.
@@ -951,13 +964,13 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, SampleRateWithSource) {
constraint_factory_.basic().sample_rate.SetMin(
media::AudioParameters::kAudioCDSampleRate);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
constraint_factory_.basic().sample_rate.SetMin(
media::AudioParameters::kAudioCDSampleRate + 1);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_FALSE(result.HasValue());
// Test set max sampleRate.
@@ -965,13 +978,13 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, SampleRateWithSource) {
constraint_factory_.basic().sample_rate.SetMax(
media::AudioParameters::kAudioCDSampleRate);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
constraint_factory_.basic().sample_rate.SetMax(
media::AudioParameters::kAudioCDSampleRate - 1);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_FALSE(result.HasValue());
// Test set ideal sampleRate.
@@ -979,13 +992,13 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, SampleRateWithSource) {
constraint_factory_.basic().sample_rate.SetIdeal(
media::AudioParameters::kAudioCDSampleRate);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
constraint_factory_.basic().sample_rate.SetIdeal(
media::AudioParameters::kAudioCDSampleRate - 1);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
}
@@ -1093,12 +1106,12 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, LatencyWithSource) {
ResetFactory();
constraint_factory_.basic().latency.SetExact(0.01);
auto result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
constraint_factory_.basic().latency.SetExact(0.1234);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_FALSE(result.HasValue());
// Test set min sampleRate.
@@ -1143,20 +1156,19 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, LatencyWithSource) {
ResetFactory();
constraint_factory_.basic().latency.SetIdeal(0.01);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
constraint_factory_.basic().latency.SetIdeal(0.1234);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
}
// DeviceID tests.
TEST_P(MediaStreamConstraintsUtilAudioTest, ExactArbitraryDeviceID) {
- const std::string kArbitraryDeviceID = "arbitrary";
- constraint_factory_.basic().device_id.SetExact(
- blink::WebString::FromASCII(kArbitraryDeviceID));
+ const String kArbitraryDeviceID = "arbitrary";
+ constraint_factory_.basic().device_id.SetExact(kArbitraryDeviceID);
auto result = SelectSettings();
// kArbitraryDeviceID is invalid for device capture, but it is considered
// valid for content capture. For content capture, validation of device
@@ -1167,7 +1179,7 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, ExactArbitraryDeviceID) {
std::string(result.failed_constraint_name()));
} else {
EXPECT_TRUE(result.HasValue());
- EXPECT_EQ(kArbitraryDeviceID, result.device_id());
+ EXPECT_EQ(kArbitraryDeviceID.Utf8(), result.device_id());
CheckBoolDefaults(AudioSettingsBoolMembers(), AudioPropertiesBoolMembers(),
result);
CheckEchoCancellationTypeDefault(result);
@@ -1176,9 +1188,8 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, ExactArbitraryDeviceID) {
// DeviceID tests check various ways to deal with the device_id constraint.
TEST_P(MediaStreamConstraintsUtilAudioTest, IdealArbitraryDeviceID) {
- const std::string kArbitraryDeviceID = "arbitrary";
- constraint_factory_.basic().device_id.SetIdeal(
- blink::WebString::FromASCII(kArbitraryDeviceID));
+ const String kArbitraryDeviceID = "arbitrary";
+ constraint_factory_.basic().device_id.SetIdeal(kArbitraryDeviceID);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
// kArbitraryDeviceID is invalid for device capture, but it is considered
@@ -1187,7 +1198,7 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, IdealArbitraryDeviceID) {
if (IsDeviceCapture())
CheckDeviceDefaults(result);
else
- EXPECT_EQ(kArbitraryDeviceID, result.device_id());
+ EXPECT_EQ(kArbitraryDeviceID.Utf8(), result.device_id());
CheckProcessingType(result);
CheckBoolDefaults(AudioSettingsBoolMembers(), AudioPropertiesBoolMembers(),
result);
@@ -1196,8 +1207,7 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, IdealArbitraryDeviceID) {
TEST_P(MediaStreamConstraintsUtilAudioTest, ExactValidDeviceID) {
for (const auto& device : capabilities_) {
- constraint_factory_.basic().device_id.SetExact(
- blink::WebString(device.DeviceID()));
+ constraint_factory_.basic().device_id.SetExact(device.DeviceID());
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
CheckDevice(device, result);
@@ -1222,8 +1232,7 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, ExactValidDeviceID) {
TEST_P(MediaStreamConstraintsUtilAudioTest, ExactGroupID) {
for (const auto& device : capabilities_) {
- constraint_factory_.basic().group_id.SetExact(
- blink::WebString(device.GroupID()));
+ constraint_factory_.basic().group_id.SetExact(device.GroupID());
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
CheckDevice(device, result);
@@ -1327,7 +1336,7 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, EchoCancellationWithSystem) {
for (bool value : kBoolValues) {
ResetFactory();
constraint_factory_.basic().device_id.SetExact(
- blink::WebString(system_echo_canceller_device_->DeviceID()));
+ system_echo_canceller_device_->DeviceID());
((constraint_factory_.*accessor)().echo_cancellation.*
set_function)(value);
auto result = SelectSettings();
@@ -1423,7 +1432,7 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, GoogEchoCancellationWithSystem) {
for (bool value : kBoolValues) {
ResetFactory();
constraint_factory_.basic().device_id.SetExact(
- blink::WebString(system_echo_canceller_device_->DeviceID()));
+ system_echo_canceller_device_->DeviceID());
((constraint_factory_.*accessor)().goog_echo_cancellation.*
set_function)(value);
auto result = SelectSettings();
@@ -1460,24 +1469,36 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, ContradictoryEchoCancellation) {
}
}
+// Test that having differing mandatory values for googAutoGainControl and
+// googAutoGainControl2 fails. This test is valid to correctly support the
+// old syntax.
+TEST_P(MediaStreamConstraintsUtilAudioTest, ContradictoryAutoGainControl) {
+ // TODO(armax): fix this.
+ for (bool value : kBoolValues) {
+ constraint_factory_.basic().goog_auto_gain_control.SetExact(value);
+ constraint_factory_.basic().goog_experimental_auto_gain_control.SetExact(
+ !value);
+ auto result = SelectSettings();
+ EXPECT_FALSE(result.HasValue());
+ EXPECT_EQ(result.failed_constraint_name(),
+ constraint_factory_.basic()
+ .goog_experimental_auto_gain_control.GetName());
+ }
+}
+
// Tests that individual boolean audio-processing constraints override the
// default value set by the echoCancellation constraint.
TEST_P(MediaStreamConstraintsUtilAudioTest,
EchoCancellationAndSingleBoolConstraint) {
-
- const std::vector<
- blink::BooleanConstraint blink::WebMediaTrackConstraintSet::*>
+ const std::vector<blink::BooleanConstraint MediaTrackConstraintSetPlatform::*>
kAudioProcessingConstraints = {
- &blink::WebMediaTrackConstraintSet::goog_audio_mirroring,
- &blink::WebMediaTrackConstraintSet::goog_auto_gain_control,
- &blink::WebMediaTrackConstraintSet::
- goog_experimental_echo_cancellation,
- &blink::WebMediaTrackConstraintSet::goog_noise_suppression,
- &blink::WebMediaTrackConstraintSet::
- goog_experimental_noise_suppression,
- &blink::WebMediaTrackConstraintSet::goog_highpass_filter,
- &blink::WebMediaTrackConstraintSet::
- goog_experimental_auto_gain_control,
+ &MediaTrackConstraintSetPlatform::goog_audio_mirroring,
+ &MediaTrackConstraintSetPlatform::goog_auto_gain_control,
+ &MediaTrackConstraintSetPlatform::goog_experimental_echo_cancellation,
+ &MediaTrackConstraintSetPlatform::goog_noise_suppression,
+ &MediaTrackConstraintSetPlatform::goog_experimental_noise_suppression,
+ &MediaTrackConstraintSetPlatform::goog_highpass_filter,
+ &MediaTrackConstraintSetPlatform::goog_experimental_auto_gain_control,
};
ASSERT_EQ(kAudioProcessingProperties.size(),
@@ -1507,6 +1528,15 @@ TEST_P(MediaStreamConstraintsUtilAudioTest,
for (size_t j = 0; j < kAudioProcessingProperties.size(); ++j) {
if (i == j)
continue;
+ // goog_auto_gain_control and goog_experimental_auto_gain_control
+ // should always match in value.
+ if ((i == 1 && j == 6) || (i == 6 && j == 1)) {
+ EXPECT_EQ(result.audio_processing_properties().*
+ kAudioProcessingProperties[i],
+ result.audio_processing_properties().*
+ kAudioProcessingProperties[j]);
+ continue;
+ }
EXPECT_FALSE(result.audio_processing_properties().*
kAudioProcessingProperties[j]);
}
@@ -1538,14 +1568,14 @@ TEST_P(MediaStreamConstraintsUtilAudioTest,
constraint_factory_.Reset();
constraint_factory_.basic().device_id.SetExact(
- blink::WebString(system_echo_canceller_with_source->DeviceID()));
+ system_echo_canceller_with_source->DeviceID());
constraint_factory_.basic().echo_cancellation.SetExact(true);
auto result = SelectSettings(true, capabilities);
EXPECT_TRUE(result.HasValue());
constraint_factory_.Reset();
constraint_factory_.basic().device_id.SetExact(
- blink::WebString(system_echo_canceller_with_source->DeviceID()));
+ system_echo_canceller_with_source->DeviceID());
constraint_factory_.basic().echo_cancellation.SetExact(false);
result = SelectSettings(true, capabilities);
EXPECT_FALSE(result.HasValue());
@@ -1615,7 +1645,7 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, NoDevicesNoConstraints) {
AudioDeviceCaptureCapabilities capabilities;
auto result = SelectSettingsAudioCapture(
- capabilities, constraint_factory_.CreateWebMediaConstraints(), false);
+ capabilities, constraint_factory_.CreateMediaConstraints(), false);
EXPECT_FALSE(result.HasValue());
EXPECT_TRUE(std::string(result.failed_constraint_name()).empty());
}
@@ -1628,7 +1658,7 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, NoDevicesWithConstraints) {
AudioDeviceCaptureCapabilities capabilities;
constraint_factory_.basic().sample_size.SetExact(16);
auto result = SelectSettingsAudioCapture(
- capabilities, constraint_factory_.CreateWebMediaConstraints(), false);
+ capabilities, constraint_factory_.CreateMediaConstraints(), false);
EXPECT_FALSE(result.HasValue());
EXPECT_TRUE(std::string(result.failed_constraint_name()).empty());
}
@@ -1645,11 +1675,11 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, SourceWithNoAudioProcessing) {
// These constraints are false in |source|.
const std::vector<
- blink::BooleanConstraint blink::WebMediaTrackConstraintSet::*>
+ blink::BooleanConstraint MediaTrackConstraintSetPlatform::*>
kConstraints = {
- &blink::WebMediaTrackConstraintSet::echo_cancellation,
- &blink::WebMediaTrackConstraintSet::disable_local_echo,
- &blink::WebMediaTrackConstraintSet::render_to_associated_sink,
+ &MediaTrackConstraintSetPlatform::echo_cancellation,
+ &MediaTrackConstraintSetPlatform::disable_local_echo,
+ &MediaTrackConstraintSetPlatform::render_to_associated_sink,
};
for (size_t i = 0; i < kConstraints.size(); ++i) {
@@ -1657,27 +1687,27 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, SourceWithNoAudioProcessing) {
(constraint_factory_.basic().*kConstraints[i])
.SetExact(enable_properties);
auto result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
constraint_factory_.Reset();
(constraint_factory_.basic().*kConstraints[i])
.SetExact(!enable_properties);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_FALSE(result.HasValue());
// Setting just ideal values should always succeed.
constraint_factory_.Reset();
(constraint_factory_.basic().*kConstraints[i]).SetIdeal(true);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
constraint_factory_.Reset();
(constraint_factory_.basic().*kConstraints[i]).SetIdeal(false);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
}
}
@@ -1712,17 +1742,17 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, SourceWithAudioProcessing) {
properties, use_defaults /* disable_local_echo */,
use_defaults /* render_to_associated_sink */);
const std::vector<
- blink::BooleanConstraint blink::WebMediaTrackConstraintSet::*>
+ blink::BooleanConstraint MediaTrackConstraintSetPlatform::*>
kAudioProcessingConstraints = {
- &blink::WebMediaTrackConstraintSet::goog_audio_mirroring,
- &blink::WebMediaTrackConstraintSet::goog_auto_gain_control,
- &blink::WebMediaTrackConstraintSet::
+ &MediaTrackConstraintSetPlatform::goog_audio_mirroring,
+ &MediaTrackConstraintSetPlatform::goog_auto_gain_control,
+ &MediaTrackConstraintSetPlatform::
goog_experimental_echo_cancellation,
- &blink::WebMediaTrackConstraintSet::goog_noise_suppression,
- &blink::WebMediaTrackConstraintSet::
+ &MediaTrackConstraintSetPlatform::goog_noise_suppression,
+ &MediaTrackConstraintSetPlatform::
goog_experimental_noise_suppression,
- &blink::WebMediaTrackConstraintSet::goog_highpass_filter,
- &blink::WebMediaTrackConstraintSet::
+ &MediaTrackConstraintSetPlatform::goog_highpass_filter,
+ &MediaTrackConstraintSetPlatform::
goog_experimental_auto_gain_control,
};
ASSERT_EQ(kAudioProcessingConstraints.size(),
@@ -1733,14 +1763,14 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, SourceWithAudioProcessing) {
(constraint_factory_.basic().*kAudioProcessingConstraints[i])
.SetExact(properties.*kAudioProcessingProperties[i]);
auto result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
constraint_factory_.Reset();
(constraint_factory_.basic().*kAudioProcessingConstraints[i])
.SetExact(!(properties.*kAudioProcessingProperties[i]));
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_FALSE(result.HasValue());
// Setting just ideal values should always succeed.
@@ -1748,14 +1778,14 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, SourceWithAudioProcessing) {
(constraint_factory_.basic().*kAudioProcessingConstraints[i])
.SetIdeal(true);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
constraint_factory_.Reset();
(constraint_factory_.basic().*kAudioProcessingConstraints[i])
.SetIdeal(false);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
}
@@ -1765,7 +1795,7 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, SourceWithAudioProcessing) {
properties.echo_cancellation_type ==
EchoCancellationType::kEchoCancellationAec3);
auto result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
constraint_factory_.Reset();
@@ -1773,54 +1803,54 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, SourceWithAudioProcessing) {
properties.echo_cancellation_type !=
EchoCancellationType::kEchoCancellationAec3);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_FALSE(result.HasValue());
constraint_factory_.Reset();
constraint_factory_.basic().echo_cancellation.SetIdeal(true);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
constraint_factory_.Reset();
constraint_factory_.basic().echo_cancellation.SetIdeal(false);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
// These constraints are false in |source|.
const std::vector<
- blink::BooleanConstraint blink::WebMediaTrackConstraintSet::*>
+ blink::BooleanConstraint MediaTrackConstraintSetPlatform::*>
kAudioBrowserConstraints = {
- &blink::WebMediaTrackConstraintSet::disable_local_echo,
- &blink::WebMediaTrackConstraintSet::render_to_associated_sink,
+ &MediaTrackConstraintSetPlatform::disable_local_echo,
+ &MediaTrackConstraintSetPlatform::render_to_associated_sink,
};
for (size_t i = 0; i < kAudioBrowserConstraints.size(); ++i) {
constraint_factory_.Reset();
(constraint_factory_.basic().*kAudioBrowserConstraints[i])
.SetExact(use_defaults);
auto result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
constraint_factory_.Reset();
(constraint_factory_.basic().*kAudioBrowserConstraints[i])
.SetExact(!use_defaults);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_FALSE(result.HasValue());
constraint_factory_.Reset();
(constraint_factory_.basic().*kAudioBrowserConstraints[i]).SetIdeal(true);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
constraint_factory_.Reset();
(constraint_factory_.basic().*kAudioBrowserConstraints[i])
.SetIdeal(false);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
}
@@ -1828,25 +1858,25 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, SourceWithAudioProcessing) {
constraint_factory_.Reset();
constraint_factory_.basic().echo_cancellation.SetExact(use_defaults);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
constraint_factory_.Reset();
constraint_factory_.basic().echo_cancellation.SetExact(!use_defaults);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_FALSE(result.HasValue());
constraint_factory_.Reset();
constraint_factory_.basic().echo_cancellation.SetIdeal(true);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
constraint_factory_.Reset();
constraint_factory_.basic().echo_cancellation.SetIdeal(false);
result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
}
}
@@ -1874,7 +1904,7 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, UsedAndUnusedSources) {
constraint_factory_.basic().echo_cancellation.SetExact(false);
auto result = SelectSettingsAudioCapture(
- capabilities, constraint_factory_.CreateWebMediaConstraints(),
+ capabilities, constraint_factory_.CreateMediaConstraints(),
false /* should_disable_hardware_noise_suppression */);
EXPECT_TRUE(result.HasValue());
EXPECT_EQ(result.device_id(), kUnusedDeviceID.Utf8());
@@ -1886,7 +1916,7 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, UsedAndUnusedSources) {
constraint_factory_.Reset();
constraint_factory_.basic().echo_cancellation.SetExact(true);
auto result = SelectSettingsAudioCapture(
- capabilities, constraint_factory_.CreateWebMediaConstraints(),
+ capabilities, constraint_factory_.CreateMediaConstraints(),
false /* should_disable_hardware_noise_suppression */);
EXPECT_TRUE(result.HasValue());
EXPECT_EQ(result.device_id(), processed_source->device().id);
@@ -1906,7 +1936,7 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, ExperimetanlEcWithSource) {
constraint_factory_.basic().echo_cancellation.SetExact(false);
auto result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
+ source.get(), constraint_factory_.CreateMediaConstraints());
EXPECT_TRUE(result.HasValue());
}
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.cc
index c4a2c391d77..522645dfddc 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.cc
@@ -6,8 +6,8 @@
#include <cmath>
-#include "third_party/blink/public/platform/web_media_constraints.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.h"
+#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
namespace blink {
namespace media_constraints {
@@ -119,7 +119,6 @@ Point::Point(double height, double width) : height_(height), width_(width) {
}
Point::Point(const Point& other) = default;
Point& Point::operator=(const Point& other) = default;
-Point::~Point() = default;
bool Point::operator==(const Point& other) const {
return height_ == other.height_ && width_ == other.width_;
@@ -216,7 +215,7 @@ ResolutionSet::ResolutionSet()
: ResolutionSet(0, kMaxDimension, 0, kMaxDimension, 0.0, HUGE_VAL) {}
ResolutionSet::ResolutionSet(const ResolutionSet& other) = default;
-ResolutionSet::~ResolutionSet() = default;
+
ResolutionSet& ResolutionSet::operator=(const ResolutionSet& other) = default;
bool ResolutionSet::IsHeightEmpty() const {
@@ -269,7 +268,7 @@ ResolutionSet ResolutionSet::Intersection(const ResolutionSet& other) const {
}
Point ResolutionSet::SelectClosestPointToIdeal(
- const WebMediaTrackConstraintSet& constraint_set,
+ const MediaTrackConstraintSetPlatform& constraint_set,
int default_height,
int default_width) const {
DCHECK_GE(default_height, 1);
@@ -536,7 +535,7 @@ void ResolutionSet::TryAddVertex(std::vector<Point>* vertices,
}
ResolutionSet ResolutionSet::FromConstraintSet(
- const WebMediaTrackConstraintSet& constraint_set) {
+ const MediaTrackConstraintSetPlatform& constraint_set) {
return ResolutionSet(
MinDimensionFromConstraint(constraint_set.height),
MaxDimensionFromConstraint(constraint_set.height),
@@ -568,12 +567,12 @@ DiscreteSet<bool> BoolSetFromConstraint(const BooleanConstraint& constraint) {
DiscreteSet<bool> RescaleSetFromConstraint(
const StringConstraint& resize_mode_constraint) {
DCHECK_EQ(resize_mode_constraint.GetName(),
- WebMediaTrackConstraintSet().resize_mode.GetName());
+ MediaTrackConstraintSetPlatform().resize_mode.GetName());
bool contains_none = resize_mode_constraint.Matches(
WebString::FromASCII(WebMediaStreamTrack::kResizeModeNone));
bool contains_rescale = resize_mode_constraint.Matches(
WebString::FromASCII(WebMediaStreamTrack::kResizeModeRescale));
- if (resize_mode_constraint.Exact().empty() ||
+ if (resize_mode_constraint.Exact().IsEmpty() ||
(contains_none && contains_rescale)) {
return DiscreteSet<bool>::UniversalSet();
}
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 4ef02252a24..955b20a1e2b 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
@@ -14,12 +14,12 @@
#include "base/gtest_prod_util.h"
#include "base/logging.h"
#include "base/optional.h"
-#include "third_party/blink/public/platform/web_media_constraints.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
namespace blink {
-struct WebMediaTrackConstraintSet;
+struct MediaTrackConstraintSetPlatform;
template <typename ConstraintType>
bool ConstraintHasMax(const ConstraintType& constraint) {
@@ -239,7 +239,6 @@ class MODULES_EXPORT ResolutionSet {
Point(double height, double width);
Point(const Point& other);
Point& operator=(const Point& other);
- ~Point();
// Accessors.
double height() const { return height_; }
@@ -286,7 +285,6 @@ class MODULES_EXPORT ResolutionSet {
double max_aspect_ratio);
ResolutionSet(const ResolutionSet& other);
ResolutionSet& operator=(const ResolutionSet& other);
- ~ResolutionSet();
// Getters.
int min_height() const { return min_height_; }
@@ -368,7 +366,7 @@ class MODULES_EXPORT ResolutionSet {
//
// This function has undefined behavior if this set is empty.
Point SelectClosestPointToIdeal(
- const WebMediaTrackConstraintSet& constraint_set,
+ const MediaTrackConstraintSetPlatform& constraint_set,
int default_height,
int default_width) const;
@@ -386,7 +384,7 @@ class MODULES_EXPORT ResolutionSet {
// Returns a ResolutionCandidateSet initialized with |constraint_set|'s
// width, height and aspectRatio constraints.
static ResolutionSet FromConstraintSet(
- const WebMediaTrackConstraintSet& constraint_set);
+ const MediaTrackConstraintSetPlatform& constraint_set);
private:
FRIEND_TEST_ALL_PREFIXES(MediaStreamConstraintsUtilSetsTest,
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets_test.cc
index 7d8091da853..bba9255c9d2 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets_test.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets_test.cc
@@ -125,7 +125,7 @@ class MediaStreamConstraintsUtilSetsTest : public testing::Test {
Point SelectClosestPointToIdeal(const ResolutionSet& set) {
return set.SelectClosestPointToIdeal(
- factory_.CreateWebMediaConstraints().Basic(), kDefaultHeight,
+ factory_.CreateMediaConstraints().Basic(), kDefaultHeight,
kDefaultWidth);
}
@@ -1509,21 +1509,20 @@ TEST_F(MediaStreamConstraintsUtilSetsTest, DiscreteSetBool) {
TEST_F(MediaStreamConstraintsUtilSetsTest, RescaleSetFromConstraints) {
factory_.Reset();
- factory_.CreateWebMediaConstraints();
+ factory_.CreateMediaConstraints();
BoolSet set =
media_constraints::RescaleSetFromConstraint(factory_.basic().resize_mode);
EXPECT_TRUE(set.is_universal());
EXPECT_FALSE(set.HasExplicitElements());
// Invalid exact value.
- factory_.basic().resize_mode.SetExact({WebString::FromASCII("invalid")});
+ factory_.basic().resize_mode.SetExact("invalid");
set =
media_constraints::RescaleSetFromConstraint(factory_.basic().resize_mode);
EXPECT_TRUE(set.IsEmpty());
// No rescaling
- factory_.basic().resize_mode.SetExact(
- WebString::FromASCII(WebMediaStreamTrack::kResizeModeNone));
+ factory_.basic().resize_mode.SetExact(WebMediaStreamTrack::kResizeModeNone);
set =
media_constraints::RescaleSetFromConstraint(factory_.basic().resize_mode);
EXPECT_TRUE(set.Contains(false));
@@ -1531,18 +1530,16 @@ TEST_F(MediaStreamConstraintsUtilSetsTest, RescaleSetFromConstraints) {
// Rescaling
factory_.basic().resize_mode.SetExact(
- WebString::FromASCII(WebMediaStreamTrack::kResizeModeRescale));
+ WebMediaStreamTrack::kResizeModeRescale);
set =
media_constraints::RescaleSetFromConstraint(factory_.basic().resize_mode);
EXPECT_TRUE(set.Contains(true));
EXPECT_FALSE(set.Contains(false));
// Both explicit
- WebString rescale_modes[] = {
- WebString::FromASCII(WebMediaStreamTrack::kResizeModeRescale),
- WebString::FromASCII(WebMediaStreamTrack::kResizeModeNone)};
- factory_.basic().resize_mode.SetExact(
- WebVector<WebString>(rescale_modes, base::size(rescale_modes)));
+ Vector<String> rescale_modes = {WebMediaStreamTrack::kResizeModeRescale,
+ WebMediaStreamTrack::kResizeModeNone};
+ factory_.basic().resize_mode.SetExact(rescale_modes);
set =
media_constraints::RescaleSetFromConstraint(factory_.basic().resize_mode);
EXPECT_TRUE(set.Contains(true));
@@ -1550,8 +1547,7 @@ TEST_F(MediaStreamConstraintsUtilSetsTest, RescaleSetFromConstraints) {
// Invalid and no rescaling.
rescale_modes[0] = "invalid";
- factory_.basic().resize_mode.SetExact(
- WebVector<WebString>(rescale_modes, base::size(rescale_modes)));
+ factory_.basic().resize_mode.SetExact(Vector<String>(rescale_modes));
set =
media_constraints::RescaleSetFromConstraint(factory_.basic().resize_mode);
EXPECT_FALSE(set.Contains(true));
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_test.cc
index a69165a0b8e..9bc18d3006c 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_test.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_test.cc
@@ -21,7 +21,7 @@ constexpr double kSourceAspectRatio =
constexpr double kSourceFrameRate = 100.0;
VideoTrackAdapterSettings SelectTrackSettings(
- const WebMediaTrackConstraintSet& basic_constraint_set,
+ const MediaTrackConstraintSetPlatform& basic_constraint_set,
const media_constraints::ResolutionSet& resolution_set,
const media_constraints::NumericRangeSet<double>& frame_rate_set,
bool enable_rescale = true) {
@@ -49,15 +49,14 @@ TEST_F(MediaStreamConstraintsUtilTest, BooleanConstraints) {
// Mandatory constraints.
constraint_factory.basic().echo_cancellation.SetExact(true);
constraint_factory.basic().goog_echo_cancellation.SetExact(false);
- WebMediaConstraints constraints =
- constraint_factory.CreateWebMediaConstraints();
+ MediaConstraints constraints = constraint_factory.CreateMediaConstraints();
bool value_true = false;
bool value_false = false;
EXPECT_TRUE(GetConstraintValueAsBoolean(
- constraints, &WebMediaTrackConstraintSet::echo_cancellation,
+ constraints, &MediaTrackConstraintSetPlatform::echo_cancellation,
&value_true));
EXPECT_TRUE(GetConstraintValueAsBoolean(
- constraints, &WebMediaTrackConstraintSet::goog_echo_cancellation,
+ constraints, &MediaTrackConstraintSetPlatform::goog_echo_cancellation,
&value_false));
EXPECT_TRUE(value_true);
EXPECT_FALSE(value_false);
@@ -66,12 +65,12 @@ TEST_F(MediaStreamConstraintsUtilTest, BooleanConstraints) {
constraint_factory.Reset();
constraint_factory.AddAdvanced().echo_cancellation.SetExact(false);
constraint_factory.AddAdvanced().goog_echo_cancellation.SetExact(true);
- constraints = constraint_factory.CreateWebMediaConstraints();
+ constraints = constraint_factory.CreateMediaConstraints();
EXPECT_TRUE(GetConstraintValueAsBoolean(
- constraints, &WebMediaTrackConstraintSet::echo_cancellation,
+ constraints, &MediaTrackConstraintSetPlatform::echo_cancellation,
&value_false));
EXPECT_TRUE(GetConstraintValueAsBoolean(
- constraints, &WebMediaTrackConstraintSet::goog_echo_cancellation,
+ constraints, &MediaTrackConstraintSetPlatform::goog_echo_cancellation,
&value_true));
EXPECT_TRUE(value_true);
EXPECT_FALSE(value_false);
@@ -80,9 +79,9 @@ TEST_F(MediaStreamConstraintsUtilTest, BooleanConstraints) {
constraint_factory.Reset();
constraint_factory.AddAdvanced().echo_cancellation.SetExact(false);
constraint_factory.basic().echo_cancellation.SetExact(true);
- constraints = constraint_factory.CreateWebMediaConstraints();
+ constraints = constraint_factory.CreateMediaConstraints();
EXPECT_TRUE(GetConstraintValueAsBoolean(
- constraints, &WebMediaTrackConstraintSet::echo_cancellation,
+ constraints, &MediaTrackConstraintSetPlatform::echo_cancellation,
&value_true));
EXPECT_TRUE(value_true);
}
@@ -92,14 +91,13 @@ TEST_F(MediaStreamConstraintsUtilTest, DoubleConstraints) {
const double test_value = 0.01f;
constraint_factory.basic().aspect_ratio.SetExact(test_value);
- WebMediaConstraints constraints =
- constraint_factory.CreateWebMediaConstraints();
+ MediaConstraints constraints = constraint_factory.CreateMediaConstraints();
double value;
EXPECT_FALSE(GetConstraintValueAsDouble(
- constraints, &WebMediaTrackConstraintSet::frame_rate, &value));
+ constraints, &MediaTrackConstraintSetPlatform::frame_rate, &value));
EXPECT_TRUE(GetConstraintValueAsDouble(
- constraints, &WebMediaTrackConstraintSet::aspect_ratio, &value));
+ constraints, &MediaTrackConstraintSetPlatform::aspect_ratio, &value));
EXPECT_EQ(test_value, value);
}
@@ -108,20 +106,19 @@ TEST_F(MediaStreamConstraintsUtilTest, IntConstraints) {
const int test_value = 327;
constraint_factory.basic().width.SetExact(test_value);
- WebMediaConstraints constraints =
- constraint_factory.CreateWebMediaConstraints();
+ MediaConstraints constraints = constraint_factory.CreateMediaConstraints();
int value;
EXPECT_TRUE(GetConstraintValueAsInteger(
- constraints, &WebMediaTrackConstraintSet::width, &value));
+ constraints, &MediaTrackConstraintSetPlatform::width, &value));
EXPECT_EQ(test_value, value);
// An exact value should also be reflected as min and max.
EXPECT_TRUE(GetConstraintMaxAsInteger(
- constraints, &WebMediaTrackConstraintSet::width, &value));
+ constraints, &MediaTrackConstraintSetPlatform::width, &value));
EXPECT_EQ(test_value, value);
EXPECT_TRUE(GetConstraintMinAsInteger(
- constraints, &WebMediaTrackConstraintSet::width, &value));
+ constraints, &MediaTrackConstraintSetPlatform::width, &value));
EXPECT_EQ(test_value, value);
}
@@ -132,9 +129,9 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsUnconstrained) {
// No ideal values.
{
MockConstraintFactory constraint_factory;
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(kSourceHeight, result.target_height());
EXPECT_EQ(kSourceWidth, result.target_width());
EXPECT_EQ(0.0, result.min_aspect_ratio());
@@ -147,9 +144,9 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsUnconstrained) {
const int kIdealHeight = 400;
MockConstraintFactory constraint_factory;
constraint_factory.basic().height.SetIdeal(kIdealHeight);
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(kIdealHeight, result.target_height());
EXPECT_EQ(std::round(kIdealHeight * kSourceAspectRatio),
result.target_width());
@@ -163,9 +160,9 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsUnconstrained) {
const int kIdealWidth = 400;
MockConstraintFactory constraint_factory;
constraint_factory.basic().width.SetIdeal(kIdealWidth);
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(std::round(kIdealWidth / kSourceAspectRatio),
result.target_height());
EXPECT_EQ(kIdealWidth, result.target_width());
@@ -179,9 +176,9 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsUnconstrained) {
const double kIdealAspectRatio = 2.0;
MockConstraintFactory constraint_factory;
constraint_factory.basic().aspect_ratio.SetIdeal(kIdealAspectRatio);
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(kSourceHeight, result.target_height());
EXPECT_EQ(std::round(kSourceHeight * kIdealAspectRatio),
result.target_width());
@@ -195,9 +192,9 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsUnconstrained) {
const double kIdealFrameRate = 33;
MockConstraintFactory constraint_factory;
constraint_factory.basic().frame_rate.SetIdeal(kIdealFrameRate);
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(kSourceHeight, result.target_height());
EXPECT_EQ(kSourceWidth, result.target_width());
EXPECT_EQ(0.0, result.min_aspect_ratio());
@@ -217,9 +214,9 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsUnconstrained) {
// Ideal aspect ratio is ignored if ideal width and height are supplied.
constraint_factory.basic().aspect_ratio.SetIdeal(kIdealAspectRatio);
constraint_factory.basic().frame_rate.SetIdeal(kIdealFrameRate);
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(kIdealHeight, result.target_height());
EXPECT_EQ(kIdealWidth, result.target_width());
EXPECT_EQ(0.0, result.min_aspect_ratio());
@@ -247,9 +244,9 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsConstrained) {
// No ideal values.
{
MockConstraintFactory constraint_factory;
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(kSourceHeight, result.target_height());
EXPECT_EQ(kSourceWidth, result.target_width());
EXPECT_EQ(kMinAspectRatio, result.min_aspect_ratio());
@@ -264,9 +261,9 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsConstrained) {
"kIdealHeight must be less than kMinHeight");
MockConstraintFactory constraint_factory;
constraint_factory.basic().height.SetIdeal(kIdealHeight);
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(kMinHeight, result.target_height());
// kMinWidth > kMinHeight * kNativeAspectRatio
EXPECT_EQ(kMinWidth, result.target_width());
@@ -284,9 +281,9 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsConstrained) {
"kIdealHeight must be less than kMaxHeight");
MockConstraintFactory constraint_factory;
constraint_factory.basic().height.SetIdeal(kIdealHeight);
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(kIdealHeight, result.target_height());
EXPECT_EQ(std::round(kIdealHeight * kSourceAspectRatio),
result.target_width());
@@ -302,9 +299,9 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsConstrained) {
"kIdealHeight must be greater than kMaxHeight");
MockConstraintFactory constraint_factory;
constraint_factory.basic().height.SetIdeal(kIdealHeight);
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(kMaxHeight, result.target_height());
EXPECT_EQ(std::round(kMaxHeight * kSourceAspectRatio),
result.target_width());
@@ -320,9 +317,9 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsConstrained) {
"kIdealWidth must be less than kMinWidth");
MockConstraintFactory constraint_factory;
constraint_factory.basic().width.SetIdeal(kIdealWidth);
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(std::round(kMinWidth / kSourceAspectRatio),
result.target_height());
EXPECT_EQ(kMinWidth, result.target_width());
@@ -340,9 +337,9 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsConstrained) {
"kIdealWidth must be less than kMaxWidth");
MockConstraintFactory constraint_factory;
constraint_factory.basic().width.SetIdeal(kIdealWidth);
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(std::round(kIdealWidth / kSourceAspectRatio),
result.target_height());
EXPECT_EQ(kIdealWidth, result.target_width());
@@ -358,9 +355,9 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsConstrained) {
"kIdealWidth must be greater than kMaxWidth");
MockConstraintFactory constraint_factory;
constraint_factory.basic().width.SetIdeal(kIdealWidth);
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
// kMaxHeight < kMaxWidth / kNativeAspectRatio
EXPECT_EQ(kMaxHeight, result.target_height());
EXPECT_EQ(kMaxWidth, result.target_width());
@@ -376,9 +373,9 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsConstrained) {
"kIdealAspectRatio must be less than kMinAspectRatio");
MockConstraintFactory constraint_factory;
constraint_factory.basic().aspect_ratio.SetIdeal(kIdealAspectRatio);
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
// Desired point is (kNativeWidth/kMinAspectRatio, kNativeWidth), but it
// is outside the size constraints. Closest to that while maintaining the
// same aspect ratio is (kMaxHeight, kMaxHeight * kMinAspectRatio).
@@ -398,9 +395,9 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsConstrained) {
"kIdealAspectRatio must be less than kMaxAspectRatio");
MockConstraintFactory constraint_factory;
constraint_factory.basic().aspect_ratio.SetIdeal(kIdealAspectRatio);
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(std::round(kSourceWidth / kIdealAspectRatio),
result.target_height());
EXPECT_EQ(kSourceWidth, result.target_width());
@@ -416,9 +413,9 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsConstrained) {
"kIdealAspectRatio must be greater than kMaxAspectRatio");
MockConstraintFactory constraint_factory;
constraint_factory.basic().aspect_ratio.SetIdeal(kIdealAspectRatio);
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(kSourceHeight, result.target_height());
EXPECT_EQ(std::round(kSourceHeight * kMaxAspectRatio),
result.target_width());
@@ -434,9 +431,9 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsConstrained) {
"kIdealFrameRate must be less than kMinFrameRate");
MockConstraintFactory constraint_factory;
constraint_factory.basic().frame_rate.SetIdeal(kIdealFrameRate);
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(kSourceHeight, result.target_height());
EXPECT_EQ(kSourceWidth, result.target_width());
EXPECT_EQ(kMinAspectRatio, result.min_aspect_ratio());
@@ -453,9 +450,9 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsConstrained) {
"kIdealFrameRate must be less than kMaxFrameRate");
MockConstraintFactory constraint_factory;
constraint_factory.basic().frame_rate.SetIdeal(kIdealFrameRate);
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(kSourceHeight, result.target_height());
EXPECT_EQ(kSourceWidth, result.target_width());
EXPECT_EQ(kMinAspectRatio, result.min_aspect_ratio());
@@ -470,9 +467,9 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsConstrained) {
"kIdealFrameRate must be greater than kMaxFrameRate");
MockConstraintFactory constraint_factory;
constraint_factory.basic().frame_rate.SetIdeal(kIdealFrameRate);
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(kSourceHeight, result.target_height());
EXPECT_EQ(kSourceWidth, result.target_width());
EXPECT_EQ(kMinAspectRatio, result.min_aspect_ratio());
@@ -501,9 +498,9 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsConstrained) {
constraint_factory.basic().height.SetIdeal(kIdealHeight);
constraint_factory.basic().width.SetIdeal(kIdealWidth);
constraint_factory.basic().frame_rate.SetIdeal(kIdealFrameRate);
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(kIdealHeight, result.target_height());
EXPECT_EQ(kIdealWidth, result.target_width());
EXPECT_EQ(kMinAspectRatio, result.min_aspect_ratio());
@@ -526,9 +523,9 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsConstrained) {
constraint_factory.basic().height.SetIdeal(kIdealHeight);
constraint_factory.basic().width.SetIdeal(kIdealWidth);
constraint_factory.basic().frame_rate.SetIdeal(kIdealFrameRate);
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(kMaxHeight, result.target_height());
EXPECT_EQ(kMaxWidth, result.target_width());
EXPECT_EQ(kMinAspectRatio, result.min_aspect_ratio());
@@ -540,9 +537,9 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsConstrained) {
{
DoubleRangeSet frame_rate_set(kMinFrameRate, kSourceFrameRate);
MockConstraintFactory constraint_factory;
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(kSourceHeight, result.target_height());
EXPECT_EQ(kSourceWidth, result.target_width());
EXPECT_EQ(kMinAspectRatio, result.min_aspect_ratio());
@@ -559,9 +556,9 @@ TEST_F(MediaStreamConstraintsUtilTest, VideoTrackAdapterSettingsConstrained) {
static_assert(kHighFrameRate > kSourceFrameRate,
"kIdealFrameRate must be greater than kSourceFrameRate");
MockConstraintFactory constraint_factory;
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(kSourceHeight, result.target_height());
EXPECT_EQ(kSourceWidth, result.target_width());
EXPECT_EQ(kMinAspectRatio, result.min_aspect_ratio());
@@ -579,9 +576,9 @@ TEST_F(MediaStreamConstraintsUtilTest,
{
MockConstraintFactory constraint_factory;
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(kSourceHeight, result.target_height());
EXPECT_EQ(kSourceWidth, result.target_width());
EXPECT_EQ(0.0, result.min_aspect_ratio());
@@ -591,9 +588,9 @@ TEST_F(MediaStreamConstraintsUtilTest,
{
MockConstraintFactory constraint_factory;
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(kSourceHeight, result.target_height());
EXPECT_EQ(kSourceWidth, result.target_width());
EXPECT_EQ(0.0, result.min_aspect_ratio());
@@ -613,9 +610,9 @@ TEST_F(MediaStreamConstraintsUtilTest,
// Ideal aspect ratio is ignored if ideal width and height are supplied.
constraint_factory.basic().aspect_ratio.SetIdeal(kIdealAspectRatio);
constraint_factory.basic().frame_rate.SetIdeal(kIdealFrameRate);
- auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
- frame_rate_set);
+ auto result =
+ SelectTrackSettings(constraint_factory.CreateMediaConstraints().Basic(),
+ resolution_set, frame_rate_set);
EXPECT_EQ(kIdealHeight, result.target_height());
EXPECT_EQ(kIdealWidth, result.target_width());
EXPECT_EQ(0.0, result.min_aspect_ratio());
@@ -633,7 +630,7 @@ TEST_F(MediaStreamConstraintsUtilTest,
{
MockConstraintFactory constraint_factory;
auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
+ constraint_factory.CreateMediaConstraints().Basic(), resolution_set,
frame_rate_set, false /* enable_rescale */);
// No target resolution since rescaling is disabled.
EXPECT_FALSE(result.target_size());
@@ -657,7 +654,7 @@ TEST_F(MediaStreamConstraintsUtilTest,
constraint_factory.basic().aspect_ratio.SetIdeal(kIdealAspectRatio);
constraint_factory.basic().frame_rate.SetIdeal(kIdealFrameRate);
auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
+ constraint_factory.CreateMediaConstraints().Basic(), resolution_set,
frame_rate_set, false /* enable_rescale */);
// No target resolution since rescaling is disabled.
EXPECT_FALSE(result.target_size());
@@ -690,7 +687,7 @@ TEST_F(MediaStreamConstraintsUtilTest,
{
MockConstraintFactory constraint_factory;
auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
+ constraint_factory.CreateMediaConstraints().Basic(), resolution_set,
frame_rate_set, false /* enable_rescale */);
// No target size since rescaling is disabled.
EXPECT_FALSE(result.target_size());
@@ -711,7 +708,7 @@ TEST_F(MediaStreamConstraintsUtilTest,
constraint_factory.basic().width.SetIdeal(kIdealWidth);
constraint_factory.basic().frame_rate.SetIdeal(kIdealFrameRate);
auto result = SelectTrackSettings(
- constraint_factory.CreateWebMediaConstraints().Basic(), resolution_set,
+ constraint_factory.CreateMediaConstraints().Basic(), resolution_set,
frame_rate_set, false /* enable_rescale */);
// No target size since rescaling is disabled, despite ideal values.
EXPECT_FALSE(result.target_size());
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.cc
index 56a09ec169a..5b07a0320b9 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.cc
@@ -10,11 +10,11 @@
#include "media/base/limits.h"
#include "third_party/blink/public/common/mediastream/media_stream_controls.h"
-#include "third_party/blink/public/platform/web_media_constraints.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/renderer/modules/mediastream/media_stream_constraints_util.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.h"
+#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
namespace blink {
@@ -57,7 +57,7 @@ class VideoContentCaptureCandidates {
VideoContentCaptureCandidates()
: has_explicit_max_height_(false), has_explicit_max_width_(false) {}
explicit VideoContentCaptureCandidates(
- const WebMediaTrackConstraintSet& constraint_set)
+ const MediaTrackConstraintSetPlatform& constraint_set)
: resolution_set_(ResolutionSet::FromConstraintSet(constraint_set)),
has_explicit_max_height_(ConstraintHasMax(constraint_set.height) &&
ConstraintMax(constraint_set.height) <=
@@ -174,7 +174,7 @@ gfx::Size ToGfxSize(const Point& point) {
double SelectFrameRateFromCandidates(
const DoubleRangeSet& candidate_set,
- const WebMediaTrackConstraintSet& basic_constraint_set,
+ const MediaTrackConstraintSetPlatform& basic_constraint_set,
double default_frame_rate) {
double frame_rate = basic_constraint_set.frame_rate.HasIdeal()
? basic_constraint_set.frame_rate.Ideal()
@@ -189,7 +189,7 @@ double SelectFrameRateFromCandidates(
media::VideoCaptureParams SelectVideoCaptureParamsFromCandidates(
const VideoContentCaptureCandidates& candidates,
- const WebMediaTrackConstraintSet& basic_constraint_set,
+ const MediaTrackConstraintSetPlatform& basic_constraint_set,
int default_height,
int default_width,
double default_frame_rate,
@@ -213,7 +213,7 @@ media::VideoCaptureParams SelectVideoCaptureParamsFromCandidates(
std::string SelectDeviceIDFromCandidates(
const StringSet& candidates,
- const WebMediaTrackConstraintSet& basic_constraint_set) {
+ const MediaTrackConstraintSetPlatform& basic_constraint_set) {
DCHECK(!candidates.IsEmpty());
if (basic_constraint_set.device_id.HasIdeal()) {
// If there are multiple elements specified by ideal, break ties by choosing
@@ -239,7 +239,7 @@ std::string SelectDeviceIDFromCandidates(
base::Optional<bool> SelectNoiseReductionFromCandidates(
const BoolSet& candidates,
- const WebMediaTrackConstraintSet& basic_constraint_set) {
+ const MediaTrackConstraintSetPlatform& basic_constraint_set) {
DCHECK(!candidates.IsEmpty());
if (basic_constraint_set.goog_noise_reduction.HasIdeal() &&
candidates.Contains(basic_constraint_set.goog_noise_reduction.Ideal())) {
@@ -256,7 +256,7 @@ base::Optional<bool> SelectNoiseReductionFromCandidates(
bool SelectRescaleFromCandidates(
const BoolSet& candidates,
- const WebMediaTrackConstraintSet& basic_constraint_set) {
+ const MediaTrackConstraintSetPlatform& basic_constraint_set) {
DCHECK(!candidates.IsEmpty());
if (basic_constraint_set.resize_mode.HasIdeal()) {
for (const auto& ideal_resize_value :
@@ -288,7 +288,7 @@ int ClampToValidScreenCastDimension(int value) {
VideoCaptureSettings SelectResultFromCandidates(
const VideoContentCaptureCandidates& candidates,
- const WebMediaTrackConstraintSet& basic_constraint_set,
+ const MediaTrackConstraintSetPlatform& basic_constraint_set,
mojom::MediaStreamType stream_type,
int screen_width,
int screen_height) {
@@ -357,7 +357,7 @@ VideoCaptureSettings SelectResultFromCandidates(
VideoCaptureSettings UnsatisfiedConstraintsResult(
const VideoContentCaptureCandidates& candidates,
- const WebMediaTrackConstraintSet& constraint_set) {
+ const MediaTrackConstraintSetPlatform& constraint_set) {
DCHECK(candidates.IsEmpty());
if (candidates.resolution_set().IsHeightEmpty()) {
return VideoCaptureSettings(constraint_set.height.GetName());
@@ -380,7 +380,7 @@ VideoCaptureSettings UnsatisfiedConstraintsResult(
} // namespace
VideoCaptureSettings SelectSettingsVideoContentCapture(
- const WebMediaConstraints& constraints,
+ const MediaConstraints& constraints,
mojom::MediaStreamType stream_type,
int screen_width,
int screen_height) {
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.h b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.h
index 96f7c0d8cf8..2f4986c266d 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.h
@@ -10,7 +10,7 @@
namespace blink {
-class WebMediaConstraints;
+class MediaConstraints;
class VideoCaptureSettings;
MODULES_EXPORT extern const int kMinScreenCastDimension;
@@ -24,7 +24,7 @@ MODULES_EXPORT extern const double kDefaultScreenCastFrameRate;
// This function performs source, source-settings and track-settings selection
// for content video capture based on the given |constraints|.
VideoCaptureSettings MODULES_EXPORT
-SelectSettingsVideoContentCapture(const WebMediaConstraints& constraints,
+SelectSettingsVideoContentCapture(const MediaConstraints& constraints,
mojom::MediaStreamType stream_type,
int screen_width,
int screen_height);
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content_test.cc
index cdda70340eb..10935eea372 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content_test.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content_test.cc
@@ -10,9 +10,9 @@
#include "media/base/limits.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h"
-#include "third_party/blink/public/platform/web_media_constraints.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.h"
#include "third_party/blink/renderer/modules/mediastream/mock_constraint_factory.h"
+#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
namespace blink {
@@ -67,8 +67,7 @@ class MediaStreamConstraintsUtilVideoContentTest : public testing::Test {
VideoCaptureSettings SelectSettings(
mojom::MediaStreamType stream_type =
mojom::MediaStreamType::GUM_DESKTOP_VIDEO_CAPTURE) {
- WebMediaConstraints constraints =
- constraint_factory_.CreateWebMediaConstraints();
+ MediaConstraints constraints = constraint_factory_.CreateMediaConstraints();
return SelectSettingsVideoContentCapture(constraints, stream_type,
kDefaultScreenCastWidth,
kDefaultScreenCastHeight);
@@ -189,8 +188,7 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest, OverconstrainedOnFrameRate) {
TEST_F(MediaStreamConstraintsUtilVideoContentTest,
OverconstrainedOnInvalidResizeMode) {
constraint_factory_.Reset();
- constraint_factory_.basic().resize_mode.SetExact(
- WebString::FromASCII("invalid"));
+ constraint_factory_.basic().resize_mode.SetExact("invalid");
auto result = SelectSettings();
EXPECT_FALSE(result.HasValue());
EXPECT_EQ(constraint_factory_.basic().resize_mode.GetName(),
@@ -200,7 +198,7 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest,
TEST_F(MediaStreamConstraintsUtilVideoContentTest,
OverconstrainedOnEmptyResizeMode) {
constraint_factory_.Reset();
- constraint_factory_.basic().resize_mode.SetExact(WebString::FromASCII(""));
+ constraint_factory_.basic().resize_mode.SetExact("");
auto result = SelectSettings();
EXPECT_FALSE(result.HasValue());
EXPECT_EQ(constraint_factory_.basic().resize_mode.GetName(),
@@ -210,13 +208,12 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest,
// The "Mandatory" and "Ideal" tests check that various selection criteria work
// for each individual constraint in the basic constraint set.
TEST_F(MediaStreamConstraintsUtilVideoContentTest, MandatoryDeviceID) {
- const std::string kDeviceID = "Some ID";
+ const String kDeviceID = "Some ID";
constraint_factory_.Reset();
- constraint_factory_.basic().device_id.SetExact(
- WebString::FromASCII(kDeviceID));
+ constraint_factory_.basic().device_id.SetExact(kDeviceID);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
- EXPECT_EQ(kDeviceID, result.device_id());
+ EXPECT_EQ(kDeviceID.Utf8(), result.device_id());
// Other settings should have default values.
EXPECT_EQ(kDefaultScreenCastHeight, result.Height());
EXPECT_EQ(kDefaultScreenCastWidth, result.Width());
@@ -226,21 +223,21 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest, MandatoryDeviceID) {
}
TEST_F(MediaStreamConstraintsUtilVideoContentTest, IdealDeviceID) {
- const std::string kDeviceID = "Some ID";
- const std::string kIdealID = "Ideal ID";
- WebVector<WebString> device_ids(static_cast<size_t>(2));
- device_ids[0] = WebString::FromASCII(kDeviceID);
- device_ids[1] = WebString::FromASCII(kIdealID);
+ const String kDeviceID = "Some ID";
+ const String kIdealID = "Ideal ID";
+ Vector<String> device_ids(static_cast<size_t>(2));
+ device_ids[0] = kDeviceID;
+ device_ids[1] = kIdealID;
constraint_factory_.Reset();
constraint_factory_.basic().device_id.SetExact(device_ids);
- WebVector<WebString> ideal_id(static_cast<size_t>(1));
- ideal_id[0] = WebString::FromASCII(kIdealID);
+ Vector<String> ideal_id(static_cast<size_t>(1));
+ ideal_id[0] = kIdealID;
constraint_factory_.basic().device_id.SetIdeal(ideal_id);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
- EXPECT_EQ(kIdealID, result.device_id());
+ EXPECT_EQ(kIdealID.Utf8(), result.device_id());
// Other settings should have default values.
EXPECT_EQ(kDefaultScreenCastHeight, result.Height());
EXPECT_EQ(kDefaultScreenCastWidth, result.Width());
@@ -1543,8 +1540,7 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest, MandatoryResizeMode) {
constraint_factory_.Reset();
constraint_factory_.basic().width.SetIdeal(kIdealWidth);
constraint_factory_.basic().height.SetIdeal(kIdealHeight);
- constraint_factory_.basic().resize_mode.SetExact(
- WebString::FromASCII("none"));
+ constraint_factory_.basic().resize_mode.SetExact("none");
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
// Screen capture will proceed at 641x480, which will be considered "native".
@@ -1553,8 +1549,7 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest, MandatoryResizeMode) {
EXPECT_EQ(result.Height(), kIdealHeight);
EXPECT_FALSE(result.track_adapter_settings().target_size().has_value());
- constraint_factory_.basic().resize_mode.SetExact(
- WebString::FromASCII("crop-and-scale"));
+ constraint_factory_.basic().resize_mode.SetExact("crop-and-scale");
result = SelectSettings();
EXPECT_TRUE(result.HasValue());
EXPECT_EQ(result.Width(), kIdealWidth);
@@ -1568,7 +1563,8 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest, MandatoryResizeMode) {
TEST_F(MediaStreamConstraintsUtilVideoContentTest,
AdvancedMinMaxResolutionFrameRate) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.width.SetMin(2000000000);
advanced1.height.SetMin(2000000000);
// The first advanced set cannot be satisfied and is therefore ignored in all
@@ -1581,7 +1577,8 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest,
CheckNonResolutionDefaults(result);
CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.height.SetMax(400);
advanced2.width.SetMax(500);
advanced2.aspect_ratio.SetExact(5.0 / 4.0);
@@ -1594,7 +1591,8 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest,
EXPECT_EQ(5.0 / 4.0, result.track_adapter_settings().max_aspect_ratio());
CheckTrackAdapterSettingsEqualsFormat(result);
- WebMediaTrackConstraintSet& advanced3 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced3 =
+ constraint_factory_.AddAdvanced();
advanced3.frame_rate.SetMax(10.0);
result = SelectSettings();
EXPECT_TRUE(result.HasValue());
@@ -1608,7 +1606,8 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest,
EXPECT_EQ(5.0 / 4.0, result.track_adapter_settings().max_aspect_ratio());
CheckTrackAdapterSettingsEqualsFormat(result);
- WebMediaTrackConstraintSet& advanced4 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced4 =
+ constraint_factory_.AddAdvanced();
advanced4.width.SetExact(1000);
advanced4.height.SetExact(1000);
result = SelectSettings();
@@ -1661,10 +1660,12 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest,
TEST_F(MediaStreamConstraintsUtilVideoContentTest, AdvancedExactResolution) {
{
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.width.SetExact(40000000);
advanced1.height.SetExact(40000000);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.width.SetExact(300000000);
advanced2.height.SetExact(300000000);
auto result = SelectSettings();
@@ -1676,7 +1677,8 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest, AdvancedExactResolution) {
CheckNonResolutionDefaults(result);
CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result);
- WebMediaTrackConstraintSet& advanced3 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced3 =
+ constraint_factory_.AddAdvanced();
advanced3.width.SetExact(1920);
advanced3.height.SetExact(1080);
result = SelectSettings();
@@ -1690,7 +1692,8 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest, AdvancedExactResolution) {
result.track_adapter_settings().max_aspect_ratio());
CheckTrackAdapterSettingsEqualsFormat(result);
- WebMediaTrackConstraintSet& advanced4 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced4 =
+ constraint_factory_.AddAdvanced();
advanced4.width.SetExact(640);
advanced4.height.SetExact(480);
result = SelectSettings();
@@ -1725,10 +1728,12 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest, AdvancedExactResolution) {
TEST_F(MediaStreamConstraintsUtilVideoContentTest,
AdvancedResolutionAndFrameRate) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.width.SetExact(1920);
advanced1.height.SetExact(1080);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.frame_rate.SetExact(60.0);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
@@ -1744,10 +1749,12 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest,
TEST_F(MediaStreamConstraintsUtilVideoContentTest, AdvancedNoiseReduction) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.width.SetMin(640);
advanced1.height.SetMin(480);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
const int kMinWidth = 4000;
const int kMinHeight = 2000;
advanced2.width.SetMin(kMinWidth);
@@ -1773,11 +1780,13 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest, AdvancedNoiseReduction) {
TEST_F(MediaStreamConstraintsUtilVideoContentTest,
AdvancedContradictoryNoiseReduction) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.width.SetExact(640);
advanced1.height.SetExact(480);
advanced1.goog_noise_reduction.SetExact(true);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.width.SetExact(1920);
advanced2.height.SetExact(1080);
advanced2.goog_noise_reduction.SetExact(false);
@@ -1794,10 +1803,12 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest,
TEST_F(MediaStreamConstraintsUtilVideoContentTest,
AdvancedContradictoryExactResolution) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.width.SetExact(640);
advanced1.height.SetExact(480);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.width.SetExact(1920);
advanced2.height.SetExact(1080);
auto result = SelectSettings();
@@ -1813,10 +1824,12 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest,
TEST_F(MediaStreamConstraintsUtilVideoContentTest,
AdvancedContradictoryMaxMinResolutionFrameRate) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.width.SetMax(640);
advanced1.height.SetMax(480);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.width.SetMin(1920);
advanced2.height.SetMin(1080);
advanced2.frame_rate.SetExact(60.0);
@@ -1838,10 +1851,12 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest,
const int kMinHeight = 2600;
const int kMinWidth = 2800;
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.width.SetMin(kMinWidth);
advanced1.height.SetMin(kMinHeight);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.width.SetMax(640);
advanced2.height.SetMax(480);
advanced2.frame_rate.SetExact(60.0);
@@ -1861,10 +1876,12 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest,
TEST_F(MediaStreamConstraintsUtilVideoContentTest,
AdvancedContradictoryExactAspectRatio) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
const double kMinAspectRatio = 5.0;
advanced1.aspect_ratio.SetExact(kMinAspectRatio);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.aspect_ratio.SetExact(3.0);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
@@ -1882,10 +1899,12 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest,
TEST_F(MediaStreamConstraintsUtilVideoContentTest,
AdvancedContradictoryAspectRatioRange) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
const double kMinAspectRatio = 5.0;
advanced1.aspect_ratio.SetMin(kMinAspectRatio);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.aspect_ratio.SetMax(3.0);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
@@ -1904,9 +1923,11 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest,
TEST_F(MediaStreamConstraintsUtilVideoContentTest,
AdvancedContradictoryExactFrameRate) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.frame_rate.SetExact(40.0);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.frame_rate.SetExact(45.0);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
@@ -1918,9 +1939,11 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest,
TEST_F(MediaStreamConstraintsUtilVideoContentTest,
AdvancedContradictoryFrameRateRange) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.frame_rate.SetMin(40.0);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.frame_rate.SetMax(35.0);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
@@ -1933,12 +1956,15 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest,
AdvancedContradictoryWidthFrameRate) {
const int kMaxWidth = 1920;
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.width.SetMax(kMaxWidth);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.width.SetMin(2000);
advanced2.frame_rate.SetExact(10.0);
- WebMediaTrackConstraintSet& advanced3 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced3 =
+ constraint_factory_.AddAdvanced();
advanced3.frame_rate.SetExact(90.0);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
@@ -1958,12 +1984,15 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest,
AdvancedContradictoryHeightFrameRate) {
const int kMaxHeight = 2000;
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.height.SetMax(kMaxHeight);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.height.SetMin(4500);
advanced2.frame_rate.SetExact(10.0);
- WebMediaTrackConstraintSet& advanced3 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced3 =
+ constraint_factory_.AddAdvanced();
advanced3.frame_rate.SetExact(60.0);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
@@ -1980,74 +2009,66 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest,
}
TEST_F(MediaStreamConstraintsUtilVideoContentTest, AdvancedDeviceID) {
- const std::string kDeviceID1 = "fake_device_1";
- const std::string kDeviceID2 = "fake_device_2";
- const std::string kDeviceID3 = "fake_device_3";
- const std::string kDeviceID4 = "fake_device_4";
+ const String kDeviceID1 = "fake_device_1";
+ const String kDeviceID2 = "fake_device_2";
+ const String kDeviceID3 = "fake_device_3";
+ const String kDeviceID4 = "fake_device_4";
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
- WebString id_vector1[] = {WebString::FromASCII(kDeviceID1),
- WebString::FromASCII(kDeviceID2)};
- advanced1.device_id.SetExact(
- WebVector<WebString>(id_vector1, base::size(id_vector1)));
- WebString id_vector2[] = {WebString::FromASCII(kDeviceID2),
- WebString::FromASCII(kDeviceID3)};
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
- advanced2.device_id.SetExact(
- WebVector<WebString>(id_vector2, base::size(id_vector2)));
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
+ Vector<String> id_vector1 = {kDeviceID1, kDeviceID2};
+ advanced1.device_id.SetExact(id_vector1);
+ Vector<String> id_vector2 = {kDeviceID2, kDeviceID3};
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
+ advanced2.device_id.SetExact(id_vector2);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
// kDeviceID2 must be selected because it is the only one that satisfies both
// advanced sets.
- EXPECT_EQ(kDeviceID2, result.device_id());
+ EXPECT_EQ(kDeviceID2.Utf8(), result.device_id());
CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result);
}
TEST_F(MediaStreamConstraintsUtilVideoContentTest,
AdvancedContradictoryDeviceID) {
- const std::string kDeviceID1 = "fake_device_1";
- const std::string kDeviceID2 = "fake_device_2";
- const std::string kDeviceID3 = "fake_device_3";
- const std::string kDeviceID4 = "fake_device_4";
+ const String kDeviceID1 = "fake_device_1";
+ const String kDeviceID2 = "fake_device_2";
+ const String kDeviceID3 = "fake_device_3";
+ const String kDeviceID4 = "fake_device_4";
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
- WebString id_vector1[] = {WebString::FromASCII(kDeviceID1),
- WebString::FromASCII(kDeviceID2)};
- advanced1.device_id.SetExact(
- WebVector<WebString>(id_vector1, base::size(id_vector1)));
- WebString id_vector2[] = {WebString::FromASCII(kDeviceID3),
- WebString::FromASCII(kDeviceID4)};
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
- advanced2.device_id.SetExact(
- WebVector<WebString>(id_vector2, base::size(id_vector2)));
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
+ Vector<String> id_vector1 = {kDeviceID1, kDeviceID2};
+ advanced1.device_id.SetExact(id_vector1);
+ Vector<String> id_vector2 = {kDeviceID3, kDeviceID4};
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
+ advanced2.device_id.SetExact(id_vector2);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
// The second advanced set must be ignored because it contradicts the first
// set.
- EXPECT_EQ(std::string(kDeviceID1), result.device_id());
+ EXPECT_EQ(kDeviceID1.Utf8(), result.device_id());
CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result);
}
TEST_F(MediaStreamConstraintsUtilVideoContentTest, AdvancedIdealDeviceID) {
- const std::string kDeviceID1 = "fake_device_1";
- const std::string kDeviceID2 = "fake_device_2";
- const std::string kDeviceID3 = "fake_device_3";
+ const String kDeviceID1 = "fake_device_1";
+ const String kDeviceID2 = "fake_device_2";
+ const String kDeviceID3 = "fake_device_3";
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced = constraint_factory_.AddAdvanced();
- WebString id_vector1[] = {WebString::FromASCII(kDeviceID1),
- WebString::FromASCII(kDeviceID2)};
- advanced.device_id.SetExact(
- WebVector<WebString>(id_vector1, base::size(id_vector1)));
-
- WebString id_vector2[] = {WebString::FromASCII(kDeviceID2),
- WebString::FromASCII(kDeviceID3)};
- constraint_factory_.basic().device_id.SetIdeal(
- WebVector<WebString>(id_vector2, base::size(id_vector2)));
+ MediaTrackConstraintSetPlatform& advanced = constraint_factory_.AddAdvanced();
+ Vector<String> id_vector1 = {kDeviceID1, kDeviceID2};
+ advanced.device_id.SetExact(id_vector1);
+
+ Vector<String> id_vector2 = {kDeviceID2, kDeviceID3};
+ constraint_factory_.basic().device_id.SetIdeal(id_vector2);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
// Should select kDeviceID2, which appears in ideal and satisfies the advanced
// set.
- EXPECT_EQ(std::string(kDeviceID2), result.device_id());
+ EXPECT_EQ(kDeviceID2.Utf8(), result.device_id());
CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result);
}
@@ -2057,8 +2078,8 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest, AdvancedResizeMode) {
constraint_factory_.Reset();
constraint_factory_.basic().width.SetIdeal(kIdealWidth);
constraint_factory_.basic().height.SetIdeal(kIdealHeight);
- WebMediaTrackConstraintSet& advanced = constraint_factory_.AddAdvanced();
- advanced.resize_mode.SetExact(WebString::FromASCII("none"));
+ MediaTrackConstraintSetPlatform& advanced = constraint_factory_.AddAdvanced();
+ advanced.resize_mode.SetExact("none");
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
// Screen capture will proceed at 641x480, which will be considered "native".
@@ -2068,7 +2089,7 @@ TEST_F(MediaStreamConstraintsUtilVideoContentTest, AdvancedResizeMode) {
EXPECT_EQ(result.Height(), kIdealHeight);
EXPECT_FALSE(result.track_adapter_settings().target_size().has_value());
- advanced.resize_mode.SetExact(WebString::FromASCII("crop-and-scale"));
+ advanced.resize_mode.SetExact("crop-and-scale");
result = SelectSettings();
EXPECT_TRUE(result.HasValue());
// Screen capture will proceed at 641x480, which will be considered "native".
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 993a6fe597e..c3dbb578e7a 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
@@ -12,11 +12,11 @@
#include "media/base/limits.h"
#include "media/mojo/mojom/display_media_information.mojom-blink.h"
-#include "third_party/blink/public/platform/web_media_constraints.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/renderer/modules/mediastream/media_stream_constraints_util.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.h"
+#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
namespace blink {
@@ -186,7 +186,7 @@ class CandidateFormat {
// false is returned, and the name of one of the constraints that
// could not be satisfied is returned in |failed_constraint_name| if
// |failed_constraint_name| is not null.
- bool ApplyConstraintSet(const WebMediaTrackConstraintSet& constraint_set,
+ bool ApplyConstraintSet(const MediaTrackConstraintSetPlatform& constraint_set,
const char** failed_constraint_name = nullptr) {
auto rescale_intersection =
rescale_set_.Intersection(media_constraints::RescaleSetFromConstraint(
@@ -253,7 +253,7 @@ class CandidateFormat {
// The track settings that correspond to this fitness are returned on the
// |track_settings| output parameter. The fitness function is based on
// https://w3c.github.io/mediacapture-main/#dfn-fitness-distance.
- double Fitness(const WebMediaTrackConstraintSet& basic_constraint_set,
+ double Fitness(const MediaTrackConstraintSetPlatform& basic_constraint_set,
VideoTrackAdapterSettings* track_settings) const {
DCHECK(!rescale_set_.IsEmpty());
double track_fitness_with_rescale = HUGE_VAL;
@@ -338,7 +338,8 @@ class CandidateFormat {
// the corresponding width, height and frameRate properties.
// This distance is intended to be used to break ties among candidates that
// are equally good according to the standard fitness distance.
- double NativeFitness(const WebMediaTrackConstraintSet& constraint_set) const {
+ double NativeFitness(
+ const MediaTrackConstraintSetPlatform& constraint_set) const {
return NumericRangeNativeFitness(constraint_set.width, MinWidth(),
MaxWidth(), NativeWidth()) +
NumericRangeNativeFitness(constraint_set.height, MinHeight(),
@@ -351,9 +352,10 @@ class CandidateFormat {
bool SatisfiesFrameRateConstraint(const DoubleConstraint& constraint) {
double constraint_min =
ConstraintHasMin(constraint) ? ConstraintMin(constraint) : -1.0;
- double constraint_max = ConstraintHasMax(constraint)
- ? ConstraintMax(constraint)
- : media::limits::kMaxFramesPerSecond;
+ double constraint_max =
+ ConstraintHasMax(constraint)
+ ? ConstraintMax(constraint)
+ : static_cast<double>(media::limits::kMaxFramesPerSecond);
bool constraint_min_out_of_range =
((constraint_min > NativeFrameRate()) ||
(constraint_min > MaxFrameRateConstraint().value_or(
@@ -395,7 +397,7 @@ bool FacingModeSatisfiesConstraint(media::VideoFacingMode value,
const StringConstraint& constraint) {
WebString string_value = ToWebString(value);
if (string_value.IsNull())
- return constraint.Exact().empty();
+ return constraint.Exact().IsEmpty();
return constraint.Matches(string_value);
}
@@ -406,7 +408,7 @@ bool FacingModeSatisfiesConstraint(media::VideoFacingMode value,
// satisfied.
bool DeviceSatisfiesConstraintSet(
const DeviceInfo& device,
- const WebMediaTrackConstraintSet& constraint_set,
+ const MediaTrackConstraintSetPlatform& constraint_set,
const char** failed_constraint_name = nullptr) {
if (!constraint_set.device_id.Matches(WebString(device.device_id))) {
UpdateFailedConstraintName(constraint_set.device_id,
@@ -447,7 +449,7 @@ bool OptionalBoolSatisfiesConstraint(
}
double DeviceFitness(const DeviceInfo& device,
- const WebMediaTrackConstraintSet& constraint_set) {
+ const MediaTrackConstraintSetPlatform& constraint_set) {
return StringConstraintFitnessDistance(WebString(device.device_id),
constraint_set.device_id) +
StringConstraintFitnessDistance(WebString(device.group_id),
@@ -464,7 +466,7 @@ double DeviceFitness(const DeviceInfo& device,
double CandidateFitness(const DeviceInfo& device,
const CandidateFormat& candidate_format,
const base::Optional<bool>& noise_reduction,
- const WebMediaTrackConstraintSet& constraint_set,
+ const MediaTrackConstraintSetPlatform& constraint_set,
VideoTrackAdapterSettings* track_settings) {
return DeviceFitness(device, constraint_set) +
candidate_format.Fitness(constraint_set, track_settings) +
@@ -564,7 +566,7 @@ VideoDeviceCaptureCapabilities& VideoDeviceCaptureCapabilities::operator=(
VideoCaptureSettings SelectSettingsVideoDeviceCapture(
const VideoDeviceCaptureCapabilities& capabilities,
- const WebMediaConstraints& constraints,
+ const MediaConstraints& constraints,
int default_width,
int default_height,
double default_frame_rate) {
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 a6e4d94dee0..4bbaa2f2362 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
@@ -13,8 +13,8 @@
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
+class MediaConstraints;
class WebString;
-class WebMediaConstraints;
} // namespace blink
namespace blink {
@@ -124,7 +124,7 @@ struct MODULES_EXPORT VideoDeviceCaptureCapabilities {
// documentation.
VideoCaptureSettings MODULES_EXPORT SelectSettingsVideoDeviceCapture(
const VideoDeviceCaptureCapabilities& capabilities,
- const WebMediaConstraints& constraints,
+ const MediaConstraints& constraints,
int default_width,
int default_height,
double default_frame_rate);
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 1f7853dc86d..326b787b176 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
@@ -10,9 +10,9 @@
#include "base/optional.h"
#include "media/base/limits.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/web_media_constraints.h"
#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
#include "third_party/blink/renderer/modules/mediastream/mock_constraint_factory.h"
+#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
namespace blink {
@@ -60,7 +60,7 @@ double AspectRatio(const media::VideoCaptureFormat& format) {
VideoCaptureSettings SelectSettingsVideoDeviceCapture(
const VideoDeviceCaptureCapabilities& capabilities,
- const WebMediaConstraints& constraints) {
+ const MediaConstraints& constraints) {
return SelectSettingsVideoDeviceCapture(
capabilities, constraints, MediaStreamVideoSource::kDefaultWidth,
MediaStreamVideoSource::kDefaultHeight,
@@ -180,8 +180,7 @@ class MediaStreamConstraintsUtilVideoDeviceTest : public testing::Test {
protected:
VideoCaptureSettings SelectSettings() {
- WebMediaConstraints constraints =
- constraint_factory_.CreateWebMediaConstraints();
+ MediaConstraints constraints = constraint_factory_.CreateMediaConstraints();
return SelectSettingsVideoDeviceCapture(capabilities_, constraints);
}
@@ -215,8 +214,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, Unconstrained) {
// constraint results in failure to select a candidate.
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, OverconstrainedOnDeviceID) {
constraint_factory_.Reset();
- constraint_factory_.basic().device_id.SetExact(
- WebString::FromASCII("NONEXISTING"));
+ constraint_factory_.basic().device_id.SetExact("NONEXISTING");
auto result = SelectSettings();
EXPECT_FALSE(result.HasValue());
EXPECT_EQ(constraint_factory_.basic().device_id.GetName(),
@@ -225,8 +223,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, OverconstrainedOnDeviceID) {
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, OverconstrainedOnGroupID) {
constraint_factory_.Reset();
- constraint_factory_.basic().group_id.SetExact(
- WebString::FromASCII("NONEXISTING"));
+ constraint_factory_.basic().group_id.SetExact("NONEXISTING");
auto result = SelectSettings();
EXPECT_FALSE(result.HasValue());
EXPECT_EQ(constraint_factory_.basic().group_id.GetName(),
@@ -236,8 +233,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, OverconstrainedOnGroupID) {
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, OverconstrainedOnFacingMode) {
constraint_factory_.Reset();
// No device in |capabilities_| has facing mode equal to LEFT.
- constraint_factory_.basic().facing_mode.SetExact(
- WebString::FromASCII("left"));
+ constraint_factory_.basic().facing_mode.SetExact("left");
auto result = SelectSettings();
EXPECT_FALSE(result.HasValue());
EXPECT_EQ(constraint_factory_.basic().facing_mode.GetName(),
@@ -248,7 +244,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
OverconstrainedOnEmptyFacingMode) {
constraint_factory_.Reset();
// Empty is not a valid facingMode value.
- constraint_factory_.basic().facing_mode.SetExact(WebString::FromASCII(""));
+ constraint_factory_.basic().facing_mode.SetExact("");
auto result = SelectSettings();
EXPECT_FALSE(result.HasValue());
EXPECT_EQ(constraint_factory_.basic().facing_mode.GetName(),
@@ -258,8 +254,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
OverconstrainedOnInvalidResizeMode) {
constraint_factory_.Reset();
- constraint_factory_.basic().resize_mode.SetExact(
- WebString::FromASCII("invalid"));
+ constraint_factory_.basic().resize_mode.SetExact("invalid");
auto result = SelectSettings();
EXPECT_FALSE(result.HasValue());
EXPECT_EQ(constraint_factory_.basic().resize_mode.GetName(),
@@ -269,7 +264,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
OverconstrainedOnEmptyResizeMode) {
constraint_factory_.Reset();
- constraint_factory_.basic().resize_mode.SetExact(WebString::FromASCII(""));
+ constraint_factory_.basic().resize_mode.SetExact("");
auto result = SelectSettings();
EXPECT_FALSE(result.HasValue());
EXPECT_EQ(constraint_factory_.basic().resize_mode.GetName(),
@@ -279,8 +274,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, OverconstrainedOnVideoKind) {
constraint_factory_.Reset();
// No device in |capabilities_| has video kind infrared.
- constraint_factory_.basic().video_kind.SetExact(
- WebString::FromASCII("infrared"));
+ constraint_factory_.basic().video_kind.SetExact("infrared");
auto result = SelectSettings();
EXPECT_FALSE(result.HasValue());
EXPECT_EQ(constraint_factory_.basic().video_kind.GetName(),
@@ -400,7 +394,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
constraint_factory_.Reset();
constraint_factory_.basic().goog_noise_reduction.SetExact(true);
- auto constraints = constraint_factory_.CreateWebMediaConstraints();
+ auto constraints = constraint_factory_.CreateMediaConstraints();
auto result = SelectSettingsVideoDeviceCapture(capabilities, constraints);
EXPECT_FALSE(result.HasValue());
EXPECT_EQ(constraint_factory_.basic().goog_noise_reduction.GetName(),
@@ -411,23 +405,20 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
// for each individual constraint in the basic constraint set.
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryDeviceID) {
constraint_factory_.Reset();
- constraint_factory_.basic().device_id.SetExact(
- WebString(default_device_->device_id));
+ constraint_factory_.basic().device_id.SetExact(default_device_->device_id);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
EXPECT_EQ(default_device_->device_id.Utf8(), result.device_id());
EXPECT_EQ(*default_closest_format_, result.Format());
CheckTrackAdapterSettingsEqualsFormat(result);
- constraint_factory_.basic().device_id.SetExact(
- WebString(low_res_device_->device_id));
+ constraint_factory_.basic().device_id.SetExact(low_res_device_->device_id);
result = SelectSettings();
EXPECT_EQ(low_res_device_->device_id.Utf8(), result.device_id());
EXPECT_EQ(*low_res_closest_format_, result.Format());
CheckTrackAdapterSettingsEqualsFormat(result);
- constraint_factory_.basic().device_id.SetExact(
- WebString(high_res_device_->device_id));
+ constraint_factory_.basic().device_id.SetExact(high_res_device_->device_id);
result = SelectSettings();
EXPECT_EQ(high_res_device_->device_id.Utf8(), result.device_id());
EXPECT_EQ(*high_res_closest_format_, result.Format());
@@ -436,23 +427,20 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryDeviceID) {
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryGroupID) {
constraint_factory_.Reset();
- constraint_factory_.basic().group_id.SetExact(
- WebString(default_device_->group_id));
+ constraint_factory_.basic().group_id.SetExact(default_device_->group_id);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
EXPECT_EQ(default_device_->device_id.Utf8(), result.device_id());
EXPECT_EQ(*default_closest_format_, result.Format());
CheckTrackAdapterSettingsEqualsFormat(result);
- constraint_factory_.basic().group_id.SetExact(
- WebString(low_res_device_->group_id));
+ constraint_factory_.basic().group_id.SetExact(low_res_device_->group_id);
result = SelectSettings();
EXPECT_EQ(low_res_device_->device_id.Utf8(), result.device_id());
EXPECT_EQ(*low_res_closest_format_, result.Format());
CheckTrackAdapterSettingsEqualsFormat(result);
- constraint_factory_.basic().group_id.SetExact(
- WebString(high_res_device_->group_id));
+ constraint_factory_.basic().group_id.SetExact(high_res_device_->group_id);
result = SelectSettings();
EXPECT_EQ(high_res_device_->device_id.Utf8(), result.device_id());
EXPECT_EQ(*high_res_closest_format_, result.Format());
@@ -461,8 +449,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryGroupID) {
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryFacingMode) {
constraint_factory_.Reset();
- constraint_factory_.basic().facing_mode.SetExact(
- WebString::FromASCII("environment"));
+ constraint_factory_.basic().facing_mode.SetExact("environment");
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
// Only the low-res device supports environment facing mode. Should select
@@ -473,8 +460,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryFacingMode) {
EXPECT_EQ(*low_res_closest_format_, result.Format());
CheckTrackAdapterSettingsEqualsFormat(result);
- constraint_factory_.basic().facing_mode.SetExact(
- WebString::FromASCII("user"));
+ constraint_factory_.basic().facing_mode.SetExact("user");
result = SelectSettings();
EXPECT_TRUE(result.HasValue());
// Only the high-res device supports user facing mode. Should select default
@@ -487,16 +473,14 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryFacingMode) {
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryVideoKind) {
constraint_factory_.Reset();
- constraint_factory_.basic().video_kind.SetExact(
- WebString::FromASCII("depth"));
+ constraint_factory_.basic().video_kind.SetExact("depth");
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
EXPECT_EQ(kDeviceID4, result.device_id());
EXPECT_EQ(media::PIXEL_FORMAT_Y16, result.Format().pixel_format);
CheckTrackAdapterSettingsEqualsFormat(result);
- constraint_factory_.basic().video_kind.SetExact(
- WebString::FromASCII("color"));
+ constraint_factory_.basic().video_kind.SetExact("color");
result = SelectSettings();
EXPECT_TRUE(result.HasValue());
EXPECT_EQ(default_device_->device_id.Utf8(), result.device_id());
@@ -1688,8 +1672,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryResizeMode) {
constraint_factory_.Reset();
constraint_factory_.basic().width.SetIdeal(kIdealWidth);
constraint_factory_.basic().height.SetIdeal(kIdealHeight);
- constraint_factory_.basic().resize_mode.SetExact(
- WebString::FromASCII("none"));
+ constraint_factory_.basic().resize_mode.SetExact("none");
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
// A native mode of 640x480 should be selected since it is closest native mode
@@ -1698,8 +1681,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryResizeMode) {
EXPECT_EQ(result.Height(), 480);
EXPECT_FALSE(result.track_adapter_settings().target_size().has_value());
- constraint_factory_.basic().resize_mode.SetExact(
- WebString::FromASCII("crop-and-scale"));
+ constraint_factory_.basic().resize_mode.SetExact("crop-and-scale");
result = SelectSettings();
EXPECT_TRUE(result.HasValue());
EXPECT_GE(result.Width(), kIdealWidth);
@@ -1710,8 +1692,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryResizeMode) {
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, IdealResizeMode) {
constraint_factory_.Reset();
- constraint_factory_.basic().resize_mode.SetIdeal(
- WebString::FromASCII("crop-and-scale"));
+ constraint_factory_.basic().resize_mode.SetIdeal("crop-and-scale");
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
// Since no constraints are given, the default device with resolution closest
@@ -1743,8 +1724,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
EXPECT_EQ(result.Height(), 480);
EXPECT_FALSE(result.track_adapter_settings().target_size().has_value());
- constraint_factory_.basic().resize_mode.SetIdeal(
- WebString::FromASCII("crop-and-scale"));
+ constraint_factory_.basic().resize_mode.SetIdeal("crop-and-scale");
result = SelectSettings();
EXPECT_TRUE(result.HasValue());
EXPECT_GE(result.Width(), kIdealWidth);
@@ -1771,8 +1751,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
EXPECT_EQ(result.Height(), 480);
EXPECT_FALSE(result.track_adapter_settings().target_size().has_value());
- constraint_factory_.basic().resize_mode.SetIdeal(
- WebString::FromASCII("crop-and-scale"));
+ constraint_factory_.basic().resize_mode.SetIdeal("crop-and-scale");
result = SelectSettings();
EXPECT_TRUE(result.HasValue());
// Rescaling is preferred, therefore a native mode greater than the ideal
@@ -1823,8 +1802,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, TwoIdealResizeValues) {
constraint_factory_.Reset();
constraint_factory_.basic().width.SetIdeal(641);
constraint_factory_.basic().height.SetIdeal(481);
- constraint_factory_.basic().resize_mode.SetIdeal(WebVector<WebString>(
- {WebString::FromASCII("none"), WebString::FromASCII("crop-and-scale")}));
+ constraint_factory_.basic().resize_mode.SetIdeal({"none", "crop-and-scale"});
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
// 800x600 rescaled to 641x481 is closest to the specified ideal values.
@@ -1838,8 +1816,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, TwoIdealResizeValues) {
EXPECT_EQ(result.track_adapter_settings().target_height(), 481);
constraint_factory_.Reset();
- constraint_factory_.basic().resize_mode.SetIdeal(WebVector<WebString>(
- {WebString::FromASCII("none"), WebString::FromASCII("crop-and-scale")}));
+ constraint_factory_.basic().resize_mode.SetIdeal({"none", "crop-and-scale"});
result = SelectSettings();
EXPECT_TRUE(result.HasValue());
// Given that both resize modes are ideal, the default device with the
@@ -1855,7 +1832,8 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, TwoIdealResizeValues) {
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
AdvancedMinMaxResolutionFrameRate) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.width.SetMin(4000);
advanced1.height.SetMin(4000);
// No device supports the first advanced set. This first advanced constraint
@@ -1866,7 +1844,8 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
EXPECT_EQ(*default_closest_format_, result.Format());
CheckTrackAdapterSettingsEqualsFormat(result);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.width.SetMin(320);
advanced2.height.SetMin(240);
advanced2.width.SetMax(640);
@@ -1882,7 +1861,8 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
EXPECT_EQ(640.0 / 240.0, result.track_adapter_settings().max_aspect_ratio());
CheckTrackAdapterSettingsEqualsFrameRate(result);
- WebMediaTrackConstraintSet& advanced3 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced3 =
+ constraint_factory_.AddAdvanced();
advanced3.frame_rate.SetMax(10.0);
result = SelectSettings();
EXPECT_TRUE(result.HasValue());
@@ -1896,7 +1876,8 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
EXPECT_EQ(640.0 / 240.0, result.track_adapter_settings().max_aspect_ratio());
CheckTrackAdapterSettingsEqualsFrameRate(result, 10.0);
- WebMediaTrackConstraintSet& advanced4 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced4 =
+ constraint_factory_.AddAdvanced();
advanced4.width.SetMax(1000);
advanced4.height.SetMax(1000);
result = SelectSettings();
@@ -1951,12 +1932,15 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
AdvancedResolutionAndFrameRate) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.width.SetExact(1920);
advanced1.height.SetExact(1080);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.frame_rate.SetExact(60.0);
- WebMediaTrackConstraintSet& advanced3 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced3 =
+ constraint_factory_.AddAdvanced();
advanced3.width.SetExact(2304);
advanced3.height.SetExact(1536);
auto result = SelectSettings();
@@ -1979,10 +1963,12 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, AdvancedNoiseReduction) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.width.SetMin(640);
advanced1.height.SetMin(480);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.width.SetMin(1920);
advanced2.height.SetMin(1080);
advanced2.goog_noise_reduction.SetExact(false);
@@ -2004,11 +1990,13 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
AdvancedContradictoryNoiseReduction) {
{
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.width.SetMin(640);
advanced1.height.SetMin(480);
advanced1.goog_noise_reduction.SetExact(true);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.width.SetMin(1920);
advanced2.height.SetMin(1080);
advanced2.goog_noise_reduction.SetExact(false);
@@ -2032,10 +2020,12 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
// Same test without noise reduction
{
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.width.SetMin(640);
advanced1.height.SetMin(480);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.width.SetMin(1920);
advanced2.height.SetMin(1080);
auto result = SelectSettings();
@@ -2058,10 +2048,12 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
AdvancedContradictoryExactResolution) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.width.SetExact(640);
advanced1.height.SetExact(480);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.width.SetExact(1920);
advanced2.height.SetExact(1080);
auto result = SelectSettings();
@@ -2081,10 +2073,12 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
AdvancedContradictoryMaxMinResolutionFrameRate) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.width.SetMax(640);
advanced1.height.SetMax(480);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.width.SetMin(1920);
advanced2.height.SetMin(1080);
advanced2.frame_rate.SetExact(60.0);
@@ -2108,10 +2102,12 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
AdvancedContradictoryMinMaxResolutionFrameRate) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.width.SetMin(800);
advanced1.height.SetMin(600);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.width.SetMax(640);
advanced2.height.SetMax(480);
advanced2.frame_rate.SetExact(60.0);
@@ -2136,9 +2132,11 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
AdvancedContradictoryExactAspectRatio) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.aspect_ratio.SetExact(2300.0);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.aspect_ratio.SetExact(3.0);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
@@ -2159,9 +2157,11 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
AdvancedContradictoryAspectRatioRange) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.aspect_ratio.SetMin(2300.0);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.aspect_ratio.SetMax(3.0);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
@@ -2182,9 +2182,11 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
AdvancedContradictoryExactFrameRate) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.frame_rate.SetExact(40.0);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.frame_rate.SetExact(45.0);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
@@ -2198,9 +2200,11 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
AdvancedContradictoryFrameRateRange) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.frame_rate.SetMin(40.0);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.frame_rate.SetMax(35.0);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
@@ -2214,12 +2218,15 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
AdvancedContradictoryWidthFrameRate) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.width.SetMax(1920);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.width.SetMin(2000);
advanced2.frame_rate.SetExact(10.0);
- WebMediaTrackConstraintSet& advanced3 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced3 =
+ constraint_factory_.AddAdvanced();
advanced3.frame_rate.SetExact(30.0);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
@@ -2235,12 +2242,15 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
AdvancedContradictoryHeightFrameRate) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.height.SetMax(1080);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.height.SetMin(1500);
advanced2.frame_rate.SetExact(10.0);
- WebMediaTrackConstraintSet& advanced3 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced3 =
+ constraint_factory_.AddAdvanced();
advanced3.frame_rate.SetExact(60.0);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
@@ -2256,16 +2266,14 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, AdvancedDeviceID) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
- WebString id_vector1[] = {WebString::FromASCII(kDeviceID1),
- WebString::FromASCII(kDeviceID2)};
- advanced1.device_id.SetExact(
- WebVector<WebString>(id_vector1, base::size(id_vector1)));
- WebString id_vector2[] = {WebString::FromASCII(kDeviceID2),
- WebString::FromASCII(kDeviceID3)};
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
- advanced2.device_id.SetExact(
- WebVector<WebString>(id_vector2, base::size(id_vector2)));
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
+ Vector<String> id_vector1 = {kDeviceID1, kDeviceID2};
+ advanced1.device_id.SetExact(id_vector1);
+ Vector<String> id_vector2 = {kDeviceID2, kDeviceID3};
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
+ advanced2.device_id.SetExact(id_vector2);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
// kDeviceID2 must be selected because it is the only one that satisfies both
@@ -2276,16 +2284,14 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, AdvancedDeviceID) {
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, AdvancedGroupID) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
- WebString id_vector1[] = {WebString::FromASCII(kGroupID1),
- WebString::FromASCII(kGroupID2)};
- advanced1.group_id.SetExact(
- WebVector<WebString>(id_vector1, base::size(id_vector1)));
- WebString id_vector2[] = {WebString::FromASCII(kGroupID2),
- WebString::FromASCII(kGroupID3)};
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
- advanced2.group_id.SetExact(
- WebVector<WebString>(id_vector2, base::size(id_vector2)));
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
+ Vector<String> id_vector1 = {kGroupID1, kGroupID2};
+ advanced1.group_id.SetExact(id_vector1);
+ Vector<String> id_vector2 = {kGroupID2, kGroupID3};
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
+ advanced2.group_id.SetExact(id_vector2);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
// The device with group_id kGroupID2 must be selected because it is the only
@@ -2297,16 +2303,14 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, AdvancedGroupID) {
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
AdvancedContradictoryDeviceID) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
- WebString id_vector1[] = {WebString::FromASCII(kDeviceID1),
- WebString::FromASCII(kDeviceID2)};
- advanced1.device_id.SetExact(
- WebVector<WebString>(id_vector1, base::size(id_vector1)));
- WebString id_vector2[] = {WebString::FromASCII(kDeviceID3),
- WebString::FromASCII(kDeviceID4)};
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
- advanced2.device_id.SetExact(
- WebVector<WebString>(id_vector2, base::size(id_vector2)));
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
+ Vector<String> id_vector1 = {kDeviceID1, kDeviceID2};
+ advanced1.device_id.SetExact(id_vector1);
+ Vector<String> id_vector2 = {kDeviceID3, kDeviceID4};
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
+ advanced2.device_id.SetExact(id_vector2);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
// The second advanced set must be ignored because it contradicts the first
@@ -2318,15 +2322,18 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
AdvancedContradictoryDeviceIDAndResolution) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
- advanced1.device_id.SetExact({WebString(low_res_device_->device_id)});
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
+ advanced1.device_id.SetExact({low_res_device_->device_id});
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
- advanced2.device_id.SetExact({WebString(high_res_device_->device_id)});
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
+ advanced2.device_id.SetExact({high_res_device_->device_id});
advanced2.width.SetMax(50);
advanced2.height.SetMax(50);
- WebMediaTrackConstraintSet& advanced3 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced3 =
+ constraint_factory_.AddAdvanced();
advanced3.width.SetExact(800);
advanced3.height.SetExact(600);
@@ -2343,16 +2350,14 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
AdvancedContradictoryGroupID) {
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
- WebString id_vector1[] = {WebString::FromASCII(kGroupID1),
- WebString::FromASCII(kGroupID2)};
- advanced1.group_id.SetExact(
- WebVector<WebString>(id_vector1, base::size(id_vector1)));
- WebString id_vector2[] = {WebString::FromASCII(kGroupID3),
- WebString::FromASCII(kGroupID4)};
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
- advanced2.group_id.SetExact(
- WebVector<WebString>(id_vector2, base::size(id_vector2)));
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
+ Vector<String> id_vector1 = {kGroupID1, kGroupID2};
+ advanced1.group_id.SetExact(id_vector1);
+ Vector<String> id_vector2 = {kGroupID3, kGroupID4};
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
+ advanced2.group_id.SetExact(id_vector2);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
// The second advanced set must be ignored because it contradicts the first
@@ -2365,9 +2370,11 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
AdvancedContradictoryAspectRatioWidth) {
{
constraint_factory_.Reset();
- WebMediaTrackConstraintSet& advanced1 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced1 =
+ constraint_factory_.AddAdvanced();
advanced1.aspect_ratio.SetMin(17);
- WebMediaTrackConstraintSet& advanced2 = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced2 =
+ constraint_factory_.AddAdvanced();
advanced2.width.SetMax(1);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
@@ -2390,9 +2397,9 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, AdvancedResize) {
constraint_factory_.Reset();
constraint_factory_.basic().width.SetIdeal(1);
constraint_factory_.basic().height.SetIdeal(1);
- WebMediaTrackConstraintSet& advanced = constraint_factory_.AddAdvanced();
+ MediaTrackConstraintSetPlatform& advanced = constraint_factory_.AddAdvanced();
- advanced.resize_mode.SetExact(WebString::FromASCII("none"));
+ advanced.resize_mode.SetExact("none");
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
// The native mode closest to 1x1 is 40x30 with the low-res device.
@@ -2411,8 +2418,8 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
// This advanced set must be ignored because there are no native resolutions
// with width equal to 639.
- WebMediaTrackConstraintSet& advanced = constraint_factory_.AddAdvanced();
- advanced.resize_mode.SetExact(WebString::FromASCII("none"));
+ MediaTrackConstraintSetPlatform& advanced = constraint_factory_.AddAdvanced();
+ advanced.resize_mode.SetExact("none");
advanced.frame_rate.SetExact(19.0);
auto result = SelectSettings();
@@ -2459,7 +2466,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, NoDevicesNoConstraints) {
constraint_factory_.Reset();
VideoDeviceCaptureCapabilities capabilities;
auto result = SelectSettingsVideoDeviceCapture(
- capabilities, constraint_factory_.CreateWebMediaConstraints());
+ capabilities, constraint_factory_.CreateMediaConstraints());
EXPECT_FALSE(result.HasValue());
EXPECT_TRUE(std::string(result.failed_constraint_name()).empty());
}
@@ -2469,7 +2476,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, NoDevicesWithConstraints) {
constraint_factory_.basic().height.SetExact(100);
VideoDeviceCaptureCapabilities capabilities;
auto result = SelectSettingsVideoDeviceCapture(
- capabilities, constraint_factory_.CreateWebMediaConstraints());
+ capabilities, constraint_factory_.CreateMediaConstraints());
EXPECT_FALSE(result.HasValue());
EXPECT_TRUE(std::string(result.failed_constraint_name()).empty());
}
@@ -2479,7 +2486,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, NoDevicesWithConstraints) {
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, InvalidFrameRateDevice) {
constraint_factory_.Reset();
constraint_factory_.basic().device_id.SetExact(
- WebString(invalid_frame_rate_device_->device_id));
+ invalid_frame_rate_device_->device_id);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
EXPECT_EQ(invalid_frame_rate_device_->device_id.Utf8(), result.device_id());
@@ -2505,8 +2512,7 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, InvalidFrameRateDevice) {
// the actual default resolution.
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, InvertedDefaultResolution) {
constraint_factory_.Reset();
- constraint_factory_.basic().device_id.SetExact(
- WebString(high_res_device_->device_id));
+ constraint_factory_.basic().device_id.SetExact(high_res_device_->device_id);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
EXPECT_EQ(high_res_device_->device_id.Utf8(), result.device_id());
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 b4563f7e736..6ef3e5b0c43 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
@@ -11,7 +11,6 @@
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "third_party/blink/public/platform/interface_registry.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/user_media_processor.h"
@@ -42,15 +41,13 @@ struct MediaStreamDeviceObserver::Stream {
MediaStreamDevices video_devices;
};
-MediaStreamDeviceObserver::MediaStreamDeviceObserver(WebLocalFrame* frame) {
+MediaStreamDeviceObserver::MediaStreamDeviceObserver(LocalFrame* frame) {
// There is no frame on unit tests.
- if (!frame)
- return;
- static_cast<LocalFrame*>(WebFrame::ToCoreFrame(*frame))
- ->GetInterfaceRegistry()
- ->AddInterface(WTF::BindRepeating(
- &MediaStreamDeviceObserver::BindMediaStreamDeviceObserverReceiver,
- WTF::Unretained(this)));
+ if (frame) {
+ frame->GetInterfaceRegistry()->AddInterface(WTF::BindRepeating(
+ &MediaStreamDeviceObserver::BindMediaStreamDeviceObserverReceiver,
+ WTF::Unretained(this)));
+ }
}
MediaStreamDeviceObserver::~MediaStreamDeviceObserver() {}
@@ -135,9 +132,6 @@ void MediaStreamDeviceObserver::OnDeviceChanged(
void MediaStreamDeviceObserver::BindMediaStreamDeviceObserverReceiver(
mojo::PendingReceiver<mojom::blink::MediaStreamDeviceObserver> receiver) {
- if (receiver_.is_bound())
- return;
-
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 cf4477650a1..3e844ab1a70 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
@@ -23,15 +23,15 @@
#include "third_party/blink/renderer/modules/modules_export.h"
namespace blink {
+class LocalFrame;
class UserMediaProcessor;
-class WebLocalFrame;
// This class implements a Mojo object that receives device stopped
// notifications and forwards them to UserMediaProcessor.
class MODULES_EXPORT MediaStreamDeviceObserver
: public mojom::blink::MediaStreamDeviceObserver {
public:
- explicit MediaStreamDeviceObserver(WebLocalFrame* frame);
+ explicit MediaStreamDeviceObserver(LocalFrame* frame);
~MediaStreamDeviceObserver() override;
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 4d46f726544..f7f7d15d361 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(blink::Visitor* visitor) {
+void MediaStreamEvent::Trace(Visitor* visitor) {
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 b2a4ac61bd3..f07e7876b68 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
@@ -25,9 +25,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_MEDIA_STREAM_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_MEDIA_STREAM_EVENT_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_stream_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
-#include "third_party/blink/renderer/modules/mediastream/media_stream_event_init.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
namespace blink {
@@ -48,7 +48,7 @@ class MediaStreamEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<MediaStream> stream_;
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_event.idl b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_event.idl
index 9f63d4f46d9..68ea235f382 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_event.idl
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_event.idl
@@ -27,8 +27,8 @@
// https://www.w3.org/TR/2015/WD-webrtc-20150210/#mediastreamevent
[
- Exposed=Window,
- Constructor(DOMString type, optional MediaStreamEventInit eventInitDict)
+ Exposed=Window
] interface MediaStreamEvent : Event {
+ constructor(DOMString type, optional MediaStreamEventInit eventInitDict = {});
readonly attribute 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 ba821fb5309..8fe3372c884 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
@@ -6,7 +6,6 @@
#include <utility>
-#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.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.h"
@@ -17,6 +16,7 @@
#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/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"
@@ -39,6 +39,10 @@ base::UnguessableToken GetSessionIdForWebRtcAudioRenderer() {
: base::UnguessableToken();
}
+void SendLogMessage(const WTF::String& message) {
+ WebRtcLogMessage("MSRFI::" + message.Utf8());
+}
+
} // namespace
std::unique_ptr<WebMediaStreamRendererFactory>
@@ -78,15 +82,23 @@ MediaStreamRendererFactoryImpl::GetAudioRenderer(
WebLocalFrame* web_frame,
const WebString& device_id) {
DCHECK(!web_stream.IsNull());
+ 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()) {
- WebRtcLogMessage("No audio tracks in media stream (return null).");
+ // 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()) {
+ SendLogMessage(String::Format(
+ "%s => (ERROR: no audio tracks in media stream)", __func__));
+ }
return nullptr;
}
- DVLOG(1) << "MediaStreamRendererFactoryImpl::GetAudioRenderer stream:"
- << web_stream.Id().Utf8();
-
// TODO(tommi): We need to fix the data flow so that
// it works the same way for all track implementations, local, remote or what
// have you.
@@ -99,7 +111,8 @@ MediaStreamRendererFactoryImpl::GetAudioRenderer(
if (!audio_track) {
// This can happen if the track was cloned.
// TODO(tommi, perkj): Fix cloning of tracks to handle extra data too.
- WebRtcLogMessage("Error: No native track for WebMediaStreamTrack");
+ SendLogMessage(String::Format(
+ "%s => (ERROR: no native track for WebMediaStreamTrack)", __func__));
return nullptr;
}
@@ -108,9 +121,10 @@ MediaStreamRendererFactoryImpl::GetAudioRenderer(
if (!PeerConnectionRemoteAudioTrack::From(audio_track)) {
// TODO(xians): Add support for the case where the media stream contains
// multiple audio tracks.
- DVLOG(1) << "Creating TrackAudioRenderer for "
- << (audio_track->is_local_track() ? "local" : "remote")
- << " track.";
+ SendLogMessage(String::Format(
+ "%s => (creating TrackAudioRenderer for %s audio track)", __func__,
+ audio_track->is_local_track() ? "local" : "remote"));
+
return new TrackAudioRenderer(audio_tracks[0], web_frame,
/*session_id=*/base::UnguessableToken(),
String(device_id));
@@ -120,13 +134,19 @@ MediaStreamRendererFactoryImpl::GetAudioRenderer(
WebRtcAudioDeviceImpl* audio_device =
PeerConnectionDependencyFactory::GetInstance()->GetWebRtcAudioDevice();
DCHECK(audio_device);
-
+ SendLogMessage(String::Format(
+ "%s => (media stream is a remote WebRTC stream)", __func__));
// Share the existing renderer if any, otherwise create a new one.
scoped_refptr<WebRtcAudioRenderer> renderer(audio_device->renderer());
+
if (renderer) {
- DVLOG(1) << "Using existing WebRtcAudioRenderer for remote WebRTC track.";
+ SendLogMessage(String::Format(
+ "%s => (using existing WebRtcAudioRenderer for remote stream)",
+ __func__));
} else {
- DVLOG(1) << "Creating WebRtcAudioRenderer for remote WebRTC track.";
+ SendLogMessage(String::Format(
+ "%s => (creating new WebRtcAudioRenderer for remote stream)",
+ __func__));
renderer = new WebRtcAudioRenderer(
PeerConnectionDependencyFactory::GetInstance()
@@ -135,14 +155,17 @@ MediaStreamRendererFactoryImpl::GetAudioRenderer(
device_id.Utf8());
if (!audio_device->SetAudioRenderer(renderer.get())) {
- WebRtcLogMessage("Error: SetAudioRenderer failed for remote track.");
+ SendLogMessage(String::Format(
+ "%s => (ERROR: WRADI::SetAudioRenderer failed)", __func__));
return nullptr;
}
}
auto ret = renderer->CreateSharedAudioRendererProxy(web_stream);
- if (!ret)
- WebRtcLogMessage("Error: CreateSharedAudioRendererProxy failed.");
+ if (!ret) {
+ SendLogMessage(String::Format(
+ "%s => (ERROR: CreateSharedAudioRendererProxy failed)", __func__));
+ }
return ret;
}
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 4e3f20ae5f3..fa66ec9af41 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
@@ -27,10 +27,15 @@
#include <memory>
+#include "base/strings/stringprintf.h"
+#include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.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/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_capabilities.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_constraints.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_settings.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/events/event.h"
@@ -41,9 +46,6 @@
#include "third_party/blink/renderer/modules/mediastream/media_constraints_impl.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_utils.h"
-#include "third_party/blink/renderer/modules/mediastream/media_track_capabilities.h"
-#include "third_party/blink/renderer/modules/mediastream/media_track_constraints.h"
-#include "third_party/blink/renderer/modules/mediastream/media_track_settings.h"
#include "third_party/blink/renderer/modules/mediastream/overconstrained_error.h"
#include "third_party/blink/renderer/modules/mediastream/user_media_controller.h"
#include "third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.h"
@@ -67,6 +69,10 @@ static const char kContentHintStringVideoMotion[] = "motion";
static const char kContentHintStringVideoDetail[] = "detail";
static const char kContentHintStringVideoText[] = "text";
+void SendLogMessage(const std::string& message) {
+ blink::WebRtcLogMessage("MST::" + message);
+}
+
// The set of constrainable properties for image capture is available at
// https://w3c.github.io/mediacapture-image/#constrainable-properties
// TODO(guidou): Integrate image-capture constraints processing with the
@@ -209,11 +215,6 @@ void DidCloneMediaStreamTrack(const WebMediaStreamTrack& original,
} // namespace
-MediaStreamTrack* MediaStreamTrack::Create(ExecutionContext* context,
- MediaStreamComponent* component) {
- return MakeGarbageCollected<MediaStreamTrack>(context, component);
-}
-
MediaStreamTrack::MediaStreamTrack(ExecutionContext* context,
MediaStreamComponent* component)
: MediaStreamTrack(context,
@@ -226,6 +227,7 @@ MediaStreamTrack::MediaStreamTrack(ExecutionContext* context,
: ready_state_(ready_state),
component_(component),
execution_context_(context) {
+ SendLogMessage(GetTrackLogString());
component_->Source()->AddObserver(this);
// If the source is already non-live at this point, the observer won't have
@@ -242,6 +244,16 @@ MediaStreamTrack::MediaStreamTrack(ExecutionContext* context,
MediaStreamTrack::~MediaStreamTrack() = default;
+std::string MediaStreamTrack::GetTrackLogString() const {
+ String str = String::Format(
+ "MediaStreamTrack([kind: %s, id: %s, label: %s, enabled: %s, muted: %s, "
+ "readyState: %s])",
+ kind().Utf8().c_str(), id().Utf8().c_str(), label().Utf8().c_str(),
+ enabled() ? "true" : "false", muted() ? "true" : "false",
+ readyState().Utf8().c_str());
+ return str.Utf8();
+}
+
String MediaStreamTrack::kind() const {
DEFINE_STATIC_LOCAL(String, audio_kind, ("audio"));
DEFINE_STATIC_LOCAL(String, video_kind, ("video"));
@@ -270,6 +282,9 @@ bool MediaStreamTrack::enabled() const {
}
void MediaStreamTrack::setEnabled(bool enabled) {
+ SendLogMessage(base::StringPrintf("setEnabled([id=%s] {enabled=%s})",
+ id().Utf8().c_str(),
+ enabled ? "true" : "false"));
if (enabled == component_->Enabled())
return;
@@ -305,6 +320,8 @@ String MediaStreamTrack::ContentHint() const {
}
void MediaStreamTrack::SetContentHint(const String& hint) {
+ SendLogMessage(base::StringPrintf("SetContentHint([id=%s] {hint=%s})",
+ id().Utf8().c_str(), hint.Utf8().c_str()));
WebMediaStreamTrack::ContentHintType translated_hint =
WebMediaStreamTrack::ContentHintType::kNone;
switch (component_->Source()->GetType()) {
@@ -361,11 +378,12 @@ String MediaStreamTrack::readyState() const {
}
void MediaStreamTrack::stopTrack(ExecutionContext* execution_context) {
+ SendLogMessage(base::StringPrintf("stopTrack([id=%s])", id().Utf8().c_str()));
if (Ended())
return;
ready_state_ = MediaStreamSource::kReadyStateEnded;
- Document* document = To<Document>(execution_context);
+ Document* document = Document::From(execution_context);
UserMediaController* user_media =
UserMediaController::From(document->GetFrame());
if (user_media)
@@ -382,7 +400,7 @@ MediaStreamTrack* MediaStreamTrack::clone(ScriptState* script_state) {
return cloned_track;
}
-void MediaStreamTrack::SetConstraints(const WebMediaConstraints& constraints) {
+void MediaStreamTrack::SetConstraints(const MediaConstraints& constraints) {
component_->SetConstraints(constraints);
}
@@ -634,7 +652,7 @@ ScriptPromise MediaStreamTrack::applyConstraints(
MediaErrorState error_state;
ExecutionContext* execution_context = ExecutionContext::From(script_state);
- WebMediaConstraints web_constraints = media_constraints_impl::Create(
+ MediaConstraints web_constraints = media_constraints_impl::Create(
execution_context, constraints, error_state);
if (error_state.HadException()) {
resolver->Reject(
@@ -674,7 +692,7 @@ ScriptPromise MediaStreamTrack::applyConstraints(
return promise;
}
- Document* document = To<Document>(execution_context);
+ Document* document = Document::From(execution_context);
UserMediaController* user_media =
UserMediaController::From(document->GetFrame());
if (!user_media) {
@@ -724,6 +742,9 @@ void MediaStreamTrack::SourceChangedState() {
PropagateTrackEnded();
break;
}
+ SendLogMessage(
+ base::StringPrintf("SourceChangedState([id=%s] {readyState=%s})",
+ id().Utf8().c_str(), readyState().Utf8().c_str()));
}
void MediaStreamTrack::PropagateTrackEnded() {
@@ -781,7 +802,7 @@ ExecutionContext* MediaStreamTrack::GetExecutionContext() const {
return execution_context_.Get();
}
-void MediaStreamTrack::Trace(blink::Visitor* visitor) {
+void MediaStreamTrack::Trace(Visitor* visitor) {
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 fe0be2d87f2..5652168de8f 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
@@ -54,8 +54,6 @@ class MODULES_EXPORT MediaStreamTrack
DEFINE_WRAPPERTYPEINFO();
public:
- static MediaStreamTrack* Create(ExecutionContext*, MediaStreamComponent*);
-
MediaStreamTrack(ExecutionContext*, MediaStreamComponent*);
MediaStreamTrack(ExecutionContext*,
MediaStreamComponent*,
@@ -81,7 +79,7 @@ class MODULES_EXPORT MediaStreamTrack
// This function is called when constrains have been successfully applied.
// Called from UserMediaRequest when it succeeds. It is not IDL-exposed.
- void SetConstraints(const WebMediaConstraints&);
+ void SetConstraints(const MediaConstraints&);
MediaTrackCapabilities* getCapabilities() const;
MediaTrackConstraints* getConstraints() const;
@@ -108,7 +106,7 @@ class MODULES_EXPORT MediaStreamTrack
std::unique_ptr<AudioSourceProvider> CreateWebAudioSource(
int context_sample_rate);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
friend class CanvasCaptureMediaStreamTrack;
@@ -120,6 +118,8 @@ class MODULES_EXPORT MediaStreamTrack
void applyConstraintsImageCapture(ScriptPromiseResolver*,
const MediaTrackConstraints*);
+ std::string GetTrackLogString() const;
+
MediaStreamSource::ReadyState ready_state_;
HeapHashSet<Member<MediaStream>> registered_media_streams_;
bool is_iterating_registered_media_streams_ = false;
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.idl b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.idl
index 8a1e2a4476e..fac1a9cf83d 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.idl
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.idl
@@ -30,6 +30,7 @@ enum MediaStreamTrackState {
"ended"
};
+// https://w3c.github.io/mediacapture-main/#media-stream-track-interface-definition
[
Exposed=Window,
ActiveScriptWrappable
@@ -50,5 +51,5 @@ enum MediaStreamTrackState {
MediaTrackCapabilities getCapabilities();
MediaTrackConstraints getConstraints();
MediaTrackSettings getSettings();
- [CallWith=ScriptState] Promise<void> applyConstraints(optional MediaTrackConstraints constraints);
+ [CallWith=ScriptState] Promise<void> applyConstraints(optional MediaTrackConstraints constraints = {});
};
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 7b368b3fc16..115f3981d52 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(blink::Visitor* visitor) {
+void MediaStreamTrackEvent::Trace(Visitor* visitor) {
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 1c501ac262d..152deed005d 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
@@ -25,8 +25,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_MEDIA_STREAM_TRACK_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_MEDIA_STREAM_TRACK_EVENT_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_stream_track_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
-#include "third_party/blink/renderer/modules/mediastream/media_stream_track_event_init.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
namespace blink {
@@ -51,7 +51,7 @@ class MediaStreamTrackEvent final : public Event {
// Event
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<MediaStreamTrack> track_;
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_event.idl b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_event.idl
index 0d0f4471945..f2f2350e0e6 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_event.idl
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_event.idl
@@ -26,8 +26,8 @@
// https://w3c.github.io/mediacapture-main/#mediastreamtrackevent
[
- Exposed=Window,
- Constructor(DOMString type, MediaStreamTrackEventInit eventInitDict)
+ Exposed=Window
] interface MediaStreamTrackEvent : Event {
+ constructor(DOMString type, MediaStreamTrackEventInit eventInitDict);
[SameObject] readonly attribute 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 c8f392a4c3e..52957ccf554 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
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/modules/mediastream/media_stream_utils.h"
+#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.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"
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 c653e920863..87fab684cfc 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
@@ -7,6 +7,7 @@
#include <utility>
#include "base/bind.h"
+#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "media/base/bind_to_current_loop.h"
#include "mojo/public/cpp/bindings/remote.h"
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 69d4a697e0e..ce9215d3568 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
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "media/base/video_frame.h"
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_source_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_source_test.cc
index e4d6f7e906c..b855dc1b2be 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_source_test.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_source_test.cc
@@ -5,6 +5,7 @@
#include <string>
#include <utility>
+#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
@@ -160,7 +161,7 @@ class MediaStreamVideoSourceTest : public testing::Test {
MockMediaStreamVideoSink* sink) {
base::RunLoop run_loop;
base::OnceClosure quit_closure = run_loop.QuitClosure();
- EXPECT_CALL(*sink, OnVideoFrame()).WillOnce([&]() {
+ EXPECT_CALL(*sink, OnVideoFrame).WillOnce([&](base::TimeTicks) {
std::move(quit_closure).Run();
});
scoped_refptr<media::VideoFrame> frame =
@@ -183,8 +184,8 @@ class MediaStreamVideoSourceTest : public testing::Test {
MockMediaStreamVideoSink* sink2) {
base::RunLoop run_loop;
base::OnceClosure quit_closure = run_loop.QuitClosure();
- EXPECT_CALL(*sink1, OnVideoFrame());
- EXPECT_CALL(*sink2, OnVideoFrame()).WillOnce([&]() {
+ EXPECT_CALL(*sink1, OnVideoFrame);
+ EXPECT_CALL(*sink2, OnVideoFrame).WillOnce([&](base::TimeTicks) {
std::move(quit_closure).Run();
});
scoped_refptr<media::VideoFrame> frame =
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 d9f70a4fffc..2d8308c9c13 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
@@ -19,6 +19,7 @@
#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/vector.h"
namespace blink {
namespace {
@@ -122,9 +123,8 @@ class MediaStreamVideoTrack::FrameDeliverer
using VideoIdCallbackPair =
std::pair<VideoSinkId, VideoCaptureDeliverFrameInternalCallback>;
- std::vector<VideoIdCallbackPair> callbacks_;
- WTF::HashMap<VideoSinkId, EncodedVideoFrameInternalCallback>
- encoded_callbacks_;
+ Vector<VideoIdCallbackPair> callbacks_;
+ HashMap<VideoSinkId, EncodedVideoFrameInternalCallback> encoded_callbacks_;
bool await_next_key_frame_;
DISALLOW_COPY_AND_ASSIGN(FrameDeliverer);
@@ -149,7 +149,7 @@ MediaStreamVideoTrack::FrameDeliverer::FrameDeliverer(
}
MediaStreamVideoTrack::FrameDeliverer::~FrameDeliverer() {
- DCHECK(callbacks_.empty());
+ DCHECK(callbacks_.IsEmpty());
}
void MediaStreamVideoTrack::FrameDeliverer::AddCallback(
@@ -203,7 +203,7 @@ void MediaStreamVideoTrack::FrameDeliverer::RemoveCallbackOnIO(
VideoSinkId id,
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
- auto it = callbacks_.begin();
+ auto* it = callbacks_.begin();
for (; it != callbacks_.end(); ++it) {
if (it->first == id) {
// Callback destruction needs to happen on the specified task runner.
@@ -494,7 +494,8 @@ void MediaStreamVideoTrack::AddEncodedSink(WebMediaStreamSink* sink,
DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_);
AddSinkInternal(&encoded_sinks_, sink);
frame_deliverer_->AddEncodedCallback(sink, std::move(callback));
- source_->UpdateNumEncodedSinks();
+ if (source_)
+ source_->UpdateNumEncodedSinks();
UpdateSourceHasConsumers();
}
@@ -514,7 +515,8 @@ void MediaStreamVideoTrack::RemoveEncodedSink(WebMediaStreamSink* sink) {
DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_);
RemoveSinkInternal(&encoded_sinks_, sink);
frame_deliverer_->RemoveEncodedCallback(sink);
- source_->UpdateNumEncodedSinks();
+ if (source_)
+ source_->UpdateNumEncodedSinks();
UpdateSourceHasConsumers();
}
@@ -532,13 +534,16 @@ void MediaStreamVideoTrack::SetEnabled(bool enabled) {
// need a new keyframe from the source as we may have dropped data making the
// stream undecodable.
bool maybe_await_key_frame = false;
- if (enabled && source_->SupportsEncodedOutput() && !encoded_sinks_.empty()) {
+ if (enabled && source_ && source_->SupportsEncodedOutput() &&
+ !encoded_sinks_.empty()) {
source_->RequestRefreshFrame();
maybe_await_key_frame = true;
}
frame_deliverer_->SetEnabled(enabled, maybe_await_key_frame);
for (auto* sink : sinks_)
sink->OnEnabledChanged(enabled);
+ for (auto* encoded_sink : encoded_sinks_)
+ encoded_sink->OnEnabledChanged(enabled);
}
size_t MediaStreamVideoTrack::CountEncodedSinks() const {
@@ -551,6 +556,8 @@ void MediaStreamVideoTrack::SetContentHint(
DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_);
for (auto* sink : sinks_)
sink->OnContentHintChanged(content_hint);
+ for (auto* encoded_sink : encoded_sinks_)
+ encoded_sink->OnContentHintChanged(content_hint);
}
void MediaStreamVideoTrack::StopAndNotify(base::OnceClosure callback) {
@@ -611,6 +618,8 @@ void MediaStreamVideoTrack::OnReadyStateChanged(
DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_);
for (auto* sink : sinks_)
sink->OnReadyStateChanged(state);
+ for (auto* encoded_sink : encoded_sinks_)
+ encoded_sink->OnReadyStateChanged(state);
}
void MediaStreamVideoTrack::SetTrackAdapterSettings(
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_track_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_track_test.cc
index 1c21cf381ac..cc1be0c8326 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_track_test.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_track_test.cc
@@ -7,9 +7,11 @@
#include <utility>
#include "base/callback.h"
+#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind_test_util.h"
+#include "base/test/gmock_callback_support.h"
#include "base/threading/thread_checker.h"
#include "media/base/video_frame.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -27,21 +29,22 @@ namespace blink {
// To avoid symbol collisions in jumbo builds.
namespace media_stream_video_track_test {
+using base::test::RunOnceClosure;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::Mock;
using ::testing::Return;
+using ::testing::Values;
+
+using ContentHintType = WebMediaStreamTrack::ContentHintType;
const uint8_t kBlackValue = 0x00;
const uint8_t kColorValue = 0xAB;
const int kMockSourceWidth = 640;
const int kMockSourceHeight = 480;
-ACTION_P(RunClosure, closure) {
- closure.Run();
-}
-
-class MediaStreamVideoTrackTest : public testing::Test {
+class MediaStreamVideoTrackTest
+ : public testing::TestWithParam<ContentHintType> {
public:
MediaStreamVideoTrackTest() : mock_source_(nullptr), source_started_(false) {}
@@ -57,8 +60,8 @@ class MediaStreamVideoTrackTest : public testing::Test {
MockMediaStreamVideoSink* sink) {
base::RunLoop run_loop;
base::RepeatingClosure quit_closure = run_loop.QuitClosure();
- EXPECT_CALL(*sink, OnVideoFrame())
- .WillOnce(RunClosure(std::move(quit_closure)));
+ EXPECT_CALL(*sink, OnVideoFrame)
+ .WillOnce(RunOnceClosure(std::move(quit_closure)));
mock_source()->DeliverVideoFrame(std::move(frame));
run_loop.Run();
}
@@ -67,9 +70,9 @@ class MediaStreamVideoTrackTest : public testing::Test {
MockMediaStreamVideoSink* sink) {
base::RunLoop run_loop;
base::RepeatingClosure quit_closure = run_loop.QuitClosure();
- EXPECT_CALL(*sink, OnEncodedVideoFrame).WillOnce(Invoke([&] {
- std::move(quit_closure).Run();
- }));
+ EXPECT_CALL(*sink, OnEncodedVideoFrame)
+ .WillOnce(
+ Invoke([&](base::TimeTicks) { std::move(quit_closure).Run(); }));
mock_source()->DeliverEncodedVideoFrame(frame);
run_loop.Run();
}
@@ -251,6 +254,22 @@ TEST_F(MediaStreamVideoTrackTest, SetEnabled) {
sink.DisconnectFromTrack();
}
+TEST_F(MediaStreamVideoTrackTest, SourceDetached) {
+ InitializeSource();
+ WebMediaStreamTrack track = CreateTrack();
+ MockMediaStreamVideoSink sink;
+ auto* video_track = MediaStreamVideoTrack::GetVideoTrack(track);
+ video_track->StopAndNotify(base::BindOnce([] {}));
+ sink.ConnectToTrack(track);
+ sink.ConnectEncodedToTrack(track);
+ video_track->SetEnabled(true);
+ video_track->SetEnabled(false);
+ WebMediaStreamTrack::Settings settings;
+ video_track->GetSettings(settings);
+ sink.DisconnectFromTrack();
+ sink.DisconnectEncodedFromTrack();
+}
+
TEST_F(MediaStreamVideoTrackTest, SourceStopped) {
InitializeSource();
MockMediaStreamVideoSink sink;
@@ -304,8 +323,8 @@ TEST_F(MediaStreamVideoTrackTest, CheckTrackRequestsFrame) {
MockMediaStreamVideoSink sink;
base::RunLoop run_loop;
base::RepeatingClosure quit_closure = run_loop.QuitClosure();
- EXPECT_CALL(sink, OnVideoFrame())
- .WillOnce(RunClosure(std::move(quit_closure)));
+ EXPECT_CALL(sink, OnVideoFrame)
+ .WillOnce(RunOnceClosure(std::move(quit_closure)));
sink.ConnectToTrack(track);
run_loop.Run();
EXPECT_EQ(1, sink.number_of_frames());
@@ -385,6 +404,16 @@ TEST_F(MediaStreamVideoTrackTest, DeliverFramesAndGetSettings) {
sink.DisconnectFromTrack();
}
+TEST_P(MediaStreamVideoTrackTest, PropagatesContentHintType) {
+ InitializeSource();
+ MockMediaStreamVideoSink sink;
+ WebMediaStreamTrack track = CreateTrack();
+ sink.ConnectToTrack(track);
+ MediaStreamVideoTrack::GetVideoTrack(track)->SetContentHint(GetParam());
+ EXPECT_EQ(sink.content_hint(), GetParam());
+ sink.DisconnectFromTrack();
+}
+
class MediaStreamVideoTrackEncodedTest : public MediaStreamVideoTrackTest {
public:
void InitializeSource() override {
@@ -441,7 +470,7 @@ TEST_F(MediaStreamVideoTrackEncodedTest, TransferOneEncodedVideoFrame) {
sink.ConnectEncodedToTrack(track);
base::RunLoop run_loop;
base::RepeatingClosure quit_closure = run_loop.QuitClosure();
- EXPECT_CALL(sink, OnEncodedVideoFrame).WillOnce(Invoke([&] {
+ EXPECT_CALL(sink, OnEncodedVideoFrame).WillOnce(Invoke([&](base::TimeTicks) {
std::move(quit_closure).Run();
}));
mock_source()->DeliverEncodedVideoFrame(
@@ -466,6 +495,7 @@ TEST_F(MediaStreamVideoTrackEncodedTest, SupportsEncodedDisableEnable) {
// Key frame when disabled -> shouldn't get dispatched
MediaStreamVideoTrack::GetVideoTrack(track)->SetEnabled(false);
+ EXPECT_FALSE(sink.enabled());
{
EXPECT_CALL(sink, OnEncodedVideoFrame).Times(0);
mock_source()->DeliverEncodedVideoFrame(key_frame);
@@ -476,6 +506,7 @@ TEST_F(MediaStreamVideoTrackEncodedTest, SupportsEncodedDisableEnable) {
// appears.
EXPECT_CALL(*mock_source(), OnRequestRefreshFrame);
MediaStreamVideoTrack::GetVideoTrack(track)->SetEnabled(true);
+ EXPECT_TRUE(sink.enabled());
{
EXPECT_CALL(sink, OnEncodedVideoFrame).Times(0);
mock_source()->DeliverEncodedVideoFrame(delta_frame);
@@ -490,5 +521,39 @@ TEST_F(MediaStreamVideoTrackEncodedTest, SupportsEncodedDisableEnable) {
sink.DisconnectEncodedFromTrack();
}
+TEST_P(MediaStreamVideoTrackEncodedTest, PropagatesContentHintType) {
+ InitializeSource();
+ MockMediaStreamVideoSink sink;
+ WebMediaStreamTrack track = CreateTrack();
+ sink.ConnectEncodedToTrack(track);
+ MediaStreamVideoTrack::GetVideoTrack(track)->SetContentHint(GetParam());
+ EXPECT_EQ(sink.content_hint(), GetParam());
+ sink.DisconnectEncodedFromTrack();
+}
+
+TEST_F(MediaStreamVideoTrackEncodedTest, SourceStopped) {
+ InitializeSource();
+ MockMediaStreamVideoSink sink;
+ WebMediaStreamTrack track = CreateTrack();
+ sink.ConnectEncodedToTrack(track);
+ EXPECT_EQ(WebMediaStreamSource::kReadyStateLive, sink.state());
+
+ mock_source()->StopSource();
+ EXPECT_EQ(WebMediaStreamSource::kReadyStateEnded, sink.state());
+ sink.DisconnectEncodedFromTrack();
+}
+
+INSTANTIATE_TEST_SUITE_P(,
+ MediaStreamVideoTrackTest,
+ Values(ContentHintType::kVideoMotion,
+ ContentHintType::kVideoDetail,
+ ContentHintType::kVideoText));
+
+INSTANTIATE_TEST_SUITE_P(,
+ MediaStreamVideoTrackEncodedTest,
+ Values(ContentHintType::kVideoMotion,
+ ContentHintType::kVideoDetail,
+ ContentHintType::kVideoText));
+
} // namespace media_stream_video_track_test
} // namespace blink
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 64ec4749ca1..3368c0a8254 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
@@ -54,6 +54,6 @@ dictionary MediaTrackConstraintSet {
ConstrainBoolean torch;
// The "mandatory" and "_optional" members are retained for conformance
// with https://www.w3.org/TR/2013/WD-mediacapture-streams-20130903/
- Dictionary mandatory;
- sequence<Dictionary> _optional;
+ object mandatory;
+ sequence<object> _optional;
};
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/mock_constraint_factory.cc b/chromium/third_party/blink/renderer/modules/mediastream/mock_constraint_factory.cc
index ee68d856669..62de962d581 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/mock_constraint_factory.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/mock_constraint_factory.cc
@@ -14,13 +14,13 @@ MockConstraintFactory::MockConstraintFactory() {}
MockConstraintFactory::~MockConstraintFactory() {}
-WebMediaTrackConstraintSet& MockConstraintFactory::AddAdvanced() {
+MediaTrackConstraintSetPlatform& MockConstraintFactory::AddAdvanced() {
advanced_.emplace_back();
return advanced_.back();
}
-WebMediaConstraints MockConstraintFactory::CreateWebMediaConstraints() const {
- WebMediaConstraints constraints;
+MediaConstraints MockConstraintFactory::CreateMediaConstraints() const {
+ MediaConstraints constraints;
constraints.Initialize(basic_, advanced_);
return constraints;
}
@@ -41,7 +41,7 @@ void MockConstraintFactory::DisableAecAudioConstraints() {
}
void MockConstraintFactory::Reset() {
- basic_ = WebMediaTrackConstraintSet();
+ basic_ = MediaTrackConstraintSetPlatform();
advanced_.clear();
}
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/mock_constraint_factory.h b/chromium/third_party/blink/renderer/modules/mediastream/mock_constraint_factory.h
index c4f96a88a2c..27457d9ae8a 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/mock_constraint_factory.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/mock_constraint_factory.h
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_MOCK_CONSTRAINT_FACTORY_H_
#include "base/macros.h"
-#include "third_party/blink/public/platform/web_media_constraints.h"
+#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
@@ -18,17 +18,17 @@ class MockConstraintFactory {
MockConstraintFactory();
~MockConstraintFactory();
- WebMediaConstraints CreateWebMediaConstraints() const;
- WebMediaTrackConstraintSet& basic() { return basic_; }
- WebMediaTrackConstraintSet& AddAdvanced();
+ MediaConstraints CreateMediaConstraints() const;
+ MediaTrackConstraintSetPlatform& basic() { return basic_; }
+ MediaTrackConstraintSetPlatform& AddAdvanced();
void DisableDefaultAudioConstraints();
void DisableAecAudioConstraints();
void Reset();
private:
- WebMediaTrackConstraintSet basic_;
- Vector<WebMediaTrackConstraintSet> advanced_;
+ MediaTrackConstraintSetPlatform basic_;
+ Vector<MediaTrackConstraintSetPlatform> advanced_;
DISALLOW_COPY_AND_ASSIGN(MockConstraintFactory);
};
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 f3b62ce4b15..1d451a6d42c 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
@@ -6,6 +6,7 @@
#include <memory>
+#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"
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_video_sink.cc b/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_video_sink.cc
index 7351a1ced5d..36c31d02b23 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_video_sink.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_video_sink.cc
@@ -37,13 +37,13 @@ void MockMediaStreamVideoSink::DeliverVideoFrame(
format_ = frame->format();
frame_size_ = frame->natural_size();
last_frame_ = std::move(frame);
- OnVideoFrame();
+ OnVideoFrame(estimated_capture_time);
}
void MockMediaStreamVideoSink::DeliverEncodedVideoFrame(
scoped_refptr<EncodedVideoFrame> frame,
base::TimeTicks estimated_capture_time) {
- OnEncodedVideoFrame();
+ OnEncodedVideoFrame(estimated_capture_time);
}
void MockMediaStreamVideoSink::OnReadyStateChanged(
@@ -55,4 +55,9 @@ void MockMediaStreamVideoSink::OnEnabledChanged(bool enabled) {
enabled_ = enabled;
}
+void MockMediaStreamVideoSink::OnContentHintChanged(
+ WebMediaStreamTrack::ContentHintType content_hint) {
+ content_hint_ = content_hint;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_video_sink.h b/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_video_sink.h
index ea7c7022c90..9d92deb05e6 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_video_sink.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_video_sink.h
@@ -38,11 +38,13 @@ class MockMediaStreamVideoSink : public MediaStreamVideoSink {
void OnReadyStateChanged(WebMediaStreamSource::ReadyState state) override;
void OnEnabledChanged(bool enabled) override;
+ void OnContentHintChanged(
+ WebMediaStreamTrack::ContentHintType content_hint) override;
// Triggered when OnVideoFrame(scoped_refptr<media::VideoFrame> frame)
// is called.
- MOCK_METHOD0(OnVideoFrame, void());
- MOCK_METHOD0(OnEncodedVideoFrame, void());
+ MOCK_METHOD1(OnVideoFrame, void(base::TimeTicks));
+ MOCK_METHOD1(OnEncodedVideoFrame, void(base::TimeTicks));
VideoCaptureDeliverFrameCB GetDeliverFrameCB();
EncodedVideoFrameCB GetDeliverEncodedVideoFrameCB();
@@ -54,6 +56,9 @@ class MockMediaStreamVideoSink : public MediaStreamVideoSink {
bool enabled() const { return enabled_; }
WebMediaStreamSource::ReadyState state() const { return state_; }
+ base::Optional<WebMediaStreamTrack::ContentHintType> content_hint() const {
+ return content_hint_;
+ }
private:
void DeliverVideoFrame(scoped_refptr<media::VideoFrame> frame,
@@ -67,6 +72,7 @@ class MockMediaStreamVideoSink : public MediaStreamVideoSink {
WebMediaStreamSource::ReadyState state_;
gfx::Size frame_size_;
scoped_refptr<media::VideoFrame> last_frame_;
+ base::Optional<WebMediaStreamTrack::ContentHintType> content_hint_;
base::WeakPtrFactory<MockMediaStreamVideoSink> weak_factory_{this};
};
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/navigator_media_stream.cc b/chromium/third_party/blink/renderer/modules/mediastream/navigator_media_stream.cc
index 1dba754a5b8..f1658e54be6 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/navigator_media_stream.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/navigator_media_stream.cc
@@ -24,6 +24,7 @@
#include "third_party/blink/renderer/modules/mediastream/navigator_media_stream.h"
#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_navigator_user_media_error_callback.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_navigator_user_media_success_callback.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -32,7 +33,6 @@
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/modules/mediastream/media_error_state.h"
-#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints.h"
#include "third_party/blink/renderer/modules/mediastream/user_media_controller.h"
#include "third_party/blink/renderer/modules/mediastream/user_media_request.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -59,8 +59,8 @@ void NavigatorMediaStream::getUserMedia(
MediaErrorState error_state;
UserMediaRequest* request = UserMediaRequest::Create(
- navigator.GetFrame()->GetDocument(), user_media, options,
- success_callback, error_callback, error_state);
+ navigator.GetFrame()->GetDocument()->ToExecutionContext(), user_media,
+ options, success_callback, error_callback, error_state);
if (!request) {
DCHECK(error_state.HadException());
if (error_state.CanGenerateException()) {
@@ -74,7 +74,7 @@ void NavigatorMediaStream::getUserMedia(
String error_message;
if (!request->IsSecureContextUse(error_message)) {
- request->Fail(WebUserMediaRequest::Error::kSecurityError, error_message);
+ request->Fail(UserMediaRequest::Error::kSecurityError, error_message);
return;
}
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 35e49dd02ba..79d02b24132 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
@@ -15,8 +15,9 @@ namespace blink {
NavigatorUserMedia::NavigatorUserMedia(Navigator& navigator)
: Supplement<Navigator>(navigator),
media_devices_(MakeGarbageCollected<MediaDevices>(
- navigator.GetFrame() ? navigator.GetFrame()->GetDocument()
- : nullptr)) {}
+ navigator.GetFrame()
+ ? navigator.GetFrame()->GetDocument()->ToExecutionContext()
+ : nullptr)) {}
const char NavigatorUserMedia::kSupplementName[] = "NavigatorUserMedia";
@@ -38,7 +39,7 @@ MediaDevices* NavigatorUserMedia::mediaDevices(Navigator& navigator) {
return NavigatorUserMedia::From(navigator).GetMediaDevices();
}
-void NavigatorUserMedia::Trace(blink::Visitor* visitor) {
+void NavigatorUserMedia::Trace(Visitor* visitor) {
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 c7a9a2dec05..1c81f3619a1 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
MediaDevices* GetMediaDevices();
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/overconstrained_error.idl b/chromium/third_party/blink/renderer/modules/mediastream/overconstrained_error.idl
index 328a7686787..e9a43800e0a 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/overconstrained_error.idl
+++ b/chromium/third_party/blink/renderer/modules/mediastream/overconstrained_error.idl
@@ -6,9 +6,8 @@
// TODO(guidou): OverconstrainedError should be an Error subclass and not an
// interface. http://crbug.com/769726
-[
- Constructor(DOMString constraint, DOMString message)
-] interface OverconstrainedError {
+interface OverconstrainedError {
+ constructor(DOMString constraint, DOMString message);
readonly attribute DOMString name;
readonly attribute DOMString? message;
readonly attribute DOMString? constraint;
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 45785bf8b04..f7e09d9c37b 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
@@ -20,9 +20,10 @@
#include "third_party/blink/public/mojom/mediastream/media_stream.mojom-blink.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/web/web_local_frame.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_audio_processor.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.h"
-#include "third_party/blink/renderer/modules/mediastream/media_stream_local_frame_wrapper.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/platform/mediastream/audio_service_audio_processor_proxy.h"
@@ -36,11 +37,26 @@ using EchoCancellationType =
blink::AudioProcessingProperties::EchoCancellationType;
namespace {
+
+void SendLogMessage(const std::string& message) {
+ blink::WebRtcLogMessage("PLAS::" + message);
+}
+
// Used as an identifier for ProcessedLocalAudioSource::From().
void* const kProcessedLocalAudioSourceIdentifier =
const_cast<void**>(&kProcessedLocalAudioSourceIdentifier);
-void LogAudioProcesingProperties(
+std::string GetEnsureSourceIsStartedLogString(
+ const blink::MediaStreamDevice& device) {
+ return base::StringPrintf(
+ "EnsureSourceIsStarted({session_id=%s}, {channel_layout=%d}, "
+ "{sample_rate=%d}, {buffer_size=%d}, {effects=%d})",
+ device.session_id().ToString().c_str(), device.input.channel_layout(),
+ device.input.sample_rate(), device.input.frames_per_buffer(),
+ device.input.effects());
+}
+
+std::string GetAudioProcesingPropertiesLogString(
const blink::AudioProcessingProperties& properties) {
auto aec_to_string =
[](blink::AudioProcessingProperties::EchoCancellationType type) {
@@ -56,18 +72,17 @@ void LogAudioProcesingProperties(
};
auto bool_to_string = [](bool value) { return value ? "true" : "false"; };
auto str = base::StringPrintf(
- "AudioProcessingProperties: "
- "aec=%s, "
- "disable_hw_ns=%s, "
- "goog_audio_mirroring=%s, "
- "goog_auto_gain_control=%s, "
- "goog_experimental_echo_cancellation=%s, "
- "goog_typing_noise_detection=%s, "
- "goog_noise_suppression=%s, "
- "goog_experimental_noise_suppression=%s, "
- "goog_highpass_filter=%s, "
- "goog_experimental_agc=%s, "
- "hybrid_agc=%s",
+ "aec: %s, "
+ "disable_hw_ns: %s, "
+ "goog_audio_mirroring: %s, "
+ "goog_auto_gain_control: %s, "
+ "goog_experimental_echo_cancellation: %s, "
+ "goog_typing_noise_detection: %s, "
+ "goog_noise_suppression: %s, "
+ "goog_experimental_noise_suppression: %s, "
+ "goog_highpass_filter: %s, "
+ "goog_experimental_agc: %s, "
+ "hybrid_agc: %s",
aec_to_string(properties.echo_cancellation_type),
bool_to_string(properties.disable_hw_noise_suppression),
bool_to_string(properties.goog_audio_mirroring),
@@ -79,13 +94,12 @@ void LogAudioProcesingProperties(
bool_to_string(properties.goog_highpass_filter),
bool_to_string(properties.goog_experimental_auto_gain_control),
bool_to_string(base::FeatureList::IsEnabled(features::kWebRtcHybridAgc)));
-
- blink::WebRtcLogMessage(str);
+ return str;
}
} // namespace
ProcessedLocalAudioSource::ProcessedLocalAudioSource(
- WebLocalFrame* web_frame,
+ LocalFrame* frame,
const blink::MediaStreamDevice& device,
bool disable_local_echo,
const blink::AudioProcessingProperties& audio_processing_properties,
@@ -94,18 +108,19 @@ ProcessedLocalAudioSource::ProcessedLocalAudioSource(
: blink::MediaStreamAudioSource(std::move(task_runner),
true /* is_local_source */,
disable_local_echo),
- internal_consumer_frame_(
- std::make_unique<MediaStreamInternalFrameWrapper>(web_frame)),
+ consumer_frame_(frame),
audio_processing_properties_(audio_processing_properties),
started_callback_(std::move(started_callback)),
volume_(0),
allow_invalid_render_frame_id_for_testing_(false) {
- DVLOG(1) << "ProcessedLocalAudioSource::ProcessedLocalAudioSource()";
SetDevice(device);
+ SendLogMessage(
+ base::StringPrintf("ProcessedLocalAudioSource({session_id=%s})",
+ device.session_id().ToString().c_str()));
}
ProcessedLocalAudioSource::~ProcessedLocalAudioSource() {
- DVLOG(1) << "ProcessedLocalAudioSource::~ProcessedLocalAudioSource()";
+ DVLOG(1) << "PLAS::~ProcessedLocalAudioSource()";
EnsureSourceIsStopped();
}
@@ -118,6 +133,12 @@ ProcessedLocalAudioSource* ProcessedLocalAudioSource::From(
return nullptr;
}
+void ProcessedLocalAudioSource::SendLogMessageWithSessionId(
+ const std::string& message) const {
+ SendLogMessage(message + " [session_id=" + device().session_id().ToString() +
+ "]");
+}
+
base::Optional<blink::AudioProcessingProperties>
ProcessedLocalAudioSource::GetAudioProcessingProperties() const {
return audio_processing_properties_;
@@ -135,25 +156,18 @@ bool ProcessedLocalAudioSource::EnsureSourceIsStarted() {
// Sanity-check that the consuming RenderFrame still exists. This is required
// to initialize the audio source.
- if (!allow_invalid_render_frame_id_for_testing_ &&
- !internal_consumer_frame_->frame()) {
- blink::WebRtcLogMessage(
- "ProcessedLocalAudioSource::EnsureSourceIsStarted() fails "
- " because the render frame does not exist.");
+ if (!allow_invalid_render_frame_id_for_testing_ && !consumer_frame_) {
+ SendLogMessageWithSessionId(
+ "EnsureSourceIsStarted() => (ERROR: "
+ " render frame does not exist)");
return false;
}
- std::string str = base::StringPrintf(
- "ProcessedLocalAudioSource::EnsureSourceIsStarted."
- "channel_layout=%d, sample_rate=%d, buffer_size=%d, session_id=%s"
- ", effects=%d. ",
- device().input.channel_layout(), device().input.sample_rate(),
- device().input.frames_per_buffer(),
- device().session_id().ToString().c_str(), device().input.effects());
- blink::WebRtcLogMessage(str);
- DVLOG(1) << str;
-
- LogAudioProcesingProperties(audio_processing_properties_);
+ SendLogMessage(GetEnsureSourceIsStartedLogString(device()));
+ SendLogMessageWithSessionId(base::StringPrintf(
+ "EnsureSourceIsStarted() => (audio_processing_properties=[%s])",
+ GetAudioProcesingPropertiesLogString(audio_processing_properties_)
+ .c_str()));
blink::MediaStreamDevice modified_device(device());
bool device_is_modified = false;
@@ -197,9 +211,8 @@ bool ProcessedLocalAudioSource::EnsureSourceIsStarted() {
WebRtcAudioDeviceImpl* const rtc_audio_device =
PeerConnectionDependencyFactory::GetInstance()->GetWebRtcAudioDevice();
if (!rtc_audio_device) {
- blink::WebRtcLogMessage(
- "ProcessedLocalAudioSource::EnsureSourceIsStarted() fails"
- " because there is no WebRtcAudioDeviceImpl instance.");
+ SendLogMessageWithSessionId(
+ "EnsureSourceIsStarted() => (ERROR: no WebRTC ADM instance)");
return false;
}
@@ -227,10 +240,10 @@ bool ProcessedLocalAudioSource::EnsureSourceIsStarted() {
channel_layout != media::CHANNEL_LAYOUT_STEREO &&
channel_layout != media::CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC &&
channel_layout != media::CHANNEL_LAYOUT_DISCRETE) {
- blink::WebRtcLogMessage(base::StringPrintf(
- "ProcessedLocalAudioSource::EnsureSourceIsStarted() fails "
- " because the input channel layout (%d) is not supported.",
- static_cast<int>(channel_layout)));
+ SendLogMessage(
+ base::StringPrintf("EnsureSourceIsStarted() => (ERROR: "
+ "input channel layout (%d) is not supported.",
+ static_cast<int>(channel_layout)));
return false;
}
@@ -258,6 +271,7 @@ bool ProcessedLocalAudioSource::EnsureSourceIsStarted() {
}
DVLOG(1) << params.AsHumanReadableString();
DCHECK(params.IsValid());
+
media::AudioSourceParameters source_params(device().session_id());
const bool use_remote_apm =
media::IsWebRtcApmInAudioServiceEnabled() &&
@@ -277,8 +291,9 @@ bool ProcessedLocalAudioSource::EnsureSourceIsStarted() {
source_params.processing->settings.automatic_gain_control =
media::AutomaticGainControlType::kHybridExperimental;
}
- blink::WebRtcLogMessage(base::StringPrintf(
- "Using APM in audio process; settings: %s",
+ SendLogMessageWithSessionId(base::StringPrintf(
+ "EnsureSourceIsStarted() => (using APM in audio process: "
+ "settings=[%s])",
source_params.processing->settings.ToString().c_str()));
} else {
@@ -291,13 +306,15 @@ bool ProcessedLocalAudioSource::EnsureSourceIsStarted() {
}
// Start the source.
- DVLOG(1) << "Starting WebRTC audio source for consumption "
- << "with input parameters={" << params.AsHumanReadableString()
- << "} and output parameters={"
- << GetAudioParameters().AsHumanReadableString() << '}';
+ SendLogMessageWithSessionId(base::StringPrintf(
+ "EnsureSourceIsStarted() => (WebRTC audio source starts: "
+ "input_parameters=[%s], output_parameters=[%s])",
+ params.AsHumanReadableString().c_str(),
+ GetAudioParameters().AsHumanReadableString().c_str()));
+ auto* web_frame =
+ static_cast<WebLocalFrame*>(WebFrame::FromFrame(consumer_frame_));
scoped_refptr<media::AudioCapturerSource> new_source =
- Platform::Current()->NewAudioCapturerSource(
- internal_consumer_frame_->web_frame(), source_params);
+ Platform::Current()->NewAudioCapturerSource(web_frame, source_params);
new_source->Initialize(params, this);
// We need to set the AGC control before starting the stream.
new_source->SetAutomaticGainControl(true);
@@ -372,6 +389,7 @@ int ProcessedLocalAudioSource::MaxVolume() const {
}
void ProcessedLocalAudioSource::OnCaptureStarted() {
+ SendLogMessageWithSessionId(base::StringPrintf("OnCaptureStarted()"));
std::move(started_callback_)
.Run(this, blink::mojom::MediaStreamRequestResult::OK, "");
}
@@ -392,24 +410,29 @@ void ProcessedLocalAudioSource::Capture(const media::AudioBus* audio_bus,
}
void ProcessedLocalAudioSource::OnCaptureError(const std::string& message) {
- blink::WebRtcLogMessage("ProcessedLocalAudioSource::OnCaptureError: " +
- message);
+ SendLogMessageWithSessionId(
+ base::StringPrintf("OnCaptureError({message=%s})", message.c_str()));
StopSourceOnError(message);
}
void ProcessedLocalAudioSource::OnCaptureMuted(bool is_muted) {
+ SendLogMessageWithSessionId(base::StringPrintf(
+ "OnCaptureMuted({is_muted=%s})", is_muted ? "true" : "false"));
SetMutedState(is_muted);
}
void ProcessedLocalAudioSource::OnCaptureProcessorCreated(
media::AudioProcessorControls* controls) {
+ SendLogMessageWithSessionId(
+ base::StringPrintf("OnCaptureProcessorCreated()"));
DCHECK(audio_processor_proxy_);
audio_processor_proxy_->SetControls(controls);
}
void ProcessedLocalAudioSource::SetOutputDeviceForAec(
const std::string& output_device_id) {
- DVLOG(1) << "ProcessedLocalAudioSource::SetOutputDeviceForAec()";
+ SendLogMessageWithSessionId(base::StringPrintf(
+ "SetOutputDeviceForAec({device_id=%s})", output_device_id.c_str()));
if (source_)
source_->SetOutputDeviceForAec(output_device_id);
}
@@ -493,8 +516,7 @@ int ProcessedLocalAudioSource::GetBufferSize(int sample_rate) const {
// TODO(henrika): Re-evaluate whether to use same logic as other platforms.
// https://crbug.com/638081
return (2 * sample_rate / 100);
-#endif
-
+#else
// If audio processing is turned on, require 10ms buffers.
if (audio_processor_->has_audio_processing() || audio_processor_proxy_)
return (sample_rate / 100);
@@ -512,6 +534,7 @@ int ProcessedLocalAudioSource::GetBufferSize(int sample_rate) const {
// TODO(miu): Identify where/why the buffer size might be missing, fix the
// code, and then require it here. https://crbug.com/638081
return (sample_rate / 100);
+#endif
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.h b/chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.h
index 6982b0c7ff3..a190d59e7f4 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.h
+++ b/chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.h
@@ -12,8 +12,8 @@
#include "base/memory/scoped_refptr.h"
#include "base/synchronization/lock.h"
#include "media/base/audio_capturer_source.h"
-#include "third_party/blink/public/platform/web_media_constraints.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_level_calculator.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
@@ -27,9 +27,8 @@ class AudioProcessorControls;
namespace blink {
class AudioServiceAudioProcessorProxy;
+class LocalFrame;
class MediaStreamAudioProcessor;
-class MediaStreamInternalFrameWrapper;
-class WebLocalFrame;
// Represents a local source of audio data that is routed through the WebRTC
// audio pipeline for post-processing (e.g., for echo cancellation during a
@@ -37,18 +36,18 @@ class WebLocalFrame;
// MediaStreamProcessor that modifies its audio. Modified audio is delivered to
// one or more MediaStreamAudioTracks.
class MODULES_EXPORT ProcessedLocalAudioSource final
- : public blink::MediaStreamAudioSource,
+ : public MediaStreamAudioSource,
public media::AudioCapturerSource::CaptureCallback {
public:
- // |internal_consumer_frame_| references the blink::LocalFrame that will
+ // |consumer_frame_| references the LocalFrame that will
// consume the audio data. Audio parameters and (optionally) a pre-existing
// audio session ID are derived from |device_info|. |factory| must outlive
// this instance.
ProcessedLocalAudioSource(
- WebLocalFrame* web_frame,
- const blink::MediaStreamDevice& device,
+ LocalFrame* frame,
+ const MediaStreamDevice& device,
bool disable_local_echo,
- const blink::AudioProcessingProperties& audio_processing_properties,
+ const AudioProcessingProperties& audio_processing_properties,
ConstraintsOnceCallback started_callback,
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
@@ -119,9 +118,17 @@ class MODULES_EXPORT ProcessedLocalAudioSource final
// processing will take place.
int GetBufferSize(int sample_rate) const;
+ // Helper method which sends the log |message| to a native WebRTC log and
+ // adds the current session ID (from the associated media stream device) to
+ // make the log unique.
+ void SendLogMessageWithSessionId(const std::string& message) const;
+
// The LocalFrame that will consume the audio data. Used when creating
// AudioCapturerSources.
- std::unique_ptr<MediaStreamInternalFrameWrapper> internal_consumer_frame_;
+ //
+ // TODO(crbug.com/704136): Consider moving ProcessedLocalAudioSource to
+ // Oilpan and use Member<> here.
+ WeakPersistent<LocalFrame> consumer_frame_;
blink::AudioProcessingProperties audio_processing_properties_;
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 de13e2ee84b..441935eeb24 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
@@ -12,15 +12,15 @@
#include "media/base/audio_parameters.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.h"
#include "third_party/blink/public/platform/modules/mediastream/web_media_stream_audio_sink.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
-#include "third_party/blink/public/platform/web_media_constraints.h"
#include "third_party/blink/public/web/web_heap.h"
#include "third_party/blink/renderer/modules/mediastream/processed_local_audio_source.h"
#include "third_party/blink/renderer/modules/mediastream/testing_platform_support_with_mock_audio_capture_source.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_processor_options.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h"
using ::testing::_;
using ::testing::AtLeast;
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 f4edee38188..61e734e638a 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
@@ -24,14 +24,10 @@ RemoteVideoTrackAdapter::RemoteVideoTrackAdapter(
std::unique_ptr<TrackObserver> observer(
new TrackObserver(main_thread, observed_track().get()));
// Here, we use CrossThreadUnretained() to avoid a circular reference.
- //
- // TODO(crbug.com/963574): Remove the use of ConvertToBaseOnceCallback here
- // once the file that includes remote_media_stream_track_adapter.h (namely
- // webrtc_media_stream_track_adapter.h) is Onion souped.
- web_initialize_ = ConvertToBaseOnceCallback(
+ web_initialize_ =
CrossThreadBindOnce(&RemoteVideoTrackAdapter::InitializeWebVideoTrack,
CrossThreadUnretained(this), std::move(observer),
- observed_track()->enabled()));
+ observed_track()->enabled());
}
RemoteVideoTrackAdapter::~RemoteVideoTrackAdapter() {
@@ -76,13 +72,9 @@ RemoteAudioTrackAdapter::RemoteAudioTrackAdapter(
// TODO(tommi): Use TrackObserver instead.
observed_track()->RegisterObserver(this);
// Here, we use CrossThreadUnretained() to avoid a circular reference.
- //
- // TODO(crbug.com/963574): Remove the use of ConvertToBaseOnceCallback here
- // once the file that includes remote_media_stream_track_adapter.h (namely
- // webrtc_media_stream_track_adapter.h) is Onion souped.
- web_initialize_ = ConvertToBaseOnceCallback(
+ web_initialize_ =
CrossThreadBindOnce(&RemoteAudioTrackAdapter::InitializeWebAudioTrack,
- CrossThreadUnretained(this), main_thread));
+ CrossThreadUnretained(this), main_thread);
}
RemoteAudioTrackAdapter::~RemoteAudioTrackAdapter() {
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 29c46faec01..20401c01b89 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,12 +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/callback.h"
#include "base/logging.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/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
#include "third_party/webrtc/api/media_stream_interface.h"
@@ -84,7 +84,7 @@ class MODULES_EXPORT RemoteMediaStreamTrackAdapter
// The callback is used by derived classes to bind objects that need to be
// instantiated and initialized on the signaling thread but then moved to
// and used on the main thread when initializing the web object(s).
- base::OnceClosure web_initialize_;
+ CrossThreadOnceClosure web_initialize_;
private:
const scoped_refptr<WebRtcMediaStreamTrackType> webrtc_track_;
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 ed96938b594..6a482ccc425 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
@@ -16,11 +16,11 @@
#include "media/base/audio_bus.h"
#include "media/base/audio_latency.h"
#include "media/base/audio_shifter.h"
-#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.h"
#include "third_party/blink/public/platform/platform.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"
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 03889489f60..f40e32f2b81 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
@@ -13,17 +13,15 @@
#include "base/strings/stringprintf.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h"
-#include "third_party/blink/public/platform/web_media_constraints.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_document.h"
#include "third_party/blink/public/web/web_local_frame.h"
-#include "third_party/blink/public/web/web_user_gesture_indicator.h"
-#include "third_party/blink/public/web/web_user_media_request.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/modules/mediastream/apply_constraints_processor.h"
#include "third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h"
+#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
#include "third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -34,13 +32,13 @@ static int g_next_request_id = 0;
// The histogram counts the number of calls to the JS API
// getUserMedia or getDisplayMedia().
-void UpdateAPICount(blink::WebUserMediaRequest::MediaType media_type) {
+void UpdateAPICount(UserMediaRequest::MediaType media_type) {
RTCAPIName api_name = RTCAPIName::kGetUserMedia;
switch (media_type) {
- case blink::WebUserMediaRequest::MediaType::kUserMedia:
+ case UserMediaRequest::MediaType::kUserMedia:
api_name = RTCAPIName::kGetUserMedia;
break;
- case blink::WebUserMediaRequest::MediaType::kDisplayMedia:
+ case UserMediaRequest::MediaType::kDisplayMedia:
api_name = RTCAPIName::kGetDisplayMedia;
break;
}
@@ -49,8 +47,8 @@ void UpdateAPICount(blink::WebUserMediaRequest::MediaType media_type) {
} // namespace
-UserMediaClient::Request::Request(std::unique_ptr<UserMediaRequestInfo> request)
- : user_media_request_(std::move(request)) {
+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());
@@ -73,9 +71,10 @@ UserMediaClient::Request::Request(
UserMediaClient::Request::~Request() = default;
-std::unique_ptr<UserMediaRequestInfo>
-UserMediaClient::Request::MoveUserMediaRequest() {
- return std::move(user_media_request_);
+UserMediaRequest* UserMediaClient::Request::MoveUserMediaRequest() {
+ auto user_media_request = user_media_request_;
+ user_media_request_ = nullptr;
+ return user_media_request;
}
UserMediaClient::UserMediaClient(
@@ -130,54 +129,59 @@ UserMediaClient::~UserMediaClient() {
DCHECK(!is_processing_request_);
}
-void UserMediaClient::RequestUserMedia(
- const blink::WebUserMediaRequest& web_request) {
+void UserMediaClient::RequestUserMedia(UserMediaRequest* user_media_request) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(!web_request.IsNull());
- DCHECK(web_request.Audio() || web_request.Video());
+ DCHECK(user_media_request);
+ DCHECK(user_media_request->Audio() || user_media_request->Video());
// ownerDocument may be null if we are in a test.
// In that case, it's OK to not check frame().
- DCHECK(web_request.OwnerDocument().IsNull() ||
- WebFrame::FromFrame(frame_) ==
- static_cast<blink::WebFrame*>(
- web_request.OwnerDocument().GetFrame()));
+ DCHECK(!user_media_request->OwnerDocument() ||
+ frame_ == user_media_request->OwnerDocument()->GetFrame());
// Save histogram data so we can see how much GetUserMedia is used.
- UpdateAPICount(web_request.MediaRequestType());
+ UpdateAPICount(user_media_request->MediaRequestType());
// TODO(crbug.com/787254): Communicate directly with the
// PeerConnectionTrackerHost mojo object once it is available from Blink.
- PeerConnectionTracker::GetInstance()->TrackGetUserMedia(web_request);
+ PeerConnectionTracker::GetInstance()->TrackGetUserMedia(user_media_request);
int request_id = g_next_request_id++;
blink::WebRtcLogMessage(base::StringPrintf(
- "UMCI::RequestUserMedia. request_id=%d, audio constraints=%s, "
- "video constraints=%s",
- request_id, web_request.AudioConstraints().ToString().Utf8().c_str(),
- web_request.VideoConstraints().ToString().Utf8().c_str()));
-
- // The value returned by isProcessingUserGesture() is used by the browser to
- // make decisions about the permissions UI. Its value can be lost while
+ "UMCI::RequestUserMedia({request_id=%d}, {audio constraints=%s}, "
+ "{video constraints=%s})",
+ request_id,
+ user_media_request->AudioConstraints().ToString().Utf8().c_str(),
+ user_media_request->VideoConstraints().ToString().Utf8().c_str()));
+
+ // The value returned by HasTransientUserActivation() is used by the browser
+ // to make decisions about the permissions UI. Its value can be lost while
// switching threads, so saving its value here.
- bool user_gesture = blink::WebUserGestureIndicator::IsProcessingUserGesture(
- web_request.OwnerDocument().IsNull()
- ? nullptr
- : web_request.OwnerDocument().GetFrame());
- std::unique_ptr<UserMediaRequestInfo> request_info =
- std::make_unique<UserMediaRequestInfo>(request_id, web_request,
- user_gesture);
+ //
+ // TODO(mustaq): The description above seems specific to pre-UAv2 stack-based
+ // tokens. Perhaps we don't need to preserve this bit?
+ bool has_transient_user_activation = false;
+ if (user_media_request->OwnerDocument() &&
+ user_media_request->OwnerDocument()->GetFrame()) {
+ has_transient_user_activation = user_media_request->OwnerDocument()
+ ->GetFrame()
+ ->Frame::HasTransientUserActivation();
+ }
+ user_media_request->set_request_id(request_id);
+ user_media_request->set_has_transient_user_activation(
+ has_transient_user_activation);
pending_request_infos_.push_back(
- MakeGarbageCollected<Request>(std::move(request_info)));
+ MakeGarbageCollected<Request>(user_media_request));
if (!is_processing_request_)
MaybeProcessNextRequestInfo();
}
void UserMediaClient::ApplyConstraints(
- blink::ApplyConstraintsRequest* web_request) {
+ blink::ApplyConstraintsRequest* user_media_request) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- pending_request_infos_.push_back(MakeGarbageCollected<Request>(web_request));
+ pending_request_infos_.push_back(
+ MakeGarbageCollected<Request>(user_media_request));
if (!is_processing_request_)
MaybeProcessNextRequestInfo();
}
@@ -237,25 +241,26 @@ void UserMediaClient::CurrentRequestCompleted() {
}
void UserMediaClient::CancelUserMediaRequest(
- const blink::WebUserMediaRequest& web_request) {
+ UserMediaRequest* user_media_request) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
{
// TODO(guidou): Remove this conditional logging. https://crbug.com/764293
- UserMediaRequestInfo* request = user_media_processor_->CurrentRequest();
- if (request && request->web_request == web_request) {
- blink::WebRtcLogMessage(base::StringPrintf(
- "UMCI::CancelUserMediaRequest. request_id=%d", request->request_id));
+ UserMediaRequest* request = user_media_processor_->CurrentRequest();
+ if (request == user_media_request) {
+ blink::WebRtcLogMessage(
+ base::StringPrintf("UMCI::CancelUserMediaRequest. request_id=%d",
+ request->request_id()));
}
}
bool did_remove_request = false;
- if (user_media_processor_->DeleteWebRequest(web_request)) {
+ if (user_media_processor_->DeleteUserMediaRequest(user_media_request)) {
did_remove_request = true;
} else {
for (auto it = pending_request_infos_.begin();
it != pending_request_infos_.end(); ++it) {
if ((*it)->IsUserMedia() &&
- (*it)->user_media_request()->web_request == web_request) {
+ (*it)->user_media_request() == user_media_request) {
pending_request_infos_.erase(it);
did_remove_request = true;
break;
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 f6c403a8750..2f528b7307d 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
@@ -14,10 +14,10 @@
#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/public/web/web_user_media_request.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/mediastream/apply_constraints_request.h"
#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/wtf/deque.h"
@@ -47,9 +47,9 @@ class MODULES_EXPORT UserMediaClient
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
virtual ~UserMediaClient();
- void RequestUserMedia(const blink::WebUserMediaRequest& web_request);
- void CancelUserMediaRequest(const blink::WebUserMediaRequest& web_request);
- void ApplyConstraints(blink::ApplyConstraintsRequest* web_request);
+ 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 ContextDestroyed();
@@ -64,16 +64,14 @@ class MODULES_EXPORT UserMediaClient
private:
class Request final : public GarbageCollected<Request> {
public:
- explicit Request(std::unique_ptr<UserMediaRequestInfo> request);
+ explicit Request(UserMediaRequest* request);
explicit Request(blink::ApplyConstraintsRequest* request);
explicit Request(const blink::WebMediaStreamTrack& request);
~Request();
- std::unique_ptr<UserMediaRequestInfo> MoveUserMediaRequest();
+ UserMediaRequest* MoveUserMediaRequest();
- UserMediaRequestInfo* user_media_request() const {
- return user_media_request_.get();
- }
+ UserMediaRequest* user_media_request() const { return user_media_request_; }
blink::ApplyConstraintsRequest* apply_constraints_request() const {
return apply_constraints_request_;
}
@@ -85,10 +83,13 @@ class MODULES_EXPORT UserMediaClient
bool IsApplyConstraints() const { return apply_constraints_request_; }
bool IsStopTrack() const { return !web_track_to_stop_.IsNull(); }
- void Trace(Visitor* visitor) { visitor->Trace(apply_constraints_request_); }
+ void Trace(Visitor* visitor) {
+ visitor->Trace(user_media_request_);
+ visitor->Trace(apply_constraints_request_);
+ }
private:
- std::unique_ptr<UserMediaRequestInfo> user_media_request_;
+ Member<UserMediaRequest> user_media_request_;
Member<blink::ApplyConstraintsRequest> apply_constraints_request_;
blink::WebMediaStreamTrack web_track_to_stop_;
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 ab4aace314a..a2ee8157bc8 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
@@ -12,6 +12,7 @@
#include <vector>
#include "base/bind.h"
+#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "media/audio/audio_device_description.h"
@@ -20,7 +21,6 @@
#include "third_party/blink/public/common/mediastream/media_devices.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"
-#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.h"
#include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_track.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "third_party/blink/public/platform/web_media_stream.h"
@@ -39,6 +39,7 @@
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.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/testing/io_task_runner_testing_platform_support.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -55,58 +56,52 @@ using EchoCancellationType =
namespace {
-blink::WebMediaConstraints CreateDefaultConstraints() {
+MediaConstraints CreateDefaultConstraints() {
blink::MockConstraintFactory factory;
factory.AddAdvanced();
- return factory.CreateWebMediaConstraints();
+ return factory.CreateMediaConstraints();
}
-blink::WebMediaConstraints CreateDeviceConstraints(
+MediaConstraints CreateDeviceConstraints(
const char* basic_exact_value,
const char* basic_ideal_value = nullptr,
const char* advanced_exact_value = nullptr) {
blink::MockConstraintFactory factory;
if (basic_exact_value) {
- factory.basic().device_id.SetExact(
- blink::WebString::FromUTF8(basic_exact_value));
+ factory.basic().device_id.SetExact(basic_exact_value);
}
if (basic_ideal_value) {
- blink::WebString value = blink::WebString::FromUTF8(basic_ideal_value);
- factory.basic().device_id.SetIdeal(
- blink::WebVector<blink::WebString>(&value, 1));
+ factory.basic().device_id.SetIdeal(Vector<String>({basic_ideal_value}));
}
auto& advanced = factory.AddAdvanced();
if (advanced_exact_value) {
- blink::WebString value = blink::WebString::FromUTF8(advanced_exact_value);
+ String value = String::FromUTF8(advanced_exact_value);
advanced.device_id.SetExact(value);
}
- return factory.CreateWebMediaConstraints();
+ return factory.CreateMediaConstraints();
}
-blink::WebMediaConstraints CreateFacingModeConstraints(
+MediaConstraints CreateFacingModeConstraints(
const char* basic_exact_value,
const char* basic_ideal_value = nullptr,
const char* advanced_exact_value = nullptr) {
blink::MockConstraintFactory factory;
if (basic_exact_value) {
- factory.basic().facing_mode.SetExact(
- blink::WebString::FromUTF8(basic_exact_value));
+ factory.basic().facing_mode.SetExact(String::FromUTF8(basic_exact_value));
}
if (basic_ideal_value) {
- blink::WebString value = blink::WebString::FromUTF8(basic_ideal_value);
- factory.basic().device_id.SetIdeal(
- blink::WebVector<blink::WebString>(&value, 1));
+ factory.basic().device_id.SetIdeal(Vector<String>({basic_ideal_value}));
}
auto& advanced = factory.AddAdvanced();
if (advanced_exact_value) {
- blink::WebString value = blink::WebString::FromUTF8(advanced_exact_value);
+ String value = String::FromUTF8(advanced_exact_value);
advanced.device_id.SetExact(value);
}
- return factory.CreateWebMediaConstraints();
+ return factory.CreateMediaConstraints();
}
void CheckVideoSource(blink::MediaStreamVideoSource* source,
@@ -197,7 +192,7 @@ class MockMediaDevicesDispatcherHost
blink::mojom::blink::VideoInputDeviceCapabilities::New();
device->device_id = kFakeVideoInputDeviceId1;
device->group_id = String("dummy");
- device->facing_mode = blink::mojom::FacingMode::USER;
+ device->facing_mode = media::MEDIA_VIDEO_FACING_USER;
if (!video_source_ || !video_source_->IsRunning() ||
!video_source_->GetCurrentFormat()) {
device->formats.push_back(media::VideoCaptureFormat(
@@ -215,7 +210,7 @@ class MockMediaDevicesDispatcherHost
device = blink::mojom::blink::VideoInputDeviceCapabilities::New();
device->device_id = kFakeVideoInputDeviceId2;
device->group_id = String("dummy");
- device->facing_mode = blink::mojom::FacingMode::ENVIRONMENT;
+ device->facing_mode = media::MEDIA_VIDEO_FACING_ENVIRONMENT;
device->formats.push_back(media::VideoCaptureFormat(
gfx::Size(640, 480), 30.0f, media::PIXEL_FORMAT_I420));
result.push_back(std::move(device));
@@ -409,9 +404,8 @@ class UserMediaProcessorUnderTest : public UserMediaProcessor {
return source;
}
- void GetUserMediaRequestSucceeded(
- const blink::WebMediaStream& stream,
- blink::WebUserMediaRequest request_info) override {
+ void GetUserMediaRequestSucceeded(const blink::WebMediaStream& stream,
+ UserMediaRequest* request_info) override {
last_generated_stream_ = stream;
*state_ = REQUEST_SUCCEEDED;
}
@@ -456,17 +450,15 @@ class UserMediaClientUnderTest : public UserMediaClient {
blink::scheduler::GetSingleThreadTaskRunnerForTesting()),
state_(state) {}
- void RequestUserMediaForTest(
- const blink::WebUserMediaRequest& user_media_request) {
+ void RequestUserMediaForTest(UserMediaRequest* user_media_request) {
*state_ = REQUEST_NOT_COMPLETE;
RequestUserMedia(user_media_request);
base::RunLoop().RunUntilIdle();
}
void RequestUserMediaForTest() {
- blink::WebUserMediaRequest user_media_request =
- blink::WebUserMediaRequest::CreateForTesting(
- CreateDefaultConstraints(), CreateDefaultConstraints());
+ UserMediaRequest* user_media_request = UserMediaRequest::CreateForTesting(
+ CreateDefaultConstraints(), CreateDefaultConstraints());
RequestUserMediaForTest(user_media_request);
}
@@ -530,9 +522,8 @@ class UserMediaClientTest : public ::testing::Test {
}
blink::WebMediaStreamTrack RequestLocalVideoTrack() {
- blink::WebUserMediaRequest user_media_request =
- blink::WebUserMediaRequest::CreateForTesting(
- blink::WebMediaConstraints(), CreateDefaultConstraints());
+ UserMediaRequest* user_media_request = UserMediaRequest::CreateForTesting(
+ MediaConstraints(), CreateDefaultConstraints());
user_media_client_impl_->RequestUserMediaForTest(user_media_request);
StartMockedVideoSource();
EXPECT_EQ(REQUEST_SUCCEEDED, request_state());
@@ -555,10 +546,8 @@ class UserMediaClientTest : public ::testing::Test {
blink::MockConstraintFactory constraint_factory;
constraint_factory.basic().render_to_associated_sink.SetExact(
render_to_associated_sink);
- blink::WebUserMediaRequest user_media_request =
- blink::WebUserMediaRequest::CreateForTesting(
- constraint_factory.CreateWebMediaConstraints(),
- blink::WebMediaConstraints());
+ UserMediaRequest* user_media_request = UserMediaRequest::CreateForTesting(
+ constraint_factory.CreateMediaConstraints(), MediaConstraints());
user_media_client_impl_->RequestUserMediaForTest(user_media_request);
EXPECT_EQ(REQUEST_SUCCEEDED, request_state());
@@ -591,15 +580,14 @@ class UserMediaClientTest : public ::testing::Test {
}
void TestValidRequestWithConstraints(
- const blink::WebMediaConstraints& audio_constraints,
- const blink::WebMediaConstraints& video_constraints,
+ const MediaConstraints& audio_constraints,
+ const MediaConstraints& video_constraints,
const std::string& expected_audio_device_id,
const std::string& expected_video_device_id) {
DCHECK(!audio_constraints.IsNull());
DCHECK(!video_constraints.IsNull());
- blink::WebUserMediaRequest request =
- blink::WebUserMediaRequest::CreateForTesting(audio_constraints,
- video_constraints);
+ UserMediaRequest* request = UserMediaRequest::CreateForTesting(
+ audio_constraints, video_constraints);
user_media_client_impl_->RequestUserMediaForTest(request);
StartMockedVideoSource();
@@ -629,7 +617,7 @@ class UserMediaClientTest : public ::testing::Test {
auto* apply_constraints_request =
MakeGarbageCollected<blink::ApplyConstraintsRequest>(
- web_track, factory.CreateWebMediaConstraints(), nullptr);
+ web_track, factory.CreateMediaConstraints(), nullptr);
user_media_client_impl_->ApplyConstraints(apply_constraints_request);
base::RunLoop().RunUntilIdle();
}
@@ -897,9 +885,8 @@ TEST_F(UserMediaClientTest, StopTrackAfterReload) {
}
TEST_F(UserMediaClientTest, DefaultConstraintsPropagate) {
- blink::WebUserMediaRequest request =
- blink::WebUserMediaRequest::CreateForTesting(CreateDefaultConstraints(),
- CreateDefaultConstraints());
+ UserMediaRequest* request = UserMediaRequest::CreateForTesting(
+ CreateDefaultConstraints(), CreateDefaultConstraints());
user_media_client_impl_->RequestUserMediaForTest(request);
blink::AudioCaptureSettings audio_capture_settings =
user_media_processor_->AudioSettings();
@@ -955,15 +942,11 @@ TEST_F(UserMediaClientTest, DefaultConstraintsPropagate) {
TEST_F(UserMediaClientTest, DefaultTabCapturePropagate) {
blink::MockConstraintFactory factory;
- factory.basic().media_stream_source.SetExact(
- blink::WebString::FromASCII(blink::kMediaStreamSourceTab));
- blink::WebMediaConstraints audio_constraints =
- factory.CreateWebMediaConstraints();
- blink::WebMediaConstraints video_constraints =
- factory.CreateWebMediaConstraints();
- blink::WebUserMediaRequest request =
- blink::WebUserMediaRequest::CreateForTesting(audio_constraints,
- video_constraints);
+ factory.basic().media_stream_source.SetExact(kMediaStreamSourceTab);
+ MediaConstraints audio_constraints = factory.CreateMediaConstraints();
+ MediaConstraints video_constraints = factory.CreateMediaConstraints();
+ UserMediaRequest* request =
+ UserMediaRequest::CreateForTesting(audio_constraints, video_constraints);
user_media_client_impl_->RequestUserMediaForTest(request);
blink::AudioCaptureSettings audio_capture_settings =
user_media_processor_->AudioSettings();
@@ -1013,15 +996,11 @@ TEST_F(UserMediaClientTest, DefaultTabCapturePropagate) {
TEST_F(UserMediaClientTest, DefaultDesktopCapturePropagate) {
blink::MockConstraintFactory factory;
- factory.basic().media_stream_source.SetExact(
- blink::WebString::FromASCII(blink::kMediaStreamSourceDesktop));
- blink::WebMediaConstraints audio_constraints =
- factory.CreateWebMediaConstraints();
- blink::WebMediaConstraints video_constraints =
- factory.CreateWebMediaConstraints();
- blink::WebUserMediaRequest request =
- blink::WebUserMediaRequest::CreateForTesting(audio_constraints,
- video_constraints);
+ factory.basic().media_stream_source.SetExact(kMediaStreamSourceDesktop);
+ MediaConstraints audio_constraints = factory.CreateMediaConstraints();
+ MediaConstraints video_constraints = factory.CreateMediaConstraints();
+ UserMediaRequest* request =
+ UserMediaRequest::CreateForTesting(audio_constraints, video_constraints);
user_media_client_impl_->RequestUserMediaForTest(request);
blink::AudioCaptureSettings audio_capture_settings =
user_media_processor_->AudioSettings();
@@ -1074,18 +1053,15 @@ TEST_F(UserMediaClientTest, NonDefaultAudioConstraintsPropagate) {
mock_dispatcher_host_.DoNotRunCallback();
blink::MockConstraintFactory factory;
- factory.basic().device_id.SetExact(
- blink::WebString::FromASCII(kFakeAudioInputDeviceId1));
+ factory.basic().device_id.SetExact(kFakeAudioInputDeviceId1);
factory.basic().disable_local_echo.SetExact(true);
factory.basic().render_to_associated_sink.SetExact(true);
factory.basic().echo_cancellation.SetExact(false);
factory.basic().goog_audio_mirroring.SetExact(true);
- blink::WebMediaConstraints audio_constraints =
- factory.CreateWebMediaConstraints();
+ MediaConstraints audio_constraints = factory.CreateMediaConstraints();
// Request contains only audio
- blink::WebUserMediaRequest request =
- blink::WebUserMediaRequest::CreateForTesting(
- audio_constraints, blink::WebMediaConstraints());
+ UserMediaRequest* request =
+ UserMediaRequest::CreateForTesting(audio_constraints, MediaConstraints());
user_media_client_impl_->RequestUserMediaForTest(request);
blink::AudioCaptureSettings audio_capture_settings =
user_media_processor_->AudioSettings();
@@ -1114,29 +1090,27 @@ TEST_F(UserMediaClientTest, NonDefaultAudioConstraintsPropagate) {
}
TEST_F(UserMediaClientTest, CreateWithMandatoryInvalidAudioDeviceId) {
- blink::WebMediaConstraints audio_constraints =
+ MediaConstraints audio_constraints =
CreateDeviceConstraints(kInvalidDeviceId);
- blink::WebUserMediaRequest request =
- blink::WebUserMediaRequest::CreateForTesting(
- audio_constraints, blink::WebMediaConstraints());
+ UserMediaRequest* request =
+ UserMediaRequest::CreateForTesting(audio_constraints, MediaConstraints());
user_media_client_impl_->RequestUserMediaForTest(request);
EXPECT_EQ(REQUEST_FAILED, request_state());
}
TEST_F(UserMediaClientTest, CreateWithMandatoryInvalidVideoDeviceId) {
- blink::WebMediaConstraints video_constraints =
+ MediaConstraints video_constraints =
CreateDeviceConstraints(kInvalidDeviceId);
- blink::WebUserMediaRequest request =
- blink::WebUserMediaRequest::CreateForTesting(blink::WebMediaConstraints(),
- video_constraints);
+ UserMediaRequest* request =
+ UserMediaRequest::CreateForTesting(MediaConstraints(), video_constraints);
user_media_client_impl_->RequestUserMediaForTest(request);
EXPECT_EQ(REQUEST_FAILED, request_state());
}
TEST_F(UserMediaClientTest, CreateWithMandatoryValidDeviceIds) {
- blink::WebMediaConstraints audio_constraints =
+ MediaConstraints audio_constraints =
CreateDeviceConstraints(kFakeAudioInputDeviceId1);
- blink::WebMediaConstraints video_constraints =
+ MediaConstraints video_constraints =
CreateDeviceConstraints(kFakeVideoInputDeviceId1);
TestValidRequestWithConstraints(audio_constraints, video_constraints,
kFakeAudioInputDeviceId1,
@@ -1144,9 +1118,9 @@ TEST_F(UserMediaClientTest, CreateWithMandatoryValidDeviceIds) {
}
TEST_F(UserMediaClientTest, CreateWithBasicIdealValidDeviceId) {
- blink::WebMediaConstraints audio_constraints =
+ MediaConstraints audio_constraints =
CreateDeviceConstraints(nullptr, kFakeAudioInputDeviceId1);
- blink::WebMediaConstraints video_constraints =
+ MediaConstraints video_constraints =
CreateDeviceConstraints(nullptr, kFakeVideoInputDeviceId1);
TestValidRequestWithConstraints(audio_constraints, video_constraints,
kFakeAudioInputDeviceId1,
@@ -1154,9 +1128,9 @@ TEST_F(UserMediaClientTest, CreateWithBasicIdealValidDeviceId) {
}
TEST_F(UserMediaClientTest, CreateWithAdvancedExactValidDeviceId) {
- blink::WebMediaConstraints audio_constraints =
+ MediaConstraints audio_constraints =
CreateDeviceConstraints(nullptr, nullptr, kFakeAudioInputDeviceId1);
- blink::WebMediaConstraints video_constraints =
+ MediaConstraints video_constraints =
CreateDeviceConstraints(nullptr, nullptr, kFakeVideoInputDeviceId1);
TestValidRequestWithConstraints(audio_constraints, video_constraints,
kFakeAudioInputDeviceId1,
@@ -1164,9 +1138,9 @@ TEST_F(UserMediaClientTest, CreateWithAdvancedExactValidDeviceId) {
}
TEST_F(UserMediaClientTest, CreateWithAllOptionalInvalidDeviceId) {
- blink::WebMediaConstraints audio_constraints =
+ MediaConstraints audio_constraints =
CreateDeviceConstraints(nullptr, kInvalidDeviceId, kInvalidDeviceId);
- blink::WebMediaConstraints video_constraints =
+ MediaConstraints video_constraints =
CreateDeviceConstraints(nullptr, kInvalidDeviceId, kInvalidDeviceId);
// MockMojoMediaStreamDispatcherHost uses empty string as default audio device
// ID. MockMediaDevicesDispatcher uses the first device in the enumeration as
@@ -1179,10 +1153,9 @@ TEST_F(UserMediaClientTest, CreateWithAllOptionalInvalidDeviceId) {
}
TEST_F(UserMediaClientTest, CreateWithFacingModeUser) {
- blink::WebMediaConstraints audio_constraints =
+ MediaConstraints audio_constraints =
CreateDeviceConstraints(kFakeAudioInputDeviceId1);
- blink::WebMediaConstraints video_constraints =
- CreateFacingModeConstraints("user");
+ MediaConstraints video_constraints = CreateFacingModeConstraints("user");
// kFakeVideoInputDeviceId1 has user facing mode.
TestValidRequestWithConstraints(audio_constraints, video_constraints,
kFakeAudioInputDeviceId1,
@@ -1190,9 +1163,9 @@ TEST_F(UserMediaClientTest, CreateWithFacingModeUser) {
}
TEST_F(UserMediaClientTest, CreateWithFacingModeEnvironment) {
- blink::WebMediaConstraints audio_constraints =
+ MediaConstraints audio_constraints =
CreateDeviceConstraints(kFakeAudioInputDeviceId1);
- blink::WebMediaConstraints video_constraints =
+ MediaConstraints video_constraints =
CreateFacingModeConstraints("environment");
// kFakeVideoInputDeviceId2 has environment facing mode.
TestValidRequestWithConstraints(audio_constraints, video_constraints,
@@ -1402,13 +1375,10 @@ TEST_F(UserMediaClientTest, DesktopCaptureChangeSource) {
blink::MockConstraintFactory factory;
factory.basic().media_stream_source.SetExact(
blink::WebString::FromASCII(blink::kMediaStreamSourceDesktop));
- blink::WebMediaConstraints audio_constraints =
- factory.CreateWebMediaConstraints();
- blink::WebMediaConstraints video_constraints =
- factory.CreateWebMediaConstraints();
- blink::WebUserMediaRequest request =
- blink::WebUserMediaRequest::CreateForTesting(audio_constraints,
- video_constraints);
+ MediaConstraints audio_constraints = factory.CreateMediaConstraints();
+ MediaConstraints video_constraints = factory.CreateMediaConstraints();
+ UserMediaRequest* request =
+ UserMediaRequest::CreateForTesting(audio_constraints, video_constraints);
user_media_client_impl_->RequestUserMediaForTest(request);
// Test changing video source.
@@ -1438,15 +1408,11 @@ TEST_F(UserMediaClientTest, DesktopCaptureChangeSource) {
TEST_F(UserMediaClientTest, DesktopCaptureChangeSourceWithoutAudio) {
blink::MockConstraintFactory factory;
- factory.basic().media_stream_source.SetExact(
- blink::WebString::FromASCII(blink::kMediaStreamSourceDesktop));
- blink::WebMediaConstraints audio_constraints =
- factory.CreateWebMediaConstraints();
- blink::WebMediaConstraints video_constraints =
- factory.CreateWebMediaConstraints();
- blink::WebUserMediaRequest request =
- blink::WebUserMediaRequest::CreateForTesting(audio_constraints,
- video_constraints);
+ factory.basic().media_stream_source.SetExact(kMediaStreamSourceDesktop);
+ MediaConstraints audio_constraints = factory.CreateMediaConstraints();
+ MediaConstraints video_constraints = factory.CreateMediaConstraints();
+ UserMediaRequest* request =
+ UserMediaRequest::CreateForTesting(audio_constraints, video_constraints);
user_media_client_impl_->RequestUserMediaForTest(request);
EXPECT_EQ(1U, mock_dispatcher_host_.audio_devices().size());
EXPECT_EQ(1U, mock_dispatcher_host_.video_devices().size());
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 e7ee552cab6..9bad0c1e6e4 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
@@ -31,11 +31,11 @@ const char UserMediaController::kSupplementName[] = "UserMediaController";
UserMediaController::UserMediaController(LocalFrame& frame)
: Supplement<LocalFrame>(frame),
- ContextLifecycleObserver(frame.GetDocument()) {}
+ ExecutionContextLifecycleObserver(frame.GetDocument()) {}
-void UserMediaController::Trace(blink::Visitor* visitor) {
+void UserMediaController::Trace(Visitor* visitor) {
Supplement<LocalFrame>::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
visitor->Trace(client_);
}
@@ -48,7 +48,7 @@ UserMediaClient* UserMediaController::Client() {
return client_;
}
-void UserMediaController::ContextDestroyed(ExecutionContext*) {
+void UserMediaController::ContextDestroyed() {
if (!client_)
return;
client_->ContextDestroyed();
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 d674cb7271c..617ee8a13bc 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
@@ -27,7 +27,7 @@
#include <memory>
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/modules/mediastream/user_media_client.h"
@@ -39,14 +39,14 @@ class UserMediaRequest;
class UserMediaController final : public GarbageCollected<UserMediaController>,
public Supplement<LocalFrame>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(UserMediaController);
public:
static const char kSupplementName[];
UserMediaController(LocalFrame&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
UserMediaClient* Client();
@@ -56,8 +56,8 @@ class UserMediaController final : public GarbageCollected<UserMediaController>,
void StopTrack(MediaStreamComponent*);
bool HasRequestedUserMedia();
- // ContextLifecycleObserver implementation.
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver implementation.
+ void ContextDestroyed() override;
static UserMediaController* From(LocalFrame* frame) {
return Supplement<LocalFrame>::From<UserMediaController>(frame);
@@ -75,7 +75,7 @@ inline void UserMediaController::RequestUserMedia(UserMediaRequest* request) {
inline void UserMediaController::CancelUserMediaRequest(
UserMediaRequest* request) {
- Client()->CancelUserMediaRequest(WebUserMediaRequest(request));
+ Client()->CancelUserMediaRequest(request);
}
inline void UserMediaController::ApplyConstraints(
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 f924da3c536..4ed80c6970d 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
@@ -21,7 +21,6 @@
#include "third_party/blink/public/common/mediastream/media_stream_controls.h"
#include "third_party/blink/public/common/mediastream/media_stream_request.h"
#include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h"
-#include "third_party/blink/public/platform/web_media_constraints.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"
@@ -43,11 +42,13 @@
#include "third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.h"
#include "third_party/blink/renderer/modules/mediastream/processed_local_audio_source.h"
#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/webrtc_uma_histograms.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/video_capture/local_video_capturer_source.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
#include "ui/gfx/geometry/size.h"
@@ -59,12 +60,6 @@ struct CrossThreadCopier<blink::WebMediaStream>
STATIC_ONLY(CrossThreadCopier);
};
-template <>
-struct CrossThreadCopier<blink::WebUserMediaRequest>
- : public CrossThreadCopierPassThrough<blink::WebUserMediaRequest> {
- STATIC_ONLY(CrossThreadCopier);
-};
-
} // namespace WTF
namespace blink {
@@ -77,19 +72,99 @@ using EchoCancellationType =
namespace {
-void InitializeAudioTrackControls(const blink::WebUserMediaRequest& web_request,
+const char* MediaStreamRequestResultToString(MediaStreamRequestResult value) {
+ switch (value) {
+ case MediaStreamRequestResult::OK:
+ return "OK";
+ case MediaStreamRequestResult::PERMISSION_DENIED:
+ return "PERMISSION_DENIED";
+ case MediaStreamRequestResult::PERMISSION_DISMISSED:
+ return "PERMISSION_DISMISSED";
+ case MediaStreamRequestResult::INVALID_STATE:
+ return "INVALID_STATE";
+ case MediaStreamRequestResult::NO_HARDWARE:
+ return "NO_HARDWARE";
+ case MediaStreamRequestResult::INVALID_SECURITY_ORIGIN:
+ return "INVALID_SECURITY_ORIGIN";
+ case MediaStreamRequestResult::TAB_CAPTURE_FAILURE:
+ return "TAB_CAPTURE_FAILURE";
+ case MediaStreamRequestResult::SCREEN_CAPTURE_FAILURE:
+ return "SCREEN_CAPTURE_FAILURE";
+ case MediaStreamRequestResult::CAPTURE_FAILURE:
+ return "CAPTURE_FAILURE";
+ case MediaStreamRequestResult::CONSTRAINT_NOT_SATISFIED:
+ return "CONSTRAINT_NOT_SATISFIED";
+ case MediaStreamRequestResult::TRACK_START_FAILURE_AUDIO:
+ return "TRACK_START_FAILURE_AUDIO";
+ case MediaStreamRequestResult::TRACK_START_FAILURE_VIDEO:
+ return "TRACK_START_FAILURE_VIDEO";
+ case MediaStreamRequestResult::NOT_SUPPORTED:
+ return "NOT_SUPPORTED";
+ case MediaStreamRequestResult::FAILED_DUE_TO_SHUTDOWN:
+ return "FAILED_DUE_TO_SHUTDOWN";
+ case MediaStreamRequestResult::KILL_SWITCH_ON:
+ return "KILL_SWITCH_ON";
+ case MediaStreamRequestResult::SYSTEM_PERMISSION_DENIED:
+ return "SYSTEM_PERMISSION_DENIED";
+ case MediaStreamRequestResult::NUM_MEDIA_REQUEST_RESULTS:
+ return "NUM_MEDIA_REQUEST_RESULTS";
+ default:
+ NOTREACHED();
+ }
+ return "INVALID";
+}
+
+void SendLogMessage(const std::string& message) {
+ blink::WebRtcLogMessage("UMP::" + message);
+}
+
+std::string GetTrackLogString(const blink::WebMediaStreamTrack& track,
+ 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(),
+ is_pending);
+ return str.Utf8();
+}
+
+std::string GetTrackSourceLogString(blink::MediaStreamAudioSource* source) {
+ const MediaStreamDevice& device = source->device();
+ StringBuilder builder;
+ builder.AppendFormat("StartAudioTrack(source: {session_id=%s}, ",
+ device.session_id().ToString().c_str());
+ builder.AppendFormat("{is_local_source=%d}, ", source->is_local_source());
+ builder.AppendFormat("{device=[id: %s", device.id.c_str());
+ if (device.group_id.has_value()) {
+ builder.AppendFormat(", group_id: %s", device.group_id.value().c_str());
+ }
+ builder.AppendFormat(", name: %s", device.name.c_str());
+ builder.Append(String("]})"));
+ return builder.ToString().Utf8();
+}
+
+std::string GetOnTrackStartedLogString(
+ blink::WebPlatformMediaStreamSource* source,
+ MediaStreamRequestResult result) {
+ const MediaStreamDevice& device = source->device();
+ String str = String::Format("OnTrackStarted({session_id=%s}, {result=%s})",
+ device.session_id().ToString().c_str(),
+ MediaStreamRequestResultToString(result));
+ return str.Utf8();
+}
+
+void InitializeAudioTrackControls(UserMediaRequest* user_media_request,
TrackControls* track_controls) {
- if (web_request.MediaRequestType() ==
- blink::WebUserMediaRequest::MediaType::kDisplayMedia) {
+ if (user_media_request->MediaRequestType() ==
+ UserMediaRequest::MediaType::kDisplayMedia) {
track_controls->requested = true;
track_controls->stream_type = MediaStreamType::DISPLAY_AUDIO_CAPTURE;
return;
}
- DCHECK_EQ(blink::WebUserMediaRequest::MediaType::kUserMedia,
- web_request.MediaRequestType());
- const blink::WebMediaConstraints& constraints =
- web_request.AudioConstraints();
+ DCHECK_EQ(UserMediaRequest::MediaType::kUserMedia,
+ user_media_request->MediaRequestType());
+ const MediaConstraints& constraints = user_media_request->AudioConstraints();
DCHECK(!constraints.IsNull());
track_controls->requested = true;
@@ -97,7 +172,7 @@ void InitializeAudioTrackControls(const blink::WebUserMediaRequest& web_request,
*stream_type = MediaStreamType::NO_SERVICE;
String source_constraint =
- constraints.Basic().media_stream_source.Exact().empty()
+ constraints.Basic().media_stream_source.Exact().IsEmpty()
? String()
: String(constraints.Basic().media_stream_source.Exact()[0]);
if (!source_constraint.IsEmpty()) {
@@ -112,19 +187,18 @@ void InitializeAudioTrackControls(const blink::WebUserMediaRequest& web_request,
}
}
-void InitializeVideoTrackControls(const blink::WebUserMediaRequest& web_request,
+void InitializeVideoTrackControls(UserMediaRequest* user_media_request,
TrackControls* track_controls) {
- if (web_request.MediaRequestType() ==
- blink::WebUserMediaRequest::MediaType::kDisplayMedia) {
+ if (user_media_request->MediaRequestType() ==
+ UserMediaRequest::MediaType::kDisplayMedia) {
track_controls->requested = true;
track_controls->stream_type = MediaStreamType::DISPLAY_VIDEO_CAPTURE;
return;
}
- DCHECK_EQ(blink::WebUserMediaRequest::MediaType::kUserMedia,
- web_request.MediaRequestType());
- const blink::WebMediaConstraints& constraints =
- web_request.VideoConstraints();
+ DCHECK_EQ(UserMediaRequest::MediaType::kUserMedia,
+ user_media_request->MediaRequestType());
+ const MediaConstraints& constraints = user_media_request->VideoConstraints();
DCHECK(!constraints.IsNull());
track_controls->requested = true;
@@ -132,7 +206,7 @@ void InitializeVideoTrackControls(const blink::WebUserMediaRequest& web_request,
*stream_type = MediaStreamType::NO_SERVICE;
String source_constraint =
- constraints.Basic().media_stream_source.Exact().empty()
+ constraints.Basic().media_stream_source.Exact().IsEmpty()
? String()
: String(constraints.Basic().media_stream_source.Exact()[0]);
if (!source_constraint.IsEmpty()) {
@@ -220,33 +294,13 @@ std::vector<T> ToStdVector(const Vector<T>& format_vector) {
return formats;
}
-media::VideoFacingMode ToMediaVideoFacingMode(
- mojom::blink::FacingMode facing_mode) {
- switch (facing_mode) {
- case mojom::FacingMode::NONE:
- return media::MEDIA_VIDEO_FACING_NONE;
- case mojom::FacingMode::USER:
- return media::MEDIA_VIDEO_FACING_USER;
- case mojom::FacingMode::ENVIRONMENT:
- return media::MEDIA_VIDEO_FACING_ENVIRONMENT;
- case mojom::FacingMode::LEFT:
- case mojom::FacingMode::RIGHT:
- NOTREACHED();
- }
- return media::MEDIA_VIDEO_FACING_NONE;
-}
-
Vector<blink::VideoInputDeviceCapabilities> ToVideoInputDeviceCapabilities(
const Vector<blink::mojom::blink::VideoInputDeviceCapabilitiesPtr>&
input_capabilities) {
Vector<blink::VideoInputDeviceCapabilities> capabilities;
for (const auto& capability : input_capabilities) {
- // TODO(crbug.com/704136): Make the conversion from mojom::blink::FacingMode
- // to be handled automatically, eg by making media_devices.typemap work in
- // blink/renderer/platform/mojo/blink_typemaps.gni.
capabilities.emplace_back(capability->device_id, capability->group_id,
- capability->formats,
- ToMediaVideoFacingMode(capability->facing_mode));
+ capability->formats, capability->facing_mode);
}
return capabilities;
@@ -254,14 +308,6 @@ Vector<blink::VideoInputDeviceCapabilities> ToVideoInputDeviceCapabilities(
} // namespace
-UserMediaRequestInfo::UserMediaRequestInfo(
- int request_id,
- const blink::WebUserMediaRequest& web_request,
- bool is_processing_user_gesture)
- : request_id(request_id),
- web_request(web_request),
- is_processing_user_gesture(is_processing_user_gesture) {}
-
// Class for storing state of the the processing of getUserMedia requests.
class UserMediaProcessor::RequestInfo final
: public GarbageCollected<UserMediaProcessor::RequestInfo> {
@@ -276,7 +322,7 @@ class UserMediaProcessor::RequestInfo final
GENERATED,
};
- explicit RequestInfo(std::unique_ptr<UserMediaRequestInfo> request);
+ explicit RequestInfo(UserMediaRequest* request);
void StartAudioTrack(const blink::WebMediaStreamTrack& track,
bool is_pending);
@@ -292,8 +338,8 @@ class UserMediaProcessor::RequestInfo final
MediaStreamRequestResult result,
const String& result_name);
- UserMediaRequestInfo* request() { return request_.get(); }
- int request_id() const { return request_->request_id; }
+ UserMediaRequest* request() { return request_; }
+ int request_id() const { return request_->request_id(); }
State state() const { return state_; }
void set_state(State state) { state_ = state; }
@@ -355,17 +401,13 @@ class UserMediaProcessor::RequestInfo final
blink::WebMediaStream* web_stream() { return &web_stream_; }
- const blink::WebUserMediaRequest& web_request() const {
- return request_->web_request;
- }
-
StreamControls* stream_controls() { return &stream_controls_; }
bool is_processing_user_gesture() const {
- return request_->is_processing_user_gesture;
+ return request_->has_transient_user_activation();
}
- void Trace(Visitor* visitor) {}
+ void Trace(Visitor* visitor) { visitor->Trace(request_); }
private:
void OnTrackStarted(blink::WebPlatformMediaStreamSource* source,
@@ -377,7 +419,7 @@ class UserMediaProcessor::RequestInfo final
// that |this| might be deleted when the function returns.
void CheckAllTracksStarted();
- std::unique_ptr<UserMediaRequestInfo> request_;
+ Member<UserMediaRequest> request_;
State state_ = State::NOT_SENT_FOR_GENERATION;
blink::AudioCaptureSettings audio_capture_settings_;
bool is_audio_content_capture_ = false;
@@ -398,20 +440,21 @@ class UserMediaProcessor::RequestInfo final
// TODO(guidou): Initialize request_result_name_ as a null WTF::String.
// https://crbug.com/764293
-UserMediaProcessor::RequestInfo::RequestInfo(
- std::unique_ptr<UserMediaRequestInfo> request)
- : request_(std::move(request)), request_result_name_("") {}
+UserMediaProcessor::RequestInfo::RequestInfo(UserMediaRequest* request)
+ : request_(request), request_result_name_("") {}
void UserMediaProcessor::RequestInfo::StartAudioTrack(
const blink::WebMediaStreamTrack& track,
bool is_pending) {
DCHECK(track.Source().GetType() == blink::WebMediaStreamSource::kTypeAudio);
- DCHECK(web_request().Audio());
+ 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(GetTrackSourceLogString(native_source));
// Add the source as pending since OnTrackStarted will expect it to be there.
sources_waiting_for_callback_.push_back(native_source);
@@ -430,8 +473,11 @@ blink::WebMediaStreamTrack
UserMediaProcessor::RequestInfo::CreateAndStartVideoTrack(
const blink::WebMediaStreamSource& source) {
DCHECK(source.GetType() == blink::WebMediaStreamSource::kTypeVideo);
- DCHECK(web_request().Video());
+ 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);
DCHECK(native_source);
@@ -457,7 +503,7 @@ void UserMediaProcessor::RequestInfo::OnTrackStarted(
blink::WebPlatformMediaStreamSource* source,
MediaStreamRequestResult result,
const blink::WebString& result_name) {
- DVLOG(1) << "OnTrackStarted result " << result;
+ SendLogMessage(GetOnTrackStartedLogString(source, result));
auto** it = std::find(sources_waiting_for_callback_.begin(),
sources_waiting_for_callback_.end(), source);
DCHECK(it != sources_waiting_for_callback_.end());
@@ -505,24 +551,24 @@ UserMediaProcessor::~UserMediaProcessor() {
!local_sources_.size());
}
-UserMediaRequestInfo* UserMediaProcessor::CurrentRequest() {
+UserMediaRequest* UserMediaProcessor::CurrentRequest() {
return current_request_info_ ? current_request_info_->request() : nullptr;
}
-void UserMediaProcessor::ProcessRequest(
- std::unique_ptr<UserMediaRequestInfo> request,
- base::OnceClosure callback) {
+void UserMediaProcessor::ProcessRequest(UserMediaRequest* request,
+ base::OnceClosure callback) {
DCHECK(!request_completed_cb_);
DCHECK(!current_request_info_);
request_completed_cb_ = std::move(callback);
- current_request_info_ = MakeGarbageCollected<RequestInfo>(std::move(request));
- blink::WebRtcLogMessage(base::StringPrintf(
- "UMP::ProcessRequest. request_id=%d. Has audio=%d. Has video=%d.",
- current_request_info_->request_id(),
- current_request_info_->request()->web_request.Audio(),
- current_request_info_->request()->web_request.Video()));
+ current_request_info_ = MakeGarbageCollected<RequestInfo>(request);
+ SendLogMessage(
+ base::StringPrintf("ProcessRequest({request_id=%d}, {audio=%d}, "
+ "{video=%d})",
+ current_request_info_->request_id(),
+ current_request_info_->request()->Audio(),
+ current_request_info_->request()->Video()));
// TODO(guidou): Set up audio and video in parallel.
- if (current_request_info_->web_request().Audio()) {
+ if (current_request_info_->request()->Audio()) {
SetupAudioInput();
return;
}
@@ -532,39 +578,40 @@ void UserMediaProcessor::ProcessRequest(
void UserMediaProcessor::SetupAudioInput() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(current_request_info_);
- DCHECK(current_request_info_->web_request().Audio());
- blink::WebRtcLogMessage(base::StringPrintf(
- "UMP::SetupAudioInput. request_id=%d, audio constraints=%s",
- current_request_info_->request_id(),
- current_request_info_->request()
- ->web_request.AudioConstraints()
- .ToString()
- .Utf8()
- .c_str()));
+ DCHECK(current_request_info_->request()->Audio());
+ SendLogMessage(
+ base::StringPrintf("SetupAudioInput({request_id=%d}, {constraints=%s})",
+ current_request_info_->request_id(),
+ current_request_info_->request()
+ ->AudioConstraints()
+ .ToString()
+ .Utf8()
+ .c_str()));
auto& audio_controls = current_request_info_->stream_controls()->audio;
- InitializeAudioTrackControls(current_request_info_->web_request(),
+ InitializeAudioTrackControls(current_request_info_->request(),
&audio_controls);
if (audio_controls.stream_type == MediaStreamType::DISPLAY_AUDIO_CAPTURE) {
- SelectAudioSettings(current_request_info_->web_request(),
+ SelectAudioSettings(current_request_info_->request(),
{blink::AudioDeviceCaptureCapability()});
return;
}
if (blink::IsDeviceMediaType(audio_controls.stream_type)) {
- blink::WebRtcLogMessage(
- base::StringPrintf("UMP::SetupAudioInput. request_id=%d, "
- "Requesting device capabilities",
+ SendLogMessage(
+ base::StringPrintf("SetupAudioInput({request_id=%d}) => "
+ "(Requesting device capabilities)",
current_request_info_->request_id()));
- GetMediaDevicesDispatcher()->GetAudioInputCapabilities(WTF::Bind(
- &UserMediaProcessor::SelectAudioDeviceSettings,
- WrapWeakPersistent(this), current_request_info_->web_request()));
+ GetMediaDevicesDispatcher()->GetAudioInputCapabilities(
+ WTF::Bind(&UserMediaProcessor::SelectAudioDeviceSettings,
+ WrapWeakPersistent(this),
+ WrapPersistent(current_request_info_->request())));
} else {
if (!blink::IsAudioInputMediaType(audio_controls.stream_type)) {
String failed_constraint_name =
- String(current_request_info_->web_request()
- .AudioConstraints()
+ String(current_request_info_->request()
+ ->AudioConstraints()
.Basic()
.media_stream_source.GetName());
MediaStreamRequestResult result =
@@ -572,13 +619,13 @@ void UserMediaProcessor::SetupAudioInput() {
GetUserMediaRequestFailed(result, failed_constraint_name);
return;
}
- SelectAudioSettings(current_request_info_->web_request(),
+ SelectAudioSettings(current_request_info_->request(),
{blink::AudioDeviceCaptureCapability()});
}
}
void UserMediaProcessor::SelectAudioDeviceSettings(
- const blink::WebUserMediaRequest& web_request,
+ UserMediaRequest* user_media_request,
Vector<blink::mojom::blink::AudioInputDeviceCapabilitiesPtr>
audio_input_capabilities) {
blink::AudioDeviceCaptureCapabilities capabilities;
@@ -608,26 +655,25 @@ void UserMediaProcessor::SelectAudioDeviceSettings(
}
}
- SelectAudioSettings(web_request, capabilities);
+ SelectAudioSettings(user_media_request, capabilities);
}
void UserMediaProcessor::SelectAudioSettings(
- const blink::WebUserMediaRequest& web_request,
+ UserMediaRequest* user_media_request,
const blink::AudioDeviceCaptureCapabilities& capabilities) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- // The frame might reload or |web_request| might be cancelled while
+ // The frame might reload or |user_media_request| might be cancelled while
// capabilities are queried. Do nothing if a different request is being
// processed at this point.
- if (!IsCurrentRequestInfo(web_request))
+ if (!IsCurrentRequestInfo(user_media_request))
return;
DCHECK(current_request_info_->stream_controls()->audio.requested);
- blink::WebRtcLogMessage(
- base::StringPrintf("UMP::SelectAudioSettings. request_id=%d.",
- current_request_info_->request_id()));
+ SendLogMessage(base::StringPrintf("SelectAudioSettings({request_id=%d})",
+ current_request_info_->request_id()));
auto settings = SelectSettingsAudioCapture(
- capabilities, web_request.AudioConstraints(),
- web_request.ShouldDisableHardwareNoiseSuppression(),
+ capabilities, user_media_request->AudioConstraints(),
+ user_media_request->ShouldDisableHardwareNoiseSuppression(),
true /* is_reconfiguration_allowed */);
if (!settings.HasValue()) {
String failed_constraint_name = String(settings.failed_constraint_name());
@@ -656,7 +702,7 @@ void UserMediaProcessor::SelectAudioSettings(
base::Optional<base::UnguessableToken>
UserMediaProcessor::DetermineExistingAudioSessionId() {
- DCHECK(current_request_info_->web_request().Audio());
+ DCHECK(current_request_info_->request()->Audio());
auto settings = current_request_info_->audio_capture_settings();
auto device_id = settings.device_id();
@@ -668,7 +714,9 @@ UserMediaProcessor::DetermineExistingAudioSessionId() {
std::back_inserter(matching_sources),
[&device_id](const blink::WebMediaStreamSource& web_source) {
DCHECK(!web_source.IsNull());
- return web_source.Id().Utf8() == device_id;
+ return web_source.GetType() ==
+ WebMediaStreamSource::kTypeAudio &&
+ web_source.Id().Utf8() == device_id;
});
// Return the session ID associated to the source that has the same settings
@@ -692,7 +740,7 @@ void UserMediaProcessor::SetupVideoInput() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(current_request_info_);
- if (!current_request_info_->web_request().Video()) {
+ if (!current_request_info_->request()->Video()) {
base::Optional<base::UnguessableToken> audio_session_id =
DetermineExistingAudioSessionId();
GenerateStreamForCurrentRequestInfo(
@@ -701,27 +749,28 @@ void UserMediaProcessor::SetupVideoInput() {
: StreamSelectionStrategy::FORCE_NEW_STREAM);
return;
}
- blink::WebRtcLogMessage(base::StringPrintf(
- "UMP::SetupVideoInput. request_id=%d, video constraints=%s",
- current_request_info_->request_id(),
- current_request_info_->request()
- ->web_request.VideoConstraints()
- .ToString()
- .Utf8()
- .c_str()));
+ SendLogMessage(
+ base::StringPrintf("SetupVideoInput. request_id=%d, video constraints=%s",
+ current_request_info_->request_id(),
+ current_request_info_->request()
+ ->VideoConstraints()
+ .ToString()
+ .Utf8()
+ .c_str()));
auto& video_controls = current_request_info_->stream_controls()->video;
- InitializeVideoTrackControls(current_request_info_->web_request(),
+ InitializeVideoTrackControls(current_request_info_->request(),
&video_controls);
if (blink::IsDeviceMediaType(video_controls.stream_type)) {
- GetMediaDevicesDispatcher()->GetVideoInputCapabilities(WTF::Bind(
- &UserMediaProcessor::SelectVideoDeviceSettings,
- WrapWeakPersistent(this), current_request_info_->web_request()));
+ GetMediaDevicesDispatcher()->GetVideoInputCapabilities(
+ WTF::Bind(&UserMediaProcessor::SelectVideoDeviceSettings,
+ WrapWeakPersistent(this),
+ WrapPersistent(current_request_info_->request())));
} else {
if (!blink::IsVideoInputMediaType(video_controls.stream_type)) {
String failed_constraint_name =
- String(current_request_info_->web_request()
- .VideoConstraints()
+ String(current_request_info_->request()
+ ->VideoConstraints()
.Basic()
.media_stream_source.GetName());
MediaStreamRequestResult result =
@@ -734,22 +783,21 @@ void UserMediaProcessor::SetupVideoInput() {
}
void UserMediaProcessor::SelectVideoDeviceSettings(
- const blink::WebUserMediaRequest& web_request,
+ UserMediaRequest* user_media_request,
Vector<blink::mojom::blink::VideoInputDeviceCapabilitiesPtr>
video_input_capabilities) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- // The frame might reload or |web_request| might be cancelled while
+ // The frame might reload or |user_media_request| might be cancelled while
// capabilities are queried. Do nothing if a different request is being
// processed at this point.
- if (!IsCurrentRequestInfo(web_request))
+ if (!IsCurrentRequestInfo(user_media_request))
return;
DCHECK(current_request_info_->stream_controls()->video.requested);
DCHECK(blink::IsDeviceMediaType(
current_request_info_->stream_controls()->video.stream_type));
- blink::WebRtcLogMessage(
- base::StringPrintf("UMP::SelectVideoDeviceSettings. request_id=%d.",
- current_request_info_->request_id()));
+ SendLogMessage(base::StringPrintf("SelectVideoDeviceSettings. request_id=%d.",
+ current_request_info_->request_id()));
blink::VideoDeviceCaptureCapabilities capabilities;
capabilities.device_capabilities =
@@ -758,7 +806,7 @@ void UserMediaProcessor::SelectVideoDeviceSettings(
base::Optional<bool>(true),
base::Optional<bool>(false)};
blink::VideoCaptureSettings settings = SelectSettingsVideoDeviceCapture(
- std::move(capabilities), web_request.VideoConstraints(),
+ std::move(capabilities), user_media_request->VideoConstraints(),
blink::MediaStreamVideoSource::kDefaultWidth,
blink::MediaStreamVideoSource::kDefaultHeight,
blink::MediaStreamVideoSource::kDefaultFrameRate);
@@ -776,7 +824,7 @@ void UserMediaProcessor::SelectVideoDeviceSettings(
current_request_info_->SetVideoCaptureSettings(
settings, false /* is_content_capture */);
- if (current_request_info_->web_request().Audio()) {
+ if (current_request_info_->request()->Audio()) {
base::Optional<base::UnguessableToken> audio_session_id =
DetermineExistingAudioSessionId();
GenerateStreamForCurrentRequestInfo(
@@ -791,13 +839,13 @@ void UserMediaProcessor::SelectVideoDeviceSettings(
void UserMediaProcessor::SelectVideoContentSettings() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(current_request_info_);
- blink::WebRtcLogMessage(
- base::StringPrintf("UMP::SelectVideoContentSettings. request_id=%d.",
+ SendLogMessage(
+ base::StringPrintf("SelectVideoContentSettings. request_id=%d.",
current_request_info_->request_id()));
gfx::Size screen_size = GetScreenSize();
blink::VideoCaptureSettings settings =
blink::SelectSettingsVideoContentCapture(
- current_request_info_->web_request().VideoConstraints(),
+ current_request_info_->request()->VideoConstraints(),
current_request_info_->stream_controls()->video.stream_type,
screen_size.width(), screen_size.height());
if (!settings.HasValue()) {
@@ -824,9 +872,9 @@ void UserMediaProcessor::GenerateStreamForCurrentRequestInfo(
blink::mojom::StreamSelectionStrategy strategy) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(current_request_info_);
- blink::WebRtcLogMessage(base::StringPrintf(
- "UMP::GenerateStreamForCurrentRequestInfo. request_id=%d, "
- "audio device id=\"%s\", video device id=\"%s\"",
+ SendLogMessage(base::StringPrintf(
+ "GenerateStreamForCurrentRequestInfo({request_id=%d}, "
+ "{audio.device_id=%s}, {video.device_id=%s})",
current_request_info_->request_id(),
current_request_info_->stream_controls()->audio.device_id.c_str(),
current_request_info_->stream_controls()->video.device_id.c_str()));
@@ -875,24 +923,25 @@ void UserMediaProcessor::OnStreamGenerated(
}
if (!IsCurrentRequestInfo(request_id)) {
- // This can happen if the request is cancelled or the frame reloads while
+ // This can happen if the request is canceled or the frame reloads while
// MediaStreamDispatcherHost is processing the request.
- DVLOG(1) << "Request ID not found";
+ SendLogMessage(base::StringPrintf(
+ "OnStreamGenerated([request_id=%d]) => (ERROR: invalid request ID)",
+ request_id));
OnStreamGeneratedForCancelledRequest(audio_devices, video_devices);
return;
}
- blink::WebRtcLogMessage(
- base::StringPrintf("UMP::OnStreamGenerated. request_id=%d.",
- current_request_info_->request_id()));
current_request_info_->set_state(RequestInfo::State::GENERATED);
for (const auto* devices : {&audio_devices, &video_devices}) {
for (const auto& device : *devices) {
- blink::WebRtcLogMessage(base::StringPrintf(
- "UMP::OnStreamGenerated. request_id=%d, device id=\"%s\", "
- "device name=\"%s\"",
- request_id, device.id.c_str(), device.name.c_str()));
+ SendLogMessage(base::StringPrintf(
+ "OnStreamGenerated({request_id=%d}, {label=%s}, {device=[id: %s, "
+ "name: "
+ "%s]})",
+ request_id, label.Utf8().c_str(), device.id.c_str(),
+ device.name.c_str()));
}
}
@@ -918,28 +967,38 @@ void UserMediaProcessor::OnStreamGenerated(
}
for (const auto& video_device : video_devices) {
+ SendLogMessage(base::StringPrintf(
+ "OnStreamGenerated({request_id=%d}, {label=%s}, {device=[id: %s, "
+ "name: %s]}) => (Requesting video device formats)",
+ request_id, label.Utf8().c_str(), video_device.id.c_str(),
+ video_device.name.c_str()));
String video_device_id(video_device.id.data());
GetMediaDevicesDispatcher()->GetAllVideoInputDeviceFormats(
video_device_id,
WTF::Bind(&UserMediaProcessor::GotAllVideoInputFormatsForDevice,
WrapWeakPersistent(this),
- current_request_info_->web_request(), label,
+ WrapPersistent(current_request_info_->request()), label,
video_device_id));
}
}
void UserMediaProcessor::GotAllVideoInputFormatsForDevice(
- const blink::WebUserMediaRequest& web_request,
+ UserMediaRequest* user_media_request,
const String& label,
const String& device_id,
const Vector<media::VideoCaptureFormat>& formats) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- // The frame might reload or |web_request| might be cancelled while video
- // formats are queried. Do nothing if a different request is being processed
- // at this point.
- if (!IsCurrentRequestInfo(web_request))
+ // The frame might reload or |user_media_request| might be cancelled while
+ // video formats are queried. Do nothing if a different request is being
+ // processed at this point.
+ if (!IsCurrentRequestInfo(user_media_request))
return;
+ SendLogMessage(
+ base::StringPrintf("GotAllVideoInputFormatsForDevice({request_id=%d}, "
+ "{label=%s}, {device=[id: %s]})",
+ current_request_info_->request_id(),
+ label.Utf8().c_str(), device_id.Utf8().c_str()));
current_request_info_->AddNativeVideoFormats(device_id, formats);
if (current_request_info_->CanStartTracks())
StartTracks(label);
@@ -959,7 +1018,7 @@ gfx::Size UserMediaProcessor::GetScreenSize() {
void UserMediaProcessor::OnStreamGeneratedForCancelledRequest(
const Vector<MediaStreamDevice>& audio_devices,
const Vector<MediaStreamDevice>& video_devices) {
- blink::WebRtcLogMessage("UMP::OnStreamGeneratedForCancelledRequest.");
+ SendLogMessage("OnStreamGeneratedForCancelledRequest()");
// Only stop the device if the device is not used in another MediaStream.
for (auto* it = audio_devices.begin(); it != audio_devices.end(); ++it) {
if (!FindLocalSource(*it)) {
@@ -1028,22 +1087,22 @@ void UserMediaProcessor::OnStreamGenerationFailed(
MediaStreamRequestResult result) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (!IsCurrentRequestInfo(request_id)) {
- // This can happen if the request is cancelled or the frame reloads while
+ // This can happen if the request is canceled or the frame reloads while
// MediaStreamDispatcherHost is processing the request.
return;
}
- blink::WebRtcLogMessage(
- base::StringPrintf("UMP::OnStreamGenerationFailed. request_id=%d.",
- current_request_info_->request_id()));
+ SendLogMessage(base::StringPrintf("OnStreamGenerationFailed({request_id=%d})",
+ current_request_info_->request_id()));
GetUserMediaRequestFailed(result);
- DeleteWebRequest(current_request_info_->web_request());
+ DeleteUserMediaRequest(current_request_info_->request());
}
void UserMediaProcessor::OnDeviceStopped(const MediaStreamDevice& device) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DVLOG(1) << "UserMediaProcessor::OnDeviceStopped("
- << "{device_id = " << device.id << "})";
+ SendLogMessage(base::StringPrintf(
+ "OnDeviceStopped({session_id=%s}, {device_id=%s})",
+ device.session_id().ToString().c_str(), device.id.c_str()));
const blink::WebMediaStreamSource* source_ptr = FindLocalSource(device);
if (!source_ptr) {
@@ -1062,6 +1121,7 @@ void UserMediaProcessor::OnDeviceStopped(const MediaStreamDevice& device) {
void UserMediaProcessor::OnDeviceChanged(const MediaStreamDevice& old_device,
const MediaStreamDevice& new_device) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ // TODO(https://crbug.com/1017219): possibly useful in native logs as well.
DVLOG(1) << "UserMediaProcessor::OnDeviceChange("
<< "{old_device_id = " << old_device.id
<< ", session id = " << old_device.session_id()
@@ -1103,7 +1163,11 @@ blink::WebMediaStreamSource UserMediaProcessor::InitializeVideoSourceObject(
const MediaStreamDevice& device) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(current_request_info_);
-
+ SendLogMessage(base::StringPrintf(
+ "UMP::InitializeVideoSourceObject({request_id=%d}, {device=[id: %s, "
+ "name: %s]})",
+ current_request_info_->request_id(), device.id.c_str(),
+ device.name.c_str()));
blink::WebMediaStreamSource source = FindOrInitializeSourceObject(device);
if (!source.GetPlatformSource()) {
source.SetPlatformSource(CreateVideoSource(
@@ -1127,6 +1191,9 @@ blink::WebMediaStreamSource UserMediaProcessor::InitializeAudioSourceObject(
bool* is_pending) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(current_request_info_);
+ SendLogMessage(
+ base::StringPrintf("InitializeAudioSourceObject({session_id=%s})",
+ device.session_id().ToString().c_str()));
*is_pending = true;
@@ -1244,14 +1311,8 @@ UserMediaProcessor::CreateAudioSource(
// The audio device is not associated with screen capture and also requires
// processing.
- //
- // TODO(crbug.com/c/704136): Convert ProcessedLocalAudioSource ctor to
- // operate over LocalFrame instead of WebLocalFrame.
- WebLocalFrame* web_frame =
- frame_ ? static_cast<WebLocalFrame*>(WebFrame::FromFrame(frame_))
- : nullptr;
return std::make_unique<blink::ProcessedLocalAudioSource>(
- web_frame, device, stream_controls->disable_local_echo,
+ frame_, device, stream_controls->disable_local_echo,
audio_processing_properties, std::move(source_ready), task_runner_);
}
@@ -1272,7 +1333,10 @@ UserMediaProcessor::CreateVideoSource(
}
void UserMediaProcessor::StartTracks(const String& label) {
- DCHECK(!current_request_info_->web_request().IsNull());
+ DCHECK(current_request_info_->request());
+ SendLogMessage(base::StringPrintf("StartTracks({request_id=%d}, {label=%s})",
+ current_request_info_->request_id(),
+ label.Utf8().c_str()));
if (auto* media_stream_device_observer = GetMediaStreamDeviceObserver()) {
media_stream_device_observer->AddStream(
blink::WebString(label),
@@ -1310,6 +1374,8 @@ void UserMediaProcessor::CreateVideoTracks(
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(current_request_info_);
DCHECK_EQ(devices.size(), webkit_tracks->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 =
@@ -1331,6 +1397,9 @@ void UserMediaProcessor::CreateAudioTracks(
current_request_info_->audio_capture_settings().HasValue() &&
current_request_info_->audio_capture_settings()
.render_to_associated_sink();
+ SendLogMessage(
+ base::StringPrintf("CreateAudioTracks({render_to_associated_sink=%d})",
+ render_to_associated_sink));
if (!render_to_associated_sink) {
// If the GetUserMedia request did not explicitly set the constraint
// kMediaStreamRenderToAssociatedSink, the output device id must
@@ -1358,9 +1427,12 @@ void UserMediaProcessor::OnCreateNativeTracksCompleted(
MediaStreamRequestResult result,
const String& constraint_name) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ SendLogMessage(base::StringPrintf(
+ "UMP::OnCreateNativeTracksCompleted({request_id = %d}, {label=%s})",
+ request_info->request_id(), label.Utf8().c_str()));
if (result == MediaStreamRequestResult::OK) {
GetUserMediaRequestSucceeded(*request_info->web_stream(),
- request_info->web_request());
+ request_info->request());
GetMediaStreamDispatcherHost()->OnStreamStarted(label);
} else {
GetUserMediaRequestFailed(result, constraint_name);
@@ -1380,16 +1452,16 @@ void UserMediaProcessor::OnCreateNativeTracksCompleted(
}
}
- DeleteWebRequest(request_info->web_request());
+ DeleteUserMediaRequest(request_info->request());
}
void UserMediaProcessor::GetUserMediaRequestSucceeded(
const blink::WebMediaStream& stream,
- blink::WebUserMediaRequest web_request) {
+ UserMediaRequest* user_media_request) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(IsCurrentRequestInfo(web_request));
- blink::WebRtcLogMessage(
- base::StringPrintf("UMP::GetUserMediaRequestSucceeded. request_id=%d",
+ DCHECK(IsCurrentRequestInfo(user_media_request));
+ SendLogMessage(
+ base::StringPrintf("GetUserMediaRequestSucceeded({request_id=%d})",
current_request_info_->request_id()));
// Completing the getUserMedia request can lead to that the RenderFrame and
@@ -1399,17 +1471,22 @@ void UserMediaProcessor::GetUserMediaRequestSucceeded(
task_runner_->PostTask(
FROM_HERE,
WTF::Bind(&UserMediaProcessor::DelayedGetUserMediaRequestSucceeded,
- WrapWeakPersistent(this), stream, web_request));
+ WrapWeakPersistent(this), current_request_info_->request_id(),
+ stream, WrapPersistent(user_media_request)));
}
void UserMediaProcessor::DelayedGetUserMediaRequestSucceeded(
+ int request_id,
const blink::WebMediaStream& stream,
- blink::WebUserMediaRequest web_request) {
+ UserMediaRequest* user_media_request) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DVLOG(1) << "UserMediaProcessor::DelayedGetUserMediaRequestSucceeded";
+ SendLogMessage(base::StringPrintf(
+ "DelayedGetUserMediaRequestSucceeded({request_id=%d}, {result=%s})",
+ request_id,
+ MediaStreamRequestResultToString(MediaStreamRequestResult::OK)));
blink::LogUserMediaRequestResult(MediaStreamRequestResult::OK);
- DeleteWebRequest(web_request);
- web_request.RequestSucceeded(stream);
+ DeleteUserMediaRequest(user_media_request);
+ user_media_request->Succeed(stream);
}
void UserMediaProcessor::GetUserMediaRequestFailed(
@@ -1417,8 +1494,8 @@ void UserMediaProcessor::GetUserMediaRequestFailed(
const String& constraint_name) {
DCHECK(current_request_info_);
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- blink::WebRtcLogMessage(
- base::StringPrintf("UMP::GetUserMediaRequestFailed. request_id=%d",
+ SendLogMessage(
+ base::StringPrintf("GetUserMediaRequestFailed({request_id=%d})",
current_request_info_->request_id()));
// Completing the getUserMedia request can lead to that the RenderFrame and
@@ -1428,92 +1505,88 @@ void UserMediaProcessor::GetUserMediaRequestFailed(
task_runner_->PostTask(
FROM_HERE,
WTF::Bind(&UserMediaProcessor::DelayedGetUserMediaRequestFailed,
- WrapWeakPersistent(this), current_request_info_->web_request(),
- result, constraint_name));
+ WrapWeakPersistent(this), current_request_info_->request_id(),
+ WrapPersistent(current_request_info_->request()), result,
+ constraint_name));
}
void UserMediaProcessor::DelayedGetUserMediaRequestFailed(
- blink::WebUserMediaRequest web_request,
+ int request_id,
+ UserMediaRequest* user_media_request,
MediaStreamRequestResult result,
const String& constraint_name) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
blink::LogUserMediaRequestResult(result);
- DeleteWebRequest(web_request);
+ SendLogMessage(base::StringPrintf(
+ "DelayedGetUserMediaRequestFailed({request_id=%d}, {result=%s})",
+ request_id, MediaStreamRequestResultToString(result)));
+ DeleteUserMediaRequest(user_media_request);
switch (result) {
case MediaStreamRequestResult::OK:
case MediaStreamRequestResult::NUM_MEDIA_REQUEST_RESULTS:
NOTREACHED();
return;
case MediaStreamRequestResult::PERMISSION_DENIED:
- web_request.RequestFailed(
- blink::WebUserMediaRequest::Error::kPermissionDenied,
- "Permission denied");
+ user_media_request->Fail(UserMediaRequest::Error::kPermissionDenied,
+ "Permission denied");
return;
case MediaStreamRequestResult::PERMISSION_DISMISSED:
- web_request.RequestFailed(
- blink::WebUserMediaRequest::Error::kPermissionDismissed,
- "Permission dismissed");
+ user_media_request->Fail(UserMediaRequest::Error::kPermissionDismissed,
+ "Permission dismissed");
return;
case MediaStreamRequestResult::INVALID_STATE:
- web_request.RequestFailed(
- blink::WebUserMediaRequest::Error::kInvalidState, "Invalid state");
+ user_media_request->Fail(UserMediaRequest::Error::kInvalidState,
+ "Invalid state");
return;
case MediaStreamRequestResult::NO_HARDWARE:
- web_request.RequestFailed(
- blink::WebUserMediaRequest::Error::kDevicesNotFound,
- "Requested device not found");
+ user_media_request->Fail(UserMediaRequest::Error::kDevicesNotFound,
+ "Requested device not found");
return;
case MediaStreamRequestResult::INVALID_SECURITY_ORIGIN:
- web_request.RequestFailed(
- blink::WebUserMediaRequest::Error::kSecurityError,
- "Invalid security origin");
+ user_media_request->Fail(UserMediaRequest::Error::kSecurityError,
+ "Invalid security origin");
return;
case MediaStreamRequestResult::TAB_CAPTURE_FAILURE:
- web_request.RequestFailed(blink::WebUserMediaRequest::Error::kTabCapture,
- "Error starting tab capture");
+ user_media_request->Fail(UserMediaRequest::Error::kTabCapture,
+ "Error starting tab capture");
return;
case MediaStreamRequestResult::SCREEN_CAPTURE_FAILURE:
- web_request.RequestFailed(
- blink::WebUserMediaRequest::Error::kScreenCapture,
- "Error starting screen capture");
+ user_media_request->Fail(UserMediaRequest::Error::kScreenCapture,
+ "Error starting screen capture");
return;
case MediaStreamRequestResult::CAPTURE_FAILURE:
- web_request.RequestFailed(blink::WebUserMediaRequest::Error::kCapture,
- "Error starting capture");
+ user_media_request->Fail(UserMediaRequest::Error::kCapture,
+ "Error starting capture");
return;
case MediaStreamRequestResult::CONSTRAINT_NOT_SATISFIED:
- web_request.RequestFailedConstraint(constraint_name);
+ user_media_request->FailConstraint(constraint_name, "");
return;
case MediaStreamRequestResult::TRACK_START_FAILURE_AUDIO:
- web_request.RequestFailed(blink::WebUserMediaRequest::Error::kTrackStart,
- "Could not start audio source");
+ user_media_request->Fail(UserMediaRequest::Error::kTrackStart,
+ "Could not start audio source");
return;
case MediaStreamRequestResult::TRACK_START_FAILURE_VIDEO:
- web_request.RequestFailed(blink::WebUserMediaRequest::Error::kTrackStart,
- "Could not start video source");
+ user_media_request->Fail(UserMediaRequest::Error::kTrackStart,
+ "Could not start video source");
return;
case MediaStreamRequestResult::NOT_SUPPORTED:
- web_request.RequestFailed(
- blink::WebUserMediaRequest::Error::kNotSupported, "Not supported");
+ user_media_request->Fail(UserMediaRequest::Error::kNotSupported,
+ "Not supported");
return;
case MediaStreamRequestResult::FAILED_DUE_TO_SHUTDOWN:
- web_request.RequestFailed(
- blink::WebUserMediaRequest::Error::kFailedDueToShutdown,
- "Failed due to shutdown");
+ user_media_request->Fail(UserMediaRequest::Error::kFailedDueToShutdown,
+ "Failed due to shutdown");
return;
case MediaStreamRequestResult::KILL_SWITCH_ON:
- web_request.RequestFailed(
- blink::WebUserMediaRequest::Error::kKillSwitchOn);
+ user_media_request->Fail(UserMediaRequest::Error::kKillSwitchOn, "");
return;
case MediaStreamRequestResult::SYSTEM_PERMISSION_DENIED:
- web_request.RequestFailed(
- blink::WebUserMediaRequest::Error::kSystemPermissionDenied,
- "Permission denied by system");
+ user_media_request->Fail(UserMediaRequest::Error::kSystemPermissionDenied,
+ "Permission denied by system");
return;
}
NOTREACHED();
- web_request.RequestFailed(
- blink::WebUserMediaRequest::Error::kPermissionDenied);
+ user_media_request->Fail(UserMediaRequest::Error::kPermissionDenied, "");
}
const blink::WebMediaStreamSource* UserMediaProcessor::FindLocalSource(
@@ -1549,16 +1622,16 @@ blink::WebMediaStreamSource UserMediaProcessor::FindOrInitializeSourceObject(
false /* remote */);
if (device.group_id)
source.SetGroupId(blink::WebString::FromUTF8(*device.group_id));
-
- DVLOG(1) << "Initialize source object :"
- << "id = " << source.Id().Utf8()
- << ", name = " << source.GetName().Utf8();
return source;
}
bool UserMediaProcessor::RemoveLocalSource(
const blink::WebMediaStreamSource& source) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ SendLogMessage(base::StringPrintf(
+ "RemoveLocalSource({id=%s}, {name=%s}, {group_id=%s})",
+ source.Id().Utf8().c_str(), source.GetName().Utf8().c_str(),
+ source.GroupId().Utf8().c_str()));
for (auto* device_it = local_sources_.begin();
device_it != local_sources_.end(); ++device_it) {
@@ -1598,17 +1671,17 @@ bool UserMediaProcessor::IsCurrentRequestInfo(int request_id) const {
}
bool UserMediaProcessor::IsCurrentRequestInfo(
- const blink::WebUserMediaRequest& web_request) const {
+ UserMediaRequest* user_media_request) const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return current_request_info_ &&
- current_request_info_->web_request() == web_request;
+ current_request_info_->request() == user_media_request;
}
-bool UserMediaProcessor::DeleteWebRequest(
- const blink::WebUserMediaRequest& web_request) {
+bool UserMediaProcessor::DeleteUserMediaRequest(
+ UserMediaRequest* user_media_request) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (current_request_info_ &&
- current_request_info_->web_request() == web_request) {
+ current_request_info_->request() == user_media_request) {
current_request_info_ = nullptr;
std::move(request_completed_cb_).Run();
return true;
@@ -1651,12 +1724,14 @@ void UserMediaProcessor::StopAllProcessing() {
void UserMediaProcessor::OnLocalSourceStopped(
const blink::WebMediaStreamSource& source) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DVLOG(1) << "UserMediaProcessor::OnLocalSourceStopped";
+ blink::WebPlatformMediaStreamSource* source_impl = source.GetPlatformSource();
+ SendLogMessage(base::StringPrintf(
+ "OnLocalSourceStopped({session_id=%s})",
+ source_impl->device().session_id().ToString().c_str()));
const bool some_source_removed = RemoveLocalSource(source);
CHECK(some_source_removed);
- blink::WebPlatformMediaStreamSource* source_impl = source.GetPlatformSource();
if (auto* media_stream_device_observer = GetMediaStreamDeviceObserver())
media_stream_device_observer->RemoveStreamDevice(source_impl->device());
@@ -1669,8 +1744,9 @@ void UserMediaProcessor::StopLocalSource(
const blink::WebMediaStreamSource& source,
bool notify_dispatcher) {
blink::WebPlatformMediaStreamSource* source_impl = source.GetPlatformSource();
- DVLOG(1) << "UserMediaProcessor::StopLocalSource("
- << "{device_id = " << source_impl->device().id << "})";
+ SendLogMessage(base::StringPrintf(
+ "StopLocalSource({session_id=%s})",
+ source_impl->device().session_id().ToString().c_str()));
if (notify_dispatcher) {
if (auto* media_stream_device_observer = GetMediaStreamDeviceObserver())
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 ef5dbcef024..730cfd406b6 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
@@ -17,8 +17,8 @@
#include "third_party/blink/public/mojom/mediastream/media_devices.mojom-blink.h"
#include "third_party/blink/public/mojom/mediastream/media_stream.mojom-blink.h"
#include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h"
-#include "third_party/blink/public/web/web_user_media_request.h"
#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/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -38,17 +38,6 @@ class WebMediaStreamDeviceObserver;
class WebMediaStreamSource;
class WebString;
-// TODO(guidou): Add |request_id| and |is_processing_user_gesture| to
-// blink::WebUserMediaRequest and remove this struct.
-struct UserMediaRequestInfo {
- UserMediaRequestInfo(int request_id,
- const blink::WebUserMediaRequest& web_request,
- bool is_processing_user_gesture);
- const int request_id;
- const blink::WebUserMediaRequest web_request;
- const bool is_processing_user_gesture;
-};
-
// UserMediaProcessor is responsible for processing getUserMedia() requests.
// It also keeps tracks of all sources used by streams created with
// getUserMedia().
@@ -61,7 +50,7 @@ class MODULES_EXPORT UserMediaProcessor
public:
using MediaDevicesDispatcherCallback = base::RepeatingCallback<
blink::mojom::blink::MediaDevicesDispatcherHost*()>;
- // |web_frame| must outlive this instance.
+ // |frame| must outlive this instance.
UserMediaProcessor(LocalFrame* frame,
MediaDevicesDispatcherCallback media_devices_dispatcher_cb,
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
@@ -69,24 +58,23 @@ class MODULES_EXPORT UserMediaProcessor
// It can be assumed that the output of CurrentRequest() remains the same
// during the execution of a task on the main thread unless ProcessRequest or
- // DeleteWebRequest are invoked.
+ // DeleteUserMediaRequest are invoked.
// TODO(guidou): Remove this method. https://crbug.com/764293
- UserMediaRequestInfo* CurrentRequest();
+ UserMediaRequest* CurrentRequest();
// Starts processing |request| in order to create a new MediaStream. When
// processing of |request| is complete, it notifies by invoking |callback|.
// This method must be called only if there is no request currently being
// processed.
- void ProcessRequest(std::unique_ptr<UserMediaRequestInfo> request,
- base::OnceClosure callback);
+ void ProcessRequest(UserMediaRequest* request, base::OnceClosure callback);
- // If |web_request| is the request currently being processed, stops processing
- // the request and returns true. Otherwise, performs no action and returns
- // false.
+ // If |user_media_request| is the request currently being processed, stops
+ // processing the request and returns true. Otherwise, performs no action and
+ // returns false.
// TODO(guidou): Make this method private and replace with a public
// CancelRequest() method that deletes the request only if it has not been
// generated yet. https://crbug.com/764293
- bool DeleteWebRequest(const blink::WebUserMediaRequest& web_request);
+ bool DeleteUserMediaRequest(UserMediaRequest* user_media_request);
// Stops processing the current request, if any, and stops all sources
// currently being tracked, effectively stopping all tracks associated with
@@ -113,7 +101,7 @@ class MODULES_EXPORT UserMediaProcessor
// |request| have completed.
virtual void GetUserMediaRequestSucceeded(
const blink::WebMediaStream& stream,
- blink::WebUserMediaRequest web_request);
+ UserMediaRequest* user_media_request);
virtual void GetUserMediaRequestFailed(
blink::mojom::blink::MediaStreamRequestResult result,
const String& constraint_name = String());
@@ -146,7 +134,7 @@ class MODULES_EXPORT UserMediaProcessor
const Vector<blink::MediaStreamDevice>& video_devices);
void GotAllVideoInputFormatsForDevice(
- const blink::WebUserMediaRequest& web_request,
+ UserMediaRequest* user_media_request,
const String& label,
const String& device_id,
const Vector<media::VideoCaptureFormat>& formats);
@@ -158,13 +146,14 @@ class MODULES_EXPORT UserMediaProcessor
blink::mojom::blink::MediaStreamRequestResult result);
bool IsCurrentRequestInfo(int request_id) const;
- bool IsCurrentRequestInfo(
- const blink::WebUserMediaRequest& web_request) const;
+ bool IsCurrentRequestInfo(UserMediaRequest* user_media_request) const;
void DelayedGetUserMediaRequestSucceeded(
+ int request_id,
const blink::WebMediaStream& stream,
- blink::WebUserMediaRequest web_request);
+ UserMediaRequest* user_media_request);
void DelayedGetUserMediaRequestFailed(
- blink::WebUserMediaRequest web_request,
+ int request_id,
+ UserMediaRequest* user_media_request,
blink::mojom::blink::MediaStreamRequestResult result,
const String& constraint_name);
@@ -251,20 +240,20 @@ class MODULES_EXPORT UserMediaProcessor
void SetupAudioInput();
void SelectAudioDeviceSettings(
- const blink::WebUserMediaRequest& web_request,
+ UserMediaRequest* user_media_request,
Vector<blink::mojom::blink::AudioInputDeviceCapabilitiesPtr>
audio_input_capabilities);
void SelectAudioSettings(
- const blink::WebUserMediaRequest& web_request,
+ UserMediaRequest* user_media_request,
const blink::AudioDeviceCaptureCapabilities& capabilities);
void SetupVideoInput();
void SelectVideoDeviceSettings(
- const blink::WebUserMediaRequest& web_request,
+ UserMediaRequest* user_media_request,
Vector<blink::mojom::blink::VideoInputDeviceCapabilitiesPtr>
video_input_capabilities);
void FinalizeSelectVideoDeviceSettings(
- const blink::WebUserMediaRequest& web_request,
+ UserMediaRequest* user_media_request,
const blink::VideoCaptureSettings& settings);
void SelectVideoContentSettings();
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 3cdb7765564..10863987163 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
@@ -38,15 +38,14 @@
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
#include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h"
#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"
-#include "third_party/blink/renderer/core/frame/hosts_using_features.h"
#include "third_party/blink/renderer/modules/mediastream/media_constraints_impl.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
-#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints.h"
-#include "third_party/blink/renderer/modules/mediastream/media_track_constraints.h"
#include "third_party/blink/renderer/modules/mediastream/overconstrained_error.h"
#include "third_party/blink/renderer/modules/mediastream/user_media_controller.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -60,23 +59,23 @@ namespace {
template <typename NumericConstraint>
bool SetUsesNumericConstraint(
- const WebMediaTrackConstraintSet& set,
- NumericConstraint WebMediaTrackConstraintSet::*field) {
+ const MediaTrackConstraintSetPlatform& set,
+ NumericConstraint MediaTrackConstraintSetPlatform::*field) {
return (set.*field).HasExact() || (set.*field).HasIdeal() ||
(set.*field).HasMin() || (set.*field).HasMax();
}
template <typename DiscreteConstraint>
bool SetUsesDiscreteConstraint(
- const WebMediaTrackConstraintSet& set,
- DiscreteConstraint WebMediaTrackConstraintSet::*field) {
+ const MediaTrackConstraintSetPlatform& set,
+ DiscreteConstraint MediaTrackConstraintSetPlatform::*field) {
return (set.*field).HasExact() || (set.*field).HasIdeal();
}
template <typename NumericConstraint>
bool RequestUsesNumericConstraint(
- const WebMediaConstraints& constraints,
- NumericConstraint WebMediaTrackConstraintSet::*field) {
+ const MediaConstraints& constraints,
+ NumericConstraint MediaTrackConstraintSetPlatform::*field) {
if (SetUsesNumericConstraint(constraints.Basic(), field))
return true;
for (const auto& advanced_set : constraints.Advanced()) {
@@ -88,13 +87,15 @@ bool RequestUsesNumericConstraint(
template <typename DiscreteConstraint>
bool RequestUsesDiscreteConstraint(
- const WebMediaConstraints& constraints,
- DiscreteConstraint WebMediaTrackConstraintSet::*field) {
+ const MediaConstraints& constraints,
+ DiscreteConstraint MediaTrackConstraintSetPlatform::*field) {
static_assert(
- std::is_same<decltype(field),
- StringConstraint WebMediaTrackConstraintSet::*>::value ||
- std::is_same<decltype(field),
- BooleanConstraint WebMediaTrackConstraintSet::*>::value,
+ std::is_same<
+ decltype(field),
+ StringConstraint MediaTrackConstraintSetPlatform::*>::value ||
+ std::is_same<
+ decltype(field),
+ BooleanConstraint MediaTrackConstraintSetPlatform::*>::value,
"Must use StringConstraint or BooleanConstraint");
if (SetUsesDiscreteConstraint(constraints.Basic(), field))
return true;
@@ -123,90 +124,95 @@ class FeatureCounter {
};
void CountAudioConstraintUses(ExecutionContext* context,
- const WebMediaConstraints& constraints) {
+ const MediaConstraints& constraints) {
FeatureCounter counter(context);
- if (RequestUsesNumericConstraint(constraints,
- &WebMediaTrackConstraintSet::sample_rate)) {
+ if (RequestUsesNumericConstraint(
+ constraints, &MediaTrackConstraintSetPlatform::sample_rate)) {
counter.Count(WebFeature::kMediaStreamConstraintsSampleRate);
}
- if (RequestUsesNumericConstraint(constraints,
- &WebMediaTrackConstraintSet::sample_size)) {
+ if (RequestUsesNumericConstraint(
+ constraints, &MediaTrackConstraintSetPlatform::sample_size)) {
counter.Count(WebFeature::kMediaStreamConstraintsSampleSize);
}
if (RequestUsesDiscreteConstraint(
- constraints, &WebMediaTrackConstraintSet::echo_cancellation)) {
+ constraints, &MediaTrackConstraintSetPlatform::echo_cancellation)) {
counter.Count(WebFeature::kMediaStreamConstraintsEchoCancellation);
}
if (RequestUsesNumericConstraint(constraints,
- &WebMediaTrackConstraintSet::latency)) {
+ &MediaTrackConstraintSetPlatform::latency)) {
counter.Count(WebFeature::kMediaStreamConstraintsLatency);
}
if (RequestUsesNumericConstraint(
- constraints, &WebMediaTrackConstraintSet::channel_count)) {
+ constraints, &MediaTrackConstraintSetPlatform::channel_count)) {
counter.Count(WebFeature::kMediaStreamConstraintsChannelCount);
}
- if (RequestUsesDiscreteConstraint(constraints,
- &WebMediaTrackConstraintSet::device_id)) {
+ if (RequestUsesDiscreteConstraint(
+ constraints, &MediaTrackConstraintSetPlatform::device_id)) {
counter.Count(WebFeature::kMediaStreamConstraintsDeviceIdAudio);
}
if (RequestUsesDiscreteConstraint(
- constraints, &WebMediaTrackConstraintSet::disable_local_echo)) {
+ constraints, &MediaTrackConstraintSetPlatform::disable_local_echo)) {
counter.Count(WebFeature::kMediaStreamConstraintsDisableLocalEcho);
}
- if (RequestUsesDiscreteConstraint(constraints,
- &WebMediaTrackConstraintSet::group_id)) {
+ if (RequestUsesDiscreteConstraint(
+ constraints, &MediaTrackConstraintSetPlatform::group_id)) {
counter.Count(WebFeature::kMediaStreamConstraintsGroupIdAudio);
}
if (RequestUsesDiscreteConstraint(
- constraints, &WebMediaTrackConstraintSet::media_stream_source)) {
+ constraints, &MediaTrackConstraintSetPlatform::media_stream_source)) {
counter.Count(WebFeature::kMediaStreamConstraintsMediaStreamSourceAudio);
}
if (RequestUsesDiscreteConstraint(
constraints,
- &WebMediaTrackConstraintSet::render_to_associated_sink)) {
+ &MediaTrackConstraintSetPlatform::render_to_associated_sink)) {
counter.Count(WebFeature::kMediaStreamConstraintsRenderToAssociatedSink);
}
if (RequestUsesDiscreteConstraint(
- constraints, &WebMediaTrackConstraintSet::goog_echo_cancellation)) {
+ constraints,
+ &MediaTrackConstraintSetPlatform::goog_echo_cancellation)) {
counter.Count(WebFeature::kMediaStreamConstraintsGoogEchoCancellation);
}
- if (RequestUsesDiscreteConstraint(
- constraints,
- &WebMediaTrackConstraintSet::goog_experimental_echo_cancellation)) {
+ if (RequestUsesDiscreteConstraint(constraints,
+ &MediaTrackConstraintSetPlatform::
+ goog_experimental_echo_cancellation)) {
counter.Count(
WebFeature::kMediaStreamConstraintsGoogExperimentalEchoCancellation);
}
if (RequestUsesDiscreteConstraint(
- constraints, &WebMediaTrackConstraintSet::goog_auto_gain_control)) {
+ constraints,
+ &MediaTrackConstraintSetPlatform::goog_auto_gain_control)) {
counter.Count(WebFeature::kMediaStreamConstraintsGoogAutoGainControl);
}
- if (RequestUsesDiscreteConstraint(
- constraints,
- &WebMediaTrackConstraintSet::goog_experimental_auto_gain_control)) {
+ if (RequestUsesDiscreteConstraint(constraints,
+ &MediaTrackConstraintSetPlatform::
+ goog_experimental_auto_gain_control)) {
counter.Count(
WebFeature::kMediaStreamConstraintsGoogExperimentalAutoGainControl);
}
if (RequestUsesDiscreteConstraint(
- constraints, &WebMediaTrackConstraintSet::goog_noise_suppression)) {
+ constraints,
+ &MediaTrackConstraintSetPlatform::goog_noise_suppression)) {
counter.Count(WebFeature::kMediaStreamConstraintsGoogNoiseSuppression);
}
if (RequestUsesDiscreteConstraint(
- constraints, &WebMediaTrackConstraintSet::goog_highpass_filter)) {
+ constraints,
+ &MediaTrackConstraintSetPlatform::goog_highpass_filter)) {
counter.Count(WebFeature::kMediaStreamConstraintsGoogHighpassFilter);
}
- if (RequestUsesDiscreteConstraint(
- constraints,
- &WebMediaTrackConstraintSet::goog_experimental_noise_suppression)) {
+ if (RequestUsesDiscreteConstraint(constraints,
+ &MediaTrackConstraintSetPlatform::
+ goog_experimental_noise_suppression)) {
counter.Count(
WebFeature::kMediaStreamConstraintsGoogExperimentalNoiseSuppression);
}
if (RequestUsesDiscreteConstraint(
- constraints, &WebMediaTrackConstraintSet::goog_audio_mirroring)) {
+ constraints,
+ &MediaTrackConstraintSetPlatform::goog_audio_mirroring)) {
counter.Count(WebFeature::kMediaStreamConstraintsGoogAudioMirroring);
}
if (RequestUsesDiscreteConstraint(
constraints,
- &WebMediaTrackConstraintSet::goog_da_echo_cancellation)) {
+ &MediaTrackConstraintSetPlatform::goog_da_echo_cancellation)) {
counter.Count(WebFeature::kMediaStreamConstraintsGoogDAEchoCancellation);
}
@@ -218,46 +224,47 @@ void CountAudioConstraintUses(ExecutionContext* context,
}
void CountVideoConstraintUses(ExecutionContext* context,
- const WebMediaConstraints& constraints) {
+ const MediaConstraints& constraints) {
FeatureCounter counter(context);
if (RequestUsesNumericConstraint(constraints,
- &WebMediaTrackConstraintSet::width)) {
+ &MediaTrackConstraintSetPlatform::width)) {
counter.Count(WebFeature::kMediaStreamConstraintsWidth);
}
if (RequestUsesNumericConstraint(constraints,
- &WebMediaTrackConstraintSet::height)) {
+ &MediaTrackConstraintSetPlatform::height)) {
counter.Count(WebFeature::kMediaStreamConstraintsHeight);
}
- if (RequestUsesNumericConstraint(constraints,
- &WebMediaTrackConstraintSet::aspect_ratio)) {
+ if (RequestUsesNumericConstraint(
+ constraints, &MediaTrackConstraintSetPlatform::aspect_ratio)) {
counter.Count(WebFeature::kMediaStreamConstraintsAspectRatio);
}
- if (RequestUsesNumericConstraint(constraints,
- &WebMediaTrackConstraintSet::frame_rate)) {
+ if (RequestUsesNumericConstraint(
+ constraints, &MediaTrackConstraintSetPlatform::frame_rate)) {
counter.Count(WebFeature::kMediaStreamConstraintsFrameRate);
}
- if (RequestUsesDiscreteConstraint(constraints,
- &WebMediaTrackConstraintSet::facing_mode)) {
+ if (RequestUsesDiscreteConstraint(
+ constraints, &MediaTrackConstraintSetPlatform::facing_mode)) {
counter.Count(WebFeature::kMediaStreamConstraintsFacingMode);
}
- if (RequestUsesDiscreteConstraint(constraints,
- &WebMediaTrackConstraintSet::device_id)) {
+ if (RequestUsesDiscreteConstraint(
+ constraints, &MediaTrackConstraintSetPlatform::device_id)) {
counter.Count(WebFeature::kMediaStreamConstraintsDeviceIdVideo);
}
- if (RequestUsesDiscreteConstraint(constraints,
- &WebMediaTrackConstraintSet::group_id)) {
+ if (RequestUsesDiscreteConstraint(
+ constraints, &MediaTrackConstraintSetPlatform::group_id)) {
counter.Count(WebFeature::kMediaStreamConstraintsGroupIdVideo);
}
- if (RequestUsesDiscreteConstraint(constraints,
- &WebMediaTrackConstraintSet::video_kind)) {
+ if (RequestUsesDiscreteConstraint(
+ constraints, &MediaTrackConstraintSetPlatform::video_kind)) {
counter.Count(WebFeature::kMediaStreamConstraintsVideoKind);
}
if (RequestUsesDiscreteConstraint(
- constraints, &WebMediaTrackConstraintSet::media_stream_source)) {
+ constraints, &MediaTrackConstraintSetPlatform::media_stream_source)) {
counter.Count(WebFeature::kMediaStreamConstraintsMediaStreamSourceVideo);
}
if (RequestUsesDiscreteConstraint(
- constraints, &WebMediaTrackConstraintSet::goog_noise_reduction)) {
+ constraints,
+ &MediaTrackConstraintSetPlatform::goog_noise_reduction)) {
counter.Count(WebFeature::kMediaStreamConstraintsGoogNoiseReduction);
}
@@ -268,10 +275,10 @@ void CountVideoConstraintUses(ExecutionContext* context,
}
}
-WebMediaConstraints ParseOptions(ExecutionContext* context,
- const BooleanOrMediaTrackConstraints& options,
- MediaErrorState& error_state) {
- WebMediaConstraints constraints;
+MediaConstraints ParseOptions(ExecutionContext* context,
+ const BooleanOrMediaTrackConstraints& options,
+ MediaErrorState& error_state) {
+ MediaConstraints constraints;
if (options.IsNull()) {
// Do nothing.
@@ -297,7 +304,7 @@ class UserMediaRequest::V8Callbacks final : public UserMediaRequest::Callbacks {
: success_callback_(success_callback), error_callback_(error_callback) {}
~V8Callbacks() override = default;
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(success_callback_);
visitor->Trace(error_callback_);
UserMediaRequest::Callbacks::Trace(visitor);
@@ -320,21 +327,19 @@ class UserMediaRequest::V8Callbacks final : public UserMediaRequest::Callbacks {
UserMediaRequest* UserMediaRequest::Create(
ExecutionContext* context,
UserMediaController* controller,
- WebUserMediaRequest::MediaType media_type,
+ UserMediaRequest::MediaType media_type,
const MediaStreamConstraints* options,
Callbacks* callbacks,
MediaErrorState& error_state) {
- WebMediaConstraints audio =
- ParseOptions(context, options->audio(), error_state);
+ MediaConstraints audio = ParseOptions(context, options->audio(), error_state);
if (error_state.HadException())
return nullptr;
- WebMediaConstraints video =
- ParseOptions(context, options->video(), error_state);
+ MediaConstraints video = ParseOptions(context, options->video(), error_state);
if (error_state.HadException())
return nullptr;
- if (media_type == WebUserMediaRequest::MediaType::kDisplayMedia) {
+ if (media_type == UserMediaRequest::MediaType::kDisplayMedia) {
// https://w3c.github.io/mediacapture-screen-share/#mediadevices-additions
// MediaDevices Additions
// The user agent MUST reject audio-only requests.
@@ -350,8 +355,8 @@ UserMediaRequest* UserMediaRequest::Create(
// either a dictionary value or a value of true.
// 4. If requestedMediaTypes is the empty set, set requestedMediaTypes to a
// set containing "video".
- if ((!audio.IsNull() && !audio.Advanced().empty()) ||
- (!video.IsNull() && !video.Advanced().empty())) {
+ if ((!audio.IsNull() && !audio.Advanced().IsEmpty()) ||
+ (!video.IsNull() && !video.Advanced().IsEmpty())) {
error_state.ThrowTypeError("Advanced constraints are not supported");
return nullptr;
}
@@ -401,26 +406,26 @@ UserMediaRequest* UserMediaRequest::Create(
V8NavigatorUserMediaErrorCallback* error_callback,
MediaErrorState& error_state) {
return Create(
- context, controller, WebUserMediaRequest::MediaType::kUserMedia, options,
+ context, controller, UserMediaRequest::MediaType::kUserMedia, options,
MakeGarbageCollected<V8Callbacks>(success_callback, error_callback),
error_state);
}
UserMediaRequest* UserMediaRequest::CreateForTesting(
- const WebMediaConstraints& audio,
- const WebMediaConstraints& video) {
+ const MediaConstraints& audio,
+ const MediaConstraints& video) {
return MakeGarbageCollected<UserMediaRequest>(
- nullptr, nullptr, WebUserMediaRequest::MediaType::kUserMedia, audio,
- video, nullptr);
+ nullptr, nullptr, UserMediaRequest::MediaType::kUserMedia, audio, video,
+ nullptr);
}
UserMediaRequest::UserMediaRequest(ExecutionContext* context,
UserMediaController* controller,
- WebUserMediaRequest::MediaType media_type,
- WebMediaConstraints audio,
- WebMediaConstraints video,
+ UserMediaRequest::MediaType media_type,
+ MediaConstraints audio,
+ MediaConstraints video,
Callbacks* callbacks)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
media_type_(media_type),
audio_(audio),
video_(video),
@@ -437,7 +442,7 @@ UserMediaRequest::UserMediaRequest(ExecutionContext* context,
UserMediaRequest::~UserMediaRequest() = default;
-WebUserMediaRequest::MediaType UserMediaRequest::MediaRequestType() const {
+UserMediaRequest::MediaType UserMediaRequest::MediaRequestType() const {
return media_type_;
}
@@ -449,11 +454,11 @@ bool UserMediaRequest::Video() const {
return !video_.IsNull();
}
-WebMediaConstraints UserMediaRequest::AudioConstraints() const {
+MediaConstraints UserMediaRequest::AudioConstraints() const {
return audio_;
}
-WebMediaConstraints UserMediaRequest::VideoConstraints() const {
+MediaConstraints UserMediaRequest::VideoConstraints() const {
return video_;
}
@@ -471,22 +476,22 @@ bool UserMediaRequest::IsSecureContextUse(String& error_message) {
// Feature policy deprecation messages.
if (Audio()) {
- if (!document->IsFeatureEnabled(mojom::FeaturePolicyFeature::kMicrophone,
- ReportOptions::kReportOnFailure)) {
+ if (!document->IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kMicrophone,
+ ReportOptions::kReportOnFailure)) {
UseCounter::Count(
document, WebFeature::kMicrophoneDisabledByFeaturePolicyEstimate);
}
}
if (Video()) {
- if (!document->IsFeatureEnabled(mojom::FeaturePolicyFeature::kCamera,
- ReportOptions::kReportOnFailure)) {
+ if (!document->IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kCamera,
+ ReportOptions::kReportOnFailure)) {
UseCounter::Count(document,
WebFeature::kCameraDisabledByFeaturePolicyEstimate);
}
}
- HostsUsingFeatures::CountAnyWorld(
- *document, HostsUsingFeatures::Feature::kGetUserMediaSecureHost);
return true;
}
@@ -496,13 +501,11 @@ bool UserMediaRequest::IsSecureContextUse(String& error_message) {
WebFeature::kGetUserMediaInsecureOrigin);
Deprecation::CountDeprecationCrossOriginIframe(
*document, WebFeature::kGetUserMediaInsecureOriginIframe);
- HostsUsingFeatures::CountAnyWorld(
- *document, HostsUsingFeatures::Feature::kGetUserMediaInsecureHost);
return false;
}
Document* UserMediaRequest::OwnerDocument() {
- return To<Document>(GetExecutionContext());
+ return Document::From(GetExecutionContext());
}
void UserMediaRequest::Start() {
@@ -546,37 +549,36 @@ void UserMediaRequest::FailConstraint(const String& constraint_name,
is_resolved_ = true;
}
-void UserMediaRequest::Fail(WebUserMediaRequest::Error name,
- const String& message) {
+void UserMediaRequest::Fail(Error name, const String& message) {
DCHECK(!is_resolved_);
if (!GetExecutionContext())
return;
DOMExceptionCode exception_code = DOMExceptionCode::kNotSupportedError;
switch (name) {
- case WebUserMediaRequest::Error::kPermissionDenied:
- case WebUserMediaRequest::Error::kPermissionDismissed:
- case WebUserMediaRequest::Error::kInvalidState:
- case WebUserMediaRequest::Error::kFailedDueToShutdown:
- case WebUserMediaRequest::Error::kKillSwitchOn:
- case WebUserMediaRequest::Error::kSystemPermissionDenied:
+ case Error::kPermissionDenied:
+ case Error::kPermissionDismissed:
+ case Error::kInvalidState:
+ case Error::kFailedDueToShutdown:
+ case Error::kKillSwitchOn:
+ case Error::kSystemPermissionDenied:
exception_code = DOMExceptionCode::kNotAllowedError;
break;
- case WebUserMediaRequest::Error::kDevicesNotFound:
+ case Error::kDevicesNotFound:
exception_code = DOMExceptionCode::kNotFoundError;
break;
- case WebUserMediaRequest::Error::kTabCapture:
- case WebUserMediaRequest::Error::kScreenCapture:
- case WebUserMediaRequest::Error::kCapture:
+ case Error::kTabCapture:
+ case Error::kScreenCapture:
+ case Error::kCapture:
exception_code = DOMExceptionCode::kAbortError;
break;
- case WebUserMediaRequest::Error::kTrackStart:
+ case Error::kTrackStart:
exception_code = DOMExceptionCode::kNotReadableError;
break;
- case WebUserMediaRequest::Error::kNotSupported:
+ case Error::kNotSupported:
exception_code = DOMExceptionCode::kNotSupportedError;
break;
- case WebUserMediaRequest::Error::kSecurityError:
+ case Error::kSecurityError:
exception_code = DOMExceptionCode::kSecurityError;
break;
default:
@@ -589,7 +591,7 @@ void UserMediaRequest::Fail(WebUserMediaRequest::Error name,
is_resolved_ = true;
}
-void UserMediaRequest::ContextDestroyed(ExecutionContext*) {
+void UserMediaRequest::ContextDestroyed() {
if (!is_resolved_)
blink::WebRtcLogMessage("UMR::ContextDestroyed. Request not resolved.");
if (controller_) {
@@ -610,10 +612,10 @@ void UserMediaRequest::ContextDestroyed(ExecutionContext*) {
}
}
-void UserMediaRequest::Trace(blink::Visitor* visitor) {
+void UserMediaRequest::Trace(Visitor* visitor) {
visitor->Trace(controller_);
visitor->Trace(callbacks_);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 e70387f331c..a56501f2e7e 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
@@ -31,12 +31,11 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_USER_MEDIA_REQUEST_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_USER_MEDIA_REQUEST_H_
-#include "third_party/blink/public/platform/web_media_constraints.h"
-#include "third_party/blink/public/web/web_user_media_request.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_navigator_user_media_error_callback.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_navigator_user_media_success_callback.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -50,10 +49,31 @@ class UserMediaController;
class MODULES_EXPORT UserMediaRequest final
: public GarbageCollected<UserMediaRequest>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(UserMediaRequest);
public:
+ enum class Error {
+ kNotSupported,
+ kSecurityError,
+ kPermissionDenied,
+ kPermissionDismissed,
+ kInvalidState,
+ kDevicesNotFound,
+ kTabCapture,
+ kScreenCapture,
+ kCapture,
+ kTrackStart,
+ kFailedDueToShutdown,
+ kKillSwitchOn,
+ kSystemPermissionDenied
+ };
+
+ enum class MediaType {
+ kUserMedia,
+ kDisplayMedia,
+ };
+
class Callbacks : public GarbageCollected<Callbacks> {
public:
virtual ~Callbacks() = default;
@@ -63,7 +83,7 @@ class MODULES_EXPORT UserMediaRequest final
virtual void OnError(ScriptWrappable* callback_this_value,
DOMExceptionOrOverconstrainedError) = 0;
- virtual void Trace(blink::Visitor*) {}
+ virtual void Trace(Visitor*) {}
protected:
Callbacks() = default;
@@ -73,7 +93,7 @@ class MODULES_EXPORT UserMediaRequest final
static UserMediaRequest* Create(ExecutionContext*,
UserMediaController*,
- WebUserMediaRequest::MediaType media_type,
+ MediaType media_type,
const MediaStreamConstraints* options,
Callbacks*,
MediaErrorState&);
@@ -83,14 +103,14 @@ class MODULES_EXPORT UserMediaRequest final
V8NavigatorUserMediaSuccessCallback*,
V8NavigatorUserMediaErrorCallback*,
MediaErrorState&);
- static UserMediaRequest* CreateForTesting(const WebMediaConstraints& audio,
- const WebMediaConstraints& video);
+ static UserMediaRequest* CreateForTesting(const MediaConstraints& audio,
+ const MediaConstraints& video);
UserMediaRequest(ExecutionContext*,
UserMediaController*,
- WebUserMediaRequest::MediaType media_type,
- WebMediaConstraints audio,
- WebMediaConstraints video,
+ MediaType media_type,
+ MediaConstraints audio,
+ MediaConstraints video,
Callbacks*);
virtual ~UserMediaRequest();
@@ -100,13 +120,13 @@ class MODULES_EXPORT UserMediaRequest final
void Succeed(MediaStreamDescriptor*);
void FailConstraint(const String& constraint_name, const String& message);
- void Fail(WebUserMediaRequest::Error name, const String& message);
+ void Fail(Error name, const String& message);
- WebUserMediaRequest::MediaType MediaRequestType() const;
+ MediaType MediaRequestType() const;
bool Audio() const;
bool Video() const;
- WebMediaConstraints AudioConstraints() const;
- WebMediaConstraints VideoConstraints() const;
+ MediaConstraints AudioConstraints() const;
+ MediaConstraints VideoConstraints() const;
// Flag tied to whether or not the similarly named Origin Trial is
// enabled. Will be removed at end of trial. See: http://crbug.com/789152.
@@ -116,16 +136,28 @@ class MODULES_EXPORT UserMediaRequest final
// Caller is responsible for properly setting errors and canceling request.
bool IsSecureContextUse(String& error_message);
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
+
+ void set_request_id(int id) { request_id_ = id; }
+ int request_id() { return request_id_; }
+
+ void set_has_transient_user_activation(bool value) {
+ has_transient_user_activation_ = value;
+ }
+ bool has_transient_user_activation() const {
+ return has_transient_user_activation_;
+ }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
- WebUserMediaRequest::MediaType media_type_;
- WebMediaConstraints audio_;
- WebMediaConstraints video_;
+ MediaType media_type_;
+ MediaConstraints audio_;
+ MediaConstraints video_;
bool should_disable_hardware_noise_suppression_;
+ bool has_transient_user_activation_ = false;
+ int request_id_ = -1;
Member<UserMediaController> controller_;
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 c7ca75ca948..41f288cd370 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
@@ -342,9 +342,17 @@ void VideoTrackAdapter::VideoFrameResolutionAdapter::DeliverFrame(
// |desired_size| that fits entirely inside of |frame->visible_rect()|.
// This will be the rect we need to crop the original frame to.
// From this rect, the original frame can be scaled down to |desired_size|.
- const gfx::Rect region_in_frame =
+ gfx::Rect region_in_frame =
media::ComputeLetterboxRegion(frame->visible_rect(), desired_size);
+ if (frame->HasTextures() || frame->HasGpuMemoryBuffer()) {
+ // ComputeLetterboxRegion() produces in some cases odd dimensions due to
+ // internal rounding errors; |region_in_frame| is always smaller or equal
+ // to frame->visible_rect(), we can "grow it" if the dimensions are odd.
+ region_in_frame.set_width((region_in_frame.width() + 1) & ~1);
+ region_in_frame.set_height((region_in_frame.height() + 1) & ~1);
+ }
+
video_frame = media::VideoFrame::WrapVideoFrame(
frame, frame->format(), region_in_frame, desired_size);
if (!video_frame) {
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/video_track_adapter_unittest.cc b/chromium/third_party/blink/renderer/modules/mediastream/video_track_adapter_unittest.cc
index 579cbd488ac..c842b1a065b 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/video_track_adapter_unittest.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/video_track_adapter_unittest.cc
@@ -6,6 +6,7 @@
#include <limits>
+#include "base/bind_helpers.h"
#include "base/run_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/bind_test_util.h"
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/web_media_stream_device_observer.cc b/chromium/third_party/blink/renderer/modules/mediastream/web_media_stream_device_observer.cc
index 27ba74be041..8a3105ee4f1 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/web_media_stream_device_observer.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/web_media_stream_device_observer.cc
@@ -5,12 +5,18 @@
#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/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_device_observer.h"
namespace blink {
-WebMediaStreamDeviceObserver::WebMediaStreamDeviceObserver(WebLocalFrame* frame)
- : observer_(std::make_unique<MediaStreamDeviceObserver>(frame)) {}
+WebMediaStreamDeviceObserver::WebMediaStreamDeviceObserver(
+ WebLocalFrame* frame) {
+ auto* local_frame =
+ frame ? static_cast<LocalFrame*>(WebFrame::ToCoreFrame(*frame)) : nullptr;
+ observer_ = std::make_unique<MediaStreamDeviceObserver>(local_frame);
+}
+
WebMediaStreamDeviceObserver::~WebMediaStreamDeviceObserver() = default;
MediaStreamDevices WebMediaStreamDeviceObserver::GetNonScreenCaptureDevices() {
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 601c43b18ac..3f3652d0603 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
@@ -9,8 +9,8 @@
#include "base/logging.h"
#include "media/base/audio_fifo.h"
#include "media/base/audio_parameters.h"
-#include "third_party/blink/public/platform/web_audio_source_provider_client.h"
#include "third_party/blink/public/web/web_local_frame.h"
+#include "third_party/blink/renderer/platform/media/web_audio_source_provider_client.h"
namespace {
static const size_t kMaxNumberOfAudioFifoBuffers = 10;
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 16c3b630643..96834fdd310 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
@@ -10,10 +10,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/modules/mediastream/media_stream_audio_track.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"
namespace blink {
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 9dc6072824b..b757981f38d 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
+++ b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
@@ -23,7 +23,6 @@
#include "media/base/video_types.h"
#include "media/video/gpu_memory_buffer_video_frame_pool.h"
#include "services/viz/public/cpp/gpu/context_provider_command_buffer.h"
-#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.h"
#include "third_party/blink/public/platform/modules/mediastream/web_media_element_source_utils.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_video_renderer.h"
@@ -40,6 +39,7 @@
#include "third_party/blink/public/web/web_local_frame.h"
#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/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
@@ -57,6 +57,51 @@ bool IsPlayableTrack(const blink::WebMediaStreamTrack& track) {
blink::WebMediaStreamSource::kReadyStateEnded;
}
+const char* LoadTypeToString(blink::WebMediaPlayer::LoadType type) {
+ switch (type) {
+ case blink::WebMediaPlayer::kLoadTypeURL:
+ return "URL";
+ case blink::WebMediaPlayer::kLoadTypeMediaSource:
+ return "MediaSource";
+ case blink::WebMediaPlayer::kLoadTypeMediaStream:
+ return "MediaStream";
+ }
+}
+
+const char* ReadyStateToString(blink::WebMediaPlayer::ReadyState state) {
+ switch (state) {
+ case blink::WebMediaPlayer::kReadyStateHaveNothing:
+ return "HaveNothing";
+ case blink::WebMediaPlayer::kReadyStateHaveMetadata:
+ return "HaveMetadata";
+ case blink::WebMediaPlayer::kReadyStateHaveCurrentData:
+ return "HaveCurrentData";
+ case blink::WebMediaPlayer::kReadyStateHaveFutureData:
+ return "HaveFutureData";
+ case blink::WebMediaPlayer::kReadyStateHaveEnoughData:
+ return "HaveEnoughData";
+ }
+}
+
+const char* NetworkStateToString(blink::WebMediaPlayer::NetworkState state) {
+ switch (state) {
+ case blink::WebMediaPlayer::kNetworkStateEmpty:
+ return "Empty";
+ case blink::WebMediaPlayer::kNetworkStateIdle:
+ return "Idle";
+ case blink::WebMediaPlayer::kNetworkStateLoading:
+ return "Loading";
+ case blink::WebMediaPlayer::kNetworkStateLoaded:
+ return "Loaded";
+ case blink::WebMediaPlayer::kNetworkStateFormatError:
+ return "FormatError";
+ case blink::WebMediaPlayer::kNetworkStateNetworkError:
+ return "NetworkError";
+ case blink::WebMediaPlayer::kNetworkStateDecodeError:
+ return "DecodeError";
+ }
+}
+
} // namespace
namespace WTF {
@@ -287,18 +332,20 @@ WebMediaPlayerMS::WebMediaPlayerMS(
create_bridge_callback_(std::move(create_bridge_callback)),
submitter_(std::move(submitter)),
surface_layer_mode_(surface_layer_mode) {
- DVLOG(1) << __func__;
DCHECK(client);
DCHECK(delegate_);
weak_this_ = weak_factory_.GetWeakPtr();
delegate_id_ = delegate_->AddObserver(this);
+ SendLogMessage(String::Format("%s({delegate_id=%d}, {is_audio_element=%s})",
+ __func__, delegate_id_,
+ client->IsAudioElement() ? "true" : "false"));
- media_log_->AddEvent(
- media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED));
+ // TODO(tmathmeyer) WebMediaPlayerImpl gets the URL from the WebLocalFrame.
+ // doing that here causes a nullptr deref.
+ media_log_->AddEvent<media::MediaLogEvent::kWebMediaPlayerCreated>();
}
WebMediaPlayerMS::~WebMediaPlayerMS() {
- DVLOG(1) << __func__;
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (!web_stream_.IsNull())
@@ -323,8 +370,7 @@ WebMediaPlayerMS::~WebMediaPlayerMS() {
if (audio_renderer_)
audio_renderer_->Stop();
- media_log_->AddEvent(
- media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED));
+ media_log_->AddEvent<media::MediaLogEvent::kWebMediaPlayerDestroyed>();
delegate_->PlayerGone(delegate_id_);
delegate_->RemoveObserver(delegate_id_);
@@ -334,8 +380,9 @@ WebMediaPlayer::LoadTiming WebMediaPlayerMS::Load(
LoadType load_type,
const WebMediaPlayerSource& source,
CorsMode /*cors_mode*/) {
- DVLOG(1) << __func__;
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ SendLogMessage(String::Format("%s({load_type=%s})", __func__,
+ LoadTypeToString(load_type)));
// TODO(acolwell): Change this to DCHECK_EQ(load_type, LoadTypeMediaStream)
// once Blink-side changes land.
@@ -348,11 +395,21 @@ WebMediaPlayer::LoadTiming WebMediaPlayerMS::Load(
compositor_task_runner_, io_task_runner_, web_stream_,
std::move(submitter_), surface_layer_mode_, weak_this_);
+ // We can receive a call to RequestAnimationFrame() before |compositor_| is
+ // created. In that case, we suspend the request, and wait until now to
+ // reiniate it.
+ if (pending_rvfc_request_) {
+ RequestVideoFrameCallback();
+ pending_rvfc_request_ = false;
+ }
+
SetNetworkState(WebMediaPlayer::kNetworkStateLoading);
SetReadyState(WebMediaPlayer::kReadyStateHaveNothing);
std::string stream_id =
web_stream_.IsNull() ? std::string() : web_stream_.Id().Utf8();
- media_log_->AddEvent(media_log_->CreateLoadEvent(stream_id));
+ media_log_->AddEvent<media::MediaLogEvent::kLoad>(stream_id);
+ SendLogMessage(
+ String::Format("%s => (stream_id=%s)", __func__, stream_id.c_str()));
frame_deliverer_.reset(new WebMediaPlayerMS::FrameDeliverer(
weak_this_,
@@ -375,11 +432,10 @@ WebMediaPlayer::LoadTiming WebMediaPlayerMS::Load(
web_stream_, internal_frame_->web_frame(),
initial_audio_output_device_id_);
- if (!audio_renderer_)
- WebRtcLogMessage("Warning: Failed to instantiate audio renderer.");
-
if (!video_frame_provider_ && !audio_renderer_) {
SetNetworkState(WebMediaPlayer::kNetworkStateNetworkError);
+ SendLogMessage(String::Format(
+ "%s => (ERROR: WebMediaPlayer::kNetworkStateNetworkError)", __func__));
return WebMediaPlayer::LoadTiming::kImmediate;
}
@@ -387,31 +443,35 @@ WebMediaPlayer::LoadTiming WebMediaPlayerMS::Load(
audio_renderer_->SetVolume(volume_);
audio_renderer_->Start();
- // Store the ID of audio track being played in |current_video_track_id_|
+ // 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();
+ SendLogMessage(String::Format("%s => (audio_track_id=%s)", __func__,
+ current_audio_track_id_.Utf8().c_str()));
}
}
if (video_frame_provider_) {
video_frame_provider_->Start();
- // Store the ID of video track being played in |current_video_track_id_|
+ // 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();
+ SendLogMessage(String::Format("%s => (video_track_id=%s)", __func__,
+ current_video_track_id_.Utf8().c_str()));
}
}
// When associated with an <audio> element, we don't want to wait for the
- // first video fram to become available as we do for <video> elements
+ // first video frame to become available as we do for <video> elements
// (<audio> elements can also be assigned video tracks).
// For more details, see https://crbug.com/738379
if (audio_renderer_ &&
(client_->IsAudioElement() || !video_frame_provider_)) {
- // This is audio-only mode.
+ SendLogMessage(String::Format("%s => (audio only mode)", __func__));
SetReadyState(WebMediaPlayer::kReadyStateHaveMetadata);
SetReadyState(WebMediaPlayer::kReadyStateHaveEnoughData);
}
@@ -445,20 +505,26 @@ void WebMediaPlayerMS::OnSurfaceIdUpdated(viz::SurfaceId surface_id) {
}
void WebMediaPlayerMS::TrackAdded(const WebMediaStreamTrack& track) {
+ SendLogMessage(
+ String::Format("%s({track_id=%s})", __func__, track.Id().Utf8().c_str()));
Reload();
}
void WebMediaPlayerMS::TrackRemoved(const WebMediaStreamTrack& track) {
+ SendLogMessage(
+ String::Format("%s({track_id=%s})", __func__, track.Id().Utf8().c_str()));
Reload();
}
void WebMediaPlayerMS::ActiveStateChanged(bool is_active) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ SendLogMessage(String::Format("%s({is_active=%s})", __func__,
+ is_active ? "true" : "false"));
// The case when the stream becomes active is handled by TrackAdded().
if (is_active)
return;
- // This makes the media element elegible to be garbage collected. Otherwise,
+ // This makes the media element eligible to be garbage collected. Otherwise,
// the element will be considered active and will never be garbage
// collected.
SetNetworkState(kNetworkStateIdle);
@@ -536,12 +602,8 @@ void WebMediaPlayerMS::ReloadVideo() {
}
DCHECK_NE(renderer_action, RendererReloadAction::KEEP_RENDERER);
- if (!paused_) {
- // TODO(crbug.com/964494): Remove this explicit conversion.
- WebSize natural_size = NaturalSize();
- gfx::Size gfx_size(natural_size.height, natural_size.width);
- delegate_->DidPlayerSizeChange(delegate_id_, gfx_size);
- }
+ if (!paused_)
+ delegate_->DidPlayerSizeChange(delegate_id_, NaturalSize());
}
void WebMediaPlayerMS::ReloadAudio() {
@@ -549,6 +611,7 @@ void WebMediaPlayerMS::ReloadAudio() {
DCHECK(!web_stream_.IsNull());
if (!internal_frame_->web_frame())
return;
+ SendLogMessage(String::Format("%s()", __func__));
WebVector<WebMediaStreamTrack> audio_tracks = web_stream_.AudioTracks();
@@ -593,10 +656,10 @@ void WebMediaPlayerMS::ReloadAudio() {
}
void WebMediaPlayerMS::Play() {
- DVLOG(1) << __func__;
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ SendLogMessage(String::Format("%s()", __func__));
- media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PLAY));
+ media_log_->AddEvent<media::MediaLogEvent::kPlay>();
if (!paused_)
return;
@@ -608,12 +671,8 @@ void WebMediaPlayerMS::Play() {
if (audio_renderer_)
audio_renderer_->Play();
- if (HasVideo()) {
- // TODO(crbug.com/964494): Remove this explicit conversion.
- WebSize natural_size = NaturalSize();
- gfx::Size gfx_size(natural_size.height, natural_size.width);
- delegate_->DidPlayerSizeChange(delegate_id_, gfx_size);
- }
+ if (HasVideo())
+ delegate_->DidPlayerSizeChange(delegate_id_, NaturalSize());
// |delegate_| expects the notification only if there is at least one track
// actually playing. A media stream might have none since tracks can be
@@ -631,11 +690,11 @@ void WebMediaPlayerMS::Play() {
}
void WebMediaPlayerMS::Pause() {
- DVLOG(1) << __func__;
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ SendLogMessage(String::Format("%s()", __func__));
should_play_upon_shown_ = false;
- media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PAUSE));
+ media_log_->AddEvent<media::MediaLogEvent::kPause>();
if (paused_)
return;
@@ -663,8 +722,8 @@ void WebMediaPlayerMS::SetRate(double rate) {
}
void WebMediaPlayerMS::SetVolume(double volume) {
- DVLOG(1) << __func__ << "(volume=" << volume << ")";
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ SendLogMessage(String::Format("%s({volume=%.2f})", __func__, volume));
volume_ = volume;
if (audio_renderer_.get())
audio_renderer_->SetVolume(volume_ * volume_multiplier_);
@@ -686,17 +745,28 @@ void WebMediaPlayerMS::OnRequestPictureInPicture() {
DCHECK(bridge_->GetSurfaceId().is_valid());
}
+void WebMediaPlayerMS::OnPictureInPictureAvailabilityChanged(bool available) {
+ delegate_->DidPictureInPictureAvailabilityChange(delegate_id_, available);
+}
+
void WebMediaPlayerMS::SetSinkId(
const WebString& sink_id,
WebSetSinkIdCompleteCallback completion_callback) {
- DVLOG(1) << __func__;
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ SendLogMessage(
+ String::Format("%s({sink_id=%s})", __func__, sink_id.Utf8().c_str()));
+ if (!audio_renderer_) {
+ SendLogMessage(String::Format(
+ "%s => (WARNING: failed to instantiate audio renderer)", __func__));
+ }
media::OutputDeviceStatusCB callback =
ConvertToOutputDeviceStatusCB(std::move(completion_callback));
if (audio_renderer_) {
audio_renderer_->SwitchOutputDevice(sink_id.Utf8(), std::move(callback));
} else {
std::move(callback).Run(media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL);
+ SendLogMessage(String::Format(
+ "%s => (ERROR: OUTPUT_DEVICE_STATUS_ERROR_INTERNAL)", __func__));
}
}
@@ -714,31 +784,31 @@ bool WebMediaPlayerMS::HasAudio() const {
return !!audio_renderer_;
}
-WebSize WebMediaPlayerMS::NaturalSize() const {
+gfx::Size WebMediaPlayerMS::NaturalSize() const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (!video_frame_provider_)
- return WebSize();
+ return gfx::Size();
+ const gfx::Size& current_size = compositor_->GetCurrentSize();
if (video_transformation_.rotation == media::VIDEO_ROTATION_90 ||
video_transformation_.rotation == media::VIDEO_ROTATION_270) {
- const gfx::Size& current_size = compositor_->GetCurrentSize();
- return WebSize(current_size.height(), current_size.width());
+ return gfx::Size(current_size.height(), current_size.width());
}
- return WebSize(compositor_->GetCurrentSize());
+ return current_size;
}
-WebSize WebMediaPlayerMS::VisibleRect() const {
+gfx::Size WebMediaPlayerMS::VisibleSize() const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
scoped_refptr<media::VideoFrame> video_frame = compositor_->GetCurrentFrame();
if (!video_frame)
- return WebSize();
+ return gfx::Size();
const gfx::Rect& visible_rect = video_frame->visible_rect();
if (video_transformation_.rotation == media::VIDEO_ROTATION_90 ||
video_transformation_.rotation == media::VIDEO_ROTATION_270) {
- return WebSize(visible_rect.height(), visible_rect.width());
+ return gfx::Size(visible_rect.height(), visible_rect.width());
}
- return WebSize(visible_rect.width(), visible_rect.height());
+ return visible_rect.size();
}
bool WebMediaPlayerMS::Paused() const {
@@ -766,14 +836,17 @@ double WebMediaPlayerMS::CurrentTime() const {
return 0.0;
}
+bool WebMediaPlayerMS::IsEnded() const {
+ // MediaStreams never end.
+ return false;
+}
+
WebMediaPlayer::NetworkState WebMediaPlayerMS::GetNetworkState() const {
- DVLOG(2) << __func__ << ", state:" << network_state_;
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return network_state_;
}
WebMediaPlayer::ReadyState WebMediaPlayerMS::GetReadyState() const {
- DVLOG(1) << __func__ << ", state:" << ready_state_;
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return ready_state_;
}
@@ -812,7 +885,7 @@ void WebMediaPlayerMS::Paint(cc::PaintCanvas* canvas,
const scoped_refptr<media::VideoFrame> frame = compositor_->GetCurrentFrame();
- viz::ContextProvider* provider = nullptr;
+ viz::RasterContextProvider* provider = nullptr;
if (frame && frame->HasTextures()) {
provider = Platform::Current()->SharedMainThreadContextProvider();
// GPU Process crashed.
@@ -944,6 +1017,8 @@ void WebMediaPlayerMS::OnPause() {
}
void WebMediaPlayerMS::OnMuted(bool muted) {
+ SendLogMessage(
+ String::Format("%s({muted=%s})", __func__, muted ? "true" : "false"));
client_->RequestMuted(muted);
}
@@ -955,6 +1030,14 @@ void WebMediaPlayerMS::OnSeekBackward(double seconds) {
// TODO(perkj, magjed): See TODO in OnPlay().
}
+void WebMediaPlayerMS::OnEnterPictureInPicture() {
+ client_->RequestEnterPictureInPicture();
+}
+
+void WebMediaPlayerMS::OnExitPictureInPicture() {
+ client_->RequestExitPictureInPicture();
+}
+
void WebMediaPlayerMS::OnVolumeMultiplierUpdate(double multiplier) {
// TODO(perkj, magjed): See TODO in OnPlay().
}
@@ -1164,6 +1247,8 @@ void WebMediaPlayerMS::RepaintInternal() {
void WebMediaPlayerMS::SetNetworkState(WebMediaPlayer::NetworkState state) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ SendLogMessage(String::Format("%s => (state=%s)", __func__,
+ NetworkStateToString(network_state_)));
network_state_ = state;
// Always notify to ensure client has the latest value.
get_client()->NetworkStateChanged();
@@ -1171,6 +1256,8 @@ void WebMediaPlayerMS::SetNetworkState(WebMediaPlayer::NetworkState state) {
void WebMediaPlayerMS::SetReadyState(WebMediaPlayer::ReadyState state) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ SendLogMessage(String::Format("%s => (state=%s)", __func__,
+ ReadyStateToString(ready_state_)));
ready_state_ = state;
// Always notify to ensure client has the latest value.
get_client()->ReadyStateChanged();
@@ -1190,10 +1277,7 @@ void WebMediaPlayerMS::TriggerResize() {
if (HasVideo())
get_client()->SizeChanged();
- // TODO(crbug.com/964494): Remove this explicit conversion.
- WebSize natural_size = NaturalSize();
- gfx::Size gfx_size(natural_size.height, natural_size.width);
- delegate_->DidPlayerSizeChange(delegate_id_, gfx_size);
+ delegate_->DidPlayerSizeChange(delegate_id_, NaturalSize());
}
void WebMediaPlayerMS::SetGpuMemoryBufferVideoForTesting(
@@ -1215,4 +1299,38 @@ void WebMediaPlayerMS::OnDisplayTypeChanged(
display_type == WebMediaPlayer::DisplayType::kPictureInPicture));
}
+void WebMediaPlayerMS::OnNewFramePresentedCallback() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ client_->OnRequestVideoFrameCallback();
+}
+
+void WebMediaPlayerMS::SendLogMessage(const WTF::String& message) const {
+ blink::WebRtcLogMessage(
+ "WMPMS::" + message.Utf8() +
+ String::Format(" [delegate_id=%d]", delegate_id_).Utf8());
+}
+
+std::unique_ptr<WebMediaPlayer::VideoFramePresentationMetadata>
+WebMediaPlayerMS::GetVideoFramePresentationMetadata() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(compositor_);
+
+ return compositor_->GetLastPresentedFrameMetadata();
+}
+
+void WebMediaPlayerMS::RequestVideoFrameCallback() {
+ DCHECK(RuntimeEnabledFeatures::RequestVideoFrameCallbackEnabled());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ if (!compositor_) {
+ // Reissue the request after |compositor_| is created, in Load().
+ pending_rvfc_request_ = true;
+ return;
+ }
+
+ compositor_->SetOnFramePresentedCallback(
+ media::BindToCurrentLoop(base::BindOnce(
+ &WebMediaPlayerMS::OnNewFramePresentedCallback, weak_this_)));
+}
+
} // namespace blink
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 815c2e45768..254bb4d5fe8 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
@@ -12,6 +12,7 @@
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
+#include "build/build_config.h"
#include "cc/paint/skia_paint_canvas.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/video_frame.h"
@@ -73,16 +74,18 @@ scoped_refptr<media::VideoFrame> CopyFrame(
frame->visible_rect().width(), frame->visible_rect().height()));
cc::SkiaPaintCanvas paint_canvas(bitmap);
- DCHECK(provider->ContextGL());
+ DCHECK(provider->RasterInterface());
video_renderer->Copy(frame.get(), &paint_canvas, provider);
SkPixmap pixmap;
const bool result = bitmap.peekPixels(&pixmap);
DCHECK(result) << "Error trying to access SkBitmap's pixels";
- const uint32_t source_pixel_format =
- (kN32_SkColorType == kRGBA_8888_SkColorType) ? libyuv::FOURCC_ABGR
- : libyuv::FOURCC_ARGB;
+#if SK_PMCOLOR_BYTE_ORDER(R, G, B, A)
+ const uint32_t source_pixel_format = libyuv::FOURCC_ABGR;
+#else
+ const uint32_t source_pixel_format = libyuv::FOURCC_ARGB;
+#endif
libyuv::ConvertToI420(static_cast<const uint8_t*>(pixmap.addr(0, 0)),
pixmap.computeByteSize(),
new_frame->visible_data(media::VideoFrame::kYPlane),
@@ -422,7 +425,11 @@ void WebMediaPlayerMSCompositor::PutCurrentFrame() {
base::TimeDelta WebMediaPlayerMSCompositor::GetPreferredRenderInterval() {
DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
- return viz::BeginFrameArgs::MinInterval();
+ if (!rendering_frame_buffer_) {
+ return last_render_length_;
+ } else {
+ return rendering_frame_buffer_->average_frame_duration();
+ }
}
void WebMediaPlayerMSCompositor::StartRendering() {
@@ -501,7 +508,7 @@ void WebMediaPlayerMSCompositor::RenderUsingAlgorithm(
return;
const base::TimeDelta timestamp = frame->timestamp();
- SetCurrentFrame(std::move(frame));
+ SetCurrentFrame(std::move(frame), deadline_min);
const auto& end = timestamps_to_clock_times_.end();
const auto& begin = timestamps_to_clock_times_.begin();
@@ -526,14 +533,17 @@ void WebMediaPlayerMSCompositor::RenderWithoutAlgorithmOnCompositor(
DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
{
base::AutoLock auto_lock(current_frame_lock_);
- SetCurrentFrame(std::move(frame));
+ if (current_frame_)
+ last_render_length_ = frame->timestamp() - current_frame_->timestamp();
+ SetCurrentFrame(std::move(frame), base::nullopt);
}
if (video_frame_provider_client_)
video_frame_provider_client_->DidReceiveFrame();
}
void WebMediaPlayerMSCompositor::SetCurrentFrame(
- scoped_refptr<media::VideoFrame> frame) {
+ scoped_refptr<media::VideoFrame> frame,
+ base::Optional<base::TimeTicks> expected_display_time) {
DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
current_frame_lock_.AssertAcquired();
TRACE_EVENT_INSTANT1("media", "WebMediaPlayerMSCompositor::SetCurrentFrame",
@@ -580,6 +590,23 @@ void WebMediaPlayerMSCompositor::SetCurrentFrame(
current_frame_ = std::move(frame);
+ // TODO(https://crbug.com/1050755): Improve the accuracy of these fields when
+ // we only use RenderWithoutAlgorithm.
+ base::TimeTicks now = base::TimeTicks::Now();
+ last_presentation_time_ = now;
+ last_expected_display_time_ = expected_display_time.value_or(now);
+ ++presented_frames_;
+
+ OnNewFramePresentedCB presented_frame_cb;
+ {
+ base::AutoLock lock(new_frame_presented_cb_lock_);
+ presented_frame_cb = std::move(new_frame_presented_cb_);
+ }
+
+ if (presented_frame_cb) {
+ std::move(presented_frame_cb).Run();
+ }
+
// Complete the checks after |current_frame_| is accessible to avoid
// deadlocks, see https://crbug.com/901744.
PostCrossThreadTask(
@@ -604,6 +631,7 @@ void WebMediaPlayerMSCompositor::CheckForFrameChanges(
*new_frame_rotation, *new_frame_opacity));
return;
}
+
if (new_frame_rotation.has_value()) {
PostCrossThreadTask(
*main_task_runner_, FROM_HERE,
@@ -700,4 +728,37 @@ void WebMediaPlayerMSCompositor::SetAlgorithmEnabledForTesting(
}
}
+void WebMediaPlayerMSCompositor::SetOnFramePresentedCallback(
+ OnNewFramePresentedCB presented_cb) {
+ base::AutoLock lock(new_frame_presented_cb_lock_);
+ new_frame_presented_cb_ = std::move(presented_cb);
+}
+
+std::unique_ptr<WebMediaPlayer::VideoFramePresentationMetadata>
+WebMediaPlayerMSCompositor::GetLastPresentedFrameMetadata() {
+ auto frame_metadata =
+ std::make_unique<WebMediaPlayer::VideoFramePresentationMetadata>();
+
+ scoped_refptr<media::VideoFrame> last_frame;
+ {
+ base::AutoLock lock(current_frame_lock_);
+ last_frame = current_frame_;
+ frame_metadata->presentation_time = last_presentation_time_;
+ frame_metadata->expected_display_time = last_expected_display_time_;
+ frame_metadata->presented_frames = static_cast<uint32_t>(presented_frames_);
+
+ frame_metadata->average_frame_duration = GetPreferredRenderInterval();
+ frame_metadata->rendering_interval = last_render_length_;
+ }
+
+ frame_metadata->width = last_frame->visible_rect().width();
+ frame_metadata->height = last_frame->visible_rect().height();
+
+ frame_metadata->media_time = last_frame->timestamp();
+
+ frame_metadata->metadata.MergeMetadataFrom(last_frame->metadata());
+
+ return frame_metadata;
+}
+
} // namespace blink
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 bdf8ef62323..20f4191cb39 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
@@ -21,6 +21,7 @@
#include "third_party/blink/public/platform/web_media_player.h"
#include "third_party/blink/public/platform/web_video_frame_submitter.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
namespace base {
@@ -58,6 +59,8 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
public WTF::ThreadSafeRefCounted<WebMediaPlayerMSCompositor,
WebMediaPlayerMSCompositorTraits> {
public:
+ using OnNewFramePresentedCB = base::OnceClosure;
+
WebMediaPlayerMSCompositor(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
@@ -111,6 +114,18 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
// preparation for dtor.
void StopUsingProvider();
+ // Sets a hook to be notified when a new frame is presented, to fulfill a
+ // prending video.requestAnimationFrame() request.
+ // Can be called from any thread.
+ 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/.
+ // Can be called on any thread.
+ std::unique_ptr<WebMediaPlayer::VideoFramePresentationMetadata>
+ GetLastPresentedFrameMetadata();
+
private:
friend class WTF::ThreadSafeRefCounted<WebMediaPlayerMSCompositor,
WebMediaPlayerMSCompositorTraits>;
@@ -148,7 +163,9 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
scoped_refptr<media::VideoFrame> frame);
// Update |current_frame_| and |dropped_frame_count_|
- void SetCurrentFrame(scoped_refptr<media::VideoFrame> frame);
+ void SetCurrentFrame(
+ scoped_refptr<media::VideoFrame> frame,
+ base::Optional<base::TimeTicks> expected_presentation_time);
// Following the update to |current_frame_|, this will check for changes that
// require updating video layer.
void CheckForFrameChanges(
@@ -214,9 +231,23 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor
size_t total_frame_count_;
size_t dropped_frame_count_;
+ // Used to complete video.requestAnimationFrame() calls. Reported up via
+ // GetLastPresentedFrameMetadata().
+ // TODO(https://crbug.com/1050755): Improve the accuracy of these fields for
+ // cases where we only use RenderWithoutAlgorithm().
+ base::TimeTicks last_presentation_time_ GUARDED_BY(current_frame_lock_);
+ base::TimeTicks last_expected_display_time_ GUARDED_BY(current_frame_lock_);
+ size_t presented_frames_ GUARDED_BY(current_frame_lock_) = 0u;
+
bool stopped_;
bool render_started_;
+ // Called when a new frame is enqueued, either in RenderWithoutAlgorithm() or
+ // in RenderUsingAlgorithm(). Used to fulfill video.requestAnimationFrame()
+ // requests.
+ base::Lock new_frame_presented_cb_lock_;
+ OnNewFramePresentedCB new_frame_presented_cb_;
+
std::unique_ptr<WebVideoFrameSubmitter> submitter_;
// TODO(crbug.com/952716): Replace the use of std::map by WTF::HashMap.
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 cc9b5258b42..b326d7db451 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
@@ -39,7 +39,9 @@ using ::testing::Eq;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::ReturnRef;
+using ::testing::SaveArg;
using ::testing::StrictMock;
+using ::testing::WithArgs;
namespace blink {
@@ -167,6 +169,11 @@ class FakeWebMediaPlayerDelegate
EXPECT_EQ(delegate_id_, delegate_id);
}
+ void DidPictureInPictureAvailabilityChange(int delegate_id,
+ bool available) override {
+ EXPECT_EQ(delegate_id_, delegate_id);
+ }
+
private:
int delegate_id_ = 1234;
Observer* observer_ = nullptr;
@@ -183,9 +190,9 @@ class ReusableMessageLoopEvent {
public:
ReusableMessageLoopEvent() : event_(new media::WaitableMessageLoopEvent()) {}
- base::Closure GetClosure() const { return event_->GetClosure(); }
+ base::OnceClosure GetClosure() const { return event_->GetClosure(); }
- media::PipelineStatusCB GetPipelineStatusCB() const {
+ media::PipelineStatusCallback GetPipelineStatusCB() const {
return event_->GetPipelineStatusCB();
}
@@ -583,15 +590,17 @@ class WebMediaPlayerMSTest
bool HasNativeControls() override { return false; }
bool IsAudioElement() override { return is_audio_element_; }
bool IsInAutoPIP() const override { return false; }
- void ActivateViewportIntersectionMonitoring(bool activate) override {}
void MediaRemotingStarted(
const WebString& remote_device_friendly_name) override {}
void MediaRemotingStopped(int error_code) override {}
void RequestPlay() override {}
void RequestPause() override {}
void RequestMuted(bool muted) override {}
+ void RequestEnterPictureInPicture() override {}
+ void RequestExitPictureInPicture() override {}
Features GetFeatures() override { return Features(); }
+
// Implementation of cc::VideoFrameProvider::Client
void StopUsingProvider() override;
void StartRendering() override;
@@ -626,6 +635,7 @@ class WebMediaPlayerMSTest
MOCK_METHOD1(CheckSizeChanged, void(gfx::Size));
MOCK_CONST_METHOD0(DisplayType, WebMediaPlayer::DisplayType());
MOCK_CONST_METHOD0(CouldPlayIfEnoughData, bool());
+ MOCK_METHOD0(OnRequestVideoFrameCallback, void());
std::unique_ptr<WebSurfaceLayerBridge> CreateMockSurfaceLayerBridge(
WebSurfaceLayerBridgeObserver*,
@@ -723,8 +733,8 @@ void WebMediaPlayerMSTest::ReadyStateChanged() {
if (state == WebMediaPlayer::ReadyState::kReadyStateHaveMetadata &&
!player_->HasAudio()) {
const auto& size = player_->NaturalSize();
- EXPECT_GT(size.width, 0);
- EXPECT_GT(size.height, 0);
+ EXPECT_GT(size.width(), 0);
+ EXPECT_GT(size.height(), 0);
}
if (state == WebMediaPlayer::ReadyState::kReadyStateHaveEnoughData)
player_->Play();
@@ -886,9 +896,9 @@ TEST_P(WebMediaPlayerMSTest, Playing_Normal) {
CheckSizeChanged(gfx::Size(kStandardWidth, kStandardHeight)));
message_loop_controller_.RunAndWaitForStatus(
media::PipelineStatus::PIPELINE_OK);
- const WebSize& natural_size = player_->NaturalSize();
- EXPECT_EQ(kStandardWidth, natural_size.width);
- EXPECT_EQ(kStandardHeight, natural_size.height);
+ const gfx::Size& natural_size = player_->NaturalSize();
+ EXPECT_EQ(kStandardWidth, natural_size.width());
+ EXPECT_EQ(kStandardHeight, natural_size.height());
testing::Mock::VerifyAndClearExpectations(this);
EXPECT_CALL(*this, DoSetCcLayer(false));
@@ -1048,10 +1058,10 @@ TEST_P(WebMediaPlayerMSTest, RotationChange) {
// Make sure we run all non-delayed tasks (E.G. CheckForFrameChanges) before
// testing state.
base::RunLoop().RunUntilIdle();
- WebSize natural_size = player_->NaturalSize();
+ gfx::Size natural_size = player_->NaturalSize();
// Check that height and width are flipped.
- EXPECT_EQ(kStandardHeight, natural_size.width);
- EXPECT_EQ(kStandardWidth, natural_size.height);
+ EXPECT_EQ(kStandardHeight, natural_size.width());
+ EXPECT_EQ(kStandardWidth, natural_size.height());
// Change rotation.
tokens[0] = 33;
@@ -1068,8 +1078,8 @@ TEST_P(WebMediaPlayerMSTest, RotationChange) {
media::PipelineStatus::PIPELINE_OK);
base::RunLoop().RunUntilIdle();
natural_size = player_->NaturalSize();
- EXPECT_EQ(kStandardHeight, natural_size.height);
- EXPECT_EQ(kStandardWidth, natural_size.width);
+ EXPECT_EQ(kStandardHeight, natural_size.height());
+ EXPECT_EQ(kStandardWidth, natural_size.width());
// Change rotation again.
tokens[0] = 66;
@@ -1086,8 +1096,8 @@ TEST_P(WebMediaPlayerMSTest, RotationChange) {
media::PipelineStatus::PIPELINE_OK);
base::RunLoop().RunUntilIdle();
natural_size = player_->NaturalSize();
- EXPECT_EQ(kStandardHeight, natural_size.width);
- EXPECT_EQ(kStandardWidth, natural_size.height);
+ EXPECT_EQ(kStandardHeight, natural_size.width());
+ EXPECT_EQ(kStandardWidth, natural_size.height());
testing::Mock::VerifyAndClearExpectations(this);
EXPECT_CALL(*this, DoSetCcLayer(false));
@@ -1364,6 +1374,73 @@ TEST_P(WebMediaPlayerMSTest, HiddenPlayerTests) {
}
#endif
+TEST_P(WebMediaPlayerMSTest, RequestVideoFrameCallback) {
+ InitializeWebMediaPlayerMS();
+
+ MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(true);
+
+ const int kTestBrake = static_cast<int>(FrameType::TEST_BRAKE);
+ int tokens[] = {0, 33, kTestBrake, 66, 100, 133, 166};
+ std::vector<int> timestamps(tokens, tokens + sizeof(tokens) / sizeof(int));
+ provider->QueueFrames(timestamps);
+
+ // Verify a basic call to RAF.
+ player_->RequestVideoFrameCallback();
+ EXPECT_CALL(*this, OnRequestVideoFrameCallback()).Times(1);
+ message_loop_controller_.RunAndWaitForStatus(
+ media::PipelineStatus::PIPELINE_OK);
+
+ auto metadata = player_->GetVideoFramePresentationMetadata();
+
+ EXPECT_GT(metadata->presentation_time, base::TimeTicks());
+ EXPECT_GE(metadata->expected_display_time, metadata->presentation_time);
+ testing::Mock::VerifyAndClearExpectations(this);
+
+ // Make sure multiple calls to RAF only result in one call per frame to OnRAF.
+ player_->RequestVideoFrameCallback();
+ player_->RequestVideoFrameCallback();
+ player_->RequestVideoFrameCallback();
+
+ EXPECT_CALL(*this, OnRequestVideoFrameCallback()).Times(1);
+ message_loop_controller_.RunAndWaitForStatus(
+ media::PipelineStatus::PIPELINE_OK);
+ testing::Mock::VerifyAndClearExpectations(this);
+}
+
+TEST_P(WebMediaPlayerMSTest, GetVideoFramePresentationMetadata) {
+ InitializeWebMediaPlayerMS();
+
+ MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(true);
+
+ const int kTestBrake = static_cast<int>(FrameType::TEST_BRAKE);
+ int tokens[] = {0, kTestBrake, 33, kTestBrake, 66, kTestBrake};
+ std::vector<int> timestamps(tokens, tokens + sizeof(tokens) / sizeof(int));
+ provider->QueueFrames(timestamps);
+
+ // Chain calls to video.rAF.
+ int num_frames = 3;
+ player_->RequestVideoFrameCallback();
+
+ // Verify that the presentation frame counter is monotonically increasing.
+ // Queue up a rAF call immediately after each frame.
+ int last_frame_counter = -1;
+ EXPECT_CALL(*this, OnRequestVideoFrameCallback())
+ .Times(num_frames)
+ .WillRepeatedly([&]() {
+ auto metadata = player_->GetVideoFramePresentationMetadata();
+ EXPECT_GT((int)metadata->presented_frames, last_frame_counter);
+ last_frame_counter = metadata->presented_frames;
+ player_->RequestVideoFrameCallback();
+ });
+
+ // Wait for each of the frame/kTestBreak pairs.
+ while (num_frames--) {
+ message_loop_controller_.RunAndWaitForStatus(
+ media::PipelineStatus::PIPELINE_OK);
+ }
+ testing::Mock::VerifyAndClearExpectations(this);
+}
+
INSTANTIATE_TEST_SUITE_P(All,
WebMediaPlayerMSTest,
::testing::Combine(::testing::Bool(),
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/window_media_stream.idl b/chromium/third_party/blink/renderer/modules/mediastream/window_media_stream.idl
index ecb82580e6f..18959e188f5 100644
--- a/chromium/third_party/blink/renderer/modules/mediastream/window_media_stream.idl
+++ b/chromium/third_party/blink/renderer/modules/mediastream/window_media_stream.idl
@@ -5,7 +5,7 @@
[
ImplementedAs=DOMWindowMediaStream
] partial interface Window {
- [Measure] attribute MediaStreamConstructor webkitMediaStream;
+ [DisableInNewIDLCompiler, Measure] attribute MediaStreamConstructor webkitMediaStream;
- [Measure] attribute RTCPeerConnectionConstructor webkitRTCPeerConnection;
+ [DisableInNewIDLCompiler, Measure] attribute RTCPeerConnectionConstructor webkitRTCPeerConnection;
};
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 1bb5f1a0739..8b95cf95273 100644
--- a/chromium/third_party/blink/renderer/modules/modules_idl_files.gni
+++ b/chromium/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -8,6 +8,188 @@ import("//third_party/blink/renderer/config.gni")
# The paths in this file are absolute since this file is imported and the
# file lists must be valid from multple "current directories".
+# IDL files for a module are defined by idls.gni in the module's corresponding
+# directory. idls.gni can define certain variables to add additional IDL files
+# to the build.
+#
+# modules_idl_files = [
+# # IDL files that don't fit in one of the below categories. Typically
+# # (but not required to) defines interfaces.
+# # Spec reference: https://heycam.github.io/webidl/#idl-interfaces
+# ]
+#
+# modules_callback_function_idl_files = [
+# # IDL files that only define callback functions (note: these are distinct
+# # from callback interfaces).
+# # Spec reference: https://heycam.github.io/webidl/#dfn-callback-function).
+# # TODO(dcheng): Figure out why this is its own category.
+# ]
+#
+# modules_dictionary_idl_files = [
+# # IDL files that define dictionaries and any supporting types (such as
+# # enums) for the dictionaries.
+# # Spec reference: https://heycam.github.io/webidl/#idl-dictionaries
+# ]
+#
+# modules_dependency_idl_files = [
+# # IDL files that either define partial interfaces or target (right side
+# # of) `includes`.
+# # Spec reference: https://heycam.github.io/webidl/#dfn-partial-interface
+# # Spec reference: https://heycam.github.io/webidl/#idl-interface-mixins
+# ]
+#
+# modules_testing_dependency_idl_files = [
+# # Similar to |modules_dependency_idl_files| but limited to things that are
+# # exposed only for testing.
+# ]
+_idl_imports = [
+ "//third_party/blink/renderer/modules/accessibility/idls.gni",
+ "//third_party/blink/renderer/modules/animationworklet/idls.gni",
+ "//third_party/blink/renderer/modules/app_banner/idls.gni",
+ "//third_party/blink/renderer/modules/audio_output_devices/idls.gni",
+ "//third_party/blink/renderer/modules/background_fetch/idls.gni",
+ "//third_party/blink/renderer/modules/background_sync/idls.gni",
+ "//third_party/blink/renderer/modules/badging/idls.gni",
+ "//third_party/blink/renderer/modules/battery/idls.gni",
+ "//third_party/blink/renderer/modules/beacon/idls.gni",
+ "//third_party/blink/renderer/modules/bluetooth/idls.gni",
+ "//third_party/blink/renderer/modules/broadcastchannel/idls.gni",
+ "//third_party/blink/renderer/modules/cache_storage/idls.gni",
+ "//third_party/blink/renderer/modules/canvas/idls.gni",
+ "//third_party/blink/renderer/modules/clipboard/idls.gni",
+ "//third_party/blink/renderer/modules/compression/idls.gni",
+ "//third_party/blink/renderer/modules/contacts_picker/idls.gni",
+ "//third_party/blink/renderer/modules/content_index/idls.gni",
+ "//third_party/blink/renderer/modules/cookie_store/idls.gni",
+ "//third_party/blink/renderer/modules/credentialmanager/idls.gni",
+ "//third_party/blink/renderer/modules/crypto/idls.gni",
+ "//third_party/blink/renderer/modules/csspaint/idls.gni",
+ "//third_party/blink/renderer/modules/device_orientation/idls.gni",
+ "//third_party/blink/renderer/modules/donottrack/idls.gni",
+ "//third_party/blink/renderer/modules/encoding/idls.gni",
+ "//third_party/blink/renderer/modules/encryptedmedia/idls.gni",
+ "//third_party/blink/renderer/modules/eventsource/idls.gni",
+ "//third_party/blink/renderer/modules/filesystem/idls.gni",
+ "//third_party/blink/renderer/modules/font_access/idls.gni",
+ "//third_party/blink/renderer/modules/gamepad/idls.gni",
+ "//third_party/blink/renderer/modules/geolocation/idls.gni",
+ "//third_party/blink/renderer/modules/hid/idls.gni",
+ "//third_party/blink/renderer/modules/idle/idls.gni",
+ "//third_party/blink/renderer/modules/imagecapture/idls.gni",
+ "//third_party/blink/renderer/modules/indexeddb/idls.gni",
+ "//third_party/blink/renderer/modules/installedapp/idls.gni",
+ "//third_party/blink/renderer/modules/keyboard/idls.gni",
+ "//third_party/blink/renderer/modules/launch/idls.gni",
+ "//third_party/blink/renderer/modules/locks/idls.gni",
+ "//third_party/blink/renderer/modules/manifest/idls.gni",
+ "//third_party/blink/renderer/modules/media_capabilities/idls.gni",
+ "//third_party/blink/renderer/modules/mediacapturefromelement/idls.gni",
+ "//third_party/blink/renderer/modules/mediarecorder/idls.gni",
+ "//third_party/blink/renderer/modules/mediasession/idls.gni",
+ "//third_party/blink/renderer/modules/mediasource/idls.gni",
+ "//third_party/blink/renderer/modules/mediastream/idls.gni",
+ "//third_party/blink/renderer/modules/native_file_system/idls.gni",
+ "//third_party/blink/renderer/modules/native_io/idls.gni",
+ "//third_party/blink/renderer/modules/navigatorcontentutils/idls.gni",
+ "//third_party/blink/renderer/modules/netinfo/idls.gni",
+ "//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/peerconnection/idls.gni",
+ "//third_party/blink/renderer/modules/permissions/idls.gni",
+ "//third_party/blink/renderer/modules/picture_in_picture/idls.gni",
+ "//third_party/blink/renderer/modules/plugins/idls.gni",
+ "//third_party/blink/renderer/modules/presentation/idls.gni",
+ "//third_party/blink/renderer/modules/push_messaging/idls.gni",
+ "//third_party/blink/renderer/modules/quota/idls.gni",
+ "//third_party/blink/renderer/modules/remoteplayback/idls.gni",
+ "//third_party/blink/renderer/modules/scheduler/idls.gni",
+ "//third_party/blink/renderer/modules/screen_enumeration/idls.gni",
+ "//third_party/blink/renderer/modules/screen_orientation/idls.gni",
+ "//third_party/blink/renderer/modules/sensor/idls.gni",
+ "//third_party/blink/renderer/modules/service_worker/idls.gni",
+ "//third_party/blink/renderer/modules/shapedetection/idls.gni",
+ "//third_party/blink/renderer/modules/speech/idls.gni",
+ "//third_party/blink/renderer/modules/srcobject/idls.gni",
+ "//third_party/blink/renderer/modules/storage/idls.gni",
+ "//third_party/blink/renderer/modules/vibration/idls.gni",
+ "//third_party/blink/renderer/modules/video_rvfc/idls.gni",
+ "//third_party/blink/renderer/modules/wake_lock/idls.gni",
+ "//third_party/blink/renderer/modules/webaudio/idls.gni",
+ "//third_party/blink/renderer/modules/webcodecs/idls.gni",
+ "//third_party/blink/renderer/modules/webdatabase/idls.gni",
+ "//third_party/blink/renderer/modules/webgl/idls.gni",
+ "//third_party/blink/renderer/modules/webgpu/idls.gni",
+ "//third_party/blink/renderer/modules/webmidi/idls.gni",
+ "//third_party/blink/renderer/modules/webshare/idls.gni",
+ "//third_party/blink/renderer/modules/websockets/idls.gni",
+ "//third_party/blink/renderer/modules/webtransport/idls.gni",
+ "//third_party/blink/renderer/modules/webusb/idls.gni",
+ "//third_party/blink/renderer/modules/xr/idls.gni",
+]
+
+# TODO(dcheng): For whatever reason, is_android doesn't seem to be defined, even
+# if using import() instead of read_file() in the foreach() loop below...
+if (!is_android) {
+ _idl_imports += [ "//third_party/blink/renderer/modules/serial/idls.gni" ]
+}
+
+# Do not add IDL files directly to these lists. See _idl_imports above instead
+# on how to add IDL files for a module.
+modules_idl_files = []
+modules_callback_function_idl_files = []
+modules_dictionary_idl_files = []
+modules_dependency_idl_files = []
+modules_testing_dependency_idl_files = []
+
+foreach(idl_import, _idl_imports) {
+ # Avoid reassignment error by assigning to empty scope first.
+ _imported = {
+ }
+ _imported = read_file(idl_import, "scope")
+
+ # Paths are potentially relative to the location of the .gni. Rebase them
+ # relative to "." so get_path_info() works as expected.
+ gni_dir = get_path_info(idl_import, "dir")
+
+ if (defined(_imported.modules_idl_files)) {
+ modules_idl_files +=
+ get_path_info(rebase_path(_imported.modules_idl_files, ".", gni_dir),
+ "abspath")
+ }
+
+ if (defined(_imported.modules_callback_function_idl_files)) {
+ modules_callback_function_idl_files +=
+ get_path_info(rebase_path(_imported.modules_callback_function_idl_files,
+ ".",
+ gni_dir),
+ "abspath")
+ }
+
+ if (defined(_imported.modules_dictionary_idl_files)) {
+ modules_dictionary_idl_files +=
+ get_path_info(
+ rebase_path(_imported.modules_dictionary_idl_files, ".", gni_dir),
+ "abspath")
+ }
+
+ if (defined(_imported.modules_dependency_idl_files)) {
+ modules_dependency_idl_files +=
+ get_path_info(
+ rebase_path(_imported.modules_dependency_idl_files, ".", gni_dir),
+ "abspath")
+ }
+
+ if (defined(_imported.modules_testing_dependency_idl_files)) {
+ modules_testing_dependency_idl_files +=
+ get_path_info(
+ rebase_path(_imported.modules_testing_dependency_idl_files,
+ ".",
+ gni_dir),
+ "abspath")
+ }
+}
+
bindings_modules_output_dir = "$bindings_output_dir/modules"
blink_modules_output_dir = "$root_gen_dir/third_party/blink/renderer/modules"
@@ -57,1020 +239,6 @@ modules_global_constructors_generated_idl_files = process_file_template(
modules_global_constructors_original_interface_basenames,
[ "$blink_modules_output_dir/{{source_name_part}}_modules_constructors.idl" ])
-modules_idl_files =
- get_path_info(
- [
- "animationworklet/animation_worklet_global_scope.idl",
- "animationworklet/worklet_animation_effect.idl",
- "animationworklet/worklet_animation.idl",
- "animationworklet/worklet_group_effect.idl",
- "app_banner/before_install_prompt_event.idl",
- "background_fetch/background_fetch_event.idl",
- "background_fetch/background_fetch_manager.idl",
- "background_fetch/background_fetch_record.idl",
- "background_fetch/background_fetch_registration.idl",
- "background_fetch/background_fetch_update_ui_event.idl",
- "background_sync/sync_event.idl",
- "background_sync/periodic_sync_event.idl",
- "background_sync/periodic_sync_manager.idl",
- "background_sync/sync_manager.idl",
- "battery/battery_manager.idl",
- "bluetooth/bluetooth.idl",
- "bluetooth/bluetooth_advertising_event.idl",
- "bluetooth/bluetooth_characteristic_properties.idl",
- "bluetooth/bluetooth_device.idl",
- "bluetooth/bluetooth_le_scan.idl",
- "bluetooth/bluetooth_manufacturer_data_map.idl",
- "bluetooth/bluetooth_remote_gatt_characteristic.idl",
- "bluetooth/bluetooth_remote_gatt_descriptor.idl",
- "bluetooth/bluetooth_remote_gatt_server.idl",
- "bluetooth/bluetooth_remote_gatt_service.idl",
- "bluetooth/bluetooth_service_data_map.idl",
- "bluetooth/bluetooth_uuid.idl",
- "broadcastchannel/broadcast_channel.idl",
- "cache_storage/cache.idl",
- "cache_storage/cache_storage.idl",
- "canvas/canvas2d/canvas_gradient.idl",
- "canvas/canvas2d/canvas_pattern.idl",
- "canvas/canvas2d/canvas_rendering_context_2d.idl",
- "canvas/canvas2d/path_2d.idl",
- "canvas/imagebitmap/image_bitmap_rendering_context.idl",
- "canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl",
- "clipboard/clipboard.idl",
- "clipboard/clipboard_item.idl",
- "compression/compression_stream.idl",
- "compression/decompression_stream.idl",
- "contacts_picker/contact_address.idl",
- "contacts_picker/contacts_manager.idl",
- "content_index/content_index.idl",
- "content_index/content_index_event.idl",
- "cookie_store/cookie_change_event.idl",
- "cookie_store/cookie_store.idl",
- "cookie_store/cookie_store_manager.idl",
- "cookie_store/extendable_cookie_change_event.idl",
- "credentialmanager/authenticator_assertion_response.idl",
- "credentialmanager/authenticator_attestation_response.idl",
- "credentialmanager/authenticator_response.idl",
- "credentialmanager/credential.idl",
- "credentialmanager/credentials_container.idl",
- "credentialmanager/federated_credential.idl",
- "credentialmanager/password_credential.idl",
- "credentialmanager/public_key_credential.idl",
- "crypto/crypto.idl",
- "crypto/crypto_key.idl",
- "crypto/subtle_crypto.idl",
- "csspaint/paint_rendering_context_2d.idl",
- "csspaint/paint_size.idl",
- "csspaint/paint_worklet_global_scope.idl",
- "device_orientation/device_motion_event.idl",
- "device_orientation/device_motion_event_acceleration.idl",
- "device_orientation/device_motion_event_rotation_rate.idl",
- "device_orientation/device_orientation_event.idl",
- "encoding/text_decoder.idl",
- "encoding/text_decoder_stream.idl",
- "encoding/text_encoder.idl",
- "encoding/text_encoder_stream.idl",
- "encryptedmedia/media_encrypted_event.idl",
- "encryptedmedia/media_key_message_event.idl",
- "encryptedmedia/media_key_session.idl",
- "encryptedmedia/media_key_status_map.idl",
- "encryptedmedia/media_key_system_access.idl",
- "encryptedmedia/media_keys.idl",
- "eventsource/event_source.idl",
- "filesystem/directory_entry.idl",
- "filesystem/directory_entry_sync.idl",
- "filesystem/directory_reader.idl",
- "filesystem/directory_reader_sync.idl",
- "filesystem/dom_file_system.idl",
- "filesystem/dom_file_system_sync.idl",
- "filesystem/entries_callback.idl",
- "filesystem/entry.idl",
- "filesystem/entry_callback.idl",
- "filesystem/entry_sync.idl",
- "filesystem/error_callback.idl",
- "filesystem/file_callback.idl",
- "filesystem/file_entry.idl",
- "filesystem/file_entry_sync.idl",
- "filesystem/file_system_callback.idl",
- "filesystem/file_writer.idl",
- "filesystem/file_writer_callback.idl",
- "filesystem/file_writer_sync.idl",
- "filesystem/metadata.idl",
- "filesystem/metadata_callback.idl",
- "launch/launch_params.idl",
- "launch/launch_queue.idl",
- "gamepad/gamepad.idl",
- "gamepad/gamepad_axis_event.idl",
- "gamepad/gamepad_button.idl",
- "gamepad/gamepad_button_event.idl",
- "gamepad/gamepad_event.idl",
- "gamepad/gamepad_haptic_actuator.idl",
- "gamepad/gamepad_list.idl",
- "geolocation/geolocation.idl",
- "geolocation/geolocation_coordinates.idl",
- "geolocation/geolocation_position.idl",
- "geolocation/geolocation_position_error.idl",
- "hid/hid.idl",
- "hid/hid_collection_info.idl",
- "hid/hid_connection_event.idl",
- "hid/hid_device.idl",
- "hid/hid_input_report_event.idl",
- "hid/hid_report_info.idl",
- "hid/hid_report_item.idl",
- "idle/idle_detector.idl",
- "idle/idle_state.idl",
- "imagecapture/image_capture.idl",
- "imagecapture/media_settings_range.idl",
- "imagecapture/photo_capabilities.idl",
- "indexeddb/idb_cursor.idl",
- "indexeddb/idb_cursor_with_value.idl",
- "indexeddb/idb_database.idl",
- "indexeddb/idb_factory.idl",
- "indexeddb/idb_index.idl",
- "indexeddb/idb_key_range.idl",
- "indexeddb/idb_object_store.idl",
- "indexeddb/idb_observation.idl",
- "indexeddb/idb_observer.idl",
- "indexeddb/idb_observer_changes.idl",
- "indexeddb/idb_open_db_request.idl",
- "indexeddb/idb_request.idl",
- "indexeddb/idb_transaction.idl",
- "indexeddb/idb_version_change_event.idl",
- "keyboard/keyboard.idl",
- "keyboard/keyboard_layout_map.idl",
- "locks/lock.idl",
- "locks/lock_manager.idl",
- "media_capabilities/media_capabilities.idl",
- "mediacapturefromelement/canvas_capture_media_stream_track.idl",
- "mediarecorder/blob_event.idl",
- "mediarecorder/media_recorder.idl",
- "mediasession/media_metadata.idl",
- "mediasession/media_session.idl",
- "mediasource/media_source.idl",
- "mediasource/source_buffer.idl",
- "mediasource/source_buffer_list.idl",
- "mediasource/track_default.idl",
- "mediasource/track_default_list.idl",
- "mediasource/video_playback_quality.idl",
- "mediastream/input_device_info.idl",
- "mediastream/media_device_info.idl",
- "mediastream/media_devices.idl",
- "mediastream/media_stream.idl",
- "mediastream/media_stream_event.idl",
- "mediastream/media_stream_track.idl",
- "mediastream/media_stream_track_event.idl",
- "mediastream/overconstrained_error.idl",
- "native_file_system/native_file_system_directory_iterator.idl",
- "native_file_system/file_system_directory_handle.idl",
- "native_file_system/file_system_file_handle.idl",
- "native_file_system/file_system_handle.idl",
- "native_file_system/file_system_writer.idl",
- "netinfo/network_information.idl",
- "nfc/ndef_message.idl",
- "nfc/ndef_record.idl",
- "nfc/ndef_error_event.idl",
- "nfc/ndef_reader.idl",
- "nfc/ndef_reading_event.idl",
- "nfc/ndef_writer.idl",
- "notifications/notification.idl",
- "notifications/notification_event.idl",
- "notifications/timestamp_trigger.idl",
- "payments/abort_payment_event.idl",
- "payments/can_make_payment_event.idl",
- "payments/merchant_validation_event.idl",
- "payments/payment_address.idl",
- "payments/payment_instruments.idl",
- "payments/payment_manager.idl",
- "payments/payment_method_change_event.idl",
- "payments/payment_request.idl",
- "payments/payment_request_event.idl",
- "payments/payment_request_update_event.idl",
- "payments/payment_response.idl",
- "peerconnection/rtc_certificate.idl",
- "peerconnection/rtc_data_channel.idl",
- "peerconnection/rtc_data_channel_event.idl",
- "peerconnection/rtc_dtls_transport.idl",
- "peerconnection/rtc_dtmf_sender.idl",
- "peerconnection/rtc_dtmf_tone_change_event.idl",
- "peerconnection/rtc_error.idl",
- "peerconnection/rtc_error_event.idl",
- "peerconnection/rtc_ice_candidate.idl",
- "peerconnection/rtc_ice_transport.idl",
- "peerconnection/rtc_legacy_stats_report.idl",
- "peerconnection/rtc_peer_connection.idl",
- "peerconnection/rtc_peer_connection_ice_error_event.idl",
- "peerconnection/rtc_peer_connection_ice_event.idl",
- "peerconnection/rtc_quic_stream.idl",
- "peerconnection/rtc_quic_stream_event.idl",
- "peerconnection/rtc_quic_transport.idl",
- "peerconnection/rtc_rtp_receiver.idl",
- "peerconnection/rtc_rtp_sender.idl",
- "peerconnection/rtc_rtp_transceiver.idl",
- "peerconnection/rtc_sctp_transport.idl",
- "peerconnection/rtc_session_description.idl",
- "peerconnection/rtc_stats_report.idl",
- "peerconnection/rtc_stats_response.idl",
- "peerconnection/rtc_track_event.idl",
- "permissions/permission_status.idl",
- "permissions/permissions.idl",
- "picture_in_picture/enter_picture_in_picture_event.idl",
- "picture_in_picture/picture_in_picture_window.idl",
- "plugins/mime_type.idl",
- "plugins/mime_type_array.idl",
- "plugins/plugin.idl",
- "plugins/plugin_array.idl",
- "presentation/presentation.idl",
- "presentation/presentation_availability.idl",
- "presentation/presentation_connection.idl",
- "presentation/presentation_connection_available_event.idl",
- "presentation/presentation_connection_close_event.idl",
- "presentation/presentation_connection_list.idl",
- "presentation/presentation_receiver.idl",
- "presentation/presentation_request.idl",
- "push_messaging/push_event.idl",
- "push_messaging/push_manager.idl",
- "push_messaging/push_message_data.idl",
- "push_messaging/push_subscription.idl",
- "push_messaging/push_subscription_change_event.idl",
- "push_messaging/push_subscription_options.idl",
- "quota/deprecated_storage_info.idl",
- "quota/deprecated_storage_quota.idl",
- "quota/dom_error.idl",
- "quota/storage_manager.idl",
- "remoteplayback/remote_playback.idl",
- "scheduler/scheduler.idl",
- "scheduler/task_controller.idl",
- "scheduler/task_signal.idl",
- "screen_enumeration/screen_manager.idl",
- "screen_orientation/screen_orientation.idl",
- "sensor/absolute_orientation_sensor.idl",
- "sensor/accelerometer.idl",
- "sensor/ambient_light_sensor.idl",
- "sensor/gyroscope.idl",
- "sensor/linear_acceleration_sensor.idl",
- "sensor/magnetometer.idl",
- "sensor/orientation_sensor.idl",
- "sensor/relative_orientation_sensor.idl",
- "sensor/sensor.idl",
- "sensor/sensor_error_event.idl",
- "service_worker/client.idl",
- "service_worker/clients.idl",
- "service_worker/extendable_event.idl",
- "service_worker/extendable_message_event.idl",
- "service_worker/fetch_event.idl",
- "service_worker/install_event.idl",
- "service_worker/navigation_preload_manager.idl",
- "service_worker/service_worker.idl",
- "service_worker/service_worker_container.idl",
- "service_worker/service_worker_global_scope.idl",
- "service_worker/service_worker_registration.idl",
- "service_worker/window_client.idl",
- "shapedetection/barcode_detector.idl",
- "shapedetection/detected_barcode.idl",
- "shapedetection/detected_face.idl",
- "shapedetection/detected_text.idl",
- "shapedetection/face_detector.idl",
- "shapedetection/text_detector.idl",
- "speech/speech_grammar.idl",
- "speech/speech_grammar_list.idl",
- "speech/speech_recognition.idl",
- "speech/speech_recognition_alternative.idl",
- "speech/speech_recognition_error_event.idl",
- "speech/speech_recognition_event.idl",
- "speech/speech_recognition_result.idl",
- "speech/speech_recognition_result_list.idl",
- "speech/speech_synthesis.idl",
- "speech/speech_synthesis_error_event.idl",
- "speech/speech_synthesis_event.idl",
- "speech/speech_synthesis_utterance.idl",
- "speech/speech_synthesis_voice.idl",
- "sms/sms.idl",
- "sms/sms_receiver.idl",
- "storage/storage.idl",
- "storage/storage_event.idl",
- "wake_lock/wake_lock.idl",
- "wake_lock/wake_lock_sentinel.idl",
- "webaudio/analyser_node.idl",
- "webaudio/audio_buffer.idl",
- "webaudio/audio_buffer_source_node.idl",
- "webaudio/audio_context.idl",
- "webaudio/audio_destination_node.idl",
- "webaudio/audio_listener.idl",
- "webaudio/audio_node.idl",
- "webaudio/audio_param.idl",
- "webaudio/audio_param_map.idl",
- "webaudio/audio_processing_event.idl",
- "webaudio/audio_scheduled_source_node.idl",
- "webaudio/audio_worklet.idl",
- "webaudio/audio_worklet_global_scope.idl",
- "webaudio/audio_worklet_node.idl",
- "webaudio/audio_worklet_processor.idl",
- "webaudio/base_audio_context.idl",
- "webaudio/biquad_filter_node.idl",
- "webaudio/channel_merger_node.idl",
- "webaudio/channel_splitter_node.idl",
- "webaudio/constant_source_node.idl",
- "webaudio/convolver_node.idl",
- "webaudio/delay_node.idl",
- "webaudio/dynamics_compressor_node.idl",
- "webaudio/gain_node.idl",
- "webaudio/iir_filter_node.idl",
- "webaudio/media_element_audio_source_node.idl",
- "webaudio/media_stream_audio_destination_node.idl",
- "webaudio/media_stream_audio_source_node.idl",
- "webaudio/offline_audio_completion_event.idl",
- "webaudio/offline_audio_context.idl",
- "webaudio/oscillator_node.idl",
- "webaudio/panner_node.idl",
- "webaudio/periodic_wave.idl",
- "webaudio/script_processor_node.idl",
- "webaudio/stereo_panner_node.idl",
- "webaudio/wave_shaper_node.idl",
- "webdatabase/database.idl",
- "webdatabase/sql_error.idl",
- "webdatabase/sql_result_set.idl",
- "webdatabase/sql_result_set_row_list.idl",
- "webdatabase/sql_statement_callback.idl",
- "webdatabase/sql_statement_error_callback.idl",
- "webdatabase/sql_transaction.idl",
- "webdatabase/sql_transaction_callback.idl",
- "webdatabase/sql_transaction_error_callback.idl",
- "webgl/angle_instanced_arrays.idl",
- "webgl/ext_blend_min_max.idl",
- "webgl/ext_color_buffer_float.idl",
- "webgl/ext_color_buffer_half_float.idl",
- "webgl/ext_disjoint_timer_query.idl",
- "webgl/ext_disjoint_timer_query_webgl2.idl",
- "webgl/ext_float_blend.idl",
- "webgl/ext_frag_depth.idl",
- "webgl/ext_shader_texture_lod.idl",
- "webgl/ext_srgb.idl",
- "webgl/ext_texture_filter_anisotropic.idl",
- "webgl/khr_parallel_shader_compile.idl",
- "webgl/oes_element_index_uint.idl",
- "webgl/oes_fbo_render_mipmap.idl",
- "webgl/oes_standard_derivatives.idl",
- "webgl/oes_texture_float.idl",
- "webgl/oes_texture_float_linear.idl",
- "webgl/oes_texture_half_float.idl",
- "webgl/oes_texture_half_float_linear.idl",
- "webgl/oes_vertex_array_object.idl",
- "webgl/ovr_multiview_2.idl",
- "webgl/webgl2_rendering_context.idl",
- "webgl/webgl_active_info.idl",
- "webgl/webgl_buffer.idl",
- "webgl/webgl_color_buffer_float.idl",
- "webgl/webgl_compressed_texture_astc.idl",
- "webgl/webgl_compressed_texture_etc.idl",
- "webgl/webgl_compressed_texture_etc1.idl",
- "webgl/webgl_compressed_texture_pvrtc.idl",
- "webgl/webgl_compressed_texture_s3tc.idl",
- "webgl/webgl_compressed_texture_s3tc_srgb.idl",
- "webgl/webgl_context_event.idl",
- "webgl/webgl_debug_renderer_info.idl",
- "webgl/webgl_debug_shaders.idl",
- "webgl/webgl_depth_texture.idl",
- "webgl/webgl_draw_buffers.idl",
- "webgl/webgl_draw_instanced_base_vertex_base_instance.idl",
- "webgl/webgl_framebuffer.idl",
- "webgl/webgl_lose_context.idl",
- "webgl/webgl_multi_draw_instanced_base_vertex_base_instance.idl",
- "webgl/webgl_multi_draw.idl",
- "webgl/webgl_program.idl",
- "webgl/webgl_query.idl",
- "webgl/webgl_renderbuffer.idl",
- "webgl/webgl_rendering_context.idl",
- "webgl/webgl_sampler.idl",
- "webgl/webgl_shader.idl",
- "webgl/webgl_shader_precision_format.idl",
- "webgl/webgl_sync.idl",
- "webgl/webgl_texture.idl",
- "webgl/webgl_timer_query_ext.idl",
- "webgl/webgl_transform_feedback.idl",
- "webgl/webgl_uniform_location.idl",
- "webgl/webgl_vertex_array_object.idl",
- "webgl/webgl_vertex_array_object_oes.idl",
- "webgl/webgl_video_frame_metadata.idl",
- "webgl/webgl_video_texture.idl",
- "webgpu/gpu.idl",
- "webgpu/gpu_adapter.idl",
- "webgpu/gpu_bind_group.idl",
- "webgpu/gpu_bind_group_layout.idl",
- "webgpu/gpu_buffer.idl",
- "webgpu/gpu_buffer_usage.idl",
- "webgpu/gpu_canvas_context.idl",
- "webgpu/gpu_color_write.idl",
- "webgpu/gpu_command_buffer.idl",
- "webgpu/gpu_command_encoder.idl",
- "webgpu/gpu_compute_pass_encoder.idl",
- "webgpu/gpu_compute_pipeline.idl",
- "webgpu/gpu_device.idl",
- "webgpu/gpu_device_lost_info.idl",
- "webgpu/gpu_fence.idl",
- "webgpu/gpu_out_of_memory_error.idl",
- "webgpu/gpu_pipeline_layout.idl",
- "webgpu/gpu_queue.idl",
- "webgpu/gpu_render_bundle.idl",
- "webgpu/gpu_render_bundle_encoder.idl",
- "webgpu/gpu_render_pass_encoder.idl",
- "webgpu/gpu_render_pipeline.idl",
- "webgpu/gpu_sampler.idl",
- "webgpu/gpu_shader_module.idl",
- "webgpu/gpu_shader_stage.idl",
- "webgpu/gpu_swap_chain.idl",
- "webgpu/gpu_texture.idl",
- "webgpu/gpu_texture_usage.idl",
- "webgpu/gpu_texture_view.idl",
- "webgpu/gpu_uncaptured_error_event.idl",
- "webgpu/gpu_validation_error.idl",
- "webmidi/midi_access.idl",
- "webmidi/midi_connection_event.idl",
- "webmidi/midi_input.idl",
- "webmidi/midi_input_map.idl",
- "webmidi/midi_message_event.idl",
- "webmidi/midi_output.idl",
- "webmidi/midi_output_map.idl",
- "webmidi/midi_port.idl",
- "websockets/close_event.idl",
- "websockets/websocket.idl",
- "websockets/websocket_stream.idl",
- "webtransport/quic_transport.idl",
- "webusb/usb.idl",
- "webusb/usb_alternate_interface.idl",
- "webusb/usb_configuration.idl",
- "webusb/usb_connection_event.idl",
- "webusb/usb_device.idl",
- "webusb/usb_endpoint.idl",
- "webusb/usb_in_transfer_result.idl",
- "webusb/usb_interface.idl",
- "webusb/usb_isochronous_in_transfer_packet.idl",
- "webusb/usb_isochronous_in_transfer_result.idl",
- "webusb/usb_isochronous_out_transfer_packet.idl",
- "webusb/usb_isochronous_out_transfer_result.idl",
- "webusb/usb_out_transfer_result.idl",
- "xr/xr.idl",
- "xr/xr_anchor.idl",
- "xr/xr_anchor_set.idl",
- "xr/xr_bounded_reference_space.idl",
- "xr/xr_frame.idl",
- "xr/xr_hit_result.idl",
- "xr/xr_input_source.idl",
- "xr/xr_input_source_array.idl",
- "xr/xr_input_source_event.idl",
- "xr/xr_input_sources_change_event.idl",
- "xr/xr_plane.idl",
- "xr/xr_plane_detection_state.idl",
- "xr/xr_plane_set.idl",
- "xr/xr_pose.idl",
- "xr/xr_ray.idl",
- "xr/xr_reference_space.idl",
- "xr/xr_reference_space_event.idl",
- "xr/xr_render_state.idl",
- "xr/xr_rigid_transform.idl",
- "xr/xr_hit_test_result.idl",
- "xr/xr_hit_test_source.idl",
- "xr/xr_session.idl",
- "xr/xr_session_event.idl",
- "xr/xr_space.idl",
- "xr/xr_transient_input_hit_test_result.idl",
- "xr/xr_transient_input_hit_test_source.idl",
- "xr/xr_view.idl",
- "xr/xr_viewer_pose.idl",
- "xr/xr_viewport.idl",
- "xr/xr_webgl_layer.idl",
- "xr/xr_world_information.idl",
- "xr/xr_world_tracking_state.idl",
- ],
- "abspath")
-
-if (!is_android) {
- modules_idl_files += get_path_info([
- "serial/serial.idl",
- "serial/serial_port.idl",
- ],
- "abspath")
-}
-
-if (support_webgl2_compute_context) {
- modules_idl_files +=
- get_path_info([ "webgl/webgl2_compute_rendering_context.idl" ], "abspath")
-}
-
-modules_callback_function_idl_files =
- get_path_info([
- "quota/deprecated_storage_callbacks.idl",
- "video_raf/video_frame_request_callback.idl",
- "xr/xr_frame_request_callback.idl",
- ],
- "abspath")
-
-modules_dictionary_idl_files =
- get_path_info(
- [
- "app_banner/app_banner_prompt_result.idl",
- "app_banner/before_install_prompt_event_init.idl",
- "background_fetch/background_fetch_event_init.idl",
- "background_fetch/background_fetch_options.idl",
- "background_fetch/background_fetch_ui_options.idl",
- "background_sync/background_sync_options.idl",
- "background_sync/sync_event_init.idl",
- "background_sync/periodic_sync_event_init.idl",
- "bluetooth/bluetooth_advertising_event_init.idl",
- "bluetooth/bluetooth_le_scan_filter_init.idl",
- "bluetooth/bluetooth_le_scan_options.idl",
- "bluetooth/request_device_options.idl",
- "cache_storage/cache_query_options.idl",
- "cache_storage/multi_cache_query_options.idl",
- "canvas/canvas2d/canvas_rendering_context_2d_settings.idl",
- "canvas/canvas2d/hit_region_options.idl",
- "canvas/htmlcanvas/canvas_context_creation_attributes_module.idl",
- "contacts_picker/contact_info.idl",
- "contacts_picker/contacts_select_options.idl",
- "content_index/content_description.idl",
- "content_index/content_icon_definition.idl",
- "content_index/content_index_event_init.idl",
- "cookie_store/cookie_change_event_init.idl",
- "cookie_store/cookie_list_item.idl",
- "cookie_store/cookie_store_delete_options.idl",
- "cookie_store/cookie_store_get_options.idl",
- "cookie_store/cookie_store_set_extra_options.idl",
- "cookie_store/cookie_store_set_options.idl",
- "cookie_store/extendable_cookie_change_event_init.idl",
- "credentialmanager/authentication_extensions_client_inputs.idl",
- "credentialmanager/authentication_extensions_client_outputs.idl",
- "credentialmanager/authenticator_selection_criteria.idl",
- "credentialmanager/cable_authentication_data.idl",
- "credentialmanager/cable_registration_data.idl",
- "credentialmanager/collected_client_data.idl",
- "credentialmanager/credential_creation_options.idl",
- "credentialmanager/credential_data.idl",
- "credentialmanager/credential_request_options.idl",
- "credentialmanager/federated_credential_init.idl",
- "credentialmanager/federated_credential_request_options.idl",
- "credentialmanager/password_credential_data.idl",
- "credentialmanager/public_key_credential_creation_options.idl",
- "credentialmanager/public_key_credential_descriptor.idl",
- "credentialmanager/public_key_credential_entity.idl",
- "credentialmanager/public_key_credential_parameters.idl",
- "credentialmanager/public_key_credential_request_options.idl",
- "credentialmanager/public_key_credential_rp_entity.idl",
- "credentialmanager/public_key_credential_user_entity.idl",
- "csspaint/paint_rendering_context_2d_settings.idl",
- "device_orientation/device_motion_event_acceleration_init.idl",
- "device_orientation/device_motion_event_init.idl",
- "device_orientation/device_motion_event_rotation_rate_init.idl",
- "device_orientation/device_orientation_event_init.idl",
- "encoding/text_decode_options.idl",
- "encoding/text_decoder_options.idl",
- "encoding/text_encoder_encode_into_result.idl",
- "encryptedmedia/media_encrypted_event_init.idl",
- "encryptedmedia/media_key_message_event_init.idl",
- "encryptedmedia/media_key_system_configuration.idl",
- "encryptedmedia/media_key_system_media_capability.idl",
- "encryptedmedia/media_keys_policy.idl",
- "eventsource/event_source_init.idl",
- "filesystem/file_system_flags.idl",
- "gamepad/gamepad_axis_event_init.idl",
- "gamepad/gamepad_button_event_init.idl",
- "gamepad/gamepad_effect_parameters.idl",
- "gamepad/gamepad_event_init.idl",
- "geolocation/position_options.idl",
- "hid/hid_connection_event_init.idl",
- "hid/hid_device_filter.idl",
- "hid/hid_device_request_options.idl",
- "idle/idle_options.idl",
- "imagecapture/constrain_point_2d_parameters.idl",
- "imagecapture/photo_settings.idl",
- "imagecapture/point_2d.idl",
- "indexeddb/idb_database_info.idl",
- "indexeddb/idb_index_parameters.idl",
- "indexeddb/idb_object_store_parameters.idl",
- "indexeddb/idb_observer_init.idl",
- "indexeddb/idb_transaction_options.idl",
- "indexeddb/idb_version_change_event_init.idl",
- "installedapp/related_application.idl",
- "locks/lock_info.idl",
- "locks/lock_manager_snapshot.idl",
- "locks/lock_options.idl",
- "manifest/image_resource.idl",
- "media_capabilities/audio_configuration.idl",
- "media_capabilities/key_system_track_configuration.idl",
- "media_capabilities/media_configuration.idl",
- "media_capabilities/media_capabilities_decoding_info.idl",
- "media_capabilities/media_capabilities_info.idl",
- "media_capabilities/media_capabilities_key_system_configuration.idl",
- "media_capabilities/media_decoding_configuration.idl",
- "media_capabilities/media_encoding_configuration.idl",
- "media_capabilities/video_configuration.idl",
- "mediarecorder/blob_event_init.idl",
- "mediarecorder/media_recorder_options.idl",
- "mediasession/media_image.idl",
- "mediasession/media_metadata_init.idl",
- "mediasession/media_position_state.idl",
- "mediasession/media_session_action_details.idl",
- "mediasession/media_session_seek_to_action_details.idl",
- "mediastream/constrain_boolean_parameters.idl",
- "mediastream/constrain_dom_string_parameters.idl",
- "mediastream/constrain_double_range.idl",
- "mediastream/constrain_long_range.idl",
- "mediastream/double_range.idl",
- "mediastream/long_range.idl",
- "mediastream/media_stream_constraints.idl",
- "mediastream/media_stream_event_init.idl",
- "mediastream/media_stream_track_event_init.idl",
- "mediastream/media_track_capabilities.idl",
- "mediastream/media_track_constraint_set.idl",
- "mediastream/media_track_constraints.idl",
- "mediastream/media_track_settings.idl",
- "mediastream/media_track_supported_constraints.idl",
- "native_file_system/choose_file_system_entries_options.idl",
- "native_file_system/choose_file_system_entries_options_accepts.idl",
- "native_file_system/file_system_create_writer_options.idl",
- "native_file_system/file_system_get_directory_options.idl",
- "native_file_system/file_system_get_file_options.idl",
- "native_file_system/file_system_handle_permission_descriptor.idl",
- "native_file_system/file_system_remove_options.idl",
- "native_file_system/get_system_directory_options.idl",
- "native_file_system/native_file_system_directory_iterator_entry.idl",
- "nfc/ndef_message_init.idl",
- "nfc/ndef_record_init.idl",
- "nfc/ndef_error_event_init.idl",
- "nfc/ndef_push_options.idl",
- "nfc/ndef_reading_event_init.idl",
- "nfc/ndef_scan_options.idl",
- "notifications/get_notification_options.idl",
- "notifications/notification_action.idl",
- "notifications/notification_event_init.idl",
- "notifications/notification_options.idl",
- "payments/address_errors.idl",
- "payments/android_pay_method_data.idl",
- "payments/android_pay_tokenization.idl",
- "payments/basic_card_request.idl",
- "payments/can_make_payment_event_init.idl",
- "payments/image_object.idl",
- "payments/merchant_validation_event_init.idl",
- "payments/payer_errors.idl",
- "payments/payment_address_init.idl",
- "payments/payment_currency_amount.idl",
- "payments/payment_details_base.idl",
- "payments/payment_details_init.idl",
- "payments/payment_details_modifier.idl",
- "payments/payment_details_update.idl",
- "payments/payment_handler_response.idl",
- "payments/payment_instrument.idl",
- "payments/payment_item.idl",
- "payments/payment_method_change_event_init.idl",
- "payments/payment_method_data.idl",
- "payments/payment_options.idl",
- "payments/payment_request_details_update.idl",
- "payments/payment_request_event_init.idl",
- "payments/payment_request_update_event_init.idl",
- "payments/payment_shipping_option.idl",
- "payments/payment_validation_errors.idl",
- "peerconnection/rtc_answer_options.idl",
- "peerconnection/rtc_configuration.idl",
- "peerconnection/rtc_data_channel_event_init.idl",
- "peerconnection/rtc_data_channel_init.idl",
- "peerconnection/rtc_dtls_fingerprint.idl",
- "peerconnection/rtc_dtmf_tone_change_event_init.idl",
- "peerconnection/rtc_error_event_init.idl",
- "peerconnection/rtc_error_init.idl",
- "peerconnection/rtc_ice_candidate_init.idl",
- "peerconnection/rtc_ice_candidate_pair.idl",
- "peerconnection/rtc_ice_gather_options.idl",
- "peerconnection/rtc_ice_parameters.idl",
- "peerconnection/rtc_ice_server.idl",
- "peerconnection/rtc_offer_answer_options.idl",
- "peerconnection/rtc_offer_options.idl",
- "peerconnection/rtc_peer_connection_ice_error_event_init.idl",
- "peerconnection/rtc_peer_connection_ice_event_init.idl",
- "peerconnection/rtc_quic_parameters.idl",
- "peerconnection/rtc_quic_stream_event_init.idl",
- "peerconnection/rtc_quic_stream_read_result.idl",
- "peerconnection/rtc_quic_stream_write_parameters.idl",
- "peerconnection/rtc_quic_transport_stats.idl",
- "peerconnection/rtc_rtcp_parameters.idl",
- "peerconnection/rtc_rtp_capabilities.idl",
- "peerconnection/rtc_rtp_codec_capability.idl",
- "peerconnection/rtc_rtp_codec_parameters.idl",
- "peerconnection/rtc_rtp_coding_parameters.idl",
- "peerconnection/rtc_rtp_contributing_source.idl",
- "peerconnection/rtc_rtp_decoding_parameters.idl",
- "peerconnection/rtc_rtp_encoding_parameters.idl",
- "peerconnection/rtc_rtp_header_extension_capability.idl",
- "peerconnection/rtc_rtp_header_extension_parameters.idl",
- "peerconnection/rtc_rtp_parameters.idl",
- "peerconnection/rtc_rtp_receive_parameters.idl",
- "peerconnection/rtc_rtp_send_parameters.idl",
- "peerconnection/rtc_rtp_synchronization_source.idl",
- "peerconnection/rtc_rtp_transceiver_init.idl",
- "peerconnection/rtc_session_description_init.idl",
- "peerconnection/rtc_track_event_init.idl",
- "permissions/clipboard_permission_descriptor.idl",
- "permissions/midi_permission_descriptor.idl",
- "permissions/permission_descriptor.idl",
- "permissions/push_permission_descriptor.idl",
- "permissions/wake_lock_permission_descriptor.idl",
- "picture_in_picture/enter_picture_in_picture_event_init.idl",
- "picture_in_picture/picture_in_picture_options.idl",
- "presentation/presentation_connection_available_event_init.idl",
- "presentation/presentation_connection_close_event_init.idl",
- "push_messaging/push_event_init.idl",
- "push_messaging/push_subscription_change_event_init.idl",
- "push_messaging/push_subscription_options_init.idl",
- "quota/storage_estimate.idl",
- "quota/storage_usage_details.idl",
- "scheduler/scheduler_post_task_options.idl",
- "sensor/sensor_error_event_init.idl",
- "sensor/sensor_options.idl",
- "sensor/spatial_sensor_options.idl",
- "service_worker/client_query_options.idl",
- "service_worker/extendable_event_init.idl",
- "service_worker/extendable_message_event_init.idl",
- "service_worker/fetch_event_init.idl",
- "service_worker/navigation_preload_state.idl",
- "service_worker/registration_options.idl",
- "shapedetection/barcode_detector_options.idl",
- "shapedetection/face_detector_options.idl",
- "shapedetection/landmark.idl",
- "sms/sms_receiver_options.idl",
- "speech/speech_recognition_error_event_init.idl",
- "speech/speech_recognition_event_init.idl",
- "speech/speech_synthesis_error_event_init.idl",
- "speech/speech_synthesis_event_init.idl",
- "storage/storage_event_init.idl",
- "video_raf/video_frame_metadata.idl",
- "webaudio/analyser_options.idl",
- "webaudio/audio_buffer_options.idl",
- "webaudio/audio_buffer_source_options.idl",
- "webaudio/audio_context_options.idl",
- "webaudio/audio_node_options.idl",
- "webaudio/audio_param_descriptor.idl",
- "webaudio/audio_processing_event_init.idl",
- "webaudio/audio_timestamp.idl",
- "webaudio/audio_worklet_node_options.idl",
- "webaudio/biquad_filter_options.idl",
- "webaudio/channel_merger_options.idl",
- "webaudio/channel_splitter_options.idl",
- "webaudio/constant_source_options.idl",
- "webaudio/convolver_options.idl",
- "webaudio/delay_options.idl",
- "webaudio/dynamics_compressor_options.idl",
- "webaudio/gain_options.idl",
- "webaudio/iir_filter_options.idl",
- "webaudio/media_element_audio_source_options.idl",
- "webaudio/media_stream_audio_source_options.idl",
- "webaudio/offline_audio_completion_event_init.idl",
- "webaudio/offline_audio_context_options.idl",
- "webaudio/oscillator_options.idl",
- "webaudio/panner_options.idl",
- "webaudio/periodic_wave_constraints.idl",
- "webaudio/periodic_wave_options.idl",
- "webaudio/stereo_panner_options.idl",
- "webaudio/wave_shaper_options.idl",
- "webgl/webgl_context_attributes.idl",
- "webgl/webgl_context_event_init.idl",
- "webgpu/gpu_bind_group_binding.idl",
- "webgpu/gpu_bind_group_descriptor.idl",
- "webgpu/gpu_bind_group_layout_binding.idl",
- "webgpu/gpu_bind_group_layout_descriptor.idl",
- "webgpu/gpu_blend_descriptor.idl",
- "webgpu/gpu_buffer_binding.idl",
- "webgpu/gpu_command_buffer_descriptor.idl",
- "webgpu/gpu_buffer_copy_view.idl",
- "webgpu/gpu_buffer_descriptor.idl",
- "webgpu/gpu_color_dict.idl",
- "webgpu/gpu_color_state_descriptor.idl",
- "webgpu/gpu_command_encoder_descriptor.idl",
- "webgpu/gpu_compute_pipeline_descriptor.idl",
- "webgpu/gpu_compute_pass_descriptor.idl",
- "webgpu/gpu_depth_stencil_state_descriptor.idl",
- "webgpu/gpu_device_descriptor.idl",
- "webgpu/gpu_extensions.idl",
- "webgpu/gpu_extent_3d_dict.idl",
- "webgpu/gpu_fence_descriptor.idl",
- "webgpu/gpu_image_bitmap_copy_view.idl",
- "webgpu/gpu_limits.idl",
- "webgpu/gpu_object_descriptor_base.idl",
- "webgpu/gpu_origin_2d_dict.idl",
- "webgpu/gpu_origin_3d_dict.idl",
- "webgpu/gpu_pipeline_descriptor_base.idl",
- "webgpu/gpu_pipeline_layout_descriptor.idl",
- "webgpu/gpu_programmable_stage_descriptor.idl",
- "webgpu/gpu_rasterization_state_descriptor.idl",
- "webgpu/gpu_render_bundle_descriptor.idl",
- "webgpu/gpu_render_bundle_encoder_descriptor.idl",
- "webgpu/gpu_render_pass_color_attachment_descriptor.idl",
- "webgpu/gpu_render_pass_depth_stencil_attachment_descriptor.idl",
- "webgpu/gpu_render_pass_descriptor.idl",
- "webgpu/gpu_render_pipeline_descriptor.idl",
- "webgpu/gpu_request_adapter_options.idl",
- "webgpu/gpu_sampler_descriptor.idl",
- "webgpu/gpu_shader_module_descriptor.idl",
- "webgpu/gpu_stencil_state_face_descriptor.idl",
- "webgpu/gpu_swap_chain_descriptor.idl",
- "webgpu/gpu_texture_copy_view.idl",
- "webgpu/gpu_texture_descriptor.idl",
- "webgpu/gpu_texture_view_descriptor.idl",
- "webgpu/gpu_uncaptured_error_event_init.idl",
- "webgpu/gpu_vertex_attribute_descriptor.idl",
- "webgpu/gpu_vertex_buffer_layout_descriptor.idl",
- "webgpu/gpu_vertex_state_descriptor.idl",
- "webmidi/midi_connection_event_init.idl",
- "webmidi/midi_message_event_init.idl",
- "webmidi/midi_options.idl",
- "webshare/share_data.idl",
- "websockets/close_event_init.idl",
- "websockets/websocket_close_info.idl",
- "websockets/websocket_connection.idl",
- "websockets/websocket_stream_options.idl",
- "webtransport/web_transport_close_info.idl",
- "webusb/usb_connection_event_init.idl",
- "webusb/usb_control_transfer_parameters.idl",
- "webusb/usb_device_filter.idl",
- "webusb/usb_device_request_options.idl",
- "xr/xr_hit_test_options_init.idl",
- "xr/xr_input_source_event_init.idl",
- "xr/xr_input_sources_change_event_init.idl",
- "xr/xr_plane_detection_state_init.idl",
- "xr/xr_reference_space_event_init.idl",
- "xr/xr_render_state_init.idl",
- "xr/xr_session_event_init.idl",
- "xr/xr_session_init.idl",
- "xr/xr_transient_input_hit_test_options_init.idl",
- "xr/xr_webgl_layer_init.idl",
- "xr/xr_world_tracking_state_init.idl",
- ],
- "abspath")
-
-if (!is_android) {
- modules_dictionary_idl_files +=
- get_path_info([
- "serial/serial_input_signals.idl",
- "serial/serial_options.idl",
- "serial/serial_output_signals.idl",
- "serial/serial_port_request_options.idl",
- ],
- "abspath")
-}
-
-# 'partial interface' or target (right side of) 'implements'
-modules_dependency_idl_files =
- get_path_info(
- [
- "animationworklet/css_animation_worklet.idl",
- "app_banner/window_installation.idl",
- "audio_output_devices/html_media_element_audio_output_device.idl",
- "background_fetch/service_worker_global_scope_background_fetch.idl",
- "background_fetch/service_worker_registration_background_fetch.idl",
- "background_sync/service_worker_global_scope_sync.idl",
- "background_sync/service_worker_registration_sync.idl",
- "badging/navigator_badge.idl",
- "battery/navigator_battery.idl",
- "beacon/navigator_beacon.idl",
- "bluetooth/navigator_bluetooth.idl",
- "cache_storage/window_cache_storage.idl",
- "cache_storage/worker_cache_storage.idl",
- "canvas/canvas2d/canvas_path.idl",
- "clipboard/navigator_clipboard.idl",
- "contacts_picker/navigator_contacts.idl",
- "content_index/service_worker_global_scope_content_index.idl",
- "content_index/service_worker_registration_content_index.idl",
- "cookie_store/service_worker_global_scope_cookie_store.idl",
- "cookie_store/service_worker_registration_cookies.idl",
- "cookie_store/window_cookie_store.idl",
- "credentialmanager/credential_user_data.idl",
- "credentialmanager/navigator_credentials.idl",
- "crypto/window_crypto.idl",
- "crypto/worker_global_scope_crypto.idl",
- "csspaint/css_paint_worklet.idl",
- "device_orientation/window_device_motion.idl",
- "device_orientation/window_device_orientation.idl",
- "donottrack/navigator_do_not_track.idl",
- "encryptedmedia/html_media_element_encrypted_media.idl",
- "encryptedmedia/media_keys_get_status_for_policy.idl",
- "encryptedmedia/navigator_request_media_key_system_access.idl",
- "filesystem/data_transfer_item_file_system.idl",
- "filesystem/dedicated_worker_global_scope_file_system.idl",
- "filesystem/dev_tools_host_file_system.idl",
- "filesystem/html_input_element_file_system.idl",
- "filesystem/shared_worker_global_scope_file_system.idl",
- "filesystem/window_file_system.idl",
- "launch/dom_window_launch_queue.idl",
- "gamepad/navigator_gamepad.idl",
- "geolocation/navigator_geolocation.idl",
- "hid/navigator_hid.idl",
- "indexeddb/window_indexed_database.idl",
- "indexeddb/worker_global_scope_indexed_database.idl",
- "installedapp/navigator_installed_app.idl",
- "keyboard/navigator_keyboard.idl",
- "locks/navigator_locks.idl",
- "locks/worker_navigator_locks.idl",
- "media_capabilities/navigator_media_capabilities.idl",
- "media_capabilities/worker_navigator_media_capabilities.idl",
- "mediacapturefromelement/html_canvas_element_capture.idl",
- "mediacapturefromelement/html_media_element_capture.idl",
- "mediasession/navigator_media_session.idl",
- "mediasource/audio_track_source_buffer.idl",
- "mediasource/html_video_element_media_source.idl",
- "mediasource/url_media_source.idl",
- "mediasource/video_track_source_buffer.idl",
- "mediastream/media_stream_track_content_hint.idl",
- "mediastream/navigator_media_stream.idl",
- "mediastream/navigator_user_media.idl",
- "mediastream/window_media_stream.idl",
- "native_file_system/window_native_file_system.idl",
- "navigatorcontentutils/navigator_content_utils.idl",
- "netinfo/navigator_network_information.idl",
- "netinfo/worker_navigator_network_information.idl",
- "notifications/service_worker_global_scope_notifications.idl",
- "notifications/service_worker_registration_notifications.idl",
- "payments/html_iframe_element_payments.idl",
- "payments/payment_app_service_worker_global_scope.idl",
- "payments/payment_app_service_worker_registration.idl",
- "permissions/navigator_permissions.idl",
- "permissions/worker_navigator_permissions.idl",
- "picture_in_picture/document_picture_in_picture.idl",
- "picture_in_picture/html_element_picture_in_picture.idl",
- "picture_in_picture/html_video_element_picture_in_picture.idl",
- "picture_in_picture/shadow_root_picture_in_picture.idl",
- "plugins/navigator_plugins.idl",
- "presentation/navigator_presentation.idl",
- "push_messaging/service_worker_global_scope_push.idl",
- "push_messaging/service_worker_registration_push.idl",
- "quota/navigator_storage_quota.idl",
- "quota/window_quota.idl",
- "quota/worker_navigator_storage_quota.idl",
- "remoteplayback/html_media_element_remote_playback.idl",
- "scheduler/window_scheduler.idl",
- "screen_enumeration/navigator_screen_manager.idl",
- "screen_enumeration/worker_navigator_screen_manager.idl",
- "screen_orientation/screen_screen_orientation.idl",
- "service_worker/navigator_service_worker.idl",
- "sms/navigator_sms.idl",
- "speech/window_speech.idl",
- "speech/window_speech_synthesis.idl",
- "srcobject/html_media_element_src_object.idl",
- "storage/window_storage.idl",
- "video_raf/html_video_element_video_request_animation_frame.idl",
- "vibration/navigator_vibration.idl",
- "wake_lock/navigator_wake_lock.idl",
- "wake_lock/worker_navigator_wake_lock.idl",
- "webdatabase/window_web_database.idl",
- "webgl/webgl2_rendering_context_base.idl",
- "webgl/webgl_rendering_context_base.idl",
- "webgpu/gpu_programmable_pass_encoder.idl",
- "webgpu/gpu_render_encoder_base.idl",
- "webgpu/navigator_gpu.idl",
- "webgpu/worker_navigator_gpu.idl",
- "webmidi/navigator_web_midi.idl",
- "webshare/navigator_share.idl",
- "webusb/navigator_usb.idl",
- "webusb/worker_navigator_usb.idl",
- "xr/navigator_xr.idl",
- ],
- "abspath")
-
-if (!is_android) {
- modules_dependency_idl_files +=
- get_path_info([
- "serial/navigator_serial.idl",
- "serial/worker_navigator_serial.idl",
- ],
- "abspath")
-}
-
-if (support_webgl2_compute_context) {
- modules_dependency_idl_files += get_path_info(
- [
- "canvas/htmlcanvas/html_canvas_element_module_support_webgl2_compute.idl",
- "canvas/offscreencanvas/offscreen_canvas_module_support_webgl2_compute.idl",
- "webgl/webgl2_compute_rendering_context_base.idl",
- ],
- "abspath")
-} else {
- modules_dependency_idl_files +=
- get_path_info([
- "canvas/htmlcanvas/html_canvas_element_module.idl",
- "canvas/offscreencanvas/offscreen_canvas_module.idl",
- ],
- "abspath")
-}
-
-modules_testing_dependency_idl_files =
- get_path_info([
- "accessibility/testing/internals_accessibility.idl",
- "mediastream/testing/internals_media_stream.idl",
- "netinfo/testing/internals_net_info.idl",
- "peerconnection/testing/internals_rtc_certificate.idl",
- "peerconnection/testing/internals_rtc_peer_connection.idl",
- "service_worker/testing/internals_service_worker.idl",
- "speech/testing/internals_speech_synthesis.idl",
- "vibration/testing/internals_vibration.idl",
- "webaudio/testing/internals_web_audio.idl",
- ],
- "abspath")
-
modules_definition_idl_files = modules_dictionary_idl_files + modules_idl_files
# Static IDL files
diff --git a/chromium/third_party/blink/renderer/modules/modules_initializer.cc b/chromium/third_party/blink/renderer/modules/modules_initializer.cc
index 945d1ccef7e..f67d07600d0 100644
--- a/chromium/third_party/blink/renderer/modules/modules_initializer.cc
+++ b/chromium/third_party/blink/renderer/modules/modules_initializer.cc
@@ -7,6 +7,7 @@
#include <memory>
#include "base/memory/ptr_util.h"
+#include "build/build_config.h"
#include "mojo/public/cpp/bindings/binder_map.h"
#include "third_party/blink/public/mojom/dom_storage/session_storage_namespace.mojom-blink.h"
#include "third_party/blink/public/platform/interface_registry.h"
@@ -43,7 +44,7 @@
#include "third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.h"
#include "third_party/blink/renderer/modules/device_orientation/device_orientation_controller.h"
#include "third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.h"
-#include "third_party/blink/renderer/modules/document_metadata/copyless_paste_server.h"
+#include "third_party/blink/renderer/modules/document_metadata/document_metadata_server.h"
#include "third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.h"
#include "third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.h"
#include "third_party/blink/renderer/modules/event_interface_modules_names.h"
@@ -58,6 +59,7 @@
#include "third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.h"
#include "third_party/blink/renderer/modules/installation/installation_service_impl.h"
#include "third_party/blink/renderer/modules/installedapp/installed_app_controller.h"
+#include "third_party/blink/renderer/modules/launch/file_handling_expiry_impl.h"
#include "third_party/blink/renderer/modules/launch/web_launch_service_impl.h"
#include "third_party/blink/renderer/modules/manifest/manifest_manager.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h"
@@ -88,6 +90,7 @@
#include "third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h"
#include "third_party/blink/renderer/modules/worklet/animation_and_paint_worklet_thread.h"
#include "third_party/blink/renderer/modules/xr/navigator_xr.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/mojo/mojo_helper.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
@@ -98,6 +101,10 @@
#include "third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.h"
#endif
+#if defined(OS_ANDROID)
+#include "third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.h"
+#endif
+
namespace blink {
void ModulesInitializer::Initialize() {
@@ -154,12 +161,13 @@ void ModulesInitializer::Initialize() {
void ModulesInitializer::InitLocalFrame(LocalFrame& frame) const {
if (frame.IsMainFrame()) {
frame.GetInterfaceRegistry()->AddInterface(WTF::BindRepeating(
- &CopylessPasteServer::BindMojoReceiver, WrapWeakPersistent(&frame)));
- }
- if (RuntimeEnabledFeatures::FileHandlingEnabled(frame.GetDocument())) {
- frame.GetInterfaceRegistry()->AddAssociatedInterface(WTF::BindRepeating(
- &WebLaunchServiceImpl::Create, WrapWeakPersistent(&frame)));
+ &DocumentMetadataServer::BindMojoReceiver, WrapWeakPersistent(&frame)));
}
+ frame.GetInterfaceRegistry()->AddAssociatedInterface(WTF::BindRepeating(
+ &WebLaunchServiceImpl::Create, WrapWeakPersistent(&frame)));
+ frame.GetInterfaceRegistry()->AddAssociatedInterface(WTF::BindRepeating(
+ &FileHandlingExpiryImpl::Create, WrapWeakPersistent(&frame)));
+
frame.GetInterfaceRegistry()->AddInterface(WTF::BindRepeating(
&InstallationServiceImpl::Create, WrapWeakPersistent(&frame)));
// TODO(dominickn): This interface should be document-scoped rather than
@@ -169,6 +177,10 @@ void ModulesInitializer::InitLocalFrame(LocalFrame& frame) const {
&AppBannerController::BindMojoRequest, WrapWeakPersistent(&frame)));
frame.GetInterfaceRegistry()->AddInterface(WTF::BindRepeating(
&TextSuggestionBackendImpl::Create, WrapWeakPersistent(&frame)));
+#if defined(OS_ANDROID)
+ frame.GetInterfaceRegistry()->AddInterface(WTF::BindRepeating(
+ &RemoteObjectGatewayFactoryImpl::Create, WrapWeakPersistent(&frame)));
+#endif // OS_ANDROID
}
void ModulesInitializer::InstallSupplements(LocalFrame& frame) const {
@@ -187,10 +199,7 @@ void ModulesInitializer::InstallSupplements(LocalFrame& frame) const {
InspectorAccessibilityAgent::ProvideTo(&frame);
ManifestManager::ProvideTo(frame);
InstalledAppController::ProvideTo(frame);
- if (frame.IsMainFrame()) {
- // Only main frame has ImageDownloader service.
- ImageDownloaderImpl::ProvideTo(frame);
- }
+ ImageDownloaderImpl::ProvideTo(frame);
MediaInspectorContextImpl::ProvideToLocalFrame(frame);
}
@@ -207,7 +216,7 @@ MediaControls* ModulesInitializer::CreateMediaControls(
PictureInPictureController*
ModulesInitializer::CreatePictureInPictureController(Document& document) const {
- return PictureInPictureControllerImpl::Create(document);
+ return MakeGarbageCollected<PictureInPictureControllerImpl>(document);
}
void ModulesInitializer::InitInspectorAgentSession(
@@ -249,6 +258,13 @@ void ModulesInitializer::OnClearWindowObjectInMainWorld(
// presentation can offer a connection to the presentation receiver.
PresentationReceiver::From(document);
}
+
+#if defined(OS_ANDROID)
+ LocalFrame* frame = document.GetFrame();
+ DCHECK(frame);
+ if (auto* gateway = RemoteObjectGatewayImpl::From(*frame))
+ gateway->OnClearWindowObjectInMainWorld();
+#endif // OS_ANDROID
}
std::unique_ptr<WebMediaPlayer> ModulesInitializer::CreateWebMediaPlayer(
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 6f07c5a9a0e..c248e70eba5 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
@@ -16,22 +16,22 @@ blink_modules_sources("native_file_system") {
"native_file_system_file_handle.h",
"native_file_system_handle.cc",
"native_file_system_handle.h",
+ "native_file_system_underlying_sink.cc",
+ "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",
- ]
+ deps = [ "//third_party/blink/renderer/platform" ]
}
jumbo_source_set("unit_tests") {
testonly = true
- sources = [
- "window_native_file_system_test.cc",
- ]
+ sources = [ "window_native_file_system_test.cc" ]
configs += [
"//third_party/blink/renderer:config",
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/choose_file_system_entries_options.idl b/chromium/third_party/blink/renderer/modules/native_file_system/choose_file_system_entries_options.idl
index a3e158fbc13..8e907eb2629 100644
--- a/chromium/third_party/blink/renderer/modules/native_file_system/choose_file_system_entries_options.idl
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/choose_file_system_entries_options.idl
@@ -3,11 +3,15 @@
// found in the LICENSE file.
// https://wicg.github.io/native-file-system/#enumdef-choosefilesystementriestype
-enum ChooseFileSystemEntriesType { "openFile", "saveFile", "openDirectory" };
+enum ChooseFileSystemEntriesType {
+ "open-file",
+ "save-file",
+ "open-directory",
+};
// https://wicg.github.io/native-file-system/#dictdef-choosefilesystementriesoptions
dictionary ChooseFileSystemEntriesOptions {
- ChooseFileSystemEntriesType type = "openFile";
+ ChooseFileSystemEntriesType type = "open-file";
boolean multiple = false;
sequence<ChooseFileSystemEntriesOptionsAccepts> accepts;
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 ff791d2e660..bf4d4deda7b 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
@@ -10,12 +10,14 @@
RuntimeEnabled=NativeFileSystem,
ImplementedAs=NativeFileSystemDirectoryHandle
] interface FileSystemDirectoryHandle : FileSystemHandle {
- [CallWith=ScriptState] Promise<FileSystemFileHandle> getFile(USVString name, optional FileSystemGetFileOptions options);
- [CallWith=ScriptState] Promise<FileSystemDirectoryHandle> getDirectory(USVString name, optional FileSystemGetDirectoryOptions options);
+ [CallWith=ScriptState] Promise<FileSystemFileHandle> getFile(USVString name, optional FileSystemGetFileOptions options = {});
+ [CallWith=ScriptState] Promise<FileSystemDirectoryHandle> getDirectory(USVString name, optional FileSystemGetDirectoryOptions options = {});
[CallWith=ScriptState] object getEntries();
- [CallWith=ScriptState] Promise<void> removeEntry(USVString name, optional FileSystemRemoveOptions options);
+ [CallWith=ScriptState] Promise<void> removeEntry(USVString name, optional FileSystemRemoveOptions options = {});
- [CallWith=ScriptState, Measure]
+ [CallWith=ScriptState, Measure] Promise<sequence<USVString>?> resolve(FileSystemHandle possibleChild);
+
+ [CallWith=ScriptState, Measure, RaisesException]
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 1e34ae1f745..c725cb9ae72 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] Promise<FileSystemWriter> createWriter(optional FileSystemCreateWriterOptions options);
- [CallWith=ScriptState] Promise<File> getFile();
+ [CallWith=ScriptState, RuntimeEnabled=WritableFileStream, 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_handle.idl b/chromium/third_party/blink/renderer/modules/native_file_system/file_system_handle.idl
index 74f0c7958b6..d151e0b5dcd 100644
--- a/chromium/third_party/blink/renderer/modules/native_file_system/file_system_handle.idl
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/file_system_handle.idl
@@ -19,7 +19,9 @@
readonly attribute USVString name;
[CallWith=ScriptState] Promise<PermissionState> queryPermission(
- optional FileSystemHandlePermissionDescriptor descriptor);
+ optional FileSystemHandlePermissionDescriptor descriptor = {});
[CallWith=ScriptState] Promise<PermissionState> requestPermission(
- optional FileSystemHandlePermissionDescriptor descriptor);
+ optional FileSystemHandlePermissionDescriptor descriptor = {});
+
+ [CallWith=ScriptState, Measure] Promise<boolean> isSameEntry(FileSystemHandle other);
};
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
new file mode 100644
index 00000000000..8fd21015f1e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/file_system_writable_file_stream.idl
@@ -0,0 +1,16 @@
+// 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/#filesystemwritablefilestream
+[
+ Exposed=(Window,Worker),
+ SecureContext,
+ ImplementedAs=NativeFileSystemWritableFileStream,
+ RuntimeEnabled=WritableFileStream
+ ] 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);
+ [CallWith=ScriptState, RaisesException] Promise<void> close();
+ [CallWith=ScriptState, RaisesException] Promise<void> seek(unsigned long long offset);
+ };
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
index 8fb85898c83..5f8787b38ce 100644
--- 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
@@ -10,7 +10,7 @@
RuntimeEnabled=NativeFileSystem
] interface FileSystemWriter {
[CallWith=ScriptState, RaisesException] Promise<void> write(unsigned long long position, (BufferSource or Blob or USVString) data);
- [CallWith=ScriptState] Promise<void> truncate(unsigned long long size);
+ [CallWith=ScriptState, RaisesException] Promise<void> truncate(unsigned long long size);
- [CallWith=ScriptState] Promise<void> close();
+ [CallWith=ScriptState, RaisesException] Promise<void> close();
};
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
new file mode 100644
index 00000000000..490d4ad43aa
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "native_file_system_directory_iterator.idl",
+ "file_system_directory_handle.idl",
+ "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",
+ "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",
+ "native_file_system_directory_iterator_entry.idl",
+ "write_params.idl",
+]
+
+modules_dependency_idl_files = [ "window_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 490f58b7475..ad38666a794 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
@@ -11,15 +11,16 @@
#include "third_party/blink/public/mojom/native_file_system/native_file_system_manager.mojom-blink.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_file_system_get_directory_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_file_system_get_file_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_file_system_remove_options.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/modules/native_file_system/file_system_get_directory_options.h"
-#include "third_party/blink/renderer/modules/native_file_system/file_system_get_file_options.h"
-#include "third_party/blink/renderer/modules/native_file_system/file_system_remove_options.h"
#include "third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.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/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -156,24 +157,54 @@ ScriptPromise NativeFileSystemDirectoryHandle::removeEntry(
return result;
}
+ScriptPromise NativeFileSystemDirectoryHandle::resolve(
+ ScriptState* script_state,
+ NativeFileSystemHandle* possible_child) {
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ ScriptPromise result = resolver->Promise();
+
+ if (!mojo_ptr_) {
+ resolver->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kInvalidStateError));
+ return result;
+ }
+
+ mojo_ptr_->Resolve(
+ possible_child->Transfer(),
+ WTF::Bind(
+ [](ScriptPromiseResolver* resolver, NativeFileSystemErrorPtr result,
+ const base::Optional<Vector<String>>& path) {
+ if (result->status != mojom::blink::NativeFileSystemStatus::kOk) {
+ native_file_system_error::Reject(resolver, *result);
+ return;
+ }
+ if (!path.has_value()) {
+ resolver->Resolve(static_cast<ScriptWrappable*>(nullptr));
+ return;
+ }
+ resolver->Resolve(*path);
+ },
+ WrapPersistent(resolver)));
+
+ return result;
+}
+
// static
ScriptPromise NativeFileSystemDirectoryHandle::getSystemDirectory(
ScriptState* script_state,
- const GetSystemDirectoryOptions* options) {
+ const GetSystemDirectoryOptions* options,
+ ExceptionState& exception_state) {
ExecutionContext* context = ExecutionContext::From(script_state);
if (!context->GetSecurityOrigin()->CanAccessNativeFileSystem()) {
- if (context->GetSecurityContext().IsSandboxed(WebSandboxFlags::kOrigin)) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kSecurityError,
- "System directory access is denied because the context is "
- "sandboxed and lacks the 'allow-same-origin' flag."));
+ if (context->GetSecurityContext().IsSandboxed(
+ 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 {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kSecurityError,
- "System directory access is denied."));
+ exception_state.ThrowSecurityError("System directory access is denied.");
+ return ScriptPromise();
}
}
@@ -244,7 +275,33 @@ void NativeFileSystemDirectoryHandle::RequestPermissionImpl(
mojo_ptr_->RequestPermission(writable, std::move(callback));
}
-void NativeFileSystemDirectoryHandle::ContextDestroyed(ExecutionContext*) {
+void NativeFileSystemDirectoryHandle::IsSameEntryImpl(
+ mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken> other,
+ base::OnceCallback<void(mojom::blink::NativeFileSystemErrorPtr, bool)>
+ callback) {
+ if (!mojo_ptr_) {
+ std::move(callback).Run(
+ mojom::blink::NativeFileSystemError::New(
+ mojom::blink::NativeFileSystemStatus::kInvalidState,
+ base::File::Error::FILE_ERROR_FAILED, "Context Destroyed"),
+ false);
+ return;
+ }
+
+ mojo_ptr_->Resolve(
+ std::move(other),
+ WTF::Bind(
+ [](base::OnceCallback<void(mojom::blink::NativeFileSystemErrorPtr,
+ bool)> callback,
+ NativeFileSystemErrorPtr result,
+ const base::Optional<Vector<String>>& path) {
+ std::move(callback).Run(std::move(result),
+ path.has_value() && path->IsEmpty());
+ },
+ std::move(callback)));
+}
+
+void NativeFileSystemDirectoryHandle::ContextDestroyed() {
mojo_ptr_.reset();
}
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 8c037ea4114..8da60775d94 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
@@ -38,8 +38,11 @@ class NativeFileSystemDirectoryHandle final : public NativeFileSystemHandle {
const String& name,
const FileSystemRemoveOptions*);
+ ScriptPromise resolve(ScriptState*, NativeFileSystemHandle* possible_child);
+
static ScriptPromise getSystemDirectory(ScriptState*,
- const GetSystemDirectoryOptions*);
+ const GetSystemDirectoryOptions*,
+ ExceptionState&);
mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken> Transfer()
override;
@@ -48,7 +51,7 @@ class NativeFileSystemDirectoryHandle final : public NativeFileSystemHandle {
return mojo_ptr_.get();
}
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
private:
void QueryPermissionImpl(
@@ -58,6 +61,12 @@ class NativeFileSystemDirectoryHandle final : public NativeFileSystemHandle {
bool writable,
base::OnceCallback<void(mojom::blink::NativeFileSystemErrorPtr,
mojom::blink::PermissionStatus)>) override;
+ // IsSameEntry for directories is implemented in terms of resolve, as resolve
+ // also can be used to figure out if two directories are the same entry.
+ void IsSameEntryImpl(
+ mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken> other,
+ base::OnceCallback<void(mojom::blink::NativeFileSystemErrorPtr, bool)>)
+ override;
mojo::Remote<mojom::blink::NativeFileSystemDirectoryHandle> mojo_ptr_;
};
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 e8b2111112f..6152bc1996b 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
@@ -5,10 +5,10 @@
#include "third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_native_file_system_directory_iterator_entry.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/modules/native_file_system/native_file_system_directory_handle.h"
-#include "third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator_entry.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/wtf/functional.h"
@@ -18,7 +18,7 @@ namespace blink {
NativeFileSystemDirectoryIterator::NativeFileSystemDirectoryIterator(
NativeFileSystemDirectoryHandle* directory,
ExecutionContext* execution_context)
- : ContextLifecycleObserver(execution_context), directory_(directory) {
+ : ExecutionContextClient(execution_context), directory_(directory) {
directory_->MojoHandle()->GetEntries(receiver_.BindNewPipeAndPassRemote());
}
@@ -52,7 +52,7 @@ ScriptPromise NativeFileSystemDirectoryIterator::next(
void NativeFileSystemDirectoryIterator::Trace(Visitor* visitor) {
ScriptWrappable::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
visitor->Trace(entries_);
visitor->Trace(pending_next_);
visitor->Trace(directory_);
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 34026cd8a19..00caa8967bc 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
@@ -9,7 +9,7 @@
#include "mojo/public/cpp/bindings/receiver.h"
#include "third_party/blink/public/mojom/native_file_system/native_file_system_directory_handle.mojom-blink.h"
#include "third_party/blink/public/mojom/native_file_system/native_file_system_error.mojom-blink.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
namespace blink {
@@ -21,7 +21,7 @@ class ScriptState;
class NativeFileSystemDirectoryIterator final
: public ScriptWrappable,
- public ContextLifecycleObserver,
+ public ExecutionContextClient,
public mojom::blink::NativeFileSystemDirectoryEntriesListener {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(NativeFileSystemDirectoryIterator);
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 369ebd2a907..cb6f5f13587 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
@@ -8,12 +8,14 @@
#include "third_party/blink/public/mojom/native_file_system/native_file_system_file_writer.mojom-blink.h"
#include "third_party/blink/public/mojom/native_file_system/native_file_system_transfer_token.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_file_system_create_writer_options.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/fileapi/file.h"
#include "third_party/blink/renderer/core/fileapi/file_error.h"
-#include "third_party/blink/renderer/modules/native_file_system/file_system_create_writer_options.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"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -65,16 +67,52 @@ ScriptPromise NativeFileSystemFileHandle::createWriter(
return result;
}
-ScriptPromise NativeFileSystemFileHandle::getFile(ScriptState* script_state) {
+ScriptPromise NativeFileSystemFileHandle::createWritable(
+ ScriptState* script_state,
+ const FileSystemCreateWriterOptions* options,
+ ExceptionState& exception_state) {
+ if (!mojo_ptr_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, "");
+ return ScriptPromise();
+ }
+
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise result = resolver->Promise();
+ mojo_ptr_->CreateFileWriter(
+ options->keepExistingData(),
+ WTF::Bind(
+ [](ScriptPromiseResolver* resolver,
+ mojom::blink::NativeFileSystemErrorPtr result,
+ mojo::PendingRemote<mojom::blink::NativeFileSystemFileWriter>
+ writer) {
+ ScriptState* script_state = resolver->GetScriptState();
+ if (!script_state)
+ return;
+ if (result->status != mojom::blink::NativeFileSystemStatus::kOk) {
+ native_file_system_error::Reject(resolver, *result);
+ return;
+ }
+
+ resolver->Resolve(NativeFileSystemWritableFileStream::Create(
+ script_state, std::move(writer)));
+ },
+ WrapPersistent(resolver)));
+
+ return result;
+}
+
+ScriptPromise NativeFileSystemFileHandle::getFile(
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
if (!mojo_ptr_) {
- resolver->Reject(MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError));
- return result;
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, "");
+ return ScriptPromise();
}
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ ScriptPromise result = resolver->Promise();
+
mojo_ptr_->AsBlob(WTF::Bind(
[](ScriptPromiseResolver* resolver, const String& name,
NativeFileSystemErrorPtr result, const base::File::Info& info,
@@ -99,7 +137,7 @@ NativeFileSystemFileHandle::Transfer() {
return result;
}
-void NativeFileSystemFileHandle::ContextDestroyed(ExecutionContext*) {
+void NativeFileSystemFileHandle::ContextDestroyed() {
mojo_ptr_.reset();
}
@@ -129,4 +167,20 @@ void NativeFileSystemFileHandle::RequestPermissionImpl(
mojo_ptr_->RequestPermission(writable, std::move(callback));
}
+void NativeFileSystemFileHandle::IsSameEntryImpl(
+ mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken> other,
+ base::OnceCallback<void(mojom::blink::NativeFileSystemErrorPtr, bool)>
+ callback) {
+ if (!mojo_ptr_) {
+ std::move(callback).Run(
+ mojom::blink::NativeFileSystemError::New(
+ mojom::blink::NativeFileSystemStatus::kInvalidState,
+ base::File::Error::FILE_ERROR_FAILED, "Context Destroyed"),
+ false);
+ return;
+ }
+
+ mojo_ptr_->IsSameEntry(std::move(other), std::move(callback));
+}
+
} // namespace blink
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 81686cd2490..e94321462ee 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
@@ -26,12 +26,15 @@ class NativeFileSystemFileHandle final : public NativeFileSystemHandle {
ScriptPromise createWriter(ScriptState*,
const FileSystemCreateWriterOptions* options);
- ScriptPromise getFile(ScriptState*);
+ ScriptPromise createWritable(ScriptState*,
+ const FileSystemCreateWriterOptions* options,
+ ExceptionState&);
+ ScriptPromise getFile(ScriptState*, ExceptionState&);
mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken> Transfer()
override;
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
mojom::blink::NativeFileSystemFileHandle* MojoHandle() {
return mojo_ptr_.get();
@@ -45,6 +48,10 @@ class NativeFileSystemFileHandle final : public NativeFileSystemHandle {
bool writable,
base::OnceCallback<void(mojom::blink::NativeFileSystemErrorPtr,
mojom::blink::PermissionStatus)>) override;
+ void IsSameEntryImpl(
+ mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken> other,
+ base::OnceCallback<void(mojom::blink::NativeFileSystemErrorPtr, bool)>)
+ override;
mojo::Remote<mojom::blink::NativeFileSystemFileHandle> mojo_ptr_;
};
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 634b1ecbe14..ba00937b314 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
@@ -7,9 +7,9 @@
#include "third_party/blink/public/mojom/native_file_system/native_file_system_error.mojom-blink.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_file_system_handle_permission_descriptor.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/modules/native_file_system/file_system_handle_permission_descriptor.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"
@@ -22,7 +22,7 @@ using mojom::blink::NativeFileSystemErrorPtr;
NativeFileSystemHandle::NativeFileSystemHandle(
ExecutionContext* execution_context,
const String& name)
- : ContextLifecycleObserver(execution_context), name_(name) {}
+ : ExecutionContextLifecycleObserver(execution_context), name_(name) {}
// static
NativeFileSystemHandle* NativeFileSystemHandle::CreateFromMojoEntry(
@@ -91,9 +91,30 @@ ScriptPromise NativeFileSystemHandle::requestPermission(
return result;
}
+ScriptPromise NativeFileSystemHandle::isSameEntry(
+ ScriptState* script_state,
+ NativeFileSystemHandle* other) {
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ ScriptPromise result = resolver->Promise();
+
+ IsSameEntryImpl(
+ other->Transfer(),
+ WTF::Bind(
+ [](ScriptPromiseResolver* resolver, NativeFileSystemErrorPtr result,
+ bool same) {
+ if (result->status != mojom::blink::NativeFileSystemStatus::kOk) {
+ native_file_system_error::Reject(resolver, *result);
+ return;
+ }
+ resolver->Resolve(same);
+ },
+ WrapPersistent(resolver)));
+ return result;
+}
+
void NativeFileSystemHandle::Trace(Visitor* visitor) {
ScriptWrappable::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 1491d217a5a..6fd78e3c148 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
@@ -11,7 +11,7 @@
#include "third_party/blink/public/mojom/native_file_system/native_file_system_transfer_token.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink-forward.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/heap/handle.h"
@@ -22,7 +22,7 @@ class ExecutionContext;
class FileSystemHandlePermissionDescriptor;
class NativeFileSystemHandle : public ScriptWrappable,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(NativeFileSystemHandle);
@@ -42,6 +42,8 @@ class NativeFileSystemHandle : public ScriptWrappable,
ScriptPromise requestPermission(ScriptState*,
const FileSystemHandlePermissionDescriptor*);
+ ScriptPromise isSameEntry(ScriptState*, NativeFileSystemHandle* other);
+
// Grab a handle to a transfer token. This may return an invalid PendingRemote
// if the context is already destroyed.
virtual mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken>
@@ -57,6 +59,10 @@ class NativeFileSystemHandle : public ScriptWrappable,
bool writable,
base::OnceCallback<void(mojom::blink::NativeFileSystemErrorPtr,
mojom::blink::PermissionStatus)>) = 0;
+ virtual void IsSameEntryImpl(
+ mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken> other,
+ base::OnceCallback<void(mojom::blink::NativeFileSystemErrorPtr,
+ bool)>) = 0;
String name_;
};
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
new file mode 100644
index 00000000000..9bf2a30c89c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_underlying_sink.cc
@@ -0,0 +1,274 @@
+// 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/native_file_system_underlying_sink.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/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_write_params.h"
+#include "third_party/blink/renderer/core/dom/dom_exception.h"
+#include "third_party/blink/renderer/core/fileapi/blob.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/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/blob/blob_data.h"
+
+namespace blink {
+
+NativeFileSystemUnderlyingSink::NativeFileSystemUnderlyingSink(
+ ExecutionContext* context,
+ mojo::PendingRemote<mojom::blink::NativeFileSystemFileWriter> writer_remote)
+ : ExecutionContextLifecycleObserver(context),
+ writer_remote_(std::move(writer_remote)) {
+ DCHECK(writer_remote_);
+}
+
+ScriptPromise NativeFileSystemUnderlyingSink::start(
+ ScriptState* script_state,
+ WritableStreamDefaultController* controller,
+ ExceptionState& exception_state) {
+ return ScriptPromise::CastUndefined(script_state);
+}
+
+ScriptPromise NativeFileSystemUnderlyingSink::write(
+ ScriptState* script_state,
+ ScriptValue chunk,
+ WritableStreamDefaultController* controller,
+ ExceptionState& exception_state) {
+ v8::Local<v8::Value> value = chunk.V8Value();
+
+ ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrWriteParams input;
+ V8ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrWriteParams::ToImpl(
+ script_state->GetIsolate(), value, input,
+ UnionTypeConversionMode::kNotNullable, exception_state);
+ if (exception_state.HadException())
+ return ScriptPromise();
+
+ if (input.IsNull()) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Cannot provide null object");
+ return ScriptPromise();
+ }
+
+ if (input.IsWriteParams()) {
+ return HandleParams(script_state, std::move(*input.GetAsWriteParams()),
+ exception_state);
+ }
+
+ ArrayBufferOrArrayBufferViewOrBlobOrUSVString write_data;
+ V8ArrayBufferOrArrayBufferViewOrBlobOrUSVString::ToImpl(
+ script_state->GetIsolate(), value, write_data,
+ UnionTypeConversionMode::kNotNullable, exception_state);
+ if (exception_state.HadException())
+ return ScriptPromise();
+ return WriteData(script_state, offset_, std::move(write_data),
+ exception_state);
+}
+
+ScriptPromise NativeFileSystemUnderlyingSink::close(
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
+ if (!writer_remote_ || pending_operation_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Object reached an invalid state");
+ return ScriptPromise();
+ }
+ pending_operation_ =
+ MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ ScriptPromise result = pending_operation_->Promise();
+ writer_remote_->Close(WTF::Bind(
+ &NativeFileSystemUnderlyingSink::CloseComplete, WrapPersistent(this)));
+
+ return result;
+}
+
+ScriptPromise NativeFileSystemUnderlyingSink::abort(
+ ScriptState* script_state,
+ ScriptValue reason,
+ ExceptionState& exception_state) {
+ // The specification guarantees that this will only be called after all
+ // pending writes have been aborted. Terminating the remote connection
+ // will ensure that the writes are not closed successfully.
+ if (writer_remote_)
+ writer_remote_.reset();
+ return ScriptPromise::CastUndefined(script_state);
+}
+
+ScriptPromise NativeFileSystemUnderlyingSink::HandleParams(
+ ScriptState* script_state,
+ const WriteParams& params,
+ ExceptionState& exception_state) {
+ if (params.type() == "truncate") {
+ if (!params.hasSize()) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kSyntaxError,
+ "Invalid params passed. truncate requires a size argument");
+ return ScriptPromise();
+ }
+ return Truncate(script_state, params.size(), exception_state);
+ }
+
+ if (params.type() == "seek") {
+ if (!params.hasPosition()) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kSyntaxError,
+ "Invalid params passed. seek requires a position argument");
+ return ScriptPromise();
+ }
+ return Seek(script_state, params.position(), exception_state);
+ }
+
+ if (params.type() == "write") {
+ uint64_t position = params.hasPosition() ? params.position() : offset_;
+ if (!params.hasData()) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kSyntaxError,
+ "Invalid params passed. write requires a data argument");
+ return ScriptPromise();
+ }
+ return WriteData(script_state, position, params.data(), exception_state);
+ }
+
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Object reached an invalid state");
+ return ScriptPromise();
+}
+
+ScriptPromise NativeFileSystemUnderlyingSink::WriteData(
+ 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 NativeFileSystemUnderlyingSink::WriteBlob(
+ ScriptState* script_state,
+ uint64_t position,
+ Blob* blob,
+ ExceptionState& exception_state) {
+ if (!writer_remote_ || pending_operation_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Object reached an invalid state");
+ return ScriptPromise();
+ }
+ pending_operation_ =
+ MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ ScriptPromise result = pending_operation_->Promise();
+ writer_remote_->Write(
+ position, blob->AsMojoBlob(),
+ WTF::Bind(&NativeFileSystemUnderlyingSink::WriteComplete,
+ WrapPersistent(this)));
+ return result;
+}
+
+ScriptPromise NativeFileSystemUnderlyingSink::Truncate(
+ ScriptState* script_state,
+ uint64_t size,
+ ExceptionState& exception_state) {
+ if (!writer_remote_ || pending_operation_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Object reached an invalid state");
+ return ScriptPromise();
+ }
+ pending_operation_ =
+ MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ ScriptPromise result = pending_operation_->Promise();
+ writer_remote_->Truncate(
+ size, WTF::Bind(&NativeFileSystemUnderlyingSink::TruncateComplete,
+ WrapPersistent(this), size));
+ return result;
+}
+
+ScriptPromise NativeFileSystemUnderlyingSink::Seek(
+ ScriptState* script_state,
+ uint64_t offset,
+ ExceptionState& exception_state) {
+ if (!writer_remote_ || pending_operation_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Object reached an invalid state");
+ return ScriptPromise();
+ }
+ offset_ = offset;
+ return ScriptPromise::CastUndefined(script_state);
+}
+
+void NativeFileSystemUnderlyingSink::WriteComplete(
+ mojom::blink::NativeFileSystemErrorPtr result,
+ uint64_t bytes_written) {
+ DCHECK(pending_operation_);
+ native_file_system_error::ResolveOrReject(pending_operation_, *result);
+ pending_operation_ = nullptr;
+
+ if (result->status == mojom::blink::NativeFileSystemStatus::kOk) {
+ // Advance offset.
+ offset_ += bytes_written;
+ }
+}
+
+void NativeFileSystemUnderlyingSink::TruncateComplete(
+ uint64_t to_size,
+ mojom::blink::NativeFileSystemErrorPtr result) {
+ DCHECK(pending_operation_);
+ native_file_system_error::ResolveOrReject(pending_operation_, *result);
+ pending_operation_ = nullptr;
+
+ if (result->status == mojom::blink::NativeFileSystemStatus::kOk) {
+ // Set offset to smallest last set size so that a subsequent write is not
+ // out of bounds.
+ offset_ = to_size < offset_ ? to_size : offset_;
+ }
+}
+
+void NativeFileSystemUnderlyingSink::CloseComplete(
+ mojom::blink::NativeFileSystemErrorPtr result) {
+ DCHECK(pending_operation_);
+ native_file_system_error::ResolveOrReject(pending_operation_, *result);
+ pending_operation_ = nullptr;
+ // We close the mojo pipe because we intend this writable file stream to be
+ // discarded after close. Subsequent operations will fail.
+ writer_remote_.reset();
+}
+
+void NativeFileSystemUnderlyingSink::Trace(Visitor* visitor) {
+ ScriptWrappable::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
+ UnderlyingSinkBase::Trace(visitor);
+ visitor->Trace(pending_operation_);
+}
+
+void NativeFileSystemUnderlyingSink::ContextDestroyed() {
+ writer_remote_.reset();
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..f1cdd64d544
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_underlying_sink.h
@@ -0,0 +1,74 @@
+// 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_NATIVE_FILE_SYSTEM_UNDERLYING_SINK_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_NATIVE_FILE_SYSTEM_UNDERLYING_SINK_H_
+
+#include "mojo/public/cpp/bindings/remote.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_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/streams/underlying_sink_base.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+
+namespace blink {
+
+class ExceptionState;
+class ScriptPromiseResolver;
+class WriteParams;
+
+class NativeFileSystemUnderlyingSink final
+ : public UnderlyingSinkBase,
+ public ExecutionContextLifecycleObserver {
+ USING_GARBAGE_COLLECTED_MIXIN(NativeFileSystemUnderlyingSink);
+
+ public:
+ explicit NativeFileSystemUnderlyingSink(
+ ExecutionContext*,
+ mojo::PendingRemote<mojom::blink::NativeFileSystemFileWriter>);
+
+ // UnderlyingSinkBase
+ ScriptPromise start(ScriptState*,
+ WritableStreamDefaultController*,
+ ExceptionState&) override;
+ ScriptPromise write(ScriptState*,
+ ScriptValue chunk,
+ WritableStreamDefaultController*,
+ ExceptionState&) override;
+ ScriptPromise close(ScriptState*, ExceptionState&) override;
+ ScriptPromise abort(ScriptState*,
+ ScriptValue reason,
+ ExceptionState&) override;
+
+ void Trace(Visitor*) override;
+ void ContextDestroyed() override;
+
+ private:
+ ScriptPromise HandleParams(ScriptState*, const WriteParams&, ExceptionState&);
+ ScriptPromise WriteData(
+ ScriptState*,
+ uint64_t position,
+ const ArrayBufferOrArrayBufferViewOrBlobOrUSVString& data,
+ ExceptionState&);
+ ScriptPromise WriteBlob(ScriptState*,
+ uint64_t position,
+ Blob*,
+ ExceptionState&);
+ ScriptPromise Truncate(ScriptState*, uint64_t size, ExceptionState&);
+ ScriptPromise Seek(ScriptState*, uint64_t offset, ExceptionState&);
+ void WriteComplete(mojom::blink::NativeFileSystemErrorPtr result,
+ uint64_t bytes_written);
+ void TruncateComplete(uint64_t to_size,
+ mojom::blink::NativeFileSystemErrorPtr result);
+ void CloseComplete(mojom::blink::NativeFileSystemErrorPtr result);
+
+ mojo::Remote<mojom::blink::NativeFileSystemFileWriter> writer_remote_;
+
+ uint64_t offset_ = 0;
+ Member<ScriptPromiseResolver> pending_operation_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_NATIVE_FILE_SYSTEM_UNDERLYING_SINK_H_
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
new file mode 100644
index 00000000000..9eb16481ea4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writable_file_stream.cc
@@ -0,0 +1,131 @@
+// 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/native_file_system_writable_file_stream.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_queuing_strategy_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_write_params.h"
+#include "third_party/blink/renderer/core/streams/count_queuing_strategy.h"
+#include "third_party/blink/renderer/core/streams/writable_stream_default_controller.h"
+#include "third_party/blink/renderer/core/streams/writable_stream_default_writer.h"
+#include "third_party/blink/renderer/modules/native_file_system/native_file_system_underlying_sink.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
+
+namespace blink {
+
+NativeFileSystemWritableFileStream* NativeFileSystemWritableFileStream::Create(
+ ScriptState* script_state,
+ mojo::PendingRemote<mojom::blink::NativeFileSystemFileWriter>
+ writer_pending_remote) {
+ DCHECK(writer_pending_remote);
+ ScriptState::Scope scope(script_state);
+
+ ExecutionContext* context = ExecutionContext::From(script_state);
+
+ auto* stream = MakeGarbageCollected<NativeFileSystemWritableFileStream>();
+
+ auto* underlying_sink = MakeGarbageCollected<NativeFileSystemUnderlyingSink>(
+ context, std::move(writer_pending_remote));
+ stream->underlying_sink_ = underlying_sink;
+ auto underlying_sink_value = ScriptValue::From(script_state, underlying_sink);
+
+ auto* init = QueuingStrategyInit::Create();
+ // HighWaterMark set to 1 here. This allows the stream to appear available
+ // without adding additional buffering.
+ init->setHighWaterMark(
+ ScriptValue::From(script_state, static_cast<double>(1)));
+ auto* strategy = CountQueuingStrategy::Create(script_state, init);
+ ScriptValue strategy_value = ScriptValue::From(script_state, strategy);
+
+ ExceptionState exception_state(script_state->GetIsolate(),
+ ExceptionState::kConstructionContext,
+ "NativeFileSystemWritableFileStream");
+ stream->InitInternal(script_state, underlying_sink_value, strategy_value,
+ exception_state);
+
+ if (exception_state.HadException())
+ return nullptr;
+
+ return stream;
+}
+
+ScriptPromise NativeFileSystemWritableFileStream::write(
+ ScriptState* script_state,
+ const ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrWriteParams& data,
+ ExceptionState& exception_state) {
+ WritableStreamDefaultWriter* writer =
+ WritableStream::AcquireDefaultWriter(script_state, this, exception_state);
+ if (exception_state.HadException())
+ return ScriptPromise();
+
+ ScriptPromise promise = writer->write(
+ script_state, ScriptValue::From(script_state, data), exception_state);
+
+ WritableStreamDefaultWriter::Release(script_state, writer);
+ return promise;
+}
+
+ScriptPromise NativeFileSystemWritableFileStream::truncate(
+ ScriptState* script_state,
+ uint64_t size,
+ ExceptionState& exception_state) {
+ WritableStreamDefaultWriter* writer =
+ WritableStream::AcquireDefaultWriter(script_state, this, exception_state);
+ if (exception_state.HadException())
+ return ScriptPromise();
+
+ auto* options = WriteParams::Create();
+ options->setType("truncate");
+ options->setSize(size);
+
+ ScriptPromise promise = writer->write(
+ script_state, ScriptValue::From(script_state, options), exception_state);
+
+ WritableStreamDefaultWriter::Release(script_state, writer);
+ return promise;
+}
+
+ScriptPromise NativeFileSystemWritableFileStream::close(
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
+ WritableStreamDefaultWriter* writer =
+ WritableStream::AcquireDefaultWriter(script_state, this, exception_state);
+ if (exception_state.HadException())
+ return ScriptPromise();
+
+ ScriptPromise promise = writer->close(script_state, exception_state);
+
+ WritableStreamDefaultWriter::Release(script_state, writer);
+ return promise;
+}
+
+ScriptPromise NativeFileSystemWritableFileStream::seek(
+ ScriptState* script_state,
+ uint64_t offset,
+ ExceptionState& exception_state) {
+ WritableStreamDefaultWriter* writer =
+ WritableStream::AcquireDefaultWriter(script_state, this, exception_state);
+ if (exception_state.HadException())
+ return ScriptPromise();
+
+ auto* options = WriteParams::Create();
+ options->setType("seek");
+ options->setPosition(offset);
+
+ ScriptPromise promise = writer->write(
+ script_state, ScriptValue::From(script_state, options), exception_state);
+
+ WritableStreamDefaultWriter::Release(script_state, writer);
+ return promise;
+}
+
+void NativeFileSystemWritableFileStream::Trace(Visitor* visitor) {
+ WritableStream::Trace(visitor);
+ visitor->Trace(underlying_sink_);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..3eb79e89f89
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writable_file_stream.h
@@ -0,0 +1,46 @@
+// 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_NATIVE_FILE_SYSTEM_WRITABLE_FILE_STREAM_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_NATIVE_FILE_SYSTEM_WRITABLE_FILE_STREAM_H_
+
+#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/blink/public/mojom/native_file_system/native_file_system_error.mojom-blink.h"
+#include "third_party/blink/public/mojom/native_file_system/native_file_system_file_writer.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/modules/v8/array_buffer_or_array_buffer_view_or_blob_or_usv_string_or_write_params.h"
+#include "third_party/blink/renderer/core/streams/writable_stream.h"
+#include "third_party/blink/renderer/core/streams/writable_stream_default_writer.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+
+namespace blink {
+
+class ScriptPromise;
+class ScriptState;
+class NativeFileSystemUnderlyingSink;
+
+class NativeFileSystemWritableFileStream final : public WritableStream {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static NativeFileSystemWritableFileStream* Create(
+ ScriptState*,
+ mojo::PendingRemote<mojom::blink::NativeFileSystemFileWriter>);
+
+ void Trace(Visitor* visitor) override;
+
+ // IDL defined functions specific to NativeFileSystemWritableFileStream.
+ ScriptPromise write(
+ ScriptState*,
+ const ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrWriteParams& data,
+ ExceptionState&);
+ ScriptPromise truncate(ScriptState*, uint64_t size, ExceptionState&);
+ ScriptPromise close(ScriptState*, ExceptionState&);
+ ScriptPromise seek(ScriptState*, uint64_t offset, ExceptionState&);
+
+ private:
+ Member<NativeFileSystemUnderlyingSink> underlying_sink_;
+};
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_NATIVE_FILE_SYSTEM_WRITABLE_FILE_STREAM_H_
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
index 9ceb62bc70c..85b7ad88a66 100644
--- 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
@@ -30,7 +30,7 @@ NativeFileSystemWriter::NativeFileSystemWriter(
ExecutionContext* context,
mojo::PendingRemote<mojom::blink::NativeFileSystemFileWriter>
writer_pending_remote)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
writer_remote_(std::move(writer_pending_remote)) {
DCHECK(writer_remote_);
}
@@ -51,7 +51,7 @@ ScriptPromise NativeFileSystemWriter::write(
} else if (data.IsArrayBufferView()) {
DOMArrayBufferView* array_buffer_view = data.GetAsArrayBufferView().View();
blob_data->AppendBytes(array_buffer_view->BaseAddress(),
- array_buffer_view->deprecatedByteLengthAsUnsigned());
+ array_buffer_view->byteLengthAsSizeT());
} else if (data.IsBlob()) {
blob = data.GetAsBlob();
} else if (data.IsUSVString()) {
@@ -66,16 +66,17 @@ ScriptPromise NativeFileSystemWriter::write(
BlobDataHandle::Create(std::move(blob_data), size));
}
- return WriteBlob(script_state, position, blob);
+ return WriteBlob(script_state, position, blob, exception_state);
}
-ScriptPromise NativeFileSystemWriter::WriteBlob(ScriptState* script_state,
- uint64_t position,
- Blob* blob) {
+ScriptPromise NativeFileSystemWriter::WriteBlob(
+ ScriptState* script_state,
+ uint64_t position,
+ Blob* blob,
+ ExceptionState& exception_state) {
if (!writer_remote_ || pending_operation_) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, "");
+ return ScriptPromise();
}
pending_operation_ =
MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -178,9 +179,8 @@ ScriptPromise NativeFileSystemWriter::WriteStream(
ReadableStream* stream,
ExceptionState& exception_state) {
if (!writer_remote_ || pending_operation_) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, "");
+ return ScriptPromise();
}
DCHECK(!stream_loader_);
@@ -203,12 +203,13 @@ ScriptPromise NativeFileSystemWriter::WriteStream(
return result;
}
-ScriptPromise NativeFileSystemWriter::truncate(ScriptState* script_state,
- uint64_t size) {
+ScriptPromise NativeFileSystemWriter::truncate(
+ ScriptState* script_state,
+ uint64_t size,
+ ExceptionState& exception_state) {
if (!writer_remote_ || pending_operation_) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, "");
+ return ScriptPromise();
}
pending_operation_ =
MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -219,11 +220,11 @@ ScriptPromise NativeFileSystemWriter::truncate(ScriptState* script_state,
return result;
}
-ScriptPromise NativeFileSystemWriter::close(ScriptState* script_state) {
+ScriptPromise NativeFileSystemWriter::close(ScriptState* script_state,
+ ExceptionState& exception_state) {
if (!writer_remote_ || pending_operation_) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, "");
+ return ScriptPromise();
}
pending_operation_ =
MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -236,7 +237,7 @@ ScriptPromise NativeFileSystemWriter::close(ScriptState* script_state) {
void NativeFileSystemWriter::Trace(Visitor* visitor) {
ScriptWrappable::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
visitor->Trace(file_);
visitor->Trace(pending_operation_);
visitor->Trace(stream_loader_);
@@ -268,7 +269,7 @@ void NativeFileSystemWriter::CloseComplete(
writer_remote_.reset();
}
-void NativeFileSystemWriter::ContextDestroyed(ExecutionContext*) {
+void NativeFileSystemWriter::ContextDestroyed() {
writer_remote_.reset();
}
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
index f7de9e038ad..e78c237f524 100644
--- 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
@@ -9,7 +9,7 @@
#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/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
namespace blink {
@@ -24,7 +24,7 @@ class ScriptState;
class NativeFileSystemFileHandle;
class NativeFileSystemWriter final : public ScriptWrappable,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(NativeFileSystemWriter);
@@ -37,16 +37,19 @@ class NativeFileSystemWriter final : public ScriptWrappable,
uint64_t position,
const ArrayBufferOrArrayBufferViewOrBlobOrUSVString& data,
ExceptionState&);
- ScriptPromise truncate(ScriptState*, uint64_t size);
- ScriptPromise close(ScriptState*);
+ ScriptPromise truncate(ScriptState*, uint64_t size, ExceptionState&);
+ ScriptPromise close(ScriptState*, ExceptionState&);
void Trace(Visitor*) override;
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
private:
class StreamWriterClient;
- ScriptPromise WriteBlob(ScriptState*, uint64_t position, Blob*);
+ ScriptPromise WriteBlob(ScriptState*,
+ uint64_t position,
+ Blob*,
+ ExceptionState&);
ScriptPromise WriteStream(ScriptState*,
uint64_t position,
ReadableStream* stream,
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
index b45f3c07d5d..e0fe751b8a1 100644
--- 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
@@ -10,16 +10,17 @@
#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/choose_file_system_entries_options.h"
-#include "third_party/blink/renderer/modules/native_file_system/choose_file_system_entries_options_accepts.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"
@@ -29,14 +30,14 @@ namespace {
mojom::blink::ChooseFileSystemEntryType ConvertChooserType(const String& input,
bool multiple) {
- if (input == "openFile") {
+ if (input == "open-file" || input == "openFile") {
return multiple
? mojom::blink::ChooseFileSystemEntryType::kOpenMultipleFiles
: mojom::blink::ChooseFileSystemEntryType::kOpenFile;
}
- if (input == "saveFile")
+ if (input == "save-file" || input == "saveFile")
return mojom::blink::ChooseFileSystemEntryType::kSaveFile;
- if (input == "openDirectory")
+ if (input == "open-directory" || input == "openDirectory")
return mojom::blink::ChooseFileSystemEntryType::kOpenDirectory;
NOTREACHED();
return mojom::blink::ChooseFileSystemEntryType::kOpenFile;
@@ -62,51 +63,42 @@ Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> ConvertAccepts(
ScriptPromise WindowNativeFileSystem::chooseFileSystemEntries(
ScriptState* script_state,
LocalDOMWindow& window,
- const ChooseFileSystemEntriesOptions* options) {
+ const ChooseFileSystemEntriesOptions* options,
+ ExceptionState& exception_state) {
if (!window.IsCurrentlyDisplayedInFrame()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError));
+ exception_state.ThrowDOMException(DOMExceptionCode::kAbortError, "");
+ return ScriptPromise();
}
Document* document = window.document();
if (!document) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError));
+ exception_state.ThrowDOMException(DOMExceptionCode::kAbortError, "");
+ return ScriptPromise();
}
if (!document->GetSecurityOrigin()->CanAccessNativeFileSystem()) {
- if (document->IsSandboxed(WebSandboxFlags::kOrigin)) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kSecurityError,
- "Sandboxed documents aren't allowed to show a file picker."));
+ if (document->IsSandboxed(mojom::blink::WebSandboxFlags::kOrigin)) {
+ exception_state.ThrowSecurityError(
+ "Sandboxed documents aren't allowed to show a file picker.");
+ return ScriptPromise();
} else {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kSecurityError,
- "This document isn't allowed to show a file picker."));
+ 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->IsCrossOriginSubframe()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kSecurityError,
- "Cross origin sub frames aren't allowed to show a file picker."));
+ 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)) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kSecurityError,
- "Must be handling a user gesture to show a file picker."));
+ exception_state.ThrowSecurityError(
+ "Must be handling a user gesture to show a file picker.");
+ return ScriptPromise();
}
Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> accepts;
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
index c72d8e3a486..8f4926ab0d6 100644
--- 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
@@ -11,6 +11,7 @@
namespace blink {
class ChooseFileSystemEntriesOptions;
+class ExceptionState;
class LocalDOMWindow;
class ScriptPromise;
class ScriptState;
@@ -22,7 +23,8 @@ class WindowNativeFileSystem {
static ScriptPromise chooseFileSystemEntries(
ScriptState*,
LocalDOMWindow&,
- const ChooseFileSystemEntriesOptions*);
+ const ChooseFileSystemEntriesOptions*,
+ ExceptionState&);
};
} // namespace blink
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 e2b338df606..fae73c8984d 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
@@ -8,7 +8,7 @@
RuntimeEnabled=NativeFileSystem,
ImplementedAs=WindowNativeFileSystem
] partial interface Window {
- [CallWith=ScriptState, Measure]
+ [CallWith=ScriptState, Measure, RaisesException]
Promise<(FileSystemHandle or sequence<FileSystemHandle>)>
- chooseFileSystemEntries(optional ChooseFileSystemEntriesOptions options);
+ chooseFileSystemEntries(optional ChooseFileSystemEntriesOptions options = {});
};
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/window_native_file_system_test.cc
index fd589b2fcbd..476b6549e17 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/window_native_file_system_test.cc
@@ -118,7 +118,7 @@ class WindowNativeFileSystemTest : public PageTestBase {
TEST_F(WindowNativeFileSystemTest, UserActivationRequiredOtherwiseDenied) {
LocalFrame* frame = &GetFrame();
- EXPECT_FALSE(frame->HasBeenActivated());
+ EXPECT_FALSE(frame->HasStickyUserActivation());
MockNativeFileSystemManager manager(frame->GetBrowserInterfaceBroker());
manager.SetChooseEntriesResponse(WTF::Bind(
@@ -126,17 +126,17 @@ TEST_F(WindowNativeFileSystemTest, UserActivationRequiredOtherwiseDenied) {
FAIL();
}));
GetFrame().GetScriptController().ExecuteScriptInMainWorld(
- "window.chooseFileSystemEntries({type: 'openFile'});");
+ "window.chooseFileSystemEntries({type: 'open-file'});");
base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(frame->HasBeenActivated());
+ EXPECT_FALSE(frame->HasStickyUserActivation());
}
TEST_F(WindowNativeFileSystemTest, UserActivationChooseEntriesSuccessful) {
LocalFrame* frame = &GetFrame();
- EXPECT_FALSE(frame->HasBeenActivated());
+ EXPECT_FALSE(frame->HasStickyUserActivation());
LocalFrame::NotifyUserActivation(frame);
- EXPECT_TRUE(frame->HasBeenActivated());
+ EXPECT_TRUE(frame->HasStickyUserActivation());
base::RunLoop manager_run_loop;
MockNativeFileSystemManager manager(frame->GetBrowserInterfaceBroker(),
@@ -160,23 +160,23 @@ TEST_F(WindowNativeFileSystemTest, UserActivationChooseEntriesSuccessful) {
std::move(callback).Run(std::move(error), std::move(entries));
}));
GetFrame().GetScriptController().ExecuteScriptInMainWorld(
- "window.chooseFileSystemEntries({type: 'openFile'});");
+ "window.chooseFileSystemEntries({type: 'open-file'});");
manager_run_loop.Run();
// Mock Manager finished sending data over the mojo pipe.
// Clearing the user activation.
- frame->ClearActivation();
- EXPECT_FALSE(frame->HasBeenActivated());
+ frame->ClearUserActivation();
+ EXPECT_FALSE(frame->HasStickyUserActivation());
// Let blink-side receiver process the response and set the user activation
// again.
base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(frame->HasBeenActivated());
+ EXPECT_TRUE(frame->HasStickyUserActivation());
}
TEST_F(WindowNativeFileSystemTest, UserActivationChooseEntriesErrors) {
LocalFrame* frame = &GetFrame();
- EXPECT_FALSE(frame->HasBeenActivated());
+ EXPECT_FALSE(frame->HasStickyUserActivation());
using mojom::blink::NativeFileSystemStatus;
@@ -192,7 +192,7 @@ TEST_F(WindowNativeFileSystemTest, UserActivationChooseEntriesErrors) {
for (const NativeFileSystemStatus& status : statuses) {
LocalFrame::NotifyUserActivation(frame);
- EXPECT_TRUE(frame->HasBeenActivated());
+ EXPECT_TRUE(frame->HasStickyUserActivation());
base::RunLoop manager_run_loop;
manager.SetQuitClosure(manager_run_loop.QuitClosure());
@@ -208,16 +208,16 @@ TEST_F(WindowNativeFileSystemTest, UserActivationChooseEntriesErrors) {
},
status));
GetFrame().GetScriptController().ExecuteScriptInMainWorld(
- "window.chooseFileSystemEntries({type: 'openFile'});");
+ "window.chooseFileSystemEntries({type: 'open-file'});");
manager_run_loop.Run();
// Mock Manager finished sending data over the mojo pipe.
// Clearing the user activation.
- frame->ClearActivation();
- EXPECT_FALSE(frame->HasBeenActivated());
+ frame->ClearUserActivation();
+ EXPECT_FALSE(frame->HasStickyUserActivation());
base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(frame->HasBeenActivated());
+ EXPECT_FALSE(frame->HasStickyUserActivation());
}
}
diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/write_params.idl b/chromium/third_party/blink/renderer/modules/native_file_system/write_params.idl
new file mode 100644
index 00000000000..9e6a39c7f52
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_file_system/write_params.idl
@@ -0,0 +1,18 @@
+// 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/#enumdef-writecommandtype
+enum WriteCommandType {
+ "truncate",
+ "seek",
+ "write",
+};
+
+// https://wicg.github.io/native-file-system/#dictdef-writeparams
+dictionary WriteParams {
+ required WriteCommandType type;
+ unsigned long long? size;
+ unsigned long long? position;
+ (BufferSource or Blob or USVString)? data;
+};
diff --git a/chromium/third_party/blink/renderer/modules/native_io/BUILD.gn b/chromium/third_party/blink/renderer/modules/native_io/BUILD.gn
new file mode 100644
index 00000000000..61ed8d843f9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_io/BUILD.gn
@@ -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.
+
+import("//third_party/blink/renderer/modules/modules.gni")
+
+blink_modules_sources("native_io") {
+ sources = [
+ "global_native_io.cc",
+ "global_native_io.h",
+ "native_io_file.cc",
+ "native_io_file.h",
+ "native_io_file_sync.cc",
+ "native_io_file_sync.h",
+ "native_io_manager.cc",
+ "native_io_manager.h",
+ ]
+
+ deps = [ "//third_party/blink/renderer/platform" ]
+}
diff --git a/chromium/third_party/blink/renderer/modules/native_io/DEPS b/chromium/third_party/blink/renderer/modules/native_io/DEPS
new file mode 100644
index 00000000000..8c20ba39153
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_io/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+base/files/file.h",
+]
diff --git a/chromium/third_party/blink/renderer/modules/native_io/OWNERS b/chromium/third_party/blink/renderer/modules/native_io/OWNERS
new file mode 100644
index 00000000000..271647c4a24
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_io/OWNERS
@@ -0,0 +1,4 @@
+file://content/browser/native_io/OWNERS
+
+# TEAM: storage-dev@chromium.org
+# COMPONENT: Blink>Storage>NativeIO
diff --git a/chromium/third_party/blink/renderer/modules/native_io/README.md b/chromium/third_party/blink/renderer/modules/native_io/README.md
new file mode 100644
index 00000000000..89abc128180
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_io/README.md
@@ -0,0 +1,59 @@
+# NativeIO
+
+[NativeIO](https://github.com/fivedots/nativeio-explainer) is a proposal for
+a low-level storage mechanism that will open a path for developers to use
+their favorite database in their web applications. This API is expected to be
+used heavily from WebAssembly, and the most popular ported database is
+expected to be SQLite.
+
+Most of the Blink implementation should be unsurprising, given the WebIDL for
+the feature. This README goes over the parts that may be surprising to a storage
+engineer.
+
+## Synchronous storage APIs
+
+The current prototype implements both synchronous and asynchronous versions of
+NativeIO. This allows us to collaborate with web developers to understand the
+overhead of an asynchronous API, compared to the fastest synchronous API we
+could possibly build.
+
+The synchronous API is limited to dedicated workers.
+
+## SharedArrayBuffer
+
+The current NativeIO design assumes that allocating and copying memory buffers
+will result in significant overhead. To test this hypothesis, the prototype
+includes zero-copy APIs, where the caller passes in a view into a caller-owned
+I/O buffer.
+
+This approach introduces an interesting design challenge for the asynchronous
+API, because the web application can run code that interacts with the I/O buffer
+while the operation is in progress, and observe side-effects. For example, the
+application can read the buffer in a tight loop, and observe how the OS is
+filling it with data from disk.
+
+The current prototype requires that I/O buffers passed to the asynchronous API
+are backed by SharedArrayBuffers, because these are intended to be modified by
+multiple threads at the same time.
+
+This aspect of the prototype is fairly unstable. Benchmarking may reveal that
+we don't need zero-copy, and WebAssembly interfacing concerns may nudge us
+towards a different design.
+
+# Locking
+
+The current prototype enforces that there is at most one open handle to a
+NativeIO file. In other words, opening a file only succeeds if it can get an
+exclusive lock on the file, and closing the file releases the lock.
+
+This approach is different from other storage APIs, which wait until they can
+grab a lock. The main reason for the difference is this is the first API built
+after
+[Web Locks](https://developer.mozilla.org/en-US/docs/Web/API/Web_Locks_API), so
+we can ask developers to take advantage of Web Locks instead of building a lock
+manager with associated tests into each new storage API.
+
+The main reason for enforcing locking early in the API design is to avoid
+exposing the details of OS-level file descriptor sharing to the Web Platform.
+This aspect of the prototype may also change, based on research and developer
+feedback.
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
new file mode 100644
index 00000000000..59d95769add
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_io/global_native_io.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/modules/native_io/global_native_io.h"
+
+#include <utility>
+
+#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
+#include "third_party/blink/public/mojom/native_io/native_io.mojom-blink.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/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_io/native_io_manager.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/supplementable.h"
+
+namespace blink {
+
+namespace {
+
+template <typename T>
+class GlobalNativeIOImpl final : public GarbageCollected<GlobalNativeIOImpl<T>>,
+ public Supplement<T> {
+ USING_GARBAGE_COLLECTED_MIXIN(GlobalNativeIOImpl);
+
+ public:
+ static const char kSupplementName[];
+
+ static GlobalNativeIOImpl& From(T& supplementable) {
+ GlobalNativeIOImpl* supplement =
+ Supplement<T>::template From<GlobalNativeIOImpl>(supplementable);
+ if (!supplement) {
+ supplement = MakeGarbageCollected<GlobalNativeIOImpl>(supplementable);
+ Supplement<T>::ProvideTo(supplementable, supplement);
+ }
+ return *supplement;
+ }
+
+ explicit GlobalNativeIOImpl(T& supplementable)
+ : Supplement<T>(supplementable) {}
+
+ NativeIOManager* GetNativeIOManager(T& scope) {
+ if (!native_io_manager_) {
+ ExecutionContext* execution_context = scope.GetExecutionContext();
+ if (&execution_context->GetBrowserInterfaceBroker() ==
+ &GetEmptyBrowserInterfaceBroker()) {
+ return nullptr;
+ }
+
+ mojo::Remote<mojom::blink::NativeIOHost> backend;
+ execution_context->GetBrowserInterfaceBroker().GetInterface(
+ backend.BindNewPipeAndPassReceiver(
+ execution_context->GetTaskRunner(TaskType::kMiscPlatformAPI)));
+ native_io_manager_ = MakeGarbageCollected<NativeIOManager>(
+ execution_context, std::move(backend));
+ }
+ return native_io_manager_;
+ }
+
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(native_io_manager_);
+ Supplement<T>::Trace(visitor);
+ }
+
+ private:
+ Member<NativeIOManager> native_io_manager_;
+};
+
+// static
+template <typename T>
+const char GlobalNativeIOImpl<T>::kSupplementName[] = "GlobalNativeIOImpl";
+
+} // namespace
+
+// static
+NativeIOManager* GlobalNativeIO::nativeIO(LocalDOMWindow& window) {
+ return GlobalNativeIOImpl<LocalDOMWindow>::From(window).GetNativeIOManager(
+ window);
+}
+
+// static
+NativeIOManager* GlobalNativeIO::nativeIO(WorkerGlobalScope& worker) {
+ return GlobalNativeIOImpl<WorkerGlobalScope>::From(worker).GetNativeIOManager(
+ worker);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/native_io/global_native_io.h b/chromium/third_party/blink/renderer/modules/native_io/global_native_io.h
new file mode 100644
index 00000000000..bb9b05b9399
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_io/global_native_io.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_IO_GLOBAL_NATIVE_IO_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_IO_GLOBAL_NATIVE_IO_H_
+
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+
+namespace blink {
+
+class LocalDOMWindow;
+class NativeIOManager;
+class WorkerGlobalScope;
+
+// The "nativeIO" attribute on the Window global and Worker global scope.
+class GlobalNativeIO {
+ STATIC_ONLY(GlobalNativeIO);
+
+ public:
+ static NativeIOManager* nativeIO(LocalDOMWindow&);
+ static NativeIOManager* nativeIO(WorkerGlobalScope&);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_IO_GLOBAL_NATIVE_IO_H_
diff --git a/chromium/third_party/blink/renderer/modules/native_io/idls.gni b/chromium/third_party/blink/renderer/modules/native_io/idls.gni
new file mode 100644
index 00000000000..694bfa928fd
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_io/idls.gni
@@ -0,0 +1,14 @@
+# 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 = [
+ "native_io_file.idl",
+ "native_io_file_sync.idl",
+ "native_io_manager.idl",
+]
+
+modules_dependency_idl_files = [
+ "window_native_io.idl",
+ "worker_global_scope_native_io.idl",
+]
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
new file mode 100644
index 00000000000..465f519e77f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_io/native_io_file.cc
@@ -0,0 +1,403 @@
+// 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/native_io/native_io_file.h"
+
+#include <utility>
+
+#include "base/files/file.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/numerics/safe_conversions.h"
+#include "base/sequenced_task_runner.h"
+#include "base/task/thread_pool.h"
+#include "third_party/blink/public/platform/task_type.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/core/dom/dom_exception.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h"
+#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
+#include "third_party/blink/renderer/platform/bindings/exception_code.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/heap/heap.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
+#include "third_party/blink/renderer/platform/scheduler/public/worker_pool.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/threading_primitives.h"
+#include "third_party/blink/renderer/platform/wtf/wtf.h"
+
+namespace blink {
+
+namespace {
+
+// Extracts the read/write operation size from the buffer size.
+int OperationSize(const DOMArrayBufferView& buffer) {
+ // On 32-bit platforms, clamp operation sizes to 2^31-1.
+ return base::saturated_cast<int>(buffer.byteLengthAsSizeT());
+}
+
+} // namespace
+
+struct NativeIOFile::FileState {
+ explicit FileState(base::File file) : file(std::move(file)) {}
+
+ FileState(const FileState&) = delete;
+ FileState& operator=(const FileState&) = delete;
+
+ ~FileState() = default;
+
+ // Lock coordinating cross-thread access to the state.
+ WTF::Mutex mutex;
+ // The file on disk backing this NativeIOFile.
+ base::File file GUARDED_BY(mutex);
+};
+
+NativeIOFile::NativeIOFile(
+ base::File backing_file,
+ mojo::Remote<mojom::blink::NativeIOFileHost> backend_file,
+ ExecutionContext* execution_context)
+ : ExecutionContextLifecycleObserver(execution_context),
+ file_state_(std::make_unique<FileState>(std::move(backing_file))),
+ // TODO(pwnall): Get a dedicated queue when the specification matures.
+ resolver_task_runner_(
+ execution_context->GetTaskRunner(TaskType::kMiscPlatformAPI)),
+ backend_file_(std::move(backend_file)) {
+ backend_file_.set_disconnect_handler(
+ WTF::Bind(&NativeIOFile::OnBackendDisconnect, WrapWeakPersistent(this)));
+}
+
+NativeIOFile::~NativeIOFile() {
+ // Needed to avoid having the base::File destructor close the file descriptor
+ // synchronously on the main thread.
+ CloseBackingFile();
+}
+
+ScriptPromise NativeIOFile::close(ScriptState* script_state) {
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+
+ if (closed_) {
+ // close() is idempotent.
+ resolver->Resolve();
+ return resolver->Promise();
+ }
+
+ closed_ = true;
+
+ DCHECK(!queued_close_resolver_) << "Close logic kicked off twice";
+ queued_close_resolver_ = resolver;
+
+ if (!io_pending_) {
+ // Pretend that a close() promise was queued behind an I/O operation, and
+ // the operation just finished. This is less logic than handling the
+ // non-queued case separately.
+ DispatchQueuedClose();
+ }
+
+ return resolver->Promise();
+}
+
+ScriptPromise NativeIOFile::read(ScriptState* script_state,
+ MaybeShared<DOMArrayBufferView> buffer,
+ uint64_t file_offset,
+ ExceptionState& exception_state) {
+ if (!buffer.View()->IsShared()) {
+ exception_state.ThrowTypeError(
+ "The I/O buffer must be backed by a SharedArrayBuffer");
+ return ScriptPromise();
+ }
+
+ if (io_pending_) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "Another I/O operation is in progress on the same file");
+ return ScriptPromise();
+ }
+ if (closed_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "The file was already closed");
+ return ScriptPromise();
+ }
+ io_pending_ = true;
+
+ int read_size = OperationSize(*buffer.View());
+ char* read_buffer =
+ static_cast<char*>(buffer.View()->BaseAddressMaybeShared());
+ DOMSharedArrayBuffer* read_buffer_keepalive = buffer.View()->BufferShared();
+
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ // The first CrossThreadUnretained() is safe here because the
+ // NativeIOFile::FileState instance is owned by this NativeIOFile, which is
+ // also passed to the task via WrapCrossThreadPersistent. Therefore, the
+ // FileState instance is guaranteed to remain alive during the task's
+ // execution.
+ //
+ // The second CrossThreadUnretained() is safe here because the read buffer is
+ // backed by a DOMSharedArrayBuffer that is also passed to the task via
+ // WrapCrossThreadPersistent. Therefore, the buffer is guaranteed to remain
+ // alive during the task's execution.
+ worker_pool::PostTask(
+ FROM_HERE, {base::MayBlock(), base::ThreadPool()},
+ CrossThreadBindOnce(
+ &DoRead, WrapCrossThreadPersistent(this),
+ WrapCrossThreadPersistent(resolver),
+ WrapCrossThreadPersistent(read_buffer_keepalive),
+ CrossThreadUnretained(file_state_.get()), resolver_task_runner_,
+ CrossThreadUnretained(read_buffer), file_offset, read_size));
+ return resolver->Promise();
+}
+
+ScriptPromise NativeIOFile::write(ScriptState* script_state,
+ MaybeShared<DOMArrayBufferView> buffer,
+ uint64_t file_offset,
+ ExceptionState& exception_state) {
+ if (!buffer.View()->IsShared()) {
+ exception_state.ThrowTypeError(
+ "The I/O buffer must be backed by a SharedArrayBuffer");
+ return ScriptPromise();
+ }
+
+ if (io_pending_) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "Another I/O operation is in progress on the same file");
+ return ScriptPromise();
+ }
+ if (closed_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "The file was already closed");
+ return ScriptPromise();
+ }
+ io_pending_ = true;
+
+ int write_size = OperationSize(*buffer.View());
+ const char* write_data =
+ static_cast<const char*>(buffer.View()->BaseAddressMaybeShared());
+ DOMSharedArrayBuffer* read_buffer_keepalive = buffer.View()->BufferShared();
+
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ // The first CrossThreadUnretained() is safe here because the
+ // NativeIOFile::FileState instance is owned by this NativeIOFile, which is
+ // also passed to the task via WrapCrossThreadPersistent. Therefore, the
+ // FileState instance is guaranteed to remain alive during the task's
+ // execution.
+ //
+ // The second CrossThreadUnretained() is safe here because the write data is
+ // backed by a DOMSharedArrayBuffer that is also passed to the task via
+ // WrapCrossThreadPersistent. Therefore, the data is guaranteed to remain
+ // alive during the task's execution.
+ worker_pool::PostTask(
+ FROM_HERE, {base::MayBlock(), base::ThreadPool()},
+ CrossThreadBindOnce(
+ &DoWrite, WrapCrossThreadPersistent(this),
+ WrapCrossThreadPersistent(resolver),
+ WrapCrossThreadPersistent(read_buffer_keepalive),
+ CrossThreadUnretained(file_state_.get()), resolver_task_runner_,
+ CrossThreadUnretained(write_data), file_offset, write_size));
+ return resolver->Promise();
+}
+
+void NativeIOFile::Trace(Visitor* visitor) {
+ ScriptWrappable::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
+ visitor->Trace(queued_close_resolver_);
+}
+
+void NativeIOFile::ContextDestroyed() {
+ backend_file_.reset();
+}
+
+void NativeIOFile::OnBackendDisconnect() {
+ backend_file_.reset();
+ CloseBackingFile();
+}
+
+void NativeIOFile::DispatchQueuedClose() {
+ DCHECK(!io_pending_)
+ << "Dispatching close() concurrently with other I/O operations is racy";
+
+ if (!queued_close_resolver_)
+ return;
+
+ DCHECK(closed_) << "close() resolver queued without setting closed_";
+ ScriptPromiseResolver* resolver = queued_close_resolver_;
+ queued_close_resolver_ = nullptr;
+
+ worker_pool::PostTask(
+ FROM_HERE, {base::MayBlock(), base::ThreadPool()},
+ CrossThreadBindOnce(&DoClose, WrapCrossThreadPersistent(this),
+ WrapCrossThreadPersistent(resolver),
+ CrossThreadUnretained(file_state_.get()),
+ resolver_task_runner_));
+}
+
+// static
+void NativeIOFile::DoClose(
+ CrossThreadPersistent<NativeIOFile> native_io_file,
+ CrossThreadPersistent<ScriptPromiseResolver> resolver,
+ NativeIOFile::FileState* file_state,
+ scoped_refptr<base::SequencedTaskRunner> resolver_task_runner) {
+ DCHECK(!IsMainThread()) << "File I/O should not happen on the main thread";
+
+ {
+ WTF::MutexLocker locker(file_state->mutex);
+ DCHECK(file_state->file.IsValid())
+ << "file I/O operation queued after file closed";
+ file_state->file.Close();
+ }
+
+ PostCrossThreadTask(
+ *resolver_task_runner, FROM_HERE,
+ CrossThreadBindOnce(&NativeIOFile::DidClose, std::move(native_io_file),
+ std::move(resolver)));
+}
+
+void NativeIOFile::DidClose(
+ CrossThreadPersistent<ScriptPromiseResolver> resolver) {
+ ScriptState* script_state = resolver->GetScriptState();
+ if (!script_state->ContextIsValid()) {
+ // If the context was torn down, the backend is disconnecting or
+ // disconnected. No need to report that the file is closing.
+ return;
+ }
+
+ if (!backend_file_) {
+ // If the backend went away, no need to tell it that the file was closed.
+ resolver->Resolve();
+ return;
+ }
+
+ backend_file_->Close(
+ WTF::Bind([](ScriptPromiseResolver* resolver) { resolver->Resolve(); },
+ WrapPersistent(resolver.Get())));
+}
+
+// static
+void NativeIOFile::DoRead(
+ CrossThreadPersistent<NativeIOFile> native_io_file,
+ CrossThreadPersistent<ScriptPromiseResolver> resolver,
+ CrossThreadPersistent<DOMSharedArrayBuffer> read_buffer_keepalive,
+ NativeIOFile::FileState* file_state,
+ scoped_refptr<base::SequencedTaskRunner> resolver_task_runner,
+ char* read_buffer,
+ uint64_t file_offset,
+ int read_size) {
+ DCHECK(!IsMainThread()) << "File I/O should not happen on the main thread";
+
+ int read_bytes;
+ base::File::Error read_error;
+ {
+ WTF::MutexLocker mutex_locker(file_state->mutex);
+ DCHECK(file_state->file.IsValid())
+ << "file I/O operation queued after file closed";
+ read_bytes = file_state->file.Read(file_offset, read_buffer, read_size);
+ read_error = (read_bytes < 0) ? file_state->file.GetLastFileError()
+ : base::File::FILE_OK;
+ }
+
+ PostCrossThreadTask(
+ *resolver_task_runner, FROM_HERE,
+ CrossThreadBindOnce(&NativeIOFile::DidRead, std::move(native_io_file),
+ std::move(resolver), read_bytes, read_error));
+}
+
+void NativeIOFile::DidRead(
+ CrossThreadPersistent<ScriptPromiseResolver> resolver,
+ int read_bytes,
+ base::File::Error read_error) {
+ ScriptState* script_state = resolver->GetScriptState();
+ if (!script_state->ContextIsValid())
+ return;
+ ScriptState::Scope scope(script_state);
+
+ DCHECK(io_pending_) << "I/O operation performed without io_pending_ set";
+ io_pending_ = false;
+
+ DispatchQueuedClose();
+
+ if (read_bytes < 0) {
+ resolver->Reject(V8ThrowDOMException::CreateOrEmpty(
+ script_state->GetIsolate(), DOMExceptionCode::kInvalidStateError,
+ "read() failed"));
+ return;
+ }
+ resolver->Resolve(read_bytes);
+}
+
+// static
+void NativeIOFile::DoWrite(
+ CrossThreadPersistent<NativeIOFile> native_io_file,
+ CrossThreadPersistent<ScriptPromiseResolver> resolver,
+ CrossThreadPersistent<DOMSharedArrayBuffer> write_data_keepalive,
+ NativeIOFile::FileState* file_state,
+ scoped_refptr<base::SequencedTaskRunner> resolver_task_runner,
+ const char* write_data,
+ uint64_t file_offset,
+ int write_size) {
+ DCHECK(!IsMainThread()) << "File I/O should not happen on the main thread";
+
+ int written_bytes;
+ base::File::Error write_error;
+ {
+ WTF::MutexLocker mutex_locker(file_state->mutex);
+ DCHECK(file_state->file.IsValid())
+ << "file I/O operation queued after file closed";
+ written_bytes = file_state->file.Write(file_offset, write_data, write_size);
+ write_error = (written_bytes < 0) ? file_state->file.GetLastFileError()
+ : base::File::FILE_OK;
+ }
+
+ PostCrossThreadTask(
+ *resolver_task_runner, FROM_HERE,
+ CrossThreadBindOnce(&NativeIOFile::DidRead, std::move(native_io_file),
+ std::move(resolver), written_bytes, write_error));
+}
+
+void NativeIOFile::DidWrite(
+ CrossThreadPersistent<ScriptPromiseResolver> resolver,
+ int written_bytes,
+ base::File::Error write_error) {
+ ScriptState* script_state = resolver->GetScriptState();
+ if (!script_state->ContextIsValid())
+ return;
+ ScriptState::Scope scope(script_state);
+
+ DCHECK(io_pending_) << "I/O operation performed without io_pending_ set";
+ io_pending_ = false;
+
+ DispatchQueuedClose();
+
+ if (written_bytes < 0) {
+ resolver->Reject(V8ThrowDOMException::CreateOrEmpty(
+ script_state->GetIsolate(), DOMExceptionCode::kDataError,
+ "write() failed"));
+ return;
+ }
+ resolver->Resolve(written_bytes);
+}
+
+void NativeIOFile::CloseBackingFile() {
+ closed_ = true;
+ file_state_->mutex.lock();
+ base::File backing_file = std::move(file_state_->file);
+ file_state_->mutex.unlock();
+
+ if (!backing_file.IsValid()) {
+ // Avoid posting a cross-thread task if the file is already closed. This is
+ // the expected path.
+ return;
+ }
+
+ worker_pool::PostTask(
+ FROM_HERE, {base::MayBlock(), base::ThreadPool()},
+ CrossThreadBindOnce([](base::File file) { file.Close(); },
+ std::move(backing_file)));
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..270c43f111d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_io/native_io_file.h
@@ -0,0 +1,150 @@
+// 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_NATIVE_IO_NATIVE_IO_FILE_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_IO_NATIVE_IO_FILE_H_
+
+#include <memory>
+
+#include "base/files/file.h"
+#include "base/memory/scoped_refptr.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/blink/public/mojom/native_io/native_io.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h"
+#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.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/heap/persistent.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace base {
+class SequencedTaskRunner;
+} // namespace base
+
+namespace blink {
+
+class DOMSharedArrayBuffer;
+class ExecutionContext;
+class ScriptPromiseResolver;
+class ScriptState;
+
+class NativeIOFile final : public ScriptWrappable,
+ public ExecutionContextLifecycleObserver {
+ DEFINE_WRAPPERTYPEINFO();
+ USING_GARBAGE_COLLECTED_MIXIN(NativeIOFile);
+
+ public:
+ NativeIOFile(base::File backing_file,
+ mojo::Remote<mojom::blink::NativeIOFileHost> backend_file,
+ ExecutionContext*);
+
+ NativeIOFile(const NativeIOFile&) = delete;
+ NativeIOFile& operator=(const NativeIOFile&) = delete;
+
+ // Needed because of the mojo::Remote<mojom::blink::NativeIOFile>.
+ ~NativeIOFile() override;
+
+ ScriptPromise close(ScriptState*);
+ ScriptPromise read(ScriptState*,
+ MaybeShared<DOMArrayBufferView> buffer,
+ uint64_t file_offset,
+ ExceptionState&);
+ ScriptPromise write(ScriptState*,
+ MaybeShared<DOMArrayBufferView> buffer,
+ uint64_t file_offset,
+ ExceptionState&);
+
+ // GarbageCollected
+ void Trace(Visitor* visitor) override;
+
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
+
+ private:
+ // Data accessed on the threads that do file I/O.
+ //
+ // Instances are allocated on the PartitionAlloc heap. Instances are initially
+ // constructed on Blink's main thread, or on a worker thread. Afterwards,
+ // instances are only accessed on dedicated threads that do blocking file I/O.
+ struct FileState;
+
+ // Called when the mojo backend disconnects.
+ void OnBackendDisconnect();
+
+ // Runs any queued close operation.
+ void DispatchQueuedClose();
+
+ // Performs the file I/O part of close().
+ static void DoClose(
+ CrossThreadPersistent<NativeIOFile> native_io_file,
+ CrossThreadPersistent<ScriptPromiseResolver> resolver,
+ NativeIOFile::FileState* file_state,
+ scoped_refptr<base::SequencedTaskRunner> file_task_runner);
+ // Performs the post file-I/O part of close(), on the main thread.
+ void DidClose(CrossThreadPersistent<ScriptPromiseResolver> resolver);
+
+ // Performs the file I/O part of read().
+ static void DoRead(
+ CrossThreadPersistent<NativeIOFile> native_io_file,
+ CrossThreadPersistent<ScriptPromiseResolver> resolver,
+ CrossThreadPersistent<DOMSharedArrayBuffer> read_buffer_keepalive,
+ NativeIOFile::FileState* file_state,
+ scoped_refptr<base::SequencedTaskRunner> file_task_runner,
+ char* read_buffer,
+ uint64_t file_offset,
+ int read_size);
+ // Performs the post file-I/O part of read(), on the main thread.
+ void DidRead(CrossThreadPersistent<ScriptPromiseResolver> resolver,
+ int read_bytes,
+ base::File::Error read_error);
+
+ // Performs the file I/O part of write().
+ static void DoWrite(
+ CrossThreadPersistent<NativeIOFile> native_io_file,
+ CrossThreadPersistent<ScriptPromiseResolver> resolver,
+ CrossThreadPersistent<DOMSharedArrayBuffer> write_data_keepalive,
+ NativeIOFile::FileState* file_state,
+ scoped_refptr<base::SequencedTaskRunner> file_task_runner,
+ const char* write_data,
+ uint64_t file_offset,
+ int write_size);
+ // Performs the post file-I/O part of write(), on the main thread.
+ void DidWrite(CrossThreadPersistent<ScriptPromiseResolver> resolver,
+ int written_bytes,
+ base::File::Error write_error);
+
+ // Kicks off closing the file from the main thread.
+ void CloseBackingFile();
+
+ // True when an I/O operation other than close is underway.
+ //
+ // Checked before kicking off any I/O operation except for close(). This
+ // ensures that at most one I/O operation is underway at any given time.
+ bool io_pending_ = false;
+
+ // Non-null when a close() I/O is queued behind another I/O operation.
+ //
+ // Set when close() is called while another I/O operation is underway. Cleared
+ // when the queued close() operation is queued.
+ Member<ScriptPromiseResolver> queued_close_resolver_;
+
+ // Set to true when close() is called, or when the backend goes away.
+ bool closed_ = false;
+
+ // See NativeIO::FileState, declared above.
+ const std::unique_ptr<FileState> file_state_;
+
+ // Schedules resolving Promises with file I/O results.
+ const scoped_refptr<base::SequencedTaskRunner> resolver_task_runner_;
+
+ // Mojo pipe that holds the renderer's lock on the file.
+ mojo::Remote<mojom::blink::NativeIOFileHost> backend_file_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_IO_NATIVE_IO_FILE_H_
diff --git a/chromium/third_party/blink/renderer/modules/native_io/native_io_file.idl b/chromium/third_party/blink/renderer/modules/native_io/native_io_file.idl
new file mode 100644
index 00000000000..fce545fa24b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_io/native_io_file.idl
@@ -0,0 +1,21 @@
+// 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/fivedots/nativeio-explainer
+
+[
+ Exposed=(Window, Worker),
+ RuntimeEnabled=NativeIO,
+ SecureContext
+] interface NativeIOFile {
+ [CallWith=ScriptState] Promise<void> close();
+ [
+ CallWith=ScriptState, RaisesException
+ ] Promise<unsigned long long> read([AllowShared] ArrayBufferView buffer,
+ unsigned long long file_offset);
+ [
+ CallWith=ScriptState, RaisesException
+ ] Promise<unsigned long long> write([AllowShared] ArrayBufferView buffer,
+ unsigned long long file_offset);
+};
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
new file mode 100644
index 00000000000..466c4d75b43
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.cc
@@ -0,0 +1,104 @@
+// 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/native_io/native_io_file_sync.h"
+
+#include <limits>
+
+#include "base/numerics/safe_conversions.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h"
+#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h"
+#include "third_party/blink/renderer/modules/native_io/native_io_file.h"
+#include "third_party/blink/renderer/platform/bindings/exception_code.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/heap/heap.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
+
+namespace blink {
+
+// Extracts the read/write operation size from the buffer size.
+int OperationSize(const DOMArrayBufferView& buffer) {
+ // On 32-bit platforms, clamp operation sizes to 2^31-1.
+ return base::saturated_cast<int>(buffer.byteLengthAsSizeT());
+}
+
+NativeIOFileSync::NativeIOFileSync(
+ base::File backing_file,
+ mojo::Remote<mojom::blink::NativeIOFileHost> backend_file,
+ ExecutionContext* execution_context)
+ : ExecutionContextLifecycleObserver(execution_context),
+ backing_file_(std::move(backing_file)),
+ backend_file_(std::move(backend_file)) {
+ backend_file_.set_disconnect_handler(WTF::Bind(
+ &NativeIOFileSync::OnBackendDisconnect, WrapWeakPersistent(this)));
+}
+
+NativeIOFileSync::~NativeIOFileSync() = default;
+
+void NativeIOFileSync::close() {
+ backing_file_.Close();
+
+ if (!backend_file_) {
+ // If the backend went away, it already considers the file closed. Nothing
+ // to report here.
+ return;
+ }
+ backend_file_->Close();
+}
+
+int NativeIOFileSync::read(MaybeShared<DOMArrayBufferView> buffer,
+ uint64_t file_offset,
+ ExceptionState& exception_state) {
+ int read_size = OperationSize(*buffer.View());
+ char* read_data = static_cast<char*>(buffer.View()->BaseAddressMaybeShared());
+ if (!backing_file_.IsValid()) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "File already closed");
+ return 0;
+ }
+ int read_bytes = backing_file_.Read(file_offset, read_data, read_size);
+ if (read_bytes < 0) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kDataError,
+ "read() failed");
+ }
+ return read_bytes;
+}
+
+int NativeIOFileSync::write(MaybeShared<DOMArrayBufferView> buffer,
+ uint64_t file_offset,
+ ExceptionState& exception_state) {
+ int write_size = OperationSize(*buffer.View());
+ char* write_data =
+ static_cast<char*>(buffer.View()->BaseAddressMaybeShared());
+ if (!backing_file_.IsValid()) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "File already closed");
+ return 0;
+ }
+ int written_bytes = backing_file_.Write(file_offset, write_data, write_size);
+ if (written_bytes < 0) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kDataError,
+ "write() failed");
+ }
+ return written_bytes;
+}
+
+void NativeIOFileSync::Trace(Visitor* visitor) {
+ ScriptWrappable::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
+}
+
+void NativeIOFileSync::ContextDestroyed() {
+ backend_file_.reset();
+}
+
+void NativeIOFileSync::OnBackendDisconnect() {
+ backend_file_.reset();
+ backing_file_.Close();
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..d36815e6c93
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.h
@@ -0,0 +1,69 @@
+// 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_NATIVE_IO_NATIVE_IO_FILE_SYNC_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_IO_NATIVE_IO_FILE_SYNC_H_
+
+#include <stdint.h>
+
+#include "base/files/file.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/blink/public/mojom/native_io/native_io.mojom-blink.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h"
+#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.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/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace blink {
+
+class ExceptionState;
+class ExecutionContext;
+
+class NativeIOFileSync final : public ScriptWrappable,
+ public ExecutionContextLifecycleObserver {
+ DEFINE_WRAPPERTYPEINFO();
+ USING_GARBAGE_COLLECTED_MIXIN(NativeIOFileSync);
+
+ public:
+ NativeIOFileSync(base::File backing_file,
+ mojo::Remote<mojom::blink::NativeIOFileHost> backend_file,
+ ExecutionContext*);
+
+ NativeIOFileSync(const NativeIOFileSync&) = delete;
+ NativeIOFileSync& operator=(const NativeIOFileSync&) = delete;
+
+ // Needed because of the mojo::Remote<mojom::blink::NativeIOFile>.
+ ~NativeIOFileSync() override;
+
+ void close();
+ int read(MaybeShared<DOMArrayBufferView> buffer,
+ uint64_t file_offset,
+ ExceptionState&);
+ int write(MaybeShared<DOMArrayBufferView> buffer,
+ uint64_t file_offset,
+ ExceptionState&);
+
+ // GarbageCollected
+ void Trace(Visitor* visitor) override;
+
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
+
+ private:
+ // Called when the mojo backend disconnects.
+ void OnBackendDisconnect();
+
+ // The file on disk backing this NativeIOFile.
+ base::File backing_file_;
+
+ // Mojo pipe that holds the renderer's lock on the file.
+ mojo::Remote<mojom::blink::NativeIOFileHost> backend_file_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_IO_NATIVE_IO_FILE_SYNC_H_
diff --git a/chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.idl b/chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.idl
new file mode 100644
index 00000000000..001d5487dc6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.idl
@@ -0,0 +1,21 @@
+// 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/fivedots/nativeio-explainer
+
+[
+ Exposed=DedicatedWorker,
+ RuntimeEnabled=NativeIO,
+ SecureContext
+] interface NativeIOFileSync {
+ void close();
+ [
+ RaisesException
+ ] unsigned long long read([AllowShared] ArrayBufferView buffer,
+ unsigned long long file_offset);
+ [
+ RaisesException
+ ] unsigned long long write([AllowShared] ArrayBufferView buffer,
+ unsigned long long file_offset);
+};
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
new file mode 100644
index 00000000000..0fad4c7a7a6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.cc
@@ -0,0 +1,269 @@
+// 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/native_io/native_io_manager.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "base/files/file.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/blink/public/mojom/native_io/native_io.mojom-blink.h"
+#include "third_party/blink/public/platform/task_type.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/core/dom/dom_exception.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
+#include "third_party/blink/renderer/modules/native_io/native_io_file.h"
+#include "third_party/blink/renderer/modules/native_io/native_io_file_sync.h"
+#include "third_party/blink/renderer/platform/bindings/exception_code.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/heap/heap.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
+
+namespace blink {
+
+namespace {
+
+bool IsValidNativeIONameCharacter(int name_char) {
+ return (name_char >= 'a' && name_char <= 'z') ||
+ (name_char >= '0' && name_char <= '9') || name_char == '_';
+}
+
+bool IsValidNativeIOName(const String& name) {
+ if (name.IsEmpty())
+ return false;
+
+ if (name.Is8Bit()) {
+ return std::all_of(name.Span8().begin(), name.Span8().end(),
+ &IsValidNativeIONameCharacter);
+ }
+ return std::all_of(name.Span16().begin(), name.Span16().end(),
+ &IsValidNativeIONameCharacter);
+}
+
+void OnOpenResult(ScriptPromiseResolver* resolver,
+ mojo::Remote<mojom::blink::NativeIOFileHost> backend_file,
+ base::File backing_file) {
+ ScriptState* script_state = resolver->GetScriptState();
+ if (!script_state->ContextIsValid())
+ return;
+ ScriptState::Scope scope(script_state);
+
+ if (!backing_file.IsValid()) {
+ resolver->Reject(V8ThrowDOMException::CreateOrEmpty(
+ script_state->GetIsolate(), DOMExceptionCode::kUnknownError,
+ "open() failed"));
+ return;
+ }
+
+ NativeIOFile* file = MakeGarbageCollected<NativeIOFile>(
+ std::move(backing_file), std::move(backend_file),
+ ExecutionContext::From(script_state));
+ resolver->Resolve(file);
+}
+
+void OnDeleteResult(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,
+ "delete() failed"));
+ return;
+ }
+
+ resolver->Resolve();
+}
+
+void OnGetAllResult(ScriptPromiseResolver* resolver,
+ bool backend_success,
+ const Vector<String>& file_names) {
+ 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,
+ "getAll() failed"));
+ return;
+ }
+
+ resolver->Resolve(file_names);
+}
+
+} // namespace
+
+NativeIOManager::NativeIOManager(
+ ExecutionContext* execution_context,
+ mojo::Remote<mojom::blink::NativeIOHost> backend)
+ : ExecutionContextLifecycleObserver(execution_context),
+ // TODO(pwnall): Get a dedicated queue when the specification matures.
+ receiver_task_runner_(
+ execution_context->GetTaskRunner(TaskType::kMiscPlatformAPI)),
+ backend_(std::move(backend)) {
+ backend_.set_disconnect_handler(WTF::Bind(
+ &NativeIOManager::OnBackendDisconnect, WrapWeakPersistent(this)));
+}
+
+NativeIOManager::~NativeIOManager() = default;
+
+ScriptPromise NativeIOManager::open(ScriptState* script_state,
+ String name,
+ ExceptionState& exception_state) {
+ if (!IsValidNativeIOName(name)) {
+ exception_state.ThrowTypeError("Invalid file name");
+ return ScriptPromise();
+ }
+
+ if (!backend_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "NativeIOHost backend went away");
+ return ScriptPromise();
+ }
+
+ ExecutionContext* execution_context = GetExecutionContext();
+ DCHECK(execution_context);
+
+ mojo::Remote<mojom::blink::NativeIOFileHost> backend_file;
+ mojo::PendingReceiver<mojom::blink::NativeIOFileHost> backend_file_receiver =
+ backend_file.BindNewPipeAndPassReceiver(receiver_task_runner_);
+
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ backend_->OpenFile(name, std::move(backend_file_receiver),
+ WTF::Bind(&OnOpenResult, WrapPersistent(resolver),
+ std::move(backend_file)));
+ return resolver->Promise();
+}
+
+ScriptPromise NativeIOManager::Delete(ScriptState* script_state,
+ String name,
+ ExceptionState& exception_state) {
+ if (!IsValidNativeIOName(name)) {
+ exception_state.ThrowTypeError("Invalid file name");
+ return ScriptPromise();
+ }
+
+ if (!backend_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "NativeIOHost backend went away");
+ return ScriptPromise();
+ }
+
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ backend_->DeleteFile(name,
+ WTF::Bind(&OnDeleteResult, WrapPersistent(resolver)));
+ return resolver->Promise();
+}
+
+ScriptPromise NativeIOManager::getAll(ScriptState* script_state,
+ ExceptionState& exception_state) {
+ if (!backend_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "NativeIOHost backend went away");
+ return ScriptPromise();
+ }
+
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ backend_->GetAllFileNames(
+ WTF::Bind(&OnGetAllResult, WrapPersistent(resolver)));
+ return resolver->Promise();
+}
+
+NativeIOFileSync* NativeIOManager::openSync(String name,
+ ExceptionState& exception_state) {
+ if (!IsValidNativeIOName(name)) {
+ exception_state.ThrowTypeError("Invalid file name");
+ return nullptr;
+ }
+
+ if (!backend_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "NativeIOHost backend went away");
+ return nullptr;
+ }
+
+ ExecutionContext* execution_context = GetExecutionContext();
+ DCHECK(execution_context);
+
+ mojo::Remote<mojom::blink::NativeIOFileHost> backend_file;
+ mojo::PendingReceiver<mojom::blink::NativeIOFileHost> backend_file_receiver =
+ backend_file.BindNewPipeAndPassReceiver(receiver_task_runner_);
+
+ base::File backing_file;
+ bool call_succeeded =
+ backend_->OpenFile(name, std::move(backend_file_receiver), &backing_file);
+
+ if (!call_succeeded || !backing_file.IsValid()) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kUnknownError,
+ "openSync() failed");
+ return nullptr;
+ }
+
+ return MakeGarbageCollected<NativeIOFileSync>(
+ std::move(backing_file), std::move(backend_file), execution_context);
+}
+
+void NativeIOManager::deleteSync(String name, ExceptionState& exception_state) {
+ if (!IsValidNativeIOName(name)) {
+ exception_state.ThrowTypeError("Invalid file name");
+ return;
+ }
+
+ if (!backend_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "NativeIOHost backend went away");
+ return;
+ }
+
+ bool backend_success = false;
+ bool call_succeeded = backend_->DeleteFile(name, &backend_success);
+
+ if (!call_succeeded || !backend_success) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kUnknownError,
+ "deleteSync() failed");
+ }
+}
+
+Vector<String> NativeIOManager::getAllSync(ExceptionState& exception_state) {
+ Vector<String> result;
+ if (!backend_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "NativeIOHost backend went away");
+ return result;
+ }
+
+ bool backend_success = false;
+ bool call_succeeded = backend_->GetAllFileNames(&backend_success, &result);
+
+ if (!call_succeeded || !backend_success) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kUnknownError,
+ "getAllSync() failed");
+ }
+ return result;
+}
+
+void NativeIOManager::Trace(Visitor* visitor) {
+ ScriptWrappable::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
+}
+
+void NativeIOManager::ContextDestroyed() {
+ backend_.reset();
+}
+
+void NativeIOManager::OnBackendDisconnect() {
+ backend_.reset();
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..c028e7ba4e0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.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_MODULES_NATIVE_IO_NATIVE_IO_MANAGER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_IO_NATIVE_IO_MANAGER_H_
+
+#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/blink/public/mojom/native_io/native_io.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace blink {
+
+class ExecutionContext;
+class ExceptionState;
+class NativeIOFileSync;
+class ScriptState;
+
+class NativeIOManager final : public ScriptWrappable,
+ public ExecutionContextLifecycleObserver {
+ DEFINE_WRAPPERTYPEINFO();
+ USING_GARBAGE_COLLECTED_MIXIN(NativeIOManager);
+
+ public:
+ explicit NativeIOManager(ExecutionContext*,
+ mojo::Remote<mojom::blink::NativeIOHost> backend);
+
+ NativeIOManager(const NativeIOManager&) = delete;
+ NativeIOManager& operator=(const NativeIOManager&) = delete;
+
+ // Needed because of the
+ // mojo::Remote<blink::mojom::NativeIOHost>
+ ~NativeIOManager() override;
+
+ ScriptPromise open(ScriptState*, String name, ExceptionState&);
+ ScriptPromise Delete(ScriptState*, String name, ExceptionState&);
+ ScriptPromise getAll(ScriptState*, ExceptionState&);
+
+ NativeIOFileSync* openSync(String name, ExceptionState&);
+ void deleteSync(String name, ExceptionState&);
+ Vector<String> getAllSync(ExceptionState&);
+
+ // GarbageCollected
+ void Trace(Visitor* visitor) override;
+
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
+
+ private:
+ // Called when the mojo backend disconnects.
+ void OnBackendDisconnect();
+
+ // Task runner used by NativeIOFile mojo receivers generated by this API.
+ const scoped_refptr<base::SequencedTaskRunner> receiver_task_runner_;
+
+ // Wraps an always-on Mojo pipe for sending requests to the storage backend.
+ mojo::Remote<mojom::blink::NativeIOHost> backend_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_IO_NATIVE_IO_MANAGER_H_
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
new file mode 100644
index 00000000000..c2317ff73d5
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.idl
@@ -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.
+
+// https://github.com/fivedots/nativeio-explainer
+
+[
+ Exposed=(Window,Worker),
+ RuntimeEnabled=NativeIO,
+ SecureContext
+] interface NativeIOManager {
+ [
+ CallWith=ScriptState, RaisesException
+ ] Promise<NativeIOFile> open(DOMString name);
+ [
+ Exposed=DedicatedWorker, RaisesException
+ ] NativeIOFileSync openSync(DOMString name);
+
+ [
+ CallWith=ScriptState, ImplementedAs=Delete, RaisesException
+ ] Promise<void> delete(DOMString name);
+ [Exposed=DedicatedWorker, RaisesException] void deleteSync(DOMString name);
+
+ [
+ CallWith=ScriptState, RaisesException
+ ] Promise<sequence<DOMString>> getAll();
+ [Exposed=DedicatedWorker, RaisesException] sequence<DOMString> getAllSync();
+};
diff --git a/chromium/third_party/blink/renderer/modules/native_io/window_native_io.idl b/chromium/third_party/blink/renderer/modules/native_io/window_native_io.idl
new file mode 100644
index 00000000000..1b78cc42f38
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_io/window_native_io.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/fivedots/nativeio-explainer
+
+[
+ ImplementedAs=GlobalNativeIO,
+ RuntimeEnabled=NativeIO,
+ SecureContext
+] partial interface Window {
+ readonly attribute NativeIOManager nativeIO;
+};
diff --git a/chromium/third_party/blink/renderer/modules/native_io/worker_global_scope_native_io.idl b/chromium/third_party/blink/renderer/modules/native_io/worker_global_scope_native_io.idl
new file mode 100644
index 00000000000..aa03a6ca7c5
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/native_io/worker_global_scope_native_io.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/fivedots/nativeio-explainer
+
+[
+ ImplementedAs=GlobalNativeIO,
+ RuntimeEnabled=NativeIO,
+ SecureContext
+] partial interface WorkerGlobalScope {
+ readonly attribute NativeIOManager nativeIO;
+};
diff --git a/chromium/third_party/blink/renderer/modules/navigatorcontentutils/idls.gni b/chromium/third_party/blink/renderer/modules/navigatorcontentutils/idls.gni
new file mode 100644
index 00000000000..08fc1d447df
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/navigatorcontentutils/idls.gni
@@ -0,0 +1,5 @@
+# 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_dependency_idl_files = [ "navigator_content_utils.idl" ]
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 3be6ca9602a..9b2d1baf92c 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
@@ -102,6 +102,22 @@ static bool VerifyCustomHandlerURL(const Document& document,
return true;
}
+// HTML5 requires that schemes with the |web+| prefix contain one or more
+// ASCII alphas after that prefix.
+static bool IsValidWebSchemeName(const String& protocol) {
+ if (protocol.length() < 5)
+ return false;
+
+ unsigned protocol_length = protocol.length();
+ for (unsigned i = 4; i < protocol_length; i++) {
+ char c = protocol[i];
+ if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) {
+ return false;
+ }
+ }
+ return true;
+}
+
static bool VerifyCustomHandlerScheme(const String& scheme,
ExceptionState& exception_state) {
if (!IsValidProtocol(scheme)) {
@@ -112,13 +128,12 @@ static bool VerifyCustomHandlerScheme(const String& scheme,
}
if (scheme.StartsWith("web+")) {
- // The specification requires that the length of scheme is at least five
- // characters (including 'web+' prefix).
- if (scheme.length() >= 5)
+ if (IsValidWebSchemeName(scheme))
return true;
-
- exception_state.ThrowSecurityError("The scheme name '" + scheme +
- "' is less than five characters long.");
+ exception_state.ThrowSecurityError(
+ "The scheme name '" + scheme +
+ "' is not allowed. Schemes starting with 'web+' must be followed by "
+ "one or more ASCII letters.");
return false;
}
@@ -170,7 +185,7 @@ void NavigatorContentUtils::registerProtocolHandler(
// Count usage; perhaps we can forbid this from cross-origin subframes as
// proposed in https://crbug.com/977083.
UseCounter::Count(
- *document, frame->IsCrossOriginSubframe()
+ *document, frame->IsCrossOriginToMainFrame()
? WebFeature::kRegisterProtocolHandlerCrossOriginSubframe
: WebFeature::kRegisterProtocolHandlerSameOriginAsTop);
// Count usage. Context should now always be secure due to the same-origin
@@ -207,7 +222,7 @@ void NavigatorContentUtils::unregisterProtocolHandler(
->UnregisterProtocolHandler(scheme, document->CompleteURL(url));
}
-void NavigatorContentUtils::Trace(blink::Visitor* visitor) {
+void NavigatorContentUtils::Trace(Visitor* visitor) {
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 0abb5f1a16c..cf4ae1bab3f 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
@@ -63,7 +63,7 @@ class MODULES_EXPORT NavigatorContentUtils final
const String& url,
ExceptionState&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 5823efd8055..a358d4dfe0e 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(blink::Visitor* visitor) {
+void NavigatorContentUtilsClient::Trace(Visitor* visitor) {
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 ac034c0aa02..f7f0d906067 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(blink::Visitor*);
+ virtual void Trace(Visitor*);
private:
Member<LocalFrame> frame_;
diff --git a/chromium/third_party/blink/renderer/modules/netinfo/idls.gni b/chromium/third_party/blink/renderer/modules/netinfo/idls.gni
new file mode 100644
index 00000000000..471ef7bcd00
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/netinfo/idls.gni
@@ -0,0 +1,12 @@
+# 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 = [ "network_information.idl" ]
+
+modules_dependency_idl_files = [
+ "navigator_network_information.idl",
+ "worker_navigator_network_information.idl",
+]
+
+modules_testing_dependency_idl_files = [ "testing/internals_net_info.idl" ]
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 98c4dad0569..86df6beed3f 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
@@ -12,7 +12,7 @@
namespace blink {
NavigatorNetworkInformation::NavigatorNetworkInformation(Navigator& navigator)
- : ContextClient(navigator.GetFrame()) {}
+ : ExecutionContextClient(navigator.GetFrame()) {}
NavigatorNetworkInformation& NavigatorNetworkInformation::From(
Navigator& navigator) {
@@ -48,10 +48,10 @@ NetworkInformation* NavigatorNetworkInformation::connection() {
return connection_.Get();
}
-void NavigatorNetworkInformation::Trace(blink::Visitor* visitor) {
+void NavigatorNetworkInformation::Trace(Visitor* visitor) {
visitor->Trace(connection_);
Supplement<Navigator>::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 e8b0fd53fbf..0945246caad 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
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_NETINFO_NAVIGATOR_NETWORK_INFORMATION_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_NETINFO_NAVIGATOR_NETWORK_INFORMATION_H_
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/frame/navigator.h"
#include "third_party/blink/renderer/platform/supplementable.h"
@@ -17,7 +17,7 @@ class NetworkInformation;
class NavigatorNetworkInformation final
: public GarbageCollected<NavigatorNetworkInformation>,
public Supplement<Navigator>,
- public ContextClient {
+ public ExecutionContextClient {
USING_GARBAGE_COLLECTED_MIXIN(NavigatorNetworkInformation);
public:
@@ -29,7 +29,7 @@ class NavigatorNetworkInformation final
explicit NavigatorNetworkInformation(Navigator&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 fe023d9a53f..8f17811e55c 100644
--- a/chromium/third_party/blink/renderer/modules/netinfo/network_information.cc
+++ b/chromium/third_party/blink/renderer/modules/netinfo/network_information.cc
@@ -14,6 +14,7 @@
#include "third_party/blink/renderer/core/frame/settings.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/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -25,7 +26,7 @@ Settings* GetSettings(ExecutionContext* execution_context) {
if (!execution_context)
return nullptr;
- auto* document = DynamicTo<Document>(execution_context);
+ auto* document = Document::DynamicFrom(execution_context);
if (!document)
return nullptr;
@@ -221,7 +222,7 @@ const AtomicString& NetworkInformation::InterfaceName() const {
}
ExecutionContext* NetworkInformation::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
void NetworkInformation::AddedEventListener(
@@ -255,7 +256,7 @@ bool NetworkInformation::HasPendingActivity() const {
return IsObserving();
}
-void NetworkInformation::ContextDestroyed(ExecutionContext*) {
+void NetworkInformation::ContextDestroyed() {
context_stopped_ = true;
StopObserving();
}
@@ -278,7 +279,7 @@ void NetworkInformation::StopObserving() {
}
NetworkInformation::NetworkInformation(ExecutionContext* context)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
web_holdback_console_message_shown_(false),
context_stopped_(false) {
base::Optional<base::TimeDelta> http_rtt;
@@ -297,9 +298,9 @@ NetworkInformation::NetworkInformation(ExecutionContext* context)
DCHECK_GE(20u, GetNetworkStateNotifier().RandomizationSalt());
}
-void NetworkInformation::Trace(blink::Visitor* visitor) {
+void NetworkInformation::Trace(Visitor* visitor) {
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
const String NetworkInformation::Host() const {
@@ -312,7 +313,7 @@ void NetworkInformation::MaybeShowWebHoldbackConsoleMsg() {
web_holdback_console_message_shown_ = true;
if (!GetNetworkStateNotifier().GetWebHoldbackEffectiveType())
return;
- GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
+ GetExecutionContext()->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther, mojom::ConsoleMessageLevel::kWarning,
GetConsoleLogStringForWebHoldback()));
}
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 9e47e33aa5e..2797435c7a9 100644
--- a/chromium/third_party/blink/renderer/modules/netinfo/network_information.h
+++ b/chromium/third_party/blink/renderer/modules/netinfo/network_information.h
@@ -10,7 +10,7 @@
#include "third_party/blink/public/platform/web_effective_connection_type.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/network/network_state_notifier.h"
namespace blink {
@@ -20,7 +20,7 @@ class ExecutionContext;
class NetworkInformation final
: public EventTargetWithInlineData,
public ActiveScriptWrappable<NetworkInformation>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public NetworkStateNotifier::NetworkStateObserver {
USING_GARBAGE_COLLECTED_MIXIN(NetworkInformation);
DEFINE_WRAPPERTYPEINFO();
@@ -53,10 +53,10 @@ class NetworkInformation final
// ScriptWrappable
bool HasPendingActivity() const final;
- // ContextLifecycleObserver overrides.
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver overrides.
+ void ContextDestroyed() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange)
DEFINE_ATTRIBUTE_EVENT_LISTENER(typechange, kTypechange) // Deprecated
@@ -106,7 +106,8 @@ class NetworkInformation final
// message has been shown, or if the holdback experiment is not enabled.
bool web_holdback_console_message_shown_;
- // Whether ContextLifecycleObserver::contextDestroyed has been called.
+ // Whether ExecutionContextLifecycleObserver::contextDestroyed has been
+ // called.
bool context_stopped_;
std::unique_ptr<NetworkStateNotifier::NetworkStateObserverHandle>
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 ad29ae8ab12..f0086c7f52b 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(blink::Visitor* visitor) {
+void WorkerNavigatorNetworkInformation::Trace(Visitor* visitor) {
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 9a6a9615caa..89d7c479367 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
NetworkInformation* connection(ExecutionContext*);
diff --git a/chromium/third_party/blink/renderer/modules/nfc/BUILD.gn b/chromium/third_party/blink/renderer/modules/nfc/BUILD.gn
index 1585a0f8f97..b117c3e7c70 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/nfc/BUILD.gn
@@ -6,8 +6,6 @@ import("//third_party/blink/renderer/modules/modules.gni")
blink_modules_sources("nfc") {
sources = [
- "ndef_error_event.cc",
- "ndef_error_event.h",
"ndef_message.cc",
"ndef_message.h",
"ndef_reader.cc",
diff --git a/chromium/third_party/blink/renderer/modules/nfc/DEPS b/chromium/third_party/blink/renderer/modules/nfc/DEPS
index 0918a9b586f..7537a71ad2e 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/DEPS
+++ b/chromium/third_party/blink/renderer/modules/nfc/DEPS
@@ -1,5 +1,4 @@
include_rules = [
- "+mojo/public/cpp/bindings/binding.h",
"+services/device/public/mojom/nfc.mojom-blink.h",
"+services/device/public/mojom/nfc.mojom-blink-forward.h",
]
diff --git a/chromium/third_party/blink/renderer/modules/nfc/README.md b/chromium/third_party/blink/renderer/modules/nfc/README.md
new file mode 100644
index 00000000000..4d6f599d1cf
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/nfc/README.md
@@ -0,0 +1,20 @@
+# Web NFC Blink Module
+
+`renderer/modules/nfc` implements the renderer process details and bindings for
+the [Web NFC specification]. It communicates with the browser process through the
+[Web NFC Mojo interface]. The platform-specific parts of the
+implementation are located in `services/device/nfc`.
+
+[Web NFC specification]: https://w3c.github.io/web-nfc/
+[Web NFC Mojo interface]: ../../../../../services/device/public/mojom/nfc.mojom
+
+
+## Testing
+
+Web NFC is primarily tested in [Web Platform Tests](https://source.chromium.org/chromium/chromium/src/+/master:third_party/blink/web_tests/external/wpt/web-nfc/).
+
+
+## Design Documents
+
+Please refer to the [design documentation](https://sites.google.com/a/chromium.org/dev/developers/design-documents/web-nfc)
+for more details. \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/nfc/idls.gni b/chromium/third_party/blink/renderer/modules/nfc/idls.gni
new file mode 100644
index 00000000000..34266343cc9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/nfc/idls.gni
@@ -0,0 +1,19 @@
+# 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 = [
+ "ndef_message.idl",
+ "ndef_record.idl",
+ "ndef_reader.idl",
+ "ndef_reading_event.idl",
+ "ndef_writer.idl",
+]
+
+modules_dictionary_idl_files = [
+ "ndef_message_init.idl",
+ "ndef_record_init.idl",
+ "ndef_reading_event_init.idl",
+ "ndef_scan_options.idl",
+ "ndef_write_options.idl",
+]
diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_error_event.cc b/chromium/third_party/blink/renderer/modules/nfc/ndef_error_event.cc
deleted file mode 100644
index 2e3a9249414..00000000000
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_error_event.cc
+++ /dev/null
@@ -1,35 +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/nfc/ndef_error_event.h"
-
-#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
-#include "v8/include/v8.h"
-
-namespace blink {
-
-NDEFErrorEvent::NDEFErrorEvent(const AtomicString& event_type,
- DOMException* error)
- : Event(event_type, Bubbles::kNo, Cancelable::kNo), error_(error) {
- DCHECK(error_);
-}
-
-NDEFErrorEvent::NDEFErrorEvent(const AtomicString& event_type,
- const NDEFErrorEventInit* initializer)
- : Event(event_type, initializer), error_(initializer->error()) {
- DCHECK(error_);
-}
-
-NDEFErrorEvent::~NDEFErrorEvent() = default;
-
-const AtomicString& NDEFErrorEvent::InterfaceName() const {
- return event_interface_names::kNDEFErrorEvent;
-}
-
-void NDEFErrorEvent::Trace(blink::Visitor* visitor) {
- visitor->Trace(error_);
- Event::Trace(visitor);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_error_event.h b/chromium/third_party/blink/renderer/modules/nfc/ndef_error_event.h
deleted file mode 100644
index e4595f73312..00000000000
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_error_event.h
+++ /dev/null
@@ -1,49 +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_NFC_NDEF_ERROR_EVENT_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_NFC_NDEF_ERROR_EVENT_H_
-
-#include "third_party/blink/renderer/core/dom/dom_exception.h"
-#include "third_party/blink/renderer/modules/event_modules.h"
-#include "third_party/blink/renderer/modules/nfc/ndef_error_event_init.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
-
-namespace blink {
-
-class NDEFErrorEvent : public Event {
- DEFINE_WRAPPERTYPEINFO();
-
- public:
- static NDEFErrorEvent* Create(const AtomicString& event_type,
- const NDEFErrorEventInit* initializer) {
- return MakeGarbageCollected<NDEFErrorEvent>(event_type, initializer);
- }
-
- NDEFErrorEvent(const AtomicString& event_type, DOMException* error);
- NDEFErrorEvent(const AtomicString& event_type,
- const NDEFErrorEventInit* initializer);
- ~NDEFErrorEvent() override;
-
- void Trace(blink::Visitor*) override;
-
- const AtomicString& InterfaceName() const override;
-
- DOMException* error() { return error_; }
-
- private:
- Member<DOMException> error_;
-};
-
-DEFINE_TYPE_CASTS(NDEFErrorEvent,
- Event,
- event,
- event->InterfaceName() ==
- event_interface_names::kNDEFErrorEvent,
- event.InterfaceName() ==
- event_interface_names::kNDEFErrorEvent);
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_NFC_NDEF_ERROR_EVENT_H_
diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_error_event.idl b/chromium/third_party/blink/renderer/modules/nfc/ndef_error_event.idl
deleted file mode 100644
index a0e1e60eea8..00000000000
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_error_event.idl
+++ /dev/null
@@ -1,15 +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.
-
-// Specification at:
-// http://w3c.github.io/web-nfc/#dom-ndeferrorevent
-
-[
- RuntimeEnabled=WebNFC,
- SecureContext,
- Constructor(DOMString type, NDEFErrorEventInit eventInitDict),
- Exposed=Window
-] interface NDEFErrorEvent : Event {
- readonly attribute DOMException error;
-};
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 61b1a04242d..52b9f214c13 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_message.cc
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_message.cc
@@ -6,8 +6,9 @@
#include "services/device/public/mojom/nfc.mojom-blink.h"
#include "third_party/blink/renderer/bindings/modules/v8/string_or_array_buffer_or_array_buffer_view_or_ndef_message_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_ndef_message_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_ndef_record_init.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
-#include "third_party/blink/renderer/modules/nfc/ndef_message_init.h"
#include "third_party/blink/renderer/modules/nfc/ndef_record.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -16,18 +17,26 @@ namespace blink {
// static
NDEFMessage* NDEFMessage::Create(const ExecutionContext* execution_context,
const NDEFMessageInit* init,
- ExceptionState& exception_state) {
+ ExceptionState& exception_state,
+ bool is_embedded) {
+ // https://w3c.github.io/web-nfc/#creating-ndef-message
+
+ // NDEFMessageInit#records is a required field.
+ DCHECK(init->hasRecords());
+ if (init->records().IsEmpty()) {
+ exception_state.ThrowTypeError(
+ "NDEFMessageInit#records being empty makes no sense.");
+ return nullptr;
+ }
+
NDEFMessage* message = MakeGarbageCollected<NDEFMessage>();
- message->url_ = init->url();
- if (init->hasRecords()) {
- for (const NDEFRecordInit* record_init : init->records()) {
- NDEFRecord* record =
- NDEFRecord::Create(execution_context, record_init, exception_state);
- if (exception_state.HadException())
- return nullptr;
- DCHECK(record);
- message->records_.push_back(record);
- }
+ for (const NDEFRecordInit* record_init : init->records()) {
+ NDEFRecord* record = NDEFRecord::Create(execution_context, record_init,
+ exception_state, is_embedded);
+ if (exception_state.HadException())
+ return nullptr;
+ DCHECK(record);
+ message->records_.push_back(record);
}
return message;
}
@@ -36,6 +45,7 @@ NDEFMessage* NDEFMessage::Create(const ExecutionContext* execution_context,
NDEFMessage* NDEFMessage::Create(const ExecutionContext* execution_context,
const NDEFMessageSource& source,
ExceptionState& exception_state) {
+ // https://w3c.github.io/web-nfc/#creating-ndef-message
if (source.IsString()) {
NDEFMessage* message = MakeGarbageCollected<NDEFMessage>();
message->records_.push_back(MakeGarbageCollected<NDEFRecord>(
@@ -45,24 +55,39 @@ NDEFMessage* NDEFMessage::Create(const ExecutionContext* execution_context,
if (source.IsArrayBuffer()) {
WTF::Vector<uint8_t> payload_data;
+ size_t byte_length = source.GetAsArrayBuffer()->ByteLengthAsSizeT();
+ if (byte_length > std::numeric_limits<wtf_size_t>::max()) {
+ exception_state.ThrowRangeError(
+ "Buffer size exceeds maximum heap object size.");
+ return nullptr;
+ }
payload_data.Append(
static_cast<uint8_t*>(source.GetAsArrayBuffer()->Data()),
- source.GetAsArrayBuffer()->DeprecatedByteLengthAsUnsigned());
+ static_cast<wtf_size_t>(byte_length));
NDEFMessage* message = MakeGarbageCollected<NDEFMessage>();
message->records_.push_back(MakeGarbageCollected<NDEFRecord>(
- std::move(payload_data), "application/octet-stream"));
+ String() /* id */, "application/octet-stream",
+ std::move(payload_data)));
return message;
}
if (source.IsArrayBufferView()) {
+ size_t byte_length =
+ source.GetAsArrayBufferView().View()->byteLengthAsSizeT();
+ if (byte_length > std::numeric_limits<wtf_size_t>::max()) {
+ exception_state.ThrowRangeError(
+ "Buffer size exceeds maximum heap object size.");
+ return nullptr;
+ }
WTF::Vector<uint8_t> payload_data;
payload_data.Append(
static_cast<uint8_t*>(
source.GetAsArrayBufferView().View()->BaseAddress()),
- source.GetAsArrayBufferView().View()->deprecatedByteLengthAsUnsigned());
+ static_cast<wtf_size_t>(byte_length));
NDEFMessage* message = MakeGarbageCollected<NDEFMessage>();
message->records_.push_back(MakeGarbageCollected<NDEFRecord>(
- std::move(payload_data), "application/octet-stream"));
+ String() /* id */, "application/octet-stream",
+ std::move(payload_data)));
return message;
}
@@ -75,24 +100,101 @@ NDEFMessage* NDEFMessage::Create(const ExecutionContext* execution_context,
return nullptr;
}
+// static
+NDEFMessage* NDEFMessage::CreateAsPayloadOfSmartPoster(
+ const ExecutionContext* execution_context,
+ const NDEFMessageInit* init,
+ ExceptionState& exception_state) {
+ // NDEFMessageInit#records is a required field.
+ DCHECK(init->hasRecords());
+
+ NDEFMessage* payload_message = MakeGarbageCollected<NDEFMessage>();
+
+ bool has_url_record = false;
+ bool has_size_record = false;
+ bool has_type_record = false;
+ bool has_action_record = false;
+ for (const NDEFRecordInit* record_init : init->records()) {
+ const String& record_type = record_init->recordType();
+ if (record_type == "url") {
+ // The single mandatory url record.
+ if (has_url_record) {
+ exception_state.ThrowTypeError(
+ "'smart-poster' NDEFRecord contains more than one url record.");
+ return nullptr;
+ }
+ has_url_record = true;
+ } else if (record_type == ":s") {
+ // Zero or one size record.
+ if (has_size_record) {
+ exception_state.ThrowTypeError(
+ "'smart-poster' NDEFRecord contains more than one size record.");
+ return nullptr;
+ }
+ has_size_record = true;
+ } else if (record_type == ":t") {
+ // Zero or one type record.
+ if (has_type_record) {
+ exception_state.ThrowTypeError(
+ "'smart-poster' NDEFRecord contains more than one type record.");
+ return nullptr;
+ }
+ has_type_record = true;
+ } else if (record_type == ":act") {
+ // Zero or one action record.
+ if (has_action_record) {
+ exception_state.ThrowTypeError(
+ "'smart-poster' NDEFRecord contains more than one action record.");
+ return nullptr;
+ }
+ has_action_record = true;
+ } else {
+ // No restriction on other record types.
+ }
+ NDEFRecord* record = NDEFRecord::Create(
+ execution_context, record_init, exception_state, /*is_embedded=*/true);
+ if (exception_state.HadException())
+ return nullptr;
+ DCHECK(record);
+
+ if (record->recordType() == ":s" && record->payloadData().size() != 4) {
+ exception_state.ThrowTypeError(
+ "Size record of smart-poster must contain a 4-byte 32 bit unsigned "
+ "integer.");
+ return nullptr;
+ }
+ if (record->recordType() == ":act" && record->payloadData().size() != 1) {
+ exception_state.ThrowTypeError(
+ "Action record of smart-poster must contain only a single byte.");
+ return nullptr;
+ }
+
+ payload_message->records_.push_back(record);
+ }
+
+ if (!has_url_record) {
+ exception_state.ThrowTypeError(
+ "'smart-poster' NDEFRecord is missing the single mandatory url "
+ "record.");
+ return nullptr;
+ }
+
+ return payload_message;
+}
+
NDEFMessage::NDEFMessage() = default;
-NDEFMessage::NDEFMessage(const device::mojom::blink::NDEFMessage& message)
- : url_(message.url) {
+NDEFMessage::NDEFMessage(const device::mojom::blink::NDEFMessage& message) {
for (wtf_size_t i = 0; i < message.data.size(); ++i) {
records_.push_back(MakeGarbageCollected<NDEFRecord>(*message.data[i]));
}
}
-const String& NDEFMessage::url() const {
- return url_;
-}
-
const HeapVector<Member<NDEFRecord>>& NDEFMessage::records() const {
return records_;
}
-void NDEFMessage::Trace(blink::Visitor* visitor) {
+void NDEFMessage::Trace(Visitor* visitor) {
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 b8e9f70a84c..9a5f485e24c 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_message.h
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_message.h
@@ -9,7 +9,6 @@
#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/heap/handle.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -25,23 +24,27 @@ class MODULES_EXPORT NDEFMessage final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
+ // |is_embedded| indicates if this message serves as payload for a parent
+ // record.
static NDEFMessage* Create(const ExecutionContext*,
const NDEFMessageInit*,
- ExceptionState&);
+ ExceptionState&,
+ bool is_embedded = false);
static NDEFMessage* Create(const ExecutionContext*,
const NDEFMessageSource&,
ExceptionState&);
+ static NDEFMessage* CreateAsPayloadOfSmartPoster(const ExecutionContext*,
+ const NDEFMessageInit*,
+ ExceptionState&);
NDEFMessage();
explicit NDEFMessage(const device::mojom::blink::NDEFMessage&);
- const String& url() const;
const HeapVector<Member<NDEFRecord>>& records() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
- String url_;
HeapVector<Member<NDEFRecord>> records_;
};
diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_message.idl b/chromium/third_party/blink/renderer/modules/nfc/ndef_message.idl
index 4e0fc4987e6..557c97618bf 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_message.idl
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_message.idl
@@ -7,11 +7,8 @@
[
RuntimeEnabled=WebNFC,
SecureContext,
- Constructor(NDEFMessageInit messageInit),
- ConstructorCallWith=ExecutionContext,
- RaisesException=Constructor,
Exposed=Window
] interface NDEFMessage {
- readonly attribute USVString url;
+ [CallWith=ExecutionContext, RaisesException] constructor(NDEFMessageInit messageInit);
readonly attribute FrozenArray<NDEFRecord> records;
};
diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_message_init.idl b/chromium/third_party/blink/renderer/modules/nfc/ndef_message_init.idl
index d6b68ae6d5a..d078ff8747d 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_message_init.idl
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_message_init.idl
@@ -5,6 +5,5 @@
// https://w3c.github.io/web-nfc/#dom-ndefmessageinit
dictionary NDEFMessageInit {
- USVString url;
- sequence<NDEFRecordInit> records;
+ required sequence<NDEFRecordInit> 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 bd64e28e2ad..2147253e712 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.cc
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.cc
@@ -8,17 +8,22 @@
#include "services/device/public/mojom/nfc.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_ndef_scan_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/events/error_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/modules/event_target_modules.h"
-#include "third_party/blink/renderer/modules/nfc/ndef_error_event.h"
#include "third_party/blink/renderer/modules/nfc/ndef_message.h"
#include "third_party/blink/renderer/modules/nfc/ndef_reading_event.h"
-#include "third_party/blink/renderer/modules/nfc/ndef_scan_options.h"
#include "third_party/blink/renderer/modules/nfc/nfc_proxy.h"
#include "third_party/blink/renderer/modules/nfc/nfc_utils.h"
#include "third_party/blink/renderer/modules/permissions/permission_utils.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.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/kurl.h"
namespace blink {
@@ -29,10 +34,14 @@ using mojom::blink::PermissionStatus;
namespace {
+constexpr char kNotSupportedOrPermissionDenied[] =
+ "WebNFC feature is unavailable or permission denied.";
+
void OnScanRequestCompleted(ScriptPromiseResolver* resolver,
device::mojom::blink::NDEFErrorPtr error) {
if (error) {
- resolver->Reject(NDEFErrorTypeToDOMException(error->error_type));
+ resolver->Reject(
+ NDEFErrorTypeToDOMException(error->error_type, error->error_message));
return;
}
resolver->Resolve();
@@ -42,11 +51,14 @@ void OnScanRequestCompleted(ScriptPromiseResolver* resolver,
// static
NDEFReader* NDEFReader::Create(ExecutionContext* context) {
+ context->GetScheduler()->RegisterStickyFeature(
+ SchedulingPolicy::Feature::kWebNfc,
+ {SchedulingPolicy::RecordMetricsForBackForwardCache()});
return MakeGarbageCollected<NDEFReader>(context);
}
NDEFReader::NDEFReader(ExecutionContext* context)
- : ContextLifecycleObserver(context) {
+ : ExecutionContextLifecycleObserver(context) {
// Call GetNFCProxy to create a proxy. This guarantees no allocation will
// be needed when calling HasPendingActivity later during gc tracing.
GetNfcProxy();
@@ -59,7 +71,7 @@ const AtomicString& NDEFReader::InterfaceName() const {
}
ExecutionContext* NDEFReader::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
bool NDEFReader::HasPendingActivity() const {
@@ -72,7 +84,7 @@ ScriptPromise NDEFReader::scan(ScriptState* script_state,
const NDEFScanOptions* options,
ExceptionState& exception_state) {
ExecutionContext* execution_context = GetExecutionContext();
- Document* document = To<Document>(execution_context);
+ Document* document = Document::From(execution_context);
// https://w3c.github.io/web-nfc/#security-policies
// WebNFC API must be only accessible from top level browsing context.
if (!execution_context || !document->IsInMainFrame()) {
@@ -90,20 +102,6 @@ ScriptPromise NDEFReader::scan(ScriptState* script_state,
return ScriptPromise();
}
- // 9.4 If the reader.[[Id]] is not an empty string and it is not a valid URL
- // pattern, then reject p with a "SyntaxError" DOMException and return p.
- // TODO(https://crbug.com/520391): Instead of NDEFScanOptions#url, introduce
- // and use NDEFScanOptions#id to do the filtering after we add support for
- // writing NDEFRecord#id.
- if (options->hasId() && !options->id().IsEmpty()) {
- KURL pattern_url(options->id());
- if (!pattern_url.IsValid() || pattern_url.Protocol() != "https") {
- exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
- "Invalid URL pattern was provided.");
- return ScriptPromise();
- }
- }
-
// TODO(https://crbug.com/520391): With the note in
// https://w3c.github.io/web-nfc/#the-ndefreader-and-ndefwriter-objects,
// successive invocations of NDEFReader.scan() with new options should replace
@@ -157,17 +155,19 @@ void NDEFReader::OnRequestPermission(ScriptPromiseResolver* resolver,
}
UseCounter::Count(GetExecutionContext(), WebFeature::kWebNfcNdefReaderScan);
+ // TODO(https://crbug.com/994936) remove when origin trial is complete.
+ UseCounter::Count(GetExecutionContext(), WebFeature::kWebNfcAPI);
GetNfcProxy()->StartReading(
this, options,
WTF::Bind(&OnScanRequestCompleted, WrapPersistent(resolver)));
}
-void NDEFReader::Trace(blink::Visitor* visitor) {
+void NDEFReader::Trace(Visitor* visitor) {
visitor->Trace(resolver_);
EventTargetWithInlineData::Trace(visitor);
ActiveScriptWrappable::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
void NDEFReader::OnReading(const String& serial_number,
@@ -178,22 +178,25 @@ void NDEFReader::OnReading(const String& serial_number,
MakeGarbageCollected<NDEFMessage>(message)));
}
-void NDEFReader::OnError(device::mojom::blink::NDEFErrorType error) {
- DispatchEvent(*MakeGarbageCollected<NDEFErrorEvent>(
- event_type_names::kError, NDEFErrorTypeToDOMException(error)));
+void NDEFReader::OnError(const String& message) {
+ ErrorEvent* event = ErrorEvent::Create(
+ message, SourceLocation::Capture(GetExecutionContext()), nullptr);
+ DispatchEvent(*event);
}
void NDEFReader::OnMojoConnectionError() {
// If |resolver_| has already settled this rejection is silently ignored.
if (resolver_) {
resolver_->Reject(NDEFErrorTypeToDOMException(
- device::mojom::blink::NDEFErrorType::NOT_SUPPORTED));
+ device::mojom::blink::NDEFErrorType::NOT_SUPPORTED,
+ kNotSupportedOrPermissionDenied));
}
+
// Dispatches an error event.
- OnError(device::mojom::blink::NDEFErrorType::NOT_SUPPORTED);
+ OnError(kNotSupportedOrPermissionDenied);
}
-void NDEFReader::ContextDestroyed(ExecutionContext*) {
+void NDEFReader::ContextDestroyed() {
// If |resolver_| has already settled this rejection is silently ignored.
if (resolver_) {
resolver_->Reject(MakeGarbageCollected<DOMException>(
@@ -212,7 +215,7 @@ void NDEFReader::Abort(ScriptPromiseResolver* resolver) {
NFCProxy* NDEFReader::GetNfcProxy() const {
DCHECK(GetExecutionContext());
- return NFCProxy::From(*To<Document>(GetExecutionContext()));
+ return NFCProxy::From(*To<LocalDOMWindow>(GetExecutionContext()));
}
} // namespace blink
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 0e6f664c37f..224f9d3f7c8 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.h
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.h
@@ -11,7 +11,7 @@
#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/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -24,7 +24,7 @@ class ScriptPromiseResolver;
class MODULES_EXPORT NDEFReader : public EventTargetWithInlineData,
public ActiveScriptWrappable<NDEFReader>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(NDEFReader);
DEFINE_WRAPPERTYPEINFO();
@@ -45,19 +45,19 @@ class MODULES_EXPORT NDEFReader : public EventTargetWithInlineData,
DEFINE_ATTRIBUTE_EVENT_LISTENER(reading, kReading)
ScriptPromise scan(ScriptState*, const NDEFScanOptions*, ExceptionState&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// Called by NFCProxy for dispatching events.
virtual void OnReading(const String& serial_number,
const device::mojom::blink::NDEFMessage&);
- virtual void OnError(device::mojom::blink::NDEFErrorType);
+ virtual void OnError(const String& message);
// Called by NFCProxy for notification about connection error.
void OnMojoConnectionError();
private:
- // ContextLifecycleObserver overrides.
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver overrides.
+ void ContextDestroyed() override;
void Abort(ScriptPromiseResolver*);
diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.idl b/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.idl
index 3604095c1d0..280ebf5ac6e 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.idl
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.idl
@@ -8,10 +8,9 @@
RuntimeEnabled=WebNFC,
ActiveScriptWrappable,
SecureContext,
- Constructor(),
- ConstructorCallWith=ExecutionContext,
Exposed=Window
] interface NDEFReader : EventTarget {
+ [CallWith=ExecutionContext] constructor();
attribute EventHandler onreading;
attribute EventHandler onerror;
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 e2a1bbdc467..2035d5628d6 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
@@ -4,8 +4,8 @@
#include "third_party/blink/renderer/modules/nfc/ndef_reading_event.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_ndef_reading_event_init.h"
#include "third_party/blink/renderer/modules/nfc/ndef_message.h"
-#include "third_party/blink/renderer/modules/nfc/ndef_reading_event_init.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
namespace blink {
@@ -42,7 +42,7 @@ const AtomicString& NDEFReadingEvent::InterfaceName() const {
return event_interface_names::kNDEFReadingEvent;
}
-void NDEFReadingEvent::Trace(blink::Visitor* visitor) {
+void NDEFReadingEvent::Trace(Visitor* visitor) {
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 239437d17a3..6f7e5f8f463 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
const String& serialNumber() const;
NDEFMessage* message() const;
@@ -41,14 +41,6 @@ class NDEFReadingEvent final : public Event {
Member<NDEFMessage> message_;
};
-DEFINE_TYPE_CASTS(NDEFReadingEvent,
- Event,
- event,
- event->InterfaceName() ==
- event_interface_names::kNDEFReadingEvent,
- event.InterfaceName() ==
- event_interface_names::kNDEFReadingEvent);
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_NFC_NDEF_READING_EVENT_H_
diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.idl b/chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.idl
index 61e21cba7d9..84432047e6a 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.idl
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.idl
@@ -8,10 +8,9 @@
[
RuntimeEnabled=WebNFC,
SecureContext,
- Constructor(DOMString type, NDEFReadingEventInit eventInitDict),
- RaisesException=Constructor,
Exposed=Window
] interface NDEFReadingEvent : Event {
+ [RaisesException] constructor(DOMString type, NDEFReadingEventInit eventInitDict);
readonly attribute DOMString serialNumber;
[SameObject] readonly attribute NDEFMessage message;
};
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 aeb3e21fbee..6594a7d3aa9 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_record.cc
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_record.cc
@@ -8,17 +8,16 @@
#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/modules/v8/string_or_array_buffer_or_array_buffer_view_or_ndef_message_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_ndef_record_init.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/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_data_view.h"
#include "third_party/blink/renderer/modules/nfc/ndef_message.h"
-#include "third_party/blink/renderer/modules/nfc/ndef_record_init.h"
#include "third_party/blink/renderer/modules/nfc/nfc_utils.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/network/http_parsers.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/ascii_ctype.h"
#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
@@ -40,69 +39,104 @@ bool IsBufferSource(const NDEFRecordDataSource& data) {
return data.IsArrayBuffer() || data.IsArrayBufferView();
}
-WTF::Vector<uint8_t> GetBytesOfBufferSource(
- const NDEFRecordDataSource& buffer_source) {
+bool GetBytesOfBufferSource(const NDEFRecordDataSource& buffer_source,
+ WTF::Vector<uint8_t>* target,
+ ExceptionState& exception_state) {
DCHECK(IsBufferSource(buffer_source));
- WTF::Vector<uint8_t> bytes;
+ uint8_t* data;
+ size_t data_length;
if (buffer_source.IsArrayBuffer()) {
DOMArrayBuffer* array_buffer = buffer_source.GetAsArrayBuffer();
- bytes.Append(static_cast<uint8_t*>(array_buffer->Data()),
- array_buffer->DeprecatedByteLengthAsUnsigned());
+ data = reinterpret_cast<uint8_t*>(array_buffer->Data());
+ data_length = array_buffer->ByteLengthAsSizeT();
} else if (buffer_source.IsArrayBufferView()) {
const DOMArrayBufferView* array_buffer_view =
buffer_source.GetAsArrayBufferView().View();
- bytes.Append(static_cast<uint8_t*>(array_buffer_view->BaseAddress()),
- array_buffer_view->deprecatedByteLengthAsUnsigned());
+ data = reinterpret_cast<uint8_t*>(array_buffer_view->BaseAddress());
+ data_length = array_buffer_view->byteLengthAsSizeT();
} else {
NOTREACHED();
+ return false;
+ }
+ wtf_size_t checked_length;
+ if (!base::CheckedNumeric<wtf_size_t>(data_length)
+ .AssignIfValid(&checked_length)) {
+ exception_state.ThrowRangeError(
+ "The provided buffer source exceeds the maximum supported length");
+ return false;
}
- return bytes;
+ target->Append(data, checked_length);
+ return true;
}
-// https://w3c.github.io/web-nfc/#ndef-record-types
-// Derives a formatted custom type for the external type record from |input|.
-// Returns a null string for an invalid |input|.
-//
-// TODO(https://crbug.com/520391): Refine the validation algorithm here
-// accordingly once there is a conclusion on some case-sensitive things at
-// https://github.com/w3c/web-nfc/issues/331.
-String ValidateCustomRecordType(const String& input) {
- static const String kOtherCharsForCustomType("()+,-:=@;$_!*'.");
+// https://w3c.github.io/web-nfc/#dfn-validate-external-type
+// Validates |input| as an external type.
+bool IsValidExternalType(const String& input) {
+ static const String kOtherCharsForCustomType(":!()+,-=@;$_*'.");
+
+ // Ensure |input| is an ASCII string.
+ if (!input.ContainsOnlyASCIIOrEmpty())
+ return false;
- if (input.IsEmpty())
- return String();
+ // As all characters in |input| is ASCII, limiting its length within 255 just
+ // limits the length of its utf-8 encoded bytes we finally write into the
+ // record payload.
+ if (input.IsEmpty() || input.length() > 255)
+ return false;
- // Finds the separator ':'.
+ // Finds the first occurrence of ':'.
wtf_size_t colon_index = input.find(':');
if (colon_index == kNotFound)
- return String();
-
- // Derives the domain (FQDN) from the part before ':'.
- String left = input.Left(colon_index);
- bool success = false;
- String domain = SecurityOrigin::CanonicalizeHost(left, &success);
- if (!success || domain.IsEmpty())
- return String();
-
- // Validates the part after ':'.
- String right = input.Substring(colon_index + 1);
- if (right.length() == 0)
- return String();
- for (wtf_size_t i = 0; i < right.length(); i++) {
- if (!IsASCIIAlphanumeric(right[i]) &&
- !kOtherCharsForCustomType.Contains(right[i])) {
- return String();
+ return false;
+
+ // Validates the domain (the part before ':').
+ String domain = input.Left(colon_index);
+ if (domain.IsEmpty())
+ return false;
+ // TODO(https://crbug.com/520391): Validate |domain|.
+
+ // Validates the type (the part after ':').
+ String type = input.Substring(colon_index + 1);
+ if (type.IsEmpty())
+ return false;
+ for (wtf_size_t i = 0; i < type.length(); i++) {
+ if (!IsASCIIAlphanumeric(type[i]) &&
+ !kOtherCharsForCustomType.Contains(type[i])) {
+ return false;
}
}
- return domain + ':' + right;
+ return true;
+}
+
+// https://w3c.github.io/web-nfc/#dfn-validate-local-type
+// Validates |input| as an local type.
+bool IsValidLocalType(const String& input) {
+ // Ensure |input| is an ASCII string.
+ if (!input.ContainsOnlyASCIIOrEmpty())
+ return false;
+
+ // The prefix ':' will be omitted when we actually write the record type into
+ // the nfc tag. We're taking it into consideration for validating the length
+ // here.
+ if (input.length() < 2 || input.length() > 256)
+ return false;
+ if (input[0] != ':')
+ return false;
+ if (!IsASCIILower(input[1]) && !IsASCIIDigit(input[1]))
+ return false;
+
+ // TODO(https://crbug.com/520391): Validate |input| is not equal to the record
+ // type of any NDEF record defined in its containing NDEF message.
+
+ return true;
}
String getDocumentLanguage(const ExecutionContext* execution_context) {
DCHECK(execution_context);
String document_language;
Element* document_element =
- To<Document>(execution_context)->documentElement();
+ Document::From(execution_context)->documentElement();
if (document_element) {
document_language = document_element->getAttribute(html_names::kLangAttr);
}
@@ -112,7 +146,8 @@ String getDocumentLanguage(const ExecutionContext* execution_context) {
return document_language;
}
-static NDEFRecord* CreateTextRecord(const ExecutionContext* execution_context,
+static NDEFRecord* CreateTextRecord(const String& id,
+ const ExecutionContext* execution_context,
const String& encoding,
const String& lang,
const NDEFRecordDataSource& data,
@@ -134,34 +169,43 @@ static NDEFRecord* CreateTextRecord(const ExecutionContext* execution_context,
// Bits 0 to 5 define the length of the language tag
// https://w3c.github.io/web-nfc/#text-record
if (language.length() > 63) {
- exception_state.ThrowTypeError("Lang length cannot be stored in 6 bit.");
- return nullptr;
- }
-
- String encoding_label = !encoding.IsEmpty() ? encoding : "utf-8";
- if (encoding_label != "utf-8" && encoding_label != "utf-16" &&
- encoding_label != "utf-16be" && encoding_label != "utf-16le") {
- exception_state.ThrowTypeError(
- "Encoding must be either \"utf-8\", \"utf-16\", \"utf-16be\", or "
- "\"utf-16le\".");
+ exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
+ "Lang length cannot be stored in 6 bit.");
return nullptr;
}
+ String encoding_label = encoding.IsNull() ? "utf-8" : encoding;
WTF::Vector<uint8_t> bytes;
if (data.IsString()) {
+ if (encoding_label != "utf-8") {
+ exception_state.ThrowTypeError(
+ "A DOMString data source is always encoded as \"utf-8\" so other "
+ "encodings are not allowed.");
+ return nullptr;
+ }
StringUTF8Adaptor utf8_string(data.GetAsString());
bytes.Append(utf8_string.data(), utf8_string.size());
} else {
DCHECK(IsBufferSource(data));
- bytes = GetBytesOfBufferSource(data);
+ if (encoding_label != "utf-8" && encoding_label != "utf-16" &&
+ encoding_label != "utf-16be" && encoding_label != "utf-16le") {
+ exception_state.ThrowTypeError(
+ "Encoding must be either \"utf-8\", \"utf-16\", \"utf-16be\", or "
+ "\"utf-16le\".");
+ return nullptr;
+ }
+ if (!GetBytesOfBufferSource(data, &bytes, exception_state)) {
+ return nullptr;
+ }
}
- return MakeGarbageCollected<NDEFRecord>("text", encoding_label, language,
+ return MakeGarbageCollected<NDEFRecord>(id, encoding_label, language,
std::move(bytes));
}
// Create a 'url' record or an 'absolute-url' record.
static NDEFRecord* CreateUrlRecord(const String& record_type,
+ const String& id,
const NDEFRecordDataSource& data,
ExceptionState& exception_state) {
// https://w3c.github.io/web-nfc/#mapping-url-to-ndef
@@ -178,11 +222,13 @@ static NDEFRecord* CreateUrlRecord(const String& record_type,
"Cannot parse data for url record.");
return nullptr;
}
- return MakeGarbageCollected<NDEFRecord>(record_type,
- GetUTF8DataFromString(url));
+ return MakeGarbageCollected<NDEFRecord>(
+ device::mojom::blink::NDEFRecordTypeCategory::kStandardized, record_type,
+ id, GetUTF8DataFromString(url));
}
-static NDEFRecord* CreateMimeRecord(const NDEFRecordDataSource& data,
+static NDEFRecord* CreateMimeRecord(const String& id,
+ const NDEFRecordDataSource& data,
const String& media_type,
ExceptionState& exception_state) {
// https://w3c.github.io/web-nfc/#mapping-binary-data-to-ndef
@@ -192,11 +238,22 @@ static NDEFRecord* CreateMimeRecord(const NDEFRecordDataSource& data,
return nullptr;
}
- return MakeGarbageCollected<NDEFRecord>(GetBytesOfBufferSource(data),
- media_type);
+ 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()) {
+ mime_type = "application/octet-stream";
+ }
+
+ return MakeGarbageCollected<NDEFRecord>(id, mime_type, bytes);
}
-static NDEFRecord* CreateUnknownRecord(const NDEFRecordDataSource& data,
+static NDEFRecord* CreateUnknownRecord(const String& id,
+ const NDEFRecordDataSource& data,
ExceptionState& exception_state) {
if (!IsBufferSource(data)) {
exception_state.ThrowTypeError(
@@ -204,25 +261,101 @@ static NDEFRecord* CreateUnknownRecord(const NDEFRecordDataSource& data,
return nullptr;
}
- return MakeGarbageCollected<NDEFRecord>("unknown",
- GetBytesOfBufferSource(data));
+ WTF::Vector<uint8_t> bytes;
+ if (!GetBytesOfBufferSource(data, &bytes, exception_state)) {
+ return nullptr;
+ }
+ return MakeGarbageCollected<NDEFRecord>(
+ device::mojom::blink::NDEFRecordTypeCategory::kStandardized, "unknown",
+ id, bytes);
}
-static NDEFRecord* CreateExternalRecord(const String& custom_type,
- const NDEFRecordDataSource& data,
- ExceptionState& exception_state) {
- // TODO(https://crbug.com/520391): Add support in case of |data| being an
- // NDEFMessageInit.
-
- // https://w3c.github.io/web-nfc/#dfn-map-external-data-to-ndef
- if (!IsBufferSource(data)) {
+static NDEFRecord* CreateSmartPosterRecord(
+ const ExecutionContext* execution_context,
+ const String& id,
+ const NDEFRecordDataSource& data,
+ ExceptionState& exception_state) {
+ // https://w3c.github.io/web-nfc/#dfn-map-smart-poster-to-ndef
+ if (!data.IsNDEFMessageInit()) {
exception_state.ThrowTypeError(
- "The data for external type NDEFRecord must be a BufferSource.");
+ "The data for 'smart-poster' NDEFRecord must be an NDEFMessageInit.");
+ return nullptr;
+ }
+
+ NDEFMessage* payload_message = NDEFMessage::CreateAsPayloadOfSmartPoster(
+ execution_context, data.GetAsNDEFMessageInit(), exception_state);
+ if (exception_state.HadException())
return nullptr;
+ DCHECK(payload_message);
+
+ return MakeGarbageCollected<NDEFRecord>(
+ device::mojom::blink::NDEFRecordTypeCategory::kStandardized,
+ "smart-poster", id, payload_message);
+}
+
+static NDEFRecord* CreateExternalRecord(
+ const ExecutionContext* execution_context,
+ const String& record_type,
+ const String& id,
+ const NDEFRecordDataSource& data,
+ ExceptionState& exception_state) {
+ // https://w3c.github.io/web-nfc/#dfn-map-external-data-to-ndef
+ if (IsBufferSource(data)) {
+ WTF::Vector<uint8_t> bytes;
+ if (!GetBytesOfBufferSource(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);
+ if (exception_state.HadException())
+ return nullptr;
+ DCHECK(payload_message);
+ return MakeGarbageCollected<NDEFRecord>(
+ device::mojom::blink::NDEFRecordTypeCategory::kExternal, record_type,
+ id, payload_message);
+ }
+
+ exception_state.ThrowTypeError(
+ "The data for external type NDEFRecord must be a BufferSource or an "
+ "NDEFMessageInit.");
+ return nullptr;
+}
+
+static NDEFRecord* CreateLocalRecord(const ExecutionContext* execution_context,
+ const String& record_type,
+ const String& id,
+ const NDEFRecordDataSource& data,
+ ExceptionState& exception_state) {
+ // https://w3c.github.io/web-nfc/#dfn-map-local-type-to-ndef
+ if (IsBufferSource(data)) {
+ WTF::Vector<uint8_t> bytes;
+ if (!GetBytesOfBufferSource(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);
+ if (exception_state.HadException())
+ return nullptr;
+ DCHECK(payload_message);
+ return MakeGarbageCollected<NDEFRecord>(
+ device::mojom::blink::NDEFRecordTypeCategory::kLocal, record_type, id,
+ payload_message);
}
- return MakeGarbageCollected<NDEFRecord>(custom_type,
- GetBytesOfBufferSource(data));
+ exception_state.ThrowTypeError(
+ "The data for local type NDEFRecord must be a BufferSource or an "
+ "NDEFMessageInit.");
+ return nullptr;
}
} // namespace
@@ -230,22 +363,13 @@ static NDEFRecord* CreateExternalRecord(const String& custom_type,
// static
NDEFRecord* NDEFRecord::Create(const ExecutionContext* execution_context,
const NDEFRecordInit* init,
- ExceptionState& exception_state) {
- // https://w3c.github.io/web-nfc/#creating-web-nfc-message
- String record_type;
- if (!init->hasRecordType()) {
- if (!init->hasData()) {
- exception_state.ThrowTypeError("The record has neither type nor data.");
- return nullptr;
- }
- if (init->data().IsString()) {
- record_type = "text";
- } else {
- record_type = "mime";
- }
- } else {
- record_type = init->recordType();
- }
+ 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();
// https://w3c.github.io/web-nfc/#dom-ndefrecordinit-mediatype
if (init->hasMediaType() && record_type != "mime") {
@@ -254,93 +378,131 @@ NDEFRecord* NDEFRecord::Create(const ExecutionContext* execution_context,
return nullptr;
}
- NDEFRecord* instance = nullptr;
+ // https://w3c.github.io/web-nfc/#dfn-map-empty-record-to-ndef
+ if (init->hasId() && record_type == "empty") {
+ exception_state.ThrowTypeError(
+ "NDEFRecordInit#id is not applicable for 'empty' records.");
+ return nullptr;
+ }
+
if (record_type == "empty") {
// https://w3c.github.io/web-nfc/#mapping-empty-record-to-ndef
- instance =
- MakeGarbageCollected<NDEFRecord>(record_type, WTF::Vector<uint8_t>());
+ return MakeGarbageCollected<NDEFRecord>(
+ device::mojom::blink::NDEFRecordTypeCategory::kStandardized,
+ record_type, init->id(), WTF::Vector<uint8_t>());
} else if (record_type == "text") {
- instance = CreateTextRecord(execution_context, init->encoding(),
- init->lang(), init->data(), exception_state);
+ return CreateTextRecord(init->id(), execution_context, init->encoding(),
+ init->lang(), init->data(), exception_state);
} else if (record_type == "url" || record_type == "absolute-url") {
- instance = CreateUrlRecord(record_type, init->data(), exception_state);
+ return CreateUrlRecord(record_type, init->id(), init->data(),
+ exception_state);
} else if (record_type == "mime") {
- instance =
- CreateMimeRecord(init->data(), init->mediaType(), exception_state);
+ return CreateMimeRecord(init->id(), init->data(), init->mediaType(),
+ exception_state);
} else if (record_type == "unknown") {
- instance = CreateUnknownRecord(init->data(), exception_state);
+ return CreateUnknownRecord(init->id(), init->data(), exception_state);
} else if (record_type == "smart-poster") {
- // TODO(https://crbug.com/520391): Support creating smart-poster records.
- exception_state.ThrowTypeError("smart-poster type is not supported yet");
- return nullptr;
- } else {
- // TODO(https://crbug.com/520391): Here |record_type| may be a custom type
- // name for an external type record, or a local type name for an external
- // type record embedded within a ndef message as payload of a parent record,
- // in either case we should try to create an external type record from
- // |data|.
- String formated_type = ValidateCustomRecordType(record_type);
- if (formated_type.IsNull()) {
- exception_state.ThrowTypeError("Invalid NDEFRecord type.");
+ return CreateSmartPosterRecord(execution_context, init->id(), init->data(),
+ exception_state);
+ } else if (IsValidExternalType(record_type)) {
+ return CreateExternalRecord(execution_context, record_type, init->id(),
+ init->data(), exception_state);
+ } else if (IsValidLocalType(record_type)) {
+ if (!is_embedded) {
+ exception_state.ThrowTypeError(
+ "Local type records are only supposed to be embedded in the payload "
+ "of another record (smart-poster, external, or local).");
return nullptr;
}
- instance =
- CreateExternalRecord(formated_type, init->data(), exception_state);
+ return CreateLocalRecord(execution_context, record_type, init->id(),
+ init->data(), exception_state);
}
- if (instance && init->hasId()) {
- instance->id_ = init->id();
- }
- return instance;
+ exception_state.ThrowTypeError("Invalid NDEFRecord type.");
+ return nullptr;
}
-NDEFRecord::NDEFRecord(const String& record_type,
+NDEFRecord::NDEFRecord(device::mojom::blink::NDEFRecordTypeCategory category,
+ const String& record_type,
+ const String& id,
WTF::Vector<uint8_t> data)
- : record_type_(record_type),
- payload_data_(std::move(data)) {}
+ : category_(category),
+ record_type_(record_type),
+ id_(id),
+ payload_data_(std::move(data)) {
+ DCHECK_EQ(
+ category_ == device::mojom::blink::NDEFRecordTypeCategory::kExternal,
+ IsValidExternalType(record_type_));
+ DCHECK_EQ(category_ == device::mojom::blink::NDEFRecordTypeCategory::kLocal,
+ IsValidLocalType(record_type_));
+}
-NDEFRecord::NDEFRecord(const String& record_type,
+NDEFRecord::NDEFRecord(device::mojom::blink::NDEFRecordTypeCategory category,
+ const String& record_type,
+ const String& id,
+ NDEFMessage* payload_message)
+ : category_(category),
+ record_type_(record_type),
+ id_(id),
+ payload_message_(payload_message) {
+ DCHECK(record_type_ == "smart-poster" ||
+ category_ == device::mojom::blink::NDEFRecordTypeCategory::kExternal ||
+ category_ == device::mojom::blink::NDEFRecordTypeCategory::kLocal);
+ DCHECK_EQ(
+ category_ == device::mojom::blink::NDEFRecordTypeCategory::kExternal,
+ IsValidExternalType(record_type_));
+ DCHECK_EQ(category_ == device::mojom::blink::NDEFRecordTypeCategory::kLocal,
+ IsValidLocalType(record_type_));
+}
+
+NDEFRecord::NDEFRecord(const String& id,
const String& encoding,
const String& lang,
WTF::Vector<uint8_t> data)
- : record_type_(record_type),
+ : category_(device::mojom::blink::NDEFRecordTypeCategory::kStandardized),
+ record_type_("text"),
+ id_(id),
encoding_(encoding),
lang_(lang),
payload_data_(std::move(data)) {}
NDEFRecord::NDEFRecord(const ExecutionContext* execution_context,
const String& text)
- : record_type_("text"),
+ : category_(device::mojom::blink::NDEFRecordTypeCategory::kStandardized),
+ record_type_("text"),
encoding_("utf-8"),
lang_(getDocumentLanguage(execution_context)),
payload_data_(GetUTF8DataFromString(text)) {}
-NDEFRecord::NDEFRecord(WTF::Vector<uint8_t> payload_data,
- const String& media_type)
- : record_type_("mime"), payload_data_(std::move(payload_data)) {
- // ExtractMIMETypeFromMediaType() ignores parameters of the MIME type.
- media_type_ = ExtractMIMETypeFromMediaType(AtomicString(media_type));
- if (media_type_.IsEmpty()) {
- media_type_ = "application/octet-stream";
- }
-}
+NDEFRecord::NDEFRecord(const String& id,
+ const String& media_type,
+ WTF::Vector<uint8_t> data)
+ : category_(device::mojom::blink::NDEFRecordTypeCategory::kStandardized),
+ record_type_("mime"),
+ id_(id),
+ media_type_(media_type),
+ payload_data_(std::move(data)) {}
+// Even if |record| is for a local type record, here we do not validate if it's
+// in the context of a parent record but just expose to JS as is.
NDEFRecord::NDEFRecord(const device::mojom::blink::NDEFRecord& record)
- : record_type_(record.record_type),
- media_type_(record.media_type),
+ : category_(record.category),
+ record_type_(record.record_type),
id_(record.id),
+ media_type_(record.media_type),
encoding_(record.encoding),
lang_(record.lang),
- payload_data_(record.data) {
+ payload_data_(record.data),
+ payload_message_(
+ record.payload_message
+ ? MakeGarbageCollected<NDEFMessage>(*record.payload_message)
+ : nullptr) {
DCHECK_NE(record_type_ == "mime", media_type_.IsNull());
- if (record.payload_message) {
- payload_message_ =
- MakeGarbageCollected<NDEFMessage>(*record.payload_message);
- }
-}
-
-const String& NDEFRecord::recordType() const {
- return record_type_;
+ DCHECK_EQ(
+ category_ == device::mojom::blink::NDEFRecordTypeCategory::kExternal,
+ IsValidExternalType(record_type_));
+ DCHECK_EQ(category_ == device::mojom::blink::NDEFRecordTypeCategory::kLocal,
+ IsValidLocalType(record_type_));
}
const String& NDEFRecord::mediaType() const {
@@ -348,36 +510,26 @@ const String& NDEFRecord::mediaType() const {
return media_type_;
}
-const String& NDEFRecord::id() const {
- return id_;
-}
-
-const String& NDEFRecord::encoding() const {
- return encoding_;
-}
-
-const String& NDEFRecord::lang() const {
- return lang_;
-}
-
DOMDataView* NDEFRecord::data() const {
+ // Step 4 in https://w3c.github.io/web-nfc/#dfn-parse-an-ndef-record
+ if (record_type_ == "empty") {
+ DCHECK(payload_data_.IsEmpty());
+ return nullptr;
+ }
DOMArrayBuffer* dom_buffer =
DOMArrayBuffer::Create(payload_data_.data(), payload_data_.size());
return DOMDataView::Create(dom_buffer, 0, payload_data_.size());
}
-const WTF::Vector<uint8_t>& NDEFRecord::payloadData() const {
- return payload_data_;
-}
-
// https://w3c.github.io/web-nfc/#dfn-convert-ndefrecord-payloaddata-bytes
base::Optional<HeapVector<Member<NDEFRecord>>> NDEFRecord::toRecords(
ExceptionState& exception_state) const {
if (record_type_ != "smart-poster" &&
- ValidateCustomRecordType(record_type_).IsNull()) {
+ category_ != device::mojom::blink::NDEFRecordTypeCategory::kExternal &&
+ category_ != device::mojom::blink::NDEFRecordTypeCategory::kLocal) {
exception_state.ThrowDOMException(
DOMExceptionCode::kNotSupportedError,
- "Only smart-poster records and external type records could have a ndef "
+ "Only {smart-poster, external, local} type records could have a ndef "
"message as payload.");
return base::nullopt;
}
@@ -388,11 +540,7 @@ base::Optional<HeapVector<Member<NDEFRecord>>> NDEFRecord::toRecords(
return payload_message_->records();
}
-const NDEFMessage* NDEFRecord::payload_message() const {
- return payload_message_.Get();
-}
-
-void NDEFRecord::Trace(blink::Visitor* visitor) {
+void NDEFRecord::Trace(Visitor* visitor) {
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 57611a3c32b..ab00de43d6b 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_record.h
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_record.h
@@ -24,50 +24,73 @@ class MODULES_EXPORT NDEFRecord final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
+ // |is_embedded| indicates if this record is within the context of a parent
+ // record.
static NDEFRecord* Create(const ExecutionContext*,
const NDEFRecordInit*,
- ExceptionState&);
+ ExceptionState&,
+ bool is_embedded = false);
- // Construct a "text" record from a string.
+ explicit NDEFRecord(device::mojom::NDEFRecordTypeCategory,
+ const String& record_type,
+ const String& id,
+ WTF::Vector<uint8_t>);
+
+ // For constructing a "smart-poster", an external type or a local type record
+ // whose payload is an NDEF message.
+ explicit NDEFRecord(device::mojom::NDEFRecordTypeCategory,
+ const String& record_type,
+ const String& id,
+ NDEFMessage*);
+
+ // Only for constructing "text" type record. The type category will be
+ // device::mojom::NDEFRecordTypeCategory::kStandardized.
+ explicit NDEFRecord(const String& id,
+ const String& encoding,
+ const String& lang,
+ WTF::Vector<uint8_t>);
+
+ // Only for constructing "text" type record from just a text. The type
+ // category will be device::mojom::NDEFRecordTypeCategory::kStandardized.
+ // Called by NDEFMessage.
explicit NDEFRecord(const ExecutionContext*, const String&);
- // Construct a "mime" record from the raw payload bytes.
- explicit NDEFRecord(WTF::Vector<uint8_t> /* payload_data */,
- const String& /* media_type */);
+ // Only for constructing "mime" type record. The type category will be
+ // device::mojom::NDEFRecordTypeCategory::kStandardized.
+ explicit NDEFRecord(const String& id,
+ const String& media_type,
+ WTF::Vector<uint8_t>);
- NDEFRecord(const String& /* record_type */, WTF::Vector<uint8_t> /* data */);
- NDEFRecord(const String& /* record_type */,
- const String& /* encoding */,
- const String& /* lang */,
- WTF::Vector<uint8_t> /* data */);
explicit NDEFRecord(const device::mojom::blink::NDEFRecord&);
- const String& recordType() const;
+ const String& recordType() const { return record_type_; }
const String& mediaType() const;
- const String& id() const;
- const String& encoding() const;
- const String& lang() const;
+ const String& id() const { return id_; }
+ const String& encoding() const { return encoding_; }
+ const String& lang() const { return lang_; }
DOMDataView* data() const;
base::Optional<HeapVector<Member<NDEFRecord>>> toRecords(
ExceptionState& exception_state) const;
- const WTF::Vector<uint8_t>& payloadData() const;
- const NDEFMessage* payload_message() const;
+ device::mojom::NDEFRecordTypeCategory category() const { return category_; }
+ const WTF::Vector<uint8_t>& payloadData() const { return payload_data_; }
+ const NDEFMessage* payload_message() const { return payload_message_.Get(); }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
- String record_type_;
- String media_type_;
- String id_;
- String encoding_;
- String lang_;
+ const device::mojom::NDEFRecordTypeCategory category_;
+ const String record_type_;
+ const String id_;
+ const String media_type_;
+ const String encoding_;
+ const String lang_;
// Holds the NDEFRecord.[[PayloadData]] bytes defined at
// https://w3c.github.io/web-nfc/#the-ndefrecord-interface.
- WTF::Vector<uint8_t> payload_data_;
+ const WTF::Vector<uint8_t> payload_data_;
// |payload_data_| parsed as an NDEFMessage. This field will be set for some
- // "smart-poster" and external type records.
- Member<NDEFMessage> payload_message_;
+ // "smart-poster", external, and local type records.
+ const Member<NDEFMessage> payload_message_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_record.idl b/chromium/third_party/blink/renderer/modules/nfc/ndef_record.idl
index 03e2a95e34e..0d6af2eb1e6 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_record.idl
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_record.idl
@@ -7,11 +7,9 @@
[
RuntimeEnabled=WebNFC,
SecureContext,
- Constructor(NDEFRecordInit recordInit),
- ConstructorCallWith=ExecutionContext,
- RaisesException=Constructor,
Exposed=Window
] interface NDEFRecord {
+ [CallWith=ExecutionContext, RaisesException] constructor(NDEFRecordInit recordInit);
readonly attribute USVString recordType;
readonly attribute USVString? mediaType;
readonly attribute USVString? id;
diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_record_init.idl b/chromium/third_party/blink/renderer/modules/nfc/ndef_record_init.idl
index 110ae70c590..135130b0370 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_record_init.idl
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_record_init.idl
@@ -4,16 +4,12 @@
// https://w3c.github.io/web-nfc/#idl-def-ndefrecorddatasource
-// The bindings generator does not support "typedef in union".
-// Must be (DOMString or BufferSource or NDEFMessageInit).
-// TODO(http://crbug.com/1019126): Support nested typedef in Web IDLs.
-typedef (DOMString or ArrayBuffer or ArrayBufferView or NDEFMessageInit)
- NDEFRecordDataSource;
+typedef (DOMString or BufferSource or NDEFMessageInit) NDEFRecordDataSource;
// https://w3c.github.io/web-nfc/#dom-ndefrecordinit
dictionary NDEFRecordInit {
- USVString recordType;
+ required USVString recordType;
USVString mediaType;
USVString id;
diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_scan_options.idl b/chromium/third_party/blink/renderer/modules/nfc/ndef_scan_options.idl
index e6fb5530e4f..cf20cf59f6d 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_scan_options.idl
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_scan_options.idl
@@ -4,8 +4,8 @@
// https://w3c.github.io/web-nfc/#the-ndefscanoptions-dictionary
dictionary NDEFScanOptions {
- AbortSignal? signal;
- USVString id = "";
+ USVString id;
USVString recordType;
- USVString mediaType = "";
+ USVString mediaType;
+ AbortSignal? signal;
};
diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_push_options.idl b/chromium/third_party/blink/renderer/modules/nfc/ndef_write_options.idl
index 9290a9cb9ee..81fe17b1b31 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_push_options.idl
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_write_options.idl
@@ -2,12 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://w3c.github.io/web-nfc/#the-ndefpushoptions-dictionary
+// https://w3c.github.io/web-nfc/#the-ndefwriteoptions-dictionary
-enum NDEFPushTarget { "tag", "peer", "any" };
-
-dictionary NDEFPushOptions {
- NDEFPushTarget target = "any";
+dictionary NDEFWriteOptions {
boolean ignoreRead = true;
+ boolean overwrite = true;
AbortSignal? signal;
};
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 bd8654657f1..5c3503e9dfc 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.cc
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.cc
@@ -9,14 +9,19 @@
#include "mojo/public/cpp/bindings/callback_helpers.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/modules/v8/string_or_array_buffer_or_array_buffer_view_or_ndef_message_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_ndef_write_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/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
-#include "third_party/blink/renderer/modules/nfc/ndef_push_options.h"
+#include "third_party/blink/renderer/modules/nfc/ndef_message.h"
#include "third_party/blink/renderer/modules/nfc/nfc_type_converters.h"
#include "third_party/blink/renderer/modules/nfc/nfc_utils.h"
#include "third_party/blink/renderer/modules/permissions/permission_utils.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/scheduler/public/frame_scheduler.h"
+#include "third_party/blink/renderer/platform/scheduler/public/scheduling_policy.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
namespace blink {
@@ -27,80 +32,58 @@ using mojom::blink::PermissionStatus;
// static
NDEFWriter* NDEFWriter::Create(ExecutionContext* context) {
+ context->GetScheduler()->RegisterStickyFeature(
+ blink::SchedulingPolicy::Feature::kWebNfc,
+ {blink::SchedulingPolicy::RecordMetricsForBackForwardCache()});
return MakeGarbageCollected<NDEFWriter>(context);
}
-NDEFWriter::NDEFWriter(ExecutionContext* context) : ContextClient(context) {}
+NDEFWriter::NDEFWriter(ExecutionContext* context)
+ : ExecutionContextClient(context) {}
-void NDEFWriter::Trace(blink::Visitor* visitor) {
+void NDEFWriter::Trace(Visitor* visitor) {
visitor->Trace(nfc_proxy_);
visitor->Trace(requests_);
ScriptWrappable::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
-// https://w3c.github.io/web-nfc/#writing-or-pushing-content
-// https://w3c.github.io/web-nfc/#the-push-method
-ScriptPromise NDEFWriter::push(ScriptState* script_state,
- const NDEFMessageSource& push_message,
- const NDEFPushOptions* options,
- ExceptionState& exception_state) {
+// https://w3c.github.io/web-nfc/#writing-content
+// https://w3c.github.io/web-nfc/#the-write-method
+ScriptPromise NDEFWriter::write(ScriptState* script_state,
+ const NDEFMessageSource& write_message,
+ const NDEFWriteOptions* options,
+ ExceptionState& exception_state) {
ExecutionContext* execution_context = GetExecutionContext();
- Document* document = To<Document>(execution_context);
+ Document* document = Document::From(execution_context);
// https://w3c.github.io/web-nfc/#security-policies
// WebNFC API must be only accessible from top level browsing context.
if (!execution_context || !document->IsInMainFrame()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotAllowedError,
- "NFC interfaces are only avaliable "
- "in a top-level browsing context"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kNotAllowedError,
+ "NFC interfaces are only avaliable "
+ "in a top-level browsing context");
+ return ScriptPromise();
}
if (options->hasSignal() && options->signal()->aborted()) {
// If signal’s aborted flag is set, then reject p with an "AbortError"
// DOMException and return p.
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError,
- "The NFC operation was cancelled."));
+ exception_state.ThrowDOMException(DOMExceptionCode::kAbortError,
+ "The NFC operation was cancelled.");
+ return ScriptPromise();
}
- // Step 10.10.1: Run "create NDEF message", if this throws an exception,
+ // Step 11.2: Run "create NDEF message", if this throws an exception,
// reject p with that exception and abort these steps.
NDEFMessage* ndef_message =
- NDEFMessage::Create(execution_context, push_message, exception_state);
+ NDEFMessage::Create(execution_context, write_message, exception_state);
if (exception_state.HadException()) {
return ScriptPromise();
}
- // If NDEFMessage.records is empty, reject promise with TypeError
- if (ndef_message->records().size() == 0) {
- return ScriptPromise::Reject(
- script_state,
- V8ThrowException::CreateTypeError(script_state->GetIsolate(),
- "Empty NDEFMessage was provided."));
- }
-
auto message = device::mojom::blink::NDEFMessage::From(ndef_message);
DCHECK(message);
- if (!SetNDEFMessageURL(execution_context->GetSecurityOrigin()->ToString(),
- message.get())) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kSyntaxError,
- "Cannot set WebNFC Id."));
- }
-
- if (GetNDEFMessageSize(*message) >
- device::mojom::blink::NDEFMessage::kMaxSize) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotSupportedError,
- "NDEFMessage exceeds maximum supported size."));
- }
-
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
requests_.insert(resolver);
InitNfcProxyIfNeeded();
@@ -125,7 +108,7 @@ PermissionService* NDEFWriter::GetPermissionService() {
void NDEFWriter::OnRequestPermission(
ScriptPromiseResolver* resolver,
- const NDEFPushOptions* options,
+ const NDEFWriteOptions* options,
device::mojom::blink::NDEFMessagePtr message,
PermissionStatus status) {
if (status != PermissionStatus::GRANTED) {
@@ -142,28 +125,30 @@ void NDEFWriter::OnRequestPermission(
// If signal is not null, then add the abort steps to signal.
if (options->hasSignal() && !options->signal()->aborted()) {
- options->signal()->AddAlgorithm(
- WTF::Bind(&NDEFWriter::Abort, WrapPersistent(this), options->target(),
- WrapPersistent(resolver)));
+ options->signal()->AddAlgorithm(WTF::Bind(
+ &NDEFWriter::Abort, WrapPersistent(this), WrapPersistent(resolver)));
}
- UseCounter::Count(GetExecutionContext(), WebFeature::kWebNfcNdefWriterPush);
+ UseCounter::Count(GetExecutionContext(), WebFeature::kWebNfcNdefWriterWrite);
+ // TODO(https://crbug.com/994936) remove when origin trial is complete.
+ UseCounter::Count(GetExecutionContext(), WebFeature::kWebNfcAPI);
auto callback = WTF::Bind(&NDEFWriter::OnRequestCompleted,
WrapPersistent(this), WrapPersistent(resolver));
nfc_proxy_->Push(std::move(message),
- device::mojom::blink::NDEFPushOptions::From(options),
+ device::mojom::blink::NDEFWriteOptions::From(options),
std::move(callback));
}
void NDEFWriter::OnMojoConnectionError() {
nfc_proxy_.Clear();
- // If the mojo connection breaks, all push requests will be reject with a
+ // If the mojo connection breaks, all push requests will be rejected with a
// default error.
for (ScriptPromiseResolver* resolver : requests_) {
resolver->Reject(NDEFErrorTypeToDOMException(
- device::mojom::blink::NDEFErrorType::NOT_SUPPORTED));
+ device::mojom::blink::NDEFErrorType::NOT_SUPPORTED,
+ "WebNFC feature is unavailable or permission denied."));
}
requests_.clear();
}
@@ -173,7 +158,7 @@ void NDEFWriter::InitNfcProxyIfNeeded() {
if (nfc_proxy_)
return;
- nfc_proxy_ = NFCProxy::From(*To<Document>(GetExecutionContext()));
+ nfc_proxy_ = NFCProxy::From(*To<LocalDOMWindow>(GetExecutionContext()));
DCHECK(nfc_proxy_);
// Add the writer to proxy's writer list for mojo connection error
@@ -181,7 +166,7 @@ void NDEFWriter::InitNfcProxyIfNeeded() {
nfc_proxy_->AddWriter(this);
}
-void NDEFWriter::Abort(const String& target, ScriptPromiseResolver* resolver) {
+void NDEFWriter::Abort(ScriptPromiseResolver* resolver) {
// |nfc_proxy_| could be null on Mojo connection failure, simply ignore the
// abort request in this case.
if (!nfc_proxy_)
@@ -189,8 +174,7 @@ void NDEFWriter::Abort(const String& target, ScriptPromiseResolver* resolver) {
// OnRequestCompleted() should always be called whether the push operation is
// cancelled successfully or not. So do nothing for the cancelled callback.
- nfc_proxy_->CancelPush(target,
- device::mojom::blink::NFC::CancelPushCallback());
+ nfc_proxy_->CancelPush(device::mojom::blink::NFC::CancelPushCallback());
}
void NDEFWriter::OnRequestCompleted(ScriptPromiseResolver* resolver,
@@ -199,10 +183,12 @@ void NDEFWriter::OnRequestCompleted(ScriptPromiseResolver* resolver,
requests_.erase(resolver);
- if (error.is_null())
+ if (error.is_null()) {
resolver->Resolve();
- else
- resolver->Reject(NDEFErrorTypeToDOMException(error->error_type));
+ } else {
+ resolver->Reject(
+ NDEFErrorTypeToDOMException(error->error_type, error->error_message));
+ }
}
} // namespace blink
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 eb266032b5b..b53fefc834a 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.h
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.h
@@ -8,14 +8,14 @@
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/nfc/nfc_proxy.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
namespace blink {
-class NDEFPushOptions;
+class NDEFWriteOptions;
class ExceptionState;
class ExecutionContext;
class ScriptPromise;
@@ -23,7 +23,7 @@ class StringOrArrayBufferOrArrayBufferViewOrNDEFMessageInit;
using NDEFMessageSource = StringOrArrayBufferOrArrayBufferViewOrNDEFMessageInit;
-class NDEFWriter : public ScriptWrappable, public ContextClient {
+class NDEFWriter : public ScriptWrappable, public ExecutionContextClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(NDEFWriter);
@@ -33,26 +33,26 @@ class NDEFWriter : public ScriptWrappable, public ContextClient {
explicit NDEFWriter(ExecutionContext*);
~NDEFWriter() override = default;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
- // Pushes NDEFMessageSource asynchronously to NFC tag / peer.
- ScriptPromise push(ScriptState*,
- const NDEFMessageSource&,
- const NDEFPushOptions*,
- ExceptionState&);
+ // Write NDEFMessageSource asynchronously to NFC tag.
+ ScriptPromise write(ScriptState*,
+ const NDEFMessageSource&,
+ const NDEFWriteOptions*,
+ ExceptionState&);
// Called by NFCProxy for notification about connection error.
void OnMojoConnectionError();
private:
void InitNfcProxyIfNeeded();
- void Abort(const String& target, ScriptPromiseResolver* resolver);
+ void Abort(ScriptPromiseResolver* resolver);
void OnRequestCompleted(ScriptPromiseResolver* resolver,
device::mojom::blink::NDEFErrorPtr error);
// Permission handling
void OnRequestPermission(ScriptPromiseResolver* resolver,
- const NDEFPushOptions* options,
+ const NDEFWriteOptions* options,
device::mojom::blink::NDEFMessagePtr ndef_message,
mojom::blink::PermissionStatus status);
mojom::blink::PermissionService* GetPermissionService();
diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.idl b/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.idl
index 9508caa0b88..23e2dcce135 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.idl
+++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.idl
@@ -4,22 +4,17 @@
// https://w3c.github.io/web-nfc/#dom-ndefmessagesource
-// The bindings generator does not support "typedef in union".
-// Must be (DOMString or BufferSource or NDEFMessageInit).
-// TODO(http://crbug.com/1019126): Support nested typedef in Web IDLs.
-typedef (DOMString or ArrayBuffer or ArrayBufferView or NDEFMessageInit)
- NDEFMessageSource;
+typedef (DOMString or BufferSource or NDEFMessageInit) NDEFMessageSource;
// https://w3c.github.io/web-nfc/#dom-nfcwriter
[
RuntimeEnabled=WebNFC,
SecureContext,
- Constructor(),
- ConstructorCallWith=ExecutionContext,
Exposed=Window
] interface NDEFWriter {
- [CallWith=ScriptState, RaisesException] Promise<void> push(
+ [CallWith=ExecutionContext] constructor();
+ [CallWith=ScriptState, RaisesException] Promise<void> write(
NDEFMessageSource message,
- optional NDEFPushOptions options={});
+ optional NDEFWriteOptions options={});
};
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 a375696c17f..b90735f7086 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.cc
+++ b/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.cc
@@ -7,6 +7,8 @@
#include <utility>
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/modules/nfc/ndef_reader.h"
#include "third_party/blink/renderer/modules/nfc/ndef_writer.h"
#include "third_party/blink/renderer/modules/nfc/nfc_type_converters.h"
@@ -19,24 +21,22 @@ namespace blink {
const char NFCProxy::kSupplementName[] = "NFCProxy";
// static
-NFCProxy* NFCProxy::From(Document& document) {
+NFCProxy* NFCProxy::From(LocalDOMWindow& window) {
// https://w3c.github.io/web-nfc/#security-policies
// WebNFC API must be only accessible from top level browsing context.
- DCHECK(document.IsInMainFrame());
+ DCHECK(window.GetFrame()->IsMainFrame());
- NFCProxy* nfc_proxy = Supplement<Document>::From<NFCProxy>(document);
+ NFCProxy* nfc_proxy = Supplement<LocalDOMWindow>::From<NFCProxy>(window);
if (!nfc_proxy) {
- nfc_proxy = MakeGarbageCollected<NFCProxy>(document);
- Supplement<Document>::ProvideTo(document, nfc_proxy);
+ nfc_proxy = MakeGarbageCollected<NFCProxy>(window);
+ Supplement<LocalDOMWindow>::ProvideTo(window, nfc_proxy);
}
return nfc_proxy;
}
// NFCProxy
-NFCProxy::NFCProxy(Document& document)
- : PageVisibilityObserver(document.GetPage()),
- Supplement<Document>(document),
- client_receiver_(this) {}
+NFCProxy::NFCProxy(LocalDOMWindow& window)
+ : Supplement<LocalDOMWindow>(window), client_receiver_(this) {}
NFCProxy::~NFCProxy() = default;
@@ -44,11 +44,10 @@ void NFCProxy::Dispose() {
client_receiver_.reset();
}
-void NFCProxy::Trace(blink::Visitor* visitor) {
+void NFCProxy::Trace(Visitor* visitor) {
visitor->Trace(writers_);
visitor->Trace(readers_);
- PageVisibilityObserver::Trace(visitor);
- Supplement<Document>::Trace(visitor);
+ Supplement<LocalDOMWindow>::Trace(visitor);
}
void NFCProxy::StartReading(NDEFReader* reader,
@@ -90,17 +89,16 @@ void NFCProxy::AddWriter(NDEFWriter* writer) {
}
void NFCProxy::Push(device::mojom::blink::NDEFMessagePtr message,
- device::mojom::blink::NDEFPushOptionsPtr options,
+ device::mojom::blink::NDEFWriteOptionsPtr options,
device::mojom::blink::NFC::PushCallback cb) {
EnsureMojoConnection();
nfc_remote_->Push(std::move(message), std::move(options), std::move(cb));
}
void NFCProxy::CancelPush(
- const String& target,
device::mojom::blink::NFC::CancelPushCallback callback) {
DCHECK(nfc_remote_);
- nfc_remote_->CancelPush(StringToNDEFPushTarget(target), std::move(callback));
+ nfc_remote_->CancelPush(std::move(callback));
}
// device::mojom::blink::NFCClient implementation.
@@ -108,10 +106,9 @@ void NFCProxy::OnWatch(const Vector<uint32_t>& watch_ids,
const String& serial_number,
device::mojom::blink::NDEFMessagePtr message) {
// Dispatch the event to all matched readers. We iterate on a copy of
- // |readers_| because the user's NDEFReader#onreading event handler may call
- // NDEFReader#stop() to modify |readers_| just during the iteration process.
- // This loop is O(n^2), however, we assume the number of readers to be small
- // so it'd be just OK.
+ // |readers_| because a reader's onreading event handler may remove itself
+ // from |readers_| just during the iteration process. This loop is O(n^2),
+ // however, we assume the number of readers to be small so it'd be just OK.
ReaderMap copy = readers_;
for (auto& pair : copy) {
if (watch_ids.Contains(pair.value))
@@ -119,6 +116,16 @@ void NFCProxy::OnWatch(const Vector<uint32_t>& watch_ids,
}
}
+void NFCProxy::OnError(device::mojom::blink::NDEFErrorPtr error) {
+ // Dispatch the event to all readers. We iterate on a copy of |readers_|
+ // because a reader's onerror event handler may remove itself from |readers_|
+ // just during the iteration process.
+ ReaderMap copy = readers_;
+ for (auto& pair : copy) {
+ pair.key->OnError(error->error_message);
+ }
+}
+
void NFCProxy::OnReaderRegistered(
NDEFReader* reader,
uint32_t watch_id,
@@ -147,38 +154,31 @@ void NFCProxy::OnReaderRegistered(
// message notifications in OnWatch().
}
-void NFCProxy::PageVisibilityChanged() {
- // If service is not initialized, there cannot be any pending NFC activities.
- if (!nfc_remote_)
- return;
-
- // NFC operations should be suspended.
- // https://w3c.github.io/web-nfc/#nfc-suspended
- // TODO(https://crbug.com/520391): Suspend/Resume NFC in the browser process
- // instead to prevent a compromised renderer from using NFC in the background.
- if (!GetPage()->IsPageVisible())
- nfc_remote_->SuspendNFCOperations();
- else
- nfc_remote_->ResumeNFCOperations();
-}
-
void NFCProxy::EnsureMojoConnection() {
if (nfc_remote_)
return;
+ // See https://bit.ly/2S0zRAS for task types.
+ auto task_runner =
+ GetSupplementable()->GetTaskRunner(TaskType::kMiscPlatformAPI);
+
GetSupplementable()->GetBrowserInterfaceBroker().GetInterface(
- nfc_remote_.BindNewPipeAndPassReceiver());
+ nfc_remote_.BindNewPipeAndPassReceiver(task_runner));
nfc_remote_.set_disconnect_handler(
WTF::Bind(&NFCProxy::OnMojoConnectionError, WrapWeakPersistent(this)));
- // See https://bit.ly/2S0zRAS for task types.
- auto task_runner =
- GetSupplementable()->GetTaskRunner(TaskType::kMiscPlatformAPI);
// Set client for OnWatch event.
nfc_remote_->SetClient(
client_receiver_.BindNewPipeAndPassRemote(task_runner));
}
+// This method will be called if either the NFC service is unavailable (such
+// as if the feature flag is disabled) or when the user revokes the NFC
+// permission after the Mojo connection has already been opened. It is
+// currently impossible to distinguish between these two cases.
+//
+// In the future this code may also handle the case where an out-of-process
+// Device Service encounters a fatal error and must be restarted.
void NFCProxy::OnMojoConnectionError() {
nfc_remote_.reset();
client_receiver_.reset();
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 bd9b733ccf3..7ebc41d4a1a 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.h
+++ b/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.h
@@ -8,14 +8,13 @@
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/device/public/mojom/nfc.mojom-blink.h"
-#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/page/page_visibility_observer.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/supplementable.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
namespace blink {
-class Document;
+class LocalDOMWindow;
class NDEFScanOptions;
class NDEFReader;
class NDEFWriter;
@@ -23,22 +22,21 @@ class NDEFWriter;
// This is a proxy class used by NDEFWriter(s) and NDEFReader(s) to connect
// to implementation of device::mojom::blink::NFC interface.
class MODULES_EXPORT NFCProxy final : public GarbageCollected<NFCProxy>,
- public PageVisibilityObserver,
- public Supplement<Document>,
+ public Supplement<LocalDOMWindow>,
public device::mojom::blink::NFCClient {
USING_GARBAGE_COLLECTED_MIXIN(NFCProxy);
USING_PRE_FINALIZER(NFCProxy, Dispose);
public:
static const char kSupplementName[];
- static NFCProxy* From(Document&);
+ static NFCProxy* From(LocalDOMWindow&);
- explicit NFCProxy(Document&);
+ explicit NFCProxy(LocalDOMWindow&);
~NFCProxy() override;
void Dispose();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// There is no matching RemoveWriter() method because writers are
// automatically removed from the weak hash set when they are garbage
@@ -51,24 +49,22 @@ class MODULES_EXPORT NFCProxy final : public GarbageCollected<NFCProxy>,
void StopReading(NDEFReader*);
bool IsReading(const NDEFReader*);
void Push(device::mojom::blink::NDEFMessagePtr,
- device::mojom::blink::NDEFPushOptionsPtr,
+ device::mojom::blink::NDEFWriteOptionsPtr,
device::mojom::blink::NFC::PushCallback);
- void CancelPush(const String&, device::mojom::blink::NFC::CancelPushCallback);
+ void CancelPush(device::mojom::blink::NFC::CancelPushCallback);
private:
// Implementation of device::mojom::blink::NFCClient.
void OnWatch(const Vector<uint32_t>&,
const String&,
device::mojom::blink::NDEFMessagePtr) override;
+ void OnError(device::mojom::blink::NDEFErrorPtr) override;
void OnReaderRegistered(NDEFReader*,
uint32_t watch_id,
device::mojom::blink::NFC::WatchCallback,
device::mojom::blink::NDEFErrorPtr);
- // Implementation of PageVisibilityObserver.
- void PageVisibilityChanged() override;
-
void EnsureMojoConnection();
// This could only happen when the embedder does not implement NFC interface.
diff --git a/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy_test.cc b/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy_test.cc
index 08f2b7c01f2..a28a9c23cd0 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy_test.cc
+++ b/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy_test.cc
@@ -13,9 +13,10 @@
#include "testing/gmock/include/gmock/gmock.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/bindings/modules/v8/v8_ndef_scan_options.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/modules/nfc/ndef_reader.h"
-#include "third_party/blink/renderer/modules/nfc/ndef_scan_options.h"
#include "third_party/blink/renderer/modules/nfc/nfc_proxy.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
@@ -25,7 +26,8 @@ namespace {
using ::testing::_;
using ::testing::Invoke;
-static const char kTestUrl[] = "https://w3c.github.io/web-nfc/";
+static const char kFakeRecordId[] =
+ "https://w3c.github.io/web-nfc/dummy-record-id";
static const char kFakeNfcTagSerialNumber[] = "c0:45:00:02";
MATCHER_P(MessageEquals, expected, "") {
@@ -77,10 +79,10 @@ class FakeNfcService : public device::mojom::blink::NFC {
if (!client_ || !tag_message_)
return;
- // Only match the watches using |url| in options.
+ // Only match the watches using |id| in options.
WTF::Vector<uint32_t> ids;
for (auto& pair : watches_) {
- if (pair.second->id == tag_message_->url) {
+ if (pair.second->id == tag_message_->data[0]->id) {
ids.push_back(pair.first);
}
}
@@ -114,13 +116,12 @@ class FakeNfcService : public device::mojom::blink::NFC {
client_.Bind(std::move(client));
}
void Push(device::mojom::blink::NDEFMessagePtr message,
- device::mojom::blink::NDEFPushOptionsPtr options,
+ device::mojom::blink::NDEFWriteOptionsPtr options,
PushCallback callback) override {
set_tag_message(std::move(message));
std::move(callback).Run(nullptr);
}
- void CancelPush(device::mojom::blink::NDEFPushTarget target,
- CancelPushCallback callback) override {
+ void CancelPush(CancelPushCallback callback) override {
std::move(callback).Run(nullptr);
}
void Watch(device::mojom::blink::NDEFScanOptionsPtr options,
@@ -136,7 +137,7 @@ class FakeNfcService : public device::mojom::blink::NFC {
void CancelWatch(uint32_t id, CancelWatchCallback callback) override {
if (watches_.erase(id) < 1) {
std::move(callback).Run(device::mojom::blink::NDEFError::New(
- device::mojom::blink::NDEFErrorType::NOT_FOUND));
+ device::mojom::blink::NDEFErrorType::NOT_FOUND, ""));
} else {
std::move(callback).Run(nullptr);
}
@@ -145,8 +146,6 @@ class FakeNfcService : public device::mojom::blink::NFC {
watches_.clear();
std::move(callback).Run(nullptr);
}
- void SuspendNFCOperations() override {}
- void ResumeNFCOperations() override {}
device::mojom::blink::NDEFErrorPtr watch_error_;
device::mojom::blink::NDEFMessagePtr tag_message_;
@@ -162,14 +161,14 @@ class NFCProxyTest : public PageTestBase {
void SetUp() override {
PageTestBase::SetUp(IntSize());
- GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting(
+ GetFrame().DomWindow()->GetBrowserInterfaceBroker().SetBinderForTesting(
device::mojom::blink::NFC::Name_,
WTF::BindRepeating(&FakeNfcService::BindRequest,
WTF::Unretained(nfc_service())));
}
void TearDown() override {
- GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting(
+ GetFrame().DomWindow()->GetBrowserInterfaceBroker().SetBinderForTesting(
device::mojom::blink::NFC::Name_, {});
}
@@ -180,11 +179,11 @@ class NFCProxyTest : public PageTestBase {
};
TEST_F(NFCProxyTest, SuccessfulPath) {
- auto& document = GetDocument();
- auto* nfc_proxy = NFCProxy::From(document);
+ auto* window = GetFrame().DomWindow();
+ auto* nfc_proxy = NFCProxy::From(*window);
auto* scan_options = NDEFScanOptions::Create();
- scan_options->setId(kTestUrl);
- auto* reader = MakeGarbageCollected<MockNDEFReader>(&document);
+ scan_options->setId(kFakeRecordId);
+ auto* reader = MakeGarbageCollected<MockNDEFReader>(window);
{
base::RunLoop loop;
@@ -201,11 +200,11 @@ TEST_F(NFCProxyTest, SuccessfulPath) {
// Construct a NDEFMessagePtr
auto message = device::mojom::blink::NDEFMessage::New();
- message->url = kTestUrl;
auto record = device::mojom::blink::NDEFRecord::New();
WTF::Vector<uint8_t> record_data(
{0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10});
record->record_type = "mime";
+ record->id = kFakeRecordId;
record->data = WTF::Vector<uint8_t>(record_data);
message->data.push_back(std::move(record));
@@ -233,15 +232,15 @@ TEST_F(NFCProxyTest, SuccessfulPath) {
}
TEST_F(NFCProxyTest, ErrorPath) {
- auto& document = GetDocument();
- auto* nfc_proxy = NFCProxy::From(document);
+ auto* window = GetFrame().DomWindow();
+ auto* nfc_proxy = NFCProxy::From(*window);
auto* scan_options = NDEFScanOptions::Create();
- scan_options->setId(kTestUrl);
- auto* reader = MakeGarbageCollected<MockNDEFReader>(&document);
+ scan_options->setId(kFakeRecordId);
+ auto* reader = MakeGarbageCollected<MockNDEFReader>(window);
// Make the fake NFC service return an error for the incoming watch request.
nfc_service()->set_watch_error(device::mojom::blink::NDEFError::New(
- device::mojom::blink::NDEFErrorType::NOT_READABLE));
+ device::mojom::blink::NDEFErrorType::NOT_READABLE, ""));
base::RunLoop loop;
nfc_proxy->StartReading(
reader, scan_options,
diff --git a/chromium/third_party/blink/renderer/modules/nfc/nfc_type_converters.cc b/chromium/third_party/blink/renderer/modules/nfc/nfc_type_converters.cc
index aaa142a0428..7587b5a46f5 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/nfc_type_converters.cc
+++ b/chromium/third_party/blink/renderer/modules/nfc/nfc_type_converters.cc
@@ -8,21 +8,21 @@
#include <utility>
#include "services/device/public/mojom/nfc.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_ndef_scan_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_ndef_write_options.h"
#include "third_party/blink/renderer/modules/nfc/ndef_message.h"
-#include "third_party/blink/renderer/modules/nfc/ndef_push_options.h"
#include "third_party/blink/renderer/modules/nfc/ndef_record.h"
-#include "third_party/blink/renderer/modules/nfc/ndef_scan_options.h"
#include "third_party/blink/renderer/modules/nfc/nfc_utils.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
using device::mojom::blink::NDEFMessage;
using device::mojom::blink::NDEFMessagePtr;
-using device::mojom::blink::NDEFPushOptions;
-using device::mojom::blink::NDEFPushOptionsPtr;
using device::mojom::blink::NDEFRecord;
using device::mojom::blink::NDEFRecordPtr;
using device::mojom::blink::NDEFScanOptions;
using device::mojom::blink::NDEFScanOptionsPtr;
+using device::mojom::blink::NDEFWriteOptions;
+using device::mojom::blink::NDEFWriteOptionsPtr;
// Mojo type converters
namespace mojo {
@@ -30,8 +30,8 @@ namespace mojo {
NDEFRecordPtr TypeConverter<NDEFRecordPtr, blink::NDEFRecord*>::Convert(
const blink::NDEFRecord* record) {
return NDEFRecord::New(
- record->recordType(), record->mediaType(), record->id(),
- record->encoding(), record->lang(), record->payloadData(),
+ record->category(), record->recordType(), record->mediaType(),
+ record->id(), record->encoding(), record->lang(), record->payloadData(),
TypeConverter<NDEFMessagePtr, blink::NDEFMessage*>::Convert(
record->payload_message()));
}
@@ -42,45 +42,50 @@ NDEFMessagePtr TypeConverter<NDEFMessagePtr, blink::NDEFMessage*>::Convert(
// possible to be null for some "smart-poster" and external type records.
if (!message)
return nullptr;
- NDEFMessagePtr messagePtr = NDEFMessage::New();
- messagePtr->url = message->url();
- messagePtr->data.resize(message->records().size());
+ NDEFMessagePtr message_ptr = NDEFMessage::New();
+ message_ptr->data.resize(message->records().size());
for (wtf_size_t i = 0; i < message->records().size(); ++i) {
NDEFRecordPtr record = NDEFRecord::From(message->records()[i].Get());
DCHECK(record);
- messagePtr->data[i] = std::move(record);
+ message_ptr->data[i] = std::move(record);
}
- return messagePtr;
+ return message_ptr;
}
-NDEFPushOptionsPtr
-TypeConverter<NDEFPushOptionsPtr, const blink::NDEFPushOptions*>::Convert(
- const blink::NDEFPushOptions* pushOptions) {
- // https://w3c.github.io/web-nfc/#the-ndefpushoptions-dictionary
- // Default values for NDEFPushOptions dictionary are:
- // target = 'any', ignoreRead = true
- NDEFPushOptionsPtr pushOptionsPtr = NDEFPushOptions::New();
- pushOptionsPtr->target = blink::StringToNDEFPushTarget(pushOptions->target());
- pushOptionsPtr->ignore_read = pushOptions->ignoreRead();
+NDEFWriteOptionsPtr
+TypeConverter<NDEFWriteOptionsPtr, const blink::NDEFWriteOptions*>::Convert(
+ const blink::NDEFWriteOptions* write_options) {
+ // https://w3c.github.io/web-nfc/#the-ndefwriteoptions-dictionary
+ // Default values for NDEFWriteOptions dictionary are:
+ // ignoreRead = true, overwrite = true
+ NDEFWriteOptionsPtr write_options_ptr = NDEFWriteOptions::New();
+ write_options_ptr->ignore_read = write_options->ignoreRead();
+ write_options_ptr->overwrite = write_options->overwrite();
- return pushOptionsPtr;
+ return write_options_ptr;
}
NDEFScanOptionsPtr
TypeConverter<NDEFScanOptionsPtr, const blink::NDEFScanOptions*>::Convert(
- const blink::NDEFScanOptions* scanOptions) {
+ const blink::NDEFScanOptions* scan_options) {
// https://w3c.github.io/web-nfc/#dom-ndefscanoptions
// Default values for NDEFScanOptions dictionary are:
- // id = "", recordType = null, mediaType = ""
- NDEFScanOptionsPtr scanOptionsPtr = NDEFScanOptions::New();
- scanOptionsPtr->id = scanOptions->id();
- scanOptionsPtr->media_type = scanOptions->mediaType();
+ // id = undefined, recordType = undefined, mediaType = undefined
+ NDEFScanOptionsPtr scan_options_ptr = NDEFScanOptions::New();
- if (scanOptions->hasRecordType()) {
- scanOptionsPtr->record_type = scanOptions->recordType();
+ if (scan_options->hasId()) {
+ scan_options_ptr->id = scan_options->id();
}
- return scanOptionsPtr;
+ if (scan_options->hasRecordType()) {
+ scan_options_ptr->record_type = scan_options->recordType();
+ }
+
+ if (scan_options->hasMediaType()) {
+ scan_options_ptr->media_type = scan_options->mediaType();
+ }
+
+ return scan_options_ptr;
}
} // namespace mojo
diff --git a/chromium/third_party/blink/renderer/modules/nfc/nfc_type_converters.h b/chromium/third_party/blink/renderer/modules/nfc/nfc_type_converters.h
index 88a89cee097..1343c151f89 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/nfc_type_converters.h
+++ b/chromium/third_party/blink/renderer/modules/nfc/nfc_type_converters.h
@@ -14,7 +14,7 @@ namespace blink {
class NDEFRecord;
class NDEFMessage;
class NDEFScanOptions;
-class NDEFPushOptions;
+class NDEFWriteOptions;
} // namespace blink
@@ -35,10 +35,10 @@ struct TypeConverter<device::mojom::blink::NDEFMessagePtr,
};
template <>
-struct TypeConverter<device::mojom::blink::NDEFPushOptionsPtr,
- const ::blink::NDEFPushOptions*> {
- static device::mojom::blink::NDEFPushOptionsPtr Convert(
- const ::blink::NDEFPushOptions* pushOptions);
+struct TypeConverter<device::mojom::blink::NDEFWriteOptionsPtr,
+ const ::blink::NDEFWriteOptions*> {
+ static device::mojom::blink::NDEFWriteOptionsPtr Convert(
+ const ::blink::NDEFWriteOptions* writeOptions);
};
template <>
diff --git a/chromium/third_party/blink/renderer/modules/nfc/nfc_utils.cc b/chromium/third_party/blink/renderer/modules/nfc/nfc_utils.cc
index 58d8d6e800c..9e01de92619 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/nfc_utils.cc
+++ b/chromium/third_party/blink/renderer/modules/nfc/nfc_utils.cc
@@ -9,76 +9,37 @@
#include "services/device/public/mojom/nfc.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
-#include "third_party/blink/renderer/modules/nfc/nfc_type_converters.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/weborigin/kurl.h"
-
-using device::mojom::blink::NDEFPushTarget;
namespace blink {
-size_t GetNDEFMessageSize(const device::mojom::blink::NDEFMessage& message) {
- size_t message_size = message.url.CharactersSizeInBytes();
- for (wtf_size_t i = 0; i < message.data.size(); ++i) {
- message_size += message.data[i]->media_type.CharactersSizeInBytes();
- message_size += message.data[i]->data.size();
- }
- return message_size;
-}
-
-bool SetNDEFMessageURL(const String& origin,
- device::mojom::blink::NDEFMessage* message) {
- KURL origin_url(origin);
-
- if (!message->url.IsEmpty() && origin_url.CanSetPathname()) {
- origin_url.SetPath(message->url);
- }
-
- message->url = origin_url;
- return origin_url.IsValid();
-}
-
-NDEFPushTarget StringToNDEFPushTarget(const String& target) {
- if (target == "tag")
- return NDEFPushTarget::TAG;
-
- if (target == "peer")
- return NDEFPushTarget::PEER;
-
- return NDEFPushTarget::ANY;
-}
-
DOMException* NDEFErrorTypeToDOMException(
- device::mojom::blink::NDEFErrorType error_type) {
+ device::mojom::blink::NDEFErrorType error_type,
+ const String& error_message) {
switch (error_type) {
case device::mojom::blink::NDEFErrorType::NOT_ALLOWED:
return MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotAllowedError, "NFC operation not allowed.");
+ DOMExceptionCode::kNotAllowedError, error_message);
case device::mojom::blink::NDEFErrorType::NOT_SUPPORTED:
return MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotSupportedError,
- "No NFC adapter or cannot establish connection.");
+ DOMExceptionCode::kNotSupportedError, error_message);
case device::mojom::blink::NDEFErrorType::NOT_READABLE:
return MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotReadableError, "NFC is not enabled.");
+ DOMExceptionCode::kNotReadableError, error_message);
case device::mojom::blink::NDEFErrorType::NOT_FOUND:
return MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotFoundError,
- "Provided watch id cannot be found.");
+ DOMExceptionCode::kNotFoundError, error_message);
case device::mojom::blink::NDEFErrorType::INVALID_MESSAGE:
- return MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kSyntaxError, "Invalid NFC message was provided.");
+ return MakeGarbageCollected<DOMException>(DOMExceptionCode::kSyntaxError,
+ error_message);
case device::mojom::blink::NDEFErrorType::OPERATION_CANCELLED:
- return MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kAbortError, "The NFC operation was cancelled.");
+ return MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError,
+ error_message);
case device::mojom::blink::NDEFErrorType::CANNOT_CANCEL:
return MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNoModificationAllowedError,
- "NFC operation cannot be cancelled.");
+ DOMExceptionCode::kNoModificationAllowedError, error_message);
case device::mojom::blink::NDEFErrorType::IO_ERROR:
- return MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNetworkError,
- "NFC data transfer error has occurred.");
+ return MakeGarbageCollected<DOMException>(DOMExceptionCode::kNetworkError,
+ error_message);
}
NOTREACHED();
// Don't need to handle the case after a NOTREACHED().
diff --git a/chromium/third_party/blink/renderer/modules/nfc/nfc_utils.h b/chromium/third_party/blink/renderer/modules/nfc/nfc_utils.h
index 72e2282ad3c..36d0f2387f8 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/nfc_utils.h
+++ b/chromium/third_party/blink/renderer/modules/nfc/nfc_utils.h
@@ -6,25 +6,15 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_NFC_NFC_UTILS_H_
#include "services/device/public/mojom/nfc.mojom-blink-forward.h"
-#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
-#include "third_party/blink/renderer/modules/nfc/ndef_message.h"
-#include "third_party/blink/renderer/modules/nfc/ndef_record.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
class DOMException;
-size_t GetNDEFMessageSize(const device::mojom::blink::NDEFMessage& message);
-
-bool SetNDEFMessageURL(const String& origin,
- device::mojom::blink::NDEFMessage* message);
-
-device::mojom::blink::NDEFPushTarget StringToNDEFPushTarget(
- const WTF::String& target);
-
DOMException* NDEFErrorTypeToDOMException(
- device::mojom::blink::NDEFErrorType error_type);
+ device::mojom::blink::NDEFErrorType error_type,
+ const String& error_message);
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/notifications/BUILD.gn b/chromium/third_party/blink/renderer/modules/notifications/BUILD.gn
index 51776ed1cd5..97145afbdc4 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/notifications/BUILD.gn
@@ -22,7 +22,6 @@ blink_modules_sources("notifications") {
"timestamp_trigger.cc",
"timestamp_trigger.h",
]
- deps = [
- "//services/resource_coordinator/public/cpp:resource_coordinator_cpp",
- ]
+ deps =
+ [ "//services/resource_coordinator/public/cpp:resource_coordinator_cpp" ]
}
diff --git a/chromium/third_party/blink/renderer/modules/notifications/idls.gni b/chromium/third_party/blink/renderer/modules/notifications/idls.gni
new file mode 100644
index 00000000000..c357dd01d65
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/notifications/idls.gni
@@ -0,0 +1,21 @@
+# 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 = [
+ "notification.idl",
+ "notification_event.idl",
+ "timestamp_trigger.idl",
+]
+
+modules_dictionary_idl_files = [
+ "get_notification_options.idl",
+ "notification_action.idl",
+ "notification_event_init.idl",
+ "notification_options.idl",
+]
+
+modules_dependency_idl_files = [
+ "service_worker_global_scope_notifications.idl",
+ "service_worker_registration_notifications.idl",
+]
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification.cc b/chromium/third_party/blink/renderer/modules/notifications/notification.cc
index c4e48c7f359..e925affcd5c 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification.cc
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification.cc
@@ -40,6 +40,7 @@
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_factory.h"
#include "third_party/blink/renderer/bindings/core/v8/source_location.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/dom/document.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/scoped_window_focus_allowed_indicator.h"
@@ -48,10 +49,8 @@
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/performance_monitor.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
-#include "third_party/blink/renderer/modules/notifications/notification_action.h"
#include "third_party/blink/renderer/modules/notifications/notification_data.h"
#include "third_party/blink/renderer/modules/notifications/notification_manager.h"
-#include "third_party/blink/renderer/modules/notifications/notification_options.h"
#include "third_party/blink/renderer/modules/notifications/notification_resources_loader.h"
#include "third_party/blink/renderer/modules/notifications/timestamp_trigger.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -98,7 +97,7 @@ Notification* Notification::Create(ExecutionContext* context,
return nullptr;
}
- auto* document = DynamicTo<Document>(context);
+ auto* document = Document::DynamicFrom(context);
if (context->IsSecureContext()) {
UseCounter::Count(context, WebFeature::kNotificationSecureOrigin);
if (document) {
@@ -162,7 +161,7 @@ Notification* Notification::Create(ExecutionContext* context,
Notification::Notification(ExecutionContext* context,
Type type,
mojom::blink::NotificationDataPtr data)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
type_(type),
state_(State::kLoading),
data_(std::move(data)),
@@ -247,7 +246,7 @@ void Notification::OnShow() {
void Notification::OnClick(OnClickCallback completed_closure) {
ExecutionContext* context = GetExecutionContext();
- Document* document = DynamicTo<Document>(context);
+ Document* document = Document::DynamicFrom(context);
if (document && document->GetFrame())
LocalFrame::NotifyUserActivation(document->GetFrame());
ScopedWindowFocusAllowedIndicator window_focus_allowed(GetExecutionContext());
@@ -420,9 +419,9 @@ String Notification::permission(ExecutionContext* context) {
// TODO(crbug.com/758603): Move this check to the browser process when the
// NotificationService connection becomes frame-bound.
if (status == mojom::blink::PermissionStatus::ASK) {
- auto* document = DynamicTo<Document>(context);
+ auto* document = Document::DynamicFrom(context);
LocalFrame* frame = document ? document->GetFrame() : nullptr;
- if (!frame || frame->IsCrossOriginSubframe())
+ if (!frame || frame->IsCrossOriginToMainFrame())
status = mojom::blink::PermissionStatus::DENIED;
}
@@ -433,7 +432,7 @@ ScriptPromise Notification::requestPermission(
ScriptState* script_state,
V8NotificationPermissionCallback* deprecated_callback) {
ExecutionContext* context = ExecutionContext::From(script_state);
- Document* doc = DynamicTo<Document>(context);
+ Document* doc = Document::DynamicFrom(context);
probe::BreakableLocation(context, "Notification.requestPermission");
if (!LocalFrame::HasTransientUserActivation(doc ? doc->GetFrame()
@@ -452,9 +451,9 @@ ScriptPromise Notification::requestPermission(
// Sites cannot request notification permission from cross-origin iframes,
// but they can use notifications if permission had already been granted.
- if (auto* document = DynamicTo<Document>(context)) {
+ if (auto* document = Document::DynamicFrom(context)) {
LocalFrame* frame = document->GetFrame();
- if (!frame || frame->IsCrossOriginSubframe()) {
+ if (!frame || frame->IsCrossOriginToMainFrame()) {
Deprecation::CountDeprecation(
context, WebFeature::kNotificationPermissionRequestedIframe);
}
@@ -477,7 +476,7 @@ const AtomicString& Notification::InterfaceName() const {
return event_target_names::kNotification;
}
-void Notification::ContextDestroyed(ExecutionContext* context) {
+void Notification::ContextDestroyed() {
listener_receiver_.reset();
state_ = State::kClosed;
@@ -498,11 +497,11 @@ bool Notification::HasPendingActivity() const {
return false;
}
-void Notification::Trace(blink::Visitor* visitor) {
+void Notification::Trace(Visitor* visitor) {
visitor->Trace(show_trigger_);
visitor->Trace(loader_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification.h b/chromium/third_party/blink/renderer/modules/notifications/notification.h
index b45101ea0ec..8274bdfa259 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification.h
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification.h
@@ -40,7 +40,7 @@
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
#include "third_party/blink/renderer/core/dom/dom_time_stamp.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#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/modules/vibration/navigator_vibration.h"
@@ -60,7 +60,7 @@ class TimestampTrigger;
class MODULES_EXPORT Notification final
: public EventTargetWithInlineData,
public ActiveScriptWrappable<Notification>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public mojom::blink::NonPersistentNotificationListener {
USING_GARBAGE_COLLECTED_MIXIN(Notification);
DEFINE_WRAPPERTYPEINFO();
@@ -130,17 +130,17 @@ class MODULES_EXPORT Notification final
// EventTarget interface.
ExecutionContext* GetExecutionContext() const final {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
const AtomicString& InterfaceName() const override;
- // ContextLifecycleObserver interface.
- void ContextDestroyed(ExecutionContext* context) override;
+ // ExecutionContextLifecycleObserver interface.
+ void ContextDestroyed() override;
// ScriptWrappable interface.
bool HasPendingActivity() const final;
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
protected:
// EventTarget interface.
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification.idl b/chromium/third_party/blink/renderer/modules/notifications/notification.idl
index 6d358f68314..d7604eccb62 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification.idl
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification.idl
@@ -41,13 +41,10 @@ enum NotificationPermission {
[
ActiveScriptWrappable,
- ConstructorCallWith=ExecutionContext,
- Constructor(DOMString title, optional NotificationOptions options),
Exposed=(Window,Worker),
- MeasureAs=NotificationCreated,
- RaisesException=Constructor,
RuntimeEnabled=Notifications
] interface Notification : EventTarget {
+ [CallWith=ExecutionContext, RaisesException, MeasureAs=NotificationCreated] constructor(DOMString title, optional NotificationOptions options = {});
[CallWith=ExecutionContext, MeasureAs=NotificationPermission] static readonly attribute NotificationPermission permission;
// TODO(crbug.com/841185): |deprecatedCallback| is not nullable in the spec.
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 8316d2e8d10..5a1eff98893 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_data.cc
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_data.cc
@@ -7,10 +7,11 @@
#include "third_party/blink/public/common/notifications/notification_constants.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/modules/v8/v8_notification_action.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_notification_options.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/modules/notifications/notification.h"
-#include "third_party/blink/renderer/modules/notifications/notification_action.h"
-#include "third_party/blink/renderer/modules/notifications/notification_options.h"
#include "third_party/blink/renderer/modules/notifications/timestamp_trigger.h"
#include "third_party/blink/renderer/modules/vibration/vibration_controller.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
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 c360e70deb5..cd965915c5b 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,10 +7,10 @@
#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/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/notification_action.h"
-#include "third_party/blink/renderer/modules/notifications/notification_options.h"
#include "third_party/blink/renderer/modules/notifications/timestamp_trigger.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
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 d41d96adbe0..cbb64ff9c7c 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_event.cc
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_event.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/modules/notifications/notification_event.h"
-#include "third_party/blink/renderer/modules/notifications/notification_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_notification_event_init.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -34,7 +34,7 @@ const AtomicString& NotificationEvent::InterfaceName() const {
return event_interface_names::kNotificationEvent;
}
-void NotificationEvent::Trace(blink::Visitor* visitor) {
+void NotificationEvent::Trace(Visitor* visitor) {
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 2ff7f52baf2..52442e1edaf 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(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
Member<Notification> notification_;
diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_event.idl b/chromium/third_party/blink/renderer/modules/notifications/notification_event.idl
index 89ded1ac7b2..768a5c5308a 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_event.idl
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_event.idl
@@ -5,10 +5,10 @@
// https://notifications.spec.whatwg.org/#service-worker-api
[
- Constructor(DOMString type, NotificationEventInit eventInitDict),
Exposed=ServiceWorker,
RuntimeEnabled=Notifications
] interface NotificationEvent : ExtendableEvent {
+ constructor(DOMString type, NotificationEventInit eventInitDict);
[ImplementedAs=getNotification] readonly attribute Notification notification;
readonly attribute DOMString action;
readonly attribute DOMString? reply;
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 041943664cf..f98a023602a 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_manager.cc
@@ -6,12 +6,12 @@
#include <utility>
+#include "base/metrics/histogram_functions.h"
#include "base/numerics/safe_conversions.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/notifications/notification.mojom-blink.h"
#include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h"
#include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink.h"
-#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -23,7 +23,6 @@
#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/histogram.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -48,7 +47,9 @@ NotificationManager* NotificationManager::From(ExecutionContext* context) {
const char NotificationManager::kSupplementName[] = "NotificationManager";
NotificationManager::NotificationManager(ExecutionContext& context)
- : Supplement<ExecutionContext>(context) {}
+ : Supplement<ExecutionContext>(context),
+ notification_service_(&context),
+ permission_service_(&context) {}
NotificationManager::~NotificationManager() = default;
@@ -70,7 +71,7 @@ ScriptPromise NotificationManager::RequestPermission(
V8NotificationPermissionCallback* deprecated_callback) {
ExecutionContext* context = ExecutionContext::From(script_state);
- if (!permission_service_) {
+ if (!permission_service_.is_bound()) {
// See https://bit.ly/2S0zRAS for task types
scoped_refptr<base::SingleThreadTaskRunner> task_runner =
context->GetTaskRunner(TaskType::kMiscPlatformAPI);
@@ -85,7 +86,7 @@ ScriptPromise NotificationManager::RequestPermission(
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
- Document* doc = DynamicTo<Document>(context);
+ Document* doc = Document::DynamicFrom(context);
permission_service_->RequestPermission(
CreatePermissionDescriptor(mojom::blink::PermissionName::NOTIFICATIONS),
LocalFrame::HasTransientUserActivation(doc ? doc->GetFrame() : nullptr),
@@ -158,10 +159,8 @@ void NotificationManager::DisplayPersistentNotification(
size_t author_data_size =
notification_data->data.has_value() ? notification_data->data->size() : 0;
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, notification_data_size_histogram,
- ("Notifications.AuthorDataSize", 1, 1000, 50));
- notification_data_size_histogram.Count(
+ base::UmaHistogramCounts1000(
+ "Notifications.AuthorDataSize",
base::saturated_cast<base::HistogramBase::Sample>(author_data_size));
if (author_data_size >
@@ -230,9 +229,9 @@ void NotificationManager::DidGetNotifications(
resolver->Resolve(notifications);
}
-const mojo::Remote<mojom::blink::NotificationService>&
+mojom::blink::NotificationService*
NotificationManager::GetNotificationService() {
- if (!notification_service_) {
+ if (!notification_service_.is_bound()) {
// See https://bit.ly/2S0zRAS for task types
scoped_refptr<base::SingleThreadTaskRunner> task_runner =
GetSupplementable()->GetTaskRunner(TaskType::kMiscPlatformAPI);
@@ -244,10 +243,12 @@ NotificationManager::GetNotificationService() {
WrapWeakPersistent(this)));
}
- return notification_service_;
+ return notification_service_.get();
}
-void NotificationManager::Trace(blink::Visitor* visitor) {
+void NotificationManager::Trace(Visitor* visitor) {
+ 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 da9fb1f6d75..bb3d8d12fa2 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/notification_manager.h
+++ b/chromium/third_party/blink/renderer/modules/notifications/notification_manager.h
@@ -7,12 +7,13 @@
#include "base/macros.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
-#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/notifications/notification_service.mojom-blink.h"
#include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_notification_permission_callback.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.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"
namespace blink {
@@ -79,7 +80,7 @@ class NotificationManager final : public GarbageCollected<NotificationManager>,
bool include_triggered,
ScriptPromiseResolver* resolver);
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
void DidDisplayPersistentNotification(
@@ -93,8 +94,7 @@ class NotificationManager final : public GarbageCollected<NotificationManager>,
// Returns an initialized NotificationService remote. A connection will be
// established the first time this method is called.
- const mojo::Remote<mojom::blink::NotificationService>&
- GetNotificationService();
+ mojom::blink::NotificationService* GetNotificationService();
void OnPermissionRequestComplete(
ScriptPromiseResolver* resolver,
@@ -104,8 +104,12 @@ class NotificationManager final : public GarbageCollected<NotificationManager>,
void OnNotificationServiceConnectionError();
void OnPermissionServiceConnectionError();
- mojo::Remote<mojom::blink::NotificationService> notification_service_;
- mojo::Remote<mojom::blink::PermissionService> permission_service_;
+ HeapMojoRemote<mojom::blink::NotificationService,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ notification_service_;
+ HeapMojoRemote<mojom::blink::PermissionService,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ permission_service_;
DISALLOW_COPY_AND_ASSIGN(NotificationManager);
};
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 be77a72dbd8..3fb8d3c562e 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
@@ -25,7 +25,7 @@ constexpr base::TimeDelta kImageFetchTimeout = base::TimeDelta::FromSeconds(90);
enum class NotificationIconType { kImage, kIcon, kBadge, kActionIcon };
-WebSize GetIconDimensions(NotificationIconType type) {
+gfx::Size GetIconDimensions(NotificationIconType type) {
switch (type) {
case NotificationIconType::kImage:
return {kNotificationMaxImageWidthPx, kNotificationMaxImageHeightPx};
@@ -102,14 +102,14 @@ void NotificationResourcesLoader::Stop() {
icon_loader->Stop();
}
-void NotificationResourcesLoader::Trace(blink::Visitor* visitor) {
+void NotificationResourcesLoader::Trace(Visitor* visitor) {
visitor->Trace(icon_loaders_);
}
void NotificationResourcesLoader::LoadIcon(
ExecutionContext* context,
const KURL& url,
- const WebSize& resize_dimensions,
+ const gfx::Size& resize_dimensions,
ThreadedIconLoader::IconCallback icon_callback) {
if (url.IsNull() || url.IsEmpty() || !url.IsValid()) {
std::move(icon_callback).Run(SkBitmap(), -1.0);
@@ -118,6 +118,8 @@ void NotificationResourcesLoader::LoadIcon(
ResourceRequest resource_request(url);
resource_request.SetRequestContext(mojom::RequestContextType::IMAGE);
+ resource_request.SetRequestDestination(
+ network::mojom::RequestDestination::kImage);
resource_request.SetPriority(ResourceLoadPriority::kMedium);
resource_request.SetTimeoutInterval(kImageFetchTimeout);
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 c772d116ecd..221d4961776 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
@@ -21,7 +21,6 @@
namespace blink {
class ExecutionContext;
-struct WebSize;
// Fetches the resources specified in a given NotificationData. Uses a
// callback to notify the caller when all fetches have finished.
@@ -55,12 +54,12 @@ class MODULES_EXPORT NotificationResourcesLoader final
// pre-finalizer.
void Stop();
- virtual void Trace(blink::Visitor* visitor);
+ virtual void Trace(Visitor* visitor);
private:
void LoadIcon(ExecutionContext* context,
const KURL& url,
- const WebSize& resize_dimensions,
+ const gfx::Size& resize_dimensions,
ThreadedIconLoader::IconCallback icon_callback);
void DidLoadIcon(SkBitmap* out_icon, SkBitmap icon, double resize_scale);
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 e46ec6de3de..7b928798975 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
@@ -48,7 +48,9 @@ class NotificationResourcesLoaderTest : public PageTestBase {
void SetUp() override { PageTestBase::SetUp(IntSize()); }
protected:
- ExecutionContext* GetExecutionContext() const { return &GetDocument(); }
+ ExecutionContext* GetExecutionContext() const {
+ return GetDocument().ToExecutionContext();
+ }
NotificationResourcesLoader* Loader() const { return loader_.Get(); }
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 1cde76266d2..cb84c76e10e 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
@@ -5,19 +5,20 @@
#include "third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.h"
#include <utility>
+
#include "base/memory/scoped_refptr.h"
+#include "base/metrics/histogram_functions.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_security_origin.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_get_notification_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_notification_options.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
-#include "third_party/blink/renderer/modules/notifications/get_notification_options.h"
#include "third_party/blink/renderer/modules/notifications/notification_data.h"
#include "third_party/blink/renderer/modules/notifications/notification_manager.h"
-#include "third_party/blink/renderer/modules/notifications/notification_options.h"
#include "third_party/blink/renderer/modules/notifications/notification_resources_loader.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_registration.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
@@ -26,7 +27,7 @@ namespace blink {
ServiceWorkerRegistrationNotifications::ServiceWorkerRegistrationNotifications(
ExecutionContext* context,
ServiceWorkerRegistration* registration)
- : ContextLifecycleObserver(context), registration_(registration) {}
+ : ExecutionContextLifecycleObserver(context), registration_(registration) {}
ScriptPromise ServiceWorkerRegistrationNotifications::showNotification(
ScriptState* script_state,
@@ -64,10 +65,9 @@ ScriptPromise ServiceWorkerRegistrationNotifications::showNotification(
// 0 -> underflow bucket,
// 1-16 -> distinct buckets,
// 17+ -> overflow bucket.
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- EnumerationHistogram, notification_count_histogram,
- ("Notifications.PersistentNotificationActionCount", 17));
- notification_count_histogram.Count(options->actions().size());
+ base::UmaHistogramExactLinear(
+ "Notifications.PersistentNotificationActionCount",
+ options->actions().size(), 17);
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
@@ -92,17 +92,16 @@ ScriptPromise ServiceWorkerRegistrationNotifications::getNotifications(
return promise;
}
-void ServiceWorkerRegistrationNotifications::ContextDestroyed(
- ExecutionContext* context) {
+void ServiceWorkerRegistrationNotifications::ContextDestroyed() {
for (auto loader : loaders_)
loader->Stop();
}
-void ServiceWorkerRegistrationNotifications::Trace(blink::Visitor* visitor) {
+void ServiceWorkerRegistrationNotifications::Trace(Visitor* visitor) {
visitor->Trace(registration_);
visitor->Trace(loaders_);
Supplement<ServiceWorkerRegistration>::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
const char ServiceWorkerRegistrationNotifications::kSupplementName[] =
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 ae6680b15b7..8af419240be 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
@@ -11,7 +11,7 @@
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/public/mojom/notifications/notification.mojom-blink-forward.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
@@ -32,7 +32,7 @@ class ServiceWorkerRegistration;
class ServiceWorkerRegistrationNotifications final
: public GarbageCollected<ServiceWorkerRegistrationNotifications>,
public Supplement<ServiceWorkerRegistration>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(ServiceWorkerRegistrationNotifications);
public:
@@ -50,10 +50,10 @@ class ServiceWorkerRegistrationNotifications final
ServiceWorkerRegistrationNotifications(ExecutionContext*,
ServiceWorkerRegistration*);
- // ContextLifecycleObserver interface.
- void ContextDestroyed(ExecutionContext* context) override;
+ // ExecutionContextLifecycleObserver interface.
+ void ContextDestroyed() override;
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
static ServiceWorkerRegistrationNotifications& From(
diff --git a/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.idl b/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.idl
index d40f95de00c..b4ec0aa5f7b 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.idl
+++ b/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.idl
@@ -9,6 +9,6 @@
ImplementedAs=ServiceWorkerRegistrationNotifications,
RuntimeEnabled=Notifications
] partial interface ServiceWorkerRegistration {
- [CallWith=ScriptState, RaisesException] Promise<void> showNotification(DOMString title, optional NotificationOptions options);
- [CallWith=ScriptState] Promise<sequence<Notification>> getNotifications(optional GetNotificationOptions filter);
+ [CallWith=ScriptState, RaisesException] Promise<void> showNotification(DOMString title, optional NotificationOptions options = {});
+ [CallWith=ScriptState] Promise<sequence<Notification>> getNotifications(optional GetNotificationOptions filter = {});
};
diff --git a/chromium/third_party/blink/renderer/modules/notifications/timestamp_trigger.idl b/chromium/third_party/blink/renderer/modules/notifications/timestamp_trigger.idl
index a648e571430..c8aa8c8440d 100644
--- a/chromium/third_party/blink/renderer/modules/notifications/timestamp_trigger.idl
+++ b/chromium/third_party/blink/renderer/modules/notifications/timestamp_trigger.idl
@@ -5,9 +5,9 @@
// Explainer: https://github.com/beverloo/notification-triggers
[
- Constructor(DOMTimeStamp timestamp),
Exposed=(Window,Worker),
RuntimeEnabled=NotificationTriggers
] interface TimestampTrigger {
+ constructor(DOMTimeStamp timestamp);
readonly attribute DOMTimeStamp timestamp;
};
diff --git a/chromium/third_party/blink/renderer/modules/payments/BUILD.gn b/chromium/third_party/blink/renderer/modules/payments/BUILD.gn
index 7a61f03750c..7fd286a66b2 100644
--- a/chromium/third_party/blink/renderer/modules/payments/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/payments/BUILD.gn
@@ -10,6 +10,8 @@ blink_modules_sources("payments") {
"abort_payment_event.h",
"abort_payment_respond_with_observer.cc",
"abort_payment_respond_with_observer.h",
+ "address_init_type_converter.cc",
+ "address_init_type_converter.h",
"basic_card_helper.cc",
"basic_card_helper.h",
"can_make_payment_event.cc",
@@ -22,8 +24,6 @@ blink_modules_sources("payments") {
"merchant_validation_event.h",
"payment_address.cc",
"payment_address.h",
- "payment_address_init_type_converter.cc",
- "payment_address_init_type_converter.h",
"payment_app_service_worker_global_scope.h",
"payment_app_service_worker_registration.cc",
"payment_app_service_worker_registration.h",
@@ -62,7 +62,5 @@ blink_modules_sources("payments") {
]
}
- deps = [
- "//components/payments/mojom:mojom_blink",
- ]
+ deps = [ "//components/payments/mojom:mojom_blink" ]
}
diff --git a/chromium/third_party/blink/renderer/modules/payments/DEPS b/chromium/third_party/blink/renderer/modules/payments/DEPS
index ffd1489d709..a7c0a85b25e 100644
--- a/chromium/third_party/blink/renderer/modules/payments/DEPS
+++ b/chromium/third_party/blink/renderer/modules/payments/DEPS
@@ -1,5 +1,3 @@
include_rules = [
"+components/payments/mojom",
- "+mojo/public/cpp/bindings/binding.h",
- "+mojo/public/cpp/bindings/interface_request.h",
]
diff --git a/chromium/third_party/blink/renderer/modules/payments/OWNERS b/chromium/third_party/blink/renderer/modules/payments/OWNERS
index c7040d66ea4..3bc3573d3eb 100644
--- a/chromium/third_party/blink/renderer/modules/payments/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/payments/OWNERS
@@ -1,12 +1,13 @@
-# TEAM: paymentrequest@chromium.org
+# TEAM: payments-dev@chromium.org
# COMPONENT: Blink>Payments
+file://components/payments/OWNERS
+
jinho.bang@samsung.com
-mathp@chromium.org
mek@chromium.org
-rouslan@chromium.org
-danyao@chromium.org
-sahel@chromium.org
per-file *_type_converter*.*=set noparent
per-file *_type_converter*.*=file://ipc/SECURITY_OWNERS
+
+# Emeritus
+mathp@chromium.org
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 99dcad8a830..eccca7e5b28 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
@@ -6,8 +6,8 @@
#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_extendable_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
-#include "third_party/blink/renderer/modules/service_worker/extendable_event_init.h"
#include "third_party/blink/renderer/modules/service_worker/respond_with_observer.h"
#include "third_party/blink/renderer/modules/service_worker/wait_until_observer.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -47,7 +47,7 @@ void AbortPaymentEvent::respondWith(ScriptState* script_state,
}
}
-void AbortPaymentEvent::Trace(blink::Visitor* visitor) {
+void AbortPaymentEvent::Trace(Visitor* visitor) {
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 06bfa035529..43716808d9e 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<RespondWithObserver> observer_;
diff --git a/chromium/third_party/blink/renderer/modules/payments/abort_payment_event.idl b/chromium/third_party/blink/renderer/modules/payments/abort_payment_event.idl
index e1cd327f99c..0bb4311eb72 100644
--- a/chromium/third_party/blink/renderer/modules/payments/abort_payment_event.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/abort_payment_event.idl
@@ -6,8 +6,8 @@
[
RuntimeEnabled=PaymentApp,
- Constructor(DOMString type, ExtendableEventInit eventInitDict),
Exposed=ServiceWorker
] interface AbortPaymentEvent : ExtendableEvent {
+ constructor(DOMString type, ExtendableEventInit eventInitDict);
[CallWith=ScriptState, RaisesException] void respondWith(Promise<boolean> paymentAbortedResponse);
};
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 c1b726fc76c..64212d5be81 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(blink::Visitor* visitor) {
+void AbortPaymentRespondWithObserver::Trace(Visitor* visitor) {
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 112e23f1d28..da44a5a0102 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/payments/abort_test.cc b/chromium/third_party/blink/renderer/modules/payments/abort_test.cc
index 744bf207dc1..0e1963d90d8 100644
--- a/chromium/third_party/blink/renderer/modules/payments/abort_test.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/abort_test.cc
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/modules/payments/payment_request.h"
#include "third_party/blink/renderer/modules/payments/payment_test_helper.h"
+#include "third_party/blink/renderer/platform/bindings/exception_code.h"
namespace blink {
namespace {
@@ -16,28 +17,28 @@ namespace {
// abort() should reject with exception.
TEST(AbortTest, CannotAbortBeforeShow) {
PaymentRequestV8TestingScope scope;
- PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
- request->abort(scope.GetScriptState())
- .Then(funcs.ExpectNoCall(), funcs.ExpectCall());
+ request->abort(scope.GetScriptState(), scope.GetExceptionState());
+ EXPECT_EQ(scope.GetExceptionState().Code(),
+ ToExceptionCode(DOMExceptionCode::kInvalidStateError));
}
// If request.abort() is called again before the previous abort() resolved, then
// the second abort() should reject with exception.
TEST(AbortTest, CannotAbortTwiceConcurrently) {
PaymentRequestV8TestingScope scope;
- PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- request->show(scope.GetScriptState());
- request->abort(scope.GetScriptState());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION);
+ request->abort(scope.GetScriptState(), ASSERT_NO_EXCEPTION);
- request->abort(scope.GetScriptState())
- .Then(funcs.ExpectNoCall(), funcs.ExpectCall());
+ request->abort(scope.GetScriptState(), scope.GetExceptionState());
+ EXPECT_EQ(scope.GetExceptionState().Code(),
+ ToExceptionCode(DOMExceptionCode::kInvalidStateError));
}
// If request.abort() is called after calling request.show(), then abort()
@@ -47,10 +48,10 @@ TEST(AbortTest, CanAbortAfterShow) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- request->show(scope.GetScriptState());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION);
- request->abort(scope.GetScriptState())
+ request->abort(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectNoCall());
}
@@ -61,10 +62,10 @@ TEST(AbortTest, FailedAbortShouldRejectAbortPromise) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- request->show(scope.GetScriptState());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION);
- request->abort(scope.GetScriptState())
+ request->abort(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)->OnAbort(
@@ -78,13 +79,13 @@ TEST(AbortTest, CanAbortAgainAfterFirstAbortRejected) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- request->show(scope.GetScriptState());
- request->abort(scope.GetScriptState());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION);
+ request->abort(scope.GetScriptState(), ASSERT_NO_EXCEPTION);
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)->OnAbort(
false);
- request->abort(scope.GetScriptState())
+ request->abort(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectNoCall());
}
@@ -95,11 +96,11 @@ TEST(AbortTest, SuccessfulAbortShouldRejectShowPromiseAndResolveAbortPromise) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
- request->abort(scope.GetScriptState())
+ request->abort(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectCall(), funcs.ExpectNoCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)->OnAbort(
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_address_init.idl b/chromium/third_party/blink/renderer/modules/payments/address_init.idl
index fb7733fa217..bd1dc3d456e 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_address_init.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/address_init.idl
@@ -4,7 +4,7 @@
// https://w3c.github.io/payment-request/#dom-addressinit
-dictionary PaymentAddressInit {
+dictionary AddressInit {
DOMString country;
sequence<DOMString> addressLine;
DOMString region;
@@ -15,4 +15,4 @@ dictionary PaymentAddressInit {
DOMString organization;
DOMString recipient;
DOMString phone;
-}; \ No newline at end of file
+};
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_address_init_type_converter.cc b/chromium/third_party/blink/renderer/modules/payments/address_init_type_converter.cc
index a983a133f4d..21fc8270d17 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_address_init_type_converter.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/address_init_type_converter.cc
@@ -2,15 +2,14 @@
// 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_address_init_type_converter.h"
+#include "third_party/blink/renderer/modules/payments/address_init_type_converter.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace mojo {
-payments::mojom::blink::PaymentAddressPtr TypeConverter<
- payments::mojom::blink::PaymentAddressPtr,
- blink::PaymentAddressInit*>::Convert(const blink::PaymentAddressInit*
- input) {
+payments::mojom::blink::PaymentAddressPtr
+TypeConverter<payments::mojom::blink::PaymentAddressPtr,
+ blink::AddressInit*>::Convert(const blink::AddressInit* input) {
payments::mojom::blink::PaymentAddressPtr output =
payments::mojom::blink::PaymentAddress::New();
output->country = input->hasCountry() ? input->country() : g_empty_string;
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_address_init_type_converter.h b/chromium/third_party/blink/renderer/modules/payments/address_init_type_converter.h
index f857842673c..10dff24f9fd 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_address_init_type_converter.h
+++ b/chromium/third_party/blink/renderer/modules/payments/address_init_type_converter.h
@@ -2,22 +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_MODULES_PAYMENTS_PAYMENT_ADDRESS_INIT_TYPE_CONVERTER_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_ADDRESS_INIT_TYPE_CONVERTER_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_ADDRESS_INIT_TYPE_CONVERTER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_ADDRESS_INIT_TYPE_CONVERTER_H_
#include "components/payments/mojom/payment_request_data.mojom-blink.h"
#include "mojo/public/cpp/bindings/type_converter.h"
-#include "third_party/blink/renderer/modules/payments/payment_address_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_address_init.h"
namespace mojo {
template <>
struct TypeConverter<payments::mojom::blink::PaymentAddressPtr,
- blink::PaymentAddressInit*> {
+ blink::AddressInit*> {
static payments::mojom::blink::PaymentAddressPtr Convert(
- const blink::PaymentAddressInit* input);
+ const blink::AddressInit* input);
};
} // namespace mojo
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_ADDRESS_INIT_TYPE_CONVERTER_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_ADDRESS_INIT_TYPE_CONVERTER_H_
diff --git a/chromium/third_party/blink/renderer/modules/payments/android_pay_method_data.idl b/chromium/third_party/blink/renderer/modules/payments/android_pay_method_data.idl
index ad52173b460..301c118d885 100644
--- a/chromium/third_party/blink/renderer/modules/payments/android_pay_method_data.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/android_pay_method_data.idl
@@ -7,10 +7,6 @@
dictionary AndroidPayMethodData {
DOMString environment;
- DOMString merchantName;
- DOMString merchantId;
- sequence<DOMString> allowedCardNetworks;
- AndroidPayTokenization paymentMethodTokenizationParameters;
DOMString minGooglePlayServicesVersion;
long apiVersion;
};
diff --git a/chromium/third_party/blink/renderer/modules/payments/android_pay_tokenization.idl b/chromium/third_party/blink/renderer/modules/payments/android_pay_tokenization.idl
deleted file mode 100644
index dfd76880731..00000000000
--- a/chromium/third_party/blink/renderer/modules/payments/android_pay_tokenization.idl
+++ /dev/null
@@ -1,11 +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.
-
-// https://developers.google.com/web/fundamentals/getting-started/primers/payment-request/android-pay
-// TODO(rouslan): Stop parsing Android Pay data. http://crbug.com/620173
-
-dictionary AndroidPayTokenization {
- DOMString tokenizationType;
- Dictionary parameters;
-};
diff --git a/chromium/third_party/blink/renderer/modules/payments/basic_card_helper.cc b/chromium/third_party/blink/renderer/modules/payments/basic_card_helper.cc
index 96d7c5fd9c5..042ba904134 100644
--- a/chromium/third_party/blink/renderer/modules/payments/basic_card_helper.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/basic_card_helper.cc
@@ -5,8 +5,8 @@
#include "third_party/blink/renderer/modules/payments/basic_card_helper.h"
#include "base/stl_util.h"
+#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_basic_card_request.h"
-#include "third_party/blink/renderer/modules/payments/basic_card_request.h"
#include "third_party/blink/renderer/modules/payments/payment_request.h"
namespace blink {
@@ -14,7 +14,6 @@ namespace blink {
namespace {
using ::payments::mojom::blink::BasicCardNetwork;
-using ::payments::mojom::blink::BasicCardType;
const struct {
const payments::mojom::BasicCardNetwork code;
@@ -28,26 +27,17 @@ const struct {
{BasicCardNetwork::UNIONPAY, "unionpay"},
{BasicCardNetwork::VISA, "visa"}};
-const struct {
- const BasicCardType code;
- const char* const name;
-} kBasicCardTypes[] = {{BasicCardType::CREDIT, "credit"},
- {BasicCardType::DEBIT, "debit"},
- {BasicCardType::PREPAID, "prepaid"}};
-
} // namespace
void BasicCardHelper::ParseBasiccardData(
const ScriptValue& input,
Vector<BasicCardNetwork>& supported_networks_output,
- Vector<BasicCardType>& supported_types_output,
- bool* has_supported_card_types,
ExceptionState& exception_state) {
DCHECK(!input.IsEmpty());
- BasicCardRequest* basic_card = BasicCardRequest::Create();
- V8BasicCardRequest::ToImpl(input.GetIsolate(), input.V8Value(), basic_card,
- exception_state);
+ BasicCardRequest* basic_card =
+ NativeValueTraits<BasicCardRequest>::NativeValue(
+ input.GetIsolate(), input.V8Value(), exception_state);
if (exception_state.HadException())
return;
@@ -67,27 +57,6 @@ void BasicCardHelper::ParseBasiccardData(
}
}
}
-
- if (basic_card->hasSupportedTypes()) {
- if (has_supported_card_types) {
- *has_supported_card_types = true;
- }
-
- if (basic_card->supportedTypes().size() > PaymentRequest::kMaxListSize) {
- exception_state.ThrowTypeError(
- "basic-card supportedTypes cannot be longer than 1024 elements");
- return;
- }
-
- for (const String& type : basic_card->supportedTypes()) {
- for (size_t i = 0; i < base::size(kBasicCardTypes); ++i) {
- if (type == kBasicCardTypes[i].name) {
- supported_types_output.push_back(kBasicCardTypes[i].code);
- break;
- }
- }
- }
- }
}
bool BasicCardHelper::IsNetworkName(const String& input) {
diff --git a/chromium/third_party/blink/renderer/modules/payments/basic_card_helper.h b/chromium/third_party/blink/renderer/modules/payments/basic_card_helper.h
index 67b7a83f3da..647f49315ae 100644
--- a/chromium/third_party/blink/renderer/modules/payments/basic_card_helper.h
+++ b/chromium/third_party/blink/renderer/modules/payments/basic_card_helper.h
@@ -18,17 +18,11 @@ class BasicCardHelper {
public:
// Parse 'basic-card' data in |input| and store result in
- // |supported_networks_output| and |supported_types_output| or throw
- // exception.
- //
- // If |has_supported_card_types| is not null, then it is set to true if the
- // basic-card specific method data has the "supportedTypes" field.
+ // |supported_networks_output| or throw exception.
static void ParseBasiccardData(
const ScriptValue& input,
Vector<::payments::mojom::blink::BasicCardNetwork>&
supported_networks_output,
- Vector<::payments::mojom::blink::BasicCardType>& supported_types_output,
- bool* has_supported_card_types,
ExceptionState&);
// Check whether |input| is 'basic-card' network name.
diff --git a/chromium/third_party/blink/renderer/modules/payments/basic_card_request.idl b/chromium/third_party/blink/renderer/modules/payments/basic_card_request.idl
index 9bd0aeb9b2b..98d9b5d47ca 100644
--- a/chromium/third_party/blink/renderer/modules/payments/basic_card_request.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/basic_card_request.idl
@@ -2,15 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://w3c.github.io/webpayments-methods-card/#basiccardrequest
-
-enum BasicCardType {
- "credit",
- "debit",
- "prepaid"
-};
+// https://w3c.github.io/payment-method-basic-card/#basiccardrequest-dictionary
dictionary BasicCardRequest {
- sequence<DOMString> supportedNetworks;
- sequence<BasicCardType> supportedTypes;
+ sequence<DOMString> supportedNetworks = [];
};
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 f30ba000e7d..f78a31117f9 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
@@ -8,7 +8,7 @@
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/core/workers/worker_location.h"
-#include "third_party/blink/renderer/modules/service_worker/respond_with_observer.h"
+#include "third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
@@ -24,7 +24,7 @@ CanMakePaymentEvent* CanMakePaymentEvent::Create(
CanMakePaymentEvent* CanMakePaymentEvent::Create(
const AtomicString& type,
const CanMakePaymentEventInit* initializer,
- RespondWithObserver* respond_with_observer,
+ CanMakePaymentRespondWithObserver* respond_with_observer,
WaitUntilObserver* wait_until_observer) {
return MakeGarbageCollected<CanMakePaymentEvent>(
type, initializer, respond_with_observer, wait_until_observer);
@@ -57,20 +57,23 @@ CanMakePaymentEvent::modifiers() const {
void CanMakePaymentEvent::respondWith(ScriptState* script_state,
ScriptPromise script_promise,
ExceptionState& exception_state) {
- if (!isTrusted()) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kInvalidStateError,
- "Cannot respond with data when the event is not trusted");
- return;
- }
+ RespondToCanMakePaymentEvent(script_state, script_promise, exception_state,
+ /*is_minimal_ui=*/false);
+}
- stopImmediatePropagation();
- if (observer_) {
- observer_->RespondWith(script_state, script_promise, exception_state);
- }
+const String& CanMakePaymentEvent::currency() const {
+ return currency_;
+}
+
+void CanMakePaymentEvent::respondWithMinimalUI(
+ ScriptState* script_state,
+ ScriptPromise script_promise,
+ ExceptionState& exception_state) {
+ RespondToCanMakePaymentEvent(script_state, script_promise, exception_state,
+ /*is_minimal_ui=*/true);
}
-void CanMakePaymentEvent::Trace(blink::Visitor* visitor) {
+void CanMakePaymentEvent::Trace(Visitor* visitor) {
visitor->Trace(method_data_);
visitor->Trace(modifiers_);
visitor->Trace(observer_);
@@ -80,7 +83,7 @@ void CanMakePaymentEvent::Trace(blink::Visitor* visitor) {
CanMakePaymentEvent::CanMakePaymentEvent(
const AtomicString& type,
const CanMakePaymentEventInit* initializer,
- RespondWithObserver* respond_with_observer,
+ CanMakePaymentRespondWithObserver* respond_with_observer,
WaitUntilObserver* wait_until_observer)
: ExtendableEvent(type, initializer, wait_until_observer),
top_origin_(initializer->topOrigin()),
@@ -91,6 +94,26 @@ CanMakePaymentEvent::CanMakePaymentEvent(
modifiers_(initializer->hasModifiers()
? initializer->modifiers()
: HeapVector<Member<PaymentDetailsModifier>>()),
+ currency_(initializer->currency()),
observer_(respond_with_observer) {}
+void CanMakePaymentEvent::RespondToCanMakePaymentEvent(
+ ScriptState* script_state,
+ ScriptPromise script_promise,
+ ExceptionState& exception_state,
+ bool is_minimal_ui) {
+ if (!isTrusted()) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "Cannot respond with data when the event is not trusted");
+ return;
+ }
+
+ stopImmediatePropagation();
+ if (observer_) {
+ observer_->ObservePromiseResponse(script_state, script_promise,
+ exception_state, is_minimal_ui);
+ }
+}
+
} // namespace blink
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 32a0ffaaab5..42d84b9f54a 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
@@ -7,10 +7,10 @@
#include "base/macros.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.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_details_modifier.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_method_data.h"
#include "third_party/blink/renderer/modules/event_modules.h"
-#include "third_party/blink/renderer/modules/payments/can_make_payment_event_init.h"
-#include "third_party/blink/renderer/modules/payments/payment_details_modifier.h"
-#include "third_party/blink/renderer/modules/payments/payment_method_data.h"
#include "third_party/blink/renderer/modules/service_worker/extendable_event.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -20,7 +20,7 @@ class AtomicString;
namespace blink {
-class RespondWithObserver;
+class CanMakePaymentRespondWithObserver;
class ScriptState;
class MODULES_EXPORT CanMakePaymentEvent final : public ExtendableEvent {
@@ -31,12 +31,12 @@ class MODULES_EXPORT CanMakePaymentEvent final : public ExtendableEvent {
const CanMakePaymentEventInit*);
static CanMakePaymentEvent* Create(const AtomicString& type,
const CanMakePaymentEventInit*,
- RespondWithObserver*,
+ CanMakePaymentRespondWithObserver*,
WaitUntilObserver*);
CanMakePaymentEvent(const AtomicString& type,
const CanMakePaymentEventInit*,
- RespondWithObserver*,
+ CanMakePaymentRespondWithObserver*,
WaitUntilObserver*);
~CanMakePaymentEvent() override;
@@ -49,15 +49,24 @@ class MODULES_EXPORT CanMakePaymentEvent final : public ExtendableEvent {
void respondWith(ScriptState*, ScriptPromise, ExceptionState&);
- void Trace(blink::Visitor*) override;
+ const String& currency() const;
+ void respondWithMinimalUI(ScriptState*, ScriptPromise, ExceptionState&);
+
+ void Trace(Visitor*) override;
private:
+ void RespondToCanMakePaymentEvent(ScriptState*,
+ ScriptPromise,
+ ExceptionState&,
+ bool is_minimal_ui);
+
String top_origin_;
String payment_request_origin_;
HeapVector<Member<PaymentMethodData>> method_data_;
HeapVector<Member<PaymentDetailsModifier>> modifiers_;
+ String currency_;
- Member<RespondWithObserver> observer_;
+ Member<CanMakePaymentRespondWithObserver> observer_;
DISALLOW_COPY_AND_ASSIGN(CanMakePaymentEvent);
};
diff --git a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.idl b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.idl
index b56ea70f03f..9f08ffdabcc 100644
--- a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.idl
@@ -2,17 +2,21 @@
// 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/#the-canmakepaymentevent
[
RuntimeEnabled=PaymentApp,
- Constructor(DOMString type, CanMakePaymentEventInit eventInitDict),
Exposed=ServiceWorker
] interface CanMakePaymentEvent : ExtendableEvent {
+ constructor(DOMString type, CanMakePaymentEventInit eventInitDict);
readonly attribute USVString topOrigin;
readonly attribute USVString paymentRequestOrigin;
readonly attribute FrozenArray<PaymentMethodData> methodData;
readonly attribute FrozenArray<PaymentDetailsModifier> modifiers;
[CallWith=ScriptState, RaisesException] void respondWith(Promise<boolean> canMakePaymentResponse);
+
+ // https://gist.github.com/rsolomakhin/eba91c185028899883d2c7f37f357d7c
+ [RuntimeEnabled=PaymentHandlerMinimalUI] readonly attribute DOMString currency;
+ [RuntimeEnabled=PaymentHandlerMinimalUI, CallWith=ScriptState, RaisesException] void respondWithMinimalUI(Promise<CanMakePaymentResponse> response);
};
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 aed5b687b5a..e7d2240a6dd 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
@@ -9,4 +9,7 @@ dictionary CanMakePaymentEventInit : ExtendableEventInit {
USVString paymentRequestOrigin;
sequence<PaymentMethodData> methodData;
sequence<PaymentDetailsModifier> modifiers;
+
+ // https://gist.github.com/rsolomakhin/eba91c185028899883d2c7f37f357d7c
+ DOMString currency;
};
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 6bcf47031e8..0b11a249f30 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
@@ -6,14 +6,22 @@
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_can_make_payment_response.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/modules/payments/payment_handler_utils.h"
+#include "third_party/blink/renderer/modules/payments/payments_validators.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h"
#include "third_party/blink/renderer/modules/service_worker/wait_until_observer.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "v8/include/v8.h"
namespace blink {
+namespace {
+
+using ResponseType = payments::mojom::blink::CanMakePaymentEventResponseType;
+
+} // namespace
CanMakePaymentRespondWithObserver::CanMakePaymentRespondWithObserver(
ExecutionContext* context,
@@ -22,12 +30,14 @@ CanMakePaymentRespondWithObserver::CanMakePaymentRespondWithObserver(
: RespondWithObserver(context, event_id, observer) {}
void CanMakePaymentRespondWithObserver::OnResponseRejected(
- blink::mojom::ServiceWorkerResponseError error) {
+ mojom::blink::ServiceWorkerResponseError error) {
PaymentHandlerUtils::ReportResponseError(GetExecutionContext(),
"CanMakePaymentEvent", error);
-
- To<ServiceWorkerGlobalScope>(GetExecutionContext())
- ->RespondToCanMakePaymentEvent(event_id_, false);
+ RespondWithoutMinimalUI(
+ error == mojom::blink::ServiceWorkerResponseError::kPromiseRejected
+ ? ResponseType::REJECT
+ : ResponseType::INTERNAL_ERROR,
+ false);
}
void CanMakePaymentRespondWithObserver::OnResponseFulfilled(
@@ -39,26 +49,120 @@ void CanMakePaymentRespondWithObserver::OnResponseFulfilled(
DCHECK(GetExecutionContext());
ExceptionState exception_state(script_state->GetIsolate(), context_type,
interface_name, property_name);
- bool response =
+ if (is_minimal_ui_) {
+ OnResponseFulfilledForMinimalUI(script_state, value, exception_state);
+ return;
+ }
+
+ bool can_make_payment =
ToBoolean(script_state->GetIsolate(), value.V8Value(), exception_state);
if (exception_state.HadException()) {
- exception_state.ClearException();
- OnResponseRejected(blink::mojom::ServiceWorkerResponseError::kNoV8Instance);
+ RespondWithoutMinimalUI(ResponseType::BOOLEAN_CONVERSION_ERROR, false);
return;
}
- To<ServiceWorkerGlobalScope>(GetExecutionContext())
- ->RespondToCanMakePaymentEvent(event_id_, response);
+ RespondWithoutMinimalUI(ResponseType::SUCCESS, can_make_payment);
}
void CanMakePaymentRespondWithObserver::OnNoResponse() {
- DCHECK(GetExecutionContext());
- To<ServiceWorkerGlobalScope>(GetExecutionContext())
- ->RespondToCanMakePaymentEvent(event_id_, true);
+ ConsoleWarning(
+ "To control whether your payment handler can be used, handle the "
+ "'canmakepayment' event explicitly. Otherwise, it is assumed implicitly "
+ "that your payment handler can always be used.");
+ RespondWithoutMinimalUI(ResponseType::NO_RESPONSE, true);
}
-void CanMakePaymentRespondWithObserver::Trace(blink::Visitor* visitor) {
+void CanMakePaymentRespondWithObserver::Trace(Visitor* visitor) {
RespondWithObserver::Trace(visitor);
}
+void CanMakePaymentRespondWithObserver::ObservePromiseResponse(
+ ScriptState* script_state,
+ ScriptPromise promise,
+ ExceptionState& exception_state,
+ bool is_minimal_ui) {
+ is_minimal_ui_ = is_minimal_ui;
+ RespondWith(script_state, promise, exception_state);
+}
+
+void CanMakePaymentRespondWithObserver::OnResponseFulfilledForMinimalUI(
+ ScriptState* script_state,
+ const ScriptValue& value,
+ ExceptionState& exception_state) {
+ CanMakePaymentResponse* response =
+ NativeValueTraits<CanMakePaymentResponse>::NativeValue(
+ script_state->GetIsolate(), value.V8Value(), exception_state);
+ if (exception_state.HadException()) {
+ RespondWithoutMinimalUI(ResponseType::MINIMAL_UI_RESPONSE_CONVERSION_ERROR,
+ false);
+ return;
+ }
+
+ if (!response->hasCanMakePayment()) {
+ ConsoleWarning(
+ "To use minimal UI, specify the value of 'canMakePayment' explicitly. "
+ "Otherwise, the value of 'false' is assumed implicitly.");
+ RespondWithoutMinimalUI(ResponseType::NO_CAN_MAKE_PAYMENT_VALUE, false);
+ return;
+ }
+
+ if (!response->hasReadyForMinimalUI()) {
+ ConsoleWarning(
+ "To use minimal UI, specify the value of 'readyForMinimalUI' "
+ "explicitly. Otherwise, the value of 'false' is assumed implicitly.");
+ RespondWithoutMinimalUI(ResponseType::NO_READY_FOR_MINIMAL_UI_VALUE,
+ response->canMakePayment());
+ return;
+ }
+
+ if (!response->hasAccountBalance() || response->accountBalance().IsEmpty()) {
+ ConsoleWarning(
+ "To use minimal UI, specify 'accountBalance' value, e.g., '1.00'.");
+ RespondWithoutMinimalUI(ResponseType::NO_ACCOUNT_BALANCE_VALUE,
+ response->canMakePayment());
+ return;
+ }
+
+ String error_message;
+ if (!PaymentsValidators::IsValidAmountFormat(
+ response->accountBalance(), "account balance", &error_message)) {
+ ConsoleWarning(error_message +
+ ". To use minimal UI, format 'accountBalance' as, for "
+ "example, '1.00'.");
+ RespondWithoutMinimalUI(ResponseType::INVALID_ACCOUNT_BALANCE_VALUE,
+ response->canMakePayment());
+ return;
+ }
+
+ RespondInternal(ResponseType::SUCCESS, response->canMakePayment(),
+ response->readyForMinimalUI(), response->accountBalance());
+}
+
+void CanMakePaymentRespondWithObserver::ConsoleWarning(const String& message) {
+ GetExecutionContext()->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kJavaScript,
+ mojom::blink::ConsoleMessageLevel::kWarning, message));
+}
+
+void CanMakePaymentRespondWithObserver::RespondWithoutMinimalUI(
+ ResponseType response_type,
+ bool can_make_payment) {
+ RespondInternal(response_type, can_make_payment,
+ /*ready_for_minimal_ui=*/false,
+ /*account_balance=*/String());
+}
+
+void CanMakePaymentRespondWithObserver::RespondInternal(
+ ResponseType response_type,
+ bool can_make_payment,
+ bool ready_for_minimal_ui,
+ const String& account_balance) {
+ DCHECK(GetExecutionContext());
+ To<ServiceWorkerGlobalScope>(GetExecutionContext())
+ ->RespondToCanMakePaymentEvent(
+ event_id_, payments::mojom::blink::CanMakePaymentResponse::New(
+ response_type, can_make_payment, ready_for_minimal_ui,
+ account_balance));
+}
+
} // namespace blink
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 4adbd591a0f..41a0b5ca480 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
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_CAN_MAKE_PAYMENT_RESPOND_WITH_OBSERVER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_CAN_MAKE_PAYMENT_RESPOND_WITH_OBSERVER_H_
+#include "third_party/blink/public/mojom/payments/payment_app.mojom-blink.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom-blink-forward.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/service_worker/respond_with_observer.h"
@@ -15,8 +16,9 @@ class ExecutionContext;
class ScriptValue;
class WaitUntilObserver;
-// Implementation for CanMakePaymentEvent.respondWith(), which is used by the
-// payment handler to indicate whether it can respond to a payment request.
+// Implementation for CanMakePaymentEvent.respondWith() and
+// CanMakePayment.respondWithMinimalUI(), which are used by the payment handler
+// to indicate whether it can respond to a payment request.
class MODULES_EXPORT CanMakePaymentRespondWithObserver final
: public RespondWithObserver {
public:
@@ -25,7 +27,7 @@ class MODULES_EXPORT CanMakePaymentRespondWithObserver final
WaitUntilObserver*);
~CanMakePaymentRespondWithObserver() override = default;
- void OnResponseRejected(mojom::ServiceWorkerResponseError) override;
+ void OnResponseRejected(mojom::blink::ServiceWorkerResponseError) override;
void OnResponseFulfilled(ScriptState*,
const ScriptValue&,
ExceptionState::ContextType,
@@ -33,7 +35,31 @@ class MODULES_EXPORT CanMakePaymentRespondWithObserver final
const char* property_name) override;
void OnNoResponse() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
+
+ // Observes the given promise and calls OnResponseRejected() or
+ // OnResponseFulfilled().
+ void ObservePromiseResponse(ScriptState*,
+ ScriptPromise,
+ ExceptionState&,
+ bool is_minimal_ui);
+
+ private:
+ void OnResponseFulfilledForMinimalUI(ScriptState*,
+ const ScriptValue&,
+ ExceptionState&);
+
+ void ConsoleWarning(const String& message);
+ void RespondWithoutMinimalUI(
+ payments::mojom::blink::CanMakePaymentEventResponseType response_type,
+ bool can_make_payment);
+ void RespondInternal(
+ payments::mojom::blink::CanMakePaymentEventResponseType response_type,
+ bool can_make_payment,
+ bool ready_for_minimal_ui,
+ const String& account_balance);
+
+ bool is_minimal_ui_ = false;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_response.idl b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_response.idl
new file mode 100644
index 00000000000..6d28b324374
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_response.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://gist.github.com/rsolomakhin/eba91c185028899883d2c7f37f357d7c
+
+dictionary CanMakePaymentResponse {
+ boolean canMakePayment;
+ boolean readyForMinimalUI;
+ DOMString accountBalance;
+};
diff --git a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_test.cc b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_test.cc
index aa8eee53e38..96b539aee6d 100644
--- a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_test.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_test.cc
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/modules/payments/payment_request.h"
#include "third_party/blink/renderer/modules/payments/payment_test_helper.h"
+#include "third_party/blink/renderer/platform/bindings/exception_code.h"
namespace blink {
namespace {
@@ -22,9 +23,9 @@ TEST(HasEnrolledInstrumentTest, RejectPromiseOnUserCancel) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
- request->hasEnrolledInstrument(scope.GetScriptState())
+ request->hasEnrolledInstrument(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<PaymentRequestClient*>(request)->OnError(
@@ -36,9 +37,9 @@ TEST(HasEnrolledInstrumentTest, RejectPromiseOnUnknownError) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
- request->hasEnrolledInstrument(scope.GetScriptState())
+ request->hasEnrolledInstrument(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<PaymentRequestClient*>(request)->OnError(
@@ -47,13 +48,14 @@ TEST(HasEnrolledInstrumentTest, RejectPromiseOnUnknownError) {
TEST(HasEnrolledInstrumentTest, RejectDuplicateRequest) {
PaymentRequestV8TestingScope scope;
- PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- request->hasEnrolledInstrument(scope.GetScriptState());
- request->hasEnrolledInstrument(scope.GetScriptState())
- .Then(funcs.ExpectNoCall(), funcs.ExpectCall());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
+ request->hasEnrolledInstrument(scope.GetScriptState(), ASSERT_NO_EXCEPTION);
+ request->hasEnrolledInstrument(scope.GetScriptState(),
+ scope.GetExceptionState());
+ EXPECT_EQ(scope.GetExceptionState().Code(),
+ ToExceptionCode(DOMExceptionCode::kInvalidStateError));
}
TEST(HasEnrolledInstrumentTest, RejectQueryQuotaExceeded) {
@@ -61,9 +63,9 @@ TEST(HasEnrolledInstrumentTest, RejectQueryQuotaExceeded) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
- request->hasEnrolledInstrument(scope.GetScriptState())
+ request->hasEnrolledInstrument(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<PaymentRequestClient*>(request)->OnHasEnrolledInstrument(
@@ -75,9 +77,9 @@ TEST(HasEnrolledInstrumentTest, ReturnHasNoEnrolledInstrument) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
String captor;
- request->hasEnrolledInstrument(scope.GetScriptState())
+ request->hasEnrolledInstrument(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectCall(&captor), funcs.ExpectNoCall());
static_cast<PaymentRequestClient*>(request)->OnHasEnrolledInstrument(
@@ -92,9 +94,9 @@ TEST(HasEnrolledInstrumentTest, ReturnHasEnrolledInstrument) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
String captor;
- request->hasEnrolledInstrument(scope.GetScriptState())
+ request->hasEnrolledInstrument(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectCall(&captor), funcs.ExpectNoCall());
static_cast<PaymentRequestClient*>(request)->OnHasEnrolledInstrument(
@@ -109,9 +111,9 @@ TEST(CanMakePaymentTest, RejectPromiseOnUserCancel) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
- request->canMakePayment(scope.GetScriptState())
+ request->canMakePayment(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<PaymentRequestClient*>(request)->OnError(
@@ -124,9 +126,9 @@ TEST(CanMakePaymentTest, RejectPromiseOnUnknownError) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
- request->canMakePayment(scope.GetScriptState())
+ request->canMakePayment(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<PaymentRequestClient*>(request)->OnError(
@@ -135,14 +137,14 @@ TEST(CanMakePaymentTest, RejectPromiseOnUnknownError) {
TEST(CanMakePaymentTest, RejectDuplicateRequest) {
PaymentRequestV8TestingScope scope;
- PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- request->canMakePayment(scope.GetScriptState());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
+ request->canMakePayment(scope.GetScriptState(), ASSERT_NO_EXCEPTION);
- request->canMakePayment(scope.GetScriptState())
- .Then(funcs.ExpectNoCall(), funcs.ExpectCall());
+ request->canMakePayment(scope.GetScriptState(), scope.GetExceptionState());
+ EXPECT_EQ(scope.GetExceptionState().Code(),
+ ToExceptionCode(DOMExceptionCode::kInvalidStateError));
}
TEST(CanMakePaymentTest, ReturnCannotMakePayment) {
@@ -150,9 +152,9 @@ TEST(CanMakePaymentTest, ReturnCannotMakePayment) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
String captor;
- request->canMakePayment(scope.GetScriptState())
+ request->canMakePayment(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectCall(&captor), funcs.ExpectNoCall());
static_cast<PaymentRequestClient*>(request)->OnCanMakePayment(
@@ -167,9 +169,9 @@ TEST(CanMakePaymentTest, ReturnCanMakePayment) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
String captor;
- request->canMakePayment(scope.GetScriptState())
+ request->canMakePayment(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectCall(&captor), funcs.ExpectNoCall());
static_cast<PaymentRequestClient*>(request)->OnCanMakePayment(
diff --git a/chromium/third_party/blink/renderer/modules/payments/complete_test.cc b/chromium/third_party/blink/renderer/modules/payments/complete_test.cc
index eb6d5eb7dcd..112020f7ef5 100644
--- a/chromium/third_party/blink/renderer/modules/payments/complete_test.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/complete_test.cc
@@ -8,27 +8,28 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/modules/payments/payment_request.h"
#include "third_party/blink/renderer/modules/payments/payment_test_helper.h"
+#include "third_party/blink/renderer/platform/bindings/exception_code.h"
namespace blink {
namespace {
TEST(CompleteTest, CannotCallCompleteTwice) {
PaymentRequestV8TestingScope scope;
- PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
- request->show(scope.GetScriptState());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION);
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
->OnPaymentResponse(BuildPaymentResponseForTest());
request->Complete(scope.GetScriptState(),
- PaymentStateResolver::PaymentComplete::kFail);
+ PaymentStateResolver::PaymentComplete::kFail,
+ ASSERT_NO_EXCEPTION);
- request
- ->Complete(scope.GetScriptState(),
- PaymentStateResolver::PaymentComplete::kSuccess)
- .Then(funcs.ExpectNoCall(), funcs.ExpectCall());
+ request->Complete(scope.GetScriptState(),
+ PaymentStateResolver::PaymentComplete::kSuccess,
+ scope.GetExceptionState());
+ EXPECT_EQ(scope.GetExceptionState().Code(),
+ ToExceptionCode(DOMExceptionCode::kInvalidStateError));
}
TEST(CompleteTest, ResolveCompletePromiseOnUnknownError) {
@@ -36,15 +37,15 @@ TEST(CompleteTest, ResolveCompletePromiseOnUnknownError) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
- request->show(scope.GetScriptState());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION);
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
->OnPaymentResponse(BuildPaymentResponseForTest());
request
->Complete(scope.GetScriptState(),
- PaymentStateResolver::PaymentComplete::kSuccess)
+ PaymentStateResolver::PaymentComplete::kSuccess,
+ ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectCall(), funcs.ExpectNoCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)->OnError(
@@ -56,15 +57,15 @@ TEST(CompleteTest, ResolveCompletePromiseOnUserClosingUI) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
- request->show(scope.GetScriptState());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION);
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
->OnPaymentResponse(BuildPaymentResponseForTest());
request
->Complete(scope.GetScriptState(),
- PaymentStateResolver::PaymentComplete::kSuccess)
+ PaymentStateResolver::PaymentComplete::kSuccess,
+ ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectCall(), funcs.ExpectNoCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)->OnError(
@@ -76,22 +77,21 @@ TEST(CompleteTest, ResolveCompletePromiseOnUserClosingUI) {
// should be rejected.
TEST(CompleteTest, RejectCompletePromiseAfterError) {
PaymentRequestV8TestingScope scope;
- PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
- request->show(scope.GetScriptState());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION);
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
->OnPaymentResponse(BuildPaymentResponseForTest());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)->OnError(
payments::mojom::blink::PaymentErrorReason::USER_CANCEL,
"User closed the UI.");
- request
- ->Complete(scope.GetScriptState(),
- PaymentStateResolver::PaymentComplete::kSuccess)
- .Then(funcs.ExpectNoCall(), funcs.ExpectCall());
+ request->Complete(scope.GetScriptState(),
+ PaymentStateResolver::PaymentComplete::kSuccess,
+ scope.GetExceptionState());
+ EXPECT_EQ(scope.GetExceptionState().Code(),
+ ToExceptionCode(DOMExceptionCode::kInvalidStateError));
}
TEST(CompleteTest, ResolvePromiseOnComplete) {
@@ -99,15 +99,15 @@ TEST(CompleteTest, ResolvePromiseOnComplete) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
- request->show(scope.GetScriptState());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION);
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
->OnPaymentResponse(BuildPaymentResponseForTest());
request
->Complete(scope.GetScriptState(),
- PaymentStateResolver::PaymentComplete::kSuccess)
+ PaymentStateResolver::PaymentComplete::kSuccess,
+ ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectCall(), funcs.ExpectNoCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -119,9 +119,8 @@ TEST(CompleteTest, RejectCompletePromiseOnUpdateDetailsFailure) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
- request->show(scope.GetScriptState())
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectCall(), funcs.ExpectNoCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
->OnPaymentResponse(BuildPaymentResponseForTest());
@@ -129,7 +128,8 @@ TEST(CompleteTest, RejectCompletePromiseOnUpdateDetailsFailure) {
String error_message;
request
->Complete(scope.GetScriptState(),
- PaymentStateResolver::PaymentComplete::kSuccess)
+ PaymentStateResolver::PaymentComplete::kSuccess,
+ ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall(&error_message));
request->OnUpdatePaymentDetailsFailure("oops");
@@ -143,25 +143,23 @@ TEST(CompleteTest, RejectCompletePromiseAfterTimeout) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
- request->show(scope.GetScriptState())
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectCall(), funcs.ExpectNoCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
->OnPaymentResponse(BuildPaymentResponseForTest());
request->OnCompleteTimeoutForTesting();
String error_message;
- request
- ->Complete(scope.GetScriptState(),
- PaymentStateResolver::PaymentComplete::kSuccess)
- .Then(funcs.ExpectNoCall(), funcs.ExpectCall(&error_message));
+ request->Complete(scope.GetScriptState(),
+ PaymentStateResolver::PaymentComplete::kSuccess,
+ scope.GetExceptionState());
+ EXPECT_EQ(scope.GetExceptionState().Code(),
+ ToExceptionCode(DOMExceptionCode::kInvalidStateError));
v8::MicrotasksScope::PerformCheckpoint(scope.GetScriptState()->GetIsolate());
- EXPECT_EQ(
- "InvalidStateError: Timed out after 60 seconds, complete() called too "
- "late",
- error_message);
+ EXPECT_EQ("Timed out after 60 seconds, complete() called too late",
+ scope.GetExceptionState().Message());
}
} // namespace
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 0170596ef7d..09752416771 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
@@ -18,15 +18,15 @@ const char HTMLIFrameElementPayments::kSupplementName[] =
// static
bool HTMLIFrameElementPayments::FastHasAttribute(
- const QualifiedName& name,
- const HTMLIFrameElement& element) {
+ const HTMLIFrameElement& element,
+ const QualifiedName& name) {
DCHECK(name == html_names::kAllowpaymentrequestAttr);
return element.FastHasAttribute(name);
}
// static
-void HTMLIFrameElementPayments::SetBooleanAttribute(const QualifiedName& name,
- HTMLIFrameElement& element,
+void HTMLIFrameElementPayments::SetBooleanAttribute(HTMLIFrameElement& element,
+ const QualifiedName& name,
bool value) {
DCHECK(name == html_names::kAllowpaymentrequestAttr);
element.SetBooleanAttribute(name, value);
@@ -51,7 +51,7 @@ bool HTMLIFrameElementPayments::AllowPaymentRequest(
element.FastHasAttribute(html_names::kAllowpaymentrequestAttr);
}
-void HTMLIFrameElementPayments::Trace(blink::Visitor* visitor) {
+void HTMLIFrameElementPayments::Trace(Visitor* visitor) {
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 195d5e3de67..810d72a3148 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
@@ -24,14 +24,14 @@ class HTMLIFrameElementPayments final
HTMLIFrameElementPayments();
- static bool FastHasAttribute(const QualifiedName&, const HTMLIFrameElement&);
- static void SetBooleanAttribute(const QualifiedName&,
- HTMLIFrameElement&,
+ static bool FastHasAttribute(const HTMLIFrameElement&, const QualifiedName&);
+ static void SetBooleanAttribute(HTMLIFrameElement&,
+ const QualifiedName&,
bool);
static HTMLIFrameElementPayments& From(HTMLIFrameElement&);
static bool AllowPaymentRequest(HTMLIFrameElement&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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
new file mode 100644
index 00000000000..f48bed77859
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/payments/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "abort_payment_event.idl",
+ "can_make_payment_event.idl",
+ "merchant_validation_event.idl",
+ "payment_address.idl",
+ "payment_instruments.idl",
+ "payment_manager.idl",
+ "payment_method_change_event.idl",
+ "payment_request.idl",
+ "payment_request_event.idl",
+ "payment_request_update_event.idl",
+ "payment_response.idl",
+]
+
+modules_dictionary_idl_files = [
+ "address_errors.idl",
+ "android_pay_method_data.idl",
+ "basic_card_request.idl",
+ "can_make_payment_event_init.idl",
+ "can_make_payment_response.idl",
+ "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",
+ "payment_details_modifier.idl",
+ "payment_details_update.idl",
+ "payment_handler_response.idl",
+ "payment_instrument.idl",
+ "payment_item.idl",
+ "payment_method_change_event_init.idl",
+ "payment_method_data.idl",
+ "payment_options.idl",
+ "payment_request_details_update.idl",
+ "payment_request_event_init.idl",
+ "payment_request_update_event_init.idl",
+ "payment_shipping_option.idl",
+ "payment_validation_errors.idl",
+]
+
+modules_dependency_idl_files = [
+ "html_iframe_element_payments.idl",
+ "payment_app_service_worker_global_scope.idl",
+ "payment_app_service_worker_registration.idl",
+]
diff --git a/chromium/third_party/blink/renderer/modules/payments/merchant_validation_event.h b/chromium/third_party/blink/renderer/modules/payments/merchant_validation_event.h
index eb6b7544a3a..41c35327258 100644
--- a/chromium/third_party/blink/renderer/modules/payments/merchant_validation_event.h
+++ b/chromium/third_party/blink/renderer/modules/payments/merchant_validation_event.h
@@ -8,9 +8,9 @@
#include "base/macros.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/modules/v8/v8_merchant_validation_event_init.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/modules/event_modules.h"
-#include "third_party/blink/renderer/modules/payments/merchant_validation_event_init.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
namespace WTF {
diff --git a/chromium/third_party/blink/renderer/modules/payments/merchant_validation_event.idl b/chromium/third_party/blink/renderer/modules/payments/merchant_validation_event.idl
index df9f1f35e9a..7388579fd93 100644
--- a/chromium/third_party/blink/renderer/modules/payments/merchant_validation_event.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/merchant_validation_event.idl
@@ -6,12 +6,10 @@
// https://crbug.com/867904
[
RuntimeEnabled=PaymentRequestMerchantValidationEvent,
- Constructor(DOMString type, optional MerchantValidationEventInit eventInitDict),
- ConstructorCallWith=ScriptState,
- RaisesException=Constructor,
SecureContext,
Exposed=Window
] interface MerchantValidationEvent : Event {
+ [CallWith=ScriptState, RaisesException] constructor(DOMString type, optional MerchantValidationEventInit eventInitDict = {});
readonly attribute DOMString methodName;
readonly attribute USVString validationURL;
[CallWith=ScriptState,RaisesException] void complete(Promise<any> merchantSessionPromise);
diff --git a/chromium/third_party/blink/renderer/modules/payments/merchant_validation_event_test.cc b/chromium/third_party/blink/renderer/modules/payments/merchant_validation_event_test.cc
index 3e7d086c930..1b3a54592a8 100644
--- a/chromium/third_party/blink/renderer/modules/payments/merchant_validation_event_test.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/merchant_validation_event_test.cc
@@ -8,7 +8,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
-#include "third_party/blink/renderer/modules/payments/merchant_validation_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_merchant_validation_event_init.h"
#include "third_party/blink/renderer/platform/bindings/exception_code.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
diff --git a/chromium/third_party/blink/renderer/modules/payments/on_payment_response_test.cc b/chromium/third_party/blink/renderer/modules/payments/on_payment_response_test.cc
index 4876a3184ae..fd30e364600 100644
--- a/chromium/third_party/blink/renderer/modules/payments/on_payment_response_test.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/on_payment_response_test.cc
@@ -25,14 +25,13 @@ TEST(OnPaymentResponseTest, RejectMissingShippingOption) {
options->setRequestShipping(true);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- ASSERT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
payments::mojom::blink::PaymentResponsePtr response =
BuildPaymentResponseForTest();
response->shipping_address = payments::mojom::blink::PaymentAddress::New();
response->shipping_address->country = "US";
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -48,13 +47,12 @@ TEST(OnPaymentResponseTest, RejectMissingAddress) {
options->setRequestShipping(true);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- ASSERT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
payments::mojom::blink::PaymentResponsePtr response =
BuildPaymentResponseForTest();
response->shipping_option = "standardShipping";
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -70,12 +68,11 @@ TEST(OnPaymentResponseTest, RejectMissingName) {
options->setRequestPayerName(true);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
payments::mojom::blink::PaymentResponsePtr response =
BuildPaymentResponseForTest();
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -91,12 +88,11 @@ TEST(OnPaymentResponseTest, RejectMissingEmail) {
options->setRequestPayerEmail(true);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
payments::mojom::blink::PaymentResponsePtr response =
BuildPaymentResponseForTest();
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -112,12 +108,11 @@ TEST(OnPaymentResponseTest, RejectMissingPhone) {
options->setRequestPayerPhone(true);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
payments::mojom::blink::PaymentResponsePtr response =
BuildPaymentResponseForTest();
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -133,15 +128,14 @@ TEST(OnPaymentResponseTest, RejectEmptyShippingOption) {
options->setRequestShipping(true);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- ASSERT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
payments::mojom::blink::PaymentResponsePtr response =
BuildPaymentResponseForTest();
response->shipping_option = "";
response->shipping_address = payments::mojom::blink::PaymentAddress::New();
response->shipping_address->country = "US";
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -157,14 +151,13 @@ TEST(OnPaymentResponseTest, RejectEmptyAddress) {
options->setRequestShipping(true);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- ASSERT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
payments::mojom::blink::PaymentResponsePtr response =
BuildPaymentResponseForTest();
response->shipping_option = "standardShipping";
response->shipping_address = payments::mojom::blink::PaymentAddress::New();
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -180,13 +173,12 @@ TEST(OnPaymentResponseTest, RejectEmptyName) {
options->setRequestPayerName(true);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
payments::mojom::blink::PaymentResponsePtr response =
BuildPaymentResponseForTest();
response->payer->name = "";
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -202,13 +194,12 @@ TEST(OnPaymentResponseTest, RejectEmptyEmail) {
options->setRequestPayerEmail(true);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
payments::mojom::blink::PaymentResponsePtr response =
BuildPaymentResponseForTest();
response->payer->email = "";
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -224,13 +215,12 @@ TEST(OnPaymentResponseTest, RejectEmptyPhone) {
options->setRequestPayerPhone(true);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
payments::mojom::blink::PaymentResponsePtr response =
BuildPaymentResponseForTest();
response->payer->phone = "";
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -246,14 +236,13 @@ TEST(OnPaymentResponseTest, RejectNotRequestedAddress) {
options->setRequestShipping(false);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- ASSERT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
payments::mojom::blink::PaymentResponsePtr response =
BuildPaymentResponseForTest();
response->shipping_address = payments::mojom::blink::PaymentAddress::New();
response->shipping_address->country = "US";
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -269,13 +258,12 @@ TEST(OnPaymentResponseTest, RejectNotRequestedShippingOption) {
options->setRequestShipping(false);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- ASSERT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
payments::mojom::blink::PaymentResponsePtr response =
BuildPaymentResponseForTest();
response->shipping_option = "";
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -291,13 +279,12 @@ TEST(OnPaymentResponseTest, RejectNotRequestedName) {
options->setRequestPayerName(false);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
payments::mojom::blink::PaymentResponsePtr response =
BuildPaymentResponseForTest();
response->payer->name = "";
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -313,13 +300,12 @@ TEST(OnPaymentResponseTest, RejectNotRequestedEmail) {
options->setRequestPayerEmail(false);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
payments::mojom::blink::PaymentResponsePtr response =
BuildPaymentResponseForTest();
response->payer->email = "";
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -335,13 +321,12 @@ TEST(OnPaymentResponseTest, RejectNotRequestedPhone) {
options->setRequestPayerPhone(false);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
payments::mojom::blink::PaymentResponsePtr response =
BuildPaymentResponseForTest();
response->payer->phone = "";
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -357,15 +342,14 @@ TEST(OnPaymentResponseTest, RejectInvalidAddress) {
options->setRequestShipping(true);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- ASSERT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
payments::mojom::blink::PaymentResponsePtr response =
BuildPaymentResponseForTest();
response->shipping_option = "standardShipping";
response->shipping_address = payments::mojom::blink::PaymentAddress::New();
response->shipping_address->country = "Atlantis";
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -405,15 +389,14 @@ TEST(OnPaymentResponseTest, CanRequestShippingInformation) {
options->setRequestShipping(true);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- ASSERT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
payments::mojom::blink::PaymentResponsePtr response =
BuildPaymentResponseForTest();
response->shipping_option = "standardShipping";
response->shipping_address = payments::mojom::blink::PaymentAddress::New();
response->shipping_address->country = "US";
ScriptValue out_value;
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(PaymentResponseFunction::Create(scope.GetScriptState(), &out_value),
funcs.ExpectNoCall());
@@ -435,14 +418,13 @@ TEST(OnPaymentResponseTest, CanRequestName) {
options->setRequestPayerName(true);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
payments::mojom::blink::PaymentResponsePtr response =
BuildPaymentResponseForTest();
response->payer = payments::mojom::blink::PayerDetail::New();
response->payer->name = "Jon Doe";
ScriptValue out_value;
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(PaymentResponseFunction::Create(scope.GetScriptState(), &out_value),
funcs.ExpectNoCall());
@@ -464,13 +446,12 @@ TEST(OnPaymentResponseTest, CanRequestEmail) {
options->setRequestPayerEmail(true);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
payments::mojom::blink::PaymentResponsePtr response =
BuildPaymentResponseForTest();
response->payer->email = "abc@gmail.com";
ScriptValue out_value;
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(PaymentResponseFunction::Create(scope.GetScriptState(), &out_value),
funcs.ExpectNoCall());
@@ -492,14 +473,13 @@ TEST(OnPaymentResponseTest, CanRequestPhone) {
options->setRequestPayerPhone(true);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
payments::mojom::blink::PaymentResponsePtr response =
BuildPaymentResponseForTest();
response->payer->phone = "0123";
ScriptValue out_value;
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(PaymentResponseFunction::Create(scope.GetScriptState(), &out_value),
funcs.ExpectNoCall());
@@ -521,10 +501,9 @@ TEST(OnPaymentResponseTest, ShippingInformationNotRequired) {
options->setRequestShipping(false);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- ASSERT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
ScriptValue out_value;
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(PaymentResponseFunction::Create(scope.GetScriptState(), &out_value),
funcs.ExpectNoCall());
@@ -547,13 +526,12 @@ TEST(OnPaymentResponseTest, PhoneNotRequred) {
options->setRequestPayerPhone(false);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
payments::mojom::blink::PaymentResponsePtr response =
BuildPaymentResponseForTest();
response->payer->phone = String();
ScriptValue out_value;
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(PaymentResponseFunction::Create(scope.GetScriptState(), &out_value),
funcs.ExpectNoCall());
@@ -575,13 +553,12 @@ TEST(OnPaymentResponseTest, NameNotRequired) {
options->setRequestPayerName(false);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
payments::mojom::blink::PaymentResponsePtr response =
BuildPaymentResponseForTest();
response->payer->name = String();
ScriptValue out_value;
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(PaymentResponseFunction::Create(scope.GetScriptState(), &out_value),
funcs.ExpectNoCall());
@@ -603,13 +580,12 @@ TEST(OnPaymentResponseTest, EmailNotRequired) {
options->setRequestPayerEmail(false);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
payments::mojom::blink::PaymentResponsePtr response =
BuildPaymentResponseForTest();
response->payer->email = String();
ScriptValue out_value;
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(PaymentResponseFunction::Create(scope.GetScriptState(), &out_value),
funcs.ExpectNoCall());
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 55b96f6e9ed..70c052af16c 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
@@ -41,12 +41,12 @@ PaymentManager* PaymentAppServiceWorkerRegistration::paymentManager(
PaymentManager* PaymentAppServiceWorkerRegistration::paymentManager(
ScriptState* script_state) {
if (!payment_manager_) {
- payment_manager_ = PaymentManager::Create(registration_);
+ payment_manager_ = MakeGarbageCollected<PaymentManager>(registration_);
}
return payment_manager_.Get();
}
-void PaymentAppServiceWorkerRegistration::Trace(blink::Visitor* visitor) {
+void PaymentAppServiceWorkerRegistration::Trace(Visitor* visitor) {
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 92733d22ab7..9a8a29ec407 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<ServiceWorkerRegistration> registration_;
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 620081a417b..18816cf7913 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
@@ -6,14 +6,13 @@
#include "third_party/blink/public/mojom/payments/payment_app.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
-#include "third_party/blink/renderer/modules/payments/can_make_payment_event_init.h"
-#include "third_party/blink/renderer/modules/payments/payment_currency_amount.h"
-#include "third_party/blink/renderer/modules/payments/payment_details_modifier.h"
-#include "third_party/blink/renderer/modules/payments/payment_item.h"
-#include "third_party/blink/renderer/modules/payments/payment_method_data.h"
-#include "third_party/blink/renderer/modules/payments/payment_options.h"
-#include "third_party/blink/renderer/modules/payments/payment_request_event_init.h"
-#include "third_party/blink/renderer/modules/payments/payment_shipping_option.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_currency_amount.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_details_modifier.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_item.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_method_data.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_request_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_shipping_option.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
namespace blink {
@@ -192,6 +191,7 @@ CanMakePaymentEventInit* PaymentEventDataConversion::ToCanMakePaymentEventInit(
ToPaymentDetailsModifier(script_state, std::move(modifier)));
}
event_init->setModifiers(modifiers);
+ event_init->setCurrency(event_data->currency);
return event_init;
}
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 c9d4999e9aa..b6ceee1454d 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
@@ -6,8 +6,8 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_EVENT_DATA_CONVERSION_H_
#include "third_party/blink/public/mojom/payments/payment_app.mojom-blink-forward.h"
-#include "third_party/blink/renderer/modules/payments/can_make_payment_event_init.h"
-#include "third_party/blink/renderer/modules/payments/payment_request_event_init.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"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion_test.cc b/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion_test.cc
index 035de93715a..81190c3d8f5 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion_test.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion_test.cc
@@ -10,10 +10,10 @@
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
-#include "third_party/blink/renderer/modules/payments/payment_currency_amount.h"
-#include "third_party/blink/renderer/modules/payments/payment_method_data.h"
-#include "third_party/blink/renderer/modules/payments/payment_options.h"
-#include "third_party/blink/renderer/modules/payments/payment_shipping_option.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_currency_amount.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_method_data.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_shipping_option.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_handler_response.idl b/chromium/third_party/blink/renderer/modules/payments/payment_handler_response.idl
index 6f17e0d6e2a..c00df854f91 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_handler_response.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_handler_response.idl
@@ -10,6 +10,6 @@ dictionary PaymentHandlerResponse {
[RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] DOMString? payerName;
[RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] DOMString? payerEmail;
[RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] DOMString? payerPhone;
- [RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] PaymentAddressInit shippingAddress;
+ [RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] AddressInit shippingAddress;
[RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] DOMString? shippingOption;
};
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_handler_utils.cc b/chromium/third_party/blink/renderer/modules/payments/payment_handler_utils.cc
index 415470686a6..49b54a10d8f 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_handler_utils.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_handler_utils.cc
@@ -7,6 +7,7 @@
#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom-blink.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
using blink::mojom::ServiceWorkerResponseError;
@@ -53,7 +54,7 @@ void PaymentHandlerUtils::ReportResponseError(
}
DCHECK(execution_context);
- execution_context->AddConsoleMessage(ConsoleMessage::Create(
+ execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning, error_message));
}
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 dc245032b6b..36b523af43f 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_instruments.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_instruments.cc
@@ -16,6 +16,8 @@
#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_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_image_object.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_instrument.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"
@@ -23,8 +25,6 @@
#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/payments/basic_card_helper.h"
-#include "third_party/blink/renderer/modules/payments/image_object.h"
-#include "third_party/blink/renderer/modules/payments/payment_instrument.h"
#include "third_party/blink/renderer/modules/payments/payment_manager.h"
#include "third_party/blink/renderer/modules/permissions/permission_utils.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -80,15 +80,16 @@ bool AllowedToUsePaymentFeatures(ScriptState* script_state) {
return ExecutionContext::From(script_state)
->GetSecurityContext()
.GetFeaturePolicy()
- ->IsFeatureEnabled(mojom::FeaturePolicyFeature::kPayment);
+ ->IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kPayment);
}
-ScriptPromise RejectNotAllowedToUsePaymentFeatures(ScriptState* script_state) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kSecurityError,
- "Must be in a top-level browsing context or an iframe "
- "needs to specify allow=\"payment\" explicitly"));
+ScriptPromise RejectNotAllowedToUsePaymentFeatures(
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
+ exception_state.ThrowSecurityError(
+ "Must be in a top-level browsing context or an iframe needs to specify "
+ "allow=\"payment\" explicitly");
+ return ScriptPromise();
}
} // namespace
@@ -125,7 +126,7 @@ class PaymentInstrumentParameter final
bool has_name() const { return has_name_; }
const String& name() const { return name_; }
- void Trace(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
visitor->Trace(icons_);
visitor->Trace(capabilities_);
}
@@ -148,15 +149,15 @@ PaymentInstruments::PaymentInstruments(
ScriptPromise PaymentInstruments::deleteInstrument(
ScriptState* script_state,
- const String& instrument_key) {
+ const String& instrument_key,
+ ExceptionState& exception_state) {
if (!AllowedToUsePaymentFeatures(script_state))
- return RejectNotAllowedToUsePaymentFeatures(script_state);
+ return RejectNotAllowedToUsePaymentFeatures(script_state, exception_state);
if (!manager_.is_bound()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- kPaymentManagerUnavailable));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ kPaymentManagerUnavailable);
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -170,15 +171,15 @@ ScriptPromise PaymentInstruments::deleteInstrument(
}
ScriptPromise PaymentInstruments::get(ScriptState* script_state,
- const String& instrument_key) {
+ const String& instrument_key,
+ ExceptionState& exception_state) {
if (!AllowedToUsePaymentFeatures(script_state))
- return RejectNotAllowedToUsePaymentFeatures(script_state);
+ return RejectNotAllowedToUsePaymentFeatures(script_state, exception_state);
if (!manager_.is_bound()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- kPaymentManagerUnavailable));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ kPaymentManagerUnavailable);
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -191,15 +192,15 @@ ScriptPromise PaymentInstruments::get(ScriptState* script_state,
return promise;
}
-ScriptPromise PaymentInstruments::keys(ScriptState* script_state) {
+ScriptPromise PaymentInstruments::keys(ScriptState* script_state,
+ ExceptionState& exception_state) {
if (!AllowedToUsePaymentFeatures(script_state))
- return RejectNotAllowedToUsePaymentFeatures(script_state);
+ return RejectNotAllowedToUsePaymentFeatures(script_state, exception_state);
if (!manager_.is_bound()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- kPaymentManagerUnavailable));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ kPaymentManagerUnavailable);
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -212,15 +213,15 @@ ScriptPromise PaymentInstruments::keys(ScriptState* script_state) {
}
ScriptPromise PaymentInstruments::has(ScriptState* script_state,
- const String& instrument_key) {
+ const String& instrument_key,
+ ExceptionState& exception_state) {
if (!AllowedToUsePaymentFeatures(script_state))
- return RejectNotAllowedToUsePaymentFeatures(script_state);
+ return RejectNotAllowedToUsePaymentFeatures(script_state, exception_state);
if (!manager_.is_bound()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- kPaymentManagerUnavailable));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ kPaymentManagerUnavailable);
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -238,18 +239,17 @@ ScriptPromise PaymentInstruments::set(ScriptState* script_state,
const PaymentInstrument* details,
ExceptionState& exception_state) {
if (!AllowedToUsePaymentFeatures(script_state))
- return RejectNotAllowedToUsePaymentFeatures(script_state);
+ return RejectNotAllowedToUsePaymentFeatures(script_state, exception_state);
if (!manager_.is_bound()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- kPaymentManagerUnavailable));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ kPaymentManagerUnavailable);
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ExecutionContext* context = ExecutionContext::From(script_state);
- Document* doc = DynamicTo<Document>(context);
+ Document* doc = Document::DynamicFrom(context);
// Should move this permission check to browser process.
// Please see http://crbug.com/795929
@@ -267,15 +267,15 @@ ScriptPromise PaymentInstruments::set(ScriptState* script_state,
return resolver->Promise();
}
-ScriptPromise PaymentInstruments::clear(ScriptState* script_state) {
+ScriptPromise PaymentInstruments::clear(ScriptState* script_state,
+ ExceptionState& exception_state) {
if (!AllowedToUsePaymentFeatures(script_state))
- return RejectNotAllowedToUsePaymentFeatures(script_state);
+ return RejectNotAllowedToUsePaymentFeatures(script_state, exception_state);
if (!manager_.is_bound()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- kPaymentManagerUnavailable));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ kPaymentManagerUnavailable);
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -364,10 +364,9 @@ void PaymentInstruments::OnRequestPermission(
ExceptionState exception_state(resolver->GetScriptState()->GetIsolate(),
ExceptionState::kSetterContext,
"PaymentInstruments", "set");
- BasicCardHelper::ParseBasiccardData(
- details->capabilities(), instrument->supported_networks,
- instrument->supported_types, /*has_supported_card_types=*/nullptr,
- exception_state);
+ BasicCardHelper::ParseBasiccardData(details->capabilities(),
+ instrument->supported_networks,
+ exception_state);
if (exception_state.HadException()) {
resolver->Reject(exception_state);
return;
@@ -417,7 +416,7 @@ void PaymentInstruments::onGetPaymentInstrument(
image_object->setType(icon->type);
String sizes = WTF::g_empty_string;
for (const auto& size : icon->sizes) {
- sizes = sizes + String::Format("%dx%d ", size.width, size.height);
+ sizes = sizes + String::Format("%dx%d ", size.width(), size.height());
}
image_object->setSizes(sizes.StripWhiteSpace());
icons.push_back(image_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 13e9824aaf2..c7cb763b739 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_instruments.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_instruments.h
@@ -30,15 +30,21 @@ class MODULES_EXPORT PaymentInstruments final : public ScriptWrappable {
explicit PaymentInstruments(
const mojo::Remote<payments::mojom::blink::PaymentManager>&);
- ScriptPromise deleteInstrument(ScriptState*, const String& instrument_key);
- ScriptPromise get(ScriptState*, const String& instrument_key);
- ScriptPromise keys(ScriptState*);
- ScriptPromise has(ScriptState*, const String& instrument_key);
+ ScriptPromise deleteInstrument(ScriptState*,
+ const String& instrument_key,
+ ExceptionState&);
+ ScriptPromise get(ScriptState*,
+ const String& instrument_key,
+ ExceptionState&);
+ ScriptPromise keys(ScriptState*, ExceptionState&);
+ ScriptPromise has(ScriptState*,
+ const String& instrument_key,
+ ExceptionState&);
ScriptPromise set(ScriptState*,
const String& instrument_key,
const PaymentInstrument* details,
ExceptionState&);
- ScriptPromise clear(ScriptState*);
+ ScriptPromise clear(ScriptState*, ExceptionState&);
private:
mojom::blink::PermissionService* GetPermissionService(ScriptState*);
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_instruments.idl b/chromium/third_party/blink/renderer/modules/payments/payment_instruments.idl
index 3bf03fba218..0914d6f6eee 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_instruments.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_instruments.idl
@@ -8,10 +8,10 @@
RuntimeEnabled=PaymentApp,
Exposed=(Window,Worker)
] interface PaymentInstruments {
- [CallWith=ScriptState, ImplementedAs=deleteInstrument] Promise<boolean> delete(DOMString instrumentKey);
- [CallWith=ScriptState] Promise<any> get(DOMString instrumentKey);
- [CallWith=ScriptState] Promise<sequence<DOMString>> keys();
- [CallWith=ScriptState] Promise<boolean> has(DOMString instrumentKey);
+ [CallWith=ScriptState, RaisesException, ImplementedAs=deleteInstrument] Promise<boolean> delete(DOMString instrumentKey);
+ [CallWith=ScriptState, RaisesException] Promise<any> get(DOMString instrumentKey);
+ [CallWith=ScriptState, RaisesException] Promise<sequence<DOMString>> keys();
+ [CallWith=ScriptState, RaisesException] Promise<boolean> has(DOMString instrumentKey);
[CallWith=ScriptState, RaisesException] Promise<void> set(DOMString instrumentKey, PaymentInstrument details);
- [CallWith=ScriptState] Promise<void> clear();
+ [CallWith=ScriptState, RaisesException] Promise<void> clear();
};
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 029f5ce7901..f1029af6e40 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_manager.cc
@@ -10,16 +10,12 @@
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/modules/payments/payment_instruments.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_registration.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/wtf/functional.h"
namespace blink {
-PaymentManager* PaymentManager::Create(
- ServiceWorkerRegistration* registration) {
- return MakeGarbageCollected<PaymentManager>(registration);
-}
-
PaymentInstruments* PaymentManager::instruments() {
if (!instruments_)
instruments_ = MakeGarbageCollected<PaymentInstruments>(manager_);
@@ -37,20 +33,20 @@ void PaymentManager::setUserHint(const String& user_hint) {
ScriptPromise PaymentManager::enableDelegations(
ScriptState* script_state,
- const Vector<String>& stringified_delegations) {
+ const Vector<String>& stringified_delegations,
+ ExceptionState& exception_state) {
if (!script_state->ContextIsValid()) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "Cannot enable payment delegations"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Cannot enable payment delegations");
+ return ScriptPromise();
}
if (enable_delegations_resolver_) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "Cannot call enableDelegations() again until "
- "the previous enableDelegations() is finished"));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "Cannot call enableDelegations() again until the previous "
+ "enableDelegations() is finished");
+ return ScriptPromise();
}
Vector<payments::mojom::blink::PaymentDelegation> delegations;
@@ -80,7 +76,7 @@ ScriptPromise PaymentManager::enableDelegations(
return enable_delegations_resolver_->Promise();
}
-void PaymentManager::Trace(blink::Visitor* visitor) {
+void PaymentManager::Trace(Visitor* visitor) {
visitor->Trace(registration_);
visitor->Trace(instruments_);
visitor->Trace(enable_delegations_resolver_);
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 d60f8bcc1c6..de761cae3d4 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_manager.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_manager.h
@@ -14,6 +14,7 @@
namespace blink {
+class ExceptionState;
class PaymentInstruments;
class ScriptPromiseResolver;
class ScriptPromise;
@@ -24,8 +25,6 @@ class MODULES_EXPORT PaymentManager final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- static PaymentManager* Create(ServiceWorkerRegistration*);
-
explicit PaymentManager(ServiceWorkerRegistration*);
PaymentInstruments* instruments();
@@ -33,11 +32,11 @@ class MODULES_EXPORT PaymentManager final : public ScriptWrappable {
const String& userHint();
void setUserHint(const String&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
- ScriptPromise enableDelegations(
- ScriptState*,
- const Vector<String>& stringified_delegations);
+ ScriptPromise enableDelegations(ScriptState*,
+ const Vector<String>& stringified_delegations,
+ ExceptionState&);
private:
void OnServiceConnectionError();
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_manager.idl b/chromium/third_party/blink/renderer/modules/payments/payment_manager.idl
index 10b88279dc2..48abe2f66e5 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_manager.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_manager.idl
@@ -17,5 +17,5 @@ enum PaymentDelegation {
] interface PaymentManager {
[SameObject] readonly attribute PaymentInstruments instruments;
attribute DOMString userHint;
- [CallWith=ScriptState, RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] Promise<void> enableDelegations(FrozenArray<PaymentDelegation> delegations);
+ [CallWith=ScriptState, RaisesException, RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] Promise<void> enableDelegations(FrozenArray<PaymentDelegation> delegations);
};
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 162ce1e3e1d..993446ac1f5 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
@@ -7,8 +7,8 @@
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_method_change_event_init.h"
#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/modules/payments/payment_method_change_event_init.h"
#include "third_party/blink/renderer/modules/payments/payment_request_update_event.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.idl b/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.idl
index 98e6d845206..f2f85fc3412 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.idl
@@ -6,11 +6,10 @@
[
RuntimeEnabled=PaymentMethodChangeEvent,
- ConstructorCallWith=ScriptState,
- Constructor(DOMString type, optional PaymentMethodChangeEventInit eventInitDict),
SecureContext,
Exposed=Window
] interface PaymentMethodChangeEvent : PaymentRequestUpdateEvent {
+ [CallWith=ScriptState] constructor(DOMString type, optional PaymentMethodChangeEventInit eventInitDict = {});
readonly attribute DOMString methodName;
[CallWith=ScriptState] readonly attribute object? methodDetails;
};
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 e55238490af..b173aafff04 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request.cc
@@ -17,11 +17,19 @@
#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/renderer/bindings/core/v8/native_value_traits_impl.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_string_resource.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_address_errors.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_android_pay_method_data.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_basic_card_request.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payer_errors.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_details_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_details_modifier.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_details_update.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_item.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_shipping_option.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_validation_errors.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/events/event.h"
@@ -35,23 +43,12 @@
#include "third_party/blink/renderer/core/html/html_iframe_element.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/modules/event_target_modules_names.h"
-#include "third_party/blink/renderer/modules/payments/address_errors.h"
-#include "third_party/blink/renderer/modules/payments/android_pay_method_data.h"
-#include "third_party/blink/renderer/modules/payments/android_pay_tokenization.h"
#include "third_party/blink/renderer/modules/payments/basic_card_helper.h"
-#include "third_party/blink/renderer/modules/payments/basic_card_request.h"
#include "third_party/blink/renderer/modules/payments/html_iframe_element_payments.h"
-#include "third_party/blink/renderer/modules/payments/payer_errors.h"
#include "third_party/blink/renderer/modules/payments/payment_address.h"
-#include "third_party/blink/renderer/modules/payments/payment_details_init.h"
-#include "third_party/blink/renderer/modules/payments/payment_details_modifier.h"
-#include "third_party/blink/renderer/modules/payments/payment_details_update.h"
-#include "third_party/blink/renderer/modules/payments/payment_item.h"
#include "third_party/blink/renderer/modules/payments/payment_method_change_event.h"
#include "third_party/blink/renderer/modules/payments/payment_request_update_event.h"
#include "third_party/blink/renderer/modules/payments/payment_response.h"
-#include "third_party/blink/renderer/modules/payments/payment_shipping_option.h"
-#include "third_party/blink/renderer/modules/payments/payment_validation_errors.h"
#include "third_party/blink/renderer/modules/payments/payments_validators.h"
#include "third_party/blink/renderer/modules/payments/update_payment_details_function.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -261,7 +258,7 @@ void ValidateShippingOptionOrPaymentItem(const T* item,
}
if (item->label().IsEmpty()) {
- execution_context.AddConsoleMessage(ConsoleMessage::Create(
+ execution_context.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kError,
"Empty " + item_name + " label may be confusing the user"));
@@ -320,7 +317,7 @@ void ValidateAndConvertShippingOptions(
}
if (option->id().IsEmpty()) {
- execution_context.AddConsoleMessage(ConsoleMessage::Create(
+ execution_context.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kWarning,
"Empty shipping option ID may be hard to debug"));
@@ -367,9 +364,9 @@ void SetAndroidPayMethodData(v8::Isolate* isolate,
const ScriptValue& input,
PaymentMethodDataPtr& output,
ExceptionState& exception_state) {
- AndroidPayMethodData* android_pay = AndroidPayMethodData::Create();
- V8AndroidPayMethodData::ToImpl(isolate, input.V8Value(), android_pay,
- exception_state);
+ AndroidPayMethodData* android_pay =
+ NativeValueTraits<AndroidPayMethodData>::NativeValue(
+ isolate, input.V8Value(), exception_state);
if (exception_state.HadException())
return;
@@ -394,13 +391,11 @@ void SetAndroidPayMethodData(v8::Isolate* isolate,
output->api_version = android_pay->apiVersion();
}
-void StringifyAndParseMethodSpecificData(
- v8::Isolate* isolate,
- const String& supported_method,
- const ScriptValue& input,
- PaymentMethodDataPtr& output,
- bool* basic_card_has_supported_card_types,
- ExceptionState& exception_state) {
+void StringifyAndParseMethodSpecificData(v8::Isolate* isolate,
+ const String& supported_method,
+ const ScriptValue& input,
+ PaymentMethodDataPtr& output,
+ ExceptionState& exception_state) {
PaymentsValidators::ValidateAndStringifyObject(
isolate, "Payment method data", input, output->stringified_data,
exception_state);
@@ -419,16 +414,14 @@ void StringifyAndParseMethodSpecificData(
if (supported_method == "basic-card") {
// Parses basic-card data to avoid parsing JSON in the browser.
- BasicCardHelper::ParseBasiccardData(
- input, output->supported_networks, output->supported_types,
- basic_card_has_supported_card_types, exception_state);
+ BasicCardHelper::ParseBasiccardData(input, output->supported_networks,
+ exception_state);
}
}
void ValidateAndConvertPaymentDetailsModifiers(
const HeapVector<Member<PaymentDetailsModifier>>& input,
Vector<PaymentDetailsModifierPtr>& output,
- bool* basic_card_has_supported_card_types,
ExecutionContext& execution_context,
ExceptionState& exception_state) {
if (input.size() > PaymentRequest::kMaxListSize) {
@@ -468,22 +461,19 @@ void ValidateAndConvertPaymentDetailsModifiers(
if (modifier->hasData() && !modifier->data().IsEmpty()) {
StringifyAndParseMethodSpecificData(
execution_context.GetIsolate(), modifier->supportedMethod(),
- modifier->data(), output.back()->method_data,
- basic_card_has_supported_card_types, exception_state);
+ modifier->data(), output.back()->method_data, exception_state);
} else {
output.back()->method_data->stringified_data = "";
}
}
}
-void ValidateAndConvertPaymentDetailsBase(
- const PaymentDetailsBase* input,
- const PaymentOptions* options,
- PaymentDetailsPtr& output,
- String& shipping_option_output,
- bool* basic_card_has_supported_card_types,
- ExecutionContext& execution_context,
- ExceptionState& exception_state) {
+void ValidateAndConvertPaymentDetailsBase(const PaymentDetailsBase* input,
+ const PaymentOptions* options,
+ PaymentDetailsPtr& output,
+ String& shipping_option_output,
+ ExecutionContext& execution_context,
+ ExceptionState& exception_state) {
if (input->hasDisplayItems()) {
output->display_items = Vector<PaymentItemPtr>();
ValidateAndConvertDisplayItems(input->displayItems(), "display items",
@@ -509,29 +499,26 @@ void ValidateAndConvertPaymentDetailsBase(
if (input->hasModifiers()) {
output->modifiers = Vector<PaymentDetailsModifierPtr>();
ValidateAndConvertPaymentDetailsModifiers(
- input->modifiers(), *output->modifiers,
- basic_card_has_supported_card_types, execution_context,
+ input->modifiers(), *output->modifiers, execution_context,
exception_state);
}
}
-void ValidateAndConvertPaymentDetailsInit(
- const PaymentDetailsInit* input,
- const PaymentOptions* options,
- PaymentDetailsPtr& output,
- String& shipping_option_output,
- bool* basic_card_has_supported_card_types,
- ExecutionContext& execution_context,
- ExceptionState& exception_state) {
+void ValidateAndConvertPaymentDetailsInit(const PaymentDetailsInit* input,
+ const PaymentOptions* options,
+ PaymentDetailsPtr& output,
+ String& shipping_option_output,
+ ExecutionContext& execution_context,
+ ExceptionState& exception_state) {
DCHECK(input->hasTotal());
ValidateAndConvertTotal(input->total(), "total", output->total,
execution_context, exception_state);
if (exception_state.HadException())
return;
- ValidateAndConvertPaymentDetailsBase(
- input, options, output, shipping_option_output,
- basic_card_has_supported_card_types, execution_context, exception_state);
+ ValidateAndConvertPaymentDetailsBase(input, options, output,
+ shipping_option_output,
+ execution_context, exception_state);
}
void ValidateAndConvertPaymentDetailsUpdate(const PaymentDetailsUpdate* input,
@@ -540,9 +527,9 @@ void ValidateAndConvertPaymentDetailsUpdate(const PaymentDetailsUpdate* input,
String& shipping_option_output,
ExecutionContext& execution_context,
ExceptionState& exception_state) {
- ValidateAndConvertPaymentDetailsBase(
- input, options, output, shipping_option_output,
- /*has_supported_card_types=*/nullptr, execution_context, exception_state);
+ ValidateAndConvertPaymentDetailsBase(input, options, output,
+ shipping_option_output,
+ execution_context, exception_state);
if (exception_state.HadException())
return;
@@ -590,7 +577,6 @@ void ValidateAndConvertPaymentMethodData(
bool& skip_to_gpay_ready,
Vector<payments::mojom::blink::PaymentMethodDataPtr>& output,
HashSet<String>& method_names,
- bool* basic_card_has_supported_card_types,
ExecutionContext& execution_context,
ExceptionState& exception_state) {
if (input.IsEmpty()) {
@@ -627,7 +613,7 @@ void ValidateAndConvertPaymentMethodData(
StringifyAndParseMethodSpecificData(
execution_context.GetIsolate(),
payment_method_data->supportedMethod(), payment_method_data->data(),
- output.back(), basic_card_has_supported_card_types, exception_state);
+ output.back(), exception_state);
if (exception_state.HadException())
continue;
@@ -650,13 +636,14 @@ bool AllowedToUsePaymentRequest(const ExecutionContext* execution_context) {
// Note: PaymentRequest is only exposed to Window and not workers.
// 1. If |document| has no browsing context, then return false.
- const Document* document = To<Document>(execution_context);
+ const Document* document = Document::From(execution_context);
if (!document->GetFrame())
return false;
// 2. If Feature Policy is enabled, return the policy for "payment" feature.
- return document->IsFeatureEnabled(mojom::FeaturePolicyFeature::kPayment,
- ReportOptions::kReportOnFailure);
+ return document->IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kPayment,
+ ReportOptions::kReportOnFailure);
}
void WarnIgnoringQueryQuotaForCanMakePayment(
@@ -667,9 +654,9 @@ void WarnIgnoringQueryQuotaForCanMakePayment(
"reject the promise, but allowing continued usage on localhost and "
"file:// scheme origins.",
method_name);
- execution_context.AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning, error));
+ execution_context.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning, error));
}
} // namespace
@@ -696,25 +683,25 @@ PaymentRequest* PaymentRequest::Create(
PaymentRequest::~PaymentRequest() = default;
-ScriptPromise PaymentRequest::show(ScriptState* script_state) {
- return show(script_state, ScriptPromise());
+ScriptPromise PaymentRequest::show(ScriptState* script_state,
+ ExceptionState& exception_state) {
+ return show(script_state, ScriptPromise(), exception_state);
}
ScriptPromise PaymentRequest::show(ScriptState* script_state,
- ScriptPromise details_promise) {
+ ScriptPromise details_promise,
+ ExceptionState& exception_state) {
if (!script_state->ContextIsValid() || !LocalDOMWindow::From(script_state) ||
!LocalDOMWindow::From(script_state)->GetFrame()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError,
- "Cannot show the payment request"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kAbortError,
+ "Cannot show the payment request");
+ return ScriptPromise();
}
if (!payment_provider_.is_bound() || accept_resolver_) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- "Already called show() once"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Already called show() once");
+ return ScriptPromise();
}
// TODO(crbug.com/825270): Reject with SecurityError DOMException if triggered
@@ -725,17 +712,12 @@ ScriptPromise PaymentRequest::show(ScriptState* script_state,
WebFeature::kPaymentRequestShowWithoutGesture);
}
- if (basic_card_has_supported_card_types_) {
- UseCounter::Count(GetExecutionContext(), WebFeature::kBasicCardType);
- }
-
// TODO(crbug.com/779126): add support for handling payment requests in
// immersive mode.
if (GetFrame()->GetDocument()->GetSettings()->GetImmersiveModeEnabled()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- "Page popups are suppressed"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Page popups are suppressed");
+ return ScriptPromise();
}
UseCounter::Count(GetExecutionContext(), WebFeature::kPaymentRequestShow);
@@ -761,28 +743,26 @@ ScriptPromise PaymentRequest::show(ScriptState* script_state,
return accept_resolver_->Promise();
}
-ScriptPromise PaymentRequest::abort(ScriptState* script_state) {
+ScriptPromise PaymentRequest::abort(ScriptState* script_state,
+ ExceptionState& exception_state) {
if (!script_state->ContextIsValid()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- "Cannot abort payment"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Cannot abort payment");
+ return ScriptPromise();
}
if (abort_resolver_) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "Cannot abort() again until the previous abort() "
- "has resolved or rejected"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Cannot abort() again until the previous "
+ "abort() has resolved or rejected");
+ return ScriptPromise();
}
if (!GetPendingAcceptPromiseResolver()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "No show() or retry() in progress, so nothing to abort"));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "No show() or retry() in progress, so nothing to abort");
+ return ScriptPromise();
}
abort_resolver_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -790,13 +770,13 @@ ScriptPromise PaymentRequest::abort(ScriptState* script_state) {
return abort_resolver_->Promise();
}
-ScriptPromise PaymentRequest::canMakePayment(ScriptState* script_state) {
+ScriptPromise PaymentRequest::canMakePayment(ScriptState* script_state,
+ ExceptionState& exception_state) {
if (!payment_provider_.is_bound() || GetPendingAcceptPromiseResolver() ||
can_make_payment_resolver_ || !script_state->ContextIsValid()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- "Cannot query payment request"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Cannot query payment request");
+ return ScriptPromise();
}
payment_provider_->CanMakePayment();
@@ -806,13 +786,14 @@ ScriptPromise PaymentRequest::canMakePayment(ScriptState* script_state) {
return can_make_payment_resolver_->Promise();
}
-ScriptPromise PaymentRequest::hasEnrolledInstrument(ScriptState* script_state) {
+ScriptPromise PaymentRequest::hasEnrolledInstrument(
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
if (!payment_provider_.is_bound() || GetPendingAcceptPromiseResolver() ||
has_enrolled_instrument_resolver_ || !script_state->ContextIsValid()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- "Cannot query payment request"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Cannot query payment request");
+ return ScriptPromise();
}
bool per_method_quota =
@@ -839,83 +820,83 @@ const AtomicString& PaymentRequest::InterfaceName() const {
}
ExecutionContext* PaymentRequest::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
ScriptPromise PaymentRequest::Retry(ScriptState* script_state,
- const PaymentValidationErrors* errors) {
+ const PaymentValidationErrors* errors,
+ ExceptionState& exception_state) {
if (!script_state->ContextIsValid() || !LocalDOMWindow::From(script_state) ||
!LocalDOMWindow::From(script_state)->GetFrame()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError,
- "Cannot retry the payment request"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kAbortError,
+ "Cannot retry the payment request");
+ return ScriptPromise();
}
if (complete_resolver_) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "Cannot call retry() because already called complete()"));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "Cannot call retry() because already called complete()");
+ return ScriptPromise();
}
if (retry_resolver_) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- "Cannot call retry() again until "
- "the previous retry() is finished"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Cannot call retry() again until "
+ "the previous retry() is finished");
+ return ScriptPromise();
}
if (!payment_provider_) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- "Payment request terminated"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Payment request terminated");
+ return ScriptPromise();
}
String error_message;
if (!PaymentsValidators::IsValidPaymentValidationErrorsFormat(
errors, &error_message)) {
- return ScriptPromise::Reject(
- script_state, V8ThrowException::CreateTypeError(
- script_state->GetIsolate(), error_message));
+ exception_state.ThrowTypeError(error_message);
+ return ScriptPromise();
}
if (!options_->requestPayerName() && errors->hasPayer() &&
errors->payer()->hasName()) {
GetExecutionContext()->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning,
- "The payer.name passed to retry() may not be "
- "shown because requestPayerName is false"));
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning,
+ "The payer.name passed to retry() may not be "
+ "shown because requestPayerName is false"));
}
if (!options_->requestPayerEmail() && errors->hasPayer() &&
errors->payer()->hasEmail()) {
GetExecutionContext()->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning,
- "The payer.email passed to retry() may not be "
- "shown because requestPayerEmail is false"));
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning,
+ "The payer.email passed to retry() may not be "
+ "shown because requestPayerEmail is false"));
}
if (!options_->requestPayerPhone() && errors->hasPayer() &&
errors->payer()->hasPhone()) {
GetExecutionContext()->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning,
- "The payer.phone passed to retry() may not be "
- "shown because requestPayerPhone is false"));
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning,
+ "The payer.phone passed to retry() may not be "
+ "shown because requestPayerPhone is false"));
}
if (!options_->requestShipping() && errors->hasShippingAddress()) {
GetExecutionContext()->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning,
- "The shippingAddress passed to retry() may not "
- "be shown because requestShipping is false"));
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning,
+ "The shippingAddress passed to retry() may not "
+ "be shown because requestShipping is false"));
}
complete_timer_.Stop();
@@ -931,41 +912,39 @@ ScriptPromise PaymentRequest::Retry(ScriptState* script_state,
}
ScriptPromise PaymentRequest::Complete(ScriptState* script_state,
- PaymentComplete result) {
+ PaymentComplete result,
+ ExceptionState& exception_state) {
if (!script_state->ContextIsValid()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- "Cannot complete payment"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Cannot complete payment");
+ return ScriptPromise();
}
if (complete_resolver_) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- "Already called complete() once"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Already called complete() once");
+ return ScriptPromise();
}
if (retry_resolver_) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "Cannot call complete() before retry() is finished"));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "Cannot call complete() before retry() is finished");
+ return ScriptPromise();
}
if (!complete_timer_.IsActive()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "Timed out after 60 seconds, complete() called too late"));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "Timed out after 60 seconds, complete() called too late");
+ return ScriptPromise();
}
// User has cancelled the transaction while the website was processing it.
if (!payment_provider_) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kAbortError, "Request cancelled"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kAbortError,
+ "Request cancelled");
+ return ScriptPromise();
}
complete_timer_.Stop();
@@ -988,13 +967,13 @@ void PaymentRequest::OnUpdatePaymentDetails(
update_payment_details_timer_.Stop();
- PaymentDetailsUpdate* details = PaymentDetailsUpdate::Create();
ExceptionState exception_state(v8::Isolate::GetCurrent(),
ExceptionState::kConstructionContext,
"PaymentDetailsUpdate");
- V8PaymentDetailsUpdate::ToImpl(resolver->GetScriptState()->GetIsolate(),
- details_script_value.V8Value(), details,
- exception_state);
+ PaymentDetailsUpdate* details =
+ NativeValueTraits<PaymentDetailsUpdate>::NativeValue(
+ resolver->GetScriptState()->GetIsolate(),
+ details_script_value.V8Value(), exception_state);
if (exception_state.HadException()) {
resolver->Reject(exception_state.GetException());
ClearResolversAndCloseMojoConnection();
@@ -1052,7 +1031,7 @@ bool PaymentRequest::IsInteractive() const {
return !!GetPendingAcceptPromiseResolver();
}
-void PaymentRequest::Trace(blink::Visitor* visitor) {
+void PaymentRequest::Trace(Visitor* visitor) {
visitor->Trace(options_);
visitor->Trace(shipping_address_);
visitor->Trace(payment_response_);
@@ -1063,7 +1042,7 @@ void PaymentRequest::Trace(blink::Visitor* visitor) {
visitor->Trace(can_make_payment_resolver_);
visitor->Trace(has_enrolled_instrument_resolver_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
void PaymentRequest::OnCompleteTimeoutForTesting() {
@@ -1088,7 +1067,7 @@ PaymentRequest::PaymentRequest(
const PaymentDetailsInit* details,
const PaymentOptions* options,
ExceptionState& exception_state)
- : ContextLifecycleObserver(execution_context),
+ : ExecutionContextLifecycleObserver(execution_context),
options_(options),
complete_timer_(
execution_context->GetTaskRunner(TaskType::kMiscPlatformAPI),
@@ -1098,8 +1077,7 @@ PaymentRequest::PaymentRequest(
execution_context->GetTaskRunner(TaskType::kMiscPlatformAPI),
this,
&PaymentRequest::OnUpdatePaymentDetailsTimeout),
- is_waiting_for_show_promise_to_resolve_(false),
- basic_card_has_supported_card_types_(false) {
+ is_waiting_for_show_promise_to_resolve_(false) {
DCHECK(GetExecutionContext()->IsSecureContext());
if (!AllowedToUsePaymentRequest(execution_context)) {
@@ -1129,15 +1107,13 @@ PaymentRequest::PaymentRequest(
Vector<payments::mojom::blink::PaymentMethodDataPtr> validated_method_data;
ValidateAndConvertPaymentMethodData(method_data, options_, skip_to_gpay_ready,
validated_method_data, method_names_,
- &basic_card_has_supported_card_types_,
*GetExecutionContext(), exception_state);
if (exception_state.HadException())
return;
ValidateAndConvertPaymentDetailsInit(details, options_, validated_details,
- shipping_option_,
- &basic_card_has_supported_card_types_,
- *GetExecutionContext(), exception_state);
+ shipping_option_, *GetExecutionContext(),
+ exception_state);
if (exception_state.HadException())
return;
@@ -1186,7 +1162,7 @@ PaymentRequest::PaymentRequest(
#endif
}
-void PaymentRequest::ContextDestroyed(ExecutionContext*) {
+void PaymentRequest::ContextDestroyed() {
ClearResolversAndCloseMojoConnection();
}
@@ -1487,15 +1463,15 @@ void PaymentRequest::OnHasEnrolledInstrument(
}
void PaymentRequest::WarnNoFavicon() {
- GetExecutionContext()->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning,
- "Favicon not found for PaymentRequest UI. User "
- "may not recognize the website."));
+ GetExecutionContext()->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning,
+ "Favicon not found for PaymentRequest UI. User "
+ "may not recognize the website."));
}
void PaymentRequest::OnCompleteTimeout(TimerBase*) {
- GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
+ GetExecutionContext()->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kError,
"Timed out waiting for a PaymentResponse.complete() call."));
@@ -1550,8 +1526,9 @@ void PaymentRequest::DispatchPaymentRequestUpdateEvent(
"line items and total.",
event->type().Ascii().c_str());
GetExecutionContext()->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning, message));
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning, message));
payment_provider_->OnPaymentDetailsNotUpdated();
// Make sure that updateWith() is only allowed to be called within the same
// event loop as the event dispatch. See
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 2315ff65bfa..c3aec087ca3 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request.h
@@ -14,11 +14,11 @@
#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/core/v8/script_value.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_method_data.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_options.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/modules/payments/payment_method_data.h"
-#include "third_party/blink/renderer/modules/payments/payment_options.h"
#include "third_party/blink/renderer/modules/payments/payment_request_delegate.h"
#include "third_party/blink/renderer/modules/payments/payment_state_resolver.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -43,7 +43,7 @@ class MODULES_EXPORT PaymentRequest final
public payments::mojom::blink::PaymentRequestClient,
public PaymentStateResolver,
public PaymentRequestDelegate,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public ActiveScriptWrappable<PaymentRequest> {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(PaymentRequest);
@@ -67,9 +67,11 @@ class MODULES_EXPORT PaymentRequest final
ExceptionState&);
~PaymentRequest() override;
- ScriptPromise show(ScriptState*);
- ScriptPromise show(ScriptState*, ScriptPromise details_promise);
- ScriptPromise abort(ScriptState*);
+ ScriptPromise show(ScriptState*, ExceptionState&);
+ ScriptPromise show(ScriptState*,
+ ScriptPromise details_promise,
+ ExceptionState&);
+ ScriptPromise abort(ScriptState*, ExceptionState&);
const String& id() const { return id_; }
PaymentAddress* getShippingAddress() const { return shipping_address_.Get(); }
@@ -80,8 +82,8 @@ class MODULES_EXPORT PaymentRequest final
DEFINE_ATTRIBUTE_EVENT_LISTENER(shippingoptionchange, kShippingoptionchange)
DEFINE_ATTRIBUTE_EVENT_LISTENER(paymentmethodchange, kPaymentmethodchange)
- ScriptPromise canMakePayment(ScriptState*);
- ScriptPromise hasEnrolledInstrument(ScriptState*);
+ ScriptPromise canMakePayment(ScriptState*, ExceptionState&);
+ ScriptPromise hasEnrolledInstrument(ScriptState*, ExceptionState&);
// ScriptWrappable:
bool HasPendingActivity() const override;
@@ -91,15 +93,19 @@ class MODULES_EXPORT PaymentRequest final
ExecutionContext* GetExecutionContext() const override;
// PaymentStateResolver:
- ScriptPromise Complete(ScriptState*, PaymentComplete result) override;
- ScriptPromise Retry(ScriptState*, const PaymentValidationErrors*) override;
+ ScriptPromise Complete(ScriptState*,
+ PaymentComplete result,
+ ExceptionState&) override;
+ ScriptPromise Retry(ScriptState*,
+ const PaymentValidationErrors*,
+ ExceptionState&) override;
// PaymentRequestDelegate:
void OnUpdatePaymentDetails(const ScriptValue& details_script_value) override;
void OnUpdatePaymentDetailsFailure(const String& error) override;
bool IsInteractive() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void OnCompleteTimeoutForTesting();
void OnUpdatePaymentDetailsTimeoutForTesting();
@@ -116,7 +122,7 @@ class MODULES_EXPORT PaymentRequest final
void OnConnectionError();
// LifecycleObserver:
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
// payments::mojom::blink::PaymentRequestClient:
void OnPaymentMethodChange(const String& method_name,
@@ -172,7 +178,6 @@ class MODULES_EXPORT PaymentRequest final
TaskRunnerTimer<PaymentRequest> complete_timer_;
TaskRunnerTimer<PaymentRequest> update_payment_details_timer_;
bool is_waiting_for_show_promise_to_resolve_;
- bool basic_card_has_supported_card_types_;
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 db417602b7b..9ef367ee752 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request.idl
@@ -7,17 +7,15 @@
[
RuntimeEnabled=PaymentRequest,
- Constructor(sequence<PaymentMethodData> methodData, PaymentDetailsInit details, optional PaymentOptions options),
- ConstructorCallWith=ExecutionContext,
- RaisesException=Constructor,
SecureContext,
Exposed=Window,
ActiveScriptWrappable
] interface PaymentRequest : EventTarget {
- [CallWith=ScriptState, NewObject] Promise<PaymentResponse> show(optional Promise<PaymentDetailsUpdate> detailsPromise);
- [CallWith=ScriptState, NewObject] Promise<void> abort();
- [CallWith=ScriptState, HighEntropy, Measure, NewObject] Promise<boolean> canMakePayment();
- [CallWith=ScriptState, HighEntropy, Measure, NewObject] Promise<boolean> hasEnrolledInstrument();
+ [CallWith=ExecutionContext, RaisesException] constructor(sequence<PaymentMethodData> methodData, 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();
+ [CallWith=ScriptState, RaisesException, HighEntropy, Measure, NewObject] Promise<boolean> hasEnrolledInstrument();
readonly attribute DOMString id;
[ImplementedAs=getShippingAddress] readonly attribute PaymentAddress? shippingAddress;
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request_details_test.cc b/chromium/third_party/blink/renderer/modules/payments/payment_request_details_test.cc
index 15164172895..ce5fdf02c55 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request_details_test.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_details_test.cc
@@ -7,9 +7,9 @@
#include <ostream> // NOLINT
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_details_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_options.h"
#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/modules/payments/payment_details_init.h"
-#include "third_party/blink/renderer/modules/payments/payment_options.h"
#include "third_party/blink/renderer/modules/payments/payment_test_helper.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
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 3ee4b87118f..df0a14ca8e3 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
@@ -7,25 +7,25 @@
#include <utility>
#include "third_party/blink/public/mojom/payments/payment_request.mojom-blink.h"
-#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_address_errors.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_currency_amount.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_details_modifier.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_item.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_method_data.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_request_details_update.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_shipping_option.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/core/workers/worker_location.h"
-#include "third_party/blink/renderer/modules/payments/address_errors.h"
-#include "third_party/blink/renderer/modules/payments/payment_address_init_type_converter.h"
-#include "third_party/blink/renderer/modules/payments/payment_currency_amount.h"
-#include "third_party/blink/renderer/modules/payments/payment_details_modifier.h"
-#include "third_party/blink/renderer/modules/payments/payment_item.h"
-#include "third_party/blink/renderer/modules/payments/payment_method_data.h"
-#include "third_party/blink/renderer/modules/payments/payment_options.h"
-#include "third_party/blink/renderer/modules/payments/payment_request_details_update.h"
-#include "third_party/blink/renderer/modules/payments/payment_shipping_option.h"
+#include "third_party/blink/renderer/modules/payments/address_init_type_converter.h"
#include "third_party/blink/renderer/modules/payments/payments_validators.h"
#include "third_party/blink/renderer/modules/service_worker/respond_with_observer.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_window_client.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/heap/heap.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
@@ -127,6 +127,13 @@ const ScriptValue PaymentRequestEvent::paymentOptions(
return ScriptValue::From(script_state, payment_options_);
}
+base::Optional<HeapVector<Member<PaymentShippingOption>>>
+PaymentRequestEvent::shippingOptions() const {
+ if (shipping_options_.IsEmpty())
+ return base::nullopt;
+ return shipping_options_;
+}
+
const HeapVector<Member<PaymentShippingOption>>&
PaymentRequestEvent::shippingOptions(bool& is_null) const {
is_null = shipping_options_.IsEmpty();
@@ -190,18 +197,17 @@ ScriptPromise PaymentRequestEvent::changePaymentMethod(
const ScriptValue& method_details,
ExceptionState& exception_state) {
if (change_payment_request_details_resolver_) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "Waiting for response to the previous payment "
- "request details change"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Waiting for response to the previous "
+ "payment request details change");
+ return ScriptPromise();
}
if (!payment_handler_host_.is_bound()) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "No corresponding PaymentRequest object found"));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "No corresponding PaymentRequest object found");
+ return ScriptPromise();
}
auto method_data = payments::mojom::blink::PaymentHandlerMethodData::New();
@@ -225,26 +231,25 @@ ScriptPromise PaymentRequestEvent::changePaymentMethod(
ScriptPromise PaymentRequestEvent::changeShippingAddress(
ScriptState* script_state,
- PaymentAddressInit* shipping_address) {
+ AddressInit* shipping_address,
+ ExceptionState& exception_state) {
if (change_payment_request_details_resolver_) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "Waiting for response to the previous payment "
- "request details change"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Waiting for response to the previous "
+ "payment request details change");
+ return ScriptPromise();
}
if (!payment_handler_host_.is_bound()) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "No corresponding PaymentRequest object found"));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "No corresponding PaymentRequest object found");
+ return ScriptPromise();
}
if (!shipping_address) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kSyntaxError,
- "Shipping address cannot be null"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
+ "Shipping address cannot be null");
+ return ScriptPromise();
}
auto shipping_address_ptr =
@@ -252,10 +257,9 @@ ScriptPromise PaymentRequestEvent::changeShippingAddress(
String shipping_address_error;
if (!PaymentsValidators::IsValidShippingAddress(shipping_address_ptr,
&shipping_address_error)) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kSyntaxError,
- shipping_address_error));
+ exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
+ shipping_address_error);
+ return ScriptPromise();
}
payment_handler_host_->ChangeShippingAddress(
@@ -269,20 +273,20 @@ ScriptPromise PaymentRequestEvent::changeShippingAddress(
ScriptPromise PaymentRequestEvent::changeShippingOption(
ScriptState* script_state,
- const String& shipping_option_id) {
+ const String& shipping_option_id,
+ ExceptionState& exception_state) {
if (change_payment_request_details_resolver_) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "Waiting for response to the previous payment "
- "request details change"));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "Waiting for response to the previous payment request details change");
+ return ScriptPromise();
}
if (!payment_handler_host_.is_bound()) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "No corresponding PaymentRequest object found"));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "No corresponding PaymentRequest object found");
+ return ScriptPromise();
}
bool shipping_option_id_is_valid = false;
@@ -293,10 +297,9 @@ ScriptPromise PaymentRequestEvent::changeShippingOption(
}
}
if (!shipping_option_id_is_valid) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kSyntaxError,
- "Shipping option identifier is invalid"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
+ "Shipping option identifier is invalid");
+ return ScriptPromise();
}
payment_handler_host_->ChangeShippingOption(
@@ -324,7 +327,7 @@ void PaymentRequestEvent::respondWith(ScriptState* script_state,
}
}
-void PaymentRequestEvent::Trace(blink::Visitor* visitor) {
+void PaymentRequestEvent::Trace(Visitor* visitor) {
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 868d5c9959e..f4ecd6f05ae 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
@@ -10,9 +10,9 @@
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/payments/payment_handler_host.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_address_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_request_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
-#include "third_party/blink/renderer/modules/payments/payment_address_init.h"
-#include "third_party/blink/renderer/modules/payments/payment_request_event_init.h"
#include "third_party/blink/renderer/modules/service_worker/extendable_event.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -22,6 +22,7 @@ class AtomicString;
namespace blink {
+class ExceptionState;
class RespondWithObserver;
class ScriptPromiseResolver;
class ScriptState;
@@ -58,8 +59,11 @@ class MODULES_EXPORT PaymentRequestEvent final : public ExtendableEvent {
const HeapVector<Member<PaymentDetailsModifier>>& modifiers() const;
const String& instrumentKey() const;
const ScriptValue paymentOptions(ScriptState*) const;
+ base::Optional<HeapVector<Member<PaymentShippingOption>>> shippingOptions()
+ const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
const HeapVector<Member<PaymentShippingOption>>& shippingOptions(
- bool& is_null) const;
+ bool& is_null) const; // DEPRECATED
ScriptPromise openWindow(ScriptState*, const String& url);
ScriptPromise changePaymentMethod(ScriptState*,
@@ -70,12 +74,14 @@ class MODULES_EXPORT PaymentRequestEvent final : public ExtendableEvent {
const ScriptValue& method_details,
ExceptionState& exception_state);
ScriptPromise changeShippingAddress(ScriptState*,
- PaymentAddressInit* shippingAddress);
+ AddressInit*,
+ ExceptionState&);
ScriptPromise changeShippingOption(ScriptState*,
- const String& shipping_option_id);
+ const String& shipping_option_id,
+ ExceptionState&);
void respondWith(ScriptState*, ScriptPromise, ExceptionState&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void OnChangePaymentRequestDetailsResponse(
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request_event.idl b/chromium/third_party/blink/renderer/modules/payments/payment_request_event.idl
index 21608ee8516..5b245c1c351 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request_event.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_event.idl
@@ -6,9 +6,9 @@
[
RuntimeEnabled=PaymentApp,
- Constructor(DOMString type, PaymentRequestEventInit eventInitDict),
Exposed=ServiceWorker
] interface PaymentRequestEvent : ExtendableEvent {
+ constructor(DOMString type, PaymentRequestEventInit eventInitDict);
readonly attribute USVString topOrigin;
readonly attribute USVString paymentRequestOrigin;
readonly attribute DOMString paymentRequestId;
@@ -22,6 +22,6 @@
[CallWith=ScriptState] Promise<WindowClient?> openWindow(USVString url);
[CallWith=ScriptState, RaisesException, RuntimeEnabled=PaymentHandlerChangePaymentMethod] Promise<PaymentRequestDetailsUpdate?> changePaymentMethod(DOMString methodName, optional object? methodDetails = null);
[CallWith=ScriptState, RaisesException] void respondWith(Promise<PaymentResponse> response);
- [CallWith=ScriptState, RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] Promise<PaymentRequestDetailsUpdate?> changeShippingAddress(PaymentAddressInit shippingAddress);
- [CallWith=ScriptState, RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] Promise<PaymentRequestDetailsUpdate> changeShippingOption(DOMString shippingOption);
+ [CallWith=ScriptState, RaisesException, RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] Promise<PaymentRequestDetailsUpdate?> changeShippingAddress(AddressInit shippingAddress);
+ [CallWith=ScriptState, RaisesException, RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] Promise<PaymentRequestDetailsUpdate> changeShippingOption(DOMString shippingOption);
};
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 5fcc26a45e5..2d6a3b72b58 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
@@ -4,21 +4,22 @@
#include "third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.h"
+#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_address_init.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_address.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_handler_response.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
+#include "third_party/blink/renderer/modules/payments/address_init_type_converter.h"
#include "third_party/blink/renderer/modules/payments/payment_address.h"
-#include "third_party/blink/renderer/modules/payments/payment_address_init.h"
-#include "third_party/blink/renderer/modules/payments/payment_address_init_type_converter.h"
-#include "third_party/blink/renderer/modules/payments/payment_handler_response.h"
#include "third_party/blink/renderer/modules/payments/payment_handler_utils.h"
#include "third_party/blink/renderer/modules/payments/payments_validators.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h"
#include "third_party/blink/renderer/modules/service_worker/wait_until_observer.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "v8/include/v8.h"
namespace blink {
@@ -69,11 +70,12 @@ void PaymentRequestRespondWithObserver::OnResponseFulfilled(
!response->hasDetails() || response->details().IsNull() ||
!response->details().IsObject()) {
GetExecutionContext()->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kError,
- "'PaymentHandlerResponse.methodName' and "
- "'PaymentHandlerResponse.details' must not "
- "be empty in payment response."));
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kError,
+ "'PaymentHandlerResponse.methodName' and "
+ "'PaymentHandlerResponse.details' must not "
+ "be empty in payment response."));
}
if (!response->hasMethodName() || response->methodName().IsEmpty()) {
@@ -97,11 +99,12 @@ void PaymentRequestRespondWithObserver::OnResponseFulfilled(
if (!v8::JSON::Stringify(script_state->GetContext(),
response->details().V8Value().As<v8::Object>())
.ToLocal(&details_value)) {
- GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kError,
- "Failed to stringify PaymentHandlerResponse.details in payment "
- "response."));
+ GetExecutionContext()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kError,
+ "Failed to stringify PaymentHandlerResponse.details in payment "
+ "response."));
BlankResponseWithError(
PaymentEventResponseType::PAYMENT_DETAILS_STRINGIFY_ERROR);
return;
@@ -169,7 +172,7 @@ PaymentRequestRespondWithObserver::PaymentRequestRespondWithObserver(
WaitUntilObserver* observer)
: RespondWithObserver(context, event_id, observer) {}
-void PaymentRequestRespondWithObserver::Trace(blink::Visitor* visitor) {
+void PaymentRequestRespondWithObserver::Trace(Visitor* visitor) {
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 a9428dc89fc..2f06819f32b 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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_test.cc b/chromium/third_party/blink/renderer/modules/payments/payment_request_test.cc
index a8f012eadf2..740369cac3d 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request_test.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_test.cc
@@ -9,6 +9,7 @@
#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"
namespace blink {
@@ -244,10 +245,9 @@ TEST(PaymentRequestTest, RejectShowPromiseOnInvalidShippingAddress) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -259,10 +259,9 @@ TEST(PaymentRequestTest, OnShippingOptionChange) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectNoCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -274,12 +273,12 @@ TEST(PaymentRequestTest, CannotCallShowTwice) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
- request->show(scope.GetScriptState());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION);
- request->show(scope.GetScriptState())
- .Then(funcs.ExpectNoCall(), funcs.ExpectCall());
+ request->show(scope.GetScriptState(), scope.GetExceptionState());
+ EXPECT_EQ(scope.GetExceptionState().Code(),
+ ToExceptionCode(DOMExceptionCode::kInvalidStateError));
}
TEST(PaymentRequestTest, CannotShowAfterAborted) {
@@ -287,15 +286,16 @@ TEST(PaymentRequestTest, CannotShowAfterAborted) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
- request->show(scope.GetScriptState());
- request->abort(scope.GetScriptState());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION);
+ request->abort(scope.GetScriptState(), ASSERT_NO_EXCEPTION);
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)->OnAbort(
true);
- request->show(scope.GetScriptState())
- .Then(funcs.ExpectNoCall(), funcs.ExpectCall());
+ request->show(scope.GetScriptState(), scope.GetExceptionState());
+ EXPECT_EQ(scope.GetExceptionState().Code(),
+ ToExceptionCode(DOMExceptionCode::kInvalidStateError));
+ ;
}
TEST(PaymentRequestTest, RejectShowPromiseOnErrorPaymentMethodNotSupported) {
@@ -303,11 +303,10 @@ TEST(PaymentRequestTest, RejectShowPromiseOnErrorPaymentMethodNotSupported) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
String error_message;
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall(&error_message));
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)->OnError(
@@ -324,11 +323,10 @@ TEST(PaymentRequestTest, RejectShowPromiseOnErrorCancelled) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
String error_message;
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall(&error_message));
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)->OnError(
@@ -344,11 +342,10 @@ TEST(PaymentRequestTest, RejectShowPromiseOnUpdateDetailsFailure) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
String error_message;
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall(&error_message));
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -364,9 +361,8 @@ TEST(PaymentRequestTest, IgnoreUpdatePaymentDetailsAfterShowPromiseResolved) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
- request->show(scope.GetScriptState())
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectCall(), funcs.ExpectNoCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
->OnPaymentResponse(BuildPaymentResponseForTest());
@@ -380,10 +376,9 @@ TEST(PaymentRequestTest, RejectShowPromiseOnNonPaymentDetailsUpdate) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -397,10 +392,9 @@ TEST(PaymentRequestTest, RejectShowPromiseOnInvalidPaymentDetailsUpdate) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -409,8 +403,7 @@ TEST(PaymentRequestTest, RejectShowPromiseOnInvalidPaymentDetailsUpdate) {
scope.GetScriptState(),
FromJSONString(scope.GetScriptState()->GetIsolate(),
scope.GetScriptState()->GetContext(), "{\"total\": {}}",
- scope.GetExceptionState())));
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ ASSERT_NO_EXCEPTION)));
}
TEST(PaymentRequestTest,
@@ -423,10 +416,9 @@ TEST(PaymentRequestTest,
options->setRequestShipping(true);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(), details,
- options, scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ options, ASSERT_NO_EXCEPTION);
EXPECT_TRUE(request->shippingOption().IsNull());
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectNoCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
->OnShippingAddressChange(BuildPaymentAddressForTest());
@@ -440,8 +432,7 @@ TEST(PaymentRequestTest,
scope.GetScriptState(),
FromJSONString(scope.GetScriptState()->GetIsolate(),
scope.GetScriptState()->GetContext(),
- detail_with_shipping_options, scope.GetExceptionState())));
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ detail_with_shipping_options, ASSERT_NO_EXCEPTION)));
EXPECT_EQ("standardShippingOption", request->shippingOption());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
->OnShippingAddressChange(BuildPaymentAddressForTest());
@@ -449,14 +440,12 @@ TEST(PaymentRequestTest,
"{\"total\": {\"label\": \"Total\", \"amount\": {\"currency\": \"USD\", "
"\"value\": \"5.00\"}}}";
- request->OnUpdatePaymentDetails(
- ScriptValue::From(scope.GetScriptState(),
- FromJSONString(scope.GetScriptState()->GetIsolate(),
- scope.GetScriptState()->GetContext(),
- detail_without_shipping_options,
- scope.GetExceptionState())));
+ request->OnUpdatePaymentDetails(ScriptValue::From(
+ scope.GetScriptState(),
+ FromJSONString(scope.GetScriptState()->GetIsolate(),
+ scope.GetScriptState()->GetContext(),
+ detail_without_shipping_options, ASSERT_NO_EXCEPTION)));
- EXPECT_FALSE(scope.GetExceptionState().HadException());
EXPECT_TRUE(request->shippingOption().IsNull());
}
@@ -469,9 +458,8 @@ TEST(
options->setRequestShipping(true);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
- request->show(scope.GetScriptState())
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectNoCall());
String detail =
"{\"total\": {\"label\": \"Total\", \"amount\": {\"currency\": \"USD\", "
@@ -485,8 +473,7 @@ TEST(
ScriptValue::From(scope.GetScriptState(),
FromJSONString(scope.GetScriptState()->GetIsolate(),
scope.GetScriptState()->GetContext(),
- detail, scope.GetExceptionState())));
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ detail, ASSERT_NO_EXCEPTION)));
EXPECT_TRUE(request->shippingOption().IsNull());
}
@@ -498,9 +485,8 @@ TEST(PaymentRequestTest, UseTheSelectedShippingOptionFromPaymentDetailsUpdate) {
options->setRequestShipping(true);
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), options, scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
- request->show(scope.GetScriptState())
+ BuildPaymentDetailsInitForTest(), options, ASSERT_NO_EXCEPTION);
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectNoCall());
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
->OnShippingAddressChange(BuildPaymentAddressForTest());
@@ -516,8 +502,7 @@ TEST(PaymentRequestTest, UseTheSelectedShippingOptionFromPaymentDetailsUpdate) {
ScriptValue::From(scope.GetScriptState(),
FromJSONString(scope.GetScriptState()->GetIsolate(),
scope.GetScriptState()->GetContext(),
- detail, scope.GetExceptionState())));
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ detail, ASSERT_NO_EXCEPTION)));
EXPECT_EQ("fast", request->shippingOption());
}
@@ -527,10 +512,9 @@ TEST(PaymentRequestTest, NoExceptionWithErrorMessageInUpdate) {
PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
PaymentRequest* request = PaymentRequest::Create(
scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
- BuildPaymentDetailsInitForTest(), scope.GetExceptionState());
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
.Then(funcs.ExpectNoCall(), funcs.ExpectNoCall());
String detail_with_error_msg =
"{\"total\": {\"label\": \"Total\", \"amount\": {\"currency\": \"USD\", "
@@ -541,8 +525,7 @@ TEST(PaymentRequestTest, NoExceptionWithErrorMessageInUpdate) {
scope.GetScriptState(),
FromJSONString(scope.GetScriptState()->GetIsolate(),
scope.GetScriptState()->GetContext(),
- detail_with_error_msg, scope.GetExceptionState())));
- EXPECT_FALSE(scope.GetExceptionState().HadException());
+ detail_with_error_msg, ASSERT_NO_EXCEPTION)));
}
TEST(PaymentRequestTest,
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 7af3e8cd6f8..fe6de07bba3 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(blink::Visitor* visitor) {
+void PaymentRequestUpdateEvent::Trace(Visitor* visitor) {
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 f3e5e0469e5..96d0b510421 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
@@ -6,9 +6,9 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_REQUEST_UPDATE_EVENT_H_
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_request_update_event_init.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/modules/payments/payment_request_update_event_init.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/timer.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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
// True after event.updateWith() was called.
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.idl b/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.idl
index 90e0ad438f0..0dded8b3f22 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.idl
@@ -6,9 +6,8 @@
[
RuntimeEnabled=PaymentRequest,
- Constructor(DOMString type, optional PaymentRequestUpdateEventInit eventInitDict),
- ConstructorCallWith=ExecutionContext,
Exposed=Window
] interface PaymentRequestUpdateEvent : Event {
+ [CallWith=ExecutionContext] constructor(DOMString type, optional PaymentRequestUpdateEventInit eventInitDict = {});
[CallWith=ScriptState,RaisesException] void updateWith(Promise<PaymentDetailsUpdate> detailsPromise);
};
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 930831f133b..f2af6da908e 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(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) override {}
private:
DISALLOW_COPY_AND_ASSIGN(MockPaymentRequest);
@@ -147,7 +147,7 @@ TEST(PaymentRequestUpdateEventTest, AddressChangeUpdateWithTimeout) {
EXPECT_FALSE(scope.GetExceptionState().HadException());
String error_message;
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), scope.GetExceptionState())
.Then(funcs.ExpectNoCall(), funcs.ExpectCall(&error_message));
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -184,7 +184,7 @@ TEST(PaymentRequestUpdateEventTest, OptionChangeUpdateWithTimeout) {
EXPECT_FALSE(scope.GetExceptionState().HadException());
String error_message;
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), scope.GetExceptionState())
.Then(funcs.ExpectNoCall(), funcs.ExpectCall(&error_message));
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
@@ -221,7 +221,7 @@ TEST(PaymentRequestUpdateEventTest, AddressChangePromiseTimeout) {
event->SetPaymentRequest(request);
event->SetEventPhase(Event::kCapturingPhase);
String error_message;
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), scope.GetExceptionState())
.Then(funcs.ExpectNoCall(), funcs.ExpectCall(&error_message));
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
->OnShippingAddressChange(BuildPaymentAddressForTest());
@@ -255,7 +255,7 @@ TEST(PaymentRequestUpdateEventTest, OptionChangePromiseTimeout) {
event->SetPaymentRequest(request);
event->SetEventPhase(Event::kCapturingPhase);
String error_message;
- request->show(scope.GetScriptState())
+ request->show(scope.GetScriptState(), scope.GetExceptionState())
.Then(funcs.ExpectNoCall(), funcs.ExpectCall(&error_message));
static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
->OnShippingAddressChange(BuildPaymentAddressForTest());
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 e95bb6f80d3..22418c87097 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_response.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_response.cc
@@ -6,9 +6,10 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_validation_errors.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/payments/payment_address.h"
#include "third_party/blink/renderer/modules/payments/payment_state_resolver.h"
-#include "third_party/blink/renderer/modules/payments/payment_validation_errors.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/wtf/assertions.h"
@@ -21,7 +22,7 @@ PaymentResponse::PaymentResponse(
PaymentAddress* shipping_address,
PaymentStateResolver* payment_state_resolver,
const String& request_id)
- : ContextLifecycleObserver(ExecutionContext::From(script_state)),
+ : ExecutionContextClient(ExecutionContext::From(script_state)),
request_id_(request_id),
method_name_(response->method_name),
shipping_address_(shipping_address),
@@ -109,20 +110,24 @@ ScriptValue PaymentResponse::details(ScriptState* script_state) const {
}
ScriptPromise PaymentResponse::complete(ScriptState* script_state,
- const String& result) {
+ const String& result,
+ ExceptionState& exception_state) {
PaymentStateResolver::PaymentComplete converted_result =
PaymentStateResolver::PaymentComplete::kUnknown;
if (result == "success")
converted_result = PaymentStateResolver::PaymentComplete::kSuccess;
else if (result == "fail")
converted_result = PaymentStateResolver::PaymentComplete::kFail;
- return payment_state_resolver_->Complete(script_state, converted_result);
+ return payment_state_resolver_->Complete(script_state, converted_result,
+ exception_state);
}
ScriptPromise PaymentResponse::retry(
ScriptState* script_state,
- const PaymentValidationErrors* error_fields) {
- return payment_state_resolver_->Retry(script_state, error_fields);
+ const PaymentValidationErrors* error_fields,
+ ExceptionState& exception_state) {
+ return payment_state_resolver_->Retry(script_state, error_fields,
+ exception_state);
}
bool PaymentResponse::HasPendingActivity() const {
@@ -134,15 +139,15 @@ const AtomicString& PaymentResponse::InterfaceName() const {
}
ExecutionContext* PaymentResponse::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextClient::GetExecutionContext();
}
-void PaymentResponse::Trace(blink::Visitor* visitor) {
+void PaymentResponse::Trace(Visitor* visitor) {
visitor->Trace(details_);
visitor->Trace(shipping_address_);
visitor->Trace(payment_state_resolver_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 c890b371325..4a48f2e9d34 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_response.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_response.h
@@ -11,16 +11,17 @@
#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/world_safe_v8_reference.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_currency_amount.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/modules/payments/payment_currency_amount.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/wtf/text/wtf_string.h"
namespace blink {
+class ExceptionState;
class PaymentAddress;
class PaymentStateResolver;
class PaymentValidationErrors;
@@ -28,7 +29,7 @@ class ScriptState;
class MODULES_EXPORT PaymentResponse final
: public EventTargetWithInlineData,
- public ContextLifecycleObserver,
+ public ExecutionContextClient,
public ActiveScriptWrappable<PaymentResponse> {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(PaymentResponse);
@@ -58,8 +59,10 @@ class MODULES_EXPORT PaymentResponse final
const String& payerEmail() const { return payer_email_; }
const String& payerPhone() const { return payer_phone_; }
- ScriptPromise complete(ScriptState*, const String& result = "");
- ScriptPromise retry(ScriptState*, const PaymentValidationErrors*);
+ ScriptPromise complete(ScriptState*, const String& result, ExceptionState&);
+ ScriptPromise retry(ScriptState*,
+ const PaymentValidationErrors*,
+ ExceptionState&);
bool HasPendingActivity() const override;
@@ -68,7 +71,7 @@ class MODULES_EXPORT PaymentResponse final
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
String request_id_;
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_response.idl b/chromium/third_party/blink/renderer/modules/payments/payment_response.idl
index 6401233f885..21a43c33a33 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_response.idl
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_response.idl
@@ -29,8 +29,8 @@ enum PaymentComplete {
readonly attribute DOMString? payerEmail;
readonly attribute DOMString? payerPhone;
- [CallWith=ScriptState, NewObject] Promise<void> complete(optional PaymentComplete paymentResult = "unknown");
- [CallWith=ScriptState, NewObject, RuntimeEnabled=PaymentRetry] Promise<void> retry(optional PaymentValidationErrors errorFields);
+ [CallWith=ScriptState, RaisesException, NewObject] Promise<void> complete(optional PaymentComplete paymentResult = "unknown");
+ [CallWith=ScriptState, RaisesException, NewObject, RuntimeEnabled=PaymentRetry] Promise<void> retry(optional PaymentValidationErrors errorFields = {});
[RuntimeEnabled=PaymentRetry] attribute EventHandler onpayerdetailchange;
};
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 35d6d02f1c4..86e2b2af20b 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
@@ -14,10 +14,10 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_validation_errors.h"
#include "third_party/blink/renderer/modules/payments/payment_address.h"
#include "third_party/blink/renderer/modules/payments/payment_state_resolver.h"
#include "third_party/blink/renderer/modules/payments/payment_test_helper.h"
-#include "third_party/blink/renderer/modules/payments/payment_validation_errors.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
@@ -31,20 +31,22 @@ class MockPaymentStateResolver final
public:
MockPaymentStateResolver() {
- ON_CALL(*this, Complete(testing::_, testing::_))
+ ON_CALL(*this, Complete(testing::_, testing::_, testing::_))
.WillByDefault(testing::ReturnPointee(&dummy_promise_));
}
~MockPaymentStateResolver() override = default;
- MOCK_METHOD2(Complete, ScriptPromise(ScriptState*, PaymentComplete result));
- MOCK_METHOD2(Retry,
+ MOCK_METHOD3(Complete,
ScriptPromise(ScriptState*,
- const PaymentValidationErrors* errorFields));
+ PaymentComplete result,
+ ExceptionState&));
+ MOCK_METHOD3(Retry,
+ ScriptPromise(ScriptState*,
+ const PaymentValidationErrors* errorFields,
+ ExceptionState&));
- void Trace(blink::Visitor* visitor) override {
- visitor->Trace(dummy_promise_);
- }
+ void Trace(Visitor* visitor) override { visitor->Trace(dummy_promise_); }
private:
ScriptPromise dummy_promise_;
@@ -145,9 +147,11 @@ TEST(PaymentResponseTest, CompleteCalledWithSuccess) {
"id");
EXPECT_CALL(*complete_callback,
- Complete(scope.GetScriptState(), PaymentStateResolver::kSuccess));
+ Complete(scope.GetScriptState(), PaymentStateResolver::kSuccess,
+ testing::_));
- output->complete(scope.GetScriptState(), "success");
+ output->complete(scope.GetScriptState(), "success",
+ scope.GetExceptionState());
}
TEST(PaymentResponseTest, CompleteCalledWithFailure) {
@@ -163,9 +167,10 @@ TEST(PaymentResponseTest, CompleteCalledWithFailure) {
"id");
EXPECT_CALL(*complete_callback,
- Complete(scope.GetScriptState(), PaymentStateResolver::kFail));
+ Complete(scope.GetScriptState(), PaymentStateResolver::kFail,
+ testing::_));
- output->complete(scope.GetScriptState(), "fail");
+ output->complete(scope.GetScriptState(), "fail", scope.GetExceptionState());
}
TEST(PaymentResponseTest, JSONSerializerTest) {
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_state_resolver.h b/chromium/third_party/blink/renderer/modules/payments/payment_state_resolver.h
index c9014ac1e96..781e24c9353 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_state_resolver.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_state_resolver.h
@@ -18,8 +18,12 @@ class MODULES_EXPORT PaymentStateResolver : public GarbageCollectedMixin {
public:
enum PaymentComplete { kFail, kSuccess, kUnknown };
- virtual ScriptPromise Complete(ScriptState*, PaymentComplete result) = 0;
- virtual ScriptPromise Retry(ScriptState*, const PaymentValidationErrors*) = 0;
+ virtual ScriptPromise Complete(ScriptState*,
+ PaymentComplete result,
+ ExceptionState&) = 0;
+ virtual ScriptPromise Retry(ScriptState*,
+ const PaymentValidationErrors*,
+ ExceptionState&) = 0;
protected:
virtual ~PaymentStateResolver() = default;
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_test_helper.cc b/chromium/third_party/blink/renderer/modules/payments/payment_test_helper.cc
index 609c8cd60a5..b79e0eb6f59 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_test_helper.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_test_helper.cc
@@ -4,10 +4,10 @@
#include "third_party/blink/renderer/modules/payments/payment_test_helper.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_currency_amount.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_details_modifier.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_method_data.h"
#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/modules/payments/payment_currency_amount.h"
-#include "third_party/blink/renderer/modules/payments/payment_details_modifier.h"
-#include "third_party/blink/renderer/modules/payments/payment_method_data.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -215,7 +215,8 @@ payments::mojom::blink::PaymentAddressPtr BuildPaymentAddressForTest() {
PaymentRequestV8TestingScope::PaymentRequestV8TestingScope()
: V8TestingScope(KURL("https://www.example.com/")) {
- GetDocument().SetSecureContextStateForTesting(SecureContextState::kSecure);
+ GetDocument().SetSecureContextModeForTesting(
+ SecureContextMode::kSecureContext);
}
PaymentRequestMockFunctionScope::PaymentRequestMockFunctionScope(
diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_test_helper.h b/chromium/third_party/blink/renderer/modules/payments/payment_test_helper.h
index 50477fdbb13..44933b8c6d9 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payment_test_helper.h
+++ b/chromium/third_party/blink/renderer/modules/payments/payment_test_helper.h
@@ -10,10 +10,10 @@
#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/core/v8/v8_dom_exception.h"
-#include "third_party/blink/renderer/modules/payments/payment_details_init.h"
-#include "third_party/blink/renderer/modules/payments/payment_details_update.h"
-#include "third_party/blink/renderer/modules/payments/payment_item.h"
-#include "third_party/blink/renderer/modules/payments/payment_shipping_option.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_details_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_details_update.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_item.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_shipping_option.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -116,7 +116,7 @@ class PaymentRequestMockFunctionScope {
String* value_;
};
- Member<ScriptState> script_state_;
+ ScriptState* script_state_;
Vector<Persistent<MockFunction>> mock_functions_;
};
diff --git a/chromium/third_party/blink/renderer/modules/payments/payments_validators.cc b/chromium/third_party/blink/renderer/modules/payments/payments_validators.cc
index 2262c8f8733..e103eea6449 100644
--- a/chromium/third_party/blink/renderer/modules/payments/payments_validators.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/payments_validators.cc
@@ -6,9 +6,9 @@
#include "third_party/blink/renderer/bindings/core/v8/script_regexp.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
-#include "third_party/blink/renderer/modules/payments/address_errors.h"
-#include "third_party/blink/renderer/modules/payments/payer_errors.h"
-#include "third_party/blink/renderer/modules/payments/payment_validation_errors.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_address_errors.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payer_errors.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_validation_errors.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/string_resource.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
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 1dc6e1baedc..e13cf4a7fdc 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
@@ -7,9 +7,9 @@
#include <ostream> // NOLINT
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/modules/payments/address_errors.h"
-#include "third_party/blink/renderer/modules/payments/payer_errors.h"
-#include "third_party/blink/renderer/modules/payments/payment_validation_errors.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_address_errors.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payer_errors.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_validation_errors.h"
#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
diff --git a/chromium/third_party/blink/renderer/modules/payments/skip_to_gpay_utils.cc b/chromium/third_party/blink/renderer/modules/payments/skip_to_gpay_utils.cc
index 1a7f1426e13..5e7fb9f1744 100644
--- a/chromium/third_party/blink/renderer/modules/payments/skip_to_gpay_utils.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/skip_to_gpay_utils.cc
@@ -5,8 +5,8 @@
#include "third_party/blink/renderer/modules/payments/skip_to_gpay_utils.h"
#include "base/logging.h"
-#include "third_party/blink/renderer/modules/payments/payment_method_data.h"
-#include "third_party/blink/renderer/modules/payments/payment_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_method_data.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_options.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/json/json_parser.h"
#include "third_party/blink/renderer/platform/json/json_values.h"
diff --git a/chromium/third_party/blink/renderer/modules/payments/skip_to_gpay_utils_test.cc b/chromium/third_party/blink/renderer/modules/payments/skip_to_gpay_utils_test.cc
index 0d56ae8025d..0de3ffca4a0 100644
--- a/chromium/third_party/blink/renderer/modules/payments/skip_to_gpay_utils_test.cc
+++ b/chromium/third_party/blink/renderer/modules/payments/skip_to_gpay_utils_test.cc
@@ -8,7 +8,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/modules/payments/payment_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_options.h"
namespace blink {
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 3cdf2fb5da9..b019e50b7e5 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(blink::Visitor* visitor) {
+void UpdatePaymentDetailsFunction::Trace(Visitor* visitor) {
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 11d32ba1aba..3b7a6426972 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 5e6915ee83f..27fe410a731 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn
@@ -76,6 +76,22 @@ blink_modules_sources("peerconnection") {
"rtc_dtmf_sender.h",
"rtc_dtmf_tone_change_event.cc",
"rtc_dtmf_tone_change_event.h",
+ "rtc_encoded_audio_frame.cc",
+ "rtc_encoded_audio_frame.h",
+ "rtc_encoded_audio_frame_delegate.cc",
+ "rtc_encoded_audio_frame_delegate.h",
+ "rtc_encoded_audio_underlying_sink.cc",
+ "rtc_encoded_audio_underlying_sink.h",
+ "rtc_encoded_audio_underlying_source.cc",
+ "rtc_encoded_audio_underlying_source.h",
+ "rtc_encoded_video_frame.cc",
+ "rtc_encoded_video_frame.h",
+ "rtc_encoded_video_frame_delegate.cc",
+ "rtc_encoded_video_frame_delegate.h",
+ "rtc_encoded_video_underlying_sink.cc",
+ "rtc_encoded_video_underlying_sink.h",
+ "rtc_encoded_video_underlying_source.cc",
+ "rtc_encoded_video_underlying_source.h",
"rtc_error.cc",
"rtc_error.h",
"rtc_error_event.cc",
@@ -151,12 +167,8 @@ blink_modules_sources("peerconnection") {
"webrtc_set_description_observer.h",
]
- public_deps = [
- "//third_party/webrtc_overrides:webrtc_component",
- ]
- deps = [
- "//third_party/abseil-cpp/absl/types:optional",
- ]
+ public_deps = [ "//third_party/webrtc_overrides:webrtc_component" ]
+ deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
}
jumbo_source_set("test_support") {
@@ -171,10 +183,10 @@ jumbo_source_set("test_support") {
"mock_peer_connection_dependency_factory.h",
"mock_peer_connection_impl.cc",
"mock_peer_connection_impl.h",
- "mock_web_rtc_peer_connection_handler.cc",
- "mock_web_rtc_peer_connection_handler.h",
- "mock_web_rtc_peer_connection_handler_client.cc",
- "mock_web_rtc_peer_connection_handler_client.h",
+ "mock_rtc_peer_connection_handler_client.cc",
+ "mock_rtc_peer_connection_handler_client.h",
+ "mock_rtc_peer_connection_handler_platform.cc",
+ "mock_rtc_peer_connection_handler_platform.h",
"test_webrtc_stats_report_obtainer.cc",
"test_webrtc_stats_report_obtainer.h",
]
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/DEPS b/chromium/third_party/blink/renderer/modules/peerconnection/DEPS
index 8870f516aaa..22a107fd92e 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/DEPS
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/DEPS
@@ -25,6 +25,7 @@ include_rules = [
"+media/media_buildflags.h",
"+media/video/gpu_video_accelerator_factories.h",
"+net/third_party/quiche/src/quic",
+ "+net/third_party/quiche/src/common",
"+net/quic/chromium",
"+net/quic",
"+net/test",
@@ -34,7 +35,7 @@ include_rules = [
specific_include_rules = {
".*test.*": [
"+base/run_loop.h",
- "+base/test/bind_test_util.h",
+ "+base/test/scoped_run_loop_timeout.h",
"+base/test/test_timeouts.h",
"+base/threading/thread.h",
"+media/audio/audio_sink_parameters.h",
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/OWNERS b/chromium/third_party/blink/renderer/modules/peerconnection/OWNERS
index e9c65646844..b2a8f2b2cb5 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/OWNERS
@@ -2,7 +2,6 @@ guidou@chromium.org
hbos@chromium.org
hta@chromium.org
orphis@chromium.org
-sergeyu@chromium.org
steveanton@chromium.org
tommi@chromium.org
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/OWNERS b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/OWNERS
new file mode 100644
index 00000000000..823362a809a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/OWNERS
@@ -0,0 +1 @@
+per-file p2p_quic_*=file://net/quic/OWNERS
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/dtls_transport_proxy.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/dtls_transport_proxy.cc
index 775a7babf0e..928bb4a6bdd 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/dtls_transport_proxy.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/dtls_transport_proxy.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/modules/peerconnection/adapters/dtls_transport_proxy.h"
#include "base/location.h"
+#include "base/memory/ptr_util.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
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 1430daaefef..5ba98d2bf75 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(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) 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/p2p_quic_crypto_config_factory_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_config_factory_impl.cc
index a42741b800f..a035286adc1 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_config_factory_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_config_factory_impl.cc
@@ -36,7 +36,7 @@ class InsecureProofVerifier : public quic::ProofVerifier {
const uint16_t port,
const std::string& server_config,
quic::QuicTransportVersion transport_version,
- quic::QuicStringPiece chlo_hash,
+ quiche::QuicheStringPiece chlo_hash,
const std::vector<std::string>& certs,
const std::string& cert_sct,
const std::string& signature,
@@ -78,7 +78,7 @@ class DummyProofSource : public quic::ProofSource {
const std::string& hostname,
const std::string& server_config,
quic::QuicTransportVersion transport_version,
- quic::QuicStringPiece chlo_hash,
+ quiche::QuicheStringPiece chlo_hash,
std::unique_ptr<Callback> callback) override {
quic::QuicCryptoProof proof;
proof.signature = "Dummy signature";
@@ -99,9 +99,9 @@ class DummyProofSource : public quic::ProofSource {
const quic::QuicSocketAddress& server_address,
const std::string& hostname,
uint16_t signature_algorithm,
- quic::QuicStringPiece in,
+ quiche::QuicheStringPiece in,
std::unique_ptr<SignatureCallback> callback) override {
- callback->Run(true, "Dummy signature");
+ callback->Run(true, "Dummy signature", nullptr);
}
};
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_stream_factory.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_stream_factory.h
index b0b9c97e4f1..c4516cf7c99 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_stream_factory.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_stream_factory.h
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_CRYPTO_STREAM_FACTORY_H_
#include "net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h"
-#include "net/third_party/quiche/src/quic/core/quic_crypto_server_stream.h"
+#include "net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.h"
namespace blink {
@@ -21,12 +21,12 @@ class P2PQuicCryptoStreamFactory {
quic::QuicCryptoClientConfig* crypto_config,
quic::QuicCryptoClientStream::ProofHandler* proof_handler) = 0;
- virtual std::unique_ptr<quic::QuicCryptoServerStream>
+ virtual std::unique_ptr<quic::QuicCryptoServerStreamBase>
CreateServerCryptoStream(
const quic::QuicCryptoServerConfig* crypto_config,
quic::QuicCompressedCertsCache* compressed_certs_cache,
quic::QuicSession* session,
- quic::QuicCryptoServerStream::Helper* helper) = 0;
+ quic::QuicCryptoServerStreamBase::Helper* helper) = 0;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_stream_factory_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_stream_factory_impl.cc
index 35bd6c14fcb..97320661f72 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_stream_factory_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_stream_factory_impl.cc
@@ -3,7 +3,7 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_stream_factory_impl.h"
-#include "net/third_party/quiche/src/quic/core/quic_crypto_server_stream.h"
+#include "net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.h"
namespace blink {
@@ -24,14 +24,14 @@ P2PQuicCryptoStreamFactoryImpl::CreateClientCryptoStream(
proof_handler);
}
-std::unique_ptr<quic::QuicCryptoServerStream>
+std::unique_ptr<quic::QuicCryptoServerStreamBase>
P2PQuicCryptoStreamFactoryImpl::CreateServerCryptoStream(
const quic::QuicCryptoServerConfig* crypto_config,
quic::QuicCompressedCertsCache* compressed_certs_cache,
quic::QuicSession* session,
- quic::QuicCryptoServerStream::Helper* helper) {
- return std::make_unique<quic::QuicCryptoServerStream>(
- crypto_config, compressed_certs_cache, session, helper);
+ quic::QuicCryptoServerStreamBase::Helper* helper) {
+ return quic::CreateCryptoServerStream(crypto_config, compressed_certs_cache,
+ session, helper);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_stream_factory_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_stream_factory_impl.h
index e4ee2aa352a..e5ef3fab82b 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_stream_factory_impl.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_stream_factory_impl.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_CRYPTO_STREAM_FACTORY_IMPL_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_CRYPTO_STREAM_FACTORY_IMPL_H_
-#include "net/third_party/quiche/src/quic/core/quic_crypto_server_stream.h"
+#include "net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_crypto_stream_factory.h"
@@ -24,11 +24,11 @@ class MODULES_EXPORT P2PQuicCryptoStreamFactoryImpl final
quic::QuicCryptoClientConfig* crypto_config,
quic::QuicCryptoClientStream::ProofHandler* proof_handler) override;
- std::unique_ptr<quic::QuicCryptoServerStream> CreateServerCryptoStream(
+ std::unique_ptr<quic::QuicCryptoServerStreamBase> CreateServerCryptoStream(
const quic::QuicCryptoServerConfig* crypto_config,
quic::QuicCompressedCertsCache* compressed_certs_cache,
quic::QuicSession* session,
- quic::QuicCryptoServerStream::Helper* helper) override;
+ quic::QuicCryptoServerStreamBase::Helper* helper) override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_impl.cc
index 3aa5e1453db..f5dccb3d0c0 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_impl.cc
@@ -131,8 +131,8 @@ void P2PQuicStreamImpl::WriteData(Vector<uint8_t> data, bool fin) {
DCHECK_GE(write_buffer_size_, data.size() + write_buffered_amount_);
write_buffered_amount_ += data.size();
QuicStream::WriteOrBufferData(
- quic::QuicStringPiece(reinterpret_cast<const char*>(data.data()),
- data.size()),
+ quiche::QuicheStringPiece(reinterpret_cast<const char*>(data.data()),
+ data.size()),
fin, nullptr);
}
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 9c0f149681a..1ffe37fb873 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
@@ -56,9 +56,10 @@ class P2PQuicStreamTest : public testing::Test {
}
template <wtf_size_t Size>
- static quic::QuicStringPiece StringPieceFromArray(
+ static quiche::QuicheStringPiece StringPieceFromArray(
const uint8_t (&array)[Size]) {
- return quic::QuicStringPiece(reinterpret_cast<const char*>(array), Size);
+ return quiche::QuicheStringPiece(reinterpret_cast<const char*>(array),
+ Size);
}
template <wtf_size_t Size>
@@ -82,8 +83,14 @@ class P2PQuicStreamTest : public testing::Test {
TEST_F(P2PQuicStreamTest, StreamSendsFinAndCanNoLongerWrite) {
InitializeStream();
- EXPECT_CALL(session_, WritevData(stream_, kStreamId, _, _, _))
- .WillOnce(Invoke(quic::test::MockQuicSession::ConsumeData));
+ EXPECT_CALL(session_,
+ WritevData(kStreamId, 0u, 0u, quic::StreamSendingState::FIN,
+ quic::NOT_RETRANSMISSION, _))
+ .WillOnce(InvokeWithoutArgs([this]() {
+ return session_.ConsumeData(stream_->id(), 0u, 0u,
+ quic::StreamSendingState::FIN,
+ quic::NOT_RETRANSMISSION, QuicheNullOpt);
+ }));
stream_->WriteData({}, /*fin=*/true);
@@ -116,8 +123,14 @@ TEST_F(P2PQuicStreamTest, StreamOnStreamFrameWithFin) {
// it has written the FIN bit, then the stream will close.
TEST_F(P2PQuicStreamTest, StreamClosedAfterSendingThenReceivingFin) {
InitializeStream();
- EXPECT_CALL(session_, WritevData(stream_, kStreamId, _, _, _))
- .WillOnce(Invoke(quic::test::MockQuicSession::ConsumeData));
+ EXPECT_CALL(session_,
+ WritevData(kStreamId, 0u, 0u, _, quic::NOT_RETRANSMISSION, _))
+ .WillOnce(InvokeWithoutArgs([this]() {
+ return session_.ConsumeData(stream_->id(), 0u, 0u,
+ quic::StreamSendingState::FIN,
+ quic::NOT_RETRANSMISSION, QuicheNullOpt);
+ }));
+
stream_->WriteData({}, /*fin=*/true);
EXPECT_FALSE(stream_->IsClosedForTesting());
@@ -137,8 +150,14 @@ TEST_F(P2PQuicStreamTest, StreamClosedAfterReceivingThenSendingFin) {
stream_->OnStreamFrame(fin_frame);
EXPECT_FALSE(stream_->IsClosedForTesting());
- EXPECT_CALL(session_, WritevData(stream_, kStreamId, _, _, _))
- .WillOnce(Invoke(quic::test::MockQuicSession::ConsumeData));
+ EXPECT_CALL(session_,
+ WritevData(kStreamId, 0u, 0u, quic::StreamSendingState::FIN,
+ quic::NOT_RETRANSMISSION, _))
+ .WillOnce(InvokeWithoutArgs([this]() {
+ return session_.ConsumeData(stream_->id(), 0u, 0u,
+ quic::StreamSendingState::FIN,
+ quic::NOT_RETRANSMISSION, QuicheNullOpt);
+ }));
stream_->WriteData({}, /*fin=*/true);
@@ -150,9 +169,27 @@ TEST_F(P2PQuicStreamTest, StreamClosedAfterReceivingThenSendingFin) {
TEST_F(P2PQuicStreamTest, StreamClosedAfterWritingAndReceivingDataWithFin) {
InitializeStream();
EXPECT_CALL(session_,
- WritevData(stream_, kStreamId,
- /*write_length=*/base::size(kSomeData), _, _))
- .WillOnce(Invoke(quic::test::MockQuicSession::ConsumeData));
+ WritevData(kStreamId,
+ /*write_length=*/base::size(kSomeData), _, _, _, _))
+ .WillOnce(Invoke(
+ [this](quic::QuicStreamId id, size_t write_length,
+ quic::QuicStreamOffset offset, quic::StreamSendingState state,
+ quic::TransmissionType type,
+ quiche::QuicheOptional<quic::EncryptionLevel> level) {
+ // WritevData does not pass the data. The data is saved to the
+ // stream, so we must grab it before it's consumed, in order to
+ // check that it's what was written.
+ std::string data_consumed_by_quic(write_length, 'a');
+ quic::QuicDataWriter writer(write_length, &data_consumed_by_quic[0],
+ quiche::NETWORK_BYTE_ORDER);
+ stream_->WriteStreamData(offset, write_length, &writer);
+
+ EXPECT_THAT(data_consumed_by_quic, ElementsAreArray(kSomeData));
+ EXPECT_EQ(quic::StreamSendingState::FIN, state);
+ return quic::QuicConsumedData(
+ write_length, state != quic::StreamSendingState::NO_FIN);
+ }));
+
stream_->WriteData(VectorFromArray(kSomeData),
/*fin=*/true);
EXPECT_FALSE(stream_->IsClosedForTesting());
@@ -200,24 +237,26 @@ TEST_F(P2PQuicStreamTest, StreamClosedAfterReceivingReset) {
TEST_F(P2PQuicStreamTest, StreamWritesData) {
InitializeStream();
EXPECT_CALL(session_,
- WritevData(stream_, kStreamId,
- /*write_length=*/base::size(kSomeData), _, _))
- .WillOnce(Invoke([](quic::QuicStream* stream, quic::QuicStreamId id,
- size_t write_length, quic::QuicStreamOffset offset,
- quic::StreamSendingState state) {
- // quic::QuicSession::WritevData does not pass the data. The data is
- // saved to the stream, so we must grab it before it's consumed, in
- // order to check that it's what was written.
- std::string data_consumed_by_quic(write_length, 'a');
- quic::QuicDataWriter writer(write_length, &data_consumed_by_quic[0],
- quiche::NETWORK_BYTE_ORDER);
- stream->WriteStreamData(offset, write_length, &writer);
-
- EXPECT_THAT(data_consumed_by_quic, ElementsAreArray(kSomeData));
- EXPECT_EQ(quic::StreamSendingState::NO_FIN, state);
- return quic::QuicConsumedData(
- write_length, state != quic::StreamSendingState::NO_FIN);
- }));
+ WritevData(kStreamId,
+ /*write_length=*/base::size(kSomeData), _, _, _, _))
+ .WillOnce(Invoke(
+ [this](quic::QuicStreamId id, size_t write_length,
+ quic::QuicStreamOffset offset, quic::StreamSendingState state,
+ quic::TransmissionType type,
+ quiche::QuicheOptional<quic::EncryptionLevel> level) {
+ // quic::QuicSession::WritevData does not pass the data. The data is
+ // saved to the stream, so we must grab it before it's consumed, in
+ // order to check that it's what was written.
+ std::string data_consumed_by_quic(write_length, 'a');
+ quic::QuicDataWriter writer(write_length, &data_consumed_by_quic[0],
+ quiche::NETWORK_BYTE_ORDER);
+ stream_->WriteStreamData(offset, write_length, &writer);
+
+ EXPECT_THAT(data_consumed_by_quic, ElementsAreArray(kSomeData));
+ EXPECT_EQ(quic::StreamSendingState::NO_FIN, state);
+ return quic::QuicConsumedData(
+ write_length, state != quic::StreamSendingState::NO_FIN);
+ }));
EXPECT_CALL(delegate_, OnWriteDataConsumed(base::size(kSomeData)));
stream_->WriteData(VectorFromArray(kSomeData), /*fin=*/false);
@@ -228,24 +267,26 @@ TEST_F(P2PQuicStreamTest, StreamWritesData) {
TEST_F(P2PQuicStreamTest, StreamWritesDataWithFin) {
InitializeStream();
EXPECT_CALL(session_,
- WritevData(stream_, kStreamId,
- /*write_length=*/base::size(kSomeData), _, _))
- .WillOnce(Invoke([](quic::QuicStream* stream, quic::QuicStreamId id,
- size_t write_length, quic::QuicStreamOffset offset,
- quic::StreamSendingState state) {
- // WritevData does not pass the data. The data is saved to the stream,
- // so we must grab it before it's consumed, in order to check that it's
- // what was written.
- std::string data_consumed_by_quic(write_length, 'a');
- quic::QuicDataWriter writer(write_length, &data_consumed_by_quic[0],
- quiche::NETWORK_BYTE_ORDER);
- stream->WriteStreamData(offset, write_length, &writer);
-
- EXPECT_THAT(data_consumed_by_quic, ElementsAreArray(kSomeData));
- EXPECT_EQ(quic::StreamSendingState::FIN, state);
- return quic::QuicConsumedData(
- write_length, state != quic::StreamSendingState::NO_FIN);
- }));
+ WritevData(kStreamId,
+ /*write_length=*/base::size(kSomeData), _, _, _, _))
+ .WillOnce(Invoke(
+ [this](quic::QuicStreamId id, size_t write_length,
+ quic::QuicStreamOffset offset, quic::StreamSendingState state,
+ quic::TransmissionType type,
+ quiche::QuicheOptional<quic::EncryptionLevel> level) {
+ // WritevData does not pass the data. The data is saved to the
+ // stream, so we must grab it before it's consumed, in order to
+ // check that it's what was written.
+ std::string data_consumed_by_quic(write_length, 'a');
+ quic::QuicDataWriter writer(write_length, &data_consumed_by_quic[0],
+ quiche::NETWORK_BYTE_ORDER);
+ stream_->WriteStreamData(offset, write_length, &writer);
+
+ EXPECT_THAT(data_consumed_by_quic, ElementsAreArray(kSomeData));
+ EXPECT_EQ(quic::StreamSendingState::FIN, state);
+ return quic::QuicConsumedData(
+ write_length, state != quic::StreamSendingState::NO_FIN);
+ }));
EXPECT_CALL(delegate_, OnWriteDataConsumed(base::size(kSomeData)));
stream_->WriteData(VectorFromArray(kSomeData), /*fin=*/true);
@@ -257,11 +298,13 @@ TEST_F(P2PQuicStreamTest, StreamWritesDataAndNotConsumedByQuic) {
InitializeStream();
EXPECT_CALL(delegate_, OnWriteDataConsumed(_)).Times(0);
EXPECT_CALL(session_,
- WritevData(stream_, kStreamId,
- /*write_length=*/base::size(kSomeData), _, _))
- .WillOnce(Invoke([](quic::QuicStream* stream, quic::QuicStreamId id,
- size_t write_length, quic::QuicStreamOffset offset,
- quic::StreamSendingState state) {
+ WritevData(kStreamId,
+ /*write_length=*/base::size(kSomeData), _, _, _, _))
+ .WillOnce(Invoke([](quic::QuicStreamId id, size_t write_length,
+ quic::QuicStreamOffset offset,
+ quic::StreamSendingState state,
+ quic::TransmissionType type,
+ quiche::QuicheOptional<quic::EncryptionLevel> level) {
// We mock that the QUIC library is not consuming the data, meaning it's
// being buffered. In this case, the OnWriteDataConsumed() callback
// should not be called.
@@ -282,18 +325,20 @@ TEST_F(P2PQuicStreamTest, StreamWritesDataAndPartiallyConsumedByQuic) {
size_t amount_consumed_by_quic = 2;
EXPECT_CALL(delegate_, OnWriteDataConsumed(amount_consumed_by_quic));
EXPECT_CALL(session_,
- WritevData(stream_, kStreamId,
- /*write_length=*/base::size(kSomeData), _, _))
- .WillOnce(Invoke([&amount_consumed_by_quic](
- quic::QuicStream* stream, quic::QuicStreamId id,
- size_t write_length, quic::QuicStreamOffset offset,
- quic::StreamSendingState state) {
- // We mock that the QUIC library is only consuming some of the data,
- // meaning the rest is being buffered.
- return quic::QuicConsumedData(
- /*bytes_consumed=*/amount_consumed_by_quic,
- quic::StreamSendingState::NO_FIN);
- }));
+ WritevData(kStreamId,
+ /*write_length=*/base::size(kSomeData), _, _, _, _))
+ .WillOnce(Invoke(
+ [&amount_consumed_by_quic](
+ quic::QuicStreamId id, size_t write_length,
+ quic::QuicStreamOffset offset, quic::StreamSendingState state,
+ quic::TransmissionType type,
+ quiche::QuicheOptional<quic::EncryptionLevel> level) {
+ // We mock that the QUIC library is only consuming some of the data,
+ // meaning the rest is being buffered.
+ return quic::QuicConsumedData(
+ /*bytes_consumed=*/amount_consumed_by_quic,
+ quic::StreamSendingState::NO_FIN);
+ }));
stream_->WriteData(VectorFromArray(kSomeData), /*fin=*/true);
}
@@ -464,11 +509,13 @@ TEST_F(P2PQuicStreamTest, UnsetDelegateDoesNotFireOnWriteDataConsumed) {
// Mock out the QuicSession to get the QuicStream::OnStreamDataConsumed
// callback to fire.
EXPECT_CALL(session_,
- WritevData(stream_, kStreamId,
- /*write_length=*/base::size(kSomeData), _, _))
- .WillOnce(Invoke([](quic::QuicStream* stream, quic::QuicStreamId id,
- size_t write_length, quic::QuicStreamOffset offset,
- quic::StreamSendingState state) {
+ WritevData(kStreamId,
+ /*write_length=*/base::size(kSomeData), _, _, _, _))
+ .WillOnce(Invoke([](quic::QuicStreamId id, size_t write_length,
+ quic::QuicStreamOffset offset,
+ quic::StreamSendingState state,
+ quic::TransmissionType type,
+ quiche::QuicheOptional<quic::EncryptionLevel> level) {
return quic::QuicConsumedData(
write_length, state != quic::StreamSendingState::NO_FIN);
}));
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 aa2ca141b4e..ddb46cf81be 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
@@ -171,7 +171,7 @@ std::unique_ptr<quic::QuicConnection> CreateQuicConnection(
// A dummy helper for a server crypto stream that accepts all client hellos
// and generates a random connection ID.
class DummyCryptoServerStreamHelper
- : public quic::QuicCryptoServerStream::Helper {
+ : public quic::QuicCryptoServerStreamBase::Helper {
public:
explicit DummyCryptoServerStreamHelper(quic::QuicRandom* random) {}
@@ -219,10 +219,8 @@ std::unique_ptr<P2PQuicTransportImpl> P2PQuicTransportImpl::Create(
// TODO(shampson): Consider setting larger initial flow control window sizes
// so that the default limit doesn't cause initial undersending.
quic::QuicConfig quic_config;
- quic_config.SetMaxIncomingBidirectionalStreamsToSend(
- kMaxIncomingDynamicStreams);
- quic_config.SetMaxIncomingUnidirectionalStreamsToSend(
- kMaxIncomingDynamicStreams);
+ quic_config.SetMaxBidirectionalStreamsToSend(kMaxIncomingDynamicStreams);
+ quic_config.SetMaxUnidirectionalStreamsToSend(kMaxIncomingDynamicStreams);
// The handshake network timeouts are configured to large values to prevent
// the QUIC connection from being closed on a slow connection. This can occur
// if signaling is slow and one side begins the handshake early.
@@ -529,32 +527,13 @@ void P2PQuicTransportImpl::InitializeCryptoStream() {
}
}
-void P2PQuicTransportImpl::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- QuicSession::OnCryptoHandshakeEvent(event);
- if (event == HANDSHAKE_CONFIRMED) {
- DCHECK(IsEncryptionEstablished());
- DCHECK(IsCryptoHandshakeConfirmed());
- P2PQuicNegotiatedParams negotiated_params;
- // The guaranteed largest message payload will not change throughout the
- // connection.
- uint16_t max_datagram_length =
- quic::QuicSession::GetGuaranteedLargestMessagePayload();
- if (max_datagram_length > 0) {
- // Datagrams are supported in this case.
- negotiated_params.set_max_datagram_length(max_datagram_length);
- }
- delegate_->OnConnected(negotiated_params);
- }
-}
-
void P2PQuicTransportImpl::SetDefaultEncryptionLevel(
quic::EncryptionLevel level) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
QuicSession::SetDefaultEncryptionLevel(level);
if (level == quic::ENCRYPTION_FORWARD_SECURE) {
DCHECK(IsEncryptionEstablished());
- DCHECK(IsCryptoHandshakeConfirmed());
+ DCHECK(OneRttKeysAvailable());
P2PQuicNegotiatedParams negotiated_params;
// The guaranteed largest message payload will not change throughout the
// connection.
@@ -568,6 +547,23 @@ void P2PQuicTransportImpl::SetDefaultEncryptionLevel(
}
}
+void P2PQuicTransportImpl::OnOneRttKeysAvailable() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ QuicSession::OnOneRttKeysAvailable();
+ DCHECK(IsEncryptionEstablished());
+ DCHECK(OneRttKeysAvailable());
+ P2PQuicNegotiatedParams negotiated_params;
+ // The guaranteed largest message payload will not change throughout the
+ // connection.
+ uint16_t max_datagram_length =
+ quic::QuicSession::GetGuaranteedLargestMessagePayload();
+ if (max_datagram_length > 0) {
+ // Datagrams are supported in this case.
+ negotiated_params.set_max_datagram_length(max_datagram_length);
+ }
+ delegate_->OnConnected(negotiated_params);
+}
+
void P2PQuicTransportImpl::OnCanWrite() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
while (!datagram_buffer_.empty()) {
@@ -583,7 +579,8 @@ void P2PQuicTransportImpl::OnCanWrite() {
QuicSession::OnCanWrite();
}
-void P2PQuicTransportImpl::OnMessageReceived(quic::QuicStringPiece message) {
+void P2PQuicTransportImpl::OnMessageReceived(
+ quiche::QuicheStringPiece message) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// This will never overflow because of the datagram size limit.
Vector<uint8_t> datagram(static_cast<wtf_size_t>(message.size()));
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.h
index 5d427476d13..376cecbacb6 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.h
@@ -12,7 +12,7 @@
#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h"
#include "net/third_party/quiche/src/quic/core/quic_connection.h"
#include "net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h"
-#include "net/third_party/quiche/src/quic/core/quic_crypto_server_stream.h"
+#include "net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.h"
#include "net/third_party/quiche/src/quic/core/quic_packet_writer.h"
#include "net/third_party/quiche/src/quic/core/quic_session.h"
#include "net/third_party/quiche/src/quic/tools/quic_simple_crypto_server_stream_helper.h"
@@ -100,7 +100,7 @@ class MODULES_EXPORT P2PQuicTransportImpl final
bool CanSendDatagram();
// quic::QuicSession override.
- void OnMessageReceived(quic::QuicStringPiece message) override;
+ void OnMessageReceived(quiche::QuicheStringPiece message) override;
void OnMessageLost(quic::QuicMessageId message_id) override;
void OnCanWrite() override;
@@ -139,8 +139,8 @@ class MODULES_EXPORT P2PQuicTransportImpl final
// quic::QuicSession.
P2PQuicStreamImpl* CreateOutgoingBidirectionalStream();
- void OnCryptoHandshakeEvent(CryptoHandshakeEvent event) override;
void SetDefaultEncryptionLevel(quic::EncryptionLevel level) override;
+ void OnOneRttKeysAvailable() override;
private:
// This is for testing connection failures and handshake failures.
@@ -180,7 +180,8 @@ class MODULES_EXPORT P2PQuicTransportImpl final
std::unique_ptr<quic::QuicCryptoClientConfig> crypto_client_config_;
// Used by server |crypto_stream_| to track most recently compressed certs.
std::unique_ptr<quic::QuicCompressedCertsCache> compressed_certs_cache_;
- std::unique_ptr<quic::QuicCryptoServerStream::Helper> server_stream_helper_;
+ std::unique_ptr<quic::QuicCryptoServerStreamBase::Helper>
+ server_stream_helper_;
// Owned by the P2PQuicTransportImpl. |helper_| is placed before
// |connection_| to ensure it outlives it.
std::unique_ptr<quic::QuicConnectionHelperInterface> helper_;
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 3935a8fe2e7..18d85df732e 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
@@ -9,13 +9,14 @@
#include "net/quic/quic_chromium_alarm_factory.h"
#include "net/quic/test_task_runner.h"
#include "net/test/gtest_util.h"
+#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
#include "net/third_party/quiche/src/quic/core/crypto/proof_verifier.h"
#include "net/third_party/quiche/src/quic/core/crypto/quic_compressed_certs_cache.h"
#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h"
+#include "net/third_party/quiche/src/quic/core/quic_circular_deque.h"
#include "net/third_party/quiche/src/quic/core/quic_server_id.h"
#include "net/third_party/quiche/src/quic/core/quic_session.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice_span.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
#include "third_party/blink/public/platform/web_vector.h"
@@ -241,7 +242,7 @@ class FakePacketTransport : public P2PQuicPacketTransport,
}
}
// If async, packets are queued here to send.
- quic::QuicDeque<std::string> packet_queue_;
+ quic::QuicCircularDeque<std::string> packet_queue_;
// Alarm used to send data asynchronously.
quic::QuicArenaScopedPtr<quic::QuicAlarm> alarm_;
// The P2PQuicTransportImpl, which sets itself as the delegate in its
@@ -334,10 +335,9 @@ class QuicPeerForTest {
rtc::scoped_refptr<rtc::RTCCertificate> CreateTestCertificate() {
rtc::KeyParams params;
- rtc::SSLIdentity* ssl_identity =
- rtc::SSLIdentity::Generate("dummy_certificate", params);
+
return rtc::RTCCertificate::Create(
- std::unique_ptr<rtc::SSLIdentity>(ssl_identity));
+ rtc::SSLIdentity::Create("dummy_certificate", params));
}
// Allows faking a failing handshake.
@@ -352,7 +352,7 @@ class FailingProofVerifierStub : public quic::ProofVerifier {
const uint16_t port,
const std::string& server_config,
quic::QuicTransportVersion transport_version,
- quic::QuicStringPiece chlo_hash,
+ quiche::QuicheStringPiece chlo_hash,
const std::vector<std::string>& certs,
const std::string& cert_sct,
const std::string& signature,
@@ -391,7 +391,7 @@ class ProofSourceStub : public quic::ProofSource {
const std::string& hostname,
const std::string& server_config,
quic::QuicTransportVersion transport_version,
- quic::QuicStringPiece chlo_hash,
+ quiche::QuicheStringPiece chlo_hash,
std::unique_ptr<Callback> callback) override {
quic::QuicCryptoProof proof;
proof.signature = "Test signature";
@@ -412,9 +412,9 @@ class ProofSourceStub : public quic::ProofSource {
const quic::QuicSocketAddress& server_address,
const std::string& hostname,
uint16_t signature_algorithm,
- quic::QuicStringPiece in,
+ quiche::QuicheStringPiece in,
std::unique_ptr<SignatureCallback> callback) override {
- callback->Run(true, "Test signature");
+ callback->Run(true, "Test signature", nullptr);
}
};
@@ -470,9 +470,9 @@ class ConnectedCryptoClientStream final : public quic::QuicCryptoClientStream {
quic::QuicTime::Delta::FromSeconds(2 * quic::kMaximumIdleTimeoutSecs),
quic::QuicTime::Delta::FromSeconds(quic::kMaximumIdleTimeoutSecs));
config.SetBytesForConnectionIdToSend(quic::PACKET_8BYTE_CONNECTION_ID);
- config.SetMaxIncomingBidirectionalStreamsToSend(
+ config.SetMaxBidirectionalStreamsToSend(
quic::kDefaultMaxStreamsPerConnection / 2);
- config.SetMaxIncomingUnidirectionalStreamsToSend(
+ config.SetMaxUnidirectionalStreamsToSend(
quic::kDefaultMaxStreamsPerConnection / 2);
quic::CryptoHandshakeMessage message;
config.ToHandshakeMessage(&message,
@@ -481,12 +481,14 @@ class ConnectedCryptoClientStream final : public quic::QuicCryptoClientStream {
session()->config()->ProcessPeerHello(message, quic::CLIENT,
&error_details);
session()->OnConfigNegotiated();
- if (session()->use_handshake_delegate()) {
- session()->SetDefaultEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
- session()->DiscardOldEncryptionKey(quic::ENCRYPTION_INITIAL);
+ if (session()->connection()->version().handshake_protocol ==
+ quic::PROTOCOL_TLS1_3) {
+ session()->OnOneRttKeysAvailable();
} else {
- session()->OnCryptoHandshakeEvent(quic::QuicSession::HANDSHAKE_CONFIRMED);
+ session()->SetDefaultEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
}
+ session()->DiscardOldEncryptionKey(quic::ENCRYPTION_INITIAL);
+ session()->NeuterHandshakeData();
return true;
}
@@ -496,7 +498,7 @@ class ConnectedCryptoClientStream final : public quic::QuicCryptoClientStream {
return encryption_established_;
}
- bool handshake_confirmed() const override { return handshake_confirmed_; }
+ bool one_rtt_keys_available() const override { return handshake_confirmed_; }
private:
bool encryption_established_ = false;
@@ -524,13 +526,13 @@ class ConnectedCryptoClientStreamFactory final
}
// Creates a real quic::QuiCryptoServerStream.
- std::unique_ptr<quic::QuicCryptoServerStream> CreateServerCryptoStream(
+ std::unique_ptr<quic::QuicCryptoServerStreamBase> CreateServerCryptoStream(
const quic::QuicCryptoServerConfig* crypto_config,
quic::QuicCompressedCertsCache* compressed_certs_cache,
quic::QuicSession* session,
- quic::QuicCryptoServerStream::Helper* helper) override {
- return std::make_unique<quic::QuicCryptoServerStream>(
- crypto_config, compressed_certs_cache, session, helper);
+ quic::QuicCryptoServerStreamBase::Helper* helper) override {
+ return quic::CreateCryptoServerStream(crypto_config, compressed_certs_cache,
+ session, helper);
}
};
@@ -708,8 +710,8 @@ class P2PQuicTransportTest : public testing::Test {
void ExpectConnectionNotEstablished() {
EXPECT_FALSE(client_peer_->quic_transport()->IsEncryptionEstablished());
- EXPECT_FALSE(client_peer_->quic_transport()->IsCryptoHandshakeConfirmed());
- EXPECT_FALSE(server_peer_->quic_transport()->IsCryptoHandshakeConfirmed());
+ EXPECT_FALSE(client_peer_->quic_transport()->OneRttKeysAvailable());
+ EXPECT_FALSE(server_peer_->quic_transport()->OneRttKeysAvailable());
EXPECT_FALSE(server_peer_->quic_transport()->IsEncryptionEstablished());
}
@@ -785,8 +787,8 @@ TEST_F(P2PQuicTransportTest, HandshakeConnectsPeersWithPreSharedKeys) {
run_loop.RunUntilCallbacksFired();
EXPECT_TRUE(client_peer()->quic_transport()->IsEncryptionEstablished());
- EXPECT_TRUE(client_peer()->quic_transport()->IsCryptoHandshakeConfirmed());
- EXPECT_TRUE(server_peer()->quic_transport()->IsCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_peer()->quic_transport()->OneRttKeysAvailable());
+ EXPECT_TRUE(server_peer()->quic_transport()->OneRttKeysAvailable());
EXPECT_TRUE(server_peer()->quic_transport()->IsEncryptionEstablished());
}
@@ -823,8 +825,8 @@ TEST_F(P2PQuicTransportTest, HandshakeConnectsPeersWithRemoteCertificates) {
run_loop.RunUntilCallbacksFired();
EXPECT_TRUE(client_peer()->quic_transport()->IsEncryptionEstablished());
- EXPECT_TRUE(client_peer()->quic_transport()->IsCryptoHandshakeConfirmed());
- EXPECT_TRUE(server_peer()->quic_transport()->IsCryptoHandshakeConfirmed());
+ EXPECT_TRUE(client_peer()->quic_transport()->OneRttKeysAvailable());
+ EXPECT_TRUE(server_peer()->quic_transport()->OneRttKeysAvailable());
EXPECT_TRUE(server_peer()->quic_transport()->IsEncryptionEstablished());
}
@@ -1080,7 +1082,8 @@ TEST_F(P2PQuicTransportTest, ClientClosingConnectionClosesStreams) {
// Tests that when the server transport calls Stop() it closes its incoming
// stream, which, in turn closes the outgoing stream on the client quic
// transport.
-TEST_F(P2PQuicTransportTest, ServerClosingConnectionClosesStreams) {
+// TODO(crbug.com/1056976): re-enable this test when crbug.com/1056976 is fixed.
+TEST_F(P2PQuicTransportTest, DISABLED_ServerClosingConnectionClosesStreams) {
Initialize();
Connect();
SetupConnectedStreams();
@@ -1400,7 +1403,7 @@ class P2PQuicTransportMockConnectionTest : public testing::Test {
TEST_F(P2PQuicTransportMockConnectionTest, OnDatagramReceived) {
EXPECT_TRUE(transport()->CanSendDatagram());
EXPECT_CALL(*delegate(), OnDatagramReceived(ElementsAreArray(kMessage)));
- transport()->OnMessageReceived(quic::QuicStringPiece(
+ transport()->OnMessageReceived(quiche::QuicheStringPiece(
reinterpret_cast<const char*>(kMessage), sizeof(kMessage)));
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/sctp_transport_proxy.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/sctp_transport_proxy.cc
index f602a2df072..8b4cd8282c8 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/sctp_transport_proxy.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/sctp_transport_proxy.cc
@@ -8,6 +8,7 @@
#include <utility>
#include "base/location.h"
+#include "base/memory/ptr_util.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
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 30d657b0f98..da39b23cecf 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(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) 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 54cb7d13bff..0d6c40f0b42 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
@@ -165,8 +165,9 @@ struct CrossThreadCopier<blink::MediaStreamVideoTrack>
};
template <>
-struct CrossThreadCopier<webrtc::VideoTrackInterface>
- : public CrossThreadCopierPassThrough<webrtc::VideoTrackInterface> {
+struct CrossThreadCopier<rtc::scoped_refptr<webrtc::VideoTrackInterface>>
+ : public CrossThreadCopierPassThrough<
+ rtc::scoped_refptr<webrtc::VideoTrackInterface>> {
STATIC_ONLY(CrossThreadCopier);
};
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 f711b3b5486..d158076281e 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
@@ -74,12 +74,13 @@ blink::WebMediaStreamTrack FakeRTCRtpSenderImpl::Track() const {
: blink::WebMediaStreamTrack(); // null
}
-blink::WebVector<blink::WebString> FakeRTCRtpSenderImpl::StreamIds() const {
- blink::WebVector<blink::WebString> web_stream_ids(stream_ids_.size());
- for (size_t i = 0; i < stream_ids_.size(); ++i) {
- web_stream_ids[i] = blink::WebString::FromUTF8(stream_ids_[i]);
+Vector<String> FakeRTCRtpSenderImpl::StreamIds() const {
+ Vector<String> wtf_stream_ids(
+ static_cast<WTF::wtf_size_t>(stream_ids_.size()));
+ for (wtf_size_t i = 0; i < stream_ids_.size(); ++i) {
+ wtf_stream_ids[i] = String::FromUTF8(stream_ids_[i]);
}
- return web_stream_ids;
+ return wtf_stream_ids;
}
void FakeRTCRtpSenderImpl::ReplaceTrack(blink::WebMediaStreamTrack with_track,
@@ -100,20 +101,18 @@ std::unique_ptr<webrtc::RtpParameters> FakeRTCRtpSenderImpl::GetParameters()
}
void FakeRTCRtpSenderImpl::SetParameters(
- blink::WebVector<webrtc::RtpEncodingParameters>,
- webrtc::DegradationPreference,
+ Vector<webrtc::RtpEncodingParameters>,
+ absl::optional<webrtc::DegradationPreference>,
blink::RTCVoidRequest*) {
NOTIMPLEMENTED();
}
-void FakeRTCRtpSenderImpl::GetStats(
- blink::WebRTCStatsReportCallback,
- const blink::WebVector<webrtc::NonStandardGroupId>&) {
+void FakeRTCRtpSenderImpl::GetStats(RTCStatsReportCallback,
+ const Vector<webrtc::NonStandardGroupId>&) {
NOTIMPLEMENTED();
}
-void FakeRTCRtpSenderImpl::SetStreams(
- const blink::WebVector<blink::WebString>& stream_ids) {
+void FakeRTCRtpSenderImpl::SetStreams(const Vector<String>& stream_ids) {
NOTIMPLEMENTED();
}
@@ -160,23 +159,22 @@ const blink::WebMediaStreamTrack& FakeRTCRtpReceiverImpl::Track() const {
return track_;
}
-blink::WebVector<blink::WebString> FakeRTCRtpReceiverImpl::StreamIds() const {
- blink::WebVector<blink::WebString> web_stream_ids(stream_ids_.size());
+Vector<String> FakeRTCRtpReceiverImpl::StreamIds() const {
+ Vector<String> wtf_stream_ids(stream_ids_.size());
for (size_t i = 0; i < stream_ids_.size(); ++i) {
- web_stream_ids[i] = blink::WebString::FromUTF8(stream_ids_[i]);
+ wtf_stream_ids[i] = String::FromUTF8(stream_ids_[i]);
}
- return web_stream_ids;
+ return wtf_stream_ids;
}
-blink::WebVector<std::unique_ptr<RTCRtpSource>>
-FakeRTCRtpReceiverImpl::GetSources() {
+Vector<std::unique_ptr<RTCRtpSource>> FakeRTCRtpReceiverImpl::GetSources() {
NOTIMPLEMENTED();
return {};
}
void FakeRTCRtpReceiverImpl::GetStats(
- blink::WebRTCStatsReportCallback,
- const blink::WebVector<webrtc::NonStandardGroupId>&) {
+ RTCStatsReportCallback,
+ const Vector<webrtc::NonStandardGroupId>&) {
NOTIMPLEMENTED();
}
@@ -217,8 +215,8 @@ uintptr_t FakeRTCRtpTransceiverImpl::Id() const {
return 0u;
}
-blink::WebString FakeRTCRtpTransceiverImpl::Mid() const {
- return mid_ ? blink::WebString::FromUTF8(*mid_) : blink::WebString();
+String FakeRTCRtpTransceiverImpl::Mid() const {
+ return mid_ ? String::FromUTF8(*mid_) : String();
}
std::unique_ptr<blink::RTCRtpSenderPlatform> FakeRTCRtpTransceiverImpl::Sender()
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 da817042948..e8bac93497a 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
@@ -9,9 +9,9 @@
#include <string>
#include <vector>
-#include "third_party/blink/public/platform/web_media_constraints.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_constraints.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.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"
@@ -41,18 +41,17 @@ class FakeRTCRtpSenderImpl : public blink::RTCRtpSenderPlatform {
rtc::scoped_refptr<webrtc::DtlsTransportInterface> DtlsTransport() override;
webrtc::DtlsTransportInformation DtlsTransportInformation() override;
blink::WebMediaStreamTrack Track() const override;
- blink::WebVector<blink::WebString> StreamIds() const override;
+ Vector<String> StreamIds() const override;
void ReplaceTrack(blink::WebMediaStreamTrack with_track,
blink::RTCVoidRequest* request) override;
std::unique_ptr<blink::RtcDtmfSenderHandler> GetDtmfSender() const override;
std::unique_ptr<webrtc::RtpParameters> GetParameters() const override;
- void SetParameters(blink::WebVector<webrtc::RtpEncodingParameters>,
- webrtc::DegradationPreference,
+ void SetParameters(Vector<webrtc::RtpEncodingParameters>,
+ absl::optional<webrtc::DegradationPreference>,
blink::RTCVoidRequest*) override;
- void GetStats(blink::WebRTCStatsReportCallback,
- const blink::WebVector<webrtc::NonStandardGroupId>&) override;
- void SetStreams(
- const blink::WebVector<blink::WebString>& stream_ids) override;
+ void GetStats(RTCStatsReportCallback,
+ const Vector<webrtc::NonStandardGroupId>&) override;
+ void SetStreams(const Vector<String>& stream_ids) override;
private:
base::Optional<std::string> track_id_;
@@ -75,10 +74,10 @@ class FakeRTCRtpReceiverImpl : public RTCRtpReceiverPlatform {
rtc::scoped_refptr<webrtc::DtlsTransportInterface> DtlsTransport() override;
webrtc::DtlsTransportInformation DtlsTransportInformation() override;
const blink::WebMediaStreamTrack& Track() const override;
- blink::WebVector<blink::WebString> StreamIds() const override;
- blink::WebVector<std::unique_ptr<RTCRtpSource>> GetSources() override;
- void GetStats(blink::WebRTCStatsReportCallback,
- const blink::WebVector<webrtc::NonStandardGroupId>&) override;
+ Vector<String> StreamIds() const override;
+ Vector<std::unique_ptr<RTCRtpSource>> GetSources() override;
+ void GetStats(RTCStatsReportCallback,
+ const Vector<webrtc::NonStandardGroupId>&) override;
std::unique_ptr<webrtc::RtpParameters> GetParameters() const override;
void SetJitterBufferMinimumDelay(
base::Optional<double> delay_seconds) override;
@@ -102,7 +101,7 @@ class FakeRTCRtpTransceiverImpl : public RTCRtpTransceiverPlatform {
RTCRtpTransceiverPlatformImplementationType ImplementationType()
const override;
uintptr_t Id() const override;
- blink::WebString Mid() const override;
+ String Mid() const override;
std::unique_ptr<blink::RTCRtpSenderPlatform> Sender() const override;
std::unique_ptr<RTCRtpReceiverPlatform> Receiver() const override;
bool Stopped() const override;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/idls.gni b/chromium/third_party/blink/renderer/modules/peerconnection/idls.gni
new file mode 100644
index 00000000000..006aca8d56f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/idls.gni
@@ -0,0 +1,81 @@
+# 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 = [
+ "rtc_certificate.idl",
+ "rtc_data_channel.idl",
+ "rtc_data_channel_event.idl",
+ "rtc_dtls_transport.idl",
+ "rtc_dtmf_sender.idl",
+ "rtc_dtmf_tone_change_event.idl",
+ "rtc_encoded_video_frame.idl",
+ "rtc_encoded_audio_frame.idl",
+ "rtc_error.idl",
+ "rtc_error_event.idl",
+ "rtc_ice_candidate.idl",
+ "rtc_ice_transport.idl",
+ "rtc_legacy_stats_report.idl",
+ "rtc_peer_connection.idl",
+ "rtc_peer_connection_ice_error_event.idl",
+ "rtc_peer_connection_ice_event.idl",
+ "rtc_quic_stream.idl",
+ "rtc_quic_stream_event.idl",
+ "rtc_quic_transport.idl",
+ "rtc_rtp_receiver.idl",
+ "rtc_rtp_sender.idl",
+ "rtc_rtp_transceiver.idl",
+ "rtc_sctp_transport.idl",
+ "rtc_session_description.idl",
+ "rtc_stats_report.idl",
+ "rtc_stats_response.idl",
+ "rtc_track_event.idl",
+]
+
+modules_dictionary_idl_files = [
+ "rtc_answer_options.idl",
+ "rtc_configuration.idl",
+ "rtc_data_channel_event_init.idl",
+ "rtc_data_channel_init.idl",
+ "rtc_dtls_fingerprint.idl",
+ "rtc_dtmf_tone_change_event_init.idl",
+ "rtc_error_event_init.idl",
+ "rtc_error_init.idl",
+ "rtc_ice_candidate_init.idl",
+ "rtc_ice_candidate_pair.idl",
+ "rtc_ice_gather_options.idl",
+ "rtc_ice_parameters.idl",
+ "rtc_ice_server.idl",
+ "rtc_insertable_streams.idl",
+ "rtc_offer_answer_options.idl",
+ "rtc_offer_options.idl",
+ "rtc_peer_connection_ice_error_event_init.idl",
+ "rtc_peer_connection_ice_event_init.idl",
+ "rtc_quic_parameters.idl",
+ "rtc_quic_stream_event_init.idl",
+ "rtc_quic_stream_read_result.idl",
+ "rtc_quic_stream_write_parameters.idl",
+ "rtc_quic_transport_stats.idl",
+ "rtc_rtcp_parameters.idl",
+ "rtc_rtp_capabilities.idl",
+ "rtc_rtp_codec_capability.idl",
+ "rtc_rtp_codec_parameters.idl",
+ "rtc_rtp_coding_parameters.idl",
+ "rtc_rtp_contributing_source.idl",
+ "rtc_rtp_decoding_parameters.idl",
+ "rtc_rtp_encoding_parameters.idl",
+ "rtc_rtp_header_extension_capability.idl",
+ "rtc_rtp_header_extension_parameters.idl",
+ "rtc_rtp_parameters.idl",
+ "rtc_rtp_receive_parameters.idl",
+ "rtc_rtp_send_parameters.idl",
+ "rtc_rtp_synchronization_source.idl",
+ "rtc_rtp_transceiver_init.idl",
+ "rtc_session_description_init.idl",
+ "rtc_track_event_init.idl",
+]
+
+modules_testing_dependency_idl_files = [
+ "testing/internals_rtc_certificate.idl",
+ "testing/internals_rtc_peer_connection.idl",
+]
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 88188c7ea23..f0e12d83d5a 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
@@ -7,6 +7,7 @@
#include <stdint.h>
#include <utility>
+#include "base/bind_helpers.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/trace_event/trace_event.h"
@@ -24,7 +25,8 @@
#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
#include "third_party/webrtc/api/video/i420_buffer.h"
#include "third_party/webrtc/api/video/recordable_encoded_frame.h"
-#include "third_party/webrtc/rtc_base/time_utils.h" // for TimeMicros
+#include "third_party/webrtc/rtc_base/time_utils.h"
+#include "third_party/webrtc/system_wrappers/include/clock.h"
namespace WTF {
@@ -118,7 +120,8 @@ class MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate
// VideoSinkInterface<webrtc::RecordableEncodedFrame>
void OnFrame(const webrtc::RecordableEncodedFrame& frame) override;
- void DoRenderFrameOnIOThread(scoped_refptr<media::VideoFrame> video_frame);
+ void DoRenderFrameOnIOThread(scoped_refptr<media::VideoFrame> video_frame,
+ base::TimeTicks estimated_capture_time);
private:
void OnEncodedVideoFrameOnIO(scoped_refptr<EncodedVideoFrame> frame,
@@ -143,6 +146,12 @@ class MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate
// WebRTC Chromium timestamp diff
const base::TimeDelta time_diff_encoded_;
+
+ // WebRTC real time clock, needed to determine NTP offset.
+ webrtc::Clock* clock_;
+
+ // Offset between NTP clock and WebRTC clock.
+ const int64_t ntp_offset_;
};
MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::
@@ -161,15 +170,13 @@ MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::
base::TimeDelta::FromMicroseconds(rtc::TimeMicros())),
start_timestamp_encoded_(media::kNoTimestamp),
time_diff_encoded_(base::TimeTicks::Now() - base::TimeTicks() -
- base::TimeDelta::FromMicroseconds(rtc::TimeMicros())) {
-}
+ base::TimeDelta::FromMicroseconds(rtc::TimeMicros())),
+ clock_(webrtc::Clock::GetRealTimeClock()),
+ ntp_offset_(clock_->TimeInMilliseconds() -
+ clock_->CurrentNtpInMilliseconds()) {}
MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::
- ~RemoteVideoSourceDelegate() {}
-
-namespace {
-void DoNothing(const scoped_refptr<rtc::RefCountInterface>& ref) {}
-} // namespace
+ ~RemoteVideoSourceDelegate() = default;
void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame(
const webrtc::VideoFrame& incoming_frame) {
@@ -260,8 +267,10 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame(
// The bind ensures that we keep a reference to the underlying buffer.
if (buffer->type() != webrtc::VideoFrameBuffer::Type::kNative) {
- video_frame->AddDestructionObserver(
- ConvertToBaseOnceCallback(CrossThreadBindOnce(&DoNothing, buffer)));
+ video_frame->AddDestructionObserver(ConvertToBaseOnceCallback(
+ CrossThreadBindOnce(base::DoNothing::Once<
+ const scoped_refptr<rtc::RefCountInterface>&>(),
+ buffer)));
}
// Rotation may be explicitly set sometimes.
@@ -286,22 +295,65 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame(
video_frame->metadata()->SetTimeTicks(
media::VideoFrameMetadata::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()));
+ if (incoming_frame.processing_time()) {
+ video_frame->metadata()->SetTimeDelta(
+ media::VideoFrameMetadata::PROCESSING_TIME,
+ base::TimeDelta::FromMicroseconds(
+ incoming_frame.processing_time()->Elapsed().us()));
+ }
+
+ // Set capture time to the NTP time, which is the estimated capture time
+ // converted to the local clock.
+ if (incoming_frame.ntp_time_ms() > 0) {
+ const base::TimeTicks capture_time =
+ base::TimeTicks() +
+ base::TimeDelta::FromMilliseconds(incoming_frame.ntp_time_ms() +
+ ntp_offset_) +
+ time_diff_;
+ video_frame->metadata()->SetTimeTicks(
+ media::VideoFrameMetadata::CAPTURE_BEGIN_TIME, capture_time);
+ }
+
+ // Set receive time to arrival of last packet.
+ if (!incoming_frame.packet_infos().empty()) {
+ int64_t last_packet_arrival_ms =
+ std::max_element(
+ incoming_frame.packet_infos().cbegin(),
+ incoming_frame.packet_infos().cend(),
+ [](const webrtc::RtpPacketInfo& a, const webrtc::RtpPacketInfo& b) {
+ return a.receive_time_ms() < b.receive_time_ms();
+ })
+ ->receive_time_ms();
+ 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);
+ }
+
+ // Use our computed render time as estimated capture time. If timestamp_us()
+ // (which is actually the suggested render time) is set by WebRTC, it's based
+ // on the RTP timestamps in the frame's packets, so congruent with the
+ // received frame capture timestamps. If set by us, it's as congruent as we
+ // can get with the timestamp sequence of frames we received.
PostCrossThreadTask(
*io_task_runner_, FROM_HERE,
CrossThreadBindOnce(&RemoteVideoSourceDelegate::DoRenderFrameOnIOThread,
- WrapRefCounted(this), video_frame));
+ WrapRefCounted(this), video_frame, render_time));
}
void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::
- DoRenderFrameOnIOThread(scoped_refptr<media::VideoFrame> video_frame) {
+ DoRenderFrameOnIOThread(scoped_refptr<media::VideoFrame> video_frame,
+ base::TimeTicks estimated_capture_time) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
TRACE_EVENT0("webrtc", "RemoteVideoSourceDelegate::DoRenderFrameOnIOThread");
- // TODO(hclam): Give the estimated capture time.
- frame_callback_.Run(std::move(video_frame), base::TimeTicks());
+ frame_callback_.Run(std::move(video_frame), estimated_capture_time);
}
void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame(
@@ -317,6 +369,11 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame(
? base::TimeTicks() + incoming_timestamp
: base::TimeTicks() + incoming_timestamp + time_diff_encoded_;
+ // Use our computed render time as estimated capture time. If render_time()
+ // is set by WebRTC, it's based on the RTP timestamps in the frame's packets,
+ // so congruent with the received frame capture timestamps. If set by us, it's
+ // as congruent as we can get with the timestamp sequence of frames we
+ // received.
PostCrossThreadTask(
*io_task_runner_, FROM_HERE,
CrossThreadBindOnce(&RemoteVideoSourceDelegate::OnEncodedVideoFrameOnIO,
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 8b9631417eb..f69debc185e 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
@@ -8,9 +8,11 @@
#include <utility>
#include "base/bind.h"
+#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
+#include "base/test/gmock_callback_support.h"
#include "media/base/video_frame.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/mediastream/media_stream.mojom-blink.h"
@@ -24,14 +26,35 @@
#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h"
#include "third_party/blink/renderer/platform/webrtc/track_observer.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
+#include "third_party/webrtc/api/rtp_packet_infos.h"
#include "third_party/webrtc/api/video/color_space.h"
#include "third_party/webrtc/api/video/i420_buffer.h"
+#include "third_party/webrtc/system_wrappers/include/clock.h"
#include "ui/gfx/color_space.h"
namespace blink {
-ACTION_P(RunClosure, closure) {
- closure.Run();
+namespace {
+// On Linux the clock in WebRTC and Chromium are more or less the same.
+// On Windows they are not the same and the accuracy of the measured time
+// difference is typically in the range [-1, 1] ms. However, for certain builds
+// such as ASAN it can be in the order of 10-20 ms. Since this is compensated
+// for both here and in MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate
+// we need to use the worst case difference between these two measurements.
+float kChromiumWebRtcMaxTimeDiffMs = 40.0f;
+
+using base::test::RunOnceClosure;
+using ::testing::_;
+using ::testing::Gt;
+using ::testing::SaveArg;
+using ::testing::Sequence;
+} // namespace
+
+webrtc::VideoFrame::Builder CreateBlackFrameBuilder() {
+ rtc::scoped_refptr<webrtc::I420Buffer> buffer =
+ webrtc::I420Buffer::Create(8, 8);
+ webrtc::I420Buffer::SetBlack(buffer);
+ return webrtc::VideoFrame::Builder().set_video_frame_buffer(buffer);
}
class MediaStreamRemoteVideoSourceUnderTest
@@ -55,7 +78,9 @@ class MediaStreamRemoteVideoSourceTest : public ::testing::Test {
blink::MockWebRtcVideoTrack::Create("test", webrtc_video_source_)),
remote_source_(nullptr),
number_of_successful_track_starts_(0),
- number_of_failed_track_starts_(0) {}
+ number_of_failed_track_starts_(0),
+ time_diff_(base::TimeTicks::Now() - base::TimeTicks() -
+ base::TimeDelta::FromMicroseconds(rtc::TimeMicros())) {}
void SetUp() override {
scoped_refptr<base::SingleThreadTaskRunner> main_thread =
@@ -139,6 +164,8 @@ class MediaStreamRemoteVideoSourceTest : public ::testing::Test {
return web_source_;
}
+ const base::TimeDelta& time_diff() const { return time_diff_; }
+
private:
void OnTrackStarted(blink::WebPlatformMediaStreamSource* source,
blink::mojom::MediaStreamRequestResult result,
@@ -159,6 +186,8 @@ class MediaStreamRemoteVideoSourceTest : public ::testing::Test {
blink::WebMediaStreamSource web_source_;
int number_of_successful_track_starts_;
int number_of_failed_track_starts_;
+ // WebRTC Chromium timestamp diff
+ const base::TimeDelta time_diff_;
};
TEST_F(MediaStreamRemoteVideoSourceTest, StartTrack) {
@@ -169,8 +198,8 @@ TEST_F(MediaStreamRemoteVideoSourceTest, StartTrack) {
track->AddSink(&sink, sink.GetDeliverFrameCB(), false);
base::RunLoop run_loop;
base::RepeatingClosure quit_closure = run_loop.QuitClosure();
- EXPECT_CALL(sink, OnVideoFrame())
- .WillOnce(RunClosure(std::move(quit_closure)));
+ EXPECT_CALL(sink, OnVideoFrame)
+ .WillOnce(RunOnceClosure(std::move(quit_closure)));
rtc::scoped_refptr<webrtc::I420Buffer> buffer(
new rtc::RefCountedObject<webrtc::I420Buffer>(320, 240));
@@ -235,8 +264,8 @@ TEST_F(MediaStreamRemoteVideoSourceTest, PreservesColorSpace) {
track->AddSink(&sink, sink.GetDeliverFrameCB(), false);
base::RunLoop run_loop;
- EXPECT_CALL(sink, OnVideoFrame())
- .WillOnce(RunClosure(run_loop.QuitClosure()));
+ EXPECT_CALL(sink, OnVideoFrame)
+ .WillOnce(RunOnceClosure(run_loop.QuitClosure()));
rtc::scoped_refptr<webrtc::I420Buffer> buffer(
new rtc::RefCountedObject<webrtc::I420Buffer>(320, 240));
webrtc::ColorSpace kColorSpace(webrtc::ColorSpace::PrimaryID::kSMPTE240M,
@@ -264,8 +293,174 @@ TEST_F(MediaStreamRemoteVideoSourceTest, PreservesColorSpace) {
track->RemoveSink(&sink);
}
+// These tests depend on measuring the difference between the internal WebRTC
+// clock and Chromium's clock. Due to this they are performance sensitive and
+// appear to be flaky for builds with ASAN enabled.
+#if defined(ADDRESS_SANITIZER)
+#define MAYBE_PopulateRequestAnimationFrameMetadata \
+ DISABLED_PopulateRequestAnimationFrameMetadata
+#define MAYBE_ReferenceTimeEqualsTimestampUs \
+ DISABLED_ReferenceTimeEqualsTimestampUs
+#else
+#define MAYBE_PopulateRequestAnimationFrameMetadata \
+ PopulateRequestAnimationFrameMetadata
+#define MAYBE_ReferenceTimeEqualsTimestampUs ReferenceTimeEqualsTimestampUs
+#endif
+TEST_F(MediaStreamRemoteVideoSourceTest,
+ MAYBE_PopulateRequestAnimationFrameMetadata) {
+ std::unique_ptr<blink::MediaStreamVideoTrack> track(CreateTrack());
+ blink::MockMediaStreamVideoSink sink;
+ track->AddSink(&sink, sink.GetDeliverFrameCB(), false);
+
+ base::RunLoop run_loop;
+ EXPECT_CALL(sink, OnVideoFrame)
+ .WillOnce(RunOnceClosure(run_loop.QuitClosure()));
+ rtc::scoped_refptr<webrtc::I420Buffer> buffer(
+ new rtc::RefCountedObject<webrtc::I420Buffer>(320, 240));
+
+ uint32_t kSsrc = 0;
+ const std::vector<uint32_t> kCsrcs;
+ uint32_t kRtpTimestamp = 123456;
+ float kProcessingTime = 0.014;
+
+ const webrtc::Timestamp kProcessingFinish =
+ webrtc::Timestamp::Millis(rtc::TimeMillis());
+ const webrtc::Timestamp kProcessingStart =
+ kProcessingFinish - webrtc::TimeDelta::Millis(1.0e3 * kProcessingTime);
+ const webrtc::Timestamp kCaptureTime =
+ kProcessingStart - webrtc::TimeDelta::Millis(20.0);
+ webrtc::Clock* clock = webrtc::Clock::GetRealTimeClock();
+ const int64_t ntp_offset =
+ clock->CurrentNtpInMilliseconds() - clock->TimeInMilliseconds();
+ const webrtc::Timestamp kCaptureTimeNtp =
+ kCaptureTime + webrtc::TimeDelta::Millis(ntp_offset);
+ // Expected capture time in Chromium epoch.
+ base::TimeTicks kExpectedCaptureTime =
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(kCaptureTime.ms()) +
+ time_diff();
+
+ webrtc::RtpPacketInfos::vector_type packet_infos;
+ for (int i = 0; i < 4; ++i) {
+ packet_infos.emplace_back(kSsrc, kCsrcs, kRtpTimestamp, absl::nullopt,
+ absl::nullopt, kProcessingStart.ms() - 100 + i);
+ }
+ // Expected receive time should be the same as the last arrival time, in
+ // Chromium epoch.
+ base::TimeTicks kExpectedReceiveTime =
+ base::TimeTicks() +
+ base::TimeDelta::FromMilliseconds(kProcessingStart.ms() - 100 + 3) +
+ time_diff();
+
+ webrtc::VideoFrame input_frame =
+ webrtc::VideoFrame::Builder()
+ .set_video_frame_buffer(buffer)
+ .set_timestamp_rtp(kRtpTimestamp)
+ .set_ntp_time_ms(kCaptureTimeNtp.ms())
+ .set_packet_infos(webrtc::RtpPacketInfos(packet_infos))
+ .build();
+
+ input_frame.set_processing_time({kProcessingStart, kProcessingFinish});
+ source()->SinkInterfaceForTesting()->OnFrame(input_frame);
+ run_loop.Run();
+
+ EXPECT_EQ(1, sink.number_of_frames());
+ 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);
+
+ track->RemoveSink(&sink);
+}
+
+TEST_F(MediaStreamRemoteVideoSourceTest, MAYBE_ReferenceTimeEqualsTimestampUs) {
+ std::unique_ptr<blink::MediaStreamVideoTrack> track(CreateTrack());
+ blink::MockMediaStreamVideoSink sink;
+ track->AddSink(&sink, sink.GetDeliverFrameCB(), false);
+
+ base::RunLoop run_loop;
+ EXPECT_CALL(sink, OnVideoFrame)
+ .WillOnce(RunOnceClosure(run_loop.QuitClosure()));
+ rtc::scoped_refptr<webrtc::I420Buffer> buffer(
+ new rtc::RefCountedObject<webrtc::I420Buffer>(320, 240));
+
+ int64_t kTimestampUs = rtc::TimeMicros();
+ webrtc::VideoFrame input_frame = webrtc::VideoFrame::Builder()
+ .set_video_frame_buffer(buffer)
+ .set_timestamp_us(kTimestampUs)
+ .build();
+
+ source()->SinkInterfaceForTesting()->OnFrame(input_frame);
+ run_loop.Run();
+
+ EXPECT_EQ(1, sink.number_of_frames());
+ 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 -
+ (base::TimeTicks() +
+ base::TimeDelta::FromMicroseconds(kTimestampUs) + time_diff()))
+ .InMillisecondsF(),
+ 0.0f, kChromiumWebRtcMaxTimeDiffMs);
+ track->RemoveSink(&sink);
+}
+
+// This is a special case that is used to signal "render immediately".
+TEST_F(MediaStreamRemoteVideoSourceTest, NoTimestampUsMeansNoReferenceTime) {
+ std::unique_ptr<blink::MediaStreamVideoTrack> track(CreateTrack());
+ blink::MockMediaStreamVideoSink sink;
+ track->AddSink(&sink, sink.GetDeliverFrameCB(), false);
+
+ base::RunLoop run_loop;
+ EXPECT_CALL(sink, OnVideoFrame)
+ .WillOnce(RunOnceClosure(run_loop.QuitClosure()));
+ rtc::scoped_refptr<webrtc::I420Buffer> buffer(
+ new rtc::RefCountedObject<webrtc::I420Buffer>(320, 240));
+
+ webrtc::VideoFrame input_frame =
+ webrtc::VideoFrame::Builder().set_video_frame_buffer(buffer).build();
+
+ source()->SinkInterfaceForTesting()->OnFrame(input_frame);
+ run_loop.Run();
+
+ EXPECT_EQ(1, sink.number_of_frames());
+ 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));
+
+ track->RemoveSink(&sink);
+}
+
class TestEncodedVideoFrame : public webrtc::RecordableEncodedFrame {
public:
+ explicit TestEncodedVideoFrame(webrtc::Timestamp timestamp)
+ : timestamp_(timestamp) {}
+
rtc::scoped_refptr<const webrtc::EncodedImageBufferInterface> encoded_buffer()
const override {
return nullptr;
@@ -280,9 +475,10 @@ class TestEncodedVideoFrame : public webrtc::RecordableEncodedFrame {
EncodedResolution resolution() const override {
return EncodedResolution{0, 0};
}
- webrtc::Timestamp render_time() const override {
- return webrtc::Timestamp::ms(0);
- }
+ webrtc::Timestamp render_time() const override { return timestamp_; }
+
+ private:
+ webrtc::Timestamp timestamp_;
};
TEST_F(MediaStreamRemoteVideoSourceTest, ForwardsEncodedVideoFrames) {
@@ -291,9 +487,114 @@ TEST_F(MediaStreamRemoteVideoSourceTest, ForwardsEncodedVideoFrames) {
track->AddEncodedSink(&sink, sink.GetDeliverEncodedVideoFrameCB());
base::RunLoop run_loop;
base::RepeatingClosure quit_closure = run_loop.QuitClosure();
- EXPECT_CALL(sink, OnEncodedVideoFrame())
- .WillOnce(RunClosure(std::move(quit_closure)));
- source()->EncodedSinkInterfaceForTesting()->OnFrame(TestEncodedVideoFrame());
+ EXPECT_CALL(sink, OnEncodedVideoFrame)
+ .WillOnce(RunOnceClosure(std::move(quit_closure)));
+ source()->EncodedSinkInterfaceForTesting()->OnFrame(
+ TestEncodedVideoFrame(webrtc::Timestamp::Millis(0)));
+ run_loop.Run();
+ track->RemoveEncodedSink(&sink);
+}
+
+TEST_F(MediaStreamRemoteVideoSourceTest,
+ ForwardsFramesWithIncreasingTimestampsWithNullSourceTimestamp) {
+ std::unique_ptr<blink::MediaStreamVideoTrack> track(CreateTrack());
+ blink::MockMediaStreamVideoSink sink;
+ track->AddSink(&sink, sink.GetDeliverFrameCB(), /*is_link_secure=*/false);
+ base::RunLoop run_loop;
+ base::RepeatingClosure quit_closure = run_loop.QuitClosure();
+
+ base::TimeTicks frame_timestamp1;
+ Sequence s;
+ EXPECT_CALL(sink, OnVideoFrame)
+ .InSequence(s)
+ .WillOnce(SaveArg<0>(&frame_timestamp1));
+ EXPECT_CALL(sink, OnVideoFrame(Gt(frame_timestamp1)))
+ .InSequence(s)
+ .WillOnce(RunOnceClosure(std::move(quit_closure)));
+ source()->SinkInterfaceForTesting()->OnFrame(
+ CreateBlackFrameBuilder().set_timestamp_ms(0).build());
+ // Spin until the time counter changes.
+ base::TimeTicks now = base::TimeTicks::Now();
+ while (base::TimeTicks::Now() == now) {
+ }
+ source()->SinkInterfaceForTesting()->OnFrame(
+ CreateBlackFrameBuilder().set_timestamp_ms(0).build());
+ run_loop.Run();
+ track->RemoveSink(&sink);
+}
+
+TEST_F(MediaStreamRemoteVideoSourceTest,
+ ForwardsFramesWithIncreasingTimestampsWithSourceTimestamp) {
+ std::unique_ptr<blink::MediaStreamVideoTrack> track(CreateTrack());
+ blink::MockMediaStreamVideoSink sink;
+ track->AddSink(&sink, sink.GetDeliverFrameCB(), /*is_link_secure=*/false);
+ base::RunLoop run_loop;
+ base::RepeatingClosure quit_closure = run_loop.QuitClosure();
+
+ base::TimeTicks frame_timestamp1;
+ Sequence s;
+ EXPECT_CALL(sink, OnVideoFrame)
+ .InSequence(s)
+ .WillOnce(SaveArg<0>(&frame_timestamp1));
+ EXPECT_CALL(sink, OnVideoFrame(Gt(frame_timestamp1)))
+ .InSequence(s)
+ .WillOnce(RunOnceClosure(std::move(quit_closure)));
+ source()->SinkInterfaceForTesting()->OnFrame(
+ CreateBlackFrameBuilder().set_timestamp_ms(4711).build());
+ source()->SinkInterfaceForTesting()->OnFrame(
+ CreateBlackFrameBuilder().set_timestamp_ms(4712).build());
+ run_loop.Run();
+ track->RemoveSink(&sink);
+}
+
+TEST_F(MediaStreamRemoteVideoSourceTest,
+ ForwardsEncodedFramesWithIncreasingTimestampsWithNullSourceTimestamp) {
+ std::unique_ptr<blink::MediaStreamVideoTrack> track(CreateTrack());
+ blink::MockMediaStreamVideoSink sink;
+ track->AddEncodedSink(&sink, sink.GetDeliverEncodedVideoFrameCB());
+ base::RunLoop run_loop;
+ base::RepeatingClosure quit_closure = run_loop.QuitClosure();
+
+ base::TimeTicks frame_timestamp1;
+ Sequence s;
+ EXPECT_CALL(sink, OnEncodedVideoFrame)
+ .InSequence(s)
+ .WillOnce(SaveArg<0>(&frame_timestamp1));
+ EXPECT_CALL(sink, OnEncodedVideoFrame(Gt(frame_timestamp1)))
+ .InSequence(s)
+ .WillOnce(RunOnceClosure(std::move(quit_closure)));
+ source()->EncodedSinkInterfaceForTesting()->OnFrame(
+ TestEncodedVideoFrame(webrtc::Timestamp::Millis(0)));
+ // Spin until the time counter changes.
+ base::TimeTicks now = base::TimeTicks::Now();
+ while (base::TimeTicks::Now() == now) {
+ }
+ source()->EncodedSinkInterfaceForTesting()->OnFrame(
+ TestEncodedVideoFrame(webrtc::Timestamp::Millis(0)));
+ run_loop.Run();
+ track->RemoveEncodedSink(&sink);
+}
+
+TEST_F(MediaStreamRemoteVideoSourceTest,
+ ForwardsEncodedFramesWithIncreasingTimestampsWithSourceTimestamp) {
+ std::unique_ptr<blink::MediaStreamVideoTrack> track(CreateTrack());
+ blink::MockMediaStreamVideoSink sink;
+ track->AddEncodedSink(&sink, sink.GetDeliverEncodedVideoFrameCB());
+ base::RunLoop run_loop;
+ base::RepeatingClosure quit_closure = run_loop.QuitClosure();
+
+ base::TimeTicks frame_timestamp1;
+ Sequence s;
+ EXPECT_CALL(sink, OnEncodedVideoFrame)
+ .InSequence(s)
+ .WillOnce(SaveArg<0>(&frame_timestamp1));
+ EXPECT_CALL(sink, OnEncodedVideoFrame(Gt(frame_timestamp1)))
+ .InSequence(s)
+ .WillOnce(RunOnceClosure(std::move(quit_closure)));
+ source()->EncodedSinkInterfaceForTesting()->OnFrame(
+ TestEncodedVideoFrame(webrtc::Timestamp::Millis(42)));
+ source()->EncodedSinkInterfaceForTesting()->OnFrame(
+ TestEncodedVideoFrame(webrtc::Timestamp::Millis(43)));
run_loop.Run();
track->RemoveEncodedSink(&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 fefac2656bf..6ba143f9911 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
@@ -7,7 +7,6 @@
#include <algorithm>
#include <memory>
-#include "base/bind.h"
#include "base/location.h"
#include "base/numerics/safe_conversions.h"
#include "base/single_thread_task_runner.h"
@@ -19,6 +18,8 @@
#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/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"
#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
#include "third_party/webrtc/api/video_track_source_proxy.h"
@@ -187,14 +188,15 @@ void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter::OnVideoFrameOnIO(
scoped_refptr<media::VideoFrame> frame,
base::TimeTicks estimated_capture_time) {
DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_);
- render_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&WebRtcVideoSourceAdapter::ResetRefreshTimerOnMainThread,
- this));
- libjingle_worker_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(&WebRtcVideoSourceAdapter::OnVideoFrameOnWorkerThread,
- this, std::move(frame)));
+ PostCrossThreadTask(
+ *render_task_runner_.get(), FROM_HERE,
+ CrossThreadBindOnce(
+ &WebRtcVideoSourceAdapter::ResetRefreshTimerOnMainThread,
+ WrapRefCounted(this)));
+ PostCrossThreadTask(
+ *libjingle_worker_thread_.get(), FROM_HERE,
+ CrossThreadBindOnce(&WebRtcVideoSourceAdapter::OnVideoFrameOnWorkerThread,
+ WrapRefCounted(this), std::move(frame)));
}
void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter::
@@ -259,8 +261,8 @@ MediaStreamVideoWebRtcSink::MediaStreamVideoWebRtcSink(
// PeerConnectionFactory::CreateVideoTrack doesn't do reference counting.
video_source_proxy_ =
factory->CreateVideoTrackSourceProxy(video_source_.get());
- video_track_ = factory->CreateLocalVideoTrack(track.Id().Utf8(),
- video_source_proxy_.get());
+ video_track_ =
+ factory->CreateLocalVideoTrack(track.Id(), video_source_proxy_.get());
video_track_->set_content_hint(
ContentHintTypeToWebRtcContentHint(track.ContentHint()));
@@ -269,13 +271,15 @@ MediaStreamVideoWebRtcSink::MediaStreamVideoWebRtcSink(
source_adapter_ = base::MakeRefCounted<WebRtcVideoSourceAdapter>(
factory->GetWebRtcWorkerTaskRunner(), video_source_.get(),
refresh_interval,
- base::Bind(&MediaStreamVideoWebRtcSink::RequestRefreshFrame,
- weak_factory_.GetWeakPtr()),
+ ConvertToBaseRepeatingCallback(CrossThreadBindRepeating(
+ &MediaStreamVideoWebRtcSink::RequestRefreshFrame,
+ weak_factory_.GetWeakPtr())),
std::move(task_runner));
MediaStreamVideoSink::ConnectToTrack(
track,
- base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnIO, source_adapter_),
+ ConvertToBaseRepeatingCallback(CrossThreadBindRepeating(
+ &WebRtcVideoSourceAdapter::OnVideoFrameOnIO, source_adapter_)),
false);
DVLOG(3) << "MediaStreamVideoWebRtcSink ctor() : is_screencast "
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.cc b/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.cc
index 87711d5bef9..2f3470c5887 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.cc
@@ -404,35 +404,34 @@ MockPeerConnectionDependencyFactory::CreateVideoTrackSourceProxy(
}
scoped_refptr<webrtc::MediaStreamInterface>
MockPeerConnectionDependencyFactory::CreateLocalMediaStream(
- const std::string& label) {
- return new rtc::RefCountedObject<MockMediaStream>(label);
+ const String& label) {
+ return new rtc::RefCountedObject<MockMediaStream>(label.Utf8());
}
scoped_refptr<webrtc::VideoTrackInterface>
MockPeerConnectionDependencyFactory::CreateLocalVideoTrack(
- const std::string& id,
+ const String& id,
webrtc::VideoTrackSourceInterface* source) {
scoped_refptr<webrtc::VideoTrackInterface> track(
- new rtc::RefCountedObject<MockWebRtcVideoTrack>(id, source));
+ new rtc::RefCountedObject<MockWebRtcVideoTrack>(id.Utf8(), source));
return track;
}
SessionDescriptionInterface*
MockPeerConnectionDependencyFactory::CreateSessionDescription(
- const std::string& type,
- const std::string& sdp,
+ const String& type,
+ const String& sdp,
webrtc::SdpParseError* error) {
if (fail_to_create_session_description_)
return nullptr;
- return new MockSessionDescription(type, sdp);
+ return new MockSessionDescription(type.Utf8(), sdp.Utf8());
}
webrtc::IceCandidateInterface*
-MockPeerConnectionDependencyFactory::CreateIceCandidate(
- const std::string& sdp_mid,
- int sdp_mline_index,
- const std::string& sdp) {
- return new MockIceCandidate(sdp_mid, sdp_mline_index, sdp);
+MockPeerConnectionDependencyFactory::CreateIceCandidate(const String& sdp_mid,
+ int sdp_mline_index,
+ const String& sdp) {
+ return new MockIceCandidate(sdp_mid.Utf8(), sdp_mline_index, sdp.Utf8());
}
scoped_refptr<base::SingleThreadTaskRunner>
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h b/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h
index 7175b114818..e93141e53d0 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h
@@ -172,18 +172,17 @@ class MockPeerConnectionDependencyFactory
scoped_refptr<webrtc::VideoTrackSourceInterface> CreateVideoTrackSourceProxy(
webrtc::VideoTrackSourceInterface* source) override;
scoped_refptr<webrtc::MediaStreamInterface> CreateLocalMediaStream(
- const std::string& label) override;
+ const String& label) override;
scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrack(
- const std::string& id,
+ const String& id,
webrtc::VideoTrackSourceInterface* source) override;
webrtc::SessionDescriptionInterface* CreateSessionDescription(
- const std::string& type,
- const std::string& sdp,
+ const String& type,
+ const String& sdp,
webrtc::SdpParseError* error) override;
- webrtc::IceCandidateInterface* CreateIceCandidate(
- const std::string& sdp_mid,
- int sdp_mline_index,
- const std::string& sdp) override;
+ webrtc::IceCandidateInterface* CreateIceCandidate(const String& sdp_mid,
+ int sdp_mline_index,
+ const String& sdp) override;
scoped_refptr<base::SingleThreadTaskRunner> GetWebRtcSignalingTaskRunner()
override;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.cc
index 177cc15aa9f..8136160f3ed 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.cc
@@ -248,7 +248,17 @@ FakeRtpTransceiver::FakeRtpTransceiver(
direction_(direction),
current_direction_(blink::ToAbslOptional(current_direction)) {}
-FakeRtpTransceiver::~FakeRtpTransceiver() {}
+FakeRtpTransceiver::~FakeRtpTransceiver() = default;
+
+void FakeRtpTransceiver::ReplaceWith(const FakeRtpTransceiver& other) {
+ media_type_ = other.media_type_;
+ sender_ = other.sender_;
+ receiver_ = other.receiver_;
+ mid_ = other.mid_;
+ stopped_ = other.stopped_;
+ direction_ = other.direction_;
+ current_direction_ = other.current_direction_;
+}
cricket::MediaType FakeRtpTransceiver::media_type() const {
return media_type_;
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 cf4a311b8e3..d9ec8fb3654 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
@@ -98,7 +98,7 @@ class FakeRtpTransceiver : public webrtc::RtpTransceiverInterface {
base::Optional<webrtc::RtpTransceiverDirection> current_direction);
~FakeRtpTransceiver() override;
- FakeRtpTransceiver& operator=(const FakeRtpTransceiver& other) = default;
+ void ReplaceWith(const FakeRtpTransceiver& other);
cricket::MediaType media_type() const override;
absl::optional<std::string> mid() const override;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler_client.cc b/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_client.cc
index aca953d8eb0..0cb5c627f2a 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler_client.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_client.cc
@@ -1,7 +1,7 @@
// Copyright (c) 2012 The Chromium 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/mock_web_rtc_peer_connection_handler_client.h"
+#include "third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_client.h"
#include "base/logging.h"
#include "third_party/blink/public/platform/web_media_stream.h"
@@ -12,41 +12,38 @@ using testing::_;
namespace blink {
-MockWebRTCPeerConnectionHandlerClient::MockWebRTCPeerConnectionHandlerClient() {
+MockRTCPeerConnectionHandlerClient::MockRTCPeerConnectionHandlerClient() {
ON_CALL(*this, DidGenerateICECandidate(_))
- .WillByDefault(
- testing::Invoke(this, &MockWebRTCPeerConnectionHandlerClient::
- didGenerateICECandidateWorker));
+ .WillByDefault(testing::Invoke(
+ this,
+ &MockRTCPeerConnectionHandlerClient::didGenerateICECandidateWorker));
ON_CALL(*this, DidAddReceiverPlanBForMock(_))
.WillByDefault(testing::Invoke(
- this, &MockWebRTCPeerConnectionHandlerClient::didAddReceiverWorker));
+ this, &MockRTCPeerConnectionHandlerClient::didAddReceiverWorker));
ON_CALL(*this, DidRemoveReceiverPlanBForMock(_))
.WillByDefault(testing::Invoke(
- this,
- &MockWebRTCPeerConnectionHandlerClient::didRemoveReceiverWorker));
+ this, &MockRTCPeerConnectionHandlerClient::didRemoveReceiverWorker));
}
-MockWebRTCPeerConnectionHandlerClient::
- ~MockWebRTCPeerConnectionHandlerClient() {}
+MockRTCPeerConnectionHandlerClient::~MockRTCPeerConnectionHandlerClient() {}
-void MockWebRTCPeerConnectionHandlerClient::didGenerateICECandidateWorker(
- scoped_refptr<RTCIceCandidatePlatform> candidate) {
+void MockRTCPeerConnectionHandlerClient::didGenerateICECandidateWorker(
+ RTCIceCandidatePlatform* candidate) {
candidate_sdp_ = candidate->Candidate().Utf8();
candidate_mline_index_ = candidate->SdpMLineIndex();
candidate_mid_ = candidate->SdpMid().Utf8();
}
-void MockWebRTCPeerConnectionHandlerClient::didAddReceiverWorker(
+void MockRTCPeerConnectionHandlerClient::didAddReceiverWorker(
std::unique_ptr<RTCRtpReceiverPlatform>* web_rtp_receiver) {
- blink::WebVector<blink::WebString> stream_ids =
- (*web_rtp_receiver)->StreamIds();
+ WebVector<String> stream_ids = (*web_rtp_receiver)->StreamIds();
DCHECK_EQ(1u, stream_ids.size());
remote_stream_id_ = stream_ids[0];
}
-void MockWebRTCPeerConnectionHandlerClient::didRemoveReceiverWorker(
+void MockRTCPeerConnectionHandlerClient::didRemoveReceiverWorker(
std::unique_ptr<RTCRtpReceiverPlatform>* web_rtp_receiver) {
- remote_stream_id_ = blink::WebString();
+ remote_stream_id_ = String();
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler_client.h b/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_client.h
index 34345c9a3a8..d88dc0201e7 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler_client.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_client.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_PEERCONNECTION_MOCK_WEB_RTC_PEER_CONNECTION_HANDLER_CLIENT_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_MOCK_WEB_RTC_PEER_CONNECTION_HANDLER_CLIENT_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_MOCK_RTC_PEER_CONNECTION_HANDLER_CLIENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_MOCK_RTC_PEER_CONNECTION_HANDLER_CLIENT_H_
#include <memory>
#include <string>
@@ -12,28 +12,30 @@
#include "base/macros.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/blink/public/platform/web_media_stream.h"
-#include "third_party/blink/public/platform/web_rtc_peer_connection_handler_client.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"
#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_receiver_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.h"
namespace blink {
-class MockWebRTCPeerConnectionHandlerClient
- : public blink::WebRTCPeerConnectionHandlerClient {
+class MockRTCPeerConnectionHandlerClient
+ : public RTCPeerConnectionHandlerClient {
public:
- MockWebRTCPeerConnectionHandlerClient();
- ~MockWebRTCPeerConnectionHandlerClient() override;
+ MockRTCPeerConnectionHandlerClient();
+ ~MockRTCPeerConnectionHandlerClient() override;
- // WebRTCPeerConnectionHandlerClient implementation.
+ // RTCPeerConnectionHandlerClient implementation.
MOCK_METHOD0(NegotiationNeeded, void());
MOCK_METHOD1(DidGenerateICECandidate,
- void(scoped_refptr<RTCIceCandidatePlatform> candidate));
- MOCK_METHOD4(DidFailICECandidate,
- void(const blink::WebString& host_candidate,
- const blink::WebString& url,
+ void(RTCIceCandidatePlatform* candidate));
+ MOCK_METHOD6(DidFailICECandidate,
+ void(const String& address,
+ base::Optional<uint16_t> port,
+ const String& host_candidate,
+ const String& url,
int error_code,
- const blink::WebString& error_text));
+ const String& error_text));
MOCK_METHOD1(DidChangeSignalingState,
void(webrtc::PeerConnectionInterface::SignalingState state));
MOCK_METHOD1(DidChangeIceGatheringState,
@@ -54,16 +56,15 @@ class MockWebRTCPeerConnectionHandlerClient
MOCK_METHOD1(DidModifySctpTransport,
void(blink::WebRTCSctpTransportSnapshot snapshot));
void DidModifyTransceivers(
- blink::WebVector<std::unique_ptr<RTCRtpTransceiverPlatform>>
- platform_transceivers,
- WebVector<uintptr_t> removed_transceivers,
+ Vector<std::unique_ptr<RTCRtpTransceiverPlatform>> platform_transceivers,
+ Vector<uintptr_t> removed_transceivers,
bool is_remote_description) override {
DidModifyTransceiversForMock(&platform_transceivers, is_remote_description);
}
MOCK_METHOD1(DidAddRemoteDataChannel,
void(scoped_refptr<webrtc::DataChannelInterface>));
MOCK_METHOD1(DidNoteInterestingUsage, void(int));
- MOCK_METHOD0(ReleasePeerConnectionHandler, void());
+ MOCK_METHOD0(UnregisterPeerConnectionHandler, void());
// Move-only arguments do not play nicely with MOCK, the workaround is to
// EXPECT_CALL with these instead.
@@ -71,13 +72,10 @@ class MockWebRTCPeerConnectionHandlerClient
void(std::unique_ptr<RTCRtpReceiverPlatform>*));
MOCK_METHOD1(DidRemoveReceiverPlanBForMock,
void(std::unique_ptr<RTCRtpReceiverPlatform>*));
- MOCK_METHOD2(
- DidModifyTransceiversForMock,
- void(blink::WebVector<std::unique_ptr<RTCRtpTransceiverPlatform>>*,
- bool));
+ MOCK_METHOD2(DidModifyTransceiversForMock,
+ void(Vector<std::unique_ptr<RTCRtpTransceiverPlatform>>*, bool));
- void didGenerateICECandidateWorker(
- scoped_refptr<RTCIceCandidatePlatform> candidate);
+ void didGenerateICECandidateWorker(RTCIceCandidatePlatform* candidate);
void didAddReceiverWorker(
std::unique_ptr<RTCRtpReceiverPlatform>* stream_web_rtp_receivers);
void didRemoveReceiverWorker(
@@ -88,17 +86,17 @@ class MockWebRTCPeerConnectionHandlerClient
return candidate_mline_index_;
}
const std::string& candidate_mid() const { return candidate_mid_; }
- const blink::WebString& remote_stream_id() const { return remote_stream_id_; }
+ const String& remote_stream_id() const { return remote_stream_id_; }
private:
- blink::WebString remote_stream_id_;
+ String remote_stream_id_;
std::string candidate_sdp_;
base::Optional<uint16_t> candidate_mline_index_;
std::string candidate_mid_;
- DISALLOW_COPY_AND_ASSIGN(MockWebRTCPeerConnectionHandlerClient);
+ DISALLOW_COPY_AND_ASSIGN(MockRTCPeerConnectionHandlerClient);
};
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_MOCK_WEB_RTC_PEER_CONNECTION_HANDLER_CLIENT_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_MOCK_RTC_PEER_CONNECTION_HANDLER_CLIENT_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler.cc b/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc
index beb72477043..a64d77d0ca7 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc
@@ -2,14 +2,13 @@
// 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/mock_web_rtc_peer_connection_handler.h"
+#include "third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.h"
#include <utility>
#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_rtc_stats.h"
#include "third_party/blink/public/platform/web_vector.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"
@@ -17,6 +16,7 @@
#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
#include "third_party/webrtc/api/stats/rtc_stats.h"
@@ -70,8 +70,8 @@ class DummyRTCRtpSenderPlatform : public RTCRtpSenderPlatform {
return dummy;
}
WebMediaStreamTrack Track() const override { return internal_->track(); }
- WebVector<WebString> StreamIds() const override {
- return std::vector<WebString>({WebString::FromUTF8("DummyStringId")});
+ Vector<String> StreamIds() const override {
+ return Vector<String>({String::FromUTF8("DummyStringId")});
}
void ReplaceTrack(WebMediaStreamTrack, RTCVoidRequest*) override {}
std::unique_ptr<RtcDtmfSenderHandler> GetDtmfSender() const override {
@@ -80,13 +80,12 @@ class DummyRTCRtpSenderPlatform : public RTCRtpSenderPlatform {
std::unique_ptr<webrtc::RtpParameters> GetParameters() const override {
return std::unique_ptr<webrtc::RtpParameters>();
}
- void SetParameters(blink::WebVector<webrtc::RtpEncodingParameters>,
- webrtc::DegradationPreference,
+ void SetParameters(Vector<webrtc::RtpEncodingParameters>,
+ absl::optional<webrtc::DegradationPreference>,
RTCVoidRequest*) override {}
- void GetStats(WebRTCStatsReportCallback,
- const WebVector<webrtc::NonStandardGroupId>&) override {}
- void SetStreams(
- const blink::WebVector<blink::WebString>& stream_ids) override {}
+ void GetStats(RTCStatsReportCallback,
+ const Vector<webrtc::NonStandardGroupId>&) override {}
+ void SetStreams(const Vector<String>& stream_ids) override {}
private:
scoped_refptr<DummyRtpSenderInternal> internal_;
@@ -133,14 +132,12 @@ class DummyRTCRtpReceiverPlatform : public RTCRtpReceiverPlatform {
return dummy;
}
const WebMediaStreamTrack& Track() const override { return track_; }
- WebVector<WebString> StreamIds() const override {
- return WebVector<WebString>();
+ Vector<String> StreamIds() const override { return Vector<String>(); }
+ Vector<std::unique_ptr<RTCRtpSource>> GetSources() override {
+ return Vector<std::unique_ptr<RTCRtpSource>>();
}
- WebVector<std::unique_ptr<RTCRtpSource>> GetSources() override {
- return WebVector<std::unique_ptr<RTCRtpSource>>();
- }
- void GetStats(WebRTCStatsReportCallback,
- const WebVector<webrtc::NonStandardGroupId>&) override {}
+ void GetStats(RTCStatsReportCallback,
+ const Vector<webrtc::NonStandardGroupId>&) override {}
std::unique_ptr<webrtc::RtpParameters> GetParameters() const override {
return nullptr;
}
@@ -198,7 +195,7 @@ uintptr_t DummyTransceiverInternal::last_id_ = 0;
} // namespace
-class MockWebRTCPeerConnectionHandler::DummyRTCRtpTransceiverPlatform
+class MockRTCPeerConnectionHandlerPlatform::DummyRTCRtpTransceiverPlatform
: public RTCRtpTransceiverPlatform {
public:
DummyRTCRtpTransceiverPlatform(WebMediaStreamSource::Type type,
@@ -216,7 +213,7 @@ class MockWebRTCPeerConnectionHandler::DummyRTCRtpTransceiverPlatform
return RTCRtpTransceiverPlatformImplementationType::kFullTransceiver;
}
uintptr_t Id() const override { return internal_->id(); }
- WebString Mid() const override { return WebString(); }
+ String Mid() const override { return String(); }
std::unique_ptr<RTCRtpSenderPlatform> Sender() const override {
return internal_->Sender();
}
@@ -243,101 +240,105 @@ class MockWebRTCPeerConnectionHandler::DummyRTCRtpTransceiverPlatform
scoped_refptr<DummyTransceiverInternal> internal_;
};
-MockWebRTCPeerConnectionHandler::MockWebRTCPeerConnectionHandler() = default;
+MockRTCPeerConnectionHandlerPlatform::MockRTCPeerConnectionHandlerPlatform() =
+ default;
-MockWebRTCPeerConnectionHandler::~MockWebRTCPeerConnectionHandler() = default;
+MockRTCPeerConnectionHandlerPlatform::~MockRTCPeerConnectionHandlerPlatform() =
+ default;
-bool MockWebRTCPeerConnectionHandler::Initialize(
+bool MockRTCPeerConnectionHandlerPlatform::Initialize(
const webrtc::PeerConnectionInterface::RTCConfiguration&,
- const WebMediaConstraints&) {
+ const MediaConstraints&,
+ WebLocalFrame*) {
return true;
}
-WebVector<std::unique_ptr<RTCRtpTransceiverPlatform>>
-MockWebRTCPeerConnectionHandler::CreateOffer(RTCSessionDescriptionRequest*,
- const WebMediaConstraints&) {
+Vector<std::unique_ptr<RTCRtpTransceiverPlatform>>
+MockRTCPeerConnectionHandlerPlatform::CreateOffer(RTCSessionDescriptionRequest*,
+ const MediaConstraints&) {
return {};
}
-WebVector<std::unique_ptr<RTCRtpTransceiverPlatform>>
-MockWebRTCPeerConnectionHandler::CreateOffer(RTCSessionDescriptionRequest*,
- RTCOfferOptionsPlatform*) {
+Vector<std::unique_ptr<RTCRtpTransceiverPlatform>>
+MockRTCPeerConnectionHandlerPlatform::CreateOffer(RTCSessionDescriptionRequest*,
+ RTCOfferOptionsPlatform*) {
return {};
}
-void MockWebRTCPeerConnectionHandler::CreateAnswer(
+void MockRTCPeerConnectionHandlerPlatform::CreateAnswer(
RTCSessionDescriptionRequest*,
- const WebMediaConstraints&) {}
+ const MediaConstraints&) {}
-void MockWebRTCPeerConnectionHandler::CreateAnswer(
+void MockRTCPeerConnectionHandlerPlatform::CreateAnswer(
RTCSessionDescriptionRequest*,
RTCAnswerOptionsPlatform*) {}
-void MockWebRTCPeerConnectionHandler::SetLocalDescription(RTCVoidRequest*) {}
+void MockRTCPeerConnectionHandlerPlatform::SetLocalDescription(
+ RTCVoidRequest*) {}
-void MockWebRTCPeerConnectionHandler::SetLocalDescription(
+void MockRTCPeerConnectionHandlerPlatform::SetLocalDescription(
RTCVoidRequest*,
RTCSessionDescriptionPlatform*) {}
-void MockWebRTCPeerConnectionHandler::SetRemoteDescription(
+void MockRTCPeerConnectionHandlerPlatform::SetRemoteDescription(
RTCVoidRequest*,
RTCSessionDescriptionPlatform*) {}
RTCSessionDescriptionPlatform*
-MockWebRTCPeerConnectionHandler::LocalDescription() {
+MockRTCPeerConnectionHandlerPlatform::LocalDescription() {
return nullptr;
}
RTCSessionDescriptionPlatform*
-MockWebRTCPeerConnectionHandler::RemoteDescription() {
+MockRTCPeerConnectionHandlerPlatform::RemoteDescription() {
return nullptr;
}
RTCSessionDescriptionPlatform*
-MockWebRTCPeerConnectionHandler::CurrentLocalDescription() {
+MockRTCPeerConnectionHandlerPlatform::CurrentLocalDescription() {
return nullptr;
}
RTCSessionDescriptionPlatform*
-MockWebRTCPeerConnectionHandler::CurrentRemoteDescription() {
+MockRTCPeerConnectionHandlerPlatform::CurrentRemoteDescription() {
return nullptr;
}
RTCSessionDescriptionPlatform*
-MockWebRTCPeerConnectionHandler::PendingLocalDescription() {
+MockRTCPeerConnectionHandlerPlatform::PendingLocalDescription() {
return nullptr;
}
RTCSessionDescriptionPlatform*
-MockWebRTCPeerConnectionHandler::PendingRemoteDescription() {
+MockRTCPeerConnectionHandlerPlatform::PendingRemoteDescription() {
return nullptr;
}
const webrtc::PeerConnectionInterface::RTCConfiguration&
-MockWebRTCPeerConnectionHandler::GetConfiguration() const {
+MockRTCPeerConnectionHandlerPlatform::GetConfiguration() const {
static const webrtc::PeerConnectionInterface::RTCConfiguration configuration;
return configuration;
}
-webrtc::RTCErrorType MockWebRTCPeerConnectionHandler::SetConfiguration(
+webrtc::RTCErrorType MockRTCPeerConnectionHandlerPlatform::SetConfiguration(
const webrtc::PeerConnectionInterface::RTCConfiguration&) {
return webrtc::RTCErrorType::NONE;
}
-void MockWebRTCPeerConnectionHandler::AddICECandidate(
+void MockRTCPeerConnectionHandlerPlatform::AddICECandidate(
RTCVoidRequest*,
- scoped_refptr<RTCIceCandidatePlatform>) {}
+ RTCIceCandidatePlatform*) {}
-void MockWebRTCPeerConnectionHandler::RestartIce() {}
+void MockRTCPeerConnectionHandlerPlatform::RestartIce() {}
-void MockWebRTCPeerConnectionHandler::GetStats(RTCStatsRequest*) {}
+void MockRTCPeerConnectionHandlerPlatform::GetStats(RTCStatsRequest*) {}
-void MockWebRTCPeerConnectionHandler::GetStats(
- blink::WebRTCStatsReportCallback,
- const WebVector<webrtc::NonStandardGroupId>&) {}
+void MockRTCPeerConnectionHandlerPlatform::GetStats(
+ RTCStatsReportCallback,
+ const Vector<webrtc::NonStandardGroupId>&) {}
webrtc::RTCErrorOr<std::unique_ptr<RTCRtpTransceiverPlatform>>
-MockWebRTCPeerConnectionHandler::AddTransceiverWithTrack(
+MockRTCPeerConnectionHandlerPlatform::AddTransceiverWithTrack(
const WebMediaStreamTrack& track,
const webrtc::RtpTransceiverInit&) {
transceivers_.push_back(std::unique_ptr<DummyRTCRtpTransceiverPlatform>(
@@ -348,8 +349,8 @@ MockWebRTCPeerConnectionHandler::AddTransceiverWithTrack(
}
webrtc::RTCErrorOr<std::unique_ptr<RTCRtpTransceiverPlatform>>
-MockWebRTCPeerConnectionHandler::AddTransceiverWithKind(
- std::string kind,
+MockRTCPeerConnectionHandlerPlatform::AddTransceiverWithKind(
+ const String& kind,
const webrtc::RtpTransceiverInit&) {
transceivers_.push_back(std::unique_ptr<DummyRTCRtpTransceiverPlatform>(
new DummyRTCRtpTransceiverPlatform(
@@ -362,8 +363,8 @@ MockWebRTCPeerConnectionHandler::AddTransceiverWithKind(
}
webrtc::RTCErrorOr<std::unique_ptr<RTCRtpTransceiverPlatform>>
-MockWebRTCPeerConnectionHandler::AddTrack(const WebMediaStreamTrack& track,
- const WebVector<WebMediaStream>&) {
+MockRTCPeerConnectionHandlerPlatform::AddTrack(const WebMediaStreamTrack& track,
+ const Vector<WebMediaStream>&) {
transceivers_.push_back(std::unique_ptr<DummyRTCRtpTransceiverPlatform>(
new DummyRTCRtpTransceiverPlatform(track.Source().GetType(), track)));
std::unique_ptr<DummyRTCRtpTransceiverPlatform> copy(
@@ -372,7 +373,8 @@ MockWebRTCPeerConnectionHandler::AddTrack(const WebMediaStreamTrack& track,
}
webrtc::RTCErrorOr<std::unique_ptr<RTCRtpTransceiverPlatform>>
-MockWebRTCPeerConnectionHandler::RemoveTrack(RTCRtpSenderPlatform* sender) {
+MockRTCPeerConnectionHandlerPlatform::RemoveTrack(
+ RTCRtpSenderPlatform* sender) {
const DummyRTCRtpTransceiverPlatform* transceiver_of_sender = nullptr;
for (const auto& transceiver : transceivers_) {
if (transceiver->Sender()->Id() == sender->Id()) {
@@ -388,30 +390,31 @@ MockWebRTCPeerConnectionHandler::RemoveTrack(RTCRtpSenderPlatform* sender) {
}
scoped_refptr<webrtc::DataChannelInterface>
-MockWebRTCPeerConnectionHandler::CreateDataChannel(
- const WebString& label,
+MockRTCPeerConnectionHandlerPlatform::CreateDataChannel(
+ const String& label,
const webrtc::DataChannelInit&) {
return nullptr;
}
-void MockWebRTCPeerConnectionHandler::Stop() {}
+void MockRTCPeerConnectionHandlerPlatform::Stop() {}
+void MockRTCPeerConnectionHandlerPlatform::StopAndUnregister() {}
webrtc::PeerConnectionInterface*
-MockWebRTCPeerConnectionHandler::NativePeerConnection() {
+MockRTCPeerConnectionHandlerPlatform::NativePeerConnection() {
return nullptr;
}
-void MockWebRTCPeerConnectionHandler::
- RunSynchronousOnceClosureOnSignalingThread(base::OnceClosure closure,
+void MockRTCPeerConnectionHandlerPlatform::
+ RunSynchronousOnceClosureOnSignalingThread(CrossThreadOnceClosure closure,
const char* trace_event_name) {}
-void MockWebRTCPeerConnectionHandler::
+void MockRTCPeerConnectionHandlerPlatform::
RunSynchronousRepeatingClosureOnSignalingThread(
const base::RepeatingClosure& closure,
const char* trace_event_name) {}
-void MockWebRTCPeerConnectionHandler::TrackIceConnectionStateChange(
- WebRTCPeerConnectionHandler::IceConnectionStateVersion version,
+void MockRTCPeerConnectionHandlerPlatform::TrackIceConnectionStateChange(
+ RTCPeerConnectionHandlerPlatform::IceConnectionStateVersion version,
webrtc::PeerConnectionInterface::IceConnectionState state) {}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler.h b/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.h
index 4fe3325eaeb..734dfc5d94e 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.h
@@ -2,14 +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_MODULES_PEERCONNECTION_MOCK_WEB_RTC_PEER_CONNECTION_HANDLER_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_MOCK_WEB_RTC_PEER_CONNECTION_HANDLER_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_MOCK_RTC_PEER_CONNECTION_HANDLER_PLATFORM_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_MOCK_RTC_PEER_CONNECTION_HANDLER_PLATFORM_H_
#include <memory>
#include <string>
#include "base/single_thread_task_runner.h"
-#include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_platform.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "third_party/webrtc/api/peer_connection_interface.h"
@@ -20,22 +20,26 @@ namespace blink {
// TODO(https://crbug.com/908461): This is currently implemented as NO-OPs or to
// create dummy objects whose methods return default values. Consider renaming
// the class, changing it to be GMOCK friendly or deleting it.
-class MockWebRTCPeerConnectionHandler : public WebRTCPeerConnectionHandler {
+class MockRTCPeerConnectionHandlerPlatform
+ : public RTCPeerConnectionHandlerPlatform {
public:
- MockWebRTCPeerConnectionHandler();
- ~MockWebRTCPeerConnectionHandler() override;
+ MockRTCPeerConnectionHandlerPlatform();
+ ~MockRTCPeerConnectionHandlerPlatform() override;
bool Initialize(const webrtc::PeerConnectionInterface::RTCConfiguration&,
- const WebMediaConstraints&) override;
+ const MediaConstraints&,
+ WebLocalFrame*) override;
+ void Stop() override;
+ void StopAndUnregister() override;
- WebVector<std::unique_ptr<RTCRtpTransceiverPlatform>> CreateOffer(
+ Vector<std::unique_ptr<RTCRtpTransceiverPlatform>> CreateOffer(
RTCSessionDescriptionRequest*,
- const WebMediaConstraints&) override;
- WebVector<std::unique_ptr<RTCRtpTransceiverPlatform>> CreateOffer(
+ const MediaConstraints&) override;
+ Vector<std::unique_ptr<RTCRtpTransceiverPlatform>> CreateOffer(
RTCSessionDescriptionRequest*,
RTCOfferOptionsPlatform*) override;
void CreateAnswer(RTCSessionDescriptionRequest*,
- const WebMediaConstraints&) override;
+ const MediaConstraints&) override;
void CreateAnswer(RTCSessionDescriptionRequest*,
RTCAnswerOptionsPlatform*) override;
void SetLocalDescription(RTCVoidRequest*) override;
@@ -53,36 +57,34 @@ class MockWebRTCPeerConnectionHandler : public WebRTCPeerConnectionHandler {
const override;
webrtc::RTCErrorType SetConfiguration(
const webrtc::PeerConnectionInterface::RTCConfiguration&) override;
- void AddICECandidate(RTCVoidRequest*,
- scoped_refptr<RTCIceCandidatePlatform>) override;
+ void AddICECandidate(RTCVoidRequest*, RTCIceCandidatePlatform*) override;
void RestartIce() override;
void GetStats(RTCStatsRequest*) override;
- void GetStats(WebRTCStatsReportCallback,
- const WebVector<webrtc::NonStandardGroupId>&) override;
+ void GetStats(RTCStatsReportCallback,
+ const Vector<webrtc::NonStandardGroupId>&) override;
webrtc::RTCErrorOr<std::unique_ptr<RTCRtpTransceiverPlatform>>
AddTransceiverWithTrack(const WebMediaStreamTrack&,
const webrtc::RtpTransceiverInit&) override;
webrtc::RTCErrorOr<std::unique_ptr<RTCRtpTransceiverPlatform>>
- AddTransceiverWithKind(std::string kind,
+ AddTransceiverWithKind(const String& kind,
const webrtc::RtpTransceiverInit&) override;
webrtc::RTCErrorOr<std::unique_ptr<RTCRtpTransceiverPlatform>> AddTrack(
const WebMediaStreamTrack&,
- const WebVector<WebMediaStream>&) override;
+ const Vector<WebMediaStream>&) override;
webrtc::RTCErrorOr<std::unique_ptr<RTCRtpTransceiverPlatform>> RemoveTrack(
RTCRtpSenderPlatform*) override;
scoped_refptr<webrtc::DataChannelInterface> CreateDataChannel(
- const WebString& label,
+ const String& label,
const webrtc::DataChannelInit&) override;
- void Stop() override;
webrtc::PeerConnectionInterface* NativePeerConnection() override;
void RunSynchronousOnceClosureOnSignalingThread(
- base::OnceClosure closure,
+ CrossThreadOnceClosure closure,
const char* trace_event_name) override;
void RunSynchronousRepeatingClosureOnSignalingThread(
const base::RepeatingClosure& closure,
const char* trace_event_name) override;
void TrackIceConnectionStateChange(
- WebRTCPeerConnectionHandler::IceConnectionStateVersion version,
+ RTCPeerConnectionHandlerPlatform::IceConnectionStateVersion version,
webrtc::PeerConnectionInterface::IceConnectionState state) override;
private:
@@ -93,4 +95,4 @@ class MockWebRTCPeerConnectionHandler : public WebRTCPeerConnectionHandler {
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_MOCK_WEB_RTC_PEER_CONNECTION_HANDLER_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_MOCK_RTC_PEER_CONNECTION_HANDLER_PLATFORM_H_
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 9249bbcc249..15929f4ae02 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
@@ -7,10 +7,10 @@
#include <stddef.h>
#include <memory>
+#include <string>
#include <utility>
#include <vector>
-#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
#include "base/logging.h"
@@ -26,11 +26,9 @@
#include "third_party/blink/public/common/peerconnection/webrtc_ip_handling_policy.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_constraints.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_rtc_peer_connection_handler.h"
#include "third_party/blink/public/platform/web_url.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"
@@ -38,6 +36,7 @@
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.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/webrtc_uma_histograms.h"
#include "third_party/blink/renderer/platform/p2p/empty_network_manager.h"
#include "third_party/blink/renderer/platform/p2p/filtering_network_manager.h"
@@ -47,8 +46,11 @@
#include "third_party/blink/renderer/platform/p2p/port_allocator.h"
#include "third_party/blink/renderer/platform/p2p/socket_dispatcher.h"
#include "third_party/blink/renderer/platform/peerconnection/audio_codec_factory.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/stun_field_trial.h"
#include "third_party/blink/renderer/platform/peerconnection/video_codec_factory.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/webrtc/api/call/call_factory_interface.h"
#include "third_party/webrtc/api/peer_connection_interface.h"
#include "third_party/webrtc/api/rtc_event_log/rtc_event_log_factory.h"
@@ -73,13 +75,12 @@ enum WebRTCIPHandlingPolicy {
DISABLE_NON_PROXIED_UDP,
};
-WebRTCIPHandlingPolicy GetWebRTCIPHandlingPolicy(
- const std::string& preference) {
- if (preference == blink::kWebRTCIPHandlingDefaultPublicAndPrivateInterfaces)
+WebRTCIPHandlingPolicy GetWebRTCIPHandlingPolicy(const String& preference) {
+ if (preference == kWebRTCIPHandlingDefaultPublicAndPrivateInterfaces)
return DEFAULT_PUBLIC_AND_PRIVATE_INTERFACES;
- if (preference == blink::kWebRTCIPHandlingDefaultPublicInterfaceOnly)
+ if (preference == kWebRTCIPHandlingDefaultPublicInterfaceOnly)
return DEFAULT_PUBLIC_INTERFACE_ONLY;
- if (preference == blink::kWebRTCIPHandlingDisableNonProxiedUdp)
+ if (preference == kWebRTCIPHandlingDisableNonProxiedUdp)
return DISABLE_NON_PROXIED_UDP;
return DEFAULT;
}
@@ -117,8 +118,8 @@ PeerConnectionDependencyFactory::PeerConnectionDependencyFactory(
create_p2p_socket_dispatcher ? new P2PSocketDispatcher() : nullptr),
signaling_thread_(nullptr),
worker_thread_(nullptr),
- chrome_signaling_thread_("Chrome_libJingle_Signaling"),
- chrome_worker_thread_("Chrome_libJingle_WorkerThread") {
+ chrome_signaling_thread_("WebRTC_Signaling"),
+ chrome_worker_thread_("WebRTC_Worker") {
TryScheduleStunProbeTrial();
}
@@ -135,16 +136,20 @@ PeerConnectionDependencyFactory::GetInstance() {
return &instance;
}
-std::unique_ptr<blink::WebRTCPeerConnectionHandler>
+std::unique_ptr<RTCPeerConnectionHandlerPlatform>
PeerConnectionDependencyFactory::CreateRTCPeerConnectionHandler(
- blink::WebRTCPeerConnectionHandlerClient* client,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
+ RTCPeerConnectionHandlerClient* client,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ bool force_encoded_audio_insertable_streams,
+ bool force_encoded_video_insertable_streams) {
// Save histogram data so we can see how much PeerConnection is used.
// The histogram counts the number of calls to the JS API
// RTCPeerConnection.
UpdateWebRTCMethodCount(RTCAPIName::kRTCPeerConnection);
- return std::make_unique<RTCPeerConnectionHandler>(client, this, task_runner);
+ return std::make_unique<RTCPeerConnectionHandler>(
+ client, this, task_runner, force_encoded_audio_insertable_streams,
+ force_encoded_video_insertable_streams);
}
const scoped_refptr<webrtc::PeerConnectionFactoryInterface>&
@@ -194,11 +199,12 @@ void PeerConnectionDependencyFactory::CreatePeerConnectionFactory() {
base::WaitableEvent start_worker_event(
base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED);
- chrome_worker_thread_.task_runner()->PostTask(
- FROM_HERE,
- base::BindOnce(&PeerConnectionDependencyFactory::InitializeWorkerThread,
- base::Unretained(this), &worker_thread_,
- &start_worker_event));
+ PostCrossThreadTask(
+ *chrome_worker_thread_.task_runner().get(), FROM_HERE,
+ CrossThreadBindOnce(
+ &PeerConnectionDependencyFactory::InitializeWorkerThread,
+ CrossThreadUnretained(this), CrossThreadUnretained(&worker_thread_),
+ CrossThreadUnretained(&start_worker_event)));
base::WaitableEvent create_network_manager_event(
base::WaitableEvent::ResetPolicy::MANUAL,
@@ -212,12 +218,13 @@ void PeerConnectionDependencyFactory::CreatePeerConnectionFactory() {
mdns_responder = std::make_unique<MdnsResponderAdapter>();
}
#endif // BUILDFLAG(ENABLE_MDNS)
- chrome_worker_thread_.task_runner()->PostTask(
- FROM_HERE,
- base::BindOnce(&PeerConnectionDependencyFactory::
- CreateIpcNetworkManagerOnWorkerThread,
- base::Unretained(this), &create_network_manager_event,
- std::move(mdns_responder)));
+ PostCrossThreadTask(
+ *chrome_worker_thread_.task_runner().get(), FROM_HERE,
+ CrossThreadBindOnce(&PeerConnectionDependencyFactory::
+ CreateIpcNetworkManagerOnWorkerThread,
+ CrossThreadUnretained(this),
+ CrossThreadUnretained(&create_network_manager_event),
+ std::move(mdns_responder)));
start_worker_event.Wait();
create_network_manager_event.Wait();
@@ -234,12 +241,13 @@ void PeerConnectionDependencyFactory::CreatePeerConnectionFactory() {
base::WaitableEvent start_signaling_event(
base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED);
- chrome_signaling_thread_.task_runner()->PostTask(
- FROM_HERE,
- base::BindOnce(
+ PostCrossThreadTask(
+ *chrome_signaling_thread_.task_runner().get(), FROM_HERE,
+ CrossThreadBindOnce(
&PeerConnectionDependencyFactory::InitializeSignalingThread,
- base::Unretained(this), blink::Platform::Current()->GetGpuFactories(),
- &start_signaling_event));
+ CrossThreadUnretained(this),
+ CrossThreadUnretained(Platform::Current()->GetGpuFactories()),
+ CrossThreadUnretained(&start_signaling_event)));
start_signaling_event.Wait();
CHECK(signaling_thread_);
@@ -395,14 +403,14 @@ PeerConnectionDependencyFactory::CreatePortAllocator(
// detached, it is impossible for RTCPeerConnectionHandler to outlive the
// frame. Therefore using a raw pointer of |media_permission| is safe here.
media::MediaPermission* media_permission = nullptr;
- if (!blink::Platform::Current()->ShouldEnforceWebRTCRoutingPreferences()) {
+ if (!Platform::Current()->ShouldEnforceWebRTCRoutingPreferences()) {
port_config.enable_multiple_routes = true;
port_config.enable_nonproxied_udp = true;
VLOG(3) << "WebRTC routing preferences will not be enforced";
} else {
if (web_frame && web_frame->View()) {
- blink::WebString webrtc_ip_handling_policy;
- blink::Platform::Current()->GetWebRTCRendererPreferences(
+ WebString webrtc_ip_handling_policy;
+ Platform::Current()->GetWebRTCRendererPreferences(
web_frame, &webrtc_ip_handling_policy, &min_port, &max_port,
&allow_mdns_obfuscation);
@@ -411,7 +419,7 @@ PeerConnectionDependencyFactory::CreatePortAllocator(
// collected depends on if mic/camera permission is granted for this
// origin.
WebRTCIPHandlingPolicy policy =
- GetWebRTCIPHandlingPolicy(webrtc_ip_handling_policy.Utf8());
+ GetWebRTCIPHandlingPolicy(webrtc_ip_handling_policy);
switch (policy) {
// TODO(guoweis): specify the flag of disabling local candidate
// collection when webrtc is updated.
@@ -457,9 +465,8 @@ PeerConnectionDependencyFactory::CreatePortAllocator(
std::unique_ptr<rtc::NetworkManager> network_manager;
if (port_config.enable_multiple_routes) {
- network_manager = std::make_unique<blink::FilteringNetworkManager>(
- network_manager_.get(), requesting_origin, media_permission,
- allow_mdns_obfuscation);
+ network_manager = std::make_unique<FilteringNetworkManager>(
+ network_manager_.get(), media_permission, allow_mdns_obfuscation);
} else {
network_manager =
std::make_unique<blink::EmptyNetworkManager>(network_manager_.get());
@@ -480,9 +487,8 @@ PeerConnectionDependencyFactory::CreateAsyncResolverFactory() {
}
scoped_refptr<webrtc::MediaStreamInterface>
-PeerConnectionDependencyFactory::CreateLocalMediaStream(
- const std::string& label) {
- return GetPcFactory()->CreateLocalMediaStream(label).get();
+PeerConnectionDependencyFactory::CreateLocalMediaStream(const String& label) {
+ return GetPcFactory()->CreateLocalMediaStream(label.Utf8()).get();
}
scoped_refptr<webrtc::VideoTrackSourceInterface>
@@ -500,24 +506,25 @@ PeerConnectionDependencyFactory::CreateVideoTrackSourceProxy(
scoped_refptr<webrtc::VideoTrackInterface>
PeerConnectionDependencyFactory::CreateLocalVideoTrack(
- const std::string& id,
+ const String& id,
webrtc::VideoTrackSourceInterface* source) {
- return GetPcFactory()->CreateVideoTrack(id, source).get();
+ return GetPcFactory()->CreateVideoTrack(id.Utf8(), source).get();
}
webrtc::SessionDescriptionInterface*
PeerConnectionDependencyFactory::CreateSessionDescription(
- const std::string& type,
- const std::string& sdp,
+ const String& type,
+ const String& sdp,
webrtc::SdpParseError* error) {
- return webrtc::CreateSessionDescription(type, sdp, error);
+ return webrtc::CreateSessionDescription(type.Utf8(), sdp.Utf8(), error);
}
webrtc::IceCandidateInterface*
-PeerConnectionDependencyFactory::CreateIceCandidate(const std::string& sdp_mid,
+PeerConnectionDependencyFactory::CreateIceCandidate(const String& sdp_mid,
int sdp_mline_index,
- const std::string& sdp) {
- return webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, sdp, nullptr);
+ const String& sdp) {
+ return webrtc::CreateIceCandidate(sdp_mid.Utf8(), sdp_mline_index, sdp.Utf8(),
+ nullptr);
}
blink::WebRtcAudioDeviceImpl*
@@ -537,27 +544,29 @@ void PeerConnectionDependencyFactory::InitializeWorkerThread(
}
void PeerConnectionDependencyFactory::TryScheduleStunProbeTrial() {
- base::Optional<std::string> params =
- blink::Platform::Current()->WebRtcStunProbeTrialParameter();
+ base::Optional<WebString> params =
+ Platform::Current()->WebRtcStunProbeTrialParameter();
if (!params)
return;
GetPcFactory();
- chrome_worker_thread_.task_runner()->PostDelayedTask(
- FROM_HERE,
- base::BindOnce(
+ PostDelayedCrossThreadTask(
+ *chrome_worker_thread_.task_runner().get(), FROM_HERE,
+ CrossThreadBindOnce(
&PeerConnectionDependencyFactory::StartStunProbeTrialOnWorkerThread,
- base::Unretained(this), *params),
+ CrossThreadUnretained(this), String(*params)),
base::TimeDelta::FromMilliseconds(blink::kExperimentStartDelayMs));
}
void PeerConnectionDependencyFactory::StartStunProbeTrialOnWorkerThread(
- const std::string& params) {
+ const String& params) {
DCHECK(network_manager_);
DCHECK(chrome_worker_thread_.task_runner()->BelongsToCurrentThread());
- stun_trial_.reset(new blink::StunProberTrial(network_manager_.get(), params,
- socket_factory_.get()));
+ // 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(
@@ -581,11 +590,11 @@ void PeerConnectionDependencyFactory::CleanupPeerConnectionFactory() {
// The network manager needs to free its resources on the thread they were
// created, which is the worked thread.
if (chrome_worker_thread_.IsRunning()) {
- chrome_worker_thread_.task_runner()->PostTask(
- FROM_HERE,
- base::BindOnce(
+ PostCrossThreadTask(
+ *chrome_worker_thread_.task_runner().get(), FROM_HERE,
+ CrossThreadBindOnce(
&PeerConnectionDependencyFactory::DeleteIpcNetworkManager,
- base::Unretained(this)));
+ 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.
@@ -626,8 +635,7 @@ void PeerConnectionDependencyFactory::EnsureWebRtcAudioDeviceImpl() {
}
std::unique_ptr<webrtc::RtpCapabilities>
-PeerConnectionDependencyFactory::GetSenderCapabilities(
- const std::string& kind) {
+PeerConnectionDependencyFactory::GetSenderCapabilities(const String& kind) {
if (kind == "audio") {
return std::make_unique<webrtc::RtpCapabilities>(
GetPcFactory()->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_AUDIO));
@@ -639,8 +647,7 @@ PeerConnectionDependencyFactory::GetSenderCapabilities(
}
std::unique_ptr<webrtc::RtpCapabilities>
-PeerConnectionDependencyFactory::GetReceiverCapabilities(
- const std::string& kind) {
+PeerConnectionDependencyFactory::GetReceiverCapabilities(const String& kind) {
if (kind == "audio") {
return std::make_unique<webrtc::RtpCapabilities>(
GetPcFactory()->GetRtpReceiverCapabilities(cricket::MEDIA_TYPE_AUDIO));
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 5dd2bc29cbe..ff1fde12ddc 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
@@ -5,14 +5,13 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_PEER_CONNECTION_DEPENDENCY_FACTORY_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_PEER_CONNECTION_DEPENDENCY_FACTORY_H_
-#include <string>
-
#include "base/macros.h"
#include "base/message_loop/message_loop_current.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread.h"
#include "base/threading/thread_checker.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/webrtc/api/peer_connection_interface.h"
#include "third_party/webrtc/p2p/stunprober/stun_prober.h"
@@ -38,30 +37,28 @@ class IpcNetworkManager;
class IpcPacketSocketFactory;
class MdnsResponderAdapter;
class P2PSocketDispatcher;
+class RTCPeerConnectionHandlerClient;
+class RTCPeerConnectionHandlerPlatform;
class StunProberTrial;
class WebLocalFrame;
-class WebRTCPeerConnectionHandler;
-class WebRTCPeerConnectionHandlerClient;
class WebRtcAudioDeviceImpl;
// Object factory for RTC PeerConnections.
class MODULES_EXPORT PeerConnectionDependencyFactory
: base::MessageLoopCurrent::DestructionObserver {
public:
- // TODO(crbug.com/787254): Make this constructor private, when
- // MockPeerConnectionDependencyFactory gets moved to blink.
- // (friend class declaration will be needed).
- PeerConnectionDependencyFactory(bool create_p2p_socket_dispatcher);
~PeerConnectionDependencyFactory() override;
static PeerConnectionDependencyFactory* GetInstance();
// Create a RTCPeerConnectionHandler object that implements the
- // WebKit WebRTCPeerConnectionHandler interface.
- std::unique_ptr<blink::WebRTCPeerConnectionHandler>
+ // WebKit RTCPeerConnectionHandlerPlatform interface.
+ std::unique_ptr<RTCPeerConnectionHandlerPlatform>
CreateRTCPeerConnectionHandler(
- blink::WebRTCPeerConnectionHandlerClient* client,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+ RTCPeerConnectionHandlerClient* client,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ bool force_encoded_audio_insertable_streams,
+ bool force_encoded_video_insertable_streams);
// Create a proxy object for a VideoTrackSource that makes sure it's called on
// the correct threads.
@@ -70,11 +67,11 @@ class MODULES_EXPORT PeerConnectionDependencyFactory
// Asks the PeerConnection factory to create a Local MediaStream object.
virtual scoped_refptr<webrtc::MediaStreamInterface> CreateLocalMediaStream(
- const std::string& label);
+ const String& label);
// Asks the PeerConnection factory to create a Local VideoTrack object.
virtual scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrack(
- const std::string& id,
+ const String& id,
webrtc::VideoTrackSourceInterface* source);
// Asks the libjingle PeerConnection factory to create a libjingle
@@ -97,22 +94,22 @@ class MODULES_EXPORT PeerConnectionDependencyFactory
// Creates a libjingle representation of a Session description. Used by a
// RTCPeerConnectionHandler instance.
virtual webrtc::SessionDescriptionInterface* CreateSessionDescription(
- const std::string& type,
- const std::string& sdp,
+ const String& type,
+ const String& sdp,
webrtc::SdpParseError* error);
// Creates a libjingle representation of an ice candidate.
virtual webrtc::IceCandidateInterface* CreateIceCandidate(
- const std::string& sdp_mid,
+ const String& sdp_mid,
int sdp_mline_index,
- const std::string& sdp);
+ const String& sdp);
// Returns the most optimistic view of the capabilities of the system for
// sending or receiving media of the given kind ("audio" or "video").
virtual std::unique_ptr<webrtc::RtpCapabilities> GetSenderCapabilities(
- const std::string& kind);
+ const String& kind);
virtual std::unique_ptr<webrtc::RtpCapabilities> GetReceiverCapabilities(
- const std::string& kind);
+ const String& kind);
blink::WebRtcAudioDeviceImpl* GetWebRtcAudioDevice();
@@ -126,6 +123,8 @@ class MODULES_EXPORT PeerConnectionDependencyFactory
GetWebRtcSignalingTaskRunner();
protected:
+ PeerConnectionDependencyFactory(bool create_p2p_socket_dispatcher);
+
virtual const scoped_refptr<webrtc::PeerConnectionFactoryInterface>&
GetPcFactory();
virtual bool PeerConnectionFactoryCreated();
@@ -142,7 +141,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 std::string& params);
+ void StartStunProbeTrialOnWorkerThread(const String& params);
// Creates |pc_factory_|, which in turn is used for
// creating PeerConnection objects.
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory_test.cc
index a7c9ca3911f..f2a47f47453 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory_test.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory_test.cc
@@ -5,7 +5,7 @@
#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/modules/peerconnection/mock_peer_connection_dependency_factory.h"
-#include "third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler_client.h"
+#include "third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_client.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h"
namespace blink {
@@ -22,11 +22,12 @@ class PeerConnectionDependencyFactoryTest : public ::testing::Test {
};
TEST_F(PeerConnectionDependencyFactoryTest, CreateRTCPeerConnectionHandler) {
- blink::MockWebRTCPeerConnectionHandlerClient client_jsep;
- std::unique_ptr<blink::WebRTCPeerConnectionHandler> pc_handler(
+ MockRTCPeerConnectionHandlerClient client_jsep;
+ std::unique_ptr<RTCPeerConnectionHandlerPlatform> pc_handler(
dependency_factory_->CreateRTCPeerConnectionHandler(
- &client_jsep,
- blink::scheduler::GetSingleThreadTaskRunnerForTesting()));
+ &client_jsep, blink::scheduler::GetSingleThreadTaskRunnerForTesting(),
+ /*force_encoded_audio_insertable_streams=*/false,
+ /*force_encoded_video_insertable_streams=*/false));
EXPECT_TRUE(pc_handler);
}
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 d4a923dede7..da8d1e0c9d8 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,38 +12,63 @@
#include <utility>
#include <vector>
-#include "base/bind.h"
#include "base/values.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_constraints.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_rtc_peer_connection_handler_client.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_local_frame.h"
-#include "third_party/blink/public/web/web_user_media_request.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#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/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"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_client.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/text/string_builder.h"
-using blink::WebRTCPeerConnectionHandlerClient;
using webrtc::StatsReport;
using webrtc::StatsReports;
namespace blink {
+class InternalStandardStatsObserver;
+}
+
+namespace WTF {
+
+template <>
+struct CrossThreadCopier<scoped_refptr<blink::InternalStandardStatsObserver>>
+ : public CrossThreadCopierPassThrough<
+ scoped_refptr<blink::InternalStandardStatsObserver>> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+template <typename T>
+struct CrossThreadCopier<rtc::scoped_refptr<T>> {
+ STATIC_ONLY(CrossThreadCopier);
+ using Type = rtc::scoped_refptr<T>;
+ static Type Copy(Type pointer) { return pointer; }
+};
+
+} // namespace WTF
+
+namespace blink {
// TODO(hta): This module should be redesigned to reduce string copies.
-static String SerializeBoolean(bool value) {
+namespace {
+
+String SerializeBoolean(bool value) {
return value ? "true" : "false";
}
-static String SerializeServers(
+String SerializeServers(
const std::vector<webrtc::PeerConnectionInterface::IceServer>& servers) {
StringBuilder result;
result.Append("[");
@@ -63,12 +88,11 @@ static String SerializeServers(
return result.ToString();
}
-static String SerializeMediaConstraints(
- const blink::WebMediaConstraints& constraints) {
+String SerializeMediaConstraints(const MediaConstraints& constraints) {
return String(constraints.ToString());
}
-static String SerializeOfferOptions(blink::RTCOfferOptionsPlatform* options) {
+String SerializeOfferOptions(blink::RTCOfferOptionsPlatform* options) {
if (!options)
return "null";
@@ -84,7 +108,7 @@ static String SerializeOfferOptions(blink::RTCOfferOptionsPlatform* options) {
return result.ToString();
}
-static String SerializeAnswerOptions(blink::RTCAnswerOptionsPlatform* options) {
+String SerializeAnswerOptions(blink::RTCAnswerOptionsPlatform* options) {
if (!options)
return "null";
@@ -94,8 +118,7 @@ static String SerializeAnswerOptions(blink::RTCAnswerOptionsPlatform* options) {
return result.ToString();
}
-static String SerializeMediaStreamIds(
- const blink::WebVector<blink::WebString>& stream_ids) {
+String SerializeMediaStreamIds(const Vector<String>& stream_ids) {
if (!stream_ids.size())
return "[]";
StringBuilder result;
@@ -104,14 +127,14 @@ static String SerializeMediaStreamIds(
if (result.length() > 2u)
result.Append(",");
result.Append("'");
- result.Append(String(stream_id));
+ result.Append(stream_id);
result.Append("'");
}
result.Append("]");
return result.ToString();
}
-static String SerializeDirection(webrtc::RtpTransceiverDirection direction) {
+String SerializeDirection(webrtc::RtpTransceiverDirection direction) {
switch (direction) {
case webrtc::RtpTransceiverDirection::kSendRecv:
return "'sendrecv'";
@@ -121,16 +144,19 @@ static String SerializeDirection(webrtc::RtpTransceiverDirection direction) {
return "'recvonly'";
case webrtc::RtpTransceiverDirection::kInactive:
return "'inactive'";
+ default:
+ NOTREACHED();
+ return String();
}
}
-static String SerializeOptionalDirection(
+String SerializeOptionalDirection(
const base::Optional<webrtc::RtpTransceiverDirection>& direction) {
return direction ? SerializeDirection(*direction) : "null";
}
-static String SerializeSender(const String& indent,
- const blink::RTCRtpSenderPlatform& sender) {
+String SerializeSender(const String& indent,
+ const blink::RTCRtpSenderPlatform& sender) {
StringBuilder result;
result.Append("{\n");
// track:'id',
@@ -154,8 +180,8 @@ static String SerializeSender(const String& indent,
return result.ToString();
}
-static String SerializeReceiver(const String& indent,
- const RTCRtpReceiverPlatform& receiver) {
+String SerializeReceiver(const String& indent,
+ const RTCRtpReceiverPlatform& receiver) {
StringBuilder result;
result.Append("{\n");
// track:'id',
@@ -174,8 +200,7 @@ static String SerializeReceiver(const String& indent,
return result.ToString();
}
-static String SerializeTransceiver(
- const RTCRtpTransceiverPlatform& transceiver) {
+String SerializeTransceiver(const RTCRtpTransceiverPlatform& transceiver) {
if (transceiver.ImplementationType() ==
RTCRtpTransceiverPlatformImplementationType::kFullTransceiver) {
StringBuilder result;
@@ -220,7 +245,7 @@ static String SerializeTransceiver(
return SerializeReceiver("", *transceiver.Receiver());
}
-static String SerializeIceTransportType(
+String SerializeIceTransportType(
webrtc::PeerConnectionInterface::IceTransportsType type) {
String transport_type("");
switch (type) {
@@ -242,7 +267,7 @@ static String SerializeIceTransportType(
return transport_type;
}
-static String SerializeBundlePolicy(
+String SerializeBundlePolicy(
webrtc::PeerConnectionInterface::BundlePolicy policy) {
String policy_str("");
switch (policy) {
@@ -261,7 +286,7 @@ static String SerializeBundlePolicy(
return policy_str;
}
-static String SerializeRtcpMuxPolicy(
+String SerializeRtcpMuxPolicy(
webrtc::PeerConnectionInterface::RtcpMuxPolicy policy) {
String policy_str("");
switch (policy) {
@@ -277,7 +302,7 @@ static String SerializeRtcpMuxPolicy(
return policy_str;
}
-static String SerializeSdpSemantics(webrtc::SdpSemantics sdp_semantics) {
+String SerializeSdpSemantics(webrtc::SdpSemantics sdp_semantics) {
String sdp_semantics_str("");
switch (sdp_semantics) {
case webrtc::SdpSemantics::kPlanB:
@@ -292,7 +317,7 @@ static String SerializeSdpSemantics(webrtc::SdpSemantics sdp_semantics) {
return sdp_semantics_str;
}
-static String SerializeConfiguration(
+String SerializeConfiguration(
const webrtc::PeerConnectionInterface::RTCConfiguration& config) {
StringBuilder result;
// TODO(hbos): Add serialization of certificate.
@@ -316,7 +341,7 @@ static String SerializeConfiguration(
// peer_connection_update_table.js, in order to be displayed as friendly
// strings on chrome://webrtc-internals.
-static const char* GetSignalingStateString(
+const char* GetSignalingStateString(
webrtc::PeerConnectionInterface::SignalingState state) {
const char* result = "";
switch (state) {
@@ -339,7 +364,7 @@ static const char* GetSignalingStateString(
return result;
}
-static const char* GetIceConnectionStateString(
+const char* GetIceConnectionStateString(
webrtc::PeerConnectionInterface::IceConnectionState state) {
switch (state) {
case webrtc::PeerConnectionInterface::kIceConnectionNew:
@@ -362,7 +387,7 @@ static const char* GetIceConnectionStateString(
}
}
-static const char* GetConnectionStateString(
+const char* GetConnectionStateString(
webrtc::PeerConnectionInterface::PeerConnectionState state) {
switch (state) {
case webrtc::PeerConnectionInterface::PeerConnectionState::kNew:
@@ -383,7 +408,7 @@ static const char* GetConnectionStateString(
}
}
-static const char* GetIceGatheringStateString(
+const char* GetIceGatheringStateString(
webrtc::PeerConnectionInterface::IceGatheringState state) {
switch (state) {
case webrtc::PeerConnectionInterface::kIceGatheringNew:
@@ -398,7 +423,7 @@ static const char* GetIceGatheringStateString(
}
}
-static const char* GetTransceiverUpdatedReasonString(
+const char* GetTransceiverUpdatedReasonString(
PeerConnectionTracker::TransceiverUpdatedReason reason) {
switch (reason) {
case PeerConnectionTracker::TransceiverUpdatedReason::kAddTransceiver:
@@ -420,7 +445,7 @@ static const char* GetTransceiverUpdatedReasonString(
// Note:
// The format must be consistent with what webrtc_internals.js expects.
// If you change it here, you must change webrtc_internals.js as well.
-static std::unique_ptr<base::DictionaryValue> GetDictValueStats(
+std::unique_ptr<base::DictionaryValue> GetDictValueStats(
const StatsReport& report) {
if (report.values().empty())
return nullptr;
@@ -464,8 +489,7 @@ static std::unique_ptr<base::DictionaryValue> GetDictValueStats(
// Builds a DictionaryValue from the StatsReport.
// The caller takes the ownership of the returned value.
-static std::unique_ptr<base::DictionaryValue> GetDictValue(
- const StatsReport& report) {
+std::unique_ptr<base::DictionaryValue> GetDictValue(const StatsReport& report) {
std::unique_ptr<base::DictionaryValue> stats = GetDictValueStats(report);
if (!stats)
return nullptr;
@@ -481,6 +505,8 @@ static std::unique_ptr<base::DictionaryValue> GetDictValue(
return result;
}
+} // namespace
+
// chrome://webrtc-internals displays stats and stats graphs. The call path
// involves thread and process hops (IPC). This is the webrtc::StatsObserver
// that is used when webrtc-internals wants legacy stats. It starts in
@@ -491,14 +517,13 @@ class InternalLegacyStatsObserver : public webrtc::StatsObserver {
InternalLegacyStatsObserver(
int lid,
scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- base::OnceCallback<void(int, base::Value)> completion_callback)
+ CrossThreadOnceFunction<void(int, base::Value)> completion_callback)
: lid_(lid),
main_thread_(std::move(main_thread)),
completion_callback_(std::move(completion_callback)) {}
void OnComplete(const StatsReports& reports) override {
- std::unique_ptr<base::ListValue> list(new base::ListValue());
-
+ auto list = std::make_unique<base::ListValue>();
for (const auto* r : reports) {
std::unique_ptr<base::DictionaryValue> report = GetDictValue(*r);
if (report)
@@ -506,11 +531,11 @@ class InternalLegacyStatsObserver : public webrtc::StatsObserver {
}
if (!list->empty()) {
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(&InternalLegacyStatsObserver::OnCompleteImpl,
- std::move(list), lid_,
- std::move(completion_callback_)));
+ PostCrossThreadTask(
+ *main_thread_.get(), FROM_HERE,
+ CrossThreadBindOnce(&InternalLegacyStatsObserver::OnCompleteImpl,
+ std::move(list), lid_,
+ std::move(completion_callback_)));
}
}
@@ -528,14 +553,14 @@ class InternalLegacyStatsObserver : public webrtc::StatsObserver {
static void OnCompleteImpl(
std::unique_ptr<base::ListValue> list,
int lid,
- base::OnceCallback<void(int, base::Value)> completion_callback) {
+ CrossThreadOnceFunction<void(int, base::Value)> completion_callback) {
DCHECK(!list->empty());
std::move(completion_callback).Run(lid, std::move(*list.get()));
}
const int lid_;
const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- base::OnceCallback<void(int, base::Value)> completion_callback_;
+ CrossThreadOnceFunction<void(int, base::Value)> completion_callback_;
};
// chrome://webrtc-internals displays stats and stats graphs. The call path
@@ -548,7 +573,7 @@ class InternalStandardStatsObserver : public webrtc::RTCStatsCollectorCallback {
InternalStandardStatsObserver(
int lid,
scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- base::OnceCallback<void(int, base::Value)> completion_callback)
+ CrossThreadOnceFunction<void(int, base::Value)> completion_callback)
: lid_(lid),
main_thread_(std::move(main_thread)),
completion_callback_(std::move(completion_callback)) {}
@@ -557,9 +582,9 @@ class InternalStandardStatsObserver : public webrtc::RTCStatsCollectorCallback {
const rtc::scoped_refptr<const webrtc::RTCStatsReport>& report) override {
// We're on the signaling thread.
DCHECK(!main_thread_->BelongsToCurrentThread());
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(
+ PostCrossThreadTask(
+ *main_thread_.get(), FROM_HERE,
+ CrossThreadBindOnce(
&InternalStandardStatsObserver::OnStatsDeliveredOnMainThread,
scoped_refptr<InternalStandardStatsObserver>(this), report));
}
@@ -638,7 +663,7 @@ class InternalStandardStatsObserver : public webrtc::RTCStatsCollectorCallback {
const int lid_;
const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- base::OnceCallback<void(int, base::Value)> completion_callback_;
+ CrossThreadOnceFunction<void(int, base::Value)> completion_callback_;
};
// static
@@ -676,7 +701,7 @@ void PeerConnectionTracker::OnSuspend() {
DCHECK_CALLED_ON_VALID_THREAD(main_thread_);
for (auto it = peer_connection_local_id_map_.begin();
it != peer_connection_local_id_map_.end(); ++it) {
- it->first->CloseClientPeerConnection();
+ it->key->CloseClientPeerConnection();
}
}
@@ -684,8 +709,8 @@ void PeerConnectionTracker::StartEventLog(int peer_connection_local_id,
int output_period_ms) {
DCHECK_CALLED_ON_VALID_THREAD(main_thread_);
for (auto& it : peer_connection_local_id_map_) {
- if (it.second == peer_connection_local_id) {
- it.first->StartEventLog(output_period_ms);
+ if (it.value == peer_connection_local_id) {
+ it.key->StartEventLog(output_period_ms);
return;
}
}
@@ -694,8 +719,8 @@ void PeerConnectionTracker::StartEventLog(int peer_connection_local_id,
void PeerConnectionTracker::StopEventLog(int peer_connection_local_id) {
DCHECK_CALLED_ON_VALID_THREAD(main_thread_);
for (auto& it : peer_connection_local_id_map_) {
- if (it.second == peer_connection_local_id) {
- it.first->StopEventLog();
+ if (it.value == peer_connection_local_id) {
+ it.key->StopEventLog();
return;
}
}
@@ -707,10 +732,10 @@ void PeerConnectionTracker::GetStandardStats() {
for (const auto& pair : peer_connection_local_id_map_) {
scoped_refptr<InternalStandardStatsObserver> observer(
new rtc::RefCountedObject<InternalStandardStatsObserver>(
- pair.second, main_thread_task_runner_,
- base::BindOnce(&PeerConnectionTracker::AddStandardStats,
- AsWeakPtr())));
- pair.first->GetStandardStatsForTracker(observer);
+ pair.value, main_thread_task_runner_,
+ CrossThreadBindOnce(&PeerConnectionTracker::AddStandardStats,
+ AsWeakPtr())));
+ pair.key->GetStandardStatsForTracker(observer);
}
}
@@ -720,19 +745,19 @@ void PeerConnectionTracker::GetLegacyStats() {
for (const auto& pair : peer_connection_local_id_map_) {
rtc::scoped_refptr<InternalLegacyStatsObserver> observer(
new rtc::RefCountedObject<InternalLegacyStatsObserver>(
- pair.second, main_thread_task_runner_,
- base::BindOnce(&PeerConnectionTracker::AddLegacyStats,
- AsWeakPtr())));
- pair.first->GetStats(
- observer, webrtc::PeerConnectionInterface::kStatsOutputLevelDebug,
- nullptr);
+ pair.value, main_thread_task_runner_,
+ CrossThreadBindOnce(&PeerConnectionTracker::AddLegacyStats,
+ AsWeakPtr())));
+ pair.key->GetStats(observer,
+ webrtc::PeerConnectionInterface::kStatsOutputLevelDebug,
+ nullptr);
}
}
void PeerConnectionTracker::RegisterPeerConnection(
RTCPeerConnectionHandler* pc_handler,
const webrtc::PeerConnectionInterface::RTCConfiguration& config,
- const blink::WebMediaConstraints& constraints,
+ const MediaConstraints& constraints,
const blink::WebLocalFrame* frame) {
DCHECK_CALLED_ON_VALID_THREAD(main_thread_);
DCHECK(pc_handler);
@@ -752,7 +777,7 @@ void PeerConnectionTracker::RegisterPeerConnection(
int32_t lid = info->lid;
peer_connection_tracker_host_->AddPeerConnection(std::move(info));
- peer_connection_local_id_map_.insert(std::make_pair(pc_handler, lid));
+ peer_connection_local_id_map_.insert(pc_handler, lid);
}
void PeerConnectionTracker::UnregisterPeerConnection(
@@ -768,7 +793,7 @@ void PeerConnectionTracker::UnregisterPeerConnection(
return;
}
- peer_connection_tracker_host_->RemovePeerConnection(it->second);
+ peer_connection_tracker_host_->RemovePeerConnection(it->value);
peer_connection_local_id_map_.erase(it);
}
@@ -786,7 +811,7 @@ void PeerConnectionTracker::TrackCreateOffer(
void PeerConnectionTracker::TrackCreateOffer(
RTCPeerConnectionHandler* pc_handler,
- const blink::WebMediaConstraints& constraints) {
+ const MediaConstraints& constraints) {
DCHECK_CALLED_ON_VALID_THREAD(main_thread_);
int id = GetLocalIDForHandler(pc_handler);
if (id == -1)
@@ -809,7 +834,7 @@ void PeerConnectionTracker::TrackCreateAnswer(
void PeerConnectionTracker::TrackCreateAnswer(
RTCPeerConnectionHandler* pc_handler,
- const blink::WebMediaConstraints& constraints) {
+ const MediaConstraints& constraints) {
DCHECK_CALLED_ON_VALID_THREAD(main_thread_);
int id = GetLocalIDForHandler(pc_handler);
if (id == -1)
@@ -859,7 +884,7 @@ void PeerConnectionTracker::TrackSetConfiguration(
void PeerConnectionTracker::TrackAddIceCandidate(
RTCPeerConnectionHandler* pc_handler,
- scoped_refptr<RTCIceCandidatePlatform> candidate,
+ RTCIceCandidatePlatform* candidate,
Source source,
bool succeeded) {
DCHECK_CALLED_ON_VALID_THREAD(main_thread_);
@@ -883,6 +908,28 @@ void PeerConnectionTracker::TrackAddIceCandidate(
SendPeerConnectionUpdate(id, event, value);
}
+void PeerConnectionTracker::TrackIceCandidateError(
+ RTCPeerConnectionHandler* pc_handler,
+ const String& address,
+ base::Optional<uint16_t> port,
+ const String& host_candidate,
+ const String& url,
+ int error_code,
+ const String& error_text) {
+ DCHECK_CALLED_ON_VALID_THREAD(main_thread_);
+ int id = GetLocalIDForHandler(pc_handler);
+ if (id == -1)
+ return;
+ String address_string = address ? "address: " + address + "\n" : String();
+ String port_string =
+ port.has_value() ? String::Format("port: %d\n", port.value()) : "";
+ String value = "url: " + url + "\n" + address_string + port_string +
+ "host_candidate: " + host_candidate + "\n" +
+ "error_text: " + error_text + "\n" +
+ "error_code: " + String::Number(error_code);
+ SendPeerConnectionUpdate(id, "icecandidateerror", value);
+}
+
void PeerConnectionTracker::TrackAddTransceiver(
RTCPeerConnectionHandler* pc_handler,
PeerConnectionTracker::TransceiverUpdatedReason reason,
@@ -1091,27 +1138,38 @@ void PeerConnectionTracker::TrackOnRenegotiationNeeded(
}
void PeerConnectionTracker::TrackGetUserMedia(
- const blink::WebUserMediaRequest& user_media_request) {
+ UserMediaRequest* user_media_request) {
DCHECK_CALLED_ON_VALID_THREAD(main_thread_);
+ // When running tests, it is possible that UserMediaRequest's
+ // ExecutionContext is null.
+ //
+ // TODO(crbug.com/704136): Is there a better way to do this?
+ String security_origin;
+ if (!user_media_request->GetExecutionContext()) {
+ security_origin =
+ SecurityOrigin::CreateFromString("test://test")->ToString();
+ } else {
+ security_origin = user_media_request->GetExecutionContext()
+ ->GetSecurityOrigin()
+ ->ToString();
+ }
+
peer_connection_tracker_host_->GetUserMedia(
- String(user_media_request.GetSecurityOrigin().ToString()),
- user_media_request.Audio(), user_media_request.Video(),
- SerializeMediaConstraints(user_media_request.AudioConstraints()),
- SerializeMediaConstraints(user_media_request.VideoConstraints()));
+ security_origin, user_media_request->Audio(), user_media_request->Video(),
+ SerializeMediaConstraints(user_media_request->AudioConstraints()),
+ SerializeMediaConstraints(user_media_request->VideoConstraints()));
}
void PeerConnectionTracker::TrackRtcEventLogWrite(
RTCPeerConnectionHandler* pc_handler,
- const std::string& output) {
+ const WTF::Vector<uint8_t>& output) {
DCHECK_CALLED_ON_VALID_THREAD(main_thread_);
int id = GetLocalIDForHandler(pc_handler);
if (id == -1)
return;
- WTF::Vector<uint8_t> converted_output;
- converted_output.AppendRange(output.begin(), output.end());
- peer_connection_tracker_host_->WebRtcEventLogWrite(id, converted_output);
+ peer_connection_tracker_host_->WebRtcEventLogWrite(id, output);
}
int PeerConnectionTracker::GetNextLocalID() {
@@ -1127,8 +1185,8 @@ int PeerConnectionTracker::GetLocalIDForHandler(
const auto found = peer_connection_local_id_map_.find(handler);
if (found == peer_connection_local_id_map_.end())
return -1;
- DCHECK_NE(found->second, -1);
- return found->second;
+ DCHECK_NE(found->value, -1);
+ return found->value;
}
void PeerConnectionTracker::SendPeerConnectionUpdate(
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 2ae2fd94226..069e01c1e41 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
@@ -5,18 +5,17 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_PEER_CONNECTION_TRACKER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_PEER_CONNECTION_TRACKER_H_
-#include <map>
-
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/peerconnection/peer_connection_tracker.mojom-blink.h"
-#include "third_party/blink/public/platform/web_rtc_peer_connection_handler_client.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_client.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h"
+#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/webrtc/api/peer_connection_interface.h"
@@ -25,13 +24,13 @@ class DataChannelInterface;
} // namespace webrtc
namespace blink {
+class MediaConstraints;
class RTCAnswerOptionsPlatform;
class RTCIceCandidatePlatform;
class RTCOfferOptionsPlatform;
class RTCPeerConnectionHandler;
+class UserMediaRequest;
class WebLocalFrame;
-class WebMediaConstraints;
-class WebUserMediaRequest;
// This class collects data about each peer connection,
// sends it to the browser process, and handles messages
@@ -42,13 +41,6 @@ class MODULES_EXPORT PeerConnectionTracker
public:
static PeerConnectionTracker* GetInstance();
- // TODO(crbug.com/787254): Make these ctors private, and accessible to
- // tests only.
- explicit PeerConnectionTracker(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
- PeerConnectionTracker(
- mojo::Remote<blink::mojom::blink::PeerConnectionTrackerHost> host,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
~PeerConnectionTracker() override;
enum Source { SOURCE_LOCAL, SOURCE_REMOTE };
@@ -89,7 +81,7 @@ class MODULES_EXPORT PeerConnectionTracker
void RegisterPeerConnection(
RTCPeerConnectionHandler* pc_handler,
const webrtc::PeerConnectionInterface::RTCConfiguration& config,
- const blink::WebMediaConstraints& constraints,
+ const MediaConstraints& constraints,
const blink::WebLocalFrame* frame);
// Sends an update when a PeerConnection has been destroyed.
@@ -102,11 +94,11 @@ class MODULES_EXPORT PeerConnectionTracker
RTCOfferOptionsPlatform* options);
// TODO(hta): Get rid of the version below.
virtual void TrackCreateOffer(RTCPeerConnectionHandler* pc_handler,
- const blink::WebMediaConstraints& options);
+ const MediaConstraints& options);
virtual void TrackCreateAnswer(RTCPeerConnectionHandler* pc_handler,
blink::RTCAnswerOptionsPlatform* options);
virtual void TrackCreateAnswer(RTCPeerConnectionHandler* pc_handler,
- const blink::WebMediaConstraints& constraints);
+ const MediaConstraints& constraints);
// Sends an update when setLocalDescription or setRemoteDescription is called.
virtual void TrackSetSessionDescription(RTCPeerConnectionHandler* pc_handler,
@@ -122,11 +114,18 @@ class MODULES_EXPORT PeerConnectionTracker
const webrtc::PeerConnectionInterface::RTCConfiguration& config);
// Sends an update when an Ice candidate is added.
- virtual void TrackAddIceCandidate(
- RTCPeerConnectionHandler* pc_handler,
- scoped_refptr<RTCIceCandidatePlatform> candidate,
- Source source,
- bool succeeded);
+ virtual void TrackAddIceCandidate(RTCPeerConnectionHandler* pc_handler,
+ RTCIceCandidatePlatform* candidate,
+ Source source,
+ bool succeeded);
+ // Sends an update when an Ice candidate error is receiver.
+ virtual void TrackIceCandidateError(RTCPeerConnectionHandler* pc_handler,
+ const String& address,
+ base::Optional<uint16_t> port,
+ const String& host_candidate,
+ const String& url,
+ int error_code,
+ const String& error_text);
// Sends an update when a transceiver is added, modified or removed. This can
// happen as a result of any of the methods indicated by |reason|.
@@ -213,16 +212,26 @@ class MODULES_EXPORT PeerConnectionTracker
virtual void TrackOnRenegotiationNeeded(RTCPeerConnectionHandler* pc_handler);
// Sends an update when getUserMedia is called.
- virtual void TrackGetUserMedia(
- const blink::WebUserMediaRequest& user_media_request);
+ virtual void TrackGetUserMedia(UserMediaRequest* user_media_request);
// Sends a new fragment on an RtcEventLog.
virtual void TrackRtcEventLogWrite(RTCPeerConnectionHandler* pc_handler,
- const std::string& output);
+ const WTF::Vector<uint8_t>& output);
private:
+ // For tests.
+ friend class PeerConnectionTrackerTest;
+ friend class MockPeerConnectionTracker;
+
+ FRIEND_TEST_ALL_PREFIXES(PeerConnectionTrackerTest, CreatingObject);
FRIEND_TEST_ALL_PREFIXES(PeerConnectionTrackerTest, OnSuspend);
+ explicit PeerConnectionTracker(
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
+ PeerConnectionTracker(
+ mojo::Remote<mojom::blink::PeerConnectionTrackerHost> host,
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
+
// Assign a local ID to a peer connection so that the browser process can
// uniquely identify a peer connection in the renderer process.
// The return value will always be positive.
@@ -265,7 +274,7 @@ class MODULES_EXPORT PeerConnectionTracker
void AddLegacyStats(int lid, base::Value value);
// This map stores the local ID assigned to each RTCPeerConnectionHandler.
- typedef std::map<RTCPeerConnectionHandler*, int> PeerConnectionLocalIdMap;
+ typedef WTF::HashMap<RTCPeerConnectionHandler*, int> PeerConnectionLocalIdMap;
PeerConnectionLocalIdMap peer_connection_local_id_map_;
// This keeps track of the next available 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 b8f61e22d0d..af78a085136 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
@@ -9,11 +9,11 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/peerconnection/peer_connection_tracker.mojom-blink.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
-#include "third_party/blink/public/platform/web_media_constraints.h"
#include "third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.h"
#include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h"
-#include "third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler_client.h"
+#include "third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_client.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/peerconnection/rtc_offer_options_platform.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"
@@ -123,14 +123,18 @@ class MockPeerConnectionHandler : public RTCPeerConnectionHandler {
: RTCPeerConnectionHandler(
&client_,
&dependency_factory_,
- blink::scheduler::GetSingleThreadTaskRunnerForTesting()) {}
+ blink::scheduler::GetSingleThreadTaskRunnerForTesting(),
+ /*force_encoded_audio_insertable_streams=*/false,
+ /*force_encoded_video_insertable_streams=*/false) {}
MOCK_METHOD0(CloseClientPeerConnection, void());
private:
blink::MockPeerConnectionDependencyFactory dependency_factory_;
- blink::MockWebRTCPeerConnectionHandlerClient client_;
+ MockRTCPeerConnectionHandlerClient client_;
};
+} // namespace
+
class PeerConnectionTrackerTest : public ::testing::Test {
public:
void CreateTrackerWithMocks() {
@@ -145,8 +149,8 @@ class PeerConnectionTrackerTest : public ::testing::Test {
EXPECT_CALL(*mock_host_, AddPeerConnection(_));
tracker_->RegisterPeerConnection(
mock_handler_.get(),
- webrtc::PeerConnectionInterface::RTCConfiguration(),
- blink::WebMediaConstraints(), nullptr);
+ webrtc::PeerConnectionInterface::RTCConfiguration(), MediaConstraints(),
+ nullptr);
base::RunLoop().RunUntilIdle();
}
@@ -156,8 +160,6 @@ class PeerConnectionTrackerTest : public ::testing::Test {
std::unique_ptr<MockPeerConnectionHandler> mock_handler_;
};
-} // namespace
-
TEST_F(PeerConnectionTrackerTest, CreatingObject) {
PeerConnectionTracker tracker(
blink::scheduler::GetSingleThreadTaskRunnerForTesting());
@@ -435,6 +437,28 @@ TEST_F(PeerConnectionTrackerTest, RemoveReceiver) {
EXPECT_EQ(expected_value, update_value);
}
+TEST_F(PeerConnectionTrackerTest, IceCandidateError) {
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ auto receiver_only = CreateDefaultTransceiver(
+ RTCRtpTransceiverPlatformImplementationType::kPlanBReceiverOnly);
+ String update_value;
+ EXPECT_CALL(*mock_host_,
+ UpdatePeerConnection(_, String("icecandidateerror"), _))
+ .WillOnce(testing::SaveArg<2>(&update_value));
+ tracker_->TrackIceCandidateError(mock_handler_.get(), "1.1.1.1", 15, "[::1]",
+ "test url", 404, "test error");
+ base::RunLoop().RunUntilIdle();
+ String expected_value(
+ "url: test url\n"
+ "address: 1.1.1.1\n"
+ "port: 15\n"
+ "host_candidate: [::1]\n"
+ "error_text: test error\n"
+ "error_code: 404");
+ EXPECT_EQ(expected_value, update_value);
+}
+
// TODO(hta): Write tests for the other tracking functions.
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate.h
index 76304d73009..c333fd856ee 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate.h
@@ -33,9 +33,9 @@
#include <memory>
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_dtls_fingerprint.h"
#include "third_party/blink/renderer/core/dom/dom_time_stamp.h"
#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_dtls_fingerprint.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_configuration.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_configuration.idl
index 662fb9a60d1..16352f50187 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_configuration.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_configuration.idl
@@ -54,5 +54,6 @@ dictionary RTCConfiguration {
[RuntimeEnabled=RtcAudioJitterBufferMaxPackets] long rtcAudioJitterBufferMaxPackets;
[RuntimeEnabled=RtcAudioJitterBufferMaxPackets] boolean rtcAudioJitterBufferFastAccelerate;
[RuntimeEnabled=RtcAudioJitterBufferMaxPackets] long rtcAudioJitterBufferMinDelayMs;
+ [RuntimeEnabled=RTCInsertableStreams] boolean forceEncodedAudioInsertableStreams = false;
+ [RuntimeEnabled=RTCInsertableStreams] boolean forceEncodedVideoInsertableStreams = false;
};
-
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 8503ad0fe75..96482dff902 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
@@ -31,14 +31,15 @@
#include "base/metrics/histogram_macros.h"
#include "third_party/blink/public/platform/task_type.h"
-#include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h"
#include "third_party/blink/renderer/core/events/message_event.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#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/rtc_error_event.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_platform.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/std_lib_extras.h"
@@ -126,6 +127,10 @@ static void ThrowNoBlobSupportException(ExceptionState* exception_state) {
"Blob support not implemented yet");
}
+static void ThrowBufferOverflowException(ExceptionState* exception_state) {
+ exception_state->ThrowRangeError("RTCDataChannel buffer overflow");
+}
+
RTCDataChannel::Observer::Observer(
scoped_refptr<base::SingleThreadTaskRunner> main_thread,
RTCDataChannel* blink_channel,
@@ -207,8 +212,8 @@ void RTCDataChannel::Observer::OnMessageImpl(
RTCDataChannel::RTCDataChannel(
ExecutionContext* context,
scoped_refptr<webrtc::DataChannelInterface> channel,
- WebRTCPeerConnectionHandler* peer_connection_handler)
- : ContextLifecycleObserver(context),
+ RTCPeerConnectionHandlerPlatform* peer_connection_handler)
+ : ExecutionContextLifecycleObserver(context),
state_(webrtc::DataChannelInterface::kConnecting),
binary_type_(kBinaryTypeArrayBuffer),
scheduled_event_timer_(context->GetTaskRunner(TaskType::kNetworking),
@@ -217,6 +222,7 @@ RTCDataChannel::RTCDataChannel(
buffered_amount_low_threshold_(0U),
buffered_amount_(0U),
stopped_(false),
+ closed_from_owner_(false),
observer_(base::MakeRefCounted<Observer>(
context->GetTaskRunner(TaskType::kNetworking),
this,
@@ -229,7 +235,7 @@ RTCDataChannel::RTCDataChannel(
// thread. Done in a single synchronous call to the signaling thread to ensure
// channel state consistency.
peer_connection_handler->RunSynchronousOnceClosureOnSignalingThread(
- ConvertToBaseOnceCallback(CrossThreadBindOnce(
+ CrossThreadBindOnce(
[](scoped_refptr<RTCDataChannel::Observer> observer,
webrtc::DataChannelInterface::DataState current_state) {
scoped_refptr<webrtc::DataChannelInterface> channel =
@@ -239,7 +245,7 @@ RTCDataChannel::RTCDataChannel(
observer->OnStateChange();
}
},
- observer_, state_)),
+ observer_, state_),
"RegisterObserverAndGetStateUpdate");
IncrementCounters(*channel.get());
@@ -262,6 +268,20 @@ bool RTCDataChannel::ordered() const {
return channel()->ordered();
}
+base::Optional<uint16_t> RTCDataChannel::maxPacketLifeTime() const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ if (channel()->maxPacketLifeTime())
+ return *channel()->maxPacketLifeTime();
+ return base::nullopt;
+}
+
+base::Optional<uint16_t> RTCDataChannel::maxRetransmits() const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ if (channel()->maxRetransmitsOpt())
+ return *channel()->maxRetransmitsOpt();
+ return base::nullopt;
+}
+
uint16_t RTCDataChannel::maxPacketLifeTime(bool& is_null) const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (channel()->maxPacketLifeTime()) {
@@ -292,6 +312,13 @@ bool RTCDataChannel::negotiated() const {
return channel()->negotiated();
}
+base::Optional<uint16_t> RTCDataChannel::id() const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ if (channel()->id() == -1)
+ return base::nullopt;
+ return channel()->id();
+}
+
uint16_t RTCDataChannel::id(bool& is_null) const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (channel()->id() == -1) {
@@ -360,6 +387,11 @@ void RTCDataChannel::send(const String& data, ExceptionState& exception_state) {
}
webrtc::DataBuffer data_buffer(data.Utf8());
+ if (!(base::CheckedNumeric<unsigned>(buffered_amount_) + data_buffer.size())
+ .IsValid()) {
+ ThrowBufferOverflowException(&exception_state);
+ return;
+ }
buffered_amount_ += data_buffer.size();
RecordMessageSent(*channel().get(), data_buffer.size());
if (!channel()->Send(data_buffer)) {
@@ -380,6 +412,11 @@ void RTCDataChannel::send(DOMArrayBuffer* data,
if (!data_length)
return;
+ if (!(base::CheckedNumeric<unsigned>(buffered_amount_) + data_length)
+ .IsValid()) {
+ ThrowBufferOverflowException(&exception_state);
+ return;
+ }
buffered_amount_ += data_length;
if (!SendRawData(static_cast<const char*>((data->Data())), data_length)) {
// TODO(https://crbug.com/937848): Don't throw an exception if data is
@@ -390,9 +427,15 @@ void RTCDataChannel::send(DOMArrayBuffer* data,
void RTCDataChannel::send(NotShared<DOMArrayBufferView> data,
ExceptionState& exception_state) {
- buffered_amount_ += data.View()->deprecatedByteLengthAsUnsigned();
+ if (!(base::CheckedNumeric<unsigned>(buffered_amount_) +
+ data.View()->byteLengthAsSizeT())
+ .IsValid()) {
+ ThrowBufferOverflowException(&exception_state);
+ return;
+ }
+ buffered_amount_ += data.View()->byteLengthAsSizeT();
if (!SendRawData(static_cast<const char*>(data.View()->BaseAddress()),
- data.View()->deprecatedByteLengthAsUnsigned())) {
+ data.View()->byteLengthAsSizeT())) {
// TODO(https://crbug.com/937848): Don't throw an exception if data is
// queued.
ThrowCouldNotSendDataException(&exception_state);
@@ -406,6 +449,7 @@ void RTCDataChannel::send(Blob* data, ExceptionState& exception_state) {
void RTCDataChannel::close() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ closed_from_owner_ = true;
if (observer_)
channel()->Close();
// Note that even though Close() will run synchronously, the readyState has
@@ -422,10 +466,10 @@ const AtomicString& RTCDataChannel::InterfaceName() const {
}
ExecutionContext* RTCDataChannel::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
-void RTCDataChannel::ContextDestroyed(ExecutionContext*) {
+void RTCDataChannel::ContextDestroyed() {
Dispose();
stopped_ = true;
state_ = webrtc::DataChannelInterface::kClosed;
@@ -438,9 +482,10 @@ bool RTCDataChannel::HasPendingActivity() const {
// A RTCDataChannel object must not be garbage collected if its
// * readyState is connecting and at least one event listener is registered
- // for open events, message events, error events, or close events.
+ // for open events, message events, error events, closing events
+ // or close events.
// * readyState is open and at least one event listener is registered for
- // message events, error events, or close events.
+ // message events, error events, closing events, or close events.
// * readyState is closing and at least one event listener is registered for
// error events, or close events.
// * underlying data transport is established and data is queued to be
@@ -451,7 +496,8 @@ bool RTCDataChannel::HasPendingActivity() const {
has_valid_listeners |= HasEventListeners(event_type_names::kOpen);
FALLTHROUGH;
case webrtc::DataChannelInterface::kOpen:
- has_valid_listeners |= HasEventListeners(event_type_names::kMessage);
+ has_valid_listeners |= HasEventListeners(event_type_names::kMessage) ||
+ HasEventListeners(event_type_names::kClosing);
FALLTHROUGH;
case webrtc::DataChannelInterface::kClosing:
has_valid_listeners |= HasEventListeners(event_type_names::kError) ||
@@ -471,7 +517,7 @@ bool RTCDataChannel::HasPendingActivity() const {
void RTCDataChannel::Trace(Visitor* visitor) {
visitor->Trace(scheduled_events_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
void RTCDataChannel::OnStateChange(
@@ -488,7 +534,16 @@ void RTCDataChannel::OnStateChange(
IncrementCounter(DataChannelCounters::kOpened);
ScheduleDispatchEvent(Event::Create(event_type_names::kOpen));
break;
+ case webrtc::DataChannelInterface::kClosing:
+ if (!closed_from_owner_) {
+ ScheduleDispatchEvent(Event::Create(event_type_names::kClosing));
+ }
+ break;
case webrtc::DataChannelInterface::kClosed:
+ if (!channel()->error().ok()) {
+ ScheduleDispatchEvent(MakeGarbageCollected<RTCErrorEvent>(
+ event_type_names::kError, channel()->error()));
+ }
ScheduleDispatchEvent(Event::Create(event_type_names::kClose));
break;
default:
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 5426427b7d2..fc5b72fc445 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
@@ -31,7 +31,7 @@
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -44,12 +44,12 @@ class Blob;
class DOMArrayBuffer;
class DOMArrayBufferView;
class ExceptionState;
-class WebRTCPeerConnectionHandler;
+class RTCPeerConnectionHandlerPlatform;
class MODULES_EXPORT RTCDataChannel final
: public EventTargetWithInlineData,
public ActiveScriptWrappable<RTCDataChannel>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(RTCDataChannel);
DEFINE_WRAPPERTYPEINFO();
USING_PRE_FINALIZER(RTCDataChannel, Dispose);
@@ -57,7 +57,7 @@ class MODULES_EXPORT RTCDataChannel final
public:
RTCDataChannel(ExecutionContext*,
scoped_refptr<webrtc::DataChannelInterface> channel,
- WebRTCPeerConnectionHandler* peer_connection_handler);
+ RTCPeerConnectionHandlerPlatform* peer_connection_handler);
~RTCDataChannel() override;
String label() const;
@@ -66,11 +66,16 @@ class MODULES_EXPORT RTCDataChannel final
bool reliable() const;
bool ordered() const;
- uint16_t maxPacketLifeTime(bool&) const;
- uint16_t maxRetransmits(bool&) const;
+ base::Optional<uint16_t> maxPacketLifeTime() const;
+ base::Optional<uint16_t> maxRetransmits() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ uint16_t maxPacketLifeTime(bool&) const; // DEPRECATED
+ uint16_t maxRetransmits(bool&) const; // DEPRECATED
String protocol() const;
bool negotiated() const;
- uint16_t id(bool& is_null) const;
+ base::Optional<uint16_t> id() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ uint16_t id(bool& is_null) const; // DEPRECATED
String readyState() const;
unsigned bufferedAmount() const;
@@ -91,19 +96,20 @@ class MODULES_EXPORT RTCDataChannel final
DEFINE_ATTRIBUTE_EVENT_LISTENER(bufferedamountlow, kBufferedamountlow)
DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
DEFINE_ATTRIBUTE_EVENT_LISTENER(close, kClose)
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(closing, kClosing)
DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage)
// EventTarget
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
// ScriptWrappable
bool HasPendingActivity() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
friend class Observer;
@@ -174,6 +180,7 @@ class MODULES_EXPORT RTCDataChannel final
unsigned buffered_amount_low_threshold_;
unsigned buffered_amount_;
bool stopped_;
+ bool closed_from_owner_;
scoped_refptr<Observer> observer_;
THREAD_CHECKER(thread_checker_);
};
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.idl
index 85f38c6f775..ceb685cc389 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.idl
@@ -51,6 +51,7 @@ enum RTCDataChannelState {
attribute EventHandler onopen;
attribute EventHandler onbufferedamountlow;
attribute EventHandler onerror;
+ attribute EventHandler onclosing;
attribute EventHandler onclose;
void close();
attribute EventHandler onmessage;
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 9ea073423aa..54df93f03ed 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(blink::Visitor* visitor) {
+void RTCDataChannelEvent::Trace(Visitor* visitor) {
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 e6efc564fd9..78e649a63f0 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
@@ -25,9 +25,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_DATA_CHANNEL_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_DATA_CHANNEL_EVENT_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_data_channel_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event_init.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
namespace blink {
@@ -50,7 +50,7 @@ class RTCDataChannelEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<RTCDataChannel> channel_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.idl
index 163432e0e7e..4851e3320d8 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.idl
@@ -26,8 +26,8 @@
// https://w3c.github.io/webrtc-pc/#rtcdatachannelevent
[
- Constructor(DOMString type, RTCDataChannelEventInit eventInitDict),
Exposed=Window
] interface RTCDataChannelEvent : Event {
+ constructor(DOMString type, RTCDataChannelEventInit eventInitDict);
readonly attribute 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 f1f242ffd47..428b8a47aa2 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
@@ -15,7 +15,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/testing/null_execution_context.h"
-#include "third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler.h"
+#include "third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.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/text/wtf_string.h"
@@ -45,14 +45,14 @@ void RunSynchronous(base::TestSimpleTaskRunner* thread,
waitable_event.Wait();
}
-class MockPeerConnectionHandler : public MockWebRTCPeerConnectionHandler {
+class MockPeerConnectionHandler : public MockRTCPeerConnectionHandlerPlatform {
public:
MockPeerConnectionHandler(
scoped_refptr<base::TestSimpleTaskRunner> signaling_thread)
: signaling_thread_(signaling_thread) {}
void RunSynchronousOnceClosureOnSignalingThread(
- base::OnceClosure closure,
+ CrossThreadOnceClosure closure,
const char* trace_event_name) override {
closure_ = std::move(closure);
RunSynchronous(
@@ -68,7 +68,7 @@ class MockPeerConnectionHandler : public MockWebRTCPeerConnectionHandler {
}
scoped_refptr<base::TestSimpleTaskRunner> signaling_thread_;
- base::OnceClosure closure_;
+ CrossThreadOnceClosure closure_;
DISALLOW_COPY_AND_ASSIGN(MockPeerConnectionHandler);
};
@@ -325,7 +325,7 @@ TEST_F(RTCDataChannelTest, SendAfterContextDestroyed) {
pc.get());
webrtc_channel->ChangeState(webrtc::DataChannelInterface::kOpen);
- channel->ContextDestroyed(nullptr);
+ channel->ContextDestroyed();
String message(std::string(100, 'A').c_str());
DummyExceptionStateForTesting exception_state;
@@ -344,7 +344,7 @@ TEST_F(RTCDataChannelTest, CloseAfterContextDestroyed) {
pc.get());
webrtc_channel->ChangeState(webrtc::DataChannelInterface::kOpen);
- channel->ContextDestroyed(nullptr);
+ channel->ContextDestroyed();
channel->close();
EXPECT_EQ(String::FromUTF8("closed"), channel->readyState());
}
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 e2cefe5aceb..e1e29bb8165 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(
ExecutionContext* context,
webrtc::DtlsTransportInterface* native_transport,
DtlsTransportProxy::Delegate* delegate) {
- LocalFrame* frame = To<Document>(context)->GetFrame();
+ LocalFrame* frame = Document::From(context)->GetFrame();
scoped_refptr<base::SingleThreadTaskRunner> proxy_thread =
frame->GetTaskRunner(TaskType::kNetworking);
scoped_refptr<base::SingleThreadTaskRunner> host_thread =
@@ -70,7 +70,7 @@ RTCDtlsTransport::RTCDtlsTransport(
ExecutionContext* context,
rtc::scoped_refptr<webrtc::DtlsTransportInterface> native_transport,
RTCIceTransport* ice_transport)
- : ContextClient(context),
+ : ExecutionContextClient(context),
current_state_(webrtc::DtlsTransportState::kNew),
native_transport_(native_transport),
proxy_(CreateProxy(context, native_transport, this)),
@@ -179,7 +179,7 @@ const AtomicString& RTCDtlsTransport::InterfaceName() const {
}
ExecutionContext* RTCDtlsTransport::GetExecutionContext() const {
- return ContextClient::GetExecutionContext();
+ return ExecutionContextClient::GetExecutionContext();
}
void RTCDtlsTransport::Trace(Visitor* visitor) {
@@ -187,7 +187,7 @@ void RTCDtlsTransport::Trace(Visitor* visitor) {
visitor->Trace(ice_transport_);
DtlsTransportProxy::Delegate::Trace(visitor);
EventTargetWithInlineData::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 04424f83b0e..36a5ff14885 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
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_DTLS_TRANSPORT_H_
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#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/peerconnection/adapters/dtls_transport_proxy.h"
#include "third_party/webrtc/api/dtls_transport_interface.h"
@@ -32,7 +32,7 @@ enum class RTCDtlsTransportState {
//
class MODULES_EXPORT RTCDtlsTransport final
: public EventTargetWithInlineData,
- public ContextClient,
+ public ExecutionContextClient,
public DtlsTransportProxy::Delegate {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(RTCDtlsTransport);
@@ -60,7 +60,7 @@ class MODULES_EXPORT RTCDtlsTransport final
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
// For garbage collection.
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
// Others
void ChangeState(webrtc::DtlsTransportInformation info);
webrtc::DtlsTransportInterface* native_transport();
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.idl
index c514ca92801..20708b3c93b 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.idl
@@ -13,8 +13,7 @@ enum RTCDtlsTransportState {
};
[
- Exposed=Window,
- RuntimeEnabled=RTCDtlsTransport
+ Exposed=Window
] interface RTCDtlsTransport : EventTarget {
readonly attribute RTCIceTransport iceTransport;
readonly attribute RTCDtlsTransportState state;
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 0860aa382fa..b7e226fc291 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
@@ -29,12 +29,12 @@
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_media_stream_track.h"
-#include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_track.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_platform.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
@@ -56,7 +56,7 @@ RTCDTMFSender* RTCDTMFSender::Create(
RTCDTMFSender::RTCDTMFSender(ExecutionContext* context,
std::unique_ptr<RtcDtmfSenderHandler> handler)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
handler_(std::move(handler)),
stopped_(false) {
handler_->SetClient(this);
@@ -142,7 +142,7 @@ void RTCDTMFSender::PlayoutTask() {
DispatchEvent(*event.Release());
return;
}
- WebString this_tone = tone_buffer_.Substring(0, 1);
+ String this_tone = tone_buffer_.Substring(0, 1);
tone_buffer_ = tone_buffer_.Substring(1, tone_buffer_.length() - 1);
// InsertDTMF handles both tones and ",", and calls DidPlayTone after
// the specified delay.
@@ -174,18 +174,18 @@ const AtomicString& RTCDTMFSender::InterfaceName() const {
}
ExecutionContext* RTCDTMFSender::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
-void RTCDTMFSender::ContextDestroyed(ExecutionContext*) {
+void RTCDTMFSender::ContextDestroyed() {
stopped_ = true;
handler_->SetClient(nullptr);
}
-void RTCDTMFSender::Trace(blink::Visitor* visitor) {
+void RTCDTMFSender::Trace(Visitor* visitor) {
EventTargetWithInlineData::Trace(visitor);
RtcDtmfSenderHandler::Client::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 0c920e1debf..c100eb4c154 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
@@ -27,7 +27,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_DTMF_SENDER_H_
#include <memory>
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#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/platform/peerconnection/rtc_dtmf_sender_handler.h"
#include "third_party/blink/renderer/platform/timer.h"
@@ -39,7 +39,7 @@ class RtcDtmfSenderHandler;
class RTCDTMFSender final : public EventTargetWithInlineData,
public RtcDtmfSenderHandler::Client,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(RTCDTMFSender);
DEFINE_WRAPPERTYPEINFO();
USING_PRE_FINALIZER(RTCDTMFSender, Dispose);
@@ -67,10 +67,10 @@ class RTCDTMFSender final : public EventTargetWithInlineData,
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 8b321187763..e0ef02556e9 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(blink::Visitor* visitor) {
+void RTCDTMFToneChangeEvent::Trace(Visitor* visitor) {
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 46db919c524..88dcddac178 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
@@ -26,8 +26,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_DTMF_TONE_CHANGE_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_DTMF_TONE_CHANGE_EVENT_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_dtmf_tone_change_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event_init.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
namespace blink {
@@ -49,7 +49,7 @@ class RTCDTMFToneChangeEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
String tone_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.idl
index 69a67ae9a32..9323e54eb6f 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.idl
@@ -26,8 +26,8 @@
// https://w3c.github.io/webrtc-pc/#rtcdtmftonechangeevent
[
- Exposed=Window,
- Constructor(DOMString type, RTCDTMFToneChangeEventInit eventInitDict)
+ Exposed=Window
] interface RTCDTMFToneChangeEvent : Event {
+ constructor(DOMString type, RTCDTMFToneChangeEventInit eventInitDict);
readonly attribute DOMString 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
new file mode 100644
index 00000000000..6dbaa7fedf7
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.cc
@@ -0,0 +1,100 @@
+// 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/peerconnection/rtc_encoded_audio_frame.h"
+
+#include <utility>
+
+#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_delegate.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
+#include "third_party/webrtc/api/frame_transformer_interface.h"
+
+namespace blink {
+
+RTCEncodedAudioFrame::RTCEncodedAudioFrame(
+ std::unique_ptr<webrtc::TransformableFrameInterface> webrtc_frame)
+ : delegate_(base::MakeRefCounted<RTCEncodedAudioFrameDelegate>(
+ std::move(webrtc_frame),
+ Vector<uint32_t>())) {}
+
+RTCEncodedAudioFrame::RTCEncodedAudioFrame(
+ std::unique_ptr<webrtc::TransformableAudioFrameInterface>
+ webrtc_audio_frame) {
+ Vector<uint32_t> contributing_sources;
+ if (webrtc_audio_frame) {
+ wtf_size_t num_csrcs = webrtc_audio_frame->GetHeader().numCSRCs;
+ contributing_sources.ReserveInitialCapacity(num_csrcs);
+ for (wtf_size_t i = 0; i < num_csrcs; i++) {
+ contributing_sources.push_back(
+ webrtc_audio_frame->GetHeader().arrOfCSRCs[i]);
+ }
+ }
+ delegate_ = base::MakeRefCounted<RTCEncodedAudioFrameDelegate>(
+ std::move(webrtc_audio_frame), std::move(contributing_sources));
+}
+
+RTCEncodedAudioFrame::RTCEncodedAudioFrame(
+ scoped_refptr<RTCEncodedAudioFrameDelegate> delegate)
+ : delegate_(std::move(delegate)) {}
+
+uint64_t RTCEncodedAudioFrame::timestamp() const {
+ return delegate_->Timestamp();
+}
+
+DOMArrayBuffer* RTCEncodedAudioFrame::data() const {
+ if (!frame_data_) {
+ frame_data_ = delegate_->CreateDataBuffer();
+ }
+ return frame_data_;
+}
+
+DOMArrayBuffer* RTCEncodedAudioFrame::additionalData() const {
+ return nullptr;
+}
+
+void RTCEncodedAudioFrame::setData(DOMArrayBuffer* data) {
+ frame_data_ = data;
+}
+
+uint32_t RTCEncodedAudioFrame::synchronizationSource() const {
+ return delegate_->Ssrc();
+}
+
+Vector<uint32_t> RTCEncodedAudioFrame::contributingSources() const {
+ return delegate_->ContributingSources();
+}
+
+String RTCEncodedAudioFrame::toString() const {
+ StringBuilder sb;
+ sb.Append("RTCEncodedAudioFrame{timestamp: ");
+ sb.AppendNumber(timestamp());
+ sb.Append("us, size: ");
+ sb.AppendNumber(data() ? data()->ByteLengthAsSizeT() : 0);
+ sb.Append("}");
+ return sb.ToString();
+}
+
+void RTCEncodedAudioFrame::SyncDelegate() const {
+ delegate_->SetData(frame_data_);
+}
+
+scoped_refptr<RTCEncodedAudioFrameDelegate> RTCEncodedAudioFrame::Delegate()
+ const {
+ SyncDelegate();
+ return delegate_;
+}
+
+std::unique_ptr<webrtc::TransformableFrameInterface>
+RTCEncodedAudioFrame::PassWebRtcFrame() {
+ SyncDelegate();
+ return delegate_->PassWebRtcFrame();
+}
+
+void RTCEncodedAudioFrame::Trace(Visitor* visitor) {
+ ScriptWrappable::Trace(visitor);
+ visitor->Trace(frame_data_);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..1e11e9ed04e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.h
@@ -0,0 +1,63 @@
+// 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_PEERCONNECTION_RTC_ENCODED_AUDIO_FRAME_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ENCODED_AUDIO_FRAME_H_
+
+#include <stdint.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"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace webrtc {
+class TransformableAudioFrameInterface;
+class TransformableFrameInterface;
+} // namespace webrtc
+
+namespace blink {
+
+class DOMArrayBuffer;
+class RTCEncodedAudioFrameDelegate;
+
+class MODULES_EXPORT RTCEncodedAudioFrame final : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ explicit RTCEncodedAudioFrame(
+ std::unique_ptr<webrtc::TransformableFrameInterface> webrtc_frame);
+ explicit RTCEncodedAudioFrame(
+ std::unique_ptr<webrtc::TransformableAudioFrameInterface> webrtc_frame);
+ explicit RTCEncodedAudioFrame(
+ scoped_refptr<RTCEncodedAudioFrameDelegate> delegate);
+
+ // rtc_encoded_audio_frame.idl implementation.
+ uint64_t timestamp() const;
+ DOMArrayBuffer* data() const;
+ DOMArrayBuffer* additionalData() const;
+ void setData(DOMArrayBuffer*);
+ uint32_t synchronizationSource() const;
+ Vector<uint32_t> contributingSources() const;
+ String toString() const;
+
+ scoped_refptr<RTCEncodedAudioFrameDelegate> Delegate() const;
+ void SyncDelegate() const;
+
+ // Returns and transfers ownership of the internal WebRTC frame
+ // backing this RTCEncodedAudioFrame, neutering all RTCEncodedAudioFrames
+ // backed by that internal WebRTC frame.
+ std::unique_ptr<webrtc::TransformableFrameInterface> PassWebRtcFrame();
+
+ void Trace(Visitor*) override;
+
+ private:
+ scoped_refptr<RTCEncodedAudioFrameDelegate> delegate_;
+ Vector<uint32_t> contributing_sources_;
+ mutable Member<DOMArrayBuffer> frame_data_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ENCODED_AUDIO_FRAME_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.idl
new file mode 100644
index 00000000000..a5996bcc121
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.idl
@@ -0,0 +1,19 @@
+// 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/alvestrand/webrtc-media-streams/blob/master/explainer.md#api
+// TODO(crbug.com/1052765): Add link to standard when available.
+
+// TODO(crbug.com/1052765): Align with WebCodecs definition once it is stable.
+[RuntimeEnabled=RTCInsertableStreams]
+interface RTCEncodedAudioFrame {
+ readonly attribute unsigned long long timestamp; // microseconds
+ attribute ArrayBuffer data;
+ // TODO(crbug.com/1052765): Replace the following fields with a dictionary
+ // with structured data once we have decided what will be exposed.
+ readonly attribute ArrayBuffer additionalData;
+ readonly attribute unsigned long synchronizationSource;
+ readonly attribute FrozenArray<unsigned long> contributingSources;
+ stringifier;
+};
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_delegate.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_delegate.cc
new file mode 100644
index 00000000000..2c71c02c522
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_delegate.cc
@@ -0,0 +1,68 @@
+// 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/peerconnection/rtc_encoded_audio_frame_delegate.h"
+
+#include <utility>
+
+#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
+
+namespace blink {
+
+const void* RTCEncodedAudioFramesAttachment::kAttachmentKey;
+
+RTCEncodedAudioFrameDelegate::RTCEncodedAudioFrameDelegate(
+ std::unique_ptr<webrtc::TransformableFrameInterface> webrtc_frame,
+ Vector<uint32_t> contributing_sources)
+ : webrtc_frame_(std::move(webrtc_frame)),
+ contributing_sources_(std::move(contributing_sources)) {}
+
+uint64_t RTCEncodedAudioFrameDelegate::Timestamp() const {
+ MutexLocker lock(mutex_);
+ return webrtc_frame_ ? webrtc_frame_->GetTimestamp() : 0;
+}
+
+DOMArrayBuffer* RTCEncodedAudioFrameDelegate::CreateDataBuffer() const {
+ ArrayBufferContents contents;
+ {
+ MutexLocker lock(mutex_);
+ if (!webrtc_frame_)
+ return nullptr;
+
+ auto data = webrtc_frame_->GetData();
+ contents =
+ ArrayBufferContents(data.size(), 1, ArrayBufferContents::kNotShared,
+ ArrayBufferContents::kDontInitialize);
+ if (UNLIKELY(!contents.Data()))
+ OOM_CRASH(data.size());
+ memcpy(contents.Data(), data.data(), data.size());
+ }
+ return DOMArrayBuffer::Create(std::move(contents));
+}
+
+void RTCEncodedAudioFrameDelegate::SetData(const DOMArrayBuffer* data) {
+ MutexLocker lock(mutex_);
+ if (webrtc_frame_ && data) {
+ webrtc_frame_->SetData(rtc::ArrayView<const uint8_t>(
+ static_cast<const uint8_t*>(data->Data()), data->ByteLengthAsSizeT()));
+ }
+}
+
+uint32_t RTCEncodedAudioFrameDelegate::Ssrc() const {
+ MutexLocker lock(mutex_);
+ return webrtc_frame_ ? webrtc_frame_->GetSsrc() : 0;
+}
+
+Vector<uint32_t> RTCEncodedAudioFrameDelegate::ContributingSources() const {
+ MutexLocker lock(mutex_);
+ return contributing_sources_;
+}
+
+std::unique_ptr<webrtc::TransformableFrameInterface>
+RTCEncodedAudioFrameDelegate::PassWebRtcFrame() {
+ MutexLocker lock(mutex_);
+ return std::move(webrtc_frame_);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_delegate.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_delegate.h
new file mode 100644
index 00000000000..90853ecfa32
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_delegate.h
@@ -0,0 +1,72 @@
+// 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_PEERCONNECTION_RTC_ENCODED_AUDIO_FRAME_DELEGATE_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ENCODED_AUDIO_FRAME_DELEGATE_H_
+
+#include <stdint.h>
+
+#include <memory>
+
+#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#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"
+
+namespace blink {
+
+class DOMArrayBuffer;
+
+// This class wraps a WebRTC audio frame and allows making shallow
+// copies. Its purpose is to support making RTCEncodedVideoFrames
+// serializable in the same process.
+class RTCEncodedAudioFrameDelegate
+ : public WTF::ThreadSafeRefCounted<RTCEncodedAudioFrameDelegate> {
+ public:
+ explicit RTCEncodedAudioFrameDelegate(
+ std::unique_ptr<webrtc::TransformableFrameInterface> webrtc_frame,
+ Vector<uint32_t> contributing_sources);
+
+ uint64_t Timestamp() const;
+ DOMArrayBuffer* CreateDataBuffer() const;
+ void SetData(const DOMArrayBuffer* data);
+ uint32_t Ssrc() const;
+ Vector<uint32_t> ContributingSources() const;
+ std::unique_ptr<webrtc::TransformableFrameInterface> PassWebRtcFrame();
+
+ private:
+ mutable Mutex mutex_;
+ std::unique_ptr<webrtc::TransformableFrameInterface> webrtc_frame_
+ GUARDED_BY(mutex_);
+ Vector<uint32_t> contributing_sources_;
+};
+
+class MODULES_EXPORT RTCEncodedAudioFramesAttachment
+ : public SerializedScriptValue::Attachment {
+ public:
+ static const void* kAttachmentKey;
+ RTCEncodedAudioFramesAttachment() = default;
+ ~RTCEncodedAudioFramesAttachment() override = default;
+
+ bool IsLockedToAgentCluster() const override {
+ return !encoded_audio_frames_.IsEmpty();
+ }
+
+ Vector<scoped_refptr<RTCEncodedAudioFrameDelegate>>& EncodedAudioFrames() {
+ return encoded_audio_frames_;
+ }
+
+ const Vector<scoped_refptr<RTCEncodedAudioFrameDelegate>>&
+ EncodedAudioFrames() const {
+ return encoded_audio_frames_;
+ }
+
+ private:
+ Vector<scoped_refptr<RTCEncodedAudioFrameDelegate>> encoded_audio_frames_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ENCODED_AUDIO_FRAME_DELEGATE_H_
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
new file mode 100644
index 00000000000..81441387008
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.cc
@@ -0,0 +1,88 @@
+// 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/peerconnection/rtc_encoded_audio_underlying_sink.h"
+
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_encoded_audio_frame.h"
+#include "third_party/blink/renderer/core/dom/dom_exception.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_encoded_audio_stream_transformer.h"
+#include "third_party/webrtc/api/frame_transformer_interface.h"
+
+namespace blink {
+
+RTCEncodedAudioUnderlyingSink::RTCEncodedAudioUnderlyingSink(
+ ScriptState* script_state,
+ TransformerCallback transformer_callback)
+ : transformer_callback_(std::move(transformer_callback)) {
+ DCHECK(transformer_callback_);
+}
+
+ScriptPromise RTCEncodedAudioUnderlyingSink::start(
+ ScriptState* script_state,
+ WritableStreamDefaultController* controller,
+ ExceptionState&) {
+ // No extra setup needed.
+ return ScriptPromise::CastUndefined(script_state);
+}
+
+ScriptPromise RTCEncodedAudioUnderlyingSink::write(
+ ScriptState* script_state,
+ ScriptValue chunk,
+ WritableStreamDefaultController* controller,
+ ExceptionState& exception_state) {
+ RTCEncodedAudioFrame* encoded_frame =
+ V8RTCEncodedAudioFrame::ToImplWithTypeCheck(script_state->GetIsolate(),
+ chunk.V8Value());
+ if (!encoded_frame) {
+ exception_state.ThrowTypeError("Invalid frame");
+ return ScriptPromise();
+ }
+
+ if (!transformer_callback_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Stream closed");
+ return ScriptPromise();
+ }
+
+ auto webrtc_frame = encoded_frame->PassWebRtcFrame();
+ if (!webrtc_frame) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kOperationError,
+ "Empty frame");
+ return ScriptPromise();
+ }
+
+ RTCEncodedAudioStreamTransformer* transformer = transformer_callback_.Run();
+ if (!transformer) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "No underlying sink");
+ return ScriptPromise();
+ }
+
+ transformer->SendFrameToSink(std::move(webrtc_frame));
+ return ScriptPromise::CastUndefined(script_state);
+}
+
+ScriptPromise RTCEncodedAudioUnderlyingSink::close(ScriptState* script_state,
+ ExceptionState&) {
+ // Disconnect from the transformer if the sink is closed.
+ if (transformer_callback_)
+ transformer_callback_.Reset();
+ return ScriptPromise::CastUndefined(script_state);
+}
+
+ScriptPromise RTCEncodedAudioUnderlyingSink::abort(
+ ScriptState* script_state,
+ ScriptValue reason,
+ ExceptionState& exception_state) {
+ // It is not possible to cancel any frames already sent to the WebRTC sink,
+ // thus abort() has the same effect as close().
+ return close(script_state, exception_state);
+}
+
+void RTCEncodedAudioUnderlyingSink::Trace(Visitor* visitor) {
+ UnderlyingSinkBase::Trace(visitor);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..152606c43f3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.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_MODULES_PEERCONNECTION_RTC_ENCODED_AUDIO_UNDERLYING_SINK_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ENCODED_AUDIO_UNDERLYING_SINK_H_
+
+#include "third_party/blink/renderer/core/streams/underlying_sink_base.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+
+namespace blink {
+
+class ExceptionState;
+class RTCEncodedAudioStreamTransformer;
+
+class MODULES_EXPORT RTCEncodedAudioUnderlyingSink final
+ : public UnderlyingSinkBase {
+ public:
+ using TransformerCallback =
+ base::RepeatingCallback<RTCEncodedAudioStreamTransformer*()>;
+ RTCEncodedAudioUnderlyingSink(ScriptState*, TransformerCallback);
+
+ // UnderlyingSinkBase
+ ScriptPromise start(ScriptState*,
+ WritableStreamDefaultController*,
+ ExceptionState&) override;
+ ScriptPromise write(ScriptState*,
+ ScriptValue chunk,
+ WritableStreamDefaultController*,
+ ExceptionState&) override;
+ ScriptPromise close(ScriptState*, ExceptionState&) override;
+ ScriptPromise abort(ScriptState*,
+ ScriptValue reason,
+ ExceptionState&) override;
+
+ void Trace(Visitor*) override;
+
+ private:
+ TransformerCallback transformer_callback_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ENCODED_AUDIO_UNDERLYING_SINK_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink_test.cc
new file mode 100644
index 00000000000..ad703c4bdea
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink_test.cc
@@ -0,0 +1,182 @@
+// 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/peerconnection/rtc_encoded_audio_underlying_sink.h"
+
+#include "base/memory/scoped_refptr.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/bindings/core/v8/script_promise_tester.h"
+#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_encoded_audio_frame.h"
+#include "third_party/blink/renderer/core/streams/writable_stream.h"
+#include "third_party/blink/renderer/core/streams/writable_stream_default_writer.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_encoded_audio_stream_transformer.h"
+#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+#include "third_party/webrtc/api/frame_transformer_interface.h"
+#include "third_party/webrtc/api/scoped_refptr.h"
+#include "third_party/webrtc/rtc_base/ref_counted_object.h"
+
+using testing::_;
+
+namespace blink {
+
+namespace {
+
+class MockWebRtcTransformedFrameCallback
+ : public webrtc::TransformedFrameCallback {
+ public:
+ MOCK_METHOD1(OnTransformedFrame,
+ void(std::unique_ptr<webrtc::TransformableFrameInterface>));
+};
+
+class FakeAudioFrame : public webrtc::TransformableFrameInterface {
+ public:
+ 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 0xDEADBEEF; }
+ uint32_t GetSsrc() const override { return 0; }
+};
+
+bool IsDOMException(ScriptState* script_state,
+ ScriptValue value,
+ DOMExceptionCode code) {
+ auto* dom_exception = V8DOMException::ToImplWithTypeCheck(
+ script_state->GetIsolate(), value.V8Value());
+ if (!dom_exception)
+ return false;
+
+ return dom_exception->code() == static_cast<uint16_t>(code);
+}
+
+} // namespace
+
+class RTCEncodedAudioUnderlyingSinkTest : public testing::Test {
+ public:
+ RTCEncodedAudioUnderlyingSinkTest()
+ : main_task_runner_(
+ blink::scheduler::GetSingleThreadTaskRunnerForTesting()),
+ webrtc_callback_(
+ new rtc::RefCountedObject<MockWebRtcTransformedFrameCallback>()),
+ transformer_(main_task_runner_) {}
+
+ void SetUp() override {
+ EXPECT_FALSE(transformer_.HasTransformedFrameCallback());
+ transformer_.RegisterTransformedFrameCallback(webrtc_callback_);
+ EXPECT_TRUE(transformer_.HasTransformedFrameCallback());
+ }
+
+ void TearDown() override {
+ platform_->RunUntilIdle();
+ transformer_.UnregisterTransformedFrameCallback();
+ EXPECT_FALSE(transformer_.HasTransformedFrameCallback());
+ }
+
+ RTCEncodedAudioUnderlyingSink* CreateSink(ScriptState* script_state) {
+ return MakeGarbageCollected<RTCEncodedAudioUnderlyingSink>(
+ script_state,
+ WTF::BindRepeating(&RTCEncodedAudioUnderlyingSinkTest::GetTransformer,
+ WTF::Unretained(this)));
+ }
+
+ RTCEncodedAudioUnderlyingSink* CreateNullCallbackSink(
+ ScriptState* script_state) {
+ return MakeGarbageCollected<RTCEncodedAudioUnderlyingSink>(
+ script_state,
+ WTF::BindRepeating(
+ []() -> RTCEncodedAudioStreamTransformer* { return nullptr; }));
+ }
+
+ RTCEncodedAudioStreamTransformer* GetTransformer() { return &transformer_; }
+
+ ScriptValue CreateEncodedAudioFrameChunk(ScriptState* script_state) {
+ RTCEncodedAudioFrame* frame = MakeGarbageCollected<RTCEncodedAudioFrame>(
+ std::make_unique<FakeAudioFrame>());
+ return ScriptValue(script_state->GetIsolate(),
+ ToV8(frame, script_state->GetContext()->Global(),
+ script_state->GetIsolate()));
+ }
+
+ protected:
+ ScopedTestingPlatformSupport<TestingPlatformSupport> platform_;
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ rtc::scoped_refptr<MockWebRtcTransformedFrameCallback> webrtc_callback_;
+ RTCEncodedAudioStreamTransformer transformer_;
+};
+
+TEST_F(RTCEncodedAudioUnderlyingSinkTest,
+ WriteToStreamForwardsToWebRtcCallback) {
+ V8TestingScope v8_scope;
+ ScriptState* script_state = v8_scope.GetScriptState();
+ auto* sink = CreateSink(script_state);
+ auto* stream =
+ WritableStream::CreateWithCountQueueingStrategy(script_state, sink, 1u);
+
+ NonThrowableExceptionState exception_state;
+ auto* writer = stream->getWriter(script_state, exception_state);
+
+ EXPECT_CALL(*webrtc_callback_, OnTransformedFrame(_));
+ ScriptPromiseTester write_tester(
+ script_state,
+ writer->write(script_state, CreateEncodedAudioFrameChunk(script_state),
+ exception_state));
+ EXPECT_FALSE(write_tester.IsFulfilled());
+
+ writer->releaseLock(script_state);
+ ScriptPromiseTester close_tester(
+ script_state, stream->close(script_state, exception_state));
+ close_tester.WaitUntilSettled();
+
+ // Writing to the sink after the stream closes should fail.
+ DummyExceptionStateForTesting dummy_exception_state;
+ sink->write(script_state, CreateEncodedAudioFrameChunk(script_state), nullptr,
+ dummy_exception_state);
+ EXPECT_TRUE(dummy_exception_state.HadException());
+ EXPECT_EQ(dummy_exception_state.Code(),
+ static_cast<ExceptionCode>(DOMExceptionCode::kInvalidStateError));
+}
+
+TEST_F(RTCEncodedAudioUnderlyingSinkTest, WriteInvalidDataFails) {
+ V8TestingScope v8_scope;
+ ScriptState* script_state = v8_scope.GetScriptState();
+ auto* sink = CreateSink(script_state);
+ ScriptValue v8_integer = ScriptValue::From(script_state, 0);
+
+ // Writing something that is not an RTCEncodedAudioFrame integer to the sink
+ // should fail.
+ DummyExceptionStateForTesting dummy_exception_state;
+ sink->write(script_state, v8_integer, nullptr, dummy_exception_state);
+ EXPECT_TRUE(dummy_exception_state.HadException());
+}
+
+TEST_F(RTCEncodedAudioUnderlyingSinkTest, WriteToNullCallbackSinkFails) {
+ V8TestingScope v8_scope;
+ ScriptState* script_state = v8_scope.GetScriptState();
+ auto* sink = CreateNullCallbackSink(script_state);
+ auto* stream =
+ WritableStream::CreateWithCountQueueingStrategy(script_state, sink, 1u);
+
+ NonThrowableExceptionState exception_state;
+ auto* writer = stream->getWriter(script_state, exception_state);
+
+ EXPECT_CALL(*webrtc_callback_, OnTransformedFrame(_)).Times(0);
+ ScriptPromiseTester write_tester(
+ script_state,
+ writer->write(script_state, CreateEncodedAudioFrameChunk(script_state),
+ exception_state));
+ write_tester.WaitUntilSettled();
+ EXPECT_TRUE(write_tester.IsRejected());
+ EXPECT_TRUE(IsDOMException(script_state, write_tester.Value(),
+ DOMExceptionCode::kInvalidStateError));
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..91addd31f78
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.cc
@@ -0,0 +1,88 @@
+// 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/peerconnection/rtc_encoded_audio_underlying_source.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
+#include "third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.h"
+#include "third_party/blink/renderer/platform/bindings/exception_code.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+#include "third_party/webrtc/api/frame_transformer_interface.h"
+
+namespace blink {
+
+// Frames should not be queued at all. We allow queuing a few frames to deal
+// with transient slowdowns. Specified as a negative number of frames since
+// queuing is reported by the stream controller as a negative desired size.
+const int RTCEncodedAudioUnderlyingSource::kMinQueueDesiredSize = -60;
+
+RTCEncodedAudioUnderlyingSource::RTCEncodedAudioUnderlyingSource(
+ ScriptState* script_state,
+ base::OnceClosure disconnect_callback,
+ bool is_receiver)
+ : UnderlyingSourceBase(script_state),
+ script_state_(script_state),
+ disconnect_callback_(std::move(disconnect_callback)),
+ is_receiver_(is_receiver) {
+ DCHECK(disconnect_callback_);
+}
+
+ScriptPromise RTCEncodedAudioUnderlyingSource::pull(ScriptState* script_state) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ // WebRTC is a push source without backpressure support, so nothing to do
+ // here.
+ return ScriptPromise::CastUndefined(script_state);
+}
+
+ScriptPromise RTCEncodedAudioUnderlyingSource::Cancel(ScriptState* script_state,
+ ScriptValue reason) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ if (disconnect_callback_)
+ std::move(disconnect_callback_).Run();
+ return ScriptPromise::CastUndefined(script_state);
+}
+
+void RTCEncodedAudioUnderlyingSource::Trace(Visitor* visitor) {
+ visitor->Trace(script_state_);
+ UnderlyingSourceBase::Trace(visitor);
+}
+
+void RTCEncodedAudioUnderlyingSource::OnFrameFromSource(
+ std::unique_ptr<webrtc::TransformableFrameInterface> webrtc_frame) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ // If the source is canceled or there are too many queued frames,
+ // drop the new frame.
+ if (!disconnect_callback_ || !Controller() ||
+ Controller()->DesiredSize() <= kMinQueueDesiredSize) {
+ return;
+ }
+
+ RTCEncodedAudioFrame* encoded_frame = nullptr;
+ if (is_receiver_) {
+ // Receivers produce frames as webrtc::TransformableAudioFrameInterface,
+ // which allows exposing the CSRCs.
+ std::unique_ptr<webrtc::TransformableAudioFrameInterface> audio_frame =
+ base::WrapUnique(static_cast<webrtc::TransformableAudioFrameInterface*>(
+ webrtc_frame.release()));
+ encoded_frame =
+ MakeGarbageCollected<RTCEncodedAudioFrame>(std::move(audio_frame));
+ } else {
+ encoded_frame =
+ MakeGarbageCollected<RTCEncodedAudioFrame>(std::move(webrtc_frame));
+ }
+ Controller()->Enqueue(encoded_frame);
+}
+
+void RTCEncodedAudioUnderlyingSource::Close() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ if (disconnect_callback_)
+ std::move(disconnect_callback_).Run();
+
+ if (Controller())
+ Controller()->Close();
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..7ee6684a9eb
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.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_MODULES_PEERCONNECTION_RTC_ENCODED_AUDIO_UNDERLYING_SOURCE_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ENCODED_AUDIO_UNDERLYING_SOURCE_H_
+
+#include "base/threading/thread_checker.h"
+#include "third_party/blink/renderer/core/streams/underlying_source_base.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+
+namespace webrtc {
+class TransformableFrameInterface;
+} // namespace webrtc
+
+namespace blink {
+
+class MODULES_EXPORT RTCEncodedAudioUnderlyingSource
+ : public UnderlyingSourceBase {
+ public:
+ explicit RTCEncodedAudioUnderlyingSource(
+ ScriptState*,
+ base::OnceClosure disconnect_callback,
+ bool is_receiver);
+
+ // UnderlyingSourceBase
+ ScriptPromise pull(ScriptState*) override;
+ ScriptPromise Cancel(ScriptState*, ScriptValue reason) override;
+
+ void OnFrameFromSource(std::unique_ptr<webrtc::TransformableFrameInterface>);
+ void Close();
+
+ void Trace(Visitor*) override;
+
+ private:
+ FRIEND_TEST_ALL_PREFIXES(RTCEncodedAudioUnderlyingSourceTest,
+ QueuedFramesAreDroppedWhenOverflow);
+ static const int kMinQueueDesiredSize;
+
+ const Member<ScriptState> script_state_;
+ base::OnceClosure disconnect_callback_;
+ // Indicates if this source is for a receiver. Receiver sources
+ // expose CSRCs.
+ const bool is_receiver_;
+ THREAD_CHECKER(thread_checker_);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ENCODED_AUDIO_UNDERLYING_SOURCE_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source_test.cc
new file mode 100644
index 00000000000..297f93e3303
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source_test.cc
@@ -0,0 +1,104 @@
+// 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/peerconnection/rtc_encoded_audio_underlying_source.h"
+#include <memory>
+
+#include "base/test/mock_callback.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.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_rtc_encoded_audio_frame.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/modules/peerconnection/rtc_encoded_audio_frame.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/webrtc/api/frame_transformer_interface.h"
+
+namespace blink {
+
+namespace {
+class FakeTransformableFrame : public webrtc::TransformableFrameInterface {
+ 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; }
+};
+} // namespace
+
+class RTCEncodedAudioUnderlyingSourceTest : public testing::Test {
+ public:
+ RTCEncodedAudioUnderlyingSource* CreateSource(ScriptState* script_state,
+ bool is_receiver = false) {
+ return MakeGarbageCollected<RTCEncodedAudioUnderlyingSource>(
+ script_state, WTF::Bind(disconnect_callback_.Get()), is_receiver);
+ }
+
+ protected:
+ base::MockOnceClosure disconnect_callback_;
+};
+
+TEST_F(RTCEncodedAudioUnderlyingSourceTest,
+ SourceDataFlowsThroughStreamAndCloses) {
+ V8TestingScope v8_scope;
+ ScriptState* script_state = v8_scope.GetScriptState();
+ auto* source = CreateSource(script_state);
+ auto* stream =
+ ReadableStream::CreateWithCountQueueingStrategy(script_state, source, 0);
+
+ NonThrowableExceptionState exception_state;
+ auto* reader = stream->getReader(script_state, exception_state);
+
+ ScriptPromiseTester read_tester(script_state,
+ reader->read(script_state, exception_state));
+ EXPECT_FALSE(read_tester.IsFulfilled());
+ source->OnFrameFromSource(std::make_unique<FakeTransformableFrame>());
+ read_tester.WaitUntilSettled();
+ EXPECT_TRUE(read_tester.IsFulfilled());
+
+ EXPECT_CALL(disconnect_callback_, Run());
+ source->Close();
+}
+
+TEST_F(RTCEncodedAudioUnderlyingSourceTest, CancelStream) {
+ V8TestingScope v8_scope;
+ auto* source = CreateSource(v8_scope.GetScriptState());
+ auto* stream = ReadableStream::CreateWithCountQueueingStrategy(
+ v8_scope.GetScriptState(), source, 0);
+
+ EXPECT_CALL(disconnect_callback_, Run());
+ NonThrowableExceptionState exception_state;
+ stream->cancel(v8_scope.GetScriptState(), exception_state);
+}
+
+TEST_F(RTCEncodedAudioUnderlyingSourceTest,
+ QueuedFramesAreDroppedWhenOverflow) {
+ V8TestingScope v8_scope;
+ ScriptState* script_state = v8_scope.GetScriptState();
+ auto* source = CreateSource(script_state);
+ // Create a stream, to ensure there is a controller associated to the source.
+ ReadableStream::CreateWithCountQueueingStrategy(v8_scope.GetScriptState(),
+ source, 0);
+ for (int i = 0; i > RTCEncodedAudioUnderlyingSource::kMinQueueDesiredSize;
+ --i) {
+ EXPECT_EQ(source->Controller()->DesiredSize(), i);
+ source->OnFrameFromSource(std::make_unique<FakeTransformableFrame>());
+ }
+ EXPECT_EQ(source->Controller()->DesiredSize(),
+ RTCEncodedAudioUnderlyingSource::kMinQueueDesiredSize);
+
+ source->OnFrameFromSource(std::make_unique<FakeTransformableFrame>());
+ EXPECT_EQ(source->Controller()->DesiredSize(),
+ RTCEncodedAudioUnderlyingSource::kMinQueueDesiredSize);
+
+ EXPECT_CALL(disconnect_callback_, Run());
+ source->Close();
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..65593da5124
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.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/modules/peerconnection/rtc_encoded_video_frame.h"
+
+#include <utility>
+
+#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
+#include "third_party/webrtc/api/frame_transformer_interface.h"
+
+namespace blink {
+
+RTCEncodedVideoFrame::RTCEncodedVideoFrame(
+ std::unique_ptr<webrtc::TransformableVideoFrameInterface> webrtc_frame)
+ : delegate_(base::MakeRefCounted<RTCEncodedVideoFrameDelegate>(
+ std::move(webrtc_frame))) {}
+
+RTCEncodedVideoFrame::RTCEncodedVideoFrame(
+ scoped_refptr<RTCEncodedVideoFrameDelegate> delegate)
+ : delegate_(std::move(delegate)) {}
+
+String RTCEncodedVideoFrame::type() const {
+ return delegate_->Type();
+}
+
+uint64_t RTCEncodedVideoFrame::timestamp() const {
+ return delegate_->Timestamp();
+}
+
+DOMArrayBuffer* RTCEncodedVideoFrame::data() const {
+ if (!frame_data_)
+ frame_data_ = delegate_->CreateDataBuffer();
+ return frame_data_;
+}
+
+DOMArrayBuffer* RTCEncodedVideoFrame::additionalData() const {
+ if (!additional_data_)
+ additional_data_ = delegate_->CreateAdditionalDataBuffer();
+
+ return additional_data_;
+}
+
+uint32_t RTCEncodedVideoFrame::synchronizationSource() const {
+ return delegate_->Ssrc();
+}
+
+void RTCEncodedVideoFrame::setData(DOMArrayBuffer* data) {
+ frame_data_ = data;
+}
+
+String RTCEncodedVideoFrame::toString() const {
+ if (!delegate_)
+ return "empty";
+
+ StringBuilder sb;
+ sb.Append("RTCEncodedVideoFrame{timestamp: ");
+ sb.AppendNumber(timestamp());
+ sb.Append("us, size: ");
+ sb.AppendNumber(data()->ByteLengthAsSizeT());
+ sb.Append(" bytes, type: ");
+ sb.Append(type());
+ sb.Append("}");
+ return sb.ToString();
+}
+
+void RTCEncodedVideoFrame::SyncDelegate() const {
+ delegate_->SetData(frame_data_);
+}
+
+scoped_refptr<RTCEncodedVideoFrameDelegate> RTCEncodedVideoFrame::Delegate()
+ const {
+ SyncDelegate();
+ return delegate_;
+}
+
+std::unique_ptr<webrtc::TransformableVideoFrameInterface>
+RTCEncodedVideoFrame::PassWebRtcFrame() {
+ SyncDelegate();
+ return delegate_->PassWebRtcFrame();
+}
+
+void RTCEncodedVideoFrame::Trace(Visitor* visitor) {
+ ScriptWrappable::Trace(visitor);
+ visitor->Trace(frame_data_);
+ visitor->Trace(additional_data_);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..5e13b07e9c1
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.h
@@ -0,0 +1,65 @@
+// 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_PEERCONNECTION_RTC_ENCODED_VIDEO_FRAME_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ENCODED_VIDEO_FRAME_H_
+
+#include <stdint.h>
+
+#include <memory>
+
+#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 webrtc {
+class TransformableVideoFrameInterface;
+} // namespace webrtc
+
+namespace blink {
+
+class DOMArrayBuffer;
+class RTCEncodedVideoFrameDelegate;
+
+class MODULES_EXPORT RTCEncodedVideoFrame final : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ explicit RTCEncodedVideoFrame(
+ std::unique_ptr<webrtc::TransformableVideoFrameInterface> webrtc_frame);
+ explicit RTCEncodedVideoFrame(
+ scoped_refptr<RTCEncodedVideoFrameDelegate> delegate);
+
+ // rtc_encoded_video_frame.idl implementation.
+ String type() const;
+ // Returns the RTP Packet Timestamp for this frame.
+ uint64_t timestamp() const;
+ DOMArrayBuffer* data() const;
+ DOMArrayBuffer* additionalData() const;
+ void setData(DOMArrayBuffer*);
+ uint32_t synchronizationSource() const;
+ String toString() const;
+
+ scoped_refptr<RTCEncodedVideoFrameDelegate> Delegate() const;
+ void SyncDelegate() const;
+
+ // Returns and transfers ownership of the internal WebRTC frame
+ // backing this RTCEncodedVideoFrame, neutering all RTCEncodedVideoFrames
+ // backed by that internal WebRTC frame.
+ std::unique_ptr<webrtc::TransformableVideoFrameInterface> PassWebRtcFrame();
+
+ void Trace(Visitor*) override;
+
+ private:
+ const scoped_refptr<RTCEncodedVideoFrameDelegate> delegate_;
+
+ // Exposes encoded frame data from |delegate_|.
+ mutable Member<DOMArrayBuffer> frame_data_;
+ // Exposes additional data from |delegate_|.
+ mutable Member<DOMArrayBuffer> additional_data_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ENCODED_VIDEO_FRAME_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.idl
new file mode 100644
index 00000000000..14de6bbc44e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.idl
@@ -0,0 +1,25 @@
+// 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/alvestrand/webrtc-media-streams/blob/master/explainer.md#api
+// TODO(crbug.com/1052765): Add link to standard when available.
+
+enum RTCCodedVideoFrameType {
+ "empty",
+ "key",
+ "delta",
+};
+
+// TODO(crbug.com/1052765): Align with WebCodecs definition once it is stable.
+[RuntimeEnabled=RTCInsertableStreams]
+interface RTCEncodedVideoFrame {
+ readonly attribute RTCCodedVideoFrameType type;
+ readonly attribute unsigned long long timestamp; // microseconds
+ attribute ArrayBuffer data;
+ // TODO(crbug.com/1052765): Replace the following fields with a dictionary
+ // with structured data once we have decided what will be exposed.
+ readonly attribute ArrayBuffer additionalData;
+ readonly attribute unsigned long synchronizationSource;
+ stringifier;
+};
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
new file mode 100644
index 00000000000..6d2de5b2b77
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.cc
@@ -0,0 +1,89 @@
+// 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/peerconnection/rtc_encoded_video_frame_delegate.h"
+
+#include <utility>
+
+#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
+#include "third_party/webrtc/api/frame_transformer_interface.h"
+
+namespace blink {
+
+const void* const RTCEncodedVideoFramesAttachment::kAttachmentKey = nullptr;
+
+RTCEncodedVideoFrameDelegate::RTCEncodedVideoFrameDelegate(
+ std::unique_ptr<webrtc::TransformableVideoFrameInterface> webrtc_frame)
+ : webrtc_frame_(std::move(webrtc_frame)) {}
+
+String RTCEncodedVideoFrameDelegate::Type() const {
+ MutexLocker lock(mutex_);
+ if (!webrtc_frame_)
+ return "empty";
+
+ return webrtc_frame_->IsKeyFrame() ? "key" : "delta";
+}
+
+uint64_t RTCEncodedVideoFrameDelegate::Timestamp() const {
+ MutexLocker lock(mutex_);
+ return webrtc_frame_ ? webrtc_frame_->GetTimestamp() : 0;
+}
+
+DOMArrayBuffer* RTCEncodedVideoFrameDelegate::CreateDataBuffer() const {
+ ArrayBufferContents contents;
+ {
+ MutexLocker lock(mutex_);
+ if (!webrtc_frame_)
+ return nullptr;
+
+ auto data = webrtc_frame_->GetData();
+ contents =
+ ArrayBufferContents(data.size(), 1, ArrayBufferContents::kNotShared,
+ ArrayBufferContents::kDontInitialize);
+ if (UNLIKELY(!contents.Data()))
+ OOM_CRASH(data.size());
+ memcpy(contents.Data(), data.data(), data.size());
+ }
+ return DOMArrayBuffer::Create(std::move(contents));
+}
+
+void RTCEncodedVideoFrameDelegate::SetData(const DOMArrayBuffer* data) {
+ MutexLocker lock(mutex_);
+ if (webrtc_frame_ && data) {
+ webrtc_frame_->SetData(rtc::ArrayView<const uint8_t>(
+ static_cast<const uint8_t*>(data->Data()), data->ByteLengthAsSizeT()));
+ }
+}
+
+DOMArrayBuffer* RTCEncodedVideoFrameDelegate::CreateAdditionalDataBuffer()
+ const {
+ ArrayBufferContents contents;
+ {
+ MutexLocker lock(mutex_);
+ if (!webrtc_frame_)
+ return nullptr;
+
+ auto additional_data = webrtc_frame_->GetAdditionalData();
+ contents = ArrayBufferContents(additional_data.size(), 1,
+ ArrayBufferContents::kNotShared,
+ ArrayBufferContents::kDontInitialize);
+ if (UNLIKELY(!contents.Data()))
+ OOM_CRASH(additional_data.size());
+ memcpy(contents.Data(), additional_data.data(), additional_data.size());
+ }
+ return DOMArrayBuffer::Create(std::move(contents));
+}
+
+uint32_t RTCEncodedVideoFrameDelegate::Ssrc() const {
+ MutexLocker lock(mutex_);
+ return webrtc_frame_ ? webrtc_frame_->GetSsrc() : 0;
+}
+
+std::unique_ptr<webrtc::TransformableVideoFrameInterface>
+RTCEncodedVideoFrameDelegate::PassWebRtcFrame() {
+ MutexLocker lock(mutex_);
+ return std::move(webrtc_frame_);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..5bc300b6e82
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.h
@@ -0,0 +1,72 @@
+// 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_PEERCONNECTION_RTC_ENCODED_VIDEO_FRAME_DELEGATE_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ENCODED_VIDEO_FRAME_DELEGATE_H_
+
+#include <stdint.h>
+
+#include <memory>
+
+#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#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"
+
+namespace blink {
+
+class DOMArrayBuffer;
+
+// This class wraps a WebRTC video frame and allows making shallow
+// copies. Its purpose is to support making RTCEncodedVideoFrames
+// serializable in the same process.
+class RTCEncodedVideoFrameDelegate
+ : public WTF::ThreadSafeRefCounted<RTCEncodedVideoFrameDelegate> {
+ public:
+ explicit RTCEncodedVideoFrameDelegate(
+ std::unique_ptr<webrtc::TransformableVideoFrameInterface> webrtc_frame);
+
+ String Type() const;
+ uint64_t Timestamp() const;
+ DOMArrayBuffer* CreateDataBuffer() const;
+ void SetData(const DOMArrayBuffer* data);
+ DOMArrayBuffer* CreateAdditionalDataBuffer() const;
+ uint32_t Ssrc() const;
+ std::unique_ptr<webrtc::TransformableVideoFrameInterface> PassWebRtcFrame();
+
+ private:
+ mutable Mutex mutex_;
+ std::unique_ptr<webrtc::TransformableVideoFrameInterface> webrtc_frame_
+ GUARDED_BY(mutex_);
+};
+
+class MODULES_EXPORT RTCEncodedVideoFramesAttachment
+ : public SerializedScriptValue::Attachment {
+ public:
+ static const void* const kAttachmentKey;
+ RTCEncodedVideoFramesAttachment() = default;
+ ~RTCEncodedVideoFramesAttachment() override = default;
+
+ bool IsLockedToAgentCluster() const override {
+ return !encoded_video_frames_.IsEmpty();
+ }
+
+ Vector<scoped_refptr<RTCEncodedVideoFrameDelegate>>& EncodedVideoFrames() {
+ return encoded_video_frames_;
+ }
+
+ const Vector<scoped_refptr<RTCEncodedVideoFrameDelegate>>&
+ EncodedVideoFrames() const {
+ return encoded_video_frames_;
+ }
+
+ private:
+ Vector<scoped_refptr<RTCEncodedVideoFrameDelegate>> encoded_video_frames_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ENCODED_VIDEO_FRAME_DELEGATE_H_
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
new file mode 100644
index 00000000000..b4b7bd85aaf
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.cc
@@ -0,0 +1,88 @@
+// 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/peerconnection/rtc_encoded_video_underlying_sink.h"
+
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_encoded_video_frame.h"
+#include "third_party/blink/renderer/core/dom/dom_exception.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_encoded_video_stream_transformer.h"
+#include "third_party/webrtc/api/frame_transformer_interface.h"
+
+namespace blink {
+
+RTCEncodedVideoUnderlyingSink::RTCEncodedVideoUnderlyingSink(
+ ScriptState* script_state,
+ TransformerCallback transformer_callback)
+ : transformer_callback_(std::move(transformer_callback)) {
+ DCHECK(transformer_callback_);
+}
+
+ScriptPromise RTCEncodedVideoUnderlyingSink::start(
+ ScriptState* script_state,
+ WritableStreamDefaultController* controller,
+ ExceptionState&) {
+ // No extra setup needed.
+ return ScriptPromise::CastUndefined(script_state);
+}
+
+ScriptPromise RTCEncodedVideoUnderlyingSink::write(
+ ScriptState* script_state,
+ ScriptValue chunk,
+ WritableStreamDefaultController* controller,
+ ExceptionState& exception_state) {
+ RTCEncodedVideoFrame* encoded_frame =
+ V8RTCEncodedVideoFrame::ToImplWithTypeCheck(script_state->GetIsolate(),
+ chunk.V8Value());
+ if (!encoded_frame) {
+ exception_state.ThrowTypeError("Invalid frame");
+ return ScriptPromise();
+ }
+
+ if (!transformer_callback_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Stream closed");
+ return ScriptPromise();
+ }
+
+ auto webrtc_frame = encoded_frame->PassWebRtcFrame();
+ if (!webrtc_frame) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kOperationError,
+ "Empty frame");
+ return ScriptPromise();
+ }
+
+ RTCEncodedVideoStreamTransformer* transformer = transformer_callback_.Run();
+ if (!transformer) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "No underlying sink");
+ return ScriptPromise();
+ }
+
+ transformer->SendFrameToSink(std::move(webrtc_frame));
+ return ScriptPromise::CastUndefined(script_state);
+}
+
+ScriptPromise RTCEncodedVideoUnderlyingSink::close(ScriptState* script_state,
+ ExceptionState&) {
+ // Disconnect from the transformer if the sink is closed.
+ if (transformer_callback_)
+ transformer_callback_.Reset();
+ return ScriptPromise::CastUndefined(script_state);
+}
+
+ScriptPromise RTCEncodedVideoUnderlyingSink::abort(
+ ScriptState* script_state,
+ ScriptValue reason,
+ ExceptionState& exception_state) {
+ // It is not possible to cancel any frames already sent to the WebRTC sink,
+ // thus abort() has the same effect as close().
+ return close(script_state, exception_state);
+}
+
+void RTCEncodedVideoUnderlyingSink::Trace(Visitor* visitor) {
+ UnderlyingSinkBase::Trace(visitor);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..74719373e4e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.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_MODULES_PEERCONNECTION_RTC_ENCODED_VIDEO_UNDERLYING_SINK_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ENCODED_VIDEO_UNDERLYING_SINK_H_
+
+#include "third_party/blink/renderer/core/streams/underlying_sink_base.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+
+namespace blink {
+
+class ExceptionState;
+class RTCEncodedVideoStreamTransformer;
+
+class MODULES_EXPORT RTCEncodedVideoUnderlyingSink final
+ : public UnderlyingSinkBase {
+ public:
+ using TransformerCallback =
+ base::RepeatingCallback<RTCEncodedVideoStreamTransformer*()>;
+ RTCEncodedVideoUnderlyingSink(ScriptState*, TransformerCallback);
+
+ // UnderlyingSinkBase
+ ScriptPromise start(ScriptState*,
+ WritableStreamDefaultController*,
+ ExceptionState&) override;
+ ScriptPromise write(ScriptState*,
+ ScriptValue chunk,
+ WritableStreamDefaultController*,
+ ExceptionState&) override;
+ ScriptPromise close(ScriptState*, ExceptionState&) override;
+ ScriptPromise abort(ScriptState*,
+ ScriptValue reason,
+ ExceptionState&) override;
+
+ void Trace(Visitor*) override;
+
+ private:
+ TransformerCallback transformer_callback_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ENCODED_VIDEO_UNDERLYING_SINK_H_
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
new file mode 100644
index 00000000000..3a606d1e894
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink_test.cc
@@ -0,0 +1,192 @@
+// 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/peerconnection/rtc_encoded_video_underlying_sink.h"
+
+#include "base/memory/scoped_refptr.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/bindings/core/v8/script_promise_tester.h"
+#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_encoded_video_frame.h"
+#include "third_party/blink/renderer/core/streams/writable_stream.h"
+#include "third_party/blink/renderer/core/streams/writable_stream_default_writer.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_encoded_video_stream_transformer.h"
+#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/rtc_base/ref_counted_object.h"
+
+using testing::_;
+
+namespace blink {
+
+namespace {
+
+const uint32_t kSSRC = 1;
+
+class MockWebRtcTransformedFrameCallback
+ : public webrtc::TransformedFrameCallback {
+ public:
+ MOCK_METHOD1(OnTransformedFrame,
+ 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) {
+ auto* dom_exception = V8DOMException::ToImplWithTypeCheck(
+ script_state->GetIsolate(), value.V8Value());
+ if (!dom_exception)
+ return false;
+
+ return dom_exception->code() == static_cast<uint16_t>(code);
+}
+
+} // namespace
+
+class RTCEncodedVideoUnderlyingSinkTest : public testing::Test {
+ public:
+ RTCEncodedVideoUnderlyingSinkTest()
+ : main_task_runner_(
+ blink::scheduler::GetSingleThreadTaskRunnerForTesting()),
+ webrtc_callback_(
+ new rtc::RefCountedObject<MockWebRtcTransformedFrameCallback>()),
+ transformer_(main_task_runner_) {}
+
+ void SetUp() override {
+ EXPECT_FALSE(transformer_.HasTransformedFrameSinkCallback(kSSRC));
+ transformer_.RegisterTransformedFrameSinkCallback(webrtc_callback_, kSSRC);
+ EXPECT_TRUE(transformer_.HasTransformedFrameSinkCallback(kSSRC));
+ }
+
+ void TearDown() override {
+ platform_->RunUntilIdle();
+ transformer_.UnregisterTransformedFrameSinkCallback(kSSRC);
+ EXPECT_FALSE(transformer_.HasTransformedFrameSinkCallback(kSSRC));
+ }
+
+ RTCEncodedVideoUnderlyingSink* CreateSink(ScriptState* script_state) {
+ return MakeGarbageCollected<RTCEncodedVideoUnderlyingSink>(
+ script_state,
+ WTF::BindRepeating(&RTCEncodedVideoUnderlyingSinkTest::GetTransformer,
+ WTF::Unretained(this)));
+ }
+
+ RTCEncodedVideoUnderlyingSink* CreateNullCallbackSink(
+ ScriptState* script_state) {
+ return MakeGarbageCollected<RTCEncodedVideoUnderlyingSink>(
+ script_state,
+ WTF::BindRepeating(
+ []() -> RTCEncodedVideoStreamTransformer* { return nullptr; }));
+ }
+
+ RTCEncodedVideoStreamTransformer* GetTransformer() { return &transformer_; }
+
+ ScriptValue CreateEncodedVideoFrameChunk(ScriptState* script_state) {
+ RTCEncodedVideoFrame* frame = MakeGarbageCollected<RTCEncodedVideoFrame>(
+ std::make_unique<FakeVideoFrame>(kSSRC));
+ return ScriptValue(script_state->GetIsolate(),
+ ToV8(frame, script_state->GetContext()->Global(),
+ script_state->GetIsolate()));
+ }
+
+ protected:
+ ScopedTestingPlatformSupport<TestingPlatformSupport> platform_;
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ rtc::scoped_refptr<MockWebRtcTransformedFrameCallback> webrtc_callback_;
+ RTCEncodedVideoStreamTransformer transformer_;
+};
+
+TEST_F(RTCEncodedVideoUnderlyingSinkTest,
+ WriteToStreamForwardsToWebRtcCallback) {
+ V8TestingScope v8_scope;
+ ScriptState* script_state = v8_scope.GetScriptState();
+ auto* sink = CreateSink(script_state);
+ auto* stream =
+ WritableStream::CreateWithCountQueueingStrategy(script_state, sink, 1u);
+
+ NonThrowableExceptionState exception_state;
+ auto* writer = stream->getWriter(script_state, exception_state);
+
+ EXPECT_CALL(*webrtc_callback_, OnTransformedFrame(_));
+ ScriptPromiseTester write_tester(
+ script_state,
+ writer->write(script_state, CreateEncodedVideoFrameChunk(script_state),
+ exception_state));
+ EXPECT_FALSE(write_tester.IsFulfilled());
+
+ writer->releaseLock(script_state);
+ ScriptPromiseTester close_tester(
+ script_state, stream->close(script_state, exception_state));
+ close_tester.WaitUntilSettled();
+
+ // Writing to the sink after the stream closes should fail.
+ DummyExceptionStateForTesting dummy_exception_state;
+ sink->write(script_state, CreateEncodedVideoFrameChunk(script_state), nullptr,
+ dummy_exception_state);
+ EXPECT_TRUE(dummy_exception_state.HadException());
+ EXPECT_EQ(dummy_exception_state.Code(),
+ static_cast<ExceptionCode>(DOMExceptionCode::kInvalidStateError));
+}
+
+TEST_F(RTCEncodedVideoUnderlyingSinkTest, WriteInvalidDataFails) {
+ V8TestingScope v8_scope;
+ ScriptState* script_state = v8_scope.GetScriptState();
+ auto* sink = CreateSink(script_state);
+ ScriptValue v8_integer = ScriptValue::From(script_state, 0);
+
+ // Writing something that is not an RTCEncodedVideoFrame integer to the sink
+ // should fail.
+ DummyExceptionStateForTesting dummy_exception_state;
+ sink->write(script_state, v8_integer, nullptr, dummy_exception_state);
+ EXPECT_TRUE(dummy_exception_state.HadException());
+}
+
+TEST_F(RTCEncodedVideoUnderlyingSinkTest, WriteToNullCallbackSinkFails) {
+ V8TestingScope v8_scope;
+ ScriptState* script_state = v8_scope.GetScriptState();
+ auto* sink = CreateNullCallbackSink(script_state);
+ auto* stream =
+ WritableStream::CreateWithCountQueueingStrategy(script_state, sink, 1u);
+
+ NonThrowableExceptionState exception_state;
+ auto* writer = stream->getWriter(script_state, exception_state);
+
+ EXPECT_CALL(*webrtc_callback_, OnTransformedFrame(_)).Times(0);
+ ScriptPromiseTester write_tester(
+ script_state,
+ writer->write(script_state, CreateEncodedVideoFrameChunk(script_state),
+ exception_state));
+ write_tester.WaitUntilSettled();
+ EXPECT_TRUE(write_tester.IsRejected());
+ EXPECT_TRUE(IsDOMException(script_state, write_tester.Value(),
+ DOMExceptionCode::kInvalidStateError));
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..a459e4112b2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.cc
@@ -0,0 +1,74 @@
+// 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/peerconnection/rtc_encoded_video_underlying_source.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
+#include "third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.h"
+#include "third_party/blink/renderer/platform/bindings/exception_code.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/webrtc/api/frame_transformer_interface.h"
+
+namespace blink {
+
+// Frames should not be queued at all. We allow queuing a few frames to deal
+// with transient slowdowns. Specified as a negative number of frames since
+// queuing is reported by the stream controller as a negative desired size.
+const int RTCEncodedVideoUnderlyingSource::kMinQueueDesiredSize = -60;
+
+RTCEncodedVideoUnderlyingSource::RTCEncodedVideoUnderlyingSource(
+ ScriptState* script_state,
+ base::OnceClosure disconnect_callback)
+ : UnderlyingSourceBase(script_state),
+ script_state_(script_state),
+ disconnect_callback_(std::move(disconnect_callback)) {
+ DCHECK(disconnect_callback_);
+}
+
+ScriptPromise RTCEncodedVideoUnderlyingSource::pull(ScriptState* script_state) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ // WebRTC is a push source without backpressure support, so nothing to do
+ // here.
+ return ScriptPromise::CastUndefined(script_state);
+}
+
+ScriptPromise RTCEncodedVideoUnderlyingSource::Cancel(ScriptState* script_state,
+ ScriptValue reason) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ if (disconnect_callback_)
+ std::move(disconnect_callback_).Run();
+ return ScriptPromise::CastUndefined(script_state);
+}
+
+void RTCEncodedVideoUnderlyingSource::Trace(Visitor* visitor) {
+ visitor->Trace(script_state_);
+ UnderlyingSourceBase::Trace(visitor);
+}
+
+void RTCEncodedVideoUnderlyingSource::OnFrameFromSource(
+ std::unique_ptr<webrtc::TransformableVideoFrameInterface> webrtc_frame) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ // If the source is canceled or there are too many queued frames,
+ // drop the new frame.
+ if (!disconnect_callback_ || !Controller() ||
+ Controller()->DesiredSize() <= kMinQueueDesiredSize) {
+ return;
+ }
+
+ RTCEncodedVideoFrame* encoded_frame =
+ MakeGarbageCollected<RTCEncodedVideoFrame>(std::move(webrtc_frame));
+ Controller()->Enqueue(encoded_frame);
+}
+
+void RTCEncodedVideoUnderlyingSource::Close() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ if (disconnect_callback_)
+ std::move(disconnect_callback_).Run();
+
+ if (Controller())
+ Controller()->Close();
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..8ceb0b8b492
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.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_MODULES_PEERCONNECTION_RTC_ENCODED_VIDEO_UNDERLYING_SOURCE_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ENCODED_VIDEO_UNDERLYING_SOURCE_H_
+
+#include "base/threading/thread_checker.h"
+#include "third_party/blink/renderer/core/streams/underlying_source_base.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+
+namespace webrtc {
+class TransformableVideoFrameInterface;
+} // namespace webrtc
+
+namespace blink {
+
+class MODULES_EXPORT RTCEncodedVideoUnderlyingSource
+ : public UnderlyingSourceBase {
+ public:
+ explicit RTCEncodedVideoUnderlyingSource(
+ ScriptState*,
+ base::OnceClosure disconnect_callback);
+
+ // UnderlyingSourceBase
+ ScriptPromise pull(ScriptState*) override;
+ ScriptPromise Cancel(ScriptState*, ScriptValue reason) override;
+
+ void OnFrameFromSource(
+ std::unique_ptr<webrtc::TransformableVideoFrameInterface>);
+ void Close();
+
+ void Trace(Visitor*) override;
+
+ private:
+ FRIEND_TEST_ALL_PREFIXES(RTCEncodedVideoUnderlyingSourceTest, QueuedFramesAreDroppedWhenOverflow);
+ static const int kMinQueueDesiredSize;
+
+ const Member<ScriptState> script_state_;
+ base::OnceClosure disconnect_callback_;
+ THREAD_CHECKER(thread_checker_);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ENCODED_VIDEO_UNDERLYING_SOURCE_H_
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
new file mode 100644
index 00000000000..225207b3f52
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source_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/modules/peerconnection/rtc_encoded_video_underlying_source.h"
+#include <memory>
+
+#include "base/test/mock_callback.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.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/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/platform/bindings/exception_state.h"
+#include "third_party/webrtc/api/frame_transformer_interface.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) {
+ return MakeGarbageCollected<RTCEncodedVideoUnderlyingSource>(
+ script_state, WTF::Bind(disconnect_callback_.Get()));
+ }
+
+ protected:
+ base::MockOnceClosure disconnect_callback_;
+};
+
+TEST_F(RTCEncodedVideoUnderlyingSourceTest,
+ SourceDataFlowsThroughStreamAndCloses) {
+ V8TestingScope v8_scope;
+ ScriptState* script_state = v8_scope.GetScriptState();
+ auto* source = CreateSource(script_state);
+ auto* stream =
+ ReadableStream::CreateWithCountQueueingStrategy(script_state, source, 0);
+
+ NonThrowableExceptionState exception_state;
+ auto* reader = stream->getReader(script_state, exception_state);
+
+ ScriptPromiseTester read_tester(script_state,
+ reader->read(script_state, exception_state));
+ EXPECT_FALSE(read_tester.IsFulfilled());
+ source->OnFrameFromSource(std::make_unique<FakeTransformableFrame>());
+ read_tester.WaitUntilSettled();
+ EXPECT_TRUE(read_tester.IsFulfilled());
+
+ EXPECT_CALL(disconnect_callback_, Run());
+ source->Close();
+}
+
+TEST_F(RTCEncodedVideoUnderlyingSourceTest, CancelStream) {
+ V8TestingScope v8_scope;
+ auto* source = CreateSource(v8_scope.GetScriptState());
+ auto* stream = ReadableStream::CreateWithCountQueueingStrategy(
+ v8_scope.GetScriptState(), source, 0);
+
+ EXPECT_CALL(disconnect_callback_, Run());
+ NonThrowableExceptionState exception_state;
+ stream->cancel(v8_scope.GetScriptState(), exception_state);
+}
+
+TEST_F(RTCEncodedVideoUnderlyingSourceTest, QueuedFramesAreDroppedWhenOverflow) {
+ V8TestingScope v8_scope;
+ ScriptState* script_state = v8_scope.GetScriptState();
+ auto* source = CreateSource(script_state);
+ // Create a stream, to ensure there is a controller associated to the source.
+ ReadableStream::CreateWithCountQueueingStrategy(v8_scope.GetScriptState(),
+ source, 0);
+ for (int i = 0; i > RTCEncodedVideoUnderlyingSource::kMinQueueDesiredSize;
+ --i) {
+ EXPECT_EQ(source->Controller()->DesiredSize(), i);
+ source->OnFrameFromSource(std::make_unique<FakeTransformableFrame>());
+ }
+ EXPECT_EQ(source->Controller()->DesiredSize(),
+ RTCEncodedVideoUnderlyingSource::kMinQueueDesiredSize);
+
+ source->OnFrameFromSource(std::make_unique<FakeTransformableFrame>());
+ EXPECT_EQ(source->Controller()->DesiredSize(),
+ RTCEncodedVideoUnderlyingSource::kMinQueueDesiredSize);
+
+ EXPECT_CALL(disconnect_callback_, Run());
+ source->Close();
+}
+
+} // namespace blink
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 932fd05c919..77d77b60226 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error.cc
@@ -14,7 +14,7 @@ RTCError* RTCError::Create(const RTCErrorInit* init, String message) {
}
RTCError::RTCError(const RTCErrorInit* init, String message)
- : DOMException(0u, "RTCError", std::move(message), String()),
+ : DOMException(DOMExceptionCode::kOperationError, std::move(message)),
error_detail_(init->errorDetail()),
sdp_line_number_(init->hasSdpLineNumber()
? base::Optional<int32_t>(init->sdpLineNumber())
@@ -33,6 +33,13 @@ RTCError::RTCError(const RTCErrorInit* init, String message)
? base::Optional<uint32_t>(init->sentAlert())
: base::nullopt) {}
+RTCError::RTCError(webrtc::RTCError err)
+ : DOMException(DOMExceptionCode::kOperationError, err.message()),
+ error_detail_(webrtc::ToString(err.error_detail())),
+ sctp_cause_code_(err.sctp_cause_code()
+ ? base::Optional<int32_t>(*err.sctp_cause_code())
+ : base::nullopt) {}
+
const String& RTCError::errorDetail() const {
return error_detail_;
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error.h
index 9182e58da73..17daeb566c0 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error.h
@@ -6,10 +6,11 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ERROR_H_
#include "base/optional.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_error_init.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_error_init.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/webrtc/api/rtc_error.h"
namespace blink {
@@ -19,13 +20,22 @@ class RTCError final : public DOMException {
public:
static RTCError* Create(const RTCErrorInit* init, String message);
RTCError(const RTCErrorInit* init, String message);
+ explicit RTCError(webrtc::RTCError);
const String& errorDetail() const;
- int32_t sdpLineNumber(bool& is_null) const;
- int32_t httpRequestStatusCode(bool& is_null) const;
- int32_t sctpCauseCode(bool& is_null) const;
- uint32_t receivedAlert(bool& is_null) const;
- uint32_t sentAlert(bool& is_null) const;
+ base::Optional<int32_t> sdpLineNumber() const { return sdp_line_number_; }
+ base::Optional<int32_t> httpRequestStatusCode() const {
+ return http_request_status_code_;
+ }
+ base::Optional<int32_t> sctpCauseCode() const { return sctp_cause_code_; }
+ base::Optional<uint32_t> receivedAlert() const { return received_alert_; }
+ base::Optional<uint32_t> sentAlert() const { return sent_alert_; }
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ int32_t sdpLineNumber(bool& is_null) const; // DEPRECATED
+ int32_t httpRequestStatusCode(bool& is_null) const; // DEPRECATED
+ int32_t sctpCauseCode(bool& is_null) const; // DEPRECATED
+ uint32_t receivedAlert(bool& is_null) const; // DEPRECATED
+ uint32_t sentAlert(bool& is_null) const; // DEPRECATED
private:
// idl enum RTCErrorDetailType.
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error.idl
index 27bb63f458b..9c0e624f3ff 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error.idl
@@ -23,9 +23,9 @@ enum RTCErrorDetailType {
// https://w3c.github.io/webrtc-pc/#dfn-rtcerror
[
- Exposed=Window,
- Constructor(RTCErrorInit init, optional DOMString message = "")
+ Exposed=Window
] interface RTCError : DOMException {
+ constructor(RTCErrorInit init, optional DOMString message = "");
readonly attribute RTCErrorDetailType errorDetail;
readonly attribute long? sdpLineNumber;
readonly attribute long? httpRequestStatusCode;
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 ba5e9950690..b9df9f5a853 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
@@ -20,11 +20,15 @@ RTCErrorEvent::RTCErrorEvent(const AtomicString& type,
DCHECK(event_init_dict);
}
+RTCErrorEvent::RTCErrorEvent(const AtomicString& type, webrtc::RTCError error)
+ : Event(type, Bubbles::kNo, Cancelable::kNo),
+ error_(MakeGarbageCollected<RTCError>(error)) {}
+
RTCError* RTCErrorEvent::error() const {
return error_;
}
-void RTCErrorEvent::Trace(blink::Visitor* visitor) {
+void RTCErrorEvent::Trace(Visitor* visitor) {
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 e768586456b..9c25d404fc8 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
@@ -5,13 +5,14 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ERROR_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_ERROR_EVENT_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_error_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_error.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_error_event_init.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/member.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
+#include "third_party/webrtc/api/rtc_error.h"
namespace blink {
@@ -25,9 +26,11 @@ class RTCErrorEvent final : public Event {
RTCErrorEvent(const AtomicString& type,
const RTCErrorEventInit* event_init_dict);
+ RTCErrorEvent(const AtomicString& type, webrtc::RTCError error);
+
RTCError* error() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<RTCError> error_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.idl
index 8ef88d0a058..833520ea5cb 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.idl
@@ -4,8 +4,8 @@
// https://w3c.github.io/webrtc-pc/#dom-rtcerrorevent
[
- Exposed=Window,
- Constructor(DOMString type, RTCErrorEventInit eventInitDict)
+ Exposed=Window
] interface RTCErrorEvent : Event {
+ constructor(DOMString type, RTCErrorEventInit eventInitDict);
readonly attribute 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 923f27b56ac..21109f8937b 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
@@ -34,11 +34,12 @@
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_candidate_init.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/modules/peerconnection/rtc_ice_candidate_init.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/heap/heap.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
namespace blink {
@@ -64,19 +65,19 @@ RTCIceCandidate* RTCIceCandidate::Create(
WebFeature::kRTCIceCandidateDefaultSdpMLineIndex);
}
- return MakeGarbageCollected<RTCIceCandidate>(RTCIceCandidatePlatform::Create(
- candidate_init->candidate(), sdp_mid, std::move(sdp_m_line_index),
- candidate_init->usernameFragment()));
+ return MakeGarbageCollected<RTCIceCandidate>(
+ MakeGarbageCollected<RTCIceCandidatePlatform>(
+ candidate_init->candidate(), sdp_mid, std::move(sdp_m_line_index),
+ candidate_init->usernameFragment()));
}
RTCIceCandidate* RTCIceCandidate::Create(
- scoped_refptr<RTCIceCandidatePlatform> platform_candidate) {
- return MakeGarbageCollected<RTCIceCandidate>(std::move(platform_candidate));
+ RTCIceCandidatePlatform* platform_candidate) {
+ return MakeGarbageCollected<RTCIceCandidate>(platform_candidate);
}
-RTCIceCandidate::RTCIceCandidate(
- scoped_refptr<RTCIceCandidatePlatform> platform_candidate)
- : platform_candidate_(std::move(platform_candidate)) {}
+RTCIceCandidate::RTCIceCandidate(RTCIceCandidatePlatform* platform_candidate)
+ : platform_candidate_(platform_candidate) {}
String RTCIceCandidate::candidate() const {
return platform_candidate_->Candidate();
@@ -86,16 +87,24 @@ String RTCIceCandidate::sdpMid() const {
return platform_candidate_->SdpMid();
}
+base::Optional<uint16_t> RTCIceCandidate::sdpMLineIndex() const {
+ return platform_candidate_->SdpMLineIndex();
+}
+
uint16_t RTCIceCandidate::sdpMLineIndex(bool& is_null) const {
is_null = !platform_candidate_->SdpMLineIndex().has_value();
return platform_candidate_->SdpMLineIndex().value_or(0);
}
-scoped_refptr<RTCIceCandidatePlatform> RTCIceCandidate::PlatformCandidate()
- const {
+RTCIceCandidatePlatform* RTCIceCandidate::PlatformCandidate() const {
return platform_candidate_;
}
+void RTCIceCandidate::Trace(Visitor* visitor) {
+ visitor->Trace(platform_candidate_);
+ ScriptWrappable::Trace(visitor);
+}
+
String RTCIceCandidate::foundation() const {
return platform_candidate_->Foundation();
}
@@ -104,6 +113,10 @@ String RTCIceCandidate::component() const {
return platform_candidate_->Component();
}
+base::Optional<uint32_t> RTCIceCandidate::priority() const {
+ return platform_candidate_->Priority();
+}
+
uint32_t RTCIceCandidate::priority(bool& is_null) const {
is_null = !platform_candidate_->Priority().has_value();
return platform_candidate_->Priority().value_or(0);
@@ -117,6 +130,10 @@ String RTCIceCandidate::protocol() const {
return platform_candidate_->Protocol();
}
+base::Optional<uint16_t> RTCIceCandidate::port() const {
+ return platform_candidate_->Port();
+}
+
uint16_t RTCIceCandidate::port(bool& is_null) const {
is_null = !platform_candidate_->Port().has_value();
return platform_candidate_->Port().value_or(0);
@@ -134,6 +151,10 @@ String RTCIceCandidate::relatedAddress() const {
return platform_candidate_->RelatedAddress();
}
+base::Optional<uint16_t> RTCIceCandidate::relatedPort() const {
+ return platform_candidate_->RelatedPort();
+}
+
uint16_t RTCIceCandidate::relatedPort(bool& is_null) const {
is_null = !platform_candidate_->RelatedPort().has_value();
return platform_candidate_->RelatedPort().value_or(0);
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 76e81c9ec41..7c37c74f369 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
@@ -51,31 +51,41 @@ class MODULES_EXPORT RTCIceCandidate final : public ScriptWrappable {
static RTCIceCandidate* Create(ExecutionContext*,
const RTCIceCandidateInit*,
ExceptionState&);
- static RTCIceCandidate* Create(scoped_refptr<RTCIceCandidatePlatform>);
+ static RTCIceCandidate* Create(RTCIceCandidatePlatform*);
- explicit RTCIceCandidate(scoped_refptr<RTCIceCandidatePlatform>);
+ explicit RTCIceCandidate(RTCIceCandidatePlatform*);
String candidate() const;
String sdpMid() const;
- uint16_t sdpMLineIndex(bool& is_null) const;
+ base::Optional<uint16_t> sdpMLineIndex() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ uint16_t sdpMLineIndex(bool& is_null) const; // DEPRECATED
String foundation() const;
String component() const;
- uint32_t priority(bool& is_null) const;
+ base::Optional<uint32_t> priority() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ uint32_t priority(bool& is_null) const; // DEPRECATED
String address() const;
String protocol() const;
- uint16_t port(bool& is_null) const;
+ base::Optional<uint16_t> port() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ uint16_t port(bool& is_null) const; // DEPRECATED
String type() const;
String tcpType() const;
String relatedAddress() const;
- uint16_t relatedPort(bool& is_null) const;
+ base::Optional<uint16_t> relatedPort() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ uint16_t relatedPort(bool& is_null) const; // DEPRECATED
String usernameFragment() const;
ScriptValue toJSONForBinding(ScriptState*);
- scoped_refptr<RTCIceCandidatePlatform> PlatformCandidate() const;
+ RTCIceCandidatePlatform* PlatformCandidate() const;
+
+ void Trace(Visitor*) override;
private:
- scoped_refptr<RTCIceCandidatePlatform> platform_candidate_;
+ Member<RTCIceCandidatePlatform> platform_candidate_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.idl
index cbe411b5166..7e2b32a5579 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.idl
@@ -57,11 +57,9 @@ enum RTCIceTcpCandidateType {
// https://w3c.github.io/webrtc-pc/#rtcicecandidate-interface
[
- Constructor(optional RTCIceCandidateInit candidateInitDict),
- ConstructorCallWith=ExecutionContext,
- RaisesException=Constructor,
Exposed=Window
] interface RTCIceCandidate {
+ [CallWith=ExecutionContext, RaisesException] constructor(optional RTCIceCandidateInit candidateInitDict = {});
readonly attribute DOMString candidate;
readonly attribute DOMString? sdpMid;
readonly attribute unsigned short? sdpMLineIndex;
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 5c7d4f26eaf..ba7a8202b95 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
@@ -6,6 +6,10 @@
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/web/web_local_frame.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_gather_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_parameters.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_server.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_peer_connection_ice_event_init.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -16,13 +20,10 @@
#include "third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_error_util.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_gather_options.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_parameters.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_server.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event_init.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/webrtc/api/ice_transport_factory.h"
@@ -53,7 +54,7 @@ base::Optional<cricket::Candidate> ConvertToCricketIceCandidate(
}
RTCIceCandidate* ConvertToRtcIceCandidate(const cricket::Candidate& candidate) {
- return RTCIceCandidate::Create(RTCIceCandidatePlatform::Create(
+ return RTCIceCandidate::Create(MakeGarbageCollected<RTCIceCandidatePlatform>(
String::FromUTF8(webrtc::SdpSerializeCandidate(candidate)), "", 0));
}
@@ -109,7 +110,7 @@ class DefaultIceTransportAdapterCrossThreadFactory
} // namespace
RTCIceTransport* RTCIceTransport::Create(ExecutionContext* context) {
- LocalFrame* frame = To<Document>(context)->GetFrame();
+ LocalFrame* frame = Document::From(context)->GetFrame();
scoped_refptr<base::SingleThreadTaskRunner> proxy_thread =
frame->GetTaskRunner(TaskType::kNetworking);
@@ -126,7 +127,7 @@ RTCIceTransport* RTCIceTransport::Create(
ExecutionContext* context,
rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport,
RTCPeerConnection* peer_connection) {
- LocalFrame* frame = To<Document>(context)->GetFrame();
+ LocalFrame* frame = Document::From(context)->GetFrame();
scoped_refptr<base::SingleThreadTaskRunner> proxy_thread =
frame->GetTaskRunner(TaskType::kNetworking);
@@ -157,14 +158,15 @@ RTCIceTransport::RTCIceTransport(
scoped_refptr<base::SingleThreadTaskRunner> host_thread,
std::unique_ptr<IceTransportAdapterCrossThreadFactory> adapter_factory,
RTCPeerConnection* peer_connection)
- : ContextLifecycleObserver(context), peer_connection_(peer_connection) {
+ : ExecutionContextLifecycleObserver(context),
+ peer_connection_(peer_connection) {
DCHECK(context);
DCHECK(proxy_thread);
DCHECK(host_thread);
DCHECK(adapter_factory);
DCHECK(proxy_thread->BelongsToCurrentThread());
- LocalFrame* frame = To<Document>(context)->GetFrame();
+ LocalFrame* frame = Document::From(context)->GetFrame();
DCHECK(frame);
proxy_ = std::make_unique<IceTransportProxy>(*frame, std::move(proxy_thread),
std::move(host_thread), this,
@@ -291,13 +293,13 @@ static webrtc::PeerConnectionInterface::IceServer ConvertIceServer(
webrtc::PeerConnectionInterface::IceServer converted_ice_server;
// Prefer standardized 'urls' field over deprecated 'url' field.
Vector<String> url_strings;
- if (ice_server->hasURLs()) {
+ if (ice_server->hasUrls()) {
if (ice_server->urls().IsString()) {
url_strings.push_back(ice_server->urls().GetAsString());
} else if (ice_server->urls().IsStringSequence()) {
url_strings = ice_server->urls().GetAsStringSequence();
}
- } else if (ice_server->hasURL()) {
+ } else if (ice_server->hasUrl()) {
url_strings.push_back(ice_server->url());
}
for (const String& url_string : url_strings) {
@@ -308,17 +310,16 @@ static webrtc::PeerConnectionInterface::IceServer ConvertIceServer(
return converted_ice_server;
}
-static cricket::IceParameters ConvertIceParameters(
- const RTCIceParameters* ice_parameters) {
- cricket::IceParameters converted_ice_parameters;
- converted_ice_parameters.ufrag = ice_parameters->usernameFragment().Utf8();
- converted_ice_parameters.pwd = ice_parameters->password().Utf8();
- return converted_ice_parameters;
+static webrtc::RTCErrorOr<cricket::IceParameters> ConvertIceParameters(
+ const RTCIceParameters* raw_ice_parameters) {
+ std::string raw_ufrag = raw_ice_parameters->usernameFragment().Utf8();
+ std::string raw_pwd = raw_ice_parameters->password().Utf8();
+ return cricket::IceParameters::Parse(raw_ufrag, raw_pwd);
}
static WebVector<webrtc::PeerConnectionInterface::IceServer> ConvertIceServers(
const HeapVector<Member<RTCIceServer>>& ice_servers) {
- Vector<webrtc::PeerConnectionInterface::IceServer> converted_ice_servers;
+ WebVector<webrtc::PeerConnectionInterface::IceServer> converted_ice_servers;
for (const RTCIceServer* ice_server : ice_servers) {
converted_ice_servers.emplace_back(ConvertIceServer(ice_server));
}
@@ -363,8 +364,8 @@ void RTCIceTransport::gather(RTCIceGatherOptions* options,
return;
}
gathering_state_ = cricket::kIceGatheringGathering;
- proxy_->StartGathering(ConvertIceParameters(local_parameters_), stun_servers,
- turn_servers,
+ proxy_->StartGathering(ConvertIceParameters(local_parameters_).value(),
+ stun_servers, turn_servers,
IceTransportPolicyFromString(options->gatherPolicy()));
}
@@ -385,18 +386,27 @@ static bool RTCIceParametersAreEqual(const RTCIceParameters* a,
a->password() == b->password();
}
-void RTCIceTransport::start(RTCIceParameters* remote_parameters,
+void RTCIceTransport::start(RTCIceParameters* raw_remote_parameters,
const String& role_string,
ExceptionState& exception_state) {
if (RaiseExceptionIfClosed(exception_state)) {
return;
}
- if (!remote_parameters->hasUsernameFragment() ||
- !remote_parameters->hasPassword()) {
+ if (!raw_remote_parameters->hasUsernameFragment() ||
+ !raw_remote_parameters->hasPassword()) {
exception_state.ThrowTypeError(
"remoteParameters must have usernameFragment and password fields set.");
return;
}
+ webrtc::RTCErrorOr<cricket::IceParameters> maybe_remote_parameters =
+ ConvertIceParameters(raw_remote_parameters);
+ if (!maybe_remote_parameters.ok()) {
+ ThrowExceptionFromRTCError(maybe_remote_parameters.error(),
+ exception_state);
+ return;
+ }
+ cricket::IceParameters remote_parameters =
+ maybe_remote_parameters.MoveValue();
cricket::IceRole role = IceRoleFromString(role_string);
if (role_ != cricket::ICEROLE_UNKNOWN && role != role_) {
exception_state.ThrowDOMException(
@@ -405,7 +415,7 @@ void RTCIceTransport::start(RTCIceParameters* remote_parameters,
return;
}
if (remote_parameters_ &&
- RTCIceParametersAreEqual(remote_parameters_, remote_parameters)) {
+ RTCIceParametersAreEqual(remote_parameters_, raw_remote_parameters)) {
// No change to remote parameters: do nothing.
return;
}
@@ -422,18 +432,17 @@ void RTCIceTransport::start(RTCIceParameters* remote_parameters,
initial_remote_candidates.push_back(
*ConvertToCricketIceCandidate(*remote_candidate));
}
- proxy_->Start(ConvertIceParameters(remote_parameters), role,
- initial_remote_candidates);
+ proxy_->Start(remote_parameters, role, initial_remote_candidates);
if (consumer_) {
consumer_->OnIceTransportStarted();
}
} else {
remote_candidates_.clear();
state_ = webrtc::IceTransportState::kNew;
- proxy_->HandleRemoteRestart(ConvertIceParameters(remote_parameters));
+ proxy_->HandleRemoteRestart(remote_parameters);
}
- remote_parameters_ = remote_parameters;
+ remote_parameters_ = raw_remote_parameters;
}
void RTCIceTransport::stop() {
@@ -560,10 +569,10 @@ const AtomicString& RTCIceTransport::InterfaceName() const {
}
ExecutionContext* RTCIceTransport::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
-void RTCIceTransport::ContextDestroyed(ExecutionContext*) {
+void RTCIceTransport::ContextDestroyed() {
Close(CloseReason::kContextDestroyed);
}
@@ -573,7 +582,7 @@ bool RTCIceTransport::HasPendingActivity() const {
return !!proxy_;
}
-void RTCIceTransport::Trace(blink::Visitor* visitor) {
+void RTCIceTransport::Trace(Visitor* visitor) {
visitor->Trace(local_candidates_);
visitor->Trace(remote_candidates_);
visitor->Trace(local_parameters_);
@@ -582,7 +591,7 @@ void RTCIceTransport::Trace(blink::Visitor* visitor) {
visitor->Trace(consumer_);
visitor->Trace(peer_connection_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
void RTCIceTransport::Dispose() {
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 c4d027fa44a..ebd077282b8 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
@@ -10,11 +10,10 @@
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_candidate_pair.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_parameters.h"
+#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/peerconnection/adapters/ice_transport_proxy.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate_pair.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_parameters.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
#include "third_party/webrtc/api/transport/enums.h"
@@ -43,7 +42,7 @@ class RTCPeerConnection;
class MODULES_EXPORT RTCIceTransport final
: public EventTargetWithInlineData,
public ActiveScriptWrappable<RTCIceTransport>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public IceTransportProxy::Delegate {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(RTCIceTransport);
@@ -130,7 +129,7 @@ class MODULES_EXPORT RTCIceTransport final
RTCIceParameters* getLocalParameters() const;
RTCIceParameters* getRemoteParameters() const;
void gather(RTCIceGatherOptions* options, ExceptionState& exception_state);
- void start(RTCIceParameters* remote_parameters,
+ void start(RTCIceParameters* raw_remote_parameters,
const String& role,
ExceptionState& exception_state);
void stop();
@@ -146,14 +145,14 @@ class MODULES_EXPORT RTCIceTransport final
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
- // ContextLifecycleObserver overrides.
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver overrides.
+ void ContextDestroyed() override;
// ActiveScriptWrappable overrides.
bool HasPendingActivity() const final;
// For garbage collection.
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
// IceTransportProxy::Delegate overrides.
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.idl
index 6a149899089..7894ce1bcb2 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.idl
@@ -29,13 +29,11 @@ enum RTCIceGatheringState {
// https://w3c.github.io/webrtc-pc/#rtcicetransport
[
ActiveScriptWrappable,
- // Constructor from https://w3c.github.io/webrtc-ice/#rtcicetransport*
- Constructor(),
- ConstructorCallWith=ExecutionContext,
Exposed=Window,
- Measure,
SecureContext
] interface RTCIceTransport : EventTarget {
+ // Constructor from https://w3c.github.io/webrtc-ice/#rtcicetransport*
+ [CallWith=ExecutionContext, Measure] constructor();
// TODO(github.com/w3c/webrtc-ice/issues/4): role is non-null in the
// WebRTC-PC specification.
[Measure] readonly attribute RTCIceRole? role;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport_test.cc
index b5642e3e45d..f6f802c14f4 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport_test.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport_test.cc
@@ -10,11 +10,11 @@
#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_transport_test.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_candidate_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_gather_options.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/test/mock_ice_transport_adapter_cross_thread_factory.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/test/mock_p2p_quic_packet_transport.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate_init.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_gather_options.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h"
#include "third_party/webrtc/pc/webrtc_sdp.h"
@@ -33,10 +33,10 @@ using testing::Mock;
using testing::StrEq;
using testing::StrNe;
-constexpr char kRemoteUsernameFragment1[] = "usernameFragment";
-constexpr char kRemotePassword1[] = "password";
-constexpr char kRemoteUsernameFragment2[] = "secondUsernameFragment";
-constexpr char kRemotePassword2[] = "secondPassword";
+constexpr char kRemoteUsernameFragment1[] = "user";
+constexpr char kRemotePassword1[] = "passwordpasswordpassword";
+constexpr char kRemoteUsernameFragment2[] = "second+user";
+constexpr char kRemotePassword2[] = "password2password2password2";
RTCIceParameters* CreateRemoteRTCIceParameters2() {
RTCIceParameters* ice_parameters = RTCIceParameters::Create();
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_insertable_streams.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_insertable_streams.idl
new file mode 100644
index 00000000000..5c5a979239b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_insertable_streams.idl
@@ -0,0 +1,12 @@
+// 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/alvestrand/webrtc-media-streams/blob/master/explainer.md#api
+// TODO(guidou): Add standards link when available.
+
+[Serializable]
+dictionary RTCInsertableStreams {
+ ReadableStream readableStream;
+ WritableStream writableStream;
+};
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 6a70d3ba1f3..35aa9094e41 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
@@ -52,9 +52,16 @@
#include "third_party/blink/renderer/bindings/modules/v8/media_stream_track_or_string.h"
#include "third_party/blink/renderer/bindings/modules/v8/rtc_ice_candidate_init_or_rtc_ice_candidate.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_media_stream_track.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_answer_options.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_certificate.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_configuration.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_data_channel_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_server.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_offer_options.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_peer_connection_error_callback.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_transceiver_init.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_session_description_callback.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_session_description_init.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_stats_callback.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
@@ -62,7 +69,7 @@
#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/frame/deprecation.h"
-#include "third_party/blink/renderer/core/frame/hosts_using_features.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/modules/crypto/crypto_result_impl.h"
@@ -71,28 +78,21 @@
#include "third_party/blink/renderer/modules/mediastream/media_stream_event.h"
#include "third_party/blink/renderer/modules/mediastream/user_media_controller.h"
#include "third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_answer_options.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_configuration.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_data_channel_init.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_error_util.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_server.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_offer_options.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_init.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_session_description.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_session_description_init.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_stats_report.h"
@@ -121,7 +121,6 @@
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/webrtc/api/data_channel_interface.h"
-
#include "third_party/webrtc/api/dtls_transport_interface.h"
#include "third_party/webrtc/api/jsep.h"
#include "third_party/webrtc/api/peer_connection_interface.h"
@@ -213,7 +212,7 @@ RTCAnswerOptionsPlatform* ConvertToRTCAnswerOptionsPlatform(
: true);
}
-scoped_refptr<RTCIceCandidatePlatform> ConvertToRTCIceCandidatePlatform(
+RTCIceCandidatePlatform* ConvertToRTCIceCandidatePlatform(
ExecutionContext* context,
const RTCIceCandidateInitOrRTCIceCandidate& candidate) {
DCHECK(!candidate.IsNull());
@@ -228,7 +227,7 @@ scoped_refptr<RTCIceCandidatePlatform> ConvertToRTCIceCandidatePlatform(
UseCounter::Count(context,
WebFeature::kRTCIceCandidateDefaultSdpMLineIndex);
}
- return RTCIceCandidatePlatform::Create(
+ return MakeGarbageCollected<RTCIceCandidatePlatform>(
ice_candidate_init->candidate(), ice_candidate_init->sdpMid(),
sdp_m_line_index, ice_candidate_init->usernameFragment());
}
@@ -354,7 +353,7 @@ webrtc::PeerConnectionInterface::RTCConfiguration ParseConfiguration(
WebVector<webrtc::PeerConnectionInterface::IceServer> ice_servers;
for (const RTCIceServer* ice_server : configuration->iceServers()) {
Vector<String> url_strings;
- if (ice_server->hasURLs()) {
+ if (ice_server->hasUrls()) {
UseCounter::Count(context, WebFeature::kRTCIceServerURLs);
const StringOrStringSequence& urls = ice_server->urls();
if (urls.IsString()) {
@@ -363,7 +362,7 @@ webrtc::PeerConnectionInterface::RTCConfiguration ParseConfiguration(
DCHECK(urls.IsStringSequence());
url_strings = urls.GetAsStringSequence();
}
- } else if (ice_server->hasURL()) {
+ } else if (ice_server->hasUrl()) {
UseCounter::Count(context, WebFeature::kRTCIceServerURL);
url_strings.push_back(ice_server->url());
} else {
@@ -526,6 +525,11 @@ bool FingerprintMismatch(String old_sdp, String new_sdp) {
new_fingerprint_end - new_fingerprint_pos);
}
+bool ContainsLegacySimulcast(String sdp) {
+ // Looks for the non-spec simulcast that іs enabled via SDP munging.
+ return sdp.Find("\na=ssrc-group:SIM") != kNotFound;
+}
+
enum class SdpFormat {
kSimple,
kComplexPlanB,
@@ -628,7 +632,7 @@ bool RTCPeerConnection::EventWrapper::Setup() {
return true;
}
-void RTCPeerConnection::EventWrapper::Trace(blink::Visitor* visitor) {
+void RTCPeerConnection::EventWrapper::Trace(Visitor* visitor) {
visitor->Trace(event_);
}
@@ -637,14 +641,19 @@ RTCPeerConnection* RTCPeerConnection::Create(
const RTCConfiguration* rtc_configuration,
const Dictionary& media_constraints,
ExceptionState& exception_state) {
+ if (context->IsContextDestroyed()) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotSupportedError,
+ "PeerConnections may not be created in detached documents.");
+ return nullptr;
+ }
+
// Count number of PeerConnections that could potentially be impacted by CSP
- if (context) {
- auto& security_context = context->GetSecurityContext();
- auto* content_security_policy = security_context.GetContentSecurityPolicy();
- if (content_security_policy &&
- content_security_policy->IsActiveForConnections()) {
- UseCounter::Count(context, WebFeature::kRTCPeerConnectionWithActiveCsp);
- }
+ auto& security_context = context->GetSecurityContext();
+ auto* content_security_policy = security_context.GetContentSecurityPolicy();
+ if (content_security_policy &&
+ content_security_policy->IsActiveForConnections()) {
+ UseCounter::Count(context, WebFeature::kRTCPeerConnectionWithActiveCsp);
}
if (media_constraints.IsObject()) {
@@ -676,7 +685,7 @@ RTCPeerConnection* RTCPeerConnection::Create(
}
MediaErrorState media_error_state;
- WebMediaConstraints constraints = media_constraints_impl::Create(
+ MediaConstraints constraints = media_constraints_impl::Create(
context, media_constraints, media_error_state);
if (media_error_state.HadException()) {
media_error_state.RaiseException(exception_state);
@@ -685,7 +694,9 @@ RTCPeerConnection* RTCPeerConnection::Create(
RTCPeerConnection* peer_connection = MakeGarbageCollected<RTCPeerConnection>(
context, std::move(configuration), rtc_configuration->hasSdpSemantics(),
- constraints, exception_state);
+ rtc_configuration->forceEncodedAudioInsertableStreams(),
+ rtc_configuration->forceEncodedVideoInsertableStreams(), constraints,
+ exception_state);
if (exception_state.HadException())
return nullptr;
@@ -699,13 +710,36 @@ RTCPeerConnection* RTCPeerConnection::Create(
return peer_connection;
}
+RTCPeerConnection* RTCPeerConnection::Create(
+ ExecutionContext* context,
+ const RTCConfiguration* rtc_configuration,
+ const ScriptValue& media_constraints_value,
+ ExceptionState& exception_state) {
+ Dictionary media_constraints(context->GetIsolate(),
+ media_constraints_value.V8Value(),
+ exception_state);
+ if (exception_state.HadException())
+ return nullptr;
+
+ return Create(context, rtc_configuration, media_constraints, exception_state);
+}
+
+RTCPeerConnection* RTCPeerConnection::Create(
+ ExecutionContext* context,
+ const RTCConfiguration* rtc_configuration,
+ ExceptionState& exception_state) {
+ return Create(context, rtc_configuration, Dictionary(), exception_state);
+}
+
RTCPeerConnection::RTCPeerConnection(
ExecutionContext* context,
webrtc::PeerConnectionInterface::RTCConfiguration configuration,
bool sdp_semantics_specified,
- WebMediaConstraints constraints,
+ bool force_encoded_audio_insertable_streams,
+ bool force_encoded_video_insertable_streams,
+ MediaConstraints constraints,
ExceptionState& exception_state)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
signaling_state_(
webrtc::PeerConnectionInterface::SignalingState::kStable),
ice_gathering_state_(webrtc::PeerConnectionInterface::kIceGatheringNew),
@@ -720,8 +754,12 @@ RTCPeerConnection::RTCPeerConnection(
sdp_semantics_specified_(sdp_semantics_specified),
blink_webrtc_time_diff_(
base::TimeTicks::Now() - base::TimeTicks() -
- base::TimeDelta::FromMicroseconds(rtc::TimeMicros())) {
- Document* document = To<Document>(GetExecutionContext());
+ base::TimeDelta::FromMicroseconds(rtc::TimeMicros())),
+ force_encoded_audio_insertable_streams_(
+ force_encoded_audio_insertable_streams),
+ force_encoded_video_insertable_streams_(
+ force_encoded_video_insertable_streams) {
+ LocalDOMWindow* window = To<LocalDOMWindow>(context);
InstanceCounters::IncrementCounter(
InstanceCounters::kRTCPeerConnectionCounter);
@@ -735,14 +773,6 @@ RTCPeerConnection::RTCPeerConnection(
"Cannot create so many PeerConnections");
return;
}
- if (!document->GetFrame()) {
- closed_ = true;
- stopped_ = true;
- exception_state.ThrowDOMException(
- DOMExceptionCode::kNotSupportedError,
- "PeerConnections may not be created in detached documents.");
- return;
- }
// Tests might need a custom RtcPeerConnectionHandler implementation.
if (!g_create_rpc_peer_connection_handler_callback_.Get().is_null()) {
@@ -752,7 +782,9 @@ RTCPeerConnection::RTCPeerConnection(
peer_handler_ =
PeerConnectionDependencyFactory::GetInstance()
->CreateRTCPeerConnectionHandler(
- this, document->GetTaskRunner(TaskType::kInternalMedia));
+ this, window->GetTaskRunner(TaskType::kInternalMedia),
+ force_encoded_audio_insertable_streams_,
+ force_encoded_video_insertable_streams_);
}
if (!peer_handler_) {
@@ -764,14 +796,9 @@ RTCPeerConnection::RTCPeerConnection(
return;
}
- // TODO(crbug.com/787254): Can the frame be associated when
- // calling RtcPeerConnectionHandler::Initialize()?
- auto* web_local_frame =
- static_cast<WebLocalFrame*>(WebFrame::FromFrame(document->GetFrame()));
- if (web_local_frame)
- peer_handler_->AssociateWithFrame(web_local_frame);
-
- if (!peer_handler_->Initialize(configuration, constraints)) {
+ 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(
@@ -781,7 +808,7 @@ RTCPeerConnection::RTCPeerConnection(
}
feature_handle_for_scheduler_ =
- document->GetFrame()->GetFrameScheduler()->RegisterFeature(
+ window->GetFrame()->GetFrameScheduler()->RegisterFeature(
SchedulingPolicy::Feature::kWebRTC,
{SchedulingPolicy::DisableAggressiveThrottling(),
SchedulingPolicy::RecordMetricsForBackForwardCache()});
@@ -800,45 +827,21 @@ RTCPeerConnection::~RTCPeerConnection() {
}
void RTCPeerConnection::Dispose() {
- // Promptly clears a raw reference from content/ to an on-heap object
+ // Promptly clears the handler's pointer to |this|
// so that content/ doesn't access it in a lazy sweeping phase.
- peer_handler_.reset();
-
- // UMA for CallSetupStates. This metric is reported regardless of whether or
- // not getUserMedia() has been called in this document.
- UMA_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.CallSetupState.OffererState",
- call_setup_state_tracker_.offerer_state());
- UMA_HISTOGRAM_ENUMERATION(
- "WebRTC.PeerConnection.CallSetupState.AnswererState",
- call_setup_state_tracker_.answerer_state());
- UMA_HISTOGRAM_ENUMERATION(
- "WebRTC.PeerConnection.CallSetupState.CallSetupState",
- call_setup_state_tracker_.GetCallSetupState());
- // UMA for CallSetupStates only for documents that have performed
- // getUserMedia(). This heuristic hints that the peer connection is likely
- // used in a media/conferencing context, which is a use case that may be
- // particularly sensitive to the Plan B vs Unified Plan switch.
- if (call_setup_state_tracker_.document_uses_media()) {
- UMA_HISTOGRAM_ENUMERATION(
- "WebRTC.PeerConnection.CallSetupStateWithGum.OffererState",
- call_setup_state_tracker_.offerer_state());
- UMA_HISTOGRAM_ENUMERATION(
- "WebRTC.PeerConnection.CallSetupStateWithGum.AnswererState",
- call_setup_state_tracker_.answerer_state());
- UMA_HISTOGRAM_ENUMERATION(
- "WebRTC.PeerConnection.CallSetupStateWithGum.CallSetupState",
- call_setup_state_tracker_.GetCallSetupState());
+ if (peer_handler_) {
+ peer_handler_->StopAndUnregister();
}
}
ScriptPromise RTCPeerConnection::createOffer(ScriptState* script_state,
- const RTCOfferOptions* options) {
+ const RTCOfferOptions* options,
+ ExceptionState& exception_state) {
if (signaling_state_ ==
webrtc::PeerConnectionInterface::SignalingState::kClosed) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- kSignalingStateClosedMessage));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ kSignalingStateClosedMessage);
+ return ScriptPromise();
}
call_setup_state_tracker_.NoteOffererStateEvent(
OffererState::kCreateOfferPending, HasDocumentMedia());
@@ -865,6 +868,31 @@ ScriptPromise RTCPeerConnection::createOffer(
ScriptState* script_state,
V8RTCSessionDescriptionCallback* success_callback,
V8RTCPeerConnectionErrorCallback* error_callback,
+ const ScriptValue& rtc_offer_options_value,
+ ExceptionState& exception_state) {
+ Dictionary rtc_offer_options(script_state->GetIsolate(),
+ rtc_offer_options_value.V8Value(),
+ exception_state);
+ if (exception_state.HadException())
+ return ScriptPromise();
+
+ return CreateOffer(script_state, success_callback, error_callback,
+ rtc_offer_options, exception_state);
+}
+
+ScriptPromise RTCPeerConnection::createOffer(
+ ScriptState* script_state,
+ V8RTCSessionDescriptionCallback* success_callback,
+ V8RTCPeerConnectionErrorCallback* error_callback,
+ ExceptionState& exception_state) {
+ return CreateOffer(script_state, success_callback, error_callback,
+ Dictionary(), exception_state);
+}
+
+ScriptPromise RTCPeerConnection::CreateOffer(
+ ScriptState* script_state,
+ V8RTCSessionDescriptionCallback* success_callback,
+ V8RTCPeerConnectionErrorCallback* error_callback,
const Dictionary& rtc_offer_options,
ExceptionState& exception_state) {
DCHECK(success_callback);
@@ -887,7 +915,7 @@ ScriptPromise RTCPeerConnection::createOffer(
RTCCreateSessionDescriptionOperation::kCreateOffer, this,
success_callback, error_callback);
- WebVector<std::unique_ptr<RTCRtpTransceiverPlatform>> platform_transceivers;
+ Vector<std::unique_ptr<RTCRtpTransceiverPlatform>> platform_transceivers;
if (offer_options) {
if (offer_options->OfferToReceiveAudio() != -1 ||
offer_options->OfferToReceiveVideo() != -1) {
@@ -901,7 +929,7 @@ ScriptPromise RTCPeerConnection::createOffer(
platform_transceivers = peer_handler_->CreateOffer(request, offer_options);
} else {
MediaErrorState media_error_state;
- WebMediaConstraints constraints = media_constraints_impl::Create(
+ MediaConstraints constraints = media_constraints_impl::Create(
context, rtc_offer_options, media_error_state);
// Report constraints parsing errors via the callback, but ignore
// unknown/unsupported constraints as they would be silently discarded by
@@ -931,13 +959,13 @@ ScriptPromise RTCPeerConnection::createOffer(
}
ScriptPromise RTCPeerConnection::createAnswer(ScriptState* script_state,
- const RTCAnswerOptions* options) {
+ const RTCAnswerOptions* options,
+ ExceptionState& exception_state) {
if (signaling_state_ ==
webrtc::PeerConnectionInterface::SignalingState::kClosed) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- kSignalingStateClosedMessage));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ kSignalingStateClosedMessage);
+ return ScriptPromise();
}
call_setup_state_tracker_.NoteAnswererStateEvent(
@@ -957,6 +985,30 @@ ScriptPromise RTCPeerConnection::createAnswer(
ScriptState* script_state,
V8RTCSessionDescriptionCallback* success_callback,
V8RTCPeerConnectionErrorCallback* error_callback,
+ const ScriptValue& media_constraints_value,
+ ExceptionState& exception_state) {
+ Dictionary media_constraints(script_state->GetIsolate(),
+ media_constraints_value.V8Value(),
+ exception_state);
+ if (exception_state.HadException())
+ return ScriptPromise();
+ return CreateAnswer(script_state, success_callback, error_callback,
+ media_constraints);
+}
+
+ScriptPromise RTCPeerConnection::createAnswer(
+ ScriptState* script_state,
+ V8RTCSessionDescriptionCallback* success_callback,
+ V8RTCPeerConnectionErrorCallback* error_callback,
+ ExceptionState&) {
+ return CreateAnswer(script_state, success_callback, error_callback,
+ Dictionary());
+}
+
+ScriptPromise RTCPeerConnection::CreateAnswer(
+ ScriptState* script_state,
+ V8RTCSessionDescriptionCallback* success_callback,
+ V8RTCPeerConnectionErrorCallback* error_callback,
const Dictionary& media_constraints) {
DCHECK(success_callback);
DCHECK(error_callback);
@@ -975,7 +1027,7 @@ ScriptPromise RTCPeerConnection::createAnswer(
return ScriptPromise::CastUndefined(script_state);
MediaErrorState media_error_state;
- WebMediaConstraints constraints = media_constraints_impl::Create(
+ MediaConstraints constraints = media_constraints_impl::Create(
context, media_constraints, media_error_state);
// Report constraints parsing errors via the callback, but ignore
// unknown/unsupported constraints as they would be silently discarded by
@@ -1019,6 +1071,10 @@ DOMException* RTCPeerConnection::checkSdpForStateErrors(
DOMExceptionCode::kInvalidModificationError, kModifiedSdpMessage);
} else {
UseCounter::Count(context, WebFeature::kRTCLocalSdpModification);
+ if (ContainsLegacySimulcast(*sdp)) {
+ UseCounter::Count(context,
+ WebFeature::kRTCLocalSdpModificationSimulcast);
+ }
return nullptr;
// TODO(https://crbug.com/823036): Return failure for all modification.
}
@@ -1033,6 +1089,10 @@ DOMException* RTCPeerConnection::checkSdpForStateErrors(
DOMExceptionCode::kInvalidModificationError, kModifiedSdpMessage);
} else {
UseCounter::Count(context, WebFeature::kRTCLocalSdpModification);
+ if (ContainsLegacySimulcast(*sdp)) {
+ UseCounter::Count(context,
+ WebFeature::kRTCLocalSdpModificationSimulcast);
+ }
return nullptr;
// TODO(https://crbug.com/823036): Return failure for all modification.
}
@@ -1072,12 +1132,12 @@ void RTCPeerConnection::MaybeWarnAboutUnsafeSdp(
const RTCSessionDescriptionInit* session_description_init) const {
base::Optional<ComplexSdpCategory> complex_sdp_category =
CheckForComplexSdp(session_description_init);
- if (!complex_sdp_category)
+ if (!complex_sdp_category || !GetExecutionContext())
return;
- Document* document = To<Document>(GetExecutionContext());
- RTCPeerConnectionController::From(*document).MaybeReportComplexSdp(
- *complex_sdp_category);
+ LocalDOMWindow* window = To<LocalDOMWindow>(GetExecutionContext());
+ RTCPeerConnectionController::From(*window->document())
+ .MaybeReportComplexSdp(*complex_sdp_category);
if (*complex_sdp_category == ComplexSdpCategory::kPlanBImplicitSemantics) {
Deprecation::CountDeprecation(
@@ -1211,8 +1271,10 @@ void RTCPeerConnection::GenerateCertificateCompleted(
}
bool RTCPeerConnection::HasDocumentMedia() const {
+ if (!GetExecutionContext())
+ return false;
UserMediaController* user_media_controller = UserMediaController::From(
- To<Document>(GetExecutionContext())->GetFrame());
+ To<LocalDOMWindow>(GetExecutionContext())->GetFrame());
return user_media_controller &&
user_media_controller->HasRequestedUserMedia();
}
@@ -1222,7 +1284,7 @@ void RTCPeerConnection::UpdateIceConnectionState() {
auto new_state = ComputeIceConnectionState();
if (ice_connection_state_ != new_state) {
peer_handler_->TrackIceConnectionStateChange(
- WebRTCPeerConnectionHandler::IceConnectionStateVersion::kDefault,
+ RTCPeerConnectionHandlerPlatform::IceConnectionStateVersion::kDefault,
new_state);
}
ChangeIceConnectionState(new_state);
@@ -1273,7 +1335,8 @@ ScriptPromise RTCPeerConnection::setLocalDescription(
ScriptPromise RTCPeerConnection::setLocalDescription(
ScriptState* script_state,
- const RTCSessionDescriptionInit* session_description_init) {
+ const RTCSessionDescriptionInit* session_description_init,
+ ExceptionState& exception_state) {
if (session_description_init->type().IsNull() &&
session_description_init->sdp().IsNull()) {
return setLocalDescription(script_state);
@@ -1287,7 +1350,10 @@ ScriptPromise RTCPeerConnection::setLocalDescription(
DOMException* exception = checkSdpForStateErrors(
ExecutionContext::From(script_state), session_description_init, &sdp);
if (exception) {
- return ScriptPromise::RejectWithDOMException(script_state, exception);
+ exception_state.ThrowDOMException(
+ static_cast<DOMExceptionCode>(exception->code()),
+ exception->message());
+ return ScriptPromise();
}
}
NoteCallSetupStateEventPending(SetSdpOperationType::kSetLocalDescription,
@@ -1381,7 +1447,8 @@ RTCSessionDescription* RTCPeerConnection::pendingLocalDescription() {
ScriptPromise RTCPeerConnection::setRemoteDescription(
ScriptState* script_state,
- const RTCSessionDescriptionInit* session_description_init) {
+ const RTCSessionDescriptionInit* session_description_init,
+ ExceptionState& exception_state) {
if (session_description_init->type() != "rollback") {
MaybeWarnAboutUnsafeSdp(session_description_init);
ReportSetSdpUsage(SetSdpOperationType::kSetRemoteDescription,
@@ -1389,10 +1456,9 @@ ScriptPromise RTCPeerConnection::setRemoteDescription(
}
if (signaling_state_ ==
webrtc::PeerConnectionInterface::SignalingState::kClosed) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- kSignalingStateClosedMessage));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ kSignalingStateClosedMessage);
+ return ScriptPromise();
}
NoteCallSetupStateEventPending(SetSdpOperationType::kSetRemoteDescription,
@@ -1547,7 +1613,7 @@ RTCConfiguration* RTCPeerConnection::getConfiguration(
}
urls.SetStringSequence(std::move(url_vector));
- ice_server->setURLs(urls);
+ ice_server->setUrls(urls);
ice_server->setUsername(webrtc_server.username.c_str());
ice_server->setCredential(webrtc_server.password.c_str());
ice_servers.push_back(ice_server);
@@ -1627,23 +1693,28 @@ ScriptPromise RTCPeerConnection::generateCertificate(
// Normalize |keygenAlgorithm| with WebCrypto, making sure it is a recognized
// AlgorithmIdentifier.
WebCryptoAlgorithm crypto_algorithm;
- AlgorithmError error;
- if (!NormalizeAlgorithm(keygen_algorithm, kWebCryptoOperationGenerateKey,
- crypto_algorithm, &error)) {
- // Reject generateCertificate with the same error as was produced by
- // WebCrypto. |result| is garbage collected, no need to delete.
- auto* result = MakeGarbageCollected<CryptoResultImpl>(script_state);
- ScriptPromise promise = result->Promise();
- result->CompleteWithError(error.error_type, error.error_details);
- return promise;
+ if (!NormalizeAlgorithm(script_state->GetIsolate(), keygen_algorithm,
+ kWebCryptoOperationGenerateKey, crypto_algorithm,
+ exception_state)) {
+ return ScriptPromise();
}
// Check if |keygenAlgorithm| contains the optional DOMTimeStamp |expires|
// attribute.
base::Optional<DOMTimeStamp> expires;
- if (keygen_algorithm.IsDictionary()) {
- Dictionary keygen_algorithm_dict = keygen_algorithm.GetAsDictionary();
- if (keygen_algorithm_dict.HasProperty("expires", exception_state)) {
+ if (keygen_algorithm.IsObject()) {
+ Dictionary keygen_algorithm_dict(script_state->GetIsolate(),
+ keygen_algorithm.GetAsObject().V8Value(),
+ exception_state);
+ if (exception_state.HadException())
+ return ScriptPromise();
+
+ bool has_expires =
+ keygen_algorithm_dict.HasProperty("expires", exception_state);
+ if (exception_state.HadException())
+ return ScriptPromise();
+
+ if (has_expires) {
v8::Local<v8::Value> expires_value;
keygen_algorithm_dict.Get("expires", expires_value);
if (expires_value->IsNumber()) {
@@ -1658,9 +1729,6 @@ ScriptPromise RTCPeerConnection::generateCertificate(
}
}
}
- if (exception_state.HadException()) {
- return ScriptPromise();
- }
// Convert from WebCrypto representation to recognized WebRTCKeyParams. WebRTC
// supports a small subset of what are valid AlgorithmIdentifiers.
@@ -1682,10 +1750,9 @@ ScriptPromise RTCPeerConnection::generateCertificate(
crypto_algorithm.RsaHashedKeyGenParams()->ModulusLengthBits();
key_params = rtc::KeyParams::RSA(modulus_length, public_exponent);
} else {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotSupportedError,
- unsupported_params_string));
+ exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
+ unsupported_params_string);
+ return ScriptPromise();
}
break;
case kWebCryptoAlgorithmIdEcdsa:
@@ -1695,19 +1762,17 @@ ScriptPromise RTCPeerConnection::generateCertificate(
kWebCryptoNamedCurveP256) {
key_params = rtc::KeyParams::ECDSA(rtc::EC_NIST_P256);
} else {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotSupportedError,
- unsupported_params_string));
+ exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
+ unsupported_params_string);
+ return ScriptPromise();
}
break;
default:
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotSupportedError,
- "The 1st argument provided is an "
- "AlgorithmIdentifier, but the "
- "algorithm is not supported."));
+ exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
+ "The 1st argument provided is an "
+ "AlgorithmIdentifier, but the "
+ "algorithm is not supported.");
+ return ScriptPromise();
break;
}
DCHECK(key_params.has_value());
@@ -1717,10 +1782,9 @@ ScriptPromise RTCPeerConnection::generateCertificate(
// |keyParams| was successfully constructed, but does the certificate
// generator support these parameters?
if (!certificate_generator->IsSupportedKeyParams(key_params.value())) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError,
- unsupported_params_string));
+ exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
+ unsupported_params_string);
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -1755,10 +1819,9 @@ ScriptPromise RTCPeerConnection::addIceCandidate(
ExceptionState& exception_state) {
if (signaling_state_ ==
webrtc::PeerConnectionInterface::SignalingState::kClosed) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- kSignalingStateClosedMessage));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ kSignalingStateClosedMessage);
+ return ScriptPromise();
}
if (IsIceCandidateMissingSdp(candidate)) {
@@ -1767,7 +1830,7 @@ ScriptPromise RTCPeerConnection::addIceCandidate(
return ScriptPromise();
}
- scoped_refptr<RTCIceCandidatePlatform> platform_candidate =
+ RTCIceCandidatePlatform* platform_candidate =
ConvertToRTCIceCandidatePlatform(ExecutionContext::From(script_state),
candidate);
@@ -1804,7 +1867,7 @@ ScriptPromise RTCPeerConnection::addIceCandidate(
return ScriptPromise();
}
- scoped_refptr<RTCIceCandidatePlatform> platform_candidate =
+ RTCIceCandidatePlatform* platform_candidate =
ConvertToRTCIceCandidatePlatform(ExecutionContext::From(script_state),
candidate);
@@ -1905,6 +1968,29 @@ String RTCPeerConnection::connectionState() const {
return String();
}
+base::Optional<bool> RTCPeerConnection::canTrickleIceCandidates() const {
+ if (closed_ || !peer_handler_->RemoteDescription()) {
+ return base::nullopt;
+ }
+ webrtc::PeerConnectionInterface* native_connection =
+ peer_handler_->NativePeerConnection();
+ if (!native_connection) {
+ return base::nullopt;
+ }
+ absl::optional<bool> can_trickle =
+ native_connection->can_trickle_ice_candidates();
+ if (!can_trickle) {
+ return base::nullopt;
+ }
+ return *can_trickle;
+}
+
+bool RTCPeerConnection::canTrickleIceCandidates(bool& is_null) const {
+ base::Optional<bool> result = canTrickleIceCandidates();
+ is_null = !result;
+ return result.value_or(false);
+}
+
void RTCPeerConnection::restartIce() {
if (closed_)
return;
@@ -1913,13 +1999,31 @@ void RTCPeerConnection::restartIce() {
void RTCPeerConnection::addStream(ScriptState* script_state,
MediaStream* stream,
+ const ScriptValue& media_constraints_value,
+ ExceptionState& exception_state) {
+ Dictionary media_constraints(script_state->GetIsolate(),
+ media_constraints_value.V8Value(),
+ exception_state);
+ if (exception_state.HadException())
+ return;
+ AddStream(script_state, stream, media_constraints, exception_state);
+}
+
+void RTCPeerConnection::addStream(ScriptState* script_state,
+ MediaStream* stream,
+ ExceptionState& exception_state) {
+ AddStream(script_state, stream, Dictionary(), exception_state);
+}
+
+void RTCPeerConnection::AddStream(ScriptState* script_state,
+ MediaStream* stream,
const Dictionary& media_constraints,
ExceptionState& exception_state) {
if (ThrowExceptionIfSignalingStateClosed(signaling_state_, &exception_state))
return;
if (!media_constraints.IsUndefinedOrNull()) {
MediaErrorState media_error_state;
- WebMediaConstraints constraints =
+ MediaConstraints constraints =
media_constraints_impl::Create(ExecutionContext::From(script_state),
media_constraints, media_error_state);
if (media_error_state.HadException()) {
@@ -1999,10 +2103,10 @@ MediaStreamVector RTCPeerConnection::getRemoteStreams() const {
return remote_streams;
}
-MediaStream* RTCPeerConnection::getRemoteStreamById(const WebString& id) const {
+MediaStream* RTCPeerConnection::getRemoteStreamById(const String& id) const {
for (const auto& rtp_receiver : rtp_receivers_) {
for (const auto& stream : rtp_receiver->streams()) {
- if (static_cast<WebString>(stream->id()) == id) {
+ if (stream->id() == id) {
return stream;
}
}
@@ -2060,12 +2164,12 @@ ScriptPromise RTCPeerConnection::getStats(ScriptState* script_state,
// "getStats(optional MediaStreamTrack? selector)". null is a valid selector
// value, but a value of the wrong type isn't.
if (first_argument->IsNullOrUndefined())
- return PromiseBasedGetStats(script_state, nullptr);
+ return PromiseBasedGetStats(script_state, nullptr, exception_state);
MediaStreamTrack* track =
V8MediaStreamTrack::ToImplWithTypeCheck(isolate, first_argument);
if (track)
- return PromiseBasedGetStats(script_state, track);
+ return PromiseBasedGetStats(script_state, track, exception_state);
exception_state.ThrowTypeError(
"The argument provided as parameter 1 is neither a callback (function) "
@@ -2094,17 +2198,17 @@ ScriptPromise RTCPeerConnection::LegacyCallbackBasedGetStats(
ScriptPromise RTCPeerConnection::PromiseBasedGetStats(
ScriptState* script_state,
- MediaStreamTrack* selector) {
+ MediaStreamTrack* selector,
+ ExceptionState& exception_state) {
if (!selector) {
ExecutionContext* context = ExecutionContext::From(script_state);
UseCounter::Count(context, WebFeature::kRTCPeerConnectionGetStats);
if (!peer_handler_) {
LOG(ERROR) << "Internal error: peer_handler_ has been discarded";
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kOperationError,
- "Internal error: release in progress"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kOperationError,
+ "Internal error: release in progress");
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
@@ -2132,17 +2236,16 @@ ScriptPromise RTCPeerConnection::PromiseBasedGetStats(
}
}
if (track_uses == 0u) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidAccessError,
- "There is no sender or receiver for the track."));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidAccessError,
+ "There is no sender or receiver for the track.");
+ return ScriptPromise();
}
if (track_uses > 1u) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidAccessError,
- "There are more than one sender or receiver for the track."));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidAccessError,
+ "There are more than one sender or receiver for the track.");
+ return ScriptPromise();
}
// There is just one use of the track, a sender or receiver.
if (track_sender) {
@@ -2179,6 +2282,20 @@ RTCRtpTransceiver* RTCPeerConnection::addTransceiver(
if (ThrowExceptionIfSignalingStateClosed(signaling_state_, &exception_state))
return nullptr;
auto webrtc_init = ToRtpTransceiverInit(init);
+ // Validate sendEncodings.
+ for (auto& encoding : webrtc_init.send_encodings) {
+ if (encoding.rid.length() > 16) {
+ exception_state.ThrowTypeError("Illegal length of rid");
+ return nullptr;
+ }
+ // Allowed characters: a-z 0-9 _ and -
+ if (encoding.rid.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM"
+ "NOPQRSTUVWXYZ0123456789-_") !=
+ std::string::npos) {
+ exception_state.ThrowTypeError("Illegal character in rid");
+ return nullptr;
+ }
+ }
webrtc::RTCErrorOr<std::unique_ptr<RTCRtpTransceiverPlatform>> result =
webrtc::RTCError(webrtc::RTCErrorType::UNSUPPORTED_OPERATION);
if (track_or_kind.IsMediaStreamTrack()) {
@@ -2190,7 +2307,7 @@ RTCRtpTransceiver* RTCPeerConnection::addTransceiver(
const String& kind_string = track_or_kind.GetAsString();
// TODO(hbos): Make cricket::MediaType an allowed identifier in
// rtc_peer_connection.cc and use that instead of a boolean.
- std::string kind;
+ String kind;
if (kind_string == "audio") {
kind = webrtc::MediaStreamTrackInterface::kAudioKind;
} else if (kind_string == "video") {
@@ -2235,7 +2352,7 @@ RTCRtpSender* RTCPeerConnection::addTrack(MediaStreamTrack* track,
}
}
- WebVector<WebMediaStream> web_streams(streams.size());
+ Vector<WebMediaStream> web_streams(streams.size());
for (wtf_size_t i = 0; i < streams.size(); ++i) {
web_streams[i] = streams[i]->Descriptor();
}
@@ -2474,7 +2591,9 @@ RTCRtpSender* RTCPeerConnection::CreateOrUpdateSender(
if (sender_it == rtp_senders_.end()) {
// Create new sender (with empty stream set).
sender = MakeGarbageCollected<RTCRtpSender>(
- this, std::move(web_sender), kind, track, MediaStreamVector());
+ this, std::move(web_sender), kind, track, MediaStreamVector(),
+ force_encoded_audio_insertable_streams(),
+ force_encoded_video_insertable_streams());
rtp_senders_.push_back(sender);
} else {
// Update existing sender (not touching the stream set).
@@ -2494,8 +2613,8 @@ RTCRtpReceiver* RTCPeerConnection::CreateOrUpdateReceiver(
// Create track.
MediaStreamTrack* track;
if (receiver_it == rtp_receivers_.end()) {
- track = MediaStreamTrack::Create(GetExecutionContext(),
- platform_receiver->Track());
+ track = MakeGarbageCollected<MediaStreamTrack>(GetExecutionContext(),
+ platform_receiver->Track());
RegisterTrack(track);
} else {
track = (*receiver_it)->track();
@@ -2507,7 +2626,9 @@ RTCRtpReceiver* RTCPeerConnection::CreateOrUpdateReceiver(
if (receiver_it == rtp_receivers_.end()) {
// Create new receiver.
receiver = MakeGarbageCollected<RTCRtpReceiver>(
- this, std::move(platform_receiver), track, MediaStreamVector());
+ this, std::move(platform_receiver), track, MediaStreamVector(),
+ force_encoded_audio_insertable_streams(),
+ force_encoded_video_insertable_streams());
// Receiving tracks should be muted by default. SetReadyState() propagates
// the related state changes to ensure it is muted on all layers. It also
// fires events - which is not desired - but because they fire synchronously
@@ -2698,22 +2819,24 @@ void RTCPeerConnection::MaybeFireNegotiationNeeded() {
}
void RTCPeerConnection::DidGenerateICECandidate(
- scoped_refptr<RTCIceCandidatePlatform> platform_candidate) {
+ RTCIceCandidatePlatform* platform_candidate) {
DCHECK(!closed_);
DCHECK(GetExecutionContext()->IsContextThread());
DCHECK(platform_candidate);
- RTCIceCandidate* ice_candidate =
- RTCIceCandidate::Create(std::move(platform_candidate));
+ RTCIceCandidate* ice_candidate = RTCIceCandidate::Create(platform_candidate);
ScheduleDispatchEvent(RTCPeerConnectionIceEvent::Create(ice_candidate));
}
-void RTCPeerConnection::DidFailICECandidate(const WebString& host_candidate,
- const WebString& url,
+
+void RTCPeerConnection::DidFailICECandidate(const String& address,
+ base::Optional<uint16_t> port,
+ const String& host_candidate,
+ const String& url,
int error_code,
- const WebString& error_text) {
+ const String& error_text) {
DCHECK(!closed_);
DCHECK(GetExecutionContext()->IsContextThread());
ScheduleDispatchEvent(RTCPeerConnectionIceErrorEvent::Create(
- host_candidate, url, error_code, error_text));
+ address, port, host_candidate, url, error_code, error_text));
}
void RTCPeerConnection::DidChangeSignalingState(
@@ -2737,11 +2860,11 @@ void RTCPeerConnection::DidChangeIceConnectionState(
if (sdp_semantics_ == webrtc::SdpSemantics::kUnifiedPlan) {
// Unified plan relies on UpdateIceConnectionState() instead.
peer_handler_->TrackIceConnectionStateChange(
- WebRTCPeerConnectionHandler::IceConnectionStateVersion::kLegacy,
+ RTCPeerConnectionHandlerPlatform::IceConnectionStateVersion::kLegacy,
new_state);
} else {
peer_handler_->TrackIceConnectionStateChange(
- WebRTCPeerConnectionHandler::IceConnectionStateVersion::kDefault,
+ RTCPeerConnectionHandlerPlatform::IceConnectionStateVersion::kDefault,
new_state);
ChangeIceConnectionState(new_state);
}
@@ -2763,7 +2886,7 @@ void RTCPeerConnection::DidAddReceiverPlanB(
webrtc::PeerConnectionInterface::SignalingState::kClosed)
return;
// Create track.
- MediaStreamTrack* track = MediaStreamTrack::Create(
+ auto* track = MakeGarbageCollected<MediaStreamTrack>(
GetExecutionContext(), platform_receiver->Track());
tracks_.insert(track->Component(), track);
// Create or update streams.
@@ -2804,7 +2927,9 @@ void RTCPeerConnection::DidAddReceiverPlanB(
}
DCHECK(FindReceiver(*platform_receiver) == rtp_receivers_.end());
RTCRtpReceiver* rtp_receiver = MakeGarbageCollected<RTCRtpReceiver>(
- this, std::move(platform_receiver), track, streams);
+ this, std::move(platform_receiver), track, streams,
+ force_encoded_audio_insertable_streams(),
+ force_encoded_video_insertable_streams());
rtp_receivers_.push_back(rtp_receiver);
ScheduleDispatchEvent(MakeGarbageCollected<RTCTrackEvent>(
rtp_receiver, rtp_receiver->track(), streams, nullptr));
@@ -2868,8 +2993,8 @@ void RTCPeerConnection::DidModifySctpTransport(
}
void RTCPeerConnection::DidModifyTransceivers(
- WebVector<std::unique_ptr<RTCRtpTransceiverPlatform>> platform_transceivers,
- WebVector<uintptr_t> removed_transceiver_ids,
+ Vector<std::unique_ptr<RTCRtpTransceiverPlatform>> platform_transceivers,
+ Vector<uintptr_t> removed_transceiver_ids,
bool is_remote_description) {
for (auto id : removed_transceiver_ids) {
for (auto* it = transceivers_.begin(); it != transceivers_.end(); ++it) {
@@ -3000,7 +3125,7 @@ void RTCPeerConnection::DidModifyTransceivers(
void RTCPeerConnection::SetAssociatedMediaStreams(
RTCRtpReceiver* receiver,
- const WebVector<WebString>& stream_ids,
+ const Vector<String>& stream_ids,
HeapVector<std::pair<Member<MediaStream>, Member<MediaStreamTrack>>>*
remove_list,
HeapVector<std::pair<Member<MediaStream>, Member<MediaStreamTrack>>>*
@@ -3011,7 +3136,7 @@ void RTCPeerConnection::SetAssociatedMediaStreams(
for (const auto& stream_id : stream_ids) {
MediaStream* curr_stream = nullptr;
for (const auto& known_stream : known_streams) {
- if (static_cast<WebString>(known_stream->id()) == stream_id) {
+ if (known_stream->id() == stream_id) {
curr_stream = known_stream;
break;
}
@@ -3059,14 +3184,16 @@ void RTCPeerConnection::DidAddRemoteDataChannel(
}
void RTCPeerConnection::DidNoteInterestingUsage(int usage_pattern) {
- Document* document = To<Document>(GetExecutionContext());
- ukm::SourceId source_id = document->UkmSourceID();
+ if (!GetExecutionContext())
+ return;
+ LocalDOMWindow* window = To<LocalDOMWindow>(GetExecutionContext());
+ ukm::SourceId source_id = window->document()->UkmSourceID();
ukm::builders::WebRTC_AddressHarvesting(source_id)
.SetUsagePattern(usage_pattern)
- .Record(document->UkmRecorder());
+ .Record(window->document()->UkmRecorder());
}
-void RTCPeerConnection::ReleasePeerConnectionHandler() {
+void RTCPeerConnection::UnregisterPeerConnectionHandler() {
if (stopped_)
return;
@@ -3074,7 +3201,7 @@ void RTCPeerConnection::ReleasePeerConnectionHandler() {
ice_connection_state_ = webrtc::PeerConnectionInterface::kIceConnectionClosed;
signaling_state_ = webrtc::PeerConnectionInterface::SignalingState::kClosed;
- peer_handler_.reset();
+ peer_handler_->StopAndUnregister();
dispatch_scheduled_events_task_handle_.Cancel();
feature_handle_for_scheduler_.reset();
}
@@ -3090,11 +3217,11 @@ const AtomicString& RTCPeerConnection::InterfaceName() const {
}
ExecutionContext* RTCPeerConnection::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
-void RTCPeerConnection::ContextDestroyed(ExecutionContext*) {
- ReleasePeerConnectionHandler();
+void RTCPeerConnection::ContextDestroyed() {
+ UnregisterPeerConnectionHandler();
}
void RTCPeerConnection::ChangeSignalingState(
@@ -3151,10 +3278,6 @@ void RTCPeerConnection::ChangeIceConnectionState(
}
ice_connection_state_ = ice_connection_state;
DispatchEvent(*Event::Create(event_type_names::kIceconnectionstatechange));
- if (ice_connection_state_ ==
- webrtc::PeerConnectionInterface::kIceConnectionConnected) {
- RecordRapporMetrics();
- }
}
webrtc::PeerConnectionInterface::IceConnectionState
@@ -3276,10 +3399,6 @@ void RTCPeerConnection::CloseInternal() {
dtls_transport_iter.value->Close();
}
- Document* document = To<Document>(GetExecutionContext());
- HostsUsingFeatures::CountAnyWorld(
- *document, HostsUsingFeatures::Feature::kRTCPeerConnectionUsed);
-
feature_handle_for_scheduler_.reset();
}
@@ -3322,29 +3441,7 @@ void RTCPeerConnection::DispatchScheduledEvents() {
events.clear();
}
-void RTCPeerConnection::RecordRapporMetrics() {
- Document* document = To<Document>(GetExecutionContext());
- for (const auto& component : tracks_.Keys()) {
- switch (component->Source()->GetType()) {
- case MediaStreamSource::kTypeAudio:
- HostsUsingFeatures::CountAnyWorld(
- *document, HostsUsingFeatures::Feature::kRTCPeerConnectionAudio);
- break;
- case MediaStreamSource::kTypeVideo:
- HostsUsingFeatures::CountAnyWorld(
- *document, HostsUsingFeatures::Feature::kRTCPeerConnectionVideo);
- break;
- default:
- NOTREACHED();
- }
- }
-
- if (has_data_channels_)
- HostsUsingFeatures::CountAnyWorld(
- *document, HostsUsingFeatures::Feature::kRTCPeerConnectionDataChannel);
-}
-
-void RTCPeerConnection::Trace(blink::Visitor* visitor) {
+void RTCPeerConnection::Trace(Visitor* visitor) {
visitor->Trace(tracks_);
visitor->Trace(rtp_senders_);
visitor->Trace(rtp_receivers_);
@@ -3354,7 +3451,7 @@ void RTCPeerConnection::Trace(blink::Visitor* visitor) {
visitor->Trace(ice_transports_by_native_transport_);
visitor->Trace(sctp_transport_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
MediaStreamObserver::Trace(visitor);
}
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 d756173ba4b..52491f924d9 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
@@ -34,13 +34,10 @@
#include <memory>
#include <utility>
-#include "third_party/blink/public/platform/web_media_constraints.h"
-#include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h"
-#include "third_party/blink/public/platform/web_rtc_peer_connection_handler_client.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/core/v8/script_promise_resolver.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/crypto/normalize_algorithm.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
@@ -50,6 +47,9 @@
#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_session_description_enums.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
+#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_client.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_session_description_request.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_void_request.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
@@ -110,9 +110,9 @@ DeduceSdpUsageCategory(const String& sdp_type,
class MODULES_EXPORT RTCPeerConnection final
: public EventTargetWithInlineData,
- public WebRTCPeerConnectionHandlerClient,
+ public RTCPeerConnectionHandlerClient,
public ActiveScriptWrappable<RTCPeerConnection>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public MediaStreamObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(RTCPeerConnection);
@@ -123,30 +123,62 @@ class MODULES_EXPORT RTCPeerConnection final
const RTCConfiguration*,
const Dictionary&,
ExceptionState&);
+ static RTCPeerConnection* Create(ExecutionContext*,
+ const RTCConfiguration*,
+ const ScriptValue&,
+ ExceptionState&);
+ static RTCPeerConnection* Create(ExecutionContext*,
+ const RTCConfiguration*,
+ ExceptionState&);
RTCPeerConnection(ExecutionContext*,
webrtc::PeerConnectionInterface::RTCConfiguration,
bool sdp_semantics_specified,
- WebMediaConstraints,
+ bool force_encoded_audio_insertable_streams,
+ bool force_encoded_video_insertable_streams,
+ MediaConstraints,
ExceptionState&);
~RTCPeerConnection() override;
- ScriptPromise createOffer(ScriptState*, const RTCOfferOptions*);
ScriptPromise createOffer(ScriptState*,
+ const RTCOfferOptions*,
+ ExceptionState&);
+ ScriptPromise createOffer(ScriptState*,
+ V8RTCSessionDescriptionCallback*,
+ V8RTCPeerConnectionErrorCallback*,
+ const ScriptValue&,
+ ExceptionState&);
+ ScriptPromise createOffer(ScriptState*,
+ V8RTCSessionDescriptionCallback*,
+ V8RTCPeerConnectionErrorCallback*,
+ ExceptionState&);
+ ScriptPromise CreateOffer(ScriptState*,
V8RTCSessionDescriptionCallback*,
V8RTCPeerConnectionErrorCallback*,
const Dictionary&,
ExceptionState&);
- ScriptPromise createAnswer(ScriptState*, const RTCAnswerOptions*);
+ ScriptPromise createAnswer(ScriptState*,
+ const RTCAnswerOptions*,
+ ExceptionState&);
+ ScriptPromise createAnswer(ScriptState*,
+ V8RTCSessionDescriptionCallback*,
+ V8RTCPeerConnectionErrorCallback*,
+ const ScriptValue&,
+ ExceptionState&);
ScriptPromise createAnswer(ScriptState*,
V8RTCSessionDescriptionCallback*,
V8RTCPeerConnectionErrorCallback*,
+ ExceptionState&);
+ ScriptPromise CreateAnswer(ScriptState*,
+ V8RTCSessionDescriptionCallback*,
+ V8RTCPeerConnectionErrorCallback*,
const Dictionary&);
ScriptPromise setLocalDescription(ScriptState*);
ScriptPromise setLocalDescription(ScriptState*,
- const RTCSessionDescriptionInit*);
+ const RTCSessionDescriptionInit*,
+ ExceptionState&);
ScriptPromise setLocalDescription(
ScriptState*,
const RTCSessionDescriptionInit*,
@@ -157,7 +189,8 @@ class MODULES_EXPORT RTCPeerConnection final
RTCSessionDescription* pendingLocalDescription();
ScriptPromise setRemoteDescription(ScriptState*,
- const RTCSessionDescriptionInit*);
+ const RTCSessionDescriptionInit*,
+ ExceptionState&);
ScriptPromise setRemoteDescription(
ScriptState*,
const RTCSessionDescriptionInit*,
@@ -194,17 +227,26 @@ class MODULES_EXPORT RTCPeerConnection final
String connectionState() const;
+ base::Optional<bool> canTrickleIceCandidates() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ bool canTrickleIceCandidates(bool&) const; // DEPRECATED
+
void restartIce();
// A local stream is any stream associated with a sender.
MediaStreamVector getLocalStreams() const;
// A remote stream is any stream associated with a receiver.
MediaStreamVector getRemoteStreams() const;
- MediaStream* getRemoteStreamById(const WebString&) const;
+ MediaStream* getRemoteStreamById(const String&) const;
bool IsRemoteStream(MediaStream* stream) const;
void addStream(ScriptState*,
MediaStream*,
+ const ScriptValue& media_constraints,
+ ExceptionState&);
+ void addStream(ScriptState*, MediaStream*, ExceptionState&);
+ void AddStream(ScriptState*,
+ MediaStream*,
const Dictionary& media_constraints,
ExceptionState&);
@@ -224,7 +266,9 @@ class MODULES_EXPORT RTCPeerConnection final
ScriptState*,
V8RTCStatsCallback* success_callback,
MediaStreamTrack* selector);
- ScriptPromise PromiseBasedGetStats(ScriptState*, MediaStreamTrack* selector);
+ ScriptPromise PromiseBasedGetStats(ScriptState*,
+ MediaStreamTrack* selector,
+ ExceptionState&);
const HeapVector<Member<RTCRtpTransceiver>>& getTransceivers() const;
const HeapVector<Member<RTCRtpSender>>& getSenders() const;
@@ -284,13 +328,16 @@ class MODULES_EXPORT RTCPeerConnection final
void OnStreamAddTrack(MediaStream*, MediaStreamTrack*) override;
void OnStreamRemoveTrack(MediaStream*, MediaStreamTrack*) override;
- // WebRTCPeerConnectionHandlerClient
+ // RTCPeerConnectionHandlerClient
void NegotiationNeeded() override;
- void DidGenerateICECandidate(scoped_refptr<RTCIceCandidatePlatform>) override;
- void DidFailICECandidate(const WebString& host_candidate,
- const WebString& url,
+
+ void DidGenerateICECandidate(RTCIceCandidatePlatform*) override;
+ void DidFailICECandidate(const String& address,
+ base::Optional<uint16_t> port,
+ const String& host_candidate,
+ const String& url,
int error_code,
- const WebString& error_text) override;
+ const String& error_text) override;
void DidChangeSignalingState(
webrtc::PeerConnectionInterface::SignalingState) override;
void DidChangeIceGatheringState(
@@ -302,22 +349,21 @@ class MODULES_EXPORT RTCPeerConnection final
void DidAddReceiverPlanB(std::unique_ptr<RTCRtpReceiverPlatform>) override;
void DidRemoveReceiverPlanB(std::unique_ptr<RTCRtpReceiverPlatform>) override;
void DidModifySctpTransport(WebRTCSctpTransportSnapshot) override;
- void DidModifyTransceivers(
- WebVector<std::unique_ptr<RTCRtpTransceiverPlatform>>,
- WebVector<uintptr_t>,
- bool is_remote_description) override;
+ void DidModifyTransceivers(Vector<std::unique_ptr<RTCRtpTransceiverPlatform>>,
+ Vector<uintptr_t>,
+ bool is_remote_description) override;
void DidAddRemoteDataChannel(
scoped_refptr<webrtc::DataChannelInterface> channel) override;
void DidNoteInterestingUsage(int usage_pattern) override;
- void ReleasePeerConnectionHandler() override;
+ void UnregisterPeerConnectionHandler() override;
void ClosePeerConnection() override;
// EventTarget
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
// ScriptWrappable
// We keep the this object alive until either stopped or closed.
@@ -359,13 +405,21 @@ class MODULES_EXPORT RTCPeerConnection final
webrtc::SdpSemantics sdp_semantics() { return sdp_semantics_; }
- void Trace(blink::Visitor*) override;
+ bool force_encoded_audio_insertable_streams() {
+ return force_encoded_audio_insertable_streams_;
+ }
+
+ bool force_encoded_video_insertable_streams() {
+ return force_encoded_video_insertable_streams_;
+ }
+
+ void Trace(Visitor*) override;
base::TimeTicks WebRtcTimestampToBlinkTimestamp(
base::TimeTicks webrtc_monotonic_time) const;
- using RtcPeerConnectionHandlerFactoryCallback =
- base::RepeatingCallback<std::unique_ptr<WebRTCPeerConnectionHandler>()>;
+ using RtcPeerConnectionHandlerFactoryCallback = base::RepeatingCallback<
+ std::unique_ptr<RTCPeerConnectionHandlerPlatform>()>;
static void SetRtcPeerConnectionHandlerFactoryForTesting(
RtcPeerConnectionHandlerFactoryCallback);
@@ -387,7 +441,7 @@ class MODULES_EXPORT RTCPeerConnection final
// |m_event| will only be fired if setup() returns true;
bool Setup();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
Member<Event> event_;
@@ -454,7 +508,7 @@ class MODULES_EXPORT RTCPeerConnection final
// https://w3c.github.io/webrtc-pc/#set-associated-remote-streams
void SetAssociatedMediaStreams(
RTCRtpReceiver* receiver,
- const WebVector<WebString>& stream_ids,
+ const Vector<String>& stream_ids,
HeapVector<std::pair<Member<MediaStream>, Member<MediaStreamTrack>>>*
remove_list,
HeapVector<std::pair<Member<MediaStream>, Member<MediaStreamTrack>>>*
@@ -518,6 +572,10 @@ class MODULES_EXPORT RTCPeerConnection final
webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state_;
webrtc::PeerConnectionInterface::IceConnectionState ice_connection_state_;
webrtc::PeerConnectionInterface::PeerConnectionState peer_connection_state_;
+ // TODO(https://crbug.com/857004): The trackers' metrics are currently not
+ // uploaded; either use the metrics it produces (i.e. revert
+ // https://chromium-review.googlesource.com/c/chromium/src/+/1991421) or
+ // delete all CallSetupStateTracker code for good.
CallSetupStateTracker call_setup_state_tracker_;
// A map containing any track that is in use by the peer connection. This
@@ -546,7 +604,7 @@ class MODULES_EXPORT RTCPeerConnection final
ice_transports_by_native_transport_;
// TODO(crbug.com/787254): Use RTCPeerConnectionHandler.
- std::unique_ptr<WebRTCPeerConnectionHandler> peer_handler_;
+ std::unique_ptr<RTCPeerConnectionHandlerPlatform> peer_handler_;
TaskHandle dispatch_scheduled_events_task_handle_;
HeapVector<Member<EventWrapper>> scheduled_events_;
@@ -579,6 +637,10 @@ class MODULES_EXPORT RTCPeerConnection final
// Blink and WebRTC timestamp diff.
const base::TimeDelta blink_webrtc_time_diff_;
+
+ // Insertable streams.
+ bool force_encoded_audio_insertable_streams_;
+ bool force_encoded_video_insertable_streams_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.idl
index 916ffb2b598..a977ad2ebdf 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.idl
@@ -61,22 +61,22 @@ enum RTCPeerConnectionState {
// https://w3c.github.io/webrtc-pc/#interface-definition
// TODO(guidou): Many types are of the wrong type in this interface:
-// * Dictionary -> specific dictionary types like RTCConfiguration
+// * any -> specific dictionary types like RTCConfiguration
[
ActiveScriptWrappable,
- // TODO(guidou): There should only be one constructor argument.
- Constructor(optional RTCConfiguration configuration, optional Dictionary mediaConstraints),
- ConstructorCallWith=ExecutionContext,
- RaisesException=Constructor,
- Exposed=Window
+ Exposed=Window,
+ LegacyWindowAlias=webkitRTCPeerConnection,
+ LegacyWindowAlias_Measure
] interface RTCPeerConnection : EventTarget {
- [CallWith=ScriptState] Promise<RTCSessionDescription> createOffer(optional RTCOfferOptions options);
- [CallWith=ScriptState] Promise<RTCSessionDescription> createAnswer(optional RTCAnswerOptions options);
- [CallWith=ScriptState] Promise<void> setLocalDescription(optional RTCSessionDescriptionInit description = {});
+ // TODO(guidou): There should only be one constructor argument.
+ [CallWith=ExecutionContext, RaisesException] constructor(optional RTCConfiguration configuration = {}, optional any mediaConstraints);
+ [CallWith=ScriptState, RaisesException] Promise<RTCSessionDescription> createOffer(optional RTCOfferOptions options = {});
+ [CallWith=ScriptState, RaisesException] Promise<RTCSessionDescription> createAnswer(optional RTCAnswerOptions options = {});
+ [CallWith=ScriptState, RaisesException] Promise<void> setLocalDescription(optional RTCSessionDescriptionInit description = {});
readonly attribute RTCSessionDescription? localDescription;
readonly attribute RTCSessionDescription? currentLocalDescription;
readonly attribute RTCSessionDescription? pendingLocalDescription;
- [CallWith=ScriptState] Promise<void> setRemoteDescription(RTCSessionDescriptionInit description);
+ [CallWith=ScriptState, RaisesException] Promise<void> setRemoteDescription(RTCSessionDescriptionInit description);
readonly attribute RTCSessionDescription? remoteDescription;
readonly attribute RTCSessionDescription? currentRemoteDescription;
readonly attribute RTCSessionDescription? pendingRemoteDescription;
@@ -85,7 +85,7 @@ enum RTCPeerConnectionState {
readonly attribute RTCIceGatheringState iceGatheringState;
readonly attribute RTCIceConnectionState iceConnectionState;
readonly attribute RTCPeerConnectionState connectionState;
- // readonly attribute boolean? canTrickleIceCandidates;
+ readonly attribute boolean? canTrickleIceCandidates;
void restartIce();
[CallWith=ScriptState] RTCConfiguration getConfiguration();
[CallWith=ScriptState, RaisesException] void setConfiguration(RTCConfiguration configuration);
@@ -100,9 +100,9 @@ enum RTCPeerConnectionState {
// https://w3c.github.io/webrtc-pc/#legacy-interface-extensions
// These methods return Promise<void> because having Promise-based versions requires that all overloads return Promises.
- [CallWith=ScriptState, RaisesException] Promise<void> createOffer(RTCSessionDescriptionCallback successCallback, RTCPeerConnectionErrorCallback failureCallback, optional Dictionary rtcOfferOptions);
+ [CallWith=ScriptState, RaisesException] Promise<void> createOffer(RTCSessionDescriptionCallback successCallback, RTCPeerConnectionErrorCallback failureCallback, optional any rtcOfferOptions);
// TODO(guidou): There should be no mediaConstraints argument.
- [CallWith=ScriptState] Promise<void> createAnswer(RTCSessionDescriptionCallback successCallback, RTCPeerConnectionErrorCallback failureCallback, optional Dictionary mediaConstraints);
+ [CallWith=ScriptState, RaisesException] Promise<void> createAnswer(RTCSessionDescriptionCallback successCallback, RTCPeerConnectionErrorCallback failureCallback, optional any mediaConstraints);
// TODO(guidou): The failureCallback argument should be non-optional.
// TODO(crbug.com/841185): |failureCallback| is not nullable in the spec.
[CallWith=ScriptState] Promise<void> setLocalDescription(RTCSessionDescriptionInit description, VoidFunction successCallback, optional RTCPeerConnectionErrorCallback? failureCallback);
@@ -149,8 +149,8 @@ enum RTCPeerConnectionState {
[Measure] sequence<RTCRtpReceiver> getReceivers();
// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addtransceiver
[Measure, RaisesException] RTCRtpTransceiver addTransceiver(
- (MediaStreamTrack or DOMString) track_or_kind,
- optional RTCRtpTransceiverInit init);
+ (MediaStreamTrack or DOMString) trackOrKind,
+ optional RTCRtpTransceiverInit init = {});
// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addtrack
[Measure, RaisesException] RTCRtpSender addTrack(MediaStreamTrack track, MediaStream... streams);
// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-removetrack
@@ -159,8 +159,8 @@ enum RTCPeerConnectionState {
attribute EventHandler ontrack;
// https://w3c.github.io/webrtc-pc/#peer-to-peer-data-api
- [RuntimeEnabled=RTCSctpTransport] readonly attribute RTCSctpTransport? sctp;
- [CallWith=ScriptState, RaisesException] RTCDataChannel createDataChannel(USVString label, optional RTCDataChannelInit dataChannelDict);
+ readonly attribute RTCSctpTransport? sctp;
+ [CallWith=ScriptState, RaisesException] RTCDataChannel createDataChannel(USVString label, optional RTCDataChannelInit dataChannelDict = {});
attribute EventHandler ondatachannel;
// Certificate management
@@ -171,7 +171,7 @@ enum RTCPeerConnectionState {
[Measure] sequence<MediaStream> getLocalStreams();
[Measure] sequence<MediaStream> getRemoteStreams();
// TODO(hbos): Remove |mediaConstraints|, they are no longer supported.
- [Measure, CallWith=ScriptState, RaisesException] void addStream(MediaStream stream, optional Dictionary mediaConstraints);
+ [Measure, CallWith=ScriptState, RaisesException] void addStream(MediaStream stream, optional any mediaConstraints);
[Measure, RaisesException] void removeStream(MediaStream stream);
[Measure, RaisesException] RTCDTMFSender createDTMFSender(MediaStreamTrack track);
attribute EventHandler onaddstream;
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 9457fb951fe..10d2d856ee6 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
@@ -26,8 +26,6 @@
#include "media/base/media_switches.h"
#include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_track.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_media_constraints.h"
-#include "third_party/blink/public/platform/web_rtc_stats.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.h"
@@ -37,6 +35,8 @@
#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.h"
#include "third_party/blink/renderer/modules/peerconnection/webrtc_set_description_observer.h"
#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/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"
@@ -46,11 +46,12 @@
#include "third_party/blink/renderer/platform/peerconnection/rtc_offer_options_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_sender_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_scoped_refptr_cross_thread_copier.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_session_description_request.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/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/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
#include "third_party/webrtc/api/data_channel_interface.h"
@@ -66,6 +67,38 @@ using webrtc::PeerConnectionObserver;
using webrtc::StatsReport;
using webrtc::StatsReports;
+namespace WTF {
+
+template <>
+struct CrossThreadCopier<scoped_refptr<DataChannelInterface>>
+ : public CrossThreadCopierPassThrough<scoped_refptr<DataChannelInterface>> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+template <>
+struct CrossThreadCopier<scoped_refptr<PeerConnectionInterface>>
+ : public CrossThreadCopierPassThrough<
+ scoped_refptr<PeerConnectionInterface>> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+template <>
+struct CrossThreadCopier<scoped_refptr<webrtc::StatsObserver>>
+ : public CrossThreadCopierPassThrough<
+ scoped_refptr<webrtc::StatsObserver>> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+template <>
+struct CrossThreadCopier<
+ RetainedRefWrapper<webrtc::SetSessionDescriptionObserver>>
+ : public CrossThreadCopierPassThrough<
+ RetainedRefWrapper<webrtc::SetSessionDescriptionObserver>> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+} // namespace WTF
+
namespace blink {
namespace {
@@ -101,13 +134,13 @@ RTCSessionDescriptionPlatform* CreateWebKitSessionDescription(
return CreateWebKitSessionDescription(sdp, native_desc->type());
}
-void RunClosureWithTrace(base::OnceClosure closure,
+void RunClosureWithTrace(CrossThreadOnceClosure closure,
const char* trace_event_name) {
TRACE_EVENT0("webrtc", trace_event_name);
std::move(closure).Run();
}
-void RunSynchronousOnceClosure(base::OnceClosure closure,
+void RunSynchronousOnceClosure(CrossThreadOnceClosure closure,
const char* trace_event_name,
base::WaitableEvent* event) {
{
@@ -130,7 +163,7 @@ void RunSynchronousRepeatingClosure(const base::RepeatingClosure& closure,
// Initializes |description| if |description_callback| returns non-null,
// otherwise does nothing.
void GetRTCSessionDescriptionPlatformFromSessionDescriptionCallback(
- base::OnceCallback<const webrtc::SessionDescriptionInterface*()>
+ CrossThreadOnceFunction<const webrtc::SessionDescriptionInterface*()>
description_callback,
std::string* out_type,
std::string* out_sdp,
@@ -153,8 +186,8 @@ void GetRTCSessionDescriptionPlatformFromSessionDescriptionCallback(
// Converter functions from Blink types to WebRTC types.
absl::optional<bool> ConstraintToOptional(
- const blink::WebMediaConstraints& constraints,
- const blink::BooleanConstraint blink::WebMediaTrackConstraintSet::*picker) {
+ const MediaConstraints& constraints,
+ const blink::BooleanConstraint MediaTrackConstraintSetPlatform::*picker) {
bool value;
if (GetConstraintValueAsBoolean(constraints, picker, &value)) {
return absl::optional<bool>(value);
@@ -163,7 +196,7 @@ absl::optional<bool> ConstraintToOptional(
}
void CopyConstraintsIntoRtcConfiguration(
- const blink::WebMediaConstraints constraints,
+ const MediaConstraints constraints,
webrtc::PeerConnectionInterface::RTCConfiguration* configuration) {
// Copy info from constraints into configuration, if present.
if (constraints.IsEmpty()) {
@@ -172,7 +205,7 @@ void CopyConstraintsIntoRtcConfiguration(
bool the_value;
if (GetConstraintValueAsBoolean(
- constraints, &blink::WebMediaTrackConstraintSet::enable_i_pv6,
+ constraints, &MediaTrackConstraintSetPlatform::enable_i_pv6,
&the_value)) {
configuration->disable_ipv6 = !the_value;
} else {
@@ -180,22 +213,22 @@ void CopyConstraintsIntoRtcConfiguration(
configuration->disable_ipv6 = false;
}
- if (GetConstraintValueAsBoolean(
- constraints, &blink::WebMediaTrackConstraintSet::enable_dscp,
- &the_value)) {
+ if (GetConstraintValueAsBoolean(constraints,
+ &MediaTrackConstraintSetPlatform::enable_dscp,
+ &the_value)) {
configuration->set_dscp(the_value);
}
if (GetConstraintValueAsBoolean(
constraints,
- &blink::WebMediaTrackConstraintSet::goog_cpu_overuse_detection,
+ &MediaTrackConstraintSetPlatform::goog_cpu_overuse_detection,
&the_value)) {
configuration->set_cpu_adaptation(the_value);
}
if (GetConstraintValueAsBoolean(
constraints,
- &blink::WebMediaTrackConstraintSet::
+ &MediaTrackConstraintSetPlatform::
goog_enable_video_suspend_below_min_bitrate,
&the_value)) {
configuration->set_suspend_below_min_bitrate(the_value);
@@ -203,22 +236,22 @@ void CopyConstraintsIntoRtcConfiguration(
if (!GetConstraintValueAsBoolean(
constraints,
- &blink::WebMediaTrackConstraintSet::enable_rtp_data_channels,
+ &MediaTrackConstraintSetPlatform::enable_rtp_data_channels,
&configuration->enable_rtp_data_channel)) {
configuration->enable_rtp_data_channel = false;
}
int rate;
if (GetConstraintValueAsInteger(
constraints,
- &blink::WebMediaTrackConstraintSet::goog_screencast_min_bitrate,
+ &MediaTrackConstraintSetPlatform::goog_screencast_min_bitrate,
&rate)) {
configuration->screencast_min_bitrate = rate;
}
configuration->combined_audio_video_bwe = ConstraintToOptional(
constraints,
- &blink::WebMediaTrackConstraintSet::goog_combined_audio_video_bwe);
+ &MediaTrackConstraintSetPlatform::goog_combined_audio_video_bwe);
configuration->enable_dtls_srtp = ConstraintToOptional(
- constraints, &blink::WebMediaTrackConstraintSet::enable_dtls_srtp);
+ constraints, &MediaTrackConstraintSetPlatform::enable_dtls_srtp);
}
// Class mapping responses from calls to libjingle CreateOffer/Answer and
@@ -240,11 +273,12 @@ class CreateSessionDescriptionRequest
void OnSuccess(webrtc::SessionDescriptionInterface* desc) override {
if (!main_thread_->BelongsToCurrentThread()) {
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(
+ PostCrossThreadTask(
+ *main_thread_.get(), FROM_HERE,
+ CrossThreadBindOnce(
&CreateSessionDescriptionRequest::OnSuccess,
- rtc::scoped_refptr<CreateSessionDescriptionRequest>(this), desc));
+ rtc::scoped_refptr<CreateSessionDescriptionRequest>(this),
+ CrossThreadUnretained(desc)));
return;
}
@@ -265,9 +299,9 @@ class CreateSessionDescriptionRequest
}
void OnFailure(webrtc::RTCError error) override {
if (!main_thread_->BelongsToCurrentThread()) {
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(
+ PostCrossThreadTask(
+ *main_thread_.get(), FROM_HERE,
+ CrossThreadBindOnce(
&CreateSessionDescriptionRequest::OnFailure,
rtc::scoped_refptr<CreateSessionDescriptionRequest>(this),
std::move(error)));
@@ -310,7 +344,8 @@ class StatsResponse : public webrtc::StatsObserver {
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
: request_(request.get()), main_thread_(task_runner) {
// Measure the overall time it takes to satisfy a getStats request.
- TRACE_EVENT_ASYNC_BEGIN0("webrtc", "getStats_Native", this);
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("webrtc", "getStats_Native",
+ TRACE_ID_LOCAL(this));
DETACH_FROM_THREAD(signaling_thread_checker_);
}
@@ -429,7 +464,8 @@ class StatsResponse : public webrtc::StatsObserver {
// Record the getStats operation as done before calling into Blink so that
// we don't skew the perf measurements of the native code with whatever the
// callback might be doing.
- TRACE_EVENT_ASYNC_END0("webrtc", "getStats_Native", this);
+ TRACE_EVENT_NESTABLE_ASYNC_END0("webrtc", "getStats_Native",
+ TRACE_ID_LOCAL(this));
request_->requestSucceeded(response);
request_ = nullptr; // must be freed on the main thread.
}
@@ -479,15 +515,18 @@ void GetStatsOnSignalingThread(
}
}
+using RTCStatsReportCallbackInternal =
+ CrossThreadOnceFunction<void(std::unique_ptr<RTCStatsReportPlatform>)>;
+
void GetRTCStatsOnSignalingThread(
const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
- blink::WebRTCStatsReportCallback callback,
- const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids) {
+ RTCStatsReportCallbackInternal callback,
+ const Vector<webrtc::NonStandardGroupId>& exposed_group_ids) {
TRACE_EVENT0("webrtc", "GetRTCStatsOnSignalingThread");
-
- native_peer_connection->GetStats(blink::CreateRTCStatsCollectorCallback(
- main_thread, std::move(callback), exposed_group_ids));
+ native_peer_connection->GetStats(CreateRTCStatsCollectorCallback(
+ main_thread, ConvertToBaseOnceCallback(std::move(callback)),
+ exposed_group_ids));
}
void ConvertOfferOptionsToWebrtcOfferOptions(
@@ -507,12 +546,12 @@ void ConvertAnswerOptionsToWebrtcAnswerOptions(
}
void ConvertConstraintsToWebrtcOfferOptions(
- const blink::WebMediaConstraints& constraints,
+ const MediaConstraints& constraints,
webrtc::PeerConnectionInterface::RTCOfferAnswerOptions* output) {
if (constraints.IsEmpty()) {
return;
}
- std::string failing_name;
+ String failing_name;
if (constraints.Basic().HasMandatoryOutsideSet(
{constraints.Basic().offer_to_receive_audio.GetName(),
constraints.Basic().offer_to_receive_video.GetName(),
@@ -525,16 +564,16 @@ void ConvertConstraintsToWebrtcOfferOptions(
<< failing_name;
}
GetConstraintValueAsInteger(
- constraints, &blink::WebMediaTrackConstraintSet::offer_to_receive_audio,
+ constraints, &MediaTrackConstraintSetPlatform::offer_to_receive_audio,
&output->offer_to_receive_audio);
GetConstraintValueAsInteger(
- constraints, &blink::WebMediaTrackConstraintSet::offer_to_receive_video,
+ constraints, &MediaTrackConstraintSetPlatform::offer_to_receive_video,
&output->offer_to_receive_video);
GetConstraintValueAsBoolean(
- constraints, &blink::WebMediaTrackConstraintSet::voice_activity_detection,
+ constraints, &MediaTrackConstraintSetPlatform::voice_activity_detection,
&output->voice_activity_detection);
GetConstraintValueAsBoolean(constraints,
- &blink::WebMediaTrackConstraintSet::ice_restart,
+ &MediaTrackConstraintSetPlatform::ice_restart,
&output->ice_restart);
}
@@ -731,11 +770,12 @@ class RTCPeerConnectionHandler::WebRtcSetDescriptionObserverImpl
// Instead, do it all synchronously. This must happen as the last step
// before returning so that all effects of SRD have occurred when the
// event executes. https://crbug.com/788558
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(&RTCPeerConnectionHandler::
- WebRtcSetDescriptionObserverImpl::ResolvePromise,
- this));
+ PostCrossThreadTask(
+ *main_thread_.get(), FROM_HERE,
+ CrossThreadBindOnce(
+ &RTCPeerConnectionHandler::WebRtcSetDescriptionObserverImpl::
+ ResolvePromise,
+ WrapRefCounted(this)));
} else {
// Resolve promise immediately if we can. https://crbug.com/788558 still
// needs to be addressed for "setLocalDescription(answer)" rejecting a
@@ -832,31 +872,33 @@ class RTCPeerConnectionHandler::WebRtcSetDescriptionObserverImpl
// and checks for the existence of the RTCPeerConnectionHandler instance before
// delivering callbacks on the main thread.
class RTCPeerConnectionHandler::Observer
- : public WTF::ThreadSafeRefCounted<RTCPeerConnectionHandler::Observer>,
+ : public GarbageCollected<RTCPeerConnectionHandler::Observer>,
public PeerConnectionObserver,
- public blink::RtcEventLogOutputSink {
+ public RtcEventLogOutputSink {
+ USING_GARBAGE_COLLECTED_MIXIN(Observer);
+
public:
Observer(const base::WeakPtr<RTCPeerConnectionHandler>& handler,
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
: handler_(handler), main_thread_(task_runner) {}
+ ~Observer() override = default;
// When an RTC event log is sent back from PeerConnection, it arrives here.
- void OnWebRtcEventLogWrite(const std::string& output) override {
+ void OnWebRtcEventLogWrite(const WTF::Vector<uint8_t>& output) override {
if (!main_thread_->BelongsToCurrentThread()) {
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(
- &RTCPeerConnectionHandler::Observer::OnWebRtcEventLogWrite, this,
- output));
+ PostCrossThreadTask(
+ *main_thread_.get(), FROM_HERE,
+ CrossThreadBindOnce(
+ &RTCPeerConnectionHandler::Observer::OnWebRtcEventLogWrite,
+ WrapCrossThreadPersistent(this), output));
} else if (handler_) {
handler_->OnWebRtcEventLogWrite(output);
}
}
- protected:
- friend class WTF::ThreadSafeRefCounted<RTCPeerConnectionHandler::Observer>;
- ~Observer() override = default;
+ void Trace(Visitor* visitor) override {}
+ protected:
// TODO(hbos): Remove once no longer mandatory to implement.
void OnSignalingChange(PeerConnectionInterface::SignalingState) override {}
void OnAddStream(rtc::scoped_refptr<MediaStreamInterface>) override {}
@@ -864,20 +906,21 @@ class RTCPeerConnectionHandler::Observer
void OnDataChannel(
rtc::scoped_refptr<DataChannelInterface> data_channel) override {
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(
- &RTCPeerConnectionHandler::Observer::OnDataChannelImpl, this,
+ PostCrossThreadTask(
+ *main_thread_.get(), FROM_HERE,
+ CrossThreadBindOnce(
+ &RTCPeerConnectionHandler::Observer::OnDataChannelImpl,
+ WrapCrossThreadPersistent(this),
base::WrapRefCounted<DataChannelInterface>(data_channel.get())));
}
void OnRenegotiationNeeded() override {
if (!main_thread_->BelongsToCurrentThread()) {
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(
+ PostCrossThreadTask(
+ *main_thread_.get(), FROM_HERE,
+ CrossThreadBindOnce(
&RTCPeerConnectionHandler::Observer::OnRenegotiationNeeded,
- this));
+ WrapCrossThreadPersistent(this)));
} else if (handler_) {
handler_->OnRenegotiationNeeded();
}
@@ -888,10 +931,11 @@ class RTCPeerConnectionHandler::Observer
void OnStandardizedIceConnectionChange(
PeerConnectionInterface::IceConnectionState new_state) override {
if (!main_thread_->BelongsToCurrentThread()) {
- main_thread_->PostTask(
- FROM_HERE, base::BindOnce(&RTCPeerConnectionHandler::Observer::
- OnStandardizedIceConnectionChange,
- this, new_state));
+ PostCrossThreadTask(
+ *main_thread_.get(), FROM_HERE,
+ CrossThreadBindOnce(&RTCPeerConnectionHandler::Observer::
+ OnStandardizedIceConnectionChange,
+ WrapCrossThreadPersistent(this), new_state));
} else if (handler_) {
handler_->OnIceConnectionChange(new_state);
}
@@ -900,11 +944,11 @@ class RTCPeerConnectionHandler::Observer
void OnConnectionChange(
PeerConnectionInterface::PeerConnectionState new_state) override {
if (!main_thread_->BelongsToCurrentThread()) {
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(
- &RTCPeerConnectionHandler::Observer::OnConnectionChange, this,
- new_state));
+ PostCrossThreadTask(
+ *main_thread_.get(), FROM_HERE,
+ CrossThreadBindOnce(
+ &RTCPeerConnectionHandler::Observer::OnConnectionChange,
+ WrapCrossThreadPersistent(this), new_state));
} else if (handler_) {
handler_->OnConnectionChange(new_state);
}
@@ -913,11 +957,11 @@ class RTCPeerConnectionHandler::Observer
void OnIceGatheringChange(
PeerConnectionInterface::IceGatheringState new_state) override {
if (!main_thread_->BelongsToCurrentThread()) {
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(
- &RTCPeerConnectionHandler::Observer::OnIceGatheringChange, this,
- new_state));
+ PostCrossThreadTask(
+ *main_thread_.get(), FROM_HERE,
+ CrossThreadBindOnce(
+ &RTCPeerConnectionHandler::Observer::OnIceGatheringChange,
+ WrapCrossThreadPersistent(this), new_state));
} else if (handler_) {
handler_->OnIceGatheringChange(new_state);
}
@@ -930,25 +974,30 @@ class RTCPeerConnectionHandler::Observer
return;
}
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(
- &RTCPeerConnectionHandler::Observer::OnIceCandidateImpl, this,
- String::FromUTF8(sdp), String::FromUTF8(candidate->sdp_mid()),
+ PostCrossThreadTask(
+ *main_thread_.get(), FROM_HERE,
+ CrossThreadBindOnce(
+ &RTCPeerConnectionHandler::Observer::OnIceCandidateImpl,
+ WrapCrossThreadPersistent(this), String::FromUTF8(sdp),
+ String::FromUTF8(candidate->sdp_mid()),
candidate->sdp_mline_index(), candidate->candidate().component(),
candidate->candidate().address().family()));
}
- void OnIceCandidateError(const std::string& host_candidate,
+ void OnIceCandidateError(const std::string& address,
+ int port,
const std::string& url,
int error_code,
const std::string& error_text) override {
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(
- &RTCPeerConnectionHandler::Observer::OnIceCandidateErrorImpl, this,
- String::FromUTF8(host_candidate), String::FromUTF8(url), error_code,
- String::FromUTF8(error_text)));
+ PostCrossThreadTask(
+ *main_thread_.get(), FROM_HERE,
+ CrossThreadBindOnce(
+ &RTCPeerConnectionHandler::Observer::OnIceCandidateErrorImpl,
+ WrapCrossThreadPersistent(this),
+ port ? String::FromUTF8(address) : String(),
+ static_cast<uint16_t>(port),
+ String::Format("%s:%d", address.c_str(), port),
+ String::FromUTF8(url), error_code, String::FromUTF8(error_text)));
}
void OnDataChannelImpl(scoped_refptr<DataChannelInterface> channel) {
@@ -969,23 +1018,28 @@ class RTCPeerConnectionHandler::Observer
}
}
- void OnIceCandidateErrorImpl(const String& host_candidate,
+ void OnIceCandidateErrorImpl(const String& address,
+ int port,
+ const String& host_candidate,
const String& url,
int error_code,
const String& error_text) {
DCHECK(main_thread_->BelongsToCurrentThread());
if (handler_) {
- handler_->OnIceCandidateError(host_candidate, url, error_code,
- error_text);
+ handler_->OnIceCandidateError(
+ address,
+ port ? base::Optional<uint16_t>(static_cast<uint16_t>(port))
+ : base::nullopt,
+ host_candidate, url, error_code, error_text);
}
}
void OnInterestingUsage(int usage_pattern) override {
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(
- &RTCPeerConnectionHandler::Observer::OnInterestingUsageImpl, this,
- usage_pattern));
+ PostCrossThreadTask(
+ *main_thread_.get(), FROM_HERE,
+ CrossThreadBindOnce(
+ &RTCPeerConnectionHandler::Observer::OnInterestingUsageImpl,
+ WrapCrossThreadPersistent(this), usage_pattern));
}
void OnInterestingUsageImpl(int usage_pattern) {
@@ -1001,17 +1055,24 @@ class RTCPeerConnectionHandler::Observer
};
RTCPeerConnectionHandler::RTCPeerConnectionHandler(
- blink::WebRTCPeerConnectionHandlerClient* client,
+ RTCPeerConnectionHandlerClient* client,
blink::PeerConnectionDependencyFactory* dependency_factory,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ bool force_encoded_audio_insertable_streams,
+ bool force_encoded_video_insertable_streams)
: initialize_called_(false),
client_(client),
is_closed_(false),
+ is_unregistered_(false),
dependency_factory_(dependency_factory),
track_adapter_map_(
base::MakeRefCounted<blink::WebRtcMediaStreamTrackAdapterMap>(
dependency_factory_,
task_runner)),
+ force_encoded_audio_insertable_streams_(
+ force_encoded_audio_insertable_streams),
+ force_encoded_video_insertable_streams_(
+ force_encoded_video_insertable_streams),
task_runner_(std::move(task_runner)) {
CHECK(client_);
@@ -1019,6 +1080,12 @@ RTCPeerConnectionHandler::RTCPeerConnectionHandler(
}
RTCPeerConnectionHandler::~RTCPeerConnectionHandler() {
+ if (!is_unregistered_) {
+ StopAndUnregister();
+ }
+}
+
+void RTCPeerConnectionHandler::StopAndUnregister() {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
Stop();
@@ -1029,20 +1096,20 @@ RTCPeerConnectionHandler::~RTCPeerConnectionHandler() {
UMA_HISTOGRAM_COUNTS_10000("WebRTC.NumDataChannelsPerPeerConnection",
num_data_channels_created_);
-}
-
-void RTCPeerConnectionHandler::AssociateWithFrame(blink::WebLocalFrame* frame) {
- DCHECK(task_runner_->RunsTasksInCurrentSequence());
- DCHECK(frame);
- frame_ = frame;
+ // Clear the pointer to client_ so that it does not interfere with
+ // garbage collection.
+ client_ = nullptr;
+ is_unregistered_ = true;
}
bool RTCPeerConnectionHandler::Initialize(
const webrtc::PeerConnectionInterface::RTCConfiguration&
server_configuration,
- const blink::WebMediaConstraints& options) {
+ const MediaConstraints& options,
+ WebLocalFrame* frame) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
- DCHECK(frame_);
+ DCHECK(frame);
+ frame_ = frame;
CHECK(!initialize_called_);
initialize_called_ = true;
@@ -1073,9 +1140,9 @@ bool RTCPeerConnectionHandler::Initialize(
CopyConstraintsIntoRtcConfiguration(options, &configuration_);
peer_connection_observer_ =
- base::MakeRefCounted<Observer>(weak_factory_.GetWeakPtr(), task_runner_);
+ MakeGarbageCollected<Observer>(weak_factory_.GetWeakPtr(), task_runner_);
native_peer_connection_ = dependency_factory_->CreatePeerConnection(
- configuration_, frame_, peer_connection_observer_.get());
+ configuration_, frame_, peer_connection_observer_);
if (!native_peer_connection_.get()) {
LOG(ERROR) << "Failed to initialize native PeerConnection.";
@@ -1093,7 +1160,7 @@ bool RTCPeerConnectionHandler::Initialize(
bool RTCPeerConnectionHandler::InitializeForTest(
const webrtc::PeerConnectionInterface::RTCConfiguration&
server_configuration,
- const blink::WebMediaConstraints& options,
+ const MediaConstraints& options,
const base::WeakPtr<PeerConnectionTracker>& peer_connection_tracker) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
@@ -1103,11 +1170,11 @@ bool RTCPeerConnectionHandler::InitializeForTest(
configuration_ = server_configuration;
peer_connection_observer_ =
- base::MakeRefCounted<Observer>(weak_factory_.GetWeakPtr(), task_runner_);
+ MakeGarbageCollected<Observer>(weak_factory_.GetWeakPtr(), task_runner_);
CopyConstraintsIntoRtcConfiguration(options, &configuration_);
native_peer_connection_ = dependency_factory_->CreatePeerConnection(
- configuration_, nullptr, peer_connection_observer_.get());
+ configuration_, nullptr, peer_connection_observer_);
if (!native_peer_connection_.get()) {
LOG(ERROR) << "Failed to initialize native PeerConnection.";
return false;
@@ -1116,10 +1183,9 @@ bool RTCPeerConnectionHandler::InitializeForTest(
return true;
}
-blink::WebVector<std::unique_ptr<RTCRtpTransceiverPlatform>>
-RTCPeerConnectionHandler::CreateOffer(
- blink::RTCSessionDescriptionRequest* request,
- const blink::WebMediaConstraints& options) {
+Vector<std::unique_ptr<RTCRtpTransceiverPlatform>>
+RTCPeerConnectionHandler::CreateOffer(RTCSessionDescriptionRequest* request,
+ const MediaConstraints& options) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::createOffer");
@@ -1131,10 +1197,9 @@ RTCPeerConnectionHandler::CreateOffer(
return CreateOfferInternal(request, std::move(webrtc_options));
}
-blink::WebVector<std::unique_ptr<RTCRtpTransceiverPlatform>>
-RTCPeerConnectionHandler::CreateOffer(
- blink::RTCSessionDescriptionRequest* request,
- blink::RTCOfferOptionsPlatform* options) {
+Vector<std::unique_ptr<RTCRtpTransceiverPlatform>>
+RTCPeerConnectionHandler::CreateOffer(RTCSessionDescriptionRequest* request,
+ RTCOfferOptionsPlatform* options) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::createOffer");
@@ -1146,7 +1211,7 @@ RTCPeerConnectionHandler::CreateOffer(
return CreateOfferInternal(request, std::move(webrtc_options));
}
-std::vector<std::unique_ptr<RTCRtpTransceiverPlatform>>
+Vector<std::unique_ptr<RTCRtpTransceiverPlatform>>
RTCPeerConnectionHandler::CreateOfferInternal(
blink::RTCSessionDescriptionRequest* request,
webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options) {
@@ -1168,7 +1233,7 @@ RTCPeerConnectionHandler::CreateOfferInternal(
DCHECK(transceiver_state_surfacer.is_initialized());
auto transceiver_states = transceiver_state_surfacer.ObtainStates();
- std::vector<std::unique_ptr<RTCRtpTransceiverPlatform>> transceivers;
+ Vector<std::unique_ptr<RTCRtpTransceiverPlatform>> transceivers;
for (auto& transceiver_state : transceiver_states) {
auto transceiver = CreateOrUpdateTransceiver(
std::move(transceiver_state), blink::TransceiverStateUpdateMode::kAll);
@@ -1194,7 +1259,7 @@ void RTCPeerConnectionHandler::CreateOfferOnSignalingThread(
void RTCPeerConnectionHandler::CreateAnswer(
blink::RTCSessionDescriptionRequest* request,
- const blink::WebMediaConstraints& options) {
+ const MediaConstraints& options) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::createAnswer");
scoped_refptr<CreateSessionDescriptionRequest> description_request(
@@ -1261,16 +1326,16 @@ void RTCPeerConnectionHandler::SetLocalDescription(
track_adapter_map_, content_observer, surface_receivers_only)
.get());
- signaling_thread()->PostTask(
- FROM_HERE,
- base::BindOnce(
+ PostCrossThreadTask(
+ *signaling_thread().get(), FROM_HERE,
+ CrossThreadBindOnce(
&RunClosureWithTrace,
- base::BindOnce(
+ CrossThreadBindOnce(
static_cast<void (webrtc::PeerConnectionInterface::*)(
webrtc::SetSessionDescriptionObserver*)>(
&webrtc::PeerConnectionInterface::SetLocalDescription),
- native_peer_connection_, base::RetainedRef(webrtc_observer)),
- "SetLocalDescription"));
+ native_peer_connection_, WTF::RetainedRef(webrtc_observer)),
+ CrossThreadUnretained("SetLocalDescription")));
}
void RTCPeerConnectionHandler::SetLocalDescription(
@@ -1337,20 +1402,18 @@ void RTCPeerConnectionHandler::SetLocalDescription(
track_adapter_map_, content_observer, surface_receivers_only)
.get());
- signaling_thread()->PostTask(
- FROM_HERE,
- base::BindOnce(
+ PostCrossThreadTask(
+ *signaling_thread().get(), FROM_HERE,
+ CrossThreadBindOnce(
&RunClosureWithTrace,
- base::BindOnce(
+ CrossThreadBindOnce(
static_cast<void (webrtc::PeerConnectionInterface::*)(
webrtc::SetSessionDescriptionObserver*,
webrtc::SessionDescriptionInterface*)>(
&webrtc::PeerConnectionInterface::SetLocalDescription),
- native_peer_connection_,
- // TODO(crbug.com/787254): Replace with WTF::WrapRefCounted?
- base::RetainedRef(webrtc_observer),
- base::Unretained(native_desc)),
- "SetLocalDescription"));
+ native_peer_connection_, WTF::RetainedRef(webrtc_observer),
+ CrossThreadUnretained(native_desc)),
+ CrossThreadUnretained("SetLocalDescription")));
}
void RTCPeerConnectionHandler::SetRemoteDescription(
@@ -1420,29 +1483,29 @@ void RTCPeerConnectionHandler::SetRemoteDescription(
content_observer, surface_receivers_only)
.get());
- signaling_thread()->PostTask(
- FROM_HERE,
- base::BindOnce(
+ PostCrossThreadTask(
+ *signaling_thread().get(), FROM_HERE,
+ CrossThreadBindOnce(
&RunClosureWithTrace,
- base::BindOnce(
+ CrossThreadBindOnce(
static_cast<void (webrtc::PeerConnectionInterface::*)(
std::unique_ptr<webrtc::SessionDescriptionInterface>,
rtc::scoped_refptr<
webrtc::SetRemoteDescriptionObserverInterface>)>(
&webrtc::PeerConnectionInterface::SetRemoteDescription),
- native_peer_connection_, base::Passed(&native_desc),
+ native_peer_connection_, WTF::Passed(std::move(native_desc)),
webrtc_observer),
- "SetRemoteDescription"));
+ CrossThreadUnretained("SetRemoteDescription")));
}
RTCSessionDescriptionPlatform* RTCPeerConnectionHandler::LocalDescription() {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::localDescription");
- base::OnceCallback<const webrtc::SessionDescriptionInterface*()>
- description_cb =
- base::BindOnce(&webrtc::PeerConnectionInterface::local_description,
- native_peer_connection_);
+ CrossThreadOnceFunction<const webrtc::SessionDescriptionInterface*()>
+ description_cb = CrossThreadBindOnce(
+ &webrtc::PeerConnectionInterface::local_description,
+ native_peer_connection_);
return GetRTCSessionDescriptionPlatformOnSignalingThread(
std::move(description_cb), "localDescription");
}
@@ -1450,10 +1513,11 @@ RTCSessionDescriptionPlatform* RTCPeerConnectionHandler::LocalDescription() {
RTCSessionDescriptionPlatform* RTCPeerConnectionHandler::RemoteDescription() {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::remoteDescription");
- base::OnceCallback<const webrtc::SessionDescriptionInterface*()>
- description_cb =
- base::BindOnce(&webrtc::PeerConnectionInterface::remote_description,
- native_peer_connection_);
+
+ CrossThreadOnceFunction<const webrtc::SessionDescriptionInterface*()>
+ description_cb = CrossThreadBindOnce(
+ &webrtc::PeerConnectionInterface::remote_description,
+ native_peer_connection_);
return GetRTCSessionDescriptionPlatformOnSignalingThread(
std::move(description_cb), "remoteDescription");
}
@@ -1463,8 +1527,8 @@ RTCPeerConnectionHandler::CurrentLocalDescription() {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::currentLocalDescription");
- base::OnceCallback<const webrtc::SessionDescriptionInterface*()>
- description_cb = base::BindOnce(
+ CrossThreadOnceFunction<const webrtc::SessionDescriptionInterface*()>
+ description_cb = CrossThreadBindOnce(
&webrtc::PeerConnectionInterface::current_local_description,
native_peer_connection_);
return GetRTCSessionDescriptionPlatformOnSignalingThread(
@@ -1475,8 +1539,9 @@ RTCSessionDescriptionPlatform*
RTCPeerConnectionHandler::CurrentRemoteDescription() {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::currentRemoteDescription");
- base::OnceCallback<const webrtc::SessionDescriptionInterface*()>
- description_cb = base::BindOnce(
+
+ CrossThreadOnceFunction<const webrtc::SessionDescriptionInterface*()>
+ description_cb = CrossThreadBindOnce(
&webrtc::PeerConnectionInterface::current_remote_description,
native_peer_connection_);
return GetRTCSessionDescriptionPlatformOnSignalingThread(
@@ -1487,8 +1552,9 @@ RTCSessionDescriptionPlatform*
RTCPeerConnectionHandler::PendingLocalDescription() {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::pendingLocalDescription");
- base::OnceCallback<const webrtc::SessionDescriptionInterface*()>
- description_cb = base::BindOnce(
+
+ CrossThreadOnceFunction<const webrtc::SessionDescriptionInterface*()>
+ description_cb = CrossThreadBindOnce(
&webrtc::PeerConnectionInterface::pending_local_description,
native_peer_connection_);
return GetRTCSessionDescriptionPlatformOnSignalingThread(
@@ -1499,8 +1565,8 @@ RTCSessionDescriptionPlatform*
RTCPeerConnectionHandler::PendingRemoteDescription() {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::pendingRemoteDescription");
- base::OnceCallback<const webrtc::SessionDescriptionInterface*()>
- description_cb = base::BindOnce(
+ CrossThreadOnceFunction<const webrtc::SessionDescriptionInterface*()>
+ description_cb = CrossThreadBindOnce(
&webrtc::PeerConnectionInterface::pending_remote_description,
native_peer_connection_);
return GetRTCSessionDescriptionPlatformOnSignalingThread(
@@ -1543,22 +1609,22 @@ webrtc::RTCErrorType RTCPeerConnectionHandler::SetConfiguration(
void RTCPeerConnectionHandler::AddICECandidate(
RTCVoidRequest* request,
- scoped_refptr<RTCIceCandidatePlatform> candidate) {
+ RTCIceCandidatePlatform* candidate) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::addICECandidate");
std::unique_ptr<webrtc::IceCandidateInterface> native_candidate(
dependency_factory_->CreateIceCandidate(
- candidate->SdpMid().Utf8(),
+ candidate->SdpMid(),
candidate->SdpMLineIndex()
? static_cast<int>(*candidate->SdpMLineIndex())
: -1,
- candidate->Candidate().Utf8()));
+ candidate->Candidate()));
auto callback_on_task_runner =
[](base::WeakPtr<RTCPeerConnectionHandler> handler_weak_ptr,
base::WeakPtr<PeerConnectionTracker> tracker_weak_ptr,
- scoped_refptr<RTCIceCandidatePlatform> candidate,
- webrtc::RTCError result, RTCVoidRequest* request) {
+ RTCIceCandidatePlatform* candidate, webrtc::RTCError result,
+ RTCVoidRequest* request) {
// Inform tracker (chrome://webrtc-internals).
if (handler_weak_ptr && tracker_weak_ptr) {
tracker_weak_ptr->TrackAddIceCandidate(
@@ -1585,10 +1651,10 @@ void RTCPeerConnectionHandler::AddICECandidate(
// a fake |native_peer_connection_|). Jump back to the renderer thread.
PostCrossThreadTask(
*task_runner, FROM_HERE,
- WTF::CrossThreadBindOnce(std::move(callback_on_task_runner),
- handler_weak_ptr, tracker_weak_ptr,
- candidate, std::move(result),
- std::move(persistent_request)));
+ WTF::CrossThreadBindOnce(
+ std::move(callback_on_task_runner), handler_weak_ptr,
+ tracker_weak_ptr, WrapCrossThreadPersistent(candidate),
+ std::move(result), std::move(persistent_request)));
});
}
@@ -1643,20 +1709,22 @@ void RTCPeerConnectionHandler::GetStats(
webrtc::PeerConnectionInterface::StatsOutputLevel level,
rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> selector) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
- signaling_thread()->PostTask(
- FROM_HERE,
- base::BindOnce(&GetStatsOnSignalingThread, native_peer_connection_, level,
- base::WrapRefCounted(observer), std::move(selector)));
+ PostCrossThreadTask(
+ *signaling_thread().get(), FROM_HERE,
+ CrossThreadBindOnce(&GetStatsOnSignalingThread, native_peer_connection_,
+ level, base::WrapRefCounted(observer),
+ std::move(selector)));
}
void RTCPeerConnectionHandler::GetStats(
- blink::WebRTCStatsReportCallback callback,
- const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids) {
+ RTCStatsReportCallback callback,
+ const Vector<webrtc::NonStandardGroupId>& exposed_group_ids) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
- signaling_thread()->PostTask(
- FROM_HERE, base::BindOnce(&GetRTCStatsOnSignalingThread, task_runner_,
- native_peer_connection_, std::move(callback),
- exposed_group_ids));
+ PostCrossThreadTask(
+ *signaling_thread().get(), FROM_HERE,
+ CrossThreadBindOnce(
+ &GetRTCStatsOnSignalingThread, task_runner_, native_peer_connection_,
+ CrossThreadBindOnce(std::move(callback)), exposed_group_ids));
}
webrtc::RTCErrorOr<std::unique_ptr<RTCRtpTransceiverPlatform>>
@@ -1710,7 +1778,7 @@ void RTCPeerConnectionHandler::AddTransceiverWithTrackOnSignalingThread(
webrtc::RTCErrorOr<std::unique_ptr<RTCRtpTransceiverPlatform>>
RTCPeerConnectionHandler::AddTransceiverWithKind(
- std::string kind,
+ const String& kind,
const webrtc::RtpTransceiverInit& init) {
DCHECK_EQ(configuration_.sdp_semantics, webrtc::SdpSemantics::kUnifiedPlan);
DCHECK(task_runner_->RunsTasksInCurrentSequence());
@@ -1764,16 +1832,15 @@ void RTCPeerConnectionHandler::AddTransceiverWithMediaTypeOnSignalingThread(
}
webrtc::RTCErrorOr<std::unique_ptr<RTCRtpTransceiverPlatform>>
-RTCPeerConnectionHandler::AddTrack(
- const blink::WebMediaStreamTrack& track,
- const blink::WebVector<blink::WebMediaStream>& streams) {
+RTCPeerConnectionHandler::AddTrack(const WebMediaStreamTrack& track,
+ const Vector<WebMediaStream>& streams) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::AddTrack");
std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
track_ref = track_adapter_map_->GetOrCreateLocalTrackAdapter(track);
std::vector<std::string> stream_ids(streams.size());
- for (size_t i = 0; i < streams.size(); ++i)
+ for (WTF::wtf_size_t i = 0; i < streams.size(); ++i)
stream_ids[i] = streams[i].Id().Utf8();
// Invoke native AddTrack() on the signaling thread and surface the resulting
@@ -1815,7 +1882,9 @@ RTCPeerConnectionHandler::AddTrack(
blink::RtpSenderState sender_state = transceiver_state.MoveSenderState();
DCHECK(sender_state.is_initialized());
rtp_senders_.push_back(std::make_unique<blink::RTCRtpSenderImpl>(
- native_peer_connection_, track_adapter_map_, std::move(sender_state)));
+ native_peer_connection_, track_adapter_map_, std::move(sender_state),
+ force_encoded_audio_insertable_streams_,
+ force_encoded_video_insertable_streams_));
platform_transceiver = std::make_unique<blink::RTCRtpSenderOnlyTransceiver>(
std::make_unique<blink::RTCRtpSenderImpl>(*rtp_senders_.back().get()));
} else {
@@ -1900,9 +1969,11 @@ bool RTCPeerConnectionHandler::RemoveTrackPlanB(
return false;
if (!(*it)->RemoveFromPeerConnection(native_peer_connection_.get()))
return false;
- track_metrics_.RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
- MediaStreamTrackMetricsKind(web_track),
- web_track.Id().Utf8());
+ if (web_track) {
+ track_metrics_.RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetricsKind(web_track),
+ web_track.Id().Utf8());
+ }
if (peer_connection_tracker_) {
auto sender_only_transceiver =
std::make_unique<blink::RTCRtpSenderOnlyTransceiver>(
@@ -2016,8 +2087,7 @@ void RTCPeerConnectionHandler::StartEventLog(int output_period_ms) {
// or find a way to be able to use it.
// https://crbug.com/775415
native_peer_connection_->StartRtcEventLog(
- std::make_unique<RtcEventLogOutputSinkProxy>(
- peer_connection_observer_.get()),
+ std::make_unique<RtcEventLogOutputSinkProxy>(peer_connection_observer_),
output_period_ms);
}
@@ -2027,7 +2097,7 @@ void RTCPeerConnectionHandler::StopEventLog() {
}
void RTCPeerConnectionHandler::OnWebRtcEventLogWrite(
- const std::string& output) {
+ const WTF::Vector<uint8_t>& output) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
if (peer_connection_tracker_) {
peer_connection_tracker_->TrackRtcEventLogWrite(this, output);
@@ -2035,7 +2105,7 @@ void RTCPeerConnectionHandler::OnWebRtcEventLogWrite(
}
scoped_refptr<DataChannelInterface> RTCPeerConnectionHandler::CreateDataChannel(
- const blink::WebString& label,
+ const String& label,
const webrtc::DataChannelInit& init) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::createDataChannel");
@@ -2079,7 +2149,7 @@ RTCPeerConnectionHandler::NativePeerConnection() {
}
void RTCPeerConnectionHandler::RunSynchronousOnceClosureOnSignalingThread(
- base::OnceClosure closure,
+ CrossThreadOnceClosure closure,
const char* trace_event_name) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
scoped_refptr<base::SingleThreadTaskRunner> thread(signaling_thread());
@@ -2089,11 +2159,11 @@ void RTCPeerConnectionHandler::RunSynchronousOnceClosureOnSignalingThread(
} else {
base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED);
- thread->PostTask(
- FROM_HERE,
- base::BindOnce(&RunSynchronousOnceClosure, std::move(closure),
- base::Unretained(trace_event_name),
- base::Unretained(&event)));
+ PostCrossThreadTask(
+ *thread.get(), FROM_HERE,
+ CrossThreadBindOnce(&RunSynchronousOnceClosure, std::move(closure),
+ CrossThreadUnretained(trace_event_name),
+ CrossThreadUnretained(&event)));
event.Wait();
}
}
@@ -2131,6 +2201,10 @@ void RTCPeerConnectionHandler::OnSignalingChange(
peer_connection_tracker_->TrackSignalingStateChange(this, stable_state);
if (!is_closed_)
client_->DidChangeSignalingState(stable_state);
+ // The callback may have closed the PC. If so, do not continue.
+ if (is_closed_ || !client_) {
+ return;
+ }
}
previous_signaling_state_ = new_state;
if (peer_connection_tracker_)
@@ -2172,16 +2246,16 @@ void RTCPeerConnectionHandler::OnIceConnectionChange(
}
void RTCPeerConnectionHandler::TrackIceConnectionStateChange(
- WebRTCPeerConnectionHandler::IceConnectionStateVersion version,
+ RTCPeerConnectionHandlerPlatform::IceConnectionStateVersion version,
webrtc::PeerConnectionInterface::IceConnectionState state) {
if (!peer_connection_tracker_)
return;
switch (version) {
- case WebRTCPeerConnectionHandler::IceConnectionStateVersion::kLegacy:
+ case RTCPeerConnectionHandlerPlatform::IceConnectionStateVersion::kLegacy:
peer_connection_tracker_->TrackLegacyIceConnectionStateChange(this,
state);
break;
- case WebRTCPeerConnectionHandler::IceConnectionStateVersion::kDefault:
+ case RTCPeerConnectionHandlerPlatform::IceConnectionStateVersion::kDefault:
peer_connection_tracker_->TrackIceConnectionStateChange(this, state);
break;
}
@@ -2252,7 +2326,9 @@ void RTCPeerConnectionHandler::OnAddReceiverPlanB(
blink::RTCRtpReceiverImpl::getId(receiver_state.webrtc_receiver().get());
DCHECK(FindReceiver(receiver_id) == rtp_receivers_.end());
auto rtp_receiver = std::make_unique<blink::RTCRtpReceiverImpl>(
- native_peer_connection_, std::move(receiver_state));
+ native_peer_connection_, std::move(receiver_state),
+ force_encoded_audio_insertable_streams_,
+ force_encoded_video_insertable_streams_);
rtp_receivers_.push_back(
std::make_unique<blink::RTCRtpReceiverImpl>(*rtp_receiver));
if (peer_connection_tracker_) {
@@ -2304,22 +2380,23 @@ void RTCPeerConnectionHandler::OnRemoveReceiverPlanB(uintptr_t receiver_id) {
void RTCPeerConnectionHandler::OnModifySctpTransport(
blink::WebRTCSctpTransportSnapshot state) {
- client_->DidModifySctpTransport(state);
+ if (client_)
+ client_->DidModifySctpTransport(state);
}
void RTCPeerConnectionHandler::OnModifyTransceivers(
std::vector<blink::RtpTransceiverState> transceiver_states,
bool is_remote_description) {
DCHECK_EQ(configuration_.sdp_semantics, webrtc::SdpSemantics::kUnifiedPlan);
- std::vector<std::unique_ptr<RTCRtpTransceiverPlatform>> platform_transceivers(
- transceiver_states.size());
+ Vector<std::unique_ptr<RTCRtpTransceiverPlatform>> platform_transceivers(
+ SafeCast<WTF::wtf_size_t>(transceiver_states.size()));
PeerConnectionTracker::TransceiverUpdatedReason update_reason =
!is_remote_description ? PeerConnectionTracker::TransceiverUpdatedReason::
kSetLocalDescription
: PeerConnectionTracker::TransceiverUpdatedReason::
kSetRemoteDescription;
- blink::WebVector<uintptr_t> ids(transceiver_states.size());
- for (size_t i = 0; i < transceiver_states.size(); ++i) {
+ Vector<uintptr_t> ids(SafeCast<wtf_size_t>(transceiver_states.size()));
+ for (WTF::wtf_size_t i = 0; i < transceiver_states.size(); ++i) {
// Figure out if this transceiver is new or if setting the state modified
// the transceiver such that it should be logged by the
// |peer_connection_tracker_|.
@@ -2361,7 +2438,7 @@ void RTCPeerConnectionHandler::OnModifyTransceivers(
}
}
// Search for removed transceivers by comparing to previous state.
- blink::WebVector<uintptr_t> removed_transceivers;
+ Vector<uintptr_t> removed_transceivers;
for (auto transceiver_id : previous_transceiver_ids_) {
if (std::find(ids.begin(), ids.end(), transceiver_id) == ids.end()) {
removed_transceivers.emplace_back(transceiver_id);
@@ -2396,11 +2473,11 @@ void RTCPeerConnectionHandler::OnIceCandidate(const String& sdp,
int address_family) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnIceCandidateImpl");
- scoped_refptr<RTCIceCandidatePlatform> web_candidate =
- RTCIceCandidatePlatform::Create(sdp, sdp_mid, sdp_mline_index);
+ auto* platform_candidate = MakeGarbageCollected<RTCIceCandidatePlatform>(
+ sdp, sdp_mid, sdp_mline_index);
if (peer_connection_tracker_) {
peer_connection_tracker_->TrackAddIceCandidate(
- this, web_candidate, PeerConnectionTracker::SOURCE_LOCAL, true);
+ this, platform_candidate, PeerConnectionTracker::SOURCE_LOCAL, true);
}
// Only the first m line's first component is tracked to avoid
@@ -2410,28 +2487,37 @@ void RTCPeerConnectionHandler::OnIceCandidate(const String& sdp,
++num_local_candidates_ipv4_;
} else if (address_family == AF_INET6) {
++num_local_candidates_ipv6_;
- } else if (!IsHostnameCandidate(*web_candidate)) {
+ } else if (!IsHostnameCandidate(*platform_candidate)) {
NOTREACHED();
}
}
if (!is_closed_)
- client_->DidGenerateICECandidate(std::move(web_candidate));
+ client_->DidGenerateICECandidate(platform_candidate);
}
-void RTCPeerConnectionHandler::OnIceCandidateError(const String& host_candidate,
- const String& url,
- int error_code,
- const String& error_text) {
+void RTCPeerConnectionHandler::OnIceCandidateError(
+ const String& address,
+ base::Optional<uint16_t> port,
+ const String& host_candidate,
+ const String& url,
+ int error_code,
+ const String& error_text) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnIceCandidateError");
+ if (peer_connection_tracker_) {
+ peer_connection_tracker_->TrackIceCandidateError(
+ this, address, port, host_candidate, url, error_code, error_text);
+ }
if (!is_closed_) {
- client_->DidFailICECandidate(host_candidate, url, error_code, error_text);
+ client_->DidFailICECandidate(address, port, host_candidate, url, error_code,
+ error_text);
}
}
void RTCPeerConnectionHandler::OnInterestingUsage(int usage_pattern) {
- client_->DidNoteInterestingUsage(usage_pattern);
+ if (client_)
+ client_->DidNoteInterestingUsage(usage_pattern);
}
webrtc::SessionDescriptionInterface*
@@ -2440,8 +2526,7 @@ RTCPeerConnectionHandler::CreateNativeSessionDescription(
const String& type,
webrtc::SdpParseError* error) {
webrtc::SessionDescriptionInterface* native_desc =
- dependency_factory_->CreateSessionDescription(type.Utf8(), sdp.Utf8(),
- error);
+ dependency_factory_->CreateSessionDescription(type, sdp, error);
LOG_IF(ERROR, !native_desc) << "Failed to create native session description."
<< " Type: " << type << " SDP: " << sdp;
@@ -2555,7 +2640,8 @@ RTCPeerConnectionHandler::CreateOrUpdateTransceiver(
// Create a new transceiver, including a sender and a receiver.
transceiver = std::make_unique<blink::RTCRtpTransceiverImpl>(
native_peer_connection_, track_adapter_map_,
- std::move(transceiver_state));
+ std::move(transceiver_state), force_encoded_audio_insertable_streams_,
+ force_encoded_video_insertable_streams_);
rtp_transceivers_.push_back(transceiver->ShallowCopy());
DCHECK(FindSender(blink::RTCRtpSenderImpl::getId(webrtc_sender.get())) ==
rtp_senders_.end());
@@ -2585,7 +2671,7 @@ RTCPeerConnectionHandler::signaling_thread() const {
RTCSessionDescriptionPlatform*
RTCPeerConnectionHandler::GetRTCSessionDescriptionPlatformOnSignalingThread(
- base::OnceCallback<const webrtc::SessionDescriptionInterface*()>
+ CrossThreadOnceFunction<const webrtc::SessionDescriptionInterface*()>
description_cb,
const char* log_text) {
// Since the webrtc::PeerConnectionInterface::*_description() functions
@@ -2599,10 +2685,10 @@ RTCPeerConnectionHandler::GetRTCSessionDescriptionPlatformOnSignalingThread(
std::string type, sdp;
bool success = false;
RunSynchronousOnceClosureOnSignalingThread(
- base::BindOnce(
+ CrossThreadBindOnce(
&GetRTCSessionDescriptionPlatformFromSessionDescriptionCallback,
- std::move(description_cb), base::Unretained(&type),
- base::Unretained(&sdp), base::Unretained(&success)),
+ std::move(description_cb), CrossThreadUnretained(&type),
+ CrossThreadUnretained(&sdp), CrossThreadUnretained(&success)),
log_text);
if (!success)
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 1aa9ffa273b..8fe217559c7 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
@@ -17,15 +17,15 @@
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "third_party/blink/public/platform/web_media_stream_source.h"
-#include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h"
-#include "third_party/blink/public/platform/web_rtc_peer_connection_handler_client.h"
-#include "third_party/blink/public/platform/web_rtc_stats.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/transceiver_state_surfacer.h"
#include "third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_client.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_platform.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_stats_request.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_stats_response_base.h"
#include "third_party/webrtc/api/stats/rtc_stats.h"
@@ -37,10 +37,10 @@ class PeerConnectionTracker;
class RTCAnswerOptionsPlatform;
class RTCLegacyStats;
class RTCOfferOptionsPlatform;
+class RTCPeerConnectionHandlerClient;
class RTCVoidRequest;
class SetLocalDescriptionRequest;
class WebLocalFrame;
-class WebRTCPeerConnectionHandlerClient;
// Mockable wrapper for blink::RTCStatsResponseBase
class MODULES_EXPORT LocalRTCStatsResponse : public rtc::RefCountInterface {
@@ -85,37 +85,41 @@ class MODULES_EXPORT LocalRTCStatsRequest : public rtc::RefCountInterface {
// Callbacks to the webrtc::PeerConnectionObserver implementation also occur on
// the main render thread.
class MODULES_EXPORT RTCPeerConnectionHandler
- : public blink::WebRTCPeerConnectionHandler {
+ : public RTCPeerConnectionHandlerPlatform {
public:
RTCPeerConnectionHandler(
- blink::WebRTCPeerConnectionHandlerClient* client,
+ RTCPeerConnectionHandlerClient* client,
blink::PeerConnectionDependencyFactory* dependency_factory,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ bool force_encoded_audio_insertable_streams,
+ bool force_encoded_video_insertable_streams);
~RTCPeerConnectionHandler() override;
- void AssociateWithFrame(blink::WebLocalFrame* frame) override;
-
// Initialize method only used for unit test.
bool InitializeForTest(
const webrtc::PeerConnectionInterface::RTCConfiguration&
server_configuration,
- const blink::WebMediaConstraints& options,
+ const MediaConstraints& options,
const base::WeakPtr<PeerConnectionTracker>& peer_connection_tracker);
- // blink::WebRTCPeerConnectionHandler implementation
+ // RTCPeerConnectionHandlerPlatform implementation
bool Initialize(const webrtc::PeerConnectionInterface::RTCConfiguration&
server_configuration,
- const blink::WebMediaConstraints& options) override;
+ const MediaConstraints& options,
+ WebLocalFrame* web_frame) override;
- blink::WebVector<std::unique_ptr<RTCRtpTransceiverPlatform>> CreateOffer(
- blink::RTCSessionDescriptionRequest* request,
- const blink::WebMediaConstraints& options) override;
- blink::WebVector<std::unique_ptr<RTCRtpTransceiverPlatform>> CreateOffer(
- blink::RTCSessionDescriptionRequest* request,
- blink::RTCOfferOptionsPlatform* options) override;
+ void Stop() override;
+ void StopAndUnregister() override;
+
+ Vector<std::unique_ptr<RTCRtpTransceiverPlatform>> CreateOffer(
+ RTCSessionDescriptionRequest* request,
+ const MediaConstraints& options) override;
+ Vector<std::unique_ptr<RTCRtpTransceiverPlatform>> CreateOffer(
+ RTCSessionDescriptionRequest* request,
+ RTCOfferOptionsPlatform* options) override;
void CreateAnswer(blink::RTCSessionDescriptionRequest* request,
- const blink::WebMediaConstraints& options) override;
+ const MediaConstraints& options) override;
void CreateAnswer(blink::RTCSessionDescriptionRequest* request,
blink::RTCAnswerOptionsPlatform* options) override;
@@ -138,41 +142,39 @@ class MODULES_EXPORT RTCPeerConnectionHandler
webrtc::RTCErrorType SetConfiguration(
const webrtc::PeerConnectionInterface::RTCConfiguration& configuration)
override;
- void AddICECandidate(
- blink::RTCVoidRequest* request,
- scoped_refptr<RTCIceCandidatePlatform> candidate) override;
+ void AddICECandidate(blink::RTCVoidRequest* request,
+ RTCIceCandidatePlatform* candidate) override;
void RestartIce() override;
void GetStats(RTCStatsRequest* request) override;
- void GetStats(blink::WebRTCStatsReportCallback callback,
- const blink::WebVector<webrtc::NonStandardGroupId>&
- exposed_group_ids) override;
+ void GetStats(
+ RTCStatsReportCallback callback,
+ const Vector<webrtc::NonStandardGroupId>& exposed_group_ids) override;
webrtc::RTCErrorOr<std::unique_ptr<RTCRtpTransceiverPlatform>>
AddTransceiverWithTrack(const blink::WebMediaStreamTrack& web_track,
const webrtc::RtpTransceiverInit& init) override;
webrtc::RTCErrorOr<std::unique_ptr<RTCRtpTransceiverPlatform>>
- AddTransceiverWithKind(std::string kind,
+ AddTransceiverWithKind(const String& kind,
const webrtc::RtpTransceiverInit& init) override;
webrtc::RTCErrorOr<std::unique_ptr<RTCRtpTransceiverPlatform>> AddTrack(
- const blink::WebMediaStreamTrack& web_track,
- const blink::WebVector<blink::WebMediaStream>& web_streams) override;
+ const WebMediaStreamTrack& web_track,
+ const Vector<WebMediaStream>& web_streams) override;
webrtc::RTCErrorOr<std::unique_ptr<RTCRtpTransceiverPlatform>> RemoveTrack(
blink::RTCRtpSenderPlatform* web_sender) override;
scoped_refptr<webrtc::DataChannelInterface> CreateDataChannel(
- const blink::WebString& label,
+ const String& label,
const webrtc::DataChannelInit& init) override;
- void Stop() override;
webrtc::PeerConnectionInterface* NativePeerConnection() override;
void RunSynchronousOnceClosureOnSignalingThread(
- base::OnceClosure closure,
+ CrossThreadOnceClosure closure,
const char* trace_event_name) override;
void RunSynchronousRepeatingClosureOnSignalingThread(
const base::RepeatingClosure& closure,
const char* trace_event_name) override;
void TrackIceConnectionStateChange(
- WebRTCPeerConnectionHandler::IceConnectionStateVersion version,
+ RTCPeerConnectionHandlerPlatform::IceConnectionStateVersion version,
webrtc::PeerConnectionInterface::IceConnectionState state) override;
// Delegate functions to allow for mocking of WebKit interfaces.
@@ -197,7 +199,15 @@ class MODULES_EXPORT RTCPeerConnectionHandler
void StopEventLog();
// WebRTC event log fragments sent back from PeerConnection land here.
- void OnWebRtcEventLogWrite(const std::string& output);
+ void OnWebRtcEventLogWrite(const WTF::Vector<uint8_t>& output);
+
+ bool force_encoded_audio_insertable_streams() {
+ return force_encoded_audio_insertable_streams_;
+ }
+
+ bool force_encoded_video_insertable_streams() {
+ return force_encoded_video_insertable_streams_;
+ }
protected:
webrtc::PeerConnectionInterface* native_peer_connection() {
@@ -234,7 +244,9 @@ class MODULES_EXPORT RTCPeerConnectionHandler
int sdp_mline_index,
int component,
int address_family);
- void OnIceCandidateError(const String& host_candidate,
+ void OnIceCandidateError(const String& address,
+ base::Optional<uint16_t> port,
+ const String& host_candidate,
const String& url,
int error_code,
const String& error_text);
@@ -266,7 +278,7 @@ class MODULES_EXPORT RTCPeerConnectionHandler
RTCSessionDescriptionPlatform*
GetRTCSessionDescriptionPlatformOnSignalingThread(
- base::OnceCallback<const webrtc::SessionDescriptionInterface*()>
+ CrossThreadOnceFunction<const webrtc::SessionDescriptionInterface*()>
description_cb,
const char* log_text);
@@ -307,7 +319,7 @@ class MODULES_EXPORT RTCPeerConnectionHandler
rtc::scoped_refptr<webrtc::RtpSenderInterface> sender,
blink::TransceiverStateSurfacer* transceiver_state_surfacer,
CancellableBooleanOperationResult* result);
- std::vector<std::unique_ptr<RTCRtpTransceiverPlatform>> CreateOfferInternal(
+ Vector<std::unique_ptr<RTCRtpTransceiverPlatform>> CreateOfferInternal(
blink::RTCSessionDescriptionRequest* request,
webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options);
void CreateOfferOnSignalingThread(
@@ -339,14 +351,18 @@ class MODULES_EXPORT RTCPeerConnectionHandler
// first call fails.
bool initialize_called_;
- // |client_| is a weak pointer to the blink object (blink::RTCPeerConnection)
+ // |client_| is a raw pointer to the blink object (blink::RTCPeerConnection)
// that owns this object.
- // It is valid for the lifetime of this object.
- blink::WebRTCPeerConnectionHandlerClient* const client_;
+ // It is valid for the lifetime of this object, but is cleared when
+ // StopAndUnregister() is called, in order to make sure it doesn't
+ // interfere with garbage collection of the owner object.
+ RTCPeerConnectionHandlerClient* client_;
// True if this PeerConnection has been closed.
// After the PeerConnection has been closed, this object may no longer
// forward callbacks to blink.
bool is_closed_;
+ // True if StopAndUnregister has been called.
+ bool is_unregistered_;
// Transition from kHaveLocalOffer to kHaveRemoteOffer indicates implicit
// rollback in which case we need to also make visiting of kStable observable.
@@ -379,7 +395,7 @@ class MODULES_EXPORT RTCPeerConnectionHandler
std::vector<std::unique_ptr<blink::RTCRtpTransceiverImpl>> rtp_transceivers_;
// A snapshot of transceiver ids taken before the last transition, used to
// detect any removals during rollback.
- blink::WebVector<uintptr_t> previous_transceiver_ids_;
+ Vector<uintptr_t> previous_transceiver_ids_;
base::WeakPtr<PeerConnectionTracker> peer_connection_tracker_;
@@ -394,7 +410,7 @@ class MODULES_EXPORT RTCPeerConnectionHandler
// To make sure the observers are released after native_peer_connection_,
// they have to come first.
- scoped_refptr<Observer> peer_connection_observer_;
+ CrossThreadPersistent<Observer> peer_connection_observer_;
// |native_peer_connection_| is the libjingle native PeerConnection object.
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection_;
@@ -403,6 +419,8 @@ class MODULES_EXPORT RTCPeerConnectionHandler
// used when constructing the PeerConnection carry over when
// SetConfiguration is called.
webrtc::PeerConnectionInterface::RTCConfiguration configuration_;
+ bool force_encoded_audio_insertable_streams_;
+ bool force_encoded_video_insertable_streams_;
// Record info about the first SessionDescription from the local and
// remote side to record UMA stats once both are set. We only check
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 0aa7ca1f6b1..d2e420256eb 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
@@ -15,22 +15,20 @@
#include <vector>
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/location.h"
+#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
#include "base/values.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.h"
#include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
-#include "third_party/blink/public/platform/web_media_constraints.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_rtc_peer_connection_handler_client.h"
-#include "third_party/blink/public/platform/web_rtc_stats.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
#include "third_party/blink/public/web/web_heap.h"
@@ -41,12 +39,15 @@
#include "third_party/blink/renderer/modules/peerconnection/mock_data_channel_impl.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/modules/peerconnection/mock_web_rtc_peer_connection_handler_client.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/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/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"
#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_receiver_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
@@ -62,7 +63,6 @@
static const char kDummySdp[] = "dummy sdp";
static const char kDummySdpType[] = "dummy type";
-using blink::WebRTCPeerConnectionHandlerClient;
using testing::_;
using testing::Invoke;
using testing::NiceMock;
@@ -151,10 +151,10 @@ class MockPeerConnectionTracker : public PeerConnectionTracker {
// TODO(jiayl): add coverage for the following methods
MOCK_METHOD2(TrackCreateOffer,
void(RTCPeerConnectionHandler* pc_handler,
- const blink::WebMediaConstraints& constraints));
+ const MediaConstraints& constraints));
MOCK_METHOD2(TrackCreateAnswer,
void(RTCPeerConnectionHandler* pc_handler,
- const blink::WebMediaConstraints& constraints));
+ const MediaConstraints& constraints));
MOCK_METHOD4(TrackSetSessionDescription,
void(RTCPeerConnectionHandler* pc_handler,
const String& sdp,
@@ -168,7 +168,7 @@ class MockPeerConnectionTracker : public PeerConnectionTracker {
const webrtc::PeerConnectionInterface::RTCConfiguration& config));
MOCK_METHOD4(TrackAddIceCandidate,
void(RTCPeerConnectionHandler* pc_handler,
- scoped_refptr<RTCIceCandidatePlatform> candidate,
+ RTCIceCandidatePlatform* candidate,
Source source,
bool succeeded));
MOCK_METHOD4(TrackAddTransceiver,
@@ -225,9 +225,7 @@ class DummyRTCVoidRequest final : public RTCVoidRequest {
void RequestSucceeded() override { was_called_ = true; }
void RequestFailed(const webrtc::RTCError&) override { was_called_ = true; }
- void Trace(blink::Visitor* visitor) override {
- RTCVoidRequest::Trace(visitor);
- }
+ void Trace(Visitor* visitor) override { RTCVoidRequest::Trace(visitor); }
private:
bool was_called_ = false;
@@ -249,7 +247,7 @@ std::vector<T> ToSequence(T value) {
}
template <typename T>
-void ExpectSequenceEquals(const blink::WebVector<T>& sequence, T value) {
+void ExpectSequenceEquals(const Vector<T>& sequence, T value) {
EXPECT_EQ(sequence.size(), static_cast<size_t>(1));
EXPECT_EQ(sequence[0], value);
}
@@ -257,12 +255,16 @@ void ExpectSequenceEquals(const blink::WebVector<T>& sequence, T value) {
class RTCPeerConnectionHandlerUnderTest : public RTCPeerConnectionHandler {
public:
RTCPeerConnectionHandlerUnderTest(
- WebRTCPeerConnectionHandlerClient* client,
- blink::PeerConnectionDependencyFactory* dependency_factory)
+ RTCPeerConnectionHandlerClient* client,
+ blink::PeerConnectionDependencyFactory* dependency_factory,
+ bool force_encoded_audio_insertable_streams = false,
+ bool force_encoded_video_insertable_streams = false)
: RTCPeerConnectionHandler(
client,
dependency_factory,
- blink::scheduler::GetSingleThreadTaskRunnerForTesting()) {}
+ blink::scheduler::GetSingleThreadTaskRunnerForTesting(),
+ force_encoded_audio_insertable_streams,
+ force_encoded_video_insertable_streams) {}
blink::MockPeerConnectionImpl* native_peer_connection() {
return static_cast<blink::MockPeerConnectionImpl*>(
@@ -279,8 +281,7 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
RTCPeerConnectionHandlerTest() : mock_peer_connection_(nullptr) {}
void SetUp() override {
- mock_client_.reset(
- new NiceMock<blink::MockWebRTCPeerConnectionHandlerClient>());
+ mock_client_.reset(new NiceMock<MockRTCPeerConnectionHandlerClient>());
mock_dependency_factory_.reset(
new blink::MockPeerConnectionDependencyFactory());
@@ -288,7 +289,7 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
mock_tracker_.reset(new NiceMock<MockPeerConnectionTracker>());
webrtc::PeerConnectionInterface::RTCConfiguration config;
config.sdp_semantics = webrtc::SdpSemantics::kPlanB;
- blink::WebMediaConstraints constraints;
+ MediaConstraints constraints;
EXPECT_TRUE(pc_handler_->InitializeForTest(
config, constraints, mock_tracker_.get()->AsWeakPtr()));
@@ -312,8 +313,7 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
}
// Creates a WebKit local MediaStream.
- blink::WebMediaStream CreateLocalMediaStream(
- const std::string& stream_label) {
+ WebMediaStream CreateLocalMediaStream(const std::string& stream_label) {
std::string video_track_label("video-label");
std::string audio_track_label("audio-label");
blink::WebMediaStreamSource blink_audio_source;
@@ -376,18 +376,18 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
// Creates a remote MediaStream and adds it to the mocked native
// peer connection.
rtc::scoped_refptr<webrtc::MediaStreamInterface> AddRemoteMockMediaStream(
- const std::string& stream_label,
- const std::string& video_track_label,
- const std::string& audio_track_label) {
+ const String& stream_label,
+ const String& video_track_label,
+ const String& audio_track_label) {
rtc::scoped_refptr<webrtc::MediaStreamInterface> stream(
mock_dependency_factory_->CreateLocalMediaStream(stream_label).get());
- if (!video_track_label.empty()) {
+ if (!video_track_label.IsEmpty()) {
InvokeAddTrack(
- stream, blink::MockWebRtcVideoTrack::Create(video_track_label).get());
+ stream, MockWebRtcVideoTrack::Create(video_track_label.Utf8()).get());
}
- if (!audio_track_label.empty()) {
+ if (!audio_track_label.IsEmpty()) {
InvokeAddTrack(
- stream, blink::MockWebRtcAudioTrack::Create(audio_track_label).get());
+ stream, MockWebRtcAudioTrack::Create(audio_track_label.Utf8()).get());
}
mock_peer_connection_->AddRemoteStream(stream);
return stream;
@@ -404,7 +404,7 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
size_t senders_size_before_add = senders_.size();
for (const auto& web_audio_track : web_stream.AudioTracks()) {
auto error_or_transceiver = pc_handler_->AddTrack(
- web_audio_track, std::vector<blink::WebMediaStream>({web_stream}));
+ web_audio_track, Vector<WebMediaStream>({web_stream}));
if (error_or_transceiver.ok()) {
DCHECK_EQ(
error_or_transceiver.value()->ImplementationType(),
@@ -416,7 +416,7 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
}
for (const auto& web_video_track : web_stream.VideoTracks()) {
auto error_or_transceiver = pc_handler_->AddTrack(
- web_video_track, std::vector<blink::WebMediaStream>({web_stream}));
+ web_video_track, Vector<WebMediaStream>({web_stream}));
if (error_or_transceiver.ok()) {
DCHECK_EQ(
error_or_transceiver.value()->ImplementationType(),
@@ -575,7 +575,7 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
public:
ScopedTestingPlatformSupport<AudioCapturerSourceTestingPlatformSupport>
webrtc_audio_device_platform_support_;
- std::unique_ptr<blink::MockWebRTCPeerConnectionHandlerClient> mock_client_;
+ std::unique_ptr<MockRTCPeerConnectionHandlerClient> mock_client_;
std::unique_ptr<blink::MockPeerConnectionDependencyFactory>
mock_dependency_factory_;
std::unique_ptr<NiceMock<MockPeerConnectionTracker>> mock_tracker_;
@@ -637,7 +637,7 @@ TEST_F(RTCPeerConnectionHandlerTest, NoCallbacksToClientAfterStop) {
}
TEST_F(RTCPeerConnectionHandlerTest, CreateOffer) {
- blink::WebMediaConstraints options;
+ MediaConstraints options;
EXPECT_CALL(*mock_tracker_.get(), TrackCreateOffer(pc_handler_.get(), _));
// TODO(perkj): Can blink::RTCSessionDescriptionRequest be changed so
@@ -649,7 +649,7 @@ TEST_F(RTCPeerConnectionHandlerTest, CreateOffer) {
}
TEST_F(RTCPeerConnectionHandlerTest, CreateAnswer) {
- blink::WebMediaConstraints options;
+ MediaConstraints options;
EXPECT_CALL(*mock_tracker_.get(), TrackCreateAnswer(pc_handler_.get(), _));
// TODO(perkj): Can blink::RTCSessionDescriptionRequest be changed so
// the |request| requestSucceeded can be tested? Currently the |request|
@@ -791,8 +791,8 @@ TEST_F(RTCPeerConnectionHandlerTest, setConfigurationError) {
}
TEST_F(RTCPeerConnectionHandlerTest, addICECandidate) {
- scoped_refptr<RTCIceCandidatePlatform> candidate =
- RTCIceCandidatePlatform::Create(kDummySdp, "sdpMid", 1);
+ auto* candidate =
+ MakeGarbageCollected<RTCIceCandidatePlatform>(kDummySdp, "sdpMid", 1);
EXPECT_CALL(*mock_tracker_.get(),
TrackAddIceCandidate(pc_handler_.get(), candidate,
@@ -998,7 +998,7 @@ TEST_F(RTCPeerConnectionHandlerTest, GetRTCStats) {
EXPECT_EQ(member->ValueString(), "42");
break;
case webrtc::RTCStatsMemberInterface::kSequenceBool:
- ExpectSequenceEquals(member->ValueSequenceBool(), 1);
+ ExpectSequenceEquals(member->ValueSequenceBool(), true);
break;
case webrtc::RTCStatsMemberInterface::kSequenceInt32:
ExpectSequenceEquals(member->ValueSequenceInt32(),
@@ -1279,4 +1279,19 @@ TEST_F(RTCPeerConnectionHandlerTest, CreateDataChannel) {
EXPECT_EQ(label.Utf8(), channel->label());
}
+TEST_F(RTCPeerConnectionHandlerTest, CheckInsertableStreamsConfig) {
+ for (bool force_encoded_audio_insertable_streams : {true, false}) {
+ for (bool force_encoded_video_insertable_streams : {true, false}) {
+ auto handler = std::make_unique<RTCPeerConnectionHandlerUnderTest>(
+ mock_client_.get(), mock_dependency_factory_.get(),
+ force_encoded_audio_insertable_streams,
+ force_encoded_video_insertable_streams);
+ EXPECT_EQ(handler->force_encoded_audio_insertable_streams(),
+ force_encoded_audio_insertable_streams);
+ EXPECT_EQ(handler->force_encoded_video_insertable_streams(),
+ force_encoded_video_insertable_streams);
+ }
+ }
+}
+
} // 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 3f2b7f60712..5e51a132b1c 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
@@ -2,20 +2,23 @@
// 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/event_type_names.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_peer_connection_ice_error_event_init.h"
+#include "third_party/blink/renderer/core/event_type_names.h"
namespace blink {
RTCPeerConnectionIceErrorEvent* RTCPeerConnectionIceErrorEvent::Create(
+ const String& address,
+ base::Optional<uint16_t> port,
const String& host_candidate,
const String& url,
int error_code,
const String& txt) {
DCHECK(error_code > 0 && error_code <= USHRT_MAX);
return MakeGarbageCollected<RTCPeerConnectionIceErrorEvent>(
- host_candidate, url, static_cast<uint16_t>(error_code), txt);
+ address, port, host_candidate, url, static_cast<uint16_t>(error_code),
+ txt);
}
RTCPeerConnectionIceErrorEvent* RTCPeerConnectionIceErrorEvent::Create(
@@ -26,6 +29,8 @@ RTCPeerConnectionIceErrorEvent* RTCPeerConnectionIceErrorEvent::Create(
}
RTCPeerConnectionIceErrorEvent::RTCPeerConnectionIceErrorEvent(
+ const String& address,
+ base::Optional<uint16_t> port,
const String& host_candidate,
const String& url,
uint16_t error_code,
@@ -33,6 +38,8 @@ RTCPeerConnectionIceErrorEvent::RTCPeerConnectionIceErrorEvent(
: Event(event_type_names::kIcecandidateerror,
Bubbles::kNo,
Cancelable::kNo),
+ address_(address),
+ port_(port),
host_candidate_(host_candidate),
url_(url),
error_code_(error_code),
@@ -42,6 +49,8 @@ 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()),
@@ -49,6 +58,19 @@ RTCPeerConnectionIceErrorEvent::RTCPeerConnectionIceErrorEvent(
RTCPeerConnectionIceErrorEvent::~RTCPeerConnectionIceErrorEvent() = default;
+String RTCPeerConnectionIceErrorEvent::address() const {
+ return address_;
+}
+
+base::Optional<uint16_t> RTCPeerConnectionIceErrorEvent::port() const {
+ return port_;
+}
+
+uint16_t RTCPeerConnectionIceErrorEvent::port(bool& is_null) const {
+ is_null = !port_.has_value();
+ return is_null ? uint16_t() : port_.value();
+}
+
String RTCPeerConnectionIceErrorEvent::hostCandidate() const {
return host_candidate_;
}
@@ -69,7 +91,7 @@ const AtomicString& RTCPeerConnectionIceErrorEvent::InterfaceName() const {
return event_interface_names::kRTCPeerConnectionIceErrorEvent;
}
-void RTCPeerConnectionIceErrorEvent::Trace(blink::Visitor* visitor) {
+void RTCPeerConnectionIceErrorEvent::Trace(Visitor* visitor) {
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 d3770c32cf9..33d397ac177 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
@@ -16,7 +16,9 @@ class MODULES_EXPORT RTCPeerConnectionIceErrorEvent final : public Event {
DEFINE_WRAPPERTYPEINFO();
public:
- RTCPeerConnectionIceErrorEvent(const String& host_candidate,
+ RTCPeerConnectionIceErrorEvent(const String& address,
+ base::Optional<uint16_t> port,
+ const String& host_candidate,
const String& url,
uint16_t error_code,
const String& error_text);
@@ -25,7 +27,9 @@ class MODULES_EXPORT RTCPeerConnectionIceErrorEvent final : public Event {
const RTCPeerConnectionIceErrorEventInit*);
~RTCPeerConnectionIceErrorEvent() override;
- static RTCPeerConnectionIceErrorEvent* Create(const String& host_candidate,
+ static RTCPeerConnectionIceErrorEvent* Create(const String& address,
+ base::Optional<uint16_t> port,
+ const String& host_candidate,
const String& url,
int error_code,
const String& error_text);
@@ -34,15 +38,21 @@ class MODULES_EXPORT RTCPeerConnectionIceErrorEvent final : public Event {
const AtomicString& type,
const RTCPeerConnectionIceErrorEventInit*);
+ String address() const;
+ base::Optional<uint16_t> port() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ uint16_t port(bool& is_null) const; // DEPRECATED
String hostCandidate() const;
String url() const;
uint16_t errorCode() const;
String errorText() const;
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
+ String address_;
+ base::Optional<uint16_t> port_;
String host_candidate_;
String url_;
uint16_t error_code_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.idl
index f9adca402a7..e3cc2b6118c 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.idl
@@ -5,10 +5,12 @@
//https://w3c.github.io/webrtc-pc/#rtcpeerconnectioniceerrorevent
[
- Constructor (DOMString type, RTCPeerConnectionIceErrorEventInit eventInitDict),
Exposed=Window
] interface RTCPeerConnectionIceErrorEvent : Event {
- readonly attribute DOMString hostCandidate;
+ constructor (DOMString type, RTCPeerConnectionIceErrorEventInit eventInitDict);
+ readonly attribute DOMString? address;
+ readonly attribute unsigned short? port;
+ [DeprecateAs=HostCandidateAttributeGetter] readonly attribute DOMString hostCandidate;
readonly attribute DOMString url;
readonly attribute unsigned short errorCode;
readonly attribute USVString errorText;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event_init.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event_init.idl
index 60aee0b71fd..a0734029421 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event_init.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event_init.idl
@@ -5,6 +5,8 @@
// https://w3c.github.io/webrtc-pc/#rtcpeerconnectioniceerrorevent
dictionary RTCPeerConnectionIceErrorEventInit : EventInit {
+ DOMString? address;
+ unsigned short? port;
DOMString hostCandidate;
DOMString url;
required unsigned short errorCode;
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 747643b78c1..2d59646ae15 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
@@ -24,9 +24,9 @@
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_peer_connection_ice_event_init.h"
#include "third_party/blink/renderer/core/event_type_names.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event_init.h"
namespace blink {
@@ -60,7 +60,7 @@ const AtomicString& RTCPeerConnectionIceEvent::InterfaceName() const {
return event_interface_names::kRTCPeerConnectionIceEvent;
}
-void RTCPeerConnectionIceEvent::Trace(blink::Visitor* visitor) {
+void RTCPeerConnectionIceEvent::Trace(Visitor* visitor) {
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 fd335e0ad36..803f67c546f 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<RTCIceCandidate> candidate_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.idl
index 6fde12e29c3..164cbfd132a 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.idl
@@ -24,9 +24,9 @@
*/
[
- Constructor(DOMString type, optional RTCPeerConnectionIceEventInit eventInitDict),
Exposed=Window
] interface RTCPeerConnectionIceEvent : Event {
+ constructor(DOMString type, optional RTCPeerConnectionIceEventInit eventInitDict = {});
readonly attribute RTCIceCandidate? candidate;
// TODO(loonybear): add nullable url attribute here:
// https://rawgit.com/w3c/webrtc-pc/master/webrtc.html#rtcpeerconnectioniceevent
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 9daaa9e8a3e..4fed7a75817 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
@@ -10,7 +10,6 @@
#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_rtc_peer_connection_handler.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/web/web_heap.h"
#include "third_party/blink/public/web/web_script_source.h"
@@ -18,21 +17,22 @@
#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_void_function.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_answer_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_configuration.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_server.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_offer_options.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_peer_connection_error_callback.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_session_description_callback.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_session_description_init.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_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/modules/mediastream/media_stream.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_track.h"
-#include "third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_answer_options.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_configuration.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_server.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_offer_options.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_session_description_init.h"
+#include "third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.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/peerconnection/rtc_peer_connection_handler_platform.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"
#include "third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h"
@@ -377,31 +377,35 @@ static const char* kOfferSdpPlanBMultipleAudioTracks =
"a=ssrc:4092260337 mslabel:46f8615e-7599-49f3-9a45-3cf0faf58614\r\n"
"a=ssrc:4092260337 label:6b5f436e-f85d-40a1-83e4-acec63ca4b82\r\n";
-template <typename PlatformSupportType>
-class RTCPeerConnectionTestWithPlatformTestingPlatformType
- : public testing::Test {
+class RTCPeerConnectionTest : public testing::Test {
public:
- RTCPeerConnection* CreatePC(V8TestingScope& scope,
- const String& sdpSemantics = String()) {
+ RTCPeerConnection* CreatePC(
+ V8TestingScope& scope,
+ const String& sdpSemantics = String(),
+ bool force_encoded_audio_insertable_streams = false,
+ bool force_encoded_video_insertable_streams = false) {
RTCConfiguration* config = RTCConfiguration::Create();
config->setSdpSemantics(sdpSemantics);
+ config->setForceEncodedAudioInsertableStreams(
+ force_encoded_audio_insertable_streams);
+ config->setForceEncodedVideoInsertableStreams(
+ force_encoded_video_insertable_streams);
RTCIceServer* ice_server = RTCIceServer::Create();
- ice_server->setURL("stun:fake.stun.url");
+ ice_server->setUrl("stun:fake.stun.url");
HeapVector<Member<RTCIceServer>> ice_servers;
ice_servers.push_back(ice_server);
config->setIceServers(ice_servers);
RTCPeerConnection::SetRtcPeerConnectionHandlerFactoryForTesting(
base::BindRepeating(
- &RTCPeerConnectionTestWithPlatformTestingPlatformType::
- CreateRTCPeerConnectionHandler,
+ &RTCPeerConnectionTest::CreateRTCPeerConnectionHandler,
base::Unretained(this)));
return RTCPeerConnection::Create(scope.GetExecutionContext(), config,
- Dictionary(), scope.GetExceptionState());
+ scope.GetExceptionState());
}
- virtual std::unique_ptr<WebRTCPeerConnectionHandler>
+ virtual std::unique_ptr<RTCPeerConnectionHandlerPlatform>
CreateRTCPeerConnectionHandler() {
- return std::make_unique<MockWebRTCPeerConnectionHandler>();
+ return std::make_unique<MockRTCPeerConnectionHandlerPlatform>();
}
MediaStreamTrack* CreateTrack(V8TestingScope& scope,
@@ -410,7 +414,8 @@ class RTCPeerConnectionTestWithPlatformTestingPlatformType
auto* source = MakeGarbageCollected<MediaStreamSource>("sourceId", type,
"sourceName", false);
auto* component = MakeGarbageCollected<MediaStreamComponent>(id, source);
- return MediaStreamTrack::Create(scope.GetExecutionContext(), component);
+ return MakeGarbageCollected<MediaStreamTrack>(scope.GetExecutionContext(),
+ component);
}
std::string GetExceptionMessage(V8TestingScope& scope) {
@@ -422,8 +427,7 @@ class RTCPeerConnectionTestWithPlatformTestingPlatformType
void AddStream(V8TestingScope& scope,
RTCPeerConnection* pc,
MediaStream* stream) {
- pc->addStream(scope.GetScriptState(), stream, Dictionary(),
- scope.GetExceptionState());
+ pc->addStream(scope.GetScriptState(), stream, scope.GetExceptionState());
EXPECT_EQ("", GetExceptionMessage(scope));
}
@@ -435,15 +439,9 @@ class RTCPeerConnectionTestWithPlatformTestingPlatformType
}
protected:
- ScopedTestingPlatformSupport<PlatformSupportType> platform_;
+ ScopedTestingPlatformSupport<TestingPlatformSupport> platform_;
};
-// TODO(crbug.com/787254): Consider removing or simplifying the inheritance
-// altogether.
-class RTCPeerConnectionTest
- : public RTCPeerConnectionTestWithPlatformTestingPlatformType<
- TestingPlatformSupport> {};
-
TEST_F(RTCPeerConnectionTest, GetAudioTrack) {
V8TestingScope scope;
RTCPeerConnection* pc = CreatePC(scope);
@@ -652,6 +650,21 @@ TEST_F(RTCPeerConnectionTest, CheckForComplexSdpWithSdpSemanticsUnspecified) {
ASSERT_FALSE(pc->CheckForComplexSdp(sdp).has_value());
}
+TEST_F(RTCPeerConnectionTest, CheckInsertableStreamsConfig) {
+ for (bool force_encoded_audio_insertable_streams : {true, false}) {
+ for (bool force_encoded_video_insertable_streams : {true, false}) {
+ V8TestingScope scope;
+ Persistent<RTCPeerConnection> pc =
+ CreatePC(scope, String(), force_encoded_audio_insertable_streams,
+ force_encoded_video_insertable_streams);
+ EXPECT_EQ(pc->force_encoded_audio_insertable_streams(),
+ force_encoded_audio_insertable_streams);
+ EXPECT_EQ(pc->force_encoded_video_insertable_streams(),
+ force_encoded_video_insertable_streams);
+ }
+ }
+}
+
enum class AsyncOperationAction {
kLeavePending,
kResolve,
@@ -701,17 +714,18 @@ void PostToCompleteRequest(AsyncOperationAction action, RequestType* request) {
}
}
-class FakeWebRTCPeerConnectionHandler : public MockWebRTCPeerConnectionHandler {
+class FakeRTCPeerConnectionHandlerPlatform
+ : public MockRTCPeerConnectionHandlerPlatform {
public:
- WebVector<std::unique_ptr<RTCRtpTransceiverPlatform>> CreateOffer(
+ Vector<std::unique_ptr<RTCRtpTransceiverPlatform>> CreateOffer(
RTCSessionDescriptionRequest* request,
- const WebMediaConstraints&) override {
+ const MediaConstraints&) override {
PostToCompleteRequest<RTCSessionDescriptionRequest>(async_operation_action_,
request);
return {};
}
- WebVector<std::unique_ptr<RTCRtpTransceiverPlatform>> CreateOffer(
+ Vector<std::unique_ptr<RTCRtpTransceiverPlatform>> CreateOffer(
RTCSessionDescriptionRequest* request,
RTCOfferOptionsPlatform*) override {
PostToCompleteRequest<RTCSessionDescriptionRequest>(async_operation_action_,
@@ -720,7 +734,7 @@ class FakeWebRTCPeerConnectionHandler : public MockWebRTCPeerConnectionHandler {
}
void CreateAnswer(RTCSessionDescriptionRequest* request,
- const WebMediaConstraints&) override {
+ const MediaConstraints&) override {
PostToCompleteRequest<RTCSessionDescriptionRequest>(async_operation_action_,
request);
}
@@ -759,15 +773,11 @@ class FakeWebRTCPeerConnectionHandler : public MockWebRTCPeerConnectionHandler {
// completed. Without fakes we would have had to await promises and callbacks,
// passing SDP returned by one operation to the next.
//
-// TODO(crbug.com/787254): Consider removing or simplifying the inheritance
-// altogether.
-class RTCPeerConnectionCallSetupStateTest
- : public RTCPeerConnectionTestWithPlatformTestingPlatformType<
- TestingPlatformSupport> {
+class RTCPeerConnectionCallSetupStateTest : public RTCPeerConnectionTest {
public:
- std::unique_ptr<WebRTCPeerConnectionHandler> CreateRTCPeerConnectionHandler()
- override {
- auto handler = std::make_unique<FakeWebRTCPeerConnectionHandler>();
+ std::unique_ptr<RTCPeerConnectionHandlerPlatform>
+ CreateRTCPeerConnectionHandler() override {
+ auto handler = std::make_unique<FakeRTCPeerConnectionHandlerPlatform>();
handler_ = handler.get();
return handler;
}
@@ -804,12 +814,10 @@ class RTCPeerConnectionCallSetupStateTest
return CallbackType::Create(v8_function);
}
- Dictionary ToDictionary(V8TestingScope& scope,
- const IDLDictionaryBase* value) {
- return Dictionary(
- scope.GetIsolate(),
- ToV8(value, scope.GetContext()->Global(), scope.GetIsolate()),
- scope.GetExceptionState());
+ ScriptValue ToScriptValue(V8TestingScope& scope, RTCOfferOptions* value) {
+ v8::Isolate* isolate = scope.GetIsolate();
+ return ScriptValue(isolate,
+ ToV8(value, scope.GetContext()->Global(), isolate));
}
private:
@@ -817,7 +825,7 @@ class RTCPeerConnectionCallSetupStateTest
protected:
const CallSetupStateTracker* tracker_ = nullptr;
- FakeWebRTCPeerConnectionHandler* handler_ = nullptr;
+ FakeRTCPeerConnectionHandlerPlatform* handler_ = nullptr;
};
TEST_F(RTCPeerConnectionCallSetupStateTest, InitialState) {
@@ -832,18 +840,21 @@ TEST_F(RTCPeerConnectionCallSetupStateTest, OffererSucceeded) {
V8TestingScope scope;
RTCPeerConnection* pc = Initialize(scope);
// createOffer()
- pc->createOffer(scope.GetScriptState(), RTCOfferOptions::Create());
+ pc->createOffer(scope.GetScriptState(), RTCOfferOptions::Create(),
+ scope.GetExceptionState());
EXPECT_EQ(OffererState::kCreateOfferPending, tracker_->offerer_state());
EXPECT_EQ(CallSetupState::kStarted, tracker_->GetCallSetupState());
platform_->RunUntilIdle();
EXPECT_EQ(OffererState::kCreateOfferResolved, tracker_->offerer_state());
// setLocalDescription(offer)
- pc->setLocalDescription(scope.GetScriptState(), EmptyOffer());
+ pc->setLocalDescription(scope.GetScriptState(), EmptyOffer(),
+ scope.GetExceptionState());
EXPECT_EQ(OffererState::kSetLocalOfferPending, tracker_->offerer_state());
platform_->RunUntilIdle();
EXPECT_EQ(OffererState::kSetLocalOfferResolved, tracker_->offerer_state());
// setRemoteDescription(answer)
- pc->setRemoteDescription(scope.GetScriptState(), EmptyAnswer());
+ pc->setRemoteDescription(scope.GetScriptState(), EmptyAnswer(),
+ scope.GetExceptionState());
EXPECT_EQ(OffererState::kSetRemoteAnswerPending, tracker_->offerer_state());
EXPECT_EQ(CallSetupState::kStarted, tracker_->GetCallSetupState());
platform_->RunUntilIdle();
@@ -856,7 +867,8 @@ TEST_F(RTCPeerConnectionCallSetupStateTest, OffererFailedAtCreateOffer) {
RTCPeerConnection* pc = Initialize(scope);
// createOffer()
SetNextOperationIsSuccessful(false);
- pc->createOffer(scope.GetScriptState(), RTCOfferOptions::Create());
+ pc->createOffer(scope.GetScriptState(), RTCOfferOptions::Create(),
+ scope.GetExceptionState());
platform_->RunUntilIdle();
EXPECT_EQ(OffererState::kCreateOfferRejected, tracker_->offerer_state());
EXPECT_EQ(CallSetupState::kFailed, tracker_->GetCallSetupState());
@@ -867,11 +879,13 @@ TEST_F(RTCPeerConnectionCallSetupStateTest,
V8TestingScope scope;
RTCPeerConnection* pc = Initialize(scope);
// createOffer()
- pc->createOffer(scope.GetScriptState(), RTCOfferOptions::Create());
+ pc->createOffer(scope.GetScriptState(), RTCOfferOptions::Create(),
+ scope.GetExceptionState());
platform_->RunUntilIdle();
// setLocalDescription(offer)
SetNextOperationIsSuccessful(false);
- pc->setLocalDescription(scope.GetScriptState(), EmptyOffer());
+ pc->setLocalDescription(scope.GetScriptState(), EmptyOffer(),
+ scope.GetExceptionState());
platform_->RunUntilIdle();
EXPECT_EQ(OffererState::kSetLocalOfferRejected, tracker_->offerer_state());
EXPECT_EQ(CallSetupState::kFailed, tracker_->GetCallSetupState());
@@ -882,14 +896,17 @@ TEST_F(RTCPeerConnectionCallSetupStateTest,
V8TestingScope scope;
RTCPeerConnection* pc = Initialize(scope);
// createOffer()
- pc->createOffer(scope.GetScriptState(), RTCOfferOptions::Create());
+ pc->createOffer(scope.GetScriptState(), RTCOfferOptions::Create(),
+ scope.GetExceptionState());
platform_->RunUntilIdle();
// setLocalDescription(offer)
- pc->setLocalDescription(scope.GetScriptState(), EmptyOffer());
+ pc->setLocalDescription(scope.GetScriptState(), EmptyOffer(),
+ scope.GetExceptionState());
platform_->RunUntilIdle();
// setRemoteDescription(answer)
SetNextOperationIsSuccessful(false);
- pc->setRemoteDescription(scope.GetScriptState(), EmptyAnswer());
+ pc->setRemoteDescription(scope.GetScriptState(), EmptyAnswer(),
+ scope.GetExceptionState());
platform_->RunUntilIdle();
EXPECT_EQ(OffererState::kSetRemoteAnswerRejected, tracker_->offerer_state());
EXPECT_EQ(CallSetupState::kFailed, tracker_->GetCallSetupState());
@@ -902,7 +919,7 @@ TEST_F(RTCPeerConnectionCallSetupStateTest, OffererLegacyApiPath) {
pc->createOffer(scope.GetScriptState(),
CreateEmptyCallback<V8RTCSessionDescriptionCallback>(scope),
CreateEmptyCallback<V8RTCPeerConnectionErrorCallback>(scope),
- ToDictionary(scope, RTCOfferOptions::Create()),
+ ToScriptValue(scope, RTCOfferOptions::Create()),
scope.GetExceptionState());
EXPECT_EQ(OffererState::kCreateOfferPending, tracker_->offerer_state());
EXPECT_EQ(CallSetupState::kStarted, tracker_->GetCallSetupState());
@@ -932,18 +949,21 @@ TEST_F(RTCPeerConnectionCallSetupStateTest, AnswererSucceeded) {
V8TestingScope scope;
RTCPeerConnection* pc = Initialize(scope);
// setRemoteDescription(offer)
- pc->setRemoteDescription(scope.GetScriptState(), EmptyOffer());
+ pc->setRemoteDescription(scope.GetScriptState(), EmptyOffer(),
+ scope.GetExceptionState());
EXPECT_EQ(AnswererState::kSetRemoteOfferPending, tracker_->answerer_state());
EXPECT_EQ(CallSetupState::kStarted, tracker_->GetCallSetupState());
platform_->RunUntilIdle();
EXPECT_EQ(AnswererState::kSetRemoteOfferResolved, tracker_->answerer_state());
// createAnswer()
- pc->createAnswer(scope.GetScriptState(), RTCAnswerOptions::Create());
+ pc->createAnswer(scope.GetScriptState(), RTCAnswerOptions::Create(),
+ scope.GetExceptionState());
EXPECT_EQ(AnswererState::kCreateAnswerPending, tracker_->answerer_state());
platform_->RunUntilIdle();
EXPECT_EQ(AnswererState::kCreateAnswerResolved, tracker_->answerer_state());
// setLocalDescription(answer)
- pc->setLocalDescription(scope.GetScriptState(), EmptyAnswer());
+ pc->setLocalDescription(scope.GetScriptState(), EmptyAnswer(),
+ scope.GetExceptionState());
EXPECT_EQ(AnswererState::kSetLocalAnswerPending, tracker_->answerer_state());
EXPECT_EQ(CallSetupState::kStarted, tracker_->GetCallSetupState());
platform_->RunUntilIdle();
@@ -957,7 +977,8 @@ TEST_F(RTCPeerConnectionCallSetupStateTest,
RTCPeerConnection* pc = Initialize(scope);
// setRemoteDescription(offer)
SetNextOperationIsSuccessful(false);
- pc->setRemoteDescription(scope.GetScriptState(), EmptyOffer());
+ pc->setRemoteDescription(scope.GetScriptState(), EmptyOffer(),
+ scope.GetExceptionState());
platform_->RunUntilIdle();
EXPECT_EQ(AnswererState::kSetRemoteOfferRejected, tracker_->answerer_state());
EXPECT_EQ(CallSetupState::kFailed, tracker_->GetCallSetupState());
@@ -967,11 +988,13 @@ TEST_F(RTCPeerConnectionCallSetupStateTest, AnswererFailedAtCreateAnswer) {
V8TestingScope scope;
RTCPeerConnection* pc = Initialize(scope);
// setRemoteDescription(offer)
- pc->setRemoteDescription(scope.GetScriptState(), EmptyOffer());
+ pc->setRemoteDescription(scope.GetScriptState(), EmptyOffer(),
+ scope.GetExceptionState());
platform_->RunUntilIdle();
// createAnswer()
SetNextOperationIsSuccessful(false);
- pc->createAnswer(scope.GetScriptState(), RTCAnswerOptions::Create());
+ pc->createAnswer(scope.GetScriptState(), RTCAnswerOptions::Create(),
+ scope.GetExceptionState());
platform_->RunUntilIdle();
EXPECT_EQ(AnswererState::kCreateAnswerRejected, tracker_->answerer_state());
EXPECT_EQ(CallSetupState::kFailed, tracker_->GetCallSetupState());
@@ -982,14 +1005,17 @@ TEST_F(RTCPeerConnectionCallSetupStateTest,
V8TestingScope scope;
RTCPeerConnection* pc = Initialize(scope);
// setRemoteDescription(offer)
- pc->setRemoteDescription(scope.GetScriptState(), EmptyOffer());
+ pc->setRemoteDescription(scope.GetScriptState(), EmptyOffer(),
+ scope.GetExceptionState());
platform_->RunUntilIdle();
// createAnswer()
- pc->createAnswer(scope.GetScriptState(), RTCAnswerOptions::Create());
+ pc->createAnswer(scope.GetScriptState(), RTCAnswerOptions::Create(),
+ scope.GetExceptionState());
platform_->RunUntilIdle();
// setLocalDescription(answer)
SetNextOperationIsSuccessful(false);
- pc->setLocalDescription(scope.GetScriptState(), EmptyAnswer());
+ pc->setLocalDescription(scope.GetScriptState(), EmptyAnswer(),
+ scope.GetExceptionState());
platform_->RunUntilIdle();
EXPECT_EQ(AnswererState::kSetLocalAnswerRejected, tracker_->answerer_state());
EXPECT_EQ(CallSetupState::kFailed, tracker_->GetCallSetupState());
@@ -1011,7 +1037,7 @@ TEST_F(RTCPeerConnectionCallSetupStateTest, AnswererLegacyApiPath) {
pc->createAnswer(scope.GetScriptState(),
CreateEmptyCallback<V8RTCSessionDescriptionCallback>(scope),
CreateEmptyCallback<V8RTCPeerConnectionErrorCallback>(scope),
- Dictionary() /* media_constraints */);
+ scope.GetExceptionState());
EXPECT_EQ(AnswererState::kCreateAnswerPending, tracker_->answerer_state());
platform_->RunUntilIdle();
EXPECT_EQ(AnswererState::kCreateAnswerResolved, tracker_->answerer_state());
@@ -1153,9 +1179,9 @@ class SchedulingAffectingWebRTCFeaturesTest : public SimTest {
return result;
}
- std::unique_ptr<WebRTCPeerConnectionHandler>
+ std::unique_ptr<RTCPeerConnectionHandlerPlatform>
CreateRTCPeerConnectionHandler() {
- return std::make_unique<MockWebRTCPeerConnectionHandler>();
+ return std::make_unique<MockRTCPeerConnectionHandlerPlatform>();
}
};
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 51330591f0c..cbdcc36d046 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
@@ -53,7 +53,9 @@ class RTCQuicStream::PendingWriteBufferedAmountPromise
RTCQuicStream::RTCQuicStream(ExecutionContext* context,
RTCQuicTransport* transport,
QuicStreamProxy* stream_proxy)
- : ContextClient(context), transport_(transport), proxy_(stream_proxy) {
+ : ExecutionContextClient(context),
+ transport_(transport),
+ proxy_(stream_proxy) {
DCHECK(transport_);
DCHECK(proxy_);
}
@@ -397,15 +399,15 @@ const AtomicString& RTCQuicStream::InterfaceName() const {
}
ExecutionContext* RTCQuicStream::GetExecutionContext() const {
- return ContextClient::GetExecutionContext();
+ return ExecutionContextClient::GetExecutionContext();
}
-void RTCQuicStream::Trace(blink::Visitor* visitor) {
+void RTCQuicStream::Trace(Visitor* visitor) {
visitor->Trace(transport_);
visitor->Trace(pending_read_buffered_amount_promises_);
visitor->Trace(pending_write_buffered_amount_promises_);
EventTargetWithInlineData::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 d288f62aa46..069934a6288 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
@@ -5,15 +5,15 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_STREAM_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_STREAM_H_
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_quic_stream_read_result.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_quic_stream_write_parameters.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_proxy.h"
#include "third_party/blink/renderer/modules/peerconnection/byte_buffer_queue.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_read_result.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_write_parameters.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h"
namespace blink {
@@ -26,7 +26,7 @@ enum class RTCQuicStreamState { kNew, kOpening, kOpen, kClosing, kClosed };
// RTCQuicTransport that it is associated with holds a strong reference to it
// as long as it is not closed.
class MODULES_EXPORT RTCQuicStream final : public EventTargetWithInlineData,
- public ContextClient,
+ public ExecutionContextClient,
public QuicStreamProxy::Delegate {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(RTCQuicStream);
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 f6eaaba0657..13298ae9a4c 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
@@ -3,8 +3,8 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_quic_stream_event_init.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event_init.h"
namespace blink {
@@ -37,7 +37,7 @@ const AtomicString& RTCQuicStreamEvent::InterfaceName() const {
return event_interface_names::kRTCQuicStreamEvent;
}
-void RTCQuicStreamEvent::Trace(blink::Visitor* visitor) {
+void RTCQuicStreamEvent::Trace(Visitor* visitor) {
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 8f924f93335..39888dbe79d 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<RTCQuicStream> stream_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.idl
index ced237c75eb..3facdd02986 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.idl
@@ -5,8 +5,8 @@
// https://w3c.github.io/webrtc-quic/#rtcquicstreamevent
[
RuntimeEnabled=RTCQuicTransport,
- Constructor(DOMString type, optional RTCQuicStreamEventInit eventInitDict),
Exposed=Window
] interface RTCQuicStreamEvent : Event {
+ constructor(DOMString type, optional RTCQuicStreamEventInit eventInitDict = {});
readonly attribute 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 05715c9ab7d..801e5baeef4 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
@@ -8,6 +8,7 @@
#include "net/quic/quic_chromium_alarm_factory.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_quic_transport_stats.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_high_res_time_stamp.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
@@ -20,7 +21,6 @@
#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_stats.h"
namespace blink {
namespace {
@@ -150,7 +150,7 @@ RTCQuicTransport::RTCQuicTransport(
const HeapVector<Member<RTCCertificate>>& certificates,
ExceptionState& exception_state,
std::unique_ptr<P2PQuicTransportFactory> p2p_quic_transport_factory)
- : ContextClient(context),
+ : ExecutionContextClient(context),
transport_(transport),
key_(key),
certificates_(certificates),
@@ -691,10 +691,10 @@ const AtomicString& RTCQuicTransport::InterfaceName() const {
}
ExecutionContext* RTCQuicTransport::GetExecutionContext() const {
- return ContextClient::GetExecutionContext();
+ return ExecutionContextClient::GetExecutionContext();
}
-void RTCQuicTransport::Trace(blink::Visitor* visitor) {
+void RTCQuicTransport::Trace(Visitor* visitor) {
visitor->Trace(transport_);
visitor->Trace(certificates_);
visitor->Trace(remote_certificates_);
@@ -706,7 +706,7 @@ void RTCQuicTransport::Trace(blink::Visitor* visitor) {
visitor->Trace(ready_to_send_datagram_promise_);
visitor->Trace(received_datagrams_);
EventTargetWithInlineData::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 5c8d20dee02..a6bb76d6150 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
@@ -6,13 +6,13 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_QUIC_TRANSPORT_H_
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_quic_parameters.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_piece.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/quic_transport_proxy.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_quic_parameters.h"
namespace blink {
@@ -55,7 +55,7 @@ const uint32_t kMaxBufferedRecvDatagrams = 5000;
// long as it is alive.
class MODULES_EXPORT RTCQuicTransport final
: public EventTargetWithInlineData,
- public ContextClient,
+ public ExecutionContextClient,
public QuicTransportProxy::Delegate {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(RTCQuicTransport);
@@ -117,7 +117,11 @@ class MODULES_EXPORT RTCQuicTransport final
// The maximum datagram size in bytes allowed with sendDatagram.
// Before the transport has become connected this will be 0.
- uint16_t maxDatagramLength(bool& is_null) const {
+ base::Optional<uint16_t> maxDatagramLength() const {
+ return max_datagram_length_;
+ }
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ uint16_t maxDatagramLength(bool& is_null) const { // DEPRECATED
is_null = !max_datagram_length_.has_value();
return max_datagram_length_.value_or(0);
}
@@ -188,7 +192,7 @@ class MODULES_EXPORT RTCQuicTransport final
ExecutionContext* GetExecutionContext() const override;
// For garbage collection.
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
enum class StartReason {
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.idl
index bd4055ad9e9..54524edfd9c 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.idl
@@ -13,14 +13,11 @@ enum RTCQuicTransportState {
// https://w3c.github.io/webrtc-quic/#quic-transport*
[
- Constructor(RTCIceTransport transport),
- ConstructorCallWith=ExecutionContext,
- RaisesException=Constructor,
Exposed=Window,
- Measure,
RuntimeEnabled=RTCQuicTransport,
SecureContext
] interface RTCQuicTransport : EventTarget {
+ [CallWith=ExecutionContext, RaisesException, Measure] constructor(RTCIceTransport transport);
[Measure] readonly attribute RTCIceTransport transport;
[Measure] readonly attribute RTCQuicTransportState state;
[Measure] readonly attribute unsigned short? maxDatagramLength;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_test.cc
index d99bc69ead6..94b0ab8e4b9 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_test.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport_test.cc
@@ -12,13 +12,13 @@
#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_gather_options.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_quic_transport_stats.h"
#include "third_party/blink/renderer/core/dom/dom_high_res_time_stamp.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_stats.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/test/mock_p2p_quic_packet_transport.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_gather_options.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/webrtc/rtc_base/rtc_certificate_generator.h"
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_contributing_source.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_contributing_source.idl
index f6825168885..997333fd197 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_contributing_source.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_contributing_source.idl
@@ -8,4 +8,6 @@ dictionary RTCRtpContributingSource {
required unsigned long source;
double audioLevel;
required unsigned long rtpTimestamp;
+ // https://w3c.github.io/webrtc-extensions/#dom-rtcrtpcontributingsource-capturetimestamp
+ [RuntimeEnabled=CaptureTimeInCsrc] DOMHighResTimeStamp captureTimestamp;
};
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 f4abaed8624..a3a012cbecd 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
@@ -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://w3c.github.io/webrtc-pc/#rtcprioritytype-enum
+// https://w3c.github.io/webrtc-priority/#rtc-priority-type
enum RTCPriorityType {
"very-low",
"low",
@@ -12,14 +12,14 @@ enum RTCPriorityType {
// https://w3c.github.io/webrtc-pc/#rtcrtpencodingparameters*
dictionary RTCRtpEncodingParameters : RTCRtpCodingParameters {
- //TODO(orphis): Missing codecPayloadType. https://crbug.com/857042
- //TODO(orphis): Missing dtx. https://crbug.com/857044
boolean active = true;
- RTCPriorityType priority = "low";
- RTCPriorityType networkPriority = "low";
- //TODO(orphis): Missing ptime. https://crbug.com/857046
unsigned long maxBitrate;
- //TODO(orphis): Missing maxFramerate. https://crbug.com/857047
double scaleResolutionDownBy;
+ // https://w3c.github.io/webrtc-priority/#encoding-parameters
+ RTCPriorityType priority = "low";
+ RTCPriorityType networkPriority = "low";
+ // https://w3c.github.io/webrtc-extensions/#dom-rtcrtpencodingparameters-maxframerate
+ double maxFramerate;
+ // https://w3c.github.io/webrtc-svc/#dom-rtcrtpencodingparameters-scalabilitymode
[RuntimeEnabled=RTCSvcScalabilityMode] DOMString scalabilityMode;
};
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 c5b2bf353e8..47fbf7dd8ed 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
@@ -6,20 +6,30 @@
#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/modules/v8/v8_rtc_insertable_streams.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtcp_parameters.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_capabilities.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_codec_parameters.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_decoding_parameters.h"
+#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/loader/document_loader.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/peerconnection/peer_connection_dependency_factory.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_rtcp_parameters.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_capabilities.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_codec_parameters.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_decoding_parameters.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_header_extension_capability.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_header_extension_parameters.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_stats_report.h"
#include "third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.h"
#include "third_party/blink/renderer/platform/bindings/microtask.h"
+#include "third_party/blink/renderer/platform/heap/persistent.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"
#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -30,13 +40,24 @@ namespace blink {
RTCRtpReceiver::RTCRtpReceiver(RTCPeerConnection* pc,
std::unique_ptr<RTCRtpReceiverPlatform> receiver,
MediaStreamTrack* track,
- MediaStreamVector streams)
+ MediaStreamVector streams,
+ bool force_encoded_audio_insertable_streams,
+ bool force_encoded_video_insertable_streams)
: pc_(pc),
receiver_(std::move(receiver)),
track_(track),
- streams_(std::move(streams)) {
+ streams_(std::move(streams)),
+ force_encoded_audio_insertable_streams_(
+ force_encoded_audio_insertable_streams),
+ force_encoded_video_insertable_streams_(
+ force_encoded_video_insertable_streams) {
+ DCHECK(pc_);
DCHECK(receiver_);
DCHECK(track_);
+ if (force_encoded_audio_insertable_streams_ && track_->kind() == "audio")
+ RegisterEncodedAudioStreamCallback();
+ if (force_encoded_video_insertable_streams_ && track_->kind() == "video")
+ RegisterEncodedVideoStreamCallback();
}
MediaStreamTrack* RTCRtpReceiver::track() const {
@@ -52,7 +73,22 @@ RTCDtlsTransport* RTCRtpReceiver::rtcpTransport() {
return nullptr;
}
-double RTCRtpReceiver::playoutDelayHint(bool& is_null, ExceptionState&) {
+base::Optional<double> RTCRtpReceiver::playoutDelayHint() const {
+ return playout_delay_hint_;
+}
+
+void RTCRtpReceiver::setPlayoutDelayHint(base::Optional<double> hint,
+ ExceptionState& exception_state) {
+ if (hint.has_value() && hint.value() < 0.0) {
+ exception_state.ThrowTypeError("playoutDelayHint can't be negative");
+ return;
+ }
+
+ playout_delay_hint_ = hint;
+ receiver_->SetJitterBufferMinimumDelay(playout_delay_hint_);
+}
+
+double RTCRtpReceiver::playoutDelayHint(bool& is_null) {
is_null = !playout_delay_hint_.has_value();
return playout_delay_hint_.value_or(0.0);
}
@@ -75,7 +111,7 @@ HeapVector<Member<RTCRtpSynchronizationSource>>
RTCRtpReceiver::getSynchronizationSources() {
UpdateSourcesIfNeeded();
- Document* document = To<Document>(pc_->GetExecutionContext());
+ Document* document = Document::From(pc_->GetExecutionContext());
DocumentLoadTiming& time_converter = document->Loader()->GetTiming();
HeapVector<Member<RTCRtpSynchronizationSource>> synchronization_sources;
@@ -92,6 +128,10 @@ RTCRtpReceiver::getSynchronizationSources() {
synchronization_source->setSource(web_source->Source());
if (web_source->AudioLevel())
synchronization_source->setAudioLevel(*web_source->AudioLevel());
+ if (web_source->CaptureTimestamp()) {
+ synchronization_source->setCaptureTimestamp(
+ *web_source->CaptureTimestamp());
+ }
synchronization_source->setRtpTimestamp(web_source->RtpTimestamp());
synchronization_sources.push_back(synchronization_source);
}
@@ -102,7 +142,7 @@ HeapVector<Member<RTCRtpContributingSource>>
RTCRtpReceiver::getContributingSources() {
UpdateSourcesIfNeeded();
- Document* document = To<Document>(pc_->GetExecutionContext());
+ Document* document = Document::From(pc_->GetExecutionContext());
DocumentLoadTiming& time_converter = document->Loader()->GetTiming();
HeapVector<Member<RTCRtpContributingSource>> contributing_sources;
@@ -119,6 +159,9 @@ RTCRtpReceiver::getContributingSources() {
contributing_source->setSource(web_source->Source());
if (web_source->AudioLevel())
contributing_source->setAudioLevel(*web_source->AudioLevel());
+ if (web_source->CaptureTimestamp()) {
+ contributing_source->setCaptureTimestamp(*web_source->CaptureTimestamp());
+ }
contributing_source->setRtpTimestamp(web_source->RtpTimestamp());
contributing_sources.push_back(contributing_source);
}
@@ -134,6 +177,44 @@ ScriptPromise RTCRtpReceiver::getStats(ScriptState* script_state) {
return promise;
}
+RTCInsertableStreams* RTCRtpReceiver::createEncodedAudioStreams(
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
+ if (!force_encoded_audio_insertable_streams_) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "Encoded audio streams not requested at PC initialization");
+ return nullptr;
+ }
+ if (encoded_audio_streams_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Encoded audio streams already created");
+ return nullptr;
+ }
+
+ InitializeEncodedAudioStreams(script_state);
+ return encoded_audio_streams_;
+}
+
+RTCInsertableStreams* RTCRtpReceiver::createEncodedVideoStreams(
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
+ if (!force_encoded_video_insertable_streams_) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "Encoded video streams not requested at PC initialization");
+ return nullptr;
+ }
+ if (encoded_video_streams_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Encoded video streams already created");
+ return nullptr;
+ }
+
+ InitializeEncodedVideoStreams(script_state);
+ return encoded_video_streams_;
+}
+
RTCRtpReceiverPlatform* RTCRtpReceiver::platform_receiver() {
return receiver_.get();
}
@@ -173,12 +254,18 @@ void RTCRtpReceiver::SetContributingSourcesNeedsUpdating() {
web_sources_needs_updating_ = true;
}
-void RTCRtpReceiver::Trace(blink::Visitor* visitor) {
+void RTCRtpReceiver::Trace(Visitor* visitor) {
visitor->Trace(pc_);
visitor->Trace(track_);
visitor->Trace(transport_);
visitor->Trace(streams_);
visitor->Trace(transceiver_);
+ visitor->Trace(audio_from_depacketizer_underlying_source_);
+ visitor->Trace(audio_to_decoder_underlying_sink_);
+ visitor->Trace(encoded_audio_streams_);
+ visitor->Trace(video_from_depacketizer_underlying_source_);
+ visitor->Trace(video_to_decoder_underlying_sink_);
+ visitor->Trace(encoded_video_streams_);
ScriptWrappable::Trace(visitor);
}
@@ -192,8 +279,8 @@ RTCRtpCapabilities* RTCRtpReceiver::getCapabilities(const String& kind) {
HeapVector<Member<RTCRtpHeaderExtensionCapability>>());
std::unique_ptr<webrtc::RtpCapabilities> rtc_capabilities =
- PeerConnectionDependencyFactory::GetInstance()->GetSenderCapabilities(
- kind.Utf8());
+ PeerConnectionDependencyFactory::GetInstance()->GetReceiverCapabilities(
+ kind);
HeapVector<Member<RTCRtpCodecCapability>> codecs;
codecs.ReserveInitialCapacity(
@@ -271,4 +358,142 @@ RTCRtpReceiveParameters* RTCRtpReceiver::getParameters() {
return parameters;
}
+void RTCRtpReceiver::RegisterEncodedAudioStreamCallback() {
+ DCHECK(!platform_receiver()
+ ->GetEncodedAudioStreamTransformer()
+ ->HasTransformerCallback());
+ DCHECK_EQ(track_->kind(), "audio");
+ platform_receiver()
+ ->GetEncodedAudioStreamTransformer()
+ ->SetTransformerCallback(
+ WTF::BindRepeating(&RTCRtpReceiver::OnAudioFrameFromDepacketizer,
+ WrapWeakPersistent(this)));
+}
+
+void RTCRtpReceiver::UnregisterEncodedAudioStreamCallback() {
+ DCHECK_EQ(track_->kind(), "audio");
+ platform_receiver()
+ ->GetEncodedAudioStreamTransformer()
+ ->ResetTransformerCallback();
+}
+
+void RTCRtpReceiver::InitializeEncodedAudioStreams(ScriptState* script_state) {
+ DCHECK(!encoded_audio_streams_);
+ DCHECK(!audio_from_depacketizer_underlying_source_);
+ DCHECK(!audio_to_decoder_underlying_sink_);
+ DCHECK(force_encoded_audio_insertable_streams_);
+
+ encoded_audio_streams_ = RTCInsertableStreams::Create();
+
+ // Set up readable.
+ audio_from_depacketizer_underlying_source_ =
+ MakeGarbageCollected<RTCEncodedAudioUnderlyingSource>(
+ script_state,
+ WTF::Bind(&RTCRtpReceiver::UnregisterEncodedAudioStreamCallback,
+ WrapWeakPersistent(this)),
+ /*is_receiver=*/true);
+ // The high water mark for the readable stream is set to 0 so that frames are
+ // removed from the queue right away, without introducing a new buffer.
+ encoded_audio_streams_->setReadableStream(
+ ReadableStream::CreateWithCountQueueingStrategy(
+ script_state, audio_from_depacketizer_underlying_source_,
+ /*high_water_mark=*/0));
+
+ // Set up writable.
+ audio_to_decoder_underlying_sink_ =
+ MakeGarbageCollected<RTCEncodedAudioUnderlyingSink>(
+ script_state,
+ WTF::BindRepeating(
+ [](RTCRtpReceiver* receiver)
+ -> RTCEncodedAudioStreamTransformer* {
+ return receiver ? receiver->platform_receiver()
+ ->GetEncodedAudioStreamTransformer()
+ : nullptr;
+ },
+ WrapWeakPersistent(this)));
+ // The high water mark for the stream is set to 1 so that the stream seems
+ // ready to write, but without queuing frames.
+ encoded_audio_streams_->setWritableStream(
+ WritableStream::CreateWithCountQueueingStrategy(
+ script_state, audio_to_decoder_underlying_sink_,
+ /*high_water_mark=*/1));
+}
+
+void RTCRtpReceiver::OnAudioFrameFromDepacketizer(
+ std::unique_ptr<webrtc::TransformableFrameInterface> encoded_audio_frame) {
+ if (audio_from_depacketizer_underlying_source_) {
+ audio_from_depacketizer_underlying_source_->OnFrameFromSource(
+ std::move(encoded_audio_frame));
+ }
+}
+
+void RTCRtpReceiver::RegisterEncodedVideoStreamCallback() {
+ DCHECK(!platform_receiver()
+ ->GetEncodedVideoStreamTransformer()
+ ->HasTransformerCallback());
+ DCHECK_EQ(track_->kind(), "video");
+ platform_receiver()
+ ->GetEncodedVideoStreamTransformer()
+ ->SetTransformerCallback(
+ WTF::BindRepeating(&RTCRtpReceiver::OnVideoFrameFromDepacketizer,
+ WrapWeakPersistent(this)));
+}
+
+void RTCRtpReceiver::UnregisterEncodedVideoStreamCallback() {
+ DCHECK_EQ(track_->kind(), "video");
+ platform_receiver()
+ ->GetEncodedVideoStreamTransformer()
+ ->ResetTransformerCallback();
+}
+
+void RTCRtpReceiver::InitializeEncodedVideoStreams(ScriptState* script_state) {
+ DCHECK(!encoded_video_streams_);
+ DCHECK(!video_from_depacketizer_underlying_source_);
+ DCHECK(!video_to_decoder_underlying_sink_);
+ DCHECK(force_encoded_video_insertable_streams_);
+
+ encoded_video_streams_ = RTCInsertableStreams::Create();
+
+ // Set up readable.
+ video_from_depacketizer_underlying_source_ =
+ MakeGarbageCollected<RTCEncodedVideoUnderlyingSource>(
+ script_state,
+ WTF::Bind(&RTCRtpReceiver::UnregisterEncodedVideoStreamCallback,
+ WrapWeakPersistent(this)));
+ // The high water mark for the readable stream is set to 0 so that frames are
+ // removed from the queue right away, without introducing a new buffer.
+ encoded_video_streams_->setReadableStream(
+ ReadableStream::CreateWithCountQueueingStrategy(
+ script_state, video_from_depacketizer_underlying_source_,
+ /*high_water_mark=*/0));
+
+ // Set up writable.
+ video_to_decoder_underlying_sink_ =
+ MakeGarbageCollected<RTCEncodedVideoUnderlyingSink>(
+ script_state,
+ WTF::BindRepeating(
+ [](RTCRtpReceiver* receiver)
+ -> RTCEncodedVideoStreamTransformer* {
+ return receiver ? receiver->platform_receiver()
+ ->GetEncodedVideoStreamTransformer()
+ : nullptr;
+ },
+ WrapWeakPersistent(this)));
+ // The high water mark for the stream is set to 1 so that the stream seems
+ // ready to write, but without queuing frames.
+ encoded_video_streams_->setWritableStream(
+ WritableStream::CreateWithCountQueueingStrategy(
+ script_state, video_to_decoder_underlying_sink_,
+ /*high_water_mark=*/1));
+}
+
+void RTCRtpReceiver::OnVideoFrameFromDepacketizer(
+ std::unique_ptr<webrtc::TransformableVideoFrameInterface>
+ encoded_video_frame) {
+ if (video_from_depacketizer_underlying_source_) {
+ video_from_depacketizer_underlying_source_->OnFrameFromSource(
+ std::move(encoded_video_frame));
+ }
+}
+
} // namespace blink
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 cb53ebba38d..7f922ff24af 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
@@ -8,11 +8,11 @@
#include "base/optional.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_vector.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_contributing_source.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_receive_parameters.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_synchronization_source.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_track.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_contributing_source.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_receive_parameters.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_synchronization_source.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/heap/garbage_collected.h"
@@ -23,6 +23,11 @@
namespace blink {
class RTCDtlsTransport;
+class RTCEncodedAudioUnderlyingSource;
+class RTCEncodedAudioUnderlyingSink;
+class RTCEncodedVideoUnderlyingSource;
+class RTCEncodedVideoUnderlyingSink;
+class RTCInsertableStreams;
class RTCPeerConnection;
class RTCRtpCapabilities;
class RTCRtpTransceiver;
@@ -36,19 +41,28 @@ class RTCRtpReceiver final : public ScriptWrappable {
RTCRtpReceiver(RTCPeerConnection*,
std::unique_ptr<RTCRtpReceiverPlatform>,
MediaStreamTrack*,
- MediaStreamVector);
+ MediaStreamVector,
+ bool force_encoded_audio_insertable_streams,
+ bool force_encoded_video_insertable_streams);
static RTCRtpCapabilities* getCapabilities(const String& kind);
MediaStreamTrack* track() const;
RTCDtlsTransport* transport();
RTCDtlsTransport* rtcpTransport();
- double playoutDelayHint(bool&, ExceptionState&);
- void setPlayoutDelayHint(double, bool, ExceptionState&);
+ base::Optional<double> playoutDelayHint() const;
+ void setPlayoutDelayHint(base::Optional<double>, ExceptionState&);
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ double playoutDelayHint(bool&); // DEPRECATED
+ void setPlayoutDelayHint(double, bool, ExceptionState&); // DEPRECATED
RTCRtpReceiveParameters* getParameters();
HeapVector<Member<RTCRtpSynchronizationSource>> getSynchronizationSources();
HeapVector<Member<RTCRtpContributingSource>> getContributingSources();
ScriptPromise getStats(ScriptState*);
+ RTCInsertableStreams* createEncodedAudioStreams(ScriptState*,
+ ExceptionState&);
+ RTCInsertableStreams* createEncodedVideoStreams(ScriptState*,
+ ExceptionState&);
RTCRtpReceiverPlatform* platform_receiver();
MediaStreamVector streams() const;
@@ -57,12 +71,23 @@ class RTCRtpReceiver final : public ScriptWrappable {
void set_transport(RTCDtlsTransport*);
void UpdateSourcesIfNeeded();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
- Member<RTCPeerConnection> pc_;
void SetContributingSourcesNeedsUpdating();
+ void RegisterEncodedAudioStreamCallback();
+ void UnregisterEncodedAudioStreamCallback();
+ void InitializeEncodedAudioStreams(ScriptState*);
+ void OnAudioFrameFromDepacketizer(
+ std::unique_ptr<webrtc::TransformableFrameInterface> encoded_audio_frame);
+ void RegisterEncodedVideoStreamCallback();
+ void UnregisterEncodedVideoStreamCallback();
+ void InitializeEncodedVideoStreams(ScriptState*);
+ void OnVideoFrameFromDepacketizer(
+ std::unique_ptr<webrtc::TransformableVideoFrameInterface>
+ encoded_video_frame);
+ Member<RTCPeerConnection> pc_;
std::unique_ptr<RTCRtpReceiverPlatform> receiver_;
Member<MediaStreamTrack> track_;
Member<RTCDtlsTransport> transport_;
@@ -70,7 +95,7 @@ class RTCRtpReceiver final : public ScriptWrappable {
// The current SSRCs and CSRCs. getSynchronizationSources() returns the SSRCs
// and getContributingSources() returns the CSRCs.
- WebVector<std::unique_ptr<RTCRtpSource>> web_sources_;
+ Vector<std::unique_ptr<RTCRtpSource>> web_sources_;
bool web_sources_needs_updating_ = true;
Member<RTCRtpTransceiver> transceiver_;
@@ -78,6 +103,20 @@ class RTCRtpReceiver final : public ScriptWrappable {
// observed delay may differ depending on the congestion control. |nullopt|
// means default value must be used.
base::Optional<double> playout_delay_hint_;
+
+ // Insertable Streams support for audio
+ bool force_encoded_audio_insertable_streams_;
+ Member<RTCEncodedAudioUnderlyingSource>
+ audio_from_depacketizer_underlying_source_;
+ Member<RTCEncodedAudioUnderlyingSink> audio_to_decoder_underlying_sink_;
+ Member<RTCInsertableStreams> encoded_audio_streams_;
+
+ // Insertable Streams support for video
+ bool force_encoded_video_insertable_streams_;
+ Member<RTCEncodedVideoUnderlyingSource>
+ video_from_depacketizer_underlying_source_;
+ Member<RTCEncodedVideoUnderlyingSink> video_to_decoder_underlying_sink_;
+ Member<RTCInsertableStreams> encoded_video_streams_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.idl
index 0d88ea811ef..54d2c964d8c 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.idl
@@ -6,13 +6,15 @@
[Exposed=Window]
interface RTCRtpReceiver {
readonly attribute MediaStreamTrack track;
- [RuntimeEnabled=RTCDtlsTransport] readonly attribute RTCDtlsTransport? transport;
- [RuntimeEnabled=RTCDtlsTransport] readonly attribute RTCDtlsTransport? rtcpTransport;
+ readonly attribute RTCDtlsTransport? transport;
+ readonly attribute RTCDtlsTransport? rtcpTransport;
// https://henbos.github.io/webrtc-extensions/#dom-rtcrtpreceiver-playoutdelayhint
- [RaisesException, Measure] attribute double? playoutDelayHint;
+ [RaisesException=Setter, Measure] attribute double? playoutDelayHint;
static RTCRtpCapabilities? getCapabilities(DOMString kind);
RTCRtpReceiveParameters getParameters();
sequence<RTCRtpSynchronizationSource> getSynchronizationSources();
sequence<RTCRtpContributingSource> getContributingSources();
[CallWith=ScriptState] Promise<RTCStatsReport> getStats();
+ [Measure, RuntimeEnabled=RTCInsertableStreams, CallWith=ScriptState, RaisesException] RTCInsertableStreams createEncodedAudioStreams();
+ [Measure, RuntimeEnabled=RTCInsertableStreams, CallWith=ScriptState, RaisesException] RTCInsertableStreams createEncodedVideoStreams();
};
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 659fb9bb59f..a6afe97220d 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
@@ -6,9 +6,11 @@
#include "base/bind.h"
#include "base/logging.h"
-#include "third_party/blink/public/platform/web_rtc_stats.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"
#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_sender_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
#include "third_party/blink/renderer/platform/peerconnection/webrtc_util.h"
#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
#include "third_party/webrtc/api/scoped_refptr.h"
@@ -135,7 +137,9 @@ class RTCRtpReceiverImpl::RTCRtpReceiverInternal
public:
RTCRtpReceiverInternal(
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
- RtpReceiverState state)
+ RtpReceiverState state,
+ bool force_encoded_audio_insertable_streams,
+ bool force_encoded_video_insertable_streams)
: native_peer_connection_(std::move(native_peer_connection)),
main_task_runner_(state.main_task_runner()),
signaling_task_runner_(state.signaling_task_runner()),
@@ -143,6 +147,21 @@ class RTCRtpReceiverImpl::RTCRtpReceiverInternal
state_(std::move(state)) {
DCHECK(native_peer_connection_);
DCHECK(state_.is_initialized());
+ if (force_encoded_audio_insertable_streams &&
+ webrtc_receiver_->media_type() == cricket::MEDIA_TYPE_AUDIO) {
+ encoded_audio_transformer_ =
+ std::make_unique<RTCEncodedAudioStreamTransformer>(main_task_runner_);
+ webrtc_receiver_->SetDepacketizerToDecoderFrameTransformer(
+ encoded_audio_transformer_->Delegate());
+ }
+ if (force_encoded_video_insertable_streams &&
+ webrtc_receiver_->media_type() == cricket::MEDIA_TYPE_VIDEO) {
+ encoded_video_transformer_ =
+ std::make_unique<RTCEncodedVideoStreamTransformer>(main_task_runner_);
+ webrtc_receiver_->SetDepacketizerToDecoderFrameTransformer(
+ encoded_video_transformer_->Delegate());
+ }
+ DCHECK(!encoded_audio_transformer_ || !encoded_video_transformer_);
}
const RtpReceiverState& state() const {
@@ -159,21 +178,20 @@ class RTCRtpReceiverImpl::RTCRtpReceiverInternal
state_ = std::move(state);
}
- blink::WebVector<std::unique_ptr<RTCRtpSource>> GetSources() {
+ Vector<std::unique_ptr<RTCRtpSource>> GetSources() {
// The webrtc_recever_ is a proxy, so this is a blocking call to the webrtc
// signalling thread.
auto webrtc_sources = webrtc_receiver_->GetSources();
- blink::WebVector<std::unique_ptr<RTCRtpSource>> sources(
- webrtc_sources.size());
- for (size_t i = 0; i < webrtc_sources.size(); ++i) {
+ Vector<std::unique_ptr<RTCRtpSource>> sources(
+ static_cast<WTF::wtf_size_t>(webrtc_sources.size()));
+ for (WTF::wtf_size_t i = 0; i < webrtc_sources.size(); ++i) {
sources[i] = std::make_unique<RTCRtpSource>(webrtc_sources[i]);
}
return sources;
}
- void GetStats(
- blink::WebRTCStatsReportCallback callback,
- const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids) {
+ void GetStats(RTCStatsReportCallback callback,
+ const Vector<webrtc::NonStandardGroupId>& exposed_group_ids) {
signaling_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&RTCRtpReceiverInternal::GetStatsOnSignalingThread, this,
@@ -190,6 +208,14 @@ class RTCRtpReceiverImpl::RTCRtpReceiverInternal
blink::ToAbslOptional(delay_seconds));
}
+ RTCEncodedAudioStreamTransformer* GetEncodedAudioStreamTransformer() const {
+ return encoded_audio_transformer_.get();
+ }
+
+ RTCEncodedVideoStreamTransformer* GetEncodedVideoStreamTransformer() const {
+ return encoded_video_transformer_.get();
+ }
+
private:
friend class WTF::ThreadSafeRefCounted<RTCRtpReceiverInternal,
RTCRtpReceiverInternalTraits>;
@@ -200,12 +226,12 @@ class RTCRtpReceiverImpl::RTCRtpReceiverInternal
}
void GetStatsOnSignalingThread(
- blink::WebRTCStatsReportCallback callback,
- const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids) {
+ RTCStatsReportCallback callback,
+ const Vector<webrtc::NonStandardGroupId>& exposed_group_ids) {
native_peer_connection_->GetStats(
webrtc_receiver_.get(),
- blink::CreateRTCStatsCollectorCallback(
- main_task_runner_, std::move(callback), exposed_group_ids));
+ CreateRTCStatsCollectorCallback(main_task_runner_, std::move(callback),
+ exposed_group_ids));
}
const scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection_;
@@ -215,6 +241,8 @@ class RTCRtpReceiverImpl::RTCRtpReceiverInternal
const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
const scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_;
const scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver_;
+ std::unique_ptr<RTCEncodedAudioStreamTransformer> encoded_audio_transformer_;
+ std::unique_ptr<RTCEncodedVideoStreamTransformer> encoded_video_transformer_;
RtpReceiverState state_;
};
@@ -241,10 +269,14 @@ uintptr_t RTCRtpReceiverImpl::getId(
RTCRtpReceiverImpl::RTCRtpReceiverImpl(
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
- RtpReceiverState state)
+ RtpReceiverState state,
+ bool force_encoded_audio_insertable_streams,
+ bool force_encoded_video_insertable_streams)
: internal_(base::MakeRefCounted<RTCRtpReceiverInternal>(
std::move(native_peer_connection),
- std::move(state))) {}
+ std::move(state),
+ force_encoded_audio_insertable_streams,
+ force_encoded_video_insertable_streams)) {}
RTCRtpReceiverImpl::RTCRtpReceiverImpl(const RTCRtpReceiverImpl& other)
: internal_(other.internal_) {}
@@ -288,22 +320,22 @@ const blink::WebMediaStreamTrack& RTCRtpReceiverImpl::Track() const {
return internal_->state().track_ref()->web_track();
}
-blink::WebVector<blink::WebString> RTCRtpReceiverImpl::StreamIds() const {
+Vector<String> RTCRtpReceiverImpl::StreamIds() const {
const auto& stream_ids = internal_->state().stream_ids();
- blink::WebVector<blink::WebString> web_stream_ids(stream_ids.size());
- for (size_t i = 0; i < stream_ids.size(); ++i)
- web_stream_ids[i] = blink::WebString::FromUTF8(stream_ids[i]);
- return web_stream_ids;
+ Vector<String> wtf_stream_ids(
+ static_cast<WTF::wtf_size_t>(stream_ids.size()));
+ for (WTF::wtf_size_t i = 0; i < stream_ids.size(); ++i)
+ wtf_stream_ids[i] = String::FromUTF8(stream_ids[i]);
+ return wtf_stream_ids;
}
-blink::WebVector<std::unique_ptr<RTCRtpSource>>
-RTCRtpReceiverImpl::GetSources() {
+Vector<std::unique_ptr<RTCRtpSource>> RTCRtpReceiverImpl::GetSources() {
return internal_->GetSources();
}
void RTCRtpReceiverImpl::GetStats(
- blink::WebRTCStatsReportCallback callback,
- const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids) {
+ RTCStatsReportCallback callback,
+ const Vector<webrtc::NonStandardGroupId>& exposed_group_ids) {
internal_->GetStats(std::move(callback), exposed_group_ids);
}
@@ -317,6 +349,16 @@ void RTCRtpReceiverImpl::SetJitterBufferMinimumDelay(
internal_->SetJitterBufferMinimumDelay(delay_seconds);
}
+RTCEncodedAudioStreamTransformer*
+RTCRtpReceiverImpl::GetEncodedAudioStreamTransformer() const {
+ return internal_->GetEncodedAudioStreamTransformer();
+}
+
+RTCEncodedVideoStreamTransformer*
+RTCRtpReceiverImpl::GetEncodedVideoStreamTransformer() const {
+ return internal_->GetEncodedVideoStreamTransformer();
+}
+
RTCRtpReceiverOnlyTransceiver::RTCRtpReceiverOnlyTransceiver(
std::unique_ptr<RTCRtpReceiverPlatform> receiver)
: receiver_(std::move(receiver)) {
@@ -335,9 +377,9 @@ uintptr_t RTCRtpReceiverOnlyTransceiver::Id() const {
return 0u;
}
-blink::WebString RTCRtpReceiverOnlyTransceiver::Mid() const {
+String RTCRtpReceiverOnlyTransceiver::Mid() const {
NOTIMPLEMENTED();
- return blink::WebString();
+ return String();
}
std::unique_ptr<blink::RTCRtpSenderPlatform>
@@ -380,7 +422,7 @@ RTCRtpReceiverOnlyTransceiver::FiredDirection() const {
}
webrtc::RTCError RTCRtpReceiverOnlyTransceiver::SetCodecPreferences(
- blink::WebVector<webrtc::RtpCodecCapability>) {
+ Vector<webrtc::RtpCodecCapability>) {
NOTIMPLEMENTED();
return {};
}
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 53504987519..81c2d44cace 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
@@ -12,11 +12,11 @@
#include "base/single_thread_task_runner.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/platform/web_rtc_stats.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_receiver_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
#include "third_party/webrtc/api/media_stream_interface.h"
#include "third_party/webrtc/api/peer_connection_interface.h"
#include "third_party/webrtc/api/rtp_receiver_interface.h"
@@ -24,6 +24,9 @@
namespace blink {
+class RTCEncodedAudioStreamTransformer;
+class RTCEncodedVideoStreamTransformer;
+
// This class represents the state of a receiver; a snapshot of what a
// webrtc-layer receiver looked like when it was inspected on the signaling
// thread such that this information can be moved to the main thread in a single
@@ -113,7 +116,9 @@ class MODULES_EXPORT RTCRtpReceiverImpl : public RTCRtpReceiverPlatform {
RTCRtpReceiverImpl(
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
- RtpReceiverState state);
+ RtpReceiverState state,
+ bool force_encoded_audio_insertable_streams,
+ bool force_encoded_video_insertable_streams);
RTCRtpReceiverImpl(const RTCRtpReceiverImpl& other);
~RTCRtpReceiverImpl() override;
@@ -128,13 +133,17 @@ class MODULES_EXPORT RTCRtpReceiverImpl : public RTCRtpReceiverPlatform {
webrtc::DtlsTransportInformation DtlsTransportInformation() override;
const blink::WebMediaStreamTrack& Track() const override;
- blink::WebVector<blink::WebString> StreamIds() const override;
- blink::WebVector<std::unique_ptr<RTCRtpSource>> GetSources() override;
- void GetStats(blink::WebRTCStatsReportCallback,
- const blink::WebVector<webrtc::NonStandardGroupId>&) override;
+ Vector<String> StreamIds() const override;
+ Vector<std::unique_ptr<RTCRtpSource>> GetSources() override;
+ void GetStats(RTCStatsReportCallback,
+ const Vector<webrtc::NonStandardGroupId>&) override;
std::unique_ptr<webrtc::RtpParameters> GetParameters() const override;
void SetJitterBufferMinimumDelay(
base::Optional<double> delay_seconds) override;
+ RTCEncodedAudioStreamTransformer* GetEncodedAudioStreamTransformer()
+ const override;
+ RTCEncodedVideoStreamTransformer* GetEncodedVideoStreamTransformer()
+ const override;
private:
class RTCRtpReceiverInternal;
@@ -153,7 +162,7 @@ class MODULES_EXPORT RTCRtpReceiverOnlyTransceiver
RTCRtpTransceiverPlatformImplementationType ImplementationType()
const override;
uintptr_t Id() const override;
- blink::WebString Mid() const override;
+ String Mid() const override;
std::unique_ptr<blink::RTCRtpSenderPlatform> Sender() const override;
std::unique_ptr<RTCRtpReceiverPlatform> Receiver() const override;
bool Stopped() const override;
@@ -164,7 +173,7 @@ class MODULES_EXPORT RTCRtpReceiverOnlyTransceiver
base::Optional<webrtc::RtpTransceiverDirection> FiredDirection()
const override;
webrtc::RTCError SetCodecPreferences(
- blink::WebVector<webrtc::RtpCodecCapability>) override;
+ Vector<webrtc::RtpCodecCapability>) override;
private:
std::unique_ptr<RTCRtpReceiverPlatform> receiver_;
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 7327a4d5b21..cf601a79ad4 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
@@ -14,7 +14,6 @@
#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_rtc_stats.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"
@@ -60,7 +59,9 @@ class RTCRtpReceiverImplTest : public ::testing::Test {
}
std::unique_ptr<RTCRtpReceiverImpl> CreateReceiver(
- scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track) {
+ scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track,
+ bool force_encoded_audio_insertable_streams = false,
+ bool force_encoded_video_insertable_streams = false) {
std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
track_ref;
base::RunLoop run_loop;
@@ -77,8 +78,10 @@ class RTCRtpReceiverImplTest : public ::testing::Test {
main_thread_, dependency_factory_->GetWebRtcSignalingTaskRunner(),
mock_webrtc_receiver_.get(), std::move(track_ref), {});
state.Initialize();
- return std::make_unique<RTCRtpReceiverImpl>(peer_connection_.get(),
- std::move(state));
+ return std::make_unique<RTCRtpReceiverImpl>(
+ peer_connection_.get(), std::move(state),
+ force_encoded_audio_insertable_streams,
+ force_encoded_video_insertable_streams);
}
scoped_refptr<blink::TestWebRTCStatsReportObtainer> GetStats() {
@@ -118,6 +121,8 @@ TEST_F(RTCRtpReceiverImplTest, CreateReceiver) {
EXPECT_FALSE(receiver_->Track().IsNull());
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());
}
TEST_F(RTCRtpReceiverImplTest, ShallowCopy) {
@@ -166,4 +171,15 @@ TEST_F(RTCRtpReceiverImplTest, GetStats) {
EXPECT_EQ(stats->Timestamp(), 1.234);
}
+TEST_F(RTCRtpReceiverImplTest, CreateReceiverWithInsertableStreams) {
+ scoped_refptr<blink::MockWebRtcAudioTrack> webrtc_track =
+ blink::MockWebRtcAudioTrack::Create("webrtc_track");
+ receiver_ = CreateReceiver(webrtc_track,
+ /*force_encoded_audio_insertable_streams=*/true,
+ /*force_encoded_video_insertable_streams=*/true);
+ EXPECT_TRUE(receiver_->GetEncodedAudioStreamTransformer());
+ // There should be no video transformer in audio receivers.
+ EXPECT_FALSE(receiver_->GetEncodedVideoStreamTransformer());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_send_parameters.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_send_parameters.idl
index 29664cbe38d..da4295da16b 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_send_parameters.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_send_parameters.idl
@@ -2,9 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// https://w3c.github.io/mst-content-hint/#dom-rtcdegradationpreference
+enum RTCDegradationPreference {
+ "maintain-framerate",
+ "maintain-resolution",
+ "balanced"
+};
+
// https://w3c.github.io/webrtc-pc/#rtcsendrtpparameters
dictionary RTCRtpSendParameters : RTCRtpParameters {
required DOMString transactionId;
required sequence<RTCRtpEncodingParameters> encodings;
- //TODO(orphis): Missing degradationPrerence. https://crbug.com/857041
-}; \ No newline at end of file
+ RTCDegradationPreference degradationPreference;
+};
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 4e6f28a8cfb..d1f190e117b 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
@@ -10,18 +10,25 @@
#include <utility>
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_insertable_streams.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtcp_parameters.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_capabilities.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_codec_parameters.h"
+#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/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"
#include "third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_error_util.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_rtcp_parameters.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_capabilities.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_codec_parameters.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_header_extension_capability.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_header_extension_parameters.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_stats_report.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.h"
#include "third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.h"
@@ -29,6 +36,8 @@
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/persistent.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"
#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/wtf/functional.h"
@@ -61,7 +70,7 @@ class ReplaceTrackRequest : public RTCVoidRequest {
resolver_->Reject(exception_state);
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(sender_);
visitor->Trace(with_track_);
visitor->Trace(resolver_);
@@ -92,7 +101,7 @@ class SetParametersRequest : public RTCVoidRequestScriptPromiseResolverImpl {
RTCVoidRequestScriptPromiseResolverImpl::RequestFailed(error);
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(sender_);
RTCVoidRequestScriptPromiseResolverImpl::Trace(visitor);
}
@@ -245,7 +254,38 @@ double PriorityToDouble(const WTF::String& priority) {
return result;
}
-std::tuple<Vector<webrtc::RtpEncodingParameters>, webrtc::DegradationPreference>
+std::string PriorityFromEnum(webrtc::Priority priority) {
+ switch (priority) {
+ case webrtc::Priority::kVeryLow:
+ return "very-low";
+ case webrtc::Priority::kLow:
+ return "low";
+ case webrtc::Priority::kMedium:
+ return "medium";
+ case webrtc::Priority::kHigh:
+ return "high";
+ }
+}
+
+webrtc::Priority PriorityToEnum(const WTF::String& priority) {
+ webrtc::Priority result = webrtc::Priority::kLow;
+
+ if (priority == "very-low") {
+ result = webrtc::Priority::kVeryLow;
+ } else if (priority == "low") {
+ result = webrtc::Priority::kLow;
+ } else if (priority == "medium") {
+ result = webrtc::Priority::kMedium;
+ } else if (priority == "high") {
+ result = webrtc::Priority::kHigh;
+ } else {
+ NOTREACHED();
+ }
+ return result;
+}
+
+std::tuple<Vector<webrtc::RtpEncodingParameters>,
+ absl::optional<webrtc::DegradationPreference>>
ToRtpParameters(const RTCRtpSendParameters* parameters) {
Vector<webrtc::RtpEncodingParameters> encodings;
if (parameters->hasEncodings()) {
@@ -256,8 +296,22 @@ ToRtpParameters(const RTCRtpSendParameters* parameters) {
}
}
- webrtc::DegradationPreference degradation_preference =
- webrtc::DegradationPreference::BALANCED;
+ absl::optional<webrtc::DegradationPreference> degradation_preference;
+
+ if (parameters->hasDegradationPreference()) {
+ if (parameters->degradationPreference() == "balanced") {
+ degradation_preference = webrtc::DegradationPreference::BALANCED;
+ } else if (parameters->degradationPreference() == "maintain-framerate") {
+ degradation_preference =
+ webrtc::DegradationPreference::MAINTAIN_FRAMERATE;
+ } else if (parameters->degradationPreference() == "maintain-resolution") {
+ degradation_preference =
+ webrtc::DegradationPreference::MAINTAIN_RESOLUTION;
+ } else {
+ NOTREACHED();
+ }
+ }
+
return std::make_tuple(encodings, degradation_preference);
}
@@ -265,8 +319,6 @@ ToRtpParameters(const RTCRtpSendParameters* parameters) {
webrtc::RtpEncodingParameters ToRtpEncodingParameters(
const RTCRtpEncodingParameters* encoding) {
- // TODO(orphis): Forward missing fields from the WebRTC library:
- // codecPayloadType, dtx, ptime, maxFramerate, scaleResolutionDownBy.
webrtc::RtpEncodingParameters webrtc_encoding;
if (encoding->hasRid()) {
webrtc_encoding.rid = encoding->rid().Utf8();
@@ -274,7 +326,7 @@ webrtc::RtpEncodingParameters ToRtpEncodingParameters(
webrtc_encoding.active = encoding->active();
webrtc_encoding.bitrate_priority = PriorityToDouble(encoding->priority());
webrtc_encoding.network_priority =
- PriorityToDouble(encoding->networkPriority());
+ PriorityToEnum(encoding->networkPriority());
if (encoding->hasMaxBitrate()) {
webrtc_encoding.max_bitrate_bps = clampTo<int>(encoding->maxBitrate());
}
@@ -282,6 +334,9 @@ webrtc::RtpEncodingParameters ToRtpEncodingParameters(
webrtc_encoding.scale_resolution_down_by =
encoding->scaleResolutionDownBy();
}
+ if (encoding->hasMaxFramerate()) {
+ webrtc_encoding.max_framerate = encoding->maxFramerate();
+ }
// https://w3c.github.io/webrtc-svc/
if (encoding->hasScalabilityMode()) {
if (encoding->scalabilityMode() == "L1T2") {
@@ -294,7 +349,7 @@ webrtc::RtpEncodingParameters ToRtpEncodingParameters(
}
RTCRtpHeaderExtensionParameters* ToRtpHeaderExtensionParameters(
- const webrtc::RtpHeaderExtensionParameters& webrtc_header) {
+ const webrtc::RtpExtension& webrtc_header) {
RTCRtpHeaderExtensionParameters* header =
RTCRtpHeaderExtensionParameters::Create();
header->setUri(webrtc_header.uri.c_str());
@@ -328,15 +383,27 @@ RTCRtpSender::RTCRtpSender(RTCPeerConnection* pc,
std::unique_ptr<RTCRtpSenderPlatform> sender,
String kind,
MediaStreamTrack* track,
- MediaStreamVector streams)
+ MediaStreamVector streams,
+ bool force_encoded_audio_insertable_streams,
+ bool force_encoded_video_insertable_streams)
: pc_(pc),
sender_(std::move(sender)),
kind_(std::move(kind)),
track_(track),
- streams_(std::move(streams)) {
+ streams_(std::move(streams)),
+ force_encoded_audio_insertable_streams_(
+ force_encoded_audio_insertable_streams && kind_ == "audio"),
+ force_encoded_video_insertable_streams_(
+ force_encoded_video_insertable_streams && kind_ == "video") {
DCHECK(pc_);
DCHECK(sender_);
DCHECK(!track || kind_ == track->kind());
+ DCHECK(!force_encoded_audio_insertable_streams_ ||
+ !force_encoded_video_insertable_streams_);
+ if (force_encoded_audio_insertable_streams_)
+ RegisterEncodedAudioStreamCallback();
+ if (force_encoded_video_insertable_streams_)
+ RegisterEncodedVideoStreamCallback();
}
MediaStreamTrack* RTCRtpSender::track() {
@@ -375,13 +442,28 @@ ScriptPromise RTCRtpSender::replaceTrack(ScriptState* script_state,
RTCRtpSendParameters* RTCRtpSender::getParameters() {
RTCRtpSendParameters* parameters = RTCRtpSendParameters::Create();
- // TODO(orphis): Forward missing fields from the WebRTC library:
- // degradationPreference
std::unique_ptr<webrtc::RtpParameters> webrtc_parameters =
sender_->GetParameters();
parameters->setTransactionId(webrtc_parameters->transaction_id.c_str());
+ if (webrtc_parameters->degradation_preference.has_value()) {
+ WTF::String degradation_preference_str;
+ switch (webrtc_parameters->degradation_preference.value()) {
+ case webrtc::DegradationPreference::MAINTAIN_FRAMERATE:
+ degradation_preference_str = "maintain-framerate";
+ break;
+ case webrtc::DegradationPreference::MAINTAIN_RESOLUTION:
+ degradation_preference_str = "maintain-resolution";
+ break;
+ case webrtc::DegradationPreference::BALANCED:
+ degradation_preference_str = "balanced";
+ break;
+ default:
+ NOTREACHED();
+ }
+ parameters->setDegradationPreference(degradation_preference_str);
+ }
RTCRtcpParameters* rtcp = RTCRtcpParameters::Create();
rtcp->setCname(webrtc_parameters->rtcp.cname.c_str());
rtcp->setReducedSize(webrtc_parameters->rtcp.reduced_size);
@@ -391,10 +473,10 @@ RTCRtpSendParameters* RTCRtpSender::getParameters() {
encodings.ReserveCapacity(
SafeCast<wtf_size_t>(webrtc_parameters->encodings.size()));
for (const auto& webrtc_encoding : webrtc_parameters->encodings) {
- // TODO(orphis): Forward missing fields from the WebRTC library:
- // codecPayloadType, dtx, ptime, maxFramerate, scaleResolutionDownBy.
RTCRtpEncodingParameters* encoding = RTCRtpEncodingParameters::Create();
- encoding->setRid(WebString::FromUTF8(webrtc_encoding.rid));
+ if (!webrtc_encoding.rid.empty()) {
+ encoding->setRid(String::FromUTF8(webrtc_encoding.rid));
+ }
encoding->setActive(webrtc_encoding.active);
if (webrtc_encoding.max_bitrate_bps) {
encoding->setMaxBitrate(webrtc_encoding.max_bitrate_bps.value());
@@ -403,10 +485,13 @@ RTCRtpSendParameters* RTCRtpSender::getParameters() {
encoding->setScaleResolutionDownBy(
webrtc_encoding.scale_resolution_down_by.value());
}
+ if (webrtc_encoding.max_framerate) {
+ encoding->setMaxFramerate(webrtc_encoding.max_framerate.value());
+ }
encoding->setPriority(
PriorityFromDouble(webrtc_encoding.bitrate_priority).c_str());
encoding->setNetworkPriority(
- PriorityFromDouble(webrtc_encoding.network_priority).c_str());
+ PriorityFromEnum(webrtc_encoding.network_priority).c_str());
if (webrtc_encoding.num_temporal_layers) {
if (*webrtc_encoding.num_temporal_layers == 2) {
encoding->setScalabilityMode("L1T2");
@@ -471,7 +556,7 @@ ScriptPromise RTCRtpSender::setParameters(
// native layer without having to transform all the other read-only
// parameters.
Vector<webrtc::RtpEncodingParameters> encodings;
- webrtc::DegradationPreference degradation_preference;
+ absl::optional<webrtc::DegradationPreference> degradation_preference;
std::tie(encodings, degradation_preference) = ToRtpParameters(parameters);
auto* request = MakeGarbageCollected<SetParametersRequest>(resolver, this);
@@ -552,13 +637,51 @@ void RTCRtpSender::setStreams(HeapVector<Member<MediaStream>> streams,
kOnlySupportedInUnifiedPlanMessage);
return;
}
- WebVector<WebString> stream_ids;
+ Vector<String> stream_ids;
for (auto stream : streams)
stream_ids.emplace_back(stream->id());
sender_->SetStreams(stream_ids);
}
-void RTCRtpSender::Trace(blink::Visitor* visitor) {
+RTCInsertableStreams* RTCRtpSender::createEncodedAudioStreams(
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
+ if (!force_encoded_audio_insertable_streams_) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "Encoded audio streams not requested at PC initialization");
+ return nullptr;
+ }
+ if (encoded_video_streams_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Encoded audio streams already created");
+ return nullptr;
+ }
+
+ InitializeEncodedAudioStreams(script_state);
+ return encoded_audio_streams_;
+}
+
+RTCInsertableStreams* RTCRtpSender::createEncodedVideoStreams(
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
+ if (!force_encoded_video_insertable_streams_) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "Encoded video streams not requested at PC initialization");
+ return nullptr;
+ }
+ if (encoded_video_streams_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Encoded video streams already created");
+ return nullptr;
+ }
+
+ InitializeEncodedVideoStreams(script_state);
+ return encoded_video_streams_;
+}
+
+void RTCRtpSender::Trace(Visitor* visitor) {
visitor->Trace(pc_);
visitor->Trace(track_);
visitor->Trace(transport_);
@@ -566,6 +689,13 @@ void RTCRtpSender::Trace(blink::Visitor* visitor) {
visitor->Trace(streams_);
visitor->Trace(last_returned_parameters_);
visitor->Trace(transceiver_);
+ visitor->Trace(audio_from_encoder_underlying_source_);
+ visitor->Trace(audio_to_packetizer_underlying_sink_);
+ visitor->Trace(encoded_video_streams_);
+ visitor->Trace(encoded_audio_streams_);
+ visitor->Trace(video_from_encoder_underlying_source_);
+ visitor->Trace(video_to_packetizer_underlying_sink_);
+ visitor->Trace(encoded_video_streams_);
ScriptWrappable::Trace(visitor);
}
@@ -580,7 +710,7 @@ RTCRtpCapabilities* RTCRtpSender::getCapabilities(const String& kind) {
std::unique_ptr<webrtc::RtpCapabilities> rtc_capabilities =
PeerConnectionDependencyFactory::GetInstance()->GetSenderCapabilities(
- kind.Utf8());
+ kind);
HeapVector<Member<RTCRtpCodecCapability>> codecs;
codecs.ReserveInitialCapacity(
@@ -625,4 +755,127 @@ RTCRtpCapabilities* RTCRtpSender::getCapabilities(const String& kind) {
return capabilities;
}
+void RTCRtpSender::RegisterEncodedAudioStreamCallback() {
+ DCHECK(!web_sender()
+ ->GetEncodedAudioStreamTransformer()
+ ->HasTransformerCallback());
+ DCHECK_EQ(kind_, "audio");
+ web_sender()->GetEncodedAudioStreamTransformer()->SetTransformerCallback(
+ WTF::BindRepeating(&RTCRtpSender::OnAudioFrameFromEncoder,
+ WrapWeakPersistent(this)));
+}
+
+void RTCRtpSender::UnregisterEncodedAudioStreamCallback() {
+ web_sender()->GetEncodedAudioStreamTransformer()->ResetTransformerCallback();
+}
+
+void RTCRtpSender::InitializeEncodedAudioStreams(ScriptState* script_state) {
+ DCHECK(!audio_from_encoder_underlying_source_);
+ DCHECK(!audio_to_packetizer_underlying_sink_);
+ DCHECK(!encoded_audio_streams_);
+ DCHECK(force_encoded_audio_insertable_streams_);
+
+ encoded_audio_streams_ = RTCInsertableStreams::Create();
+
+ // Set up readable stream.
+ audio_from_encoder_underlying_source_ =
+ MakeGarbageCollected<RTCEncodedAudioUnderlyingSource>(
+ script_state,
+ WTF::Bind(&RTCRtpSender::UnregisterEncodedAudioStreamCallback,
+ WrapWeakPersistent(this)),
+ /*is_receiver=*/false);
+ // The high water mark for the readable stream is set to 0 so that frames are
+ // removed from the queue right away, without introducing any buffering.
+ encoded_audio_streams_->setReadableStream(
+ ReadableStream::CreateWithCountQueueingStrategy(
+ script_state, audio_from_encoder_underlying_source_,
+ /*high_water_mark=*/0));
+
+ // Set up writable stream.
+ audio_to_packetizer_underlying_sink_ =
+ MakeGarbageCollected<RTCEncodedAudioUnderlyingSink>(
+ script_state,
+ WTF::BindRepeating(
+ [](RTCRtpSender* sender) -> RTCEncodedAudioStreamTransformer* {
+ return sender ? sender->web_sender()
+ ->GetEncodedAudioStreamTransformer()
+ : nullptr;
+ },
+ WrapWeakPersistent(this)));
+ // The high water mark for the stream is set to 1 so that the stream is
+ // ready to write, but without queuing frames.
+ encoded_audio_streams_->setWritableStream(
+ WritableStream::CreateWithCountQueueingStrategy(
+ script_state, audio_to_packetizer_underlying_sink_,
+ /*high_water_mark=*/1));
+}
+
+void RTCRtpSender::OnAudioFrameFromEncoder(
+ std::unique_ptr<webrtc::TransformableFrameInterface> frame) {
+ if (audio_from_encoder_underlying_source_) {
+ audio_from_encoder_underlying_source_->OnFrameFromSource(std::move(frame));
+ }
+}
+
+void RTCRtpSender::RegisterEncodedVideoStreamCallback() {
+ DCHECK(!web_sender()
+ ->GetEncodedVideoStreamTransformer()
+ ->HasTransformerCallback());
+ DCHECK_EQ(kind_, "video");
+ web_sender()->GetEncodedVideoStreamTransformer()->SetTransformerCallback(
+ WTF::BindRepeating(&RTCRtpSender::OnVideoFrameFromEncoder,
+ WrapWeakPersistent(this)));
+}
+
+void RTCRtpSender::UnregisterEncodedVideoStreamCallback() {
+ web_sender()->GetEncodedVideoStreamTransformer()->ResetTransformerCallback();
+}
+
+void RTCRtpSender::InitializeEncodedVideoStreams(ScriptState* script_state) {
+ DCHECK(!video_from_encoder_underlying_source_);
+ DCHECK(!video_to_packetizer_underlying_sink_);
+ DCHECK(!encoded_video_streams_);
+ DCHECK(force_encoded_video_insertable_streams_);
+
+ encoded_video_streams_ = RTCInsertableStreams::Create();
+
+ // Set up readable stream.
+ video_from_encoder_underlying_source_ =
+ MakeGarbageCollected<RTCEncodedVideoUnderlyingSource>(
+ script_state,
+ WTF::Bind(&RTCRtpSender::UnregisterEncodedVideoStreamCallback,
+ WrapWeakPersistent(this)));
+ // The high water mark for the readable stream is set to 0 so that frames are
+ // removed from the queue right away, without introducing any buffering.
+ encoded_video_streams_->setReadableStream(
+ ReadableStream::CreateWithCountQueueingStrategy(
+ script_state, video_from_encoder_underlying_source_,
+ /*high_water_mark=*/0));
+
+ // Set up writable stream.
+ video_to_packetizer_underlying_sink_ =
+ MakeGarbageCollected<RTCEncodedVideoUnderlyingSink>(
+ script_state,
+ WTF::BindRepeating(
+ [](RTCRtpSender* sender) -> RTCEncodedVideoStreamTransformer* {
+ return sender ? sender->web_sender()
+ ->GetEncodedVideoStreamTransformer()
+ : nullptr;
+ },
+ WrapWeakPersistent(this)));
+ // The high water mark for the stream is set to 1 so that the stream is
+ // ready to write, but without queuing frames.
+ encoded_video_streams_->setWritableStream(
+ WritableStream::CreateWithCountQueueingStrategy(
+ script_state, video_to_packetizer_underlying_sink_,
+ /*high_water_mark=*/1));
+}
+
+void RTCRtpSender::OnVideoFrameFromEncoder(
+ std::unique_ptr<webrtc::TransformableVideoFrameInterface> frame) {
+ if (video_from_encoder_underlying_source_) {
+ video_from_encoder_underlying_source_->OnFrameFromSource(std::move(frame));
+ }
+}
+
} // namespace blink
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 f9accd0ecfd..6f519f7e7a2 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
@@ -8,9 +8,9 @@
#include <memory>
#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/modules/mediastream/media_stream.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_encoding_parameters.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_send_parameters.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/member.h"
@@ -25,14 +25,20 @@ class ExceptionState;
class MediaStreamTrack;
class RTCDtlsTransport;
class RTCDTMFSender;
+class RTCEncodedAudioUnderlyingSink;
+class RTCEncodedAudioUnderlyingSource;
+class RTCEncodedVideoUnderlyingSink;
+class RTCEncodedVideoUnderlyingSource;
+class RTCInsertableStreams;
class RTCPeerConnection;
class RTCRtpCapabilities;
class RTCRtpTransceiver;
+class RTCInsertableStreams;
webrtc::RtpEncodingParameters ToRtpEncodingParameters(
const RTCRtpEncodingParameters*);
RTCRtpHeaderExtensionParameters* ToRtpHeaderExtensionParameters(
- const webrtc::RtpHeaderExtensionParameters& headers);
+ const webrtc::RtpExtension& headers);
RTCRtpCodecParameters* ToRtpCodecParameters(
const webrtc::RtpCodecParameters& codecs);
@@ -47,7 +53,9 @@ class RTCRtpSender final : public ScriptWrappable {
std::unique_ptr<RTCRtpSenderPlatform>,
String kind,
MediaStreamTrack*,
- MediaStreamVector streams);
+ MediaStreamVector streams,
+ bool force_encoded_audio_insertable_streams,
+ bool force_encoded_video_insertable_streams);
MediaStreamTrack* track();
RTCDtlsTransport* transport();
@@ -59,6 +67,10 @@ class RTCRtpSender final : public ScriptWrappable {
ScriptPromise setParameters(ScriptState*, const RTCRtpSendParameters*);
ScriptPromise getStats(ScriptState*);
void setStreams(HeapVector<Member<MediaStream>> streams, ExceptionState&);
+ RTCInsertableStreams* createEncodedAudioStreams(ScriptState*,
+ ExceptionState&);
+ RTCInsertableStreams* createEncodedVideoStreams(ScriptState*,
+ ExceptionState&);
RTCRtpSenderPlatform* web_sender();
// Sets the track. This must be called when the |RTCRtpSenderPlatform| has its
@@ -71,9 +83,21 @@ class RTCRtpSender final : public ScriptWrappable {
void set_transceiver(RTCRtpTransceiver*);
void set_transport(RTCDtlsTransport*);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
+ void RegisterEncodedAudioStreamCallback();
+ void UnregisterEncodedAudioStreamCallback();
+ void InitializeEncodedAudioStreams(ScriptState*);
+ void OnAudioFrameFromEncoder(
+ std::unique_ptr<webrtc::TransformableFrameInterface> frame);
+
+ void RegisterEncodedVideoStreamCallback();
+ void UnregisterEncodedVideoStreamCallback();
+ void InitializeEncodedVideoStreams(ScriptState*);
+ void OnVideoFrameFromEncoder(
+ std::unique_ptr<webrtc::TransformableVideoFrameInterface> frame);
+
Member<RTCPeerConnection> pc_;
std::unique_ptr<RTCRtpSenderPlatform> sender_;
// The spec says that "kind" should be looked up in transceiver, but keeping
@@ -85,6 +109,18 @@ class RTCRtpSender final : public ScriptWrappable {
MediaStreamVector streams_;
Member<RTCRtpSendParameters> last_returned_parameters_;
Member<RTCRtpTransceiver> transceiver_;
+
+ // Insertable Streams audio support
+ bool force_encoded_audio_insertable_streams_;
+ Member<RTCEncodedAudioUnderlyingSource> audio_from_encoder_underlying_source_;
+ Member<RTCEncodedAudioUnderlyingSink> audio_to_packetizer_underlying_sink_;
+ Member<RTCInsertableStreams> encoded_audio_streams_;
+
+ // Insertable Streams video support
+ bool force_encoded_video_insertable_streams_;
+ Member<RTCEncodedVideoUnderlyingSource> video_from_encoder_underlying_source_;
+ Member<RTCEncodedVideoUnderlyingSink> video_to_packetizer_underlying_sink_;
+ Member<RTCInsertableStreams> encoded_video_streams_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.idl
index 335e2e9465f..91f8b28af39 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.idl
@@ -6,14 +6,15 @@
[Exposed=Window]
interface RTCRtpSender {
readonly attribute MediaStreamTrack? track;
- [RuntimeEnabled=RTCDtlsTransport] readonly attribute RTCDtlsTransport? transport;
- [RuntimeEnabled=RTCDtlsTransport] readonly attribute RTCDtlsTransport? rtcpTransport;
+ readonly attribute RTCDtlsTransport? transport;
+ readonly attribute RTCDtlsTransport? rtcpTransport;
static RTCRtpCapabilities? getCapabilities(DOMString kind);
- [CallWith=ScriptState] Promise<void> setParameters(optional RTCRtpSendParameters parameters);
+ [CallWith=ScriptState] Promise<void> setParameters(optional RTCRtpSendParameters parameters = {});
RTCRtpSendParameters getParameters();
[Measure, CallWith=ScriptState] Promise<void> replaceTrack(MediaStreamTrack? withTrack);
[Measure] readonly attribute RTCDTMFSender? dtmf;
[Measure, RaisesException] void setStreams(MediaStream... streams);
[CallWith=ScriptState] Promise<RTCStatsReport> getStats();
- // TODO(hbos): Implement the rest of RTCRtpSender, https://crbug.com/700916.
+ [Measure, RuntimeEnabled=RTCInsertableStreams, CallWith=ScriptState, RaisesException] RTCInsertableStreams createEncodedAudioStreams();
+ [Measure, RuntimeEnabled=RTCInsertableStreams, CallWith=ScriptState, RaisesException] RTCInsertableStreams createEncodedVideoStreams();
};
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 28ca5724140..1fb0fe94920 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
@@ -7,13 +7,32 @@
#include <memory>
#include <utility>
-#include "base/bind.h"
#include "base/logging.h"
-#include "third_party/blink/public/platform/web_rtc_stats.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"
+#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/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/thread_safe_ref_counted.h"
+namespace WTF {
+
+template <>
+struct CrossThreadCopier<webrtc::RtpParameters>
+ : public CrossThreadCopierPassThrough<webrtc::RtpParameters> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+template <>
+struct CrossThreadCopier<webrtc::RTCError>
+ : public CrossThreadCopierPassThrough<webrtc::RTCError> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+} // namespace WTF
+
namespace blink {
namespace {
@@ -166,7 +185,9 @@ class RTCRtpSenderImpl::RTCRtpSenderInternal
RTCRtpSenderInternal(
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map,
- RtpSenderState state)
+ RtpSenderState state,
+ bool force_encoded_audio_insertable_streams,
+ bool force_encoded_video_insertable_streams)
: native_peer_connection_(std::move(native_peer_connection)),
track_map_(std::move(track_map)),
main_task_runner_(state.main_task_runner()),
@@ -175,6 +196,21 @@ class RTCRtpSenderImpl::RTCRtpSenderInternal
state_(std::move(state)) {
DCHECK(track_map_);
DCHECK(state_.is_initialized());
+ if (force_encoded_audio_insertable_streams &&
+ webrtc_sender_->media_type() == cricket::MEDIA_TYPE_AUDIO) {
+ encoded_audio_transformer_ =
+ std::make_unique<RTCEncodedAudioStreamTransformer>(main_task_runner_);
+ webrtc_sender_->SetEncoderToPacketizerFrameTransformer(
+ encoded_audio_transformer_->Delegate());
+ }
+ if (force_encoded_video_insertable_streams &&
+ webrtc_sender_->media_type() == cricket::MEDIA_TYPE_VIDEO) {
+ encoded_video_transformer_ =
+ std::make_unique<RTCEncodedVideoStreamTransformer>(main_task_runner_);
+ webrtc_sender_->SetEncoderToPacketizerFrameTransformer(
+ encoded_video_transformer_->Delegate());
+ }
+ DCHECK(!encoded_audio_transformer_ || !encoded_video_transformer_);
}
const RtpSenderState& state() const {
@@ -201,12 +237,13 @@ class RTCRtpSenderImpl::RTCRtpSenderInternal
track_ref = track_map_->GetOrCreateLocalTrackAdapter(with_track);
webrtc_track = track_ref->webrtc_track();
}
- signaling_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&RTCRtpSenderImpl::RTCRtpSenderInternal::
- ReplaceTrackOnSignalingThread,
- this, std::move(track_ref),
- base::Unretained(webrtc_track), std::move(callback)));
+ PostCrossThreadTask(
+ *signaling_task_runner_.get(), FROM_HERE,
+ CrossThreadBindOnce(&RTCRtpSenderImpl::RTCRtpSenderInternal::
+ ReplaceTrackOnSignalingThread,
+ WrapRefCounted(this), std::move(track_ref),
+ CrossThreadUnretained(webrtc_track),
+ CrossThreadBindOnce(std::move(callback))));
}
std::unique_ptr<blink::RtcDtmfSenderHandler> GetDtmfSender() const {
@@ -225,16 +262,17 @@ class RTCRtpSenderImpl::RTCRtpSenderInternal
return std::make_unique<webrtc::RtpParameters>(parameters_);
}
- void SetParameters(blink::WebVector<webrtc::RtpEncodingParameters> encodings,
- webrtc::DegradationPreference degradation_preference,
- base::OnceCallback<void(webrtc::RTCError)> callback) {
+ void SetParameters(
+ Vector<webrtc::RtpEncodingParameters> encodings,
+ absl::optional<webrtc::DegradationPreference> degradation_preference,
+ base::OnceCallback<void(webrtc::RTCError)> callback) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
webrtc::RtpParameters new_parameters = parameters_;
new_parameters.degradation_preference = degradation_preference;
- for (std::size_t i = 0; i < new_parameters.encodings.size(); ++i) {
+ for (WTF::wtf_size_t i = 0; i < new_parameters.encodings.size(); ++i) {
// Encodings have other parameters in the native layer that aren't exposed
// to the blink layer. So instead of copying the new struct over the old
// one, we copy the members one by one over the old struct, effectively
@@ -250,21 +288,22 @@ class RTCRtpSenderImpl::RTCRtpSenderInternal
encoding.scale_resolution_down_by;
}
- signaling_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&RTCRtpSenderImpl::RTCRtpSenderInternal::
- SetParametersOnSignalingThread,
- this, std::move(new_parameters), std::move(callback)));
+ PostCrossThreadTask(
+ *signaling_task_runner_.get(), FROM_HERE,
+ CrossThreadBindOnce(&RTCRtpSenderImpl::RTCRtpSenderInternal::
+ SetParametersOnSignalingThread,
+ WrapRefCounted(this), std::move(new_parameters),
+ CrossThreadBindOnce(std::move(callback))));
}
- void GetStats(
- blink::WebRTCStatsReportCallback callback,
- const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids) {
- signaling_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(
+ void GetStats(RTCStatsReportCallback callback,
+ const Vector<webrtc::NonStandardGroupId>& exposed_group_ids) {
+ PostCrossThreadTask(
+ *signaling_task_runner_.get(), FROM_HERE,
+ CrossThreadBindOnce(
&RTCRtpSenderImpl::RTCRtpSenderInternal::GetStatsOnSignalingThread,
- this, std::move(callback), exposed_group_ids));
+ WrapRefCounted(this), CrossThreadBindOnce(std::move(callback)),
+ exposed_group_ids));
}
bool RemoveFromPeerConnection(webrtc::PeerConnectionInterface* pc) {
@@ -279,12 +318,21 @@ class RTCRtpSenderImpl::RTCRtpSenderInternal
return true;
}
- void SetStreams(std::vector<std::string> stream_ids) {
+ void SetStreams(const Vector<String>& stream_ids) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
- signaling_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&RTCRtpSenderImpl::RTCRtpSenderInternal::
- SetStreamsOnSignalingThread,
- this, std::move(stream_ids)));
+ PostCrossThreadTask(
+ *signaling_task_runner_.get(), FROM_HERE,
+ CrossThreadBindOnce(&RTCRtpSenderImpl::RTCRtpSenderInternal::
+ SetStreamsOnSignalingThread,
+ WrapRefCounted(this), stream_ids));
+ }
+
+ RTCEncodedAudioStreamTransformer* GetEncodedAudioStreamTransformer() const {
+ return encoded_audio_transformer_.get();
+ }
+
+ RTCEncodedVideoStreamTransformer* GetEncodedVideoStreamTransformer() const {
+ return encoded_video_transformer_.get();
}
private:
@@ -300,61 +348,69 @@ class RTCRtpSenderImpl::RTCRtpSenderInternal
// |webrtc_track| is passed as an argument because |track_ref->webrtc_track()|
// cannot be accessed on the signaling thread. https://crbug.com/756436
void ReplaceTrackOnSignalingThread(
- std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
- track_ref,
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
webrtc::MediaStreamTrackInterface* webrtc_track,
- base::OnceCallback<void(bool)> callback) {
+ CrossThreadOnceFunction<void(bool)> callback) {
DCHECK(signaling_task_runner_->BelongsToCurrentThread());
bool result = webrtc_sender_->SetTrack(webrtc_track);
- main_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(
- &RTCRtpSenderImpl::RTCRtpSenderInternal::ReplaceTrackCallback, this,
- result, std::move(track_ref), std::move(callback)));
+ PostCrossThreadTask(
+ *main_task_runner_.get(), FROM_HERE,
+ CrossThreadBindOnce(
+ &RTCRtpSenderImpl::RTCRtpSenderInternal::ReplaceTrackCallback,
+ WrapRefCounted(this), result, std::move(track_ref),
+ std::move(callback)));
}
void ReplaceTrackCallback(
bool result,
std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
track_ref,
- base::OnceCallback<void(bool)> callback) {
+ CrossThreadOnceFunction<void(bool)> callback) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
if (result)
state_.set_track_ref(std::move(track_ref));
std::move(callback).Run(result);
}
+ using RTCStatsReportCallbackInternal =
+ CrossThreadOnceFunction<void(std::unique_ptr<RTCStatsReportPlatform>)>;
+
void GetStatsOnSignalingThread(
- blink::WebRTCStatsReportCallback callback,
- const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids) {
+ RTCStatsReportCallbackInternal callback,
+ const Vector<webrtc::NonStandardGroupId>& exposed_group_ids) {
native_peer_connection_->GetStats(
webrtc_sender_.get(),
- blink::CreateRTCStatsCollectorCallback(
- main_task_runner_, std::move(callback), exposed_group_ids));
+ CreateRTCStatsCollectorCallback(
+ main_task_runner_, ConvertToBaseOnceCallback(std::move(callback)),
+ exposed_group_ids));
}
void SetParametersOnSignalingThread(
webrtc::RtpParameters parameters,
- base::OnceCallback<void(webrtc::RTCError)> callback) {
+ CrossThreadOnceFunction<void(webrtc::RTCError)> callback) {
DCHECK(signaling_task_runner_->BelongsToCurrentThread());
webrtc::RTCError result = webrtc_sender_->SetParameters(parameters);
- main_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(
+ PostCrossThreadTask(
+ *main_task_runner_.get(), FROM_HERE,
+ CrossThreadBindOnce(
&RTCRtpSenderImpl::RTCRtpSenderInternal::SetParametersCallback,
- this, std::move(result), std::move(callback)));
+ WrapRefCounted(this), std::move(result), std::move(callback)));
}
void SetParametersCallback(
webrtc::RTCError result,
- base::OnceCallback<void(webrtc::RTCError)> callback) {
+ CrossThreadOnceFunction<void(webrtc::RTCError)> callback) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
std::move(callback).Run(std::move(result));
}
- void SetStreamsOnSignalingThread(std::vector<std::string> stream_ids) {
+ void SetStreamsOnSignalingThread(const Vector<String>& stream_ids) {
DCHECK(signaling_task_runner_->BelongsToCurrentThread());
- webrtc_sender_->SetStreams(stream_ids);
+ std::vector<std::string> ids;
+ for (auto stream_id : stream_ids)
+ ids.emplace_back(stream_id.Utf8());
+
+ webrtc_sender_->SetStreams(std::move(ids));
}
const scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection_;
@@ -365,6 +421,8 @@ class RTCRtpSenderImpl::RTCRtpSenderInternal
const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
const scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_;
const scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender_;
+ std::unique_ptr<RTCEncodedAudioStreamTransformer> encoded_audio_transformer_;
+ std::unique_ptr<RTCEncodedVideoStreamTransformer> encoded_video_transformer_;
RtpSenderState state_;
webrtc::RtpParameters parameters_;
};
@@ -374,11 +432,11 @@ struct RTCRtpSenderImpl::RTCRtpSenderInternalTraits {
// RTCRtpSenderInternal owns AdapterRefs which have to be destroyed on the
// main thread, this ensures delete always happens there.
if (!sender->main_task_runner_->BelongsToCurrentThread()) {
- sender->main_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(
+ PostCrossThreadTask(
+ *sender->main_task_runner_.get(), FROM_HERE,
+ CrossThreadBindOnce(
&RTCRtpSenderImpl::RTCRtpSenderInternalTraits::Destruct,
- base::Unretained(sender)));
+ CrossThreadUnretained(sender)));
return;
}
delete sender;
@@ -393,11 +451,15 @@ uintptr_t RTCRtpSenderImpl::getId(
RTCRtpSenderImpl::RTCRtpSenderImpl(
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map,
- RtpSenderState state)
+ RtpSenderState state,
+ bool force_encoded_audio_insertable_streams,
+ bool force_encoded_video_insertable_streams)
: internal_(base::MakeRefCounted<RTCRtpSenderInternal>(
std::move(native_peer_connection),
std::move(track_map),
- std::move(state))) {}
+ std::move(state),
+ force_encoded_audio_insertable_streams,
+ force_encoded_video_insertable_streams)) {}
RTCRtpSenderImpl::RTCRtpSenderImpl(const RTCRtpSenderImpl& other)
: internal_(other.internal_) {}
@@ -440,12 +502,13 @@ blink::WebMediaStreamTrack RTCRtpSenderImpl::Track() const {
return track_ref ? track_ref->web_track() : blink::WebMediaStreamTrack();
}
-blink::WebVector<blink::WebString> RTCRtpSenderImpl::StreamIds() const {
+Vector<String> RTCRtpSenderImpl::StreamIds() const {
const auto& stream_ids = internal_->state().stream_ids();
- blink::WebVector<blink::WebString> web_stream_ids(stream_ids.size());
- for (size_t i = 0; i < stream_ids.size(); ++i)
- web_stream_ids[i] = blink::WebString::FromUTF8(stream_ids[i]);
- return web_stream_ids;
+ Vector<String> wtf_stream_ids(
+ static_cast<WTF::wtf_size_t>(stream_ids.size()));
+ for (WTF::wtf_size_t i = 0; i < stream_ids.size(); ++i)
+ wtf_stream_ids[i] = String::FromUTF8(stream_ids[i]);
+ return wtf_stream_ids;
}
void RTCRtpSenderImpl::ReplaceTrack(blink::WebMediaStreamTrack with_track,
@@ -465,8 +528,8 @@ std::unique_ptr<webrtc::RtpParameters> RTCRtpSenderImpl::GetParameters() const {
}
void RTCRtpSenderImpl::SetParameters(
- blink::WebVector<webrtc::RtpEncodingParameters> encodings,
- webrtc::DegradationPreference degradation_preference,
+ Vector<webrtc::RtpEncodingParameters> encodings,
+ absl::optional<webrtc::DegradationPreference> degradation_preference,
blink::RTCVoidRequest* request) {
internal_->SetParameters(
std::move(encodings), degradation_preference,
@@ -474,18 +537,13 @@ void RTCRtpSenderImpl::SetParameters(
}
void RTCRtpSenderImpl::GetStats(
- blink::WebRTCStatsReportCallback callback,
- const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids) {
+ RTCStatsReportCallback callback,
+ const Vector<webrtc::NonStandardGroupId>& exposed_group_ids) {
internal_->GetStats(std::move(callback), exposed_group_ids);
}
-void RTCRtpSenderImpl::SetStreams(
- const blink::WebVector<blink::WebString>& stream_ids) {
- std::vector<std::string> ids;
- for (auto stream_id : stream_ids)
- ids.emplace_back(stream_id.Utf8());
-
- internal_->SetStreams(std::move(ids));
+void RTCRtpSenderImpl::SetStreams(const Vector<String>& stream_ids) {
+ internal_->SetStreams(stream_ids);
}
void RTCRtpSenderImpl::ReplaceTrack(blink::WebMediaStreamTrack with_track,
@@ -498,6 +556,16 @@ bool RTCRtpSenderImpl::RemoveFromPeerConnection(
return internal_->RemoveFromPeerConnection(pc);
}
+RTCEncodedAudioStreamTransformer*
+RTCRtpSenderImpl::GetEncodedAudioStreamTransformer() const {
+ return internal_->GetEncodedAudioStreamTransformer();
+}
+
+RTCEncodedVideoStreamTransformer*
+RTCRtpSenderImpl::GetEncodedVideoStreamTransformer() const {
+ return internal_->GetEncodedVideoStreamTransformer();
+}
+
RTCRtpSenderOnlyTransceiver::RTCRtpSenderOnlyTransceiver(
std::unique_ptr<blink::RTCRtpSenderPlatform> sender)
: sender_(std::move(sender)) {
@@ -516,9 +584,9 @@ uintptr_t RTCRtpSenderOnlyTransceiver::Id() const {
return 0u;
}
-blink::WebString RTCRtpSenderOnlyTransceiver::Mid() const {
+String RTCRtpSenderOnlyTransceiver::Mid() const {
NOTIMPLEMENTED();
- return blink::WebString();
+ return String();
}
std::unique_ptr<blink::RTCRtpSenderPlatform>
@@ -560,7 +628,7 @@ RTCRtpSenderOnlyTransceiver::FiredDirection() const {
}
webrtc::RTCError RTCRtpSenderOnlyTransceiver::SetCodecPreferences(
- blink::WebVector<webrtc::RtpCodecCapability>) {
+ Vector<webrtc::RtpCodecCapability>) {
NOTIMPLEMENTED();
return {};
}
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 06f8583454e..7ea211799b2 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
@@ -12,17 +12,20 @@
#include "base/callback.h"
#include "base/single_thread_task_runner.h"
#include "third_party/blink/public/platform/web_media_stream_track.h"
-#include "third_party/blink/public/platform/web_rtc_stats.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_sender_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
#include "third_party/webrtc/api/peer_connection_interface.h"
#include "third_party/webrtc/api/rtp_sender_interface.h"
#include "third_party/webrtc/api/scoped_refptr.h"
namespace blink {
+class RTCEncodedAudioStreamTransformer;
+class RTCEncodedVideoStreamTransformer;
+
// This class represents the state of a sender; a snapshot of what a
// webrtc-layer sender looked like when it was inspected on the signaling thread
// such that this information can be moved to the main thread in a single
@@ -120,7 +123,9 @@ class MODULES_EXPORT RTCRtpSenderImpl : public blink::RTCRtpSenderPlatform {
RTCRtpSenderImpl(
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map,
- RtpSenderState state);
+ RtpSenderState state,
+ bool force_encoded_audio_insertable_streams,
+ bool force_encoded_video_insertable_streams);
RTCRtpSenderImpl(const RTCRtpSenderImpl& other);
~RTCRtpSenderImpl() override;
RTCRtpSenderImpl& operator=(const RTCRtpSenderImpl& other);
@@ -134,18 +139,21 @@ class MODULES_EXPORT RTCRtpSenderImpl : public blink::RTCRtpSenderPlatform {
rtc::scoped_refptr<webrtc::DtlsTransportInterface> DtlsTransport() override;
webrtc::DtlsTransportInformation DtlsTransportInformation() override;
blink::WebMediaStreamTrack Track() const override;
- blink::WebVector<blink::WebString> StreamIds() const override;
+ Vector<String> StreamIds() const override;
void ReplaceTrack(blink::WebMediaStreamTrack with_track,
blink::RTCVoidRequest* request) override;
std::unique_ptr<blink::RtcDtmfSenderHandler> GetDtmfSender() const override;
std::unique_ptr<webrtc::RtpParameters> GetParameters() const override;
- void SetParameters(blink::WebVector<webrtc::RtpEncodingParameters>,
- webrtc::DegradationPreference,
+ void SetParameters(Vector<webrtc::RtpEncodingParameters>,
+ absl::optional<webrtc::DegradationPreference>,
blink::RTCVoidRequest*) override;
- void GetStats(blink::WebRTCStatsReportCallback,
- const blink::WebVector<webrtc::NonStandardGroupId>&) override;
- void SetStreams(
- const blink::WebVector<blink::WebString>& stream_ids) override;
+ void GetStats(RTCStatsReportCallback,
+ const Vector<webrtc::NonStandardGroupId>&) override;
+ void SetStreams(const Vector<String>& stream_ids) override;
+ RTCEncodedAudioStreamTransformer* GetEncodedAudioStreamTransformer()
+ const override;
+ RTCEncodedVideoStreamTransformer* GetEncodedVideoStreamTransformer()
+ const override;
// The ReplaceTrack() that takes a blink::RTCVoidRequest is implemented on
// top of this, which returns the result in a callback instead. Allows doing
@@ -172,7 +180,7 @@ class MODULES_EXPORT RTCRtpSenderOnlyTransceiver
RTCRtpTransceiverPlatformImplementationType ImplementationType()
const override;
uintptr_t Id() const override;
- WebString Mid() const override;
+ String Mid() const override;
std::unique_ptr<RTCRtpSenderPlatform> Sender() const override;
std::unique_ptr<RTCRtpReceiverPlatform> Receiver() const override;
bool Stopped() const override;
@@ -183,7 +191,7 @@ class MODULES_EXPORT RTCRtpSenderOnlyTransceiver
base::Optional<webrtc::RtpTransceiverDirection> FiredDirection()
const override;
webrtc::RTCError SetCodecPreferences(
- blink::WebVector<webrtc::RtpCodecCapability>) override;
+ Vector<webrtc::RtpCodecCapability>) override;
private:
std::unique_ptr<blink::RTCRtpSenderPlatform> sender_;
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 292a515b191..3c60c478ba5 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
@@ -7,6 +7,7 @@
#include <memory>
#include "base/bind.h"
+#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
@@ -15,7 +16,6 @@
#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_rtc_stats.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"
@@ -96,7 +96,9 @@ class RTCRtpSenderImplTest : public ::testing::Test {
std::vector<std::string>());
sender_state.Initialize();
return std::make_unique<RTCRtpSenderImpl>(
- peer_connection_.get(), track_map_, std::move(sender_state));
+ peer_connection_.get(), track_map_, std::move(sender_state),
+ /*force_encoded_audio_insertable_streams=*/false,
+ /*force_encoded_video_insertable_streams=*/false);
}
// Calls replaceTrack(), which is asynchronous, returning a callback that when
@@ -109,9 +111,10 @@ class RTCRtpSenderImplTest : public ::testing::Test {
// On complete, |*result_holder| is set with the result of replaceTrack()
// and the |run_loop| quit.
sender_->ReplaceTrack(
- web_track, base::BindOnce(&RTCRtpSenderImplTest::CallbackOnComplete,
- base::Unretained(this), result_holder.get(),
- run_loop.get()));
+ web_track,
+ WTF::Bind(&RTCRtpSenderImplTest::CallbackOnComplete,
+ WTF::Unretained(this), WTF::Unretained(result_holder.get()),
+ WTF::Unretained(run_loop.get())));
// When the resulting callback is invoked, waits for |run_loop| to complete
// and returns |*result_holder|.
return base::BindOnce(&RTCRtpSenderImplTest::RunLoopAndReturnResult,
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 ce9377a6ebd..0dae6df2457 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
@@ -28,6 +28,9 @@ String TransceiverDirectionToString(
return "recvonly";
case webrtc::RtpTransceiverDirection::kInactive:
return "inactive";
+ default:
+ NOTREACHED();
+ return String();
}
}
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 3ee9a756a90..a5ca5da2c5f 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
@@ -6,8 +6,8 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_RTP_TRANSCEIVER_H_
#include "base/optional.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_codec_capability.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_init.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/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"
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.idl
index 7b7ef2c2d99..5fdb8270163 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.idl
@@ -7,7 +7,8 @@ enum RTCRtpTransceiverDirection {
"sendrecv",
"sendonly",
"recvonly",
- "inactive"
+ "inactive",
+ "stopped"
};
// https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl.cc
index f968ff671ae..e06c15d7ef1 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl.cc
@@ -186,15 +186,21 @@ class RTCRtpTransceiverImpl::RTCRtpTransceiverInternal
RTCRtpTransceiverInternal(
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map,
- RtpTransceiverState state)
+ RtpTransceiverState state,
+ bool force_encoded_audio_insertable_streams,
+ bool force_encoded_video_insertable_streams)
: main_task_runner_(state.main_task_runner()),
signaling_task_runner_(state.signaling_task_runner()),
webrtc_transceiver_(state.webrtc_transceiver()),
state_(std::move(state)) {
sender_ = std::make_unique<blink::RTCRtpSenderImpl>(
- native_peer_connection, track_map, state_.MoveSenderState());
+ native_peer_connection, track_map, state_.MoveSenderState(),
+ force_encoded_audio_insertable_streams,
+ force_encoded_video_insertable_streams);
receiver_ = std::make_unique<blink::RTCRtpReceiverImpl>(
- native_peer_connection, state_.MoveReceiverState());
+ native_peer_connection, state_.MoveReceiverState(),
+ force_encoded_audio_insertable_streams,
+ force_encoded_video_insertable_streams);
}
const RtpTransceiverState& state() const {
@@ -297,11 +303,15 @@ uintptr_t RTCRtpTransceiverImpl::GetId(
RTCRtpTransceiverImpl::RTCRtpTransceiverImpl(
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map,
- RtpTransceiverState transceiver_state)
+ RtpTransceiverState transceiver_state,
+ bool force_encoded_audio_insertable_streams,
+ bool force_encoded_video_insertable_streams)
: internal_(base::MakeRefCounted<RTCRtpTransceiverInternal>(
std::move(native_peer_connection),
std::move(track_map),
- std::move(transceiver_state))) {}
+ std::move(transceiver_state),
+ force_encoded_audio_insertable_streams,
+ force_encoded_video_insertable_streams)) {}
RTCRtpTransceiverImpl::RTCRtpTransceiverImpl(const RTCRtpTransceiverImpl& other)
: internal_(other.internal_) {}
@@ -345,13 +355,12 @@ uintptr_t RTCRtpTransceiverImpl::Id() const {
return GetId(internal_->state().webrtc_transceiver().get());
}
-blink::WebString RTCRtpTransceiverImpl::Mid() const {
+String RTCRtpTransceiverImpl::Mid() const {
const auto& mid = internal_->state().mid();
- return mid ? blink::WebString::FromUTF8(*mid)
- : blink::WebString(); // IsNull()
+ return mid ? String::FromUTF8(*mid) : String();
}
-void RTCRtpTransceiverImpl::SetMid(base::Optional<blink::WebString> mid) {
+void RTCRtpTransceiverImpl::SetMid(base::Optional<String> mid) {
internal_->set_mid(mid ? base::Optional<std::string>(mid->Utf8())
: base::nullopt);
}
@@ -390,7 +399,11 @@ RTCRtpTransceiverImpl::FiredDirection() const {
}
webrtc::RTCError RTCRtpTransceiverImpl::SetCodecPreferences(
- blink::WebVector<webrtc::RtpCodecCapability> codec_preferences) {
- return internal_->setCodecPreferences(codec_preferences.ReleaseVector());
+ Vector<webrtc::RtpCodecCapability> codec_preferences) {
+ std::vector<webrtc::RtpCodecCapability> std_codec_preferences(
+ codec_preferences.size());
+ std::move(codec_preferences.begin(), codec_preferences.end(),
+ std_codec_preferences.begin());
+ return internal_->setCodecPreferences(std_codec_preferences);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl.h
index fb14757608c..24921befc65 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl.h
@@ -152,7 +152,9 @@ class MODULES_EXPORT RTCRtpTransceiverImpl : public RTCRtpTransceiverPlatform {
RTCRtpTransceiverImpl(
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map,
- RtpTransceiverState state);
+ RtpTransceiverState state,
+ bool force_encoded_audio_insertable_streams,
+ bool force_encoded_video_insertable_streams);
RTCRtpTransceiverImpl(const RTCRtpTransceiverImpl& other);
~RTCRtpTransceiverImpl() override;
@@ -168,8 +170,8 @@ class MODULES_EXPORT RTCRtpTransceiverImpl : public RTCRtpTransceiverPlatform {
RTCRtpTransceiverPlatformImplementationType ImplementationType()
const override;
uintptr_t Id() const override;
- blink::WebString Mid() const override;
- void SetMid(base::Optional<blink::WebString>) override;
+ String Mid() const override;
+ void SetMid(base::Optional<String>) override;
std::unique_ptr<RTCRtpSenderPlatform> Sender() const override;
std::unique_ptr<RTCRtpReceiverPlatform> Receiver() const override;
bool Stopped() const override;
@@ -180,7 +182,7 @@ class MODULES_EXPORT RTCRtpTransceiverImpl : public RTCRtpTransceiverPlatform {
base::Optional<webrtc::RtpTransceiverDirection> FiredDirection()
const override;
webrtc::RTCError SetCodecPreferences(
- blink::WebVector<webrtc::RtpCodecCapability>) override;
+ Vector<webrtc::RtpCodecCapability>) override;
private:
class RTCRtpTransceiverInternal;
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 746060a93c8..a3cb3bf78dc 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
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/logging.h"
+#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/optional.h"
#include "base/run_loop.h"
@@ -253,8 +254,10 @@ TEST_F(RTCRtpTransceiverImplTest, CreateTranceiver) {
EXPECT_FALSE(transceiver_state.is_initialized());
transceiver_state.Initialize();
- RTCRtpTransceiverImpl transceiver(peer_connection_.get(), track_map_,
- std::move(transceiver_state));
+ RTCRtpTransceiverImpl transceiver(
+ peer_connection_.get(), track_map_, std::move(transceiver_state),
+ /*force_encoded_audio_insertable_streams=*/false,
+ /*force_encoded_video_insertable_streams=*/false);
EXPECT_TRUE(transceiver.Mid().IsNull());
EXPECT_TRUE(transceiver.Sender());
EXPECT_TRUE(transceiver.Receiver());
@@ -285,10 +288,10 @@ TEST_F(RTCRtpTransceiverImplTest, ModifyTransceiver) {
// Modify the webrtc transceiver and create a new state object for the
// modified state.
- *webrtc_transceiver =
+ webrtc_transceiver->ReplaceWith(
*CreateWebRtcTransceiver(webrtc_sender, webrtc_receiver, "MidyMacMidface",
true, webrtc::RtpTransceiverDirection::kInactive,
- webrtc::RtpTransceiverDirection::kSendRecv);
+ webrtc::RtpTransceiverDirection::kSendRecv));
RtpTransceiverState modified_transceiver_state =
CreateTransceiverState(webrtc_transceiver, local_track_adapter->Copy(),
remote_track_adapter->Copy());
@@ -297,8 +300,10 @@ TEST_F(RTCRtpTransceiverImplTest, ModifyTransceiver) {
// Modifying the webrtc transceiver after the initial state was created should
// not have affected the transceiver state.
- RTCRtpTransceiverImpl transceiver(peer_connection_.get(), track_map_,
- std::move(initial_transceiver_state));
+ RTCRtpTransceiverImpl transceiver(
+ peer_connection_.get(), track_map_, std::move(initial_transceiver_state),
+ /*force_encoded_audio_insertable_streams=*/false,
+ /*force_encoded_video_insertable_streams=*/false);
EXPECT_TRUE(transceiver.Mid().IsNull());
EXPECT_TRUE(transceiver.Sender());
EXPECT_TRUE(transceiver.Receiver());
@@ -342,7 +347,9 @@ TEST_F(RTCRtpTransceiverImplTest, ShallowCopy) {
EXPECT_FALSE(transceiver_state.is_initialized());
transceiver_state.Initialize();
transceiver.reset(new RTCRtpTransceiverImpl(
- peer_connection_.get(), track_map_, std::move(transceiver_state)));
+ peer_connection_.get(), track_map_, std::move(transceiver_state),
+ /*force_encoded_audio_insertable_streams=*/false,
+ /*force_encoded_video_insertable_streams=*/false));
}
DCHECK(transceiver);
EXPECT_FALSE(transceiver->Stopped());
@@ -353,9 +360,9 @@ TEST_F(RTCRtpTransceiverImplTest, ShallowCopy) {
// shared internal state.
{
// Modify webrtc transceiver to be stopped.
- *webrtc_transceiver = *CreateWebRtcTransceiver(
+ webrtc_transceiver->ReplaceWith(*CreateWebRtcTransceiver(
webrtc_sender, webrtc_receiver, base::nullopt, true /* stopped */,
- webrtc::RtpTransceiverDirection::kSendRecv, base::nullopt);
+ webrtc::RtpTransceiverDirection::kSendRecv, base::nullopt));
RtpTransceiverState transceiver_state =
CreateTransceiverState(webrtc_transceiver, local_track_adapter->Copy(),
remote_track_adapter->Copy());
@@ -390,10 +397,10 @@ TEST_F(RTCRtpTransceiverImplTest, TransceiverStateUpdateModeSetDescription) {
// Modify the webrtc transceiver and create a new state object for the
// modified state.
webrtc_sender->SetTrack(nullptr);
- *webrtc_transceiver =
+ webrtc_transceiver->ReplaceWith(
*CreateWebRtcTransceiver(webrtc_sender, webrtc_receiver, "MidyMacMidface",
true, webrtc::RtpTransceiverDirection::kInactive,
- webrtc::RtpTransceiverDirection::kSendRecv);
+ webrtc::RtpTransceiverDirection::kSendRecv));
RtpTransceiverState modified_transceiver_state =
CreateTransceiverState(webrtc_transceiver, local_track_adapter->Copy(),
remote_track_adapter->Copy());
@@ -401,8 +408,10 @@ TEST_F(RTCRtpTransceiverImplTest, TransceiverStateUpdateModeSetDescription) {
modified_transceiver_state.Initialize();
// Construct a transceiver from the initial state.
- RTCRtpTransceiverImpl transceiver(peer_connection_.get(), track_map_,
- std::move(initial_transceiver_state));
+ RTCRtpTransceiverImpl transceiver(
+ peer_connection_.get(), track_map_, std::move(initial_transceiver_state),
+ /*force_encoded_audio_insertable_streams=*/false,
+ /*force_encoded_video_insertable_streams=*/false);
// Setting the state with TransceiverStateUpdateMode::kSetDescription should
// make the transceiver state up-to-date, except leaving
// "transceiver.direction" and "transceiver.sender.track" unmodified.
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 fd6762b3db6..760a5e9b0c0 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
@@ -55,7 +55,7 @@ std::unique_ptr<SctpTransportProxy> CreateProxy(
scoped_refptr<base::SingleThreadTaskRunner> worker_thread) {
DCHECK(main_thread);
DCHECK(worker_thread);
- LocalFrame* frame = To<Document>(context)->GetFrame();
+ LocalFrame* frame = Document::From(context)->GetFrame();
DCHECK(frame);
return SctpTransportProxy::Create(*frame, main_thread, worker_thread,
native_transport, delegate);
@@ -68,7 +68,7 @@ RTCSctpTransport::RTCSctpTransport(
rtc::scoped_refptr<webrtc::SctpTransportInterface> native_transport)
: RTCSctpTransport(context,
native_transport,
- To<Document>(context)->GetFrame()->GetTaskRunner(
+ Document::From(context)->GetFrame()->GetTaskRunner(
TaskType::kNetworking),
PeerConnectionDependencyFactory::GetInstance()
->GetWebRtcWorkerTaskRunner()) {}
@@ -78,7 +78,7 @@ RTCSctpTransport::RTCSctpTransport(
rtc::scoped_refptr<webrtc::SctpTransportInterface> native_transport,
scoped_refptr<base::SingleThreadTaskRunner> main_thread,
scoped_refptr<base::SingleThreadTaskRunner> worker_thread)
- : ContextClient(context),
+ : ExecutionContextClient(context),
current_state_(webrtc::SctpTransportState::kNew),
native_transport_(native_transport),
proxy_(CreateProxy(context,
@@ -106,6 +106,12 @@ double RTCSctpTransport::maxMessageSize() const {
return std::numeric_limits<double>::infinity();
}
+base::Optional<int16_t> RTCSctpTransport::maxChannels() const {
+ if (!current_state_.MaxChannels())
+ return base::nullopt;
+ return current_state_.MaxChannels().value();
+}
+
int16_t RTCSctpTransport::maxChannels(bool& isNull) const {
if (!current_state_.MaxChannels()) {
isNull = true;
@@ -163,13 +169,13 @@ const AtomicString& RTCSctpTransport::InterfaceName() const {
}
ExecutionContext* RTCSctpTransport::GetExecutionContext() const {
- return ContextClient::GetExecutionContext();
+ return ExecutionContextClient::GetExecutionContext();
}
void RTCSctpTransport::Trace(Visitor* visitor) {
visitor->Trace(dtls_transport_);
EventTargetWithInlineData::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
SctpTransportProxy::Delegate::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 2ecee068c95..dcc71c72cfd 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
@@ -8,7 +8,7 @@
#include <memory>
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#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/peerconnection/adapters/sctp_transport_proxy.h"
#include "third_party/webrtc/api/scoped_refptr.h"
@@ -24,7 +24,7 @@ enum class RTCSctpTransportState { kChecking, kConnected, kClosed };
// Blink bindings for the RTCSctpTransport JavaScript object.
class MODULES_EXPORT RTCSctpTransport final
: public EventTargetWithInlineData,
- public ContextClient,
+ public ExecutionContextClient,
public SctpTransportProxy::Delegate {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(RTCSctpTransport);
@@ -45,7 +45,9 @@ class MODULES_EXPORT RTCSctpTransport final
RTCDtlsTransport* transport() const;
String state() const;
double maxMessageSize() const;
- int16_t maxChannels(bool& is_null) const;
+ base::Optional<int16_t> maxChannels() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ int16_t maxChannels(bool& is_null) const; // DEPRECATED
DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange, kStatechange)
@@ -63,7 +65,7 @@ class MODULES_EXPORT RTCSctpTransport final
// Called from owning RtcPeerConnection when it is closed.
void Close();
// For garbage collection.
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
webrtc::SctpTransportInformation current_state_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.idl
index d8d84d655d6..fd8fa35b609 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.idl
@@ -12,8 +12,7 @@ enum RTCSctpTransportState {
// http://w3c.github.io/webrtc-pc/#rtcdtlstransport-interface
[
- Exposed=Window,
- RuntimeEnabled=RTCSctpTransport
+ Exposed=Window
] interface RTCSctpTransport : EventTarget {
readonly attribute RTCDtlsTransport transport;
readonly attribute RTCSctpTransportState 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 c9bd2b192ef..d745c55d479 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
@@ -32,9 +32,9 @@
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_session_description_init.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/modules/peerconnection/rtc_session_description_init.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
namespace blink {
@@ -95,7 +95,7 @@ RTCSessionDescriptionPlatform* RTCSessionDescription::WebSessionDescription() {
return platform_session_description_;
}
-void RTCSessionDescription::Trace(blink::Visitor* visitor) {
+void RTCSessionDescription::Trace(Visitor* visitor) {
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 16be9f4bb38..f0171ec1fb1 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<RTCSessionDescriptionPlatform> platform_session_description_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description.idl
index 425dc9a8c52..2a5b2d41511 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description.idl
@@ -38,10 +38,9 @@ enum RTCSdpType {
};
[
- Constructor(optional RTCSessionDescriptionInit descriptionInitDict),
- ConstructorCallWith=ExecutionContext,
Exposed=Window
] interface RTCSessionDescription {
+ [CallWith=ExecutionContext] constructor(optional RTCSessionDescriptionInit descriptionInitDict = {});
// TODO(foolip): |type| and |sdp| should be readonly and not nullable.
// https://crbug.com/662898
[Measure] attribute RTCSdpType? type;
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 15c81c8bf79..13ff0641076 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
@@ -55,7 +55,7 @@ RTCSessionDescriptionRequestImpl::RTCSessionDescriptionRequestImpl(
RTCPeerConnection* requester,
V8RTCSessionDescriptionCallback* success_callback,
V8RTCPeerConnectionErrorCallback* error_callback)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
operation_(operation),
success_callback_(success_callback),
error_callback_(error_callback),
@@ -90,7 +90,7 @@ void RTCSessionDescriptionRequestImpl::RequestFailed(
Clear();
}
-void RTCSessionDescriptionRequestImpl::ContextDestroyed(ExecutionContext*) {
+void RTCSessionDescriptionRequestImpl::ContextDestroyed() {
Clear();
}
@@ -100,12 +100,12 @@ void RTCSessionDescriptionRequestImpl::Clear() {
requester_.Clear();
}
-void RTCSessionDescriptionRequestImpl::Trace(blink::Visitor* visitor) {
+void RTCSessionDescriptionRequestImpl::Trace(Visitor* visitor) {
visitor->Trace(success_callback_);
visitor->Trace(error_callback_);
visitor->Trace(requester_);
RTCSessionDescriptionRequest::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 31292880688..de4b1f9dc12 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
@@ -34,7 +34,7 @@
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_peer_connection_error_callback.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_session_description_callback.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_session_description_enums.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_session_description_request.h"
@@ -49,7 +49,7 @@ class RTCSessionDescriptionPlatform;
// shared code as to not repeat the majority of the implementations.
class RTCSessionDescriptionRequestImpl final
: public RTCSessionDescriptionRequest,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(RTCSessionDescriptionRequestImpl);
public:
@@ -70,10 +70,10 @@ class RTCSessionDescriptionRequestImpl final
void RequestSucceeded(RTCSessionDescriptionPlatform*) override;
void RequestFailed(const webrtc::RTCError& error) override;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 973c6b398b3..638ad1029c8 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(blink::Visitor* visitor) {
+void RTCSessionDescriptionRequestPromiseImpl::Trace(Visitor* visitor) {
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 961007093d6..3413844cf87 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void Clear();
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc
index 3efe7ebf0c9..8dd8c3506a4 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc
@@ -23,18 +23,11 @@ v8::Local<v8::Value> RTCStatsToValue(ScriptState* script_state,
builder.AddNumber("timestamp", stats->Timestamp());
builder.AddString("type", stats->GetType());
- auto add_vector = [&builder](const WebString& name, auto web_vector) {
- Vector<typename decltype(web_vector)::value_type> vector(
- SafeCast<wtf_size_t>(web_vector.size()));
- std::move(web_vector.begin(), web_vector.end(), vector.begin());
- builder.Add(name, vector);
- };
-
for (size_t i = 0; i < stats->MembersCount(); ++i) {
std::unique_ptr<RTCStatsMember> member = stats->GetMember(i);
if (!member->IsDefined())
continue;
- WebString name = member->GetName();
+ String name = member->GetName();
switch (member->GetType()) {
case webrtc::RTCStatsMemberInterface::kBool:
builder.AddBoolean(name, member->ValueBool());
@@ -58,29 +51,26 @@ v8::Local<v8::Value> RTCStatsToValue(ScriptState* script_state,
builder.AddString(name, member->ValueString());
break;
case webrtc::RTCStatsMemberInterface::kSequenceBool: {
- WebVector<int> sequence = member->ValueSequenceBool();
- Vector<bool> vector(SafeCast<wtf_size_t>(sequence.size()));
- std::copy(sequence.begin(), sequence.end(), vector.begin());
- builder.Add(name, vector);
+ builder.Add(name, member->ValueSequenceBool());
break;
}
case webrtc::RTCStatsMemberInterface::kSequenceInt32:
- add_vector(name, member->ValueSequenceInt32());
+ builder.Add(name, member->ValueSequenceInt32());
break;
case webrtc::RTCStatsMemberInterface::kSequenceUint32:
- add_vector(name, member->ValueSequenceUint32());
+ builder.Add(name, member->ValueSequenceUint32());
break;
case webrtc::RTCStatsMemberInterface::kSequenceInt64:
- add_vector(name, member->ValueSequenceInt64());
+ builder.Add(name, member->ValueSequenceInt64());
break;
case webrtc::RTCStatsMemberInterface::kSequenceUint64:
- add_vector(name, member->ValueSequenceUint64());
+ builder.Add(name, member->ValueSequenceUint64());
break;
case webrtc::RTCStatsMemberInterface::kSequenceDouble:
- add_vector(name, member->ValueSequenceDouble());
+ builder.Add(name, member->ValueSequenceDouble());
break;
case webrtc::RTCStatsMemberInterface::kSequenceString:
- add_vector(name, member->ValueSequenceString());
+ builder.Add(name, member->ValueSequenceString());
break;
default:
NOTREACHED();
@@ -119,11 +109,11 @@ class RTCStatsReportIterationSource final
} // namespace
-WebVector<webrtc::NonStandardGroupId> GetExposedGroupIds(
+Vector<webrtc::NonStandardGroupId> GetExposedGroupIds(
const ScriptState* script_state) {
const ExecutionContext* context = ExecutionContext::From(script_state);
DCHECK(context->IsContextThread());
- WebVector<webrtc::NonStandardGroupId> enabled_origin_trials;
+ Vector<webrtc::NonStandardGroupId> enabled_origin_trials;
if (RuntimeEnabledFeatures::RtcAudioJitterBufferMaxPacketsEnabled(context)) {
enabled_origin_trials.emplace_back(
webrtc::NonStandardGroupId::kRtcAudioJitterBufferMaxPackets);
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.h
index cd5eeb33767..fe7e8048be8 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.h
@@ -5,11 +5,11 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_STATS_REPORT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_STATS_REPORT_H_
-#include "third_party/blink/public/platform/web_rtc_stats.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/renderer/bindings/core/v8/maplike.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/webrtc/api/stats/rtc_stats.h"
@@ -17,7 +17,7 @@ namespace blink {
// Returns the group ids for non-standardized members which should be exposed
// based on what Origin Trials are running.
-WebVector<webrtc::NonStandardGroupId> GetExposedGroupIds(
+Vector<webrtc::NonStandardGroupId> GetExposedGroupIds(
const ScriptState* script_state);
// https://w3c.github.io/webrtc-pc/#rtcstatsreport-object
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 42cab2fe4db..785932a3d1e 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
@@ -33,7 +33,7 @@ RTCStatsRequestImpl::RTCStatsRequestImpl(ExecutionContext* context,
RTCPeerConnection* requester,
V8RTCStatsCallback* callback,
MediaStreamTrack* selector)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
success_callback_(callback),
component_(selector ? selector->Component() : nullptr),
requester_(requester) {
@@ -64,7 +64,7 @@ void RTCStatsRequestImpl::RequestSucceeded(RTCStatsResponseBase* response) {
Clear();
}
-void RTCStatsRequestImpl::ContextDestroyed(ExecutionContext*) {
+void RTCStatsRequestImpl::ContextDestroyed() {
Clear();
}
@@ -73,12 +73,12 @@ void RTCStatsRequestImpl::Clear() {
requester_.Clear();
}
-void RTCStatsRequestImpl::Trace(blink::Visitor* visitor) {
+void RTCStatsRequestImpl::Trace(Visitor* visitor) {
visitor->Trace(success_callback_);
visitor->Trace(component_);
visitor->Trace(requester_);
RTCStatsRequest::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 12132d446c2..031c5444dc6 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
@@ -26,7 +26,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_STATS_REQUEST_IMPL_H_
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_stats_callback.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_stats_response.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_stats_request.h"
@@ -39,7 +39,7 @@ class MediaStreamTrack;
class RTCPeerConnection;
class RTCStatsRequestImpl final : public RTCStatsRequest,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(RTCStatsRequestImpl);
public:
@@ -55,10 +55,10 @@ class RTCStatsRequestImpl final : public RTCStatsRequest,
void RequestSucceeded(RTCStatsResponseBase*) override;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 3717e5c6773..1945e076953 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(blink::Visitor* visitor) {
+void RTCStatsResponse::Trace(Visitor* visitor) {
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 2687a9e82e5..39a8eebfc6c 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
HeapVector<Member<RTCLegacyStatsReport>> result_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.idl
index 21222987985..92bc2034602 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.idl
@@ -27,6 +27,6 @@
NoInterfaceObject
] interface RTCStatsResponse {
sequence<RTCLegacyStatsReport> result();
- RTCLegacyStatsReport namedItem([DefaultValue=Undefined] optional DOMString name);
+ RTCLegacyStatsReport namedItem(optional DOMString name = "undefined");
[NotEnumerable, ImplementedAs=namedItem] getter RTCLegacyStatsReport (DOMString name);
};
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 83aa2cb595e..e3268c654f4 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
@@ -4,11 +4,11 @@
#include "third_party/blink/renderer/modules/peerconnection/rtc_track_event.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_track_event_init.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_track.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.h"
-#include "third_party/blink/renderer/modules/peerconnection/rtc_track_event_init.h"
namespace blink {
@@ -57,7 +57,7 @@ RTCRtpTransceiver* RTCTrackEvent::transceiver() const {
return transceiver_;
}
-void RTCTrackEvent::Trace(blink::Visitor* visitor) {
+void RTCTrackEvent::Trace(Visitor* visitor) {
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 dc39e9b29fe..cdcd99aa374 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<RTCRtpReceiver> receiver_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_track_event.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_track_event.idl
index 5c55b025712..eaefdc255e8 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_track_event.idl
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_track_event.idl
@@ -4,9 +4,9 @@
// https://w3c.github.io/webrtc-pc/#rtctrackevent
[
- Constructor(DOMString type, RTCTrackEventInit eventInitDict),
Exposed=Window
] interface RTCTrackEvent : Event {
+ constructor(DOMString type, RTCTrackEventInit eventInitDict);
readonly attribute RTCRtpReceiver receiver;
readonly attribute MediaStreamTrack track;
[SameObject]
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 13a8144c09c..eb55fd9d5d8 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
@@ -42,7 +42,7 @@ RTCVoidRequestImpl::RTCVoidRequestImpl(
RTCPeerConnection* requester,
V8VoidFunction* success_callback,
V8RTCPeerConnectionErrorCallback* error_callback)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
operation_(std::move(operation)),
success_callback_(success_callback),
error_callback_(error_callback),
@@ -77,7 +77,7 @@ void RTCVoidRequestImpl::RequestFailed(const webrtc::RTCError& error) {
Clear();
}
-void RTCVoidRequestImpl::ContextDestroyed(ExecutionContext*) {
+void RTCVoidRequestImpl::ContextDestroyed() {
Clear();
}
@@ -87,12 +87,12 @@ void RTCVoidRequestImpl::Clear() {
requester_.Clear();
}
-void RTCVoidRequestImpl::Trace(blink::Visitor* visitor) {
+void RTCVoidRequestImpl::Trace(Visitor* visitor) {
visitor->Trace(success_callback_);
visitor->Trace(error_callback_);
visitor->Trace(requester_);
RTCVoidRequest::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 96af311c4ae..7455d4cfcca 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
@@ -34,7 +34,7 @@
#include "base/optional.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_void_function.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_peer_connection_error_callback.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_session_description_enums.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_void_request.h"
@@ -47,7 +47,7 @@ class RTCPeerConnection;
// into separate request implementations and find a way to consolidate the
// shared code as to not repeat the majority of the implementations.
class RTCVoidRequestImpl final : public RTCVoidRequest,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(RTCVoidRequestImpl);
public:
@@ -62,10 +62,10 @@ class RTCVoidRequestImpl final : public RTCVoidRequest,
void RequestSucceeded() override;
void RequestFailed(const webrtc::RTCError&) override;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 dd3b6b8db6e..1443e2e415c 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(blink::Visitor* visitor) {
+void RTCVoidRequestPromiseImpl::Trace(Visitor* visitor) {
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 5c85a85f9fc..2a2b1af02f6 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 946fb97cb7e..e8f22ed0f28 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(blink::Visitor* visitor) {
+void RTCVoidRequestScriptPromiseResolverImpl::Trace(Visitor* visitor) {
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 eca84459151..3d02337262c 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
Member<ScriptPromiseResolver> resolver_;
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.cc b/chromium/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.cc
index 9d78cded867..18d63d57a57 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.cc
@@ -14,7 +14,7 @@ TestWebRTCStatsReportObtainer::TestWebRTCStatsReportObtainer() {}
TestWebRTCStatsReportObtainer::~TestWebRTCStatsReportObtainer() {}
-blink::WebRTCStatsReportCallback
+RTCStatsReportCallback
TestWebRTCStatsReportObtainer::GetStatsCallbackWrapper() {
return base::BindOnce(&TestWebRTCStatsReportObtainer::OnStatsDelivered, this);
}
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.h b/chromium/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.h
index 9d376e05f27..2738a7f7ff2 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.h
@@ -8,7 +8,7 @@
#include <memory>
#include "base/run_loop.h"
-#include "third_party/blink/public/platform/web_rtc_stats.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
namespace blink {
@@ -25,7 +25,7 @@ class TestWebRTCStatsReportObtainer
public:
TestWebRTCStatsReportObtainer();
- blink::WebRTCStatsReportCallback GetStatsCallbackWrapper();
+ RTCStatsReportCallback GetStatsCallbackWrapper();
RTCStatsReportPlatform* report() const;
RTCStatsReportPlatform* WaitForReport();
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer.h b/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer.h
index 46f6c3e36ce..5ffde75e8be 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer.h
@@ -5,10 +5,10 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_TRANSCEIVER_STATE_SURFACER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_TRANSCEIVER_STATE_SURFACER_H_
-#include "third_party/blink/public/platform/web_rtc_peer_connection_handler_client.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl.h"
#include "third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_client.h"
#include "third_party/webrtc/api/rtp_transceiver_interface.h"
#include "third_party/webrtc/api/sctp_transport_interface.h"
#include "third_party/webrtc/rtc_base/ref_count.h"
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 51c0ea5049d..d70aefb00fa 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
@@ -8,6 +8,7 @@
#include <tuple>
#include "base/bind.h"
+#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.h b/chromium/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.h
index 8aa110b4409..99b018b5f90 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.h
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.h
@@ -7,9 +7,9 @@
#include <memory>
-#include "third_party/blink/public/platform/web_rtc_stats.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_stats_report.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_audio_renderer_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_audio_renderer_test.cc
index a34dec28b03..af0afc2d479 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_audio_renderer_test.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_audio_renderer_test.cc
@@ -56,7 +56,7 @@ class MockAudioRendererSource : public blink::WebRtcAudioRendererSource {
base::TimeDelta* current_time));
MOCK_METHOD1(RemoveAudioRenderer, void(blink::WebRtcAudioRenderer* renderer));
MOCK_METHOD0(AudioRendererThreadStopped, void());
- MOCK_METHOD1(SetOutputDeviceForAec, void(const std::string&));
+ MOCK_METHOD1(SetOutputDeviceForAec, void(const String&));
MOCK_CONST_METHOD0(GetAudioProcessingId, base::UnguessableToken());
};
@@ -128,10 +128,10 @@ class WebRtcAudioRendererTest : public testing::Test {
.WillRepeatedly(Return(*kAudioProcessingId));
}
- void SetupRenderer(const std::string& device_id) {
+ void SetupRenderer(const String& device_id) {
renderer_ = new blink::WebRtcAudioRenderer(
blink::scheduler::GetSingleThreadTaskRunnerForTesting(), stream_,
- nullptr, base::UnguessableToken::Create(), device_id);
+ nullptr, base::UnguessableToken::Create(), device_id.Utf8());
media::AudioSinkParameters params;
EXPECT_CALL(
@@ -140,7 +140,7 @@ class WebRtcAudioRendererTest : public testing::Test {
nullptr /*blink::WebLocalFrame*/, _))
.Times(testing::AtLeast(1))
.WillRepeatedly(DoAll(SaveArg<2>(&params), InvokeWithoutArgs([&]() {
- EXPECT_EQ(params.device_id, device_id);
+ EXPECT_EQ(params.device_id, device_id.Utf8());
})));
EXPECT_CALL(*source_.get(), SetOutputDeviceForAec(device_id));
@@ -294,7 +294,8 @@ TEST_F(WebRtcAudioRendererTest, SwitchOutputDevice) {
MockNewAudioRendererSink(blink::WebAudioDeviceSourceType::kWebRtc, _, _))
.WillOnce(SaveArg<2>(&params));
EXPECT_CALL(*source_.get(), AudioRendererThreadStopped());
- EXPECT_CALL(*source_.get(), SetOutputDeviceForAec(kOtherOutputDeviceId));
+ EXPECT_CALL(*source_.get(),
+ SetOutputDeviceForAec(String::FromUTF8(kOtherOutputDeviceId)));
EXPECT_CALL(*this, MockSwitchDeviceCallback(media::OUTPUT_DEVICE_STATUS_OK));
base::RunLoop loop;
renderer_proxy_->SwitchOutputDevice(
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 dcd91b4e28a..6ec834173ca 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
@@ -4,11 +4,22 @@
#include "third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.h"
-#include "base/bind.h"
-#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.h"
+#include "base/strings/stringprintf.h"
+#include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h"
#include "third_party/blink/renderer/modules/mediastream/processed_local_audio_source.h"
#include "third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.h"
#include "third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.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"
+
+namespace {
+
+void SendLogMessage(const std::string& message) {
+ blink::WebRtcLogMessage("WRMSTA::" + message);
+}
+
+} // namespace
namespace blink {
@@ -81,10 +92,10 @@ WebRtcMediaStreamTrackAdapter::~WebRtcMediaStreamTrackAdapter() {
void WebRtcMediaStreamTrackAdapterTraits::Destruct(
const WebRtcMediaStreamTrackAdapter* adapter) {
if (!adapter->main_thread_->BelongsToCurrentThread()) {
- adapter->main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(&WebRtcMediaStreamTrackAdapterTraits::Destruct,
- base::Unretained(adapter)));
+ PostCrossThreadTask(
+ *adapter->main_thread_.get(), FROM_HERE,
+ CrossThreadBindOnce(&WebRtcMediaStreamTrackAdapterTraits::Destruct,
+ CrossThreadUnretained(adapter)));
return;
}
delete adapter;
@@ -155,6 +166,8 @@ void WebRtcMediaStreamTrackAdapter::InitializeLocalAudioTrack(
DCHECK(!web_track.IsNull());
DCHECK_EQ(web_track.Source().GetType(),
blink::WebMediaStreamSource::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_);
@@ -208,6 +221,8 @@ void WebRtcMediaStreamTrackAdapter::InitializeRemoteAudioTrack(
DCHECK(webrtc_audio_track);
DCHECK_EQ(webrtc_audio_track->kind(),
webrtc::MediaStreamTrackInterface::kAudioKind);
+ SendLogMessage(
+ base::StringPrintf("InitializeRemoteAudioTrack([this=%p])", this));
remote_audio_track_adapter_ =
base::MakeRefCounted<blink::RemoteAudioTrackAdapter>(
main_thread_, webrtc_audio_track.get());
@@ -218,11 +233,11 @@ void WebRtcMediaStreamTrackAdapter::InitializeRemoteAudioTrack(
// http://crbug.com/810848
webrtc_audio_track->GetSource()->SetVolume(0);
remote_track_can_complete_initialization_.Signal();
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(&WebRtcMediaStreamTrackAdapter::
- FinalizeRemoteTrackInitializationOnMainThread,
- this));
+ PostCrossThreadTask(
+ *main_thread_.get(), FROM_HERE,
+ CrossThreadBindOnce(&WebRtcMediaStreamTrackAdapter::
+ FinalizeRemoteTrackInitializationOnMainThread,
+ WrapRefCounted(this)));
}
void WebRtcMediaStreamTrackAdapter::InitializeRemoteVideoTrack(
@@ -236,11 +251,11 @@ void WebRtcMediaStreamTrackAdapter::InitializeRemoteVideoTrack(
main_thread_, webrtc_video_track.get());
webrtc_track_ = webrtc_video_track;
remote_track_can_complete_initialization_.Signal();
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(&WebRtcMediaStreamTrackAdapter::
- FinalizeRemoteTrackInitializationOnMainThread,
- this));
+ PostCrossThreadTask(
+ *main_thread_.get(), FROM_HERE,
+ CrossThreadBindOnce(&WebRtcMediaStreamTrackAdapter::
+ FinalizeRemoteTrackInitializationOnMainThread,
+ WrapRefCounted(this)));
}
void WebRtcMediaStreamTrackAdapter::
@@ -300,11 +315,12 @@ void WebRtcMediaStreamTrackAdapter::DisposeRemoteAudioTrack() {
DCHECK(remote_audio_track_adapter_);
DCHECK_EQ(web_track_.Source().GetType(),
blink::WebMediaStreamSource::kTypeAudio);
- factory_->GetWebRtcSignalingTaskRunner()->PostTask(
- FROM_HERE,
- base::BindOnce(&WebRtcMediaStreamTrackAdapter::
- UnregisterRemoteAudioTrackAdapterOnSignalingThread,
- this));
+ PostCrossThreadTask(
+ *factory_->GetWebRtcSignalingTaskRunner().get(), FROM_HERE,
+ CrossThreadBindOnce(
+ &WebRtcMediaStreamTrackAdapter::
+ UnregisterRemoteAudioTrackAdapterOnSignalingThread,
+ WrapRefCounted(this)));
}
void WebRtcMediaStreamTrackAdapter::DisposeRemoteVideoTrack() {
@@ -320,10 +336,11 @@ void WebRtcMediaStreamTrackAdapter::
DCHECK(!main_thread_->BelongsToCurrentThread());
DCHECK(remote_audio_track_adapter_);
remote_audio_track_adapter_->Unregister();
- main_thread_->PostTask(
- FROM_HERE, base::BindOnce(&WebRtcMediaStreamTrackAdapter::
- FinalizeRemoteTrackDisposingOnMainThread,
- this));
+ PostCrossThreadTask(
+ *main_thread_.get(), FROM_HERE,
+ CrossThreadBindOnce(&WebRtcMediaStreamTrackAdapter::
+ FinalizeRemoteTrackDisposingOnMainThread,
+ WrapRefCounted(this)));
}
void WebRtcMediaStreamTrackAdapter::FinalizeRemoteTrackDisposingOnMainThread() {
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 2f75f4ed56a..36cab7da739 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
@@ -7,6 +7,7 @@
#include <utility>
#include "base/bind.h"
+#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h"
#include "third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h"
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 c6e4ac847e7..b1f4af0d59f 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
@@ -7,10 +7,11 @@
#include <memory>
#include "base/bind.h"
+#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
-#include "base/test/bind_test_util.h"
+#include "base/test/scoped_run_loop_timeout.h"
#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"
@@ -261,11 +262,7 @@ class WebRtcMediaStreamTrackAdapterMapStressTest
: public WebRtcMediaStreamTrackAdapterMapTest {
public:
WebRtcMediaStreamTrackAdapterMapStressTest()
- : WebRtcMediaStreamTrackAdapterMapTest(),
- increased_run_timeout_(
- TestTimeouts::action_max_timeout(),
- base::MakeExpectedNotRunClosure(FROM_HERE,
- "RunLoop::Run() timed out.")) {}
+ : increased_run_timeout_(FROM_HERE, TestTimeouts::action_max_timeout()) {}
void RunStressTest(size_t iterations) {
base::RunLoop run_loop;
@@ -344,7 +341,7 @@ class WebRtcMediaStreamTrackAdapterMapStressTest
private:
// TODO(https://crbug.com/1002761): Fix this test to run in < action_timeout()
// on slower bots (e.g. Debug, ASAN, etc).
- const base::RunLoop::ScopedRunTimeoutForTest increased_run_timeout_;
+ const base::test::ScopedRunLoopTimeout increased_run_timeout_;
size_t remaining_iterations_;
};
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 d49bee021a0..18ea868fdcf 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
@@ -7,6 +7,7 @@
#include <memory>
#include "base/bind.h"
+#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_set_description_observer_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_set_description_observer_test.cc
index dac6d6d3f52..1d81066605a 100644
--- a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_set_description_observer_test.cc
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_set_description_observer_test.cc
@@ -9,6 +9,7 @@
#include <vector>
#include "base/bind.h"
+#include "base/memory/ptr_util.h"
#include "base/optional.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
@@ -481,7 +482,7 @@ TEST_P(WebRtcSetDescriptionObserverHandlerTest,
}
INSTANTIATE_TEST_SUITE_P(
- /* no prefix */,
+ All,
WebRtcSetDescriptionObserverHandlerTest,
::testing::Values(std::make_tuple(ObserverHandlerType::kLocal,
StateSurfacerType::kTransceivers),
diff --git a/chromium/third_party/blink/renderer/modules/permissions/clipboard_permission_descriptor.idl b/chromium/third_party/blink/renderer/modules/permissions/clipboard_permission_descriptor.idl
index b351a623b7a..6476bfca274 100644
--- a/chromium/third_party/blink/renderer/modules/permissions/clipboard_permission_descriptor.idl
+++ b/chromium/third_party/blink/renderer/modules/permissions/clipboard_permission_descriptor.idl
@@ -4,4 +4,7 @@
dictionary ClipboardPermissionDescriptor : PermissionDescriptor {
boolean allowWithoutGesture = false;
+ // TODO(https://crbug.com/1026088): Update Clipboard Specification to
+ // include allowWithoutSanitization in the PermissionDescriptor.
+ boolean allowWithoutSanitization = false;
};
diff --git a/chromium/third_party/blink/renderer/modules/permissions/idls.gni b/chromium/third_party/blink/renderer/modules/permissions/idls.gni
new file mode 100644
index 00000000000..b4435525e53
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/permissions/idls.gni
@@ -0,0 +1,23 @@
+# 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 = [
+ "permission_status.idl",
+ "permissions.idl",
+]
+
+modules_dictionary_idl_files = [
+ "clipboard_permission_descriptor.idl",
+ "midi_permission_descriptor.idl",
+ "permission_descriptor.idl",
+ "push_permission_descriptor.idl",
+ "wake_lock_permission_descriptor.idl",
+]
+
+modules_dependency_idl_files = [
+ "navigator_permissions.idl",
+ "worker_navigator_permissions.idl",
+]
+
+modules_testing_dependency_idl_files = [ "testing/internals_permission.idl" ]
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 e477dc3b0e5..566c3cf60bf 100644
--- a/chromium/third_party/blink/renderer/modules/permissions/navigator_permissions.cc
+++ b/chromium/third_party/blink/renderer/modules/permissions/navigator_permissions.cc
@@ -33,7 +33,7 @@ Permissions* NavigatorPermissions::permissions(Navigator& navigator) {
return self.permissions_.Get();
}
-void NavigatorPermissions::Trace(blink::Visitor* visitor) {
+void NavigatorPermissions::Trace(Visitor* visitor) {
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 651603a3bff..434c43a0a52 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<Permissions> permissions_;
diff --git a/chromium/third_party/blink/renderer/modules/permissions/permission_descriptor.idl b/chromium/third_party/blink/renderer/modules/permissions/permission_descriptor.idl
index 44ab79319af..323fd1179f8 100644
--- a/chromium/third_party/blink/renderer/modules/permissions/permission_descriptor.idl
+++ b/chromium/third_party/blink/renderer/modules/permissions/permission_descriptor.idl
@@ -31,6 +31,7 @@ enum PermissionName {
"payment-handler",
"idle-detection",
"periodic-background-sync",
+ "storage-access",
};
// The PermissionDescriptor dictionary is a base to describe permissions. Some
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 a39645fdb05..172da74d95f 100644
--- a/chromium/third_party/blink/renderer/modules/permissions/permission_status.cc
+++ b/chromium/third_party/blink/renderer/modules/permissions/permission_status.cc
@@ -37,7 +37,7 @@ PermissionStatus* PermissionStatus::CreateAndListen(
PermissionStatus::PermissionStatus(ExecutionContext* execution_context,
MojoPermissionStatus status,
MojoPermissionDescriptor descriptor)
- : ContextLifecycleStateObserver(execution_context),
+ : ExecutionContextLifecycleStateObserver(execution_context),
status_(status),
descriptor_(std::move(descriptor)) {}
@@ -52,7 +52,7 @@ const AtomicString& PermissionStatus::InterfaceName() const {
}
ExecutionContext* PermissionStatus::GetExecutionContext() const {
- return ContextLifecycleStateObserver::GetExecutionContext();
+ return ExecutionContextLifecycleStateObserver::GetExecutionContext();
}
bool PermissionStatus::HasPendingActivity() const {
@@ -67,7 +67,7 @@ void PermissionStatus::ContextLifecycleStateChanged(
StopListening();
}
-void PermissionStatus::ContextDestroyed(ExecutionContext*) {
+void PermissionStatus::ContextDestroyed() {
StopListening();
}
@@ -101,9 +101,9 @@ void PermissionStatus::OnPermissionStatusChange(MojoPermissionStatus status) {
DispatchEvent(*Event::Create(event_type_names::kChange));
}
-void PermissionStatus::Trace(blink::Visitor* visitor) {
+void PermissionStatus::Trace(Visitor* visitor) {
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleStateObserver::Trace(visitor);
+ ExecutionContextLifecycleStateObserver::Trace(visitor);
}
} // namespace blink
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 6a12afad3f4..99b96f0b8f7 100644
--- a/chromium/third_party/blink/renderer/modules/permissions/permission_status.h
+++ b/chromium/third_party/blink/renderer/modules/permissions/permission_status.h
@@ -9,7 +9,7 @@
#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/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -23,7 +23,7 @@ class ScriptPromiseResolver;
// ExecutionContext.
class PermissionStatus final : public EventTargetWithInlineData,
public ActiveScriptWrappable<PermissionStatus>,
- public ContextLifecycleStateObserver,
+ public ExecutionContextLifecycleStateObserver,
public mojom::blink::PermissionObserver {
USING_GARBAGE_COLLECTED_MIXIN(PermissionStatus);
DEFINE_WRAPPERTYPEINFO();
@@ -54,15 +54,15 @@ class PermissionStatus final : public EventTargetWithInlineData,
// ScriptWrappable implementation.
bool HasPendingActivity() const final;
- // ContextLifecycleStateObserver implementation.
+ // ExecutionContextLifecycleStateObserver implementation.
void ContextLifecycleStateChanged(mojom::FrameLifecycleState) override;
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
String state() const;
DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange)
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 e03c047d0eb..2c0fb546ceb 100644
--- a/chromium/third_party/blink/renderer/modules/permissions/permission_utils.cc
+++ b/chromium/third_party/blink/renderer/modules/permissions/permission_utils.cc
@@ -7,11 +7,21 @@
#include <utility>
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
+#include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_clipboard_permission_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_midi_permission_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_permission_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_push_permission_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_wake_lock_permission_descriptor.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_frame.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/core/workers/worker_thread.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/wtf/text/wtf_string.h"
namespace blink {
@@ -60,10 +70,11 @@ PermissionDescriptorPtr CreateMidiPermissionDescriptor(bool sysex) {
PermissionDescriptorPtr CreateClipboardPermissionDescriptor(
PermissionName name,
- bool allow_without_gesture) {
+ bool allow_without_gesture,
+ bool allow_without_sanitization) {
auto descriptor = CreatePermissionDescriptor(name);
- auto clipboard_extension =
- mojom::blink::ClipboardPermissionDescriptor::New(allow_without_gesture);
+ auto clipboard_extension = mojom::blink::ClipboardPermissionDescriptor::New(
+ allow_without_gesture, allow_without_sanitization);
descriptor->extension = mojom::blink::PermissionDescriptorExtension::New();
descriptor->extension->set_clipboard(std::move(clipboard_extension));
return descriptor;
@@ -80,4 +91,137 @@ PermissionDescriptorPtr CreateWakeLockPermissionDescriptor(
return descriptor;
}
+PermissionDescriptorPtr ParsePermissionDescriptor(
+ ScriptState* script_state,
+ const ScriptValue& raw_descriptor,
+ ExceptionState& exception_state) {
+ PermissionDescriptor* permission =
+ NativeValueTraits<PermissionDescriptor>::NativeValue(
+ script_state->GetIsolate(), raw_descriptor.V8Value(),
+ exception_state);
+
+ if (exception_state.HadException())
+ return nullptr;
+
+ const String& name = permission->name();
+ if (name == "geolocation")
+ return CreatePermissionDescriptor(PermissionName::GEOLOCATION);
+ if (name == "camera")
+ return CreatePermissionDescriptor(PermissionName::VIDEO_CAPTURE);
+ if (name == "microphone")
+ return CreatePermissionDescriptor(PermissionName::AUDIO_CAPTURE);
+ if (name == "notifications")
+ return CreatePermissionDescriptor(PermissionName::NOTIFICATIONS);
+ if (name == "persistent-storage")
+ return CreatePermissionDescriptor(PermissionName::DURABLE_STORAGE);
+ if (name == "push") {
+ PushPermissionDescriptor* push_permission =
+ NativeValueTraits<PushPermissionDescriptor>::NativeValue(
+ script_state->GetIsolate(), raw_descriptor.V8Value(),
+ exception_state);
+ if (exception_state.HadException())
+ return nullptr;
+
+ // Only "userVisibleOnly" push is supported for now.
+ if (!push_permission->userVisibleOnly()) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotSupportedError,
+ "Push Permission without userVisibleOnly:true isn't supported yet.");
+ return nullptr;
+ }
+
+ return CreatePermissionDescriptor(PermissionName::NOTIFICATIONS);
+ }
+ if (name == "midi") {
+ MidiPermissionDescriptor* midi_permission =
+ NativeValueTraits<MidiPermissionDescriptor>::NativeValue(
+ script_state->GetIsolate(), raw_descriptor.V8Value(),
+ exception_state);
+ return CreateMidiPermissionDescriptor(midi_permission->sysex());
+ }
+ if (name == "background-sync")
+ return CreatePermissionDescriptor(PermissionName::BACKGROUND_SYNC);
+ if (name == "ambient-light-sensor" || name == "accelerometer" ||
+ name == "gyroscope" || name == "magnetometer") {
+ // ALS requires an extra flag.
+ if (name == "ambient-light-sensor") {
+ if (!RuntimeEnabledFeatures::SensorExtraClassesEnabled()) {
+ exception_state.ThrowTypeError(
+ "GenericSensorExtraClasses flag is not enabled.");
+ return nullptr;
+ }
+ }
+
+ return CreatePermissionDescriptor(PermissionName::SENSORS);
+ }
+ if (name == "accessibility-events") {
+ if (!RuntimeEnabledFeatures::AccessibilityObjectModelEnabled()) {
+ exception_state.ThrowTypeError(
+ "Accessibility Object Model is not enabled.");
+ return nullptr;
+ }
+ return CreatePermissionDescriptor(PermissionName::ACCESSIBILITY_EVENTS);
+ }
+ if (name == "clipboard-read" || name == "clipboard-write") {
+ PermissionName permission_name = PermissionName::CLIPBOARD_READ;
+ if (name == "clipboard-write")
+ permission_name = PermissionName::CLIPBOARD_WRITE;
+
+ ClipboardPermissionDescriptor* clipboard_permission =
+ NativeValueTraits<ClipboardPermissionDescriptor>::NativeValue(
+ script_state->GetIsolate(), raw_descriptor.V8Value(),
+ exception_state);
+ return CreateClipboardPermissionDescriptor(
+ permission_name, clipboard_permission->allowWithoutGesture(),
+ clipboard_permission->allowWithoutSanitization());
+ }
+ if (name == "payment-handler")
+ return CreatePermissionDescriptor(PermissionName::PAYMENT_HANDLER);
+ if (name == "background-fetch")
+ return CreatePermissionDescriptor(PermissionName::BACKGROUND_FETCH);
+ if (name == "idle-detection")
+ return CreatePermissionDescriptor(PermissionName::IDLE_DETECTION);
+ if (name == "periodic-background-sync")
+ return CreatePermissionDescriptor(PermissionName::PERIODIC_BACKGROUND_SYNC);
+ if (name == "wake-lock") {
+ if (!RuntimeEnabledFeatures::WakeLockEnabled(
+ ExecutionContext::From(script_state))) {
+ exception_state.ThrowTypeError("Wake Lock is not enabled.");
+ return nullptr;
+ }
+ WakeLockPermissionDescriptor* wake_lock_permission =
+ NativeValueTraits<WakeLockPermissionDescriptor>::NativeValue(
+ script_state->GetIsolate(), raw_descriptor.V8Value(),
+ exception_state);
+ if (exception_state.HadException())
+ return nullptr;
+ const String& type = wake_lock_permission->type();
+ if (type == "screen") {
+ return CreateWakeLockPermissionDescriptor(
+ mojom::blink::WakeLockType::kScreen);
+ } else if (type == "system") {
+ return CreateWakeLockPermissionDescriptor(
+ mojom::blink::WakeLockType::kSystem);
+ } else {
+ NOTREACHED();
+ }
+ }
+ if (name == "nfc") {
+ if (!RuntimeEnabledFeatures::WebNFCEnabled(
+ ExecutionContext::From(script_state))) {
+ exception_state.ThrowTypeError("Web NFC is not enabled.");
+ return nullptr;
+ }
+ return CreatePermissionDescriptor(PermissionName::NFC);
+ }
+ if (name == "storage-access") {
+ if (!RuntimeEnabledFeatures::StorageAccessAPIEnabled()) {
+ exception_state.ThrowTypeError("The Storage Access API is not enabled.");
+ return nullptr;
+ }
+ return CreatePermissionDescriptor(PermissionName::STORAGE_ACCESS);
+ }
+ return nullptr;
+}
+
} // namespace blink
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 5a52edb7053..e790055c88d 100644
--- a/chromium/third_party/blink/renderer/modules/permissions/permission_utils.h
+++ b/chromium/third_party/blink/renderer/modules/permissions/permission_utils.h
@@ -7,11 +7,15 @@
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
namespace blink {
class ExecutionContext;
+class ExceptionState;
+class ScriptState;
+class ScriptValue;
void ConnectToPermissionService(
ExecutionContext*,
@@ -27,11 +31,24 @@ mojom::blink::PermissionDescriptorPtr CreateMidiPermissionDescriptor(
mojom::blink::PermissionDescriptorPtr CreateClipboardPermissionDescriptor(
mojom::blink::PermissionName,
- bool allow_without_gesture);
+ bool allow_without_gesture,
+ bool allow_without_sanitization);
mojom::blink::PermissionDescriptorPtr CreateWakeLockPermissionDescriptor(
mojom::blink::WakeLockType type);
+// 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.
+//
+// Websites will be able to run code when `name()` is called, changing the
+// current context. The caller should make sure that no assumption is made
+// after this has been called.
+MODULES_EXPORT mojom::blink::PermissionDescriptorPtr ParsePermissionDescriptor(
+ ScriptState*,
+ const ScriptValue& raw_permission,
+ ExceptionState&);
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PERMISSIONS_PERMISSION_UTILS_H_
diff --git a/chromium/third_party/blink/renderer/modules/permissions/permissions.cc b/chromium/third_party/blink/renderer/modules/permissions/permissions.cc
index d85f87e0794..5ec49bcbb79 100644
--- a/chromium/third_party/blink/renderer/modules/permissions/permissions.cc
+++ b/chromium/third_party/blink/renderer/modules/permissions/permissions.cc
@@ -11,18 +11,13 @@
#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/script_value.h"
-#include "third_party/blink/renderer/bindings/modules/v8/v8_clipboard_permission_descriptor.h"
-#include "third_party/blink/renderer/bindings/modules/v8/v8_midi_permission_descriptor.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_permission_descriptor.h"
-#include "third_party/blink/renderer/bindings/modules/v8/v8_push_permission_descriptor.h"
-#include "third_party/blink/renderer/bindings/modules/v8/v8_wake_lock_permission_descriptor.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/frame.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/origin_trials/origin_trials.h"
-#include "third_party/blink/renderer/modules/permissions/permission_descriptor.h"
#include "third_party/blink/renderer/modules/permissions/permission_status.h"
#include "third_party/blink/renderer/modules/permissions/permission_utils.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -36,152 +31,11 @@ using mojom::blink::PermissionDescriptorPtr;
using mojom::blink::PermissionName;
using mojom::blink::PermissionService;
-namespace {
-
-// 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 null will be returned. Therefore, the
-// |exceptionState| should be checked before attempting to use the returned
-// permission as the non-null assert will be fired otherwise.
-//
-// Websites will be able to run code when `name()` is called, changing the
-// current context. The caller should make sure that no assumption is made
-// after this has been called.
-PermissionDescriptorPtr ParsePermission(ScriptState* script_state,
- const ScriptValue raw_permission,
- ExceptionState& exception_state) {
- PermissionDescriptor* permission =
- NativeValueTraits<PermissionDescriptor>::NativeValue(
- script_state->GetIsolate(), raw_permission.V8Value(),
- exception_state);
-
- if (exception_state.HadException()) {
- exception_state.ThrowTypeError(exception_state.Message());
- return nullptr;
- }
-
- const String& name = permission->name();
- if (name == "geolocation")
- return CreatePermissionDescriptor(PermissionName::GEOLOCATION);
- if (name == "camera")
- return CreatePermissionDescriptor(PermissionName::VIDEO_CAPTURE);
- if (name == "microphone")
- return CreatePermissionDescriptor(PermissionName::AUDIO_CAPTURE);
- if (name == "notifications")
- return CreatePermissionDescriptor(PermissionName::NOTIFICATIONS);
- if (name == "persistent-storage")
- return CreatePermissionDescriptor(PermissionName::DURABLE_STORAGE);
- if (name == "push") {
- PushPermissionDescriptor* push_permission =
- NativeValueTraits<PushPermissionDescriptor>::NativeValue(
- script_state->GetIsolate(), raw_permission.V8Value(),
- exception_state);
- if (exception_state.HadException()) {
- exception_state.ThrowTypeError(exception_state.Message());
- return nullptr;
- }
-
- // Only "userVisibleOnly" push is supported for now.
- if (!push_permission->userVisibleOnly()) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kNotSupportedError,
- "Push Permission without userVisibleOnly:true isn't supported yet.");
- return nullptr;
- }
-
- return CreatePermissionDescriptor(PermissionName::NOTIFICATIONS);
- }
- if (name == "midi") {
- MidiPermissionDescriptor* midi_permission =
- NativeValueTraits<MidiPermissionDescriptor>::NativeValue(
- script_state->GetIsolate(), raw_permission.V8Value(),
- exception_state);
- return CreateMidiPermissionDescriptor(midi_permission->sysex());
- }
- if (name == "background-sync")
- return CreatePermissionDescriptor(PermissionName::BACKGROUND_SYNC);
- if (name == "ambient-light-sensor" || name == "accelerometer" ||
- name == "gyroscope" || name == "magnetometer") {
- // ALS requires an extra flag.
- if (name == "ambient-light-sensor") {
- if (!RuntimeEnabledFeatures::SensorExtraClassesEnabled()) {
- exception_state.ThrowTypeError(
- "GenericSensorExtraClasses flag is not enabled.");
- return nullptr;
- }
- }
-
- return CreatePermissionDescriptor(PermissionName::SENSORS);
- }
- if (name == "accessibility-events") {
- if (!RuntimeEnabledFeatures::AccessibilityObjectModelEnabled()) {
- exception_state.ThrowTypeError(
- "Accessibility Object Model is not enabled.");
- return nullptr;
- }
- return CreatePermissionDescriptor(PermissionName::ACCESSIBILITY_EVENTS);
- }
- if (name == "clipboard-read" || name == "clipboard-write") {
- PermissionName permission_name = PermissionName::CLIPBOARD_READ;
- if (name == "clipboard-write")
- permission_name = PermissionName::CLIPBOARD_WRITE;
-
- ClipboardPermissionDescriptor* clipboard_permission =
- NativeValueTraits<ClipboardPermissionDescriptor>::NativeValue(
- script_state->GetIsolate(), raw_permission.V8Value(),
- exception_state);
- return CreateClipboardPermissionDescriptor(
- permission_name, clipboard_permission->allowWithoutGesture());
- }
- if (name == "payment-handler")
- return CreatePermissionDescriptor(PermissionName::PAYMENT_HANDLER);
- if (name == "background-fetch")
- return CreatePermissionDescriptor(PermissionName::BACKGROUND_FETCH);
- if (name == "idle-detection")
- return CreatePermissionDescriptor(PermissionName::IDLE_DETECTION);
- if (name == "periodic-background-sync")
- return CreatePermissionDescriptor(PermissionName::PERIODIC_BACKGROUND_SYNC);
- if (name == "wake-lock") {
- if (!RuntimeEnabledFeatures::WakeLockEnabled(
- ExecutionContext::From(script_state))) {
- exception_state.ThrowTypeError("Wake Lock is not enabled.");
- return nullptr;
- }
- WakeLockPermissionDescriptor* wake_lock_permission =
- NativeValueTraits<WakeLockPermissionDescriptor>::NativeValue(
- script_state->GetIsolate(), raw_permission.V8Value(),
- exception_state);
- if (exception_state.HadException())
- return nullptr;
- const String& type = wake_lock_permission->type();
- if (type == "screen") {
- return CreateWakeLockPermissionDescriptor(
- mojom::blink::WakeLockType::kScreen);
- } else if (type == "system") {
- return CreateWakeLockPermissionDescriptor(
- mojom::blink::WakeLockType::kSystem);
- } else {
- NOTREACHED();
- }
- }
- if (name == "nfc") {
- if (!RuntimeEnabledFeatures::WebNFCEnabled(
- ExecutionContext::From(script_state))) {
- exception_state.ThrowTypeError("Web NFC is not enabled.");
- return nullptr;
- }
- return CreatePermissionDescriptor(PermissionName::NFC);
- }
- return nullptr;
-}
-
-} // anonymous namespace
-
ScriptPromise Permissions::query(ScriptState* script_state,
const ScriptValue& raw_permission,
ExceptionState& exception_state) {
PermissionDescriptorPtr descriptor =
- ParsePermission(script_state, raw_permission, exception_state);
+ ParsePermissionDescriptor(script_state, raw_permission, exception_state);
if (exception_state.HadException())
return ScriptPromise();
@@ -205,7 +59,7 @@ ScriptPromise Permissions::request(ScriptState* script_state,
const ScriptValue& raw_permission,
ExceptionState& exception_state) {
PermissionDescriptorPtr descriptor =
- ParsePermission(script_state, raw_permission, exception_state);
+ ParsePermissionDescriptor(script_state, raw_permission, exception_state);
if (exception_state.HadException())
return ScriptPromise();
@@ -215,7 +69,7 @@ ScriptPromise Permissions::request(ScriptState* script_state,
ScriptPromise promise = resolver->Promise();
PermissionDescriptorPtr descriptor_copy = descriptor->Clone();
- Document* doc = DynamicTo<Document>(context);
+ Document* doc = Document::DynamicFrom(context);
LocalFrame* frame = doc ? doc->GetFrame() : nullptr;
GetService(ExecutionContext::From(script_state))
->RequestPermission(
@@ -230,7 +84,7 @@ ScriptPromise Permissions::revoke(ScriptState* script_state,
const ScriptValue& raw_permission,
ExceptionState& exception_state) {
PermissionDescriptorPtr descriptor =
- ParsePermission(script_state, raw_permission, exception_state);
+ ParsePermissionDescriptor(script_state, raw_permission, exception_state);
if (exception_state.HadException())
return ScriptPromise();
@@ -260,8 +114,8 @@ ScriptPromise Permissions::requestAll(
for (wtf_size_t i = 0; i < raw_permissions.size(); ++i) {
const ScriptValue& raw_permission = raw_permissions[i];
- auto descriptor =
- ParsePermission(script_state, raw_permission, exception_state);
+ auto descriptor = ParsePermissionDescriptor(script_state, raw_permission,
+ exception_state);
if (exception_state.HadException())
return ScriptPromise();
@@ -288,7 +142,7 @@ ScriptPromise Permissions::requestAll(
for (const auto& descriptor : internal_permissions)
internal_permissions_copy.push_back(descriptor->Clone());
- Document* doc = DynamicTo<Document>(context);
+ Document* doc = Document::DynamicFrom(context);
LocalFrame* frame = doc ? doc->GetFrame() : nullptr;
GetService(ExecutionContext::From(script_state))
->RequestPermissions(
@@ -301,9 +155,14 @@ ScriptPromise Permissions::requestAll(
return promise;
}
+void Permissions::Trace(Visitor* visitor) {
+ visitor->Trace(service_);
+ ScriptWrappable::Trace(visitor);
+}
+
PermissionService* Permissions::GetService(
ExecutionContext* execution_context) {
- if (!service_) {
+ if (!service_.is_bound()) {
ConnectToPermissionService(
execution_context,
service_.BindNewPipeAndPassReceiver(
diff --git a/chromium/third_party/blink/renderer/modules/permissions/permissions.h b/chromium/third_party/blink/renderer/modules/permissions/permissions.h
index 66260d025e7..c58cd0f4b8f 100644
--- a/chromium/third_party/blink/renderer/modules/permissions/permissions.h
+++ b/chromium/third_party/blink/renderer/modules/permissions/permissions.h
@@ -5,11 +5,12 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PERMISSIONS_PERMISSIONS_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PERMISSIONS_PERMISSIONS_H_
-#include "mojo/public/cpp/bindings/remote.h"
#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/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"
namespace blink {
@@ -22,6 +23,7 @@ class Permissions final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
+ Permissions() : service_(nullptr) {}
ScriptPromise query(ScriptState*, const ScriptValue&, ExceptionState&);
ScriptPromise request(ScriptState*, const ScriptValue&, ExceptionState&);
ScriptPromise revoke(ScriptState*, const ScriptValue&, ExceptionState&);
@@ -29,6 +31,8 @@ class Permissions final : public ScriptWrappable {
const HeapVector<ScriptValue>&,
ExceptionState&);
+ void Trace(Visitor*) override;
+
private:
mojom::blink::PermissionService* GetService(ExecutionContext*);
void ServiceConnectionError();
@@ -40,7 +44,9 @@ class Permissions final : public ScriptWrappable {
Vector<int>,
const Vector<mojom::blink::PermissionStatus>&);
- mojo::Remote<mojom::blink::PermissionService> service_;
+ HeapMojoRemote<mojom::blink::PermissionService,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ service_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/permissions/testing/internals_permission.cc b/chromium/third_party/blink/renderer/modules/permissions/testing/internals_permission.cc
new file mode 100644
index 00000000000..883c70a2bad
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/permissions/testing/internals_permission.cc
@@ -0,0 +1,121 @@
+// 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/permissions/testing/internals_permission.h"
+
+#include <utility>
+
+#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
+#include "third_party/blink/public/common/permissions/permission_utils.h"
+#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
+#include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h"
+#include "third_party/blink/public/mojom/permissions/permission_automation.mojom-blink.h"
+#include "third_party/blink/public/platform/platform.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/script_value.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_frame.h"
+#include "third_party/blink/renderer/core/page/frame_tree.h"
+#include "third_party/blink/renderer/core/testing/internals.h"
+#include "third_party/blink/renderer/modules/permissions/permission_utils.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/weborigin/kurl.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+// static
+ScriptPromise InternalsPermission::setPermission(
+ ScriptState* script_state,
+ Internals&,
+ const ScriptValue& raw_descriptor,
+ const String& state,
+ const String& origin,
+ const String& embedding_origin,
+ ExceptionState& exception_state) {
+ mojom::blink::PermissionDescriptorPtr descriptor =
+ ParsePermissionDescriptor(script_state, raw_descriptor, exception_state);
+ if (exception_state.HadException())
+ return ScriptPromise();
+
+ ExecutionContext* context = ExecutionContext::From(script_state);
+ KURL url;
+ if (origin.IsNull()) {
+ const SecurityOrigin* security_origin =
+ context->GetSecurityContext().GetSecurityOrigin();
+ if (security_origin->IsOpaque()) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotAllowedError,
+ "Unable to set permission for an opaque origin.");
+ return ScriptPromise();
+ }
+ url = KURL(security_origin->ToString());
+ DCHECK(url.IsValid());
+ } else {
+ url = KURL(origin);
+ if (!url.IsValid()) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError,
+ "'" + origin + "' is not a valid URL.");
+ return ScriptPromise();
+ }
+ }
+
+ KURL embedding_url;
+ if (embedding_origin.IsNull()) {
+ const SecurityOrigin* security_origin = Document::From(context)
+ ->GetFrame()
+ ->Tree()
+ .Top()
+ .GetSecurityContext()
+ ->GetSecurityOrigin();
+ if (security_origin->IsOpaque()) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotAllowedError,
+ "Unable to set permission for an opaque embedding origin.");
+ return ScriptPromise();
+ }
+ embedding_url = KURL(security_origin->ToString());
+ } else {
+ embedding_url = KURL(embedding_origin);
+ if (!embedding_url.IsValid()) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kSyntaxError,
+ "'" + embedding_origin + "' is not a valid URL.");
+ return ScriptPromise();
+ }
+ }
+
+ mojo::Remote<test::mojom::blink::PermissionAutomation> permission_automation;
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
+ permission_automation.BindNewPipeAndPassReceiver());
+ DCHECK(permission_automation.is_bound());
+
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ ScriptPromise promise = resolver->Promise();
+ auto* raw_permission_automation = permission_automation.get();
+ raw_permission_automation->SetPermission(
+ std::move(descriptor), ToPermissionStatus(state.Utf8()), url,
+ embedding_url,
+ WTF::Bind(
+ // While we only really need |resolver|, we also take the
+ // mojo::Remote<> so that it remains alive after this function exits.
+ [](ScriptPromiseResolver* resolver,
+ mojo::Remote<test::mojom::blink::PermissionAutomation>,
+ bool success) {
+ if (success)
+ resolver->Resolve();
+ else
+ resolver->Reject();
+ },
+ WrapPersistent(resolver), std::move(permission_automation)));
+
+ return promise;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/permissions/testing/internals_permission.h b/chromium/third_party/blink/renderer/modules/permissions/testing/internals_permission.h
new file mode 100644
index 00000000000..59fd0f0035e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/permissions/testing/internals_permission.h
@@ -0,0 +1,34 @@
+// 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_PERMISSIONS_TESTING_INTERNALS_PERMISSION_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PERMISSIONS_TESTING_INTERNALS_PERMISSION_H_
+
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "third_party/blink/renderer/platform/wtf/forward.h"
+
+namespace blink {
+
+class ExceptionState;
+class Internals;
+class ScriptPromise;
+class ScriptState;
+class ScriptValue;
+
+class InternalsPermission {
+ STATIC_ONLY(InternalsPermission);
+
+ public:
+ static ScriptPromise setPermission(ScriptState*,
+ Internals&,
+ const ScriptValue&,
+ const String& state,
+ const String& origin,
+ const String& embedding_origin,
+ ExceptionState&);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PERMISSIONS_TESTING_INTERNALS_PERMISSION_H_
diff --git a/chromium/third_party/blink/renderer/modules/permissions/testing/internals_permission.idl b/chromium/third_party/blink/renderer/modules/permissions/testing/internals_permission.idl
new file mode 100644
index 00000000000..3046a6edb5e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/permissions/testing/internals_permission.idl
@@ -0,0 +1,9 @@
+// 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.
+
+[
+ ImplementedAs=InternalsPermission
+] partial interface Internals {
+ [CallWith=ScriptState, RaisesException] Promise<void> setPermission(object descriptor, PermissionState state, optional USVString? origin = null, optional USVString? embedding_origin = null);
+};
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 db143caee7e..1016492501c 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
@@ -38,7 +38,7 @@ Permissions* WorkerNavigatorPermissions::permissions(
return self.permissions_;
}
-void WorkerNavigatorPermissions::Trace(blink::Visitor* visitor) {
+void WorkerNavigatorPermissions::Trace(Visitor* visitor) {
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 06aab064a49..2139f5e8b4c 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<Permissions> permissions_;
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/enter_picture_in_picture_event.cc
index 438d36f5b13..f20e0b7d878 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/enter_picture_in_picture_event.cc
@@ -36,7 +36,7 @@ EnterPictureInPictureEvent::EnterPictureInPictureEvent(
: Event(type, initializer),
picture_in_picture_window_(initializer->pictureInPictureWindow()) {}
-void EnterPictureInPictureEvent::Trace(blink::Visitor* visitor) {
+void EnterPictureInPictureEvent::Trace(Visitor* visitor) {
visitor->Trace(picture_in_picture_window_);
Event::Trace(visitor);
}
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
index e931afcba05..cc3b34fffe3 100644
--- 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
@@ -5,8 +5,8 @@
#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/enter_picture_in_picture_event_init.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"
@@ -30,7 +30,7 @@ class MODULES_EXPORT EnterPictureInPictureEvent final : public Event {
PictureInPictureWindow* pictureInPictureWindow() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<PictureInPictureWindow> picture_in_picture_window_;
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
index a10341a77a6..2c8aad04e79 100644
--- 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
@@ -5,10 +5,9 @@
// https://wicg.github.io/picture-in-picture/#enterpictureinpictureevent
[
RuntimeEnabled=PictureInPictureAPI,
- Constructor(DOMString type, EnterPictureInPictureEventInit eventInitDict),
Exposed=Window
-]
-interface EnterPictureInPictureEvent : Event {
+] 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/html_element_picture_in_picture.cc b/chromium/third_party/blink/renderer/modules/picture_in_picture/html_element_picture_in_picture.cc
index 2e69085829b..e751c593a7f 100644
--- a/chromium/third_party/blink/renderer/modules/picture_in_picture/html_element_picture_in_picture.cc
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/html_element_picture_in_picture.cc
@@ -5,11 +5,11 @@
#include "third_party/blink/renderer/modules/picture_in_picture/html_element_picture_in_picture.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_picture_in_picture_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/html/html_element.h"
#include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h"
-#include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_options.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/html_element_picture_in_picture.idl b/chromium/third_party/blink/renderer/modules/picture_in_picture/html_element_picture_in_picture.idl
index be8608ce59c..7eb7cadb196 100644
--- a/chromium/third_party/blink/renderer/modules/picture_in_picture/html_element_picture_in_picture.idl
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/html_element_picture_in_picture.idl
@@ -2,11 +2,11 @@
// 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/v2/
+// https://w3c.github.io/picture-in-picture/#htmlvideoelement-extensions
[
ImplementedAs=HTMLElementPictureInPicture,
RuntimeEnabled=PictureInPictureV2
]
partial interface HTMLElement {
- [CallWith=ScriptState, NewObject, RaisesException] Promise<PictureInPictureWindow> requestPictureInPicture(optional PictureInPictureOptions options);
+ [CallWith=ScriptState, NewObject, RaisesException] Promise<PictureInPictureWindow> requestPictureInPicture(optional PictureInPictureOptions options = {});
};
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.cc b/chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.cc
index 7765509d52d..e316f6c5bf2 100644
--- a/chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.cc
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.cc
@@ -36,8 +36,8 @@ ScriptPromise HTMLVideoElementPictureInPicture::requestPictureInPicture(
// static
bool HTMLVideoElementPictureInPicture::FastHasAttribute(
- const QualifiedName& name,
- const HTMLVideoElement& element) {
+ const HTMLVideoElement& element,
+ const QualifiedName& name) {
DCHECK(name == html_names::kDisablepictureinpictureAttr ||
name == html_names::kAutopictureinpictureAttr);
return element.FastHasAttribute(name);
@@ -45,8 +45,8 @@ bool HTMLVideoElementPictureInPicture::FastHasAttribute(
// static
void HTMLVideoElementPictureInPicture::SetBooleanAttribute(
- const QualifiedName& name,
HTMLVideoElement& element,
+ const QualifiedName& name,
bool value) {
DCHECK(name == html_names::kDisablepictureinpictureAttr ||
name == html_names::kAutopictureinpictureAttr);
diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.h b/chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.h
index ff5741265b2..9f5fd91ebdf 100644
--- a/chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.h
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.h
@@ -23,10 +23,10 @@ class HTMLVideoElementPictureInPicture {
HTMLVideoElement&,
ExceptionState&);
- static bool FastHasAttribute(const QualifiedName&, const HTMLVideoElement&);
+ static bool FastHasAttribute(const HTMLVideoElement&, const QualifiedName&);
- static void SetBooleanAttribute(const QualifiedName&,
- HTMLVideoElement&,
+ static void SetBooleanAttribute(HTMLVideoElement&,
+ const QualifiedName&,
bool);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(enterpictureinpicture,
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
new file mode 100644
index 00000000000..10b5024d081
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "enter_picture_in_picture_event.idl",
+ "picture_in_picture_window.idl",
+]
+
+modules_dictionary_idl_files = [
+ "enter_picture_in_picture_event_init.idl",
+ "picture_in_picture_options.idl",
+]
+
+modules_dependency_idl_files = [
+ "document_picture_in_picture.idl",
+ "html_element_picture_in_picture.idl",
+ "html_video_element_picture_in_picture.idl",
+ "shadow_root_picture_in_picture.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 16fb43a2f1c..962fb260612 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
@@ -12,6 +12,7 @@
#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/manifest/display_mode.mojom-shared.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_picture_in_picture_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/dom/events/event.h"
@@ -20,7 +21,6 @@
#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_options.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"
@@ -45,12 +45,6 @@ bool IsVideoElement(const Element& element) {
} // namespace
// static
-PictureInPictureControllerImpl* PictureInPictureControllerImpl::Create(
- Document& document) {
- return MakeGarbageCollected<PictureInPictureControllerImpl>(document);
-}
-
-// static
PictureInPictureControllerImpl& PictureInPictureControllerImpl::From(
Document& document) {
return static_cast<PictureInPictureControllerImpl&>(
@@ -58,11 +52,11 @@ PictureInPictureControllerImpl& PictureInPictureControllerImpl::From(
}
bool PictureInPictureControllerImpl::PictureInPictureEnabled() const {
- return IsDocumentAllowed() == Status::kEnabled;
+ return IsDocumentAllowed(/*report_failure=*/true) == Status::kEnabled;
}
PictureInPictureController::Status
-PictureInPictureControllerImpl::IsDocumentAllowed() const {
+PictureInPictureControllerImpl::IsDocumentAllowed(bool report_failure) const {
DCHECK(GetSupplementable());
// If document has been detached from a frame, return kFrameDetached status.
@@ -80,8 +74,9 @@ PictureInPictureControllerImpl::IsDocumentAllowed() const {
// "picture-in-picture", return kDisabledByFeaturePolicy status.
if (RuntimeEnabledFeatures::PictureInPictureAPIEnabled() &&
!GetSupplementable()->IsFeatureEnabled(
- blink::mojom::FeaturePolicyFeature::kPictureInPicture,
- ReportOptions::kReportOnFailure)) {
+ blink::mojom::blink::FeaturePolicyFeature::kPictureInPicture,
+ report_failure ? ReportOptions::kReportOnFailure
+ : ReportOptions::kDoNotReport)) {
return Status::kDisabledByFeaturePolicy;
}
@@ -104,13 +99,19 @@ PictureInPictureControllerImpl::VerifyElementAndOptions(
}
}
- return IsElementAllowed(element);
+ return IsElementAllowed(element, /*report_failure=*/true);
}
PictureInPictureController::Status
PictureInPictureControllerImpl::IsElementAllowed(
const HTMLElement& element) const {
- PictureInPictureController::Status status = IsDocumentAllowed();
+ return IsElementAllowed(element, /*report_failure=*/false);
+}
+
+PictureInPictureController::Status
+PictureInPictureControllerImpl::IsElementAllowed(const HTMLElement& element,
+ bool report_failure) const {
+ PictureInPictureController::Status status = IsDocumentAllowed(report_failure);
if (status != Status::kEnabled)
return status;
@@ -187,7 +188,7 @@ void PictureInPictureControllerImpl::OnEnteredPictureInPicture(
HTMLVideoElement* element,
ScriptPromiseResolver* resolver,
mojo::PendingRemote<mojom::blink::PictureInPictureSession> session_remote,
- const WebSize& picture_in_picture_window_size) {
+ const gfx::Size& picture_in_picture_window_size) {
// If |session_ptr| is null then Picture-in-Picture is not supported by the
// browser. We should rarely see this because we should have already rejected
// with |kDisabledBySystem|.
@@ -205,7 +206,7 @@ void PictureInPictureControllerImpl::OnEnteredPictureInPicture(
mojo::Remote<mojom::blink::PictureInPictureSession>(
std::move(session_remote));
- if (IsElementAllowed(*element) != Status::kEnabled) {
+ if (IsElementAllowed(*element, /*report_failure=*/true) != Status::kEnabled) {
if (resolver) {
resolver->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kInvalidStateError, ""));
@@ -222,7 +223,8 @@ void PictureInPictureControllerImpl::OnEnteredPictureInPicture(
picture_in_picture_element_->OnEnteredPictureInPicture();
picture_in_picture_window_ = MakeGarbageCollected<PictureInPictureWindow>(
- GetSupplementable(), picture_in_picture_window_size);
+ GetSupplementable()->ToExecutionContext(),
+ picture_in_picture_window_size);
picture_in_picture_element_->DispatchEvent(
*EnterPictureInPictureEvent::Create(
@@ -339,7 +341,8 @@ bool PictureInPictureControllerImpl::IsEnterAutoPictureInPictureAllowed()
return false;
// Allow if video is allowed to enter Picture-in-Picture.
- return (IsElementAllowed(*AutoPictureInPictureElement()) == Status::kEnabled);
+ return (IsElementAllowed(*AutoPictureInPictureElement(),
+ /*report_failure=*/true) == Status::kEnabled);
}
bool PictureInPictureControllerImpl::IsExitAutoPictureInPictureAllowed() const {
@@ -372,7 +375,7 @@ void PictureInPictureControllerImpl::PageVisibilityChanged() {
}
}
-void PictureInPictureControllerImpl::ContextDestroyed(Document*) {
+void PictureInPictureControllerImpl::ContextDestroyed() {
picture_in_picture_service_.reset();
session_observer_receiver_.reset();
}
@@ -389,7 +392,7 @@ void PictureInPictureControllerImpl::OnPictureInPictureStateChange() {
}
void PictureInPictureControllerImpl::OnWindowSizeChanged(
- const blink::WebSize& size) {
+ const gfx::Size& size) {
if (picture_in_picture_window_)
picture_in_picture_window_->OnResize(size);
}
@@ -398,19 +401,20 @@ void PictureInPictureControllerImpl::OnStopped() {
OnExitedPictureInPicture(nullptr);
}
-void PictureInPictureControllerImpl::Trace(blink::Visitor* visitor) {
+void PictureInPictureControllerImpl::Trace(Visitor* visitor) {
visitor->Trace(picture_in_picture_element_);
visitor->Trace(auto_picture_in_picture_elements_);
visitor->Trace(picture_in_picture_window_);
PictureInPictureController::Trace(visitor);
PageVisibilityObserver::Trace(visitor);
- DocumentShutdownObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
PictureInPictureControllerImpl::PictureInPictureControllerImpl(
Document& document)
: PictureInPictureController(document),
PageVisibilityObserver(document.GetPage()),
+ ExecutionContextLifecycleObserver(&document),
session_observer_receiver_(this) {}
bool PictureInPictureControllerImpl::EnsureService() {
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 916fcc2e9af..e442422d1d7 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
@@ -10,7 +10,7 @@
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/picture_in_picture/picture_in_picture.mojom-blink.h"
-#include "third_party/blink/renderer/core/dom/document_shutdown_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/frame/picture_in_picture_controller.h"
#include "third_party/blink/renderer/core/page/page_visibility_observer.h"
#include "third_party/blink/renderer/modules/modules_export.h"
@@ -21,7 +21,6 @@ class HTMLVideoElement;
class PictureInPictureOptions;
class PictureInPictureWindow;
class TreeScope;
-struct WebSize;
// The PictureInPictureControllerImpl is keeping the state and implementing the
// logic around the Picture-in-Picture feature. It is meant to be used as well
@@ -34,7 +33,7 @@ struct WebSize;
class MODULES_EXPORT PictureInPictureControllerImpl
: public PictureInPictureController,
public PageVisibilityObserver,
- public DocumentShutdownObserver,
+ public ExecutionContextLifecycleObserver,
public blink::mojom::blink::PictureInPictureSessionObserver {
USING_GARBAGE_COLLECTED_MIXIN(PictureInPictureControllerImpl);
@@ -42,10 +41,6 @@ class MODULES_EXPORT PictureInPictureControllerImpl
explicit PictureInPictureControllerImpl(Document&);
~PictureInPictureControllerImpl() override = default;
- // Meant to be called internally by PictureInPictureController::From()
- // through ModulesInitializer.
- static PictureInPictureControllerImpl* Create(Document&);
-
// Gets, or creates, PictureInPictureControllerImpl supplement on Document.
// Should be called before any other call to make sure a document is attached.
static PictureInPictureControllerImpl& From(Document&);
@@ -56,7 +51,7 @@ class MODULES_EXPORT PictureInPictureControllerImpl
// Returns whether the document associated with the controller is allowed to
// request Picture-in-Picture.
- Status IsDocumentAllowed() const;
+ Status IsDocumentAllowed(bool report_failure) const;
// Returns whether the combination of element and options can be in
// Picture-in-Picture.
@@ -89,16 +84,16 @@ class MODULES_EXPORT PictureInPictureControllerImpl
void OnPictureInPictureStateChange() override;
// Implementation of PictureInPictureSessionObserver.
- void OnWindowSizeChanged(const blink::WebSize&) override;
+ void OnWindowSizeChanged(const gfx::Size&) override;
void OnStopped() override;
// Implementation of PageVisibilityObserver.
void PageVisibilityChanged() override;
- // Implementation of DocumentShutdownObserver.
- void ContextDestroyed(Document*) override;
+ // Implementation of ExecutionContextLifecycleObserver.
+ void ContextDestroyed() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
bool IsSessionObserverReceiverBoundForTesting() {
return session_observer_receiver_.is_bound();
@@ -109,8 +104,9 @@ class MODULES_EXPORT PictureInPictureControllerImpl
HTMLVideoElement*,
ScriptPromiseResolver*,
mojo::PendingRemote<mojom::blink::PictureInPictureSession>,
- const WebSize&);
+ const gfx::Size&);
void OnExitedPictureInPicture(ScriptPromiseResolver*) override;
+ Status IsElementAllowed(const HTMLElement&, bool report_failure) const;
// Makes sure the `picture_in_picture_service_` is set. Returns whether it was
// initialized successfully.
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 b8ba2bf0907..c43a2bf9c7e 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
@@ -10,7 +10,6 @@
#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/public/common/media/media_player_action.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"
@@ -48,7 +47,7 @@ class MockPictureInPictureSession
MOCK_METHOD4(Update,
void(uint32_t,
const base::Optional<viz::SurfaceId>&,
- const blink::WebSize&,
+ const gfx::Size&,
bool));
private:
@@ -81,7 +80,7 @@ class MockPictureInPictureService
StartSession,
void(uint32_t,
const base::Optional<viz::SurfaceId>&,
- const blink::WebSize&,
+ const gfx::Size&,
bool,
mojo::PendingRemote<mojom::blink::PictureInPictureSessionObserver>,
StartSessionCallback));
@@ -91,11 +90,11 @@ class MockPictureInPictureService
void StartSessionInternal(
uint32_t,
const base::Optional<viz::SurfaceId>&,
- const blink::WebSize&,
+ const gfx::Size&,
bool,
mojo::PendingRemote<mojom::blink::PictureInPictureSessionObserver>,
StartSessionCallback callback) {
- std::move(callback).Run(std::move(session_remote_), WebSize());
+ std::move(callback).Run(std::move(session_remote_), gfx::Size());
}
private:
@@ -337,9 +336,10 @@ TEST_F(PictureInPictureControllerTest, PerformMediaPlayerAction) {
IntPoint bounds = video->BoundsInViewport().Center();
- frame->PerformMediaPlayerAction(
- WebPoint(bounds.X(), bounds.Y()),
- MediaPlayerAction(MediaPlayerAction::Type::kPictureInPicture, true));
+ // Performs the specified media player action on the media element at the
+ // given location.
+ frame->GetFrame()->MediaPlayerActionAtViewportPoint(
+ bounds, blink::mojom::MediaPlayerActionType::kPictureInPicture, true);
}
} // namespace blink
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 3a37d6e94ea..2403ed2412f 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
@@ -13,14 +13,14 @@ namespace blink {
PictureInPictureWindow::PictureInPictureWindow(
ExecutionContext* execution_context,
- const WebSize& size)
- : ContextClient(execution_context), size_(size) {}
+ const gfx::Size& size)
+ : ExecutionContextClient(execution_context), size_(size) {}
void PictureInPictureWindow::OnClose() {
- size_.width = size_.height = 0;
+ size_ = gfx::Size();
}
-void PictureInPictureWindow::OnResize(const WebSize& size) {
+void PictureInPictureWindow::OnResize(const gfx::Size& size) {
if (size_ == size)
return;
@@ -48,9 +48,9 @@ bool PictureInPictureWindow::HasPendingActivity() const {
return GetExecutionContext() && HasEventListeners();
}
-void PictureInPictureWindow::Trace(blink::Visitor* visitor) {
+void PictureInPictureWindow::Trace(Visitor* visitor) {
EventTargetWithInlineData::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 245df4aad4d..bb53a2fb627 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
@@ -5,11 +5,11 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_WINDOW_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_WINDOW_H_
-#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "ui/gfx/geometry/size.h"
namespace blink {
@@ -19,35 +19,35 @@ namespace blink {
class PictureInPictureWindow
: public EventTargetWithInlineData,
public ActiveScriptWrappable<PictureInPictureWindow>,
- public ContextClient {
+ public ExecutionContextClient {
USING_GARBAGE_COLLECTED_MIXIN(PictureInPictureWindow);
DEFINE_WRAPPERTYPEINFO();
public:
- PictureInPictureWindow(ExecutionContext*, const WebSize& size);
+ PictureInPictureWindow(ExecutionContext*, const gfx::Size& size);
- int width() const { return size_.width; }
- int height() const { return size_.height; }
+ int width() const { return size_.width(); }
+ int height() const { return size_.height(); }
Document* document() const { return nullptr; }
// Called when Picture-in-Picture window state is closed.
void OnClose();
// Called when the Picture-in-Picture window is resized.
- void OnResize(const WebSize&);
+ void OnResize(const gfx::Size&);
DEFINE_ATTRIBUTE_EVENT_LISTENER(resize, kResize)
// EventTarget overrides.
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override {
- return ContextClient::GetExecutionContext();
+ return ExecutionContextClient::GetExecutionContext();
}
// ActiveScriptWrappable overrides.
bool HasPendingActivity() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
// EventTarget overrides.
@@ -56,7 +56,7 @@ class PictureInPictureWindow
private:
// The Picture-in-Picture window size in pixels.
- WebSize size_;
+ gfx::Size size_;
DISALLOW_IMPLICIT_CONSTRUCTORS(PictureInPictureWindow);
};
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 a086557ea27..d39c2dc248d 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
@@ -33,12 +33,12 @@ namespace blink {
DOMMimeType::DOMMimeType(LocalFrame* frame,
const MimeClassInfo& mime_class_info)
- : ContextClient(frame), mime_class_info_(&mime_class_info) {}
+ : ExecutionContextClient(frame), mime_class_info_(&mime_class_info) {}
-void DOMMimeType::Trace(blink::Visitor* visitor) {
+void DOMMimeType::Trace(Visitor* visitor) {
visitor->Trace(mime_class_info_);
ScriptWrappable::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
const String& DOMMimeType::type() const {
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 e8ff8f375ac..23ee306115f 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
@@ -21,7 +21,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PLUGINS_DOM_MIME_TYPE_H_
#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/page/plugin_data.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -32,7 +32,8 @@ namespace blink {
class DOMPlugin;
class LocalFrame;
-class DOMMimeType final : public ScriptWrappable, public ContextClient {
+class DOMMimeType final : public ScriptWrappable,
+ public ExecutionContextClient {
USING_GARBAGE_COLLECTED_MIXIN(DOMMimeType);
DEFINE_WRAPPERTYPEINFO();
@@ -44,7 +45,7 @@ class DOMMimeType final : public ScriptWrappable, public ContextClient {
const String& description() const;
DOMPlugin* enabledPlugin() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 98fd4b889a9..174be4f5565 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
@@ -30,15 +30,15 @@
namespace blink {
DOMMimeTypeArray::DOMMimeTypeArray(LocalFrame* frame)
- : ContextLifecycleObserver(frame ? frame->GetDocument() : nullptr),
+ : ExecutionContextLifecycleObserver(frame ? frame->GetDocument() : nullptr),
PluginsChangedObserver(frame ? frame->GetPage() : nullptr) {
UpdatePluginData();
}
-void DOMMimeTypeArray::Trace(blink::Visitor* visitor) {
+void DOMMimeTypeArray::Trace(Visitor* visitor) {
visitor->Trace(dom_mime_types_);
ScriptWrappable::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
unsigned DOMMimeTypeArray::length() const {
@@ -120,7 +120,7 @@ void DOMMimeTypeArray::UpdatePluginData() {
}
}
-void DOMMimeTypeArray::ContextDestroyed(ExecutionContext*) {
+void DOMMimeTypeArray::ContextDestroyed() {
dom_mime_types_.clear();
}
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 d57a3ef6abd..af3afc3aaa2 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
@@ -21,7 +21,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PLUGINS_DOM_MIME_TYPE_ARRAY_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PLUGINS_DOM_MIME_TYPE_ARRAY_H_
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/page/plugins_changed_observer.h"
#include "third_party/blink/renderer/modules/plugins/dom_mime_type.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -35,7 +35,7 @@ class LocalFrame;
class PluginData;
class DOMMimeTypeArray final : public ScriptWrappable,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public PluginsChangedObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(DOMMimeTypeArray);
@@ -54,11 +54,11 @@ class DOMMimeTypeArray final : public ScriptWrappable,
// PluginsChangedObserver implementation.
void PluginsChanged() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
PluginData* GetPluginData() const;
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
HeapVector<Member<DOMMimeType>> dom_mime_types_;
};
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 65a5a2f2745..09bf7a21e1b 100644
--- a/chromium/third_party/blink/renderer/modules/plugins/dom_plugin.cc
+++ b/chromium/third_party/blink/renderer/modules/plugins/dom_plugin.cc
@@ -26,12 +26,12 @@
namespace blink {
DOMPlugin::DOMPlugin(LocalFrame* frame, const PluginInfo& plugin_info)
- : ContextClient(frame), plugin_info_(&plugin_info) {}
+ : ExecutionContextClient(frame), plugin_info_(&plugin_info) {}
-void DOMPlugin::Trace(blink::Visitor* visitor) {
+void DOMPlugin::Trace(Visitor* visitor) {
visitor->Trace(plugin_info_);
ScriptWrappable::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
String DOMPlugin::name() const {
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 0b71748f98a..9b738d96015 100644
--- a/chromium/third_party/blink/renderer/modules/plugins/dom_plugin.h
+++ b/chromium/third_party/blink/renderer/modules/plugins/dom_plugin.h
@@ -21,7 +21,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PLUGINS_DOM_PLUGIN_H_
#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/plugins/dom_mime_type.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -31,7 +31,7 @@ namespace blink {
class ExceptionState;
-class DOMPlugin final : public ScriptWrappable, public ContextClient {
+class DOMPlugin final : public ScriptWrappable, public ExecutionContextClient {
USING_GARBAGE_COLLECTED_MIXIN(DOMPlugin);
DEFINE_WRAPPERTYPEINFO();
@@ -49,7 +49,7 @@ class DOMPlugin final : public ScriptWrappable, public ContextClient {
void NamedPropertyEnumerator(Vector<String>&, ExceptionState&) const;
bool NamedPropertyQuery(const AtomicString&, ExceptionState&) const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 a20e7667936..322e74880dd 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
@@ -35,15 +35,15 @@
namespace blink {
DOMPluginArray::DOMPluginArray(LocalFrame* frame)
- : ContextLifecycleObserver(frame ? frame->GetDocument() : nullptr),
+ : ExecutionContextLifecycleObserver(frame ? frame->GetDocument() : nullptr),
PluginsChangedObserver(frame ? frame->GetPage() : nullptr) {
UpdatePluginData();
}
-void DOMPluginArray::Trace(blink::Visitor* visitor) {
+void DOMPluginArray::Trace(Visitor* visitor) {
visitor->Trace(dom_plugins_);
ScriptWrappable::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
PluginsChangedObserver::Trace(visitor);
}
@@ -148,7 +148,7 @@ void DOMPluginArray::UpdatePluginData() {
}
}
-void DOMPluginArray::ContextDestroyed(ExecutionContext*) {
+void DOMPluginArray::ContextDestroyed() {
dom_plugins_.clear();
}
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 b241ff07983..031fe219515 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
@@ -21,7 +21,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PLUGINS_DOM_PLUGIN_ARRAY_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PLUGINS_DOM_PLUGIN_ARRAY_H_
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/page/plugins_changed_observer.h"
#include "third_party/blink/renderer/modules/plugins/dom_plugin.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -35,7 +35,7 @@ class LocalFrame;
class PluginData;
class DOMPluginArray final : public ScriptWrappable,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public PluginsChangedObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(DOMPluginArray);
@@ -56,11 +56,11 @@ class DOMPluginArray final : public ScriptWrappable,
// PluginsChangedObserver implementation.
void PluginsChanged() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
PluginData* GetPluginData() const;
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
HeapVector<Member<DOMPlugin>> dom_plugins_;
};
diff --git a/chromium/third_party/blink/renderer/modules/plugins/idls.gni b/chromium/third_party/blink/renderer/modules/plugins/idls.gni
new file mode 100644
index 00000000000..c5a2cb7d0d8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/plugins/idls.gni
@@ -0,0 +1,12 @@
+# 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 = [
+ "mime_type.idl",
+ "mime_type_array.idl",
+ "plugin.idl",
+ "plugin_array.idl",
+]
+
+modules_dependency_idl_files = [ "navigator_plugins.idl" ]
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 10d9d7b847b..921dbd87b04 100644
--- a/chromium/third_party/blink/renderer/modules/plugins/navigator_plugins.cc
+++ b/chromium/third_party/blink/renderer/modules/plugins/navigator_plugins.cc
@@ -60,7 +60,7 @@ DOMMimeTypeArray* NavigatorPlugins::mimeTypes(LocalFrame* frame) const {
return mime_types_.Get();
}
-void NavigatorPlugins::Trace(blink::Visitor* visitor) {
+void NavigatorPlugins::Trace(Visitor* visitor) {
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 602ebc816d4..4fcc984c013 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
DOMPluginArray* plugins(LocalFrame*) const;
diff --git a/chromium/third_party/blink/renderer/modules/presentation/idls.gni b/chromium/third_party/blink/renderer/modules/presentation/idls.gni
new file mode 100644
index 00000000000..f6ddfb28277
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/presentation/idls.gni
@@ -0,0 +1,21 @@
+# 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 = [
+ "presentation.idl",
+ "presentation_availability.idl",
+ "presentation_connection.idl",
+ "presentation_connection_available_event.idl",
+ "presentation_connection_close_event.idl",
+ "presentation_connection_list.idl",
+ "presentation_receiver.idl",
+ "presentation_request.idl",
+]
+
+modules_dictionary_idl_files = [
+ "presentation_connection_available_event_init.idl",
+ "presentation_connection_close_event_init.idl",
+]
+
+modules_dependency_idl_files = [ "navigator_presentation.idl" ]
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 5faa2d52511..fcee9cf9252 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(blink::Visitor* visitor) {
+void NavigatorPresentation::Trace(Visitor* visitor) {
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 e0818acc7fd..86ecc636cab 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 385e1def64a..6ff96ee1f4e 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation.cc
@@ -15,7 +15,7 @@
namespace blink {
-Presentation::Presentation(LocalFrame* frame) : ContextClient(frame) {}
+Presentation::Presentation(LocalFrame* frame) : ExecutionContextClient(frame) {}
// static
Presentation* Presentation::Create(LocalFrame* frame) {
@@ -27,11 +27,11 @@ Presentation* Presentation::Create(LocalFrame* frame) {
return presentation;
}
-void Presentation::Trace(blink::Visitor* visitor) {
+void Presentation::Trace(Visitor* visitor) {
visitor->Trace(default_request_);
visitor->Trace(receiver_);
ScriptWrappable::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
PresentationRequest* Presentation::defaultRequest() const {
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation.h b/chromium/third_party/blink/renderer/modules/presentation/presentation.h
index e66b517a0aa..e4c63ed5086 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PRESENTATION_PRESENTATION_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PRESENTATION_PRESENTATION_H_
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/heap/heap.h"
@@ -20,7 +20,8 @@ class PresentationRequest;
// Presentation.idl
// See https://w3c.github.io/presentation-api/#navigatorpresentation for
// details.
-class Presentation final : public ScriptWrappable, public ContextClient {
+class Presentation final : public ScriptWrappable,
+ public ExecutionContextClient {
USING_GARBAGE_COLLECTED_MIXIN(Presentation);
DEFINE_WRAPPERTYPEINFO();
@@ -29,7 +30,7 @@ class Presentation final : public ScriptWrappable, public ContextClient {
explicit Presentation(LocalFrame*);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 944819f4d64..a3058da4a90 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.cc
@@ -33,8 +33,8 @@ PresentationAvailability::PresentationAvailability(
ExecutionContext* execution_context,
const WTF::Vector<KURL>& urls,
bool value)
- : ContextLifecycleStateObserver(execution_context),
- PageVisibilityObserver(To<Document>(execution_context)->GetPage()),
+ : ExecutionContextLifecycleStateObserver(execution_context),
+ PageVisibilityObserver(Document::From(execution_context)->GetPage()),
urls_(urls),
value_(value),
state_(State::kActive) {
@@ -48,7 +48,7 @@ const AtomicString& PresentationAvailability::InterfaceName() const {
}
ExecutionContext* PresentationAvailability::GetExecutionContext() const {
- return ContextLifecycleStateObserver::GetExecutionContext();
+ return ExecutionContextLifecycleStateObserver::GetExecutionContext();
}
void PresentationAvailability::AddedEventListener(
@@ -84,7 +84,7 @@ void PresentationAvailability::ContextLifecycleStateChanged(
SetState(State::kSuspended);
}
-void PresentationAvailability::ContextDestroyed(ExecutionContext*) {
+void PresentationAvailability::ContextDestroyed() {
SetState(State::kInactive);
}
@@ -106,7 +106,7 @@ void PresentationAvailability::UpdateListening() {
return;
if (state_ == State::kActive &&
- (To<Document>(GetExecutionContext())->IsPageVisible()))
+ (Document::From(GetExecutionContext())->IsPageVisible()))
controller->GetAvailabilityState()->AddObserver(this);
else
controller->GetAvailabilityState()->RemoveObserver(this);
@@ -120,10 +120,10 @@ bool PresentationAvailability::value() const {
return value_;
}
-void PresentationAvailability::Trace(blink::Visitor* visitor) {
+void PresentationAvailability::Trace(Visitor* visitor) {
EventTargetWithInlineData::Trace(visitor);
PageVisibilityObserver::Trace(visitor);
- ContextLifecycleStateObserver::Trace(visitor);
+ ExecutionContextLifecycleStateObserver::Trace(visitor);
}
} // namespace blink
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 b8e6f78ecd0..e46c910beb3 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.h
@@ -9,7 +9,7 @@
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h"
#include "third_party/blink/renderer/core/page/page_visibility_observer.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/presentation/presentation_availability_observer.h"
@@ -28,7 +28,7 @@ class ExecutionContext;
class MODULES_EXPORT PresentationAvailability final
: public EventTargetWithInlineData,
public ActiveScriptWrappable<PresentationAvailability>,
- public ContextLifecycleStateObserver,
+ public ExecutionContextLifecycleStateObserver,
public PageVisibilityObserver,
public PresentationAvailabilityObserver {
USING_GARBAGE_COLLECTED_MIXIN(PresentationAvailability);
@@ -53,9 +53,9 @@ class MODULES_EXPORT PresentationAvailability final
// ScriptWrappable implementation.
bool HasPendingActivity() const final;
- // ContextLifecycleStateObserver implementation.
+ // ExecutionContextLifecycleStateObserver implementation.
void ContextLifecycleStateChanged(mojom::FrameLifecycleState) override;
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
// PageVisibilityObserver implementation.
void PageVisibilityChanged() override;
@@ -64,7 +64,7 @@ class MODULES_EXPORT PresentationAvailability final
DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange)
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
// EventTarget implementation.
@@ -72,10 +72,10 @@ class MODULES_EXPORT PresentationAvailability final
RegisteredEventListener&) override;
private:
- // Current state of the ContextLifecycleStateObserver. It is Active when
- // created. It becomes Suspended when suspend() is called and moves back to
- // Active if resume() is called. It becomes Inactive when stop() is called or
- // at destruction time.
+ // Current state of the ExecutionContextLifecycleStateObserver. It is Active
+ // when created. It becomes Suspended when suspend() is called and moves back
+ // to Active if resume() is called. It becomes Inactive when stop() is called
+ // or at destruction time.
enum class State : char {
kActive,
kSuspended,
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 d365e7c6e76..bb4593da903 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(blink::Visitor* visitor) {
+void PresentationAvailabilityCallbacks::Trace(Visitor* visitor) {
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 022e6c45a98..0622ae6ac1e 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(blink::Visitor*);
+ void Trace(Visitor*);
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 f95c717d134..b9990104a97 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(blink::Visitor* visitor) {
+void PresentationAvailabilityState::Trace(Visitor* visitor) {
visitor->Trace(availability_listeners_);
}
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 c85f91240f1..45ce76eefee 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(blink::Visitor*);
+ void Trace(Visitor*);
private:
enum class ListeningState {
@@ -71,7 +71,7 @@ class MODULES_EXPORT PresentationAvailabilityState final
availability_callbacks;
HeapVector<Member<PresentationAvailabilityObserver>> availability_observers;
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
DISALLOW_COPY_AND_ASSIGN(AvailabilityListener);
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_test.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_test.cc
index 0eebe1d3322..89cbd28677a 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_test.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_test.cc
@@ -30,8 +30,7 @@ TEST(PresentationAvailabilityTest, NoPageVisibilityChangeAfterDetach) {
Persistent<PresentationAvailabilityProperty> resolver =
MakeGarbageCollected<PresentationAvailabilityProperty>(
- scope.GetExecutionContext(), nullptr,
- PresentationAvailabilityProperty::kReady);
+ scope.GetExecutionContext());
Persistent<PresentationAvailability> availability =
PresentationAvailability::Take(resolver, urls, false);
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 7fd797b5439..de49ab2f381 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.cc
@@ -43,7 +43,7 @@ mojom::blink::PresentationConnectionMessagePtr MakeBinaryMessage(
WTF::Vector<uint8_t>());
WTF::Vector<uint8_t>& data = message->get_data();
data.Append(static_cast<const uint8_t*>(buffer->Data()),
- buffer->DeprecatedByteLengthAsUnsigned());
+ base::checked_cast<wtf_size_t>(buffer->ByteLengthAsSizeT()));
return message;
}
@@ -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(blink::Visitor* visitor) { visitor->Trace(array_buffer); }
+ void Trace(Visitor* visitor) { visitor->Trace(array_buffer); }
MessageType type;
String text;
@@ -148,9 +148,7 @@ class PresentationConnection::BlobLoader final
void Cancel() { loader_->Cancel(); }
- void Trace(blink::Visitor* visitor) {
- visitor->Trace(presentation_connection_);
- }
+ void Trace(Visitor* visitor) { visitor->Trace(presentation_connection_); }
private:
Member<PresentationConnection> presentation_connection_;
@@ -160,7 +158,7 @@ class PresentationConnection::BlobLoader final
PresentationConnection::PresentationConnection(LocalFrame& frame,
const String& id,
const KURL& url)
- : ContextLifecycleStateObserver(frame.GetDocument()),
+ : ExecutionContextLifecycleStateObserver(frame.GetDocument()),
id_(id),
url_(url),
state_(mojom::blink::PresentationConnectionState::CONNECTING),
@@ -221,7 +219,7 @@ ControllerPresentationConnection* ControllerPresentationConnection::Take(
DCHECK(resolver);
DCHECK(request);
- Document* document = To<Document>(resolver->GetExecutionContext());
+ Document* document = Document::From(resolver->GetExecutionContext());
if (!document->GetFrame())
return nullptr;
@@ -267,7 +265,7 @@ ControllerPresentationConnection::ControllerPresentationConnection(
ControllerPresentationConnection::~ControllerPresentationConnection() {}
-void ControllerPresentationConnection::Trace(blink::Visitor* visitor) {
+void ControllerPresentationConnection::Trace(Visitor* visitor) {
visitor->Trace(controller_);
PresentationConnection::Trace(visitor);
}
@@ -377,7 +375,7 @@ void ReceiverPresentationConnection::TerminateInternal() {
target_connection_->DidChangeState(state_);
}
-void ReceiverPresentationConnection::Trace(blink::Visitor* visitor) {
+void ReceiverPresentationConnection::Trace(Visitor* visitor) {
visitor->Trace(receiver_);
PresentationConnection::Trace(visitor);
}
@@ -387,9 +385,7 @@ const AtomicString& PresentationConnection::InterfaceName() const {
}
ExecutionContext* PresentationConnection::GetExecutionContext() const {
- if (!GetFrame())
- return nullptr;
- return GetFrame()->GetDocument();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
void PresentationConnection::AddedEventListener(
@@ -413,7 +409,7 @@ void PresentationConnection::AddedEventListener(
}
}
-void PresentationConnection::ContextDestroyed(ExecutionContext*) {
+void PresentationConnection::ContextDestroyed() {
CloseConnection();
}
@@ -431,11 +427,11 @@ void PresentationConnection::CloseConnection() {
connection_receiver_.reset();
}
-void PresentationConnection::Trace(blink::Visitor* visitor) {
+void PresentationConnection::Trace(Visitor* visitor) {
visitor->Trace(blob_loader_);
visitor->Trace(messages_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleStateObserver::Trace(visitor);
+ ExecutionContextLifecycleStateObserver::Trace(visitor);
}
const AtomicString& PresentationConnection::state() const {
@@ -454,9 +450,17 @@ void PresentationConnection::send(const String& message,
void PresentationConnection::send(DOMArrayBuffer* array_buffer,
ExceptionState& exception_state) {
DCHECK(array_buffer);
- DCHECK(array_buffer->Buffer());
if (!CanSendMessage(exception_state))
return;
+ if (!base::CheckedNumeric<wtf_size_t>(array_buffer->ByteLengthAsSizeT())
+ .IsValid()) {
+ static_assert(
+ 4294967295 == std::numeric_limits<wtf_size_t>::max(),
+ "Change the error message below if this static_assert fails.");
+ exception_state.ThrowRangeError(
+ "ArrayBuffer size exceeds the maximum supported size (4294967295)");
+ return;
+ }
messages_.push_back(MakeGarbageCollected<Message>(array_buffer));
HandleMessageQueue();
@@ -468,6 +472,16 @@ void PresentationConnection::send(
DCHECK(array_buffer_view);
if (!CanSendMessage(exception_state))
return;
+ if (!base::CheckedNumeric<wtf_size_t>(
+ array_buffer_view.View()->byteLengthAsSizeT())
+ .IsValid()) {
+ static_assert(
+ 4294967295 == std::numeric_limits<wtf_size_t>::max(),
+ "Change the error message below if this static_assert fails.");
+ exception_state.ThrowRangeError(
+ "ArrayBuffer size exceeds the maximum supported size (4294967295)");
+ return;
+ }
messages_.push_back(
MakeGarbageCollected<Message>(array_buffer_view.View()->buffer()));
@@ -628,8 +642,16 @@ void PresentationConnection::DidFinishLoadingBlob(DOMArrayBuffer* buffer) {
DCHECK(!messages_.IsEmpty());
DCHECK_EQ(messages_.front()->type, kMessageTypeBlob);
DCHECK(buffer);
- DCHECK(buffer->Buffer());
-
+ if (!base::CheckedNumeric<wtf_size_t>(buffer->ByteLengthAsSizeT())
+ .IsValid()) {
+ // TODO(crbug.com/1036565): generate error message? The problem is that the
+ // content of {buffer} is copied into a WTF::Vector, but a DOMArrayBuffer
+ // has a bigger maximum size than a WTF::Vector. Ignore the current failed
+ // blob item and continue with next items.
+ messages_.pop_front();
+ blob_loader_.Clear();
+ HandleMessageQueue();
+ }
// Send the loaded blob immediately here and continue processing the queue.
SendMessageToTargetConnection(MakeBinaryMessage(buffer));
@@ -641,7 +663,7 @@ void PresentationConnection::DidFinishLoadingBlob(DOMArrayBuffer* buffer) {
void PresentationConnection::DidFailLoadingBlob(FileErrorCode error_code) {
DCHECK(!messages_.IsEmpty());
DCHECK_EQ(messages_.front()->type, kMessageTypeBlob);
- // FIXME: generate error message?
+ // TODO(crbug.com/1036565): generate error message?
// Ignore the current failed blob item and continue with next items.
messages_.pop_front();
blob_loader_.Clear();
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 76a4fa3fe2d..87e3368834c 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.h
@@ -12,7 +12,7 @@
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/presentation/presentation.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
#include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -34,7 +34,7 @@ class PresentationRequest;
class WebString;
class PresentationConnection : public EventTargetWithInlineData,
- public ContextLifecycleStateObserver,
+ public ExecutionContextLifecycleStateObserver,
public mojom::blink::PresentationConnection {
USING_GARBAGE_COLLECTED_MIXIN(PresentationConnection);
DEFINE_WRAPPERTYPEINFO();
@@ -46,7 +46,7 @@ class PresentationConnection : public EventTargetWithInlineData,
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
const String& id() const { return id_; }
const String& url() const { return url_; }
@@ -96,10 +96,10 @@ class PresentationConnection : public EventTargetWithInlineData,
void AddedEventListener(const AtomicString& event_type,
RegisteredEventListener&) override;
- // ContextLifecycleObserver implementation.
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver implementation.
+ void ContextDestroyed() override;
- // ContextLifecycleStateObserver implementation.
+ // ExecutionContextLifecycleStateObserver implementation.
void ContextLifecycleStateChanged(mojom::FrameLifecycleState state) override;
String id_;
@@ -186,7 +186,7 @@ class ControllerPresentationConnection final : public PresentationConnection {
const KURL&);
~ControllerPresentationConnection() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 27c7dcd1047..a6dd3e2c47b 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
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/modules/presentation/presentation_connection_available_event.h"
-#include "third_party/blink/renderer/modules/presentation/presentation_connection_available_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_presentation_connection_available_event_init.h"
namespace blink {
@@ -27,7 +27,7 @@ const AtomicString& PresentationConnectionAvailableEvent::InterfaceName()
return event_interface_names::kPresentationConnectionAvailableEvent;
}
-void PresentationConnectionAvailableEvent::Trace(blink::Visitor* visitor) {
+void PresentationConnectionAvailableEvent::Trace(Visitor* visitor) {
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 af32dc82ed8..b5a5a6b7967 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<PresentationConnection> connection_;
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.idl b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.idl
index a692f43867f..4a153f5c5c5 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.idl
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.idl
@@ -5,10 +5,10 @@
// https://w3c.github.io/presentation-api/#interface-presentationconnectionavailableeevent
[
- Constructor(DOMString type, PresentationConnectionAvailableEventInit eventInitDict),
RuntimeEnabled=Presentation,
SecureContext,
Exposed=Window
] interface PresentationConnectionAvailableEvent : Event {
+ constructor(DOMString type, PresentationConnectionAvailableEventInit eventInitDict);
[SameObject] readonly attribute PresentationConnection connection;
};
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 7dc754f4013..7b77fbedf63 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
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/modules/presentation/presentation_connection_close_event.h"
-#include "third_party/blink/renderer/modules/presentation/presentation_connection_close_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_presentation_connection_close_event_init.h"
namespace blink {
@@ -27,7 +27,7 @@ const AtomicString& PresentationConnectionCloseEvent::InterfaceName() const {
return event_interface_names::kPresentationConnectionCloseEvent;
}
-void PresentationConnectionCloseEvent::Trace(blink::Visitor* visitor) {
+void PresentationConnectionCloseEvent::Trace(Visitor* visitor) {
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 e719dd6d0d2..e13f871a531 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
String reason_;
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.idl b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.idl
index c89e56cae42..11eda2ed27e 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.idl
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.idl
@@ -7,11 +7,11 @@
enum PresentationConnectionCloseReason { "error", "closed", "wentaway" };
[
- Constructor(DOMString type, PresentationConnectionCloseEventInit eventInitDict),
RuntimeEnabled=Presentation,
SecureContext,
Exposed=Window
] interface PresentationConnectionCloseEvent : Event {
+ constructor(DOMString type, PresentationConnectionCloseEventInit eventInitDict);
readonly attribute PresentationConnectionCloseReason reason;
readonly attribute DOMString message;
};
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 ef041abcd9d..ba1210de20b 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
@@ -14,7 +14,7 @@ namespace blink {
PresentationConnectionList::PresentationConnectionList(
ExecutionContext* context)
- : ContextClient(context) {}
+ : ExecutionContextClient(context) {}
const AtomicString& PresentationConnectionList::InterfaceName() const {
return event_target_names::kPresentationConnectionList;
@@ -63,10 +63,10 @@ bool PresentationConnectionList::IsEmpty() {
return connections_.IsEmpty();
}
-void PresentationConnectionList::Trace(blink::Visitor* visitor) {
+void PresentationConnectionList::Trace(Visitor* visitor) {
visitor->Trace(connections_);
EventTargetWithInlineData::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 f6d8d8f8275..5405a6c8c8f 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
@@ -18,7 +18,7 @@ namespace blink {
// presentation controllers.
class MODULES_EXPORT PresentationConnectionList final
: public EventTargetWithInlineData,
- public ContextClient {
+ public ExecutionContextClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(PresentationConnectionList);
@@ -29,7 +29,7 @@ class MODULES_EXPORT PresentationConnectionList final
// EventTarget implementation.
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override {
- return ContextClient::GetExecutionContext();
+ return ExecutionContextClient::GetExecutionContext();
}
// PresentationConnectionList.idl implementation.
@@ -43,7 +43,7 @@ class MODULES_EXPORT PresentationConnectionList final
void DispatchConnectionAvailableEvent(PresentationConnection*);
bool IsEmpty();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 1c39732e27d..da33dfb7952 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.cc
@@ -21,7 +21,7 @@ namespace blink {
PresentationController::PresentationController(LocalFrame& frame)
: Supplement<LocalFrame>(frame),
- ContextLifecycleObserver(frame.GetDocument()) {}
+ ExecutionContextLifecycleObserver(frame.GetDocument()) {}
PresentationController::~PresentationController() = default;
@@ -45,19 +45,19 @@ PresentationController* PresentationController::FromContext(
if (!execution_context)
return nullptr;
- Document* document = To<Document>(execution_context);
+ Document* document = Document::From(execution_context);
if (!document->GetFrame())
return nullptr;
return PresentationController::From(*document->GetFrame());
}
-void PresentationController::Trace(blink::Visitor* visitor) {
+void PresentationController::Trace(Visitor* visitor) {
visitor->Trace(presentation_);
visitor->Trace(connections_);
visitor->Trace(availability_state_);
Supplement<LocalFrame>::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
void PresentationController::SetPresentation(Presentation* presentation) {
@@ -132,7 +132,7 @@ void PresentationController::OnDefaultPresentationStarted(
std::move(result->connection_receiver));
}
-void PresentationController::ContextDestroyed(ExecutionContext*) {
+void PresentationController::ContextDestroyed() {
presentation_controller_receiver_.reset();
}
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 0518081b27f..045170d5a74 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.h
@@ -8,9 +8,8 @@
#include "base/macros.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/mojom/presentation/presentation.mojom-blink.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/modules/modules_export.h"
@@ -32,7 +31,7 @@ class PresentationAvailabilityState;
class MODULES_EXPORT PresentationController
: public GarbageCollected<PresentationController>,
public Supplement<LocalFrame>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public mojom::blink::PresentationController {
USING_GARBAGE_COLLECTED_MIXIN(PresentationController);
@@ -49,7 +48,7 @@ class MODULES_EXPORT PresentationController
static PresentationController* FromContext(ExecutionContext*);
// Implementation of Supplement.
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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
@@ -80,8 +79,8 @@ class MODULES_EXPORT PresentationController
virtual void RemoveAvailabilityObserver(PresentationAvailabilityObserver*);
private:
- // Implementation of ContextLifecycleObserver.
- void ContextDestroyed(ExecutionContext*) override;
+ // Implementation of ExecutionContextLifecycleObserver.
+ void ContextDestroyed() override;
// mojom::blink::PresentationController implementation.
void OnScreenAvailabilityUpdated(const KURL&,
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_promise_property.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_promise_property.h
index 9ab4783d508..c9b9c9f1bbf 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_promise_property.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_promise_property.h
@@ -11,11 +11,9 @@
namespace blink {
class PresentationAvailability;
-class PresentationRequest;
using PresentationAvailabilityProperty =
- ScriptPromiseProperty<Member<PresentationRequest>,
- Member<PresentationAvailability>,
+ ScriptPromiseProperty<Member<PresentationAvailability>,
Member<DOMException>>;
} // namespace blink
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 df661cb69b8..69fda328df8 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.cc
@@ -4,7 +4,6 @@
#include "third_party/blink/renderer/modules/presentation/presentation_receiver.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
@@ -25,13 +24,15 @@
namespace blink {
PresentationReceiver::PresentationReceiver(LocalFrame* frame)
- : ContextLifecycleObserver(frame->GetDocument()),
- connection_list_(MakeGarbageCollected<PresentationConnectionList>(
- frame->GetDocument())) {
- frame->GetBrowserInterfaceBroker().GetInterface(
- presentation_service_remote_.BindNewPipeAndPassReceiver());
+ : connection_list_(
+ MakeGarbageCollected<PresentationConnectionList>(frame->DomWindow())),
+ presentation_receiver_receiver_(this, frame->DomWindow()),
+ presentation_service_remote_(frame->DomWindow()),
+ frame_(frame) {
scoped_refptr<base::SingleThreadTaskRunner> task_runner =
frame->GetTaskRunner(TaskType::kPresentation);
+ frame->GetBrowserInterfaceBroker().GetInterface(
+ presentation_service_remote_.BindNewPipeAndPassReceiver(task_runner));
// Set the mojo::Remote<T> that remote implementation of PresentationService
// will use to interact with the associated PresentationReceiver, in order
@@ -53,15 +54,13 @@ PresentationReceiver* PresentationReceiver::From(Document& document) {
}
ScriptPromise PresentationReceiver::connectionList(ScriptState* script_state) {
- ExecutionContext* execution_context = ExecutionContext::From(script_state);
- RecordOriginTypeAccess(*execution_context);
if (!connection_list_property_) {
connection_list_property_ = MakeGarbageCollected<ConnectionListProperty>(
- execution_context, this, ConnectionListProperty::kReady);
+ ExecutionContext::From(script_state));
}
- if (!connection_list_->IsEmpty() && connection_list_property_->GetState() ==
- ScriptPromisePropertyBase::kPending)
+ if (!connection_list_->IsEmpty() &&
+ connection_list_property_->GetState() == ConnectionListProperty::kPending)
connection_list_property_->Resolve(connection_list_);
return connection_list_property_->Promise(script_state->World());
@@ -102,10 +101,10 @@ void PresentationReceiver::OnReceiverConnectionAvailable(
return;
if (connection_list_property_->GetState() ==
- ScriptPromisePropertyBase::kPending) {
+ ConnectionListProperty::kPending) {
connection_list_property_->Resolve(connection_list_);
} else if (connection_list_property_->GetState() ==
- ScriptPromisePropertyBase::kResolved) {
+ ConnectionListProperty::kResolved) {
connection_list_->DispatchConnectionAvailableEvent(connection);
}
}
@@ -116,28 +115,13 @@ void PresentationReceiver::RegisterConnection(
connection_list_->AddConnection(connection);
}
-// static
-void PresentationReceiver::RecordOriginTypeAccess(
- ExecutionContext& execution_context) {
- if (execution_context.IsSecureContext()) {
- UseCounter::Count(&execution_context,
- WebFeature::kPresentationReceiverSecureOrigin);
- } else {
- Deprecation::CountDeprecation(
- &execution_context, WebFeature::kPresentationReceiverInsecureOrigin);
- }
-}
-
-void PresentationReceiver::ContextDestroyed(ExecutionContext*) {
- presentation_receiver_receiver_.reset();
- presentation_service_remote_.reset();
-}
-
-void PresentationReceiver::Trace(blink::Visitor* visitor) {
+void PresentationReceiver::Trace(Visitor* visitor) {
visitor->Trace(connection_list_);
visitor->Trace(connection_list_property_);
+ visitor->Trace(presentation_receiver_receiver_);
+ visitor->Trace(presentation_service_remote_);
+ visitor->Trace(frame_);
ScriptWrappable::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 714eba9559d..964430badff 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.h
@@ -7,17 +7,17 @@
#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/remote.h"
#include "third_party/blink/public/mojom/presentation/presentation.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_property.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
namespace blink {
@@ -31,13 +31,10 @@ class ReceiverPresentationConnection;
// client.
class MODULES_EXPORT PresentationReceiver final
: public ScriptWrappable,
- public ContextLifecycleObserver,
public mojom::blink::PresentationReceiver {
- USING_GARBAGE_COLLECTED_MIXIN(PresentationReceiver);
DEFINE_WRAPPERTYPEINFO();
using ConnectionListProperty =
- ScriptPromiseProperty<Member<PresentationReceiver>,
- Member<PresentationConnectionList>,
+ ScriptPromiseProperty<Member<PresentationConnectionList>,
Member<DOMException>>;
public:
@@ -59,22 +56,23 @@ class MODULES_EXPORT PresentationReceiver final
void RemoveConnection(ReceiverPresentationConnection*);
void Terminate();
- void Trace(blink::Visitor*) override;
+ LocalFrame* GetFrame() const { return frame_; }
+
+ void Trace(Visitor*) override;
private:
friend class PresentationReceiverTest;
static void RecordOriginTypeAccess(ExecutionContext&);
- // ContextLifecycleObserver implementation.
- void ContextDestroyed(ExecutionContext*) override;
-
Member<ConnectionListProperty> connection_list_property_;
Member<PresentationConnectionList> connection_list_;
- mojo::Receiver<mojom::blink::PresentationReceiver>
- presentation_receiver_receiver_{this};
- mojo::Remote<mojom::blink::PresentationService> presentation_service_remote_;
+ HeapMojoReceiver<mojom::blink::PresentationReceiver>
+ presentation_receiver_receiver_;
+ HeapMojoRemote<mojom::blink::PresentationService>
+ presentation_service_remote_;
+ Member<LocalFrame> frame_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver_test.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver_test.cc
index cc6e8a48bbc..7a4f1653784 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver_test.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver_test.cc
@@ -29,11 +29,12 @@ class MockEventListenerForPresentationReceiver : public NativeEventListener {
class PresentationReceiverTest : public testing::Test {
public:
+ using ConnectionListProperty = PresentationReceiver::ConnectionListProperty;
PresentationReceiverTest()
: connection_info_(KURL("https://example.com"), "id") {}
void AddConnectionavailableEventListener(EventListener*,
const PresentationReceiver*);
- void VerifyConnectionListPropertyState(ScriptPromisePropertyBase::State,
+ void VerifyConnectionListPropertyState(ConnectionListProperty::State,
const PresentationReceiver*);
void VerifyConnectionListSize(size_t expected_size,
const PresentationReceiver*);
@@ -65,7 +66,7 @@ void PresentationReceiverTest::AddConnectionavailableEventListener(
}
void PresentationReceiverTest::VerifyConnectionListPropertyState(
- ScriptPromisePropertyBase::State expected_state,
+ ConnectionListProperty::State expected_state,
const PresentationReceiver* receiver) {
EXPECT_EQ(expected_state, receiver->connection_list_property_->GetState());
}
@@ -90,8 +91,7 @@ TEST_F(PresentationReceiverTest, NoConnectionUnresolvedConnectionList) {
receiver->connectionList(scope.GetScriptState());
- VerifyConnectionListPropertyState(ScriptPromisePropertyBase::kPending,
- receiver);
+ VerifyConnectionListPropertyState(ConnectionListProperty::kPending, receiver);
VerifyConnectionListSize(0, receiver);
}
@@ -112,7 +112,7 @@ TEST_F(PresentationReceiverTest, OneConnectionResolvedConnectionListNoEvent) {
connection_info_.Clone(), std::move(controller_connection_),
std::move(receiver_connection_receiver_));
- VerifyConnectionListPropertyState(ScriptPromisePropertyBase::kResolved,
+ VerifyConnectionListPropertyState(ConnectionListProperty::kResolved,
receiver);
VerifyConnectionListSize(1, receiver);
}
@@ -187,7 +187,7 @@ TEST_F(PresentationReceiverTest, TwoConnectionsNoEvent) {
std::move(receiver_connection_receiver_2));
receiver->connectionList(scope.GetScriptState());
- VerifyConnectionListPropertyState(ScriptPromisePropertyBase::kResolved,
+ VerifyConnectionListPropertyState(ConnectionListProperty::kResolved,
receiver);
VerifyConnectionListSize(2, receiver);
}
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 29df8f2c35c..9483efa4d8f 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_request.cc
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_request.cc
@@ -34,7 +34,7 @@ namespace {
Settings* GetSettings(ExecutionContext* execution_context) {
DCHECK(execution_context);
- Document* document = To<Document>(execution_context);
+ Document* document = Document::From(execution_context);
return document->GetSettings();
}
@@ -59,8 +59,9 @@ PresentationRequest* PresentationRequest::Create(
ExecutionContext* execution_context,
const Vector<String>& urls,
ExceptionState& exception_state) {
- if (To<Document>(execution_context)
- ->IsSandboxed(WebSandboxFlags::kPresentationController)) {
+ if (Document::From(execution_context)
+ ->IsSandboxed(
+ mojom::blink::WebSandboxFlags::kPresentationController)) {
exception_state.ThrowSecurityError(
"The document is sandboxed and lacks the 'allow-presentation' flag.");
return nullptr;
@@ -105,7 +106,7 @@ const AtomicString& PresentationRequest::InterfaceName() const {
}
ExecutionContext* PresentationRequest::GetExecutionContext() const {
- return ContextClient::GetExecutionContext();
+ return ExecutionContextClient::GetExecutionContext();
}
void PresentationRequest::AddedEventListener(
@@ -129,35 +130,37 @@ bool PresentationRequest::HasPendingActivity() const {
if (HasEventListeners())
return true;
- return availability_property_ && availability_property_->GetState() ==
- ScriptPromisePropertyBase::kPending;
+ return availability_property_ &&
+ availability_property_->GetState() ==
+ PresentationAvailabilityProperty::kPending;
}
-ScriptPromise PresentationRequest::start(ScriptState* script_state) {
+ScriptPromise PresentationRequest::start(ScriptState* script_state,
+ ExceptionState& exception_state) {
ExecutionContext* execution_context = GetExecutionContext();
Settings* context_settings = GetSettings(execution_context);
- Document* doc = To<Document>(execution_context);
+ Document* doc = Document::From(execution_context);
bool is_user_gesture_required =
!context_settings ||
context_settings->GetPresentationRequiresUserGesture();
if (is_user_gesture_required &&
- !LocalFrame::HasTransientUserActivation(doc->GetFrame()))
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidAccessError,
- "PresentationRequest::start() requires user gesture."));
+ !LocalFrame::HasTransientUserActivation(doc->GetFrame())) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidAccessError,
+ "PresentationRequest::start() requires user gesture.");
+ return ScriptPromise();
+ }
PresentationController* controller =
PresentationController::FromContext(GetExecutionContext());
- if (!controller)
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "The PresentationRequest is no longer associated to a frame."));
+ if (!controller) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "The PresentationRequest is no longer associated to a frame.");
+ return ScriptPromise();
+ }
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -170,15 +173,16 @@ ScriptPromise PresentationRequest::start(ScriptState* script_state) {
}
ScriptPromise PresentationRequest::reconnect(ScriptState* script_state,
- const String& id) {
+ const String& id,
+ ExceptionState& exception_state) {
PresentationController* controller =
PresentationController::FromContext(GetExecutionContext());
- if (!controller)
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "The PresentationRequest is no longer associated to a frame."));
+ if (!controller) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "The PresentationRequest is no longer associated to a frame.");
+ return ScriptPromise();
+ }
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -200,21 +204,22 @@ ScriptPromise PresentationRequest::reconnect(ScriptState* script_state,
return resolver->Promise();
}
-ScriptPromise PresentationRequest::getAvailability(ScriptState* script_state) {
+ScriptPromise PresentationRequest::getAvailability(
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
PresentationController* controller =
PresentationController::FromContext(GetExecutionContext());
- if (!controller)
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "The PresentationRequest is no longer associated to a frame."));
+ if (!controller) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "The PresentationRequest is no longer associated to a frame.");
+ return ScriptPromise();
+ }
if (!availability_property_) {
availability_property_ =
MakeGarbageCollected<PresentationAvailabilityProperty>(
- ExecutionContext::From(script_state), this,
- PresentationAvailabilityProperty::kReady);
+ ExecutionContext::From(script_state));
controller->GetAvailabilityState()->RequestAvailability(
urls_, MakeGarbageCollected<PresentationAvailabilityCallbacks>(
@@ -227,14 +232,14 @@ const Vector<KURL>& PresentationRequest::Urls() const {
return urls_;
}
-void PresentationRequest::Trace(blink::Visitor* visitor) {
+void PresentationRequest::Trace(Visitor* visitor) {
visitor->Trace(availability_property_);
EventTargetWithInlineData::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
PresentationRequest::PresentationRequest(ExecutionContext* execution_context,
const Vector<KURL>& urls)
- : ContextClient(execution_context), urls_(urls) {}
+ : ExecutionContextClient(execution_context), urls_(urls) {}
} // namespace blink
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 3a7015eb374..9d6d944f0bb 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_request.h
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_request.h
@@ -8,7 +8,7 @@
#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/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/presentation/presentation_promise_property.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -18,12 +18,14 @@
namespace blink {
+class ExceptionState;
+
// Implements the PresentationRequest interface from the Presentation API from
// which websites can start or join presentation connections.
class MODULES_EXPORT PresentationRequest final
: public EventTargetWithInlineData,
public ActiveScriptWrappable<PresentationRequest>,
- public ContextClient {
+ public ExecutionContextClient {
USING_GARBAGE_COLLECTED_MIXIN(PresentationRequest);
DEFINE_WRAPPERTYPEINFO();
@@ -45,15 +47,15 @@ class MODULES_EXPORT PresentationRequest final
// ScriptWrappable implementation.
bool HasPendingActivity() const final;
- ScriptPromise start(ScriptState*);
- ScriptPromise reconnect(ScriptState*, const String& id);
- ScriptPromise getAvailability(ScriptState*);
+ ScriptPromise start(ScriptState*, ExceptionState&);
+ ScriptPromise reconnect(ScriptState*, const String& id, ExceptionState&);
+ ScriptPromise getAvailability(ScriptState*, ExceptionState&);
const Vector<KURL>& Urls() const;
DEFINE_ATTRIBUTE_EVENT_LISTENER(connectionavailable, kConnectionavailable)
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
// EventTarget implementation.
diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_request.idl b/chromium/third_party/blink/renderer/modules/presentation/presentation_request.idl
index 82299190a1b..87f5b447836 100644
--- a/chromium/third_party/blink/renderer/modules/presentation/presentation_request.idl
+++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_request.idl
@@ -6,18 +6,15 @@
[
ActiveScriptWrappable,
- ConstructorCallWith=ExecutionContext,
- Constructor(USVString url),
- Constructor(sequence<USVString> urls),
- MeasureAs=PresentationRequestConstructor,
- RaisesException=Constructor,
RuntimeEnabled=Presentation,
SecureContext,
Exposed=Window
] interface PresentationRequest : EventTarget {
- [CallWith=ScriptState, MeasureAs=PresentationRequestStart] Promise<PresentationConnection> start();
- [CallWith=ScriptState, MeasureAs=PresentationRequestReconnect] Promise<PresentationConnection> reconnect(DOMString id);
- [CallWith=ScriptState, MeasureAs=PresentationRequestGetAvailability] Promise<PresentationAvailability> getAvailability();
+ [CallWith=ExecutionContext, RaisesException, MeasureAs=PresentationRequestConstructor] constructor(USVString url);
+ [CallWith=ExecutionContext, RaisesException, MeasureAs=PresentationRequestConstructor] constructor(sequence<USVString> urls);
+ [CallWith=ScriptState, RaisesException, MeasureAs=PresentationRequestStart] Promise<PresentationConnection> start();
+ [CallWith=ScriptState, RaisesException, MeasureAs=PresentationRequestReconnect] Promise<PresentationConnection> reconnect(DOMString id);
+ [CallWith=ScriptState, RaisesException, MeasureAs=PresentationRequestGetAvailability] Promise<PresentationAvailability> getAvailability();
attribute EventHandler onconnectionavailable;
};
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/BUILD.gn b/chromium/third_party/blink/renderer/modules/push_messaging/BUILD.gn
index 7005dd419fa..fc787d57c6d 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/BUILD.gn
@@ -18,8 +18,6 @@ blink_modules_sources("push_messaging") {
"push_messaging_bridge.h",
"push_messaging_client.cc",
"push_messaging_client.h",
- "push_messaging_type_converters.cc",
- "push_messaging_type_converters.h",
"push_messaging_utils.cc",
"push_messaging_utils.h",
"push_provider.cc",
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/idls.gni b/chromium/third_party/blink/renderer/modules/push_messaging/idls.gni
new file mode 100644
index 00000000000..3b3cdced712
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/idls.gni
@@ -0,0 +1,23 @@
+# 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 = [
+ "push_event.idl",
+ "push_manager.idl",
+ "push_message_data.idl",
+ "push_subscription.idl",
+ "push_subscription_change_event.idl",
+ "push_subscription_options.idl",
+]
+
+modules_dictionary_idl_files = [
+ "push_event_init.idl",
+ "push_subscription_change_event_init.idl",
+ "push_subscription_options_init.idl",
+]
+
+modules_dependency_idl_files = [
+ "service_worker_global_scope_push.idl",
+ "service_worker_registration_push.idl",
+]
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 8353a24cd4c..b2e685968b3 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
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/modules/push_messaging/push_event.h"
-#include "third_party/blink/renderer/modules/push_messaging/push_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_push_event_init.h"
namespace blink {
@@ -14,10 +14,28 @@ PushEvent::PushEvent(const AtomicString& type,
: ExtendableEvent(type, ExtendableEventInit::Create(), observer),
data_(data) {}
-PushEvent::PushEvent(const AtomicString& type, const PushEventInit* initializer)
+PushEvent::PushEvent(const AtomicString& type,
+ const PushEventInit* initializer,
+ ExceptionState& exception_state)
: ExtendableEvent(type, initializer) {
- if (initializer->hasData())
+ if (initializer->hasData()) {
+ const ArrayBufferOrArrayBufferViewOrUSVString& message_data =
+ initializer->data();
+ if (message_data.IsArrayBuffer() || message_data.IsArrayBufferView()) {
+ DOMArrayBuffer* buffer =
+ message_data.IsArrayBufferView()
+ ? message_data.GetAsArrayBufferView().View()->buffer()
+ : message_data.GetAsArrayBuffer();
+ if (!base::CheckedNumeric<uint32_t>(buffer->ByteLengthAsSizeT())
+ .IsValid()) {
+ exception_state.ThrowRangeError(
+ "The provided ArrayBuffer exceeds the maximum supported size "
+ "(4294967295)");
+ return;
+ }
+ }
data_ = PushMessageData::Create(initializer->data());
+ }
}
PushEvent::~PushEvent() = default;
@@ -30,7 +48,7 @@ PushMessageData* PushEvent::data() {
return data_.Get();
}
-void PushEvent::Trace(blink::Visitor* visitor) {
+void PushEvent::Trace(Visitor* visitor) {
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 296a1db0828..82a2005933c 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
@@ -27,14 +27,17 @@ class MODULES_EXPORT PushEvent final : public ExtendableEvent {
return MakeGarbageCollected<PushEvent>(type, data, observer);
}
static PushEvent* Create(const AtomicString& type,
- const PushEventInit* initializer) {
- return MakeGarbageCollected<PushEvent>(type, initializer);
+ const PushEventInit* initializer,
+ ExceptionState& exception_state) {
+ return MakeGarbageCollected<PushEvent>(type, initializer, exception_state);
}
PushEvent(const AtomicString& type,
PushMessageData* data,
WaitUntilObserver* observer);
- PushEvent(const AtomicString& type, const PushEventInit* initializer);
+ PushEvent(const AtomicString& type,
+ const PushEventInit* initializer,
+ ExceptionState& exception_state);
~PushEvent() override;
// ExtendableEvent interface.
@@ -42,7 +45,7 @@ class MODULES_EXPORT PushEvent final : public ExtendableEvent {
PushMessageData* data();
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
Member<PushMessageData> data_;
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_event.idl b/chromium/third_party/blink/renderer/modules/push_messaging/push_event.idl
index 1b24a32233b..c4fb82b7a10 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_event.idl
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_event.idl
@@ -5,9 +5,9 @@
// https://w3c.github.io/push-api/#pushevent-interface
[
- Constructor(DOMString type, optional PushEventInit eventInitDict),
Exposed=ServiceWorker,
RuntimeEnabled=PushMessaging
] interface PushEvent : ExtendableEvent {
+ [RaisesException] constructor(DOMString type, optional PushEventInit eventInitDict = {});
readonly attribute 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 00bbef9f62b..36459f8ca8a 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
@@ -9,6 +9,7 @@
#include "base/memory/scoped_refptr.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_push_subscription_options_init.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"
@@ -22,8 +23,8 @@
#include "third_party/blink/renderer/modules/push_messaging/push_subscription.h"
#include "third_party/blink/renderer/modules/push_messaging/push_subscription_callbacks.h"
#include "third_party/blink/renderer/modules/push_messaging/push_subscription_options.h"
-#include "third_party/blink/renderer/modules/push_messaging/push_subscription_options_init.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_registration.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/heap/heap.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
@@ -51,15 +52,29 @@ Vector<String> PushManager::supportedContentEncodings() {
return Vector<String>({"aes128gcm", "aesgcm"});
}
+namespace {
+bool ValidateOptions(blink::PushSubscriptionOptions* options,
+ ExceptionState& exception_state) {
+ DOMArrayBuffer* buffer = options->applicationServerKey();
+ if (!base::CheckedNumeric<wtf_size_t>(buffer->ByteLengthAsSizeT())
+ .IsValid()) {
+ exception_state.ThrowRangeError(
+ "ApplicationServerKey size exceeded the maximum supported size");
+ return false;
+ }
+ return true;
+}
+} // namespace
+
ScriptPromise PushManager::subscribe(
ScriptState* script_state,
const PushSubscriptionOptionsInit* options_init,
ExceptionState& exception_state) {
if (!registration_->active()) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kAbortError,
- "Subscription failed - no active Service Worker"));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kAbortError,
+ "Subscription failed - no active Service Worker");
+ return ScriptPromise();
}
PushSubscriptionOptions* options =
@@ -67,15 +82,8 @@ ScriptPromise PushManager::subscribe(
if (exception_state.HadException())
return ScriptPromise();
- if (!options->IsApplicationServerKeyVapid()) {
- ExecutionContext::From(script_state)
- ->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning,
- "The provided application server key is not a VAPID key. Only "
- "VAPID keys will be supported in the future. For more information "
- "check https://crbug.com/979235."));
- }
+ if (!ValidateOptions(options, exception_state))
+ return ScriptPromise();
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
@@ -84,13 +92,12 @@ ScriptPromise PushManager::subscribe(
// user for permission to use the Push API. The embedder should persist the
// permission so that later calls in different contexts can succeed.
if (auto* document =
- DynamicTo<Document>(ExecutionContext::From(script_state))) {
+ Document::DynamicFrom(ExecutionContext::From(script_state))) {
LocalFrame* frame = document->GetFrame();
if (!document->domWindow() || !frame) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "Document is detached from window."));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Document is detached from window.");
+ return ScriptPromise();
}
PushMessagingClient* messaging_client = PushMessagingClient::From(frame);
@@ -124,12 +131,11 @@ ScriptPromise PushManager::permissionState(
const PushSubscriptionOptionsInit* options,
ExceptionState& exception_state) {
if (auto* document =
- DynamicTo<Document>(ExecutionContext::From(script_state))) {
+ Document::DynamicFrom(ExecutionContext::From(script_state))) {
if (!document->domWindow() || !document->GetFrame()) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "Document is detached from window."));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Document is detached from window.");
+ return ScriptPromise();
}
}
@@ -137,7 +143,7 @@ ScriptPromise PushManager::permissionState(
->GetPermissionState(script_state, options);
}
-void PushManager::Trace(blink::Visitor* visitor) {
+void PushManager::Trace(Visitor* visitor) {
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 b22a00789f7..c66927e8347 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
@@ -21,10 +21,6 @@ class MODULES_EXPORT PushManager final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- static PushManager* Create(ServiceWorkerRegistration* registration) {
- return MakeGarbageCollected<PushManager>(registration);
- }
-
explicit PushManager(ServiceWorkerRegistration* registration);
// Web-exposed property:
@@ -39,7 +35,7 @@ class MODULES_EXPORT PushManager final : public ScriptWrappable {
const PushSubscriptionOptionsInit* options,
ExceptionState& exception_state);
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
Member<ServiceWorkerRegistration> registration_;
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.idl b/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.idl
index 734a7463df8..ede1aa2fc7f 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.idl
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.idl
@@ -11,9 +11,9 @@
[SameObject, SaveSameObject]
static readonly attribute FrozenArray<DOMString> supportedContentEncodings;
- [CallWith=ScriptState, RaisesException] Promise<PushSubscription> subscribe(optional PushSubscriptionOptionsInit options);
+ [CallWith=ScriptState, RaisesException] Promise<PushSubscription> subscribe(optional PushSubscriptionOptionsInit options = {});
[CallWith=ScriptState] Promise<PushSubscription?> getSubscription();
- [CallWith=ScriptState, RaisesException] Promise<PushPermissionState> permissionState(optional PushSubscriptionOptionsInit options);
+ [CallWith=ScriptState, RaisesException] Promise<PushPermissionState> permissionState(optional PushSubscriptionOptionsInit options = {});
};
enum PushPermissionState {
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_manager_test.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_manager_test.cc
index cfb1899e86a..3add888414a 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_manager_test.cc
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_manager_test.cc
@@ -5,9 +5,9 @@
#include "third_party/blink/renderer/modules/push_messaging/push_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_push_subscription_options_init.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/modules/push_messaging/push_subscription_options.h"
-#include "third_party/blink/renderer/modules/push_messaging/push_subscription_options_init.h"
#include "third_party/blink/renderer/platform/wtf/text/base64.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -35,12 +35,13 @@ void IsApplicationServerKeyValid(PushSubscriptionOptions* output) {
sender_key[i] = kApplicationServerKey[i];
sender_key[kApplicationServerKeyLength] = 0x0;
+ ASSERT_EQ(output->applicationServerKey()->ByteLengthAsSizeT(),
+ kApplicationServerKeyLength);
+
String application_server_key(
reinterpret_cast<const char*>(output->applicationServerKey()->Data()),
- output->applicationServerKey()->DeprecatedByteLengthAsUnsigned());
-
- ASSERT_EQ(output->applicationServerKey()->DeprecatedByteLengthAsUnsigned(),
- kApplicationServerKeyLength);
+ static_cast<unsigned>(
+ output->applicationServerKey()->ByteLengthAsSizeT()));
ASSERT_EQ(reinterpret_cast<const char*>(sender_key),
application_server_key.Latin1());
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_message_data.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_message_data.cc
index 42c9a0efc5a..f841beb2ea3 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_message_data.cc
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_message_data.cc
@@ -40,7 +40,7 @@ PushMessageData* PushMessageData::Create(
return MakeGarbageCollected<PushMessageData>(
static_cast<const char*>(buffer->Data()),
- buffer->DeprecatedByteLengthAsUnsigned());
+ base::checked_cast<wtf_size_t>(buffer->ByteLengthAsSizeT()));
}
if (message_data.IsUSVString()) {
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 ae69d79146f..83f0cef88c9 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
@@ -4,9 +4,9 @@
#include "third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_push_subscription_options_init.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/modules/permissions/permission_utils.h"
-#include "third_party/blink/renderer/modules/push_messaging/push_subscription_options_init.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/wtf/functional.h"
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 273922bd9a0..912aec0fa75 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
@@ -13,10 +13,10 @@
#include "third_party/blink/public/platform/platform.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_client.h"
#include "third_party/blink/renderer/modules/manifest/manifest_manager.h"
#include "third_party/blink/renderer/modules/push_messaging/push_error.h"
-#include "third_party/blink/renderer/modules/push_messaging/push_messaging_type_converters.h"
#include "third_party/blink/renderer/modules/push_messaging/push_messaging_utils.h"
#include "third_party/blink/renderer/modules/push_messaging/push_subscription.h"
#include "third_party/blink/renderer/modules/push_messaging/push_subscription_options.h"
@@ -31,7 +31,8 @@ namespace blink {
const char PushMessagingClient::kSupplementName[] = "PushMessagingClient";
PushMessagingClient::PushMessagingClient(LocalFrame& frame)
- : Supplement<LocalFrame>(frame) {
+ : Supplement<LocalFrame>(frame),
+ push_messaging_manager_(frame.DomWindow()) {
// This class will be instantiated for every page load (rather than on push
// messaging use), so there's nothing to be done in this constructor.
}
@@ -43,7 +44,7 @@ PushMessagingClient* PushMessagingClient::From(LocalFrame* frame) {
}
mojom::blink::PushMessaging* PushMessagingClient::GetPushMessagingRemote() {
- if (!push_messaging_manager_) {
+ if (!push_messaging_manager_.is_bound()) {
GetSupplementable()->GetBrowserInterfaceBroker().GetInterface(
push_messaging_manager_.BindNewPipeAndPassReceiver(
GetSupplementable()->GetTaskRunner(TaskType::kMiscPlatformAPI)));
@@ -60,7 +61,7 @@ void PushMessagingClient::Subscribe(
DCHECK(callbacks);
mojom::blink::PushSubscriptionOptionsPtr options_ptr =
- mojom::blink::PushSubscriptionOptions::From(options);
+ ConvertSubscriptionOptionPointer(options);
// If a developer provided an application server key in |options|, skip
// fetching the manifest.
@@ -77,6 +78,11 @@ void PushMessagingClient::Subscribe(
}
}
+void PushMessagingClient::Trace(Visitor* visitor) {
+ Supplement<LocalFrame>::Trace(visitor);
+ visitor->Trace(push_messaging_manager_);
+}
+
void PushMessagingClient::DidGetManifest(
ServiceWorkerRegistration* service_worker_registration,
mojom::blink::PushSubscriptionOptionsPtr options,
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 dab40d00c38..7457e705b35 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
@@ -9,11 +9,12 @@
#include <memory>
#include "base/macros.h"
-#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/manifest/manifest.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/push_messaging/push_messaging.mojom-blink.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/modules/push_messaging/push_subscription_callbacks.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 {
@@ -42,6 +43,7 @@ class PushMessagingClient final : public GarbageCollected<PushMessagingClient>,
PushSubscriptionOptions* options,
bool user_gesture,
std::unique_ptr<PushSubscriptionCallbacks> callbacks);
+ void Trace(Visitor*) override;
private:
// Returns an initialized PushMessaging service. A connection will be
@@ -65,7 +67,9 @@ class PushMessagingClient final : public GarbageCollected<PushMessagingClient>,
mojom::blink::PushRegistrationStatus status,
mojom::blink::PushSubscriptionPtr subscription);
- mojo::Remote<mojom::blink::PushMessaging> push_messaging_manager_;
+ HeapMojoRemote<mojom::blink::PushMessaging,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ push_messaging_manager_;
DISALLOW_COPY_AND_ASSIGN(PushMessagingClient);
};
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_type_converters.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_type_converters.cc
deleted file mode 100644
index 9452bd7648f..00000000000
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_type_converters.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/modules/push_messaging/push_messaging_type_converters.h"
-
-#include <string>
-#include <utility>
-
-#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
-#include "third_party/blink/renderer/modules/push_messaging/push_subscription_options.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
-
-namespace mojo {
-
-blink::mojom::blink::PushSubscriptionOptionsPtr TypeConverter<
- blink::mojom::blink::PushSubscriptionOptionsPtr,
- blink::PushSubscriptionOptions*>::Convert(blink::PushSubscriptionOptions*
- input) {
- Vector<uint8_t> application_server_key;
- application_server_key.Append(
- reinterpret_cast<uint8_t*>(input->applicationServerKey()->Data()),
- input->applicationServerKey()->DeprecatedByteLengthAsUnsigned());
-
- return blink::mojom::blink::PushSubscriptionOptions::New(
- input->userVisibleOnly(), application_server_key);
-}
-
-} // namespace mojo
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_type_converters.h b/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_type_converters.h
deleted file mode 100644
index aa1d5597c29..00000000000
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_type_converters.h
+++ /dev/null
@@ -1,26 +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_PUSH_MESSAGING_PUSH_MESSAGING_TYPE_CONVERTERS_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_PUSH_MESSAGING_PUSH_MESSAGING_TYPE_CONVERTERS_H_
-
-#include "third_party/blink/public/mojom/push_messaging/push_messaging.mojom-blink.h"
-#include "third_party/blink/renderer/modules/modules_export.h"
-
-namespace blink {
-class PushSubscriptionOptions;
-} // namespace blink
-
-namespace mojo {
-
-template <>
-struct TypeConverter<blink::mojom::blink::PushSubscriptionOptionsPtr,
- blink::PushSubscriptionOptions*> {
- static blink::mojom::blink::PushSubscriptionOptionsPtr Convert(
- blink::PushSubscriptionOptions* input);
-};
-
-} // namespace mojo
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PUSH_MESSAGING_PUSH_MESSAGING_TYPE_CONVERTERS_H_
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_utils.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_utils.cc
index fe7845b5197..f2faaa53de6 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_utils.cc
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_utils.cc
@@ -4,8 +4,10 @@
#include "third_party/blink/renderer/modules/push_messaging/push_messaging_utils.h"
-#include "third_party/blink/public/mojom/push_messaging/push_messaging.mojom-blink.h"
#include "third_party/blink/public/mojom/push_messaging/push_messaging_status.mojom-blink.h"
+#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
+#include "third_party/blink/renderer/modules/push_messaging/push_subscription_options.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
@@ -66,6 +68,10 @@ String PushRegistrationStatusToString(mojom::PushRegistrationStatus status) {
case mojom::PushRegistrationStatus::RENDERER_SHUTDOWN:
return "Registration failed - renderer shutdown";
+
+ case mojom::PushRegistrationStatus::UNSUPPORTED_GCM_SENDER_ID:
+ return "Registration failed - GCM Sender IDs are no longer supported, "
+ "please upgrade to VAPID authentication instead";
}
NOTREACHED();
return String();
@@ -97,10 +103,25 @@ mojom::PushErrorType PushRegistrationStatusToPushErrorType(
case mojom::PushRegistrationStatus::MANIFEST_EMPTY_OR_MISSING:
case mojom::PushRegistrationStatus::STORAGE_CORRUPT:
case mojom::PushRegistrationStatus::RENDERER_SHUTDOWN:
+ case mojom::PushRegistrationStatus::UNSUPPORTED_GCM_SENDER_ID:
error_type = mojom::PushErrorType::ABORT;
break;
}
return error_type;
}
+blink::mojom::blink::PushSubscriptionOptionsPtr
+ConvertSubscriptionOptionPointer(blink::PushSubscriptionOptions* input) {
+ Vector<uint8_t> application_server_key;
+ // The checked_cast here guarantees that the input buffer fits into the
+ // result buffer.
+ application_server_key.Append(
+ reinterpret_cast<uint8_t*>(input->applicationServerKey()->Data()),
+ base::checked_cast<wtf_size_t>(
+ input->applicationServerKey()->ByteLengthAsSizeT()));
+
+ return blink::mojom::blink::PushSubscriptionOptions::New(
+ input->userVisibleOnly(), application_server_key);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_utils.h b/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_utils.h
index eb86fe7d140..9fbe147fef7 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_utils.h
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_utils.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PUSH_MESSAGING_PUSH_MESSAGING_UTILS_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PUSH_MESSAGING_PUSH_MESSAGING_UTILS_H_
+#include "third_party/blink/public/mojom/push_messaging/push_messaging.mojom-blink.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -14,12 +15,21 @@ enum class PushErrorType;
enum class PushRegistrationStatus;
} // namespace mojom
+class PushSubscriptionOptions;
+
WTF::String PushRegistrationStatusToString(
mojom::PushRegistrationStatus status);
mojom::PushErrorType PushRegistrationStatusToPushErrorType(
mojom::PushRegistrationStatus status);
+// Converts a {blink::PushSubscriptionOptions} object into a
+// {blink::mojom::blink::PushSubscriptionOptions} object. Since the buffer of
+// the former may be bigger than the capacity of the latter, a caller of this
+// function has to guarantee that the ByteLength of the input buffer fits into
+// {wtf_size_t} range.
+blink::mojom::blink::PushSubscriptionOptionsPtr
+ConvertSubscriptionOptionPointer(blink::PushSubscriptionOptions* input);
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PUSH_MESSAGING_PUSH_MESSAGING_UTILS_H_
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 f487a394e78..082166dcc12 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
@@ -6,11 +6,10 @@
#include <utility>
+#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/push_messaging/push_messaging_status.mojom-blink.h"
-#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/modules/push_messaging/push_error.h"
-#include "third_party/blink/renderer/modules/push_messaging/push_messaging_type_converters.h"
#include "third_party/blink/renderer/modules/push_messaging/push_messaging_utils.h"
#include "third_party/blink/renderer/modules/push_messaging/push_subscription.h"
#include "third_party/blink/renderer/modules/push_messaging/push_subscription_options.h"
@@ -43,7 +42,7 @@ PushProvider* PushProvider::From(ServiceWorkerRegistration* registration) {
// static
mojom::blink::PushMessaging* PushProvider::GetPushMessagingRemote() {
if (!push_messaging_manager_) {
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
push_messaging_manager_.BindNewPipeAndPassReceiver());
}
@@ -57,7 +56,7 @@ void PushProvider::Subscribe(
DCHECK(callbacks);
mojom::blink::PushSubscriptionOptionsPtr content_options_ptr =
- mojom::blink::PushSubscriptionOptions::From(options);
+ ConvertSubscriptionOptionPointer(options);
GetPushMessagingRemote()->Subscribe(
GetSupplementable()->RegistrationId(), std::move(content_options_ptr),
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 afadd498aa0..1876628f017 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
@@ -13,6 +13,7 @@
#include "third_party/blink/renderer/modules/push_messaging/push_provider.h"
#include "third_party/blink/renderer/modules/push_messaging/push_subscription_options.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_registration.h"
+#include "third_party/blink/renderer/platform/heap/heap.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/std_lib_extras.h"
@@ -26,8 +27,11 @@ namespace {
// This method and its dependencies must remain constant time, thus not branch
// based on the value of |buffer| while encoding, assuming a known length.
String ToBase64URLWithoutPadding(DOMArrayBuffer* buffer) {
- String value = WTF::Base64URLEncode(static_cast<const char*>(buffer->Data()),
- buffer->DeprecatedByteLengthAsUnsigned());
+ String value = WTF::Base64URLEncode(
+ static_cast<const char*>(buffer->Data()),
+ // The size of {buffer} should always fit into into {wtf_size_t}, because
+ // the buffer content itself origins from a WTF::Vector.
+ base::checked_cast<wtf_size_t>(buffer->ByteLengthAsSizeT()));
DCHECK_GT(value.length(), 0u);
unsigned padding_to_remove = 0;
@@ -65,8 +69,9 @@ PushSubscription::PushSubscription(
const WTF::Vector<unsigned char>& auth,
ServiceWorkerRegistration* service_worker_registration)
: endpoint_(endpoint),
- options_(PushSubscriptionOptions::Create(user_visible_only,
- application_server_key)),
+ options_(MakeGarbageCollected<PushSubscriptionOptions>(
+ user_visible_only,
+ application_server_key)),
p256dh_(DOMArrayBuffer::Create(p256dh.data(),
SafeCast<unsigned>(p256dh.size()))),
auth_(
@@ -75,6 +80,13 @@ PushSubscription::PushSubscription(
PushSubscription::~PushSubscription() = default;
+base::Optional<DOMTimeStamp> PushSubscription::expirationTime() const {
+ // This attribute reflects the time at which the subscription will expire,
+ // which is not relevant to this implementation yet as subscription refreshes
+ // are not supported.
+ return base::nullopt;
+}
+
DOMTimeStamp PushSubscription::expirationTime(bool& out_is_null) const {
// This attribute reflects the time at which the subscription will expire,
// which is not relevant to this implementation yet as subscription refreshes
@@ -121,7 +133,7 @@ ScriptValue PushSubscription::toJSONForBinding(ScriptState* script_state) {
return result.GetScriptValue();
}
-void PushSubscription::Trace(blink::Visitor* visitor) {
+void PushSubscription::Trace(Visitor* visitor) {
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 8098e52b8ff..70d0e6e205a 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
@@ -43,7 +43,9 @@ class MODULES_EXPORT PushSubscription final : public ScriptWrappable {
~PushSubscription() override;
KURL endpoint() const { return endpoint_; }
- DOMTimeStamp expirationTime(bool& out_is_null) const;
+ base::Optional<DOMTimeStamp> expirationTime() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ DOMTimeStamp expirationTime(bool& out_is_null) const; // DEPRECATED
PushSubscriptionOptions* options() const { return options_.Get(); }
@@ -52,7 +54,7 @@ class MODULES_EXPORT PushSubscription final : public ScriptWrappable {
ScriptValue toJSONForBinding(ScriptState* script_state);
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) 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 86e6bf9c19f..a152970b08c 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
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.h"
-#include "third_party/blink/renderer/modules/push_messaging/push_subscription_change_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_push_subscription_change_event_init.h"
namespace blink {
@@ -37,7 +37,7 @@ PushSubscription* PushSubscriptionChangeEvent::oldSubscription() const {
return old_subscription_;
}
-void PushSubscriptionChangeEvent::Trace(blink::Visitor* visitor) {
+void PushSubscriptionChangeEvent::Trace(Visitor* visitor) {
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 58895ad1fdb..0eb9214c71e 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(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
Member<PushSubscription> new_subscription_;
diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.idl b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.idl
index 0c64c45c229..beb21f142ff 100644
--- a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.idl
+++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.idl
@@ -5,10 +5,10 @@
// https://w3c.github.io/push-api/#pushsubscriptionchangeevent-interface
[
- Constructor(DOMString type, optional PushSubscriptionChangeEventInit eventInitDict),
Exposed=ServiceWorker,
RuntimeEnabled=PushMessagingSubscriptionChange
] interface PushSubscriptionChangeEvent : ExtendableEvent {
+ constructor(DOMString type, optional PushSubscriptionChangeEventInit eventInitDict = {});
readonly attribute PushSubscription? newSubscription;
readonly attribute PushSubscription? oldSubscription;
-}; \ No newline at end of file
+};
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 ad43b565d9e..144d0749396 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
@@ -4,8 +4,9 @@
#include "third_party/blink/renderer/modules/push_messaging/push_subscription_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/array_buffer_or_array_buffer_view_or_string.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_push_subscription_options_init.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
-#include "third_party/blink/renderer/modules/push_messaging/push_subscription_options_init.h"
#include "third_party/blink/renderer/platform/bindings/exception_code.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
@@ -22,7 +23,7 @@ Vector<uint8_t> BufferSourceToVector(
const ArrayBufferOrArrayBufferViewOrString& application_server_key,
ExceptionState& exception_state) {
char* input;
- int length;
+ size_t length;
Vector<char> decoded_application_server_key;
Vector<uint8_t> result;
@@ -30,15 +31,14 @@ Vector<uint8_t> BufferSourceToVector(
if (application_server_key.IsArrayBuffer()) {
input =
static_cast<char*>(application_server_key.GetAsArrayBuffer()->Data());
- length = application_server_key.GetAsArrayBuffer()
- ->DeprecatedByteLengthAsUnsigned();
+ length = application_server_key.GetAsArrayBuffer()->ByteLengthAsSizeT();
} else if (application_server_key.IsArrayBufferView()) {
input = static_cast<char*>(
application_server_key.GetAsArrayBufferView().View()->buffer()->Data());
length = application_server_key.GetAsArrayBufferView()
.View()
->buffer()
- ->DeprecatedByteLengthAsUnsigned();
+ ->ByteLengthAsSizeT();
} else if (application_server_key.IsString()) {
if (!Base64UnpaddedURLDecode(application_server_key.GetAsString(),
decoded_application_server_key)) {
@@ -65,7 +65,7 @@ Vector<uint8_t> BufferSourceToVector(
input + length);
if (is_vapid || is_sender_id) {
- result.Append(input, length);
+ result.Append(input, static_cast<wtf_size_t>(length));
} else {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidAccessError,
@@ -99,14 +99,7 @@ PushSubscriptionOptions::PushSubscriptionOptions(
application_server_key.data(),
SafeCast<unsigned>(application_server_key.size()))) {}
-bool PushSubscriptionOptions::IsApplicationServerKeyVapid() const {
- if (!application_server_key_)
- return false;
- return application_server_key_->ByteLengthAsSizeT() == 65 &&
- static_cast<uint8_t*>(application_server_key_->Data())[0] == 0x04;
-}
-
-void PushSubscriptionOptions::Trace(blink::Visitor* visitor) {
+void PushSubscriptionOptions::Trace(Visitor* visitor) {
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 3907c3643d9..99d5467d204 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
@@ -26,13 +26,6 @@ class PushSubscriptionOptions final : public ScriptWrappable {
const PushSubscriptionOptionsInit* options_init,
ExceptionState& exception_state);
- static PushSubscriptionOptions* Create(
- bool user_visible_only,
- const WTF::Vector<uint8_t>& application_server_key) {
- return MakeGarbageCollected<PushSubscriptionOptions>(
- user_visible_only, application_server_key);
- }
-
explicit PushSubscriptionOptions(
bool user_visible_only,
const WTF::Vector<uint8_t>& application_server_key);
@@ -44,10 +37,7 @@ class PushSubscriptionOptions final : public ScriptWrappable {
return application_server_key_;
}
- // Whether the application server key follows the VAPID protocol.
- bool IsApplicationServerKeyVapid() const;
-
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) 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 25eb7810a74..2977148f2a3 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
@@ -6,6 +6,7 @@
#include "third_party/blink/renderer/modules/push_messaging/push_manager.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_registration.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
@@ -38,11 +39,11 @@ PushManager* ServiceWorkerRegistrationPush::pushManager(
PushManager* ServiceWorkerRegistrationPush::pushManager() {
if (!push_manager_)
- push_manager_ = PushManager::Create(registration_);
+ push_manager_ = MakeGarbageCollected<PushManager>(registration_);
return push_manager_.Get();
}
-void ServiceWorkerRegistrationPush::Trace(blink::Visitor* visitor) {
+void ServiceWorkerRegistrationPush::Trace(Visitor* visitor) {
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 1c72a139be0..aa8c1293c69 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(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) 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 b02c623aa3f..44235d9feca 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
@@ -106,7 +106,7 @@ DeprecatedStorageQuota* DeprecatedStorageInfo::GetStorageQuota(
return nullptr;
}
-void DeprecatedStorageInfo::Trace(blink::Visitor* visitor) {
+void DeprecatedStorageInfo::Trace(Visitor* visitor) {
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 2d75ef57b16..b981528176c 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,7 +65,7 @@ class DeprecatedStorageInfo final : public ScriptWrappable {
V8StorageQuotaCallback* = nullptr,
V8StorageErrorCallback* = nullptr);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
DeprecatedStorageQuota* GetStorageQuota(int storage_type);
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 b0f3b0a75d5..44e2bffdd55 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
@@ -35,6 +35,7 @@
#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/v8_storage_error_callback.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_storage_estimate.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_storage_quota_callback.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_storage_usage_callback.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -42,7 +43,6 @@
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/modules/quota/dom_error.h"
#include "third_party/blink/renderer/modules/quota/quota_utils.h"
-#include "third_party/blink/renderer/modules/quota/storage_estimate.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -51,7 +51,7 @@
namespace blink {
-using mojom::StorageType;
+using mojom::blink::StorageType;
using mojom::blink::UsageBreakdownPtr;
namespace {
@@ -70,11 +70,11 @@ StorageType GetStorageType(DeprecatedStorageQuota::Type type) {
void DeprecatedQueryStorageUsageAndQuotaCallback(
V8StorageUsageCallback* success_callback,
V8StorageErrorCallback* error_callback,
- mojom::QuotaStatusCode status_code,
+ mojom::blink::QuotaStatusCode status_code,
int64_t usage_in_bytes,
int64_t quota_in_bytes,
UsageBreakdownPtr usage_breakdown) {
- if (status_code != mojom::QuotaStatusCode::kOk) {
+ if (status_code != mojom::blink::QuotaStatusCode::kOk) {
if (error_callback) {
error_callback->InvokeAndReportException(nullptr,
DOMError::Create(status_code));
@@ -90,10 +90,10 @@ void DeprecatedQueryStorageUsageAndQuotaCallback(
void RequestStorageQuotaCallback(V8StorageQuotaCallback* success_callback,
V8StorageErrorCallback* error_callback,
- mojom::QuotaStatusCode status_code,
+ mojom::blink::QuotaStatusCode status_code,
int64_t usage_in_bytes,
int64_t granted_quota_in_bytes) {
- if (status_code != mojom::QuotaStatusCode::kOk) {
+ if (status_code != mojom::blink::QuotaStatusCode::kOk) {
if (error_callback) {
error_callback->InvokeAndReportException(nullptr,
DOMError::Create(status_code));
@@ -158,10 +158,10 @@ void DeprecatedStorageQuota::queryUsageAndQuota(
WrapPersistent(error_callback));
GetQuotaHost(execution_context)
->QueryStorageUsageAndQuota(
- WrapRefCounted(security_origin), storage_type,
+ storage_type,
mojo::WrapCallbackWithDefaultInvokeIfNotRun(
- std::move(callback), mojom::QuotaStatusCode::kErrorAbort, 0, 0,
- nullptr));
+ std::move(callback), mojom::blink::QuotaStatusCode::kErrorAbort,
+ 0, 0, nullptr));
}
void DeprecatedStorageQuota::requestQuota(
@@ -187,25 +187,26 @@ void DeprecatedStorageQuota::requestQuota(
WTF::Bind(&RequestStorageQuotaCallback, WrapPersistent(success_callback),
WrapPersistent(error_callback));
- Document& document = To<Document>(*execution_context);
+ Document& document = Document::From(*execution_context);
const SecurityOrigin* security_origin = document.GetSecurityOrigin();
if (security_origin->IsOpaque()) {
// Unique origins cannot store persistent state.
- std::move(callback).Run(blink::mojom::QuotaStatusCode::kErrorAbort, 0, 0);
+ std::move(callback).Run(mojom::blink::QuotaStatusCode::kErrorAbort, 0, 0);
return;
}
GetQuotaHost(execution_context)
->RequestStorageQuota(
- WrapRefCounted(security_origin), storage_type, new_quota_in_bytes,
+ storage_type, new_quota_in_bytes,
mojo::WrapCallbackWithDefaultInvokeIfNotRun(
- std::move(callback), mojom::QuotaStatusCode::kErrorAbort, 0, 0));
+ std::move(callback), mojom::blink::QuotaStatusCode::kErrorAbort,
+ 0, 0));
}
-mojom::blink::QuotaDispatcherHost* DeprecatedStorageQuota::GetQuotaHost(
+mojom::blink::QuotaManagerHost* DeprecatedStorageQuota::GetQuotaHost(
ExecutionContext* execution_context) {
if (!quota_host_) {
- ConnectToQuotaDispatcherHost(
+ ConnectToQuotaManagerHost(
execution_context,
quota_host_.BindNewPipeAndPassReceiver(execution_context->GetTaskRunner(
blink::TaskType::kInternalDefault)));
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 d957a33ee76..fd5162308c9 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,7 +32,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_QUOTA_DEPRECATED_STORAGE_QUOTA_H_
#include "mojo/public/cpp/bindings/remote.h"
-#include "third_party/blink/public/mojom/quota/quota_dispatcher_host.mojom-blink.h"
+#include "third_party/blink/public/mojom/quota/quota_manager_host.mojom-blink.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"
@@ -72,10 +72,10 @@ class DeprecatedStorageQuota final : public ScriptWrappable {
private:
// Binds the interface (if not already bound) with the given interface
// provider, and returns it,
- mojom::blink::QuotaDispatcherHost* GetQuotaHost(ExecutionContext*);
+ mojom::blink::QuotaManagerHost* GetQuotaHost(ExecutionContext*);
Type type_;
- mojo::Remote<mojom::blink::QuotaDispatcherHost> quota_host_;
+ mojo::Remote<mojom::blink::QuotaManagerHost> quota_host_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/quota/dom_error.cc b/chromium/third_party/blink/renderer/modules/quota/dom_error.cc
index 7cc2ce8b1ef..e696ca01276 100644
--- a/chromium/third_party/blink/renderer/modules/quota/dom_error.cc
+++ b/chromium/third_party/blink/renderer/modules/quota/dom_error.cc
@@ -28,7 +28,7 @@
namespace blink {
// static
-DOMError* DOMError::Create(mojom::QuotaStatusCode status_code) {
+DOMError* DOMError::Create(mojom::blink::QuotaStatusCode status_code) {
ExceptionCode exception_code = static_cast<ExceptionCode>(status_code);
if (IsDOMExceptionCode(exception_code)) {
DOMExceptionCode code = static_cast<DOMExceptionCode>(exception_code);
diff --git a/chromium/third_party/blink/renderer/modules/quota/dom_error.h b/chromium/third_party/blink/renderer/modules/quota/dom_error.h
index 8ea2baffc08..80da05cc0af 100644
--- a/chromium/third_party/blink/renderer/modules/quota/dom_error.h
+++ b/chromium/third_party/blink/renderer/modules/quota/dom_error.h
@@ -50,7 +50,7 @@ class MODULES_EXPORT DOMError : public ScriptWrappable {
DOMException::GetErrorName(exception_code),
DOMException::GetErrorMessage(exception_code));
}
- static DOMError* Create(mojom::QuotaStatusCode status_code);
+ static DOMError* Create(mojom::blink::QuotaStatusCode status_code);
explicit DOMError(const String& name);
DOMError(const String& name, const String& message);
diff --git a/chromium/third_party/blink/renderer/modules/quota/dom_error.idl b/chromium/third_party/blink/renderer/modules/quota/dom_error.idl
index cd62ea75daf..768ac5dec07 100644
--- a/chromium/third_party/blink/renderer/modules/quota/dom_error.idl
+++ b/chromium/third_party/blink/renderer/modules/quota/dom_error.idl
@@ -29,10 +29,8 @@
// https://dom.spec.whatwg.org/#domerror
// FIXME: DOMError has been removed from the spec. crbug.com/460725
-[
- Constructor(DOMString name, optional DOMString message = null),
- Measure
-] interface DOMError {
+interface DOMError {
+ [Measure] constructor(DOMString name, optional DOMString message);
[Measure] readonly attribute DOMString name;
[Measure] readonly attribute DOMString message;
};
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 50319ee2dce..5ccf5e8b497 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(blink::Visitor* visitor) {
+void DOMWindowQuota::Trace(Visitor* visitor) {
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 bfd2e97b0fa..997056fa2bd 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
mutable Member<DeprecatedStorageInfo> storage_info_;
diff --git a/chromium/third_party/blink/renderer/modules/quota/idls.gni b/chromium/third_party/blink/renderer/modules/quota/idls.gni
new file mode 100644
index 00000000000..59cbde178ab
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/quota/idls.gni
@@ -0,0 +1,23 @@
+# 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 = [
+ "deprecated_storage_info.idl",
+ "deprecated_storage_quota.idl",
+ "dom_error.idl",
+ "storage_manager.idl",
+]
+
+modules_callback_function_idl_files = [ "deprecated_storage_callbacks.idl" ]
+
+modules_dictionary_idl_files = [
+ "storage_estimate.idl",
+ "storage_usage_details.idl",
+]
+
+modules_dependency_idl_files = [
+ "navigator_storage_quota.idl",
+ "window_quota.idl",
+ "worker_navigator_storage_quota.idl",
+]
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 b344345417a..c4d14b7953a 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
@@ -88,7 +88,7 @@ StorageManager* NavigatorStorageQuota::storage() const {
return storage_manager_.Get();
}
-void NavigatorStorageQuota::Trace(blink::Visitor* visitor) {
+void NavigatorStorageQuota::Trace(Visitor* visitor) {
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 a79d60a862b..8812881b0bf 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
mutable Member<DeprecatedStorageQuota> temporary_storage_;
diff --git a/chromium/third_party/blink/renderer/modules/quota/quota_utils.cc b/chromium/third_party/blink/renderer/modules/quota/quota_utils.cc
index d34fcdb5479..eefaa669874 100644
--- a/chromium/third_party/blink/renderer/modules/quota/quota_utils.cc
+++ b/chromium/third_party/blink/renderer/modules/quota/quota_utils.cc
@@ -9,9 +9,9 @@
namespace blink {
-void ConnectToQuotaDispatcherHost(
+void ConnectToQuotaManagerHost(
ExecutionContext* execution_context,
- mojo::PendingReceiver<mojom::blink::QuotaDispatcherHost> receiver) {
+ mojo::PendingReceiver<mojom::blink::QuotaManagerHost> receiver) {
execution_context->GetBrowserInterfaceBroker().GetInterface(
std::move(receiver));
}
diff --git a/chromium/third_party/blink/renderer/modules/quota/quota_utils.h b/chromium/third_party/blink/renderer/modules/quota/quota_utils.h
index 1fcb3f16272..4e0e2b79f13 100644
--- a/chromium/third_party/blink/renderer/modules/quota/quota_utils.h
+++ b/chromium/third_party/blink/renderer/modules/quota/quota_utils.h
@@ -6,15 +6,15 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_QUOTA_QUOTA_UTILS_H_
#include "mojo/public/cpp/bindings/pending_receiver.h"
-#include "third_party/blink/public/mojom/quota/quota_dispatcher_host.mojom-blink.h"
+#include "third_party/blink/public/mojom/quota/quota_manager_host.mojom-blink.h"
namespace blink {
class ExecutionContext;
-void ConnectToQuotaDispatcherHost(
+void ConnectToQuotaManagerHost(
ExecutionContext*,
- mojo::PendingReceiver<mojom::blink::QuotaDispatcherHost>);
+ mojo::PendingReceiver<mojom::blink::QuotaManagerHost>);
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/quota/storage_estimate.idl b/chromium/third_party/blink/renderer/modules/quota/storage_estimate.idl
index 46b9a7326ff..78c827a19c3 100644
--- a/chromium/third_party/blink/renderer/modules/quota/storage_estimate.idl
+++ b/chromium/third_party/blink/renderer/modules/quota/storage_estimate.idl
@@ -7,5 +7,5 @@
dictionary StorageEstimate {
unsigned long long usage;
unsigned long long quota;
- [RuntimeEnabled=StorageQuotaDetails] StorageUsageDetails usageDetails;
+ StorageUsageDetails usageDetails;
};
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 23c7b7654e6..f677a610e88 100644
--- a/chromium/third_party/blink/renderer/modules/quota/storage_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/quota/storage_manager.cc
@@ -9,6 +9,7 @@
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_storage_estimate.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_storage_usage_details.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"
@@ -17,8 +18,6 @@
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/modules/permissions/permission_utils.h"
#include "third_party/blink/renderer/modules/quota/quota_utils.h"
-#include "third_party/blink/renderer/modules/quota/storage_estimate.h"
-#include "third_party/blink/renderer/modules/quota/storage_usage_details.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/assertions.h"
@@ -36,15 +35,16 @@ namespace {
const char kUniqueOriginErrorMessage[] =
"The operation is not supported in this context.";
-void QueryStorageUsageAndQuotaCallback(ScriptPromiseResolver* resolver,
- mojom::QuotaStatusCode status_code,
- int64_t usage_in_bytes,
- int64_t quota_in_bytes,
- UsageBreakdownPtr usage_breakdown) {
+void QueryStorageUsageAndQuotaCallback(
+ ScriptPromiseResolver* resolver,
+ mojom::blink::QuotaStatusCode status_code,
+ int64_t usage_in_bytes,
+ int64_t quota_in_bytes,
+ UsageBreakdownPtr usage_breakdown) {
// Avoid crash on shutdown. crbug.com/971594
if (!resolver)
return;
- if (status_code != mojom::QuotaStatusCode::kOk) {
+ if (status_code != mojom::blink::QuotaStatusCode::kOk) {
// TODO(sashab): Replace this with a switch statement, and remove the enum
// values from QuotaStatusCode.
resolver->Reject(MakeGarbageCollected<DOMException>(
@@ -97,7 +97,7 @@ ScriptPromise StorageManager::persist(ScriptState* script_state) {
return promise;
}
- Document* doc = To<Document>(execution_context);
+ Document* doc = Document::From(execution_context);
GetPermissionService(ExecutionContext::From(script_state))
->RequestPermission(
CreatePermissionDescriptor(PermissionName::DURABLE_STORAGE),
@@ -151,10 +151,10 @@ ScriptPromise StorageManager::estimate(ScriptState* script_state) {
WTF::Bind(&QueryStorageUsageAndQuotaCallback, WrapPersistent(resolver));
GetQuotaHost(execution_context)
->QueryStorageUsageAndQuota(
- WrapRefCounted(security_origin), mojom::StorageType::kTemporary,
+ mojom::blink::StorageType::kTemporary,
mojo::WrapCallbackWithDefaultInvokeIfNotRun(
- std::move(callback), mojom::QuotaStatusCode::kErrorAbort, 0, 0,
- nullptr));
+ std::move(callback), mojom::blink::QuotaStatusCode::kErrorAbort,
+ 0, 0, nullptr));
return promise;
}
@@ -184,10 +184,10 @@ void StorageManager::PermissionRequestComplete(ScriptPromiseResolver* resolver,
resolver->Resolve(status == PermissionStatus::GRANTED);
}
-mojom::blink::QuotaDispatcherHost* StorageManager::GetQuotaHost(
+mojom::blink::QuotaManagerHost* StorageManager::GetQuotaHost(
ExecutionContext* execution_context) {
if (!quota_host_) {
- ConnectToQuotaDispatcherHost(
+ ConnectToQuotaManagerHost(
execution_context,
quota_host_.BindNewPipeAndPassReceiver(
execution_context->GetTaskRunner(TaskType::kMiscPlatformAPI)));
@@ -195,13 +195,13 @@ mojom::blink::QuotaDispatcherHost* StorageManager::GetQuotaHost(
return quota_host_.get();
}
-STATIC_ASSERT_ENUM(mojom::QuotaStatusCode::kErrorNotSupported,
+STATIC_ASSERT_ENUM(mojom::blink::QuotaStatusCode::kErrorNotSupported,
DOMExceptionCode::kNotSupportedError);
-STATIC_ASSERT_ENUM(mojom::QuotaStatusCode::kErrorInvalidModification,
+STATIC_ASSERT_ENUM(mojom::blink::QuotaStatusCode::kErrorInvalidModification,
DOMExceptionCode::kInvalidModificationError);
-STATIC_ASSERT_ENUM(mojom::QuotaStatusCode::kErrorInvalidAccess,
+STATIC_ASSERT_ENUM(mojom::blink::QuotaStatusCode::kErrorInvalidAccess,
DOMExceptionCode::kInvalidAccessError);
-STATIC_ASSERT_ENUM(mojom::QuotaStatusCode::kErrorAbort,
+STATIC_ASSERT_ENUM(mojom::blink::QuotaStatusCode::kErrorAbort,
DOMExceptionCode::kAbortError);
} // namespace blink
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 7ec91e717cd..05c5d75ac80 100644
--- a/chromium/third_party/blink/renderer/modules/quota/storage_manager.h
+++ b/chromium/third_party/blink/renderer/modules/quota/storage_manager.h
@@ -7,7 +7,7 @@
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h"
-#include "third_party/blink/public/mojom/quota/quota_dispatcher_host.mojom-blink.h"
+#include "third_party/blink/public/mojom/quota/quota_manager_host.mojom-blink.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
@@ -35,10 +35,10 @@ class StorageManager final : public ScriptWrappable {
// Binds the interface (if not already bound) with the given interface
// provider, and returns it,
- mojom::blink::QuotaDispatcherHost* GetQuotaHost(ExecutionContext*);
+ mojom::blink::QuotaManagerHost* GetQuotaHost(ExecutionContext*);
mojo::Remote<mojom::blink::PermissionService> permission_service_;
- mojo::Remote<mojom::blink::QuotaDispatcherHost> quota_host_;
+ mojo::Remote<mojom::blink::QuotaManagerHost> quota_host_;
};
} // namespace blink
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 4958c37f581..f0f8a6598ad 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
@@ -62,7 +62,7 @@ StorageManager* WorkerNavigatorStorageQuota::storage() const {
return storage_manager_.Get();
}
-void WorkerNavigatorStorageQuota::Trace(blink::Visitor* visitor) {
+void WorkerNavigatorStorageQuota::Trace(Visitor* visitor) {
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 d87758f5387..b2bc26f52fa 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
mutable Member<StorageManager> storage_manager_;
diff --git a/chromium/third_party/blink/renderer/modules/sms/BUILD.gn b/chromium/third_party/blink/renderer/modules/remote_objects/BUILD.gn
index 6e2707280a0..bf423cad82c 100644
--- a/chromium/third_party/blink/renderer/modules/sms/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/remote_objects/BUILD.gn
@@ -4,15 +4,11 @@
import("//third_party/blink/renderer/modules/modules.gni")
-blink_modules_sources("sms") {
+blink_modules_sources("remote_objects") {
sources = [
- "navigator_sms.cc",
- "navigator_sms.h",
- "sms.cc",
- "sms.h",
- "sms_metrics.cc",
- "sms_metrics.h",
- "sms_receiver.cc",
- "sms_receiver.h",
+ "remote_object.cc",
+ "remote_object.h",
+ "remote_object_gateway_impl.cc",
+ "remote_object_gateway_impl.h",
]
}
diff --git a/chromium/third_party/blink/renderer/modules/remote_objects/DEPS b/chromium/third_party/blink/renderer/modules/remote_objects/DEPS
new file mode 100644
index 00000000000..b462077ce45
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/remote_objects/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+gin",
+]
diff --git a/chromium/third_party/blink/renderer/modules/remote_objects/remote_object.cc b/chromium/third_party/blink/renderer/modules/remote_objects/remote_object.cc
new file mode 100644
index 00000000000..abb3c4766ae
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/remote_objects/remote_object.cc
@@ -0,0 +1,308 @@
+// 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/remote_objects/remote_object.h"
+#include "gin/converter.h"
+#include "third_party/blink/public/web/blink.h"
+#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
+#include "third_party/blink/renderer/platform/bindings/v8_private_property.h"
+
+namespace blink {
+
+gin::WrapperInfo RemoteObject::kWrapperInfo = {gin::kEmbedderNativeGin};
+
+namespace {
+const char kMethodInvocationAsConstructorDisallowed[] =
+ "Java bridge method can't be invoked as a constructor";
+const char kMethodInvocationNonexistentMethod[] =
+ "Java bridge method does not exist for this object";
+const char kMethodInvocationOnNonInjectedObjectDisallowed[] =
+ "Java bridge method can't be invoked on a non-injected object";
+const char kMethodInvocationErrorMessage[] =
+ "Java bridge method invocation error";
+
+String RemoteInvocationErrorToString(
+ mojom::blink::RemoteInvocationError value) {
+ switch (value) {
+ case mojom::blink::RemoteInvocationError::METHOD_NOT_FOUND:
+ return "method not found";
+ case mojom::blink::RemoteInvocationError::OBJECT_GET_CLASS_BLOCKED:
+ return "invoking Object.getClass() is not permitted";
+ case mojom::blink::RemoteInvocationError::EXCEPTION_THROWN:
+ return "an exception was thrown";
+ default:
+ return String::Format("unknown RemoteInvocationError value: %d", value);
+ }
+}
+
+v8::Local<v8::Object> GetMethodCache(v8::Isolate* isolate,
+ v8::Local<v8::Object> object) {
+ static const V8PrivateProperty::SymbolKey kMethodCacheKey;
+ V8PrivateProperty::Symbol method_cache_symbol =
+ V8PrivateProperty::GetSymbol(isolate, kMethodCacheKey);
+ v8::Local<v8::Value> result;
+ if (!method_cache_symbol.GetOrUndefined(object).ToLocal(&result))
+ return v8::Local<v8::Object>();
+
+ if (result->IsUndefined()) {
+ result = v8::Object::New(isolate, v8::Null(isolate), nullptr, nullptr, 0);
+ ignore_result(method_cache_symbol.Set(object, result));
+ }
+
+ DCHECK(result->IsObject());
+ return result.As<v8::Object>();
+}
+
+mojom::blink::RemoteInvocationArgumentPtr JSValueToMojom(
+ const v8::Local<v8::Value>& js_value,
+ v8::Isolate* isolate) {
+ if (js_value->IsNumber()) {
+ return mojom::blink::RemoteInvocationArgument::NewNumberValue(
+ js_value->NumberValue(isolate->GetCurrentContext()).ToChecked());
+ }
+
+ if (js_value->IsBoolean()) {
+ return mojom::blink::RemoteInvocationArgument::NewBooleanValue(
+ js_value->BooleanValue(isolate));
+ }
+
+ if (js_value->IsString()) {
+ return mojom::blink::RemoteInvocationArgument::NewStringValue(
+ ToCoreString(js_value.As<v8::String>()));
+ }
+
+ if (js_value->IsNull()) {
+ return mojom::blink::RemoteInvocationArgument::NewSingletonValue(
+ mojom::blink::SingletonJavaScriptValue::kNull);
+ }
+
+ if (js_value->IsUndefined()) {
+ return mojom::blink::RemoteInvocationArgument::NewSingletonValue(
+ mojom::blink::SingletonJavaScriptValue::kUndefined);
+ }
+
+ if (js_value->IsArray()) {
+ auto array = js_value.As<v8::Array>();
+ WTF::Vector<mojom::blink::RemoteInvocationArgumentPtr> nested_arguments;
+ for (uint32_t i = 0; i < array->Length(); ++i) {
+ v8::Local<v8::Value> element_v8;
+
+ if (!array->Get(isolate->GetCurrentContext(), i).ToLocal(&element_v8))
+ return nullptr;
+
+ // The array length might change during iteration. Set the output array
+ // elements to null for nonexistent input array elements.
+ if (!array->HasRealIndexedProperty(isolate->GetCurrentContext(), i)
+ .FromMaybe(false)) {
+ nested_arguments.push_back(
+ mojom::blink::RemoteInvocationArgument::NewSingletonValue(
+ mojom::blink::SingletonJavaScriptValue::kNull));
+ } else {
+ mojom::blink::RemoteInvocationArgumentPtr nested_argument;
+
+ // This code prevents infinite recursion on the sender side.
+ // Null value is sent according to the Java-side conversion rules for
+ // expected parameter types:
+ // - multi-dimensional and object arrays are not allowed and are
+ // converted to nulls;
+ // - for primitive arrays, the null value will be converted to primitive
+ // zero;
+ // - for string arrays, the null value will be converted to a null
+ // string. See RemoteObjectImpl.convertArgument() in
+ // content/public/android/java/src/org/chromium/content/browser/remoteobjects/RemoteObjectImpl.java
+ if (element_v8->IsObject()) {
+ nested_argument =
+ mojom::blink::RemoteInvocationArgument::NewSingletonValue(
+ mojom::blink::SingletonJavaScriptValue::kNull);
+ } else {
+ nested_argument = JSValueToMojom(element_v8, isolate);
+ }
+
+ if (!nested_argument)
+ return nullptr;
+
+ nested_arguments.push_back(std::move(nested_argument));
+ }
+ }
+
+ return mojom::blink::RemoteInvocationArgument::NewArrayValue(
+ std::move(nested_arguments));
+ }
+
+ return nullptr;
+}
+
+v8::Local<v8::Value> MojomToJSValue(
+ const mojom::blink::RemoteInvocationResultValuePtr& result_value,
+ v8::Isolate* isolate) {
+ if (result_value->is_number_value()) {
+ return v8::Number::New(isolate, result_value->get_number_value());
+ }
+
+ if (result_value->is_boolean_value()) {
+ return v8::Boolean::New(isolate, result_value->get_boolean_value());
+ }
+
+ if (result_value->is_string_value()) {
+ return V8String(isolate, result_value->get_string_value());
+ }
+
+ switch (result_value->get_singleton_value()) {
+ case mojom::blink::SingletonJavaScriptValue::kNull:
+ return v8::Null(isolate);
+ case mojom::blink::SingletonJavaScriptValue::kUndefined:
+ return v8::Undefined(isolate);
+ }
+
+ return v8::Local<v8::Value>();
+}
+} // namespace
+
+RemoteObject::RemoteObject(v8::Isolate* isolate,
+ RemoteObjectGatewayImpl* gateway,
+ int32_t object_id)
+ : gin::NamedPropertyInterceptor(isolate, this),
+ gateway_(gateway),
+ object_id_(object_id) {}
+
+gin::ObjectTemplateBuilder RemoteObject::GetObjectTemplateBuilder(
+ v8::Isolate* isolate) {
+ return gin::Wrappable<RemoteObject>::GetObjectTemplateBuilder(isolate)
+ .AddNamedPropertyInterceptor();
+}
+
+void RemoteObject::RemoteObjectInvokeCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ v8::Isolate* isolate = info.GetIsolate();
+ if (info.IsConstructCall()) {
+ // This is not a constructor. Throw and return.
+ isolate->ThrowException(v8::Exception::Error(
+ V8String(isolate, kMethodInvocationAsConstructorDisallowed)));
+ return;
+ }
+
+ RemoteObject* remote_object;
+ if (!gin::ConvertFromV8(isolate, info.Holder(), &remote_object)) {
+ // Someone messed with the |this| pointer. Throw and return.
+ isolate->ThrowException(v8::Exception::Error(
+ V8String(isolate, kMethodInvocationOnNonInjectedObjectDisallowed)));
+ return;
+ }
+
+ String method_name = ToCoreString(info.Data().As<v8::String>());
+
+ v8::Local<v8::Object> method_cache = GetMethodCache(
+ isolate, remote_object->GetWrapper(isolate).ToLocalChecked());
+ if (method_cache.IsEmpty())
+ return;
+
+ v8::Local<v8::Value> cached_method =
+ method_cache
+ ->Get(isolate->GetCurrentContext(), info.Data().As<v8::String>())
+ .ToLocalChecked();
+
+ if (cached_method->IsUndefined()) {
+ isolate->ThrowException(v8::Exception::Error(
+ V8String(isolate, kMethodInvocationNonexistentMethod)));
+ return;
+ }
+
+ WTF::Vector<mojom::blink::RemoteInvocationArgumentPtr> arguments;
+ arguments.ReserveInitialCapacity(info.Length());
+
+ for (int i = 0; i < info.Length(); i++) {
+ auto argument = JSValueToMojom(info[i], isolate);
+ if (!argument)
+ return;
+
+ arguments.push_back(std::move(argument));
+ }
+
+ remote_object->EnsureRemoteIsBound();
+ mojom::blink::RemoteInvocationResultPtr result;
+ remote_object->object_->InvokeMethod(method_name, std::move(arguments),
+ &result);
+
+ if (result->error != mojom::blink::RemoteInvocationError::OK) {
+ String message = String::Format("%s : ", kMethodInvocationErrorMessage) +
+ RemoteInvocationErrorToString(result->error);
+ isolate->ThrowException(v8::Exception::Error(V8String(isolate, message)));
+ return;
+ }
+
+ if (!result->value)
+ return;
+
+ if (result->value->is_object_id()) {
+ // TODO(crbug.com/794320): need to check whether an object with this id has
+ // already been injected
+ RemoteObject* object_result =
+ new RemoteObject(info.GetIsolate(), remote_object->gateway_,
+ result->value->get_object_id());
+ gin::Handle<RemoteObject> controller =
+ gin::CreateHandle(isolate, object_result);
+ if (controller.IsEmpty())
+ info.GetReturnValue().SetUndefined();
+ else
+ info.GetReturnValue().Set(controller.ToV8());
+ } else {
+ info.GetReturnValue().Set(MojomToJSValue(result->value, isolate));
+ }
+}
+
+void RemoteObject::EnsureRemoteIsBound() {
+ if (!object_.is_bound()) {
+ gateway_->BindRemoteObjectReceiver(object_id_,
+ object_.BindNewPipeAndPassReceiver());
+ }
+}
+
+v8::Local<v8::Value> RemoteObject::GetNamedProperty(
+ v8::Isolate* isolate,
+ const std::string& property) {
+ auto wtf_property = WTF::String::FromUTF8(property);
+
+ v8::Local<v8::String> v8_property = V8AtomicString(isolate, wtf_property);
+ v8::Local<v8::Object> method_cache =
+ GetMethodCache(isolate, GetWrapper(isolate).ToLocalChecked());
+ if (method_cache.IsEmpty())
+ return v8::Local<v8::Value>();
+
+ v8::Local<v8::Value> cached_method =
+ method_cache->Get(isolate->GetCurrentContext(), v8_property)
+ .ToLocalChecked();
+
+ if (!cached_method->IsUndefined())
+ return cached_method;
+
+ // if not in the cache, ask the browser
+ EnsureRemoteIsBound();
+ bool method_exists = false;
+ object_->HasMethod(wtf_property, &method_exists);
+
+ if (!method_exists) {
+ return v8::Local<v8::Value>();
+ }
+
+ auto function = v8::Function::New(isolate->GetCurrentContext(),
+ RemoteObjectInvokeCallback, v8_property)
+ .ToLocalChecked();
+
+ ignore_result(method_cache->CreateDataProperty(isolate->GetCurrentContext(),
+ v8_property, function));
+ return function;
+}
+
+std::vector<std::string> RemoteObject::EnumerateNamedProperties(
+ v8::Isolate* isolate) {
+ EnsureRemoteIsBound();
+ WTF::Vector<WTF::String> methods;
+ object_->GetMethods(&methods);
+ std::vector<std::string> result;
+ for (const auto& method : methods)
+ result.push_back(method.Utf8());
+ return result;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/remote_objects/remote_object.h b/chromium/third_party/blink/renderer/modules/remote_objects/remote_object.h
new file mode 100644
index 00000000000..29ad0635991
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/remote_objects/remote_object.h
@@ -0,0 +1,52 @@
+// 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_REMOTE_OBJECTS_REMOTE_OBJECT_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_REMOTE_OBJECTS_REMOTE_OBJECT_H_
+
+#include "gin/handle.h"
+#include "gin/interceptor.h"
+#include "gin/object_template_builder.h"
+#include "gin/wrappable.h"
+#include "third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
+
+namespace blink {
+
+// Gin wrapper for representing objects that could be injected by the browser.
+// Recreated every time the window object is cleared.
+class RemoteObject : public gin::Wrappable<RemoteObject>,
+ public gin::NamedPropertyInterceptor {
+ public:
+ static gin::WrapperInfo kWrapperInfo;
+
+ RemoteObject(v8::Isolate*, RemoteObjectGatewayImpl*, int32_t);
+ // Not copyable or movable
+ RemoteObject(const RemoteObject&) = delete;
+ RemoteObject& operator=(const RemoteObject&) = delete;
+ ~RemoteObject() override = default;
+
+ // gin::Wrappable.
+ gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
+ v8::Isolate* isolate) override;
+
+ // gin::NamedPropertyInterceptor
+ v8::Local<v8::Value> GetNamedProperty(v8::Isolate* isolate,
+ const std::string& property) override;
+ std::vector<std::string> EnumerateNamedProperties(
+ v8::Isolate* isolate) override;
+
+ private:
+ static void RemoteObjectInvokeCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ void EnsureRemoteIsBound();
+
+ WeakPersistent<RemoteObjectGatewayImpl> gateway_{nullptr};
+ mojo::Remote<mojom::blink::RemoteObject> object_;
+ int32_t object_id_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_REMOTE_OBJECTS_REMOTE_OBJECT_H_
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
new file mode 100644
index 00000000000..351e5b9ed29
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.cc
@@ -0,0 +1,124 @@
+// 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/remote_objects/remote_object_gateway_impl.h"
+#include "third_party/blink/public/web/web_local_frame.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/modules/remote_objects/remote_object.h"
+#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
+#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
+
+#undef GetObject
+
+namespace blink {
+
+// static
+const char RemoteObjectGatewayImpl::kSupplementName[] = "RemoteObjectGateway";
+
+// static
+RemoteObjectGatewayImpl* RemoteObjectGatewayImpl::From(LocalFrame& frame) {
+ return Supplement<LocalFrame>::From<RemoteObjectGatewayImpl>(frame);
+}
+
+void RemoteObjectGatewayImpl::InjectNamed(const WTF::String& object_name,
+ int32_t object_id) {
+ ScriptState* script_state = ToScriptStateForMainWorld(GetSupplementable());
+ ScriptState::Scope scope(script_state);
+ v8::Isolate* isolate = script_state->GetIsolate();
+ v8::Local<v8::Context> context = script_state->GetContext();
+ if (context.IsEmpty())
+ return;
+
+ RemoteObject* object = new RemoteObject(isolate, this, object_id);
+
+ v8::Context::Scope context_scope(context);
+ v8::Local<v8::Object> global = context->Global();
+ gin::Handle<RemoteObject> controller = gin::CreateHandle(isolate, object);
+
+ // WrappableBase instance deletes itself in case of a wrapper
+ // creation failure, thus there is no need to delete |object|.
+ if (controller.IsEmpty())
+ return;
+
+ global->Set(context, V8AtomicString(isolate, object_name), controller.ToV8())
+ .Check();
+}
+
+// static
+void RemoteObjectGatewayImpl::BindMojoReceiver(
+ LocalFrame* frame,
+ mojo::PendingRemote<mojom::blink::RemoteObjectHost> host,
+ mojo::PendingReceiver<mojom::blink::RemoteObjectGateway> receiver) {
+ if (!frame)
+ return;
+
+ DCHECK(!RemoteObjectGatewayImpl::From(*frame));
+
+ auto* self = MakeGarbageCollected<RemoteObjectGatewayImpl>(
+ util::PassKey<RemoteObjectGatewayImpl>(), *frame, std::move(receiver),
+ std::move(host));
+ Supplement<LocalFrame>::ProvideTo(*frame, self);
+}
+
+RemoteObjectGatewayImpl::RemoteObjectGatewayImpl(
+ util::PassKey<RemoteObjectGatewayImpl>,
+ LocalFrame& frame,
+ mojo::PendingReceiver<mojom::blink::RemoteObjectGateway>
+ object_gateway_receiver,
+ mojo::PendingRemote<mojom::blink::RemoteObjectHost> object_host_remote)
+ : Supplement<LocalFrame>(frame),
+ receiver_(this, std::move(object_gateway_receiver)),
+ object_host_(std::move(object_host_remote)) {}
+
+void RemoteObjectGatewayImpl::OnClearWindowObjectInMainWorld() {
+ for (const auto& pair : named_objects_)
+ 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
+ // are only added into the internal map.
+ named_objects_.insert(name, id);
+}
+
+void RemoteObjectGatewayImpl::RemoveNamedObject(const WTF::String& name) {
+ // Removal becomes in effect on next reload. We simply remove the entry
+ // from the map here.
+ auto iter = named_objects_.find(name);
+ DCHECK(iter != named_objects_.end());
+ named_objects_.erase(iter);
+}
+
+void RemoteObjectGatewayImpl::BindRemoteObjectReceiver(
+ int32_t object_id,
+ mojo::PendingReceiver<mojom::blink::RemoteObject> receiver) {
+ object_host_->GetObject(object_id, std::move(receiver));
+}
+
+// static
+void RemoteObjectGatewayFactoryImpl::Create(
+ LocalFrame* frame,
+ mojo::PendingReceiver<mojom::blink::RemoteObjectGatewayFactory> receiver) {
+ mojo::MakeSelfOwnedReceiver(std::unique_ptr<RemoteObjectGatewayFactoryImpl>(
+ new RemoteObjectGatewayFactoryImpl(*frame)),
+ std::move(receiver));
+}
+
+RemoteObjectGatewayFactoryImpl::RemoteObjectGatewayFactoryImpl(
+ LocalFrame& frame)
+ : frame_(frame) {}
+
+void RemoteObjectGatewayFactoryImpl::CreateRemoteObjectGateway(
+ mojo::PendingRemote<mojom::blink::RemoteObjectHost> host,
+ mojo::PendingReceiver<mojom::blink::RemoteObjectGateway> receiver) {
+ RemoteObjectGatewayImpl::BindMojoReceiver(frame_, std::move(host),
+ std::move(receiver));
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..32097c522a1
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.h
@@ -0,0 +1,100 @@
+// 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_REMOTE_OBJECTS_REMOTE_OBJECT_GATEWAY_IMPL_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_REMOTE_OBJECTS_REMOTE_OBJECT_GATEWAY_IMPL_H_
+
+#include "base/util/type_safety/pass_key.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/self_owned_receiver.h"
+#include "third_party/blink/public/mojom/remote_objects/remote_objects.mojom-blink.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
+
+namespace blink {
+
+class MODULES_EXPORT RemoteObjectGatewayImpl
+ : public GarbageCollected<RemoteObjectGatewayImpl>,
+ public Supplement<LocalFrame>,
+ public mojom::blink::RemoteObjectGateway {
+ USING_GARBAGE_COLLECTED_MIXIN(RemoteObjectGatewayImpl);
+ USING_PRE_FINALIZER(RemoteObjectGatewayImpl, Dispose);
+
+ public:
+ static const char kSupplementName[];
+
+ RemoteObjectGatewayImpl(
+ util::PassKey<RemoteObjectGatewayImpl>,
+ LocalFrame&,
+ mojo::PendingReceiver<mojom::blink::RemoteObjectGateway>,
+ mojo::PendingRemote<mojom::blink::RemoteObjectHost>);
+
+ // Not copyable or movable
+ RemoteObjectGatewayImpl(const RemoteObjectGatewayImpl&) = delete;
+ RemoteObjectGatewayImpl& operator=(const RemoteObjectGatewayImpl&) = delete;
+ ~RemoteObjectGatewayImpl() override = default;
+ void Dispose();
+
+ static void BindMojoReceiver(
+ LocalFrame*,
+ mojo::PendingRemote<mojom::blink::RemoteObjectHost>,
+ mojo::PendingReceiver<mojom::blink::RemoteObjectGateway>);
+
+ // This supplement is only installed if the RemoteObjectGateway mojom
+ // interface is requested to be bound (currently only for Android WebView).
+ static RemoteObjectGatewayImpl* From(LocalFrame&);
+
+ void OnClearWindowObjectInMainWorld();
+
+ void Trace(Visitor* visitor) override {
+ Supplement<LocalFrame>::Trace(visitor);
+ }
+
+ void BindRemoteObjectReceiver(
+ int32_t object_id,
+ mojo::PendingReceiver<mojom::blink::RemoteObject>);
+
+ private:
+ // mojom::blink::RemoteObjectGateway
+ void AddNamedObject(const WTF::String& name, int32_t id) override;
+ void RemoveNamedObject(const WTF::String& name) override;
+
+ void InjectNamed(const WTF::String& object_name, int32_t object_id);
+
+ HashMap<String, int32_t> named_objects_;
+
+ mojo::Receiver<mojom::blink::RemoteObjectGateway> receiver_;
+ mojo::Remote<mojom::blink::RemoteObjectHost> object_host_;
+};
+
+class RemoteObjectGatewayFactoryImpl
+ : public mojom::blink::RemoteObjectGatewayFactory {
+ public:
+ static void Create(
+ LocalFrame* frame,
+ mojo::PendingReceiver<mojom::blink::RemoteObjectGatewayFactory> receiver);
+
+ private:
+ explicit RemoteObjectGatewayFactoryImpl(LocalFrame& frame);
+ // Not copyable or movable
+ RemoteObjectGatewayFactoryImpl(const RemoteObjectGatewayFactoryImpl&) =
+ delete;
+ RemoteObjectGatewayFactoryImpl& operator=(
+ const RemoteObjectGatewayFactoryImpl&) = delete;
+
+ // mojom::blink::RemoteObjectGatewayFactory
+ void CreateRemoteObjectGateway(
+ mojo::PendingRemote<mojom::blink::RemoteObjectHost> host,
+ mojo::PendingReceiver<mojom::blink::RemoteObjectGateway> receiver)
+ override;
+
+ WeakPersistent<LocalFrame> frame_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_REMOTE_OBJECTS_REMOTE_OBJECT_GATEWAY_IMPL_H_
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 5f04db553cb..526b56716c6 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(blink::Visitor* visitor) {
+void AvailabilityCallbackWrapper::Trace(Visitor* visitor) {
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 1520f7575e2..79abd6c89db 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(blink::Visitor*);
+ virtual void Trace(Visitor*);
const char* NameInHeapSnapshot() const override {
return "AvailabilityCallbackWrapper";
}
diff --git a/chromium/third_party/blink/renderer/modules/remoteplayback/html_media_element_remote_playback.cc b/chromium/third_party/blink/renderer/modules/remoteplayback/html_media_element_remote_playback.cc
index 9def6729425..7df7892f50d 100644
--- a/chromium/third_party/blink/renderer/modules/remoteplayback/html_media_element_remote_playback.cc
+++ b/chromium/third_party/blink/renderer/modules/remoteplayback/html_media_element_remote_playback.cc
@@ -14,16 +14,16 @@ namespace blink {
// static
bool HTMLMediaElementRemotePlayback::FastHasAttribute(
- const QualifiedName& name,
- const HTMLMediaElement& element) {
+ const HTMLMediaElement& element,
+ const QualifiedName& name) {
DCHECK(name == html_names::kDisableremoteplaybackAttr);
return element.FastHasAttribute(name);
}
// static
void HTMLMediaElementRemotePlayback::SetBooleanAttribute(
- const QualifiedName& name,
HTMLMediaElement& element,
+ const QualifiedName& name,
bool value) {
DCHECK(name == html_names::kDisableremoteplaybackAttr);
element.SetBooleanAttribute(name, value);
diff --git a/chromium/third_party/blink/renderer/modules/remoteplayback/html_media_element_remote_playback.h b/chromium/third_party/blink/renderer/modules/remoteplayback/html_media_element_remote_playback.h
index 3f2cc4ad05a..aedcc62e3d4 100644
--- a/chromium/third_party/blink/renderer/modules/remoteplayback/html_media_element_remote_playback.h
+++ b/chromium/third_party/blink/renderer/modules/remoteplayback/html_media_element_remote_playback.h
@@ -23,9 +23,9 @@ class MODULES_EXPORT HTMLMediaElementRemotePlayback final {
STATIC_ONLY(HTMLMediaElementRemotePlayback);
public:
- static bool FastHasAttribute(const QualifiedName&, const HTMLMediaElement&);
- static void SetBooleanAttribute(const QualifiedName&,
- HTMLMediaElement&,
+ static bool FastHasAttribute(const HTMLMediaElement&, const QualifiedName&);
+ static void SetBooleanAttribute(HTMLMediaElement&,
+ const QualifiedName&,
bool);
static HTMLMediaElementRemotePlayback& From(HTMLMediaElement&);
diff --git a/chromium/third_party/blink/renderer/modules/remoteplayback/idls.gni b/chromium/third_party/blink/renderer/modules/remoteplayback/idls.gni
new file mode 100644
index 00000000000..5c61fc81eef
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/remoteplayback/idls.gni
@@ -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.
+
+modules_idl_files = [ "remote_playback.idl" ]
+
+modules_dependency_idl_files = [ "html_media_element_remote_playback.idl" ]
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 6f9836a57e1..ce408040132 100644
--- a/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc
+++ b/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc
@@ -38,15 +38,18 @@ const AtomicString& RemotePlaybackStateToString(
DEFINE_STATIC_LOCAL(const AtomicString, connected_value, ("connected"));
DEFINE_STATIC_LOCAL(const AtomicString, disconnected_value, ("disconnected"));
- if (state == mojom::blink::PresentationConnectionState::CONNECTING)
- return connecting_value;
- if (state == mojom::blink::PresentationConnectionState::CONNECTED)
- return connected_value;
- if (state == mojom::blink::PresentationConnectionState::CLOSED)
- return disconnected_value;
-
- NOTREACHED();
- return disconnected_value;
+ switch (state) {
+ case mojom::blink::PresentationConnectionState::CONNECTING:
+ return connecting_value;
+ case mojom::blink::PresentationConnectionState::CONNECTED:
+ return connected_value;
+ case mojom::blink::PresentationConnectionState::CLOSED:
+ case mojom::blink::PresentationConnectionState::TERMINATED:
+ return disconnected_value;
+ default:
+ NOTREACHED();
+ return disconnected_value;
+ }
}
void RunRemotePlaybackTask(ExecutionContext* context,
@@ -88,7 +91,7 @@ RemotePlayback& RemotePlayback::From(HTMLMediaElement& element) {
}
RemotePlayback::RemotePlayback(HTMLMediaElement& element)
- : ContextLifecycleObserver(element.GetExecutionContext()),
+ : ExecutionContextLifecycleObserver(element.GetExecutionContext()),
RemotePlaybackController(element),
state_(mojom::blink::PresentationConnectionState::CLOSED),
availability_(mojom::ScreenAvailability::UNKNOWN),
@@ -100,7 +103,7 @@ const AtomicString& RemotePlayback::InterfaceName() const {
}
ExecutionContext* RemotePlayback::GetExecutionContext() const {
- return &media_element_->GetDocument();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
ScriptPromise RemotePlayback::watchAvailability(
@@ -241,7 +244,7 @@ bool RemotePlayback::HasPendingActivity() const {
prompt_promise_resolver_;
}
-void RemotePlayback::ContextDestroyed(ExecutionContext*) {
+void RemotePlayback::ContextDestroyed() {
CleanupConnections();
}
@@ -281,6 +284,9 @@ int RemotePlayback::WatchAvailabilityInternal(
return kWatchAvailabilityNotSupported;
}
+ if (!GetExecutionContext())
+ return kWatchAvailabilityNotSupported;
+
int id;
do {
id = GetExecutionContext()->CircularSequentialID();
@@ -366,7 +372,8 @@ void RemotePlayback::StateChanged(
media_element_->FlingingStarted();
} else if (state_ == mojom::blink::PresentationConnectionState::CONNECTED) {
DispatchEvent(*Event::Create(event_type_names::kConnect));
- } else if (state_ == mojom::blink::PresentationConnectionState::CLOSED) {
+ } else if (state_ == mojom::blink::PresentationConnectionState::CLOSED ||
+ state_ == mojom::blink::PresentationConnectionState::TERMINATED) {
DispatchEvent(*Event::Create(event_type_names::kDisconnect));
if (auto* video_element =
DynamicTo<HTMLVideoElement>(media_element_.Get())) {
@@ -462,8 +469,10 @@ void RemotePlayback::RemotePlaybackDisabled() {
availability_callbacks_.clear();
StopListeningForAvailability();
- if (state_ == mojom::blink::PresentationConnectionState::CLOSED)
+ if (state_ == mojom::blink::PresentationConnectionState::CLOSED ||
+ state_ == mojom::blink::PresentationConnectionState::TERMINATED) {
return;
+ }
auto* controller = PresentationController::FromContext(GetExecutionContext());
if (controller) {
@@ -592,13 +601,13 @@ void RemotePlayback::MaybeStartListeningForAvailability() {
is_listening_ = true;
}
-void RemotePlayback::Trace(blink::Visitor* visitor) {
+void RemotePlayback::Trace(Visitor* visitor) {
visitor->Trace(availability_callbacks_);
visitor->Trace(prompt_promise_resolver_);
visitor->Trace(media_element_);
visitor->Trace(observers_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
RemotePlaybackController::Trace(visitor);
}
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 70b99402b7a..68e396bb05a 100644
--- a/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.h
+++ b/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.h
@@ -14,8 +14,8 @@
#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/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/html/media/remote_playback_controller.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/presentation/presentation_availability_observer.h"
@@ -40,7 +40,7 @@ class V8RemotePlaybackAvailabilityCallback;
// - A remote playback session is implemented as a PresentationConnection.
class MODULES_EXPORT RemotePlayback final
: public EventTargetWithInlineData,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public ActiveScriptWrappable<RemotePlayback>,
public WebRemotePlaybackClient,
public PresentationAvailabilityObserver,
@@ -125,8 +125,8 @@ class MODULES_EXPORT RemotePlayback final
// ScriptWrappable implementation.
bool HasPendingActivity() const final;
- // ContextLifecycleObserver implementation.
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver implementation.
+ void ContextDestroyed() override;
// Adjusts the internal state of |this| after a playback state change.
void StateChanged(mojom::blink::PresentationConnectionState);
@@ -135,7 +135,7 @@ class MODULES_EXPORT RemotePlayback final
DEFINE_ATTRIBUTE_EVENT_LISTENER(connect, kConnect)
DEFINE_ATTRIBUTE_EVENT_LISTENER(disconnect, kDisconnect)
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
friend class V8RemotePlayback;
diff --git a/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback_test.cc b/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback_test.cc
index 4228514f76b..d6863c62008 100644
--- a/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback_test.cc
+++ b/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback_test.cc
@@ -23,6 +23,8 @@
namespace blink {
+namespace {
+
class MockFunction : public ScriptFunction {
public:
static testing::StrictMock<MockFunction>* Create(ScriptState* script_state) {
@@ -55,6 +57,7 @@ class MockPresentationController final : public PresentationController {
MOCK_METHOD1(RemoveAvailabilityObserver,
void(PresentationAvailabilityObserver*));
};
+} // namespace
class RemotePlaybackTest : public testing::Test,
private ScopedRemotePlaybackBackendForTest {
@@ -192,6 +195,7 @@ TEST_F(RemotePlaybackTest, StateChangeEvents) {
remote_playback.addEventListener(event_type_names::kDisconnect,
disconnect_handler);
+ // Verify a state changes when a route is connected and closed.
EXPECT_CALL(*connecting_handler, Invoke(testing::_, testing::_)).Times(1);
EXPECT_CALL(*connect_handler, Invoke(testing::_, testing::_)).Times(1);
EXPECT_CALL(*disconnect_handler, Invoke(testing::_, testing::_)).Times(1);
@@ -212,6 +216,30 @@ TEST_F(RemotePlaybackTest, StateChangeEvents) {
testing::Mock::VerifyAndClear(connecting_handler);
testing::Mock::VerifyAndClear(connect_handler);
testing::Mock::VerifyAndClear(disconnect_handler);
+
+ // Verify a state changes when a route is connected and terminated.
+ EXPECT_CALL(*connecting_handler, Invoke(testing::_, testing::_)).Times(1);
+ EXPECT_CALL(*connect_handler, Invoke(testing::_, testing::_)).Times(1);
+ EXPECT_CALL(*disconnect_handler, Invoke(testing::_, testing::_)).Times(1);
+
+ SetState(remote_playback,
+ mojom::blink::PresentationConnectionState::CONNECTING);
+ SetState(remote_playback,
+ mojom::blink::PresentationConnectionState::CONNECTED);
+ SetState(remote_playback,
+ mojom::blink::PresentationConnectionState::TERMINATED);
+
+ // Verify mock expectations explicitly as the mock objects are garbage
+ // collected.
+ testing::Mock::VerifyAndClear(connecting_handler);
+ testing::Mock::VerifyAndClear(connect_handler);
+ testing::Mock::VerifyAndClear(disconnect_handler);
+
+ // Verify we can connect after a route termination.
+ EXPECT_CALL(*connecting_handler, Invoke(testing::_, testing::_)).Times(1);
+ SetState(remote_playback,
+ mojom::blink::PresentationConnectionState::CONNECTING);
+ testing::Mock::VerifyAndClear(connecting_handler);
}
TEST_F(RemotePlaybackTest,
@@ -234,7 +262,7 @@ TEST_F(RemotePlaybackTest,
remote_playback.prompt(scope.GetScriptState())
.Then(resolve->Bind(), reject->Bind());
HTMLMediaElementRemotePlayback::SetBooleanAttribute(
- html_names::kDisableremoteplaybackAttr, *element, true);
+ *element, html_names::kDisableremoteplaybackAttr, true);
// Runs pending promises.
v8::MicrotasksScope::PerformCheckpoint(scope.GetIsolate());
@@ -274,7 +302,7 @@ TEST_F(RemotePlaybackTest, DisableRemotePlaybackCancelsAvailabilityCallbacks) {
.Then(resolve->Bind(), reject->Bind());
HTMLMediaElementRemotePlayback::SetBooleanAttribute(
- html_names::kDisableremoteplaybackAttr, *element, true);
+ *element, html_names::kDisableremoteplaybackAttr, true);
// Runs pending promises.
v8::MicrotasksScope::PerformCheckpoint(scope.GetIsolate());
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 c8327ba8b48..b9620939d45 100644
--- a/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.cc
+++ b/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.cc
@@ -5,11 +5,12 @@
#include "third_party/blink/renderer/modules/scheduler/dom_scheduler.h"
#include "base/memory/weak_ptr.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_scheduler_post_task_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_task_signal.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/modules/scheduler/dom_task.h"
#include "third_party/blink/renderer/modules/scheduler/dom_task_signal.h"
-#include "third_party/blink/renderer/modules/scheduler/scheduler_post_task_options.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_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"
@@ -18,11 +19,12 @@ namespace blink {
namespace {
-static ScriptPromise RejectPromiseImmediately(ScriptState* script_state) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError,
- "Current document is detached"));
+static ScriptPromise RejectPromiseImmediately(ExceptionState& exception_state) {
+ // The bindings layer implicitly converts thrown exceptions in
+ // promise-returning functions to promise rejections.
+ exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
+ "Current document is detached");
+ return ScriptPromise();
}
} // namespace
@@ -39,7 +41,8 @@ DOMScheduler* DOMScheduler::From(Document& document) {
}
DOMScheduler::DOMScheduler(Document* document)
- : ContextLifecycleObserver(document) {
+ : ExecutionContextLifecycleObserver(document),
+ Supplement<Document>(*document) {
if (document->IsContextDestroyed())
return;
DCHECK(document->GetScheduler());
@@ -47,53 +50,54 @@ DOMScheduler::DOMScheduler(Document* document)
CreateGlobalTaskQueues(document);
}
-void DOMScheduler::ContextDestroyed(ExecutionContext* context) {
+void DOMScheduler::ContextDestroyed() {
global_task_queues_.clear();
}
void DOMScheduler::Trace(Visitor* visitor) {
ScriptWrappable::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
Supplement<Document>::Trace(visitor);
}
-// TODO(japhet,shaseley): These are probably useful for metrics/tracing, or
-// for handling incumbent task state.
-void DOMScheduler::OnTaskStarted(DOMTask*) {}
-void DOMScheduler::OnTaskCompleted(DOMTask*) {}
-
ScriptPromise DOMScheduler::postTask(ScriptState* script_state,
V8Function* callback_function,
SchedulerPostTaskOptions* options,
- const HeapVector<ScriptValue>& args) {
+ const HeapVector<ScriptValue>& args,
+ ExceptionState& exception_state) {
if (!GetExecutionContext() || GetExecutionContext()->IsContextDestroyed())
- return RejectPromiseImmediately(script_state);
-
- // Always honor the priority and the task signal if given. Therefore:
- // * If both priority and signal are set, use the signal but choose the
- // default task runner for the given priority, so that it is scheduled at
- // the given priority.
- // * If only the signal is set, use the signal and its associated priority.
- // * If only a priority is set, use the default task runner for that priority,
- // and no signal.
- // * If neither is set, use the default priority task runner and no signal.
- //
- // Note that |options->signal()| may be a generic AbortSignal, rather than a
- // TaskSignal. In that case, use it for abort signalling, but use a default
- // task runner for priority purposes.
- base::SingleThreadTaskRunner* task_runner = nullptr;
- if (options->hasPriority()) {
- WebSchedulingPriority priority =
- WebSchedulingPriorityFromString(AtomicString(options->priority()));
- task_runner = GetTaskRunnerFor(priority);
- } else if (auto* task_signal = DynamicTo<DOMTaskSignal>(options->signal())) {
- task_runner = task_signal->GetTaskRunner();
- if (!task_runner)
- return RejectPromiseImmediately(script_state);
+ return RejectPromiseImmediately(exception_state);
+ if (options->signal() && options->signal()->aborted())
+ return RejectPromiseImmediately(exception_state);
+
+ // Always honor the priority and the task signal if given.
+ DOMTaskSignal* task_signal = nullptr;
+ if (!options->hasPriority() && 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());
} else {
- task_runner = GetTaskRunnerFor(WebSchedulingPriority::kDefaultPriority);
+ // Otherwise, construct an implicit TaskSignal. Have it follow the signal
+ // if it was given, so that it can still honor any aborts, but have it
+ // at the fixed given priority (or default if none was specified).
+ //
+ // An implicit TaskSignal, in addition to being read-only, won't own its
+ // own task queue. Instead, it will use the appropriate task queue from
+ // |global_task_queues_|.
+ WebSchedulingPriority priority =
+ options->hasPriority()
+ ? WebSchedulingPriorityFromString(AtomicString(options->priority()))
+ : WebSchedulingPriority::kUserVisiblePriority;
+ task_signal = MakeGarbageCollected<DOMTaskSignal>(
+ GetSupplementable(), priority, DOMTaskSignal::Type::kImplicit);
+ if (options->signal())
+ task_signal->Follow(options->signal());
}
+ DCHECK(task_signal);
+ if (!task_signal->GetTaskRunner())
+ return RejectPromiseImmediately(exception_state);
+
// TODO(shaseley): We need to figure out the behavior we want for delay. For
// now, we use behavior that is very similar to setTimeout: negative delays
// are treated as 0, and we use the Blink scheduler's delayed task behavior.
@@ -104,10 +108,22 @@ ScriptPromise DOMScheduler::postTask(ScriptState* script_state,
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
MakeGarbageCollected<DOMTask>(this, resolver, callback_function, args,
- task_runner, options->signal(), delay);
+ task_signal, delay);
return resolver->Promise();
}
+DOMTaskSignal* DOMScheduler::currentTaskSignal(
+ ScriptState* script_state) const {
+ v8::Local<v8::Value> embedder_data =
+ script_state->GetContext()->GetContinuationPreservedEmbedderData();
+ if (V8TaskSignal::HasInstance(embedder_data, script_state->GetIsolate()))
+ return V8TaskSignal::ToImpl(v8::Local<v8::Object>::Cast(embedder_data));
+
+ return MakeGarbageCollected<DOMTaskSignal>(
+ GetSupplementable(), WebSchedulingPriority::kUserVisiblePriority,
+ DOMTaskSignal::Type::kImplicit);
+}
+
base::SingleThreadTaskRunner* DOMScheduler::GetTaskRunnerFor(
WebSchedulingPriority priority) {
DCHECK(!global_task_queues_.IsEmpty());
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 f83cd93f4e1..7b9e6756bec 100644
--- a/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.h
+++ b/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.h
@@ -7,7 +7,7 @@
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/heap/handle.h"
@@ -18,14 +18,15 @@
namespace blink {
class DOMTask;
-class ExecutionContext;
+class DOMTaskSignal;
+class ExceptionState;
class SchedulerPostTaskOptions;
class ScriptValue;
class V8Function;
class WebSchedulingTaskQueue;
class MODULES_EXPORT DOMScheduler : public ScriptWrappable,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public Supplement<Document> {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(DOMScheduler);
@@ -46,13 +47,25 @@ class MODULES_EXPORT DOMScheduler : public ScriptWrappable,
ScriptPromise postTask(ScriptState*,
V8Function*,
SchedulerPostTaskOptions*,
- const HeapVector<ScriptValue>& args);
+ const HeapVector<ScriptValue>& args,
+ ExceptionState&);
+
+ // Returns a TaskSignal representing the state when the current task was
+ // scheduled. If postTask is given a signal but no priority, it will return
+ // that signal. If postTask is given both a signal and a priority, it will
+ // return a signal with the given priority that follows the given signal.
+ // If a priority only was given, it will return a signal with the given
+ // priority that neither follows another signal nor is known to a controller,
+ // and is therefore unmodifiable. If called outside of a postTask task, it
+ // will return a task signal at the default priority (user-visible).
+ // NOTE: This uses V8's ContinuationPreservedEmbedderData to propagate the
+ // currentTaskSignal across microtask boundaries, so it will remain usable
+ // even in then() blocks or after an await in an async function.
+ DOMTaskSignal* currentTaskSignal(ScriptState*) const;
- // Callbacks invoked by DOMTasks when they run.
- void OnTaskStarted(DOMTask*);
- void OnTaskCompleted(DOMTask*);
+ base::SingleThreadTaskRunner* GetTaskRunnerFor(WebSchedulingPriority);
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
void Trace(Visitor*) override;
@@ -61,7 +74,6 @@ class MODULES_EXPORT DOMScheduler : public ScriptWrappable,
static_cast<size_t>(WebSchedulingPriority::kLastPriority) + 1;
void CreateGlobalTaskQueues(Document*);
- base::SingleThreadTaskRunner* GetTaskRunnerFor(WebSchedulingPriority);
// |global_task_queues_| is initialized with one entry per priority, indexed
// by priority. This will be empty when the document is detached.
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 00531c8139f..38cf7b4ba6b 100644
--- a/chromium/third_party/blink/renderer/modules/scheduler/dom_task.cc
+++ b/chromium/third_party/blink/renderer/modules/scheduler/dom_task.cc
@@ -7,40 +7,59 @@
#include <utility>
#include "base/logging.h"
+#include "base/metrics/histogram_macros.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_function.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
+#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/modules/scheduler/dom_scheduler.h"
#include "third_party/blink/renderer/modules/scheduler/dom_task_signal.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
namespace blink {
+#define QUEUEING_TIME_PER_PRIORITY_METRIC_NAME \
+ "DOMScheduler.QueueingDurationPerPriority"
+
+#define PRIORITY_CHANGED_HISTOGRAM_NAME \
+ "DOMSchedler.TaskSignalPriorityWasChanged"
+
+// Same as UMA_HISTOGRAM_TIMES but for a broader view of this metric we end
+// at 1 minute instead of 10 seconds.
+#define QUEUEING_TIME_HISTOGRAM(name, sample) \
+ UMA_HISTOGRAM_CUSTOM_TIMES(QUEUEING_TIME_PER_PRIORITY_METRIC_NAME name, \
+ sample, base::TimeDelta::FromMilliseconds(1), \
+ base::TimeDelta::FromMinutes(1), 50)
+
DOMTask::DOMTask(DOMScheduler* scheduler,
ScriptPromiseResolver* resolver,
V8Function* callback,
const HeapVector<ScriptValue>& args,
- base::SingleThreadTaskRunner* task_runner,
- AbortSignal* signal,
+ DOMTaskSignal* signal,
base::TimeDelta delay)
: scheduler_(scheduler),
callback_(callback),
arguments_(args),
- resolver_(resolver) {
+ resolver_(resolver),
+ signal_(signal),
+ // TODO(kdillon): Expose queuing time from base::sequence_manager so we
+ // don't have to recalculate it here.
+ queue_time_(delay.is_zero() ? base::TimeTicks::Now()
+ : base::TimeTicks()) {
+ DCHECK(signal_);
+ DCHECK(signal_->GetTaskRunner());
DCHECK(callback_);
- DCHECK(task_runner);
- if (signal) {
- if (signal->aborted()) {
- Abort();
- return;
- }
-
- signal->AddAlgorithm(WTF::Bind(&DOMTask::Abort, WrapWeakPersistent(this)));
- }
+ signal_->AddAlgorithm(WTF::Bind(&DOMTask::Abort, WrapWeakPersistent(this)));
task_handle_ = PostDelayedCancellableTask(
- *task_runner, FROM_HERE,
+ *signal_->GetTaskRunner(), FROM_HERE,
WTF::Bind(&DOMTask::Invoke, WrapPersistent(this)), delay);
+
+ ScriptState* script_state =
+ callback_->CallbackRelevantScriptStateOrReportError("DOMTask", "Create");
+ DCHECK(script_state && script_state->ContextIsValid());
+ probe::AsyncTaskScheduled(ExecutionContext::From(script_state), "postTask",
+ &async_task_id_);
}
void DOMTask::Trace(Visitor* visitor) {
@@ -48,6 +67,7 @@ void DOMTask::Trace(Visitor* visitor) {
visitor->Trace(callback_);
visitor->Trace(arguments_);
visitor->Trace(resolver_);
+ visitor->Trace(signal_);
}
void DOMTask::Invoke() {
@@ -58,28 +78,74 @@ void DOMTask::Invoke() {
if (!script_state || !script_state->ContextIsValid())
return;
- scheduler_->OnTaskStarted(this);
+ RecordTaskStartMetrics();
InvokeInternal(script_state);
- scheduler_->OnTaskCompleted(this);
callback_.Release();
}
void DOMTask::InvokeInternal(ScriptState* script_state) {
+ v8::Isolate* isolate = script_state->GetIsolate();
ScriptState::Scope scope(script_state);
- v8::TryCatch try_catch(script_state->GetIsolate());
+ v8::TryCatch try_catch(isolate);
try_catch.SetVerbose(true);
+ ExecutionContext* context = ExecutionContext::From(script_state);
+ DCHECK(context);
+ probe::AsyncTask async_task(context, &async_task_id_);
+ probe::UserCallback probe(context, "postTask", AtomicString(), true);
+
+ v8::Local<v8::Context> v8_context = script_state->GetContext();
+ v8_context->SetContinuationPreservedEmbedderData(
+ ToV8(signal_.Get(), v8_context->Global(), isolate));
ScriptValue result;
if (callback_->Invoke(nullptr, arguments_).To(&result))
resolver_->Resolve(result.V8Value());
else if (try_catch.HasCaught())
resolver_->Reject(try_catch.Exception());
+ v8_context->SetContinuationPreservedEmbedderData(v8::Local<v8::Object>());
}
void DOMTask::Abort() {
+ // If the task has already finished running, the promise is either resolved or
+ // rejected, in which case abort will no longer have any effect.
+ if (!callback_)
+ return;
+
task_handle_.Cancel();
resolver_->Reject(
MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError));
+
+ ScriptState* script_state =
+ callback_->CallbackRelevantScriptStateOrReportError("DOMTask", "Abort");
+ DCHECK(script_state && script_state->ContextIsValid());
+ probe::AsyncTaskCanceled(ExecutionContext::From(script_state),
+ &async_task_id_);
+}
+
+void DOMTask::RecordTaskStartMetrics() {
+ UMA_HISTOGRAM_ENUMERATION(PRIORITY_CHANGED_HISTOGRAM_NAME,
+ signal_->GetPriorityChangeStatus());
+
+ if (queue_time_ > base::TimeTicks()) {
+ base::TimeDelta queue_duration = base::TimeTicks::Now() - queue_time_;
+ DCHECK_GT(queue_duration, base::TimeDelta());
+ if (signal_->GetPriorityChangeStatus() ==
+ DOMTaskSignal::PriorityChangeStatus::kNoPriorityChange) {
+ WebSchedulingPriority priority =
+ WebSchedulingPriorityFromString(signal_->priority());
+ switch (priority) {
+ case WebSchedulingPriority::kUserBlockingPriority:
+ QUEUEING_TIME_HISTOGRAM(".UserBlocking", queue_duration);
+ break;
+ case WebSchedulingPriority::kUserVisiblePriority:
+ QUEUEING_TIME_HISTOGRAM(".UserVisable", queue_duration);
+ break;
+ case WebSchedulingPriority::kBackgroundPriority:
+ QUEUEING_TIME_HISTOGRAM(".Background", queue_duration);
+ break;
+ }
+ }
+ }
}
} // namespace blink
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 00b7ed66642..d9c4f784d0c 100644
--- a/chromium/third_party/blink/renderer/modules/scheduler/dom_task.h
+++ b/chromium/third_party/blink/renderer/modules/scheduler/dom_task.h
@@ -7,12 +7,13 @@
#include "base/time/time.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/core/probe/async_task_id.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
namespace blink {
-class AbortSignal;
class DOMScheduler;
+class DOMTaskSignal;
class ScriptState;
class ScriptValue;
class V8Function;
@@ -26,8 +27,7 @@ class DOMTask final : public GarbageCollected<DOMTask> {
ScriptPromiseResolver*,
V8Function*,
const HeapVector<ScriptValue>& args,
- base::SingleThreadTaskRunner*,
- AbortSignal*,
+ DOMTaskSignal*,
base::TimeDelta delay);
virtual void Trace(Visitor*);
@@ -40,11 +40,16 @@ class DOMTask final : public GarbageCollected<DOMTask> {
void InvokeInternal(ScriptState*);
void Abort();
+ void RecordTaskStartMetrics();
+
Member<DOMScheduler> scheduler_;
TaskHandle task_handle_;
Member<V8Function> callback_;
HeapVector<ScriptValue> arguments_;
Member<ScriptPromiseResolver> resolver_;
+ probe::AsyncTaskId async_task_id_;
+ Member<DOMTaskSignal> signal_;
+ const base::TimeTicks queue_time_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/scheduler/dom_task_controller.cc b/chromium/third_party/blink/renderer/modules/scheduler/dom_task_controller.cc
index 71af9a922e0..30ae3d8f65d 100644
--- a/chromium/third_party/blink/renderer/modules/scheduler/dom_task_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/scheduler/dom_task_controller.cc
@@ -18,8 +18,10 @@ DOMTaskController* DOMTaskController::Create(Document& document,
DOMTaskController::DOMTaskController(Document& document,
WebSchedulingPriority priority)
- : AbortController(
- MakeGarbageCollected<DOMTaskSignal>(&document, priority)) {
+ : AbortController(MakeGarbageCollected<DOMTaskSignal>(
+ &document,
+ priority,
+ DOMTaskSignal::Type::kCreatedByController)) {
DCHECK(!document.IsContextDestroyed());
}
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 a350ac89d6f..08ec26c110b 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
@@ -8,6 +8,7 @@
#include "base/callback.h"
#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/modules/scheduler/dom_scheduler.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
@@ -18,13 +19,17 @@
namespace blink {
-DOMTaskSignal::DOMTaskSignal(Document* document, WebSchedulingPriority priority)
- : AbortSignal(document),
- ContextLifecycleObserver(document),
- priority_(priority),
- web_scheduling_task_queue_(document->GetScheduler()
+DOMTaskSignal::DOMTaskSignal(Document* document,
+ WebSchedulingPriority priority,
+ Type type)
+ : AbortSignal(document->ToExecutionContext()),
+ ExecutionContextLifecycleObserver(document),
+ priority_(priority) {
+ if (type == Type::kCreatedByController) {
+ web_scheduling_task_queue_ = document->GetScheduler()
->ToFrameScheduler()
- ->CreateWebSchedulingTaskQueue(priority)) {
+ ->CreateWebSchedulingTaskQueue(priority_);
+ }
}
DOMTaskSignal::~DOMTaskSignal() = default;
@@ -33,7 +38,7 @@ AtomicString DOMTaskSignal::priority() {
return WebSchedulingPriorityToString(priority_);
}
-void DOMTaskSignal::ContextDestroyed(ExecutionContext*) {
+void DOMTaskSignal::ContextDestroyed() {
web_scheduling_task_queue_.reset();
}
@@ -43,17 +48,23 @@ void DOMTaskSignal::SignalPriorityChange(WebSchedulingPriority priority) {
priority_ = priority;
if (web_scheduling_task_queue_)
web_scheduling_task_queue_->SetPriority(priority);
+ priority_change_status_ = PriorityChangeStatus::kPriorityHasChanged;
+ DispatchEvent(*Event::Create(event_type_names::kPrioritychange));
}
base::SingleThreadTaskRunner* DOMTaskSignal::GetTaskRunner() {
- return web_scheduling_task_queue_
- ? web_scheduling_task_queue_->GetTaskRunner().get()
- : nullptr;
+ auto* document =
+ Document::From(ExecutionContextLifecycleObserver::GetExecutionContext());
+ if (!document)
+ return nullptr;
+ if (web_scheduling_task_queue_)
+ return web_scheduling_task_queue_->GetTaskRunner().get();
+ return DOMScheduler::From(*document)->GetTaskRunnerFor(priority_);
}
void DOMTaskSignal::Trace(Visitor* visitor) {
AbortSignal::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 8311a099b78..b3ccd939ade 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
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_DOM_TASK_SIGNAL_H_
#include "third_party/blink/renderer/core/dom/abort_signal.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/scheduler/public/web_scheduling_priority.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
@@ -17,22 +17,34 @@ class SingleThreadTaskRunner;
namespace blink {
class Document;
-class ExecutionContext;
class WebSchedulingTaskQueue;
-class MODULES_EXPORT DOMTaskSignal final : public AbortSignal,
- public ContextLifecycleObserver {
+class MODULES_EXPORT DOMTaskSignal final
+ : public AbortSignal,
+ public ExecutionContextLifecycleObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(DOMTaskSignal);
public:
- explicit DOMTaskSignal(Document*, WebSchedulingPriority);
+ enum class Type { kCreatedByController, kImplicit };
+
+ // These values are persisted to logs. Entries should not be renumbered and
+ // numeric values should never be reused.
+ enum class PriorityChangeStatus {
+ kNoPriorityChange = 0,
+ kPriorityHasChanged = 1,
+
+ kMaxValue = kPriorityHasChanged
+ };
+
+ DOMTaskSignal(Document*, WebSchedulingPriority, Type);
~DOMTaskSignal() override;
// task_signal.idl
AtomicString priority();
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(prioritychange, kPrioritychange)
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
void SignalPriorityChange(WebSchedulingPriority);
base::SingleThreadTaskRunner* GetTaskRunner();
@@ -41,6 +53,10 @@ class MODULES_EXPORT DOMTaskSignal final : public AbortSignal,
void Trace(Visitor*) override;
+ PriorityChangeStatus GetPriorityChangeStatus() const {
+ return priority_change_status_;
+ }
+
private:
WebSchedulingPriority priority_;
@@ -50,6 +66,9 @@ class MODULES_EXPORT DOMTaskSignal final : public AbortSignal,
// detach, so a DOMTaskSignal will fail to schedule tasks in a detached
// frame.
std::unique_ptr<WebSchedulingTaskQueue> web_scheduling_task_queue_;
+
+ PriorityChangeStatus priority_change_status_ =
+ PriorityChangeStatus::kNoPriorityChange;
};
template <>
diff --git a/chromium/third_party/blink/renderer/modules/scheduler/idls.gni b/chromium/third_party/blink/renderer/modules/scheduler/idls.gni
new file mode 100644
index 00000000000..eeb622a4d78
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/scheduler/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "scheduler.idl",
+ "task_controller.idl",
+ "task_signal.idl",
+]
+
+modules_dictionary_idl_files = [ "scheduler_post_task_options.idl" ]
+
+modules_dependency_idl_files = [ "window_scheduler.idl" ]
diff --git a/chromium/third_party/blink/renderer/modules/scheduler/scheduler.idl b/chromium/third_party/blink/renderer/modules/scheduler/scheduler.idl
index 5c2f4b7a03a..a90601caa96 100644
--- a/chromium/third_party/blink/renderer/modules/scheduler/scheduler.idl
+++ b/chromium/third_party/blink/renderer/modules/scheduler/scheduler.idl
@@ -8,5 +8,6 @@
ImplementedAs=DOMScheduler,
RuntimeEnabled=WebScheduler
] interface Scheduler {
- [CallWith=ScriptState] Promise<any> postTask(Function callback, optional SchedulerPostTaskOptions options, any... arguments);
+ [CallWith=ScriptState, MeasureAs=SchedulerPostTask, RaisesException] Promise<any> postTask(Function callback, optional SchedulerPostTaskOptions options = {}, any... arguments);
+ [CallWith=ScriptState, MeasureAs=SchedulerCurrentTaskSignal] readonly attribute TaskSignal currentTaskSignal;
};
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 854de5bdc13..c3a301134ef 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
@@ -5,11 +5,9 @@
// Experimental Scheduling API Proposal:
// https://docs.google.com/document/d/1xU7HyNsEsbXhTgt0ZnXDbeSXm5-m5FzkLJAT6LTizEI/edit#
enum TaskPriority {
- "immediate",
- "high",
- "default",
- "low",
- "idle"
+ "user-blocking",
+ "user-visible",
+ "background"
};
dictionary SchedulerPostTaskOptions {
diff --git a/chromium/third_party/blink/renderer/modules/scheduler/task_controller.idl b/chromium/third_party/blink/renderer/modules/scheduler/task_controller.idl
index bfa247c272b..ac22aec237f 100644
--- a/chromium/third_party/blink/renderer/modules/scheduler/task_controller.idl
+++ b/chromium/third_party/blink/renderer/modules/scheduler/task_controller.idl
@@ -6,11 +6,11 @@
// https://docs.google.com/document/d/1xU7HyNsEsbXhTgt0ZnXDbeSXm5-m5FzkLJAT6LTizEI/edit#
[
- Constructor(optional TaskPriority priority = "default"),
- ConstructorCallWith=Document,
ImplementedAs=DOMTaskController,
+ MeasureAs=TaskControllerConstructor,
RuntimeEnabled=WebScheduler
] interface TaskController : AbortController {
- void setPriority(TaskPriority priority);
+ [CallWith=Document] constructor(optional TaskPriority priority = "user-visible");
+ [MeasureAs=TaskControllerSetPriority] void setPriority(TaskPriority priority);
};
diff --git a/chromium/third_party/blink/renderer/modules/scheduler/task_signal.idl b/chromium/third_party/blink/renderer/modules/scheduler/task_signal.idl
index ff62edc04ae..1943e81a955 100644
--- a/chromium/third_party/blink/renderer/modules/scheduler/task_signal.idl
+++ b/chromium/third_party/blink/renderer/modules/scheduler/task_signal.idl
@@ -9,5 +9,6 @@
ImplementedAs=DOMTaskSignal,
RuntimeEnabled=WebScheduler
] interface TaskSignal : AbortSignal {
- readonly attribute TaskPriority priority;
+ [MeasureAs=TaskSignalPriority] readonly attribute TaskPriority priority;
+ attribute EventHandler onprioritychange;
};
diff --git a/chromium/third_party/blink/renderer/modules/screen_enumeration/BUILD.gn b/chromium/third_party/blink/renderer/modules/screen_enumeration/BUILD.gn
index 595c80d9579..8460b99ad05 100644
--- a/chromium/third_party/blink/renderer/modules/screen_enumeration/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/screen_enumeration/BUILD.gn
@@ -6,10 +6,8 @@ import("//third_party/blink/renderer/modules/modules.gni")
blink_modules_sources("screen_enumeration") {
sources = [
- "navigator_screen_manager.cc",
- "navigator_screen_manager.h",
- "screen_manager.cc",
- "screen_manager.h",
+ "global_screen_enumeration.cc",
+ "global_screen_enumeration.h",
]
public_deps = [
diff --git a/chromium/third_party/blink/renderer/modules/screen_enumeration/screen_manager.cc b/chromium/third_party/blink/renderer/modules/screen_enumeration/global_screen_enumeration.cc
index 682e4111b9f..0dad38d92c0 100644
--- a/chromium/third_party/blink/renderer/modules/screen_enumeration/screen_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/screen_enumeration/global_screen_enumeration.cc
@@ -2,9 +2,14 @@
// 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/screen_enumeration/screen_manager.h"
+#include "third_party/blink/renderer/modules/screen_enumeration/global_screen_enumeration.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
+#include "third_party/blink/public/mojom/screen_enumeration/screen_enumeration.mojom-blink.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/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/screen.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
@@ -19,7 +24,9 @@ namespace {
void DidGetDisplays(
ScriptPromiseResolver* resolver,
+ mojo::Remote<mojom::blink::ScreenEnumeration>,
WTF::Vector<display::mojom::blink::DisplayPtr> backend_displays,
+ int64_t internal_id,
int64_t primary_id,
bool success) {
ScriptState* script_state = resolver->GetScriptState();
@@ -29,38 +36,38 @@ void DidGetDisplays(
HeapVector<Member<Screen>> screens;
screens.ReserveInitialCapacity(backend_displays.size());
for (display::mojom::blink::DisplayPtr& backend_display : backend_displays) {
+ const bool internal = backend_display->id == internal_id;
const bool primary = backend_display->id == primary_id;
- screens.emplace_back(
- MakeGarbageCollected<Screen>(std::move(backend_display), primary));
+ screens.emplace_back(MakeGarbageCollected<Screen>(
+ std::move(backend_display), internal, primary));
}
resolver->Resolve(std::move(screens));
}
} // namespace
-ScreenManager::ScreenManager(
- mojo::Remote<mojom::blink::ScreenEnumeration> backend)
- : backend_(std::move(backend)) {
- backend_.set_disconnect_handler(WTF::Bind(
- &ScreenManager::OnBackendDisconnected, WrapWeakPersistent(this)));
-}
+// static
+ScriptPromise GlobalScreenEnumeration::getScreens(
+ ScriptState* script_state,
+ LocalDOMWindow&,
+ ExceptionState& exception_state) {
+ // TODO(msw): Cache the backend connection.
+ mojo::Remote<mojom::blink::ScreenEnumeration> backend;
+ ExecutionContext::From(script_state)
+ ->GetBrowserInterfaceBroker()
+ .GetInterface(backend.BindNewPipeAndPassReceiver());
-ScriptPromise ScreenManager::getScreens(ScriptState* script_state,
- ExceptionState& exception_state) {
- if (!backend_) {
+ if (!backend) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
- "ScreenManager backend went away");
+ "ScreenEnumeration backend unavailable");
return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
- backend_->GetDisplays(WTF::Bind(&DidGetDisplays, WrapPersistent(resolver)));
-
+ auto* raw_backend = backend.get();
+ raw_backend->GetDisplays(
+ WTF::Bind(&DidGetDisplays, WrapPersistent(resolver), std::move(backend)));
return resolver->Promise();
}
-void ScreenManager::OnBackendDisconnected() {
- backend_.reset();
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/screen_enumeration/global_screen_enumeration.h b/chromium/third_party/blink/renderer/modules/screen_enumeration/global_screen_enumeration.h
new file mode 100644
index 00000000000..721de7f4705
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/screen_enumeration/global_screen_enumeration.h
@@ -0,0 +1,31 @@
+// 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_SCREEN_ENUMERATION_GLOBAL_SCREEN_ENUMERATION_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_SCREEN_ENUMERATION_GLOBAL_SCREEN_ENUMERATION_H_
+
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+
+namespace blink {
+
+class ExceptionState;
+class LocalDOMWindow;
+class ScriptPromise;
+class ScriptState;
+
+// A proposed interface for querying the state of the device's screen space.
+// https://github.com/webscreens/screen-enumeration
+class GlobalScreenEnumeration {
+ STATIC_ONLY(GlobalScreenEnumeration);
+
+ public:
+ // Resolves to the list of |Screen| objects in the device's screen space.
+ static ScriptPromise getScreens(ScriptState*,
+ LocalDOMWindow&,
+ ExceptionState&);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SCREEN_ENUMERATION_GLOBAL_SCREEN_ENUMERATION_H_
diff --git a/chromium/third_party/blink/renderer/modules/screen_enumeration/idls.gni b/chromium/third_party/blink/renderer/modules/screen_enumeration/idls.gni
new file mode 100644
index 00000000000..8f27fce0edb
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/screen_enumeration/idls.gni
@@ -0,0 +1,5 @@
+# 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_dependency_idl_files = [ "screen_enumeration.idl" ]
diff --git a/chromium/third_party/blink/renderer/modules/screen_enumeration/navigator_screen_manager.cc b/chromium/third_party/blink/renderer/modules/screen_enumeration/navigator_screen_manager.cc
deleted file mode 100644
index cdf517b9ff9..00000000000
--- a/chromium/third_party/blink/renderer/modules/screen_enumeration/navigator_screen_manager.cc
+++ /dev/null
@@ -1,94 +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/screen_enumeration/navigator_screen_manager.h"
-
-#include "services/service_manager/public/cpp/interface_provider.h"
-#include "third_party/blink/public/common/browser_interface_broker_proxy.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/navigator.h"
-#include "third_party/blink/renderer/core/workers/worker_navigator.h"
-#include "third_party/blink/renderer/modules/screen_enumeration/screen_manager.h"
-#include "third_party/blink/renderer/platform/supplementable.h"
-
-namespace blink {
-
-namespace {
-
-template <typename T>
-class NavigatorScreenManagerImpl final
- : public GarbageCollected<NavigatorScreenManagerImpl<T>>,
- public Supplement<T> {
- USING_GARBAGE_COLLECTED_MIXIN(NavigatorScreenManagerImpl<T>);
-
- public:
- static const char kSupplementName[];
-
- static NavigatorScreenManagerImpl<T>& From(T& supplementable) {
- NavigatorScreenManagerImpl<T>* supplement =
- Supplement<T>::template From<NavigatorScreenManagerImpl<T>>(
- supplementable);
- if (!supplement) {
- supplement =
- MakeGarbageCollected<NavigatorScreenManagerImpl<T>>(supplementable);
- Supplement<T>::ProvideTo(supplementable, supplement);
- }
- return *supplement;
- }
-
- explicit NavigatorScreenManagerImpl(T& supplementable)
- : Supplement<T>(supplementable) {}
-
- NavigatorScreenManagerImpl(const NavigatorScreenManagerImpl&) = delete;
- NavigatorScreenManagerImpl& operator=(const NavigatorScreenManagerImpl&) =
- delete;
-
- ScreenManager* GetScreen(ExecutionContext* execution_context) {
- if (!screen_manager_) {
- mojo::Remote<mojom::blink::ScreenEnumeration> backend;
- execution_context->GetBrowserInterfaceBroker().GetInterface(
- backend.BindNewPipeAndPassReceiver());
- screen_manager_ = MakeGarbageCollected<ScreenManager>(std::move(backend));
- }
- return screen_manager_;
- }
-
- void Trace(blink::Visitor* visitor) override {
- visitor->Trace(screen_manager_);
- Supplement<T>::Trace(visitor);
- }
-
- private:
- Member<ScreenManager> screen_manager_;
-};
-
-// static
-template <typename T>
-const char NavigatorScreenManagerImpl<T>::kSupplementName[] =
- "NavigatorScreenManager";
-
-} // namespace
-
-// static
-ScreenManager* NavigatorScreenManager::screen(Navigator& navigator) {
- LocalFrame* local_frame = navigator.GetFrame();
- if (!local_frame) {
- return nullptr;
- }
-
- ExecutionContext* execution_context =
- local_frame->DomWindow()->GetExecutionContext();
- return NavigatorScreenManagerImpl<Navigator>::From(navigator).GetScreen(
- execution_context);
-}
-
-// static
-ScreenManager* NavigatorScreenManager::screen(ScriptState* script_state,
- WorkerNavigator& navigator) {
- return NavigatorScreenManagerImpl<WorkerNavigator>::From(navigator).GetScreen(
- ExecutionContext::From(script_state));
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/screen_enumeration/navigator_screen_manager.h b/chromium/third_party/blink/renderer/modules/screen_enumeration/navigator_screen_manager.h
deleted file mode 100644
index fbcd82fbad4..00000000000
--- a/chromium/third_party/blink/renderer/modules/screen_enumeration/navigator_screen_manager.h
+++ /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.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SCREEN_ENUMERATION_NAVIGATOR_SCREEN_MANAGER_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_SCREEN_ENUMERATION_NAVIGATOR_SCREEN_MANAGER_H_
-
-#include "third_party/blink/renderer/modules/modules_export.h"
-
-namespace blink {
-
-class Navigator;
-class ScreenManager;
-class ScriptState;
-class WorkerNavigator;
-
-// Exposes the ScreenManager interface on both the Navigator and
-// WorkerNavigator interfaces.
-class MODULES_EXPORT NavigatorScreenManager {
- public:
- // The ScreenManager exposed in the Navigator execution context.
- static ScreenManager* screen(Navigator&);
-
- // The ScreenManager exposed in the WorkerNavigator execution context.
- static ScreenManager* screen(ScriptState*, WorkerNavigator&);
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SCREEN_ENUMERATION_NAVIGATOR_SCREEN_MANAGER_H_
diff --git a/chromium/third_party/blink/renderer/modules/screen_enumeration/navigator_screen_manager.idl b/chromium/third_party/blink/renderer/modules/screen_enumeration/navigator_screen_manager.idl
deleted file mode 100644
index d9062139381..00000000000
--- a/chromium/third_party/blink/renderer/modules/screen_enumeration/navigator_screen_manager.idl
+++ /dev/null
@@ -1,12 +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.
-
-// https://github.com/spark008/screen-enumeration/blob/master/EXPLAINER.md
-[
- ImplementedAs=NavigatorScreenManager,
- SecureContext,
- RuntimeEnabled=ScreenEnumeration
-] partial interface Navigator {
- [SameObject] readonly attribute ScreenManager screen;
-};
diff --git a/chromium/third_party/blink/renderer/modules/screen_enumeration/screen_manager.idl b/chromium/third_party/blink/renderer/modules/screen_enumeration/screen_enumeration.idl
index 9ee9d13f139..42071592a88 100644
--- a/chromium/third_party/blink/renderer/modules/screen_enumeration/screen_manager.idl
+++ b/chromium/third_party/blink/renderer/modules/screen_enumeration/screen_enumeration.idl
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://github.com/spark008/screen-enumeration/blob/master/EXPLAINER.md
+// https://github.com/webscreens/screen-enumeration
[
SecureContext,
- Exposed=(Window,Worker),
- RuntimeEnabled=ScreenEnumeration
-] interface ScreenManager {
+ RuntimeEnabled=ScreenEnumeration,
+ ImplementedAs=GlobalScreenEnumeration
+] partial interface Window {
[CallWith=ScriptState, RaisesException] Promise<sequence<Screen>> getScreens();
};
diff --git a/chromium/third_party/blink/renderer/modules/screen_enumeration/screen_manager.h b/chromium/third_party/blink/renderer/modules/screen_enumeration/screen_manager.h
deleted file mode 100644
index ef1f3012af4..00000000000
--- a/chromium/third_party/blink/renderer/modules/screen_enumeration/screen_manager.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_MODULES_SCREEN_ENUMERATION_SCREEN_MANAGER_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_SCREEN_ENUMERATION_SCREEN_MANAGER_H_
-
-#include "mojo/public/cpp/bindings/remote.h"
-#include "third_party/blink/public/mojom/screen_enumeration/screen_enumeration.mojom-blink.h"
-#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
-#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
-
-namespace blink {
-
-class ScriptState;
-
-// A proposed interface for querying the state of the device's screen space.
-// https://github.com/spark008/screen-enumeration/blob/master/EXPLAINER.md
-// The interface is available in both window and worker execution contexts.
-class ScreenManager final : public ScriptWrappable {
- DEFINE_WRAPPERTYPEINFO();
-
- public:
- // Creates a ScreenManager and binds it to the browser-side implementation.
- explicit ScreenManager(mojo::Remote<mojom::blink::ScreenEnumeration> backend);
-
- // Resolves to the list of |Screen| objects in the device's screen space.
- ScriptPromise getScreens(ScriptState*, ExceptionState&);
-
- // Called if the backend is disconnected, e.g. during renderer shutdown.
- void OnBackendDisconnected();
-
- private:
- // Connection to the ScreenEnumeration implementation in the browser process.
- mojo::Remote<mojom::blink::ScreenEnumeration> backend_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SCREEN_ENUMERATION_SCREEN_MANAGER_H_
diff --git a/chromium/third_party/blink/renderer/modules/screen_enumeration/worker_navigator_screen_manager.idl b/chromium/third_party/blink/renderer/modules/screen_enumeration/worker_navigator_screen_manager.idl
deleted file mode 100644
index 04e2cf45669..00000000000
--- a/chromium/third_party/blink/renderer/modules/screen_enumeration/worker_navigator_screen_manager.idl
+++ /dev/null
@@ -1,12 +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.
-
-// https://github.com/spark008/screen-enumeration/blob/master/EXPLAINER.md
-[
- ImplementedAs=NavigatorScreenManager,
- SecureContext,
- RuntimeEnabled=ScreenEnumeration
-] partial interface WorkerNavigator {
- [CallWith=ScriptState, SameObject] readonly attribute ScreenManager screen;
-};
diff --git a/chromium/third_party/blink/renderer/modules/screen_orientation/idls.gni b/chromium/third_party/blink/renderer/modules/screen_orientation/idls.gni
new file mode 100644
index 00000000000..9b71e5a28de
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/screen_orientation/idls.gni
@@ -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.
+
+modules_idl_files = [ "screen_orientation.idl" ]
+
+modules_dependency_idl_files = [ "screen_screen_orientation.idl" ]
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 79c43ee3e85..b232b8fb589 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
@@ -117,7 +117,9 @@ ScreenOrientation* ScreenOrientation::Create(LocalFrame* frame) {
}
ScreenOrientation::ScreenOrientation(LocalFrame* frame)
- : ContextClient(frame), type_(kWebScreenOrientationUndefined), angle_(0) {}
+ : ExecutionContextClient(frame),
+ type_(kWebScreenOrientationUndefined),
+ angle_(0) {}
ScreenOrientation::~ScreenOrientation() = default;
@@ -128,7 +130,7 @@ const WTF::AtomicString& ScreenOrientation::InterfaceName() const {
ExecutionContext* ScreenOrientation::GetExecutionContext() const {
if (!GetFrame())
return nullptr;
- return GetFrame()->GetDocument();
+ return GetFrame()->GetDocument()->ToExecutionContext();
}
String ScreenOrientation::type() const {
@@ -148,22 +150,22 @@ void ScreenOrientation::SetAngle(uint16_t angle) {
}
ScriptPromise ScreenOrientation::lock(ScriptState* state,
- const AtomicString& lock_string) {
+ const AtomicString& lock_string,
+ ExceptionState& exception_state) {
Document* document = GetFrame() ? GetFrame()->GetDocument() : nullptr;
if (!document || !Controller()) {
- return ScriptPromise::RejectWithDOMException(
- state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "The object is no longer associated to a document."));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "The object is no longer associated to a document.");
+ return ScriptPromise();
}
- if (document->IsSandboxed(WebSandboxFlags::kOrientationLock)) {
- return ScriptPromise::RejectWithDOMException(
- state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kSecurityError,
- "The document is sandboxed and lacks the "
- "'allow-orientation-lock' flag."));
+ if (document->IsSandboxed(mojom::blink::WebSandboxFlags::kOrientationLock)) {
+ exception_state.ThrowSecurityError(
+ "The document is sandboxed and lacks the "
+ "'allow-orientation-lock' flag.");
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(state);
@@ -187,9 +189,9 @@ ScreenOrientationControllerImpl* ScreenOrientation::Controller() {
return ScreenOrientationControllerImpl::From(*GetFrame());
}
-void ScreenOrientation::Trace(blink::Visitor* visitor) {
+void ScreenOrientation::Trace(Visitor* visitor) {
EventTargetWithInlineData::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 4464944d2ab..5e4d410c8b5 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
@@ -7,7 +7,7 @@
#include "third_party/blink/public/common/screen_orientation/web_screen_orientation_type.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/wtf/text/atomic_string.h"
@@ -15,6 +15,7 @@
namespace blink {
+class ExceptionState;
class ExecutionContext;
class LocalFrame;
class ScriptPromise;
@@ -22,7 +23,7 @@ class ScriptState;
class ScreenOrientationControllerImpl;
class ScreenOrientation final : public EventTargetWithInlineData,
- public ContextClient {
+ public ExecutionContextClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(ScreenOrientation);
@@ -42,7 +43,9 @@ class ScreenOrientation final : public EventTargetWithInlineData,
void SetType(WebScreenOrientationType);
void SetAngle(uint16_t);
- ScriptPromise lock(ScriptState*, const AtomicString& orientation);
+ ScriptPromise lock(ScriptState*,
+ const AtomicString& orientation,
+ ExceptionState&);
void unlock();
DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange)
@@ -50,7 +53,7 @@ class ScreenOrientation final : public EventTargetWithInlineData,
// Helper being used by this class and LockOrientationCallback.
static const AtomicString& OrientationTypeToString(WebScreenOrientationType);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
ScreenOrientationControllerImpl* Controller();
diff --git a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.idl b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.idl
index 16cd1dbb22e..81384bae479 100644
--- a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.idl
+++ b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.idl
@@ -27,7 +27,7 @@ interface ScreenOrientation : EventTarget {
[MeasureAs=ScreenOrientationAngle] readonly attribute unsigned short angle;
[MeasureAs=ScreenOrientationType] readonly attribute DOMString type;
- [CallWith=ScriptState, MeasureAs=ScreenOrientationLock] Promise<void> lock(OrientationLockType orientation);
+ [CallWith=ScriptState, MeasureAs=ScreenOrientationLock, RaisesException] Promise<void> lock(OrientationLockType orientation);
[MeasureAs=ScreenOrientationUnlock] void unlock();
attribute EventHandler onchange;
diff --git a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.cc b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.cc
index e2a7884ff63..dab9c78fcb5 100644
--- a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.cc
@@ -37,7 +37,7 @@ ScreenOrientationControllerImpl* ScreenOrientationControllerImpl::From(
ScreenOrientationControllerImpl::ScreenOrientationControllerImpl(
LocalFrame& frame)
: ScreenOrientationController(frame),
- ContextLifecycleObserver(frame.GetDocument()),
+ ExecutionContextLifecycleObserver(frame.GetDocument()),
PageVisibilityObserver(frame.GetPage()) {
AssociatedInterfaceProvider* provider =
frame.GetRemoteNavigationAssociatedInterfaces();
@@ -214,14 +214,14 @@ bool ScreenOrientationControllerImpl::MaybeHasActiveLock() const {
return active_lock_;
}
-void ScreenOrientationControllerImpl::ContextDestroyed(ExecutionContext*) {
+void ScreenOrientationControllerImpl::ContextDestroyed() {
screen_orientation_service_.reset();
active_lock_ = false;
}
-void ScreenOrientationControllerImpl::Trace(blink::Visitor* visitor) {
+void ScreenOrientationControllerImpl::Trace(Visitor* visitor) {
visitor->Trace(orientation_);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
PageVisibilityObserver::Trace(visitor);
Supplement<LocalFrame>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.h b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.h
index 55adcb80b91..d40198e6570 100644
--- a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.h
+++ b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.h
@@ -26,7 +26,7 @@ using device::mojom::blink::ScreenOrientationLockResult;
class MODULES_EXPORT ScreenOrientationControllerImpl final
: public ScreenOrientationController,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public PageVisibilityObserver {
USING_GARBAGE_COLLECTED_MIXIN(ScreenOrientationControllerImpl);
@@ -49,7 +49,7 @@ class MODULES_EXPORT ScreenOrientationControllerImpl final
void SetScreenOrientationAssociatedRemoteForTests(
mojo::AssociatedRemote<device::mojom::blink::ScreenOrientation>);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
friend class MediaControlsOrientationLockAndRotateToFullscreenDelegateTest;
@@ -57,8 +57,9 @@ class MODULES_EXPORT ScreenOrientationControllerImpl final
static WebScreenOrientationType ComputeOrientation(const IntRect&, uint16_t);
- // Inherited from ContextLifecycleObserver and PageVisibilityObserver.
- void ContextDestroyed(ExecutionContext*) override;
+ // Inherited from ExecutionContextLifecycleObserver and
+ // PageVisibilityObserver.
+ void ContextDestroyed() override;
void PageVisibilityChanged() override;
void UpdateOrientation();
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 892fba511f8..cd051c38039 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
@@ -36,7 +36,7 @@ ScreenOrientation* ScreenScreenOrientation::orientation(Screen& screen) {
const char ScreenScreenOrientation::kSupplementName[] =
"ScreenScreenOrientation";
-void ScreenScreenOrientation::Trace(blink::Visitor* visitor) {
+void ScreenScreenOrientation::Trace(Visitor* visitor) {
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 0eadb9a8f82..c7d63845576 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 d13b52dff27..8c67fe88f1a 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
@@ -34,11 +34,11 @@ AbsoluteOrientationSensor::AbsoluteOrientationSensor(
options,
exception_state,
SensorType::ABSOLUTE_ORIENTATION_QUATERNION,
- {mojom::FeaturePolicyFeature::kAccelerometer,
- mojom::FeaturePolicyFeature::kGyroscope,
- mojom::FeaturePolicyFeature::kMagnetometer}) {}
+ {mojom::blink::FeaturePolicyFeature::kAccelerometer,
+ mojom::blink::FeaturePolicyFeature::kGyroscope,
+ mojom::blink::FeaturePolicyFeature::kMagnetometer}) {}
-void AbsoluteOrientationSensor::Trace(blink::Visitor* visitor) {
+void AbsoluteOrientationSensor::Trace(Visitor* visitor) {
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 225282f9faf..588c5dc78c1 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
@@ -5,8 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SENSOR_ABSOLUTE_ORIENTATION_SENSOR_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SENSOR_ABSOLUTE_ORIENTATION_SENSOR_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_spatial_sensor_options.h"
#include "third_party/blink/renderer/modules/sensor/orientation_sensor.h"
-#include "third_party/blink/renderer/modules/sensor/spatial_sensor_options.h"
namespace blink {
@@ -23,7 +23,7 @@ class AbsoluteOrientationSensor final : public OrientationSensor {
const SpatialSensorOptions*,
ExceptionState&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.idl b/chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.idl
index 3f6765b28f8..0b1c7fc12f9 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.idl
+++ b/chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.idl
@@ -2,15 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Specification at:
// https://w3c.github.io/orientation-sensor/#absoluteorientationsensor-interface
[
- Constructor(optional SpatialSensorOptions sensorOptions),
- ConstructorCallWith=ExecutionContext,
SecureContext,
- RaisesException=Constructor,
- MeasureAs=AbsoluteOrientationSensorConstructor,
Exposed=Window
] interface AbsoluteOrientationSensor : OrientationSensor {
+ [CallWith=ExecutionContext, RaisesException, MeasureAs=AbsoluteOrientationSensorConstructor] constructor(optional SpatialSensorOptions sensorOptions = {});
};
diff --git a/chromium/third_party/blink/renderer/modules/sensor/accelerometer.cc b/chromium/third_party/blink/renderer/modules/sensor/accelerometer.cc
index 0b1aad22976..151b72f24eb 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/accelerometer.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/accelerometer.cc
@@ -13,8 +13,8 @@ namespace blink {
Accelerometer* Accelerometer::Create(ExecutionContext* execution_context,
const SpatialSensorOptions* options,
ExceptionState& exception_state) {
- const Vector<mojom::FeaturePolicyFeature> features(
- {mojom::FeaturePolicyFeature::kAccelerometer});
+ const Vector<mojom::blink::FeaturePolicyFeature> features(
+ {mojom::blink::FeaturePolicyFeature::kAccelerometer});
return MakeGarbageCollected<Accelerometer>(
execution_context, options, exception_state, SensorType::ACCELEROMETER,
features);
@@ -32,13 +32,31 @@ Accelerometer::Accelerometer(
const SpatialSensorOptions* options,
ExceptionState& exception_state,
SensorType sensor_type,
- const Vector<mojom::FeaturePolicyFeature>& features)
+ const Vector<mojom::blink::FeaturePolicyFeature>& features)
: Sensor(execution_context,
options,
exception_state,
sensor_type,
features) {}
+base::Optional<double> Accelerometer::x() const {
+ if (hasReading())
+ return GetReading().accel.x;
+ return base::nullopt;
+}
+
+base::Optional<double> Accelerometer::y() const {
+ if (hasReading())
+ return GetReading().accel.y;
+ return base::nullopt;
+}
+
+base::Optional<double> Accelerometer::z() const {
+ if (hasReading())
+ return GetReading().accel.z;
+ return base::nullopt;
+}
+
double Accelerometer::x(bool& is_null) const {
INIT_IS_NULL_AND_RETURN(is_null, 0.0);
return GetReading().accel.x;
@@ -54,7 +72,7 @@ double Accelerometer::z(bool& is_null) const {
return GetReading().accel.z;
}
-void Accelerometer::Trace(blink::Visitor* visitor) {
+void Accelerometer::Trace(Visitor* visitor) {
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 5005db7f04c..1a9d9ddece1 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/accelerometer.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/accelerometer.h
@@ -5,8 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SENSOR_ACCELEROMETER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SENSOR_ACCELEROMETER_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_spatial_sensor_options.h"
#include "third_party/blink/renderer/modules/sensor/sensor.h"
-#include "third_party/blink/renderer/modules/sensor/spatial_sensor_options.h"
namespace blink {
@@ -23,13 +23,17 @@ class Accelerometer : public Sensor {
const SpatialSensorOptions*,
ExceptionState&,
device::mojom::blink::SensorType,
- const Vector<mojom::FeaturePolicyFeature>&);
+ const Vector<mojom::blink::FeaturePolicyFeature>&);
- double x(bool& is_null) const;
- double y(bool& is_null) const;
- double z(bool& is_null) const;
+ base::Optional<double> x() const;
+ base::Optional<double> y() const;
+ base::Optional<double> z() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ double x(bool& is_null) const; // DEPRECATED
+ double y(bool& is_null) const; // DEPRECATED
+ double z(bool& is_null) const; // DEPRECATED
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/sensor/accelerometer.idl b/chromium/third_party/blink/renderer/modules/sensor/accelerometer.idl
index 0f09759e699..460d3970cfe 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/accelerometer.idl
+++ b/chromium/third_party/blink/renderer/modules/sensor/accelerometer.idl
@@ -2,17 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Specification at:
// https://w3c.github.io/accelerometer/#accelerometer-interface
[
- Constructor(optional SpatialSensorOptions sensorOptions),
- ConstructorCallWith=ExecutionContext,
SecureContext,
- RaisesException=Constructor,
- MeasureAs=AccelerometerConstructor,
Exposed=Window
] interface Accelerometer : Sensor {
+ [CallWith=ExecutionContext, RaisesException, MeasureAs=AccelerometerConstructor] constructor(optional SpatialSensorOptions sensorOptions = {});
readonly attribute unrestricted double? x;
readonly attribute unrestricted double? y;
readonly attribute unrestricted double? z;
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 a35c7f3b4a5..7d31a652c66 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
@@ -55,7 +55,15 @@ AmbientLightSensor::AmbientLightSensor(ExecutionContext* execution_context,
options,
exception_state,
SensorType::AMBIENT_LIGHT,
- {mojom::FeaturePolicyFeature::kAmbientLightSensor}) {}
+ {mojom::blink::FeaturePolicyFeature::kAmbientLightSensor}) {}
+
+base::Optional<double> AmbientLightSensor::illuminance() const {
+ if (hasReading()) {
+ DCHECK(latest_reading_.has_value());
+ return RoundIlluminance(latest_reading_.value());
+ }
+ return base::nullopt;
+}
double AmbientLightSensor::illuminance(bool& is_null) const {
INIT_IS_NULL_AND_RETURN(is_null, 0.0);
@@ -67,6 +75,12 @@ double AmbientLightSensor::illuminance(bool& is_null) const {
// value, we discard this reading and do not emit any events. This is a privacy
// measure to avoid giving readings that are too specific.
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())
+ return;
+
const double new_reading = GetReading().als.value;
if (latest_reading_.has_value() &&
!IsSignificantlyDifferent(*latest_reading_, new_reading)) {
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 5d69f2fb5c3..88031cee123 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,7 +23,9 @@ class MODULES_EXPORT AmbientLightSensor final : public Sensor {
AmbientLightSensor(ExecutionContext*, const SensorOptions*, ExceptionState&);
- double illuminance(bool& is_null) const;
+ base::Optional<double> illuminance() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ double illuminance(bool& is_null) const; // DEPRECATED
void OnSensorReadingChanged() override;
@@ -31,6 +33,8 @@ class MODULES_EXPORT AmbientLightSensor final : public Sensor {
base::Optional<double> latest_reading_;
FRIEND_TEST_ALL_PREFIXES(AmbientLightSensorTest, IlluminanceRounding);
+ FRIEND_TEST_ALL_PREFIXES(AmbientLightSensorTest,
+ PlatformSensorReadingsBeforeActivation);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.idl b/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.idl
index 4de8affdb9a..b589643b847 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.idl
+++ b/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.idl
@@ -2,17 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Specification at:
// https://w3c.github.io/ambient-light/#ambient-light-sensor-interface
[
RuntimeEnabled=SensorExtraClasses,
- Constructor(optional SensorOptions sensorOptions),
- ConstructorCallWith=ExecutionContext,
SecureContext,
- RaisesException=Constructor,
- MeasureAs=AmbientLightSensorConstructor,
Exposed=Window
] interface AmbientLightSensor : Sensor {
+ [CallWith=ExecutionContext, RaisesException, MeasureAs=AmbientLightSensorConstructor] constructor(optional SensorOptions sensorOptions = {});
readonly attribute unrestricted double? illuminance;
};
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 dff6922d122..2804ef45fa4 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
@@ -26,17 +26,34 @@ class MockSensorProxyObserver
// Synchronously waits for OnSensorReadingChanged() to be called.
void WaitForOnSensorReadingChanged() {
- run_loop_.emplace();
- run_loop_->Run();
+ sensor_reading_changed_run_loop_.emplace();
+ sensor_reading_changed_run_loop_->Run();
+ }
+
+ // Synchronously waits for OnSensorInitialized() to be called.
+ void WaitForSensorInitialization() {
+ sensor_initialized_run_loop_.emplace();
+ sensor_initialized_run_loop_->Run();
+ }
+
+ // SensorProxy::Observer overrides.
+ void OnSensorInitialized() override {
+ if (sensor_initialized_run_loop_.has_value() &&
+ sensor_initialized_run_loop_->running()) {
+ sensor_initialized_run_loop_->Quit();
+ }
}
void OnSensorReadingChanged() override {
- DCHECK(run_loop_.has_value() && run_loop_->running());
- run_loop_->Quit();
+ if (sensor_reading_changed_run_loop_.has_value() &&
+ sensor_reading_changed_run_loop_->running()) {
+ sensor_reading_changed_run_loop_->Quit();
+ }
}
private:
- base::Optional<base::RunLoop> run_loop_;
+ base::Optional<base::RunLoop> sensor_initialized_run_loop_;
+ base::Optional<base::RunLoop> sensor_reading_changed_run_loop_;
};
} // namespace
@@ -86,7 +103,7 @@ TEST(AmbientLightSensorTest, IlluminanceRounding) {
// the order that each observer is notified is arbitrary, we know that by the
// time we get to the next call here all observers will have been called.
auto* sensor_proxy =
- SensorProviderProxy::From(To<Document>(context.GetExecutionContext()))
+ SensorProviderProxy::From(Document::From(context.GetExecutionContext()))
->GetSensorProxy(device::mojom::blink::SensorType::AMBIENT_LIGHT);
ASSERT_NE(sensor_proxy, nullptr);
auto* mock_observer = MakeGarbageCollected<MockSensorProxyObserver>();
@@ -149,4 +166,41 @@ TEST(AmbientLightSensorTest, IlluminanceRounding) {
EXPECT_EQ(3U, event_counter->event_count());
}
+TEST(AmbientLightSensorTest, PlatformSensorReadingsBeforeActivation) {
+ SensorTestContext context;
+ NonThrowableExceptionState exception_state;
+
+ auto* sensor = AmbientLightSensor::Create(context.GetExecutionContext(),
+ exception_state);
+ sensor->start();
+
+ auto* sensor_proxy =
+ SensorProviderProxy::From(Document::From(context.GetExecutionContext()))
+ ->GetSensorProxy(device::mojom::blink::SensorType::AMBIENT_LIGHT);
+ ASSERT_NE(sensor_proxy, nullptr);
+ auto* mock_observer = MakeGarbageCollected<MockSensorProxyObserver>();
+ sensor_proxy->AddObserver(mock_observer);
+
+ bool illuminance_is_null;
+
+ // Instead of waiting for SensorProxy::Observer::OnSensorReadingChanged(), we
+ // wait for OnSensorInitialized(), which happens earlier. The platform may
+ // start sending readings and calling OnSensorReadingChanged() at any moment
+ // from this point on.
+ // This test verifies AmbientLightSensor::OnSensorReadingChanged() is able to
+ // handle the case of it being called before Sensor itself has transitioned to
+ // a fully activated state.
+ mock_observer->WaitForSensorInitialization();
+ context.sensor_provider()->UpdateAmbientLightSensorData(42);
+ ASSERT_FALSE(sensor->IsActivated());
+ EXPECT_EQ(0, sensor->illuminance(illuminance_is_null));
+ EXPECT_TRUE(illuminance_is_null);
+
+ SensorTestUtils::WaitForEvent(sensor, event_type_names::kReading);
+
+ EXPECT_EQ(42, sensor->latest_reading_);
+ EXPECT_EQ(50, sensor->illuminance(illuminance_is_null));
+ EXPECT_FALSE(illuminance_is_null);
+}
+
} // 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 793edcd148e..4fb7bf6710a 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/gyroscope.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/gyroscope.cc
@@ -31,7 +31,25 @@ Gyroscope::Gyroscope(ExecutionContext* execution_context,
options,
exception_state,
SensorType::GYROSCOPE,
- {mojom::FeaturePolicyFeature::kGyroscope}) {}
+ {mojom::blink::FeaturePolicyFeature::kGyroscope}) {}
+
+base::Optional<double> Gyroscope::x() const {
+ if (hasReading())
+ return GetReading().gyro.x;
+ return base::nullopt;
+}
+
+base::Optional<double> Gyroscope::y() const {
+ if (hasReading())
+ return GetReading().gyro.y;
+ return base::nullopt;
+}
+
+base::Optional<double> Gyroscope::z() const {
+ if (hasReading())
+ return GetReading().gyro.z;
+ return base::nullopt;
+}
double Gyroscope::x(bool& is_null) const {
INIT_IS_NULL_AND_RETURN(is_null, 0.0);
@@ -48,7 +66,7 @@ double Gyroscope::z(bool& is_null) const {
return GetReading().gyro.z;
}
-void Gyroscope::Trace(blink::Visitor* visitor) {
+void Gyroscope::Trace(Visitor* visitor) {
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 27e36a14e9a..ed2af4b59f7 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/gyroscope.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/gyroscope.h
@@ -5,8 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SENSOR_GYROSCOPE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SENSOR_GYROSCOPE_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_spatial_sensor_options.h"
#include "third_party/blink/renderer/modules/sensor/sensor.h"
-#include "third_party/blink/renderer/modules/sensor/spatial_sensor_options.h"
namespace blink {
@@ -21,11 +21,15 @@ class Gyroscope final : public Sensor {
Gyroscope(ExecutionContext*, const SpatialSensorOptions*, ExceptionState&);
- double x(bool& is_null) const;
- double y(bool& is_null) const;
- double z(bool& is_null) const;
+ base::Optional<double> x() const;
+ base::Optional<double> y() const;
+ base::Optional<double> z() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ double x(bool& is_null) const; // DEPRECATED
+ double y(bool& is_null) const; // DEPRECATED
+ double z(bool& is_null) const; // DEPRECATED
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/sensor/gyroscope.idl b/chromium/third_party/blink/renderer/modules/sensor/gyroscope.idl
index 98f3291bfbd..a81702060d8 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/gyroscope.idl
+++ b/chromium/third_party/blink/renderer/modules/sensor/gyroscope.idl
@@ -6,13 +6,10 @@
// https://w3c.github.io/gyroscope/#gyroscope-interface
[
- Constructor(optional SpatialSensorOptions sensorOptions),
- ConstructorCallWith=ExecutionContext,
- RaisesException=Constructor,
SecureContext,
- Exposed=Window,
- MeasureAs=GyroscopeConstructor
+ Exposed=Window
] interface Gyroscope : Sensor {
+ [CallWith=ExecutionContext, RaisesException, MeasureAs=GyroscopeConstructor] constructor(optional SpatialSensorOptions sensorOptions = {});
readonly attribute unrestricted double? x;
readonly attribute unrestricted double? y;
readonly attribute unrestricted double? z;
diff --git a/chromium/third_party/blink/renderer/modules/sensor/idls.gni b/chromium/third_party/blink/renderer/modules/sensor/idls.gni
new file mode 100644
index 00000000000..07639bd06c7
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/sensor/idls.gni
@@ -0,0 +1,22 @@
+# 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 = [
+ "absolute_orientation_sensor.idl",
+ "accelerometer.idl",
+ "ambient_light_sensor.idl",
+ "gyroscope.idl",
+ "linear_acceleration_sensor.idl",
+ "magnetometer.idl",
+ "orientation_sensor.idl",
+ "relative_orientation_sensor.idl",
+ "sensor.idl",
+ "sensor_error_event.idl",
+]
+
+modules_dictionary_idl_files = [
+ "sensor_error_event_init.idl",
+ "sensor_options.idl",
+ "spatial_sensor_options.idl",
+]
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 2ce628894ca..a1bcf3beccf 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
@@ -34,9 +34,9 @@ LinearAccelerationSensor::LinearAccelerationSensor(
options,
exception_state,
SensorType::LINEAR_ACCELERATION,
- {mojom::FeaturePolicyFeature::kAccelerometer}) {}
+ {mojom::blink::FeaturePolicyFeature::kAccelerometer}) {}
-void LinearAccelerationSensor::Trace(blink::Visitor* visitor) {
+void LinearAccelerationSensor::Trace(Visitor* visitor) {
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 bf54c82ba31..96dc875e415 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.idl b/chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.idl
index feb72964559..c04f6485468 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.idl
+++ b/chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.idl
@@ -2,15 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Specification at:
// https://w3c.github.io/accelerometer/#linearaccelerationsensor
[
- Constructor(optional SpatialSensorOptions sensorOptions),
- ConstructorCallWith=ExecutionContext,
SecureContext,
- RaisesException=Constructor,
- MeasureAs=LinearAccelerationSensorConstructor,
Exposed=Window
] interface LinearAccelerationSensor : Accelerometer {
+ [CallWith=ExecutionContext, RaisesException, MeasureAs=LinearAccelerationSensorConstructor] constructor(optional SpatialSensorOptions sensorOptions = {});
};
diff --git a/chromium/third_party/blink/renderer/modules/sensor/magnetometer.cc b/chromium/third_party/blink/renderer/modules/sensor/magnetometer.cc
index 0eb58a59c0a..2f8d19a7a63 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/magnetometer.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/magnetometer.cc
@@ -32,7 +32,25 @@ Magnetometer::Magnetometer(ExecutionContext* execution_context,
options,
exception_state,
SensorType::MAGNETOMETER,
- {mojom::FeaturePolicyFeature::kMagnetometer}) {}
+ {mojom::blink::FeaturePolicyFeature::kMagnetometer}) {}
+
+base::Optional<double> Magnetometer::x() const {
+ if (hasReading())
+ return GetReading().magn.x;
+ return base::nullopt;
+}
+
+base::Optional<double> Magnetometer::y() const {
+ if (hasReading())
+ return GetReading().magn.y;
+ return base::nullopt;
+}
+
+base::Optional<double> Magnetometer::z() const {
+ if (hasReading())
+ return GetReading().magn.z;
+ return base::nullopt;
+}
double Magnetometer::x(bool& is_null) const {
INIT_IS_NULL_AND_RETURN(is_null, 0.0);
@@ -49,7 +67,7 @@ double Magnetometer::z(bool& is_null) const {
return GetReading().magn.z;
}
-void Magnetometer::Trace(blink::Visitor* visitor) {
+void Magnetometer::Trace(Visitor* visitor) {
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 f4e2e576ea5..6ab0846dfdc 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/magnetometer.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/magnetometer.h
@@ -5,8 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SENSOR_MAGNETOMETER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SENSOR_MAGNETOMETER_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_spatial_sensor_options.h"
#include "third_party/blink/renderer/modules/sensor/sensor.h"
-#include "third_party/blink/renderer/modules/sensor/spatial_sensor_options.h"
namespace blink {
@@ -21,11 +21,15 @@ class Magnetometer final : public Sensor {
Magnetometer(ExecutionContext*, const SpatialSensorOptions*, ExceptionState&);
- double x(bool& is_null) const;
- double y(bool& is_null) const;
- double z(bool& is_null) const;
+ base::Optional<double> x() const;
+ base::Optional<double> y() const;
+ base::Optional<double> z() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ double x(bool& is_null) const; // DEPRECATED
+ double y(bool& is_null) const; // DEPRECATED
+ double z(bool& is_null) const; // DEPRECATED
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/sensor/magnetometer.idl b/chromium/third_party/blink/renderer/modules/sensor/magnetometer.idl
index 6edcbc7affc..9ef493de673 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/magnetometer.idl
+++ b/chromium/third_party/blink/renderer/modules/sensor/magnetometer.idl
@@ -2,18 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Specification at:
// https://w3c.github.io/magnetometer/#magnetometer-interface
[
Exposed=Window,
RuntimeEnabled=SensorExtraClasses,
- Constructor(optional SpatialSensorOptions sensorOptions),
- ConstructorCallWith=ExecutionContext,
- SecureContext,
- RaisesException=Constructor,
- MeasureAs=MagnetometerConstructor
+ SecureContext
] interface Magnetometer : Sensor {
+ [CallWith=ExecutionContext, RaisesException, MeasureAs=MagnetometerConstructor] constructor(optional SpatialSensorOptions sensorOptions = {});
readonly attribute unrestricted double? x;
readonly attribute unrestricted double? y;
readonly attribute unrestricted double? z;
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 3a33e0ea5f9..b69a90bd8f0 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.cc
@@ -11,6 +11,14 @@ using device::mojom::blink::SensorType;
namespace blink {
+base::Optional<Vector<double>> OrientationSensor::quaternion() {
+ reading_dirty_ = false;
+ if (!hasReading())
+ return base::nullopt;
+ const auto& quat = GetReading().orientation_quat;
+ return Vector<double>({quat.x, quat.y, quat.z, quat.w});
+}
+
Vector<double> OrientationSensor::quaternion(bool& is_null) {
reading_dirty_ = false;
INIT_IS_NULL_AND_RETURN(is_null, Vector<double>());
@@ -119,7 +127,7 @@ OrientationSensor::OrientationSensor(
const SpatialSensorOptions* options,
ExceptionState& exception_state,
device::mojom::blink::SensorType type,
- const Vector<mojom::FeaturePolicyFeature>& features)
+ const Vector<mojom::blink::FeaturePolicyFeature>& features)
: Sensor(execution_context, options, exception_state, type, features),
reading_dirty_(true) {}
@@ -128,7 +136,7 @@ void OrientationSensor::OnSensorReadingChanged() {
Sensor::OnSensorReadingChanged();
}
-void OrientationSensor::Trace(blink::Visitor* visitor) {
+void OrientationSensor::Trace(Visitor* visitor) {
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 d6936e83039..d5149b63614 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.h
@@ -6,9 +6,9 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SENSOR_ORIENTATION_SENSOR_H_
#include "third_party/blink/renderer/bindings/modules/v8/float32_array_or_float64_array_or_dom_matrix.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_spatial_sensor_options.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
#include "third_party/blink/renderer/modules/sensor/sensor.h"
-#include "third_party/blink/renderer/modules/sensor/spatial_sensor_options.h"
namespace blink {
@@ -16,19 +16,21 @@ class OrientationSensor : public Sensor {
DEFINE_WRAPPERTYPEINFO();
public:
- Vector<double> quaternion(bool& is_null);
+ base::Optional<Vector<double>> quaternion();
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ Vector<double> quaternion(bool& is_null); // DEPRECATED
void populateMatrix(Float32ArrayOrFloat64ArrayOrDOMMatrix&, ExceptionState&);
bool isReadingDirty() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
OrientationSensor(ExecutionContext*,
const SpatialSensorOptions*,
ExceptionState&,
device::mojom::blink::SensorType,
- const Vector<mojom::FeaturePolicyFeature>& features);
+ const Vector<mojom::blink::FeaturePolicyFeature>& features);
private:
// SensorProxy override.
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 87d9a9190b4..ed7884e079d 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
@@ -34,10 +34,10 @@ RelativeOrientationSensor::RelativeOrientationSensor(
options,
exception_state,
SensorType::RELATIVE_ORIENTATION_QUATERNION,
- {mojom::FeaturePolicyFeature::kAccelerometer,
- mojom::FeaturePolicyFeature::kGyroscope}) {}
+ {mojom::blink::FeaturePolicyFeature::kAccelerometer,
+ mojom::blink::FeaturePolicyFeature::kGyroscope}) {}
-void RelativeOrientationSensor::Trace(blink::Visitor* visitor) {
+void RelativeOrientationSensor::Trace(Visitor* visitor) {
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 fca41a496ac..37562d1b94b 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
@@ -5,8 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SENSOR_RELATIVE_ORIENTATION_SENSOR_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SENSOR_RELATIVE_ORIENTATION_SENSOR_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_spatial_sensor_options.h"
#include "third_party/blink/renderer/modules/sensor/orientation_sensor.h"
-#include "third_party/blink/renderer/modules/sensor/spatial_sensor_options.h"
namespace blink {
@@ -23,7 +23,7 @@ class RelativeOrientationSensor final : public OrientationSensor {
const SpatialSensorOptions*,
ExceptionState&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.idl b/chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.idl
index c728fc844e9..c0d7d888ee6 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.idl
+++ b/chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.idl
@@ -2,15 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Specification at:
// https://w3c.github.io/orientation-sensor/#relativeorientationsensor-interface
[
- Constructor(optional SpatialSensorOptions sensorOptions),
- ConstructorCallWith=ExecutionContext,
SecureContext,
- RaisesException=Constructor,
- MeasureAs=RelativeOrientationSensorConstructor,
Exposed=Window
] interface RelativeOrientationSensor : OrientationSensor {
+ [CallWith=ExecutionContext, RaisesException, MeasureAs=RelativeOrientationSensorConstructor] constructor(optional SpatialSensorOptions sensorOptions = {});
};
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor.cc b/chromium/third_party/blink/renderer/modules/sensor/sensor.cc
index a233936449d..330227331c3 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor.cc
@@ -25,10 +25,11 @@ namespace blink {
namespace {
const double kWaitingIntervalThreshold = 0.01;
-bool AreFeaturesEnabled(Document* document,
- const Vector<mojom::FeaturePolicyFeature>& features) {
+bool AreFeaturesEnabled(
+ Document* document,
+ const Vector<mojom::blink::FeaturePolicyFeature>& features) {
return std::all_of(features.begin(), features.end(),
- [document](mojom::FeaturePolicyFeature feature) {
+ [document](mojom::blink::FeaturePolicyFeature feature) {
return document->IsFeatureEnabled(
feature, ReportOptions::kReportOnFailure);
});
@@ -40,8 +41,8 @@ Sensor::Sensor(ExecutionContext* execution_context,
const SensorOptions* sensor_options,
ExceptionState& exception_state,
device::mojom::blink::SensorType type,
- const Vector<mojom::FeaturePolicyFeature>& features)
- : ContextLifecycleObserver(execution_context),
+ const Vector<mojom::blink::FeaturePolicyFeature>& features)
+ : ExecutionContextLifecycleObserver(execution_context),
frequency_(0.0),
type_(type),
state_(SensorState::kIdle),
@@ -49,7 +50,7 @@ Sensor::Sensor(ExecutionContext* execution_context,
// [SecureContext] in idl.
DCHECK(execution_context->IsSecureContext());
DCHECK(!features.IsEmpty());
- Document* document = To<Document>(execution_context);
+ Document* document = Document::From(execution_context);
if (!AreFeaturesEnabled(document, features)) {
exception_state.ThrowSecurityError(
@@ -67,7 +68,7 @@ Sensor::Sensor(ExecutionContext* execution_context,
String message = String::Format(
"Maximum allowed frequency value for this sensor type is %.0f Hz.",
max_allowed_frequency);
- ConsoleMessage* console_message = ConsoleMessage::Create(
+ auto* console_message = MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kInfo, std::move(message));
execution_context->AddConsoleMessage(console_message);
@@ -79,7 +80,7 @@ Sensor::Sensor(ExecutionContext* execution_context,
const SpatialSensorOptions* options,
ExceptionState& exception_state,
device::mojom::blink::SensorType sensor_type,
- const Vector<mojom::FeaturePolicyFeature>& features)
+ const Vector<mojom::blink::FeaturePolicyFeature>& features)
: Sensor(execution_context,
static_cast<const SensorOptions*>(options),
exception_state,
@@ -116,23 +117,20 @@ bool Sensor::hasReading() const {
return sensor_proxy_->GetReading().timestamp() != 0.0;
}
-DOMHighResTimeStamp Sensor::timestamp(ScriptState* script_state,
- bool& is_null) const {
+base::Optional<DOMHighResTimeStamp> Sensor::timestamp(
+ ScriptState* script_state) const {
if (!hasReading()) {
- is_null = true;
- return 0.0;
+ return base::nullopt;
}
LocalDOMWindow* window = LocalDOMWindow::From(script_state);
if (!window) {
- is_null = true;
- return 0.0;
+ return base::nullopt;
}
WindowPerformance* performance = DOMWindowPerformance::performance(*window);
DCHECK(performance);
DCHECK(sensor_proxy_);
- is_null = false;
if (WebTestSupport::IsRunningWebTest()) {
// In web tests performance.now() * 0.001 is passed to the shared buffer.
@@ -144,10 +142,17 @@ DOMHighResTimeStamp Sensor::timestamp(ScriptState* script_state,
base::TimeDelta::FromSecondsD(sensor_proxy_->GetReading().timestamp()));
}
-void Sensor::Trace(blink::Visitor* visitor) {
+DOMHighResTimeStamp Sensor::timestamp(ScriptState* script_state,
+ bool& is_null) const {
+ base::Optional<DOMHighResTimeStamp> result = timestamp(script_state);
+ is_null = !result;
+ return result.value_or(0);
+}
+
+void Sensor::Trace(Visitor* visitor) {
visitor->Trace(sensor_proxy_);
ActiveScriptWrappable::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
EventTargetWithInlineData::Trace(visitor);
}
@@ -179,7 +184,7 @@ void Sensor::InitSensorProxyIfNeeded() {
if (sensor_proxy_)
return;
- Document* document = To<Document>(GetExecutionContext());
+ Document* document = Document::From(GetExecutionContext());
if (!document || !document->GetFrame())
return;
@@ -190,7 +195,7 @@ void Sensor::InitSensorProxyIfNeeded() {
sensor_proxy_ = provider->CreateSensorProxy(type_, document->GetPage());
}
-void Sensor::ContextDestroyed(ExecutionContext*) {
+void Sensor::ContextDestroyed() {
if (!IsIdleOrErrored())
Deactivate();
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor.h b/chromium/third_party/blink/renderer/modules/sensor/sensor.h
index 14fc0de5560..534338928a4 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor.h
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor.h
@@ -6,16 +6,17 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SENSOR_SENSOR_H_
#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/bindings/core/v8/active_script_wrappable.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_sensor_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_spatial_sensor_options.h"
#include "third_party/blink/renderer/core/dom/dom_high_res_time_stamp.h"
#include "third_party/blink/renderer/core/dom/dom_time_stamp.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/frame/platform_event_controller.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/modules/sensor/sensor_options.h"
#include "third_party/blink/renderer/modules/sensor/sensor_proxy.h"
-#include "third_party/blink/renderer/modules/sensor/spatial_sensor_options.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"
@@ -29,7 +30,7 @@ class ExecutionContext;
class MODULES_EXPORT Sensor : public EventTargetWithInlineData,
public ActiveScriptWrappable<Sensor>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public SensorProxy::Observer {
USING_GARBAGE_COLLECTED_MIXIN(Sensor);
DEFINE_WRAPPERTYPEINFO();
@@ -47,13 +48,16 @@ class MODULES_EXPORT Sensor : public EventTargetWithInlineData,
return event_target_names::kSensor;
}
ExecutionContext* GetExecutionContext() const override {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
// Getters
bool activated() const;
bool hasReading() const;
- DOMHighResTimeStamp timestamp(ScriptState*, bool& is_null) const;
+ base::Optional<DOMHighResTimeStamp> timestamp(ScriptState*) const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ DOMHighResTimeStamp timestamp(ScriptState*,
+ bool& is_null) const; // DEPRECATED
DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
DEFINE_ATTRIBUTE_EVENT_LISTENER(reading, kReading)
@@ -62,20 +66,20 @@ class MODULES_EXPORT Sensor : public EventTargetWithInlineData,
// ActiveScriptWrappable overrides.
bool HasPendingActivity() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
Sensor(ExecutionContext*,
const SensorOptions*,
ExceptionState&,
device::mojom::blink::SensorType,
- const Vector<mojom::FeaturePolicyFeature>&);
+ const Vector<mojom::blink::FeaturePolicyFeature>&);
Sensor(ExecutionContext*,
const SpatialSensorOptions*,
ExceptionState&,
device::mojom::blink::SensorType,
- const Vector<mojom::FeaturePolicyFeature>&);
+ const Vector<mojom::blink::FeaturePolicyFeature>&);
using SensorConfigurationPtr = device::mojom::blink::SensorConfigurationPtr;
using SensorConfiguration = device::mojom::blink::SensorConfiguration;
@@ -99,8 +103,8 @@ class MODULES_EXPORT Sensor : public EventTargetWithInlineData,
private:
void InitSensorProxyIfNeeded();
- // ContextLifecycleObserver overrides.
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver overrides.
+ void ContextDestroyed() override;
void OnAddConfigurationRequestCompleted(bool);
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 7a5fbfee904..ac770c50116 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(blink::Visitor* visitor) {
+void SensorErrorEvent::Trace(Visitor* visitor) {
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 4825d586fb6..5246fb18223 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
@@ -5,9 +5,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SENSOR_SENSOR_ERROR_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SENSOR_SENSOR_ERROR_EVENT_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_sensor_error_event_init.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/modules/event_modules.h"
-#include "third_party/blink/renderer/modules/sensor/sensor_error_event_init.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
@@ -31,7 +31,7 @@ class SensorErrorEvent : public Event {
const SensorErrorEventInit* initializer);
~SensorErrorEvent() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
const AtomicString& InterfaceName() const override;
@@ -41,14 +41,6 @@ class SensorErrorEvent : public Event {
Member<DOMException> error_;
};
-DEFINE_TYPE_CASTS(SensorErrorEvent,
- Event,
- event,
- event->InterfaceName() ==
- event_interface_names::kSensorErrorEvent,
- event.InterfaceName() ==
- event_interface_names::kSensorErrorEvent);
-
} // namepsace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SENSOR_SENSOR_ERROR_EVENT_H_
diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_error_event.idl b/chromium/third_party/blink/renderer/modules/sensor/sensor_error_event.idl
index 916f4364ab2..042cc7b4acc 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor_error_event.idl
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_error_event.idl
@@ -7,8 +7,8 @@
[
SecureContext,
- Constructor(DOMString type, SensorErrorEventInit eventInitDict),
Exposed=Window
] interface SensorErrorEvent : Event {
+ constructor(DOMString type, SensorErrorEventInit eventInitDict);
readonly attribute DOMException error;
};
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 77d2c2d680a..2ba3713d12a 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
@@ -10,13 +10,14 @@
#include "third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h"
#include "third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.h"
#include "third_party/blink/renderer/platform/bindings/exception_code.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
SensorInspectorAgent::SensorInspectorAgent(Document* document)
: provider_(SensorProviderProxy::From(document)) {}
-void SensorInspectorAgent::Trace(blink::Visitor* visitor) {
+void SensorInspectorAgent::Trace(Visitor* visitor) {
visitor->Trace(provider_);
}
@@ -79,7 +80,7 @@ void SensorInspectorAgent::SetOrientationSensorOverride(double alpha,
if (!provider_->inspector_mode()) {
Document* document = provider_->GetSupplementable();
if (document) {
- ConsoleMessage* console_message = ConsoleMessage::Create(
+ auto* console_message = MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kInfo, kInspectorConsoleMessage);
document->AddConsoleMessage(console_message);
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 932017e201c..5a2423e8d6a 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(Document* document);
- virtual void Trace(blink::Visitor*);
+ virtual void Trace(Visitor*);
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 aba986057d5..649ed30b42f 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
@@ -13,14 +13,17 @@ namespace blink {
// SensorProviderProxy
SensorProviderProxy::SensorProviderProxy(Document& document)
- : Supplement<Document>(document), inspector_mode_(false) {}
+ : Supplement<Document>(document),
+ sensor_provider_(document.ToExecutionContext()),
+ inspector_mode_(false) {}
void SensorProviderProxy::InitializeIfNeeded() {
if (IsInitialized())
return;
GetSupplementable()->GetBrowserInterfaceBroker().GetInterface(
- sensor_provider_.BindNewPipeAndPassReceiver());
+ sensor_provider_.BindNewPipeAndPassReceiver(
+ GetSupplementable()->GetTaskRunner(TaskType::kSensor)));
sensor_provider_.set_disconnect_handler(
WTF::Bind(&SensorProviderProxy::OnSensorProviderConnectionError,
WrapWeakPersistent(this)));
@@ -44,8 +47,9 @@ SensorProviderProxy* SensorProviderProxy::From(Document* document) {
SensorProviderProxy::~SensorProviderProxy() = default;
-void SensorProviderProxy::Trace(blink::Visitor* visitor) {
+void SensorProviderProxy::Trace(Visitor* visitor) {
visitor->Trace(sensor_proxies_);
+ visitor->Trace(sensor_provider_);
Supplement<Document>::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 458e133730d..46616c3ac30 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
@@ -6,12 +6,13 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SENSOR_SENSOR_PROVIDER_PROXY_H_
#include "base/macros.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/dom/document.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 {
@@ -39,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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
friend class SensorProxy;
@@ -58,7 +59,9 @@ class MODULES_EXPORT SensorProviderProxy final
void OnSensorProviderConnectionError();
SensorsSet sensor_proxies_;
- mojo::Remote<device::mojom::blink::SensorProvider> sensor_provider_;
+ HeapMojoRemote<device::mojom::blink::SensorProvider,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ sensor_provider_;
bool inspector_mode_;
DISALLOW_COPY_AND_ASSIGN(SensorProviderProxy);
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 bdf81b05d7f..eb4e3f10f55 100644
--- a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.cc
+++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.cc
@@ -10,6 +10,7 @@
#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/focus_controller.h"
+#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h"
#include "third_party/blink/renderer/modules/sensor/sensor_reading_remapper.h"
#include "third_party/blink/renderer/platform/web_test_support.h"
@@ -31,7 +32,7 @@ SensorProxy::SensorProxy(device::mojom::blink::SensorType sensor_type,
SensorProxy::~SensorProxy() {}
-void SensorProxy::Trace(blink::Visitor* visitor) {
+void SensorProxy::Trace(Visitor* visitor) {
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 f25fc82384b..c6c2ea69016 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 9f574c42d57..2a2c9906c91 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
@@ -30,7 +30,7 @@ void SensorProxyImpl::Dispose() {
client_receiver_.reset();
}
-void SensorProxyImpl::Trace(blink::Visitor* visitor) {
+void SensorProxyImpl::Trace(Visitor* visitor) {
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 ea7973ce683..2124822cf16 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
@@ -29,7 +29,7 @@ class SensorProxyImpl final : public SensorProxy,
Page*);
~SensorProxyImpl() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void Dispose();
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 2eb8cfdf1ab..d398eedebdd 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(blink::Visitor* visitor) {
+void SensorProxyInspectorImpl::Trace(Visitor* visitor) {
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 36c89d22237..c5531d98a38 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 76b03b67e6f..cc0c3c8c79c 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
@@ -41,8 +41,8 @@ class SyncEventListener final : public NativeEventListener {
SensorTestContext::SensorTestContext() {
// Sensor's constructor has a check for this that could be removed in the
// future.
- testing_scope_.GetDocument().SetSecureContextStateForTesting(
- SecureContextState::kSecure);
+ testing_scope_.GetDocument().SetSecureContextModeForTesting(
+ SecureContextMode::kSecureContext);
// Necessary for SensorProxy::ShouldSuspendUpdates() to work correctly.
testing_scope_.GetPage().GetFocusController().SetFocused(true);
diff --git a/chromium/third_party/blink/renderer/modules/serial/BUILD.gn b/chromium/third_party/blink/renderer/modules/serial/BUILD.gn
index c5d19ee5bfd..db1e96d3167 100644
--- a/chromium/third_party/blink/renderer/modules/serial/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/serial/BUILD.gn
@@ -14,6 +14,8 @@ blink_modules_sources("serial") {
"navigator_serial.h",
"serial.cc",
"serial.h",
+ "serial_connection_event.cc",
+ "serial_connection_event.h",
"serial_port.cc",
"serial_port.h",
"serial_port_underlying_sink.cc",
diff --git a/chromium/third_party/blink/renderer/modules/serial/idls.gni b/chromium/third_party/blink/renderer/modules/serial/idls.gni
new file mode 100644
index 00000000000..ba4a9008d2b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/serial/idls.gni
@@ -0,0 +1,23 @@
+# 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.
+
+modules_idl_files = [
+ "serial.idl",
+ "serial_connection_event.idl",
+ "serial_port.idl",
+]
+
+modules_dictionary_idl_files = [
+ "serial_connection_event_init.idl",
+ "serial_input_signals.idl",
+ "serial_options.idl",
+ "serial_output_signals.idl",
+ "serial_port_filter.idl",
+ "serial_port_request_options.idl",
+]
+
+modules_dependency_idl_files = [
+ "navigator_serial.idl",
+ "worker_navigator_serial.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 4ad27602b47..283d33beba8 100644
--- a/chromium/third_party/blink/renderer/modules/serial/navigator_serial.cc
+++ b/chromium/third_party/blink/renderer/modules/serial/navigator_serial.cc
@@ -26,7 +26,7 @@ Serial* NavigatorSerial::serial(Navigator& navigator) {
return NavigatorSerial::From(navigator).serial();
}
-void NavigatorSerial::Trace(blink::Visitor* visitor) {
+void NavigatorSerial::Trace(Visitor* visitor) {
visitor->Trace(serial_);
Supplement<Navigator>::Trace(visitor);
}
@@ -35,8 +35,8 @@ NavigatorSerial::NavigatorSerial(Navigator& navigator)
: Supplement<Navigator>(navigator) {
if (navigator.GetFrame()) {
DCHECK(navigator.GetFrame()->GetDocument());
- serial_ =
- MakeGarbageCollected<Serial>(*navigator.GetFrame()->GetDocument());
+ serial_ = MakeGarbageCollected<Serial>(
+ *navigator.GetFrame()->GetDocument()->ToExecutionContext());
}
}
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial.cc b/chromium/third_party/blink/renderer/modules/serial/serial.cc
index b9654d2cdae..4051e1d1859 100644
--- a/chromium/third_party/blink/renderer/modules/serial/serial.cc
+++ b/chromium/third_party/blink/renderer/modules/serial/serial.cc
@@ -12,11 +12,14 @@
#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink.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_serial_port_filter.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_serial_port_request_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/local_frame.h"
#include "third_party/blink/renderer/modules/event_target_modules_names.h"
+#include "third_party/blink/renderer/modules/serial/serial_connection_event.h"
#include "third_party/blink/renderer/modules/serial/serial_port.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
@@ -39,21 +42,31 @@ String TokenToString(const base::UnguessableToken& token) {
} // namespace
Serial::Serial(ExecutionContext& execution_context)
- : ContextLifecycleObserver(&execution_context) {}
+ : ExecutionContextLifecycleObserver(&execution_context) {}
ExecutionContext* Serial::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
const AtomicString& Serial::InterfaceName() const {
return event_target_names::kSerial;
}
-void Serial::ContextDestroyed(ExecutionContext*) {
+void Serial::ContextDestroyed() {
for (auto& entry : port_cache_)
entry.value->ContextDestroyed();
}
+void Serial::OnPortAdded(mojom::blink::SerialPortInfoPtr port_info) {
+ DispatchEvent(*SerialConnectionEvent::Create(
+ event_type_names::kConnect, GetOrCreatePort(std::move(port_info))));
+}
+
+void Serial::OnPortRemoved(mojom::blink::SerialPortInfoPtr port_info) {
+ DispatchEvent(*SerialConnectionEvent::Create(
+ event_type_names::kDisconnect, GetOrCreatePort(std::move(port_info))));
+}
+
ScriptPromise Serial::getPorts(ScriptState* script_state,
ExceptionState& exception_state) {
auto* context = GetExecutionContext();
@@ -63,9 +76,8 @@ ScriptPromise Serial::getPorts(ScriptState* script_state,
return ScriptPromise();
}
- if (!context->GetSecurityContext().IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kSerial,
- ReportOptions::kReportOnFailure)) {
+ if (!context->IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kSerial,
+ ReportOptions::kReportOnFailure)) {
exception_state.ThrowSecurityError(kFeaturePolicyBlocked);
return ScriptPromise();
}
@@ -91,7 +103,7 @@ ScriptPromise Serial::requestPort(ScriptState* script_state,
}
if (!frame->GetDocument()->IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kSerial,
+ mojom::blink::FeaturePolicyFeature::kSerial,
ReportOptions::kReportOnFailure)) {
exception_state.ThrowSecurityError(kFeaturePolicyBlocked);
return ScriptPromise();
@@ -103,17 +115,50 @@ ScriptPromise Serial::requestPort(ScriptState* script_state,
return ScriptPromise();
}
+ Vector<mojom::blink::SerialPortFilterPtr> filters;
+ if (options && options->hasFilters()) {
+ for (const auto& filter : options->filters()) {
+ auto mojo_filter = mojom::blink::SerialPortFilter::New();
+
+ mojo_filter->has_vendor_id = filter->hasUsbVendorId();
+ if (mojo_filter->has_vendor_id) {
+ mojo_filter->vendor_id = filter->usbVendorId();
+ } else {
+ exception_state.ThrowTypeError(
+ "A filter must provide a property to filter by.");
+ return ScriptPromise();
+ }
+
+ mojo_filter->has_product_id = filter->hasUsbProductId();
+ if (mojo_filter->has_product_id) {
+ if (!mojo_filter->has_vendor_id) {
+ exception_state.ThrowTypeError(
+ "A filter containing a usbProductId must also specify a "
+ "usbVendorId.");
+ return ScriptPromise();
+ }
+ mojo_filter->product_id = filter->usbProductId();
+ }
+
+ filters.push_back(std::move(mojo_filter));
+ }
+ }
+
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
request_port_promises_.insert(resolver);
EnsureServiceConnection();
- service_->RequestPort(Vector<mojom::blink::SerialPortFilterPtr>(),
+ service_->RequestPort(std::move(filters),
WTF::Bind(&Serial::OnRequestPort, WrapPersistent(this),
WrapPersistent(resolver)));
return resolver->Promise();
}
+void Serial::Dispose() {
+ receiver_.reset();
+}
+
void Serial::GetPort(
const base::UnguessableToken& token,
mojo::PendingReceiver<device::mojom::blink::SerialPort> receiver) {
@@ -126,7 +171,26 @@ void Serial::Trace(Visitor* visitor) {
visitor->Trace(request_port_promises_);
visitor->Trace(port_cache_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
+}
+
+void Serial::AddedEventListener(const AtomicString& event_type,
+ RegisteredEventListener& listener) {
+ EventTargetWithInlineData::AddedEventListener(event_type, listener);
+
+ if (event_type != event_type_names::kConnect &&
+ event_type != event_type_names::kDisconnect) {
+ return;
+ }
+
+ ExecutionContext* context = GetExecutionContext();
+ if (!context ||
+ !context->IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kSerial,
+ ReportOptions::kDoNotReport)) {
+ return;
+ }
+
+ EnsureServiceConnection();
}
void Serial::EnsureServiceConnection() {
@@ -141,10 +205,13 @@ void Serial::EnsureServiceConnection() {
service_.BindNewPipeAndPassReceiver(task_runner));
service_.set_disconnect_handler(
WTF::Bind(&Serial::OnServiceConnectionError, WrapWeakPersistent(this)));
+
+ service_->SetClient(receiver_.BindNewPipeAndPassRemote());
}
void Serial::OnServiceConnectionError() {
service_.reset();
+ receiver_.reset();
// Script may execute during a call to Resolve(). Swap these sets to prevent
// concurrent modification.
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial.h b/chromium/third_party/blink/renderer/modules/serial/serial.h
index cba9edd27e9..bd3115ff191 100644
--- a/chromium/third_party/blink/renderer/modules/serial/serial.h
+++ b/chromium/third_party/blink/renderer/modules/serial/serial.h
@@ -5,11 +5,12 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SERIAL_SERIAL_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SERIAL_SERIAL_H_
+#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/serial/serial.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -24,9 +25,11 @@ class SerialPort;
class SerialPortRequestOptions;
class Serial final : public EventTargetWithInlineData,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver,
+ public mojom::blink::SerialServiceClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(Serial);
+ USING_PRE_FINALIZER(Serial, Dispose);
public:
explicit Serial(ExecutionContext&);
@@ -35,8 +38,12 @@ class Serial final : public EventTargetWithInlineData,
ExecutionContext* GetExecutionContext() const override;
const AtomicString& InterfaceName() const override;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
+
+ // SerialServiceClient
+ void OnPortAdded(mojom::blink::SerialPortInfoPtr port_info) override;
+ void OnPortRemoved(mojom::blink::SerialPortInfoPtr port_info) override;
// Web-exposed interfaces
DEFINE_ATTRIBUTE_EVENT_LISTENER(connect, kConnect)
@@ -46,11 +53,17 @@ class Serial final : public EventTargetWithInlineData,
const SerialPortRequestOptions*,
ExceptionState&);
+ void Dispose();
void GetPort(
const base::UnguessableToken& token,
mojo::PendingReceiver<device::mojom::blink::SerialPort> receiver);
void Trace(Visitor*) override;
+ protected:
+ // EventTarget
+ void AddedEventListener(const AtomicString& event_type,
+ RegisteredEventListener&) override;
+
private:
void EnsureServiceConnection();
void OnServiceConnectionError();
@@ -60,6 +73,7 @@ class Serial final : public EventTargetWithInlineData,
void OnRequestPort(ScriptPromiseResolver*, mojom::blink::SerialPortInfoPtr);
mojo::Remote<mojom::blink::SerialService> service_;
+ mojo::Receiver<mojom::blink::SerialServiceClient> receiver_{this};
HeapHashSet<Member<ScriptPromiseResolver>> get_ports_promises_;
HeapHashSet<Member<ScriptPromiseResolver>> request_port_promises_;
HeapHashMap<String, WeakMember<SerialPort>> port_cache_;
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial.idl b/chromium/third_party/blink/renderer/modules/serial/serial.idl
index 48d7960a578..7d7a898445b 100644
--- a/chromium/third_party/blink/renderer/modules/serial/serial.idl
+++ b/chromium/third_party/blink/renderer/modules/serial/serial.idl
@@ -2,10 +2,10 @@
// 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
+// https://wicg.github.io/serial/#serial-interface
[
- Exposed(Window Serial,DedicatedWorker Serial),
+ Exposed(Window Serial, DedicatedWorker Serial),
SecureContext
] interface Serial : EventTarget {
attribute EventHandler onconnect;
@@ -15,5 +15,5 @@
Promise<sequence<SerialPort>> getPorts();
[CallWith=ScriptState, RaisesException, MeasureAs=SerialRequestPort, Exposed=Window]
- Promise<SerialPort> requestPort(optional SerialPortRequestOptions options);
+ Promise<SerialPort> requestPort(optional SerialPortRequestOptions options = {});
};
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
new file mode 100644
index 00000000000..c1ffbdde4df
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/serial/serial_connection_event.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/modules/serial/serial_connection_event.h"
+
+#include "third_party/blink/renderer/bindings/modules/v8/v8_serial_connection_event_init.h"
+#include "third_party/blink/renderer/modules/serial/serial_port.h"
+
+namespace blink {
+
+SerialConnectionEvent* SerialConnectionEvent::Create(
+ const AtomicString& type,
+ const SerialConnectionEventInit* initializer) {
+ return MakeGarbageCollected<SerialConnectionEvent>(type, initializer);
+}
+
+SerialConnectionEvent* SerialConnectionEvent::Create(const AtomicString& type,
+ SerialPort* port) {
+ return MakeGarbageCollected<SerialConnectionEvent>(type, port);
+}
+
+SerialConnectionEvent::SerialConnectionEvent(
+ const AtomicString& type,
+ const SerialConnectionEventInit* initializer)
+ : Event(type, initializer), port_(initializer->port()) {}
+
+SerialConnectionEvent::SerialConnectionEvent(const AtomicString& type,
+ SerialPort* port)
+ : Event(type, Bubbles::kNo, Cancelable::kNo), port_(port) {}
+
+void SerialConnectionEvent::Trace(Visitor* visitor) {
+ visitor->Trace(port_);
+ Event::Trace(visitor);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..ac4cd5242ea
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/serial/serial_connection_event.h
@@ -0,0 +1,38 @@
+// 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_SERIAL_SERIAL_CONNECTION_EVENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_SERIAL_SERIAL_CONNECTION_EVENT_H_
+
+#include "third_party/blink/renderer/modules/event_modules.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+
+namespace blink {
+
+class SerialConnectionEventInit;
+class SerialPort;
+
+class SerialConnectionEvent final : public Event {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static SerialConnectionEvent* Create(const AtomicString& type,
+ const SerialConnectionEventInit*);
+ static SerialConnectionEvent* Create(const AtomicString& type, SerialPort*);
+
+ SerialConnectionEvent(const AtomicString& type,
+ const SerialConnectionEventInit*);
+ SerialConnectionEvent(const AtomicString& type, SerialPort*);
+
+ SerialPort* port() const { return port_; }
+
+ void Trace(Visitor*) override;
+
+ private:
+ Member<SerialPort> port_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SERIAL_SERIAL_CONNECTION_EVENT_H_
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_connection_event.idl b/chromium/third_party/blink/renderer/modules/serial/serial_connection_event.idl
new file mode 100644
index 00000000000..994f85892bb
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/serial/serial_connection_event.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.
+
+[
+ Exposed(Window Serial, DedicatedWorker Serial),
+ SecureContext
+] interface SerialConnectionEvent : Event {
+ constructor(DOMString type, SerialConnectionEventInit eventInitDict);
+ [SameObject] readonly attribute SerialPort port;
+};
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_connection_event_init.idl b/chromium/third_party/blink/renderer/modules/serial/serial_connection_event_init.idl
new file mode 100644
index 00000000000..70c2c0d5d1f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/serial/serial_connection_event_init.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.
+
+dictionary SerialConnectionEventInit : EventInit {
+ required 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 dda87bda014..574011bd297 100644
--- a/chromium/third_party/blink/renderer/modules/serial/serial_port.cc
+++ b/chromium/third_party/blink/renderer/modules/serial/serial_port.cc
@@ -7,13 +7,13 @@
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "third_party/blink/renderer/bindings/core/v8/script_function.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#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/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"
#include "third_party/blink/renderer/modules/serial/serial.h"
-#include "third_party/blink/renderer/modules/serial/serial_input_signals.h"
-#include "third_party/blink/renderer/modules/serial/serial_options.h"
-#include "third_party/blink/renderer/modules/serial/serial_output_signals.h"
#include "third_party/blink/renderer/modules/serial/serial_port_underlying_sink.h"
#include "third_party/blink/renderer/modules/serial/serial_port_underlying_source.h"
#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_port_filter.idl b/chromium/third_party/blink/renderer/modules/serial/serial_port_filter.idl
new file mode 100644
index 00000000000..d173cdd9356
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/serial/serial_port_filter.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 SerialPortFilter {
+ unsigned short usbVendorId;
+ unsigned short usbProductId;
+};
diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_port_request_options.idl b/chromium/third_party/blink/renderer/modules/serial/serial_port_request_options.idl
index 8e9c05c5439..8a58d207be7 100644
--- a/chromium/third_party/blink/renderer/modules/serial/serial_port_request_options.idl
+++ b/chromium/third_party/blink/renderer/modules/serial/serial_port_request_options.idl
@@ -5,4 +5,5 @@
// https://wicg.github.io/serial
dictionary SerialPortRequestOptions {
+ sequence<SerialPortFilter> filters;
};
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 55876b3a402..439c6c995be 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
@@ -25,14 +25,16 @@ SerialPortUnderlyingSink::SerialPortUnderlyingSink(
ScriptPromise SerialPortUnderlyingSink::start(
ScriptState* script_state,
- WritableStreamDefaultController* controller) {
+ WritableStreamDefaultController* controller,
+ ExceptionState& exception_state) {
return ScriptPromise::CastUndefined(script_state);
}
ScriptPromise SerialPortUnderlyingSink::write(
ScriptState* script_state,
ScriptValue chunk,
- WritableStreamDefaultController* controller) {
+ WritableStreamDefaultController* controller,
+ ExceptionState& exception_state) {
// There can only be one call to write() in progress at a time.
DCHECK(buffer_source_.IsNull());
DCHECK_EQ(0u, offset_);
@@ -42,18 +44,15 @@ ScriptPromise SerialPortUnderlyingSink::write(
DOMException* exception = pending_exception_;
pending_exception_ = nullptr;
serial_port_->UnderlyingSinkClosed();
- return ScriptPromise::RejectWithDOMException(script_state, exception);
+ exception_state.RethrowV8Exception(ToV8(exception, script_state));
+ return ScriptPromise();
}
- ExceptionState exception_state(script_state->GetIsolate(),
- ExceptionState::kExecutionContext,
- "SerialPortUnderlyingSink", "write");
-
V8ArrayBufferOrArrayBufferView::ToImpl(
script_state->GetIsolate(), chunk.V8Value(), buffer_source_,
UnionTypeConversionMode::kNotNullable, exception_state);
if (exception_state.HadException())
- return ScriptPromise::Reject(script_state, exception_state);
+ return ScriptPromise();
pending_write_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = pending_write_->Promise();
@@ -62,7 +61,8 @@ ScriptPromise SerialPortUnderlyingSink::write(
return promise;
}
-ScriptPromise SerialPortUnderlyingSink::close(ScriptState* script_state) {
+ScriptPromise SerialPortUnderlyingSink::close(ScriptState* script_state,
+ ExceptionState& exception_state) {
// The specification guarantees that this will only be called after all
// pending writes have been completed.
DCHECK(!pending_write_);
@@ -74,7 +74,8 @@ ScriptPromise SerialPortUnderlyingSink::close(ScriptState* script_state) {
if (pending_exception_) {
DOMException* exception = pending_exception_;
pending_exception_ = nullptr;
- return ScriptPromise::RejectWithDOMException(script_state, exception);
+ exception_state.RethrowV8Exception(ToV8(exception, script_state));
+ return ScriptPromise();
}
// TODO(crbug.com/989656): close() should wait for data to be flushed before
@@ -83,12 +84,13 @@ ScriptPromise SerialPortUnderlyingSink::close(ScriptState* script_state) {
}
ScriptPromise SerialPortUnderlyingSink::abort(ScriptState* script_state,
- ScriptValue reason) {
+ ScriptValue reason,
+ ExceptionState& exception_state) {
// The specification guarantees that this will only be called after all
// pending writes have been completed.
// TODO(crbug.com/969653): abort() should trigger a purge of the serial write
// buffers.
- return close(script_state);
+ return close(script_state, exception_state);
}
void SerialPortUnderlyingSink::SignalErrorOnClose(DOMException* exception) {
@@ -135,15 +137,23 @@ void SerialPortUnderlyingSink::WriteData() {
const uint8_t* data = nullptr;
uint32_t length = 0;
+ size_t byte_size = 0;
if (buffer_source_.IsArrayBuffer()) {
DOMArrayBuffer* array = buffer_source_.GetAsArrayBuffer();
+ byte_size = array->ByteLengthAsSizeT();
data = static_cast<const uint8_t*>(array->Data());
- length = array->DeprecatedByteLengthAsUnsigned();
} else {
DOMArrayBufferView* view = buffer_source_.GetAsArrayBufferView().View();
+ byte_size = view->byteLengthAsSizeT();
data = static_cast<const uint8_t*>(view->BaseAddress());
- length = view->deprecatedByteLengthAsUnsigned();
}
+ if (byte_size > std::numeric_limits<uint32_t>::max()) {
+ pending_exception_ = DOMException::Create(
+ "Buffer size exceeds maximum heap object size.", "DataError");
+ PipeClosed();
+ return;
+ }
+ length = static_cast<uint32_t>(byte_size);
DCHECK_LT(offset_, length);
data += offset_;
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 2719dc4ea49..4b1ef651c19 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
@@ -12,6 +12,7 @@
namespace blink {
+class ExceptionState;
class ScriptPromiseResolver;
class SerialPort;
@@ -20,12 +21,17 @@ class SerialPortUnderlyingSink final : public UnderlyingSinkBase {
SerialPortUnderlyingSink(SerialPort*, mojo::ScopedDataPipeProducerHandle);
// UnderlyingSinkBase
- ScriptPromise start(ScriptState*, WritableStreamDefaultController*) override;
+ ScriptPromise start(ScriptState*,
+ WritableStreamDefaultController*,
+ ExceptionState&) override;
ScriptPromise write(ScriptState*,
ScriptValue chunk,
- WritableStreamDefaultController*) override;
- ScriptPromise close(ScriptState*) override;
- ScriptPromise abort(ScriptState*, ScriptValue reason) override;
+ WritableStreamDefaultController*,
+ ExceptionState&) override;
+ ScriptPromise close(ScriptState*, ExceptionState&) override;
+ ScriptPromise abort(ScriptState*,
+ ScriptValue reason,
+ ExceptionState&) override;
// After |data_pipe_| has closed calls to write() will return a Promise
// rejected with this DOMException.
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 7adcc063c3e..6f794772368 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
@@ -49,10 +49,9 @@ ScriptPromise SerialPortUnderlyingSource::Cancel(ScriptState* script_state,
return ScriptPromise::CastUndefined(script_state);
}
-void SerialPortUnderlyingSource::ContextDestroyed(
- ExecutionContext* execution_context) {
+void SerialPortUnderlyingSource::ContextDestroyed() {
Close();
- UnderlyingSourceBase::ContextDestroyed(execution_context);
+ UnderlyingSourceBase::ContextDestroyed();
}
void SerialPortUnderlyingSource::SignalErrorImmediately(
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 1d6116aa6d0..f96014d16f6 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
@@ -23,7 +23,7 @@ class SerialPortUnderlyingSource : public UnderlyingSourceBase {
// UnderlyingSourceBase
ScriptPromise pull(ScriptState*) override;
ScriptPromise Cancel(ScriptState*, ScriptValue reason) override;
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
void SignalErrorImmediately(DOMException*);
void SignalErrorOnClose(DOMException*);
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 8c1951ab80d..e151cec9283 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(blink::Visitor* visitor) {
+void WorkerNavigatorSerial::Trace(Visitor* visitor) {
visitor->Trace(serial_);
Supplement<WorkerNavigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/BUILD.gn b/chromium/third_party/blink/renderer/modules/service_worker/BUILD.gn
index d71015dccc6..2e0e69a9571 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/service_worker/BUILD.gn
@@ -6,6 +6,8 @@ import("//third_party/blink/renderer/modules/modules.gni")
blink_modules_sources("service_worker") {
sources = [
+ "cross_origin_resource_policy_checker.cc",
+ "cross_origin_resource_policy_checker.h",
"extendable_event.cc",
"extendable_event.h",
"extendable_message_event.cc",
@@ -60,11 +62,7 @@ blink_modules_sources("service_worker") {
"wait_until_observer.h",
]
- public_deps = [
- "//third_party/blink/renderer/platform",
- ]
+ public_deps = [ "//third_party/blink/renderer/platform" ]
- deps = [
- "//base",
- ]
+ deps = [ "//base" ]
}
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/DEPS b/chromium/third_party/blink/renderer/modules/service_worker/DEPS
index 91caf3352d9..f96e545391c 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/DEPS
+++ b/chromium/third_party/blink/renderer/modules/service_worker/DEPS
@@ -2,8 +2,8 @@ include_rules = [
"+base/barrier_closure.h",
"+base/threading/thread_checker.h",
"+base/trace_event/trace_event.h",
- "+mojo/public/cpp/bindings/strong_binding.h",
"+mojo/public/cpp/system/data_pipe.h",
+ "+services/network/public",
"-third_party/blink/renderer/modules",
"+third_party/blink/renderer/modules/event_modules.h",
"+third_party/blink/renderer/modules/event_target_modules.h",
@@ -12,11 +12,6 @@ include_rules = [
]
specific_include_rules = {
- "fetch_respond_with_observer\.cc": [
- "+services/network/public/cpp/cross_origin_resource_policy.h",
- "+services/network/public/cpp/features.h",
- "+services/network/public/cpp/resource_response_info.h",
- ],
"service_worker_global_scope\.cc": [
"+third_party/blink/renderer/modules/background_fetch",
"+third_party/blink/renderer/modules/background_sync",
@@ -31,7 +26,6 @@ specific_include_rules = {
],
"service_worker_installed_scripts_manager_test\.cc": [
"+base/run_loop.h",
- "+mojo/public/cpp/bindings/binding.h",
],
"service_worker_event_queue_test\.cc": [
"+base/test/test_mock_time_task_runner.h",
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/client.idl b/chromium/third_party/blink/renderer/modules/service_worker/client.idl
index 640ef5c6395..638cf5647c3 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/client.idl
+++ b/chromium/third_party/blink/renderer/modules/service_worker/client.idl
@@ -17,7 +17,7 @@ enum ClientLifecycleState {
readonly attribute DOMString id;
readonly attribute ClientType type;
[CallWith=ScriptState, RaisesException] void postMessage(any message, sequence<object> transfer);
- [CallWith=ScriptState, RaisesException] void postMessage(any message, optional PostMessageOptions options);
+ [CallWith=ScriptState, RaisesException] void postMessage(any message, optional PostMessageOptions options = {});
// FIXME: frameType is non-standard, see https://crbug.com/697110
[CallWith=ScriptState] readonly attribute ContextFrameType frameType;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/clients.idl b/chromium/third_party/blink/renderer/modules/service_worker/clients.idl
index 8f90d4dd343..a97db407b35 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/clients.idl
+++ b/chromium/third_party/blink/renderer/modules/service_worker/clients.idl
@@ -8,7 +8,7 @@
ImplementedAs=ServiceWorkerClients
] interface Clients {
[CallWith=ScriptState] Promise<any> get(DOMString id);
- [CallWith=ScriptState] Promise<sequence<Client>> matchAll(optional ClientQueryOptions options);
+ [CallWith=ScriptState] Promise<sequence<Client>> matchAll(optional ClientQueryOptions options = {});
[CallWith=ScriptState] Promise<WindowClient?> openWindow(USVString url);
[CallWith=ScriptState] Promise<void> claim();
};
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/cross_origin_resource_policy_checker.cc b/chromium/third_party/blink/renderer/modules/service_worker/cross_origin_resource_policy_checker.cc
new file mode 100644
index 00000000000..fc87af51c4e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/service_worker/cross_origin_resource_policy_checker.cc
@@ -0,0 +1,56 @@
+// 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/service_worker/cross_origin_resource_policy_checker.h"
+
+#include "services/network/public/cpp/cross_origin_resource_policy.h"
+#include "third_party/blink/renderer/core/fetch/response.h"
+
+namespace blink {
+
+CrossOriginResourcePolicyChecker::CrossOriginResourcePolicyChecker(
+ network::CrossOriginEmbedderPolicy policy,
+ mojo::PendingRemote<
+ network::mojom::blink::CrossOriginEmbedderPolicyReporter> reporter)
+ : policy_(std::move(policy)) {
+ if (reporter) {
+ mojo::PendingRemote<network::mojom::CrossOriginEmbedderPolicyReporter>
+ pending_reporter_non_blink{
+ reporter.PassPipe(),
+ network::mojom::CrossOriginEmbedderPolicyReporter::Version_};
+ reporter_.Bind(std::move(pending_reporter_non_blink));
+ }
+}
+
+bool CrossOriginResourcePolicyChecker::IsBlocked(
+ const url::Origin& initiator_origin,
+ network::mojom::RequestMode request_mode,
+ const blink::Response& response) {
+ if (response.InternalURLList().IsEmpty()) {
+ // The response is synthesized in the service worker, so it's considered as
+ // the same origin.
+ return false;
+ }
+ base::Optional<std::string> corp_header_value;
+ String wtf_corp_header_value;
+ if (response.InternalHeaderList()->Get(
+ network::CrossOriginResourcePolicy::kHeaderName,
+ wtf_corp_header_value)) {
+ corp_header_value = wtf_corp_header_value.Utf8();
+ }
+
+ return network::CrossOriginResourcePolicy::IsBlockedByHeaderValue(
+ response.InternalURLList().back(),
+ response.InternalURLList().front(), initiator_origin,
+ corp_header_value, request_mode, initiator_origin, policy_,
+ reporter_ ? reporter_.get() : nullptr)
+ .has_value();
+}
+
+base::WeakPtr<CrossOriginResourcePolicyChecker>
+CrossOriginResourcePolicyChecker::GetWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/cross_origin_resource_policy_checker.h b/chromium/third_party/blink/renderer/modules/service_worker/cross_origin_resource_policy_checker.h
new file mode 100644
index 00000000000..dc73ce1612e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/service_worker/cross_origin_resource_policy_checker.h
@@ -0,0 +1,53 @@
+// 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_SERVICE_WORKER_CROSS_ORIGIN_RESOURCE_POLICY_CHECKER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_CROSS_ORIGIN_RESOURCE_POLICY_CHECKER_H_
+
+#include "mojo/public/cpp/bindings/remote.h"
+#include "services/network/public/cpp/cross_origin_embedder_policy.h"
+#include "services/network/public/mojom/cross_origin_embedder_policy.mojom-blink-forward.h"
+#include "services/network/public/mojom/cross_origin_embedder_policy.mojom.h"
+#include "services/network/public/mojom/fetch_api.mojom.h"
+
+namespace url {
+class Origin;
+} // namespace url
+
+namespace blink {
+
+class Response;
+
+// Contains the COEP policy and the reporter for the controllee and does CORP
+// validation based on it. The lifetime is bound with the Mojo connection
+// between the controllee and the service worker.
+class CrossOriginResourcePolicyChecker {
+ public:
+ // |reporter| can be null if reporting is not necessary.
+ CrossOriginResourcePolicyChecker(
+ network::CrossOriginEmbedderPolicy policy,
+ mojo::PendingRemote<
+ network::mojom::blink::CrossOriginEmbedderPolicyReporter> reporter);
+
+ CrossOriginResourcePolicyChecker(const CrossOriginResourcePolicyChecker&) =
+ delete;
+ CrossOriginResourcePolicyChecker& operator=(
+ const CrossOriginResourcePolicyChecker&) = delete;
+
+ bool IsBlocked(const url::Origin& initiator_origin,
+ network::mojom::RequestMode request_mode,
+ const Response& response);
+
+ base::WeakPtr<CrossOriginResourcePolicyChecker> GetWeakPtr();
+
+ private:
+ const network::CrossOriginEmbedderPolicy policy_;
+ mojo::Remote<network::mojom::CrossOriginEmbedderPolicyReporter> reporter_;
+
+ base::WeakPtrFactory<CrossOriginResourcePolicyChecker> weak_factory_{this};
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_CROSS_ORIGIN_RESOURCE_POLICY_CHECKER_H_
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 1335f012dba..f9734fc64d5 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(blink::Visitor* visitor) {
+void ExtendableEvent::Trace(Visitor* visitor) {
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 75932320766..45ac529723e 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
@@ -32,9 +32,9 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_EXTENDABLE_EVENT_H_
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_extendable_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/modules/service_worker/extendable_event_init.h"
namespace blink {
@@ -59,7 +59,7 @@ class MODULES_EXPORT ExtendableEvent : public Event {
void waitUntil(ScriptState*, ScriptPromise, ExceptionState&);
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
Member<WaitUntilObserver> observer_;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/extendable_event.idl b/chromium/third_party/blink/renderer/modules/service_worker/extendable_event.idl
index a55175d6c8e..f470b8de857 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/extendable_event.idl
+++ b/chromium/third_party/blink/renderer/modules/service_worker/extendable_event.idl
@@ -30,8 +30,8 @@
// https://w3c.github.io/ServiceWorker/#extendableevent-interface
[
- Constructor(DOMString type, optional ExtendableEventInit eventInitDict),
Exposed=ServiceWorker
] interface ExtendableEvent : Event {
+ constructor(DOMString type, optional ExtendableEventInit eventInitDict = {});
[CallWith=ScriptState, RaisesException] void waitUntil(Promise<any> f);
};
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 758194d9081..a2725f915a4 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
@@ -13,46 +13,66 @@ ExtendableMessageEvent* ExtendableMessageEvent::Create(
}
ExtendableMessageEvent* ExtendableMessageEvent::Create(
- const AtomicString& type,
- const ExtendableMessageEventInit* initializer,
+ scoped_refptr<SerializedScriptValue> data,
+ const String& origin,
+ MessagePortArray* ports,
+ ServiceWorkerClient* source,
WaitUntilObserver* observer) {
- return MakeGarbageCollected<ExtendableMessageEvent>(type, initializer,
- observer);
+ ExtendableMessageEvent* event = MakeGarbageCollected<ExtendableMessageEvent>(
+ std::move(data), origin, ports, observer);
+ event->source_as_client_ = source;
+ return event;
}
ExtendableMessageEvent* ExtendableMessageEvent::Create(
scoped_refptr<SerializedScriptValue> data,
const String& origin,
MessagePortArray* ports,
+ ServiceWorker* source,
WaitUntilObserver* observer) {
- return MakeGarbageCollected<ExtendableMessageEvent>(std::move(data), origin,
- ports, observer);
+ ExtendableMessageEvent* event = MakeGarbageCollected<ExtendableMessageEvent>(
+ std::move(data), origin, ports, observer);
+ event->source_as_service_worker_ = source;
+ return event;
}
-ExtendableMessageEvent* ExtendableMessageEvent::Create(
- scoped_refptr<SerializedScriptValue> data,
+ExtendableMessageEvent* ExtendableMessageEvent::CreateError(
const String& origin,
MessagePortArray* ports,
ServiceWorkerClient* source,
WaitUntilObserver* observer) {
- ExtendableMessageEvent* event = MakeGarbageCollected<ExtendableMessageEvent>(
- std::move(data), origin, ports, observer);
+ ExtendableMessageEvent* event =
+ MakeGarbageCollected<ExtendableMessageEvent>(origin, ports, observer);
event->source_as_client_ = source;
return event;
}
-ExtendableMessageEvent* ExtendableMessageEvent::Create(
- scoped_refptr<SerializedScriptValue> data,
+ExtendableMessageEvent* ExtendableMessageEvent::CreateError(
const String& origin,
MessagePortArray* ports,
ServiceWorker* source,
WaitUntilObserver* observer) {
- ExtendableMessageEvent* event = MakeGarbageCollected<ExtendableMessageEvent>(
- std::move(data), origin, ports, observer);
+ ExtendableMessageEvent* event =
+ MakeGarbageCollected<ExtendableMessageEvent>(origin, ports, observer);
event->source_as_service_worker_ = source;
return event;
}
+ScriptValue ExtendableMessageEvent::data(ScriptState* script_state) const {
+ v8::Local<v8::Value> value;
+ if (!data_.IsEmpty()) {
+ value = data_.GetAcrossWorld(script_state);
+ } else if (serialized_data_) {
+ SerializedScriptValue::DeserializeOptions options;
+ MessagePortArray message_ports = ports();
+ options.message_ports = &message_ports;
+ value = serialized_data_->Deserialize(script_state->GetIsolate(), options);
+ } else {
+ value = v8::Null(script_state->GetIsolate());
+ }
+ return ScriptValue(script_state->GetIsolate(), value);
+}
+
void ExtendableMessageEvent::source(
ClientOrServiceWorkerOrMessagePort& result) const {
if (source_as_client_)
@@ -82,7 +102,8 @@ const AtomicString& ExtendableMessageEvent::InterfaceName() const {
return event_interface_names::kExtendableMessageEvent;
}
-void ExtendableMessageEvent::Trace(blink::Visitor* visitor) {
+void ExtendableMessageEvent::Trace(Visitor* visitor) {
+ visitor->Trace(data_);
visitor->Trace(source_as_client_);
visitor->Trace(source_as_service_worker_);
visitor->Trace(source_as_message_port_);
@@ -100,6 +121,10 @@ ExtendableMessageEvent::ExtendableMessageEvent(
const ExtendableMessageEventInit* initializer,
WaitUntilObserver* observer)
: ExtendableEvent(type, initializer, observer) {
+ if (initializer->hasData()) {
+ const ScriptValue& data = initializer->data();
+ data_.Set(data.GetIsolate(), data.V8Value());
+ }
if (initializer->hasOrigin())
origin_ = initializer->origin();
if (initializer->hasLastEventId())
@@ -132,4 +157,14 @@ ExtendableMessageEvent::ExtendableMessageEvent(
serialized_data_->RegisterMemoryAllocatedWithCurrentScriptContext();
}
+ExtendableMessageEvent::ExtendableMessageEvent(const String& origin,
+ MessagePortArray* ports,
+ WaitUntilObserver* observer)
+ : ExtendableEvent(event_type_names::kMessageerror,
+ ExtendableMessageEventInit::Create(),
+ observer),
+ origin_(origin),
+ last_event_id_(String()),
+ ports_(ports) {}
+
} // namespace blink
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 b0517c6dc54..af67cae6b93 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
@@ -5,10 +5,11 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_EXTENDABLE_MESSAGE_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_EXTENDABLE_MESSAGE_EVENT_H_
+#include "third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_extendable_message_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/service_worker/extendable_event.h"
-#include "third_party/blink/renderer/modules/service_worker/extendable_message_event_init.h"
namespace blink {
@@ -20,15 +21,6 @@ class MODULES_EXPORT ExtendableMessageEvent final : public ExtendableEvent {
const AtomicString& type,
const ExtendableMessageEventInit* initializer);
static ExtendableMessageEvent* Create(
- const AtomicString& type,
- const ExtendableMessageEventInit* initializer,
- WaitUntilObserver*);
- static ExtendableMessageEvent* Create(
- scoped_refptr<SerializedScriptValue> data,
- const String& origin,
- MessagePortArray* ports,
- WaitUntilObserver*);
- static ExtendableMessageEvent* Create(
scoped_refptr<SerializedScriptValue> data,
const String& origin,
MessagePortArray* ports,
@@ -40,6 +32,14 @@ class MODULES_EXPORT ExtendableMessageEvent final : public ExtendableEvent {
MessagePortArray* ports,
ServiceWorker* source,
WaitUntilObserver*);
+ static ExtendableMessageEvent* CreateError(const String& origin,
+ MessagePortArray* ports,
+ ServiceWorkerClient* source,
+ WaitUntilObserver*);
+ static ExtendableMessageEvent* CreateError(const String& origin,
+ MessagePortArray* ports,
+ ServiceWorker* source,
+ WaitUntilObserver*);
ExtendableMessageEvent(const AtomicString& type,
const ExtendableMessageEventInit* initializer);
@@ -50,6 +50,10 @@ class MODULES_EXPORT ExtendableMessageEvent final : public ExtendableEvent {
const String& origin,
MessagePortArray* ports,
WaitUntilObserver*);
+ // Creates a 'messageerror' event.
+ ExtendableMessageEvent(const String& origin,
+ MessagePortArray* ports,
+ WaitUntilObserver*);
SerializedScriptValue* SerializedData() const {
return serialized_data_.get();
@@ -58,6 +62,8 @@ class MODULES_EXPORT ExtendableMessageEvent final : public ExtendableEvent {
serialized_data_ = std::move(serialized_data);
}
+ ScriptValue data(ScriptState* script_state) const;
+ bool isDataDirty() const { return false; }
const String& origin() const { return origin_; }
const String& lastEventId() const { return last_event_id_; }
void source(ClientOrServiceWorkerOrMessagePort& result) const;
@@ -65,10 +71,11 @@ class MODULES_EXPORT ExtendableMessageEvent final : public ExtendableEvent {
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
scoped_refptr<SerializedScriptValue> serialized_data_;
+ WorldSafeV8Reference<v8::Value> data_;
String origin_;
String last_event_id_;
Member<ServiceWorkerClient> source_as_client_;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.idl b/chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.idl
index a508c35226f..d6b1d3f6fc1 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.idl
+++ b/chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.idl
@@ -5,14 +5,10 @@
// https://w3c.github.io/ServiceWorker/#extendablemessageevent-interface
[
- // TODO(bashi): Stop using CustomConstructor once we solve reference
- // circulation between Blink and V8. http://crbug.com/501866
- // Constructor should be:
- // Constructor(DOMString type, optional ExtendableMessageEventInit eventInitDict),
- CustomConstructor,
Exposed=ServiceWorker
] interface ExtendableMessageEvent : ExtendableEvent {
- [Custom=Getter] readonly attribute any data;
+ constructor(DOMString type, optional ExtendableMessageEventInit eventInitDict = {});
+ [CallWith=ScriptState, CachedAttribute=isDataDirty] readonly attribute any data;
readonly attribute DOMString origin;
readonly attribute DOMString lastEventId;
[SameObject] readonly attribute (Client or ServiceWorker or MessagePort)? source;
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 1b6f3e6286d..049cc962464 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
@@ -91,12 +91,10 @@ FetchEvent::FetchEvent(ScriptState* script_state,
worker_timing_remote,
bool navigation_preload_sent)
: ExtendableEvent(type, initializer, wait_until_observer),
- ContextClient(ExecutionContext::From(script_state)),
+ ExecutionContextClient(ExecutionContext::From(script_state)),
observer_(respond_with_observer),
preload_response_property_(MakeGarbageCollected<PreloadResponseProperty>(
- ExecutionContext::From(script_state),
- this,
- PreloadResponseProperty::kPreloadResponse)),
+ ExecutionContext::From(script_state))),
worker_timing_remote_(std::move(worker_timing_remote)) {
if (!navigation_preload_sent)
preload_response_property_->ResolveWithUndefined();
@@ -130,12 +128,12 @@ void FetchEvent::OnNavigationPreloadResponse(
}
// TODO(ricea): Verify that this response can't be aborted from JS.
FetchResponseData* response_data =
- bytes_consumer ? FetchResponseData::CreateWithBuffer(
- MakeGarbageCollected<BodyStreamBuffer>(
- script_state, bytes_consumer,
- MakeGarbageCollected<AbortSignal>(
- ExecutionContext::From(script_state))))
- : FetchResponseData::Create();
+ bytes_consumer
+ ? FetchResponseData::CreateWithBuffer(BodyStreamBuffer::Create(
+ script_state, bytes_consumer,
+ MakeGarbageCollected<AbortSignal>(
+ ExecutionContext::From(script_state))))
+ : FetchResponseData::Create();
Vector<KURL> url_list(1);
url_list[0] = preload_response_->CurrentRequestUrl();
response_data->SetURLList(url_list);
@@ -198,7 +196,8 @@ void FetchEvent::OnNavigationPreloadComplete(
// According to the Resource Timing spec, the initiator type of
// navigation preload request is "navigation".
scoped_refptr<ResourceTimingInfo> info = ResourceTimingInfo::Create(
- "navigation", request_time, request_->GetRequestContextType());
+ "navigation", request_time, request_->GetRequestContextType(),
+ request_->GetRequestDestination());
info->SetNegativeAllowed(true);
info->SetLoadResponseEnd(completion_time);
info->SetInitialURL(request_->url());
@@ -227,13 +226,13 @@ void FetchEvent::addPerformanceEntry(PerformanceMeasure* performance_measure) {
}
}
-void FetchEvent::Trace(blink::Visitor* visitor) {
+void FetchEvent::Trace(Visitor* visitor) {
visitor->Trace(observer_);
visitor->Trace(request_);
visitor->Trace(preload_response_property_);
visitor->Trace(body_completion_notifier_);
ExtendableEvent::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 1b688c51ff2..decd215fe4c 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
@@ -12,12 +12,12 @@
#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/core/v8/script_promise_property.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_fetch_event_init.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/fetch/request.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/service_worker/extendable_event.h"
-#include "third_party/blink/renderer/modules/service_worker/fetch_event_init.h"
#include "third_party/blink/renderer/modules/service_worker/wait_until_observer.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer.h"
@@ -42,14 +42,13 @@ class WorkerGlobalScope;
class MODULES_EXPORT FetchEvent final
: public ExtendableEvent,
public ActiveScriptWrappable<FetchEvent>,
- public ContextClient {
+ public ExecutionContextClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(FetchEvent);
public:
- using PreloadResponseProperty = ScriptPromiseProperty<Member<FetchEvent>,
- Member<Response>,
- Member<DOMException>>;
+ using PreloadResponseProperty =
+ ScriptPromiseProperty<Member<Response>, Member<DOMException>>;
static FetchEvent* Create(ScriptState*,
const AtomicString& type,
const FetchEventInit*);
@@ -90,7 +89,7 @@ class MODULES_EXPORT FetchEvent final
// ScriptWrappable
bool HasPendingActivity() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<FetchRespondWithObserver> observer_;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.idl b/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.idl
index 4e2c283d0a7..409e193ece0 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.idl
+++ b/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.idl
@@ -5,10 +5,9 @@
// https://w3c.github.io/ServiceWorker/#fetchevent-interface
[
ActiveScriptWrappable,
- Constructor(DOMString type, FetchEventInit eventInitDict),
- ConstructorCallWith=ScriptState,
Exposed=ServiceWorker
] interface FetchEvent : ExtendableEvent {
+ [CallWith=ScriptState] constructor(DOMString type, FetchEventInit eventInitDict);
[SameObject] readonly attribute Request request;
readonly attribute DOMString clientId;
readonly attribute DOMString resultingClientId;
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 f6b891a54ae..88271d75126 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
@@ -12,9 +12,7 @@
#include "base/metrics/histogram_macros.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
-#include "services/network/public/cpp/cross_origin_resource_policy.h"
#include "services/network/public/cpp/features.h"
-#include "services/network/public/cpp/resource_response_info.h"
#include "services/network/public/mojom/fetch_api.mojom-blink.h"
#include "third_party/blink/public/mojom/devtools/console_message.mojom-blink.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink-forward.h"
@@ -26,9 +24,11 @@
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/fetch/body_stream_buffer.h"
#include "third_party/blink/renderer/core/inspector/console_message.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_global_scope.h"
#include "third_party/blink/renderer/modules/service_worker/wait_until_observer.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/loader/fetch/bytes_consumer.h"
#include "v8/include/v8.h"
@@ -120,11 +120,11 @@ const String GetMessageForResponseError(ServiceWorkerResponseError error,
return error_message;
}
-bool IsNavigationRequest(network::mojom::RequestContextFrameType frame_type) {
- return frame_type != network::mojom::RequestContextFrameType::kNone;
+bool IsNavigationRequest(mojom::RequestContextFrameType frame_type) {
+ return frame_type != mojom::RequestContextFrameType::kNone;
}
-bool IsClientRequest(network::mojom::RequestContextFrameType frame_type,
+bool IsClientRequest(mojom::RequestContextFrameType frame_type,
mojom::RequestContextType request_context) {
return IsNavigationRequest(frame_type) ||
request_context == mojom::RequestContextType::SHARED_WORKER ||
@@ -177,7 +177,7 @@ class FetchLoaderClient final : public GarbageCollected<FetchLoaderClient>,
std::move(body_stream_), std::move(callback_receiver_));
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
FetchDataLoader::Client::Trace(visitor);
}
@@ -194,26 +194,16 @@ class FetchLoaderClient final : public GarbageCollected<FetchLoaderClient>,
} // namespace
-FetchRespondWithObserver* FetchRespondWithObserver::Create(
- ExecutionContext* context,
- int fetch_event_id,
- network::mojom::blink::CrossOriginEmbedderPolicy requestor_coep,
- const mojom::blink::FetchAPIRequest& request,
- WaitUntilObserver* observer) {
- return MakeGarbageCollected<FetchRespondWithObserver>(
- context, fetch_event_id, requestor_coep, request, observer);
-}
-
// This function may be called when an exception is scheduled. Thus, it must
// never invoke any code that might throw. In particular, it must never invoke
// JavaScript.
void FetchRespondWithObserver::OnResponseRejected(
ServiceWorkerResponseError error) {
DCHECK(GetExecutionContext());
- GetExecutionContext()->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning,
- GetMessageForResponseError(error, request_url_)));
+ GetExecutionContext()->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning,
+ GetMessageForResponseError(error, request_url_)));
// The default value of FetchAPIResponse's status is 0, which maps to a
// network error.
@@ -317,14 +307,8 @@ void FetchRespondWithObserver::OnResponseFulfilled(
// If Cross-Origin-Embedder-Policy is set to require-corp,
// Cross-Origin-Resource-Policy verification should happen before passing the
// response to the client.
- if (base::FeatureList::IsEnabled(network::features::kCrossOriginIsolation)) {
- base::Optional<std::string> corp_header_value;
- WTF::String wtf_corp_header_value;
- if (response->InternalHeaderList()->Get(
- network::CrossOriginResourcePolicy::kHeaderName,
- wtf_corp_header_value)) {
- corp_header_value = wtf_corp_header_value.Utf8();
- }
+ if (base::FeatureList::IsEnabled(
+ network::features::kCrossOriginEmbedderPolicy)) {
// The service worker script must be in the same origin with the requestor,
// which is a client of the service worker.
//
@@ -332,10 +316,15 @@ void FetchRespondWithObserver::OnResponseFulfilled(
// Hence we provide |initiator_origin| as |request_initiator_site_lock|.
auto initiator_origin =
url::Origin::Create(GURL(service_worker_global_scope->Url()));
- if (network::CrossOriginResourcePolicy::VerifyByHeaderValue(
- request_url_, initiator_origin, corp_header_value, request_mode_,
- initiator_origin, requestor_coep_) !=
- network::CrossOriginResourcePolicy::VerificationResult::kAllow) {
+ // |corp_checker_| could be nullptr when the request is for a main resource
+ // or the connection to the client which initiated the request is broken.
+ // CORP check isn't needed in both cases because a service worker should be
+ // in the same origin with the main resource, and the response to the broken
+ // connection won't reach to the client.
+ if (corp_checker_ &&
+ corp_checker_->IsBlocked(
+ url::Origin::Create(GURL(service_worker_global_scope->Url())),
+ request_mode_, *response)) {
OnResponseRejected(ServiceWorkerResponseError::kDisallowedByCorp);
return;
}
@@ -343,6 +332,10 @@ void FetchRespondWithObserver::OnResponseFulfilled(
BodyStreamBuffer* buffer = response->InternalBodyBuffer();
if (buffer) {
+ // The |side_data_blob| must be taken before the body buffer is
+ // drained or loading begins.
+ fetch_api_response->side_data_blob = buffer->TakeSideDataBlob();
+
scoped_refptr<BlobDataHandle> blob_data_handle =
buffer->DrainAsBlobDataHandle(
BytesConsumer::BlobSizePolicy::kAllowBlobWithInvalidSize,
@@ -401,7 +394,7 @@ void FetchRespondWithObserver::OnNoResponse() {
FetchRespondWithObserver::FetchRespondWithObserver(
ExecutionContext* context,
int fetch_event_id,
- network::mojom::blink::CrossOriginEmbedderPolicy requestor_coep,
+ base::WeakPtr<CrossOriginResourcePolicyChecker> corp_checker,
const mojom::blink::FetchAPIRequest& request,
WaitUntilObserver* observer)
: RespondWithObserver(context, fetch_event_id, observer),
@@ -410,10 +403,10 @@ FetchRespondWithObserver::FetchRespondWithObserver(
redirect_mode_(request.redirect_mode),
frame_type_(request.frame_type),
request_context_(request.request_context_type),
- requestor_coep_(requestor_coep),
+ corp_checker_(std::move(corp_checker)),
task_runner_(context->GetTaskRunner(TaskType::kNetworking)) {}
-void FetchRespondWithObserver::Trace(blink::Visitor* visitor) {
+void FetchRespondWithObserver::Trace(Visitor* visitor) {
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 4591c6f9d6f..b96e682a3bf 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
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_FETCH_RESPOND_WITH_OBSERVER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_FETCH_RESPOND_WITH_OBSERVER_H_
-#include "services/network/public/mojom/cross_origin_embedder_policy.mojom-blink-forward.h"
+#include "services/network/public/cpp/cross_origin_embedder_policy.h"
#include "services/network/public/mojom/fetch_api.mojom-blink-forward.h"
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/renderer/modules/modules_export.h"
@@ -15,6 +15,7 @@
namespace blink {
+class CrossOriginResourcePolicyChecker;
class ExecutionContext;
class ScriptValue;
class WaitUntilObserver;
@@ -29,19 +30,13 @@ class FetchAPIRequest;
// notifies the client.
class MODULES_EXPORT FetchRespondWithObserver : public RespondWithObserver {
public:
- FetchRespondWithObserver(ExecutionContext*,
- int fetch_event_id,
- network::mojom::blink::CrossOriginEmbedderPolicy,
- const mojom::blink::FetchAPIRequest&,
- WaitUntilObserver*);
- ~FetchRespondWithObserver() override = default;
-
- static FetchRespondWithObserver* Create(
+ FetchRespondWithObserver(
ExecutionContext*,
int fetch_event_id,
- network::mojom::blink::CrossOriginEmbedderPolicy,
+ base::WeakPtr<CrossOriginResourcePolicyChecker> corp_checker,
const mojom::blink::FetchAPIRequest&,
WaitUntilObserver*);
+ ~FetchRespondWithObserver() override = default;
void OnResponseRejected(mojom::ServiceWorkerResponseError) override;
void OnResponseFulfilled(ScriptState*,
@@ -51,15 +46,15 @@ class MODULES_EXPORT FetchRespondWithObserver : public RespondWithObserver {
const char* property_name) override;
void OnNoResponse() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
const KURL request_url_;
const network::mojom::RequestMode request_mode_;
const network::mojom::RedirectMode redirect_mode_;
- const network::mojom::RequestContextFrameType frame_type_;
+ const mojom::RequestContextFrameType frame_type_;
const mojom::RequestContextType request_context_;
- const network::mojom::blink::CrossOriginEmbedderPolicy requestor_coep_;
+ base::WeakPtr<CrossOriginResourcePolicyChecker> corp_checker_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
};
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/idls.gni b/chromium/third_party/blink/renderer/modules/service_worker/idls.gni
new file mode 100644
index 00000000000..6206a7a212f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/service_worker/idls.gni
@@ -0,0 +1,32 @@
+# 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 = [
+ "client.idl",
+ "clients.idl",
+ "extendable_event.idl",
+ "extendable_message_event.idl",
+ "fetch_event.idl",
+ "install_event.idl",
+ "navigation_preload_manager.idl",
+ "service_worker.idl",
+ "service_worker_container.idl",
+ "service_worker_global_scope.idl",
+ "service_worker_registration.idl",
+ "window_client.idl",
+]
+
+modules_dictionary_idl_files = [
+ "client_query_options.idl",
+ "extendable_event_init.idl",
+ "extendable_message_event_init.idl",
+ "fetch_event_init.idl",
+ "navigation_preload_state.idl",
+ "registration_options.idl",
+]
+
+modules_dependency_idl_files = [ "navigator_service_worker.idl" ]
+
+modules_testing_dependency_idl_files =
+ [ "testing/internals_service_worker.idl" ]
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/install_event.idl b/chromium/third_party/blink/renderer/modules/service_worker/install_event.idl
index ce16062c0b9..29b97ecda56 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/install_event.idl
+++ b/chromium/third_party/blink/renderer/modules/service_worker/install_event.idl
@@ -5,7 +5,7 @@
// https://w3c.github.io/ServiceWorker/#installevent
[
- Constructor(DOMString type, optional ExtendableEventInit eventInitDict),
Exposed=ServiceWorker
] interface InstallEvent : ExtendableEvent {
+ constructor(DOMString type, optional ExtendableEventInit eventInitDict = {});
};
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 3c48c20ce58..06b7f854921 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
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/bindings/core/v8/callback_promise_adapter.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_registration.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/network/http_parsers.h"
namespace blink {
@@ -23,13 +24,13 @@ ScriptPromise NavigationPreloadManager::disable(ScriptState* script_state) {
ScriptPromise NavigationPreloadManager::setHeaderValue(
ScriptState* script_state,
- const String& value) {
+ const String& value,
+ ExceptionState& exception_state) {
if (!IsValidHTTPHeaderValue(value)) {
- return ScriptPromise::Reject(
- script_state, V8ThrowException::CreateTypeError(
- script_state->GetIsolate(),
- "The string provided to setHeaderValue ('" + value +
- "') is not a valid HTTP header field value."));
+ exception_state.ThrowTypeError(
+ "The string provided to setHeaderValue ('" + value +
+ "') is not a valid HTTP header field value.");
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -57,7 +58,7 @@ ScriptPromise NavigationPreloadManager::SetEnabled(bool enable,
return promise;
}
-void NavigationPreloadManager::Trace(blink::Visitor* visitor) {
+void NavigationPreloadManager::Trace(Visitor* visitor) {
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 a04c52825d2..631913533b9 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
@@ -11,25 +11,23 @@
namespace blink {
+class ExceptionState;
class ServiceWorkerRegistration;
class NavigationPreloadManager final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- static NavigationPreloadManager* Create(
- ServiceWorkerRegistration* registration) {
- return MakeGarbageCollected<NavigationPreloadManager>(registration);
- }
-
explicit NavigationPreloadManager(ServiceWorkerRegistration*);
ScriptPromise enable(ScriptState*);
ScriptPromise disable(ScriptState*);
- ScriptPromise setHeaderValue(ScriptState*, const String& value);
+ ScriptPromise setHeaderValue(ScriptState*,
+ const String& value,
+ ExceptionState& exception_state);
ScriptPromise getState(ScriptState*);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
ScriptPromise SetEnabled(bool enable, ScriptState*);
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.idl b/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.idl
index 6176378d549..86786f5945b 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.idl
+++ b/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.idl
@@ -9,6 +9,6 @@
] interface NavigationPreloadManager {
[CallWith=ScriptState] Promise<void> enable();
[CallWith=ScriptState] Promise<void> disable();
- [CallWith=ScriptState] Promise<void> setHeaderValue(ByteString value);
+ [CallWith=ScriptState, RaisesException] Promise<void> setHeaderValue(ByteString value);
[CallWith=ScriptState] Promise<NavigationPreloadState> getState();
};
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/navigator_service_worker.cc b/chromium/third_party/blink/renderer/modules/service_worker/navigator_service_worker.cc
index 6d385b9cce7..668a8deb299 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/navigator_service_worker.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/navigator_service_worker.cc
@@ -90,7 +90,8 @@ ServiceWorkerContainer* NavigatorServiceWorker::GetOrCreateContainer(
->GetSecurityOrigin()
->CanAccessServiceWorkers()) {
String error_message;
- if (frame->GetSecurityContext()->IsSandboxed(WebSandboxFlags::kOrigin)) {
+ if (frame->GetSecurityContext()->IsSandboxed(
+ mojom::blink::WebSandboxFlags::kOrigin)) {
error_message =
"Service worker is disabled because the context is sandboxed and "
"lacks the 'allow-same-origin' flag.";
@@ -108,10 +109,10 @@ ServiceWorkerContainer* NavigatorServiceWorker::GetOrCreateContainer(
}
return ServiceWorkerContainer::From(
- To<Document>(frame->DomWindow()->GetExecutionContext()));
+ Document::From(frame->DomWindow()->GetExecutionContext()));
}
-void NavigatorServiceWorker::Trace(blink::Visitor* visitor) {
+void NavigatorServiceWorker::Trace(Visitor* visitor) {
Supplement<Navigator>::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/navigator_service_worker.h b/chromium/third_party/blink/renderer/modules/service_worker/navigator_service_worker.h
index fabc55aae30..896dda0a726 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/navigator_service_worker.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/navigator_service_worker.h
@@ -34,7 +34,7 @@ class MODULES_EXPORT NavigatorServiceWorker final
ExceptionState&);
explicit NavigatorServiceWorker(Navigator&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
ServiceWorkerContainer* GetOrCreateContainer(LocalFrame*, ExceptionState&);
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 9732b7eba96..15e5ec1dfa0 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
@@ -101,14 +101,14 @@ void RespondWithObserver::ResponseWasFulfilled(
RespondWithObserver::RespondWithObserver(ExecutionContext* context,
int event_id,
WaitUntilObserver* observer)
- : ContextClient(context),
+ : ExecutionContextClient(context),
event_id_(event_id),
state_(kInitial),
observer_(observer) {}
-void RespondWithObserver::Trace(blink::Visitor* visitor) {
+void RespondWithObserver::Trace(Visitor* visitor) {
visitor->Trace(observer_);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 63e8cee54f1..20134324337 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
@@ -7,7 +7,7 @@
#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/heap/handle.h"
@@ -26,7 +26,7 @@ class WaitUntilObserver;
// overriding onResponseFulfilled, onResponseRejected and onNoResponse.
class MODULES_EXPORT RespondWithObserver
: public GarbageCollected<RespondWithObserver>,
- public ContextClient {
+ public ExecutionContextClient {
USING_GARBAGE_COLLECTED_MIXIN(RespondWithObserver);
public:
@@ -54,7 +54,7 @@ class MODULES_EXPORT RespondWithObserver
// Called when the event handler finished without calling respondWith().
virtual void OnNoResponse() = 0;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 e08ae0d17a9..1d032a921ef 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
@@ -37,11 +37,11 @@
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_post_message_options.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/messaging/blink_transferable_message.h"
#include "third_party/blink/renderer/core/messaging/message_port.h"
-#include "third_party/blink/renderer/core/messaging/post_message_options.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_container.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h"
@@ -95,6 +95,12 @@ void ServiceWorker::postMessage(ScriptState* script_state,
if (exception_state.HadException())
return;
+ if (msg.message->IsLockedToAgentCluster()) {
+ msg.locked_agent_cluster_id = GetExecutionContext()->GetAgentClusterID();
+ } else {
+ msg.locked_agent_cluster_id = base::nullopt;
+ }
+
host_->PostMessageToServiceWorker(std::move(msg));
}
@@ -157,7 +163,7 @@ ServiceWorker* ServiceWorker::From(ExecutionContext* context,
return scope->GetOrCreateServiceWorker(std::move(info));
}
- return ServiceWorkerContainer::From(To<Document>(context))
+ return ServiceWorkerContainer::From(Document::From(context))
->GetOrCreateServiceWorker(std::move(info));
}
@@ -170,7 +176,7 @@ bool ServiceWorker::HasPendingActivity() const {
void ServiceWorker::ContextLifecycleStateChanged(
mojom::FrameLifecycleState state) {}
-void ServiceWorker::ContextDestroyed(ExecutionContext*) {
+void ServiceWorker::ContextDestroyed() {
was_stopped_ = true;
}
@@ -199,7 +205,7 @@ void ServiceWorker::Dispose() {
receiver_.reset();
}
-void ServiceWorker::Trace(blink::Visitor* visitor) {
+void ServiceWorker::Trace(Visitor* visitor) {
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 4d6385ef29c..0c281cc7f03 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// Pre-finalization needed to promptly release owned WebServiceWorker.
void Dispose();
@@ -105,9 +105,9 @@ class MODULES_EXPORT ServiceWorker final
ScriptPromise InternalsTerminate(ScriptState*);
private:
- // ContextLifecycleStateObserver overrides.
+ // ExecutionContextLifecycleStateObserver overrides.
void ContextLifecycleStateChanged(mojom::FrameLifecycleState state) override;
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
bool was_stopped_;
const KURL url_;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker.idl b/chromium/third_party/blink/renderer/modules/service_worker/service_worker.idl
index 3b1a85c71ce..fee6b379a9d 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker.idl
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker.idl
@@ -48,7 +48,7 @@ enum ServiceWorkerState {
] interface ServiceWorker : EventTarget {
[CallWith=ScriptState, RaisesException] void postMessage(any message, sequence<object> transfer);
- [CallWith=ScriptState, RaisesException] void postMessage(any message, optional PostMessageOptions options);
+ [CallWith=ScriptState, RaisesException] void postMessage(any message, optional PostMessageOptions options = {});
readonly attribute USVString scriptURL;
readonly attribute ServiceWorkerState state;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.cc
index ba7ad129306..4078ad2783e 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.cc
@@ -11,10 +11,10 @@
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/renderer/bindings/core/v8/callback_promise_adapter.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_post_message_options.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/messaging/blink_transferable_message.h"
#include "third_party/blink/renderer/core/messaging/message_port.h"
-#include "third_party/blink/renderer/core/messaging/post_message_options.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
@@ -22,11 +22,6 @@
namespace blink {
-ServiceWorkerClient* ServiceWorkerClient::Create(
- const mojom::blink::ServiceWorkerClientInfo& info) {
- return MakeGarbageCollected<ServiceWorkerClient>(info);
-}
-
ServiceWorkerClient::ServiceWorkerClient(
const mojom::blink::ServiceWorkerClientInfo& info)
: uuid_(info.client_uuid),
@@ -58,13 +53,13 @@ String ServiceWorkerClient::frameType(ScriptState* script_state) const {
UseCounter::Count(ExecutionContext::From(script_state),
WebFeature::kServiceWorkerClientFrameType);
switch (frame_type_) {
- case network::mojom::RequestContextFrameType::kAuxiliary:
+ case mojom::RequestContextFrameType::kAuxiliary:
return "auxiliary";
- case network::mojom::RequestContextFrameType::kNested:
+ case mojom::RequestContextFrameType::kNested:
return "nested";
- case network::mojom::RequestContextFrameType::kNone:
+ case mojom::RequestContextFrameType::kNone:
return "none";
- case network::mojom::RequestContextFrameType::kTopLevel:
+ case mojom::RequestContextFrameType::kTopLevel:
return "top-level";
}
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.h
index b44ef1ca091..406ed052a00 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.h
@@ -22,9 +22,6 @@ class MODULES_EXPORT ServiceWorkerClient : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- static ServiceWorkerClient* Create(
- const mojom::blink::ServiceWorkerClientInfo&);
-
explicit ServiceWorkerClient(const mojom::blink::ServiceWorkerClientInfo&);
~ServiceWorkerClient() override;
@@ -50,7 +47,7 @@ class MODULES_EXPORT ServiceWorkerClient : public ScriptWrappable {
const String uuid_;
const String url_;
const mojom::ServiceWorkerClientType type_;
- const network::mojom::RequestContextFrameType frame_type_;
+ const mojom::RequestContextFrameType frame_type_;
const mojom::ServiceWorkerClientLifecycleState lifecycle_state_;
};
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.cc
index 9c4ee806a60..1d246159a9d 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.cc
@@ -54,11 +54,11 @@ void DidGetClient(ScriptPromiseResolver* resolver,
ServiceWorkerClient* client = nullptr;
switch (info->client_type) {
case mojom::ServiceWorkerClientType::kWindow:
- client = ServiceWorkerWindowClient::Create(*info);
+ client = MakeGarbageCollected<ServiceWorkerWindowClient>(*info);
break;
case mojom::ServiceWorkerClientType::kDedicatedWorker:
case mojom::ServiceWorkerClientType::kSharedWorker:
- client = ServiceWorkerClient::Create(*info);
+ client = MakeGarbageCollected<ServiceWorkerClient>(*info);
break;
case mojom::ServiceWorkerClientType::kAll:
NOTREACHED();
@@ -95,9 +95,9 @@ void DidGetClients(ScriptPromiseResolver* resolver,
HeapVector<Member<ServiceWorkerClient>> clients;
for (const auto& info : infos) {
if (info->client_type == mojom::blink::ServiceWorkerClientType::kWindow)
- clients.push_back(ServiceWorkerWindowClient::Create(*info));
+ clients.push_back(MakeGarbageCollected<ServiceWorkerWindowClient>(*info));
else
- clients.push_back(ServiceWorkerClient::Create(*info));
+ clients.push_back(MakeGarbageCollected<ServiceWorkerClient>(*info));
}
resolver->Resolve(std::move(clients));
}
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.h
index ccd60ed1d5b..ff829919745 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_SERVICE_WORKER_CLIENTS_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_SERVICE_WORKER_CLIENTS_H_
-#include "third_party/blink/renderer/modules/service_worker/client_query_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_client_query_options.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
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 31ecf19e827..4795fc804c7 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
@@ -33,6 +33,7 @@
#include <utility>
#include "base/macros.h"
+#include "base/optional.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom-blink.h"
#include "third_party/blink/public/platform/web_fetch_client_settings_object.h"
#include "third_party/blink/public/platform/web_string.h"
@@ -55,18 +56,20 @@
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/messaging/blink_transferable_message.h"
#include "third_party/blink/renderer/core/messaging/message_port.h"
+#include "third_party/blink/renderer/core/script/script.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_error.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_registration.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/v8_throw_exception.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/resource_fetcher.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h"
+#include "third_party/blink/renderer/platform/weborigin/reporting_disposition.h"
#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
-#include "third_party/blink/renderer/platform/weborigin/security_violation_reporting_policy.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
@@ -77,17 +80,11 @@ void MaybeRecordThirdPartyServiceWorkerUsage(
ExecutionContext* execution_context) {
DCHECK(execution_context);
// ServiceWorkerContainer is only supported on documents.
- Document* document = To<Document>(execution_context);
+ Document* document = Document::From(execution_context);
DCHECK(document);
- // Don't record the use counter if the frame is same-origin to the top frame,
- // or if we can't tell whether the frame was ever cross-origin or not.
- if (!document->TopFrameOrigin() ||
- document->TopFrameOrigin()->CanAccess(document->GetSecurityOrigin())) {
- return;
- }
-
- UseCounter::Count(document, WebFeature::kThirdPartyServiceWorker);
+ if (document->IsCrossSiteSubframe())
+ UseCounter::Count(document, WebFeature::kThirdPartyServiceWorker);
}
bool HasFiredDomContentLoaded(const Document& document) {
@@ -105,15 +102,6 @@ mojom::ServiceWorkerUpdateViaCache ParseUpdateViaCache(const String& value) {
return mojom::ServiceWorkerUpdateViaCache::kImports;
}
-mojom::ScriptType ParseScriptType(const String& type) {
- if (type == "classic")
- return mojom::ScriptType::kClassic;
- if (type == "module")
- return mojom::ScriptType::kModule;
- NOTREACHED() << "Invalid type: " << type;
- return mojom::ScriptType::kClassic;
-}
-
class GetRegistrationCallback : public WebServiceWorkerProvider::
WebServiceWorkerGetRegistrationCallbacks {
public:
@@ -155,7 +143,7 @@ class ServiceWorkerContainer::DomContentLoadedListener final
void Invoke(ExecutionContext* execution_context, Event* event) override {
DCHECK_EQ(event->type(), "DOMContentLoaded");
- Document& document = *To<Document>(execution_context);
+ Document& document = *Document::From(execution_context);
DCHECK(HasFiredDomContentLoaded(document));
auto* container =
@@ -208,7 +196,7 @@ ServiceWorkerContainer::~ServiceWorkerContainer() {
DCHECK(!provider_);
}
-void ServiceWorkerContainer::ContextDestroyed(ExecutionContext*) {
+void ServiceWorkerContainer::ContextDestroyed() {
if (provider_) {
provider_->SetClient(nullptr);
provider_ = nullptr;
@@ -216,7 +204,7 @@ void ServiceWorkerContainer::ContextDestroyed(ExecutionContext*) {
controller_ = nullptr;
}
-void ServiceWorkerContainer::Trace(blink::Visitor* visitor) {
+void ServiceWorkerContainer::Trace(Visitor* visitor) {
visitor->Trace(controller_);
visitor->Trace(ready_);
visitor->Trace(dom_content_loaded_observer_);
@@ -224,7 +212,7 @@ void ServiceWorkerContainer::Trace(blink::Visitor* visitor) {
visitor->Trace(service_worker_objects_);
EventTargetWithInlineData::Trace(visitor);
Supplement<Document>::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
ScriptPromise ServiceWorkerContainer::registerServiceWorker(
@@ -359,20 +347,17 @@ ScriptPromise ServiceWorkerContainer::registerServiceWorker(
mojom::ServiceWorkerUpdateViaCache update_via_cache =
ParseUpdateViaCache(options->updateViaCache());
- mojom::ScriptType type = ParseScriptType(options->type());
+ base::Optional<mojom::ScriptType> script_type =
+ Script::ParseScriptType(options->type());
+ DCHECK(script_type);
WebFetchClientSettingsObject fetch_client_settings_object(
execution_context->Fetcher()
->GetProperties()
.GetFetchClientSettingsObject());
- // The outgoing referrer is a required parameter. Use |script_url| if the
- // ResourceFetcher doesn't provide it.
- if (fetch_client_settings_object.outgoing_referrer.IsEmpty()) {
- fetch_client_settings_object.outgoing_referrer = script_url;
- }
provider_->RegisterServiceWorker(
- scope_url, script_url, type, update_via_cache,
+ scope_url, script_url, *script_type, update_via_cache,
std::move(fetch_client_settings_object), std::move(callbacks));
return promise;
}
@@ -477,17 +462,17 @@ void ServiceWorkerContainer::startMessages() {
EnableClientMessageQueue();
}
-ScriptPromise ServiceWorkerContainer::ready(ScriptState* caller_state) {
+ScriptPromise ServiceWorkerContainer::ready(ScriptState* caller_state,
+ ExceptionState& exception_state) {
if (!GetExecutionContext())
return ScriptPromise();
if (!caller_state->World().IsMainWorld()) {
// FIXME: Support .ready from isolated worlds when
// ScriptPromiseProperty can vend Promises in isolated worlds.
- return ScriptPromise::RejectWithDOMException(
- caller_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotSupportedError,
- "'ready' is only supported in pages."));
+ exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
+ "'ready' is only supported in pages.");
+ return ScriptPromise();
}
if (!ready_) {
@@ -526,7 +511,7 @@ void ServiceWorkerContainer::ReceiveMessage(WebServiceWorkerObjectInfo source,
if (!context || !context->ExecutingWindow())
return;
// ServiceWorkerContainer is only supported on documents.
- auto* document = DynamicTo<Document>(context);
+ auto* document = Document::DynamicFrom(context);
DCHECK(document);
if (!is_client_message_queue_enabled_) {
@@ -570,7 +555,7 @@ void ServiceWorkerContainer::CountFeature(mojom::WebFeature feature) {
}
ExecutionContext* ServiceWorkerContainer::GetExecutionContext() const {
- return GetSupplementable();
+ return GetSupplementable()->ToExecutionContext();
}
const AtomicString& ServiceWorkerContainer::InterfaceName() const {
@@ -603,7 +588,7 @@ ServiceWorkerContainer::GetOrCreateServiceWorkerRegistration(
}
registration = MakeGarbageCollected<ServiceWorkerRegistration>(
- GetSupplementable(), std::move(info));
+ GetSupplementable()->ToExecutionContext(), std::move(info));
service_worker_registration_objects_.Set(info.registration_id, registration);
return registration;
}
@@ -614,19 +599,20 @@ ServiceWorker* ServiceWorkerContainer::GetOrCreateServiceWorker(
return nullptr;
ServiceWorker* worker = service_worker_objects_.at(info.version_id);
if (!worker) {
- worker = ServiceWorker::Create(GetSupplementable(), std::move(info));
+ worker = ServiceWorker::Create(GetSupplementable()->ToExecutionContext(),
+ std::move(info));
service_worker_objects_.Set(info.version_id, worker);
}
return worker;
}
ServiceWorkerContainer::ServiceWorkerContainer(Document* document)
- : Supplement<Document>(*document), ContextLifecycleObserver(document) {}
+ : Supplement<Document>(*document),
+ ExecutionContextLifecycleObserver(document) {}
ServiceWorkerContainer::ReadyProperty*
ServiceWorkerContainer::CreateReadyProperty() {
- return MakeGarbageCollected<ReadyProperty>(GetExecutionContext(), this,
- ReadyProperty::kReady);
+ return MakeGarbageCollected<ReadyProperty>(GetExecutionContext());
}
void ServiceWorkerContainer::EnableClientMessageQueue() {
@@ -694,7 +680,7 @@ void ServiceWorkerContainer::OnGetRegistrationForReady(
!ready_->GetExecutionContext()->IsContextDestroyed()) {
ready_->Resolve(
ServiceWorkerContainer::From(
- To<Document>(ready_->GetExecutionContext()))
+ Document::From(ready_->GetExecutionContext()))
->GetOrCreateServiceWorkerRegistration(std::move(info)));
}
}
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 f31b651320a..2f26ec0405c 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
@@ -38,12 +38,12 @@
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider_client.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_property.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_registration_options.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/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/service_worker/message_from_service_worker.h"
-#include "third_party/blink/renderer/modules/service_worker/registration_options.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_registration.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -54,11 +54,12 @@
namespace blink {
class ExecutionContext;
+class ExceptionState;
class MODULES_EXPORT ServiceWorkerContainer final
: public EventTargetWithInlineData,
public Supplement<Document>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public WebServiceWorkerProviderClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(ServiceWorkerContainer);
@@ -78,10 +79,10 @@ class MODULES_EXPORT ServiceWorkerContainer final
explicit ServiceWorkerContainer(Document*);
~ServiceWorkerContainer() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
ServiceWorker* controller() { return controller_; }
- ScriptPromise ready(ScriptState*);
+ ScriptPromise ready(ScriptState*, ExceptionState&);
ScriptPromise registerServiceWorker(ScriptState*,
const String& pattern,
@@ -91,7 +92,7 @@ class MODULES_EXPORT ServiceWorkerContainer final
void startMessages();
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
// WebServiceWorkerProviderClient implementation.
void SetController(WebServiceWorkerObjectInfo,
@@ -124,8 +125,7 @@ class MODULES_EXPORT ServiceWorkerContainer final
class DomContentLoadedListener;
using ReadyProperty =
- ScriptPromiseProperty<Member<ServiceWorkerContainer>,
- Member<ServiceWorkerRegistration>,
+ ScriptPromiseProperty<Member<ServiceWorkerRegistration>,
Member<ServiceWorkerRegistration>>;
ReadyProperty* CreateReadyProperty();
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.idl b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.idl
index bdd323d0133..857b0d4304b 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.idl
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.idl
@@ -33,9 +33,9 @@
SecureContext
] interface ServiceWorkerContainer : EventTarget {
readonly attribute ServiceWorker? controller;
- [CallWith=ScriptState] readonly attribute Promise<ServiceWorkerRegistration> ready;
+ [CallWith=ScriptState, RaisesException] readonly attribute Promise<ServiceWorkerRegistration> ready;
- [CallWith=ScriptState, ImplementedAs=registerServiceWorker] Promise<ServiceWorkerRegistration> register(USVString url, optional RegistrationOptions options);
+ [CallWith=ScriptState, ImplementedAs=registerServiceWorker] Promise<ServiceWorkerRegistration> register(ScriptURLString url, optional RegistrationOptions options = {});
[CallWith=ScriptState] Promise<ServiceWorkerRegistration> getRegistration(optional USVString documentURL = "");
[CallWith=ScriptState] Promise<sequence<ServiceWorkerRegistration>> getRegistrations();
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 e5b8ac7f8f4..66fa3abd627 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(blink::Visitor* visitor) { visitor->Trace(arg_); }
+ void Trace(Visitor* visitor) { visitor->Trace(arg_); }
private:
size_t call_count_;
@@ -193,8 +193,8 @@ class ServiceWorkerContainerTest : public PageTestBase {
NavigateTo(KURL(NullURL(), url));
if (url.StartsWith("https://") || url.StartsWith("http://localhost/")) {
- GetDocument().SetSecureContextStateForTesting(
- SecureContextState::kSecure);
+ GetDocument().SetSecureContextModeForTesting(
+ SecureContextMode::kSecureContext);
}
}
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_event_queue.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_event_queue.cc
index 7c52d2bdd34..85e31311c63 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_event_queue.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_event_queue.cc
@@ -28,7 +28,6 @@ int NextEventId() {
} // namespace
// static
-constexpr base::TimeDelta ServiceWorkerEventQueue::kIdleDelay;
constexpr base::TimeDelta ServiceWorkerEventQueue::kEventTimeout;
constexpr base::TimeDelta ServiceWorkerEventQueue::kUpdateInterval;
@@ -36,6 +35,7 @@ ServiceWorkerEventQueue::StayAwakeToken::StayAwakeToken(
base::WeakPtr<ServiceWorkerEventQueue> event_queue)
: event_queue_(std::move(event_queue)) {
DCHECK(event_queue_);
+ event_queue_->ResetIdleTimeout();
event_queue_->num_of_stay_awake_tokens_++;
}
@@ -52,14 +52,23 @@ ServiceWorkerEventQueue::StayAwakeToken::~StayAwakeToken() {
}
ServiceWorkerEventQueue::ServiceWorkerEventQueue(
- base::RepeatingClosure idle_callback)
- : ServiceWorkerEventQueue(std::move(idle_callback),
+ BeforeStartEventCallback before_start_event_callback,
+ base::RepeatingClosure idle_callback,
+ scoped_refptr<base::SequencedTaskRunner> task_runner)
+ : ServiceWorkerEventQueue(std::move(before_start_event_callback),
+ std::move(idle_callback),
+ std::move(task_runner),
base::DefaultTickClock::GetInstance()) {}
ServiceWorkerEventQueue::ServiceWorkerEventQueue(
+ BeforeStartEventCallback before_start_event_callback,
base::RepeatingClosure idle_callback,
+ scoped_refptr<base::SequencedTaskRunner> task_runner,
const base::TickClock* tick_clock)
- : idle_callback_(std::move(idle_callback)), tick_clock_(tick_clock) {}
+ : task_runner_(std::move(task_runner)),
+ before_start_event_callback_(std::move(before_start_event_callback)),
+ idle_callback_(std::move(idle_callback)),
+ tick_clock_(tick_clock) {}
ServiceWorkerEventQueue::~ServiceWorkerEventQueue() {
in_dtor_ = true;
@@ -72,9 +81,10 @@ ServiceWorkerEventQueue::~ServiceWorkerEventQueue() {
void ServiceWorkerEventQueue::Start() {
DCHECK(!timer_.IsRunning());
- // |idle_callback_| will be invoked if no event happens in |kIdleDelay|.
- if (!HasInflightEvent() && idle_time_.is_null())
- idle_time_ = tick_clock_->NowTicks() + kIdleDelay;
+ if (!HasInflightEvent() && !HasScheduledIdleCallback()) {
+ // If no event happens until Start(), the idle callback should be scheduled.
+ OnNoInflightEvent();
+ }
timer_.Start(FROM_HERE, kUpdateInterval,
WTF::BindRepeating(&ServiceWorkerEventQueue::UpdateStatus,
WTF::Unretained(this)));
@@ -120,12 +130,11 @@ void ServiceWorkerEventQueue::EnqueueEvent(std::unique_ptr<Event> event) {
bool can_start_processing_events =
!processing_events_ && event->type != Event::Type::Pending;
queue_.emplace_back(std::move(event));
+
if (!can_start_processing_events)
return;
- if (did_idle_timeout()) {
- idle_time_ = base::TimeTicks();
- did_idle_timeout_ = false;
- }
+
+ ResetIdleTimeout();
ProcessEvents();
}
@@ -148,7 +157,6 @@ void ServiceWorkerEventQueue::ProcessEvents() {
void ServiceWorkerEventQueue::StartEvent(std::unique_ptr<Event> event) {
DCHECK(CanStartEvent(*event));
running_offline_events_ = event->type == Event::Type::Offline;
- idle_time_ = base::TimeTicks();
const int event_id = NextEventId();
DCHECK(!HasEvent(event_id));
id_event_map_.insert(
@@ -156,6 +164,8 @@ void ServiceWorkerEventQueue::StartEvent(std::unique_ptr<Event> event) {
tick_clock_->NowTicks() +
event->custom_timeout.value_or(kEventTimeout),
WTF::Bind(std::move(event->abort_callback), event_id)));
+ if (before_start_event_callback_)
+ before_start_event_callback_.Run(event->type == Event::Type::Offline);
std::move(event->start_callback).Run(event_id);
}
@@ -179,10 +189,38 @@ ServiceWorkerEventQueue::CreateStayAwakeToken() {
weak_factory_.GetWeakPtr());
}
-void ServiceWorkerEventQueue::SetIdleTimerDelayToZero() {
- zero_idle_timer_delay_ = true;
- if (!HasInflightEvent())
- MaybeTriggerIdleTimer();
+void ServiceWorkerEventQueue::SetIdleDelay(base::TimeDelta idle_delay) {
+ idle_delay_ = idle_delay;
+
+ if (HasInflightEvent())
+ return;
+
+ if (did_idle_timeout()) {
+ // The idle callback has already been called. It should not be called again
+ // until this worker becomes active.
+ return;
+ }
+
+ // There should be a scheduled idle callback because this is now in the idle
+ // delay. The idle callback will be rescheduled based on the new idle delay.
+ DCHECK(HasScheduledIdleCallback());
+ idle_callback_handle_.Cancel();
+
+ // Calculate the updated time of when the |idle_callback_| should be invoked.
+ DCHECK(!last_no_inflight_event_.is_null());
+ auto new_idle_callback_time = last_no_inflight_event_ + idle_delay;
+ base::TimeDelta delta_until_idle =
+ new_idle_callback_time - tick_clock_->NowTicks();
+
+ if (delta_until_idle <= base::TimeDelta::FromSeconds(0)) {
+ // The new idle delay is shorter than the previous idle delay, and the idle
+ // time has been already passed. Let's run the idle callback immediately.
+ TriggerIdleCallback();
+ return;
+ }
+
+ // Let's schedule the idle callback in |delta_until_idle|.
+ ScheduleIdleCallback(delta_until_idle);
}
void ServiceWorkerEventQueue::UpdateStatus() {
@@ -190,6 +228,7 @@ void ServiceWorkerEventQueue::UpdateStatus() {
HashMap<int /* event_id */, std::unique_ptr<EventInfo>> new_id_event_map;
+ bool should_idle_delay_to_be_zero = false;
// Abort all events exceeding |kEventTimeout|.
for (auto& it : id_event_map_) {
auto& event_info = it.value;
@@ -199,33 +238,41 @@ void ServiceWorkerEventQueue::UpdateStatus() {
}
std::move(event_info->abort_callback)
.Run(blink::mojom::ServiceWorkerEventStatus::TIMEOUT);
- // Shut down the worker as soon as possible since the worker may have gone
- // into bad state.
- zero_idle_timer_delay_ = true;
+ should_idle_delay_to_be_zero = true;
}
id_event_map_.swap(new_id_event_map);
-
- // If the worker is now idle, set the |idle_time_| and possibly trigger the
- // idle callback.
- if (!HasInflightEvent() && idle_time_.is_null()) {
- OnNoInflightEvent();
- return;
+ if (should_idle_delay_to_be_zero) {
+ // Inflight events might be timed out and there might be no inflight event
+ // at this point.
+ if (!HasInflightEvent()) {
+ OnNoInflightEvent();
+ }
+ // Shut down the worker as soon as possible since the worker may have gone
+ // into bad state.
+ SetIdleDelay(base::TimeDelta::FromSeconds(0));
}
+}
- if (!idle_time_.is_null() && idle_time_ < now) {
- did_idle_timeout_ = true;
- idle_callback_.Run();
- }
+void ServiceWorkerEventQueue::ScheduleIdleCallback(base::TimeDelta delay) {
+ DCHECK(!HasInflightEvent());
+ DCHECK(!HasScheduledIdleCallback());
+
+ // WTF::Unretained() is safe because the task runner will be destroyed
+ // before |this| is destroyed at ServiceWorkerGlobalScope::Dispose().
+ idle_callback_handle_ = PostDelayedCancellableTask(
+ *task_runner_, FROM_HERE,
+ WTF::Bind(&ServiceWorkerEventQueue::TriggerIdleCallback,
+ WTF::Unretained(this)),
+ delay);
}
-bool ServiceWorkerEventQueue::MaybeTriggerIdleTimer() {
+void ServiceWorkerEventQueue::TriggerIdleCallback() {
DCHECK(!HasInflightEvent());
- if (!zero_idle_timer_delay_)
- return false;
+ DCHECK(!HasScheduledIdleCallback());
+ DCHECK(!did_idle_timeout_);
did_idle_timeout_ = true;
idle_callback_.Run();
- return true;
}
void ServiceWorkerEventQueue::OnNoInflightEvent() {
@@ -237,14 +284,24 @@ void ServiceWorkerEventQueue::OnNoInflightEvent() {
ProcessEvents();
return;
}
- idle_time_ = tick_clock_->NowTicks() + kIdleDelay;
- MaybeTriggerIdleTimer();
+ last_no_inflight_event_ = tick_clock_->NowTicks();
+ ScheduleIdleCallback(idle_delay_);
}
bool ServiceWorkerEventQueue::HasInflightEvent() const {
return !id_event_map_.IsEmpty() || num_of_stay_awake_tokens_ > 0;
}
+void ServiceWorkerEventQueue::ResetIdleTimeout() {
+ last_no_inflight_event_ = base::TimeTicks();
+ idle_callback_handle_.Cancel();
+ did_idle_timeout_ = false;
+}
+
+bool ServiceWorkerEventQueue::HasScheduledIdleCallback() const {
+ return idle_callback_handle_.IsActive();
+}
+
ServiceWorkerEventQueue::Event::Event(
ServiceWorkerEventQueue::Event::Type type,
StartCallback start_callback,
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 37a556d75a4..2899557c9f2 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
@@ -11,8 +11,10 @@
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
+#include "third_party/blink/public/mojom/service_worker/service_worker.mojom-blink.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom-blink-forward.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
#include "third_party/blink/renderer/platform/wtf/deque.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
@@ -33,12 +35,14 @@ namespace blink {
// 1) Event timeout: when an event starts, StartEvent() records the expiration
// time of the event (kEventTimeout). If EndEvent() has not been called within
// the timeout time, |abort_callback| passed to StartEvent() is called with
-// status TIMEOUT. Also, |zero_idle_timer_delay_| is set to true to shut down
+// status TIMEOUT. Additionally, the |idle_delay_| is set to zero to shut down
// the worker as soon as possible since the worker may have gone into bad state.
-// 2) Idle timeout: when a certain time has passed (kIdleDelay) since all of
-// events have ended, ServiceWorkerEventQueue calls the |idle_callback|.
-// |idle_callback| will be continuously called at a certain interval
-// (kUpdateInterval) until the next event starts.
+// 2) Idle timeout: when a certain time has passed (|idle_delay_|) since all of
+// events have ended, ServiceWorkerEventQueue calls the |idle_callback_|.
+// Idle callbacks are called on the |task_runner| passed by the constructor.
+// Note that the implementation assumes the task runner is provided by
+// ServiceWorkerGlobalScope, and the lifetime of the task runner is shorter than
+// |this|.
//
// The lifetime of ServiceWorkerEventQueue is the same with the worker
// thread. If ServiceWorkerEventQueue is destructed while there are inflight
@@ -60,9 +64,16 @@ class MODULES_EXPORT ServiceWorkerEventQueue {
base::OnceCallback<void(int /* event_id */,
mojom::blink::ServiceWorkerEventStatus)>;
- explicit ServiceWorkerEventQueue(base::RepeatingClosure idle_callback);
+ using BeforeStartEventCallback =
+ base::RepeatingCallback<void(/*is_offline_event=*/bool)>;
+
+ ServiceWorkerEventQueue(BeforeStartEventCallback before_start_event_callback,
+ base::RepeatingClosure idle_callback,
+ scoped_refptr<base::SequencedTaskRunner> task_runner);
// For testing.
- ServiceWorkerEventQueue(base::RepeatingClosure idle_callback,
+ ServiceWorkerEventQueue(BeforeStartEventCallback before_start_event_callback,
+ base::RepeatingClosure idle_callback,
+ scoped_refptr<base::SequencedTaskRunner> task_runner,
const base::TickClock* tick_clock);
~ServiceWorkerEventQueue();
@@ -96,23 +107,19 @@ class MODULES_EXPORT ServiceWorkerEventQueue {
// Returns true if |event_id| was started and hasn't ended.
bool HasEvent(int event_id) const;
- // Creates a StayAwakeToken to ensure that the idle timer won't be triggered
- // while any of these are alive.
+ // Creates a StayAwakeToken to ensure that the idle callback won't be
+ // triggered while any of these are alive.
std::unique_ptr<StayAwakeToken> CreateStayAwakeToken();
- // Sets the |zero_idle_timer_delay_| to true and triggers the idle callback if
- // there are not inflight events. If there are, the callback will be called
- // next time when the set of inflight events becomes empty in EndEvent().
- void SetIdleTimerDelayToZero();
+ // Sets the |idle_delay_| to the new value, and re-schedule the idle callback
+ // based on the new delay if it's now pending.
+ void SetIdleDelay(base::TimeDelta idle_delay);
- // Returns true if the timer thinks no events ran for a while, and has
- // triggered the |idle_callback| passed to the constructor. It'll be reset to
+ // Returns true if the event queue thinks no events ran for a while, and has
+ // triggered the |idle_callback_| passed to the constructor. It'll be reset to
// false again when StartEvent() is called.
bool did_idle_timeout() const { return did_idle_timeout_; }
- // Idle timeout duration since the last event has finished.
- static constexpr base::TimeDelta kIdleDelay =
- base::TimeDelta::FromSeconds(30);
// Duration of the long standing event timeout since StartEvent() has been
// called.
static constexpr base::TimeDelta kEventTimeout =
@@ -171,12 +178,15 @@ class MODULES_EXPORT ServiceWorkerEventQueue {
// Starts a single event.
void StartEvent(std::unique_ptr<Event> event);
- // Updates the internal states and fires timeout callbacks if any.
+ // Updates the internal states and fires the event timeout callbacks if any.
+ // TODO(shimazu): re-implement it by delayed tasks and cancelable callbacks.
void UpdateStatus();
- // Triggers idle timer if |zero_idle_timer_delay_| is true. Returns true if
- // the idle callback is called.
- bool MaybeTriggerIdleTimer();
+ // Schedules the idle callback in |delay|.
+ void ScheduleIdleCallback(base::TimeDelta delay);
+
+ // Runs the idle callback and updates the state accordingly.
+ void TriggerIdleCallback();
// Sets the |idle_time_| and maybe calls |idle_callback_| immediately if the
// timeout delay is set to zero.
@@ -188,6 +198,12 @@ class MODULES_EXPORT ServiceWorkerEventQueue {
// Processes all events in |queue_|.
void ProcessEvents();
+ // Resets the members for idle timeouts to cancel the idle callback.
+ void ResetIdleTimeout();
+
+ // True if the idle callback is scheduled to run.
+ bool HasScheduledIdleCallback() const;
+
struct EventInfo {
EventInfo(base::TimeTicks expiration_time,
base::OnceCallback<void(mojom::blink::ServiceWorkerEventStatus)>
@@ -198,22 +214,32 @@ class MODULES_EXPORT ServiceWorkerEventQueue {
abort_callback;
};
+ scoped_refptr<base::SequencedTaskRunner> task_runner_;
+
// For long standing event timeouts. This is used to look up an EventInfo
// by event id.
HashMap<int /* event_id */, std::unique_ptr<EventInfo>> id_event_map_;
- // For idle timeouts. The time the service worker started being considered
- // idle. This time is null if there are any inflight events.
- base::TimeTicks idle_time_;
-
- // Set to true if the idle callback should be fired immediately after all
- // inflight events finish.
- bool zero_idle_timer_delay_ = false;
+ // Callback which is run just before starting an event.
+ BeforeStartEventCallback before_start_event_callback_;
- // For idle timeouts. Invoked when UpdateStatus() is called after
- // |idle_time_|.
+ // For idle timeouts. When there's no inflight event, this is scheduled to run
+ // in |idle_delay_|.
base::RepeatingClosure idle_callback_;
+ // For idle timeouts. The handle of the scheduled |idle_callback_|. This can
+ // be canceled when a new event happens before the scheduled callback runs.
+ TaskHandle idle_callback_handle_;
+
+ // For idle timeouts. The time when there's no inflight event. Set to null if
+ // there are inflight events.
+ base::TimeTicks last_no_inflight_event_;
+
+ // For idle timeouts. The delay until the worker is identified as idle after
+ // all inflight events are completed.
+ base::TimeDelta idle_delay_ = base::TimeDelta::FromSeconds(
+ mojom::blink::kServiceWorkerDefaultIdleDelayInSeconds);
+
// Set to true once |idle_callback_| has been invoked. Set to false when
// StartEvent() is called.
bool did_idle_timeout_ = false;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_event_queue_test.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_event_queue_test.cc
index a32e5882797..fafe57a7c5c 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_event_queue_test.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_event_queue_test.cc
@@ -128,14 +128,13 @@ class ServiceWorkerEventQueueTest : public testing::Test {
};
TEST_F(ServiceWorkerEventQueueTest, IdleTimer) {
- const base::TimeDelta kIdleInterval =
- ServiceWorkerEventQueue::kIdleDelay +
- ServiceWorkerEventQueue::kUpdateInterval +
- base::TimeDelta::FromSeconds(1);
+ const base::TimeDelta kIdleInterval = base::TimeDelta::FromSeconds(
+ mojom::blink::kServiceWorkerDefaultIdleDelayInSeconds);
bool is_idle = false;
- ServiceWorkerEventQueue event_queue(CreateReceiverWithCalledFlag(&is_idle),
- task_runner()->GetMockTickClock());
+ ServiceWorkerEventQueue event_queue(
+ base::NullCallback(), CreateReceiverWithCalledFlag(&is_idle),
+ task_runner(), task_runner()->GetMockTickClock());
task_runner()->FastForwardBy(kIdleInterval);
// Nothing should happen since the event queue has not started yet.
EXPECT_FALSE(is_idle);
@@ -190,14 +189,13 @@ TEST_F(ServiceWorkerEventQueueTest, IdleTimer) {
}
TEST_F(ServiceWorkerEventQueueTest, InflightEventBeforeStart) {
- const base::TimeDelta kIdleInterval =
- ServiceWorkerEventQueue::kIdleDelay +
- ServiceWorkerEventQueue::kUpdateInterval +
- base::TimeDelta::FromSeconds(1);
+ const base::TimeDelta kIdleInterval = base::TimeDelta::FromSeconds(
+ mojom::blink::kServiceWorkerDefaultIdleDelayInSeconds);
bool is_idle = false;
- ServiceWorkerEventQueue event_queue(CreateReceiverWithCalledFlag(&is_idle),
- task_runner()->GetMockTickClock());
+ ServiceWorkerEventQueue event_queue(
+ base::DoNothing(), CreateReceiverWithCalledFlag(&is_idle), task_runner(),
+ task_runner()->GetMockTickClock());
MockEvent event;
event.EnqueueTo(&event_queue);
event_queue.Start();
@@ -218,8 +216,9 @@ TEST_F(ServiceWorkerEventQueueTest, InflightEventBeforeStart) {
// In the first UpdateStatus() the idle callback should be triggered.
TEST_F(ServiceWorkerEventQueueTest, EventFinishedBeforeStart) {
bool is_idle = false;
- ServiceWorkerEventQueue event_queue(CreateReceiverWithCalledFlag(&is_idle),
- task_runner()->GetMockTickClock());
+ ServiceWorkerEventQueue event_queue(
+ base::DoNothing(), CreateReceiverWithCalledFlag(&is_idle), task_runner(),
+ task_runner()->GetMockTickClock());
// Start and finish an event before starting the timer.
MockEvent event;
event.EnqueueTo(&event_queue);
@@ -228,21 +227,23 @@ TEST_F(ServiceWorkerEventQueueTest, EventFinishedBeforeStart) {
// Move the time ticks to almost before |idle_time_| so that |idle_callback|
// will get called at the first update check.
- task_runner()->FastForwardBy(ServiceWorkerEventQueue::kIdleDelay -
- base::TimeDelta::FromSeconds(1));
+ task_runner()->FastForwardBy(
+ base::TimeDelta::FromSeconds(
+ mojom::blink::kServiceWorkerDefaultIdleDelayInSeconds) -
+ base::TimeDelta::FromSeconds(1));
event_queue.Start();
// Make sure the timer calls UpdateStatus().
- task_runner()->FastForwardBy(ServiceWorkerEventQueue::kUpdateInterval +
- base::TimeDelta::FromSeconds(1));
+ task_runner()->FastForwardBy(base::TimeDelta::FromSeconds(1));
// |idle_callback| should be fired because enough time passed since the last
// event.
EXPECT_TRUE(is_idle);
}
TEST_F(ServiceWorkerEventQueueTest, EventTimer) {
- ServiceWorkerEventQueue event_queue(base::DoNothing(),
+ ServiceWorkerEventQueue event_queue(base::DoNothing(), base::DoNothing(),
+ task_runner(),
task_runner()->GetMockTickClock());
event_queue.Start();
@@ -265,7 +266,8 @@ TEST_F(ServiceWorkerEventQueueTest, EventTimer) {
}
TEST_F(ServiceWorkerEventQueueTest, CustomTimeouts) {
- ServiceWorkerEventQueue event_queue(base::DoNothing(),
+ ServiceWorkerEventQueue event_queue(base::DoNothing(), base::DoNothing(),
+ task_runner(),
task_runner()->GetMockTickClock());
event_queue.Start();
MockEvent event1, event2;
@@ -293,8 +295,9 @@ TEST_F(ServiceWorkerEventQueueTest, CustomTimeouts) {
TEST_F(ServiceWorkerEventQueueTest, BecomeIdleAfterAbort) {
bool is_idle = false;
- ServiceWorkerEventQueue event_queue(CreateReceiverWithCalledFlag(&is_idle),
- task_runner()->GetMockTickClock());
+ ServiceWorkerEventQueue event_queue(
+ base::DoNothing(), CreateReceiverWithCalledFlag(&is_idle), task_runner(),
+ task_runner()->GetMockTickClock());
event_queue.Start();
MockEvent event;
@@ -312,7 +315,8 @@ TEST_F(ServiceWorkerEventQueueTest, BecomeIdleAfterAbort) {
TEST_F(ServiceWorkerEventQueueTest, AbortAllOnDestruction) {
MockEvent event1, event2;
{
- ServiceWorkerEventQueue event_queue(base::DoNothing(),
+ ServiceWorkerEventQueue event_queue(base::DoNothing(), base::DoNothing(),
+ task_runner(),
task_runner()->GetMockTickClock());
event_queue.Start();
@@ -335,12 +339,12 @@ TEST_F(ServiceWorkerEventQueueTest, AbortAllOnDestruction) {
}
TEST_F(ServiceWorkerEventQueueTest, PushPendingTask) {
- ServiceWorkerEventQueue event_queue(base::DoNothing(),
+ ServiceWorkerEventQueue event_queue(base::DoNothing(), base::DoNothing(),
+ task_runner(),
task_runner()->GetMockTickClock());
event_queue.Start();
- task_runner()->FastForwardBy(ServiceWorkerEventQueue::kIdleDelay +
- ServiceWorkerEventQueue::kUpdateInterval +
- base::TimeDelta::FromSeconds(1));
+ task_runner()->FastForwardBy(base::TimeDelta::FromSeconds(
+ mojom::blink::kServiceWorkerDefaultIdleDelayInSeconds));
EXPECT_TRUE(event_queue.did_idle_timeout());
MockEvent pending_event;
@@ -357,10 +361,12 @@ TEST_F(ServiceWorkerEventQueueTest, PushPendingTask) {
// Test that pending tasks are run when StartEvent() is called while there the
// idle event_queue.delay is zero. Regression test for https://crbug.com/878608.
TEST_F(ServiceWorkerEventQueueTest, RunPendingTasksWithZeroIdleTimerDelay) {
- ServiceWorkerEventQueue event_queue(base::DoNothing(),
+ ServiceWorkerEventQueue event_queue(base::DoNothing(), base::DoNothing(),
+ task_runner(),
task_runner()->GetMockTickClock());
event_queue.Start();
- event_queue.SetIdleTimerDelayToZero();
+ event_queue.SetIdleDelay(base::TimeDelta::FromSeconds(0));
+ task_runner()->RunUntilIdle();
EXPECT_TRUE(event_queue.did_idle_timeout());
MockEvent event1, event2;
@@ -384,49 +390,58 @@ TEST_F(ServiceWorkerEventQueueTest, RunPendingTasksWithZeroIdleTimerDelay) {
TEST_F(ServiceWorkerEventQueueTest, SetIdleTimerDelayToZero) {
{
bool is_idle = false;
- ServiceWorkerEventQueue event_queue(CreateReceiverWithCalledFlag(&is_idle),
- task_runner()->GetMockTickClock());
+ ServiceWorkerEventQueue event_queue(
+ base::DoNothing(), CreateReceiverWithCalledFlag(&is_idle),
+ task_runner(), task_runner()->GetMockTickClock());
event_queue.Start();
EXPECT_FALSE(is_idle);
- event_queue.SetIdleTimerDelayToZero();
+ event_queue.SetIdleDelay(base::TimeDelta::FromSeconds(0));
+ task_runner()->RunUntilIdle();
// |idle_callback| should be fired since there is no event.
EXPECT_TRUE(is_idle);
}
{
bool is_idle = false;
- ServiceWorkerEventQueue event_queue(CreateReceiverWithCalledFlag(&is_idle),
- task_runner()->GetMockTickClock());
+ ServiceWorkerEventQueue event_queue(
+ base::DoNothing(), CreateReceiverWithCalledFlag(&is_idle),
+ task_runner(), task_runner()->GetMockTickClock());
event_queue.Start();
MockEvent event;
event.EnqueueTo(&event_queue);
- event_queue.SetIdleTimerDelayToZero();
+ event_queue.SetIdleDelay(base::TimeDelta::FromSeconds(0));
+ task_runner()->RunUntilIdle();
// Nothing happens since there is an inflight event.
EXPECT_FALSE(is_idle);
event_queue.EndEvent(event.event_id());
+ task_runner()->RunUntilIdle();
// EndEvent() immediately triggers the idle callback.
EXPECT_TRUE(is_idle);
}
{
bool is_idle = false;
- ServiceWorkerEventQueue event_queue(CreateReceiverWithCalledFlag(&is_idle),
- task_runner()->GetMockTickClock());
+ ServiceWorkerEventQueue event_queue(
+ base::DoNothing(), CreateReceiverWithCalledFlag(&is_idle),
+ task_runner(), task_runner()->GetMockTickClock());
event_queue.Start();
MockEvent event1, event2;
event1.EnqueueTo(&event_queue);
event2.EnqueueTo(&event_queue);
- event_queue.SetIdleTimerDelayToZero();
+ event_queue.SetIdleDelay(base::TimeDelta::FromSeconds(0));
+ task_runner()->RunUntilIdle();
// Nothing happens since there are two inflight events.
EXPECT_FALSE(is_idle);
event_queue.EndEvent(event1.event_id());
+ task_runner()->RunUntilIdle();
// Nothing happens since there is an inflight event.
EXPECT_FALSE(is_idle);
event_queue.EndEvent(event2.event_id());
+ task_runner()->RunUntilIdle();
// EndEvent() immediately triggers the idle callback when no inflight events
// exist.
EXPECT_TRUE(is_idle);
@@ -434,29 +449,34 @@ TEST_F(ServiceWorkerEventQueueTest, SetIdleTimerDelayToZero) {
{
bool is_idle = false;
- ServiceWorkerEventQueue event_queue(CreateReceiverWithCalledFlag(&is_idle),
- task_runner()->GetMockTickClock());
+ ServiceWorkerEventQueue event_queue(
+ base::DoNothing(), CreateReceiverWithCalledFlag(&is_idle),
+ task_runner(), task_runner()->GetMockTickClock());
event_queue.Start();
std::unique_ptr<StayAwakeToken> token_1 =
event_queue.CreateStayAwakeToken();
std::unique_ptr<StayAwakeToken> token_2 =
event_queue.CreateStayAwakeToken();
- event_queue.SetIdleTimerDelayToZero();
+ event_queue.SetIdleDelay(base::TimeDelta::FromSeconds(0));
+ task_runner()->RunUntilIdle();
// Nothing happens since there are two living tokens.
EXPECT_FALSE(is_idle);
token_1.reset();
+ task_runner()->RunUntilIdle();
// Nothing happens since there is an living token.
EXPECT_FALSE(is_idle);
token_2.reset();
+ task_runner()->RunUntilIdle();
// EndEvent() immediately triggers the idle callback when no tokens exist.
EXPECT_TRUE(is_idle);
}
}
TEST_F(ServiceWorkerEventQueueTest, EnqueuOffline) {
- ServiceWorkerEventQueue event_queue(base::DoNothing(),
+ ServiceWorkerEventQueue event_queue(base::DoNothing(), base::DoNothing(),
+ task_runner(),
task_runner()->GetMockTickClock());
event_queue.Start();
@@ -544,14 +564,13 @@ TEST_F(ServiceWorkerEventQueueTest, EnqueuOffline) {
}
TEST_F(ServiceWorkerEventQueueTest, IdleTimerWithOfflineEvents) {
- const base::TimeDelta kIdleInterval =
- ServiceWorkerEventQueue::kIdleDelay +
- ServiceWorkerEventQueue::kUpdateInterval +
- base::TimeDelta::FromSeconds(1);
+ const base::TimeDelta kIdleInterval = base::TimeDelta::FromSeconds(
+ mojom::blink::kServiceWorkerDefaultIdleDelayInSeconds);
bool is_idle = false;
- ServiceWorkerEventQueue event_queue(CreateReceiverWithCalledFlag(&is_idle),
- task_runner()->GetMockTickClock());
+ ServiceWorkerEventQueue event_queue(
+ base::DoNothing(), CreateReceiverWithCalledFlag(&is_idle), task_runner(),
+ task_runner()->GetMockTickClock());
event_queue.Start();
MockEvent event1;
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 be46d139284..4de7a718252 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
@@ -33,22 +33,31 @@
#include <memory>
#include <utility>
+#include "base/bind_helpers.h"
#include "base/feature_list.h"
#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_functions.h"
#include "base/numerics/safe_conversions.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"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/appcache/appcache.mojom-blink.h"
#include "third_party/blink/public/mojom/timing/worker_timing_container.mojom-blink.h"
+#include "third_party/blink/public/mojom/worker/subresource_loader_updater.mojom.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_fetch_context.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_url.h"
#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/source_location.h"
-#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script_url.h"
#include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_background_fetch_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_content_index_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_notification_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_request_event_init.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/fetch/global_fetch.h"
@@ -66,30 +75,27 @@
#include "third_party/blink/renderer/core/workers/worker_clients.h"
#include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_event.h"
-#include "third_party/blink/renderer/modules/background_fetch/background_fetch_event_init.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.h"
#include "third_party/blink/renderer/modules/background_sync/periodic_sync_event.h"
#include "third_party/blink/renderer/modules/background_sync/sync_event.h"
#include "third_party/blink/renderer/modules/content_index/content_index_event.h"
-#include "third_party/blink/renderer/modules/content_index/content_index_event_init.h"
#include "third_party/blink/renderer/modules/cookie_store/cookie_change_event.h"
#include "third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/notifications/notification.h"
#include "third_party/blink/renderer/modules/notifications/notification_event.h"
-#include "third_party/blink/renderer/modules/notifications/notification_event_init.h"
#include "third_party/blink/renderer/modules/payments/abort_payment_event.h"
#include "third_party/blink/renderer/modules/payments/abort_payment_respond_with_observer.h"
#include "third_party/blink/renderer/modules/payments/can_make_payment_event.h"
#include "third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.h"
#include "third_party/blink/renderer/modules/payments/payment_event_data_conversion.h"
#include "third_party/blink/renderer/modules/payments/payment_request_event.h"
-#include "third_party/blink/renderer/modules/payments/payment_request_event_init.h"
#include "third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.h"
#include "third_party/blink/renderer/modules/push_messaging/push_event.h"
#include "third_party/blink/renderer/modules/push_messaging/push_message_data.h"
#include "third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.h"
+#include "third_party/blink/renderer/modules/service_worker/cross_origin_resource_policy_checker.h"
#include "third_party/blink/renderer/modules/service_worker/extendable_event.h"
#include "third_party/blink/renderer/modules/service_worker/extendable_message_event.h"
#include "third_party/blink/renderer/modules/service_worker/fetch_event.h"
@@ -108,7 +114,7 @@
#include "third_party/blink/renderer/modules/service_worker/wait_until_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h"
#include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
@@ -185,9 +191,6 @@ ServiceWorkerGlobalScope* ServiceWorkerGlobalScope::Create(
installed_scripts_manager,
mojo::PendingRemote<mojom::blink::CacheStorage> cache_storage_remote,
base::TimeTicks time_origin) {
- DCHECK_EQ(creation_params->off_main_thread_fetch_option,
- OffMainThreadWorkerScriptFetchOption::kEnabled);
-
#if DCHECK_IS_ON()
// If the script is being loaded via script streaming, the script is not yet
// loaded.
@@ -217,10 +220,21 @@ ServiceWorkerGlobalScope::ServiceWorkerGlobalScope(
: WorkerGlobalScope(std::move(creation_params), thread, time_origin),
installed_scripts_manager_(std::move(installed_scripts_manager)),
cache_storage_remote_(std::move(cache_storage_remote)) {
- // Create the event queue. At this point the timer is not started. It will be
+ // Create the event queue. At this point its timer is not started. It will be
// started by DidEvaluateScript().
- event_queue_ = std::make_unique<ServiceWorkerEventQueue>(WTF::BindRepeating(
- &ServiceWorkerGlobalScope::OnIdleTimeout, WrapWeakPersistent(this)));
+ //
+ // We are using TaskType::kInternalDefault for the idle callback, and it can
+ // be paused or throttled. This should work for now because we don't throttle
+ // or pause service worker threads, while it may cause not calling idle
+ // callback. We need to revisit this once we want to implement pausing
+ // service workers, but basically that won't be big problem because we have
+ // ping-pong timer and that will kill paused service workers.
+ event_queue_ = std::make_unique<ServiceWorkerEventQueue>(
+ WTF::BindRepeating(&ServiceWorkerGlobalScope::OnBeforeStartEvent,
+ WrapWeakPersistent(this)),
+ WTF::BindRepeating(&ServiceWorkerGlobalScope::OnIdleTimeout,
+ WrapWeakPersistent(this)),
+ GetTaskRunner(TaskType::kInternalDefault));
}
ServiceWorkerGlobalScope::~ServiceWorkerGlobalScope() = default;
@@ -249,7 +263,8 @@ void ServiceWorkerGlobalScope::FetchAndRunClassicScript(
// "classic: Fetch a classic worker script given job's serialized script url,
// job's client, "serviceworker", and the to-be-created environment settings
// object for this service worker."
- auto destination = mojom::RequestContextType::SERVICE_WORKER;
+ auto context_type = mojom::RequestContextType::SERVICE_WORKER;
+ auto destination = network::mojom::RequestDestination::kServiceWorker;
// "To perform the fetch given request, run the following steps:"
// Step 9.1. "Append `Service-Worker`/`script` to request's header list."
@@ -274,7 +289,8 @@ void ServiceWorkerGlobalScope::FetchAndRunClassicScript(
*this,
CreateOutsideSettingsFetcher(outside_settings_object,
outside_resource_timing_notifier),
- script_url, destination, network::mojom::RequestMode::kSameOrigin,
+ script_url, context_type, destination,
+ network::mojom::RequestMode::kSameOrigin,
network::mojom::CredentialsMode::kSameOrigin,
WTF::Bind(&ServiceWorkerGlobalScope::DidReceiveResponseForClassicScript,
WrapWeakPersistent(this),
@@ -288,17 +304,19 @@ void ServiceWorkerGlobalScope::FetchAndRunModuleScript(
const KURL& module_url_record,
const FetchClientSettingsObjectSnapshot& outside_settings_object,
WorkerResourceTimingNotifier& outside_resource_timing_notifier,
- network::mojom::CredentialsMode credentials_mode) {
+ network::mojom::CredentialsMode credentials_mode,
+ RejectCoepUnsafeNone reject_coep_unsafe_none) {
DCHECK(IsContextThread());
-
+ DCHECK(!reject_coep_unsafe_none);
ModuleScriptCustomFetchType fetch_type =
installed_scripts_manager_
? ModuleScriptCustomFetchType::kInstalledServiceWorker
: ModuleScriptCustomFetchType::kWorkerConstructor;
FetchModuleScript(module_url_record, outside_settings_object,
outside_resource_timing_notifier,
- mojom::RequestContextType::SERVICE_WORKER, credentials_mode,
- fetch_type,
+ mojom::RequestContextType::SERVICE_WORKER,
+ network::mojom::RequestDestination::kServiceWorker,
+ credentials_mode, fetch_type,
MakeGarbageCollected<ServiceWorkerModuleTreeClient>(
ScriptController()->GetScriptState()));
}
@@ -320,18 +338,16 @@ ServiceWorkerGlobalScope::GetInstalledScriptsManager() {
void ServiceWorkerGlobalScope::CountWorkerScript(size_t script_size,
size_t cached_metadata_size) {
DCHECK_EQ(GetScriptType(), mojom::ScriptType::kClassic);
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, script_size_histogram,
- ("ServiceWorker.ScriptSize", 1000, 5000000, 50));
- script_size_histogram.Count(
- base::saturated_cast<base::Histogram::Sample>(script_size));
+ base::UmaHistogramCustomCounts(
+ "ServiceWorker.ScriptSize",
+ base::saturated_cast<base::Histogram::Sample>(script_size), 1000, 5000000,
+ 50);
if (cached_metadata_size) {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, script_cached_metadata_size_histogram,
- ("ServiceWorker.ScriptCachedMetadataSize", 1000, 50000000, 50));
- script_cached_metadata_size_histogram.Count(
- base::saturated_cast<base::Histogram::Sample>(cached_metadata_size));
+ base::UmaHistogramCustomCounts(
+ "ServiceWorker.ScriptCachedMetadataSize",
+ base::saturated_cast<base::Histogram::Sample>(cached_metadata_size),
+ 1000, 50000000, 50);
}
CountScriptInternal(script_size, cached_metadata_size);
@@ -359,22 +375,19 @@ void ServiceWorkerGlobalScope::DidEvaluateScript() {
// TODO(asamidoi,nhiroki): Record the UMAs for module scripts, or remove them
// if they're no longer used.
- DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, script_count_histogram,
- ("ServiceWorker.ScriptCount", 1, 1000, 50));
- script_count_histogram.Count(
+ base::UmaHistogramCounts1000(
+ "ServiceWorker.ScriptCount",
base::saturated_cast<base::Histogram::Sample>(script_count_));
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, script_total_size_histogram,
- ("ServiceWorker.ScriptTotalSize", 1000, 5000000, 50));
- script_total_size_histogram.Count(
- base::saturated_cast<base::Histogram::Sample>(script_total_size_));
+ base::UmaHistogramCustomCounts(
+ "ServiceWorker.ScriptTotalSize",
+ base::saturated_cast<base::Histogram::Sample>(script_total_size_), 1000,
+ 5000000, 50);
if (script_cached_metadata_total_size_) {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, cached_metadata_histogram,
- ("ServiceWorker.ScriptCachedMetadataTotalSize", 1000, 50000000, 50));
- cached_metadata_histogram.Count(
+ base::UmaHistogramCustomCounts(
+ "ServiceWorker.ScriptCachedMetadataTotalSize",
base::saturated_cast<base::Histogram::Sample>(
- script_cached_metadata_total_size_));
+ script_cached_metadata_total_size_),
+ 1000, 50000000, 50);
}
}
@@ -463,7 +476,7 @@ void ServiceWorkerGlobalScope::Initialize(
SetReferrerPolicy(response_referrer_policy);
// https://wicg.github.io/cors-rfc1918/#integration-html
- SetAddressSpace(response_address_space);
+ GetSecurityContext().SetAddressSpace(response_address_space);
// This is quoted from the "Content Security Policy" algorithm in the service
// workers spec:
@@ -615,8 +628,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),
- network::mojom::blink::CrossOriginEmbedderPolicy::kNone,
+ this, std::move(receiver), /*context=*/nullptr,
GetThread()->GetTaskRunner(TaskType::kInternalDefault));
}
@@ -646,7 +658,7 @@ void ServiceWorkerGlobalScope::OnNavigationPreloadError(
? error->message
: error->unsanitized_message;
if (!error_message.IsEmpty()) {
- AddConsoleMessage(ConsoleMessage::Create(
+ AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kWorker,
mojom::ConsoleMessageLevel::kError, error_message));
}
@@ -695,9 +707,9 @@ bool ServiceWorkerGlobalScope::AddEventListenerInternal(
"Event handler of '%s' event must be added on the initial evaluation "
"of worker script.",
event_type.Utf8().c_str());
- AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning, message));
+ AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning, message));
}
return WorkerGlobalScope::AddEventListenerInternal(event_type, listener,
options);
@@ -758,7 +770,7 @@ void ServiceWorkerGlobalScope::DispatchExtendableEventWithRespondWith(
wait_until_observer->DidDispatchEvent(false /* event_dispatch_failed */);
}
-void ServiceWorkerGlobalScope::Trace(blink::Visitor* visitor) {
+void ServiceWorkerGlobalScope::Trace(Visitor* visitor) {
visitor->Trace(clients_);
visitor->Trace(registration_);
visitor->Trace(service_worker_);
@@ -773,14 +785,9 @@ bool ServiceWorkerGlobalScope::HasRelatedFetchEvent(
return it != unresponded_fetch_event_counts_.end();
}
-void ServiceWorkerGlobalScope::importScripts(
- const HeapVector<StringOrTrustedScriptURL>& urls,
- ExceptionState& exception_state) {
- for (const StringOrTrustedScriptURL& stringOrUrl : urls) {
- String string_url = stringOrUrl.IsString()
- ? stringOrUrl.GetAsString()
- : stringOrUrl.GetAsTrustedScriptURL()->toString();
-
+void ServiceWorkerGlobalScope::importScripts(const Vector<String>& urls,
+ ExceptionState& exception_state) {
+ for (const String& string_url : urls) {
KURL completed_url = CompleteURL(string_url);
if (installed_scripts_manager_ &&
!installed_scripts_manager_->IsScriptInstalled(completed_url)) {
@@ -800,8 +807,8 @@ SingleCachedMetadataHandler*
ServiceWorkerGlobalScope::CreateWorkerScriptCachedMetadataHandler(
const KURL& script_url,
std::unique_ptr<Vector<uint8_t>> meta_data) {
- return ServiceWorkerScriptCachedMetadataHandler::Create(this, script_url,
- std::move(meta_data));
+ return MakeGarbageCollected<ServiceWorkerScriptCachedMetadataHandler>(
+ this, script_url, std::move(meta_data));
}
ScriptPromise ServiceWorkerGlobalScope::fetch(ScriptState* script_state,
@@ -825,20 +832,16 @@ void ServiceWorkerGlobalScope::CountCacheStorageInstalledScript(
cache_storage_installed_script_total_size_ += script_size;
cache_storage_installed_script_metadata_total_size_ += script_metadata_size;
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, script_size_histogram,
- ("ServiceWorker.CacheStorageInstalledScript.ScriptSize", 1000, 5000000,
- 50));
- script_size_histogram.Count(
- base::saturated_cast<base::Histogram::Sample>(script_size));
+ base::UmaHistogramCustomCounts(
+ "ServiceWorker.CacheStorageInstalledScript.ScriptSize",
+ base::saturated_cast<base::Histogram::Sample>(script_size), 1000, 5000000,
+ 50);
if (script_metadata_size) {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, script_metadata_size_histogram,
- ("ServiceWorker.CacheStorageInstalledScript.CachedMetadataSize", 1000,
- 50000000, 50));
- script_metadata_size_histogram.Count(
- base::saturated_cast<base::Histogram::Sample>(script_metadata_size));
+ base::UmaHistogramCustomCounts(
+ "ServiceWorker.CacheStorageInstalledScript.CachedMetadataSize",
+ base::saturated_cast<base::Histogram::Sample>(script_metadata_size),
+ 1000, 50000000, 50);
}
}
@@ -855,8 +858,7 @@ void ServiceWorkerGlobalScope::DidHandleInstallEvent(
TRACE_ID_LOCAL(install_event_id)),
TRACE_EVENT_FLAG_FLOW_IN, "status", MojoEnumToString(status));
RunEventCallback(&install_event_callbacks_, event_queue_.get(),
- install_event_id, status,
- HasEventListeners(event_type_names::kFetch));
+ install_event_id, status);
}
void ServiceWorkerGlobalScope::DidHandleActivateEvent(
@@ -1156,7 +1158,7 @@ void ServiceWorkerGlobalScope::DidHandleAbortPaymentEvent(
void ServiceWorkerGlobalScope::RespondToCanMakePaymentEvent(
int event_id,
- bool can_make_payment) {
+ payments::mojom::blink::CanMakePaymentResponsePtr response) {
DCHECK(IsContextThread());
TRACE_EVENT_WITH_FLOW0(
"ServiceWorker", "ServiceWorkerGlobalScope::RespondToCanMakePaymentEvent",
@@ -1166,7 +1168,7 @@ void ServiceWorkerGlobalScope::RespondToCanMakePaymentEvent(
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);
- result_callback->OnResponseForCanMakePayment(can_make_payment);
+ result_callback->OnResponseForCanMakePayment(std::move(response));
}
void ServiceWorkerGlobalScope::DidHandleCanMakePaymentEvent(
@@ -1247,29 +1249,22 @@ void ServiceWorkerGlobalScope::SetIsInstalling(bool is_installing) {
// Installing phase is finished; record the stats for the scripts that are
// stored in Cache storage during installation.
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, cache_storage_installed_script_count_histogram,
- ("ServiceWorker.CacheStorageInstalledScript.Count", 1, 1000, 50));
- cache_storage_installed_script_count_histogram.Count(
+ base::UmaHistogramCounts1000(
+ "ServiceWorker.CacheStorageInstalledScript.Count",
base::saturated_cast<base::Histogram::Sample>(
cache_storage_installed_script_count_));
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, cache_storage_installed_script_total_size_histogram,
- ("ServiceWorker.CacheStorageInstalledScript.ScriptTotalSize", 1000,
- 50000000, 50));
- cache_storage_installed_script_total_size_histogram.Count(
+ base::UmaHistogramCustomCounts(
+ "ServiceWorker.CacheStorageInstalledScript.ScriptTotalSize",
base::saturated_cast<base::Histogram::Sample>(
- cache_storage_installed_script_total_size_));
+ cache_storage_installed_script_total_size_),
+ 1000, 50000000, 50);
if (cache_storage_installed_script_metadata_total_size_) {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram,
- cache_storage_installed_script_metadata_total_size_histogram,
- ("ServiceWorker.CacheStorageInstalledScript.CachedMetadataTotalSize",
- 1000, 50000000, 50));
- cache_storage_installed_script_metadata_total_size_histogram.Count(
+ base::UmaHistogramCustomCounts(
+ "ServiceWorker.CacheStorageInstalledScript.CachedMetadataTotalSize",
base::saturated_cast<base::Histogram::Sample>(
- cache_storage_installed_script_metadata_total_size_));
+ cache_storage_installed_script_metadata_total_size_),
+ 1000, 50000000, 50);
}
}
@@ -1284,6 +1279,11 @@ ServiceWorkerGlobalScope::GetServiceWorkerHost() {
return service_worker_host_.get();
}
+void ServiceWorkerGlobalScope::OnBeforeStartEvent(bool is_offline_event) {
+ DCHECK(IsContextThread());
+ SetIsOfflineMode(is_offline_event);
+}
+
void ServiceWorkerGlobalScope::OnIdleTimeout() {
DCHECK(IsContextThread());
// RequestedTermination() returns true if ServiceWorkerEventQueue agrees
@@ -1324,8 +1324,8 @@ void ServiceWorkerGlobalScope::DispatchExtendableMessageEventInternal(
String origin;
if (!event->source_origin->IsOpaque())
origin = event->source_origin->ToString();
- WaitUntilObserver* observer =
- WaitUntilObserver::Create(this, WaitUntilObserver::kMessage, event_id);
+ WaitUntilObserver* observer = nullptr;
+ Event* event_to_dispatch = nullptr;
if (event->source_info_for_client) {
mojom::blink::ServiceWorkerClientInfoPtr client_info =
@@ -1333,11 +1333,37 @@ void ServiceWorkerGlobalScope::DispatchExtendableMessageEventInternal(
DCHECK(!client_info->client_uuid.IsEmpty());
ServiceWorkerClient* source = nullptr;
if (client_info->client_type == mojom::ServiceWorkerClientType::kWindow)
- source = ServiceWorkerWindowClient::Create(*client_info);
+ source = MakeGarbageCollected<ServiceWorkerWindowClient>(*client_info);
else
- source = ServiceWorkerClient::Create(*client_info);
- Event* event_to_dispatch = ExtendableMessageEvent::Create(
- std::move(msg.message), origin, ports, source, observer);
+ source = MakeGarbageCollected<ServiceWorkerClient>(*client_info);
+ // TODO(crbug.com/1018092): Factor out these security checks so they aren't
+ // duplicated in so many places.
+ if (msg.message->IsOriginCheckRequired()) {
+ const SecurityOrigin* target_origin =
+ GetExecutionContext()->GetSecurityOrigin();
+ if (!msg.sender_origin ||
+ !msg.sender_origin->IsSameOriginWith(target_origin)) {
+ observer = MakeGarbageCollected<WaitUntilObserver>(
+ this, WaitUntilObserver::kMessageerror, event_id);
+ event_to_dispatch = ExtendableMessageEvent::CreateError(
+ origin, ports, source, observer);
+ }
+ }
+ if (!event_to_dispatch) {
+ if (!msg.locked_agent_cluster_id ||
+ GetExecutionContext()->IsSameAgentCluster(
+ *msg.locked_agent_cluster_id)) {
+ observer = MakeGarbageCollected<WaitUntilObserver>(
+ this, WaitUntilObserver::kMessage, event_id);
+ event_to_dispatch = ExtendableMessageEvent::Create(
+ std::move(msg.message), origin, ports, source, observer);
+ } else {
+ observer = MakeGarbageCollected<WaitUntilObserver>(
+ this, WaitUntilObserver::kMessageerror, event_id);
+ event_to_dispatch = ExtendableMessageEvent::CreateError(
+ origin, ports, source, observer);
+ }
+ }
DispatchExtendableEvent(event_to_dispatch, observer);
return;
}
@@ -1346,14 +1372,40 @@ void ServiceWorkerGlobalScope::DispatchExtendableMessageEventInternal(
mojom::blink::kInvalidServiceWorkerVersionId);
::blink::ServiceWorker* source = ::blink::ServiceWorker::From(
GetExecutionContext(), std::move(event->source_info_for_service_worker));
- Event* event_to_dispatch = ExtendableMessageEvent::Create(
- std::move(msg.message), origin, ports, source, observer);
+ // TODO(crbug.com/1018092): Factor out these security checks so they aren't
+ // duplicated in so many places.
+ if (msg.message->IsOriginCheckRequired()) {
+ const SecurityOrigin* target_origin =
+ GetExecutionContext()->GetSecurityOrigin();
+ if (!msg.sender_origin ||
+ !msg.sender_origin->IsSameOriginWith(target_origin)) {
+ observer = MakeGarbageCollected<WaitUntilObserver>(
+ this, WaitUntilObserver::kMessageerror, event_id);
+ event_to_dispatch =
+ ExtendableMessageEvent::CreateError(origin, ports, source, observer);
+ }
+ }
+ if (!event_to_dispatch) {
+ if (!msg.locked_agent_cluster_id ||
+ GetExecutionContext()->IsSameAgentCluster(
+ *msg.locked_agent_cluster_id)) {
+ observer = MakeGarbageCollected<WaitUntilObserver>(
+ this, WaitUntilObserver::kMessage, event_id);
+ event_to_dispatch = ExtendableMessageEvent::Create(
+ std::move(msg.message), origin, ports, source, observer);
+ } else {
+ observer = MakeGarbageCollected<WaitUntilObserver>(
+ this, WaitUntilObserver::kMessageerror, event_id);
+ event_to_dispatch =
+ ExtendableMessageEvent::CreateError(origin, ports, source, observer);
+ }
+ }
DispatchExtendableEvent(event_to_dispatch, observer);
}
void ServiceWorkerGlobalScope::StartFetchEvent(
mojom::blink::DispatchFetchEventParamsPtr params,
- network::mojom::blink::CrossOriginEmbedderPolicy requestor_coep,
+ base::WeakPtr<CrossOriginResourcePolicyChecker> corp_checker,
mojo::PendingRemote<mojom::blink::ServiceWorkerFetchResponseCallback>
response_callback,
DispatchFetchEventInternalCallback callback,
@@ -1383,11 +1435,11 @@ void ServiceWorkerGlobalScope::StartFetchEvent(
mojom::blink::FetchAPIRequest& fetch_request = *params->request;
ScriptState::Scope scope(ScriptController()->GetScriptState());
- WaitUntilObserver* wait_until_observer =
- WaitUntilObserver::Create(this, WaitUntilObserver::kFetch, event_id);
- FetchRespondWithObserver* respond_with_observer =
- FetchRespondWithObserver::Create(this, event_id, requestor_coep,
- fetch_request, wait_until_observer);
+ 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,
+ wait_until_observer);
Request* request =
Request::Create(ScriptController()->GetScriptState(), fetch_request,
Request::ForServiceWorkerFetchEvent::kTrue);
@@ -1436,20 +1488,20 @@ void ServiceWorkerGlobalScope::DispatchFetchEventForSubresource(
"ServiceWorkerGlobalScope::DispatchFetchEventForSubresource",
"url", params->request->url.ElidedString().Utf8(), "queued",
RequestedTermination() ? "true" : "false");
- network::mojom::blink::CrossOriginEmbedderPolicy requestor_coep =
- controller_receivers_.current_context();
+ base::WeakPtr<CrossOriginResourcePolicyChecker> corp_checker =
+ controller_receivers_.current_context()->GetWeakPtr();
if (RequestedTermination()) {
event_queue_->EnqueuePending(
WTF::Bind(&ServiceWorkerGlobalScope::StartFetchEvent,
WrapWeakPersistent(this), std::move(params),
- std::move(requestor_coep), std::move(response_callback),
+ std::move(corp_checker), std::move(response_callback),
std::move(callback)),
CreateAbortCallback(&fetch_event_callbacks_), base::nullopt);
} else {
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartFetchEvent,
WrapWeakPersistent(this), std::move(params),
- std::move(requestor_coep), std::move(response_callback),
+ std::move(corp_checker), std::move(response_callback),
std::move(callback)),
CreateAbortCallback(&fetch_event_callbacks_), base::nullopt);
}
@@ -1457,11 +1509,16 @@ void ServiceWorkerGlobalScope::DispatchFetchEventForSubresource(
void ServiceWorkerGlobalScope::Clone(
mojo::PendingReceiver<mojom::blink::ControllerServiceWorker> receiver,
- network::mojom::blink::CrossOriginEmbedderPolicy
- cross_origin_embedder_policy) {
+ const network::CrossOriginEmbedderPolicy& cross_origin_embedder_policy,
+ mojo::PendingRemote<
+ network::mojom::blink::CrossOriginEmbedderPolicyReporter>
+ coep_reporter) {
DCHECK(IsContextThread());
+ auto checker = std::make_unique<CrossOriginResourcePolicyChecker>(
+ cross_origin_embedder_policy, std::move(coep_reporter));
+
controller_receivers_.Add(
- this, std::move(receiver), cross_origin_embedder_policy,
+ this, std::move(receiver), std::move(checker),
GetThread()->GetTaskRunner(TaskType::kInternalDefault));
}
@@ -1470,7 +1527,9 @@ void ServiceWorkerGlobalScope::InitializeGlobalScope(
service_worker_host,
mojom::blink::ServiceWorkerRegistrationObjectInfoPtr registration_info,
mojom::blink::ServiceWorkerObjectInfoPtr service_worker_info,
- mojom::blink::FetchHandlerExistence fetch_hander_existence) {
+ mojom::blink::FetchHandlerExistence fetch_hander_existence,
+ std::unique_ptr<PendingURLLoaderFactoryBundle>
+ subresource_loader_factories) {
DCHECK(IsContextThread());
DCHECK(!global_scope_initialized_);
@@ -1479,6 +1538,13 @@ void ServiceWorkerGlobalScope::InitializeGlobalScope(
service_worker_host_.Bind(std::move(service_worker_host),
GetTaskRunner(TaskType::kInternalDefault));
+ if (subresource_loader_factories) {
+ static_cast<WebServiceWorkerFetchContext*>(web_worker_fetch_context())
+ ->GetSubresourceLoaderUpdater()
+ ->UpdateSubresourceLoaderFactories(
+ std::move(subresource_loader_factories));
+ }
+
// Set ServiceWorkerGlobalScope#registration.
DCHECK_NE(registration_info->registration_id,
mojom::blink::kInvalidServiceWorkerRegistrationId);
@@ -1523,9 +1589,7 @@ void ServiceWorkerGlobalScope::DispatchInstallEvent(
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartInstallEvent,
WrapWeakPersistent(this), std::move(callback)),
- CreateAbortCallback(&install_event_callbacks_,
- false /* has_fetch_handler */),
- base::nullopt);
+ CreateAbortCallback(&install_event_callbacks_), base::nullopt);
}
void ServiceWorkerGlobalScope::StartInstallEvent(
@@ -1539,8 +1603,8 @@ void ServiceWorkerGlobalScope::StartInstallEvent(
TRACE_ID_LOCAL(event_id)),
TRACE_EVENT_FLAG_FLOW_OUT);
- WaitUntilObserver* observer =
- WaitUntilObserver::Create(this, WaitUntilObserver::kInstall, event_id);
+ auto* observer = MakeGarbageCollected<WaitUntilObserver>(
+ this, WaitUntilObserver::kInstall, event_id);
Event* event =
InstallEvent::Create(event_type_names::kInstall,
ExtendableEventInit::Create(), event_id, observer);
@@ -1568,8 +1632,8 @@ void ServiceWorkerGlobalScope::StartActivateEvent(
TRACE_ID_LOCAL(event_id)),
TRACE_EVENT_FLAG_FLOW_OUT);
- WaitUntilObserver* observer =
- WaitUntilObserver::Create(this, WaitUntilObserver::kActivate, event_id);
+ auto* observer = MakeGarbageCollected<WaitUntilObserver>(
+ this, WaitUntilObserver::kActivate, event_id);
Event* event = ExtendableEvent::Create(
event_type_names::kActivate, ExtendableEventInit::Create(), observer);
DispatchExtendableEvent(event, observer);
@@ -1600,7 +1664,7 @@ void ServiceWorkerGlobalScope::StartBackgroundFetchAbortEvent(
TRACE_ID_LOCAL(event_id)),
TRACE_EVENT_FLAG_FLOW_OUT);
- WaitUntilObserver* observer = WaitUntilObserver::Create(
+ auto* observer = MakeGarbageCollected<WaitUntilObserver>(
this, WaitUntilObserver::kBackgroundFetchAbort, event_id);
ScriptState* script_state = ScriptController()->GetScriptState();
@@ -1643,7 +1707,7 @@ void ServiceWorkerGlobalScope::StartBackgroundFetchClickEvent(
TRACE_ID_LOCAL(event_id)),
TRACE_EVENT_FLAG_FLOW_OUT);
- WaitUntilObserver* observer = WaitUntilObserver::Create(
+ auto* observer = MakeGarbageCollected<WaitUntilObserver>(
this, WaitUntilObserver::kBackgroundFetchClick, event_id);
BackgroundFetchEventInit* init = BackgroundFetchEventInit::Create();
@@ -1681,7 +1745,7 @@ void ServiceWorkerGlobalScope::StartBackgroundFetchFailEvent(
TRACE_ID_LOCAL(event_id)),
TRACE_EVENT_FLAG_FLOW_OUT);
- WaitUntilObserver* observer = WaitUntilObserver::Create(
+ auto* observer = MakeGarbageCollected<WaitUntilObserver>(
this, WaitUntilObserver::kBackgroundFetchFail, event_id);
ScriptState* script_state = ScriptController()->GetScriptState();
@@ -1724,7 +1788,7 @@ void ServiceWorkerGlobalScope::StartBackgroundFetchSuccessEvent(
TRACE_ID_LOCAL(event_id)),
TRACE_EVENT_FLAG_FLOW_OUT);
- WaitUntilObserver* observer = WaitUntilObserver::Create(
+ auto* observer = MakeGarbageCollected<WaitUntilObserver>(
this, WaitUntilObserver::kBackgroundFetchSuccess, event_id);
ScriptState* script_state = ScriptController()->GetScriptState();
@@ -1775,14 +1839,24 @@ void ServiceWorkerGlobalScope::DispatchFetchEventForMainResource(
response_callback,
DispatchFetchEventForMainResourceCallback callback) {
DCHECK(IsContextThread());
- // We can use kNone as a |requestor_coep| for the main resource because it
+
+ // We can use nullptr as a |corp_checker| for the main resource because it
// must be the same origin.
- event_queue_->EnqueueNormal(
- WTF::Bind(&ServiceWorkerGlobalScope::StartFetchEvent,
- WrapWeakPersistent(this), std::move(params),
- network::mojom::blink::CrossOriginEmbedderPolicy::kNone,
- std::move(response_callback), std::move(callback)),
- CreateAbortCallback(&fetch_event_callbacks_), base::nullopt);
+ if (params->is_offline_capability_check) {
+ event_queue_->EnqueueOffline(
+ WTF::Bind(&ServiceWorkerGlobalScope::StartFetchEvent,
+ WrapWeakPersistent(this), std::move(params),
+ /*corp_checker=*/nullptr, std::move(response_callback),
+ std::move(callback)),
+ 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)),
+ CreateAbortCallback(&fetch_event_callbacks_), base::nullopt);
+ }
}
void ServiceWorkerGlobalScope::DispatchNotificationClickEvent(
@@ -1815,7 +1889,7 @@ void ServiceWorkerGlobalScope::StartNotificationClickEvent(
TRACE_ID_LOCAL(event_id)),
TRACE_EVENT_FLAG_FLOW_OUT);
- WaitUntilObserver* observer = WaitUntilObserver::Create(
+ auto* observer = MakeGarbageCollected<WaitUntilObserver>(
this, WaitUntilObserver::kNotificationClick, event_id);
NotificationEventInit* event_init = NotificationEventInit::Create();
if (notification_data->actions.has_value() && 0 <= action_index &&
@@ -1855,7 +1929,7 @@ void ServiceWorkerGlobalScope::StartNotificationCloseEvent(
TRACE_ID_WITH_SCOPE(kServiceWorkerGlobalScopeTraceScope,
TRACE_ID_LOCAL(event_id)),
TRACE_EVENT_FLAG_FLOW_OUT);
- WaitUntilObserver* observer = WaitUntilObserver::Create(
+ auto* observer = MakeGarbageCollected<WaitUntilObserver>(
this, WaitUntilObserver::kNotificationClose, event_id);
NotificationEventInit* event_init = NotificationEventInit::Create();
event_init->setAction(WTF::String()); // initialize as null.
@@ -1891,8 +1965,8 @@ void ServiceWorkerGlobalScope::StartPushEvent(
TRACE_ID_LOCAL(event_id)),
TRACE_EVENT_FLAG_FLOW_OUT);
- WaitUntilObserver* observer =
- WaitUntilObserver::Create(this, WaitUntilObserver::kPush, event_id);
+ auto* observer = MakeGarbageCollected<WaitUntilObserver>(
+ this, WaitUntilObserver::kPush, event_id);
Event* event = PushEvent::Create(event_type_names::kPush,
PushMessageData::Create(payload), observer);
DispatchExtendableEvent(event, observer);
@@ -1925,7 +1999,7 @@ void ServiceWorkerGlobalScope::StartPushSubscriptionChangeEvent(
TRACE_ID_LOCAL(event_id)),
TRACE_EVENT_FLAG_FLOW_OUT);
- WaitUntilObserver* observer = WaitUntilObserver::Create(
+ auto* observer = MakeGarbageCollected<WaitUntilObserver>(
this, WaitUntilObserver::kPushSubscriptionChange, event_id);
Event* event = PushSubscriptionChangeEvent::Create(
event_type_names::kPushsubscriptionchange, nullptr /* new_subscription */,
@@ -1959,8 +2033,8 @@ void ServiceWorkerGlobalScope::StartSyncEvent(
TRACE_ID_LOCAL(event_id)),
TRACE_EVENT_FLAG_FLOW_OUT);
- WaitUntilObserver* observer =
- WaitUntilObserver::Create(this, WaitUntilObserver::kSync, event_id);
+ auto* observer = MakeGarbageCollected<WaitUntilObserver>(
+ this, WaitUntilObserver::kSync, event_id);
Event* event =
SyncEvent::Create(event_type_names::kSync, tag, last_chance, observer);
DispatchExtendableEvent(event, observer);
@@ -1989,7 +2063,7 @@ void ServiceWorkerGlobalScope::StartPeriodicSyncEvent(
TRACE_ID_LOCAL(event_id)),
TRACE_EVENT_FLAG_FLOW_OUT);
- WaitUntilObserver* observer = WaitUntilObserver::Create(
+ auto* observer = MakeGarbageCollected<WaitUntilObserver>(
this, WaitUntilObserver::kPeriodicSync, event_id);
Event* event =
PeriodicSyncEvent::Create(event_type_names::kPeriodicsync, tag, observer);
@@ -2025,7 +2099,7 @@ void ServiceWorkerGlobalScope::StartAbortPaymentEvent(
TRACE_ID_LOCAL(event_id)),
TRACE_EVENT_FLAG_FLOW_OUT);
- WaitUntilObserver* wait_until_observer = WaitUntilObserver::Create(
+ auto* wait_until_observer = MakeGarbageCollected<WaitUntilObserver>(
this, WaitUntilObserver::kAbortPayment, event_id);
AbortPaymentRespondWithObserver* respond_with_observer =
MakeGarbageCollected<AbortPaymentRespondWithObserver>(
@@ -2070,7 +2144,7 @@ void ServiceWorkerGlobalScope::StartCanMakePaymentEvent(
TRACE_ID_LOCAL(event_id)),
TRACE_EVENT_FLAG_FLOW_OUT);
- WaitUntilObserver* wait_until_observer = WaitUntilObserver::Create(
+ auto* wait_until_observer = MakeGarbageCollected<WaitUntilObserver>(
this, WaitUntilObserver::kCanMakePayment, event_id);
CanMakePaymentRespondWithObserver* respond_with_observer =
MakeGarbageCollected<CanMakePaymentRespondWithObserver>(
@@ -2117,7 +2191,7 @@ void ServiceWorkerGlobalScope::StartPaymentRequestEvent(
TRACE_ID_LOCAL(event_id)),
TRACE_EVENT_FLAG_FLOW_OUT);
- WaitUntilObserver* wait_until_observer = WaitUntilObserver::Create(
+ auto* wait_until_observer = MakeGarbageCollected<WaitUntilObserver>(
this, WaitUntilObserver::kPaymentRequest, event_id);
PaymentRequestRespondWithObserver* respond_with_observer =
PaymentRequestRespondWithObserver::Create(this, event_id,
@@ -2171,7 +2245,7 @@ void ServiceWorkerGlobalScope::StartCookieChangeEvent(
TRACE_ID_LOCAL(event_id)),
TRACE_EVENT_FLAG_FLOW_OUT);
- WaitUntilObserver* observer = WaitUntilObserver::Create(
+ auto* observer = MakeGarbageCollected<WaitUntilObserver>(
this, WaitUntilObserver::kCookieChange, event_id);
HeapVector<Member<CookieListItem>> changed;
@@ -2210,7 +2284,7 @@ void ServiceWorkerGlobalScope::StartContentDeleteEvent(
TRACE_ID_LOCAL(event_id)),
TRACE_EVENT_FLAG_FLOW_OUT);
- WaitUntilObserver* observer = WaitUntilObserver::Create(
+ auto* observer = MakeGarbageCollected<WaitUntilObserver>(
this, WaitUntilObserver::kContentDelete, event_id);
auto* init = ContentIndexEventInit::Create();
@@ -2227,16 +2301,16 @@ void ServiceWorkerGlobalScope::Ping(PingCallback callback) {
std::move(callback).Run();
}
-void ServiceWorkerGlobalScope::SetIdleTimerDelayToZero() {
+void ServiceWorkerGlobalScope::SetIdleDelay(base::TimeDelta delay) {
DCHECK(IsContextThread());
DCHECK(event_queue_);
- event_queue_->SetIdleTimerDelayToZero();
+ event_queue_->SetIdleDelay(delay);
}
void ServiceWorkerGlobalScope::AddMessageToConsole(
mojom::blink::ConsoleMessageLevel level,
const String& message) {
- AddConsoleMessage(ConsoleMessage::Create(
+ AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther, level, message,
SourceLocation::Capture(/* url= */ "", /* line_number= */ 0,
/* column_number= */ 0)));
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 c5581d41593..2a8b589dcc5 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
@@ -54,8 +54,10 @@
namespace blink {
+class CrossOriginResourcePolicyChecker;
class ExceptionState;
class FetchEvent;
+class PendingURLLoaderFactoryBundle;
class RespondWithObserver;
class RequestInit;
class ScriptPromise;
@@ -65,7 +67,6 @@ class ServiceWorkerClients;
class ServiceWorkerInstalledScriptsManager;
class ServiceWorkerRegistration;
class ServiceWorkerThread;
-class StringOrTrustedScriptURL;
class WaitUntilObserver;
class WebURLResponse;
class WorkerClassicScriptLoader;
@@ -121,7 +122,8 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final
const KURL& module_url_record,
const FetchClientSettingsObjectSnapshot& outside_settings_object,
WorkerResourceTimingNotifier& outside_resource_timing_notifier,
- network::mojom::CredentialsMode) override;
+ network::mojom::CredentialsMode,
+ RejectCoepUnsafeNone reject_coep_unsafe_none) override;
void Dispose() override;
InstalledScriptsManager* GetInstalledScriptsManager() override;
@@ -241,11 +243,13 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final
// |event_id| is the id that was passed to DispatchAbortPaymentEvent.
void RespondToAbortPaymentEvent(int event_id, bool abort_payment);
// RespondToCanMakePaymentEvent will be called after the service worker
- // returns a response to a CanMakePaymentEvent, and
+ // returns the |response| to a CanMakePaymentEvent, and
// DidHandleCanMakePaymentEvent will be called after the end of
- // CanMakePaymentEvent's lifecycle. |event_id| is the id that was passed
- // to DispatchCanMakePaymentEvent.
- void RespondToCanMakePaymentEvent(int event_id, bool can_make_payment);
+ // CanMakePaymentEvent's lifecycle. |event_id| is the id that was passed to
+ // DispatchCanMakePaymentEvent.
+ void RespondToCanMakePaymentEvent(
+ int event_id,
+ payments::mojom::blink::CanMakePaymentResponsePtr response);
// RespondToPaymentRequestEvent will be called after the service worker
// returns a response to a PaymentRequestEvent, and
// DidHandlePaymentRequestEvent will be called after the end of
@@ -285,8 +289,9 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final
DEFINE_ATTRIBUTE_EVENT_LISTENER(activate, kActivate)
DEFINE_ATTRIBUTE_EVENT_LISTENER(fetch, kFetch)
DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage)
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(messageerror, kMessageerror)
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// Returns true if a FetchEvent exists with the given request URL and
// is still waiting for a Response.
@@ -307,8 +312,7 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final
std::unique_ptr<Vector<uint8_t>>* out_cached_meta_data) override;
private:
- void importScripts(const HeapVector<StringOrTrustedScriptURL>& urls,
- ExceptionState&) override;
+ void importScripts(const Vector<String>& urls, ExceptionState&) override;
SingleCachedMetadataHandler* CreateWorkerScriptCachedMetadataHandler(
const KURL& script_url,
std::unique_ptr<Vector<uint8_t>> meta_data) override;
@@ -338,6 +342,9 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final
// number of scripts and the total bytes of scripts.
void CountScriptInternal(size_t script_size, size_t cached_metadata_size);
+ // Called by ServiceWorkerEventQueue just before they start an event.
+ void OnBeforeStartEvent(bool is_offline_event);
+
// Called by ServiceWorkerEventQueue when a certain time has passed since
// the last task finished.
void OnIdleTimeout();
@@ -369,9 +376,11 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final
response_callback,
DispatchFetchEventForSubresourceCallback callback) override;
void Clone(
- mojo::PendingReceiver<mojom::blink::ControllerServiceWorker> reciever,
- network::mojom::blink::CrossOriginEmbedderPolicy
- cross_origin_embedder_policy) override;
+ mojo::PendingReceiver<mojom::blink::ControllerServiceWorker> receiver,
+ const network::CrossOriginEmbedderPolicy& cross_origin_embedder_policy,
+ mojo::PendingRemote<
+ network::mojom::blink::CrossOriginEmbedderPolicyReporter>
+ coep_reporter) override;
// Implements mojom::blink::ServiceWorker.
void InitializeGlobalScope(
@@ -379,7 +388,9 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final
service_worker_host,
mojom::blink::ServiceWorkerRegistrationObjectInfoPtr registration_info,
mojom::blink::ServiceWorkerObjectInfoPtr service_worker_info,
- mojom::blink::FetchHandlerExistence fetch_hander_existence) override;
+ mojom::blink::FetchHandlerExistence fetch_handler_existence,
+ std::unique_ptr<PendingURLLoaderFactoryBundle>
+ subresource_loader_factories) override;
void DispatchInstallEvent(DispatchInstallEventCallback callback) override;
void DispatchActivateEvent(DispatchActivateEventCallback callback) override;
void DispatchBackgroundFetchAbortEvent(
@@ -450,7 +461,7 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final
const String& id,
DispatchContentDeleteEventCallback callback) override;
void Ping(PingCallback callback) override;
- void SetIdleTimerDelayToZero() override;
+ void SetIdleDelay(base::TimeDelta delay) override;
void AddMessageToConsole(mojom::blink::ConsoleMessageLevel,
const String& message) override;
@@ -461,7 +472,7 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final
// the event queue, and executed immediately or sometimes later.
void StartFetchEvent(
mojom::blink::DispatchFetchEventParamsPtr params,
- network::mojom::blink::CrossOriginEmbedderPolicy requestor_coep,
+ base::WeakPtr<CrossOriginResourcePolicyChecker> corp_checker,
mojo::PendingRemote<mojom::blink::ServiceWorkerFetchResponseCallback>
response_callback,
DispatchFetchEventInternalCallback callback,
@@ -656,12 +667,12 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final
// |event_queue_| since the pipe needs to be disconnected before callbacks
// passed by DispatchSomeEvent() get destructed, which may be stored in
// |event_queue_|.
- // network::mojom::blink::CrossOriginEmbedderPolicy set as the context of
+ // network::CrossOriginEmbedderPolicy set as the context of
// 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,
- network::mojom::blink::CrossOriginEmbedderPolicy>
+ std::unique_ptr<CrossOriginResourcePolicyChecker>>
controller_receivers_;
};
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.idl b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.idl
index e76abe6f525..0a4a3e08e52 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.idl
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.idl
@@ -45,4 +45,5 @@
attribute EventHandler onfetch;
attribute EventHandler oninstall;
attribute EventHandler onmessage;
+ attribute EventHandler onmessageerror;
};
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 ed45d15abca..8cc3133de17 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
@@ -184,9 +184,9 @@ void ServiceWorkerGlobalScopeProxy::WillEvaluateClassicScript(
size_t script_size,
size_t cached_metadata_size) {
DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_);
- TRACE_EVENT_ASYNC_BEGIN0(
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(
"ServiceWorker", "ServiceWorkerGlobalScopeProxy::EvaluateClassicScript",
- this);
+ TRACE_ID_LOCAL(this));
// TODO(asamidoi): Remove CountWorkerScript which is called for recording
// metrics if the metrics are no longer referenced, and then merge
// WillEvaluateClassicScript and WillEvaluateModuleScript for cleanup.
@@ -217,9 +217,9 @@ void ServiceWorkerGlobalScopeProxy::DidEvaluateClassicScript(bool success) {
DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_);
WorkerGlobalScope()->DidEvaluateScript();
Client().DidEvaluateScript(success);
- TRACE_EVENT_ASYNC_END1("ServiceWorker",
- "ServiceWorkerGlobalScopeProxy::EvaluateClassicScript",
- this, "success", success);
+ TRACE_EVENT_NESTABLE_ASYNC_END1(
+ "ServiceWorker", "ServiceWorkerGlobalScopeProxy::EvaluateClassicScript",
+ TRACE_ID_LOCAL(this), "success", success);
}
void ServiceWorkerGlobalScopeProxy::DidEvaluateModuleScript(bool success) {
@@ -274,9 +274,9 @@ void ServiceWorkerGlobalScopeProxy::SetupNavigationPreload(
mojom::blink::FetchEventPreloadHandlePtr preload_handle) {
DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_);
auto web_preload_handle = std::make_unique<WebFetchEventPreloadHandle>();
- web_preload_handle->url_loader = preload_handle->url_loader.PassPipe();
+ web_preload_handle->url_loader = std::move(preload_handle->url_loader);
web_preload_handle->url_loader_client_receiver =
- preload_handle->url_loader_client_receiver.PassPipe();
+ std::move(preload_handle->url_loader_client_receiver);
Client().SetupNavigationPreload(fetch_event_id, url,
std::move(web_preload_handle));
}
@@ -324,6 +324,10 @@ void ServiceWorkerGlobalScopeProxy::ResumeEvaluation() {
WorkerGlobalScope()->ResumeEvaluation();
}
+bool ServiceWorkerGlobalScopeProxy::HasFetchHandler() {
+ return WorkerGlobalScope()->HasEventListeners(event_type_names::kFetch);
+}
+
WebServiceWorkerContextClient& ServiceWorkerGlobalScopeProxy::Client() const {
DCHECK(client_);
return *client_;
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 981994b3fa3..74ab5568ba9 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
@@ -93,6 +93,7 @@ class ServiceWorkerGlobalScopeProxy final : public WebServiceWorkerContextProxy,
bool IsWindowInteractionAllowed() override;
void PauseEvaluation() override;
void ResumeEvaluation() override;
+ bool HasFetchHandler() override;
// WorkerReportingProxy overrides:
void CountFeature(WebFeature) override;
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 6136ce36971..fa1c33f498a 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(blink::Visitor* visitor) {
+void ServiceWorkerModuleTreeClient::Trace(Visitor* visitor) {
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 94e2ec67e37..8831a54c16f 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 dc6d6d4778c..f03c560c33b 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
@@ -9,16 +9,19 @@
#include "base/memory/ptr_util.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
+#include "third_party/blink/public/common/security_context/insecure_request_policy.h"
#include "third_party/blink/public/mojom/loader/fetch_client_settings_object.mojom-blink.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_navigation_preload_state.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/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
-#include "third_party/blink/renderer/modules/service_worker/navigation_preload_state.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_container.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_error.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope.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/heap/heap.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object.h"
@@ -128,14 +131,14 @@ ServiceWorkerRegistration* ServiceWorkerRegistration::Take(
ScriptPromiseResolver* resolver,
WebServiceWorkerRegistrationObjectInfo info) {
return ServiceWorkerContainer::From(
- To<Document>(resolver->GetExecutionContext()))
+ Document::From(resolver->GetExecutionContext()))
->GetOrCreateServiceWorkerRegistration(std::move(info));
}
ServiceWorkerRegistration::ServiceWorkerRegistration(
ExecutionContext* execution_context,
WebServiceWorkerRegistrationObjectInfo info)
- : ContextLifecycleObserver(execution_context),
+ : ExecutionContextLifecycleObserver(execution_context),
registration_id_(info.registration_id),
scope_(std::move(info.scope)),
stopped_(false) {
@@ -147,7 +150,7 @@ ServiceWorkerRegistration::ServiceWorkerRegistration(
ServiceWorkerRegistration::ServiceWorkerRegistration(
ExecutionContext* execution_context,
mojom::blink::ServiceWorkerRegistrationObjectInfoPtr info)
- : ContextLifecycleObserver(execution_context),
+ : ExecutionContextLifecycleObserver(execution_context),
registration_id_(info->registration_id),
scope_(std::move(info->scope)),
stopped_(false) {
@@ -211,7 +214,7 @@ const AtomicString& ServiceWorkerRegistration::InterfaceName() const {
NavigationPreloadManager* ServiceWorkerRegistration::navigationPreload() {
if (!navigation_preload_)
- navigation_preload_ = NavigationPreloadManager::Create(this);
+ navigation_preload_ = MakeGarbageCollected<NavigationPreloadManager>(this);
return navigation_preload_;
}
@@ -253,13 +256,15 @@ void ServiceWorkerRegistration::SetNavigationPreloadHeader(
WTF::Bind(&DidSetNavigationPreloadHeader, WrapPersistent(resolver)));
}
-ScriptPromise ServiceWorkerRegistration::update(ScriptState* script_state) {
+ScriptPromise ServiceWorkerRegistration::update(
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
if (!GetExecutionContext()) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "Failed to update a ServiceWorkerRegistration: No "
- "associated provider is available."));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "Failed to update a ServiceWorkerRegistration: No associated provider "
+ "is available.");
+ return ScriptPromise();
}
// The fetcher is lazily loaded in a worker global scope.
@@ -274,8 +279,9 @@ ScriptPromise ServiceWorkerRegistration::update(ScriptState* script_state) {
auto mojom_settings_object = mojom::blink::FetchClientSettingsObject::New(
settings_object.GetReferrerPolicy(),
KURL(settings_object.GetOutgoingReferrer()),
- settings_object.GetInsecureRequestsPolicy() &
- blink::kUpgradeInsecureRequests
+ (settings_object.GetInsecureRequestsPolicy() &
+ mojom::blink::InsecureRequestPolicy::kUpgradeInsecureRequests) !=
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone
? blink::mojom::InsecureRequestsPolicy::kUpgrade
: blink::mojom::InsecureRequestsPolicy::kDoNotUpgrade);
@@ -286,14 +292,15 @@ ScriptPromise ServiceWorkerRegistration::update(ScriptState* script_state) {
return resolver->Promise();
}
-ScriptPromise ServiceWorkerRegistration::unregister(ScriptState* script_state) {
+ScriptPromise ServiceWorkerRegistration::unregister(
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
if (!GetExecutionContext()) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "Failed to unregister a "
- "ServiceWorkerRegistration: No "
- "associated provider is available."));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Failed to unregister a "
+ "ServiceWorkerRegistration: No "
+ "associated provider is available.");
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
host_->Unregister(WTF::Bind(&DidUnregister, WrapPersistent(resolver)));
@@ -307,17 +314,17 @@ void ServiceWorkerRegistration::Dispose() {
receiver_.reset();
}
-void ServiceWorkerRegistration::Trace(blink::Visitor* visitor) {
+void ServiceWorkerRegistration::Trace(Visitor* visitor) {
visitor->Trace(installing_);
visitor->Trace(waiting_);
visitor->Trace(active_);
visitor->Trace(navigation_preload_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
Supplementable<ServiceWorkerRegistration>::Trace(visitor);
}
-void ServiceWorkerRegistration::ContextDestroyed(ExecutionContext*) {
+void ServiceWorkerRegistration::ContextDestroyed() {
if (stopped_)
return;
stopped_ = true;
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 1c24538374f..ab20fc03861 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
@@ -14,7 +14,7 @@
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/service_worker/navigation_preload_manager.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker.h"
#include "third_party/blink/renderer/platform/supplementable.h"
@@ -22,6 +22,7 @@
namespace blink {
+class ExceptionState;
class ScriptPromise;
class ScriptState;
@@ -29,7 +30,7 @@ class ScriptState;
class ServiceWorkerRegistration final
: public EventTargetWithInlineData,
public ActiveScriptWrappable<ServiceWorkerRegistration>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public Supplementable<ServiceWorkerRegistration>,
public mojom::blink::ServiceWorkerRegistrationObject {
DEFINE_WRAPPERTYPEINFO();
@@ -64,7 +65,7 @@ class ServiceWorkerRegistration final
// EventTarget overrides.
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
ServiceWorker* installing() { return installing_; }
@@ -82,8 +83,8 @@ class ServiceWorkerRegistration final
void SetNavigationPreloadHeader(const String& value,
ScriptPromiseResolver* resolver);
- ScriptPromise update(ScriptState*);
- ScriptPromise unregister(ScriptState*);
+ ScriptPromise update(ScriptState*, ExceptionState&);
+ ScriptPromise unregister(ScriptState*, ExceptionState&);
DEFINE_ATTRIBUTE_EVENT_LISTENER(updatefound, kUpdatefound)
@@ -91,11 +92,11 @@ class ServiceWorkerRegistration final
void Dispose();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
- // ContextLifecycleObserver overrides.
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver overrides.
+ void ContextDestroyed() override;
// Implements mojom::blink::ServiceWorkerRegistrationObject.
void SetServiceWorkerObjects(
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.idl b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.idl
index 21795936964..6bd8ed8acab 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.idl
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.idl
@@ -23,8 +23,8 @@ enum ServiceWorkerUpdateViaCache {
readonly attribute USVString scope;
readonly attribute ServiceWorkerUpdateViaCache updateViaCache;
- [CallWith=ScriptState] Promise<ServiceWorkerRegistration> update();
- [CallWith=ScriptState] Promise<boolean> unregister();
+ [CallWith=ScriptState, RaisesException] Promise<ServiceWorkerRegistration> update();
+ [CallWith=ScriptState, RaisesException] Promise<boolean> unregister();
attribute EventHandler onupdatefound;
};
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 23ab064b76c..354e0465b91 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
@@ -17,6 +17,11 @@ ServiceWorkerScriptCachedMetadataHandler::
std::unique_ptr<Vector<uint8_t>> meta_data)
: global_scope_(global_scope), script_url_(script_url) {
if (meta_data) {
+ // Non-null |meta_data| means the "platform" already has the CachedMetadata.
+ // In that case, set |cached_metadata_| to this incoming metadata. In
+ // contrast, SetCachedMetadata() is called when there is new metadata to be
+ // cached. In that case, |cached_metadata_| is set to the metadata and
+ // additionally it is sent back to the persistent storage as well.
cached_metadata_ =
CachedMetadata::CreateFromSerializedData(std::move(*meta_data));
}
@@ -25,7 +30,7 @@ ServiceWorkerScriptCachedMetadataHandler::
ServiceWorkerScriptCachedMetadataHandler::
~ServiceWorkerScriptCachedMetadataHandler() = default;
-void ServiceWorkerScriptCachedMetadataHandler::Trace(blink::Visitor* visitor) {
+void ServiceWorkerScriptCachedMetadataHandler::Trace(Visitor* visitor) {
visitor->Trace(global_scope_);
CachedMetadataHandler::Trace(visitor);
}
@@ -33,10 +38,7 @@ void ServiceWorkerScriptCachedMetadataHandler::Trace(blink::Visitor* visitor) {
void ServiceWorkerScriptCachedMetadataHandler::SetCachedMetadata(
uint32_t data_type_id,
const uint8_t* data,
- size_t size,
- CacheType type) {
- if (type != kSendToPlatform)
- return;
+ size_t size) {
cached_metadata_ = CachedMetadata::Create(data_type_id, data, size);
base::span<const uint8_t> serialized_data =
cached_metadata_->SerializedData();
@@ -45,10 +47,10 @@ void ServiceWorkerScriptCachedMetadataHandler::SetCachedMetadata(
}
void ServiceWorkerScriptCachedMetadataHandler::ClearCachedMetadata(
- CacheType type) {
- if (type != kSendToPlatform)
- return;
+ ClearCacheType type) {
cached_metadata_ = nullptr;
+ if (type != kClearPersistentStorage)
+ return;
global_scope_->GetServiceWorkerHost()->ClearCachedMetadata(script_url_);
}
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 fb16653c872..7b7e8d3de5d 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
@@ -19,25 +19,16 @@ class ServiceWorkerGlobalScope;
class ServiceWorkerScriptCachedMetadataHandler
: public SingleCachedMetadataHandler {
public:
- static ServiceWorkerScriptCachedMetadataHandler* Create(
- ServiceWorkerGlobalScope* global_scope,
- const KURL& script_url,
- std::unique_ptr<Vector<uint8_t>> meta_data) {
- return MakeGarbageCollected<ServiceWorkerScriptCachedMetadataHandler>(
- global_scope, script_url, std::move(meta_data));
- }
-
ServiceWorkerScriptCachedMetadataHandler(
ServiceWorkerGlobalScope*,
const KURL& script_url,
std::unique_ptr<Vector<uint8_t>> meta_data);
~ServiceWorkerScriptCachedMetadataHandler() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void SetCachedMetadata(uint32_t data_type_id,
const uint8_t*,
- size_t,
- CacheType) override;
- void ClearCachedMetadata(CacheType) override;
+ size_t) override;
+ void ClearCachedMetadata(ClearCacheType) override;
scoped_refptr<CachedMetadata> GetCachedMetadata(
uint32_t data_type_id) const override;
String Encoding() const 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 620b73cd74a..8f79377705c 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
@@ -35,7 +35,7 @@ void DidFocus(ScriptPromiseResolver* resolver,
"The client was not found."));
return;
}
- resolver->Resolve(ServiceWorkerWindowClient::Create(*client));
+ resolver->Resolve(MakeGarbageCollected<ServiceWorkerWindowClient>(*client));
}
void DidNavigateOrOpenWindow(ScriptPromiseResolver* resolver,
@@ -67,12 +67,6 @@ void DidNavigateOrOpenWindow(ScriptPromiseResolver* resolver,
} // namespace
-ServiceWorkerWindowClient* ServiceWorkerWindowClient::Create(
- const mojom::blink::ServiceWorkerClientInfo& info) {
- DCHECK_EQ(mojom::blink::ServiceWorkerClientType::kWindow, info.client_type);
- return MakeGarbageCollected<ServiceWorkerWindowClient>(info);
-}
-
// static
ServiceWorkerWindowClient::ResolveWindowClientCallback
ServiceWorkerWindowClient::CreateResolveWindowClientCallback(
@@ -84,7 +78,9 @@ ServiceWorkerWindowClient::ServiceWorkerWindowClient(
const mojom::blink::ServiceWorkerClientInfo& info)
: ServiceWorkerClient(info),
page_hidden_(info.page_hidden),
- is_focused_(info.is_focused) {}
+ is_focused_(info.is_focused) {
+ DCHECK_EQ(mojom::blink::ServiceWorkerClientType::kWindow, info.client_type);
+}
ServiceWorkerWindowClient::~ServiceWorkerWindowClient() = default;
@@ -136,7 +132,7 @@ ScriptPromise ServiceWorkerWindowClient::navigate(ScriptState* script_state,
return promise;
}
-void ServiceWorkerWindowClient::Trace(blink::Visitor* visitor) {
+void ServiceWorkerWindowClient::Trace(Visitor* visitor) {
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 c0c602d1174..d08a7bfff9e 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
@@ -25,9 +25,6 @@ class MODULES_EXPORT ServiceWorkerWindowClient final
using ResolveWindowClientCallback = base::OnceCallback<
void(bool, mojom::blink::ServiceWorkerClientInfoPtr, const String&)>;
- static ServiceWorkerWindowClient* Create(
- const mojom::blink::ServiceWorkerClientInfo&);
-
static ResolveWindowClientCallback CreateResolveWindowClientCallback(
ScriptPromiseResolver*);
@@ -41,7 +38,7 @@ class MODULES_EXPORT ServiceWorkerWindowClient final
ScriptPromise focus(ScriptState*);
ScriptPromise navigate(ScriptState*, const String& url);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 6969e7aa6f4..abfa072f96f 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(observer_);
ScriptFunction::Trace(visitor);
}
@@ -108,12 +108,6 @@ class WaitUntilObserver::ThenFunction final : public ScriptFunction {
PromiseSettledCallback callback_;
};
-WaitUntilObserver* WaitUntilObserver::Create(ExecutionContext* context,
- EventType type,
- int event_id) {
- return MakeGarbageCollected<WaitUntilObserver>(context, type, event_id);
-}
-
void WaitUntilObserver::WillDispatchEvent() {
DCHECK(GetExecutionContext());
@@ -195,7 +189,7 @@ bool WaitUntilObserver::IsDispatchingEvent() const {
WaitUntilObserver::WaitUntilObserver(ExecutionContext* context,
EventType type,
int event_id)
- : ContextClient(context),
+ : ExecutionContextClient(context),
type_(type),
event_id_(event_id),
consume_window_interaction_timer_(
@@ -280,6 +274,10 @@ void WaitUntilObserver::MaybeCompleteEvent() {
service_worker_global_scope->DidHandleExtendableMessageEvent(event_id_,
status);
break;
+ case kMessageerror:
+ service_worker_global_scope->DidHandleExtendableMessageEvent(event_id_,
+ status);
+ break;
case kNotificationClick:
service_worker_global_scope->DidHandleNotificationClickEvent(event_id_,
status);
@@ -336,8 +334,8 @@ void WaitUntilObserver::ConsumeWindowInteraction(TimerBase*) {
context->ConsumeWindowInteraction();
}
-void WaitUntilObserver::Trace(blink::Visitor* visitor) {
- ContextClient::Trace(visitor);
+void WaitUntilObserver::Trace(Visitor* visitor) {
+ ExecutionContextClient::Trace(visitor);
}
} // namespace blink
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 13a009afcd4..816ce1084b9 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
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_WAIT_UNTIL_OBSERVER_H_
#include "base/callback.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
@@ -21,7 +21,7 @@ class ScriptValue;
// Created for each ExtendableEvent instance.
class MODULES_EXPORT WaitUntilObserver final
: public GarbageCollected<WaitUntilObserver>,
- public ContextClient {
+ public ExecutionContextClient {
USING_GARBAGE_COLLECTED_MIXIN(WaitUntilObserver);
public:
@@ -36,6 +36,7 @@ class MODULES_EXPORT WaitUntilObserver final
kFetch,
kInstall,
kMessage,
+ kMessageerror,
kNotificationClick,
kNotificationClose,
kPaymentRequest,
@@ -50,8 +51,6 @@ class MODULES_EXPORT WaitUntilObserver final
kContentDelete,
};
- static WaitUntilObserver* Create(ExecutionContext*, EventType, int event_id);
-
WaitUntilObserver(ExecutionContext*, EventType, int event_id);
// Must be called before dispatching the event.
@@ -92,7 +91,7 @@ class MODULES_EXPORT WaitUntilObserver final
// TODO(falken): Can this just use Event::IsBeingDispatched?
bool IsDispatchingEvent() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 1cc5397f311..833d7a15833 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
@@ -43,23 +43,35 @@ const char* kNotFoundScriptURL = "https://www.example.com/sw-404.js";
// A fake WebURLLoader which is used for off-main-thread script fetch tests.
class FakeWebURLLoader final : public WebURLLoader {
public:
- FakeWebURLLoader() {}
+ FakeWebURLLoader() = default;
~FakeWebURLLoader() override = default;
- void LoadSynchronously(const WebURLRequest&,
- WebURLLoaderClient*,
- WebURLResponse&,
- base::Optional<WebURLError>&,
- WebData&,
- int64_t& encoded_data_length,
- int64_t& encoded_body_length,
- WebBlobInfo& downloaded_blob) override {
+ void LoadSynchronously(
+ std::unique_ptr<network::ResourceRequest> request,
+ scoped_refptr<WebURLRequest::ExtraData> request_extra_data,
+ int requestor_id,
+ bool download_to_network_cache_only,
+ bool pass_response_pipe_to_client,
+ bool no_mime_sniffing,
+ base::TimeDelta timeout_interval,
+ WebURLLoaderClient*,
+ WebURLResponse&,
+ base::Optional<WebURLError>&,
+ WebData&,
+ int64_t& encoded_data_length,
+ int64_t& encoded_body_length,
+ WebBlobInfo& downloaded_blob) override {
NOTREACHED();
}
- void LoadAsynchronously(const WebURLRequest& request,
- WebURLLoaderClient* client) override {
- if (request.Url().GetString() == kNotFoundScriptURL) {
+ void LoadAsynchronously(
+ std::unique_ptr<network::ResourceRequest> request,
+ scoped_refptr<WebURLRequest::ExtraData> request_extra_data,
+ int requestor_id,
+ bool download_to_network_cache_only,
+ bool no_mime_sniffing,
+ WebURLLoaderClient* client) override {
+ if (request->url.spec() == kNotFoundScriptURL) {
WebURLResponse response;
response.SetMimeType("text/javascript");
response.SetHttpStatusCode(404);
@@ -88,9 +100,10 @@ class FakeWebURLLoaderFactory final : public WebURLLoaderFactory {
}
};
-// A fake WebWorkerFetchContext which is used for off-main-thread script fetch
-// tests.
-class FakeWebWorkerFetchContext final : public WebWorkerFetchContext {
+// A fake WebServiceWorkerFetchContext which is used for off-main-thread script
+// fetch tests.
+class FakeWebServiceWorkerFetchContext final
+ : public WebServiceWorkerFetchContext {
public:
void SetTerminateSyncLoadEvent(base::WaitableEvent*) override {}
void InitializeOnWorkerThread(AcceptLanguagesWatcher*) override {}
@@ -106,7 +119,9 @@ class FakeWebWorkerFetchContext final : public WebWorkerFetchContext {
const override {
return mojom::ControllerServiceWorkerMode::kNoController;
}
- WebURL SiteForCookies() const override { return WebURL(); }
+ net::SiteForCookies SiteForCookies() const override {
+ return net::SiteForCookies();
+ }
base::Optional<WebSecurityOrigin> TopFrameOrigin() const override {
return base::Optional<WebSecurityOrigin>();
}
@@ -115,6 +130,10 @@ class FakeWebWorkerFetchContext final : public WebWorkerFetchContext {
int request_id) override {
return {};
}
+ void SetIsOfflineMode(bool is_offline_mode) override {}
+ mojom::SubresourceLoaderUpdater* GetSubresourceLoaderUpdater() override {
+ return nullptr;
+ }
private:
FakeWebURLLoaderFactory fake_web_url_loader_factory_;
@@ -168,7 +187,8 @@ class MockServiceWorkerContextClient final
mojom::blink::ServiceWorkerState::kParsed,
KURL("https://example.com"), std::move(service_worker_object_host),
service_worker_object.InitWithNewEndpointAndPassReceiver()),
- mojom::blink::FetchHandlerExistence::EXISTS);
+ mojom::blink::FetchHandlerExistence::EXISTS,
+ /*subresource_loader_factories=*/nullptr);
// To make the other side callable.
mojo::AssociateWithDisconnectedPipe(host_receiver.PassHandle());
@@ -186,9 +206,9 @@ class MockServiceWorkerContextClient final
script_evaluated_event_.Signal();
}
- scoped_refptr<WebWorkerFetchContext>
+ scoped_refptr<WebServiceWorkerFetchContext>
CreateWorkerFetchContextOnInitiatorThread() override {
- return base::MakeRefCounted<FakeWebWorkerFetchContext>();
+ return base::MakeRefCounted<FakeWebServiceWorkerFetchContext>();
}
void WorkerContextDestroyed() override { termination_event_.Signal(); }
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/BUILD.gn b/chromium/third_party/blink/renderer/modules/shapedetection/BUILD.gn
index 4442ea54f81..5a9b8a96281 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/BUILD.gn
@@ -10,12 +10,6 @@ blink_modules_sources("shapedetection") {
"barcode_detector.h",
"barcode_detector_statics.cc",
"barcode_detector_statics.h",
- "detected_barcode.cc",
- "detected_barcode.h",
- "detected_face.cc",
- "detected_face.h",
- "detected_text.cc",
- "detected_text.h",
"face_detector.cc",
"face_detector.h",
"shape_detection_type_converter.h",
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/DEPS b/chromium/third_party/blink/renderer/modules/shapedetection/DEPS
index 7b205447533..cf22ab4a920 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/DEPS
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/DEPS
@@ -5,7 +5,7 @@ include_rules = [
"+skia/public/mojom/bitmap.mojom-blink-forward.h",
"-third_party/blink/renderer/modules",
"+third_party/blink/renderer/modules/canvas/canvas2d",
- "+third_party/blink/renderer/modules/imagecapture/point_2d.h",
+ "+third_party/blink/renderer/bindings/modules/v8/v8_point_2d.h",
"+third_party/blink/renderer/modules/modules_export.h",
"+third_party/blink/renderer/modules/shapedetection",
"+third_party/skia/include/core/SkImage.h",
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 46ad05e8bad..6e03c810c8d 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc
@@ -6,15 +6,15 @@
#include <utility>
+#include "third_party/blink/renderer/bindings/modules/v8/v8_barcode_detector_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_detected_barcode.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_point_2d.h"
#include "third_party/blink/renderer/core/dom/dom_exception.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/html/canvas/canvas_image_source.h"
#include "third_party/blink/renderer/core/workers/worker_thread.h"
-#include "third_party/blink/renderer/modules/imagecapture/point_2d.h"
-#include "third_party/blink/renderer/modules/shapedetection/barcode_detector_options.h"
#include "third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.h"
-#include "third_party/blink/renderer/modules/shapedetection/detected_barcode.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
@@ -93,12 +93,48 @@ BarcodeDetector::BarcodeDetector(ExecutionContext* context,
WTF::Bind(&BarcodeDetector::OnConnectionError, WrapWeakPersistent(this)));
}
+// static
ScriptPromise BarcodeDetector::getSupportedFormats(ScriptState* script_state) {
ExecutionContext* context = ExecutionContext::From(script_state);
return BarcodeDetectorStatics::From(context)->EnumerateSupportedFormats(
script_state);
}
+// static
+String BarcodeDetector::BarcodeFormatToString(
+ const shape_detection::mojom::BarcodeFormat format) {
+ switch (format) {
+ case shape_detection::mojom::BarcodeFormat::AZTEC:
+ return "aztec";
+ case shape_detection::mojom::BarcodeFormat::CODE_128:
+ return "code_128";
+ case shape_detection::mojom::BarcodeFormat::CODE_39:
+ return "code_39";
+ case shape_detection::mojom::BarcodeFormat::CODE_93:
+ return "code_93";
+ case shape_detection::mojom::BarcodeFormat::CODABAR:
+ return "codabar";
+ case shape_detection::mojom::BarcodeFormat::DATA_MATRIX:
+ return "data_matrix";
+ case shape_detection::mojom::BarcodeFormat::EAN_13:
+ return "ean_13";
+ case shape_detection::mojom::BarcodeFormat::EAN_8:
+ return "ean_8";
+ case shape_detection::mojom::BarcodeFormat::ITF:
+ return "itf";
+ case shape_detection::mojom::BarcodeFormat::PDF417:
+ return "pdf417";
+ case shape_detection::mojom::BarcodeFormat::QR_CODE:
+ return "qr_code";
+ case shape_detection::mojom::BarcodeFormat::UNKNOWN:
+ return "unknown";
+ case shape_detection::mojom::BarcodeFormat::UPC_A:
+ return "upc_a";
+ case shape_detection::mojom::BarcodeFormat::UPC_E:
+ return "upc_e";
+ }
+}
+
ScriptPromise BarcodeDetector::DoDetect(ScriptPromiseResolver* resolver,
SkBitmap bitmap) {
ScriptPromise promise = resolver->Promise();
@@ -127,16 +163,19 @@ void BarcodeDetector::OnDetectBarcodes(
HeapVector<Member<Point2D>> corner_points;
for (const auto& corner_point : barcode->corner_points) {
Point2D* point = Point2D::Create();
- point->setX(corner_point.x);
- point->setY(corner_point.y);
+ point->setX(corner_point.x());
+ point->setY(corner_point.y());
corner_points.push_back(point);
}
- detected_barcodes.push_back(MakeGarbageCollected<DetectedBarcode>(
- barcode->raw_value,
- DOMRectReadOnly::Create(
- barcode->bounding_box.x, barcode->bounding_box.y,
- barcode->bounding_box.width, barcode->bounding_box.height),
- barcode->format, corner_points));
+
+ DetectedBarcode* detected_barcode = DetectedBarcode::Create();
+ detected_barcode->setRawValue(barcode->raw_value);
+ detected_barcode->setBoundingBox(DOMRectReadOnly::Create(
+ barcode->bounding_box.x(), barcode->bounding_box.y(),
+ barcode->bounding_box.width(), barcode->bounding_box.height()));
+ detected_barcode->setFormat(BarcodeFormatToString(barcode->format));
+ detected_barcode->setCornerPoints(corner_points);
+ detected_barcodes.push_back(detected_barcode);
}
resolver->Resolve(detected_barcodes);
@@ -154,7 +193,7 @@ void BarcodeDetector::OnConnectionError() {
}
}
-void BarcodeDetector::Trace(blink::Visitor* visitor) {
+void BarcodeDetector::Trace(Visitor* visitor) {
ShapeDetector::Trace(visitor);
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 98a324a2e88..91b98a4733b 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.h
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.h
@@ -29,11 +29,14 @@ class MODULES_EXPORT BarcodeDetector final : public ShapeDetector {
// Barcode Detection API functions.
static ScriptPromise getSupportedFormats(ScriptState*);
+ static String BarcodeFormatToString(
+ const shape_detection::mojom::BarcodeFormat format);
+
explicit BarcodeDetector(ExecutionContext*,
const BarcodeDetectorOptions*,
ExceptionState& exception_state);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
~BarcodeDetector() override = default;
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.idl b/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.idl
index f7c5ce69690..025f6a5af98 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.idl
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.idl
@@ -5,14 +5,11 @@
// https://wicg.github.io/shape-detection-api/#barcode-detection-api
[
- Constructor(optional BarcodeDetectorOptions barcodeDetectorOptions),
- ConstructorCallWith=ExecutionContext,
Exposed=(Window,Worker),
SecureContext,
- MeasureAs=ShapeDetection_BarcodeDetectorConstructor,
- RaisesException=Constructor,
- RuntimeEnabled=ShapeDetection
+ RuntimeEnabled=BarcodeDetector
] interface BarcodeDetector {
+ [CallWith=ExecutionContext, RaisesException, MeasureAs=ShapeDetection_BarcodeDetectorConstructor] constructor(optional BarcodeDetectorOptions barcodeDetectorOptions = {});
[CallWith=ScriptState] static Promise<sequence<BarcodeFormat>> getSupportedFormats();
[CallWith=ScriptState, MeasureAs=ShapeDetectionAPI] Promise<sequence<DetectedBarcode>> detect(ImageBitmapSource image);
};
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 4ec76fed03b..afa53d2a48e 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
@@ -8,7 +8,7 @@
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
-#include "third_party/blink/renderer/modules/shapedetection/detected_barcode.h"
+#include "third_party/blink/renderer/modules/shapedetection/barcode_detector.h"
namespace blink {
@@ -81,7 +81,7 @@ void BarcodeDetectorStatics::OnEnumerateSupportedFormats(
Vector<WTF::String> results;
results.ReserveInitialCapacity(results.size());
for (const auto& format : formats)
- results.push_back(DetectedBarcode::BarcodeFormatToString(format));
+ results.push_back(BarcodeDetector::BarcodeFormatToString(format));
resolver->Resolve(results);
}
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.cc b/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.cc
deleted file mode 100644
index 9d2467c3582..00000000000
--- a/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.cc
+++ /dev/null
@@ -1,62 +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/modules/shapedetection/detected_barcode.h"
-
-#include "third_party/blink/renderer/core/geometry/dom_rect.h"
-#include "third_party/blink/renderer/modules/imagecapture/point_2d.h"
-
-namespace blink {
-
-// static
-String DetectedBarcode::BarcodeFormatToString(
- const shape_detection::mojom::BarcodeFormat format) {
- switch (format) {
- case shape_detection::mojom::BarcodeFormat::AZTEC:
- return "aztec";
- case shape_detection::mojom::BarcodeFormat::CODE_128:
- return "code_128";
- case shape_detection::mojom::BarcodeFormat::CODE_39:
- return "code_39";
- case shape_detection::mojom::BarcodeFormat::CODE_93:
- return "code_93";
- case shape_detection::mojom::BarcodeFormat::CODABAR:
- return "codabar";
- case shape_detection::mojom::BarcodeFormat::DATA_MATRIX:
- return "data_matrix";
- case shape_detection::mojom::BarcodeFormat::EAN_13:
- return "ean_13";
- case shape_detection::mojom::BarcodeFormat::EAN_8:
- return "ean_8";
- case shape_detection::mojom::BarcodeFormat::ITF:
- return "itf";
- case shape_detection::mojom::BarcodeFormat::PDF417:
- return "pdf417";
- case shape_detection::mojom::BarcodeFormat::QR_CODE:
- return "qr_code";
- case shape_detection::mojom::BarcodeFormat::UNKNOWN:
- return "unknown";
- case shape_detection::mojom::BarcodeFormat::UPC_A:
- return "upc_a";
- case shape_detection::mojom::BarcodeFormat::UPC_E:
- return "upc_e";
- }
-}
-
-DetectedBarcode::DetectedBarcode(String raw_value,
- DOMRectReadOnly* bounding_box,
- shape_detection::mojom::BarcodeFormat format,
- HeapVector<Member<Point2D>> corner_points)
- : raw_value_(raw_value),
- bounding_box_(bounding_box),
- format_(format),
- corner_points_(corner_points) {}
-
-void DetectedBarcode::Trace(blink::Visitor* visitor) {
- visitor->Trace(bounding_box_);
- visitor->Trace(corner_points_);
- ScriptWrappable::Trace(visitor);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.h b/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.h
deleted file mode 100644
index 560433c4f3e..00000000000
--- a/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.h
+++ /dev/null
@@ -1,48 +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_MODULES_SHAPEDETECTION_DETECTED_BARCODE_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_DETECTED_BARCODE_H_
-
-#include "services/shape_detection/public/mojom/barcodedetection_provider.mojom-blink.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 DOMRectReadOnly;
-class Point2D;
-
-class MODULES_EXPORT DetectedBarcode final : public ScriptWrappable {
- DEFINE_WRAPPERTYPEINFO();
-
- public:
- static String BarcodeFormatToString(
- const shape_detection::mojom::BarcodeFormat format);
-
- DetectedBarcode(String,
- DOMRectReadOnly*,
- shape_detection::mojom::BarcodeFormat,
- HeapVector<Member<Point2D>>);
-
- const String& rawValue() const { return raw_value_; }
- DOMRectReadOnly* boundingBox() const { return bounding_box_; }
- String format() const { return BarcodeFormatToString(format_); }
- const HeapVector<Member<Point2D>>& cornerPoints() const {
- return corner_points_;
- }
-
- void Trace(blink::Visitor*) override;
-
- private:
- const String raw_value_;
- const Member<DOMRectReadOnly> bounding_box_;
- const shape_detection::mojom::BarcodeFormat format_;
- const HeapVector<Member<Point2D>> corner_points_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_DETECTED_BARCODE_H_
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.idl b/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.idl
index 740717eeb67..f02177cf587 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.idl
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/detected_barcode.idl
@@ -4,17 +4,11 @@
// https://wicg.github.io/shape-detection-api/#barcode-detection-api
-[
- Serializable,
- Exposed=(Window,Worker),
- SecureContext,
- RuntimeEnabled=ShapeDetection
-] interface DetectedBarcode {
- // TODO(mcasas): Implement missing fields. https://crbug.com/646083
- [SameObject] readonly attribute DOMString rawValue;
- [SameObject] readonly attribute DOMRectReadOnly boundingBox;
- [SameObject] readonly attribute DOMString format;
+dictionary DetectedBarcode {
+ required DOMString rawValue;
+ required DOMRectReadOnly boundingBox;
+ required DOMString format;
// 4 corner points in clockwise direction starting with top-left. Due to
// possible perspective distortions, this is not necessarily a rectangle.
- [SameObject, SaveSameObject] readonly attribute FrozenArray<Point2D> cornerPoints;
+ required FrozenArray<Point2D> cornerPoints;
};
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.cc b/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.cc
deleted file mode 100644
index bf873d9c1ce..00000000000
--- a/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.cc
+++ /dev/null
@@ -1,22 +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/modules/shapedetection/detected_face.h"
-
-#include "third_party/blink/renderer/core/geometry/dom_rect.h"
-#include "third_party/blink/renderer/modules/shapedetection/landmark.h"
-
-namespace blink {
-
-DetectedFace::DetectedFace(DOMRectReadOnly* bounding_box,
- const HeapVector<Member<Landmark>>& landmarks)
- : bounding_box_(bounding_box), landmarks_(landmarks) {}
-
-void DetectedFace::Trace(blink::Visitor* visitor) {
- visitor->Trace(bounding_box_);
- visitor->Trace(landmarks_);
- ScriptWrappable::Trace(visitor);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.h b/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.h
deleted file mode 100644
index db8828f5d14..00000000000
--- a/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.h
+++ /dev/null
@@ -1,34 +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_MODULES_SHAPEDETECTION_DETECTED_FACE_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_DETECTED_FACE_H_
-
-#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
-
-namespace blink {
-
-class DOMRectReadOnly;
-class Landmark;
-
-class MODULES_EXPORT DetectedFace final : public ScriptWrappable {
- DEFINE_WRAPPERTYPEINFO();
-
- public:
- DetectedFace(DOMRectReadOnly*, const HeapVector<Member<Landmark>>&);
-
- DOMRectReadOnly* boundingBox() const { return bounding_box_; }
- const HeapVector<Member<Landmark>>& landmarks() const { return landmarks_; }
-
- void Trace(blink::Visitor*) override;
-
- private:
- const Member<DOMRectReadOnly> bounding_box_;
- const HeapVector<Member<Landmark>> landmarks_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_DETECTED_FACE_H_
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.idl b/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.idl
index ada91d85329..fd91f68a955 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.idl
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/detected_face.idl
@@ -4,13 +4,8 @@
// https://wicg.github.io/shape-detection-api/#face-detection-api
-[
- Serializable,
- Exposed=(Window,Worker),
- SecureContext,
- RuntimeEnabled=ShapeDetection
-] interface DetectedFace {
+dictionary DetectedFace {
// TODO(xianglu): Implement any other fields. https://crbug.com/646083
- [SameObject] readonly attribute DOMRectReadOnly boundingBox;
- [SameObject, SaveSameObject] readonly attribute FrozenArray<Landmark> landmarks;
+ required DOMRectReadOnly boundingBox;
+ required FrozenArray<Landmark> landmarks;
};
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.cc b/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.cc
deleted file mode 100644
index ba1b3f7ad4d..00000000000
--- a/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.cc
+++ /dev/null
@@ -1,25 +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/modules/shapedetection/detected_text.h"
-
-#include "third_party/blink/renderer/core/geometry/dom_rect.h"
-#include "third_party/blink/renderer/modules/imagecapture/point_2d.h"
-
-namespace blink {
-
-DetectedText::DetectedText(String raw_value,
- DOMRectReadOnly* bounding_box,
- HeapVector<Member<Point2D>> corner_points)
- : raw_value_(raw_value),
- bounding_box_(bounding_box),
- corner_points_(corner_points) {}
-
-void DetectedText::Trace(blink::Visitor* visitor) {
- visitor->Trace(bounding_box_);
- visitor->Trace(corner_points_);
- ScriptWrappable::Trace(visitor);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.h b/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.h
deleted file mode 100644
index bddec6832bb..00000000000
--- a/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.h
+++ /dev/null
@@ -1,39 +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_MODULES_SHAPEDETECTION_DETECTED_TEXT_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_DETECTED_TEXT_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 DOMRectReadOnly;
-class Point2D;
-
-class MODULES_EXPORT DetectedText final : public ScriptWrappable {
- DEFINE_WRAPPERTYPEINFO();
-
- public:
- DetectedText(String, DOMRectReadOnly*, HeapVector<Member<Point2D>>);
-
- const String& rawValue() const { return raw_value_; }
- DOMRectReadOnly* boundingBox() const { return bounding_box_; }
- const HeapVector<Member<Point2D>>& cornerPoints() const {
- return corner_points_;
- }
-
- void Trace(blink::Visitor*) override;
-
- private:
- const String raw_value_;
- const Member<DOMRectReadOnly> bounding_box_;
- const HeapVector<Member<Point2D>> corner_points_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_DETECTED_TEXT_H_
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.idl b/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.idl
index aa8b1ecd8be..9179e337193 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.idl
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/detected_text.idl
@@ -4,15 +4,10 @@
// https://wicg.github.io/shape-detection-api/text.html#detectedtext-section
-[
- Serializable,
- Exposed=(Window,Worker),
- SecureContext,
- RuntimeEnabled=ShapeDetection
-] interface DetectedText {
- [SameObject] readonly attribute DOMString rawValue;
- [SameObject] readonly attribute DOMRectReadOnly boundingBox;
+dictionary DetectedText {
+ required DOMString rawValue;
+ required DOMRectReadOnly boundingBox;
// 4 corner points in clockwise direction starting with top-left. Due to
// possible perspective distortions, this is not necessarily a rectangle.
- [SameObject] readonly attribute FrozenArray<Point2D> cornerPoints;
+ required FrozenArray<Point2D> cornerPoints;
};
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 6577edc0000..766f30a271d 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.cc
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.cc
@@ -9,15 +9,15 @@
#include "services/shape_detection/public/mojom/facedetection_provider.mojom-blink.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/bindings/modules/v8/v8_detected_face.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_face_detector_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_landmark.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_point_2d.h"
#include "third_party/blink/renderer/core/dom/dom_exception.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/html/canvas/canvas_image_source.h"
#include "third_party/blink/renderer/core/workers/worker_thread.h"
-#include "third_party/blink/renderer/modules/imagecapture/point_2d.h"
-#include "third_party/blink/renderer/modules/shapedetection/detected_face.h"
-#include "third_party/blink/renderer/modules/shapedetection/face_detector_options.h"
-#include "third_party/blink/renderer/modules/shapedetection/landmark.h"
#include "third_party/blink/renderer/modules/shapedetection/shape_detection_type_converter.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -31,7 +31,7 @@ FaceDetector* FaceDetector::Create(ExecutionContext* context,
FaceDetector::FaceDetector(ExecutionContext* context,
const FaceDetectorOptions* options)
- : ShapeDetector() {
+ : face_service_(context) {
auto face_detector_options =
shape_detection::mojom::blink::FaceDetectorOptions::New();
face_detector_options->max_detected_faces = options->maxDetectedFaces();
@@ -54,7 +54,7 @@ FaceDetector::FaceDetector(ExecutionContext* context,
ScriptPromise FaceDetector::DoDetect(ScriptPromiseResolver* resolver,
SkBitmap bitmap) {
ScriptPromise promise = resolver->Promise();
- if (!face_service_) {
+ if (!face_service_.is_bound()) {
resolver->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kNotSupportedError,
"Face detection service unavailable."));
@@ -82,8 +82,8 @@ void FaceDetector::OnDetectFaces(
HeapVector<Member<Point2D>> locations;
for (const auto& location : landmark->locations) {
Point2D* web_location = Point2D::Create();
- web_location->setX(location.x);
- web_location->setY(location.y);
+ web_location->setX(location.x());
+ web_location->setY(location.y());
locations.push_back(web_location);
}
@@ -93,11 +93,12 @@ void FaceDetector::OnDetectFaces(
landmarks.push_back(web_landmark);
}
- detected_faces.push_back(MakeGarbageCollected<DetectedFace>(
- DOMRectReadOnly::Create(face->bounding_box.x, face->bounding_box.y,
- face->bounding_box.width,
- face->bounding_box.height),
- landmarks));
+ DetectedFace* detected_face = DetectedFace::Create();
+ detected_face->setBoundingBox(DOMRectReadOnly::Create(
+ face->bounding_box.x(), face->bounding_box.y(),
+ face->bounding_box.width(), face->bounding_box.height()));
+ detected_face->setLandmarks(landmarks);
+ detected_faces.push_back(detected_face);
}
resolver->Resolve(detected_faces);
@@ -113,8 +114,9 @@ void FaceDetector::OnFaceServiceConnectionError() {
face_service_.reset();
}
-void FaceDetector::Trace(blink::Visitor* visitor) {
+void FaceDetector::Trace(Visitor* visitor) {
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 7c5bb6b07f3..bdfc333c7dc 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.h
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.h
@@ -5,13 +5,14 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_FACE_DETECTOR_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_FACE_DETECTOR_H_
-#include "mojo/public/cpp/bindings/remote.h"
#include "services/shape_detection/public/mojom/facedetection.mojom-blink.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/modules/canvas/canvas2d/canvas_rendering_context_2d.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/shapedetection/shape_detector.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 {
@@ -26,7 +27,7 @@ class MODULES_EXPORT FaceDetector final : public ShapeDetector {
FaceDetector(ExecutionContext*, const FaceDetectorOptions*);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
~FaceDetector() override = default;
@@ -37,7 +38,9 @@ class MODULES_EXPORT FaceDetector final : public ShapeDetector {
Vector<shape_detection::mojom::blink::FaceDetectionResultPtr>);
void OnFaceServiceConnectionError();
- mojo::Remote<shape_detection::mojom::blink::FaceDetection> face_service_;
+ HeapMojoRemote<shape_detection::mojom::blink::FaceDetection,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ face_service_;
HeapHashSet<Member<ScriptPromiseResolver>> face_service_requests_;
};
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.idl b/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.idl
index 574c1a519fb..b3dfdcd0f52 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.idl
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.idl
@@ -5,12 +5,10 @@
// https://wicg.github.io/shape-detection-api/#face-detection-api
[
- Constructor(optional FaceDetectorOptions faceDetectorOptions),
- ConstructorCallWith=ExecutionContext,
Exposed=(Window,Worker),
SecureContext,
- MeasureAs=ShapeDetection_FaceDetectorConstructor,
- RuntimeEnabled=ShapeDetection
+ RuntimeEnabled=FaceDetector
] interface FaceDetector {
+ [CallWith=ExecutionContext, MeasureAs=ShapeDetection_FaceDetectorConstructor] constructor(optional FaceDetectorOptions faceDetectorOptions = {});
[CallWith=ScriptState, MeasureAs=ShapeDetectionAPI] Promise<sequence<DetectedFace>> detect(ImageBitmapSource image);
};
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/idls.gni b/chromium/third_party/blink/renderer/modules/shapedetection/idls.gni
new file mode 100644
index 00000000000..f5bd50cc4b7
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "barcode_detector.idl",
+ "face_detector.idl",
+ "text_detector.idl",
+]
+
+modules_dictionary_idl_files = [
+ "barcode_detector_options.idl",
+ "detected_barcode.idl",
+ "detected_face.idl",
+ "detected_text.idl",
+ "face_detector_options.idl",
+ "landmark.idl",
+]
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 d40750fcfd5..2ed51da2d4b 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/shape_detector.cc
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/shape_detector.cc
@@ -68,7 +68,8 @@ ScriptPromise ShapeDetector::detect(
// there is a local WebCam associated, there might be sophisticated ways to
// detect faces on it. Until then, treat as a normal <video> element.
- const FloatSize size(canvas_image_source->ElementSize(FloatSize()));
+ const FloatSize size(
+ canvas_image_source->ElementSize(FloatSize(), kRespectImageOrientation));
SourceImageStatus source_image_status = kInvalidSourceImageStatus;
scoped_refptr<Image> image = canvas_image_source->GetSourceImageForCanvas(
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 8c01af260ce..caa2b2eda56 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.cc
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.cc
@@ -7,13 +7,13 @@
#include <utility>
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_detected_text.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_point_2d.h"
#include "third_party/blink/renderer/core/dom/dom_exception.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/html/canvas/canvas_image_source.h"
#include "third_party/blink/renderer/core/workers/worker_thread.h"
-#include "third_party/blink/renderer/modules/imagecapture/point_2d.h"
-#include "third_party/blink/renderer/modules/shapedetection/detected_text.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
@@ -56,24 +56,26 @@ void TextDetector::OnDetectText(
DCHECK(text_service_requests_.Contains(resolver));
text_service_requests_.erase(resolver);
- HeapVector<Member<DetectedText>> detected_text;
+ HeapVector<Member<DetectedText>> results;
for (const auto& text : text_detection_results) {
HeapVector<Member<Point2D>> corner_points;
for (const auto& corner_point : text->corner_points) {
Point2D* point = Point2D::Create();
- point->setX(corner_point.x);
- point->setY(corner_point.y);
+ point->setX(corner_point.x());
+ point->setY(corner_point.y());
corner_points.push_back(point);
}
- detected_text.push_back(MakeGarbageCollected<DetectedText>(
- text->raw_value,
- DOMRectReadOnly::Create(text->bounding_box.x, text->bounding_box.y,
- text->bounding_box.width,
- text->bounding_box.height),
- corner_points));
+
+ DetectedText* detected_text = DetectedText::Create();
+ detected_text->setRawValue(text->raw_value);
+ detected_text->setBoundingBox(DOMRectReadOnly::Create(
+ text->bounding_box.x(), text->bounding_box.y(),
+ text->bounding_box.width(), text->bounding_box.height()));
+ detected_text->setCornerPoints(corner_points);
+ results.push_back(detected_text);
}
- resolver->Resolve(detected_text);
+ resolver->Resolve(results);
}
void TextDetector::OnTextServiceConnectionError() {
@@ -86,7 +88,7 @@ void TextDetector::OnTextServiceConnectionError() {
text_service_.reset();
}
-void TextDetector::Trace(blink::Visitor* visitor) {
+void TextDetector::Trace(Visitor* visitor) {
ShapeDetector::Trace(visitor);
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 48e06aff0f3..11622c301cc 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.h
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.h
@@ -25,7 +25,7 @@ class MODULES_EXPORT TextDetector final : public ShapeDetector {
explicit TextDetector(ExecutionContext*);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
~TextDetector() override = default;
diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.idl b/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.idl
index 3fb9ff4aebb..82c53e842c4 100644
--- a/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.idl
+++ b/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.idl
@@ -5,12 +5,10 @@
// https://wicg.github.io/shape-detection-api/text.html#text-detection-api
[
- Constructor,
- ConstructorCallWith=ExecutionContext,
Exposed=(Window,Worker),
SecureContext,
- MeasureAs=ShapeDetection_TextDetectorConstructor,
- RuntimeEnabled=ShapeDetection
+ RuntimeEnabled=TextDetector
] interface TextDetector {
+ [CallWith=ExecutionContext, MeasureAs=ShapeDetection_TextDetectorConstructor] constructor();
[CallWith=ScriptState, MeasureAs=ShapeDetectionAPI] Promise<sequence<DetectedText>> detect(ImageBitmapSource image);
};
diff --git a/chromium/third_party/blink/renderer/modules/sms/DEPS b/chromium/third_party/blink/renderer/modules/sms/DEPS
deleted file mode 100644
index 8c9d4dfad0f..00000000000
--- a/chromium/third_party/blink/renderer/modules/sms/DEPS
+++ /dev/null
@@ -1,10 +0,0 @@
-include_rules = [
- "+mojo/public/cpp/bindings/binding.h",
- "+services/metrics/public/cpp/ukm_builders.h",
- "+services/metrics/public/cpp/ukm_source_id.h",
- "-third_party/blink/renderer/modules",
- "+third_party/blink/renderer/modules/event_modules.h",
- "+third_party/blink/renderer/modules/event_target_modules.h",
- "+third_party/blink/renderer/modules/modules_export.h",
- "+third_party/blink/renderer/modules/sms",
-]
diff --git a/chromium/third_party/blink/renderer/modules/sms/OWNERS b/chromium/third_party/blink/renderer/modules/sms/OWNERS
deleted file mode 100644
index 39f063f46bf..00000000000
--- a/chromium/third_party/blink/renderer/modules/sms/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-file://content/browser/sms/OWNERS
-
-# COMPONENT: Blink>SMS
-# TEAM: fugu-dev@chromium.org
diff --git a/chromium/third_party/blink/renderer/modules/sms/README.md b/chromium/third_party/blink/renderer/modules/sms/README.md
deleted file mode 100644
index b2f0832a790..00000000000
--- a/chromium/third_party/blink/renderer/modules/sms/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# SMS Receiver API
-
-This directory contains code for the renderer side implementation of the SMS Receiver API. For more details, refer to [this README file](https://cs.chromium.org/chromium/src/content/browser/sms/README.md).
diff --git a/chromium/third_party/blink/renderer/modules/sms/navigator_sms.cc b/chromium/third_party/blink/renderer/modules/sms/navigator_sms.cc
deleted file mode 100644
index f24849405eb..00000000000
--- a/chromium/third_party/blink/renderer/modules/sms/navigator_sms.cc
+++ /dev/null
@@ -1,46 +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/sms/navigator_sms.h"
-
-#include "third_party/blink/renderer/core/frame/navigator.h"
-#include "third_party/blink/renderer/modules/sms/sms_receiver.h"
-#include "third_party/blink/renderer/platform/bindings/script_state.h"
-
-namespace blink {
-
-NavigatorSMS::NavigatorSMS(Navigator& navigator)
- : Supplement<Navigator>(navigator) {}
-
-const char NavigatorSMS::kSupplementName[] = "NavigatorSMS";
-
-NavigatorSMS& NavigatorSMS::From(Navigator& navigator) {
- NavigatorSMS* supplement =
- Supplement<Navigator>::From<NavigatorSMS>(navigator);
- if (!supplement) {
- supplement = MakeGarbageCollected<NavigatorSMS>(navigator);
- Supplement<Navigator>::ProvideTo(navigator, supplement);
- }
- return *supplement;
-}
-
-SMSReceiver* NavigatorSMS::GetSMSReceiver(ScriptState* script_state) {
- if (!sms_receiver_) {
- sms_receiver_ =
- MakeGarbageCollected<SMSReceiver>(ExecutionContext::From(script_state));
- }
- return sms_receiver_.Get();
-}
-
-SMSReceiver* NavigatorSMS::sms(ScriptState* script_state,
- Navigator& navigator) {
- return NavigatorSMS::From(navigator).GetSMSReceiver(script_state);
-}
-
-void NavigatorSMS::Trace(blink::Visitor* visitor) {
- visitor->Trace(sms_receiver_);
- Supplement<Navigator>::Trace(visitor);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/sms/navigator_sms.h b/chromium/third_party/blink/renderer/modules/sms/navigator_sms.h
deleted file mode 100644
index 91f595e58af..00000000000
--- a/chromium/third_party/blink/renderer/modules/sms/navigator_sms.h
+++ /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.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SMS_NAVIGATOR_SMS_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_SMS_NAVIGATOR_SMS_H_
-
-#include "third_party/blink/renderer/core/frame/navigator.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/supplementable.h"
-
-namespace blink {
-
-class Navigator;
-class ScriptState;
-class SMSReceiver;
-
-class NavigatorSMS final : public GarbageCollected<NavigatorSMS>,
- public Supplement<Navigator> {
- USING_GARBAGE_COLLECTED_MIXIN(NavigatorSMS);
-
- public:
- static const char kSupplementName[];
-
- static NavigatorSMS& From(Navigator&);
-
- static SMSReceiver* sms(ScriptState*, Navigator&);
-
- explicit NavigatorSMS(Navigator&);
-
- void Trace(blink::Visitor*) override;
-
- private:
- SMSReceiver* GetSMSReceiver(ScriptState*);
-
- Member<SMSReceiver> sms_receiver_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SMS_NAVIGATOR_SMS_H_
diff --git a/chromium/third_party/blink/renderer/modules/sms/navigator_sms.idl b/chromium/third_party/blink/renderer/modules/sms/navigator_sms.idl
deleted file mode 100644
index b979116f8af..00000000000
--- a/chromium/third_party/blink/renderer/modules/sms/navigator_sms.idl
+++ /dev/null
@@ -1,14 +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.
-
-// https://github.com/samuelgoto/sms-receiver
-
-[
- SecureContext,
- Exposed=Window,
- ImplementedAs=NavigatorSMS,
- RuntimeEnabled=SmsReceiver
-] partial interface Navigator {
- [CallWith=ScriptState] readonly attribute SMSReceiver sms;
-};
diff --git a/chromium/third_party/blink/renderer/modules/sms/sms.cc b/chromium/third_party/blink/renderer/modules/sms/sms.cc
deleted file mode 100644
index 9bdcc1a2438..00000000000
--- a/chromium/third_party/blink/renderer/modules/sms/sms.cc
+++ /dev/null
@@ -1,19 +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/sms/sms.h"
-
-#include <utility>
-
-namespace blink {
-
-SMS::SMS(const WTF::String& content) : content_(content) {}
-
-SMS::~SMS() = default;
-
-const String& SMS::content() const {
- return content_;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/sms/sms.h b/chromium/third_party/blink/renderer/modules/sms/sms.h
deleted file mode 100644
index e8a881e0f0d..00000000000
--- a/chromium/third_party/blink/renderer/modules/sms/sms.h
+++ /dev/null
@@ -1,35 +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_SMS_SMS_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_SMS_SMS_H_
-
-#include "base/macros.h"
-#include "mojo/public/cpp/bindings/binding.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 SMS final : public ScriptWrappable {
- DEFINE_WRAPPERTYPEINFO();
-
- public:
- // |content| is the raw content of the SMS message.
- explicit SMS(const WTF::String& content);
-
- ~SMS() override;
-
- // Sms IDL interface.
- const String& content() const;
-
- private:
- const String content_;
-
- DISALLOW_COPY_AND_ASSIGN(SMS);
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SMS_SMS_H_
diff --git a/chromium/third_party/blink/renderer/modules/sms/sms.idl b/chromium/third_party/blink/renderer/modules/sms/sms.idl
deleted file mode 100644
index a3c624b4311..00000000000
--- a/chromium/third_party/blink/renderer/modules/sms/sms.idl
+++ /dev/null
@@ -1,13 +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.
-
-// https://github.com/samuelgoto/sms-receiver
-
-[
- SecureContext,
- Exposed=(Window,DedicatedWorker),
- RuntimeEnabled=SmsReceiver]
-interface SMS {
- readonly attribute DOMString content;
-};
diff --git a/chromium/third_party/blink/renderer/modules/sms/sms_metrics.h b/chromium/third_party/blink/renderer/modules/sms/sms_metrics.h
deleted file mode 100644
index 526da7e15a9..00000000000
--- a/chromium/third_party/blink/renderer/modules/sms/sms_metrics.h
+++ /dev/null
@@ -1,38 +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_SMS_SMS_METRICS_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_SMS_SMS_METRICS_H_
-
-#include <stdint.h>
-
-#include "services/metrics/public/cpp/ukm_source_id.h"
-#include "third_party/blink/public/common/sms/sms_receiver_outcome.h"
-
-namespace base {
-class TimeDelta;
-} // namespace base
-
-namespace ukm {
-class UkmRecorder;
-} // namespace ukm
-
-namespace blink {
-
-// Records the result of a call to the SMSReceiver API.
-void RecordSMSOutcome(SMSReceiverOutcome outcome,
- ukm::SourceId source_id,
- ukm::UkmRecorder* ukm_recorder);
-
-// Records the time from when the API is called to when the user successfully
-// receives the SMS and presses continue to move on with the verification flow.
-void RecordSMSSuccessTime(base::TimeDelta duration);
-
-// Records the time from when the API is called to when the user presses the
-// cancel button to abort SMS retrieval.
-void RecordSMSCancelTime(base::TimeDelta duration);
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SMS_SMS_METRICS_H_
diff --git a/chromium/third_party/blink/renderer/modules/sms/sms_receiver.cc b/chromium/third_party/blink/renderer/modules/sms/sms_receiver.cc
deleted file mode 100644
index 2f79b2c90ea..00000000000
--- a/chromium/third_party/blink/renderer/modules/sms/sms_receiver.cc
+++ /dev/null
@@ -1,145 +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/modules/sms/sms_receiver.h"
-
-#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
-#include "third_party/blink/public/mojom/sms/sms_receiver.mojom-blink.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/abort_signal.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_frame.h"
-#include "third_party/blink/renderer/modules/sms/sms.h"
-#include "third_party/blink/renderer/modules/sms/sms_metrics.h"
-#include "third_party/blink/renderer/modules/sms/sms_receiver_options.h"
-#include "third_party/blink/renderer/platform/bindings/name_client.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/heap/persistent.h"
-#include "third_party/blink/renderer/platform/wtf/functional.h"
-
-namespace blink {
-
-SMSReceiver::SMSReceiver(ExecutionContext* context) : ContextClient(context) {}
-
-SMSReceiver::~SMSReceiver() = default;
-
-ScriptPromise SMSReceiver::receive(ScriptState* script_state,
- const SMSReceiverOptions* options,
- ExceptionState& exception_state) {
- ExecutionContext* context = ExecutionContext::From(script_state);
- DCHECK(context->IsContextThread());
-
- LocalFrame* frame = GetFrame();
- if (!frame) {
- exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
- "Script context has shut down.");
- return ScriptPromise();
- }
-
- if (!frame->IsMainFrame() && frame->IsCrossOriginSubframe()) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kNotAllowedError,
- "Must have the same origin as the top-level frame.");
- return ScriptPromise();
- }
-
- if (options->hasSignal() && options->signal()->aborted()) {
- RecordSMSOutcome(SMSReceiverOutcome::kAborted, GetDocument()->UkmSourceID(),
- GetDocument()->UkmRecorder());
- exception_state.ThrowDOMException(DOMExceptionCode::kAbortError,
- "Request has been aborted.");
- return ScriptPromise();
- }
-
- auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
-
- if (options->hasSignal()) {
- options->signal()->AddAlgorithm(WTF::Bind(&SMSReceiver::Abort,
- WrapWeakPersistent(this),
- WrapPersistent(resolver)));
- }
-
- requests_.insert(resolver);
-
- // See https://bit.ly/2S0zRAS for task types.
- scoped_refptr<base::SingleThreadTaskRunner> task_runner =
- GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI);
-
- if (!service_) {
- GetExecutionContext()->GetBrowserInterfaceBroker().GetInterface(
- service_.BindNewPipeAndPassReceiver(task_runner));
- service_.set_disconnect_handler(WTF::Bind(
- &SMSReceiver::OnSMSReceiverConnectionError, WrapWeakPersistent(this)));
- }
-
- service_->Receive(
- WTF::Bind(&SMSReceiver::OnReceive, WrapPersistent(this),
- WrapPersistent(resolver), base::TimeTicks::Now()));
-
- return resolver->Promise();
-}
-
-void SMSReceiver::Abort(ScriptPromiseResolver* resolver) {
- RecordSMSOutcome(SMSReceiverOutcome::kAborted, GetDocument()->UkmSourceID(),
- GetDocument()->UkmRecorder());
- service_->Abort();
-
- resolver->Reject(
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError));
-
- requests_.erase(resolver);
-}
-
-void SMSReceiver::OnReceive(ScriptPromiseResolver* resolver,
- base::TimeTicks start_time,
- mojom::blink::SmsStatus status,
- const WTF::String& sms) {
- requests_.erase(resolver);
-
- ukm::SourceId source_id = GetDocument()->UkmSourceID();
- ukm::UkmRecorder* recorder = GetDocument()->UkmRecorder();
-
- if (status == mojom::blink::SmsStatus::kTimeout) {
- resolver->Reject(MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kTimeoutError, "SMSReceiver timed out."));
- RecordSMSOutcome(SMSReceiverOutcome::kTimeout, source_id, recorder);
- return;
- } else if (status == mojom::blink::SmsStatus::kCancelled) {
- resolver->Reject(MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kAbortError, "SMSReceiver was aborted."));
- RecordSMSCancelTime(base::TimeTicks::Now() - start_time);
- RecordSMSOutcome(SMSReceiverOutcome::kCancelled, source_id, recorder);
- return;
- }
-
- RecordSMSSuccessTime(base::TimeTicks::Now() - start_time);
- RecordSMSOutcome(SMSReceiverOutcome::kSuccess, source_id, recorder);
-
- resolver->Resolve(MakeGarbageCollected<blink::SMS>(sms));
-}
-
-void SMSReceiver::OnSMSReceiverConnectionError() {
- service_.reset();
- for (ScriptPromiseResolver* request : requests_) {
- request->Reject(MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotFoundError, "SMSReceiver not available."));
- RecordSMSOutcome(SMSReceiverOutcome::kConnectionError,
- GetDocument()->UkmSourceID(),
- GetDocument()->UkmRecorder());
- }
- requests_.clear();
-}
-
-void SMSReceiver::Trace(Visitor* visitor) {
- ScriptWrappable::Trace(visitor);
- ContextClient::Trace(visitor);
- visitor->Trace(requests_);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/sms/sms_receiver.h b/chromium/third_party/blink/renderer/modules/sms/sms_receiver.h
deleted file mode 100644
index 87f1ee27a3b..00000000000
--- a/chromium/third_party/blink/renderer/modules/sms/sms_receiver.h
+++ /dev/null
@@ -1,56 +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_SMS_SMS_RECEIVER_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_SMS_SMS_RECEIVER_H_
-
-#include "base/macros.h"
-#include "mojo/public/cpp/bindings/remote.h"
-#include "third_party/blink/public/mojom/sms/sms_receiver.mojom-blink.h"
-#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
-#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
-#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
-
-namespace blink {
-
-class SMSReceiverOptions;
-class ScriptPromiseResolver;
-
-class SMSReceiver final : public ScriptWrappable, public ContextClient {
- USING_GARBAGE_COLLECTED_MIXIN(SMSReceiver);
- DEFINE_WRAPPERTYPEINFO();
-
- public:
- explicit SMSReceiver(ExecutionContext*);
-
- ~SMSReceiver() override;
-
- // SMSReceiver IDL interface.
- ScriptPromise receive(ScriptState*,
- const SMSReceiverOptions*,
- ExceptionState&);
-
- void Trace(blink::Visitor*) override;
-
- private:
- HeapHashSet<Member<ScriptPromiseResolver>> requests_;
-
- void Abort(ScriptPromiseResolver* resolver);
-
- void OnReceive(ScriptPromiseResolver* resolver,
- base::TimeTicks start_time,
- mojom::blink::SmsStatus status,
- const WTF::String& sms);
-
- void OnSMSReceiverConnectionError();
-
- mojo::Remote<mojom::blink::SmsReceiver> service_;
-
- DISALLOW_COPY_AND_ASSIGN(SMSReceiver);
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SMS_SMS_RECEIVER_H_
diff --git a/chromium/third_party/blink/renderer/modules/sms/sms_receiver.idl b/chromium/third_party/blink/renderer/modules/sms/sms_receiver.idl
deleted file mode 100644
index 677c4bd398d..00000000000
--- a/chromium/third_party/blink/renderer/modules/sms/sms_receiver.idl
+++ /dev/null
@@ -1,14 +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.
-
-// https://github.com/samuelgoto/sms-receiver
-
-[
- SecureContext,
- Exposed=Window,
- RuntimeEnabled=SmsReceiver
-] interface SMSReceiver {
- [CallWith=ScriptState, RaisesException, MeasureAs=SMSReceiverStart]
- Promise<SMS> receive(optional SMSReceiverOptions options);
-};
diff --git a/chromium/third_party/blink/renderer/modules/speech/DEPS b/chromium/third_party/blink/renderer/modules/speech/DEPS
index 04e6d625efe..f26ccc26d7c 100644
--- a/chromium/third_party/blink/renderer/modules/speech/DEPS
+++ b/chromium/third_party/blink/renderer/modules/speech/DEPS
@@ -5,5 +5,4 @@ include_rules = [
"+third_party/blink/renderer/modules/modules_export.h",
"+third_party/blink/renderer/modules/mediastream",
"+third_party/blink/renderer/modules/speech",
- "+mojo/public/cpp/bindings/binding.h"
]
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
index 31f511c1e6d..912fda21f85 100644
--- 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
@@ -63,7 +63,7 @@ SpeechSynthesis* DOMWindowSpeechSynthesis::speechSynthesis(
return DOMWindowSpeechSynthesis::From(window).speechSynthesis(script_state);
}
-void DOMWindowSpeechSynthesis::Trace(blink::Visitor* visitor) {
+void DOMWindowSpeechSynthesis::Trace(Visitor* visitor) {
visitor->Trace(speech_synthesis_);
Supplement<LocalDOMWindow>::Trace(visitor);
}
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
index c139bce73d9..d215de871db 100644
--- 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
@@ -49,7 +49,7 @@ class MODULES_EXPORT DOMWindowSpeechSynthesis final
static SpeechSynthesis* speechSynthesis(ScriptState*, LocalDOMWindow&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void SetSpeechSynthesisForTesting(SpeechSynthesis*);
diff --git a/chromium/third_party/blink/renderer/modules/speech/idls.gni b/chromium/third_party/blink/renderer/modules/speech/idls.gni
new file mode 100644
index 00000000000..e8020109c1d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/speech/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "speech_grammar.idl",
+ "speech_grammar_list.idl",
+ "speech_recognition.idl",
+ "speech_recognition_alternative.idl",
+ "speech_recognition_error_event.idl",
+ "speech_recognition_event.idl",
+ "speech_recognition_result.idl",
+ "speech_recognition_result_list.idl",
+ "speech_synthesis.idl",
+ "speech_synthesis_error_event.idl",
+ "speech_synthesis_event.idl",
+ "speech_synthesis_utterance.idl",
+ "speech_synthesis_voice.idl",
+]
+
+modules_dictionary_idl_files = [
+ "speech_recognition_error_event_init.idl",
+ "speech_recognition_event_init.idl",
+ "speech_synthesis_error_event_init.idl",
+ "speech_synthesis_event_init.idl",
+]
+
+modules_dependency_idl_files = [
+ "window_speech.idl",
+ "window_speech_synthesis.idl",
+]
+
+modules_testing_dependency_idl_files =
+ [ "testing/internals_speech_synthesis.idl" ]
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_grammar.cc b/chromium/third_party/blink/renderer/modules/speech/speech_grammar.cc
index fba694147e1..7fd2c15771d 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_grammar.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_grammar.cc
@@ -39,7 +39,7 @@ SpeechGrammar* SpeechGrammar::Create(const KURL& src, double weight) {
}
void SpeechGrammar::setSrc(ScriptState* script_state, const String& src) {
- Document* document = To<Document>(ExecutionContext::From(script_state));
+ Document* document = Document::From(ExecutionContext::From(script_state));
src_ = document->CompleteURL(src);
}
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_grammar.idl b/chromium/third_party/blink/renderer/modules/speech/speech_grammar.idl
index 3d922c0d192..22bdec54b31 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_grammar.idl
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_grammar.idl
@@ -26,10 +26,12 @@
// https://w3c.github.io/speech-api/#speechgrammar
[
- Constructor,
- Measure,
+ LegacyWindowAlias=webkitSpeechGrammar,
+ LegacyWindowAlias_Measure,
+ LegacyWindowAlias_RuntimeEnabled=ScriptedSpeechRecognition,
NoInterfaceObject
] interface SpeechGrammar {
+ [Measure] constructor();
[URL,CallWith=ScriptState] attribute DOMString src;
attribute float weight;
};
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 c4cebb4a753..c8328244833 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
@@ -45,7 +45,7 @@ SpeechGrammar* SpeechGrammarList::item(unsigned index) const {
void SpeechGrammarList::addFromUri(ScriptState* script_state,
const String& src,
double weight) {
- Document* document = To<Document>(ExecutionContext::From(script_state));
+ Document* document = Document::From(ExecutionContext::From(script_state));
grammars_.push_back(
SpeechGrammar::Create(document->CompleteURL(src), weight));
}
@@ -59,7 +59,7 @@ void SpeechGrammarList::addFromString(const String& string, double weight) {
SpeechGrammarList::SpeechGrammarList() = default;
-void SpeechGrammarList::Trace(blink::Visitor* visitor) {
+void SpeechGrammarList::Trace(Visitor* visitor) {
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 14978bac681..8592a9abc73 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
HeapVector<Member<SpeechGrammar>> grammars_;
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.idl b/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.idl
index cdc19d4f3dd..0ca57de48a5 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.idl
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.idl
@@ -26,10 +26,12 @@
// https://w3c.github.io/speech-api/#speechgrammarlist
[
- Constructor,
- Measure,
+ LegacyWindowAlias=webkitSpeechGrammarList,
+ LegacyWindowAlias_Measure,
+ LegacyWindowAlias_RuntimeEnabled=ScriptedSpeechRecognition,
NoInterfaceObject
] interface SpeechGrammarList {
+ [Measure] constructor();
readonly attribute unsigned long length;
[Measure] getter SpeechGrammar item(unsigned long index);
[CallWith=ScriptState, Measure] void addFromUri(DOMString src, optional float weight);
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 ea507a2a1a4..a7632906aa4 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition.cc
@@ -31,20 +31,22 @@
#include "mojo/public/cpp/bindings/pending_remote.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/page/page.h"
#include "third_party/blink/renderer/modules/speech/speech_recognition_controller.h"
#include "third_party/blink/renderer/modules/speech/speech_recognition_error_event.h"
#include "third_party/blink/renderer/modules/speech/speech_recognition_event.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
SpeechRecognition* SpeechRecognition::Create(ExecutionContext* context) {
- Document& document = To<Document>(*context);
+ Document& document = Document::From(*context);
return MakeGarbageCollected<SpeechRecognition>(document.GetFrame(), context);
}
void SpeechRecognition::start(ExceptionState& exception_state) {
- if (!controller_)
+ if (!controller_ || !GetExecutionContext())
return;
if (started_) {
@@ -55,18 +57,20 @@ void SpeechRecognition::start(ExceptionState& exception_state) {
final_results_.clear();
- // See https://bit.ly/2S0zRAS for task types.
- scoped_refptr<base::SingleThreadTaskRunner> task_runner =
- GetExecutionContext()->GetTaskRunner(blink::TaskType::kMiscPlatformAPI);
mojo::PendingRemote<mojom::blink::SpeechRecognitionSessionClient>
session_client;
- receiver_.Bind(session_client.InitWithNewPipeAndPassReceiver(), task_runner);
+ // See https://bit.ly/2S0zRAS for task types.
+ receiver_.Bind(
+ session_client.InitWithNewPipeAndPassReceiver(),
+ GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI));
receiver_.set_disconnect_handler(WTF::Bind(
&SpeechRecognition::OnConnectionError, WrapWeakPersistent(this)));
- controller_->Start(session_.BindNewPipeAndPassReceiver(),
- std::move(session_client), *grammars_, lang_, continuous_,
- interim_results_, max_alternatives_);
+ controller_->Start(
+ session_.BindNewPipeAndPassReceiver(
+ GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI)),
+ std::move(session_client), *grammars_, lang_, continuous_,
+ interim_results_, max_alternatives_);
started_ = true;
}
@@ -107,7 +111,7 @@ void SpeechRecognition::ResultRetrieved(
HeapVector<Member<SpeechRecognitionAlternative>> alternatives;
alternatives.ReserveInitialCapacity(result->hypotheses.size());
for (const auto& hypothesis : result->hypotheses) {
- alternatives.push_back(SpeechRecognitionAlternative::Create(
+ alternatives.push_back(MakeGarbageCollected<SpeechRecognitionAlternative>(
hypothesis->utterance, hypothesis->confidence));
}
aggregated_results.push_back(SpeechRecognitionResult::Create(
@@ -179,13 +183,11 @@ const AtomicString& SpeechRecognition::InterfaceName() const {
}
ExecutionContext* SpeechRecognition::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
-void SpeechRecognition::ContextDestroyed(ExecutionContext*) {
+void SpeechRecognition::ContextDestroyed() {
controller_ = nullptr;
- receiver_.reset();
- session_.reset();
}
bool SpeechRecognition::HasPendingActivity() const {
@@ -208,7 +210,7 @@ void SpeechRecognition::OnConnectionError() {
SpeechRecognition::SpeechRecognition(LocalFrame* frame,
ExecutionContext* context)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
PageVisibilityObserver(frame ? frame->GetPage() : nullptr),
grammars_(SpeechGrammarList::Create()), // FIXME: The spec is not clear
// on the default value for the
@@ -219,16 +221,19 @@ SpeechRecognition::SpeechRecognition(LocalFrame* frame,
controller_(SpeechRecognitionController::From(frame)),
started_(false),
stopping_(false),
- receiver_(this) {}
+ receiver_(this, context),
+ session_(context) {}
SpeechRecognition::~SpeechRecognition() = default;
-void SpeechRecognition::Trace(blink::Visitor* visitor) {
+void SpeechRecognition::Trace(Visitor* visitor) {
visitor->Trace(grammars_);
visitor->Trace(controller_);
visitor->Trace(final_results_);
+ visitor->Trace(receiver_);
+ visitor->Trace(session_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
PageVisibilityObserver::Trace(visitor);
}
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 a849c046819..66636447be9 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition.h
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition.h
@@ -31,13 +31,15 @@
#include "third_party/blink/public/mojom/speech/speech_recognizer.mojom-blink.h"
#include "third_party/blink/public/platform/web_private_ptr.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/page/page_visibility_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/modules/speech/speech_grammar_list.h"
#include "third_party/blink/renderer/modules/speech/speech_recognition_result.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/wtf/text/wtf_string.h"
namespace blink {
@@ -50,7 +52,7 @@ class SpeechRecognitionController;
class MODULES_EXPORT SpeechRecognition final
: public EventTargetWithInlineData,
public ActiveScriptWrappable<SpeechRecognition>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public mojom::blink::SpeechRecognitionSessionClient,
public PageVisibilityObserver {
USING_GARBAGE_COLLECTED_MIXIN(SpeechRecognition);
@@ -102,8 +104,8 @@ class MODULES_EXPORT SpeechRecognition final
// ScriptWrappable
bool HasPendingActivity() const final;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
// PageVisibilityObserver
void PageVisibilityChanged() override;
@@ -120,7 +122,7 @@ class MODULES_EXPORT SpeechRecognition final
DEFINE_ATTRIBUTE_EVENT_LISTENER(start, kStart)
DEFINE_ATTRIBUTE_EVENT_LISTENER(end, kEnd)
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void OnConnectionError();
@@ -135,8 +137,8 @@ class MODULES_EXPORT SpeechRecognition final
bool started_;
bool stopping_;
HeapVector<Member<SpeechRecognitionResult>> final_results_;
- mojo::Receiver<mojom::blink::SpeechRecognitionSessionClient> receiver_;
- mojo::Remote<mojom::blink::SpeechRecognitionSession> session_;
+ HeapMojoReceiver<mojom::blink::SpeechRecognitionSessionClient> receiver_;
+ HeapMojoRemote<mojom::blink::SpeechRecognitionSession> session_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition.idl b/chromium/third_party/blink/renderer/modules/speech/speech_recognition.idl
index bc93835f2fe..de359f83725 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition.idl
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition.idl
@@ -27,11 +27,12 @@
[
ActiveScriptWrappable,
- Constructor,
- ConstructorCallWith=ExecutionContext,
- Measure,
+ LegacyWindowAlias=webkitSpeechRecognition,
+ LegacyWindowAlias_Measure,
+ LegacyWindowAlias_RuntimeEnabled=ScriptedSpeechRecognition,
NoInterfaceObject
] interface SpeechRecognition : EventTarget {
+ [CallWith=ExecutionContext, Measure] constructor();
// recognition parameters
[Measure] attribute SpeechGrammarList grammars;
attribute DOMString lang;
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_alternative.cc b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_alternative.cc
index e2dddb608fe..a4844e3dcac 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_alternative.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_alternative.cc
@@ -27,13 +27,6 @@
namespace blink {
-SpeechRecognitionAlternative* SpeechRecognitionAlternative::Create(
- const String& transcript,
- double confidence) {
- return MakeGarbageCollected<SpeechRecognitionAlternative>(transcript,
- confidence);
-}
-
SpeechRecognitionAlternative::SpeechRecognitionAlternative(
const String& transcript,
double confidence)
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_alternative.h b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_alternative.h
index 1a7e21e8b07..98dacdc23f7 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_alternative.h
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_alternative.h
@@ -37,8 +37,6 @@ class MODULES_EXPORT SpeechRecognitionAlternative final
DEFINE_WRAPPERTYPEINFO();
public:
- static SpeechRecognitionAlternative* Create(const String&, double);
-
SpeechRecognitionAlternative(const String&, double);
const String& transcript() const { return transcript_; }
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 40ff86dcb07..8c917b5ebde 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
@@ -31,6 +31,7 @@
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/modules/speech/speech_grammar_list.h"
#include "third_party/blink/renderer/modules/speech/speech_recognition.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
@@ -44,11 +45,6 @@ SpeechRecognitionController::~SpeechRecognitionController() {
// FIXME: Call m_client->pageDestroyed(); once we have implemented a client.
}
-SpeechRecognitionController* SpeechRecognitionController::Create(
- LocalFrame& frame) {
- return MakeGarbageCollected<SpeechRecognitionController>(frame);
-}
-
void SpeechRecognitionController::Start(
mojo::PendingReceiver<mojom::blink::SpeechRecognitionSession>
session_receiver,
@@ -78,7 +74,7 @@ void SpeechRecognitionController::Start(
void ProvideSpeechRecognitionTo(LocalFrame& frame) {
SpeechRecognitionController::ProvideTo(
- frame, SpeechRecognitionController::Create(frame));
+ frame, MakeGarbageCollected<SpeechRecognitionController>(frame));
}
mojo::Remote<mojom::blink::SpeechRecognizer>&
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 1c3c658e95d..4991ced398c 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
@@ -60,7 +60,6 @@ class SpeechRecognitionController final
bool interim_results,
uint32_t max_alternatives);
- static SpeechRecognitionController* Create(LocalFrame& frame);
static SpeechRecognitionController* From(LocalFrame* frame) {
return Supplement<LocalFrame>::From<SpeechRecognitionController>(frame);
}
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 a8f68f994f7..7bb2fba5917 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
@@ -27,9 +27,9 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_RECOGNITION_ERROR_EVENT_H_
#include "third_party/blink/public/mojom/speech/speech_recognition_error_code.mojom-blink-forward.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_speech_recognition_error_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/modules/speech/speech_recognition_error_event_init.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -54,7 +54,7 @@ class MODULES_EXPORT SpeechRecognitionErrorEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor* visitor) override { Event::Trace(visitor); }
+ void Trace(Visitor* visitor) override { Event::Trace(visitor); }
private:
String error_;
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_error_event.idl b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_error_event.idl
index 837251cb42f..c2bd04e96d9 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_error_event.idl
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_error_event.idl
@@ -26,9 +26,12 @@
// https://w3c.github.io/speech-api/#speechrecognitionerrorevent
[
- NoInterfaceObject,
- Constructor(DOMString type, optional SpeechRecognitionErrorEventInit eventInitDict)
+ LegacyWindowAlias=webkitSpeechRecognitionError,
+ LegacyWindowAlias_Measure,
+ LegacyWindowAlias_RuntimeEnabled=ScriptedSpeechRecognition,
+ NoInterfaceObject
] interface SpeechRecognitionErrorEvent : Event {
+ constructor(DOMString type, optional SpeechRecognitionErrorEventInit eventInitDict = {});
readonly attribute DOMString error;
readonly attribute DOMString message;
};
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 682bb5f608c..9e8782da429 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
@@ -81,7 +81,7 @@ SpeechRecognitionEvent::SpeechRecognitionEvent(
SpeechRecognitionEvent::~SpeechRecognitionEvent() = default;
-void SpeechRecognitionEvent::Trace(blink::Visitor* visitor) {
+void SpeechRecognitionEvent::Trace(Visitor* visitor) {
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 44e08c2e6f6..fc1863be3e2 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
@@ -26,8 +26,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_RECOGNITION_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_RECOGNITION_EVENT_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_speech_recognition_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
-#include "third_party/blink/renderer/modules/speech/speech_recognition_event_init.h"
#include "third_party/blink/renderer/modules/speech/speech_recognition_result.h"
#include "third_party/blink/renderer/modules/speech/speech_recognition_result_list.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -66,7 +66,7 @@ class SpeechRecognitionEvent final : public Event {
// Event
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
uint32_t result_index_;
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.idl b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.idl
index e7d1421ee87..4150623acc9 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.idl
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.idl
@@ -26,9 +26,12 @@
// https://w3c.github.io/speech-api/#speechrecognitionevent
[
- NoInterfaceObject,
- Constructor(DOMString type, optional SpeechRecognitionEventInit initDict)
+ LegacyWindowAlias=webkitSpeechRecognitionEvent,
+ LegacyWindowAlias_Measure,
+ LegacyWindowAlias_RuntimeEnabled=ScriptedSpeechRecognition,
+ NoInterfaceObject
] interface SpeechRecognitionEvent : Event {
+ constructor(DOMString type, optional SpeechRecognitionEventInit initDict = {});
readonly attribute unsigned long resultIndex;
readonly attribute SpeechRecognitionResultList? results;
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 4d861bbec8c..40e22e00348 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(blink::Visitor* visitor) {
+void SpeechRecognitionResult::Trace(Visitor* visitor) {
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 570d39e779a..89ffd66ac41 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 ae92bc1a31f..da548bb5ff4 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(blink::Visitor* visitor) {
+void SpeechRecognitionResultList::Trace(Visitor* visitor) {
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 6046b093410..e90cd8af048 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 d929ee915ea..fc643d49c5d 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.cc
@@ -29,6 +29,8 @@
#include "third_party/blink/public/common/browser_interface_broker_proxy.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/renderer/bindings/modules/v8/v8_speech_synthesis_error_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_speech_synthesis_event_init.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.h"
@@ -36,9 +38,7 @@
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/core/timing/performance.h"
#include "third_party/blink/renderer/modules/speech/speech_synthesis_error_event.h"
-#include "third_party/blink/renderer/modules/speech/speech_synthesis_error_event_init.h"
#include "third_party/blink/renderer/modules/speech/speech_synthesis_event.h"
-#include "third_party/blink/renderer/modules/speech/speech_synthesis_event_init.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
namespace blink {
@@ -65,15 +65,19 @@ SpeechSynthesis* SpeechSynthesis::CreateForTesting(
}
SpeechSynthesis::SpeechSynthesis(ExecutionContext* context)
- : ContextClient(context) {
+ : ExecutionContextClient(context),
+ receiver_(this, context),
+ mojom_synthesis_(context) {
DCHECK(!GetExecutionContext() || GetExecutionContext()->IsDocument());
}
void SpeechSynthesis::OnSetVoiceList(
Vector<mojom::blink::SpeechSynthesisVoicePtr> mojom_voices) {
voice_list_.clear();
- for (auto& mojom_voice : mojom_voices)
- voice_list_.push_back(SpeechSynthesisVoice::Create(std::move(mojom_voice)));
+ for (auto& mojom_voice : mojom_voices) {
+ voice_list_.push_back(
+ MakeGarbageCollected<SpeechSynthesisVoice>(std::move(mojom_voice)));
+ }
VoicesDidChange();
}
@@ -102,7 +106,7 @@ bool SpeechSynthesis::paused() const {
void SpeechSynthesis::speak(SpeechSynthesisUtterance* utterance) {
DCHECK(utterance);
- Document* document = To<Document>(GetExecutionContext());
+ Document* document = Document::From(GetExecutionContext());
if (!document)
return;
@@ -192,11 +196,6 @@ void SpeechSynthesis::SentenceBoundaryEventOccurred(
sentence_boundary_string);
}
-void SpeechSynthesis::Dispose() {
- receiver_.reset();
- mojom_synthesis_.reset();
-}
-
void SpeechSynthesis::VoicesDidChange() {
if (GetExecutionContext())
DispatchEvent(*Event::Create(event_type_names::kVoiceschanged));
@@ -288,17 +287,19 @@ SpeechSynthesisUtterance* SpeechSynthesis::CurrentSpeechUtterance() const {
return utterance_queue_.front();
}
-void SpeechSynthesis::Trace(blink::Visitor* visitor) {
+void SpeechSynthesis::Trace(Visitor* visitor) {
+ visitor->Trace(receiver_);
+ visitor->Trace(mojom_synthesis_);
visitor->Trace(voice_list_);
visitor->Trace(utterance_queue_);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
EventTargetWithInlineData::Trace(visitor);
}
bool SpeechSynthesis::GetElapsedTimeMillis(double* millis) {
if (!GetExecutionContext())
return false;
- Document* delegate_document = To<Document>(GetExecutionContext());
+ Document* delegate_document = Document::From(GetExecutionContext());
if (!delegate_document || delegate_document->IsStopped())
return false;
LocalDOMWindow* delegate_dom_window = delegate_document->domWindow();
@@ -310,7 +311,7 @@ bool SpeechSynthesis::GetElapsedTimeMillis(double* millis) {
}
bool SpeechSynthesis::IsAllowedToStartByAutoplay() const {
- Document* document = To<Document>(GetExecutionContext());
+ Document* document = Document::From(GetExecutionContext());
DCHECK(document);
// Note: could check the utterance->volume here, but that could be overriden
@@ -324,29 +325,36 @@ bool SpeechSynthesis::IsAllowedToStartByAutoplay() const {
void SpeechSynthesis::SetMojomSynthesisForTesting(
mojo::PendingRemote<mojom::blink::SpeechSynthesis> mojom_synthesis) {
- mojom_synthesis_.Bind(std::move(mojom_synthesis));
+ mojom_synthesis_.Bind(
+ std::move(mojom_synthesis),
+ GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI));
receiver_.reset();
- mojom_synthesis_->AddVoiceListObserver(receiver_.BindNewPipeAndPassRemote());
+ mojom_synthesis_->AddVoiceListObserver(receiver_.BindNewPipeAndPassRemote(
+ GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI)));
}
void SpeechSynthesis::InitializeMojomSynthesis() {
- DCHECK(!mojom_synthesis_);
-
- auto receiver = mojom_synthesis_.BindNewPipeAndPassReceiver();
+ DCHECK(!mojom_synthesis_.is_bound());
// The frame could be detached. In that case, calls on mojom_synthesis_ will
// just get dropped. That's okay and is simpler than having to null-check
// mojom_synthesis_ before each use.
ExecutionContext* context = GetExecutionContext();
- if (context) {
- context->GetBrowserInterfaceBroker().GetInterface(std::move(receiver));
- }
- mojom_synthesis_->AddVoiceListObserver(receiver_.BindNewPipeAndPassRemote());
+ if (!context)
+ return;
+
+ auto receiver = mojom_synthesis_.BindNewPipeAndPassReceiver(
+ context->GetTaskRunner(TaskType::kMiscPlatformAPI));
+
+ context->GetBrowserInterfaceBroker().GetInterface(std::move(receiver));
+
+ mojom_synthesis_->AddVoiceListObserver(receiver_.BindNewPipeAndPassRemote(
+ context->GetTaskRunner(TaskType::kMiscPlatformAPI)));
}
void SpeechSynthesis::InitializeMojomSynthesisIfNeeded() {
- if (!mojom_synthesis_)
+ if (!mojom_synthesis_.is_bound())
InitializeMojomSynthesis();
}
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 5bc2017c751..d605797ffec 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.h
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.h
@@ -26,24 +26,24 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_SYNTHESIS_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_SYNTHESIS_H_
-#include "mojo/public/cpp/bindings/receiver.h"
-#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/speech/speech_synthesis.mojom-blink-forward.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#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/modules/speech/speech_synthesis_utterance.h"
#include "third_party/blink/renderer/modules/speech/speech_synthesis_voice.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 blink {
class MODULES_EXPORT SpeechSynthesis final
: public EventTargetWithInlineData,
- public ContextClient,
+ public ExecutionContextClient,
public mojom::blink::SpeechSynthesisVoiceListObserver {
DEFINE_WRAPPERTYPEINFO();
- USING_PRE_FINALIZER(SpeechSynthesis, Dispose);
USING_GARBAGE_COLLECTED_MIXIN(SpeechSynthesis);
public:
@@ -68,11 +68,11 @@ class MODULES_EXPORT SpeechSynthesis final
DEFINE_ATTRIBUTE_EVENT_LISTENER(voiceschanged, kVoiceschanged)
ExecutionContext* GetExecutionContext() const override {
- return ContextClient::GetExecutionContext();
+ return ExecutionContextClient::GetExecutionContext();
}
// GarbageCollected
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// mojom::blink::SpeechSynthesisVoiceListObserver
void OnSetVoiceList(
@@ -91,15 +91,11 @@ class MODULES_EXPORT SpeechSynthesis final
unsigned char_index,
unsigned char_length);
- mojo::Remote<mojom::blink::SpeechSynthesis>& MojomSynthesis() {
- return mojom_synthesis_;
+ mojom::blink::SpeechSynthesis* MojomSynthesis() {
+ return mojom_synthesis_.get();
}
private:
- // USING_PRE_FINALIZER interface.
- // Called before the object gets garbage collected.
- void Dispose();
-
void VoicesDidChange();
void StartSpeakingImmediately();
void HandleSpeakingCompleted(SpeechSynthesisUtterance*, bool error_occurred);
@@ -127,9 +123,12 @@ class MODULES_EXPORT SpeechSynthesis final
void InitializeMojomSynthesis();
void InitializeMojomSynthesisIfNeeded();
- mojo::Receiver<mojom::blink::SpeechSynthesisVoiceListObserver> receiver_{
- this};
- mojo::Remote<mojom::blink::SpeechSynthesis> mojom_synthesis_;
+ HeapMojoReceiver<mojom::blink::SpeechSynthesisVoiceListObserver,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ receiver_;
+ HeapMojoRemote<mojom::blink::SpeechSynthesis,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ mojom_synthesis_;
HeapVector<Member<SpeechSynthesisVoice>> voice_list_;
HeapDeque<Member<SpeechSynthesisUtterance>> utterance_queue_;
bool is_paused_ = false;
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event.h b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event.h
index 75122f905e7..d8dbbdc1cda 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event.h
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event.h
@@ -5,8 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_SYNTHESIS_ERROR_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_SYNTHESIS_ERROR_EVENT_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_speech_synthesis_error_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
-#include "third_party/blink/renderer/modules/speech/speech_synthesis_error_event_init.h"
#include "third_party/blink/renderer/modules/speech/speech_synthesis_event.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event.idl b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event.idl
index f766c5b5161..f23c651aa8b 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event.idl
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_error_event.idl
@@ -21,8 +21,8 @@ enum SpeechSynthesisErrorCode {
// https://w3c.github.io/speech-api/#speechsynthesiserrorevent
[
Exposed=Window,
- Constructor(DOMString type, SpeechSynthesisErrorEventInit eventInitDict),
RuntimeEnabled=ScriptedSpeechSynthesis
] interface SpeechSynthesisErrorEvent : SpeechSynthesisEvent {
+ constructor(DOMString type, SpeechSynthesisErrorEventInit eventInitDict);
readonly attribute SpeechSynthesisErrorCode error;
};
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 540ffbfb57a..fa0f6c83794 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(blink::Visitor* visitor) {
+void SpeechSynthesisEvent::Trace(Visitor* visitor) {
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 77ce3b832da..464e583126b 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
@@ -26,8 +26,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_SYNTHESIS_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_SYNTHESIS_EVENT_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_speech_synthesis_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
-#include "third_party/blink/renderer/modules/speech/speech_synthesis_event_init.h"
#include "third_party/blink/renderer/modules/speech/speech_synthesis_utterance.h"
namespace blink {
@@ -56,7 +56,7 @@ class SpeechSynthesisEvent : public Event {
return event_interface_names::kSpeechSynthesisEvent;
}
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<SpeechSynthesisUtterance> utterance_;
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.idl b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.idl
index bfacf03a648..dcc0e0c9b8a 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.idl
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.idl
@@ -25,9 +25,9 @@
// https://w3c.github.io/speech-api/#speechsynthesisevent
[
- RuntimeEnabled=ScriptedSpeechSynthesis,
- Constructor(DOMString type, SpeechSynthesisEventInit eventInitDict)
+ RuntimeEnabled=ScriptedSpeechSynthesis
] interface SpeechSynthesisEvent : Event {
+ constructor(DOMString type, SpeechSynthesisEventInit eventInitDict);
readonly attribute SpeechSynthesisUtterance utterance;
readonly attribute unsigned long charIndex;
readonly attribute unsigned long charLength;
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 fcf5c89ac85..e5f70e63c72 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
@@ -33,6 +33,11 @@
namespace blink {
SpeechSynthesisUtterance* SpeechSynthesisUtterance::Create(
+ ExecutionContext* context) {
+ return MakeGarbageCollected<SpeechSynthesisUtterance>(context, String());
+}
+
+SpeechSynthesisUtterance* SpeechSynthesisUtterance::Create(
ExecutionContext* context,
const String& text) {
return MakeGarbageCollected<SpeechSynthesisUtterance>(context, text);
@@ -40,7 +45,8 @@ SpeechSynthesisUtterance* SpeechSynthesisUtterance::Create(
SpeechSynthesisUtterance::SpeechSynthesisUtterance(ExecutionContext* context,
const String& text)
- : ContextClient(context),
+ : ExecutionContextClient(context),
+ receiver_(this, context),
mojom_utterance_(mojom::blink::SpeechSynthesisUtterance::New()) {
// Set default values. |voice| intentionally left null.
mojom_utterance_->text = text;
@@ -69,10 +75,11 @@ void SpeechSynthesisUtterance::setVoice(SpeechSynthesisVoice* voice) {
mojom_utterance_->voice = voice_ ? voice_->name() : String();
}
-void SpeechSynthesisUtterance::Trace(blink::Visitor* visitor) {
+void SpeechSynthesisUtterance::Trace(Visitor* visitor) {
+ visitor->Trace(receiver_);
visitor->Trace(synthesis_);
visitor->Trace(voice_);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
EventTargetWithInlineData::Trace(visitor);
}
@@ -117,6 +124,10 @@ void SpeechSynthesisUtterance::OnEncounteredSpeakingError() {
}
void SpeechSynthesisUtterance::Start(SpeechSynthesis* synthesis) {
+ ExecutionContext* context = GetExecutionContext();
+ if (!context)
+ return;
+
finished_ = false;
mojom::blink::SpeechSynthesisUtterancePtr mojom_utterance_to_send =
@@ -129,8 +140,10 @@ void SpeechSynthesisUtterance::Start(SpeechSynthesis* synthesis) {
receiver_.reset();
synthesis_ = synthesis;
- synthesis_->MojomSynthesis()->Speak(std::move(mojom_utterance_to_send),
- receiver_.BindNewPipeAndPassRemote());
+ synthesis_->MojomSynthesis()->Speak(
+ std::move(mojom_utterance_to_send),
+ receiver_.BindNewPipeAndPassRemote(
+ context->GetTaskRunner(TaskType::kMiscPlatformAPI)));
// Add a disconnect handler so we can cleanup appropriately.
receiver_.set_disconnect_handler(WTF::Bind(
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 2c6a99eb16a..ed750eb6da9 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
@@ -28,10 +28,11 @@
#include "mojo/public/cpp/bindings/receiver.h"
#include "third_party/blink/public/mojom/speech/speech_synthesis.mojom-blink-forward.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#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/speech/speech_synthesis_voice.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/math_extras.h"
namespace blink {
@@ -39,13 +40,14 @@ class SpeechSynthesis;
class SpeechSynthesisUtterance final
: public EventTargetWithInlineData,
- public ContextClient,
+ public ExecutionContextClient,
public mojom::blink::SpeechSynthesisClient {
DEFINE_WRAPPERTYPEINFO();
USING_PRE_FINALIZER(SpeechSynthesisUtterance, Dispose);
USING_GARBAGE_COLLECTED_MIXIN(SpeechSynthesisUtterance);
public:
+ static SpeechSynthesisUtterance* Create(ExecutionContext*);
static SpeechSynthesisUtterance* Create(ExecutionContext*, const String&);
SpeechSynthesisUtterance(ExecutionContext*, const String&);
@@ -87,10 +89,10 @@ class SpeechSynthesisUtterance final
DEFINE_ATTRIBUTE_EVENT_LISTENER(boundary, kBoundary)
ExecutionContext* GetExecutionContext() const override {
- return ContextClient::GetExecutionContext();
+ return ExecutionContextClient::GetExecutionContext();
}
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// mojom::blink::SpeechSynthesisClient
void OnStartedSpeaking() override;
@@ -115,7 +117,7 @@ class SpeechSynthesisUtterance final
// EventTarget
const AtomicString& InterfaceName() const override;
- mojo::Receiver<mojom::blink::SpeechSynthesisClient> receiver_{this};
+ HeapMojoReceiver<mojom::blink::SpeechSynthesisClient> receiver_;
mojom::blink::SpeechSynthesisUtterancePtr mojom_utterance_;
Member<SpeechSynthesis> synthesis_;
Member<SpeechSynthesisVoice> voice_;
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.idl b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.idl
index 7ceef52c681..4d551066332 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.idl
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.idl
@@ -26,10 +26,9 @@
// https://w3c.github.io/speech-api/#speechsynthesisutterance
[
- Constructor(optional DOMString text = null),
- ConstructorCallWith=ExecutionContext,
RuntimeEnabled=ScriptedSpeechSynthesis
] interface SpeechSynthesisUtterance : EventTarget {
+ [CallWith=ExecutionContext] constructor(optional DOMString text);
attribute DOMString text;
attribute DOMString lang;
attribute SpeechSynthesisVoice? voice;
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_voice.cc b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_voice.cc
index 288eb431866..1d6eba0ba84 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_voice.cc
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_voice.cc
@@ -27,11 +27,6 @@
namespace blink {
-SpeechSynthesisVoice* SpeechSynthesisVoice::Create(
- mojom::blink::SpeechSynthesisVoicePtr voice) {
- return MakeGarbageCollected<SpeechSynthesisVoice>(std::move(voice));
-}
-
SpeechSynthesisVoice::SpeechSynthesisVoice(
mojom::blink::SpeechSynthesisVoicePtr mojom_voice)
: mojom_voice_(std::move(mojom_voice)) {}
diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_voice.h b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_voice.h
index c2de3a058bd..84917358265 100644
--- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_voice.h
+++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_voice.h
@@ -38,9 +38,6 @@ class SpeechSynthesisVoice final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- static SpeechSynthesisVoice* Create(
- mojom::blink::SpeechSynthesisVoicePtr mojom_voice);
-
explicit SpeechSynthesisVoice(
mojom::blink::SpeechSynthesisVoicePtr mojom_voice);
~SpeechSynthesisVoice() override;
diff --git a/chromium/third_party/blink/renderer/modules/speech/window_speech.idl b/chromium/third_party/blink/renderer/modules/speech/window_speech.idl
index 9f30b4fdf65..12f7346cbf4 100644
--- a/chromium/third_party/blink/renderer/modules/speech/window_speech.idl
+++ b/chromium/third_party/blink/renderer/modules/speech/window_speech.idl
@@ -6,10 +6,10 @@
ImplementedAs=DOMWindowSpeech,
RuntimeEnabled=ScriptedSpeechRecognition
] partial interface Window {
- [Measure] attribute SpeechGrammarConstructor webkitSpeechGrammar;
- [Measure] attribute SpeechGrammarListConstructor webkitSpeechGrammarList;
- [Measure] attribute SpeechRecognitionConstructor webkitSpeechRecognition;
+ [DisableInNewIDLCompiler, Measure] attribute SpeechGrammarConstructor webkitSpeechGrammar;
+ [DisableInNewIDLCompiler, Measure] attribute SpeechGrammarListConstructor webkitSpeechGrammarList;
+ [DisableInNewIDLCompiler, Measure] attribute SpeechRecognitionConstructor webkitSpeechRecognition;
// Note that the prefixed variant does not end with "Event".
- [Measure] attribute SpeechRecognitionErrorEventConstructor webkitSpeechRecognitionError;
- [Measure] attribute SpeechRecognitionEventConstructor webkitSpeechRecognitionEvent;
+ [DisableInNewIDLCompiler, Measure] attribute SpeechRecognitionErrorEventConstructor webkitSpeechRecognitionError;
+ [DisableInNewIDLCompiler, Measure] attribute SpeechRecognitionEventConstructor webkitSpeechRecognitionEvent;
};
diff --git a/chromium/third_party/blink/renderer/modules/srcobject/idls.gni b/chromium/third_party/blink/renderer/modules/srcobject/idls.gni
new file mode 100644
index 00000000000..d845a7188e8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/srcobject/idls.gni
@@ -0,0 +1,5 @@
+# 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_dependency_idl_files = [ "html_media_element_src_object.idl" ]
diff --git a/chromium/third_party/blink/renderer/modules/storage/cached_storage_area.cc b/chromium/third_party/blink/renderer/modules/storage/cached_storage_area.cc
index d91fdc2a7d5..1497131f2ab 100644
--- a/chromium/third_party/blink/renderer/modules/storage/cached_storage_area.cc
+++ b/chromium/third_party/blink/renderer/modules/storage/cached_storage_area.cc
@@ -6,12 +6,15 @@
#include <inttypes.h>
+#include <algorithm>
+
+#include "base/bind_helpers.h"
+#include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/rand_util.h"
#include "base/task/post_task.h"
#include "base/trace_event/memory_dump_manager.h"
-#include "mojo/public/cpp/bindings/self_owned_associated_receiver.h"
#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -29,26 +32,6 @@ namespace {
// are serialized on disk.
enum class StorageFormat : uint8_t { UTF16 = 0, Latin1 = 1 };
-class GetAllCallback : public mojom::blink::StorageAreaGetAllCallback {
- public:
- static mojo::PendingAssociatedRemote<mojom::blink::StorageAreaGetAllCallback>
- CreateAndBind(base::OnceCallback<void(bool)> callback) {
- mojo::PendingAssociatedRemote<mojom::blink::StorageAreaGetAllCallback>
- pending_remote;
- mojo::MakeSelfOwnedAssociatedReceiver(
- base::WrapUnique(new GetAllCallback(std::move(callback))),
- pending_remote.InitWithNewEndpointAndPassReceiver());
- return pending_remote;
- }
-
- private:
- explicit GetAllCallback(base::OnceCallback<void(bool)> callback)
- : m_callback(std::move(callback)) {}
- void Complete(bool success) override { std::move(m_callback).Run(success); }
-
- base::OnceCallback<void(bool)> m_callback;
-};
-
// These methods are used to pack and unpack the page_url/storage_area_id into
// source strings to/from the browser.
String PackSource(const KURL& page_url, const String& storage_area_id) {
@@ -65,27 +48,20 @@ void UnpackSource(const String& source,
*storage_area_id = result[1];
}
-} // namespace
-
-// static
-scoped_refptr<CachedStorageArea> CachedStorageArea::CreateForLocalStorage(
- scoped_refptr<const SecurityOrigin> origin,
- mojo::PendingRemote<mojom::blink::StorageArea> area,
- scoped_refptr<base::SingleThreadTaskRunner> ipc_runner,
- InspectorEventListener* listener) {
- return base::AdoptRef(new CachedStorageArea(
- std::move(origin), std::move(area), std::move(ipc_runner), listener));
+// Makes a callback which ignores the |success| result of some async operation
+// but which also holds onto a paused WebScopedVirtualTimePauser until invoked.
+base::OnceCallback<void(bool)> MakeSuccessCallback(
+ CachedStorageArea::Source* source) {
+ WebScopedVirtualTimePauser virtual_time_pauser =
+ source->CreateWebScopedVirtualTimePauser(
+ "CachedStorageArea",
+ WebScopedVirtualTimePauser::VirtualTaskDuration::kNonInstant);
+ virtual_time_pauser.PauseVirtualTime();
+ return WTF::Bind([](WebScopedVirtualTimePauser, bool) {},
+ std::move(virtual_time_pauser));
}
-// static
-scoped_refptr<CachedStorageArea> CachedStorageArea::CreateForSessionStorage(
- scoped_refptr<const SecurityOrigin> origin,
- mojo::PendingAssociatedRemote<mojom::blink::StorageArea> area,
- scoped_refptr<base::SingleThreadTaskRunner> ipc_runner,
- InspectorEventListener* listener) {
- return base::AdoptRef(new CachedStorageArea(
- std::move(origin), std::move(area), std::move(ipc_runner), listener));
-}
+} // namespace
unsigned CachedStorageArea::GetLength() {
EnsureLoaded();
@@ -110,42 +86,29 @@ bool CachedStorageArea::SetItem(const String& key,
// A quick check to reject obviously overbudget items to avoid priming the
// cache.
if ((key.length() + value.length()) * 2 >
- mojom::blink::StorageArea::kPerStorageAreaQuota)
+ mojom::blink::StorageArea::kPerStorageAreaQuota) {
return false;
+ }
EnsureLoaded();
String old_value;
if (!map_->SetItem(key, value, &old_value))
return false;
- // Determine data formats.
- const FormatOption key_format = GetKeyFormat();
const FormatOption value_format = GetValueFormat();
-
- // Ignore mutations to |key| until OnSetItemComplete.
- auto ignore_add_result = ignore_key_mutations_.insert(key, 1);
- if (!ignore_add_result.is_new_entry)
- ignore_add_result.stored_value->value++;
-
base::Optional<Vector<uint8_t>> optional_old_value;
- if (!old_value.IsNull())
+ if (!old_value.IsNull() && should_send_old_value_on_mutations_)
optional_old_value = StringToUint8Vector(old_value, value_format);
-
KURL page_url = source->GetPageUrl();
String source_id = areas_->at(source);
-
- blink::WebScopedVirtualTimePauser virtual_time_pauser =
- source->CreateWebScopedVirtualTimePauser(
- "CachedStorageArea",
- WebScopedVirtualTimePauser::VirtualTaskDuration::kNonInstant);
- virtual_time_pauser.PauseVirtualTime();
- mojo_area_->Put(StringToUint8Vector(key, key_format),
- StringToUint8Vector(value, value_format), optional_old_value,
- PackSource(page_url, source_id),
- WTF::Bind(&CachedStorageArea::OnSetItemComplete,
- weak_factory_.GetWeakPtr(), key,
- std::move(virtual_time_pauser)));
- if (IsSessionStorage() && old_value != value)
+ String source_string = PackSource(page_url, source_id);
+ remote_area_->Put(StringToUint8Vector(key, GetKeyFormat()),
+ StringToUint8Vector(value, value_format),
+ optional_old_value, source_string,
+ MakeSuccessCallback(source));
+ if (!IsSessionStorage())
+ EnqueuePendingMutation(key, value, old_value, source_string);
+ else if (old_value != value)
EnqueueStorageEvent(key, old_value, value, page_url, source_id);
return true;
}
@@ -158,64 +121,54 @@ void CachedStorageArea::RemoveItem(const String& key, Source* source) {
if (!map_->RemoveItem(key, &old_value))
return;
- // Determine data formats.
- const FormatOption key_format = GetKeyFormat();
- const FormatOption value_format = GetValueFormat();
-
- // Ignore mutations to |key| until OnRemoveItemComplete.
- auto ignore_add_result = ignore_key_mutations_.insert(key, 1);
- if (!ignore_add_result.is_new_entry)
- ignore_add_result.stored_value->value++;
-
base::Optional<Vector<uint8_t>> optional_old_value;
if (should_send_old_value_on_mutations_)
- optional_old_value = StringToUint8Vector(old_value, value_format);
-
+ optional_old_value = StringToUint8Vector(old_value, GetValueFormat());
KURL page_url = source->GetPageUrl();
String source_id = areas_->at(source);
-
- blink::WebScopedVirtualTimePauser virtual_time_pauser =
- source->CreateWebScopedVirtualTimePauser(
- "CachedStorageArea",
- WebScopedVirtualTimePauser::VirtualTaskDuration::kNonInstant);
- virtual_time_pauser.PauseVirtualTime();
- mojo_area_->Delete(StringToUint8Vector(key, key_format), optional_old_value,
- PackSource(page_url, source_id),
- WTF::Bind(&CachedStorageArea::OnRemoveItemComplete,
- weak_factory_.GetWeakPtr(), key,
- std::move(virtual_time_pauser)));
-
- if (IsSessionStorage())
+ String source_string = PackSource(page_url, source_id);
+ remote_area_->Delete(StringToUint8Vector(key, GetKeyFormat()),
+ optional_old_value, source_string,
+ MakeSuccessCallback(source));
+ if (!IsSessionStorage())
+ EnqueuePendingMutation(key, String(), old_value, source_string);
+ else
EnqueueStorageEvent(key, old_value, String(), page_url, source_id);
}
void CachedStorageArea::Clear(Source* source) {
DCHECK(areas_->Contains(source));
+ mojo::PendingRemote<mojom::blink::StorageAreaObserver> new_observer;
bool already_empty = false;
if (IsSessionStorage()) {
EnsureLoaded();
already_empty = map_->GetLength() == 0u;
+ } else if (!map_) {
+ // If this is our first operation on the StorageArea, |map_| is null and
+ // |receiver_| is still bound to the initial StorageAreaObserver pipe
+ // created upon CachedStorageArea construction. We rebind |receiver_| here
+ // with a new pipe whose event sequence will be synchronized against the
+ // backend from the exact point at which the impending |DeleteAll()|
+ // operation takes place. The first event observed after this will always
+ // be a corresponding |AllDeleted()| from |source|.
+ DCHECK(pending_mutations_by_source_.IsEmpty());
+ DCHECK(pending_mutations_by_key_.IsEmpty());
+ receiver_.reset();
+ new_observer = receiver_.BindNewPipeAndPassRemote();
}
- // No need to prime the cache in this case.
- Reset();
+
map_ = std::make_unique<StorageAreaMap>(
mojom::blink::StorageArea::kPerStorageAreaQuota);
- ignore_all_mutations_ = true;
KURL page_url = source->GetPageUrl();
String source_id = areas_->at(source);
-
- blink::WebScopedVirtualTimePauser virtual_time_pauser =
- source->CreateWebScopedVirtualTimePauser(
- "CachedStorageArea",
- WebScopedVirtualTimePauser::VirtualTaskDuration::kNonInstant);
- virtual_time_pauser.PauseVirtualTime();
- mojo_area_->DeleteAll(
- PackSource(page_url, source_id),
- WTF::Bind(&CachedStorageArea::OnClearComplete, weak_factory_.GetWeakPtr(),
- std::move(virtual_time_pauser)));
- if (IsSessionStorage() && !already_empty)
+ String source_string = PackSource(page_url, source_id);
+ remote_area_->DeleteAll(source_string, std::move(new_observer),
+ MakeSuccessCallback(source));
+ if (!IsSessionStorage())
+ EnqueuePendingMutation(String(), String(), String(), source_string);
+ else if (!already_empty)
EnqueueStorageEvent(String(), String(), String(), page_url, source_id);
}
@@ -225,37 +178,17 @@ String CachedStorageArea::RegisterSource(Source* source) {
return id;
}
-// LocalStorage constructor.
CachedStorageArea::CachedStorageArea(
+ AreaType type,
scoped_refptr<const SecurityOrigin> origin,
- mojo::PendingRemote<mojom::blink::StorageArea> area,
scoped_refptr<base::SingleThreadTaskRunner> ipc_runner,
- InspectorEventListener* listener)
- : origin_(std::move(origin)),
- inspector_event_listener_(listener),
- mojo_area_remote_(std::move(area), ipc_runner),
- mojo_area_(mojo_area_remote_.get()),
+ StorageNamespace* storage_namespace)
+ : type_(type),
+ origin_(std::move(origin)),
+ storage_namespace_(storage_namespace),
+ ipc_task_runner_(std::move(ipc_runner)),
areas_(MakeGarbageCollected<HeapHashMap<WeakMember<Source>, String>>()) {
- mojo_area_->AddObserver(
- receiver_.BindNewEndpointAndPassRemote(std::move(ipc_runner)));
- base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
- this, "DOMStorage",
- ThreadScheduler::Current()->DeprecatedDefaultTaskRunner());
-}
-
-// SessionStorage constructor.
-CachedStorageArea::CachedStorageArea(
- scoped_refptr<const SecurityOrigin> origin,
- mojo::PendingAssociatedRemote<mojom::blink::StorageArea> area,
- scoped_refptr<base::SingleThreadTaskRunner> ipc_runner,
- InspectorEventListener* listener)
- : origin_(std::move(origin)),
- inspector_event_listener_(listener),
- mojo_area_associated_remote_(std::move(area), ipc_runner),
- mojo_area_(mojo_area_associated_remote_.get()),
- areas_(MakeGarbageCollected<HeapHashMap<WeakMember<Source>, String>>()) {
- mojo_area_->AddObserver(
- receiver_.BindNewEndpointAndPassRemote(std::move(ipc_runner)));
+ BindStorageArea();
base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
this, "DOMStorage",
ThreadScheduler::Current()->DeprecatedDefaultTaskRunner());
@@ -266,85 +199,256 @@ CachedStorageArea::~CachedStorageArea() {
this);
}
-void CachedStorageArea::KeyAdded(const Vector<uint8_t>& key,
- const Vector<uint8_t>& value,
- const String& source) {
- DCHECK(!IsSessionStorage());
- KeyAddedOrChanged(key, value, String(), source);
+void CachedStorageArea::BindStorageArea(
+ mojo::PendingRemote<mojom::blink::StorageArea> new_area) {
+ // Some tests may not provide a StorageNamespace.
+ DCHECK(!remote_area_);
+ if (new_area) {
+ remote_area_.Bind(std::move(new_area), ipc_task_runner_);
+ } else if (storage_namespace_) {
+ storage_namespace_->BindStorageArea(
+ origin_, remote_area_.BindNewPipeAndPassReceiver(ipc_task_runner_));
+ } else {
+ return;
+ }
+
+ receiver_.reset();
+ remote_area_->AddObserver(
+ receiver_.BindNewPipeAndPassRemote(ipc_task_runner_));
}
-void CachedStorageArea::KeyChanged(const Vector<uint8_t>& key,
- const Vector<uint8_t>& new_value,
- const Vector<uint8_t>& old_value,
- const String& source) {
- DCHECK(!IsSessionStorage());
- KeyAddedOrChanged(
- key, new_value,
- Uint8VectorToString(old_value, FormatOption::kLocalStorageDetectFormat),
- source);
+void CachedStorageArea::ResetConnection(
+ mojo::PendingRemote<mojom::blink::StorageArea> new_area) {
+ remote_area_.reset();
+ BindStorageArea(std::move(new_area));
+
+ // If we had not yet initialized a local cache, there's no synchronization to
+ // be done.
+ if (!map_)
+ return;
+
+ std::unique_ptr<StorageAreaMap> old_map;
+ std::swap(map_, old_map);
+ pending_mutations_by_key_.clear();
+ pending_mutations_by_source_.clear();
+
+ // Fully repopulate the cache from the loaded backend state.
+ EnsureLoaded();
+
+ // The data received from the backend may differ from what we had cached
+ // previously. How we proceed depends on the type of storage. First we
+ // compute the full diff between our old cache and the restored cache.
+ struct ValueDelta {
+ String previously_cached_value;
+ String restored_value;
+ };
+ HashMap<String, ValueDelta> deltas;
+ for (unsigned i = 0; i < map_->GetLength(); ++i) {
+ const String key = map_->GetKey(i);
+ const String previously_cached_value = old_map->GetItem(key);
+ const String restored_value = map_->GetItem(key);
+ if (previously_cached_value != restored_value)
+ deltas.insert(key, ValueDelta{previously_cached_value, restored_value});
+ }
+
+ // Make sure we also get values for keys that weren't stored in the backend.
+ for (unsigned i = 0; i < old_map->GetLength(); ++i) {
+ const String key = old_map->GetKey(i);
+ const String previously_cached_value = old_map->GetItem(key);
+ // This key will already be covered if it's also present in the restored
+ // cache.
+ if (!map_->GetItem(key).IsNull())
+ continue;
+ deltas.insert(key, ValueDelta{previously_cached_value, String()});
+ }
+
+ if (!IsSessionStorage()) {
+ // For Local Storage we have no way of knowing whether changes not reflected
+ // by the backend were merely dropped, or if they were landed and
+ // overwritten by another client. For simplicity we treat them as dropped,
+ // use the restored cache without modification, and notify script about any
+ // deltas from the previously cached state.
+ for (const auto& delta : deltas) {
+ EnqueueStorageEvent(delta.key, delta.value.previously_cached_value,
+ delta.value.restored_value, "", "");
+ }
+ return;
+ }
+
+ // For Session Storage, we're the source of truth for our own data, so we
+ // can simply push any needed updates down to the backend and continue
+ // using our previous cache.
+ map_ = std::move(old_map);
+ for (const auto& delta : deltas) {
+ if (delta.value.previously_cached_value.IsNull()) {
+ remote_area_->Delete(
+ StringToUint8Vector(delta.key, GetKeyFormat()),
+ StringToUint8Vector(delta.value.restored_value, GetValueFormat()),
+ /*source=*/"\n", base::DoNothing());
+ } else {
+ const FormatOption value_format = GetValueFormat();
+ remote_area_->Put(
+ StringToUint8Vector(delta.key, GetKeyFormat()),
+ StringToUint8Vector(delta.value.previously_cached_value,
+ value_format),
+ StringToUint8Vector(delta.value.restored_value, value_format),
+ /*source=*/"\n", base::DoNothing());
+ }
+ }
}
-void CachedStorageArea::KeyDeleted(const Vector<uint8_t>& key,
- const Vector<uint8_t>& old_value,
- const String& source) {
+void CachedStorageArea::KeyChanged(
+ const Vector<uint8_t>& key,
+ const Vector<uint8_t>& new_value,
+ const base::Optional<Vector<uint8_t>>& old_value,
+ const String& source) {
DCHECK(!IsSessionStorage());
+
+ String key_string =
+ Uint8VectorToString(key, FormatOption::kLocalStorageDetectFormat);
+ String new_value_string =
+ Uint8VectorToString(new_value, FormatOption::kLocalStorageDetectFormat);
+ String old_value_string;
+ if (old_value) {
+ old_value_string = Uint8VectorToString(
+ *old_value, FormatOption::kLocalStorageDetectFormat);
+ }
+
+ std::unique_ptr<PendingMutation> local_mutation = PopPendingMutation(source);
+ if (map_ && !local_mutation)
+ MaybeApplyNonLocalMutationForKey(key_string, new_value_string);
+
+ // If we did pop a mutation, it had better be for the same key this event
+ // references.
+ DCHECK(!local_mutation || local_mutation->key == key_string);
+
KURL page_url;
String storage_area_id;
UnpackSource(source, &page_url, &storage_area_id);
+ EnqueueStorageEvent(key_string, old_value_string, new_value_string, page_url,
+ storage_area_id);
+}
+
+void CachedStorageArea::KeyChangeFailed(const Vector<uint8_t>& key,
+ const String& source) {
+ DCHECK(!IsSessionStorage());
String key_string =
Uint8VectorToString(key, FormatOption::kLocalStorageDetectFormat);
+ std::unique_ptr<PendingMutation> local_mutation = PopPendingMutation(source);
- bool from_local_area = false;
- String old_value_string =
- Uint8VectorToString(old_value, FormatOption::kLocalStorageDetectFormat);
- for (const auto& area : *areas_) {
- if (area.value == storage_area_id) {
- from_local_area = true;
- break;
- }
- }
- if (map_ && !from_local_area) {
- // This was from another process or the storage area is gone. If the former,
- // remove it from our cache if we haven't already changed it and are waiting
- // for the confirmation callback. In the latter case, we won't do anything
- // because ignore_key_mutations_ won't be updated until the callback runs.
- if (!ignore_all_mutations_ &&
- ignore_key_mutations_.find(key_string) == ignore_key_mutations_.end())
+ // We don't care about failed changes from other clients.
+ if (!local_mutation)
+ return;
+
+ // If we did pop a mutation, it had better be for the same key this event
+ // references.
+ DCHECK_EQ(local_mutation->key, key_string);
+
+ // A pending local mutation was rejected by the backend.
+ String old_value = local_mutation->old_value;
+ auto key_queue_iter = pending_mutations_by_key_.find(key_string);
+ if (key_queue_iter == pending_mutations_by_key_.end()) {
+ // If this was the only pending local mutation for the key, we simply revert
+ // the cache to the stored |old_value|. Note that this may not be the value
+ // originally stored before the corresponding |Put()| which enqueued this
+ // mutation: see logic below and in |MaybeApplyNonLocalMutationForKey()| for
+ // potential updates to the stored |old_value|.
+ DCHECK(map_);
+ String invalid_cached_value = map_->GetItem(key_string);
+ if (old_value.IsNull())
map_->RemoveItem(key_string, nullptr);
+ else
+ map_->SetItemIgnoringQuota(key_string, old_value);
+
+ KURL page_url;
+ String storage_area_id;
+ UnpackSource(source, &page_url, &storage_area_id);
+ EnqueueStorageEvent(key_string, invalid_cached_value, old_value, page_url,
+ storage_area_id);
+ return;
}
- EnqueueStorageEvent(key_string, old_value_string, String(), page_url,
- storage_area_id);
+
+ // This was NOT the only pending local mutation for the key, so its failure
+ // is irrelevant to the current cache state (i.e. something has already
+ // overwritten its local change.) In this case, there's no event to dispatch
+ // and no cache update to make. We do however need to propagate the stored
+ // |old_value| to the next queued PendingMutation so that *it* can restore the
+ // correct value if it fails.
+ key_queue_iter->value.front()->old_value = old_value;
}
-void CachedStorageArea::AllDeleted(const String& source) {
- KURL page_url;
- String storage_area_id;
- UnpackSource(source, &page_url, &storage_area_id);
+void CachedStorageArea::KeyDeleted(
+ const Vector<uint8_t>& key,
+ const base::Optional<Vector<uint8_t>>& old_value,
+ const String& source) {
+ DCHECK(!IsSessionStorage());
- bool from_local_area = false;
- for (const auto& area : *areas_) {
- if (area.value == storage_area_id) {
- from_local_area = true;
- break;
- }
+ String key_string =
+ Uint8VectorToString(key, FormatOption::kLocalStorageDetectFormat);
+ std::unique_ptr<PendingMutation> local_mutation = PopPendingMutation(source);
+
+ if (map_ && !local_mutation)
+ MaybeApplyNonLocalMutationForKey(key_string, String());
+
+ // If we did pop a mutation, it had better be for the same key this event
+ // references.
+ DCHECK(!local_mutation || local_mutation->key == key_string);
+
+ if (old_value) {
+ KURL page_url;
+ String storage_area_id;
+ UnpackSource(source, &page_url, &storage_area_id);
+ EnqueueStorageEvent(
+ key_string,
+ Uint8VectorToString(*old_value,
+ FormatOption::kLocalStorageDetectFormat),
+ String(), page_url, storage_area_id);
}
- if (map_ && !from_local_area && !ignore_all_mutations_) {
- auto old = std::move(map_);
+}
+
+void CachedStorageArea::AllDeleted(bool was_nonempty, const String& source) {
+ std::unique_ptr<PendingMutation> local_mutation = PopPendingMutation(source);
+
+ // Note that if this event was from a local source, we've already cleared the
+ // cache when |Clear()| was called so there's nothing to do other than
+ // broadcast the StorageEvent (see below). Broadcast was deferred until now in
+ // that case because we needed to know whether the StorageArea was actually
+ // non-empty prior to the call.
+ if (!local_mutation) {
map_ = std::make_unique<StorageAreaMap>(
mojom::blink::StorageArea::kPerStorageAreaQuota);
- // We have to retain local additions which happened after this clear
- // operation from another process.
- auto iter = ignore_key_mutations_.begin();
- while (iter != ignore_key_mutations_.end()) {
- String value = old->GetItem(iter->key);
- if (!value.IsNull())
- map_->SetItemIgnoringQuota(iter->key, value);
- ++iter;
+ // Re-apply the most recent local mutations for each key. These must have
+ // occurred after the deletion, because we haven't observed events for them
+ // yet. Since they would eventually need to be restored by those impending
+ // events otherwise, we instead restore them now to avoid observable churn
+ // in the storage state.
+ for (const auto& key_mutations : pending_mutations_by_key_) {
+ DCHECK(!key_mutations.value.empty());
+ PendingMutation* const most_recent_mutation = key_mutations.value.back();
+ if (!most_recent_mutation->new_value.IsNull()) {
+ map_->SetItemIgnoringQuota(key_mutations.key,
+ most_recent_mutation->new_value);
+ }
+
+ // And now the first unacked mutation should revert to an empty value on
+ // failure since that's the state in the backend.
+ key_mutations.value.front()->old_value = String();
}
}
- EnqueueStorageEvent(String(), String(), String(), page_url, storage_area_id);
+
+ // If we did pop a mutation, it had better be from a corresponding |Clear()|,
+ // i.e. with no key value.
+ DCHECK(!local_mutation || local_mutation->key.IsNull());
+
+ if (was_nonempty) {
+ KURL page_url;
+ String storage_area_id;
+ UnpackSource(source, &page_url, &storage_area_id);
+ EnqueueStorageEvent(String(), String(), String(), page_url,
+ storage_area_id);
+ }
}
void CachedStorageArea::ShouldSendOldValueOnMutations(bool value) {
@@ -369,81 +473,87 @@ bool CachedStorageArea::OnMemoryDump(
return true;
}
-void CachedStorageArea::KeyAddedOrChanged(const Vector<uint8_t>& key,
- const Vector<uint8_t>& new_value,
- const String& old_value,
- const String& source) {
- DCHECK(!IsSessionStorage());
- KURL page_url;
- String storage_area_id;
- UnpackSource(source, &page_url, &storage_area_id);
+void CachedStorageArea::EnqueuePendingMutation(const String& key,
+ const String& new_value,
+ const String& old_value,
+ const String& source) {
+ // Track this pending mutation until we observe a corresponding event on
+ // our StorageAreaObserver interface. As long as this operation is pending,
+ // we will effectively ignore other observed mutations on this key. Note that
+ // |old_value| may be updated while this PendingMutation sits in queue, if
+ // non-local mutations are observed while waiting for this local mutation to
+ // be acknowledged. See logic in |MaybeApplyNonLocalMutationForKey()|.
+ auto mutation = std::make_unique<PendingMutation>();
+ mutation->key = key;
+ mutation->new_value = new_value;
+ mutation->old_value = old_value;
+
+ // |key| is null for |Clear()| mutation events.
+ if (!key.IsNull()) {
+ pending_mutations_by_key_.insert(key, Deque<PendingMutation*>())
+ .stored_value->value.push_back(mutation.get());
+ }
+ pending_mutations_by_source_.insert(source, OwnedPendingMutationQueue())
+ .stored_value->value.push_back(std::move(mutation));
+}
+
+std::unique_ptr<CachedStorageArea::PendingMutation>
+CachedStorageArea::PopPendingMutation(const String& source) {
+ auto source_queue_iter = pending_mutations_by_source_.find(source);
+ if (source_queue_iter == pending_mutations_by_source_.end())
+ return nullptr;
+
+ OwnedPendingMutationQueue& mutations_for_source = source_queue_iter->value;
+ DCHECK(!mutations_for_source.IsEmpty());
+ std::unique_ptr<PendingMutation> mutation =
+ std::move(mutations_for_source.front());
+ mutations_for_source.pop_front();
+ if (mutations_for_source.empty())
+ pending_mutations_by_source_.erase(source_queue_iter);
+
+ // If |key| is non-null, the oldest mutation queued for that key MUST be this
+ // mutation, and we remove it as well. If |key| is null, that means |mutation|
+ // was a |DeleteAll()| request and there is no corresponding per-key queue
+ // entry.
+ const String key = mutation->key;
+ if (!key.IsNull()) {
+ auto key_queue_iter = pending_mutations_by_key_.find(key);
+ DCHECK(key_queue_iter != pending_mutations_by_key_.end());
+ DCHECK_EQ(key_queue_iter->value.front(), mutation.get());
+ key_queue_iter->value.pop_front();
+ if (key_queue_iter->value.empty())
+ pending_mutations_by_key_.erase(key_queue_iter);
+ }
- String key_string =
- Uint8VectorToString(key, FormatOption::kLocalStorageDetectFormat);
- String new_value_string =
- Uint8VectorToString(new_value, FormatOption::kLocalStorageDetectFormat);
+ return mutation;
+}
- bool from_local_area = false;
- for (const auto& area : *areas_) {
- if (area.value == storage_area_id) {
- from_local_area = true;
- break;
- }
- }
- if (map_ && !from_local_area) {
- // This was from another process or the storage area is gone. If the former,
- // apply it to our cache if we haven't already changed it and are waiting
- // for the confirmation callback. In the latter case, we won't do anything
- // because ignore_key_mutations_ won't be updated until the callback runs.
- if (!ignore_all_mutations_ &&
- ignore_key_mutations_.find(key_string) == ignore_key_mutations_.end()) {
+void CachedStorageArea::MaybeApplyNonLocalMutationForKey(
+ const String& key,
+ const String& new_value) {
+ DCHECK(map_);
+ auto key_queue_iter = pending_mutations_by_key_.find(key);
+ if (key_queue_iter == pending_mutations_by_key_.end()) {
+ // No pending local mutations, so we can apply this non-local mutation
+ // directly to our cache and then we're done.
+ if (new_value.IsNull()) {
+ map_->RemoveItem(key, nullptr);
+ } else {
// We turn off quota checking here to accommodate the over budget
// allowance that's provided in the browser process.
- map_->SetItemIgnoringQuota(key_string, new_value_string);
+ map_->SetItemIgnoringQuota(key, new_value);
}
- }
- EnqueueStorageEvent(key_string, old_value, new_value_string, page_url,
- storage_area_id);
-}
-void CachedStorageArea::OnSetItemComplete(const String& key,
- WebScopedVirtualTimePauser,
- bool success) {
- if (!success) {
- Reset();
return;
}
- auto it = ignore_key_mutations_.find(key);
- DCHECK(it != ignore_key_mutations_.end());
- if (--it->value == 0)
- ignore_key_mutations_.erase(it);
-}
-
-void CachedStorageArea::OnRemoveItemComplete(const String& key,
- WebScopedVirtualTimePauser,
- bool success) {
- DCHECK(success);
- auto it = ignore_key_mutations_.find(key);
- DCHECK(it != ignore_key_mutations_.end());
- if (--it->value == 0)
- ignore_key_mutations_.erase(it);
-}
-
-void CachedStorageArea::OnClearComplete(WebScopedVirtualTimePauser,
- bool success) {
- DCHECK(success);
- DCHECK(ignore_all_mutations_);
- ignore_all_mutations_ = false;
-}
-
-void CachedStorageArea::OnGetAllComplete(bool success) {
- // Since the GetAll method is synchronous, we need this asynchronously
- // delivered notification to avoid applying changes to the returned array
- // that we already have.
- DCHECK(success);
- DCHECK(ignore_all_mutations_);
- ignore_all_mutations_ = false;
+ // We don't want to apply this mutation yet, possibly ever. We need to wait
+ // until one or more pending local mutations are acknowledged either
+ // successfully or unsuccessfully. For now we stash this non-local mutation in
+ // the |old_value| at the front of the key's queue so we don't lose it. If the
+ // local mutation eventually fails, we may restore the key to this non-local
+ // mutation value.
+ key_queue_iter->value.front()->old_value = new_value;
}
void CachedStorageArea::EnsureLoaded() {
@@ -455,13 +565,14 @@ void CachedStorageArea::EnsureLoaded() {
// problem. See https://crbug.com/915577.
scoped_refptr<CachedStorageArea> keep_alive(this);
base::TimeTicks before = base::TimeTicks::Now();
- ignore_all_mutations_ = true;
- bool success = false;
Vector<mojom::blink::KeyValuePtr> data;
- mojo_area_->GetAll(
- GetAllCallback::CreateAndBind(WTF::Bind(
- &CachedStorageArea::OnGetAllComplete, weak_factory_.GetWeakPtr())),
- &success, &data);
+
+ // We had no cached |map_|, which means |receiver_| was bound to the original
+ // StorageAreaObserver pipe created upon CachedStorageArea construction. We
+ // replace it with a new receiver whose event sequence is synchronized against
+ // the result of |GetAll()| for consistency.
+ receiver_.reset();
+ remote_area_->GetAll(receiver_.BindNewPipeAndPassRemote(), &data);
// Determine data formats.
const FormatOption key_format = GetKeyFormat();
@@ -497,13 +608,6 @@ void CachedStorageArea::EnsureLoaded() {
}
}
-void CachedStorageArea::Reset() {
- map_ = nullptr;
- ignore_key_mutations_.clear();
- ignore_all_mutations_ = false;
- weak_factory_.InvalidateWeakPtrs();
-}
-
CachedStorageArea::FormatOption CachedStorageArea::GetKeyFormat() const {
return IsSessionStorage() ? FormatOption::kSessionStorageForceUTF8
: FormatOption::kLocalStorageDetectFormat;
@@ -515,7 +619,7 @@ CachedStorageArea::FormatOption CachedStorageArea::GetValueFormat() const {
}
bool CachedStorageArea::IsSessionStorage() const {
- return mojo_area_associated_remote_.is_bound();
+ return type_ == AreaType::kSessionStorage;
}
void CachedStorageArea::EnqueueStorageEvent(const String& key,
@@ -523,6 +627,10 @@ void CachedStorageArea::EnqueueStorageEvent(const String& key,
const String& new_value,
const String& url,
const String& storage_area_id) {
+ // Ignore key-change events which aren't actually changing the value.
+ if (!key.IsNull() && new_value == old_value)
+ return;
+
HeapVector<Member<Source>, 1> areas_to_remove_;
for (const auto& area : *areas_) {
if (area.value != storage_area_id) {
@@ -532,8 +640,10 @@ void CachedStorageArea::EnqueueStorageEvent(const String& key,
}
}
areas_->RemoveAll(areas_to_remove_);
- inspector_event_listener_->DidDispatchStorageEvent(origin_.get(), key,
- old_value, new_value);
+ if (storage_namespace_) {
+ storage_namespace_->DidDispatchStorageEvent(origin_.get(), key, old_value,
+ new_value);
+ }
}
// static
diff --git a/chromium/third_party/blink/renderer/modules/storage/cached_storage_area.h b/chromium/third_party/blink/renderer/modules/storage/cached_storage_area.h
index 0373b11cc42..b4e046bd365 100644
--- a/chromium/third_party/blink/renderer/modules/storage/cached_storage_area.h
+++ b/chromium/third_party/blink/renderer/modules/storage/cached_storage_area.h
@@ -6,18 +6,19 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_STORAGE_CACHED_STORAGE_AREA_H_
#include "base/trace_event/memory_dump_provider.h"
-#include "mojo/public/cpp/bindings/associated_receiver.h"
-#include "mojo/public/cpp/bindings/associated_remote.h"
-#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/dom_storage/storage_area.mojom-blink.h"
#include "third_party/blink/public/platform/scheduler/web_scoped_virtual_time_pauser.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/storage/storage_area_map.h"
+#include "third_party/blink/renderer/modules/storage/storage_namespace.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.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/text/wtf_string.h"
namespace blink {
@@ -54,26 +55,15 @@ class MODULES_EXPORT CachedStorageArea
WebScopedVirtualTimePauser::VirtualTaskDuration duration) = 0;
};
- // Used to send events to the InspectorDOMStorageAgent.
- class InspectorEventListener {
- public:
- virtual ~InspectorEventListener() = default;
- virtual void DidDispatchStorageEvent(const SecurityOrigin* origin,
- const String& key,
- const String& old_value,
- const String& new_value) = 0;
+ enum class AreaType {
+ kSessionStorage,
+ kLocalStorage,
};
- static scoped_refptr<CachedStorageArea> CreateForLocalStorage(
- scoped_refptr<const SecurityOrigin> origin,
- mojo::PendingRemote<mojom::blink::StorageArea> area,
- scoped_refptr<base::SingleThreadTaskRunner> ipc_runner,
- InspectorEventListener* listener);
- static scoped_refptr<CachedStorageArea> CreateForSessionStorage(
- scoped_refptr<const SecurityOrigin> origin,
- mojo::PendingAssociatedRemote<mojom::blink::StorageArea> area,
- scoped_refptr<base::SingleThreadTaskRunner> ipc_runner,
- InspectorEventListener* listener);
+ CachedStorageArea(AreaType type,
+ scoped_refptr<const SecurityOrigin> origin,
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_runner,
+ StorageNamespace* storage_namespace);
// These correspond to blink::Storage.
unsigned GetLength();
@@ -98,62 +88,77 @@ class MODULES_EXPORT CachedStorageArea
kSessionStorageForceUTF8
};
- private:
- CachedStorageArea(scoped_refptr<const SecurityOrigin> origin,
- mojo::PendingRemote<mojom::blink::StorageArea> area,
- scoped_refptr<base::SingleThreadTaskRunner> ipc_runner,
- InspectorEventListener* listener);
- CachedStorageArea(
- scoped_refptr<const SecurityOrigin> origin,
- mojo::PendingAssociatedRemote<mojom::blink::StorageArea> area,
- scoped_refptr<base::SingleThreadTaskRunner> ipc_runner,
- InspectorEventListener* listener);
+ mojo::Remote<mojom::blink::StorageArea>& RemoteArea() { return remote_area_; }
+ // Invoked by the owning StorageNamespace the renderer is told to reset its
+ // DOM Storage connections (e.g. to recover from a backend crash). Normally
+ // a new StorageArea pipe is bound through the owning StorageNamespace, but
+ // |new_area| may be provided by test code instead.
+ void ResetConnection(
+ mojo::PendingRemote<mojom::blink::StorageArea> new_area = {});
+
+ void SetRemoteAreaForTesting(
+ mojo::PendingRemote<mojom::blink::StorageArea> area) {
+ remote_area_.Bind(std::move(area));
+ }
+
+ private:
friend class RefCounted<CachedStorageArea>;
~CachedStorageArea() override;
friend class CachedStorageAreaTest;
friend class CachedStorageAreaStringFormatTest;
+ friend class MockStorageArea;
+
+ // Simple structure used to return information about each locally-initiated
+ // mutation on the StorageArea until the mutation is acknowledged by a
+ // corresponding StorageAreaObserver event. See |pending_mutations_by_source_|
+ // and |pending_mutations_by_key_| below.
+ struct PendingMutation {
+ String key;
+ String new_value;
+ String old_value;
+ };
+
+ void BindStorageArea(
+ mojo::PendingRemote<mojom::blink::StorageArea> new_area = {});
- // StorageAreaObserver:
- void KeyAdded(const Vector<uint8_t>& key,
- const Vector<uint8_t>& value,
- const String& source) override;
+ // mojom::blink::StorageAreaObserver:
void KeyChanged(const Vector<uint8_t>& key,
const Vector<uint8_t>& new_value,
- const Vector<uint8_t>& old_value,
+ const base::Optional<Vector<uint8_t>>& old_value,
const String& source) override;
+ void KeyChangeFailed(const Vector<uint8_t>& key,
+ const String& source) override;
void KeyDeleted(const Vector<uint8_t>& key,
- const Vector<uint8_t>& old_value,
+ const base::Optional<Vector<uint8_t>>& old_value,
const String& source) override;
- void AllDeleted(const String& source) override;
+ void AllDeleted(bool was_nonempty, const String& source) override;
void ShouldSendOldValueOnMutations(bool value) override;
// base::trace_event::MemoryDumpProvider:
bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
base::trace_event::ProcessMemoryDump* pmd) override;
- // Common helper for KeyAdded() and KeyChanged()
- void KeyAddedOrChanged(const Vector<uint8_t>& key,
- const Vector<uint8_t>& new_value,
- const String& old_value,
- const String& source);
-
- void OnSetItemComplete(const String& key,
- WebScopedVirtualTimePauser,
- bool success);
- void OnRemoveItemComplete(const String& key,
- WebScopedVirtualTimePauser,
- bool success);
- void OnClearComplete(WebScopedVirtualTimePauser, bool success);
- void OnGetAllComplete(bool success);
+ // Enqueues state regarding a locally-initiated storage mutation which will
+ // eventually be acknowledged by a StorageAreaObserver event targeting
+ // |receiver_|.
+ void EnqueuePendingMutation(const String& key,
+ const String& new_value,
+ const String& old_value,
+ const String& source);
+
+ // Dequeues and returns the oldest PendingMutation from the queue for |source|
+ // if one exists. If there is no pending mutation queued for |source| this
+ // returns null.
+ std::unique_ptr<PendingMutation> PopPendingMutation(const String& source);
+
+ void MaybeApplyNonLocalMutationForKey(const String& key,
+ const String& new_value);
// Synchronously fetches the areas data if it hasn't been fetched already.
void EnsureLoaded();
- // Resets the object back to its newly constructed state.
- void Reset();
-
bool IsSessionStorage() const;
FormatOption GetKeyFormat() const;
FormatOption GetValueFormat() const;
@@ -169,29 +174,49 @@ class MODULES_EXPORT CachedStorageArea
static Vector<uint8_t> StringToUint8Vector(const String& input,
FormatOption format_option);
- scoped_refptr<const SecurityOrigin> origin_;
- InspectorEventListener* inspector_event_listener_;
+ const AreaType type_;
+ const scoped_refptr<const SecurityOrigin> origin_;
+ const WeakPersistent<StorageNamespace> storage_namespace_;
+ const scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner_;
std::unique_ptr<StorageAreaMap> map_;
- HashMap<String, int> ignore_key_mutations_;
- bool ignore_all_mutations_ = false;
+ // Queues of local mutations which are pending browser acknowledgement via
+ // StorageAreaObserver events. This map is keyed by local source ID and owns
+ // the PendingMutation objects.
+ //
+ // Only used for Local Storage. Session Storage operations are confined to
+ // local side-effects and are not acknowledged with StorageAreaObsever events.
+ using OwnedPendingMutationQueue = Deque<std::unique_ptr<PendingMutation>>;
+ HashMap<String, OwnedPendingMutationQueue> pending_mutations_by_source_;
+
+ // Queues of local mutations indexed per key. Every queued value references a
+ // PendingMutation owned by |pending_mutations_by_source_| above.
+ //
+ // These per-key queues exists for two main reasons:
+ //
+ // * As long as a key's queue is non-empty, non-local mutations observed for
+ // the key are ignored.
+ // * Any time a non-local |AllDeleted| (i.e. script |clear()|) is observed,
+ // the most recent mutation for each key is re-applied locally to the
+ // cleared area, as this improves locally script-observable consistency.
+ //
+ // Only used for Local Storage. Session Storage operations are confined to
+ // local side-effects and are not acknowledged with StorageAreaObsever events.
+ HashMap<String, Deque<PendingMutation*>> pending_mutations_by_key_;
// See ShouldSendOldValueOnMutations().
bool should_send_old_value_on_mutations_ = true;
- // Depending on if this is a session storage or local storage area only one of
- // |mojo_area_remote_| and |mojo_area_associated_remote_| will be non-null.
- // Either way |mojo_area_| will be equal to the non-null one.
- mojo::Remote<mojom::blink::StorageArea> mojo_area_remote_;
- mojo::AssociatedRemote<mojom::blink::StorageArea>
- mojo_area_associated_remote_;
- mojom::blink::StorageArea* mojo_area_;
- mojo::AssociatedReceiver<mojom::blink::StorageAreaObserver> receiver_{this};
+ // Connection to the backing implementation of this StorageArea. This is
+ // always bound.
+ mojo::Remote<mojom::blink::StorageArea> remote_area_;
- Persistent<HeapHashMap<WeakMember<Source>, String>> areas_;
+ // Receives StorageAreaObserver events from the StorageArea implementation and
+ // dispatches them to this CachedStorageArea.
+ mojo::Receiver<mojom::blink::StorageAreaObserver> receiver_{this};
- base::WeakPtrFactory<CachedStorageArea> weak_factory_{this};
+ Persistent<HeapHashMap<WeakMember<Source>, String>> areas_;
DISALLOW_COPY_AND_ASSIGN(CachedStorageArea);
};
diff --git a/chromium/third_party/blink/renderer/modules/storage/cached_storage_area_test.cc b/chromium/third_party/blink/renderer/modules/storage/cached_storage_area_test.cc
index 89cb97f28cb..e40dc9ff2a7 100644
--- a/chromium/third_party/blink/renderer/modules/storage/cached_storage_area_test.cc
+++ b/chromium/third_party/blink/renderer/modules/storage/cached_storage_area_test.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/modules/storage/cached_storage_area.h"
+#include "base/memory/scoped_refptr.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/modules/storage/testing/fake_area_source.h"
@@ -15,9 +17,10 @@
namespace blink {
using FormatOption = CachedStorageArea::FormatOption;
+using ::testing::ElementsAre;
+using ::testing::UnorderedElementsAre;
-class CachedStorageAreaTest : public testing::Test,
- public CachedStorageArea::InspectorEventListener {
+class CachedStorageAreaTest : public testing::Test {
public:
const scoped_refptr<SecurityOrigin> kOrigin =
SecurityOrigin::CreateFromString("http://dom_storage/");
@@ -30,15 +33,14 @@ class CachedStorageAreaTest : public testing::Test,
const String kRemoteSource = kPageUrl2.GetString() + "\n" + kRemoteSourceId;
void SetUp() override {
- if (IsSessionStorage()) {
- cached_area_ = CachedStorageArea::CreateForSessionStorage(
- kOrigin, mock_storage_area_.GetAssociatedInterfaceRemote(),
- scheduler::GetSingleThreadTaskRunnerForTesting(), this);
- } else {
- cached_area_ = CachedStorageArea::CreateForLocalStorage(
- kOrigin, mock_storage_area_.GetInterfaceRemote(),
- scheduler::GetSingleThreadTaskRunnerForTesting(), this);
- }
+ const CachedStorageArea::AreaType area_type =
+ IsSessionStorage() ? CachedStorageArea::AreaType::kSessionStorage
+ : CachedStorageArea::AreaType::kLocalStorage;
+ cached_area_ = base::MakeRefCounted<CachedStorageArea>(
+ area_type, kOrigin, scheduler::GetSingleThreadTaskRunnerForTesting(),
+ nullptr);
+ cached_area_->SetRemoteAreaForTesting(
+ mock_storage_area_.GetInterfaceRemote());
source_area_ = MakeGarbageCollected<FakeAreaSource>(kPageUrl);
source_area_id_ = cached_area_->RegisterSource(source_area_);
source_ = kPageUrl.GetString() + "\n" + source_area_id_;
@@ -46,22 +48,12 @@ class CachedStorageAreaTest : public testing::Test,
cached_area_->RegisterSource(source_area2_);
}
- void DidDispatchStorageEvent(const SecurityOrigin* origin,
- const String& key,
- const String& old_value,
- const String& new_value) override {}
-
virtual bool IsSessionStorage() { return false; }
bool IsCacheLoaded() { return cached_area_->map_.get(); }
- bool IsIgnoringAllMutations() { return cached_area_->ignore_all_mutations_; }
-
- void ResetCache() { cached_area_->Reset(); }
-
bool IsIgnoringKeyMutations(const String& key) {
- return cached_area_->ignore_key_mutations_.find(key) !=
- cached_area_->ignore_key_mutations_.end();
+ return cached_area_->pending_mutations_by_key_.Contains(key);
}
static Vector<uint8_t> StringToUint8Vector(const String& input,
@@ -98,6 +90,29 @@ class CachedStorageAreaTest : public testing::Test,
: FormatOption::kLocalStorageDetectFormat);
}
+ MockStorageArea::ObservedPut ObservedPut(const String& key,
+ const String& value,
+ const String& source) {
+ return MockStorageArea::ObservedPut{KeyToUint8Vector(key),
+ ValueToUint8Vector(value), source};
+ }
+
+ MockStorageArea::ObservedDelete ObservedDelete(const String& key,
+ const String& source) {
+ return MockStorageArea::ObservedDelete{KeyToUint8Vector(key), source};
+ }
+
+ FakeAreaSource::Event Event(const String& key,
+ const String& old_value,
+ const String& new_value) {
+ return FakeAreaSource::Event{key, old_value, new_value, ""};
+ }
+
+ void InjectKeyValue(const String& key, const String& value) {
+ mock_storage_area_.InjectKeyValue(KeyToUint8Vector(key),
+ ValueToUint8Vector(value));
+ }
+
protected:
MockStorageArea mock_storage_area_;
Persistent<FakeAreaSource> source_area_;
@@ -134,48 +149,39 @@ TEST_P(CachedStorageAreaTestWithParam, Basics) {
}
TEST_P(CachedStorageAreaTestWithParam, GetLength) {
- // GetLength, we expect to see one call to load in the db.
+ // Expect GetLength to load the cache.
EXPECT_FALSE(IsCacheLoaded());
EXPECT_EQ(0u, cached_area_->GetLength());
EXPECT_TRUE(IsCacheLoaded());
- EXPECT_TRUE(mock_storage_area_.observed_get_all());
- EXPECT_EQ(1u, mock_storage_area_.pending_callbacks_count());
- EXPECT_TRUE(IsIgnoringAllMutations());
- mock_storage_area_.CompleteAllPendingCallbacks();
- mock_storage_area_.Flush();
- EXPECT_FALSE(IsIgnoringAllMutations());
+ EXPECT_EQ(1, mock_storage_area_.observed_get_alls());
}
TEST_P(CachedStorageAreaTestWithParam, GetKey) {
- // GetKey, expect the one call to load.
+ // Expect GetKey to load the cache.
EXPECT_FALSE(IsCacheLoaded());
EXPECT_TRUE(cached_area_->GetKey(2).IsNull());
EXPECT_TRUE(IsCacheLoaded());
- EXPECT_TRUE(mock_storage_area_.observed_get_all());
- EXPECT_EQ(1u, mock_storage_area_.pending_callbacks_count());
+ EXPECT_EQ(1, mock_storage_area_.observed_get_alls());
}
TEST_P(CachedStorageAreaTestWithParam, GetItem) {
- // GetItem, ditto.
+ // Expect GetItem to load the cache.
EXPECT_FALSE(IsCacheLoaded());
EXPECT_TRUE(cached_area_->GetItem(kKey).IsNull());
EXPECT_TRUE(IsCacheLoaded());
- EXPECT_TRUE(mock_storage_area_.observed_get_all());
- EXPECT_EQ(1u, mock_storage_area_.pending_callbacks_count());
+ EXPECT_EQ(1, mock_storage_area_.observed_get_alls());
}
TEST_P(CachedStorageAreaTestWithParam, SetItem) {
- // SetItem, we expect a call to load followed by a call to put in the db.
+ // Expect SetItem to load the cache and then generate a change event.
EXPECT_FALSE(IsCacheLoaded());
EXPECT_TRUE(cached_area_->SetItem(kKey, kValue, source_area_));
- mock_storage_area_.Flush();
EXPECT_TRUE(IsCacheLoaded());
- EXPECT_TRUE(mock_storage_area_.observed_get_all());
- EXPECT_TRUE(mock_storage_area_.observed_put());
- EXPECT_EQ(source_, mock_storage_area_.observed_source());
- EXPECT_EQ(KeyToUint8Vector(kKey), mock_storage_area_.observed_key());
- EXPECT_EQ(ValueToUint8Vector(kValue), mock_storage_area_.observed_value());
- EXPECT_EQ(2u, mock_storage_area_.pending_callbacks_count());
+ EXPECT_EQ(1, mock_storage_area_.observed_get_alls());
+
+ mock_storage_area_.Flush();
+ EXPECT_THAT(mock_storage_area_.observed_puts(),
+ ElementsAre(ObservedPut(kKey, kValue, source_)));
EXPECT_TRUE(source_area_->events.IsEmpty());
if (IsSessionStorage()) {
@@ -198,14 +204,11 @@ TEST_P(CachedStorageAreaTestWithParam, Clear_AlreadyEmpty) {
cached_area_->Clear(source_area_);
mock_storage_area_.Flush();
EXPECT_TRUE(IsCacheLoaded());
- EXPECT_TRUE(mock_storage_area_.observed_delete_all());
- EXPECT_EQ(source_, mock_storage_area_.observed_source());
+ EXPECT_THAT(mock_storage_area_.observed_delete_alls(), ElementsAre(source_));
if (IsSessionStorage()) {
- EXPECT_TRUE(mock_storage_area_.observed_get_all());
- EXPECT_EQ(2u, mock_storage_area_.pending_callbacks_count());
+ EXPECT_EQ(1, mock_storage_area_.observed_get_alls());
} else {
- EXPECT_FALSE(mock_storage_area_.observed_get_all());
- EXPECT_EQ(1u, mock_storage_area_.pending_callbacks_count());
+ EXPECT_EQ(0, mock_storage_area_.observed_get_alls());
}
// Neither should have events since area was already empty.
@@ -214,22 +217,17 @@ TEST_P(CachedStorageAreaTestWithParam, Clear_AlreadyEmpty) {
}
TEST_P(CachedStorageAreaTestWithParam, Clear_WithData) {
- mock_storage_area_.mutable_get_all_return_values().push_back(
- mojom::blink::KeyValue::New(KeyToUint8Vector(kKey),
- ValueToUint8Vector(kValue)));
+ InjectKeyValue(kKey, kValue);
EXPECT_FALSE(IsCacheLoaded());
cached_area_->Clear(source_area_);
mock_storage_area_.Flush();
EXPECT_TRUE(IsCacheLoaded());
- EXPECT_TRUE(mock_storage_area_.observed_delete_all());
- EXPECT_EQ(source_, mock_storage_area_.observed_source());
+ EXPECT_THAT(mock_storage_area_.observed_delete_alls(), ElementsAre(source_));
if (IsSessionStorage()) {
- EXPECT_TRUE(mock_storage_area_.observed_get_all());
- EXPECT_EQ(2u, mock_storage_area_.pending_callbacks_count());
+ EXPECT_EQ(1, mock_storage_area_.observed_get_alls());
} else {
- EXPECT_FALSE(mock_storage_area_.observed_get_all());
- EXPECT_EQ(1u, mock_storage_area_.pending_callbacks_count());
+ EXPECT_EQ(0, mock_storage_area_.observed_get_alls());
}
EXPECT_TRUE(source_area_->events.IsEmpty());
@@ -250,9 +248,8 @@ TEST_P(CachedStorageAreaTestWithParam, RemoveItem_NothingToRemove) {
cached_area_->RemoveItem(kKey, source_area_);
mock_storage_area_.Flush();
EXPECT_TRUE(IsCacheLoaded());
- EXPECT_TRUE(mock_storage_area_.observed_get_all());
- EXPECT_FALSE(mock_storage_area_.observed_delete());
- EXPECT_EQ(1u, mock_storage_area_.pending_callbacks_count());
+ EXPECT_EQ(1, mock_storage_area_.observed_get_alls());
+ EXPECT_TRUE(mock_storage_area_.observed_deletes().IsEmpty());
// Neither should have events since area was already empty.
EXPECT_TRUE(source_area_->events.IsEmpty());
@@ -262,18 +259,15 @@ TEST_P(CachedStorageAreaTestWithParam, RemoveItem_NothingToRemove) {
TEST_P(CachedStorageAreaTestWithParam, RemoveItem) {
// RemoveItem with something to remove, expect a call to load followed
// by a call to remove.
- mock_storage_area_.mutable_get_all_return_values().push_back(
- mojom::blink::KeyValue::New(KeyToUint8Vector(kKey),
- ValueToUint8Vector(kValue)));
+ InjectKeyValue(kKey, kValue);
+
EXPECT_FALSE(IsCacheLoaded());
cached_area_->RemoveItem(kKey, source_area_);
mock_storage_area_.Flush();
EXPECT_TRUE(IsCacheLoaded());
- EXPECT_TRUE(mock_storage_area_.observed_get_all());
- EXPECT_TRUE(mock_storage_area_.observed_delete());
- EXPECT_EQ(source_, mock_storage_area_.observed_source());
- EXPECT_EQ(KeyToUint8Vector(kKey), mock_storage_area_.observed_key());
- EXPECT_EQ(2u, mock_storage_area_.pending_callbacks_count());
+ EXPECT_EQ(1, mock_storage_area_.observed_get_alls());
+ EXPECT_THAT(mock_storage_area_.observed_deletes(),
+ ElementsAre(ObservedDelete(kKey, source_)));
EXPECT_TRUE(source_area_->events.IsEmpty());
if (IsSessionStorage()) {
@@ -288,13 +282,11 @@ TEST_P(CachedStorageAreaTestWithParam, RemoveItem) {
}
TEST_P(CachedStorageAreaTestWithParam, BrowserDisconnect) {
+ InjectKeyValue(kKey, kValue);
+
// GetLength to prime the cache.
- mock_storage_area_.mutable_get_all_return_values().push_back(
- mojom::blink::KeyValue::New(KeyToUint8Vector(kKey),
- ValueToUint8Vector(kValue)));
EXPECT_EQ(1u, cached_area_->GetLength());
EXPECT_TRUE(IsCacheLoaded());
- mock_storage_area_.CompleteAllPendingCallbacks();
mock_storage_area_.ResetObservations();
// Now disconnect the pipe from the browser, simulating situations where the
@@ -309,65 +301,242 @@ TEST_P(CachedStorageAreaTestWithParam, BrowserDisconnect) {
cached_area_->RemoveItem(kKey, source_area_);
EXPECT_EQ(0u, cached_area_->GetLength());
EXPECT_TRUE(cached_area_->GetItem(kKey).IsNull());
-
- // TODO(mek): This should work for session storage too, but for some reason
- // instead just hangs.
- if (!IsSessionStorage()) {
- // Even resetting the cache should still allow class to function properly.
- ResetCache();
- EXPECT_TRUE(cached_area_->GetItem(kKey).IsNull());
- EXPECT_TRUE(cached_area_->SetItem(kKey, kValue, source_area_));
- EXPECT_EQ(1u, cached_area_->GetLength());
- EXPECT_EQ(kValue, cached_area_->GetItem(kKey));
- }
}
-TEST_F(CachedStorageAreaTest, MutationsAreIgnoredUntilLoadCompletion) {
- mojom::blink::StorageAreaObserver* observer = cached_area_.get();
+TEST_P(CachedStorageAreaTestWithParam, ResetConnectionWithNoDelta) {
+ const String kKey1 = "key1";
+ const String kValue1 = "value1";
+ const String kKey2 = "key2";
+ const String kValue2 = "value2";
+ InjectKeyValue(kKey1, kValue1);
+ InjectKeyValue(kKey2, kValue2);
- EXPECT_TRUE(cached_area_->GetItem(kKey).IsNull());
+ // Prime the cache.
+ EXPECT_EQ(2u, cached_area_->GetLength());
EXPECT_TRUE(IsCacheLoaded());
- EXPECT_TRUE(IsIgnoringAllMutations());
+ EXPECT_EQ(1, mock_storage_area_.observed_get_alls());
- // Before load completion, the mutation should be ignored.
- observer->KeyAdded(KeyToUint8Vector(kKey), ValueToUint8Vector(kValue),
- kRemoteSource);
- EXPECT_TRUE(cached_area_->GetItem(kKey).IsNull());
+ // Simulate a connection reset, which should always re-initialize the local
+ // cache.
+ cached_area_->ResetConnection(mock_storage_area_.GetInterfaceRemote());
+ EXPECT_TRUE(IsCacheLoaded());
+ EXPECT_EQ(2, mock_storage_area_.observed_get_alls());
+ EXPECT_EQ(2u, cached_area_->GetLength());
+
+ // Cached values should be unchanged for both Session and Local Storage.
+ EXPECT_EQ(kValue1, cached_area_->GetItem(kKey1));
+ EXPECT_EQ(kValue2, cached_area_->GetItem(kKey2));
- // Call the load completion callback.
- mock_storage_area_.CompleteOnePendingCallback(true);
+ // There should be no observed operations on the backend.
mock_storage_area_.Flush();
- EXPECT_FALSE(IsIgnoringAllMutations());
+ EXPECT_TRUE(mock_storage_area_.observed_puts().IsEmpty());
+ EXPECT_TRUE(mock_storage_area_.observed_deletes().IsEmpty());
- // Verify that mutations are now applied.
- observer->KeyAdded(KeyToUint8Vector(kKey), ValueToUint8Vector(kValue),
- kRemoteSource);
- EXPECT_EQ(kValue, cached_area_->GetItem(kKey));
+ // There should also be no generated storage events.
+ EXPECT_TRUE(source_area_->events.IsEmpty());
}
-TEST_F(CachedStorageAreaTest, MutationsAreIgnoredUntilClearCompletion) {
- cached_area_->Clear(source_area_);
- mock_storage_area_.Flush();
- EXPECT_TRUE(IsIgnoringAllMutations());
- mock_storage_area_.CompleteOnePendingCallback(true);
- mock_storage_area_.Flush();
- EXPECT_FALSE(IsIgnoringAllMutations());
+TEST_P(CachedStorageAreaTestWithParam, ResetConnectionWithKeyDiff) {
+ const String kKey1 = "key1";
+ const String kValue1 = "value1";
+ const String kKey2 = "key2";
+ const String kCachedValue2 = "cached_value2";
+ const String kPersistedValue2 = "persisted_value2";
+ InjectKeyValue(kKey1, kValue1);
+ InjectKeyValue(kKey2, kCachedValue2);
+
+ // Prime the cache.
+ EXPECT_EQ(2u, cached_area_->GetLength());
+ EXPECT_TRUE(IsCacheLoaded());
+ EXPECT_EQ(1, mock_storage_area_.observed_get_alls());
- // Verify that calling Clear twice works as expected, the first
- // completion callback should have been cancelled.
- ResetCache();
- cached_area_->Clear(source_area_);
+ // Now modify the backend so it's out of sync with the cache. Namely, the
+ // value of |kKey2| is no different.
+ mock_storage_area_.Clear();
+ InjectKeyValue(kKey1, kValue1);
+ InjectKeyValue(kKey2, kPersistedValue2);
+
+ // Resetting the connection should re-initialize the local cache, with
+ // different outcomes for Local and Session Storage.
+ cached_area_->ResetConnection(mock_storage_area_.GetInterfaceRemote());
+ EXPECT_TRUE(IsCacheLoaded());
+ EXPECT_EQ(2, mock_storage_area_.observed_get_alls());
+ EXPECT_EQ(2u, cached_area_->GetLength());
+ EXPECT_EQ(kValue1, cached_area_->GetItem(kKey1));
mock_storage_area_.Flush();
- EXPECT_TRUE(IsIgnoringAllMutations());
- cached_area_->Clear(source_area_);
+
+ if (IsSessionStorage()) {
+ // For Session Storage, we expect the local cache to push changes to the
+ // backend, as the local cache is the source of truth.
+ EXPECT_EQ(kCachedValue2, cached_area_->GetItem(kKey2));
+ EXPECT_THAT(mock_storage_area_.observed_puts(),
+ ElementsAre(ObservedPut(kKey2, kCachedValue2, "\n")));
+ EXPECT_TRUE(mock_storage_area_.observed_deletes().IsEmpty());
+ EXPECT_TRUE(source_area_->events.IsEmpty());
+ } else {
+ // For Local Storage, we expect no mutations to the backend but instead a
+ // storage event to be broadcast for the diff.
+ EXPECT_EQ(kPersistedValue2, cached_area_->GetItem(kKey2));
+ EXPECT_TRUE(mock_storage_area_.observed_puts().IsEmpty());
+ EXPECT_TRUE(mock_storage_area_.observed_deletes().IsEmpty());
+ EXPECT_THAT(source_area_->events,
+ ElementsAre(Event(kKey2, kCachedValue2, kPersistedValue2)));
+ }
+}
+
+TEST_P(CachedStorageAreaTestWithParam, ResetConnectionWithMissingBackendKey) {
+ const String kKey1 = "key1";
+ const String kValue1 = "value1";
+ const String kKey2 = "key2";
+ const String kValue2 = "value2";
+ InjectKeyValue(kKey1, kValue1);
+ InjectKeyValue(kKey2, kValue2);
+
+ // Prime the cache.
+ EXPECT_EQ(2u, cached_area_->GetLength());
+ EXPECT_TRUE(IsCacheLoaded());
+ EXPECT_EQ(1, mock_storage_area_.observed_get_alls());
+
+ // Now modify the backend so it's out of sync with the cache. Namely, |kKey2|
+ // is no longer present in the backend.
+ mock_storage_area_.Clear();
+ InjectKeyValue(kKey1, kValue1);
+
+ // Resetting the connection should re-initialize the local cache, with
+ // different outcomes for Local and Session Storage.
+ cached_area_->ResetConnection(mock_storage_area_.GetInterfaceRemote());
+ EXPECT_TRUE(IsCacheLoaded());
+ EXPECT_EQ(2, mock_storage_area_.observed_get_alls());
+ EXPECT_EQ(kValue1, cached_area_->GetItem(kKey1));
mock_storage_area_.Flush();
- EXPECT_TRUE(IsIgnoringAllMutations());
- mock_storage_area_.CompleteOnePendingCallback(true);
+
+ if (IsSessionStorage()) {
+ // For Session Storage, we expect the local cache to push changes to the
+ // backend, as the local cache is the source of truth.
+ EXPECT_EQ(2u, cached_area_->GetLength());
+ EXPECT_EQ(kValue2, cached_area_->GetItem(kKey2));
+ EXPECT_THAT(mock_storage_area_.observed_puts(),
+ ElementsAre(ObservedPut(kKey2, kValue2, "\n")));
+ EXPECT_TRUE(mock_storage_area_.observed_deletes().IsEmpty());
+ EXPECT_TRUE(source_area_->events.IsEmpty());
+ } else {
+ // For Local Storage, we expect no mutations to the backend but instead a
+ // storage event to be broadcast for the diff.
+ EXPECT_EQ(1u, cached_area_->GetLength());
+ EXPECT_TRUE(cached_area_->GetItem(kKey2).IsNull());
+ EXPECT_TRUE(mock_storage_area_.observed_puts().IsEmpty());
+ EXPECT_TRUE(mock_storage_area_.observed_deletes().IsEmpty());
+ EXPECT_THAT(source_area_->events,
+ ElementsAre(Event(kKey2, kValue2, String())));
+ }
+}
+
+TEST_P(CachedStorageAreaTestWithParam, ResetConnectionWithMissingLocalKey) {
+ const String kKey1 = "key1";
+ const String kValue1 = "value1";
+ const String kKey2 = "key2";
+ const String kValue2 = "value2";
+ InjectKeyValue(kKey1, kValue1);
+
+ // Prime the cache.
+ EXPECT_EQ(1u, cached_area_->GetLength());
+ EXPECT_TRUE(IsCacheLoaded());
+ EXPECT_EQ(1, mock_storage_area_.observed_get_alls());
+
+ // Now modify the backend so it's out of sync with the cache. Namely, |kKey2|
+ // is present in the backend despite never being cached locally.
+ InjectKeyValue(kKey2, kValue2);
+
+ // Resetting the connection should re-initialize the local cache, with
+ // different outcomes for Local and Session Storage.
+ cached_area_->ResetConnection(mock_storage_area_.GetInterfaceRemote());
+ EXPECT_TRUE(IsCacheLoaded());
+ EXPECT_EQ(2, mock_storage_area_.observed_get_alls());
+ EXPECT_EQ(kValue1, cached_area_->GetItem(kKey1));
mock_storage_area_.Flush();
- EXPECT_TRUE(IsIgnoringAllMutations());
- mock_storage_area_.CompleteOnePendingCallback(true);
+
+ if (IsSessionStorage()) {
+ // For Session Storage, we expect the local cache to push changes to the
+ // backend, as the local cache is the source of truth.
+ EXPECT_EQ(1u, cached_area_->GetLength());
+ EXPECT_TRUE(cached_area_->GetItem(kKey2).IsNull());
+ EXPECT_THAT(mock_storage_area_.observed_deletes(),
+ ElementsAre(ObservedDelete(kKey2, "\n")));
+ EXPECT_TRUE(mock_storage_area_.observed_puts().IsEmpty());
+ EXPECT_TRUE(source_area_->events.IsEmpty());
+ } else {
+ // For Local Storage, we expect no mutations to the backend but instead a
+ // storage event to be broadcast for the diff.
+ EXPECT_EQ(2u, cached_area_->GetLength());
+ EXPECT_EQ(kValue2, cached_area_->GetItem(kKey2));
+ EXPECT_TRUE(mock_storage_area_.observed_puts().IsEmpty());
+ EXPECT_TRUE(mock_storage_area_.observed_deletes().IsEmpty());
+ EXPECT_THAT(source_area_->events,
+ ElementsAre(Event(kKey2, String(), kValue2)));
+ }
+}
+
+TEST_P(CachedStorageAreaTestWithParam, ResetConnectionWithComplexDiff) {
+ const String kKey1 = "key1";
+ const String kValue1 = "value1";
+ const String kKey2 = "key2";
+ const String kValue2 = "value2";
+ const String kAltValue2 = "alt_value2";
+ const String kKey3 = "key3";
+ const String kValue3 = "value3";
+ const String kKey4 = "key4";
+ const String kValue4 = "value4";
+ InjectKeyValue(kKey1, kValue1);
+ InjectKeyValue(kKey2, kValue2);
+ InjectKeyValue(kKey3, kValue3);
+
+ // Prime the cache.
+ EXPECT_EQ(3u, cached_area_->GetLength());
+ EXPECT_TRUE(IsCacheLoaded());
+ EXPECT_EQ(1, mock_storage_area_.observed_get_alls());
+
+ // Now modify the backend so it's out of sync with the cache. Namely, the
+ // value of |kKey2| differs, |kKey3| is no longer present in the backend, and
+ // |kKey4| is now present where it wasn't before.
+ mock_storage_area_.Clear();
+ InjectKeyValue(kKey1, kValue1);
+ InjectKeyValue(kKey2, kAltValue2);
+ InjectKeyValue(kKey4, kValue4);
+
+ // Resetting the connection should re-initialize the local cache, with
+ // different outcomes for Local and Session Storage.
+ cached_area_->ResetConnection(mock_storage_area_.GetInterfaceRemote());
+ EXPECT_TRUE(IsCacheLoaded());
+ EXPECT_EQ(2, mock_storage_area_.observed_get_alls());
+ EXPECT_EQ(3u, cached_area_->GetLength());
+ EXPECT_EQ(kValue1, cached_area_->GetItem(kKey1));
mock_storage_area_.Flush();
- EXPECT_FALSE(IsIgnoringAllMutations());
+
+ if (IsSessionStorage()) {
+ // For Session Storage, we expect the local cache to push changes to the
+ // backend, as the local cache is the source of truth.
+ EXPECT_EQ(kValue2, cached_area_->GetItem(kKey2));
+ EXPECT_EQ(kValue3, cached_area_->GetItem(kKey3));
+ EXPECT_TRUE(cached_area_->GetItem(kKey4).IsNull());
+ EXPECT_THAT(mock_storage_area_.observed_puts(),
+ UnorderedElementsAre(ObservedPut(kKey2, kValue2, "\n"),
+ ObservedPut(kKey3, kValue3, "\n")));
+ EXPECT_THAT(mock_storage_area_.observed_deletes(),
+ ElementsAre(ObservedDelete(kKey4, "\n")));
+ EXPECT_TRUE(source_area_->events.IsEmpty());
+ } else {
+ // For Local Storage, we expect no mutations to the backend but instead a
+ // storage event to be broadcast for the diff.
+ EXPECT_EQ(kAltValue2, cached_area_->GetItem(kKey2));
+ EXPECT_TRUE(cached_area_->GetItem(kKey3).IsNull());
+ EXPECT_EQ(kValue4, cached_area_->GetItem(kKey4));
+ EXPECT_TRUE(mock_storage_area_.observed_puts().IsEmpty());
+ EXPECT_TRUE(mock_storage_area_.observed_deletes().IsEmpty());
+ EXPECT_THAT(source_area_->events,
+ UnorderedElementsAre(Event(kKey2, kValue2, kAltValue2),
+ Event(kKey3, kValue3, String()),
+ Event(kKey4, String(), kValue4)));
+ }
}
TEST_F(CachedStorageAreaTest, KeyMutationsAreIgnoredUntilCompletion) {
@@ -375,59 +544,58 @@ TEST_F(CachedStorageAreaTest, KeyMutationsAreIgnoredUntilCompletion) {
// SetItem
EXPECT_TRUE(cached_area_->SetItem(kKey, kValue, source_area_));
- mock_storage_area_.CompleteOnePendingCallback(true); // load completion
mock_storage_area_.Flush();
- EXPECT_FALSE(IsIgnoringAllMutations());
EXPECT_TRUE(IsIgnoringKeyMutations(kKey));
- observer->KeyDeleted(KeyToUint8Vector(kKey), {0}, kRemoteSource);
- mock_storage_area_.Flush();
+ observer->KeyDeleted(KeyToUint8Vector(kKey), base::nullopt, kRemoteSource);
+ EXPECT_TRUE(IsIgnoringKeyMutations(kKey));
EXPECT_EQ(kValue, cached_area_->GetItem(kKey));
- mock_storage_area_.CompleteOnePendingCallback(true); // set completion
- mock_storage_area_.Flush();
+ observer->KeyChanged(KeyToUint8Vector(kKey), ValueToUint8Vector(kValue),
+ base::nullopt, source_);
EXPECT_FALSE(IsIgnoringKeyMutations(kKey));
// RemoveItem
cached_area_->RemoveItem(kKey, source_area_);
mock_storage_area_.Flush();
EXPECT_TRUE(IsIgnoringKeyMutations(kKey));
- mock_storage_area_.CompleteOnePendingCallback(true); // remove completion
- mock_storage_area_.Flush();
+ observer->KeyDeleted(KeyToUint8Vector(kKey), ValueToUint8Vector(kValue),
+ source_);
EXPECT_FALSE(IsIgnoringKeyMutations(kKey));
// Multiple mutations to the same key.
EXPECT_TRUE(cached_area_->SetItem(kKey, kValue, source_area_));
cached_area_->RemoveItem(kKey, source_area_);
- mock_storage_area_.Flush();
- EXPECT_TRUE(IsIgnoringKeyMutations(kKey));
- mock_storage_area_.CompleteOnePendingCallback(true); // set completion
- mock_storage_area_.Flush();
EXPECT_TRUE(IsIgnoringKeyMutations(kKey));
- mock_storage_area_.CompleteOnePendingCallback(true); // remove completion
mock_storage_area_.Flush();
+ observer->KeyChanged(KeyToUint8Vector(kKey), ValueToUint8Vector(kValue),
+ base::nullopt, source_);
+ observer->KeyDeleted(KeyToUint8Vector(kKey), ValueToUint8Vector(kValue),
+ source_);
EXPECT_FALSE(IsIgnoringKeyMutations(kKey));
- // A failed set item operation should Reset the cache.
+ // A failed set item operation should reset the key's cached value.
EXPECT_TRUE(cached_area_->SetItem(kKey, kValue, source_area_));
mock_storage_area_.Flush();
EXPECT_TRUE(IsIgnoringKeyMutations(kKey));
- mock_storage_area_.CompleteOnePendingCallback(false);
- mock_storage_area_.Flush();
- EXPECT_FALSE(IsCacheLoaded());
+ observer->KeyChangeFailed(KeyToUint8Vector(kKey), source_);
+ EXPECT_TRUE(cached_area_->GetItem(kKey).IsNull());
}
TEST_F(CachedStorageAreaTest, ChangeEvents) {
mojom::blink::StorageAreaObserver* observer = cached_area_.get();
- observer->KeyAdded(KeyToUint8Vector(kKey), ValueToUint8Vector(kValue),
- source_);
+ cached_area_->SetItem(kKey, kValue, source_area_);
+ cached_area_->SetItem(kKey, kValue2, source_area_);
+ cached_area_->RemoveItem(kKey, source_area_);
+ observer->KeyChanged(KeyToUint8Vector(kKey), ValueToUint8Vector(kValue),
+ base::nullopt, source_);
observer->KeyChanged(KeyToUint8Vector(kKey), ValueToUint8Vector(kValue2),
ValueToUint8Vector(kValue), source_);
observer->KeyDeleted(KeyToUint8Vector(kKey), ValueToUint8Vector(kValue2),
source_);
- observer->KeyAdded(KeyToUint8Vector(kKey), ValueToUint8Vector(kValue),
- kRemoteSource);
- observer->AllDeleted(kRemoteSource);
+ observer->KeyChanged(KeyToUint8Vector(kKey), ValueToUint8Vector(kValue),
+ base::nullopt, kRemoteSource);
+ observer->AllDeleted(/*was_nonempty=*/true, kRemoteSource);
// Source area should have ignored all but the last two events.
ASSERT_EQ(2u, source_area_->events.size());
@@ -471,6 +639,92 @@ TEST_F(CachedStorageAreaTest, ChangeEvents) {
EXPECT_EQ(kPageUrl2, source_area2_->events[4].url);
}
+TEST_F(CachedStorageAreaTest, RevertOnChangeFailed) {
+ // Verifies that when local key changes fail, the cache is restored to an
+ // appropriate state.
+ mojom::blink::StorageAreaObserver* observer = cached_area_.get();
+ cached_area_->SetItem(kKey, kValue, source_area_);
+ EXPECT_EQ(kValue, cached_area_->GetItem(kKey));
+ observer->KeyChangeFailed(KeyToUint8Vector(kKey), source_);
+ EXPECT_TRUE(cached_area_->GetItem(kKey).IsNull());
+}
+
+TEST_F(CachedStorageAreaTest, RevertOnChangeFailedWithSubsequentChanges) {
+ // Failure of an operation observed while another subsequent operation is
+ // still queued. In this case, no revert should happen because the change that
+ // would be reverted has already been overwritten.
+ mojom::blink::StorageAreaObserver* observer = cached_area_.get();
+ cached_area_->SetItem(kKey, kValue, source_area_);
+ EXPECT_EQ(kValue, cached_area_->GetItem(kKey));
+ cached_area_->SetItem(kKey, kValue2, source_area_);
+ EXPECT_EQ(kValue2, cached_area_->GetItem(kKey));
+ observer->KeyChangeFailed(KeyToUint8Vector(kKey), source_);
+ EXPECT_EQ(kValue2, cached_area_->GetItem(kKey));
+ observer->KeyChanged(KeyToUint8Vector(kKey), ValueToUint8Vector(kValue2),
+ base::nullopt, source_);
+ EXPECT_EQ(kValue2, cached_area_->GetItem(kKey));
+}
+
+TEST_F(CachedStorageAreaTest, RevertOnConsecutiveChangeFailures) {
+ mojom::blink::StorageAreaObserver* observer = cached_area_.get();
+ // If two operations fail in a row, the cache should revert to the original
+ // state before either |SetItem()|.
+ cached_area_->SetItem(kKey, kValue, source_area_);
+ cached_area_->SetItem(kKey, kValue2, source_area_);
+ EXPECT_EQ(kValue2, cached_area_->GetItem(kKey));
+ observer->KeyChangeFailed(KeyToUint8Vector(kKey), source_);
+ // Still caching |kValue2| because that operation is still pending.
+ EXPECT_EQ(kValue2, cached_area_->GetItem(kKey));
+ observer->KeyChangeFailed(KeyToUint8Vector(kKey), source_);
+ // Now that the second operation also failed, the cache should revert to the
+ // value from before the first |SetItem()|, i.e. no value.
+ EXPECT_TRUE(cached_area_->GetItem(kKey).IsNull());
+}
+
+TEST_F(CachedStorageAreaTest, RevertOnChangeFailedWithNonLocalChanges) {
+ // If a non-local mutation is observed while a local mutation is pending
+ // acknowledgement, and that local mutation ends up getting rejected, the
+ // cache should revert to a state reflecting the non-local change that was
+ // temporarily ignored.
+ mojom::blink::StorageAreaObserver* observer = cached_area_.get();
+ cached_area_->SetItem(kKey, kValue, source_area_);
+ EXPECT_EQ(kValue, cached_area_->GetItem(kKey));
+ // Should be ignored.
+ observer->KeyChanged(KeyToUint8Vector(kKey), ValueToUint8Vector(kValue2),
+ base::nullopt, kRemoteSource);
+ EXPECT_EQ(kValue, cached_area_->GetItem(kKey));
+ // Now that we fail the pending |SetItem()|, the above remote change should be
+ // reflected.
+ observer->KeyChangeFailed(KeyToUint8Vector(kKey), source_);
+ EXPECT_EQ(kValue2, cached_area_->GetItem(kKey));
+}
+
+TEST_F(CachedStorageAreaTest, RevertOnChangeFailedAfterNonLocalClear) {
+ // If a non-local clear is observed while a local mutation is pending
+ // acknowledgement and that local mutation ends up getting rejected, the cache
+ // should revert the key to have no value, even if it had a value during the
+ // corresponding |SetItem()| call.
+ mojom::blink::StorageAreaObserver* observer = cached_area_.get();
+ cached_area_->SetItem(kKey, kValue, source_area_);
+ EXPECT_EQ(kValue, cached_area_->GetItem(kKey));
+ cached_area_->SetItem(kKey, kValue2, source_area_);
+ EXPECT_EQ(kValue2, cached_area_->GetItem(kKey));
+ observer->KeyChanged(KeyToUint8Vector(kKey), ValueToUint8Vector(kValue),
+ base::nullopt, source_);
+ // We still have |kValue2| cached since its mutation is still pending.
+ EXPECT_EQ(kValue2, cached_area_->GetItem(kKey));
+
+ // Even after a non-local clear is observed, |kValue2| remains cached because
+ // pending local mutations are replayed over a non-local clear.
+ observer->AllDeleted(true, kRemoteSource);
+ EXPECT_EQ(kValue2, cached_area_->GetItem(kKey));
+
+ // But if that pending mutation fails, we should "revert" to the cleared
+ // value, as that's what the backend would have.
+ observer->KeyChangeFailed(KeyToUint8Vector(kKey), source_);
+ EXPECT_TRUE(cached_area_->GetItem(kKey).IsNull());
+}
+
namespace {
class StringEncoding : public CachedStorageAreaTest,
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 d0b24da0fca..31e07a88755 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
@@ -23,7 +23,7 @@ namespace blink {
DOMWindowStorage::DOMWindowStorage(LocalDOMWindow& window)
: Supplement<LocalDOMWindow>(window) {}
-void DOMWindowStorage::Trace(blink::Visitor* visitor) {
+void DOMWindowStorage::Trace(Visitor* visitor) {
visitor->Trace(session_storage_);
visitor->Trace(local_storage_);
Supplement<LocalDOMWindow>::Trace(visitor);
@@ -64,7 +64,7 @@ StorageArea* DOMWindowStorage::sessionStorage(
DCHECK(document);
String access_denied_message = "Access is denied for this document.";
if (!document->GetSecurityOrigin()->CanAccessSessionStorage()) {
- if (document->IsSandboxed(WebSandboxFlags::kOrigin))
+ if (document->IsSandboxed(mojom::blink::WebSandboxFlags::kOrigin))
exception_state.ThrowSecurityError(
"The document is sandboxed and lacks the 'allow-same-origin' flag.");
else if (document->Url().ProtocolIs("data"))
@@ -116,7 +116,7 @@ StorageArea* DOMWindowStorage::localStorage(
DCHECK(document);
String access_denied_message = "Access is denied for this document.";
if (!document->GetSecurityOrigin()->CanAccessLocalStorage()) {
- if (document->IsSandboxed(WebSandboxFlags::kOrigin))
+ if (document->IsSandboxed(mojom::blink::WebSandboxFlags::kOrigin))
exception_state.ThrowSecurityError(
"The document is sandboxed and lacks the 'allow-same-origin' flag.");
else if (document->Url().ProtocolIs("data"))
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 34d67facfdc..2a0d86e04b5 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 0bca8b97e15..b1468d4db4b 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(blink::Visitor* visitor) {
+void DOMWindowStorageController::Trace(Visitor* visitor) {
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 f0a17f7d299..9f72492ff91 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
static DOMWindowStorageController& From(Document&);
diff --git a/chromium/third_party/blink/renderer/modules/storage/idls.gni b/chromium/third_party/blink/renderer/modules/storage/idls.gni
new file mode 100644
index 00000000000..075b9410548
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/storage/idls.gni
@@ -0,0 +1,12 @@
+# 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 = [
+ "storage.idl",
+ "storage_event.idl",
+]
+
+modules_dictionary_idl_files = [ "storage_event_init.idl" ]
+
+modules_dependency_idl_files = [ "window_storage.idl" ]
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 abc24169246..39eda8d2829 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
@@ -49,14 +49,15 @@ using protocol::Response;
static Response ToResponse(ExceptionState& exception_state) {
if (!exception_state.HadException())
- return Response::OK();
+ return Response::Success();
String name_prefix = IsDOMExceptionCode(exception_state.Code())
? DOMException::GetErrorName(
exception_state.CodeAs<DOMExceptionCode>()) +
" "
: g_empty_string;
- return Response::Error(name_prefix + exception_state.Message());
+ String msg = name_prefix + exception_state.Message();
+ return Response::ServerError(msg.Utf8());
}
InspectorDOMStorageAgent::InspectorDOMStorageAgent(
@@ -66,7 +67,7 @@ InspectorDOMStorageAgent::InspectorDOMStorageAgent(
InspectorDOMStorageAgent::~InspectorDOMStorageAgent() = default;
-void InspectorDOMStorageAgent::Trace(blink::Visitor* visitor) {
+void InspectorDOMStorageAgent::Trace(Visitor* visitor) {
visitor->Trace(inspected_frames_);
InspectorBaseAgent::Trace(visitor);
}
@@ -86,15 +87,15 @@ void InspectorDOMStorageAgent::InnerEnable() {
Response InspectorDOMStorageAgent::enable() {
if (enabled_.Get())
- return Response::OK();
+ return Response::Success();
enabled_.Set(true);
InnerEnable();
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMStorageAgent::disable() {
if (!enabled_.Get())
- return Response::OK();
+ return Response::Success();
enabled_.Set(false);
StorageController::GetInstance()->RemoveLocalStorageInspectorStorageAgent(
this);
@@ -102,20 +103,20 @@ Response InspectorDOMStorageAgent::disable() {
StorageNamespace::From(inspected_frames_->Root()->GetPage());
if (ns)
ns->RemoveInspectorStorageAgent(this);
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMStorageAgent::clear(
std::unique_ptr<protocol::DOMStorage::StorageId> storage_id) {
StorageArea* storage_area = nullptr;
Response response = FindStorageArea(std::move(storage_id), storage_area);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
DummyExceptionStateForTesting exception_state;
storage_area->clear(exception_state);
if (exception_state.HadException())
- return Response::Error("Could not clear the storage");
- return Response::OK();
+ return Response::ServerError("Could not clear the storage");
+ return Response::Success();
}
Response InspectorDOMStorageAgent::getDOMStorageItems(
@@ -123,7 +124,7 @@ Response InspectorDOMStorageAgent::getDOMStorageItems(
std::unique_ptr<protocol::Array<protocol::Array<String>>>* items) {
StorageArea* storage_area = nullptr;
Response response = FindStorageArea(std::move(storage_id), storage_area);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
auto storage_items =
@@ -133,11 +134,11 @@ Response InspectorDOMStorageAgent::getDOMStorageItems(
for (unsigned i = 0; i < storage_area->length(exception_state); ++i) {
String name(storage_area->key(i, exception_state));
response = ToResponse(exception_state);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
String value(storage_area->getItem(name, exception_state));
response = ToResponse(exception_state);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
auto entry = std::make_unique<protocol::Array<String>>();
entry->emplace_back(name);
@@ -145,7 +146,7 @@ Response InspectorDOMStorageAgent::getDOMStorageItems(
storage_items->emplace_back(std::move(entry));
}
*items = std::move(storage_items);
- return Response::OK();
+ return Response::Success();
}
Response InspectorDOMStorageAgent::setDOMStorageItem(
@@ -154,7 +155,7 @@ Response InspectorDOMStorageAgent::setDOMStorageItem(
const String& value) {
StorageArea* storage_area = nullptr;
Response response = FindStorageArea(std::move(storage_id), storage_area);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
DummyExceptionStateForTesting exception_state;
@@ -167,7 +168,7 @@ Response InspectorDOMStorageAgent::removeDOMStorageItem(
const String& key) {
StorageArea* storage_area = nullptr;
Response response = FindStorageArea(std::move(storage_id), storage_area);
- if (!response.isSuccess())
+ if (!response.IsSuccess())
return response;
DummyExceptionStateForTesting exception_state;
@@ -214,26 +215,31 @@ Response InspectorDOMStorageAgent::FindStorageArea(
bool is_local_storage = storage_id->getIsLocalStorage();
LocalFrame* frame =
inspected_frames_->FrameWithSecurityOrigin(security_origin);
- if (!frame)
- return Response::Error("Frame not found for the given security origin");
-
+ if (!frame) {
+ return Response::ServerError(
+ "Frame not found for the given security origin");
+ }
if (is_local_storage) {
- if (!frame->GetDocument()->GetSecurityOrigin()->CanAccessLocalStorage())
- return Response::Error("Security origin cannot access local storage");
+ if (!frame->GetDocument()->GetSecurityOrigin()->CanAccessLocalStorage()) {
+ return Response::ServerError(
+ "Security origin cannot access local storage");
+ }
storage_area = StorageArea::CreateForInspectorAgent(
frame,
StorageController::GetInstance()->GetLocalStorageArea(
frame->GetDocument()->GetSecurityOrigin()),
StorageArea::StorageType::kLocalStorage);
- return Response::OK();
+ return Response::Success();
}
- if (!frame->GetDocument()->GetSecurityOrigin()->CanAccessSessionStorage())
- return Response::Error("Security origin cannot access session storage");
+ if (!frame->GetDocument()->GetSecurityOrigin()->CanAccessSessionStorage()) {
+ return Response::ServerError(
+ "Security origin cannot access session storage");
+ }
StorageNamespace* session_namespace =
StorageNamespace::From(frame->GetPage());
if (!session_namespace)
- return Response::Error("SessionStorage is not supported");
+ return Response::ServerError("SessionStorage is not supported");
DCHECK(session_namespace->IsSessionStorage());
storage_area = StorageArea::CreateForInspectorAgent(
@@ -241,7 +247,7 @@ Response InspectorDOMStorageAgent::FindStorageArea(
session_namespace->GetCachedArea(
frame->GetDocument()->GetSecurityOrigin()),
StorageArea::StorageType::kSessionStorage);
- return Response::OK();
+ return Response::Success();
}
} // namespace blink
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 f2d68b67f31..d74c08e016f 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 2c118818e68..cc24c65ae77 100644
--- a/chromium/third_party/blink/renderer/modules/storage/storage_area.cc
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_area.cc
@@ -63,7 +63,7 @@ StorageArea::StorageArea(LocalFrame* frame,
scoped_refptr<CachedStorageArea> storage_area,
StorageType storage_type,
bool should_enqueue_events)
- : ContextClient(frame),
+ : ExecutionContextClient(frame),
cached_area_(std::move(storage_area)),
storage_type_(storage_type),
should_enqueue_events_(should_enqueue_events) {
@@ -97,29 +97,32 @@ String StorageArea::getItem(const String& key,
return cached_area_->GetItem(key);
}
-bool StorageArea::setItem(const String& key,
- const String& value,
- ExceptionState& exception_state) {
+NamedPropertySetterResult StorageArea::setItem(
+ const String& key,
+ const String& value,
+ ExceptionState& exception_state) {
if (!CanAccessStorage()) {
exception_state.ThrowSecurityError("access is denied for this document.");
- return true;
+ return NamedPropertySetterResult::kIntercepted;
}
if (!cached_area_->SetItem(key, value, this)) {
exception_state.ThrowDOMException(
DOMExceptionCode::kQuotaExceededError,
"Setting the value of '" + key + "' exceeded the quota.");
+ return NamedPropertySetterResult::kIntercepted;
}
- return true;
+ return NamedPropertySetterResult::kIntercepted;
}
-DeleteResult StorageArea::removeItem(const String& key,
- ExceptionState& exception_state) {
+NamedPropertyDeleterResult StorageArea::removeItem(
+ const String& key,
+ ExceptionState& exception_state) {
if (!CanAccessStorage()) {
exception_state.ThrowSecurityError("access is denied for this document.");
- return kDeleteSuccess;
+ return NamedPropertyDeleterResult::kDidNotDelete;
}
cached_area_->RemoveItem(key, this);
- return kDeleteSuccess;
+ return NamedPropertyDeleterResult::kDeleted;
}
void StorageArea::clear(ExceptionState& exception_state) {
@@ -165,9 +168,9 @@ bool StorageArea::NamedPropertyQuery(const AtomicString& name,
return found && !exception_state.HadException();
}
-void StorageArea::Trace(blink::Visitor* visitor) {
+void StorageArea::Trace(Visitor* visitor) {
ScriptWrappable::Trace(visitor);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
}
bool StorageArea::CanAccessStorage() const {
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 2f734457340..e9ea3308bf5 100644
--- a/chromium/third_party/blink/renderer/modules/storage/storage_area.h
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_area.h
@@ -28,7 +28,7 @@
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/storage/cached_storage_area.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -40,7 +40,7 @@ class ExceptionState;
class LocalFrame;
class StorageArea final : public ScriptWrappable,
- public ContextClient,
+ public ExecutionContextClient,
public CachedStorageArea::Source {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(StorageArea);
@@ -66,8 +66,10 @@ class StorageArea final : public ScriptWrappable,
unsigned length(ExceptionState&) const;
String key(unsigned index, ExceptionState&) const;
String getItem(const String& key, ExceptionState&) const;
- bool setItem(const String& key, const String& value, ExceptionState&);
- DeleteResult removeItem(const String& key, ExceptionState&);
+ NamedPropertySetterResult setItem(const String& key,
+ const String& value,
+ ExceptionState&);
+ NamedPropertyDeleterResult removeItem(const String& key, ExceptionState&);
void clear(ExceptionState&);
bool Contains(const String& key, ExceptionState& ec) const;
@@ -76,7 +78,7 @@ class StorageArea final : public ScriptWrappable,
bool CanAccessStorage() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// CachedStorageArea::Source:
KURL GetPageUrl() const override;
diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_controller.cc b/chromium/third_party/blink/renderer/modules/storage/storage_controller.cc
index 4106200a98f..995be273325 100644
--- a/chromium/third_party/blink/renderer/modules/storage/storage_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_controller.cc
@@ -7,7 +7,7 @@
#include "base/feature_list.h"
#include "base/system/sys_info.h"
#include "third_party/blink/public/common/features.h"
-#include "third_party/blink/public/platform/interface_provider.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_content_settings_client.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -19,25 +19,32 @@
#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
namespace blink {
+
namespace {
const size_t kStorageControllerTotalCacheLimitInBytesLowEnd = 1 * 1024 * 1024;
const size_t kStorageControllerTotalCacheLimitInBytes = 5 * 1024 * 1024;
-mojo::PendingRemote<mojom::blink::StoragePartitionService>
-GetAndCreateStorageInterface() {
- mojo::PendingRemote<mojom::blink::StoragePartitionService> pending_remote;
- Platform::Current()->GetInterfaceProvider()->GetInterface(
- pending_remote.InitWithNewPipeAndPassReceiver());
- return pending_remote;
+StorageController::DomStorageConnection GetDomStorageConnection() {
+ StorageController::DomStorageConnection connection;
+ mojo::Remote<mojom::blink::DomStorageProvider> provider;
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
+ provider.BindNewPipeAndPassReceiver());
+ mojo::PendingRemote<mojom::blink::DomStorageClient> client;
+ connection.client_receiver = client.InitWithNewPipeAndPassReceiver();
+ provider->BindDomStorage(
+ connection.dom_storage_remote.BindNewPipeAndPassReceiver(),
+ std::move(client));
+ return connection;
}
+
} // namespace
// static
StorageController* StorageController::GetInstance() {
DEFINE_STATIC_LOCAL(StorageController, gCachedStorageAreaController,
- (Thread::MainThread()->Scheduler()->IPCTaskRunner(),
- GetAndCreateStorageInterface(),
+ (GetDomStorageConnection(),
+ Thread::MainThread()->Scheduler()->IPCTaskRunner(),
base::SysInfo::IsLowEndDevice()
? kStorageControllerTotalCacheLimitInBytesLowEnd
: kStorageControllerTotalCacheLimitInBytes));
@@ -55,15 +62,18 @@ bool StorageController::CanAccessStorageArea(LocalFrame* frame,
}
StorageController::StorageController(
+ DomStorageConnection connection,
scoped_refptr<base::SingleThreadTaskRunner> ipc_runner,
- mojo::PendingRemote<mojom::blink::StoragePartitionService>
- storage_partition_service,
size_t total_cache_limit)
: ipc_runner_(std::move(ipc_runner)),
namespaces_(MakeGarbageCollected<
HeapHashMap<String, WeakMember<StorageNamespace>>>()),
total_cache_limit_(total_cache_limit),
- storage_partition_service_(std::move(storage_partition_service)) {}
+ dom_storage_remote_(std::move(connection.dom_storage_remote)) {
+ // May be null in tests.
+ if (connection.client_receiver)
+ dom_storage_client_receiver_.Bind(std::move(connection.client_receiver));
+}
StorageNamespace* StorageController::CreateSessionStorageNamespace(
const String& namespace_id) {
@@ -138,4 +148,13 @@ void StorageController::EnsureLocalStorageNamespaceCreated() {
local_storage_namespace_ = MakeGarbageCollected<StorageNamespace>(this);
}
+void StorageController::ResetStorageAreaAndNamespaceConnections() {
+ for (auto& ns : *namespaces_) {
+ if (ns.value)
+ ns.value->ResetStorageAreaAndNamespaceConnections();
+ }
+ if (local_storage_namespace_)
+ local_storage_namespace_->ResetStorageAreaAndNamespaceConnections();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_controller.h b/chromium/third_party/blink/renderer/modules/storage/storage_controller.h
index 8b482341efb..3deb45c0fb2 100644
--- a/chromium/third_party/blink/renderer/modules/storage/storage_controller.h
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_controller.h
@@ -7,11 +7,13 @@
#include <memory>
+#include "base/callback.h"
#include "base/sequence_checker.h"
-#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/common/dom_storage/session_storage_namespace_id.h"
-#include "third_party/blink/public/mojom/dom_storage/storage_partition_service.mojom-blink.h"
+#include "third_party/blink/public/mojom/dom_storage/dom_storage.mojom-blink.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/storage/storage_area.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
@@ -42,10 +44,9 @@ class StorageNamespace;
//
// The LocalStorage StorageNamespace object is owned internally, and
// StorageController delegates the following methods to that namespace:
-// GetLocalStorageArea, GetWebLocalStorageArea,
-// AddLocalStorageInspectorStorageAgent,
+// GetLocalStorageArea, AddLocalStorageInspectorStorageAgent,
// RemoveLocalStorageInspectorStorageAgent, DidDispatchLocalStorageEvent
-class MODULES_EXPORT StorageController {
+class MODULES_EXPORT StorageController : public mojom::blink::DomStorageClient {
USING_FAST_MALLOC(StorageController);
public:
@@ -56,9 +57,12 @@ class MODULES_EXPORT StorageController {
StorageArea::StorageType type);
// Visible for testing.
- StorageController(scoped_refptr<base::SingleThreadTaskRunner> ipc_runner,
- mojo::PendingRemote<mojom::blink::StoragePartitionService>
- storage_partition_service,
+ struct DomStorageConnection {
+ mojo::Remote<mojom::blink::DomStorage> dom_storage_remote;
+ mojo::PendingReceiver<mojom::blink::DomStorageClient> client_receiver;
+ };
+ StorageController(DomStorageConnection connection,
+ scoped_refptr<base::SingleThreadTaskRunner> ipc_runner,
size_t total_cache_limit);
// Creates a MakeGarbageCollected<StorageNamespace> for Session storage, and
@@ -84,8 +88,8 @@ class MODULES_EXPORT StorageController {
const String& old_value,
const String& new_value);
- mojom::blink::StoragePartitionService* storage_partition_service() const {
- return storage_partition_service_.get();
+ mojom::blink::DomStorage* dom_storage() const {
+ return dom_storage_remote_.get();
}
scoped_refptr<base::SingleThreadTaskRunner> IPCTaskRunner() {
@@ -95,13 +99,17 @@ class MODULES_EXPORT StorageController {
private:
void EnsureLocalStorageNamespaceCreated();
+ // mojom::blink::DomStorageClient:
+ void ResetStorageAreaAndNamespaceConnections() override;
+
scoped_refptr<base::SingleThreadTaskRunner> ipc_runner_;
Persistent<HeapHashMap<String, WeakMember<StorageNamespace>>> namespaces_;
Persistent<StorageNamespace> local_storage_namespace_;
size_t total_cache_limit_;
- mojo::Remote<mojom::blink::StoragePartitionService>
- storage_partition_service_;
+ mojo::Remote<mojom::blink::DomStorage> dom_storage_remote_;
+ mojo::Receiver<mojom::blink::DomStorageClient> dom_storage_client_receiver_{
+ this};
SEQUENCE_CHECKER(sequence_checker_);
};
diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_controller_test.cc b/chromium/third_party/blink/renderer/modules/storage/storage_controller_test.cc
index a8e9d9c82a2..35af301c6b9 100644
--- a/chromium/third_party/blink/renderer/modules/storage/storage_controller_test.cc
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_controller_test.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/run_loop.h"
#include "base/task/post_task.h"
+#include "base/task/thread_pool.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
@@ -25,17 +26,20 @@ namespace blink {
namespace {
const size_t kTestCacheLimit = 100;
-class MockStoragePartitionService
- : public mojom::blink::StoragePartitionService {
+class MockDomStorage : public mojom::blink::DomStorage {
public:
+ // mojom::blink::DomStorage implementation:
void OpenLocalStorage(
const scoped_refptr<const SecurityOrigin>& origin,
mojo::PendingReceiver<mojom::blink::StorageArea> receiver) override {}
-
- void OpenSessionStorage(
+ void BindSessionStorageNamespace(
const String& namespace_id,
mojo::PendingReceiver<mojom::blink::SessionStorageNamespace> receiver)
- override {
+ override {}
+ void BindSessionStorageArea(
+ const scoped_refptr<const SecurityOrigin>& origin,
+ const String& namespace_id,
+ mojo::PendingReceiver<mojom::blink::StorageArea> receiver) override {
session_storage_opens++;
}
@@ -60,22 +64,19 @@ TEST(StorageControllerTest, CacheLimit) {
Persistent<FakeAreaSource> source_area =
MakeGarbageCollected<FakeAreaSource>(kPageUrl);
- mojo::PendingRemote<mojom::blink::StoragePartitionService>
- storage_partition_service_remote;
+ StorageController::DomStorageConnection connection;
PostCrossThreadTask(
- *base::CreateSequencedTaskRunner({base::ThreadPool()}), FROM_HERE,
+ *base::ThreadPool::CreateSequencedTaskRunner({}), FROM_HERE,
CrossThreadBindOnce(
- [](mojo::PendingReceiver<mojom::blink::StoragePartitionService>
- receiver) {
- mojo::MakeSelfOwnedReceiver(
- std::make_unique<MockStoragePartitionService>(),
- std::move(receiver));
+ [](mojo::PendingReceiver<mojom::blink::DomStorage> receiver) {
+ mojo::MakeSelfOwnedReceiver(std::make_unique<MockDomStorage>(),
+ std::move(receiver));
},
- WTF::Passed(storage_partition_service_remote
- .InitWithNewPipeAndPassReceiver())));
+ WTF::Passed(
+ connection.dom_storage_remote.BindNewPipeAndPassReceiver())));
- StorageController controller(scheduler::GetSingleThreadTaskRunnerForTesting(),
- std::move(storage_partition_service_remote),
+ StorageController controller(std::move(connection),
+ scheduler::GetSingleThreadTaskRunnerForTesting(),
kTestCacheLimit);
auto cached_area1 = controller.GetLocalStorageArea(kOrigin.get());
@@ -116,30 +117,25 @@ TEST(StorageControllerTest, CacheLimitSessionStorage) {
Persistent<FakeAreaSource> source_area =
MakeGarbageCollected<FakeAreaSource>(kPageUrl);
- auto task_runner = base::CreateSequencedTaskRunner({base::ThreadPool()});
+ auto task_runner = base::ThreadPool::CreateSequencedTaskRunner({});
- auto mock_storage_partition_service =
- std::make_unique<MockStoragePartitionService>();
- MockStoragePartitionService* storage_partition_ptr =
- mock_storage_partition_service.get();
+ auto mock_dom_storage = std::make_unique<MockDomStorage>();
+ MockDomStorage* dom_storage_ptr = mock_dom_storage.get();
- mojo::PendingRemote<mojom::blink::StoragePartitionService>
- storage_partition_service_remote;
+ StorageController::DomStorageConnection connection;
PostCrossThreadTask(
*task_runner, FROM_HERE,
CrossThreadBindOnce(
- [](std::unique_ptr<MockStoragePartitionService> storage_partition_ptr,
- mojo::PendingReceiver<mojom::blink::StoragePartitionService>
- receiver) {
- mojo::MakeSelfOwnedReceiver(std::move(storage_partition_ptr),
+ [](std::unique_ptr<MockDomStorage> dom_storage_ptr,
+ mojo::PendingReceiver<mojom::blink::DomStorage> receiver) {
+ mojo::MakeSelfOwnedReceiver(std::move(dom_storage_ptr),
std::move(receiver));
},
- WTF::Passed(std::move(mock_storage_partition_service)),
- WTF::Passed(storage_partition_service_remote
- .InitWithNewPipeAndPassReceiver())));
+ WTF::Passed(std::move(mock_dom_storage)),
+ WTF::Passed(
+ connection.dom_storage_remote.BindNewPipeAndPassReceiver())));
- StorageController controller(
- nullptr, std::move(storage_partition_service_remote), kTestCacheLimit);
+ StorageController controller(std::move(connection), nullptr, kTestCacheLimit);
StorageNamespace* ns1 = controller.CreateSessionStorageNamespace(kNamespace1);
StorageNamespace* ns2 = controller.CreateSessionStorageNamespace(kNamespace2);
@@ -171,12 +167,12 @@ TEST(StorageControllerTest, CacheLimitSessionStorage) {
base::RunLoop loop;
task_runner->PostTaskAndReply(
FROM_HERE,
- base::BindOnce(&MockStoragePartitionService::GetSessionStorageUsage,
- base::Unretained(storage_partition_ptr), &opens),
+ base::BindOnce(&MockDomStorage::GetSessionStorageUsage,
+ base::Unretained(dom_storage_ptr), &opens),
loop.QuitClosure());
loop.Run();
}
- EXPECT_EQ(opens, 2);
+ EXPECT_EQ(opens, 3);
}
} // namespace blink
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 d0f475c1574..3a7f17e2521 100644
--- a/chromium/third_party/blink/renderer/modules/storage/storage_event.cc
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_event.cc
@@ -25,9 +25,9 @@
#include "third_party/blink/renderer/modules/storage/storage_event.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_storage_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/storage/storage_area.h"
-#include "third_party/blink/renderer/modules/storage/storage_event_init.h"
namespace blink {
@@ -76,7 +76,7 @@ StorageEvent::StorageEvent(const AtomicString& type,
old_value_ = initializer->oldValue();
if (initializer->hasNewValue())
new_value_ = initializer->newValue();
- if (initializer->hasURL())
+ if (initializer->hasUrl())
url_ = initializer->url();
if (initializer->hasStorageArea())
storage_area_ = initializer->storageArea();
@@ -106,7 +106,7 @@ const AtomicString& StorageEvent::InterfaceName() const {
return event_interface_names::kStorageEvent;
}
-void StorageEvent::Trace(blink::Visitor* visitor) {
+void StorageEvent::Trace(Visitor* visitor) {
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 8d58da048d0..c2eae0ebf00 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
String key_;
diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_event.idl b/chromium/third_party/blink/renderer/modules/storage/storage_event.idl
index 0414d23f581..80388ffff5e 100644
--- a/chromium/third_party/blink/renderer/modules/storage/storage_event.idl
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_event.idl
@@ -26,9 +26,9 @@
// https://html.spec.whatwg.org/C/#the-storageevent-interface
[
- Exposed=Window,
- Constructor(DOMString type, optional StorageEventInit eventInitDict)
+ Exposed=Window
] interface StorageEvent : Event {
+ constructor(DOMString type, optional StorageEventInit eventInitDict = {});
readonly attribute DOMString? key;
readonly attribute DOMString? oldValue;
readonly attribute DOMString? newValue;
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 d6995788e12..4efcbb8d0da 100644
--- a/chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc
@@ -29,8 +29,8 @@
#include "base/feature_list.h"
#include "base/memory/ptr_util.h"
+#include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_macros.h"
-#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/platform.h"
@@ -52,8 +52,6 @@ StorageNamespace::StorageNamespace(StorageController* controller,
const String& namespace_id)
: controller_(controller), namespace_id_(namespace_id) {}
-StorageNamespace::~StorageNamespace() = default;
-
// static
void StorageNamespace::ProvideSessionStorageNamespaceTo(Page& page,
WebViewClient* client) {
@@ -100,20 +98,10 @@ scoped_refptr<CachedStorageArea> StorageNamespace::GetCachedArea(
scoped_refptr<const SecurityOrigin> origin(origin_ptr);
controller_->ClearAreasIfNeeded();
- if (IsSessionStorage()) {
- EnsureConnected();
- mojo::PendingAssociatedRemote<mojom::blink::StorageArea> area_remote;
- namespace_->OpenArea(origin,
- area_remote.InitWithNewEndpointAndPassReceiver());
- result = CachedStorageArea::CreateForSessionStorage(
- origin, std::move(area_remote), controller_->IPCTaskRunner(), this);
- } else {
- mojo::PendingRemote<mojom::blink::StorageArea> area_remote;
- controller_->storage_partition_service()->OpenLocalStorage(
- origin, area_remote.InitWithNewPipeAndPassReceiver());
- result = CachedStorageArea::CreateForLocalStorage(
- origin, std::move(area_remote), controller_->IPCTaskRunner(), this);
- }
+ result = base::MakeRefCounted<CachedStorageArea>(
+ IsSessionStorage() ? CachedStorageArea::AreaType::kSessionStorage
+ : CachedStorageArea::AreaType::kLocalStorage,
+ origin, controller_->IPCTaskRunner(), this);
cached_areas_.insert(std::move(origin), result);
return result;
}
@@ -121,7 +109,40 @@ scoped_refptr<CachedStorageArea> StorageNamespace::GetCachedArea(
void StorageNamespace::CloneTo(const String& target) {
DCHECK(IsSessionStorage()) << "Cannot clone a local storage namespace.";
EnsureConnected();
+
+ // Spec requires that all mutations on storage areas *before* cloning are
+ // visible in the clone and that no mutations on the original storage areas
+ // *after* cloning, are visible in the clone. Consider the following scenario
+ // in the comments below:
+ //
+ // 1. Area A calls Put("x", 42)
+ // 2. Area B calls Put("y", 13)
+ // 3. Area A & B's StorageNamespace gets CloneTo()'d to a new namespace
+ // 4. Area A calls Put("x", 43) in the original namespace
+ //
+ // First, we synchronize StorageNamespace against every cached StorageArea.
+ // This ensures that all StorageArea operations (e.g. Put, Delete) up to this
+ // point will have executed before the StorageNamespace implementation is able
+ // to receive or process the following |Clone()| call. Given the above
+ // example, this would mean that A.x=42 and B.y=13 definitely WILL be present
+ // in the cloned namespace.
+ for (auto& entry : cached_areas_) {
+ namespace_.PauseReceiverUntilFlushCompletes(
+ entry.value->RemoteArea().FlushAsync());
+ }
+
namespace_->Clone(target);
+
+ // Finally, we synchronize every StorageArea against StorageNamespace. This
+ // ensures that any future calls on each StorageArea cannot be received and
+ // processed until after the above |Clone()| call executes. Given the example
+ // above, this would mean that A.x=43 definitely WILL NOT be present in the
+ // cloned namespace; only the original namespace will be updated, and A.x will
+ // still hold a value of 42 in the new clone.
+ for (auto& entry : cached_areas_) {
+ entry.value->RemoteArea().PauseReceiverUntilFlushCompletes(
+ namespace_.FlushAsync());
+ }
}
size_t StorageNamespace::TotalCacheSize() const {
@@ -167,11 +188,28 @@ void StorageNamespace::DidDispatchStorageEvent(const SecurityOrigin* origin,
}
}
+void StorageNamespace::BindStorageArea(
+ const scoped_refptr<const SecurityOrigin>& origin,
+ mojo::PendingReceiver<mojom::blink::StorageArea> receiver) {
+ if (IsSessionStorage()) {
+ controller_->dom_storage()->BindSessionStorageArea(origin, namespace_id_,
+ std::move(receiver));
+ } else {
+ controller_->dom_storage()->OpenLocalStorage(origin, std::move(receiver));
+ }
+}
+
+void StorageNamespace::ResetStorageAreaAndNamespaceConnections() {
+ for (const auto& area : cached_areas_)
+ area.value->ResetConnection();
+ namespace_.reset();
+}
+
void StorageNamespace::EnsureConnected() {
DCHECK(IsSessionStorage());
if (namespace_)
return;
- controller_->storage_partition_service()->OpenSessionStorage(
+ controller_->dom_storage()->BindSessionStorageNamespace(
namespace_id_,
namespace_.BindNewPipeAndPassReceiver(controller_->IPCTaskRunner()));
}
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 3e04a018e3e..132e380fda0 100644
--- a/chromium/third_party/blink/renderer/modules/storage/storage_namespace.h
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_namespace.h
@@ -30,11 +30,11 @@
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/blink/public/mojom/dom_storage/dom_storage.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/dom_storage/session_storage_namespace.mojom-blink.h"
-#include "third_party/blink/public/mojom/dom_storage/storage_partition_service.mojom-blink-forward.h"
+#include "third_party/blink/public/mojom/dom_storage/storage_area.mojom-blink-forward.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/modules/storage/cached_storage_area.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/supplementable.h"
@@ -44,6 +44,7 @@
namespace blink {
+class CachedStorageArea;
class InspectorDOMStorageAgent;
class StorageController;
class SecurityOrigin;
@@ -66,8 +67,7 @@ class WebViewClient;
// is used to get the storage area for an origin.
class MODULES_EXPORT StorageNamespace final
: public GarbageCollected<StorageNamespace>,
- public Supplement<Page>,
- public CachedStorageArea::InspectorEventListener {
+ public Supplement<Page> {
USING_GARBAGE_COLLECTED_MIXIN(StorageNamespace);
public:
@@ -83,8 +83,6 @@ class MODULES_EXPORT StorageNamespace final
// Creates a namespace for SessionStorage.
StorageNamespace(StorageController*, const String& namespace_id);
- ~StorageNamespace() override;
-
scoped_refptr<CachedStorageArea> GetCachedArea(const SecurityOrigin* origin);
// Only valid to call this if |this| and |target| are session storage
@@ -108,7 +106,18 @@ class MODULES_EXPORT StorageNamespace final
void DidDispatchStorageEvent(const SecurityOrigin* origin,
const String& key,
const String& old_value,
- const String& new_value) override;
+ const String& new_value);
+
+ // Called by areas in |cached_areas_| to bind/rebind their StorageArea
+ // interface.
+ void BindStorageArea(
+ const scoped_refptr<const SecurityOrigin>& origin,
+ mojo::PendingReceiver<mojom::blink::StorageArea> receiver);
+
+ // If this StorageNamespace was previously connected to the backend, this
+ // forcibly disconnects it so that it reconnects lazily when next needed.
+ // Also forces all owned CachedStorageAreas to be reconnected.
+ void ResetStorageAreaAndNamespaceConnections();
private:
void EnsureConnected();
diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_namespace_test.cc b/chromium/third_party/blink/renderer/modules/storage/storage_namespace_test.cc
index 86253746410..f98b18fc227 100644
--- a/chromium/third_party/blink/renderer/modules/storage/storage_namespace_test.cc
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_namespace_test.cc
@@ -17,34 +17,12 @@
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/uuid.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
-
namespace blink {
namespace {
-class NoopStoragePartitionService
- : public mojom::blink::StoragePartitionService {
- public:
- void OpenLocalStorage(
- const scoped_refptr<const SecurityOrigin>& origin,
- mojo::PendingReceiver<mojom::blink::StorageArea> receiver) override {}
-
- void OpenSessionStorage(
- const String& namespace_id,
- mojo::PendingReceiver<mojom::blink::SessionStorageNamespace> receiver)
- override {}
-};
-
-} // namespace
-class StorageNamespaceTest : public testing::Test {
- public:
- const size_t kTestCacheLimit = 100;
+constexpr size_t kTestCacheLimit = 100;
- StorageNamespaceTest() {}
- ~StorageNamespaceTest() override {}
-};
-
-TEST_F(StorageNamespaceTest, BasicStorageAreas) {
+TEST(StorageNamespaceTest, BasicStorageAreas) {
const auto kOrigin = SecurityOrigin::CreateFromString("http://dom_storage1/");
const auto kOrigin2 =
SecurityOrigin::CreateFromString("http://dom_storage2/");
@@ -57,22 +35,10 @@ TEST_F(StorageNamespaceTest, BasicStorageAreas) {
Persistent<FakeAreaSource> source_area =
MakeGarbageCollected<FakeAreaSource>(kPageUrl);
- mojo::PendingRemote<mojom::blink::StoragePartitionService>
- storage_partition_service_remote;
- PostCrossThreadTask(
- *base::CreateSequencedTaskRunner({base::ThreadPool()}), FROM_HERE,
- CrossThreadBindOnce(
- [](mojo::PendingReceiver<mojom::blink::StoragePartitionService>
- receiver) {
- mojo::MakeSelfOwnedReceiver(
- std::make_unique<NoopStoragePartitionService>(),
- std::move(receiver));
- },
- WTF::Passed(storage_partition_service_remote
- .InitWithNewPipeAndPassReceiver())));
-
- StorageController controller(scheduler::GetSingleThreadTaskRunnerForTesting(),
- std::move(storage_partition_service_remote),
+ StorageController::DomStorageConnection connection;
+ ignore_result(connection.dom_storage_remote.BindNewPipeAndPassReceiver());
+ StorageController controller(std::move(connection),
+ scheduler::GetSingleThreadTaskRunnerForTesting(),
kTestCacheLimit);
StorageNamespace* localStorage =
@@ -98,4 +64,5 @@ TEST_F(StorageNamespaceTest, BasicStorageAreas) {
EXPECT_EQ(cached_area3->GetItem(kKey), kValue);
}
+} // namespace
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/storage/testing/fake_area_source.h b/chromium/third_party/blink/renderer/modules/storage/testing/fake_area_source.h
index 9d57e679df2..d697cb7bb41 100644
--- a/chromium/third_party/blink/renderer/modules/storage/testing/fake_area_source.h
+++ b/chromium/third_party/blink/renderer/modules/storage/testing/fake_area_source.h
@@ -35,6 +35,11 @@ class FakeAreaSource : public GarbageCollected<FakeAreaSource>,
struct Event {
String key, old_value, new_value, url;
+
+ bool operator==(const Event& other) const {
+ return std::tie(key, old_value, new_value, url) ==
+ std::tie(other.key, other.old_value, other.new_value, other.url);
+ }
};
Vector<Event> events;
diff --git a/chromium/third_party/blink/renderer/modules/storage/testing/mock_storage_area.cc b/chromium/third_party/blink/renderer/modules/storage/testing/mock_storage_area.cc
index 2b9ba6478ad..7441f91a605 100644
--- a/chromium/third_party/blink/renderer/modules/storage/testing/mock_storage_area.cc
+++ b/chromium/third_party/blink/renderer/modules/storage/testing/mock_storage_area.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/modules/storage/testing/mock_storage_area.h"
-#include "mojo/public/cpp/bindings/associated_remote.h"
+#include "base/bind.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
@@ -19,16 +19,17 @@ MockStorageArea::GetInterfaceRemote() {
return result;
}
-mojo::PendingAssociatedRemote<mojom::blink::StorageArea>
-MockStorageArea::GetAssociatedInterfaceRemote() {
- mojo::AssociatedRemote<mojom::blink::StorageArea> result;
- associated_receivers_.Add(
- this, result.BindNewEndpointAndPassDedicatedReceiverForTesting());
- return result.Unbind();
+void MockStorageArea::InjectKeyValue(const Vector<uint8_t>& key,
+ const Vector<uint8_t>& value) {
+ key_values_.push_back(KeyValue{key, value});
+}
+
+void MockStorageArea::Clear() {
+ key_values_.clear();
}
void MockStorageArea::AddObserver(
- mojo::PendingAssociatedRemote<mojom::blink::StorageAreaObserver> observer) {
+ mojo::PendingRemote<mojom::blink::StorageAreaObserver> observer) {
++observer_count_;
}
@@ -38,11 +39,8 @@ void MockStorageArea::Put(
const base::Optional<Vector<uint8_t>>& client_old_value,
const String& source,
PutCallback callback) {
- observed_put_ = true;
- observed_key_ = key;
- observed_value_ = value;
- observed_source_ = source;
- pending_callbacks_.push_back(std::move(callback));
+ observed_puts_.push_back(ObservedPut{key, value, source});
+ std::move(callback).Run(true);
}
void MockStorageArea::Delete(
@@ -50,17 +48,17 @@ void MockStorageArea::Delete(
const base::Optional<Vector<uint8_t>>& client_old_value,
const String& source,
DeleteCallback callback) {
- observed_delete_ = true;
- observed_key_ = key;
- observed_source_ = source;
- pending_callbacks_.push_back(std::move(callback));
+ observed_deletes_.push_back(ObservedDelete{key, source});
+ std::move(callback).Run(true);
}
-void MockStorageArea::DeleteAll(const String& source,
- DeleteAllCallback callback) {
- observed_delete_all_ = true;
- observed_source_ = source;
- pending_callbacks_.push_back(std::move(callback));
+void MockStorageArea::DeleteAll(
+ const String& source,
+ mojo::PendingRemote<mojom::blink::StorageAreaObserver> new_observer,
+ DeleteAllCallback callback) {
+ observed_delete_alls_.push_back(source);
+ ++observer_count_;
+ std::move(callback).Run(true);
}
void MockStorageArea::Get(const Vector<uint8_t>& key, GetCallback callback) {
@@ -68,17 +66,15 @@ void MockStorageArea::Get(const Vector<uint8_t>& key, GetCallback callback) {
}
void MockStorageArea::GetAll(
- mojo::PendingAssociatedRemote<mojom::blink::StorageAreaGetAllCallback>
- complete_callback,
+ mojo::PendingRemote<mojom::blink::StorageAreaObserver> new_observer,
GetAllCallback callback) {
- mojo::AssociatedRemote<mojom::blink::StorageAreaGetAllCallback>
- complete_remote(std::move(complete_callback));
- pending_callbacks_.push_back(
- WTF::Bind(&mojom::blink::StorageAreaGetAllCallback::Complete,
- std::move(complete_remote)));
+ ++observed_get_alls_;
+ ++observer_count_;
- observed_get_all_ = true;
- std::move(callback).Run(true, std::move(get_all_return_values_));
+ Vector<mojom::blink::KeyValuePtr> entries;
+ for (const auto& entry : key_values_)
+ entries.push_back(mojom::blink::KeyValue::New(entry.key, entry.value));
+ std::move(callback).Run(std::move(entries));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/storage/testing/mock_storage_area.h b/chromium/third_party/blink/renderer/modules/storage/testing/mock_storage_area.h
index c706bf8efb4..a5ee4b0afba 100644
--- a/chromium/third_party/blink/renderer/modules/storage/testing/mock_storage_area.h
+++ b/chromium/third_party/blink/renderer/modules/storage/testing/mock_storage_area.h
@@ -5,8 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_STORAGE_TESTING_MOCK_STORAGE_AREA_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_STORAGE_TESTING_MOCK_STORAGE_AREA_H_
-#include "mojo/public/cpp/bindings/associated_receiver_set.h"
-#include "mojo/public/cpp/bindings/pending_associated_remote.h"
+#include <utility>
+
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -20,103 +20,98 @@ class MockStorageArea : public mojom::blink::StorageArea {
public:
using ResultCallback = base::OnceCallback<void(bool)>;
+ struct ObservedPut {
+ Vector<uint8_t> key;
+ Vector<uint8_t> value;
+ String source;
+
+ bool operator==(const ObservedPut& other) const {
+ return std::tie(key, value, source) ==
+ std::tie(other.key, other.value, other.source);
+ }
+ };
+
+ struct ObservedDelete {
+ Vector<uint8_t> key;
+ String source;
+
+ bool operator==(const ObservedDelete& other) const {
+ return std::tie(key, source) == std::tie(other.key, other.source);
+ }
+ };
+
+ struct KeyValue {
+ Vector<uint8_t> key;
+ Vector<uint8_t> value;
+ };
+
MockStorageArea();
~MockStorageArea() override;
mojo::PendingRemote<mojom::blink::StorageArea> GetInterfaceRemote();
- mojo::PendingAssociatedRemote<mojom::blink::StorageArea>
- GetAssociatedInterfaceRemote();
+
+ void InjectKeyValue(const Vector<uint8_t>& key, const Vector<uint8_t>& value);
+ void Clear();
// StorageArea implementation:
void AddObserver(
- mojo::PendingAssociatedRemote<mojom::blink::StorageAreaObserver> observer)
- override;
-
+ mojo::PendingRemote<mojom::blink::StorageAreaObserver> observer) override;
void Put(const Vector<uint8_t>& key,
const Vector<uint8_t>& value,
const base::Optional<Vector<uint8_t>>& client_old_value,
const String& source,
PutCallback callback) override;
-
void Delete(const Vector<uint8_t>& key,
const base::Optional<Vector<uint8_t>>& client_old_value,
const String& source,
DeleteCallback callback) override;
-
- void DeleteAll(const String& source, DeleteAllCallback callback) override;
-
+ void DeleteAll(
+ const String& source,
+ mojo::PendingRemote<mojom::blink::StorageAreaObserver> new_observer,
+ DeleteAllCallback callback) override;
void Get(const Vector<uint8_t>& key, GetCallback callback) override;
-
- void GetAll(mojo::PendingAssociatedRemote<
- mojom::blink::StorageAreaGetAllCallback> complete_callback,
- GetAllCallback callback) override;
+ void GetAll(
+ mojo::PendingRemote<mojom::blink::StorageAreaObserver> new_observer,
+ GetAllCallback callback) override;
// Methods and members for use by test fixtures.
- bool HasBindings() {
- return !receivers_.empty() || !associated_receivers_.empty();
- }
+ bool HasBindings() { return !receivers_.empty(); }
void ResetObservations() {
- observed_get_all_ = false;
- observed_put_ = false;
- observed_delete_ = false;
- observed_delete_all_ = false;
- observed_key_.clear();
- observed_value_.clear();
- observed_source_ = String();
- }
-
- void CompleteAllPendingCallbacks() {
- while (!pending_callbacks_.empty())
- CompleteOnePendingCallback(true);
- }
-
- void CompleteOnePendingCallback(bool success) {
- ASSERT_TRUE(!pending_callbacks_.empty());
- std::move(pending_callbacks_.front()).Run(success);
- pending_callbacks_.pop_front();
+ observed_get_alls_ = 0;
+ observed_puts_.clear();
+ observed_deletes_.clear();
+ observed_delete_alls_.clear();
}
void Flush() {
receivers_.FlushForTesting();
- associated_receivers_.FlushForTesting();
}
void CloseAllBindings() {
receivers_.Clear();
- associated_receivers_.Clear();
}
- size_t pending_callbacks_count() const { return pending_callbacks_.size(); }
-
- bool observed_get_all() const { return observed_get_all_; }
- bool observed_put() const { return observed_put_; }
- bool observed_delete() const { return observed_delete_; }
- bool observed_delete_all() const { return observed_delete_all_; }
- const Vector<uint8_t>& observed_key() const { return observed_key_; }
- const Vector<uint8_t>& observed_value() const { return observed_value_; }
- const String& observed_source() const { return observed_source_; }
- size_t observer_count() const { return observer_count_; }
-
- Vector<mojom::blink::KeyValuePtr>& mutable_get_all_return_values() {
- return get_all_return_values_;
+ int observed_get_alls() const { return observed_get_alls_; }
+ const Vector<ObservedPut>& observed_puts() const { return observed_puts_; }
+ const Vector<ObservedDelete>& observed_deletes() const {
+ return observed_deletes_;
}
+ const Vector<String>& observed_delete_alls() const {
+ return observed_delete_alls_;
+ }
+ size_t observer_count() const { return observer_count_; }
private:
- Deque<ResultCallback> pending_callbacks_;
- bool observed_get_all_ = false;
- bool observed_put_ = false;
- bool observed_delete_ = false;
- bool observed_delete_all_ = false;
- Vector<uint8_t> observed_key_;
- Vector<uint8_t> observed_value_;
- String observed_source_;
+ int observed_get_alls_ = 0;
+ Vector<ObservedPut> observed_puts_;
+ Vector<ObservedDelete> observed_deletes_;
+ Vector<String> observed_delete_alls_;
size_t observer_count_ = 0;
- Vector<mojom::blink::KeyValuePtr> get_all_return_values_;
+ Vector<KeyValue> key_values_;
mojo::ReceiverSet<mojom::blink::StorageArea> receivers_;
- mojo::AssociatedReceiverSet<mojom::blink::StorageArea> associated_receivers_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/vibration/BUILD.gn b/chromium/third_party/blink/renderer/modules/vibration/BUILD.gn
index f4012cb7a1d..a09c7f44646 100644
--- a/chromium/third_party/blink/renderer/modules/vibration/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/vibration/BUILD.gn
@@ -12,7 +12,5 @@ blink_modules_sources("vibration") {
"vibration_controller.h",
]
- deps = [
- "//services/service_manager/public/cpp",
- ]
+ deps = [ "//services/service_manager/public/cpp" ]
}
diff --git a/chromium/third_party/blink/renderer/modules/vibration/idls.gni b/chromium/third_party/blink/renderer/modules/vibration/idls.gni
new file mode 100644
index 00000000000..41a2729d594
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/vibration/idls.gni
@@ -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.
+
+modules_dependency_idl_files = [ "navigator_vibration.idl" ]
+
+modules_testing_dependency_idl_files = [ "testing/internals_vibration.idl" ]
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 74ec2f12a7d..a74c74aa0df 100644
--- a/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.cc
+++ b/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.cc
@@ -19,6 +19,7 @@
#include "third_party/blink/renderer/modules/vibration/navigator_vibration.h"
+#include "base/metrics/histogram_functions.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/frame_console.h"
@@ -29,13 +30,12 @@
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/modules/vibration/vibration_controller.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
namespace blink {
NavigatorVibration::NavigatorVibration(Navigator& navigator)
- : ContextLifecycleObserver(navigator.GetFrame()->GetDocument()) {}
+ : ExecutionContextLifecycleObserver(navigator.GetFrame()->GetDocument()) {}
NavigatorVibration::~NavigatorVibration() = default;
@@ -77,9 +77,9 @@ bool NavigatorVibration::vibrate(Navigator& navigator,
if (!frame->GetPage()->IsPageVisible())
return false;
- if (!frame->HasBeenActivated()) {
+ if (!frame->HasStickyUserActivation()) {
String message;
- if (frame->IsCrossOriginSubframe()) {
+ if (frame->IsCrossOriginToMainFrame()) {
message =
"Blocked call to navigator.vibrate inside a cross-origin "
"iframe because the frame has never been activated by the user: "
@@ -103,13 +103,13 @@ bool NavigatorVibration::vibrate(Navigator& navigator,
void NavigatorVibration::CollectHistogramMetrics(const Navigator& navigator) {
NavigatorVibrationType type;
LocalFrame* frame = navigator.GetFrame();
- bool user_gesture = frame->HasBeenActivated();
+ bool user_gesture = frame->HasStickyUserActivation();
UseCounter::Count(navigator.DomWindow()->document(),
WebFeature::kNavigatorVibrate);
if (!frame->IsMainFrame()) {
UseCounter::Count(navigator.DomWindow()->document(),
WebFeature::kNavigatorVibrateSubFrame);
- if (frame->IsCrossOriginSubframe()) {
+ if (frame->IsCrossOriginToMainFrame()) {
if (user_gesture)
type = NavigatorVibrationType::kCrossOriginSubFrameWithUserGesture;
else
@@ -126,9 +126,7 @@ void NavigatorVibration::CollectHistogramMetrics(const Navigator& navigator) {
else
type = NavigatorVibrationType::kMainFrameNoUserGesture;
}
- DEFINE_STATIC_LOCAL(EnumerationHistogram, navigator_vibrate_histogram,
- ("Vibration.Context", NavigatorVibrationType::kEnumMax));
- navigator_vibrate_histogram.Count(type);
+ base::UmaHistogramEnumeration("Vibration.Context", type);
}
VibrationController* NavigatorVibration::Controller(LocalFrame& frame) {
@@ -138,17 +136,17 @@ VibrationController* NavigatorVibration::Controller(LocalFrame& frame) {
return controller_.Get();
}
-void NavigatorVibration::ContextDestroyed(ExecutionContext*) {
+void NavigatorVibration::ContextDestroyed() {
if (controller_) {
controller_->Cancel();
controller_ = nullptr;
}
}
-void NavigatorVibration::Trace(blink::Visitor* visitor) {
+void NavigatorVibration::Trace(Visitor* visitor) {
visitor->Trace(controller_);
Supplement<Navigator>::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 c478a282200..c584bdd831d 100644
--- a/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.h
+++ b/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.h
@@ -21,7 +21,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_VIBRATION_NAVIGATOR_VIBRATION_H_
#include "base/macros.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/frame/navigator.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
@@ -35,20 +35,22 @@ class LocalFrame;
class Navigator;
class VibrationController;
-enum NavigatorVibrationType {
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum class NavigatorVibrationType {
kMainFrameNoUserGesture = 0,
kMainFrameWithUserGesture = 1,
kSameOriginSubFrameNoUserGesture = 2,
kSameOriginSubFrameWithUserGesture = 3,
kCrossOriginSubFrameNoUserGesture = 4,
kCrossOriginSubFrameWithUserGesture = 5,
- kEnumMax = 6
+ kMaxValue = kCrossOriginSubFrameWithUserGesture,
};
class MODULES_EXPORT NavigatorVibration final
: public GarbageCollected<NavigatorVibration>,
public Supplement<Navigator>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(NavigatorVibration);
public:
@@ -66,11 +68,11 @@ class MODULES_EXPORT NavigatorVibration final
VibrationController* Controller(LocalFrame&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
- // Inherited from ContextLifecycleObserver.
- void ContextDestroyed(ExecutionContext*) override;
+ // Inherited from ExecutionContextLifecycleObserver.
+ void ContextDestroyed() override;
static void CollectHistogramMetrics(const Navigator&);
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 c42f2033249..591515c2029 100644
--- a/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.cc
+++ b/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.cc
@@ -24,6 +24,7 @@
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_or_unsigned_long_sequence.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/navigator.h"
#include "third_party/blink/renderer/core/page/page.h"
@@ -76,8 +77,9 @@ VibrationController::SanitizeVibrationPattern(
}
VibrationController::VibrationController(LocalFrame& frame)
- : ContextLifecycleObserver(frame.GetDocument()),
+ : ExecutionContextLifecycleObserver(frame.GetDocument()),
PageVisibilityObserver(frame.GetDocument()->GetPage()),
+ vibration_manager_(frame.DomWindow()),
timer_do_vibrate_(
frame.GetDocument()->GetTaskRunner(TaskType::kMiscPlatformAPI),
this,
@@ -86,7 +88,8 @@ VibrationController::VibrationController(LocalFrame& frame)
is_calling_cancel_(false),
is_calling_vibrate_(false) {
frame.GetBrowserInterfaceBroker().GetInterface(
- vibration_manager_.BindNewPipeAndPassReceiver());
+ vibration_manager_.BindNewPipeAndPassReceiver(
+ frame.GetDocument()->GetTaskRunner(TaskType::kMiscPlatformAPI)));
}
VibrationController::~VibrationController() = default;
@@ -126,7 +129,7 @@ void VibrationController::DoVibrate(TimerBase* timer) {
!GetExecutionContext() || !GetPage()->IsPageVisible())
return;
- if (vibration_manager_) {
+ if (vibration_manager_.is_bound()) {
is_calling_vibrate_ = true;
vibration_manager_->Vibrate(
pattern_[0],
@@ -160,7 +163,7 @@ void VibrationController::Cancel() {
pattern_.clear();
timer_do_vibrate_.Stop();
- if (is_running_ && !is_calling_cancel_ && vibration_manager_) {
+ if (is_running_ && !is_calling_cancel_ && vibration_manager_.is_bound()) {
is_calling_cancel_ = true;
vibration_manager_->Cancel(
WTF::Bind(&VibrationController::DidCancel, WrapPersistent(this)));
@@ -178,11 +181,8 @@ void VibrationController::DidCancel() {
timer_do_vibrate_.StartOneShot(base::TimeDelta(), FROM_HERE);
}
-void VibrationController::ContextDestroyed(ExecutionContext*) {
+void VibrationController::ContextDestroyed() {
Cancel();
-
- // If the document context was destroyed, never call the mojo service again.
- vibration_manager_.reset();
}
void VibrationController::PageVisibilityChanged() {
@@ -190,9 +190,10 @@ void VibrationController::PageVisibilityChanged() {
Cancel();
}
-void VibrationController::Trace(blink::Visitor* visitor) {
- ContextLifecycleObserver::Trace(visitor);
+void VibrationController::Trace(Visitor* visitor) {
+ ExecutionContextLifecycleObserver::Trace(visitor);
PageVisibilityObserver::Trace(visitor);
+ visitor->Trace(vibration_manager_);
}
} // namespace blink
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 3e4153725b0..39ff943d8b7 100644
--- a/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.h
+++ b/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.h
@@ -21,13 +21,13 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_VIBRATION_VIBRATION_CONTROLLER_H_
#include "base/macros.h"
-#include "mojo/public/cpp/bindings/remote.h"
#include "services/device/public/mojom/vibration_manager.mojom-blink.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/page/page_visibility_observer.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/handle.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -38,7 +38,7 @@ class UnsignedLongOrUnsignedLongSequence;
class MODULES_EXPORT VibrationController final
: public GarbageCollected<VibrationController>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public PageVisibilityObserver {
USING_GARBAGE_COLLECTED_MIXIN(VibrationController);
@@ -65,18 +65,18 @@ class MODULES_EXPORT VibrationController final
VibrationPattern Pattern() const { return pattern_; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
- // Inherited from ContextLifecycleObserver.
- void ContextDestroyed(ExecutionContext*) override;
+ // Inherited from ExecutionContextLifecycleObserver.
+ void ContextDestroyed() override;
// Inherited from PageVisibilityObserver.
void PageVisibilityChanged() override;
// Remote to VibrationManager mojo interface. This is reset in
// |contextDestroyed| and must not be called or recreated after it is reset.
- mojo::Remote<device::mojom::blink::VibrationManager> vibration_manager_;
+ HeapMojoRemote<device::mojom::blink::VibrationManager> vibration_manager_;
// Timer for calling |doVibrate| after a delay. It is safe to call
// |startOneshot| when the timer is already running: it may affect the time
diff --git a/chromium/third_party/blink/renderer/modules/video_raf/html_video_element_video_request_animation_frame.idl b/chromium/third_party/blink/renderer/modules/video_raf/html_video_element_video_request_animation_frame.idl
deleted file mode 100644
index fb8b63ed0b7..00000000000
--- a/chromium/third_party/blink/renderer/modules/video_raf/html_video_element_video_request_animation_frame.idl
+++ /dev/null
@@ -1,12 +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.
-
-// TODO(https://crbug.com/1022186): Add pointer to video.rAF spec.
-[
- RuntimeEnabled=VideoRequestAnimationFrame,
- ImplementedAs=VideoRequestAnimationFrameImpl
-] partial interface HTMLVideoElement {
- long requestAnimationFrame(VideoFrameRequestCallback callback);
- void cancelAnimationFrame(long handle);
-}; \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/video_raf/video_request_animation_frame_impl.cc b/chromium/third_party/blink/renderer/modules/video_raf/video_request_animation_frame_impl.cc
deleted file mode 100644
index eaa07f261e0..00000000000
--- a/chromium/third_party/blink/renderer/modules/video_raf/video_request_animation_frame_impl.cc
+++ /dev/null
@@ -1,141 +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/video_raf/video_request_animation_frame_impl.h"
-
-#include <memory>
-#include <utility>
-
-#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/loader/document_loader.h"
-#include "third_party/blink/renderer/modules/video_raf/video_frame_metadata.h"
-#include "third_party/blink/renderer/modules/video_raf/video_frame_request_callback_collection.h"
-
-namespace blink {
-
-VideoRequestAnimationFrameImpl::VideoRequestAnimationFrameImpl(
- HTMLVideoElement& element)
- : VideoRequestAnimationFrame(element),
- callback_collection_(
- MakeGarbageCollected<VideoFrameRequestCallbackCollection>(
- element.GetExecutionContext())) {}
-
-// static
-VideoRequestAnimationFrameImpl& VideoRequestAnimationFrameImpl::From(
- HTMLVideoElement& element) {
- VideoRequestAnimationFrameImpl* supplement =
- Supplement<HTMLVideoElement>::From<VideoRequestAnimationFrameImpl>(
- element);
- if (!supplement) {
- supplement = MakeGarbageCollected<VideoRequestAnimationFrameImpl>(element);
- Supplement<HTMLVideoElement>::ProvideTo(element, supplement);
- }
-
- return *supplement;
-}
-
-// static
-int VideoRequestAnimationFrameImpl::requestAnimationFrame(
- HTMLVideoElement& element,
- V8VideoFrameRequestCallback* callback) {
- return VideoRequestAnimationFrameImpl::From(element).requestAnimationFrame(
- callback);
-}
-
-// static
-void VideoRequestAnimationFrameImpl::cancelAnimationFrame(
- HTMLVideoElement& element,
- int callback_id) {
- VideoRequestAnimationFrameImpl::From(element).cancelAnimationFrame(
- callback_id);
-}
-
-void VideoRequestAnimationFrameImpl::OnWebMediaPlayerCreated() {
- DCHECK(RuntimeEnabledFeatures::VideoRequestAnimationFrameEnabled());
- if (callback_collection_->HasFrameCallback())
- GetSupplementable()->GetWebMediaPlayer()->RequestAnimationFrame();
-}
-
-void VideoRequestAnimationFrameImpl::OnRequestAnimationFrame(
- base::TimeTicks presentation_time,
- base::TimeTicks expected_presentation_time,
- uint32_t presented_frames_counter,
- const media::VideoFrame& presented_frame) {
- DCHECK(RuntimeEnabledFeatures::VideoRequestAnimationFrameEnabled());
-
- // Skip this work if there are no registered callbacks.
- if (callback_collection_->IsEmpty())
- return;
-
- auto& time_converter =
- GetSupplementable()->GetDocument().Loader()->GetTiming();
- auto* metadata = VideoFrameMetadata::Create();
-
- metadata->setPresentationTime(
- time_converter.MonotonicTimeToZeroBasedDocumentTime(presentation_time)
- .InMillisecondsF());
-
- metadata->setExpectedPresentationTime(
- time_converter
- .MonotonicTimeToZeroBasedDocumentTime(expected_presentation_time)
- .InMillisecondsF());
-
- metadata->setWidth(presented_frame.visible_rect().width());
- metadata->setHeight(presented_frame.visible_rect().height());
-
- metadata->setPresentationTimestamp(presented_frame.timestamp().InSecondsF());
-
- base::TimeDelta elapsed;
- if (presented_frame.metadata()->GetTimeDelta(
- media::VideoFrameMetadata::PROCESSING_TIME, &elapsed)) {
- metadata->setElapsedProcessingTime(elapsed.InSecondsF());
- }
-
- metadata->setPresentedFrames(presented_frames_counter);
-
- base::TimeTicks time;
- if (presented_frame.metadata()->GetTimeTicks(
- media::VideoFrameMetadata::CAPTURE_BEGIN_TIME, &time)) {
- metadata->setElapsedProcessingTime(
- time_converter.MonotonicTimeToZeroBasedDocumentTime(time)
- .InMillisecondsF());
- }
-
- double rtp_timestamp;
- if (presented_frame.metadata()->GetDouble(
- media::VideoFrameMetadata::RTP_TIMESTAMP, &rtp_timestamp)) {
- base::CheckedNumeric<uint32_t> uint_rtp_timestamp = rtp_timestamp;
- if (uint_rtp_timestamp.IsValid())
- metadata->setRtpTimestamp(rtp_timestamp);
- }
-
- callback_collection_->ExecuteFrameCallbacks(
- time_converter
- .MonotonicTimeToZeroBasedDocumentTime(base::TimeTicks::Now())
- .InMillisecondsF(),
- metadata);
-}
-
-int VideoRequestAnimationFrameImpl::requestAnimationFrame(
- V8VideoFrameRequestCallback* callback) {
- if (auto* player = GetSupplementable()->GetWebMediaPlayer())
- player->RequestAnimationFrame();
-
- auto* frame_callback = MakeGarbageCollected<
- VideoFrameRequestCallbackCollection::V8VideoFrameCallback>(callback);
-
- return callback_collection_->RegisterFrameCallback(frame_callback);
-}
-
-void VideoRequestAnimationFrameImpl::cancelAnimationFrame(int id) {
- callback_collection_->CancelFrameCallback(id);
-}
-
-void VideoRequestAnimationFrameImpl::Trace(blink::Visitor* visitor) {
- visitor->Trace(callback_collection_);
- Supplement<HTMLVideoElement>::Trace(visitor);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/video_raf/video_request_animation_frame_impl.h b/chromium/third_party/blink/renderer/modules/video_raf/video_request_animation_frame_impl.h
deleted file mode 100644
index 978ba3a6ef9..00000000000
--- a/chromium/third_party/blink/renderer/modules/video_raf/video_request_animation_frame_impl.h
+++ /dev/null
@@ -1,56 +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_VIDEO_RAF_VIDEO_REQUEST_ANIMATION_FRAME_IMPL_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_VIDEO_RAF_VIDEO_REQUEST_ANIMATION_FRAME_IMPL_H_
-
-#include "media/base/video_frame.h"
-#include "third_party/blink/renderer/core/html/media/html_video_element.h"
-#include "third_party/blink/renderer/core/html/media/video_request_animation_frame.h"
-#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/modules/video_raf/video_frame_request_callback_collection.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/supplementable.h"
-
-namespace blink {
-
-class HTMLVideoElement;
-
-// Implementation of the <video>.requestAnimationFrame() API.
-// Extends HTMLVideoElement via the VideoRequestAnimationFrame interface.
-class MODULES_EXPORT VideoRequestAnimationFrameImpl final
- : public VideoRequestAnimationFrame {
- USING_GARBAGE_COLLECTED_MIXIN(VideoRequestAnimationFrameImpl);
-
- public:
- static VideoRequestAnimationFrameImpl& From(HTMLVideoElement&);
-
- // Web API entry points for requestAnimationFrame().
- static int requestAnimationFrame(HTMLVideoElement&,
- V8VideoFrameRequestCallback*);
- static void cancelAnimationFrame(HTMLVideoElement&, int);
-
- explicit VideoRequestAnimationFrameImpl(HTMLVideoElement&);
- ~VideoRequestAnimationFrameImpl() override = default;
-
- void Trace(blink::Visitor*) override;
-
- int requestAnimationFrame(V8VideoFrameRequestCallback*);
- void cancelAnimationFrame(int);
-
- void OnWebMediaPlayerCreated() override;
- void OnRequestAnimationFrame(base::TimeTicks presentation_time,
- base::TimeTicks expected_presentation_time,
- uint32_t presented_frames_counter,
- const media::VideoFrame&) override;
-
- private:
- Member<VideoFrameRequestCallbackCollection> callback_collection_;
-
- DISALLOW_COPY_AND_ASSIGN(VideoRequestAnimationFrameImpl);
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_VIDEO_RAF_VIDEO_REQUEST_ANIMATION_FRAME_IMPL_H_
diff --git a/chromium/third_party/blink/renderer/modules/video_raf/BUILD.gn b/chromium/third_party/blink/renderer/modules/video_rvfc/BUILD.gn
index 10aba6b2746..6c561e7dbef 100644
--- a/chromium/third_party/blink/renderer/modules/video_raf/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/video_rvfc/BUILD.gn
@@ -4,11 +4,11 @@
import("//third_party/blink/renderer/modules/modules.gni")
-blink_modules_sources("video_raf") {
+blink_modules_sources("video_rvfc") {
sources = [
+ "video_frame_callback_requester_impl.cc",
+ "video_frame_callback_requester_impl.h",
"video_frame_request_callback_collection.cc",
"video_frame_request_callback_collection.h",
- "video_request_animation_frame_impl.cc",
- "video_request_animation_frame_impl.h",
]
}
diff --git a/chromium/third_party/blink/renderer/modules/video_raf/DEPS b/chromium/third_party/blink/renderer/modules/video_rvfc/DEPS
index 4430949198d..26a030c42bc 100644
--- a/chromium/third_party/blink/renderer/modules/video_raf/DEPS
+++ b/chromium/third_party/blink/renderer/modules/video_rvfc/DEPS
@@ -1,3 +1,4 @@
include_rules = [
+ "+media/base/media_switches.h",
"+media/base/video_frame.h",
-] \ No newline at end of file
+]
diff --git a/chromium/third_party/blink/renderer/modules/video_rvfc/OWNERS b/chromium/third_party/blink/renderer/modules/video_rvfc/OWNERS
new file mode 100644
index 00000000000..5cb69a44bd7
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/video_rvfc/OWNERS
@@ -0,0 +1,2 @@
+dalecurtis@chromium.org
+tguilbert@chromium.org
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
new file mode 100644
index 00000000000..0f5d39704e6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/video_rvfc/html_video_element_request_video_frame_callback.idl
@@ -0,0 +1,12 @@
+// 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.
+
+// See https://wicg.github.io/video-raf/.
+[
+ RuntimeEnabled=RequestVideoFrameCallback,
+ ImplementedAs=VideoFrameCallbackRequesterImpl
+] partial interface HTMLVideoElement {
+ long requestVideoFrameCallback(VideoFrameRequestCallback callback);
+ void cancelVideoFrameCallback(long handle);
+}; \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/video_rvfc/idls.gni b/chromium/third_party/blink/renderer/modules/video_rvfc/idls.gni
new file mode 100644
index 00000000000..5590aab117c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/video_rvfc/idls.gni
@@ -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.
+
+modules_callback_function_idl_files = [ "video_frame_request_callback.idl" ]
+
+modules_dictionary_idl_files = [ "video_frame_metadata.idl" ]
+
+modules_dependency_idl_files =
+ [ "html_video_element_request_video_frame_callback.idl" ]
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
new file mode 100644
index 00000000000..35c4a9b5da1
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.cc
@@ -0,0 +1,271 @@
+// 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/video_rvfc/video_frame_callback_requester_impl.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/trace_event/trace_event.h"
+#include "media/base/media_switches.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_video_frame_metadata.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/dom/scripted_animation_controller.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/loader/document_loader.h"
+#include "third_party/blink/renderer/core/timing/performance.h"
+#include "third_party/blink/renderer/core/timing/time_clamper.h"
+#include "third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.h"
+#include "third_party/blink/renderer/platform/bindings/microtask.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
+
+namespace blink {
+
+namespace {
+// Returns whether or not a video's frame rate is close to the browser's frame
+// rate, as measured by their rendering intervals. For example, on a 60hz
+// screen, this should return false for a 25fps video and true for a 60fps
+// video. On a 144hz screen, both videos would return false.
+static bool IsFrameRateRelativelyHigh(base::TimeDelta rendering_interval,
+ base::TimeDelta average_frame_duration) {
+ if (average_frame_duration.is_zero())
+ return false;
+
+ constexpr double kThreshold = 0.05;
+ return kThreshold >
+ std::abs(1.0 - (rendering_interval.InMillisecondsF() /
+ average_frame_duration.InMillisecondsF()));
+}
+
+} // namespace
+
+VideoFrameCallbackRequesterImpl::VideoFrameCallbackRequesterImpl(
+ HTMLVideoElement& element)
+ : VideoFrameCallbackRequester(element),
+ callback_collection_(
+ MakeGarbageCollected<VideoFrameRequestCallbackCollection>(
+ element.GetExecutionContext())) {}
+
+// static
+VideoFrameCallbackRequesterImpl& VideoFrameCallbackRequesterImpl::From(
+ HTMLVideoElement& element) {
+ VideoFrameCallbackRequesterImpl* supplement =
+ Supplement<HTMLVideoElement>::From<VideoFrameCallbackRequesterImpl>(
+ element);
+ if (!supplement) {
+ supplement = MakeGarbageCollected<VideoFrameCallbackRequesterImpl>(element);
+ Supplement<HTMLVideoElement>::ProvideTo(element, supplement);
+ }
+
+ return *supplement;
+}
+
+// static
+int VideoFrameCallbackRequesterImpl::requestVideoFrameCallback(
+ HTMLVideoElement& element,
+ V8VideoFrameRequestCallback* callback) {
+ return VideoFrameCallbackRequesterImpl::From(element)
+ .requestVideoFrameCallback(callback);
+}
+
+// static
+void VideoFrameCallbackRequesterImpl::cancelVideoFrameCallback(
+ HTMLVideoElement& element,
+ int callback_id) {
+ VideoFrameCallbackRequesterImpl::From(element).cancelVideoFrameCallback(
+ callback_id);
+}
+
+void VideoFrameCallbackRequesterImpl::OnWebMediaPlayerCreated() {
+ DCHECK(RuntimeEnabledFeatures::RequestVideoFrameCallbackEnabled());
+ if (!callback_collection_->IsEmpty())
+ GetSupplementable()->GetWebMediaPlayer()->RequestVideoFrameCallback();
+}
+
+void VideoFrameCallbackRequesterImpl::ScheduleCallbackExecution() {
+ TRACE_EVENT1("blink",
+ "VideoFrameCallbackRequesterImpl::ScheduleCallbackExecution",
+ "did_schedule", !pending_execution_);
+
+ if (pending_execution_)
+ return;
+
+ pending_execution_ = true;
+ GetSupplementable()
+ ->GetDocument()
+ .GetScriptedAnimationController()
+ .ScheduleVideoFrameCallbacksExecution(
+ WTF::Bind(&VideoFrameCallbackRequesterImpl::OnRenderingSteps,
+ WrapWeakPersistent(this)));
+}
+
+void VideoFrameCallbackRequesterImpl::OnRequestVideoFrameCallback() {
+ DCHECK(RuntimeEnabledFeatures::RequestVideoFrameCallbackEnabled());
+ TRACE_EVENT1("blink",
+ "VideoFrameCallbackRequesterImpl::OnRequestVideoFrameCallback",
+ "has_callbacks", !callback_collection_->IsEmpty());
+
+ // Skip this work if there are no registered callbacks.
+ if (callback_collection_->IsEmpty())
+ return;
+
+ ScheduleCallbackExecution();
+}
+
+void VideoFrameCallbackRequesterImpl::ExecuteVideoFrameCallbacks(
+ double high_res_now_ms,
+ std::unique_ptr<WebMediaPlayer::VideoFramePresentationMetadata>
+ frame_metadata) {
+ TRACE_EVENT0("blink",
+ "VideoFrameCallbackRequesterImpl::ExecuteVideoFrameCallbacks");
+
+ last_presented_frames_ = frame_metadata->presented_frames;
+
+ auto* metadata = VideoFrameMetadata::Create();
+ auto& time_converter =
+ GetSupplementable()->GetDocument().Loader()->GetTiming();
+
+ metadata->setPresentationTime(GetClampedTimeInMillis(
+ time_converter.MonotonicTimeToZeroBasedDocumentTime(
+ frame_metadata->presentation_time)));
+
+ metadata->setExpectedDisplayTime(GetClampedTimeInMillis(
+ time_converter.MonotonicTimeToZeroBasedDocumentTime(
+ frame_metadata->expected_display_time)));
+
+ metadata->setPresentedFrames(frame_metadata->presented_frames);
+
+ metadata->setWidth(frame_metadata->width);
+ metadata->setHeight(frame_metadata->height);
+
+ 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));
+ }
+
+ base::TimeTicks capture_time;
+ if (frame_metadata->metadata.GetTimeTicks(
+ media::VideoFrameMetadata::CAPTURE_BEGIN_TIME, &capture_time)) {
+ metadata->setCaptureTime(GetClampedTimeInMillis(
+ time_converter.MonotonicTimeToZeroBasedDocumentTime(capture_time)));
+ }
+
+ base::TimeTicks receive_time;
+ if (frame_metadata->metadata.GetTimeTicks(
+ media::VideoFrameMetadata::RECEIVE_TIME, &receive_time)) {
+ metadata->setReceiveTime(GetClampedTimeInMillis(
+ time_converter.MonotonicTimeToZeroBasedDocumentTime(receive_time)));
+ }
+
+ double rtp_timestamp;
+ if (frame_metadata->metadata.GetDouble(
+ media::VideoFrameMetadata::RTP_TIMESTAMP, &rtp_timestamp)) {
+ base::CheckedNumeric<uint32_t> uint_rtp_timestamp = rtp_timestamp;
+ if (uint_rtp_timestamp.IsValid())
+ metadata->setRtpTimestamp(rtp_timestamp);
+ }
+
+ callback_collection_->ExecuteFrameCallbacks(high_res_now_ms, metadata);
+}
+
+void VideoFrameCallbackRequesterImpl::OnRenderingSteps(double high_res_now_ms) {
+ DCHECK(pending_execution_);
+ TRACE_EVENT1("blink", "VideoFrameCallbackRequesterImpl::OnRenderingSteps",
+ "has_callbacks", !callback_collection_->IsEmpty());
+
+ pending_execution_ = false;
+
+ // Callbacks could have been canceled from the time we scheduled their
+ // execution.
+ if (callback_collection_->IsEmpty())
+ return;
+
+ auto* player = GetSupplementable()->GetWebMediaPlayer();
+ if (!player)
+ return;
+
+ auto metadata = player->GetVideoFramePresentationMetadata();
+
+ const bool is_hfr = IsFrameRateRelativelyHigh(
+ metadata->rendering_interval, metadata->average_frame_duration);
+
+ // Check if we have a new frame or not.
+ if (last_presented_frames_ == metadata->presented_frames) {
+ ++consecutive_stale_frames_;
+ } else {
+ consecutive_stale_frames_ = 0;
+ ExecuteVideoFrameCallbacks(high_res_now_ms, std::move(metadata));
+ }
+
+ // If the video's frame rate is relatively close to the screen's refresh rate
+ // (or brower's current frame rate), schedule ourselves immediately.
+ // Otherwise, jittering and thread hopping means that the call to
+ // OnRequestVideoFrameCallback() would barely miss the rendering steps, and we
+ // would miss a frame.
+ // Also check |consecutive_stale_frames_| to make sure we don't schedule
+ // executions when paused, or in other scenarios where potentially scheduling
+ // extra rendering steps would be wasteful.
+ if (is_hfr && !callback_collection_->IsEmpty() &&
+ consecutive_stale_frames_ < 2) {
+ ScheduleCallbackExecution();
+ }
+}
+
+// static
+double VideoFrameCallbackRequesterImpl::GetClampedTimeInMillis(
+ base::TimeDelta time) {
+ constexpr double kSecondsToMillis = 1000.0;
+ return Performance::ClampTimeResolution(time.InSecondsF()) * kSecondsToMillis;
+}
+
+// static
+double VideoFrameCallbackRequesterImpl::GetCoarseClampedTimeInSeconds(
+ base::TimeDelta time) {
+ constexpr double kCoarseResolutionInSeconds = 100e-6;
+ // Add this assert, in case TimeClamper's resolution were to change to be
+ // stricter.
+ static_assert(kCoarseResolutionInSeconds >= TimeClamper::kResolutionSeconds,
+ "kCoarseResolutionInSeconds should be at least "
+ "as coarse as other clock resolutions");
+ double interval = floor(time.InSecondsF() / kCoarseResolutionInSeconds);
+ double clamped_time = interval * kCoarseResolutionInSeconds;
+
+ return clamped_time;
+}
+
+int VideoFrameCallbackRequesterImpl::requestVideoFrameCallback(
+ V8VideoFrameRequestCallback* callback) {
+ TRACE_EVENT0("blink",
+ "VideoFrameCallbackRequesterImpl::requestVideoFrameCallback");
+
+ if (auto* player = GetSupplementable()->GetWebMediaPlayer())
+ player->RequestVideoFrameCallback();
+
+ auto* frame_callback = MakeGarbageCollected<
+ VideoFrameRequestCallbackCollection::V8VideoFrameCallback>(callback);
+
+ return callback_collection_->RegisterFrameCallback(frame_callback);
+}
+
+void VideoFrameCallbackRequesterImpl::RegisterCallbackForTest(
+ VideoFrameRequestCallbackCollection::VideoFrameCallback* callback) {
+ pending_execution_ = true;
+
+ callback_collection_->RegisterFrameCallback(callback);
+}
+
+void VideoFrameCallbackRequesterImpl::cancelVideoFrameCallback(int id) {
+ callback_collection_->CancelFrameCallback(id);
+}
+
+void VideoFrameCallbackRequesterImpl::Trace(Visitor* visitor) {
+ visitor->Trace(callback_collection_);
+ Supplement<HTMLVideoElement>::Trace(visitor);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..b926f645555
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.h
@@ -0,0 +1,93 @@
+// 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_VIDEO_RVFC_VIDEO_FRAME_CALLBACK_REQUESTER_IMPL_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_VIDEO_RVFC_VIDEO_FRAME_CALLBACK_REQUESTER_IMPL_H_
+
+#include "third_party/blink/renderer/core/html/media/html_video_element.h"
+#include "third_party/blink/renderer/core/html/media/video_frame_callback_requester.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/supplementable.h"
+
+namespace blink {
+
+class HTMLVideoElement;
+
+// Implementation of the <video>.requestVideoFrameCallback() API.
+// Extends HTMLVideoElement via the VideoFrameCallbackRequester interface.
+class MODULES_EXPORT VideoFrameCallbackRequesterImpl final
+ : public VideoFrameCallbackRequester {
+ USING_GARBAGE_COLLECTED_MIXIN(VideoFrameCallbackRequesterImpl);
+
+ public:
+ static VideoFrameCallbackRequesterImpl& From(HTMLVideoElement&);
+
+ // Web API entry points for requestAnimationFrame().
+ static int requestVideoFrameCallback(HTMLVideoElement&,
+ V8VideoFrameRequestCallback*);
+ static void cancelVideoFrameCallback(HTMLVideoElement&, int);
+
+ explicit VideoFrameCallbackRequesterImpl(HTMLVideoElement&);
+ ~VideoFrameCallbackRequesterImpl() override = default;
+
+ void Trace(Visitor*) override;
+
+ int requestVideoFrameCallback(V8VideoFrameRequestCallback*);
+ void cancelVideoFrameCallback(int);
+
+ void OnWebMediaPlayerCreated() override;
+ void OnRequestVideoFrameCallback() override;
+
+ // Called by ScriptedAnimationController as part of the rendering steps,
+ // right before the execution of window.rAF callbacks.
+ void OnRenderingSteps(double high_res_now_ms);
+
+ private:
+ friend class VideoFrameCallbackRequesterImplTest;
+
+ // Utility functions to limit the clock resolution of fields, for security
+ // reasons.
+ static double GetClampedTimeInMillis(base::TimeDelta time);
+ static double GetCoarseClampedTimeInSeconds(base::TimeDelta time);
+
+ void ExecuteVideoFrameCallbacks(
+ double high_res_now_ms,
+ std::unique_ptr<WebMediaPlayer::VideoFramePresentationMetadata>);
+
+ // Register a non-V8 callback for testing. Also sets |pending_execution_| to
+ // true, to allow calling into ExecuteFrameCallbacks() directly.
+ void RegisterCallbackForTest(
+ VideoFrameRequestCallbackCollection::VideoFrameCallback*);
+
+ // Adds |this| to the ScriptedAnimationController's queue of video.rAF
+ // callbacks that should be executed during the next rendering steps.
+ // Also causes rendering steps to be scheduled if needed.
+ void ScheduleCallbackExecution();
+
+ // Used to keep track of whether or not we have already scheduled a call to
+ // ExecuteFrameCallbacks() in the next rendering steps.
+ bool pending_execution_ = false;
+
+ // The value of the |metadata->presented_frames| field the last time called
+ // ExecuteFrameCallbacks. Used to determine whether or not a new frame was
+ // presented since we last executed the frame callbacks.
+ // The values coming from the compositor should start at 1, we can use 0
+ // as a "null" starting value.
+ uint32_t last_presented_frames_ = 0;
+
+ // Number of times OnRenderingSteps() was called in a row, without us having a
+ // new frame. Used to abort auto-rescheduling if we aren't consistently
+ // getting new frames.
+ int consecutive_stale_frames_ = 0;
+
+ Member<VideoFrameRequestCallbackCollection> callback_collection_;
+
+ DISALLOW_COPY_AND_ASSIGN(VideoFrameCallbackRequesterImpl);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_VIDEO_RVFC_VIDEO_FRAME_CALLBACK_REQUESTER_IMPL_H_
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
new file mode 100644
index 00000000000..e7c3fe022ac
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl_test.cc
@@ -0,0 +1,383 @@
+// 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/video_rvfc/video_frame_callback_requester_impl.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/core/dom/scripted_animation_controller.h"
+#include "third_party/blink/renderer/core/html/media/html_media_test_helper.h"
+#include "third_party/blink/renderer/core/html/media/html_video_element.h"
+#include "third_party/blink/renderer/core/loader/empty_clients.h"
+#include "third_party/blink/renderer/core/testing/page_test_base.h"
+#include "third_party/blink/renderer/core/timing/performance.h"
+#include "third_party/blink/renderer/platform/testing/empty_web_media_player.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"
+
+using testing::_;
+using testing::ByMove;
+using testing::Invoke;
+using testing::Return;
+
+namespace blink {
+
+using VideoFramePresentationMetadata =
+ WebMediaPlayer::VideoFramePresentationMetadata;
+
+namespace {
+
+class MockWebMediaPlayer : public EmptyWebMediaPlayer {
+ public:
+ MOCK_METHOD0(RequestVideoFrameCallback, void());
+ MOCK_METHOD0(GetVideoFramePresentationMetadata,
+ std::unique_ptr<VideoFramePresentationMetadata>());
+};
+
+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) {}
+};
+
+// Helper class to wrap a VideoFramePresentationData, which can't have a copy
+// constructor, due to it having a media::VideoFrameMetadata instance.
+class MetadataHelper {
+ public:
+ static VideoFramePresentationMetadata* GetDefaultMedatada() {
+ DCHECK(initialized);
+ return &metadata_;
+ }
+
+ static std::unique_ptr<VideoFramePresentationMetadata> CopyDefaultMedatada() {
+ DCHECK(initialized);
+ auto copy = std::make_unique<VideoFramePresentationMetadata>();
+
+ copy->presented_frames = metadata_.presented_frames;
+ copy->presentation_time = metadata_.presentation_time;
+ copy->expected_display_time = metadata_.expected_display_time;
+ copy->width = metadata_.width;
+ copy->height = metadata_.height;
+ copy->media_time = metadata_.media_time;
+ copy->metadata.MergeMetadataFrom(&(metadata_.metadata));
+
+ return copy;
+ }
+
+ static void InitializeFields(base::TimeTicks now) {
+ if (initialized)
+ return;
+
+ // We don't want any time ticks be a multiple of 5us, otherwise, we couldn't
+ // tell whether or not the implementation clamped their values. Therefore,
+ // we manually set the values for a deterministic test, and make sure we
+ // have sub-microsecond resolution for those values.
+
+ metadata_.presented_frames = 42;
+ metadata_.presentation_time =
+ now + base::TimeDelta::FromMillisecondsD(10.1234);
+ metadata_.expected_display_time =
+ now + base::TimeDelta::FromMillisecondsD(26.3467);
+ 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);
+
+ initialized = true;
+ }
+
+ private:
+ static bool initialized;
+ static VideoFramePresentationMetadata metadata_;
+};
+
+bool MetadataHelper::initialized = false;
+VideoFramePresentationMetadata MetadataHelper::metadata_;
+
+// Helper class that compares the parameters used when invoking a callback, with
+// the reference parameters we expect.
+class VfcRequesterParameterVerifierCallback
+ : public VideoFrameRequestCallbackCollection::VideoFrameCallback {
+ public:
+ explicit VfcRequesterParameterVerifierCallback(DocumentLoadTiming& timing)
+ : timing_(timing) {}
+ ~VfcRequesterParameterVerifierCallback() override = default;
+
+ void Invoke(double now, const VideoFrameMetadata* metadata) override {
+ was_invoked_ = true;
+ now_ = now;
+
+ auto* expected = MetadataHelper::GetDefaultMedatada();
+ EXPECT_EQ(expected->presented_frames, metadata->presentedFrames());
+ EXPECT_EQ((unsigned int)expected->width, metadata->width());
+ 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());
+
+ // Verify that values were correctly clamped.
+ VerifyTicksClamping(expected->presentation_time,
+ metadata->presentationTime(), "presentation_time");
+ VerifyTicksClamping(expected->expected_display_time,
+ 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");
+
+ base::TimeTicks receive_time;
+ EXPECT_TRUE(expected->metadata.GetTimeTicks(
+ media::VideoFrameMetadata::RECEIVE_TIME, &receive_time));
+ VerifyTicksClamping(receive_time, metadata->receiveTime(), "receive_time");
+
+ base::TimeDelta processing_time;
+ EXPECT_TRUE(expected->metadata.GetTimeDelta(
+ media::VideoFrameMetadata::PROCESSING_TIME, &processing_time));
+ EXPECT_EQ(ClampElapsedProcessingTime(processing_time),
+ metadata->processingDuration());
+ EXPECT_NE(processing_time.InSecondsF(), metadata->processingDuration());
+ }
+
+ double last_now() { return now_; }
+ bool was_invoked() { return was_invoked_; }
+
+ private:
+ void VerifyTicksClamping(base::TimeTicks reference,
+ double actual,
+ std::string name) {
+ EXPECT_EQ(TicksToClampedMillisecondsF(reference), actual)
+ << name << " was not clamped properly.";
+ EXPECT_NE(TicksToMillisecondsF(reference), actual)
+ << "Did not successfully test clamping for " << name;
+ }
+
+ double TicksToClampedMillisecondsF(base::TimeTicks ticks) {
+ constexpr double kSecondsToMillis = 1000.0;
+ return Performance::ClampTimeResolution(
+ timing_.MonotonicTimeToZeroBasedDocumentTime(ticks)
+ .InSecondsF()) *
+ kSecondsToMillis;
+ }
+
+ double TicksToMillisecondsF(base::TimeTicks ticks) {
+ return timing_.MonotonicTimeToZeroBasedDocumentTime(ticks)
+ .InMillisecondsF();
+ }
+
+ static double ClampElapsedProcessingTime(base::TimeDelta time) {
+ constexpr double kProcessingTimeResolution = 100e-6;
+ double interval = floor(time.InSecondsF() / kProcessingTimeResolution);
+ double clamped_time = interval * kProcessingTimeResolution;
+
+ return clamped_time;
+ }
+
+ double now_;
+ bool was_invoked_ = false;
+ DocumentLoadTiming& timing_;
+};
+
+} // namespace
+
+class VideoFrameCallbackRequesterImplTest
+ : public PageTestBase,
+ private ScopedRequestVideoFrameCallbackForTest {
+ public:
+ VideoFrameCallbackRequesterImplTest()
+ : ScopedRequestVideoFrameCallbackForTest(true) {}
+
+ virtual void SetUpWebMediaPlayer() {
+ auto mock_media_player = std::make_unique<MockWebMediaPlayer>();
+ media_player_ = mock_media_player.get();
+ SetupPageWithClients(nullptr,
+ MakeGarbageCollected<test::MediaStubLocalFrameClient>(
+ std::move(mock_media_player)),
+ nullptr);
+ }
+
+ void SetUp() override {
+ SetUpWebMediaPlayer();
+
+ video_ = MakeGarbageCollected<HTMLVideoElement>(GetDocument());
+ GetDocument().body()->appendChild(video_);
+
+ video()->SetSrc("http://example.com/foo.mp4");
+ test::RunPendingTasks();
+ UpdateAllLifecyclePhasesForTest();
+ }
+
+ HTMLVideoElement* video() { return video_.Get(); }
+
+ MockWebMediaPlayer* media_player() { return media_player_; }
+
+ VideoFrameCallbackRequesterImpl& vfc_requester() {
+ return VideoFrameCallbackRequesterImpl::From(*video());
+ }
+
+ void SimulateFramePresented() { video_->OnRequestVideoFrameCallback(); }
+
+ void SimulateVideoFrameCallback(base::TimeTicks now) {
+ GetDocument().GetScriptedAnimationController().ServiceScriptedAnimations(
+ now);
+ }
+
+ V8VideoFrameRequestCallback* GetCallback(MockFunction* function) {
+ return V8VideoFrameRequestCallback::Create(function->Bind());
+ }
+
+ void RegisterCallbackDirectly(
+ VfcRequesterParameterVerifierCallback* callback) {
+ vfc_requester().RegisterCallbackForTest(callback);
+ }
+
+ private:
+ Persistent<HTMLVideoElement> video_;
+
+ // Owned by HTMLVideoElementFrameClient.
+ MockWebMediaPlayer* media_player_;
+};
+
+class VideoFrameCallbackRequesterImplNullMediaPlayerTest
+ : public VideoFrameCallbackRequesterImplTest {
+ public:
+ void SetUpWebMediaPlayer() override {
+ SetupPageWithClients(nullptr,
+ MakeGarbageCollected<test::MediaStubLocalFrameClient>(
+ std::unique_ptr<MockWebMediaPlayer>(),
+ /* allow_empty_client */ true),
+ nullptr);
+ }
+};
+
+TEST_F(VideoFrameCallbackRequesterImplTest, VerifyRequestVideoFrameCallback) {
+ V8TestingScope scope;
+
+ auto* function = MockFunction::Create(scope.GetScriptState());
+
+ // Queuing up a video.rAF call should propagate to the WebMediaPlayer.
+ EXPECT_CALL(*media_player(), RequestVideoFrameCallback()).Times(1);
+ vfc_requester().requestVideoFrameCallback(GetCallback(function));
+
+ testing::Mock::VerifyAndClear(media_player());
+
+ // Callbacks should not be run immediately when a frame is presented.
+ EXPECT_CALL(*function, Call(_)).Times(0);
+ SimulateFramePresented();
+
+ testing::Mock::VerifyAndClear(function);
+
+ // Callbacks should be called during the rendering steps.
+ auto metadata = std::make_unique<VideoFramePresentationMetadata>();
+ metadata->presented_frames = 1;
+
+ EXPECT_CALL(*function, Call(_)).Times(1);
+ EXPECT_CALL(*media_player(), GetVideoFramePresentationMetadata())
+ .WillOnce(Return(ByMove(std::move(metadata))));
+ SimulateVideoFrameCallback(base::TimeTicks::Now());
+
+ testing::Mock::VerifyAndClear(function);
+}
+
+TEST_F(VideoFrameCallbackRequesterImplTest,
+ VerifyCancelVideoFrameCallback_BeforePresentedFrame) {
+ V8TestingScope scope;
+
+ auto* function = MockFunction::Create(scope.GetScriptState());
+
+ // Queue and cancel a request before a frame is presented.
+ int callback_id =
+ vfc_requester().requestVideoFrameCallback(GetCallback(function));
+ vfc_requester().cancelVideoFrameCallback(callback_id);
+
+ EXPECT_CALL(*function, Call(_)).Times(0);
+ SimulateFramePresented();
+ SimulateVideoFrameCallback(base::TimeTicks::Now());
+
+ testing::Mock::VerifyAndClear(function);
+}
+
+TEST_F(VideoFrameCallbackRequesterImplTest,
+ VerifyCancelVideoFrameCallback_AfterPresentedFrame) {
+ V8TestingScope scope;
+
+ auto* function = MockFunction::Create(scope.GetScriptState());
+
+ // Queue a request.
+ int callback_id =
+ vfc_requester().requestVideoFrameCallback(GetCallback(function));
+ SimulateFramePresented();
+
+ // The callback should be scheduled for execution, but not yet run.
+ EXPECT_CALL(*function, Call(_)).Times(0);
+ vfc_requester().cancelVideoFrameCallback(callback_id);
+ SimulateVideoFrameCallback(base::TimeTicks::Now());
+
+ testing::Mock::VerifyAndClear(function);
+}
+
+TEST_F(VideoFrameCallbackRequesterImplTest, VerifyParameters) {
+ auto timing = GetDocument().Loader()->GetTiming();
+ MetadataHelper::InitializeFields(timing.ReferenceMonotonicTime());
+
+ auto* callback =
+ MakeGarbageCollected<VfcRequesterParameterVerifierCallback>(timing);
+
+ // Register the non-V8 callback.
+ RegisterCallbackDirectly(callback);
+
+ EXPECT_CALL(*media_player(), GetVideoFramePresentationMetadata())
+ .WillOnce(Return(ByMove(MetadataHelper::CopyDefaultMedatada())));
+
+ double now_ms =
+ timing.MonotonicTimeToZeroBasedDocumentTime(base::TimeTicks::Now())
+ .InMillisecondsF();
+
+ // Run the callbacks directly, since they weren't scheduled to be run by the
+ // ScriptedAnimationController.
+ vfc_requester().OnRenderingSteps(now_ms);
+
+ EXPECT_EQ(callback->last_now(), now_ms);
+ EXPECT_TRUE(callback->was_invoked());
+
+ testing::Mock::VerifyAndClear(media_player());
+}
+
+TEST_F(VideoFrameCallbackRequesterImplNullMediaPlayerTest, VerifyNoCrash) {
+ V8TestingScope scope;
+
+ auto* function = MockFunction::Create(scope.GetScriptState());
+
+ vfc_requester().requestVideoFrameCallback(GetCallback(function));
+
+ SimulateFramePresented();
+ SimulateVideoFrameCallback(base::TimeTicks::Now());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/video_raf/video_frame_metadata.idl b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_metadata.idl
index 129e882a008..1d8e03c39cd 100644
--- a/chromium/third_party/blink/renderer/modules/video_raf/video_frame_metadata.idl
+++ b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_metadata.idl
@@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// TODO(https://crbug.com/1022186): Add pointer to video.rAF spec.
+// See https://wicg.github.io/video-raf/.
dictionary VideoFrameMetadata {
// The time at which the user agent submitted the frame for composition.
required DOMHighResTimeStamp presentationTime;
// The time at which the user agent expects the frame to be visible.
- required DOMHighResTimeStamp expectedPresentationTime;
+ required DOMHighResTimeStamp expectedDisplayTime;
// The visible width and height of the presented video frame.
required unsigned long width;
@@ -17,7 +17,7 @@ dictionary VideoFrameMetadata {
// The presentation timestamp in seconds of the frame presented. May not be
// known to the compositor or exist in all cases.
- double presentationTimestamp;
+ required double mediaTime;
// The elapsed time in seconds from submission of the encoded packet with
// the same presentationTimestamp as this frame to the decoder until the
@@ -25,18 +25,26 @@ dictionary VideoFrameMetadata {
//
// In addition to decoding time, may include processing time. E.g., YUV
// conversion and/or staging into GPU backed memory.
- double elapsedProcessingTime;
+ double processingDuration;
// A count of the number of frames submitted for composition. Allows clients
// to determine if frames were missed between VideoFrameRequestCallbacks.
//
// https://wiki.whatwg.org/wiki/Video_Metrics#presentedFrames
- unsigned long presentedFrames;
+ required unsigned long presentedFrames;
- // For video frames coming from a local device like a camera, the time at
- // which the frame was received from the device.
+ // For video frames coming from either a local or remote source, this is
+ // the time at which the frame was captured by the camera. For a remote
+ // source, the capture time is estimated using clock synchronization and
+ // RTCP sender reports to convert RTP timestamps to capture time as
+ // specified in RFC 3550 Section 6.4.1.
DOMHighResTimeStamp captureTime;
+ // For video frames coming from a remote source, this is the time the
+ // encoded frame was received by the platform, i.e., the time at which the
+ // last packet belonging to this frame was received over the network.
+ DOMHighResTimeStamp receiveTime;
+
// The RTP timestamp associated with this video frame.
//
// https://w3c.github.io/webrtc-pc/#dom-rtcrtpcontributingsource
diff --git a/chromium/third_party/blink/renderer/modules/video_raf/video_frame_request_callback.idl b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback.idl
index 9618349258e..58f324d69a4 100644
--- a/chromium/third_party/blink/renderer/modules/video_raf/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.
-// TODO(https://crbug.com/1022186): Add pointer to video.rAF spec.
+// See https://wicg.github.io/video-raf/.
[RuntimeEnabled=VideoRequestAnimationFrame]
callback VideoFrameRequestCallback = void(DOMHighResTimeStamp time, VideoFrameMetadata metadata);
diff --git a/chromium/third_party/blink/renderer/modules/video_raf/video_frame_request_callback_collection.cc b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.cc
index a904eec12a5..b9676a22842 100644
--- a/chromium/third_party/blink/renderer/modules/video_raf/video_frame_request_callback_collection.cc
+++ b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.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/video_raf/video_frame_request_callback_collection.h"
+#include "third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.h"
#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
diff --git a/chromium/third_party/blink/renderer/modules/video_raf/video_frame_request_callback_collection.h b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.h
index fe8f4e84d40..2cffc395e6d 100644
--- a/chromium/third_party/blink/renderer/modules/video_raf/video_frame_request_callback_collection.h
+++ b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.h
@@ -2,13 +2,13 @@
// 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_VIDEO_RAF_VIDEO_FRAME_REQUEST_CALLBACK_COLLECTION_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_VIDEO_RAF_VIDEO_FRAME_REQUEST_CALLBACK_COLLECTION_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_VIDEO_RVFC_VIDEO_FRAME_REQUEST_CALLBACK_COLLECTION_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_VIDEO_RVFC_VIDEO_FRAME_REQUEST_CALLBACK_COLLECTION_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_video_frame_metadata.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_video_frame_request_callback.h"
#include "third_party/blink/renderer/core/dom/dom_high_res_time_stamp.h"
#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/modules/video_raf/video_frame_metadata.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -83,8 +83,7 @@ class MODULES_EXPORT VideoFrameRequestCallbackCollection final
// Invokes all callbacks with the provided information.
void ExecuteFrameCallbacks(double high_res_now_ms, const VideoFrameMetadata*);
- bool HasFrameCallback() const { return frame_callbacks_.size(); }
- bool IsEmpty() const { return !HasFrameCallback(); }
+ bool IsEmpty() const { return !frame_callbacks_.size(); }
virtual void Trace(Visitor*);
const char* NameInHeapSnapshot() const override {
@@ -105,4 +104,4 @@ class MODULES_EXPORT VideoFrameRequestCallbackCollection final
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_VIDEO_RAF_VIDEO_FRAME_REQUEST_CALLBACK_COLLECTION_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_VIDEO_RVFC_VIDEO_FRAME_REQUEST_CALLBACK_COLLECTION_H_
diff --git a/chromium/third_party/blink/renderer/modules/video_raf/video_frame_request_callback_collection_test.cc b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection_test.cc
index a0a7f4bc4ca..df0b3e7246b 100644
--- a/chromium/third_party/blink/renderer/modules/video_raf/video_frame_request_callback_collection_test.cc
+++ b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection_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/video_raf/video_frame_request_callback_collection.h"
+#include "third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -44,14 +44,12 @@ class VideoFrameRequestCallbackCollectionTest : public PageTestBase {
};
TEST_F(VideoFrameRequestCallbackCollectionTest, AddSingleCallback) {
- EXPECT_FALSE(collection()->HasFrameCallback());
EXPECT_TRUE(collection()->IsEmpty());
auto callback = CreateCallback();
CallbackId id = collection()->RegisterFrameCallback(callback.Get());
EXPECT_EQ(id, callback->Id());
- EXPECT_TRUE(collection()->HasFrameCallback());
EXPECT_FALSE(collection()->IsEmpty());
}
@@ -63,7 +61,7 @@ TEST_F(VideoFrameRequestCallbackCollectionTest, InvokeSingleCallback) {
EXPECT_CALL(*callback, Invoke(kDefaultTimestamp, metadata));
collection()->ExecuteFrameCallbacks(kDefaultTimestamp, metadata);
- EXPECT_FALSE(collection()->HasFrameCallback());
+ EXPECT_TRUE(collection()->IsEmpty());
}
TEST_F(VideoFrameRequestCallbackCollectionTest, CancelSingleCallback) {
@@ -75,12 +73,12 @@ TEST_F(VideoFrameRequestCallbackCollectionTest, CancelSingleCallback) {
// Cancelling an non existent ID should do nothing.
collection()->CancelFrameCallback(id + 100);
- EXPECT_TRUE(collection()->HasFrameCallback());
+ EXPECT_FALSE(collection()->IsEmpty());
EXPECT_FALSE(callback->IsCancelled());
// Cancel the callback this time.
collection()->CancelFrameCallback(id);
- EXPECT_FALSE(collection()->HasFrameCallback());
+ EXPECT_TRUE(collection()->IsEmpty());
collection()->ExecuteFrameCallbacks(kDefaultTimestamp,
VideoFrameMetadata::Create());
@@ -121,13 +119,13 @@ TEST_F(VideoFrameRequestCallbackCollectionTest, CreateCallbackDuringExecution) {
VideoFrameMetadata::Create());
EXPECT_NE(created_id, 0);
- EXPECT_TRUE(collection()->HasFrameCallback());
+ EXPECT_FALSE(collection()->IsEmpty());
// The created callback should be executed the second time around.
EXPECT_CALL(*created_callback, Invoke(_, _)).Times(1);
collection()->ExecuteFrameCallbacks(kDefaultTimestamp,
VideoFrameMetadata::Create());
- EXPECT_FALSE(collection()->HasFrameCallback());
+ EXPECT_TRUE(collection()->IsEmpty());
}
TEST_F(VideoFrameRequestCallbackCollectionTest,
@@ -158,7 +156,7 @@ TEST_F(VideoFrameRequestCallbackCollectionTest,
VideoFrameMetadata::Create());
// Everything should have been cleared
- EXPECT_FALSE(collection()->HasFrameCallback());
+ EXPECT_TRUE(collection()->IsEmpty());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/idls.gni b/chromium/third_party/blink/renderer/modules/wake_lock/idls.gni
new file mode 100644
index 00000000000..685f7209b06
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/idls.gni
@@ -0,0 +1,12 @@
+# 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 = [
+ "wake_lock.idl",
+ "wake_lock_sentinel.idl",
+]
+
+modules_dependency_idl_files = [
+ "navigator_wake_lock.idl",
+ "worker_navigator_wake_lock.idl",
+]
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 e6f900b1bd3..daea00ef166 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
@@ -44,7 +44,7 @@ WakeLock* NavigatorWakeLock::wakeLock(Navigator& navigator) {
return NavigatorWakeLock::From(navigator).GetWakeLock();
}
-void NavigatorWakeLock::Trace(blink::Visitor* visitor) {
+void NavigatorWakeLock::Trace(Visitor* visitor) {
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 bdfd505cad1..62c54ce9c20 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 33a45aa7ad0..a69e06515df 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
@@ -11,10 +11,13 @@
#include "third_party/blink/renderer/core/execution_context/execution_context.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/page/page.h"
#include "third_party/blink/renderer/modules/permissions/permission_utils.h"
#include "third_party/blink/renderer/modules/wake_lock/wake_lock_manager.h"
#include "third_party/blink/renderer/modules/wake_lock/wake_lock_type.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/scheduler/public/frame_or_worker_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -24,45 +27,69 @@ using mojom::blink::PermissionService;
using mojom::blink::PermissionStatus;
WakeLock::WakeLock(Document& document)
- : ContextLifecycleObserver(&document),
+ : ExecutionContextLifecycleObserver(&document),
PageVisibilityObserver(document.GetPage()),
- managers_{MakeGarbageCollected<WakeLockManager>(&document,
- WakeLockType::kScreen),
- MakeGarbageCollected<WakeLockManager>(&document,
- WakeLockType::kSystem)} {}
+ managers_{
+ MakeGarbageCollected<WakeLockManager>(document.ToExecutionContext(),
+ WakeLockType::kScreen),
+ MakeGarbageCollected<WakeLockManager>(document.ToExecutionContext(),
+ WakeLockType::kSystem)} {
+ document.GetScheduler()->RegisterStickyFeature(
+ SchedulingPolicy::Feature::kWakeLock,
+ {SchedulingPolicy::RecordMetricsForBackForwardCache()});
+}
WakeLock::WakeLock(DedicatedWorkerGlobalScope& worker_scope)
- : ContextLifecycleObserver(&worker_scope),
+ : ExecutionContextLifecycleObserver(&worker_scope),
PageVisibilityObserver(nullptr),
managers_{MakeGarbageCollected<WakeLockManager>(&worker_scope,
WakeLockType::kScreen),
MakeGarbageCollected<WakeLockManager>(&worker_scope,
WakeLockType::kSystem)} {}
-ScriptPromise WakeLock::request(ScriptState* script_state, const String& type) {
+ScriptPromise WakeLock::request(ScriptState* script_state,
+ const String& type,
+ ExceptionState& exception_state) {
// https://w3c.github.io/wake-lock/#the-request-method
auto* context = ExecutionContext::From(script_state);
DCHECK(context->IsDocument() || context->IsDedicatedWorkerGlobalScope());
- // 2.1. If document is not allowed to use the policy-controlled feature named
- // "wake-lock", reject promise with a "NotAllowedError" DOMException and
- // return promise.
+ if (type == "screen" &&
+ !RuntimeEnabledFeatures::ScreenWakeLockEnabled(context)) {
+ exception_state.ThrowTypeError(
+ "The provided value 'screen' is not a valid enum value of type "
+ "WakeLockType.");
+ return ScriptPromise();
+ }
+
+ if (type == "system" && !RuntimeEnabledFeatures::SystemWakeLockEnabled()) {
+ exception_state.ThrowTypeError(
+ "The provided value 'system' is not a valid enum value of type "
+ "WakeLockType.");
+ return ScriptPromise();
+ }
+
+ // 2.1 If type is 'screen' and the document is not allowed to use the
+ // policy-controlled feature named "screen-wake-lock", reject promise with
+ // a "NotAllowedError" DOMException and return promise.
// [N.B. Per https://github.com/w3c/webappsec-feature-policy/issues/207 there
// is no official support for workers in the Feature Policy spec, but we can
// perform FP checks in workers in Blink]
// 2.2. If the user agent denies the wake lock of this type for document,
// reject promise with a "NotAllowedError" DOMException and return
// promise.
- if (!context->GetSecurityContext().IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kWakeLock,
+ if (type == "screen" &&
+ !context->IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kScreenWakeLock,
ReportOptions::kReportOnFailure)) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotAllowedError,
- "Access to WakeLock features is disallowed by feature policy"));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotAllowedError,
+ "Access to Screen Wake Lock features is disallowed by feature policy");
+ return ScriptPromise();
}
+ // TODO: Check feature policy enabling for System Wake Lock
+
if (context->IsDedicatedWorkerGlobalScope()) {
// 3. If the current global object is the DedicatedWorkerGlobalScope object:
// 3.1. If the current global object's owner set is empty, reject promise
@@ -70,43 +97,41 @@ ScriptPromise WakeLock::request(ScriptState* script_state, const String& type) {
// 3.2. If type is "screen", reject promise with a "NotAllowedError"
// DOMException, and return promise.
if (type == "screen") {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotAllowedError,
- "Screen locks cannot be requested from workers"));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotAllowedError,
+ "Screen locks cannot be requested from workers");
+ return ScriptPromise();
}
} else if (context->IsDocument()) {
// 2. Let document be the responsible document of the current settings
// object.
- auto* document = To<Document>(context);
+ auto* document = Document::From(context);
// 4. Otherwise, if the current global object is the Window object:
// 4.1. If the document's browsing context is null, reject promise with a
// "NotAllowedError" DOMException and return promise.
if (!document) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotAllowedError,
- "The document has no associated browsing context"));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotAllowedError,
+ "The document has no associated browsing context");
+ return ScriptPromise();
}
// 4.2. If document is not fully active, reject promise with a
// "NotAllowedError" DOMException, and return promise.
if (!document->IsActive()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotAllowedError,
- "The document is not active"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kNotAllowedError,
+ "The document is not active");
+ return ScriptPromise();
}
// 4.3. If type is "screen" and the Document of the top-level browsing
// context is hidden, reject promise with a "NotAllowedError"
// DOMException, and return promise.
if (type == "screen" &&
!(document->GetPage() && document->GetPage()->IsPageVisible())) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotAllowedError,
- "The requesting page is not visible"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kNotAllowedError,
+ "The requesting page is not visible");
+ return ScriptPromise();
}
}
@@ -177,7 +202,7 @@ void WakeLock::DidReceivePermissionResponse(WakeLockType type,
manager->AcquireWakeLock(resolver);
}
-void WakeLock::ContextDestroyed(ExecutionContext*) {
+void WakeLock::ContextDestroyed() {
// https://w3c.github.io/wake-lock/#handling-document-loss-of-full-activity
// 1. Let document be the responsible document of the current settings object.
// 2. Let screenRecord be the platform wake lock's state record associated
@@ -238,7 +263,7 @@ void WakeLock::ObtainPermission(
"WakeLockType and mojom::blink::WakeLockType must have identical values");
auto* local_frame = GetExecutionContext()->IsDocument()
- ? To<Document>(GetExecutionContext())->GetFrame()
+ ? Document::From(GetExecutionContext())->GetFrame()
: nullptr;
GetPermissionService()->RequestPermission(
CreateWakeLockPermissionDescriptor(
@@ -256,10 +281,10 @@ PermissionService* WakeLock::GetPermissionService() {
}
void WakeLock::Trace(Visitor* visitor) {
- for (WakeLockManager* manager : managers_)
+ for (const WakeLockManager* manager : managers_)
visitor->Trace(manager);
PageVisibilityObserver::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
ScriptWrappable::Trace(visitor);
}
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 55a08415d07..a2379f0707b 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
@@ -10,7 +10,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/dom/document.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/page/page_visibility_observer.h"
#include "third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h"
#include "third_party/blink/renderer/modules/modules_export.h"
@@ -26,12 +26,12 @@ class String;
namespace blink {
-class ExecutionContext;
+class ExceptionState;
class ScriptState;
class WakeLockManager;
class MODULES_EXPORT WakeLock final : public ScriptWrappable,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public PageVisibilityObserver {
USING_GARBAGE_COLLECTED_MIXIN(WakeLock);
DEFINE_WRAPPERTYPEINFO();
@@ -40,9 +40,11 @@ class MODULES_EXPORT WakeLock final : public ScriptWrappable,
explicit WakeLock(Document&);
explicit WakeLock(DedicatedWorkerGlobalScope&);
- ScriptPromise request(ScriptState*, const WTF::String& type);
+ ScriptPromise request(ScriptState*,
+ const WTF::String& type,
+ ExceptionState& exception_state);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
// While this could be part of request() itself, having it as a separate
@@ -54,8 +56,8 @@ class MODULES_EXPORT WakeLock final : public ScriptWrappable,
ScriptPromiseResolver*,
mojom::blink::PermissionStatus);
- // ContextLifecycleObserver implementation
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver implementation
+ void ContextDestroyed() override;
// PageVisibilityObserver implementation
void PageVisibilityChanged() override;
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.idl b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.idl
index 806981c25f9..16ac657ec3f 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.idl
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.idl
@@ -10,8 +10,7 @@ enum WakeLockType {
// https://w3c.github.io/wake-lock/#the-wakelock-interface
[
SecureContext,
- Exposed=(DedicatedWorker,Window),
- RuntimeEnabled=WakeLock
+ Exposed(DedicatedWorker SystemWakeLock, Window WakeLock)
] interface WakeLock {
- [CallWith=ScriptState] Promise<WakeLockSentinel> request(WakeLockType type);
+ [CallWith=ScriptState, RaisesException] Promise<WakeLockSentinel> request(WakeLockType type);
};
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 7de2db7edd4..579fdf7cccb 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
@@ -17,7 +17,9 @@ namespace blink {
WakeLockManager::WakeLockManager(ExecutionContext* execution_context,
WakeLockType type)
- : wake_lock_type_(type), execution_context_(execution_context) {
+ : wake_lock_(execution_context),
+ wake_lock_type_(type),
+ execution_context_(execution_context) {
DCHECK_NE(execution_context, nullptr);
}
@@ -36,15 +38,16 @@ void WakeLockManager::AcquireWakeLock(ScriptPromiseResolver* resolver) {
// document and type.
// 4.3. Add lock to record.[[ActiveLocks]].
// 5. Return active.
- if (!wake_lock_) {
+ if (!wake_lock_.is_bound()) {
mojo::Remote<mojom::blink::WakeLockService> wake_lock_service;
execution_context_->GetBrowserInterfaceBroker().GetInterface(
wake_lock_service.BindNewPipeAndPassReceiver());
- wake_lock_service->GetWakeLock(ToMojomWakeLockType(wake_lock_type_),
- device::mojom::blink::WakeLockReason::kOther,
- "Blink Wake Lock",
- wake_lock_.BindNewPipeAndPassReceiver());
+ wake_lock_service->GetWakeLock(
+ ToMojomWakeLockType(wake_lock_type_),
+ device::mojom::blink::WakeLockReason::kOther, "Blink Wake Lock",
+ wake_lock_.BindNewPipeAndPassReceiver(
+ execution_context_->GetTaskRunner(TaskType::kMiscPlatformAPI)));
wake_lock_.set_disconnect_handler(WTF::Bind(
&WakeLockManager::OnWakeLockConnectionError, WrapWeakPersistent(this)));
wake_lock_->RequestWakeLock();
@@ -96,9 +99,10 @@ void WakeLockManager::OnWakeLockConnectionError() {
ClearWakeLocks();
}
-void WakeLockManager::Trace(blink::Visitor* visitor) {
+void WakeLockManager::Trace(Visitor* visitor) {
visitor->Trace(execution_context_);
visitor->Trace(wake_lock_sentinels_);
+ visitor->Trace(wake_lock_);
}
} // namespace blink
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 32efa029dee..1375d9e5292 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
@@ -6,11 +6,12 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_MANAGER_H_
#include "base/gtest_prod_util.h"
-#include "mojo/public/cpp/bindings/remote.h"
#include "services/device/public/mojom/wake_lock.mojom-blink-forward.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/wake_lock/wake_lock_type.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"
namespace blink {
@@ -30,7 +31,7 @@ class MODULES_EXPORT WakeLockManager final
void UnregisterSentinel(WakeLockSentinel*);
- void Trace(blink::Visitor* visitor);
+ void Trace(Visitor* visitor);
private:
// Handle connection errors from |wake_lock_|.
@@ -42,7 +43,9 @@ class MODULES_EXPORT WakeLockManager final
// An actual platform WakeLock. If bound, it means there is an active wake
// lock for a given type.
- mojo::Remote<device::mojom::blink::WakeLock> wake_lock_;
+ HeapMojoRemote<device::mojom::blink::WakeLock,
+ HeapMojoWrapperMode::kWithoutContextObserver>
+ wake_lock_;
WakeLockType wake_lock_type_;
// ExecutionContext from which we will connect to |wake_lock_service_|.
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager_test.cc b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager_test.cc
index d3ebd99b0f3..dcb9df8a535 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager_test.cc
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager_test.cc
@@ -20,7 +20,8 @@ namespace {
WakeLockManager* MakeManager(WakeLockTestingContext& context,
WakeLockType type) {
- return MakeGarbageCollected<WakeLockManager>(context.GetDocument(), type);
+ return MakeGarbageCollected<WakeLockManager>(
+ context.GetDocument()->ToExecutionContext(), type);
}
} // namespace
@@ -193,6 +194,7 @@ TEST(WakeLockManagerTest, WakeLockConnectionError) {
context.WaitForPromiseFulfillment(promise1);
context.WaitForPromiseFulfillment(promise2);
+ EXPECT_TRUE(manager->wake_lock_.is_bound());
EXPECT_EQ(2U, manager->wake_lock_sentinels_.size());
// Unbind and wait for the disconnection to reach |wake_lock_|'s
@@ -201,7 +203,7 @@ TEST(WakeLockManagerTest, WakeLockConnectionError) {
manager->wake_lock_.FlushForTesting();
EXPECT_EQ(0U, manager->wake_lock_sentinels_.size());
- EXPECT_FALSE(manager->wake_lock_);
+ EXPECT_FALSE(manager->wake_lock_.is_bound());
EXPECT_FALSE(system_lock.is_acquired());
}
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 6be3f1111fe..2a6a7bbad35 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
@@ -16,7 +16,7 @@ namespace blink {
WakeLockSentinel::WakeLockSentinel(ScriptState* script_state,
WakeLockType type,
WakeLockManager* manager)
- : ContextLifecycleObserver(ExecutionContext::From(script_state)),
+ : ExecutionContextLifecycleObserver(ExecutionContext::From(script_state)),
manager_(manager),
type_(type) {}
@@ -46,17 +46,17 @@ String WakeLockSentinel::type() const {
}
ExecutionContext* WakeLockSentinel::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
const AtomicString& WakeLockSentinel::InterfaceName() const {
return event_target_names::kWakeLockSentinel;
}
-void WakeLockSentinel::Trace(blink::Visitor* visitor) {
+void WakeLockSentinel::Trace(Visitor* visitor) {
visitor->Trace(manager_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
bool WakeLockSentinel::HasPendingActivity() const {
@@ -66,7 +66,7 @@ bool WakeLockSentinel::HasPendingActivity() const {
return manager_ && HasEventListeners();
}
-void WakeLockSentinel::ContextDestroyed(ExecutionContext*) {
+void WakeLockSentinel::ContextDestroyed() {
// Release all event listeners so that HasPendingActivity() does not return
// true forever once a listener has been added to the object.
RemoveAllEventListeners();
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 1acbfb4d477..35e192c501f 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
@@ -9,7 +9,7 @@
#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/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/wake_lock/wake_lock_type.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -24,7 +24,7 @@ class WakeLockManager;
class MODULES_EXPORT WakeLockSentinel final
: public EventTargetWithInlineData,
public ActiveScriptWrappable<WakeLockSentinel>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(WakeLockSentinel);
@@ -42,13 +42,13 @@ class MODULES_EXPORT WakeLockSentinel final
// EventTarget overrides.
ExecutionContext* GetExecutionContext() const override;
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// ActiveScriptWrappable overrides.
bool HasPendingActivity() const override;
- // ContextLifecycleObserver overrides.
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver overrides.
+ void ContextDestroyed() override;
private:
friend class WakeLockManager;
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.idl b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.idl
index 45b382cf877..c09c08c5878 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.idl
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.idl
@@ -6,8 +6,7 @@
[
ActiveScriptWrappable,
- Exposed=(DedicatedWorker,Window),
- RuntimeEnabled=WakeLock,
+ Exposed(DedicatedWorker SystemWakeLock, Window WakeLock),
SecureContext
] interface WakeLockSentinel : EventTarget {
attribute EventHandler onrelease;
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel_test.cc b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel_test.cc
index 59cf4837b28..7c2b89aa809 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel_test.cc
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel_test.cc
@@ -11,6 +11,8 @@
#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/events/native_event_listener.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/event_target_modules_names.h"
#include "third_party/blink/renderer/modules/wake_lock/wake_lock.h"
#include "third_party/blink/renderer/modules/wake_lock/wake_lock_manager.h"
@@ -54,8 +56,8 @@ TEST(WakeLockSentinelTest, MultipleReleaseCalls) {
MockWakeLockService wake_lock_service;
WakeLockTestingContext context(&wake_lock_service);
- auto* manager = MakeGarbageCollected<WakeLockManager>(context.GetDocument(),
- WakeLockType::kScreen);
+ auto* manager = MakeGarbageCollected<WakeLockManager>(
+ context.GetDocument()->ToExecutionContext(), WakeLockType::kScreen);
auto* resolver =
MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState());
ScriptPromise promise = resolver->Promise();
@@ -112,7 +114,7 @@ TEST(WakeLockSentinelTest, ContextDestruction) {
sentinel->addEventListener(event_type_names::kRelease, event_listener);
EXPECT_TRUE(sentinel->HasPendingActivity());
- context.GetDocument()->Shutdown();
+ context.Frame()->DomWindow()->FrameDestroyed();
// If the method returns false the object can be GC'ed.
EXPECT_FALSE(sentinel->HasPendingActivity());
@@ -122,8 +124,8 @@ TEST(WakeLockSentinelTest, HasPendingActivityConditions) {
MockWakeLockService wake_lock_service;
WakeLockTestingContext context(&wake_lock_service);
- auto* manager = MakeGarbageCollected<WakeLockManager>(context.GetDocument(),
- WakeLockType::kScreen);
+ auto* manager = MakeGarbageCollected<WakeLockManager>(
+ context.GetDocument()->ToExecutionContext(), WakeLockType::kScreen);
auto* resolver =
MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState());
ScriptPromise promise = resolver->Promise();
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_test.cc b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_test.cc
index 6bcb561c9bd..3e711528050 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_test.cc
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_test.cc
@@ -8,6 +8,9 @@
#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/dom_exception.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/page.h"
#include "third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "v8/include/v8.h"
@@ -110,7 +113,7 @@ TEST(WakeLockTest, LossOfDocumentActivity) {
// been cleared. We cannot check that the promises have been rejected because
// ScriptPromiseResolver::Reject() will bail out if we no longer have a valid
// execution context.
- context.GetDocument()->Shutdown();
+ context.Frame()->DomWindow()->FrameDestroyed();
screen_lock.WaitForCancelation();
system_lock.WaitForCancelation();
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.cc b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.cc
index 804169849a8..6d2403f5fb9 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.cc
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.cc
@@ -17,6 +17,7 @@
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/modules/wake_lock/wake_lock_type.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
+#include "third_party/blink/renderer/platform/heap/thread_state_scopes.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -27,6 +28,11 @@ using mojom::blink::PermissionStatus;
namespace {
+void RunWithStack(base::RunLoop* run_loop) {
+ ThreadState::HeapPointersOnStackScope scan_stack(ThreadState::Current());
+ run_loop->Run();
+}
+
// Helper class for WaitForPromise{Fulfillment,Rejection}(). It provides a
// function that invokes |callback| when a ScriptPromise is resolved.
class ClosureRunnerFunction final : public ScriptFunction {
@@ -88,14 +94,14 @@ void MockWakeLock::WaitForRequest() {
DCHECK(!request_wake_lock_callback_);
base::RunLoop run_loop;
request_wake_lock_callback_ = run_loop.QuitClosure();
- run_loop.Run();
+ RunWithStack(&run_loop);
}
void MockWakeLock::WaitForCancelation() {
DCHECK(!cancel_wake_lock_callback_);
base::RunLoop run_loop;
cancel_wake_lock_callback_ = run_loop.QuitClosure();
- run_loop.Run();
+ RunWithStack(&run_loop);
}
void MockWakeLock::OnConnectionError() {
@@ -191,7 +197,7 @@ void MockPermissionService::WaitForPermissionRequest(WakeLockType type) {
DCHECK(!request_permission_callbacks_[pos]);
base::RunLoop run_loop;
request_permission_callbacks_[pos] = run_loop.QuitClosure();
- run_loop.Run();
+ RunWithStack(&run_loop);
}
void MockPermissionService::HasPermission(PermissionDescriptorPtr permission,
@@ -293,7 +299,7 @@ ScriptPromise WakeLockTestingContext::WaitForPromiseFulfillment(
// Execute pending microtasks, otherwise it can take a few seconds for the
// promise to resolve.
v8::MicrotasksScope::PerformCheckpoint(GetScriptState()->GetIsolate());
- run_loop.Run();
+ RunWithStack(&run_loop);
return return_promise;
}
@@ -306,7 +312,7 @@ void WakeLockTestingContext::WaitForPromiseRejection(ScriptPromise promise) {
// Execute pending microtasks, otherwise it can take a few seconds for the
// promise to resolve.
v8::MicrotasksScope::PerformCheckpoint(GetScriptState()->GetIsolate());
- run_loop.Run();
+ RunWithStack(&run_loop);
}
// ScriptPromiseUtils
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 094a3baedb1..c7bbe98a4e9 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(blink::Visitor* visitor) {
+void WorkerNavigatorWakeLock::Trace(Visitor* visitor) {
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 bc01e30e4a5..5e11c5154af 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
WakeLock* GetWakeLock(ScriptState*);
diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.idl b/chromium/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.idl
index 251ff83ac12..6523341c170 100644
--- a/chromium/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.idl
+++ b/chromium/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.idl
@@ -6,7 +6,7 @@
[
ImplementedAs=WorkerNavigatorWakeLock,
- RuntimeEnabled=WakeLock,
+ RuntimeEnabled=SystemWakeLock,
SecureContext
] partial interface WorkerNavigator {
[CallWith=ScriptState, SameObject] readonly attribute WakeLock wakeLock;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/OWNERS b/chromium/third_party/blink/renderer/modules/webaudio/OWNERS
index caaf05cf1d8..bcc0e71a548 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/webaudio/OWNERS
@@ -1,5 +1,4 @@
hongchan@chromium.org
-kbr@chromium.org
rtoy@chromium.org
# COMPONENT: Blink>WebAudio
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/analyser_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/analyser_node.cc
index 4df218da56b..cb281f5b728 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/analyser_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/analyser_node.cc
@@ -25,7 +25,7 @@
#include "third_party/blink/renderer/modules/webaudio/analyser_node.h"
-#include "third_party/blink/renderer/modules/webaudio/analyser_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_analyser_options.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_input.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_output.h"
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
@@ -58,12 +58,12 @@ void AnalyserHandler::Process(uint32_t frames_to_process) {
return;
}
- AudioBus* input_bus = Input(0).Bus();
+ scoped_refptr<AudioBus> input_bus = Input(0).Bus();
// Give the analyser the audio which is passing through this
// AudioNode. This must always be done so that the state of the
// Analyser reflects the current input.
- analyser_.WriteInput(input_bus, frames_to_process);
+ analyser_.WriteInput(input_bus.get(), frames_to_process);
if (!Input(0).IsConnected()) {
// No inputs, so clear the output, and propagate the silence hint.
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/analyser_node.idl b/chromium/third_party/blink/renderer/modules/webaudio/analyser_node.idl
index 8a299b41466..d879f4212f2 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/analyser_node.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/analyser_node.idl
@@ -23,14 +23,11 @@
* DAMAGE.
*/
-// See https://webaudio.github.io/web-audio-api/#analysernode
+// https://webaudio.github.io/web-audio-api/#analysernode
[
- Exposed=Window,
- Constructor(BaseAudioContext context, optional AnalyserOptions options),
- RaisesException=Constructor,
- Measure
-]
-interface AnalyserNode : AudioNode {
+ Exposed=Window
+] interface AnalyserNode : AudioNode {
+ [RaisesException, Measure] constructor(BaseAudioContext context, optional AnalyserOptions options = {});
[RaisesException=Setter] attribute unsigned long fftSize;
readonly attribute unsigned long frequencyBinCount;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_basic_processor_handler.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_basic_processor_handler.cc
index c2d85bf8016..1afb7c95494 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_basic_processor_handler.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_basic_processor_handler.cc
@@ -75,14 +75,14 @@ void AudioBasicProcessorHandler::Process(uint32_t frames_to_process) {
Processor()->NumberOfChannels() != NumberOfChannels()) {
destination_bus->Zero();
} else {
- AudioBus* source_bus = Input(0).Bus();
+ scoped_refptr<AudioBus> source_bus = Input(0).Bus();
// FIXME: if we take "tail time" into account, then we can avoid calling
// processor()->process() once the tail dies down.
if (!Input(0).IsConnected())
source_bus->Zero();
- Processor()->Process(source_bus, destination_bus, frames_to_process);
+ Processor()->Process(source_bus.get(), destination_bus, frames_to_process);
}
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_basic_processor_handler_test.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_basic_processor_handler_test.cc
index e5703d7a2bb..720e7269f72 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_basic_processor_handler_test.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_basic_processor_handler_test.cc
@@ -53,8 +53,9 @@ class MockProcessorNode final : public AudioNode {
TEST(AudioBasicProcessorHandlerTest, ProcessorFinalization) {
auto page = std::make_unique<DummyPageHolder>();
- OfflineAudioContext* context = OfflineAudioContext::Create(
- &page->GetDocument(), 2, 1, 48000, ASSERT_NO_EXCEPTION);
+ OfflineAudioContext* context =
+ OfflineAudioContext::Create(page->GetDocument().ToExecutionContext(), 2,
+ 1, 48000, ASSERT_NO_EXCEPTION);
MockProcessorNode* node = MakeGarbageCollected<MockProcessorNode>(*context);
AudioBasicProcessorHandler& handler =
static_cast<AudioBasicProcessorHandler&>(node->Handler());
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer.cc
index f173f1bbf32..37a1650dfa2 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer.cc
@@ -29,7 +29,7 @@
#include "third_party/blink/renderer/modules/webaudio/audio_buffer.h"
#include <memory>
-#include "third_party/blink/renderer/modules/webaudio/audio_buffer_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_audio_buffer_options.h"
#include "third_party/blink/renderer/modules/webaudio/base_audio_context.h"
#include "third_party/blink/renderer/platform/audio/audio_bus.h"
#include "third_party/blink/renderer/platform/audio/audio_file_reader.h"
@@ -164,7 +164,6 @@ AudioBuffer::AudioBuffer(unsigned number_of_channels,
if (!channel_data_array)
return;
- channel_data_array->SetDetachable(false);
channels_.push_back(channel_data_array);
}
}
@@ -182,7 +181,6 @@ AudioBuffer::AudioBuffer(AudioBus* bus)
if (!channel_data_array)
return;
- channel_data_array->SetDetachable(false);
const float* src = bus->Channel(i)->Data();
float* dst = channel_data_array->Data();
memmove(dst, src, length_ * sizeof(*dst));
@@ -220,7 +218,7 @@ void AudioBuffer::copyFromChannel(NotShared<DOMFloat32Array> destination,
void AudioBuffer::copyFromChannel(NotShared<DOMFloat32Array> destination,
int32_t channel_number,
- uint32_t buffer_offset,
+ size_t buffer_offset,
ExceptionState& exception_state) {
if (channel_number < 0 ||
static_cast<uint32_t>(channel_number) >= channels_.size()) {
@@ -237,23 +235,24 @@ void AudioBuffer::copyFromChannel(NotShared<DOMFloat32Array> destination,
DOMFloat32Array* channel_data = channels_[channel_number].Get();
- if (buffer_offset >= channel_data->deprecatedLengthAsUnsigned()) {
+ size_t data_length = channel_data->lengthAsSizeT();
+
+ if (buffer_offset >= data_length) {
// Nothing to copy if the buffer offset is past the end of the AudioBuffer.
return;
}
- unsigned int count =
- channel_data->deprecatedLengthAsUnsigned() - buffer_offset;
+ size_t count = data_length - buffer_offset;
- count = std::min(destination.View()->deprecatedLengthAsUnsigned(), count);
+ count = std::min(destination.View()->lengthAsSizeT(), count);
const float* src = channel_data->Data();
float* dst = destination.View()->Data();
DCHECK(src);
DCHECK(dst);
- DCHECK_LE(count, channel_data->deprecatedLengthAsUnsigned());
- DCHECK_LE(buffer_offset + count, channel_data->deprecatedLengthAsUnsigned());
+ DCHECK_LE(count, data_length);
+ DCHECK_LE(buffer_offset + count, data_length);
memcpy(dst, src + buffer_offset, count * sizeof(*src));
}
@@ -266,7 +265,7 @@ void AudioBuffer::copyToChannel(NotShared<DOMFloat32Array> source,
void AudioBuffer::copyToChannel(NotShared<DOMFloat32Array> source,
int32_t channel_number,
- uint32_t buffer_offset,
+ size_t buffer_offset,
ExceptionState& exception_state) {
if (channel_number < 0 ||
static_cast<uint32_t>(channel_number) >= channels_.size()) {
@@ -282,22 +281,21 @@ void AudioBuffer::copyToChannel(NotShared<DOMFloat32Array> source,
DOMFloat32Array* channel_data = channels_[channel_number].Get();
- if (buffer_offset >= channel_data->deprecatedLengthAsUnsigned()) {
+ if (buffer_offset >= channel_data->lengthAsSizeT()) {
// Nothing to copy if the buffer offset is past the end of the AudioBuffer.
return;
}
- unsigned int count =
- channel_data->deprecatedLengthAsUnsigned() - buffer_offset;
+ size_t count = channel_data->lengthAsSizeT() - buffer_offset;
- count = std::min(source.View()->deprecatedLengthAsUnsigned(), count);
+ count = std::min(source.View()->lengthAsSizeT(), count);
const float* src = source.View()->Data();
float* dst = channel_data->Data();
DCHECK(src);
DCHECK(dst);
- DCHECK_LE(buffer_offset + count, channel_data->deprecatedLengthAsUnsigned());
- DCHECK_LE(count, source.View()->deprecatedLengthAsUnsigned());
+ DCHECK_LE(buffer_offset + count, channel_data->lengthAsSizeT());
+ DCHECK_LE(count, source.View()->lengthAsSizeT());
memcpy(dst + buffer_offset, src, count * sizeof(*dst));
}
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 9abd3054b42..a70c5f013b5 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer.h
@@ -95,19 +95,19 @@ class MODULES_EXPORT AudioBuffer final : public ScriptWrappable {
ExceptionState&);
void copyFromChannel(NotShared<DOMFloat32Array>,
int32_t channel_number,
- uint32_t buffer_offset,
+ size_t buffer_offset,
ExceptionState&);
void copyToChannel(NotShared<DOMFloat32Array>,
int32_t channel_number,
ExceptionState&);
void copyToChannel(NotShared<DOMFloat32Array>,
int32_t channel_number,
- uint32_t buffer_offset,
+ size_t buffer_offset,
ExceptionState&);
void Zero();
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(channels_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer.idl b/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer.idl
index 54e002a3015..d396fb78d87 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer.idl
@@ -28,18 +28,23 @@
// See https://webaudio.github.io/web-audio-api/#AudioBuffer
[
- Exposed=Window,
- Constructor(AudioBufferOptions options),
- RaisesException=Constructor,
- Measure
+ Exposed=Window
] interface AudioBuffer {
- readonly attribute long length; // in sample-frames
+ [RaisesException, Measure] constructor(AudioBufferOptions options);
+ readonly attribute unsigned long length; // in sample-frames
readonly attribute double duration; // in seconds
readonly attribute float sampleRate; // in sample-frames per second
// Channel access
readonly attribute unsigned long numberOfChannels;
- [HighEntropy, Measure, RaisesException] Float32Array getChannelData(unsigned long channelIndex);
- [HighEntropy, Measure, RaisesException] void copyFromChannel(Float32Array destination, long channelNumber, optional unsigned long bufferOffset = 0);
- [RaisesException] void copyToChannel(Float32Array source, long channelNumber, optional unsigned long bufferOffset = 0);
+ [HighEntropy, Measure, RaisesException] Float32Array getChannelData(
+ unsigned long channelIndex);
+ [HighEntropy, Measure, RaisesException] void copyFromChannel(
+ Float32Array destination,
+ unsigned long channelNumber,
+ optional unsigned long bufferOffset = 0);
+ [RaisesException] void copyToChannel(
+ Float32Array source,
+ unsigned long channelNumber,
+ optional unsigned long bufferOffset = 0);
};
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 3f80fdd4c82..cc8282bfd3f 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
@@ -26,14 +26,15 @@
#include <algorithm>
#include "base/numerics/safe_conversions.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_audio_buffer_source_options.h"
#include "third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.h"
-#include "third_party/blink/renderer/modules/webaudio/audio_buffer_source_options.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_output.h"
#include "third_party/blink/renderer/modules/webaudio/base_audio_context.h"
#include "third_party/blink/renderer/platform/audio/audio_utilities.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/instrumentation/use_counter.h"
+#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
namespace blink {
@@ -86,6 +87,9 @@ AudioBufferSourceHandler::~AudioBufferSourceHandler() {
}
void AudioBufferSourceHandler::Process(uint32_t frames_to_process) {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("webaudio.audionode"),
+ "AudioBufferSourceHandler::Process");
+
AudioBus* output_bus = Output(0).Bus();
if (!IsInitialized()) {
@@ -711,7 +715,7 @@ AudioBufferSourceNode* AudioBufferSourceNode::Create(
return node;
}
-void AudioBufferSourceNode::Trace(blink::Visitor* visitor) {
+void AudioBufferSourceNode::Trace(Visitor* visitor) {
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 f7c882d6f63..9dcf0bdec3f 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
AudioBufferSourceHandler& GetAudioBufferSourceHandler() const;
AudioBuffer* buffer() const;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.idl b/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.idl
index e41167f625b..87c54dfea0d 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.idl
@@ -24,15 +24,12 @@
*/
// A cached (non-streamed), memory-resident audio source
-// See https://webaudio.github.io/web-audio-api/#AudioBufferSourceNode
+// https://webaudio.github.io/web-audio-api/#AudioBufferSourceNode
[
Exposed=Window,
- Constructor(BaseAudioContext context, optional AudioBufferSourceOptions options),
- RaisesException=Constructor,
- ActiveScriptWrappable,
- Measure
-]
-interface AudioBufferSourceNode : AudioScheduledSourceNode {
+ ActiveScriptWrappable
+] interface AudioBufferSourceNode : AudioScheduledSourceNode {
+ [RaisesException, Measure] constructor(BaseAudioContext context, optional AudioBufferSourceOptions options = {});
[RaisesException=Setter] attribute AudioBuffer? buffer;
readonly attribute AudioParam playbackRate;
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 063475274c1..8f982aad34e 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc
@@ -4,12 +4,15 @@
#include "third_party/blink/renderer/modules/webaudio/audio_context.h"
+#include "base/metrics/histogram_functions.h"
#include "build/build_config.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/platform/web_audio_latency_hint.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_audio_context_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_audio_timestamp.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -19,9 +22,7 @@
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/core/timing/window_performance.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
-#include "third_party/blink/renderer/modules/webaudio/audio_context_options.h"
#include "third_party/blink/renderer/modules/webaudio/audio_listener.h"
-#include "third_party/blink/renderer/modules/webaudio/audio_timestamp.h"
#include "third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.h"
#include "third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.h"
#include "third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.h"
@@ -31,7 +32,6 @@
#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/heap/heap.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.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"
@@ -118,10 +118,8 @@ AudioContext* AudioContext::Create(Document& document,
audio_context, audio_context->context_id_, g_hardware_context_count);
#endif
- DEFINE_STATIC_LOCAL(SparseHistogram, max_channel_count_histogram,
- ("WebAudio.AudioContext.MaxChannelsAvailable"));
- max_channel_count_histogram.Sample(
- audio_context->destination()->maxChannelCount());
+ base::UmaHistogramSparse("WebAudio.AudioContext.MaxChannelsAvailable",
+ audio_context->destination()->maxChannelCount());
probe::DidCreateAudioContext(&document);
@@ -132,7 +130,8 @@ AudioContext::AudioContext(Document& document,
const WebAudioLatencyHint& latency_hint,
base::Optional<float> sample_rate)
: BaseAudioContext(&document, kRealtimeContext),
- context_id_(g_context_id++) {
+ context_id_(g_context_id++),
+ keep_alive_(PERSISTENT_FROM_HERE, this) {
destination_node_ =
RealtimeAudioDestinationNode::Create(this, latency_hint, sample_rate);
@@ -143,13 +142,13 @@ AudioContext::AudioContext(Document& document,
// kUserGestureRequire policy only applies to cross-origin iframes for Web
// Audio.
if (document.GetFrame() &&
- document.GetFrame()->IsCrossOriginSubframe()) {
- autoplay_status_ = AutoplayStatus::kAutoplayStatusFailed;
+ document.GetFrame()->IsCrossOriginToMainFrame()) {
+ autoplay_status_ = AutoplayStatus::kFailed;
user_gesture_required_ = true;
}
break;
case AutoplayPolicy::Type::kDocumentUserActivationRequired:
- autoplay_status_ = AutoplayStatus::kAutoplayStatusFailed;
+ autoplay_status_ = AutoplayStatus::kFailed;
user_gesture_required_ = true;
break;
}
@@ -169,13 +168,14 @@ AudioContext::AudioContext(Document& document,
destination()->GetAudioDestinationHandler());
base_latency_ = destination_handler.GetFramesPerBuffer() /
static_cast<double>(sampleRate());
+
}
void AudioContext::Uninitialize() {
DCHECK(IsMainThread());
DCHECK_NE(g_hardware_context_count, 0u);
--g_hardware_context_count;
-
+ StopRendering();
DidClose();
RecordAutoplayMetrics();
BaseAudioContext::Uninitialize();
@@ -194,7 +194,7 @@ AudioContext::~AudioContext() {
#endif
}
-void AudioContext::Trace(blink::Visitor* visitor) {
+void AudioContext::Trace(Visitor* visitor) {
visitor->Trace(close_resolver_);
BaseAudioContext::Trace(visitor);
}
@@ -214,7 +214,7 @@ ScriptPromise AudioContext::suspendContext(ScriptState* script_state) {
// Stop rendering now.
if (destination())
- StopRendering();
+ SuspendRendering();
// Since we don't have any way of knowing when the hardware actually stops,
// we'll just resolve the promise now.
@@ -227,14 +227,14 @@ ScriptPromise AudioContext::suspendContext(ScriptState* script_state) {
return promise;
}
-ScriptPromise AudioContext::resumeContext(ScriptState* script_state) {
+ScriptPromise AudioContext::resumeContext(ScriptState* script_state,
+ ExceptionState& exception_state) {
DCHECK(IsMainThread());
if (IsContextClosed()) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidAccessError,
- "cannot resume a closed AudioContext"));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidAccessError,
+ "cannot resume a closed AudioContext");
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -322,15 +322,17 @@ AudioTimestamp* AudioContext::getOutputTimestamp(
return result;
}
-ScriptPromise AudioContext::closeContext(ScriptState* script_state) {
+ScriptPromise AudioContext::closeContext(ScriptState* script_state,
+ ExceptionState& exception_state) {
if (IsContextClosed()) {
// We've already closed the context previously, but it hasn't yet been
- // resolved, so just create a new promise and reject it.
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "Cannot close a context that is being closed or "
- "has already been closed."));
+ // resolved, so just throw a DOM exception to trigger a promise rejection
+ // and return an empty promise.
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "Cannot close a context that is being closed or has already been "
+ "closed.");
+ return ScriptPromise();
}
close_resolver_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -358,14 +360,36 @@ bool AudioContext::IsContextClosed() const {
return close_resolver_ || BaseAudioContext::IsContextClosed();
}
+void AudioContext::StartRendering() {
+ DCHECK(IsMainThread());
+
+ if (!keep_alive_)
+ keep_alive_ = this;
+ BaseAudioContext::StartRendering();
+}
+
void AudioContext::StopRendering() {
DCHECK(IsMainThread());
DCHECK(destination());
+ // It is okay to perform the following on a suspended AudioContext because
+ // this method gets called from ExecutionContext::ContextDestroyed() meaning
+ // the AudioContext is already unreachable from the user code.
+ if (ContextState() != kClosed) {
+ destination()->GetAudioDestinationHandler().StopRendering();
+ SetContextState(kClosed);
+ GetDeferredTaskHandler().ClearHandlersToBeDeleted();
+ keep_alive_.Clear();
+ }
+}
+
+void AudioContext::SuspendRendering() {
+ DCHECK(IsMainThread());
+ DCHECK(destination());
+
if (ContextState() == kRunning) {
destination()->GetAudioDestinationHandler().StopRendering();
SetContextState(kSuspended);
- GetDeferredTaskHandler().ClearHandlersToBeDeleted();
}
}
@@ -461,10 +485,10 @@ void AudioContext::MaybeAllowAutoplayWithUnlockType(AutoplayUnlockType type) {
return;
DCHECK(!autoplay_status_.has_value() ||
- autoplay_status_ != AutoplayStatus::kAutoplayStatusSucceeded);
+ autoplay_status_ != AutoplayStatus::kSucceeded);
user_gesture_required_ = false;
- autoplay_status_ = AutoplayStatus::kAutoplayStatusSucceeded;
+ autoplay_status_ = AutoplayStatus::kSucceeded;
DCHECK(!autoplay_unlock_type_.has_value());
autoplay_unlock_type_ = type;
@@ -474,7 +498,7 @@ bool AudioContext::IsAllowedToStart() const {
if (!user_gesture_required_)
return true;
- Document* document = To<Document>(GetExecutionContext());
+ Document* document = Document::From(GetExecutionContext());
DCHECK(document);
switch (GetAutoplayPolicy()) {
@@ -483,15 +507,15 @@ bool AudioContext::IsAllowedToStart() const {
break;
case AutoplayPolicy::Type::kUserGestureRequired:
DCHECK(document->GetFrame());
- DCHECK(document->GetFrame()->IsCrossOriginSubframe());
- document->AddConsoleMessage(ConsoleMessage::Create(
+ DCHECK(document->GetFrame()->IsCrossOriginToMainFrame());
+ document->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kWarning,
"The AudioContext was not allowed to start. It must be resumed (or "
"created) from a user gesture event handler. https://goo.gl/7K7WLu"));
break;
case AutoplayPolicy::Type::kDocumentUserActivationRequired:
- document->AddConsoleMessage(ConsoleMessage::Create(
+ document->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kWarning,
"The AudioContext was not allowed to start. It must be resumed (or "
@@ -509,7 +533,7 @@ void AudioContext::RecordAutoplayMetrics() {
ukm::UkmRecorder* ukm_recorder = GetDocument()->UkmRecorder();
DCHECK(ukm_recorder);
ukm::builders::Media_Autoplay_AudioContext(GetDocument()->UkmSourceID())
- .SetStatus(autoplay_status_.value())
+ .SetStatus(static_cast<int>(autoplay_status_.value()))
.SetUnlockType(autoplay_unlock_type_
? static_cast<int>(autoplay_unlock_type_.value())
: -1)
@@ -517,43 +541,33 @@ void AudioContext::RecordAutoplayMetrics() {
.Record(ukm_recorder);
// Record autoplay_status_ value.
- DEFINE_STATIC_LOCAL(
- EnumerationHistogram, autoplay_histogram,
- ("WebAudio.Autoplay", AutoplayStatus::kAutoplayStatusCount));
- DEFINE_STATIC_LOCAL(
- EnumerationHistogram, cross_origin_autoplay_histogram,
- ("WebAudio.Autoplay.CrossOrigin", AutoplayStatus::kAutoplayStatusCount));
-
- autoplay_histogram.Count(autoplay_status_.value());
+ base::UmaHistogramEnumeration("WebAudio.Autoplay", autoplay_status_.value());
if (GetDocument()->GetFrame() &&
- GetDocument()->GetFrame()->IsCrossOriginSubframe()) {
- cross_origin_autoplay_histogram.Count(autoplay_status_.value());
+ GetDocument()->GetFrame()->IsCrossOriginToMainFrame()) {
+ base::UmaHistogramEnumeration("WebAudio.Autoplay.CrossOrigin",
+ autoplay_status_.value());
}
autoplay_status_.reset();
// Record autoplay_unlock_type_ value.
if (autoplay_unlock_type_.has_value()) {
- DEFINE_STATIC_LOCAL(EnumerationHistogram, autoplay_unlock_type_histogram,
- ("WebAudio.Autoplay.UnlockType",
- static_cast<int>(AutoplayUnlockType::kCount)));
-
- autoplay_unlock_type_histogram.Count(
- static_cast<int>(autoplay_unlock_type_.value()));
+ base::UmaHistogramEnumeration("WebAudio.Autoplay.UnlockType",
+ autoplay_unlock_type_.value());
autoplay_unlock_type_.reset();
}
}
-void AudioContext::ContextDestroyed(ExecutionContext*) {
+void AudioContext::ContextDestroyed() {
Uninitialize();
}
bool AudioContext::HasPendingActivity() const {
// There's activity if the context is is not closed. Suspended contexts count
// as having activity even though they are basically idle with nothing going
- // on. However, the can be resumed at any time, so we don't want contexts
+ // on. However, they can be resumed at any time, so we don't want contexts
// going away prematurely.
return (ContextState() != kClosed) && BaseAudioContext::HasPendingActivity();
}
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 013eee56725..10630b0c6a5 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.h
@@ -9,10 +9,11 @@
#include "third_party/blink/public/mojom/webaudio/audio_context_manager.mojom-blink.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_audio_context_options.h"
#include "third_party/blink/renderer/core/html/media/autoplay_policy.h"
-#include "third_party/blink/renderer/modules/webaudio/audio_context_options.h"
#include "third_party/blink/renderer/modules/webaudio/base_audio_context.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/self_keep_alive.h"
namespace blink {
@@ -42,17 +43,17 @@ class MODULES_EXPORT AudioContext : public BaseAudioContext {
const WebAudioLatencyHint&,
base::Optional<float> sample_rate);
~AudioContext() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// For ContextLifeCycleObserver
- void ContextDestroyed(ExecutionContext*) final;
+ void ContextDestroyed() final;
bool HasPendingActivity() const override;
- ScriptPromise closeContext(ScriptState*);
+ ScriptPromise closeContext(ScriptState*, ExceptionState&);
bool IsContextClosed() const final;
ScriptPromise suspendContext(ScriptState*);
- ScriptPromise resumeContext(ScriptState*);
+ ScriptPromise resumeContext(ScriptState*, ExceptionState&);
bool HasRealtimeConstraint() final { return true; }
@@ -92,10 +93,11 @@ class MODULES_EXPORT AudioContext : public BaseAudioContext {
friend class AudioContextAutoplayTest;
friend class AudioContextTest;
- // Do not change the order of this enum, it is used for metrics.
- enum AutoplayStatus {
+ // These values are persisted to logs. Entries should not be renumbered and
+ // numeric values should never be reused.
+ enum class AutoplayStatus {
// The AudioContext failed to activate because of user gesture requirements.
- kAutoplayStatusFailed = 0,
+ kFailed = 0,
// Same as AutoplayStatusFailed but start() on a node was called with a user
// gesture.
// This value is no longer used but the enum entry should not be re-used
@@ -103,10 +105,9 @@ class MODULES_EXPORT AudioContext : public BaseAudioContext {
// kAutoplayStatusFailedWithStart = 1,
// The AudioContext had user gesture requirements and was able to activate
// with a user gesture.
- kAutoplayStatusSucceeded = 2,
+ kSucceeded = 2,
- // Keep at the end.
- kAutoplayStatusCount
+ kMaxValue = kSucceeded,
};
// Returns the AutoplayPolicy currently applying to this instance.
@@ -120,7 +121,7 @@ class MODULES_EXPORT AudioContext : public BaseAudioContext {
kContextConstructor = 0,
kContextResume = 1,
kSourceNodeStart = 2,
- kCount
+ kMaxValue = kSourceNodeStart,
};
// If possible, allows autoplay for the AudioContext and marke it as allowed
@@ -133,8 +134,19 @@ class MODULES_EXPORT AudioContext : public BaseAudioContext {
// Record the current autoplay metrics.
void RecordAutoplayMetrics();
+ // Starts rendering via AudioDestinationNode. This sets the self-referencing
+ // pointer to this object.
+ void StartRendering() override;
+
+ // Called when the context is being closed to stop rendering audio and clean
+ // up handlers. This clears the self-referencing pointer, making this object
+ // available for the potential GC.
void StopRendering();
+ // Called when suspending the context to stop reundering audio, but don't
+ // clean up handlers because we expect to be resuming where we left off.
+ void SuspendRendering();
+
void DidClose();
// Called by the audio thread to handle Promises for resume() and suspend(),
@@ -190,6 +202,8 @@ class MODULES_EXPORT AudioContext : public BaseAudioContext {
// determine audibility on render quantum boundaries, so counting quanta is
// all that's needed.
size_t total_audible_renders_ = 0;
+
+ SelfKeepAlive<AudioContext> keep_alive_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.idl b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.idl
index 41fd88b849a..ec84063001e 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.idl
@@ -30,18 +30,15 @@ enum AudioContextLatencyCategory {
"playback"
};
-// See https://webaudio.github.io/web-audio-api/#AudioContext
+// https://webaudio.github.io/web-audio-api/#AudioContext
[
Exposed=Window,
- ActiveScriptWrappable,
- Constructor(optional AudioContextOptions contextOptions),
- ConstructorCallWith=Document,
- RaisesException=Constructor,
- Measure
+ ActiveScriptWrappable
] interface AudioContext : BaseAudioContext {
+ [CallWith=Document, RaisesException, Measure] constructor(optional AudioContextOptions contextOptions = {});
[MeasureAs=AudioContextSuspend, CallWith=ScriptState, ImplementedAs=suspendContext] Promise<void> suspend();
- [MeasureAs=AudioContextClose, CallWith=ScriptState, ImplementedAs=closeContext] Promise<void> close();
- [MeasureAs=AudioContextResume, CallWith=ScriptState, ImplementedAs=resumeContext] Promise<void> resume();
+ [MeasureAs=AudioContextClose, RaisesException, CallWith=ScriptState, ImplementedAs=closeContext] Promise<void> close();
+ [MeasureAs=AudioContextResume, RaisesException, CallWith=ScriptState, ImplementedAs=resumeContext] Promise<void> resume();
// Output timestamp
[MeasureAs=AudioContextGetOutputTimestamp, CallWith=ScriptState] AudioTimestamp getOutputTimestamp();
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 f234d7c0b33..0be3ef462de 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
@@ -12,6 +12,7 @@
#include "third_party/blink/public/platform/web_audio_device.h"
#include "third_party/blink/public/platform/web_audio_latency_hint.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_audio_context_options.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
#include "third_party/blink/renderer/core/frame/frame_types.h"
@@ -20,7 +21,6 @@
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/html/media/autoplay_policy.h"
#include "third_party/blink/renderer/core/loader/empty_clients.h"
-#include "third_party/blink/renderer/modules/webaudio/audio_context_options.h"
#include "third_party/blink/renderer/modules/webaudio/audio_worklet_thread.h"
#include "third_party/blink/renderer/platform/testing/histogram_tester.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
@@ -37,7 +37,7 @@ class MockCrossOriginLocalFrameClient final : public EmptyLocalFrameClient {
public:
explicit MockCrossOriginLocalFrameClient(Frame* parent) : parent_(parent) {}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(parent_);
EmptyLocalFrameClient::Trace(visitor);
}
@@ -151,10 +151,11 @@ TEST_P(AudioContextAutoplayTest, AutoplayMetrics_CreateNoGesture_Child) {
case AutoplayPolicy::Type::kUserGestureRequired:
case AutoplayPolicy::Type::kDocumentUserActivationRequired:
GetHistogramTester()->ExpectBucketCount(
- kAutoplayMetric, AutoplayStatus::kAutoplayStatusFailed, 1);
+ kAutoplayMetric, static_cast<int>(AutoplayStatus::kFailed), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayMetric, 1);
GetHistogramTester()->ExpectBucketCount(
- kAutoplayCrossOriginMetric, AutoplayStatus::kAutoplayStatusFailed, 1);
+ kAutoplayCrossOriginMetric, static_cast<int>(AutoplayStatus::kFailed),
+ 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayCrossOriginMetric, 1);
break;
}
@@ -174,7 +175,7 @@ TEST_P(AudioContextAutoplayTest, AutoplayMetrics_CreateNoGesture_Main) {
break;
case AutoplayPolicy::Type::kDocumentUserActivationRequired:
GetHistogramTester()->ExpectBucketCount(
- kAutoplayMetric, AutoplayStatus::kAutoplayStatusFailed, 1);
+ kAutoplayMetric, static_cast<int>(AutoplayStatus::kFailed), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayMetric, 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayCrossOriginMetric, 0);
break;
@@ -189,7 +190,8 @@ TEST_P(AudioContextAutoplayTest,
AudioContext* audio_context = AudioContext::Create(
ChildDocument(), AudioContextOptions::Create(), ASSERT_NO_EXCEPTION);
- audio_context->resumeContext(GetScriptStateFrom(ChildDocument()));
+ audio_context->resumeContext(GetScriptStateFrom(ChildDocument()),
+ ASSERT_NO_EXCEPTION);
RejectPendingResolvers(audio_context);
RecordAutoplayStatus(audio_context);
@@ -201,10 +203,11 @@ TEST_P(AudioContextAutoplayTest,
case AutoplayPolicy::Type::kUserGestureRequired:
case AutoplayPolicy::Type::kDocumentUserActivationRequired:
GetHistogramTester()->ExpectBucketCount(
- kAutoplayMetric, AutoplayStatus::kAutoplayStatusFailed, 1);
+ kAutoplayMetric, static_cast<int>(AutoplayStatus::kFailed), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayMetric, 1);
GetHistogramTester()->ExpectBucketCount(
- kAutoplayCrossOriginMetric, AutoplayStatus::kAutoplayStatusFailed, 1);
+ kAutoplayCrossOriginMetric, static_cast<int>(AutoplayStatus::kFailed),
+ 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayCrossOriginMetric, 1);
break;
}
@@ -216,7 +219,8 @@ TEST_P(AudioContextAutoplayTest, AutoplayMetrics_CallResumeNoGesture_Main) {
AudioContext* audio_context = AudioContext::Create(
GetDocument(), AudioContextOptions::Create(), ASSERT_NO_EXCEPTION);
- audio_context->resumeContext(GetScriptStateFrom(ChildDocument()));
+ audio_context->resumeContext(GetScriptStateFrom(ChildDocument()),
+ ASSERT_NO_EXCEPTION);
RejectPendingResolvers(audio_context);
RecordAutoplayStatus(audio_context);
@@ -228,7 +232,7 @@ TEST_P(AudioContextAutoplayTest, AutoplayMetrics_CallResumeNoGesture_Main) {
break;
case AutoplayPolicy::Type::kDocumentUserActivationRequired:
GetHistogramTester()->ExpectBucketCount(
- kAutoplayMetric, AutoplayStatus::kAutoplayStatusFailed, 1);
+ kAutoplayMetric, static_cast<int>(AutoplayStatus::kFailed), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayMetric, 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayCrossOriginMetric, 0);
break;
@@ -251,11 +255,11 @@ TEST_P(AudioContextAutoplayTest, AutoplayMetrics_CreateGesture_Child) {
case AutoplayPolicy::Type::kUserGestureRequired:
case AutoplayPolicy::Type::kDocumentUserActivationRequired:
GetHistogramTester()->ExpectBucketCount(
- kAutoplayMetric, AutoplayStatus::kAutoplayStatusSucceeded, 1);
+ kAutoplayMetric, static_cast<int>(AutoplayStatus::kSucceeded), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayMetric, 1);
GetHistogramTester()->ExpectBucketCount(
- kAutoplayCrossOriginMetric, AutoplayStatus::kAutoplayStatusSucceeded,
- 1);
+ kAutoplayCrossOriginMetric,
+ static_cast<int>(AutoplayStatus::kSucceeded), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayCrossOriginMetric, 1);
break;
}
@@ -277,7 +281,7 @@ TEST_P(AudioContextAutoplayTest, AutoplayMetrics_CreateGesture_Main) {
break;
case AutoplayPolicy::Type::kDocumentUserActivationRequired:
GetHistogramTester()->ExpectBucketCount(
- kAutoplayMetric, AutoplayStatus::kAutoplayStatusSucceeded, 1);
+ kAutoplayMetric, static_cast<int>(AutoplayStatus::kSucceeded), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayMetric, 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayCrossOriginMetric, 0);
break;
@@ -294,7 +298,8 @@ TEST_P(AudioContextAutoplayTest, AutoplayMetrics_CallResumeGesture_Child) {
LocalFrame::NotifyUserActivation(ChildDocument().GetFrame());
- audio_context->resumeContext(GetScriptStateFrom(ChildDocument()));
+ audio_context->resumeContext(GetScriptStateFrom(ChildDocument()),
+ ASSERT_NO_EXCEPTION);
RejectPendingResolvers(audio_context);
RecordAutoplayStatus(audio_context);
@@ -306,11 +311,11 @@ TEST_P(AudioContextAutoplayTest, AutoplayMetrics_CallResumeGesture_Child) {
case AutoplayPolicy::Type::kUserGestureRequired:
case AutoplayPolicy::Type::kDocumentUserActivationRequired:
GetHistogramTester()->ExpectBucketCount(
- kAutoplayMetric, AutoplayStatus::kAutoplayStatusSucceeded, 1);
+ kAutoplayMetric, static_cast<int>(AutoplayStatus::kSucceeded), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayMetric, 1);
GetHistogramTester()->ExpectBucketCount(
- kAutoplayCrossOriginMetric, AutoplayStatus::kAutoplayStatusSucceeded,
- 1);
+ kAutoplayCrossOriginMetric,
+ static_cast<int>(AutoplayStatus::kSucceeded), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayCrossOriginMetric, 1);
break;
}
@@ -326,7 +331,8 @@ TEST_P(AudioContextAutoplayTest, AutoplayMetrics_CallResumeGesture_Main) {
LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
- audio_context->resumeContext(GetScriptStateFrom(GetDocument()));
+ audio_context->resumeContext(GetScriptStateFrom(GetDocument()),
+ ASSERT_NO_EXCEPTION);
RejectPendingResolvers(audio_context);
RecordAutoplayStatus(audio_context);
@@ -338,7 +344,7 @@ TEST_P(AudioContextAutoplayTest, AutoplayMetrics_CallResumeGesture_Main) {
break;
case AutoplayPolicy::Type::kDocumentUserActivationRequired:
GetHistogramTester()->ExpectBucketCount(
- kAutoplayMetric, AutoplayStatus::kAutoplayStatusSucceeded, 1);
+ kAutoplayMetric, static_cast<int>(AutoplayStatus::kSucceeded), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayMetric, 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayCrossOriginMetric, 0);
break;
@@ -361,10 +367,11 @@ TEST_P(AudioContextAutoplayTest, AutoplayMetrics_NodeStartNoGesture_Child) {
case AutoplayPolicy::Type::kUserGestureRequired:
case AutoplayPolicy::Type::kDocumentUserActivationRequired:
GetHistogramTester()->ExpectBucketCount(
- kAutoplayMetric, AutoplayStatus::kAutoplayStatusFailed, 1);
+ kAutoplayMetric, static_cast<int>(AutoplayStatus::kFailed), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayMetric, 1);
GetHistogramTester()->ExpectBucketCount(
- kAutoplayCrossOriginMetric, AutoplayStatus::kAutoplayStatusFailed, 1);
+ kAutoplayCrossOriginMetric, static_cast<int>(AutoplayStatus::kFailed),
+ 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayCrossOriginMetric, 1);
break;
}
@@ -386,7 +393,7 @@ TEST_P(AudioContextAutoplayTest, AutoplayMetrics_NodeStartNoGesture_Main) {
break;
case AutoplayPolicy::Type::kDocumentUserActivationRequired:
GetHistogramTester()->ExpectBucketCount(
- kAutoplayMetric, AutoplayStatus::kAutoplayStatusFailed, 1);
+ kAutoplayMetric, static_cast<int>(AutoplayStatus::kFailed), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayMetric, 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayCrossOriginMetric, 0);
break;
@@ -411,11 +418,11 @@ TEST_P(AudioContextAutoplayTest, AutoplayMetrics_NodeStartGesture_Child) {
case AutoplayPolicy::Type::kUserGestureRequired:
case AutoplayPolicy::Type::kDocumentUserActivationRequired:
GetHistogramTester()->ExpectBucketCount(
- kAutoplayMetric, AutoplayStatus::kAutoplayStatusSucceeded, 1);
+ kAutoplayMetric, static_cast<int>(AutoplayStatus::kSucceeded), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayMetric, 1);
GetHistogramTester()->ExpectBucketCount(
- kAutoplayCrossOriginMetric, AutoplayStatus::kAutoplayStatusSucceeded,
- 1);
+ kAutoplayCrossOriginMetric,
+ static_cast<int>(AutoplayStatus::kSucceeded), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayCrossOriginMetric, 1);
break;
}
@@ -439,7 +446,7 @@ TEST_P(AudioContextAutoplayTest, AutoplayMetrics_NodeStartGesture_Main) {
break;
case AutoplayPolicy::Type::kDocumentUserActivationRequired:
GetHistogramTester()->ExpectBucketCount(
- kAutoplayMetric, AutoplayStatus::kAutoplayStatusSucceeded, 1);
+ kAutoplayMetric, static_cast<int>(AutoplayStatus::kSucceeded), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayMetric, 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayCrossOriginMetric, 0);
break;
@@ -457,7 +464,8 @@ TEST_P(AudioContextAutoplayTest,
audio_context->NotifySourceNodeStart();
LocalFrame::NotifyUserActivation(ChildDocument().GetFrame());
- audio_context->resumeContext(GetScriptStateFrom(ChildDocument()));
+ audio_context->resumeContext(GetScriptStateFrom(ChildDocument()),
+ ASSERT_NO_EXCEPTION);
RejectPendingResolvers(audio_context);
RecordAutoplayStatus(audio_context);
@@ -469,11 +477,11 @@ TEST_P(AudioContextAutoplayTest,
case AutoplayPolicy::Type::kUserGestureRequired:
case AutoplayPolicy::Type::kDocumentUserActivationRequired:
GetHistogramTester()->ExpectBucketCount(
- kAutoplayMetric, AutoplayStatus::kAutoplayStatusSucceeded, 1);
+ kAutoplayMetric, static_cast<int>(AutoplayStatus::kSucceeded), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayMetric, 1);
GetHistogramTester()->ExpectBucketCount(
- kAutoplayCrossOriginMetric, AutoplayStatus::kAutoplayStatusSucceeded,
- 1);
+ kAutoplayCrossOriginMetric,
+ static_cast<int>(AutoplayStatus::kSucceeded), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayCrossOriginMetric, 1);
break;
}
@@ -490,7 +498,8 @@ TEST_P(AudioContextAutoplayTest,
audio_context->NotifySourceNodeStart();
LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
- audio_context->resumeContext(GetScriptStateFrom(GetDocument()));
+ audio_context->resumeContext(GetScriptStateFrom(GetDocument()),
+ ASSERT_NO_EXCEPTION);
RejectPendingResolvers(audio_context);
RecordAutoplayStatus(audio_context);
@@ -502,7 +511,7 @@ TEST_P(AudioContextAutoplayTest,
break;
case AutoplayPolicy::Type::kDocumentUserActivationRequired:
GetHistogramTester()->ExpectBucketCount(
- kAutoplayMetric, AutoplayStatus::kAutoplayStatusSucceeded, 1);
+ kAutoplayMetric, static_cast<int>(AutoplayStatus::kSucceeded), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayMetric, 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayCrossOriginMetric, 0);
break;
@@ -520,7 +529,8 @@ TEST_P(AudioContextAutoplayTest,
LocalFrame::NotifyUserActivation(ChildDocument().GetFrame());
audio_context->NotifySourceNodeStart();
- audio_context->resumeContext(GetScriptStateFrom(ChildDocument()));
+ audio_context->resumeContext(GetScriptStateFrom(ChildDocument()),
+ ASSERT_NO_EXCEPTION);
RejectPendingResolvers(audio_context);
RecordAutoplayStatus(audio_context);
@@ -532,11 +542,11 @@ TEST_P(AudioContextAutoplayTest,
case AutoplayPolicy::Type::kUserGestureRequired:
case AutoplayPolicy::Type::kDocumentUserActivationRequired:
GetHistogramTester()->ExpectBucketCount(
- kAutoplayMetric, AutoplayStatus::kAutoplayStatusSucceeded, 1);
+ kAutoplayMetric, static_cast<int>(AutoplayStatus::kSucceeded), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayMetric, 1);
GetHistogramTester()->ExpectBucketCount(
- kAutoplayCrossOriginMetric, AutoplayStatus::kAutoplayStatusSucceeded,
- 1);
+ kAutoplayCrossOriginMetric,
+ static_cast<int>(AutoplayStatus::kSucceeded), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayCrossOriginMetric, 1);
break;
}
@@ -553,7 +563,8 @@ TEST_P(AudioContextAutoplayTest,
LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
audio_context->NotifySourceNodeStart();
- audio_context->resumeContext(GetScriptStateFrom(GetDocument()));
+ audio_context->resumeContext(GetScriptStateFrom(GetDocument()),
+ ASSERT_NO_EXCEPTION);
RejectPendingResolvers(audio_context);
RecordAutoplayStatus(audio_context);
@@ -565,7 +576,7 @@ TEST_P(AudioContextAutoplayTest,
break;
case AutoplayPolicy::Type::kDocumentUserActivationRequired:
GetHistogramTester()->ExpectBucketCount(
- kAutoplayMetric, AutoplayStatus::kAutoplayStatusSucceeded, 1);
+ kAutoplayMetric, static_cast<int>(AutoplayStatus::kSucceeded), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayMetric, 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayCrossOriginMetric, 0);
break;
@@ -589,20 +600,20 @@ TEST_P(AudioContextAutoplayTest,
break;
case AutoplayPolicy::Type::kUserGestureRequired:
GetHistogramTester()->ExpectBucketCount(
- kAutoplayMetric, AutoplayStatus::kAutoplayStatusSucceeded, 1);
+ kAutoplayMetric, static_cast<int>(AutoplayStatus::kSucceeded), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayMetric, 1);
GetHistogramTester()->ExpectBucketCount(
- kAutoplayCrossOriginMetric, AutoplayStatus::kAutoplayStatusSucceeded,
- 1);
+ kAutoplayCrossOriginMetric,
+ static_cast<int>(AutoplayStatus::kSucceeded), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayCrossOriginMetric, 1);
break;
case AutoplayPolicy::Type::kDocumentUserActivationRequired:
GetHistogramTester()->ExpectBucketCount(
- kAutoplayMetric, AutoplayStatus::kAutoplayStatusSucceeded, 1);
+ kAutoplayMetric, static_cast<int>(AutoplayStatus::kSucceeded), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayMetric, 1);
GetHistogramTester()->ExpectBucketCount(
- kAutoplayCrossOriginMetric, AutoplayStatus::kAutoplayStatusSucceeded,
- 1);
+ kAutoplayCrossOriginMetric,
+ static_cast<int>(AutoplayStatus::kSucceeded), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayCrossOriginMetric, 1);
break;
}
@@ -626,7 +637,7 @@ TEST_P(AudioContextAutoplayTest,
break;
case AutoplayPolicy::Type::kDocumentUserActivationRequired:
GetHistogramTester()->ExpectBucketCount(
- kAutoplayMetric, AutoplayStatus::kAutoplayStatusSucceeded, 1);
+ kAutoplayMetric, static_cast<int>(AutoplayStatus::kSucceeded), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayMetric, 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayCrossOriginMetric, 0);
break;
@@ -637,8 +648,7 @@ TEST_P(AudioContextAutoplayTest,
// document received a user gesture before navigation.
TEST_P(AudioContextAutoplayTest,
AutoplayMetrics_DocumentReceivedGesture_BeforeNavigation) {
- GetDocument().GetFrame()->SetDocumentHasReceivedUserGestureBeforeNavigation(
- true);
+ GetDocument().GetFrame()->SetHadStickyUserActivationBeforeNavigation(true);
AudioContext* audio_context = AudioContext::Create(
GetDocument(), AudioContextOptions::Create(), ASSERT_NO_EXCEPTION);
@@ -652,7 +662,7 @@ TEST_P(AudioContextAutoplayTest,
break;
case AutoplayPolicy::Type::kDocumentUserActivationRequired:
GetHistogramTester()->ExpectBucketCount(
- kAutoplayMetric, AutoplayStatus::kAutoplayStatusSucceeded, 1);
+ kAutoplayMetric, static_cast<int>(AutoplayStatus::kSucceeded), 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayMetric, 1);
GetHistogramTester()->ExpectTotalCount(kAutoplayCrossOriginMetric, 0);
break;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_context_test.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_context_test.cc
index 4d388e8b18c..3a2d85074b3 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_context_test.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_context_test.cc
@@ -183,9 +183,11 @@ TEST_F(AudioContextTest, ExecutionContextPaused) {
audio_context->set_was_audible_for_testing(true);
EXPECT_FALSE(web_audio_device_paused_);
- GetDocument().SetLifecycleState(mojom::FrameLifecycleState::kFrozen);
+ GetDocument().ToExecutionContext()->SetLifecycleState(
+ mojom::FrameLifecycleState::kFrozen);
EXPECT_TRUE(web_audio_device_paused_);
- GetDocument().SetLifecycleState(mojom::FrameLifecycleState::kRunning);
+ GetDocument().ToExecutionContext()->SetLifecycleState(
+ mojom::FrameLifecycleState::kRunning);
EXPECT_FALSE(web_audio_device_paused_);
}
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 82fd3202f35..05cba348460 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(blink::Visitor* visitor) {
+void AudioGraphTracer::Trace(Visitor* visitor) {
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 4cc03fef445..b6847261dd9 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 8c5ac3ead69..8cb80d52560 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(blink::Visitor* visitor) {
+void AudioListener::Trace(Visitor* visitor) {
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 04779d33d41..6be215b1b70 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_listener.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_listener.h
@@ -133,7 +133,7 @@ class AudioListener : public ScriptWrappable, public InspectorHelperMixin {
void ReportDidCreate() final;
void ReportWillBeDestroyed() final;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 15496ffdc8b..67ac709bbfa 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc
@@ -25,9 +25,9 @@
#include "third_party/blink/renderer/modules/webaudio/audio_node.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_audio_node_options.h"
#include "third_party/blink/renderer/modules/webaudio/audio_graph_tracer.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_input.h"
-#include "third_party/blink/renderer/modules/webaudio/audio_node_options.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_output.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_wiring.h"
#include "third_party/blink/renderer/modules/webaudio/audio_param.h"
@@ -650,7 +650,7 @@ AudioHandler& AudioNode::Handler() const {
return *handler_;
}
-void AudioNode::Trace(blink::Visitor* visitor) {
+void AudioNode::Trace(Visitor* visitor) {
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 5f716c83d44..82806009d4e 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
AudioHandler& Handler() const;
void HandleChannelOptions(const AudioNodeOptions*, ExceptionState&);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_node_input.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_node_input.cc
index 2672910faff..38c23201dfd 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_node_input.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_node_input.cc
@@ -86,7 +86,7 @@ unsigned AudioNodeInput::NumberOfChannels() const {
return max_channels;
}
-AudioBus* AudioNodeInput::Bus() {
+scoped_refptr<AudioBus> AudioNodeInput::Bus() {
DCHECK(GetDeferredTaskHandler().IsAudioThread());
// Handle single connection specially to allow for in-place processing.
@@ -98,13 +98,13 @@ AudioBus* AudioNodeInput::Bus() {
return InternalSummingBus();
}
-AudioBus* AudioNodeInput::InternalSummingBus() {
+scoped_refptr<AudioBus> AudioNodeInput::InternalSummingBus() {
DCHECK(GetDeferredTaskHandler().IsAudioThread());
- return internal_summing_bus_.get();
+ return internal_summing_bus_;
}
-void AudioNodeInput::SumAllConnections(AudioBus* summing_bus,
+void AudioNodeInput::SumAllConnections(scoped_refptr<AudioBus> summing_bus,
uint32_t frames_to_process) {
DCHECK(GetDeferredTaskHandler().IsAudioThread());
@@ -132,8 +132,8 @@ void AudioNodeInput::SumAllConnections(AudioBus* summing_bus,
}
}
-AudioBus* AudioNodeInput::Pull(AudioBus* in_place_bus,
- uint32_t frames_to_process) {
+scoped_refptr<AudioBus> AudioNodeInput::Pull(AudioBus* in_place_bus,
+ uint32_t frames_to_process) {
DCHECK(GetDeferredTaskHandler().IsAudioThread());
// Handle single connection case.
@@ -144,7 +144,7 @@ AudioBus* AudioNodeInput::Pull(AudioBus* in_place_bus,
return output->Pull(in_place_bus, frames_to_process);
}
- AudioBus* internal_summing_bus = this->InternalSummingBus();
+ scoped_refptr<AudioBus> internal_summing_bus = this->InternalSummingBus();
if (!NumberOfRenderingConnections()) {
// At least, generate silence if we're not connected to anything.
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_node_input.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_node_input.h
index 794bea7d629..e720f8801eb 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_node_input.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_node_input.h
@@ -65,12 +65,13 @@ class MODULES_EXPORT AudioNodeInput final : public AudioSummingJunction {
// where possible using inPlaceBus. It returns the bus which it rendered
// into, returning inPlaceBus if in-place processing was performed.
// Called from context's audio thread.
- AudioBus* Pull(AudioBus* in_place_bus, uint32_t frames_to_process);
+ scoped_refptr<AudioBus> Pull(AudioBus* in_place_bus,
+ uint32_t frames_to_process);
// bus() contains the rendered audio after pull() has been called for each
// time quantum.
// Called from context's audio thread.
- AudioBus* Bus();
+ scoped_refptr<AudioBus> Bus();
// updateInternalBus() updates m_internalSummingBus appropriately for the
// number of channels. This must be called when we own the context's graph
@@ -97,8 +98,9 @@ class MODULES_EXPORT AudioNodeInput final : public AudioSummingJunction {
HashSet<AudioNodeOutput*> disabled_outputs_;
// Called from context's audio thread.
- AudioBus* InternalSummingBus();
- void SumAllConnections(AudioBus* summing_bus, uint32_t frames_to_process);
+ scoped_refptr<AudioBus> InternalSummingBus();
+ void SumAllConnections(scoped_refptr<AudioBus> summing_bus,
+ uint32_t frames_to_process);
scoped_refptr<AudioBus> internal_summing_bus_;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_node_input_test.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_node_input_test.cc
index 89f564794f9..270e146401f 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_node_input_test.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_node_input_test.cc
@@ -17,8 +17,9 @@ namespace blink {
TEST(AudioNodeInputTest, InputDestroyedBeforeOutput) {
auto page = std::make_unique<DummyPageHolder>();
- OfflineAudioContext* context = OfflineAudioContext::Create(
- &page->GetDocument(), 2, 1, 48000, ASSERT_NO_EXCEPTION);
+ OfflineAudioContext* context =
+ OfflineAudioContext::Create(page->GetDocument().ToExecutionContext(), 2,
+ 1, 48000, ASSERT_NO_EXCEPTION);
DelayNode* node1 = context->createDelay(ASSERT_NO_EXCEPTION);
auto& handler1 = node1->Handler();
DelayNode* node2 = context->createDelay(ASSERT_NO_EXCEPTION);
@@ -41,8 +42,9 @@ TEST(AudioNodeInputTest, InputDestroyedBeforeOutput) {
TEST(AudioNodeInputTest, OutputDestroyedBeforeInput) {
auto page = std::make_unique<DummyPageHolder>();
- OfflineAudioContext* context = OfflineAudioContext::Create(
- &page->GetDocument(), 2, 1, 48000, ASSERT_NO_EXCEPTION);
+ OfflineAudioContext* context =
+ OfflineAudioContext::Create(page->GetDocument().ToExecutionContext(), 2,
+ 1, 48000, ASSERT_NO_EXCEPTION);
DelayNode* node1 = context->createDelay(ASSERT_NO_EXCEPTION);
auto& handler1 = node1->Handler();
DelayNode* node2 = context->createDelay(ASSERT_NO_EXCEPTION);
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 e8dbea2d58f..ecdcc71331d 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_param.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_param.cc
@@ -32,7 +32,7 @@
#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/bindings/exception_state.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
namespace blink {
@@ -355,7 +355,7 @@ AudioParam::~AudioParam() {
}
}
-void AudioParam::Trace(blink::Visitor* visitor) {
+void AudioParam::Trace(Visitor* visitor) {
visitor->Trace(context_);
InspectorHelperMixin::Trace(visitor);
ScriptWrappable::Trace(visitor);
@@ -367,13 +367,14 @@ float AudioParam::value() const {
void AudioParam::WarnIfOutsideRange(const String& param_method, float value) {
if (value < minValue() || value > maxValue()) {
- Context()->GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning,
- Handler().GetParamName() + "." + param_method + " " +
- String::Number(value) + " outside nominal range [" +
- String::Number(minValue()) + ", " + String::Number(maxValue()) +
- "]; value will be clamped."));
+ Context()->GetExecutionContext()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning,
+ Handler().GetParamName() + "." + param_method + " " +
+ String::Number(value) + " outside nominal range [" +
+ String::Number(minValue()) + ", " + String::Number(maxValue()) +
+ "]; value will be clamped."));
}
}
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 08e6c8c2666..b5675265aa6 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_param.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_param.h
@@ -190,6 +190,17 @@ class AudioParamHandler final : public ThreadSafeRefCounted<AudioParamHandler>,
return has_values || NumberOfRenderingConnections();
}
+ // TODO(crbug.com/1015760) This is like HasSAmpleAccurateValues, but
+ // we don't check for the rate. When the bug is fixed,
+ // HasSampleAccurateValues can be removed and this methed renamed.
+ bool HasSampleAccurateValuesTimeline() {
+ bool has_values =
+ timeline_.HasValues(destination_handler_->CurrentSampleFrame(),
+ destination_handler_->SampleRate());
+
+ return has_values || NumberOfRenderingConnections();
+ }
+
bool IsAudioRate() const { return automation_rate_ == kAudio; }
// Calculates numberOfValues parameter values starting at the context's
@@ -282,7 +293,7 @@ class AudioParam final : public ScriptWrappable, public InspectorHelperMixin {
~AudioParam() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 de7c7b1654e..04cc77bfcb5 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
@@ -11,7 +11,7 @@ class AudioParamMapIterationSource final
public:
AudioParamMapIterationSource(
const HeapHashMap<String, Member<AudioParam>>& map) {
- for (const auto name : map.Keys()) {
+ for (const auto& name : map.Keys()) {
parameter_names_.push_back(name);
parameter_objects_.push_back(map.at(name));
}
@@ -29,7 +29,7 @@ class AudioParamMapIterationSource final
return true;
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 e6203469873..f3da25ae3fa 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(parameter_map_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_param_timeline.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_param_timeline.cc
index e136083ea0f..c6177422fc2 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_param_timeline.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_param_timeline.cc
@@ -694,7 +694,7 @@ bool AudioParamTimeline::HasValues(size_t current_frame,
}
void AudioParamTimeline::CancelScheduledValues(
- double start_time,
+ double cancel_time,
ExceptionState& exception_state) {
DCHECK(IsMainThread());
@@ -702,7 +702,21 @@ void AudioParamTimeline::CancelScheduledValues(
// Remove all events starting at startTime.
for (wtf_size_t i = 0; i < events_.size(); ++i) {
- if (events_[i]->Time() >= start_time) {
+ // Removal all events whose event time (start) is greater than or
+ // equal to the cancel time. And also handle the special case
+ // where the cancel time lies in the middle of a setValueCurve
+ // event.
+ //
+ // This critically depends on the fact that no event can be
+ // scheduled in the middle of the curve or at the same start time.
+ // Then removing the setValueCurve doesn't remove any events that
+ // shouldn't have been.
+ double start_time = events_[i]->Time();
+
+ if (start_time >= cancel_time ||
+ ((events_[i]->GetType() == ParamEvent::kSetValueCurve) &&
+ start_time <= cancel_time &&
+ (start_time + events_[i]->Duration() > cancel_time))) {
RemoveCancelledEvents(i);
break;
}
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 5d26c22c213..c023bf3d110 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
@@ -25,8 +25,8 @@
#include "third_party/blink/renderer/modules/webaudio/audio_processing_event.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_audio_processing_event_init.h"
#include "third_party/blink/renderer/core/event_type_names.h"
-#include "third_party/blink/renderer/modules/webaudio/audio_processing_event_init.h"
namespace blink {
@@ -72,7 +72,7 @@ const AtomicString& AudioProcessingEvent::InterfaceName() const {
return event_interface_names::kAudioProcessingEvent;
}
-void AudioProcessingEvent::Trace(blink::Visitor* visitor) {
+void AudioProcessingEvent::Trace(Visitor* visitor) {
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 9c662f38d94..26725400cf7 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
@@ -27,9 +27,9 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_AUDIO_PROCESSING_EVENT_H_
#include "base/memory/scoped_refptr.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_audio_processing_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/webaudio/audio_buffer.h"
-#include "third_party/blink/renderer/modules/webaudio/audio_processing_event_init.h"
namespace blink {
@@ -62,7 +62,7 @@ class AudioProcessingEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<AudioBuffer> input_buffer_;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.idl b/chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.idl
index 8ca38a526a4..f9a87b66848 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.idl
@@ -25,10 +25,9 @@
// See https://webaudio.github.io/web-audio-api/#audioprocessingevent
[
- Exposed=Window,
- Constructor(DOMString type, AudioProcessingEventInit eventInitDict)
-]
-interface AudioProcessingEvent : Event {
+ Exposed=Window
+] interface AudioProcessingEvent : Event {
+ constructor(DOMString type, AudioProcessingEventInit eventInitDict);
readonly attribute double playbackTime;
readonly attribute AudioBuffer inputBuffer;
readonly attribute AudioBuffer outputBuffer;
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 d526a776c4c..3cd126a3333 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
@@ -179,7 +179,7 @@ class AudioScheduledSourceNode
// ScriptWrappable:
bool HasPendingActivity() const final;
- void Trace(blink::Visitor* visitor) override { AudioNode::Trace(visitor); }
+ void Trace(Visitor* visitor) 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 bf40475db63..dc4c8723468 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.cc
@@ -17,7 +17,7 @@
namespace blink {
AudioWorklet::AudioWorklet(BaseAudioContext* context)
- : Worklet(To<Document>(context->GetExecutionContext())),
+ : Worklet(Document::From(context->GetExecutionContext())),
context_(context) {}
void AudioWorklet::CreateProcessor(
@@ -90,7 +90,7 @@ AudioWorkletMessagingProxy* AudioWorklet::GetMessagingProxy() {
FindAvailableGlobalScope());
}
-void AudioWorklet::Trace(blink::Visitor* visitor) {
+void AudioWorklet::Trace(Visitor* visitor) {
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 1a51696ca74..c6705f9abef 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 72e7eb137d9..533a9f51bf8 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
@@ -24,7 +24,6 @@
#include "third_party/blink/renderer/core/workers/global_scope_creation_params.h"
#include "third_party/blink/renderer/core/workers/worker_thread.h"
#include "third_party/blink/renderer/modules/webaudio/audio_buffer.h"
-#include "third_party/blink/renderer/modules/webaudio/audio_param_descriptor.h"
#include "third_party/blink/renderer/modules/webaudio/audio_worklet_processor.h"
#include "third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.h"
#include "third_party/blink/renderer/modules/webaudio/audio_worklet_processor_error_state.h"
@@ -40,7 +39,13 @@ AudioWorkletGlobalScope::AudioWorkletGlobalScope(
WorkerThread* thread)
: WorkletGlobalScope(std::move(creation_params),
thread->GetWorkerReportingProxy(),
- thread) {}
+ thread) {
+ // Audio is prone to jank introduced by e.g. the garbage collector. Workers
+ // are generally put in a background mode (as they are non-visible). Audio is
+ // an exception here, requiring low-latency behavior similar to any visible
+ // state.
+ GetIsolate()->IsolateInForegroundNotification();
+}
AudioWorkletGlobalScope::~AudioWorkletGlobalScope() = default;
@@ -174,7 +179,7 @@ AudioWorkletProcessor* AudioWorkletGlobalScope::CreateProcessor(
bool AudioWorkletGlobalScope::Process(
AudioWorkletProcessor* processor,
- Vector<AudioBus*>* input_buses,
+ Vector<scoped_refptr<AudioBus>>* input_buses,
Vector<AudioBus*>* output_buses,
HashMap<String, std::unique_ptr<AudioFloatArray>>* param_value_map) {
CHECK_GE(input_buses->size(), 0u);
@@ -200,7 +205,7 @@ bool AudioWorkletGlobalScope::Process(
// 1st arg of JS callback: inputs
v8::Local<v8::Array> inputs = v8::Array::New(isolate, input_buses->size());
uint32_t input_bus_index = 0;
- for (auto* const input_bus : *input_buses) {
+ for (auto input_bus : *input_buses) {
// If |input_bus| is null, then the input is not connected, and
// the array for that input should have one channel and a length
// of 0.
@@ -387,7 +392,7 @@ double AudioWorkletGlobalScope::currentTime() const {
: 0.0;
}
-void AudioWorkletGlobalScope::Trace(blink::Visitor* visitor) {
+void AudioWorkletGlobalScope::Trace(Visitor* visitor) {
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 6166e0bc986..fc6051a4bb8 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
@@ -5,10 +5,10 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_AUDIO_WORKLET_GLOBAL_SCOPE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_AUDIO_WORKLET_GLOBAL_SCOPE_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_audio_param_descriptor.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/workers/worklet_global_scope.h"
#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/modules/webaudio/audio_param_descriptor.h"
#include "third_party/blink/renderer/platform/audio/audio_array.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
@@ -81,7 +81,7 @@ class MODULES_EXPORT AudioWorkletGlobalScope final : public WorkletGlobalScope {
// AudioWorkletProcessor, along with given AudioBuffer from the audio graph.
bool Process(
AudioWorkletProcessor*,
- Vector<AudioBus*>* input_buses,
+ Vector<scoped_refptr<AudioBus>>* input_buses,
Vector<AudioBus*>* output_buses,
HashMap<String, std::unique_ptr<AudioFloatArray>>* param_value_map);
@@ -104,7 +104,7 @@ class MODULES_EXPORT AudioWorkletGlobalScope final : public WorkletGlobalScope {
double currentTime() const;
float sampleRate() const { return sample_rate_; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
bool is_closing_ = false;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope_test.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope_test.cc
index 3daae5124ed..77563709c5f 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope_test.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope_test.cc
@@ -67,14 +67,15 @@ class AudioWorkletGlobalScopeTest : public PageTestBase {
Document* document = &GetDocument();
thread->Start(
std::make_unique<GlobalScopeCreationParams>(
- document->Url(), mojom::ScriptType::kModule,
- OffMainThreadWorkerScriptFetchOption::kEnabled, "AudioWorklet",
- document->UserAgent(), nullptr /* web_worker_fetch_context */,
- Vector<CSPHeaderAndType>(), document->GetReferrerPolicy(),
- document->GetSecurityOrigin(), document->IsSecureContext(),
- document->GetHttpsState(), nullptr /* worker_clients */,
- nullptr /* content_settings_client */, document->AddressSpace(),
- OriginTrialContext::GetTokens(document).get(),
+ document->Url(), mojom::blink::ScriptType::kModule, "AudioWorklet",
+ document->UserAgent(),
+ document->GetFrame()->Loader().UserAgentMetadata(),
+ nullptr /* web_worker_fetch_context */, Vector<CSPHeaderAndType>(),
+ document->GetReferrerPolicy(), document->GetSecurityOrigin(),
+ document->IsSecureContext(), document->GetHttpsState(),
+ nullptr /* worker_clients */, nullptr /* content_settings_client */,
+ document->GetSecurityContext().AddressSpace(),
+ OriginTrialContext::GetTokens(document->ToExecutionContext()).get(),
base::UnguessableToken::Create(), nullptr /* worker_settings */,
kV8CacheOptionsDefault,
MakeGarbageCollected<WorkletModuleResponsesMap>()),
@@ -290,7 +291,7 @@ class AudioWorkletGlobalScopeTest : public PageTestBase {
SerializedScriptValue::NullValue());
EXPECT_TRUE(processor);
- Vector<AudioBus*> input_buses;
+ Vector<scoped_refptr<AudioBus>> input_buses;
Vector<AudioBus*> output_buses;
HashMap<String, std::unique_ptr<AudioFloatArray>> param_data_map;
scoped_refptr<AudioBus> input_bus =
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 858b0250877..2d07b2e6a8b 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
@@ -6,13 +6,13 @@
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_audio_param_descriptor.h"
#include "third_party/blink/renderer/core/messaging/message_channel.h"
#include "third_party/blink/renderer/core/messaging/message_port.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/webaudio/audio_buffer.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_input.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_output.h"
-#include "third_party/blink/renderer/modules/webaudio/audio_param_descriptor.h"
#include "third_party/blink/renderer/modules/webaudio/audio_worklet.h"
#include "third_party/blink/renderer/modules/webaudio/audio_worklet_processor.h"
#include "third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.h"
@@ -21,6 +21,7 @@
#include "third_party/blink/renderer/platform/audio/audio_utilities.h"
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.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"
@@ -85,16 +86,20 @@ scoped_refptr<AudioWorkletHandler> AudioWorkletHandler::Create(
void AudioWorkletHandler::Process(uint32_t frames_to_process) {
DCHECK(Context()->IsAudioThread());
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("webaudio.audionode"),
+ "AudioWorkletHandler::Process");
+
// Render and update the node state when the processor is ready with no error.
// We also need to check if the global scope is valid before we request
// the rendering in the AudioWorkletGlobalScope.
if (processor_ && !processor_->hasErrorOccured()) {
- Vector<AudioBus*> input_buses;
+ Vector<scoped_refptr<AudioBus>> input_buses;
Vector<AudioBus*> output_buses;
for (unsigned i = 0; i < NumberOfInputs(); ++i) {
// If the input is not connected, inform the processor of that
// fact by setting the bus to null.
- AudioBus* bus = Input(i).IsConnected() ? Input(i).Bus() : nullptr;
+ scoped_refptr<AudioBus> bus =
+ Input(i).IsConnected() ? Input(i).Bus() : nullptr;
input_buses.push_back(bus);
}
for (unsigned i = 0; i < NumberOfOutputs(); ++i)
@@ -177,7 +182,7 @@ void AudioWorkletHandler::SetProcessorOnRenderThread(
PostCrossThreadTask(
*main_thread_task_runner_, FROM_HERE,
CrossThreadBindOnce(
- &AudioWorkletHandler::NotifyProcessorError, WrapRefCounted(this),
+ &AudioWorkletHandler::NotifyProcessorError, AsWeakPtr(),
AudioWorkletProcessorErrorState::kConstructionError));
}
}
@@ -192,7 +197,7 @@ void AudioWorkletHandler::FinishProcessorOnRenderThread() {
PostCrossThreadTask(
*main_thread_task_runner_, FROM_HERE,
CrossThreadBindOnce(&AudioWorkletHandler::NotifyProcessorError,
- WrapRefCounted(this), error_state));
+ AsWeakPtr(), error_state));
}
// TODO(hongchan): After this point, The handler has no more pending activity
@@ -310,6 +315,13 @@ AudioWorkletNode* AudioWorkletNode::Create(
return nullptr;
}
+ if (context->IsContextClosed()) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "AudioWorkletNode cannot be created: No execution context available.");
+ return nullptr;
+ }
+
auto* channel =
MakeGarbageCollected<MessageChannel>(context->GetExecutionContext());
MessagePortChannel processor_port_channel = channel->port2()->Disentangle();
@@ -383,7 +395,7 @@ scoped_refptr<AudioWorkletHandler> AudioWorkletNode::GetWorkletHandler() const {
return WrapRefCounted(&static_cast<AudioWorkletHandler&>(Handler()));
}
-void AudioWorkletNode::Trace(blink::Visitor* visitor) {
+void AudioWorkletNode::Trace(Visitor* visitor) {
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 03e1c58e9e4..d32d2f9ac25 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
@@ -6,9 +6,10 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_AUDIO_WORKLET_NODE_H_
#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_audio_worklet_node_options.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node.h"
#include "third_party/blink/renderer/modules/webaudio/audio_param_map.h"
-#include "third_party/blink/renderer/modules/webaudio/audio_worklet_node_options.h"
#include "third_party/blink/renderer/modules/webaudio/audio_worklet_processor_error_state.h"
#include "third_party/blink/renderer/platform/wtf/threading.h"
@@ -31,7 +32,9 @@ class ScriptState;
// AudioWorkletNode <-> AudioWorkletHandler <==|==> AudioWorkletProcessor
// (JS interface) (Renderer access) | (V8 audio processing)
-class AudioWorkletHandler final : public AudioHandler {
+class AudioWorkletHandler final
+ : public AudioHandler,
+ public base::SupportsWeakPtr<AudioWorkletHandler> {
public:
static scoped_refptr<AudioWorkletHandler> Create(
AudioNode&,
@@ -118,7 +121,7 @@ class AudioWorkletNode final : public AudioNode,
void FireProcessorError();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// InspectorHelperMixin
void ReportDidCreate() final;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.idl b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.idl
index ac7e6daeacc..9c985b4baee 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.idl
@@ -2,16 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// See https://webaudio.github.io/web-audio-api/#audioworkletnode
+// https://webaudio.github.io/web-audio-api/#audioworkletnode
[
Exposed=Window,
- ActiveScriptWrappable,
- Constructor(BaseAudioContext context, DOMString name, optional AudioWorkletNodeOptions options),
- ConstructorCallWith=ScriptState,
- MeasureAs=AudioWorkletNodeConstructor,
- RaisesException=Constructor
+ ActiveScriptWrappable
] interface AudioWorkletNode : AudioNode {
+ [CallWith=ScriptState, RaisesException, MeasureAs=AudioWorkletNodeConstructor] constructor(BaseAudioContext context, DOMString name, optional AudioWorkletNodeOptions options = {});
readonly attribute AudioParamMap parameters;
readonly attribute MessagePort port;
attribute EventHandler onprocessorerror;
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 8c19bd3b628..332bbc578d3 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
@@ -34,7 +34,7 @@ AudioWorkletProcessor::AudioWorkletProcessor(
: global_scope_(global_scope), processor_port_(port), name_(name) {}
bool AudioWorkletProcessor::Process(
- Vector<AudioBus*>* input_buses,
+ Vector<scoped_refptr<AudioBus>>* input_buses,
Vector<AudioBus*>* output_buses,
HashMap<String, std::unique_ptr<AudioFloatArray>>* param_value_map) {
DCHECK(global_scope_->IsContextThread());
@@ -60,7 +60,7 @@ MessagePort* AudioWorkletProcessor::port() const {
return processor_port_.Get();
}
-void AudioWorkletProcessor::Trace(blink::Visitor* visitor) {
+void AudioWorkletProcessor::Trace(Visitor* visitor) {
visitor->Trace(global_scope_);
visitor->Trace(processor_port_);
ScriptWrappable::Trace(visitor);
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 e5e9aedcac0..c658de5e68d 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
@@ -45,7 +45,7 @@ class MODULES_EXPORT AudioWorkletProcessor : public ScriptWrappable {
// |AudioWorkletHandler| invokes this method to process audio.
bool Process(
- Vector<AudioBus*>* input_buses,
+ Vector<scoped_refptr<AudioBus>>* input_buses,
Vector<AudioBus*>* output_buses,
HashMap<String, std::unique_ptr<AudioFloatArray>>* param_value_map);
@@ -58,7 +58,7 @@ class MODULES_EXPORT AudioWorkletProcessor : public ScriptWrappable {
// IDL
MessagePort* port() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<AudioWorkletGlobalScope> global_scope_;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.idl b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.idl
index 9853c972979..a6ed0388028 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.idl
@@ -5,9 +5,8 @@
// See https://webaudio.github.io/web-audio-api/#audioworkletprocessor
[
- Constructor,
- ConstructorCallWith=ExecutionContext,
Exposed=AudioWorklet
] interface AudioWorkletProcessor {
+ [CallWith=ExecutionContext] constructor();
readonly attribute MessagePort port;
};
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 a4d0d466b43..4582883825c 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
@@ -34,7 +34,7 @@ void AudioWorkletProcessorDefinition::SetAudioParamDescriptors(
const Vector<String>
AudioWorkletProcessorDefinition::GetAudioParamDescriptorNames() const {
Vector<String> names;
- for (const auto descriptor : audio_param_descriptors_) {
+ for (const auto& descriptor : audio_param_descriptors_) {
names.push_back(descriptor->name());
}
return names;
@@ -43,14 +43,14 @@ const Vector<String>
const AudioParamDescriptor*
AudioWorkletProcessorDefinition::GetAudioParamDescriptor (
const String& key) const {
- for (const auto descriptor : audio_param_descriptors_) {
+ for (const auto& descriptor : audio_param_descriptors_) {
if (descriptor->name() == key)
return descriptor;
}
return nullptr;
}
-void AudioWorkletProcessorDefinition::Trace(blink::Visitor* visitor) {
+void AudioWorkletProcessorDefinition::Trace(Visitor* visitor) {
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 4ff7ca44d3a..8423067b7c7 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
@@ -5,8 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_AUDIO_WORKLET_PROCESSOR_DEFINITION_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_AUDIO_WORKLET_PROCESSOR_DEFINITION_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_audio_param_descriptor.h"
#include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/blink/renderer/modules/webaudio/audio_param_descriptor.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -56,7 +56,7 @@ class MODULES_EXPORT AudioWorkletProcessorDefinition final
bool IsSynchronized() const { return is_synchronized_; }
void MarkAsSynchronized() { is_synchronized_ = true; }
- void Trace(blink::Visitor* visitor);
+ void Trace(Visitor* visitor);
const char* NameInHeapSnapshot() const override {
return "AudioWorkletProcessorDefinition";
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread_test.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread_test.cc
index 2a566ace5af..017e7eaf8b2 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread_test.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_thread_test.cc
@@ -57,14 +57,15 @@ class AudioWorkletThreadTest : public PageTestBase {
Document* document = &GetDocument();
thread->Start(
std::make_unique<GlobalScopeCreationParams>(
- document->Url(), mojom::ScriptType::kModule,
- OffMainThreadWorkerScriptFetchOption::kEnabled, "AudioWorklet",
- document->UserAgent(), nullptr /* web_worker_fetch_context */,
- Vector<CSPHeaderAndType>(), document->GetReferrerPolicy(),
- document->GetSecurityOrigin(), document->IsSecureContext(),
- document->GetHttpsState(), nullptr /* worker_clients */,
- nullptr /* content_settings_client */, document->AddressSpace(),
- OriginTrialContext::GetTokens(document).get(),
+ document->Url(), mojom::blink::ScriptType::kModule, "AudioWorklet",
+ document->UserAgent(),
+ document->GetFrame()->Loader().UserAgentMetadata(),
+ nullptr /* web_worker_fetch_context */, Vector<CSPHeaderAndType>(),
+ document->GetReferrerPolicy(), document->GetSecurityOrigin(),
+ document->IsSecureContext(), document->GetHttpsState(),
+ nullptr /* worker_clients */, nullptr /* content_settings_client */,
+ document->GetSecurityContext().AddressSpace(),
+ OriginTrialContext::GetTokens(document->ToExecutionContext()).get(),
base::UnguessableToken::Create(), nullptr /* worker_settings */,
kV8CacheOptionsDefault,
MakeGarbageCollected<WorkletModuleResponsesMap>()),
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 34f2c6d63eb..8d008c21430 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
@@ -25,12 +25,14 @@
#include "third_party/blink/renderer/modules/webaudio/base_audio_context.h"
+#include "base/metrics/histogram_functions.h"
#include "build/build_config.h"
#include "third_party/blink/public/mojom/devtools/console_message.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/core/v8/dictionary.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_periodic_wave_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/frame/settings.h"
@@ -47,7 +49,6 @@
#include "third_party/blink/renderer/modules/webaudio/audio_worklet.h"
#include "third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h"
#include "third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.h"
-#include "third_party/blink/renderer/modules/webaudio/audio_graph_tracer.h"
#include "third_party/blink/renderer/modules/webaudio/biquad_filter_node.h"
#include "third_party/blink/renderer/modules/webaudio/channel_merger_node.h"
#include "third_party/blink/renderer/modules/webaudio/channel_splitter_node.h"
@@ -64,7 +65,6 @@
#include "third_party/blink/renderer/modules/webaudio/oscillator_node.h"
#include "third_party/blink/renderer/modules/webaudio/panner_node.h"
#include "third_party/blink/renderer/modules/webaudio/periodic_wave.h"
-#include "third_party/blink/renderer/modules/webaudio/periodic_wave_constraints.h"
#include "third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.h"
#include "third_party/blink/renderer/modules/webaudio/script_processor_node.h"
#include "third_party/blink/renderer/modules/webaudio/stereo_panner_node.h"
@@ -74,7 +74,6 @@
#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/heap/heap.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/uuid.h"
@@ -86,7 +85,7 @@ namespace blink {
// Constructor for rendering to the audio hardware.
BaseAudioContext::BaseAudioContext(Document* document,
enum ContextType context_type)
- : ContextLifecycleStateObserver(document),
+ : ExecutionContextLifecycleStateObserver(document),
InspectorHelperMixin(*AudioGraphTracer::FromDocument(*document),
String()),
destination_node_(nullptr),
@@ -151,8 +150,6 @@ void BaseAudioContext::Clear() {
void BaseAudioContext::Uninitialize() {
DCHECK(IsMainThread());
- MutexLocker locker(GetTearDownMutex());
-
if (!IsDestinationInitialized())
return;
@@ -200,7 +197,7 @@ void BaseAudioContext::ContextLifecycleStateChanged(
destination()->GetAudioDestinationHandler().Pause();
}
-void BaseAudioContext::ContextDestroyed(ExecutionContext*) {
+void BaseAudioContext::ContextDestroyed() {
destination()->GetAudioDestinationHandler().ContextDestroyed();
Uninitialize();
}
@@ -227,17 +224,17 @@ void BaseAudioContext::WarnIfContextClosed(const AudioHandler* handler) const {
DCHECK(handler);
if (IsContextClosed() && GetDocument()) {
- GetDocument()->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kOther,
- mojom::ConsoleMessageLevel::kWarning,
- "Construction of " + handler->NodeTypeName() +
- " is not useful when context is closed."));
+ GetDocument()->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kOther,
+ mojom::ConsoleMessageLevel::kWarning,
+ "Construction of " + handler->NodeTypeName() +
+ " is not useful when context is closed."));
}
}
void BaseAudioContext::WarnForConnectionIfContextClosed() const {
if (IsContextClosed() && GetDocument()) {
- GetDocument()->AddConsoleMessage(ConsoleMessage::Create(
+ GetDocument()->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kWarning,
"Connecting nodes after the context has been closed is not useful."));
@@ -254,27 +251,22 @@ AudioBuffer* BaseAudioContext::createBuffer(uint32_t number_of_channels,
AudioBuffer* buffer = AudioBuffer::Create(
number_of_channels, number_of_frames, sample_rate, exception_state);
+ // Only record the data if the creation succeeded.
if (buffer) {
- // Only record the data if the creation succeeded.
- DEFINE_STATIC_LOCAL(SparseHistogram, audio_buffer_channels_histogram,
- ("WebAudio.AudioBuffer.NumberOfChannels"));
+ base::UmaHistogramSparse("WebAudio.AudioBuffer.NumberOfChannels",
+ number_of_channels);
// Arbitrarly limit the maximum length to 1 million frames (about 20 sec
// at 48kHz). The number of buckets is fairly arbitrary.
- DEFINE_STATIC_LOCAL(CustomCountHistogram, audio_buffer_length_histogram,
- ("WebAudio.AudioBuffer.Length", 1, 1000000, 50));
+ base::UmaHistogramCounts1M("WebAudio.AudioBuffer.Length", number_of_frames);
+
// The limits are the min and max AudioBuffer sample rates currently
// supported. We use explicit values here instead of
// audio_utilities::minAudioBufferSampleRate() and
// audio_utilities::maxAudioBufferSampleRate(). The number of buckets is
// fairly arbitrary.
- DEFINE_STATIC_LOCAL(
- CustomCountHistogram, audio_buffer_sample_rate_histogram,
- ("WebAudio.AudioBuffer.SampleRate384kHz", 3000, 384000, 60));
-
- audio_buffer_channels_histogram.Sample(number_of_channels);
- audio_buffer_length_histogram.Count(number_of_frames);
- audio_buffer_sample_rate_histogram.Count(sample_rate);
+ base::UmaHistogramCustomCounts("WebAudio.AudioBuffer.SampleRate384kHz",
+ sample_rate, 3000, 384000, 60);
// Compute the ratio of the buffer rate and the context rate so we know
// how often the buffer needs to be resampled to match the context. For
@@ -286,12 +278,10 @@ AudioBuffer* BaseAudioContext::createBuffer(uint32_t number_of_channels,
// 100*(384000/3000) = 12800, where 3000 and 384000 are the current
// min and max sample rates possible for an AudioBuffer. The number
// of buckets is fairly arbitrary.
- DEFINE_STATIC_LOCAL(
- CustomCountHistogram, audio_buffer_sample_rate_ratio_histogram,
- ("WebAudio.AudioBuffer.SampleRateRatio384kHz", 1, 12800, 50));
float ratio = 100 * sample_rate / this->sampleRate();
- audio_buffer_sample_rate_ratio_histogram.Count(
- static_cast<int>(0.5 + ratio));
+ base::UmaHistogramCustomCounts(
+ "WebAudio.AudioBuffer.SampleRateRatio384kHz",
+ static_cast<int>(0.5 + ratio), 1, 12800, 50);
}
}
@@ -324,6 +314,15 @@ ScriptPromise BaseAudioContext::decodeAudioData(
DCHECK(IsMainThread());
DCHECK(audio_data);
+ // TODO(crbug.com/1060315): This check needs to be revised when the spec
+ // behavior is clarified for the case of a non-existent ExecutionContext.
+ if (!GetExecutionContext()) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotAllowedError,
+ "Cannot decode audio data: The document is no longer active.");
+ return ScriptPromise();
+ }
+
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
@@ -671,7 +670,7 @@ void BaseAudioContext::NotifySourceNodeFinishedProcessing(
}
Document* BaseAudioContext::GetDocument() const {
- return To<Document>(GetExecutionContext());
+ return Document::From(GetExecutionContext());
}
void BaseAudioContext::NotifySourceNodeStartedProcessing(AudioNode* node) {
@@ -791,7 +790,7 @@ const AtomicString& BaseAudioContext::InterfaceName() const {
}
ExecutionContext* BaseAudioContext::GetExecutionContext() const {
- return ContextLifecycleStateObserver::GetExecutionContext();
+ return ExecutionContextLifecycleStateObserver::GetExecutionContext();
}
void BaseAudioContext::StartRendering() {
@@ -807,7 +806,7 @@ void BaseAudioContext::StartRendering() {
}
}
-void BaseAudioContext::Trace(blink::Visitor* visitor) {
+void BaseAudioContext::Trace(Visitor* visitor) {
visitor->Trace(destination_node_);
visitor->Trace(listener_);
visitor->Trace(resume_resolvers_);
@@ -819,7 +818,7 @@ void BaseAudioContext::Trace(blink::Visitor* visitor) {
visitor->Trace(audio_worklet_);
InspectorHelperMixin::Trace(visitor);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleStateObserver::Trace(visitor);
+ ExecutionContextLifecycleStateObserver::Trace(visitor);
}
const SecurityOrigin* BaseAudioContext::GetSecurityOrigin() const {
@@ -910,4 +909,17 @@ void BaseAudioContext::ReportWillBeDestroyed() {
GraphTracer().WillDestroyBaseAudioContext(this);
}
+bool BaseAudioContext::CheckExecutionContextAndThrowIfNecessary(
+ ExceptionState& exception_state) {
+ if (!GetExecutionContext()) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotAllowedError,
+ "The operation is not allowed on a detached frame or document because "
+ "no execution context is available.");
+ return false;
+ }
+
+ return true;
+}
+
} // namespace blink
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 a99b2dddad4..4a253013fe3 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
@@ -33,7 +33,7 @@
#include "third_party/blink/renderer/bindings/modules/v8/v8_decode_error_callback.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_decode_success_callback.h"
#include "third_party/blink/renderer/core/dom/events/event_listener.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.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"
#include "third_party/blink/renderer/modules/event_target_modules.h"
@@ -92,7 +92,7 @@ class WorkerThread;
class MODULES_EXPORT BaseAudioContext
: public EventTargetWithInlineData,
public ActiveScriptWrappable<BaseAudioContext>,
- public ContextLifecycleStateObserver,
+ public ExecutionContextLifecycleStateObserver,
public InspectorHelperMixin {
USING_GARBAGE_COLLECTED_MIXIN(BaseAudioContext);
DEFINE_WRAPPERTYPEINFO();
@@ -108,7 +108,7 @@ class MODULES_EXPORT BaseAudioContext
~BaseAudioContext() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// Is the destination node initialized and ready to handle audio?
bool IsDestinationInitialized() const {
@@ -120,10 +120,10 @@ class MODULES_EXPORT BaseAudioContext
// Document notification
void ContextLifecycleStateChanged(mojom::FrameLifecycleState) override;
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
bool HasPendingActivity() const override;
- // Cannnot be called from the audio thread.
+ // Cannot be called from the audio thread.
AudioDestinationNode* destination() const;
size_t CurrentSampleFrame() const {
@@ -285,7 +285,7 @@ class MODULES_EXPORT BaseAudioContext
DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange, kStatechange)
- void StartRendering();
+ virtual void StartRendering();
void NotifyStateChange();
@@ -331,7 +331,10 @@ class MODULES_EXPORT BaseAudioContext
void ReportDidCreate() final;
void ReportWillBeDestroyed() final;
- Mutex& GetTearDownMutex() const { return tear_down_mutex_; }
+ // TODO(crbug.com/1055983): Remove this when the execution context validity
+ // check is not required in the AudioNode factory methods. Returns false
+ // if the execution context does not exist.
+ bool CheckExecutionContextAndThrowIfNecessary(ExceptionState&);
protected:
enum ContextType { kRealtimeContext, kOfflineContext };
@@ -434,12 +437,6 @@ class MODULES_EXPORT BaseAudioContext
// This cannot be nullptr once it is assigned from AudioWorkletThread until
// the BaseAudioContext goes away.
WorkerThread* audio_worklet_thread_ = nullptr;
-
- // Due to the multi-threading architecture of WebAudio, it is possible that
- // object allocated by the main thread still can be accessed by the audio
- // rendering thread while this context is torn down (GCed) by
- // |Uninitialize()|.
- mutable Mutex tear_down_mutex_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.idl b/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.idl
index 3a9bd6a0803..13eca1ad65c 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.idl
@@ -56,7 +56,7 @@ callback DecodeSuccessCallback = void (AudioBuffer decodedData);
[RaisesException, MeasureAs=AudioContextCreateScriptProcessor] ScriptProcessorNode createScriptProcessor(optional unsigned long bufferSize, optional unsigned long numberOfInputChannels, optional unsigned long numberOfOutputChannels);
[RaisesException, MeasureAs=AudioContextCreateStereoPanner] StereoPannerNode createStereoPanner();
[RaisesException, MeasureAs=AudioContextCreateOscillator] OscillatorNode createOscillator();
- [RaisesException, MeasureAs=AudioContextCreatePeriodicWave] PeriodicWave createPeriodicWave(sequence<float> real, sequence<float> imag, optional PeriodicWaveConstraints options);
+ [RaisesException, MeasureAs=AudioContextCreatePeriodicWave] PeriodicWave createPeriodicWave(sequence<float> real, sequence<float> imag, optional PeriodicWaveConstraints constraints = {});
// Channel splitting and merging
[RaisesException, MeasureAs=AudioContextCreateChannelSplitter] ChannelSplitterNode createChannelSplitter(optional unsigned long numberOfOutputs);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/biquad_dsp_kernel.cc b/chromium/third_party/blink/renderer/modules/webaudio/biquad_dsp_kernel.cc
index 38fb9516486..7ccfe59c823 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/biquad_dsp_kernel.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/biquad_dsp_kernel.cc
@@ -110,35 +110,35 @@ void BiquadDSPKernel::UpdateCoefficients(int number_of_frames,
// Configure the biquad with the new filter parameters for the appropriate
// type of filter.
switch (GetBiquadProcessor()->GetType()) {
- case BiquadProcessor::kLowPass:
+ case BiquadProcessor::FilterType::kLowPass:
biquad_.SetLowpassParams(k, normalized_frequency, q[k]);
break;
- case BiquadProcessor::kHighPass:
+ case BiquadProcessor::FilterType::kHighPass:
biquad_.SetHighpassParams(k, normalized_frequency, q[k]);
break;
- case BiquadProcessor::kBandPass:
+ case BiquadProcessor::FilterType::kBandPass:
biquad_.SetBandpassParams(k, normalized_frequency, q[k]);
break;
- case BiquadProcessor::kLowShelf:
+ case BiquadProcessor::FilterType::kLowShelf:
biquad_.SetLowShelfParams(k, normalized_frequency, gain[k]);
break;
- case BiquadProcessor::kHighShelf:
+ case BiquadProcessor::FilterType::kHighShelf:
biquad_.SetHighShelfParams(k, normalized_frequency, gain[k]);
break;
- case BiquadProcessor::kPeaking:
+ case BiquadProcessor::FilterType::kPeaking:
biquad_.SetPeakingParams(k, normalized_frequency, q[k], gain[k]);
break;
- case BiquadProcessor::kNotch:
+ case BiquadProcessor::FilterType::kNotch:
biquad_.SetNotchParams(k, normalized_frequency, q[k]);
break;
- case BiquadProcessor::kAllpass:
+ case BiquadProcessor::FilterType::kAllpass:
biquad_.SetAllpassParams(k, normalized_frequency, q[k]);
break;
}
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 f0cf1ae8610..e518806139b 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
@@ -27,13 +27,14 @@
#include <memory>
+#include "base/metrics/histogram_functions.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_biquad_filter_options.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/modules/webaudio/audio_basic_processor_handler.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_output.h"
-#include "third_party/blink/renderer/modules/webaudio/biquad_filter_options.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/instrumentation/histogram.h"
+#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.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"
@@ -76,6 +77,9 @@ scoped_refptr<BiquadFilterHandler> BiquadFilterHandler::Create(
}
void BiquadFilterHandler::Process(uint32_t frames_to_process) {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("webaudio.audionode"),
+ "BiquadFilterHandler::Process");
+
AudioBasicProcessorHandler::Process(frames_to_process);
if (!did_warn_bad_filter_state_) {
@@ -98,11 +102,13 @@ void BiquadFilterHandler::NotifyBadState() const {
if (!Context() || !Context()->GetExecutionContext())
return;
- Context()->GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning,
- NodeTypeName() + ": state is bad, probably due to unstable filter caused "
- "by fast parameter automation."));
+ Context()->GetExecutionContext()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning,
+ NodeTypeName() +
+ ": state is bad, probably due to unstable filter caused "
+ "by fast parameter automation."));
}
BiquadFilterNode::BiquadFilterNode(BaseAudioContext& context)
@@ -122,20 +128,23 @@ BiquadFilterNode::BiquadFilterNode(BaseAudioContext& context)
1.0,
AudioParamHandler::AutomationRate::kAudio,
AudioParamHandler::AutomationRateMode::kVariable)),
- gain_(
+ gain_(AudioParam::Create(context,
+ Uuid(),
+ AudioParamHandler::kParamTypeBiquadFilterGain,
+ 0.0,
+ AudioParamHandler::AutomationRate::kAudio,
+ AudioParamHandler::AutomationRateMode::kVariable,
+ std::numeric_limits<float>::lowest(),
+ 40 * log10f(std::numeric_limits<float>::max()))),
+ detune_(
AudioParam::Create(context,
Uuid(),
- AudioParamHandler::kParamTypeBiquadFilterGain,
+ AudioParamHandler::kParamTypeBiquadFilterDetune,
0.0,
AudioParamHandler::AutomationRate::kAudio,
- AudioParamHandler::AutomationRateMode::kVariable)),
- detune_(AudioParam::Create(
- context,
- Uuid(),
- AudioParamHandler::kParamTypeBiquadFilterDetune,
- 0.0,
- AudioParamHandler::AutomationRate::kAudio,
- AudioParamHandler::AutomationRateMode::kVariable)) {
+ AudioParamHandler::AutomationRateMode::kVariable,
+ -1200 * log2f(std::numeric_limits<float>::max()),
+ 1200 * log2f(std::numeric_limits<float>::max()))) {
SetHandler(BiquadFilterHandler::Create(*this, context.sampleRate(),
frequency_->Handler(), q_->Handler(),
gain_->Handler(), detune_->Handler()));
@@ -147,6 +156,11 @@ BiquadFilterNode* BiquadFilterNode::Create(BaseAudioContext& context,
ExceptionState& exception_state) {
DCHECK(IsMainThread());
+ // TODO(crbug.com/1055983): Remove this when the execution context validity
+ // check is not required in the AudioNode factory methods.
+ if (!context.CheckExecutionContextAndThrowIfNecessary(exception_state))
+ return nullptr;
+
return MakeGarbageCollected<BiquadFilterNode>(context);
}
@@ -161,7 +175,7 @@ BiquadFilterNode* BiquadFilterNode::Create(BaseAudioContext* context,
node->HandleChannelOptions(options, exception_state);
node->setType(options->type());
- node->q()->setValue(options->Q());
+ node->q()->setValue(options->q());
node->detune()->setValue(options->detune());
node->frequency()->setValue(options->frequency());
node->gain()->setValue(options->gain());
@@ -169,7 +183,7 @@ BiquadFilterNode* BiquadFilterNode::Create(BaseAudioContext* context,
return node;
}
-void BiquadFilterNode::Trace(blink::Visitor* visitor) {
+void BiquadFilterNode::Trace(Visitor* visitor) {
visitor->Trace(frequency_);
visitor->Trace(q_);
visitor->Trace(gain_);
@@ -185,58 +199,54 @@ BiquadProcessor* BiquadFilterNode::GetBiquadProcessor() const {
String BiquadFilterNode::type() const {
switch (
const_cast<BiquadFilterNode*>(this)->GetBiquadProcessor()->GetType()) {
- case BiquadProcessor::kLowPass:
+ case BiquadProcessor::FilterType::kLowPass:
return "lowpass";
- case BiquadProcessor::kHighPass:
+ case BiquadProcessor::FilterType::kHighPass:
return "highpass";
- case BiquadProcessor::kBandPass:
+ case BiquadProcessor::FilterType::kBandPass:
return "bandpass";
- case BiquadProcessor::kLowShelf:
+ case BiquadProcessor::FilterType::kLowShelf:
return "lowshelf";
- case BiquadProcessor::kHighShelf:
+ case BiquadProcessor::FilterType::kHighShelf:
return "highshelf";
- case BiquadProcessor::kPeaking:
+ case BiquadProcessor::FilterType::kPeaking:
return "peaking";
- case BiquadProcessor::kNotch:
+ case BiquadProcessor::FilterType::kNotch:
return "notch";
- case BiquadProcessor::kAllpass:
+ case BiquadProcessor::FilterType::kAllpass:
return "allpass";
- default:
- NOTREACHED();
- return "lowpass";
}
+ NOTREACHED();
+ return "lowpass";
}
void BiquadFilterNode::setType(const String& type) {
if (type == "lowpass") {
- setType(BiquadProcessor::kLowPass);
+ SetType(BiquadProcessor::FilterType::kLowPass);
} else if (type == "highpass") {
- setType(BiquadProcessor::kHighPass);
+ SetType(BiquadProcessor::FilterType::kHighPass);
} else if (type == "bandpass") {
- setType(BiquadProcessor::kBandPass);
+ SetType(BiquadProcessor::FilterType::kBandPass);
} else if (type == "lowshelf") {
- setType(BiquadProcessor::kLowShelf);
+ SetType(BiquadProcessor::FilterType::kLowShelf);
} else if (type == "highshelf") {
- setType(BiquadProcessor::kHighShelf);
+ SetType(BiquadProcessor::FilterType::kHighShelf);
} else if (type == "peaking") {
- setType(BiquadProcessor::kPeaking);
+ SetType(BiquadProcessor::FilterType::kPeaking);
} else if (type == "notch") {
- setType(BiquadProcessor::kNotch);
+ SetType(BiquadProcessor::FilterType::kNotch);
} else if (type == "allpass") {
- setType(BiquadProcessor::kAllpass);
+ SetType(BiquadProcessor::FilterType::kAllpass);
}
}
-bool BiquadFilterNode::setType(unsigned type) {
- if (type > BiquadProcessor::kAllpass)
+bool BiquadFilterNode::SetType(BiquadProcessor::FilterType type) {
+ if (type > BiquadProcessor::FilterType::kAllpass)
return false;
- DEFINE_STATIC_LOCAL(
- EnumerationHistogram, filter_type_histogram,
- ("WebAudio.BiquadFilter.Type", BiquadProcessor::kAllpass + 1));
- filter_type_histogram.Count(type);
+ base::UmaHistogramEnumeration("WebAudio.BiquadFilter.Type", type);
- GetBiquadProcessor()->SetType(static_cast<BiquadProcessor::FilterType>(type));
+ GetBiquadProcessor()->SetType(type);
return true;
}
@@ -245,35 +255,37 @@ void BiquadFilterNode::getFrequencyResponse(
NotShared<DOMFloat32Array> mag_response,
NotShared<DOMFloat32Array> phase_response,
ExceptionState& exception_state) {
- unsigned frequency_hz_length =
- frequency_hz.View()->deprecatedLengthAsUnsigned();
+ size_t frequency_hz_length = frequency_hz.View()->lengthAsSizeT();
- if (mag_response.View()->deprecatedLengthAsUnsigned() !=
- frequency_hz_length) {
+ if (mag_response.View()->lengthAsSizeT() != frequency_hz_length) {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidAccessError,
ExceptionMessages::IndexOutsideRange(
- "magResponse length",
- mag_response.View()->deprecatedLengthAsUnsigned(),
+ "magResponse length", mag_response.View()->lengthAsSizeT(),
frequency_hz_length, ExceptionMessages::kInclusiveBound,
frequency_hz_length, ExceptionMessages::kInclusiveBound));
return;
}
- if (phase_response.View()->deprecatedLengthAsUnsigned() !=
- frequency_hz_length) {
+ if (phase_response.View()->lengthAsSizeT() != frequency_hz_length) {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidAccessError,
ExceptionMessages::IndexOutsideRange(
- "phaseResponse length",
- phase_response.View()->deprecatedLengthAsUnsigned(),
+ "phaseResponse length", phase_response.View()->lengthAsSizeT(),
frequency_hz_length, ExceptionMessages::kInclusiveBound,
frequency_hz_length, ExceptionMessages::kInclusiveBound));
return;
}
+ int frequency_hz_length_as_int;
+ if (!base::CheckedNumeric<int>(frequency_hz_length)
+ .AssignIfValid(&frequency_hz_length_as_int)) {
+ exception_state.ThrowRangeError(
+ "frequencyHz length exceeds the maximum supported length");
+ return;
+ }
GetBiquadProcessor()->GetFrequencyResponse(
- frequency_hz_length, frequency_hz.View()->Data(),
+ frequency_hz_length_as_int, frequency_hz.View()->Data(),
mag_response.View()->Data(), phase_response.View()->Data());
}
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 07c0c455ecb..c12bb49406a 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
String type() const;
void setType(const String&);
@@ -116,7 +116,7 @@ class BiquadFilterNode final : public AudioNode {
private:
BiquadProcessor* GetBiquadProcessor() const;
- bool setType(unsigned); // Returns true on success.
+ bool SetType(BiquadProcessor::FilterType); // Returns true on success.
Member<AudioParam> frequency_;
Member<AudioParam> q_;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.idl b/chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.idl
index f50739460dc..f221cc9222a 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.idl
@@ -23,7 +23,7 @@
* DAMAGE.
*/
-// See https://webaudio.github.io/web-audio-api/#biquadfilternode
+// https://webaudio.github.io/web-audio-api/#biquadfilternode
enum BiquadFilterType {
"lowpass",
"highpass",
@@ -36,12 +36,9 @@ enum BiquadFilterType {
};
[
- Exposed=Window,
- Constructor(BaseAudioContext context, optional BiquadFilterOptions options),
- RaisesException=Constructor,
- Measure
-]
-interface BiquadFilterNode : AudioNode {
+ Exposed=Window
+] interface BiquadFilterNode : AudioNode {
+ [RaisesException, Measure] constructor(BaseAudioContext context, optional BiquadFilterOptions options = {});
attribute BiquadFilterType type;
readonly attribute AudioParam frequency; // in Hertz
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/biquad_processor.cc b/chromium/third_party/blink/renderer/modules/webaudio/biquad_processor.cc
index 59eb72d94ce..d0ff3875ddd 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/biquad_processor.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/biquad_processor.cc
@@ -37,7 +37,7 @@ BiquadProcessor::BiquadProcessor(float sample_rate,
AudioParamHandler& gain,
AudioParamHandler& detune)
: AudioDSPKernelProcessor(sample_rate, number_of_channels),
- type_(kLowPass),
+ type_(FilterType::kLowPass),
parameter1_(&frequency),
parameter2_(&q),
parameter3_(&gain),
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/biquad_processor.h b/chromium/third_party/blink/renderer/modules/webaudio/biquad_processor.h
index 954ac2cc33e..6dcd04160be 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/biquad_processor.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/biquad_processor.h
@@ -41,8 +41,9 @@ namespace blink {
class BiquadProcessor final : public AudioDSPKernelProcessor {
public:
- // This values are used in histograms and should not be renumbered or deleted.
- enum FilterType {
+ // These values are persisted to logs. Entries should not be renumbered and
+ // numeric values should never be reused.
+ enum class FilterType {
kLowPass = 0,
kHighPass = 1,
kBandPass = 2,
@@ -50,7 +51,8 @@ class BiquadProcessor final : public AudioDSPKernelProcessor {
kHighShelf = 4,
kPeaking = 5,
kNotch = 6,
- kAllpass = 7
+ kAllpass = 7,
+ kMaxValue = kAllpass,
};
BiquadProcessor(float sample_rate,
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/channel_merger_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/channel_merger_node.cc
index c0a3303c46b..d21cc8ac7ea 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/channel_merger_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/channel_merger_node.cc
@@ -28,11 +28,11 @@
#include "third_party/blink/renderer/modules/webaudio/channel_merger_node.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_channel_merger_options.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_input.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_output.h"
#include "third_party/blink/renderer/modules/webaudio/base_audio_context.h"
-#include "third_party/blink/renderer/modules/webaudio/channel_merger_options.h"
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/channel_merger_node.idl b/chromium/third_party/blink/renderer/modules/webaudio/channel_merger_node.idl
index f0639ea2122..21b31d014bd 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/channel_merger_node.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/channel_merger_node.idl
@@ -26,12 +26,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// See https://webaudio.github.io/web-audio-api/#channelmergernode
+// https://webaudio.github.io/web-audio-api/#channelmergernode
[
- Exposed=Window,
- Constructor(BaseAudioContext context, optional ChannelMergerOptions options),
- RaisesException=Constructor,
- Measure
-]
-interface ChannelMergerNode : AudioNode {
+ Exposed=Window
+] interface ChannelMergerNode : AudioNode {
+ [RaisesException, Measure] constructor(BaseAudioContext context, optional ChannelMergerOptions options = {});
};
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/channel_splitter_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/channel_splitter_node.cc
index 32061de317c..dd72c09b91a 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/channel_splitter_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/channel_splitter_node.cc
@@ -25,10 +25,10 @@
#include "third_party/blink/renderer/modules/webaudio/channel_splitter_node.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_channel_splitter_options.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_input.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_output.h"
#include "third_party/blink/renderer/modules/webaudio/base_audio_context.h"
-#include "third_party/blink/renderer/modules/webaudio/channel_splitter_options.h"
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -61,7 +61,7 @@ scoped_refptr<ChannelSplitterHandler> ChannelSplitterHandler::Create(
}
void ChannelSplitterHandler::Process(uint32_t frames_to_process) {
- AudioBus* source = Input(0).Bus();
+ scoped_refptr<AudioBus> source = Input(0).Bus();
DCHECK(source);
DCHECK_EQ(frames_to_process, source->length());
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/channel_splitter_node.idl b/chromium/third_party/blink/renderer/modules/webaudio/channel_splitter_node.idl
index a91d7e7601f..6bc52acd7ef 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/channel_splitter_node.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/channel_splitter_node.idl
@@ -23,12 +23,9 @@
* DAMAGE.
*/
-// See https://webaudio.github.io/web-audio-api/#channelsplitternode
+// https://webaudio.github.io/web-audio-api/#channelsplitternode
[
- Exposed=Window,
- Constructor(BaseAudioContext context, optional ChannelSplitterOptions options),
- RaisesException=Constructor,
- Measure
-]
-interface ChannelSplitterNode : AudioNode {
+ Exposed=Window
+] interface ChannelSplitterNode : AudioNode {
+ [RaisesException, Measure] constructor(BaseAudioContext context, optional ChannelSplitterOptions options = {});
};
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 77e91a7f98b..075b2802a57 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
@@ -6,8 +6,8 @@
#include <algorithm>
+#include "third_party/blink/renderer/bindings/modules/v8/v8_constant_source_options.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_output.h"
-#include "third_party/blink/renderer/modules/webaudio/constant_source_options.h"
#include "third_party/blink/renderer/platform/audio/audio_utilities.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
@@ -70,7 +70,9 @@ void ConstantSourceHandler::Process(uint32_t frames_to_process) {
return;
}
- if (offset_->HasSampleAccurateValues()) {
+ bool is_sample_accurate = offset_->HasSampleAccurateValuesTimeline();
+
+ if (is_sample_accurate && offset_->IsAudioRate()) {
DCHECK_LE(frames_to_process, sample_accurate_values_.size());
float* offsets = sample_accurate_values_.Data();
offset_->CalculateSampleAccurateValues(offsets, frames_to_process);
@@ -82,19 +84,20 @@ void ConstantSourceHandler::Process(uint32_t frames_to_process) {
} else {
output_bus->Zero();
}
- } else {
- float value = offset_->Value();
- if (value == 0) {
- output_bus->Zero();
- } else {
- float* dest = output_bus->Channel(0)->MutableData();
- dest += quantum_frame_offset;
- for (unsigned k = 0; k < non_silent_frames_to_process; ++k) {
- dest[k] = value;
- }
- output_bus->ClearSilentFlag();
+ return;
+ }
+
+ float value = is_sample_accurate ? offset_->FinalValue() : offset_->Value();
+ if (value == 0) {
+ output_bus->Zero();
+ } else {
+ float* dest = output_bus->Channel(0)->MutableData();
+ dest += quantum_frame_offset;
+ for (unsigned k = 0; k < non_silent_frames_to_process; ++k) {
+ dest[k] = value;
}
+ output_bus->ClearSilentFlag();
}
}
@@ -153,7 +156,7 @@ ConstantSourceNode* ConstantSourceNode::Create(
return node;
}
-void ConstantSourceNode::Trace(blink::Visitor* visitor) {
+void ConstantSourceNode::Trace(Visitor* visitor) {
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 6476ee0a0f3..141100ab827 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
AudioParam* offset();
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.idl b/chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.idl
index 6a21393a470..0bc1ab3c131 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.idl
@@ -2,14 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// See https://webaudio.github.io/web-audio-api/#ConstantSourceNode
+// https://webaudio.github.io/web-audio-api/#ConstantSourceNode
[
Exposed=Window,
- Constructor(BaseAudioContext context, optional ConstantSourceOptions options),
- RaisesException=Constructor,
- ActiveScriptWrappable,
- Measure
-]
-interface ConstantSourceNode : AudioScheduledSourceNode {
+ ActiveScriptWrappable
+] interface ConstantSourceNode : AudioScheduledSourceNode {
+ [RaisesException, Measure] constructor(BaseAudioContext context, optional ConstantSourceOptions options = {});
readonly attribute 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 ce19fe6675c..71fa4abd2dc 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.cc
@@ -24,14 +24,17 @@
*/
#include "third_party/blink/renderer/modules/webaudio/convolver_node.h"
+
#include <memory>
+
+#include "base/metrics/histogram_macros.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_convolver_options.h"
#include "third_party/blink/renderer/modules/webaudio/audio_buffer.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_input.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_output.h"
-#include "third_party/blink/renderer/modules/webaudio/convolver_options.h"
#include "third_party/blink/renderer/platform/audio/reverb.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/instrumentation/histogram.h"
// Note about empirical tuning:
// The maximum FFT size affects reverb performance and accuracy.
@@ -89,7 +92,8 @@ void ConvolverHandler::Process(uint32_t frames_to_process) {
// FIXME: If we wanted to get fancy we could try to factor in the 'tail
// time' and stop processing once the tail dies down if
// we keep getting fed silence.
- reverb_->Process(Input(0).Bus(), output_bus, frames_to_process);
+ scoped_refptr<AudioBus> input_bus = Input(0).Bus();
+ reverb_->Process(input_bus.get(), output_bus, frames_to_process);
}
} else {
// Too bad - the tryLock() failed. We must be in the middle of setting a
@@ -219,11 +223,19 @@ void ConvolverHandler::SetChannelCount(unsigned channel_count,
DCHECK(IsMainThread());
BaseAudioContext::GraphAutoLocker locker(Context());
- // channelCount must be 2.
- if (channel_count != 2) {
+ // channelCount must be 1 or 2
+ if (channel_count == 1 || channel_count == 2) {
+ if (channel_count_ != channel_count) {
+ channel_count_ = channel_count;
+ UpdateChannelsForInputs();
+ }
+ } else {
exception_state.ThrowDOMException(
DOMExceptionCode::kNotSupportedError,
- "ConvolverNode: channelCount cannot be changed from 2");
+ ExceptionMessages::IndexOutsideRange<uint32_t>(
+ "channelCount", channel_count, 1,
+ ExceptionMessages::kInclusiveBound, 2,
+ ExceptionMessages::kInclusiveBound));
}
}
@@ -232,11 +244,27 @@ void ConvolverHandler::SetChannelCountMode(const String& mode,
DCHECK(IsMainThread());
BaseAudioContext::GraphAutoLocker locker(Context());
- // channcelCountMode must be 'clamped-max'.
- if (mode != "clamped-max") {
+ ChannelCountMode old_mode = InternalChannelCountMode();
+
+ // The channelCountMode cannot be "max". For a convolver node, the
+ // number of input channels must be 1 or 2 (see
+ // https://webaudio.github.io/web-audio-api/#audionode-channelcount-constraints)
+ // and "max" would be incompatible with that.
+ if (mode == "max") {
exception_state.ThrowDOMException(
DOMExceptionCode::kNotSupportedError,
- "ConvolverNode: channelCountMode cannot be changed from 'clamped-max'");
+ "ConvolverNode: channelCountMode cannot be changed to 'max'");
+ new_channel_count_mode_ = old_mode;
+ } else if (mode == "explicit") {
+ new_channel_count_mode_ = kExplicit;
+ } else if (mode == "clamped-max") {
+ new_channel_count_mode_ = kClampedMax;
+ } else {
+ NOTREACHED();
+ }
+
+ if (new_channel_count_mode_ != old_mode) {
+ Context()->GetDeferredTaskHandler().AddChangedChannelCountMode(this);
}
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.idl b/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.idl
index f1dcda3b1ce..3d41a804338 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.idl
@@ -24,14 +24,11 @@
*/
// A linear convolution effect
-// See https://webaudio.github.io/web-audio-api/#ConvolverNode
+// https://webaudio.github.io/web-audio-api/#ConvolverNode
[
- Exposed=Window,
- Constructor(BaseAudioContext context, optional ConvolverOptions options),
- RaisesException=Constructor,
- Measure
-]
-interface ConvolverNode : AudioNode {
+ Exposed=Window
+] interface ConvolverNode : AudioNode {
+ [RaisesException, Measure] constructor(BaseAudioContext context, optional ConvolverOptions options = {});
[RaisesException=Setter] attribute AudioBuffer? buffer;
attribute boolean normalize;
};
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/convolver_node_test.cc b/chromium/third_party/blink/renderer/modules/webaudio/convolver_node_test.cc
index f3f85bc51e5..c690c08ad91 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/convolver_node_test.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/convolver_node_test.cc
@@ -13,8 +13,9 @@ namespace blink {
TEST(ConvolverNodeTest, ReverbLifetime) {
auto page = std::make_unique<DummyPageHolder>();
- OfflineAudioContext* context = OfflineAudioContext::Create(
- &page->GetDocument(), 2, 1, 48000, ASSERT_NO_EXCEPTION);
+ OfflineAudioContext* context =
+ OfflineAudioContext::Create(page->GetDocument().ToExecutionContext(), 2,
+ 1, 48000, ASSERT_NO_EXCEPTION);
ConvolverNode* node = context->createConvolver(ASSERT_NO_EXCEPTION);
ConvolverHandler& handler = node->GetConvolverHandler();
EXPECT_FALSE(handler.reverb_);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/cross_thread_audio_worklet_processor_info.h b/chromium/third_party/blink/renderer/modules/webaudio/cross_thread_audio_worklet_processor_info.h
index 64cf12545be..553216518f7 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/cross_thread_audio_worklet_processor_info.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/cross_thread_audio_worklet_processor_info.h
@@ -5,7 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_CROSS_THREAD_AUDIO_WORKLET_PROCESSOR_INFO_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_CROSS_THREAD_AUDIO_WORKLET_PROCESSOR_INFO_H_
-#include "third_party/blink/renderer/modules/webaudio/audio_param_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_audio_param_descriptor.h"
#include "third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc b/chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
index 2afb5cf60f7..09e88ac41d0 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
@@ -344,7 +344,7 @@ void DeferredTaskHandler::RequestToDeleteHandlersOnMainThread() {
PostCrossThreadTask(
*task_runner_, FROM_HERE,
CrossThreadBindOnce(&DeferredTaskHandler::DeleteHandlersOnMainThread,
- scoped_refptr<DeferredTaskHandler>(this)));
+ AsWeakPtr()));
}
void DeferredTaskHandler::DeleteHandlersOnMainThread() {
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.h b/chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.h
index 7d13eeb1a58..0530c7fc127 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.h
@@ -28,6 +28,7 @@
#include <atomic>
#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.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/wtf/hash_set.h"
@@ -62,7 +63,8 @@ class AudioSummingJunction;
// - GC happens and it collects the BaseAudioContext before the task execution.
//
class MODULES_EXPORT DeferredTaskHandler final
- : public ThreadSafeRefCounted<DeferredTaskHandler> {
+ : public ThreadSafeRefCounted<DeferredTaskHandler>,
+ public base::SupportsWeakPtr<DeferredTaskHandler> {
public:
static scoped_refptr<DeferredTaskHandler> Create(
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
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 785e09da80b..5651d362a72 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/delay_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/delay_node.cc
@@ -27,8 +27,8 @@
#include <memory>
+#include "third_party/blink/renderer/bindings/modules/v8/v8_delay_options.h"
#include "third_party/blink/renderer/modules/webaudio/audio_basic_processor_handler.h"
-#include "third_party/blink/renderer/modules/webaudio/delay_options.h"
#include "third_party/blink/renderer/modules/webaudio/delay_processor.h"
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -123,7 +123,7 @@ AudioParam* DelayNode::delayTime() {
return delay_time_;
}
-void DelayNode::Trace(blink::Visitor* visitor) {
+void DelayNode::Trace(Visitor* visitor) {
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 d5116784c52..e6d21497330 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
AudioParam* delayTime();
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/delay_node.idl b/chromium/third_party/blink/renderer/modules/webaudio/delay_node.idl
index 9dc6923f5c4..c30a4a03cef 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/delay_node.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/delay_node.idl
@@ -23,13 +23,10 @@
* DAMAGE.
*/
-// See https://webaudio.github.io/web-audio-api/#DelayNode
+// https://webaudio.github.io/web-audio-api/#DelayNode
[
- Exposed=Window,
- Constructor(BaseAudioContext context, optional DelayOptions options),
- RaisesException=Constructor,
- Measure
-]
-interface DelayNode : AudioNode {
+ Exposed=Window
+] interface DelayNode : AudioNode {
+ [RaisesException, Measure] constructor(BaseAudioContext context, optional DelayOptions options = {});
readonly attribute 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 d6f22ddda18..3ff3a896d66 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
@@ -25,9 +25,9 @@
#include "third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_dynamics_compressor_options.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_input.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_output.h"
-#include "third_party/blink/renderer/modules/webaudio/dynamics_compressor_options.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/bindings/exception_messages.h"
@@ -97,7 +97,8 @@ void DynamicsCompressorHandler::Process(uint32_t frames_to_process) {
dynamics_compressor_->SetParameterValue(DynamicsCompressor::kParamRelease,
release);
- dynamics_compressor_->Process(Input(0).Bus(), output_bus, frames_to_process);
+ scoped_refptr<AudioBus> input_bus = Input(0).Bus();
+ dynamics_compressor_->Process(input_bus.get(), output_bus, frames_to_process);
float reduction =
dynamics_compressor_->ParameterValue(DynamicsCompressor::kParamReduction);
@@ -272,7 +273,7 @@ DynamicsCompressorNode* DynamicsCompressorNode::Create(
return node;
}
-void DynamicsCompressorNode::Trace(blink::Visitor* visitor) {
+void DynamicsCompressorNode::Trace(Visitor* visitor) {
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 8e541004430..ed33b6f47e7 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
AudioParam* threshold() const;
AudioParam* knee() const;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.idl b/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.idl
index adcbed3867f..1d16e033cfe 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.idl
@@ -23,14 +23,11 @@
* DAMAGE.
*/
-// See https://webaudio.github.io/web-audio-api/#dynamicscompressornode
+// https://webaudio.github.io/web-audio-api/#dynamicscompressornode
[
- Exposed=Window,
- Constructor(BaseAudioContext context, optional DynamicsCompressorOptions options),
- RaisesException=Constructor,
- Measure
-]
-interface DynamicsCompressorNode : AudioNode {
+ Exposed=Window
+] interface DynamicsCompressorNode : AudioNode {
+ [RaisesException, Measure] constructor(BaseAudioContext context, optional DynamicsCompressorOptions options = {});
readonly attribute AudioParam threshold; // in Decibels
readonly attribute AudioParam knee; // in Decibels
readonly attribute AudioParam ratio; // unit-less
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node_test.cc b/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node_test.cc
index 8ecf679c994..2496b5f1213 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node_test.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node_test.cc
@@ -13,8 +13,9 @@ namespace blink {
TEST(DynamicsCompressorNodeTest, ProcessorLifetime) {
auto page = std::make_unique<DummyPageHolder>();
- OfflineAudioContext* context = OfflineAudioContext::Create(
- &page->GetDocument(), 2, 1, 48000, ASSERT_NO_EXCEPTION);
+ OfflineAudioContext* context =
+ OfflineAudioContext::Create(page->GetDocument().ToExecutionContext(), 2,
+ 1, 48000, ASSERT_NO_EXCEPTION);
DynamicsCompressorNode* node =
context->createDynamicsCompressor(ASSERT_NO_EXCEPTION);
DynamicsCompressorHandler& handler = node->GetDynamicsCompressorHandler();
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 dff0d772e06..acd0b5ba4fa 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/gain_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/gain_node.cc
@@ -23,12 +23,13 @@
* DAMAGE.
*/
+#include "third_party/blink/renderer/modules/webaudio/gain_node.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gain_options.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_input.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_output.h"
-#include "third_party/blink/renderer/modules/webaudio/gain_node.h"
-#include "third_party/blink/renderer/modules/webaudio/gain_options.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/instrumentation/tracing/trace_event.h"
namespace blink {
@@ -55,6 +56,9 @@ scoped_refptr<GainHandler> GainHandler::Create(AudioNode& node,
}
void GainHandler::Process(uint32_t frames_to_process) {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("webaudio.audionode"),
+ "GainHandler::Process");
+
// FIXME: for some cases there is a nice optimization to avoid processing
// here, and let the gain change happen in the summing junction input of the
// AudioNode we're connected to. Then we can avoid all of the following:
@@ -65,9 +69,11 @@ void GainHandler::Process(uint32_t frames_to_process) {
if (!IsInitialized() || !Input(0).IsConnected()) {
output_bus->Zero();
} else {
- AudioBus* input_bus = Input(0).Bus();
+ scoped_refptr<AudioBus> input_bus = Input(0).Bus();
+
+ bool is_sample_accurate = gain_->HasSampleAccurateValuesTimeline();
- if (gain_->HasSampleAccurateValues()) {
+ if (is_sample_accurate && gain_->IsAudioRate()) {
// Apply sample-accurate gain scaling for precise envelopes, grain
// windows, etc.
DCHECK_LE(frames_to_process, sample_accurate_gain_values_.size());
@@ -75,14 +81,19 @@ void GainHandler::Process(uint32_t frames_to_process) {
gain_->CalculateSampleAccurateValues(gain_values, frames_to_process);
output_bus->CopyWithSampleAccurateGainValuesFrom(*input_bus, gain_values,
frames_to_process);
+
+ return;
+ }
+
+ // The gain is not sample-accurate or not a-rate. In this case, we have a
+ // fixed gain for the render and just need to incorporate any inputs to the
+ // gain, if any.
+ float gain = is_sample_accurate ? gain_->FinalValue() : gain_->Value();
+
+ if (gain == 0) {
+ output_bus->Zero();
} else {
- // Apply the gain.
- if (gain_->Value() == 0) {
- // If the gain is 0, just zero the bus and set the silence hint.
- output_bus->Zero();
- } else {
- output_bus->CopyWithGainFrom(*input_bus, gain_->Value());
- }
+ output_bus->CopyWithGainFrom(*input_bus, gain);
}
}
}
@@ -168,7 +179,7 @@ AudioParam* GainNode::gain() const {
return gain_;
}
-void GainNode::Trace(blink::Visitor* visitor) {
+void GainNode::Trace(Visitor* visitor) {
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 e426a63e6b8..614181d180c 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
AudioParam* gain() const;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/gain_node.idl b/chromium/third_party/blink/renderer/modules/webaudio/gain_node.idl
index 78a68d69c36..e8193adb6d8 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/gain_node.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/gain_node.idl
@@ -23,14 +23,11 @@
* DAMAGE.
*/
-// See https://webaudio.github.io/web-audio-api/#gainnode
+// https://webaudio.github.io/web-audio-api/#gainnode
[
- Exposed=Window,
- Constructor(BaseAudioContext context, optional GainOptions options),
- RaisesException=Constructor,
- Measure
-]
-interface GainNode : AudioNode {
+ Exposed=Window
+] interface GainNode : AudioNode {
+ [RaisesException, Measure] constructor(BaseAudioContext context, optional GainOptions options = {});
// FIXME: eventually it will be interesting to remove the readonly restriction, but need to properly deal with thread safety here.
readonly attribute AudioParam gain;
};
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/idls.gni b/chromium/third_party/blink/renderer/modules/webaudio/idls.gni
new file mode 100644
index 00000000000..50e6ee361a0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webaudio/idls.gni
@@ -0,0 +1,75 @@
+# 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 = [
+ "analyser_node.idl",
+ "audio_buffer.idl",
+ "audio_buffer_source_node.idl",
+ "audio_context.idl",
+ "audio_destination_node.idl",
+ "audio_listener.idl",
+ "audio_node.idl",
+ "audio_param.idl",
+ "audio_param_map.idl",
+ "audio_processing_event.idl",
+ "audio_scheduled_source_node.idl",
+ "audio_worklet.idl",
+ "audio_worklet_global_scope.idl",
+ "audio_worklet_node.idl",
+ "audio_worklet_processor.idl",
+ "base_audio_context.idl",
+ "biquad_filter_node.idl",
+ "channel_merger_node.idl",
+ "channel_splitter_node.idl",
+ "constant_source_node.idl",
+ "convolver_node.idl",
+ "delay_node.idl",
+ "dynamics_compressor_node.idl",
+ "gain_node.idl",
+ "iir_filter_node.idl",
+ "media_element_audio_source_node.idl",
+ "media_stream_audio_destination_node.idl",
+ "media_stream_audio_source_node.idl",
+ "offline_audio_completion_event.idl",
+ "offline_audio_context.idl",
+ "oscillator_node.idl",
+ "panner_node.idl",
+ "periodic_wave.idl",
+ "script_processor_node.idl",
+ "stereo_panner_node.idl",
+ "wave_shaper_node.idl",
+]
+
+modules_dictionary_idl_files = [
+ "analyser_options.idl",
+ "audio_buffer_options.idl",
+ "audio_buffer_source_options.idl",
+ "audio_context_options.idl",
+ "audio_node_options.idl",
+ "audio_param_descriptor.idl",
+ "audio_processing_event_init.idl",
+ "audio_timestamp.idl",
+ "audio_worklet_node_options.idl",
+ "biquad_filter_options.idl",
+ "channel_merger_options.idl",
+ "channel_splitter_options.idl",
+ "constant_source_options.idl",
+ "convolver_options.idl",
+ "delay_options.idl",
+ "dynamics_compressor_options.idl",
+ "gain_options.idl",
+ "iir_filter_options.idl",
+ "media_element_audio_source_options.idl",
+ "media_stream_audio_source_options.idl",
+ "offline_audio_completion_event_init.idl",
+ "offline_audio_context_options.idl",
+ "oscillator_options.idl",
+ "panner_options.idl",
+ "periodic_wave_constraints.idl",
+ "periodic_wave_options.idl",
+ "stereo_panner_options.idl",
+ "wave_shaper_options.idl",
+]
+
+modules_testing_dependency_idl_files = [ "testing/internals_web_audio.idl" ]
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 7606049afa3..3eb0c113b97 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
@@ -6,13 +6,14 @@
#include <memory>
+#include "base/metrics/histogram_functions.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_iir_filter_options.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_output.h"
#include "third_party/blink/renderer/modules/webaudio/base_audio_context.h"
-#include "third_party/blink/renderer/modules/webaudio/iir_filter_options.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/instrumentation/histogram.h"
+#include "third_party/blink/renderer/platform/heap/heap.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"
@@ -116,10 +117,11 @@ void IIRFilterHandler::NotifyBadState() const {
if (!Context() || !Context()->GetExecutionContext())
return;
- Context()->GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning,
- NodeTypeName() + ": state is bad, probably due to unstable filter."));
+ Context()->GetExecutionContext()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning,
+ NodeTypeName() + ": state is bad, probably due to unstable filter."));
}
IIRFilterNode::IIRFilterNode(BaseAudioContext& context,
@@ -134,10 +136,8 @@ IIRFilterNode::IIRFilterNode(BaseAudioContext& context,
// Histogram of the IIRFilter order. createIIRFilter ensures that the length
// of |feedbackCoef| is in the range [1, IIRFilter::kMaxOrder + 1]. The order
// is one less than the length of this vector.
- DEFINE_STATIC_LOCAL(SparseHistogram, filter_order_histogram,
- ("WebAudio.IIRFilterNode.Order"));
-
- filter_order_histogram.Sample(feedback_coef.size() - 1);
+ base::UmaHistogramSparse("WebAudio.IIRFilterNode.Order",
+ feedback_coef.size() - 1);
}
IIRFilterNode* IIRFilterNode::Create(BaseAudioContext& context,
@@ -146,6 +146,11 @@ IIRFilterNode* IIRFilterNode::Create(BaseAudioContext& context,
ExceptionState& exception_state) {
DCHECK(IsMainThread());
+ // TODO(crbug.com/1055983): Remove this when the execution context validity
+ // check is not required in the AudioNode factory methods.
+ if (!context.CheckExecutionContextAndThrowIfNecessary(exception_state))
+ return nullptr;
+
if (feedback_coef.size() == 0 ||
(feedback_coef.size() > IIRFilter::kMaxOrder + 1)) {
exception_state.ThrowDOMException(
@@ -202,9 +207,10 @@ IIRFilterNode* IIRFilterNode::Create(BaseAudioContext& context,
}
message.Append(']');
- context.GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning, message.ToString()));
+ context.GetExecutionContext()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning, message.ToString()));
}
return MakeGarbageCollected<IIRFilterNode>(context, feedforward_coef,
@@ -225,7 +231,7 @@ IIRFilterNode* IIRFilterNode::Create(BaseAudioContext* context,
return node;
}
-void IIRFilterNode::Trace(blink::Visitor* visitor) {
+void IIRFilterNode::Trace(Visitor* visitor) {
AudioNode::Trace(visitor);
}
@@ -239,37 +245,39 @@ void IIRFilterNode::getFrequencyResponse(
NotShared<DOMFloat32Array> mag_response,
NotShared<DOMFloat32Array> phase_response,
ExceptionState& exception_state) {
- unsigned frequency_hz_length =
- frequency_hz.View()->deprecatedLengthAsUnsigned();
+ size_t frequency_hz_length = frequency_hz.View()->lengthAsSizeT();
// All the arrays must have the same length. Just verify that all
// the arrays have the same length as the |frequency_hz| array.
- if (mag_response.View()->deprecatedLengthAsUnsigned() !=
- frequency_hz_length) {
+ if (mag_response.View()->lengthAsSizeT() != frequency_hz_length) {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidAccessError,
ExceptionMessages::IndexOutsideRange(
- "magResponse length",
- mag_response.View()->deprecatedLengthAsUnsigned(),
+ "magResponse length", mag_response.View()->lengthAsSizeT(),
frequency_hz_length, ExceptionMessages::kInclusiveBound,
frequency_hz_length, ExceptionMessages::kInclusiveBound));
return;
}
- if (phase_response.View()->deprecatedLengthAsUnsigned() !=
- frequency_hz_length) {
+ if (phase_response.View()->lengthAsSizeT() != frequency_hz_length) {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidAccessError,
ExceptionMessages::IndexOutsideRange(
- "phaseResponse length",
- phase_response.View()->deprecatedLengthAsUnsigned(),
+ "phaseResponse length", phase_response.View()->lengthAsSizeT(),
frequency_hz_length, ExceptionMessages::kInclusiveBound,
frequency_hz_length, ExceptionMessages::kInclusiveBound));
return;
}
+ int frequency_hz_length_as_int;
+ if (!base::CheckedNumeric<int>(frequency_hz_length)
+ .AssignIfValid(&frequency_hz_length_as_int)) {
+ exception_state.ThrowRangeError(
+ "frequencyHz length exceeds the maximum supported length");
+ return;
+ }
GetIIRFilterProcessor()->GetFrequencyResponse(
- frequency_hz_length, frequency_hz.View()->Data(),
+ frequency_hz_length_as_int, frequency_hz.View()->Data(),
mag_response.View()->Data(), phase_response.View()->Data());
}
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 cc2c09b6d9d..1f9234be435 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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/iir_filter_node.idl b/chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.idl
index 6bd6e6d55b4..e39447cb26e 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.idl
@@ -4,12 +4,9 @@
// See https://webaudio.github.io/web-audio-api/#iirfilternode
[
- Exposed=Window,
- Constructor(BaseAudioContext context, IIRFilterOptions options),
- RaisesException=Constructor,
- Measure
-]
-interface IIRFilterNode : AudioNode {
+ Exposed=Window
+] interface IIRFilterNode : AudioNode {
+ [RaisesException, Measure] constructor(BaseAudioContext context, IIRFilterOptions options);
[RaisesException] void getFrequencyResponse(Float32Array frequencyHz,
Float32Array magResponse,
Float32Array phaseResponse);
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 5daea62af1a..8e947f093bb 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(blink::Visitor* visitor) {
+void InspectorHelperMixin::Trace(Visitor* visitor) {
visitor->Trace(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 533ac430ddc..5d679a895f3 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
@@ -74,20 +74,20 @@ void InspectorWebAudioAgent::Restore() {
Response InspectorWebAudioAgent::enable() {
if (enabled_.Get())
- return Response::OK();
+ return Response::Success();
enabled_.Set(true);
AudioGraphTracer* graph_tracer = AudioGraphTracer::FromPage(page_);
graph_tracer->SetInspectorAgent(this);
- return Response::OK();
+ return Response::Success();
}
Response InspectorWebAudioAgent::disable() {
if (!enabled_.Get())
- return Response::OK();
+ return Response::Success();
enabled_.Clear();
AudioGraphTracer* graph_tracer = AudioGraphTracer::FromPage(page_);
graph_tracer->SetInspectorAgent(nullptr);
- return Response::OK();
+ return Response::Success();
}
Response InspectorWebAudioAgent::getRealtimeData(
@@ -95,14 +95,14 @@ Response InspectorWebAudioAgent::getRealtimeData(
std::unique_ptr<ContextRealtimeData>* out_data) {
auto* const graph_tracer = AudioGraphTracer::FromPage(page_);
if (!enabled_.Get())
- return Response::Error("Enable agent first.");
+ return Response::ServerError("Enable agent first.");
BaseAudioContext* context = graph_tracer->GetContextById(contextId);
if (!context)
- return Response::Error("Cannot find BaseAudioContext with such id.");
+ return Response::ServerError("Cannot find BaseAudioContext with such id.");
if (!context->HasRealtimeConstraint()) {
- return Response::Error(
+ return Response::ServerError(
"ContextRealtimeData is only avaliable for an AudioContext.");
}
@@ -115,7 +115,7 @@ Response InspectorWebAudioAgent::getRealtimeData(
.setCallbackIntervalMean(metric.mean_callback_interval)
.setCallbackIntervalVariance(metric.variance_callback_interval)
.build();
- return Response::OK();
+ return Response::Success();
}
void InspectorWebAudioAgent::DidCreateBaseAudioContext(
@@ -243,7 +243,7 @@ InspectorWebAudioAgent::BuildProtocolContext(BaseAudioContext* context) {
.build();
}
-void InspectorWebAudioAgent::Trace(blink::Visitor* visitor) {
+void InspectorWebAudioAgent::Trace(Visitor* visitor) {
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 506299d6219..0b7afdae27f 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 98e4b184434..ef239b45c28 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
@@ -26,14 +26,15 @@
#include "third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.h"
#include "third_party/blink/public/platform/task_type.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_element_audio_source_options.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/modules/webaudio/audio_context.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_output.h"
-#include "third_party/blink/renderer/modules/webaudio/media_element_audio_source_options.h"
#include "third_party/blink/renderer/platform/audio/audio_utilities.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/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
@@ -137,8 +138,12 @@ void MediaElementAudioSourceHandler::SetFormat(uint32_t number_of_channels,
if (source_sample_rate != Context()->sampleRate()) {
double scale_factor = source_sample_rate / Context()->sampleRate();
- multi_channel_resampler_ = std::make_unique<MultiChannelResampler>(
- scale_factor, number_of_channels);
+ multi_channel_resampler_.reset(new MediaMultiChannelResampler(
+ number_of_channels, scale_factor,
+ audio_utilities::kRenderQuantumFrames,
+ CrossThreadBindRepeating(
+ &MediaElementAudioSourceHandler::ProvideResamplerInput,
+ CrossThreadUnretained(this))));
} else {
// Bypass resampling.
multi_channel_resampler_.reset();
@@ -162,14 +167,24 @@ bool MediaElementAudioSourceHandler::WouldTaintOrigin() {
void MediaElementAudioSourceHandler::PrintCorsMessage(const String& message) {
if (Context()->GetExecutionContext()) {
Context()->GetExecutionContext()->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kSecurity,
- mojom::ConsoleMessageLevel::kInfo,
- "MediaElementAudioSource outputs zeroes due to "
- "CORS access restrictions for " +
- message));
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kSecurity,
+ mojom::ConsoleMessageLevel::kInfo,
+ "MediaElementAudioSource outputs zeroes due to "
+ "CORS access restrictions for " +
+ message));
}
}
+void MediaElementAudioSourceHandler::ProvideResamplerInput(
+ int resampler_frame_delay,
+ AudioBus* dest) {
+ DCHECK(Context()->IsAudioThread());
+ DCHECK(MediaElement());
+ DCHECK(dest);
+ MediaElement()->GetAudioSourceProvider().ProvideInput(dest, dest->length());
+}
+
void MediaElementAudioSourceHandler::Process(uint32_t number_of_frames) {
AudioBus* output_bus = Output(0).Bus();
@@ -197,8 +212,7 @@ void MediaElementAudioSourceHandler::Process(uint32_t number_of_frames) {
// progress, even if we're going to output silence anyway.
if (multi_channel_resampler_.get()) {
DCHECK_NE(source_sample_rate_, Context()->sampleRate());
- multi_channel_resampler_->Process(&provider, output_bus,
- number_of_frames);
+ multi_channel_resampler_->Resample(number_of_frames, output_bus);
} else {
// Bypass the resampler completely if the source is at the context's
// sample-rate.
@@ -271,7 +285,7 @@ MediaElementAudioSourceNode* MediaElementAudioSourceNode::Create(
return Create(*context, *options->mediaElement(), exception_state);
}
-void MediaElementAudioSourceNode::Trace(blink::Visitor* visitor) {
+void MediaElementAudioSourceNode::Trace(Visitor* visitor) {
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 f81588cf780..322b61ed85e 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
@@ -32,7 +32,7 @@
#include "base/thread_annotations.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node.h"
#include "third_party/blink/renderer/platform/audio/audio_source_provider_client.h"
-#include "third_party/blink/renderer/platform/audio/multi_channel_resampler.h"
+#include "third_party/blink/renderer/platform/audio/media_multi_channel_resampler.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
@@ -86,6 +86,9 @@ class MediaElementAudioSourceHandler final : public AudioHandler {
// zeroes.
void PrintCorsMessage(const String& message);
+ // Provide input to the resampler (if used).
+ void ProvideResamplerInput(int resampler_frame_delay, AudioBus* dest);
+
// The HTMLMediaElement is held alive by MediaElementAudioSourceNode which is
// an AudioNode. AudioNode uses pre-finalizers to dispose the handler, so
// holding a weak reference is ok here and will not interfer with garbage
@@ -99,7 +102,7 @@ class MediaElementAudioSourceHandler final : public AudioHandler {
unsigned source_number_of_channels_;
double source_sample_rate_;
- std::unique_ptr<MultiChannelResampler> multi_channel_resampler_;
+ std::unique_ptr<MediaMultiChannelResampler> multi_channel_resampler_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
@@ -124,7 +127,7 @@ class MediaElementAudioSourceNode final : public AudioNode,
MediaElementAudioSourceNode(AudioContext&, HTMLMediaElement&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
MediaElementAudioSourceHandler& GetMediaElementAudioSourceHandler() const;
HTMLMediaElement* mediaElement() const;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.idl b/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.idl
index 22552cc86a8..1477fe618fc 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.idl
@@ -25,11 +25,8 @@
// See https://webaudio.github.io/web-audio-api/#mediaelementaudiosourcenode
[
- Exposed=Window,
- Constructor(AudioContext context, MediaElementAudioSourceOptions options),
- RaisesException=Constructor,
- Measure
-]
-interface MediaElementAudioSourceNode : AudioNode {
+ Exposed=Window
+] interface MediaElementAudioSourceNode : AudioNode {
+ [RaisesException, Measure] constructor(AudioContext context, MediaElementAudioSourceOptions options);
[SameObject] readonly attribute HTMLMediaElement mediaElement;
};
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 9faa5bfb81b..f6870b858ff 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
@@ -25,15 +25,16 @@
#include "third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.h"
-#include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_audio_node_options.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_utils.h"
#include "third_party/blink/renderer/modules/webaudio/audio_context.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_input.h"
-#include "third_party/blink/renderer/modules/webaudio/audio_node_options.h"
#include "third_party/blink/renderer/modules/webaudio/base_audio_context.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/heap/heap.h"
+#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_platform.h"
#include "third_party/blink/renderer/platform/wtf/uuid.h"
namespace blink {
@@ -80,6 +81,9 @@ MediaStreamAudioDestinationHandler::~MediaStreamAudioDestinationHandler() {
}
void MediaStreamAudioDestinationHandler::Process(uint32_t number_of_frames) {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("webaudio.audionode"),
+ "MediaStreamAudioDestinationHandler::Process");
+
// Conform the input bus into the internal mix bus, which represents
// MediaStreamDestination's channel count.
@@ -207,6 +211,11 @@ MediaStreamAudioDestinationNode* MediaStreamAudioDestinationNode::Create(
ExceptionState& exception_state) {
DCHECK(IsMainThread());
+ // TODO(crbug.com/1055983): Remove this when the execution context validity
+ // check is not required in the AudioNode factory methods.
+ if (!context.CheckExecutionContextAndThrowIfNecessary(exception_state))
+ return nullptr;
+
return MakeGarbageCollected<MediaStreamAudioDestinationNode>(
context, number_of_channels);
}
@@ -217,7 +226,9 @@ MediaStreamAudioDestinationNode* MediaStreamAudioDestinationNode::Create(
ExceptionState& exception_state) {
DCHECK(IsMainThread());
- // Default to stereo; |options| will update it approriately if needed.
+ if (!context->CheckExecutionContextAndThrowIfNecessary(exception_state))
+ return nullptr;
+ // Default to stereo; |options| will update it appropriately if needed.
MediaStreamAudioDestinationNode* node =
MakeGarbageCollected<MediaStreamAudioDestinationNode>(*context, 2);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.idl b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.idl
index c291a7eaea7..833a9b4d478 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.idl
@@ -23,13 +23,10 @@
* DAMAGE.
*/
-// See https://webaudio.github.io/web-audio-api/#mediastreamaudiodestinationnode
+// https://webaudio.github.io/web-audio-api/#mediastreamaudiodestinationnode
[
- Exposed=Window,
- Constructor(AudioContext context, optional AudioNodeOptions options),
- RaisesException=Constructor,
- Measure
-]
-interface MediaStreamAudioDestinationNode : AudioNode {
+ Exposed=Window
+] interface MediaStreamAudioDestinationNode : AudioNode {
+ [RaisesException, Measure] constructor(AudioContext context, optional AudioNodeOptions options = {});
readonly attribute MediaStream stream;
};
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 af43a3ec809..253165adabe 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
@@ -26,10 +26,11 @@
#include "third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.h"
#include <memory>
+#include "third_party/blink/renderer/bindings/modules/v8/v8_media_stream_audio_source_options.h"
#include "third_party/blink/renderer/modules/webaudio/audio_context.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_output.h"
-#include "third_party/blink/renderer/modules/webaudio/media_stream_audio_source_options.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
namespace blink {
@@ -91,6 +92,9 @@ void MediaStreamAudioSourceHandler::SetFormat(uint32_t number_of_channels,
}
void MediaStreamAudioSourceHandler::Process(uint32_t number_of_frames) {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("webaudio.audionode"),
+ "MediaStreamAudioSourceHandler::Process");
+
AudioBus* output_bus = Output(0).Bus();
if (!GetAudioSourceProvider()) {
@@ -135,6 +139,11 @@ MediaStreamAudioSourceNode* MediaStreamAudioSourceNode::Create(
ExceptionState& exception_state) {
DCHECK(IsMainThread());
+ // TODO(crbug.com/1055983): Remove this when the execution context validity
+ // check is not required in the AudioNode factory methods.
+ if (!context.CheckExecutionContextAndThrowIfNecessary(exception_state))
+ return nullptr;
+
MediaStreamTrackVector audio_tracks = media_stream.getAudioTracks();
if (audio_tracks.IsEmpty()) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
@@ -176,7 +185,7 @@ MediaStreamAudioSourceNode* MediaStreamAudioSourceNode::Create(
return Create(*context, *options->mediaStream(), exception_state);
}
-void MediaStreamAudioSourceNode::Trace(blink::Visitor* visitor) {
+void MediaStreamAudioSourceNode::Trace(Visitor* visitor) {
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 453e0f37469..ac671165da5 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
MediaStream* getMediaStream() const;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.idl b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.idl
index 654b6e057ad..c6256915806 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.idl
@@ -25,11 +25,8 @@
// See https://webaudio.github.io/web-audio-api/#mediastreamaudiosourcenode
[
- Constructor(AudioContext context, MediaStreamAudioSourceOptions options),
- RaisesException=Constructor,
- Measure,
ActiveScriptWrappable
-]
-interface MediaStreamAudioSourceNode : AudioNode {
+] interface MediaStreamAudioSourceNode : AudioNode {
+ [RaisesException, Measure] constructor(AudioContext context, MediaStreamAudioSourceOptions options);
[SameObject, ImplementedAs=getMediaStream] readonly attribute MediaStream mediaStream;
};
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 9b33de63654..167bf5bab30 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(blink::Visitor* visitor) {
+void OfflineAudioCompletionEvent::Trace(Visitor* visitor) {
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 f897a794725..cdf26cd1f12 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
@@ -27,9 +27,9 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_OFFLINE_AUDIO_COMPLETION_EVENT_H_
#include "base/memory/scoped_refptr.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_offline_audio_completion_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/webaudio/audio_buffer.h"
-#include "third_party/blink/renderer/modules/webaudio/offline_audio_completion_event_init.h"
namespace blink {
@@ -56,7 +56,7 @@ class OfflineAudioCompletionEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<AudioBuffer> rendered_buffer_;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.idl b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.idl
index 504d8fe2894..91ddcc92e3f 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.idl
@@ -25,9 +25,8 @@
// See https://webaudio.github.io/web-audio-api/#offlineaudiocompletionevent
[
- Exposed=Window,
- Constructor(DOMString type, OfflineAudioCompletionEventInit eventInitDict)
-]
-interface OfflineAudioCompletionEvent : Event {
+ Exposed=Window
+] interface OfflineAudioCompletionEvent : Event {
+ constructor(DOMString type, OfflineAudioCompletionEventInit eventInitDict);
readonly attribute AudioBuffer renderedBuffer;
};
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 a505b1e4a10..eeb930b4b20 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
@@ -25,21 +25,21 @@
#include "third_party/blink/renderer/modules/webaudio/offline_audio_context.h"
+#include "base/metrics/histogram_functions.h"
#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_offline_audio_context_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/modules/webaudio/audio_listener.h"
#include "third_party/blink/renderer/modules/webaudio/deferred_task_handler.h"
#include "third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.h"
-#include "third_party/blink/renderer/modules/webaudio/offline_audio_context_options.h"
#include "third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.h"
#include "third_party/blink/renderer/platform/audio/audio_utilities.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/script_state.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/wtf/cross_thread_functional.h"
namespace blink {
@@ -51,7 +51,7 @@ OfflineAudioContext* OfflineAudioContext::Create(
float sample_rate,
ExceptionState& exception_state) {
// FIXME: add support for workers.
- auto* document = DynamicTo<Document>(context);
+ auto* document = Document::DynamicFrom(context);
if (!document) {
exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
"Workers are not supported.");
@@ -107,24 +107,20 @@ OfflineAudioContext* OfflineAudioContext::Create(
fprintf(stderr, "[%16p]: OfflineAudioContext::OfflineAudioContext()\n",
audio_context);
#endif
- DEFINE_STATIC_LOCAL(SparseHistogram, offline_context_channel_count_histogram,
- ("WebAudio.OfflineAudioContext.ChannelCount"));
+ base::UmaHistogramSparse("WebAudio.OfflineAudioContext.ChannelCount",
+ number_of_channels);
// Arbitrarly limit the maximum length to 1 million frames (about 20 sec
// at 48kHz). The number of buckets is fairly arbitrary.
- DEFINE_STATIC_LOCAL(CustomCountHistogram, offline_context_length_histogram,
- ("WebAudio.OfflineAudioContext.Length", 1, 1000000, 50));
+ base::UmaHistogramCounts1M("WebAudio.OfflineAudioContext.Length",
+ number_of_frames);
// The limits are the min and max AudioBuffer sample rates currently
// supported. We use explicit values here instead of
// audio_utilities::minAudioBufferSampleRate() and
// audio_utilities::maxAudioBufferSampleRate(). The number of buckets is
// fairly arbitrary.
- DEFINE_STATIC_LOCAL(
- CustomCountHistogram, offline_context_sample_rate_histogram,
- ("WebAudio.OfflineAudioContext.SampleRate384kHz", 3000, 384000, 50));
-
- offline_context_channel_count_histogram.Sample(number_of_channels);
- offline_context_length_histogram.Count(number_of_frames);
- offline_context_sample_rate_histogram.Count(sample_rate);
+ base::UmaHistogramCustomCounts(
+ "WebAudio.OfflineAudioContext.SampleRate384kHz", sample_rate, 3000,
+ 384000, 50);
return audio_context;
}
@@ -160,14 +156,15 @@ OfflineAudioContext::~OfflineAudioContext() {
#endif
}
-void OfflineAudioContext::Trace(blink::Visitor* visitor) {
+void OfflineAudioContext::Trace(Visitor* visitor) {
visitor->Trace(complete_resolver_);
visitor->Trace(scheduled_suspends_);
BaseAudioContext::Trace(visitor);
}
ScriptPromise OfflineAudioContext::startOfflineRendering(
- ScriptState* script_state) {
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
DCHECK(IsMainThread());
// Calling close() on an OfflineAudioContext is not supported/allowed,
@@ -175,29 +172,28 @@ ScriptPromise OfflineAudioContext::startOfflineRendering(
//
// See: crbug.com/435867
if (IsContextClosed()) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "cannot call startRendering on an "
- "OfflineAudioContext in a stopped state."));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "cannot call startRendering on an OfflineAudioContext in a stopped "
+ "state.");
+ return ScriptPromise();
}
// If the context is not in the suspended state (i.e. running), reject the
// promise.
if (ContextState() != AudioContextState::kSuspended) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "cannot startRendering when an OfflineAudioContext is " + state()));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "cannot startRendering when an OfflineAudioContext is " + state());
+ return ScriptPromise();
}
// Can't call startRendering more than once. Return a rejected promise now.
if (is_rendering_started_) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError,
- "cannot call startRendering more than once"));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "cannot call startRendering more than once");
+ return ScriptPromise();
}
DCHECK(!is_rendering_started_);
@@ -213,13 +209,13 @@ ScriptPromise OfflineAudioContext::startOfflineRendering(
number_of_channels, total_render_frames_, sample_rate);
if (!render_target) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotSupportedError,
- "startRendering failed to create AudioBuffer(" +
- String::Number(number_of_channels) + ", " +
- String::Number(total_render_frames_) + ", " +
- String::Number(sample_rate) + ")"));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotSupportedError,
+ "startRendering failed to create AudioBuffer(" +
+ String::Number(number_of_channels) + ", " +
+ String::Number(total_render_frames_) + ", " +
+ String::Number(sample_rate) + ")");
+ return ScriptPromise();
}
// Start rendering and return the promise.
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 f35b5363f84..5022c96be5f 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,11 +57,11 @@ class MODULES_EXPORT OfflineAudioContext final : public BaseAudioContext {
ExceptionState&);
~OfflineAudioContext() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
uint32_t length() const { return total_render_frames_; }
- ScriptPromise startOfflineRendering(ScriptState*);
+ ScriptPromise startOfflineRendering(ScriptState*, ExceptionState&);
ScriptPromise suspendContext(ScriptState*, double);
ScriptPromise resumeContext(ScriptState*);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.idl b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.idl
index 7832c125ea5..d2b4c185a79 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.idl
@@ -25,17 +25,14 @@
// See https://webaudio.github.io/web-audio-api/#OfflineAudioContext
[
- Exposed=Window,
- Constructor(unsigned long numberOfChannels, unsigned long numberOfFrames, float sampleRate),
- Constructor(OfflineAudioContextOptions options),
- ConstructorCallWith=ExecutionContext,
- RaisesException=Constructor,
- Measure
+ Exposed=Window
] interface OfflineAudioContext : BaseAudioContext {
+ [CallWith=ExecutionContext, RaisesException, Measure] constructor(unsigned long numberOfChannels, unsigned long numberOfFrames, float sampleRate);
+ [CallWith=ExecutionContext, RaisesException, Measure] constructor(OfflineAudioContextOptions options);
// Offline rendering
attribute EventHandler oncomplete;
readonly attribute unsigned long length;
- [CallWith=ScriptState, ImplementedAs=startOfflineRendering, MeasureAs=OfflineAudioContextStartRendering] Promise<AudioBuffer> startRendering();
+ [CallWith=ScriptState, RaisesException, ImplementedAs=startOfflineRendering, MeasureAs=OfflineAudioContextStartRendering] Promise<AudioBuffer> startRendering();
[CallWith=ScriptState, ImplementedAs=suspendContext, MeasureAs=OfflineAudioContextSuspend] Promise<void> suspend(double suspendTime);
[MeasureAs=OfflineAudioContextResume, CallWith=ScriptState, ImplementedAs=resumeContext] Promise<void> resume();
};
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 71f8855b94b..ec610b99c67 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
@@ -293,32 +293,25 @@ bool OfflineAudioDestinationHandler::RenderIfNotSuspended(
return true;
}
- {
- MutexTryLocker try_locker(Context()->GetTearDownMutex());
- if (try_locker.Locked()) {
- DCHECK_GE(NumberOfInputs(), 1u);
-
- // This will cause the node(s) connected to us to process, which in turn
- // will pull on their input(s), all the way backwards through the
- // rendering graph.
- AudioBus* rendered_bus = Input(0).Pull(destination_bus, number_of_frames);
-
- if (!rendered_bus) {
- destination_bus->Zero();
- } else if (rendered_bus != destination_bus) {
- // in-place processing was not possible - so copy
- destination_bus->CopyFrom(*rendered_bus);
- }
- } else {
- destination_bus->Zero();
- }
+ DCHECK_GE(NumberOfInputs(), 1u);
- // Process nodes which need a little extra help because they are not
- // connected to anything, but still need to process.
- Context()->GetDeferredTaskHandler().ProcessAutomaticPullNodes(
- number_of_frames);
+ // This will cause the node(s) connected to us to process, which in turn will
+ // pull on their input(s), all the way backwards through the rendering graph.
+ scoped_refptr<AudioBus> rendered_bus =
+ Input(0).Pull(destination_bus, number_of_frames);
+
+ if (!rendered_bus) {
+ destination_bus->Zero();
+ } else if (rendered_bus != destination_bus) {
+ // in-place processing was not possible - so copy
+ destination_bus->CopyFrom(*rendered_bus);
}
+ // Process nodes which need a little extra help because they are not connected
+ // to anything, but still need to process.
+ Context()->GetDeferredTaskHandler().ProcessAutomaticPullNodes(
+ number_of_frames);
+
// Let the context take care of any business at the end of each render
// quantum.
Context()->HandlePostRenderTasks();
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 da282b553eb..8e86bd7b267 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.cc
@@ -563,7 +563,7 @@ OscillatorNode* OscillatorNode::Create(BaseAudioContext* context,
return node;
}
-void OscillatorNode::Trace(blink::Visitor* visitor) {
+void OscillatorNode::Trace(Visitor* visitor) {
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 4417cfe4343..e763c404e0a 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.h
@@ -27,9 +27,9 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_OSCILLATOR_NODE_H_
#include "base/memory/scoped_refptr.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_oscillator_options.h"
#include "third_party/blink/renderer/modules/webaudio/audio_param.h"
#include "third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.h"
-#include "third_party/blink/renderer/modules/webaudio/oscillator_options.h"
#include "third_party/blink/renderer/platform/audio/audio_bus.h"
#include "third_party/blink/renderer/platform/wtf/threading.h"
@@ -125,7 +125,7 @@ class OscillatorNode final : public AudioScheduledSourceNode {
OscillatorNode(BaseAudioContext&,
const String& oscillator_type,
PeriodicWave* wave_table);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
String type() const;
void setType(const String&, ExceptionState&);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.idl b/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.idl
index 328f0429b4f..8f0685b96c6 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.idl
@@ -23,7 +23,9 @@
* DAMAGE.
*/
-// See https://webaudio.github.io/web-audio-api/#oscillatornode
+// https://webaudio.github.io/web-audio-api/#oscillatornode
+
+// https://webaudio.github.io/web-audio-api/#enumdef-oscillatortype
enum OscillatorType {
"sine",
"square",
@@ -34,12 +36,9 @@ enum OscillatorType {
// OscillatorNode is an audio generator of periodic waveforms.
[
- Exposed=Window,
- Constructor(BaseAudioContext context, optional OscillatorOptions options),
- RaisesException=Constructor,
- Measure
-]
-interface OscillatorNode : AudioScheduledSourceNode {
+ Exposed=Window
+] interface OscillatorNode : AudioScheduledSourceNode {
+ [RaisesException, Measure] constructor(BaseAudioContext context, optional OscillatorOptions options = {});
[RaisesException=Setter] attribute OscillatorType type;
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 a10eb9fbb03..e1e46d93dcb 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/panner_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/panner_node.cc
@@ -25,16 +25,17 @@
#include "third_party/blink/renderer/modules/webaudio/panner_node.h"
+#include "base/metrics/histogram_functions.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_panner_options.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_input.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_output.h"
#include "third_party/blink/renderer/modules/webaudio/base_audio_context.h"
-#include "third_party/blink/renderer/modules/webaudio/panner_options.h"
#include "third_party/blink/renderer/platform/audio/hrtf_panner.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/instrumentation/histogram.h"
+#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
namespace blink {
@@ -163,6 +164,9 @@ void PannerHandler::ProcessIfNecessary(uint32_t frames_to_process) {
}
void PannerHandler::Process(uint32_t frames_to_process) {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("webaudio.audionode"),
+ "PannerHandler::Process");
+
AudioBus* destination = Output(0).Bus();
if (!IsInitialized() || !panner_.get()) {
@@ -170,7 +174,7 @@ void PannerHandler::Process(uint32_t frames_to_process) {
return;
}
- AudioBus* source = Input(0).Bus();
+ scoped_refptr<AudioBus> source = Input(0).Bus();
if (!source) {
destination->Zero();
return;
@@ -181,7 +185,7 @@ void PannerHandler::Process(uint32_t frames_to_process) {
if (try_listener_locker.Locked()) {
if (!Context()->HasRealtimeConstraint() &&
- panning_model_ == Panner::kPanningModelHRTF) {
+ panning_model_ == Panner::PanningModel::kHRTF) {
// For an OfflineAudioContext, we need to make sure the HRTFDatabase
// is loaded before proceeding. For realtime contexts, we don't
// have to wait. The HRTF panner handles that case itself.
@@ -194,7 +198,7 @@ void PannerHandler::Process(uint32_t frames_to_process) {
// But in general we can't because something may scheduled to start in the
// middle of the rendering quantum. On the other hand, the audible effect
// may be small enough that we can afford to do this optimization.
- ProcessSampleAccurateValues(destination, source, frames_to_process);
+ ProcessSampleAccurateValues(destination, source.get(), frames_to_process);
} else {
// Apply the panning effect.
double azimuth;
@@ -206,8 +210,8 @@ void PannerHandler::Process(uint32_t frames_to_process) {
AzimuthElevation(&azimuth, &elevation);
- panner_->Pan(azimuth, elevation, source, destination, frames_to_process,
- InternalChannelInterpretation());
+ panner_->Pan(azimuth, elevation, source.get(), destination,
+ frames_to_process, InternalChannelInterpretation());
// Get the distance and cone gain.
float total_gain = DistanceConeGain();
@@ -354,34 +358,31 @@ AudioListener* PannerHandler::Listener() {
String PannerHandler::PanningModel() const {
switch (panning_model_) {
- case Panner::kPanningModelEqualPower:
+ case Panner::PanningModel::kEqualPower:
return "equalpower";
- case Panner::kPanningModelHRTF:
+ case Panner::PanningModel::kHRTF:
return "HRTF";
- default:
- NOTREACHED();
- return "equalpower";
}
+ NOTREACHED();
+ return "equalpower";
}
void PannerHandler::SetPanningModel(const String& model) {
// WebIDL should guarantee that we are never called with an invalid string
// for the model.
if (model == "equalpower")
- SetPanningModel(Panner::kPanningModelEqualPower);
+ SetPanningModel(Panner::PanningModel::kEqualPower);
else if (model == "HRTF")
- SetPanningModel(Panner::kPanningModelHRTF);
+ SetPanningModel(Panner::PanningModel::kHRTF);
else
NOTREACHED();
}
// This method should only be called from setPanningModel(const String&)!
-bool PannerHandler::SetPanningModel(unsigned model) {
- DEFINE_STATIC_LOCAL(EnumerationHistogram, panning_model_histogram,
- ("WebAudio.PannerNode.PanningModel", 2));
- panning_model_histogram.Count(model);
+bool PannerHandler::SetPanningModel(Panner::PanningModel model) {
+ base::UmaHistogramEnumeration("WebAudio.PannerNode.PanningModel", model);
- if (model == Panner::kPanningModelHRTF) {
+ if (model == Panner::PanningModel::kHRTF) {
// Load the HRTF database asynchronously so we don't block the
// Javascript thread while creating the HRTF database. It's ok to call
// this multiple times; we won't be constantly loading the database over
@@ -949,7 +950,7 @@ void PannerNode::setConeOuterGain(double gain,
GetPannerHandler().SetConeOuterGain(gain);
}
-void PannerNode::Trace(blink::Visitor* visitor) {
+void PannerNode::Trace(Visitor* visitor) {
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 8fe0ec50822..e74f9d054da 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/panner_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/panner_node.h
@@ -135,7 +135,7 @@ class PannerHandler final : public AudioHandler {
// BaseAudioContext's listener
AudioListener* Listener();
- bool SetPanningModel(unsigned); // Returns true on success.
+ bool SetPanningModel(Panner::PanningModel); // Returns true on success.
bool SetDistanceModel(unsigned); // Returns true on success.
void CalculateAzimuthElevation(double* out_azimuth,
@@ -160,7 +160,7 @@ class PannerHandler final : public AudioHandler {
// AudioListener is held alive by PannerNode.
CrossThreadWeakPersistent<AudioListener> listener_;
std::unique_ptr<Panner> panner_;
- unsigned panning_model_;
+ Panner::PanningModel panning_model_;
unsigned distance_model_;
bool is_azimuth_elevation_dirty_;
@@ -216,7 +216,7 @@ class PannerNode final : public AudioNode {
PannerNode(BaseAudioContext&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// Uses a 3D cartesian coordinate system
AudioParam* positionX() const { return position_x_; }
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/panner_node.idl b/chromium/third_party/blink/renderer/modules/webaudio/panner_node.idl
index 4a0d7097fe3..1ac9b00a9aa 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/panner_node.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/panner_node.idl
@@ -23,7 +23,7 @@
* DAMAGE.
*/
-// See https://webaudio.github.io/web-audio-api/#pannernode
+// https://webaudio.github.io/web-audio-api/#pannernode
enum PanningModelType {
"equalpower",
"HRTF"
@@ -36,11 +36,9 @@ enum DistanceModelType {
};
[
- Exposed=Window,
- Constructor(BaseAudioContext context, optional PannerOptions options),
- RaisesException=Constructor,
- Measure
+ Exposed=Window
] interface PannerNode : AudioNode {
+ [RaisesException, Measure] constructor(BaseAudioContext context, optional PannerOptions options = {});
// Default model for stereo is equalpower.
attribute PanningModelType panningModel;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/periodic_wave.cc b/chromium/third_party/blink/renderer/modules/webaudio/periodic_wave.cc
index b8a64742a0a..e0efd39759e 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/periodic_wave.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/periodic_wave.cc
@@ -29,10 +29,10 @@
#include <algorithm>
#include <memory>
+#include "third_party/blink/renderer/bindings/modules/v8/v8_periodic_wave_options.h"
#include "third_party/blink/renderer/modules/webaudio/base_audio_context.h"
#include "third_party/blink/renderer/modules/webaudio/oscillator_node.h"
#include "third_party/blink/renderer/modules/webaudio/periodic_wave.h"
-#include "third_party/blink/renderer/modules/webaudio/periodic_wave_options.h"
#include "third_party/blink/renderer/platform/audio/fft_frame.h"
#include "third_party/blink/renderer/platform/audio/vector_math.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -241,17 +241,19 @@ void PeriodicWave::CreateBandLimitedTables(const float* real_data,
for (unsigned range_index = 0; range_index < NumberOfRanges();
++range_index) {
// This FFTFrame is used to cull partials (represented by frequency bins).
- float* real_p = frame.RealData();
- float* imag_p = frame.ImagData();
+ AudioFloatArray& real = frame.RealData();
+ DCHECK_GE(real.size(), number_of_components);
+ AudioFloatArray& imag = frame.ImagData();
+ DCHECK_GE(imag.size(), number_of_components);
// Copy from loaded frequency data and generate the complex conjugate
// because of the way the inverse FFT is defined versus the values in the
// arrays. Need to scale the data by fftSize to remove the scaling that the
// inverse IFFT would do.
float scale = fft_size;
- vector_math::Vsmul(real_data, 1, &scale, real_p, 1, number_of_components);
+ vector_math::Vsmul(real_data, 1, &scale, real.Data(), 1, number_of_components);
scale = -scale;
- vector_math::Vsmul(imag_data, 1, &scale, imag_p, 1, number_of_components);
+ vector_math::Vsmul(imag_data, 1, &scale, imag.Data(), 1, number_of_components);
// Find the starting bin where we should start culling. We need to clear
// out the highest frequencies to band-limit the waveform.
@@ -262,13 +264,13 @@ void PeriodicWave::CreateBandLimitedTables(const float* real_data,
// pitch range.
for (i = std::min(number_of_components, number_of_partials + 1);
i < half_size; ++i) {
- real_p[i] = 0;
- imag_p[i] = 0;
+ real[i] = 0;
+ imag[i] = 0;
}
// Clear packed-nyquist and any DC-offset.
- real_p[0] = 0;
- imag_p[0] = 0;
+ real[0] = 0;
+ imag[0] = 0;
// Create the band-limited table.
unsigned wave_size = PeriodicWaveSize();
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/periodic_wave.idl b/chromium/third_party/blink/renderer/modules/webaudio/periodic_wave.idl
index 6dcbc504c11..521b2be5c27 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/periodic_wave.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/periodic_wave.idl
@@ -24,12 +24,9 @@
*/
// PeriodicWave represents a periodic audio waveform given by its Fourier coefficients.
-// See https://webaudio.github.io/web-audio-api/#periodicwave
+// https://webaudio.github.io/web-audio-api/#periodicwave
[
- Exposed=Window,
- Constructor(BaseAudioContext context, optional PeriodicWaveOptions options),
- RaisesException=Constructor,
- Measure
-]
-interface PeriodicWave {
+ Exposed=Window
+] interface PeriodicWave {
+ [RaisesException, Measure] constructor(BaseAudioContext context, optional PeriodicWaveOptions options = {});
};
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc b/chromium/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc
index 5415becfb49..325f61e14ac 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc
@@ -154,11 +154,11 @@ void RealtimeAnalyser::DoFFTAnalysis() {
// Do the analysis.
analysis_frame_->DoFFT(temp_p);
- const float* real_p = analysis_frame_->RealData();
- float* imag_p = analysis_frame_->ImagData();
+ const AudioFloatArray& real = analysis_frame_->RealData();
+ AudioFloatArray& imag = analysis_frame_->ImagData();
// Blow away the packed nyquist component.
- imag_p[0] = 0;
+ imag[0] = 0;
// Normalize so than an input sine wave at 0dBfs registers as 0dBfs (undo FFT
// scaling factor).
@@ -174,8 +174,12 @@ void RealtimeAnalyser::DoFFTAnalysis() {
// previous result.
float* destination = MagnitudeBuffer().Data();
size_t n = MagnitudeBuffer().size();
+ DCHECK_GE(real.size(), n);
+ const float* real_p_data = real.Data();
+ DCHECK_GE(imag.size(), n);
+ const float* imag_p_data = imag.Data();
for (size_t i = 0; i < n; ++i) {
- std::complex<double> c(real_p[i], imag_p[i]);
+ std::complex<double> c(real_p_data[i], imag_p_data[i]);
double scalar_magnitude = abs(c) * magnitude_scale;
destination[i] = float(k * destination[i] + (1 - k) * scalar_magnitude);
}
@@ -273,8 +277,8 @@ void RealtimeAnalyser::GetFloatTimeDomainData(
DCHECK(destination_array);
unsigned fft_size = this->FftSize();
- size_t len =
- std::min(fft_size, destination_array->deprecatedLengthAsUnsigned());
+ size_t len = std::min(static_cast<size_t>(fft_size),
+ destination_array->lengthAsSizeT());
if (len > 0) {
DCHECK_EQ(input_buffer_.size(), kInputBufferSize);
DCHECK_GT(input_buffer_.size(), fft_size);
@@ -300,8 +304,8 @@ void RealtimeAnalyser::GetByteTimeDomainData(DOMUint8Array* destination_array) {
DCHECK(destination_array);
unsigned fft_size = this->FftSize();
- size_t len =
- std::min(fft_size, destination_array->deprecatedLengthAsUnsigned());
+ size_t len = std::min(static_cast<size_t>(fft_size),
+ destination_array->lengthAsSizeT());
if (len > 0) {
DCHECK_EQ(input_buffer_.size(), kInputBufferSize);
DCHECK_GT(input_buffer_.size(), fft_size);
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.cc
index 58caf2b93a0..743cddb2d4b 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.cc
@@ -198,34 +198,30 @@ void RealtimeAudioDestinationHandler::Render(
// Only pull on the audio graph if we have not stopped the destination. It
// takes time for the destination to stop, but we want to stop pulling before
// the destination has actually stopped.
- {
- MutexTryLocker try_locker(context->GetTearDownMutex());
- if (try_locker.Locked() && IsPullingAudioGraphAllowed()) {
- // Renders the graph by pulling all the inputs to this node. This will
- // in turn pull on their inputs, all the way backwards through the graph.
- AudioBus* rendered_bus = Input(0).Pull(destination_bus, number_of_frames);
-
- DCHECK(rendered_bus);
- if (!rendered_bus) {
- // AudioNodeInput might be in the middle of destruction. Then the
- // internal summing bus will return as nullptr. Then zero out the
- // output.
- destination_bus->Zero();
- } else if (rendered_bus != destination_bus) {
- // In-place processing was not possible. Copy the rendererd result to
- // the given |destination_bus| buffer.
- destination_bus->CopyFrom(*rendered_bus);
- }
- } else {
+ if (IsPullingAudioGraphAllowed()) {
+ // Renders the graph by pulling all the inputs to this node. This will in
+ // turn pull on their inputs, all the way backwards through the graph.
+ scoped_refptr<AudioBus> rendered_bus =
+ Input(0).Pull(destination_bus, number_of_frames);
+
+ DCHECK(rendered_bus);
+ if (!rendered_bus) {
+ // AudioNodeInput might be in the middle of destruction. Then the internal
+ // summing bus will return as nullptr. Then zero out the output.
destination_bus->Zero();
+ } else if (rendered_bus != destination_bus) {
+ // In-place processing was not possible. Copy the rendered result to the
+ // given |destination_bus| buffer.
+ destination_bus->CopyFrom(*rendered_bus);
}
-
- // Processes "automatic" nodes that are not connected to anything. This can
- // be done after copying because it does not affect the rendered result.
- context->GetDeferredTaskHandler().ProcessAutomaticPullNodes(
- number_of_frames);
+ } else {
+ destination_bus->Zero();
}
+ // Processes "automatic" nodes that are not connected to anything. This can
+ // be done after copying because it does not affect the rendered result.
+ context->GetDeferredTaskHandler().ProcessAutomaticPullNodes(number_of_frames);
+
context->HandlePostRenderTasks();
context->HandleAudibility(destination_bus);
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 db3180801e5..33d5b11733d 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
@@ -119,7 +119,7 @@ void ScriptProcessorHandler::Process(uint32_t frames_to_process) {
// code is the consumer of inputBuffer and the producer for outputBuffer.
// Get input and output busses.
- AudioBus* input_bus = Input(0).Bus();
+ scoped_refptr<AudioBus> input_bus = Input(0).Bus();
AudioBus* output_bus = Output(0).Bus();
// Get input and output buffers. We double-buffer both the input and output
@@ -204,7 +204,7 @@ void ScriptProcessorHandler::Process(uint32_t frames_to_process) {
PostCrossThreadTask(
*task_runner_, FROM_HERE,
CrossThreadBindOnce(&ScriptProcessorHandler::FireProcessEvent,
- WrapRefCounted(this), double_buffer_index_));
+ AsWeakPtr(), double_buffer_index_));
} else {
// If this node is in the offline audio context, use the
// waitable event to synchronize to the offline rendering thread.
@@ -215,7 +215,7 @@ void ScriptProcessorHandler::Process(uint32_t frames_to_process) {
*task_runner_, FROM_HERE,
CrossThreadBindOnce(
&ScriptProcessorHandler::FireProcessEventForOfflineAudioContext,
- WrapRefCounted(this), double_buffer_index_,
+ AsWeakPtr(), double_buffer_index_,
CrossThreadUnretained(waitable_event.get())));
// Okay to block the offline audio rendering thread since it is
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 6a372578166..4691e7c79fc 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
@@ -28,6 +28,7 @@
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
#include "base/synchronization/waitable_event.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node.h"
@@ -51,7 +52,9 @@ class WaitableEvent;
// periodically with an AudioProcessingEvent which has AudioBuffers for each
// input and output.
-class ScriptProcessorHandler final : public AudioHandler {
+class ScriptProcessorHandler final
+ : public AudioHandler,
+ public base::SupportsWeakPtr<ScriptProcessorHandler> {
public:
static scoped_refptr<ScriptProcessorHandler> Create(
AudioNode&,
@@ -157,7 +160,7 @@ class ScriptProcessorNode final
// ScriptWrappable
bool HasPendingActivity() const final;
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
// InspectorHelperMixin
void ReportDidCreate() final;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node_test.cc b/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node_test.cc
index be980307d1a..a2a446e95af 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node_test.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node_test.cc
@@ -12,8 +12,9 @@ namespace blink {
TEST(ScriptProcessorNodeTest, BufferLifetime) {
auto page = std::make_unique<DummyPageHolder>();
- OfflineAudioContext* context = OfflineAudioContext::Create(
- &page->GetDocument(), 2, 1, 48000, ASSERT_NO_EXCEPTION);
+ OfflineAudioContext* context =
+ OfflineAudioContext::Create(page->GetDocument().ToExecutionContext(), 2,
+ 1, 48000, ASSERT_NO_EXCEPTION);
ScriptProcessorNode* node =
context->createScriptProcessor(ASSERT_NO_EXCEPTION);
ScriptProcessorHandler& handler =
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 ab31a3dacec..b5698ee47f6 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
@@ -4,11 +4,11 @@
#include "third_party/blink/renderer/modules/webaudio/stereo_panner_node.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_stereo_panner_options.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_input.h"
#include "third_party/blink/renderer/modules/webaudio/audio_node_output.h"
#include "third_party/blink/renderer/modules/webaudio/base_audio_context.h"
-#include "third_party/blink/renderer/modules/webaudio/stereo_panner_options.h"
#include "third_party/blink/renderer/platform/audio/stereo_panner.h"
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -53,23 +53,31 @@ void StereoPannerHandler::Process(uint32_t frames_to_process) {
return;
}
- AudioBus* input_bus = Input(0).Bus();
+ scoped_refptr<AudioBus> input_bus = Input(0).Bus();
if (!input_bus) {
output_bus->Zero();
return;
}
- if (pan_->HasSampleAccurateValues()) {
+ bool is_sample_accurate = pan_->HasSampleAccurateValuesTimeline();
+
+ if (is_sample_accurate && pan_->IsAudioRate()) {
// Apply sample-accurate panning specified by AudioParam automation.
DCHECK_LE(frames_to_process, sample_accurate_pan_values_.size());
float* pan_values = sample_accurate_pan_values_.Data();
pan_->CalculateSampleAccurateValues(pan_values, frames_to_process);
- stereo_panner_->PanWithSampleAccurateValues(input_bus, output_bus,
+ stereo_panner_->PanWithSampleAccurateValues(input_bus.get(), output_bus,
pan_values, frames_to_process);
- } else {
- stereo_panner_->PanToTargetValue(input_bus, output_bus, pan_->Value(),
- frames_to_process);
+ return;
}
+
+ // The pan value is not sample-accurate or not a-rate. In this case, we have
+ // a fixed pan value for the render and just need to incorporate any inputs to
+ // the value, if any.
+ float pan_value = is_sample_accurate ? pan_->FinalValue() : pan_->Value();
+
+ stereo_panner_->PanToTargetValue(input_bus.get(), output_bus, pan_value,
+ frames_to_process);
}
void StereoPannerHandler::ProcessOnlyAudioParams(uint32_t frames_to_process) {
@@ -174,7 +182,7 @@ StereoPannerNode* StereoPannerNode::Create(BaseAudioContext* context,
return node;
}
-void StereoPannerNode::Trace(blink::Visitor* visitor) {
+void StereoPannerNode::Trace(Visitor* visitor) {
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 2ee6ebe23bc..8dfaf04d969 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
AudioParam* pan() const;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.idl b/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.idl
index ce9dedbf6d7..da44448b895 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.idl
@@ -2,14 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// See https://webaudio.github.io/web-audio-api/#stereopannernode
+// https://webaudio.github.io/web-audio-api/#stereopannernode
[
- Exposed=Window,
- Constructor(BaseAudioContext context, optional StereoPannerOptions options),
- RaisesException=Constructor,
- Measure
-]
-interface StereoPannerNode : AudioNode {
+ Exposed=Window
+] interface StereoPannerNode : AudioNode {
+ [RaisesException, Measure] constructor(BaseAudioContext context, optional StereoPannerOptions options = {});
readonly attribute AudioParam pan;
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node_test.cc b/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node_test.cc
index 1e92d21812b..7b6ee1aa12e 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node_test.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node_test.cc
@@ -12,8 +12,9 @@ namespace blink {
TEST(StereoPannerNodeTest, StereoPannerLifetime) {
auto page = std::make_unique<DummyPageHolder>();
- OfflineAudioContext* context = OfflineAudioContext::Create(
- &page->GetDocument(), 2, 1, 48000, ASSERT_NO_EXCEPTION);
+ OfflineAudioContext* context =
+ OfflineAudioContext::Create(page->GetDocument().ToExecutionContext(), 2,
+ 1, 48000, ASSERT_NO_EXCEPTION);
StereoPannerNode* node = context->createStereoPanner(ASSERT_NO_EXCEPTION);
StereoPannerHandler& handler =
static_cast<StereoPannerHandler&>(node->Handler());
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_node.cc
index 1aa56eac462..5d6a3bdc864 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_node.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_node.cc
@@ -27,8 +27,8 @@
#include <memory>
+#include "third_party/blink/renderer/bindings/modules/v8/v8_wave_shaper_options.h"
#include "third_party/blink/renderer/modules/webaudio/base_audio_context.h"
-#include "third_party/blink/renderer/modules/webaudio/wave_shaper_options.h"
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -82,16 +82,26 @@ WaveShaperProcessor* WaveShaperNode::GetWaveShaperProcessor() const {
}
void WaveShaperNode::SetCurveImpl(const float* curve_data,
- unsigned curve_length,
+ size_t curve_length,
ExceptionState& exception_state) {
DCHECK(IsMainThread());
- if (curve_data && curve_length < 2) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kInvalidAccessError,
- ExceptionMessages::IndexExceedsMinimumBound<unsigned>("curve length",
- curve_length, 2));
- return;
+ unsigned length = static_cast<unsigned>(curve_length);
+
+ if (curve_data) {
+ if (!base::CheckedNumeric<unsigned>(curve_length).AssignIfValid(&length)) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotSupportedError,
+ "The curve length exceeds the maximum supported length");
+ return;
+ }
+ if (length < 2) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidAccessError,
+ ExceptionMessages::IndexExceedsMinimumBound<unsigned>("curve length",
+ length, 2));
+ return;
+ }
}
// This is to synchronize with the changes made in
@@ -99,7 +109,7 @@ void WaveShaperNode::SetCurveImpl(const float* curve_data,
// Initialize() and Uninitialize(), changing the number of kernels.
BaseAudioContext::GraphAutoLocker context_locker(context());
- GetWaveShaperProcessor()->SetCurve(curve_data, curve_length);
+ GetWaveShaperProcessor()->SetCurve(curve_data, length);
}
void WaveShaperNode::setCurve(NotShared<DOMFloat32Array> curve,
@@ -107,8 +117,8 @@ void WaveShaperNode::setCurve(NotShared<DOMFloat32Array> curve,
DCHECK(IsMainThread());
if (curve) {
- SetCurveImpl(curve.View()->Data(),
- curve.View()->deprecatedLengthAsUnsigned(), exception_state);
+ SetCurveImpl(curve.View()->Data(), curve.View()->lengthAsSizeT(),
+ exception_state);
} else {
SetCurveImpl(nullptr, 0, exception_state);
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_node.h b/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_node.h
index 17c0c5aad6b..cdf59e6a181 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_node.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_node.h
@@ -71,7 +71,7 @@ class WaveShaperNode final : public AudioNode {
private:
void SetCurveImpl(const float* curve_data,
- unsigned curve_length,
+ size_t curve_length,
ExceptionState&);
WaveShaperProcessor* GetWaveShaperProcessor() const;
};
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_node.idl b/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_node.idl
index 19f396c3250..f391280f136 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_node.idl
+++ b/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_node.idl
@@ -23,7 +23,7 @@
* DAMAGE.
*/
-// See https://webaudio.github.io/web-audio-api/#waveshapernode
+// https://webaudio.github.io/web-audio-api/#waveshapernode
enum OverSampleType {
"none",
"2x",
@@ -31,12 +31,9 @@ enum OverSampleType {
};
[
- Exposed=Window,
- Constructor(BaseAudioContext context, optional WaveShaperOptions options),
- RaisesException=Constructor,
- Measure
-]
-interface WaveShaperNode : AudioNode {
+ Exposed=Window
+] interface WaveShaperNode : AudioNode {
+ [RaisesException, Measure] constructor(BaseAudioContext context, optional WaveShaperOptions options = {});
[RaisesException=Setter] attribute Float32Array? curve;
attribute OverSampleType oversample;
};
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/BUILD.gn b/chromium/third_party/blink/renderer/modules/webcodecs/BUILD.gn
new file mode 100644
index 00000000000..677518de66b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/BUILD.gn
@@ -0,0 +1,44 @@
+# 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.
+
+import("//third_party/blink/renderer/modules/modules.gni")
+
+blink_modules_sources("webcodecs") {
+ sources = [
+ "encoded_video_chunk.cc",
+ "encoded_video_chunk.h",
+ "encoded_video_metadata.h",
+ "video_decoder.cc",
+ "video_decoder.h",
+ "video_frame.cc",
+ "video_frame.h",
+ "video_track_reader.cc",
+ "video_track_reader.h",
+ "video_track_writer.cc",
+ "video_track_writer.h",
+ ]
+}
+
+source_set("unit_tests") {
+ testonly = true
+ sources = [
+ "encoded_video_chunk_test.cc",
+ "video_frame_test.cc",
+ "video_track_reader_writer_test.cc",
+ ]
+
+ configs += [
+ "//third_party/blink/renderer:config",
+ "//third_party/blink/renderer:inside_blink",
+ "//third_party/blink/renderer/core:blink_core_pch",
+ ]
+
+ deps = [
+ "//testing/gmock",
+ "//testing/gtest",
+ "//third_party/blink/renderer/modules",
+ "//third_party/blink/renderer/platform",
+ "//third_party/blink/renderer/platform/wtf",
+ ]
+}
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/DEPS b/chromium/third_party/blink/renderer/modules/webcodecs/DEPS
new file mode 100644
index 00000000000..21f825ca9a3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/DEPS
@@ -0,0 +1,9 @@
+include_rules = [
+ "+base/run_loop.h",
+ "+media/base/media_util.h",
+ "+media/base/video_decoder.h",
+ "+media/base/video_frame.h",
+ "+media/base/status.h",
+ "+ui/gfx/geometry/rect.h",
+ "+ui/gfx/geometry/size.h",
+]
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/OWNERS b/chromium/third_party/blink/renderer/modules/webcodecs/OWNERS
new file mode 100644
index 00000000000..cc72639d7c4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/OWNERS
@@ -0,0 +1,3 @@
+mlamouri@chromium.org
+sandersd@chromium.org
+dalecurtis@chromium.org
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/README.md b/chromium/third_party/blink/renderer/modules/webcodecs/README.md
new file mode 100644
index 00000000000..35d9e504ee7
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/README.md
@@ -0,0 +1,9 @@
+# WebCodecs API
+
+This directory will contain the implementation of
+https://github.com/WICG/web-codecs/, which is a low-level API for encode and
+decode of audio and video.
+
+It will use the existing codec implementations in src/media used by the video
+stack, WebRTC, and MediaRecorder, such as media::DecoderFactory,
+media::VideoEncodeAccelerator, and media::VideoFrame. \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.cc b/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.cc
new file mode 100644
index 00000000000..ad165d8dd39
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.cc
@@ -0,0 +1,64 @@
+// 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/webcodecs/encoded_video_chunk.h"
+
+#include <utility>
+
+#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+EncodedVideoChunk* EncodedVideoChunk::Create(String type,
+ uint64_t timestamp,
+ const DOMArrayPiece& data) {
+ return EncodedVideoChunk::Create(type, timestamp, 0 /* duration */, data);
+}
+
+EncodedVideoChunk* EncodedVideoChunk::Create(String type,
+ uint64_t timestamp,
+ uint64_t duration,
+ const DOMArrayPiece& data) {
+ EncodedVideoMetadata metadata;
+ metadata.timestamp = base::TimeDelta::FromMicroseconds(timestamp);
+ metadata.key_frame = (type == "key");
+ if (duration)
+ metadata.duration = base::TimeDelta::FromMicroseconds(duration);
+ return MakeGarbageCollected<EncodedVideoChunk>(
+ metadata, DOMArrayBuffer::Create(data.Bytes(), data.ByteLengthAsSizeT()));
+}
+
+EncodedVideoChunk::EncodedVideoChunk(EncodedVideoMetadata metadata,
+ DOMArrayBuffer* buffer)
+ : metadata_(metadata), buffer_(buffer) {}
+
+String EncodedVideoChunk::type() const {
+ return metadata_.key_frame ? "key" : "delta";
+}
+
+uint64_t EncodedVideoChunk::timestamp() const {
+ return metadata_.timestamp.InMicroseconds();
+}
+
+base::Optional<uint64_t> EncodedVideoChunk::duration() const {
+ if (!metadata_.duration)
+ return base::nullopt;
+ return metadata_.duration->InMicroseconds();
+}
+
+uint64_t EncodedVideoChunk::duration(bool* is_null) const {
+ if (!metadata_.duration) {
+ *is_null = true;
+ return 0;
+ }
+ *is_null = false;
+ return metadata_.duration->InMicroseconds();
+}
+
+DOMArrayBuffer* EncodedVideoChunk::data() const {
+ return buffer_;
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..4d063fdfcb2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.h
@@ -0,0 +1,54 @@
+// 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_WEBCODECS_ENCODED_VIDEO_CHUNK_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_ENCODED_VIDEO_CHUNK_H_
+
+#include "third_party/blink/renderer/core/typed_arrays/dom_array_piece.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/modules/webcodecs/encoded_video_metadata.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+
+namespace blink {
+
+class DOMArrayBuffer;
+
+class MODULES_EXPORT EncodedVideoChunk final : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ EncodedVideoChunk(EncodedVideoMetadata metadata, DOMArrayBuffer* buffer);
+
+ static EncodedVideoChunk* Create(String type,
+ uint64_t timestamp,
+ const DOMArrayPiece& data);
+ static EncodedVideoChunk* Create(String type,
+ uint64_t timestamp,
+ uint64_t duration,
+ const DOMArrayPiece& data);
+
+ // encoded_video_chunk.idl implementation.
+ String type() const;
+ uint64_t timestamp() const;
+ base::Optional<uint64_t> duration() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ uint64_t duration(bool* is_null) const; // DEPRECATED
+ uint64_t duration(bool& is_null) const { // DEPRECATED
+ return duration(&is_null);
+ }
+ DOMArrayBuffer* data() const;
+
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(buffer_);
+ ScriptWrappable::Trace(visitor);
+ }
+
+ private:
+ EncodedVideoMetadata metadata_;
+ Member<DOMArrayBuffer> buffer_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_ENCODED_VIDEO_CHUNK_H_
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.idl b/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.idl
new file mode 100644
index 00000000000..b2eff05301b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.idl
@@ -0,0 +1,20 @@
+// 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.
+
+enum EncodedVideoChunkType {
+ "key",
+ "delta",
+};
+
+[
+ RuntimeEnabled=WebCodecs
+] interface EncodedVideoChunk {
+ constructor(EncodedVideoChunkType type, unsigned long long timestamp, BufferSource data);
+ constructor(EncodedVideoChunkType type, unsigned long long timestamp, unsigned long long duration, BufferSource data);
+ readonly attribute EncodedVideoChunkType type;
+ // TODO: Add frame dependency information
+ readonly attribute unsigned long long timestamp; // microseconds
+ readonly attribute unsigned long long? duration; // microseconds
+ readonly attribute ArrayBuffer data;
+}; \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk_test.cc b/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk_test.cc
new file mode 100644
index 00000000000..9844820876d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk_test.cc
@@ -0,0 +1,58 @@
+// 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/webcodecs/encoded_video_chunk.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+namespace {
+
+class EncodedVideoChunkTest : public testing::Test {
+ public:
+ DOMArrayBuffer* StringToBuffer(std::string data) {
+ return DOMArrayBuffer::Create(data.data(), data.size());
+ }
+
+ std::string BufferToString(DOMArrayBuffer* buffer) {
+ return std::string(static_cast<char*>(buffer->Data()),
+ buffer->ByteLengthAsSizeT());
+ }
+};
+
+TEST_F(EncodedVideoChunkTest, ConstructorAndAttributes) {
+ String type = "key";
+ uint64_t timestamp = 1000000;
+ std::string data = "test";
+ auto* encoded =
+ EncodedVideoChunk::Create(type, timestamp, StringToBuffer(data));
+
+ EXPECT_EQ(type, encoded->type());
+ EXPECT_EQ(timestamp, encoded->timestamp());
+ EXPECT_EQ(data, BufferToString(encoded->data()));
+ bool is_null = false;
+ encoded->duration(&is_null);
+ EXPECT_TRUE(is_null);
+}
+
+TEST_F(EncodedVideoChunkTest, ConstructorWithDuration) {
+ String type = "key";
+ uint64_t timestamp = 1000000;
+ uint64_t duration = 16667;
+ std::string data = "test";
+ auto* encoded = EncodedVideoChunk::Create(type, timestamp, duration,
+ StringToBuffer(data));
+
+ EXPECT_EQ(type, encoded->type());
+ EXPECT_EQ(timestamp, encoded->timestamp());
+ EXPECT_EQ(data, BufferToString(encoded->data()));
+ bool is_null = false;
+ EXPECT_EQ(duration, encoded->duration(&is_null));
+ EXPECT_FALSE(is_null);
+}
+
+} // namespace
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_config.idl b/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_config.idl
new file mode 100644
index 00000000000..7af04a69e78
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_config.idl
@@ -0,0 +1,21 @@
+// 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 EncodedVideoConfig {
+ // Codec string, eg. "avc1.42001e" or "vp09.00.10.08".
+ // TODO(sandersd): Accept "avc1" if |description| is provided?
+ required DOMString codec;
+
+ // avcC, vpcC, or etc.
+ BufferSource description;
+
+ // If provided, these override in-band configuration.
+ double sampleAspect;
+ // TODO(sandersd): color space.
+
+ // TODO(sandersd): Constraints (sequential access) and requirements
+ // (imagebitmap, colorspace conversion).
+};
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_metadata.h b/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_metadata.h
new file mode 100644
index 00000000000..124b3bf6c72
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_metadata.h
@@ -0,0 +1,17 @@
+// 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_WEBCODECS_ENCODED_VIDEO_METADATA_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_ENCODED_VIDEO_METADATA_H_
+
+#include "base/optional.h"
+#include "base/time/time.h"
+
+struct EncodedVideoMetadata {
+ bool key_frame = false;
+ base::TimeDelta timestamp;
+ base::Optional<base::TimeDelta> duration;
+};
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_ENCODED_VIDEO_METADATA_H_
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/idls.gni b/chromium/third_party/blink/renderer/modules/webcodecs/idls.gni
new file mode 100644
index 00000000000..973ad53968d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "encoded_video_chunk.idl",
+ "video_decoder.idl",
+ "video_frame.idl",
+ "video_track_reader.idl",
+ "video_track_writer.idl",
+]
+
+modules_callback_function_idl_files = [
+ "video_decoder_output_callback.idl",
+ "webcodecs_error_callback.idl",
+]
+
+modules_dictionary_idl_files = [
+ "encoded_video_config.idl",
+ "video_decoder_init.idl",
+ "video_track_writer_parameters.idl",
+]
+
+# IDL files that either define partial interfaces or target (right side of)
+# `includes`.
+modules_dependency_idl_files = []
+
+# Similar to |modules_dependency_idl_files| but limited to things that are
+# exposed only for testing.
+modules_testing_dependency_idl_files = []
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.cc b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.cc
new file mode 100644
index 00000000000..cc422bb0ecf
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.cc
@@ -0,0 +1,158 @@
+// 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/webcodecs/video_decoder.h"
+
+#include "base/logging.h"
+#include "base/time/time.h"
+#include "media/base/media_util.h"
+#include "media/base/video_decoder.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/core/dom/dom_exception.h"
+#include "third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.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"
+#include "third_party/blink/renderer/platform/bindings/script_state.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size.h"
+
+namespace blink {
+
+// static
+VideoDecoder* VideoDecoder::Create(ScriptState* script_state,
+ const VideoDecoderInit* init,
+ ExceptionState& exception_state) {
+ return MakeGarbageCollected<VideoDecoder>(script_state, init,
+ exception_state);
+}
+
+VideoDecoder::VideoDecoder(ScriptState* script_state,
+ const VideoDecoderInit* init,
+ ExceptionState& exception_state)
+ : script_state_(script_state) {
+ DVLOG(1) << __func__;
+ // TODO(sandersd): Extract callbacks from |init|.
+}
+
+VideoDecoder::~VideoDecoder() {
+ DVLOG(1) << __func__;
+}
+
+int32_t VideoDecoder::decodeQueueSize() {
+ return requested_decodes_;
+}
+
+int32_t VideoDecoder::decodeProcessingCount() {
+ return pending_decodes_.size();
+}
+
+ScriptPromise VideoDecoder::configure(const EncodedVideoConfig* config,
+ ExceptionState&) {
+ DVLOG(1) << __func__;
+ Request* request = MakeGarbageCollected<Request>();
+ request->type = Request::Type::kConfigure;
+ request->config = config;
+ return EnqueueRequest(request);
+}
+
+ScriptPromise 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);
+}
+
+ScriptPromise VideoDecoder::flush(ExceptionState&) {
+ DVLOG(3) << __func__;
+ Request* request = MakeGarbageCollected<Request>();
+ request->type = Request::Type::kFlush;
+ return EnqueueRequest(request);
+}
+
+ScriptPromise 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);
+
+ // If there were no requests before, trigger request processing.
+ if (requests_.size() == 1)
+ ProcessRequests();
+
+ return resolver->Promise();
+}
+
+void VideoDecoder::ProcessRequests() {}
+
+void VideoDecoder::HandleError() {}
+
+void VideoDecoder::OnInitializeDone(media::Status status) {
+ DVLOG(3) << __func__;
+
+ Request* request = requests_.TakeFirst();
+ DCHECK_EQ(request->type, Request::Type::kConfigure);
+
+ if (!status.is_ok()) {
+ // TODO(tmathmeyer) this drops the media error - should we consider logging
+ // it or converting it to the DOMException type somehow?
+ request->resolver.Release()->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kNotSupportedError, "Codec initialization failed."));
+ HandleError();
+ return;
+ }
+
+ request->resolver.Release()->Resolve();
+ ProcessRequests();
+}
+
+void VideoDecoder::OnDecodeDone(uint32_t id, media::DecodeStatus status) {
+ DVLOG(3) << __func__;
+ DCHECK(pending_decodes_.Contains(id));
+
+ if (status != media::DecodeStatus::OK) {
+ // TODO(sandersd): Handle ABORTED during Reset.
+ HandleError();
+ return;
+ }
+
+ auto it = pending_decodes_.find(id);
+ it->value->resolver.Release()->Resolve();
+ pending_decodes_.erase(it);
+ ProcessRequests();
+}
+
+void VideoDecoder::OnOutput(scoped_refptr<media::VideoFrame> frame) {
+ DVLOG(3) << __func__;
+ // TODO(sandersd): Call output callback.
+ // MakeGarbageCollected<VideoFrame>(frame)
+}
+
+void VideoDecoder::Trace(Visitor* visitor) {
+ visitor->Trace(script_state_);
+ visitor->Trace(requests_);
+ visitor->Trace(pending_decodes_);
+ ScriptWrappable::Trace(visitor);
+}
+
+void VideoDecoder::Request::Trace(Visitor* visitor) {
+ visitor->Trace(config);
+ visitor->Trace(chunk);
+ visitor->Trace(resolver);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.h b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.h
new file mode 100644
index 00000000000..03c62537f19
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.h
@@ -0,0 +1,90 @@
+// 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_WEBCODECS_VIDEO_DECODER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_DECODER_H_
+
+#include <stdint.h>
+#include <memory>
+
+#include "media/base/status.h"
+#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/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.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/member.h"
+
+namespace blink {
+
+class EncodedVideoChunk;
+class EncodedVideoConfig;
+class ExceptionState;
+class ScriptState;
+class VideoDecoderInit;
+
+class MODULES_EXPORT VideoDecoder final : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static VideoDecoder* Create(ScriptState*,
+ const VideoDecoderInit*,
+ ExceptionState&);
+
+ VideoDecoder(ScriptState*, const VideoDecoderInit*, ExceptionState&);
+ ~VideoDecoder() override;
+
+ // video_decoder.idl implementation.
+ int32_t decodeQueueSize();
+ int32_t decodeProcessingCount();
+ ScriptPromise configure(const EncodedVideoConfig*, ExceptionState&);
+ ScriptPromise decode(const EncodedVideoChunk*, ExceptionState&);
+ ScriptPromise flush(ExceptionState&);
+ ScriptPromise reset(ExceptionState&);
+
+ // GarbageCollected override.
+ void Trace(Visitor*) override;
+
+ private:
+ struct Request : public GarbageCollected<Request> {
+ enum class Type {
+ kConfigure,
+ kDecode,
+ kFlush,
+ kReset,
+ };
+
+ void Trace(Visitor*);
+
+ Type type;
+ Member<const EncodedVideoConfig> config;
+ Member<const EncodedVideoChunk> chunk;
+ Member<ScriptPromiseResolver> resolver;
+ };
+
+ ScriptPromise EnqueueRequest(Request* request);
+ void ProcessRequests();
+ void HandleError();
+
+ // Called by |decoder_|.
+ void OnInitializeDone(media::Status status);
+ void OnDecodeDone(uint32_t id, media::DecodeStatus);
+ void OnOutput(scoped_refptr<media::VideoFrame>);
+
+ Member<ScriptState> script_state_;
+
+ HeapDeque<Member<Request>> requests_;
+ int32_t requested_decodes_ = 0;
+ int32_t requested_resets_ = 0;
+
+ std::unique_ptr<media::VideoDecoder> decoder_;
+ HeapHashMap<uint32_t, Member<Request>> pending_decodes_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_DECODER_H_
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.idl b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.idl
new file mode 100644
index 00000000000..8d930506f5e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.idl
@@ -0,0 +1,87 @@
+// 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://github.com/WICG/web-codecs
+
+// A VideoDecoder processes a queue of configure, decode, and flush requests.
+// Requests are taken from the queue sequentially but may be processed
+// concurrently.
+//
+// TODO(sandersd): Specify a tune() implementation for changing decoder
+// parameters (separate from stream parameters). This is more important for
+// encoders.
+[RuntimeEnabled=WebCodecs]
+interface VideoDecoder {
+ // |init| includes an |output| callback for emitting VideoFrames and an
+ // |error| callback for emitting decode errors.
+ //
+ // 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.
+ //
+ // 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;
+
+ // Enqueue a request to set or change the stream configuration.
+ //
+ // The next enqueued 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);
+
+ // Enqueue a request to decode an input chunk.
+ //
+ // You must call configure() before calling enqueue() for the first time.
+ //
+ // Resolved after decoding of the input chunk has started (that is, after
+ // decreasing |decodeQueueSize|).
+ //
+ // 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);
+
+ // Enqueue a request to finish decoding queued input chunks.
+ //
+ // The next enqueued input chunk must be a keyframe.
+ //
+ // Resolved after emitting output for all earlier decode requests.
+ //
+ // TODO(sandersd): Consider relaxing the keyframe requirement.
+ [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.
+ //
+ // Resolved after all earlier enqueue() promises have been resolved.
+ //
+ // TODO(sandersd): Require configure() after reset()?
+ [RaisesException] Promise<void> reset();
+};
diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_error_event_init.idl b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_init.idl
index b8d7f502543..5335bbaebd5 100644
--- a/chromium/third_party/blink/renderer/modules/nfc/ndef_error_event_init.idl
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_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.
-// Specification at:
-// http://w3c.github.io/web-nfc/#dom-ndeferroreventinit
+// https://github.com/WICG/web-codecs
-dictionary NDEFErrorEventInit : EventInit {
- required DOMException error;
+dictionary VideoDecoderInit {
+ VideoDecoderOutputCallback output;
+ WebCodecsErrorCallback error;
};
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_output_callback.idl b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_output_callback.idl
new file mode 100644
index 00000000000..3daff3e415d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_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 VideoDecoderOutputCallback = void(VideoFrame 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
new file mode 100644
index 00000000000..fca64b49cbf
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.cc
@@ -0,0 +1,60 @@
+// 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/webcodecs/video_frame.h"
+
+#include <utility>
+
+#include "media/base/video_frame.h"
+
+namespace blink {
+
+VideoFrame::VideoFrame(scoped_refptr<media::VideoFrame> frame)
+ : frame_(std::move(frame)) {
+ DCHECK(frame_);
+}
+
+scoped_refptr<media::VideoFrame> VideoFrame::frame() {
+ return frame_;
+}
+
+scoped_refptr<const media::VideoFrame> VideoFrame::frame() const {
+ return frame_;
+}
+
+uint64_t VideoFrame::timestamp() const {
+ if (!frame_)
+ return 0;
+ return frame_->timestamp().InMicroseconds();
+}
+
+uint32_t VideoFrame::coded_width() const {
+ if (!frame_)
+ return 0;
+ return frame_->coded_size().width();
+}
+
+uint32_t VideoFrame::coded_height() const {
+ if (!frame_)
+ return 0;
+ return frame_->coded_size().height();
+}
+
+uint32_t VideoFrame::visible_width() const {
+ if (!frame_)
+ return 0;
+ return frame_->visible_rect().width();
+}
+
+uint32_t VideoFrame::visible_height() const {
+ if (!frame_)
+ return 0;
+ return frame_->visible_rect().height();
+}
+
+void VideoFrame::release() {
+ frame_.reset();
+}
+
+} // 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
new file mode 100644
index 00000000000..269543f12de
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.h
@@ -0,0 +1,41 @@
+// 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_WEBCODECS_VIDEO_FRAME_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_FRAME_H_
+
+#include "media/base/video_frame.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 MODULES_EXPORT VideoFrame final : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ explicit VideoFrame(scoped_refptr<media::VideoFrame> frame);
+
+ // video_track_frame.idl implementation.
+ uint64_t timestamp() const;
+
+ uint32_t coded_width() const;
+ uint32_t coded_height() const;
+ uint32_t visible_width() const;
+ uint32_t visible_height() const;
+
+ void release();
+
+ // Convenience functions
+ scoped_refptr<media::VideoFrame> frame();
+ scoped_refptr<const media::VideoFrame> frame() const;
+
+ private:
+ scoped_refptr<media::VideoFrame> frame_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_FRAME_H_
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.idl b/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.idl
new file mode 100644
index 00000000000..5b4f67254f9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.idl
@@ -0,0 +1,17 @@
+// 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.
+
+[
+ RuntimeEnabled=WebCodecs
+] interface VideoFrame {
+ void release();
+
+ readonly attribute unsigned long long timestamp; // microseconds
+
+ readonly attribute unsigned long coded_width;
+ readonly attribute unsigned long coded_height;
+
+ readonly attribute unsigned long visible_width;
+ readonly attribute unsigned long visible_height;
+}; \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc b/chromium/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc
new file mode 100644
index 00000000000..d3e6d42cd91
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc
@@ -0,0 +1,62 @@
+// 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 "media/base/video_frame.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/modules/webcodecs/video_frame.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size.h"
+
+namespace blink {
+
+namespace {
+
+class VideoFrameTest : public testing::Test {
+ public:
+ VideoFrame* CreateBlinkVideoFrame(
+ scoped_refptr<media::VideoFrame> media_frame) {
+ return MakeGarbageCollected<VideoFrame>(std::move(media_frame));
+ }
+ scoped_refptr<media::VideoFrame> CreateBlackMediaVideoFrame(
+ base::TimeDelta timestamp,
+ media::VideoPixelFormat format,
+ const gfx::Size& coded_size,
+ const gfx::Size& visible_size) {
+ scoped_refptr<media::VideoFrame> media_frame =
+ media::VideoFrame::WrapVideoFrame(
+ media::VideoFrame::CreateBlackFrame(coded_size), format,
+ gfx::Rect(visible_size) /* visible_rect */,
+ visible_size /* natural_size */);
+ media_frame->set_timestamp(timestamp);
+ return media_frame;
+ }
+};
+
+TEST_F(VideoFrameTest, ConstructorAndAttributes) {
+ scoped_refptr<media::VideoFrame> media_frame = CreateBlackMediaVideoFrame(
+ base::TimeDelta::FromMicroseconds(1000), media::PIXEL_FORMAT_I420,
+ gfx::Size(112, 208) /* coded_size */,
+ gfx::Size(100, 200) /* visible_size */);
+ VideoFrame* blink_frame = CreateBlinkVideoFrame(media_frame);
+
+ EXPECT_EQ(1000u, blink_frame->timestamp());
+ EXPECT_EQ(112u, blink_frame->coded_width());
+ EXPECT_EQ(208u, blink_frame->coded_height());
+ EXPECT_EQ(100u, blink_frame->visible_width());
+ EXPECT_EQ(200u, blink_frame->visible_height());
+ EXPECT_EQ(media_frame, blink_frame->frame());
+
+ blink_frame->release();
+
+ EXPECT_EQ(0u, blink_frame->timestamp());
+ EXPECT_EQ(0u, blink_frame->coded_width());
+ EXPECT_EQ(0u, blink_frame->coded_height());
+ EXPECT_EQ(0u, blink_frame->visible_width());
+ EXPECT_EQ(0u, blink_frame->visible_height());
+ EXPECT_EQ(nullptr, blink_frame->frame());
+}
+
+} // namespace
+
+} // namespace blink
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
new file mode 100644
index 00000000000..d1b603f0dfb
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.cc
@@ -0,0 +1,121 @@
+// 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/video_track_reader.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/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"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
+
+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 */);
+ }
+
+ // 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)));
+ }
+
+ void OnFrameFromVideoTrackOnTaskRunner(
+ scoped_refptr<media::VideoFrame> media_frame) {
+ Controller()->Enqueue(
+ MakeGarbageCollected<VideoFrame>(std::move(media_frame)));
+ }
+
+ // MediaStreamVideoSink override
+ void OnReadyStateChanged(WebMediaStreamSource::ReadyState state) override {
+ if (state == WebMediaStreamSource::kReadyStateEnded)
+ Close();
+ }
+
+ // 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);
+ }
+
+ ScriptPromise Cancel(ScriptState* script_state, ScriptValue reason) override {
+ Close();
+ return ScriptPromise::CastUndefined(script_state);
+ }
+
+ void ContextDestroyed() override { DisconnectFromTrack(); }
+
+ void Close() {
+ if (Controller())
+ Controller()->Close();
+ DisconnectFromTrack();
+ }
+
+ // VideoFrames will be queue on this task runner.
+ const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+};
+
+VideoTrackReader* VideoTrackReader::Create(ScriptState* script_state,
+ MediaStreamTrack* track,
+ ExceptionState& exception_state) {
+ if (track->kind() != "video") {
+ exception_state.ThrowTypeError(
+ "Can only read video frames from video tracks.");
+ return nullptr;
+ }
+
+ if (!script_state->ContextIsValid()) { // when the context is detached
+ exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
+ "The context has been destroyed");
+
+ 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_;
+}
+
+void VideoTrackReader::Trace(Visitor* visitor) {
+ visitor->Trace(readable_);
+ ScriptWrappable::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
new file mode 100644
index 00000000000..1928a08ba6f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.h
@@ -0,0 +1,38 @@
+// 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_VIDEO_TRACK_READER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_TRACK_READER_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 {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static VideoTrackReader* Create(ScriptState* script_state,
+ MediaStreamTrack* track,
+ ExceptionState& exception_state);
+ explicit VideoTrackReader(ReadableStream* readable);
+ ReadableStream* readable() const;
+
+ void Trace(Visitor* visitor) override;
+
+ private:
+ VideoTrackReader(const VideoTrackReader&) = delete;
+ VideoTrackReader& operator=(const VideoTrackReader&) = delete;
+
+ Member<ReadableStream> readable_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_TRACK_READER_H_
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
new file mode 100644
index 00000000000..bb5aded4d5f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.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.
+
+// See spec in developement at https://github.com/WICG/web-codecs/blob/master/index.bs
+// and https://github.com/WICG/web-codecs/blob/master/explainer.md.
+[
+ RuntimeEnabled=WebCodecs
+] interface VideoTrackReader {
+ [CallWith=ScriptState, RaisesException]
+ constructor(MediaStreamTrack track);
+ readonly attribute ReadableStream readable; // of VideoFrame
+}; \ No newline at end of file
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
new file mode 100644
index 00000000000..f576da4559f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader_writer_test.cc
@@ -0,0 +1,133 @@
+// 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 "base/run_loop.h"
+#include "testing/gtest/include/gtest/gtest.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"
+#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/core/streams/writable_stream_default_writer.h"
+#include "third_party/blink/renderer/modules/webcodecs/video_frame.h"
+#include "third_party/blink/renderer/modules/webcodecs/video_track_reader.h"
+#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/testing/io_task_runner_testing_platform_support.h"
+
+namespace blink {
+
+class VideoTrackReaderWriterTest : public testing::Test {
+ public:
+ void TearDown() override {
+ RunIOUntilIdle();
+ ThreadState::Current()->CollectAllGarbageForTesting();
+ }
+
+ protected:
+ VideoFrame* CreateBlackVideoFrame() {
+ return MakeGarbageCollected<VideoFrame>(
+ media::VideoFrame::CreateBlackFrame(gfx::Size(100, 100)));
+ }
+
+ void RunIOUntilIdle() const {
+ // Tracks use the IO thread to send frames to sinks. Make sure that
+ // tasks on IO thread are completed before moving on.
+ base::RunLoop run_loop;
+ platform_->GetIOTaskRunner()->PostTaskAndReply(
+ FROM_HERE, base::BindOnce([] {}), run_loop.QuitClosure());
+ run_loop.Run();
+ base::RunLoop().RunUntilIdle();
+ }
+
+ private:
+ ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_;
+};
+
+TEST_F(VideoTrackReaderWriterTest, WriteAndRead) {
+ V8TestingScope scope;
+ auto* script_state = scope.GetScriptState();
+
+ VideoTrackWriterParameters params;
+ params.setReleaseFrames(false);
+ auto* writer =
+ VideoTrackWriter::Create(script_state, &params, ASSERT_NO_EXCEPTION);
+ auto* reader = VideoTrackReader::Create(script_state, writer->track(),
+ ASSERT_NO_EXCEPTION);
+
+ auto* frame = CreateBlackVideoFrame();
+ writer->writable()
+ ->getWriter(script_state, ASSERT_NO_EXCEPTION)
+ ->write(script_state,
+ 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());
+
+ RunIOUntilIdle();
+
+ EXPECT_EQ(v8::Promise::kFulfilled, v8_read_promise->State());
+
+ auto* read_frame = V8VideoFrame::ToImplWithTypeCheck(
+ scope.GetIsolate(),
+ v8_read_promise->Result()
+ ->ToObject(scope.GetContext())
+ .ToLocalChecked()
+ ->Get(scope.GetContext(), V8String(scope.GetIsolate(), "value"))
+ .ToLocalChecked());
+
+ ASSERT_TRUE(frame);
+ EXPECT_EQ(frame->frame(), read_frame->frame());
+
+ // Auto-release turned off
+ EXPECT_NE(nullptr, frame->frame());
+}
+
+TEST_F(VideoTrackReaderWriterTest, AutoRelease) {
+ V8TestingScope scope;
+ auto* script_state = scope.GetScriptState();
+
+ VideoTrackWriterParameters params;
+ params.setReleaseFrames(true);
+ auto* writer =
+ VideoTrackWriter::Create(script_state, &params, ASSERT_NO_EXCEPTION);
+
+ auto* frame = CreateBlackVideoFrame();
+ writer->writable()
+ ->getWriter(script_state, ASSERT_NO_EXCEPTION)
+ ->write(script_state,
+ ScriptValue(scope.GetIsolate(), ToV8(frame, script_state)),
+ ASSERT_NO_EXCEPTION);
+
+ RunIOUntilIdle();
+
+ // Auto-release worked
+ EXPECT_EQ(nullptr, frame->frame());
+}
+
+TEST_F(VideoTrackReaderWriterTest, Abort) {
+ V8TestingScope scope;
+ auto* script_state = scope.GetScriptState();
+
+ VideoTrackWriterParameters params;
+ params.setReleaseFrames(false);
+ auto* writer =
+ VideoTrackWriter::Create(script_state, &params, ASSERT_NO_EXCEPTION);
+
+ EXPECT_EQ(writer->track()->readyState(), "live");
+
+ writer->writable()->abort(script_state, ASSERT_NO_EXCEPTION);
+
+ RunIOUntilIdle();
+
+ EXPECT_TRUE(writer->track()->Ended());
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..1d3089a2c52
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.cc
@@ -0,0 +1,194 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this Sink code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/modules/webcodecs/video_track_writer.h"
+
+#include "media/base/video_frame.h"
+#include "third_party/blink/public/mojom/mediastream/media_stream.mojom-blink.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/modules/v8/v8_video_frame.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_video_track_writer_parameters.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/streams/underlying_sink_base.h"
+#include "third_party/blink/renderer/core/streams/writable_stream.h"
+#include "third_party/blink/renderer/core/streams/writable_stream_default_controller.h"
+#include "third_party/blink/renderer/modules/mediastream/media_stream_track.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"
+#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/uuid.h"
+
+namespace blink {
+
+// Simplifies the creation of video tracks. Just do this:
+// auto source = std::make_unique<PushableVideoTrackSource>();
+// auto* track = CreateVideoTrackFromSource(script_state, source);
+// for each frame:
+// source->PushFrame(video_frame, capture_time);
+// source->Stop();
+class PushableVideoTrackSource : public MediaStreamVideoSource {
+ public:
+ void PushFrame(scoped_refptr<media::VideoFrame> video_frame,
+ base::TimeTicks estimated_capture_time) {
+ if (!running_)
+ return;
+
+ // Note that although use of the IO thread is rare in blink, it's required
+ // by any implementation of MediaStreamVideoSource, which is made clear by
+ // the documentation of MediaStreamVideoSource::StartSourceImpl which reads
+ // "An implementation must call |frame_callback| on the IO thread."
+ // Also see the DCHECK at VideoTrackAdapter::DeliverFrameOnIO
+ // and the other of implementations of MediaStreamVideoSource at
+ // MediaStreamRemoteVideoSource::StartSourceImpl,
+ // CastReceiverSession::StartVideo,
+ // CanvasCaptureHandler::SendFrame,
+ // and HtmlVideoElementCapturerSource::sendNewFrame.
+ PostCrossThreadTask(
+ *io_task_runner(), FROM_HERE,
+ CrossThreadBindOnce(deliver_frame_cb_, std::move(video_frame),
+ estimated_capture_time));
+ }
+
+ void Stop() {
+ DoStopSource();
+ running_ = false;
+ }
+
+ void StartSourceImpl(VideoCaptureDeliverFrameCB frame_callback,
+ EncodedVideoFrameCB encoded_frame_callback) override {
+ DCHECK(frame_callback);
+ running_ = true;
+ deliver_frame_cb_ = frame_callback;
+ OnStartDone(mojom::blink::MediaStreamRequestResult::OK);
+ }
+
+ void StopSourceImpl() override { running_ = false; }
+
+ private:
+ bool running_ = false;
+ VideoCaptureDeliverFrameCB deliver_frame_cb_;
+};
+
+// Implements a WritableStream's UnderlyingSinkBase by pushing frames into a
+// PushableVideoTrackSource. Also optionally releases the frames.
+class VideoTrackWritableStreamSink final : public UnderlyingSinkBase {
+ public:
+ // The source must out live the sink.
+ VideoTrackWritableStreamSink(PushableVideoTrackSource* source,
+ bool release_frames)
+ : source_(source), release_frames_(release_frames) {}
+
+ // UnderlyingSinkBase overrides.
+ ScriptPromise start(ScriptState* script_state,
+ WritableStreamDefaultController* controller,
+ ExceptionState& exception_state) override {
+ // We're ready write away
+ return ScriptPromise::CastUndefined(script_state);
+ }
+
+ ScriptPromise write(ScriptState* script_state,
+ ScriptValue chunk,
+ WritableStreamDefaultController* controller,
+ ExceptionState& exception_state) override {
+ VideoFrame* video_frame = V8VideoFrame::ToImplWithTypeCheck(
+ script_state->GetIsolate(), chunk.V8Value());
+ if (!video_frame) {
+ exception_state.ThrowTypeError("Provided chunk is not a VideoFrame.");
+ return ScriptPromise();
+ }
+
+ base::TimeTicks estimated_capture_time = base::TimeTicks::Now();
+ source_->PushFrame(video_frame->frame(), estimated_capture_time);
+
+ if (release_frames_)
+ video_frame->release();
+
+ return ScriptPromise::CastUndefined(script_state);
+ }
+
+ ScriptPromise abort(ScriptState* script_state,
+ ScriptValue reason,
+ ExceptionState& exception_state) override {
+ source_->Stop();
+ return ScriptPromise::CastUndefined(script_state);
+ }
+
+ ScriptPromise close(ScriptState* script_state,
+ ExceptionState& exception_state) override {
+ source_->Stop();
+ return ScriptPromise::CastUndefined(script_state);
+ }
+
+ PushableVideoTrackSource* source_;
+ bool release_frames_;
+};
+
+MediaStreamTrack* CreateVideoTrackFromSource(
+ ScriptState* script_state,
+ std::unique_ptr<MediaStreamVideoSource> video_source) {
+ // Get "video_source.get()" before std::move(source) into owner.
+ auto* video_source_ptr = video_source.get();
+
+ String track_id = WTF::CreateCanonicalUUIDString();
+ MediaStreamSource* video_source_owner =
+ MakeGarbageCollected<MediaStreamSource>(
+ track_id, MediaStreamSource::kTypeVideo, track_id /* name */,
+ false /* remote */);
+ video_source->SetOwner(video_source_owner);
+ video_source_owner->SetPlatformSource(std::move(video_source));
+
+ return MakeGarbageCollected<MediaStreamTrack>(
+ ExecutionContext::From(script_state),
+ MediaStreamVideoTrack::CreateVideoTrack(
+ video_source_ptr, MediaStreamVideoSource::ConstraintsOnceCallback(),
+ true /* enabled */));
+}
+
+VideoTrackWriter* VideoTrackWriter::Create(
+ ScriptState* script_state,
+ const VideoTrackWriterParameters* params,
+ ExceptionState& exception_state) {
+ if (!script_state->ContextIsValid()) { // when the context is detached
+ exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
+ "The context has been destroyed");
+
+ return nullptr;
+ }
+
+ std::unique_ptr<PushableVideoTrackSource> track_source =
+ std::make_unique<PushableVideoTrackSource>();
+ VideoTrackWritableStreamSink* writable_sink =
+ MakeGarbageCollected<VideoTrackWritableStreamSink>(
+ track_source.get(), params->releaseFrames());
+
+ auto* track =
+ CreateVideoTrackFromSource(script_state, std::move(track_source));
+ auto* writable = WritableStream::Create(
+ script_state, ScriptValue::From(script_state, writable_sink),
+ exception_state);
+ return MakeGarbageCollected<VideoTrackWriter>(track, writable);
+}
+
+VideoTrackWriter::VideoTrackWriter(MediaStreamTrack* track,
+ WritableStream* writable)
+ : track_(track), writable_(writable) {}
+
+WritableStream* VideoTrackWriter::writable() {
+ return writable_;
+}
+
+MediaStreamTrack* VideoTrackWriter::track() {
+ return track_;
+}
+
+void VideoTrackWriter::Trace(Visitor* visitor) {
+ visitor->Trace(track_);
+ visitor->Trace(writable_);
+ ScriptWrappable::Trace(visitor);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..1b925f6b80c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.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_MODULES_WEBCODECS_VIDEO_TRACK_WRITER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_TRACK_WRITER_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 ScriptState;
+class WritableStream;
+class VideoTrackWriterParameters;
+
+class MODULES_EXPORT VideoTrackWriter final : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ // video_track_writer.idl implementation
+ static VideoTrackWriter* Create(ScriptState* script_state,
+ const VideoTrackWriterParameters* params,
+ ExceptionState& exception_state);
+ VideoTrackWriter(MediaStreamTrack* track, WritableStream* writable);
+ MediaStreamTrack* track();
+ WritableStream* writable();
+
+ // GarbageCollected override
+ void Trace(Visitor* visitor) override;
+
+ private:
+ Member<MediaStreamTrack> track_;
+ Member<WritableStream> writable_;
+
+ DISALLOW_COPY_AND_ASSIGN(VideoTrackWriter);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_TRACK_WRITER_H_
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.idl b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.idl
new file mode 100644
index 00000000000..aa5d3fd1fe2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.idl
@@ -0,0 +1,14 @@
+// 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.
+
+// See spec in developement at https://github.com/WICG/web-codecs/blob/master/index.bs
+// and https://github.com/WICG/web-codecs/blob/master/explainer.md.
+[
+ RuntimeEnabled=WebCodecs
+] interface VideoTrackWriter {
+ [CallWith=ScriptState, RaisesException]
+ constructor(VideoTrackWriterParameters params);
+ readonly attribute WritableStream writable; // of VideoFrame
+ readonly attribute MediaStreamTrack track;
+}; \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer_parameters.idl b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer_parameters.idl
new file mode 100644
index 00000000000..7687d4949b3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer_parameters.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.
+
+// See spec in developement at https://github.com/WICG/web-codecs/blob/master/index.bs
+// and https://github.com/WICG/web-codecs/blob/master/explainer.md.
+dictionary VideoTrackWriterParameters {
+ boolean releaseFrames = true;
+}; \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/webcodecs_error_callback.idl b/chromium/third_party/blink/renderer/modules/webcodecs/webcodecs_error_callback.idl
new file mode 100644
index 00000000000..4dcaf89f186
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webcodecs/webcodecs_error_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 WebCodecsErrorCallback = void(DOMException error);
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/DEPS b/chromium/third_party/blink/renderer/modules/webdatabase/DEPS
index 4d65cedbcd8..0d01ddacadd 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/DEPS
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/DEPS
@@ -1,7 +1,6 @@
include_rules = [
"+base/files/file.h",
"+base/task/task_traits.h",
- "+mojo/public/cpp/bindings/strong_binding.h",
"-third_party/blink/renderer/modules",
"+third_party/blink/renderer/modules/modules_export.h",
"+third_party/blink/renderer/modules/webdatabase",
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database.cc b/chromium/third_party/blink/renderer/modules/webdatabase/database.cc
index a7c8d8a1018..2f617dd4aa6 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database.cc
@@ -51,6 +51,7 @@
#include "third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_transaction.h"
#include "third_party/blink/renderer/modules/webdatabase/storage_log.h"
#include "third_party/blink/renderer/modules/webdatabase/web_database_host.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
@@ -269,7 +270,7 @@ Database::~Database() {
DCHECK(!Opened());
}
-void Database::Trace(blink::Visitor* visitor) {
+void Database::Trace(Visitor* visitor) {
visitor->Trace(database_context_);
ScriptWrappable::Trace(visitor);
}
@@ -746,9 +747,9 @@ void Database::ReportSqliteError(int sqlite_error_code) {
}
void Database::LogErrorMessage(const String& message) {
- GetExecutionContext()->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kStorage,
- mojom::ConsoleMessageLevel::kError, message));
+ GetExecutionContext()->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kStorage, mojom::ConsoleMessageLevel::kError,
+ message));
}
ExecutionContext* Database::GetExecutionContext() const {
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database.h b/chromium/third_party/blink/renderer/modules/webdatabase/database.h
index d9563c6ca28..4c51c655b2a 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database.h
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database.h
@@ -59,7 +59,7 @@ class Database final : public ScriptWrappable {
const String& display_name,
uint32_t estimated_size);
~Database() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
bool OpenAndVerifyVersion(bool set_version_in_new_database,
DatabaseError&,
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database.idl b/chromium/third_party/blink/renderer/modules/webdatabase/database.idl
index 7b03a4cf639..b9a96a6ccbc 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database.idl
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database.idl
@@ -33,11 +33,11 @@
readonly attribute DOMString version;
// TODO(crbug.com/841185): |callback|, |errorCallback|, and
// |successCallback| are not nullable in the spec.
- [Measure] void changeVersion(DOMString oldVersion, DOMString newVersion, optional SQLTransactionCallback? callback, optional SQLTransactionErrorCallback? errorCallback, optional VoidCallback? successCallback);
+ [Measure] void changeVersion(DOMString oldVersion, DOMString newVersion, optional SQLTransactionCallback? callback = null, optional SQLTransactionErrorCallback? errorCallback = null, optional VoidCallback? successCallback = null);
// TODO(crbug.com/841185): |errorCallback| and |successCallback| are not
// nullable in the spec.
- [Measure] void transaction(SQLTransactionCallback callback, optional SQLTransactionErrorCallback? errorCallback, optional VoidCallback? successCallback);
+ [Measure] void transaction(SQLTransactionCallback callback, optional SQLTransactionErrorCallback? errorCallback = null, optional VoidCallback? successCallback = null);
// TODO(crbug.com/841185): |errorCallback| and |successCallback| are not
// nullable in the spec.
- [Measure] void readTransaction(SQLTransactionCallback callback, optional SQLTransactionErrorCallback? errorCallback, optional VoidCallback? successCallback);
+ [Measure] void readTransaction(SQLTransactionCallback callback, optional SQLTransactionErrorCallback? errorCallback = null, optional VoidCallback? successCallback = null);
};
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database_authorizer.cc b/chromium/third_party/blink/renderer/modules/webdatabase/database_authorizer.cc
index 21c8f66d0fe..ad57dc43fdd 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database_authorizer.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_authorizer.cc
@@ -339,13 +339,13 @@ int DatabaseAuthorizer::DenyBasedOnTableName(const String& table_name) const {
// Sadly, normal creates and drops end up affecting sqlite_master in an
// authorizer callback, so it will be tough to enforce all of the following
// policies:
- // if (equalIgnoringCase(tableName, "sqlite_master") ||
- // equalIgnoringCase(tableName, "sqlite_temp_master") ||
- // equalIgnoringCase(tableName, "sqlite_sequence") ||
- // equalIgnoringCase(tableName, Database::databaseInfoTableName()))
+ // if (EqualIgnoringASCIICase(table_name, "sqlite_master") ||
+ // EqualIgnoringASCIICase(table_name, "sqlite_temp_master") ||
+ // EqualIgnoringASCIICase(table_name, "sqlite_sequence") ||
+ // EqualIgnoringASCIICase(table_name, database_info_table_name_))
// return SQLAuthDeny;
- if (DeprecatedEqualIgnoringCase(table_name, database_info_table_name_))
+ if (EqualIgnoringASCIICase(table_name, database_info_table_name_))
return kSQLAuthDeny;
return kSQLAuthAllow;
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 5b0a433b932..d3cd7b99bc9 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(blink::Visitor* visitor) {
+void DatabaseClient::Trace(Visitor* visitor) {
visitor->Trace(inspector_agent_);
Supplement<Page>::Trace(visitor);
}
@@ -51,14 +51,14 @@ DatabaseClient* DatabaseClient::FromPage(Page* page) {
}
DatabaseClient* DatabaseClient::From(ExecutionContext* context) {
- return DatabaseClient::FromPage(To<Document>(context)->GetPage());
+ return DatabaseClient::FromPage(Document::From(context)->GetPage());
}
const char DatabaseClient::kSupplementName[] = "DatabaseClient";
bool DatabaseClient::AllowDatabase(ExecutionContext* context) {
DCHECK(context->IsContextThread());
- Document* document = To<Document>(context);
+ Document* document = Document::From(context);
if (auto* client = document->GetFrame()->GetContentSettingsClient())
return client->AllowDatabase();
return true;
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 583f4f529c0..a365f41fd4e 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 a77f1304e75..a026b224bd7 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database_context.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_context.cc
@@ -69,8 +69,8 @@ namespace blink {
// 1. "outlive" the ExecutionContext.
// - This is needed because the DatabaseContext needs to remove itself from
// the
-// ExecutionContext's ContextLifecycleObserver list and
-// ContextLifecycleObserver
+// ExecutionContext's ExecutionContextLifecycleObserver list and
+// ExecutionContextLifecycleObserver
// list. This removal needs to be executed on the script's thread. Hence,
// we
// rely on the ExecutionContext's shutdown process to call
@@ -99,7 +99,7 @@ DatabaseContext* DatabaseContext::Create(ExecutionContext* context) {
}
DatabaseContext::DatabaseContext(ExecutionContext* context)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
has_open_databases_(false),
has_requested_termination_(false) {
DCHECK(IsMainThread());
@@ -115,9 +115,9 @@ DatabaseContext::~DatabaseContext() {
DatabaseManager::Manager().DidDestructDatabaseContext();
}
-void DatabaseContext::Trace(blink::Visitor* visitor) {
+void DatabaseContext::Trace(Visitor* visitor) {
visitor->Trace(database_thread_);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
// This is called if the associated ExecutionContext is destructing while
@@ -125,7 +125,7 @@ void DatabaseContext::Trace(blink::Visitor* visitor) {
// To do this, we stop the database and let everything shutdown naturally
// because the database closing process may still make use of this context.
// It is not safe to just delete the context here.
-void DatabaseContext::ContextDestroyed(ExecutionContext*) {
+void DatabaseContext::ContextDestroyed() {
StopDatabases();
DatabaseManager::Manager().UnregisterDatabaseContext(this);
}
@@ -175,7 +175,7 @@ void DatabaseContext::StopDatabases() {
}
bool DatabaseContext::AllowDatabaseAccess() const {
- return To<Document>(GetExecutionContext())->IsActive();
+ return Document::From(GetExecutionContext())->IsActive();
}
const SecurityOrigin* DatabaseContext::GetSecurityOrigin() const {
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 cb56a462f5d..ec86707519d 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database_context.h
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_context.h
@@ -28,7 +28,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBDATABASE_DATABASE_CONTEXT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBDATABASE_DATABASE_CONTEXT_H_
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
@@ -39,7 +39,7 @@ class ExecutionContext;
class SecurityOrigin;
class DatabaseContext final : public GarbageCollected<DatabaseContext>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(DatabaseContext);
public:
@@ -49,10 +49,11 @@ class DatabaseContext final : public GarbageCollected<DatabaseContext>,
explicit DatabaseContext(ExecutionContext*);
~DatabaseContext();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
- // For life-cycle management (inherited from ContextLifecycleObserver):
- void ContextDestroyed(ExecutionContext*) override;
+ // For life-cycle management (inherited from
+ // ExecutionContextLifecycleObserver):
+ void ContextDestroyed() override;
DatabaseContext* Backend();
DatabaseThread* GetDatabaseThread();
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database_manager.cc b/chromium/third_party/blink/renderer/modules/webdatabase/database_manager.cc
index 7c9b9ade610..af523812951 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_manager.cc
@@ -36,6 +36,7 @@
#include "third_party/blink/renderer/modules/webdatabase/database_tracker.h"
#include "third_party/blink/renderer/modules/webdatabase/storage_log.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/weborigin/security_origin.h"
namespace blink {
@@ -199,9 +200,9 @@ String DatabaseManager::FullPathForDatabase(const SecurityOrigin* origin,
void DatabaseManager::LogErrorMessage(ExecutionContext* context,
const String& message) {
- context->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kStorage,
- mojom::ConsoleMessageLevel::kError, message));
+ context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kStorage, mojom::ConsoleMessageLevel::kError,
+ message));
}
} // namespace blink
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 1fb21e72feb..f2f35ff8091 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(blink::Visitor* visitor) {}
+void DatabaseThread::Trace(Visitor* visitor) {}
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 3f5faf80f52..5fc1d1919f2 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(blink::Visitor*);
+ void Trace(Visitor*);
// Callable only from the main thread.
void Start();
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database_tracker.cc b/chromium/third_party/blink/renderer/modules/webdatabase/database_tracker.cc
index b19c0bd7a94..e9261a38ea6 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/database_tracker.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_tracker.cc
@@ -203,7 +203,7 @@ void DatabaseTracker::ForEachOpenDatabaseInPage(Page* page,
for (auto& name_database_set : *origin_map.value) {
for (Database* database : *name_database_set.value) {
ExecutionContext* context = database->GetExecutionContext();
- if (To<Document>(context)->GetPage() == page)
+ if (Document::From(context)->GetPage() == page)
callback.Run(database);
}
}
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/dom_window_web_database.cc b/chromium/third_party/blink/renderer/modules/webdatabase/dom_window_web_database.cc
index 125012edd3b..fdefa087ee4 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/dom_window_web_database.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/dom_window_web_database.cc
@@ -69,9 +69,9 @@ Database* DOMWindowWebDatabase::openDatabase(
UseCounter::Count(window.document(), WebFeature::kFileAccessedDatabase);
String error_message;
- database = db_manager.OpenDatabase(window.document(), name, version,
- display_name, estimated_size,
- creation_callback, error, error_message);
+ database = db_manager.OpenDatabase(
+ window.document()->ToExecutionContext(), name, version, display_name,
+ estimated_size, creation_callback, error, error_message);
DCHECK(database || error != DatabaseError::kNone);
if (error != DatabaseError::kNone)
DatabaseManager::ThrowExceptionForDatabaseError(error, error_message,
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/idls.gni b/chromium/third_party/blink/renderer/modules/webdatabase/idls.gni
new file mode 100644
index 00000000000..3877456b354
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "database.idl",
+ "sql_error.idl",
+ "sql_result_set.idl",
+ "sql_result_set_row_list.idl",
+ "sql_statement_callback.idl",
+ "sql_statement_error_callback.idl",
+ "sql_transaction.idl",
+ "sql_transaction_callback.idl",
+ "sql_transaction_error_callback.idl",
+]
+
+modules_dependency_idl_files = [ "window_web_database.idl" ]
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 01d716fe2e1..8f15d7530af 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
@@ -235,20 +235,20 @@ void InspectorDatabaseAgent::InnerEnable() {
Response InspectorDatabaseAgent::enable() {
if (enabled_.Get())
- return Response::OK();
+ return Response::Success();
enabled_.Set(true);
InnerEnable();
- return Response::OK();
+ return Response::Success();
}
Response InspectorDatabaseAgent::disable() {
if (!enabled_.Get())
- return Response::OK();
+ return Response::Success();
enabled_.Set(false);
if (DatabaseClient* client = DatabaseClient::FromPage(page_))
client->SetInspectorAgent(nullptr);
resources_.clear();
- return Response::OK();
+ return Response::Success();
}
void InspectorDatabaseAgent::Restore() {
@@ -260,7 +260,7 @@ Response InspectorDatabaseAgent::getDatabaseTableNames(
const String& database_id,
std::unique_ptr<protocol::Array<String>>* names) {
if (!enabled_.Get())
- return Response::Error("Database agent is not enabled");
+ return Response::ServerError("Database agent is not enabled");
blink::Database* database = DatabaseForId(database_id);
if (database) {
@@ -270,7 +270,7 @@ Response InspectorDatabaseAgent::getDatabaseTableNames(
} else {
*names = std::make_unique<protocol::Array<String>>();
}
- return Response::OK();
+ return Response::Success();
}
void InspectorDatabaseAgent::executeSQL(
@@ -282,13 +282,13 @@ void InspectorDatabaseAgent::executeSQL(
if (!enabled_.Get()) {
request_callback->sendFailure(
- Response::Error("Database agent is not enabled"));
+ Response::ServerError("Database agent is not enabled"));
return;
}
blink::Database* database = DatabaseForId(database_id);
if (!database) {
- request_callback->sendFailure(Response::Error("Database not found"));
+ request_callback->sendFailure(Response::ServerError("Database not found"));
return;
}
@@ -319,7 +319,7 @@ blink::Database* InspectorDatabaseAgent::DatabaseForId(
return it->value->GetDatabase();
}
-void InspectorDatabaseAgent::Trace(blink::Visitor* visitor) {
+void InspectorDatabaseAgent::Trace(Visitor* visitor) {
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 9b9e502bff4..ac8b61500ab 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 8926d251f48..99adeecae35 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(blink::Visitor* visitor) {
+void InspectorDatabaseResource::Trace(Visitor* visitor) {
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 19490afaa05..942e78c55f9 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(blink::Visitor*);
+ void Trace(Visitor*);
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 b9741826656..4a5cc455390 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(blink::Visitor* visitor) {
+void SQLResultSet::Trace(Visitor* visitor) {
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 5afa63aed05..12d6155180f 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 c5a0fcec3e7..d0b2a1f4d71 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(blink::Visitor* visitor) {
+void SQLStatement::OnSuccessV8Impl::Trace(Visitor* visitor) {
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(blink::Visitor* visitor) {
+void SQLStatement::OnErrorV8Impl::Trace(Visitor* visitor) {
visitor->Trace(callback_);
OnErrorCallback::Trace(visitor);
}
@@ -94,7 +94,7 @@ SQLStatement::SQLStatement(Database* database,
}
}
-void SQLStatement::Trace(blink::Visitor* visitor) {
+void SQLStatement::Trace(Visitor* visitor) {
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 dfe45739142..5bae74b432a 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(blink::Visitor*) {}
+ virtual void Trace(Visitor*) {}
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(blink::Visitor*) override;
+ void Trace(Visitor*) 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(blink::Visitor*) {}
+ virtual void Trace(Visitor*) {}
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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
bool OnError(SQLTransaction*, SQLError*) override;
private:
@@ -102,7 +102,7 @@ class SQLStatement final : public GarbageCollected<SQLStatement> {
SQLStatement(Database*, OnSuccessCallback*, OnErrorCallback*);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
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 7110120b3e6..9dbfb876585 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(blink::Visitor* visitor) {
+void SQLStatementBackend::Trace(Visitor* visitor) {
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 788633e4a14..96fe7ac6d2e 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(blink::Visitor*);
+ void Trace(Visitor*);
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 776d50e2724..b1a68bc895d 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(blink::Visitor* visitor) {
+void SQLTransaction::OnProcessV8Impl::Trace(Visitor* visitor) {
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(blink::Visitor* visitor) {
+void SQLTransaction::OnSuccessV8Impl::Trace(Visitor* visitor) {
visitor->Trace(callback_);
OnSuccessCallback::Trace(visitor);
}
@@ -67,7 +67,7 @@ void SQLTransaction::OnSuccessV8Impl::OnSuccess() {
callback_->InvokeAndReportException(nullptr);
}
-void SQLTransaction::OnErrorV8Impl::Trace(blink::Visitor* visitor) {
+void SQLTransaction::OnErrorV8Impl::Trace(Visitor* visitor) {
visitor->Trace(callback_);
OnErrorCallback::Trace(visitor);
}
@@ -109,7 +109,7 @@ SQLTransaction::SQLTransaction(Database* db,
SQLTransaction::~SQLTransaction() = default;
-void SQLTransaction::Trace(blink::Visitor* visitor) {
+void SQLTransaction::Trace(Visitor* visitor) {
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 74d99c733fe..3ee9e458216 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(blink::Visitor*) {}
+ virtual void Trace(Visitor*) {}
virtual bool OnProcess(SQLTransaction*) = 0;
protected:
@@ -76,7 +76,7 @@ class SQLTransaction final : public ScriptWrappable,
explicit OnProcessV8Impl(V8SQLTransactionCallback* callback)
: callback_(callback) {}
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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(blink::Visitor*) {}
+ virtual void Trace(Visitor*) {}
virtual void OnSuccess() = 0;
protected:
@@ -102,7 +102,7 @@ class SQLTransaction final : public ScriptWrappable,
explicit OnSuccessV8Impl(V8VoidCallback* callback) : callback_(callback) {}
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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(blink::Visitor*) {}
+ virtual void Trace(Visitor*) {}
virtual bool OnError(SQLError*) = 0;
protected:
@@ -128,7 +128,7 @@ class SQLTransaction final : public ScriptWrappable,
explicit OnErrorV8Impl(V8SQLTransactionErrorCallback* callback)
: callback_(callback) {}
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
bool OnError(SQLError*) override;
private:
@@ -147,7 +147,7 @@ class SQLTransaction final : public ScriptWrappable,
OnErrorCallback*,
bool read_only);
~SQLTransaction() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void PerformPendingCallback();
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.idl b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.idl
index b116ce496c2..01ca792addd 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.idl
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.idl
@@ -39,6 +39,6 @@ typedef sequence<any> ObjectArray;
// nullable in the spec.
[Measure, RaisesException, CallWith=ScriptState] void executeSql(DOMString sqlStatement,
optional ObjectArray? arguments,
- optional SQLStatementCallback? callback,
- optional SQLStatementErrorCallback? errorCallback);
+ optional SQLStatementCallback? callback = null,
+ optional SQLStatementErrorCallback? errorCallback = null);
};
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 b71b5f50c60..24dfe898d33 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(blink::Visitor* visitor) {
+void SQLTransactionBackend::Trace(Visitor* visitor) {
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 8c82b2eeb08..aa5b1fbd5b6 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(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
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(blink::Visitor*);
+ void Trace(Visitor*);
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 8298bddcbef..0be02921b2b 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(blink::Visitor* visitor) {}
+void SQLTransactionCoordinator::Trace(Visitor* visitor) {}
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 593bc5b3293..823da7e53bc 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(blink::Visitor*);
+ void Trace(Visitor*);
void AcquireLock(SQLTransactionBackend*);
void ReleaseLock(SQLTransactionBackend*);
void Shutdown();
diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/web_database_host.cc b/chromium/third_party/blink/renderer/modules/webdatabase/web_database_host.cc
index 1d7c1ef91ce..d3615747f14 100644
--- a/chromium/third_party/blink/renderer/modules/webdatabase/web_database_host.cc
+++ b/chromium/third_party/blink/renderer/modules/webdatabase/web_database_host.cc
@@ -9,8 +9,9 @@
#include "base/single_thread_task_runner.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
+#include "base/task/thread_pool.h"
+#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/webdatabase/web_database.mojom-blink.h"
-#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -27,7 +28,7 @@ WebDatabaseHost& WebDatabaseHost::GetInstance() {
}
void WebDatabaseHost::Init() {
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
pending_remote_.InitWithNewPipeAndPassReceiver());
}
@@ -38,9 +39,8 @@ mojom::blink::WebDatabaseHost& WebDatabaseHost::GetWebDatabaseHost() {
if (!shared_remote_) {
DCHECK(pending_remote_);
shared_remote_ = mojo::SharedRemote<mojom::blink::WebDatabaseHost>(
- std::move(pending_remote_),
- base::CreateSequencedTaskRunner(
- {base::ThreadPool(), base::WithBaseSyncPrimitives()}));
+ std::move(pending_remote_), base::ThreadPool::CreateSequencedTaskRunner(
+ {base::WithBaseSyncPrimitives()}));
}
return *shared_remote_;
diff --git a/chromium/third_party/blink/renderer/modules/webgl/BUILD.gn b/chromium/third_party/blink/renderer/modules/webgl/BUILD.gn
index 7627bd0d969..e64e0c2e102 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/webgl/BUILD.gn
@@ -26,8 +26,14 @@ blink_modules_sources("webgl") {
"ext_shader_texture_lod.h",
"ext_srgb.cc",
"ext_srgb.h",
+ "ext_texture_compression_bptc.cc",
+ "ext_texture_compression_bptc.h",
+ "ext_texture_compression_rgtc.cc",
+ "ext_texture_compression_rgtc.h",
"ext_texture_filter_anisotropic.cc",
"ext_texture_filter_anisotropic.h",
+ "ext_texture_norm_16.cc",
+ "ext_texture_norm_16.h",
"gl_string_query.h",
"khr_parallel_shader_compile.cc",
"khr_parallel_shader_compile.h",
@@ -141,8 +147,6 @@ blink_modules_sources("webgl") {
"webgl_vertex_array_object_base.h",
"webgl_vertex_array_object_oes.cc",
"webgl_vertex_array_object_oes.h",
- "webgl_video_frame_metadata.cc",
- "webgl_video_frame_metadata.h",
"webgl_video_texture.cc",
"webgl_video_texture.h",
"webgl_video_texture_enum.h",
diff --git a/chromium/third_party/blink/renderer/modules/webgl/DEPS b/chromium/third_party/blink/renderer/modules/webgl/DEPS
index 7f39fad499d..d0ca58d0939 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/DEPS
+++ b/chromium/third_party/blink/renderer/modules/webgl/DEPS
@@ -2,6 +2,7 @@ include_rules = [
"+base/containers/mru_cache.h",
"+gpu/GLES2/gl2extchromium.h",
"+gpu/command_buffer/client/gles2_interface.h",
+ "+gpu/command_buffer/client/raster_interface.h",
"+gpu/command_buffer/common/capabilities.h",
"+gpu/config/gpu_feature_info.h",
"+skia/ext",
diff --git a/chromium/third_party/blink/renderer/modules/webgl/OWNERS b/chromium/third_party/blink/renderer/modules/webgl/OWNERS
index 5eeccc4842c..5a7463513ec 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/webgl/OWNERS
@@ -2,5 +2,6 @@ bajones@chromium.org
kainino@chromium.org
kbr@chromium.org
zmo@chromium.org
+jdarpinian@chromium.org
# COMPONENT: Blink>WebGL
diff --git a/chromium/third_party/blink/renderer/modules/webgl/angle_instanced_arrays.cc b/chromium/third_party/blink/renderer/modules/webgl/angle_instanced_arrays.cc
index d71f56d33ff..f002377019a 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/angle_instanced_arrays.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/angle_instanced_arrays.cc
@@ -44,11 +44,6 @@ WebGLExtensionName ANGLEInstancedArrays::GetName() const {
return kANGLEInstancedArraysName;
}
-ANGLEInstancedArrays* ANGLEInstancedArrays::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<ANGLEInstancedArrays>(context);
-}
-
bool ANGLEInstancedArrays::Supported(WebGLRenderingContextBase* context) {
return context->ExtensionsUtil()->SupportsExtension(
"GL_ANGLE_instanced_arrays");
diff --git a/chromium/third_party/blink/renderer/modules/webgl/angle_instanced_arrays.h b/chromium/third_party/blink/renderer/modules/webgl/angle_instanced_arrays.h
index 969bf15d9d0..1cce2f5320b 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/angle_instanced_arrays.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/angle_instanced_arrays.h
@@ -40,7 +40,6 @@ class ANGLEInstancedArrays final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static ANGLEInstancedArrays* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_blend_min_max.cc b/chromium/third_party/blink/renderer/modules/webgl/ext_blend_min_max.cc
index 9ccc0f19eaa..66bdf90ee68 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/ext_blend_min_max.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_blend_min_max.cc
@@ -15,10 +15,6 @@ WebGLExtensionName EXTBlendMinMax::GetName() const {
return kEXTBlendMinMaxName;
}
-EXTBlendMinMax* EXTBlendMinMax::Create(WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<EXTBlendMinMax>(context);
-}
-
bool EXTBlendMinMax::Supported(WebGLRenderingContextBase* context) {
return context->ExtensionsUtil()->SupportsExtension("GL_EXT_blend_minmax");
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_blend_min_max.h b/chromium/third_party/blink/renderer/modules/webgl/ext_blend_min_max.h
index 09598f29db3..6fa05b0a7a5 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/ext_blend_min_max.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_blend_min_max.h
@@ -13,7 +13,6 @@ class EXTBlendMinMax final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static EXTBlendMinMax* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_color_buffer_float.cc b/chromium/third_party/blink/renderer/modules/webgl/ext_color_buffer_float.cc
index f6110ae9b6d..ff2aed72e07 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/ext_color_buffer_float.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_color_buffer_float.cc
@@ -20,11 +20,6 @@ WebGLExtensionName EXTColorBufferFloat::GetName() const {
return kEXTColorBufferFloatName;
}
-EXTColorBufferFloat* EXTColorBufferFloat::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<EXTColorBufferFloat>(context);
-}
-
bool EXTColorBufferFloat::Supported(WebGLRenderingContextBase* context) {
return context->ExtensionsUtil()->SupportsExtension(
"GL_EXT_color_buffer_float");
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_color_buffer_float.h b/chromium/third_party/blink/renderer/modules/webgl/ext_color_buffer_float.h
index 15a85874ae2..490d56b1d24 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/ext_color_buffer_float.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_color_buffer_float.h
@@ -13,7 +13,6 @@ class EXTColorBufferFloat final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static EXTColorBufferFloat* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_color_buffer_half_float.cc b/chromium/third_party/blink/renderer/modules/webgl/ext_color_buffer_half_float.cc
index 82bd7bc0ad0..6581e588127 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/ext_color_buffer_half_float.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_color_buffer_half_float.cc
@@ -35,11 +35,6 @@ WebGLExtensionName EXTColorBufferHalfFloat::GetName() const {
return kEXTColorBufferHalfFloatName;
}
-EXTColorBufferHalfFloat* EXTColorBufferHalfFloat::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<EXTColorBufferHalfFloat>(context);
-}
-
bool EXTColorBufferHalfFloat::Supported(WebGLRenderingContextBase* context) {
return context->ExtensionsUtil()->SupportsExtension(
"GL_OES_texture_half_float") &&
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_color_buffer_half_float.h b/chromium/third_party/blink/renderer/modules/webgl/ext_color_buffer_half_float.h
index e82ec1b7d6b..c40fd092bca 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/ext_color_buffer_half_float.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_color_buffer_half_float.h
@@ -34,7 +34,6 @@ class EXTColorBufferHalfFloat final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static EXTColorBufferHalfFloat* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
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 aa45e44a2ad..4470f4dd747 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
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/bindings/modules/v8/webgl_any.h"
#include "third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h"
#include "third_party/blink/renderer/modules/webgl/webgl_timer_query_ext.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
@@ -15,11 +16,6 @@ WebGLExtensionName EXTDisjointTimerQuery::GetName() const {
return kEXTDisjointTimerQueryName;
}
-EXTDisjointTimerQuery* EXTDisjointTimerQuery::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<EXTDisjointTimerQuery>(context);
-}
-
bool EXTDisjointTimerQuery::Supported(WebGLRenderingContextBase* context) {
return context->ExtensionsUtil()->SupportsExtension(
"GL_EXT_disjoint_timer_query");
@@ -34,7 +30,7 @@ WebGLTimerQueryEXT* EXTDisjointTimerQuery::createQueryEXT() {
if (scoped.IsLost())
return nullptr;
- return WebGLTimerQueryEXT::Create(scoped.Context());
+ return MakeGarbageCollected<WebGLTimerQueryEXT>(scoped.Context());
}
void EXTDisjointTimerQuery::deleteQueryEXT(WebGLTimerQueryEXT* query) {
@@ -205,7 +201,7 @@ ScriptValue EXTDisjointTimerQuery::getQueryObjectEXT(ScriptState* script_state,
return ScriptValue::CreateNull(script_state->GetIsolate());
}
-void EXTDisjointTimerQuery::Trace(blink::Visitor* visitor) {
+void EXTDisjointTimerQuery::Trace(Visitor* visitor) {
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 2a1e205caae..1cbb778a40f 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
@@ -18,7 +18,6 @@ class EXTDisjointTimerQuery final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static EXTDisjointTimerQuery* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
@@ -35,7 +34,7 @@ class EXTDisjointTimerQuery final : public WebGLExtension {
ScriptValue getQueryEXT(ScriptState*, GLenum, GLenum);
ScriptValue getQueryObjectEXT(ScriptState*, WebGLTimerQueryEXT*, GLenum);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 7e94d11109b..972eb8a0217 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
@@ -14,13 +14,6 @@ WebGLExtensionName EXTDisjointTimerQueryWebGL2::GetName() const {
return kEXTDisjointTimerQueryWebGL2Name;
}
-EXTDisjointTimerQueryWebGL2* EXTDisjointTimerQueryWebGL2::Create(
- WebGLRenderingContextBase* context) {
- EXTDisjointTimerQueryWebGL2* o =
- MakeGarbageCollected<EXTDisjointTimerQueryWebGL2>(context);
- return o;
-}
-
bool EXTDisjointTimerQueryWebGL2::Supported(
WebGLRenderingContextBase* context) {
return context->ExtensionsUtil()->SupportsExtension(
@@ -58,7 +51,7 @@ void EXTDisjointTimerQueryWebGL2::queryCounterEXT(WebGLQuery* query,
query->ResetCachedResult();
}
-void EXTDisjointTimerQueryWebGL2::Trace(blink::Visitor* visitor) {
+void EXTDisjointTimerQueryWebGL2::Trace(Visitor* visitor) {
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 8ff994aa549..e383cff3902 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
@@ -19,7 +19,6 @@ class EXTDisjointTimerQueryWebGL2 final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static EXTDisjointTimerQueryWebGL2* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
@@ -29,7 +28,7 @@ class EXTDisjointTimerQueryWebGL2 final : public WebGLExtension {
void queryCounterEXT(WebGLQuery*, GLenum);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_float_blend.cc b/chromium/third_party/blink/renderer/modules/webgl/ext_float_blend.cc
index f55b5e6c763..ab91c001841 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/ext_float_blend.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_float_blend.cc
@@ -15,10 +15,6 @@ WebGLExtensionName EXTFloatBlend::GetName() const {
return kEXTFloatBlendName;
}
-EXTFloatBlend* EXTFloatBlend::Create(WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<EXTFloatBlend>(context);
-}
-
bool EXTFloatBlend::Supported(WebGLRenderingContextBase* context) {
return context->ExtensionsUtil()->SupportsExtension("GL_EXT_float_blend");
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_float_blend.h b/chromium/third_party/blink/renderer/modules/webgl/ext_float_blend.h
index 5a428d84177..27df92e0dd2 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/ext_float_blend.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_float_blend.h
@@ -13,7 +13,6 @@ class EXTFloatBlend final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static EXTFloatBlend* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_frag_depth.cc b/chromium/third_party/blink/renderer/modules/webgl/ext_frag_depth.cc
index e5e78867a1d..ccfc6e5f9d1 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/ext_frag_depth.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_frag_depth.cc
@@ -36,10 +36,6 @@ WebGLExtensionName EXTFragDepth::GetName() const {
return kEXTFragDepthName;
}
-EXTFragDepth* EXTFragDepth::Create(WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<EXTFragDepth>(context);
-}
-
bool EXTFragDepth::Supported(WebGLRenderingContextBase* context) {
return context->ExtensionsUtil()->SupportsExtension("GL_EXT_frag_depth");
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_frag_depth.h b/chromium/third_party/blink/renderer/modules/webgl/ext_frag_depth.h
index 3d332a90cdf..2e5cdc32027 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/ext_frag_depth.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_frag_depth.h
@@ -34,7 +34,6 @@ class EXTFragDepth final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static EXTFragDepth* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_shader_texture_lod.cc b/chromium/third_party/blink/renderer/modules/webgl/ext_shader_texture_lod.cc
index a15db7a72af..61c435ced80 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/ext_shader_texture_lod.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_shader_texture_lod.cc
@@ -16,11 +16,6 @@ WebGLExtensionName EXTShaderTextureLOD::GetName() const {
return kEXTShaderTextureLODName;
}
-EXTShaderTextureLOD* EXTShaderTextureLOD::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<EXTShaderTextureLOD>(context);
-}
-
bool EXTShaderTextureLOD::Supported(WebGLRenderingContextBase* context) {
return context->ExtensionsUtil()->SupportsExtension(
"GL_EXT_shader_texture_lod");
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_shader_texture_lod.h b/chromium/third_party/blink/renderer/modules/webgl/ext_shader_texture_lod.h
index 1f8065e5ed0..cca5821ed1e 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/ext_shader_texture_lod.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_shader_texture_lod.h
@@ -13,7 +13,6 @@ class EXTShaderTextureLOD final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static EXTShaderTextureLOD* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_srgb.cc b/chromium/third_party/blink/renderer/modules/webgl/ext_srgb.cc
index bd28afaf3a2..09f0466bc20 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/ext_srgb.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_srgb.cc
@@ -16,10 +16,6 @@ WebGLExtensionName EXTsRGB::GetName() const {
return kEXTsRGBName;
}
-EXTsRGB* EXTsRGB::Create(WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<EXTsRGB>(context);
-}
-
bool EXTsRGB::Supported(WebGLRenderingContextBase* context) {
Extensions3DUtil* extensions_util = context->ExtensionsUtil();
return extensions_util->SupportsExtension("GL_EXT_sRGB");
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_srgb.h b/chromium/third_party/blink/renderer/modules/webgl/ext_srgb.h
index 673f3b9e690..27ab8a4385e 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/ext_srgb.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_srgb.h
@@ -13,7 +13,6 @@ class EXTsRGB final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static EXTsRGB* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_bptc.cc b/chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_bptc.cc
new file mode 100644
index 00000000000..5cc4efd56cd
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_bptc.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/modules/webgl/ext_texture_compression_bptc.h"
+
+#include "third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h"
+
+namespace blink {
+
+EXTTextureCompressionBPTC::EXTTextureCompressionBPTC(
+ WebGLRenderingContextBase* context)
+ : WebGLExtension(context) {
+ context->ExtensionsUtil()->EnsureExtensionEnabled(
+ "GL_EXT_texture_compression_bptc");
+ context->AddCompressedTextureFormat(GL_COMPRESSED_RGBA_BPTC_UNORM_EXT);
+ context->AddCompressedTextureFormat(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT);
+ context->AddCompressedTextureFormat(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT);
+ context->AddCompressedTextureFormat(
+ GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT);
+}
+
+WebGLExtensionName EXTTextureCompressionBPTC::GetName() const {
+ return kEXTTextureCompressionBPTCName;
+}
+
+bool EXTTextureCompressionBPTC::Supported(WebGLRenderingContextBase* context) {
+ Extensions3DUtil* extensions_util = context->ExtensionsUtil();
+ return extensions_util->SupportsExtension("GL_EXT_texture_compression_bptc");
+}
+
+const char* EXTTextureCompressionBPTC::ExtensionName() {
+ return "EXT_texture_compression_bptc";
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_bptc.h b/chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_bptc.h
new file mode 100644
index 00000000000..2608d9f5c70
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_bptc.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_EXT_TEXTURE_COMPRESSION_BPTC_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_EXT_TEXTURE_COMPRESSION_BPTC_H_
+
+#include "third_party/blink/renderer/modules/webgl/webgl_extension.h"
+
+namespace blink {
+
+class EXTTextureCompressionBPTC final : public WebGLExtension {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static bool Supported(WebGLRenderingContextBase*);
+ static const char* ExtensionName();
+
+ explicit EXTTextureCompressionBPTC(WebGLRenderingContextBase*);
+
+ WebGLExtensionName GetName() const override;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_EXT_TEXTURE_COMPRESSION_BPTC_H_
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_bptc.idl b/chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_bptc.idl
new file mode 100644
index 00000000000..1de39693cde
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_bptc.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.
+
+// https://www.khronos.org/registry/webgl/extensions/EXT_texture_compression_bptc/
+
+[
+ NoInterfaceObject,
+ DoNotCheckConstants
+] interface EXTTextureCompressionBPTC {
+ const unsigned long COMPRESSED_RGBA_BPTC_UNORM_EXT = 0x8E8C;
+ const unsigned long COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT = 0x8E8D;
+ const unsigned long COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT = 0x8E8E;
+ const unsigned long COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT = 0x8E8F;
+};
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_rgtc.cc b/chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_rgtc.cc
new file mode 100644
index 00000000000..e9071449d99
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_rgtc.cc
@@ -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.
+
+#include "third_party/blink/renderer/modules/webgl/ext_texture_compression_rgtc.h"
+
+#include "third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h"
+
+namespace blink {
+
+EXTTextureCompressionRGTC::EXTTextureCompressionRGTC(
+ WebGLRenderingContextBase* context)
+ : WebGLExtension(context) {
+ context->ExtensionsUtil()->EnsureExtensionEnabled(
+ "GL_EXT_texture_compression_rgtc");
+ context->AddCompressedTextureFormat(GL_COMPRESSED_RED_RGTC1_EXT);
+ context->AddCompressedTextureFormat(GL_COMPRESSED_SIGNED_RED_RGTC1_EXT);
+ context->AddCompressedTextureFormat(GL_COMPRESSED_RED_GREEN_RGTC2_EXT);
+ context->AddCompressedTextureFormat(GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT);
+}
+
+WebGLExtensionName EXTTextureCompressionRGTC::GetName() const {
+ return kEXTTextureCompressionRGTCName;
+}
+
+bool EXTTextureCompressionRGTC::Supported(WebGLRenderingContextBase* context) {
+ Extensions3DUtil* extensions_util = context->ExtensionsUtil();
+ return extensions_util->SupportsExtension("GL_EXT_texture_compression_rgtc");
+}
+
+const char* EXTTextureCompressionRGTC::ExtensionName() {
+ return "EXT_texture_compression_rgtc";
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_rgtc.h b/chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_rgtc.h
new file mode 100644
index 00000000000..05c4ea1f1a5
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_rgtc.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_EXT_TEXTURE_COMPRESSION_RGTC_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_EXT_TEXTURE_COMPRESSION_RGTC_H_
+
+#include "third_party/blink/renderer/modules/webgl/webgl_extension.h"
+
+namespace blink {
+
+class EXTTextureCompressionRGTC final : public WebGLExtension {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static bool Supported(WebGLRenderingContextBase*);
+ static const char* ExtensionName();
+
+ explicit EXTTextureCompressionRGTC(WebGLRenderingContextBase*);
+
+ WebGLExtensionName GetName() const override;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_EXT_TEXTURE_COMPRESSION_RGTC_H_
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_rgtc.idl b/chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_rgtc.idl
new file mode 100644
index 00000000000..f2762fab545
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_texture_compression_rgtc.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.
+
+// https://www.khronos.org/registry/webgl/extensions/EXT_texture_compression_rgtc/
+
+[
+ NoInterfaceObject,
+ DoNotCheckConstants
+] interface EXTTextureCompressionRGTC {
+ const unsigned long COMPRESSED_RED_RGTC1_EXT = 0x8DBB;
+ const unsigned long COMPRESSED_SIGNED_RED_RGTC1_EXT = 0x8DBC;
+ const unsigned long COMPRESSED_RED_GREEN_RGTC2_EXT = 0x8DBD;
+ const unsigned long COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT = 0x8DBE;
+};
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_texture_filter_anisotropic.cc b/chromium/third_party/blink/renderer/modules/webgl/ext_texture_filter_anisotropic.cc
index 31d33a985f6..8ac4eb74d22 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/ext_texture_filter_anisotropic.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_texture_filter_anisotropic.cc
@@ -38,11 +38,6 @@ WebGLExtensionName EXTTextureFilterAnisotropic::GetName() const {
return kEXTTextureFilterAnisotropicName;
}
-EXTTextureFilterAnisotropic* EXTTextureFilterAnisotropic::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<EXTTextureFilterAnisotropic>(context);
-}
-
bool EXTTextureFilterAnisotropic::Supported(
WebGLRenderingContextBase* context) {
return context->ExtensionsUtil()->SupportsExtension(
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_texture_filter_anisotropic.h b/chromium/third_party/blink/renderer/modules/webgl/ext_texture_filter_anisotropic.h
index 353e0487f78..ad58d8e9a7c 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/ext_texture_filter_anisotropic.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_texture_filter_anisotropic.h
@@ -34,7 +34,6 @@ class EXTTextureFilterAnisotropic final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static EXTTextureFilterAnisotropic* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_texture_norm_16.cc b/chromium/third_party/blink/renderer/modules/webgl/ext_texture_norm_16.cc
new file mode 100644
index 00000000000..5fc71e9ad30
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_texture_norm_16.cc
@@ -0,0 +1,30 @@
+// 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/ext_texture_norm_16.h"
+
+namespace blink {
+
+EXTTextureNorm16::EXTTextureNorm16(WebGLRenderingContextBase* context)
+ : WebGLExtension(context) {
+ context->ExtensionsUtil()->EnsureExtensionEnabled("GL_EXT_texture_norm16");
+}
+
+WebGLExtensionName EXTTextureNorm16::GetName() const {
+ return kEXTTextureNorm16Name;
+}
+
+EXTTextureNorm16* EXTTextureNorm16::Create(WebGLRenderingContextBase* context) {
+ return MakeGarbageCollected<EXTTextureNorm16>(context);
+}
+
+bool EXTTextureNorm16::Supported(WebGLRenderingContextBase* context) {
+ return context->ExtensionsUtil()->SupportsExtension("GL_EXT_texture_norm16");
+}
+
+const char* EXTTextureNorm16::ExtensionName() {
+ return "EXT_texture_norm16";
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_texture_norm_16.h b/chromium/third_party/blink/renderer/modules/webgl/ext_texture_norm_16.h
new file mode 100644
index 00000000000..67a4e405d5e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_texture_norm_16.h
@@ -0,0 +1,27 @@
+// 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_WEBGL_EXT_TEXTURE_NORM_16_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_EXT_TEXTURE_NORM_16_H_
+
+#include "third_party/blink/renderer/modules/webgl/webgl_extension.h"
+
+namespace blink {
+
+class EXTTextureNorm16 final : public WebGLExtension {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ static EXTTextureNorm16* Create(WebGLRenderingContextBase*);
+ static bool Supported(WebGLRenderingContextBase*);
+ static const char* ExtensionName();
+
+ explicit EXTTextureNorm16(WebGLRenderingContextBase*);
+
+ WebGLExtensionName GetName() const override;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_EXT_TEXTURE_NORM_16_H_
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_texture_norm_16.idl b/chromium/third_party/blink/renderer/modules/webgl/ext_texture_norm_16.idl
new file mode 100644
index 00000000000..38158d129bb
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgl/ext_texture_norm_16.idl
@@ -0,0 +1,19 @@
+// 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://www.khronos.org/registry/webgl/extensions/EXT_texture_norm16/
+
+[
+ NoInterfaceObject,
+ DoNotCheckConstants
+] interface EXTTextureNorm16 {
+ const unsigned long R16_EXT = 0x822A;
+ const unsigned long RG16_EXT = 0x822C;
+ const unsigned long RGB16_EXT = 0x8054;
+ const unsigned long RGBA16_EXT = 0x805B;
+ const unsigned long R16_SNORM_EXT = 0x8F98;
+ const unsigned long RG16_SNORM_EXT = 0x8F99;
+ const unsigned long RGB16_SNORM_EXT = 0x8F9A;
+ const unsigned long RGBA16_SNORM_EXT = 0x8F9B;
+};
diff --git a/chromium/third_party/blink/renderer/modules/webgl/idls.gni b/chromium/third_party/blink/renderer/modules/webgl/idls.gni
new file mode 100644
index 00000000000..8338ea61e5a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgl/idls.gni
@@ -0,0 +1,94 @@
+# 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/config.gni")
+
+# Note: WebGL extensions are the most frequently added IDL files and
+# don't go through Blink's Intent to Ship process. Instead, these are
+# discussed among all browser vendors within the WebGL working group
+# as defined by the process here:
+#
+# https://www.khronos.org/registry/webgl/extensions/
+#
+# and only enabled in any browser by default once all browsers are in
+# agreement that the extension is ready to ship.
+
+modules_idl_files = [
+ "angle_instanced_arrays.idl",
+ "ext_blend_min_max.idl",
+ "ext_color_buffer_float.idl",
+ "ext_color_buffer_half_float.idl",
+ "ext_disjoint_timer_query.idl",
+ "ext_disjoint_timer_query_webgl2.idl",
+ "ext_float_blend.idl",
+ "ext_frag_depth.idl",
+ "ext_shader_texture_lod.idl",
+ "ext_srgb.idl",
+ "ext_texture_compression_bptc.idl",
+ "ext_texture_compression_rgtc.idl",
+ "ext_texture_filter_anisotropic.idl",
+ "ext_texture_norm_16.idl",
+ "khr_parallel_shader_compile.idl",
+ "oes_element_index_uint.idl",
+ "oes_fbo_render_mipmap.idl",
+ "oes_standard_derivatives.idl",
+ "oes_texture_float.idl",
+ "oes_texture_float_linear.idl",
+ "oes_texture_half_float.idl",
+ "oes_texture_half_float_linear.idl",
+ "oes_vertex_array_object.idl",
+ "ovr_multiview_2.idl",
+ "webgl2_rendering_context.idl",
+ "webgl_active_info.idl",
+ "webgl_buffer.idl",
+ "webgl_color_buffer_float.idl",
+ "webgl_compressed_texture_astc.idl",
+ "webgl_compressed_texture_etc.idl",
+ "webgl_compressed_texture_etc1.idl",
+ "webgl_compressed_texture_pvrtc.idl",
+ "webgl_compressed_texture_s3tc.idl",
+ "webgl_compressed_texture_s3tc_srgb.idl",
+ "webgl_context_event.idl",
+ "webgl_debug_renderer_info.idl",
+ "webgl_debug_shaders.idl",
+ "webgl_depth_texture.idl",
+ "webgl_draw_buffers.idl",
+ "webgl_draw_instanced_base_vertex_base_instance.idl",
+ "webgl_framebuffer.idl",
+ "webgl_lose_context.idl",
+ "webgl_multi_draw_instanced_base_vertex_base_instance.idl",
+ "webgl_multi_draw.idl",
+ "webgl_program.idl",
+ "webgl_query.idl",
+ "webgl_renderbuffer.idl",
+ "webgl_rendering_context.idl",
+ "webgl_sampler.idl",
+ "webgl_shader.idl",
+ "webgl_shader_precision_format.idl",
+ "webgl_sync.idl",
+ "webgl_texture.idl",
+ "webgl_timer_query_ext.idl",
+ "webgl_transform_feedback.idl",
+ "webgl_uniform_location.idl",
+ "webgl_vertex_array_object.idl",
+ "webgl_vertex_array_object_oes.idl",
+ "webgl_video_texture.idl",
+]
+
+modules_dictionary_idl_files = [
+ "webgl_context_attributes.idl",
+ "webgl_context_event_init.idl",
+]
+
+modules_dependency_idl_files = [
+ "webgl2_rendering_context_base.idl",
+ "webgl_rendering_context_base.idl",
+]
+
+if (support_webgl2_compute_context) {
+ modules_idl_files += [ "webgl2_compute_rendering_context.idl" ]
+
+ modules_dependency_idl_files +=
+ [ "webgl2_compute_rendering_context_base.idl" ]
+}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.cc b/chromium/third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.cc
index db3a8c6e3ce..792e3657f82 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.cc
@@ -45,11 +45,6 @@ WebGLExtensionName KHRParallelShaderCompile::GetName() const {
return kKHRParallelShaderCompileName;
}
-KHRParallelShaderCompile* KHRParallelShaderCompile::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<KHRParallelShaderCompile>(context);
-}
-
bool KHRParallelShaderCompile::Supported(WebGLRenderingContextBase* context) {
return context->ExtensionsUtil()->SupportsExtension(
"GL_KHR_parallel_shader_compile");
diff --git a/chromium/third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.h b/chromium/third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.h
index 4739526d27d..03574a6e512 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.h
@@ -34,7 +34,6 @@ class KHRParallelShaderCompile final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static KHRParallelShaderCompile* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/oes_element_index_uint.cc b/chromium/third_party/blink/renderer/modules/webgl/oes_element_index_uint.cc
index e1b13e49ef2..1bd7339759a 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/oes_element_index_uint.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/oes_element_index_uint.cc
@@ -37,11 +37,6 @@ WebGLExtensionName OESElementIndexUint::GetName() const {
return kOESElementIndexUintName;
}
-OESElementIndexUint* OESElementIndexUint::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<OESElementIndexUint>(context);
-}
-
bool OESElementIndexUint::Supported(WebGLRenderingContextBase* context) {
return context->ExtensionsUtil()->SupportsExtension(
"GL_OES_element_index_uint");
diff --git a/chromium/third_party/blink/renderer/modules/webgl/oes_element_index_uint.h b/chromium/third_party/blink/renderer/modules/webgl/oes_element_index_uint.h
index 5e57acac62a..05c1ecf8cec 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/oes_element_index_uint.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/oes_element_index_uint.h
@@ -34,7 +34,6 @@ class OESElementIndexUint final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static OESElementIndexUint* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/oes_fbo_render_mipmap.cc b/chromium/third_party/blink/renderer/modules/webgl/oes_fbo_render_mipmap.cc
index c84e18b7351..c5649434665 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/oes_fbo_render_mipmap.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/oes_fbo_render_mipmap.cc
@@ -15,11 +15,6 @@ WebGLExtensionName OESFboRenderMipmap::GetName() const {
return kOESFboRenderMipmapName;
}
-OESFboRenderMipmap* OESFboRenderMipmap::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<OESFboRenderMipmap>(context);
-}
-
bool OESFboRenderMipmap::Supported(WebGLRenderingContextBase* context) {
return context->ExtensionsUtil()->SupportsExtension(
"GL_OES_fbo_render_mipmap");
diff --git a/chromium/third_party/blink/renderer/modules/webgl/oes_fbo_render_mipmap.h b/chromium/third_party/blink/renderer/modules/webgl/oes_fbo_render_mipmap.h
index cc2d7192627..bb06fbcc2db 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/oes_fbo_render_mipmap.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/oes_fbo_render_mipmap.h
@@ -13,7 +13,6 @@ class OESFboRenderMipmap final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static OESFboRenderMipmap* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/oes_standard_derivatives.cc b/chromium/third_party/blink/renderer/modules/webgl/oes_standard_derivatives.cc
index ff4b64bc2fb..925c825e689 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/oes_standard_derivatives.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/oes_standard_derivatives.cc
@@ -38,11 +38,6 @@ WebGLExtensionName OESStandardDerivatives::GetName() const {
return kOESStandardDerivativesName;
}
-OESStandardDerivatives* OESStandardDerivatives::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<OESStandardDerivatives>(context);
-}
-
bool OESStandardDerivatives::Supported(WebGLRenderingContextBase* context) {
return context->ExtensionsUtil()->SupportsExtension(
"GL_OES_standard_derivatives");
diff --git a/chromium/third_party/blink/renderer/modules/webgl/oes_standard_derivatives.h b/chromium/third_party/blink/renderer/modules/webgl/oes_standard_derivatives.h
index 5b6023632a1..0a33c0a94ed 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/oes_standard_derivatives.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/oes_standard_derivatives.h
@@ -34,7 +34,6 @@ class OESStandardDerivatives final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static OESStandardDerivatives* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/oes_texture_float.cc b/chromium/third_party/blink/renderer/modules/webgl/oes_texture_float.cc
index 1de054b254e..c7aebe23305 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/oes_texture_float.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/oes_texture_float.cc
@@ -47,10 +47,6 @@ WebGLExtensionName OESTextureFloat::GetName() const {
return kOESTextureFloatName;
}
-OESTextureFloat* OESTextureFloat::Create(WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<OESTextureFloat>(context);
-}
-
bool OESTextureFloat::Supported(WebGLRenderingContextBase* context) {
return context->ExtensionsUtil()->SupportsExtension("GL_OES_texture_float");
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/oes_texture_float.h b/chromium/third_party/blink/renderer/modules/webgl/oes_texture_float.h
index 95f64796bf4..2e54cee5b8b 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/oes_texture_float.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/oes_texture_float.h
@@ -34,7 +34,6 @@ class OESTextureFloat final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static OESTextureFloat* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/oes_texture_float_linear.cc b/chromium/third_party/blink/renderer/modules/webgl/oes_texture_float_linear.cc
index 588c758cc72..c9c667e0faf 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/oes_texture_float_linear.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/oes_texture_float_linear.cc
@@ -37,11 +37,6 @@ WebGLExtensionName OESTextureFloatLinear::GetName() const {
return kOESTextureFloatLinearName;
}
-OESTextureFloatLinear* OESTextureFloatLinear::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<OESTextureFloatLinear>(context);
-}
-
bool OESTextureFloatLinear::Supported(WebGLRenderingContextBase* context) {
return context->ExtensionsUtil()->SupportsExtension(
"GL_OES_texture_float_linear");
diff --git a/chromium/third_party/blink/renderer/modules/webgl/oes_texture_float_linear.h b/chromium/third_party/blink/renderer/modules/webgl/oes_texture_float_linear.h
index 5aa67dfd7c4..3950be5ca35 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/oes_texture_float_linear.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/oes_texture_float_linear.h
@@ -34,7 +34,6 @@ class OESTextureFloatLinear final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static OESTextureFloatLinear* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/oes_texture_half_float.cc b/chromium/third_party/blink/renderer/modules/webgl/oes_texture_half_float.cc
index ef44f4a4a5d..b12d2d0619e 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/oes_texture_half_float.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/oes_texture_half_float.cc
@@ -39,11 +39,6 @@ WebGLExtensionName OESTextureHalfFloat::GetName() const {
return kOESTextureHalfFloatName;
}
-OESTextureHalfFloat* OESTextureHalfFloat::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<OESTextureHalfFloat>(context);
-}
-
bool OESTextureHalfFloat::Supported(WebGLRenderingContextBase* context) {
return context->ExtensionsUtil()->SupportsExtension(
"GL_OES_texture_half_float");
diff --git a/chromium/third_party/blink/renderer/modules/webgl/oes_texture_half_float.h b/chromium/third_party/blink/renderer/modules/webgl/oes_texture_half_float.h
index 470c8aad6a0..822ac132808 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/oes_texture_half_float.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/oes_texture_half_float.h
@@ -34,7 +34,6 @@ class OESTextureHalfFloat final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static OESTextureHalfFloat* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/oes_texture_half_float_linear.cc b/chromium/third_party/blink/renderer/modules/webgl/oes_texture_half_float_linear.cc
index e17e2647472..af1e1aa3237 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/oes_texture_half_float_linear.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/oes_texture_half_float_linear.cc
@@ -38,11 +38,6 @@ WebGLExtensionName OESTextureHalfFloatLinear::GetName() const {
return kOESTextureHalfFloatLinearName;
}
-OESTextureHalfFloatLinear* OESTextureHalfFloatLinear::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<OESTextureHalfFloatLinear>(context);
-}
-
bool OESTextureHalfFloatLinear::Supported(WebGLRenderingContextBase* context) {
return context->ExtensionsUtil()->SupportsExtension(
"GL_OES_texture_half_float_linear");
diff --git a/chromium/third_party/blink/renderer/modules/webgl/oes_texture_half_float_linear.h b/chromium/third_party/blink/renderer/modules/webgl/oes_texture_half_float_linear.h
index 19405ae16e6..ed0873fdcd8 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/oes_texture_half_float_linear.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/oes_texture_half_float_linear.h
@@ -34,7 +34,6 @@ class OESTextureHalfFloatLinear final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static OESTextureHalfFloatLinear* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.cc b/chromium/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.cc
index bdb1fd9369b..2f2e2a16b51 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.cc
@@ -29,6 +29,7 @@
#include "third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h"
#include "third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_oes.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
@@ -42,17 +43,12 @@ WebGLExtensionName OESVertexArrayObject::GetName() const {
return kOESVertexArrayObjectName;
}
-OESVertexArrayObject* OESVertexArrayObject::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<OESVertexArrayObject>(context);
-}
-
WebGLVertexArrayObjectOES* OESVertexArrayObject::createVertexArrayOES() {
WebGLExtensionScopedContext scoped(this);
if (scoped.IsLost())
return nullptr;
- return WebGLVertexArrayObjectOES::Create(
+ return MakeGarbageCollected<WebGLVertexArrayObjectOES>(
scoped.Context(), WebGLVertexArrayObjectOES::kVaoTypeUser);
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.h b/chromium/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.h
index 98f87c978fa..f3f1e5f7f78 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.h
@@ -37,7 +37,6 @@ class OESVertexArrayObject final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static OESVertexArrayObject* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.idl b/chromium/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.idl
index 1c8ac283f5e..7f78d15ebc3 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.idl
+++ b/chromium/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.idl
@@ -32,7 +32,7 @@
const unsigned long VERTEX_ARRAY_BINDING_OES = 0x85B5;
WebGLVertexArrayObjectOES createVertexArrayOES();
- void deleteVertexArrayOES([DefaultValue=Undefined] optional WebGLVertexArrayObjectOES? arrayObject);
- boolean isVertexArrayOES([DefaultValue=Undefined] optional WebGLVertexArrayObjectOES? arrayObject);
- void bindVertexArrayOES([DefaultValue=Undefined] optional WebGLVertexArrayObjectOES? arrayObject);
+ void deleteVertexArrayOES(optional WebGLVertexArrayObjectOES? arrayObject = null);
+ boolean isVertexArrayOES(optional WebGLVertexArrayObjectOES? arrayObject = null);
+ void bindVertexArrayOES(optional WebGLVertexArrayObjectOES? arrayObject = null);
};
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ovr_multiview_2.cc b/chromium/third_party/blink/renderer/modules/webgl/ovr_multiview_2.cc
index 8e4a3467c2f..c0c2527b3ee 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/ovr_multiview_2.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/ovr_multiview_2.cc
@@ -20,10 +20,6 @@ WebGLExtensionName OVRMultiview2::GetName() const {
return kOVRMultiview2Name;
}
-OVRMultiview2* OVRMultiview2::Create(WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<OVRMultiview2>(context);
-}
-
void OVRMultiview2::framebufferTextureMultiviewOVR(GLenum target,
GLenum attachment,
WebGLTexture* texture,
diff --git a/chromium/third_party/blink/renderer/modules/webgl/ovr_multiview_2.h b/chromium/third_party/blink/renderer/modules/webgl/ovr_multiview_2.h
index f6a3ff91cd2..3a2f16c74e6 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/ovr_multiview_2.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/ovr_multiview_2.h
@@ -13,7 +13,6 @@ class OVRMultiview2 final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static OVRMultiview2* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
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 fc2ae8662cc..6a533d40da2 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
@@ -120,28 +120,24 @@ ImageBitmap* WebGL2ComputeRenderingContext::TransferToImageBitmap(
void WebGL2ComputeRenderingContext::RegisterContextExtensions() {
// Register extensions.
- RegisterExtension<EXTColorBufferFloat>(ext_color_buffer_float_);
- RegisterExtension<EXTDisjointTimerQueryWebGL2>(
- ext_disjoint_timer_query_web_gl2_);
- RegisterExtension<EXTFloatBlend>(ext_float_blend_);
- RegisterExtension<EXTTextureFilterAnisotropic>(
- ext_texture_filter_anisotropic_);
- RegisterExtension<OESTextureFloatLinear>(oes_texture_float_linear_);
- RegisterExtension<WebGLCompressedTextureASTC>(webgl_compressed_texture_astc_);
- RegisterExtension<WebGLCompressedTextureETC>(webgl_compressed_texture_etc_);
- RegisterExtension<WebGLCompressedTextureETC1>(webgl_compressed_texture_etc1_);
- RegisterExtension<WebGLCompressedTexturePVRTC>(
- webgl_compressed_texture_pvrtc_);
- RegisterExtension<WebGLCompressedTextureS3TC>(webgl_compressed_texture_s3tc_);
- RegisterExtension<WebGLCompressedTextureS3TCsRGB>(
- webgl_compressed_texture_s3tc_srgb_);
- RegisterExtension<WebGLDebugRendererInfo>(webgl_debug_renderer_info_);
- RegisterExtension<WebGLDebugShaders>(webgl_debug_shaders_);
- RegisterExtension<WebGLLoseContext>(webgl_lose_context_);
- RegisterExtension<WebGLVideoTexture>(webgl_video_texture_, kDraftExtension);
+ RegisterExtension(ext_color_buffer_float_);
+ RegisterExtension(ext_disjoint_timer_query_web_gl2_);
+ RegisterExtension(ext_float_blend_);
+ RegisterExtension(ext_texture_filter_anisotropic_);
+ RegisterExtension(oes_texture_float_linear_);
+ RegisterExtension(webgl_compressed_texture_astc_);
+ RegisterExtension(webgl_compressed_texture_etc_);
+ RegisterExtension(webgl_compressed_texture_etc1_);
+ RegisterExtension(webgl_compressed_texture_pvrtc_);
+ RegisterExtension(webgl_compressed_texture_s3tc_);
+ RegisterExtension(webgl_compressed_texture_s3tc_srgb_);
+ RegisterExtension(webgl_debug_renderer_info_);
+ RegisterExtension(webgl_debug_shaders_);
+ RegisterExtension(webgl_lose_context_);
+ RegisterExtension(webgl_video_texture_, kDraftExtension);
}
-void WebGL2ComputeRenderingContext::Trace(blink::Visitor* visitor) {
+void WebGL2ComputeRenderingContext::Trace(Visitor* visitor) {
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 8aef6a09115..7cf9ae4b6dc 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
Member<EXTColorBufferFloat> ext_color_buffer_float_;
@@ -80,16 +80,6 @@ class WebGL2ComputeRenderingContext : public WebGL2ComputeRenderingContextBase {
Member<WebGLVideoTexture> webgl_video_texture_;
};
-DEFINE_TYPE_CASTS(WebGL2ComputeRenderingContext,
- CanvasRenderingContext,
- context,
- context->Is3d() &&
- WebGLRenderingContextBase::GetWebGLVersion(context) ==
- Platform::kWebGL2ComputeContextType,
- context.Is3d() &&
- WebGLRenderingContextBase::GetWebGLVersion(&context) ==
- Platform::kWebGL2ComputeContextType);
-
} // namespace blink
#endif
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 b196c45c175..9a6ca48241d 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
@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/modules/webgl/webgl_program.h"
#include "third_party/blink/renderer/modules/webgl/webgl_uniform_location.h"
#include "third_party/blink/renderer/modules/webgl/webgl_vertex_array_object.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -483,7 +484,7 @@ ScriptValue WebGL2ComputeRenderingContextBase::getIndexedParameter(
}
}
-void WebGL2ComputeRenderingContextBase::Trace(blink::Visitor* visitor) {
+void WebGL2ComputeRenderingContextBase::Trace(Visitor* visitor) {
visitor->Trace(bound_dispatch_indirect_buffer_);
visitor->Trace(bound_draw_indirect_buffer_);
visitor->Trace(bound_atomic_counter_buffer_);
@@ -674,7 +675,7 @@ ScriptValue WebGL2ComputeRenderingContextBase::WrapLocation(
return ScriptValue::CreateNull(script_state->GetIsolate());
DCHECK_GE(location, 0);
WebGLUniformLocation* uniform_location =
- WebGLUniformLocation::Create(program, location);
+ MakeGarbageCollected<WebGLUniformLocation>(program, location);
return ScriptValue(script_state->GetIsolate(),
ToV8(uniform_location, script_state));
}
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 0953f26e985..7b8ab3b5566 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
WebGL2ComputeRenderingContextBase(
@@ -126,16 +126,6 @@ class WebGL2ComputeRenderingContextBase : public WebGL2RenderingContextBase {
HeapVector<Member<WebGLBuffer>> bound_indexed_shader_storage_buffers_;
};
-DEFINE_TYPE_CASTS(WebGL2ComputeRenderingContextBase,
- CanvasRenderingContext,
- context,
- context->Is3d() &&
- WebGLRenderingContextBase::GetWebGLVersion(context) ==
- Platform::kWebGL2ComputeContextType,
- context.Is3d() &&
- WebGLRenderingContextBase::GetWebGLVersion(&context) ==
- Platform::kWebGL2ComputeContextType);
-
} // namespace blink
#endif
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 3e16e97b1a9..722a86ca719 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
@@ -17,7 +17,10 @@
#include "third_party/blink/renderer/modules/webgl/ext_color_buffer_float.h"
#include "third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.h"
#include "third_party/blink/renderer/modules/webgl/ext_float_blend.h"
+#include "third_party/blink/renderer/modules/webgl/ext_texture_compression_bptc.h"
+#include "third_party/blink/renderer/modules/webgl/ext_texture_compression_rgtc.h"
#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_texture_float_linear.h"
#include "third_party/blink/renderer/modules/webgl/ovr_multiview_2.h"
@@ -124,39 +127,41 @@ ImageBitmap* WebGL2RenderingContext::TransferToImageBitmap(
void WebGL2RenderingContext::RegisterContextExtensions() {
// Register extensions.
- RegisterExtension<EXTColorBufferFloat>(ext_color_buffer_float_);
- RegisterExtension<EXTDisjointTimerQueryWebGL2>(
- ext_disjoint_timer_query_web_gl2_);
- RegisterExtension<EXTFloatBlend>(ext_float_blend_);
- RegisterExtension<EXTTextureFilterAnisotropic>(
- ext_texture_filter_anisotropic_);
- RegisterExtension<KHRParallelShaderCompile>(khr_parallel_shader_compile_);
- RegisterExtension<OESTextureFloatLinear>(oes_texture_float_linear_);
- RegisterExtension<WebGLCompressedTextureASTC>(webgl_compressed_texture_astc_);
- RegisterExtension<WebGLCompressedTextureETC>(webgl_compressed_texture_etc_);
- RegisterExtension<WebGLCompressedTextureETC1>(webgl_compressed_texture_etc1_);
- RegisterExtension<WebGLCompressedTexturePVRTC>(
- webgl_compressed_texture_pvrtc_);
- RegisterExtension<WebGLCompressedTextureS3TC>(webgl_compressed_texture_s3tc_);
- RegisterExtension<WebGLCompressedTextureS3TCsRGB>(
- webgl_compressed_texture_s3tc_srgb_);
- RegisterExtension<WebGLDebugRendererInfo>(webgl_debug_renderer_info_);
- RegisterExtension<WebGLDebugShaders>(webgl_debug_shaders_);
- RegisterExtension<WebGLDrawInstancedBaseVertexBaseInstance>(
- webgl_draw_instanced_base_vertex_base_instance_, kDraftExtension);
- RegisterExtension<WebGLLoseContext>(webgl_lose_context_);
- RegisterExtension<WebGLMultiDraw>(webgl_multi_draw_, kDraftExtension);
- RegisterExtension<WebGLMultiDrawInstancedBaseVertexBaseInstance>(
- webgl_multi_draw_instanced_base_vertex_base_instance_, kDraftExtension);
- RegisterExtension<WebGLVideoTexture>(webgl_video_texture_, kDraftExtension);
- RegisterExtension<OVRMultiview2>(ovr_multiview2_);
+ RegisterExtension(ext_color_buffer_float_);
+ RegisterExtension(ext_disjoint_timer_query_web_gl2_);
+ RegisterExtension(ext_float_blend_);
+ RegisterExtension(ext_texture_compression_bptc_);
+ RegisterExtension(ext_texture_compression_rgtc_);
+ RegisterExtension(ext_texture_filter_anisotropic_);
+ RegisterExtension(ext_texture_norm16_, kDraftExtension);
+ RegisterExtension(khr_parallel_shader_compile_);
+ RegisterExtension(oes_texture_float_linear_);
+ RegisterExtension(webgl_compressed_texture_astc_);
+ RegisterExtension(webgl_compressed_texture_etc_);
+ RegisterExtension(webgl_compressed_texture_etc1_);
+ RegisterExtension(webgl_compressed_texture_pvrtc_);
+ RegisterExtension(webgl_compressed_texture_s3tc_);
+ RegisterExtension(webgl_compressed_texture_s3tc_srgb_);
+ RegisterExtension(webgl_debug_renderer_info_);
+ RegisterExtension(webgl_debug_shaders_);
+ RegisterExtension(webgl_draw_instanced_base_vertex_base_instance_,
+ kDraftExtension);
+ RegisterExtension(webgl_lose_context_);
+ RegisterExtension(webgl_multi_draw_, kDraftExtension);
+ RegisterExtension(webgl_multi_draw_instanced_base_vertex_base_instance_,
+ kDraftExtension);
+ RegisterExtension(webgl_video_texture_, kDraftExtension);
+ RegisterExtension(ovr_multiview2_);
}
-void WebGL2RenderingContext::Trace(blink::Visitor* visitor) {
+void WebGL2RenderingContext::Trace(Visitor* visitor) {
visitor->Trace(ext_color_buffer_float_);
visitor->Trace(ext_disjoint_timer_query_web_gl2_);
visitor->Trace(ext_float_blend_);
+ visitor->Trace(ext_texture_compression_bptc_);
+ visitor->Trace(ext_texture_compression_rgtc_);
visitor->Trace(ext_texture_filter_anisotropic_);
+ visitor->Trace(ext_texture_norm16_);
visitor->Trace(khr_parallel_shader_compile_);
visitor->Trace(oes_texture_float_linear_);
visitor->Trace(ovr_multiview2_);
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 33aec32972e..dfe4ac4d5f9 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
@@ -16,7 +16,10 @@ namespace blink {
class CanvasContextCreationAttributesCore;
class EXTColorBufferFloat;
class EXTFloatBlend;
+class EXTTextureCompressionBPTC;
+class EXTTextureCompressionRGTC;
class EXTTextureFilterAnisotropic;
+class EXTTextureNorm16;
class OESTextureFloatLinear;
class OVRMultiview2;
class WebGLDebugRendererInfo;
@@ -63,13 +66,16 @@ class WebGL2RenderingContext : public WebGL2RenderingContextBase {
void SetCanvasGetContextResult(RenderingContext&) final;
void SetOffscreenCanvasGetContextResult(OffscreenRenderingContext&) final;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
Member<EXTColorBufferFloat> ext_color_buffer_float_;
Member<EXTDisjointTimerQueryWebGL2> ext_disjoint_timer_query_web_gl2_;
Member<EXTFloatBlend> ext_float_blend_;
+ Member<EXTTextureCompressionBPTC> ext_texture_compression_bptc_;
+ Member<EXTTextureCompressionRGTC> ext_texture_compression_rgtc_;
Member<EXTTextureFilterAnisotropic> ext_texture_filter_anisotropic_;
+ Member<EXTTextureNorm16> ext_texture_norm16_;
Member<KHRParallelShaderCompile> khr_parallel_shader_compile_;
Member<OESTextureFloatLinear> oes_texture_float_linear_;
Member<OVRMultiview2> ovr_multiview2_;
@@ -90,16 +96,6 @@ class WebGL2RenderingContext : public WebGL2RenderingContextBase {
Member<WebGLVideoTexture> webgl_video_texture_;
};
-DEFINE_TYPE_CASTS(WebGL2RenderingContext,
- CanvasRenderingContext,
- context,
- context->Is3d() &&
- WebGLRenderingContextBase::GetWebGLVersion(context) ==
- Platform::kWebGL2ContextType,
- context.Is3d() &&
- WebGLRenderingContextBase::GetWebGLVersion(&context) ==
- Platform::kWebGL2ContextType);
-
} // namespace blink
#endif
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 ad915481f8d..a8cae56cbe4 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
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/modules/webgl/webgl_transform_feedback.h"
#include "third_party/blink/renderer/modules/webgl/webgl_uniform_location.h"
#include "third_party/blink/renderer/modules/webgl/webgl_vertex_array_object.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
using WTF::String;
@@ -210,7 +211,7 @@ void WebGL2RenderingContextBase::InitializeNewContext() {
&max_transform_feedback_separate_attribs_);
// Create a default transform feedback object so there is a place to
// hold any bound buffers.
- default_transform_feedback_ = WebGLTransformFeedback::Create(
+ default_transform_feedback_ = MakeGarbageCollected<WebGLTransformFeedback>(
this, WebGLTransformFeedback::TFTypeDefault);
transform_feedback_binding_ = default_transform_feedback_;
@@ -924,6 +925,17 @@ void WebGL2RenderingContextBase::RenderbufferStorageImpl(
RenderbufferStorageHelper(target, samples, internalformat, width, height,
function_name);
break;
+ case GL_R16_EXT:
+ case GL_RG16_EXT:
+ case GL_RGBA16_EXT:
+ if (!ExtensionEnabled(kEXTTextureNorm16Name)) {
+ SynthesizeGLError(GL_INVALID_ENUM, function_name,
+ "EXT_texture_norm16 not enabled");
+ return;
+ }
+ RenderbufferStorageHelper(target, samples, internalformat, width, height,
+ function_name);
+ break;
default:
SynthesizeGLError(GL_INVALID_ENUM, function_name,
"invalid internalformat");
@@ -994,70 +1006,6 @@ void WebGL2RenderingContextBase::RestoreUnpackParameters() {
ContextGL()->PixelStorei(GL_UNPACK_SKIP_IMAGES, unpack_skip_images_);
}
-/* Texture objects */
-bool WebGL2RenderingContextBase::ValidateTexStorage(
- const char* function_name,
- GLenum target,
- GLsizei levels,
- GLenum internalformat,
- GLsizei width,
- GLsizei height,
- GLsizei depth,
- TexStorageType function_type) {
- if (function_type == kTexStorageType2D) {
- if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP) {
- SynthesizeGLError(GL_INVALID_ENUM, function_name, "invalid 2D target");
- return false;
- }
- } else {
- if (target != GL_TEXTURE_3D && target != GL_TEXTURE_2D_ARRAY) {
- SynthesizeGLError(GL_INVALID_ENUM, function_name, "invalid 3D target");
- return false;
- }
- }
-
- if (function_type == kTexStorageType3D && target != GL_TEXTURE_2D_ARRAY &&
- compressed_texture_formats_etc2eac_.find(internalformat) !=
- compressed_texture_formats_etc2eac_.end()) {
- SynthesizeGLError(
- GL_INVALID_OPERATION, function_name,
- "target for ETC2/EAC internal formats must be TEXTURE_2D_ARRAY");
- return false;
- }
-
- if (supported_internal_formats_storage_.find(internalformat) ==
- supported_internal_formats_storage_.end() &&
- (function_type == kTexStorageType2D &&
- !compressed_texture_formats_.Contains(internalformat))) {
- SynthesizeGLError(GL_INVALID_ENUM, function_name, "invalid internalformat");
- return false;
- }
-
- if (width <= 0 || height <= 0 || depth <= 0) {
- SynthesizeGLError(GL_INVALID_VALUE, function_name, "invalid dimensions");
- return false;
- }
-
- if (levels <= 0) {
- SynthesizeGLError(GL_INVALID_VALUE, function_name, "invalid levels");
- return false;
- }
-
- if (target == GL_TEXTURE_3D) {
- if (levels > log2(std::max(std::max(width, height), depth)) + 1) {
- SynthesizeGLError(GL_INVALID_OPERATION, function_name, "to many levels");
- return false;
- }
- } else {
- if (levels > log2(std::max(width, height)) + 1) {
- SynthesizeGLError(GL_INVALID_OPERATION, function_name, "to many levels");
- return false;
- }
- }
-
- return true;
-}
-
void WebGL2RenderingContextBase::texImage2D(GLenum target,
GLint level,
GLint internalformat,
@@ -1666,9 +1614,7 @@ void WebGL2RenderingContextBase::texStorage2D(GLenum target,
GLenum internalformat,
GLsizei width,
GLsizei height) {
- if (isContextLost() ||
- !ValidateTexStorage("texStorage2D", target, levels, internalformat, width,
- height, 1, kTexStorageType2D))
+ if (isContextLost())
return;
ContextGL()->TexStorage2DEXT(target, levels, internalformat, width, height);
@@ -1680,9 +1626,7 @@ void WebGL2RenderingContextBase::texStorage3D(GLenum target,
GLsizei width,
GLsizei height,
GLsizei depth) {
- if (isContextLost() ||
- !ValidateTexStorage("texStorage3D", target, levels, internalformat, width,
- height, depth, kTexStorageType3D))
+ if (isContextLost())
return;
ContextGL()->TexStorage3D(target, levels, internalformat, width, height,
@@ -2178,16 +2122,17 @@ void WebGL2RenderingContextBase::compressedTexImage2D(
return;
if (!ValidateCompressedTexFormat("compressedTexImage2D", internalformat))
return;
- if (src_offset > data.View()->deprecatedByteLengthAsUnsigned()) {
+ GLuint data_length;
+ if (!ExtractDataLengthIfValid("compressedTexImage2D", data, &data_length))
+ return;
+ if (src_offset > data_length) {
SynthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D",
"srcOffset is out of range");
return;
}
if (src_length_override == 0) {
- src_length_override =
- data.View()->deprecatedByteLengthAsUnsigned() - src_offset;
- } else if (src_length_override >
- data.View()->deprecatedByteLengthAsUnsigned() - src_offset) {
+ src_length_override = data_length - src_offset;
+ } else if (src_length_override > data_length - src_offset) {
SynthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D",
"srcLengthOverride is out of range");
return;
@@ -2260,16 +2205,17 @@ void WebGL2RenderingContextBase::compressedTexSubImage2D(
return;
if (!ValidateCompressedTexFormat("compressedTexSubImage2D", format))
return;
- if (src_offset > data.View()->deprecatedByteLengthAsUnsigned()) {
+ GLuint data_length;
+ if (!ExtractDataLengthIfValid("compressedTexSubImage2D", data, &data_length))
+ return;
+ if (src_offset > data_length) {
SynthesizeGLError(GL_INVALID_VALUE, "compressedTexSubImage2D",
"srcOffset is out of range");
return;
}
if (src_length_override == 0) {
- src_length_override =
- data.View()->deprecatedByteLengthAsUnsigned() - src_offset;
- } else if (src_length_override >
- data.View()->deprecatedByteLengthAsUnsigned() - src_offset) {
+ src_length_override = data_length - src_offset;
+ } else if (src_length_override > data_length - src_offset) {
SynthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D",
"srcLengthOverride is out of range");
return;
@@ -2324,16 +2270,17 @@ void WebGL2RenderingContextBase::compressedTexImage3D(
return;
if (!ValidateCompressedTexFormat("compressedTexImage3D", internalformat))
return;
- if (src_offset > data.View()->deprecatedByteLengthAsUnsigned()) {
+ GLuint data_length;
+ if (!ExtractDataLengthIfValid("compressedTexImage3D", data, &data_length))
+ return;
+ if (src_offset > data_length) {
SynthesizeGLError(GL_INVALID_VALUE, "compressedTexImage3D",
"srcOffset is out of range");
return;
}
if (src_length_override == 0) {
- src_length_override =
- data.View()->deprecatedByteLengthAsUnsigned() - src_offset;
- } else if (src_length_override >
- data.View()->deprecatedByteLengthAsUnsigned() - src_offset) {
+ src_length_override = data_length - src_offset;
+ } else if (src_length_override > data_length - src_offset) {
SynthesizeGLError(GL_INVALID_VALUE, "compressedTexImage3D",
"srcLengthOverride is out of range");
return;
@@ -2390,16 +2337,17 @@ void WebGL2RenderingContextBase::compressedTexSubImage3D(
return;
if (!ValidateCompressedTexFormat("compressedTexSubImage3D", format))
return;
- if (src_offset > data.View()->deprecatedByteLengthAsUnsigned()) {
+ GLuint data_length;
+ if (!ExtractDataLengthIfValid("compressedTexSubImage3D", data, &data_length))
+ return;
+ if (src_offset > data_length) {
SynthesizeGLError(GL_INVALID_VALUE, "compressedTexSubImage3D",
"srcOffset is out of range");
return;
}
if (src_length_override == 0) {
- src_length_override =
- data.View()->deprecatedByteLengthAsUnsigned() - src_offset;
- } else if (src_length_override >
- data.View()->deprecatedByteLengthAsUnsigned() - src_offset) {
+ src_length_override = data_length - src_offset;
+ } else if (src_length_override > data_length - src_offset) {
SynthesizeGLError(GL_INVALID_VALUE, "compressedTexSubImage3D",
"srcLengthOverride is out of range");
return;
@@ -2511,16 +2459,18 @@ void WebGL2RenderingContextBase::uniform4ui(
void WebGL2RenderingContextBase::uniform1fv(
const WebGLUniformLocation* location,
- const FlexibleFloat32ArrayView& v,
+ const FlexibleFloat32Array& v,
GLuint src_offset,
GLuint src_length) {
if (isContextLost() || !ValidateUniformParameters("uniform1fv", location, v,
1, src_offset, src_length))
return;
- ContextGL()->Uniform1fv(location->Location(),
- src_length ? src_length : (v.length() - src_offset),
- v.DataMaybeOnStack() + src_offset);
+ ContextGL()->Uniform1fv(
+ location->Location(),
+ src_length ? src_length
+ : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset),
+ v.DataMaybeOnStack() + src_offset);
}
void WebGL2RenderingContextBase::uniform1fv(
@@ -2540,7 +2490,7 @@ void WebGL2RenderingContextBase::uniform1fv(
void WebGL2RenderingContextBase::uniform2fv(
const WebGLUniformLocation* location,
- const FlexibleFloat32ArrayView& v,
+ const FlexibleFloat32Array& v,
GLuint src_offset,
GLuint src_length) {
if (isContextLost() || !ValidateUniformParameters("uniform2fv", location, v,
@@ -2549,7 +2499,10 @@ void WebGL2RenderingContextBase::uniform2fv(
ContextGL()->Uniform2fv(
location->Location(),
- (src_length ? src_length : (v.length() - src_offset)) >> 1,
+ (src_length
+ ? src_length
+ : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset)) >>
+ 1,
v.DataMaybeOnStack() + src_offset);
}
@@ -2571,7 +2524,7 @@ void WebGL2RenderingContextBase::uniform2fv(
void WebGL2RenderingContextBase::uniform3fv(
const WebGLUniformLocation* location,
- const FlexibleFloat32ArrayView& v,
+ const FlexibleFloat32Array& v,
GLuint src_offset,
GLuint src_length) {
if (isContextLost() || !ValidateUniformParameters("uniform3fv", location, v,
@@ -2580,7 +2533,10 @@ void WebGL2RenderingContextBase::uniform3fv(
ContextGL()->Uniform3fv(
location->Location(),
- (src_length ? src_length : (v.length() - src_offset)) / 3,
+ (src_length
+ ? src_length
+ : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset)) /
+ 3,
v.DataMaybeOnStack() + src_offset);
}
@@ -2602,7 +2558,7 @@ void WebGL2RenderingContextBase::uniform3fv(
void WebGL2RenderingContextBase::uniform4fv(
const WebGLUniformLocation* location,
- const FlexibleFloat32ArrayView& v,
+ const FlexibleFloat32Array& v,
GLuint src_offset,
GLuint src_length) {
if (isContextLost() || !ValidateUniformParameters("uniform4fv", location, v,
@@ -2611,7 +2567,10 @@ void WebGL2RenderingContextBase::uniform4fv(
ContextGL()->Uniform4fv(
location->Location(),
- (src_length ? src_length : (v.length() - src_offset)) >> 2,
+ (src_length
+ ? src_length
+ : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset)) >>
+ 2,
v.DataMaybeOnStack() + src_offset);
}
@@ -2633,16 +2592,18 @@ void WebGL2RenderingContextBase::uniform4fv(
void WebGL2RenderingContextBase::uniform1iv(
const WebGLUniformLocation* location,
- const FlexibleInt32ArrayView& v,
+ const FlexibleInt32Array& v,
GLuint src_offset,
GLuint src_length) {
if (isContextLost() || !ValidateUniformParameters("uniform1iv", location, v,
1, src_offset, src_length))
return;
- ContextGL()->Uniform1iv(location->Location(),
- src_length ? src_length : (v.length() - src_offset),
- v.DataMaybeOnStack() + src_offset);
+ ContextGL()->Uniform1iv(
+ location->Location(),
+ src_length ? src_length
+ : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset),
+ v.DataMaybeOnStack() + src_offset);
}
void WebGL2RenderingContextBase::uniform1iv(
@@ -2662,7 +2623,7 @@ void WebGL2RenderingContextBase::uniform1iv(
void WebGL2RenderingContextBase::uniform2iv(
const WebGLUniformLocation* location,
- const FlexibleInt32ArrayView& v,
+ const FlexibleInt32Array& v,
GLuint src_offset,
GLuint src_length) {
if (isContextLost() || !ValidateUniformParameters("uniform2iv", location, v,
@@ -2671,7 +2632,10 @@ void WebGL2RenderingContextBase::uniform2iv(
ContextGL()->Uniform2iv(
location->Location(),
- (src_length ? src_length : (v.length() - src_offset)) >> 1,
+ (src_length
+ ? src_length
+ : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset)) >>
+ 1,
v.DataMaybeOnStack() + src_offset);
}
@@ -2693,7 +2657,7 @@ void WebGL2RenderingContextBase::uniform2iv(
void WebGL2RenderingContextBase::uniform3iv(
const WebGLUniformLocation* location,
- const FlexibleInt32ArrayView& v,
+ const FlexibleInt32Array& v,
GLuint src_offset,
GLuint src_length) {
if (isContextLost() || !ValidateUniformParameters("uniform3iv", location, v,
@@ -2702,7 +2666,10 @@ void WebGL2RenderingContextBase::uniform3iv(
ContextGL()->Uniform3iv(
location->Location(),
- (src_length ? src_length : (v.length() - src_offset)) / 3,
+ (src_length
+ ? src_length
+ : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset)) /
+ 3,
v.DataMaybeOnStack() + src_offset);
}
@@ -2724,7 +2691,7 @@ void WebGL2RenderingContextBase::uniform3iv(
void WebGL2RenderingContextBase::uniform4iv(
const WebGLUniformLocation* location,
- const FlexibleInt32ArrayView& v,
+ const FlexibleInt32Array& v,
GLuint src_offset,
GLuint src_length) {
if (isContextLost() || !ValidateUniformParameters("uniform4iv", location, v,
@@ -2733,7 +2700,10 @@ void WebGL2RenderingContextBase::uniform4iv(
ContextGL()->Uniform4iv(
location->Location(),
- (src_length ? src_length : (v.length() - src_offset)) >> 2,
+ (src_length
+ ? src_length
+ : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset)) >>
+ 2,
v.DataMaybeOnStack() + src_offset);
}
@@ -2755,16 +2725,18 @@ void WebGL2RenderingContextBase::uniform4iv(
void WebGL2RenderingContextBase::uniform1uiv(
const WebGLUniformLocation* location,
- const FlexibleUint32ArrayView& v,
+ const FlexibleUint32Array& v,
GLuint src_offset,
GLuint src_length) {
if (isContextLost() || !ValidateUniformParameters("uniform1uiv", location, v,
1, src_offset, src_length))
return;
- ContextGL()->Uniform1uiv(location->Location(),
- src_length ? src_length : (v.length() - src_offset),
- v.DataMaybeOnStack() + src_offset);
+ ContextGL()->Uniform1uiv(
+ location->Location(),
+ src_length ? src_length
+ : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset),
+ v.DataMaybeOnStack() + src_offset);
}
void WebGL2RenderingContextBase::uniform1uiv(
@@ -2785,7 +2757,7 @@ void WebGL2RenderingContextBase::uniform1uiv(
void WebGL2RenderingContextBase::uniform2uiv(
const WebGLUniformLocation* location,
- const FlexibleUint32ArrayView& v,
+ const FlexibleUint32Array& v,
GLuint src_offset,
GLuint src_length) {
if (isContextLost() || !ValidateUniformParameters("uniform2uiv", location, v,
@@ -2794,7 +2766,10 @@ void WebGL2RenderingContextBase::uniform2uiv(
ContextGL()->Uniform2uiv(
location->Location(),
- (src_length ? src_length : (v.length() - src_offset)) >> 1,
+ (src_length
+ ? src_length
+ : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset)) >>
+ 1,
v.DataMaybeOnStack() + src_offset);
}
@@ -2816,7 +2791,7 @@ void WebGL2RenderingContextBase::uniform2uiv(
void WebGL2RenderingContextBase::uniform3uiv(
const WebGLUniformLocation* location,
- const FlexibleUint32ArrayView& v,
+ const FlexibleUint32Array& v,
GLuint src_offset,
GLuint src_length) {
if (isContextLost() || !ValidateUniformParameters("uniform3uiv", location, v,
@@ -2825,7 +2800,10 @@ void WebGL2RenderingContextBase::uniform3uiv(
ContextGL()->Uniform3uiv(
location->Location(),
- (src_length ? src_length : (v.length() - src_offset)) / 3,
+ (src_length
+ ? src_length
+ : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset)) /
+ 3,
v.DataMaybeOnStack() + src_offset);
}
@@ -2847,7 +2825,7 @@ void WebGL2RenderingContextBase::uniform3uiv(
void WebGL2RenderingContextBase::uniform4uiv(
const WebGLUniformLocation* location,
- const FlexibleUint32ArrayView& v,
+ const FlexibleUint32Array& v,
GLuint src_offset,
GLuint src_length) {
if (isContextLost() || !ValidateUniformParameters("uniform4uiv", location, v,
@@ -2856,7 +2834,10 @@ void WebGL2RenderingContextBase::uniform4uiv(
ContextGL()->Uniform4uiv(
location->Location(),
- (src_length ? src_length : (v.length() - src_offset)) >> 2,
+ (src_length
+ ? src_length
+ : (base::checked_cast<GLuint>(v.lengthAsSizeT()) - src_offset)) >>
+ 2,
v.DataMaybeOnStack() + src_offset);
}
@@ -2889,7 +2870,8 @@ void WebGL2RenderingContextBase::uniformMatrix2fv(
ContextGL()->UniformMatrix2fv(
location->Location(),
(src_length ? src_length
- : (v.View()->deprecatedLengthAsUnsigned() - src_offset)) >>
+ : (base::checked_cast<GLuint>(v.View()->lengthAsSizeT()) -
+ src_offset)) >>
2,
transpose, v.View()->DataMaybeShared() + src_offset);
}
@@ -2923,7 +2905,8 @@ void WebGL2RenderingContextBase::uniformMatrix3fv(
ContextGL()->UniformMatrix3fv(
location->Location(),
(src_length ? src_length
- : (v.View()->deprecatedLengthAsUnsigned() - src_offset)) /
+ : (base::checked_cast<GLuint>(v.View()->lengthAsSizeT()) -
+ src_offset)) /
9,
transpose, v.View()->DataMaybeShared() + src_offset);
}
@@ -2957,7 +2940,8 @@ void WebGL2RenderingContextBase::uniformMatrix4fv(
ContextGL()->UniformMatrix4fv(
location->Location(),
(src_length ? src_length
- : (v.View()->deprecatedLengthAsUnsigned() - src_offset)) >>
+ : (base::checked_cast<GLuint>(v.View()->lengthAsSizeT()) -
+ src_offset)) >>
4,
transpose, v.View()->DataMaybeShared() + src_offset);
}
@@ -2991,7 +2975,8 @@ void WebGL2RenderingContextBase::uniformMatrix2x3fv(
ContextGL()->UniformMatrix2x3fv(
location->Location(),
(src_length ? src_length
- : (value.View()->deprecatedLengthAsUnsigned() - src_offset)) /
+ : (base::checked_cast<GLuint>(value.View()->lengthAsSizeT()) -
+ src_offset)) /
6,
transpose, value.View()->DataMaybeShared() + src_offset);
}
@@ -3026,7 +3011,8 @@ void WebGL2RenderingContextBase::uniformMatrix3x2fv(
ContextGL()->UniformMatrix3x2fv(
location->Location(),
(src_length ? src_length
- : (value.View()->deprecatedLengthAsUnsigned() - src_offset)) /
+ : (base::checked_cast<GLuint>(value.View()->lengthAsSizeT()) -
+ src_offset)) /
6,
transpose, value.View()->DataMaybeShared() + src_offset);
}
@@ -3060,9 +3046,9 @@ void WebGL2RenderingContextBase::uniformMatrix2x4fv(
return;
ContextGL()->UniformMatrix2x4fv(
location->Location(),
- (src_length
- ? src_length
- : (value.View()->deprecatedLengthAsUnsigned() - src_offset)) >>
+ (src_length ? src_length
+ : (base::checked_cast<GLuint>(value.View()->lengthAsSizeT()) -
+ src_offset)) >>
3,
transpose, value.View()->DataMaybeShared() + src_offset);
}
@@ -3096,9 +3082,9 @@ void WebGL2RenderingContextBase::uniformMatrix4x2fv(
return;
ContextGL()->UniformMatrix4x2fv(
location->Location(),
- (src_length
- ? src_length
- : (value.View()->deprecatedLengthAsUnsigned() - src_offset)) >>
+ (src_length ? src_length
+ : (base::checked_cast<GLuint>(value.View()->lengthAsSizeT()) -
+ src_offset)) >>
3,
transpose, value.View()->DataMaybeShared() + src_offset);
}
@@ -3133,7 +3119,8 @@ void WebGL2RenderingContextBase::uniformMatrix3x4fv(
ContextGL()->UniformMatrix3x4fv(
location->Location(),
(src_length ? src_length
- : (value.View()->deprecatedLengthAsUnsigned() - src_offset)) /
+ : (base::checked_cast<GLuint>(value.View()->lengthAsSizeT()) -
+ src_offset)) /
12,
transpose, value.View()->DataMaybeShared() + src_offset);
}
@@ -3168,7 +3155,8 @@ void WebGL2RenderingContextBase::uniformMatrix4x3fv(
ContextGL()->UniformMatrix4x3fv(
location->Location(),
(src_length ? src_length
- : (value.View()->deprecatedLengthAsUnsigned() - src_offset)) /
+ : (base::checked_cast<GLuint>(value.View()->lengthAsSizeT()) -
+ src_offset)) /
12,
transpose, value.View()->DataMaybeShared() + src_offset);
}
@@ -3192,7 +3180,7 @@ void WebGL2RenderingContextBase::uniformMatrix4x3fv(
void WebGL2RenderingContextBase::uniform1fv(
const WebGLUniformLocation* location,
- const FlexibleFloat32ArrayView& v) {
+ const FlexibleFloat32Array& v) {
WebGLRenderingContextBase::uniform1fv(location, v);
}
@@ -3204,7 +3192,7 @@ void WebGL2RenderingContextBase::uniform1fv(
void WebGL2RenderingContextBase::uniform2fv(
const WebGLUniformLocation* location,
- const FlexibleFloat32ArrayView& v) {
+ const FlexibleFloat32Array& v) {
WebGLRenderingContextBase::uniform2fv(location, v);
}
@@ -3216,7 +3204,7 @@ void WebGL2RenderingContextBase::uniform2fv(
void WebGL2RenderingContextBase::uniform3fv(
const WebGLUniformLocation* location,
- const FlexibleFloat32ArrayView& v) {
+ const FlexibleFloat32Array& v) {
WebGLRenderingContextBase::uniform3fv(location, v);
}
@@ -3228,7 +3216,7 @@ void WebGL2RenderingContextBase::uniform3fv(
void WebGL2RenderingContextBase::uniform4fv(
const WebGLUniformLocation* location,
- const FlexibleFloat32ArrayView& v) {
+ const FlexibleFloat32Array& v) {
WebGLRenderingContextBase::uniform4fv(location, v);
}
@@ -3240,7 +3228,7 @@ void WebGL2RenderingContextBase::uniform4fv(
void WebGL2RenderingContextBase::uniform1iv(
const WebGLUniformLocation* location,
- const FlexibleInt32ArrayView& v) {
+ const FlexibleInt32Array& v) {
WebGLRenderingContextBase::uniform1iv(location, v);
}
@@ -3252,7 +3240,7 @@ void WebGL2RenderingContextBase::uniform1iv(
void WebGL2RenderingContextBase::uniform2iv(
const WebGLUniformLocation* location,
- const FlexibleInt32ArrayView& v) {
+ const FlexibleInt32Array& v) {
WebGLRenderingContextBase::uniform2iv(location, v);
}
@@ -3264,7 +3252,7 @@ void WebGL2RenderingContextBase::uniform2iv(
void WebGL2RenderingContextBase::uniform3iv(
const WebGLUniformLocation* location,
- const FlexibleInt32ArrayView& v) {
+ const FlexibleInt32Array& v) {
WebGLRenderingContextBase::uniform3iv(location, v);
}
@@ -3276,7 +3264,7 @@ void WebGL2RenderingContextBase::uniform3iv(
void WebGL2RenderingContextBase::uniform4iv(
const WebGLUniformLocation* location,
- const FlexibleInt32ArrayView& v) {
+ const FlexibleInt32Array& v) {
WebGLRenderingContextBase::uniform4iv(location, v);
}
@@ -3564,7 +3552,7 @@ void WebGL2RenderingContextBase::drawBuffers(const Vector<GLenum>& buffers) {
bool WebGL2RenderingContextBase::ValidateClearBuffer(const char* function_name,
GLenum buffer,
- GLsizei size,
+ size_t size,
GLuint src_offset) {
base::CheckedNumeric<GLsizei> checked_size(size);
checked_size -= src_offset;
@@ -3611,8 +3599,7 @@ void WebGL2RenderingContextBase::clearBufferiv(GLenum buffer,
GLuint src_offset) {
if (isContextLost() ||
!ValidateClearBuffer("clearBufferiv", buffer,
- value.View()->deprecatedLengthAsUnsigned(),
- src_offset))
+ value.View()->lengthAsSizeT(), src_offset))
return;
ScopedRGBEmulationColorMask emulation_color_mask(this, color_mask_,
@@ -3645,8 +3632,7 @@ void WebGL2RenderingContextBase::clearBufferuiv(
GLuint src_offset) {
if (isContextLost() ||
!ValidateClearBuffer("clearBufferuiv", buffer,
- value.View()->deprecatedLengthAsUnsigned(),
- src_offset))
+ value.View()->lengthAsSizeT(), src_offset))
return;
ScopedRGBEmulationColorMask emulation_color_mask(this, color_mask_,
@@ -3679,8 +3665,7 @@ void WebGL2RenderingContextBase::clearBufferfv(
GLuint src_offset) {
if (isContextLost() ||
!ValidateClearBuffer("clearBufferfv", buffer,
- value.View()->deprecatedLengthAsUnsigned(),
- src_offset))
+ value.View()->lengthAsSizeT(), src_offset))
return;
// As of this writing the default back buffer will always have an
@@ -3816,7 +3801,7 @@ void WebGL2RenderingContextBase::UpdateBuffersToAutoClear(
WebGLQuery* WebGL2RenderingContextBase::createQuery() {
if (isContextLost())
return nullptr;
- return WebGLQuery::Create(this);
+ return MakeGarbageCollected<WebGLQuery>(this);
}
void WebGL2RenderingContextBase::deleteQuery(WebGLQuery* query) {
@@ -4044,7 +4029,7 @@ ScriptValue WebGL2RenderingContextBase::getQueryParameter(
WebGLSampler* WebGL2RenderingContextBase::createSampler() {
if (isContextLost())
return nullptr;
- return WebGLSampler::Create(this);
+ return MakeGarbageCollected<WebGLSampler>(this);
}
void WebGL2RenderingContextBase::deleteSampler(WebGLSampler* sampler) {
@@ -4261,7 +4246,7 @@ WebGLSync* WebGL2RenderingContextBase::fenceSync(GLenum condition,
SynthesizeGLError(GL_INVALID_VALUE, "fenceSync", "flags must be zero");
return nullptr;
}
- return WebGLFenceSync::Create(this, condition, flags);
+ return MakeGarbageCollected<WebGLFenceSync>(this, condition, flags);
}
GLboolean WebGL2RenderingContextBase::isSync(WebGLSync* sync) {
@@ -4355,8 +4340,8 @@ ScriptValue WebGL2RenderingContextBase::getSyncParameter(
WebGLTransformFeedback* WebGL2RenderingContextBase::createTransformFeedback() {
if (isContextLost())
return nullptr;
- return WebGLTransformFeedback::Create(this,
- WebGLTransformFeedback::TFTypeUser);
+ return MakeGarbageCollected<WebGLTransformFeedback>(
+ this, WebGLTransformFeedback::TFTypeUser);
}
void WebGL2RenderingContextBase::deleteTransformFeedback(
@@ -4552,7 +4537,7 @@ WebGLActiveInfo* WebGL2RenderingContextBase::getTransformFeedbackVarying(
return nullptr;
}
- return WebGLActiveInfo::Create(
+ return MakeGarbageCollected<WebGLActiveInfo>(
String(name.get(), static_cast<uint32_t>(length)), type, size);
}
@@ -4945,7 +4930,7 @@ WebGLVertexArrayObject* WebGL2RenderingContextBase::createVertexArray() {
if (isContextLost())
return nullptr;
- return WebGLVertexArrayObject::Create(
+ return MakeGarbageCollected<WebGLVertexArrayObject>(
this, WebGLVertexArrayObjectBase::kVaoTypeUser);
}
@@ -5752,7 +5737,7 @@ ScriptValue WebGL2RenderingContextBase::getFramebufferAttachmentParameter(
return ScriptValue::CreateNull(script_state->GetIsolate());
}
-void WebGL2RenderingContextBase::Trace(blink::Visitor* visitor) {
+void WebGL2RenderingContextBase::Trace(Visitor* visitor) {
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 c971693d788..1906f0e66e9 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
@@ -617,7 +617,7 @@ class WebGL2RenderingContextBase : public WebGLRenderingContextBase {
void uniform3ui(const WebGLUniformLocation*, GLuint, GLuint, GLuint);
void uniform4ui(const WebGLUniformLocation*, GLuint, GLuint, GLuint, GLuint);
void uniform1fv(const WebGLUniformLocation*,
- const FlexibleFloat32ArrayView&,
+ const FlexibleFloat32Array&,
GLuint,
GLuint);
void uniform1fv(const WebGLUniformLocation*,
@@ -625,7 +625,7 @@ class WebGL2RenderingContextBase : public WebGLRenderingContextBase {
GLuint,
GLuint);
void uniform2fv(const WebGLUniformLocation*,
- const FlexibleFloat32ArrayView&,
+ const FlexibleFloat32Array&,
GLuint,
GLuint);
void uniform2fv(const WebGLUniformLocation*,
@@ -633,7 +633,7 @@ class WebGL2RenderingContextBase : public WebGLRenderingContextBase {
GLuint,
GLuint);
void uniform3fv(const WebGLUniformLocation*,
- const FlexibleFloat32ArrayView&,
+ const FlexibleFloat32Array&,
GLuint,
GLuint);
void uniform3fv(const WebGLUniformLocation*,
@@ -641,7 +641,7 @@ class WebGL2RenderingContextBase : public WebGLRenderingContextBase {
GLuint,
GLuint);
void uniform4fv(const WebGLUniformLocation*,
- const FlexibleFloat32ArrayView&,
+ const FlexibleFloat32Array&,
GLuint,
GLuint);
void uniform4fv(const WebGLUniformLocation*,
@@ -649,27 +649,27 @@ class WebGL2RenderingContextBase : public WebGLRenderingContextBase {
GLuint,
GLuint);
void uniform1iv(const WebGLUniformLocation*,
- const FlexibleInt32ArrayView&,
+ const FlexibleInt32Array&,
GLuint,
GLuint);
void uniform1iv(const WebGLUniformLocation*, Vector<GLint>&, GLuint, GLuint);
void uniform2iv(const WebGLUniformLocation*,
- const FlexibleInt32ArrayView&,
+ const FlexibleInt32Array&,
GLuint,
GLuint);
void uniform2iv(const WebGLUniformLocation*, Vector<GLint>&, GLuint, GLuint);
void uniform3iv(const WebGLUniformLocation*,
- const FlexibleInt32ArrayView&,
+ const FlexibleInt32Array&,
GLuint,
GLuint);
void uniform3iv(const WebGLUniformLocation*, Vector<GLint>&, GLuint, GLuint);
void uniform4iv(const WebGLUniformLocation*,
- const FlexibleInt32ArrayView&,
+ const FlexibleInt32Array&,
GLuint,
GLuint);
void uniform4iv(const WebGLUniformLocation*, Vector<GLint>&, GLuint, GLuint);
void uniform1uiv(const WebGLUniformLocation*,
- const FlexibleUint32ArrayView&,
+ const FlexibleUint32Array&,
GLuint,
GLuint);
void uniform1uiv(const WebGLUniformLocation*,
@@ -677,7 +677,7 @@ class WebGL2RenderingContextBase : public WebGLRenderingContextBase {
GLuint,
GLuint);
void uniform2uiv(const WebGLUniformLocation*,
- const FlexibleUint32ArrayView&,
+ const FlexibleUint32Array&,
GLuint,
GLuint);
void uniform2uiv(const WebGLUniformLocation*,
@@ -685,7 +685,7 @@ class WebGL2RenderingContextBase : public WebGLRenderingContextBase {
GLuint,
GLuint);
void uniform3uiv(const WebGLUniformLocation*,
- const FlexibleUint32ArrayView&,
+ const FlexibleUint32Array&,
GLuint,
GLuint);
void uniform3uiv(const WebGLUniformLocation*,
@@ -693,7 +693,7 @@ class WebGL2RenderingContextBase : public WebGLRenderingContextBase {
GLuint,
GLuint);
void uniform4uiv(const WebGLUniformLocation*,
- const FlexibleUint32ArrayView&,
+ const FlexibleUint32Array&,
GLuint,
GLuint);
void uniform4uiv(const WebGLUniformLocation*,
@@ -793,21 +793,21 @@ class WebGL2RenderingContextBase : public WebGLRenderingContextBase {
// Have to re-declare/re-define the following uniform*()
// functions from the base class. This is because the above
// uniform*() hide the name from base class.
- void uniform1fv(const WebGLUniformLocation*, const FlexibleFloat32ArrayView&);
+ void uniform1fv(const WebGLUniformLocation*, const FlexibleFloat32Array&);
void uniform1fv(const WebGLUniformLocation*, Vector<GLfloat>&);
- void uniform2fv(const WebGLUniformLocation*, const FlexibleFloat32ArrayView&);
+ void uniform2fv(const WebGLUniformLocation*, const FlexibleFloat32Array&);
void uniform2fv(const WebGLUniformLocation*, Vector<GLfloat>&);
- void uniform3fv(const WebGLUniformLocation*, const FlexibleFloat32ArrayView&);
+ void uniform3fv(const WebGLUniformLocation*, const FlexibleFloat32Array&);
void uniform3fv(const WebGLUniformLocation*, Vector<GLfloat>&);
- void uniform4fv(const WebGLUniformLocation*, const FlexibleFloat32ArrayView&);
+ void uniform4fv(const WebGLUniformLocation*, const FlexibleFloat32Array&);
void uniform4fv(const WebGLUniformLocation*, Vector<GLfloat>&);
- void uniform1iv(const WebGLUniformLocation*, const FlexibleInt32ArrayView&);
+ void uniform1iv(const WebGLUniformLocation*, const FlexibleInt32Array&);
void uniform1iv(const WebGLUniformLocation*, Vector<GLint>&);
- void uniform2iv(const WebGLUniformLocation*, const FlexibleInt32ArrayView&);
+ void uniform2iv(const WebGLUniformLocation*, const FlexibleInt32Array&);
void uniform2iv(const WebGLUniformLocation*, Vector<GLint>&);
- void uniform3iv(const WebGLUniformLocation*, const FlexibleInt32ArrayView&);
+ void uniform3iv(const WebGLUniformLocation*, const FlexibleInt32Array&);
void uniform3iv(const WebGLUniformLocation*, Vector<GLint>&);
- void uniform4iv(const WebGLUniformLocation*, const FlexibleInt32ArrayView&);
+ void uniform4iv(const WebGLUniformLocation*, const FlexibleInt32Array&);
void uniform4iv(const WebGLUniformLocation*, Vector<GLint>&);
void uniformMatrix2fv(const WebGLUniformLocation*,
GLboolean transpose,
@@ -970,7 +970,7 @@ class WebGL2RenderingContextBase : public WebGLRenderingContextBase {
/* Helpers */
GLint GetMaxTransformFeedbackSeparateAttribs() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
friend class V8WebGL2RenderingContext;
@@ -997,21 +997,13 @@ class WebGL2RenderingContextBase : public WebGLRenderingContextBase {
bool ValidateClearBuffer(const char* function_name,
GLenum buffer,
- GLsizei length,
+ size_t length,
GLuint src_offset);
enum TexStorageType {
kTexStorageType2D,
kTexStorageType3D,
};
- bool ValidateTexStorage(const char*,
- GLenum,
- GLsizei,
- GLenum,
- GLsizei,
- GLsizei,
- GLsizei,
- TexStorageType);
bool ValidateUniformBlockIndex(const char*, WebGLProgram*, GLuint);
@@ -1121,7 +1113,6 @@ class WebGL2RenderingContextBase : public WebGLRenderingContextBase {
Member<WebGLTransformFeedback> default_transform_feedback_;
GLenumHashSet supported_internal_formats_storage_;
- GLenumHashSet compressed_texture_formats_etc2eac_;
Member<WebGLBuffer> bound_copy_read_buffer_;
Member<WebGLBuffer> bound_copy_write_buffer_;
@@ -1146,16 +1137,6 @@ class WebGL2RenderingContextBase : public WebGLRenderingContextBase {
GLint unpack_skip_images_;
};
-DEFINE_TYPE_CASTS(WebGL2RenderingContextBase,
- CanvasRenderingContext,
- context,
- context->Is3d() &&
- WebGLRenderingContextBase::GetWebGLVersion(context) ==
- Platform::kWebGL2ContextType,
- context.Is3d() &&
- WebGLRenderingContextBase::GetWebGLVersion(&context) ==
- Platform::kWebGL2ContextType);
-
} // namespace blink
#endif
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_active_info.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_active_info.h
index 6168c57b2e0..6d34c555b5c 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_active_info.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_active_info.h
@@ -27,6 +27,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_ACTIVE_INFO_H_
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/khronos/GLES2/gl2.h"
namespace blink {
@@ -35,9 +36,6 @@ class WebGLActiveInfo final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- static WebGLActiveInfo* Create(const String& name, GLenum type, GLint size) {
- return MakeGarbageCollected<WebGLActiveInfo>(name, type, size);
- }
WebGLActiveInfo(const String& name, GLenum type, GLint size)
: name_(name), type_(type), size_(size) {
DCHECK(name.length());
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_buffer.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_buffer.cc
index d49b4feb7d5..caa0d9b20e2 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_buffer.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_buffer.cc
@@ -30,10 +30,6 @@
namespace blink {
-WebGLBuffer* WebGLBuffer::Create(WebGLRenderingContextBase* ctx) {
- return MakeGarbageCollected<WebGLBuffer>(ctx);
-}
-
WebGLBuffer::WebGLBuffer(WebGLRenderingContextBase* ctx)
: WebGLSharedPlatform3DObject(ctx), initial_target_(0), size_(0) {
GLuint buffer;
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_buffer.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_buffer.h
index f5328b34c83..b5243813900 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_buffer.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_buffer.h
@@ -37,8 +37,6 @@ class WebGLBuffer final : public WebGLSharedPlatform3DObject {
explicit WebGLBuffer(WebGLRenderingContextBase*);
~WebGLBuffer() override;
- static WebGLBuffer* Create(WebGLRenderingContextBase*);
-
GLenum GetInitialTarget() const { return initial_target_; }
void SetInitialTarget(GLenum);
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_color_buffer_float.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_color_buffer_float.cc
index 557a214b5a9..32c682af3aa 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_color_buffer_float.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_color_buffer_float.cc
@@ -38,11 +38,6 @@ WebGLExtensionName WebGLColorBufferFloat::GetName() const {
return kWebGLColorBufferFloatName;
}
-WebGLColorBufferFloat* WebGLColorBufferFloat::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<WebGLColorBufferFloat>(context);
-}
-
bool WebGLColorBufferFloat::Supported(WebGLRenderingContextBase* context) {
return context->ExtensionsUtil()->SupportsExtension("GL_OES_texture_float") &&
context->ExtensionsUtil()->SupportsExtension(
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_color_buffer_float.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_color_buffer_float.h
index f12d349f693..73d51a8d3b9 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_color_buffer_float.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_color_buffer_float.h
@@ -34,7 +34,6 @@ class WebGLColorBufferFloat final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static WebGLColorBufferFloat* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_astc.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_astc.cc
index dc3d856d4cd..cf248ef6cc3 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_astc.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_astc.cc
@@ -32,6 +32,9 @@ WebGLCompressedTextureASTC::WebGLCompressedTextureASTC(
context->ExtensionsUtil()->EnsureExtensionEnabled(
"GL_KHR_texture_compression_astc_ldr");
+ supports_hdr = context->ExtensionsUtil()->EnsureExtensionEnabled(
+ "GL_KHR_texture_compression_astc_hdr");
+
const int kAlphaFormatGap =
GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR - GL_COMPRESSED_RGBA_ASTC_4x4_KHR;
@@ -52,11 +55,6 @@ WebGLExtensionName WebGLCompressedTextureASTC::GetName() const {
return kWebGLCompressedTextureASTCName;
}
-WebGLCompressedTextureASTC* WebGLCompressedTextureASTC::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<WebGLCompressedTextureASTC>(context);
-}
-
bool WebGLCompressedTextureASTC::Supported(WebGLRenderingContextBase* context) {
Extensions3DUtil* extensions_util = context->ExtensionsUtil();
return extensions_util->SupportsExtension(
@@ -64,9 +62,15 @@ bool WebGLCompressedTextureASTC::Supported(WebGLRenderingContextBase* context) {
}
const char* WebGLCompressedTextureASTC::ExtensionName() {
- // TODO(cyzero.kim): implement extension for
- // GL_KHR_texture_compression_astc_hdr.
return "WEBGL_compressed_texture_astc";
}
+Vector<String> WebGLCompressedTextureASTC::getSupportedProfiles() {
+ Vector<String> result = {"ldr"};
+ if (supports_hdr) {
+ result.emplace_back("hdr");
+ }
+ return result;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_astc.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_astc.h
index 6da53dbf7f4..8edfd20ceee 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_astc.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_astc.h
@@ -12,6 +12,8 @@ namespace blink {
class WebGLCompressedTextureASTC final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
+ bool supports_hdr;
+
public:
typedef struct {
int compress_type;
@@ -19,7 +21,6 @@ class WebGLCompressedTextureASTC final : public WebGLExtension {
int block_height;
} BlockSizeCompressASTC;
- static WebGLCompressedTextureASTC* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
@@ -27,6 +28,8 @@ class WebGLCompressedTextureASTC final : public WebGLExtension {
WebGLExtensionName GetName() const override;
static const BlockSizeCompressASTC kBlockSizeCompressASTC[];
+
+ Vector<String> getSupportedProfiles();
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_astc.idl b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_astc.idl
index 4d290dc986b..a4d521d87fd 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_astc.idl
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_astc.idl
@@ -37,4 +37,6 @@
const unsigned long COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR = 0x93DB;
const unsigned long COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR = 0x93DC;
const unsigned long COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR = 0x93DD;
+
+ sequence<DOMString> getSupportedProfiles();
};
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc.cc
index 5f30971ef34..25ccdb03804 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc.cc
@@ -31,11 +31,6 @@ WebGLExtensionName WebGLCompressedTextureETC::GetName() const {
return kWebGLCompressedTextureETCName;
}
-WebGLCompressedTextureETC* WebGLCompressedTextureETC::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<WebGLCompressedTextureETC>(context);
-}
-
bool WebGLCompressedTextureETC::Supported(WebGLRenderingContextBase* context) {
Extensions3DUtil* extensions_util = context->ExtensionsUtil();
return extensions_util->SupportsExtension("GL_ANGLE_compressed_texture_etc");
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc.h
index eca56909ba4..f000d45cdda 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc.h
@@ -13,7 +13,6 @@ class WebGLCompressedTextureETC final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static WebGLCompressedTextureETC* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc1.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc1.cc
index 0558499b496..7d25d3fb6ba 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc1.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc1.cc
@@ -21,11 +21,6 @@ WebGLExtensionName WebGLCompressedTextureETC1::GetName() const {
return kWebGLCompressedTextureETC1Name;
}
-WebGLCompressedTextureETC1* WebGLCompressedTextureETC1::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<WebGLCompressedTextureETC1>(context);
-}
-
bool WebGLCompressedTextureETC1::Supported(WebGLRenderingContextBase* context) {
Extensions3DUtil* extensions_util = context->ExtensionsUtil();
return extensions_util->SupportsExtension(
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc1.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc1.h
index afd69b8d6b1..c00fe32b7da 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc1.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc1.h
@@ -13,7 +13,6 @@ class WebGLCompressedTextureETC1 final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static WebGLCompressedTextureETC1* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_pvrtc.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_pvrtc.cc
index b6d88b81397..93964d92b85 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_pvrtc.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_pvrtc.cc
@@ -45,11 +45,6 @@ WebGLExtensionName WebGLCompressedTexturePVRTC::GetName() const {
return kWebGLCompressedTexturePVRTCName;
}
-WebGLCompressedTexturePVRTC* WebGLCompressedTexturePVRTC::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<WebGLCompressedTexturePVRTC>(context);
-}
-
bool WebGLCompressedTexturePVRTC::Supported(
WebGLRenderingContextBase* context) {
return context->ExtensionsUtil()->SupportsExtension(
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_pvrtc.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_pvrtc.h
index 67c62fc9e0d..acf2f9f01b7 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_pvrtc.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_pvrtc.h
@@ -34,7 +34,6 @@ class WebGLCompressedTexturePVRTC final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static WebGLCompressedTexturePVRTC* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc.cc
index 3fd26280eed..12dd4a9752b 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc.cc
@@ -51,11 +51,6 @@ WebGLExtensionName WebGLCompressedTextureS3TC::GetName() const {
return kWebGLCompressedTextureS3TCName;
}
-WebGLCompressedTextureS3TC* WebGLCompressedTextureS3TC::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<WebGLCompressedTextureS3TC>(context);
-}
-
bool WebGLCompressedTextureS3TC::Supported(WebGLRenderingContextBase* context) {
Extensions3DUtil* extensions_util = context->ExtensionsUtil();
return extensions_util->SupportsExtension(
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc.h
index 5e8d2c531cf..cf12323442a 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc.h
@@ -34,7 +34,6 @@ class WebGLCompressedTextureS3TC final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static WebGLCompressedTextureS3TC* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc_srgb.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc_srgb.cc
index 9d417dd9ab6..560ac18451a 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc_srgb.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc_srgb.cc
@@ -26,11 +26,6 @@ WebGLExtensionName WebGLCompressedTextureS3TCsRGB::GetName() const {
return kWebGLCompressedTextureS3TCsRGBName;
}
-WebGLCompressedTextureS3TCsRGB* WebGLCompressedTextureS3TCsRGB::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<WebGLCompressedTextureS3TCsRGB>(context);
-}
-
bool WebGLCompressedTextureS3TCsRGB::Supported(
WebGLRenderingContextBase* context) {
Extensions3DUtil* extensions_util = context->ExtensionsUtil();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc_srgb.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc_srgb.h
index 7e44399c31c..2d26b81a97b 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc_srgb.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc_srgb.h
@@ -13,7 +13,6 @@ class WebGLCompressedTextureS3TCsRGB final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static WebGLCompressedTextureS3TCsRGB* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_attribute_helpers.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_attribute_helpers.h
index 61988273ac7..ba1fd7aa9b4 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_attribute_helpers.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_attribute_helpers.h
@@ -6,8 +6,8 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_CONTEXT_ATTRIBUTE_HELPERS_H_
#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_webgl_context_attributes.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h"
-#include "third_party/blink/renderer/modules/webgl/webgl_context_attributes.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace gl {
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 7b799dae9ca..7bfb22a7b4f 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(blink::Visitor* visitor) {
+void WebGLContextEvent::Trace(Visitor* visitor) {
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 0b9c207f9f9..beac6933836 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
@@ -26,8 +26,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_CONTEXT_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_CONTEXT_EVENT_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_webgl_context_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
-#include "third_party/blink/renderer/modules/webgl/webgl_context_event_init.h"
namespace blink {
@@ -56,7 +56,7 @@ class WebGLContextEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
String status_message_;
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_event.idl b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_event.idl
index f08c814764b..e7bf82025c9 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_event.idl
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_event.idl
@@ -25,8 +25,7 @@
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15
-[
- Constructor(DOMString type, optional WebGLContextEventInit eventInit)
-] interface WebGLContextEvent : Event {
+interface WebGLContextEvent : Event {
+ constructor(DOMString type, optional WebGLContextEventInit eventInit = {});
readonly attribute DOMString statusMessage;
};
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 8e114e35d14..355434b9d20 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(blink::Visitor* visitor) { visitor->Trace(contexts_); }
+ void Trace(Visitor* visitor) { 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 fd0a1de2bfe..4ed4e0b7141 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(blink::Visitor* visitor) {
+void WebGLContextObject::Trace(Visitor* visitor) {
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 e7c535598ad..15fce90b530 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
explicit WebGLContextObject(WebGLRenderingContextBase*);
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_debug_renderer_info.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_debug_renderer_info.cc
index 9a16dd71399..88113032285 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_debug_renderer_info.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_debug_renderer_info.cc
@@ -35,11 +35,6 @@ WebGLExtensionName WebGLDebugRendererInfo::GetName() const {
return kWebGLDebugRendererInfoName;
}
-WebGLDebugRendererInfo* WebGLDebugRendererInfo::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<WebGLDebugRendererInfo>(context);
-}
-
bool WebGLDebugRendererInfo::Supported(WebGLRenderingContextBase*) {
return true;
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_debug_renderer_info.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_debug_renderer_info.h
index 6746429fb4d..ffe6e23ffb0 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_debug_renderer_info.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_debug_renderer_info.h
@@ -39,8 +39,6 @@ class WebGLDebugRendererInfo final : public WebGLExtension {
kUnmaskedRendererWebgl = 0x9246
};
- static WebGLDebugRendererInfo* Create(WebGLRenderingContextBase*);
-
explicit WebGLDebugRendererInfo(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_debug_shaders.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_debug_shaders.cc
index 0f3595ad993..6d1dc7b9bae 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_debug_shaders.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_debug_shaders.cc
@@ -42,11 +42,6 @@ WebGLExtensionName WebGLDebugShaders::GetName() const {
return kWebGLDebugShadersName;
}
-WebGLDebugShaders* WebGLDebugShaders::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<WebGLDebugShaders>(context);
-}
-
String WebGLDebugShaders::getTranslatedShaderSource(WebGLShader* shader) {
WebGLExtensionScopedContext scoped(this);
if (scoped.IsLost())
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_debug_shaders.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_debug_shaders.h
index 64945ba4bad..45352c09811 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_debug_shaders.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_debug_shaders.h
@@ -36,7 +36,6 @@ class WebGLDebugShaders final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static WebGLDebugShaders* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_depth_texture.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_depth_texture.cc
index e472f987d78..8ccadaaa730 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_depth_texture.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_depth_texture.cc
@@ -37,11 +37,6 @@ WebGLExtensionName WebGLDepthTexture::GetName() const {
return kWebGLDepthTextureName;
}
-WebGLDepthTexture* WebGLDepthTexture::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<WebGLDepthTexture>(context);
-}
-
bool WebGLDepthTexture::Supported(WebGLRenderingContextBase* context) {
Extensions3DUtil* extensions_util = context->ExtensionsUtil();
// Emulating the UNSIGNED_INT_24_8_WEBGL texture internal format in terms
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_depth_texture.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_depth_texture.h
index f8885ddb07b..2a7cf5de5cd 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_depth_texture.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_depth_texture.h
@@ -34,7 +34,6 @@ class WebGLDepthTexture final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static WebGLDepthTexture* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_draw_buffers.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_draw_buffers.cc
index b60fcbfc7b9..066b69e4b06 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_draw_buffers.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_draw_buffers.cc
@@ -39,10 +39,6 @@ WebGLExtensionName WebGLDrawBuffers::GetName() const {
return kWebGLDrawBuffersName;
}
-WebGLDrawBuffers* WebGLDrawBuffers::Create(WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<WebGLDrawBuffers>(context);
-}
-
// static
bool WebGLDrawBuffers::Supported(WebGLRenderingContextBase* context) {
return context->ExtensionsUtil()->SupportsExtension("GL_EXT_draw_buffers");
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_draw_buffers.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_draw_buffers.h
index b60aaeb039b..f634a1d79bb 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_draw_buffers.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_draw_buffers.h
@@ -35,7 +35,6 @@ class WebGLDrawBuffers final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static WebGLDrawBuffers* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_draw_instanced_base_vertex_base_instance.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_draw_instanced_base_vertex_base_instance.cc
index 92c4d7309a0..4bca3959dcd 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_draw_instanced_base_vertex_base_instance.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_draw_instanced_base_vertex_base_instance.cc
@@ -42,13 +42,6 @@ WebGLExtensionName WebGLDrawInstancedBaseVertexBaseInstance::GetName() const {
return kWebGLDrawInstancedBaseVertexBaseInstanceName;
}
-WebGLDrawInstancedBaseVertexBaseInstance*
-WebGLDrawInstancedBaseVertexBaseInstance::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<WebGLDrawInstancedBaseVertexBaseInstance>(
- context);
-}
-
// static
bool WebGLDrawInstancedBaseVertexBaseInstance::Supported(
WebGLRenderingContextBase* context) {
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_draw_instanced_base_vertex_base_instance.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_draw_instanced_base_vertex_base_instance.h
index 16388a5077f..047f1c48e17 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_draw_instanced_base_vertex_base_instance.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_draw_instanced_base_vertex_base_instance.h
@@ -35,8 +35,6 @@ class WebGLDrawInstancedBaseVertexBaseInstance final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static WebGLDrawInstancedBaseVertexBaseInstance* Create(
- WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
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 bb576c936cb..71a521f322a 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_extension.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_extension.cc
@@ -31,12 +31,10 @@ WebGLExtensionScopedContext::WebGLExtensionScopedContext(
WebGLExtension* extension)
: context_(extension->context_) {}
-WebGLExtensionScopedContext::~WebGLExtensionScopedContext() = default;
-
WebGLExtension::WebGLExtension(WebGLRenderingContextBase* context)
: context_(context) {}
-void WebGLExtension::Trace(blink::Visitor* visitor) {
+void WebGLExtension::Trace(Visitor* visitor) {
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 adc2b412788..b1f25d189a0 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_extension.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_extension.h
@@ -40,13 +40,12 @@ class WebGLExtensionScopedContext final {
public:
explicit WebGLExtensionScopedContext(WebGLExtension*);
- ~WebGLExtensionScopedContext();
bool IsLost() const { return !context_; }
- WebGLRenderingContextBase* Context() const { return context_.Get(); }
+ WebGLRenderingContextBase* Context() const { return context_; }
private:
- Member<WebGLRenderingContextBase> context_;
+ WebGLRenderingContextBase* context_;
DISALLOW_COPY_AND_ASSIGN(WebGLExtensionScopedContext);
};
@@ -62,7 +61,7 @@ class WebGLExtension : public ScriptWrappable {
bool IsLost() { return !context_; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 2126c6bc4d1..d67dea6c0e1 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
@@ -19,8 +19,11 @@ enum WebGLExtensionName {
kEXTFragDepthName,
kEXTShaderTextureLODName,
kEXTsRGBName,
- kKHRParallelShaderCompileName,
+ kEXTTextureCompressionBPTCName,
+ kEXTTextureCompressionRGTCName,
kEXTTextureFilterAnisotropicName,
+ kEXTTextureNorm16Name,
+ kKHRParallelShaderCompileName,
kOESElementIndexUintName,
kOESFboRenderMipmapName,
kOESStandardDerivativesName,
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_fence_sync.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_fence_sync.cc
index 2cdb82072f2..4c56d69f6ae 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_fence_sync.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_fence_sync.cc
@@ -10,18 +10,13 @@
namespace blink {
-WebGLSync* WebGLFenceSync::Create(WebGL2RenderingContextBase* ctx,
- GLenum condition,
- GLbitfield flags) {
- DCHECK(condition == GL_SYNC_GPU_COMMANDS_COMPLETE);
- DCHECK(flags == 0);
- return MakeGarbageCollected<WebGLFenceSync>(ctx, condition, flags);
-}
-
WebGLFenceSync::WebGLFenceSync(WebGL2RenderingContextBase* ctx,
GLenum condition,
GLbitfield flags)
- : WebGLSync(ctx, insertQuery(ctx), GL_SYNC_FENCE) {}
+ : WebGLSync(ctx, insertQuery(ctx), GL_SYNC_FENCE) {
+ DCHECK(condition == GL_SYNC_GPU_COMMANDS_COMPLETE);
+ DCHECK_EQ(flags, 0u);
+}
GLuint WebGLFenceSync::insertQuery(WebGL2RenderingContextBase* ctx) {
auto* gl = ctx->ContextGL();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_fence_sync.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_fence_sync.h
index 7612adfade1..c1e68776257 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_fence_sync.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_fence_sync.h
@@ -13,10 +13,6 @@ class WebGL2RenderingContextBase;
class WebGLFenceSync : public WebGLSync {
public:
- static WebGLSync* Create(WebGL2RenderingContextBase*,
- GLenum condition,
- GLbitfield flags);
-
WebGLFenceSync(WebGL2RenderingContextBase*,
GLenum condition,
GLbitfield flags);
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 a8d4232c21d..d284827c9f5 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.cc
@@ -41,11 +41,9 @@ const char kIncompleteOpaque[] =
class WebGLRenderbufferAttachment final
: public WebGLFramebuffer::WebGLAttachment {
public:
- static WebGLFramebuffer::WebGLAttachment* Create(WebGLRenderbuffer*);
-
explicit WebGLRenderbufferAttachment(WebGLRenderbuffer*);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
const char* NameInHeapSnapshot() const override { return "WebGLAttachment"; }
private:
@@ -63,12 +61,7 @@ class WebGLRenderbufferAttachment final
Member<WebGLRenderbuffer> renderbuffer_;
};
-WebGLFramebuffer::WebGLAttachment* WebGLRenderbufferAttachment::Create(
- WebGLRenderbuffer* renderbuffer) {
- return MakeGarbageCollected<WebGLRenderbufferAttachment>(renderbuffer);
-}
-
-void WebGLRenderbufferAttachment::Trace(blink::Visitor* visitor) {
+void WebGLRenderbufferAttachment::Trace(Visitor* visitor) {
visitor->Trace(renderbuffer_);
WebGLFramebuffer::WebGLAttachment::Trace(visitor);
}
@@ -109,17 +102,12 @@ void WebGLRenderbufferAttachment::Unattach(gpu::gles2::GLES2Interface* gl,
class WebGLTextureAttachment final : public WebGLFramebuffer::WebGLAttachment {
public:
- static WebGLFramebuffer::WebGLAttachment* Create(WebGLTexture*,
- GLenum target,
- GLint level,
- GLint layer);
-
WebGLTextureAttachment(WebGLTexture*,
GLenum target,
GLint level,
GLint layer);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
const char* NameInHeapSnapshot() const override {
return "WebGLTextureAttachment";
}
@@ -142,16 +130,7 @@ class WebGLTextureAttachment final : public WebGLFramebuffer::WebGLAttachment {
GLint layer_;
};
-WebGLFramebuffer::WebGLAttachment* WebGLTextureAttachment::Create(
- WebGLTexture* texture,
- GLenum target,
- GLint level,
- GLint layer) {
- return MakeGarbageCollected<WebGLTextureAttachment>(texture, target, level,
- layer);
-}
-
-void WebGLTextureAttachment::Trace(blink::Visitor* visitor) {
+void WebGLTextureAttachment::Trace(Visitor* visitor) {
visitor->Trace(texture_);
WebGLFramebuffer::WebGLAttachment::Trace(visitor);
}
@@ -204,13 +183,12 @@ void WebGLTextureAttachment::Unattach(gpu::gles2::GLES2Interface* gl,
WebGLFramebuffer::WebGLAttachment::WebGLAttachment() = default;
-WebGLFramebuffer* WebGLFramebuffer::Create(WebGLRenderingContextBase* ctx) {
- return MakeGarbageCollected<WebGLFramebuffer>(ctx, false);
-}
-
-WebGLFramebuffer* WebGLFramebuffer::CreateOpaque(
- WebGLRenderingContextBase* ctx) {
- return MakeGarbageCollected<WebGLFramebuffer>(ctx, true);
+WebGLFramebuffer* WebGLFramebuffer::CreateOpaque(WebGLRenderingContextBase* ctx,
+ bool has_stencil) {
+ WebGLFramebuffer* const fb =
+ MakeGarbageCollected<WebGLFramebuffer>(ctx, true);
+ fb->SetOpaqueHasStencil(has_stencil);
+ return fb;
}
WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContextBase* ctx, bool opaque)
@@ -391,10 +369,14 @@ GLenum WebGLFramebuffer::CheckDepthStencilStatus(const char** reason) const {
}
bool WebGLFramebuffer::HasStencilBuffer() const {
- WebGLAttachment* attachment = GetAttachment(GL_STENCIL_ATTACHMENT);
- if (!attachment)
- attachment = GetAttachment(GL_DEPTH_STENCIL_ATTACHMENT);
- return attachment && attachment->Valid();
+ if (opaque_) {
+ return opaque_has_stencil_;
+ } else {
+ WebGLAttachment* attachment = GetAttachment(GL_STENCIL_ATTACHMENT);
+ if (!attachment)
+ attachment = GetAttachment(GL_DEPTH_STENCIL_ATTACHMENT);
+ return attachment && attachment->Valid();
+ }
}
void WebGLFramebuffer::DeleteObjectImpl(gpu::gles2::GLES2Interface* gl) {
@@ -459,8 +441,9 @@ void WebGLFramebuffer::SetAttachmentInternal(GLenum target,
DCHECK(object_);
RemoveAttachmentInternal(target, attachment);
if (texture && texture->Object()) {
- attachments_.insert(attachment, WebGLTextureAttachment::Create(
- texture, tex_target, level, layer));
+ attachments_.insert(attachment,
+ MakeGarbageCollected<WebGLTextureAttachment>(
+ texture, tex_target, level, layer));
DrawBuffersIfNecessary(false);
texture->OnAttached();
}
@@ -473,8 +456,9 @@ void WebGLFramebuffer::SetAttachmentInternal(GLenum target,
DCHECK(object_);
RemoveAttachmentInternal(target, attachment);
if (renderbuffer && renderbuffer->Object()) {
- attachments_.insert(attachment,
- WebGLRenderbufferAttachment::Create(renderbuffer));
+ attachments_.insert(
+ attachment,
+ MakeGarbageCollected<WebGLRenderbufferAttachment>(renderbuffer));
DrawBuffersIfNecessary(false);
renderbuffer->OnAttached();
}
@@ -563,7 +547,7 @@ GLenum WebGLFramebuffer::GetDrawBuffer(GLenum draw_buffer) {
return GL_NONE;
}
-void WebGLFramebuffer::Trace(blink::Visitor* visitor) {
+void WebGLFramebuffer::Trace(Visitor* visitor) {
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 98ec17ddf34..d379ed20a99 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.h
@@ -59,21 +59,20 @@ class WebGLFramebuffer final : public WebGLContextObject {
GLenum target,
GLenum attachment) = 0;
- virtual void Trace(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
protected:
WebGLAttachment();
};
- explicit WebGLFramebuffer(WebGLRenderingContextBase*, bool opaque);
+ explicit WebGLFramebuffer(WebGLRenderingContextBase*, bool opaque = false);
~WebGLFramebuffer() override;
- static WebGLFramebuffer* Create(WebGLRenderingContextBase*);
-
// An opaque framebuffer is one whose attachments are created and managed by
// the browser and not inspectable or alterable via Javascript. This is
// primarily used by the VRWebGLLayer interface.
- static WebGLFramebuffer* CreateOpaque(WebGLRenderingContextBase*);
+ static WebGLFramebuffer* CreateOpaque(WebGLRenderingContextBase*,
+ bool has_stencil);
GLuint Object() const { return object_; }
@@ -110,6 +109,9 @@ class WebGLFramebuffer final : public WebGLContextObject {
bool Opaque() const { return opaque_; }
void MarkOpaqueBufferComplete(bool complete) { opaque_complete_ = complete; }
+ void SetOpaqueHasStencil(bool has_stencil) {
+ opaque_has_stencil_ = has_stencil;
+ }
// Wrapper for drawBuffersEXT/drawBuffersARB to work around a driver bug.
void DrawBuffers(const Vector<GLenum>& bufs);
@@ -120,7 +122,7 @@ class WebGLFramebuffer final : public WebGLContextObject {
GLenum GetReadBuffer() const { return read_buffer_; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
const char* NameInHeapSnapshot() const override { return "WebGLFramebuffer"; }
protected:
@@ -162,6 +164,7 @@ class WebGLFramebuffer final : public WebGLContextObject {
bool web_gl1_depth_stencil_consistent_;
bool contents_changed_ = false;
const bool opaque_;
+ bool opaque_has_stencil_ = false;
bool opaque_complete_ = false;
Vector<GLenum> draw_buffers_;
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_lose_context.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_lose_context.cc
index 28a643c23b0..a39cdae44bb 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_lose_context.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_lose_context.cc
@@ -41,10 +41,6 @@ WebGLExtensionName WebGLLoseContext::GetName() const {
return kWebGLLoseContextName;
}
-WebGLLoseContext* WebGLLoseContext::Create(WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<WebGLLoseContext>(context);
-}
-
void WebGLLoseContext::loseContext() {
WebGLExtensionScopedContext scoped(this);
if (!scoped.IsLost()) {
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_lose_context.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_lose_context.h
index 19b168fab73..671647922fc 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_lose_context.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_lose_context.h
@@ -36,7 +36,6 @@ class WebGLLoseContext final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static WebGLLoseContext* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_multi_draw.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_multi_draw.cc
index 9316eab52a9..d3dcaca00a8 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_multi_draw.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_multi_draw.cc
@@ -14,10 +14,6 @@ WebGLMultiDraw::WebGLMultiDraw(WebGLRenderingContextBase* context)
context->ExtensionsUtil()->EnsureExtensionEnabled("GL_ANGLE_multi_draw");
}
-WebGLMultiDraw* WebGLMultiDraw::Create(WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<WebGLMultiDraw>(context);
-}
-
WebGLExtensionName WebGLMultiDraw::GetName() const {
return kWebGLMultiDrawName;
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_multi_draw.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_multi_draw.h
index aa579c1890a..162721f98c6 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_multi_draw.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_multi_draw.h
@@ -17,7 +17,6 @@ class WebGLMultiDraw final : public WebGLExtension,
DEFINE_WRAPPERTYPEINFO();
public:
- static WebGLMultiDraw* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_multi_draw_instanced_base_vertex_base_instance.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_multi_draw_instanced_base_vertex_base_instance.cc
index 13c6d68a700..9bdd5fed441 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_multi_draw_instanced_base_vertex_base_instance.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_multi_draw_instanced_base_vertex_base_instance.cc
@@ -20,13 +20,6 @@ WebGLMultiDrawInstancedBaseVertexBaseInstance::
context->ExtensionsUtil()->EnsureExtensionEnabled("GL_ANGLE_multi_draw");
}
-WebGLMultiDrawInstancedBaseVertexBaseInstance*
-WebGLMultiDrawInstancedBaseVertexBaseInstance::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<WebGLMultiDrawInstancedBaseVertexBaseInstance>(
- context);
-}
-
WebGLExtensionName WebGLMultiDrawInstancedBaseVertexBaseInstance::GetName()
const {
return kWebGLMultiDrawInstancedBaseVertexBaseInstanceName;
@@ -37,13 +30,18 @@ bool WebGLMultiDrawInstancedBaseVertexBaseInstance::Supported(
// Logic: IsSupportedByValidating || IsSupportedByPassthroughOnANGLE
// GL_ANGLE_base_vertex_base_instance is removed from supports if we requested
// GL_WEBGL_draw_instanced_base_vertex_base_instance first
- // So we need to add a or for
+ // So we need to add an OR for
// GL_WEBGL_draw_instanced_base_vertex_base_instance
+ // Same happens for GL_ANGLE_multi_draw if GL_WEBGL_multi_draw is requested
+ // first
return (context->ExtensionsUtil()->SupportsExtension(
"GL_WEBGL_draw_instanced_base_vertex_base_instance") &&
context->ExtensionsUtil()->SupportsExtension(
"GL_WEBGL_multi_draw_instanced_base_vertex_base_instance")) ||
- (context->ExtensionsUtil()->SupportsExtension("GL_ANGLE_multi_draw") &&
+ ((context->ExtensionsUtil()->SupportsExtension(
+ "GL_ANGLE_multi_draw") ||
+ context->ExtensionsUtil()->EnsureExtensionEnabled(
+ "GL_WEBGL_multi_draw")) &&
(context->ExtensionsUtil()->SupportsExtension(
"GL_ANGLE_base_vertex_base_instance") ||
context->ExtensionsUtil()->SupportsExtension(
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_multi_draw_instanced_base_vertex_base_instance.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_multi_draw_instanced_base_vertex_base_instance.h
index 97f8a266198..c8032122a62 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_multi_draw_instanced_base_vertex_base_instance.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_multi_draw_instanced_base_vertex_base_instance.h
@@ -17,8 +17,6 @@ class WebGLMultiDrawInstancedBaseVertexBaseInstance final
DEFINE_WRAPPERTYPEINFO();
public:
- static WebGLMultiDrawInstancedBaseVertexBaseInstance* Create(
- WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
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 48372fe09d6..974e0b31744 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_program.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_program.cc
@@ -31,10 +31,6 @@
namespace blink {
-WebGLProgram* WebGLProgram::Create(WebGLRenderingContextBase* ctx) {
- return MakeGarbageCollected<WebGLProgram>(ctx);
-}
-
WebGLProgram::WebGLProgram(WebGLRenderingContextBase* ctx)
: WebGLSharedPlatform3DObject(ctx),
link_status_(false),
@@ -177,7 +173,7 @@ void WebGLProgram::setLinkStatus(bool link_status) {
info_valid_ = true;
}
-void WebGLProgram::Trace(blink::Visitor* visitor) {
+void WebGLProgram::Trace(Visitor* visitor) {
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 ce155697aec..39ac2478493 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_program.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_program.h
@@ -39,8 +39,6 @@ class WebGLProgram final : public WebGLSharedPlatform3DObject {
explicit WebGLProgram(WebGLRenderingContextBase*);
~WebGLProgram() override;
- static WebGLProgram* Create(WebGLRenderingContextBase*);
-
bool LinkStatus(WebGLRenderingContextBase*);
void setLinkStatus(bool link_status);
@@ -73,7 +71,7 @@ class WebGLProgram final : public WebGLSharedPlatform3DObject {
bool AttachShader(WebGLShader*);
bool DetachShader(WebGLShader*);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
void DeleteObjectImpl(gpu::gles2::GLES2Interface*) override;
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_query.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_query.cc
index 6b533e6ebd7..52c1dbdc320 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_query.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_query.cc
@@ -11,23 +11,13 @@
namespace blink {
-WebGLQuery* WebGLQuery::Create(WebGL2RenderingContextBase* ctx) {
- return MakeGarbageCollected<WebGLQuery>(ctx);
-}
-
WebGLQuery::WebGLQuery(WebGL2RenderingContextBase* ctx)
: WebGLSharedPlatform3DObject(ctx),
target_(0),
can_update_availability_(false),
query_result_available_(false),
- query_result_(0) {
- if (ctx->canvas()) {
- task_runner_ =
- ctx->canvas()->GetDocument().GetTaskRunner(TaskType::kInternalDefault);
- } else {
- // Fallback for OffscreenCanvas (no frame scheduler)
- task_runner_ = Thread::Current()->GetTaskRunner();
- }
+ query_result_(0),
+ task_runner_(ctx->GetContextTaskRunner()) {
GLuint query;
ctx->ContextGL()->GenQueriesEXT(1, &query);
SetObject(query);
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_query.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_query.h
index 3258c409ed7..ab6949b304e 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_query.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_query.h
@@ -26,8 +26,6 @@ class WebGLQuery : public WebGLSharedPlatform3DObject {
explicit WebGLQuery(WebGL2RenderingContextBase*);
~WebGLQuery() override;
- static WebGLQuery* Create(WebGL2RenderingContextBase*);
-
void SetTarget(GLenum);
bool HasTarget() const { return target_ != 0; }
GLenum GetTarget() const { return target_; }
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 34255af9643..13a26a1b357 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.cc
@@ -30,10 +30,6 @@
namespace blink {
-WebGLRenderbuffer* WebGLRenderbuffer::Create(WebGLRenderingContextBase* ctx) {
- return MakeGarbageCollected<WebGLRenderbuffer>(ctx);
-}
-
WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContextBase* ctx)
: WebGLSharedPlatform3DObject(ctx),
internal_format_(GL_RGBA4),
@@ -63,7 +59,7 @@ int WebGLRenderbuffer::UpdateMultisampleState(bool multisampled) {
return result;
}
-void WebGLRenderbuffer::Trace(blink::Visitor* visitor) {
+void WebGLRenderbuffer::Trace(Visitor* visitor) {
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 dd1897f2cec..f23439ffce6 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.h
@@ -38,8 +38,6 @@ class WebGLRenderbuffer final : public WebGLSharedPlatform3DObject {
explicit WebGLRenderbuffer(WebGLRenderingContextBase*);
~WebGLRenderbuffer() override;
- static WebGLRenderbuffer* Create(WebGLRenderingContextBase*);
-
void SetInternalFormat(GLenum internalformat) {
internal_format_ = internalformat;
}
@@ -63,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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 3a068aec4e9..372521b1e0c 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
@@ -44,6 +44,8 @@
#include "third_party/blink/renderer/modules/webgl/ext_frag_depth.h"
#include "third_party/blink/renderer/modules/webgl/ext_shader_texture_lod.h"
#include "third_party/blink/renderer/modules/webgl/ext_srgb.h"
+#include "third_party/blink/renderer/modules/webgl/ext_texture_compression_bptc.h"
+#include "third_party/blink/renderer/modules/webgl/ext_texture_compression_rgtc.h"
#include "third_party/blink/renderer/modules/webgl/ext_texture_filter_anisotropic.h"
#include "third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.h"
#include "third_party/blink/renderer/modules/webgl/oes_element_index_uint.h"
@@ -156,47 +158,46 @@ void WebGLRenderingContext::RegisterContextExtensions() {
"", "WEBKIT_", nullptr,
};
- RegisterExtension<ANGLEInstancedArrays>(angle_instanced_arrays_);
- RegisterExtension<EXTBlendMinMax>(ext_blend_min_max_);
- RegisterExtension<EXTColorBufferHalfFloat>(ext_color_buffer_half_float_);
- RegisterExtension<EXTDisjointTimerQuery>(ext_disjoint_timer_query_);
- RegisterExtension<EXTFloatBlend>(ext_float_blend_);
- RegisterExtension<EXTFragDepth>(ext_frag_depth_);
- RegisterExtension<EXTShaderTextureLOD>(ext_shader_texture_lod_);
- RegisterExtension<EXTTextureFilterAnisotropic>(
- ext_texture_filter_anisotropic_, kApprovedExtension, kBothPrefixes);
- RegisterExtension<EXTsRGB>(exts_rgb_);
- RegisterExtension<KHRParallelShaderCompile>(khr_parallel_shader_compile_);
- RegisterExtension<OESElementIndexUint>(oes_element_index_uint_);
- RegisterExtension<OESFboRenderMipmap>(oes_fbo_render_mipmap_);
- RegisterExtension<OESStandardDerivatives>(oes_standard_derivatives_);
- RegisterExtension<OESTextureFloat>(oes_texture_float_);
- RegisterExtension<OESTextureFloatLinear>(oes_texture_float_linear_);
- RegisterExtension<OESTextureHalfFloat>(oes_texture_half_float_);
- RegisterExtension<OESTextureHalfFloatLinear>(oes_texture_half_float_linear_);
- RegisterExtension<OESVertexArrayObject>(oes_vertex_array_object_);
- RegisterExtension<WebGLColorBufferFloat>(webgl_color_buffer_float_);
- RegisterExtension<WebGLCompressedTextureASTC>(webgl_compressed_texture_astc_);
- RegisterExtension<WebGLCompressedTextureETC>(webgl_compressed_texture_etc_);
- RegisterExtension<WebGLCompressedTextureETC1>(webgl_compressed_texture_etc1_);
- RegisterExtension<WebGLCompressedTexturePVRTC>(
- webgl_compressed_texture_pvrtc_, kApprovedExtension, kBothPrefixes);
- RegisterExtension<WebGLCompressedTextureS3TC>(
- webgl_compressed_texture_s3tc_, kApprovedExtension, kBothPrefixes);
- RegisterExtension<WebGLCompressedTextureS3TCsRGB>(
- webgl_compressed_texture_s3tc_srgb_);
- RegisterExtension<WebGLDebugRendererInfo>(webgl_debug_renderer_info_);
- RegisterExtension<WebGLDebugShaders>(webgl_debug_shaders_);
- RegisterExtension<WebGLDepthTexture>(webgl_depth_texture_, kApprovedExtension,
- kBothPrefixes);
- RegisterExtension<WebGLDrawBuffers>(webgl_draw_buffers_);
- RegisterExtension<WebGLLoseContext>(webgl_lose_context_, kApprovedExtension,
- kBothPrefixes);
- RegisterExtension<WebGLMultiDraw>(webgl_multi_draw_, kDraftExtension);
- RegisterExtension<WebGLVideoTexture>(webgl_video_texture_, kDraftExtension);
+ RegisterExtension(angle_instanced_arrays_);
+ RegisterExtension(ext_blend_min_max_);
+ RegisterExtension(ext_color_buffer_half_float_);
+ RegisterExtension(ext_disjoint_timer_query_);
+ RegisterExtension(ext_float_blend_);
+ RegisterExtension(ext_frag_depth_);
+ RegisterExtension(ext_shader_texture_lod_);
+ RegisterExtension(ext_texture_compression_bptc_);
+ RegisterExtension(ext_texture_compression_rgtc_);
+ RegisterExtension(ext_texture_filter_anisotropic_, kApprovedExtension,
+ kBothPrefixes);
+ RegisterExtension(exts_rgb_);
+ RegisterExtension(khr_parallel_shader_compile_);
+ RegisterExtension(oes_element_index_uint_);
+ RegisterExtension(oes_fbo_render_mipmap_);
+ RegisterExtension(oes_standard_derivatives_);
+ RegisterExtension(oes_texture_float_);
+ RegisterExtension(oes_texture_float_linear_);
+ RegisterExtension(oes_texture_half_float_);
+ RegisterExtension(oes_texture_half_float_linear_);
+ RegisterExtension(oes_vertex_array_object_);
+ RegisterExtension(webgl_color_buffer_float_);
+ RegisterExtension(webgl_compressed_texture_astc_);
+ RegisterExtension(webgl_compressed_texture_etc_);
+ RegisterExtension(webgl_compressed_texture_etc1_);
+ RegisterExtension(webgl_compressed_texture_pvrtc_, kApprovedExtension,
+ kBothPrefixes);
+ RegisterExtension(webgl_compressed_texture_s3tc_, kApprovedExtension,
+ kBothPrefixes);
+ RegisterExtension(webgl_compressed_texture_s3tc_srgb_);
+ RegisterExtension(webgl_debug_renderer_info_);
+ RegisterExtension(webgl_debug_shaders_);
+ RegisterExtension(webgl_depth_texture_, kApprovedExtension, kBothPrefixes);
+ RegisterExtension(webgl_draw_buffers_);
+ RegisterExtension(webgl_lose_context_, kApprovedExtension, kBothPrefixes);
+ RegisterExtension(webgl_multi_draw_, kDraftExtension);
+ RegisterExtension(webgl_video_texture_, kDraftExtension);
}
-void WebGLRenderingContext::Trace(blink::Visitor* visitor) {
+void WebGLRenderingContext::Trace(Visitor* visitor) {
visitor->Trace(angle_instanced_arrays_);
visitor->Trace(ext_blend_min_max_);
visitor->Trace(ext_color_buffer_half_float_);
@@ -204,6 +205,8 @@ void WebGLRenderingContext::Trace(blink::Visitor* visitor) {
visitor->Trace(ext_float_blend_);
visitor->Trace(ext_frag_depth_);
visitor->Trace(ext_shader_texture_lod_);
+ visitor->Trace(ext_texture_compression_bptc_);
+ visitor->Trace(ext_texture_compression_rgtc_);
visitor->Trace(ext_texture_filter_anisotropic_);
visitor->Trace(exts_rgb_);
visitor->Trace(khr_parallel_shader_compile_);
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 3bf24b7d407..a4fe51d91ca 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
@@ -42,6 +42,8 @@ class EXTFloatBlend;
class EXTFragDepth;
class EXTShaderTextureLOD;
class EXTsRGB;
+class EXTTextureCompressionBPTC;
+class EXTTextureCompressionRGTC;
class EXTTextureFilterAnisotropic;
class KHRParallelShaderCompile;
class OESElementIndexUint;
@@ -94,7 +96,7 @@ class WebGLRenderingContext final : public WebGLRenderingContextBase {
void SetCanvasGetContextResult(RenderingContext&) final;
void SetOffscreenCanvasGetContextResult(OffscreenRenderingContext&) final;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
// Enabled extension objects.
@@ -105,6 +107,8 @@ class WebGLRenderingContext final : public WebGLRenderingContextBase {
Member<EXTFloatBlend> ext_float_blend_;
Member<EXTFragDepth> ext_frag_depth_;
Member<EXTShaderTextureLOD> ext_shader_texture_lod_;
+ Member<EXTTextureCompressionBPTC> ext_texture_compression_bptc_;
+ Member<EXTTextureCompressionRGTC> ext_texture_compression_rgtc_;
Member<EXTTextureFilterAnisotropic> ext_texture_filter_anisotropic_;
Member<EXTsRGB> exts_rgb_;
Member<KHRParallelShaderCompile> khr_parallel_shader_compile_;
@@ -132,16 +136,6 @@ class WebGLRenderingContext final : public WebGLRenderingContextBase {
Member<WebGLVideoTexture> webgl_video_texture_;
};
-DEFINE_TYPE_CASTS(WebGLRenderingContext,
- CanvasRenderingContext,
- context,
- context->Is3d() &&
- WebGLRenderingContextBase::GetWebGLVersion(context) ==
- Platform::kWebGL1ContextType,
- context.Is3d() &&
- WebGLRenderingContextBase::GetWebGLVersion(&context) ==
- Platform::kWebGL1ContextType);
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_RENDERING_CONTEXT_H_
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 4e518f9dfbb..39d00937e8a 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
@@ -56,6 +56,7 @@
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/origin_trials/origin_trials.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
+#include "third_party/blink/renderer/core/svg/graphics/svg_image.h"
#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h"
#include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
@@ -108,6 +109,7 @@
#include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
+#include "third_party/blink/renderer/platform/heap/heap.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/wtf/cross_thread_functional.h"
@@ -509,7 +511,7 @@ class ScopedTexture2DRestorer {
~ScopedTexture2DRestorer() { context_->RestoreCurrentTexture2D(); }
private:
- Member<WebGLRenderingContextBase> context_;
+ WebGLRenderingContextBase* context_;
};
class ScopedFramebufferRestorer {
@@ -522,7 +524,7 @@ class ScopedFramebufferRestorer {
~ScopedFramebufferRestorer() { context_->RestoreCurrentFramebuffer(); }
private:
- Member<WebGLRenderingContextBase> context_;
+ WebGLRenderingContextBase* context_;
};
class ScopedUnpackParametersResetRestore {
@@ -543,7 +545,7 @@ class ScopedUnpackParametersResetRestore {
}
private:
- Member<WebGLRenderingContextBase> context_;
+ WebGLRenderingContextBase* context_;
bool enabled_;
};
@@ -734,8 +736,8 @@ ImageBitmap* WebGLRenderingContextBase::TransferToImageBitmapBase(
ScriptState* script_state) {
WebFeature feature = WebFeature::kOffscreenCanvasTransferToImageBitmapWebGL;
UseCounter::Count(ExecutionContext::From(script_state), feature);
- return ImageBitmap::Create(
- GetDrawingBuffer()->TransferToStaticBitmapImage(nullptr));
+ return MakeGarbageCollected<ImageBitmap>(
+ GetDrawingBuffer()->TransferToStaticBitmapImage());
}
void WebGLRenderingContextBase::commit() {
@@ -769,16 +771,22 @@ scoped_refptr<StaticBitmapImage> WebGLRenderingContextBase::GetImage(
// Since we are grabbing a snapshot that is not for compositing, we use a
// custom resource provider. This avoids consuming compositing-specific
// resources (e.g. GpuMemoryBuffer)
+ auto color_params = ColorParams();
std::unique_ptr<CanvasResourceProvider> resource_provider =
- CanvasResourceProvider::Create(
- size,
- CanvasResourceProvider::ResourceUsage::kAcceleratedResourceUsage,
- SharedGpuContext::ContextProviderWrapper(), 0,
- GetDrawingBuffer()->FilterQuality(), ColorParams(),
- CanvasResourceProvider::kDefaultPresentationMode,
- nullptr /* canvas_resource_dispatcher */, is_origin_top_left_);
+ CanvasResourceProvider::CreateSharedImageProvider(
+ size, SharedGpuContext::ContextProviderWrapper(),
+ GetDrawingBuffer()->FilterQuality(), color_params,
+ is_origin_top_left_, CanvasResourceProvider::RasterMode::kGPU,
+ 0u /*shared_image_usage_flags*/);
+ // todo(bug 1035589) Check if this cpu fallback is really needed here
+ if (!resource_provider || !resource_provider->IsValid()) {
+ resource_provider = CanvasResourceProvider::CreateBitmapProvider(
+ size, GetDrawingBuffer()->FilterQuality(), color_params);
+ }
+
if (!resource_provider || !resource_provider->IsValid())
return nullptr;
+
if (!CopyRenderingResultsFromDrawingBuffer(resource_provider.get(),
kBackBuffer)) {
// copyRenderingResultsFromDrawingBuffer is expected to always succeed
@@ -791,12 +799,12 @@ scoped_refptr<StaticBitmapImage> WebGLRenderingContextBase::GetImage(
}
ScriptPromise WebGLRenderingContextBase::makeXRCompatible(
- ScriptState* script_state) {
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
if (isContextLost()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError,
- "Context lost."));
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "Context lost.");
+ return ScriptPromise();
}
if (xr_compatible_) {
@@ -811,11 +819,10 @@ ScriptPromise WebGLRenderingContextBase::makeXRCompatible(
// TODO(http://crbug.com/876140) Trigger context loss and recreate on
// compatible GPU.
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotSupportedError,
- "Context is not compatible. Switching not yet implemented."));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotSupportedError,
+ "Context is not compatible. Switching not yet implemented.");
+ return ScriptPromise();
}
bool WebGLRenderingContextBase::IsXRCompatible() {
@@ -875,6 +882,18 @@ static const GLenum kSupportedInternalFormatsTexImageES3[] = {
GL_DEPTH32F_STENCIL8,
};
+// Exposed by EXT_texture_norm16
+static constexpr GLenum kSupportedInternalFormatsEXTTextureNorm16ES3[] = {
+ GL_R16_EXT, GL_RG16_EXT, GL_RGB16_EXT,
+ GL_RGBA16_EXT, GL_R16_SNORM_EXT, GL_RG16_SNORM_EXT,
+ GL_RGB16_SNORM_EXT, GL_RGBA16_SNORM_EXT};
+
+static constexpr GLenum kSupportedFormatsEXTTextureNorm16ES3[] = {GL_RED,
+ GL_RG};
+
+static constexpr GLenum kSupportedTypesEXTTextureNorm16ES3[] = {
+ GL_SHORT, GL_UNSIGNED_SHORT};
+
// Exposed by EXT_color_buffer_float
static const GLenum kSupportedInternalFormatsCopyTexImageFloatES3[] = {
GL_R16F, GL_R32F, GL_RG16F, GL_RG32F, GL_RGB16F,
@@ -1178,7 +1197,7 @@ void WebGLRenderingContextBase::InitializeNewContext() {
read_buffer_of_default_framebuffer_ = GL_BACK;
- default_vertex_array_object_ = WebGLVertexArrayObject::Create(
+ default_vertex_array_object_ = MakeGarbageCollected<WebGLVertexArrayObject>(
this, WebGLVertexArrayObjectBase::kVaoTypeDefault);
bound_vertex_array_object_ = default_vertex_array_object_;
@@ -1234,6 +1253,7 @@ void WebGLRenderingContextBase::InitializeNewContext() {
is_web_gl_depth_texture_formats_types_added_ = false;
is_ext_srgb_formats_types_added_ = false;
is_ext_color_buffer_float_formats_added_ = false;
+ is_ext_texture_norm16_added_ = false;
supported_internal_formats_.clear();
ADD_VALUES_TO_SET(supported_internal_formats_, kSupportedFormatsES2);
@@ -1263,10 +1283,8 @@ void WebGLRenderingContextBase::InitializeNewContext() {
void WebGLRenderingContextBase::SetupFlags() {
DCHECK(GetDrawingBuffer());
if (canvas()) {
- if (Page* p = canvas()->GetDocument().GetPage()) {
- synthesized_errors_to_console_ =
- p->GetSettings().GetWebGLErrorsToConsoleEnabled();
- }
+ synthesized_errors_to_console_ =
+ canvas()->GetDocument().GetSettings()->GetWebGLErrorsToConsoleEnabled();
}
is_depth_stencil_supported_ =
@@ -1370,14 +1388,19 @@ void WebGLRenderingContextBase::MarkContextChanged(
if (!marked_canvas_dirty_) {
marked_canvas_dirty_ = true;
LayoutBox* layout_box = canvas()->GetLayoutBox();
- if (layout_box && layout_box->HasAcceleratedCompositing()) {
+ auto* settings = canvas()->GetDocument().GetSettings();
+ if (layout_box && settings->GetAcceleratedCompositingEnabled())
layout_box->ContentChanged(change_type);
- }
IntSize canvas_size = ClampedCanvasSize();
DidDraw(SkIRect::MakeXYWH(0, 0, canvas_size.Width(), canvas_size.Height()));
}
}
+scoped_refptr<base::SingleThreadTaskRunner>
+WebGLRenderingContextBase::GetContextTaskRunner() {
+ return task_runner_;
+}
+
void WebGLRenderingContextBase::DidDraw(const SkIRect& dirty_rect) {
MarkContextChanged(kCanvasChanged);
CanvasRenderingContext::DidDraw(dirty_rect);
@@ -1389,11 +1412,11 @@ void WebGLRenderingContextBase::DidDraw() {
}
bool WebGLRenderingContextBase::PushFrame() {
- int width = GetDrawingBuffer()->Size().Width();
- int height = GetDrawingBuffer()->Size().Height();
int submitted_frame = false;
if (PaintRenderingResultsToCanvas(kBackBuffer)) {
if (Host()->GetOrCreateCanvasResourceProvider(kPreferAcceleration)) {
+ int width = GetDrawingBuffer()->Size().Width();
+ int height = GetDrawingBuffer()->Size().Height();
submitted_frame =
Host()->PushFrame(Host()->ResourceProvider()->ProduceCanvasResource(),
SkIRect::MakeWH(width, height));
@@ -1543,8 +1566,7 @@ void WebGLRenderingContextBase::SetIsInHiddenPage(bool hidden) {
GetDrawingBuffer()->SetIsInHiddenPage(hidden);
if (!hidden && isContextLost() && restore_allowed_ &&
- auto_recovery_method_ == kAuto) {
- DCHECK(!restore_timer_.IsActive());
+ auto_recovery_method_ == kAuto && !restore_timer_.IsActive()) {
restore_timer_.StartOneShot(base::TimeDelta(), FROM_HERE);
}
}
@@ -1621,23 +1643,23 @@ bool WebGLRenderingContextBase::CopyRenderingResultsFromDrawingBuffer(
SharedGpuContext::ContextProviderWrapper();
if (!shared_context_wrapper || !shared_context_wrapper->ContextProvider())
return false;
- gpu::gles2::GLES2Interface* gl =
- shared_context_wrapper->ContextProvider()->ContextGL();
- GLuint texture_id =
- resource_provider->GetBackingTextureHandleForOverwrite();
+ gpu::raster::RasterInterface* raster_interface =
+ shared_context_wrapper->ContextProvider()->RasterInterface();
+ const gpu::Mailbox& mailbox =
+ resource_provider->GetBackingMailboxForOverwrite(
+ MailboxSyncMode::kOrderingBarrier);
GLenum texture_target = resource_provider->GetBackingTextureTarget();
- if (!texture_id)
+ if (mailbox.IsZero())
return false;
// TODO(xlai): Flush should not be necessary if the synchronization in
// CopyToPlatformTexture is done correctly. See crbug.com/794706.
- gl->Flush();
+ raster_interface->Flush();
bool flip_y = IsOriginTopLeft() != resource_provider->IsOriginTopLeft();
- return drawing_buffer_->CopyToPlatformTexture(
- gl, texture_target, texture_id, 0 /*texture LOD */, true, flip_y,
- IntPoint(0, 0), IntRect(IntPoint(0, 0), drawing_buffer_->Size()),
- source_buffer);
+ return drawing_buffer_->CopyToPlatformMailbox(
+ raster_interface, mailbox, texture_target, flip_y, IntPoint(0, 0),
+ IntRect(IntPoint(0, 0), drawing_buffer_->Size()), source_buffer);
}
// Note: This code path could work for all cases. The only reason there
@@ -1867,8 +1889,11 @@ void WebGLRenderingContextBase::bindTexture(GLenum target,
// We use TEXTURE_EXTERNAL_OES to implement video texture on Android platform
if (target == GL_TEXTURE_VIDEO_IMAGE_WEBGL) {
#if defined(OS_ANDROID)
- ContextGL()->BindTexture(GL_TEXTURE_EXTERNAL_OES, ObjectOrZero(texture));
+ // TODO(crbug.com/776222): Support extension on Android
+ NOTIMPLEMENTED();
+ return;
#else
+ // TODO(crbug.com/776222): Using GL_TEXTURE_VIDEO_IMAGE_WEBGL in blink
ContextGL()->BindTexture(GL_TEXTURE_2D, ObjectOrZero(texture));
if (texture && !texture->GetTarget()) {
ContextGL()->TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
@@ -1993,7 +2018,7 @@ void WebGLRenderingContextBase::bufferData(GLenum target,
if (isContextLost())
return;
DCHECK(data);
- BufferDataImpl(target, data.View()->deprecatedByteLengthAsUnsigned(),
+ BufferDataImpl(target, data.View()->byteLengthAsSizeT(),
data.View()->BaseAddressMaybeShared(), usage);
}
@@ -2032,7 +2057,7 @@ void WebGLRenderingContextBase::bufferSubData(
if (isContextLost())
return;
DCHECK(data);
- BufferSubDataImpl(target, offset, data.ByteLength(),
+ BufferSubDataImpl(target, offset, data.ByteLengthAsSizeT(),
data.BaseAddressMaybeOnStack());
}
@@ -2184,10 +2209,12 @@ void WebGLRenderingContextBase::compressedTexImage2D(
return;
if (!ValidateCompressedTexFormat("compressedTexImage2D", internalformat))
return;
- ContextGL()->CompressedTexImage2D(
- target, level, internalformat, width, height, border,
- data.View()->deprecatedByteLengthAsUnsigned(),
- data.View()->BaseAddressMaybeShared());
+ GLsizei data_length;
+ if (!ExtractDataLengthIfValid("compressedTexImage2D", data, &data_length))
+ return;
+ ContextGL()->CompressedTexImage2D(target, level, internalformat, width,
+ height, border, data_length,
+ data.View()->BaseAddressMaybeShared());
}
void WebGLRenderingContextBase::compressedTexSubImage2D(
@@ -2205,10 +2232,12 @@ void WebGLRenderingContextBase::compressedTexSubImage2D(
return;
if (!ValidateCompressedTexFormat("compressedTexSubImage2D", format))
return;
- ContextGL()->CompressedTexSubImage2D(
- target, level, xoffset, yoffset, width, height, format,
- data.View()->deprecatedByteLengthAsUnsigned(),
- data.View()->BaseAddressMaybeShared());
+ GLsizei data_length;
+ if (!ExtractDataLengthIfValid("compressedTexSubImage2D", data, &data_length))
+ return;
+ ContextGL()->CompressedTexSubImage2D(target, level, xoffset, yoffset, width,
+ height, format, data_length,
+ data.View()->BaseAddressMaybeShared());
}
bool WebGLRenderingContextBase::ValidateSettableTexFormat(
@@ -2302,31 +2331,31 @@ void WebGLRenderingContextBase::copyTexSubImage2D(GLenum target,
WebGLBuffer* WebGLRenderingContextBase::createBuffer() {
if (isContextLost())
return nullptr;
- return WebGLBuffer::Create(this);
+ return MakeGarbageCollected<WebGLBuffer>(this);
}
WebGLFramebuffer* WebGLRenderingContextBase::createFramebuffer() {
if (isContextLost())
return nullptr;
- return WebGLFramebuffer::Create(this);
+ return MakeGarbageCollected<WebGLFramebuffer>(this);
}
WebGLTexture* WebGLRenderingContextBase::createTexture() {
if (isContextLost())
return nullptr;
- return WebGLTexture::Create(this);
+ return MakeGarbageCollected<WebGLTexture>(this);
}
WebGLProgram* WebGLRenderingContextBase::createProgram() {
if (isContextLost())
return nullptr;
- return WebGLProgram::Create(this);
+ return MakeGarbageCollected<WebGLProgram>(this);
}
WebGLRenderbuffer* WebGLRenderingContextBase::createRenderbuffer() {
if (isContextLost())
return nullptr;
- return WebGLRenderbuffer::Create(this);
+ return MakeGarbageCollected<WebGLRenderbuffer>(this);
}
void WebGLRenderingContextBase::SetBoundVertexArrayObject(
@@ -2344,7 +2373,7 @@ WebGLShader* WebGLRenderingContextBase::createShader(GLenum type) {
return nullptr;
}
- return WebGLShader::Create(this, type);
+ return MakeGarbageCollected<WebGLShader>(this, type);
}
void WebGLRenderingContextBase::cullFace(GLenum mode) {
@@ -2829,7 +2858,8 @@ WebGLActiveInfo* WebGLRenderingContextBase::getActiveAttrib(
reinterpret_cast<GLchar*>(name_ptr));
if (size < 0)
return nullptr;
- return WebGLActiveInfo::Create(name_impl->Substring(0, length), type, size);
+ return MakeGarbageCollected<WebGLActiveInfo>(name_impl->Substring(0, length),
+ type, size);
}
WebGLActiveInfo* WebGLRenderingContextBase::getActiveUniform(
@@ -2859,7 +2889,8 @@ WebGLActiveInfo* WebGLRenderingContextBase::getActiveUniform(
reinterpret_cast<GLchar*>(name_ptr));
if (size < 0)
return nullptr;
- return WebGLActiveInfo::Create(name_impl->Substring(0, length), type, size);
+ return MakeGarbageCollected<WebGLActiveInfo>(name_impl->Substring(0, length),
+ type, size);
}
base::Optional<HeapVector<Member<WebGLShader>>>
@@ -3608,7 +3639,8 @@ WebGLShaderPrecisionFormat* WebGLRenderingContextBase::getShaderPrecisionFormat(
GLint precision = 0;
ContextGL()->GetShaderPrecisionFormat(shader_type, precision_type, range,
&precision);
- return WebGLShaderPrecisionFormat::Create(range[0], range[1], precision);
+ return MakeGarbageCollected<WebGLShaderPrecisionFormat>(range[0], range[1],
+ precision);
}
String WebGLRenderingContextBase::getShaderSource(WebGLShader* shader) {
@@ -3972,7 +4004,7 @@ WebGLUniformLocation* WebGLRenderingContextBase::getUniformLocation(
ObjectOrZero(program), name.Utf8().c_str());
if (uniform_location == -1)
return nullptr;
- return WebGLUniformLocation::Create(program, uniform_location);
+ return MakeGarbageCollected<WebGLUniformLocation>(program, uniform_location);
}
ScriptValue WebGLRenderingContextBase::getVertexAttrib(
@@ -4418,7 +4450,8 @@ void WebGLRenderingContextBase::ReadPixelsHelper(GLint x,
base::CheckedNumeric<GLuint> offset_in_bytes = offset;
offset_in_bytes *= pixels->TypeSize();
if (!offset_in_bytes.IsValid() ||
- offset_in_bytes.ValueOrDie() > pixels->deprecatedByteLengthAsUnsigned()) {
+ static_cast<size_t>(offset_in_bytes.ValueOrDie()) >
+ pixels->byteLengthAsSizeT()) {
SynthesizeGLError(GL_INVALID_VALUE, "readPixels",
"destination offset out of range");
return;
@@ -4431,7 +4464,7 @@ void WebGLRenderingContextBase::ReadPixelsHelper(GLint x,
return;
}
base::CheckedNumeric<GLuint> buffer_size =
- pixels->deprecatedByteLengthAsUnsigned() - offset_in_bytes;
+ pixels->byteLengthAsSizeT() - offset_in_bytes;
if (!buffer_size.IsValid()) {
SynthesizeGLError(GL_INVALID_VALUE, "readPixels",
"destination offset out of range");
@@ -4886,7 +4919,7 @@ scoped_refptr<Image> WebGLRenderingContextBase::DrawImageIntoBuffer(
// TODO(ccameron): WebGL should produce sRGB images.
// https://crbug.com/672299
image->Draw(resource_provider->Canvas(), flags, FloatRect(dest_rect),
- FloatRect(src_rect), kDoNotRespectImageOrientation,
+ FloatRect(src_rect), kRespectImageOrientation,
Image::kDoNotClampImageToSourceRect, Image::kSyncDecode);
return resource_provider->Snapshot();
}
@@ -5179,7 +5212,7 @@ void WebGLRenderingContextBase::TexImageHelperHTMLImageElement(
return;
scoped_refptr<Image> image_for_render = image->CachedImage()->GetImage();
- if (image_for_render && image_for_render->IsSVGImage()) {
+ if (IsA<SVGImage>(image_for_render.get())) {
if (canvas()) {
UseCounter::Count(canvas()->GetDocument(), WebFeature::kSVGInWebGL);
}
@@ -5418,7 +5451,7 @@ void WebGLRenderingContextBase::TexImageHelperCanvasRenderingContextHost(
// (e.g. CanUseTexImageViaGPU returning false).
if (is_webgl_canvas && upload_via_gpu) {
source_canvas_webgl_context =
- ToWebGLRenderingContextBase(context_host->RenderingContext());
+ To<WebGLRenderingContextBase>(context_host->RenderingContext());
} else {
image = context_host->GetSourceImageForCanvas(
&source_image_status, kPreferAcceleration,
@@ -5430,14 +5463,15 @@ void WebGLRenderingContextBase::TexImageHelperCanvasRenderingContextHost(
// Still not clear whether we will take the accelerated upload path
// at this point; it depends on what came back from
// CanUseTexImageViaGPU, for example.
+ auto* static_bitmap_image = DynamicTo<StaticBitmapImage>(image.get());
upload_via_gpu &= source_canvas_webgl_context ||
- (image->IsStaticBitmapImage() && image->IsTextureBacked());
+ (static_bitmap_image && image->IsTextureBacked());
if (upload_via_gpu) {
AcceleratedStaticBitmapImage* accel_image = nullptr;
if (image) {
- accel_image = static_cast<AcceleratedStaticBitmapImage*>(
- ToStaticBitmapImage(image.get()));
+ accel_image =
+ static_cast<AcceleratedStaticBitmapImage*>(static_bitmap_image);
}
// The GPU-GPU copy path uses the Y-up coordinate system.
@@ -5584,10 +5618,18 @@ void WebGLRenderingContextBase::TexImageHelperHTMLVideoElement(
source_image_rect == SentinelEmptyRect() ||
source_image_rect ==
IntRect(0, 0, video->videoWidth(), video->videoHeight());
- const bool use_copyTextureCHROMIUM = function_id == kTexImage2D &&
- source_image_rect_is_default &&
- depth == 1 && GL_TEXTURE_2D == target &&
- CanUseTexImageViaGPU(format, type);
+
+ const auto& caps = GetDrawingBuffer()->ContextProvider()->GetCapabilities();
+ const bool may_need_image_external_essl3 =
+ caps.egl_image_external &&
+ Extensions3DUtil::CopyTextureCHROMIUMNeedsESSL3(internalformat);
+ const bool have_image_external_essl3 = caps.egl_image_external_essl3;
+ const bool use_copyTextureCHROMIUM =
+ function_id == kTexImage2D && source_image_rect_is_default &&
+ depth == 1 && GL_TEXTURE_2D == target &&
+ (have_image_external_essl3 || !may_need_image_external_essl3) &&
+ CanUseTexImageViaGPU(format, type);
+
// Format of source video may be 16-bit format, e.g. Y16 format.
// glCopyTextureCHROMIUM requires the source texture to be in 8-bit format.
// Converting 16-bits formated source texture to 8-bits formated texture will
@@ -6017,12 +6059,13 @@ void WebGLRenderingContextBase::uniform1f(const WebGLUniformLocation* location,
}
void WebGLRenderingContextBase::uniform1fv(const WebGLUniformLocation* location,
- const FlexibleFloat32ArrayView& v) {
- if (isContextLost() ||
- !ValidateUniformParameters("uniform1fv", location, v, 1, 0, v.length()))
+ const FlexibleFloat32Array& v) {
+ if (isContextLost() || !ValidateUniformParameters("uniform1fv", location, v,
+ 1, 0, v.lengthAsSizeT()))
return;
- ContextGL()->Uniform1fv(location->Location(), v.length(),
+ ContextGL()->Uniform1fv(location->Location(),
+ base::checked_cast<GLuint>(v.lengthAsSizeT()),
v.DataMaybeOnStack());
}
@@ -6051,12 +6094,13 @@ void WebGLRenderingContextBase::uniform1i(const WebGLUniformLocation* location,
}
void WebGLRenderingContextBase::uniform1iv(const WebGLUniformLocation* location,
- const FlexibleInt32ArrayView& v) {
- if (isContextLost() ||
- !ValidateUniformParameters("uniform1iv", location, v, 1, 0, v.length()))
+ const FlexibleInt32Array& v) {
+ if (isContextLost() || !ValidateUniformParameters("uniform1iv", location, v,
+ 1, 0, v.lengthAsSizeT()))
return;
- ContextGL()->Uniform1iv(location->Location(), v.length(),
+ ContextGL()->Uniform1iv(location->Location(),
+ base::checked_cast<GLuint>(v.lengthAsSizeT()),
v.DataMaybeOnStack());
}
@@ -6086,12 +6130,13 @@ void WebGLRenderingContextBase::uniform2f(const WebGLUniformLocation* location,
}
void WebGLRenderingContextBase::uniform2fv(const WebGLUniformLocation* location,
- const FlexibleFloat32ArrayView& v) {
- if (isContextLost() ||
- !ValidateUniformParameters("uniform2fv", location, v, 2, 0, v.length()))
+ const FlexibleFloat32Array& v) {
+ if (isContextLost() || !ValidateUniformParameters("uniform2fv", location, v,
+ 2, 0, v.lengthAsSizeT()))
return;
- ContextGL()->Uniform2fv(location->Location(), v.length() >> 1,
+ ContextGL()->Uniform2fv(location->Location(),
+ base::checked_cast<GLuint>(v.lengthAsSizeT()) >> 1,
v.DataMaybeOnStack());
}
@@ -6121,12 +6166,13 @@ void WebGLRenderingContextBase::uniform2i(const WebGLUniformLocation* location,
}
void WebGLRenderingContextBase::uniform2iv(const WebGLUniformLocation* location,
- const FlexibleInt32ArrayView& v) {
- if (isContextLost() ||
- !ValidateUniformParameters("uniform2iv", location, v, 2, 0, v.length()))
+ const FlexibleInt32Array& v) {
+ if (isContextLost() || !ValidateUniformParameters("uniform2iv", location, v,
+ 2, 0, v.lengthAsSizeT()))
return;
- ContextGL()->Uniform2iv(location->Location(), v.length() >> 1,
+ ContextGL()->Uniform2iv(location->Location(),
+ base::checked_cast<GLuint>(v.lengthAsSizeT()) >> 1,
v.DataMaybeOnStack());
}
@@ -6157,12 +6203,13 @@ void WebGLRenderingContextBase::uniform3f(const WebGLUniformLocation* location,
}
void WebGLRenderingContextBase::uniform3fv(const WebGLUniformLocation* location,
- const FlexibleFloat32ArrayView& v) {
- if (isContextLost() ||
- !ValidateUniformParameters("uniform3fv", location, v, 3, 0, v.length()))
+ const FlexibleFloat32Array& v) {
+ if (isContextLost() || !ValidateUniformParameters("uniform3fv", location, v,
+ 3, 0, v.lengthAsSizeT()))
return;
- ContextGL()->Uniform3fv(location->Location(), v.length() / 3,
+ ContextGL()->Uniform3fv(location->Location(),
+ base::checked_cast<GLuint>(v.lengthAsSizeT()) / 3,
v.DataMaybeOnStack());
}
@@ -6193,12 +6240,13 @@ void WebGLRenderingContextBase::uniform3i(const WebGLUniformLocation* location,
}
void WebGLRenderingContextBase::uniform3iv(const WebGLUniformLocation* location,
- const FlexibleInt32ArrayView& v) {
- if (isContextLost() ||
- !ValidateUniformParameters("uniform3iv", location, v, 3, 0, v.length()))
+ const FlexibleInt32Array& v) {
+ if (isContextLost() || !ValidateUniformParameters("uniform3iv", location, v,
+ 3, 0, v.lengthAsSizeT()))
return;
- ContextGL()->Uniform3iv(location->Location(), v.length() / 3,
+ ContextGL()->Uniform3iv(location->Location(),
+ base::checked_cast<GLuint>(v.lengthAsSizeT()) / 3,
v.DataMaybeOnStack());
}
@@ -6230,12 +6278,13 @@ void WebGLRenderingContextBase::uniform4f(const WebGLUniformLocation* location,
}
void WebGLRenderingContextBase::uniform4fv(const WebGLUniformLocation* location,
- const FlexibleFloat32ArrayView& v) {
- if (isContextLost() ||
- !ValidateUniformParameters("uniform4fv", location, v, 4, 0, v.length()))
+ const FlexibleFloat32Array& v) {
+ if (isContextLost() || !ValidateUniformParameters("uniform4fv", location, v,
+ 4, 0, v.lengthAsSizeT()))
return;
- ContextGL()->Uniform4fv(location->Location(), v.length() >> 2,
+ ContextGL()->Uniform4fv(location->Location(),
+ base::checked_cast<GLuint>(v.lengthAsSizeT()) >> 2,
v.DataMaybeOnStack());
}
@@ -6267,12 +6316,13 @@ void WebGLRenderingContextBase::uniform4i(const WebGLUniformLocation* location,
}
void WebGLRenderingContextBase::uniform4iv(const WebGLUniformLocation* location,
- const FlexibleInt32ArrayView& v) {
- if (isContextLost() ||
- !ValidateUniformParameters("uniform4iv", location, v, 4, 0, v.length()))
+ const FlexibleInt32Array& v) {
+ if (isContextLost() || !ValidateUniformParameters("uniform4iv", location, v,
+ 4, 0, v.lengthAsSizeT()))
return;
- ContextGL()->Uniform4iv(location->Location(), v.length() >> 2,
+ ContextGL()->Uniform4iv(location->Location(),
+ base::checked_cast<GLuint>(v.lengthAsSizeT()) >> 2,
v.DataMaybeOnStack());
}
@@ -6292,11 +6342,12 @@ void WebGLRenderingContextBase::uniformMatrix2fv(
MaybeShared<DOMFloat32Array> v) {
if (isContextLost() || !ValidateUniformMatrixParameters(
"uniformMatrix2fv", location, transpose, v.View(),
- 4, 0, v.View()->deprecatedLengthAsUnsigned()))
+ 4, 0, v.View()->lengthAsSizeT()))
return;
- ContextGL()->UniformMatrix2fv(location->Location(),
- v.View()->deprecatedLengthAsUnsigned() >> 2,
- transpose, v.View()->DataMaybeShared());
+ ContextGL()->UniformMatrix2fv(
+ location->Location(),
+ base::checked_cast<GLuint>(v.View()->lengthAsSizeT()) >> 2, transpose,
+ v.View()->DataMaybeShared());
}
void WebGLRenderingContextBase::uniformMatrix2fv(
@@ -6317,11 +6368,12 @@ void WebGLRenderingContextBase::uniformMatrix3fv(
MaybeShared<DOMFloat32Array> v) {
if (isContextLost() || !ValidateUniformMatrixParameters(
"uniformMatrix3fv", location, transpose, v.View(),
- 9, 0, v.View()->deprecatedLengthAsUnsigned()))
+ 9, 0, v.View()->lengthAsSizeT()))
return;
- ContextGL()->UniformMatrix3fv(location->Location(),
- v.View()->deprecatedLengthAsUnsigned() / 9,
- transpose, v.View()->DataMaybeShared());
+ ContextGL()->UniformMatrix3fv(
+ location->Location(),
+ base::checked_cast<GLuint>(v.View()->lengthAsSizeT()) / 9, transpose,
+ v.View()->DataMaybeShared());
}
void WebGLRenderingContextBase::uniformMatrix3fv(
@@ -6342,11 +6394,12 @@ void WebGLRenderingContextBase::uniformMatrix4fv(
MaybeShared<DOMFloat32Array> v) {
if (isContextLost() || !ValidateUniformMatrixParameters(
"uniformMatrix4fv", location, transpose, v.View(),
- 16, 0, v.View()->deprecatedLengthAsUnsigned()))
+ 16, 0, v.View()->lengthAsSizeT()))
return;
- ContextGL()->UniformMatrix4fv(location->Location(),
- v.View()->deprecatedLengthAsUnsigned() >> 4,
- transpose, v.View()->DataMaybeShared());
+ ContextGL()->UniformMatrix4fv(
+ location->Location(),
+ base::checked_cast<GLuint>(v.View()->lengthAsSizeT()) >> 4, transpose,
+ v.View()->DataMaybeShared());
}
void WebGLRenderingContextBase::uniformMatrix4fv(
@@ -7111,6 +7164,19 @@ void WebGLRenderingContextBase::AddExtensionSupportedFormatsTypes() {
}
}
+void WebGLRenderingContextBase::AddExtensionSupportedFormatsTypesWebGL2() {
+ if (!is_ext_texture_norm16_added_ &&
+ ExtensionEnabled(kEXTTextureNorm16Name)) {
+ ADD_VALUES_TO_SET(supported_internal_formats_,
+ kSupportedInternalFormatsEXTTextureNorm16ES3);
+ ADD_VALUES_TO_SET(supported_tex_image_source_internal_formats_,
+ kSupportedInternalFormatsEXTTextureNorm16ES3);
+ ADD_VALUES_TO_SET(supported_formats_, kSupportedFormatsEXTTextureNorm16ES3);
+ ADD_VALUES_TO_SET(supported_types_, kSupportedTypesEXTTextureNorm16ES3);
+ is_ext_texture_norm16_added_ = true;
+ }
+}
+
bool WebGLRenderingContextBase::ValidateTexImageSourceFormatAndType(
const char* function_name,
TexImageFunctionType function_type,
@@ -7129,6 +7195,8 @@ bool WebGLRenderingContextBase::ValidateTexImageSourceFormatAndType(
if (!IsWebGL2OrHigher()) {
AddExtensionSupportedFormatsTypes();
+ } else {
+ AddExtensionSupportedFormatsTypesWebGL2();
}
if (internalformat != 0 &&
@@ -7176,6 +7244,8 @@ bool WebGLRenderingContextBase::ValidateTexFuncFormatAndType(
if (!IsWebGL2OrHigher()) {
AddExtensionSupportedFormatsTypes();
+ } else {
+ AddExtensionSupportedFormatsTypesWebGL2();
}
if (internalformat != 0 && supported_internal_formats_.find(internalformat) ==
@@ -7488,7 +7558,7 @@ bool WebGLRenderingContextBase::ValidateTexFuncData(
total += total_bytes_required;
total += skip_bytes;
if (!total.IsValid() ||
- pixels->deprecatedByteLengthAsUnsigned() < total.ValueOrDie()) {
+ pixels->byteLengthAsSizeT() < static_cast<size_t>(total.ValueOrDie())) {
SynthesizeGLError(GL_INVALID_OPERATION, function_name,
"ArrayBufferView not big enough for request");
return false;
@@ -7543,9 +7613,9 @@ void WebGLRenderingContextBase::PrintGLErrorToConsole(const String& message) {
void WebGLRenderingContextBase::PrintWarningToConsole(const String& message) {
blink::ExecutionContext* context = Host()->GetTopExecutionContext();
if (context && !context->IsContextDestroyed()) {
- context->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kRendering,
- mojom::ConsoleMessageLevel::kWarning, message));
+ context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kRendering,
+ mojom::ConsoleMessageLevel::kWarning, message));
}
}
@@ -7648,15 +7718,20 @@ bool WebGLRenderingContextBase::ValidateUniformMatrixParameters(
DOMFloat32Array* v,
GLsizei required_min_size,
GLuint src_offset,
- GLuint src_length) {
+ size_t src_length) {
if (!v) {
SynthesizeGLError(GL_INVALID_VALUE, function_name, "no array");
return false;
}
+ if (!base::CheckedNumeric<GLuint>(src_length).IsValid()) {
+ SynthesizeGLError(GL_INVALID_VALUE, function_name,
+ "src_length exceeds the maximum supported length");
+ return false;
+ }
return ValidateUniformMatrixParameters(
function_name, location, transpose, v->DataMaybeShared(),
- v->deprecatedLengthAsUnsigned(), required_min_size, src_offset,
- src_length);
+ v->lengthAsSizeT(), required_min_size, src_offset,
+ static_cast<GLuint>(src_length));
}
bool WebGLRenderingContextBase::ValidateUniformMatrixParameters(
@@ -7664,7 +7739,7 @@ bool WebGLRenderingContextBase::ValidateUniformMatrixParameters(
const WebGLUniformLocation* location,
GLboolean transpose,
void* v,
- GLsizei size,
+ size_t size,
GLsizei required_min_size,
GLuint src_offset,
GLuint src_length) {
@@ -7680,6 +7755,11 @@ bool WebGLRenderingContextBase::ValidateUniformMatrixParameters(
SynthesizeGLError(GL_INVALID_VALUE, function_name, "no array");
return false;
}
+ if (!base::CheckedNumeric<GLsizei>(size).IsValid()) {
+ SynthesizeGLError(GL_INVALID_VALUE, function_name,
+ "array exceeds the maximum supported size");
+ return false;
+ }
if (transpose && !IsWebGL2OrHigher()) {
SynthesizeGLError(GL_INVALID_VALUE, function_name, "transpose not FALSE");
return false;
@@ -7688,7 +7768,7 @@ bool WebGLRenderingContextBase::ValidateUniformMatrixParameters(
SynthesizeGLError(GL_INVALID_VALUE, function_name, "invalid srcOffset");
return false;
}
- GLsizei actual_size = size - src_offset;
+ GLsizei actual_size = static_cast<GLsizei>(size) - src_offset;
if (src_length > 0) {
if (src_length > static_cast<GLuint>(actual_size)) {
SynthesizeGLError(GL_INVALID_VALUE, function_name,
@@ -7901,7 +7981,10 @@ void WebGLRenderingContextBase::MaybeRestoreContext(TimerBase*) {
LocalFrame* frame = canvas()->GetDocument().GetFrame();
if (!frame)
return;
- if (frame->Client()->ShouldBlockWebGL())
+
+ bool blocked = false;
+ frame->GetLocalFrameHostRemote().Are3DAPIsBlocked(&blocked);
+ if (blocked)
return;
Settings* settings = frame->GetSettings();
@@ -7997,15 +8080,12 @@ CanvasResourceProvider* WebGLRenderingContextBase::
return resource_provider;
}
- // TODO(fserb): why is this software?
- std::unique_ptr<CanvasResourceProvider> temp(CanvasResourceProvider::Create(
- size, CanvasResourceProvider::ResourceUsage::kSoftwareResourceUsage,
- nullptr, // context_provider_wrapper
- 0, // msaa_sample_count,
- kLow_SkFilterQuality,
- CanvasColorParams(), // TODO: should this use the canvas's colorspace?
- CanvasResourceProvider::kDefaultPresentationMode,
- nullptr)); // canvas_resource_dispatcher
+ // TODO(fserb): why is this a BITMAP?
+ std::unique_ptr<CanvasResourceProvider> temp(
+ CanvasResourceProvider::CreateBitmapProvider(
+ size, kLow_SkFilterQuality,
+ CanvasColorParams())); // TODO: should this use the canvas's
+
if (!temp)
return nullptr;
i = std::min(resource_providers_.size() - 1, i);
@@ -8181,7 +8261,7 @@ void WebGLRenderingContextBase::TextureUnitState::Trace(
visitor->Trace(texture_video_image_binding_);
}
-void WebGLRenderingContextBase::Trace(blink::Visitor* visitor) {
+void WebGLRenderingContextBase::Trace(Visitor* visitor) {
visitor->Trace(context_group_);
visitor->Trace(bound_array_buffer_);
visitor->Trace(default_vertex_array_object_);
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 95d4683690d..cf1727cac24 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
@@ -36,6 +36,7 @@
#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"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_webgl_context_attributes.h"
#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"
@@ -43,7 +44,6 @@
#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"
#include "third_party/blink/renderer/core/typed_arrays/typed_flexible_array_buffer_view.h"
-#include "third_party/blink/renderer/modules/webgl/webgl_context_attributes.h"
#include "third_party/blink/renderer/modules/webgl/webgl_extension_name.h"
#include "third_party/blink/renderer/modules/webgl/webgl_texture.h"
#include "third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_base.h"
@@ -52,6 +52,7 @@
#include "third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h"
#include "third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h"
#include "third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.h"
+#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/khronos/GLES2/gl2.h"
@@ -122,7 +123,7 @@ class ScopedRGBEmulationColorMask {
~ScopedRGBEmulationColorMask();
private:
- Member<WebGLRenderingContextBase> context_;
+ WebGLRenderingContextBase* context_;
GLboolean color_mask_[4];
const bool requires_emulation_;
};
@@ -452,36 +453,36 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
ExceptionState&);
void uniform1f(const WebGLUniformLocation*, GLfloat x);
- void uniform1fv(const WebGLUniformLocation*, const FlexibleFloat32ArrayView&);
+ void uniform1fv(const WebGLUniformLocation*, const FlexibleFloat32Array&);
void uniform1fv(const WebGLUniformLocation*, Vector<GLfloat>&);
void uniform1i(const WebGLUniformLocation*, GLint x);
- void uniform1iv(const WebGLUniformLocation*, const FlexibleInt32ArrayView&);
+ void uniform1iv(const WebGLUniformLocation*, const FlexibleInt32Array&);
void uniform1iv(const WebGLUniformLocation*, Vector<GLint>&);
void uniform2f(const WebGLUniformLocation*, GLfloat x, GLfloat y);
- void uniform2fv(const WebGLUniformLocation*, const FlexibleFloat32ArrayView&);
+ void uniform2fv(const WebGLUniformLocation*, const FlexibleFloat32Array&);
void uniform2fv(const WebGLUniformLocation*, Vector<GLfloat>&);
void uniform2i(const WebGLUniformLocation*, GLint x, GLint y);
- void uniform2iv(const WebGLUniformLocation*, const FlexibleInt32ArrayView&);
+ void uniform2iv(const WebGLUniformLocation*, const FlexibleInt32Array&);
void uniform2iv(const WebGLUniformLocation*, Vector<GLint>&);
void uniform3f(const WebGLUniformLocation*, GLfloat x, GLfloat y, GLfloat z);
- void uniform3fv(const WebGLUniformLocation*, const FlexibleFloat32ArrayView&);
+ void uniform3fv(const WebGLUniformLocation*, const FlexibleFloat32Array&);
void uniform3fv(const WebGLUniformLocation*, Vector<GLfloat>&);
void uniform3i(const WebGLUniformLocation*, GLint x, GLint y, GLint z);
- void uniform3iv(const WebGLUniformLocation*, const FlexibleInt32ArrayView&);
+ void uniform3iv(const WebGLUniformLocation*, const FlexibleInt32Array&);
void uniform3iv(const WebGLUniformLocation*, Vector<GLint>&);
void uniform4f(const WebGLUniformLocation*,
GLfloat x,
GLfloat y,
GLfloat z,
GLfloat w);
- void uniform4fv(const WebGLUniformLocation*, const FlexibleFloat32ArrayView&);
+ void uniform4fv(const WebGLUniformLocation*, const FlexibleFloat32Array&);
void uniform4fv(const WebGLUniformLocation*, Vector<GLfloat>&);
void uniform4i(const WebGLUniformLocation*,
GLint x,
GLint y,
GLint z,
GLint w);
- void uniform4iv(const WebGLUniformLocation*, const FlexibleInt32ArrayView&);
+ void uniform4iv(const WebGLUniformLocation*, const FlexibleInt32Array&);
void uniform4iv(const WebGLUniformLocation*, Vector<GLint>&);
void uniformMatrix2fv(const WebGLUniformLocation*,
GLboolean transpose,
@@ -571,7 +572,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
unsigned MaxVertexAttribs() const { return max_vertex_attribs_; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// Returns approximate gpu memory allocated per pixel.
int ExternallyAllocatedBufferCountPerPixel() override;
@@ -591,7 +592,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
Member<WebGLTexture> texture2d_array_binding_;
Member<WebGLTexture> texture_video_image_binding_;
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
};
scoped_refptr<StaticBitmapImage> GetImage(
@@ -606,38 +607,47 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
void commit();
- ScriptPromise makeXRCompatible(ScriptState*);
+ ScriptPromise makeXRCompatible(ScriptState*, ExceptionState&);
bool IsXRCompatible();
void UpdateNumberOfUserAllocatedMultisampledRenderbuffers(int delta);
protected:
+ // WebGL object types.
+ friend class WebGLContextObject;
+ friend class WebGLObject;
+ friend class WebGLQuery;
+ friend class WebGLTimerQueryEXT;
+ friend class WebGLVertexArrayObjectBase;
+
+ // Implementation helpers.
+ friend class ScopedDrawingBufferBinder;
+ friend class ScopedFramebufferRestorer;
+ friend class ScopedTexture2DRestorer;
+ friend class ScopedUnpackParametersResetRestore;
+ friend class WebGLRenderingContextErrorMessageCallback;
+
+ // WebGL extensions.
friend class EXTDisjointTimerQuery;
friend class EXTDisjointTimerQueryWebGL2;
- friend class WebGLDrawBuffers;
- friend class WebGLFramebuffer;
- friend class WebGLObject;
- friend class WebGLContextObject;
+ friend class EXTTextureCompressionBPTC;
+ friend class EXTTextureCompressionRGTC;
friend class OESVertexArrayObject;
friend class OVRMultiview2;
- friend class WebGLDebugShaders;
friend class WebGLCompressedTextureASTC;
friend class WebGLCompressedTextureETC;
friend class WebGLCompressedTextureETC1;
friend class WebGLCompressedTexturePVRTC;
friend class WebGLCompressedTextureS3TC;
friend class WebGLCompressedTextureS3TCsRGB;
+ friend class WebGLDebugShaders;
+ friend class WebGLDrawBuffers;
+ friend class WebGLDrawInstancedBaseVertexBaseInstance;
+ friend class WebGLFramebuffer;
friend class WebGLMultiDraw;
friend class WebGLMultiDrawCommon;
- friend class WebGLDrawInstancedBaseVertexBaseInstance;
friend class WebGLMultiDrawInstancedBaseVertexBaseInstance;
- friend class WebGLRenderingContextErrorMessageCallback;
- friend class WebGLVertexArrayObjectBase;
friend class WebGLVideoTexture;
- friend class ScopedDrawingBufferBinder;
- friend class ScopedTexture2DRestorer;
- friend class ScopedFramebufferRestorer;
- friend class ScopedUnpackParametersResetRestore;
WebGLRenderingContextBase(CanvasRenderingContextHost*,
std::unique_ptr<WebGraphicsContext3DProvider>,
@@ -683,6 +693,8 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
void OnErrorMessage(const char*, int32_t id);
+ scoped_refptr<base::SingleThreadTaskRunner> GetContextTaskRunner();
+
// Query if depth_stencil buffer is supported.
bool IsDepthStencilSupported() { return is_depth_stencil_supported_; }
@@ -874,7 +886,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(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
const char* NameInHeapSnapshot() const override {
return "ExtensionTracker";
}
@@ -887,13 +899,6 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
template <typename T>
class TypedExtensionTracker final : public ExtensionTracker {
public:
- static TypedExtensionTracker<T>* Create(Member<T>& extension_field,
- ExtensionFlags flags,
- const char* const* prefixes) {
- return MakeGarbageCollected<TypedExtensionTracker<T>>(extension_field,
- flags, prefixes);
- }
-
TypedExtensionTracker(Member<T>& extension_field,
ExtensionFlags flags,
const char* const* prefixes)
@@ -902,7 +907,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
WebGLExtension* GetExtension(WebGLRenderingContextBase* context) override {
if (!extension_) {
- extension_ = T::Create(context);
+ extension_ = MakeGarbageCollected<T>(context);
extension_field_ = extension_;
}
@@ -927,7 +932,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
return extension_;
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(extension_);
ExtensionTracker::Trace(visitor);
}
@@ -948,8 +953,8 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
void RegisterExtension(Member<T>& extension_ptr,
ExtensionFlags flags = kApprovedExtension,
const char* const* prefixes = nullptr) {
- extensions_.push_back(
- TypedExtensionTracker<T>::Create(extension_ptr, flags, prefixes));
+ extensions_.push_back(MakeGarbageCollected<TypedExtensionTracker<T>>(
+ extension_ptr, flags, prefixes));
}
bool ExtensionSupportedAndAllowed(const ExtensionTracker*);
@@ -984,7 +989,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
private:
DrawingBuffer* drawing_buffer_;
- Member<WebGLFramebuffer> read_framebuffer_binding_;
+ WebGLFramebuffer* read_framebuffer_binding_;
};
// Errors raised by synthesizeGLError() while the context is lost.
@@ -1000,6 +1005,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
bool is_web_gl_depth_texture_formats_types_added_ = false;
bool is_ext_srgb_formats_types_added_ = false;
bool is_ext_color_buffer_float_formats_added_ = false;
+ bool is_ext_texture_norm16_added_ = false;
GLenumHashSet supported_internal_formats_;
GLenumHashSet supported_tex_image_source_internal_formats_;
@@ -1224,6 +1230,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
GLenum target);
void AddExtensionSupportedFormatsTypes();
+ void AddExtensionSupportedFormatsTypesWebGL2();
// Helper function to check input internalformat/format/type for functions
// Tex{Sub}Image taking TexImageSource source data. Generates GL error and
@@ -1426,12 +1433,12 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
DOMFloat32Array*,
GLsizei mod,
GLuint src_offset,
- GLuint src_length);
+ size_t src_length);
bool ValidateUniformMatrixParameters(const char* function_name,
const WebGLUniformLocation*,
GLboolean transpose,
void*,
- GLsizei,
+ size_t size,
GLsizei mod,
GLuint src_offset,
GLuint src_length);
@@ -1443,14 +1450,26 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
const TypedFlexibleArrayBufferView<WTFTypedArray>& v,
GLsizei required_min_size,
GLuint src_offset,
- GLuint src_length) {
+ size_t src_length) {
+ GLuint length;
+ if (!base::CheckedNumeric<GLuint>(src_length).AssignIfValid(&length)) {
+ SynthesizeGLError(GL_INVALID_VALUE, function_name,
+ "src_length is too big");
+ return false;
+ }
+ GLuint array_length;
+ if (!base::CheckedNumeric<GLuint>(v.lengthAsSizeT())
+ .AssignIfValid(&array_length)) {
+ SynthesizeGLError(GL_INVALID_VALUE, function_name, "array is too big");
+ return false;
+ }
if (!v.DataMaybeOnStack()) {
SynthesizeGLError(GL_INVALID_VALUE, function_name, "no array");
return false;
}
return ValidateUniformMatrixParameters(
- function_name, location, false, v.DataMaybeOnStack(), v.length(),
- required_min_size, src_offset, src_length);
+ function_name, location, false, v.DataMaybeOnStack(), array_length,
+ required_min_size, src_offset, length);
}
// Helper function to validate the target for bufferData and
@@ -1506,6 +1525,21 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
GLenum type,
int64_t offset);
+ // Helper function to check if the byte length of {data} fits into an integer
+ // of type {T.} If so, the byte length is stored in {data_length}.
+ template <typename T>
+ bool ExtractDataLengthIfValid(const char* function_name,
+ MaybeShared<DOMArrayBufferView> data,
+ T* data_length) {
+ if (base::CheckedNumeric<T>(data.View()->byteLengthAsSizeT())
+ .AssignIfValid(data_length)) {
+ return true;
+ }
+ SynthesizeGLError(GL_INVALID_VALUE, function_name,
+ "provided data exceeds the maximum supported length");
+ return false;
+ }
+
// State updates and operations necessary before or at draw call time.
virtual void OnBeforeDrawCall();
@@ -1762,12 +1796,12 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
DISALLOW_COPY_AND_ASSIGN(WebGLRenderingContextBase);
};
-// TODO(fserb): remove this.
-DEFINE_TYPE_CASTS(WebGLRenderingContextBase,
- CanvasRenderingContext,
- context,
- context->Is3d(),
- context.Is3d());
+template <>
+struct DowncastTraits<WebGLRenderingContextBase> {
+ static bool AllowFrom(const CanvasRenderingContext& context) {
+ return context.Is3d();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.idl b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.idl
index 60824477580..88259a38569 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.idl
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.idl
@@ -709,5 +709,5 @@ interface mixin WebGLRenderingContextBase {
[RuntimeEnabled=OffscreenCanvasCommit] void commit();
// WebXR Device API support
- [RuntimeEnabled=WebXR, SecureContext, CallWith=ScriptState] Promise<void> makeXRCompatible();
+ [RuntimeEnabled=WebXR, SecureContext, CallWith=ScriptState, RaisesException] Promise<void> makeXRCompatible();
};
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_sampler.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_sampler.cc
index 24d45aff1d0..455f0481ca2 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_sampler.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_sampler.cc
@@ -9,10 +9,6 @@
namespace blink {
-WebGLSampler* WebGLSampler::Create(WebGL2RenderingContextBase* ctx) {
- return MakeGarbageCollected<WebGLSampler>(ctx);
-}
-
WebGLSampler::WebGLSampler(WebGL2RenderingContextBase* ctx)
: WebGLSharedPlatform3DObject(ctx) {
GLuint sampler;
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_sampler.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_sampler.h
index 288145477c4..679ace0c7c8 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_sampler.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_sampler.h
@@ -18,8 +18,6 @@ class WebGLSampler : public WebGLSharedPlatform3DObject {
explicit WebGLSampler(WebGL2RenderingContextBase*);
~WebGLSampler() override;
- static WebGLSampler* Create(WebGL2RenderingContextBase*);
-
protected:
void DeleteObjectImpl(gpu::gles2::GLES2Interface*) override;
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_shader.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_shader.cc
index 50f4417dcde..2cb663893fb 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_shader.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_shader.cc
@@ -30,10 +30,6 @@
namespace blink {
-WebGLShader* WebGLShader::Create(WebGLRenderingContextBase* ctx, GLenum type) {
- return MakeGarbageCollected<WebGLShader>(ctx, type);
-}
-
WebGLShader::WebGLShader(WebGLRenderingContextBase* ctx, GLenum type)
: WebGLSharedPlatform3DObject(ctx), type_(type), source_("") {
SetObject(ctx->ContextGL()->CreateShader(type));
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_shader.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_shader.h
index 0cc62ead4a1..5344a702c55 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_shader.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_shader.h
@@ -37,8 +37,6 @@ class WebGLShader final : public WebGLSharedPlatform3DObject {
public:
~WebGLShader() override;
- static WebGLShader* Create(WebGLRenderingContextBase*, GLenum);
-
WebGLShader(WebGLRenderingContextBase*, GLenum);
GLenum GetType() const { return type_; }
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_shader_precision_format.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_shader_precision_format.cc
index b29becdb23f..6c3bb3f240f 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_shader_precision_format.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_shader_precision_format.cc
@@ -28,15 +28,6 @@
namespace blink {
-// static
-WebGLShaderPrecisionFormat* WebGLShaderPrecisionFormat::Create(
- GLint range_min,
- GLint range_max,
- GLint precision) {
- return MakeGarbageCollected<WebGLShaderPrecisionFormat>(range_min, range_max,
- precision);
-}
-
GLint WebGLShaderPrecisionFormat::rangeMin() const {
return range_min_;
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_shader_precision_format.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_shader_precision_format.h
index a7432ab8158..aee6c5b7ea0 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_shader_precision_format.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_shader_precision_format.h
@@ -37,10 +37,6 @@ class WebGLShaderPrecisionFormat final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- static WebGLShaderPrecisionFormat* Create(GLint range_min,
- GLint range_max,
- GLint precision);
-
WebGLShaderPrecisionFormat(GLint range_min, GLint range_max, GLint precision);
GLint rangeMin() const;
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 8eeabfe86cf..29b519b17be 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(blink::Visitor* visitor) {
+void WebGLSharedObject::Trace(Visitor* visitor) {
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 0054c58c675..0385495dc75 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
explicit WebGLSharedObject(WebGLRenderingContextBase*);
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_sync.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_sync.cc
index 01ec4dd9166..6fab1b9eb9e 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_sync.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_sync.cc
@@ -17,14 +17,8 @@ WebGLSync::WebGLSync(WebGL2RenderingContextBase* ctx,
: WebGLSharedObject(ctx),
sync_status_(GL_UNSIGNALED),
object_(object),
- object_type_(object_type) {
- if (ctx->canvas()) {
- task_runner_ =
- ctx->canvas()->GetDocument().GetTaskRunner(TaskType::kInternalDefault);
- } else {
- // Fallback for OffscreenCanvas (no frame scheduler)
- task_runner_ = Thread::Current()->GetTaskRunner();
- }
+ object_type_(object_type),
+ task_runner_(ctx->GetContextTaskRunner()) {
ScheduleAllowCacheUpdate();
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_texture.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_texture.cc
index 6b2dc572171..3c9738aaebb 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_texture.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_texture.cc
@@ -30,10 +30,6 @@
namespace blink {
-WebGLTexture* WebGLTexture::Create(WebGLRenderingContextBase* ctx) {
- return MakeGarbageCollected<WebGLTexture>(ctx);
-}
-
WebGLTexture::WebGLTexture(WebGLRenderingContextBase* ctx)
: WebGLSharedPlatform3DObject(ctx), target_(0) {
GLuint texture;
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_texture.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_texture.h
index 93c6e88d5b1..18b310bc23c 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_texture.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_texture.h
@@ -38,8 +38,6 @@ class WebGLTexture final : public WebGLSharedPlatform3DObject {
explicit WebGLTexture(WebGLRenderingContextBase*);
~WebGLTexture() override;
- static WebGLTexture* Create(WebGLRenderingContextBase*);
-
void SetTarget(GLenum);
GLenum GetTarget() const { return target_; }
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_timer_query_ext.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_timer_query_ext.cc
index 344dc2d7324..52820dc5d7c 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_timer_query_ext.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_timer_query_ext.cc
@@ -11,10 +11,6 @@
namespace blink {
-WebGLTimerQueryEXT* WebGLTimerQueryEXT::Create(WebGLRenderingContextBase* ctx) {
- return MakeGarbageCollected<WebGLTimerQueryEXT>(ctx);
-}
-
WebGLTimerQueryEXT::WebGLTimerQueryEXT(WebGLRenderingContextBase* ctx)
: WebGLContextObject(ctx),
target_(0),
@@ -22,8 +18,7 @@ WebGLTimerQueryEXT::WebGLTimerQueryEXT(WebGLRenderingContextBase* ctx)
can_update_availability_(false),
query_result_available_(false),
query_result_(0),
- task_runner_(ctx->canvas()->GetDocument().GetTaskRunner(
- TaskType::kInternalDefault)) {
+ task_runner_(ctx->GetContextTaskRunner()) {
Context()->ContextGL()->GenQueriesEXT(1, &query_id_);
}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_timer_query_ext.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_timer_query_ext.h
index d5f709f528c..b2d2d007ff8 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_timer_query_ext.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_timer_query_ext.h
@@ -21,8 +21,6 @@ class WebGLTimerQueryEXT : public WebGLContextObject {
DEFINE_WRAPPERTYPEINFO();
public:
- static WebGLTimerQueryEXT* Create(WebGLRenderingContextBase*);
-
WebGLTimerQueryEXT(WebGLRenderingContextBase*);
~WebGLTimerQueryEXT() override;
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 7203b6471f5..dc9adfac1d2 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
@@ -9,12 +9,6 @@
namespace blink {
-WebGLTransformFeedback* WebGLTransformFeedback::Create(
- WebGL2RenderingContextBase* ctx,
- TFType type) {
- return MakeGarbageCollected<WebGLTransformFeedback>(ctx, type);
-}
-
WebGLTransformFeedback::WebGLTransformFeedback(WebGL2RenderingContextBase* ctx,
TFType type)
: WebGLContextObject(ctx),
@@ -139,7 +133,7 @@ void WebGLTransformFeedback::UnbindBuffer(WebGLBuffer* buffer) {
}
}
-void WebGLTransformFeedback::Trace(blink::Visitor* visitor) {
+void WebGLTransformFeedback::Trace(Visitor* visitor) {
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 7908b0e5775..570e11dad4c 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
@@ -28,8 +28,6 @@ class WebGLTransformFeedback : public WebGLContextObject {
GLuint Object() const { return object_; }
- static WebGLTransformFeedback* Create(WebGL2RenderingContextBase*, TFType);
-
bool IsDefaultObject() const { return type_ == TFTypeDefault; }
GLenum GetTarget() const { return target_; }
@@ -51,7 +49,7 @@ class WebGLTransformFeedback : public WebGLContextObject {
bool UsesBuffer(WebGLBuffer*);
void UnbindBuffer(WebGLBuffer*);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 e6d7a1db38c..4203c0c4194 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
@@ -28,11 +28,6 @@
namespace blink {
-WebGLUniformLocation* WebGLUniformLocation::Create(WebGLProgram* program,
- GLint location) {
- return MakeGarbageCollected<WebGLUniformLocation>(program, location);
-}
-
WebGLUniformLocation::WebGLUniformLocation(WebGLProgram* program,
GLint location)
: program_(program), location_(location) {
@@ -55,7 +50,7 @@ GLint WebGLUniformLocation::Location() const {
return location_;
}
-void WebGLUniformLocation::Trace(blink::Visitor* visitor) {
+void WebGLUniformLocation::Trace(Visitor* visitor) {
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 3ed78d9c05f..15673dbf9f2 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
@@ -36,15 +36,13 @@ class WebGLUniformLocation final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- static WebGLUniformLocation* Create(WebGLProgram*, GLint location);
-
WebGLUniformLocation(WebGLProgram*, GLint location);
WebGLProgram* Program() const;
GLint Location() const;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<WebGLProgram> program_;
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object.cc
index de593528f27..e3938c4065d 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object.cc
@@ -8,12 +8,6 @@
namespace blink {
-WebGLVertexArrayObject* WebGLVertexArrayObject::Create(
- WebGLRenderingContextBase* ctx,
- VaoType type) {
- return MakeGarbageCollected<WebGLVertexArrayObject>(ctx, type);
-}
-
WebGLVertexArrayObject::WebGLVertexArrayObject(WebGLRenderingContextBase* ctx,
VaoType type)
: WebGLVertexArrayObjectBase(ctx, type) {}
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object.h
index 8b09f2283f1..16c137b071e 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object.h
@@ -13,8 +13,6 @@ class WebGLVertexArrayObject final : public WebGLVertexArrayObjectBase {
DEFINE_WRAPPERTYPEINFO();
public:
- static WebGLVertexArrayObject* Create(WebGLRenderingContextBase*, VaoType);
-
explicit WebGLVertexArrayObject(WebGLRenderingContextBase*, VaoType);
};
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 2fec1e62464..f929c1ae523 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(blink::Visitor* visitor) {
+void WebGLVertexArrayObjectBase::Trace(Visitor* visitor) {
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 7e8967d34be..4c3c1238193 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
WebGLVertexArrayObjectBase(WebGLRenderingContextBase*, VaoType);
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_oes.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_oes.cc
index 34928eef020..ee9026bb7be 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_oes.cc
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_oes.cc
@@ -29,12 +29,6 @@
namespace blink {
-WebGLVertexArrayObjectOES* WebGLVertexArrayObjectOES::Create(
- WebGLRenderingContextBase* ctx,
- VaoType type) {
- return MakeGarbageCollected<WebGLVertexArrayObjectOES>(ctx, type);
-}
-
WebGLVertexArrayObjectOES::WebGLVertexArrayObjectOES(
WebGLRenderingContextBase* ctx,
VaoType type)
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_oes.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_oes.h
index 9368d09830a..a46e3cc62d1 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_oes.h
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_oes.h
@@ -34,8 +34,6 @@ class WebGLVertexArrayObjectOES final : public WebGLVertexArrayObjectBase {
DEFINE_WRAPPERTYPEINFO();
public:
- static WebGLVertexArrayObjectOES* Create(WebGLRenderingContextBase*, VaoType);
-
explicit WebGLVertexArrayObjectOES(WebGLRenderingContextBase*, VaoType);
};
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_video_frame_metadata.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_video_frame_metadata.cc
deleted file mode 100644
index c3bb43e2824..00000000000
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_video_frame_metadata.cc
+++ /dev/null
@@ -1,23 +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/webgl/webgl_video_frame_metadata.h"
-
-namespace blink {
-
-WebGLVideoFrameMetadata* WebGLVideoFrameMetadata::Create(
- WebMediaPlayer::VideoFrameUploadMetadata* frame_metadata_ptr) {
- return MakeGarbageCollected<WebGLVideoFrameMetadata>(frame_metadata_ptr);
-}
-
-WebGLVideoFrameMetadata::WebGLVideoFrameMetadata(
- WebMediaPlayer::VideoFrameUploadMetadata* frame_metadata_ptr) {
- presentation_time_ = frame_metadata_ptr->timestamp.InMicrosecondsF();
- expected_presentation_time_ =
- frame_metadata_ptr->expected_timestamp.InMicrosecondsF();
- width_ = frame_metadata_ptr->visible_rect.width();
- height_ = frame_metadata_ptr->visible_rect.height();
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_video_frame_metadata.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_video_frame_metadata.h
deleted file mode 100644
index f27ae3e4460..00000000000
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_video_frame_metadata.h
+++ /dev/null
@@ -1,49 +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_WEBGL_WEBGL_VIDEO_FRAME_METADATA_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_VIDEO_FRAME_METADATA_H_
-
-#include "third_party/blink/public/platform/web_media_player.h"
-#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
-
-namespace blink {
-
-class WebGLVideoFrameMetadata final : public ScriptWrappable {
- DEFINE_WRAPPERTYPEINFO();
-
- public:
- static WebGLVideoFrameMetadata* Create(
- WebMediaPlayer::VideoFrameUploadMetadata*);
- explicit WebGLVideoFrameMetadata(WebMediaPlayer::VideoFrameUploadMetadata*);
-
- double presentationTime() const { return presentation_time_; }
- double expectedPresentationTime() const {
- return expected_presentation_time_;
- }
- unsigned width() const { return width_; }
- unsigned height() const { return height_; }
-
- double presentationTimestamp() const { return presentation_timestamp_; }
- double elapsedProcessingTime() const { return elapsed_processing_time_; }
- double captureTime() const { return capture_time_; }
- unsigned presentedFrames() const { return presented_frames_; }
- unsigned rtpTimestamp() const { return rtp_timestamp_; }
-
- private:
- double presentation_time_ = 0;
- double expected_presentation_time_ = 0;
- unsigned width_ = 0;
- unsigned height_ = 0;
-
- double presentation_timestamp_ = 0;
- double elapsed_processing_time_ = 0;
- double capture_time_ = 0;
- unsigned presented_frames_ = 0;
- unsigned rtp_timestamp_ = 0;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_VIDEO_FRAME_METADATA_H_
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_video_frame_metadata.idl b/chromium/third_party/blink/renderer/modules/webgl/webgl_video_frame_metadata.idl
deleted file mode 100644
index ef59c2881dc..00000000000
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_video_frame_metadata.idl
+++ /dev/null
@@ -1,19 +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/dalecurtis/video-animation-frame/blob/master/explainer.md
-[
- RuntimeEnabled=WebGLDraftExtensions
-] interface WebGLVideoFrameMetadata {
- readonly attribute double presentationTime;
- readonly attribute double expectedPresentationTime;
- readonly attribute unsigned long width;
- readonly attribute unsigned long height;
-
- readonly attribute double presentationTimestamp;
- readonly attribute double elapsedProcessingTime;
- readonly attribute double captureTime;
- readonly attribute unsigned long presentedFrames;
- readonly attribute unsigned long rtpTimestamp;
-};
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 494ea9d4078..d8eeff653b0 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
@@ -5,9 +5,9 @@
#include "third_party/blink/renderer/modules/webgl/webgl_video_texture.h"
#include "build/build_config.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_video_frame_metadata.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h"
-#include "third_party/blink/renderer/modules/webgl/webgl_video_frame_metadata.h"
#include "third_party/blink/renderer/modules/webgl/webgl_video_texture_enum.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -15,23 +15,17 @@ namespace blink {
WebGLVideoTexture::WebGLVideoTexture(WebGLRenderingContextBase* context)
: WebGLExtension(context) {
- context->ExtensionsUtil()->EnsureExtensionEnabled("WEBGL_video_texture");
+ context->ExtensionsUtil()->EnsureExtensionEnabled("GL_WEBGL_video_texture");
}
WebGLExtensionName WebGLVideoTexture::GetName() const {
return kWebGLVideoTextureName;
}
-WebGLVideoTexture* WebGLVideoTexture::Create(
- WebGLRenderingContextBase* context) {
- return MakeGarbageCollected<WebGLVideoTexture>(context);
-}
-
-// We only need GL_OES_EGL_image_external extension on Android.
bool WebGLVideoTexture::Supported(WebGLRenderingContextBase* context) {
#if defined(OS_ANDROID)
- return context->ExtensionsUtil()->SupportsExtension(
- "GL_OES_EGL_image_external");
+ // TODO(crbug.com/776222): support extension on Android
+ return false;
#else // defined OS_ANDROID
return true;
#endif
@@ -41,16 +35,16 @@ const char* WebGLVideoTexture::ExtensionName() {
return "WEBGL_video_texture";
}
-void WebGLVideoTexture::Trace(blink::Visitor* visitor) {
+void WebGLVideoTexture::Trace(Visitor* visitor) {
visitor->Trace(current_frame_metadata_);
WebGLExtension::Trace(visitor);
}
-WebGLVideoFrameMetadata* WebGLVideoTexture::VideoElementTargetVideoTexture(
+VideoFrameMetadata* WebGLVideoTexture::VideoElementTargetVideoTexture(
ExecutionContext* execution_context,
unsigned target,
HTMLVideoElement* video,
- ExceptionState& exceptionState) {
+ ExceptionState& exception_state) {
WebGLExtensionScopedContext scoped(this);
if (!video || scoped.IsLost())
return nullptr;
@@ -62,46 +56,73 @@ WebGLVideoFrameMetadata* WebGLVideoTexture::VideoElementTargetVideoTexture(
if (!scoped.Context()->ValidateHTMLVideoElement(
execution_context->GetSecurityOrigin(), "WEBGLVideoTexture", video,
- exceptionState) ||
- !scoped.Context()->ValidateTexFuncDimensions(
+ exception_state)) {
+ return nullptr;
+ }
+
+ if (!scoped.Context()->ValidateTexFuncDimensions(
"WEBGLVideoTexture", WebGLRenderingContextBase::kTexImage, target, 0,
- video->videoWidth(), video->videoHeight(), 1))
+ video->videoWidth(), video->videoHeight(), 1)) {
return nullptr;
+ }
WebGLTexture* texture =
scoped.Context()->ValidateTextureBinding("WEBGLVideoTexture", target);
- if (!texture)
+ if (!texture) {
+ exception_state.ThrowTypeError(
+ "Failed to get correct binding texture for WEBGL_video_texture");
return nullptr;
+ }
+#if defined(OS_ANDROID)
+ // TODO(crbug.com/776222): support extension on Android
+ NOTIMPLEMENTED();
+ return nullptr;
+#else
// For WebGL last-uploaded-frame-metadata API.
WebMediaPlayer::VideoFrameUploadMetadata frame_metadata = {};
+ auto* frame_metadata_ptr = &frame_metadata;
int already_uploaded_id = HTMLVideoElement::kNoAlreadyUploadedFrame;
- WebMediaPlayer::VideoFrameUploadMetadata* frame_metadata_ptr =
- &frame_metadata;
- if (RuntimeEnabledFeatures::ExtraWebGLVideoTextureMetadataEnabled()) {
+ if (RuntimeEnabledFeatures::ExtraWebGLVideoTextureMetadataEnabled())
already_uploaded_id = texture->GetLastUploadedVideoFrameId();
- }
-#if defined(OS_ANDROID)
- target = GL_TEXTURE_EXTERNAL_OES;
-#else // defined OS_ANDROID
target = GL_TEXTURE_2D;
-#endif // defined OS_ANDROID
-
+ // TODO(shaobo.yan@intel.com) : A fallback path or exception needs to be
+ // added when video is not using gpu decoder.
video->PrepareVideoFrameForWebGL(scoped.Context()->ContextGL(), target,
texture->Object(), already_uploaded_id,
frame_metadata_ptr);
if (!frame_metadata_ptr) {
+ exception_state.ThrowTypeError("Failed to share video to texture.");
return nullptr;
}
- if (frame_metadata_ptr) {
- current_frame_metadata_ =
- WebGLVideoFrameMetadata::Create(frame_metadata_ptr);
- }
-
+ if (RuntimeEnabledFeatures::ExtraWebGLVideoTextureMetadataEnabled())
+ texture->UpdateLastUploadedFrame(frame_metadata);
+
+ if (!current_frame_metadata_)
+ current_frame_metadata_ = VideoFrameMetadata::Create();
+
+ // TODO(crbug.com/776222): These should be read from the VideoFrameCompositor
+ // when the VideoFrame is retrieved in WebMediaPlayerImpl. These fields are
+ // not currently saved in VideoFrameCompositor, so VFC::ProcessNewFrame()
+ // would need to save the current time as well as the presentation time.
+ current_frame_metadata_->setPresentationTime(
+ frame_metadata_ptr->timestamp.InMicrosecondsF());
+ current_frame_metadata_->setExpectedDisplayTime(
+ frame_metadata_ptr->expected_timestamp.InMicrosecondsF());
+
+ current_frame_metadata_->setWidth(frame_metadata_ptr->visible_rect.width());
+ current_frame_metadata_->setHeight(frame_metadata_ptr->visible_rect.height());
+ current_frame_metadata_->setMediaTime(
+ 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.
+ current_frame_metadata_->setPresentedFrames(0);
return current_frame_metadata_;
+#endif // defined OS_ANDROID
}
} // namespace blink
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 197430b0ca7..9350643877b 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
@@ -10,13 +10,12 @@
namespace blink {
class HTMLVideoElement;
-class WebGLVideoFrameMetadata;
+class VideoFrameMetadata;
class WebGLVideoTexture final : public WebGLExtension {
DEFINE_WRAPPERTYPEINFO();
public:
- static WebGLVideoTexture* Create(WebGLRenderingContextBase*);
static bool Supported(WebGLRenderingContextBase*);
static const char* ExtensionName();
@@ -24,17 +23,17 @@ class WebGLVideoTexture final : public WebGLExtension {
WebGLExtensionName GetName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
// Get video frame from video frame compositor and bind it to platform
// texture.
- WebGLVideoFrameMetadata* VideoElementTargetVideoTexture(ExecutionContext*,
- unsigned,
- HTMLVideoElement*,
- ExceptionState&);
+ VideoFrameMetadata* VideoElementTargetVideoTexture(ExecutionContext*,
+ unsigned,
+ HTMLVideoElement*,
+ ExceptionState&);
private:
- Member<WebGLVideoFrameMetadata> current_frame_metadata_;
+ Member<VideoFrameMetadata> current_frame_metadata_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.idl b/chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.idl
index 445238b0234..1065379809d 100644
--- a/chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.idl
+++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.idl
@@ -12,5 +12,5 @@
const GLenum TEXTURE_VIDEO_IMAGE = 0x9248;
const GLenum SAMPLER_VIDEO_IMAGE = 0x9249;
- [CallWith=ExecutionContext, RaisesException] WebGLVideoFrameMetadata VideoElementTargetVideoTexture(GLenum target, HTMLVideoElement video);
+ [CallWith=ExecutionContext, RaisesException] VideoFrameMetadata VideoElementTargetVideoTexture(GLenum target, HTMLVideoElement video);
};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/BUILD.gn b/chromium/third_party/blink/renderer/modules/webgpu/BUILD.gn
index e5c95a93864..01c03224f93 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/webgpu/BUILD.gn
@@ -6,6 +6,8 @@ import("//third_party/blink/renderer/modules/modules.gni")
blink_modules_sources("webgpu") {
sources = [
+ "client_validation.cc",
+ "client_validation.h",
"dawn_callback.h",
"dawn_conversions.cc",
"dawn_conversions.h",
@@ -76,7 +78,5 @@ blink_modules_sources("webgpu") {
"worker_navigator_gpu.cc",
"worker_navigator_gpu.h",
]
- deps = [
- "//third_party/dawn/src/dawn:dawn_headers",
- ]
+ deps = [ "//third_party/dawn/src/dawn:dawn_headers" ]
}
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/client_validation.cc b/chromium/third_party/blink/renderer/modules/webgpu/client_validation.cc
new file mode 100644
index 00000000000..007bb3c9c26
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgpu/client_validation.cc
@@ -0,0 +1,42 @@
+// 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/webgpu/client_validation.h"
+
+#include <dawn/webgpu.h>
+
+#include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_sequence_or_gpu_extent_3d_dict.h"
+#include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_sequence_or_gpu_origin_2d_dict.h"
+#include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_sequence_or_gpu_origin_3d_dict.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_copy_view.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+
+namespace blink {
+
+bool ValidateCopySize(UnsignedLongSequenceOrGPUExtent3DDict& copy_size,
+ ExceptionState& exception_state) {
+ if (copy_size.IsUnsignedLongSequence() &&
+ copy_size.GetAsUnsignedLongSequence().size() != 3) {
+ exception_state.ThrowRangeError("copySize length must be 3");
+ return false;
+ }
+ return true;
+}
+
+bool ValidateTextureCopyView(GPUTextureCopyView* texture_copy_view,
+ ExceptionState& exception_state) {
+ DCHECK(texture_copy_view);
+
+ const UnsignedLongSequenceOrGPUOrigin3DDict origin =
+ texture_copy_view->origin();
+ if (origin.IsUnsignedLongSequence() &&
+ origin.GetAsUnsignedLongSequence().size() != 3) {
+ exception_state.ThrowRangeError(
+ "texture copy view origin length must be 3");
+ return false;
+ }
+ return true;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/client_validation.h b/chromium/third_party/blink/renderer/modules/webgpu/client_validation.h
new file mode 100644
index 00000000000..6da8833a180
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgpu/client_validation.h
@@ -0,0 +1,24 @@
+// 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_WEBGPU_CLIENT_VALIDATION_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_CLIENT_VALIDATION_H_
+
+#include <dawn/webgpu.h>
+
+// This file provides helpers for validating copy operation in WebGPU.
+
+namespace blink {
+
+class ExceptionState;
+class GPUTextureCopyView;
+class UnsignedLongSequenceOrGPUExtent3DDict;
+
+bool ValidateCopySize(UnsignedLongSequenceOrGPUExtent3DDict& copy_size,
+ ExceptionState& exception_state);
+bool ValidateTextureCopyView(GPUTextureCopyView* texture_copy_view,
+ ExceptionState& exception_state);
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_CLIENT_VALIDATION_H_
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 94f4849110e..04b27545541 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc
@@ -9,8 +9,10 @@
#include "third_party/blink/renderer/bindings/modules/v8/double_sequence_or_gpu_color_dict.h"
#include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_sequence_or_gpu_extent_3d_dict.h"
#include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_sequence_or_gpu_origin_3d_dict.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_programmable_stage_descriptor.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_shader_module.h"
+#include "third_party/blink/renderer/modules/webgpu/gpu_texture.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -23,6 +25,9 @@ WGPUBindingType AsDawnEnum<WGPUBindingType>(const WTF::String& webgpu_enum) {
if (webgpu_enum == "storage-buffer") {
return WGPUBindingType_StorageBuffer;
}
+ if (webgpu_enum == "readonly-storage-buffer") {
+ return WGPUBindingType_ReadonlyStorageBuffer;
+ }
if (webgpu_enum == "sampler") {
return WGPUBindingType_Sampler;
}
@@ -218,6 +223,50 @@ WGPUTextureFormat AsDawnEnum<WGPUTextureFormat>(
return WGPUTextureFormat_Depth24PlusStencil8;
}
+ // Block Compression (BC) formats
+ if (webgpu_enum == "bc1-rgba-unorm") {
+ return WGPUTextureFormat_BC1RGBAUnorm;
+ }
+ if (webgpu_enum == "bc1-rgba-unorm-srgb") {
+ return WGPUTextureFormat_BC1RGBAUnormSrgb;
+ }
+ if (webgpu_enum == "bc2-rgba-unorm") {
+ return WGPUTextureFormat_BC2RGBAUnorm;
+ }
+ if (webgpu_enum == "bc2-rgba-unorm-srgb") {
+ return WGPUTextureFormat_BC2RGBAUnormSrgb;
+ }
+ if (webgpu_enum == "bc3-rgba-unorm") {
+ return WGPUTextureFormat_BC3RGBAUnorm;
+ }
+ if (webgpu_enum == "bc3-rgba-unorm-srgb") {
+ return WGPUTextureFormat_BC3RGBAUnormSrgb;
+ }
+ if (webgpu_enum == "bc4-r-unorm") {
+ return WGPUTextureFormat_BC4RUnorm;
+ }
+ if (webgpu_enum == "bc4-r-snorm") {
+ return WGPUTextureFormat_BC4RSnorm;
+ }
+ if (webgpu_enum == "bc5-rg-unorm") {
+ return WGPUTextureFormat_BC5RGUnorm;
+ }
+ if (webgpu_enum == "bc5-rg-snorm") {
+ return WGPUTextureFormat_BC5RGSnorm;
+ }
+ if (webgpu_enum == "bc6h-rgb-ufloat") {
+ return WGPUTextureFormat_BC6HRGBUfloat;
+ }
+ if (webgpu_enum == "bc6h-rgb-sfloat") {
+ return WGPUTextureFormat_BC6HRGBSfloat;
+ }
+ if (webgpu_enum == "bc7-rgba-unorm") {
+ return WGPUTextureFormat_BC7RGBAUnorm;
+ }
+ if (webgpu_enum == "bc7-rgba-unorm-srgb") {
+ return WGPUTextureFormat_BC7RGBAUnormSrgb;
+ }
+
return WGPUTextureFormat_Force32;
}
@@ -695,6 +744,20 @@ WGPUOrigin3D AsDawnType(
return dawn_origin;
}
+WGPUTextureCopyView AsDawnType(const GPUTextureCopyView* webgpu_view) {
+ DCHECK(webgpu_view);
+ DCHECK(webgpu_view->texture());
+
+ WGPUTextureCopyView dawn_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());
+
+ return dawn_view;
+}
+
OwnedProgrammableStageDescriptor AsDawnType(
const GPUProgrammableStageDescriptor* webgpu_stage) {
DCHECK(webgpu_stage);
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 6fc85465464..bff483d589c 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.h
@@ -22,6 +22,7 @@ namespace blink {
class DoubleSequenceOrGPUColorDict;
class GPUColorDict;
class GPUProgrammableStageDescriptor;
+class GPUTextureCopyView;
class UnsignedLongSequenceOrGPUExtent3DDict;
class UnsignedLongSequenceOrGPUOrigin3DDict;
@@ -43,7 +44,7 @@ WGPUColor AsDawnType(const GPUColorDict*);
WGPUColor AsDawnType(const DoubleSequenceOrGPUColorDict*);
WGPUExtent3D AsDawnType(const UnsignedLongSequenceOrGPUExtent3DDict*);
WGPUOrigin3D AsDawnType(const UnsignedLongSequenceOrGPUOrigin3DDict*);
-
+WGPUTextureCopyView AsDawnType(const GPUTextureCopyView* webgpu_view);
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 8ce13313c75..db2e9099801 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.cc
@@ -34,7 +34,7 @@ DawnObjectImpl::DawnObjectImpl(GPUDevice* device)
DawnObjectImpl::~DawnObjectImpl() = default;
-void DawnObjectImpl::Trace(blink::Visitor* visitor) {
+void DawnObjectImpl::Trace(Visitor* visitor) {
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 31fb27ab282..52543eef44b 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.h
@@ -47,7 +47,7 @@ class DawnObjectImpl : public ScriptWrappable, public DawnObjectBase {
DawnObjectImpl(GPUDevice* device);
~DawnObjectImpl() override;
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
protected:
Member<GPUDevice> device_;
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu.cc
index ba90d3fdee4..23176e95f33 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu.cc
@@ -10,12 +10,13 @@
#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_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_request_adapter_options.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/inspector/console_message.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_adapter.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_request_adapter_options.h"
#include "third_party/blink/renderer/platform/graphics/gpu/dawn_control_client_holder.h"
+#include "third_party/blink/renderer/platform/heap/heap.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/weborigin/kurl.h"
@@ -86,26 +87,26 @@ GPU* GPU::Create(ExecutionContext& execution_context) {
GPU::GPU(ExecutionContext& execution_context,
std::unique_ptr<WebGraphicsContext3DProvider> context_provider)
- : ContextLifecycleObserver(&execution_context),
+ : ExecutionContextLifecycleObserver(&execution_context),
dawn_control_client_(base::MakeRefCounted<DawnControlClientHolder>(
std::move(context_provider))) {}
GPU::~GPU() = default;
-void GPU::Trace(blink::Visitor* visitor) {
+void GPU::Trace(Visitor* visitor) {
ScriptWrappable::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
-void GPU::ContextDestroyed(ExecutionContext* execution_context) {
+void GPU::ContextDestroyed() {
dawn_control_client_->Destroy();
}
void GPU::OnRequestAdapterCallback(ScriptPromiseResolver* resolver,
uint32_t adapter_server_id,
const WGPUDeviceProperties& properties) {
- GPUAdapter* adapter = GPUAdapter::Create("Default", adapter_server_id,
- properties, dawn_control_client_);
+ auto* adapter = MakeGarbageCollected<GPUAdapter>(
+ "Default", adapter_server_id, properties, dawn_control_client_);
resolver->Resolve(adapter);
}
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu.h
index 2608ea31fcf..f9e8b33b314 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu.h
@@ -7,8 +7,8 @@
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
struct WGPUDeviceProperties;
@@ -21,7 +21,8 @@ class ScriptState;
class WebGraphicsContext3DProvider;
class DawnControlClientHolder;
-class GPU final : public ScriptWrappable, public ContextLifecycleObserver {
+class GPU final : public ScriptWrappable,
+ public ExecutionContextLifecycleObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(GPU);
@@ -32,10 +33,10 @@ class GPU final : public ScriptWrappable, public ContextLifecycleObserver {
~GPU() override;
// ScriptWrappable overrides
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
- // ContextLifecycleObserver overrides
- void ContextDestroyed(ExecutionContext* execution_context) override;
+ // ExecutionContextLifecycleObserver overrides
+ void ContextDestroyed() override;
// gpu.idl
ScriptPromise requestAdapter(ScriptState* script_state,
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc
index 3c4004cfeec..16697b5c677 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc
@@ -6,10 +6,11 @@
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_device_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_request_adapter_options.h"
+#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_device_descriptor.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_extensions.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_request_adapter_options.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
@@ -17,24 +18,20 @@ namespace {
WGPUDeviceProperties AsDawnType(const GPUDeviceDescriptor* descriptor) {
DCHECK_NE(nullptr, descriptor);
+ HashSet<String> extension_set;
+ for (auto& extension : descriptor->extensions())
+ extension_set.insert(extension);
+
WGPUDeviceProperties requested_device_properties = {};
+ // TODO(crbug.com/1048603): We should validate that the extension_set is a
+ // subset of the adapter's extension set.
requested_device_properties.textureCompressionBC =
- descriptor->extensions()->textureCompressionBC();
+ extension_set.Contains("textureCompressionBC");
return requested_device_properties;
}
} // anonymous namespace
-// static
-GPUAdapter* GPUAdapter::Create(
- const String& name,
- uint32_t adapter_service_id,
- const WGPUDeviceProperties& properties,
- scoped_refptr<DawnControlClientHolder> dawn_control_client) {
- return MakeGarbageCollected<GPUAdapter>(name, adapter_service_id, properties,
- std::move(dawn_control_client));
-}
-
GPUAdapter::GPUAdapter(
const String& name,
uint32_t adapter_service_id,
@@ -43,17 +40,40 @@ GPUAdapter::GPUAdapter(
: DawnObjectBase(dawn_control_client),
name_(name),
adapter_service_id_(adapter_service_id),
- adapter_properties_(properties) {}
+ adapter_properties_(properties) {
+ InitializeExtensionNameList();
+}
const String& GPUAdapter::name() const {
return name_;
}
-ScriptValue GPUAdapter::extensions(ScriptState* script_state) const {
- V8ObjectBuilder object_builder(script_state);
- object_builder.AddBoolean("textureCompressionBC",
- adapter_properties_.textureCompressionBC);
- return object_builder.GetScriptValue();
+Vector<String> GPUAdapter::extensions(ScriptState* script_state) const {
+ return extension_name_list_;
+}
+
+void GPUAdapter::OnRequestDeviceCallback(ScriptPromiseResolver* resolver,
+ const GPUDeviceDescriptor* descriptor,
+ bool is_request_device_success,
+ uint64_t device_client_id) {
+ if (is_request_device_success) {
+ ExecutionContext* execution_context = resolver->GetExecutionContext();
+ auto* device = MakeGarbageCollected<GPUDevice>(
+ execution_context, GetDawnControlClient(), this, device_client_id,
+ descriptor);
+ resolver->Resolve(device);
+ } else {
+ resolver->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kOperationError,
+ "Fail to request GPUDevice with the given GPUDeviceDescriptor"));
+ }
+}
+
+void GPUAdapter::InitializeExtensionNameList() {
+ DCHECK(extension_name_list_.IsEmpty());
+ if (adapter_properties_.textureCompressionBC) {
+ extension_name_list_.emplace_back("textureCompressionBC");
+ }
}
ScriptPromise GPUAdapter::requestDevice(ScriptState* script_state,
@@ -62,16 +82,15 @@ ScriptPromise GPUAdapter::requestDevice(ScriptState* script_state,
ScriptPromise promise = resolver->Promise();
WGPUDeviceProperties requested_device_properties = AsDawnType(descriptor);
- GetInterface()->RequestDevice(adapter_service_id_,
- &requested_device_properties);
- // TODO(jiawei.shao@intel.com): create GPUDevice in the callback of
- // GetInterface()->RequestDevice().
- ExecutionContext* execution_context = ExecutionContext::From(script_state);
- GPUDevice* device = GPUDevice::Create(
- execution_context, GetDawnControlClient(), this, descriptor);
+ if (!GetInterface()->RequestDeviceAsync(
+ adapter_service_id_, requested_device_properties,
+ WTF::Bind(&GPUAdapter::OnRequestDeviceCallback, WrapPersistent(this),
+ WrapPersistent(resolver), WrapPersistent(descriptor)))) {
+ resolver->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kOperationError, "Unknown error creating GPUDevice"));
+ }
- resolver->Resolve(device);
return promise;
}
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.h
index d7dac24202e..991e911b572 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.h
@@ -16,31 +16,34 @@
namespace blink {
class GPUDeviceDescriptor;
+class ScriptPromiseResolver;
class GPUAdapter final : public ScriptWrappable, public DawnObjectBase {
DEFINE_WRAPPERTYPEINFO();
public:
- static GPUAdapter* Create(
- const String& name,
- uint32_t adapter_service_id,
- const WGPUDeviceProperties& properties,
- scoped_refptr<DawnControlClientHolder> dawn_control_client);
GPUAdapter(const String& name,
uint32_t adapter_service_id,
const WGPUDeviceProperties& properties,
scoped_refptr<DawnControlClientHolder> dawn_control_client);
const String& name() const;
- ScriptValue extensions(ScriptState* script_state) const;
+ Vector<String> extensions(ScriptState* script_state) const;
ScriptPromise requestDevice(ScriptState* script_state,
const GPUDeviceDescriptor* descriptor);
private:
+ void OnRequestDeviceCallback(ScriptPromiseResolver* resolver,
+ const GPUDeviceDescriptor* descriptor,
+ bool is_request_device_success,
+ uint64_t device_client_id);
+ void InitializeExtensionNameList();
+
String name_;
uint32_t adapter_service_id_;
WGPUDeviceProperties adapter_properties_;
+ Vector<String> extension_name_list_;
DISALLOW_COPY_AND_ASSIGN(GPUAdapter);
};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.idl
index 92440f45713..735742c66bb 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.idl
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.idl
@@ -4,11 +4,15 @@
// https://gpuweb.github.io/gpuweb/
+enum GPUExtensionName {
+ "textureCompressionBC",
+};
+
[
Exposed(Window WebGPU, Worker WebGPU)
] interface GPUAdapter {
readonly attribute DOMString name;
- [CallWith=ScriptState, SameObject] readonly attribute object extensions;
+ [CallWith=ScriptState, SameObject] readonly attribute FrozenArray<GPUExtensionName> extensions;
[CallWith=ScriptState] Promise<GPUDevice> requestDevice(optional GPUDeviceDescriptor descriptor = {});
};
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 a994694d7c0..6347eb76bc2 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
@@ -4,9 +4,9 @@
#include "third_party/blink/renderer/modules/webgpu/gpu_bind_group.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_bind_group_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_bind_group_entry.h"
#include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_bind_group_binding.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_bind_group_descriptor.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_buffer.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
@@ -15,7 +15,7 @@
namespace blink {
-WGPUBindGroupBinding AsDawnType(const GPUBindGroupBinding* webgpu_binding) {
+WGPUBindGroupBinding AsDawnType(const GPUBindGroupEntry* webgpu_binding) {
WGPUBindGroupBinding dawn_binding = {};
dawn_binding.binding = webgpu_binding->binding();
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 c347eed9402..fda975a87a0 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,5 +6,5 @@
dictionary GPUBindGroupDescriptor : GPUObjectDescriptorBase {
required GPUBindGroupLayout layout;
- required sequence<GPUBindGroupBinding> bindings;
+ required sequence<GPUBindGroupEntry> bindings;
};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_binding.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_entry.idl
index 3dbc7d391e6..31ece4489c8 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_binding.idl
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_entry.idl
@@ -6,7 +6,7 @@
typedef (GPUSampler or GPUTextureView or GPUBufferBinding) GPUBindingResource;
-dictionary GPUBindGroupBinding {
+dictionary GPUBindGroupEntry {
required unsigned long binding;
required GPUBindingResource resource;
};
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 e62a45484d2..af55fe6968d 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
@@ -4,15 +4,15 @@
#include "third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_bind_group_layout_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_bind_group_layout_entry.h"
#include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_binding.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_descriptor.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
namespace blink {
WGPUBindGroupLayoutBinding AsDawnType(
- const GPUBindGroupLayoutBinding* webgpu_binding) {
+ const GPUBindGroupLayoutEntry* webgpu_binding) {
WGPUBindGroupLayoutBinding dawn_binding = {};
dawn_binding.binding = webgpu_binding->binding();
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 96f07ac5e21..45a11bc6ebb 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,5 +5,5 @@
// https://gpuweb.github.io/gpuweb/
dictionary GPUBindGroupLayoutDescriptor : GPUObjectDescriptorBase {
- required sequence<GPUBindGroupLayoutBinding> bindings;
+ required sequence<GPUBindGroupLayoutEntry> bindings;
};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_binding.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_entry.idl
index 02a000d5b40..89c44dc288b 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_binding.idl
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_entry.idl
@@ -4,7 +4,7 @@
// https://gpuweb.github.io/gpuweb/
-dictionary GPUBindGroupLayoutBinding {
+dictionary GPUBindGroupLayoutEntry {
required unsigned long binding;
required GPUShaderStageFlags visibility;
required GPUBindingType type;
@@ -17,6 +17,7 @@ dictionary GPUBindGroupLayoutBinding {
enum GPUBindingType {
"uniform-buffer",
"storage-buffer",
+ "readonly-storage-buffer",
"sampler",
"sampled-texture",
"storage-texture",
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 20a99ca4080..80a4f47b2d5 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.cc
@@ -8,11 +8,11 @@
#include "gpu/command_buffer/client/webgpu_interface.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_buffer_descriptor.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/modules/webgpu/dawn_callback.h"
#include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_buffer_descriptor.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
@@ -121,7 +121,7 @@ GPUBuffer::~GPUBuffer() {
GetProcs().bufferRelease(GetHandle());
}
-void GPUBuffer::Trace(blink::Visitor* visitor) {
+void GPUBuffer::Trace(Visitor* visitor) {
visitor->Trace(mapped_buffer_);
DawnObject<WGPUBuffer>::Trace(visitor);
}
@@ -133,7 +133,7 @@ void GPUBuffer::setSubData(uint64_t dst_byte_offset,
ExceptionState& exception_state) {
const uint8_t* src_base =
reinterpret_cast<const uint8_t*>(src.BaseAddressMaybeOnStack());
- size_t src_byte_length = src.ByteLength();
+ size_t src_byte_length = src.ByteLengthAsSizeT();
if (src_byte_offset > src_byte_length) {
exception_state.ThrowRangeError("srcOffset is too large");
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 eafd242fe15..b7266242464 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(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
// gpu_buffer.idl
void setSubData(uint64_t dst_byte_offset,
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 773faf3070d..526a5f4d606 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
@@ -29,7 +29,7 @@ GPUCanvasContext::GPUCanvasContext(
GPUCanvasContext::~GPUCanvasContext() {}
-void GPUCanvasContext::Trace(blink::Visitor* visitor) {
+void GPUCanvasContext::Trace(Visitor* visitor) {
visitor->Trace(swapchain_);
CanvasRenderingContext::Trace(visitor);
}
@@ -76,7 +76,7 @@ GPUSwapChain* GPUCanvasContext::configureSwapChain(
// destroy all its resources (and produce errors when used).
swapchain_->Neuter();
}
- swapchain_ = GPUSwapChain::Create(this, descriptor);
+ swapchain_ = MakeGarbageCollected<GPUSwapChain>(this, descriptor);
return swapchain_;
}
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 f7adee97aa7..85c9f8174d5 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,7 +39,7 @@ class GPUCanvasContext : public CanvasRenderingContext {
const CanvasContextCreationAttributesCore&);
~GPUCanvasContext() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
const IntSize& CanvasSize() const;
// CanvasRenderingContext implementation
@@ -72,14 +72,6 @@ class GPUCanvasContext : public CanvasRenderingContext {
bool stopped_ = false;
};
-DEFINE_TYPE_CASTS(GPUCanvasContext,
- CanvasRenderingContext,
- context,
- context->GetContextType() ==
- CanvasRenderingContext::kContextGPUPresent,
- context.GetContextType() ==
- CanvasRenderingContext::kContextGPUPresent);
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_CANVAS_CONTEXT_H_
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_buffer.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_buffer.cc
index d2057ad6a22..c781a899d5f 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_buffer.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_buffer.cc
@@ -8,12 +8,6 @@
namespace blink {
-// static
-GPUCommandBuffer* GPUCommandBuffer::Create(GPUDevice* device,
- WGPUCommandBuffer command_buffer) {
- return MakeGarbageCollected<GPUCommandBuffer>(device, command_buffer);
-}
-
GPUCommandBuffer::GPUCommandBuffer(GPUDevice* device,
WGPUCommandBuffer command_buffer)
: DawnObject<WGPUCommandBuffer>(device, command_buffer) {}
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_buffer.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_buffer.h
index af3523c8d7d..efbbfa525cf 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_buffer.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_buffer.h
@@ -13,8 +13,6 @@ class GPUCommandBuffer : public DawnObject<WGPUCommandBuffer> {
DEFINE_WRAPPERTYPEINFO();
public:
- static GPUCommandBuffer* Create(GPUDevice* device,
- WGPUCommandBuffer command_buffer);
explicit GPUCommandBuffer(GPUDevice* device,
WGPUCommandBuffer command_buffer);
~GPUCommandBuffer() override;
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 b7fee550f19..b2544dca2b4 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
@@ -7,50 +7,27 @@
#include "third_party/blink/renderer/bindings/modules/v8/double_sequence_or_gpu_color_dict.h"
#include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_sequence_or_gpu_extent_3d_dict.h"
#include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_sequence_or_gpu_origin_3d_dict.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_buffer_copy_view.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_command_buffer_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_command_encoder_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_compute_pass_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_render_pass_color_attachment_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_render_pass_depth_stencil_attachment_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_render_pass_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_copy_view.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_buffer_copy_view.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_command_buffer.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_command_buffer_descriptor.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_command_encoder_descriptor.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_compute_pass_descriptor.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_render_pass_color_attachment_descriptor.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_render_pass_depth_stencil_attachment_descriptor.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_render_pass_descriptor.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_texture.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_texture_copy_view.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_texture_view.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
-bool ValidateCopySize(UnsignedLongSequenceOrGPUExtent3DDict& copy_size,
- ExceptionState& exception_state) {
- if (copy_size.IsUnsignedLongSequence() &&
- copy_size.GetAsUnsignedLongSequence().size() != 3) {
- exception_state.ThrowRangeError("copySize length must be 3");
- return false;
- }
- return true;
-}
-
-bool ValidateTextureCopyView(GPUTextureCopyView* texture_copy_view,
- ExceptionState& exception_state) {
- DCHECK(texture_copy_view);
-
- const UnsignedLongSequenceOrGPUOrigin3DDict origin =
- texture_copy_view->origin();
- if (origin.IsUnsignedLongSequence() &&
- origin.GetAsUnsignedLongSequence().size() != 3) {
- exception_state.ThrowRangeError(
- "texture copy view origin length must be 3");
- return false;
- }
- return true;
-}
-
WGPURenderPassColorAttachmentDescriptor AsDawnType(
const GPURenderPassColorAttachmentDescriptor* webgpu_desc) {
DCHECK(webgpu_desc);
@@ -145,20 +122,6 @@ WGPUBufferCopyView AsDawnType(const GPUBufferCopyView* webgpu_view) {
return dawn_view;
}
-WGPUTextureCopyView AsDawnType(const GPUTextureCopyView* webgpu_view) {
- DCHECK(webgpu_view);
- DCHECK(webgpu_view->texture());
-
- WGPUTextureCopyView dawn_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());
-
- return dawn_view;
-}
-
WGPUCommandEncoderDescriptor AsDawnType(
const GPUCommandEncoderDescriptor* webgpu_desc) {
DCHECK(webgpu_desc);
@@ -249,7 +212,7 @@ GPURenderPassEncoder* GPUCommandEncoder::beginRenderPass(
dawn_desc.depthStencilAttachment = nullptr;
}
- return GPURenderPassEncoder::Create(
+ return MakeGarbageCollected<GPURenderPassEncoder>(
device_,
GetProcs().commandEncoderBeginRenderPass(GetHandle(), &dawn_desc));
}
@@ -261,7 +224,7 @@ GPUComputePassEncoder* GPUCommandEncoder::beginComputePass(
dawn_desc.label = descriptor->label().Utf8().data();
}
- return GPUComputePassEncoder::Create(
+ return MakeGarbageCollected<GPUComputePassEncoder>(
device_,
GetProcs().commandEncoderBeginComputePass(GetHandle(), &dawn_desc));
}
@@ -354,7 +317,7 @@ GPUCommandBuffer* GPUCommandEncoder::finish(
dawn_desc.label = descriptor->label().Utf8().data();
}
- return GPUCommandBuffer::Create(
+ return MakeGarbageCollected<GPUCommandBuffer>(
device_, GetProcs().commandEncoderFinish(GetHandle(), &dawn_desc));
}
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.cc
index f1bb3a622e1..0c875bb0164 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.cc
@@ -11,14 +11,6 @@
namespace blink {
-// static
-GPUComputePassEncoder* GPUComputePassEncoder::Create(
- GPUDevice* device,
- WGPUComputePassEncoder compute_pass_encoder) {
- return MakeGarbageCollected<GPUComputePassEncoder>(device,
- compute_pass_encoder);
-}
-
GPUComputePassEncoder::GPUComputePassEncoder(
GPUDevice* device,
WGPUComputePassEncoder compute_pass_encoder)
@@ -43,7 +35,7 @@ void GPUComputePassEncoder::setBindGroup(
void GPUComputePassEncoder::setBindGroup(
uint32_t index,
GPUBindGroup* bind_group,
- const FlexibleUint32ArrayView& dynamic_offsets_data,
+ const FlexibleUint32Array& dynamic_offsets_data,
uint64_t dynamic_offsets_data_start,
uint32_t dynamic_offsets_data_length,
ExceptionState& exception_state) {
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.h
index d328255a832..7d8dead8daa 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.h
@@ -20,9 +20,6 @@ class GPUComputePassEncoder : public DawnObject<WGPUComputePassEncoder>,
DEFINE_WRAPPERTYPEINFO();
public:
- static GPUComputePassEncoder* Create(
- GPUDevice* device,
- WGPUComputePassEncoder compute_pass_encoder);
explicit GPUComputePassEncoder(GPUDevice* device,
WGPUComputePassEncoder compute_pass_encoder);
~GPUComputePassEncoder() override;
@@ -33,7 +30,7 @@ class GPUComputePassEncoder : public DawnObject<WGPUComputePassEncoder>,
const Vector<uint32_t>& dynamicOffsets);
void setBindGroup(uint32_t index,
GPUBindGroup* bind_group,
- const FlexibleUint32ArrayView& dynamic_offsets_data,
+ const FlexibleUint32Array& dynamic_offsets_data,
uint64_t dynamic_offsets_data_start,
uint32_t dynamic_offsets_data_length,
ExceptionState& exception_state);
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline.cc
index b056b29fea4..46746b71dc7 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline.cc
@@ -4,12 +4,12 @@
#include "third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_compute_pipeline_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_programmable_stage_descriptor.h"
#include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline_descriptor.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_programmable_stage_descriptor.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_shader_module.h"
namespace blink {
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 e05039330f1..eb67079bbeb 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.cc
@@ -7,6 +7,8 @@
#include "gpu/command_buffer/client/webgpu_interface.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_device_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_uncaptured_error_event_init.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
@@ -17,7 +19,6 @@
#include "third_party/blink/renderer/modules/webgpu/gpu_buffer.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_command_encoder.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_device_descriptor.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_queue.h"
@@ -27,37 +28,30 @@
#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/modules/webgpu/gpu_uncaptured_error_event.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event_init.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
-// static
-GPUDevice* GPUDevice::Create(
- ExecutionContext* execution_context,
- scoped_refptr<DawnControlClientHolder> dawn_control_client,
- GPUAdapter* adapter,
- const GPUDeviceDescriptor* descriptor) {
- return MakeGarbageCollected<GPUDevice>(
- execution_context, std::move(dawn_control_client), adapter, descriptor);
-}
-
// TODO(enga): Handle adapter options and device descriptor
GPUDevice::GPUDevice(ExecutionContext* execution_context,
scoped_refptr<DawnControlClientHolder> dawn_control_client,
GPUAdapter* adapter,
+ uint64_t client_id,
const GPUDeviceDescriptor* descriptor)
- : ContextClient(execution_context),
+ : ExecutionContextClient(execution_context),
DawnObject(dawn_control_client,
- dawn_control_client->GetInterface()->GetDefaultDevice()),
+ dawn_control_client->GetInterface()->GetDevice(client_id)),
adapter_(adapter),
- queue_(GPUQueue::Create(this, GetProcs().deviceCreateQueue(GetHandle()))),
- lost_property_(MakeGarbageCollected<LostProperty>(execution_context,
- this,
- LostProperty::kLost)),
+ queue_(MakeGarbageCollected<GPUQueue>(
+ this,
+ GetProcs().deviceCreateQueue(GetHandle()))),
+ lost_property_(MakeGarbageCollected<LostProperty>(execution_context)),
error_callback_(
BindRepeatingDawnCallback(&GPUDevice::OnUncapturedError,
WrapWeakPersistent(this),
- WrapWeakPersistent(execution_context))) {
+ WrapWeakPersistent(execution_context))),
+ client_id_(client_id) {
+ DCHECK(dawn_control_client->GetInterface()->GetDevice(client_id));
GetProcs().deviceSetUncapturedErrorCallback(
GetHandle(), error_callback_->UnboundRepeatingCallback(),
error_callback_->AsUserdata());
@@ -67,7 +61,13 @@ GPUDevice::~GPUDevice() {
if (IsDawnControlClientDestroyed()) {
return;
}
+ queue_ = nullptr;
GetProcs().deviceRelease(GetHandle());
+ GetInterface()->RemoveDevice(client_id_);
+}
+
+uint64_t GPUDevice::GetClientID() const {
+ return client_id_;
}
void GPUDevice::OnUncapturedError(ExecutionContext* execution_context,
@@ -76,22 +76,22 @@ void GPUDevice::OnUncapturedError(ExecutionContext* execution_context,
if (execution_context) {
DCHECK_NE(errorType, WGPUErrorType_NoError);
LOG(ERROR) << "GPUDevice: " << message;
- ConsoleMessage* console_message =
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kRendering,
- mojom::ConsoleMessageLevel::kWarning, message);
+ auto* console_message = MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kRendering,
+ mojom::ConsoleMessageLevel::kWarning, message);
execution_context->AddConsoleMessage(console_message);
}
// TODO: Use device lost callback instead of uncaptured error callback.
if (errorType == WGPUErrorType_DeviceLost &&
- lost_property_->GetState() == ScriptPromisePropertyBase::kPending) {
- GPUDeviceLostInfo* device_lost_info = GPUDeviceLostInfo::Create(message);
+ lost_property_->GetState() == LostProperty::kPending) {
+ auto* device_lost_info = MakeGarbageCollected<GPUDeviceLostInfo>(message);
lost_property_->Resolve(device_lost_info);
}
GPUUncapturedErrorEventInit* init = GPUUncapturedErrorEventInit::Create();
if (errorType == WGPUErrorType_Validation) {
- GPUValidationError* error = GPUValidationError::Create(message);
+ auto* error = MakeGarbageCollected<GPUValidationError>(message);
init->setError(
GPUOutOfMemoryErrorOrGPUValidationError::FromGPUValidationError(error));
} else if (errorType == WGPUErrorType_OutOfMemory) {
@@ -122,59 +122,16 @@ GPUBuffer* GPUDevice::createBuffer(const GPUBufferDescriptor* descriptor) {
return GPUBuffer::Create(this, descriptor);
}
-HeapVector<ScriptValue> GPUDevice::createBufferMapped(
- ScriptState* script_state,
+HeapVector<GPUBufferOrArrayBuffer> GPUDevice::createBufferMapped(
const GPUBufferDescriptor* descriptor,
ExceptionState& exception_state) {
GPUBuffer* gpu_buffer;
DOMArrayBuffer* array_buffer;
std::tie(gpu_buffer, array_buffer) =
GPUBuffer::CreateMapped(this, descriptor, exception_state);
-
- v8::Isolate* isolate = script_state->GetIsolate();
- v8::Local<v8::Object> creation_context = script_state->GetContext()->Global();
-
- return HeapVector<ScriptValue>({
- ScriptValue(isolate, ToV8(gpu_buffer, creation_context, isolate)),
- ScriptValue(isolate, ToV8(array_buffer, creation_context, isolate)),
- });
-}
-
-ScriptPromise GPUDevice::createBufferMappedAsync(
- ScriptState* script_state,
- const GPUBufferDescriptor* descriptor,
- ExceptionState& exception_state) {
- GPUBuffer* gpu_buffer;
- DOMArrayBuffer* array_buffer;
- std::tie(gpu_buffer, array_buffer) =
- GPUBuffer::CreateMapped(this, descriptor, exception_state);
-
- v8::Isolate* isolate = script_state->GetIsolate();
- v8::Local<v8::Object> creation_context = script_state->GetContext()->Global();
-
- v8::Local<v8::Value> elements[] = {
- ToV8(gpu_buffer, creation_context, isolate),
- ToV8(array_buffer, creation_context, isolate),
- };
-
- ScriptValue result(isolate, v8::Array::New(isolate, elements, 2));
-
- auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
- ScriptPromise promise = resolver->Promise();
- // TODO(enga): CreateBufferMappedAsync is intended to spend more time to
- // create an optimal mapping for the buffer. It resolves the promise when the
- // mapping is complete. Currently, there is always a staging buffer in the
- // wire so this is already the optimal path and the promise is immediately
- // resolved. When we can create a buffer such that the memory is mapped
- // directly in the renderer process, this promise should be resolved
- // asynchronously.
-
- if (exception_state.HadException()) {
- resolver->Reject(exception_state);
- } else {
- resolver->Resolve(result);
- }
- return promise;
+ return HeapVector<GPUBufferOrArrayBuffer>(
+ {GPUBufferOrArrayBuffer::FromGPUBuffer(gpu_buffer),
+ GPUBufferOrArrayBuffer::FromArrayBuffer(array_buffer)});
}
GPUTexture* GPUDevice::createTexture(const GPUTextureDescriptor* descriptor,
@@ -202,8 +159,9 @@ GPUPipelineLayout* GPUDevice::createPipelineLayout(
}
GPUShaderModule* GPUDevice::createShaderModule(
- const GPUShaderModuleDescriptor* descriptor) {
- return GPUShaderModule::Create(this, descriptor);
+ const GPUShaderModuleDescriptor* descriptor,
+ ExceptionState& exception_state) {
+ return GPUShaderModule::Create(this, descriptor, exception_state);
}
GPURenderPipeline* GPUDevice::createRenderPipeline(
@@ -269,7 +227,7 @@ void GPUDevice::OnPopErrorScopeCallback(ScriptPromiseResolver* resolver,
resolver->Resolve(GPUOutOfMemoryError::Create());
break;
case WGPUErrorType_Validation:
- resolver->Resolve(GPUValidationError::Create(message));
+ resolver->Resolve(MakeGarbageCollected<GPUValidationError>(message));
break;
case WGPUErrorType_Unknown:
case WGPUErrorType_DeviceLost:
@@ -282,18 +240,18 @@ void GPUDevice::OnPopErrorScopeCallback(ScriptPromiseResolver* resolver,
}
ExecutionContext* GPUDevice::GetExecutionContext() const {
- return ContextClient::GetExecutionContext();
+ return ExecutionContextClient::GetExecutionContext();
}
const AtomicString& GPUDevice::InterfaceName() const {
return event_target_names::kGPUDevice;
}
-void GPUDevice::Trace(blink::Visitor* visitor) {
+void GPUDevice::Trace(Visitor* visitor) {
visitor->Trace(adapter_);
visitor->Trace(queue_);
visitor->Trace(lost_property_);
- ContextClient::Trace(visitor);
+ ExecutionContextClient::Trace(visitor);
EventTargetWithInlineData::Trace(visitor);
}
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 41abf22c476..c04fd6f679c 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.h
@@ -8,6 +8,7 @@
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_property.h"
+#include "third_party/blink/renderer/bindings/modules/v8/gpu_buffer_or_array_buffer.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/webgpu/dawn_callback.h"
@@ -47,24 +48,22 @@ class ScriptPromiseResolver;
class ScriptState;
class GPUDevice final : public EventTargetWithInlineData,
- public ContextClient,
+ public ExecutionContextClient,
public DawnObject<WGPUDevice> {
USING_GARBAGE_COLLECTED_MIXIN(GPUDevice);
DEFINE_WRAPPERTYPEINFO();
public:
- static GPUDevice* Create(
- ExecutionContext* execution_context,
- scoped_refptr<DawnControlClientHolder> dawn_control_client,
- GPUAdapter* adapter,
- const GPUDeviceDescriptor* descriptor);
explicit GPUDevice(ExecutionContext* execution_context,
scoped_refptr<DawnControlClientHolder> dawn_control_client,
GPUAdapter* adapter,
+ uint64_t client_id,
const GPUDeviceDescriptor* descriptor);
~GPUDevice() override;
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
+
+ uint64_t GetClientID() const;
// gpu_device.idl
GPUAdapter* adapter() const;
@@ -73,13 +72,9 @@ class GPUDevice final : public EventTargetWithInlineData,
GPUQueue* defaultQueue();
GPUBuffer* createBuffer(const GPUBufferDescriptor* descriptor);
- HeapVector<ScriptValue> createBufferMapped(
- ScriptState* script_state,
+ HeapVector<GPUBufferOrArrayBuffer> createBufferMapped(
const GPUBufferDescriptor* descriptor,
ExceptionState& exception_state);
- ScriptPromise createBufferMappedAsync(ScriptState* script_state,
- const GPUBufferDescriptor* descriptor,
- ExceptionState& exception_state);
GPUTexture* createTexture(const GPUTextureDescriptor* descriptor,
ExceptionState& exception_state);
GPUSampler* createSampler(const GPUSamplerDescriptor* descriptor);
@@ -91,7 +86,8 @@ class GPUDevice final : public EventTargetWithInlineData,
const GPUPipelineLayoutDescriptor* descriptor);
GPUShaderModule* createShaderModule(
- const GPUShaderModuleDescriptor* descriptor);
+ const GPUShaderModuleDescriptor* descriptor,
+ ExceptionState& exception_state);
GPURenderPipeline* createRenderPipeline(
ScriptState* script_state,
const GPURenderPipelineDescriptor* descriptor);
@@ -113,9 +109,8 @@ class GPUDevice final : public EventTargetWithInlineData,
ExecutionContext* GetExecutionContext() const override;
private:
- using LostProperty = ScriptPromiseProperty<Member<GPUDevice>,
- Member<GPUDeviceLostInfo>,
- ToV8UndefinedGenerator>;
+ using LostProperty =
+ ScriptPromiseProperty<Member<GPUDeviceLostInfo>, ToV8UndefinedGenerator>;
void OnUncapturedError(ExecutionContext* execution_context,
WGPUErrorType errorType,
@@ -132,6 +127,8 @@ class GPUDevice final : public EventTargetWithInlineData,
DawnCallback<base::RepeatingCallback<void(WGPUErrorType, const char*)>>>
error_callback_;
+ uint64_t client_id_;
+
DISALLOW_COPY_AND_ASSIGN(GPUDevice);
};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.idl
index bd58fb3ee0e..74528e68560 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.idl
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.idl
@@ -13,8 +13,7 @@
[SameObject] readonly attribute GPUQueue defaultQueue;
GPUBuffer createBuffer(GPUBufferDescriptor descriptor);
- [CallWith=ScriptState, RaisesException] GPUMappedBuffer createBufferMapped(GPUBufferDescriptor descriptor);
- [CallWith=ScriptState, RaisesException] Promise<GPUMappedBuffer> createBufferMappedAsync(GPUBufferDescriptor descriptor);
+ [RaisesException] GPUMappedBuffer createBufferMapped(GPUBufferDescriptor descriptor);
[RaisesException] GPUTexture createTexture(GPUTextureDescriptor descriptor);
GPUSampler createSampler(optional GPUSamplerDescriptor descriptor = {});
@@ -22,7 +21,7 @@
GPUBindGroupLayout createBindGroupLayout(GPUBindGroupLayoutDescriptor descriptor);
GPUPipelineLayout createPipelineLayout(GPUPipelineLayoutDescriptor descriptor);
- GPUShaderModule createShaderModule(GPUShaderModuleDescriptor descriptor);
+ [RaisesException] GPUShaderModule createShaderModule(GPUShaderModuleDescriptor descriptor);
[CallWith=ScriptState] GPURenderPipeline createRenderPipeline(GPURenderPipelineDescriptor descriptor);
GPUComputePipeline createComputePipeline(GPUComputePipelineDescriptor descriptor);
@@ -41,5 +40,5 @@ enum GPUErrorFilter {
"validation"
};
-typedef sequence<any> GPUMappedBuffer; // [GPUBuffer, ArrayBuffer]
+typedef sequence<(GPUBuffer or ArrayBuffer)> GPUMappedBuffer;
typedef (GPUOutOfMemoryError or GPUValidationError) GPUError;
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_descriptor.idl
index 83468228edd..fbfe94db830 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_descriptor.idl
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_descriptor.idl
@@ -5,6 +5,6 @@
// https://gpuweb.github.io/gpuweb/
dictionary GPUDeviceDescriptor : GPUObjectDescriptorBase {
- GPUExtensions extensions = {};
+ sequence<GPUExtensionName> extensions = [];
GPULimits limits = {};
};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.cc
index 3a6f1022868..3b97f68351e 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.cc
@@ -6,11 +6,6 @@
namespace blink {
-// static
-GPUDeviceLostInfo* GPUDeviceLostInfo::Create(const String& message) {
- return MakeGarbageCollected<GPUDeviceLostInfo>(message);
-}
-
GPUDeviceLostInfo::GPUDeviceLostInfo(const String& message) {
message_ = message;
}
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.h
index db6b2142a98..eda239e9a7a 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.h
@@ -14,8 +14,7 @@ class GPUDeviceLostInfo : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- static GPUDeviceLostInfo* Create(const String& message);
- GPUDeviceLostInfo(const String& message);
+ explicit GPUDeviceLostInfo(const String& message);
// gpu_device_lost_info.idl
const String& message() const;
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_fence.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_fence.cc
index 11d75d8c6e1..af59d02ce0c 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_fence.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_fence.cc
@@ -13,11 +13,6 @@
namespace blink {
-// static
-GPUFence* GPUFence::Create(GPUDevice* device, WGPUFence fence) {
- return MakeGarbageCollected<GPUFence>(device, fence);
-}
-
GPUFence::GPUFence(GPUDevice* device, WGPUFence fence)
: DawnObject<WGPUFence>(device, fence) {}
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_fence.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_fence.h
index 27dbcac4b87..6dd3b505131 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_fence.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_fence.h
@@ -17,7 +17,6 @@ class GPUFence : public DawnObject<WGPUFence> {
DEFINE_WRAPPERTYPEINFO();
public:
- static GPUFence* Create(GPUDevice* device, WGPUFence fence);
explicit GPUFence(GPUDevice* device, WGPUFence fence);
~GPUFence() override;
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_out_of_memory_error.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_out_of_memory_error.idl
index bd16e3b0e42..495f4d8956b 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_out_of_memory_error.idl
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_out_of_memory_error.idl
@@ -5,7 +5,7 @@
// https://gpuweb.github.io/gpuweb/
[
- Constructor(),
Exposed(Window WebGPU, Worker WebGPU)
] interface GPUOutOfMemoryError {
+ constructor();
};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.cc
index 490d05bd396..bd3760a7bb1 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.cc
@@ -4,10 +4,10 @@
#include "third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_pipeline_layout_descriptor.h"
#include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout_descriptor.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.cc
index 7e6649e9348..11375455bc6 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.cc
@@ -7,12 +7,12 @@
namespace blink {
bool GPUProgrammablePassEncoder::ValidateSetBindGroupDynamicOffsets(
- const FlexibleUint32ArrayView& dynamic_offsets_data,
+ const FlexibleUint32Array& dynamic_offsets_data,
uint64_t dynamic_offsets_data_start,
uint32_t dynamic_offsets_data_length,
ExceptionState& exception_state) {
const uint64_t src_length =
- static_cast<uint64_t>(dynamic_offsets_data.length());
+ static_cast<uint64_t>(dynamic_offsets_data.lengthAsSizeT());
if (dynamic_offsets_data_start > src_length) {
exception_state.ThrowRangeError("dynamicOffsetsDataStart too large");
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.h
index 16dad6100b1..5b427719f36 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.h
@@ -13,7 +13,7 @@ namespace blink {
class GPUProgrammablePassEncoder {
protected:
bool ValidateSetBindGroupDynamicOffsets(
- const FlexibleUint32ArrayView& dynamic_offsets_data,
+ const FlexibleUint32Array& dynamic_offsets_data,
uint64_t dynamic_offsets_data_start,
uint32_t dynamic_offsets_data_length,
ExceptionState& exception_state);
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 3f9afe1c223..fb9b144f986 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
@@ -8,21 +8,52 @@
#include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_sequence_or_gpu_extent_3d_dict.h"
#include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_sequence_or_gpu_origin_2d_dict.h"
#include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_sequence_or_gpu_origin_3d_dict.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_command_buffer_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_fence_descriptor.h"
+#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/modules/webgpu/client_validation.h"
#include "third_party/blink/renderer/modules/webgpu/dawn_conversions.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"
-#include "third_party/blink/renderer/modules/webgpu/gpu_fence_descriptor.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_texture.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_texture_copy_view.h"
+#include "third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
-// static
-GPUQueue* GPUQueue::Create(GPUDevice* device, WGPUQueue queue) {
- return MakeGarbageCollected<GPUQueue>(device, queue);
+namespace {
+
+WGPUOrigin3D GPUOrigin2DToWGPUOrigin3D(
+ const UnsignedLongSequenceOrGPUOrigin2DDict* webgpu_origin) {
+ DCHECK(webgpu_origin);
+
+ WGPUOrigin3D dawn_origin = {};
+
+ if (webgpu_origin->IsUnsignedLongSequence()) {
+ const Vector<uint32_t>& webgpu_origin_sequence =
+ webgpu_origin->GetAsUnsignedLongSequence();
+ DCHECK_EQ(webgpu_origin_sequence.size(), 3UL);
+ dawn_origin.x = webgpu_origin_sequence[0];
+ dawn_origin.y = webgpu_origin_sequence[1];
+ dawn_origin.z = 0;
+ } else if (webgpu_origin->IsGPUOrigin2DDict()) {
+ const GPUOrigin2DDict* webgpu_origin_2d_dict =
+ webgpu_origin->GetAsGPUOrigin2DDict();
+ dawn_origin.x = webgpu_origin_2d_dict->x();
+ dawn_origin.y = webgpu_origin_2d_dict->y();
+ dawn_origin.z = 0;
+ } else {
+ NOTREACHED();
+ }
+
+ return dawn_origin;
}
+} // anonymous namespace
+
GPUQueue::GPUQueue(GPUDevice* device, WGPUQueue queue)
: DawnObject<WGPUQueue>(device, queue) {}
@@ -60,8 +91,8 @@ GPUFence* GPUQueue::createFence(const GPUFenceDescriptor* descriptor) {
desc.label = descriptor->label().Utf8().data();
}
- return GPUFence::Create(device_,
- GetProcs().queueCreateFence(GetHandle(), &desc));
+ return MakeGarbageCollected<GPUFence>(
+ device_, GetProcs().queueCreateFence(GetHandle(), &desc));
}
// TODO(shaobo.yan@intel.com): Implement this function
@@ -70,12 +101,113 @@ void GPUQueue::copyImageBitmapToTexture(
GPUTextureCopyView* destination,
UnsignedLongSequenceOrGPUExtent3DDict& copy_size,
ExceptionState& exception_state) {
- NOTIMPLEMENTED();
+ if (!source->imageBitmap()) {
+ exception_state.ThrowTypeError("No valid imageBitmap");
+ return;
+ }
+
+ // TODO(shaobo.yan@intel.com): only the same color format texture copy allowed
+ // now. Need to Explore compatible texture format copy.
+ if (!ValidateCopySize(copy_size, exception_state) ||
+ !ValidateTextureCopyView(destination, exception_state)) {
+ return;
+ }
+
+ scoped_refptr<StaticBitmapImage> image = source->imageBitmap()->BitmapImage();
+
+ // TODO(shaobo.yan@intel.com): Implement GPU copy path
+ if (image->IsTextureBacked()) {
+ NOTIMPLEMENTED();
+ exception_state.ThrowTypeError(
+ "No support for texture backed imageBitmap yet.");
+ return;
+ }
+
+ // TODO(shaobo.yan@intel.com) : Check that the destination GPUTexture has an
+ // appropriate format. Now only support texture format exactly the same. The
+ // compatible formats need to be defined in WebGPU spec.
+
+ WGPUExtent3D dawn_copy_size = AsDawnType(&copy_size);
+
+ // Extract imageBitmap attributes
+ WGPUOrigin3D origin_in_image_bitmap =
+ GPUOrigin2DToWGPUOrigin3D(&(source->origin()));
+
+ // Validate origin value
+ if (static_cast<uint32_t>(image->width()) <= origin_in_image_bitmap.x ||
+ static_cast<uint32_t>(image->height()) <= origin_in_image_bitmap.y) {
+ exception_state.ThrowRangeError(
+ "Copy origin is out of bounds of imageBitmap.");
+ return;
+ }
+
+ // Validate the copy rect is inside the imageBitmap
+ if (image->width() - origin_in_image_bitmap.x < dawn_copy_size.width ||
+ image->height() - origin_in_image_bitmap.y < dawn_copy_size.height) {
+ exception_state.ThrowRangeError(
+ "Copy rect is out of bounds of imageBitmap.");
+ return;
+ }
+
+ // Prepare for uploading CPU data.
+ IntRect image_data_rect(origin_in_image_bitmap.x, origin_in_image_bitmap.y,
+ dawn_copy_size.width, dawn_copy_size.height);
+ const CanvasColorParams& color_params =
+ source->imageBitmap()->GetCanvasColorParams();
+ WebGPUImageUploadSizeInfo info =
+ ComputeImageBitmapWebGPUUploadSizeInfo(image_data_rect, color_params);
+
+ // Create a mapped buffer to receive image bitmap contents
+ WGPUBufferDescriptor buffer_desc;
+ buffer_desc.nextInChain = nullptr;
+ buffer_desc.label = nullptr;
+ buffer_desc.usage = WGPUBufferUsage_CopySrc;
+ buffer_desc.size = info.size_in_bytes;
+
+ WGPUCreateBufferMappedResult result =
+ GetProcs().deviceCreateBufferMapped(device_->GetHandle(), &buffer_desc);
+
+ if (!CopyBytesFromImageBitmapForWebGPU(
+ image,
+ base::span<uint8_t>(reinterpret_cast<uint8_t*>(result.data),
+ static_cast<size_t>(result.dataLength)),
+ image_data_rect, color_params)) {
+ exception_state.ThrowRangeError("Failed to copy image data");
+ // Release the buffer.
+ GetProcs().bufferRelease(result.buffer);
+ return;
+ }
+
+ GetProcs().bufferUnmap(result.buffer);
+
+ // Start a B2T copy to move contents from buffer to destination texture
+ WGPUBufferCopyView dawn_intermediate;
+ dawn_intermediate.nextInChain = nullptr;
+ dawn_intermediate.buffer = result.buffer;
+ dawn_intermediate.offset = 0;
+ dawn_intermediate.rowPitch = info.wgpu_row_pitch;
+ dawn_intermediate.imageHeight = source->imageBitmap()->height();
+
+ WGPUTextureCopyView dawn_destination = AsDawnType(destination);
+
+ WGPUCommandEncoderDescriptor encoder_desc = {};
+ WGPUCommandEncoder encoder = GetProcs().deviceCreateCommandEncoder(
+ device_->GetHandle(), &encoder_desc);
+ GetProcs().commandEncoderCopyBufferToTexture(
+ encoder, &dawn_intermediate, &dawn_destination, &dawn_copy_size);
+ WGPUCommandBufferDescriptor dawn_desc_command = {};
+ WGPUCommandBuffer commands =
+ GetProcs().commandEncoderFinish(encoder, &dawn_desc_command);
+
+ // Don't need to add fence after this submit. Because if user want to use the
+ // texture to do copy or render, it will trigger another queue submit. Dawn
+ // will insert the necessary resource transitions.
+ GetProcs().queueSubmit(GetHandle(), 1, &commands);
- // TODO(shaobo.yan@intel.com): Validate source copy size, format and dest copy
- // size format
- // TODO(shaobo.yan@intel.com): Implement sharing to staging texture path.
- return;
+ // Release intermediate resources.
+ GetProcs().commandBufferRelease(commands);
+ GetProcs().commandEncoderRelease(encoder);
+ GetProcs().bufferRelease(result.buffer);
}
} // namespace blink
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 042a59d9ee9..a2e54689e8e 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.h
@@ -22,7 +22,6 @@ class GPUQueue : public DawnObject<WGPUQueue> {
DEFINE_WRAPPERTYPEINFO();
public:
- static GPUQueue* Create(GPUDevice* device, WGPUQueue queue);
explicit GPUQueue(GPUDevice* device, WGPUQueue queue);
~GPUQueue() override;
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 fd6251efe19..417ab153a7a 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.idl
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.idl
@@ -11,4 +11,8 @@
GPUFence createFence(optional GPUFenceDescriptor descriptor = {});
void signal(GPUFence fence, unsigned long long signalValue);
+ [RaisesException] void copyImageBitmapToTexture(
+ GPUImageBitmapCopyView source,
+ GPUTextureCopyView destination,
+ GPUExtent3D copySize);
};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle.cc
index a84dc98a7d0..266a5b99e87 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle.cc
@@ -8,12 +8,6 @@
namespace blink {
-// static
-GPURenderBundle* GPURenderBundle::Create(GPUDevice* device,
- WGPURenderBundle render_bundle) {
- return MakeGarbageCollected<GPURenderBundle>(device, render_bundle);
-}
-
GPURenderBundle::GPURenderBundle(GPUDevice* device,
WGPURenderBundle render_bundle)
: DawnObject<WGPURenderBundle>(device, render_bundle) {}
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle.h
index 8107a123c2d..b9f06fdac5a 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle.h
@@ -15,8 +15,6 @@ class GPURenderBundle : public DawnObject<WGPURenderBundle> {
DEFINE_WRAPPERTYPEINFO();
public:
- static GPURenderBundle* Create(GPUDevice* device,
- WGPURenderBundle render_bundle);
explicit GPURenderBundle(GPUDevice* device, WGPURenderBundle render_bundle);
~GPURenderBundle() override;
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.cc
index 3cab5d2a547..718ca35af7c 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.cc
@@ -4,14 +4,15 @@
#include "third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_render_bundle_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_render_bundle_encoder_descriptor.h"
#include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_bind_group.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_buffer.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_render_bundle.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_render_bundle_descriptor.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder_descriptor.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
@@ -70,7 +71,7 @@ void GPURenderBundleEncoder::setBindGroup(
void GPURenderBundleEncoder::setBindGroup(
uint32_t index,
GPUBindGroup* bind_group,
- const FlexibleUint32ArrayView& dynamic_offsets_data,
+ const FlexibleUint32Array& dynamic_offsets_data,
uint64_t dynamic_offsets_data_start,
uint32_t dynamic_offsets_data_length,
ExceptionState& exception_state) {
@@ -159,7 +160,7 @@ GPURenderBundle* GPURenderBundleEncoder::finish(
WGPURenderBundle render_bundle =
GetProcs().renderBundleEncoderFinish(GetHandle(), &dawn_desc);
- return GPURenderBundle::Create(device_, render_bundle);
+ return MakeGarbageCollected<GPURenderBundle>(device_, render_bundle);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.h
index a18bd84653a..24ef7b4f9d2 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.h
@@ -37,7 +37,7 @@ class GPURenderBundleEncoder : public DawnObject<WGPURenderBundleEncoder>,
const Vector<uint32_t>& dynamicOffsets);
void setBindGroup(uint32_t index,
GPUBindGroup* bind_group,
- const FlexibleUint32ArrayView& dynamic_offsets_data,
+ const FlexibleUint32Array& dynamic_offsets_data,
uint64_t dynamic_offsets_data_start,
uint32_t dynamic_offsets_data_length,
ExceptionState& exception_state);
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc
index 2761389593c..423978577fa 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc
@@ -15,14 +15,6 @@
namespace blink {
-// static
-GPURenderPassEncoder* GPURenderPassEncoder::Create(
- GPUDevice* device,
- WGPURenderPassEncoder render_pass_encoder) {
- return MakeGarbageCollected<GPURenderPassEncoder>(device,
- render_pass_encoder);
-}
-
GPURenderPassEncoder::GPURenderPassEncoder(
GPUDevice* device,
WGPURenderPassEncoder render_pass_encoder)
@@ -47,7 +39,7 @@ void GPURenderPassEncoder::setBindGroup(
void GPURenderPassEncoder::setBindGroup(
uint32_t index,
GPUBindGroup* bind_group,
- const FlexibleUint32ArrayView& dynamic_offsets_data,
+ const FlexibleUint32Array& dynamic_offsets_data,
uint64_t dynamic_offsets_data_start,
uint32_t dynamic_offsets_data_length,
ExceptionState& exception_state) {
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h
index 3faf70327d9..feb580b1c29 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h
@@ -22,9 +22,6 @@ class GPURenderPassEncoder : public DawnObject<WGPURenderPassEncoder>,
DEFINE_WRAPPERTYPEINFO();
public:
- static GPURenderPassEncoder* Create(
- GPUDevice* device,
- WGPURenderPassEncoder render_pass_encoder);
explicit GPURenderPassEncoder(GPUDevice* device,
WGPURenderPassEncoder render_pass_encoder);
~GPURenderPassEncoder() override;
@@ -35,7 +32,7 @@ class GPURenderPassEncoder : public DawnObject<WGPURenderPassEncoder>,
const Vector<uint32_t>& dynamicOffsets);
void setBindGroup(uint32_t index,
GPUBindGroup* bind_group,
- const FlexibleUint32ArrayView& dynamic_offsets_data,
+ const FlexibleUint32Array& dynamic_offsets_data,
uint64_t dynamic_offsets_data_start,
uint32_t dynamic_offsets_data_length,
ExceptionState& exception_state);
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.cc
index 2a2b75b0442..d22361fc0b8 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.cc
@@ -4,20 +4,20 @@
#include "third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.h"
+#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_blend_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_color_state_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_depth_stencil_state_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_rasterization_state_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_render_pipeline_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_stencil_state_face_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_vertex_attribute_descriptor.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_vertex_buffer_layout_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_vertex_state_descriptor.h"
#include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_blend_descriptor.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_color_state_descriptor.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_depth_stencil_state_descriptor.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_rasterization_state_descriptor.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_render_pipeline_descriptor.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_stencil_state_face_descriptor.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_vertex_attribute_descriptor.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_vertex_buffer_layout_descriptor.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_vertex_state_descriptor.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
@@ -139,26 +139,26 @@ WGPUVertexStateInfo GPUVertexStateAsWGPUVertexState(
continue;
}
- GPUVertexBufferLayoutDescriptor vertex_buffer;
- V8GPUVertexBufferLayoutDescriptor::ToImpl(isolate, value, &vertex_buffer,
- exception_state);
+ GPUVertexBufferLayoutDescriptor* vertex_buffer =
+ NativeValueTraits<GPUVertexBufferLayoutDescriptor>::NativeValue(
+ isolate, value, exception_state);
if (exception_state.HadException()) {
return std::make_tuple(dawn_desc, std::move(dawn_vertex_buffers),
std::move(dawn_vertex_attributes));
}
WGPUVertexBufferLayoutDescriptor dawn_vertex_buffer = {};
- dawn_vertex_buffer.arrayStride = vertex_buffer.arrayStride();
+ dawn_vertex_buffer.arrayStride = vertex_buffer->arrayStride();
dawn_vertex_buffer.stepMode =
- AsDawnEnum<WGPUInputStepMode>(vertex_buffer.stepMode());
+ AsDawnEnum<WGPUInputStepMode>(vertex_buffer->stepMode());
dawn_vertex_buffer.attributeCount =
- static_cast<uint32_t>(vertex_buffer.attributes().size());
+ static_cast<uint32_t>(vertex_buffer->attributes().size());
dawn_vertex_buffer.attributes = nullptr;
dawn_vertex_buffers.push_back(dawn_vertex_buffer);
- for (wtf_size_t j = 0; j < vertex_buffer.attributes().size(); ++j) {
+ for (wtf_size_t j = 0; j < vertex_buffer->attributes().size(); ++j) {
const GPUVertexAttributeDescriptor* attribute =
- vertex_buffer.attributes()[j];
+ vertex_buffer->attributes()[j];
WGPUVertexAttributeDescriptor dawn_vertex_attribute = {};
dawn_vertex_attribute.shaderLocation = attribute->shaderLocation();
dawn_vertex_attribute.offset = attribute->offset();
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_sampler.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_sampler.cc
index b0d72e4dcbf..71d1563cfa1 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_sampler.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_sampler.cc
@@ -4,9 +4,9 @@
#include "third_party/blink/renderer/modules/webgpu/gpu_sampler.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_sampler_descriptor.h"
#include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_sampler_descriptor.h"
namespace blink {
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 c9f4e024d1b..b11a29f5a63 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
@@ -4,36 +4,37 @@
#include "third_party/blink/renderer/modules/webgpu/gpu_shader_module.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_shader_module_descriptor.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_shader_module_descriptor.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
namespace blink {
-namespace {
+// static
+GPUShaderModule* GPUShaderModule::Create(
+ GPUDevice* device,
+ const GPUShaderModuleDescriptor* webgpu_desc,
+ ExceptionState& exception_state) {
+ DCHECK(device);
+ DCHECK(webgpu_desc);
+ uint32_t byte_length = 0;
+ if (!base::CheckedNumeric<uint32_t>(
+ webgpu_desc->code().View()->lengthAsSizeT())
+ .AssignIfValid(&byte_length)) {
+ exception_state.ThrowRangeError(
+ "The provided ArrayBuffer exceeds the maximum supported size "
+ "(4294967295)");
+ return nullptr;
+ }
-WGPUShaderModuleDescriptor AsDawnType(
- const GPUShaderModuleDescriptor* webgpu_desc) {
WGPUShaderModuleDescriptor dawn_desc = {};
-
dawn_desc.nextInChain = nullptr;
- dawn_desc.code = webgpu_desc->code().View()->Data();
- dawn_desc.codeSize = webgpu_desc->code().View()->deprecatedLengthAsUnsigned();
+ dawn_desc.code = webgpu_desc->code().View()->DataMaybeShared();
+ dawn_desc.codeSize = byte_length;
if (webgpu_desc->hasLabel()) {
dawn_desc.label = webgpu_desc->label().Utf8().data();
}
- return dawn_desc;
-}
-
-} // anonymous namespace
-
-// static
-GPUShaderModule* GPUShaderModule::Create(
- GPUDevice* device,
- const GPUShaderModuleDescriptor* webgpu_desc) {
- DCHECK(device);
- DCHECK(webgpu_desc);
- WGPUShaderModuleDescriptor dawn_desc = AsDawnType(webgpu_desc);
return MakeGarbageCollected<GPUShaderModule>(
device, device->GetProcs().deviceCreateShaderModule(device->GetHandle(),
&dawn_desc));
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module.h
index 3f1d4b7b39e..90f32a1b2fd 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module.h
@@ -10,13 +10,15 @@
namespace blink {
class GPUShaderModuleDescriptor;
+class ExceptionState;
class GPUShaderModule : public DawnObject<WGPUShaderModule> {
DEFINE_WRAPPERTYPEINFO();
public:
static GPUShaderModule* Create(GPUDevice* device,
- const GPUShaderModuleDescriptor* webgpu_desc);
+ const GPUShaderModuleDescriptor* webgpu_desc,
+ ExceptionState& exception_state);
explicit GPUShaderModule(GPUDevice* device, WGPUShaderModule shader_module);
~GPUShaderModule() override;
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 ca733b9ba95..fe01b27e629 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,5 +5,5 @@
// https://gpuweb.github.io/gpuweb/
dictionary GPUShaderModuleDescriptor : GPUObjectDescriptorBase {
- [AllowShared] required Uint32Array code;
+ required [AllowShared] 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 4b98fdbd737..ffcadb1d79d 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
@@ -4,20 +4,15 @@
#include "third_party/blink/renderer/modules/webgpu/gpu_swap_chain.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_swap_chain_descriptor.h"
#include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_swap_chain_descriptor.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_texture.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
-// static
-GPUSwapChain* GPUSwapChain::Create(GPUCanvasContext* context,
- const GPUSwapChainDescriptor* descriptor) {
- return MakeGarbageCollected<GPUSwapChain>(context, descriptor);
-}
-
GPUSwapChain::GPUSwapChain(GPUCanvasContext* context,
const GPUSwapChainDescriptor* descriptor)
: DawnObjectBase(descriptor->device()->GetDawnControlClient()),
@@ -26,7 +21,7 @@ GPUSwapChain::GPUSwapChain(GPUCanvasContext* context,
usage_(AsDawnEnum<WGPUTextureUsage>(descriptor->usage())) {
// TODO: Use label from GPUObjectDescriptorBase.
swap_buffers_ = base::AdoptRef(new WebGPUSwapBufferProvider(
- this, GetDawnControlClient(), usage_,
+ this, GetDawnControlClient(), device_->GetClientID(), usage_,
AsDawnEnum<WGPUTextureFormat>(descriptor->format())));
}
@@ -34,7 +29,7 @@ GPUSwapChain::~GPUSwapChain() {
Neuter();
}
-void GPUSwapChain::Trace(blink::Visitor* visitor) {
+void GPUSwapChain::Trace(Visitor* visitor) {
visitor->Trace(device_);
visitor->Trace(context_);
visitor->Trace(texture_);
@@ -71,8 +66,8 @@ GPUTexture* GPUSwapChain::getCurrentTexture() {
return texture_;
}
- WGPUTexture dawn_client_texture = swap_buffers_->GetNewTexture(
- device_->GetHandle(), context_->CanvasSize());
+ WGPUTexture dawn_client_texture =
+ swap_buffers_->GetNewTexture(context_->CanvasSize());
DCHECK(dawn_client_texture);
texture_ = MakeGarbageCollected<GPUTexture>(device_, dawn_client_texture);
return 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 ee203863eb8..61704a33a13 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
@@ -25,13 +25,11 @@ class GPUSwapChain : public ScriptWrappable,
DEFINE_WRAPPERTYPEINFO();
public:
- static GPUSwapChain* Create(GPUCanvasContext* context,
- const GPUSwapChainDescriptor* descriptor);
explicit GPUSwapChain(GPUCanvasContext* context,
const GPUSwapChainDescriptor* descriptor);
~GPUSwapChain() override;
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
void Neuter();
cc::Layer* CcLayer();
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture.cc
index 39e6142d4a7..71366b53db0 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture.cc
@@ -4,11 +4,11 @@
#include "third_party/blink/renderer/modules/webgpu/gpu_texture.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_descriptor.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_view_descriptor.h"
#include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_texture_descriptor.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_texture_view.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_texture_view_descriptor.h"
namespace blink {
@@ -94,7 +94,7 @@ GPUTextureView* GPUTexture::createView(
DCHECK(webgpu_desc);
WGPUTextureViewDescriptor dawn_desc = AsDawnType(webgpu_desc);
- return GPUTextureView::Create(
+ return MakeGarbageCollected<GPUTextureView>(
device_, GetProcs().textureCreateView(GetHandle(), &dawn_desc));
}
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_descriptor.idl
index e7b7b96b274..6dbb94ad9f6 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_descriptor.idl
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_descriptor.idl
@@ -65,5 +65,20 @@ enum GPUTextureFormat {
/* Depth / Stencil formats */
"depth32float",
"depth24plus",
- "depth24plus-stencil8"
+ "depth24plus-stencil8",
+ /* Block Compression (BC) formats */
+ "bc1-rgba-unorm",
+ "bc1-rgba-unorm-srgb",
+ "bc2-rgba-unorm",
+ "bc2-rgba-unorm-srgb",
+ "bc3-rgba-unorm",
+ "bc3-rgba-unorm-srgb",
+ "bc4-r-unorm",
+ "bc4-r-snorm",
+ "bc5-rg-unorm",
+ "bc5-rg-snorm",
+ "bc6h-rgb-ufloat",
+ "bc6h-rgb-sfloat",
+ "bc7-rgba-unorm",
+ "bc7-rgba-unorm-srgb"
};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_view.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_view.cc
index 88ec146c10e..91641b180f0 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_view.cc
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_view.cc
@@ -8,12 +8,6 @@
namespace blink {
-// static
-GPUTextureView* GPUTextureView::Create(GPUDevice* device,
- WGPUTextureView texture_view) {
- return MakeGarbageCollected<GPUTextureView>(device, texture_view);
-}
-
GPUTextureView::GPUTextureView(GPUDevice* device, WGPUTextureView texture_view)
: DawnObject<WGPUTextureView>(device, texture_view) {}
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_view.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_view.h
index 600c55b8f39..3eb00bcb86b 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_view.h
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_view.h
@@ -13,8 +13,6 @@ class GPUTextureView : public DawnObject<WGPUTextureView> {
DEFINE_WRAPPERTYPEINFO();
public:
- static GPUTextureView* Create(GPUDevice* device,
- WGPUTextureView texture_view);
explicit GPUTextureView(GPUDevice* device, WGPUTextureView texture_view);
~GPUTextureView() override;
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 17a86edac11..ca53b3d38ca 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
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.h"
-#include "third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_uncaptured_error_event_init.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.idl
index 8fd5127ccdd..6df8aaf0f21 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.idl
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.idl
@@ -5,8 +5,8 @@
// https://gpuweb.github.io/gpuweb/
[
- Constructor(DOMString type, GPUUncapturedErrorEventInit gpuUncapturedErrorEventInitDict),
Exposed(Window WebGPU, Worker WebGPU)
] interface GPUUncapturedErrorEvent : Event {
+ constructor(DOMString type, GPUUncapturedErrorEventInit gpuUncapturedErrorEventInitDict);
[SameObject] readonly attribute GPUError error;
};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_validation_error.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_validation_error.idl
index d372e5f75e9..16fb2803cc7 100644
--- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_validation_error.idl
+++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_validation_error.idl
@@ -5,8 +5,8 @@
// https://gpuweb.github.io/gpuweb/
[
- Constructor(DOMString message),
Exposed(Window WebGPU, Worker WebGPU)
] interface GPUValidationError {
+ constructor(DOMString message);
readonly attribute DOMString message;
};
diff --git a/chromium/third_party/blink/renderer/modules/webgpu/idls.gni b/chromium/third_party/blink/renderer/modules/webgpu/idls.gni
new file mode 100644
index 00000000000..04e12c9fc18
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webgpu/idls.gni
@@ -0,0 +1,92 @@
+# 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 = [
+ "gpu.idl",
+ "gpu_adapter.idl",
+ "gpu_bind_group.idl",
+ "gpu_bind_group_layout.idl",
+ "gpu_buffer.idl",
+ "gpu_buffer_usage.idl",
+ "gpu_canvas_context.idl",
+ "gpu_color_write.idl",
+ "gpu_command_buffer.idl",
+ "gpu_command_encoder.idl",
+ "gpu_compute_pass_encoder.idl",
+ "gpu_compute_pipeline.idl",
+ "gpu_device.idl",
+ "gpu_device_lost_info.idl",
+ "gpu_fence.idl",
+ "gpu_out_of_memory_error.idl",
+ "gpu_pipeline_layout.idl",
+ "gpu_queue.idl",
+ "gpu_render_bundle.idl",
+ "gpu_render_bundle_encoder.idl",
+ "gpu_render_pass_encoder.idl",
+ "gpu_render_pipeline.idl",
+ "gpu_sampler.idl",
+ "gpu_shader_module.idl",
+ "gpu_shader_stage.idl",
+ "gpu_swap_chain.idl",
+ "gpu_texture.idl",
+ "gpu_texture_usage.idl",
+ "gpu_texture_view.idl",
+ "gpu_uncaptured_error_event.idl",
+ "gpu_validation_error.idl",
+]
+
+modules_dictionary_idl_files = [
+ "gpu_bind_group_entry.idl",
+ "gpu_bind_group_descriptor.idl",
+ "gpu_bind_group_layout_entry.idl",
+ "gpu_bind_group_layout_descriptor.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_encoder_descriptor.idl",
+ "gpu_compute_pipeline_descriptor.idl",
+ "gpu_compute_pass_descriptor.idl",
+ "gpu_depth_stencil_state_descriptor.idl",
+ "gpu_device_descriptor.idl",
+ "gpu_extent_3d_dict.idl",
+ "gpu_fence_descriptor.idl",
+ "gpu_image_bitmap_copy_view.idl",
+ "gpu_limits.idl",
+ "gpu_object_descriptor_base.idl",
+ "gpu_origin_2d_dict.idl",
+ "gpu_origin_3d_dict.idl",
+ "gpu_pipeline_descriptor_base.idl",
+ "gpu_pipeline_layout_descriptor.idl",
+ "gpu_programmable_stage_descriptor.idl",
+ "gpu_rasterization_state_descriptor.idl",
+ "gpu_render_bundle_descriptor.idl",
+ "gpu_render_bundle_encoder_descriptor.idl",
+ "gpu_render_pass_color_attachment_descriptor.idl",
+ "gpu_render_pass_depth_stencil_attachment_descriptor.idl",
+ "gpu_render_pass_descriptor.idl",
+ "gpu_render_pipeline_descriptor.idl",
+ "gpu_request_adapter_options.idl",
+ "gpu_sampler_descriptor.idl",
+ "gpu_shader_module_descriptor.idl",
+ "gpu_stencil_state_face_descriptor.idl",
+ "gpu_swap_chain_descriptor.idl",
+ "gpu_texture_copy_view.idl",
+ "gpu_texture_descriptor.idl",
+ "gpu_texture_view_descriptor.idl",
+ "gpu_uncaptured_error_event_init.idl",
+ "gpu_vertex_attribute_descriptor.idl",
+ "gpu_vertex_buffer_layout_descriptor.idl",
+ "gpu_vertex_state_descriptor.idl",
+]
+
+modules_dependency_idl_files = [
+ "gpu_programmable_pass_encoder.idl",
+ "gpu_render_encoder_base.idl",
+ "navigator_gpu.idl",
+ "worker_navigator_gpu.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 a221d489b2d..5095f6713b2 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(blink::Visitor* visitor) {
+void NavigatorGPU::Trace(Visitor* visitor) {
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 79312b234c0..0b1f91a6165 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 8f5e7cbe15e..ee687c44388 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(blink::Visitor* visitor) {
+void WorkerNavigatorGPU::Trace(Visitor* visitor) {
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 0f8eabe1d54..edde4bd8916 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<GPU> gpu_;
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/BUILD.gn b/chromium/third_party/blink/renderer/modules/webmidi/BUILD.gn
index f9d672c23c1..d804ae648dd 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/webmidi/BUILD.gn
@@ -31,7 +31,5 @@ blink_modules_sources("webmidi") {
"navigator_web_midi.h",
]
- deps = [
- "//media/midi:mojo_blink",
- ]
+ deps = [ "//media/midi:mojo_blink" ]
}
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/idls.gni b/chromium/third_party/blink/renderer/modules/webmidi/idls.gni
new file mode 100644
index 00000000000..13fdae57ed0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webmidi/idls.gni
@@ -0,0 +1,22 @@
+# 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 = [
+ "midi_access.idl",
+ "midi_connection_event.idl",
+ "midi_input.idl",
+ "midi_input_map.idl",
+ "midi_message_event.idl",
+ "midi_output.idl",
+ "midi_output_map.idl",
+ "midi_port.idl",
+]
+
+modules_dictionary_idl_files = [
+ "midi_connection_event_init.idl",
+ "midi_message_event_init.idl",
+ "midi_options.idl",
+]
+
+modules_dependency_idl_files = [ "navigator_web_midi.idl" ]
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 04cc41def10..bafeeba1060 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_access.cc
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_access.cc
@@ -64,7 +64,7 @@ MIDIAccess::MIDIAccess(
bool sysex_enabled,
const Vector<MIDIAccessInitializer::PortDescriptor>& ports,
ExecutionContext* execution_context)
- : ContextLifecycleObserver(execution_context),
+ : ExecutionContextLifecycleObserver(execution_context),
dispatcher_(std::move(dispatcher)),
sysex_enabled_(sysex_enabled),
has_pending_activity_(false) {
@@ -202,15 +202,15 @@ void MIDIAccess::SendMIDIData(unsigned port_index,
dispatcher_->SendMIDIData(port_index, data, length, time_stamp);
}
-void MIDIAccess::ContextDestroyed(ExecutionContext*) {
+void MIDIAccess::ContextDestroyed() {
dispatcher_.reset();
}
-void MIDIAccess::Trace(blink::Visitor* visitor) {
+void MIDIAccess::Trace(Visitor* visitor) {
visitor->Trace(inputs_);
visitor->Trace(outputs_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
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 45037a53088..bbc5d585898 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_access.h
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_access.h
@@ -35,7 +35,7 @@
#include "media/midi/midi_service.mojom-blink-forward.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/core/execution_context/context_lifecycle_observer.h"
+#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/webmidi/midi_access_initializer.h"
#include "third_party/blink/renderer/modules/webmidi/midi_dispatcher.h"
@@ -52,7 +52,7 @@ class MIDIOutputMap;
class MIDIAccess final : public EventTargetWithInlineData,
public ActiveScriptWrappable<MIDIAccess>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public MIDIDispatcher::Client {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(MIDIAccess);
@@ -78,14 +78,14 @@ class MIDIAccess final : public EventTargetWithInlineData,
return event_target_names::kMIDIAccess;
}
ExecutionContext* GetExecutionContext() const override {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
// ScriptWrappable
bool HasPendingActivity() const final;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
// MIDIDispatcher::Client
void DidAddInputPort(const String& id,
@@ -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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 616ecae5c39..39120ec7e60 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
@@ -8,9 +8,9 @@
#include <utility>
#include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h"
-#include "third_party/blink/public/platform/interface_provider.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_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"
@@ -18,7 +18,6 @@
#include "third_party/blink/renderer/core/frame/navigator.h"
#include "third_party/blink/renderer/modules/permissions/permission_utils.h"
#include "third_party/blink/renderer/modules/webmidi/midi_access.h"
-#include "third_party/blink/renderer/modules/webmidi/midi_options.h"
#include "third_party/blink/renderer/modules/webmidi/midi_port.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/mojo/mojo_helper.h"
@@ -38,11 +37,11 @@ void MIDIAccessInitializer::Dispose() {
permission_service_.reset();
}
-void MIDIAccessInitializer::ContextDestroyed(ExecutionContext* context) {
+void MIDIAccessInitializer::ContextDestroyed() {
dispatcher_.reset();
permission_service_.reset();
- ScriptPromiseResolver::ContextDestroyed(context);
+ ScriptPromiseResolver::ContextDestroyed();
}
ScriptPromise MIDIAccessInitializer::Start() {
@@ -56,7 +55,7 @@ ScriptPromise MIDIAccessInitializer::Start() {
GetExecutionContext(),
permission_service_.BindNewPipeAndPassReceiver(std::move(task_runner)));
- Document& doc = To<Document>(*GetExecutionContext());
+ Document& doc = Document::From(*GetExecutionContext());
permission_service_->RequestPermission(
CreateMidiPermissionDescriptor(options_->hasSysex() && options_->sysex()),
LocalFrame::HasTransientUserActivation(doc.GetFrame()),
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 b3271887604..8ae5e42a899 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
@@ -12,9 +12,9 @@
#include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink-forward.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_midi_options.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/webmidi/midi_dispatcher.h"
-#include "third_party/blink/renderer/modules/webmidi/midi_options.h"
#include "third_party/blink/renderer/modules/webmidi/midi_port.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -90,7 +90,7 @@ class MODULES_EXPORT MIDIAccessInitializer : public ScriptPromiseResolver,
ExecutionContext* GetExecutionContext() const;
ScriptPromise Start();
- void ContextDestroyed(ExecutionContext*) override;
+ void ContextDestroyed() override;
void StartSession();
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 b08a4b1d41d..94b12a6f4ee 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
@@ -30,7 +30,7 @@
#include "third_party/blink/renderer/modules/webmidi/midi_connection_event.h"
-#include "third_party/blink/renderer/modules/webmidi/midi_connection_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_midi_connection_event_init.h"
namespace blink {
@@ -42,7 +42,7 @@ MIDIConnectionEvent::MIDIConnectionEvent(
port_ = initializer->port();
}
-void MIDIConnectionEvent::Trace(blink::Visitor* visitor) {
+void MIDIConnectionEvent::Trace(Visitor* visitor) {
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 40ed7cda65d..71954524822 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<MIDIPort> port_;
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_connection_event.idl b/chromium/third_party/blink/renderer/modules/webmidi/midi_connection_event.idl
index 93532e7f782..8627cbd75c0 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_connection_event.idl
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_connection_event.idl
@@ -31,8 +31,8 @@
// https://webaudio.github.io/web-midi-api/#MIDIConnectionEvent
[
- SecureContext,
- Constructor(DOMString type, optional MIDIConnectionEventInit eventInitDict)
+ SecureContext
] interface MIDIConnectionEvent : Event {
+ constructor(DOMString type, optional MIDIConnectionEventInit eventInitDict = {});
readonly attribute MIDIPort port;
};
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_dispatcher.cc b/chromium/third_party/blink/renderer/modules/webmidi/midi_dispatcher.cc
index 23663f4f1b3..a9aba08713c 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_dispatcher.cc
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_dispatcher.cc
@@ -7,7 +7,7 @@
#include <utility>
#include "mojo/public/cpp/bindings/pending_remote.h"
-#include "third_party/blink/public/platform/interface_provider.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_string.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
@@ -27,7 +27,7 @@ MIDIDispatcher::MIDIDispatcher(
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
: task_runner_(std::move(task_runner)) {
TRACE_EVENT0("midi", "MIDIDispatcher::MIDIDispatcher");
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
midi_session_provider_.BindNewPipeAndPassReceiver(task_runner_));
midi_session_provider_->StartSession(
midi_session_.BindNewPipeAndPassReceiver(),
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 3cd09bdc7d9..380678a5659 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_input.cc
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_input.cc
@@ -95,11 +95,11 @@ void MIDIInput::DidReceiveMIDIData(unsigned port_index,
DOMUint8Array::Create(data, SafeCast<unsigned>(length));
DispatchEvent(*MakeGarbageCollected<MIDIMessageEvent>(time_stamp, array));
- UseCounter::Count(*To<Document>(GetExecutionContext()),
+ UseCounter::Count(*Document::From(GetExecutionContext()),
WebFeature::kMIDIMessageEvent);
}
-void MIDIInput::Trace(blink::Visitor* visitor) {
+void MIDIInput::Trace(Visitor* visitor) {
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 284a94dcc5c..f63efbe3770 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
void AddedEventListener(const AtomicString& event_type,
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_message_event.cc b/chromium/third_party/blink/renderer/modules/webmidi/midi_message_event.cc
index cd12cc44f80..1b5853cece8 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_message_event.cc
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_message_event.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/modules/webmidi/midi_message_event.h"
-#include "third_party/blink/renderer/modules/webmidi/midi_message_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_midi_message_event_init.h"
namespace blink {
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 2330e1d0814..fedc10888a5 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(data_);
Event::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_message_event.idl b/chromium/third_party/blink/renderer/modules/webmidi/midi_message_event.idl
index 48c9c68a559..222b4ce8e5e 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_message_event.idl
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_message_event.idl
@@ -31,8 +31,8 @@
// https://webaudio.github.io/web-midi-api/#MIDIMessageEvent
[
- SecureContext,
- Constructor(DOMString type, optional MIDIMessageEventInit eventInitDict)
+ SecureContext
] interface MIDIMessageEvent : Event {
+ constructor(DOMString type, optional MIDIMessageEventInit eventInitDict = {});
readonly attribute Uint8Array data;
};
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 c7e81624acc..fdc3d2f1ff6 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_output.cc
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_output.cc
@@ -98,6 +98,13 @@ class MessageValidator {
: data_(array->Data()), length_(array->lengthAsSizeT()), offset_(0) {}
bool Process(ExceptionState& exception_state, bool sysex_enabled) {
+ // data_ is put into a WTF::Vector eventually, which only has wtf_size_t
+ // space.
+ if (!base::CheckedNumeric<wtf_size_t>(length_).IsValid()) {
+ exception_state.ThrowRangeError(
+ "Data exceeds the maximum supported length");
+ return false;
+ }
while (!IsEndOfData() && AcceptRealTimeMessages()) {
if (!IsStatusByte()) {
exception_state.ThrowTypeError("Running status is not allowed " +
@@ -300,21 +307,22 @@ void MIDIOutput::send(Vector<unsigned> unsigned_data,
}
void MIDIOutput::DidOpen(bool opened) {
- if (!opened) {
+ if (!opened)
pending_data_.clear();
- return;
- }
- while (!pending_data_.empty()) {
- auto& front = pending_data_.front();
- midiAccess()->SendMIDIData(port_index_, front.first->Data(),
- front.first->deprecatedLengthAsUnsigned(),
- front.second);
- pending_data_.TakeFirst();
+ HeapVector<std::pair<Member<DOMUint8Array>, base::TimeTicks>> queued_data;
+ queued_data.swap(pending_data_);
+ for (auto& data : queued_data) {
+ midiAccess()->SendMIDIData(
+ port_index_, data.first->Data(),
+ base::checked_cast<wtf_size_t>(data.first->lengthAsSizeT()),
+ data.second);
}
+ queued_data.clear();
+ DCHECK(pending_data_.IsEmpty());
}
-void MIDIOutput::Trace(blink::Visitor* visitor) {
+void MIDIOutput::Trace(Visitor* visitor) {
MIDIPort::Trace(visitor);
visitor->Trace(pending_data_);
}
@@ -338,8 +346,9 @@ void MIDIOutput::SendInternal(DOMUint8Array* array,
if (IsOpening()) {
pending_data_.emplace_back(array, timestamp);
} else {
- midiAccess()->SendMIDIData(port_index_, array->Data(),
- array->deprecatedLengthAsUnsigned(), timestamp);
+ midiAccess()->SendMIDIData(
+ port_index_, array->Data(),
+ base::checked_cast<wtf_size_t>(array->lengthAsSizeT()), timestamp);
}
}
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 b9fb49b82aa..52dab7b6180 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_output.h
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_output.h
@@ -63,14 +63,14 @@ class MIDIOutput final : public MIDIPort {
void send(NotShared<DOMUint8Array>, ExceptionState&);
void send(Vector<unsigned>, ExceptionState&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void DidOpen(bool opened) override;
void SendInternal(DOMUint8Array*, base::TimeTicks timestamp, ExceptionState&);
unsigned port_index_;
- HeapDeque<std::pair<Member<DOMUint8Array>, base::TimeTicks>> pending_data_;
+ HeapVector<std::pair<Member<DOMUint8Array>, base::TimeTicks>> pending_data_;
};
} // namespace blink
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 1f29329bcf5..35fa5b507d1 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_port.cc
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_port.cc
@@ -51,7 +51,7 @@ MIDIPort::MIDIPort(MIDIAccess* access,
TypeCode type,
const String& version,
PortState state)
- : ContextLifecycleObserver(access->GetExecutionContext()),
+ : ExecutionContextLifecycleObserver(access->GetExecutionContext()),
id_(id),
manufacturer_(manufacturer),
name_(name),
@@ -183,15 +183,15 @@ bool MIDIPort::HasPendingActivity() const {
return connection_ != kConnectionStateClosed;
}
-void MIDIPort::ContextDestroyed(ExecutionContext*) {
+void MIDIPort::ContextDestroyed() {
// Should be "closed" to assume there are no pending activities.
connection_ = kConnectionStateClosed;
}
-void MIDIPort::Trace(blink::Visitor* visitor) {
+void MIDIPort::Trace(Visitor* visitor) {
visitor->Trace(access_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
void MIDIPort::OpenAsynchronously(ScriptPromiseResolver* resolver) {
@@ -200,7 +200,7 @@ void MIDIPort::OpenAsynchronously(ScriptPromiseResolver* resolver) {
if (!GetExecutionContext())
return;
- UseCounter::Count(*To<Document>(GetExecutionContext()),
+ UseCounter::Count(*Document::From(GetExecutionContext()),
WebFeature::kMIDIPortOpen);
DCHECK_NE(0u, running_open_count_);
running_open_count_--;
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 f7c92147e0c..a9c4d65d3ea 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/midi_port.h
+++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_port.h
@@ -35,7 +35,7 @@
#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/core/v8/script_promise_resolver.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#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/platform/heap/handle.h"
@@ -45,7 +45,7 @@ class MIDIAccess;
class MIDIPort : public EventTargetWithInlineData,
public ActiveScriptWrappable<MIDIPort>,
- public ContextLifecycleObserver {
+ public ExecutionContextLifecycleObserver {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(MIDIPort);
@@ -75,7 +75,7 @@ class MIDIPort : public EventTargetWithInlineData,
void SetState(midi::mojom::PortState);
ConnectionState GetConnection() const { return connection_; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange, kStatechange)
@@ -88,8 +88,8 @@ class MIDIPort : public EventTargetWithInlineData,
// ScriptWrappable
bool HasPendingActivity() const final;
- // ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
protected:
MIDIPort(MIDIAccess*,
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 c73a226a188..79f0fea64bf 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(entries_);
ScriptWrappable::Trace(visitor);
}
@@ -77,7 +77,7 @@ class MIDIPortMap : public ScriptWrappable, public Maplike<String, T*> {
return true;
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 a3f757a78bd..36668d96b8a 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
@@ -33,6 +33,7 @@
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.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_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"
@@ -41,7 +42,7 @@
#include "third_party/blink/renderer/core/frame/navigator.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/modules/webmidi/midi_access_initializer.h"
-#include "third_party/blink/renderer/modules/webmidi/midi_options.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/instrumentation/use_counter.h"
@@ -59,7 +60,7 @@ const char kFeaturePolicyConsoleWarning[] =
NavigatorWebMIDI::NavigatorWebMIDI(Navigator& navigator)
: Supplement<Navigator>(navigator) {}
-void NavigatorWebMIDI::Trace(blink::Visitor* visitor) {
+void NavigatorWebMIDI::Trace(Visitor* visitor) {
Supplement<Navigator>::Trace(visitor);
}
@@ -75,23 +76,26 @@ NavigatorWebMIDI& NavigatorWebMIDI::From(Navigator& navigator) {
return *supplement;
}
-ScriptPromise NavigatorWebMIDI::requestMIDIAccess(ScriptState* script_state,
- Navigator& navigator,
- const MIDIOptions* options) {
- return NavigatorWebMIDI::From(navigator).requestMIDIAccess(script_state,
- options);
+ScriptPromise NavigatorWebMIDI::requestMIDIAccess(
+ ScriptState* script_state,
+ Navigator& navigator,
+ const MIDIOptions* options,
+ ExceptionState& exception_state) {
+ return NavigatorWebMIDI::From(navigator).requestMIDIAccess(
+ script_state, options, exception_state);
}
-ScriptPromise NavigatorWebMIDI::requestMIDIAccess(ScriptState* script_state,
- const MIDIOptions* options) {
+ScriptPromise NavigatorWebMIDI::requestMIDIAccess(
+ ScriptState* script_state,
+ const MIDIOptions* options,
+ ExceptionState& exception_state) {
if (!script_state->ContextIsValid()) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError,
- "The frame is not working."));
+ exception_state.ThrowDOMException(DOMExceptionCode::kAbortError,
+ "The frame is not working.");
+ return ScriptPromise();
}
- Document& document = *To<Document>(ExecutionContext::From(script_state));
+ Document& document = *Document::From(ExecutionContext::From(script_state));
if (options->hasSysex() && options->sysex()) {
UseCounter::Count(
document,
@@ -112,14 +116,12 @@ ScriptPromise NavigatorWebMIDI::requestMIDIAccess(ScriptState* script_state,
document.CountUseOnlyInCrossOriginIframe(
WebFeature::kRequestMIDIAccessIframe_ObscuredByFootprinting);
- if (!document.IsFeatureEnabled(mojom::FeaturePolicyFeature::kMidiFeature,
- ReportOptions::kReportOnFailure,
- kFeaturePolicyConsoleWarning)) {
+ if (!document.IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kMidiFeature,
+ ReportOptions::kReportOnFailure, kFeaturePolicyConsoleWarning)) {
UseCounter::Count(document, WebFeature::kMidiDisabledByFeaturePolicy);
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kSecurityError,
- kFeaturePolicyErrorMessage));
+ exception_state.ThrowSecurityError(kFeaturePolicyErrorMessage);
+ return ScriptPromise();
}
return MIDIAccessInitializer::Start(script_state, options);
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 51d1c93207f..e31bd0a6476 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
@@ -32,13 +32,14 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBMIDI_NAVIGATOR_WEB_MIDI_H_
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_midi_options.h"
#include "third_party/blink/renderer/core/frame/navigator.h"
-#include "third_party/blink/renderer/modules/webmidi/midi_options.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/supplementable.h"
namespace blink {
+class ExceptionState;
class Navigator;
class NavigatorWebMIDI final : public GarbageCollected<NavigatorWebMIDI>,
@@ -51,12 +52,15 @@ class NavigatorWebMIDI final : public GarbageCollected<NavigatorWebMIDI>,
static NavigatorWebMIDI& From(Navigator&);
static ScriptPromise requestMIDIAccess(ScriptState*,
Navigator&,
- const MIDIOptions*);
- ScriptPromise requestMIDIAccess(ScriptState*, const MIDIOptions*);
+ const MIDIOptions*,
+ ExceptionState& exception_state);
+ ScriptPromise requestMIDIAccess(ScriptState*,
+ const MIDIOptions*,
+ ExceptionState& exception_state);
explicit NavigatorWebMIDI(Navigator&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.idl b/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.idl
index a569d1e1806..04c8a34865a 100644
--- a/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.idl
+++ b/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.idl
@@ -28,11 +28,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// https://webaudio.github.io/web-midi-api/#requestMIDIAccess
+// https://webaudio.github.io/web-midi-api/#extensions-to-the-navigator-interface
[
ImplementedAs=NavigatorWebMIDI,
SecureContext
] partial interface Navigator {
- [CallWith=ScriptState, MeasureAs=RequestMIDIAccess_ObscuredByFootprinting] Promise<MIDIAccess> requestMIDIAccess(optional MIDIOptions options);
+ [CallWith=ScriptState, RaisesException, MeasureAs=RequestMIDIAccess_ObscuredByFootprinting] Promise<MIDIAccess> requestMIDIAccess(optional MIDIOptions options = {});
};
diff --git a/chromium/third_party/blink/renderer/modules/webrtc/DEPS b/chromium/third_party/blink/renderer/modules/webrtc/DEPS
index 9a092ef586e..d12ed386c0a 100644
--- a/chromium/third_party/blink/renderer/modules/webrtc/DEPS
+++ b/chromium/third_party/blink/renderer/modules/webrtc/DEPS
@@ -5,6 +5,7 @@ include_rules = [
"+media/base/audio_bus.h",
"+media/base/audio_capturer_source.h",
"+media/base/audio_decoder.h",
+ "+media/base/audio_power_monitor.h",
"+media/base/audio_latency.h",
"+media/base/audio_parameters.h",
"+media/base/audio_pull_fifo.h",
diff --git a/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.cc b/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.cc
index cf3a4e5f6a2..e8f6097d4a7 100644
--- a/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.cc
@@ -7,10 +7,12 @@
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
+#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_parameters.h"
#include "media/base/sample_rates.h"
+#include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h"
#include "third_party/blink/renderer/modules/mediastream/processed_local_audio_source.h"
#include "third_party/blink/renderer/modules/webrtc/webrtc_audio_renderer.h"
@@ -19,6 +21,14 @@ using media::ChannelLayout;
namespace blink {
+namespace {
+
+void SendLogMessage(const std::string& message) {
+ blink::WebRtcLogMessage("WRADI::" + message);
+}
+
+} // namespace
+
WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl()
: audio_processing_id_(base::UnguessableToken::Create()),
audio_transport_callback_(nullptr),
@@ -26,7 +36,8 @@ WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl()
initialized_(false),
playing_(false),
recording_(false) {
- DVLOG(1) << "WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl()";
+ SendLogMessage(base::StringPrintf("%s({id=%s})", __func__,
+ GetAudioProcessingId().ToString().c_str()));
// This object can be constructed on either the signaling thread or the main
// thread, so we need to detach these thread checkers here and have them
// initialize automatically when the first methods are called.
@@ -38,7 +49,8 @@ WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl()
}
WebRtcAudioDeviceImpl::~WebRtcAudioDeviceImpl() {
- DVLOG(1) << "WebRtcAudioDeviceImpl::~WebRtcAudioDeviceImpl()";
+ SendLogMessage(base::StringPrintf("%s() [id=%s]", __func__,
+ GetAudioProcessingId().ToString().c_str()));
DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
DCHECK(!initialized_) << "Terminate must have been called.";
}
@@ -128,12 +140,15 @@ void WebRtcAudioDeviceImpl::AudioRendererThreadStopped() {
}
void WebRtcAudioDeviceImpl::SetOutputDeviceForAec(
- const std::string& output_device_id) {
+ const String& output_device_id) {
DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
+ SendLogMessage(base::StringPrintf("%s({output_device_id=%s}) [id=%s]",
+ __func__, output_device_id.Utf8().c_str(),
+ GetAudioProcessingId().ToString().c_str()));
output_device_id_for_aec_ = output_device_id;
base::AutoLock lock(lock_);
for (auto* capturer : capturers_) {
- capturer->SetOutputDeviceForAec(output_device_id);
+ capturer->SetOutputDeviceForAec(output_device_id.Utf8());
}
}
@@ -143,8 +158,9 @@ base::UnguessableToken WebRtcAudioDeviceImpl::GetAudioProcessingId() const {
int32_t WebRtcAudioDeviceImpl::RegisterAudioCallback(
webrtc::AudioTransport* audio_callback) {
- DVLOG(1) << "WebRtcAudioDeviceImpl::RegisterAudioCallback()";
DCHECK_CALLED_ON_VALID_THREAD(signaling_thread_checker_);
+ SendLogMessage(base::StringPrintf("%s() [id=%s]", __func__,
+ GetAudioProcessingId().ToString().c_str()));
base::AutoLock lock(lock_);
DCHECK_EQ(!audio_transport_callback_, !!audio_callback);
audio_transport_callback_ = audio_callback;
@@ -254,9 +270,10 @@ bool WebRtcAudioDeviceImpl::Playing() const {
}
int32_t WebRtcAudioDeviceImpl::StartRecording() {
- DVLOG(1) << "WebRtcAudioDeviceImpl::StartRecording()";
DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_);
DCHECK(initialized_);
+ SendLogMessage(base::StringPrintf("%s() [id=%s]", __func__,
+ GetAudioProcessingId().ToString().c_str()));
base::AutoLock auto_lock(lock_);
if (!audio_transport_callback_) {
LOG(ERROR) << "Audio transport is missing";
@@ -269,7 +286,6 @@ int32_t WebRtcAudioDeviceImpl::StartRecording() {
}
int32_t WebRtcAudioDeviceImpl::StopRecording() {
- DVLOG(1) << "WebRtcAudioDeviceImpl::StopRecording()";
DCHECK(initialized_);
// Can be called both from the worker thread (e.g. when called from webrtc)
// or the signaling thread (e.g. when we call it ourselves internally).
@@ -279,6 +295,8 @@ int32_t WebRtcAudioDeviceImpl::StopRecording() {
DCHECK(signaling_thread_checker_.CalledOnValidThread() ||
worker_thread_checker_.CalledOnValidThread());
#endif
+ SendLogMessage(base::StringPrintf("%s() [id=%s]", __func__,
+ GetAudioProcessingId().ToString().c_str()));
base::AutoLock auto_lock(lock_);
recording_ = false;
return 0;
@@ -379,20 +397,22 @@ bool WebRtcAudioDeviceImpl::SetAudioRenderer(
void WebRtcAudioDeviceImpl::AddAudioCapturer(
ProcessedLocalAudioSource* capturer) {
DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
- DVLOG(1) << "WebRtcAudioDeviceImpl::AddAudioCapturer()";
+ SendLogMessage(base::StringPrintf("%s() [id=%s]", __func__,
+ GetAudioProcessingId().ToString().c_str()));
DCHECK(capturer);
DCHECK(!capturer->device().id.empty());
base::AutoLock auto_lock(lock_);
DCHECK(!base::Contains(capturers_, capturer));
capturers_.push_back(capturer);
- capturer->SetOutputDeviceForAec(output_device_id_for_aec_);
+ capturer->SetOutputDeviceForAec(output_device_id_for_aec_.Utf8());
}
void WebRtcAudioDeviceImpl::RemoveAudioCapturer(
ProcessedLocalAudioSource* capturer) {
DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_);
- DVLOG(1) << "WebRtcAudioDeviceImpl::RemoveAudioCapturer()";
+ SendLogMessage(base::StringPrintf("%s() [id=%s]", __func__,
+ GetAudioProcessingId().ToString().c_str()));
DCHECK(capturer);
base::AutoLock auto_lock(lock_);
capturers_.remove(capturer);
diff --git a/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.h b/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.h
index bc78b6aa901..be3b358e9f7 100644
--- a/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.h
+++ b/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.h
@@ -10,7 +10,6 @@
#include <list>
#include <memory>
#include <string>
-#include <vector>
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
@@ -19,6 +18,7 @@
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/webrtc/webrtc_audio_device_not_impl.h"
#include "third_party/blink/renderer/platform/webrtc/webrtc_source.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
// A WebRtcAudioDeviceImpl instance implements the abstract interface
// webrtc::AudioDeviceModule which makes it possible for a user (e.g. webrtc::
@@ -133,7 +133,7 @@ class MODULES_EXPORT WebRtcAudioDeviceImpl
// Called on the main render thread.
void RemoveAudioRenderer(blink::WebRtcAudioRenderer* renderer) override;
void AudioRendererThreadStopped() override;
- void SetOutputDeviceForAec(const std::string& output_device_id) override;
+ void SetOutputDeviceForAec(const String& output_device_id) override;
base::UnguessableToken GetAudioProcessingId() const override;
// blink::WebRtcPlayoutDataSource implementation.
@@ -187,14 +187,10 @@ class MODULES_EXPORT WebRtcAudioDeviceImpl
// Buffer used for temporary storage during render callback.
// It is only accessed by the audio render thread.
- //
- // TODO(crbug.com/923394): Replace std::vector by WTF::Vector.
- std::vector<int16_t> render_buffer_;
+ Vector<int16_t> render_buffer_;
// The output device used for echo cancellation
- //
- // TODO(crbug.com/923394): Replace std::string by WTF::String.
- std::string output_device_id_for_aec_;
+ String output_device_id_for_aec_;
DISALLOW_COPY_AND_ASSIGN(WebRtcAudioDeviceImpl);
};
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 37ccb760d95..ad23ef64a65 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
@@ -17,15 +17,17 @@
#include "media/base/audio_latency.h"
#include "media/base/audio_parameters.h"
#include "media/base/sample_rates.h"
-#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.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/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"
+#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/webrtc/api/media_stream_interface.h"
namespace WTF {
@@ -47,10 +49,45 @@ namespace {
const media::AudioParameters::Format kFormat =
media::AudioParameters::AUDIO_PCM_LOW_LATENCY;
+// Time constant for AudioPowerMonitor. See See AudioPowerMonitor ctor comments
+// for details.
+constexpr base::TimeDelta kPowerMeasurementTimeConstant =
+ base::TimeDelta::FromMilliseconds(10);
+
+// Time in seconds between two successive measurements of audio power levels.
+constexpr base::TimeDelta kPowerMonitorLogInterval =
+ base::TimeDelta::FromSeconds(15);
+
// Used for UMA histograms.
const int kRenderTimeHistogramMinMicroseconds = 100;
const int kRenderTimeHistogramMaxMicroseconds = 1 * 1000 * 1000; // 1 second
+const char* OutputDeviceStatusToString(media::OutputDeviceStatus status) {
+ switch (status) {
+ case media::OUTPUT_DEVICE_STATUS_OK:
+ return "OK";
+ case media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND:
+ return "ERROR_NOT_FOUND";
+ case media::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED:
+ return "ERROR_NOT_AUTHORIZED";
+ case media::OUTPUT_DEVICE_STATUS_ERROR_TIMED_OUT:
+ return "ERROR_TIMED_OUT";
+ case media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL:
+ return "ERROR_INTERNAL";
+ }
+}
+
+const char* StateToString(WebRtcAudioRenderer::State state) {
+ switch (state) {
+ case WebRtcAudioRenderer::UNINITIALIZED:
+ return "UNINITIALIZED";
+ case WebRtcAudioRenderer::PLAYING:
+ return "PLAYING";
+ case WebRtcAudioRenderer::PAUSED:
+ return "PAUSED";
+ }
+}
+
// This is a simple wrapper class that's handed out to users of a shared
// WebRtcAudioRenderer instance. This class maintains the per-user 'playing'
// and 'started' states to avoid problems related to incorrect usage which
@@ -178,25 +215,109 @@ class WebRtcAudioRenderer::InternalFrame {
WeakPersistent<LocalFrame> frame_;
};
+WebRtcAudioRenderer::AudioStreamTracker::AudioStreamTracker(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ WebRtcAudioRenderer* renderer,
+ int sample_rate)
+ : task_runner_(std::move(task_runner)),
+ renderer_(renderer),
+ start_time_(base::TimeTicks::Now()),
+ render_callbacks_started_(false),
+ check_alive_timer_(task_runner_,
+ this,
+ &WebRtcAudioRenderer::AudioStreamTracker::CheckAlive),
+ power_monitor_(sample_rate, kPowerMeasurementTimeConstant),
+ last_audio_level_log_time_(base::TimeTicks::Now()) {
+ weak_this_ = weak_factory_.GetWeakPtr();
+ // CheckAlive() will look to see if |render_callbacks_started_| is true
+ // after the timeout expires and log this. If the stream is paused/closed
+ // before the timer fires, a warning is logged instead.
+ check_alive_timer_.StartOneShot(base::TimeDelta::FromSeconds(5), FROM_HERE);
+}
+
+WebRtcAudioRenderer::AudioStreamTracker::~AudioStreamTracker() {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ DCHECK(renderer_);
+ const auto duration = base::TimeTicks::Now() - start_time_;
+ renderer_->SendLogMessage(
+ String::Format("%s => (media stream duration=%" PRId64 " seconds)",
+ __func__, duration.InSeconds()));
+}
+
+void WebRtcAudioRenderer::AudioStreamTracker::OnRenderCallbackCalled() {
+ DCHECK(renderer_->CurrentThreadIsRenderingThread());
+ // Indicate that render callbacks has started as expected and within a
+ // reasonable time. Since this thread is the only writer of
+ // |render_callbacks_started_| once the thread starts, it's safe to compare
+ // and then change the state once.
+ if (!render_callbacks_started_)
+ render_callbacks_started_ = true;
+}
+
+void WebRtcAudioRenderer::AudioStreamTracker::MeasurePower(
+ const media::AudioBus& buffer,
+ int frames) {
+ DCHECK(renderer_->CurrentThreadIsRenderingThread());
+ // Update the average power estimate on the rendering thread to avoid posting
+ // a task which also has to copy the audio bus. According to comments in
+ // AudioPowerMonitor::Scan(), it should be safe. Note that, we only check the
+ // power once every ten seconds (on the |task_runner_| thread) and the result
+ // is only used for logging purposes.
+ power_monitor_.Scan(buffer, frames);
+ const auto now = base::TimeTicks::Now();
+ if ((now - last_audio_level_log_time_) > kPowerMonitorLogInterval) {
+ // Log the current audio level but avoid using the render thread to reduce
+ // its load and to ensure that |power_monitor_| is mainly accessed on one
+ // thread. |weak_ptr_factory_| ensures that the task is canceled when
+ // |this| is destroyed since we can't guarantee that |this| outlives the
+ // task.
+ PostCrossThreadTask(
+ *task_runner_, FROM_HERE,
+ CrossThreadBindOnce(&AudioStreamTracker::LogAudioPowerLevel,
+ weak_this_));
+ last_audio_level_log_time_ = now;
+ }
+}
+
+void WebRtcAudioRenderer::AudioStreamTracker::LogAudioPowerLevel() {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ std::pair<float, bool> power_and_clip =
+ power_monitor_.ReadCurrentPowerAndClip();
+ renderer_->SendLogMessage(String::Format(
+ "%s => (average audio level=%.2f dBFS)", __func__, power_and_clip.first));
+}
+
+void WebRtcAudioRenderer::AudioStreamTracker::CheckAlive(TimerBase*) {
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ DCHECK(renderer_);
+ renderer_->SendLogMessage(String::Format(
+ "%s => (%s)", __func__,
+ render_callbacks_started_ ? "stream is alive"
+ : "WARNING: stream is not alive"));
+}
+
WebRtcAudioRenderer::WebRtcAudioRenderer(
const scoped_refptr<base::SingleThreadTaskRunner>& signaling_thread,
const WebMediaStream& media_stream,
WebLocalFrame* web_frame,
const base::UnguessableToken& session_id,
const std::string& device_id)
- : state_(UNINITIALIZED),
+ : task_runner_(Thread::Current()->GetTaskRunner()),
+ state_(UNINITIALIZED),
source_internal_frame_(std::make_unique<InternalFrame>(web_frame)),
session_id_(session_id),
signaling_thread_(signaling_thread),
media_stream_(media_stream),
+ media_stream_id_(media_stream_.Id().Utf8()),
source_(nullptr),
play_ref_count_(0),
start_ref_count_(0),
sink_params_(kFormat, media::CHANNEL_LAYOUT_STEREO, 0, 0),
output_device_id_(device_id) {
- WebRtcLogMessage(base::StringPrintf("WAR::WAR. session_id=%s, effects=%i",
- session_id.ToString().c_str(),
- sink_params_.effects()));
+ SendLogMessage(
+ String::Format("%s({session_id=%s}, {device_id=%s})", __func__,
+ session_id.is_empty() ? "" : session_id.ToString().c_str(),
+ device_id.c_str()));
}
WebRtcAudioRenderer::~WebRtcAudioRenderer() {
@@ -205,16 +326,16 @@ WebRtcAudioRenderer::~WebRtcAudioRenderer() {
}
bool WebRtcAudioRenderer::Initialize(WebRtcAudioRendererSource* source) {
- DVLOG(1) << "WebRtcAudioRenderer::Initialize()";
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(source);
DCHECK(!sink_.get());
- // DCHECK_GE(session_id_, 0);
{
base::AutoLock auto_lock(lock_);
DCHECK_EQ(state_, UNINITIALIZED);
DCHECK(!source_);
}
+ SendLogMessage(
+ String::Format("%s([state=%s])", __func__, StateToString(state_)));
media::AudioSinkParameters sink_params(session_id_, output_device_id_);
sink_params.processing_id = source->GetAudioProcessingId();
@@ -226,22 +347,26 @@ bool WebRtcAudioRenderer::Initialize(WebRtcAudioRendererSource* source) {
sink_->GetOutputDeviceInfo().device_status();
UMA_HISTOGRAM_ENUMERATION("Media.Audio.WebRTCAudioRenderer.DeviceStatus",
sink_status, media::OUTPUT_DEVICE_STATUS_MAX + 1);
+ SendLogMessage(String::Format("%s => (sink device_status=%s)", __func__,
+ OutputDeviceStatusToString(sink_status)));
if (sink_status != media::OUTPUT_DEVICE_STATUS_OK) {
+ SendLogMessage(String::Format("%s => (ERROR: invalid output device status)",
+ __func__));
sink_->Stop();
return false;
}
PrepareSink();
{
- // No need to reassert the preconditions because the other thread accessing
- // the fields only reads them.
+ // No need to reassert the preconditions because the other thread
+ // accessing the fields only reads them.
base::AutoLock auto_lock(lock_);
source_ = source;
// User must call Play() before any audio can be heard.
state_ = PAUSED;
}
- source_->SetOutputDeviceForAec(output_device_id_);
+ source_->SetOutputDeviceForAec(String::FromUTF8(output_device_id_));
sink_->Start();
sink_->Play(); // Not all the sinks play on start.
@@ -272,15 +397,16 @@ bool WebRtcAudioRenderer::CurrentThreadIsRenderingThread() {
}
void WebRtcAudioRenderer::Start() {
- DVLOG(1) << "WebRtcAudioRenderer::Start()";
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ SendLogMessage(
+ String::Format("%s([state=%s])", __func__, StateToString(state_)));
++start_ref_count_;
}
void WebRtcAudioRenderer::Play() {
- DVLOG(1) << "WebRtcAudioRenderer::Play()";
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
+ SendLogMessage(
+ String::Format("%s([state=%s])", __func__, StateToString(state_)));
if (playing_state_.playing())
return;
@@ -293,6 +419,8 @@ void WebRtcAudioRenderer::EnterPlayState() {
DVLOG(1) << "WebRtcAudioRenderer::EnterPlayState()";
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK_GT(start_ref_count_, 0) << "Did you forget to call Start()?";
+ SendLogMessage(
+ String::Format("%s([state=%s])", __func__, StateToString(state_)));
base::AutoLock auto_lock(lock_);
if (state_ == UNINITIALIZED)
return;
@@ -303,16 +431,22 @@ void WebRtcAudioRenderer::EnterPlayState() {
if (state_ != PLAYING) {
state_ = PLAYING;
+ audio_stream_tracker_.emplace(task_runner_, this,
+ sink_params_.sample_rate());
+
if (audio_fifo_) {
audio_delay_ = base::TimeDelta();
audio_fifo_->Clear();
}
}
+ SendLogMessage(
+ String::Format("%s => (state=%s)", __func__, StateToString(state_)));
}
void WebRtcAudioRenderer::Pause() {
- DVLOG(1) << "WebRtcAudioRenderer::Pause()";
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ SendLogMessage(
+ String::Format("%s([state=%s])", __func__, StateToString(state_)));
if (!playing_state_.playing())
return;
@@ -322,9 +456,10 @@ void WebRtcAudioRenderer::Pause() {
}
void WebRtcAudioRenderer::EnterPauseState() {
- DVLOG(1) << "WebRtcAudioRenderer::EnterPauseState()";
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK_GT(start_ref_count_, 0) << "Did you forget to call Start()?";
+ SendLogMessage(
+ String::Format("%s([state=%s])", __func__, StateToString(state_)));
base::AutoLock auto_lock(lock_);
if (state_ == UNINITIALIZED)
return;
@@ -333,12 +468,15 @@ void WebRtcAudioRenderer::EnterPauseState() {
DCHECK_GT(play_ref_count_, 0);
if (!--play_ref_count_)
state_ = PAUSED;
+ SendLogMessage(
+ String::Format("%s => (state=%s)", __func__, StateToString(state_)));
}
void WebRtcAudioRenderer::Stop() {
- DVLOG(1) << "WebRtcAudioRenderer::Stop()";
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
{
+ SendLogMessage(
+ String::Format("%s([state=%s])", __func__, StateToString(state_)));
base::AutoLock auto_lock(lock_);
if (state_ == UNINITIALIZED)
return;
@@ -346,8 +484,7 @@ void WebRtcAudioRenderer::Stop() {
if (--start_ref_count_)
return;
- DVLOG(1) << "Calling RemoveAudioRenderer and Stop().";
-
+ audio_stream_tracker_.reset();
source_->RemoveAudioRenderer(this);
source_ = nullptr;
state_ = UNINITIALIZED;
@@ -363,6 +500,8 @@ void WebRtcAudioRenderer::Stop() {
static_cast<int>(max_render_time_.InMicroseconds()),
kRenderTimeHistogramMinMicroseconds,
kRenderTimeHistogramMaxMicroseconds, 50);
+ SendLogMessage(String::Format("%s => (max_render_time=%.3f ms)", __func__,
+ max_render_time_.InMillisecondsF()));
max_render_time_ = base::TimeDelta();
}
@@ -393,9 +532,12 @@ bool WebRtcAudioRenderer::IsLocalRenderer() {
void WebRtcAudioRenderer::SwitchOutputDevice(
const std::string& device_id,
media::OutputDeviceStatusCB callback) {
- DVLOG(1) << "WebRtcAudioRenderer::SwitchOutputDevice()";
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ SendLogMessage(String::Format("%s({device_id=%s} [state=%s])", __func__,
+ device_id.c_str(), StateToString(state_)));
if (!source_) {
+ SendLogMessage(String::Format(
+ "%s => (ERROR: OUTPUT_DEVICE_STATUS_ERROR_INTERNAL)", __func__));
std::move(callback).Run(media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL);
return;
}
@@ -416,8 +558,12 @@ void WebRtcAudioRenderer::SwitchOutputDevice(
UMA_HISTOGRAM_ENUMERATION(
"Media.Audio.WebRTCAudioRenderer.SwitchDeviceStatus", status,
media::OUTPUT_DEVICE_STATUS_MAX + 1);
+ SendLogMessage(String::Format("%s => (sink device_status=%s)", __func__,
+ OutputDeviceStatusToString(status)));
if (status != media::OUTPUT_DEVICE_STATUS_OK) {
+ SendLogMessage(
+ String::Format("%s => (ERROR: invalid sink device status)", __func__));
new_sink->Stop();
std::move(callback).Run(status);
return;
@@ -433,7 +579,7 @@ void WebRtcAudioRenderer::SwitchOutputDevice(
base::AutoLock auto_lock(lock_);
source_->AudioRendererThreadStopped();
}
- source_->SetOutputDeviceForAec(output_device_id_);
+ source_->SetOutputDeviceForAec(String::FromUTF8(output_device_id_));
PrepareSink();
sink_->Start();
sink_->Play(); // Not all the sinks play on start.
@@ -451,9 +597,6 @@ int WebRtcAudioRenderer::Render(base::TimeDelta delay,
if (!source_)
return 0;
- DVLOG(2) << "WebRtcAudioRenderer::Render()";
- DVLOG(2) << "audio_delay: " << delay;
-
audio_delay_ = delay;
// If there are skipped frames, pull and throw away the same amount. We always
@@ -483,6 +626,12 @@ int WebRtcAudioRenderer::Render(base::TimeDelta delay,
else
SourceCallback(0, audio_bus);
+ if (state_ == PLAYING && audio_stream_tracker_) {
+ // Mark the stream as alive the first time this method is called.
+ audio_stream_tracker_->OnRenderCallbackCalled();
+ audio_stream_tracker_->MeasurePower(*audio_bus, audio_bus->frames());
+ }
+
return (state_ == PLAYING) ? audio_bus->frames() : 0;
}
@@ -496,7 +645,7 @@ void WebRtcAudioRenderer::SourceCallback(int fifo_frame_delay,
media::AudioBus* audio_bus) {
DCHECK(sink_->CurrentThreadIsRenderingThread());
base::TimeTicks start_time = base::TimeTicks::Now();
- DVLOG(2) << "WebRtcAudioRenderer::SourceCallback(" << fifo_frame_delay << ", "
+ DVLOG(2) << "WRAR::SourceCallback(" << fifo_frame_delay << ", "
<< audio_bus->channels() << ", " << audio_bus->frames() << ")";
int output_delay_milliseconds =
@@ -556,7 +705,8 @@ void WebRtcAudioRenderer::UpdateSourceVolume(
if (volume > 10.0f)
volume = 10.0f;
- DVLOG(1) << "Setting remote source volume: " << volume;
+ SendLogMessage(String::Format("%s => (source volume changed to %.2f)",
+ __func__, volume));
if (!signaling_thread_->BelongsToCurrentThread()) {
// Libjingle hands out proxy objects in most cases, but the audio source
// object is an exception (bug?). So, to work around that, we need to make
@@ -655,7 +805,6 @@ void WebRtcAudioRenderer::OnPlayStateRemoved(PlayingState* state) {
}
void WebRtcAudioRenderer::PrepareSink() {
- DVLOG(1) << "WebRtcAudioRenderer::PrepareSink()";
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
media::AudioParameters new_sink_params;
{
@@ -665,20 +814,22 @@ void WebRtcAudioRenderer::PrepareSink() {
const media::OutputDeviceInfo& device_info = sink_->GetOutputDeviceInfo();
DCHECK_EQ(device_info.device_status(), media::OUTPUT_DEVICE_STATUS_OK);
- DVLOG(1) << "Sink parameters: " << sink_params_.AsHumanReadableString();
- DVLOG(1) << "Hardware parameters: "
- << device_info.output_params().AsHumanReadableString();
+ SendLogMessage(String::Format(
+ "%s => (hardware parameters=[%s])", __func__,
+ device_info.output_params().AsHumanReadableString().c_str()));
- // WebRTC does not yet support higher rates than 96000 on the client side
+ // WebRTC does not yet support higher rates than 192000 on the client side
// and 48000 is the preferred sample rate. Therefore, if 192000 is detected,
// we change the rate to 48000 instead. The consequence is that the native
// layer will be opened up at 192kHz but WebRTC will provide data at 48kHz
// which will then be resampled by the audio converted on the browser side
// to match the native audio layer.
int sample_rate = device_info.output_params().sample_rate();
- DVLOG(1) << "Audio output hardware sample rate: " << sample_rate;
if (sample_rate >= 192000) {
- DVLOG(1) << "Resampling from 48000 to " << sample_rate << " is required";
+ SendLogMessage(
+ String::Format("%s => (WARNING: WebRTC provides audio at 48kHz and "
+ "resampling takes place to match %dHz)",
+ __func__, sample_rate));
sample_rate = 48000;
}
media::AudioSampleRate asr;
@@ -694,7 +845,8 @@ void WebRtcAudioRenderer::PrepareSink() {
// use 10 ms of data since the WebRTC client only supports multiples of 10 ms
// as buffer size where 10 ms is preferred for lowest possible delay.
const int source_frames_per_buffer = (sample_rate / 100);
- DVLOG(1) << "Using WebRTC output buffer size: " << source_frames_per_buffer;
+ SendLogMessage(String::Format("%s => (source_frames_per_buffer=%d)", __func__,
+ source_frames_per_buffer));
// Setup sink parameters using same channel configuration as the source.
// This sink is an AudioRendererSink which is implemented by an
@@ -708,7 +860,8 @@ void WebRtcAudioRenderer::PrepareSink() {
// WebRTC does not support channel remixing for more than 8 channels (7.1).
// This is an attempt to "support" more than 8 channels by falling back to
// stereo instead. See crbug.com/1003735.
- LOG(WARNING) << "Falling back to stereo sink";
+ SendLogMessage(
+ String::Format("%s => (WARNING: sink falls back to stereo)", __func__));
channels = 2;
channel_layout = media::CHANNEL_LAYOUT_STEREO;
}
@@ -719,7 +872,6 @@ void WebRtcAudioRenderer::PrepareSink() {
if (channel_layout == media::CHANNEL_LAYOUT_DISCRETE) {
new_sink_params.set_channels_for_discrete(channels);
}
- DVLOG(1) << new_sink_params.AsHumanReadableString();
DCHECK(new_sink_params.IsValid());
// Create a FIFO if re-buffering is required to match the source input with
@@ -728,8 +880,9 @@ void WebRtcAudioRenderer::PrepareSink() {
const bool different_source_sink_frames =
source_frames_per_buffer != new_sink_params.frames_per_buffer();
if (different_source_sink_frames) {
- DVLOG(1) << "Rebuffering from " << source_frames_per_buffer << " to "
- << new_sink_params.frames_per_buffer();
+ SendLogMessage(String::Format("%s => (INFO: rebuffering from %d to %d)",
+ __func__, source_frames_per_buffer,
+ new_sink_params.frames_per_buffer()));
}
{
base::AutoLock lock(lock_);
@@ -743,7 +896,9 @@ void WebRtcAudioRenderer::PrepareSink() {
CrossThreadUnretained(this))));
}
sink_params_ = new_sink_params;
- DVLOG(1) << "New sink parameters: " << sink_params_.AsHumanReadableString();
+ SendLogMessage(
+ String::Format("%s => (sink_params=[%s])", __func__,
+ sink_params_.AsHumanReadableString().c_str()));
}
// Specify the latency info to be passed to the browser side.
@@ -753,4 +908,10 @@ void WebRtcAudioRenderer::PrepareSink() {
sink_->Initialize(new_sink_params, this);
}
+void WebRtcAudioRenderer::SendLogMessage(const WTF::String& message) {
+ WebRtcLogMessage(String::Format("WRAR::%s [label=%s]", message.Utf8().c_str(),
+ media_stream_id_.c_str())
+ .Utf8());
+}
+
} // 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 d9ab184294d..ba7df5b2ece 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
@@ -7,6 +7,7 @@
#include <stdint.h>
+#include <atomic>
#include <map>
#include <memory>
#include <string>
@@ -14,19 +15,25 @@
#include "base/macros.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 "base/synchronization/lock.h"
#include "base/threading/thread_checker.h"
+#include "base/time/time.h"
#include "base/unguessable_token.h"
#include "media/base/audio_decoder.h"
+#include "media/base/audio_power_monitor.h"
#include "media/base/audio_pull_fifo.h"
#include "media/base/audio_renderer_sink.h"
#include "media/base/channel_layout.h"
#include "third_party/blink/public/platform/modules/mediastream/web_media_stream_audio_renderer.h"
#include "third_party/blink/public/platform/web_media_stream.h"
#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/webrtc/webrtc_source.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace webrtc {
class AudioSourceInterface;
@@ -81,6 +88,12 @@ class MODULES_EXPORT WebRtcAudioRenderer
SEQUENCE_CHECKER(sequence_checker_);
};
+ enum State {
+ UNINITIALIZED,
+ PLAYING,
+ PAUSED,
+ };
+
WebRtcAudioRenderer(
const scoped_refptr<base::SingleThreadTaskRunner>& signaling_thread,
const blink::WebMediaStream& media_stream,
@@ -130,6 +143,76 @@ class MODULES_EXPORT WebRtcAudioRenderer
void SwitchOutputDevice(const std::string& device_id,
media::OutputDeviceStatusCB callback) override;
+ // Private utility class which keeps track of the state and duration of
+ // playing (rendered on an HTML5 audio tag) audio streams. Mainly intended
+ // for logging purposes to track down "can't hear" type of issues.
+ class AudioStreamTracker {
+ public:
+ // The internal on-shot timer will use the same |task_runner| as the outer
+ // class (OC) who creates this object. |renderer| must outlive the
+ // AudioStreamTracker. See comments for |AudioStreamTracker::renderer_| why
+ // it is safe to use a raw pointer here. |sample_rate| is the current sample
+ // rate used by the audio sink (see WebRtcAudioRenderer::sink_params_).
+ explicit AudioStreamTracker(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ WebRtcAudioRenderer* renderer,
+ int sample_rate);
+
+ // Note: the destructor takes care of logging of the duration of the stream.
+ ~AudioStreamTracker();
+
+ // This function should be called from the audio device callback thread,
+ // i.e., the so-called render thread.
+ void OnRenderCallbackCalled();
+
+ // Scans the provided audio samples and updates a power measurement. The
+ // "average power" is a running average calculated by using a first-order
+ // low-pass filter over the square of the samples scanned.
+ // Called from the audio render thread and it is safe. See comments in
+ // AudioPowerMonitor::Scan() for more details.
+ void MeasurePower(const media::AudioBus& buffer, int frames);
+
+ private:
+ // Called by the timer when it fires once after a delay of ~5 seconds from
+ // start. Reads the state of atomic |render_callbacks_started_|.
+ void CheckAlive(TimerBase*);
+
+ void LogAudioPowerLevel();
+
+ // Task runner of outer class (the creating WebRtcAudioRenderer).
+ const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+
+ // Using a raw pointer is safe since the OC instance will outlive this
+ // object.
+ WebRtcAudioRenderer* const renderer_;
+
+ // Stores when the timer starts. Used to calculate the stream duration.
+ const base::TimeTicks start_time_;
+
+ // Set to true in first render callback by the high-priority audio thread.
+ // Use an atomic variable since it can also be read by the outer class (OC)
+ // thread once to verify that callbacks started as intended. See comments
+ // for CheckAlive().
+ std::atomic_bool render_callbacks_started_;
+
+ // One-shot timer that fires ~5 seconds after rendering should start and
+ // calls the calls CheckAlive() which checks if |render_callbacks_started_|
+ // has been set to true or not. A message is logged to track this state.
+ // The timer uses the same task runner as the OC. Hence, the only writer of
+ // |render_callbacks_started_| is the render thread and the only reader is
+ // the OC thread. DCHECKs are used to confirm this.
+ TaskRunnerTimer<AudioStreamTracker> check_alive_timer_;
+
+ // Scans audio samples from Render() as input to compute power levels.
+ media::AudioPowerMonitor power_monitor_;
+
+ // Updated each time a power measurement is logged.
+ base::TimeTicks last_audio_level_log_time_;
+
+ base::WeakPtr<AudioStreamTracker> weak_this_;
+ base::WeakPtrFactory<AudioStreamTracker> weak_factory_{this};
+ };
+
// Called when an audio renderer, either the main or a proxy, starts playing.
// Here we maintain a reference count of how many renderers are currently
// playing so that the shared play state of all the streams can be reflected
@@ -144,12 +227,6 @@ class MODULES_EXPORT WebRtcAudioRenderer
~WebRtcAudioRenderer() override;
private:
- enum State {
- UNINITIALIZED,
- PLAYING,
- PAUSED,
- };
-
// Holds raw pointers to PlaingState objects. Ownership is managed outside
// of this type.
typedef std::vector<PlayingState*> PlayingStates;
@@ -161,6 +238,9 @@ class MODULES_EXPORT WebRtcAudioRenderer
// Used to DCHECK that we are called on the correct thread.
THREAD_CHECKER(thread_checker_);
+ // Task runner of the creating thread.
+ const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+
// Flag to keep track the state of the renderer.
State state_;
@@ -206,6 +286,8 @@ class MODULES_EXPORT WebRtcAudioRenderer
// |sink_|.
void PrepareSink();
+ void SendLogMessage(const WTF::String& message);
+
// The WebLocalFrame in which the audio is rendered into |sink_|.
//
// TODO(crbug.com/704136): Replace |source_internal_frame_| with regular
@@ -223,6 +305,12 @@ class MODULES_EXPORT WebRtcAudioRenderer
// The media stream that holds the audio tracks that this renderer renders.
const blink::WebMediaStream media_stream_;
+ // Contains a copy the unique id of the media stream. By taking a copy at
+ // construction, we can convert the id from a WebString to an std::string
+ // once and that saves resources when |media_stream_id_| is added to log
+ // messages.
+ std::string media_stream_id_;
+
// Audio data source from the browser process.
//
// TODO(crbug.com/704136): Make it a Member.
@@ -230,7 +318,8 @@ class MODULES_EXPORT WebRtcAudioRenderer
// Protects access to |state_|, |source_|, |audio_fifo_|,
// |audio_delay_milliseconds_|, |fifo_delay_milliseconds_|, |current_time_|,
- // |sink_params_|, |render_callback_count_| and |max_render_time_|.
+ // |sink_params_|, |render_callback_count_|, |max_render_time_| and
+ // |audio_stream_tracker_|.
mutable base::Lock lock_;
// Ref count for the MediaPlayers which are playing audio.
@@ -270,6 +359,11 @@ class MODULES_EXPORT WebRtcAudioRenderer
// for logging UMA data. Logged and reset when Stop() is called.
base::TimeDelta max_render_time_;
+ // Used for keeping track of and logging stats for playing audio streams.
+ // Created when a stream starts and destroyed when a stream stops.
+ // See comments for AudioStreamTracker for more details.
+ base::Optional<AudioStreamTracker> audio_stream_tracker_;
+
DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioRenderer);
};
diff --git a/chromium/third_party/blink/renderer/modules/webshare/idls.gni b/chromium/third_party/blink/renderer/modules/webshare/idls.gni
new file mode 100644
index 00000000000..65bdfe7b38b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webshare/idls.gni
@@ -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.
+
+modules_dictionary_idl_files = [ "share_data.idl" ]
+
+modules_dependency_idl_files = [ "navigator_share.idl" ]
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 ac930802c90..005b58530ab 100644
--- a/chromium/third_party/blink/renderer/modules/webshare/navigator_share.cc
+++ b/chromium/third_party/blink/renderer/modules/webshare/navigator_share.cc
@@ -9,6 +9,7 @@
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_share_data.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"
@@ -16,11 +17,12 @@
#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/web_feature.h"
-#include "third_party/blink/renderer/modules/webshare/share_data.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.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/mojo/mojo_helper.h"
+#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
namespace blink {
@@ -63,7 +65,7 @@ bool HasFiles(const ShareData& share_data) {
String CheckForTypeError(const Document& doc,
const ShareData& share_data,
KURL* full_url) {
- if (!share_data.hasTitle() && !share_data.hasText() && !share_data.hasURL() &&
+ 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 "
@@ -89,7 +91,7 @@ class NavigatorShare::ShareClientImpl final
void OnConnectionError();
- void Trace(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
visitor->Trace(navigator_);
visitor->Trace(resolver_);
}
@@ -98,13 +100,23 @@ class NavigatorShare::ShareClientImpl final
WeakMember<NavigatorShare> navigator_;
bool has_files_;
Member<ScriptPromiseResolver> resolver_;
+ FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle
+ feature_handle_for_scheduler_;
};
NavigatorShare::ShareClientImpl::ShareClientImpl(
NavigatorShare* navigator_share,
bool has_files,
ScriptPromiseResolver* resolver)
- : navigator_(navigator_share), has_files_(has_files), resolver_(resolver) {}
+ : navigator_(navigator_share),
+ has_files_(has_files),
+ resolver_(resolver),
+ feature_handle_for_scheduler_(
+ ExecutionContext::From(resolver_->GetScriptState())
+ ->GetScheduler()
+ ->RegisterFeature(
+ SchedulingPolicy::Feature::kWebShare,
+ {SchedulingPolicy::RecordMetricsForBackForwardCache()})) {}
void NavigatorShare::ShareClientImpl::Callback(mojom::blink::ShareError error) {
if (navigator_)
@@ -147,7 +159,7 @@ NavigatorShare& NavigatorShare::From(Navigator& navigator) {
return *supplement;
}
-void NavigatorShare::Trace(blink::Visitor* visitor) {
+void NavigatorShare::Trace(Visitor* visitor) {
visitor->Trace(clients_);
Supplement<Navigator>::Trace(visitor);
}
@@ -158,7 +170,7 @@ const char NavigatorShare::kSupplementName[] = "NavigatorShare";
bool NavigatorShare::canShare(ScriptState* script_state,
const ShareData* share_data) {
- Document* doc = To<Document>(ExecutionContext::From(script_state));
+ Document* doc = Document::From(ExecutionContext::From(script_state));
KURL full_url;
return CheckForTypeError(*doc, *share_data, &full_url).IsEmpty();
}
@@ -170,31 +182,31 @@ bool NavigatorShare::canShare(ScriptState* script_state,
}
ScriptPromise NavigatorShare::share(ScriptState* script_state,
- const ShareData* share_data) {
- Document* doc = To<Document>(ExecutionContext::From(script_state));
+ const ShareData* share_data,
+ ExceptionState& exception_state) {
+ Document* doc = Document::From(ExecutionContext::From(script_state));
KURL full_url;
String error_message = CheckForTypeError(*doc, *share_data, &full_url);
if (!error_message.IsEmpty()) {
- v8::Local<v8::Value> error = V8ThrowException::CreateTypeError(
- script_state->GetIsolate(), error_message);
- return ScriptPromise::Reject(script_state, error);
+ exception_state.ThrowTypeError(error_message);
+ return ScriptPromise();
}
if (!LocalFrame::HasTransientUserActivation(doc->GetFrame())) {
- auto* error = MakeGarbageCollected<DOMException>(
+ exception_state.ThrowDOMException(
DOMExceptionCode::kNotAllowedError,
"Must be handling a user gesture to perform a share request.");
- return ScriptPromise::RejectWithDOMException(script_state, error);
+ return ScriptPromise();
}
if (!service_remote_) {
LocalFrame* frame = doc->GetFrame();
if (!frame) {
- auto* error = MakeGarbageCollected<DOMException>(
+ exception_state.ThrowDOMException(
DOMExceptionCode::kAbortError,
- "Internal error: document frame is missing (the "
- "navigator may be detached).");
- return ScriptPromise::RejectWithDOMException(script_state, error);
+ "Internal error: document frame is missing (the navigator may be "
+ "detached).");
+ return ScriptPromise();
}
// See https://bit.ly/2S0zRAS for task types.
@@ -225,9 +237,9 @@ ScriptPromise NavigatorShare::share(ScriptState* script_state,
if (files.size() > kMaxSharedFileCount ||
total_bytes > kMaxSharedFileBytes) {
- auto* error = MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotAllowedError, "Permission denied");
- return ScriptPromise::RejectWithDOMException(script_state, error);
+ exception_state.ThrowDOMException(DOMExceptionCode::kNotAllowedError,
+ "Permission denied");
+ return ScriptPromise();
}
}
@@ -242,8 +254,9 @@ ScriptPromise NavigatorShare::share(ScriptState* script_state,
ScriptPromise NavigatorShare::share(ScriptState* script_state,
Navigator& navigator,
- const ShareData* share_data) {
- return From(navigator).share(script_state, share_data);
+ const ShareData* share_data,
+ ExceptionState& exception_state) {
+ return From(navigator).share(script_state, share_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 23ff0e6bc91..1f2e4894b5f 100644
--- a/chromium/third_party/blink/renderer/modules/webshare/navigator_share.h
+++ b/chromium/third_party/blink/renderer/modules/webshare/navigator_share.h
@@ -10,7 +10,7 @@
#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/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/frame/navigator.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -20,6 +20,7 @@
namespace blink {
+class ExceptionState;
class Navigator;
class ShareData;
@@ -41,10 +42,13 @@ class MODULES_EXPORT NavigatorShare final
// Navigator partial interface
bool canShare(ScriptState*, const ShareData*);
static bool canShare(ScriptState*, Navigator&, const ShareData*);
- ScriptPromise share(ScriptState*, const ShareData*);
- static ScriptPromise share(ScriptState*, Navigator&, const ShareData*);
+ ScriptPromise share(ScriptState*, const ShareData*, ExceptionState&);
+ static ScriptPromise share(ScriptState*,
+ Navigator&,
+ const ShareData*,
+ ExceptionState&);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
class ShareClientImpl;
diff --git a/chromium/third_party/blink/renderer/modules/webshare/navigator_share.idl b/chromium/third_party/blink/renderer/modules/webshare/navigator_share.idl
index 1a4bf168619..072c0280e2d 100644
--- a/chromium/third_party/blink/renderer/modules/webshare/navigator_share.idl
+++ b/chromium/third_party/blink/renderer/modules/webshare/navigator_share.idl
@@ -2,15 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://w3c.github.io/web-share/
+// https://w3c.github.io/web-share/level-2/#navigator-interface
[
ImplementedAs=NavigatorShare,
RuntimeEnabled=WebShare
] partial interface Navigator {
[SecureContext, CallWith=ScriptState, MeasureAs=WebShareCanShare, RuntimeEnabled=WebShareV2]
- boolean canShare(optional ShareData data);
+ boolean canShare(optional ShareData data = {});
- [SecureContext, CallWith=ScriptState, MeasureAs=WebShareShare]
- Promise<void> share(optional ShareData data);
+ [SecureContext, CallWith=ScriptState, RaisesException, MeasureAs=WebShareShare]
+ Promise<void> share(optional ShareData data = {});
};
diff --git a/chromium/third_party/blink/renderer/modules/webshare/navigator_share_test.cc b/chromium/third_party/blink/renderer/modules/webshare/navigator_share_test.cc
index 5cb339023c0..50d5b7ec513 100644
--- a/chromium/third_party/blink/renderer/modules/webshare/navigator_share_test.cc
+++ b/chromium/third_party/blink/renderer/modules/webshare/navigator_share_test.cc
@@ -9,13 +9,14 @@
#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/script_promise.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_file_property_bag.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_share_data.h"
#include "third_party/blink/renderer/core/fileapi/file.h"
-#include "third_party/blink/renderer/core/fileapi/file_property_bag.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/testing/dummy_page_holder.h"
-#include "third_party/blink/renderer/modules/webshare/share_data.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/testing/unit_test_helpers.h"
@@ -90,8 +91,9 @@ class NavigatorShareTest : public testing::Test {
void Share(const ShareData& share_data) {
LocalFrame::NotifyUserActivation(&GetFrame());
Navigator* navigator = GetFrame().DomWindow()->navigator();
- ScriptPromise promise =
- NavigatorShare::share(GetScriptState(), *navigator, &share_data);
+ NonThrowableExceptionState exception_state;
+ ScriptPromise promise = NavigatorShare::share(GetScriptState(), *navigator,
+ &share_data, exception_state);
test::RunPendingTasks();
EXPECT_EQ(mock_share_service_.error() == mojom::ShareError::OK
? v8::Promise::kFulfilled
@@ -140,7 +142,7 @@ TEST_F(NavigatorShareTest, ShareText) {
ShareData share_data;
share_data.setTitle(title);
share_data.setText(message);
- share_data.setURL(url);
+ share_data.setUrl(url);
Share(share_data);
EXPECT_EQ(mock_share_service().title(), title);
diff --git a/chromium/third_party/blink/renderer/modules/websockets/OWNERS b/chromium/third_party/blink/renderer/modules/websockets/OWNERS
index d5f50691953..e765c190805 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/websockets/OWNERS
@@ -1,5 +1,6 @@
ricea@chromium.org
yhirano@chromium.org
+yoichio@chromium.org
# TEAM: blink-network-dev@chromium.org
# COMPONENT: Blink>Network>WebSockets
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 7f1be93be7d..6880c91dfa8 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/close_event.h
+++ b/chromium/third_party/blink/renderer/modules/websockets/close_event.h
@@ -31,10 +31,10 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBSOCKETS_CLOSE_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBSOCKETS_CLOSE_EVENT_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_close_event_init.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/event_type_names.h"
#include "third_party/blink/renderer/modules/event_modules.h"
-#include "third_party/blink/renderer/modules/websockets/close_event_init.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/wtf/forward.h"
@@ -70,7 +70,7 @@ class CloseEvent final : public Event {
return event_interface_names::kCloseEvent;
}
- void Trace(blink::Visitor* visitor) override { Event::Trace(visitor); }
+ void Trace(Visitor* visitor) override { Event::Trace(visitor); }
private:
bool was_clean_;
diff --git a/chromium/third_party/blink/renderer/modules/websockets/close_event.idl b/chromium/third_party/blink/renderer/modules/websockets/close_event.idl
index 438a0b69cc2..e6394d3dae0 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/close_event.idl
+++ b/chromium/third_party/blink/renderer/modules/websockets/close_event.idl
@@ -31,9 +31,9 @@
// https://html.spec.whatwg.org/C/#the-closeevent-interfaces
[
- Constructor(DOMString type, optional CloseEventInit eventInitDict),
Exposed=(Window,Worker)
] interface CloseEvent : Event {
+ constructor(DOMString type, optional CloseEventInit eventInitDict = {});
readonly attribute boolean wasClean;
readonly attribute unsigned short code;
readonly attribute DOMString reason;
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 eaca908f221..7cc63e5d1ba 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.cc
+++ b/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.cc
@@ -36,10 +36,10 @@
#include "base/callback.h"
#include "base/feature_list.h"
#include "base/location.h"
+#include "base/metrics/histogram_functions.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/public/platform/web_insecure_request_policy.h"
#include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_string_sequence.h"
@@ -60,7 +60,6 @@
#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/heap/persistent.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/network/network_log.h"
#include "third_party/blink/renderer/platform/weborigin/known_ports.h"
@@ -166,7 +165,7 @@ void DOMWebSocket::EventQueue::UnpauseTask() {
DispatchQueuedEvents();
}
-void DOMWebSocket::EventQueue::Trace(blink::Visitor* visitor) {
+void DOMWebSocket::EventQueue::Trace(Visitor* visitor) {
visitor->Trace(target_);
visitor->Trace(events_);
}
@@ -182,7 +181,7 @@ constexpr WebSocketCommon::State DOMWebSocket::kClosing;
constexpr WebSocketCommon::State DOMWebSocket::kClosed;
DOMWebSocket::DOMWebSocket(ExecutionContext* context)
- : ContextLifecycleStateObserver(context),
+ : ExecutionContextLifecycleStateObserver(context),
buffered_amount_(0),
consumed_buffered_amount_(0),
buffered_amount_after_close_(0),
@@ -202,8 +201,9 @@ DOMWebSocket::~DOMWebSocket() {
void DOMWebSocket::LogError(const String& message) {
if (GetExecutionContext()) {
GetExecutionContext()->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kError, message));
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kError, message));
}
}
@@ -336,7 +336,7 @@ void DOMWebSocket::send(const String& message,
return;
}
- RecordSendTypeHistogram(kWebSocketSendTypeString);
+ RecordSendTypeHistogram(WebSocketSendType::kString);
DCHECK(channel_);
buffered_amount_ += encoded_message.length();
@@ -348,7 +348,6 @@ void DOMWebSocket::send(DOMArrayBuffer* binary_data,
NETWORK_DVLOG(1) << "WebSocket " << this << " send() Sending ArrayBuffer "
<< binary_data;
DCHECK(binary_data);
- DCHECK(binary_data->Buffer());
if (common_.GetState() == kConnecting) {
SetInvalidStateErrorForSendMethod(exception_state);
return;
@@ -357,8 +356,8 @@ void DOMWebSocket::send(DOMArrayBuffer* binary_data,
UpdateBufferedAmountAfterClose(binary_data->ByteLengthAsSizeT());
return;
}
- RecordSendTypeHistogram(kWebSocketSendTypeArrayBuffer);
- RecordSendMessageSizeHistogram(kWebSocketSendTypeArrayBuffer,
+ RecordSendTypeHistogram(WebSocketSendType::kArrayBuffer);
+ RecordSendMessageSizeHistogram(WebSocketSendType::kArrayBuffer,
binary_data->ByteLengthAsSizeT());
DCHECK(channel_);
buffered_amount_ += binary_data->ByteLengthAsSizeT();
@@ -377,16 +376,14 @@ void DOMWebSocket::send(NotShared<DOMArrayBufferView> array_buffer_view,
}
if (common_.GetState() == kClosing || common_.GetState() == kClosed) {
UpdateBufferedAmountAfterClose(
- array_buffer_view.View()->deprecatedByteLengthAsUnsigned());
+ array_buffer_view.View()->byteLengthAsSizeT());
return;
}
- RecordSendTypeHistogram(kWebSocketSendTypeArrayBufferView);
- RecordSendMessageSizeHistogram(
- kWebSocketSendTypeArrayBufferView,
- array_buffer_view.View()->deprecatedByteLengthAsUnsigned());
+ RecordSendTypeHistogram(WebSocketSendType::kArrayBufferView);
+ RecordSendMessageSizeHistogram(WebSocketSendType::kArrayBufferView,
+ array_buffer_view.View()->byteLengthAsSizeT());
DCHECK(channel_);
- buffered_amount_ +=
- array_buffer_view.View()->deprecatedByteLengthAsUnsigned();
+ buffered_amount_ += array_buffer_view.View()->byteLengthAsSizeT();
channel_->Send(*array_buffer_view.View()->buffer(),
array_buffer_view.View()->byteOffsetAsSizeT(),
array_buffer_view.View()->byteLengthAsSizeT(),
@@ -406,9 +403,9 @@ void DOMWebSocket::send(Blob* binary_data, ExceptionState& exception_state) {
return;
}
uint64_t size = binary_data->size();
- RecordSendTypeHistogram(kWebSocketSendTypeBlob);
+ RecordSendTypeHistogram(WebSocketSendType::kBlob);
RecordSendMessageSizeHistogram(
- kWebSocketSendTypeBlob,
+ WebSocketSendType::kBlob,
clampTo<size_t>(size, 0, kMaxByteSizeForHistogram));
buffered_amount_ += size;
DCHECK(channel_);
@@ -494,10 +491,10 @@ const AtomicString& DOMWebSocket::InterfaceName() const {
}
ExecutionContext* DOMWebSocket::GetExecutionContext() const {
- return ContextLifecycleStateObserver::GetExecutionContext();
+ return ExecutionContextLifecycleStateObserver::GetExecutionContext();
}
-void DOMWebSocket::ContextDestroyed(ExecutionContext*) {
+void DOMWebSocket::ContextDestroyed() {
NETWORK_DVLOG(1) << "WebSocket " << this << " contextDestroyed()";
event_queue_->ContextDestroyed();
if (channel_) {
@@ -547,7 +544,6 @@ void DOMWebSocket::DidReceiveTextMessage(const String& msg) {
DCHECK_NE(common_.GetState(), kConnecting);
if (common_.GetState() != kOpen)
return;
- RecordReceiveTypeHistogram(kWebSocketReceiveTypeString);
DCHECK(!origin_string_.IsNull());
event_queue_->Dispatch(MessageEvent::Create(msg, origin_string_));
@@ -576,16 +572,15 @@ void DOMWebSocket::DidReceiveBinaryMessage(
}
auto* blob = MakeGarbageCollected<Blob>(
BlobDataHandle::Create(std::move(blob_data), size));
- RecordReceiveTypeHistogram(kWebSocketReceiveTypeBlob);
- RecordReceiveMessageSizeHistogram(kWebSocketReceiveTypeBlob, size);
+ RecordReceiveMessageSizeHistogram(WebSocketReceiveType::kBlob, size);
event_queue_->Dispatch(MessageEvent::Create(blob, origin_string_));
break;
}
case kBinaryTypeArrayBuffer:
DOMArrayBuffer* array_buffer = DOMArrayBuffer::Create(data);
- RecordReceiveTypeHistogram(kWebSocketReceiveTypeArrayBuffer);
- RecordReceiveMessageSizeHistogram(kWebSocketReceiveTypeArrayBuffer, size);
+ RecordReceiveMessageSizeHistogram(WebSocketReceiveType::kArrayBuffer,
+ size);
event_queue_->Dispatch(
MessageEvent::Create(array_buffer, origin_string_));
break;
@@ -638,10 +633,7 @@ void DOMWebSocket::DidClose(
}
void DOMWebSocket::RecordSendTypeHistogram(WebSocketSendType type) {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- EnumerationHistogram, send_type_histogram,
- ("WebCore.WebSocket.SendType", kWebSocketSendTypeMax));
- send_type_histogram.Count(type);
+ base::UmaHistogramEnumeration("WebCore.WebSocket.SendType", type);
}
void DOMWebSocket::RecordSendMessageSizeHistogram(WebSocketSendType type,
@@ -649,43 +641,29 @@ void DOMWebSocket::RecordSendMessageSizeHistogram(WebSocketSendType type,
// Truncate |size| to avoid overflowing int32_t.
int32_t size_to_count = clampTo<int32_t>(size, 0, kMaxByteSizeForHistogram);
switch (type) {
- case kWebSocketSendTypeArrayBuffer: {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, array_buffer_message_size_histogram,
- ("WebCore.WebSocket.MessageSize.Send.ArrayBuffer", 1,
- kMaxByteSizeForHistogram, kBucketCountForMessageSizeHistogram));
- array_buffer_message_size_histogram.Count(size_to_count);
+ case WebSocketSendType::kArrayBuffer:
+ base::UmaHistogramCustomCounts(
+ "WebCore.WebSocket.MessageSize.Send.ArrayBuffer", size_to_count, 1,
+ kMaxByteSizeForHistogram, kBucketCountForMessageSizeHistogram);
return;
- }
- case kWebSocketSendTypeArrayBufferView: {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, array_buffer_view_message_size_histogram,
- ("WebCore.WebSocket.MessageSize.Send.ArrayBufferView", 1,
- kMaxByteSizeForHistogram, kBucketCountForMessageSizeHistogram));
- array_buffer_view_message_size_histogram.Count(size_to_count);
+ case WebSocketSendType::kArrayBufferView:
+ base::UmaHistogramCustomCounts(
+ "WebCore.WebSocket.MessageSize.Send.ArrayBufferView", size_to_count,
+ 1, kMaxByteSizeForHistogram, kBucketCountForMessageSizeHistogram);
return;
- }
- case kWebSocketSendTypeBlob: {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, blob_message_size_histogram,
- ("WebCore.WebSocket.MessageSize.Send.Blob", 1,
- kMaxByteSizeForHistogram, kBucketCountForMessageSizeHistogram));
- blob_message_size_histogram.Count(size_to_count);
+ case WebSocketSendType::kBlob:
+ base::UmaHistogramCustomCounts("WebCore.WebSocket.MessageSize.Send.Blob",
+ size_to_count, 1, kMaxByteSizeForHistogram,
+ kBucketCountForMessageSizeHistogram);
return;
- }
- default:
+ case WebSocketSendType::kString:
NOTREACHED();
+ return;
}
-}
-
-void DOMWebSocket::RecordReceiveTypeHistogram(WebSocketReceiveType type) {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- EnumerationHistogram, receive_type_histogram,
- ("WebCore.WebSocket.ReceiveType", kWebSocketReceiveTypeMax));
- receive_type_histogram.Count(type);
+ NOTREACHED();
}
void DOMWebSocket::RecordReceiveMessageSizeHistogram(WebSocketReceiveType type,
@@ -693,35 +671,31 @@ void DOMWebSocket::RecordReceiveMessageSizeHistogram(WebSocketReceiveType type,
// Truncate |size| to avoid overflowing int32_t.
int32_t size_to_count = clampTo<int32_t>(size, 0, kMaxByteSizeForHistogram);
switch (type) {
- case kWebSocketReceiveTypeArrayBuffer: {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, array_buffer_message_size_histogram,
- ("WebCore.WebSocket.MessageSize.Receive.ArrayBuffer", 1,
- kMaxByteSizeForHistogram, kBucketCountForMessageSizeHistogram));
- array_buffer_message_size_histogram.Count(size_to_count);
+ case WebSocketReceiveType::kArrayBuffer:
+ base::UmaHistogramCustomCounts(
+ "WebCore.WebSocket.MessageSize.Receive.ArrayBuffer", size_to_count, 1,
+ kMaxByteSizeForHistogram, kBucketCountForMessageSizeHistogram);
return;
- }
- case kWebSocketReceiveTypeBlob: {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, blob_message_size_histogram,
- ("WebCore.WebSocket.MessageSize.Receive.Blob", 1,
- kMaxByteSizeForHistogram, kBucketCountForMessageSizeHistogram));
- blob_message_size_histogram.Count(size_to_count);
+ case WebSocketReceiveType::kBlob:
+ base::UmaHistogramCustomCounts(
+ "WebCore.WebSocket.MessageSize.Receive.Blob", size_to_count, 1,
+ kMaxByteSizeForHistogram, kBucketCountForMessageSizeHistogram);
return;
- }
- default:
+ case WebSocketReceiveType::kString:
NOTREACHED();
+ return;
}
+ NOTREACHED();
}
-void DOMWebSocket::Trace(blink::Visitor* visitor) {
+void DOMWebSocket::Trace(Visitor* visitor) {
visitor->Trace(channel_);
visitor->Trace(event_queue_);
WebSocketChannelClient::Trace(visitor);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleStateObserver::Trace(visitor);
+ ExecutionContextLifecycleStateObserver::Trace(visitor);
}
} // namespace blink
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 6fd0d7871cb..2082fe9c0e7 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.h
+++ b/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.h
@@ -37,7 +37,7 @@
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/core/dom/events/event_listener.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h"
#include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/modules_export.h"
@@ -62,10 +62,11 @@ class ExceptionState;
class ExecutionContext;
class StringOrStringSequence;
-class MODULES_EXPORT DOMWebSocket : public EventTargetWithInlineData,
- public ActiveScriptWrappable<DOMWebSocket>,
- public ContextLifecycleStateObserver,
- public WebSocketChannelClient {
+class MODULES_EXPORT DOMWebSocket
+ : public EventTargetWithInlineData,
+ public ActiveScriptWrappable<DOMWebSocket>,
+ public ExecutionContextLifecycleStateObserver,
+ public WebSocketChannelClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(DOMWebSocket);
@@ -127,8 +128,8 @@ class MODULES_EXPORT DOMWebSocket : public EventTargetWithInlineData,
const AtomicString& InterfaceName() const override;
ExecutionContext* GetExecutionContext() const override;
- // ContextLifecycleStateObserver functions.
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleStateObserver functions.
+ void ContextDestroyed() override;
void ContextLifecycleStateChanged(mojom::FrameLifecycleState) override;
// ScriptWrappable functions.
@@ -148,7 +149,7 @@ class MODULES_EXPORT DOMWebSocket : public EventTargetWithInlineData,
uint16_t code,
const String& reason) override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
// FIXME: This should inherit blink::EventQueue.
@@ -174,7 +175,7 @@ class MODULES_EXPORT DOMWebSocket : public EventTargetWithInlineData,
bool IsPaused();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
enum State {
@@ -194,19 +195,19 @@ class MODULES_EXPORT DOMWebSocket : public EventTargetWithInlineData,
HeapDeque<Member<Event>> events_;
};
- enum WebSocketSendType {
- kWebSocketSendTypeString,
- kWebSocketSendTypeArrayBuffer,
- kWebSocketSendTypeArrayBufferView,
- kWebSocketSendTypeBlob,
- kWebSocketSendTypeMax,
+ enum class WebSocketSendType {
+ kString,
+ kArrayBuffer,
+ kArrayBufferView,
+ kBlob,
+ kMaxValue = kBlob,
};
- enum WebSocketReceiveType {
- kWebSocketReceiveTypeString,
- kWebSocketReceiveTypeArrayBuffer,
- kWebSocketReceiveTypeBlob,
- kWebSocketReceiveTypeMax,
+ enum class WebSocketReceiveType {
+ kString,
+ kArrayBuffer,
+ kBlob,
+ kMaxValue = kBlob,
};
enum BinaryType { kBinaryTypeBlob, kBinaryTypeArrayBuffer };
@@ -245,7 +246,6 @@ class MODULES_EXPORT DOMWebSocket : public EventTargetWithInlineData,
void ReleaseChannel();
void RecordSendTypeHistogram(WebSocketSendType);
void RecordSendMessageSizeHistogram(WebSocketSendType, size_t);
- void RecordReceiveTypeHistogram(WebSocketReceiveType);
void RecordReceiveMessageSizeHistogram(WebSocketReceiveType, size_t);
Member<WebSocketChannel> channel_;
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 8bf1cf6d1b4..a49fff11608 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
@@ -12,7 +12,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/devtools/console_message.mojom-blink.h"
-#include "third_party/blink/public/platform/web_insecure_request_policy.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/core/dom/document.h"
@@ -66,7 +66,7 @@ class DOMWebSocketWithMockChannel final : public DOMWebSocket {
return channel_.Get();
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(channel_);
DOMWebSocket::Trace(visitor);
}
@@ -190,7 +190,8 @@ TEST(DOMWebSocketTest, insecureRequestsUpgrade) {
.WillOnce(Return(true));
}
- scope.GetDocument().SetInsecureRequestPolicy(kUpgradeInsecureRequests);
+ scope.GetDocument().GetSecurityContext().SetInsecureRequestPolicy(
+ mojom::blink::InsecureRequestPolicy::kUpgradeInsecureRequests);
websocket_scope.Socket().Connect("ws://example.com/endpoint",
Vector<String>(), scope.GetExceptionState());
@@ -209,7 +210,8 @@ TEST(DOMWebSocketTest, insecureRequestsUpgradePotentiallyTrustworthy) {
.WillOnce(Return(true));
}
- scope.GetDocument().SetInsecureRequestPolicy(kUpgradeInsecureRequests);
+ scope.GetDocument().GetSecurityContext().SetInsecureRequestPolicy(
+ mojom::blink::InsecureRequestPolicy::kUpgradeInsecureRequests);
websocket_scope.Socket().Connect("ws://127.0.0.1/endpoint", Vector<String>(),
scope.GetExceptionState());
@@ -228,7 +230,8 @@ TEST(DOMWebSocketTest, insecureRequestsDoNotUpgrade) {
.WillOnce(Return(true));
}
- scope.GetDocument().SetInsecureRequestPolicy(kLeaveInsecureRequestsAlone);
+ scope.GetDocument().GetSecurityContext().SetInsecureRequestPolicy(
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone);
websocket_scope.Socket().Connect("ws://example.com/endpoint",
Vector<String>(), scope.GetExceptionState());
diff --git a/chromium/third_party/blink/renderer/modules/websockets/idls.gni b/chromium/third_party/blink/renderer/modules/websockets/idls.gni
new file mode 100644
index 00000000000..3cbe173200f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/websockets/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "close_event.idl",
+ "websocket.idl",
+ "websocket_stream.idl",
+]
+
+modules_dictionary_idl_files = [
+ "close_event_init.idl",
+ "websocket_close_info.idl",
+ "websocket_connection.idl",
+ "websocket_stream_options.idl",
+]
diff --git a/chromium/third_party/blink/renderer/modules/websockets/inspector_websocket_events.cc b/chromium/third_party/blink/renderer/modules/websockets/inspector_websocket_events.cc
index d311b27ba68..79a170bd654 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/inspector_websocket_events.cc
+++ b/chromium/third_party/blink/renderer/modules/websockets/inspector_websocket_events.cc
@@ -24,7 +24,7 @@ std::unique_ptr<TracedValue> InspectorWebSocketCreateEvent::Data(
auto value = std::make_unique<TracedValue>();
value->SetInteger("identifier", static_cast<int>(identifier));
value->SetString("url", url.GetString());
- if (auto* document = DynamicTo<Document>(execution_context)) {
+ if (auto* document = Document::DynamicFrom(execution_context)) {
value->SetString("frame",
IdentifiersFactory::FrameId(document->GetFrame()));
} else if (auto* scope = DynamicTo<WorkerGlobalScope>(execution_context)) {
@@ -47,7 +47,7 @@ std::unique_ptr<TracedValue> InspectorWebSocketEvent::Data(
DCHECK(execution_context->IsContextThread());
auto value = std::make_unique<TracedValue>();
value->SetInteger("identifier", static_cast<int>(identifier));
- if (auto* document = DynamicTo<Document>(execution_context)) {
+ if (auto* document = Document::DynamicFrom(execution_context)) {
value->SetString("frame",
IdentifiersFactory::FrameId(document->GetFrame()));
} else if (auto* scope = DynamicTo<WorkerGlobalScope>(execution_context)) {
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 228f08cd5c4..ee745730879 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
WebSocketChannelClient::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/websockets/web_pepper_socket_impl.cc b/chromium/third_party/blink/renderer/modules/websockets/web_pepper_socket_impl.cc
index c4f10736bbe..e8c0f2ad956 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/web_pepper_socket_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/websockets/web_pepper_socket_impl.cc
@@ -66,7 +66,8 @@ WebPepperSocketImpl::WebPepperSocketImpl(const WebDocument& document,
buffered_amount_(0),
buffered_amount_after_close_(0) {
Document* core_document = document;
- private_ = WebSocketChannelImpl::Create(core_document, channel_proxy_.Get(),
+ private_ = WebSocketChannelImpl::Create(core_document->ToExecutionContext(),
+ channel_proxy_.Get(),
SourceLocation::Capture());
DCHECK(private_);
}
@@ -104,7 +105,7 @@ bool WebPepperSocketImpl::SendText(const WebString& message) {
bool WebPepperSocketImpl::SendArrayBuffer(
const WebArrayBuffer& web_array_buffer) {
- unsigned size = web_array_buffer.ByteLength();
+ size_t size = web_array_buffer.ByteLengthAsSizeT();
buffered_amount_ += size;
if (is_closing_or_closed_)
buffered_amount_after_close_ += size;
diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket.idl b/chromium/third_party/blink/renderer/modules/websockets/websocket.idl
index 3c46ef69522..80883b70ade 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/websocket.idl
+++ b/chromium/third_party/blink/renderer/modules/websockets/websocket.idl
@@ -35,12 +35,10 @@ enum BinaryType { "blob", "arraybuffer" };
[
ActiveScriptWrappable,
- Constructor(USVString url, optional (DOMString or sequence<DOMString>) protocols),
- ConstructorCallWith=ExecutionContext,
Exposed=(Window,Worker),
- ImplementedAs=DOMWebSocket,
- RaisesException=Constructor
+ ImplementedAs=DOMWebSocket
] interface WebSocket : EventTarget {
+ [CallWith=ExecutionContext, RaisesException] constructor(USVString url, optional (DOMString or sequence<DOMString>) protocols);
readonly attribute USVString url;
// ready state
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 b31e5b78896..5c31fe8c0c0 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(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
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 08f12d7721f..33a5e98b116 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(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) 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 4f4788a11ce..80b37dab0e7 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
@@ -57,6 +57,7 @@
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/modules/websockets/inspector_websocket_events.h"
#include "third_party/blink/renderer/modules/websockets/websocket_channel_client.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/loader/fetch/unique_identifier.h"
#include "third_party/blink/renderer/platform/network/network_log.h"
@@ -96,7 +97,7 @@ class WebSocketChannelImpl::BlobLoader final
void DidFinishLoading() override;
void DidFail(FileErrorCode) override;
- void Trace(blink::Visitor* visitor) { visitor->Trace(channel_); }
+ void Trace(Visitor* visitor) { visitor->Trace(channel_); }
private:
Member<WebSocketChannelImpl> channel_;
@@ -112,7 +113,7 @@ class WebSocketChannelImpl::Message final
// Close message
Message(uint16_t code, const String& reason);
- void Trace(blink::Visitor* visitor) { visitor->Trace(array_buffer); }
+ void Trace(Visitor* visitor) { visitor->Trace(array_buffer); }
MessageType type;
@@ -225,9 +226,9 @@ bool WebSocketChannelImpl::Connect(const KURL& url, const String& protocol) {
String message =
"Connecting to a non-secure WebSocket server from a secure origin is "
"deprecated.";
- execution_context_->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning, message));
+ execution_context_->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning, message));
}
url_ = url;
@@ -389,9 +390,9 @@ void WebSocketChannelImpl::Fail(const String& reason,
location = location_at_construction_->Clone();
}
- execution_context_->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript, level,
- message, std::move(location)));
+ execution_context_->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript, level, message,
+ std::move(location)));
// |reason| is only for logging and should not be provided for scripts,
// hence close reason must be empty in tearDownFailedConnection.
TearDownFailedConnection();
@@ -423,12 +424,16 @@ void WebSocketChannelImpl::CancelHandshake() {
}
void WebSocketChannelImpl::ApplyBackpressure() {
+ NETWORK_DVLOG(1) << this << " ApplyBackpressure";
backpressure_ = true;
}
void WebSocketChannelImpl::RemoveBackpressure() {
- backpressure_ = false;
- ConsumePendingDataFrames();
+ NETWORK_DVLOG(1) << this << " RemoveBackpressure";
+ if (backpressure_) {
+ backpressure_ = false;
+ ConsumePendingDataFrames();
+ }
}
void WebSocketChannelImpl::OnOpeningHandshakeStarted(
@@ -451,7 +456,8 @@ void WebSocketChannelImpl::OnConnectionEstablished(
mojo::PendingReceiver<network::mojom::blink::WebSocketClient>
client_receiver,
network::mojom::blink::WebSocketHandshakeResponsePtr response,
- mojo::ScopedDataPipeConsumerHandle readable) {
+ mojo::ScopedDataPipeConsumerHandle readable,
+ mojo::ScopedDataPipeProducerHandle writable) {
DCHECK_EQ(GetState(), State::kConnecting);
const String& protocol = response->selected_protocol;
const String& extensions = response->extensions;
@@ -479,6 +485,8 @@ void WebSocketChannelImpl::OnConnectionEstablished(
websocket_.Bind(std::move(websocket),
execution_context_->GetTaskRunner(TaskType::kNetworking));
readable_ = std::move(readable);
+ // TODO(suzukikeita): Implement upload via |writable_| instead of SendFrame.
+ writable_ = std::move(writable);
const MojoResult mojo_result = readable_watcher_.Watch(
readable_.get(), MOJO_HANDLE_SIGNAL_READABLE,
MOJO_WATCH_CONDITION_SATISFIED,
@@ -544,11 +552,7 @@ void WebSocketChannelImpl::OnClosingHandshake() {
client_->DidStartClosingHandshake();
}
-ExecutionContext* WebSocketChannelImpl::GetExecutionContext() {
- return execution_context_;
-}
-
-void WebSocketChannelImpl::Trace(blink::Visitor* visitor) {
+void WebSocketChannelImpl::Trace(Visitor* visitor) {
visitor->Trace(blob_loader_);
visitor->Trace(messages_);
visitor->Trace(client_);
@@ -591,19 +595,17 @@ WebSocketChannelImpl::State WebSocketChannelImpl::GetState() const {
void WebSocketChannelImpl::SendInternal(
network::mojom::blink::WebSocketMessageType message_type,
const char* data,
- wtf_size_t total_size,
+ 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 first cast is safe since the result of min() never exceeds
- // the range of wtf_size_t. The second cast is necessary to compile
- // min() on ILP32.
- wtf_size_t size = static_cast<wtf_size_t>(
- std::min(sending_quota_,
- static_cast<uint64_t>(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,
@@ -662,8 +664,7 @@ void WebSocketChannelImpl::ProcessSendQueue() {
switch (message->type) {
case kMessageTypeText:
SendInternal(network::mojom::blink::WebSocketMessageType::TEXT,
- message->text.data(),
- static_cast<wtf_size_t>(message->text.length()),
+ message->text.data(), message->text.length(),
&consumed_buffered_amount);
break;
case kMessageTypeBlob:
@@ -677,7 +678,7 @@ void WebSocketChannelImpl::ProcessSendQueue() {
CHECK(message->array_buffer);
SendInternal(network::mojom::blink::WebSocketMessageType::BINARY,
static_cast<const char*>(message->array_buffer->Data()),
- message->array_buffer->DeprecatedByteLengthAsUnsigned(),
+ message->array_buffer->ByteLengthAsSizeT(),
&consumed_buffered_amount);
break;
case kMessageTypeClose: {
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 cbc4801b50f..6d8b9cf2c7c 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
@@ -119,7 +119,8 @@ class MODULES_EXPORT WebSocketChannelImpl final
mojo::PendingReceiver<network::mojom::blink::WebSocketClient>
client_receiver,
network::mojom::blink::WebSocketHandshakeResponsePtr,
- mojo::ScopedDataPipeConsumerHandle readable) override;
+ mojo::ScopedDataPipeConsumerHandle readable,
+ mojo::ScopedDataPipeProducerHandle writable) override;
// network::mojom::blink::WebSocketClient methods:
void OnDataFrame(bool fin,
@@ -131,9 +132,7 @@ class MODULES_EXPORT WebSocketChannelImpl final
const String& reason) override;
void OnClosingHandshake() override;
- ExecutionContext* GetExecutionContext();
-
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
struct DataFrame final {
@@ -191,7 +190,7 @@ class MODULES_EXPORT WebSocketChannelImpl final
void SendInternal(network::mojom::blink::WebSocketMessageType,
const char* data,
- wtf_size_t total_size,
+ size_t total_size,
uint64_t* consumed_buffered_amount);
void SendAndAdjustQuota(bool final,
network::mojom::blink::WebSocketMessageType,
@@ -247,7 +246,7 @@ class MODULES_EXPORT WebSocketChannelImpl final
bool throttle_passed_ = false;
bool has_initiated_opening_handshake_ = false;
uint64_t sending_quota_ = 0;
- wtf_size_t sent_size_of_top_message_ = 0;
+ size_t sent_size_of_top_message_ = 0;
FrameScheduler::SchedulingAffectingFeatureHandle
feature_handle_for_scheduler_;
@@ -267,6 +266,8 @@ class MODULES_EXPORT WebSocketChannelImpl final
mojo::SimpleWatcher readable_watcher_;
WTF::Deque<DataFrame> pending_data_frames_;
+ mojo::ScopedDataPipeProducerHandle writable_;
+
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 30a7af987a9..7556050f51b 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
@@ -74,7 +74,7 @@ class MockWebSocketChannelClient
MOCK_METHOD3(DidClose,
void(ClosingHandshakeCompletionStatus, uint16_t, const String&));
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
WebSocketChannelClient::Trace(visitor);
}
};
@@ -107,6 +107,18 @@ class WebSocketChannelImplTest : public PageTestBase {
}
};
+ struct DataFrame final {
+ DataFrame(WebSocketMessageType type, uint64_t data_length)
+ : type(type), data_length(data_length) {}
+ WebSocketMessageType type;
+ uint64_t data_length;
+
+ bool operator==(const DataFrame& that) const {
+ return std::tie(type, data_length) ==
+ std::tie(that.type, that.data_length);
+ }
+ };
+
explicit TestWebSocket(
mojo::PendingReceiver<network::mojom::blink::WebSocket>
pending_receiver)
@@ -119,6 +131,10 @@ class WebSocketChannelImplTest : public PageTestBase {
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;
+ }
void StartReceiving() override {
DCHECK(!is_start_receiving_called_);
is_start_receiving_called_ = true;
@@ -132,6 +148,10 @@ class WebSocketChannelImplTest : public PageTestBase {
const Vector<Frame>& GetFrames() const { return frames_; }
void ClearFrames() { frames_.clear(); }
+ const Vector<DataFrame>& GetDataFrames() const {
+ return pending_send_data_frames_;
+ }
+ void ClearDataFrames() { pending_send_data_frames_.clear(); }
bool IsStartReceivingCalled() const { return is_start_receiving_called_; }
bool IsStartClosingHandshakeCalled() const {
return is_start_closing_handshake_called_;
@@ -141,6 +161,7 @@ class WebSocketChannelImplTest : public PageTestBase {
private:
Vector<Frame> frames_;
+ Vector<DataFrame> pending_send_data_frames_;
bool is_start_receiving_called_ = false;
bool is_start_closing_handshake_called_ = false;
uint16_t closing_code_ = 0;
@@ -149,6 +170,7 @@ 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 {
public:
@@ -156,7 +178,7 @@ class WebSocketChannelImplTest : public PageTestBase {
ConnectArgs(
const KURL& url,
const Vector<String>& protocols,
- const KURL& site_for_cookies,
+ const net::SiteForCookies& site_for_cookies,
const String& user_agent,
mojo::PendingRemote<network::mojom::blink::WebSocketHandshakeClient>
handshake_client)
@@ -168,7 +190,7 @@ class WebSocketChannelImplTest : public PageTestBase {
KURL url;
Vector<String> protocols;
- KURL site_for_cookies;
+ net::SiteForCookies site_for_cookies;
String user_agent;
mojo::PendingRemote<network::mojom::blink::WebSocketHandshakeClient>
handshake_client;
@@ -177,7 +199,7 @@ class WebSocketChannelImplTest : public PageTestBase {
void Connect(
const KURL& url,
const Vector<String>& requested_protocols,
- const KURL& site_for_cookies,
+ const net::SiteForCookies& site_for_cookies,
const String& user_agent,
mojo::PendingRemote<network::mojom::blink::WebSocketHandshakeClient>
handshake_client) override {
@@ -233,6 +255,7 @@ class WebSocketChannelImplTest : public PageTestBase {
const String& selected_protocol,
const String& extensions,
mojo::ScopedDataPipeConsumerHandle readable,
+ mojo::ScopedDataPipeProducerHandle writable,
mojo::Remote<network::mojom::blink::WebSocketClient>* client) {
mojo::PendingRemote<network::mojom::blink::WebSocketClient> client_remote;
mojo::PendingRemote<network::mojom::blink::WebSocket> websocket_to_pass;
@@ -248,7 +271,7 @@ class WebSocketChannelImplTest : public PageTestBase {
handshake_client->OnConnectionEstablished(
std::move(websocket_to_pass),
client_remote.InitWithNewPipeAndPassReceiver(), std::move(response),
- std::move(readable));
+ std::move(readable), std::move(writable));
client->Bind(std::move(client_remote));
return websocket;
}
@@ -265,8 +288,8 @@ class WebSocketChannelImplTest : public PageTestBase {
const KURL page_url("http://example.com/");
NavigateTo(page_url);
channel_ = WebSocketChannelImpl::CreateForTesting(
- &GetDocument(), channel_client_.Get(), SourceLocation::Capture(),
- std::move(handshake_throttle_));
+ GetDocument().ToExecutionContext(), channel_client_.Get(),
+ SourceLocation::Capture(), std::move(handshake_throttle_));
}
void TearDown() override {
@@ -295,6 +318,7 @@ class WebSocketChannelImplTest : public PageTestBase {
std::unique_ptr<TestWebSocket> Connect(
uint32_t capacity,
mojo::ScopedDataPipeProducerHandle* writable,
+ mojo::ScopedDataPipeConsumerHandle* readable,
mojo::Remote<network::mojom::blink::WebSocketClient>* client) {
if (!Channel()->Connect(KURL("ws://localhost/"), "")) {
ADD_FAILURE() << "WebSocketChannelImpl::Connect returns false.";
@@ -310,13 +334,22 @@ class WebSocketChannelImplTest : public PageTestBase {
mojo::Remote<network::mojom::blink::WebSocketHandshakeClient>
handshake_client(std::move(connect_args[0].handshake_client));
- mojo::ScopedDataPipeConsumerHandle readable;
- if (CreateDataPipe(capacity, writable, &readable) != MOJO_RESULT_OK) {
+ mojo::ScopedDataPipeConsumerHandle remote_readable;
+ if (CreateDataPipe(capacity, writable, &remote_readable) !=
+ MOJO_RESULT_OK) {
+ ADD_FAILURE() << "Failed to create a datapipe.";
+ return nullptr;
+ }
+
+ mojo::ScopedDataPipeProducerHandle remote_writable;
+ if (CreateDataPipe(capacity, &remote_writable, readable) !=
+ MOJO_RESULT_OK) {
ADD_FAILURE() << "Failed to create a datapipe.";
return nullptr;
}
auto websocket = EstablishConnection(handshake_client.get(), "", "",
- std::move(readable), client);
+ std::move(remote_readable),
+ std::move(remote_writable), client);
test::RunPendingTasks();
return websocket;
}
@@ -367,8 +400,9 @@ TEST_F(WebSocketChannelImplTest, ConnectSuccess) {
EXPECT_CALL(*ChannelClient(), DidConnect(String("a"), String("b")));
}
- // Make sure that firstPartyForCookies() is set to the given value.
- EXPECT_EQ("http://example.com/", GetDocument().SiteForCookies().GetString());
+ // Make sure that SiteForCookies() is set to the given value.
+ EXPECT_TRUE(net::SiteForCookies::FromUrl(GURL("http://example.com/"))
+ .IsEquivalent(GetDocument().SiteForCookies()));
ASSERT_TRUE(Channel()->Connect(KURL("ws://localhost/"), "x"));
EXPECT_TRUE(connector_.GetConnectArgs().IsEmpty());
@@ -378,20 +412,28 @@ TEST_F(WebSocketChannelImplTest, ConnectSuccess) {
ASSERT_EQ(1u, connect_args.size());
EXPECT_EQ(connect_args[0].url, KURL("ws://localhost/"));
- EXPECT_EQ(connect_args[0].site_for_cookies, KURL("http://example.com/"));
+ EXPECT_TRUE(connect_args[0].site_for_cookies.IsEquivalent(
+ net::SiteForCookies::FromUrl(GURL("http://example.com/"))));
EXPECT_EQ(connect_args[0].protocols, Vector<String>({"x"}));
mojo::Remote<network::mojom::blink::WebSocketHandshakeClient>
handshake_client(std::move(connect_args[0].handshake_client));
- mojo::ScopedDataPipeProducerHandle writable;
- mojo::ScopedDataPipeConsumerHandle readable;
- ASSERT_EQ(CreateDataPipe(32, &writable, &readable), MOJO_RESULT_OK);
+ mojo::ScopedDataPipeProducerHandle incoming_writable;
+ mojo::ScopedDataPipeConsumerHandle incoming_readable;
+ ASSERT_EQ(CreateDataPipe(32, &incoming_writable, &incoming_readable),
+ MOJO_RESULT_OK);
+
+ mojo::ScopedDataPipeProducerHandle outgoing_writable;
+ mojo::ScopedDataPipeConsumerHandle outgoing_readable;
+ ASSERT_EQ(CreateDataPipe(32, &outgoing_writable, &outgoing_readable),
+ MOJO_RESULT_OK);
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = EstablishConnection(handshake_client.get(), "a", "b",
- std::move(readable), &client);
+ std::move(incoming_readable),
+ std::move(outgoing_writable), &client);
checkpoint.Call(1);
test::RunPendingTasks();
@@ -432,8 +474,9 @@ TEST_F(WebSocketChannelImplTest, SendText) {
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, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
Channel()->Send("foo", base::OnceClosure());
@@ -462,8 +505,9 @@ TEST_F(WebSocketChannelImplTest, SendTextContinuation) {
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, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
client->AddSendFlowControlQuota(16);
@@ -511,8 +555,9 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInVector) {
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, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
client->AddSendFlowControlQuota(16);
@@ -532,8 +577,9 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferPartial) {
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, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
client->AddSendFlowControlQuota(16);
@@ -563,8 +609,9 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferWithNullBytes) {
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, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
{
@@ -603,8 +650,9 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferNonLatin1UTF8) {
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, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
DOMArrayBuffer* b = DOMArrayBuffer::Create("\xe7\x8b\x90", 3);
@@ -625,8 +673,9 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferNonUTF8) {
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, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
DOMArrayBuffer* b = DOMArrayBuffer::Create("\x80\xff\xe7", 3);
@@ -648,8 +697,9 @@ TEST_F(WebSocketChannelImplTest,
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, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
DOMArrayBuffer* b = DOMArrayBuffer::Create(
@@ -682,8 +732,9 @@ TEST_F(WebSocketChannelImplTest, SendTextSync) {
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, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
client->AddSendFlowControlQuota(5);
@@ -699,8 +750,9 @@ TEST_F(WebSocketChannelImplTest, SendTextAsyncDueToQuota) {
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, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
client->AddSendFlowControlQuota(4);
@@ -722,8 +774,9 @@ TEST_F(WebSocketChannelImplTest, SendTextAsyncDueToQueueing) {
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, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
client->AddSendFlowControlQuota(8);
@@ -749,8 +802,9 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferSync) {
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, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
client->AddSendFlowControlQuota(5);
@@ -768,8 +822,9 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferAsyncDueToQuota) {
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, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
client->AddSendFlowControlQuota(4);
@@ -792,8 +847,9 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferAsyncDueToQueueing) {
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, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
client->AddSendFlowControlQuota(8);
@@ -824,8 +880,9 @@ TEST_F(WebSocketChannelImplTest, ReceiveText) {
}
mojo::ScopedDataPipeProducerHandle writable;
+ mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
- auto websocket = Connect(4 * 1024, &writable, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
uint32_t num_bytes = 6;
@@ -846,8 +903,9 @@ TEST_F(WebSocketChannelImplTest, ReceiveTextContinuation) {
}
mojo::ScopedDataPipeProducerHandle writable;
+ mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
- auto websocket = Connect(4 * 1024, &writable, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
uint32_t num_bytes = 3;
@@ -871,8 +929,9 @@ TEST_F(WebSocketChannelImplTest, ReceiveTextNonLatin1) {
}
mojo::ScopedDataPipeProducerHandle writable;
+ mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
- auto websocket = Connect(4 * 1024, &writable, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
uint32_t num_bytes = 6;
@@ -895,8 +954,9 @@ TEST_F(WebSocketChannelImplTest, ReceiveTextNonLatin1Continuation) {
}
mojo::ScopedDataPipeProducerHandle writable;
+ mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
- auto websocket = Connect(4 * 1024, &writable, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
uint32_t num_bytes = 6;
@@ -921,8 +981,9 @@ TEST_F(WebSocketChannelImplTest, ReceiveBinary) {
}
mojo::ScopedDataPipeProducerHandle writable;
+ mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
- auto websocket = Connect(4 * 1024, &writable, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
uint32_t num_bytes = 3;
@@ -943,8 +1004,9 @@ TEST_F(WebSocketChannelImplTest, ReceiveBinaryContinuation) {
}
mojo::ScopedDataPipeProducerHandle writable;
+ mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
- auto websocket = Connect(4 * 1024, &writable, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
uint32_t num_bytes = 3;
@@ -973,8 +1035,9 @@ TEST_F(WebSocketChannelImplTest, ReceiveBinaryWithNullBytes) {
}
mojo::ScopedDataPipeProducerHandle writable;
+ mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
- auto websocket = Connect(4 * 1024, &writable, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
uint32_t num_bytes = 12;
@@ -999,8 +1062,9 @@ TEST_F(WebSocketChannelImplTest, ReceiveBinaryNonLatin1UTF8) {
'\xe7', '\x8b', '\x90', '\xe0', '\xa4', '\x94'})));
}
mojo::ScopedDataPipeProducerHandle writable;
+ mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
- auto websocket = Connect(4 * 1024, &writable, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
uint32_t num_bytes = 6;
@@ -1023,8 +1087,9 @@ TEST_F(WebSocketChannelImplTest, ReceiveBinaryNonLatin1UTF8Continuation) {
}
mojo::ScopedDataPipeProducerHandle writable;
+ mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
- auto websocket = Connect(4 * 1024, &writable, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
uint32_t num_bytes = 6;
@@ -1049,8 +1114,9 @@ TEST_F(WebSocketChannelImplTest, ReceiveBinaryNonUTF8) {
}
mojo::ScopedDataPipeProducerHandle writable;
+ mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
- auto websocket = Connect(4 * 1024, &writable, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
uint32_t num_bytes = 2;
@@ -1072,8 +1138,9 @@ TEST_F(WebSocketChannelImplTest, ReceiveWithExplicitBackpressure) {
}
mojo::ScopedDataPipeProducerHandle writable;
+ mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
- auto websocket = Connect(4, &writable, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
uint32_t num_bytes = 3;
@@ -1111,8 +1178,9 @@ TEST_F(WebSocketChannelImplTest,
}
mojo::ScopedDataPipeProducerHandle writable;
+ mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
- auto websocket = Connect(4 * 1024, &writable, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
client->OnDataFrame(true, WebSocketMessageType::TEXT, 3);
@@ -1177,8 +1245,9 @@ TEST_F(WebSocketChannelImplTest, ConnectionCloseInitiatedByServer) {
}
mojo::ScopedDataPipeProducerHandle writable;
+ mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
- auto websocket = Connect(4 * 1024, &writable, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
client->OnClosingHandshake();
@@ -1217,8 +1286,9 @@ TEST_F(WebSocketChannelImplTest, ConnectionCloseInitiatedByClient) {
}
mojo::ScopedDataPipeProducerHandle writable;
+ mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
- auto websocket = Connect(4 * 1024, &writable, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
EXPECT_FALSE(websocket->IsStartClosingHandshakeCalled());
@@ -1252,8 +1322,9 @@ TEST_F(WebSocketChannelImplTest, MojoConnectionError) {
}
mojo::ScopedDataPipeProducerHandle writable;
+ mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
- auto websocket = Connect(4 * 1024, &writable, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
// Send a frame so that the WebSocketChannelImpl try to read the data pipe.
@@ -1283,8 +1354,9 @@ TEST_F(WebSocketChannelImplTest, FailFromClient) {
}
mojo::ScopedDataPipeProducerHandle writable;
+ mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
- auto websocket = Connect(4 * 1024, &writable, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
Channel()->Fail("fail message from WebSocket",
@@ -1327,6 +1399,11 @@ TEST_F(WebSocketChannelImplHandshakeThrottleTest, ThrottleSucceedsFirst) {
mojo::ScopedDataPipeConsumerHandle readable;
ASSERT_EQ(CreateDataPipe(32, &writable, &readable), MOJO_RESULT_OK);
+ mojo::ScopedDataPipeProducerHandle outgoing_writable;
+ mojo::ScopedDataPipeConsumerHandle outgoing_readable;
+ ASSERT_EQ(CreateDataPipe(32, &outgoing_writable, &outgoing_readable),
+ MOJO_RESULT_OK);
+
mojo::Remote<network::mojom::blink::WebSocketClient> client;
checkpoint.Call(1);
@@ -1335,8 +1412,9 @@ TEST_F(WebSocketChannelImplHandshakeThrottleTest, ThrottleSucceedsFirst) {
Channel()->OnCompletion(base::nullopt);
checkpoint.Call(2);
- auto websocket = EstablishConnection(handshake_client.get(), "", "",
- std::move(readable), &client);
+ auto websocket =
+ EstablishConnection(handshake_client.get(), "", "", std::move(readable),
+ std::move(outgoing_writable), &client);
test::RunPendingTasks();
}
@@ -1352,10 +1430,11 @@ TEST_F(WebSocketChannelImplHandshakeThrottleTest, HandshakeSucceedsFirst) {
}
mojo::ScopedDataPipeProducerHandle writable;
+ mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
checkpoint.Call(1);
- auto websocket = Connect(4 * 1024, &writable, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
checkpoint.Call(2);
@@ -1396,8 +1475,9 @@ TEST_F(WebSocketChannelImplHandshakeThrottleTest,
}
mojo::ScopedDataPipeProducerHandle writable;
+ mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
- auto websocket = Connect(4 * 1024, &writable, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
Channel()->Fail("close during handshake",
@@ -1447,8 +1527,9 @@ TEST_F(WebSocketChannelImplHandshakeThrottleTest,
}
mojo::ScopedDataPipeProducerHandle writable;
+ mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
- auto websocket = Connect(4 * 1024, &writable, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
Channel()->Disconnect();
@@ -1488,8 +1569,9 @@ TEST_F(WebSocketChannelImplHandshakeThrottleTest,
}
mojo::ScopedDataPipeProducerHandle writable;
+ mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
- auto websocket = Connect(4 * 1024, &writable, &client);
+ auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
Channel()->OnCompletion("Connection blocked by throttle");
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 bf57d173478..a416644e20d 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/websocket_common.cc
+++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_common.cc
@@ -7,15 +7,15 @@
#include <stddef.h>
#include "base/metrics/histogram_macros.h"
-#include "third_party/blink/public/platform/web_insecure_request_policy.h"
+#include "third_party/blink/public/common/security_context/insecure_request_policy.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/execution_context/security_context.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/loader/mixed_content_checker.h"
+#include "third_party/blink/renderer/modules/websockets/websocket_channel.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/modules/websockets/websocket_channel.h"
#include "third_party/blink/renderer/platform/weborigin/known_ports.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
@@ -41,8 +41,9 @@ WebSocketCommon::ConnectResult WebSocketCommon::Connect(
url_ = KURL(NullURL(), url);
bool upgrade_insecure_requests_set =
- execution_context->GetSecurityContext().GetInsecureRequestPolicy() &
- kUpgradeInsecureRequests;
+ (execution_context->GetSecurityContext().GetInsecureRequestPolicy() &
+ mojom::blink::InsecureRequestPolicy::kUpgradeInsecureRequests) !=
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone;
if (upgrade_insecure_requests_set && url_.Protocol() == "ws" &&
!SecurityOrigin::Create(url_)->IsPotentiallyTrustworthy()) {
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 48dea29aea5..1c9a29ad674 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.cc
+++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.cc
@@ -8,12 +8,15 @@
#include <string>
#include <utility>
+#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.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_array_buffer.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_websocket_close_info.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_websocket_connection.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_websocket_stream_options.h"
#include "third_party/blink/renderer/core/dom/abort_signal.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/streams/readable_stream.h"
@@ -25,9 +28,6 @@
#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/websockets/websocket_channel_impl.h"
-#include "third_party/blink/renderer/modules/websockets/websocket_close_info.h"
-#include "third_party/blink/renderer/modules/websockets/websocket_connection.h"
-#include "third_party/blink/renderer/modules/websockets/websocket_stream_options.h"
#include "third_party/blink/renderer/platform/bindings/exception_code.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
@@ -68,12 +68,17 @@ class WebSocketStream::UnderlyingSink final : public UnderlyingSinkBase {
explicit UnderlyingSink(WebSocketStream* creator) : creator_(creator) {}
// UnderlyingSinkBase implementation.
- ScriptPromise start(ScriptState*, WritableStreamDefaultController*) override;
+ ScriptPromise start(ScriptState*,
+ WritableStreamDefaultController*,
+ ExceptionState&) override;
ScriptPromise write(ScriptState*,
ScriptValue chunk,
- WritableStreamDefaultController*) override;
- ScriptPromise close(ScriptState*) override;
- ScriptPromise abort(ScriptState*, ScriptValue reason) override;
+ WritableStreamDefaultController*,
+ ExceptionState&) override;
+ ScriptPromise close(ScriptState*, ExceptionState&) override;
+ ScriptPromise abort(ScriptState*,
+ ScriptValue reason,
+ ExceptionState&) override;
// API for WebSocketStream.
void DidStartClosingHandshake();
@@ -93,7 +98,8 @@ class WebSocketStream::UnderlyingSink final : public UnderlyingSinkBase {
void SendAny(ScriptState*,
v8::Local<v8::Value> v8chunk,
ScriptPromiseResolver*,
- base::OnceClosure callback);
+ base::OnceClosure callback,
+ ExceptionState&);
void SendArrayBuffer(ScriptState*,
DOMArrayBuffer*,
size_t offset,
@@ -178,7 +184,8 @@ void WebSocketStream::UnderlyingSource::DidClose(bool was_clean,
ScriptPromise WebSocketStream::UnderlyingSink::start(
ScriptState* script_state,
- WritableStreamDefaultController*) {
+ WritableStreamDefaultController*,
+ ExceptionState& exception_state) {
DVLOG(1) << "WebSocketStream::UnderlyingSink " << this << " start()";
return ScriptPromise::CastUndefined(script_state);
}
@@ -186,7 +193,8 @@ ScriptPromise WebSocketStream::UnderlyingSink::start(
ScriptPromise WebSocketStream::UnderlyingSink::write(
ScriptState* script_state,
ScriptValue chunk,
- WritableStreamDefaultController*) {
+ WritableStreamDefaultController*,
+ ExceptionState& exception_state) {
DVLOG(1) << "WebSocketStream::UnderlyingSink " << this << " write()";
is_writing_ = true;
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -195,12 +203,16 @@ ScriptPromise WebSocketStream::UnderlyingSink::write(
WTF::Bind(&UnderlyingSink::FinishWriteCallback, WrapWeakPersistent(this),
WrapPersistent(resolver));
v8::Local<v8::Value> v8chunk = chunk.V8Value();
- SendAny(script_state, v8chunk, resolver, std::move(callback));
+ SendAny(script_state, v8chunk, resolver, std::move(callback),
+ exception_state);
+ if (exception_state.HadException())
+ return ScriptPromise();
return result;
}
ScriptPromise WebSocketStream::UnderlyingSink::close(
- ScriptState* script_state) {
+ ScriptState* script_state,
+ ExceptionState& exception_state) {
DVLOG(1) << "WebSocketStream::UnderlyingSink " << this << " close()";
closed_ = true;
creator_->CloseWithUnspecifiedCode();
@@ -209,8 +221,10 @@ ScriptPromise WebSocketStream::UnderlyingSink::close(
return close_resolver_->Promise();
}
-ScriptPromise WebSocketStream::UnderlyingSink::abort(ScriptState* script_state,
- ScriptValue reason) {
+ScriptPromise WebSocketStream::UnderlyingSink::abort(
+ ScriptState* script_state,
+ ScriptValue reason,
+ ExceptionState& exception_state) {
DVLOG(1) << "WebSocketStream::UnderlyingSink " << this << " abort()";
closed_ = true;
@@ -288,7 +302,8 @@ void WebSocketStream::UnderlyingSink::ResolveClose(bool was_clean) {
void WebSocketStream::UnderlyingSink::SendAny(ScriptState* script_state,
v8::Local<v8::Value> v8chunk,
ScriptPromiseResolver* resolver,
- base::OnceClosure callback) {
+ base::OnceClosure callback,
+ ExceptionState& exception_state) {
DVLOG(1) << "WebSocketStream::UnderlyingSink " << this << " SendAny()";
auto* isolate = script_state->GetIsolate();
if (v8chunk->IsArrayBuffer()) {
@@ -299,15 +314,12 @@ void WebSocketStream::UnderlyingSink::SendAny(ScriptState* script_state,
}
if (v8chunk->IsArrayBufferView()) {
- ExceptionState exception_state(isolate, ExceptionState::kUnknownContext, "",
- "");
NotShared<DOMArrayBufferView> data =
ToNotShared<NotShared<DOMArrayBufferView>>(isolate, v8chunk,
exception_state);
if (exception_state.HadException()) {
closed_ = true;
is_writing_ = false;
- resolver->Reject(exception_state);
return;
}
@@ -418,7 +430,7 @@ WebSocketStream* WebSocketStream::CreateInternal(
WebSocketStream::WebSocketStream(ExecutionContext* execution_context,
ScriptState* script_state)
- : ContextLifecycleObserver(execution_context),
+ : ExecutionContextLifecycleObserver(execution_context),
script_state_(script_state),
connection_resolver_(
MakeGarbageCollected<ScriptPromiseResolver>(script_state)),
@@ -473,7 +485,7 @@ void WebSocketStream::DidConnect(const String& subprotocol,
connection->setExtensions(extensions);
source_ = MakeGarbageCollected<UnderlyingSource>(script_state_, this);
auto* readable = ReadableStream::CreateWithCountQueueingStrategy(
- script_state_, source_, 0);
+ script_state_, source_, 1);
sink_ = MakeGarbageCollected<UnderlyingSink>(this);
auto* writable =
WritableStream::CreateWithCountQueueingStrategy(script_state_, sink_, 1);
@@ -558,7 +570,7 @@ void WebSocketStream::DidClose(
}
}
-void WebSocketStream::ContextDestroyed(ExecutionContext*) {
+void WebSocketStream::ContextDestroyed() {
DVLOG(1) << "WebSocketStream " << this << " ContextDestroyed()";
if (channel_) {
if (common_.GetState() == WebSocketCommon::kOpen) {
@@ -585,7 +597,7 @@ void WebSocketStream::Trace(Visitor* visitor) {
visitor->Trace(source_);
visitor->Trace(sink_);
ScriptWrappable::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
WebSocketChannelClient::Trace(visitor);
}
@@ -654,10 +666,9 @@ void WebSocketStream::CloseMaybeWithReason(ScriptValue maybe_reason) {
// Exceptions thrown here are ignored.
ExceptionState exception_state(script_state_->GetIsolate(),
ExceptionState::kUnknownContext, "", "");
- WebSocketCloseInfo* info = MakeGarbageCollected<WebSocketCloseInfo>();
- V8WebSocketCloseInfo::ToImpl(script_state_->GetIsolate(),
- maybe_reason.V8Value(), info, exception_state);
- if (info->hasCode() && !exception_state.HadException()) {
+ WebSocketCloseInfo* info = NativeValueTraits<WebSocketCloseInfo>::NativeValue(
+ script_state_->GetIsolate(), maybe_reason.V8Value(), exception_state);
+ if (!exception_state.HadException() && info->hasCode()) {
CloseInternal(info->code(), info->reason(), exception_state);
if (!exception_state.HadException())
return;
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 df0ecc29756..194c862d313 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.h
+++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.h
@@ -6,7 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBSOCKETS_WEBSOCKET_STREAM_H_
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/websockets/websocket_channel_client.h"
#include "third_party/blink/renderer/modules/websockets/websocket_common.h"
@@ -35,7 +35,7 @@ class WebSocketStreamOptions;
class MODULES_EXPORT WebSocketStream final
: public ScriptWrappable,
public ActiveScriptWrappable<WebSocketStream>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public WebSocketChannelClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(WebSocketStream);
@@ -77,8 +77,8 @@ class MODULES_EXPORT WebSocketStream final
uint16_t /* code */,
const String& /* reason */) override;
- // Implementation of ContextLifecycleObserver.
- void ContextDestroyed(ExecutionContext*) override;
+ // Implementation of ExecutionContextLifecycleObserver.
+ void ContextDestroyed() override;
// Implementation of ActiveScriptWrappable.
bool HasPendingActivity() const override;
diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.idl b/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.idl
index e205e34e54d..9b64a622b03 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.idl
+++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.idl
@@ -5,16 +5,13 @@
// TODO(ricea): Add standard link when there is one.
[
- Constructor(USVString url, optional WebSocketStreamOptions options),
- ConstructorCallWith=ScriptState,
Exposed=(Window,Worker),
- RaisesException=Constructor,
RuntimeEnabled=WebSocketStream,
- ActiveScriptWrappable,
- MeasureAs=WebSocketStreamConstructor
+ ActiveScriptWrappable
] interface WebSocketStream {
+ [CallWith=ScriptState, RaisesException, MeasureAs=WebSocketStreamConstructor] constructor(USVString url, optional WebSocketStreamOptions options = {});
readonly attribute USVString url;
[CallWith=ScriptState] readonly attribute Promise<WebSocketConnection> connection;
[CallWith=ScriptState] readonly attribute Promise<WebSocketCloseInfo> closed;
- [RaisesException] void close(optional WebSocketCloseInfo closeInfo);
+ [RaisesException] void close(optional WebSocketCloseInfo closeInfo = {});
};
diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_stream_test.cc b/chromium/third_party/blink/renderer/modules/websockets/websocket_stream_test.cc
index 4b89ff0c11f..b354da74319 100644
--- a/chromium/third_party/blink/renderer/modules/websockets/websocket_stream_test.cc
+++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_stream_test.cc
@@ -15,12 +15,12 @@
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_websocket_close_info.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_websocket_stream_options.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/modules/websockets/mock_websocket_channel.h"
#include "third_party/blink/renderer/modules/websockets/websocket_channel.h"
#include "third_party/blink/renderer/modules/websockets/websocket_channel_client.h"
-#include "third_party/blink/renderer/modules/websockets/websocket_close_info.h"
-#include "third_party/blink/renderer/modules/websockets/websocket_stream_options.h"
#include "third_party/blink/renderer/platform/bindings/exception_code.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/BUILD.gn b/chromium/third_party/blink/renderer/modules/webtransport/BUILD.gn
index eafd2f7958a..ffe23e1ef39 100644
--- a/chromium/third_party/blink/renderer/modules/webtransport/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/webtransport/BUILD.gn
@@ -6,14 +6,27 @@ import("//third_party/blink/renderer/modules/modules.gni")
blink_modules_sources("webtransport") {
sources = [
+ "incoming_stream.cc",
+ "incoming_stream.h",
+ "outgoing_stream.cc",
+ "outgoing_stream.h",
"quic_transport.cc",
"quic_transport.h",
+ "receive_stream.cc",
+ "receive_stream.h",
+ "send_stream.cc",
+ "send_stream.h",
+ "web_transport_close_proxy.h",
]
}
jumbo_source_set("unit_tests") {
testonly = true
sources = [
+ "incoming_stream_test.cc",
+ "mock_web_transport_close_proxy.cc",
+ "mock_web_transport_close_proxy.h",
+ "outgoing_stream_test.cc",
"quic_transport_test.cc",
]
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/idls.gni b/chromium/third_party/blink/renderer/modules/webtransport/idls.gni
new file mode 100644
index 00000000000..2cd36ecec8b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webtransport/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "incoming_stream.idl",
+ "outgoing_stream.idl",
+ "quic_transport.idl",
+ "receive_stream.idl",
+ "send_stream.idl",
+]
+
+modules_dictionary_idl_files = [
+ "web_transport_close_info.idl",
+ "stream_abort_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
new file mode 100644
index 00000000000..fa4ed7d6b84
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.cc
@@ -0,0 +1,350 @@
+// 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/webtransport/incoming_stream.h"
+
+#include <string.h>
+
+#include "third_party/blink/renderer/bindings/core/v8/script_function.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_stream_abort_info.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_controller_with_script_scope.h"
+#include "third_party/blink/renderer/core/streams/readable_stream_reader.h"
+#include "third_party/blink/renderer/core/streams/stream_promise_resolver.h"
+#include "third_party/blink/renderer/core/streams/underlying_source_base.h"
+#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h"
+#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
+#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
+#include "third_party/blink/renderer/modules/webtransport/web_transport_close_proxy.h"
+#include "third_party/blink/renderer/platform/bindings/exception_code.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/trace_wrapper_v8_reference.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/heap/visitor.h"
+#include "third_party/blink/renderer/platform/wtf/assertions.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+// An implementation of UnderlyingSourceBase that forwards all operations to the
+// IncomingStream object that created it.
+class IncomingStream::UnderlyingSource final : public UnderlyingSourceBase {
+ public:
+ explicit UnderlyingSource(ScriptState* script_state, IncomingStream* stream)
+ : UnderlyingSourceBase(script_state), incoming_stream_(stream) {}
+
+ ScriptPromise Start(ScriptState* script_state) override {
+ incoming_stream_->controller_ = Controller();
+ return ScriptPromise::CastUndefined(script_state);
+ }
+
+ ScriptPromise pull(ScriptState* script_state) override {
+ incoming_stream_->ReadFromPipeAndEnqueue();
+ return ScriptPromise::CastUndefined(script_state);
+ }
+
+ ScriptPromise Cancel(ScriptState* script_state, ScriptValue reason) override {
+ incoming_stream_->AbortAndReset();
+ return ScriptPromise::CastUndefined(script_state);
+ }
+
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(incoming_stream_);
+ UnderlyingSourceBase::Trace(visitor);
+ }
+
+ private:
+ const Member<IncomingStream> incoming_stream_;
+};
+
+IncomingStream::IncomingStream(ScriptState* script_state,
+ WebTransportCloseProxy* close_proxy,
+ mojo::ScopedDataPipeConsumerHandle handle)
+ : ExecutionContextLifecycleObserver(ExecutionContext::From(script_state)),
+ script_state_(script_state),
+ close_proxy_(close_proxy),
+ data_pipe_(std::move(handle)),
+ read_watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL),
+ close_watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC) {}
+
+IncomingStream::~IncomingStream() = default;
+
+void IncomingStream::Init() {
+ DVLOG(1) << "IncomingStream::Init() this=" << this;
+
+ read_watcher_.Watch(data_pipe_.get(), MOJO_HANDLE_SIGNAL_READABLE,
+ MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED,
+ WTF::BindRepeating(&IncomingStream::OnHandleReady,
+ WrapWeakPersistent(this)));
+ close_watcher_.Watch(data_pipe_.get(), MOJO_HANDLE_SIGNAL_PEER_CLOSED,
+ MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED,
+ WTF::BindRepeating(&IncomingStream::OnPeerClosed,
+ WrapWeakPersistent(this)));
+
+ // This object cannot be garbage collected as long as
+ // |reading_aborted_resolver_| is set and the ExecutionContext has not been
+ // destroyed, so it is guaranteed that that conditions in the
+ // ScriptPromiseResolver destructor will be satisfied.
+ reading_aborted_resolver_ =
+ MakeGarbageCollected<ScriptPromiseResolver>(script_state_);
+ reading_aborted_ = reading_aborted_resolver_->Promise();
+ readable_ = ReadableStream::CreateWithCountQueueingStrategy(
+ script_state_,
+ MakeGarbageCollected<UnderlyingSource>(script_state_, this), 1);
+}
+
+void IncomingStream::OnIncomingStreamClosed(bool fin_received) {
+ DVLOG(1) << "IncomingStream::OnIncomingStreamClosed(" << fin_received
+ << ") this=" << this;
+
+ DCHECK(!fin_received_.has_value());
+
+ fin_received_ = fin_received;
+
+ // QuicTransport has already dropped its reference to us, so we don't need to
+ // ForgetStream() any more.
+ close_proxy_ = nullptr;
+
+ // Wait until HandlePipeClosed() has also been called before processing the
+ // close.
+ if (is_pipe_closed_) {
+ // We need a JavaScript scope to be entered in order to resolve the
+ // |reading_aborted_| promise.
+ ScriptState::Scope scope(script_state_);
+ ProcessClose();
+ }
+}
+
+void IncomingStream::abortReading(StreamAbortInfo*) {
+ DVLOG(1) << "IncomingStream::abortReading() this=" << this;
+
+ CloseAbortAndReset();
+}
+
+void IncomingStream::Reset() {
+ DVLOG(1) << "IncomingStream::Reset() this=" << this;
+
+ // We no longer need to call ForgetStream().
+ close_proxy_ = nullptr;
+
+ ErrorStreamAbortAndReset(CreateAbortException(IsLocalAbort(false)));
+}
+
+void IncomingStream::ContextDestroyed() {
+ DVLOG(1) << "IncomingStream::ContextDestroyed() this=" << this;
+
+ if (close_proxy_) {
+ // Make QuicTransport drop its reference to us.
+ close_proxy_->ForgetStream();
+ close_proxy_ = nullptr;
+ }
+
+ ResetPipe();
+}
+
+void IncomingStream::Trace(Visitor* visitor) {
+ visitor->Trace(script_state_);
+ visitor->Trace(close_proxy_);
+ visitor->Trace(readable_);
+ visitor->Trace(controller_);
+ visitor->Trace(reading_aborted_);
+ visitor->Trace(reading_aborted_resolver_);
+ ScriptWrappable::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
+}
+
+void IncomingStream::OnHandleReady(MojoResult result,
+ const mojo::HandleSignalsState&) {
+ DVLOG(1) << "IncomingStream::OnHandleReady() this=" << this
+ << " result=" << result;
+
+ switch (result) {
+ case MOJO_RESULT_OK:
+ ReadFromPipeAndEnqueue();
+ break;
+
+ case MOJO_RESULT_FAILED_PRECONDITION:
+ // Will be handled by |close_watcher_|.
+ break;
+
+ default:
+ NOTREACHED();
+ }
+}
+
+void IncomingStream::OnPeerClosed(MojoResult result,
+ const mojo::HandleSignalsState&) {
+ DVLOG(1) << "IncomingStream::OnPeerClosed() this=" << this
+ << " result=" << result;
+
+ switch (result) {
+ case MOJO_RESULT_OK:
+ HandlePipeClosed();
+ break;
+
+ default:
+ NOTREACHED();
+ }
+}
+
+void IncomingStream::HandlePipeClosed() {
+ DVLOG(1) << "IncomingStream::HandlePipeClosed() this=" << this;
+
+ DCHECK(!is_pipe_closed_);
+
+ is_pipe_closed_ = true;
+
+ // Reset the pipe immediately to prevent being called in a loop.
+ ResetPipe();
+
+ // Wait until OnIncomingStreamClosed() has also been called before processing
+ // the close.
+ if (fin_received_.has_value()) {
+ // We need a JavaScript scope to be entered in order to resolve the
+ // |reading_aborted_| promise.
+ ScriptState::Scope scope(script_state_);
+ ProcessClose();
+ }
+}
+
+void IncomingStream::ProcessClose() {
+ DVLOG(1) << "IncomingStream::ProcessClose() this=" << this;
+
+ DCHECK(fin_received_.has_value());
+
+ if (fin_received_.value()) {
+ CloseAbortAndReset();
+ }
+
+ ErrorStreamAbortAndReset(CreateAbortException(IsLocalAbort(false)));
+}
+
+void IncomingStream::ReadFromPipeAndEnqueue() {
+ DVLOG(1) << "IncomingStream::ReadFromPipeAndEnqueue() this=" << this
+ << " in_two_phase_read_=" << in_two_phase_read_
+ << " read_pending_=" << read_pending_;
+
+ // Protect against re-entrancy.
+ if (in_two_phase_read_) {
+ read_pending_ = true;
+ return;
+ }
+ DCHECK(!read_pending_);
+
+ const void* buffer = nullptr;
+ uint32_t buffer_num_bytes = 0;
+ auto result = data_pipe_->BeginReadData(&buffer, &buffer_num_bytes,
+ MOJO_BEGIN_READ_DATA_FLAG_NONE);
+ switch (result) {
+ case MOJO_RESULT_OK: {
+ in_two_phase_read_ = true;
+ // EnqueueBytes() may re-enter this method via pull().
+ EnqueueBytes(buffer, buffer_num_bytes);
+ data_pipe_->EndReadData(buffer_num_bytes);
+ in_two_phase_read_ = false;
+ if (read_pending_) {
+ read_pending_ = false;
+ // pull() will not be called when another pull() is in progress, so the
+ // maximum recursion depth is 1.
+ ReadFromPipeAndEnqueue();
+ }
+ break;
+ }
+
+ case MOJO_RESULT_SHOULD_WAIT:
+ read_watcher_.ArmOrNotify();
+ return;
+
+ case MOJO_RESULT_FAILED_PRECONDITION:
+ // This will be handled by close_watcher_.
+ return;
+
+ default:
+ NOTREACHED() << "Unexpected result: " << result;
+ return;
+ }
+}
+
+void IncomingStream::EnqueueBytes(const void* source, uint32_t byte_length) {
+ DVLOG(1) << "IncomingStream::EnqueueBytes() this=" << this;
+
+ auto* buffer =
+ DOMUint8Array::Create(static_cast<const uint8_t*>(source), byte_length);
+ controller_->Enqueue(buffer);
+}
+
+ScriptValue IncomingStream::CreateAbortException(IsLocalAbort is_local_abort) {
+ DVLOG(1) << "IncomingStream::CreateAbortException() this=" << this
+ << " is_local_abort=" << static_cast<bool>(is_local_abort);
+
+ DOMExceptionCode code = is_local_abort ? DOMExceptionCode::kAbortError
+ : DOMExceptionCode::kNetworkError;
+ String message =
+ String::Format("The stream was aborted %s",
+ is_local_abort ? "locally" : "by the remote server");
+
+ return ScriptValue(script_state_->GetIsolate(),
+ V8ThrowDOMException::CreateOrEmpty(
+ script_state_->GetIsolate(), code, message));
+}
+
+void IncomingStream::CloseAbortAndReset() {
+ DVLOG(1) << "IncomingStream::CloseAbortAndReset() this=" << this;
+
+ controller_->Close();
+ controller_ = nullptr;
+ AbortAndReset();
+}
+
+void IncomingStream::ErrorStreamAbortAndReset(ScriptValue exception) {
+ DVLOG(1) << "IncomingStream::ErrorStreamAbortAndReset() this=" << this;
+
+ if (controller_) {
+ controller_->Error(exception);
+ controller_ = nullptr;
+ }
+
+ AbortAndReset();
+}
+
+void IncomingStream::AbortAndReset() {
+ DVLOG(1) << "IncomingStream::AbortAndReset() this=" << this;
+
+ if (reading_aborted_resolver_) {
+ // TODO(ricea): Set errorCode on the StreamAbortInfo.
+ reading_aborted_resolver_->Resolve(StreamAbortInfo::Create());
+ reading_aborted_resolver_ = nullptr;
+ }
+
+ if (close_proxy_) {
+ // Cause QuicTransport to drop its reference to us.
+ close_proxy_->ForgetStream();
+ close_proxy_ = nullptr;
+ }
+
+ ResetPipe();
+}
+
+void IncomingStream::ResetPipe() {
+ DVLOG(1) << "IncomingStream::ResetPipe() this=" << this;
+
+ read_watcher_.Cancel();
+ close_watcher_.Cancel();
+ data_pipe_.reset();
+}
+
+void IncomingStream::Dispose() {
+ DVLOG(1) << "IncomingStream::Dispose() this=" << this;
+
+ ResetPipe();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.h b/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.h
new file mode 100644
index 00000000000..82ede001d11
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.h
@@ -0,0 +1,168 @@
+// 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_WEBTRANSPORT_INCOMING_STREAM_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBTRANSPORT_INCOMING_STREAM_H_
+
+#include <stdint.h>
+
+#include "base/optional.h"
+#include "base/util/type_safety/strong_alias.h"
+#include "mojo/public/cpp/system/data_pipe.h"
+#include "mojo/public/cpp/system/simple_watcher.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/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/heap/thread_state.h"
+
+namespace blink {
+
+class ScriptState;
+class StreamAbortInfo;
+class WebTransportCloseProxy;
+class ReadableStream;
+class ReadableStreamDefaultControllerWithScriptScope;
+class Visitor;
+
+// Implementation of the IncomingStream mixin from the standard:
+// https://wicg.github.io/web-transport/#incoming-stream. ReceiveStream and
+// BidirectionalStream inherit from this.
+class MODULES_EXPORT IncomingStream
+ : public ScriptWrappable,
+ public ActiveScriptWrappable<IncomingStream>,
+ public ExecutionContextLifecycleObserver {
+ DEFINE_WRAPPERTYPEINFO();
+ USING_PRE_FINALIZER(IncomingStream, Dispose);
+ USING_GARBAGE_COLLECTED_MIXIN(IncomingStream);
+
+ public:
+ IncomingStream(ScriptState*,
+ WebTransportCloseProxy*,
+ mojo::ScopedDataPipeConsumerHandle);
+ ~IncomingStream() override;
+
+ // Init() must be called before the stream is used.
+ void Init();
+
+ WebTransportCloseProxy* GetWebTransportCloseProxy() { return close_proxy_; }
+
+ // Implementation of incoming_stream.idl.
+ ReadableStream* readable() const {
+ DVLOG(1) << "IncomingStream::readable() called";
+
+ return readable_;
+ }
+
+ ScriptPromise readingAborted() const { return reading_aborted_; }
+
+ void abortReading(StreamAbortInfo*);
+
+ // Called via WebTransportCloseProxy.
+ void OnIncomingStreamClosed(bool fin_received);
+
+ // Called via WebTransportCloseProxy. Expects a JavaScript scope to have been
+ // entered.
+ void Reset();
+
+ // IncomingStream cannot be collected until it is explicitly closed, either
+ // remotely or locally.
+ bool HasPendingActivity() const final { return reading_aborted_resolver_; }
+
+ // Implementation of ContextLifecycleObserver.
+ void ContextDestroyed() override;
+
+ void Trace(Visitor*) override;
+
+ private:
+ class UnderlyingSource;
+
+ using IsLocalAbort = util::StrongAlias<class IsLocalAbortTag, bool>;
+
+ // Called when |data_pipe_| becomes readable or errored.
+ void OnHandleReady(MojoResult, const mojo::HandleSignalsState&);
+
+ // Called when |data_pipe_| is closed.
+ void OnPeerClosed(MojoResult, const mojo::HandleSignalsState&);
+
+ // Rejects any unfinished read() calls and resets |data_pipe_|.
+ void HandlePipeClosed();
+
+ // Handles a remote close appropriately for the value of |fin_received_|.
+ void ProcessClose();
+
+ // Reads all the data currently in the pipe and enqueues it. If no data is
+ // currently available, triggers the |read_watcher_| and enqueues when data
+ // becomes available.
+ void ReadFromPipeAndEnqueue();
+
+ // Copies a sequence of bytes into an ArrayBuffer and enqueues it.
+ void EnqueueBytes(const void* source, uint32_t byte_length);
+
+ // Creates a DOMException indicating that the stream has been aborted.
+ // If IsLocalAbort it true it will indicate a locally-initiated abort,
+ // otherwise it will indicate a server--initiated abort.
+ ScriptValue CreateAbortException(IsLocalAbort);
+
+ // Closes |readable_|, resolves |reading_aborted_| and resets |data_pipe_|.
+ void CloseAbortAndReset();
+
+ // Errors |readable_|, resolves |reading_aborted_| and resets |data_pipe_|.
+ // |exception| will be set as the error on |readable_|.
+ void ErrorStreamAbortAndReset(ScriptValue exception);
+
+ // Resolves the |reading_aborted_| promise and resets the |data_pipe_|.
+ void AbortAndReset();
+
+ // Resets |data_pipe_| and clears the watchers.
+ // If the pipe is open it will be closed as a side-effect.
+ void ResetPipe();
+
+ // Prepares the object for destruction.
+ void Dispose();
+
+ const Member<ScriptState> script_state_;
+
+ // Used to call SendFin() to cause the QuicTransport object to drop its
+ // reference to us. Set to nullptr when there is no longer any need to call
+ // SendFin().
+ Member<WebTransportCloseProxy> close_proxy_;
+
+ mojo::ScopedDataPipeConsumerHandle data_pipe_;
+
+ // Only armed when we need to read something.
+ mojo::SimpleWatcher read_watcher_;
+
+ // Always armed to detect close.
+ mojo::SimpleWatcher close_watcher_;
+
+ Member<ReadableStream> readable_;
+ Member<ReadableStreamDefaultControllerWithScriptScope> controller_;
+
+ // Promise returned by the |readingAborted| attribute.
+ ScriptPromise reading_aborted_;
+ Member<ScriptPromiseResolver> reading_aborted_resolver_;
+
+ // This is set when OnIncomingStreamClosed() is called.
+ base::Optional<bool> fin_received_;
+
+ // True when |data_pipe_| has been detected to be closed. The close is not
+ // processed until |fin_received_| is also set.
+ bool is_pipe_closed_ = false;
+
+ // Indicates if we are currently performing a two-phase read from the pipe and
+ // so can't start another read.
+ bool in_two_phase_read_ = false;
+
+ // Indicates if we need to perform another read after the current one
+ // completes.
+ bool read_pending_ = false;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBTRANSPORT_INCOMING_STREAM_H_
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.idl b/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.idl
new file mode 100644
index 00000000000..4af3c3acb17
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.idl
@@ -0,0 +1,12 @@
+// 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/#incomingstream
+
+[ActiveScriptWrappable]
+interface mixin IncomingStream {
+ readonly attribute ReadableStream readable;
+ readonly attribute Promise<StreamAbortInfo> readingAborted;
+ void abortReading(optional StreamAbortInfo abortInfo = {});
+};
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream_test.cc b/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream_test.cc
new file mode 100644
index 00000000000..3fcdeb5ca77
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream_test.cc
@@ -0,0 +1,410 @@
+// 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/webtransport/incoming_stream.h"
+
+#include <utility>
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_tester.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h"
+#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/core/dom/dom_exception.h"
+#include "third_party/blink/renderer/core/streams/readable_stream.h"
+#include "third_party/blink/renderer/core/streams/readable_stream_default_reader.h"
+#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
+#include "third_party/blink/renderer/modules/webtransport/mock_web_transport_close_proxy.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+
+namespace blink {
+
+namespace {
+
+using ::testing::ElementsAre;
+using ::testing::StrictMock;
+
+class IncomingStreamTest : public ::testing::Test {
+ public:
+ // The default value of |capacity| means some sensible value selected by mojo.
+ void CreateDataPipe(uint32_t capacity = 0) {
+ MojoCreateDataPipeOptions options;
+ options.struct_size = sizeof(MojoCreateDataPipeOptions);
+ options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE;
+ options.element_num_bytes = 1;
+ options.capacity_num_bytes = capacity;
+
+ MojoResult result = mojo::CreateDataPipe(&options, &data_pipe_producer_,
+ &data_pipe_consumer_);
+ if (result != MOJO_RESULT_OK) {
+ ADD_FAILURE() << "CreateDataPipe() returned " << result;
+ }
+ }
+
+ IncomingStream* CreateIncomingStream(const V8TestingScope& scope,
+ uint32_t capacity = 0) {
+ CreateDataPipe(capacity);
+ auto* script_state = scope.GetScriptState();
+ DCHECK(!mock_close_proxy_);
+ mock_close_proxy_ =
+ MakeGarbageCollected<StrictMock<MockWebTransportCloseProxy>>();
+ auto* incoming_stream = MakeGarbageCollected<IncomingStream>(
+ script_state, mock_close_proxy_, std::move(data_pipe_consumer_));
+ incoming_stream->Init();
+ return incoming_stream;
+ }
+
+ void WriteToPipe(Vector<uint8_t> data) {
+ uint32_t num_bytes = data.size();
+ EXPECT_EQ(data_pipe_producer_->WriteData(data.data(), &num_bytes,
+ MOJO_WRITE_DATA_FLAG_ALL_OR_NONE),
+ MOJO_RESULT_OK);
+ EXPECT_EQ(num_bytes, data.size());
+ }
+
+ void ClosePipe() { data_pipe_producer_.reset(); }
+
+ // Copies the contents of a v8::Value containing a Uint8Array to a Vector.
+ static Vector<uint8_t> ToVector(const V8TestingScope& scope,
+ v8::Local<v8::Value> v8value) {
+ Vector<uint8_t> ret;
+
+ DOMUint8Array* value =
+ V8Uint8Array::ToImplWithTypeCheck(scope.GetIsolate(), v8value);
+ if (!value) {
+ ADD_FAILURE() << "chunk is not an Uint8Array";
+ return ret;
+ }
+ ret.Append(static_cast<uint8_t*>(value->Data()),
+ static_cast<wtf_size_t>(value->byteLengthAsSizeT()));
+ return ret;
+ }
+
+ struct Iterator {
+ bool done = false;
+ Vector<uint8_t> value;
+ };
+
+ // Performs a single read from |reader|, converting the output to the
+ // Iterator type. Assumes that the readable stream is not errored.
+ static Iterator Read(const V8TestingScope& scope,
+ ReadableStreamDefaultReader* reader) {
+ auto* script_state = scope.GetScriptState();
+ ScriptPromise read_promise =
+ reader->read(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromiseTester tester(script_state, read_promise);
+ tester.WaitUntilSettled();
+ EXPECT_TRUE(tester.IsFulfilled());
+ return IteratorFromReadResult(scope, tester.Value().V8Value());
+ }
+
+ static Iterator IteratorFromReadResult(const V8TestingScope& scope,
+ v8::Local<v8::Value> result) {
+ CHECK(result->IsObject());
+ Iterator ret;
+ v8::Local<v8::Value> v8value;
+ if (!V8UnpackIteratorResult(scope.GetScriptState(), result.As<v8::Object>(),
+ &ret.done)
+ .ToLocal(&v8value)) {
+ ADD_FAILURE() << "Couldn't unpack iterator";
+ return ret;
+ }
+ if (ret.done) {
+ EXPECT_TRUE(v8value->IsUndefined());
+ return ret;
+ }
+
+ ret.value = ToVector(scope, v8value);
+ return ret;
+ }
+
+ Persistent<MockWebTransportCloseProxy> mock_close_proxy_;
+ mojo::ScopedDataPipeProducerHandle data_pipe_producer_;
+ mojo::ScopedDataPipeConsumerHandle data_pipe_consumer_;
+};
+
+TEST_F(IncomingStreamTest, Create) {
+ V8TestingScope scope;
+ auto* incoming_stream = CreateIncomingStream(scope);
+ EXPECT_TRUE(incoming_stream->readable());
+
+ EXPECT_CALL(*mock_close_proxy_, ForgetStream());
+}
+
+TEST_F(IncomingStreamTest, AbortReading) {
+ V8TestingScope scope;
+
+ auto* incoming_stream = CreateIncomingStream(scope);
+ auto* script_state = scope.GetScriptState();
+ auto* reader =
+ incoming_stream->readable()->getReader(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromise reading_aborted = incoming_stream->readingAborted();
+
+ EXPECT_CALL(*mock_close_proxy_, ForgetStream());
+
+ incoming_stream->abortReading(nullptr);
+
+ // Allow the close signal to propagate down the pipe.
+ test::RunPendingTasks();
+
+ // Check that the pipe was closed.
+ const char data[] = "foo";
+ uint32_t num_bytes = 3;
+ EXPECT_EQ(data_pipe_producer_->WriteData(data, &num_bytes,
+ MOJO_WRITE_DATA_FLAG_ALL_OR_NONE),
+ MOJO_RESULT_FAILED_PRECONDITION);
+
+ ScriptPromiseTester abort_tester(script_state, reading_aborted);
+ abort_tester.WaitUntilSettled();
+ EXPECT_TRUE(abort_tester.IsFulfilled());
+
+ // Calling abortReading() does not error the stream, it simply closes it.
+ Iterator result = Read(scope, reader);
+ EXPECT_TRUE(result.done);
+}
+
+TEST_F(IncomingStreamTest, ReadArrayBuffer) {
+ V8TestingScope scope;
+
+ auto* incoming_stream = CreateIncomingStream(scope);
+ auto* script_state = scope.GetScriptState();
+ auto* reader =
+ incoming_stream->readable()->getReader(script_state, ASSERT_NO_EXCEPTION);
+ WriteToPipe({'A'});
+
+ Iterator result = Read(scope, reader);
+ EXPECT_FALSE(result.done);
+ EXPECT_THAT(result.value, ElementsAre('A'));
+ EXPECT_CALL(*mock_close_proxy_, ForgetStream());
+}
+
+// Reading data followed by a remote close should not lose data.
+TEST_F(IncomingStreamTest, ReadThenClosedWithFin) {
+ V8TestingScope scope;
+
+ auto* incoming_stream = CreateIncomingStream(scope);
+ auto* script_state = scope.GetScriptState();
+ auto* reader =
+ incoming_stream->readable()->getReader(script_state, ASSERT_NO_EXCEPTION);
+ WriteToPipe({'B'});
+ incoming_stream->OnIncomingStreamClosed(true);
+
+ Iterator result1 = Read(scope, reader);
+ EXPECT_FALSE(result1.done);
+ EXPECT_THAT(result1.value, ElementsAre('B'));
+
+ // This write arrives "out of order" due to the data pipe not being
+ // synchronised with the mojo interface.
+ WriteToPipe({'C'});
+ ClosePipe();
+
+ Iterator result2 = Read(scope, reader);
+ EXPECT_FALSE(result2.done);
+ EXPECT_THAT(result2.value, ElementsAre('C'));
+
+ Iterator result3 = Read(scope, reader);
+ EXPECT_TRUE(result3.done);
+}
+
+// Reading data followed by a remote abort should not lose data.
+TEST_F(IncomingStreamTest, ReadThenClosedWithoutFin) {
+ V8TestingScope scope;
+
+ auto* incoming_stream = CreateIncomingStream(scope);
+ auto* script_state = scope.GetScriptState();
+ auto* reader =
+ incoming_stream->readable()->getReader(script_state, ASSERT_NO_EXCEPTION);
+ WriteToPipe({'B'});
+ incoming_stream->OnIncomingStreamClosed(false);
+
+ Iterator result1 = Read(scope, reader);
+ EXPECT_FALSE(result1.done);
+ EXPECT_THAT(result1.value, ElementsAre('B'));
+
+ // This write arrives "out of order" due to the data pipe not being
+ // synchronized with the mojo interface.
+ WriteToPipe({'C'});
+ ClosePipe();
+
+ Iterator result2 = Read(scope, reader);
+ EXPECT_FALSE(result2.done);
+
+ // Even if the stream is not cleanly closed, we still endeavour to deliver all
+ // data.
+ EXPECT_THAT(result2.value, ElementsAre('C'));
+
+ ScriptPromise result3 = reader->read(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromiseTester result3_tester(script_state, result3);
+ result3_tester.WaitUntilSettled();
+ EXPECT_TRUE(result3_tester.IsRejected());
+ DOMException* exception = V8DOMException::ToImplWithTypeCheck(
+ scope.GetIsolate(), result3_tester.Value().V8Value());
+ ASSERT_TRUE(exception);
+ EXPECT_EQ(exception->code(),
+ static_cast<uint16_t>(DOMExceptionCode::kNetworkError));
+ EXPECT_EQ(exception->message(),
+ "The stream was aborted by the remote server");
+}
+
+TEST_F(IncomingStreamTest, DataPipeResetBeforeClosedWithFin) {
+ V8TestingScope scope;
+
+ auto* incoming_stream = CreateIncomingStream(scope);
+ auto* script_state = scope.GetScriptState();
+ auto* reader =
+ incoming_stream->readable()->getReader(script_state, ASSERT_NO_EXCEPTION);
+ WriteToPipe({'E'});
+ ClosePipe();
+ incoming_stream->OnIncomingStreamClosed(true);
+
+ Iterator result1 = Read(scope, reader);
+ EXPECT_FALSE(result1.done);
+ EXPECT_THAT(result1.value, ElementsAre('E'));
+
+ Iterator result2 = Read(scope, reader);
+ EXPECT_TRUE(result2.done);
+}
+
+TEST_F(IncomingStreamTest, DataPipeResetBeforeClosedWithoutFin) {
+ V8TestingScope scope;
+
+ auto* incoming_stream = CreateIncomingStream(scope);
+ auto* script_state = scope.GetScriptState();
+ auto* reader =
+ incoming_stream->readable()->getReader(script_state, ASSERT_NO_EXCEPTION);
+ WriteToPipe({'F'});
+ ClosePipe();
+ incoming_stream->OnIncomingStreamClosed(false);
+
+ Iterator result1 = Read(scope, reader);
+ EXPECT_FALSE(result1.done);
+ EXPECT_THAT(result1.value, ElementsAre('F'));
+
+ ScriptPromise result2 = reader->read(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromiseTester result2_tester(script_state, result2);
+ result2_tester.WaitUntilSettled();
+ EXPECT_TRUE(result2_tester.IsRejected());
+ DOMException* exception = V8DOMException::ToImplWithTypeCheck(
+ scope.GetIsolate(), result2_tester.Value().V8Value());
+ ASSERT_TRUE(exception);
+ EXPECT_EQ(exception->code(),
+ static_cast<uint16_t>(DOMExceptionCode::kNetworkError));
+ EXPECT_EQ(exception->message(),
+ "The stream was aborted by the remote server");
+}
+
+// A live stream will be kept alive even if there is no explicit reference.
+// When the underlying connection is shut down, the connection will be swept.
+TEST_F(IncomingStreamTest, GarbageCollection) {
+ V8TestingScope scope;
+
+ WeakPersistent<IncomingStream> incoming_stream;
+
+ {
+ // The readable stream created when creating a IncomingStream creates some
+ // v8 handles. To ensure these are collected, we need to create a handle
+ // scope. This is not a problem for garbage collection in normal operation.
+ v8::HandleScope handle_scope(scope.GetIsolate());
+
+ incoming_stream = CreateIncomingStream(scope);
+ }
+
+ // Pretend the stack is empty. This will avoid accidentally treating any
+ // copies of the |incoming_stream| pointer as references.
+ V8GCController::CollectAllGarbageForTesting(
+ scope.GetIsolate(), v8::EmbedderHeapTracer::EmbedderStackState::kEmpty);
+
+ ASSERT_TRUE(incoming_stream);
+
+ auto* script_state = scope.GetScriptState();
+
+ EXPECT_CALL(*mock_close_proxy_, ForgetStream());
+
+ ScriptPromise cancel_promise;
+ {
+ // Cancelling also creates v8 handles, so we need a new handle scope as
+ // above.
+ v8::HandleScope handle_scope(scope.GetIsolate());
+ cancel_promise =
+ incoming_stream->readable()->cancel(script_state, ASSERT_NO_EXCEPTION);
+ }
+
+ ScriptPromiseTester tester(script_state, cancel_promise);
+ tester.WaitUntilSettled();
+ EXPECT_TRUE(tester.IsFulfilled());
+
+ V8GCController::CollectAllGarbageForTesting(
+ scope.GetIsolate(), v8::EmbedderHeapTracer::EmbedderStackState::kEmpty);
+
+ EXPECT_FALSE(incoming_stream);
+}
+
+TEST_F(IncomingStreamTest, GarbageCollectionRemoteClose) {
+ V8TestingScope scope;
+
+ WeakPersistent<IncomingStream> incoming_stream;
+
+ {
+ v8::HandleScope handle_scope(scope.GetIsolate());
+
+ incoming_stream = CreateIncomingStream(scope);
+ }
+
+ V8GCController::CollectAllGarbageForTesting(
+ scope.GetIsolate(), v8::EmbedderHeapTracer::EmbedderStackState::kEmpty);
+
+ ASSERT_TRUE(incoming_stream);
+
+ // Close the other end of the pipe.
+ ClosePipe();
+
+ test::RunPendingTasks();
+
+ V8GCController::CollectAllGarbageForTesting(
+ scope.GetIsolate(), v8::EmbedderHeapTracer::EmbedderStackState::kEmpty);
+
+ ASSERT_TRUE(incoming_stream);
+
+ incoming_stream->OnIncomingStreamClosed(false);
+
+ test::RunPendingTasks();
+
+ V8GCController::CollectAllGarbageForTesting(
+ scope.GetIsolate(), v8::EmbedderHeapTracer::EmbedderStackState::kEmpty);
+
+ EXPECT_FALSE(incoming_stream);
+}
+
+TEST_F(IncomingStreamTest, WriteToPipeWithPendingRead) {
+ V8TestingScope scope;
+
+ auto* incoming_stream = CreateIncomingStream(scope);
+ auto* script_state = scope.GetScriptState();
+ auto* reader =
+ incoming_stream->readable()->getReader(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromise read_promise = reader->read(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromiseTester tester(script_state, read_promise);
+
+ test::RunPendingTasks();
+
+ WriteToPipe({'A'});
+
+ tester.WaitUntilSettled();
+ EXPECT_TRUE(tester.IsFulfilled());
+
+ Iterator result = IteratorFromReadResult(scope, tester.Value().V8Value());
+ EXPECT_FALSE(result.done);
+ EXPECT_THAT(result.value, ElementsAre('A'));
+ EXPECT_CALL(*mock_close_proxy_, ForgetStream());
+}
+
+} // namespace
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/mock_web_transport_close_proxy.cc b/chromium/third_party/blink/renderer/modules/webtransport/mock_web_transport_close_proxy.cc
new file mode 100644
index 00000000000..bf7a745630c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webtransport/mock_web_transport_close_proxy.cc
@@ -0,0 +1,12 @@
+// 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/webtransport/mock_web_transport_close_proxy.h"
+
+namespace blink {
+
+MockWebTransportCloseProxy::MockWebTransportCloseProxy() = default;
+MockWebTransportCloseProxy::~MockWebTransportCloseProxy() = default;
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/mock_web_transport_close_proxy.h b/chromium/third_party/blink/renderer/modules/webtransport/mock_web_transport_close_proxy.h
new file mode 100644
index 00000000000..4ff25033c70
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webtransport/mock_web_transport_close_proxy.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBTRANSPORT_MOCK_WEB_TRANSPORT_CLOSE_PROXY_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBTRANSPORT_MOCK_WEB_TRANSPORT_CLOSE_PROXY_H_
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "third_party/blink/renderer/modules/webtransport/web_transport_close_proxy.h"
+
+namespace blink {
+
+// A mock implementation of WebTransportCloseProxy.
+class MockWebTransportCloseProxy : public WebTransportCloseProxy {
+ public:
+ // Constructor and destructor are out-of-line to reduce compile time:
+ // https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#making-the-compilation-faster.
+ MockWebTransportCloseProxy();
+ ~MockWebTransportCloseProxy() override;
+
+ MOCK_METHOD1(OnIncomingStreamClosed, void(bool));
+ MOCK_METHOD0(SendFin, void());
+ MOCK_METHOD0(ForgetStream, void());
+ MOCK_METHOD0(Reset, void());
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBTRANSPORT_MOCK_WEB_TRANSPORT_CLOSE_PROXY_H_
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.cc b/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.cc
new file mode 100644
index 00000000000..6b45c978ced
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.cc
@@ -0,0 +1,412 @@
+// 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/webtransport/outgoing_stream.h"
+
+#include <string.h>
+#include <utility>
+
+#include "base/allocator/partition_allocator/partition_alloc.h"
+#include "base/numerics/safe_conversions.h"
+#include "mojo/public/cpp/system/simple_watcher.h"
+#include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_stream_abort_info.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/streams/underlying_sink_base.h"
+#include "third_party/blink/renderer/core/streams/writable_stream.h"
+#include "third_party/blink/renderer/modules/webtransport/web_transport_close_proxy.h"
+#include "third_party/blink/renderer/platform/bindings/exception_code.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/heap/heap.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/functional.h"
+
+namespace blink {
+
+class OutgoingStream::UnderlyingSink final : public UnderlyingSinkBase {
+ public:
+ explicit UnderlyingSink(OutgoingStream* outgoing_stream)
+ : outgoing_stream_(outgoing_stream) {}
+
+ // Implementation of UnderlyingSinkBase
+ ScriptPromise start(ScriptState* script_state,
+ WritableStreamDefaultController* controller,
+ ExceptionState&) override {
+ DVLOG(1) << "OutgoingStream::UnderlyinkSink::start() outgoing_stream_="
+ << outgoing_stream_;
+
+ outgoing_stream_->controller_ = controller;
+ return ScriptPromise::CastUndefined(script_state);
+ }
+
+ ScriptPromise write(ScriptState* script_state,
+ ScriptValue chunk,
+ WritableStreamDefaultController*,
+ ExceptionState& exception_state) override {
+ DVLOG(1) << "OutgoingStream::UnderlyingSink::write() outgoing_stream_="
+ << outgoing_stream_;
+
+ // OutgoingStream::SinkWrite() is a separate method rather than being
+ // inlined here because it makes many accesses to outgoing_stream_ member
+ // variables.
+ return outgoing_stream_->SinkWrite(script_state, chunk, exception_state);
+ }
+
+ ScriptPromise close(ScriptState* script_state, ExceptionState&) override {
+ DVLOG(1) << "OutgoingStream::UnderlingSink::close() outgoing_stream_="
+ << outgoing_stream_;
+
+ // The specification guarantees that this will only be called after all
+ // pending writes have been completed.
+ DCHECK(!outgoing_stream_->write_promise_resolver_);
+
+ outgoing_stream_->close_proxy_->SendFin();
+
+ outgoing_stream_->AbortAndReset();
+
+ // TODO(ricea): close() should wait for data to be flushed before resolving.
+ // Since DataPipeProducerHandle doesn't have an API to observe the remote
+ // side closing, this will have to be done out-of-band.
+ return ScriptPromise::CastUndefined(script_state);
+ }
+
+ ScriptPromise abort(ScriptState* script_state,
+ ScriptValue reason,
+ ExceptionState& exception_state) override {
+ DVLOG(1) << "OutgoingStream::UnderlyingSink::abort() outgoing_stream_="
+ << outgoing_stream_;
+
+ return close(script_state, exception_state);
+ }
+
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(outgoing_stream_);
+ UnderlyingSinkBase::Trace(visitor);
+ }
+
+ private:
+ const Member<OutgoingStream> outgoing_stream_;
+};
+
+OutgoingStream::CachedDataBuffer::CachedDataBuffer(v8::Isolate* isolate,
+ const uint8_t* data,
+ size_t length)
+ : isolate_(isolate), length_(length) {
+ // We use the BufferPartition() allocator here to allow big enough
+ // allocations, and to do proper accounting of the used memory. If
+ // BufferPartition() will ever not be able to provide big enough allocations,
+ // e.g. because bigger ArrayBuffers get supported, then we have to switch to
+ // another allocator, e.g. the ArrayBuffer allocator.
+ buffer_ = reinterpret_cast<uint8_t*>(
+ WTF::Partitions::BufferPartition()->Alloc(length, "OutgoingStream"));
+ memcpy(buffer_, data, length);
+ isolate_->AdjustAmountOfExternalAllocatedMemory(static_cast<int64_t>(length));
+}
+
+OutgoingStream::CachedDataBuffer::~CachedDataBuffer() {
+ WTF::Partitions::BufferPartition()->Free(buffer_);
+ isolate_->AdjustAmountOfExternalAllocatedMemory(
+ -static_cast<int64_t>(length_));
+}
+
+OutgoingStream::OutgoingStream(ScriptState* script_state,
+ WebTransportCloseProxy* close_proxy,
+ mojo::ScopedDataPipeProducerHandle handle)
+ : ExecutionContextLifecycleObserver(ExecutionContext::From(script_state)),
+ script_state_(script_state),
+ close_proxy_(close_proxy),
+ data_pipe_(std::move(handle)),
+ write_watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL),
+ close_watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC) {}
+
+OutgoingStream::~OutgoingStream() = default;
+
+void OutgoingStream::Init() {
+ DVLOG(1) << "OutgoingStream::Init() this=" << this;
+
+ write_watcher_.Watch(data_pipe_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
+ MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED,
+ WTF::BindRepeating(&OutgoingStream::OnHandleReady,
+ WrapWeakPersistent(this)));
+ close_watcher_.Watch(data_pipe_.get(), MOJO_HANDLE_SIGNAL_PEER_CLOSED,
+ MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED,
+ WTF::BindRepeating(&OutgoingStream::OnPeerClosed,
+ WrapWeakPersistent(this)));
+
+ // TODO(ricea): How do we make sure this promise is settled or detached before
+ // it is destroyed?
+ writing_aborted_resolver_ =
+ MakeGarbageCollected<ScriptPromiseResolver>(script_state_);
+ writing_aborted_ = writing_aborted_resolver_->Promise();
+ writable_ = WritableStream::CreateWithCountQueueingStrategy(
+ script_state_, MakeGarbageCollected<UnderlyingSink>(this), 1);
+}
+
+void OutgoingStream::abortWriting() {
+ abortWriting(StreamAbortInfo::Create());
+}
+
+void OutgoingStream::abortWriting(StreamAbortInfo* stream_abort_info) {
+ DVLOG(1) << "OutgoingStream::abortWriting() this=" << this;
+
+ ErrorStreamAbortAndReset(IsLocalAbort(true));
+}
+
+void OutgoingStream::Reset() {
+ DVLOG(1) << "OutgoingStream::Reset() this=" << this;
+
+ ErrorStreamAbortAndReset(IsLocalAbort(false));
+}
+
+void OutgoingStream::ContextDestroyed() {
+ DVLOG(1) << "OutgoingStream::ContextDestroyed() this=" << this;
+
+ ResetPipe();
+}
+
+void OutgoingStream::Trace(Visitor* visitor) {
+ visitor->Trace(script_state_);
+ visitor->Trace(close_proxy_);
+ visitor->Trace(writable_);
+ visitor->Trace(controller_);
+ visitor->Trace(writing_aborted_);
+ visitor->Trace(writing_aborted_resolver_);
+ visitor->Trace(write_promise_resolver_);
+ ScriptWrappable::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
+}
+
+void OutgoingStream::OnHandleReady(MojoResult result,
+ const mojo::HandleSignalsState&) {
+ DVLOG(1) << "OutgoingStream::OnHandleReady() this=" << this
+ << " result=" << result;
+
+ switch (result) {
+ case MOJO_RESULT_OK:
+ WriteCachedData();
+ break;
+ case MOJO_RESULT_FAILED_PRECONDITION:
+ HandlePipeClosed();
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
+void OutgoingStream::OnPeerClosed(MojoResult result,
+ const mojo::HandleSignalsState&) {
+ DVLOG(1) << "OutgoingStream::OnPeerClosed() this=" << this
+ << " result=" << result;
+
+ switch (result) {
+ case MOJO_RESULT_OK:
+ HandlePipeClosed();
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
+void OutgoingStream::HandlePipeClosed() {
+ DVLOG(1) << "OutgoingStream::HandlePipeClosed() this=" << this;
+
+ ErrorStreamAbortAndReset(IsLocalAbort(false));
+}
+
+ScriptPromise OutgoingStream::SinkWrite(ScriptState* script_state,
+ ScriptValue chunk,
+ ExceptionState& exception_state) {
+ DVLOG(1) << "OutgoingStream::SinkWrite() this=" << this;
+
+ // There can only be one call to write() in progress at a time.
+ DCHECK(!write_promise_resolver_);
+ DCHECK_EQ(0u, offset_);
+
+ auto* isolate = script_state->GetIsolate();
+
+ ArrayBufferOrArrayBufferView buffer_source;
+ V8ArrayBufferOrArrayBufferView::ToImpl(
+ isolate, chunk.V8Value(), buffer_source,
+ UnionTypeConversionMode::kNotNullable, exception_state);
+ if (exception_state.HadException())
+ return ScriptPromise();
+
+ DCHECK(!buffer_source.IsNull());
+
+ // |data| will not be valid when this function returns.
+ base::span<const uint8_t> data;
+ if (buffer_source.IsArrayBuffer()) {
+ const auto* array_buffer = buffer_source.GetAsArrayBuffer();
+ data = base::span<const uint8_t>(
+ static_cast<const uint8_t*>(array_buffer->Data()),
+ array_buffer->ByteLengthAsSizeT());
+ } else {
+ DCHECK(buffer_source.IsArrayBufferView());
+ const auto* array_buffer_view = buffer_source.GetAsArrayBufferView().View();
+ data = base::span<const uint8_t>(
+ static_cast<const uint8_t*>(array_buffer_view->BaseAddress()),
+ array_buffer_view->byteLengthAsSizeT());
+ }
+
+ if (!data_pipe_) {
+ return ScriptPromise::Reject(script_state,
+ CreateAbortException(IsLocalAbort(false)));
+ }
+
+ return WriteOrCacheData(script_state, data);
+}
+
+// Attempt to write |data|. Cache anything that could not be written
+// synchronously. Arrange for the cached data to be written asynchronously.
+ScriptPromise OutgoingStream::WriteOrCacheData(ScriptState* script_state,
+ base::span<const uint8_t> data) {
+ DVLOG(1) << "OutgoingStream::WriteOrCacheData() this=" << this << " data=("
+ << data.data() << ", " << data.size() << ")";
+ size_t written = WriteDataSynchronously(data);
+
+ if (written == data.size())
+ return ScriptPromise::CastUndefined(script_state);
+
+ DCHECK_LT(written, data.size());
+
+ if (!data_pipe_) {
+ return ScriptPromise::Reject(script_state,
+ CreateAbortException(IsLocalAbort(false)));
+ }
+
+ DCHECK(!cached_data_);
+ cached_data_ = std::make_unique<CachedDataBuffer>(
+ script_state->GetIsolate(), data.data() + written, data.size() - written);
+ DCHECK_EQ(offset_, 0u);
+ write_watcher_.ArmOrNotify();
+ write_promise_resolver_ =
+ MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ return write_promise_resolver_->Promise();
+}
+
+// Write data previously cached. Arrange for any remaining data to be sent
+// asynchronously. Fulfill |write_promise_resolver_| once all data has been
+// written.
+void OutgoingStream::WriteCachedData() {
+ DVLOG(1) << "OutgoingStream::WriteCachedData() this=" << this;
+
+ auto data = base::make_span(static_cast<uint8_t*>(cached_data_->data()),
+ cached_data_->length())
+ .subspan(offset_);
+ size_t written = WriteDataSynchronously(data);
+
+ if (written == data.size()) {
+ ScriptState::Scope scope(script_state_);
+
+ cached_data_.reset();
+ offset_ = 0;
+ write_promise_resolver_->Resolve();
+ write_promise_resolver_ = nullptr;
+ return;
+ }
+
+ if (!data_pipe_) {
+ cached_data_.reset();
+ offset_ = 0;
+
+ return;
+ }
+
+ offset_ += written;
+
+ write_watcher_.ArmOrNotify();
+}
+
+// Write as much of |data| as can be written synchronously. Return the number of
+// bytes written. May close |data_pipe_| as a side-effect on error.
+size_t OutgoingStream::WriteDataSynchronously(base::span<const uint8_t> data) {
+ DVLOG(1) << "OutgoingStream::WriteDataSynchronously() this=" << this
+ << " data=(" << data.data() << ", " << data.size() << ")";
+ DCHECK(data_pipe_);
+
+ // This use of saturated cast means that we will fallback to asynchronous
+ // sending if |data| is larger than 4GB. In practice we'd never be able to
+ // send 4GB synchronously anyway.
+ uint32_t num_bytes = base::saturated_cast<uint32_t>(data.size());
+ MojoResult result =
+ data_pipe_->WriteData(data.data(), &num_bytes, MOJO_WRITE_DATA_FLAG_NONE);
+ switch (result) {
+ case MOJO_RESULT_OK:
+ case MOJO_RESULT_SHOULD_WAIT:
+ return num_bytes;
+
+ case MOJO_RESULT_FAILED_PRECONDITION:
+ HandlePipeClosed();
+ return 0;
+
+ default:
+ NOTREACHED();
+ return 0;
+ }
+}
+
+ScriptValue OutgoingStream::CreateAbortException(IsLocalAbort is_local_abort) {
+ DVLOG(1) << "OutgoingStream::CreateAbortException() this=" << this
+ << " is_local_abort=" << static_cast<bool>(is_local_abort);
+
+ DOMExceptionCode code = is_local_abort ? DOMExceptionCode::kAbortError
+ : DOMExceptionCode::kNetworkError;
+ String message =
+ String::Format("The stream was aborted %s",
+ is_local_abort ? "locally" : "by the remote server");
+
+ return ScriptValue(script_state_->GetIsolate(),
+ V8ThrowDOMException::CreateOrEmpty(
+ script_state_->GetIsolate(), code, message));
+}
+
+void OutgoingStream::ErrorStreamAbortAndReset(IsLocalAbort is_local_abort) {
+ DVLOG(1) << "OutgoingStream::ErrorStreamAbortAndReset() this=" << this;
+
+ ScriptValue exception = CreateAbortException(is_local_abort);
+
+ if (write_promise_resolver_) {
+ write_promise_resolver_->Reject(exception);
+ write_promise_resolver_ = nullptr;
+ controller_ = nullptr;
+ } else if (controller_) {
+ controller_->error(script_state_, exception);
+ controller_ = nullptr;
+ }
+
+ AbortAndReset();
+}
+
+void OutgoingStream::AbortAndReset() {
+ DVLOG(1) << "OutgoingStream::AbortAndReset() this=" << this;
+
+ if (writing_aborted_resolver_) {
+ // TODO(ricea): Set errorCode on the StreamAbortInfo.
+ writing_aborted_resolver_->Resolve(StreamAbortInfo::Create());
+ writing_aborted_resolver_ = nullptr;
+ }
+ ResetPipe();
+}
+
+void OutgoingStream::ResetPipe() {
+ DVLOG(1) << "OutgoingStream::ResetPipe() this=" << this;
+
+ write_watcher_.Cancel();
+ close_watcher_.Cancel();
+ data_pipe_.reset();
+ if (cached_data_)
+ cached_data_.reset();
+}
+
+void OutgoingStream::Dispose() {
+ DVLOG(1) << "OutgoingStream::Dispose() this=" << this;
+
+ ResetPipe();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.h b/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.h
new file mode 100644
index 00000000000..636cf5398fc
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.h
@@ -0,0 +1,182 @@
+// 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_WEBTRANSPORT_OUTGOING_STREAM_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBTRANSPORT_OUTGOING_STREAM_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/containers/span.h"
+#include "base/util/type_safety/strong_alias.h"
+#include "mojo/public/cpp/system/data_pipe.h"
+#include "mojo/public/cpp/system/simple_watcher.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/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/heap/thread_state.h"
+
+namespace v8 {
+class Isolate;
+}
+
+namespace blink {
+
+class ScriptState;
+class StreamAbortInfo;
+class WebTransportCloseProxy;
+class WritableStream;
+class WritableStreamDefaultController;
+
+// Implementation of the OutgoingStream mixin from the standard. SendStream and
+// BidirectionalStream inherit from this.
+class MODULES_EXPORT OutgoingStream
+ : public ScriptWrappable,
+ public ActiveScriptWrappable<OutgoingStream>,
+ public ExecutionContextLifecycleObserver {
+ DEFINE_WRAPPERTYPEINFO();
+ USING_PRE_FINALIZER(OutgoingStream, Dispose);
+ USING_GARBAGE_COLLECTED_MIXIN(OutgoingStream);
+
+ public:
+ OutgoingStream(ScriptState*,
+ WebTransportCloseProxy*,
+ mojo::ScopedDataPipeProducerHandle);
+ ~OutgoingStream() override;
+
+ // Init() must be called before the stream is used.
+ virtual void Init();
+
+ WebTransportCloseProxy* GetWebTransportCloseProxy() { return close_proxy_; }
+
+ // Implementation of outgoing_stream.idl.
+ WritableStream* writable() const {
+ DVLOG(1) << "OutgoingStream::writable() called";
+
+ return writable_;
+ }
+
+ ScriptPromise writingAborted() const { return writing_aborted_; }
+
+ void abortWriting();
+ void abortWriting(StreamAbortInfo*);
+
+ // Called via WebTransportCloseProxy. Expects a JavaScript scope to be
+ // entered.
+ void Reset();
+
+ // OutgoingStream cannot be collected until it is explicitly closed, either
+ // remotely or locally.
+ bool HasPendingActivity() const final { return writing_aborted_resolver_; }
+
+ // Implementation of ExecutionContextLifecycleObserver.
+ void ContextDestroyed() override;
+
+ void Trace(Visitor*) override;
+
+ private:
+ class UnderlyingSink;
+
+ using IsLocalAbort = util::StrongAlias<class IsLocalAbortTag, bool>;
+
+ // Called when |data_pipe_| becomes writable or errored.
+ void OnHandleReady(MojoResult, const mojo::HandleSignalsState&);
+
+ // Called when |data_pipe_| is closed.
+ void OnPeerClosed(MojoResult, const mojo::HandleSignalsState&);
+
+ // Rejects any unfinished write() calls and resets |data_pipe_|.
+ void HandlePipeClosed();
+
+ // Implements UnderlyingSink::write().
+ ScriptPromise SinkWrite(ScriptState*, ScriptValue chunk, ExceptionState&);
+
+ // Writes |data| to |data_pipe_|, possible saving unwritten data to
+ // |cached_data_|.
+ ScriptPromise WriteOrCacheData(ScriptState*, base::span<const uint8_t> data);
+
+ // Attempts to write some more of |cached_data_| to |data_pipe_|.
+ void WriteCachedData();
+
+ // Writes zero or more bytes of |data| synchronously to |data_pipe_|,
+ // returning the number of bytes that were written.
+ size_t WriteDataSynchronously(base::span<const uint8_t> data);
+
+ // Creates a DOMException indicating that the stream has been aborted.
+ // If IsLocalAbort it true it will indicate a locally-initiated abort,
+ // otherwise it will indicate a remote-initiated abort.
+ ScriptValue CreateAbortException(IsLocalAbort);
+
+ // Errors |writable_|, resolves |writing_aborted_| and resets |data_pipe_|.
+ // The error message used to error |writable_| depends on whether IsLocalAbort
+ // is true or not.
+ void ErrorStreamAbortAndReset(IsLocalAbort);
+
+ // Resolve the |writing_aborted_| promise and reset the |data_pipe_|.
+ void AbortAndReset();
+
+ // Resets |data_pipe_| and clears the watchers. Also discards |cached_data_|.
+ // If the pipe is open it will be closed as a side-effect.
+ void ResetPipe();
+
+ // Prepares the object for destruction.
+ void Dispose();
+
+ class CachedDataBuffer {
+ public:
+ CachedDataBuffer(v8::Isolate* isolate, const uint8_t* data, size_t length);
+
+ ~CachedDataBuffer();
+
+ size_t length() const { return length_; }
+
+ uint8_t* data() { return buffer_; }
+
+ private:
+ // We need the isolate to call |AdjustAmountOfExternalAllocatedMemory| for
+ // the memory stored in |buffer_|.
+ v8::Isolate* isolate_;
+ size_t length_ = 0u;
+ uint8_t* buffer_ = nullptr;
+ };
+
+ const Member<ScriptState> script_state_;
+ const Member<WebTransportCloseProxy> close_proxy_;
+ mojo::ScopedDataPipeProducerHandle data_pipe_;
+
+ // Only armed when we need to write something.
+ mojo::SimpleWatcher write_watcher_;
+
+ // Always armed to detect close.
+ mojo::SimpleWatcher close_watcher_;
+
+ // Data which has been passed to write() but still needs to be written
+ // asynchronously.
+ // Uses a custom CachedDataBuffer rather than a Vector because
+ // WTF::Vector is currently limited to 2GB.
+ // TODO(ricea): Change this to a Vector when it becomes 64-bit safe.
+ std::unique_ptr<CachedDataBuffer> cached_data_;
+
+ // The offset into |cached_data_| of the first byte that still needs to be
+ // written.
+ size_t offset_ = 0;
+
+ Member<WritableStream> writable_;
+ Member<WritableStreamDefaultController> controller_;
+
+ // Promise returned by the |writingAborted| attribute.
+ ScriptPromise writing_aborted_;
+ Member<ScriptPromiseResolver> writing_aborted_resolver_;
+
+ // If an asynchronous write() on the underlying sink object is pending, this
+ // will be non-null.
+ Member<ScriptPromiseResolver> write_promise_resolver_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBTRANSPORT_OUTGOING_STREAM_H_
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.idl b/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.idl
new file mode 100644
index 00000000000..8ac1625e5da
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.idl
@@ -0,0 +1,12 @@
+// 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/#outgoingstream
+
+[ActiveScriptWrappable]
+interface mixin OutgoingStream {
+ readonly attribute WritableStream writable;
+ readonly attribute Promise<StreamAbortInfo> writingAborted;
+ void abortWriting(optional StreamAbortInfo abortInfo);
+};
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream_test.cc b/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream_test.cc
new file mode 100644
index 00000000000..956f8acea17
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream_test.cc
@@ -0,0 +1,419 @@
+// 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/webtransport/outgoing_stream.h"
+
+#include <utility>
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_tester.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h"
+#include "third_party/blink/renderer/core/dom/dom_exception.h"
+#include "third_party/blink/renderer/core/streams/writable_stream.h"
+#include "third_party/blink/renderer/core/streams/writable_stream_default_writer.h"
+#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
+#include "third_party/blink/renderer/modules/webtransport/mock_web_transport_close_proxy.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+
+namespace blink {
+
+namespace {
+
+using ::testing::ElementsAre;
+using ::testing::StrictMock;
+
+class OutgoingStreamTest : public ::testing::Test {
+ public:
+ // The default value of |capacity| means some sensible value selected by mojo.
+ void CreateDataPipe(uint32_t capacity = 0) {
+ MojoCreateDataPipeOptions options;
+ options.struct_size = sizeof(MojoCreateDataPipeOptions);
+ options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE;
+ options.element_num_bytes = 1;
+ options.capacity_num_bytes = capacity;
+
+ MojoResult result = mojo::CreateDataPipe(&options, &data_pipe_producer_,
+ &data_pipe_consumer_);
+ if (result != MOJO_RESULT_OK) {
+ ADD_FAILURE() << "CreateDataPipe() returned " << result;
+ }
+ }
+
+ OutgoingStream* CreateOutgoingStream(const V8TestingScope& scope,
+ uint32_t capacity = 0) {
+ CreateDataPipe(capacity);
+ auto* script_state = scope.GetScriptState();
+ DCHECK(!mock_close_proxy_);
+ mock_close_proxy_ =
+ MakeGarbageCollected<StrictMock<MockWebTransportCloseProxy>>();
+ auto* outgoing_stream = MakeGarbageCollected<OutgoingStream>(
+ script_state, mock_close_proxy_, std::move(data_pipe_producer_));
+ outgoing_stream->Init();
+ return outgoing_stream;
+ }
+
+ // Reads everything from data_pipe_consumer_ and returns it in a
+ // vector.
+ Vector<uint8_t> ReadAllPendingData() {
+ Vector<uint8_t> data;
+ const void* buffer = nullptr;
+ uint32_t buffer_num_bytes = 0;
+ MojoResult result = data_pipe_consumer_->BeginReadData(
+ &buffer, &buffer_num_bytes, MOJO_BEGIN_READ_DATA_FLAG_NONE);
+
+ switch (result) {
+ case MOJO_RESULT_OK:
+ break;
+
+ case MOJO_RESULT_SHOULD_WAIT: // No more data yet.
+ return data;
+
+ default:
+ ADD_FAILURE() << "BeginReadData() failed: " << result;
+ return data;
+ }
+
+ data.Append(static_cast<const uint8_t*>(buffer), buffer_num_bytes);
+ data_pipe_consumer_->EndReadData(buffer_num_bytes);
+ return data;
+ }
+
+ Persistent<MockWebTransportCloseProxy> mock_close_proxy_;
+ mojo::ScopedDataPipeProducerHandle data_pipe_producer_;
+ mojo::ScopedDataPipeConsumerHandle data_pipe_consumer_;
+};
+
+TEST_F(OutgoingStreamTest, Create) {
+ V8TestingScope scope;
+ auto* outgoing_stream = CreateOutgoingStream(scope);
+ EXPECT_TRUE(outgoing_stream->writable());
+}
+
+TEST_F(OutgoingStreamTest, AbortWriting) {
+ V8TestingScope scope;
+ auto* outgoing_stream = CreateOutgoingStream(scope);
+ auto* script_state = scope.GetScriptState();
+ auto* writer =
+ outgoing_stream->writable()->getWriter(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromise closed_promise = writer->closed(script_state);
+
+ ScriptPromise writing_aborted = outgoing_stream->writingAborted();
+
+ outgoing_stream->abortWriting();
+
+ ScriptPromiseTester abort_tester(script_state, writing_aborted);
+ abort_tester.WaitUntilSettled();
+ EXPECT_TRUE(abort_tester.IsFulfilled());
+
+ ScriptPromiseTester closed_tester(script_state, closed_promise);
+ closed_tester.WaitUntilSettled();
+ EXPECT_TRUE(closed_tester.IsRejected());
+ DOMException* closed_exception = V8DOMException::ToImplWithTypeCheck(
+ scope.GetIsolate(), closed_tester.Value().V8Value());
+ ASSERT_TRUE(closed_exception);
+ EXPECT_EQ(closed_exception->name(), "AbortError");
+ EXPECT_EQ(closed_exception->message(), "The stream was aborted locally");
+}
+
+TEST_F(OutgoingStreamTest, WriteArrayBuffer) {
+ V8TestingScope scope;
+ auto* outgoing_stream = CreateOutgoingStream(scope);
+ auto* script_state = scope.GetScriptState();
+ auto* writer =
+ outgoing_stream->writable()->getWriter(script_state, ASSERT_NO_EXCEPTION);
+ auto* chunk = DOMArrayBuffer::Create("A", 1);
+ ScriptPromise result =
+ writer->write(script_state, ScriptValue::From(script_state, chunk),
+ ASSERT_NO_EXCEPTION);
+ ScriptPromiseTester tester(scope.GetScriptState(), result);
+ tester.WaitUntilSettled();
+ EXPECT_TRUE(tester.IsFulfilled());
+ EXPECT_THAT(ReadAllPendingData(), ElementsAre('A'));
+}
+
+TEST_F(OutgoingStreamTest, WriteArrayBufferView) {
+ V8TestingScope scope;
+ auto* outgoing_stream = CreateOutgoingStream(scope);
+ auto* script_state = scope.GetScriptState();
+ auto* writer =
+ outgoing_stream->writable()->getWriter(script_state, ASSERT_NO_EXCEPTION);
+ auto* buffer = DOMArrayBuffer::Create("*B", 2);
+ // Create a view into the buffer with offset 1, ie. "B".
+ auto* chunk = DOMUint8Array::Create(buffer, 1, 1);
+ ScriptPromise result =
+ writer->write(script_state, ScriptValue::From(script_state, chunk),
+ ASSERT_NO_EXCEPTION);
+ ScriptPromiseTester tester(scope.GetScriptState(), result);
+ tester.WaitUntilSettled();
+ EXPECT_TRUE(tester.IsFulfilled());
+ EXPECT_THAT(ReadAllPendingData(), ElementsAre('B'));
+}
+
+bool IsAllNulls(base::span<const uint8_t> data) {
+ return std::all_of(data.begin(), data.end(), [](uint8_t c) { return !c; });
+}
+
+TEST_F(OutgoingStreamTest, AsyncWrite) {
+ V8TestingScope scope;
+ // Set a large pipe capacity, so any platform-specific excess is dwarfed in
+ // size.
+ constexpr uint32_t kPipeCapacity = 512u * 1024u;
+ auto* outgoing_stream = CreateOutgoingStream(scope, kPipeCapacity);
+
+ auto* script_state = scope.GetScriptState();
+ auto* writer =
+ outgoing_stream->writable()->getWriter(script_state, ASSERT_NO_EXCEPTION);
+
+ // Write a chunk that definitely will not fit in the pipe.
+ const size_t kChunkSize = kPipeCapacity * 3;
+ auto* chunk = DOMArrayBuffer::Create(kChunkSize, 1);
+ ScriptPromise result =
+ writer->write(script_state, ScriptValue::From(script_state, chunk),
+ ASSERT_NO_EXCEPTION);
+ ScriptPromiseTester tester(scope.GetScriptState(), result);
+
+ // Let the first pipe write complete.
+ test::RunPendingTasks();
+
+ // Let microtasks run just in case write() returns prematurely.
+ v8::MicrotasksScope::PerformCheckpoint(scope.GetIsolate());
+ EXPECT_FALSE(tester.IsFulfilled());
+
+ // Read the first part of the data.
+ auto data1 = ReadAllPendingData();
+ EXPECT_LT(data1.size(), kChunkSize);
+
+ // Verify the data wasn't corrupted.
+ EXPECT_TRUE(IsAllNulls(data1));
+
+ // Allow the asynchronous pipe write to happen.
+ test::RunPendingTasks();
+
+ // Read the second part of the data.
+ auto data2 = ReadAllPendingData();
+ EXPECT_TRUE(IsAllNulls(data2));
+
+ test::RunPendingTasks();
+
+ // Read the final part of the data.
+ auto data3 = ReadAllPendingData();
+ EXPECT_TRUE(IsAllNulls(data3));
+ EXPECT_EQ(data1.size() + data2.size() + data3.size(), kChunkSize);
+
+ // Now the write() should settle.
+ tester.WaitUntilSettled();
+ EXPECT_TRUE(tester.IsFulfilled());
+
+ // Nothing should be left to read.
+ EXPECT_THAT(ReadAllPendingData(), ElementsAre());
+}
+
+// Writing immediately followed by closing should not lose data.
+TEST_F(OutgoingStreamTest, WriteThenClose) {
+ V8TestingScope scope;
+
+ auto* outgoing_stream = CreateOutgoingStream(scope);
+ auto* script_state = scope.GetScriptState();
+ auto* writer =
+ outgoing_stream->writable()->getWriter(script_state, ASSERT_NO_EXCEPTION);
+ auto* chunk = DOMArrayBuffer::Create("D", 1);
+ ScriptPromise write_promise =
+ writer->write(script_state, ScriptValue::From(script_state, chunk),
+ ASSERT_NO_EXCEPTION);
+
+ EXPECT_CALL(*mock_close_proxy_, SendFin());
+
+ ScriptPromise close_promise =
+ writer->close(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromiseTester write_tester(scope.GetScriptState(), write_promise);
+ ScriptPromiseTester close_tester(scope.GetScriptState(), close_promise);
+
+ // Make sure that write() and close() both run before the event loop is
+ // serviced.
+ v8::MicrotasksScope::PerformCheckpoint(scope.GetIsolate());
+
+ write_tester.WaitUntilSettled();
+ EXPECT_TRUE(write_tester.IsFulfilled());
+ close_tester.WaitUntilSettled();
+ EXPECT_TRUE(close_tester.IsFulfilled());
+
+ EXPECT_THAT(ReadAllPendingData(), ElementsAre('D'));
+}
+
+// A live stream will be kept alive even if there is no explicit reference.
+// When the underlying connection is shut down, the connection will be swept.
+TEST_F(OutgoingStreamTest, GarbageCollection) {
+ V8TestingScope scope;
+
+ WeakPersistent<OutgoingStream> outgoing_stream;
+
+ {
+ // The writable stream created when creating a OutgoingStream creates some
+ // v8 handles. To ensure these are collected, we need to create a handle
+ // scope. This is not a problem for garbage collection in normal operation.
+ v8::HandleScope handle_scope(scope.GetIsolate());
+
+ outgoing_stream = CreateOutgoingStream(scope);
+ }
+
+ // Pretend the stack is empty. This will avoid accidentally treating any
+ // copies of the |outgoing_stream| pointer as references.
+ V8GCController::CollectAllGarbageForTesting(
+ scope.GetIsolate(), v8::EmbedderHeapTracer::EmbedderStackState::kEmpty);
+
+ ASSERT_TRUE(outgoing_stream);
+
+ auto* script_state = scope.GetScriptState();
+
+ EXPECT_CALL(*mock_close_proxy_, SendFin());
+
+ ScriptPromise close_promise =
+ outgoing_stream->writable()->close(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromiseTester tester(script_state, close_promise);
+ tester.WaitUntilSettled();
+ EXPECT_TRUE(tester.IsFulfilled());
+
+ V8GCController::CollectAllGarbageForTesting(
+ scope.GetIsolate(), v8::EmbedderHeapTracer::EmbedderStackState::kEmpty);
+
+ EXPECT_FALSE(outgoing_stream);
+}
+
+TEST_F(OutgoingStreamTest, GarbageCollectionRemoteClose) {
+ V8TestingScope scope;
+
+ WeakPersistent<OutgoingStream> outgoing_stream;
+
+ {
+ v8::HandleScope handle_scope(scope.GetIsolate());
+
+ outgoing_stream = CreateOutgoingStream(scope);
+ }
+
+ V8GCController::CollectAllGarbageForTesting(
+ scope.GetIsolate(), v8::EmbedderHeapTracer::EmbedderStackState::kEmpty);
+
+ ASSERT_TRUE(outgoing_stream);
+
+ // Close the other end of the pipe.
+ data_pipe_consumer_.reset();
+
+ test::RunPendingTasks();
+
+ V8GCController::CollectAllGarbageForTesting(
+ scope.GetIsolate(), v8::EmbedderHeapTracer::EmbedderStackState::kEmpty);
+
+ EXPECT_FALSE(outgoing_stream);
+}
+
+TEST_F(OutgoingStreamTest, DataPipeClosed) {
+ V8TestingScope scope;
+
+ auto* outgoing_stream = CreateOutgoingStream(scope);
+ auto* script_state = scope.GetScriptState();
+
+ ScriptPromise writing_aborted = outgoing_stream->writingAborted();
+ ScriptPromiseTester writing_aborted_tester(script_state, writing_aborted);
+
+ auto* writer =
+ outgoing_stream->writable()->getWriter(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromise closed = writer->closed(script_state);
+ ScriptPromiseTester closed_tester(script_state, closed);
+
+ // Close the other end of the pipe.
+ data_pipe_consumer_.reset();
+
+ writing_aborted_tester.WaitUntilSettled();
+ EXPECT_TRUE(writing_aborted_tester.IsFulfilled());
+
+ closed_tester.WaitUntilSettled();
+ EXPECT_TRUE(closed_tester.IsRejected());
+
+ DOMException* closed_exception = V8DOMException::ToImplWithTypeCheck(
+ scope.GetIsolate(), closed_tester.Value().V8Value());
+ ASSERT_TRUE(closed_exception);
+ EXPECT_EQ(closed_exception->name(), "NetworkError");
+ EXPECT_EQ(closed_exception->message(),
+ "The stream was aborted by the remote server");
+
+ auto* chunk = DOMArrayBuffer::Create('C', 1);
+ ScriptPromise result =
+ writer->write(script_state, ScriptValue::From(script_state, chunk),
+ ASSERT_NO_EXCEPTION);
+ ScriptPromiseTester write_tester(script_state, result);
+ write_tester.WaitUntilSettled();
+
+ EXPECT_TRUE(write_tester.IsRejected());
+
+ DOMException* write_exception = V8DOMException::ToImplWithTypeCheck(
+ scope.GetIsolate(), write_tester.Value().V8Value());
+ ASSERT_TRUE(write_exception);
+ EXPECT_EQ(write_exception->name(), "NetworkError");
+ EXPECT_EQ(write_exception->message(),
+ "The stream was aborted by the remote server");
+}
+
+TEST_F(OutgoingStreamTest, DataPipeClosedDuringAsyncWrite) {
+ V8TestingScope scope;
+
+ constexpr uint32_t kPipeCapacity = 512 * 1024;
+ auto* outgoing_stream = CreateOutgoingStream(scope, kPipeCapacity);
+
+ auto* script_state = scope.GetScriptState();
+
+ ScriptPromise writing_aborted = outgoing_stream->writingAborted();
+ ScriptPromiseTester writing_aborted_tester(script_state, writing_aborted);
+
+ auto* writer =
+ outgoing_stream->writable()->getWriter(script_state, ASSERT_NO_EXCEPTION);
+
+ const size_t kChunkSize = kPipeCapacity * 2;
+ auto* chunk = DOMArrayBuffer::Create(kChunkSize, 1);
+ ScriptPromise result =
+ writer->write(script_state, ScriptValue::From(script_state, chunk),
+ ASSERT_NO_EXCEPTION);
+ ScriptPromiseTester write_tester(script_state, result);
+
+ ScriptPromise closed = writer->closed(script_state);
+ ScriptPromiseTester closed_tester(script_state, closed);
+
+ // Close the other end of the pipe.
+ data_pipe_consumer_.reset();
+
+ write_tester.WaitUntilSettled();
+
+ EXPECT_TRUE(write_tester.IsRejected());
+
+ DOMException* write_exception = V8DOMException::ToImplWithTypeCheck(
+ scope.GetIsolate(), write_tester.Value().V8Value());
+ ASSERT_TRUE(write_exception);
+ EXPECT_EQ(write_exception->name(), "NetworkError");
+ EXPECT_EQ(write_exception->message(),
+ "The stream was aborted by the remote server");
+
+ closed_tester.WaitUntilSettled();
+
+ EXPECT_TRUE(closed_tester.IsRejected());
+
+ DOMException* closed_exception = V8DOMException::ToImplWithTypeCheck(
+ scope.GetIsolate(), write_tester.Value().V8Value());
+ ASSERT_TRUE(closed_exception);
+ EXPECT_EQ(closed_exception->name(), "NetworkError");
+ EXPECT_EQ(closed_exception->message(),
+ "The stream was aborted by the remote server");
+
+ writing_aborted_tester.WaitUntilSettled();
+
+ EXPECT_TRUE(writing_aborted_tester.IsFulfilled());
+}
+
+} // namespace
+
+} // namespace blink
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 114c9bac27d..bb5f950c836 100644
--- a/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.cc
+++ b/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.cc
@@ -4,21 +4,231 @@
#include "third_party/blink/renderer/modules/webtransport/quic_transport.h"
+#include <stdint.h>
+
#include <utility>
+#include "base/numerics/safe_conversions.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/webtransport/quic_transport_connector.mojom-blink.h"
#include "third_party/blink/public/platform/task_type.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#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/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"
+#include "third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.h"
+#include "third_party/blink/renderer/core/streams/underlying_sink_base.h"
+#include "third_party/blink/renderer/core/streams/underlying_source_base.h"
+#include "third_party/blink/renderer/core/streams/writable_stream.h"
+#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
+#include "third_party/blink/renderer/modules/webtransport/receive_stream.h"
+#include "third_party/blink/renderer/modules/webtransport/send_stream.h"
+#include "third_party/blink/renderer/modules/webtransport/web_transport_close_proxy.h"
#include "third_party/blink/renderer/platform/bindings/exception_code.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/heap/persistent.h"
+#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"
namespace blink {
+// Sends a datagram on write().
+class QuicTransport::DatagramUnderlyingSink final : public UnderlyingSinkBase {
+ public:
+ explicit DatagramUnderlyingSink(QuicTransport* quic_transport)
+ : quic_transport_(quic_transport) {}
+
+ ScriptPromise start(ScriptState* script_state,
+ WritableStreamDefaultController*,
+ ExceptionState&) override {
+ return ScriptPromise::CastUndefined(script_state);
+ }
+
+ ScriptPromise write(ScriptState* script_state,
+ ScriptValue chunk,
+ WritableStreamDefaultController*,
+ ExceptionState& exception_state) override {
+ auto v8chunk = chunk.V8Value();
+ if (v8chunk->IsArrayBuffer()) {
+ DOMArrayBuffer* data =
+ V8ArrayBuffer::ToImpl(v8chunk.As<v8::ArrayBuffer>());
+ return SendDatagram({static_cast<const uint8_t*>(data->Data()),
+ data->ByteLengthAsSizeT()});
+ }
+
+ auto* isolate = script_state->GetIsolate();
+ if (v8chunk->IsArrayBufferView()) {
+ NotShared<DOMArrayBufferView> data =
+ ToNotShared<NotShared<DOMArrayBufferView>>(isolate, v8chunk,
+ exception_state);
+ if (exception_state.HadException()) {
+ return ScriptPromise();
+ }
+
+ return SendDatagram(
+ {static_cast<const uint8_t*>(data.View()->buffer()->Data()) +
+ data.View()->byteOffsetAsSizeT(),
+ data.View()->byteLengthAsSizeT()});
+ }
+
+ exception_state.ThrowTypeError(
+ "Datagram is not an ArrayBuffer or ArrayBufferView type.");
+ return ScriptPromise();
+ }
+
+ ScriptPromise close(ScriptState* script_state, ExceptionState&) override {
+ quic_transport_ = nullptr;
+ return ScriptPromise::CastUndefined(script_state);
+ }
+
+ ScriptPromise abort(ScriptState* script_state,
+ ScriptValue reason,
+ ExceptionState&) override {
+ quic_transport_ = nullptr;
+ return ScriptPromise::CastUndefined(script_state);
+ }
+
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(quic_transport_);
+ UnderlyingSinkBase::Trace(visitor);
+ }
+
+ private:
+ ScriptPromise SendDatagram(base::span<const uint8_t> data) {
+ if (!quic_transport_->quic_transport_) {
+ // Silently drop the datagram if we are not connected.
+ // TODO(ricea): Change the behaviour if the standard changes. See
+ // https://github.com/WICG/web-transport/issues/93.
+ return ScriptPromise::CastUndefined(quic_transport_->script_state_);
+ }
+
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(
+ quic_transport_->script_state_);
+ quic_transport_->quic_transport_->SendDatagram(
+ data, WTF::Bind(&DatagramSent, WrapPersistent(resolver)));
+ return resolver->Promise();
+ }
+
+ // |sent| indicates whether the datagram was sent or dropped. Currently we
+ // |don't do anything with this information.
+ static void DatagramSent(ScriptPromiseResolver* resolver, bool sent) {
+ resolver->Resolve();
+ }
+
+ Member<QuicTransport> quic_transport_;
+};
+
+// Captures a pointer to the ReadableStreamDefaultControllerWithScriptScope in
+// the Start() method, and then does nothing else. Queuing of received datagrams
+// is done inside the implementation of QuicTransport.
+class QuicTransport::DatagramUnderlyingSource final
+ : public UnderlyingSourceBase {
+ public:
+ DatagramUnderlyingSource(ScriptState* script_state,
+ QuicTransport* quic_transport)
+ : UnderlyingSourceBase(script_state), quic_transport_(quic_transport) {}
+
+ ScriptPromise Start(ScriptState* script_state) override {
+ quic_transport_->received_datagrams_controller_ = Controller();
+ return ScriptPromise::CastUndefined(script_state);
+ }
+
+ ScriptPromise pull(ScriptState* script_state) override {
+ return ScriptPromise::CastUndefined(script_state);
+ }
+
+ ScriptPromise Cancel(ScriptState* script_state, ScriptValue reason) override {
+ // Stop Enqueue() from being called again.
+
+ quic_transport_->received_datagrams_controller_->NoteHasBeenCanceled();
+ quic_transport_->received_datagrams_controller_ = nullptr;
+ quic_transport_ = nullptr;
+ return ScriptPromise::CastUndefined(script_state);
+ }
+
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(quic_transport_);
+ UnderlyingSourceBase::Trace(visitor);
+ }
+
+ private:
+ Member<QuicTransport> quic_transport_;
+};
+
+class QuicTransport::ReceivedStreamsUnderlyingSource final
+ : public UnderlyingSourceBase {
+ public:
+ ReceivedStreamsUnderlyingSource(ScriptState* script_state,
+ QuicTransport* quic_transport)
+ : UnderlyingSourceBase(script_state),
+ script_state_(script_state),
+ quic_transport_(quic_transport) {}
+
+ ScriptPromise pull(ScriptState* script_state) override {
+ if (!is_opened_) {
+ is_pull_waiting_ = true;
+ return ScriptPromise::CastUndefined(script_state);
+ }
+
+ quic_transport_->quic_transport_->AcceptUnidirectionalStream(WTF::Bind(
+ &ReceivedStreamsUnderlyingSource::OnAcceptUnidirectionalStreamResponse,
+ WrapWeakPersistent(this)));
+
+ return ScriptPromise::CastUndefined(script_state);
+ }
+
+ // Used by QuicTransport to error the stream.
+ void Error(v8::Local<v8::Value> reason) { Controller()->Error(reason); }
+
+ // Used by QuicTransport to close the stream.
+ void Close() { Controller()->Close(); }
+
+ // Used by QuicTransport to notify that the QuicTransport interface is
+ // available.
+ void NotifyOpened() {
+ is_opened_ = true;
+
+ if (is_pull_waiting_) {
+ ScriptState::Scope scope(script_state_);
+ pull(script_state_);
+ is_pull_waiting_ = false;
+ }
+ }
+
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(script_state_);
+ visitor->Trace(quic_transport_);
+ UnderlyingSourceBase::Trace(visitor);
+ }
+
+ private:
+ void OnAcceptUnidirectionalStreamResponse(
+ uint32_t stream_id,
+ mojo::ScopedDataPipeConsumerHandle readable) {
+ ScriptState::Scope scope(script_state_);
+ auto* receive_stream = MakeGarbageCollected<ReceiveStream>(
+ script_state_, quic_transport_, stream_id, std::move(readable));
+ receive_stream->Init();
+ // 0xfffffffe and 0xffffffff are reserved values in stream_map_.
+ CHECK_LT(stream_id, 0xfffffffe);
+ quic_transport_->stream_map_.insert(
+ stream_id, receive_stream->GetWebTransportCloseProxy());
+
+ Controller()->Enqueue(receive_stream);
+ }
+
+ const Member<ScriptState> script_state_;
+ const Member<QuicTransport> quic_transport_;
+ bool is_opened_ = false;
+ bool is_pull_waiting_ = false;
+};
+
QuicTransport* QuicTransport::Create(ScriptState* script_state,
const String& url,
ExceptionState& exception_state) {
@@ -32,13 +242,81 @@ QuicTransport* QuicTransport::Create(ScriptState* script_state,
QuicTransport::QuicTransport(PassKey,
ScriptState* script_state,
const String& url)
- : ContextLifecycleObserver(ExecutionContext::From(script_state)),
+ : ExecutionContextLifecycleObserver(ExecutionContext::From(script_state)),
+ script_state_(script_state),
url_(NullURL(), url) {}
+ScriptPromise QuicTransport::createSendStream(ScriptState* script_state,
+ ExceptionState& exception_state) {
+ DVLOG(1) << "QuicTransport::createSendStream() this=" << this;
+
+ if (!quic_transport_) {
+ // TODO(ricea): Should we wait if we're still connecting?
+ exception_state.ThrowDOMException(DOMExceptionCode::kNetworkError,
+ "No connection.");
+ return ScriptPromise();
+ }
+
+ MojoCreateDataPipeOptions options;
+ options.struct_size = sizeof(MojoCreateDataPipeOptions);
+ options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE;
+ options.element_num_bytes = 1;
+ // TODO(ricea): Find an appropriate value for capacity_num_bytes.
+ options.capacity_num_bytes = 0;
+
+ mojo::ScopedDataPipeProducerHandle data_pipe_producer;
+ mojo::ScopedDataPipeConsumerHandle data_pipe_consumer;
+ MojoResult result =
+ mojo::CreateDataPipe(&options, &data_pipe_producer, &data_pipe_consumer);
+ if (result != MOJO_RESULT_OK) {
+ // Probably out of resources.
+ exception_state.ThrowDOMException(DOMExceptionCode::kUnknownError,
+ "Insufficient resources.");
+ return ScriptPromise();
+ }
+
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ create_send_stream_resolvers_.insert(resolver);
+ quic_transport_->CreateStream(
+ std::move(data_pipe_consumer), mojo::ScopedDataPipeProducerHandle(),
+ WTF::Bind(&QuicTransport::OnCreateStreamResponse,
+ WrapWeakPersistent(this), WrapWeakPersistent(resolver),
+ std::move(data_pipe_producer)));
+
+ return resolver->Promise();
+}
+
void QuicTransport::close(const WebTransportCloseInfo* close_info) {
DVLOG(1) << "QuicTransport::close() this=" << this;
// TODO(ricea): Send |close_info| to the network service.
- Dispose();
+
+ if (cleanly_closed_) {
+ // close() has already been called. Ignore it.
+ return;
+ }
+ cleanly_closed_ = true;
+
+ if (received_datagrams_controller_) {
+ received_datagrams_controller_->Close();
+ received_datagrams_controller_ = nullptr;
+ }
+
+ received_streams_underlying_source_->Close();
+
+ // If we don't manage to close the writable stream here, then it will
+ // error when a write() is attempted.
+ if (!WritableStream::IsLocked(outgoing_datagrams_) &&
+ !WritableStream::CloseQueuedOrInFlight(outgoing_datagrams_)) {
+ auto promise = WritableStream::Close(script_state_, outgoing_datagrams_);
+ promise->MarkAsHandled();
+ }
+ closed_resolver_->Resolve(close_info);
+
+ v8::Local<v8::Value> reason = V8ThrowException::CreateTypeError(
+ script_state_->GetIsolate(), "Connection closed.");
+ ready_resolver_->Reject(reason);
+ RejectPendingStreamResolvers();
+ ResetAll();
}
void QuicTransport::OnConnectionEstablished(
@@ -59,16 +337,56 @@ void QuicTransport::OnConnectionEstablished(
DCHECK(!quic_transport_);
quic_transport_.Bind(std::move(quic_transport), task_runner);
+
+ received_streams_underlying_source_->NotifyOpened();
+
+ ready_resolver_->Resolve();
}
QuicTransport::~QuicTransport() = default;
void QuicTransport::OnHandshakeFailed() {
DVLOG(1) << "QuicTransport::OnHandshakeFailed() this=" << this;
- handshake_client_receiver_.reset();
+ ScriptState::Scope scope(script_state_);
+ {
+ v8::Local<v8::Value> reason = V8ThrowException::CreateTypeError(
+ script_state_->GetIsolate(), "Connection lost.");
+ ready_resolver_->Reject(reason);
+ closed_resolver_->Reject(reason);
+ }
+ ResetAll();
+}
+
+void QuicTransport::OnDatagramReceived(base::span<const uint8_t> data) {
+ ReadableStreamDefaultControllerWithScriptScope* controller =
+ received_datagrams_controller_;
+
+ // Discard datagrams if the readable has been cancelled.
+ if (!controller)
+ return;
+
+ // The spec says we should discard older datagrams first, but that's not what
+ // ReadableStream does, so instead we might need to maintain a separate queue
+ // with the desired semantics. But for now we'll just use a small queue in
+ // ReadableStream.
+ // TODO(ricea): Figure out how to get nice semantics here.
+
+ if (controller->DesiredSize() > 0) {
+ auto* array = DOMUint8Array::Create(
+ data.data(), base::checked_cast<wtf_size_t>(data.size()));
+ controller->Enqueue(array);
+ }
+}
+
+void QuicTransport::OnIncomingStreamClosed(uint32_t stream_id,
+ bool fin_received) {
+ DVLOG(1) << "QuicTransport::OnIncomingStreamClosed(" << stream_id << ", "
+ << fin_received << ") this=" << this;
+ WebTransportCloseProxy* stream = stream_map_.Take(stream_id);
+ stream->OnIncomingStreamClosed(fin_received);
}
-void QuicTransport::ContextDestroyed(ExecutionContext* execution_context) {
+void QuicTransport::ContextDestroyed() {
DVLOG(1) << "QuicTransport::ContextDestroyed() this=" << this;
Dispose();
}
@@ -78,8 +396,29 @@ bool QuicTransport::HasPendingActivity() const {
return handshake_client_receiver_.is_bound() || client_receiver_.is_bound();
}
+void QuicTransport::SendFin(uint32_t stream_id) {
+ quic_transport_->SendFin(stream_id);
+ stream_map_.erase(stream_id);
+}
+
+void QuicTransport::ForgetStream(uint32_t stream_id) {
+ stream_map_.erase(stream_id);
+}
+
void QuicTransport::Trace(Visitor* visitor) {
- ContextLifecycleObserver::Trace(visitor);
+ visitor->Trace(received_datagrams_);
+ visitor->Trace(received_datagrams_controller_);
+ visitor->Trace(outgoing_datagrams_);
+ visitor->Trace(script_state_);
+ visitor->Trace(create_send_stream_resolvers_);
+ visitor->Trace(ready_resolver_);
+ visitor->Trace(ready_);
+ visitor->Trace(closed_resolver_);
+ visitor->Trace(closed_);
+ visitor->Trace(stream_map_);
+ visitor->Trace(received_streams_);
+ visitor->Trace(received_streams_underlying_source_);
+ ExecutionContextLifecycleObserver::Trace(visitor);
ScriptWrappable::Trace(visitor);
}
@@ -108,6 +447,12 @@ void QuicTransport::Init(const String& url, ExceptionState& exception_state) {
return;
}
+ ready_resolver_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state_);
+ ready_ = ready_resolver_->Promise();
+
+ closed_resolver_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state_);
+ closed_ = closed_resolver_->Promise();
+
auto* execution_context = GetExecutionContext();
if (!execution_context->GetContentSecurityPolicyForWorld()
@@ -140,6 +485,36 @@ void QuicTransport::Init(const String& url, ExceptionState& exception_state) {
WTF::Bind(&QuicTransport::OnConnectionError, WrapWeakPersistent(this)));
// TODO(ricea): Report something to devtools.
+
+ // The choice of 1 for the ReadableStream means that it will queue one
+ // datagram even when read() is not being called. Unfortunately, that datagram
+ // may become arbitrarily stale.
+ // TODO(ricea): Consider having a datagram queue inside this class instead.
+ received_datagrams_ = ReadableStream::CreateWithCountQueueingStrategy(
+ script_state_,
+ MakeGarbageCollected<DatagramUnderlyingSource>(script_state_, this), 1);
+ outgoing_datagrams_ = WritableStream::CreateWithCountQueueingStrategy(
+ script_state_, MakeGarbageCollected<DatagramUnderlyingSink>(this), 1);
+
+ received_streams_underlying_source_ =
+ MakeGarbageCollected<ReceivedStreamsUnderlyingSource>(script_state_,
+ this);
+ received_streams_ = ReadableStream::CreateWithCountQueueingStrategy(
+ script_state_, received_streams_underlying_source_, 1);
+}
+
+void QuicTransport::ResetAll() {
+ DVLOG(1) << "QuicTransport::ResetAll() this=" << this;
+
+ // This loop is safe even if re-entered. It will always terminate because
+ // every iteration erases one entry from the map.
+ while (!stream_map_.IsEmpty()) {
+ auto it = stream_map_.begin();
+ auto close_proxy = it->value;
+ stream_map_.erase(it);
+ close_proxy->Reset();
+ }
+ Dispose();
}
void QuicTransport::Dispose() {
@@ -147,11 +522,73 @@ void QuicTransport::Dispose() {
quic_transport_.reset();
handshake_client_receiver_.reset();
client_receiver_.reset();
+ stream_map_.clear();
}
void QuicTransport::OnConnectionError() {
DVLOG(1) << "QuicTransport::OnConnectionError() this=" << this;
- Dispose();
+
+ ScriptState::Scope scope(script_state_);
+ if (!cleanly_closed_) {
+ v8::Local<v8::Value> reason = V8ThrowException::CreateTypeError(
+ script_state_->GetIsolate(), "Connection lost.");
+ if (received_datagrams_controller_) {
+ received_datagrams_controller_->Error(reason);
+ received_datagrams_controller_ = nullptr;
+ }
+ received_streams_underlying_source_->Error(reason);
+ WritableStreamDefaultController::ErrorIfNeeded(
+ script_state_, outgoing_datagrams_->Controller(), reason);
+ ready_resolver_->Reject(reason);
+ closed_resolver_->Reject(reason);
+ }
+
+ RejectPendingStreamResolvers();
+ ResetAll();
+}
+
+void QuicTransport::RejectPendingStreamResolvers() {
+ v8::Local<v8::Value> reason = V8ThrowException::CreateTypeError(
+ script_state_->GetIsolate(), "Connection lost.");
+ for (ScriptPromiseResolver* resolver : create_send_stream_resolvers_) {
+ resolver->Reject(reason);
+ }
+ create_send_stream_resolvers_.clear();
+}
+
+void QuicTransport::OnCreateStreamResponse(
+ ScriptPromiseResolver* resolver,
+ mojo::ScopedDataPipeProducerHandle producer,
+ bool succeeded,
+ uint32_t stream_id) {
+ DVLOG(1) << "QuicTransport::OnCreateStreamResponse() this=" << this
+ << " succeeded=" << succeeded << " stream_id=" << stream_id;
+
+ // Shouldn't resolve the promise if the execution context has gone away.
+ if (!GetExecutionContext())
+ return;
+
+ // Shouldn't resolve the promise if the mojo interface is disconnected.
+ if (!resolver || !create_send_stream_resolvers_.Take(resolver))
+ return;
+
+ ScriptState::Scope scope(script_state_);
+ if (!succeeded) {
+ resolver->Reject(V8ThrowDOMException::CreateOrEmpty(
+ script_state_->GetIsolate(), DOMExceptionCode::kNetworkError,
+ "Failed to create send stream."));
+ return;
+ }
+
+ auto* send_stream = MakeGarbageCollected<SendStream>(
+ script_state_, this, stream_id, std::move(producer));
+ send_stream->Init();
+
+ // 0xfffffffe and 0xffffffff are reserved values in stream_map_.
+ CHECK_LT(stream_id, 0xfffffffe);
+ stream_map_.insert(stream_id, send_stream->GetWebTransportCloseProxy());
+
+ resolver->Resolve(send_stream);
}
} // namespace blink
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 39a3554388b..c562fabe7c1 100644
--- a/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.h
+++ b/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.h
@@ -5,30 +5,43 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBTRANSPORT_QUIC_TRANSPORT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBTRANSPORT_QUIC_TRANSPORT_H_
+#include <stdint.h>
+
+#include "base/containers/span.h"
#include "base/util/type_safety/pass_key.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/remote.h"
+#include "mojo/public/cpp/system/data_pipe.h"
#include "services/network/public/mojom/quic_transport.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
namespace blink {
class ExceptionState;
-class ExecutionContext;
+class ReadableStream;
+class ReadableStreamDefaultControllerWithScriptScope;
+class ScriptPromiseResolver;
class ScriptState;
class WebTransportCloseInfo;
+class WritableStream;
+class ScriptPromise;
+class ScriptPromiseResolver;
+class WebTransportCloseProxy;
+// https://wicg.github.io/web-transport/#quic-transport
class MODULES_EXPORT QuicTransport final
: public ScriptWrappable,
public ActiveScriptWrappable<QuicTransport>,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public network::mojom::blink::QuicTransportHandshakeClient,
public network::mojom::blink::QuicTransportClient {
DEFINE_WRAPPERTYPEINFO();
@@ -45,7 +58,14 @@ class MODULES_EXPORT QuicTransport final
~QuicTransport() override;
// QuicTransport IDL implementation.
+ ScriptPromise createSendStream(ScriptState*, ExceptionState&);
+ ReadableStream* receiveStreams() { return received_streams_; }
+
+ WritableStream* sendDatagrams() { return outgoing_datagrams_; }
+ ReadableStream* receiveDatagrams() { return received_datagrams_; }
void close(const WebTransportCloseInfo*);
+ ScriptPromise ready() { return ready_; }
+ ScriptPromise closed() { return closed_; }
// QuicTransportHandshakeClient implementation
void OnConnectionEstablished(
@@ -54,26 +74,82 @@ class MODULES_EXPORT QuicTransport final
override;
void OnHandshakeFailed() override;
- // Implementation of ContextLifecycleObserver
- void ContextDestroyed(ExecutionContext*) final;
+ // QuicTransportClient implementation
+ void OnDatagramReceived(base::span<const uint8_t> data) override;
+ void OnIncomingStreamClosed(uint32_t stream_id, bool fin_received) override;
+
+ // Implementation of ExecutionContextLifecycleObserver
+ void ContextDestroyed() final;
// Implementation of ActiveScriptWrappable
bool HasPendingActivity() const final;
+ // Forwards a SendFin() message to the mojo interface.
+ void SendFin(uint32_t stream_id);
+
+ // Removes the reference to a stream.
+ void ForgetStream(uint32_t stream_id);
+
// ScriptWrappable implementation
void Trace(Visitor* visitor) override;
private:
+ class DatagramUnderlyingSink;
+ class DatagramUnderlyingSource;
+ class ReceivedStreamsUnderlyingSource;
+
void Init(const String& url, ExceptionState&);
+
+ // Reset the QuicTransport object and all associated streams.
+ void ResetAll();
void Dispose();
void OnConnectionError();
+ void RejectPendingStreamResolvers();
+ void OnCreateStreamResponse(ScriptPromiseResolver*,
+ mojo::ScopedDataPipeProducerHandle producer,
+ bool succeeded,
+ uint32_t stream_id);
+
+ bool cleanly_closed_ = false;
+ Member<ReadableStream> received_datagrams_;
+ Member<ReadableStreamDefaultControllerWithScriptScope>
+ received_datagrams_controller_;
+
+ // This corresponds to the [[SentDatagrams]] internal slot in the standard.
+ Member<WritableStream> outgoing_datagrams_;
+
+ const Member<ScriptState> script_state_;
const KURL url_;
+
+ // Map from stream_id to SendStream, ReceiveStream or BidirectionalStream.
+ // Intentionally keeps streams reachable by GC as long as they are open.
+ // This doesn't support stream ids of 0xfffffffe or larger.
+ // TODO(ricea): Find out if such large stream ids are possible.
+ HeapHashMap<uint32_t,
+ Member<WebTransportCloseProxy>,
+ WTF::DefaultHash<uint32_t>::Hash,
+ WTF::UnsignedWithZeroKeyHashTraits<uint32_t>>
+ stream_map_;
+
mojo::Remote<network::mojom::blink::QuicTransport> quic_transport_;
mojo::Receiver<network::mojom::blink::QuicTransportHandshakeClient>
handshake_client_receiver_{this};
mojo::Receiver<network::mojom::blink::QuicTransportClient> client_receiver_{
this};
+ Member<ScriptPromiseResolver> ready_resolver_;
+ ScriptPromise ready_;
+ Member<ScriptPromiseResolver> closed_resolver_;
+ ScriptPromise closed_;
+
+ // Tracks resolvers for in-progress createSendStream() operations so they can
+ // be rejected
+ HeapHashSet<Member<ScriptPromiseResolver>> create_send_stream_resolvers_;
+
+ // The [[ReceivedStreams]] slot.
+ // https://wicg.github.io/web-transport/#dom-quictransport-receivedstreams-slot
+ Member<ReadableStream> received_streams_;
+ Member<ReceivedStreamsUnderlyingSource> received_streams_underlying_source_;
};
} // namespace blink
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 8ef7de6dc93..1879b5afe6c 100644
--- a/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.idl
+++ b/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.idl
@@ -5,16 +5,28 @@
// https://wicg.github.io/web-transport/#quic-transport
[
ActiveScriptWrappable,
- Constructor(USVString url),
Exposed=(Window,Worker),
- RuntimeEnabled=QuicTransport,
- ConstructorCallWith=ScriptState,
- RaisesException=Constructor
+ RuntimeEnabled=QuicTransport
] interface QuicTransport {
+ [CallWith=ScriptState, RaisesException, MeasureAs=QuicTransport] constructor(USVString url);
// 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
// for simplicity.
- void close(optional WebTransportCloseInfo closeInfo);
+ // From UnidirectionalStreamsTransport
+ [CallWith=ScriptState, RaisesException, MeasureAs=QuicTransportStreamApis] Promise<SendStream>
+ createSendStream();
+ // TODO(ricea): This should probably be changed to an attribute in the
+ // standard.
+ [MeasureAs=QuicTransportStreamApis] ReadableStream receiveStreams();
+
+ // From DatagramTransport mixin
+ [MeasureAs=QuicTransportDatagramApis] WritableStream sendDatagrams();
+ [MeasureAs=QuicTransportDatagramApis] ReadableStream receiveDatagrams();
+
+ // From WebTransport mixin
+ void close(optional WebTransportCloseInfo closeInfo = {});
+ readonly attribute Promise<void> ready;
+ readonly attribute Promise<WebTransportCloseInfo> closed;
};
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 abf5f24151c..f2c96711dee 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
@@ -4,23 +4,44 @@
#include "third_party/blink/renderer/modules/webtransport/quic_transport.h"
+#include <array>
#include <memory>
#include <utility>
+#include "base/containers/span.h"
#include "base/memory/weak_ptr.h"
+#include "base/test/mock_callback.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "services/network/public/mojom/quic_transport.mojom-blink.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/public/mojom/webtransport/quic_transport_connector.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_tester.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h"
+#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_receive_stream.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"
-#include "third_party/blink/renderer/modules/webtransport/web_transport_close_info.h"
+#include "third_party/blink/renderer/core/streams/readable_stream.h"
+#include "third_party/blink/renderer/core/streams/readable_stream_default_reader.h"
+#include "third_party/blink/renderer/core/streams/writable_stream.h"
+#include "third_party/blink/renderer/core/streams/writable_stream_default_writer.h"
+#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
+#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
+#include "third_party/blink/renderer/modules/webtransport/receive_stream.h"
+#include "third_party/blink/renderer/modules/webtransport/send_stream.h"
#include "third_party/blink/renderer/platform/bindings/exception_code.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+#include "third_party/blink/renderer/platform/wtf/deque.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "v8/include/v8.h"
@@ -28,6 +49,14 @@ namespace blink {
namespace {
+using ::testing::_;
+using ::testing::ElementsAre;
+using ::testing::Invoke;
+using ::testing::Mock;
+using ::testing::StrictMock;
+using ::testing::Truly;
+using ::testing::Unused;
+
class QuicTransportConnector final
: public mojom::blink::QuicTransportConnector {
public:
@@ -62,13 +91,32 @@ class QuicTransportConnector final
Vector<ConnectArgs> connect_args_;
};
-class MockQuicTransport final : public network::mojom::blink::QuicTransport {
+class MockQuicTransport : public network::mojom::blink::QuicTransport {
public:
MockQuicTransport(mojo::PendingReceiver<network::mojom::blink::QuicTransport>
pending_receiver)
: receiver_(this, std::move(pending_receiver)) {}
- // TODO(ricea): Add methods when there are some.
+ MOCK_METHOD2(SendDatagram,
+ void(base::span<const uint8_t> data,
+ base::OnceCallback<void(bool)> callback));
+
+ MOCK_METHOD3(CreateStream,
+ void(mojo::ScopedDataPipeConsumerHandle readable,
+ mojo::ScopedDataPipeProducerHandle writable,
+ base::OnceCallback<void(bool, uint32_t)> callback));
+
+ MOCK_METHOD1(
+ AcceptBidirectionalStream,
+ void(base::OnceCallback<void(uint32_t,
+ mojo::ScopedDataPipeConsumerHandle,
+ mojo::ScopedDataPipeProducerHandle)>));
+
+ MOCK_METHOD1(AcceptUnidirectionalStream,
+ void(base::OnceCallback<
+ void(uint32_t, mojo::ScopedDataPipeConsumerHandle)>));
+
+ void SendFin(uint32_t stream_id) override {}
private:
mojo::Receiver<network::mojom::blink::QuicTransport> receiver_;
@@ -76,6 +124,9 @@ class MockQuicTransport final : public network::mojom::blink::QuicTransport {
class QuicTransportTest : public ::testing::Test {
public:
+ using AcceptUnidirectionalStreamCallback =
+ base::OnceCallback<void(uint32_t, mojo::ScopedDataPipeConsumerHandle)>;
+
void AddBinder(const V8TestingScope& scope) {
interface_broker_ =
&scope.GetExecutionContext()->GetBrowserInterfaceBroker();
@@ -85,20 +136,23 @@ class QuicTransportTest : public ::testing::Test {
weak_ptr_factory_.GetWeakPtr()));
}
- // Creates, connects and returns a QuicTransport object with the given |url|.
- // Runs the event loop.
- QuicTransport* ConnectSuccessfully(const V8TestingScope& scope,
- const String& url) {
+ // Creates a QuicTransport object with the given |url|.
+ QuicTransport* Create(const V8TestingScope& scope, const String& url) {
AddBinder(scope);
- auto* quic_transport =
- QuicTransport::Create(scope.GetScriptState(), url, ASSERT_NO_EXCEPTION);
+ return QuicTransport::Create(scope.GetScriptState(), url,
+ ASSERT_NO_EXCEPTION);
+ }
+
+ // Connects a QuicTransport object. Runs the event loop.
+ void ConnectSuccessfully(QuicTransport* quic_transport) {
+ DCHECK(!mock_quic_transport_) << "Only one connection supported, sorry";
test::RunPendingTasks();
auto args = connector_.TakeConnectArgs();
if (args.size() != 1u) {
ADD_FAILURE() << "args.size() should be 1, but is " << args.size();
- return nullptr;
+ return;
}
mojo::Remote<network::mojom::blink::QuicTransportHandshakeClient>
@@ -109,18 +163,104 @@ class QuicTransportTest : public ::testing::Test {
mojo::PendingRemote<network::mojom::blink::QuicTransportClient>
client_remote;
- mock_quic_transport_ = std::make_unique<MockQuicTransport>(
+ mock_quic_transport_ = std::make_unique<StrictMock<MockQuicTransport>>(
quic_transport_to_pass.InitWithNewPipeAndPassReceiver());
+ // This is called on every connection, so expect it in every test.
+ EXPECT_CALL(*mock_quic_transport_, AcceptUnidirectionalStream(_))
+ .WillRepeatedly([this](AcceptUnidirectionalStreamCallback callback) {
+ pending_accept_callbacks_.push_back(std::move(callback));
+ });
+
handshake_client->OnConnectionEstablished(
std::move(quic_transport_to_pass),
client_remote.InitWithNewPipeAndPassReceiver());
+ client_remote_.Bind(std::move(client_remote));
test::RunPendingTasks();
+ }
+ // Creates, connects and returns a QuicTransport object with the given |url|.
+ // Runs the event loop.
+ QuicTransport* CreateAndConnectSuccessfully(const V8TestingScope& scope,
+ const String& url) {
+ auto* quic_transport = Create(scope, url);
+ ConnectSuccessfully(quic_transport);
return quic_transport;
}
+ SendStream* CreateSendStreamSuccessfully(const V8TestingScope& scope,
+ QuicTransport* quic_transport) {
+ EXPECT_CALL(*mock_quic_transport_, CreateStream(_, _, _))
+ .WillOnce([this](Unused, Unused,
+ base::OnceCallback<void(bool, uint32_t)> callback) {
+ std::move(callback).Run(true, next_stream_id_++);
+ });
+
+ auto* script_state = scope.GetScriptState();
+ ScriptPromise send_stream_promise =
+ quic_transport->createSendStream(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromiseTester tester(script_state, send_stream_promise);
+
+ tester.WaitUntilSettled();
+
+ EXPECT_TRUE(tester.IsFulfilled());
+ auto* send_stream = V8SendStream::ToImplWithTypeCheck(
+ scope.GetIsolate(), tester.Value().V8Value());
+ EXPECT_TRUE(send_stream);
+ return send_stream;
+ }
+
+ mojo::ScopedDataPipeProducerHandle DoAcceptUnidirectionalStream() {
+ MojoCreateDataPipeOptions options;
+ options.struct_size = sizeof(MojoCreateDataPipeOptions);
+ options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE;
+ options.element_num_bytes = 1;
+ options.capacity_num_bytes = 0;
+
+ mojo::ScopedDataPipeProducerHandle producer;
+ mojo::ScopedDataPipeConsumerHandle consumer;
+ MojoResult result = mojo::CreateDataPipe(&options, &producer, &consumer);
+ if (result != MOJO_RESULT_OK) {
+ ADD_FAILURE() << "CreateDataPipe() returned " << result;
+ }
+
+ std::move(pending_accept_callbacks_.front())
+ .Run(next_stream_id_++, std::move(consumer));
+ pending_accept_callbacks_.pop_front();
+
+ return producer;
+ }
+
+ ReceiveStream* ReadReceiveStream(const V8TestingScope& scope,
+ QuicTransport* quic_transport) {
+ ReadableStream* streams = quic_transport->receiveStreams();
+ auto* script_state = scope.GetScriptState();
+ auto* reader = streams->getReader(script_state, ASSERT_NO_EXCEPTION);
+
+ ScriptPromise read_promise =
+ reader->read(script_state, ASSERT_NO_EXCEPTION);
+
+ ScriptPromiseTester read_tester(script_state, read_promise);
+ read_tester.WaitUntilSettled();
+ EXPECT_TRUE(read_tester.IsFulfilled());
+
+ v8::Local<v8::Value> result = read_tester.Value().V8Value();
+ DCHECK(result->IsObject());
+ v8::Local<v8::Value> v8value;
+ bool done = false;
+ EXPECT_TRUE(
+ V8UnpackIteratorResult(script_state, result.As<v8::Object>(), &done)
+ .ToLocal(&v8value));
+ EXPECT_FALSE(done);
+
+ ReceiveStream* receive_stream =
+ V8ReceiveStream::ToImplWithTypeCheck(scope.GetIsolate(), v8value);
+ EXPECT_TRUE(receive_stream);
+
+ return receive_stream;
+ }
+
void BindConnector(mojo::ScopedMessagePipeHandle handle) {
connector_.Bind(mojo::PendingReceiver<mojom::blink::QuicTransportConnector>(
std::move(handle)));
@@ -134,8 +274,11 @@ class QuicTransportTest : public ::testing::Test {
}
BrowserInterfaceBrokerProxy* interface_broker_ = nullptr;
+ WTF::Deque<AcceptUnidirectionalStreamCallback> pending_accept_callbacks_;
QuicTransportConnector connector_;
std::unique_ptr<MockQuicTransport> mock_quic_transport_;
+ mojo::Remote<network::mojom::blink::QuicTransportClient> client_remote_;
+ uint32_t next_stream_id_ = 0;
base::WeakPtrFactory<QuicTransportTest> weak_ptr_factory_{this};
};
@@ -216,8 +359,8 @@ TEST_F(QuicTransportTest, FailByCSP) {
scope.GetExecutionContext()
->GetContentSecurityPolicyForWorld()
->DidReceiveHeader("connect-src 'none'",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ network::mojom::ContentSecurityPolicyType::kEnforce,
+ network::mojom::ContentSecurityPolicySource::kHTTP);
QuicTransport::Create(scope.GetScriptState(),
String("quic-transport://example.com/"),
exception_state);
@@ -237,8 +380,8 @@ TEST_F(QuicTransportTest, PassCSP) {
scope.GetExecutionContext()
->GetContentSecurityPolicyForWorld()
->DidReceiveHeader("connect-src quic-transport://example.com",
- kContentSecurityPolicyHeaderTypeEnforce,
- kContentSecurityPolicyHeaderSourceHTTP);
+ network::mojom::ContentSecurityPolicyType::kEnforce,
+ network::mojom::ContentSecurityPolicySource::kHTTP);
QuicTransport::Create(scope.GetScriptState(),
String("quic-transport://example.com/"),
exception_state);
@@ -263,8 +406,14 @@ TEST_F(QuicTransportTest, SendConnect) {
TEST_F(QuicTransportTest, SuccessfulConnect) {
V8TestingScope scope;
auto* quic_transport =
- ConnectSuccessfully(scope, "quic-transport://example.com");
+ CreateAndConnectSuccessfully(scope, "quic-transport://example.com");
+ ScriptPromiseTester ready_tester(scope.GetScriptState(),
+ quic_transport->ready());
+
EXPECT_TRUE(quic_transport->HasPendingActivity());
+
+ ready_tester.WaitUntilSettled();
+ EXPECT_TRUE(ready_tester.IsFulfilled());
}
TEST_F(QuicTransportTest, FailedConnect) {
@@ -273,6 +422,10 @@ TEST_F(QuicTransportTest, FailedConnect) {
auto* quic_transport = QuicTransport::Create(
scope.GetScriptState(), String("quic-transport://example.com/"),
ASSERT_NO_EXCEPTION);
+ ScriptPromiseTester ready_tester(scope.GetScriptState(),
+ quic_transport->ready());
+ ScriptPromiseTester closed_tester(scope.GetScriptState(),
+ quic_transport->closed());
test::RunPendingTasks();
@@ -286,6 +439,8 @@ TEST_F(QuicTransportTest, FailedConnect) {
test::RunPendingTasks();
EXPECT_FALSE(quic_transport->HasPendingActivity());
+ EXPECT_TRUE(ready_tester.IsRejected());
+ EXPECT_TRUE(closed_tester.IsRejected());
}
TEST_F(QuicTransportTest, CloseDuringConnect) {
@@ -294,6 +449,10 @@ TEST_F(QuicTransportTest, CloseDuringConnect) {
auto* quic_transport = QuicTransport::Create(
scope.GetScriptState(), String("quic-transport://example.com/"),
ASSERT_NO_EXCEPTION);
+ ScriptPromiseTester ready_tester(scope.GetScriptState(),
+ quic_transport->ready());
+ ScriptPromiseTester closed_tester(scope.GetScriptState(),
+ quic_transport->closed());
test::RunPendingTasks();
@@ -305,12 +464,18 @@ TEST_F(QuicTransportTest, CloseDuringConnect) {
test::RunPendingTasks();
EXPECT_FALSE(quic_transport->HasPendingActivity());
+ EXPECT_TRUE(ready_tester.IsRejected());
+ EXPECT_TRUE(closed_tester.IsFulfilled());
}
TEST_F(QuicTransportTest, CloseAfterConnection) {
V8TestingScope scope;
auto* quic_transport =
- ConnectSuccessfully(scope, "quic-transport://example.com");
+ CreateAndConnectSuccessfully(scope, "quic-transport://example.com");
+ ScriptPromiseTester ready_tester(scope.GetScriptState(),
+ quic_transport->ready());
+ ScriptPromiseTester closed_tester(scope.GetScriptState(),
+ quic_transport->closed());
WebTransportCloseInfo close_info;
close_info.setErrorCode(42);
@@ -323,6 +488,8 @@ TEST_F(QuicTransportTest, CloseAfterConnection) {
// start sending it.
EXPECT_FALSE(quic_transport->HasPendingActivity());
+ EXPECT_TRUE(ready_tester.IsFulfilled());
+ EXPECT_TRUE(closed_tester.IsFulfilled());
// Calling close again does nothing.
quic_transport->close(nullptr);
@@ -332,8 +499,17 @@ TEST_F(QuicTransportTest, CloseAfterConnection) {
// When the underlying connection is shut down, the connection will be swept.
TEST_F(QuicTransportTest, GarbageCollection) {
V8TestingScope scope;
- WeakPersistent<QuicTransport> quic_transport =
- ConnectSuccessfully(scope, "quic-transport://example.com");
+
+ WeakPersistent<QuicTransport> quic_transport;
+
+ {
+ // The streams created when creating a QuicTransport create some v8 handles.
+ // To ensure these are collected, we need to create a handle scope. This is
+ // not a problem for garbage collection in normal operation.
+ v8::HandleScope handle_scope(scope.GetIsolate());
+ quic_transport =
+ CreateAndConnectSuccessfully(scope, "quic-transport://example.com");
+ }
// Pretend the stack is empty. This will avoid accidentally treating any
// copies of the |quic_transport| pointer as references.
@@ -354,11 +530,20 @@ TEST_F(QuicTransportTest, GarbageCollection) {
TEST_F(QuicTransportTest, GarbageCollectMojoConnectionError) {
V8TestingScope scope;
- WeakPersistent<QuicTransport> quic_transport =
- ConnectSuccessfully(scope, "quic-transport://example.com");
- // Deleting the server-side object causes a mojo connection error.
- mock_quic_transport_ = nullptr;
+ WeakPersistent<QuicTransport> quic_transport;
+
+ {
+ v8::HandleScope handle_scope(scope.GetIsolate());
+ quic_transport =
+ CreateAndConnectSuccessfully(scope, "quic-transport://example.com");
+ }
+
+ ScriptPromiseTester closed_tester(scope.GetScriptState(),
+ quic_transport->closed());
+
+ // Closing the server-side of the pipe causes a mojo connection error.
+ client_remote_.reset();
test::RunPendingTasks();
@@ -366,6 +551,433 @@ TEST_F(QuicTransportTest, GarbageCollectMojoConnectionError) {
scope.GetIsolate(), v8::EmbedderHeapTracer::EmbedderStackState::kEmpty);
EXPECT_FALSE(quic_transport);
+ EXPECT_TRUE(closed_tester.IsRejected());
+}
+
+TEST_F(QuicTransportTest, SendDatagram) {
+ V8TestingScope scope;
+ auto* quic_transport =
+ CreateAndConnectSuccessfully(scope, "quic-transport://example.com");
+
+ EXPECT_CALL(*mock_quic_transport_, SendDatagram(ElementsAre('A'), _))
+ .WillOnce(Invoke([](base::span<const uint8_t>,
+ MockQuicTransport::SendDatagramCallback callback) {
+ std::move(callback).Run(true);
+ }));
+
+ auto* writable = quic_transport->sendDatagrams();
+ auto* script_state = scope.GetScriptState();
+ auto* writer = writable->getWriter(script_state, ASSERT_NO_EXCEPTION);
+ auto* chunk = DOMUint8Array::Create(1);
+ *chunk->Data() = 'A';
+ ScriptPromise result =
+ writer->write(script_state, ScriptValue::From(script_state, chunk),
+ ASSERT_NO_EXCEPTION);
+ ScriptPromiseTester tester(script_state, result);
+ tester.WaitUntilSettled();
+ EXPECT_TRUE(tester.IsFulfilled());
+ EXPECT_TRUE(tester.Value().IsUndefined());
+}
+
+TEST_F(QuicTransportTest, SendDatagramBeforeConnect) {
+ V8TestingScope scope;
+ auto* quic_transport = Create(scope, "quic-transport://example.com");
+
+ auto* writable = quic_transport->sendDatagrams();
+ auto* script_state = scope.GetScriptState();
+ auto* writer = writable->getWriter(script_state, ASSERT_NO_EXCEPTION);
+ auto* chunk = DOMUint8Array::Create(1);
+ *chunk->Data() = 'A';
+ ScriptPromise result =
+ writer->write(script_state, ScriptValue::From(script_state, chunk),
+ ASSERT_NO_EXCEPTION);
+
+ ConnectSuccessfully(quic_transport);
+
+ // No datagram is sent.
+
+ ScriptPromiseTester tester(script_state, result);
+ tester.WaitUntilSettled();
+ EXPECT_TRUE(tester.IsFulfilled());
+ EXPECT_TRUE(tester.Value().IsUndefined());
+}
+
+TEST_F(QuicTransportTest, SendDatagramAfterClose) {
+ V8TestingScope scope;
+ auto* quic_transport =
+ CreateAndConnectSuccessfully(scope, "quic-transport://example.com");
+
+ quic_transport->close(nullptr);
+ test::RunPendingTasks();
+
+ auto* writable = quic_transport->sendDatagrams();
+ auto* script_state = scope.GetScriptState();
+ auto* writer = writable->getWriter(script_state, ASSERT_NO_EXCEPTION);
+
+ auto* chunk = DOMUint8Array::Create(1);
+ *chunk->Data() = 'A';
+ ScriptPromise result =
+ writer->write(script_state, ScriptValue::From(script_state, chunk),
+ ASSERT_NO_EXCEPTION);
+
+ // No datagram is sent.
+
+ ScriptPromiseTester tester(script_state, result);
+ tester.WaitUntilSettled();
+ EXPECT_TRUE(tester.IsRejected());
+}
+
+Vector<uint8_t> GetValueAsVector(ScriptState* script_state,
+ ScriptValue iterator_result) {
+ bool done = false;
+ v8::Local<v8::Value> value;
+ if (!V8UnpackIteratorResult(script_state,
+ iterator_result.V8Value().As<v8::Object>(), &done)
+ .ToLocal(&value)) {
+ ADD_FAILURE() << "unable to unpack iterator_result";
+ return {};
+ }
+
+ EXPECT_FALSE(done);
+ auto* array =
+ V8Uint8Array::ToImplWithTypeCheck(script_state->GetIsolate(), value);
+ if (!array) {
+ ADD_FAILURE() << "value was not a Uint8Array";
+ return {};
+ }
+
+ Vector<uint8_t> result;
+ result.Append(array->Data(), array->lengthAsSizeT());
+ return result;
+}
+
+TEST_F(QuicTransportTest, ReceiveDatagramBeforeRead) {
+ V8TestingScope scope;
+ auto* quic_transport =
+ CreateAndConnectSuccessfully(scope, "quic-transport://example.com");
+
+ const std::array<uint8_t, 1> chunk = {'A'};
+ client_remote_->OnDatagramReceived(chunk);
+
+ test::RunPendingTasks();
+
+ auto* readable = quic_transport->receiveDatagrams();
+ auto* script_state = scope.GetScriptState();
+ auto* reader = readable->getReader(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromise result = reader->read(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromiseTester tester(script_state, result);
+ tester.WaitUntilSettled();
+ EXPECT_TRUE(tester.IsFulfilled());
+
+ EXPECT_THAT(GetValueAsVector(script_state, tester.Value()), ElementsAre('A'));
+}
+
+TEST_F(QuicTransportTest, ReceiveDatagramDuringRead) {
+ V8TestingScope scope;
+ auto* quic_transport =
+ CreateAndConnectSuccessfully(scope, "quic-transport://example.com");
+ auto* readable = quic_transport->receiveDatagrams();
+ auto* script_state = scope.GetScriptState();
+ auto* reader = readable->getReader(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromise result = reader->read(script_state, ASSERT_NO_EXCEPTION);
+
+ const std::array<uint8_t, 1> chunk = {'A'};
+ client_remote_->OnDatagramReceived(chunk);
+
+ ScriptPromiseTester tester(script_state, result);
+ tester.WaitUntilSettled();
+ EXPECT_TRUE(tester.IsFulfilled());
+
+ EXPECT_THAT(GetValueAsVector(script_state, tester.Value()), ElementsAre('A'));
+}
+
+// This test documents the current behaviour. If you improve the behaviour,
+// change the test!
+TEST_F(QuicTransportTest, DatagramsAreDropped) {
+ V8TestingScope scope;
+ auto* quic_transport =
+ CreateAndConnectSuccessfully(scope, "quic-transport://example.com");
+
+ // Chunk 'A' gets placed in the readable queue.
+ const std::array<uint8_t, 1> chunk1 = {'A'};
+ client_remote_->OnDatagramReceived(chunk1);
+
+ // Chunk 'B' gets dropped, because there is no space in the readable queue.
+ const std::array<uint8_t, 1> chunk2 = {'B'};
+ client_remote_->OnDatagramReceived(chunk2);
+
+ // Make sure that the calls have run.
+ test::RunPendingTasks();
+
+ auto* readable = quic_transport->receiveDatagrams();
+ auto* script_state = scope.GetScriptState();
+ auto* reader = readable->getReader(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromise result1 = reader->read(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromise result2 = reader->read(script_state, ASSERT_NO_EXCEPTION);
+
+ ScriptPromiseTester tester1(script_state, result1);
+ ScriptPromiseTester tester2(script_state, result2);
+ tester1.WaitUntilSettled();
+ EXPECT_TRUE(tester1.IsFulfilled());
+ EXPECT_FALSE(tester2.IsFulfilled());
+
+ EXPECT_THAT(GetValueAsVector(script_state, tester1.Value()),
+ ElementsAre('A'));
+
+ // Chunk 'C' fulfills the pending read.
+ const std::array<uint8_t, 1> chunk3 = {'C'};
+ client_remote_->OnDatagramReceived(chunk3);
+
+ tester2.WaitUntilSettled();
+ EXPECT_TRUE(tester2.IsFulfilled());
+
+ EXPECT_THAT(GetValueAsVector(script_state, tester2.Value()),
+ ElementsAre('C'));
+}
+
+bool ValidProducerHandle(const mojo::ScopedDataPipeProducerHandle& handle) {
+ return handle.is_valid();
+}
+
+bool ValidConsumerHandle(const mojo::ScopedDataPipeConsumerHandle& handle) {
+ return handle.is_valid();
+}
+
+TEST_F(QuicTransportTest, CreateSendStream) {
+ V8TestingScope scope;
+ auto* quic_transport =
+ CreateAndConnectSuccessfully(scope, "quic-transport://example.com");
+
+ EXPECT_CALL(*mock_quic_transport_,
+ CreateStream(Truly(ValidConsumerHandle),
+ Not(Truly(ValidProducerHandle)), _))
+ .WillOnce([](Unused, Unused,
+ base::OnceCallback<void(bool, uint32_t)> callback) {
+ std::move(callback).Run(true, 0);
+ });
+
+ auto* script_state = scope.GetScriptState();
+ ScriptPromise send_stream_promise =
+ quic_transport->createSendStream(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromiseTester tester(script_state, send_stream_promise);
+
+ tester.WaitUntilSettled();
+
+ EXPECT_TRUE(tester.IsFulfilled());
+ auto* send_stream = V8SendStream::ToImplWithTypeCheck(
+ scope.GetIsolate(), tester.Value().V8Value());
+ EXPECT_TRUE(send_stream);
+}
+
+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& exception_state = scope.GetExceptionState();
+ ScriptPromise send_stream_promise =
+ quic_transport->createSendStream(script_state, exception_state);
+ EXPECT_TRUE(send_stream_promise.IsEmpty());
+ EXPECT_TRUE(exception_state.HadException());
+ EXPECT_EQ(static_cast<int>(DOMExceptionCode::kNetworkError),
+ exception_state.Code());
+}
+
+TEST_F(QuicTransportTest, CreateSendStreamFailure) {
+ V8TestingScope scope;
+ auto* quic_transport =
+ CreateAndConnectSuccessfully(scope, "quic-transport://example.com");
+
+ EXPECT_CALL(*mock_quic_transport_, CreateStream(_, _, _))
+ .WillOnce([](Unused, Unused,
+ base::OnceCallback<void(bool, uint32_t)> callback) {
+ std::move(callback).Run(false, 0);
+ });
+
+ auto* script_state = scope.GetScriptState();
+ ScriptPromise send_stream_promise =
+ quic_transport->createSendStream(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromiseTester tester(script_state, send_stream_promise);
+
+ tester.WaitUntilSettled();
+
+ EXPECT_TRUE(tester.IsRejected());
+ DOMException* exception = V8DOMException::ToImplWithTypeCheck(
+ scope.GetIsolate(), tester.Value().V8Value());
+ EXPECT_EQ(exception->name(), "NetworkError");
+ EXPECT_EQ(exception->message(), "Failed to create send stream.");
+}
+
+// Every active stream is kept alive by the QuicTransport object.
+TEST_F(QuicTransportTest, SendStreamGarbageCollection) {
+ V8TestingScope scope;
+
+ WeakPersistent<QuicTransport> quic_transport;
+ WeakPersistent<SendStream> send_stream;
+
+ {
+ // The streams created when creating a QuicTransport or SendStream create
+ // some v8 handles. To ensure these are collected, we need to create a
+ // handle scope. This is not a problem for garbage collection in normal
+ // operation.
+ v8::HandleScope handle_scope(scope.GetIsolate());
+
+ quic_transport =
+ CreateAndConnectSuccessfully(scope, "quic-transport://example.com");
+ send_stream = CreateSendStreamSuccessfully(scope, quic_transport);
+ }
+
+ V8GCController::CollectAllGarbageForTesting(
+ scope.GetIsolate(), v8::EmbedderHeapTracer::EmbedderStackState::kEmpty);
+
+ EXPECT_TRUE(quic_transport);
+ EXPECT_TRUE(send_stream);
+
+ quic_transport->close(nullptr);
+
+ test::RunPendingTasks();
+
+ V8GCController::CollectAllGarbageForTesting(
+ scope.GetIsolate(), v8::EmbedderHeapTracer::EmbedderStackState::kEmpty);
+
+ EXPECT_FALSE(quic_transport);
+ EXPECT_FALSE(send_stream);
+}
+
+TEST_F(QuicTransportTest, CreateSendStreamAbortedByClose) {
+ V8TestingScope scope;
+
+ auto* script_state = scope.GetScriptState();
+ auto* quic_transport =
+ CreateAndConnectSuccessfully(scope, "quic-transport://example.com");
+
+ base::OnceCallback<void(bool, uint32_t)> create_stream_callback;
+ EXPECT_CALL(*mock_quic_transport_, CreateStream(_, _, _))
+ .WillOnce([&](Unused, Unused,
+ base::OnceCallback<void(bool, uint32_t)> callback) {
+ create_stream_callback = std::move(callback);
+ });
+
+ ScriptPromise send_stream_promise =
+ quic_transport->createSendStream(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromiseTester tester(script_state, send_stream_promise);
+
+ test::RunPendingTasks();
+
+ quic_transport->close(nullptr);
+ std::move(create_stream_callback).Run(true, 0);
+
+ tester.WaitUntilSettled();
+
+ EXPECT_TRUE(tester.IsRejected());
+}
+
+// ReceiveStream functionality is thoroughly tested in incoming_stream_test.cc.
+// This test just verifies that the creation is done correctly.
+TEST_F(QuicTransportTest, CreateReceiveStream) {
+ V8TestingScope scope;
+
+ auto* script_state = scope.GetScriptState();
+ auto* quic_transport =
+ CreateAndConnectSuccessfully(scope, "quic-transport://example.com");
+
+ mojo::ScopedDataPipeProducerHandle producer = DoAcceptUnidirectionalStream();
+
+ ReceiveStream* receive_stream = ReadReceiveStream(scope, quic_transport);
+
+ const char data[] = "what";
+ uint32_t num_bytes = 4u;
+
+ EXPECT_EQ(
+ producer->WriteData(data, &num_bytes, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE),
+ MOJO_RESULT_OK);
+ EXPECT_EQ(num_bytes, 4u);
+
+ producer.reset();
+ quic_transport->OnIncomingStreamClosed(/*stream_id=*/0, true);
+
+ auto* reader =
+ receive_stream->readable()->getReader(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromise read_promise = reader->read(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromiseTester read_tester(script_state, read_promise);
+ read_tester.WaitUntilSettled();
+ EXPECT_TRUE(read_tester.IsFulfilled());
+ auto read_result = read_tester.Value().V8Value();
+ ASSERT_TRUE(read_result->IsObject());
+ v8::Local<v8::Value> value;
+ bool done = false;
+ ASSERT_TRUE(
+ V8UnpackIteratorResult(script_state, read_result.As<v8::Object>(), &done)
+ .ToLocal(&value));
+ DOMUint8Array* u8array =
+ V8Uint8Array::ToImplWithTypeCheck(scope.GetIsolate(), value);
+ ASSERT_TRUE(u8array);
+ EXPECT_THAT(base::make_span(static_cast<uint8_t*>(u8array->Data()),
+ u8array->byteLengthAsSizeT()),
+ ElementsAre('w', 'h', 'a', 't'));
+}
+
+TEST_F(QuicTransportTest, CreateReceiveStreamThenClose) {
+ V8TestingScope scope;
+
+ auto* script_state = scope.GetScriptState();
+ auto* quic_transport =
+ CreateAndConnectSuccessfully(scope, "quic-transport://example.com");
+
+ mojo::ScopedDataPipeProducerHandle producer = DoAcceptUnidirectionalStream();
+
+ ReceiveStream* receive_stream = ReadReceiveStream(scope, quic_transport);
+
+ auto* reader =
+ receive_stream->readable()->getReader(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromise read_promise = reader->read(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromiseTester read_tester(script_state, read_promise);
+
+ quic_transport->close(nullptr);
+
+ read_tester.WaitUntilSettled();
+ EXPECT_TRUE(read_tester.IsRejected());
+ DOMException* exception = V8DOMException::ToImplWithTypeCheck(
+ scope.GetIsolate(), read_tester.Value().V8Value());
+ ASSERT_TRUE(exception);
+ EXPECT_EQ(exception->code(),
+ static_cast<uint16_t>(DOMExceptionCode::kNetworkError));
+
+ // TODO(ricea): Fix this message if possible.
+ EXPECT_EQ(exception->message(),
+ "The stream was aborted by the remote server");
+}
+
+TEST_F(QuicTransportTest, CreateReceiveStreamThenRemoteClose) {
+ V8TestingScope scope;
+
+ auto* script_state = scope.GetScriptState();
+ auto* quic_transport =
+ CreateAndConnectSuccessfully(scope, "quic-transport://example.com");
+
+ mojo::ScopedDataPipeProducerHandle producer = DoAcceptUnidirectionalStream();
+
+ ReceiveStream* receive_stream = ReadReceiveStream(scope, quic_transport);
+
+ auto* reader =
+ receive_stream->readable()->getReader(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromise read_promise = reader->read(script_state, ASSERT_NO_EXCEPTION);
+ ScriptPromiseTester read_tester(script_state, read_promise);
+
+ client_remote_.reset();
+
+ read_tester.WaitUntilSettled();
+ EXPECT_TRUE(read_tester.IsRejected());
+ DOMException* exception = V8DOMException::ToImplWithTypeCheck(
+ scope.GetIsolate(), read_tester.Value().V8Value());
+ ASSERT_TRUE(exception);
+ EXPECT_EQ(exception->code(),
+ static_cast<uint16_t>(DOMExceptionCode::kNetworkError));
+
+ // TODO(ricea): Fix this message if possible.
+ EXPECT_EQ(exception->message(),
+ "The stream was aborted by the remote server");
}
} // namespace
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.cc b/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.cc
new file mode 100644
index 00000000000..ee089b0079e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.cc
@@ -0,0 +1,59 @@
+// 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/webtransport/receive_stream.h"
+
+#include <utility>
+
+#include "third_party/blink/renderer/modules/webtransport/quic_transport.h"
+#include "third_party/blink/renderer/modules/webtransport/web_transport_close_proxy.h"
+#include "third_party/blink/renderer/platform/heap/visitor.h"
+
+namespace blink {
+
+namespace {
+
+class CloseProxy : public WebTransportCloseProxy {
+ public:
+ CloseProxy(QuicTransport* quic_transport,
+ IncomingStream* incoming_stream,
+ uint32_t stream_id)
+ : quic_transport_(quic_transport),
+ incoming_stream_(incoming_stream),
+ stream_id_(stream_id) {}
+
+ void OnIncomingStreamClosed(bool fin_received) override {
+ incoming_stream_->OnIncomingStreamClosed(fin_received);
+ }
+
+ void SendFin() override { NOTREACHED(); }
+
+ void ForgetStream() override { quic_transport_->ForgetStream(stream_id_); }
+
+ void Reset() override { incoming_stream_->Reset(); }
+
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(quic_transport_);
+ visitor->Trace(incoming_stream_);
+ WebTransportCloseProxy::Trace(visitor);
+ }
+
+ private:
+ const Member<QuicTransport> quic_transport_;
+ const Member<IncomingStream> incoming_stream_;
+ const uint32_t stream_id_;
+};
+
+} // namespace
+
+ReceiveStream::ReceiveStream(ScriptState* script_state,
+ QuicTransport* quic_transport,
+ uint32_t stream_id,
+ mojo::ScopedDataPipeConsumerHandle handle)
+ : IncomingStream(
+ script_state,
+ MakeGarbageCollected<CloseProxy>(quic_transport, this, stream_id),
+ std::move(handle)) {}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.h b/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.h
new file mode 100644
index 00000000000..2701c71ef77
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.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_MODULES_WEBTRANSPORT_RECEIVE_STREAM_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBTRANSPORT_RECEIVE_STREAM_H_
+
+#include <stdint.h>
+
+#include "mojo/public/cpp/system/data_pipe.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/modules/webtransport/incoming_stream.h"
+
+namespace blink {
+
+class ScriptState;
+class QuicTransport;
+
+// Implementation of ReceiveStream from the standard:
+// https://wicg.github.io/web-transport/#receive-stream.
+
+class MODULES_EXPORT ReceiveStream final : public IncomingStream {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ // ReceiveStream doesn't have a JavaScript constructor. It is only constructed
+ // from C++.
+ explicit ReceiveStream(ScriptState*,
+ QuicTransport*,
+ uint32_t stream_id,
+ mojo::ScopedDataPipeConsumerHandle);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBTRANSPORT_RECEIVE_STREAM_H_
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.idl b/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.idl
new file mode 100644
index 00000000000..83e8862aa08
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.idl
@@ -0,0 +1,12 @@
+// 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/#receive-stream
+
+[ Exposed=(Window,Worker),
+ ActiveScriptWrappable,
+ RuntimeEnabled=QuicTransport ]
+interface ReceiveStream {
+};
+ReceiveStream includes IncomingStream;
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/send_stream.cc b/chromium/third_party/blink/renderer/modules/webtransport/send_stream.cc
new file mode 100644
index 00000000000..7282dadcd7a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webtransport/send_stream.cc
@@ -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.
+
+#include "third_party/blink/renderer/modules/webtransport/send_stream.h"
+
+#include <utility>
+
+#include "base/logging.h"
+#include "third_party/blink/renderer/modules/webtransport/quic_transport.h"
+#include "third_party/blink/renderer/modules/webtransport/web_transport_close_proxy.h"
+#include "third_party/blink/renderer/platform/heap/visitor.h"
+
+namespace blink {
+
+namespace {
+
+class CloseProxy : public WebTransportCloseProxy {
+ public:
+ CloseProxy(QuicTransport* quic_transport,
+ OutgoingStream* outgoing_stream,
+ uint32_t stream_id)
+ : quic_transport_(quic_transport),
+ outgoing_stream_(outgoing_stream),
+ stream_id_(stream_id) {}
+
+ void OnIncomingStreamClosed(bool fin_received) override {
+ // OnIncomingStreamClosed only applies to IncomingStreams.
+ }
+
+ void SendFin() override { quic_transport_->SendFin(stream_id_); }
+
+ void ForgetStream() override { NOTREACHED(); }
+
+ void Reset() override { outgoing_stream_->Reset(); }
+
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(quic_transport_);
+ visitor->Trace(outgoing_stream_);
+ WebTransportCloseProxy::Trace(visitor);
+ }
+
+ private:
+ const Member<QuicTransport> quic_transport_;
+ const Member<OutgoingStream> outgoing_stream_;
+ const uint32_t stream_id_;
+};
+
+} // namespace
+
+SendStream::SendStream(ScriptState* script_state,
+ QuicTransport* quic_transport,
+ uint32_t stream_id,
+ mojo::ScopedDataPipeProducerHandle handle)
+ : OutgoingStream(
+ script_state,
+ MakeGarbageCollected<CloseProxy>(quic_transport, this, stream_id),
+ std::move(handle)) {}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/send_stream.h b/chromium/third_party/blink/renderer/modules/webtransport/send_stream.h
new file mode 100644
index 00000000000..3ae4333c450
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webtransport/send_stream.h
@@ -0,0 +1,33 @@
+// 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_WEBTRANSPORT_SEND_STREAM_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBTRANSPORT_SEND_STREAM_H_
+
+#include <stdint.h>
+
+#include "mojo/public/cpp/system/data_pipe.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/modules/webtransport/outgoing_stream.h"
+
+namespace blink {
+
+class ScriptState;
+class QuicTransport;
+
+class MODULES_EXPORT SendStream final : public OutgoingStream {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ // SendStream doesn't have a JavaScript constructor. It is only constructed
+ // from C++.
+ explicit SendStream(ScriptState*,
+ QuicTransport*,
+ uint32_t stream_id,
+ mojo::ScopedDataPipeProducerHandle);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBTRANSPORT_SEND_STREAM_H_
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/send_stream.idl b/chromium/third_party/blink/renderer/modules/webtransport/send_stream.idl
new file mode 100644
index 00000000000..ebd7cdafd6d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webtransport/send_stream.idl
@@ -0,0 +1,12 @@
+// 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/#send-stream
+
+[ Exposed=(Window,Worker),
+ ActiveScriptWrappable,
+ RuntimeEnabled=QuicTransport ]
+interface SendStream {
+};
+SendStream includes OutgoingStream;
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/stream_abort_info.idl b/chromium/third_party/blink/renderer/modules/webtransport/stream_abort_info.idl
new file mode 100644
index 00000000000..b0e46b8d653
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webtransport/stream_abort_info.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/web-transport/#stream-abort-info
+dictionary StreamAbortInfo {
+ unsigned short errorCode = 0;
+};
diff --git a/chromium/third_party/blink/renderer/modules/webtransport/web_transport_close_proxy.h b/chromium/third_party/blink/renderer/modules/webtransport/web_transport_close_proxy.h
new file mode 100644
index 00000000000..185a496c552
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webtransport/web_transport_close_proxy.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_MODULES_WEBTRANSPORT_WEB_TRANSPORT_CLOSE_PROXY_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBTRANSPORT_WEB_TRANSPORT_CLOSE_PROXY_H_
+
+#include "third_party/blink/renderer/platform/heap/heap.h"
+
+namespace blink {
+
+class Visitor;
+
+// This is an internal proxy type for passing close messages between
+// QuicTransport and the IncomingStream and OutgoingStream mixins. It is not
+// part of the standard. It exists to abstract over the fact that a single
+// stream_id can correspond to one or two JavaScript streams.
+class WebTransportCloseProxy : public GarbageCollected<WebTransportCloseProxy> {
+ public:
+ virtual ~WebTransportCloseProxy() = default;
+
+ // These match the mojo interfaces, but without the stream_id argument.
+
+ // Process an IncomingStreamClosed message from the network service. This is
+ // called by QuicTransport objects. May execute user JavaScript.
+ virtual void OnIncomingStreamClosed(bool fin_received) = 0;
+
+ // Send a Fin signal to the network service. This is used by OutgoingStream.
+ virtual void SendFin() = 0;
+
+ // Cause QuicTransport to drop reference to a stream. This is used by
+ // IncomingStream.
+ virtual void ForgetStream() = 0;
+
+ // Called from QuicTransport whenever the mojo connection is torn down. Should
+ // close and free data pipes. May execute user JavaScript.
+ virtual void Reset() = 0;
+
+ virtual void Trace(Visitor*) {}
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBTRANSPORT_WEB_TRANSPORT_CLOSE_PROXY_H_
diff --git a/chromium/third_party/blink/renderer/modules/webusb/idls.gni b/chromium/third_party/blink/renderer/modules/webusb/idls.gni
new file mode 100644
index 00000000000..d352c96b068
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/webusb/idls.gni
@@ -0,0 +1,31 @@
+# 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 = [
+ "usb.idl",
+ "usb_alternate_interface.idl",
+ "usb_configuration.idl",
+ "usb_connection_event.idl",
+ "usb_device.idl",
+ "usb_endpoint.idl",
+ "usb_in_transfer_result.idl",
+ "usb_interface.idl",
+ "usb_isochronous_in_transfer_packet.idl",
+ "usb_isochronous_in_transfer_result.idl",
+ "usb_isochronous_out_transfer_packet.idl",
+ "usb_isochronous_out_transfer_result.idl",
+ "usb_out_transfer_result.idl",
+]
+
+modules_dictionary_idl_files = [
+ "usb_connection_event_init.idl",
+ "usb_control_transfer_parameters.idl",
+ "usb_device_filter.idl",
+ "usb_device_request_options.idl",
+]
+
+modules_dependency_idl_files = [
+ "navigator_usb.idl",
+ "worker_navigator_usb.idl",
+]
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 c341a7e3c73..1b840e4b52f 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/navigator_usb.cc
+++ b/chromium/third_party/blink/renderer/modules/webusb/navigator_usb.cc
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/navigator.h"
#include "third_party/blink/renderer/modules/webusb/usb.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
@@ -29,7 +30,7 @@ USB* NavigatorUSB::usb() {
return usb_;
}
-void NavigatorUSB::Trace(blink::Visitor* visitor) {
+void NavigatorUSB::Trace(Visitor* visitor) {
visitor->Trace(usb_);
Supplement<Navigator>::Trace(visitor);
}
@@ -37,7 +38,8 @@ void NavigatorUSB::Trace(blink::Visitor* visitor) {
NavigatorUSB::NavigatorUSB(Navigator& navigator) {
if (navigator.GetFrame()) {
DCHECK(navigator.GetFrame()->GetDocument());
- usb_ = USB::Create(*navigator.GetFrame()->GetDocument());
+ usb_ = MakeGarbageCollected<USB>(
+ *navigator.GetFrame()->GetDocument()->ToExecutionContext());
}
}
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 6da05edd311..26629fad5dd 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 cbe336ae699..de66613d208 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb.cc
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb.cc
@@ -13,6 +13,8 @@
#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.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_usb_device_filter.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_usb_device_request_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/frame.h"
@@ -20,8 +22,7 @@
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/webusb/usb_connection_event.h"
#include "third_party/blink/renderer/modules/webusb/usb_device.h"
-#include "third_party/blink/renderer/modules/webusb/usb_device_filter.h"
-#include "third_party/blink/renderer/modules/webusb/usb_device_request_options.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/mojo/mojo_helper.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -91,7 +92,8 @@ UsbDeviceFilterPtr ConvertDeviceFilter(const USBDeviceFilter* filter,
} // namespace
-USB::USB(ExecutionContext& context) : ContextLifecycleObserver(&context) {}
+USB::USB(ExecutionContext& context)
+ : ExecutionContextLifecycleObserver(&context) {}
USB::~USB() {
// |service_| may still be valid but there should be no more outstanding
@@ -106,29 +108,19 @@ void USB::Dispose() {
client_receiver_.reset();
}
-ScriptPromise USB::getDevices(ScriptState* script_state) {
+ScriptPromise USB::getDevices(ScriptState* script_state,
+ ExceptionState& exception_state) {
if (!IsContextSupported()) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotSupportedError));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotSupportedError,
+ "The implementation did not support the requested type of object or "
+ "operation.");
+ return ScriptPromise();
}
- FeatureEnabledState state = GetFeatureEnabledState();
- if (state != FeatureEnabledState::kEnabled) {
- ExecutionContext* execution_context = ExecutionContext::From(script_state);
- if (auto* document = DynamicTo<Document>(execution_context)) {
- document->ReportFeaturePolicyViolation(
- mojom::FeaturePolicyFeature::kUsb,
- (state == FeatureEnabledState::kReportOnly
- ? mojom::FeaturePolicyDisposition::kReport
- : mojom::FeaturePolicyDisposition::kEnforce));
- }
- }
- if (state == FeatureEnabledState::kDisabled) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kSecurityError,
- kFeaturePolicyBlocked));
+ if (!IsFeatureEnabled(ReportOptions::kReportOnFailure)) {
+ exception_state.ThrowSecurityError(kFeaturePolicyBlocked);
+ return ScriptPromise();
}
EnsureServiceConnection();
@@ -140,30 +132,28 @@ ScriptPromise USB::getDevices(ScriptState* script_state) {
}
ScriptPromise USB::requestDevice(ScriptState* script_state,
- const USBDeviceRequestOptions* options) {
+ const USBDeviceRequestOptions* options,
+ ExceptionState& exception_state) {
LocalFrame* frame = GetFrame();
if (!frame || !frame->GetDocument()) {
- return ScriptPromise::RejectWithDOMException(
- script_state, MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kNotSupportedError));
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotSupportedError,
+ "The implementation did not support the requested type of object or "
+ "operation.");
+ return ScriptPromise();
}
- if (!frame->GetDocument()->IsFeatureEnabled(
- mojom::FeaturePolicyFeature::kUsb, ReportOptions::kReportOnFailure)) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(DOMExceptionCode::kSecurityError,
- kFeaturePolicyBlocked));
+ if (!IsFeatureEnabled(ReportOptions::kReportOnFailure)) {
+ exception_state.ThrowSecurityError(kFeaturePolicyBlocked);
+ return ScriptPromise();
}
EnsureServiceConnection();
if (!LocalFrame::HasTransientUserActivation(frame)) {
- return ScriptPromise::RejectWithDOMException(
- script_state,
- MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kSecurityError,
- "Must be handling a user gesture to show a permission request."));
+ exception_state.ThrowSecurityError(
+ "Must be handling a user gesture to show a permission request.");
+ return ScriptPromise();
}
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
@@ -189,14 +179,14 @@ ScriptPromise USB::requestDevice(ScriptState* script_state,
}
ExecutionContext* USB::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
const AtomicString& USB::InterfaceName() const {
return event_target_names::kUSB;
}
-void USB::ContextDestroyed(ExecutionContext*) {
+void USB::ContextDestroyed() {
service_.reset();
get_devices_requests_.clear();
get_permission_requests_.clear();
@@ -208,8 +198,8 @@ USBDevice* USB::GetOrCreateDevice(UsbDeviceInfoPtr device_info) {
String guid = device_info->guid;
mojo::PendingRemote<UsbDevice> pipe;
service_->GetDevice(guid, pipe.InitWithNewPipeAndPassReceiver());
- device = USBDevice::Create(std::move(device_info), std::move(pipe),
- GetExecutionContext());
+ device = MakeGarbageCollected<USBDevice>(
+ std::move(device_info), std::move(pipe), GetExecutionContext());
device_cache_.insert(guid, device);
}
return device;
@@ -253,8 +243,8 @@ void USB::OnDeviceRemoved(UsbDeviceInfoPtr device_info) {
String guid = device_info->guid;
USBDevice* device = device_cache_.at(guid);
if (!device) {
- device = USBDevice::Create(std::move(device_info), mojo::NullRemote(),
- GetExecutionContext());
+ device = MakeGarbageCollected<USBDevice>(
+ std::move(device_info), mojo::NullRemote(), GetExecutionContext());
}
DispatchEvent(
*USBConnectionEvent::Create(event_type_names::kDisconnect, device));
@@ -283,8 +273,7 @@ void USB::AddedEventListener(const AtomicString& event_type,
return;
}
- if (!IsContextSupported() ||
- GetFeatureEnabledState() == FeatureEnabledState::kDisabled)
+ if (!IsContextSupported() || !IsFeatureEnabled(ReportOptions::kDoNotReport))
return;
EnsureServiceConnection();
@@ -295,7 +284,7 @@ void USB::EnsureServiceConnection() {
return;
DCHECK(IsContextSupported());
- DCHECK(GetFeatureEnabledState() != FeatureEnabledState::kDisabled);
+ DCHECK(IsFeatureEnabled(ReportOptions::kDoNotReport));
// See https://bit.ly/2S0zRAS for task types.
auto task_runner =
GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI);
@@ -326,17 +315,17 @@ bool USB::IsContextSupported() const {
return true;
}
-FeatureEnabledState USB::GetFeatureEnabledState() const {
- return GetExecutionContext()->GetSecurityContext().GetFeatureEnabledState(
- mojom::FeaturePolicyFeature::kUsb);
+bool USB::IsFeatureEnabled(ReportOptions report_options) const {
+ return GetExecutionContext()->IsFeatureEnabled(
+ mojom::blink::FeaturePolicyFeature::kUsb, report_options);
}
-void USB::Trace(blink::Visitor* visitor) {
+void USB::Trace(Visitor* visitor) {
visitor->Trace(get_devices_requests_);
visitor->Trace(get_permission_requests_);
visitor->Trace(device_cache_);
EventTargetWithInlineData::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb.h b/chromium/third_party/blink/renderer/modules/webusb/usb.h
index 5a8d54156fa..737252063ef 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb.h
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb.h
@@ -12,39 +12,38 @@
#include "third_party/blink/public/mojom/usb/web_usb_service.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/execution_context/security_context.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
+class ExceptionState;
class ScriptPromiseResolver;
class ScriptState;
class USBDevice;
class USBDeviceRequestOptions;
class USB final : public EventTargetWithInlineData,
- public ContextLifecycleObserver,
+ public ExecutionContextLifecycleObserver,
public device::mojom::blink::UsbDeviceManagerClient {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(USB);
USING_PRE_FINALIZER(USB, Dispose);
public:
- static USB* Create(ExecutionContext& context) {
- return MakeGarbageCollected<USB>(context);
- }
-
explicit USB(ExecutionContext&);
~USB() override;
void Dispose();
// USB.idl
- ScriptPromise getDevices(ScriptState*);
- ScriptPromise requestDevice(ScriptState*, const USBDeviceRequestOptions*);
+ ScriptPromise getDevices(ScriptState*, ExceptionState&);
+ ScriptPromise requestDevice(ScriptState*,
+ const USBDeviceRequestOptions*,
+ ExceptionState&);
DEFINE_ATTRIBUTE_EVENT_LISTENER(connect, kConnect)
DEFINE_ATTRIBUTE_EVENT_LISTENER(disconnect, kDisconnect)
@@ -52,8 +51,8 @@ class USB final : public EventTargetWithInlineData,
ExecutionContext* GetExecutionContext() const override;
const AtomicString& InterfaceName() const override;
- // ContextLifecycleObserver overrides.
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver overrides.
+ void ContextDestroyed() override;
USBDevice* GetOrCreateDevice(device::mojom::blink::UsbDeviceInfoPtr);
@@ -72,7 +71,7 @@ class USB final : public EventTargetWithInlineData,
void OnServiceConnectionError();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
protected:
// EventTarget protected overrides.
@@ -83,7 +82,7 @@ class USB final : public EventTargetWithInlineData,
void EnsureServiceConnection();
bool IsContextSupported() const;
- FeatureEnabledState GetFeatureEnabledState() const;
+ bool IsFeatureEnabled(ReportOptions) const;
mojo::Remote<mojom::blink::WebUsbService> service_;
HeapHashSet<Member<ScriptPromiseResolver>> get_devices_requests_;
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb.idl b/chromium/third_party/blink/renderer/modules/webusb/usb.idl
index 05247015fbc..e9a9e34115d 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb.idl
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb.idl
@@ -10,6 +10,6 @@
] interface USB : EventTarget {
attribute EventHandler onconnect;
attribute EventHandler ondisconnect;
- [CallWith=ScriptState, MeasureAs=UsbGetDevices] Promise<sequence<USBDevice>> getDevices();
- [CallWith=ScriptState, Exposed=Window, MeasureAs=UsbRequestDevice] Promise<sequence<USBDevice>> requestDevice(USBDeviceRequestOptions options);
+ [CallWith=ScriptState, RaisesException, MeasureAs=UsbGetDevices] Promise<sequence<USBDevice>> getDevices();
+ [CallWith=ScriptState, RaisesException, Exposed=Window, MeasureAs=UsbRequestDevice] Promise<sequence<USBDevice>> requestDevice(USBDeviceRequestOptions options);
};
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 23edf415995..158c07c88f5 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(blink::Visitor* visitor) {
+void USBAlternateInterface::Trace(Visitor* visitor) {
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 2fbe07ad1f9..41018f6e5ef 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<const USBInterface> interface_;
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.idl b/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.idl
index 80de8d96866..7cd4b416d92 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.idl
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.idl
@@ -5,11 +5,10 @@
// https://wicg.github.io/webusb/#interfaces
[
- Constructor(USBInterface deviceInterface, octet alternateSetting),
Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
- RaisesException=Constructor,
SecureContext
] interface USBAlternateInterface {
+ [RaisesException] constructor(USBInterface deviceInterface, octet alternateSetting);
readonly attribute octet alternateSetting;
readonly attribute octet interfaceClass;
readonly attribute octet interfaceSubclass;
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 e7da931f4c1..5602c7abe07 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(blink::Visitor* visitor) {
+void USBConfiguration::Trace(Visitor* visitor) {
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 d779ab7d57c..04516b04ba6 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<const USBDevice> device_;
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.idl b/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.idl
index 62e2d00c9ff..beea0bd3386 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.idl
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.idl
@@ -5,11 +5,10 @@
// https://wicg.github.io/webusb/#configurations
[
- Constructor(USBDevice device, octet configurationValue),
Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
- RaisesException=Constructor,
SecureContext
] interface USBConfiguration {
+ [RaisesException] constructor(USBDevice device, octet configurationValue);
readonly attribute octet configurationValue;
readonly attribute DOMString? configurationName;
readonly attribute FrozenArray<USBInterface> interfaces;
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 898ed01fbea..54aa4fe097e 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
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/modules/webusb/usb_connection_event.h"
-#include "third_party/blink/renderer/modules/webusb/usb_connection_event_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_usb_connection_event_init.h"
#include "third_party/blink/renderer/modules/webusb/usb_device.h"
namespace blink {
@@ -29,7 +29,7 @@ USBConnectionEvent::USBConnectionEvent(const AtomicString& type,
USBDevice* device)
: Event(type, Bubbles::kNo, Cancelable::kNo), device_(device) {}
-void USBConnectionEvent::Trace(blink::Visitor* visitor) {
+void USBConnectionEvent::Trace(Visitor* visitor) {
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 96e0b092500..a8dc7bd1b9f 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<USBDevice> device_;
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_connection_event.idl b/chromium/third_party/blink/renderer/modules/webusb/usb_connection_event.idl
index e3c22d176c7..5138c10aab8 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_connection_event.idl
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_connection_event.idl
@@ -5,9 +5,9 @@
// https://wicg.github.io/webusb/#events
[
- Constructor(DOMString type, USBConnectionEventInit eventInitDict),
Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
SecureContext
] interface USBConnectionEvent : Event {
+ constructor(DOMString type, USBConnectionEventInit eventInitDict);
[SameObject] readonly attribute 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 da7d3003c3a..655212ee5dd 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_device.cc
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_device.cc
@@ -5,18 +5,19 @@
#include "third_party/blink/renderer/modules/webusb/usb_device.h"
#include <algorithm>
+#include <iterator>
#include <utility>
#include "third_party/blink/public/platform/platform.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/to_v8_for_core.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_usb_control_transfer_parameters.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/inspector/console_message.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/webusb/usb_configuration.h"
-#include "third_party/blink/renderer/modules/webusb/usb_control_transfer_parameters.h"
#include "third_party/blink/renderer/modules/webusb/usb_in_transfer_result.h"
#include "third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_result.h"
#include "third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_result.h"
@@ -51,15 +52,50 @@ const char kInterfaceNotFound[] =
const char kInterfaceStateChangeInProgress[] =
"An operation that changes interface state is in progress.";
const char kOpenRequired[] = "The device must be opened first.";
+
+#if defined(OS_CHROMEOS)
const char kExtensionProtocol[] = "chrome-extension";
-const char kImprivataLoginScreenProdExtensionId[] =
- "lpimkpkllnkdlcigdbgmabfplniahkgm";
-const char kImprivataLoginScreenDevExtensionId[] =
- "cdgickkdpbekbnalbmpgochbninibkko";
-const char kImprivataInSessionProdExtensionId[] =
- "cokoeepjbmmnhgdhlkpahohdaiedfjgn";
-const char kImprivataInSessionDevExtensionId[] =
- "omificdfgpipkkpdhbjmefgfgbppehke";
+
+// These whitelisted 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[] = {
+ "baobpecgllpajfeojepgedjdlnlfffde", "bnfoibgpjolimhppjmligmcgklpboloj",
+ "cdgickkdpbekbnalbmpgochbninibkko", "cjakdianfealdjlapagfagpdpemoppba",
+ "cokoeepjbmmnhgdhlkpahohdaiedfjgn", "dahgfgiifpnaoajmloofonkndaaafacp",
+ "dbknmmkopacopifbkgookcdbhfnggjjh", "ddcjglpbfbibgepfffpklmpihphbcdco",
+ "dhodapiemamlmhlhblgcibabhdkohlen", "dlahpllbhpbkfnoiedkgombmegnnjopi",
+ "egfpnfjeaopimgpiioeedbpmojdapaip", "fnbibocngjnefolmcodjkkghijpdlnfm",
+ "jcnflhjcfjkplgkcinikhbgbhfldkadl", "jkfjfbelolphkjckiolfcakgalloegek",
+ "kmhpgpnbglclbaccjjgoioogjlnfgbne", "lpimkpkllnkdlcigdbgmabfplniahkgm",
+ "odehonhhkcjnbeaomlodfkjaecbmhklm", "olnmflhcfkifkgbiegcoabineoknmbjc",
+ "omificdfgpipkkpdhbjmefgfgbppehke", "phjobickjiififdadeoepbdaciefacfj",
+ "pkeacbojooejnjolgjdecbpnloibpafm", "pllbepacblmgialkkpcceohmjakafnbb",
+ "plpogimmgnkkiflhpidbibfmgpkaofec", "pmhiabnkkchjeaehcodceadhdpfejmmd",
+};
+const char** kExtensionNameMappingsEnd = std::end(kImprivataExtensionIds);
+
+bool IsCStrBefore(const char* first, const char* second) {
+ return strcmp(first, second) < 0;
+}
+
+bool IsClassWhitelistedForExtension(uint8_t class_code, const KURL& url) {
+ if (url.Protocol() != kExtensionProtocol)
+ return false;
+
+ switch (class_code) {
+ case 0x03: // HID
+ DCHECK(std::is_sorted(kImprivataExtensionIds, kExtensionNameMappingsEnd,
+ IsCStrBefore));
+ return std::binary_search(kImprivataExtensionIds,
+ kExtensionNameMappingsEnd,
+ url.Host().Utf8().c_str(), IsCStrBefore);
+ default:
+ return false;
+ }
+}
+#endif // defined(OS_CHROMEOS)
DOMException* ConvertFatalTransferStatus(const UsbTransferStatus& status) {
switch (status) {
@@ -125,20 +161,20 @@ bool ConvertBufferSource(const ArrayBufferOrArrayBufferView& buffer_source,
vector->Append(static_cast<uint8_t*>(array_buffer->Data()),
static_cast<wtf_size_t>(array_buffer->ByteLengthAsSizeT()));
} else {
- ArrayBufferView* view = buffer_source.GetAsArrayBufferView().View()->View();
- if (!view->Buffer() || view->Buffer()->IsDetached()) {
+ DOMArrayBufferView* view = buffer_source.GetAsArrayBufferView().View();
+ if (!view->buffer() || view->buffer()->IsDetached()) {
resolver->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kInvalidStateError, kDetachedBuffer));
return false;
}
- if (view->ByteLengthAsSizeT() > std::numeric_limits<wtf_size_t>::max()) {
+ if (view->byteLengthAsSizeT() > std::numeric_limits<wtf_size_t>::max()) {
resolver->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kDataError, kBufferTooBig));
return false;
}
vector->Append(static_cast<uint8_t*>(view->BaseAddress()),
- static_cast<wtf_size_t>(view->ByteLengthAsSizeT()));
+ static_cast<wtf_size_t>(view->byteLengthAsSizeT()));
}
return true;
}
@@ -148,7 +184,7 @@ bool ConvertBufferSource(const ArrayBufferOrArrayBufferView& buffer_source,
USBDevice::USBDevice(UsbDeviceInfoPtr device_info,
mojo::PendingRemote<UsbDevice> device,
ExecutionContext* context)
- : ContextLifecycleObserver(context),
+ : ExecutionContextLifecycleObserver(context),
device_info_(std::move(device_info)),
device_(std::move(device)),
opened_(false),
@@ -278,11 +314,12 @@ ScriptPromise USBDevice::claimInterface(ScriptState* script_state,
resolver->Resolve();
} else if (IsProtectedInterfaceClass(interface_index)) {
GetExecutionContext()->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kWarning,
- "An attempt to claim a USB device interface "
- "has been blocked because it "
- "implements a protected interface class."));
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning,
+ "An attempt to claim a USB device interface "
+ "has been blocked because it "
+ "implements a protected interface class."));
resolver->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kSecurityError,
"The requested interface implements a protected class."));
@@ -553,15 +590,15 @@ ScriptPromise USBDevice::reset(ScriptState* script_state) {
return promise;
}
-void USBDevice::ContextDestroyed(ExecutionContext*) {
+void USBDevice::ContextDestroyed() {
device_.reset();
device_requests_.clear();
}
-void USBDevice::Trace(blink::Visitor* visitor) {
+void USBDevice::Trace(Visitor* visitor) {
visitor->Trace(device_requests_);
ScriptWrappable::Trace(visitor);
- ContextLifecycleObserver::Trace(visitor);
+ ExecutionContextLifecycleObserver::Trace(visitor);
}
wtf_size_t USBDevice::FindConfigurationIndex(
@@ -625,30 +662,18 @@ bool USBDevice::IsProtectedInterfaceClass(wtf_size_t interface_index) const {
if (std::binary_search(std::begin(kProtectedClasses),
std::end(kProtectedClasses),
alternate->class_code)) {
- return !IsClassWhitelistedForExtension(alternate->class_code);
+#if defined(OS_CHROMEOS)
+ return !IsClassWhitelistedForExtension(alternate->class_code,
+ GetExecutionContext()->Url());
+#else
+ return true;
+#endif
}
}
return false;
}
-bool USBDevice::IsClassWhitelistedForExtension(uint8_t class_code) const {
- const KURL& url = GetExecutionContext()->Url();
- if (url.Protocol() != kExtensionProtocol)
- return false;
-
- const String host = url.Host();
- switch (class_code) {
- case 0x03: // HID
- return host == kImprivataLoginScreenProdExtensionId ||
- host == kImprivataLoginScreenDevExtensionId ||
- host == kImprivataInSessionProdExtensionId ||
- host == kImprivataInSessionDevExtensionId;
- default:
- return false;
- }
-}
-
bool USBDevice::EnsureNoDeviceChangeInProgress(
ScriptPromiseResolver* resolver) const {
if (!device_) {
@@ -1058,7 +1083,8 @@ void USBDevice::AsyncIsochronousTransferIn(
DOMDataView::Create(buffer, byte_offset, packet->transferred_length);
}
packets.push_back(USBIsochronousInTransferPacket::Create(
- ConvertTransferStatus(packet->status), data_view));
+ ConvertTransferStatus(packet->status),
+ NotShared<DOMDataView>(data_view)));
byte_offset += packet->length;
}
resolver->Resolve(USBIsochronousInTransferResult::Create(buffer, packets));
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 ecb4f04a2e4..99f7983b71b 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_device.h
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_device.h
@@ -11,7 +11,7 @@
#include "services/device/public/mojom/usb_device.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/wtf/vector.h"
@@ -23,19 +23,12 @@ class ScriptState;
class USBConfiguration;
class USBControlTransferParameters;
-class USBDevice : public ScriptWrappable, public ContextLifecycleObserver {
+class USBDevice : public ScriptWrappable,
+ public ExecutionContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(USBDevice);
DEFINE_WRAPPERTYPEINFO();
public:
- static USBDevice* Create(
- device::mojom::blink::UsbDeviceInfoPtr device_info,
- mojo::PendingRemote<device::mojom::blink::UsbDevice> device,
- ExecutionContext* context) {
- return MakeGarbageCollected<USBDevice>(std::move(device_info),
- std::move(device), context);
- }
-
explicit USBDevice(device::mojom::blink::UsbDeviceInfoPtr,
mojo::PendingRemote<device::mojom::blink::UsbDevice>,
ExecutionContext*);
@@ -103,10 +96,10 @@ class USBDevice : public ScriptWrappable, public ContextLifecycleObserver {
Vector<unsigned> packet_lengths);
ScriptPromise reset(ScriptState*);
- // ContextLifecycleObserver interface.
- void ContextDestroyed(ExecutionContext*) override;
+ // ExecutionContextLifecycleObserver interface.
+ void ContextDestroyed() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
static const size_t kEndpointsBitsNumber = 16;
@@ -116,7 +109,6 @@ class USBDevice : public ScriptWrappable, public ContextLifecycleObserver {
wtf_size_t FindAlternateIndex(wtf_size_t interface_index,
uint8_t alternate_setting) const;
bool IsProtectedInterfaceClass(wtf_size_t interface_index) const;
- bool IsClassWhitelistedForExtension(uint8_t class_code) const;
bool EnsureNoDeviceChangeInProgress(ScriptPromiseResolver*) const;
bool EnsureNoDeviceOrInterfaceChangeInProgress(ScriptPromiseResolver*) const;
bool EnsureDeviceConfigured(ScriptPromiseResolver*) const;
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 5e0ea5c674d..c60a0b20fe2 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(blink::Visitor* visitor) {
+void USBEndpoint::Trace(Visitor* visitor) {
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 4695d5159c0..343a31311e1 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<const USBAlternateInterface> alternate_;
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.idl b/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.idl
index 679e88250ed..0ad761adc58 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.idl
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.idl
@@ -16,11 +16,10 @@ enum USBEndpointType {
};
[
- Constructor(USBAlternateInterface alternate, octet endpointNumber, USBDirection direction),
Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
- RaisesException=Constructor,
SecureContext
] interface USBEndpoint {
+ [RaisesException] constructor(USBAlternateInterface alternate, octet endpointNumber, USBDirection direction);
readonly attribute octet endpointNumber;
readonly attribute USBDirection direction;
readonly attribute USBEndpointType type;
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 1f1e43d508d..426a942e913 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
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBUSB_USB_IN_TRANSFER_RESULT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBUSB_USB_IN_TRANSFER_RESULT_H_
+#include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_data_view.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
@@ -29,8 +30,9 @@ class USBInTransferResult final : public ScriptWrappable {
return MakeGarbageCollected<USBInTransferResult>(status, nullptr);
}
- static USBInTransferResult* Create(const String& status, DOMDataView* data) {
- return MakeGarbageCollected<USBInTransferResult>(status, data);
+ static USBInTransferResult* Create(const String& status,
+ NotShared<DOMDataView> data) {
+ return MakeGarbageCollected<USBInTransferResult>(status, data.View());
}
USBInTransferResult(const String& status, DOMDataView* data)
@@ -41,7 +43,7 @@ class USBInTransferResult final : public ScriptWrappable {
String status() const { return status_; }
DOMDataView* data() const { return data_; }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(data_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_in_transfer_result.idl b/chromium/third_party/blink/renderer/modules/webusb/usb_in_transfer_result.idl
index 2c9fed6e37b..17353060c41 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_in_transfer_result.idl
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_in_transfer_result.idl
@@ -6,9 +6,9 @@
[
Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
- Constructor(USBTransferStatus status, optional DataView? data),
SecureContext
] interface USBInTransferResult {
+ constructor(USBTransferStatus status, optional DataView? data);
readonly attribute DataView? data;
readonly attribute USBTransferStatus status;
};
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 741f161c808..df7ac329cc6 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(blink::Visitor* visitor) {
+void USBInterface::Trace(Visitor* visitor) {
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 d7a3e2ffdc9..6c6b8c7f0a6 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<const USBDevice> device_;
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_interface.idl b/chromium/third_party/blink/renderer/modules/webusb/usb_interface.idl
index 16da8b78372..933fae5caba 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_interface.idl
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_interface.idl
@@ -5,11 +5,10 @@
// https://wicg.github.io/webusb/#interfaces
[
- Constructor(USBConfiguration configuration, octet interfaceNumber),
Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
- RaisesException=Constructor,
SecureContext
] interface USBInterface {
+ [RaisesException] constructor(USBConfiguration configuration, octet interfaceNumber);
readonly attribute octet interfaceNumber;
readonly attribute USBAlternateInterface? alternate;
readonly attribute FrozenArray<USBAlternateInterface> alternates;
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 b0b06313aaa..3afd1a08a5f 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
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBUSB_USB_ISOCHRONOUS_IN_TRANSFER_PACKET_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBUSB_USB_ISOCHRONOUS_IN_TRANSFER_PACKET_H_
+#include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_data_view.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
@@ -22,8 +23,9 @@ class USBIsochronousInTransferPacket final : public ScriptWrappable {
}
static USBIsochronousInTransferPacket* Create(const String& status,
- DOMDataView* data) {
- return MakeGarbageCollected<USBIsochronousInTransferPacket>(status, data);
+ NotShared<DOMDataView> data) {
+ return MakeGarbageCollected<USBIsochronousInTransferPacket>(status,
+ data.View());
}
USBIsochronousInTransferPacket(const String& status, DOMDataView* data)
@@ -33,7 +35,7 @@ class USBIsochronousInTransferPacket final : public ScriptWrappable {
String status() const { return status_; }
DOMDataView* data() const { return data_; }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(data_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_packet.idl b/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_packet.idl
index d1f213e0a6a..28b0759e9eb 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_packet.idl
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_packet.idl
@@ -5,10 +5,10 @@
// https://wicg.github.io/webusb/#usbisochronousintransferpacket
[
- Constructor(USBTransferStatus status, optional DataView? data),
Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
SecureContext
] interface USBIsochronousInTransferPacket {
+ constructor(USBTransferStatus status, optional DataView? data);
readonly attribute USBTransferStatus status;
readonly attribute DataView? data;
};
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 ba72761511f..c9b896e3390 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
@@ -22,15 +22,16 @@ class USBIsochronousInTransferResult final : public ScriptWrappable {
DOMArrayBuffer* data,
const HeapVector<Member<USBIsochronousInTransferPacket>>& packets) {
DOMDataView* data_view =
- DOMDataView::Create(data, 0, data->DeprecatedByteLengthAsUnsigned());
+ DOMDataView::Create(data, 0, data->ByteLengthAsSizeT());
return MakeGarbageCollected<USBIsochronousInTransferResult>(data_view,
packets);
}
static USBIsochronousInTransferResult* Create(
const HeapVector<Member<USBIsochronousInTransferPacket>>& packets,
- DOMDataView* data) {
- return MakeGarbageCollected<USBIsochronousInTransferResult>(data, packets);
+ NotShared<DOMDataView> data) {
+ return MakeGarbageCollected<USBIsochronousInTransferResult>(data.View(),
+ packets);
}
static USBIsochronousInTransferResult* Create(
@@ -51,7 +52,7 @@ class USBIsochronousInTransferResult final : public ScriptWrappable {
return packets_;
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(data_);
visitor->Trace(packets_);
ScriptWrappable::Trace(visitor);
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_result.idl b/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_result.idl
index ccf61d828f1..d5b459ac36c 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_result.idl
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_result.idl
@@ -5,10 +5,10 @@
// https://wicg.github.io/webusb/#usbisochronousintransferresult
[
- Constructor(sequence<USBIsochronousInTransferPacket> packets, optional DataView? data),
Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
SecureContext
] interface USBIsochronousInTransferResult {
+ constructor(sequence<USBIsochronousInTransferPacket> packets, optional DataView? data);
readonly attribute DataView? data;
readonly attribute FrozenArray<USBIsochronousInTransferPacket> packets;
};
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_packet.idl b/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_packet.idl
index 7473dd031c9..91ab499433c 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_packet.idl
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_packet.idl
@@ -5,10 +5,10 @@
// https://wicg.github.io/webusb/#usbisochronousouttransferpacket
[
- Constructor(USBTransferStatus status, optional unsigned long bytesWritten = 0),
Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
SecureContext
] interface USBIsochronousOutTransferPacket {
+ constructor(USBTransferStatus status, optional unsigned long bytesWritten = 0);
readonly attribute unsigned long bytesWritten;
readonly attribute USBTransferStatus status;
};
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 67bf99591ad..8f1cf5a4151 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(packets_);
ScriptWrappable::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_result.idl b/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_result.idl
index 3062e081a7f..168a1634b5b 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_result.idl
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_result.idl
@@ -5,9 +5,9 @@
// https://wicg.github.io/webusb/#usbisochronousouttransferresult
[
- Constructor(sequence<USBIsochronousOutTransferPacket> packets),
Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
SecureContext
] interface USBIsochronousOutTransferResult {
+ constructor(sequence<USBIsochronousOutTransferPacket> packets);
readonly attribute FrozenArray<USBIsochronousOutTransferPacket> packets;
};
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_out_transfer_result.idl b/chromium/third_party/blink/renderer/modules/webusb/usb_out_transfer_result.idl
index dec458c6cde..58eae2d1aae 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_out_transfer_result.idl
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_out_transfer_result.idl
@@ -6,9 +6,9 @@
[
Exposed(DedicatedWorker WebUSBOnDedicatedWorkers, Window WebUSB),
- Constructor(USBTransferStatus status, optional unsigned long bytesWritten = 0),
SecureContext
] interface USBOutTransferResult {
+ constructor(USBTransferStatus status, optional unsigned long bytesWritten = 0);
readonly attribute unsigned long bytesWritten;
readonly attribute USBTransferStatus status;
};
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 55cb400eb72..90d786324a6 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
@@ -6,6 +6,7 @@
#include "third_party/blink/renderer/core/workers/worker_navigator.h"
#include "third_party/blink/renderer/modules/webusb/usb.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
namespace blink {
@@ -44,13 +45,13 @@ USB* WorkerNavigatorUSB::usb(ScriptState* script_state) {
RuntimeEnabledFeatures::WebUSBOnDedicatedWorkersEnabled();
if (isDedicatedWorkerAndEnabled) {
- usb_ = USB::Create(*context);
+ usb_ = MakeGarbageCollected<USB>(*context);
}
}
return usb_;
}
-void WorkerNavigatorUSB::Trace(blink::Visitor* visitor) {
+void WorkerNavigatorUSB::Trace(Visitor* visitor) {
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 38b240f8ed6..07a02a6fc15 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<USB> usb_;
diff --git a/chromium/third_party/blink/renderer/modules/worklet/worklet_thread_test_common.cc b/chromium/third_party/blink/renderer/modules/worklet/worklet_thread_test_common.cc
index d46d14a6932..e8d5670c629 100644
--- a/chromium/third_party/blink/renderer/modules/worklet/worklet_thread_test_common.cc
+++ b/chromium/third_party/blink/renderer/modules/worklet/worklet_thread_test_common.cc
@@ -28,14 +28,15 @@ CreateAnimationAndPaintWorkletThread(
std::unique_ptr<AnimationAndPaintWorkletThread> thread) {
thread->Start(
std::make_unique<GlobalScopeCreationParams>(
- document->Url(), mojom::ScriptType::kModule,
- OffMainThreadWorkerScriptFetchOption::kEnabled, "Worklet",
- document->UserAgent(), nullptr /* web_worker_fetch_context */,
- Vector<CSPHeaderAndType>(), document->GetReferrerPolicy(),
- document->GetSecurityOrigin(), document->IsSecureContext(),
- document->GetHttpsState(), clients,
- nullptr /* content_settings_client */, document->AddressSpace(),
- OriginTrialContext::GetTokens(document).get(),
+ document->Url(), mojom::blink::ScriptType::kModule, "Worklet",
+ document->UserAgent(),
+ document->GetFrame()->Loader().UserAgentMetadata(),
+ nullptr /* web_worker_fetch_context */, Vector<CSPHeaderAndType>(),
+ document->GetReferrerPolicy(), document->GetSecurityOrigin(),
+ document->IsSecureContext(), document->GetHttpsState(), clients,
+ nullptr /* content_settings_client */,
+ document->GetSecurityContext().AddressSpace(),
+ OriginTrialContext::GetTokens(document->ToExecutionContext()).get(),
base::UnguessableToken::Create(), nullptr /* worker_settings */,
kV8CacheOptionsDefault,
MakeGarbageCollected<WorkletModuleResponsesMap>()),
diff --git a/chromium/third_party/blink/renderer/modules/xr/BUILD.gn b/chromium/third_party/blink/renderer/modules/xr/BUILD.gn
index 2559761839d..2bae19df8ad 100644
--- a/chromium/third_party/blink/renderer/modules/xr/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/xr/BUILD.gn
@@ -6,12 +6,11 @@ import("//third_party/blink/renderer/modules/modules.gni")
blink_modules_sources("xr") {
sources = [
+ "element_xr.h",
"navigator_xr.cc",
"navigator_xr.h",
"type_converters.cc",
"type_converters.h",
- "xr.cc",
- "xr.h",
"xr_anchor.cc",
"xr_anchor.h",
"xr_anchor_set.cc",
@@ -20,6 +19,10 @@ blink_modules_sources("xr") {
"xr_bounded_reference_space.h",
"xr_canvas_input_provider.cc",
"xr_canvas_input_provider.h",
+ "xr_cube_map.cc",
+ "xr_cube_map.h",
+ "xr_dom_overlay_state.cc",
+ "xr_dom_overlay_state.h",
"xr_frame.cc",
"xr_frame.h",
"xr_frame_provider.cc",
@@ -28,8 +31,6 @@ blink_modules_sources("xr") {
"xr_frame_request_callback_collection.h",
"xr_grip_space.cc",
"xr_grip_space.h",
- "xr_hit_result.cc",
- "xr_hit_result.h",
"xr_hit_test_result.cc",
"xr_hit_test_result.h",
"xr_hit_test_source.cc",
@@ -42,6 +43,12 @@ blink_modules_sources("xr") {
"xr_input_source_event.h",
"xr_input_sources_change_event.cc",
"xr_input_sources_change_event.h",
+ "xr_light_estimation.cc",
+ "xr_light_estimation.h",
+ "xr_light_estimation_state.cc",
+ "xr_light_estimation_state.h",
+ "xr_light_probe.cc",
+ "xr_light_probe.h",
"xr_native_origin_information.cc",
"xr_native_origin_information.h",
"xr_object_space.h",
@@ -59,6 +66,8 @@ blink_modules_sources("xr") {
"xr_reference_space.h",
"xr_reference_space_event.cc",
"xr_reference_space_event.h",
+ "xr_reflection_probe.cc",
+ "xr_reflection_probe.h",
"xr_render_state.cc",
"xr_render_state.h",
"xr_rigid_transform.cc",
@@ -70,6 +79,10 @@ blink_modules_sources("xr") {
"xr_setlike.h",
"xr_space.cc",
"xr_space.h",
+ "xr_spherical_harmonics.cc",
+ "xr_spherical_harmonics.h",
+ "xr_system.cc",
+ "xr_system.h",
"xr_target_ray_space.cc",
"xr_target_ray_space.h",
"xr_transient_input_hit_test_result.cc",
diff --git a/chromium/third_party/blink/renderer/modules/xr/DEPS b/chromium/third_party/blink/renderer/modules/xr/DEPS
index ab8648248ac..59d1139c4ec 100644
--- a/chromium/third_party/blink/renderer/modules/xr/DEPS
+++ b/chromium/third_party/blink/renderer/modules/xr/DEPS
@@ -1,5 +1,4 @@
include_rules = [
- "+mojo/public/cpp/bindings/binding.h",
"+mojo/public/cpp/system/platform_handle.h",
"+device/vr/public/mojom/vr_service.mojom-blink.h",
"+device/vr/public/mojom/vr_service.mojom-blink-forward.h",
diff --git a/chromium/third_party/blink/renderer/modules/xr/element_xr.h b/chromium/third_party/blink/renderer/modules/xr/element_xr.h
new file mode 100644
index 00000000000..a82293984a2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/element_xr.h
@@ -0,0 +1,21 @@
+// 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_XR_ELEMENT_XR_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_ELEMENT_XR_H_
+
+#include "third_party/blink/renderer/modules/event_target_modules.h"
+
+namespace blink {
+
+class ElementXR {
+ STATIC_ONLY(ElementXR);
+
+ public:
+ DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(beforexrselect, kBeforexrselect)
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_ELEMENT_XR_H_
diff --git a/chromium/third_party/blink/renderer/modules/xr/element_xr.idl b/chromium/third_party/blink/renderer/modules/xr/element_xr.idl
new file mode 100644
index 00000000000..ba69ad6761a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/element_xr.idl
@@ -0,0 +1,12 @@
+// 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://immersive-web.github.io/dom-overlays/#onbeforexrselect
+
+[
+ ImplementedAs=ElementXR
+]
+partial interface Element {
+ attribute EventHandler onbeforexrselect;
+};
diff --git a/chromium/third_party/blink/renderer/modules/xr/idls.gni b/chromium/third_party/blink/renderer/modules/xr/idls.gni
new file mode 100644
index 00000000000..242d0ab9555
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/idls.gni
@@ -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.
+
+modules_idl_files = [
+ "xr_anchor.idl",
+ "xr_anchor_set.idl",
+ "xr_bounded_reference_space.idl",
+ "xr_dom_overlay_state.idl",
+ "xr_cube_map.idl",
+ "xr_frame.idl",
+ "xr_input_source.idl",
+ "xr_input_source_array.idl",
+ "xr_input_source_event.idl",
+ "xr_input_sources_change_event.idl",
+ "xr_light_estimation.idl",
+ "xr_light_estimation_state.idl",
+ "xr_light_probe.idl",
+ "xr_plane.idl",
+ "xr_plane_detection_state.idl",
+ "xr_plane_set.idl",
+ "xr_pose.idl",
+ "xr_ray.idl",
+ "xr_reference_space.idl",
+ "xr_reference_space_event.idl",
+ "xr_reflection_probe.idl",
+ "xr_render_state.idl",
+ "xr_rigid_transform.idl",
+ "xr_hit_test_result.idl",
+ "xr_hit_test_source.idl",
+ "xr_session.idl",
+ "xr_session_event.idl",
+ "xr_space.idl",
+ "xr_spherical_harmonics.idl",
+ "xr_system.idl",
+ "xr_transient_input_hit_test_result.idl",
+ "xr_transient_input_hit_test_source.idl",
+ "xr_view.idl",
+ "xr_viewer_pose.idl",
+ "xr_viewport.idl",
+ "xr_webgl_layer.idl",
+ "xr_world_information.idl",
+ "xr_world_tracking_state.idl",
+]
+
+modules_callback_function_idl_files = [ "xr_frame_request_callback.idl" ]
+
+modules_dictionary_idl_files = [
+ "xr_dom_overlay_init.idl",
+ "xr_hit_test_options_init.idl",
+ "xr_input_source_event_init.idl",
+ "xr_input_sources_change_event_init.idl",
+ "xr_light_estimation_state_init.idl",
+ "xr_plane_detection_state_init.idl",
+ "xr_reference_space_event_init.idl",
+ "xr_render_state_init.idl",
+ "xr_session_event_init.idl",
+ "xr_session_init.idl",
+ "xr_transient_input_hit_test_options_init.idl",
+ "xr_webgl_layer_init.idl",
+ "xr_world_tracking_state_init.idl",
+]
+
+modules_dependency_idl_files = [
+ "element_xr.idl",
+ "navigator_xr.idl",
+]
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 039e450a1a1..274cf4078f9 100644
--- a/chromium/third_party/blink/renderer/modules/xr/navigator_xr.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/navigator_xr.cc
@@ -10,7 +10,8 @@
#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/inspector/console_message.h"
-#include "third_party/blink/renderer/modules/xr/xr.h"
+#include "third_party/blink/renderer/modules/xr/xr_system.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
@@ -32,7 +33,7 @@ NavigatorXR& NavigatorXR::From(Navigator& navigator) {
return *supplement;
}
-XR* NavigatorXR::xr(Navigator& navigator) {
+XRSystem* NavigatorXR::xr(Navigator& navigator) {
// Always return null when the navigator is detached.
if (!navigator.GetFrame()) {
return nullptr;
@@ -41,7 +42,7 @@ XR* NavigatorXR::xr(Navigator& navigator) {
return NavigatorXR::From(navigator).xr();
}
-XR* NavigatorXR::xr() {
+XRSystem* NavigatorXR::xr() {
auto* document = GetDocument();
// Always return null when the navigator is detached.
@@ -57,7 +58,8 @@ XR* NavigatorXR::xr() {
}
if (!xr_) {
- xr_ = XR::Create(*document->GetFrame(), document->UkmSourceID());
+ xr_ = MakeGarbageCollected<XRSystem>(*document->GetFrame(),
+ document->UkmSourceID());
}
return xr_;
@@ -70,7 +72,7 @@ Document* NavigatorXR::GetDocument() {
return GetSupplementable()->GetFrame()->GetDocument();
}
-void NavigatorXR::Trace(blink::Visitor* visitor) {
+void NavigatorXR::Trace(Visitor* visitor) {
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 89d1e217d67..78342d32497 100644
--- a/chromium/third_party/blink/renderer/modules/xr/navigator_xr.h
+++ b/chromium/third_party/blink/renderer/modules/xr/navigator_xr.h
@@ -13,7 +13,7 @@
namespace blink {
class Document;
-class XR;
+class XRSystem;
class MODULES_EXPORT NavigatorXR final : public GarbageCollected<NavigatorXR>,
public Supplement<Navigator> {
@@ -27,15 +27,15 @@ class MODULES_EXPORT NavigatorXR final : public GarbageCollected<NavigatorXR>,
explicit NavigatorXR(Navigator&);
- static XR* xr(Navigator&);
- XR* xr();
+ static XRSystem* xr(Navigator&);
+ XRSystem* xr();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Document* GetDocument();
- Member<XR> xr_;
+ Member<XRSystem> xr_;
// Gates metrics collection once per local DOM window frame.
bool did_log_navigator_xr_ = false;
diff --git a/chromium/third_party/blink/renderer/modules/xr/navigator_xr.idl b/chromium/third_party/blink/renderer/modules/xr/navigator_xr.idl
index 2e3f5133db9..9e90ef3b41a 100644
--- a/chromium/third_party/blink/renderer/modules/xr/navigator_xr.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/navigator_xr.idl
@@ -7,5 +7,5 @@
ImplementedAs=NavigatorXR
] partial interface Navigator {
// Latest API
- [SecureContext, RuntimeEnabled=WebXR, MeasureAs=NavigatorXR, SameObject] readonly attribute XR xr;
+ [SecureContext, RuntimeEnabled=WebXR, MeasureAs=NavigatorXR, SameObject] readonly attribute XRSystem xr;
};
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 7744b485a63..bfea7162f7e 100644
--- a/chromium/third_party/blink/renderer/modules/xr/type_converters.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/type_converters.cc
@@ -47,9 +47,9 @@ TypeConverter<blink::TransformationMatrix, device::mojom::blink::VRPosePtr>::
}
if (pose->position) {
- decomp.translate_x = pose->position->X();
- decomp.translate_y = pose->position->Y();
- decomp.translate_z = pose->position->Z();
+ decomp.translate_x = pose->position->x();
+ decomp.translate_y = pose->position->y();
+ decomp.translate_z = pose->position->z();
}
result.Recompose(decomp);
@@ -77,9 +77,9 @@ TypeConverter<blink::TransformationMatrix, device::mojom::blink::PosePtr>::
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();
+ decomp.translate_x = pose->position.x();
+ decomp.translate_y = pose->position.y();
+ decomp.translate_z = pose->position.z();
result.Recompose(decomp);
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 739fc6462b1..01770130987 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_anchor.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_anchor.cc
@@ -4,31 +4,30 @@
#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.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"
namespace blink {
-XRAnchor::XRAnchor(uint64_t id, XRSession* session)
- : id_(id), session_(session), anchor_data_(base::nullopt) {}
-
XRAnchor::XRAnchor(uint64_t id,
XRSession* session,
- const device::mojom::blink::XRAnchorDataPtr& anchor_data,
- double timestamp)
- : id_(id),
- session_(session),
- anchor_data_(base::in_place, anchor_data, timestamp) {}
+ const device::mojom::blink::XRAnchorData& anchor_data)
+ : id_(id), session_(session) {
+ // No need for else - if pose is not present, the default-constructed unique
+ // ptr is fine.
+ if (anchor_data.pose) {
+ SetMojoFromAnchor(
+ mojo::ConvertTo<blink::TransformationMatrix>(anchor_data.pose));
+ }
+}
-void XRAnchor::Update(const device::mojom::blink::XRAnchorDataPtr& anchor_data,
- double timestamp) {
- if (!anchor_data_) {
- anchor_data_ = AnchorData(anchor_data, timestamp);
+void XRAnchor::Update(const device::mojom::blink::XRAnchorData& anchor_data) {
+ if (anchor_data.pose) {
+ SetMojoFromAnchor(
+ mojo::ConvertTo<blink::TransformationMatrix>(anchor_data.pose));
} else {
- *anchor_data_->pose_matrix_ =
- mojo::ConvertTo<blink::TransformationMatrix>(anchor_data->pose);
- anchor_data_->last_changed_time_ = timestamp;
+ mojo_from_anchor_ = nullptr;
}
}
@@ -37,9 +36,7 @@ uint64_t XRAnchor::id() const {
}
XRSpace* XRAnchor::anchorSpace() const {
- if (!anchor_data_) {
- return nullptr;
- }
+ DCHECK(mojo_from_anchor_);
if (!anchor_space_) {
anchor_space_ =
@@ -49,43 +46,31 @@ XRSpace* XRAnchor::anchorSpace() const {
return anchor_space_;
}
-TransformationMatrix XRAnchor::poseMatrix() const {
- if (anchor_data_) {
- return *anchor_data_->pose_matrix_;
+base::Optional<TransformationMatrix> XRAnchor::MojoFromObject() const {
+ if (!mojo_from_anchor_) {
+ return base::nullopt;
}
- // |poseMatrix()| shouldn't be called by anyone except XRObjectSpace and if
- // XRObjectSpace already exists for this anchor, then anchor_data_ should also
- // exist for this anchor.
- NOTREACHED();
- return {};
-}
-
-double XRAnchor::lastChangedTime(bool& is_null) const {
- if (!anchor_data_) {
- is_null = true;
- return 0;
- }
-
- is_null = false;
- return anchor_data_->last_changed_time_;
+ return *mojo_from_anchor_;
}
void XRAnchor::detach() {
session_->xr()->xrEnvironmentProviderRemote()->DetachAnchor(id_);
}
-void XRAnchor::Trace(blink::Visitor* visitor) {
+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) {
visitor->Trace(session_);
visitor->Trace(anchor_space_);
ScriptWrappable::Trace(visitor);
}
-XRAnchor::AnchorData::AnchorData(
- const device::mojom::blink::XRAnchorDataPtr& anchor_data,
- double timestamp)
- : pose_matrix_(std::make_unique<TransformationMatrix>(
- mojo::ConvertTo<blink::TransformationMatrix>(anchor_data->pose))),
- last_changed_time_(timestamp) {}
-
} // namespace blink
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 f9c2c505d82..6ffbc612ceb 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_anchor.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_anchor.h
@@ -21,46 +21,36 @@ class XRAnchor : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- XRAnchor(uint64_t id, XRSession* session);
-
XRAnchor(uint64_t id,
XRSession* session,
- const device::mojom::blink::XRAnchorDataPtr& anchor_data,
- double timestamp);
+ const device::mojom::blink::XRAnchorData& anchor_data);
uint64_t id() const;
XRSpace* anchorSpace() const;
- TransformationMatrix poseMatrix() const;
-
- double lastChangedTime(bool& is_null) const;
+ base::Optional<TransformationMatrix> MojoFromObject() const;
void detach();
- void Update(const device::mojom::blink::XRAnchorDataPtr& anchor_data,
- double timestamp);
+ void Update(const device::mojom::blink::XRAnchorData& anchor_data);
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
- // AnchorData will only be present in an XRAnchor after the anchor was updated
- // for the first time (CreateAnchor returns a promise that will resolve to an
- // XRAnchor prior to first update of the anchor).
- struct AnchorData {
- // Anchor's pose in device (mojo) space.
- std::unique_ptr<TransformationMatrix> pose_matrix_;
- double last_changed_time_;
-
- AnchorData(const device::mojom::blink::XRAnchorDataPtr& anchor_data,
- double timestamp);
- };
+ void SetMojoFromAnchor(const TransformationMatrix& mojo_from_anchor);
const uint64_t id_;
Member<XRSession> session_;
- base::Optional<AnchorData> anchor_data_;
+ // |mojo_from_anchor_| will be non-null in an XRAnchor after the anchor was
+ // updated for the first time - this *must* happen in the same frame in which
+ // the anchor was created for the anchor to be fully usable. It is currently
+ // ensured by XRSession - anchors that got created prior to receiving the
+ // result from mojo call to GetFrameData are not returned to the application
+ // until their poses are known.
+ std::unique_ptr<TransformationMatrix> 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 337c56ef13f..48ca880cd09 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_anchor.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_anchor.idl
@@ -5,11 +5,10 @@
[
SecureContext,
Exposed=Window,
- RuntimeEnabled=WebXRAnchors
+ RuntimeEnabled=WebXRIncubations
]
interface XRAnchor {
- readonly attribute XRSpace? anchorSpace;
- readonly attribute DOMHighResTimeStamp? lastChangedTime;
+ readonly attribute XRSpace anchorSpace;
void detach();
};
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 67e1ad746fd..47588f58545 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(blink::Visitor* visitor) {
+void XRAnchorSet::Trace(Visitor* visitor) {
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 cc4e2bec4f1..fecd15421b2 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(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) 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 aee2cb2d1bb..ddb69dd718c 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=WebXRAnchors
+ RuntimeEnabled=WebXRIncubations
]
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 bef36eb3ffc..e0b47c1aea7 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
@@ -15,6 +15,10 @@
namespace blink {
namespace {
+
+// Bounds must be a valid polygon (at least 3 vertices).
+constexpr wtf_size_t kMinimumNumberOfBoundVertices = 3;
+
float RoundCm(float val) {
// Float round will only round to the nearest whole number. In order to get
// two decimal points of precision, we need to move the decimal out then
@@ -38,12 +42,6 @@ XRBoundedReferenceSpace::XRBoundedReferenceSpace(
XRBoundedReferenceSpace::~XRBoundedReferenceSpace() = default;
-// No default pose for bounded reference spaces.
-std::unique_ptr<TransformationMatrix>
-XRBoundedReferenceSpace::DefaultViewerPose() {
- return nullptr;
-}
-
void XRBoundedReferenceSpace::EnsureUpdated() {
// Check first to see if the stage parameters have updated since the last
// call. We only need to update the transform and bounds if it has.
@@ -57,57 +55,52 @@ void XRBoundedReferenceSpace::EnsureUpdated() {
if (display_info && display_info->stage_parameters) {
// Use the transform given by xrDisplayInfo's stage_parameters if available.
- bounded_space_from_mojo_ = std::make_unique<TransformationMatrix>(
+ bounded_native_from_mojo_ = std::make_unique<TransformationMatrix>(
display_info->stage_parameters->standing_transform.matrix());
// In order to ensure that the bounds continue to line up with the user's
- // physical environment we need to transform by the inverse of the
- // originOffset. TODO(https://crbug.com/1008466): move originOffset to
- // separate class? If yes, that class would need to apply a transform
- // in the boundsGeometry accessor.
- TransformationMatrix bounds_transform = InverseOriginOffsetMatrix();
+ // physical environment we need to transform them from native to offset.
+ // Bounds are provided in our native coordinate space.
+ // TODO(https://crbug.com/1008466): move originOffset to separate class? If
+ // yes, that class would need to apply a transform in the boundsGeometry
+ // accessor.
+ TransformationMatrix offset_from_native = OffsetFromNativeMatrix();
// We may not have bounds if we've lost tracking after being created.
// Whether we have them or not, we need to clear the existing bounds.
- bounds_geometry_.clear();
- if (display_info->stage_parameters->bounds) {
+ offset_bounds_geometry_.clear();
+ if (display_info->stage_parameters->bounds &&
+ display_info->stage_parameters->bounds->size() >=
+ kMinimumNumberOfBoundVertices) {
for (const auto& bound : *(display_info->stage_parameters->bounds)) {
- FloatPoint3D p =
- bounds_transform.MapPoint(FloatPoint3D(bound.X(), 0.0, bound.Z()));
- bounds_geometry_.push_back(RoundedDOMPoint(p));
+ FloatPoint3D p = offset_from_native.MapPoint(
+ FloatPoint3D(bound.x(), 0.0, bound.z()));
+ offset_bounds_geometry_.push_back(RoundedDOMPoint(p));
}
}
} else {
// If stage parameters aren't available set the transform to null, which
// will subsequently cause this reference space to return null poses.
- bounded_space_from_mojo_.reset();
- bounds_geometry_.clear();
+ bounded_native_from_mojo_.reset();
+ offset_bounds_geometry_.clear();
}
DispatchEvent(*XRReferenceSpaceEvent::Create(event_type_names::kReset, this));
}
-// Gets the pose of the mojo origin in this reference space, corresponding to a
-// transform from mojo coordinates to reference space coordinates. Ideally in
-// the future this reference space can be used without additional transforms,
-// with the various XR backends returning poses already in the right space.
-std::unique_ptr<TransformationMatrix> XRBoundedReferenceSpace::SpaceFromMojo(
- const TransformationMatrix& mojo_from_viewer) {
+std::unique_ptr<TransformationMatrix>
+XRBoundedReferenceSpace::NativeFromMojo() {
EnsureUpdated();
- // If the reference space has a transform apply it to the base pose and return
- // that, otherwise return null.
- if (bounded_space_from_mojo_) {
- std::unique_ptr<TransformationMatrix> space_from_mojo(
- std::make_unique<TransformationMatrix>(*bounded_space_from_mojo_));
- return space_from_mojo;
- }
- return nullptr;
+ if (!bounded_native_from_mojo_)
+ return nullptr;
+
+ return std::make_unique<TransformationMatrix>(*bounded_native_from_mojo_);
}
HeapVector<Member<DOMPointReadOnly>> XRBoundedReferenceSpace::boundsGeometry() {
EnsureUpdated();
- return bounds_geometry_;
+ return offset_bounds_geometry_;
}
base::Optional<XRNativeOriginInformation>
@@ -115,8 +108,8 @@ XRBoundedReferenceSpace::NativeOrigin() const {
return XRNativeOriginInformation::Create(this);
}
-void XRBoundedReferenceSpace::Trace(blink::Visitor* visitor) {
- visitor->Trace(bounds_geometry_);
+void XRBoundedReferenceSpace::Trace(Visitor* visitor) {
+ 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 8f871b2a961..faa52fcbd0f 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
@@ -19,15 +19,13 @@ class XRBoundedReferenceSpace final : public XRReferenceSpace {
XRBoundedReferenceSpace(XRSession*, XRRigidTransform*);
~XRBoundedReferenceSpace() override;
- std::unique_ptr<TransformationMatrix> DefaultViewerPose() override;
- std::unique_ptr<TransformationMatrix> SpaceFromMojo(
- const TransformationMatrix& mojo_from_viewer) override;
+ std::unique_ptr<TransformationMatrix> NativeFromMojo() override;
HeapVector<Member<DOMPointReadOnly>> boundsGeometry();
base::Optional<XRNativeOriginInformation> NativeOrigin() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void OnReset() override;
@@ -37,8 +35,8 @@ class XRBoundedReferenceSpace final : public XRReferenceSpace {
void EnsureUpdated();
- HeapVector<Member<DOMPointReadOnly>> bounds_geometry_;
- std::unique_ptr<TransformationMatrix> bounded_space_from_mojo_;
+ HeapVector<Member<DOMPointReadOnly>> offset_bounds_geometry_;
+ std::unique_ptr<TransformationMatrix> bounded_native_from_mojo_;
unsigned int stage_parameters_id_ = 0;
};
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 79b58e56eda..2b15f65c0cd 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
@@ -8,10 +8,10 @@
#include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
#include "third_party/blink/renderer/core/events/pointer_event.h"
#include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
-#include "third_party/blink/renderer/modules/xr/xr.h"
#include "third_party/blink/renderer/modules/xr/xr_frame_provider.h"
#include "third_party/blink/renderer/modules/xr/xr_input_source.h"
#include "third_party/blink/renderer/modules/xr/xr_session.h"
+#include "third_party/blink/renderer/modules/xr/xr_system.h"
#include "third_party/blink/renderer/modules/xr/xr_view.h"
namespace blink {
@@ -27,7 +27,7 @@ class XRCanvasInputEventListener : public NativeEventListener {
if (!input_provider_->ShouldProcessEvents())
return;
- PointerEvent* pointer_event = ToPointerEvent(event);
+ auto* pointer_event = To<PointerEvent>(event);
DCHECK(pointer_event);
if (!pointer_event->isPrimary())
return;
@@ -40,7 +40,7 @@ class XRCanvasInputEventListener : public NativeEventListener {
}
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(input_provider_);
EventListener::Trace(visitor);
}
@@ -128,7 +128,7 @@ void XRCanvasInputProvider::ClearInputSource() {
input_source_ = nullptr;
}
-void XRCanvasInputProvider::Trace(blink::Visitor* visitor) {
+void XRCanvasInputProvider::Trace(Visitor* visitor) {
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 3662b8d72ad..f66c96e099a 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(blink::Visitor*);
+ virtual void Trace(Visitor*);
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
new file mode 100644
index 00000000000..b2973a05e51
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_cube_map.cc
@@ -0,0 +1,105 @@
+// 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/xr/xr_cube_map.h"
+
+#include "device/vr/public/mojom/vr_service.mojom-blink.h"
+#include "third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h"
+#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"
+
+namespace {
+bool IsPowerOfTwo(uint32_t value) {
+ return value && (value & (value - 1)) == 0;
+}
+
+static constexpr char const* kErrorNonCubemapTexture =
+ "Cannot pass non-cubemap texture";
+static constexpr char const* kErrorContextMismatch = "Context mismatch";
+
+} // namespace
+
+namespace blink {
+
+XRCubeMap::XRCubeMap(const device::mojom::blink::XRCubeMap& cube_map) {
+ constexpr auto kNumComponentsPerPixel =
+ device::mojom::blink::XRCubeMap::kNumComponentsPerPixel;
+ static_assert(kNumComponentsPerPixel == 4,
+ "XRCubeMaps are expected to be in the RGBA16F format");
+
+ // Cube map sides must all be a power-of-two image
+ bool valid = IsPowerOfTwo(cube_map.width_and_height);
+ const size_t expected_size =
+ cube_map.width_and_height * cube_map.width_and_height;
+ valid &= cube_map.positive_x.size() == expected_size;
+ valid &= cube_map.negative_x.size() == expected_size;
+ valid &= cube_map.positive_y.size() == expected_size;
+ valid &= cube_map.negative_y.size() == expected_size;
+ valid &= cube_map.positive_z.size() == expected_size;
+ valid &= cube_map.negative_z.size() == expected_size;
+ DCHECK(valid);
+
+ width_and_height_ = cube_map.width_and_height;
+ positive_x_ = cube_map.positive_x;
+ negative_x_ = cube_map.negative_x;
+ positive_y_ = cube_map.positive_y;
+ negative_y_ = cube_map.negative_y;
+ positive_z_ = cube_map.positive_z;
+ negative_z_ = cube_map.negative_z;
+}
+
+WebGLTexture* XRCubeMap::updateWebGLEnvironmentCube(
+ WebGL2RenderingContextBase* context,
+ WebGLTexture* texture,
+ ExceptionState& exception_state) const {
+ // If they haven't supplied us with a texture, Create a new one.
+ if (!texture) {
+ texture = MakeGarbageCollected<WebGLTexture>(context);
+ } else if (texture->HasEverBeenBound() &&
+ texture->GetTarget() != GL_TEXTURE_CUBE_MAP) {
+ exception_state.ThrowTypeError(kErrorNonCubemapTexture);
+ return nullptr;
+ } else if (texture->ContextGroup() != context->ContextGroup()) {
+ exception_state.ThrowTypeError(kErrorContextMismatch);
+ return nullptr;
+ }
+
+ auto* gl = context->ContextGL();
+ texture->SetTarget(GL_TEXTURE_CUBE_MAP);
+ gl->BindTexture(GL_TEXTURE_CUBE_MAP, texture->Object());
+
+ // Cannot generate mip-maps for half-float textures, so use linear filtering
+ gl->TexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ gl->TexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ uint16_t const* const cubemap_images[] = {
+ positive_x_.data()->components, negative_x_.data()->components,
+ positive_y_.data()->components, negative_y_.data()->components,
+ positive_z_.data()->components, negative_z_.data()->components,
+ };
+ GLenum const cubemap_targets[] = {
+ GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
+ };
+
+ // Update image for each side of the cube map
+ for (int i = 0; i < 6; ++i) {
+ auto* image = cubemap_images[i];
+ auto target = cubemap_targets[i];
+
+ gl->TexImage2D(target, 0, GL_RGBA16F, width_and_height_, width_and_height_,
+ 0, GL_RGBA, GL_HALF_FLOAT, image);
+ }
+
+ gl->BindTexture(GL_TEXTURE_CUBE_MAP, 0);
+
+ // Debug check for success
+ DCHECK(gl->GetError() == GL_NO_ERROR);
+
+ return texture;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_cube_map.h b/chromium/third_party/blink/renderer/modules/xr/xr_cube_map.h
new file mode 100644
index 00000000000..78241320559
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_cube_map.h
@@ -0,0 +1,42 @@
+// 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_XR_XR_CUBE_MAP_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_CUBE_MAP_H_
+
+#include "base/util/type_safety/pass_key.h"
+#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h"
+#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+
+namespace blink {
+
+class WebGL2RenderingContextBase;
+class WebGLTexture;
+class ExceptionState;
+
+class XRCubeMap : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ explicit XRCubeMap(const device::mojom::blink::XRCubeMap& cube_map);
+
+ WebGLTexture* updateWebGLEnvironmentCube(
+ WebGL2RenderingContextBase* context,
+ WebGLTexture* texture,
+ ExceptionState& exception_state) const;
+
+ private:
+ uint32_t width_and_height_ = 0;
+ WTF::Vector<device::RgbaTupleF16> positive_x_;
+ WTF::Vector<device::RgbaTupleF16> negative_x_;
+ WTF::Vector<device::RgbaTupleF16> positive_y_;
+ WTF::Vector<device::RgbaTupleF16> negative_y_;
+ WTF::Vector<device::RgbaTupleF16> positive_z_;
+ WTF::Vector<device::RgbaTupleF16> negative_z_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_CUBE_MAP_H_
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_cube_map.idl b/chromium/third_party/blink/renderer/modules/xr/xr_cube_map.idl
new file mode 100644
index 00000000000..fd68d986f08
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_cube_map.idl
@@ -0,0 +1,14 @@
+// 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.
+
+[
+ SecureContext,
+ Exposed=Window,
+ RuntimeEnabled=WebXRIncubations
+]
+interface XRCubeMap {
+ [RaisesException]
+ WebGLTexture updateWebGLEnvironmentCube(WebGL2RenderingContext context, WebGLTexture? texture);
+};
+
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_init.idl b/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_init.idl
new file mode 100644
index 00000000000..7a7d2791d0e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_init.idl
@@ -0,0 +1,8 @@
+// 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://immersive-web.github.io/dom-overlays/#dictdef-xrdomoverlayinit
+dictionary XRDOMOverlayInit {
+ required Element root;
+};
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
new file mode 100644
index 00000000000..10db7030a66
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.cc
@@ -0,0 +1,31 @@
+// 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/xr/xr_dom_overlay_state.h"
+
+#include "third_party/blink/renderer/core/dom/element.h"
+
+namespace blink {
+
+namespace {
+
+const String MapOverlayType(XRDOMOverlayState::DOMOverlayType type) {
+ switch (type) {
+ case XRDOMOverlayState::DOMOverlayType::kScreen:
+ return "screen";
+ case XRDOMOverlayState::DOMOverlayType::kFloating:
+ return "floating";
+ }
+}
+
+} // namespace
+
+XRDOMOverlayState::XRDOMOverlayState(DOMOverlayType type)
+ : type_string_(MapOverlayType(type)) {}
+
+void XRDOMOverlayState::Trace(Visitor* visitor) {
+ ScriptWrappable::Trace(visitor);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..f39b2705bdb
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.h
@@ -0,0 +1,42 @@
+// 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_XR_XR_DOM_OVERLAY_STATE_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_DOM_OVERLAY_STATE_H_
+
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+// Implementation of
+// https://immersive-web.github.io/dom-overlays/#dictdef-xrdomoverlaystate, used
+// as SameObject instances owned by |XRSession|.
+class XRDOMOverlayState : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ enum class DOMOverlayType {
+ kScreen = 0,
+ kFloating,
+ };
+
+ explicit XRDOMOverlayState(DOMOverlayType type);
+ ~XRDOMOverlayState() override = default;
+
+ const String& type() const { return type_string_; }
+
+ void Trace(Visitor*) override;
+
+ private:
+ const String type_string_;
+ // Currently, instances of this class are created at session start, on the
+ // assumption that the objects are very small. If this becomes more complex in
+ // the future, i.e. when adding additional members, consider switching to lazy
+ // instantiation.
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_DOM_OVERLAY_STATE_H_
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.idl b/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.idl
new file mode 100644
index 00000000000..fcc12cfce90
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.idl
@@ -0,0 +1,17 @@
+// 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://immersive-web.github.io/dom-overlays/#enumdef-xrdomoverlaytype
+enum XRDOMOverlayType {
+ "screen",
+ "floating",
+};
+
+// https://immersive-web.github.io/dom-overlays/#dictdef-xrdomoverlaystate
+[
+ SecureContext,
+ Exposed=Window
+] interface XRDOMOverlayState {
+ readonly attribute XRDOMOverlayType type;
+};
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 b7cac4f9591..8e3bb4bb818 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_frame.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame.cc
@@ -42,6 +42,7 @@ XRFrame::XRFrame(XRSession* session, XRWorldInformation* world_information)
XRViewerPose* XRFrame::getViewerPose(XRReferenceSpace* reference_space,
ExceptionState& exception_state) const {
+ DVLOG(3) << __func__;
if (!is_active_) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kInactiveFrame);
@@ -55,6 +56,7 @@ XRViewerPose* XRFrame::getViewerPose(XRReferenceSpace* reference_space,
}
if (!reference_space) {
+ DVLOG(1) << __func__ << ": reference space not present, returning null";
return nullptr;
}
@@ -72,18 +74,24 @@ XRViewerPose* XRFrame::getViewerPose(XRReferenceSpace* reference_space,
session_->LogGetPose();
- std::unique_ptr<TransformationMatrix> pose =
- reference_space->SpaceFromViewerWithDefaultAndOffset(
- mojo_from_viewer_.get());
- if (!pose) {
+ std::unique_ptr<TransformationMatrix> offset_space_from_viewer =
+ reference_space->OffsetFromViewer();
+
+ // Can only update an XRViewerPose's views with an invertible matrix.
+ if (!(offset_space_from_viewer && offset_space_from_viewer->IsInvertible())) {
+ DVLOG(1) << __func__
+ << ": offset_space_from_viewer is invalid or not invertible - "
+ "returning nullptr, offset_space_from_viewer valid? "
+ << (offset_space_from_viewer ? true : false);
return nullptr;
}
- return MakeGarbageCollected<XRViewerPose>(session(), *pose);
+ return MakeGarbageCollected<XRViewerPose>(session(),
+ *offset_space_from_viewer);
}
XRAnchorSet* XRFrame::trackedAnchors() const {
- return session_->trackedAnchors();
+ return session_->TrackedAnchors();
}
// Return an XRPose that has a transform of basespace_from_space, while
@@ -121,13 +129,7 @@ XRPose* XRFrame::getPose(XRSpace* space,
return nullptr;
}
- return space->getPose(basespace, mojo_from_viewer_.get());
-}
-
-void XRFrame::SetMojoFromViewer(const TransformationMatrix& mojo_from_viewer,
- bool emulated_position) {
- mojo_from_viewer_ = std::make_unique<TransformationMatrix>(mojo_from_viewer);
- emulated_position_ = emulated_position;
+ return space->getPose(basespace);
}
void XRFrame::Deactivate() {
@@ -164,7 +166,44 @@ XRFrame::getHitTestResultsForTransientInput(
return hit_test_source->Results();
}
-void XRFrame::Trace(blink::Visitor* visitor) {
+ScriptPromise XRFrame::createAnchor(ScriptState* script_state,
+ XRRigidTransform* initial_pose,
+ XRSpace* space,
+ ExceptionState& exception_state) {
+ DVLOG(2) << __func__;
+
+ if (!is_active_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ kInactiveFrame);
+ return {};
+ }
+
+ if (!initial_pose) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ XRSession::kNoRigidTransformSpecified);
+ return {};
+ }
+
+ if (!space) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ XRSession::kNoSpaceSpecified);
+ return {};
+ }
+
+ auto maybe_mojo_from_offset_space = space->MojoFromOffsetMatrix();
+
+ if (!maybe_mojo_from_offset_space) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ XRSession::kUnableToRetrieveMatrix);
+ return ScriptPromise();
+ }
+
+ return session_->CreateAnchor(script_state, initial_pose->TransformMatrix(),
+ *maybe_mojo_from_offset_space, base::nullopt,
+ exception_state);
+}
+
+void XRFrame::Trace(Visitor* visitor) {
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 a6376db5aef..15e9e5996fd 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_frame.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame.h
@@ -9,6 +9,7 @@
#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/platform/bindings/script_state.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"
@@ -23,6 +24,7 @@ class XRHitTestSource;
class XRInputSource;
class XRPose;
class XRReferenceSpace;
+class XRRigidTransform;
class XRSession;
class XRSpace;
class XRTransientInputHitTestResult;
@@ -43,9 +45,7 @@ class XRFrame final : public ScriptWrappable {
XRWorldInformation* worldInformation() const { return world_information_; }
XRAnchorSet* trackedAnchors() const;
- void SetMojoFromViewer(const TransformationMatrix&, bool emulated_position);
-
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void Deactivate();
@@ -62,7 +62,10 @@ class XRFrame final : public ScriptWrappable {
XRTransientInputHitTestSource* hit_test_source,
ExceptionState& exception_state);
- bool EmulatedPosition() const { return emulated_position_; }
+ ScriptPromise createAnchor(ScriptState* script_state,
+ XRRigidTransform* initial_pose,
+ XRSpace* space,
+ ExceptionState& exception_state);
private:
std::unique_ptr<TransformationMatrix> GetAdjustedPoseMatrix(XRSpace*) const;
@@ -73,10 +76,6 @@ class XRFrame final : public ScriptWrappable {
const Member<XRSession> session_;
- // Viewer pose in mojo space, the matrix maps from viewer (headset) space to
- // mojo space.
- std::unique_ptr<TransformationMatrix> mojo_from_viewer_;
-
// Frames are only active during callbacks. getPose and getViewerPose should
// only be called from JS on active frames.
bool is_active_ = true;
@@ -85,8 +84,6 @@ class XRFrame final : public ScriptWrappable {
// animation frames. getViewerPose should only be called from JS on active
// animation frames.
bool is_animation_frame_ = false;
-
- bool emulated_position_ = false;
};
} // namespace blink
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 4c0cdfa69b0..661c06eb709 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_frame.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame.idl
@@ -12,9 +12,12 @@
// 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=WebXRPlaneDetection] readonly attribute XRWorldInformation worldInformation;
+ [RuntimeEnabled=WebXRIncubations] readonly attribute XRWorldInformation worldInformation;
- [RuntimeEnabled=WebXRAnchors] readonly attribute XRAnchorSet trackedAnchors;
+ [RuntimeEnabled=WebXRIncubations]
+ readonly attribute XRAnchorSet trackedAnchors;
+ [RuntimeEnabled=WebXRIncubations, CallWith=ScriptState, RaisesException]
+ Promise<XRAnchor> createAnchor(XRRigidTransform initial_pose, XRSpace space);
[RaisesException] XRViewerPose? getViewerPose(XRReferenceSpace referenceSpace);
[RaisesException] XRPose? getPose(XRSpace space, XRSpace relativeTo);
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 6b562aab546..5be7af5a8ac 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
@@ -13,9 +13,10 @@
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
-#include "third_party/blink/renderer/modules/xr/xr.h"
+#include "third_party/blink/renderer/modules/xr/xr_light_estimation_state.h"
#include "third_party/blink/renderer/modules/xr/xr_plane_detection_state.h"
#include "third_party/blink/renderer/modules/xr/xr_session.h"
+#include "third_party/blink/renderer/modules/xr/xr_system.h"
#include "third_party/blink/renderer/modules/xr/xr_viewport.h"
#include "third_party/blink/renderer/modules/xr/xr_webgl_layer.h"
#include "third_party/blink/renderer/modules/xr/xr_world_tracking_state.h"
@@ -39,7 +40,7 @@ class XRFrameProviderRequestCallback
frame_provider_->OnNonImmersiveVSync(high_res_time_ms);
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(frame_provider_);
FrameRequestCallbackCollection::FrameCallback::Trace(visitor);
@@ -50,7 +51,7 @@ class XRFrameProviderRequestCallback
} // namespace
-XRFrameProvider::XRFrameProvider(XR* xr)
+XRFrameProvider::XRFrameProvider(XRSystem* xr)
: xr_(xr), last_has_focus_(xr->IsFrameFocused()) {
frame_transport_ = MakeGarbageCollected<XRFrameTransport>();
}
@@ -161,7 +162,8 @@ void XRFrameProvider::RequestFrame(XRSession* session) {
DCHECK(session);
auto options = device::mojom::blink::XRFrameDataRequestOptions::New(
- session->worldTrackingState()->planeDetectionState()->enabled());
+ session->worldTrackingState()->planeDetectionState()->enabled(),
+ session->worldTrackingState()->lightEstimationState()->enabled());
// Immersive frame logic.
if (session->immersive()) {
@@ -255,9 +257,12 @@ void XRFrameProvider::OnImmersiveFrameData(
immersive_frame_pose_ = std::move(data->pose);
if (immersive_frame_pose_) {
+ DVLOG(3) << __func__ << ": pose available, emulated_position="
+ << immersive_frame_pose_->emulated_position;
is_immersive_frame_position_emulated_ =
immersive_frame_pose_->emulated_position;
} else {
+ DVLOG(2) << __func__ << ": emulating immersive frame position";
is_immersive_frame_position_emulated_ = true;
}
@@ -323,7 +328,7 @@ void XRFrameProvider::OnNonImmersiveFrameData(
}
if (frame_data) {
- request->value = std::move(frame_data->pose);
+ request->value = std::move(frame_data);
} else {
// Unexpectedly didn't get frame data, and we don't have a timestamp.
// Try to request a regular animation frame to avoid getting stuck.
@@ -350,7 +355,8 @@ void XRFrameProvider::RequestNonImmersiveFrameData(XRSession* session) {
} else {
auto& data_provider = provider->value;
auto options = device::mojom::blink::XRFrameDataRequestOptions::New(
- session->worldTrackingState()->planeDetectionState()->enabled());
+ session->worldTrackingState()->planeDetectionState()->enabled(),
+ session->worldTrackingState()->lightEstimationState()->enabled());
data_provider->GetFrameData(
std::move(options),
@@ -367,6 +373,11 @@ void XRFrameProvider::ProcessScheduledFrame(
TRACE_EVENT2("gpu", "XRFrameProvider::ProcessScheduledFrame", "frame",
frame_id_, "timestamp", high_res_now_ms);
+ LocalFrame* frame = xr_->GetFrame();
+ if (!frame) {
+ return;
+ }
+
if (!xr_->IsFrameFocused() && !immersive_session_) {
return; // Not currently focused, so we won't expose poses (except to
// immersive sessions).
@@ -426,7 +437,14 @@ void XRFrameProvider::ProcessScheduledFrame(
immersive_session_->UpdateStageParameters(frame_data->stage_parameters);
}
- immersive_session_->OnFrame(high_res_now_ms, buffer_mailbox_holder_);
+ // Run immersive_session_->OnFrame() in a posted task to ensure that
+ // createAnchor promises get a chance to run - the presentation frame state
+ // is already updated.
+ frame->GetTaskRunner(blink::TaskType::kInternalMedia)
+ ->PostTask(FROM_HERE,
+ WTF::Bind(&XRSession::OnFrame,
+ WrapWeakPersistent(immersive_session_.Get()),
+ high_res_now_ms, buffer_mailbox_holder_));
} else {
// In the process of fulfilling the frame requests for each session they are
// extremely likely to request another frame. Work off of a separate list
@@ -443,13 +461,15 @@ void XRFrameProvider::ProcessScheduledFrame(
if (session->ended())
continue;
- const auto& frame_pose = request.value;
+ const auto& inline_frame_data = request.value;
+ device::mojom::blink::VRPosePtr inline_pose_data =
+ inline_frame_data ? std::move(inline_frame_data->pose) : nullptr;
// Prior to updating input source state, update the state needed to create
// presentation frame as newly created presentation frame will get passed
// to the input source select[/start/end] events.
session->UpdatePresentationFrameState(
- high_res_now_ms, frame_pose, frame_data, frame_id_,
+ high_res_now_ms, inline_pose_data, inline_frame_data, frame_id_,
true /* Non-immersive positions are always emulated */);
// If the input state change caused this session to end, we should stop
@@ -457,7 +477,7 @@ void XRFrameProvider::ProcessScheduledFrame(
if (session->ended())
continue;
- if (frame_data && frame_data->mojo_space_reset) {
+ if (inline_frame_data && inline_frame_data->mojo_space_reset) {
session->OnMojoSpaceReset();
}
@@ -465,7 +485,13 @@ void XRFrameProvider::ProcessScheduledFrame(
if (session->ended())
continue;
- session->OnFrame(high_res_now_ms, base::nullopt);
+ // Run session->OnFrame() in a posted task to ensure that createAnchor
+ // promises get a chance to run - the presentation frame state is already
+ // updated.
+ frame->GetTaskRunner(blink::TaskType::kInternalMedia)
+ ->PostTask(FROM_HERE,
+ WTF::Bind(&XRSession::OnFrame, WrapWeakPersistent(session),
+ high_res_now_ms, base::nullopt));
}
}
}
@@ -500,8 +526,6 @@ void XRFrameProvider::SubmitWebGLLayer(XRWebGLLayer* layer, bool was_changed) {
frame_transport_->FramePreImage(webgl_context->ContextGL());
- std::unique_ptr<viz::SingleReleaseCallback> image_release_callback;
-
if (frame_transport_->DrawingIntoSharedBuffer()) {
// Image is written to shared buffer already. Just submit with a
// placeholder.
@@ -509,13 +533,12 @@ void XRFrameProvider::SubmitWebGLLayer(XRWebGLLayer* layer, bool was_changed) {
DVLOG(3) << __FUNCTION__ << ": FrameSubmit for SharedBuffer mode";
frame_transport_->FrameSubmit(immersive_presentation_provider_.get(),
webgl_context->ContextGL(), webgl_context,
- std::move(image_ref),
- std::move(image_release_callback), frame_id_);
+ std::move(image_ref), frame_id_);
return;
}
scoped_refptr<StaticBitmapImage> image_ref =
- layer->TransferToStaticBitmapImage(&image_release_callback);
+ layer->TransferToStaticBitmapImage();
if (!image_ref)
return;
@@ -529,8 +552,7 @@ void XRFrameProvider::SubmitWebGLLayer(XRWebGLLayer* layer, bool was_changed) {
frame_transport_->FrameSubmit(immersive_presentation_provider_.get(),
webgl_context->ContextGL(), webgl_context,
- std::move(image_ref),
- std::move(image_release_callback), frame_id_);
+ std::move(image_ref), frame_id_);
// Reset our frame id, since anything we'd want to do (resizing/etc) can
// no-longer happen to this frame.
@@ -550,25 +572,25 @@ void XRFrameProvider::UpdateWebGLLayerViewports(XRWebGLLayer* layer) {
// We may only have one eye view, i.e. in smartphone immersive AR mode.
// Use all-zero bounds for unused views.
- WebFloatRect left_coords =
- left ? WebFloatRect(
+ gfx::RectF left_coords =
+ left ? gfx::RectF(
static_cast<float>(left->x()) / width,
static_cast<float>(height - (left->y() + left->height())) /
height,
static_cast<float>(left->width()) / width,
static_cast<float>(left->height()) / height)
- : WebFloatRect();
- WebFloatRect right_coords =
- right ? WebFloatRect(
+ : gfx::RectF();
+ gfx::RectF right_coords =
+ right ? gfx::RectF(
static_cast<float>(right->x()) / width,
static_cast<float>(height - (right->y() + right->height())) /
height,
static_cast<float>(right->width()) / width,
static_cast<float>(right->height()) / height)
- : WebFloatRect();
+ : gfx::RectF();
immersive_presentation_provider_->UpdateLayerBounds(
- frame_id_, left_coords, right_coords, WebSize(width, height));
+ frame_id_, left_coords, right_coords, gfx::Size(width, height));
}
void XRFrameProvider::Dispose() {
@@ -580,7 +602,7 @@ void XRFrameProvider::Dispose() {
// TODO(bajones): Do something for outstanding frame requests?
}
-void XRFrameProvider::Trace(blink::Visitor* visitor) {
+void XRFrameProvider::Trace(Visitor* visitor) {
visitor->Trace(xr_);
visitor->Trace(frame_transport_);
visitor->Trace(immersive_session_);
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 8fd58cc40a5..6ed8d94dee1 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
@@ -14,16 +14,16 @@
namespace blink {
-class XR;
-class XRSession;
class XRFrameTransport;
+class XRSession;
+class XRSystem;
class XRWebGLLayer;
// This class manages requesting and dispatching frame updates, which includes
// pose information for a given XRDevice.
class XRFrameProvider final : public GarbageCollected<XRFrameProvider> {
public:
- explicit XRFrameProvider(XR*);
+ explicit XRFrameProvider(XRSystem*);
XRSession* immersive_session() const { return immersive_session_; }
@@ -45,7 +45,7 @@ class XRFrameProvider final : public GarbageCollected<XRFrameProvider> {
return immersive_data_provider_.get();
}
- virtual void Trace(blink::Visitor*);
+ virtual void Trace(Visitor*);
private:
void OnImmersiveFrameData(device::mojom::blink::XRFrameDataPtr data);
@@ -72,7 +72,7 @@ class XRFrameProvider final : public GarbageCollected<XRFrameProvider> {
void ProcessScheduledFrame(device::mojom::blink::XRFrameDataPtr frame_data,
double high_res_now_ms);
- const Member<XR> xr_;
+ const Member<XRSystem> xr_;
// Immersive session state
Member<XRSession> immersive_session_;
@@ -88,7 +88,7 @@ class XRFrameProvider final : public GarbageCollected<XRFrameProvider> {
HeapHashMap<Member<XRSession>,
mojo::Remote<device::mojom::blink::XRFrameDataProvider>>
non_immersive_data_providers_;
- HeapHashMap<Member<XRSession>, device::mojom::blink::VRPosePtr>
+ HeapHashMap<Member<XRSession>, device::mojom::blink::XRFrameDataPtr>
requesting_sessions_;
// This frame ID is XR-specific and is used to track when frames arrive at the
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 3232ba45c9c..12ebbb526c9 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
@@ -6,6 +6,7 @@
#include "third_party/blink/renderer/bindings/modules/v8/v8_xr_frame_request_callback.h"
#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
+#include "third_party/blink/renderer/core/probe/async_task_id.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/modules/xr/xr_frame.h"
#include "third_party/blink/renderer/modules/xr/xr_session.h"
@@ -20,12 +21,13 @@ XRFrameRequestCallbackCollection::CallbackId
XRFrameRequestCallbackCollection::RegisterCallback(
V8XRFrameRequestCallback* callback) {
CallbackId id = ++next_callback_id_;
- auto add_result =
- callbacks_.Set(id, CallbackAndAsyncTask(callback, probe::AsyncTaskId()));
+ auto add_result = callbacks_.Set(
+ id,
+ CallbackAndAsyncTask(callback, std::make_unique<probe::AsyncTaskId>()));
pending_callbacks_.push_back(id);
- probe::AsyncTaskScheduledBreakable(context_, "XRRequestFrame",
- &add_result.stored_value->value.second);
+ probe::AsyncTaskScheduledBreakable(
+ context_, "XRRequestFrame", add_result.stored_value->value.second.get());
return id;
}
@@ -60,7 +62,7 @@ void XRFrameRequestCallbackCollection::ExecuteCallbacks(XRSession* session,
if (it == current_callbacks_.end())
continue;
- probe::AsyncTask async_task(context_, &it->value.second);
+ probe::AsyncTask async_task(context_, it->value.second.get());
probe::UserCallback probe(context_, "XRRequestFrame", AtomicString(), true);
it->value.first->InvokeAndReportException(session, timestamp, frame);
}
@@ -68,7 +70,7 @@ void XRFrameRequestCallbackCollection::ExecuteCallbacks(XRSession* session,
current_callbacks_.clear();
}
-void XRFrameRequestCallbackCollection::Trace(blink::Visitor* visitor) {
+void XRFrameRequestCallbackCollection::Trace(Visitor* visitor) {
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 d5258abdb28..dfc5344173a 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
@@ -5,7 +5,6 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_FRAME_REQUEST_CALLBACK_COLLECTION_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_FRAME_REQUEST_CALLBACK_COLLECTION_H_
-#include "third_party/blink/renderer/core/probe/async_task_id.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -16,6 +15,10 @@ class V8XRFrameRequestCallback;
class XRFrame;
class XRSession;
+namespace probe {
+class AsyncTaskId;
+}
+
class XRFrameRequestCallbackCollection final
: public GarbageCollected<XRFrameRequestCallbackCollection>,
public NameClient {
@@ -29,7 +32,7 @@ class XRFrameRequestCallbackCollection final
bool IsEmpty() const { return !callbacks_.size(); }
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
const char* NameInHeapSnapshot() const override {
return "XRFrameRequestCallbackCollection";
}
@@ -41,8 +44,8 @@ class XRFrameRequestCallbackCollection final
!WTF::IsHashTraitsEmptyValue<Traits, CallbackId>(id);
}
- using CallbackAndAsyncTask =
- std::pair<Member<V8XRFrameRequestCallback>, probe::AsyncTaskId>;
+ using CallbackAndAsyncTask = std::pair<Member<V8XRFrameRequestCallback>,
+ std::unique_ptr<probe::AsyncTaskId>>;
using CallbackMap = HeapHashMap<CallbackId, CallbackAndAsyncTask>;
CallbackMap callbacks_;
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 0eb6ff3e93b..ac1fe4521ff 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
@@ -14,44 +14,33 @@ namespace blink {
XRGripSpace::XRGripSpace(XRSession* session, XRInputSource* source)
: XRSpace(session), input_source_(source) {}
-XRPose* XRGripSpace::getPose(XRSpace* other_space,
- const TransformationMatrix* mojo_from_viewer) {
+std::unique_ptr<TransformationMatrix> XRGripSpace::MojoFromNative() {
// Grip is only available when using tracked pointer for input.
if (input_source_->TargetRayMode() !=
device::mojom::XRTargetRayMode::POINTING) {
return nullptr;
}
- // Make sure the required pose matrices are available.
- if (!mojo_from_viewer || !input_source_->MojoFromInput()) {
+ if (!input_source_->MojoFromInput())
return nullptr;
- }
- // Calculate grip pose in other_space, aka other_from_grip
- std::unique_ptr<TransformationMatrix> other_from_grip =
- other_space->SpaceFromInputForViewer(*(input_source_->MojoFromInput()),
- *mojo_from_viewer);
- if (!other_from_grip) {
- return nullptr;
- }
+ return std::make_unique<TransformationMatrix>(
+ *(input_source_->MojoFromInput()));
+}
+
+std::unique_ptr<TransformationMatrix> XRGripSpace::NativeFromMojo() {
+ return TryInvert(MojoFromNative());
+}
- // Account for any changes made to the reference space's origin offset so
- // that things like teleportation works.
- //
- // This is offset_from_grip = offset_from_other * other_from_grip,
- // where offset_from_other = inverse(other_from_offset).
- // TODO(https://crbug.com/1008466): move originOffset to separate class?
- TransformationMatrix offset_from_grip =
- other_space->InverseOriginOffsetMatrix().Multiply(*other_from_grip);
- return MakeGarbageCollected<XRPose>(offset_from_grip,
- input_source_->emulatedPosition());
+bool XRGripSpace::EmulatedPosition() const {
+ return input_source_->emulatedPosition();
}
base::Optional<XRNativeOriginInformation> XRGripSpace::NativeOrigin() const {
return input_source_->nativeOrigin();
}
-void XRGripSpace::Trace(blink::Visitor* visitor) {
+void XRGripSpace::Trace(Visitor* visitor) {
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 0ffa42e6525..1f396f5efa7 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
@@ -14,12 +14,14 @@ namespace blink {
class XRGripSpace : public XRSpace {
public:
XRGripSpace(XRSession* session, XRInputSource* input_source);
- XRPose* getPose(XRSpace* other_space,
- const TransformationMatrix* base_pose_matrix) override;
+
+ std::unique_ptr<TransformationMatrix> MojoFromNative() override;
+ std::unique_ptr<TransformationMatrix> NativeFromMojo() override;
+ bool EmulatedPosition() const override;
base::Optional<XRNativeOriginInformation> NativeOrigin() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<XRInputSource> input_source_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_hit_result.cc b/chromium/third_party/blink/renderer/modules/xr/xr_hit_result.cc
deleted file mode 100644
index b14b3e1ea87..00000000000
--- a/chromium/third_party/blink/renderer/modules/xr/xr_hit_result.cc
+++ /dev/null
@@ -1,22 +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/xr/xr_hit_result.h"
-
-#include "third_party/blink/renderer/modules/xr/xr_utils.h"
-#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
-
-namespace blink {
-XRHitResult::XRHitResult(const TransformationMatrix& hit_transform)
- : hit_transform_(std::make_unique<TransformationMatrix>(hit_transform)) {}
-
-XRHitResult::~XRHitResult() {}
-
-DOMFloat32Array* XRHitResult::hitMatrix() const {
- if (!hit_transform_)
- return nullptr;
- return transformationMatrixToDOMFloat32Array(*hit_transform_);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_hit_result.h b/chromium/third_party/blink/renderer/modules/xr/xr_hit_result.h
deleted file mode 100644
index 705bffb717d..00000000000
--- a/chromium/third_party/blink/renderer/modules/xr/xr_hit_result.h
+++ /dev/null
@@ -1,29 +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_XR_XR_HIT_RESULT_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_HIT_RESULT_H_
-
-#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
-
-namespace blink {
-
-class TransformationMatrix;
-
-class XRHitResult final : public ScriptWrappable {
- DEFINE_WRAPPERTYPEINFO();
-
- public:
- explicit XRHitResult(const TransformationMatrix&);
- ~XRHitResult() override;
-
- DOMFloat32Array* hitMatrix() const;
-
- private:
- const std::unique_ptr<TransformationMatrix> hit_transform_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_HIT_RESULT_H_
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_hit_result.idl b/chromium/third_party/blink/renderer/modules/xr/xr_hit_result.idl
deleted file mode 100644
index de430e69503..00000000000
--- a/chromium/third_party/blink/renderer/modules/xr/xr_hit_result.idl
+++ /dev/null
@@ -1,7 +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.
-
-[RuntimeEnabled=WebXRHitTest, SecureContext, Exposed=Window] interface XRHitResult {
- readonly attribute Float32Array hitMatrix;
-}; \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_options_init.idl b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_options_init.idl
index cb535b70824..0973892b598 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_options_init.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_options_init.idl
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+[RuntimeEnabled=WebXRHitTestEntityTypes]
enum XRHitTestTrackableType {
"point",
"plane"
@@ -9,6 +10,6 @@ enum XRHitTestTrackableType {
dictionary XRHitTestOptionsInit {
required XRSpace space;
- FrozenArray<XRHitTestTrackableType> entityTypes;
+ [RuntimeEnabled=WebXRHitTestEntityTypes] FrozenArray<XRHitTestTrackableType> entityTypes;
XRRay offsetRay;
};
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 032e9a19bdf..58df9fb6808 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
@@ -6,26 +6,56 @@
#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_rigid_transform.h"
+#include "third_party/blink/renderer/modules/xr/xr_session.h"
#include "third_party/blink/renderer/modules/xr/xr_space.h"
namespace blink {
-XRHitTestResult::XRHitTestResult(const TransformationMatrix& pose)
- : pose_(std::make_unique<TransformationMatrix>(pose)) {}
+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())),
+ plane_id_(hit_result.plane_id != 0
+ ? base::Optional<uint64_t>(hit_result.plane_id)
+ : base::nullopt) {}
-XRPose* XRHitTestResult::getPose(XRSpace* relative_to) {
- DCHECK(relative_to->MojoFromSpace());
+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 = *pose_;
+ auto mojo_from_this = *mojo_from_this_;
- auto mojo_from_other = *relative_to->MojoFromSpace();
- DCHECK(mojo_from_other.IsInvertible());
+ auto other_native_from_mojo = *maybe_other_space_native_from_mojo;
+ auto other_offset_from_other_native = other->OffsetFromNativeMatrix();
- auto other_from_mojo = mojo_from_other.Inverse();
+ auto other_offset_from_mojo =
+ other_offset_from_other_native * other_native_from_mojo;
- auto other_from_this = other_from_mojo * mojo_from_this;
+ auto other_offset_from_this = other_offset_from_mojo * mojo_from_this;
- return MakeGarbageCollected<XRPose>(other_from_this, false);
+ return MakeGarbageCollected<XRPose>(other_offset_from_this, false);
}
+ScriptPromise XRHitTestResult::createAnchor(ScriptState* script_state,
+ XRRigidTransform* initial_pose,
+ ExceptionState& exception_state) {
+ DVLOG(2) << __func__;
+
+ if (!initial_pose) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ XRSession::kNoRigidTransformSpecified);
+ return {};
+ }
+
+ return session_->CreateAnchor(script_state, initial_pose->TransformMatrix(),
+ *mojo_from_this_, plane_id_, exception_state);
+}
+
+void XRHitTestResult::Trace(Visitor* visitor) {
+ visitor->Trace(session_);
+ ScriptWrappable::Trace(visitor);
+}
} // namespace blink
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 163c1fcac95..9d070373885 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
@@ -5,24 +5,43 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_HIT_TEST_RESULT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_HIT_TEST_RESULT_H_
+#include "base/optional.h"
+#include "device/vr/public/mojom/vr_service.mojom-blink.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
namespace blink {
+class ExceptionState;
+class ScriptState;
class TransformationMatrix;
class XRPose;
+class XRRigidTransform;
+class XRSession;
class XRSpace;
class XRHitTestResult : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- explicit XRHitTestResult(const TransformationMatrix& pose);
+ explicit XRHitTestResult(XRSession* session,
+ const device::mojom::blink::XRHitResult& hit_result);
XRPose* getPose(XRSpace* relative_to);
+ ScriptPromise createAnchor(ScriptState* script_state,
+ XRRigidTransform* initial_pose,
+ ExceptionState& exception_state);
+
+ void Trace(Visitor* visitor) override;
+
private:
- std::unique_ptr<TransformationMatrix> pose_;
+ 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_;
+ base::Optional<uint64_t> plane_id_;
};
} // namespace blink
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 0019eaa7606..692f78680f3 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
@@ -4,5 +4,8 @@
[SecureContext, Exposed=Window, RuntimeEnabled=WebXRHitTest]
interface XRHitTestResult {
- XRPose? getPose(XRSpace relative_to);
+ XRPose? getPose(XRSpace relative_to);
+
+ [RuntimeEnabled=WebXRIncubations, CallWith=ScriptState, RaisesException]
+ Promise<XRAnchor> createAnchor(XRRigidTransform initial_pose);
};
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 8a49f3591a7..9e539e62dc9 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
@@ -35,7 +35,8 @@ HeapVector<Member<XRHitTestResult>> XRHitTestSource::Results() {
HeapVector<Member<XRHitTestResult>> results;
for (const auto& result : last_frame_results_) {
- results.emplace_back(MakeGarbageCollected<XRHitTestResult>(*result));
+ results.emplace_back(
+ MakeGarbageCollected<XRHitTestResult>(xr_session_, result));
}
return results;
@@ -46,11 +47,14 @@ void XRHitTestSource::Update(
last_frame_results_.clear();
for (auto& result : hit_test_results) {
- last_frame_results_.push_back(
- std::make_unique<TransformationMatrix>(result->hit_matrix.matrix()));
+ DVLOG(3) << __func__ << ": processing hit test result, hit matrix: "
+ << result->hit_matrix.ToString()
+ << ", plane_id=" << result->plane_id;
+ last_frame_results_.push_back(*result);
}
}
-void XRHitTestSource::Trace(blink::Visitor* visitor) {
+
+void XRHitTestSource::Trace(Visitor* visitor) {
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 419ee803009..672909b3add 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
@@ -10,7 +10,6 @@
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h"
-#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
namespace blink {
@@ -35,13 +34,13 @@ class XRHitTestSource : public ScriptWrappable {
void Update(
const Vector<device::mojom::blink::XRHitResultPtr>& hit_test_results);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
const uint64_t id_;
Member<XRSession> xr_session_;
- Vector<std::unique_ptr<TransformationMatrix>> last_frame_results_;
+ Vector<device::mojom::blink::XRHitResult> 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 af14ac91d1f..b393c0cb3c6 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
@@ -5,12 +5,19 @@
#include "third_party/blink/renderer/modules/xr/xr_input_source.h"
#include "base/time/time.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/dom/events/event_path.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
-#include "third_party/blink/renderer/modules/xr/xr.h"
+#include "third_party/blink/renderer/core/html/html_frame_element_base.h"
+#include "third_party/blink/renderer/core/input/event_handling_util.h"
+#include "third_party/blink/renderer/core/layout/hit_test_location.h"
#include "third_party/blink/renderer/modules/xr/xr_grip_space.h"
#include "third_party/blink/renderer/modules/xr/xr_input_source_event.h"
#include "third_party/blink/renderer/modules/xr/xr_session.h"
+#include "third_party/blink/renderer/modules/xr/xr_session_event.h"
#include "third_party/blink/renderer/modules/xr/xr_space.h"
+#include "third_party/blink/renderer/modules/xr/xr_system.h"
#include "third_party/blink/renderer/modules/xr/xr_target_ray_space.h"
#include "third_party/blink/renderer/modules/xr/xr_utils.h"
@@ -69,7 +76,9 @@ XRInputSource* XRInputSource::CreateOrUpdateFrom(
updated_source = MakeGarbageCollected<XRInputSource>(*other);
}
- updated_source->UpdateGamepad(state->gamepad);
+ if (updated_source->state_.is_visible) {
+ updated_source->UpdateGamepad(state->gamepad);
+ }
// Update the input source's description if this state update includes them.
if (state->description) {
@@ -79,8 +88,10 @@ XRInputSource* XRInputSource::CreateOrUpdateFrom(
updated_source->state_.target_ray_mode = desc->target_ray_mode;
updated_source->state_.handedness = desc->handedness;
- updated_source->input_from_pointer_ =
- TryGetTransformationMatrix(desc->input_from_pointer);
+ if (updated_source->state_.is_visible) {
+ updated_source->input_from_pointer_ =
+ TryGetTransformationMatrix(desc->input_from_pointer);
+ }
updated_source->state_.profiles.clear();
for (const auto& name : state->description->profiles) {
@@ -88,8 +99,10 @@ XRInputSource* XRInputSource::CreateOrUpdateFrom(
}
}
- updated_source->mojo_from_input_ =
- TryGetTransformationMatrix(state->mojo_from_input);
+ if (updated_source->state_.is_visible) {
+ updated_source->mojo_from_input_ =
+ TryGetTransformationMatrix(state->mojo_from_input);
+ }
updated_source->state_.emulated_position = state->emulated_position;
@@ -151,6 +164,9 @@ XRSpace* XRInputSource::targetRaySpace() const {
}
XRSpace* XRInputSource::gripSpace() const {
+ if (!state_.is_visible)
+ return nullptr;
+
if (state_.target_ray_mode == device::mojom::XRTargetRayMode::POINTING) {
return grip_space_;
}
@@ -189,7 +205,9 @@ bool XRInputSource::InvalidatesSameObject(
void XRInputSource::SetInputFromPointer(
const TransformationMatrix* input_from_pointer) {
- input_from_pointer_ = TryGetTransformationMatrix(input_from_pointer);
+ if (state_.is_visible) {
+ input_from_pointer_ = TryGetTransformationMatrix(input_from_pointer);
+ }
}
void XRInputSource::SetGamepadConnected(bool state) {
@@ -216,6 +234,7 @@ base::Optional<XRNativeOriginInformation> XRInputSource::nativeOrigin() const {
}
void XRInputSource::OnSelectStart() {
+ DVLOG(3) << __func__;
// Discard duplicate events and ones after the session has ended.
if (state_.primary_input_pressed || session_->ended())
return;
@@ -223,6 +242,7 @@ void XRInputSource::OnSelectStart() {
state_.primary_input_pressed = true;
state_.selection_cancelled = false;
+ DVLOG(3) << __func__ << ": dispatch selectstart event";
XRInputSourceEvent* event =
CreateInputSourceEvent(event_type_names::kSelectstart);
session_->DispatchEvent(*event);
@@ -235,6 +255,7 @@ void XRInputSource::OnSelectStart() {
}
void XRInputSource::OnSelectEnd() {
+ DVLOG(3) << __func__;
// Discard duplicate events and ones after the session has ended.
if (!state_.primary_input_pressed || session_->ended())
return;
@@ -245,6 +266,7 @@ void XRInputSource::OnSelectEnd() {
if (!frame)
return;
+ DVLOG(3) << __func__ << ": dispatch selectend event";
XRInputSourceEvent* event =
CreateInputSourceEvent(event_type_names::kSelectend);
session_->DispatchEvent(*event);
@@ -257,6 +279,7 @@ void XRInputSource::OnSelectEnd() {
}
void XRInputSource::OnSelect() {
+ DVLOG(3) << __func__;
// If a select was fired but we had not previously started the selection it
// indicates a sub-frame or instantaneous select event, and we should fire a
// selectstart prior to the selectend.
@@ -272,6 +295,7 @@ void XRInputSource::OnSelect() {
if (!state_.selection_cancelled && !session_->ended()) {
if (!frame)
return;
+ DVLOG(3) << __func__ << ": dispatch select event";
XRInputSourceEvent* event =
CreateInputSourceEvent(event_type_names::kSelect);
session_->DispatchEvent(*event);
@@ -283,16 +307,114 @@ void XRInputSource::OnSelect() {
OnSelectEnd();
}
-void XRInputSource::UpdateSelectState(
- const device::mojom::blink::XRInputSourceStatePtr& state) {
- if (!state)
+void XRInputSource::OnSqueezeStart() {
+ DVLOG(3) << __func__;
+ // Discard duplicate events and ones after the session has ended.
+ if (state_.primary_squeeze_pressed || session_->ended())
+ return;
+
+ state_.primary_squeeze_pressed = true;
+ state_.squeezing_cancelled = false;
+
+ XRInputSourceEvent* event =
+ CreateInputSourceEvent(event_type_names::kSqueezestart);
+ session_->DispatchEvent(*event);
+
+ if (event->defaultPrevented())
+ state_.squeezing_cancelled = true;
+
+ // Ensure the frame cannot be used outside of the event handler.
+ event->frame()->Deactivate();
+}
+
+void XRInputSource::OnSqueezeEnd() {
+ DVLOG(3) << __func__;
+ // Discard duplicate events and ones after the session has ended.
+ if (!state_.primary_squeeze_pressed || session_->ended())
+ return;
+
+ state_.primary_squeeze_pressed = false;
+
+ LocalFrame* frame = session_->xr()->GetFrame();
+ if (!frame)
+ return;
+
+ DVLOG(3) << __func__ << ": dispatch squeezeend event";
+ XRInputSourceEvent* event =
+ CreateInputSourceEvent(event_type_names::kSqueezeend);
+ session_->DispatchEvent(*event);
+
+ if (event->defaultPrevented())
+ state_.squeezing_cancelled = true;
+
+ // Ensure the frame cannot be used outside of the event handler.
+ event->frame()->Deactivate();
+}
+
+void XRInputSource::OnSqueeze() {
+ DVLOG(3) << __func__;
+ // If a squeeze was fired but we had not previously started the squeezing it
+ // indicates a sub-frame or instantaneous squeeze event, and we should fire a
+ // squeezestart prior to the squeezeend.
+ if (!state_.primary_squeeze_pressed) {
+ OnSqueezeStart();
+ }
+
+ LocalFrame* frame = session_->xr()->GetFrame();
+ LocalFrame::NotifyUserActivation(frame);
+
+ // If SelectStart caused the session to end, we shouldn't try to fire the
+ // select event.
+ if (!state_.squeezing_cancelled && !session_->ended()) {
+ if (!frame)
+ return;
+ DVLOG(3) << __func__ << ": dispatch squeeze event";
+ XRInputSourceEvent* event =
+ CreateInputSourceEvent(event_type_names::kSqueeze);
+ session_->DispatchEvent(*event);
+
+ // Ensure the frame cannot be used outside of the event handler.
+ event->frame()->Deactivate();
+ }
+
+ OnSqueezeEnd();
+}
+
+void XRInputSource::UpdateButtonStates(
+ const device::mojom::blink::XRInputSourceStatePtr& new_state) {
+ if (!new_state)
return;
+ DVLOG(3) << __func__ << ": state_.is_visible=" << state_.is_visible
+ << ", state_.xr_select_events_suppressed="
+ << state_.xr_select_events_suppressed
+ << ", new_state->primary_input_clicked="
+ << new_state->primary_input_clicked;
+
+ if (!state_.is_visible) {
+ DVLOG(3) << __func__ << ": input NOT VISIBLE";
+ if (new_state->primary_input_clicked) {
+ DVLOG(3) << __func__ << ": got click while invisible, SUPPRESS end";
+ state_.xr_select_events_suppressed = false;
+ }
+ return;
+ }
+ if (state_.xr_select_events_suppressed) {
+ if (new_state->primary_input_clicked) {
+ DVLOG(3) << __func__ << ": got click, SUPPRESS end";
+ state_.xr_select_events_suppressed = false;
+ }
+ DVLOG(3) << __func__ << ": overlay input select SUPPRESSED";
+ return;
+ }
+
+ DCHECK(!state_.xr_select_events_suppressed);
+
// Handle state change of the primary input, which may fire events
- if (state->primary_input_clicked)
+ if (new_state->primary_input_clicked)
OnSelect();
- if (state->primary_input_pressed) {
+ if (new_state->primary_input_pressed) {
OnSelectStart();
} else if (state_.primary_input_pressed) {
// May get here if the input source was previously pressed but now isn't,
@@ -302,6 +424,131 @@ void XRInputSource::UpdateSelectState(
// usual select event.
OnSelectEnd();
}
+
+ // Handle state change of the primary input, which may fire events
+ if (new_state->primary_squeeze_clicked)
+ OnSqueeze();
+
+ if (new_state->primary_squeeze_pressed) {
+ OnSqueezeStart();
+ } else if (state_.primary_squeeze_pressed) {
+ // May get here if the input source was previously pressed but now isn't,
+ // but the input source did not set primary_squeeze_clicked to true. We will
+ // treat this as a cancelled squeezeing, firing the squeezeend event so the
+ // page stays in sync with the controller state but won't fire the
+ // usual squeeze event.
+ OnSqueezeEnd();
+ }
+}
+
+void XRInputSource::ProcessOverlayHitTest(
+ Element* overlay_element,
+ const device::mojom::blink::XRInputSourceStatePtr& new_state) {
+ DVLOG(3) << __func__ << ": state_.xr_select_events_suppressed="
+ << state_.xr_select_events_suppressed;
+
+ DCHECK(overlay_element);
+ DCHECK(new_state->overlay_pointer_position);
+
+ // Do a hit test at the overlay pointer position to see if the pointer
+ // intersects a cross origin iframe. If yes, set the visibility to false which
+ // causes targetRaySpace and gripSpace to return null poses.
+ FloatPoint point(new_state->overlay_pointer_position->x(),
+ new_state->overlay_pointer_position->y());
+ DVLOG(3) << __func__ << ": hit test point=" << point;
+
+ HitTestRequest::HitTestRequestType hit_type = HitTestRequest::kTouchEvent |
+ HitTestRequest::kReadOnly |
+ HitTestRequest::kActive;
+
+ HitTestResult result = event_handling_util::HitTestResultInFrame(
+ overlay_element->GetDocument().GetFrame(), HitTestLocation(point),
+ hit_type);
+ DVLOG(3) << __func__ << ": hit test InnerElement=" << result.InnerElement();
+
+ Element* hit_element = result.InnerElement();
+ if (!hit_element) {
+ return;
+ }
+
+ // Check if the hit element is cross-origin content. In addition to an iframe,
+ // this could potentially be an old-style frame in a frameset, so check for
+ // the common base class to cover both. (There's no intention to actively
+ // support framesets for DOM Overlay, but this helps prevent them from
+ // being used as a mechanism for information leaks.)
+ HTMLFrameElementBase* frame = DynamicTo<HTMLFrameElementBase>(hit_element);
+ if (frame) {
+ Document* hit_document = frame->contentDocument();
+ if (hit_document) {
+ Frame* hit_frame = hit_document->GetFrame();
+ DCHECK(hit_frame);
+ if (hit_frame->IsCrossOriginToMainFrame()) {
+ // Mark the input source as invisible until the primary button is
+ // released.
+ state_.is_visible = false;
+
+ // If this is the first touch, also suppress events, even if it
+ // ends up being released outside the frame later.
+ if (!state_.primary_input_pressed) {
+ state_.xr_select_events_suppressed = true;
+ }
+
+ DVLOG(3)
+ << __func__
+ << ": input source overlaps with cross origin content, is_visible="
+ << state_.is_visible << ", xr_select_events_suppressed="
+ << state_.xr_select_events_suppressed;
+ return;
+ }
+ }
+ }
+
+ // If we get here, the touch didn't hit a cross origin frame. Set the
+ // controller spaces visible.
+ state_.is_visible = true;
+
+ // Now that the visibility check has finished, mark non-primary input sources
+ // as suppressed.
+ if (new_state->is_auxiliary) {
+ state_.xr_select_events_suppressed = true;
+ }
+
+ // Now check if this is a new primary button press. If yes, send a
+ // beforexrselect event to give the application an opportunity to cancel the
+ // XR input "select" sequence that would normally be caused by this.
+
+ if (state_.xr_select_events_suppressed) {
+ DVLOG(3) << __func__ << ": using overlay input provider: SUPPRESS ongoing";
+ return;
+ }
+
+ if (state_.primary_input_pressed) {
+ DVLOG(3) << __func__ << ": ongoing press, not checking again";
+ return;
+ }
+
+ bool is_primary_press =
+ new_state->primary_input_pressed || new_state->primary_input_clicked;
+ if (!is_primary_press) {
+ DVLOG(3) << __func__ << ": no button press, ignoring";
+ return;
+ }
+
+ // The event needs to be cancelable (obviously), bubble (so that parent
+ // elements can handle it), and composed (so that it crosses shadow DOM
+ // boundaries, including UA-added shadow DOM).
+ Event* event = MakeGarbageCollected<XRSessionEvent>(
+ event_type_names::kBeforexrselect, session_, Event::Bubbles::kYes,
+ Event::Cancelable::kYes, Event::ComposedMode::kComposed);
+
+ hit_element->DispatchEvent(*event);
+ bool default_prevented = event->defaultPrevented();
+
+ // Keep the input source visible, so it's exposed in the input sources array,
+ // but don't generate XR select events for the current button sequence.
+ state_.xr_select_events_suppressed = default_prevented;
+ DVLOG(3) << __func__ << ": state_.xr_select_events_suppressed="
+ << state_.xr_select_events_suppressed;
}
void XRInputSource::OnRemoved() {
@@ -319,6 +566,20 @@ void XRInputSource::OnRemoved() {
event->frame()->Deactivate();
}
+ if (state_.primary_squeeze_pressed) {
+ state_.primary_squeeze_pressed = false;
+
+ XRInputSourceEvent* event =
+ CreateInputSourceEvent(event_type_names::kSqueezeend);
+ session_->DispatchEvent(*event);
+
+ if (event->defaultPrevented())
+ state_.squeezing_cancelled = true;
+
+ // Ensure the frame cannot be used outside of the event handler.
+ event->frame()->Deactivate();
+ }
+
SetGamepadConnected(false);
}
@@ -328,7 +589,7 @@ XRInputSourceEvent* XRInputSource::CreateInputSourceEvent(
return XRInputSourceEvent::Create(type, presentation_frame, this);
}
-void XRInputSource::Trace(blink::Visitor* visitor) {
+void XRInputSource::Trace(Visitor* visitor) {
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 c99dca23ad8..d61df78f3a7 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
@@ -20,6 +20,7 @@ class Gamepad;
namespace blink {
+class Element;
class XRGripSpace;
class XRInputSourceEvent;
class XRSession;
@@ -85,11 +86,25 @@ class XRInputSource : public ScriptWrappable, public Gamepad::Client {
void OnSelectStart();
void OnSelectEnd();
void OnSelect();
- void UpdateSelectState(
+
+ void OnSqueezeStart();
+ void OnSqueezeEnd();
+ void OnSqueeze();
+
+ void UpdateButtonStates(
const device::mojom::blink::XRInputSourceStatePtr& state);
void OnRemoved();
- void Trace(blink::Visitor*) override;
+ // Check which element within the DOM overlay is hit by the input source's
+ // pointer ray, and update primary input state based on that, including
+ // suppressing event data for cross-origin iframes. For background, see
+ // https://immersive-web.github.io/dom-overlays/#cross-origin-content-events
+ void ProcessOverlayHitTest(
+ Element* overlay_element,
+ const device::mojom::blink::XRInputSourceStatePtr& state);
+ bool IsVisible() const { return state_.is_visible; }
+
+ void Trace(Visitor*) override;
private:
// In order to ease copying, any new member variables that can be trivially
@@ -98,6 +113,21 @@ class XRInputSource : public ScriptWrappable, public Gamepad::Client {
int16_t active_frame_id = -1;
bool primary_input_pressed = false;
bool selection_cancelled = false;
+ bool primary_squeeze_pressed = false;
+ bool squeezing_cancelled = false;
+ // Input sources have two separate states, visible/invisible and select
+ // events active/suppressed. All input sources, including auxiliary, should
+ // use DOM overlay hit test (the ProcessOverlayHitTest() method) to check if
+ // they intersect cross-origin content. If that's the case, the input source
+ // is set as invisible, and must not return poses or hit test results. This
+ // also automatically suppresses select events (this matches the "poses are
+ // limited" conditional in the main WebXR spec). If the hit test doesn't
+ // intersect cross-origin content, and if this is the first touch, it fires
+ // a beforexrselect event and suppresses select events if that's been
+ // preventDefault()ed. For auxiliary input sources, the event does not need
+ // to be fired - per spec, their select events need to be suppressed anyway.
+ bool xr_select_events_suppressed = false;
+ bool is_visible = true;
const uint32_t source_id;
device::mojom::XRHandedness handedness = device::mojom::XRHandedness::NONE;
device::mojom::XRTargetRayMode target_ray_mode;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_input_source.idl b/chromium/third_party/blink/renderer/modules/xr/xr_input_source.idl
index 78ee80c2c2c..d1869d2fe85 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_input_source.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_input_source.idl
@@ -23,6 +23,6 @@ enum XRTargetRayMode {
readonly attribute XRTargetRayMode targetRayMode;
[SameObject] readonly attribute XRSpace targetRaySpace;
[SameObject] readonly attribute XRSpace? gripSpace;
- [SameObject, Measure, RuntimeEnabled=WebXrGamepadModule] readonly attribute Gamepad? gamepad;
+ [SameObject, Measure] readonly attribute Gamepad? gamepad;
[SameObject, SaveSameObject] readonly attribute FrozenArray<DOMString> profiles;
};
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 f39325c2c2c..bbd561b3cf1 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(blink::Visitor* visitor) {
+void XRInputSourceArray::Trace(Visitor* visitor) {
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 0c92eb0d24e..721761149f9 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 a59842c8e74..6e885b9da63 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(blink::Visitor* visitor) {
+void XRInputSourceEvent::Trace(Visitor* visitor) {
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 f7e8c286e5e..a9696357013 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
@@ -5,10 +5,10 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_INPUT_SOURCE_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_INPUT_SOURCE_EVENT_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_xr_input_source_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/xr/xr_frame.h"
#include "third_party/blink/renderer/modules/xr/xr_input_source.h"
-#include "third_party/blink/renderer/modules/xr/xr_input_source_event_init.h"
namespace blink {
@@ -40,7 +40,7 @@ class XRInputSourceEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<XRFrame> frame_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.idl b/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.idl
index d4e4a92d973..aaaf2931115 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.idl
@@ -5,9 +5,9 @@
[
SecureContext,
Exposed=Window,
- RuntimeEnabled=WebXR,
- Constructor(DOMString type, XRInputSourceEventInit eventInitDict)
+ RuntimeEnabled=WebXR
] interface XRInputSourceEvent : Event {
+ constructor(DOMString type, XRInputSourceEventInit eventInitDict);
[SameObject] readonly attribute XRFrame frame;
[SameObject] readonly attribute XRInputSource inputSource;
};
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 ca92e785456..ec5dfc9ea36 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(blink::Visitor* visitor) {
+void XRInputSourcesChangeEvent::Trace(Visitor* visitor) {
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 fe4940c331b..94786139334 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
@@ -5,9 +5,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_INPUT_SOURCES_CHANGE_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_INPUT_SOURCES_CHANGE_EVENT_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_xr_input_sources_change_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/xr/xr_input_source.h"
-#include "third_party/blink/renderer/modules/xr/xr_input_sources_change_event_init.h"
#include "third_party/blink/renderer/modules/xr/xr_session.h"
namespace blink {
@@ -45,7 +45,7 @@ class XRInputSourcesChangeEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<XRSession> session_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.idl b/chromium/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.idl
index 3d3acfa8b02..7a6cfcabd41 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.idl
@@ -5,9 +5,9 @@
[
SecureContext,
Exposed=Window,
- RuntimeEnabled=WebXR,
- Constructor(DOMString type, XRInputSourcesChangeEventInit eventInitDict)
+ RuntimeEnabled=WebXR
] interface XRInputSourcesChangeEvent : Event {
+ constructor(DOMString type, XRInputSourcesChangeEventInit eventInitDict);
[SameObject] readonly attribute XRSession session;
[SameObject, SaveSameObject] readonly attribute FrozenArray<XRInputSource> added;
[SameObject, SaveSameObject] readonly attribute FrozenArray<XRInputSource> removed;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_light_estimation.cc b/chromium/third_party/blink/renderer/modules/xr/xr_light_estimation.cc
new file mode 100644
index 00000000000..cb4c72bc4b2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_light_estimation.cc
@@ -0,0 +1,38 @@
+// 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/xr/xr_light_estimation.h"
+
+#include "device/vr/public/mojom/vr_service.mojom-blink.h"
+#include "third_party/blink/renderer/modules/xr/xr_light_probe.h"
+#include "third_party/blink/renderer/modules/xr/xr_reflection_probe.h"
+
+namespace blink {
+
+XRLightEstimation::XRLightEstimation(
+ const device::mojom::blink::XRLightEstimationData& data) {
+ if (data.light_probe) {
+ light_probe_ = MakeGarbageCollected<XRLightProbe>(*data.light_probe);
+ }
+ if (data.reflection_probe) {
+ reflection_probe_ =
+ MakeGarbageCollected<XRReflectionProbe>(*data.reflection_probe);
+ }
+}
+
+XRLightProbe* XRLightEstimation::lightProbe() const {
+ return light_probe_.Get();
+}
+
+XRReflectionProbe* XRLightEstimation::reflectionProbe() const {
+ return reflection_probe_.Get();
+}
+
+void XRLightEstimation::Trace(Visitor* visitor) {
+ visitor->Trace(light_probe_);
+ visitor->Trace(reflection_probe_);
+ ScriptWrappable::Trace(visitor);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_light_estimation.h b/chromium/third_party/blink/renderer/modules/xr/xr_light_estimation.h
new file mode 100644
index 00000000000..d4d78ab6639
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_light_estimation.h
@@ -0,0 +1,35 @@
+// 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_XR_XR_LIGHT_ESTIMATION_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_LIGHT_ESTIMATION_H_
+
+#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+
+namespace blink {
+
+class XRLightProbe;
+class XRReflectionProbe;
+
+class XRLightEstimation : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ explicit XRLightEstimation(
+ const device::mojom::blink::XRLightEstimationData& data);
+
+ XRLightProbe* lightProbe() const;
+ XRReflectionProbe* reflectionProbe() const;
+
+ void Trace(Visitor* visitor) override;
+
+ private:
+ Member<XRLightProbe> light_probe_;
+ Member<XRReflectionProbe> reflection_probe_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_LIGHT_ESTIMATION_H_
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_light_estimation.idl b/chromium/third_party/blink/renderer/modules/xr/xr_light_estimation.idl
new file mode 100644
index 00000000000..fdc12a618f8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_light_estimation.idl
@@ -0,0 +1,14 @@
+// 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.
+
+[
+ SecureContext,
+ Exposed=Window,
+ RuntimeEnabled=WebXRIncubations
+]
+interface XRLightEstimation {
+ readonly attribute XRLightProbe? lightProbe;
+ readonly attribute XRReflectionProbe? reflectionProbe;
+};
+
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_light_estimation_state.cc b/chromium/third_party/blink/renderer/modules/xr/xr_light_estimation_state.cc
new file mode 100644
index 00000000000..5e7b73d317c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_light_estimation_state.cc
@@ -0,0 +1,20 @@
+// 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/xr/xr_light_estimation_state.h"
+
+#include "third_party/blink/renderer/bindings/modules/v8/v8_xr_light_estimation_state_init.h"
+
+namespace blink {
+
+XRLightEstimationState::XRLightEstimationState(
+ XRLightEstimationStateInit* light_estimation_state_init) {
+ if (light_estimation_state_init) {
+ if (light_estimation_state_init->hasEnabled()) {
+ enabled_ = light_estimation_state_init->enabled();
+ }
+ }
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_light_estimation_state.h b/chromium/third_party/blink/renderer/modules/xr/xr_light_estimation_state.h
new file mode 100644
index 00000000000..c1ab4305167
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_light_estimation_state.h
@@ -0,0 +1,29 @@
+// 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_XR_XR_LIGHT_ESTIMATION_STATE_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_LIGHT_ESTIMATION_STATE_H_
+
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+
+namespace blink {
+
+class XRLightEstimationStateInit;
+
+class XRLightEstimationState : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ explicit XRLightEstimationState(
+ XRLightEstimationStateInit* light_estimation_state_init);
+
+ bool enabled() const { return enabled_; }
+
+ private:
+ bool enabled_ = false;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_LIGHT_ESTIMATION_STATE_H_
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_light_estimation_state.idl b/chromium/third_party/blink/renderer/modules/xr/xr_light_estimation_state.idl
new file mode 100644
index 00000000000..305f741b4f1
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_light_estimation_state.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.
+
+[
+ SecureContext,
+ Exposed=Window,
+ RuntimeEnabled=WebXRIncubations
+]
+interface XRLightEstimationState {
+ readonly attribute boolean enabled;
+};
+
diff --git a/chromium/third_party/blink/renderer/modules/sms/sms_receiver_options.idl b/chromium/third_party/blink/renderer/modules/xr/xr_light_estimation_state_init.idl
index c77820d9ffb..379f6d90f6e 100644
--- a/chromium/third_party/blink/renderer/modules/sms/sms_receiver_options.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_light_estimation_state_init.idl
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://github.com/samuelgoto/sms-receiver
-
-dictionary SMSReceiverOptions {
- AbortSignal signal;
+dictionary XRLightEstimationStateInit {
+ boolean enabled;
};
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
new file mode 100644
index 00000000000..46de95dcb1c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.cc
@@ -0,0 +1,47 @@
+// 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/xr/xr_light_probe.h"
+
+#include "device/vr/public/mojom/vr_service.mojom-blink.h"
+#include "third_party/blink/renderer/core/geometry/dom_point_read_only.h"
+#include "third_party/blink/renderer/modules/xr/xr_spherical_harmonics.h"
+
+namespace blink {
+
+XRLightProbe::XRLightProbe(
+ const device::mojom::blink::XRLightProbe& light_probe) {
+ spherical_harmonics_ = MakeGarbageCollected<XRSphericalHarmonics>(
+ *light_probe.spherical_harmonics);
+
+ main_light_direction_ =
+ DOMPointReadOnly::Create(light_probe.main_light_direction.x(),
+ light_probe.main_light_direction.y(),
+ light_probe.main_light_direction.z(), 0);
+ main_light_intensity_ =
+ DOMPointReadOnly::Create(light_probe.main_light_intensity.red(),
+ light_probe.main_light_intensity.green(),
+ light_probe.main_light_intensity.blue(), 1);
+}
+
+XRSphericalHarmonics* XRLightProbe::sphericalHarmonics() const {
+ return spherical_harmonics_.Get();
+}
+
+DOMPointReadOnly* XRLightProbe::mainLightDirection() const {
+ return main_light_direction_.Get();
+}
+
+DOMPointReadOnly* XRLightProbe::mainLightIntensity() const {
+ return main_light_intensity_.Get();
+}
+
+void XRLightProbe::Trace(Visitor* visitor) {
+ visitor->Trace(spherical_harmonics_);
+ visitor->Trace(main_light_direction_);
+ visitor->Trace(main_light_intensity_);
+ ScriptWrappable::Trace(visitor);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..06912d21516
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.h
@@ -0,0 +1,36 @@
+// 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_XR_XR_LIGHT_PROBE_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_LIGHT_PROBE_H_
+
+#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+
+namespace blink {
+
+class XRSphericalHarmonics;
+class DOMPointReadOnly;
+
+class XRLightProbe : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ explicit XRLightProbe(const device::mojom::blink::XRLightProbe& light_probe);
+
+ XRSphericalHarmonics* sphericalHarmonics() const;
+ DOMPointReadOnly* mainLightDirection() const;
+ DOMPointReadOnly* mainLightIntensity() const;
+
+ void Trace(Visitor* visitor) override;
+
+ private:
+ Member<XRSphericalHarmonics> spherical_harmonics_;
+ Member<DOMPointReadOnly> main_light_direction_;
+ Member<DOMPointReadOnly> main_light_intensity_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_LIGHT_PROBE_H_
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
new file mode 100644
index 00000000000..691c4c667d2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.idl
@@ -0,0 +1,15 @@
+// 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.
+
+[
+ SecureContext,
+ Exposed=Window,
+ RuntimeEnabled=WebXRIncubations
+]
+interface XRLightProbe {
+ readonly attribute XRSphericalHarmonics sphericalHarmonics;
+ readonly attribute DOMPointReadOnly mainLightDirection;
+ readonly attribute DOMPointReadOnly mainLightIntensity;
+};
+
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 a35b6894c01..ed71e679360 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
@@ -21,21 +21,24 @@ class XRObjectSpace : public XRSpace {
explicit XRObjectSpace(XRSession* session, const T* object)
: XRSpace(session), object_(object) {}
- std::unique_ptr<TransformationMatrix> MojoFromSpace() override {
- auto object_from_mojo = object_->poseMatrix();
-
- if (!object_from_mojo.IsInvertible()) {
+ std::unique_ptr<TransformationMatrix> MojoFromNative() override {
+ auto maybe_mojo_from_object = object_->MojoFromObject();
+ if (maybe_mojo_from_object) {
+ return std::make_unique<TransformationMatrix>(*maybe_mojo_from_object);
+ } else {
return nullptr;
}
+ }
- return std::make_unique<TransformationMatrix>(object_from_mojo.Inverse());
+ std::unique_ptr<TransformationMatrix> NativeFromMojo() final {
+ return TryInvert(MojoFromNative());
}
base::Optional<XRNativeOriginInformation> NativeOrigin() const override {
return XRNativeOriginInformation::Create(object_);
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 d15edc9cd5a..1d3d9f161a4 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_plane.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_plane.cc
@@ -15,27 +15,31 @@ namespace blink {
XRPlane::XRPlane(uint64_t id,
XRSession* session,
- const device::mojom::blink::XRPlaneDataPtr& plane_data,
+ const device::mojom::blink::XRPlaneData& plane_data,
double timestamp)
: XRPlane(id,
session,
mojo::ConvertTo<base::Optional<blink::XRPlane::Orientation>>(
- plane_data->orientation),
- mojo::ConvertTo<blink::TransformationMatrix>(plane_data->pose),
+ plane_data.orientation),
mojo::ConvertTo<HeapVector<Member<DOMPointReadOnly>>>(
- plane_data->polygon),
- timestamp) {}
+ plane_data.polygon),
+ timestamp) {
+ // No need for else - if pose is not present, the default-constructed unique
+ // ptr is fine.
+ if (plane_data.pose) {
+ SetMojoFromPlane(
+ mojo::ConvertTo<blink::TransformationMatrix>(plane_data.pose));
+ }
+}
XRPlane::XRPlane(uint64_t id,
XRSession* session,
const base::Optional<Orientation>& orientation,
- const TransformationMatrix& pose_matrix,
const HeapVector<Member<DOMPointReadOnly>>& polygon,
double timestamp)
: id_(id),
polygon_(polygon),
orientation_(orientation),
- pose_matrix_(std::make_unique<TransformationMatrix>(pose_matrix)),
session_(session),
last_changed_time_(timestamp) {
DVLOG(3) << __func__;
@@ -53,13 +57,17 @@ XRSpace* XRPlane::planeSpace() const {
return plane_space_;
}
-TransformationMatrix XRPlane::poseMatrix() const {
- return *pose_matrix_;
+base::Optional<TransformationMatrix> XRPlane::MojoFromObject() const {
+ if (!mojo_from_plane_) {
+ return base::nullopt;
+ }
+
+ return *mojo_from_plane_;
}
String XRPlane::orientation() const {
- if (orientation_.has_value()) {
- switch (orientation_.value()) {
+ if (orientation_) {
+ switch (*orientation_) {
case Orientation::kHorizontal:
return "Horizontal";
case Orientation::kVertical:
@@ -85,25 +93,57 @@ ScriptPromise XRPlane::createAnchor(ScriptState* script_state,
XRRigidTransform* initial_pose,
XRSpace* space,
ExceptionState& exception_state) {
- return session_->CreateAnchor(script_state, initial_pose, space, this,
- exception_state);
+ if (!initial_pose) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ XRSession::kNoRigidTransformSpecified);
+ return {};
+ }
+
+ if (!space) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ XRSession::kNoSpaceSpecified);
+ return {};
+ }
+
+ auto maybe_mojo_from_offset = space->MojoFromOffsetMatrix();
+
+ if (!maybe_mojo_from_offset) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ XRSession::kUnableToRetrieveMatrix);
+ return {};
+ }
+
+ return session_->CreateAnchor(script_state, initial_pose->TransformMatrix(),
+ *maybe_mojo_from_offset, id_, exception_state);
}
-void XRPlane::Update(const device::mojom::blink::XRPlaneDataPtr& plane_data,
+void XRPlane::Update(const device::mojom::blink::XRPlaneData& plane_data,
double timestamp) {
DVLOG(3) << __func__;
last_changed_time_ = timestamp;
orientation_ = mojo::ConvertTo<base::Optional<blink::XRPlane::Orientation>>(
- plane_data->orientation);
- *pose_matrix_ =
- mojo::ConvertTo<blink::TransformationMatrix>(plane_data->pose);
- polygon_ = mojo::ConvertTo<HeapVector<Member<DOMPointReadOnly>>>(
- plane_data->polygon);
+ plane_data.orientation);
+ if (plane_data.pose) {
+ SetMojoFromPlane(
+ mojo::ConvertTo<blink::TransformationMatrix>(plane_data.pose));
+ } else {
+ mojo_from_plane_ = nullptr;
+ }
+ 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(blink::Visitor* visitor) {
+void XRPlane::Trace(Visitor* visitor) {
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 f42f4089456..b4e9b877f3c 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_plane.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_plane.h
@@ -29,20 +29,14 @@ class XRPlane : public ScriptWrappable {
XRPlane(uint64_t id,
XRSession* session,
- const device::mojom::blink::XRPlaneDataPtr& plane_data,
- double timestamp);
- XRPlane(uint64_t id,
- XRSession* session,
- const base::Optional<Orientation>& orientation,
- const TransformationMatrix& pose_matrix,
- const HeapVector<Member<DOMPointReadOnly>>& polygon,
+ const device::mojom::blink::XRPlaneData& plane_data,
double timestamp);
uint64_t id() const;
XRSpace* planeSpace() const;
- TransformationMatrix poseMatrix() const;
+ base::Optional<TransformationMatrix> MojoFromObject() const;
String orientation() const;
HeapVector<Member<DOMPointReadOnly>> polygon() const;
@@ -56,18 +50,26 @@ class XRPlane : public ScriptWrappable {
// Updates plane data from passed in |plane_data|. The resulting instance
// should be equivalent to the instance that would be create by calling
// XRPlane(plane_data).
- void Update(const device::mojom::blink::XRPlaneDataPtr& plane_data,
+ void Update(const device::mojom::blink::XRPlaneData& plane_data,
double timestamp);
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
private:
+ XRPlane(uint64_t id,
+ XRSession* session,
+ const base::Optional<Orientation>& orientation,
+ const HeapVector<Member<DOMPointReadOnly>>& polygon,
+ 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.
- std::unique_ptr<TransformationMatrix> pose_matrix_;
+ std::unique_ptr<TransformationMatrix> 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 2c2f6820fa4..e448c0793bf 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=WebXRPlaneDetection
+ RuntimeEnabled=WebXRIncubations
]
interface XRPlane {
readonly attribute XRSpace planeSpace;
@@ -20,5 +20,5 @@ interface XRPlane {
readonly attribute XRPlaneOrientation? orientation;
readonly attribute DOMHighResTimeStamp lastChangedTime;
- [RuntimeEnabled=WebXRAnchors, CallWith=ScriptState, RaisesException] Promise<XRAnchor> createAnchor(XRRigidTransform initial_pose, XRSpace space);
+ [CallWith=ScriptState, RaisesException] Promise<XRAnchor> createAnchor(XRRigidTransform initial_pose, XRSpace space);
};
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_plane_detection_state.cc b/chromium/third_party/blink/renderer/modules/xr/xr_plane_detection_state.cc
index 32d242272c7..800d67a4800 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_plane_detection_state.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_plane_detection_state.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/modules/xr/xr_plane_detection_state.h"
-#include "third_party/blink/renderer/modules/xr/xr_plane_detection_state_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_xr_plane_detection_state_init.h"
namespace blink {
XRPlaneDetectionState::XRPlaneDetectionState(
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_plane_detection_state.h b/chromium/third_party/blink/renderer/modules/xr/xr_plane_detection_state.h
index ff33f51dbad..22499d7629f 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_plane_detection_state.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_plane_detection_state.h
@@ -17,8 +17,8 @@ class XRPlaneDetectionState : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
- XRPlaneDetectionState(
- XRPlaneDetectionStateInit* plane_detection_state_init = nullptr);
+ explicit XRPlaneDetectionState(
+ XRPlaneDetectionStateInit* plane_detection_state_init);
bool enabled() const { return enabled_; }
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 9457324459d..8b41426af0f 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=WebXRPlaneDetection
+ RuntimeEnabled=WebXRIncubations
]
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 085315e9393..f941384cf79 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(blink::Visitor* visitor) {
+void XRPlaneSet::Trace(Visitor* visitor) {
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 8853f15f3fd..ba27dbe0238 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(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) 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 8e04e6bd65d..f0d3a0d4ce8 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=WebXRPlaneDetection
+ RuntimeEnabled=WebXRIncubations
]
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 91a5d4c3b05..4eeb10dfe14 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(blink::Visitor* visitor) {
+void XRPose::Trace(Visitor* visitor) {
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 df99305f51c..fcc0adde4b6 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 17139f4e613..41f2ad96b27 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_ray.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_ray.cc
@@ -8,7 +8,7 @@
#include <cmath>
#include <utility>
-#include "third_party/blink/renderer/core/geometry/dom_point_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_point_init.h"
#include "third_party/blink/renderer/core/geometry/dom_point_read_only.h"
#include "third_party/blink/renderer/modules/xr/xr_rigid_transform.h"
#include "third_party/blink/renderer/modules/xr/xr_utils.h"
@@ -142,7 +142,7 @@ DOMFloat32Array* XRRay::matrix() {
// steps:
// Step 1. If the operation IsDetachedBuffer on internal matrix is false,
// return transform’s internal matrix.
- if (!matrix_ || !matrix_->View() || !matrix_->View()->Data()) {
+ if (!matrix_ || !matrix_->Data()) {
// Returned matrix should represent transformation from ray originating at
// (0,0,0) with direction (0,0,-1) into ray originating at |origin_| with
// direction |direction_|.
@@ -208,7 +208,7 @@ TransformationMatrix XRRay::RawMatrix() {
return *raw_matrix_;
}
-void XRRay::Trace(blink::Visitor* visitor) {
+void XRRay::Trace(Visitor* visitor) {
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 f76b7ac2566..c041069c2bc 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_ray.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_ray.h
@@ -49,7 +49,7 @@ class XRRay final : public ScriptWrappable {
static XRRay* Create(XRRigidTransform* transform,
ExceptionState& exception_state);
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void Set(const TransformationMatrix& matrix, ExceptionState& exception_state);
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_ray.idl b/chromium/third_party/blink/renderer/modules/xr/xr_ray.idl
index 38bb19e4100..290203afaa1 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_ray.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_ray.idl
@@ -6,13 +6,12 @@
[
SecureContext,
Exposed=Window,
- RuntimeEnabled=WebXRHitTest,
- Constructor(),
- Constructor(DOMPointInit origin),
- Constructor(DOMPointInit origin, DOMPointInit direction),
- Constructor(XRRigidTransform transform),
- RaisesException=Constructor
+ RuntimeEnabled=WebXRHitTest
] interface XRRay {
+ [RaisesException] constructor();
+ [RaisesException] constructor(DOMPointInit origin);
+ [RaisesException] constructor(DOMPointInit origin, DOMPointInit direction);
+ [RaisesException] constructor(XRRigidTransform transform);
[SameObject] readonly attribute DOMPointReadOnly origin;
[SameObject] readonly attribute DOMPointReadOnly direction;
[SameObject] readonly attribute Float32Array matrix;
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 cc1d9d673b3..94749357c8f 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
@@ -46,25 +46,23 @@ XRReferenceSpace::XRReferenceSpace(XRSession* session,
XRReferenceSpace::~XRReferenceSpace() = default;
-XRPose* XRReferenceSpace::getPose(
- XRSpace* other_space,
- const TransformationMatrix* mojo_from_viewer) {
+XRPose* XRReferenceSpace::getPose(XRSpace* other_space) {
if (type_ == Type::kTypeViewer) {
- std::unique_ptr<TransformationMatrix> other_offsetspace_from_viewer =
- other_space->SpaceFromViewerWithDefaultAndOffset(mojo_from_viewer);
- if (!other_offsetspace_from_viewer) {
+ std::unique_ptr<TransformationMatrix> other_offset_from_viewer =
+ other_space->OffsetFromViewer();
+ if (!other_offset_from_viewer) {
return nullptr;
}
- auto viewer_from_offset = OriginOffsetMatrix();
+ auto viewer_from_offset = NativeFromOffsetMatrix();
- auto other_offsetspace_from_offset =
- *other_offsetspace_from_viewer * viewer_from_offset;
+ auto other_offset_from_offset =
+ *other_offset_from_viewer * viewer_from_offset;
- return MakeGarbageCollected<XRPose>(other_offsetspace_from_offset,
+ return MakeGarbageCollected<XRPose>(other_offset_from_offset,
session()->EmulatedPosition());
} else {
- return XRSpace::getPose(other_space, mojo_from_viewer);
+ return XRSpace::getPose(other_space);
}
}
@@ -85,16 +83,8 @@ void XRReferenceSpace::SetFloorFromMojo() {
display_info_id_ = session()->DisplayInfoPtrId();
}
-// Returns a default viewer pose if no actual viewer pose is available. Only
-// applicable to viewer reference spaces.
-std::unique_ptr<TransformationMatrix> XRReferenceSpace::DefaultViewerPose() {
- // A viewer reference space always returns an identity matrix.
- return type_ == Type::kTypeViewer ? std::make_unique<TransformationMatrix>()
- : nullptr;
-}
-
-std::unique_ptr<TransformationMatrix> XRReferenceSpace::SpaceFromMojo(
- const TransformationMatrix& mojo_from_viewer) {
+std::unique_ptr<TransformationMatrix> XRReferenceSpace::NativeFromMojo() {
+ auto mojo_from_viewer = session()->MojoFromViewer();
switch (type_) {
case Type::kTypeLocal:
// Currently 'local' space is equivalent to mojo space.
@@ -111,8 +101,14 @@ std::unique_ptr<TransformationMatrix> XRReferenceSpace::SpaceFromMojo(
SetFloorFromMojo();
return std::make_unique<TransformationMatrix>(*floor_from_mojo_);
case Type::kTypeViewer:
- // Return viewer_from_mojo which is the inverse of mojo_from_viewer.
- return std::make_unique<TransformationMatrix>(mojo_from_viewer.Inverse());
+ // If we don't have mojo_from_viewer, then it's the default pose,
+ // which is the identity pose.
+ if (!mojo_from_viewer)
+ return std::make_unique<TransformationMatrix>();
+ DCHECK(mojo_from_viewer->IsInvertible());
+ // Otherwise we need to return viewer_from_mojo which is the inverse.
+ return std::make_unique<TransformationMatrix>(
+ mojo_from_viewer->Inverse());
case Type::kTypeUnbounded:
// For now we assume that poses returned by systems that support unbounded
// reference spaces are already in the correct space. Return an identity.
@@ -125,73 +121,36 @@ std::unique_ptr<TransformationMatrix> XRReferenceSpace::SpaceFromMojo(
return nullptr;
}
-// Returns the refspace-from-viewerspace transform, corresponding to the pose of
-// the viewer in this space. This takes the mojo_from_viewer transform (viewer
-// pose in mojo space) as input, and left-multiplies space_from_mojo onto that.
-std::unique_ptr<TransformationMatrix> XRReferenceSpace::SpaceFromViewer(
- const TransformationMatrix& mojo_from_viewer) {
+std::unique_ptr<TransformationMatrix> XRReferenceSpace::NativeFromViewer(
+ const TransformationMatrix* mojo_from_viewer) {
if (type_ == Type::kTypeViewer) {
// Special case for viewer space, always return an identity matrix
- // explicitly. In theory the default behavior of multiplying SpaceFromMojo *
- // MojoFromViewer would be equivalent, but that would likely return an
+ // explicitly. In theory the default behavior of multiplying NativeFromMojo
+ // onto MojoFromViewer would be equivalent, but that would likely return an
// almost-identity due to rounding errors.
return std::make_unique<TransformationMatrix>();
}
- // Return space_from_viewer = space_from_mojo * mojo_from_viewer
- auto space_from_viewer = SpaceFromMojo(mojo_from_viewer);
- if (!space_from_viewer)
+ if (!mojo_from_viewer)
return nullptr;
- space_from_viewer->Multiply(mojo_from_viewer);
- return space_from_viewer;
-}
-std::unique_ptr<TransformationMatrix> XRReferenceSpace::SpaceFromInputForViewer(
- const TransformationMatrix& mojo_from_input,
- const TransformationMatrix& mojo_from_viewer) {
- // Return space_from_input = space_from_mojo * mojo_from_input
- auto space_from_input = SpaceFromMojo(mojo_from_viewer);
- if (!space_from_input)
+ // Return native_from_viewer = native_from_mojo * mojo_from_viewer
+ auto native_from_viewer = NativeFromMojo();
+ if (!native_from_viewer)
return nullptr;
- space_from_input->Multiply(mojo_from_input);
- return space_from_input;
+ native_from_viewer->Multiply(*mojo_from_viewer);
+ return native_from_viewer;
}
-std::unique_ptr<TransformationMatrix> XRReferenceSpace::MojoFromSpace() {
- // XRReferenceSpace doesn't do anything special with the base pose, but
- // derived reference spaces (bounded, unbounded, stationary, etc.) have their
- // own custom behavior.
-
- // Calculate the offset space's pose (including originOffset) in mojo
- // space.
- // Note that although this calls SpaceFromViewer, because we're passing in
- // identity, "viewer" is actually mojo.
- TransformationMatrix identity;
- std::unique_ptr<TransformationMatrix> base_space_from_mojo =
- SpaceFromViewer(identity);
-
- if (!base_space_from_mojo) {
- // Transform wasn't possible.
- return nullptr;
- }
-
- // Rigid transforms should always be invertible.
- DCHECK(base_space_from_mojo->IsInvertible());
- TransformationMatrix mojo_from_base_space = base_space_from_mojo->Inverse();
-
- // Must account for position and orientation defined by origin offset.
- // Result is mojo_from_offset = mojo_from_base_space * base_space_from_offset,
- // where base_space_from_offset is originOffset's transform matrix.
- // TODO(https://crbug.com/1008466): move originOffset to separate class?
- return std::make_unique<TransformationMatrix>(
- mojo_from_base_space.Multiply(origin_offset_->TransformMatrix()));
+std::unique_ptr<TransformationMatrix> XRReferenceSpace::MojoFromNative() {
+ return TryInvert(NativeFromMojo());
}
-TransformationMatrix XRReferenceSpace::OriginOffsetMatrix() {
+TransformationMatrix XRReferenceSpace::NativeFromOffsetMatrix() {
return origin_offset_->TransformMatrix();
}
-TransformationMatrix XRReferenceSpace::InverseOriginOffsetMatrix() {
+TransformationMatrix XRReferenceSpace::OffsetFromNativeMatrix() {
return origin_offset_->InverseTransformMatrix();
}
@@ -202,7 +161,7 @@ XRReferenceSpace::Type XRReferenceSpace::GetType() const {
XRReferenceSpace* XRReferenceSpace::getOffsetReferenceSpace(
XRRigidTransform* additional_offset) {
auto matrix =
- OriginOffsetMatrix().Multiply(additional_offset->TransformMatrix());
+ NativeFromOffsetMatrix().Multiply(additional_offset->TransformMatrix());
auto* result_transform = MakeGarbageCollected<XRRigidTransform>(matrix);
return cloneWithOriginOffset(result_transform);
@@ -219,7 +178,7 @@ base::Optional<XRNativeOriginInformation> XRReferenceSpace::NativeOrigin()
return XRNativeOriginInformation::Create(this);
}
-void XRReferenceSpace::Trace(blink::Visitor* visitor) {
+void XRReferenceSpace::Trace(Visitor* visitor) {
visitor->Trace(origin_offset_);
XRSpace::Trace(visitor);
}
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 dd112382514..4ad5be6df0e 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
@@ -36,21 +36,21 @@ class XRReferenceSpace : public XRSpace {
Type type);
~XRReferenceSpace() override;
- XRPose* getPose(XRSpace* other_space,
- const TransformationMatrix* mojo_from_viewer) override;
- std::unique_ptr<TransformationMatrix> DefaultViewerPose() override;
- std::unique_ptr<TransformationMatrix> SpaceFromMojo(
- const TransformationMatrix& mojo_from_viewer) override;
- std::unique_ptr<TransformationMatrix> SpaceFromViewer(
- const TransformationMatrix& mojo_from_viewer) override;
- std::unique_ptr<TransformationMatrix> SpaceFromInputForViewer(
- const TransformationMatrix& mojo_from_input,
- const TransformationMatrix& mojo_from_viewer) override;
-
- std::unique_ptr<TransformationMatrix> MojoFromSpace() override;
-
- TransformationMatrix OriginOffsetMatrix() override;
- TransformationMatrix InverseOriginOffsetMatrix() override;
+ std::unique_ptr<TransformationMatrix> NativeFromMojo() override;
+ std::unique_ptr<TransformationMatrix> NativeFromViewer(
+ const TransformationMatrix* mojo_from_viewer) override;
+
+ // MojoFromNative is final to enforce that children should be returning
+ // NativeFromMojo, since this is simply written to always provide the inverse
+ // of NativeFromMojo
+ std::unique_ptr<TransformationMatrix> MojoFromNative() final;
+
+ TransformationMatrix NativeFromOffsetMatrix() override;
+ TransformationMatrix OffsetFromNativeMatrix() override;
+
+ // We override getPose to ensure that the viewer pose in viewer space returns
+ // the identity pose instead of the result of multiplying inverse matrices.
+ XRPose* getPose(XRSpace* other_space) override;
Type GetType() const;
@@ -60,7 +60,7 @@ class XRReferenceSpace : public XRSpace {
base::Optional<XRNativeOriginInformation> NativeOrigin() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
virtual void OnReset();
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 194959d4934..09a4c970517 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(blink::Visitor* visitor) {
+void XRReferenceSpaceEvent::Trace(Visitor* visitor) {
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 8a017f94558..291b5f8d0c0 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
@@ -5,8 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_REFERENCE_SPACE_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_REFERENCE_SPACE_EVENT_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_xr_reference_space_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
-#include "third_party/blink/renderer/modules/xr/xr_reference_space_event_init.h"
namespace blink {
@@ -41,7 +41,7 @@ class XRReferenceSpaceEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<XRReferenceSpace> reference_space_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_reference_space_event.idl b/chromium/third_party/blink/renderer/modules/xr/xr_reference_space_event.idl
index 3e58aaed15d..9b151dcdbe1 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_reference_space_event.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_reference_space_event.idl
@@ -6,9 +6,9 @@
[
SecureContext,
Exposed=Window,
- RuntimeEnabled=WebXR,
- Constructor(DOMString type, XRReferenceSpaceEventInit eventInitDict)
+ RuntimeEnabled=WebXR
] interface XRReferenceSpaceEvent : Event {
+ constructor(DOMString type, XRReferenceSpaceEventInit eventInitDict);
[SameObject] readonly attribute XRReferenceSpace referenceSpace;
[SameObject] readonly attribute XRRigidTransform transform;
};
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_reflection_probe.cc b/chromium/third_party/blink/renderer/modules/xr/xr_reflection_probe.cc
new file mode 100644
index 00000000000..81b55d81f0e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_reflection_probe.cc
@@ -0,0 +1,26 @@
+// 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/xr/xr_reflection_probe.h"
+
+#include "device/vr/public/mojom/vr_service.mojom-blink.h"
+#include "third_party/blink/renderer/modules/xr/xr_cube_map.h"
+
+namespace blink {
+
+XRReflectionProbe::XRReflectionProbe(
+ const device::mojom::blink::XRReflectionProbe& reflection_probe) {
+ cube_map_ = MakeGarbageCollected<XRCubeMap>(*reflection_probe.cube_map);
+}
+
+XRCubeMap* XRReflectionProbe::cubeMap() const {
+ return cube_map_.Get();
+}
+
+void XRReflectionProbe::Trace(Visitor* visitor) {
+ visitor->Trace(cube_map_);
+ ScriptWrappable::Trace(visitor);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_reflection_probe.h b/chromium/third_party/blink/renderer/modules/xr/xr_reflection_probe.h
new file mode 100644
index 00000000000..4264caf16a7
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_reflection_probe.h
@@ -0,0 +1,33 @@
+// 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_XR_XR_REFLECTION_PROBE_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_REFLECTION_PROBE_H_
+
+#include "base/util/type_safety/pass_key.h"
+#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+
+namespace blink {
+
+class XRCubeMap;
+
+class XRReflectionProbe : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ explicit XRReflectionProbe(
+ const device::mojom::blink::XRReflectionProbe& reflection_probe);
+
+ XRCubeMap* cubeMap() const;
+
+ void Trace(Visitor* visitor) override;
+
+ private:
+ Member<XRCubeMap> cube_map_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_REFLECTION_PROBE_H_
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_reflection_probe.idl b/chromium/third_party/blink/renderer/modules/xr/xr_reflection_probe.idl
new file mode 100644
index 00000000000..8d0275ae861
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_reflection_probe.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.
+
+[
+ SecureContext,
+ Exposed=Window,
+ RuntimeEnabled=WebXRIncubations
+]
+interface XRReflectionProbe {
+ readonly attribute XRCubeMap cubeMap;
+};
+
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 7f62fe21c44..427ae941677 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
@@ -9,7 +9,7 @@
#include <algorithm>
#include <cmath>
-#include "third_party/blink/renderer/modules/xr/xr_render_state_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_xr_render_state_init.h"
#include "third_party/blink/renderer/modules/xr/xr_webgl_layer.h"
namespace blink {
@@ -55,12 +55,18 @@ HTMLCanvasElement* XRRenderState::output_canvas() const {
return nullptr;
}
+base::Optional<double> XRRenderState::inlineVerticalFieldOfView() const {
+ if (immersive_)
+ return base::nullopt;
+ return inline_vertical_fov_;
+}
+
double XRRenderState::inlineVerticalFieldOfView(bool& is_null) const {
is_null = immersive_ || !inline_vertical_fov_.has_value();
return is_null ? 0 : *inline_vertical_fov_;
}
-void XRRenderState::Trace(blink::Visitor* visitor) {
+void XRRenderState::Trace(Visitor* visitor) {
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 f2837269c3c..c5f77f16e5d 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
@@ -25,7 +25,9 @@ class XRRenderState : public ScriptWrappable {
// Session's views.
double depthNear() const { return depth_near_; }
double depthFar() const { return depth_far_; }
- double inlineVerticalFieldOfView(bool& is_null) const;
+ base::Optional<double> inlineVerticalFieldOfView() const;
+ // TODO(crbug.com/1060971): Remove |is_null| version.
+ double inlineVerticalFieldOfView(bool& is_null) const; // DEPRECATED
XRWebGLLayer* baseLayer() const { return base_layer_; }
HTMLCanvasElement* output_canvas() const;
@@ -36,7 +38,7 @@ class XRRenderState : public ScriptWrappable {
// bound to a different session.
void removeOutputContext();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) 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 1e5b7314c5b..1e0b1364104 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
@@ -6,7 +6,7 @@
#include <utility>
-#include "third_party/blink/renderer/core/geometry/dom_point_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_point_init.h"
#include "third_party/blink/renderer/core/geometry/dom_point_read_only.h"
#include "third_party/blink/renderer/modules/xr/xr_utils.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -92,8 +92,7 @@ DOMFloat32Array* XRRigidTransform::matrix() {
matrix_array_ = transformationMatrixToDOMFloat32Array(*matrix_);
}
- if (!matrix_array_ || !matrix_array_->View() ||
- !matrix_array_->View()->Data()) {
+ if (!matrix_array_ || !matrix_array_->Data()) {
// A page may take the matrix_array_ value and detach it so matrix_array_ is
// a detached array buffer. This breaks the inspector, so return null
// instead.
@@ -156,7 +155,7 @@ void XRRigidTransform::EnsureInverse() {
}
}
-void XRRigidTransform::Trace(blink::Visitor* visitor) {
+void XRRigidTransform::Trace(Visitor* visitor) {
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 c395827a65d..e00e99bcc6d 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void DecomposeMatrix();
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_rigid_transform.idl b/chromium/third_party/blink/renderer/modules/xr/xr_rigid_transform.idl
index 1faea2ba3a7..84bd98a9f09 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_rigid_transform.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_rigid_transform.idl
@@ -7,10 +7,9 @@
[
SecureContext,
Exposed=Window,
- RuntimeEnabled=WebXR,
- Constructor(optional DOMPointInit position, optional DOMPointInit orientation),
- RaisesException=Constructor
+ RuntimeEnabled=WebXR
] interface XRRigidTransform {
+ [RaisesException] constructor(optional DOMPointInit position = {}, optional DOMPointInit orientation = {});
[SameObject] readonly attribute DOMPointReadOnly position;
[SameObject] readonly attribute DOMPointReadOnly orientation;
[SameObject] readonly attribute Float32Array matrix;
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 03f53ff3659..765532a27d7 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_session.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_session.cc
@@ -15,6 +15,10 @@
#include "services/metrics/public/cpp/ukm_builders.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_xr_frame_request_callback.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_xr_hit_test_options_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_xr_render_state_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_xr_transient_input_hit_test_options_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_xr_world_tracking_state_init.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/frame/frame.h"
@@ -24,14 +28,12 @@
#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.h"
#include "third_party/blink/renderer/modules/xr/xr_anchor_set.h"
#include "third_party/blink/renderer/modules/xr/xr_bounded_reference_space.h"
#include "third_party/blink/renderer/modules/xr/xr_canvas_input_provider.h"
+#include "third_party/blink/renderer/modules/xr/xr_dom_overlay_state.h"
#include "third_party/blink/renderer/modules/xr/xr_frame.h"
#include "third_party/blink/renderer/modules/xr/xr_frame_provider.h"
-#include "third_party/blink/renderer/modules/xr/xr_hit_result.h"
-#include "third_party/blink/renderer/modules/xr/xr_hit_test_options_init.h"
#include "third_party/blink/renderer/modules/xr/xr_hit_test_source.h"
#include "third_party/blink/renderer/modules/xr/xr_input_source_event.h"
#include "third_party/blink/renderer/modules/xr/xr_input_sources_change_event.h"
@@ -39,15 +41,13 @@
#include "third_party/blink/renderer/modules/xr/xr_ray.h"
#include "third_party/blink/renderer/modules/xr/xr_reference_space.h"
#include "third_party/blink/renderer/modules/xr/xr_render_state.h"
-#include "third_party/blink/renderer/modules/xr/xr_render_state_init.h"
#include "third_party/blink/renderer/modules/xr/xr_session_event.h"
-#include "third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_options_init.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_view.h"
#include "third_party/blink/renderer/modules/xr/xr_webgl_layer.h"
#include "third_party/blink/renderer/modules/xr/xr_world_information.h"
#include "third_party/blink/renderer/modules/xr/xr_world_tracking_state.h"
-#include "third_party/blink/renderer/modules/xr/xr_world_tracking_state_init.h"
#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
#include "third_party/blink/renderer/platform/geometry/float_point_3d.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
@@ -68,20 +68,10 @@ const char kIncompatibleLayer[] =
const char kInlineVerticalFOVNotSupported[] =
"This session does not support inlineVerticalFieldOfView";
-const char kNoSpaceSpecified[] = "No XRSpace specified.";
-
-const char kNoRigidTransformSpecified[] = "No XRRigidTransform specified.";
-
-const char kHitTestNotSupported[] = "Device does not support hit-test!";
-
const char kAnchorsNotSupported[] = "Device does not support anchors!";
const char kDeviceDisconnected[] = "The XR device has been disconnected.";
-const char kNonInvertibleMatrix[] =
- "The operation encountered non-invertible matrix and could not be "
- "completed.";
-
const char kUnableToDecomposeMatrix[] =
"The operation was unable to decompose a matrix and could not be "
"completed.";
@@ -90,6 +80,8 @@ const char kUnableToRetrieveNativeOrigin[] =
"The operation was unable to retrieve the native origin from XRSpace and "
"could not be completed.";
+const char kHitTestFeatureNotSupported[] = "Hit test feature is not supported.";
+
const char kHitTestSubscriptionFailed[] = "Hit test subscription failed.";
const char kEntityTypesNotSpecified[] =
@@ -97,8 +89,6 @@ const char kEntityTypesNotSpecified[] =
const double kDegToRad = M_PI / 180.0;
-constexpr wtf_size_t kMinNumberOfBounds = 2;
-
// Indices into the views array.
const unsigned int kMonoOrStereoLeftView = 0;
const unsigned int kStereoRightView = 1;
@@ -170,7 +160,8 @@ Vector<device::mojom::blink::EntityTypeForHitTest> GetEntityTypesForHitTest(
DCHECK(options_init);
HashSet<device::mojom::blink::EntityTypeForHitTest> result_set;
- if (options_init->hasEntityTypes()) {
+ if (RuntimeEnabledFeatures::WebXRHitTestEntityTypesEnabled() &&
+ options_init->hasEntityTypes()) {
DVLOG(2) << __func__ << ": options_init->entityTypes().size()="
<< options_init->entityTypes().size();
for (const auto& entity_type_string : options_init->entityTypes()) {
@@ -245,6 +236,10 @@ bool ValidateHitTestSourceExistsHelper(
} // namespace
+constexpr char XRSession::kNoRigidTransformSpecified[];
+constexpr char XRSession::kUnableToRetrieveMatrix[];
+constexpr char XRSession::kNoSpaceSpecified[];
+
class XRSession::XRSessionResizeObserverDelegate final
: public ResizeObserver::Delegate {
public:
@@ -260,7 +255,7 @@ class XRSession::XRSessionResizeObserverDelegate final
session_->UpdateCanvasDimensions(entries[0]->target());
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(session_);
ResizeObserver::Delegate::Trace(visitor);
}
@@ -298,24 +293,26 @@ void XRSession::MetricsReporter::ReportFeatureUsed(
case XRSessionFeature::REF_SPACE_UNBOUNDED:
recorder_->ReportFeatureUsed(XRSessionFeature::REF_SPACE_UNBOUNDED);
break;
- case XRSessionFeature::DOM_OVERLAY_FOR_HANDHELD_AR:
- // Not recording metrics for this feature currently
+ case XRSessionFeature::DOM_OVERLAY:
+ case XRSessionFeature::HIT_TEST:
+ // Not recording metrics for these features currently.
break;
}
}
XRSession::XRSession(
- XR* xr,
+ XRSystem* xr,
mojo::PendingReceiver<device::mojom::blink::XRSessionClient>
client_receiver,
- XRSession::SessionMode mode,
+ device::mojom::blink::XRSessionMode mode,
EnvironmentBlendMode environment_blend_mode,
bool uses_input_eventing,
bool sensorless_session,
XRSessionFeatureSet enabled_features)
: xr_(xr),
mode_(mode),
- environment_integration_(mode == kModeImmersiveAR),
+ environment_integration_(
+ mode == device::mojom::blink::XRSessionMode::kImmersiveAr),
world_tracking_state_(MakeGarbageCollected<XRWorldTrackingState>()),
world_information_(MakeGarbageCollected<XRWorldInformation>(this)),
enabled_features_(std::move(enabled_features)),
@@ -346,6 +343,24 @@ XRSession::XRSession(
}
}
+void XRSession::SetDOMOverlayElement(Element* element) {
+ DVLOG(2) << __func__ << ": element=" << element;
+ DCHECK(
+ enabled_features_.Contains(device::mojom::XRSessionFeature::DOM_OVERLAY));
+ DCHECK(element);
+
+ overlay_element_ = element;
+
+ // Set up the domOverlayState attribute. This could be done lazily on first
+ // access, but it's a tiny object and it's unclear if the memory that might
+ // save during XR sessions is worth the code size increase to do so. This
+ // should be revisited if the state gets more complex in the future.
+ //
+ // At this time, "screen" is the only supported DOM Overlay type.
+ dom_overlay_state_ = MakeGarbageCollected<XRDOMOverlayState>(
+ XRDOMOverlayState::DOMOverlayType::kScreen);
+}
+
const String XRSession::visibilityState() const {
switch (visibility_state_) {
case XRVisibilityState::VISIBLE:
@@ -357,7 +372,7 @@ const String XRSession::visibilityState() const {
}
}
-XRAnchorSet* XRSession::trackedAnchors() const {
+XRAnchorSet* XRSession::TrackedAnchors() const {
DVLOG(3) << __func__;
HeapHashSet<Member<XRAnchor>> result;
@@ -373,7 +388,8 @@ XRAnchorSet* XRSession::trackedAnchors() const {
}
bool XRSession::immersive() const {
- return mode_ == kModeImmersiveVR || mode_ == kModeImmersiveAR;
+ return mode_ == device::mojom::blink::XRSessionMode::kImmersiveVr ||
+ mode_ == device::mojom::blink::XRSessionMode::kImmersiveAr;
}
ExecutionContext* XRSession::GetExecutionContext() const {
@@ -455,6 +471,8 @@ ScriptPromise XRSession::requestReferenceSpace(
ScriptState* script_state,
const String& type,
ExceptionState& exception_state) {
+ DVLOG(2) << __func__;
+
if (ended_) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kSessionEnded);
@@ -503,18 +521,13 @@ ScriptPromise XRSession::requestReferenceSpace(
MakeGarbageCollected<XRReferenceSpace>(this, requested_type);
break;
case XRReferenceSpace::Type::kTypeBoundedFloor: {
- bool supports_bounded =
- immersive() && display_info_->stage_parameters &&
- display_info_->stage_parameters->bounds &&
- display_info_->stage_parameters->bounds->size() > kMinNumberOfBounds;
-
- if (supports_bounded) {
+ if (immersive()) {
reference_space = MakeGarbageCollected<XRBoundedReferenceSpace>(this);
}
break;
}
case XRReferenceSpace::Type::kTypeUnbounded:
- if (immersive() && environment_integration_) {
+ if (immersive()) {
reference_space = MakeGarbageCollected<XRReferenceSpace>(
this, XRReferenceSpace::Type::kTypeUnbounded);
}
@@ -542,29 +555,20 @@ ScriptPromise XRSession::requestReferenceSpace(
return promise;
}
-ScriptPromise XRSession::CreateAnchor(ScriptState* script_state,
- XRRigidTransform* initial_pose,
- XRSpace* space,
- XRPlane* plane,
- ExceptionState& exception_state) {
+ScriptPromise XRSession::CreateAnchor(
+ ScriptState* script_state,
+ const blink::TransformationMatrix& offset_space_from_anchor,
+ const blink::TransformationMatrix& mojo_from_offset_space,
+ base::Optional<uint64_t> plane_id,
+ ExceptionState& exception_state) {
+ DVLOG(2) << __func__ << ": plane_id.has_value()=" << plane_id.has_value();
+
if (ended_) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kSessionEnded);
return ScriptPromise();
}
- if (!initial_pose) {
- exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
- kNoRigidTransformSpecified);
- return ScriptPromise();
- }
-
- if (!space) {
- exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
- kNoSpaceSpecified);
- return ScriptPromise();
- }
-
// Reject the promise if device doesn't support the anchors API.
if (!xr_->xrEnvironmentProviderRemote()) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
@@ -572,41 +576,13 @@ ScriptPromise XRSession::CreateAnchor(ScriptState* script_state,
return ScriptPromise();
}
- auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
- ScriptPromise promise = resolver->Promise();
-
- // Transformation from passed in |space| to mojo space.
- std::unique_ptr<TransformationMatrix> mojo_from_space =
- space->MojoFromSpace();
-
- DVLOG(3) << __func__
- << ": mojo_from_space = " << mojo_from_space->ToString(true);
-
- // Matrix will be null if transformation from object space to mojo space is
- // not invertible, log & bail out in that case.
- if (!mojo_from_space || !mojo_from_space->IsInvertible()) {
- exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
- kNonInvertibleMatrix);
- return ScriptPromise();
- }
-
- auto space_from_mojo = mojo_from_space->Inverse();
+ auto mojo_from_anchor = mojo_from_offset_space * offset_space_from_anchor;
DVLOG(3) << __func__
- << ": space_from_mojo = " << space_from_mojo.ToString(true);
-
- // Transformation from passed in pose to |space|.
- auto mojo_from_initial_pose = initial_pose->TransformMatrix();
- auto space_from_initial_pose = space_from_mojo * mojo_from_initial_pose;
-
- DVLOG(3) << __func__ << ": mojo_from_initial_pose = "
- << mojo_from_initial_pose.ToString(true);
-
- DVLOG(3) << __func__ << ": space_from_initial_pose = "
- << space_from_initial_pose.ToString(true);
+ << ": mojo_from_anchor = " << mojo_from_anchor.ToString(true);
TransformationMatrix::DecomposedType decomposed;
- if (!space_from_initial_pose.Decompose(decomposed)) {
+ if (!mojo_from_anchor.Decompose(decomposed)) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kUnableToDecomposeMatrix);
return ScriptPromise();
@@ -624,9 +600,12 @@ ScriptPromise XRSession::CreateAnchor(ScriptState* script_state,
<< ": pose_ptr->orientation = " << pose_ptr->orientation.ToString()
<< ", pose_ptr->position = " << pose_ptr->position.ToString();
- if (plane) {
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+ ScriptPromise promise = resolver->Promise();
+
+ if (plane_id) {
xr_->xrEnvironmentProviderRemote()->CreatePlaneAnchor(
- std::move(pose_ptr), plane->id(),
+ std::move(pose_ptr), *plane_id,
WTF::Bind(&XRSession::OnCreateAnchorResult, WrapPersistent(this),
WrapPersistent(resolver)));
} else {
@@ -640,15 +619,9 @@ ScriptPromise XRSession::CreateAnchor(ScriptState* script_state,
return promise;
}
-ScriptPromise XRSession::createAnchor(ScriptState* script_state,
- XRRigidTransform* initial_pose,
- XRSpace* space,
- ExceptionState& exception_state) {
- return CreateAnchor(script_state, initial_pose, space, nullptr,
- exception_state);
-}
-
int XRSession::requestAnimationFrame(V8XRFrameRequestCallback* callback) {
+ DVLOG(3) << __func__;
+
TRACE_EVENT0("gpu", __func__);
// Don't allow any new frame requests once the session is ended.
if (ended_)
@@ -664,7 +637,7 @@ void XRSession::cancelAnimationFrame(int id) {
}
XRInputSourceArray* XRSession::inputSources() const {
- Document* doc = To<Document>(GetExecutionContext());
+ Document* doc = Document::From(GetExecutionContext());
if (!did_log_getInputSources_ && doc) {
ukm::builders::XR_WebXR(xr_->GetSourceId())
.SetDidGetXRInputSources(1)
@@ -675,50 +648,6 @@ XRInputSourceArray* XRSession::inputSources() const {
return input_sources_;
}
-ScriptPromise XRSession::requestHitTest(ScriptState* script_state,
- XRRay* ray,
- XRSpace* space,
- ExceptionState& exception_state) {
- DVLOG(2) << __func__;
-
- if (ended_) {
- exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
- kSessionEnded);
- return ScriptPromise();
- }
-
- if (!space) {
- exception_state.ThrowTypeError(kNoSpaceSpecified);
- return ScriptPromise();
- }
-
- // Reject the promise if device doesn't support the hit-test API.
- if (!xr_->xrEnvironmentProviderRemote()) {
- exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
- kHitTestNotSupported);
- return ScriptPromise();
- }
-
- device::mojom::blink::XRRayPtr ray_mojo = device::mojom::blink::XRRay::New();
-
- ray_mojo->origin =
- FloatPoint3D(ray->origin()->x(), ray->origin()->y(), ray->origin()->z());
-
- ray_mojo->direction = {ray->direction()->x(), ray->direction()->y(),
- ray->direction()->z()};
-
- auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
- ScriptPromise promise = resolver->Promise();
-
- xr_->xrEnvironmentProviderRemote()->RequestHitTest(
- std::move(ray_mojo),
- WTF::Bind(&XRSession::OnHitTestResults, WrapPersistent(this),
- WrapPersistent(resolver)));
- hit_test_promises_.insert(resolver);
-
- return promise;
-}
-
ScriptPromise XRSession::requestHitTestSource(
ScriptState* script_state,
XRHitTestOptionsInit* options_init,
@@ -726,6 +655,18 @@ ScriptPromise XRSession::requestHitTestSource(
DVLOG(2) << __func__;
DCHECK(options_init);
+ if (!IsFeatureEnabled(device::mojom::XRSessionFeature::HIT_TEST)) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
+ kHitTestFeatureNotSupported);
+ return {};
+ }
+
+ if (ended_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ kSessionEnded);
+ return {};
+ }
+
// 1. Grab the native origin from the passed in XRSpace.
base::Optional<XRNativeOriginInformation> maybe_native_origin =
options_init && options_init->hasSpace()
@@ -741,13 +682,13 @@ ScriptPromise XRSession::requestHitTestSource(
// 2. Convert the XRRay to be expressed in terms of passed in XRSpace. This
// should only matter for spaces whose transforms are not fully known on the
// device (for example any space containing origin-offset).
- TransformationMatrix origin_from_space =
- options_init->space()
- ->OriginOffsetMatrix(); // Null checks not needed since native origin
- // wouldn't be set if options_init or space()
- // were null.
+ // Null checks not needed since native origin wouldn't be set if options_init
+ // or space() were null.
+ TransformationMatrix native_from_offset =
+ options_init->space()->NativeFromOffsetMatrix();
- if (options_init->hasEntityTypes() && options_init->entityTypes().IsEmpty()) {
+ if (RuntimeEnabledFeatures::WebXRHitTestEntityTypesEnabled() &&
+ options_init->hasEntityTypes() && options_init->entityTypes().IsEmpty()) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kEntityTypesNotSpecified);
return {};
@@ -756,7 +697,7 @@ ScriptPromise XRSession::requestHitTestSource(
auto entity_types = GetEntityTypesForHitTest(options_init);
DVLOG(3) << __func__
- << ": origin_from_space = " << origin_from_space.ToString(true);
+ << ": native_from_offset = " << native_from_offset.ToString(true);
// Transformation from passed in pose to |space|.
@@ -764,7 +705,7 @@ ScriptPromise XRSession::requestHitTestSource(
? options_init->offsetRay()
: MakeGarbageCollected<XRRay>();
auto space_from_ray = offsetRay->RawMatrix();
- auto origin_from_ray = origin_from_space * space_from_ray;
+ auto origin_from_ray = native_from_offset * space_from_ray;
DVLOG(3) << __func__
<< ": space_from_ray = " << space_from_ray.ToString(true);
@@ -803,7 +744,20 @@ ScriptPromise XRSession::requestHitTestSourceForTransientInput(
DVLOG(2) << __func__;
DCHECK(options_init);
- if (options_init->hasEntityTypes() && options_init->entityTypes().IsEmpty()) {
+ if (!IsFeatureEnabled(device::mojom::XRSessionFeature::HIT_TEST)) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
+ kHitTestFeatureNotSupported);
+ return {};
+ }
+
+ if (ended_) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ kSessionEnded);
+ return {};
+ }
+
+ if (RuntimeEnabledFeatures::WebXRHitTestEntityTypesEnabled() &&
+ options_init->hasEntityTypes() && options_init->entityTypes().IsEmpty()) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kEntityTypesNotSpecified);
return {};
@@ -834,26 +788,6 @@ ScriptPromise XRSession::requestHitTestSourceForTransientInput(
return promise;
}
-void XRSession::OnHitTestResults(
- ScriptPromiseResolver* resolver,
- base::Optional<Vector<device::mojom::blink::XRHitResultPtr>> results) {
- DCHECK(hit_test_promises_.Contains(resolver));
- hit_test_promises_.erase(resolver);
-
- if (!results) {
- resolver->Reject();
- return;
- }
-
- HeapVector<Member<XRHitResult>> hit_results;
- for (const auto& mojom_result : results.value()) {
- XRHitResult* hit_result = MakeGarbageCollected<XRHitResult>(
- TransformationMatrix(mojom_result->hit_matrix.matrix()));
- hit_results.push_back(hit_result);
- }
- resolver->Resolve(hit_results);
-}
-
void XRSession::OnSubscribeToHitTestResult(
ScriptPromiseResolver* resolver,
device::mojom::SubscribeToHitTestResult result,
@@ -911,11 +845,13 @@ void XRSession::OnCreateAnchorResult(ScriptPromiseResolver* resolver,
DCHECK(create_anchor_promises_.Contains(resolver));
create_anchor_promises_.erase(resolver);
- XRAnchor* anchor = MakeGarbageCollected<XRAnchor>(id, this);
-
- anchor_ids_to_anchors_.insert(id, anchor);
-
- resolver->Resolve(anchor);
+ if (result == device::mojom::CreateAnchorResult::SUCCESS) {
+ // Anchor was created successfully on the device. Subsequent frame update
+ // must contain newly created anchor data.
+ newly_created_anchor_ids_to_resolvers_.insert(id, resolver);
+ } else {
+ resolver->Reject();
+ }
}
void XRSession::OnEnvironmentProviderCreated() {
@@ -934,13 +870,6 @@ void XRSession::EnsureEnvironmentErrorHandler() {
}
void XRSession::OnEnvironmentProviderError() {
- HeapHashSet<Member<ScriptPromiseResolver>> hit_test_promises;
- hit_test_promises_.swap(hit_test_promises);
- for (ScriptPromiseResolver* resolver : hit_test_promises) {
- resolver->Reject(MakeGarbageCollected<DOMException>(
- DOMExceptionCode::kInvalidStateError, kDeviceDisconnected));
- }
-
HeapHashSet<Member<ScriptPromiseResolver>> create_anchor_promises;
create_anchor_promises_.swap(create_anchor_promises);
for (ScriptPromiseResolver* resolver : create_anchor_promises) {
@@ -957,7 +886,7 @@ void XRSession::OnEnvironmentProviderError() {
}
void XRSession::ProcessAnchorsData(
- const device::mojom::blink::XRAnchorsDataPtr& tracked_anchors_data,
+ const device::mojom::blink::XRAnchorsData* tracked_anchors_data,
double timestamp) {
TRACE_EVENT0("xr", __func__);
@@ -985,25 +914,38 @@ void XRSession::ProcessAnchorsData(
HeapHashMap<uint64_t, Member<XRAnchor>> updated_anchors;
- // First, process all planes that had their information updated (new planes
+ // First, process all anchors that had their information updated (new anchors
// are also processed here).
for (const auto& anchor : tracked_anchors_data->updated_anchors_data) {
+ DCHECK(anchor);
+
auto it = anchor_ids_to_anchors_.find(anchor->id);
if (it != anchor_ids_to_anchors_.end()) {
updated_anchors.insert(anchor->id, it->value);
- it->value->Update(anchor, timestamp);
+ it->value->Update(*anchor);
} else {
- updated_anchors.insert(
- anchor->id,
- MakeGarbageCollected<XRAnchor>(anchor->id, this, anchor, timestamp));
+ auto resolver_it =
+ newly_created_anchor_ids_to_resolvers_.find(anchor->id);
+ if (resolver_it == newly_created_anchor_ids_to_resolvers_.end()) {
+ DCHECK(false)
+ << "Newly created anchor must have a corresponding resolver!";
+ continue;
+ }
+
+ XRAnchor* xr_anchor =
+ MakeGarbageCollected<XRAnchor>(anchor->id, this, *anchor);
+ resolver_it->value->Resolve(xr_anchor);
+ newly_created_anchor_ids_to_resolvers_.erase(resolver_it);
+
+ updated_anchors.insert(anchor->id, xr_anchor);
}
}
- // Then, copy over the planes that were not updated but are still present.
+ // Then, copy over the anchors that were not updated but are still present.
for (const auto& anchor_id : tracked_anchors_data->all_anchors_ids) {
auto it_updated = updated_anchors.find(anchor_id);
- // If the plane was already updated, there is nothing to do as it was
+ // If the anchor was already updated, there is nothing to do as it was
// already moved to |updated_anchors|. Otherwise just copy it over as-is.
if (it_updated == updated_anchors.end()) {
auto it = anchor_ids_to_anchors_.find(anchor_id);
@@ -1012,7 +954,16 @@ void XRSession::ProcessAnchorsData(
}
}
+ DVLOG(3) << __func__
+ << ": anchor count before update=" << anchor_ids_to_anchors_.size()
+ << ", after update=" << updated_anchors.size();
+
anchor_ids_to_anchors_.swap(updated_anchors);
+
+ DCHECK(newly_created_anchor_ids_to_resolvers_.IsEmpty())
+ << "All newly created anchors should be updated in subsequent frame, got "
+ << newly_created_anchor_ids_to_resolvers_.size()
+ << " anchors that have not been updated";
}
void XRSession::CleanUpUnusedHitTestSources() {
@@ -1020,10 +971,15 @@ void XRSession::CleanUpUnusedHitTestSources() {
CleanUpUnusedHitTestSourcesHelper(
&hit_test_source_ids_to_transient_input_hit_test_sources_);
+
+ DVLOG(3) << __func__ << ": Number of active hit test sources: "
+ << hit_test_source_ids_to_hit_test_sources_.size()
+ << ", number of active hit test sources for transient input: "
+ << hit_test_source_ids_to_transient_input_hit_test_sources_.size();
}
void XRSession::ProcessHitTestData(
- const device::mojom::blink::XRHitTestSubscriptionResultsDataPtr&
+ const device::mojom::blink::XRHitTestSubscriptionResultsData*
hit_test_subscriptions_data) {
DVLOG(2) << __func__;
@@ -1033,6 +989,11 @@ void XRSession::ProcessHitTestData(
// We have received hit test results for hit test subscriptions - process
// each result and notify its corresponding hit test source about new
// results for the current frame.
+ DVLOG(3) << __func__ << "hit_test_subscriptions_data->results.size()="
+ << hit_test_subscriptions_data->results.size() << ", "
+ << "hit_test_subscriptions_data->transient_input_results.size()="
+ << hit_test_subscriptions_data->transient_input_results.size();
+
for (auto& hit_test_subscription_data :
hit_test_subscriptions_data->results) {
auto it = hit_test_source_ids_to_hit_test_sources_.find(
@@ -1054,6 +1015,8 @@ void XRSession::ProcessHitTestData(
}
}
} else {
+ DVLOG(3) << __func__ << ": hit_test_subscriptions_data unavailable";
+
// We have not received hit test results for any of the hit test
// subscriptions in the current frame - clean up the results on all hit test
// source objects.
@@ -1385,8 +1348,8 @@ void XRSession::UpdatePresentationFrameState(
int16_t frame_id,
bool emulated_position) {
TRACE_EVENT0("gpu", __func__);
- DVLOG(2) << __func__ << " : frame_data valid? "
- << (frame_data ? true : false);
+ DVLOG(2) << __func__ << " : frame_data valid? " << (frame_data ? true : false)
+ << ", emulated_position=" << emulated_position;
// Don't process any outstanding frames once the session is ended.
if (ended_)
return;
@@ -1405,6 +1368,12 @@ void XRSession::UpdatePresentationFrameState(
OnInputStateChangeInternal(frame_id, input_states);
+ // World understanding includes hit testing for transient input sources, and
+ // these sources may have been hidden when touching DOM Overlay content
+ // that's inside cross-origin iframes. Since hit test subscriptions only
+ // happen for existing input_sources_ entries, these touches will not
+ // generate hit test results. For this to work, this step must happen
+ // after OnInputStateChangeInternal which updated input sources.
UpdateWorldUnderstandingStateForFrame(timestamp, frame_data);
// If this session uses input eventing, XR select events are handled via
@@ -1412,6 +1381,8 @@ void XRSession::UpdatePresentationFrameState(
if (!uses_input_eventing_) {
ProcessInputSourceEvents(input_states);
}
+ } else {
+ UpdateWorldUnderstandingStateForFrame(timestamp, frame_data);
}
}
@@ -1421,13 +1392,16 @@ void XRSession::UpdateWorldUnderstandingStateForFrame(
// Update objects that might change on per-frame basis.
if (frame_data) {
world_information_->ProcessPlaneInformation(
- frame_data->detected_planes_data, timestamp);
- ProcessAnchorsData(frame_data->anchors_data, timestamp);
- ProcessHitTestData(frame_data->hit_test_subscription_results);
+ frame_data->detected_planes_data.get(), timestamp);
+ ProcessAnchorsData(frame_data->anchors_data.get(), timestamp);
+ ProcessHitTestData(frame_data->hit_test_subscription_results.get());
+ world_information_->ProcessLightEstimationData(
+ frame_data->light_estimation_data.get(), timestamp);
} else {
world_information_->ProcessPlaneInformation(nullptr, timestamp);
ProcessAnchorsData(nullptr, timestamp);
ProcessHitTestData(nullptr);
+ world_information_->ProcessLightEstimationData(nullptr, timestamp);
}
}
@@ -1445,7 +1419,8 @@ void XRSession::OnFrame(
double timestamp,
const base::Optional<gpu::MailboxHolder>& output_mailbox_holder) {
TRACE_EVENT0("gpu", __func__);
- DVLOG(2) << __func__;
+ DVLOG(2) << __func__ << ": ended_=" << ended_
+ << ", pending_frame_=" << pending_frame_;
// Don't process any outstanding frames once the session is ended.
if (ended_)
return;
@@ -1461,10 +1436,14 @@ void XRSession::OnFrame(
// session. That would allow tracking with no associated visuals.
XRWebGLLayer* frame_base_layer = render_state_->baseLayer();
if (!frame_base_layer) {
+ DVLOG(2) << __func__ << ": frame_base_layer not present";
+
// If we previously had a frame base layer, we need to still attempt to
// submit a frame back to the runtime, as all "GetFrameData" calls need a
// matching submit.
if (prev_base_layer_) {
+ DVLOG(2) << __func__
+ << ": prev_base_layer_ is valid, submitting frame to it";
prev_base_layer_->OnFrameStart(output_mailbox_holder);
prev_base_layer_->OnFrameEnd();
prev_base_layer_ = nullptr;
@@ -1474,16 +1453,23 @@ void XRSession::OnFrame(
// Don't allow frames to be processed if an inline session doesn't have an
// output canvas.
- if (!immersive() && !render_state_->output_canvas())
+ if (!immersive() && !render_state_->output_canvas()) {
+ DVLOG(2) << __func__
+ << ": frames are not to be processed if an inline session "
+ "doesn't have an output canvas";
return;
+ }
frame_base_layer->OnFrameStart(output_mailbox_holder);
// Don't allow frames to be processed if the session's visibility state is
// "hidden".
if (visibility_state_ == XRVisibilityState::HIDDEN) {
- // If the frame is skipped because of the visibility state, make sure we
- // end the frame anyway.
+ DVLOG(2) << __func__
+ << ": frames to be processed if the session's visibility state "
+ "is \"hidden\"";
+ // If the frame is skipped because of the visibility state,
+ // make sure we end the frame anyway.
frame_base_layer->OnFrameEnd();
return;
}
@@ -1514,7 +1500,7 @@ void XRSession::OnFrame(
}
void XRSession::LogGetPose() const {
- Document* doc = To<Document>(GetExecutionContext());
+ Document* doc = Document::From(GetExecutionContext());
if (!did_log_getViewerPose_ && doc) {
did_log_getViewerPose_ = true;
@@ -1524,7 +1510,7 @@ void XRSession::LogGetPose() const {
}
}
-bool XRSession::CanReportPoses() {
+bool XRSession::CanReportPoses() const {
// The spec has a few requirements for if poses can be reported.
// If we have a session, then user intent is understood. Therefore, (due to
// the way visibility state is updatd), the rest of the steps really just
@@ -1532,21 +1518,25 @@ bool XRSession::CanReportPoses() {
return visibility_state_ == XRVisibilityState::VISIBLE;
}
+base::Optional<TransformationMatrix> XRSession::MojoFromViewer() const {
+ if (!CanReportPoses())
+ return base::nullopt;
+
+ if (!mojo_from_viewer_) {
+ if (sensorless_session_)
+ return TransformationMatrix();
+
+ return base::nullopt;
+ }
+
+ return *mojo_from_viewer_.get();
+}
+
XRFrame* XRSession::CreatePresentationFrame() {
DVLOG(2) << __func__;
XRFrame* presentation_frame =
MakeGarbageCollected<XRFrame>(this, world_information_);
-
- // TODO(https://crbug.com/1004201): Determine if world_information_ should be
- // treated similarly to mojo_from_viewer_.
- if (mojo_from_viewer_ && visibility_state_ != XRVisibilityState::HIDDEN) {
- DVLOG(2) << __func__ << " : mojo_from_viewer_ is set and not hidden,"
- << " updating presentation frame";
-
- presentation_frame->SetMojoFromViewer(*mojo_from_viewer_,
- EmulatedPosition());
- }
return presentation_frame;
}
@@ -1600,23 +1590,50 @@ void XRSession::OnInputStateChangeInternal(
HeapVector<Member<XRInputSource>> removed;
last_frame_id_ = frame_id;
+ DVLOG(2) << __func__ << ": frame_id=" << frame_id
+ << " input_states.size()=" << input_states.size();
// Build up our added array, and update the frame id of any active input
// sources so we can flag the ones that are no longer active.
for (const auto& input_state : input_states) {
+ DVLOG(2) << __func__
+ << ": input_state->source_id=" << input_state->source_id
+ << " input_state->primary_input_pressed="
+ << input_state->primary_input_pressed
+ << " clicked=" << input_state->primary_input_clicked;
+
XRInputSource* stored_input_source =
input_sources_->GetWithSourceId(input_state->source_id);
+ DVLOG(2) << __func__ << ": stored_input_source=" << stored_input_source;
XRInputSource* input_source = XRInputSource::CreateOrUpdateFrom(
stored_input_source, this, input_state);
+ // Input sources should use DOM overlay hit test to check if they intersect
+ // cross-origin content. If that's the case, the input source is set as
+ // invisible, and must not return poses or hit test results.
+ bool hide_input_source = false;
+ if (overlay_element_ && input_state->overlay_pointer_position) {
+ input_source->ProcessOverlayHitTest(overlay_element_, input_state);
+ if (!stored_input_source && !input_source->IsVisible()) {
+ DVLOG(2) << __func__ << ": (new) hidden_input_source";
+ hide_input_source = true;
+ }
+ }
+
// Using pointer equality to determine if the pointer needs to be set.
if (stored_input_source != input_source) {
- input_sources_->SetWithSourceId(input_state->source_id, input_source);
- added.push_back(input_source);
+ DVLOG(2) << __func__ << ": stored_input_source != input_source";
+ if (!hide_input_source) {
+ input_sources_->SetWithSourceId(input_state->source_id, input_source);
+ added.push_back(input_source);
+ DVLOG(2) << __func__ << ": ADDED input_source "
+ << input_state->source_id;
+ }
- // If we previously had a stored_input_source, disconnect it's gamepad
+ // If we previously had a stored_input_source, disconnect its gamepad
// and mark that it was removed.
if (stored_input_source) {
stored_input_source->SetGamepadConnected(false);
+ DVLOG(2) << __func__ << ": REMOVED stored_input_source";
removed.push_back(stored_input_source);
}
}
@@ -1662,8 +1679,10 @@ void XRSession::ProcessInputSourceEvents(
XRInputSource* input_source =
input_sources_->GetWithSourceId(input_state->source_id);
- DCHECK(input_source);
- input_source->UpdateSelectState(input_state);
+ // The input source might not be in input_sources_ if it was created hidden.
+ if (input_source) {
+ input_source->UpdateButtonStates(input_state);
+ }
}
}
@@ -1836,7 +1855,7 @@ bool XRSession::HasPendingActivity() const {
return !callback_collection_->IsEmpty() && !ended_;
}
-void XRSession::Trace(blink::Visitor* visitor) {
+void XRSession::Trace(Visitor* visitor) {
visitor->Trace(xr_);
visitor->Trace(render_state_);
visitor->Trace(world_tracking_state_);
@@ -1846,12 +1865,14 @@ void XRSession::Trace(blink::Visitor* visitor) {
visitor->Trace(input_sources_);
visitor->Trace(resize_observer_);
visitor->Trace(canvas_input_provider_);
+ visitor->Trace(overlay_element_);
+ visitor->Trace(dom_overlay_state_);
visitor->Trace(callback_collection_);
- visitor->Trace(hit_test_promises_);
visitor->Trace(create_anchor_promises_);
visitor->Trace(request_hit_test_source_promises_);
visitor->Trace(reference_spaces_);
visitor->Trace(anchor_ids_to_anchors_);
+ visitor->Trace(newly_created_anchor_ids_to_resolvers_);
visitor->Trace(prev_base_layer_);
visitor->Trace(hit_test_source_ids_to_hit_test_sources_);
visitor->Trace(hit_test_source_ids_to_transient_input_hit_test_sources_);
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 afc3a45bd41..384aa39463a 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_session.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_session.h
@@ -13,6 +13,7 @@
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
+#include "third_party/blink/renderer/core/html/html_element.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"
#include "third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h"
@@ -35,19 +36,17 @@ class HTMLCanvasElement;
class ResizeObserver;
class ScriptPromiseResolver;
class V8XRFrameRequestCallback;
-class XR;
class XRAnchor;
class XRAnchorSet;
class XRCanvasInputProvider;
+class XRDOMOverlayState;
class XRHitTestOptionsInit;
class XRHitTestSource;
-class XRPlane;
-class XRRay;
class XRReferenceSpace;
class XRRenderState;
class XRRenderStateInit;
-class XRRigidTransform;
class XRSpace;
+class XRSystem;
class XRTransientInputHitTestOptionsInit;
class XRTransientInputHitTestSource;
class XRViewData;
@@ -67,7 +66,13 @@ class XRSession final
USING_GARBAGE_COLLECTED_MIXIN(XRSession);
public:
- enum SessionMode { kModeInline = 0, kModeImmersiveVR, kModeImmersiveAR };
+ // Error strings used outside of XRSession:
+ static constexpr char kNoRigidTransformSpecified[] =
+ "No XRRigidTransform specified.";
+ static constexpr char kUnableToRetrieveMatrix[] =
+ "The operation was unable to retrieve a matrix from passed in space and "
+ "could not be completed.";
+ static constexpr char kNoSpaceSpecified[] = "No XRSpace specified.";
enum EnvironmentBlendMode {
kBlendModeOpaque = 0,
@@ -91,23 +96,24 @@ class XRSession final
HashSet<device::mojom::blink::XRSessionFeature> reported_features_;
};
- XRSession(XR* xr,
+ XRSession(XRSystem* xr,
mojo::PendingReceiver<device::mojom::blink::XRSessionClient>
client_receiver,
- SessionMode mode,
+ device::mojom::blink::XRSessionMode mode,
EnvironmentBlendMode environment_blend_mode,
bool uses_input_eventing,
bool sensorless_session,
XRSessionFeatureSet enabled_features);
~XRSession() override = default;
- XR* xr() const { return xr_; }
+ XRSystem* xr() const { return xr_; }
const String& environmentBlendMode() const { return blend_mode_string_; }
+ XRDOMOverlayState* domOverlayState() const { return dom_overlay_state_; }
const String visibilityState() const;
XRRenderState* renderState() const { return render_state_; }
XRWorldTrackingState* worldTrackingState() { return world_tracking_state_; }
XRSpace* viewerSpace() const;
- XRAnchorSet* trackedAnchors() const;
+ XRAnchorSet* TrackedAnchors() const;
bool immersive() const;
@@ -117,6 +123,9 @@ class XRSession final
DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart, kSelectstart)
DEFINE_ATTRIBUTE_EVENT_LISTENER(selectend, kSelectend)
DEFINE_ATTRIBUTE_EVENT_LISTENER(visibilitychange, kVisibilitychange)
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(squeeze, kSqueeze)
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(squeezestart, kSqueezestart)
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(squeezeend, kSqueezeend)
void updateRenderState(XRRenderStateInit* render_state_init,
ExceptionState& exception_state);
@@ -127,18 +136,20 @@ class XRSession final
const String& type,
ExceptionState&);
- // IDL-exposed
- ScriptPromise createAnchor(ScriptState* script_state,
- XRRigidTransform* initial_pose,
- XRSpace* space,
- ExceptionState& exception_state);
-
- // helper, not IDL-exposed
- ScriptPromise CreateAnchor(ScriptState* script_state,
- XRRigidTransform* pose,
- XRSpace* space,
- XRPlane* plane,
- ExceptionState& exception_state);
+ // Helper, not IDL-exposed
+ // |offset_space_from_anchor| is a matrix describing transform from offset
+ // space to the initial anchor's position.
+ // |mojo_from_offset_space| can be obtained from XRSpace and describes
+ // transform from mojo space to the offset space in which the anchor pose is
+ // expressed.
+ // |plane_id| - optional, id of the plane to which the anchor should be
+ // attached.
+ ScriptPromise CreateAnchor(
+ ScriptState* script_state,
+ const blink::TransformationMatrix& offset_space_from_anchor,
+ const blink::TransformationMatrix& mojo_from_offset_space,
+ base::Optional<uint64_t> plane_id,
+ ExceptionState& exception_state);
int requestAnimationFrame(V8XRFrameRequestCallback* callback);
void cancelAnimationFrame(int id);
@@ -153,11 +164,6 @@ class XRSession final
XRTransientInputHitTestOptionsInit* options_init,
ExceptionState& exception_state);
- ScriptPromise requestHitTest(ScriptState* script_state,
- XRRay* ray,
- XRSpace* space,
- ExceptionState&);
-
// Called by JavaScript to manually end the session.
ScriptPromise end(ScriptState* script_state, ExceptionState&);
@@ -184,6 +190,8 @@ class XRSession final
DoubleSize OutputCanvasSize() const;
void DetachOutputCanvas(HTMLCanvasElement* output_canvas);
+ void SetDOMOverlayElement(Element* element);
+
void LogGetPose() const;
// EventTarget overrides.
@@ -257,12 +265,13 @@ class XRSession final
bool UsesInputEventing() { return uses_input_eventing_; }
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
// ScriptWrappable
bool HasPendingActivity() const override;
- bool CanReportPoses();
+ bool CanReportPoses() const;
+ base::Optional<TransformationMatrix> MojoFromViewer() const;
// Creates presentation frame based on current state of the session.
// State currently used in XRFrame creation is mojo_from_viewer_ and
@@ -329,10 +338,6 @@ class XRSession final
void UpdateVisibilityState();
- void OnHitTestResults(
- ScriptPromiseResolver* resolver,
- base::Optional<Vector<device::mojom::blink::XRHitResultPtr>> results);
-
void OnSubscribeToHitTestResult(
ScriptPromiseResolver* resolver,
device::mojom::SubscribeToHitTestResult result,
@@ -351,19 +356,19 @@ class XRSession final
void OnEnvironmentProviderError();
void ProcessAnchorsData(
- const device::mojom::blink::XRAnchorsDataPtr& tracked_anchors_data,
+ const device::mojom::blink::XRAnchorsData* tracked_anchors_data,
double timestamp);
void CleanUpUnusedHitTestSources();
void ProcessHitTestData(
- const device::mojom::blink::XRHitTestSubscriptionResultsDataPtr&
+ const device::mojom::blink::XRHitTestSubscriptionResultsData*
hit_test_data);
void HandleShutdown();
- const Member<XR> xr_;
- const SessionMode mode_;
+ const Member<XRSystem> xr_;
+ const device::mojom::blink::XRSessionMode mode_;
const bool environment_integration_;
String blend_mode_string_;
XRVisibilityState device_visibility_state_ = XRVisibilityState::VISIBLE;
@@ -391,6 +396,17 @@ class XRSession final
bool is_tracked_anchors_null_ = true;
HeapHashMap<uint64_t, Member<XRAnchor>> anchor_ids_to_anchors_;
+ // Set of promises returned from CreateAnchor that are still in-flight to the
+ // device. Once the device calls us back with the newly created anchor id, the
+ // resolver will be moved to |newly_created_anchor_ids_to_resolvers_|.
+ HeapHashSet<Member<ScriptPromiseResolver>> create_anchor_promises_;
+ // Promises for which anchors have already been created on the device side but
+ // have not yet been resolved as their data is not yet available to blink.
+ // Next frame update should contain the necessary data - the promise will be
+ // resolved then.
+ HeapHashMap<uint64_t, Member<ScriptPromiseResolver>>
+ newly_created_anchor_ids_to_resolvers_;
+
// Mapping of hit test source ids (aka hit test subscription ids) to hit test
// sources. Hit test source has to be stored via weak member - JavaScript side
// will communicate that it's no longer interested in the subscription by
@@ -407,10 +423,9 @@ class XRSession final
Member<XRWebGLLayer> prev_base_layer_;
Member<ResizeObserver> resize_observer_;
Member<XRCanvasInputProvider> canvas_input_provider_;
+ Member<Element> overlay_element_;
+ Member<XRDOMOverlayState> dom_overlay_state_;
bool environment_error_handler_subscribed_ = false;
- HeapHashSet<Member<ScriptPromiseResolver>> hit_test_promises_;
- // Set of promises returned from CreateAnchor that are still in-flight.
- HeapHashSet<Member<ScriptPromiseResolver>> create_anchor_promises_;
// Set of promises returned from requestHitTestSource and
// requestHitTestSourceForTransientInput that are still in-flight.
HeapHashSet<Member<ScriptPromiseResolver>> request_hit_test_source_promises_;
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 cb85a643d06..18192fb37a0 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_session.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_session.idl
@@ -32,6 +32,7 @@ enum XRVisibilityState {
readonly attribute XRVisibilityState visibilityState;
[SameObject] readonly attribute XRRenderState renderState;
[MeasureAs=XRSessionGetInputSources, SameObject] readonly attribute XRInputSourceArray inputSources;
+ [SameObject] readonly attribute XRDOMOverlayState domOverlayState;
attribute EventHandler onend;
attribute EventHandler onselect;
@@ -39,28 +40,26 @@ enum XRVisibilityState {
attribute EventHandler onselectstart;
attribute EventHandler onselectend;
attribute EventHandler onvisibilitychange;
+ attribute EventHandler onsqueeze;
+ attribute EventHandler onsqueezestart;
+ attribute EventHandler onsqueezeend;
- [RaisesException] void updateRenderState(optional XRRenderStateInit init);
+ [RaisesException] void updateRenderState(optional XRRenderStateInit init = {});
[CallWith=ScriptState, RaisesException] Promise<XRReferenceSpace> requestReferenceSpace(XRReferenceSpaceType type);
long requestAnimationFrame(XRFrameRequestCallback callback);
void cancelAnimationFrame(long handle);
- [RuntimeEnabled=WebXRHitTest, CallWith=ScriptState, RaisesException] Promise<FrozenArray<XRHitResult>> requestHitTest(XRRay ray, XRSpace space);
-
// https://github.com/immersive-web/real-world-geometry/blob/master/plane-detection-explainer.md
- [RuntimeEnabled=WebXRPlaneDetection] readonly attribute XRWorldTrackingState worldTrackingState;
- [RuntimeEnabled=WebXRPlaneDetection, RaisesException] void updateWorldTrackingState(optional XRWorldTrackingStateInit state);
-
- [RuntimeEnabled=WebXRAnchors] readonly attribute XRAnchorSet trackedAnchors;
- [RuntimeEnabled=WebXRAnchors, CallWith=ScriptState, RaisesException] Promise<XRAnchor> createAnchor(XRRigidTransform initial_pose, XRSpace space);
+ [RuntimeEnabled=WebXRIncubations] readonly attribute XRWorldTrackingState worldTrackingState;
+ [RuntimeEnabled=WebXRIncubations, RaisesException] void updateWorldTrackingState(optional XRWorldTrackingStateInit state = {});
[CallWith=ScriptState, Measure, RaisesException] Promise<void> end();
// https://github.com/immersive-web/hit-test/blob/master/hit-testing-explainer.md
- [RuntimeEnabled=WebXRHitTest, CallWith=ScriptState, RaisesException]
+ [RuntimeEnabled=WebXRHitTest, CallWith=ScriptState, MeasureAs=XRSessionRequestHitTestSource, RaisesException]
Promise<XRHitTestSource> requestHitTestSource(XRHitTestOptionsInit options);
- [RuntimeEnabled=WebXRHitTest, CallWith=ScriptState, RaisesException]
+ [RuntimeEnabled=WebXRHitTest, CallWith=ScriptState, MeasureAs=XRSessionRequestHitTestSourceForTransientInput, RaisesException]
Promise<XRTransientInputHitTestSource> requestHitTestSourceForTransientInput(XRTransientInputHitTestOptionsInit options);
};
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 8a683ff3768..0fb73b1684b 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
@@ -12,6 +12,13 @@ XRSessionEvent::XRSessionEvent(const AtomicString& type, XRSession* session)
: Event(type, Bubbles::kNo, Cancelable::kYes), session_(session) {}
XRSessionEvent::XRSessionEvent(const AtomicString& type,
+ XRSession* session,
+ Event::Bubbles bubbles,
+ Event::Cancelable cancelable,
+ Event::ComposedMode composed)
+ : Event(type, bubbles, cancelable, composed), session_(session) {}
+
+XRSessionEvent::XRSessionEvent(const AtomicString& type,
const XRSessionEventInit* initializer)
: Event(type, initializer) {
if (initializer->hasSession())
@@ -24,7 +31,7 @@ const AtomicString& XRSessionEvent::InterfaceName() const {
return event_interface_names::kXRSessionEvent;
}
-void XRSessionEvent::Trace(blink::Visitor* visitor) {
+void XRSessionEvent::Trace(Visitor* visitor) {
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 fba431740bc..dd8d1460ef2 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
@@ -5,9 +5,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_SESSION_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_SESSION_EVENT_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_xr_session_event_init.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/xr/xr_session.h"
-#include "third_party/blink/renderer/modules/xr/xr_session_event_init.h"
namespace blink {
@@ -29,6 +29,11 @@ class XRSessionEvent final : public Event {
XRSessionEvent();
XRSessionEvent(const AtomicString& type, XRSession*);
+ XRSessionEvent(const AtomicString& type,
+ XRSession*,
+ Event::Bubbles,
+ Event::Cancelable,
+ Event::ComposedMode);
XRSessionEvent(const AtomicString& type, const XRSessionEventInit*);
~XRSessionEvent() override;
@@ -36,7 +41,7 @@ class XRSessionEvent final : public Event {
const AtomicString& InterfaceName() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
Member<XRSession> session_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_session_event.idl b/chromium/third_party/blink/renderer/modules/xr/xr_session_event.idl
index 0079794480d..b26e8f1ea46 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_session_event.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_session_event.idl
@@ -6,8 +6,8 @@
[
SecureContext,
Exposed=Window,
- RuntimeEnabled=WebXR,
- Constructor(DOMString type, XRSessionEventInit eventInitDict)
+ RuntimeEnabled=WebXR
] interface XRSessionEvent : Event {
+ constructor(DOMString type, XRSessionEventInit eventInitDict);
[SameObject] readonly attribute XRSession session;
};
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_session_init.idl b/chromium/third_party/blink/renderer/modules/xr/xr_session_init.idl
index 5de946516c2..11d315b58ae 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_session_init.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_session_init.idl
@@ -6,4 +6,5 @@
dictionary XRSessionInit {
sequence<any> requiredFeatures;
sequence<any> optionalFeatures;
+ XRDOMOverlayInit domOverlay;
};
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 446ccb0a515..03e89cdde8a 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) 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 e94164996bc..5f61ac748f7 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_space.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_space.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/modules/xr/xr_space.h"
+#include "base/stl_util.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/xr/xr_input_source.h"
#include "third_party/blink/renderer/modules/xr/xr_pose.h"
@@ -16,94 +17,97 @@ XRSpace::XRSpace(XRSession* session) : session_(session) {}
XRSpace::~XRSpace() = default;
-std::unique_ptr<TransformationMatrix> XRSpace::MojoFromSpace() {
- // The base XRSpace does not have any relevant information, so can't determine
- // a transform here.
- return nullptr;
-}
-
-std::unique_ptr<TransformationMatrix> XRSpace::DefaultViewerPose() {
- return nullptr;
-}
+std::unique_ptr<TransformationMatrix> XRSpace::NativeFromViewer(
+ const TransformationMatrix* mojo_from_viewer) {
+ if (!mojo_from_viewer)
+ return nullptr;
-std::unique_ptr<TransformationMatrix> XRSpace::SpaceFromMojo(
- const TransformationMatrix& mojo_from_viewer) {
- return nullptr;
-}
+ std::unique_ptr<TransformationMatrix> native_from_mojo = NativeFromMojo();
+ if (!native_from_mojo)
+ return nullptr;
-std::unique_ptr<TransformationMatrix> XRSpace::SpaceFromViewer(
- const TransformationMatrix& mojo_from_viewer) {
- return nullptr;
-}
+ native_from_mojo->Multiply(*mojo_from_viewer);
-std::unique_ptr<TransformationMatrix> XRSpace::SpaceFromInputForViewer(
- const TransformationMatrix& mojo_from_input,
- const TransformationMatrix& mojo_from_viewer) {
- return nullptr;
+ // This is now native_from_viewer
+ return native_from_mojo;
+ ;
}
-TransformationMatrix XRSpace::OriginOffsetMatrix() {
+TransformationMatrix XRSpace::NativeFromOffsetMatrix() {
TransformationMatrix identity;
return identity;
}
-TransformationMatrix XRSpace::InverseOriginOffsetMatrix() {
+TransformationMatrix XRSpace::OffsetFromNativeMatrix() {
TransformationMatrix identity;
return identity;
}
-XRPose* XRSpace::getPose(XRSpace* other_space,
- const TransformationMatrix* base_pose_matrix) {
- std::unique_ptr<TransformationMatrix> mojo_from_space = MojoFromSpace();
- if (!mojo_from_space) {
+std::unique_ptr<TransformationMatrix> XRSpace::MojoFromOffsetMatrix() {
+ auto maybe_mojo_from_native = MojoFromNative();
+ if (!maybe_mojo_from_native) {
return nullptr;
}
- std::unique_ptr<TransformationMatrix> mojo_from_other =
- other_space->MojoFromSpace();
- if (!mojo_from_other) {
+ // Modifies maybe_mojo_from_native - it becomes mojo_from_offset_matrix.
+ // Saves a heap allocation since there is no need to create a new unique_ptr.
+ maybe_mojo_from_native->Multiply(NativeFromOffsetMatrix());
+ return maybe_mojo_from_native;
+}
+
+std::unique_ptr<TransformationMatrix> XRSpace::TryInvert(
+ std::unique_ptr<TransformationMatrix> matrix) {
+ if (!matrix)
+ return nullptr;
+
+ DCHECK(matrix->IsInvertible());
+ return std::make_unique<TransformationMatrix>(matrix->Inverse());
+}
+
+bool XRSpace::EmulatedPosition() const {
+ return session()->EmulatedPosition();
+}
+
+XRPose* XRSpace::getPose(XRSpace* other_space) {
+ // Named mojo_from_offset because that is what we will leave it as, though it
+ // starts mojo_from_native.
+ std::unique_ptr<TransformationMatrix> mojo_from_offset = MojoFromNative();
+ if (!mojo_from_offset) {
return nullptr;
}
- // Rigid transforms should always be invertible.
- DCHECK(mojo_from_other->IsInvertible());
- TransformationMatrix other_from_mojo = mojo_from_other->Inverse();
+ // Add any origin offset now.
+ mojo_from_offset->Multiply(NativeFromOffsetMatrix());
+
+ std::unique_ptr<TransformationMatrix> other_from_mojo =
+ other_space->NativeFromMojo();
+ if (!other_from_mojo)
+ return nullptr;
+
+ // Add any origin offset from the other space now.
+ TransformationMatrix other_offset_from_mojo =
+ other_space->OffsetFromNativeMatrix().Multiply(*other_from_mojo);
// TODO(crbug.com/969133): Update how EmulatedPosition is determined here once
// spec issue https://github.com/immersive-web/webxr/issues/534 has been
// resolved.
- TransformationMatrix other_from_space =
- other_from_mojo.Multiply(*mojo_from_space);
- return MakeGarbageCollected<XRPose>(other_from_space,
- session()->EmulatedPosition());
+ TransformationMatrix other_offset_from_offset =
+ other_offset_from_mojo.Multiply(*mojo_from_offset);
+ return MakeGarbageCollected<XRPose>(
+ other_offset_from_offset,
+ EmulatedPosition() || other_space->EmulatedPosition());
}
-std::unique_ptr<TransformationMatrix>
-XRSpace::SpaceFromViewerWithDefaultAndOffset(
- const TransformationMatrix* mojo_from_viewer) {
- std::unique_ptr<TransformationMatrix> space_from_viewer;
-
- // If we don't have a valid base pose, request the reference space's default
- // viewer pose. Most common when tracking is lost.
- if (mojo_from_viewer) {
- space_from_viewer = SpaceFromViewer(*mojo_from_viewer);
- } else {
- space_from_viewer = DefaultViewerPose();
- }
+std::unique_ptr<TransformationMatrix> XRSpace::OffsetFromViewer() {
+ std::unique_ptr<TransformationMatrix> native_from_viewer =
+ NativeFromViewer(base::OptionalOrNullptr(session()->MojoFromViewer()));
- // Can only update an XRViewerPose's views with an invertible matrix.
- if (!space_from_viewer || !space_from_viewer->IsInvertible()) {
+ if (!native_from_viewer) {
return nullptr;
}
- // Account for any changes made to the reference space's origin offset so that
- // things like teleportation works.
- //
- // This is offset_from_viewer = offset_from_space * space_from_viewer,
- // where offset_from_viewer = inverse(viewer_from_offset).
- // TODO(https://crbug.com/1008466): move originOffset to separate class?
return std::make_unique<TransformationMatrix>(
- InverseOriginOffsetMatrix().Multiply(*space_from_viewer));
+ OffsetFromNativeMatrix().Multiply(*native_from_viewer));
}
ExecutionContext* XRSpace::GetExecutionContext() const {
@@ -118,7 +122,7 @@ base::Optional<XRNativeOriginInformation> XRSpace::NativeOrigin() const {
return base::nullopt;
}
-void XRSpace::Trace(blink::Visitor* visitor) {
+void XRSpace::Trace(Visitor* visitor) {
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 1ea887c709e..889718800e0 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_space.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_space.h
@@ -31,59 +31,65 @@ class XRSpace : public EventTargetWithInlineData {
public:
~XRSpace() override;
- // Gets a default viewer pose appropriate for this space. This is an identity
- // for viewer space, null for everything else.
- virtual std::unique_ptr<TransformationMatrix> DefaultViewerPose();
-
- // Gets the pose of this space's origin in mojo space. This is a transform
- // that maps from this space to mojo space (aka device space). Unless noted
- // otherwise, all data returned over vr_service.mojom interfaces is expressed
- // in mojo space coordinates. Returns nullptr if computing a transform is not
- // possible.
- virtual std::unique_ptr<TransformationMatrix> MojoFromSpace();
-
- // Gets the pose of the mojo origin in this reference space, corresponding
- // to a transform from mojo coordinates to reference space coordinates.
- virtual std::unique_ptr<TransformationMatrix> SpaceFromMojo(
- const TransformationMatrix& mojo_from_viewer);
-
- // Gets the viewer pose in this space, corresponding to a transform from
- // viewer coordinates to this space's coordinates. (The position elements of
- // the transformation matrix are the viewer's location in this space's
- // coordinates.)
- virtual std::unique_ptr<TransformationMatrix> SpaceFromViewer(
- const TransformationMatrix& mojo_from_viewer);
-
- // Gets an input pose in this space. This requires the viewer pose as
- // an additional input since a "viewer" space needs to transform the
- // input pose to headset-relative coordinates.
- virtual std::unique_ptr<TransformationMatrix> SpaceFromInputForViewer(
- const TransformationMatrix& mojo_from_input,
- const TransformationMatrix& mojo_from_viewer);
-
- virtual XRPose* getPose(XRSpace* other_space,
- const TransformationMatrix* mojo_from_viewer);
-
- // Gets the viewer pose in this space, including using an appropriate
- // default pose (i.e. if tracking is lost), and applying originOffset
- // as applicable. TODO(https://crbug.com/1008466): consider moving
- // the originOffset handling to a separate class?
- std::unique_ptr<TransformationMatrix> SpaceFromViewerWithDefaultAndOffset(
+ // Gets the pose of this space's native origin in mojo space. This transform
+ // maps from this space's native origin to mojo space (aka device space).
+ // Unless noted otherwise, all data returned over vr_service.mojom interfaces
+ // is expressed in mojo space coordinates.
+ // Returns nullptr if computing a transform is not possible.
+ virtual std::unique_ptr<TransformationMatrix> MojoFromNative() = 0;
+
+ // Convenience method to try to get the inverse of the above. This will return
+ // the pose of the mojo origin in this space's native origin.
+ // Returns nullptr if computing a transform is not possible.
+ virtual std::unique_ptr<TransformationMatrix> NativeFromMojo() = 0;
+
+ // Gets the viewer pose in the native coordinates of this space, corresponding
+ // to a transform from viewer coordinates to this space's native coordinates.
+ // (The position elements of the transformation matrix are the viewer's
+ // location in this space's coordinates.)
+ // Prefer this helper method over querying NativeFromMojo and multiplying
+ // on the calling side, as this allows the viewer space to return identity
+ // instead of something near to, but not quite, identity.
+ // Returns nullptr if computing a transform is not possible.
+ virtual std::unique_ptr<TransformationMatrix> NativeFromViewer(
const TransformationMatrix* mojo_from_viewer);
+ // Convenience method for calling NativeFromViewer with the current
+ // MojoFromViewer of the session associated with this space. This also handles
+ // the multiplication of OffsetFromNative onto the result of NativeFromViewer.
+ // Returns nullptr if computing a transform is not possible.
+ std::unique_ptr<TransformationMatrix> OffsetFromViewer();
+
+ // Return origin offset matrix, aka native_origin_from_offset_space.
+ virtual TransformationMatrix NativeFromOffsetMatrix();
+ virtual TransformationMatrix OffsetFromNativeMatrix();
+
+ // Returns transformation from offset space to mojo space. Convenience method,
+ // returns MojoFromNative() * NativeFromOffsetMatrix() or nullptr if computing
+ // a transform is not possible.
+ std::unique_ptr<TransformationMatrix> MojoFromOffsetMatrix();
+
+ // Indicates whether or not the position portion of the native origin of this
+ // space is emulated.
+ virtual bool EmulatedPosition() const;
+
+ // Gets the pose of this space's origin in |other_space|. This is a transform
+ // that maps from this space to the other's space, or in other words:
+ // other_from_this.
+ virtual XRPose* getPose(XRSpace* other_space);
XRSession* session() const { return session_; }
// EventTarget overrides.
ExecutionContext* GetExecutionContext() const override;
const AtomicString& InterfaceName() const override;
- // Return origin offset matrix, aka native_origin_from_offset_space.
- virtual TransformationMatrix OriginOffsetMatrix();
- virtual TransformationMatrix InverseOriginOffsetMatrix();
-
virtual base::Optional<XRNativeOriginInformation> NativeOrigin() const = 0;
- void Trace(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) override;
+
+ protected:
+ std::unique_ptr<TransformationMatrix> TryInvert(
+ std::unique_ptr<TransformationMatrix> matrix);
private:
const Member<XRSession> session_;
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_spherical_harmonics.cc b/chromium/third_party/blink/renderer/modules/xr/xr_spherical_harmonics.cc
new file mode 100644
index 00000000000..7d5ec4600ca
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_spherical_harmonics.cc
@@ -0,0 +1,38 @@
+// 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/xr/xr_spherical_harmonics.h"
+
+#include "device/vr/public/mojom/vr_service.mojom-blink.h"
+#include "third_party/blink/renderer/core/geometry/dom_point_read_only.h"
+
+namespace blink {
+
+XRSphericalHarmonics::XRSphericalHarmonics(
+ const device::mojom::blink::XRSphericalHarmonics& spherical_harmonics) {
+ DCHECK_EQ(spherical_harmonics.coefficients.size(), 9u);
+
+ coefficients_ = DOMFloat32Array::Create(
+ spherical_harmonics.coefficients.data()->components,
+ spherical_harmonics.coefficients.size() *
+ device::RgbTupleF32::kNumComponents);
+
+ orientation_ = DOMPointReadOnly::Create(0, 0, 0, 1);
+}
+
+DOMPointReadOnly* XRSphericalHarmonics::orientation() const {
+ return orientation_.Get();
+}
+
+DOMFloat32Array* XRSphericalHarmonics::coefficients() const {
+ return coefficients_.Get();
+}
+
+void XRSphericalHarmonics::Trace(Visitor* visitor) {
+ visitor->Trace(coefficients_);
+ visitor->Trace(orientation_);
+ ScriptWrappable::Trace(visitor);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_spherical_harmonics.h b/chromium/third_party/blink/renderer/modules/xr/xr_spherical_harmonics.h
new file mode 100644
index 00000000000..de7378ffdfe
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_spherical_harmonics.h
@@ -0,0 +1,35 @@
+// 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_XR_XR_SPHERICAL_HARMONICS_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_SPHERICAL_HARMONICS_H_
+
+#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h"
+#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+
+namespace blink {
+
+class DOMPointReadOnly;
+
+class XRSphericalHarmonics : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+
+ public:
+ XRSphericalHarmonics(
+ const device::mojom::blink::XRSphericalHarmonics& spherical_harmonics);
+
+ DOMPointReadOnly* orientation() const;
+ DOMFloat32Array* coefficients() const;
+
+ void Trace(Visitor* visitor) override;
+
+ private:
+ Member<DOMFloat32Array> coefficients_;
+ Member<DOMPointReadOnly> orientation_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_SPHERICAL_HARMONICS_H_
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_spherical_harmonics.idl b/chromium/third_party/blink/renderer/modules/xr/xr_spherical_harmonics.idl
new file mode 100644
index 00000000000..720ea985d6e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_spherical_harmonics.idl
@@ -0,0 +1,14 @@
+// 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.
+
+[
+ SecureContext,
+ Exposed=Window,
+ RuntimeEnabled=WebXRIncubations
+]
+interface XRSphericalHarmonics {
+ readonly attribute DOMPointReadOnly orientation;
+ readonly attribute Float32Array coefficients;
+};
+
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr.cc b/chromium/third_party/blink/renderer/modules/xr/xr_system.cc
index 0f0a0c792c2..a94164360dc 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_system.cc
@@ -2,20 +2,21 @@
// 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/xr/xr.h"
+#include "third_party/blink/renderer/modules/xr/xr_system.h"
#include <utility>
#include "services/metrics/public/cpp/ukm_builders.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/platform/interface_provider.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_fullscreen_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/dom/element.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
+#include "third_party/blink/renderer/core/fullscreen/scoped_allow_fullscreen.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
@@ -54,8 +55,8 @@ const char kSessionNotSupported[] =
const char kNoDevicesMessage[] = "No XR hardware found.";
const char kImmersiveArModeNotValid[] =
- "Failed to execute '%s' on 'XR': The provided value 'immersive-ar' is not "
- "a valid enum value of type XRSessionMode.";
+ "Failed to execute '%s' on 'XRSystem': The provided value 'immersive-ar' "
+ "is not a valid enum value of type XRSessionMode.";
constexpr device::mojom::XRSessionFeature kDefaultImmersiveVrFeatures[] = {
device::mojom::XRSessionFeature::REF_SPACE_VIEWER,
@@ -71,40 +72,29 @@ constexpr device::mojom::XRSessionFeature kDefaultInlineFeatures[] = {
device::mojom::XRSessionFeature::REF_SPACE_VIEWER,
};
-// Helper method to convert session mode into Mojo options.
-device::mojom::blink::XRSessionOptionsPtr convertModeToMojo(
- XRSession::SessionMode mode) {
- auto session_options = device::mojom::blink::XRSessionOptions::New();
- session_options->immersive = (mode == XRSession::kModeImmersiveVR ||
- mode == XRSession::kModeImmersiveAR);
- session_options->environment_integration =
- mode == XRSession::kModeImmersiveAR;
-
- return session_options;
-}
-
-XRSession::SessionMode stringToSessionMode(const String& mode_string) {
+device::mojom::blink::XRSessionMode stringToSessionMode(
+ const String& mode_string) {
if (mode_string == "inline") {
- return XRSession::kModeInline;
+ return device::mojom::blink::XRSessionMode::kInline;
}
if (mode_string == "immersive-vr") {
- return XRSession::kModeImmersiveVR;
+ return device::mojom::blink::XRSessionMode::kImmersiveVr;
}
if (mode_string == "immersive-ar") {
- return XRSession::kModeImmersiveAR;
+ return device::mojom::blink::XRSessionMode::kImmersiveAr;
}
NOTREACHED(); // Only strings in the enum are allowed by IDL.
- return XRSession::kModeInline;
+ return device::mojom::blink::XRSessionMode::kInline;
}
-const char* SessionModeToString(const XRSession::SessionMode& session_mode) {
- switch (session_mode) {
- case XRSession::SessionMode::kModeInline:
+const char* SessionModeToString(device::mojom::blink::XRSessionMode mode) {
+ switch (mode) {
+ case device::mojom::blink::XRSessionMode::kInline:
return "inline";
- case XRSession::SessionMode::kModeImmersiveVR:
+ case device::mojom::blink::XRSessionMode::kImmersiveVr:
return "immersive-vr";
- case XRSession::SessionMode::kModeImmersiveAR:
+ case device::mojom::blink::XRSessionMode::kImmersiveAr:
return "immersive-ar";
}
@@ -128,16 +118,21 @@ 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::WebXRARDOMOverlayEnabled(doc) &&
- feature_string == "dom-overlay-for-handheld-ar") {
- return device::mojom::XRSessionFeature::DOM_OVERLAY_FOR_HANDHELD_AR;
+ } else if (RuntimeEnabledFeatures::WebXRHitTestEnabled(doc) &&
+ feature_string == "hit-test") {
+ return device::mojom::XRSessionFeature::HIT_TEST;
+ } else if (feature_string == "dom-overlay") {
+ return device::mojom::XRSessionFeature::DOM_OVERLAY;
}
return base::nullopt;
}
bool IsFeatureValidForMode(device::mojom::XRSessionFeature feature,
- XRSession::SessionMode mode) {
+ device::mojom::blink::XRSessionMode mode,
+ XRSessionInit* session_init,
+ ExecutionContext* execution_context,
+ mojom::ConsoleMessageLevel error_level) {
switch (feature) {
case device::mojom::XRSessionFeature::REF_SPACE_VIEWER:
case device::mojom::XRSessionFeature::REF_SPACE_LOCAL:
@@ -145,10 +140,20 @@ bool IsFeatureValidForMode(device::mojom::XRSessionFeature feature,
return true;
case device::mojom::XRSessionFeature::REF_SPACE_BOUNDED_FLOOR:
case device::mojom::XRSessionFeature::REF_SPACE_UNBOUNDED:
- return mode == XRSession::kModeImmersiveVR ||
- mode == XRSession::kModeImmersiveAR;
- case device::mojom::XRSessionFeature::DOM_OVERLAY_FOR_HANDHELD_AR:
- return mode == XRSession::kModeImmersiveAR;
+ case device::mojom::XRSessionFeature::HIT_TEST:
+ return mode == device::mojom::blink::XRSessionMode::kImmersiveVr ||
+ mode == device::mojom::blink::XRSessionMode::kImmersiveAr;
+ case device::mojom::XRSessionFeature::DOM_OVERLAY:
+ if (mode != device::mojom::blink::XRSessionMode::kImmersiveAr)
+ return false;
+ if (!session_init->hasDomOverlay()) {
+ execution_context->AddConsoleMessage(MakeGarbageCollected<
+ ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript, error_level,
+ "Must specify a valid domOverlay.root element in XRSessionInit"));
+ return false;
+ }
+ return true;
}
}
@@ -164,8 +169,9 @@ bool HasRequiredFeaturePolicy(const Document* doc,
case device::mojom::XRSessionFeature::REF_SPACE_LOCAL_FLOOR:
case device::mojom::XRSessionFeature::REF_SPACE_BOUNDED_FLOOR:
case device::mojom::XRSessionFeature::REF_SPACE_UNBOUNDED:
- case device::mojom::XRSessionFeature::DOM_OVERLAY_FOR_HANDHELD_AR:
- return doc->IsFeatureEnabled(mojom::FeaturePolicyFeature::kWebXr,
+ case device::mojom::XRSessionFeature::DOM_OVERLAY:
+ case device::mojom::XRSessionFeature::HIT_TEST:
+ return doc->IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kWebXr,
ReportOptions::kReportOnFailure);
}
}
@@ -196,7 +202,7 @@ const char* CheckImmersiveSessionRequestAllowed(LocalFrame* frame,
// Ensure that the inline session request is allowed, if not
// return which security error occurred.
// https://immersive-web.github.io/webxr/#inline-session-request-is-allowed
-const char* XR::CheckInlineSessionRequestAllowed(
+const char* XRSystem::CheckInlineSessionRequestAllowed(
LocalFrame* frame,
const PendingRequestSessionQuery& query) {
// Without user activation, we must reject the session if *any* features
@@ -225,24 +231,26 @@ const char* XR::CheckInlineSessionRequestAllowed(
return nullptr;
}
-XR::PendingSupportsSessionQuery::PendingSupportsSessionQuery(
+XRSystem::PendingSupportsSessionQuery::PendingSupportsSessionQuery(
ScriptPromiseResolver* resolver,
- XRSession::SessionMode session_mode,
+ device::mojom::blink::XRSessionMode session_mode,
bool throw_on_unsupported)
: resolver_(resolver),
mode_(session_mode),
throw_on_unsupported_(throw_on_unsupported) {}
-void XR::PendingSupportsSessionQuery::Trace(blink::Visitor* visitor) {
+void XRSystem::PendingSupportsSessionQuery::Trace(Visitor* visitor) {
visitor->Trace(resolver_);
}
-void XR::PendingSupportsSessionQuery::Resolve(bool supported,
- ExceptionState* exception_state) {
+void XRSystem::PendingSupportsSessionQuery::Resolve(
+ bool supported,
+ ExceptionState* exception_state) {
if (throw_on_unsupported_) {
if (supported) {
resolver_->Resolve();
} else {
+ DVLOG(2) << __func__ << ": session is unsupported - throwing exception";
RejectWithDOMException(DOMExceptionCode::kNotSupportedError,
kSessionNotSupported, exception_state);
}
@@ -251,7 +259,7 @@ void XR::PendingSupportsSessionQuery::Resolve(bool supported,
}
}
-void XR::PendingSupportsSessionQuery::RejectWithDOMException(
+void XRSystem::PendingSupportsSessionQuery::RejectWithDOMException(
DOMExceptionCode exception_code,
const String& message,
ExceptionState* exception_state) {
@@ -269,7 +277,7 @@ void XR::PendingSupportsSessionQuery::RejectWithDOMException(
}
}
-void XR::PendingSupportsSessionQuery::RejectWithSecurityError(
+void XRSystem::PendingSupportsSessionQuery::RejectWithSecurityError(
const String& sanitized_message,
ExceptionState* exception_state) {
if (exception_state) {
@@ -284,7 +292,7 @@ void XR::PendingSupportsSessionQuery::RejectWithSecurityError(
}
}
-void XR::PendingSupportsSessionQuery::RejectWithTypeError(
+void XRSystem::PendingSupportsSessionQuery::RejectWithTypeError(
const String& message,
ExceptionState* exception_state) {
if (exception_state) {
@@ -299,14 +307,15 @@ void XR::PendingSupportsSessionQuery::RejectWithTypeError(
}
}
-XRSession::SessionMode XR::PendingSupportsSessionQuery::mode() const {
+device::mojom::blink::XRSessionMode
+XRSystem::PendingSupportsSessionQuery::mode() const {
return mode_;
}
-XR::PendingRequestSessionQuery::PendingRequestSessionQuery(
+XRSystem::PendingRequestSessionQuery::PendingRequestSessionQuery(
int64_t ukm_source_id,
ScriptPromiseResolver* resolver,
- XRSession::SessionMode session_mode,
+ device::mojom::blink::XRSessionMode session_mode,
RequestedXRSessionFeatureSet required_features,
RequestedXRSessionFeatureSet optional_features)
: resolver_(resolver),
@@ -317,7 +326,7 @@ XR::PendingRequestSessionQuery::PendingRequestSessionQuery(
ParseSensorRequirement();
}
-void XR::PendingRequestSessionQuery::Resolve(
+void XRSystem::PendingRequestSessionQuery::Resolve(
XRSession* session,
mojo::PendingRemote<device::mojom::blink::XRSessionMetricsRecorder>
metrics_recorder) {
@@ -326,7 +335,7 @@ void XR::PendingRequestSessionQuery::Resolve(
std::move(metrics_recorder));
}
-void XR::PendingRequestSessionQuery::RejectWithDOMException(
+void XRSystem::PendingRequestSessionQuery::RejectWithDOMException(
DOMExceptionCode exception_code,
const String& message,
ExceptionState* exception_state) {
@@ -343,7 +352,7 @@ void XR::PendingRequestSessionQuery::RejectWithDOMException(
ReportRequestSessionResult(SessionRequestStatus::kOtherError);
}
-void XR::PendingRequestSessionQuery::RejectWithSecurityError(
+void XRSystem::PendingRequestSessionQuery::RejectWithSecurityError(
const String& sanitized_message,
ExceptionState* exception_state) {
if (exception_state) {
@@ -357,7 +366,7 @@ void XR::PendingRequestSessionQuery::RejectWithSecurityError(
ReportRequestSessionResult(SessionRequestStatus::kOtherError);
}
-void XR::PendingRequestSessionQuery::RejectWithTypeError(
+void XRSystem::PendingRequestSessionQuery::RejectWithTypeError(
const String& message,
ExceptionState* exception_state) {
if (exception_state) {
@@ -372,7 +381,7 @@ void XR::PendingRequestSessionQuery::RejectWithTypeError(
}
device::mojom::XRSessionFeatureRequestStatus
-XR::PendingRequestSessionQuery::GetFeatureRequestStatus(
+XRSystem::PendingRequestSessionQuery::GetFeatureRequestStatus(
device::mojom::XRSessionFeature feature,
const XRSession* session) const {
using device::mojom::XRSessionFeatureRequestStatus;
@@ -394,7 +403,7 @@ XR::PendingRequestSessionQuery::GetFeatureRequestStatus(
return XRSessionFeatureRequestStatus::kNotRequested;
}
-void XR::PendingRequestSessionQuery::ReportRequestSessionResult(
+void XRSystem::PendingRequestSessionQuery::ReportRequestSessionResult(
SessionRequestStatus status,
XRSession* session,
mojo::PendingRemote<device::mojom::blink::XRSessionMetricsRecorder>
@@ -416,6 +425,8 @@ void XR::PendingRequestSessionQuery::ReportRequestSessionResult(
XRSessionFeature::REF_SPACE_BOUNDED_FLOOR, session);
auto feature_request_unbounded =
GetFeatureRequestStatus(XRSessionFeature::REF_SPACE_UNBOUNDED, session);
+ auto feature_request_dom_overlay =
+ GetFeatureRequestStatus(XRSessionFeature::DOM_OVERLAY, session);
ukm::builders::XR_WebXR_SessionRequest(ukm_source_id_)
.SetMode(static_cast<int64_t>(mode_))
@@ -428,6 +439,15 @@ void XR::PendingRequestSessionQuery::ReportRequestSessionResult(
.SetFeature_Unbounded(static_cast<int64_t>(feature_request_unbounded))
.Record(doc->UkmRecorder());
+ // If the session was successfully created and DOM overlay was requested,
+ // count this as a use of the DOM overlay feature.
+ if (session && status == SessionRequestStatus::kSuccess &&
+ feature_request_dom_overlay !=
+ device::mojom::XRSessionFeatureRequestStatus::kNotRequested) {
+ UseCounter::Count(session->GetExecutionContext(),
+ WebFeature::kXRDOMOverlay);
+ }
+
if (session && metrics_recorder) {
mojo::Remote<device::mojom::blink::XRSessionMetricsRecorder> recorder(
std::move(metrics_recorder));
@@ -436,35 +456,36 @@ void XR::PendingRequestSessionQuery::ReportRequestSessionResult(
}
}
-XRSession::SessionMode XR::PendingRequestSessionQuery::mode() const {
+device::mojom::blink::XRSessionMode XRSystem::PendingRequestSessionQuery::mode()
+ const {
return mode_;
}
-const XRSessionFeatureSet& XR::PendingRequestSessionQuery::RequiredFeatures()
- const {
+const XRSessionFeatureSet&
+XRSystem::PendingRequestSessionQuery::RequiredFeatures() const {
return required_features_.valid_features;
}
-const XRSessionFeatureSet& XR::PendingRequestSessionQuery::OptionalFeatures()
- const {
+const XRSessionFeatureSet&
+XRSystem::PendingRequestSessionQuery::OptionalFeatures() const {
return optional_features_.valid_features;
}
-bool XR::PendingRequestSessionQuery::InvalidRequiredFeatures() const {
+bool XRSystem::PendingRequestSessionQuery::InvalidRequiredFeatures() const {
return required_features_.invalid_features;
}
-bool XR::PendingRequestSessionQuery::InvalidOptionalFeatures() const {
+bool XRSystem::PendingRequestSessionQuery::InvalidOptionalFeatures() const {
return optional_features_.invalid_features;
}
-ScriptState* XR::PendingRequestSessionQuery::GetScriptState() const {
+ScriptState* XRSystem::PendingRequestSessionQuery::GetScriptState() const {
return resolver_->GetScriptState();
}
-void XR::PendingRequestSessionQuery::ParseSensorRequirement() {
+void XRSystem::PendingRequestSessionQuery::ParseSensorRequirement() {
// All modes other than inline require sensors.
- if (mode_ != XRSession::kModeInline) {
+ if (mode_ != device::mojom::blink::XRSessionMode::kInline) {
sensor_requirement_ = SensorRequirement::kRequired;
return;
}
@@ -489,14 +510,150 @@ void XR::PendingRequestSessionQuery::ParseSensorRequirement() {
sensor_requirement_ = kNone;
}
-void XR::PendingRequestSessionQuery::Trace(blink::Visitor* visitor) {
+void XRSystem::PendingRequestSessionQuery::Trace(Visitor* visitor) {
visitor->Trace(resolver_);
+ visitor->Trace(dom_overlay_element_);
+}
+
+XRSystem::OverlayFullscreenEventManager::OverlayFullscreenEventManager(
+ XRSystem* xr,
+ XRSystem::PendingRequestSessionQuery* query,
+ device::mojom::blink::RequestSessionResultPtr result)
+ : xr_(xr), query_(query), result_(std::move(result)) {
+ DVLOG(2) << __func__;
+}
+
+XRSystem::OverlayFullscreenEventManager::~OverlayFullscreenEventManager() =
+ default;
+
+void XRSystem::OverlayFullscreenEventManager::Invoke(
+ ExecutionContext* execution_context,
+ Event* event) {
+ DVLOG(2) << __func__ << ": event type=" << event->type();
+
+ // This handler should only be called once, it's unregistered after use.
+ DCHECK(query_);
+ DCHECK(result_);
+
+ Element* element = query_->DOMOverlayElement();
+ element->GetDocument().removeEventListener(
+ event_type_names::kFullscreenchange, this, true);
+ element->GetDocument().removeEventListener(event_type_names::kFullscreenerror,
+ this, true);
+
+ if (event->type() == event_type_names::kFullscreenchange) {
+ // Succeeded, proceed with session creation.
+ element->GetDocument().SetIsXrOverlay(true, element);
+ xr_->OnRequestSessionReturned(query_, std::move(result_));
+ }
+
+ if (event->type() == event_type_names::kFullscreenerror) {
+ // Failed, reject the session
+ xr_->OnRequestSessionReturned(
+ query_, device::mojom::blink::RequestSessionResult::NewFailureReason(
+ device::mojom::RequestSessionError::INVALID_CLIENT));
+ }
+}
+
+void XRSystem::OverlayFullscreenEventManager::RequestFullscreen() {
+ Element* element = query_->DOMOverlayElement();
+ DCHECK(element);
+
+ if (element == Fullscreen::FullscreenElementFrom(element->GetDocument())) {
+ // It's possible that the requested element is already fullscreen, in which
+ // case we must not wait for a fullscreenchange event since it won't arrive.
+ // Detect that and proceed directly with session creation in this case. This
+ // can happen if the site used Fullscreen API to place the element into
+ // fullscreen mode before requesting the session, and if the session can
+ // proceed without needing a consent prompt. (Showing a dialog exits
+ // fullscreen mode.)
+ DVLOG(2) << __func__ << ": requested element already fullscreen";
+ element->GetDocument().SetIsXrOverlay(true, element);
+ xr_->OnRequestSessionReturned(query_, std::move(result_));
+ return;
+ }
+
+ // Set up event listeners for success and failure.
+ element->GetDocument().addEventListener(event_type_names::kFullscreenchange,
+ this, true);
+ element->GetDocument().addEventListener(event_type_names::kFullscreenerror,
+ this, true);
+
+ // Use the event-generating unprefixed version of RequestFullscreen to ensure
+ // that the fullscreen event listener is informed once this completes.
+ FullscreenOptions* options = FullscreenOptions::Create();
+ options->setNavigationUI("hide");
+
+ // Grant fullscreen API permission for the following call. Requesting the
+ // immersive session had required a user activation state, but that may have
+ // expired by now due to the user taking time to respond to the consent
+ // prompt.
+ ScopedAllowFullscreen scope(ScopedAllowFullscreen::kXrOverlay);
+
+ Fullscreen::RequestFullscreen(*element, options,
+ Fullscreen::RequestType::kUnprefixed);
+}
+
+void XRSystem::OverlayFullscreenEventManager::Trace(Visitor* visitor) {
+ visitor->Trace(xr_);
+ visitor->Trace(query_);
+ EventListener::Trace(visitor);
+}
+
+XRSystem::OverlayFullscreenExitObserver::OverlayFullscreenExitObserver(
+ XRSystem* xr)
+ : xr_(xr) {
+ DVLOG(2) << __func__;
+}
+
+XRSystem::OverlayFullscreenExitObserver::~OverlayFullscreenExitObserver() =
+ default;
+
+void XRSystem::OverlayFullscreenExitObserver::Invoke(
+ ExecutionContext* execution_context,
+ Event* event) {
+ DVLOG(2) << __func__ << ": event type=" << event->type();
+
+ element_->GetDocument().removeEventListener(
+ event_type_names::kFullscreenchange, this, true);
+
+ if (event->type() == event_type_names::kFullscreenchange) {
+ // Succeeded, proceed with session shutdown.
+ xr_->ExitPresent(std::move(on_exited_));
+ }
+}
+
+void XRSystem::OverlayFullscreenExitObserver::ExitFullscreen(
+ Element* element,
+ base::OnceClosure on_exited) {
+ DVLOG(2) << __func__;
+ element_ = element;
+ on_exited_ = std::move(on_exited);
+
+ element->GetDocument().addEventListener(event_type_names::kFullscreenchange,
+ this, true);
+ // "ua_originated" means that the browser process already exited
+ // fullscreen. Set it to false because we need the browser process
+ // to get notified that it needs to exit fullscreen. Use
+ // FullyExitFullscreen to ensure that we return to non-fullscreen mode.
+ // ExitFullscreen only unfullscreens a single element, potentially
+ // leaving others in fullscreen mode.
+ constexpr bool kUaOriginated = false;
+
+ Fullscreen::FullyExitFullscreen(element_->GetDocument(), kUaOriginated);
+}
+
+void XRSystem::OverlayFullscreenExitObserver::Trace(Visitor* visitor) {
+ visitor->Trace(xr_);
+ visitor->Trace(element_);
+ EventListener::Trace(visitor);
}
-device::mojom::blink::XRSessionOptionsPtr XR::XRSessionOptionsFromQuery(
+device::mojom::blink::XRSessionOptionsPtr XRSystem::XRSessionOptionsFromQuery(
const PendingRequestSessionQuery& query) {
device::mojom::blink::XRSessionOptionsPtr session_options =
- convertModeToMojo(query.mode());
+ device::mojom::blink::XRSessionOptions::New();
+ session_options->mode = query.mode();
CopyToVector(query.RequiredFeatures(), session_options->required_features);
CopyToVector(query.OptionalFeatures(), session_options->optional_features);
@@ -504,8 +661,8 @@ device::mojom::blink::XRSessionOptionsPtr XR::XRSessionOptionsFromQuery(
return session_options;
}
-XR::XR(LocalFrame& frame, int64_t ukm_source_id)
- : ContextLifecycleObserver(frame.GetDocument()),
+XRSystem::XRSystem(LocalFrame& frame, int64_t ukm_source_id)
+ : ExecutionContextLifecycleObserver(frame.GetDocument()),
FocusChangedObserver(frame.GetPage()),
ukm_source_id_(ukm_source_id),
navigation_start_(
@@ -518,11 +675,12 @@ XR::XR(LocalFrame& frame, int64_t ukm_source_id)
frame.GetBrowserInterfaceBroker().GetInterface(
service_.BindNewPipeAndPassReceiver(
frame.GetTaskRunner(TaskType::kMiscPlatformAPI)));
- service_.set_disconnect_handler(WTF::Bind(
- &XR::Dispose, WrapWeakPersistent(this), DisposeType::kDisconnected));
+ service_.set_disconnect_handler(WTF::Bind(&XRSystem::Dispose,
+ WrapWeakPersistent(this),
+ DisposeType::kDisconnected));
}
-void XR::FocusedFrameChanged() {
+void XRSystem::FocusedFrameChanged() {
// Tell all sessions that focus changed.
for (const auto& session : sessions_) {
session->OnFocusChanged();
@@ -532,19 +690,19 @@ void XR::FocusedFrameChanged() {
frame_provider_->OnFocusChanged();
}
-bool XR::IsFrameFocused() {
+bool XRSystem::IsFrameFocused() {
return FocusChangedObserver::IsFrameFocused(GetFrame());
}
-ExecutionContext* XR::GetExecutionContext() const {
- return ContextLifecycleObserver::GetExecutionContext();
+ExecutionContext* XRSystem::GetExecutionContext() const {
+ return ExecutionContextLifecycleObserver::GetExecutionContext();
}
-const AtomicString& XR::InterfaceName() const {
+const AtomicString& XRSystem::InterfaceName() const {
return event_target_names::kXR;
}
-XRFrameProvider* XR::frameProvider() {
+XRFrameProvider* XRSystem::frameProvider() {
if (!frame_provider_) {
frame_provider_ = MakeGarbageCollected<XRFrameProvider>(this);
}
@@ -554,23 +712,17 @@ XRFrameProvider* XR::frameProvider() {
const mojo::AssociatedRemote<
device::mojom::blink::XREnvironmentIntegrationProvider>&
-XR::xrEnvironmentProviderRemote() {
+XRSystem::xrEnvironmentProviderRemote() {
return environment_provider_;
}
-void XR::AddEnvironmentProviderErrorHandler(
+void XRSystem::AddEnvironmentProviderErrorHandler(
EnvironmentProviderErrorCallback callback) {
environment_provider_error_callbacks_.push_back(std::move(callback));
}
-void XR::ExitPresent(base::OnceClosure on_exited) {
+void XRSystem::ExitPresent(base::OnceClosure on_exited) {
DVLOG(1) << __func__;
- if (service_) {
- service_->ExitPresent(std::move(on_exited));
- } else {
- // The service was already shut down, run the callback immediately.
- std::move(on_exited).Run();
- }
// If the document was potentially being shown in a DOM overlay via
// fullscreened elements, make sure to clear any fullscreen states on exiting
@@ -578,40 +730,51 @@ void XR::ExitPresent(base::OnceClosure on_exited) {
// - browser side ends session and exits fullscreen (i.e. back button)
// - renderer processes WebViewImpl::ExitFullscreen via ChromeClient
// - JS application sets a new element to fullscreen, this is allowed
- // because doc->IsImmersiveArOverlay() is still true at this point
+ // because doc->IsXrOverlay() is still true at this point
// - renderer processes XR session shutdown (this method)
// - browser re-enters fullscreen unexpectedly
LocalFrame* frame = GetFrame();
- if (!frame)
- return;
+ if (frame) {
+ Document* doc = frame->GetDocument();
+ DCHECK(doc);
+ DVLOG(3) << __func__ << ": doc->IsXrOverlay()=" << doc->IsXrOverlay();
+ if (doc->IsXrOverlay()) {
+ Element* fullscreen_element = Fullscreen::FullscreenElementFrom(*doc);
+ DVLOG(3) << __func__ << ": fullscreen_element=" << fullscreen_element;
+ doc->SetIsXrOverlay(false, fullscreen_element);
+
+ // Restore the FrameView background color that was changed in
+ // OnRequestSessionReturned. The layout view can be null on navigation.
+ auto* layout_view = doc->GetLayoutView();
+ if (layout_view) {
+ auto* frame_view = layout_view->GetFrameView();
+ // SetBaseBackgroundColor updates composited layer mappings.
+ // That DCHECKs IsAllowedToQueryCompositingState which requires
+ // DocumentLifecycle >= kInCompositingUpdate.
+ frame_view->UpdateLifecycleToCompositingInputsClean(
+ DocumentUpdateReason::kBaseColor);
+ frame_view->SetBaseBackgroundColor(original_base_background_color_);
+ }
- Document* doc = frame->GetDocument();
- DCHECK(doc);
- if (doc->IsImmersiveArOverlay()) {
- doc->SetIsImmersiveArOverlay(false);
- Element* fullscreen_element = Fullscreen::FullscreenElementFrom(*doc);
- if (fullscreen_element) {
- // "ua_originated" means that the browser process already exited
- // fullscreen. Set it to false because we need the browser process
- // to get notified that it needs to exit fullscreen. Use
- // FullyExitFullscreen to ensure that we return to non-fullscreen mode.
- // ExitFullscreen only unfullscreens a single element, potentially
- // leaving others in fullscreen mode.
- constexpr bool kUaOriginated = false;
- Fullscreen::FullyExitFullscreen(*doc, kUaOriginated);
+ if (fullscreen_element) {
+ fullscreen_exit_observer_ =
+ MakeGarbageCollected<OverlayFullscreenExitObserver>(this);
+ fullscreen_exit_observer_->ExitFullscreen(fullscreen_element,
+ std::move(on_exited));
+ return;
+ }
}
- // Restore the FrameView background color that was changed in
- // OnRequestSessionReturned.
- auto* frame_view = doc->GetLayoutView()->GetFrameView();
- // SetBaseBackgroundColor updates composited layer mappings.
- // That DCHECKs IsAllowedToQueryCompositingState which requires
- // DocumentLifecycle >= kInCompositingUpdate.
- frame_view->UpdateLifecycleToCompositingInputsClean();
- frame_view->SetBaseBackgroundColor(original_base_background_color_);
+ }
+
+ if (service_) {
+ service_->ExitPresent(std::move(on_exited));
+ } else {
+ // The service was already shut down, run the callback immediately.
+ std::move(on_exited).Run();
}
}
-void XR::SetFramesThrottled(const XRSession* session, bool throttled) {
+void XRSystem::SetFramesThrottled(const XRSession* session, bool throttled) {
// The service only cares if the immersive session is throttling frames.
if (session->immersive()) {
// If we have an immersive session, we should have a service.
@@ -620,22 +783,23 @@ void XR::SetFramesThrottled(const XRSession* session, bool throttled) {
}
}
-ScriptPromise XR::supportsSession(ScriptState* script_state,
- const String& mode,
- ExceptionState& exception_state) {
+ScriptPromise XRSystem::supportsSession(ScriptState* script_state,
+ const String& mode,
+ ExceptionState& exception_state) {
return InternalIsSessionSupported(script_state, mode, exception_state, true);
}
-ScriptPromise XR::isSessionSupported(ScriptState* script_state,
- const String& mode,
- ExceptionState& exception_state) {
+ScriptPromise XRSystem::isSessionSupported(ScriptState* script_state,
+ const String& mode,
+ ExceptionState& exception_state) {
return InternalIsSessionSupported(script_state, mode, exception_state, false);
}
-ScriptPromise XR::InternalIsSessionSupported(ScriptState* script_state,
- const String& mode,
- ExceptionState& exception_state,
- bool throw_on_unsupported) {
+ScriptPromise XRSystem::InternalIsSessionSupported(
+ ScriptState* script_state,
+ const String& mode,
+ ExceptionState& exception_state,
+ bool throw_on_unsupported) {
LocalFrame* frame = GetFrame();
Document* doc = frame ? frame->GetDocument() : nullptr;
if (!doc) {
@@ -648,24 +812,27 @@ ScriptPromise XR::InternalIsSessionSupported(ScriptState* script_state,
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
- XRSession::SessionMode session_mode = stringToSessionMode(mode);
+ device::mojom::blink::XRSessionMode session_mode = stringToSessionMode(mode);
PendingSupportsSessionQuery* query =
MakeGarbageCollected<PendingSupportsSessionQuery>(resolver, session_mode,
throw_on_unsupported);
- if (session_mode == XRSession::kModeImmersiveAR &&
+ if (session_mode == device::mojom::blink::XRSessionMode::kImmersiveAr &&
!RuntimeEnabledFeatures::WebXRARModuleEnabled(doc)) {
+ DVLOG(2) << __func__
+ << ": Immersive AR session is only supported if WebXRARModule "
+ "feature is enabled";
query->Resolve(false);
return promise;
}
- if (session_mode == XRSession::kModeInline) {
+ if (session_mode == device::mojom::blink::XRSessionMode::kInline) {
// inline sessions are always supported.
query->Resolve(true);
return promise;
}
- if (!doc->IsFeatureEnabled(mojom::FeaturePolicyFeature::kWebXr,
+ if (!doc->IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kWebXr,
ReportOptions::kReportOnFailure)) {
// Only allow the call to be made if the appropriate feature policy is in
// place.
@@ -681,21 +848,22 @@ ScriptPromise XR::InternalIsSessionSupported(ScriptState* script_state,
}
device::mojom::blink::XRSessionOptionsPtr session_options =
- convertModeToMojo(query->mode());
+ device::mojom::blink::XRSessionOptions::New();
+ session_options->mode = query->mode();
outstanding_support_queries_.insert(query);
service_->SupportsSession(
std::move(session_options),
- WTF::Bind(&XR::OnSupportsSessionReturned, WrapPersistent(this),
+ WTF::Bind(&XRSystem::OnSupportsSessionReturned, WrapPersistent(this),
WrapPersistent(query)));
return promise;
}
-void XR::RequestImmersiveSession(LocalFrame* frame,
- Document* doc,
- PendingRequestSessionQuery* query,
- ExceptionState* exception_state) {
+void XRSystem::RequestImmersiveSession(LocalFrame* frame,
+ Document* doc,
+ PendingRequestSessionQuery* query,
+ ExceptionState* exception_state) {
DVLOG(2) << __func__;
// Log an immersive session request if we haven't already
if (!did_log_request_immersive_session_) {
@@ -732,6 +900,7 @@ void XR::RequestImmersiveSession(LocalFrame* frame,
// Reject session if any of the required features were invalid.
if (query->InvalidRequiredFeatures()) {
+ DVLOG(2) << __func__ << ": rejecting session - invalid required features";
query->RejectWithDOMException(DOMExceptionCode::kNotSupportedError,
kSessionNotSupported, exception_state);
return;
@@ -743,15 +912,23 @@ void XR::RequestImmersiveSession(LocalFrame* frame,
// Submit the request to VrServiceImpl in the Browser process
outstanding_request_queries_.insert(query);
auto session_options = XRSessionOptionsFromQuery(*query);
- service_->RequestSession(
- std::move(session_options),
- WTF::Bind(&XR::OnRequestSessionReturned, WrapWeakPersistent(this),
- WrapPersistent(query)));
+
+ // In DOM overlay mode, there's an additional step before an immersive-ar
+ // session can start, we need to enter fullscreen mode by setting the
+ // appropriate element as fullscreen from the Renderer, then waiting for the
+ // browser side to send an event indicating success or failure.
+ auto callback =
+ query->DOMOverlayElement()
+ ? WTF::Bind(&XRSystem::OnRequestSessionSetupForDomOverlay,
+ WrapWeakPersistent(this), WrapPersistent(query))
+ : WTF::Bind(&XRSystem::OnRequestSessionReturned,
+ WrapWeakPersistent(this), WrapPersistent(query));
+ service_->RequestSession(std::move(session_options), std::move(callback));
}
-void XR::RequestInlineSession(LocalFrame* frame,
- PendingRequestSessionQuery* query,
- ExceptionState* exception_state) {
+void XRSystem::RequestInlineSession(LocalFrame* frame,
+ PendingRequestSessionQuery* query,
+ ExceptionState* exception_state) {
DVLOG(2) << __func__;
// Make sure the inline session request was allowed
auto* inline_session_request_error =
@@ -793,14 +970,15 @@ void XR::RequestInlineSession(LocalFrame* frame,
auto session_options = XRSessionOptionsFromQuery(*query);
service_->RequestSession(
std::move(session_options),
- WTF::Bind(&XR::OnRequestSessionReturned, WrapWeakPersistent(this),
+ WTF::Bind(&XRSystem::OnRequestSessionReturned, WrapWeakPersistent(this),
WrapPersistent(query)));
}
-XR::RequestedXRSessionFeatureSet XR::ParseRequestedFeatures(
+XRSystem::RequestedXRSessionFeatureSet XRSystem::ParseRequestedFeatures(
Document* doc,
const HeapVector<ScriptValue>& features,
- const XRSession::SessionMode& session_mode,
+ const device::mojom::blink::XRSessionMode& session_mode,
+ XRSessionInit* session_init,
mojom::ConsoleMessageLevel error_level) {
RequestedXRSessionFeatureSet result;
@@ -812,29 +990,35 @@ XR::RequestedXRSessionFeatureSet XR::ParseRequestedFeatures(
auto feature_enum = StringToXRSessionFeature(doc, feature_string);
if (!feature_enum) {
- GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kJavaScript, error_level,
- "Unrecognized feature requested: " + feature_string));
+ GetExecutionContext()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript, error_level,
+ "Unrecognized feature requested: " + feature_string));
result.invalid_features = true;
- } else if (!IsFeatureValidForMode(feature_enum.value(), session_mode)) {
- GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kJavaScript, error_level,
- "Feature '" + feature_string + "' is not supported for mode: " +
- SessionModeToString(session_mode)));
+ } else if (!IsFeatureValidForMode(feature_enum.value(), session_mode,
+ session_init, GetExecutionContext(),
+ error_level)) {
+ GetExecutionContext()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript, error_level,
+ "Feature '" + feature_string + "' is not supported for mode: " +
+ SessionModeToString(session_mode)));
result.invalid_features = true;
} else if (!HasRequiredFeaturePolicy(doc, feature_enum.value())) {
- GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kJavaScript, error_level,
- "Feature '" + feature_string +
- "' is not permitted by feature policy"));
+ GetExecutionContext()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript, error_level,
+ "Feature '" + feature_string +
+ "' is not permitted by feature policy"));
result.invalid_features = true;
} else {
result.valid_features.insert(feature_enum.value());
}
} else {
GetExecutionContext()->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- error_level, "Unrecognized feature value"));
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript, error_level,
+ "Unrecognized feature value"));
result.invalid_features = true;
}
}
@@ -842,10 +1026,10 @@ XR::RequestedXRSessionFeatureSet XR::ParseRequestedFeatures(
return result;
}
-ScriptPromise XR::requestSession(ScriptState* script_state,
- const String& mode,
- XRSessionInit* session_init,
- ExceptionState& exception_state) {
+ScriptPromise XRSystem::requestSession(ScriptState* script_state,
+ const String& mode,
+ XRSessionInit* session_init,
+ ExceptionState& exception_state) {
DVLOG(2) << __func__;
// TODO(https://crbug.com/968622): Make sure we don't forget to call
// metrics-related methods when the promise gets resolved/rejected.
@@ -861,10 +1045,10 @@ ScriptPromise XR::requestSession(ScriptState* script_state,
return ScriptPromise(); // Will be rejected by generated bindings
}
- XRSession::SessionMode session_mode = stringToSessionMode(mode);
+ device::mojom::blink::XRSessionMode session_mode = stringToSessionMode(mode);
// If the request is for immersive-ar, ensure that feature is enabled.
- if (session_mode == XRSession::kModeImmersiveAR &&
+ if (session_mode == device::mojom::blink::XRSessionMode::kImmersiveAr &&
!RuntimeEnabledFeatures::WebXRARModuleEnabled(doc)) {
exception_state.ThrowTypeError(
String::Format(kImmersiveArModeNotValid, "requestSession"));
@@ -883,7 +1067,7 @@ ScriptPromise XR::requestSession(ScriptState* script_state,
RequestedXRSessionFeatureSet required_features;
if (session_init && session_init->hasRequiredFeatures()) {
required_features = ParseRequestedFeatures(
- doc, session_init->requiredFeatures(), session_mode,
+ doc, session_init->requiredFeatures(), session_mode, session_init,
mojom::ConsoleMessageLevel::kError);
}
@@ -891,7 +1075,7 @@ ScriptPromise XR::requestSession(ScriptState* script_state,
RequestedXRSessionFeatureSet optional_features;
if (session_init && session_init->hasOptionalFeatures()) {
optional_features = ParseRequestedFeatures(
- doc, session_init->optionalFeatures(), session_mode,
+ doc, session_init->optionalFeatures(), session_mode, session_init,
mojom::ConsoleMessageLevel::kWarning);
}
@@ -899,13 +1083,13 @@ ScriptPromise XR::requestSession(ScriptState* script_state,
// Add those default features as required features now.
base::span<const device::mojom::XRSessionFeature> default_features;
switch (session_mode) {
- case XRSession::kModeImmersiveVR:
+ case device::mojom::blink::XRSessionMode::kImmersiveVr:
default_features = kDefaultImmersiveVrFeatures;
break;
- case XRSession::kModeImmersiveAR:
+ case device::mojom::blink::XRSessionMode::kImmersiveAr:
default_features = kDefaultImmersiveArFeatures;
break;
- case XRSession::kModeInline:
+ case device::mojom::blink::XRSessionMode::kInline:
default_features = kDefaultInlineFeatures;
break;
}
@@ -926,12 +1110,17 @@ ScriptPromise XR::requestSession(ScriptState* script_state,
GetSourceId(), resolver, session_mode, std::move(required_features),
std::move(optional_features));
+ if (session_init && session_init->hasDomOverlay()) {
+ DCHECK(session_init->domOverlay()->hasRoot()) << "required in IDL";
+ query->SetDOMOverlayElement(session_init->domOverlay()->root());
+ }
+
switch (session_mode) {
- case XRSession::kModeImmersiveVR:
- case XRSession::kModeImmersiveAR:
+ case device::mojom::blink::XRSessionMode::kImmersiveVr:
+ case device::mojom::blink::XRSessionMode::kImmersiveAr:
RequestImmersiveSession(frame, doc, query, &exception_state);
break;
- case XRSession::kModeInline:
+ case device::mojom::blink::XRSessionMode::kInline:
RequestInlineSession(frame, query, &exception_state);
break;
}
@@ -942,16 +1131,17 @@ ScriptPromise XR::requestSession(ScriptState* script_state,
// 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 XR::OnDeviceChanged() {
+void XRSystem::OnDeviceChanged() {
LocalFrame* frame = GetFrame();
Document* doc = frame ? frame->GetDocument() : nullptr;
- if (doc && doc->IsFeatureEnabled(mojom::FeaturePolicyFeature::kWebXr)) {
+ if (doc &&
+ doc->IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kWebXr)) {
DispatchEvent(*blink::Event::Create(event_type_names::kDevicechange));
}
}
-void XR::OnSupportsSessionReturned(PendingSupportsSessionQuery* query,
- bool supports_session) {
+void XRSystem::OnSupportsSessionReturned(PendingSupportsSessionQuery* query,
+ bool supports_session) {
// The session query has returned and we're about to resolve or reject the
// promise, so remove it from our outstanding list.
DCHECK(outstanding_support_queries_.Contains(query));
@@ -959,18 +1149,39 @@ void XR::OnSupportsSessionReturned(PendingSupportsSessionQuery* query,
query->Resolve(supports_session);
}
-void XR::OnRequestSessionReturned(
+void XRSystem::OnRequestSessionSetupForDomOverlay(
+ PendingRequestSessionQuery* query,
+ device::mojom::blink::RequestSessionResultPtr result) {
+ DCHECK(query->DOMOverlayElement());
+ if (result->is_success()) {
+ // Success. Now request fullscreen mode and continue with
+ // OnRequestSessionReturned once that completes.
+ fullscreen_event_manager_ =
+ MakeGarbageCollected<OverlayFullscreenEventManager>(this, query,
+ std::move(result));
+ fullscreen_event_manager_->RequestFullscreen();
+ } else {
+ // Session request failed, continue processing that normally.
+ OnRequestSessionReturned(query, std::move(result));
+ }
+}
+
+void XRSystem::OnRequestSessionReturned(
PendingRequestSessionQuery* query,
device::mojom::blink::RequestSessionResultPtr result) {
// The session query has returned and we're about to resolve or reject the
// promise, so remove it from our outstanding list.
DCHECK(outstanding_request_queries_.Contains(query));
outstanding_request_queries_.erase(query);
- if (query->mode() == XRSession::kModeImmersiveVR ||
- query->mode() == XRSession::kModeImmersiveAR) {
+ if (query->mode() == device::mojom::blink::XRSessionMode::kImmersiveVr ||
+ query->mode() == device::mojom::blink::XRSessionMode::kImmersiveAr) {
DCHECK(has_outstanding_immersive_request_);
has_outstanding_immersive_request_ = false;
}
+ // Clean up the fullscreen event manager which may have been added for
+ // DOM overlay setup. We're done with it, and it contains a reference
+ // to the query and the DOM overlay element.
+ fullscreen_event_manager_ = nullptr;
// TODO(https://crbug.com/872316) Improve the error messaging to indicate why
// a request failed.
@@ -995,7 +1206,8 @@ void XR::OnRequestSessionReturned(
auto session_ptr = std::move(result->get_success()->session);
auto metrics_recorder = std::move(result->get_success()->metrics_recorder);
- bool environment_integration = query->mode() == XRSession::kModeImmersiveAR;
+ bool environment_integration =
+ query->mode() == device::mojom::blink::XRSessionMode::kImmersiveAr;
// immersive sessions must supply display info.
DCHECK(session_ptr->display_info);
@@ -1019,8 +1231,8 @@ void XR::OnRequestSessionReturned(
frameProvider()->OnSessionStarted(session, std::move(session_ptr));
- if (query->mode() == XRSession::kModeImmersiveVR ||
- query->mode() == XRSession::kModeImmersiveAR) {
+ if (query->mode() == device::mojom::blink::XRSessionMode::kImmersiveVr ||
+ query->mode() == device::mojom::blink::XRSessionMode::kImmersiveAr) {
if (environment_integration) {
// See Task Sources spreadsheet for more information:
// https://docs.google.com/spreadsheets/d/1b-dus1Ug3A8y0lX0blkmOjJILisUASdj8x9YN_XMwYc/view
@@ -1030,20 +1242,22 @@ void XR::OnRequestSessionReturned(
environment_provider_.BindNewEndpointAndPassReceiver(
GetExecutionContext()->GetTaskRunner(
TaskType::kMiscPlatformAPI)));
- environment_provider_.set_disconnect_handler(WTF::Bind(
- &XR::OnEnvironmentProviderDisconnect, WrapWeakPersistent(this)));
+ environment_provider_.set_disconnect_handler(
+ WTF::Bind(&XRSystem::OnEnvironmentProviderDisconnect,
+ WrapWeakPersistent(this)));
session->OnEnvironmentProviderCreated();
LocalFrame* frame = GetFrame();
DCHECK(frame);
- if (enabled_features.Contains(
- device::mojom::XRSessionFeature::DOM_OVERLAY_FOR_HANDHELD_AR)) {
- // The session is using DOM overlay mode.
+ if (query->DOMOverlayElement()) {
+ // The session is using DOM overlay mode. At this point the overlay
+ // element is already in fullscreen mode, and the session can
+ // proceed.
Document* doc = frame->GetDocument();
DCHECK(doc);
- doc->SetIsImmersiveArOverlay(true);
+ session->SetDOMOverlayElement(query->DOMOverlayElement());
// Save the current base background color (restored in ExitPresent),
// and set a transparent background for the FrameView.
@@ -1051,32 +1265,14 @@ void XR::OnRequestSessionReturned(
// SetBaseBackgroundColor updates composited layer mappings.
// That DCHECKs IsAllowedToQueryCompositingState which requires
// DocumentLifecycle >= kInCompositingUpdate.
- frame_view->UpdateLifecycleToCompositingInputsClean();
+ frame_view->UpdateLifecycleToCompositingInputsClean(
+ DocumentUpdateReason::kBaseColor);
original_base_background_color_ = frame_view->BaseBackgroundColor();
frame_view->SetBaseBackgroundColor(Color::kTransparent);
-
- // In DOM overlay mode, entering fullscreen mode needs to be triggered
- // from the Renderer by actually fullscreening an element. If there
- // is no current fullscreen element, fullscreen the <body> element
- // for now. The JS application can use enterFullscreen to change this.
- //
- // A TabObserver on the browser side exits the session if there's
- // no longer a fullscreen element, for example if the JS app manually
- // unfullscreens the "body" element. That ensures we don't end up in a
- // hybrid non-fullscreen AR state.
- Element* fullscreen_element = Fullscreen::FullscreenElementFrom(*doc);
- if (!fullscreen_element) {
- Element* body = doc->body();
- DCHECK(body);
- // FIXME: this is the "prefixed" version that doesn't generate a
- // fullscreenchange event and auto-hides navigation bars. Should the
- // event be generated?
- Fullscreen::RequestFullscreen(*body);
- }
}
}
- if (query->mode() == XRSession::kModeImmersiveVR &&
+ if (query->mode() == device::mojom::blink::XRSessionMode::kImmersiveVr &&
session->UsesInputEventing()) {
frameProvider()->GetImmersiveDataProvider()->SetInputSourceButtonListener(
session->GetInputClickListener());
@@ -1089,7 +1285,7 @@ void XR::OnRequestSessionReturned(
query->Resolve(session, std::move(metrics_recorder));
}
-void XR::ReportImmersiveSupported(bool supported) {
+void XRSystem::ReportImmersiveSupported(bool supported) {
Document* doc = GetFrame() ? GetFrame()->GetDocument() : nullptr;
if (doc && !did_log_supports_immersive_ && supported) {
ukm::builders::XR_WebXR ukm_builder(ukm_source_id_);
@@ -1099,8 +1295,9 @@ void XR::ReportImmersiveSupported(bool supported) {
}
}
-void XR::AddedEventListener(const AtomicString& event_type,
- RegisteredEventListener& registered_listener) {
+void XRSystem::AddedEventListener(
+ const AtomicString& event_type,
+ RegisteredEventListener& registered_listener) {
EventTargetWithInlineData::AddedEventListener(event_type,
registered_listener);
@@ -1118,13 +1315,13 @@ void XR::AddedEventListener(const AtomicString& event_type,
}
}
-void XR::ContextDestroyed(ExecutionContext*) {
+void XRSystem::ContextDestroyed() {
Dispose(DisposeType::kContextDestroyed);
}
// A session is always created and returned.
-XRSession* XR::CreateSession(
- XRSession::SessionMode mode,
+XRSession* XRSystem::CreateSession(
+ device::mojom::blink::XRSessionMode mode,
XRSession::EnvironmentBlendMode blend_mode,
mojo::PendingReceiver<device::mojom::blink::XRSessionClient>
client_receiver,
@@ -1141,10 +1338,10 @@ XRSession* XR::CreateSession(
return session;
}
-XRSession* XR::CreateSensorlessInlineSession() {
+XRSession* XRSystem::CreateSensorlessInlineSession() {
// TODO(https://crbug.com/944936): The blend mode could be "additive".
XRSession::EnvironmentBlendMode blend_mode = XRSession::kBlendModeOpaque;
- return CreateSession(XRSession::kModeInline, blend_mode,
+ return CreateSession(device::mojom::blink::XRSessionMode::kInline, blend_mode,
mojo::NullReceiver() /* client receiver */,
nullptr /* display_info */,
false /* uses_input_eventing */,
@@ -1152,7 +1349,7 @@ XRSession* XR::CreateSensorlessInlineSession() {
true /* sensorless_session */);
}
-void XR::Dispose(DisposeType dispose_type) {
+void XRSystem::Dispose(DisposeType dispose_type) {
switch (dispose_type) {
case DisposeType::kContextDestroyed:
is_context_destroyed_ = true;
@@ -1190,7 +1387,7 @@ void XR::Dispose(DisposeType dispose_type) {
DCHECK(outstanding_support_queries_.IsEmpty());
}
-void XR::OnEnvironmentProviderDisconnect() {
+void XRSystem::OnEnvironmentProviderDisconnect() {
for (auto& callback : environment_provider_error_callbacks_) {
std::move(callback).Run();
}
@@ -1199,12 +1396,14 @@ void XR::OnEnvironmentProviderDisconnect() {
environment_provider_.reset();
}
-void XR::Trace(blink::Visitor* visitor) {
+void XRSystem::Trace(Visitor* visitor) {
visitor->Trace(frame_provider_);
visitor->Trace(sessions_);
visitor->Trace(outstanding_support_queries_);
visitor->Trace(outstanding_request_queries_);
- ContextLifecycleObserver::Trace(visitor);
+ visitor->Trace(fullscreen_event_manager_);
+ visitor->Trace(fullscreen_exit_observer_);
+ ExecutionContextLifecycleObserver::Trace(visitor);
EventTargetWithInlineData::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr.h b/chromium/third_party/blink/renderer/modules/xr/xr_system.h
index bf498cf753a..4a1258d2ec2 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_system.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_XR_XR_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_SYSTEM_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_SYSTEM_H_
#include "device/vr/public/mojom/vr_service.mojom-blink.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
@@ -11,12 +11,14 @@
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_xr_dom_overlay_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_xr_session_init.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
-#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/page/focus_changed_observer.h"
#include "third_party/blink/renderer/modules/xr/xr_session.h"
-#include "third_party/blink/renderer/modules/xr/xr_session_init.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
@@ -29,21 +31,43 @@ class ScriptPromiseResolver;
class XRFrameProvider;
class XRSessionInit;
-class XR final : public EventTargetWithInlineData,
- public ContextLifecycleObserver,
- public device::mojom::blink::VRServiceClient,
- public FocusChangedObserver {
+// Implementation of the XRSystem interface according to
+// https://immersive-web.github.io/webxr/#xrsystem-interface . This is created
+// lazily via the NavigatorXR class on first access to the navigator.xr attrib,
+// and disposed when the execution context is destroyed or on mojo communication
+// errors with the browser/device process.
+//
+// When the XRSystem is used for promises, it uses query objects to store state
+// including the associated ScriptPromiseResolver. These query objects are owned
+// by the XRSystem and remain alive until the promise is resolved or rejected.
+// (See comments below for PendingSupportsSessionQuery and
+// PendingRequestSessionQuery.) These query objects are destroyed and any
+// outstanding promises rejected when the XRSystem is disposed.
+//
+// The XRSystem owns mojo connections with the Browser process through
+// VRService, used for capability queries and session lifetime
+// management. The XRSystem is also the receiver for the VRServiceClient.
+//
+// The XRSystem owns mojo connections with the Device process (either a
+// separate utility process, or implemented as part of the Browser process,
+// depending on the runtime and options) through XRFrameProvider and
+// XREnvironmentIntegrationProvider. These are used to transport per-frame data
+// such as image data and input poses. These are lazily created when first
+// needed for a sensor-backed session (all except sensorless inline sessions),
+// and destroyed when the XRSystem is disposed.
+//
+// The XRSystem keeps weak references to XRSession objects after they were
+// returned through a successful requestSession promise, but does not own them.
+class XRSystem final : public EventTargetWithInlineData,
+ public ExecutionContextLifecycleObserver,
+ public device::mojom::blink::VRServiceClient,
+ public FocusChangedObserver {
DEFINE_WRAPPERTYPEINFO();
- USING_GARBAGE_COLLECTED_MIXIN(XR);
+ USING_GARBAGE_COLLECTED_MIXIN(XRSystem);
public:
// TODO(crbug.com/976796): Fix lint errors.
- static XR* Create(LocalFrame& frame, int64_t source_id) {
- return MakeGarbageCollected<XR>(frame, source_id);
- }
-
- // TODO(crbug.com/976796): Fix lint errors.
- XR(LocalFrame& frame, int64_t ukm_source_id);
+ XRSystem(LocalFrame& frame, int64_t ukm_source_id);
DEFINE_ATTRIBUTE_EVENT_LISTENER(devicechange, kDevicechange)
@@ -71,9 +95,9 @@ class XR final : public EventTargetWithInlineData,
ExecutionContext* GetExecutionContext() const override;
const AtomicString& InterfaceName() const override;
- // ContextLifecycleObserver overrides.
- void ContextDestroyed(ExecutionContext*) override;
- void Trace(blink::Visitor*) override;
+ // ExecutionContextLifecycleObserver overrides.
+ void ContextDestroyed() override;
+ void Trace(Visitor*) override;
// FocusChangedObserver overrides.
void FocusedFrameChanged() override;
@@ -120,15 +144,16 @@ class XR final : public EventTargetWithInlineData,
bool invalid_features = false;
};
- // Encapsulates blink-side `XR::requestSession()` call. It is a wrapper around
- // ScriptPromiseResolver that allows us to add additional logic as certain
- // things related to promise's life cycle happen.
+ // Encapsulates blink-side `XRSystem::requestSession()` call. It is a wrapper
+ // around ScriptPromiseResolver that allows us to add additional logic as
+ // certain things related to promise's life cycle happen. Instances are owned
+ // by the XRSystem, see outstanding_request_queries_ below.
class PendingRequestSessionQuery final
: public GarbageCollected<PendingRequestSessionQuery> {
public:
PendingRequestSessionQuery(int64_t ukm_source_id,
ScriptPromiseResolver* resolver,
- XRSession::SessionMode mode,
+ device::mojom::blink::XRSessionMode mode,
RequestedXRSessionFeatureSet required_features,
RequestedXRSessionFeatureSet optional_features);
virtual ~PendingRequestSessionQuery() = default;
@@ -162,7 +187,7 @@ class XR final : public EventTargetWithInlineData,
void RejectWithTypeError(const String& message,
ExceptionState* exception_state);
- XRSession::SessionMode mode() const;
+ device::mojom::blink::XRSessionMode mode() const;
const XRSessionFeatureSet& RequiredFeatures() const;
const XRSessionFeatureSet& OptionalFeatures() const;
bool InvalidRequiredFeatures() const;
@@ -175,7 +200,12 @@ class XR final : public EventTargetWithInlineData,
// Returns underlying resolver's script state.
ScriptState* GetScriptState() const;
- virtual void Trace(blink::Visitor*);
+ void SetDOMOverlayElement(Element* element) {
+ dom_overlay_element_ = element;
+ }
+ Element* DOMOverlayElement() { return dom_overlay_element_; }
+
+ virtual void Trace(Visitor*);
private:
void ParseSensorRequirement();
@@ -189,27 +219,29 @@ class XR final : public EventTargetWithInlineData,
metrics_recorder = mojo::NullRemote());
Member<ScriptPromiseResolver> resolver_;
- const XRSession::SessionMode mode_;
+ const device::mojom::blink::XRSessionMode mode_;
RequestedXRSessionFeatureSet required_features_;
RequestedXRSessionFeatureSet optional_features_;
SensorRequirement sensor_requirement_ = SensorRequirement::kNone;
const int64_t ukm_source_id_;
+ Member<Element> dom_overlay_element_;
DISALLOW_COPY_AND_ASSIGN(PendingRequestSessionQuery);
};
static device::mojom::blink::XRSessionOptionsPtr XRSessionOptionsFromQuery(
const PendingRequestSessionQuery& query);
- // Encapsulates blink-side `XR::supportsSession()` call. It is a wrapper
- // around ScriptPromiseResolver that allows us to add additional logic as
- // certain things related to promise's life cycle happen.
+ // Encapsulates blink-side `XRSystem::isSessionSupported()` call. It is a
+ // wrapper around ScriptPromiseResolver that allows us to add additional logic
+ // as certain things related to promise's life cycle happen. Instances are
+ // owned by the XRSystem, see outstanding_support_queries_ below.
class PendingSupportsSessionQuery final
: public GarbageCollected<PendingSupportsSessionQuery> {
public:
PendingSupportsSessionQuery(ScriptPromiseResolver*,
- XRSession::SessionMode,
+ device::mojom::blink::XRSessionMode,
bool throw_on_unsupported);
virtual ~PendingSupportsSessionQuery() = default;
@@ -239,13 +271,13 @@ class XR final : public EventTargetWithInlineData,
bool ThrowOnUnsupported() const { return throw_on_unsupported_; }
- XRSession::SessionMode mode() const;
+ device::mojom::blink::XRSessionMode mode() const;
- virtual void Trace(blink::Visitor*);
+ virtual void Trace(Visitor*);
private:
Member<ScriptPromiseResolver> resolver_;
- const XRSession::SessionMode mode_;
+ const device::mojom::blink::XRSessionMode mode_;
// Only set when calling the deprecated supportsSession method.
const bool throw_on_unsupported_ = false;
@@ -253,6 +285,53 @@ class XR final : public EventTargetWithInlineData,
DISALLOW_COPY_AND_ASSIGN(PendingSupportsSessionQuery);
};
+ // Native event listener for fullscreen change / error events when starting an
+ // immersive-ar session that uses DOM Overlay mode. See
+ // OnRequestSessionReturned().
+ class OverlayFullscreenEventManager : public NativeEventListener {
+ public:
+ OverlayFullscreenEventManager(
+ XRSystem* xr,
+ XRSystem::PendingRequestSessionQuery*,
+ device::mojom::blink::RequestSessionResultPtr);
+ ~OverlayFullscreenEventManager() override;
+
+ // NativeEventListener
+ void Invoke(ExecutionContext*, Event*) override;
+
+ void RequestFullscreen();
+ void OnSessionStarting();
+
+ void Trace(Visitor*) override;
+
+ private:
+ Member<XRSystem> xr_;
+ Member<PendingRequestSessionQuery> query_;
+ device::mojom::blink::RequestSessionResultPtr result_;
+ DISALLOW_COPY_AND_ASSIGN(OverlayFullscreenEventManager);
+ };
+
+ // Native event listener used when waiting for fullscreen mode to fully exit
+ // when ending an XR session.
+ class OverlayFullscreenExitObserver : public NativeEventListener {
+ public:
+ OverlayFullscreenExitObserver(XRSystem* xr);
+ ~OverlayFullscreenExitObserver() override;
+
+ // NativeEventListener
+ void Invoke(ExecutionContext*, Event*) override;
+
+ void ExitFullscreen(Element* element, base::OnceClosure on_exited);
+
+ void Trace(Visitor*) override;
+
+ private:
+ Member<XRSystem> xr_;
+ Member<Element> element_;
+ base::OnceClosure on_exited_;
+ DISALLOW_COPY_AND_ASSIGN(OverlayFullscreenExitObserver);
+ };
+
ScriptPromise InternalIsSessionSupported(ScriptState*,
const String&,
ExceptionState& exception_state,
@@ -265,7 +344,8 @@ class XR final : public EventTargetWithInlineData,
RequestedXRSessionFeatureSet ParseRequestedFeatures(
Document* doc,
const HeapVector<ScriptValue>& features,
- const XRSession::SessionMode& session_mode,
+ const device::mojom::blink::XRSessionMode& session_mode,
+ XRSessionInit* session_init,
mojom::ConsoleMessageLevel error_level);
void RequestImmersiveSession(LocalFrame* frame,
@@ -277,11 +357,18 @@ class XR final : public EventTargetWithInlineData,
PendingRequestSessionQuery* query,
ExceptionState* exception_state);
+ void OnRequestSessionSetupForDomOverlay(
+ PendingRequestSessionQuery*,
+ device::mojom::blink::RequestSessionResultPtr result);
void OnRequestSessionReturned(
PendingRequestSessionQuery*,
device::mojom::blink::RequestSessionResultPtr result);
void OnSupportsSessionReturned(PendingSupportsSessionQuery*,
bool supports_session);
+ void ResolveSessionRequest(
+ PendingRequestSessionQuery*,
+ device::mojom::blink::RequestSessionResultPtr result);
+ void RejectSessionRequest(PendingRequestSessionQuery*);
void EnsureDevice();
void ReportImmersiveSupported(bool supported);
@@ -290,7 +377,7 @@ class XR final : public EventTargetWithInlineData,
RegisteredEventListener&) override;
XRSession* CreateSession(
- XRSession::SessionMode mode,
+ device::mojom::blink::XRSessionMode mode,
XRSession::EnvironmentBlendMode blend_mode,
mojo::PendingReceiver<device::mojom::blink::XRSessionClient>
client_receiver,
@@ -317,6 +404,8 @@ class XR final : public EventTargetWithInlineData,
const int64_t ukm_source_id_;
+ // The XR object owns outstanding pending session queries, these live until
+ // the underlying promise is either resolved or rejected.
HeapHashSet<Member<PendingSupportsSessionQuery>> outstanding_support_queries_;
HeapHashSet<Member<PendingRequestSessionQuery>> outstanding_request_queries_;
bool has_outstanding_immersive_request_ = false;
@@ -338,6 +427,15 @@ class XR final : public EventTargetWithInlineData,
FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle
feature_handle_for_scheduler_;
+ // In DOM overlay mode, use a fullscreen event listener to detect when
+ // transition to fullscreen mode completes or fails, and reject/resolve
+ // the pending request session promise accordingly.
+ Member<OverlayFullscreenEventManager> fullscreen_event_manager_;
+ // DOM overlay mode uses a separate temporary fullscreen event listener
+ // if it needs to wait for fullscreen mode to fully exit when ending
+ // the session.
+ Member<OverlayFullscreenExitObserver> fullscreen_exit_observer_;
+
// In DOM overlay mode, save and restore the FrameView background color.
Color original_base_background_color_;
@@ -346,4 +444,4 @@ class XR final : public EventTargetWithInlineData,
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_SYSTEM_H_
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr.idl b/chromium/third_party/blink/renderer/modules/xr/xr_system.idl
index 93aba883d87..31a25a05df6 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_system.idl
@@ -2,14 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// https://immersive-web.github.io/webxr/#xr-interface
+// https://immersive-web.github.io/webxr/#xrsystem-interface
[
SecureContext,
Exposed=Window,
RuntimeEnabled=WebXR
-] interface XR : EventTarget {
+] interface XRSystem : EventTarget {
attribute EventHandler ondevicechange;
[CallWith=ScriptState, DeprecateAs=XRSupportsSession, RaisesException] Promise<void> supportsSession(XRSessionMode mode);
[CallWith=ScriptState, MeasureAs=XRIsSessionSupported, RaisesException] Promise<boolean> isSessionSupported(XRSessionMode mode);
- [CallWith=ScriptState, MeasureAs=XRRequestSession, RaisesException] Promise<XRSession> requestSession(XRSessionMode mode, optional XRSessionInit options);
+ [CallWith=ScriptState, MeasureAs=XRRequestSession, RaisesException] Promise<XRSession> requestSession(XRSessionMode mode, optional XRSessionInit options = {});
};
+
+// For backwards compatibility with previous interface name.
+typedef XRSystem XR;
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 90eedcfd54b..72e84fae9a3 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
@@ -8,103 +8,53 @@
#include "third_party/blink/renderer/modules/xr/xr_input_source.h"
#include "third_party/blink/renderer/modules/xr/xr_pose.h"
+#include "third_party/blink/renderer/modules/xr/xr_session.h"
namespace blink {
XRTargetRaySpace::XRTargetRaySpace(XRSession* session, XRInputSource* source)
: XRSpace(session), input_source_(source) {}
-std::unique_ptr<TransformationMatrix> XRTargetRaySpace::OtherSpaceFromScreenTap(
- XRSpace* other_space,
- const TransformationMatrix& mojo_from_viewer) {
- // If the pointer origin is the screen, the input space is viewer space, and
- // we need the head's viewer pose and the pointer pose in continue. The
- // pointer transform will represent the point the canvas was clicked as an
- // offset from the view.
- if (!input_source_->InputFromPointer()) {
- return nullptr;
- }
-
- // other_from_pointer = other_from_input * input_from_pointer,
- // where input space is equivalent to viewer space for screen taps.
- std::unique_ptr<TransformationMatrix> other_from_pointer =
- other_space->SpaceFromViewer(mojo_from_viewer);
- if (!other_from_pointer) {
- return nullptr;
- }
- other_from_pointer->Multiply(*(input_source_->InputFromPointer()));
- return other_from_pointer;
-}
-
-std::unique_ptr<TransformationMatrix>
-XRTargetRaySpace::OtherSpaceFromTrackedPointer(
- XRSpace* other_space,
- const TransformationMatrix& mojo_from_viewer) {
- if (!input_source_->MojoFromInput()) {
- return nullptr;
- }
-
- // Calculate other_from_pointer = other_from_input * input_from_pointer
- std::unique_ptr<TransformationMatrix> other_from_pointer =
- other_space->SpaceFromInputForViewer(*(input_source_->MojoFromInput()),
- mojo_from_viewer);
-
- if (!other_from_pointer) {
- return nullptr;
- }
- if (input_source_->InputFromPointer()) {
- other_from_pointer->Multiply(*(input_source_->InputFromPointer()));
- }
- return other_from_pointer;
-}
-
-XRPose* XRTargetRaySpace::getPose(
- XRSpace* other_space,
- const TransformationMatrix* mojo_from_viewer) {
- // If we don't have a valid base pose (most common when tracking is lost),
- // we can't get a target ray pose regardless of the mode.
- if (!mojo_from_viewer) {
- DVLOG(2) << __func__ << " : mojo_from_viewer is null, returning nullptr";
- return nullptr;
- }
-
- std::unique_ptr<TransformationMatrix> other_from_ray = nullptr;
+std::unique_ptr<TransformationMatrix> XRTargetRaySpace::MojoFromNative() {
+ auto mojo_from_viewer = session()->MojoFromViewer();
switch (input_source_->TargetRayMode()) {
case device::mojom::XRTargetRayMode::TAPPING: {
- other_from_ray = OtherSpaceFromScreenTap(other_space, *mojo_from_viewer);
- break;
+ // If the pointer origin is the screen, we need mojo_from_viewer, as the
+ // viewer space is the input space.
+ // So our result will be mojo_from_viewer * viewer_from_pointer
+ if (!(mojo_from_viewer && input_source_->InputFromPointer()))
+ return nullptr;
+
+ return std::make_unique<TransformationMatrix>(
+ (*mojo_from_viewer * *(input_source_->InputFromPointer())));
}
case device::mojom::XRTargetRayMode::GAZING: {
- // If the pointer origin is the users head, this is a gaze cursor and the
- // returned pointer is based on the device pose. Just return the head pose
- // as the pointer pose.
- other_from_ray = other_space->SpaceFromViewer(*mojo_from_viewer);
- break;
+ // If the pointer origin is gaze, then the pointer offset is just
+ // mojo_from_viewer.
+ if (!mojo_from_viewer)
+ return nullptr;
+
+ return std::make_unique<TransformationMatrix>(*(mojo_from_viewer));
}
case device::mojom::XRTargetRayMode::POINTING: {
- other_from_ray =
- OtherSpaceFromTrackedPointer(other_space, *mojo_from_viewer);
- break;
+ // mojo_from_pointer is just: MojoFromInput*InputFromPointer;
+ if (!(input_source_->MojoFromInput() &&
+ input_source_->InputFromPointer()))
+ return nullptr;
+
+ return std::make_unique<TransformationMatrix>(
+ (*(input_source_->MojoFromInput()) *
+ *(input_source_->InputFromPointer())));
}
}
+}
- if (!other_from_ray) {
- DVLOG(2) << __func__ << " : "
- << "other_from_ray is null, input_source_->TargetRayMode() = "
- << input_source_->TargetRayMode();
- return nullptr;
- }
+std::unique_ptr<TransformationMatrix> XRTargetRaySpace::NativeFromMojo() {
+ return TryInvert(MojoFromNative());
+}
- // Account for any changes made to the reference space's origin offset so that
- // things like teleportation works.
- //
- // otheroffset_from_ray = otheroffset_from_other * other_from_ray
- // where otheroffset_from_other = inverse(other_from_otheroffset)
- // TODO(https://crbug.com/1008466): move originOffset to separate class?
- TransformationMatrix otheroffset_from_ray =
- other_space->InverseOriginOffsetMatrix().Multiply(*other_from_ray);
- return MakeGarbageCollected<XRPose>(otheroffset_from_ray,
- input_source_->emulatedPosition());
+bool XRTargetRaySpace::EmulatedPosition() const {
+ return input_source_->emulatedPosition();
}
base::Optional<XRNativeOriginInformation> XRTargetRaySpace::NativeOrigin()
@@ -112,7 +62,7 @@ base::Optional<XRNativeOriginInformation> XRTargetRaySpace::NativeOrigin()
return input_source_->nativeOrigin();
}
-void XRTargetRaySpace::Trace(blink::Visitor* visitor) {
+void XRTargetRaySpace::Trace(Visitor* visitor) {
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 8df09c58c8a..56d2d9302cb 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
@@ -14,21 +14,16 @@ namespace blink {
class XRTargetRaySpace : public XRSpace {
public:
XRTargetRaySpace(XRSession* session, XRInputSource* input_space);
- XRPose* getPose(XRSpace* other_space,
- const TransformationMatrix* base_pose_matrix) override;
+
+ std::unique_ptr<TransformationMatrix> MojoFromNative() override;
+ std::unique_ptr<TransformationMatrix> NativeFromMojo() override;
+ bool EmulatedPosition() const override;
base::Optional<XRNativeOriginInformation> NativeOrigin() const override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
- std::unique_ptr<TransformationMatrix> OtherSpaceFromScreenTap(
- XRSpace* other_space,
- const TransformationMatrix& mojo_from_viewer);
- std::unique_ptr<TransformationMatrix> OtherSpaceFromTrackedPointer(
- XRSpace* other_space,
- const TransformationMatrix& mojo_from_viewer);
-
Member<XRInputSource> input_source_;
};
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_test_utils.h b/chromium/third_party/blink/renderer/modules/xr/xr_test_utils.h
index da35d671c1f..6c28ad513ff 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_test_utils.h
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_test_utils.h
@@ -7,7 +7,7 @@
#include <memory>
-#include "third_party/blink/renderer/core/geometry/dom_point_init.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_dom_point_init.h"
#include "third_party/blink/renderer/core/geometry/dom_point_read_only.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_options_init.idl b/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_options_init.idl
index 10f35402f36..bc143ded892 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_options_init.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_options_init.idl
@@ -4,6 +4,6 @@
dictionary XRTransientInputHitTestOptionsInit {
required DOMString profile;
- FrozenArray<XRHitTestTrackableType> entityTypes;
+ [RuntimeEnabled=WebXRHitTestEntityTypes] FrozenArray<XRHitTestTrackableType> entityTypes;
XRRay offsetRay;
};
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 58fb9dbe243..9dd27ba1d84 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
@@ -15,8 +15,8 @@ XRTransientInputHitTestResult::XRTransientInputHitTestResult(
const Vector<device::mojom::blink::XRHitResultPtr>& results)
: input_source_(input_source) {
for (const auto& result : results) {
- results_.push_back(
- MakeGarbageCollected<XRHitTestResult>(result->hit_matrix.matrix()));
+ results_.push_back(MakeGarbageCollected<XRHitTestResult>(
+ input_source->session(), *result));
}
}
@@ -28,7 +28,7 @@ HeapVector<Member<XRHitTestResult>> XRTransientInputHitTestResult::results() {
return results_;
}
-void XRTransientInputHitTestResult::Trace(blink::Visitor* visitor) {
+void XRTransientInputHitTestResult::Trace(Visitor* visitor) {
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 03fa4ab722f..a6e82790c22 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(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) 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 0afafb68371..a457b32210b 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
@@ -60,9 +60,12 @@ void XRTransientInputHitTestSource::Update(
if (!input_source)
continue;
- current_frame_results_.push_back(
- MakeGarbageCollected<XRTransientInputHitTestResult>(
- input_source, source_id_and_results.value));
+ // If the input source is not visible, ignore it.
+ if (input_source->IsVisible()) {
+ current_frame_results_.push_back(
+ MakeGarbageCollected<XRTransientInputHitTestResult>(
+ input_source, source_id_and_results.value));
+ }
}
}
@@ -71,7 +74,7 @@ XRTransientInputHitTestSource::Results() {
return current_frame_results_;
}
-void XRTransientInputHitTestSource::Trace(blink::Visitor* visitor) {
+void XRTransientInputHitTestSource::Trace(Visitor* visitor) {
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 6a25fc1d008..e23ea2dca20 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
HeapVector<Member<XRTransientInputHitTestResult>> current_frame_results_;
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 35a1381ce3b..6814178a009 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_view.cc
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_view.cc
@@ -34,8 +34,7 @@ XRSession* XRView::session() const {
}
DOMFloat32Array* XRView::projectionMatrix() const {
- if (!projection_matrix_ || !projection_matrix_->View() ||
- !projection_matrix_->View()->Data()) {
+ if (!projection_matrix_ || !projection_matrix_->Data()) {
// A page may take the projection matrix value and detach it so
// projection_matrix_ is a detached array buffer. This breaks the
// inspector, so return null instead.
@@ -142,7 +141,7 @@ XRRigidTransform* XRView::transform() const {
return ref_space_from_eye_;
}
-void XRView::Trace(blink::Visitor* visitor) {
+void XRView::Trace(Visitor* visitor) {
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 b89cdd0068f..4c20b54ca50 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 fc98618cec6..52b71f98fb1 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
@@ -13,6 +13,8 @@ namespace blink {
XRViewerPose::XRViewerPose(XRSession* session,
const TransformationMatrix& pose_model_matrix)
: XRPose(pose_model_matrix, session->EmulatedPosition()) {
+ DVLOG(3) << __func__ << ": emulatedPosition()=" << emulatedPosition();
+
Vector<XRViewData>& view_data = session->views();
// Snapshot the session's current views.
@@ -22,7 +24,7 @@ XRViewerPose::XRViewerPose(XRSession* session,
}
}
-void XRViewerPose::Trace(blink::Visitor* visitor) {
+void XRViewerPose::Trace(Visitor* visitor) {
visitor->Trace(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 652335f408e..04527284430 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
@@ -23,7 +23,7 @@ class XRViewerPose final : public XRPose {
const HeapVector<Member<XRView>>& views() const { return views_; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
HeapVector<Member<XRView>> views_;
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 064dc8f5ce7..d72ffdd38a1 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
@@ -4,13 +4,15 @@
#include "third_party/blink/renderer/modules/xr/xr_webgl_layer.h"
+#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
+#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h"
#include "third_party/blink/renderer/modules/webgl/webgl_framebuffer.h"
#include "third_party/blink/renderer/modules/webgl/webgl_rendering_context.h"
-#include "third_party/blink/renderer/modules/xr/xr.h"
#include "third_party/blink/renderer/modules/xr/xr_frame_provider.h"
#include "third_party/blink/renderer/modules/xr/xr_session.h"
+#include "third_party/blink/renderer/modules/xr/xr_system.h"
#include "third_party/blink/renderer/modules/xr/xr_view.h"
#include "third_party/blink/renderer/modules/xr/xr_viewport.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -23,6 +25,12 @@ namespace blink {
namespace {
const double kFramebufferMinScale = 0.2;
+const uint32_t kCleanFrameWarningLimit = 5;
+
+const char kCleanFrameWarning[] =
+ "Note: The XRSession has completed multiple animation frames without "
+ "drawing anything to the baseLayer's framebuffer, resulting in no visible "
+ "output.";
// Because including base::ClampToRange would be a dependency violation
double ClampToRange(const double value, const double min, const double max) {
@@ -121,7 +129,8 @@ XRWebGLLayer* XRWebGLLayer::Create(
framebuffers_size.Height() * framebuffer_scale);
// Create an opaque WebGL Framebuffer
- WebGLFramebuffer* framebuffer = WebGLFramebuffer::CreateOpaque(webgl_context);
+ WebGLFramebuffer* framebuffer =
+ WebGLFramebuffer::CreateOpaque(webgl_context, want_stencil_buffer);
scoped_refptr<XRWebGLDrawingBuffer> drawing_buffer =
XRWebGLDrawingBuffer::Create(webgl_context->GetDrawingBuffer(),
@@ -273,9 +282,31 @@ void XRWebGLLayer::OnFrameEnd() {
// Submit the frame to the XR compositor.
if (session()->immersive()) {
+ bool framebuffer_dirty = framebuffer_->HaveContentsChanged();
+
+ // Not drawing to the framebuffer during a session's rAF callback is
+ // usually a sign that something is wrong, such as the app drawing to the
+ // wrong render target. Show a warning in the console if we see that
+ // happen too many times.
+ 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()->MojoFromViewer();
+ if (frame_had_pose) {
+ clean_frame_count++;
+ if (clean_frame_count == kCleanFrameWarningLimit) {
+ session()->xr()->GetExecutionContext()->AddConsoleMessage(
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kRendering,
+ mojom::blink::ConsoleMessageLevel::kWarning,
+ kCleanFrameWarning));
+ }
+ }
+ }
+
// Always call submit, but notify if the contents were changed or not.
- session()->xr()->frameProvider()->SubmitWebGLLayer(
- this, framebuffer_->HaveContentsChanged());
+ session()->xr()->frameProvider()->SubmitWebGLLayer(this,
+ framebuffer_dirty);
}
}
}
@@ -296,15 +327,14 @@ void XRWebGLLayer::OnResize() {
viewports_dirty_ = true;
}
-scoped_refptr<StaticBitmapImage> XRWebGLLayer::TransferToStaticBitmapImage(
- std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback) {
+scoped_refptr<StaticBitmapImage> XRWebGLLayer::TransferToStaticBitmapImage() {
if (drawing_buffer_) {
- return drawing_buffer_->TransferToStaticBitmapImage(out_release_callback);
+ return drawing_buffer_->TransferToStaticBitmapImage();
}
return nullptr;
}
-void XRWebGLLayer::Trace(blink::Visitor* visitor) {
+void XRWebGLLayer::Trace(Visitor* visitor) {
visitor->Trace(session_);
visitor->Trace(left_viewport_);
visitor->Trace(right_viewport_);
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 24765b01072..03db1338571 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
@@ -5,11 +5,11 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_WEBGL_LAYER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_WEBGL_LAYER_H_
+#include "third_party/blink/renderer/bindings/modules/v8/v8_xr_webgl_layer_init.h"
#include "third_party/blink/renderer/bindings/modules/v8/webgl_rendering_context_or_webgl2_rendering_context.h"
#include "third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h"
#include "third_party/blink/renderer/modules/webgl/webgl_rendering_context.h"
#include "third_party/blink/renderer/modules/xr/xr_view.h"
-#include "third_party/blink/renderer/modules/xr/xr_webgl_layer_init.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.h"
#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
@@ -74,10 +74,9 @@ class XRWebGLLayer final : public ScriptWrappable {
// mailbox holder and its size respectively.
void HandleBackgroundImage(const gpu::MailboxHolder&, const IntSize&) {}
- scoped_refptr<StaticBitmapImage> TransferToStaticBitmapImage(
- std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback);
+ scoped_refptr<StaticBitmapImage> TransferToStaticBitmapImage();
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
const Member<XRSession> session_;
@@ -93,6 +92,8 @@ class XRWebGLLayer final : public ScriptWrappable {
bool viewports_dirty_ = true;
bool is_direct_draw_frame = false;
bool ignore_depth_values_ = false;
+
+ uint32_t clean_frame_count = 0;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.idl b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.idl
index 879c476b6e0..1f9e3af5286 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.idl
@@ -8,11 +8,9 @@ typedef (WebGLRenderingContext or WebGL2RenderingContext) XRWebGLRenderingContex
[
SecureContext,
Exposed=Window,
- RuntimeEnabled=WebXR,
- Constructor(XRSession session, XRWebGLRenderingContext context, optional XRWebGLLayerInit layerInit),
- RaisesException=Constructor,
- Measure
+ RuntimeEnabled=WebXR
] interface XRWebGLLayer {
+ [RaisesException, Measure] constructor(XRSession session, XRWebGLRenderingContext context, optional XRWebGLLayerInit layerInit = {});
readonly attribute boolean antialias;
readonly attribute boolean ignoreDepthValues;
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 9ac798dd713..02dff332be9 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
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/modules/xr/xr_world_information.h"
#include "base/trace_event/trace_event.h"
+#include "third_party/blink/renderer/modules/xr/xr_light_estimation.h"
#include "third_party/blink/renderer/modules/xr/xr_session.h"
namespace blink {
@@ -12,8 +13,9 @@ namespace blink {
XRWorldInformation::XRWorldInformation(XRSession* session)
: session_(session) {}
-void XRWorldInformation::Trace(blink::Visitor* visitor) {
+void XRWorldInformation::Trace(Visitor* visitor) {
visitor->Trace(plane_ids_to_planes_);
+ visitor->Trace(light_estimation_);
visitor->Trace(session_);
ScriptWrappable::Trace(visitor);
}
@@ -33,8 +35,12 @@ XRPlaneSet* XRWorldInformation::detectedPlanes() const {
return MakeGarbageCollected<XRPlaneSet>(result);
}
+XRLightEstimation* XRWorldInformation::lightEstimation() const {
+ return light_estimation_.Get();
+}
+
void XRWorldInformation::ProcessPlaneInformation(
- const device::mojom::blink::XRPlaneDetectionDataPtr& detected_planes_data,
+ const device::mojom::blink::XRPlaneDetectionData* detected_planes_data,
double timestamp) {
TRACE_EVENT0("xr", __FUNCTION__);
@@ -64,14 +70,16 @@ void XRWorldInformation::ProcessPlaneInformation(
// First, process all planes that had their information updated (new planes
// are also processed here).
for (const auto& plane : detected_planes_data->updated_planes_data) {
+ DCHECK(plane);
+
auto it = plane_ids_to_planes_.find(plane->id);
if (it != plane_ids_to_planes_.end()) {
updated_planes.insert(plane->id, it->value);
- it->value->Update(plane, timestamp);
+ it->value->Update(*plane, timestamp);
} else {
updated_planes.insert(
- plane->id,
- MakeGarbageCollected<XRPlane>(plane->id, session_, plane, timestamp));
+ plane->id, MakeGarbageCollected<XRPlane>(plane->id, session_, *plane,
+ timestamp));
}
}
@@ -91,4 +99,16 @@ void XRWorldInformation::ProcessPlaneInformation(
plane_ids_to_planes_.swap(updated_planes);
}
+void XRWorldInformation::ProcessLightEstimationData(
+ const device::mojom::blink::XRLightEstimationData* data,
+ double timestamp) {
+ TRACE_EVENT0("xr", __FUNCTION__);
+
+ if (data) {
+ light_estimation_ = MakeGarbageCollected<XRLightEstimation>(*data);
+ } else {
+ light_estimation_ = nullptr;
+ }
+}
+
} // namespace blink
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 d39ee9a0699..05ec44afcb6 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
@@ -11,6 +11,7 @@
namespace blink {
+class XRLightEstimation;
class XRSession;
class XRWorldInformation : public ScriptWrappable {
@@ -23,13 +24,19 @@ class XRWorldInformation : public ScriptWrappable {
// disabled.
XRPlaneSet* detectedPlanes() const;
- void Trace(blink::Visitor* visitor) override;
+ XRLightEstimation* lightEstimation() const;
+
+ void Trace(Visitor* visitor) override;
// Applies changes to the stored plane information based on the contents of
// the received frame data. This will update the contents of
// plane_ids_to_planes_.
void ProcessPlaneInformation(
- const device::mojom::blink::XRPlaneDetectionDataPtr& detected_planes_data,
+ const device::mojom::blink::XRPlaneDetectionData* detected_planes_data,
+ double timestamp);
+
+ void ProcessLightEstimationData(
+ const device::mojom::blink::XRLightEstimationData* data,
double timestamp);
private:
@@ -39,6 +46,8 @@ class XRWorldInformation : public ScriptWrappable {
bool is_detected_planes_null_ = true;
HeapHashMap<uint64_t, Member<XRPlane>> plane_ids_to_planes_;
+ Member<XRLightEstimation> light_estimation_;
+
Member<XRSession> session_;
};
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 7aa695098d9..64ad2fabd19 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,9 +7,10 @@
[
SecureContext,
Exposed=Window,
- RuntimeEnabled=WebXRPlaneDetection
+ RuntimeEnabled=WebXRIncubations
]
interface XRWorldInformation {
readonly attribute XRPlaneSet? detectedPlanes;
+ readonly attribute XRLightEstimation? lightEstimation;
};
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 53679567bcf..f545a4d3842 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
@@ -3,8 +3,12 @@
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/xr/xr_world_tracking_state.h"
+
+#include "third_party/blink/renderer/bindings/modules/v8/v8_xr_light_estimation_state_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_xr_plane_detection_state_init.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_xr_world_tracking_state_init.h"
+#include "third_party/blink/renderer/modules/xr/xr_light_estimation_state.h"
#include "third_party/blink/renderer/modules/xr/xr_plane_detection_state.h"
-#include "third_party/blink/renderer/modules/xr/xr_world_tracking_state_init.h"
namespace blink {
@@ -15,12 +19,23 @@ XRWorldTrackingState::XRWorldTrackingState(
plane_detection_state_ = MakeGarbageCollected<XRPlaneDetectionState>(
world_tracking_state_init->planeDetectionState());
} else {
- plane_detection_state_ = MakeGarbageCollected<XRPlaneDetectionState>();
+ plane_detection_state_ =
+ MakeGarbageCollected<XRPlaneDetectionState>(nullptr);
+ }
+
+ if (world_tracking_state_init &&
+ world_tracking_state_init->hasLightEstimationState()) {
+ light_estimation_state_ = MakeGarbageCollected<XRLightEstimationState>(
+ world_tracking_state_init->lightEstimationState());
+ } else {
+ light_estimation_state_ =
+ MakeGarbageCollected<XRLightEstimationState>(nullptr);
}
}
-void XRWorldTrackingState::Trace(blink::Visitor* visitor) {
+void XRWorldTrackingState::Trace(Visitor* visitor) {
visitor->Trace(plane_detection_state_);
+ visitor->Trace(light_estimation_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 87625a8cda7..425542d1803 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
@@ -7,12 +7,12 @@
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
-#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
class XRPlaneDetectionState;
+class XRLightEstimationState;
class XRWorldTrackingStateInit;
class XRWorldTrackingState : public ScriptWrappable {
@@ -26,10 +26,15 @@ class XRWorldTrackingState : public ScriptWrappable {
return plane_detection_state_;
}
- void Trace(blink::Visitor* visitor) override;
+ XRLightEstimationState* lightEstimationState() const {
+ return light_estimation_state_;
+ }
+
+ void Trace(Visitor* visitor) override;
private:
Member<XRPlaneDetectionState> plane_detection_state_;
+ Member<XRLightEstimationState> light_estimation_state_;
};
} // namespace blink
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 070ee061f96..b637518c578 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,9 +7,10 @@
[
SecureContext,
Exposed=Window,
- RuntimeEnabled=WebXRPlaneDetection
+ RuntimeEnabled=WebXRIncubations
]
interface XRWorldTrackingState {
readonly attribute XRPlaneDetectionState planeDetectionState;
+ readonly attribute XRLightEstimationState lightEstimationState;
};
diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state_init.idl b/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state_init.idl
index f8fd6bb64cf..2217591fd84 100644
--- a/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state_init.idl
+++ b/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state_init.idl
@@ -6,5 +6,6 @@
// https://github.com/immersive-web/real-world-geometry/blob/master/plane-detection-explainer.md
dictionary XRWorldTrackingStateInit {
XRPlaneDetectionStateInit planeDetectionState;
+ XRLightEstimationStateInit lightEstimationState;
};
diff --git a/chromium/third_party/blink/renderer/platform/BUILD.gn b/chromium/third_party/blink/renderer/platform/BUILD.gn
index 2cdb42f959b..6658b51a7d0 100644
--- a/chromium/third_party/blink/renderer/platform/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/BUILD.gn
@@ -4,6 +4,7 @@
import("//build/buildflag_header.gni")
import("//build/compiled_action.gni")
+import("//build/config/compiler/compiler.gni")
import("//build/config/features.gni")
import("//build/config/jumbo.gni")
import("//build/config/ui.gni")
@@ -66,14 +67,10 @@ blink_python_runner("color_data") {
script = "../build/scripts/gperf.py"
color_data_gperf = "color_data.gperf"
- inputs = [
- color_data_gperf,
- ]
+ inputs = [ color_data_gperf ]
output_file = "$blink_platform_output_dir/color_data.cc"
- outputs = [
- output_file,
- ]
+ outputs = [ output_file ]
args = [
gperf_exe,
@@ -88,9 +85,7 @@ blink_python_runner("color_data") {
compiled_action("character_data") {
tool = ":character_data_generator"
- outputs = [
- "$blink_platform_output_dir/character_property_data.cc",
- ]
+ outputs = [ "$blink_platform_output_dir/character_property_data.cc" ]
args = rebase_path(outputs, root_build_dir)
}
@@ -150,6 +145,7 @@ group("blink_platform_public_deps") {
"//gpu/command_buffer/client:client",
"//gpu/command_buffer/client:gles2_interface",
"//gpu/command_buffer/common:common",
+ "//gpu/command_buffer/common:gles2_utils",
"//net",
"//services/device/public/mojom:generic_sensor_blink",
"//services/device/public/mojom:mojom_blink",
@@ -185,6 +181,9 @@ group("blink_platform_public_deps") {
declare_args() {
runtime_call_stats_count_everything = false
+
+ # Enable TRACE_EVENT instrumentation for Blink bindings. Disabled by default as it increases binary size.
+ enable_blink_bindings_tracing = false
}
buildflag_header("bindings_buildflags") {
@@ -192,8 +191,9 @@ buildflag_header("bindings_buildflags") {
header_dir = "third_party/blink/renderer/platform/bindings"
flags = [
- "RAW_HEAP_SNAPSHOTS=$v8_enable_raw_heap_snapshots",
+ "RAW_HEAP_SNAPSHOTS=$enable_additional_blink_object_names",
"RCS_COUNT_EVERYTHING=$runtime_call_stats_count_everything",
+ "BLINK_BINDINGS_TRACE_ENABLED=$enable_blink_bindings_tracing",
]
}
@@ -225,9 +225,7 @@ config("blink_platform_pch") {
}
source_set("platform_export") {
- sources = [
- "platform_export.h",
- ]
+ sources = [ "platform_export.h" ]
visibility = [] # Allow re-assignment of list.
visibility = [
@@ -362,8 +360,6 @@ jumbo_component("platform") {
"audio/mac/vector_math_mac.h",
"audio/media_multi_channel_resampler.cc",
"audio/media_multi_channel_resampler.h",
- "audio/multi_channel_resampler.cc",
- "audio/multi_channel_resampler.h",
"audio/panner.cc",
"audio/panner.h",
"audio/pffft/fft_frame_pffft.cc",
@@ -394,6 +390,8 @@ jumbo_component("platform") {
"bindings/active_script_wrappable_base.h",
"bindings/binding_security_for_platform.cc",
"bindings/binding_security_for_platform.h",
+ "bindings/blink_isolate/blink_isolate.cc",
+ "bindings/blink_isolate/blink_isolate.h",
"bindings/callback_function_base.cc",
"bindings/callback_function_base.h",
"bindings/callback_interface_base.cc",
@@ -406,6 +404,7 @@ jumbo_component("platform") {
"bindings/dom_data_store.h",
"bindings/dom_wrapper_world.cc",
"bindings/dom_wrapper_world.h",
+ "bindings/enumeration_base.h",
"bindings/exception_code.h",
"bindings/exception_messages.cc",
"bindings/exception_messages.h",
@@ -430,7 +429,6 @@ jumbo_component("platform") {
"bindings/script_state.h",
"bindings/script_wrappable.cc",
"bindings/script_wrappable.h",
- "bindings/shared_persistent.h",
"bindings/string_resource.cc",
"bindings/string_resource.h",
"bindings/to_v8.h",
@@ -438,17 +436,21 @@ jumbo_component("platform") {
"bindings/trace_wrapper_v8_reference.h",
"bindings/trace_wrapper_v8_string.cc",
"bindings/trace_wrapper_v8_string.h",
+ "bindings/union_base.h",
"bindings/v0_custom_element_binding.cc",
"bindings/v0_custom_element_binding.h",
"bindings/v8_binding.cc",
"bindings/v8_binding.h",
"bindings/v8_binding_macros.h",
"bindings/v8_cross_origin_callback_info.h",
+ "bindings/v8_cross_origin_property_support.cc",
+ "bindings/v8_cross_origin_property_support.h",
"bindings/v8_dom_activity_logger.cc",
"bindings/v8_dom_activity_logger.h",
"bindings/v8_dom_wrapper.cc",
"bindings/v8_dom_wrapper.h",
"bindings/v8_global_value_map.h",
+ "bindings/v8_interface_bridge.h",
"bindings/v8_object_constructor.cc",
"bindings/v8_object_constructor.h",
"bindings/v8_per_context_data.cc",
@@ -457,6 +459,8 @@ jumbo_component("platform") {
"bindings/v8_per_isolate_data.h",
"bindings/v8_private_property.cc",
"bindings/v8_private_property.h",
+ "bindings/v8_set_return_value.cc",
+ "bindings/v8_set_return_value.h",
"bindings/v8_throw_exception.cc",
"bindings/v8_throw_exception.h",
"bindings/v8_value_cache.cc",
@@ -466,6 +470,9 @@ jumbo_component("platform") {
"bindings/wrapper_type_info.cc",
"bindings/wrapper_type_info.h",
"content_decryption_module_result.h",
+ "context_lifecycle_notifier.h",
+ "context_lifecycle_observer.cc",
+ "context_lifecycle_observer.h",
"cookie/canonical_cookie.cc",
"cookie/canonical_cookie.h",
"cookie/canonical_cookie_mojom_traits.cc",
@@ -474,13 +481,14 @@ jumbo_component("platform") {
"crypto.cc",
"crypto.h",
"crypto_result.h",
- "cursor.cc",
- "cursor.h",
+ "cursors.cc",
+ "cursors.h",
"data_resource_helper.cc",
"data_resource_helper.h",
+ "disk_data_allocator.cc",
+ "disk_data_allocator.h",
"exported/file_path_conversion.cc",
"exported/interface_registry.cc",
- "exported/mediastream/media_stream_audio_track.cc",
"exported/mediastream/web_media_element_source_utils.cc",
"exported/mediastream/web_platform_media_stream_source.cc",
"exported/mediastream/web_platform_media_stream_track.cc",
@@ -500,21 +508,19 @@ jumbo_component("platform") {
"exported/web_crypto_key.cc",
"exported/web_crypto_key_algorithm.cc",
"exported/web_crypto_result.cc",
- "exported/web_cursor_info.cc",
"exported/web_data.cc",
"exported/web_drag_data.cc",
"exported/web_encrypted_media_client.cc",
"exported/web_encrypted_media_key_information.cc",
"exported/web_encrypted_media_request.cc",
+ "exported/web_failing_url_loader_factory.cc",
"exported/web_font.cc",
"exported/web_font_description.cc",
- "exported/web_gesture_event.cc",
"exported/web_http_body.cc",
"exported/web_http_load_info.cc",
"exported/web_icon_sizes_parser.cc",
"exported/web_image_generator.cc",
- "exported/web_input_event.cc",
- "exported/web_media_constraints.cc",
+ "exported/web_isolate.cc",
"exported/web_media_player_client.cc",
"exported/web_media_player_encrypted_media_client.cc",
"exported/web_media_player_source.cc",
@@ -524,15 +530,7 @@ jumbo_component("platform") {
"exported/web_media_stream_track.cc",
"exported/web_memory_pressure_listener.cc",
"exported/web_mixed_content.cc",
- "exported/web_mouse_event.cc",
- "exported/web_mouse_wheel_event.cc",
"exported/web_network_state_notifier.cc",
- "exported/web_pointer_event.cc",
- "exported/web_prerender.cc",
- "exported/web_prerendering_support.cc",
- "exported/web_resource_timing_info.cc",
- "exported/web_rtc_peer_connection_handler_client.cc",
- "exported/web_rtc_stats.cc",
"exported/web_runtime_features.cc",
"exported/web_security_origin.cc",
"exported/web_string.cc",
@@ -541,10 +539,8 @@ jumbo_component("platform") {
"exported/web_text_run.cc",
"exported/web_thread_safe_data.cc",
"exported/web_time_range.cc",
- "exported/web_touch_event.cc",
"exported/web_url.cc",
"exported/web_url_error.cc",
- "exported/web_url_load_timing.cc",
"exported/web_url_loader_client.cc",
"exported/web_url_loader_test_delegate.cc",
"exported/web_url_request.cc",
@@ -643,6 +639,9 @@ jumbo_component("platform") {
"fonts/opentype/open_type_caps_support.cc",
"fonts/opentype/open_type_caps_support.h",
"fonts/opentype/open_type_caps_support_mpl.cc",
+ "fonts/opentype/open_type_math_stretch_data.h",
+ "fonts/opentype/open_type_math_support.cc",
+ "fonts/opentype/open_type_math_support.h",
"fonts/opentype/open_type_types.h",
"fonts/opentype/open_type_vertical_data.cc",
"fonts/opentype/open_type_vertical_data.h",
@@ -684,6 +683,8 @@ jumbo_component("platform") {
"fonts/shaping/shape_result_view.h",
"fonts/shaping/shaping_line_breaker.cc",
"fonts/shaping/shaping_line_breaker.h",
+ "fonts/shaping/stretchy_operator_shaper.cc",
+ "fonts/shaping/stretchy_operator_shaper.h",
"fonts/simple_font_data.cc",
"fonts/simple_font_data.h",
"fonts/skia/font_cache_skia.cc",
@@ -719,8 +720,6 @@ jumbo_component("platform") {
"fonts/win/dwrite_font_format_support.h",
"fonts/win/fallback_family_style_cache_win.cc",
"fonts/win/fallback_family_style_cache_win.h",
- "fonts/win/fallback_lru_cache_win.cc",
- "fonts/win/fallback_lru_cache_win.h",
"fonts/win/font_cache_skia_win.cc",
"fonts/win/font_fallback_win.cc",
"fonts/win/font_fallback_win.h",
@@ -951,6 +950,8 @@ jumbo_component("platform") {
"graphics/gpu/shared_gpu_context.h",
"graphics/gpu/webgl_image_conversion.cc",
"graphics/gpu/webgl_image_conversion.h",
+ "graphics/gpu/webgpu_image_bitmap_handler.cc",
+ "graphics/gpu/webgpu_image_bitmap_handler.h",
"graphics/gpu/webgpu_swap_buffer_provider.cc",
"graphics/gpu/webgpu_swap_buffer_provider.h",
"graphics/gpu/xr_frame_transport.cc",
@@ -974,8 +975,6 @@ jumbo_component("platform") {
"graphics/graphics_types.cc",
"graphics/graphics_types.h",
"graphics/graphics_types_3d.h",
- "graphics/hit_test_rect.cc",
- "graphics/hit_test_rect.h",
"graphics/image.cc",
"graphics/image.h",
"graphics/image_animation_policy.h",
@@ -1000,10 +999,12 @@ jumbo_component("platform") {
"graphics/lab_color_space.h",
"graphics/logging_canvas.cc",
"graphics/logging_canvas.h",
- "graphics/mailbox_texture_holder.cc",
- "graphics/mailbox_texture_holder.h",
"graphics/main_thread_mutator_client.cc",
"graphics/main_thread_mutator_client.h",
+ "graphics/memory_managed_paint_canvas.cc",
+ "graphics/memory_managed_paint_canvas.h",
+ "graphics/memory_managed_paint_recorder.cc",
+ "graphics/memory_managed_paint_recorder.h",
"graphics/mutator_client.h",
"graphics/offscreen_canvas_placeholder.cc",
"graphics/offscreen_canvas_placeholder.h",
@@ -1035,10 +1036,10 @@ jumbo_component("platform") {
"graphics/paint/geometry_mapper_clip_cache.h",
"graphics/paint/geometry_mapper_transform_cache.cc",
"graphics/paint/geometry_mapper_transform_cache.h",
+ "graphics/paint/graphics_layer_display_item.cc",
+ "graphics/paint/graphics_layer_display_item.h",
"graphics/paint/hit_test_data.cc",
"graphics/paint/hit_test_data.h",
- "graphics/paint/hit_test_display_item.cc",
- "graphics/paint/hit_test_display_item.h",
"graphics/paint/paint_artifact.cc",
"graphics/paint/paint_artifact.h",
"graphics/paint/paint_canvas.h",
@@ -1067,9 +1068,8 @@ jumbo_component("platform") {
"graphics/paint/raster_invalidator.h",
"graphics/paint/ref_counted_property_tree_state.h",
"graphics/paint/scoped_display_item_fragment.h",
+ "graphics/paint/scoped_paint_chunk_hint.h",
"graphics/paint/scoped_paint_chunk_properties.h",
- "graphics/paint/scroll_hit_test_display_item.cc",
- "graphics/paint/scroll_hit_test_display_item.h",
"graphics/paint/scroll_paint_property_node.cc",
"graphics/paint/scroll_paint_property_node.h",
"graphics/paint/scrollbar_display_item.cc",
@@ -1111,8 +1111,6 @@ jumbo_component("platform") {
"graphics/skia/sk_size_hash.h",
"graphics/skia/skia_utils.cc",
"graphics/skia/skia_utils.h",
- "graphics/skia_texture_holder.cc",
- "graphics/skia_texture_holder.h",
"graphics/squashing_disallowed_reasons.cc",
"graphics/squashing_disallowed_reasons.h",
"graphics/static_bitmap_image.cc",
@@ -1123,8 +1121,9 @@ jumbo_component("platform") {
"graphics/subtree_paint_property_update_reason.h",
"graphics/surface_layer_bridge.cc",
"graphics/surface_layer_bridge.h",
- "graphics/texture_holder.h",
"graphics/touch_action.h",
+ "graphics/touch_action_rect.cc",
+ "graphics/touch_action_rect.h",
"graphics/unaccelerated_static_bitmap_image.cc",
"graphics/unaccelerated_static_bitmap_image.h",
"graphics/video_frame_resource_provider.cc",
@@ -1133,6 +1132,7 @@ jumbo_component("platform") {
"graphics/video_frame_submitter.h",
"graphics/web_graphics_context_3d_provider_wrapper.cc",
"graphics/web_graphics_context_3d_provider_wrapper.h",
+ "heap_observer_list.h",
"image-decoders/bmp/bmp_image_decoder.cc",
"image-decoders/bmp/bmp_image_decoder.h",
"image-decoders/bmp/bmp_image_reader.cc",
@@ -1171,8 +1171,6 @@ jumbo_component("platform") {
"keyboard_codes.h",
"language.cc",
"language.h",
- "lifecycle_notifier.h",
- "lifecycle_observer.h",
"link_hash.cc",
"link_hash.h",
"mac/block_exceptions.h",
@@ -1185,6 +1183,7 @@ jumbo_component("platform") {
"mac/local_current_graphics_context.mm",
"mac/web_core_ns_cell_extras.h",
"mac/web_core_ns_cell_extras.mm",
+ "media/web_audio_source_provider_client.h",
"media/webaudiosourceprovider_impl.cc",
"media_capabilities/web_audio_configuration.h",
"media_capabilities/web_media_capabilities_info.h",
@@ -1194,12 +1193,17 @@ jumbo_component("platform") {
"mediastream/aec_dump_agent_impl.h",
"mediastream/audio_service_audio_processor_proxy.cc",
"mediastream/audio_service_audio_processor_proxy.h",
+ "mediastream/media_constraints.cc",
+ "mediastream/media_constraints.h",
+ "mediastream/media_stream_audio_deliverer.h",
"mediastream/media_stream_audio_level_calculator.cc",
"mediastream/media_stream_audio_level_calculator.h",
"mediastream/media_stream_audio_processor_options.cc",
"mediastream/media_stream_audio_processor_options.h",
"mediastream/media_stream_audio_source.cc",
"mediastream/media_stream_audio_source.h",
+ "mediastream/media_stream_audio_track.cc",
+ "mediastream/media_stream_audio_track.h",
"mediastream/media_stream_component.cc",
"mediastream/media_stream_component.h",
"mediastream/media_stream_descriptor.cc",
@@ -1208,6 +1212,7 @@ jumbo_component("platform") {
"mediastream/media_stream_source.h",
"mediastream/media_stream_web_audio_source.cc",
"mediastream/media_stream_web_audio_source.h",
+ "mediastream/webaudio_destination_consumer.h",
"mediastream/webaudio_media_stream_source.cc",
"mediastream/webaudio_media_stream_source.h",
"mediastream/webrtc_uma_histograms.cc",
@@ -1225,6 +1230,11 @@ jumbo_component("platform") {
"mojo/bluetooth_mojom_traits.cc",
"mojo/bluetooth_mojom_traits.h",
"mojo/fetch_api_request_headers_mojom_traits.h",
+ "mojo/heap_mojo_receiver.h",
+ "mojo/heap_mojo_receiver_set.h",
+ "mojo/heap_mojo_remote.h",
+ "mojo/heap_mojo_unique_receiver_set.h",
+ "mojo/heap_mojo_wrapper_mode.h",
"mojo/kurl_mojom_traits.h",
"mojo/mojo_helper.h",
"mojo/security_origin_mojom_traits.h",
@@ -1260,6 +1270,10 @@ jumbo_component("platform") {
"peerconnection/rtc_api_name.h",
"peerconnection/rtc_dtmf_sender_handler.cc",
"peerconnection/rtc_dtmf_sender_handler.h",
+ "peerconnection/rtc_encoded_audio_stream_transformer.cc",
+ "peerconnection/rtc_encoded_audio_stream_transformer.h",
+ "peerconnection/rtc_encoded_video_stream_transformer.cc",
+ "peerconnection/rtc_encoded_video_stream_transformer.h",
"peerconnection/rtc_event_log_output_sink.h",
"peerconnection/rtc_event_log_output_sink_proxy.cc",
"peerconnection/rtc_event_log_output_sink_proxy.h",
@@ -1267,6 +1281,9 @@ jumbo_component("platform") {
"peerconnection/rtc_ice_candidate_platform.h",
"peerconnection/rtc_legacy_stats.h",
"peerconnection/rtc_offer_options_platform.h",
+ "peerconnection/rtc_peer_connection_handler_client.cc",
+ "peerconnection/rtc_peer_connection_handler_client.h",
+ "peerconnection/rtc_peer_connection_handler_platform.h",
"peerconnection/rtc_rtp_receiver_platform.cc",
"peerconnection/rtc_rtp_receiver_platform.h",
"peerconnection/rtc_rtp_sender_platform.cc",
@@ -1275,6 +1292,7 @@ jumbo_component("platform") {
"peerconnection/rtc_rtp_source.h",
"peerconnection/rtc_rtp_transceiver_platform.cc",
"peerconnection/rtc_rtp_transceiver_platform.h",
+ "peerconnection/rtc_scoped_refptr_cross_thread_copier.h",
"peerconnection/rtc_session_description_platform.cc",
"peerconnection/rtc_session_description_platform.h",
"peerconnection/rtc_session_description_request.h",
@@ -1303,9 +1321,6 @@ jumbo_component("platform") {
"peerconnection/webrtc_util.h",
"peerconnection/webrtc_video_track_source.cc",
"peerconnection/webrtc_video_track_source.h",
- "prerender.cc",
- "prerender.h",
- "prerender_client.h",
"resolution_units.h",
"supplementable.cc",
"supplementable.h",
@@ -1416,6 +1431,7 @@ jumbo_component("platform") {
"weborigin/origin_access_entry.cc",
"weborigin/origin_access_entry.h",
"weborigin/referrer.h",
+ "weborigin/reporting_disposition.h",
"weborigin/scheme_registry.cc",
"weborigin/scheme_registry.h",
"weborigin/security_origin.cc",
@@ -1423,7 +1439,6 @@ jumbo_component("platform") {
"weborigin/security_origin_hash.h",
"weborigin/security_policy.cc",
"weborigin/security_policy.h",
- "weborigin/security_violation_reporting_policy.h",
"webrtc/peer_connection_remote_audio_source.cc",
"webrtc/peer_connection_remote_audio_source.h",
"webrtc/track_observer.cc",
@@ -1434,6 +1449,11 @@ jumbo_component("platform") {
"webrtc/webrtc_video_frame_adapter.h",
"webrtc/webrtc_video_utils.cc",
"webrtc/webrtc_video_utils.h",
+ "widget/frame_widget.cc",
+ "widget/frame_widget.h",
+ "widget/widget_base.cc",
+ "widget/widget_base.h",
+ "widget/widget_base_client.h",
"windows_keyboard_codes.h",
]
@@ -1482,6 +1502,7 @@ jumbo_component("platform") {
public_deps = [
":blink_platform_public_deps",
+ ":platform_export",
"//third_party/blink/renderer/platform/blob",
"//third_party/blink/renderer/platform/heap",
"//third_party/blink/renderer/platform/instrumentation",
@@ -1491,7 +1512,6 @@ jumbo_component("platform") {
"//ui/gfx",
]
deps = [
- ":platform_export",
"//base/allocator:buildflags",
"//cc/ipc",
"//components/paint_preview/common",
@@ -1502,12 +1522,14 @@ jumbo_component("platform") {
"//gin",
"//jingle:webrtc_glue",
"//media",
+ "//media/capture:capture_switches",
"//media/capture/mojom:video_capture",
"//mojo/public/cpp/base",
"//mojo/public/cpp/bindings",
"//mojo/public/cpp/bindings:wtf_support",
"//services/service_manager/public/cpp",
"//services/viz/public/cpp/gpu",
+ "//skia",
"//skia:skcms",
"//third_party:freetype_harfbuzz",
"//third_party/abseil-cpp/absl/types:optional",
@@ -1515,13 +1537,17 @@ jumbo_component("platform") {
"//third_party/blink/public/common",
"//third_party/blink/public/mojom:embedded_frame_sink_mojo_bindings_blink",
"//third_party/blink/public/strings",
+ "//third_party/blink/renderer/platform/wtf",
"//third_party/ced",
"//third_party/emoji-segmenter",
+ "//third_party/harfbuzz-ng:hb_scoped_util",
"//third_party/icu",
"//third_party/libyuv",
"//third_party/webrtc_overrides:webrtc_component",
"//third_party/zlib/google:compression_utils",
- "//ui/base:base",
+ "//ui/base/cursor",
+ "//ui/base/mojom:cursor_type_blink",
+ "//ui/events/ipc",
"//ui/gfx/geometry",
"//ui/gfx/mojom",
]
@@ -1597,24 +1623,15 @@ jumbo_component("platform") {
deps += [ "//third_party/pffft" ]
}
+ if (!is_debug && !optimize_for_size) {
+ configs -= [ "//build/config/compiler:default_optimization" ]
+ configs += [ "//build/config/compiler:optimize_max" ]
+ }
+
configs -= [ "//build/config/compiler:default_symbols" ]
configs += blink_symbols_config
}
-source_set("geometry_mojom_traits") {
- visibility += [ "//ui/gfx/geometry/mojom:mojom_blink" ]
-
- sources = [
- "mojo/geometry_mojom_traits.cc",
- "mojo/geometry_mojom_traits.h",
- ]
-
- public_deps = [
- "//third_party/blink/public:blink_headers",
- "//ui/gfx/geometry/mojom:mojom_blink_headers",
- ]
-}
-
jumbo_static_library("test_support") {
visibility += [ "//third_party/blink/*" ]
testonly = true
@@ -1706,6 +1723,7 @@ jumbo_static_library("test_support") {
"//mojo/public/cpp/bindings",
"//services/service_manager/public/cpp",
"//skia",
+ "//third_party/blink/public/common:common",
"//third_party/blink/renderer/platform/blob:test_support",
"//third_party/blink/renderer/platform/heap:test_support",
"//third_party/blink/renderer/platform/loader:test_support",
@@ -1719,9 +1737,7 @@ jumbo_static_library("test_support") {
}
test("blink_platform_unittests") {
- deps = [
- ":blink_platform_unittests_sources",
- ]
+ deps = [ ":blink_platform_unittests_sources" ]
}
jumbo_source_set("blink_platform_unittests_sources") {
@@ -1744,6 +1760,8 @@ jumbo_source_set("blink_platform_unittests_sources") {
"bindings/parkable_string_test.cc",
"bindings/runtime_call_stats_test.cc",
"cookie/canonical_cookie_test.cc",
+ "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",
@@ -1765,6 +1783,7 @@ jumbo_source_set("blink_platform_unittests_sources") {
"fonts/generic_font_family_settings_test.cc",
"fonts/mac/font_matcher_mac_test.mm",
"fonts/opentype/font_settings_test.cc",
+ "fonts/opentype/open_type_math_support_test.cc",
"fonts/opentype/open_type_vertical_data_test.cc",
"fonts/orientation_iterator_test.cc",
"fonts/script_run_iterator_test.cc",
@@ -1776,6 +1795,7 @@ jumbo_source_set("blink_platform_unittests_sources") {
"fonts/shaping/shape_result_test.cc",
"fonts/shaping/shape_result_view_test.cc",
"fonts/shaping/shaping_line_breaker_test.cc",
+ "fonts/shaping/stretchy_operator_shaper_test.cc",
"fonts/small_caps_iterator_test.cc",
"fonts/symbols_iterator_test.cc",
"fonts/typesetting_features_test.cc",
@@ -1817,6 +1837,7 @@ jumbo_source_set("blink_platform_unittests_sources") {
"graphics/gpu/drawing_buffer_test.cc",
"graphics/gpu/shared_gpu_context_test.cc",
"graphics/gpu/webgl_image_conversion_test.cc",
+ "graphics/gpu/webgpu_image_bitmap_handler_test.cc",
"graphics/gpu/webgpu_swap_buffer_provider_test.cc",
"graphics/graphics_context_test.cc",
"graphics/lab_color_space_test.cc",
@@ -1836,11 +1857,13 @@ jumbo_source_set("blink_platform_unittests_sources") {
"graphics/paint/paint_property_node_test.cc",
"graphics/paint/paint_record_builder_test.cc",
"graphics/paint/raster_invalidator_test.cc",
+ "graphics/paint/scrollbar_display_item_test.cc",
"graphics/paint_invalidation_reason_test.cc",
"graphics/path_test.cc",
"graphics/placeholder_image_test.cc",
"graphics/static_bitmap_image_test.cc",
"graphics/video_frame_submitter_test.cc",
+ "heap_observer_list_test.cc",
"image-decoders/bmp/bmp_image_decoder_test.cc",
"image-decoders/fast_shared_buffer_reader_test.cc",
"image-decoders/gif/gif_image_decoder_test.cc",
@@ -1857,7 +1880,6 @@ jumbo_source_set("blink_platform_unittests_sources") {
"image-decoders/webp/webp_image_decoder_test.cc",
"json/json_parser_test.cc",
"json/json_values_test.cc",
- "lifecycle_context_test.cc",
"loader/allowed_by_nosniff_test.cc",
"loader/cors/cors_test.cc",
"mac/graphics_context_canvas_test.mm",
@@ -1866,11 +1888,16 @@ jumbo_source_set("blink_platform_unittests_sources") {
"mediastream/webrtc_uma_histograms_test.cc",
"mhtml/mhtml_parser_test.cc",
"mojo/big_string_mojom_traits_test.cc",
- "mojo/geometry_mojom_traits_test.cc",
+ "mojo/heap_mojo_receiver_set_test.cc",
+ "mojo/heap_mojo_receiver_test.cc",
+ "mojo/heap_mojo_remote_test.cc",
+ "mojo/heap_mojo_unique_receiver_set_test.cc",
"mojo/kurl_security_origin_test.cc",
"mojo/string16_mojom_traits_test.cc",
"p2p/filtering_network_manager_test.cc",
"p2p/ipc_network_manager_test.cc",
+ "peerconnection/rtc_encoded_audio_stream_transformer_test.cc",
+ "peerconnection/rtc_encoded_video_stream_transformer_test.cc",
"peerconnection/rtc_stats_test.cc",
"peerconnection/rtc_video_decoder_adapter_test.cc",
"peerconnection/rtc_video_encoder_test.cc",
@@ -1878,7 +1905,9 @@ jumbo_source_set("blink_platform_unittests_sources") {
"peerconnection/task_queue_factory_test.cc",
"peerconnection/transmission_encoding_info_handler_test.cc",
"peerconnection/two_keys_adapter_map_unittest.cc",
+ "peerconnection/webrtc_audio_sink_test.cc",
"peerconnection/webrtc_video_track_source_test.cc",
+ "runtime_enabled_features_test.cc",
"text/bidi_resolver_test.cc",
"text/bidi_test_harness.h",
"text/capitalize_test.cc",
@@ -1913,8 +1942,10 @@ jumbo_source_set("blink_platform_unittests_sources") {
]
if (is_win) {
- sources += [ "text/locale_win_test.cc" ]
- sources += [ "fonts/win/fallback_lru_cache_win_test.cc" ]
+ sources += [
+ "fonts/win/fallback_lru_cache_win_test.cc",
+ "text/locale_win_test.cc",
+ ]
} else if (is_mac) {
sources += [
"fonts/opentype/open_type_caps_support_test.mm",
@@ -1946,7 +1977,6 @@ jumbo_source_set("blink_platform_unittests_sources") {
"//mojo/public/cpp/test_support:test_utils",
"//mojo/public/interfaces/bindings/tests:test_interfaces_blink",
"//services/viz/public/mojom",
- "//services/viz/public/mojom:mojom_blink",
"//skia",
"//skia:skcms",
"//skia:test_fonts",
@@ -1965,13 +1995,12 @@ jumbo_source_set("blink_platform_unittests_sources") {
"//ui/gfx",
"//ui/gfx/geometry",
"//ui/gfx/geometry/mojom:test_interfaces_blink",
+ "//ui/gfx/mojom:test_interfaces_blink",
"//url",
"//url/mojom:test_url_mojom_gurl_blink",
]
- data_deps = [
- ":blink_platform_unittests_data",
- ]
+ data_deps = [ ":blink_platform_unittests_data" ]
defines = [ "INSIDE_BLINK" ]
}
@@ -1980,9 +2009,7 @@ executable("image_decode_bench") {
visibility = [] # Allow re-assignment of list.
visibility = [ "*" ]
- sources = [
- "testing/image_decode_bench.cc",
- ]
+ sources = [ "testing/image_decode_bench.cc" ]
deps = [
":platform",
@@ -2038,6 +2065,9 @@ group("blink_platform_unittests_data") {
# Required by some image decoder tests.
"image-decoders/testing/",
"//third_party/blink/web_tests/images/resources/",
+
+ # Required by some font tests.
+ "//third_party/blink/web_tests/external/wpt/fonts/",
]
}
@@ -2049,9 +2079,7 @@ if (current_cpu == "x86" || current_cpu == "x64") {
":blink_platform_implementation",
"//third_party/blink/renderer:non_test_config",
]
- public_deps = [
- ":blink_platform_public_deps",
- ]
+ public_deps = [ ":blink_platform_public_deps" ]
if (is_win) {
cflags = [ "/arch:AVX" ]
} else {
@@ -2067,9 +2095,7 @@ test("blink_fuzzer_unittests") {
"//third_party/blink/public:test_support",
]
- sources = [
- "testing/run_all_tests.cc",
- ]
+ sources = [ "testing/run_all_tests.cc" ]
if (is_linux) {
deps += [
@@ -2097,9 +2123,7 @@ jumbo_source_set("blink_fuzzer_test_support") {
# Fuzzer for blink::MHTMLParser.
fuzzer_test("mhtml_parser_fuzzer") {
- sources = [
- "mhtml/mhtml_fuzzer.cc",
- ]
+ sources = [ "mhtml/mhtml_fuzzer.cc" ]
deps = [
":blink_fuzzer_test_support",
":platform",
@@ -2114,9 +2138,7 @@ fuzzer_test("mhtml_parser_fuzzer") {
# Fuzzer for blink::WebIconSizesParser.
fuzzer_test("web_icon_sizes_fuzzer") {
- sources = [
- "exported/web_icon_sizes_fuzzer.cc",
- ]
+ sources = [ "exported/web_icon_sizes_fuzzer.cc" ]
deps = [
":blink_fuzzer_test_support",
":platform",
@@ -2125,9 +2147,7 @@ fuzzer_test("web_icon_sizes_fuzzer") {
}
fuzzer_test("blink_png_decoder_fuzzer") {
- sources = [
- "png_fuzzer.cc",
- ]
+ sources = [ "png_fuzzer.cc" ]
deps = [
":blink_fuzzer_test_support",
":platform",
@@ -2143,9 +2163,7 @@ fuzzer_test("blink_png_decoder_fuzzer") {
# Fuzzer for blink::DateTimeFormat.
fuzzer_test("blink_date_time_format_fuzzer") {
- sources = [
- "text/date_time_format_fuzzer.cc",
- ]
+ sources = [ "text/date_time_format_fuzzer.cc" ]
deps = [
":blink_fuzzer_test_support",
":platform",
@@ -2156,9 +2174,7 @@ fuzzer_test("blink_date_time_format_fuzzer") {
# Fuzzer for blink::JSONParser.
fuzzer_test("blink_json_parser_fuzzer") {
- sources = [
- "json/json_parser_fuzzer.cc",
- ]
+ sources = [ "json/json_parser_fuzzer.cc" ]
deps = [
":blink_fuzzer_test_support",
":platform",
@@ -2167,9 +2183,7 @@ fuzzer_test("blink_json_parser_fuzzer") {
}
fuzzer_test("blink_harfbuzz_shaper_fuzzer") {
- sources = [
- "fonts/shaping/harfbuzz_shaper_fuzzer.cc",
- ]
+ sources = [ "fonts/shaping/harfbuzz_shaper_fuzzer.cc" ]
deps = [
":blink_fuzzer_test_support",
":platform",
@@ -2179,9 +2193,7 @@ fuzzer_test("blink_harfbuzz_shaper_fuzzer") {
}
fuzzer_test("blink_http_parsers_fuzzer") {
- sources = [
- "network/http_parsers_fuzzer.cc",
- ]
+ sources = [ "network/http_parsers_fuzzer.cc" ]
deps = [
":blink_fuzzer_test_support",
":platform",
@@ -2197,9 +2209,7 @@ template("blink_text_codec_fuzzer") {
}
name = target_name
fuzzer_test("blink_text_codec_" + name + "_fuzzer") {
- sources = [
- "text_codec_fuzzer.cc",
- ]
+ sources = [ "text_codec_fuzzer.cc" ]
deps = [
":blink_fuzzer_test_support",
":platform",
@@ -2249,7 +2259,6 @@ jumbo_source_set("unit_tests") {
"graphics/test/stub_image.h",
# Tests migrated from the web/tests directory.
- "exported/web_resource_timing_info_test.cc",
"exported/web_url_request_test.cc",
"exported/web_url_response_test.cc",
"timer_perf_test.cc",
@@ -2263,7 +2272,6 @@ jumbo_source_set("unit_tests") {
deps = [
":test_support",
- "//services/viz/public/mojom:mojom_blink",
"//testing/gmock",
"//testing/gtest",
]
diff --git a/chromium/third_party/blink/renderer/platform/DEPS b/chromium/third_party/blink/renderer/platform/DEPS
index 4d639942df5..99201dec859 100644
--- a/chromium/third_party/blink/renderer/platform/DEPS
+++ b/chromium/third_party/blink/renderer/platform/DEPS
@@ -62,6 +62,8 @@ include_rules = [
"+services/metrics/public/cpp/ukm_entry_builder.h",
"+services/metrics/public/cpp/ukm_recorder.h",
"+services/metrics/public/cpp/ukm_source_id.h",
+ "+services/network/public/cpp",
+ "+services/network/public/mojom",
"+services/viz/public/mojom/compositing/compositor_frame_sink.mojom-blink.h",
"+skia/ext",
#TODO(nverne): remove this
@@ -69,6 +71,7 @@ include_rules = [
"+third_party/ced/src/compact_enc_det/compact_enc_det.h",
"+third_party/khronos",
"+third_party/skia",
+ "+ui/base/cursor/cursor.h",
"+ui/base/resource/scale_factor.h",
"+ui/gfx",
"+url",
diff --git a/chromium/third_party/blink/renderer/platform/PRESUBMIT.py b/chromium/third_party/blink/renderer/platform/PRESUBMIT.py
index e053782b759..fe39215b5b2 100644
--- a/chromium/third_party/blink/renderer/platform/PRESUBMIT.py
+++ b/chromium/third_party/blink/renderer/platform/PRESUBMIT.py
@@ -1,7 +1,6 @@
# 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.
-
"""Presubmit script for changes affecting Source/platform.
See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
@@ -42,9 +41,12 @@ def _CheckRuntimeEnabledFeaturesSorted(input_api, output_api):
# Diff the sorted/unsorted versions.
differ = difflib.Differ()
diff = differ.compare(features, features_sorted)
- return [output_api.PresubmitError(
- 'runtime_enabled_features.json5 features must be sorted alphabetically. '
- 'Diff of feature order follows:', long_text='\n'.join(diff))]
+ return [
+ output_api.PresubmitError(
+ 'runtime_enabled_features.json5 features must be sorted alphabetically. '
+ 'Diff of feature order follows:',
+ long_text='\n'.join(diff))
+ ]
def _CommonChecks(input_api, output_api):
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 4ea0dacd875..f02f038486a 100644
--- a/chromium/third_party/blink/renderer/platform/animation/compositor_animation.cc
+++ b/chromium/third_party/blink/renderer/platform/animation/compositor_animation.cc
@@ -14,8 +14,7 @@ namespace blink {
std::unique_ptr<CompositorAnimation> CompositorAnimation::Create() {
return std::make_unique<CompositorAnimation>(
- cc::SingleKeyframeEffectAnimation::Create(
- cc::AnimationIdProvider::NextAnimationId()));
+ cc::Animation::Create(cc::AnimationIdProvider::NextAnimationId()));
}
std::unique_ptr<CompositorAnimation>
@@ -23,17 +22,14 @@ CompositorAnimation::CreateWorkletAnimation(
cc::WorkletAnimationId worklet_animation_id,
const String& name,
double playback_rate,
- std::unique_ptr<CompositorScrollTimeline> scroll_timeline,
std::unique_ptr<cc::AnimationOptions> options,
std::unique_ptr<cc::AnimationEffectTimings> effect_timings) {
return std::make_unique<CompositorAnimation>(cc::WorkletAnimation::Create(
- worklet_animation_id, name.Utf8(), playback_rate,
- std::move(scroll_timeline), std::move(options),
+ worklet_animation_id, name.Utf8(), playback_rate, std::move(options),
std::move(effect_timings)));
}
-CompositorAnimation::CompositorAnimation(
- scoped_refptr<cc::SingleKeyframeEffectAnimation> animation)
+CompositorAnimation::CompositorAnimation(scoped_refptr<cc::Animation> animation)
: animation_(animation), delegate_() {}
CompositorAnimation::~CompositorAnimation() {
@@ -44,7 +40,7 @@ CompositorAnimation::~CompositorAnimation() {
animation_->animation_timeline()->DetachAnimation(animation_);
}
-cc::SingleKeyframeEffectAnimation* CompositorAnimation::CcAnimation() const {
+cc::Animation* CompositorAnimation::CcAnimation() const {
return animation_.get();
}
@@ -76,7 +72,7 @@ void CompositorAnimation::RemoveKeyframeModel(int keyframe_model_id) {
}
void CompositorAnimation::PauseKeyframeModel(int keyframe_model_id,
- double time_offset) {
+ base::TimeDelta time_offset) {
animation_->PauseKeyframeModel(keyframe_model_id, time_offset);
}
@@ -88,9 +84,8 @@ void CompositorAnimation::UpdateScrollTimeline(
base::Optional<cc::ElementId> element_id,
base::Optional<double> start_scroll_offset,
base::Optional<double> end_scroll_offset) {
- cc::ToWorkletAnimation(animation_.get())
- ->UpdateScrollTimeline(element_id, start_scroll_offset,
- end_scroll_offset);
+ animation_->UpdateScrollTimeline(element_id, start_scroll_offset,
+ end_scroll_offset);
}
void CompositorAnimation::UpdatePlaybackRate(double 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 e900e473315..348a4480437 100644
--- a/chromium/third_party/blink/renderer/platform/animation/compositor_animation.h
+++ b/chromium/third_party/blink/renderer/platform/animation/compositor_animation.h
@@ -10,9 +10,8 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/optional.h"
+#include "cc/animation/animation.h"
#include "cc/animation/animation_delegate.h"
-#include "cc/animation/scroll_timeline.h"
-#include "cc/animation/single_keyframe_effect_animation.h"
#include "cc/animation/worklet_animation.h"
#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
#include "third_party/blink/renderer/platform/platform_export.h"
@@ -24,8 +23,6 @@ class AnimationCurve;
namespace blink {
-using CompositorScrollTimeline = cc::ScrollTimeline;
-
class CompositorAnimationDelegate;
class CompositorKeyframeModel;
@@ -37,15 +34,13 @@ class PLATFORM_EXPORT CompositorAnimation : public cc::AnimationDelegate {
cc::WorkletAnimationId,
const String& name,
double playback_rate,
- std::unique_ptr<CompositorScrollTimeline>,
std::unique_ptr<cc::AnimationOptions>,
std::unique_ptr<cc::AnimationEffectTimings> effect_timings);
- explicit CompositorAnimation(
- scoped_refptr<cc::SingleKeyframeEffectAnimation>);
+ explicit CompositorAnimation(scoped_refptr<cc::Animation>);
~CompositorAnimation() override;
- cc::SingleKeyframeEffectAnimation* CcAnimation() const;
+ cc::Animation* CcAnimation() const;
// An animation delegate is notified when animations are started and stopped.
// The CompositorAnimation does not take ownership of the delegate, and
@@ -59,7 +54,7 @@ class PLATFORM_EXPORT CompositorAnimation : public cc::AnimationDelegate {
void AddKeyframeModel(std::unique_ptr<CompositorKeyframeModel>);
void RemoveKeyframeModel(int keyframe_model_id);
- void PauseKeyframeModel(int keyframe_model_id, double time_offset);
+ void PauseKeyframeModel(int keyframe_model_id, base::TimeDelta time_offset);
void AbortKeyframeModel(int keyframe_model_id);
void UpdateScrollTimeline(base::Optional<cc::ElementId>,
@@ -85,7 +80,7 @@ class PLATFORM_EXPORT CompositorAnimation : public cc::AnimationDelegate {
void NotifyLocalTimeUpdated(
base::Optional<base::TimeDelta> local_time) override;
- scoped_refptr<cc::SingleKeyframeEffectAnimation> animation_;
+ scoped_refptr<cc::Animation> animation_;
CompositorAnimationDelegate* delegate_;
DISALLOW_COPY_AND_ASSIGN(CompositorAnimation);
diff --git a/chromium/third_party/blink/renderer/platform/animation/compositor_animation_test.cc b/chromium/third_party/blink/renderer/platform/animation/compositor_animation_test.cc
index c40fb3822d0..25a9e0b34ae 100644
--- a/chromium/third_party/blink/renderer/platform/animation/compositor_animation_test.cc
+++ b/chromium/third_party/blink/renderer/platform/animation/compositor_animation_test.cc
@@ -60,7 +60,7 @@ TEST_F(CompositorAnimationTest, NullDelegate) {
std::unique_ptr<CompositorAnimationTestClient> client(
new CompositorAnimationTestClient);
CompositorAnimation* animation = client->GetCompositorAnimation();
- cc::SingleKeyframeEffectAnimation* cc_animation = animation->CcAnimation();
+ cc::Animation* cc_animation = animation->CcAnimation();
timeline->AnimationAttached(*client);
int timeline_id = cc_animation->animation_timeline()->id();
@@ -93,8 +93,7 @@ TEST_F(CompositorAnimationTest, NotifyFromCCAfterCompositorAnimationDeletion) {
std::unique_ptr<CompositorAnimationTestClient> client(
new CompositorAnimationTestClient);
CompositorAnimation* animation = client->GetCompositorAnimation();
- scoped_refptr<cc::SingleKeyframeEffectAnimation> cc_animation =
- animation->CcAnimation();
+ scoped_refptr<cc::Animation> cc_animation = animation->CcAnimation();
timeline->AnimationAttached(*client);
int timeline_id = cc_animation->animation_timeline()->id();
@@ -129,8 +128,7 @@ TEST_F(CompositorAnimationTest,
scoped_refptr<cc::AnimationTimeline> cc_timeline =
timeline->GetAnimationTimeline();
- scoped_refptr<cc::SingleKeyframeEffectAnimation> cc_animation =
- client->animation_->CcAnimation();
+ scoped_refptr<cc::Animation> cc_animation = client->animation_->CcAnimation();
EXPECT_FALSE(cc_animation->animation_timeline());
timeline->AnimationAttached(*client);
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 eca78aece63..3da0644ab74 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
@@ -15,6 +15,10 @@ CompositorAnimationTimeline::CompositorAnimationTimeline()
: animation_timeline_(cc::AnimationTimeline::Create(
cc::AnimationIdProvider::NextTimelineId())) {}
+CompositorAnimationTimeline::CompositorAnimationTimeline(
+ scoped_refptr<cc::AnimationTimeline> timeline)
+ : animation_timeline_(timeline) {}
+
CompositorAnimationTimeline::~CompositorAnimationTimeline() {
// Detach timeline from host, otherwise it stays there (leaks) until
// compositor shutdown.
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 b4e6b8427d4..8307cd8f257 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
@@ -24,6 +24,7 @@ class PLATFORM_EXPORT CompositorAnimationTimeline {
public:
CompositorAnimationTimeline();
+ explicit CompositorAnimationTimeline(scoped_refptr<cc::AnimationTimeline>);
~CompositorAnimationTimeline();
cc::AnimationTimeline* GetAnimationTimeline() const;
diff --git a/chromium/third_party/blink/renderer/platform/animation/compositor_keyframe_model.cc b/chromium/third_party/blink/renderer/platform/animation/compositor_keyframe_model.cc
index 656f2f22d6d..8aeb308e331 100644
--- a/chromium/third_party/blink/renderer/platform/animation/compositor_keyframe_model.cc
+++ b/chromium/third_party/blink/renderer/platform/animation/compositor_keyframe_model.cc
@@ -90,9 +90,8 @@ double CompositorKeyframeModel::TimeOffset() const {
return keyframe_model_->time_offset().InSecondsF();
}
-void CompositorKeyframeModel::SetTimeOffset(double monotonic_time) {
- keyframe_model_->set_time_offset(
- base::TimeDelta::FromSecondsD(monotonic_time));
+void CompositorKeyframeModel::SetTimeOffset(base::TimeDelta monotonic_time) {
+ keyframe_model_->set_time_offset(monotonic_time);
}
blink::CompositorKeyframeModel::Direction
diff --git a/chromium/third_party/blink/renderer/platform/animation/compositor_keyframe_model.h b/chromium/third_party/blink/renderer/platform/animation/compositor_keyframe_model.h
index 3002115a428..7144083160b 100644
--- a/chromium/third_party/blink/renderer/platform/animation/compositor_keyframe_model.h
+++ b/chromium/third_party/blink/renderer/platform/animation/compositor_keyframe_model.h
@@ -63,7 +63,7 @@ class PLATFORM_EXPORT CompositorKeyframeModel {
void SetStartTime(base::TimeTicks);
double TimeOffset() const;
- void SetTimeOffset(double monotonic_time);
+ void SetTimeOffset(base::TimeDelta monotonic_time);
Direction GetDirection() const;
void SetDirection(Direction);
diff --git a/chromium/third_party/blink/renderer/platform/animation/compositor_keyframe_model_test.cc b/chromium/third_party/blink/renderer/platform/animation/compositor_keyframe_model_test.cc
index d6e98d70c29..98c3567a652 100644
--- a/chromium/third_party/blink/renderer/platform/animation/compositor_keyframe_model_test.cc
+++ b/chromium/third_party/blink/renderer/platform/animation/compositor_keyframe_model_test.cc
@@ -28,7 +28,7 @@ TEST(WebCompositorAnimationTest, ModifiedSettings) {
*curve, compositor_target_property::OPACITY, 0, 1);
keyframe_model->SetIterations(2);
keyframe_model->SetStartTime(2);
- keyframe_model->SetTimeOffset(2);
+ keyframe_model->SetTimeOffset(base::TimeDelta::FromSeconds(2));
keyframe_model->SetDirection(CompositorKeyframeModel::Direction::REVERSE);
EXPECT_EQ(2, keyframe_model->Iterations());
diff --git a/chromium/third_party/blink/renderer/platform/animation/compositor_transform_operations.cc b/chromium/third_party/blink/renderer/platform/animation/compositor_transform_operations.cc
index 001388046da..9ee7cf65d70 100644
--- a/chromium/third_party/blink/renderer/platform/animation/compositor_transform_operations.cc
+++ b/chromium/third_party/blink/renderer/platform/animation/compositor_transform_operations.cc
@@ -28,29 +28,29 @@ void CompositorTransformOperations::AppendTranslate(double x,
double y,
double z) {
transform_operations_.AppendTranslate(
- SkDoubleToMScalar(x), SkDoubleToMScalar(y), SkDoubleToMScalar(z));
+ SkDoubleToScalar(x), SkDoubleToScalar(y), SkDoubleToScalar(z));
}
void CompositorTransformOperations::AppendRotate(double x,
double y,
double z,
double degrees) {
- transform_operations_.AppendRotate(SkDoubleToMScalar(x), SkDoubleToMScalar(y),
- SkDoubleToMScalar(z),
- SkDoubleToMScalar(degrees));
+ transform_operations_.AppendRotate(SkDoubleToScalar(x), SkDoubleToScalar(y),
+ SkDoubleToScalar(z),
+ SkDoubleToScalar(degrees));
}
void CompositorTransformOperations::AppendScale(double x, double y, double z) {
- transform_operations_.AppendScale(SkDoubleToMScalar(x), SkDoubleToMScalar(y),
- SkDoubleToMScalar(z));
+ transform_operations_.AppendScale(SkDoubleToScalar(x), SkDoubleToScalar(y),
+ SkDoubleToScalar(z));
}
void CompositorTransformOperations::AppendSkew(double x, double y) {
- transform_operations_.AppendSkew(SkDoubleToMScalar(x), SkDoubleToMScalar(y));
+ transform_operations_.AppendSkew(SkDoubleToScalar(x), SkDoubleToScalar(y));
}
void CompositorTransformOperations::AppendPerspective(double depth) {
- transform_operations_.AppendPerspective(SkDoubleToMScalar(depth));
+ transform_operations_.AppendPerspective(SkDoubleToScalar(depth));
}
void CompositorTransformOperations::AppendMatrix(const SkMatrix44& matrix) {
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 2ea4d36719a..5d8e9c8806a 100644
--- a/chromium/third_party/blink/renderer/platform/animation/timing_function.cc
+++ b/chromium/third_party/blink/renderer/platform/animation/timing_function.cc
@@ -200,7 +200,7 @@ bool operator==(const CubicBezierTimingFunction& lhs,
if (rhs.GetType() != TimingFunction::Type::CUBIC_BEZIER)
return false;
- const CubicBezierTimingFunction& ctf = ToCubicBezierTimingFunction(rhs);
+ const auto& ctf = To<CubicBezierTimingFunction>(rhs);
if ((lhs.GetEaseType() == CubicBezierTimingFunction::EaseType::CUSTOM) &&
(ctf.GetEaseType() == CubicBezierTimingFunction::EaseType::CUSTOM))
return (lhs.X1() == ctf.X1()) && (lhs.Y1() == ctf.Y1()) &&
@@ -213,7 +213,7 @@ bool operator==(const StepsTimingFunction& lhs, const TimingFunction& rhs) {
if (rhs.GetType() != TimingFunction::Type::STEPS)
return false;
- const StepsTimingFunction& stf = ToStepsTimingFunction(rhs);
+ const auto& stf = To<StepsTimingFunction>(rhs);
return (lhs.NumberOfSteps() == stf.NumberOfSteps()) &&
(lhs.GetStepPosition() == stf.GetStepPosition());
}
@@ -223,15 +223,15 @@ bool operator==(const StepsTimingFunction& lhs, const TimingFunction& rhs) {
bool operator==(const TimingFunction& lhs, const TimingFunction& rhs) {
switch (lhs.GetType()) {
case TimingFunction::Type::LINEAR: {
- const LinearTimingFunction& linear = ToLinearTimingFunction(lhs);
+ const auto& linear = To<LinearTimingFunction>(lhs);
return (linear == rhs);
}
case TimingFunction::Type::CUBIC_BEZIER: {
- const CubicBezierTimingFunction& cubic = ToCubicBezierTimingFunction(lhs);
+ const auto& cubic = To<CubicBezierTimingFunction>(lhs);
return (cubic == rhs);
}
case TimingFunction::Type::STEPS: {
- const StepsTimingFunction& step = ToStepsTimingFunction(lhs);
+ const auto& step = To<StepsTimingFunction>(lhs);
return (step == rhs);
}
default:
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 f7a9eaef5b1..8cf6ef43f37 100644
--- a/chromium/third_party/blink/renderer/platform/animation/timing_function.h
+++ b/chromium/third_party/blink/renderer/platform/animation/timing_function.h
@@ -30,6 +30,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/casting.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
@@ -217,14 +218,24 @@ PLATFORM_EXPORT bool operator==(const StepsTimingFunction&,
PLATFORM_EXPORT bool operator==(const TimingFunction&, const TimingFunction&);
PLATFORM_EXPORT bool operator!=(const TimingFunction&, const TimingFunction&);
-#define DEFINE_TIMING_FUNCTION_TYPE_CASTS(typeName, enumName) \
- DEFINE_TYPE_CASTS(typeName##TimingFunction, TimingFunction, value, \
- value->GetType() == TimingFunction::Type::enumName, \
- value.GetType() == TimingFunction::Type::enumName)
-
-DEFINE_TIMING_FUNCTION_TYPE_CASTS(Linear, LINEAR);
-DEFINE_TIMING_FUNCTION_TYPE_CASTS(CubicBezier, CUBIC_BEZIER);
-DEFINE_TIMING_FUNCTION_TYPE_CASTS(Steps, STEPS);
+template <>
+struct DowncastTraits<LinearTimingFunction> {
+ static bool AllowFrom(const TimingFunction& value) {
+ return value.GetType() == TimingFunction::Type::LINEAR;
+ }
+};
+template <>
+struct DowncastTraits<CubicBezierTimingFunction> {
+ static bool AllowFrom(const TimingFunction& value) {
+ return value.GetType() == TimingFunction::Type::CUBIC_BEZIER;
+ }
+};
+template <>
+struct DowncastTraits<StepsTimingFunction> {
+ static bool AllowFrom(const TimingFunction& value) {
+ return value.GetType() == TimingFunction::Type::STEPS;
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/audio/DEPS b/chromium/third_party/blink/renderer/platform/audio/DEPS
index 5a7148091dd..970052c08fd 100644
--- a/chromium/third_party/blink/renderer/platform/audio/DEPS
+++ b/chromium/third_party/blink/renderer/platform/audio/DEPS
@@ -12,7 +12,6 @@ include_rules = [
"+third_party/blink/renderer/platform/wtf/cross_thread_functional.h",
"+third_party/blink/renderer/platform/geometry/float_point_3d.h",
"+third_party/blink/renderer/platform/heap",
- "+third_party/blink/renderer/platform/instrumentation/histogram.h",
"+third_party/blink/renderer/platform/instrumentation",
"+third_party/blink/renderer/platform/platform_export.h",
"+third_party/blink/renderer/platform/scheduler/public",
diff --git a/chromium/third_party/blink/renderer/platform/audio/OWNERS b/chromium/third_party/blink/renderer/platform/audio/OWNERS
index caaf05cf1d8..bcc0e71a548 100644
--- a/chromium/third_party/blink/renderer/platform/audio/OWNERS
+++ b/chromium/third_party/blink/renderer/platform/audio/OWNERS
@@ -1,5 +1,4 @@
hongchan@chromium.org
-kbr@chromium.org
rtoy@chromium.org
# COMPONENT: Blink>WebAudio
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 3e2f1a5a3fa..819ca91d754 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
@@ -61,7 +61,8 @@ size_t AudioDelayDSPKernel::BufferLengthForDelay(double max_delay_time,
// 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);
+ return 1 + audio_utilities::TimeToSampleFrame(max_delay_time, sample_rate,
+ audio_utilities::kRoundUp);
}
bool AudioDelayDSPKernel::HasSampleAccurateValues() {
@@ -79,14 +80,14 @@ double AudioDelayDSPKernel::DelayTime(float sample_rate) {
void AudioDelayDSPKernel::Process(const float* source,
float* destination,
uint32_t frames_to_process) {
- size_t buffer_length = buffer_.size();
+ int buffer_length = buffer_.size();
float* buffer = buffer_.Data();
DCHECK(buffer_length);
DCHECK(source);
DCHECK(destination);
DCHECK_GE(write_index_, 0);
- DCHECK_LT(static_cast<size_t>(write_index_), buffer_length);
+ DCHECK_LT(write_index_, buffer_length);
float sample_rate = this->SampleRate();
double max_time = MaxDelayTime();
@@ -112,28 +113,25 @@ void AudioDelayDSPKernel::Process(const float* source,
// Linearly interpolate in-between delay times.
int read_index1 = static_cast<int>(read_position);
DCHECK_GE(read_index1, 0);
- DCHECK_LT(static_cast<size_t>(read_index1), buffer_length);
+ DCHECK_LT(read_index1, buffer_length);
int read_index2 = read_index1 + 1;
- if (read_index2 >= static_cast<int>(buffer_length))
+ if (read_index2 >= buffer_length)
read_index2 -= buffer_length;
DCHECK_GE(read_index2, 0);
- DCHECK_LT(static_cast<size_t>(read_index2), buffer_length);
-
- double interpolation_factor = read_position - read_index1;
+ DCHECK_LT(read_index2, buffer_length);
buffer[w_index] = *source++;
- ++w_index;
- if (w_index >= static_cast<int>(buffer_length))
- w_index -= buffer_length;
+ float interpolation_factor = read_position - read_index1;
float sample1 = buffer[read_index1];
float sample2 = buffer[read_index2];
- double output =
- (1 - interpolation_factor) * sample1 + interpolation_factor * sample2;
+ ++w_index;
+ if (w_index >= buffer_length)
+ w_index -= buffer_length;
- *destination++ = static_cast<float>(output);
+ *destination++ = sample1 + interpolation_factor * (sample2 - sample1);
}
write_index_ = w_index;
@@ -152,7 +150,8 @@ void AudioDelayDSPKernel::Process(const float* source,
// 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;
- double read_position = write_index_ + buffer_length - desired_delay_frames;
+ int w_index = write_index_;
+ double read_position = w_index + buffer_length - desired_delay_frames;
if (read_position >= buffer_length)
read_position -= buffer_length;
@@ -161,34 +160,34 @@ void AudioDelayDSPKernel::Process(const float* source,
// interpolation.
int read_index1 = static_cast<int>(read_position);
int read_index2 = (read_index1 + 1) % buffer_length;
- double interp_factor = read_position - read_index1;
+ float interp_factor = read_position - read_index1;
- int w_index = write_index_;
+ 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.
- buffer[w_index] = *source++;
- float sample1 = buffer[read_index1];
- float sample2 = buffer[read_index2];
+ *w++ = *source++;
+ float sample1 = *r1++;
+ float sample2 = *r2++;
// Update the indices and wrap them to the beginning of the buffer if
// needed.
- ++w_index;
- ++read_index1;
- ++read_index2;
- if (w_index >= static_cast<int>(buffer_length))
- w_index -= buffer_length;
- if (read_index1 >= static_cast<int>(buffer_length))
- read_index1 -= buffer_length;
- if (read_index2 >= static_cast<int>(buffer_length))
- read_index2 -= buffer_length;
+ if (w >= buffer_end)
+ w = buffer;
+ if (r1 >= buffer_end)
+ r1 = buffer;
+ if (r2 >= buffer_end)
+ r2 = buffer;
// Linearly interpolate between samples.
- *destination++ = (1 - interp_factor) * sample1 + interp_factor * sample2;
+ *destination++ = sample1 + interp_factor * (sample2 - sample1);
}
- write_index_ = w_index;
+ write_index_ = w - buffer;
}
}
diff --git a/chromium/third_party/blink/renderer/platform/audio/audio_destination.cc b/chromium/third_party/blink/renderer/platform/audio/audio_destination.cc
index ad2ac3c5a15..c66a178d20a 100644
--- a/chromium/third_party/blink/renderer/platform/audio/audio_destination.cc
+++ b/chromium/third_party/blink/renderer/platform/audio/audio_destination.cc
@@ -32,13 +32,13 @@
#include <memory>
#include <utility>
+#include "base/metrics/histogram_functions.h"
#include "media/base/audio_bus.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_audio_latency_hint.h"
#include "third_party/blink/renderer/platform/audio/audio_utilities.h"
#include "third_party/blink/renderer/platform/audio/push_pull_fifo.h"
#include "third_party/blink/renderer/platform/audio/vector_math.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.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"
@@ -67,7 +67,6 @@ AudioDestination::AudioDestination(AudioIOCallback& callback,
const WebAudioLatencyHint& latency_hint,
base::Optional<float> context_sample_rate)
: number_of_output_channels_(number_of_output_channels),
- play_state_(PlayState::kStopped),
fifo_(
std::make_unique<PushPullFIFO>(number_of_output_channels, kFIFOSize)),
output_bus_(AudioBus::Create(number_of_output_channels,
@@ -76,7 +75,8 @@ AudioDestination::AudioDestination(AudioIOCallback& callback,
render_bus_(AudioBus::Create(number_of_output_channels,
audio_utilities::kRenderQuantumFrames)),
callback_(callback),
- frames_elapsed_(0) {
+ frames_elapsed_(0),
+ device_state_(DeviceState::kStopped) {
// Create WebAudioDevice. blink::WebAudioDevice is designed to support the
// local input (e.g. loopback from OS audio system), but Chromium's media
// renderer does not support it currently. Thus, we use zero for the number
@@ -126,29 +126,23 @@ AudioDestination::AudioDestination(AudioIOCallback& callback,
context_sample_rate_ = web_audio_device_->SampleRate();
}
- DEFINE_STATIC_LOCAL(SparseHistogram, sample_rate_histogram,
- ("WebAudio.AudioContext.HardwareSampleRate"));
-
- sample_rate_histogram.Sample(web_audio_device_->SampleRate());
-
- // The actual supplied |sampleRate| is probably a small set including 44100,
- // 48000, 22050, and 2400 Hz. Other valid values range from 3000 to 384000
- // Hz, but are not expected to be used much.
- DEFINE_STATIC_LOCAL(SparseHistogram, selected_sample_rate_histogram,
- ("WebAudio.AudioContextOptions.sampleRate"));
-
- // From the expected values above and the common HW sample rates, we expect
- // the most common ratios to be the set 0.5, 44100/48000, and 48000/44100.
- // Other values are possible but seem unlikely.
- DEFINE_STATIC_LOCAL(SparseHistogram, sample_rate_ratio_histogram,
- ("WebAudio.AudioContextOptions.sampleRateRatio"));
+ base::UmaHistogramSparse("WebAudio.AudioContext.HardwareSampleRate",
+ web_audio_device_->SampleRate());
// Record the selected sample rate and ratio if the sampleRate was given. The
// ratio is recorded as a percentage, rounded to the nearest percent.
if (context_sample_rate.has_value()) {
- selected_sample_rate_histogram.Sample(context_sample_rate.value());
- sample_rate_ratio_histogram.Sample(
- static_cast<int32_t>(100 * scale_factor + 0.5));
+ // The actual supplied |sampleRate| is probably a small set including 44100,
+ // 48000, 22050, and 2400 Hz. Other valid values range from 3000 to 384000
+ // Hz, but are not expected to be used much.
+ base::UmaHistogramSparse("WebAudio.AudioContextOptions.sampleRate",
+ context_sample_rate.value());
+ // From the expected values above and the common HW sample rates, we expect
+ // the most common ratios to be the set 0.5, 44100/48000, and 48000/44100.
+ // Other values are possible but seem unlikely.
+ base::UmaHistogramSparse("WebAudio.AudioContextOptions.sampleRateRatio",
+
+ static_cast<int32_t>(100 * scale_factor + 0.5));
}
}
@@ -214,6 +208,16 @@ void AudioDestination::RequestRender(size_t frames_requested,
"frames_to_render", frames_to_render, "timestamp (s)",
delay_timestamp);
+ MutexTryLocker locker(state_change_lock_);
+
+ // The state might be changing by ::Stop() call. If the state is locked, do
+ // not touch the below.
+ if (!locker.Locked())
+ return;
+
+ if (device_state_ != DeviceState::kRunning)
+ return;
+
metric_reporter_.BeginTrace();
frames_elapsed_ -= std::min(frames_elapsed_, prior_frames_skipped);
@@ -240,8 +244,8 @@ void AudioDestination::RequestRender(size_t frames_requested,
output_position_.position = 0.0;
if (resampler_) {
- resampler_->Resample(audio_utilities::kRenderQuantumFrames,
- resampler_bus_.get());
+ resampler_->ResampleInternal(audio_utilities::kRenderQuantumFrames,
+ resampler_bus_.get());
} else {
// Process WebAudio graph and push the rendered output to FIFO.
callback_.Render(render_bus_.get(), audio_utilities::kRenderQuantumFrames,
@@ -258,64 +262,72 @@ void AudioDestination::RequestRender(size_t frames_requested,
void AudioDestination::Start() {
DCHECK(IsMainThread());
+ TRACE_EVENT0("webaudio", "AudioDestination::Start");
- // Start the "audio device" after the rendering thread is ready.
- if (web_audio_device_ && play_state_ == PlayState::kStopped) {
- TRACE_EVENT0("webaudio", "AudioDestination::Start");
- web_audio_device_->Start();
- play_state_ = PlayState::kPlaying;
- }
+ if (device_state_ != DeviceState::kStopped)
+ return;
+ web_audio_device_->Start();
+ SetDeviceState(DeviceState::kRunning);
}
void AudioDestination::StartWithWorkletTaskRunner(
scoped_refptr<base::SingleThreadTaskRunner> worklet_task_runner) {
DCHECK(IsMainThread());
+ DCHECK_EQ(worklet_task_runner_, nullptr);
+ TRACE_EVENT0("webaudio", "AudioDestination::StartWithWorkletTaskRunner");
- if (web_audio_device_ && play_state_ == PlayState::kStopped) {
- TRACE_EVENT0("webaudio", "AudioDestination::Start");
- worklet_task_runner_ = std::move(worklet_task_runner);
- web_audio_device_->Start();
- play_state_ = PlayState::kPlaying;
- }
+ if (device_state_ != DeviceState::kStopped)
+ return;
+ worklet_task_runner_ = std::move(worklet_task_runner);
+ web_audio_device_->Start();
+ SetDeviceState(DeviceState::kRunning);
}
void AudioDestination::Stop() {
DCHECK(IsMainThread());
+ TRACE_EVENT0("webaudio", "AudioDestination::Stop");
- // This assumes stopping the "audio device" is synchronous and dumping the
- // rendering thread is safe after that.
- if (web_audio_device_ && play_state_ != PlayState::kStopped) {
- TRACE_EVENT0("webaudio", "AudioDestination::Stop");
- web_audio_device_->Stop();
- worklet_task_runner_ = nullptr;
- play_state_ = PlayState::kStopped;
- }
+ if (device_state_ == DeviceState::kStopped)
+ return;
+ web_audio_device_->Stop();
+
+ // Resetting |worklet_task_runner_| here is safe because
+ // AudioDestination::Render() won't be called after WebAudioDevice::Stop()
+ // call above.
+ worklet_task_runner_ = nullptr;
+
+ SetDeviceState(DeviceState::kStopped);
}
void AudioDestination::Pause() {
DCHECK(IsMainThread());
- if (web_audio_device_ && play_state_ == PlayState::kPlaying) {
- web_audio_device_->Pause();
- play_state_ = PlayState::kPaused;
- }
+ TRACE_EVENT0("webaudio", "AudioDestination::Pause");
+
+ if (device_state_ != DeviceState::kRunning)
+ return;
+ web_audio_device_->Pause();
+ SetDeviceState(DeviceState::kPaused);
}
void AudioDestination::Resume() {
DCHECK(IsMainThread());
- if (web_audio_device_ && play_state_ == PlayState::kPaused) {
- web_audio_device_->Resume();
- play_state_ = PlayState::kPlaying;
- }
+ TRACE_EVENT0("webaudio", "AudioDestination::Resume");
+
+ if (device_state_ != DeviceState::kPaused)
+ return;
+ web_audio_device_->Resume();
+ SetDeviceState(DeviceState::kRunning);
}
-uint32_t AudioDestination::CallbackBufferSize() const {
+bool AudioDestination::IsPlaying() {
DCHECK(IsMainThread());
- return callback_buffer_size_;
+ MutexLocker locker(state_change_lock_);
+ return device_state_ == DeviceState::kRunning;
}
-bool AudioDestination::IsPlaying() {
+uint32_t AudioDestination::CallbackBufferSize() const {
DCHECK(IsMainThread());
- return play_state_ == PlayState::kPlaying;
+ return callback_buffer_size_;
}
int AudioDestination::FramesPerBuffer() const {
@@ -336,19 +348,16 @@ uint32_t AudioDestination::MaxChannelCount() {
}
bool AudioDestination::CheckBufferSize() {
+ // Record the sizes if we successfully created an output device.
// Histogram for audioHardwareBufferSize
- DEFINE_STATIC_LOCAL(SparseHistogram, hardware_buffer_size_histogram,
- ("WebAudio.AudioDestination.HardwareBufferSize"));
+ base::UmaHistogramSparse("WebAudio.AudioDestination.HardwareBufferSize",
+ HardwareBufferSize());
// Histogram for the actual callback size used. Typically, this is the same
// as audioHardwareBufferSize, but can be adjusted depending on some
// heuristics below.
- DEFINE_STATIC_LOCAL(SparseHistogram, callback_buffer_size_histogram,
- ("WebAudio.AudioDestination.CallbackBufferSize"));
-
- // Record the sizes if we successfully created an output device.
- hardware_buffer_size_histogram.Sample(HardwareBufferSize());
- callback_buffer_size_histogram.Sample(callback_buffer_size_);
+ base::UmaHistogramSparse("WebAudio.AudioDestination.CallbackBufferSize",
+ callback_buffer_size_);
// Check if the requested buffer size is too large.
bool is_buffer_size_valid =
@@ -364,4 +373,11 @@ void AudioDestination::ProvideResamplerInput(int resampler_frame_delay,
callback_.Render(dest, audio_utilities::kRenderQuantumFrames,
output_position_, metric_reporter_.GetMetric());
}
+
+void AudioDestination::SetDeviceState(DeviceState state) {
+ DCHECK(IsMainThread());
+ MutexLocker locker(state_change_lock_);
+ device_state_ = state;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/audio/audio_destination.h b/chromium/third_party/blink/renderer/platform/audio/audio_destination.h
index f3045cceaa2..dafb1d9da4c 100644
--- a/chromium/third_party/blink/renderer/platform/audio/audio_destination.h
+++ b/chromium/third_party/blink/renderer/platform/audio/audio_destination.h
@@ -39,6 +39,7 @@
#include "third_party/blink/renderer/platform/audio/audio_io_callback.h"
#include "third_party/blink/renderer/platform/audio/media_multi_channel_resampler.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
+#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
@@ -117,11 +118,19 @@ class PLATFORM_EXPORT AudioDestination
static uint32_t MaxChannelCount();
private:
+ // Represents the current state of the underlying |WebAudioDevice| object
+ // (RendererWebAudioDeviceImpl).
+ enum DeviceState {
+ kRunning,
+ kPaused,
+ kStopped,
+ };
+
+ void SetDeviceState(DeviceState);
+
// Provide input to the resampler (if used).
void ProvideResamplerInput(int resampler_frame_delay, AudioBus* dest);
- enum class PlayState { kStopped, kPlaying, kPaused };
-
// Check if the buffer size chosen by the WebAudioDevice is too large.
bool CheckBufferSize();
@@ -131,7 +140,6 @@ class PLATFORM_EXPORT AudioDestination
std::unique_ptr<WebAudioDevice> web_audio_device_;
const unsigned number_of_output_channels_;
uint32_t callback_buffer_size_;
- PlayState play_state_;
// The task runner for AudioWorklet operation. This is only valid when
// the AudioWorklet is activated.
@@ -168,6 +176,13 @@ class PLATFORM_EXPORT AudioDestination
AudioCallbackMetricReporter metric_reporter_;
+ // This protects |device_state_| below.
+ mutable Mutex state_change_lock_;
+
+ // Modified only on the main thread, so it can be read without holding a lock
+ // there.
+ DeviceState device_state_;
+
DISALLOW_COPY_AND_ASSIGN(AudioDestination);
};
diff --git a/chromium/third_party/blink/renderer/platform/audio/audio_destination_test.cc b/chromium/third_party/blink/renderer/platform/audio/audio_destination_test.cc
index 072ca234d0a..62ea2d72525 100644
--- a/chromium/third_party/blink/renderer/platform/audio/audio_destination_test.cc
+++ b/chromium/third_party/blink/renderer/platform/audio/audio_destination_test.cc
@@ -73,6 +73,7 @@ void CountWASamplesProcessedForRate(base::Optional<float> sample_rate) {
scoped_refptr<AudioDestination> destination = AudioDestination::Create(
callback, channel_count, latency_hint, sample_rate);
+ destination->Start();
Vector<float> channels[channel_count];
WebVector<float*> dest_data(static_cast<size_t>(channel_count));
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 2d77c44a5cd..4372a94a853 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(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) override {}
protected:
virtual ~AudioSourceProviderClient() = default;
diff --git a/chromium/third_party/blink/renderer/platform/audio/equal_power_panner.cc b/chromium/third_party/blink/renderer/platform/audio/equal_power_panner.cc
index dbf97962bef..22fb5b2af72 100644
--- a/chromium/third_party/blink/renderer/platform/audio/equal_power_panner.cc
+++ b/chromium/third_party/blink/renderer/platform/audio/equal_power_panner.cc
@@ -34,7 +34,7 @@
namespace blink {
EqualPowerPanner::EqualPowerPanner(float sample_rate)
- : Panner(kPanningModelEqualPower) {}
+ : Panner(PanningModel::kEqualPower) {}
void EqualPowerPanner::Pan(double azimuth,
double /*elevation*/,
diff --git a/chromium/third_party/blink/renderer/platform/audio/ffmpeg/fft_frame_ffmpeg.cc b/chromium/third_party/blink/renderer/platform/audio/ffmpeg/fft_frame_ffmpeg.cc
index c2b692bc562..69b31dffe9d 100644
--- a/chromium/third_party/blink/renderer/platform/audio/ffmpeg/fft_frame_ffmpeg.cc
+++ b/chromium/third_party/blink/renderer/platform/audio/ffmpeg/fft_frame_ffmpeg.cc
@@ -84,8 +84,8 @@ FFTFrame::FFTFrame(const FFTFrame& frame)
// Copy/setup frame data.
unsigned nbytes = sizeof(float) * (fft_size_ / 2);
- memcpy(RealData(), frame.RealData(), nbytes);
- memcpy(ImagData(), frame.ImagData(), nbytes);
+ memcpy(RealData().Data(), frame.RealData().Data(), nbytes);
+ memcpy(ImagData().Data(), frame.ImagData().Data(), nbytes);
}
int FFTFrame::MinFFTSize() {
diff --git a/chromium/third_party/blink/renderer/platform/audio/fft_frame.cc b/chromium/third_party/blink/renderer/platform/audio/fft_frame.cc
index b5b02afabb7..b10f84b06c2 100644
--- a/chromium/third_party/blink/renderer/platform/audio/fft_frame.cc
+++ b/chromium/third_party/blink/renderer/platform/audio/fft_frame.cc
@@ -82,13 +82,13 @@ void FFTFrame::InterpolateFrequencyComponents(const FFTFrame& frame1,
double interp) {
// FIXME : with some work, this method could be optimized
- float* real_p = RealData();
- float* imag_p = ImagData();
+ AudioFloatArray& real = RealData();
+ AudioFloatArray& imag = ImagData();
- const float* real_p1 = frame1.RealData();
- const float* imag_p1 = frame1.ImagData();
- const float* real_p2 = frame2.RealData();
- const float* imag_p2 = frame2.ImagData();
+ const AudioFloatArray& real1 = frame1.RealData();
+ const AudioFloatArray& imag1 = frame1.ImagData();
+ const AudioFloatArray& real2 = frame2.RealData();
+ const AudioFloatArray& imag2 = frame2.ImagData();
fft_size_ = frame1.FftSize();
log2fft_size_ = frame1.Log2FFTSize();
@@ -100,14 +100,26 @@ void FFTFrame::InterpolateFrequencyComponents(const FFTFrame& frame1,
double last_phase1 = 0.0;
double last_phase2 = 0.0;
- real_p[0] = static_cast<float>(s1base * real_p1[0] + s2base * real_p2[0]);
- imag_p[0] = static_cast<float>(s1base * imag_p1[0] + s2base * imag_p2[0]);
+ const float* real_p1_data = real1.Data();
+ const float* real_p2_data = real2.Data();
+ const float* imag_p1_data = imag1.Data();
+ const float* imag_p2_data = imag2.Data();
+
+ real[0] = static_cast<float>(s1base * real_p1_data[0] +
+ s2base * real_p2_data[0]);
+ imag[0] = static_cast<float>(s1base * imag_p1_data[0] +
+ s2base * imag_p2_data[0]);
int n = fft_size_ / 2;
+ DCHECK_GE(real1.size(), static_cast<uint32_t>(n));
+ DCHECK_GE(imag1.size(), static_cast<uint32_t>(n));
+ DCHECK_GE(real2.size(), static_cast<uint32_t>(n));
+ DCHECK_GE(imag2.size(), static_cast<uint32_t>(n));
+
for (int i = 1; i < n; ++i) {
- std::complex<double> c1(real_p1[i], imag_p1[i]);
- std::complex<double> c2(real_p2[i], imag_p2[i]);
+ std::complex<double> c1(real_p1_data[i], imag_p1_data[i]);
+ std::complex<double> c2(real_p2_data[i], imag_p2_data[i]);
double mag1 = abs(c1);
double mag2 = abs(c2);
@@ -178,14 +190,14 @@ void FFTFrame::InterpolateFrequencyComponents(const FFTFrame& frame1,
std::complex<double> c = std::polar(mag, phase_accum);
- real_p[i] = static_cast<float>(c.real());
- imag_p[i] = static_cast<float>(c.imag());
+ real[i] = static_cast<float>(c.real());
+ imag[i] = static_cast<float>(c.imag());
}
}
double FFTFrame::ExtractAverageGroupDelay() {
- float* real_p = RealData();
- float* imag_p = ImagData();
+ AudioFloatArray& real = RealData();
+ AudioFloatArray& imag = ImagData();
double ave_sum = 0.0;
double weight_sum = 0.0;
@@ -198,7 +210,7 @@ double FFTFrame::ExtractAverageGroupDelay() {
// Calculate weighted average group delay
for (int i = 0; i < half_size; i++) {
- std::complex<double> c(real_p[i], imag_p[i]);
+ std::complex<double> c(real[i], imag[i]);
double mag = abs(c);
double phase = arg(c);
@@ -228,7 +240,7 @@ double FFTFrame::ExtractAverageGroupDelay() {
AddConstantGroupDelay(-ave_sample_delay);
// Remove DC offset
- real_p[0] = 0.0f;
+ real[0] = 0.0f;
return ave_sample_delay;
}
@@ -236,8 +248,8 @@ double FFTFrame::ExtractAverageGroupDelay() {
void FFTFrame::AddConstantGroupDelay(double sample_frame_delay) {
int half_size = FftSize() / 2;
- float* real_p = RealData();
- float* imag_p = ImagData();
+ AudioFloatArray& real = RealData();
+ AudioFloatArray& imag = ImagData();
const double sample_phase_delay =
kTwoPiDouble / static_cast<double>(FftSize());
@@ -246,7 +258,7 @@ void FFTFrame::AddConstantGroupDelay(double sample_frame_delay) {
// Add constant group delay
for (int i = 1; i < half_size; i++) {
- std::complex<double> c(real_p[i], imag_p[i]);
+ std::complex<double> c(real[i], imag[i]);
double mag = abs(c);
double phase = arg(c);
@@ -254,8 +266,8 @@ void FFTFrame::AddConstantGroupDelay(double sample_frame_delay) {
std::complex<double> c2 = std::polar(mag, phase);
- real_p[i] = static_cast<float>(c2.real());
- imag_p[i] = static_cast<float>(c2.imag());
+ real[i] = static_cast<float>(c2.real());
+ imag[i] = static_cast<float>(c2.imag());
}
}
@@ -263,21 +275,27 @@ void FFTFrame::Multiply(const FFTFrame& frame) {
FFTFrame& frame1 = *this;
const FFTFrame& frame2 = frame;
- float* real_p1 = frame1.RealData();
- float* imag_p1 = frame1.ImagData();
- const float* real_p2 = frame2.RealData();
- const float* imag_p2 = frame2.ImagData();
+ AudioFloatArray& real1 = frame1.RealData();
+ AudioFloatArray& imag1 = frame1.ImagData();
+ const AudioFloatArray& real2 = frame2.RealData();
+ const AudioFloatArray& imag2 = frame2.ImagData();
unsigned half_size = FftSize() / 2;
- float real0 = real_p1[0];
- float imag0 = imag_p1[0];
+ float real0 = real1[0];
+ float imag0 = imag1[0];
+
+ DCHECK_GE(real1.size(), half_size);
+ DCHECK_GE(imag1.size(), half_size);
+ DCHECK_GE(real2.size(), half_size);
+ DCHECK_GE(imag2.size(), half_size);
- vector_math::Zvmul(real_p1, imag_p1, real_p2, imag_p2, real_p1, imag_p1,
+ vector_math::Zvmul(real1.Data(), imag1.Data(), real2.Data(),
+ imag2.Data(), real1.Data(), imag1.Data(),
half_size);
// Multiply the packed DC/nyquist component
- real_p1[0] = real0 * real_p2[0];
- imag_p1[0] = imag0 * imag_p2[0];
+ real1[0] = real0 * real2.Data()[0];
+ imag1[0] = imag0 * imag2.Data()[0];
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/audio/fft_frame.h b/chromium/third_party/blink/renderer/platform/audio/fft_frame.h
index a6022b9d852..bfd2abd1548 100644
--- a/chromium/third_party/blink/renderer/platform/audio/fft_frame.h
+++ b/chromium/third_party/blink/renderer/platform/audio/fft_frame.h
@@ -38,13 +38,13 @@
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/threading.h"
-#if defined(OS_MACOSX)
-#include <Accelerate/Accelerate.h>
-#elif defined(WTF_USE_WEBAUDIO_FFMPEG)
+#if defined(WTF_USE_WEBAUDIO_FFMPEG)
struct RDFTContext;
#elif defined(WTF_USE_WEBAUDIO_PFFFT)
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "third_party/pffft/src/pffft.h"
+#elif defined(OS_MACOSX)
+#include <Accelerate/Accelerate.h>
#endif
namespace blink {
@@ -83,10 +83,10 @@ class PLATFORM_EXPORT FFTFrame {
// least |fft_size_| elements.
void DoInverseFFT(float* data);
- float* RealData() { return real_data_.Data(); }
- const float* RealData() const { return real_data_.Data(); }
- float* ImagData() { return imag_data_.Data(); }
- const float* ImagData() const { return imag_data_.Data(); }
+ AudioFloatArray& RealData() { return real_data_; }
+ const AudioFloatArray& RealData() const { return real_data_; }
+ AudioFloatArray& ImagData() { return imag_data_; }
+ const AudioFloatArray& ImagData() const { return imag_data_; }
unsigned FftSize() const { return fft_size_; }
unsigned Log2FFTSize() const { return log2fft_size_; }
@@ -144,7 +144,7 @@ class PLATFORM_EXPORT FFTFrame {
AudioFloatArray real_data_;
AudioFloatArray imag_data_;
-#if defined(OS_MACOSX)
+#if defined(OS_MACOSX) && !defined(WTF_USE_WEBAUDIO_PFFFT)
// Thin wrapper around FFTSetup so we can call the appropriate routines to
// construct or release the FFTSetup objects.
class FFTSetupDatum {
diff --git a/chromium/third_party/blink/renderer/platform/audio/hrtf_panner.cc b/chromium/third_party/blink/renderer/platform/audio/hrtf_panner.cc
index a4c440b1b87..cc12303b7f6 100644
--- a/chromium/third_party/blink/renderer/platform/audio/hrtf_panner.cc
+++ b/chromium/third_party/blink/renderer/platform/audio/hrtf_panner.cc
@@ -42,7 +42,7 @@ const double kMaxDelayTimeSeconds = 0.002;
const int kUninitializedAzimuth = -1;
HRTFPanner::HRTFPanner(float sample_rate, HRTFDatabaseLoader* database_loader)
- : Panner(kPanningModelHRTF),
+ : Panner(PanningModel::kHRTF),
database_loader_(database_loader),
sample_rate_(sample_rate),
crossfade_selection_(kCrossfadeSelection1),
diff --git a/chromium/third_party/blink/renderer/platform/audio/mac/fft_frame_mac.cc b/chromium/third_party/blink/renderer/platform/audio/mac/fft_frame_mac.cc
index 8b77f6dae3d..3315687447f 100644
--- a/chromium/third_party/blink/renderer/platform/audio/mac/fft_frame_mac.cc
+++ b/chromium/third_party/blink/renderer/platform/audio/mac/fft_frame_mac.cc
@@ -30,7 +30,7 @@
#include "build/build_config.h"
-#if defined(OS_MACOSX)
+#if defined(OS_MACOSX) && !defined(WTF_USE_WEBAUDIO_PFFFT)
#include "third_party/blink/renderer/platform/audio/fft_frame.h"
#include "third_party/blink/renderer/platform/audio/hrtf_panner.h"
@@ -131,8 +131,8 @@ FFTFrame::FFTFrame(const FFTFrame& frame)
// Copy/setup frame data
unsigned nbytes = sizeof(float) * fft_size_;
- memcpy(RealData(), frame.frame_.realp, nbytes);
- memcpy(ImagData(), frame.frame_.imagp, nbytes);
+ memcpy(RealData().Data(), frame.frame_.realp, nbytes);
+ memcpy(ImagData().Data(), frame.frame_.imagp, nbytes);
}
FFTFrame::~FFTFrame() {}
@@ -201,4 +201,4 @@ void FFTFrame::Cleanup() {
} // namespace blink
-#endif // #if defined(OS_MACOSX)
+#endif // #if defined(OS_MACOSX) && !defined(WTF_USE_WEBAUDIO_PFFFT)
diff --git a/chromium/third_party/blink/renderer/platform/audio/media_multi_channel_resampler.cc b/chromium/third_party/blink/renderer/platform/audio/media_multi_channel_resampler.cc
index 97778014ac3..9f01d98e939 100644
--- a/chromium/third_party/blink/renderer/platform/audio/media_multi_channel_resampler.cc
+++ b/chromium/third_party/blink/renderer/platform/audio/media_multi_channel_resampler.cc
@@ -24,8 +24,21 @@ MediaMultiChannelResampler::MediaMultiChannelResampler(
}
void MediaMultiChannelResampler::Resample(int frames,
- media::AudioBus* audio_bus) {
- resampler_->Resample(audio_bus->frames(), audio_bus);
+ blink::AudioBus* audio_bus) {
+ // Create a media::AudioBus wrapper around the memory provided by the
+ // blink::AudioBus.
+ std::unique_ptr<media::AudioBus> resampler_bus_ =
+ media::AudioBus::CreateWrapper(audio_bus->NumberOfChannels());
+ for (unsigned int i = 0; i < audio_bus->NumberOfChannels(); ++i) {
+ resampler_bus_->SetChannelData(i, audio_bus->Channel(i)->MutableData());
+ }
+ resampler_bus_->set_frames(audio_bus->length());
+ ResampleInternal(frames, resampler_bus_.get());
+}
+
+void MediaMultiChannelResampler::ResampleInternal(int frames,
+ media::AudioBus* audio_bus) {
+ resampler_->Resample(frames, audio_bus);
}
void MediaMultiChannelResampler::ProvideResamplerInput(
diff --git a/chromium/third_party/blink/renderer/platform/audio/media_multi_channel_resampler.h b/chromium/third_party/blink/renderer/platform/audio/media_multi_channel_resampler.h
index 73b8b34af94..18992a98c2c 100644
--- a/chromium/third_party/blink/renderer/platform/audio/media_multi_channel_resampler.h
+++ b/chromium/third_party/blink/renderer/platform/audio/media_multi_channel_resampler.h
@@ -31,7 +31,7 @@ class PLATFORM_EXPORT MediaMultiChannelResampler {
// frames are available to satisfy the request. |frame_delay| is the number
// of output frames already processed and can be used to estimate delay.
typedef WTF::CrossThreadRepeatingFunction<void(int frame_delay,
- AudioBus* audio_bus)>
+ blink::AudioBus* audio_bus)>
ReadCB;
public:
@@ -44,8 +44,16 @@ class PLATFORM_EXPORT MediaMultiChannelResampler {
size_t request_frames,
ReadCB read_cb);
- // Resamples |frames| of data from |read_cb_| into AudioBus.
- void Resample(int frames, media::AudioBus* audio_bus);
+ // Resamples |frames| of data from |read_cb_| into a blink::AudioBus, this
+ // requires creating a wrapper for the media::AudioBus on each call and so
+ // resampling directly into a media::AudioBus using ResampleInternal() is
+ // preferred if possible.
+ void Resample(int frames, blink::AudioBus* audio_bus);
+
+ // Resamples |frames| of data from |read_cb_| into a media::AudioBus by
+ // directly calling Resample() on the underlying
+ // media::MultiChannelResampler.
+ void ResampleInternal(int frames, media::AudioBus* audio_bus);
private:
// Wrapper method used to provide input to the media::MultiChannelResampler
diff --git a/chromium/third_party/blink/renderer/platform/audio/multi_channel_resampler.cc b/chromium/third_party/blink/renderer/platform/audio/multi_channel_resampler.cc
deleted file mode 100644
index ee5c7dac00d..00000000000
--- a/chromium/third_party/blink/renderer/platform/audio/multi_channel_resampler.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-#include "third_party/blink/renderer/platform/audio/multi_channel_resampler.h"
-
-#include <memory>
-#include "third_party/blink/renderer/platform/audio/audio_bus.h"
-
-namespace blink {
-
-namespace {
-
-// ChannelProvider provides a single channel of audio data (one channel at a
-// time) for each channel of data provided to us in a multi-channel provider.
-
-class ChannelProvider final : public AudioSourceProvider {
- public:
- ChannelProvider(AudioSourceProvider* multi_channel_provider,
- unsigned number_of_channels)
- : multi_channel_provider_(multi_channel_provider),
- number_of_channels_(number_of_channels),
- current_channel_(0),
- frames_to_process_(0) {}
-
- // provideInput() will be called once for each channel, starting with the
- // first channel. Each time it's called, it will provide the next channel of
- // data.
- void ProvideInput(AudioBus* bus, uint32_t frames_to_process) override {
- DCHECK(bus);
- DCHECK_EQ(bus->NumberOfChannels(), 1u);
-
- // Get the data from the multi-channel provider when the first channel asks
- // for it. For subsequent channels, we can just dish out the channel data
- // from that (stored in m_multiChannelBus).
- if (!current_channel_) {
- frames_to_process_ = frames_to_process;
- multi_channel_bus_ =
- AudioBus::Create(number_of_channels_, frames_to_process);
- multi_channel_provider_->ProvideInput(multi_channel_bus_.get(),
- frames_to_process);
- }
-
- DCHECK(multi_channel_bus_.get());
- DCHECK_EQ(frames_to_process, frames_to_process_);
-
- // Copy the channel data from what we received from m_multiChannelProvider.
- DCHECK_LT(current_channel_, number_of_channels_);
- memcpy(bus->Channel(0)->MutableData(),
- multi_channel_bus_->Channel(current_channel_)->Data(),
- sizeof(float) * frames_to_process);
- ++current_channel_;
- }
-
- private:
- AudioSourceProvider* multi_channel_provider_;
- scoped_refptr<AudioBus> multi_channel_bus_;
- unsigned number_of_channels_;
- unsigned current_channel_;
- // Used to verify that all channels ask for the same amount.
- uint32_t frames_to_process_;
-};
-
-} // namespace
-
-MultiChannelResampler::MultiChannelResampler(double scale_factor,
- unsigned number_of_channels)
- : number_of_channels_(number_of_channels) {
- // Create each channel's resampler.
- for (unsigned channel_index = 0; channel_index < number_of_channels;
- ++channel_index)
- kernels_.push_back(std::make_unique<SincResampler>(scale_factor));
-}
-
-void MultiChannelResampler::Process(AudioSourceProvider* provider,
- AudioBus* destination,
- uint32_t frames_to_process) {
- // The provider can provide us with multi-channel audio data. But each of our
- // single-channel resamplers (kernels) below requires a provider which
- // provides a single unique channel of data. channelProvider wraps the
- // original multi-channel provider and dishes out one channel at a time.
- ChannelProvider channel_provider(provider, number_of_channels_);
-
- for (unsigned channel_index = 0; channel_index < number_of_channels_;
- ++channel_index) {
- // Depending on the sample-rate scale factor, and the internal buffering
- // used in a SincResampler kernel, this call to process() will only
- // sometimes call provideInput() on the channelProvider. However, if it
- // calls provideInput() for the first channel, then it will call it for the
- // remaining channels, since they all buffer in the same way and are
- // processing the same number of frames.
- kernels_[channel_index]->Process(
- &channel_provider, destination->Channel(channel_index)->MutableData(),
- frames_to_process);
- }
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/audio/multi_channel_resampler.h b/chromium/third_party/blink/renderer/platform/audio/multi_channel_resampler.h
deleted file mode 100644
index 84eaa98e616..00000000000
--- a/chromium/third_party/blink/renderer/platform/audio/multi_channel_resampler.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_AUDIO_MULTI_CHANNEL_RESAMPLER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_AUDIO_MULTI_CHANNEL_RESAMPLER_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "third_party/blink/renderer/platform/audio/sinc_resampler.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
-
-namespace blink {
-
-class AudioBus;
-
-class PLATFORM_EXPORT MultiChannelResampler {
- USING_FAST_MALLOC(MultiChannelResampler);
-
- public:
- MultiChannelResampler(double scale_factor, unsigned number_of_channels);
-
- // Process given AudioSourceProvider for streaming applications.
- void Process(AudioSourceProvider*,
- AudioBus* destination,
- uint32_t frames_to_process);
-
- private:
- // FIXME: the mac port can have a more highly optimized implementation based
- // on CoreAudio instead of SincResampler. For now the default implementation
- // will be used on all ports.
- // https://bugs.webkit.org/show_bug.cgi?id=75118
-
- // Each channel will be resampled using a high-quality SincResampler.
- Vector<std::unique_ptr<SincResampler>> kernels_;
-
- unsigned number_of_channels_;
-
- DISALLOW_COPY_AND_ASSIGN(MultiChannelResampler);
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_AUDIO_MULTI_CHANNEL_RESAMPLER_H_
diff --git a/chromium/third_party/blink/renderer/platform/audio/panner.cc b/chromium/third_party/blink/renderer/platform/audio/panner.cc
index dfb9d7cf7c4..5721c6b7ccc 100644
--- a/chromium/third_party/blink/renderer/platform/audio/panner.cc
+++ b/chromium/third_party/blink/renderer/platform/audio/panner.cc
@@ -38,16 +38,14 @@ std::unique_ptr<Panner> Panner::Create(PanningModel model,
float sample_rate,
HRTFDatabaseLoader* database_loader) {
switch (model) {
- case kPanningModelEqualPower:
+ case PanningModel::kEqualPower:
return std::make_unique<EqualPowerPanner>(sample_rate);
- case kPanningModelHRTF:
+ case PanningModel::kHRTF:
return std::make_unique<HRTFPanner>(sample_rate, database_loader);
-
- default:
- NOTREACHED();
- return nullptr;
}
+ NOTREACHED();
+ return nullptr;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/audio/panner.h b/chromium/third_party/blink/renderer/platform/audio/panner.h
index 1b5e3357fba..b2bed74ccb7 100644
--- a/chromium/third_party/blink/renderer/platform/audio/panner.h
+++ b/chromium/third_party/blink/renderer/platform/audio/panner.h
@@ -46,10 +46,13 @@ class PLATFORM_EXPORT Panner {
USING_FAST_MALLOC(Panner);
public:
- // This values are used in histograms and should not be renumbered or deleted.
- enum { kPanningModelEqualPower = 0, kPanningModelHRTF = 1 };
-
- typedef unsigned PanningModel;
+ // These values are persisted to logs. Entries should not be renumbered and
+ // numeric values should never be reused.
+ enum class PanningModel {
+ kEqualPower = 0,
+ kHRTF = 1,
+ kMaxValue = kHRTF,
+ };
static std::unique_ptr<Panner> Create(PanningModel,
float sample_rate,
@@ -77,7 +80,7 @@ class PLATFORM_EXPORT Panner {
virtual bool RequiresTailProcessing() const = 0;
protected:
- Panner(PanningModel model) : panning_model_(model) {}
+ explicit Panner(PanningModel model) : panning_model_(model) {}
PanningModel panning_model_;
diff --git a/chromium/third_party/blink/renderer/platform/audio/pffft/fft_frame_pffft.cc b/chromium/third_party/blink/renderer/platform/audio/pffft/fft_frame_pffft.cc
index 7432ad58e2e..620188fff08 100644
--- a/chromium/third_party/blink/renderer/platform/audio/pffft/fft_frame_pffft.cc
+++ b/chromium/third_party/blink/renderer/platform/audio/pffft/fft_frame_pffft.cc
@@ -111,8 +111,8 @@ FFTFrame::FFTFrame(const FFTFrame& frame)
// Copy/setup frame data.
unsigned nbytes = sizeof(float) * (fft_size_ / 2);
- memcpy(RealData(), frame.RealData(), nbytes);
- memcpy(ImagData(), frame.ImagData(), nbytes);
+ memcpy(RealData().Data(), frame.RealData().Data(), nbytes);
+ memcpy(ImagData().Data(), frame.ImagData().Data(), nbytes);
}
int FFTFrame::MinFFTSize() {
diff --git a/chromium/third_party/blink/renderer/platform/audio/push_pull_fifo.cc b/chromium/third_party/blink/renderer/platform/audio/push_pull_fifo.cc
index 81e8266794c..cc56b77e982 100644
--- a/chromium/third_party/blink/renderer/platform/audio/push_pull_fifo.cc
+++ b/chromium/third_party/blink/renderer/platform/audio/push_pull_fifo.cc
@@ -7,9 +7,9 @@
#include <algorithm>
#include <memory>
+#include "base/metrics/histogram_functions.h"
#include "build/build_config.h"
#include "third_party/blink/renderer/platform/audio/audio_utilities.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
namespace blink {
@@ -40,20 +40,16 @@ PushPullFIFO::~PushPullFIFO() {
// Capture the percentage of underflow happened based on the total pull count.
// (100 buckets of size 1) This is equivalent of
// "Media.AudioRendererMissedDeadline" metric for WebAudio.
- DEFINE_STATIC_LOCAL(
- LinearHistogram,
- fifo_underflow_percentage_histogram,
- ("WebAudio.PushPullFIFO.UnderflowPercentage", 1, 100, 101));
- fifo_underflow_percentage_histogram.Count(
+ base::UmaHistogramPercentage(
+ "WebAudio.PushPullFIFO.UnderflowPercentage",
static_cast<int32_t>(100.0 * underflow_count_ / pull_count_));
// We only collect the underflow count because no overflow can happen in the
// current implementation. This is similar to
// "Media.AudioRendererAudioGlitches" metric for WebAudio, which is a simple
// flag indicates any instance of glitches during FIFO's lifetime.
- DEFINE_STATIC_LOCAL(BooleanHistogram, fifo_underflow_glitches_histogram,
- ("WebAudio.PushPullFIFO.UnderflowGlitches"));
- fifo_underflow_glitches_histogram.Count(underflow_count_ > 0);
+ base::UmaHistogramBoolean("WebAudio.PushPullFIFO.UnderflowGlitches",
+ underflow_count_ > 0);
}
// Push the data from |input_bus| to FIFO. The size of push is determined by
diff --git a/chromium/third_party/blink/renderer/platform/bindings/active_script_wrappable_base.cc b/chromium/third_party/blink/renderer/platform/bindings/active_script_wrappable_base.cc
index e56d98347f9..6a451b02b7f 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/active_script_wrappable_base.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/active_script_wrappable_base.cc
@@ -45,7 +45,8 @@ void ActiveScriptWrappableBase::TraceActiveScriptWrappables(
if (!active_wrappable->DispatchHasPendingActivity())
continue;
- ScriptWrappable* script_wrappable = active_wrappable->ToScriptWrappable();
+ const ScriptWrappable* script_wrappable =
+ active_wrappable->ToScriptWrappable();
visitor->Trace(script_wrappable);
}
}
diff --git a/chromium/third_party/blink/renderer/platform/bindings/active_script_wrappable_base.h b/chromium/third_party/blink/renderer/platform/bindings/active_script_wrappable_base.h
index f3e3f040e61..cf158f453c5 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/active_script_wrappable_base.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/active_script_wrappable_base.h
@@ -31,7 +31,7 @@ class PLATFORM_EXPORT ActiveScriptWrappableBase : public GarbageCollectedMixin {
virtual bool IsContextDestroyed() const = 0;
virtual bool DispatchHasPendingActivity() const = 0;
- virtual ScriptWrappable* ToScriptWrappable() = 0;
+ virtual const ScriptWrappable* ToScriptWrappable() const = 0;
private:
DISALLOW_COPY_AND_ASSIGN(ActiveScriptWrappableBase);
diff --git a/chromium/third_party/blink/renderer/platform/bindings/blink_isolate/blink_isolate.cc b/chromium/third_party/blink/renderer/platform/bindings/blink_isolate/blink_isolate.cc
new file mode 100644
index 00000000000..68332fece42
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/bindings/blink_isolate/blink_isolate.cc
@@ -0,0 +1,22 @@
+// 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/bindings/blink_isolate/blink_isolate.h"
+
+namespace blink {
+
+// TODO(crbug.com/1051395) Actually instantiate multiple blink isolates.
+static BlinkIsolate* g_single_isolate = nullptr;
+
+BlinkIsolate* BlinkIsolate::GetCurrent() {
+ return g_single_isolate;
+}
+
+BlinkIsolate::BlinkIsolate() {
+ g_single_isolate = this;
+}
+
+BlinkIsolate::~BlinkIsolate() = default;
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/bindings/blink_isolate/blink_isolate.h b/chromium/third_party/blink/renderer/platform/bindings/blink_isolate/blink_isolate.h
new file mode 100644
index 00000000000..e48db29c9ac
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/bindings/blink_isolate/blink_isolate.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_BINDINGS_BLINK_ISOLATE_BLINK_ISOLATE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_BLINK_ISOLATE_BLINK_ISOLATE_H_
+
+#include "third_party/blink/public/platform/web_isolate.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+
+namespace blink {
+
+// An BlinkIsolate is a memory and scheduling isolation boundary in Blink,
+// which is currently being introduced as a part of Multiple Blink Isolates
+// project.
+// TODO(crbug.com/1051790): is the tracking bug for the project.
+//
+// An Isolate will hold a distinct memory region (V8 and Oilpan heaps),
+// and a dedicated scheduler.
+class PLATFORM_EXPORT BlinkIsolate : public WebIsolate {
+ public:
+ // Get the currently active BlinkIsolate. GetCurrent() may return nullptr if
+ // there is no active BlinkIsolate.
+ // TODO(crbug.com/1051395): GetCurrent() returns the singleton BlinkIsolate
+ // instance for now, but will change once we start instantiating multiple
+ // BlinkIsolates.
+ static BlinkIsolate* GetCurrent();
+
+ BlinkIsolate();
+ ~BlinkIsolate() override;
+
+ private:
+ BlinkIsolate(const BlinkIsolate&) = delete;
+ BlinkIsolate& operator=(const BlinkIsolate&) = delete;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_BLINK_ISOLATE_BLINK_ISOLATE_H_
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 65fe7e63b89..942043b0907 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(blink::Visitor* visitor);
+ virtual void Trace(Visitor* visitor);
v8::Local<v8::Object> CallbackObject() {
return callback_function_.NewLocal(GetIsolate());
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 6176390dcec..6c303236d50 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(blink::Visitor*);
+ virtual void Trace(Visitor*);
// 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/callback_method_retriever.h b/chromium/third_party/blink/renderer/platform/bindings/callback_method_retriever.h
index 5187367c974..652ff138557 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/callback_method_retriever.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/callback_method_retriever.h
@@ -75,7 +75,7 @@ class PLATFORM_EXPORT CallbackMethodRetriever {
const StringView& property,
ExceptionState&);
- Member<CallbackFunctionBase> constructor_;
+ CallbackFunctionBase* constructor_;
v8::Isolate* isolate_;
v8::Local<v8::Context> current_context_;
v8::Local<v8::Object> prototype_object_;
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 6ee38d858ba..0d81ab9e815 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/dictionary_base.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/dictionary_base.h
@@ -10,6 +10,9 @@
#include "v8/include/v8.h"
namespace blink {
+
+class Visitor;
+
namespace bindings {
// This class is the base class for all IDL dictionary implementations. This is
@@ -33,6 +36,8 @@ class PLATFORM_EXPORT DictionaryBase : public GarbageCollected<DictionaryBase> {
return v8_object;
}
+ virtual void Trace(Visitor*) {}
+
protected:
DictionaryBase() = default;
@@ -41,7 +46,7 @@ class PLATFORM_EXPORT DictionaryBase : public GarbageCollected<DictionaryBase> {
DictionaryBase& operator=(const DictionaryBase&) = delete;
DictionaryBase& operator=(const DictionaryBase&&) = delete;
- virtual void FillWithMembers(v8::Isolate* isolate,
+ virtual bool FillWithMembers(v8::Isolate* isolate,
v8::Local<v8::Object> creation_context,
v8::Local<v8::Object> v8_object) const = 0;
};
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 5e10e7024b2..e0b991138b5 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
@@ -10,20 +10,16 @@ DOMDataStore::DOMDataStore(v8::Isolate* isolate, bool is_main_world)
: is_main_world_(is_main_world) {}
void DOMDataStore::Dispose() {
- for (const auto& it : wrapper_map_) {
+ for (auto& it : wrapper_map_) {
// Explicitly reset references so that a following V8 GC will not find them
// and treat them as roots. There's optimizations (see
// EmbedderHeapTracer::IsRootForNonTracingGC) that would not treat them as
// roots and then Blink would not be able to find and remove them from a DOM
// world. Explicitly resetting on disposal avoids that problem
- it.value->ref.Clear();
+ it.value.Clear();
}
}
-void DOMDataStore::WrappedReference::Trace(Visitor* visitor) {
- visitor->Trace(ref);
-}
-
void DOMDataStore::Trace(Visitor* visitor) {
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 975c6b567c9..0d8cfbc5ce7 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
@@ -35,6 +35,7 @@
#include "base/optional.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h"
#include "third_party/blink/renderer/platform/bindings/wrapper_type_info.h"
#include "third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -118,7 +119,7 @@ class DOMDataStore final : public GarbageCollected<DOMDataStore> {
return object->MainWorldWrapper(isolate);
auto it = wrapper_map_.find(object);
if (it != wrapper_map_.end())
- return it->value->ref.NewLocal(isolate);
+ return it->value.NewLocal(isolate);
return v8::Local<v8::Object>();
}
@@ -132,13 +133,12 @@ class DOMDataStore final : public GarbageCollected<DOMDataStore> {
return object->SetWrapper(isolate, wrapper_type_info, wrapper);
auto result = wrapper_map_.insert(
- object, MakeGarbageCollected<WrappedReference>(isolate, wrapper));
+ object, TraceWrapperV8Reference<v8::Object>(isolate, wrapper));
if (LIKELY(result.is_new_entry)) {
- wrapper_type_info->ConfigureWrapper(
- &result.stored_value->value->ref.Get());
+ wrapper_type_info->ConfigureWrapper(&result.stored_value->value.Get());
} else {
- DCHECK(!result.stored_value->value->ref.IsEmpty());
- wrapper = result.stored_value->value->ref.NewLocal(isolate);
+ DCHECK(!result.stored_value->value.IsEmpty());
+ wrapper = result.stored_value->value.NewLocal(isolate);
}
return result.is_new_entry;
}
@@ -149,8 +149,8 @@ class DOMDataStore final : public GarbageCollected<DOMDataStore> {
DCHECK(!is_main_world_);
const auto& it = wrapper_map_.find(object);
if (it != wrapper_map_.end()) {
- if (it->value->ref.Get() == handle) {
- it->value->ref.Clear();
+ if (it->value.Get() == handle) {
+ it->value.Clear();
wrapper_map_.erase(it);
return true;
}
@@ -164,7 +164,7 @@ class DOMDataStore final : public GarbageCollected<DOMDataStore> {
return object->SetReturnValue(return_value);
auto it = wrapper_map_.find(object);
if (it != wrapper_map_.end()) {
- return_value.Set(it->value->ref.Get());
+ return_value.Set(it->value.Get());
return true;
}
return false;
@@ -198,24 +198,10 @@ class DOMDataStore final : public GarbageCollected<DOMDataStore> {
return wrappable->IsEqualTo(holder);
}
- // Wrapper around TraceWrapperV8Reference to allow use in ephemeron hash map
- // below.
- class PLATFORM_EXPORT WrappedReference final
- : public GarbageCollected<WrappedReference> {
- public:
- WrappedReference() = default;
- WrappedReference(v8::Isolate* isolate, v8::Local<v8::Object> handle)
- : ref(isolate, handle) {}
-
- virtual void Trace(Visitor*);
-
- TraceWrapperV8Reference<v8::Object> ref;
- };
-
bool is_main_world_;
- // Ephemeron map: WrappedReference will be kept alive as long as
- // ScriptWrappable is alive.
- HeapHashMap<WeakMember<const ScriptWrappable>, Member<WrappedReference>>
+ // Ephemeron map: V8 wrapper will be kept alive as long as ScriptWrappable is.
+ HeapHashMap<WeakMember<const ScriptWrappable>,
+ TraceWrapperV8Reference<v8::Object>>
wrapper_map_;
DISALLOW_COPY_AND_ASSIGN(DOMDataStore);
diff --git a/chromium/third_party/blink/renderer/platform/bindings/enumeration_base.h b/chromium/third_party/blink/renderer/platform/bindings/enumeration_base.h
new file mode 100644
index 00000000000..f5e0fcf185a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/bindings/enumeration_base.h
@@ -0,0 +1,92 @@
+// 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_BINDINGS_ENUMERATION_BASE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_ENUMERATION_BASE_H_
+
+#include <type_traits>
+
+#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/text/atomic_string.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+namespace bindings {
+
+class PLATFORM_EXPORT EnumerationBase {
+ DISALLOW_NEW();
+
+ public:
+ ~EnumerationBase() = default;
+
+ const char* AsCStr() const { return string_literal_; }
+ String AsString() const { return string_literal_; }
+
+ // Migration adapter
+ operator AtomicString() const { return string_literal_; }
+ operator String() const { return string_literal_; }
+
+ // Returns true if the value is invalid. The instance in this state must be
+ // created only when an exception is thrown.
+ bool IsEmpty() const { return !string_literal_; }
+
+ protected:
+ // Integer type that is convertible from/to enum values defined in subclasses.
+ using enum_int_t = size_t;
+
+ constexpr EnumerationBase() = default;
+ explicit constexpr EnumerationBase(enum_int_t enum_value,
+ const char* string_literal)
+ : enum_value_(enum_value), string_literal_(string_literal) {}
+ constexpr EnumerationBase(const EnumerationBase&) = default;
+ constexpr EnumerationBase(EnumerationBase&&) = default;
+
+ EnumerationBase& operator=(const EnumerationBase&) = default;
+ EnumerationBase& operator=(EnumerationBase&&) = default;
+
+ enum_int_t GetEnumValue() const { return enum_value_; }
+
+ private:
+ // Subclasses are supposed to define a C++ enum class and a table of strings
+ // that represent IDL enumeration values. |enum_value_| is an enum value of
+ // the C++ enum class (must be convertible from/to enum_int_t) and
+ // |string_literal_| is a pointer to a string in the table.
+ enum_int_t enum_value_ = 0;
+ const char* string_literal_ = nullptr;
+
+ template <typename T>
+ friend typename std::
+ enable_if_t<std::is_base_of<bindings::EnumerationBase, T>::value, bool>
+ operator==(const T& lhs, const T& rhs);
+
+ template <typename T>
+ friend typename std::
+ enable_if_t<std::is_base_of<bindings::EnumerationBase, T>::value, bool>
+ operator!=(const T& lhs, const T& rhs);
+};
+
+} // namespace bindings
+
+template <typename T>
+typename std::enable_if_t<std::is_base_of<bindings::EnumerationBase, T>::value,
+ bool>
+operator==(const T& lhs, const T& rhs) {
+ DCHECK(!lhs.IsEmpty() && !rhs.IsEmpty());
+ return lhs.string_literal_ == rhs.string_literal_;
+}
+
+template <typename T>
+typename std::enable_if_t<std::is_base_of<bindings::EnumerationBase, T>::value,
+ bool>
+operator!=(const T& lhs, const T& rhs) {
+ DCHECK(!lhs.IsEmpty() && !rhs.IsEmpty());
+ return lhs.string_literal_ != rhs.string_literal_;
+}
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_ENUMERATION_BASE_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 c9f4ac49bd9..e2f8e5672d6 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/parkable_string.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/parkable_string.cc
@@ -186,6 +186,18 @@ enum class ParkableStringImpl::Status : uint8_t {
kLocked
};
+ParkableStringImpl::ParkableMetadata::ParkableMetadata(
+ String string,
+ std::unique_ptr<SecureDigest> digest)
+ : mutex_(),
+ lock_depth_(0),
+ state_(State::kUnparked),
+ compressed_(nullptr),
+ digest_(*digest),
+ is_young_(true),
+ is_8bit_(string.Is8Bit()),
+ length_(string.length()) {}
+
// static
std::unique_ptr<ParkableStringImpl::SecureDigest>
ParkableStringImpl::HashString(StringImpl* string) {
@@ -224,15 +236,10 @@ scoped_refptr<ParkableStringImpl> ParkableStringImpl::MakeParkable(
ParkableStringImpl::ParkableStringImpl(scoped_refptr<StringImpl>&& impl,
std::unique_ptr<SecureDigest> digest)
- : mutex_(),
- lock_depth_(0),
- state_(State::kUnparked),
- string_(std::move(impl)),
- compressed_(nullptr),
- digest_(std::move(digest)),
- is_young_(true),
- is_8bit_(string_.Is8Bit()),
- length_(string_.length())
+ : string_(std::move(impl)),
+ metadata_(digest ? std::make_unique<ParkableMetadata>(string_,
+ std::move(digest))
+ : nullptr)
#if DCHECK_IS_ON()
,
owning_thread_(CurrentThread())
@@ -248,7 +255,8 @@ ParkableStringImpl::~ParkableStringImpl() {
DCHECK_EQ(0, lock_depth_for_testing());
AsanUnpoisonString(string_);
- DCHECK(state_ == State::kParked || state_ == State::kUnparked);
+ DCHECK(metadata_->state_ == State::kParked ||
+ metadata_->state_ == State::kUnparked);
ParkableStringManager::Instance().Remove(this);
}
@@ -257,8 +265,8 @@ void ParkableStringImpl::Lock() {
if (!may_be_parked())
return;
- MutexLocker locker(mutex_);
- lock_depth_ += 1;
+ MutexLocker locker(metadata_->mutex_);
+ metadata_->lock_depth_ += 1;
// Make young as this is a strong (but not certain) indication that the string
// will be accessed soon.
MakeYoung();
@@ -268,8 +276,8 @@ void ParkableStringImpl::Lock() {
void ParkableStringImpl::LockWithoutMakingYoung() {
DCHECK(may_be_parked());
- MutexLocker locker(mutex_);
- lock_depth_ += 1;
+ MutexLocker locker(metadata_->mutex_);
+ metadata_->lock_depth_ += 1;
}
#endif // defined(ADDRESS_SANITIZER)
@@ -278,9 +286,9 @@ void ParkableStringImpl::Unlock() {
if (!may_be_parked())
return;
- MutexLocker locker(mutex_);
- DCHECK_GT(lock_depth_, 0);
- lock_depth_ -= 1;
+ MutexLocker locker(metadata_->mutex_);
+ DCHECK_GT(metadata_->lock_depth_, 0);
+ metadata_->lock_depth_ -= 1;
#if defined(ADDRESS_SANITIZER) && DCHECK_IS_ON()
// There are no external references to the data, nobody should touch the data.
@@ -302,13 +310,8 @@ void ParkableStringImpl::Unlock() {
void ParkableStringImpl::PurgeMemory() {
AssertOnValidThread();
- if (state_ == State::kUnparked)
- compressed_ = nullptr;
-}
-
-void ParkableStringImpl::MakeYoung() {
- mutex_.AssertAcquired();
- is_young_ = true;
+ if (metadata_->state_ == State::kUnparked)
+ metadata_->compressed_ = nullptr;
}
const String& ParkableStringImpl::ToString() {
@@ -316,7 +319,7 @@ const String& ParkableStringImpl::ToString() {
if (!may_be_parked())
return string_;
- MutexLocker locker(mutex_);
+ MutexLocker locker(metadata_->mutex_);
MakeYoung();
AsanUnpoisonString(string_);
Unpark();
@@ -325,21 +328,42 @@ const String& ParkableStringImpl::ToString() {
unsigned ParkableStringImpl::CharactersSizeInBytes() const {
AssertOnValidThread();
- return length_ * (is_8bit() ? sizeof(LChar) : sizeof(UChar));
+ if (!may_be_parked())
+ return string_.CharactersSizeInBytes();
+
+ return metadata_->length_ * (is_8bit() ? sizeof(LChar) : sizeof(UChar));
+}
+
+size_t ParkableStringImpl::MemoryFootprintForDump() const {
+ AssertOnValidThread();
+ size_t size = sizeof(ParkableStringImpl);
+
+ if (!may_be_parked())
+ return size + string_.CharactersSizeInBytes();
+
+ size += sizeof(ParkableMetadata);
+
+ if (!is_parked())
+ size += string_.CharactersSizeInBytes();
+
+ if (metadata_->compressed_)
+ size += metadata_->compressed_->size();
+
+ return size;
}
ParkableStringImpl::AgeOrParkResult ParkableStringImpl::MaybeAgeOrParkString() {
- MutexLocker locker(mutex_);
+ MutexLocker locker(metadata_->mutex_);
AssertOnValidThread();
DCHECK(may_be_parked());
DCHECK(!is_parked());
Status status = CurrentStatus();
- if (is_young_) {
+ if (metadata_->is_young_) {
if (status == Status::kUnreferencedExternally)
- is_young_ = false;
+ metadata_->is_young_ = false;
} else {
- if (state_ == State::kParkingInProgress)
+ if (metadata_->state_ == State::kParkingInProgress)
return AgeOrParkResult::kSuccessOrTransientFailure;
if (CanParkNow()) {
@@ -356,16 +380,17 @@ ParkableStringImpl::AgeOrParkResult ParkableStringImpl::MaybeAgeOrParkString() {
}
bool ParkableStringImpl::Park(ParkingMode mode) {
- MutexLocker locker(mutex_);
+ MutexLocker locker(metadata_->mutex_);
AssertOnValidThread();
DCHECK(may_be_parked());
- if (state_ == State::kParkingInProgress || state_ == State::kParked)
+ if (metadata_->state_ == State::kParkingInProgress ||
+ metadata_->state_ == State::kParked)
return true;
// Making the string old to cancel parking if it is accessed/locked before
// parking is complete.
- is_young_ = false;
+ metadata_->is_young_ = false;
if (!CanParkNow())
return false;
@@ -373,15 +398,42 @@ bool ParkableStringImpl::Park(ParkingMode mode) {
return true;
}
+bool ParkableStringImpl::is_parked() const {
+ DCHECK(may_be_parked());
+ return metadata_->state_ == State::kParked;
+}
+
+void ParkableStringImpl::MakeYoung() {
+ metadata_->is_young_ = true;
+}
+
+ParkableStringImpl::Status ParkableStringImpl::CurrentStatus() const {
+ AssertOnValidThread();
+ DCHECK(may_be_parked());
+ // Can park iff:
+ // - |this| is not locked.
+ // - There are no external reference to |string_|. Since |this| holds a
+ // reference to |string_|, it must the only one.
+ if (metadata_->lock_depth_ != 0)
+ return Status::kLocked;
+ if (!string_.Impl()->HasOneRef())
+ return Status::kTooManyReferences;
+ return Status::kUnreferencedExternally;
+}
+
+bool ParkableStringImpl::CanParkNow() const {
+ return CurrentStatus() == Status::kUnreferencedExternally &&
+ !metadata_->is_young_;
+}
+
void ParkableStringImpl::ParkInternal(ParkingMode mode) {
- mutex_.AssertAcquired();
- DCHECK_EQ(State::kUnparked, state_);
- DCHECK(!is_young_);
+ DCHECK_EQ(State::kUnparked, metadata_->state_);
+ DCHECK(!metadata_->is_young_);
DCHECK(CanParkNow());
// Parking can proceed synchronously.
if (has_compressed_data()) {
- state_ = State::kParked;
+ metadata_->state_ = State::kParked;
ParkableStringManager::Instance().OnParked(this);
// Must unpoison the memory before releasing it.
@@ -398,45 +450,21 @@ void ParkableStringImpl::ParkInternal(ParkingMode mode) {
FROM_HERE,
CrossThreadBindOnce(&ParkableStringImpl::CompressInBackground,
WTF::Passed(std::move(params))));
- state_ = State::kParkingInProgress;
+ metadata_->state_ = State::kParkingInProgress;
}
}
-bool ParkableStringImpl::is_parked() const {
- return state_ == State::kParked;
-}
-
-ParkableStringImpl::Status ParkableStringImpl::CurrentStatus() const {
- AssertOnValidThread();
- mutex_.AssertAcquired();
- DCHECK(may_be_parked());
- // Can park iff:
- // - |this| is not locked.
- // - There are no external reference to |string_|. Since |this| holds a
- // reference to |string_|, it must the only one.
- if (lock_depth_ != 0)
- return Status::kLocked;
- if (!string_.Impl()->HasOneRef())
- return Status::kTooManyReferences;
- return Status::kUnreferencedExternally;
-}
-
-bool ParkableStringImpl::CanParkNow() const {
- return CurrentStatus() == Status::kUnreferencedExternally && !is_young_;
-}
-
void ParkableStringImpl::Unpark() {
AssertOnValidThread();
DCHECK(may_be_parked());
- mutex_.AssertAcquired();
- if (state_ != State::kParked)
+ if (metadata_->state_ != State::kParked)
return;
TRACE_EVENT1("blink", "ParkableStringImpl::Unpark", "size",
CharactersSizeInBytes());
- DCHECK(compressed_);
+ DCHECK(metadata_->compressed_);
string_ = UnparkInternal();
- state_ = State::kUnparked;
+ metadata_->state_ = State::kUnparked;
ParkableStringManager::Instance().OnUnparked(this);
}
@@ -448,8 +476,8 @@ String ParkableStringImpl::UnparkInternal() const {
base::ElapsedTimer timer;
base::StringPiece compressed_string_piece(
- reinterpret_cast<const char*>(compressed_->data()),
- compressed_->size() * sizeof(uint8_t));
+ reinterpret_cast<const char*>(metadata_->compressed_->data()),
+ metadata_->compressed_->size() * sizeof(uint8_t));
String uncompressed;
base::StringPiece uncompressed_string_piece;
size_t size = CharactersSizeInBytes();
@@ -491,15 +519,15 @@ void ParkableStringImpl::OnParkingCompleteOnMainThread(
std::unique_ptr<CompressionTaskParams> params,
std::unique_ptr<Vector<uint8_t>> compressed,
base::TimeDelta parking_thread_time) {
- MutexLocker locker(mutex_);
- DCHECK_EQ(State::kParkingInProgress, state_);
+ MutexLocker locker(metadata_->mutex_);
+ DCHECK_EQ(State::kParkingInProgress, metadata_->state_);
// Always keep the compressed data. Compression is expensive, so even if the
// uncompressed representation cannot be discarded now, avoid compressing
// multiple times. This will allow synchronous parking next time.
- DCHECK(!compressed_);
+ DCHECK(!metadata_->compressed_);
if (compressed)
- compressed_ = std::move(compressed);
+ metadata_->compressed_ = std::move(compressed);
// Between |Park()| and now, things may have happened:
// 1. |ToString()| or
@@ -507,15 +535,15 @@ void ParkableStringImpl::OnParkingCompleteOnMainThread(
//
// Both of these will make the string young again, and if so we don't
// discard the compressed representation yet.
- if (CanParkNow() && compressed_) {
- state_ = State::kParked;
+ if (CanParkNow() && metadata_->compressed_) {
+ metadata_->state_ = State::kParked;
ParkableStringManager::Instance().OnParked(this);
// Must unpoison the memory before releasing it.
AsanUnpoisonString(string_);
string_ = String();
} else {
- state_ = State::kUnparked;
+ metadata_->state_ = State::kUnparked;
}
// Record the time no matter whether the string was parked or not, as the
// parking cost was paid.
@@ -606,6 +634,7 @@ void ParkableStringImpl::CompressInBackground(
RecordStatistics(size, timer.Elapsed(), ParkingAction::kParked);
}
+
ParkableString::ParkableString(scoped_refptr<StringImpl>&& impl) {
if (!impl) {
impl_ = nullptr;
@@ -634,14 +663,16 @@ void ParkableString::Unlock() const {
void ParkableString::OnMemoryDump(WebProcessMemoryDump* pmd,
const String& name) const {
- // Parkable strings are reported by ParkableStringManager.
- if (!impl_ || may_be_parked())
+ if (!impl_)
return;
auto* dump = pmd->CreateMemoryAllocatorDump(name);
- dump->AddScalar("size", "bytes", CharactersSizeInBytes());
- pmd->AddSuballocation(dump->Guid(),
- String(WTF::Partitions::kAllocatedObjectPoolName));
+ dump->AddScalar("size", "bytes", impl_->MemoryFootprintForDump());
+
+ const char* parent_allocation =
+ may_be_parked() ? ParkableStringManager::kAllocatorDumpName
+ : WTF::Partitions::kAllocatedObjectPoolName;
+ pmd->AddSuballocation(dump->Guid(), parent_allocation);
}
bool ParkableString::Is8Bit() const {
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 cd1b5ee2be8..b9d2bd8ef62 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/parkable_string.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/parkable_string.h
@@ -72,9 +72,29 @@ class PLATFORM_EXPORT ParkableStringImpl final
const String& ToString();
// See the matching String methods.
- bool is_8bit() const { return is_8bit_; }
- unsigned length() const { return length_; }
+ bool is_8bit() const {
+ if (!may_be_parked())
+ return string_.Is8Bit();
+
+ return metadata_->is_8bit_;
+ }
+ unsigned length() const {
+ if (!may_be_parked())
+ return string_.length();
+
+ return metadata_->length_;
+ }
unsigned CharactersSizeInBytes() const;
+ size_t MemoryFootprintForDump() const;
+
+ // Returns true iff the string can be parked. This does not mean that the
+ // string can be parked now, merely that it is eligible to be parked at some
+ // point.
+ bool may_be_parked() const { return !!metadata_; }
+
+ // Note: Public member functions below must only be called on strings for
+ // which |may_be_parked()| returns true. Otherwise, these will either trigger
+ // a DCHECK() or crash.
// Tries to either age or park a string:
//
@@ -98,32 +118,30 @@ class PLATFORM_EXPORT ParkableStringImpl final
//
// Returns true if the string is being parked or has been parked.
bool Park(ParkingMode mode);
- // Returns true iff the string can be parked. This does not mean that the
- // string can be parked now, merely that it is eligible to be parked at some
- // point.
- bool may_be_parked() const { return !!digest_; }
+
// Returns true if the string is parked.
bool is_parked() const;
+
// Returns whether synchronous parking is possible, that is the string was
// parked in the past.
- bool has_compressed_data() const { return !!compressed_; }
+ bool has_compressed_data() const { return !!metadata_->compressed_; }
+
// Returns the compressed size, must not be called unless the string has a
// compressed representation.
size_t compressed_size() const {
DCHECK(has_compressed_data());
- return compressed_->size();
+ return metadata_->compressed_->size();
}
bool is_young_for_testing() {
- MutexLocker locker(mutex_);
- return is_young_;
+ MutexLocker locker(metadata_->mutex_);
+ return metadata_->is_young_;
}
- // Must only be called on parkable ParkableStringImpls.
- SecureDigest* digest() const {
+ const SecureDigest* digest() const {
AssertOnValidThread();
- DCHECK(digest_);
- return digest_.get();
+ DCHECK(metadata_);
+ return &metadata_->digest_;
}
private:
@@ -136,20 +154,25 @@ class PLATFORM_EXPORT ParkableStringImpl final
ParkableStringImpl(scoped_refptr<StringImpl>&& impl,
std::unique_ptr<SecureDigest> digest);
+ // Note: Private member functions below must only be called on strings for
+ // which |may_be_parked()| returns true. Otherwise, these will either trigger
+ // a DCHECK() or crash.
+
#if defined(ADDRESS_SANITIZER)
// See |CompressInBackground()|. Doesn't make the string young.
// May be called from any thread.
void LockWithoutMakingYoung();
#endif // defined(ADDRESS_SANITIZER)
// May be called from any thread.
- void MakeYoung() EXCLUSIVE_LOCKS_REQUIRED(mutex_);
+ void MakeYoung() EXCLUSIVE_LOCKS_REQUIRED(metadata_->mutex_);
// Whether the string is referenced or locked. The return value is valid as
// long as |mutex_| is held.
- Status CurrentStatus() const EXCLUSIVE_LOCKS_REQUIRED(mutex_);
- bool CanParkNow() const EXCLUSIVE_LOCKS_REQUIRED(mutex_);
- void ParkInternal(ParkingMode mode);
- void Unpark();
- String UnparkInternal() const;
+ Status CurrentStatus() const EXCLUSIVE_LOCKS_REQUIRED(metadata_->mutex_);
+ bool CanParkNow() const EXCLUSIVE_LOCKS_REQUIRED(metadata_->mutex_);
+ void ParkInternal(ParkingMode mode)
+ EXCLUSIVE_LOCKS_REQUIRED(metadata_->mutex_);
+ void Unpark() EXCLUSIVE_LOCKS_REQUIRED(metadata_->mutex_);
+ String UnparkInternal() const EXCLUSIVE_LOCKS_REQUIRED(metadata_->mutex_);
// Called on the main thread after compression is done.
// |params| is the same as the one passed to |CompressInBackground()|,
// |compressed| is the compressed data, nullptr if compression failed.
@@ -164,31 +187,40 @@ class PLATFORM_EXPORT ParkableStringImpl final
static void CompressInBackground(std::unique_ptr<CompressionTaskParams>);
int lock_depth_for_testing() {
- MutexLocker locker_(mutex_);
- return lock_depth_;
+ MutexLocker locker_(metadata_->mutex_);
+ return metadata_->lock_depth_;
}
- Mutex mutex_;
- int lock_depth_ GUARDED_BY(mutex_);
+ // Metadata only used for parkable ParkableStrings.
+ struct ParkableMetadata {
+ ParkableMetadata(String string, std::unique_ptr<SecureDigest> digest);
+
+ Mutex mutex_;
+ int lock_depth_ GUARDED_BY(mutex_);
+
+ // Main thread only.
+ State state_;
+ std::unique_ptr<Vector<uint8_t>> compressed_;
+ const SecureDigest digest_;
+
+ // A string can either be "young" or "old". It starts young, and transitions
+ // are:
+ // Young -> Old: By calling |MaybeAgeOrParkString()|.
+ // Old -> Young: When the string is accessed, either by |Lock()|-ing it or
+ // calling |ToString()|.
+ //
+ // Thread safety: it is typically not safe to guard only one part of a
+ // bitfield with a mutex, but this is correct here, as the other members are
+ // const (and never change).
+ bool is_young_ : 1 GUARDED_BY(mutex_);
+ const bool is_8bit_ : 1;
+ const unsigned length_;
+
+ DISALLOW_COPY_AND_ASSIGN(ParkableMetadata);
+ };
- // Main thread only.
- State state_;
String string_;
- std::unique_ptr<Vector<uint8_t>> compressed_;
- const std::unique_ptr<SecureDigest> digest_;
-
- // A string can either be "young" or "old". It starts young, and transitions
- // are:
- // Young -> Old: By calling |MaybeAgeOrParkString()|.
- // Old -> Young: When the string is accessed, either by |Lock()|-ing it or
- // calling |ToString()|.
- //
- // Thread safety: it is typically not safe to guard only one part of a
- // bitfield with a mutex, but this is correct here, as the other members are
- // const (and never change).
- bool is_young_ : 1 GUARDED_BY(mutex_);
- const bool is_8bit_ : 1;
- const unsigned length_;
+ const std::unique_ptr<ParkableMetadata> metadata_;
#if DCHECK_IS_ON()
const base::PlatformThreadId owning_thread_;
@@ -200,13 +232,26 @@ class PLATFORM_EXPORT ParkableStringImpl final
#endif
}
- FRIEND_TEST_ALL_PREFIXES(ParkableStringTest, LockUnlock);
- FRIEND_TEST_ALL_PREFIXES(ParkableStringTest, LockParkedString);
+ public:
FRIEND_TEST_ALL_PREFIXES(ParkableStringTest, Equality);
FRIEND_TEST_ALL_PREFIXES(ParkableStringTest, EqualityNoUnparking);
+ FRIEND_TEST_ALL_PREFIXES(ParkableStringTest, LockUnlock);
+ FRIEND_TEST_ALL_PREFIXES(ParkableStringTest, LockParkedString);
+ FRIEND_TEST_ALL_PREFIXES(ParkableStringTest, ReportMemoryDump);
+ FRIEND_TEST_ALL_PREFIXES(ParkableStringTest, MemoryFootprintForDump);
+
DISALLOW_COPY_AND_ASSIGN(ParkableStringImpl);
};
+#if !DCHECK_IS_ON()
+// 3 pointers:
+// - vtable (from RefCounted)
+// - string_.Impl()
+// - metadata_
+static_assert(sizeof(ParkableStringImpl) == 3 * sizeof(void*),
+ "ParkableStringImpl should not be too large");
+#endif
+
class PLATFORM_EXPORT ParkableString final {
DISALLOW_NEW();
@@ -249,6 +294,9 @@ class PLATFORM_EXPORT ParkableString final {
scoped_refptr<ParkableStringImpl> impl_;
};
+static_assert(sizeof(ParkableString) == sizeof(void*),
+ "ParkableString should be small");
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_PARKABLE_STRING_H_
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 45da38a8126..dd987fac607 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
@@ -62,17 +62,20 @@ class OnPurgeMemoryListener : public GarbageCollected<OnPurgeMemoryListener>,
} // namespace
+const char* ParkableStringManager::kAllocatorDumpName = "parkable_strings";
+
// Compares not the pointers, but the arrays. Uses pointers to save space.
struct ParkableStringManager::SecureDigestHash {
STATIC_ONLY(SecureDigestHash);
- static unsigned GetHash(ParkableStringImpl::SecureDigest* const digest) {
+ static unsigned GetHash(
+ const ParkableStringImpl::SecureDigest* const digest) {
// The first bytes of the hash are as good as anything else.
return *reinterpret_cast<const unsigned*>(digest->data());
}
- static inline bool Equal(ParkableStringImpl::SecureDigest* const a,
- ParkableStringImpl::SecureDigest* const b) {
+ static inline bool Equal(const ParkableStringImpl::SecureDigest* const a,
+ const ParkableStringImpl::SecureDigest* const b) {
return a == b ||
std::equal(a->data(), a->data() + ParkableStringImpl::kDigestSize,
b->data());
@@ -121,7 +124,7 @@ bool ParkableStringManager::OnMemoryDump(
base::trace_event::ProcessMemoryDump* pmd) {
DCHECK(IsMainThread());
base::trace_event::MemoryAllocatorDump* dump =
- pmd->CreateAllocatorDump("parkable_strings");
+ pmd->CreateAllocatorDump(kAllocatorDumpName);
Statistics stats = ComputeStatistics();
@@ -375,7 +378,7 @@ ParkableStringManager::Statistics ParkableStringManager::ComputeStatistics()
// The digest has an inline capacity set to the digest size, hence sizeof() is
// accurate.
constexpr size_t kParkableStringImplActualSize =
- sizeof(ParkableStringImpl) + sizeof(ParkableStringImpl::SecureDigest);
+ sizeof(ParkableStringImpl) + sizeof(ParkableStringImpl::ParkableMetadata);
for (const auto& kv : unparked_strings_) {
ParkableStringImpl* str = kv.value;
@@ -386,6 +389,15 @@ ParkableStringManager::Statistics ParkableStringManager::ComputeStatistics()
if (str->has_compressed_data())
stats.overhead_size += str->compressed_size();
+
+ // Since ParkableStringManager wants to have a finer breakdown of memory
+ // footprint, this doesn't directly use
+ // |ParkableStringImpl::MemoryFootprintForDump()|. However we want the two
+ // computations to be consistent, hence the DCHECK().
+ size_t memory_footprint =
+ (str->has_compressed_data() ? str->compressed_size() : 0) + size +
+ kParkableStringImplActualSize;
+ DCHECK_EQ(memory_footprint, str->MemoryFootprintForDump());
}
for (const auto& kv : parked_strings_) {
@@ -395,6 +407,11 @@ ParkableStringManager::Statistics ParkableStringManager::ComputeStatistics()
stats.original_size += size;
stats.compressed_size += str->compressed_size();
stats.metadata_size += kParkableStringImplActualSize;
+
+ // See comment above.
+ size_t memory_footprint =
+ str->compressed_size() + kParkableStringImplActualSize;
+ DCHECK_EQ(memory_footprint, str->MemoryFootprintForDump());
}
stats.total_size = stats.uncompressed_size + stats.compressed_size +
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 ecc958b620f..e7fd7298c4d 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
@@ -67,6 +67,8 @@ class PLATFORM_EXPORT ParkableStringManager {
// Public for testing.
constexpr static int kAgingIntervalInSeconds = 2;
+ static const char* kAllocatorDumpName;
+
private:
friend class ParkableString;
friend class ParkableStringImpl;
@@ -102,11 +104,11 @@ class PLATFORM_EXPORT ParkableStringManager {
// Relies on secure hash equality for deduplication. If one day SHA256 becomes
// insecure, then this would need to be updated to a more robust hash.
- WTF::HashMap<ParkableStringImpl::SecureDigest*,
+ WTF::HashMap<const ParkableStringImpl::SecureDigest*,
ParkableStringImpl*,
SecureDigestHash>
unparked_strings_;
- WTF::HashMap<ParkableStringImpl::SecureDigest*,
+ WTF::HashMap<const ParkableStringImpl::SecureDigest*,
ParkableStringImpl*,
SecureDigestHash>
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 a6b796743d6..a1e7a6a9e6c 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
@@ -611,6 +611,9 @@ TEST_F(ParkableStringTest, ReportMemoryDump) {
using testing::Contains;
using testing::Eq;
+ constexpr size_t kActualSize =
+ sizeof(ParkableStringImpl) + sizeof(ParkableStringImpl::ParkableMetadata);
+
auto& manager = ParkableStringManager::Instance();
ParkableString parkable1(MakeLargeString('a').ReleaseImpl());
ParkableString parkable2(MakeLargeString('b').ReleaseImpl());
@@ -647,29 +650,53 @@ TEST_F(ParkableStringTest, ReportMemoryDump) {
kCompressedSize);
EXPECT_THAT(dump->entries(), Contains(Eq(ByRef(overhead))));
- constexpr size_t kParkableStringImplActualSize =
- sizeof(ParkableStringImpl) + sizeof(ParkableStringImpl::SecureDigest);
MemoryAllocatorDump::Entry metadata("metadata_size", "bytes",
- 2 * kParkableStringImplActualSize);
+ 2 * kActualSize);
EXPECT_THAT(dump->entries(), Contains(Eq(ByRef(metadata))));
MemoryAllocatorDump::Entry savings(
"savings_size", "bytes",
- 2 * kStringSize - (kStringSize + 2 * kCompressedSize +
- 2 * kParkableStringImplActualSize));
+ 2 * kStringSize - (kStringSize + 2 * kCompressedSize + 2 * kActualSize));
EXPECT_THAT(dump->entries(), Contains(Eq(ByRef(savings))));
}
+TEST_F(ParkableStringTest, MemoryFootprintForDump) {
+ constexpr size_t kActualSize =
+ sizeof(ParkableStringImpl) + sizeof(ParkableStringImpl::ParkableMetadata);
+
+ size_t memory_footprint;
+ ParkableString parkable1(MakeLargeString('a').ReleaseImpl());
+ ParkableString parkable2(MakeLargeString('b').ReleaseImpl());
+ ParkableString parkable3(String("short string, not parkable").ReleaseImpl());
+
+ WaitForDelayedParking();
+ parkable1.ToString();
+
+ // Compressed and uncompressed data.
+ memory_footprint = kActualSize + parkable1.Impl()->compressed_size() +
+ parkable1.Impl()->CharactersSizeInBytes();
+ EXPECT_EQ(memory_footprint, parkable1.Impl()->MemoryFootprintForDump());
+
+ // Compressed uncompressed data only.
+ memory_footprint = kActualSize + parkable2.Impl()->compressed_size();
+ EXPECT_EQ(memory_footprint, parkable2.Impl()->MemoryFootprintForDump());
+
+ // Short string, no metadata.
+ memory_footprint =
+ sizeof(ParkableStringImpl) + parkable3.Impl()->CharactersSizeInBytes();
+ EXPECT_EQ(memory_footprint, parkable3.Impl()->MemoryFootprintForDump());
+}
+
TEST_F(ParkableStringTest, CompressionDisabled) {
base::test::ScopedFeatureList features;
features.InitAndDisableFeature(kCompressParkableStrings);
ParkableString parkable(MakeLargeString().ReleaseImpl());
WaitForDelayedParking();
- EXPECT_FALSE(parkable.Impl()->is_parked());
+ EXPECT_FALSE(parkable.Impl()->may_be_parked());
MemoryPressureListenerRegistry::Instance().OnPurgeMemory();
- EXPECT_FALSE(parkable.Impl()->is_parked());
+ EXPECT_FALSE(parkable.Impl()->may_be_parked());
}
TEST_F(ParkableStringTest, Aging) {
diff --git a/chromium/third_party/blink/renderer/platform/bindings/runtime_call_stats.h b/chromium/third_party/blink/renderer/platform/bindings/runtime_call_stats.h
index d898c3c5280..99a79bb2eb2 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/runtime_call_stats.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/runtime_call_stats.h
@@ -23,6 +23,10 @@
#include "third_party/blink/renderer/platform/wtf/vector.h"
#endif
+#if BUILDFLAG(BLINK_BINDINGS_TRACE_ENABLED)
+#include "base/trace_event/trace_event.h"
+#endif
+
namespace base {
class TickClock;
}
@@ -167,6 +171,15 @@ class PLATFORM_EXPORT RuntimeCallTimer {
} while (false)
#endif
+#if BUILDFLAG(BLINK_BINDINGS_TRACE_ENABLED)
+#define BLINK_BINDINGS_TRACE_EVENT(trace_event_name) \
+ TRACE_EVENT0("blink.bindings", trace_event_name)
+#else
+#define BLINK_BINDINGS_TRACE_EVENT(trace_event_name) \
+ do { \
+ } while (false)
+#endif
+
// Maintains a stack of timers and provides functions to manage recording scopes
// by pausing and resuming timers in the chain when entering and leaving a
// scope.
@@ -236,6 +249,7 @@ class PLATFORM_EXPORT RuntimeCallStats {
#define CALLBACK_COUNTERS(V) \
BINDINGS_METHOD(V, ElementGetBoundingClientRect) \
+ BINDINGS_METHOD(V, ElementGetInnerHTML) \
BINDINGS_METHOD(V, EventTargetDispatchEvent) \
BINDINGS_METHOD(V, HTMLElementClick) \
BINDINGS_METHOD(V, NodeAppendChild) \
diff --git a/chromium/third_party/blink/renderer/platform/bindings/script_promise_properties.h b/chromium/third_party/blink/renderer/platform/bindings/script_promise_properties.h
deleted file mode 100644
index e6224751292..00000000000
--- a/chromium/third_party/blink/renderer/platform/bindings/script_promise_properties.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2014 The Chromium 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_BINDINGS_SCRIPT_PROMISE_PROPERTIES_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_SCRIPT_PROMISE_PROPERTIES_H_
-
-// See ScriptPromiseProperty.h
-#define SCRIPT_PROMISE_PROPERTIES(P, ...) \
- P(ScriptPromise, kReady##__VA_ARGS__) \
- P(ScriptPromise, kClosed##__VA_ARGS__) \
- P(ScriptPromise, kFinished##__VA_ARGS__) \
- P(ScriptPromise, kLoaded##__VA_ARGS__) \
- P(ScriptPromise, kLost##__VA_ARGS__) \
- P(ScriptPromise, kReleased##__VA_ARGS__) \
- P(ScriptPromise, kResponseReady##__VA_ARGS__) \
- P(ScriptPromise, kUserChoice##__VA_ARGS__) \
- P(ScriptPromise, kPreloadResponse##__VA_ARGS__)
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_SCRIPT_PROMISE_PROPERTIES_H_
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 f4ba8ef7edc..22baa5189bb 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/script_state.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/script_state.h
@@ -75,7 +75,7 @@ class V8PerContextData;
// all V8 proxy objects that have references to the ScriptState are destructed.
class PLATFORM_EXPORT ScriptState final : public GarbageCollected<ScriptState> {
public:
- class Scope {
+ class Scope final {
STACK_ALLOCATED();
public:
@@ -95,10 +95,36 @@ class PLATFORM_EXPORT ScriptState final : public GarbageCollected<ScriptState> {
v8::Local<v8::Context> context_;
};
+ // Use EscapableScope if you have to return a v8::Local to an outer scope.
+ // See v8::EscapableHandleScope.
+ class EscapableScope final {
+ STACK_ALLOCATED();
+
+ public:
+ // You need to make sure that scriptState->context() is not empty before
+ // creating a Scope.
+ explicit EscapableScope(ScriptState* script_state)
+ : handle_scope_(script_state->GetIsolate()),
+ context_(script_state->GetContext()) {
+ DCHECK(script_state->ContextIsValid());
+ context_->Enter();
+ }
+
+ ~EscapableScope() { context_->Exit(); }
+
+ v8::Local<v8::Value> Escape(v8::Local<v8::Value> value) {
+ return handle_scope_.Escape(value);
+ }
+
+ private:
+ v8::EscapableHandleScope handle_scope_;
+ v8::Local<v8::Context> context_;
+ };
+
ScriptState(v8::Local<v8::Context>, scoped_refptr<DOMWrapperWorld>);
~ScriptState();
- void Trace(blink::Visitor*) {}
+ void Trace(Visitor*) {}
static ScriptState* Current(v8::Isolate* isolate) { // DEPRECATED
return From(isolate->GetCurrentContext());
@@ -193,9 +219,9 @@ class PLATFORM_EXPORT ScriptState final : public GarbageCollected<ScriptState> {
// exactly.
SelfKeepAlive<ScriptState> reference_from_v8_context_;
- static constexpr int kV8ContextPerContextDataIndex = static_cast<int>(
- gin::kPerContextDataStartIndex + // NOLINT(readability/enum_casing)
- gin::kEmbedderBlink); // NOLINT(readability/enum_casing)
+ static constexpr int kV8ContextPerContextDataIndex =
+ static_cast<int>(gin::kPerContextDataStartIndex) +
+ static_cast<int>(gin::kEmbedderBlink);
DISALLOW_COPY_AND_ASSIGN(ScriptState);
};
@@ -215,7 +241,7 @@ class ScriptStateProtectingContext final
}
}
- void Trace(blink::Visitor* visitor) { visitor->Trace(script_state_); }
+ void Trace(Visitor* visitor) { 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 3f344d0ccf0..aaea2cdebb7 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable.cc
@@ -17,7 +17,7 @@ struct SameSizeAsScriptWrappable {
static_assert(sizeof(ScriptWrappable) <= sizeof(SameSizeAsScriptWrappable),
"ScriptWrappable should stay small");
-v8::Local<v8::Object> ScriptWrappable::Wrap(
+v8::Local<v8::Value> ScriptWrappable::Wrap(
v8::Isolate* isolate,
v8::Local<v8::Object> creation_context) {
const WrapperTypeInfo* wrapper_type_info = this->GetWrapperTypeInfo();
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 25475561588..2a0f41e3f32 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable.h
@@ -48,7 +48,7 @@ namespace blink {
// a v8::Object and toScriptWrappable() converts a v8::Object back to
// a ScriptWrappable. v8::Object as platform object is called "wrapper object".
// The wrapper object for the main world is stored in ScriptWrappable. Wrapper
-// objects for other worlds are stored in DOMWrapperMap.
+// objects for other worlds are stored in DOMDataStore.
class PLATFORM_EXPORT ScriptWrappable
: public GarbageCollected<ScriptWrappable>,
public NameClient {
@@ -68,7 +68,7 @@ class PLATFORM_EXPORT ScriptWrappable
const char* NameInHeapSnapshot() const override;
- virtual void Trace(blink::Visitor*);
+ virtual void Trace(Visitor*);
template <typename T>
T* ToImpl() {
@@ -78,16 +78,14 @@ class PLATFORM_EXPORT ScriptWrappable
sizeof(T) && WTF::IsGarbageCollectedType<T>::value,
"Classes implementing ScriptWrappable must be garbage collected.");
-// Check if T* is castable to ScriptWrappable*, which means T doesn't
-// have two or more ScriptWrappable as superclasses. If T has two
-// ScriptWrappable as superclasses, conversions from T* to
-// ScriptWrappable* are ambiguous.
-#if !defined(COMPILER_MSVC)
- // MSVC 2013 doesn't support static_assert + constexpr well.
+ // Check if T* is castable to ScriptWrappable*, which means T doesn't
+ // have two or more ScriptWrappable as superclasses. If T has two
+ // ScriptWrappable as superclasses, conversions from T* to
+ // ScriptWrappable* are ambiguous.
static_assert(!static_cast<ScriptWrappable*>(static_cast<T*>(nullptr)),
"Class T must not have two or more ScriptWrappable as its "
"superclasses.");
-#endif
+
return static_cast<T*>(this);
}
@@ -97,8 +95,8 @@ class PLATFORM_EXPORT ScriptWrappable
virtual const WrapperTypeInfo* GetWrapperTypeInfo() const = 0;
// Creates and returns a new wrapper object.
- virtual v8::Local<v8::Object> Wrap(v8::Isolate*,
- v8::Local<v8::Object> creation_context);
+ virtual v8::Local<v8::Value> Wrap(v8::Isolate*,
+ v8::Local<v8::Object> creation_context);
// Associates the instance with the given |wrapper| if this instance is not
// yet associated with any wrapper. Returns the wrapper already associated
@@ -190,6 +188,9 @@ inline bool ScriptWrappable::UnsetMainWorldWrapperIfSet(
const WrapperTypeInfo* GetWrapperTypeInfo() const override { \
return &wrapper_type_info_; \
} \
+ static const WrapperTypeInfo* GetStaticWrapperTypeInfo() { \
+ return &wrapper_type_info_; \
+ } \
\
private: \
static const WrapperTypeInfo& wrapper_type_info_
diff --git a/chromium/third_party/blink/renderer/platform/bindings/shared_persistent.h b/chromium/third_party/blink/renderer/platform/bindings/shared_persistent.h
deleted file mode 100644
index 03a87e9e10c..00000000000
--- a/chromium/third_party/blink/renderer/platform/bindings/shared_persistent.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2009 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.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_SHARED_PERSISTENT_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_SHARED_PERSISTENT_H_
-
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
-#include "third_party/blink/renderer/platform/bindings/scoped_persistent.h"
-#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
-#include "v8/include/v8.h"
-
-namespace blink {
-
-// A ref counted version of ScopedPersistent. This class is intended for use by
-// ScriptValue and not for normal use. Consider using ScopedPersistent directly
-// instead.
-// TODO(crbug.com/1029738): Remove once bug is fixed.
-template <typename T>
-class SharedPersistent : public RefCounted<SharedPersistent<T>> {
- USING_FAST_MALLOC(SharedPersistent);
-
- public:
- static scoped_refptr<SharedPersistent<T>> Create(v8::Isolate* isolate,
- v8::Local<T> value) {
- return base::AdoptRef(new SharedPersistent<T>(isolate, value));
- }
-
- // Returns the V8 reference. Crashes if |world_| is set and it is
- // different from |target_script_state|'s world.
- v8::Local<T> Get(ScriptState* target_script_state) const {
- DCHECK(!value_.IsEmpty());
- if (world_) {
- CHECK_EQ(world_.get(), &target_script_state->World());
- }
- return value_.NewLocal(target_script_state->GetIsolate());
- }
-
- // Returns a V8 reference that is safe to access in |target_script_state|.
- // The return value may be a cloned object.
- v8::Local<T> GetAcrossWorld(ScriptState* target_script_state) const {
- CHECK(world_);
- DCHECK(!value_.IsEmpty());
-
- v8::Isolate* isolate = target_script_state->GetIsolate();
-
- if (world_ == &target_script_state->World())
- return value_.NewLocal(isolate);
-
- // If |v8_reference| is a v8::Object, clones |v8_reference| in the context
- // of |target_script_state| and returns it. Otherwise returns
- // |v8_reference| itself that is already safe to access in
- // |target_script_state|.
-
- v8::Local<v8::Value> value = value_.NewLocal(isolate);
- DCHECK(value->IsObject());
- return value.template As<T>();
- }
-
- bool IsEmpty() { return value_.IsEmpty(); }
-
- bool operator==(const SharedPersistent<T>& other) {
- return value_ == other.value_;
- }
-
- private:
- explicit SharedPersistent(v8::Isolate* isolate, v8::Local<T> value)
- : value_(isolate, value) {
- DCHECK(!value.IsEmpty());
- // Basically, |world_| is a world when this V8 reference is created.
- // However, when this V8 reference isn't created in context and value is
- // object, we set |world_| to a value's creation cotext's world.
- if (isolate->InContext()) {
- world_ = &DOMWrapperWorld::Current(isolate);
- if (value->IsObject()) {
- v8::Local<v8::Context> context =
- value.template As<v8::Object>()->CreationContext();
- // Creation context is null if the value is a remote object.
- if (!context.IsEmpty()) {
- ScriptState* script_state = ScriptState::From(context);
- CHECK_EQ(world_.get(), &script_state->World());
- }
- }
- } else if (value->IsObject()) {
- ScriptState* script_state =
- ScriptState::From(value.template As<v8::Object>()->CreationContext());
- world_ = &script_state->World();
- }
- }
-
- ScopedPersistent<T> value_;
- // The world of the current context at the time when |value_| was set.
- // It's guaranteed that, if |value_| is a v8::Object, the world of the
- // creation context of |value_| is the same as |world_|.
- scoped_refptr<const DOMWrapperWorld> world_;
-
- DISALLOW_COPY_AND_ASSIGN(SharedPersistent);
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_SHARED_PERSISTENT_H_
diff --git a/chromium/third_party/blink/renderer/platform/bindings/to_v8.h b/chromium/third_party/blink/renderer/platform/bindings/to_v8.h
index 246140e5dcd..50ae965e76e 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/to_v8.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/to_v8.h
@@ -19,6 +19,7 @@
#include "third_party/blink/renderer/platform/bindings/dom_data_store.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/bindings/union_base.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
@@ -85,6 +86,17 @@ inline v8::Local<v8::Value> ToV8(CallbackInterfaceBase* callback,
: v8::Null(isolate).As<v8::Value>();
}
+// Union type
+
+inline v8::Local<v8::Value> ToV8(const bindings::UnionBase& value,
+ v8::Local<v8::Object> creation_context,
+ v8::Isolate* isolate) {
+ v8::Local<v8::Value> v8_value =
+ value.CreateV8Object(isolate, creation_context);
+ DCHECK(!v8_value.IsEmpty());
+ return v8_value;
+}
+
// Primitives
inline v8::Local<v8::Value> ToV8(const String& value,
@@ -208,27 +220,27 @@ inline v8::Local<v8::Value> ToV8(const base::Optional<InnerType>& value,
// Declare the function here but define it later so it can call the ToV8()
// overloads below.
template <typename Sequence>
-inline v8::Local<v8::Value> ToV8SequenceInternal(
+inline v8::Local<v8::Array> ToV8SequenceInternal(
const Sequence&,
v8::Local<v8::Object> creation_context,
v8::Isolate*);
template <typename T, size_t Extent>
-inline v8::Local<v8::Value> ToV8(base::span<T, Extent> value,
+inline v8::Local<v8::Array> ToV8(base::span<T, Extent> value,
v8::Local<v8::Object> creation_context,
v8::Isolate* isolate) {
return ToV8SequenceInternal(value, creation_context, isolate);
}
template <typename T, wtf_size_t inlineCapacity>
-inline v8::Local<v8::Value> ToV8(const Vector<T, inlineCapacity>& value,
+inline v8::Local<v8::Array> ToV8(const Vector<T, inlineCapacity>& value,
v8::Local<v8::Object> creation_context,
v8::Isolate* isolate) {
return ToV8SequenceInternal(value, creation_context, isolate);
}
template <typename T, wtf_size_t inlineCapacity>
-inline v8::Local<v8::Value> ToV8(const HeapVector<T, inlineCapacity>& value,
+inline v8::Local<v8::Array> ToV8(const HeapVector<T, inlineCapacity>& value,
v8::Local<v8::Object> creation_context,
v8::Isolate* isolate) {
return ToV8SequenceInternal(value, creation_context, isolate);
@@ -289,7 +301,7 @@ inline v8::Local<v8::Value> ToV8(const HeapVector<std::pair<String, T>>& value,
}
template <typename Sequence>
-inline v8::Local<v8::Value> ToV8SequenceInternal(
+inline v8::Local<v8::Array> ToV8SequenceInternal(
const Sequence& sequence,
v8::Local<v8::Object> creation_context,
v8::Isolate* isolate) {
@@ -312,7 +324,7 @@ inline v8::Local<v8::Value> ToV8SequenceInternal(
if (!array->CreateDataProperty(context, index++, value)
.To(&created_property) ||
!created_property) {
- return v8::Local<v8::Value>();
+ return v8::Local<v8::Array>();
}
}
return array;
diff --git a/chromium/third_party/blink/renderer/platform/bindings/union_base.h b/chromium/third_party/blink/renderer/platform/bindings/union_base.h
new file mode 100644
index 00000000000..35ce7f8151b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/bindings/union_base.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_UNION_BASE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_UNION_BASE_H_
+
+#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+class Visitor;
+
+namespace bindings {
+
+// This class is the base class for all IDL dictionary implementations. This
+// is designed to collaborate with NativeValueTraits and ToV8 with supporting
+// type dispatching (SFINAE, etc.).
+class PLATFORM_EXPORT UnionBase {
+ DISALLOW_NEW();
+
+ public:
+ virtual ~UnionBase() = default;
+
+ virtual v8::Local<v8::Value> CreateV8Object(
+ v8::Isolate* isolate,
+ v8::Local<v8::Object> creation_context) const = 0;
+
+ void Trace(Visitor*) {}
+
+ protected:
+ UnionBase() = default;
+ UnionBase(const UnionBase&) = default;
+ UnionBase(UnionBase&&) = default;
+ UnionBase& operator=(const UnionBase&) = default;
+ UnionBase& operator=(UnionBase&&) = default;
+};
+
+} // namespace bindings
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_UNION_BASE_H_
diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_binding.h b/chromium/third_party/blink/renderer/platform/bindings/v8_binding.h
index ba7445d3342..ed84d117363 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/v8_binding.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/v8_binding.h
@@ -46,6 +46,10 @@
namespace blink {
+namespace bindings {
+class DictionaryBase;
+}
+
// This file contains bindings helper functions that do not have dependencies
// to core/ or bindings/core. For core-specific helper functions, see
// bindings/core/v8/V8BindingForCore.h.
@@ -99,6 +103,11 @@ inline void V8SetReturnValue(const CallbackInfo& info, uint32_t value) {
}
template <typename CallbackInfo>
+inline void V8SetReturnValue(const CallbackInfo& info, uint64_t value) {
+ info.GetReturnValue().Set(static_cast<double>(value));
+}
+
+template <typename CallbackInfo>
inline void V8SetReturnValueBool(const CallbackInfo& info, bool v) {
info.GetReturnValue().Set(v);
}
@@ -162,7 +171,7 @@ inline void V8SetReturnValue(const CallbackInfo& callback_info,
}
if (DOMDataStore::SetReturnValue(callback_info.GetReturnValue(), impl))
return;
- v8::Local<v8::Object> wrapper =
+ v8::Local<v8::Value> wrapper =
impl->Wrap(callback_info.GetIsolate(), creation_context);
V8SetReturnValue(callback_info, wrapper);
}
@@ -184,7 +193,7 @@ inline void V8SetReturnValueForMainWorld(const CallbackInfo& callback_info,
if (DOMDataStore::SetReturnValueForMainWorld(callback_info.GetReturnValue(),
impl))
return;
- v8::Local<v8::Object> wrapper =
+ v8::Local<v8::Value> wrapper =
impl->Wrap(callback_info.GetIsolate(), callback_info.Holder());
V8SetReturnValue(callback_info, wrapper);
}
@@ -200,7 +209,7 @@ inline void V8SetReturnValueFast(const CallbackInfo& callback_info,
if (DOMDataStore::SetReturnValueFast(callback_info.GetReturnValue(), impl,
callback_info.Holder(), wrappable))
return;
- v8::Local<v8::Object> wrapper =
+ v8::Local<v8::Value> wrapper =
impl->Wrap(callback_info.GetIsolate(), callback_info.Holder());
V8SetReturnValue(callback_info, wrapper);
}
@@ -212,6 +221,20 @@ inline void V8SetReturnValueFast(const CallbackInfo& callback_info,
V8SetReturnValue(callback_info, handle);
}
+// Dictionary
+template <class CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info,
+ bindings::DictionaryBase* value,
+ v8::Local<v8::Object> creation_context) {
+ V8SetReturnValue(info, ToV8(value, creation_context, info.GetIsolate()));
+}
+
+template <class CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info,
+ bindings::DictionaryBase* value) {
+ V8SetReturnValue(info, ToV8(value, info.Holder(), info.GetIsolate()));
+}
+
// Convert v8::String to a WTF::String. If the V8 string is not already
// an external string then it is transformed into an external string at this
// point to avoid repeated conversions.
@@ -359,6 +382,24 @@ static void IndexedPropertyEnumerator(
PLATFORM_EXPORT v8::Local<v8::Value> FreezeV8Object(v8::Local<v8::Value>,
v8::Isolate*);
+// Return values of indexed properties and named properties
+
+enum class IndexedPropertySetterResult {
+ kDidNotIntercept, // Fallback to the default set operation.
+ kIntercepted, // Intercepted regardless of whether it succeeded or not.
+};
+
+enum class NamedPropertySetterResult {
+ kDidNotIntercept, // Fallback to the default set operation.
+ kIntercepted, // Intercepted regardless of whether it succeeded or not.
+};
+
+enum class NamedPropertyDeleterResult {
+ kDidNotIntercept, // Fallback to the default delete operation.
+ kDeleted, // Successfully deleted.
+ kDidNotDelete, // Intercepted but failed to delete.
+};
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_V8_BINDING_H_
diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_binding_macros.h b/chromium/third_party/blink/renderer/platform/bindings/v8_binding_macros.h
index 2ec174ff7aa..1c5a0f9dacf 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/v8_binding_macros.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/v8_binding_macros.h
@@ -59,16 +59,6 @@ namespace blink {
if (UNLIKELY(!var.Prepare())) \
return retVal;
-// Checks for a given v8::Value (value) whether it is an ArrayBufferView and
-// below a certain size limit. If below the limit, memory is allocated on the
-// stack to hold the actual payload. Keep the limit in sync with V8's
-// typed_array_max_size.
-#define allocateFlexibleArrayBufferViewStorage(value) \
- (value->IsArrayBufferView() && \
- (value.As<v8::ArrayBufferView>()->ByteLength() <= 64) \
- ? alloca(value.As<v8::ArrayBufferView>()->ByteLength()) \
- : nullptr)
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_V8_BINDING_MACROS_H_
diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_cross_origin_property_support.cc b/chromium/third_party/blink/renderer/platform/bindings/v8_cross_origin_property_support.cc
new file mode 100644
index 00000000000..a434695b8e2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/bindings/v8_cross_origin_property_support.cc
@@ -0,0 +1,96 @@
+// 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/bindings/v8_cross_origin_property_support.h"
+
+#include "third_party/blink/renderer/platform/bindings/script_state.h"
+#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
+#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
+
+namespace blink {
+
+namespace bindings {
+
+v8::MaybeLocal<v8::Function> GetCrossOriginFunction(
+ v8::Isolate* isolate,
+ v8::FunctionCallback callback,
+ int func_length,
+ const WrapperTypeInfo* wrapper_type_info) {
+ v8::Local<v8::Context> current_context = isolate->GetCurrentContext();
+ ScriptState* script_state = ScriptState::From(current_context);
+ V8PerIsolateData* per_isolate_data = V8PerIsolateData::From(isolate);
+ const void* callback_key = reinterpret_cast<const void*>(callback);
+
+ // ES functions accessible across origins are not interface objects, but we
+ // reuse the cache of interface objects, which just works because both are
+ // V8 function template.
+ v8::Local<v8::FunctionTemplate> function_template =
+ per_isolate_data->FindInterfaceTemplate(script_state->World(),
+ callback_key);
+ if (function_template.IsEmpty()) {
+ v8::Local<v8::FunctionTemplate> interface_template =
+ per_isolate_data->FindInterfaceTemplate(script_state->World(),
+ wrapper_type_info);
+ v8::Local<v8::Signature> signature =
+ v8::Signature::New(isolate, interface_template);
+ function_template = v8::FunctionTemplate::New(
+ isolate, callback, v8::Local<v8::Value>(), signature, func_length,
+ v8::ConstructorBehavior::kThrow, v8::SideEffectType::kHasSideEffect);
+ per_isolate_data->SetInterfaceTemplate(script_state->World(), callback_key,
+ function_template);
+ }
+ return function_template->GetFunction(current_context);
+}
+
+v8::MaybeLocal<v8::Value> GetCrossOriginFunctionOrUndefined(
+ v8::Isolate* isolate,
+ v8::FunctionCallback callback,
+ int func_length,
+ const WrapperTypeInfo* wrapper_type_info) {
+ if (!callback) {
+ return v8::Undefined(isolate);
+ }
+ v8::Local<v8::Function> function;
+ if (GetCrossOriginFunction(isolate, callback, func_length, wrapper_type_info)
+ .ToLocal(&function)) {
+ return function;
+ }
+ return v8::MaybeLocal<v8::Value>();
+}
+
+bool IsSupportedInCrossOriginPropertyFallback(
+ v8::Isolate* isolate,
+ v8::Local<v8::Name> property_name) {
+ return (property_name == V8AtomicString(isolate, "then") ||
+ property_name == v8::Symbol::GetToStringTag(isolate) ||
+ property_name == v8::Symbol::GetHasInstance(isolate) ||
+ property_name == v8::Symbol::GetIsConcatSpreadable(isolate));
+}
+
+v8::Local<v8::Array> EnumerateCrossOriginProperties(
+ v8::Isolate* isolate,
+ base::span<const CrossOriginAttributeTableEntry> attributes,
+ base::span<const CrossOriginOperationTableEntry> operations) {
+ v8::Local<v8::Value> default_supported[] = {
+ V8AtomicString(isolate, "then"),
+ v8::Symbol::GetToStringTag(isolate),
+ v8::Symbol::GetHasInstance(isolate),
+ v8::Symbol::GetIsConcatSpreadable(isolate),
+ };
+ const uint32_t length =
+ attributes.size() + operations.size() + base::size(default_supported);
+ Vector<v8::Local<v8::Value>> elements;
+ elements.ReserveCapacity(length);
+ for (const auto& attribute : attributes)
+ elements.UncheckedAppend(V8AtomicString(isolate, attribute.name));
+ for (const auto& operation : operations)
+ elements.UncheckedAppend(V8AtomicString(isolate, operation.name));
+ for (const auto& name : default_supported)
+ elements.UncheckedAppend(name);
+ return v8::Array::New(isolate, elements.data(), elements.size());
+}
+
+} // namespace bindings
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_cross_origin_property_support.h b/chromium/third_party/blink/renderer/platform/bindings/v8_cross_origin_property_support.h
new file mode 100644
index 00000000000..d441696a42a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/bindings/v8_cross_origin_property_support.h
@@ -0,0 +1,65 @@
+// 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_BINDINGS_V8_CROSS_ORIGIN_PROPERTY_SUPPORT_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_V8_CROSS_ORIGIN_PROPERTY_SUPPORT_H_
+
+#include "base/containers/span.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "v8/include/v8.h"
+
+// This file provides utilities to support implementation of cross origin
+// properties in generated bindings code. Should be used only in generated
+// bindings code.
+
+namespace blink {
+
+struct WrapperTypeInfo;
+
+namespace bindings {
+
+struct CrossOriginAttributeTableEntry final {
+ const char* name;
+ v8::FunctionCallback get_callback;
+ v8::FunctionCallback set_callback;
+ v8::GenericNamedPropertyGetterCallback get_value;
+ v8::GenericNamedPropertySetterCallback set_value;
+};
+
+struct CrossOriginOperationTableEntry final {
+ const char* name;
+ v8::FunctionCallback callback;
+ int func_length;
+};
+
+PLATFORM_EXPORT v8::MaybeLocal<v8::Function> GetCrossOriginFunction(
+ v8::Isolate* isolate,
+ v8::FunctionCallback callback,
+ int func_length,
+ const WrapperTypeInfo* wrapper_type_info);
+
+PLATFORM_EXPORT v8::MaybeLocal<v8::Value> GetCrossOriginFunctionOrUndefined(
+ v8::Isolate* isolate,
+ v8::FunctionCallback callback,
+ int func_length,
+ const WrapperTypeInfo* wrapper_type_info);
+
+// HTML 7.2.3.2 CrossOriginPropertyFallback ( P )
+// https://html.spec.whatwg.org/C/#crossoriginpropertyfallback-(-p-)
+PLATFORM_EXPORT bool IsSupportedInCrossOriginPropertyFallback(
+ v8::Isolate* isolate,
+ v8::Local<v8::Name> property_name);
+
+// HTML 7.2.3.7 CrossOriginOwnPropertyKeys ( O )
+// https://html.spec.whatwg.org/C/#crossoriginownpropertykeys-(-o-)
+PLATFORM_EXPORT v8::Local<v8::Array> EnumerateCrossOriginProperties(
+ v8::Isolate* isolate,
+ base::span<const CrossOriginAttributeTableEntry> attributes,
+ base::span<const CrossOriginOperationTableEntry> operations);
+
+} // namespace bindings
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_V8_CROSS_ORIGIN_PROPERTY_SUPPORT_H_
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
new file mode 100644
index 00000000000..402b97cc68a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/bindings/v8_interface_bridge.h
@@ -0,0 +1,99 @@
+// 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_BINDINGS_V8_INTERFACE_BRIDGE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_V8_INTERFACE_BRIDGE_H_
+
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
+#include "third_party/blink/renderer/platform/bindings/wrapper_type_info.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+class DOMWrapperWorld;
+
+namespace bindings {
+
+// The common base class of code-generated V8-Blink bridge class of IDL
+// interfaces and namespaces.
+class PLATFORM_EXPORT V8InterfaceBridgeBase {
+ STATIC_ONLY(V8InterfaceBridgeBase);
+
+ protected:
+ using InstallInterfaceTemplateFuncType =
+ void (*)(v8::Isolate* isolate,
+ const DOMWrapperWorld& world,
+ v8::Local<v8::FunctionTemplate> interface_template);
+ using InstallUnconditionalPropertiesFuncType =
+ void (*)(v8::Isolate* isolate,
+ const DOMWrapperWorld& world,
+ v8::Local<v8::ObjectTemplate> instance_template,
+ v8::Local<v8::ObjectTemplate> prototype_template,
+ v8::Local<v8::FunctionTemplate> interface_template);
+ using InstallContextIndependentPropertiesFuncType =
+ void (*)(v8::Isolate* isolate,
+ const DOMWrapperWorld& world,
+ v8::Local<v8::ObjectTemplate> instance_template,
+ v8::Local<v8::ObjectTemplate> prototype_template,
+ v8::Local<v8::FunctionTemplate> interface_template);
+ using InstallContextDependentPropertiesFuncType =
+ void (*)(v8::Local<v8::Context> context,
+ const DOMWrapperWorld& world,
+ v8::Local<v8::Object> instance_object,
+ v8::Local<v8::Object> prototype_object,
+ v8::Local<v8::Function> interface_object);
+};
+
+template <class V8T, class T>
+class V8InterfaceBridge : public V8InterfaceBridgeBase {
+ public:
+ static T* ToWrappable(v8::Isolate* isolate, v8::Local<v8::Value> value) {
+ return HasInstance(isolate, value)
+ ? ToWrappableUnsafe(value.As<v8::Object>())
+ : nullptr;
+ }
+
+ static T* ToWrappableUnsafe(v8::Local<v8::Object> value) {
+ return ToScriptWrappable(value)->ToImpl<T>();
+ }
+
+ static bool HasInstance(v8::Isolate* isolate, v8::Local<v8::Value> value) {
+ return V8PerIsolateData::From(isolate)->HasInstance(
+ V8T::GetWrapperTypeInfo(), value);
+ }
+
+ // Migration adapter
+ static bool HasInstance(v8::Local<v8::Value> value, v8::Isolate* isolate) {
+ return HasInstance(isolate, value);
+ }
+
+ static T* ToImpl(v8::Local<v8::Object> value) {
+ return ToWrappableUnsafe(value);
+ }
+
+ static T* ToImplWithTypeCheck(v8::Isolate* isolate,
+ v8::Local<v8::Value> value) {
+ return ToWrappable(isolate, value);
+ }
+
+ static void InstallContextDependentAdapter(
+ v8::Local<v8::Context> context,
+ const DOMWrapperWorld& 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) {
+ V8T::InstallContextDependentProperties(context, world, instance_object,
+ prototype_object, interface_object);
+ }
+};
+
+} // namespace bindings
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_V8_INTERFACE_BRIDGE_H_
diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.cc b/chromium/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.cc
index 6c25c30dcb3..032aca70e3f 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.cc
@@ -172,8 +172,9 @@ void V8PerIsolateData::WillBeDestroyed(v8::Isolate* isolate) {
// callbacks are missing and state gets out of sync.
ThreadState* const thread_state = ThreadState::Current();
thread_state->FinishIncrementalMarkingIfRunning(
- BlinkGC::kHeapPointersOnStack, BlinkGC::kAtomicMarking,
- BlinkGC::kEagerSweeping, BlinkGC::GCReason::kThreadTerminationGC);
+ BlinkGC::CollectionType::kMajor, BlinkGC::kHeapPointersOnStack,
+ BlinkGC::kAtomicMarking, BlinkGC::kEagerSweeping,
+ BlinkGC::GCReason::kThreadTerminationGC);
thread_state->DetachFromIsolate();
}
@@ -267,26 +268,28 @@ void V8PerIsolateData::ClearPersistentsForV8ContextSnapshot() {
private_property_.reset();
}
-const v8::Eternal<v8::Name>* V8PerIsolateData::FindOrCreateEternalNameCache(
+const base::span<const v8::Eternal<v8::Name>>
+V8PerIsolateData::FindOrCreateEternalNameCache(
const void* lookup_key,
- const char* const names[],
- size_t count) {
+ const base::span<const char* const>& names) {
auto it = eternal_name_cache_.find(lookup_key);
const Vector<v8::Eternal<v8::Name>>* vector = nullptr;
if (UNLIKELY(it == eternal_name_cache_.end())) {
v8::Isolate* isolate = this->GetIsolate();
- Vector<v8::Eternal<v8::Name>> new_vector(count);
- std::transform(
- names, names + count, new_vector.begin(), [isolate](const char* name) {
- return v8::Eternal<v8::Name>(isolate, V8AtomicString(isolate, name));
- });
+ Vector<v8::Eternal<v8::Name>> new_vector(names.size());
+ std::transform(names.begin(), names.end(), new_vector.begin(),
+ [isolate](const char* name) {
+ return v8::Eternal<v8::Name>(
+ isolate, V8AtomicString(isolate, name));
+ });
vector = &eternal_name_cache_.Set(lookup_key, std::move(new_vector))
.stored_value->value;
} else {
vector = &it->value;
}
- DCHECK_EQ(vector->size(), count);
- return vector->data();
+ DCHECK_EQ(vector->size(), names.size());
+ return base::span<const v8::Eternal<v8::Name>>(vector->data(),
+ vector->size());
}
v8::Local<v8::Context> V8PerIsolateData::EnsureScriptRegexpContext() {
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 6b5c64a59f3..f64cd5c5029 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
@@ -28,6 +28,7 @@
#include <memory>
+#include "base/containers/span.h"
#include "base/macros.h"
#include "gin/public/gin_embedders.h"
#include "gin/public/isolate_holder.h"
@@ -106,7 +107,7 @@ class PLATFORM_EXPORT V8PerIsolateData {
public:
virtual ~GarbageCollectedData() = default;
virtual void WillBeDestroyed() {}
- virtual void Trace(blink::Visitor*) {}
+ virtual void Trace(Visitor*) {}
};
static v8::Isolate* Initialize(scoped_refptr<base::SingleThreadTaskRunner>,
@@ -182,10 +183,9 @@ class PLATFORM_EXPORT V8PerIsolateData {
// yet exist, it is created from the given array of strings. Once created,
// these live for as long as the isolate, so this is appropriate only for a
// compile-time list of related names, such as IDL dictionary keys.
- const v8::Eternal<v8::Name>* FindOrCreateEternalNameCache(
+ const base::span<const v8::Eternal<v8::Name>> FindOrCreateEternalNameCache(
const void* lookup_key,
- const char* const names[],
- size_t count);
+ const base::span<const char* const>& names);
bool HasInstance(const WrapperTypeInfo* untrusted, v8::Local<v8::Value>);
v8::Local<v8::Object> FindInstanceInPrototypeChain(const WrapperTypeInfo*,
diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_private_property.h b/chromium/third_party/blink/renderer/platform/bindings/v8_private_property.h
index 864454f18c2..bf19f476ecc 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/v8_private_property.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/v8_private_property.h
@@ -8,7 +8,6 @@
#include <memory>
#include "base/memory/ptr_util.h"
-#include "third_party/blink/renderer/platform/bindings/script_promise_properties.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding_macros.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
#include "third_party/blink/renderer/platform/platform_export.h"
diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_set_return_value.cc b/chromium/third_party/blink/renderer/platform/bindings/v8_set_return_value.cc
new file mode 100644
index 00000000000..a80ede46d7d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/bindings/v8_set_return_value.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/platform/bindings/v8_set_return_value.h"
+
+#include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
+#include "third_party/blink/renderer/platform/bindings/v8_per_context_data.h"
+
+namespace blink {
+
+namespace bindings {
+
+v8::Local<v8::Object> CreatePropertyDescriptorObject(
+ v8::Isolate* isolate,
+ const v8::PropertyDescriptor& desc) {
+ // https://tc39.es/ecma262/#sec-frompropertydescriptor
+ v8::Local<v8::Context> current_context = isolate->GetCurrentContext();
+ v8::Local<v8::Object> object = v8::Object::New(isolate);
+
+ auto add_property = [&](const char* name, v8::Local<v8::Value> value) {
+ return object->CreateDataProperty(current_context, V8String(isolate, name),
+ value);
+ };
+ auto add_property_bool = [&](const char* name, bool value) {
+ return add_property(name, value ? v8::True(isolate) : v8::False(isolate));
+ };
+
+ bool result;
+ if (desc.has_value()) {
+ if (!(add_property("value", desc.value()).To(&result) &&
+ add_property_bool("writable", desc.writable()).To(&result)))
+ return v8::Local<v8::Object>();
+ } else {
+ if (!(add_property("get", desc.get()).To(&result) &&
+ add_property("set", desc.set()).To(&result)))
+ return v8::Local<v8::Object>();
+ }
+ if (!(add_property_bool("enumerable", desc.enumerable()).To(&result) &&
+ add_property_bool("configurable", desc.configurable()).To(&result)))
+ return v8::Local<v8::Object>();
+
+ return object;
+}
+
+v8::Local<v8::Value> GetInterfaceObjectExposedOnGlobal(
+ v8::Isolate* isolate,
+ v8::Local<v8::Object> creation_context,
+ const WrapperTypeInfo* wrapper_type_info) {
+ RUNTIME_CALL_TIMER_SCOPE_DISABLED_BY_DEFAULT(
+ isolate, "Blink_GetInterfaceObjectExposedOnGlobal");
+ V8PerContextData* per_context_data =
+ V8PerContextData::From(creation_context->CreationContext());
+ if (!per_context_data)
+ return v8::Local<v8::Value>();
+ return per_context_data->ConstructorForType(wrapper_type_info);
+}
+
+} // namespace bindings
+
+} // namespace blink
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
new file mode 100644
index 00000000000..6c7ffa11316
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/bindings/v8_set_return_value.h
@@ -0,0 +1,336 @@
+// 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_BINDINGS_V8_SET_RETURN_VALUE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_V8_SET_RETURN_VALUE_H_
+
+#include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/renderer/platform/bindings/dom_data_store.h"
+#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
+#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
+#include "third_party/blink/renderer/platform/bindings/v8_value_cache.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+namespace bindings {
+
+// V8SetReturnValue sets a return value in a V8 callback function. The first
+// two arguments are fixed as v8::{Function,Property}CallbackInfo and the
+// return value. V8SetReturnValue may take more arguments as optimization hints
+// depending on the return value type.
+
+struct V8ReturnValue {
+ // Support compile-time overload resolution by making each value have its own
+ // type.
+
+ // Nullable or not
+ enum NonNullable { kNonNullable };
+ enum Nullable { kNullable };
+
+ // Main world or not
+ enum MainWorld { kMainWorld };
+
+ // Returns the interface object of the given type.
+ enum InterfaceObject { kInterfaceObject };
+};
+
+// V8 handle types
+template <typename CallbackInfo, typename S>
+void V8SetReturnValue(const CallbackInfo& info, const v8::Global<S> value) {
+ info.GetReturnValue().Set(value);
+}
+
+template <typename CallbackInfo, typename S>
+void V8SetReturnValue(const CallbackInfo& info, const v8::Local<S> value) {
+ info.GetReturnValue().Set(value);
+}
+
+// Property descriptor
+PLATFORM_EXPORT v8::Local<v8::Object> CreatePropertyDescriptorObject(
+ v8::Isolate* isolate,
+ const v8::PropertyDescriptor& desc);
+
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info,
+ const v8::PropertyDescriptor& value) {
+ info.GetReturnValue().Set(
+ CreatePropertyDescriptorObject(info.GetIsolate(), value));
+}
+
+// Indexed properties and named properties
+PLATFORM_EXPORT inline void V8SetReturnValue(
+ const v8::FunctionCallbackInfo<v8::Value>& info,
+ IndexedPropertySetterResult value) {
+ // If an operation implementing indexed property setter is invoked as a
+ // regular operation, and the return type is not type void (V8SetReturnValue
+ // won't be called in case of type void), then return the given value as is.
+ info.GetReturnValue().Set(info[1]);
+}
+
+PLATFORM_EXPORT inline void V8SetReturnValue(
+ const v8::PropertyCallbackInfo<v8::Value>& info,
+ IndexedPropertySetterResult value) {
+ if (value == IndexedPropertySetterResult::kDidNotIntercept) {
+ // Do not set the return value to indicate that the request was not
+ // intercepted.
+ return;
+ }
+ info.GetReturnValue().SetNull();
+}
+
+PLATFORM_EXPORT inline void V8SetReturnValue(
+ const v8::FunctionCallbackInfo<v8::Value>& info,
+ NamedPropertySetterResult value) {
+ // If an operation implementing named property setter is invoked as a
+ // regular operation, and the return type is not type void (V8SetReturnValue
+ // won't be called in case of type void), then return the given value as is.
+ info.GetReturnValue().Set(info[1]);
+}
+
+PLATFORM_EXPORT inline void V8SetReturnValue(
+ const v8::PropertyCallbackInfo<v8::Value>& info,
+ NamedPropertySetterResult value) {
+ if (value == NamedPropertySetterResult::kDidNotIntercept) {
+ // Do not set the return value to indicate that the request was not
+ // intercepted.
+ return;
+ }
+ info.GetReturnValue().SetNull();
+}
+
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info,
+ NamedPropertyDeleterResult value) {
+ if (value == NamedPropertyDeleterResult::kDidNotIntercept) {
+ // Do not set the return value to indicate that the request was not
+ // intercepted.
+ return;
+ }
+ info.GetReturnValue().Set(value == NamedPropertyDeleterResult::kDeleted);
+}
+
+// nullptr
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info, std::nullptr_t) {
+ info.GetReturnValue().SetNull();
+}
+
+// Primitive types
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info, bool value) {
+ info.GetReturnValue().Set(value);
+}
+
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info, int32_t value) {
+ info.GetReturnValue().Set(value);
+}
+
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info, uint32_t value) {
+ info.GetReturnValue().Set(value);
+}
+
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info, int64_t value) {
+ // ECMAScript doesn't support 64-bit integer in Number type.
+ info.GetReturnValue().Set(static_cast<double>(value));
+}
+
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info, uint64_t value) {
+ // ECMAScript doesn't support 64-bit integer in Number type.
+ info.GetReturnValue().Set(static_cast<double>(value));
+}
+
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info, double value) {
+ info.GetReturnValue().Set(value);
+}
+
+// String types
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info,
+ const AtomicString& string,
+ v8::Isolate* isolate,
+ V8ReturnValue::NonNullable) {
+ if (string.IsNull())
+ return info.GetReturnValue().SetEmptyString();
+ V8PerIsolateData::From(isolate)->GetStringCache()->SetReturnValueFromString(
+ info.GetReturnValue(), string.Impl());
+}
+
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info,
+ const String& string,
+ v8::Isolate* isolate,
+ V8ReturnValue::NonNullable) {
+ if (string.IsNull())
+ return info.GetReturnValue().SetEmptyString();
+ V8PerIsolateData::From(isolate)->GetStringCache()->SetReturnValueFromString(
+ info.GetReturnValue(), string.Impl());
+}
+
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info,
+ const WebString& string,
+ v8::Isolate* isolate,
+ V8ReturnValue::NonNullable) {
+ if (string.IsNull())
+ return info.GetReturnValue().SetEmptyString();
+ V8PerIsolateData::From(isolate)->GetStringCache()->SetReturnValueFromString(
+ info.GetReturnValue(), static_cast<String>(string).Impl());
+}
+
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info,
+ const AtomicString& string,
+ v8::Isolate* isolate,
+ V8ReturnValue::Nullable) {
+ if (string.IsNull())
+ return info.GetReturnValue().SetNull();
+ V8PerIsolateData::From(isolate)->GetStringCache()->SetReturnValueFromString(
+ info.GetReturnValue(), string.Impl());
+}
+
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info,
+ const String& string,
+ v8::Isolate* isolate,
+ V8ReturnValue::Nullable) {
+ if (string.IsNull())
+ return info.GetReturnValue().SetNull();
+ V8PerIsolateData::From(isolate)->GetStringCache()->SetReturnValueFromString(
+ info.GetReturnValue(), string.Impl());
+}
+
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info,
+ const WebString& string,
+ v8::Isolate* isolate,
+ V8ReturnValue::Nullable) {
+ if (string.IsNull())
+ return info.GetReturnValue().SetNull();
+ V8PerIsolateData::From(isolate)->GetStringCache()->SetReturnValueFromString(
+ info.GetReturnValue(), static_cast<String>(string).Impl());
+}
+
+// ScriptWrappable
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info,
+ const ScriptWrappable* value,
+ V8ReturnValue::MainWorld) {
+ DCHECK(DOMWrapperWorld::Current(info.GetIsolate()).IsMainWorld());
+ if (UNLIKELY(!value))
+ return info.GetReturnValue().SetNull();
+
+ ScriptWrappable* wrappable = const_cast<ScriptWrappable*>(value);
+ if (DOMDataStore::SetReturnValueForMainWorld(info.GetReturnValue(),
+ wrappable))
+ return;
+
+ info.GetReturnValue().Set(wrappable->Wrap(info.GetIsolate(), info.This()));
+}
+
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info,
+ const ScriptWrappable& value,
+ V8ReturnValue::MainWorld) {
+ DCHECK(DOMWrapperWorld::Current(info.GetIsolate()).IsMainWorld());
+ ScriptWrappable* wrappable = const_cast<ScriptWrappable*>(&value);
+ if (DOMDataStore::SetReturnValueForMainWorld(info.GetReturnValue(),
+ wrappable))
+ return;
+
+ info.GetReturnValue().Set(wrappable->Wrap(info.GetIsolate(), info.This()));
+}
+
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info,
+ const ScriptWrappable* value,
+ const ScriptWrappable* receiver) {
+ if (UNLIKELY(!value))
+ return info.GetReturnValue().SetNull();
+
+ ScriptWrappable* wrappable = const_cast<ScriptWrappable*>(value);
+ if (DOMDataStore::SetReturnValueFast(info.GetReturnValue(), wrappable,
+ info.This(), receiver)) {
+ return;
+ }
+
+ info.GetReturnValue().Set(wrappable->Wrap(info.GetIsolate(), info.This()));
+}
+
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info,
+ const ScriptWrappable& value,
+ const ScriptWrappable* receiver) {
+ ScriptWrappable* wrappable = const_cast<ScriptWrappable*>(&value);
+ if (DOMDataStore::SetReturnValueFast(info.GetReturnValue(), wrappable,
+ info.This(), receiver)) {
+ return;
+ }
+
+ info.GetReturnValue().Set(wrappable->Wrap(info.GetIsolate(), info.This()));
+}
+
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info,
+ const ScriptWrappable* value,
+ v8::Local<v8::Context> creation_context) {
+ if (UNLIKELY(!value))
+ return info.GetReturnValue().SetNull();
+
+ ScriptWrappable* wrappable = const_cast<ScriptWrappable*>(value);
+ if (DOMDataStore::SetReturnValue(info.GetReturnValue(), wrappable))
+ return;
+
+ info.GetReturnValue().Set(
+ wrappable->Wrap(info.GetIsolate(), creation_context->Global()));
+}
+
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info,
+ ScriptWrappable& value,
+ v8::Local<v8::Context> creation_context) {
+ ScriptWrappable* wrappable = const_cast<ScriptWrappable*>(&value);
+ if (DOMDataStore::SetReturnValue(info.GetReturnValue(), wrappable))
+ return;
+
+ info.GetReturnValue().Set(
+ wrappable->Wrap(info.GetIsolate(), creation_context->Global()));
+}
+
+// Interface object
+PLATFORM_EXPORT v8::Local<v8::Value> GetInterfaceObjectExposedOnGlobal(
+ v8::Isolate* isolate,
+ v8::Local<v8::Object> creation_context,
+ const WrapperTypeInfo* wrapper_type_info);
+
+template <typename CallbackInfo>
+void V8SetReturnValue(const CallbackInfo& info,
+ const WrapperTypeInfo* wrapper_type_info,
+ V8ReturnValue::InterfaceObject) {
+ info.GetReturnValue().Set(GetInterfaceObjectExposedOnGlobal(
+ info.GetIsolate(), info.This(), wrapper_type_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
+ info.GetReturnValue().SetNull();
+}
+
+} // namespace bindings
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_V8_SET_RETURN_VALUE_H_
diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_value_or_script_wrappable_adapter.h b/chromium/third_party/blink/renderer/platform/bindings/v8_value_or_script_wrappable_adapter.h
index b2d53160dfb..b8aa4bd15b7 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/v8_value_or_script_wrappable_adapter.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/v8_value_or_script_wrappable_adapter.h
@@ -51,7 +51,7 @@ class PLATFORM_EXPORT V8ValueOrScriptWrappableAdapter {
private:
v8::Local<v8::Value> v8_value_;
- Member<ScriptWrappable> script_wrappable_;
+ ScriptWrappable* script_wrappable_ = nullptr;
};
} // namespace bindings
diff --git a/chromium/third_party/blink/renderer/platform/bindings/wrapper_type_info.cc b/chromium/third_party/blink/renderer/platform/bindings/wrapper_type_info.cc
index a9ce328a3b6..d621fa0345c 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/wrapper_type_info.cc
+++ b/chromium/third_party/blink/renderer/platform/bindings/wrapper_type_info.cc
@@ -27,14 +27,14 @@ void WrapperTypeInfo::WrapperDestroyed() {
stats_collector->IncreaseCollectedWrapperCount(1);
}
-void WrapperTypeInfo::Trace(Visitor* visitor, void* impl) const {
+void WrapperTypeInfo::Trace(Visitor* visitor, const void* impl) const {
switch (wrapper_class_id) {
case WrapperTypeInfo::kNodeClassId:
case WrapperTypeInfo::kObjectClassId:
- visitor->Trace(reinterpret_cast<ScriptWrappable*>(impl));
+ visitor->Trace(reinterpret_cast<const ScriptWrappable*>(impl));
break;
case WrapperTypeInfo::kCustomWrappableId:
- visitor->Trace(reinterpret_cast<CustomWrappable*>(impl));
+ visitor->Trace(reinterpret_cast<const CustomWrappable*>(impl));
break;
default:
NOTREACHED();
diff --git a/chromium/third_party/blink/renderer/platform/bindings/wrapper_type_info.h b/chromium/third_party/blink/renderer/platform/bindings/wrapper_type_info.h
index 4782a9e4557..f0b2232622b 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/wrapper_type_info.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/wrapper_type_info.h
@@ -153,7 +153,7 @@ struct WrapperTypeInfo {
// Garbage collection support for when the type depends the WrapperTypeInfo
// object.
- PLATFORM_EXPORT void Trace(Visitor*, void*) const;
+ PLATFORM_EXPORT void Trace(Visitor*, const void*) const;
// This field must be the first member of the struct WrapperTypeInfo.
// See also static_assert() in .cpp file.
diff --git a/chromium/third_party/blink/renderer/platform/blob/BUILD.gn b/chromium/third_party/blink/renderer/platform/blob/BUILD.gn
index 635665ec38c..0f744c876b8 100644
--- a/chromium/third_party/blink/renderer/platform/blob/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/blob/BUILD.gn
@@ -33,9 +33,7 @@ blink_platform_sources("blob") {
"serialized_blob_mojom_traits.h",
]
- deps = [
- "//services/network/public/mojom:mojom_blink",
- ]
+ deps = [ "//services/network/public/mojom:mojom_blink" ]
}
jumbo_source_set("unit_tests") {
diff --git a/chromium/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc b/chromium/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc
index 22cac3dac0e..833971da422 100644
--- a/chromium/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc
+++ b/chromium/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc
@@ -4,8 +4,10 @@
#include "third_party/blink/renderer/platform/blob/blob_bytes_provider.h"
+#include "base/memory/ptr_util.h"
#include "base/numerics/safe_conversions.h"
#include "base/task/post_task.h"
+#include "base/task/thread_pool.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
@@ -117,8 +119,8 @@ constexpr size_t BlobBytesProvider::kMaxConsolidatedItemSizeInBytes;
// static
BlobBytesProvider* BlobBytesProvider::CreateAndBind(
mojo::PendingReceiver<mojom::blink::BytesProvider> receiver) {
- auto task_runner = base::CreateSequencedTaskRunner(
- {base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_VISIBLE});
+ auto task_runner = base::ThreadPool::CreateSequencedTaskRunner(
+ {base::MayBlock(), base::TaskPriority::USER_VISIBLE});
auto provider = base::WrapUnique(new BlobBytesProvider(task_runner));
auto* result = provider.get();
// TODO(mek): Consider binding BytesProvider on the IPC thread instead, only
diff --git a/chromium/third_party/blink/renderer/platform/blob/blob_data.cc b/chromium/third_party/blink/renderer/platform/blob/blob_data.cc
index 1b5e7a11cc6..a381dbc3140 100644
--- a/chromium/third_party/blink/renderer/platform/blob/blob_data.cc
+++ b/chromium/third_party/blink/renderer/platform/blob/blob_data.cc
@@ -38,11 +38,11 @@
#include "base/single_thread_task_runner.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/network/public/mojom/data_pipe_getter.mojom-blink.h"
+#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.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/mojom/blob/data_element.mojom-blink.h"
#include "third_party/blink/public/platform/file_path_conversion.h"
-#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/blob/blob_bytes_provider.h"
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
@@ -85,10 +85,10 @@ mojom::blink::BlobRegistry* GetThreadSpecificRegistry() {
DEFINE_THREAD_SAFE_STATIC_LOCAL(
ThreadSpecific<mojo::Remote<mojom::blink::BlobRegistry>>, registry, ());
if (UNLIKELY(!registry.IsSet())) {
- // TODO(mek): Going through InterfaceProvider to get a
+ // TODO(mek): Going through BrowserInterfaceBroker to get a
// mojom::blink::BlobRegistry ends up going through the main thread. Ideally
// workers wouldn't need to do that.
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
(*registry).BindNewPipeAndPassReceiver());
}
return registry->get();
@@ -103,7 +103,7 @@ RawData::RawData() = default;
BlobData::BlobData(FileCompositionStatus composition)
: file_composition_(composition) {}
-BlobData::~BlobData() {}
+BlobData::~BlobData() = default;
Vector<mojom::blink::DataElementPtr> BlobData::ReleaseElements() {
return std::move(elements_);
@@ -173,6 +173,7 @@ void BlobData::AppendFile(
"create a blob with a single file with unknown size, use "
"BlobData::createForFileWithUnknownSize. Otherwise please provide the "
"file size.";
+ DCHECK_GE(length, 0);
// Skip zero-byte items, as they don't matter for the contents of the blob.
if (length == 0)
return;
@@ -201,6 +202,7 @@ void BlobData::AppendFileSystemURL(
const base::Optional<base::Time>& expected_modification_time) {
DCHECK_EQ(file_composition_, FileCompositionStatus::NO_UNKNOWN_SIZE_FILES)
<< "Blobs with a unknown-size file cannot have other items.";
+ DCHECK_GE(length, 0);
// Skip zero-byte items, as they don't matter for the contents of the blob.
if (length == 0)
return;
@@ -359,8 +361,7 @@ BlobDataHandle::BlobDataHandle(
DCHECK(blob_remote_.is_valid());
}
-BlobDataHandle::~BlobDataHandle() {
-}
+BlobDataHandle::~BlobDataHandle() = default;
mojo::PendingRemote<mojom::blink::Blob> BlobDataHandle::CloneBlobRemote() {
MutexLocker locker(blob_remote_mutex_);
@@ -415,6 +416,16 @@ void BlobDataHandle::ReadRange(
blob_remote_ = blob.Unbind();
}
+bool BlobDataHandle::CaptureSnapshot(
+ uint64_t* snapshot_size,
+ base::Optional<base::Time>* snapshot_modification_time) {
+ // This method operates on a cloned blob remote; this lets us avoid holding
+ // the |blob_remote_mutex_| locked during the duration of the (synchronous)
+ // CaptureSnapshot call.
+ mojo::Remote<mojom::blink::Blob> remote(CloneBlobRemote());
+ return remote->CaptureSnapshot(snapshot_size, snapshot_modification_time);
+}
+
// static
mojom::blink::BlobRegistry* BlobDataHandle::GetBlobRegistry() {
return GetThreadSpecificRegistry();
diff --git a/chromium/third_party/blink/renderer/platform/blob/blob_data.h b/chromium/third_party/blink/renderer/platform/blob/blob_data.h
index 9965fe9c64b..33c842a9510 100644
--- a/chromium/third_party/blink/renderer/platform/blob/blob_data.h
+++ b/chromium/third_party/blink/renderer/platform/blob/blob_data.h
@@ -219,6 +219,16 @@ class PLATFORM_EXPORT BlobDataHandle
mojo::ScopedDataPipeProducerHandle,
mojo::PendingRemote<mojom::blink::BlobReaderClient>);
+ // This does synchronous IPC, and possibly synchronous file operations. Think
+ // twice before calling this function.
+ bool CaptureSnapshot(uint64_t* snapshot_size,
+ base::Optional<base::Time>* snapshot_modification_time);
+
+ void SetBlobRemoteForTesting(mojo::PendingRemote<mojom::blink::Blob> remote) {
+ MutexLocker locker(blob_remote_mutex_);
+ blob_remote_ = std::move(remote);
+ }
+
static mojom::blink::BlobRegistry* GetBlobRegistry();
static void SetBlobRegistryForTesting(mojom::blink::BlobRegistry*);
diff --git a/chromium/third_party/blink/renderer/platform/blob/blob_data_test.cc b/chromium/third_party/blink/renderer/platform/blob/blob_data_test.cc
index aa375aa798d..b515e0b11ad 100644
--- a/chromium/third_party/blink/renderer/platform/blob/blob_data_test.cc
+++ b/chromium/third_party/blink/renderer/platform/blob/blob_data_test.cc
@@ -15,7 +15,6 @@
#include "testing/gtest/include/gtest/gtest.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/interface_provider.h"
#include "third_party/blink/renderer/platform/blob/blob_bytes_provider.h"
#include "third_party/blink/renderer/platform/blob/testing/fake_blob_registry.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
diff --git a/chromium/third_party/blink/renderer/platform/blob/testing/fake_blob.cc b/chromium/third_party/blink/renderer/platform/blob/testing/fake_blob.cc
index 733798e9c77..5dd4ae6b61e 100644
--- a/chromium/third_party/blink/renderer/platform/blob/testing/fake_blob.cc
+++ b/chromium/third_party/blink/renderer/platform/blob/testing/fake_blob.cc
@@ -80,6 +80,10 @@ void FakeBlob::ReadSideData(ReadSideDataCallback callback) {
NOTREACHED();
}
+void FakeBlob::CaptureSnapshot(CaptureSnapshotCallback callback) {
+ std::move(callback).Run(body_.length(), base::nullopt);
+}
+
void FakeBlob::GetInternalUUID(GetInternalUUIDCallback callback) {
std::move(callback).Run(uuid_);
}
diff --git a/chromium/third_party/blink/renderer/platform/blob/testing/fake_blob.h b/chromium/third_party/blink/renderer/platform/blob/testing/fake_blob.h
index 8ec5c7654c1..845330f9ee4 100644
--- a/chromium/third_party/blink/renderer/platform/blob/testing/fake_blob.h
+++ b/chromium/third_party/blink/renderer/platform/blob/testing/fake_blob.h
@@ -32,8 +32,10 @@ class FakeBlob : public mojom::blink::Blob {
void ReadAll(mojo::ScopedDataPipeProducerHandle,
mojo::PendingRemote<mojom::blink::BlobReaderClient>) override;
void ReadSideData(ReadSideDataCallback) override;
+ void CaptureSnapshot(CaptureSnapshotCallback) override;
void GetInternalUUID(GetInternalUUIDCallback) override;
- private:
+
+ protected:
String uuid_;
String body_;
State* state_;
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 d9d00569546..5bcfa0a11ea 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(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/context_lifecycle_notifier.h b/chromium/third_party/blink/renderer/platform/context_lifecycle_notifier.h
new file mode 100644
index 00000000000..6b16cfe76bb
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/context_lifecycle_notifier.h
@@ -0,0 +1,23 @@
+// 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_CONTEXT_LIFECYCLE_NOTIFIER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_CONTEXT_LIFECYCLE_NOTIFIER_H_
+
+#include "third_party/blink/renderer/platform/heap/handle.h"
+
+namespace blink {
+
+class ContextLifecycleObserver;
+
+// Notifier interface for ContextLifecycleObserver.
+class PLATFORM_EXPORT ContextLifecycleNotifier : public GarbageCollectedMixin {
+ public:
+ virtual void AddContextLifecycleObserver(ContextLifecycleObserver*) = 0;
+ virtual void RemoveContextLifecycleObserver(ContextLifecycleObserver*) = 0;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_CONTEXT_LIFECYCLE_NOTIFIER_H_
diff --git a/chromium/third_party/blink/renderer/platform/context_lifecycle_observer.cc b/chromium/third_party/blink/renderer/platform/context_lifecycle_observer.cc
new file mode 100644
index 00000000000..9387ae06507
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/context_lifecycle_observer.cc
@@ -0,0 +1,33 @@
+// 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/context_lifecycle_observer.h"
+
+#include "third_party/blink/renderer/platform/context_lifecycle_notifier.h"
+
+namespace blink {
+
+void ContextLifecycleObserver::ObserverListWillBeCleared() {
+ notifier_ = nullptr;
+}
+
+void ContextLifecycleObserver::SetContextLifecycleNotifier(
+ ContextLifecycleNotifier* notifier) {
+ if (notifier == notifier_)
+ return;
+
+ if (notifier_)
+ notifier_->RemoveContextLifecycleObserver(this);
+
+ notifier_ = notifier;
+
+ if (notifier_)
+ notifier_->AddContextLifecycleObserver(this);
+}
+
+void ContextLifecycleObserver::Trace(Visitor* visitor) {
+ visitor->Trace(notifier_);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/context_lifecycle_observer.h b/chromium/third_party/blink/renderer/platform/context_lifecycle_observer.h
new file mode 100644
index 00000000000..cc5ef14ff92
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/context_lifecycle_observer.h
@@ -0,0 +1,41 @@
+// 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_CONTEXT_LIFECYCLE_OBSERVER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_CONTEXT_LIFECYCLE_OBSERVER_H_
+
+#include "third_party/blink/renderer/platform/heap/handle.h"
+
+namespace blink {
+
+class ContextLifecycleNotifier;
+
+// Observer that gets notified when the context is destroyed. Used to observe
+// ExecutionContext from platform/.
+class PLATFORM_EXPORT ContextLifecycleObserver : public GarbageCollectedMixin {
+ public:
+ virtual void ContextDestroyed() = 0;
+
+ // Call before clearing an observer list.
+ void ObserverListWillBeCleared();
+
+ ContextLifecycleNotifier* GetContextLifecycleNotifier() const {
+ return notifier_;
+ }
+ void SetContextLifecycleNotifier(ContextLifecycleNotifier*);
+
+ virtual bool IsExecutionContextLifecycleObserver() const { return false; }
+
+ void Trace(Visitor*) override;
+
+ protected:
+ ContextLifecycleObserver() = default;
+
+ private:
+ WeakMember<ContextLifecycleNotifier> notifier_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_CONTEXT_LIFECYCLE_OBSERVER_H_
diff --git a/chromium/third_party/blink/renderer/platform/crypto_result.h b/chromium/third_party/blink/renderer/platform/crypto_result.h
index 2fc6b5aa1ee..9b4e3d54825 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(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/cursor.cc b/chromium/third_party/blink/renderer/platform/cursor.cc
deleted file mode 100644
index e8eb0874b09..00000000000
--- a/chromium/third_party/blink/renderer/platform/cursor.cc
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Copyright (C) 2010 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 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/platform/cursor.h"
-#include "third_party/blink/renderer/platform/wtf/assertions.h"
-
-namespace blink {
-
-IntPoint DetermineHotSpot(Image* image,
- bool hot_spot_specified,
- const IntPoint& specified_hot_spot) {
- if (image->IsNull())
- return IntPoint();
-
- IntRect image_rect = image->Rect();
-
- // Hot spot must be inside cursor rectangle.
- if (hot_spot_specified) {
- if (image_rect.Contains(specified_hot_spot)) {
- return specified_hot_spot;
- }
-
- return IntPoint(clampTo<int>(specified_hot_spot.X(), image_rect.X(),
- image_rect.MaxX() - 1),
- clampTo<int>(specified_hot_spot.Y(), image_rect.Y(),
- image_rect.MaxY() - 1));
- }
-
- // If hot spot is not specified externally, it can be extracted from some
- // image formats (e.g. .cur).
- IntPoint intrinsic_hot_spot;
- bool image_has_intrinsic_hot_spot = image->GetHotSpot(intrinsic_hot_spot);
- if (image_has_intrinsic_hot_spot && image_rect.Contains(intrinsic_hot_spot))
- return intrinsic_hot_spot;
-
- // If neither is provided, use a default value of (0, 0).
- return IntPoint();
-}
-
-Cursor::Cursor(Image* image, bool hot_spot_specified, const IntPoint& hot_spot)
- : type_(ui::CursorType::kCustom),
- image_(image),
- hot_spot_(DetermineHotSpot(image, hot_spot_specified, hot_spot)),
- image_scale_factor_(1) {}
-
-Cursor::Cursor(Image* image,
- bool hot_spot_specified,
- const IntPoint& hot_spot,
- float scale)
- : type_(ui::CursorType::kCustom),
- image_(image),
- hot_spot_(DetermineHotSpot(image, hot_spot_specified, hot_spot)),
- image_scale_factor_(scale) {}
-
-Cursor::Cursor(ui::CursorType type) : type_(type), image_scale_factor_(1) {}
-
-Cursor::Cursor(const Cursor& other) = default;
-
-Cursor& Cursor::operator=(const Cursor& other) {
- type_ = other.type_;
- image_ = other.image_;
- hot_spot_ = other.hot_spot_;
- image_scale_factor_ = other.image_scale_factor_;
- return *this;
-}
-
-Cursor::~Cursor() = default;
-
-const Cursor& PointerCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kPointer));
- return c;
-}
-
-const Cursor& CrossCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kCross));
- return c;
-}
-
-const Cursor& HandCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kHand));
- return c;
-}
-
-const Cursor& MoveCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kMove));
- return c;
-}
-
-const Cursor& VerticalTextCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kVerticalText));
- return c;
-}
-
-const Cursor& CellCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kCell));
- return c;
-}
-
-const Cursor& ContextMenuCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kContextMenu));
- return c;
-}
-
-const Cursor& AliasCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kAlias));
- return c;
-}
-
-const Cursor& ZoomInCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kZoomIn));
- return c;
-}
-
-const Cursor& ZoomOutCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kZoomOut));
- return c;
-}
-
-const Cursor& CopyCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kCopy));
- return c;
-}
-
-const Cursor& NoneCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kNone));
- return c;
-}
-
-const Cursor& ProgressCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kProgress));
- return c;
-}
-
-const Cursor& NoDropCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kNoDrop));
- return c;
-}
-
-const Cursor& NotAllowedCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kNotAllowed));
- return c;
-}
-
-const Cursor& IBeamCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kIBeam));
- return c;
-}
-
-const Cursor& WaitCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kWait));
- return c;
-}
-
-const Cursor& HelpCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kHelp));
- return c;
-}
-
-const Cursor& EastResizeCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kEastResize));
- return c;
-}
-
-const Cursor& NorthResizeCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kNorthResize));
- return c;
-}
-
-const Cursor& NorthEastResizeCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kNorthEastResize));
- return c;
-}
-
-const Cursor& NorthWestResizeCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kNorthWestResize));
- return c;
-}
-
-const Cursor& SouthResizeCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kSouthResize));
- return c;
-}
-
-const Cursor& SouthEastResizeCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kSouthEastResize));
- return c;
-}
-
-const Cursor& SouthWestResizeCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kSouthWestResize));
- return c;
-}
-
-const Cursor& WestResizeCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kWestResize));
- return c;
-}
-
-const Cursor& NorthSouthResizeCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kNorthSouthResize));
- return c;
-}
-
-const Cursor& EastWestResizeCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kEastWestResize));
- return c;
-}
-
-const Cursor& NorthEastSouthWestResizeCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kNorthEastSouthWestResize));
- return c;
-}
-
-const Cursor& NorthWestSouthEastResizeCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kNorthWestSouthEastResize));
- return c;
-}
-
-const Cursor& ColumnResizeCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kColumnResize));
- return c;
-}
-
-const Cursor& RowResizeCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kRowResize));
- return c;
-}
-
-const Cursor& MiddlePanningCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kMiddlePanning));
- return c;
-}
-
-const Cursor& MiddlePanningVerticalCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kMiddlePanningVertical));
- return c;
-}
-
-const Cursor& MiddlePanningHorizontalCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kMiddlePanningHorizontal));
- return c;
-}
-
-const Cursor& EastPanningCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kEastPanning));
- return c;
-}
-
-const Cursor& NorthPanningCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kNorthPanning));
- return c;
-}
-
-const Cursor& NorthEastPanningCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kNorthEastPanning));
- return c;
-}
-
-const Cursor& NorthWestPanningCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kNorthWestPanning));
- return c;
-}
-
-const Cursor& SouthPanningCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kSouthPanning));
- return c;
-}
-
-const Cursor& SouthEastPanningCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kSouthEastPanning));
- return c;
-}
-
-const Cursor& SouthWestPanningCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kSouthWestPanning));
- return c;
-}
-
-const Cursor& WestPanningCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kWestPanning));
- return c;
-}
-
-const Cursor& GrabCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kGrab));
- return c;
-}
-
-const Cursor& GrabbingCursor() {
- DEFINE_STATIC_LOCAL(Cursor, c, (ui::CursorType::kGrabbing));
- return c;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/cursor.h b/chromium/third_party/blink/renderer/platform/cursor.h
deleted file mode 100644
index 4317df0a668..00000000000
--- a/chromium/third_party/blink/renderer/platform/cursor.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2004, 2006, 2008 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_PLATFORM_CURSOR_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_CURSOR_H_
-
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/public/platform/web_cursor_info.h"
-#include "third_party/blink/renderer/platform/geometry/int_point.h"
-#include "third_party/blink/renderer/platform/graphics/image.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/assertions.h"
-
-// To avoid conflicts with the CreateWindow macro from the Windows SDK...
-#undef CopyCursor
-
-namespace blink {
-
-class PLATFORM_EXPORT Cursor {
- USING_FAST_MALLOC(Cursor);
-
- public:
- Cursor()
- // This is an invalid Cursor and should never actually get used.
- : type_(ui::CursorType::kNull) {}
-
- Cursor(Image*, bool hot_spot_specified, const IntPoint& hot_spot);
-
- // Hot spot is in image pixels.
- Cursor(Image*,
- bool hot_spot_specified,
- const IntPoint& hot_spot,
- float image_scale_factor);
-
- Cursor(const Cursor&);
- ~Cursor();
- Cursor& operator=(const Cursor&);
-
- explicit Cursor(ui::CursorType);
- ui::CursorType GetType() const {
- DCHECK_GE(type_, static_cast<ui::CursorType>(0));
- DCHECK_LE(type_, ui::CursorType::kCustom);
- return type_;
- }
- Image* GetImage() const { return image_.get(); }
- const IntPoint& HotSpot() const { return hot_spot_; }
- // Image scale in image pixels per logical (UI) pixel.
- float ImageScaleFactor() const { return image_scale_factor_; }
-
- private:
- ui::CursorType type_;
- scoped_refptr<Image> image_;
- IntPoint hot_spot_;
- float image_scale_factor_;
-};
-
-PLATFORM_EXPORT IntPoint DetermineHotSpot(Image*,
- bool hot_spot_specified,
- const IntPoint& specified_hot_spot);
-
-PLATFORM_EXPORT const Cursor& PointerCursor();
-PLATFORM_EXPORT const Cursor& CrossCursor();
-PLATFORM_EXPORT const Cursor& HandCursor();
-PLATFORM_EXPORT const Cursor& MoveCursor();
-PLATFORM_EXPORT const Cursor& IBeamCursor();
-PLATFORM_EXPORT const Cursor& WaitCursor();
-PLATFORM_EXPORT const Cursor& HelpCursor();
-PLATFORM_EXPORT const Cursor& EastResizeCursor();
-PLATFORM_EXPORT const Cursor& NorthResizeCursor();
-PLATFORM_EXPORT const Cursor& NorthEastResizeCursor();
-PLATFORM_EXPORT const Cursor& NorthWestResizeCursor();
-PLATFORM_EXPORT const Cursor& SouthResizeCursor();
-PLATFORM_EXPORT const Cursor& SouthEastResizeCursor();
-PLATFORM_EXPORT const Cursor& SouthWestResizeCursor();
-PLATFORM_EXPORT const Cursor& WestResizeCursor();
-PLATFORM_EXPORT const Cursor& NorthSouthResizeCursor();
-PLATFORM_EXPORT const Cursor& EastWestResizeCursor();
-PLATFORM_EXPORT const Cursor& NorthEastSouthWestResizeCursor();
-PLATFORM_EXPORT const Cursor& NorthWestSouthEastResizeCursor();
-PLATFORM_EXPORT const Cursor& ColumnResizeCursor();
-PLATFORM_EXPORT const Cursor& RowResizeCursor();
-PLATFORM_EXPORT const Cursor& MiddlePanningCursor();
-PLATFORM_EXPORT const Cursor& MiddlePanningVerticalCursor();
-PLATFORM_EXPORT const Cursor& MiddlePanningHorizontalCursor();
-PLATFORM_EXPORT const Cursor& EastPanningCursor();
-PLATFORM_EXPORT const Cursor& NorthPanningCursor();
-PLATFORM_EXPORT const Cursor& NorthEastPanningCursor();
-PLATFORM_EXPORT const Cursor& NorthWestPanningCursor();
-PLATFORM_EXPORT const Cursor& SouthPanningCursor();
-PLATFORM_EXPORT const Cursor& SouthEastPanningCursor();
-PLATFORM_EXPORT const Cursor& SouthWestPanningCursor();
-PLATFORM_EXPORT const Cursor& WestPanningCursor();
-PLATFORM_EXPORT const Cursor& VerticalTextCursor();
-PLATFORM_EXPORT const Cursor& CellCursor();
-PLATFORM_EXPORT const Cursor& ContextMenuCursor();
-PLATFORM_EXPORT const Cursor& NoDropCursor();
-PLATFORM_EXPORT const Cursor& NotAllowedCursor();
-PLATFORM_EXPORT const Cursor& ProgressCursor();
-PLATFORM_EXPORT const Cursor& AliasCursor();
-PLATFORM_EXPORT const Cursor& ZoomInCursor();
-PLATFORM_EXPORT const Cursor& ZoomOutCursor();
-PLATFORM_EXPORT const Cursor& CopyCursor();
-PLATFORM_EXPORT const Cursor& NoneCursor();
-PLATFORM_EXPORT const Cursor& GrabCursor();
-PLATFORM_EXPORT const Cursor& GrabbingCursor();
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_CURSOR_H_
diff --git a/chromium/third_party/blink/renderer/platform/cursors.cc b/chromium/third_party/blink/renderer/platform/cursors.cc
new file mode 100644
index 00000000000..a3a9c9f7fe9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/cursors.cc
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2010 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 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/platform/cursors.h"
+
+#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
+#include "ui/base/cursor/cursor.h"
+#include "ui/base/mojom/cursor_type.mojom-blink.h"
+
+// To avoid conflicts with the CreateWindow macro from the Windows SDK...
+#undef CopyCursor
+
+namespace blink {
+
+const ui::Cursor& PointerCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c, (ui::mojom::blink::CursorType::kPointer));
+ return c;
+}
+
+const ui::Cursor& CrossCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c, (ui::mojom::blink::CursorType::kCross));
+ return c;
+}
+
+const ui::Cursor& HandCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c, (ui::mojom::blink::CursorType::kHand));
+ return c;
+}
+
+const ui::Cursor& MoveCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c, (ui::mojom::blink::CursorType::kMove));
+ return c;
+}
+
+const ui::Cursor& VerticalTextCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kVerticalText));
+ return c;
+}
+
+const ui::Cursor& CellCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c, (ui::mojom::blink::CursorType::kCell));
+ return c;
+}
+
+const ui::Cursor& ContextMenuCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kContextMenu));
+ return c;
+}
+
+const ui::Cursor& AliasCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c, (ui::mojom::blink::CursorType::kAlias));
+ return c;
+}
+
+const ui::Cursor& ZoomInCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c, (ui::mojom::blink::CursorType::kZoomIn));
+ return c;
+}
+
+const ui::Cursor& ZoomOutCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c, (ui::mojom::blink::CursorType::kZoomOut));
+ return c;
+}
+
+const ui::Cursor& CopyCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c, (ui::mojom::blink::CursorType::kCopy));
+ return c;
+}
+
+const ui::Cursor& NoneCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c, (ui::mojom::blink::CursorType::kNone));
+ return c;
+}
+
+const ui::Cursor& ProgressCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c, (ui::mojom::blink::CursorType::kProgress));
+ return c;
+}
+
+const ui::Cursor& NoDropCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c, (ui::mojom::blink::CursorType::kNoDrop));
+ return c;
+}
+
+const ui::Cursor& NotAllowedCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kNotAllowed));
+ return c;
+}
+
+const ui::Cursor& IBeamCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c, (ui::mojom::blink::CursorType::kIBeam));
+ return c;
+}
+
+const ui::Cursor& WaitCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c, (ui::mojom::blink::CursorType::kWait));
+ return c;
+}
+
+const ui::Cursor& HelpCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c, (ui::mojom::blink::CursorType::kHelp));
+ return c;
+}
+
+const ui::Cursor& EastResizeCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kEastResize));
+ return c;
+}
+
+const ui::Cursor& NorthResizeCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kNorthResize));
+ return c;
+}
+
+const ui::Cursor& NorthEastResizeCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kNorthEastResize));
+ return c;
+}
+
+const ui::Cursor& NorthWestResizeCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kNorthWestResize));
+ return c;
+}
+
+const ui::Cursor& SouthResizeCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kSouthResize));
+ return c;
+}
+
+const ui::Cursor& SouthEastResizeCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kSouthEastResize));
+ return c;
+}
+
+const ui::Cursor& SouthWestResizeCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kSouthWestResize));
+ return c;
+}
+
+const ui::Cursor& WestResizeCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kWestResize));
+ return c;
+}
+
+const ui::Cursor& NorthSouthResizeCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kNorthSouthResize));
+ return c;
+}
+
+const ui::Cursor& EastWestResizeCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kEastWestResize));
+ return c;
+}
+
+const ui::Cursor& NorthEastSouthWestResizeCursor() {
+ DEFINE_STATIC_LOCAL(
+ ui::Cursor, c, (ui::mojom::blink::CursorType::kNorthEastSouthWestResize));
+ return c;
+}
+
+const ui::Cursor& NorthWestSouthEastResizeCursor() {
+ DEFINE_STATIC_LOCAL(
+ ui::Cursor, c, (ui::mojom::blink::CursorType::kNorthWestSouthEastResize));
+ return c;
+}
+
+const ui::Cursor& ColumnResizeCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kColumnResize));
+ return c;
+}
+
+const ui::Cursor& RowResizeCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kRowResize));
+ return c;
+}
+
+const ui::Cursor& MiddlePanningCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kMiddlePanning));
+ return c;
+}
+
+const ui::Cursor& MiddlePanningVerticalCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kMiddlePanningVertical));
+ return c;
+}
+
+const ui::Cursor& MiddlePanningHorizontalCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kMiddlePanningHorizontal));
+ return c;
+}
+
+const ui::Cursor& EastPanningCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kEastPanning));
+ return c;
+}
+
+const ui::Cursor& NorthPanningCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kNorthPanning));
+ return c;
+}
+
+const ui::Cursor& NorthEastPanningCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kNorthEastPanning));
+ return c;
+}
+
+const ui::Cursor& NorthWestPanningCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kNorthWestPanning));
+ return c;
+}
+
+const ui::Cursor& SouthPanningCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kSouthPanning));
+ return c;
+}
+
+const ui::Cursor& SouthEastPanningCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kSouthEastPanning));
+ return c;
+}
+
+const ui::Cursor& SouthWestPanningCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kSouthWestPanning));
+ return c;
+}
+
+const ui::Cursor& WestPanningCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c,
+ (ui::mojom::blink::CursorType::kWestPanning));
+ return c;
+}
+
+const ui::Cursor& GrabCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c, (ui::mojom::blink::CursorType::kGrab));
+ return c;
+}
+
+const ui::Cursor& GrabbingCursor() {
+ DEFINE_STATIC_LOCAL(ui::Cursor, c, (ui::mojom::blink::CursorType::kGrabbing));
+ return c;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/cursors.h b/chromium/third_party/blink/renderer/platform/cursors.h
new file mode 100644
index 00000000000..8cfba611ec7
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/cursors.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2004, 2006, 2008 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_PLATFORM_CURSORS_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_CURSORS_H_
+
+#include "third_party/blink/renderer/platform/platform_export.h"
+
+// To avoid conflicts with the CreateWindow macro from the Windows SDK...
+#undef CopyCursor
+
+namespace ui {
+class Cursor;
+}
+
+namespace blink {
+
+PLATFORM_EXPORT const ui::Cursor& PointerCursor();
+PLATFORM_EXPORT const ui::Cursor& CrossCursor();
+PLATFORM_EXPORT const ui::Cursor& HandCursor();
+PLATFORM_EXPORT const ui::Cursor& MoveCursor();
+PLATFORM_EXPORT const ui::Cursor& IBeamCursor();
+PLATFORM_EXPORT const ui::Cursor& WaitCursor();
+PLATFORM_EXPORT const ui::Cursor& HelpCursor();
+PLATFORM_EXPORT const ui::Cursor& EastResizeCursor();
+PLATFORM_EXPORT const ui::Cursor& NorthResizeCursor();
+PLATFORM_EXPORT const ui::Cursor& NorthEastResizeCursor();
+PLATFORM_EXPORT const ui::Cursor& NorthWestResizeCursor();
+PLATFORM_EXPORT const ui::Cursor& SouthResizeCursor();
+PLATFORM_EXPORT const ui::Cursor& SouthEastResizeCursor();
+PLATFORM_EXPORT const ui::Cursor& SouthWestResizeCursor();
+PLATFORM_EXPORT const ui::Cursor& WestResizeCursor();
+PLATFORM_EXPORT const ui::Cursor& NorthSouthResizeCursor();
+PLATFORM_EXPORT const ui::Cursor& EastWestResizeCursor();
+PLATFORM_EXPORT const ui::Cursor& NorthEastSouthWestResizeCursor();
+PLATFORM_EXPORT const ui::Cursor& NorthWestSouthEastResizeCursor();
+PLATFORM_EXPORT const ui::Cursor& ColumnResizeCursor();
+PLATFORM_EXPORT const ui::Cursor& RowResizeCursor();
+PLATFORM_EXPORT const ui::Cursor& MiddlePanningCursor();
+PLATFORM_EXPORT const ui::Cursor& MiddlePanningVerticalCursor();
+PLATFORM_EXPORT const ui::Cursor& MiddlePanningHorizontalCursor();
+PLATFORM_EXPORT const ui::Cursor& EastPanningCursor();
+PLATFORM_EXPORT const ui::Cursor& NorthPanningCursor();
+PLATFORM_EXPORT const ui::Cursor& NorthEastPanningCursor();
+PLATFORM_EXPORT const ui::Cursor& NorthWestPanningCursor();
+PLATFORM_EXPORT const ui::Cursor& SouthPanningCursor();
+PLATFORM_EXPORT const ui::Cursor& SouthEastPanningCursor();
+PLATFORM_EXPORT const ui::Cursor& SouthWestPanningCursor();
+PLATFORM_EXPORT const ui::Cursor& WestPanningCursor();
+PLATFORM_EXPORT const ui::Cursor& VerticalTextCursor();
+PLATFORM_EXPORT const ui::Cursor& CellCursor();
+PLATFORM_EXPORT const ui::Cursor& ContextMenuCursor();
+PLATFORM_EXPORT const ui::Cursor& NoDropCursor();
+PLATFORM_EXPORT const ui::Cursor& NotAllowedCursor();
+PLATFORM_EXPORT const ui::Cursor& ProgressCursor();
+PLATFORM_EXPORT const ui::Cursor& AliasCursor();
+PLATFORM_EXPORT const ui::Cursor& ZoomInCursor();
+PLATFORM_EXPORT const ui::Cursor& ZoomOutCursor();
+PLATFORM_EXPORT const ui::Cursor& CopyCursor();
+PLATFORM_EXPORT const ui::Cursor& NoneCursor();
+PLATFORM_EXPORT const ui::Cursor& GrabCursor();
+PLATFORM_EXPORT const ui::Cursor& GrabbingCursor();
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_CURSORS_H_
diff --git a/chromium/third_party/blink/renderer/platform/disk_data_allocator.cc b/chromium/third_party/blink/renderer/platform/disk_data_allocator.cc
new file mode 100644
index 00000000000..2ca595652a0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/disk_data_allocator.cc
@@ -0,0 +1,206 @@
+// 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/disk_data_allocator.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "base/logging.h"
+#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
+#include "third_party/blink/renderer/platform/wtf/wtf.h"
+
+namespace blink {
+
+DiskDataAllocator::DiskDataAllocator()
+ : free_chunks_size_(0), file_tail_(0), may_write_(false) {}
+
+DiskDataAllocator::~DiskDataAllocator() = default;
+
+bool DiskDataAllocator::may_write() {
+ MutexLocker locker(mutex_);
+ return may_write_;
+}
+
+void DiskDataAllocator::set_may_write_for_testing(bool may_write) {
+ MutexLocker locker(mutex_);
+ may_write_ = may_write;
+}
+
+DiskDataAllocator::Metadata DiskDataAllocator::FindChunk(size_t size) {
+ // Try to reuse some space. Policy:
+ // 1. Exact fit
+ // 2. Worst fit
+ Metadata chosen_chunk{-1, 0};
+
+ size_t worst_fit_size = 0;
+ for (const auto& chunk : free_chunks_) {
+ size_t chunk_size = chunk.second;
+ if (size == chunk_size) {
+ chosen_chunk = {chunk.first, chunk.second};
+ break;
+ } else if (chunk_size > size && chunk_size > worst_fit_size) {
+ chosen_chunk = {chunk.first, chunk.second};
+ worst_fit_size = chunk.second;
+ }
+ }
+
+ if (chosen_chunk.start_offset() != -1) {
+ free_chunks_size_ -= size;
+ free_chunks_.erase(chosen_chunk.start_offset());
+ if (chosen_chunk.size() > size) {
+ std::pair<int64_t, size_t> remainder_chunk = {
+ chosen_chunk.start_offset() + size, chosen_chunk.size() - size};
+ auto result = free_chunks_.insert(remainder_chunk);
+ DCHECK(result.second);
+ chosen_chunk.size_ = size;
+ }
+ } else {
+ chosen_chunk = {file_tail_, size};
+ file_tail_ += size;
+ }
+
+ return chosen_chunk;
+}
+
+void DiskDataAllocator::ReleaseChunk(const Metadata& metadata) {
+ Metadata chunk = metadata;
+ DCHECK(free_chunks_.find(chunk.start_offset()) == free_chunks_.end());
+
+ auto lower_bound = free_chunks_.lower_bound(chunk.start_offset());
+ DCHECK(free_chunks_.upper_bound(chunk.start_offset()) ==
+ free_chunks_.lower_bound(chunk.start_offset()));
+ if (lower_bound != free_chunks_.begin()) {
+ // There is a chunk left.
+ auto left = --lower_bound;
+ // Can merge with the left chunk.
+ int64_t left_chunk_end = left->first + left->second;
+ DCHECK_LE(left_chunk_end, chunk.start_offset());
+ if (left_chunk_end == chunk.start_offset()) {
+ chunk = {left->first, left->second + chunk.size()};
+ free_chunks_size_ -= left->second;
+ free_chunks_.erase(left);
+ }
+ }
+
+ auto right = free_chunks_.upper_bound(chunk.start_offset());
+ if (right != free_chunks_.end()) {
+ DCHECK_NE(right->first, chunk.start_offset());
+ int64_t chunk_end = chunk.start_offset() + chunk.size();
+ DCHECK_LE(chunk_end, right->first);
+ if (right->first == chunk_end) {
+ chunk = {chunk.start_offset(), chunk.size() + right->second};
+ free_chunks_size_ -= right->second;
+ free_chunks_.erase(right);
+ }
+ }
+
+ auto result = free_chunks_.insert({chunk.start_offset(), chunk.size()});
+ DCHECK(result.second);
+ free_chunks_size_ += chunk.size();
+}
+
+std::unique_ptr<DiskDataAllocator::Metadata> DiskDataAllocator::Write(
+ const void* data,
+ size_t size) {
+ Metadata chosen_chunk = {0, 0};
+
+ {
+ MutexLocker locker(mutex_);
+ if (!may_write_)
+ return nullptr;
+
+ chosen_chunk = FindChunk(size);
+ } // Don't hold the lock during the actual Write().
+
+ int size_int = static_cast<int>(size);
+ const char* data_char = reinterpret_cast<const char*>(data);
+ int written = DoWrite(chosen_chunk.start_offset(), data_char, size_int);
+
+ MutexLocker locker(mutex_);
+ if (size_int != written) {
+ // Assume that the error is not transient. This can happen if the disk is
+ // full for instance, in which case it is likely better not to try writing
+ // later.
+ may_write_ = false;
+ return nullptr;
+ }
+
+#if DCHECK_IS_ON()
+ allocated_chunks_.insert({chosen_chunk.start_offset(), chosen_chunk.size()});
+#endif
+
+ return std::unique_ptr<Metadata>(
+ new Metadata(chosen_chunk.start_offset(), chosen_chunk.size()));
+}
+
+bool DiskDataAllocator::Read(const Metadata& metadata, void* data) {
+ DCHECK(IsMainThread());
+
+ // Doesn't need locking as files support concurrent access, and we don't
+ // update metadata.
+ char* data_char = reinterpret_cast<char*>(data);
+ DoRead(metadata.start_offset(), data_char, metadata.size());
+
+#if DCHECK_IS_ON()
+ {
+ MutexLocker locker(mutex_);
+ auto it = allocated_chunks_.find(metadata.start_offset());
+ DCHECK(it != allocated_chunks_.end());
+ DCHECK_EQ(metadata.size(), it->second);
+ }
+#endif
+
+ return true;
+}
+
+void DiskDataAllocator::Discard(std::unique_ptr<Metadata> metadata) {
+ MutexLocker locker(mutex_);
+ DCHECK(may_write_ || file_.IsValid());
+
+#if DCHECK_IS_ON()
+ auto it = allocated_chunks_.find(metadata->start_offset());
+ DCHECK(it != allocated_chunks_.end());
+ DCHECK_EQ(metadata->size(), it->second);
+ allocated_chunks_.erase(it);
+#endif
+
+ ReleaseChunk(*metadata);
+}
+
+int DiskDataAllocator::DoWrite(int64_t offset, const char* data, int size) {
+ int rv = file_.Write(offset, data, size);
+
+ // No PCHECK(), since a file writing error is recoverable.
+ if (rv != size) {
+ LOG(ERROR) << "DISK: Cannot write to disk. written = " << rv << " "
+ << base::File::ErrorToString(base::File::GetLastFileError());
+ }
+ return rv;
+}
+
+void DiskDataAllocator::DoRead(int64_t offset, char* data, int size) {
+ int rv = file_.Read(offset, data, size);
+ // Can only crash, since we cannot continue without the data.
+ PCHECK(rv == size) << "Likely file corruption.";
+}
+
+void DiskDataAllocator::ProvideTemporaryFile(base::File file) {
+ MutexLocker locker(mutex_);
+ DCHECK(IsMainThread());
+ DCHECK(!file_.IsValid());
+ DCHECK(!may_write_);
+
+ file_ = std::move(file);
+ if (file_.IsValid())
+ may_write_ = true;
+}
+
+// static
+DiskDataAllocator& DiskDataAllocator::Instance() {
+ DEFINE_STATIC_LOCAL(DiskDataAllocator, instance, ());
+ return instance;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/disk_data_allocator.h b/chromium/third_party/blink/renderer/platform/disk_data_allocator.h
new file mode 100644
index 00000000000..5c53a04738e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/disk_data_allocator.h
@@ -0,0 +1,116 @@
+// 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_DISK_DATA_ALLOCATOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_DISK_DATA_ALLOCATOR_H_
+
+#include <map>
+#include <memory>
+
+#include "base/files/file.h"
+#include "base/synchronization/lock.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/threading.h"
+#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
+
+namespace blink {
+
+// Stores data onto a single file.
+//
+// The file is provided after construction. As a consequence, the allocator
+// initially does not accept writes, that is |Write()| returns nullptr. It may
+// also become not usable later, for instance if disk space is no longer
+// available.
+//
+// Threading:
+// - Reads must be done from the main thread
+// - Writes can be done from any thread.
+// - public methods are thread-safe, and unless otherwise noted, can be called
+// from any thread.
+class PLATFORM_EXPORT DiskDataAllocator {
+ public:
+ class Metadata {
+ public:
+ int64_t start_offset() const { return start_offset_; }
+ size_t size() const { return size_; }
+ Metadata(Metadata&& other) = delete;
+
+ private:
+ Metadata(int64_t start_offset, size_t size)
+ : start_offset_(start_offset), size_(size) {}
+ Metadata(const Metadata& other) = default;
+ Metadata& operator=(const Metadata& other) = default;
+
+ int64_t start_offset_;
+ size_t size_;
+
+ friend class DiskDataAllocator;
+ };
+
+ // Must be called on the main thread.
+ void ProvideTemporaryFile(::base::File file);
+
+ // Whether writes may succeed. This is not a guarantee. However, when this
+ // returns false, writes will fail.
+ bool may_write() LOCKS_EXCLUDED(mutex_);
+
+ // Returns |nullptr| in case of error.
+ // Note that this performs a blocking disk write.
+ std::unique_ptr<Metadata> Write(const void* data, size_t size);
+
+ // Returns |false| in case of error.
+ // Must be called from the main thread.
+ // Can be called at any time before |Discard()| destroys |metadata|.
+ //
+ // |data| must point to an area large enough to fit a |metadata.size|-ed
+ // array. Note that this performs a blocking disk read.
+ bool Read(const Metadata& metadata, void* data);
+
+ // Discards existing data pointed at by |metadata|.
+ void Discard(std::unique_ptr<Metadata> metadata);
+
+ virtual ~DiskDataAllocator();
+ static DiskDataAllocator& Instance();
+
+ protected:
+ // Protected methods for testing.
+ DiskDataAllocator();
+ void set_may_write_for_testing(bool may_write) LOCKS_EXCLUDED(mutex_);
+
+ private:
+ Metadata FindChunk(size_t size) EXCLUSIVE_LOCKS_REQUIRED(mutex_);
+ void ReleaseChunk(const Metadata& metadata) EXCLUSIVE_LOCKS_REQUIRED(mutex_);
+
+ // Virtual for testing.
+ virtual int DoWrite(int64_t offset, const char* data, int size)
+ LOCKS_EXCLUDED(mutex_);
+ // CHECK()s that the read is successful.
+ virtual void DoRead(int64_t offset, char* data, int size);
+
+ base::File file_; // May be invalid.
+
+ protected: // For testing.
+ Mutex mutex_;
+ // Using a std::map because we rely on |{lower,upper}_bound()|.
+ std::map<int64_t, size_t> free_chunks_ GUARDED_BY(mutex_);
+ size_t free_chunks_size_ GUARDED_BY(mutex_);
+
+ private:
+ int64_t file_tail_ GUARDED_BY(mutex_);
+ // Whether writing is possible now. This can be true if:
+ // - |set_may_write_for_testing()| was called, or
+ // - |file_.IsValid()| and no write error occurred (which would set
+ // |may_write_| to false).
+ bool may_write_ GUARDED_BY(mutex_);
+#if DCHECK_IS_ON()
+ std::map<int64_t, size_t> allocated_chunks_ GUARDED_BY(mutex_);
+#endif
+
+ FRIEND_TEST_ALL_PREFIXES(DiskDataAllocatorTest, ProvideInvalidFile);
+ FRIEND_TEST_ALL_PREFIXES(DiskDataAllocatorTest, ProvideValidFile);
+};
+
+} // namespace blink
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_DISK_DATA_ALLOCATOR_H_
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
new file mode 100644
index 00000000000..b1ac3b51e4e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/disk_data_allocator_test.cc
@@ -0,0 +1,266 @@
+// 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/disk_data_allocator.h"
+
+#include <cstring>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/files/file.h"
+#include "base/files/file_util.h"
+#include "base/rand_util.h"
+#include "base/test/task_environment.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/disk_data_allocator_test_utils.h"
+
+using ThreadPoolExecutionMode =
+ base::test::TaskEnvironment::ThreadPoolExecutionMode;
+
+namespace blink {
+
+class DiskDataAllocatorTest : public ::testing::Test {
+ public:
+ explicit DiskDataAllocatorTest(
+ ThreadPoolExecutionMode thread_pool_execution_mode =
+ ThreadPoolExecutionMode::DEFAULT)
+ : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME,
+ thread_pool_execution_mode) {}
+
+ static std::vector<std::unique_ptr<DiskDataAllocator::Metadata>>
+ Allocate(InMemoryDataAllocator* allocator, size_t size, size_t count) {
+ std::string random_data = base::RandBytesAsString(size);
+
+ std::vector<std::unique_ptr<DiskDataAllocator::Metadata>> all_metadata;
+ for (size_t i = 0; i < count; i++) {
+ auto metadata = allocator->Write(random_data.c_str(), random_data.size());
+ EXPECT_EQ(metadata->start_offset(), static_cast<int64_t>(i * size));
+ all_metadata.push_back(std::move(metadata));
+ }
+ return all_metadata;
+ }
+
+ protected:
+ base::test::TaskEnvironment task_environment_;
+};
+
+TEST_F(DiskDataAllocatorTest, ReadWrite) {
+ InMemoryDataAllocator allocator;
+
+ constexpr size_t kSize = 1000;
+ std::string random_data = base::RandBytesAsString(kSize);
+ auto metadata = allocator.Write(random_data.c_str(), random_data.size());
+ EXPECT_TRUE(metadata);
+ EXPECT_EQ(kSize, metadata->size());
+
+ auto read_data = std::vector<char>(kSize);
+ bool ok = allocator.Read(*metadata, &read_data[0]);
+ EXPECT_TRUE(ok);
+
+ EXPECT_EQ(0, memcmp(&read_data[0], random_data.c_str(), kSize));
+}
+
+TEST_F(DiskDataAllocatorTest, ReadWriteDiscardMultiple) {
+ InMemoryDataAllocator allocator;
+
+ std::vector<
+ std::pair<std::unique_ptr<DiskDataAllocator::Metadata>, std::string>>
+ data_written;
+
+ for (int i = 0; i < 10; i++) {
+ int size = base::RandInt(100, 1000);
+ auto data = base::RandBytesAsString(size);
+ auto metadata = allocator.Write(&data[0], size);
+ ASSERT_TRUE(metadata);
+ data_written.emplace_back(std::move(metadata), data);
+ }
+
+ base::RandomShuffle(data_written.begin(), data_written.end());
+
+ for (const auto& p : data_written) {
+ size_t size = p.first->size();
+ auto read_data = std::vector<char>(size);
+ bool ok = allocator.Read(*p.first, &read_data[0]);
+ EXPECT_TRUE(ok);
+
+ EXPECT_EQ(0, memcmp(&read_data[0], &p.second[0], size));
+ }
+
+ base::RandomShuffle(data_written.begin(), data_written.end());
+
+ for (auto& p : data_written) {
+ auto metadata = std::move(p.first);
+ allocator.Discard(std::move(metadata));
+ }
+}
+
+TEST_F(DiskDataAllocatorTest, WriteEventuallyFail) {
+ InMemoryDataAllocator allocator;
+
+ constexpr size_t kSize = 1 << 18;
+ std::string random_data = base::RandBytesAsString(kSize);
+
+ static_assert(4 * kSize == InMemoryDataAllocator::kMaxSize, "");
+ for (int i = 0; i < 4; i++) {
+ auto metadata = allocator.Write(random_data.c_str(), random_data.size());
+ EXPECT_TRUE(metadata);
+ }
+ auto metadata = allocator.Write(random_data.c_str(), random_data.size());
+ EXPECT_FALSE(metadata);
+ EXPECT_FALSE(allocator.may_write());
+}
+
+TEST_F(DiskDataAllocatorTest, CanReuseFreedChunk) {
+ InMemoryDataAllocator allocator;
+
+ constexpr size_t kSize = 1 << 10;
+ std::vector<std::unique_ptr<DiskDataAllocator::Metadata>> all_metadata;
+
+ for (int i = 0; i < 10; i++) {
+ std::string random_data = base::RandBytesAsString(kSize);
+ auto metadata = allocator.Write(random_data.c_str(), random_data.size());
+ ASSERT_TRUE(metadata);
+ all_metadata.push_back(std::move(metadata));
+ }
+
+ auto metadata = std::move(all_metadata[4]);
+ ASSERT_TRUE(metadata);
+ int64_t start_offset = metadata->start_offset();
+ allocator.Discard(std::move(metadata));
+
+ std::string random_data = base::RandBytesAsString(kSize);
+ auto new_metadata = allocator.Write(random_data.c_str(), random_data.size());
+ ASSERT_TRUE(new_metadata);
+ EXPECT_EQ(new_metadata->start_offset(), start_offset);
+}
+
+TEST_F(DiskDataAllocatorTest, ExactThenWorstFit) {
+ InMemoryDataAllocator allocator;
+
+ int count = 10;
+ size_t size_increment = 1000;
+ std::vector<std::unique_ptr<DiskDataAllocator::Metadata>> all_metadata;
+
+ size_t size = 10000;
+ // Allocate a bunch of random-sized
+ for (int i = 0; i < count; i++) {
+ std::string random_data = base::RandBytesAsString(size);
+ auto metadata = allocator.Write(random_data.c_str(), random_data.size());
+ ASSERT_TRUE(metadata);
+ all_metadata.push_back(std::move(metadata));
+ size += size_increment;
+ }
+
+ auto& hole_metadata = all_metadata[4];
+ size_t hole_size = hole_metadata->size();
+ int64_t hole_offset = hole_metadata->start_offset();
+ allocator.Discard(std::move(hole_metadata));
+
+ auto& larger_hole_metadata = all_metadata[9];
+ int64_t larger_hole_offset = larger_hole_metadata->start_offset();
+ allocator.Discard(std::move(larger_hole_metadata));
+
+ std::string random_data = base::RandBytesAsString(hole_size);
+ auto metadata = allocator.Write(random_data.c_str(), random_data.size());
+ // Exact fit.
+ EXPECT_EQ(metadata->start_offset(), hole_offset);
+ allocator.Discard(std::move(metadata));
+
+ // -1 to check that this is not best fit.
+ random_data = base::RandBytesAsString(hole_size - 1);
+ metadata = allocator.Write(random_data.c_str(), random_data.size());
+ EXPECT_EQ(metadata->start_offset(), larger_hole_offset);
+}
+
+TEST_F(DiskDataAllocatorTest, FreeChunksMerging) {
+ constexpr size_t kSize = 100;
+
+ auto allocator = std::make_unique<InMemoryDataAllocator>();
+ auto chunks = Allocate(allocator.get(), kSize, 4);
+
+ // Layout is (indices in |chunks|):
+ // | 0 | 1 | 2 | 3 |
+ // Discarding a higher index after a lower one triggers merging on the left.
+
+ // Merge left.
+ allocator->Discard(std::move(chunks[0]));
+ EXPECT_EQ(1u, allocator->FreeChunks().size());
+ allocator->Discard(std::move(chunks[1]));
+ EXPECT_EQ(1u, allocator->FreeChunks().size());
+ EXPECT_EQ(2 * kSize, allocator->FreeChunks().begin()->second);
+ allocator->Discard(std::move(chunks[2]));
+ EXPECT_EQ(1u, allocator->FreeChunks().size());
+ EXPECT_EQ(3 * kSize, allocator->FreeChunks().begin()->second);
+ allocator->Discard(std::move(chunks[3]));
+ EXPECT_EQ(1u, allocator->FreeChunks().size());
+ EXPECT_EQ(4 * kSize, allocator->FreeChunks().begin()->second);
+
+ allocator = std::make_unique<InMemoryDataAllocator>();
+ chunks = Allocate(allocator.get(), kSize, 4);
+
+ // Merge right.
+ allocator->Discard(std::move(chunks[3]));
+ EXPECT_EQ(1u, allocator->FreeChunks().size());
+ allocator->Discard(std::move(chunks[2]));
+ EXPECT_EQ(1u, allocator->FreeChunks().size());
+ EXPECT_EQ(2 * kSize, allocator->FreeChunks().begin()->second);
+ allocator->Discard(std::move(chunks[0]));
+ EXPECT_EQ(2u, allocator->FreeChunks().size());
+ // Multiple merges: left, then right.
+ allocator->Discard(std::move(chunks[1]));
+ EXPECT_EQ(1u, allocator->FreeChunks().size());
+
+ allocator = std::make_unique<InMemoryDataAllocator>();
+ chunks = Allocate(allocator.get(), kSize, 4);
+
+ // Left then right merging.
+ allocator->Discard(std::move(chunks[0]));
+ allocator->Discard(std::move(chunks[2]));
+ EXPECT_EQ(2u, allocator->FreeChunks().size());
+ allocator->Discard(std::move(chunks[1]));
+ EXPECT_EQ(1u, allocator->FreeChunks().size());
+}
+
+TEST_F(DiskDataAllocatorTest, ProvideInvalidFile) {
+ DiskDataAllocator allocator;
+ EXPECT_FALSE(allocator.may_write());
+ allocator.ProvideTemporaryFile(base::File());
+ EXPECT_FALSE(allocator.may_write());
+}
+
+TEST_F(DiskDataAllocatorTest, ProvideValidFile) {
+ base::FilePath path;
+ if (!base::CreateTemporaryFile(&path))
+ GTEST_SKIP() << "Cannot create temporary file.";
+
+ int flags = base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_READ |
+ base::File::FLAG_WRITE | base::File::FLAG_DELETE_ON_CLOSE;
+ auto file = base::File(base::FilePath(path), flags);
+ if (!file.IsValid())
+ GTEST_SKIP() << "Cannot create temporary file.";
+
+ DiskDataAllocator allocator;
+ EXPECT_FALSE(allocator.may_write());
+ allocator.ProvideTemporaryFile(std::move(file));
+ EXPECT_TRUE(allocator.may_write());
+
+ // Test read/write with a real file.
+ constexpr size_t kSize = 1000;
+ std::string random_data = base::RandBytesAsString(kSize);
+ auto metadata = allocator.Write(random_data.c_str(), random_data.size());
+ if (!metadata)
+ GTEST_SKIP() << "Disk full?";
+
+ EXPECT_EQ(kSize, metadata->size());
+
+ auto read_data = std::vector<char>(kSize);
+ bool ok = allocator.Read(*metadata, &read_data[0]);
+ EXPECT_TRUE(ok);
+
+ EXPECT_EQ(0, memcmp(&read_data[0], random_data.c_str(), kSize));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/disk_data_allocator_test_utils.h b/chromium/third_party/blink/renderer/platform/disk_data_allocator_test_utils.h
new file mode 100644
index 00000000000..4c7bb2f37da
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/disk_data_allocator_test_utils.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_DISK_DATA_ALLOCATOR_TEST_UTILS_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_DISK_DATA_ALLOCATOR_TEST_UTILS_H_
+
+#include "third_party/blink/renderer/platform/disk_data_allocator.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <cstring>
+#include <map>
+#include <vector>
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace blink {
+
+class InMemoryDataAllocator : public DiskDataAllocator {
+ public:
+ constexpr static size_t kMaxSize = 1 << 20;
+
+ InMemoryDataAllocator() : max_offset_(0), data_(kMaxSize) {
+ set_may_write_for_testing(true);
+ }
+ ~InMemoryDataAllocator() override = default;
+
+ std::map<int64_t, size_t> FreeChunks() {
+ MutexLocker locker(mutex_);
+
+ size_t free_size = 0;
+ for (const auto& p : free_chunks_)
+ free_size += p.second;
+
+ EXPECT_EQ(free_size, free_chunks_size_);
+
+ return free_chunks_;
+ }
+
+ private:
+ int DoWrite(int64_t offset, const char* data, int size) override {
+ int64_t end_offset = offset + size;
+ if (static_cast<size_t>(end_offset) > kMaxSize)
+ return -1;
+
+ memcpy(&data_[0] + offset, data, size);
+ max_offset_ = std::max(end_offset, max_offset_);
+ return size;
+ }
+
+ void DoRead(int64_t offset, char* data, int size) override {
+ int64_t end_offset = offset + size;
+ ASSERT_LE(end_offset, max_offset_);
+
+ memcpy(data, &data_[0] + offset, size);
+ }
+
+ private:
+ int64_t max_offset_;
+ std::vector<char> data_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_DISK_DATA_ALLOCATOR_TEST_UTILS_H_
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 25770c1e020..be409773273 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(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/OWNERS b/chromium/third_party/blink/renderer/platform/exported/OWNERS
index 9a717779420..f80e768428d 100644
--- a/chromium/third_party/blink/renderer/platform/exported/OWNERS
+++ b/chromium/third_party/blink/renderer/platform/exported/OWNERS
@@ -1,2 +1,7 @@
per-file notification_data_conversions*=peter@chromium.org
per-file web_rtc_*=hbos@chromium.org
+
+# Any core owner can also approve changes to runtime-enabled features.
+# Please make sure to get a review from someone with expertise on the feature
+# you are changing.
+per-file web_runtime_features*=file://third_party/blink/renderer/core/OWNERS
diff --git a/chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_test.cc b/chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_test.cc
index c5825eed5ef..e6c83416711 100644
--- a/chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_test.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_test.cc
@@ -13,12 +13,12 @@
#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/modules/mediastream/media_stream_audio_track.h"
#include "third_party/blink/public/platform/modules/mediastream/web_media_stream_audio_sink.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_audio_track.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/exported/platform.cc b/chromium/third_party/blink/renderer/platform/exported/platform.cc
index 55f9e8146b7..d498e7d31b7 100644
--- a/chromium/third_party/blink/renderer/platform/exported/platform.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/platform.cc
@@ -38,13 +38,11 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/memory_dump_manager.h"
#include "build/build_config.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
-#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
-#include "third_party/blink/public/platform/web_prerendering_support.h"
#include "third_party/blink/public/platform/websocket_handshake_throttle.h"
+#include "third_party/blink/renderer/platform/bindings/blink_isolate/blink_isolate.h"
#include "third_party/blink/renderer/platform/bindings/parkable_string_manager.h"
#include "third_party/blink/renderer/platform/font_family_names.h"
#include "third_party/blink/renderer/platform/fonts/font_cache_memory_dump_provider.h"
@@ -69,22 +67,6 @@ namespace blink {
namespace {
-class DefaultInterfaceProvider : public InterfaceProvider {
- USING_FAST_MALLOC(DefaultInterfaceProvider);
-
- public:
- DefaultInterfaceProvider() = default;
- ~DefaultInterfaceProvider() = default;
-
- // InterfaceProvider implementation:
- void GetInterface(const char* interface_name,
- mojo::ScopedMessagePipeHandle interface_pipe) override {
- Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
- mojo::GenericPendingReceiver(interface_name,
- std::move(interface_pipe)));
- }
-};
-
class DefaultBrowserInterfaceBrokerProxy
: public ThreadSafeBrowserInterfaceBrokerProxy {
USING_FAST_MALLOC(DefaultBrowserInterfaceBrokerProxy);
@@ -140,13 +122,6 @@ static Platform* g_platform = nullptr;
static GCTaskRunner* g_gc_task_runner = nullptr;
-static void CallOnMainThreadFunction(WTF::MainThreadFunction function,
- void* context) {
- PostCrossThreadTask(
- *Thread::MainThread()->GetTaskRunner(), FROM_HERE,
- CrossThreadBindOnce(function, CrossThreadUnretained(context)));
-}
-
Platform::Platform() {
WTF::Partitions::Initialize();
}
@@ -157,6 +132,8 @@ namespace {
class SimpleMainThread : public Thread {
public:
+ SimpleMainThread() : isolate_(WebIsolate::Create()) {}
+
// We rely on base::ThreadTaskRunnerHandle for tasks posted on the main
// thread. The task runner handle may not be available on Blink's startup
// (== on SimpleMainThread's construction), because some tests like
@@ -190,6 +167,7 @@ class SimpleMainThread : public Thread {
private:
bool IsSimpleMainThread() const override { return true; }
+ std::unique_ptr<WebIsolate> isolate_;
scheduler::SimpleThreadScheduler scheduler_;
scoped_refptr<base::SingleThreadTaskRunner>
main_thread_task_runner_for_testing_;
@@ -215,7 +193,7 @@ void Platform::CreateMainThreadAndInitialize(Platform* platform) {
void Platform::InitializeCommon(Platform* platform,
std::unique_ptr<Thread> main_thread) {
- WTF::Initialize(CallOnMainThreadFunction);
+ WTF::Initialize();
Thread::SetMainThread(std::move(main_thread));
@@ -287,11 +265,6 @@ Platform* Platform::Current() {
return g_platform;
}
-InterfaceProvider* Platform::GetInterfaceProvider() {
- DEFINE_STATIC_LOCAL(DefaultInterfaceProvider, provider, ());
- return &provider;
-}
-
ThreadSafeBrowserInterfaceBrokerProxy* Platform::GetBrowserInterfaceBroker() {
DEFINE_STATIC_LOCAL(DefaultBrowserInterfaceBrokerProxy, proxy, ());
return &proxy;
diff --git a/chromium/third_party/blink/renderer/platform/exported/url_conversion.cc b/chromium/third_party/blink/renderer/platform/exported/url_conversion.cc
index 5980f067a4a..4b149343d90 100644
--- a/chromium/third_party/blink/renderer/platform/exported/url_conversion.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/url_conversion.cc
@@ -5,7 +5,6 @@
#include "third_party/blink/public/platform/url_conversion.h"
#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/renderer/platform/blob/blob_data.h"
#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "url/gurl.h"
@@ -27,15 +26,4 @@ GURL WebStringToGURL(const WebString& web_string) {
return GURL(base::StringPiece16(str.Characters16(), str.length()));
}
-mojo::ScopedMessagePipeHandle DataURLToMessagePipeHandle(
- const WebString& data_url) {
- auto blob_data = std::make_unique<blink::BlobData>();
- blob_data->AppendBytes(data_url.Utf8().data(), data_url.length());
- scoped_refptr<blink::BlobDataHandle> blob_data_handle =
- blink::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();
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/video_capture/web_video_capture_impl_manager_test.cc b/chromium/third_party/blink/renderer/platform/exported/video_capture/web_video_capture_impl_manager_test.cc
index 3c104d77bf2..ecaddbf977b 100644
--- a/chromium/third_party/blink/renderer/platform/exported/video_capture/web_video_capture_impl_manager_test.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/video_capture/web_video_capture_impl_manager_test.cc
@@ -10,6 +10,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
+#include "base/test/gmock_callback_support.h"
#include "base/test/task_environment.h"
#include "media/base/bind_to_current_loop.h"
#include "media/capture/mojom/video_capture.mojom-blink.h"
@@ -21,6 +22,7 @@
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
+using base::test::RunOnceClosure;
using media::BindToCurrentLoop;
using ::testing::_;
using ::testing::DoAll;
@@ -29,10 +31,6 @@ using ::testing::SaveArg;
namespace blink {
-ACTION_P(RunClosure, closure) {
- closure.Run();
-}
-
namespace {
// Callback interface to be implemented by VideoCaptureImplManagerTest.
@@ -166,7 +164,7 @@ class VideoCaptureImplManagerTest : public ::testing::Test,
.RetiresOnSaturation();
}
EXPECT_CALL(*this, OnStarted(_))
- .WillOnce(RunClosure(std::move(quit_closure)))
+ .WillOnce(RunOnceClosure(std::move(quit_closure)))
.RetiresOnSaturation();
std::array<base::OnceClosure, kNumClients> stop_callbacks;
media::VideoCaptureParams params;
@@ -189,7 +187,7 @@ class VideoCaptureImplManagerTest : public ::testing::Test,
.Times(kNumClients - 1)
.RetiresOnSaturation();
EXPECT_CALL(*this, OnStopped(_))
- .WillOnce(RunClosure(std::move(quit_closure)))
+ .WillOnce(RunOnceClosure(std::move(quit_closure)))
.RetiresOnSaturation();
for (auto& stop_callback : *stop_callbacks)
std::move(stop_callback).Run();
@@ -281,7 +279,7 @@ TEST_F(VideoCaptureImplManagerTest, SuspendAndResumeSessions) {
.Times(1)
.RetiresOnSaturation();
EXPECT_CALL(*this, OnPaused(session_ids_[2]))
- .WillOnce(RunClosure(std::move(quit_closure)))
+ .WillOnce(RunOnceClosure(std::move(quit_closure)))
.RetiresOnSaturation();
manager_->SuspendDevices(video_devices, true);
run_loop.Run();
@@ -299,7 +297,7 @@ TEST_F(VideoCaptureImplManagerTest, SuspendAndResumeSessions) {
.Times(1)
.RetiresOnSaturation();
EXPECT_CALL(*this, OnResumed(session_ids_[2]))
- .WillOnce(RunClosure(std::move(quit_closure)))
+ .WillOnce(RunOnceClosure(std::move(quit_closure)))
.RetiresOnSaturation();
manager_->SuspendDevices(video_devices, false);
run_loop.Run();
@@ -312,7 +310,7 @@ TEST_F(VideoCaptureImplManagerTest, SuspendAndResumeSessions) {
base::RepeatingClosure quit_closure =
BindToCurrentLoop(run_loop.QuitClosure());
EXPECT_CALL(*this, OnPaused(session_ids_[0]))
- .WillOnce(RunClosure(std::move(quit_closure)))
+ .WillOnce(RunOnceClosure(std::move(quit_closure)))
.RetiresOnSaturation();
manager_->Suspend(session_ids_[0]);
run_loop.Run();
@@ -328,7 +326,7 @@ TEST_F(VideoCaptureImplManagerTest, SuspendAndResumeSessions) {
.Times(1)
.RetiresOnSaturation();
EXPECT_CALL(*this, OnPaused(session_ids_[2]))
- .WillOnce(RunClosure(std::move(quit_closure)))
+ .WillOnce(RunOnceClosure(std::move(quit_closure)))
.RetiresOnSaturation();
manager_->SuspendDevices(video_devices, true);
run_loop.Run();
@@ -353,7 +351,7 @@ TEST_F(VideoCaptureImplManagerTest, SuspendAndResumeSessions) {
.Times(1)
.RetiresOnSaturation();
EXPECT_CALL(*this, OnResumed(session_ids_[2]))
- .WillOnce(RunClosure(std::move(quit_closure)))
+ .WillOnce(RunOnceClosure(std::move(quit_closure)))
.RetiresOnSaturation();
manager_->SuspendDevices(video_devices, false);
run_loop.Run();
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 b6d911afba9..28d5befee6e 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
@@ -23,7 +23,6 @@ WebBlobInfo::WebBlobInfo(const WebString& uuid,
mojom::blink::Blob::Version_))) {}
WebBlobInfo::WebBlobInfo(const WebString& uuid,
- const WebString& file_path,
const WebString& file_name,
const WebString& type,
const base::Optional<base::Time>& last_modified,
@@ -36,7 +35,6 @@ WebBlobInfo::WebBlobInfo(const WebString& uuid,
mojo::PendingRemote<mojom::blink::Blob>(
std::move(handle),
mojom::blink::Blob::Version_)),
- file_path,
file_name,
last_modified) {}
@@ -49,10 +47,9 @@ WebBlobInfo WebBlobInfo::BlobForTesting(const WebString& uuid,
// static
WebBlobInfo WebBlobInfo::FileForTesting(const WebString& uuid,
- const WebString& file_path,
const WebString& file_name,
const WebString& type) {
- return WebBlobInfo(uuid, file_path, file_name, type, base::nullopt,
+ return WebBlobInfo(uuid, file_name, type, base::nullopt,
std::numeric_limits<uint64_t>::max(),
mojo::MessagePipe().handle0);
}
@@ -77,11 +74,9 @@ WebBlobInfo::WebBlobInfo(scoped_refptr<BlobDataHandle> handle)
: WebBlobInfo(handle, handle->GetType(), handle->size()) {}
WebBlobInfo::WebBlobInfo(scoped_refptr<BlobDataHandle> handle,
- const WebString& file_path,
const WebString& file_name,
const base::Optional<base::Time>& last_modified)
: WebBlobInfo(handle,
- file_path,
file_name,
handle->GetType(),
last_modified,
@@ -97,7 +92,6 @@ WebBlobInfo::WebBlobInfo(scoped_refptr<BlobDataHandle> handle,
blob_handle_(std::move(handle)) {}
WebBlobInfo::WebBlobInfo(scoped_refptr<BlobDataHandle> handle,
- const WebString& file_path,
const WebString& file_name,
const WebString& type,
const base::Optional<base::Time>& last_modified,
@@ -107,7 +101,6 @@ WebBlobInfo::WebBlobInfo(scoped_refptr<BlobDataHandle> handle,
type_(type),
size_(size),
blob_handle_(std::move(handle)),
- file_path_(file_path),
file_name_(file_name),
last_modified_(last_modified) {}
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_coalesced_input_event.cc b/chromium/third_party/blink/renderer/platform/exported/web_coalesced_input_event.cc
index 807a31c6a34..21edc5fe307 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_coalesced_input_event.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_coalesced_input_event.cc
@@ -4,54 +4,14 @@
#include "third_party/blink/public/platform/web_coalesced_input_event.h"
-#include "third_party/blink/public/platform/web_gesture_event.h"
-#include "third_party/blink/public/platform/web_keyboard_event.h"
-#include "third_party/blink/public/platform/web_mouse_wheel_event.h"
-#include "third_party/blink/public/platform/web_pointer_event.h"
-#include "third_party/blink/public/platform/web_touch_event.h"
+#include "third_party/blink/public/common/input/web_gesture_event.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"
namespace blink {
-namespace {
-
-struct WebInputEventDelete {
- template <class EventType>
- bool Execute(WebInputEvent* event) const {
- if (!event)
- return false;
- DCHECK_EQ(sizeof(EventType), event->size());
- delete static_cast<EventType*>(event);
- return true;
- }
-};
-
-template <typename Operator, typename ArgIn>
-bool Apply(Operator op, WebInputEvent::Type type, const ArgIn& arg_in) {
- if (WebInputEvent::IsMouseEventType(type))
- return op.template Execute<WebMouseEvent>(arg_in);
- if (type == WebInputEvent::kMouseWheel)
- return op.template Execute<WebMouseWheelEvent>(arg_in);
- if (WebInputEvent::IsKeyboardEventType(type))
- return op.template Execute<WebKeyboardEvent>(arg_in);
- if (WebInputEvent::IsTouchEventType(type))
- return op.template Execute<WebTouchEvent>(arg_in);
- if (WebInputEvent::IsGestureEventType(type))
- return op.template Execute<WebGestureEvent>(arg_in);
- if (WebInputEvent::IsPointerEventType(type))
- return op.template Execute<WebPointerEvent>(arg_in);
-
- NOTREACHED() << "Unknown webkit event type " << type;
- return false;
-}
-}
-
-void WebCoalescedInputEvent::WebInputEventDeleter::operator()(
- WebInputEvent* event) const {
- if (!event)
- return;
- Apply(WebInputEventDelete(), event->GetType(), event);
-}
-
WebInputEvent* WebCoalescedInputEvent::EventPointer() {
return event_.get();
}
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_crypto_algorithm.cc b/chromium/third_party/blink/renderer/platform/exported/web_crypto_algorithm.cc
index 67b793f5ca1..1628116da5b 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_crypto_algorithm.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_crypto_algorithm.cc
@@ -286,6 +286,40 @@ constexpr WebCryptoAlgorithmInfo kAlgorithmIdToInfo[] = {
WebCryptoAlgorithmInfo::kUndefined, // WrapKey
WebCryptoAlgorithmInfo::kUndefined // UnwrapKey
}},
+ {// Index 16
+ // TODO(crbug.com/1032821): Ed25519 is experimental behind a flag. See
+ // https://chromestatus.com/feature/4913922408710144 for the status.
+ "ED25519",
+ {
+ WebCryptoAlgorithmInfo::kUndefined, // Encrypt
+ WebCryptoAlgorithmInfo::kUndefined, // Decrypt
+ kWebCryptoAlgorithmParamsTypeEd25519Params, // Sign
+ kWebCryptoAlgorithmParamsTypeEd25519Params, // Verify
+ WebCryptoAlgorithmInfo::kUndefined, // Digest
+ kWebCryptoAlgorithmParamsTypeNone, // GenerateKey
+ kWebCryptoAlgorithmParamsTypeNone, // ImportKey
+ WebCryptoAlgorithmInfo::kUndefined, // GetKeyLength
+ WebCryptoAlgorithmInfo::kUndefined, // DeriveBits
+ WebCryptoAlgorithmInfo::kUndefined, // WrapKey
+ WebCryptoAlgorithmInfo::kUndefined // UnwrapKey
+ }},
+ {// Index 17
+ // TODO(crbug.com/1032821): X25519 is experimental behind a flag. See
+ // https://chromestatus.com/feature/4913922408710144 for the status.
+ "X25519",
+ {
+ WebCryptoAlgorithmInfo::kUndefined, // Encrypt
+ WebCryptoAlgorithmInfo::kUndefined, // Decrypt
+ WebCryptoAlgorithmInfo::kUndefined, // Sign
+ WebCryptoAlgorithmInfo::kUndefined, // Verify
+ WebCryptoAlgorithmInfo::kUndefined, // Digest
+ kWebCryptoAlgorithmParamsTypeNone, // GenerateKey
+ kWebCryptoAlgorithmParamsTypeNone, // ImportKey
+ WebCryptoAlgorithmInfo::kUndefined, // GetKeyLength
+ kWebCryptoAlgorithmParamsTypeX25519KeyDeriveParams, // DeriveBits
+ WebCryptoAlgorithmInfo::kUndefined, // WrapKey
+ WebCryptoAlgorithmInfo::kUndefined // UnwrapKey
+ }},
};
// Initializing the algorithmIdToInfo table above depends on knowing the enum
@@ -308,7 +342,9 @@ static_assert(kWebCryptoAlgorithmIdEcdsa == 12, "ECDSA id must match");
static_assert(kWebCryptoAlgorithmIdEcdh == 13, "ECDH id must match");
static_assert(kWebCryptoAlgorithmIdHkdf == 14, "HKDF id must match");
static_assert(kWebCryptoAlgorithmIdPbkdf2 == 15, "Pbkdf2 id must match");
-static_assert(kWebCryptoAlgorithmIdLast == 15, "last id must match");
+static_assert(kWebCryptoAlgorithmIdEd25519 == 16, "X25519 id must match");
+static_assert(kWebCryptoAlgorithmIdX25519 == 17, "Ed25519 id must match");
+static_assert(kWebCryptoAlgorithmIdLast == 17, "last id must match");
static_assert(10 == kWebCryptoOperationLast,
"the parameter mapping needs to be updated");
@@ -489,6 +525,21 @@ const WebCryptoPbkdf2Params* WebCryptoAlgorithm::Pbkdf2Params() const {
return nullptr;
}
+const WebCryptoEd25519Params* WebCryptoAlgorithm::Ed25519Params() const {
+ DCHECK(!IsNull());
+ if (ParamsType() == kWebCryptoAlgorithmParamsTypeEd25519Params)
+ return static_cast<WebCryptoEd25519Params*>(private_->params.get());
+ return nullptr;
+}
+
+const WebCryptoX25519KeyDeriveParams*
+WebCryptoAlgorithm::X25519KeyDeriveParams() const {
+ DCHECK(!IsNull());
+ if (ParamsType() == kWebCryptoAlgorithmParamsTypeX25519KeyDeriveParams)
+ return static_cast<WebCryptoX25519KeyDeriveParams*>(private_->params.get());
+ return nullptr;
+}
+
bool WebCryptoAlgorithm::IsHash(WebCryptoAlgorithmId id) {
switch (id) {
case kWebCryptoAlgorithmIdSha1:
@@ -508,6 +559,8 @@ bool WebCryptoAlgorithm::IsHash(WebCryptoAlgorithmId id) {
case kWebCryptoAlgorithmIdEcdh:
case kWebCryptoAlgorithmIdHkdf:
case kWebCryptoAlgorithmIdPbkdf2:
+ case kWebCryptoAlgorithmIdEd25519:
+ case kWebCryptoAlgorithmIdX25519:
break;
}
return false;
@@ -532,6 +585,8 @@ bool WebCryptoAlgorithm::IsKdf(WebCryptoAlgorithmId id) {
case kWebCryptoAlgorithmIdRsaPss:
case kWebCryptoAlgorithmIdEcdsa:
case kWebCryptoAlgorithmIdEcdh:
+ case kWebCryptoAlgorithmIdEd25519:
+ case kWebCryptoAlgorithmIdX25519:
break;
}
return false;
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_cursor_info.cc b/chromium/third_party/blink/renderer/platform/exported/web_cursor_info.cc
deleted file mode 100644
index c26adc1f2f1..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_cursor_info.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2009 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/public/platform/web_cursor_info.h"
-
-#include "third_party/blink/renderer/platform/cursor.h"
-
-namespace blink {
-
-static SkBitmap GetCursorBitmap(const Cursor& cursor) {
- if (!cursor.GetImage())
- return {};
- return cursor.GetImage()->AsSkBitmapForCurrentFrame(
- kDoNotRespectImageOrientation);
-}
-
-WebCursorInfo::WebCursorInfo(const Cursor& cursor)
- : type(static_cast<ui::CursorType>(cursor.GetType())),
- hot_spot(cursor.HotSpot()),
- image_scale_factor(cursor.ImageScaleFactor()),
- custom_image(GetCursorBitmap(cursor)) {}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_failing_url_loader_factory.cc b/chromium/third_party/blink/renderer/platform/exported/web_failing_url_loader_factory.cc
new file mode 100644
index 00000000000..e1633daf19b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/exported/web_failing_url_loader_factory.cc
@@ -0,0 +1,88 @@
+// 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/public/platform/web_failing_url_loader_factory.h"
+
+#include <memory>
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "base/single_thread_task_runner.h"
+#include "services/network/public/cpp/resource_request.h"
+#include "third_party/blink/public/platform/scheduler/web_resource_loading_task_runner_handle.h"
+#include "third_party/blink/public/platform/web_url_error.h"
+#include "third_party/blink/public/platform/web_url_loader.h"
+#include "third_party/blink/public/platform/web_url_loader_client.h"
+#include "third_party/blink/renderer/platform/loader/fetch/resource_error.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
+
+namespace blink {
+
+namespace {
+
+// A WebURLLoader which always fails loading.
+class FailingLoader final : public WebURLLoader {
+ public:
+ explicit FailingLoader(
+ std::unique_ptr<scheduler::WebResourceLoadingTaskRunnerHandle>
+ task_runner_handle)
+ : task_runner_handle_(std::move(task_runner_handle)) {}
+ ~FailingLoader() override = default;
+
+ // WebURLLoader implementation:
+ void LoadSynchronously(
+ std::unique_ptr<network::ResourceRequest> request,
+ scoped_refptr<WebURLRequest::ExtraData> request_extra_data,
+ int requestor_id,
+ bool download_to_network_cache_only,
+ bool pass_response_pipe_to_client,
+ bool no_mime_sniffing,
+ base::TimeDelta timeout_interval,
+ WebURLLoaderClient*,
+ WebURLResponse&,
+ base::Optional<WebURLError>& error,
+ WebData&,
+ int64_t& encoded_data_length,
+ int64_t& encoded_body_length,
+ WebBlobInfo& downloaded_blob) override {
+ error = ResourceError::Failure(KURL(request->url));
+ }
+ void LoadAsynchronously(
+ std::unique_ptr<network::ResourceRequest> request,
+ scoped_refptr<WebURLRequest::ExtraData> request_extra_data,
+ int requestor_id,
+ bool download_to_network_cache_only,
+ bool no_mime_sniffing,
+ WebURLLoaderClient* client) override {
+ GetTaskRunner()->PostTask(
+ FROM_HERE, WTF::Bind(&FailingLoader::Fail, weak_factory_.GetWeakPtr(),
+ KURL(request->url), WTF::Unretained(client)));
+ }
+ void SetDefersLoading(bool) override {}
+ void DidChangePriority(WebURLRequest::Priority, int) override {}
+ scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() override {
+ return task_runner_handle_->GetTaskRunner();
+ }
+
+ private:
+ void Fail(const KURL& url, WebURLLoaderClient* client) {
+ client->DidFail(ResourceError::Failure(url), 0, 0, 0);
+ }
+
+ const std::unique_ptr<scheduler::WebResourceLoadingTaskRunnerHandle>
+ task_runner_handle_;
+
+ // This must be the last member.
+ base::WeakPtrFactory<FailingLoader> weak_factory_{this};
+};
+
+} // namespace
+
+std::unique_ptr<WebURLLoader> WebFailingURLLoaderFactory::CreateURLLoader(
+ const WebURLRequest&,
+ std::unique_ptr<scheduler::WebResourceLoadingTaskRunnerHandle> handle) {
+ return std::make_unique<FailingLoader>(std::move(handle));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_font.cc b/chromium/third_party/blink/renderer/platform/exported/web_font.cc
index 96ad579b538..f8fee0c8b30 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_font.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_font.cc
@@ -4,7 +4,6 @@
#include "third_party/blink/public/platform/web_font.h"
-#include "third_party/blink/public/platform/web_float_point.h"
#include "third_party/blink/public/platform/web_float_rect.h"
#include "third_party/blink/public/platform/web_font_description.h"
#include "third_party/blink/public/platform/web_rect.h"
@@ -30,7 +29,6 @@ class WebFont::Impl final {
public:
explicit Impl(const WebFontDescription& description) : font_(description) {
- font_.Update(nullptr);
}
const Font& GetFont() const { return font_; }
@@ -82,7 +80,7 @@ float WebFont::XHeight() const {
void WebFont::DrawText(cc::PaintCanvas* canvas,
const WebTextRun& run,
- const WebFloatPoint& left_baseline,
+ const gfx::PointF& left_baseline,
SkColor color) const {
FontCachePurgePreventer font_cache_purge_preventer;
TextRun text_run(run);
@@ -95,7 +93,7 @@ void WebFont::DrawText(cc::PaintCanvas* canvas,
DrawingRecorder recorder(context, builder, DisplayItem::kWebFont);
context.Save();
context.SetFillColor(color);
- context.DrawText(private_->GetFont(), run_info, left_baseline,
+ context.DrawText(private_->GetFont(), run_info, FloatPoint(left_baseline),
kInvalidDOMNodeId);
context.Restore();
}
@@ -113,12 +111,12 @@ int WebFont::OffsetForPosition(const WebTextRun& run, float position) const {
}
WebFloatRect WebFont::SelectionRectForText(const WebTextRun& run,
- const WebFloatPoint& left_baseline,
+ const gfx::PointF& left_baseline,
int height,
int from,
int to) const {
- return private_->GetFont().SelectionRectForText(run, left_baseline, height,
- from, to);
+ return private_->GetFont().SelectionRectForText(
+ run, FloatPoint(left_baseline), height, from, to);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_gesture_event.cc b/chromium/third_party/blink/renderer/platform/exported/web_gesture_event.cc
deleted file mode 100644
index 406e279d2c5..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_gesture_event.cc
+++ /dev/null
@@ -1,155 +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/public/platform/web_gesture_event.h"
-
-namespace blink {
-
-float WebGestureEvent::DeltaXInRootFrame() const {
- if (type_ == WebInputEvent::kGestureScrollBegin)
- return data.scroll_begin.delta_x_hint / frame_scale_;
- DCHECK(type_ == WebInputEvent::kGestureScrollUpdate);
- return data.scroll_update.delta_x / frame_scale_;
-}
-
-float WebGestureEvent::DeltaYInRootFrame() const {
- if (type_ == WebInputEvent::kGestureScrollBegin)
- return data.scroll_begin.delta_y_hint / frame_scale_;
- DCHECK(type_ == WebInputEvent::kGestureScrollUpdate);
- return data.scroll_update.delta_y / frame_scale_;
-}
-
-ui::input_types::ScrollGranularity WebGestureEvent::DeltaUnits() const {
- if (type_ == WebInputEvent::kGestureScrollBegin)
- return data.scroll_begin.delta_hint_units;
- if (type_ == WebInputEvent::kGestureScrollUpdate)
- return data.scroll_update.delta_units;
- DCHECK(type_ == WebInputEvent::kGestureScrollEnd);
- return data.scroll_end.delta_units;
-}
-
-WebGestureEvent::InertialPhaseState WebGestureEvent::InertialPhase() const {
- if (type_ == WebInputEvent::kGestureScrollBegin)
- return data.scroll_begin.inertial_phase;
- if (type_ == WebInputEvent::kGestureScrollUpdate)
- return data.scroll_update.inertial_phase;
- DCHECK(type_ == WebInputEvent::kGestureScrollEnd);
- return data.scroll_end.inertial_phase;
-}
-
-bool WebGestureEvent::Synthetic() const {
- if (type_ == WebInputEvent::kGestureScrollBegin)
- return data.scroll_begin.synthetic;
- DCHECK(type_ == WebInputEvent::kGestureScrollEnd);
- return data.scroll_end.synthetic;
-}
-
-float WebGestureEvent::VelocityX() const {
- if (type_ == WebInputEvent::kGestureScrollUpdate)
- return data.scroll_update.velocity_x;
- DCHECK(type_ == WebInputEvent::kGestureFlingStart);
- return data.fling_start.velocity_x;
-}
-
-float WebGestureEvent::VelocityY() const {
- if (type_ == WebInputEvent::kGestureScrollUpdate)
- return data.scroll_update.velocity_y;
- DCHECK(type_ == WebInputEvent::kGestureFlingStart);
- return data.fling_start.velocity_y;
-}
-
-WebFloatSize WebGestureEvent::TapAreaInRootFrame() const {
- if (type_ == WebInputEvent::kGestureTwoFingerTap) {
- return WebFloatSize(data.two_finger_tap.first_finger_width / frame_scale_,
- data.two_finger_tap.first_finger_height / frame_scale_);
- } else if (type_ == WebInputEvent::kGestureLongPress ||
- type_ == WebInputEvent::kGestureLongTap) {
- return WebFloatSize(data.long_press.width / frame_scale_,
- data.long_press.height / frame_scale_);
- } else if (type_ == WebInputEvent::kGestureTap ||
- type_ == WebInputEvent::kGestureTapUnconfirmed ||
- type_ == WebInputEvent::kGestureDoubleTap) {
- return WebFloatSize(data.tap.width / frame_scale_,
- data.tap.height / frame_scale_);
- } else if (type_ == WebInputEvent::kGestureTapDown) {
- return WebFloatSize(data.tap_down.width / frame_scale_,
- data.tap_down.height / frame_scale_);
- } else if (type_ == WebInputEvent::kGestureShowPress) {
- return WebFloatSize(data.show_press.width / frame_scale_,
- data.show_press.height / frame_scale_);
- }
- // This function is called for all gestures and determined if the tap
- // area is empty or not; so return an empty rect here.
- return WebFloatSize();
-}
-
-WebFloatPoint WebGestureEvent::PositionInRootFrame() const {
- return WebFloatPoint(
- (position_in_widget_.x / frame_scale_) + frame_translate_.x,
- (position_in_widget_.y / frame_scale_) + frame_translate_.y);
-}
-
-int WebGestureEvent::TapCount() const {
- DCHECK(type_ == WebInputEvent::kGestureTap);
- return data.tap.tap_count;
-}
-
-void WebGestureEvent::ApplyTouchAdjustment(WebFloatPoint root_frame_coords) {
- // Update the window-relative position of the event so that the node that
- // was ultimately hit is under this point (i.e. elementFromPoint for the
- // client co-ordinates in a 'click' event should yield the target). The
- // global position is intentionally left unmodified because it's intended to
- // reflect raw co-ordinates unrelated to any content.
- frame_translate_.x =
- root_frame_coords.x - (position_in_widget_.x / frame_scale_);
- frame_translate_.y =
- root_frame_coords.y - (position_in_widget_.y / frame_scale_);
-}
-
-void WebGestureEvent::FlattenTransform() {
- if (frame_scale_ != 1) {
- switch (type_) {
- case WebInputEvent::kGestureScrollBegin:
- data.scroll_begin.delta_x_hint /= frame_scale_;
- data.scroll_begin.delta_y_hint /= frame_scale_;
- break;
- case WebInputEvent::kGestureScrollUpdate:
- data.scroll_update.delta_x /= frame_scale_;
- data.scroll_update.delta_y /= frame_scale_;
- break;
- case WebInputEvent::kGestureTwoFingerTap:
- data.two_finger_tap.first_finger_width /= frame_scale_;
- data.two_finger_tap.first_finger_height /= frame_scale_;
- break;
- case WebInputEvent::kGestureLongPress:
- case WebInputEvent::kGestureLongTap:
- data.long_press.width /= frame_scale_;
- data.long_press.height /= frame_scale_;
- break;
- case WebInputEvent::kGestureTap:
- case WebInputEvent::kGestureTapUnconfirmed:
- case WebInputEvent::kGestureDoubleTap:
- data.tap.width /= frame_scale_;
- data.tap.height /= frame_scale_;
- break;
- case WebInputEvent::kGestureTapDown:
- data.tap_down.width /= frame_scale_;
- data.tap_down.height /= frame_scale_;
- break;
- case WebInputEvent::kGestureShowPress:
- data.show_press.width /= frame_scale_;
- data.show_press.height /= frame_scale_;
- break;
- default:
- break;
- }
- }
-
- SetPositionInWidget(PositionInRootFrame());
- frame_translate_.x = 0;
- frame_translate_.y = 0;
- frame_scale_ = 1;
-}
-
-} // namespace blink
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 f60fa03f4c9..83c1f68f7d3 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
@@ -121,11 +121,6 @@ void WebHTTPBody::AppendData(const WebData& data) {
});
}
-void WebHTTPBody::AppendFile(const WebString& file_path) {
- EnsureMutable();
- private_->AppendFile(file_path);
-}
-
void WebHTTPBody::AppendFileRange(
const WebString& file_path,
int64_t file_start,
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_icon_sizes_parser.cc b/chromium/third_party/blink/renderer/platform/exported/web_icon_sizes_parser.cc
index 9d1960e18cf..ec882242c25 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_icon_sizes_parser.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_icon_sizes_parser.cc
@@ -50,10 +50,10 @@ static inline int PartialStringToInt(const String& string,
} // namespace
-WebVector<WebSize> WebIconSizesParser::ParseIconSizes(
+WebVector<gfx::Size> WebIconSizesParser::ParseIconSizes(
const WebString& web_sizes_string) {
String sizes_string = web_sizes_string;
- Vector<WebSize> icon_sizes;
+ Vector<gfx::Size> icon_sizes;
if (sizes_string.IsEmpty())
return icon_sizes;
@@ -67,7 +67,7 @@ WebVector<WebSize> WebIconSizesParser::ParseIconSizes(
// See if the current size is "any".
if (sizes_string.Substring(i, 3).StartsWithIgnoringCase("any") &&
(i + 3 == length || IsWhitespace(sizes_string[i + 3]))) {
- icon_sizes.push_back(WebSize(0, 0));
+ icon_sizes.push_back(gfx::Size());
i = i + 3;
continue;
}
@@ -100,8 +100,8 @@ WebVector<WebSize> WebIconSizesParser::ParseIconSizes(
// Append the parsed size to iconSizes.
icon_sizes.push_back(
- WebSize(PartialStringToInt(sizes_string, width_start, width_end),
- PartialStringToInt(sizes_string, height_start, height_end)));
+ gfx::Size(PartialStringToInt(sizes_string, width_start, width_end),
+ PartialStringToInt(sizes_string, height_start, height_end)));
}
return icon_sizes;
}
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_icon_sizes_parser_test.cc b/chromium/third_party/blink/renderer/platform/exported/web_icon_sizes_parser_test.cc
index 53959c6c10e..d35d2f3431b 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_icon_sizes_parser_test.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_icon_sizes_parser_test.cc
@@ -5,9 +5,9 @@
#include "third_party/blink/public/platform/web_icon_sizes_parser.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
+#include "ui/gfx/geometry/size.h"
namespace blink {
@@ -15,17 +15,17 @@ class WebIconSizesParserTest : public testing::Test {};
TEST(WebIconSizesParserTest, parseSizes) {
WebString sizes_attribute = "32x33";
- WebVector<WebSize> sizes;
+ WebVector<gfx::Size> sizes;
sizes = WebIconSizesParser::ParseIconSizes(sizes_attribute);
ASSERT_EQ(1U, sizes.size());
- EXPECT_EQ(32, sizes[0].width);
- EXPECT_EQ(33, sizes[0].height);
+ EXPECT_EQ(32, sizes[0].width());
+ EXPECT_EQ(33, sizes[0].height());
sizes_attribute = " 10x11 ";
sizes = WebIconSizesParser::ParseIconSizes(sizes_attribute);
ASSERT_EQ(1u, sizes.size());
- EXPECT_EQ(10, sizes[0].width);
- EXPECT_EQ(11, sizes[0].height);
+ EXPECT_EQ(10, sizes[0].width());
+ EXPECT_EQ(11, sizes[0].height());
sizes_attribute = "0x33";
sizes = WebIconSizesParser::ParseIconSizes(sizes_attribute);
@@ -35,18 +35,18 @@ TEST(WebIconSizesParserTest, parseSizes) {
sizes_attribute = AtomicString(attribute);
sizes = WebIconSizesParser::ParseIconSizes(sizes_attribute);
ASSERT_EQ(1U, sizes.size());
- EXPECT_EQ(32, sizes[0].width);
- EXPECT_EQ(33, sizes[0].height);
+ EXPECT_EQ(32, sizes[0].width());
+ EXPECT_EQ(33, sizes[0].height());
sizes_attribute = " 32x33 16X17 128x129 ";
sizes = WebIconSizesParser::ParseIconSizes(sizes_attribute);
ASSERT_EQ(3U, sizes.size());
- EXPECT_EQ(32, sizes[0].width);
- EXPECT_EQ(33, sizes[0].height);
- EXPECT_EQ(16, sizes[1].width);
- EXPECT_EQ(17, sizes[1].height);
- EXPECT_EQ(128, sizes[2].width);
- EXPECT_EQ(129, sizes[2].height);
+ EXPECT_EQ(32, sizes[0].width());
+ EXPECT_EQ(33, sizes[0].height());
+ EXPECT_EQ(16, sizes[1].width());
+ EXPECT_EQ(17, sizes[1].height());
+ EXPECT_EQ(128, sizes[2].width());
+ EXPECT_EQ(129, sizes[2].height());
sizes_attribute = " \n 32x33 \r 16X17 \t 128x129 \f ";
sizes = WebIconSizesParser::ParseIconSizes(sizes_attribute);
@@ -55,8 +55,8 @@ TEST(WebIconSizesParserTest, parseSizes) {
sizes_attribute = "any";
sizes = WebIconSizesParser::ParseIconSizes(sizes_attribute);
ASSERT_EQ(1U, sizes.size());
- EXPECT_EQ(0, sizes[0].width);
- EXPECT_EQ(0, sizes[0].height);
+ EXPECT_EQ(0, sizes[0].width());
+ EXPECT_EQ(0, sizes[0].height());
sizes_attribute = "ANY";
sizes = WebIconSizesParser::ParseIconSizes(sizes_attribute);
@@ -69,22 +69,22 @@ TEST(WebIconSizesParserTest, parseSizes) {
sizes_attribute = " any";
sizes = WebIconSizesParser::ParseIconSizes(sizes_attribute);
ASSERT_EQ(1U, sizes.size());
- EXPECT_EQ(0, sizes[0].width);
- EXPECT_EQ(0, sizes[0].height);
+ EXPECT_EQ(0, sizes[0].width());
+ EXPECT_EQ(0, sizes[0].height());
sizes_attribute = " any ";
sizes = WebIconSizesParser::ParseIconSizes(sizes_attribute);
ASSERT_EQ(1U, sizes.size());
- EXPECT_EQ(0, sizes[0].width);
- EXPECT_EQ(0, sizes[0].height);
+ EXPECT_EQ(0, sizes[0].width());
+ EXPECT_EQ(0, sizes[0].height());
sizes_attribute = "any 10x10";
sizes = WebIconSizesParser::ParseIconSizes(sizes_attribute);
ASSERT_EQ(2u, sizes.size());
- EXPECT_EQ(0, sizes[0].width);
- EXPECT_EQ(0, sizes[0].height);
- EXPECT_EQ(10, sizes[1].width);
- EXPECT_EQ(10, sizes[1].height);
+ EXPECT_EQ(0, sizes[0].width());
+ EXPECT_EQ(0, sizes[0].height());
+ EXPECT_EQ(10, sizes[1].width());
+ EXPECT_EQ(10, sizes[1].height());
sizes_attribute = "an";
sizes = WebIconSizesParser::ParseIconSizes(sizes_attribute);
@@ -129,34 +129,34 @@ TEST(WebIconSizesParserTest, parseSizes) {
sizes_attribute = "32x33 32";
sizes = WebIconSizesParser::ParseIconSizes(sizes_attribute);
ASSERT_EQ(1U, sizes.size());
- EXPECT_EQ(32, sizes[0].width);
- EXPECT_EQ(33, sizes[0].height);
+ EXPECT_EQ(32, sizes[0].width());
+ EXPECT_EQ(33, sizes[0].height());
sizes_attribute = "32x33 32x";
sizes = WebIconSizesParser::ParseIconSizes(sizes_attribute);
ASSERT_EQ(1U, sizes.size());
- EXPECT_EQ(32, sizes[0].width);
- EXPECT_EQ(33, sizes[0].height);
+ EXPECT_EQ(32, sizes[0].width());
+ EXPECT_EQ(33, sizes[0].height());
sizes_attribute = "32x33 x32";
sizes = WebIconSizesParser::ParseIconSizes(sizes_attribute);
ASSERT_EQ(1U, sizes.size());
- EXPECT_EQ(32, sizes[0].width);
- EXPECT_EQ(33, sizes[0].height);
+ EXPECT_EQ(32, sizes[0].width());
+ EXPECT_EQ(33, sizes[0].height());
sizes_attribute = "32x33 any";
sizes = WebIconSizesParser::ParseIconSizes(sizes_attribute);
ASSERT_EQ(2U, sizes.size());
- EXPECT_EQ(32, sizes[0].width);
- EXPECT_EQ(33, sizes[0].height);
- EXPECT_EQ(0, sizes[1].width);
- EXPECT_EQ(0, sizes[1].height);
+ EXPECT_EQ(32, sizes[0].width());
+ EXPECT_EQ(33, sizes[0].height());
+ EXPECT_EQ(0, sizes[1].width());
+ EXPECT_EQ(0, sizes[1].height());
sizes_attribute = "32x33, 64x64";
sizes = WebIconSizesParser::ParseIconSizes(sizes_attribute);
ASSERT_EQ(1U, sizes.size());
- EXPECT_EQ(64, sizes[0].width);
- EXPECT_EQ(64, sizes[0].height);
+ EXPECT_EQ(64, sizes[0].width());
+ EXPECT_EQ(64, sizes[0].height());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_input_event.cc b/chromium/third_party/blink/renderer/platform/exported/web_input_event.cc
deleted file mode 100644
index 85661bc1203..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_input_event.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2009 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/public/platform/web_input_event.h"
-
-#include <ctype.h>
-#include "third_party/blink/public/platform/web_gesture_event.h"
-#include "third_party/blink/public/platform/web_keyboard_event.h"
-#include "third_party/blink/public/platform/web_mouse_wheel_event.h"
-#include "third_party/blink/public/platform/web_touch_event.h"
-#include "third_party/blink/renderer/platform/keyboard_codes.h"
-#include "third_party/blink/renderer/platform/wtf/assertions.h"
-#include "third_party/blink/renderer/platform/wtf/text/ascii_ctype.h"
-
-namespace blink {
-
-struct SameSizeAsWebInputEvent {
- int input_data[8];
-};
-
-struct SameSizeAsWebKeyboardEvent : public SameSizeAsWebInputEvent {
- int keyboard_data[9];
-};
-
-struct SameSizeAsWebMouseEvent : public SameSizeAsWebInputEvent {
- int mouse_data[17];
-};
-
-struct SameSizeAsWebMouseWheelEvent : public SameSizeAsWebMouseEvent {
- int mousewheel_data[12];
-};
-
-struct SameSizeAsWebGestureEvent : public SameSizeAsWebInputEvent {
- int gesture_data[14];
-};
-
-struct SameSizeAsWebTouchEvent : public SameSizeAsWebInputEvent {
- WebTouchPoint touch_points[WebTouchEvent::kTouchesLengthCap];
- int touch_data[4];
-};
-
-static_assert(sizeof(WebInputEvent) == sizeof(SameSizeAsWebInputEvent),
- "WebInputEvent should not have gaps");
-static_assert(sizeof(WebKeyboardEvent) == sizeof(SameSizeAsWebKeyboardEvent),
- "WebKeyboardEvent should not have gaps");
-static_assert(sizeof(WebMouseEvent) == sizeof(SameSizeAsWebMouseEvent),
- "WebMouseEvent should not have gaps");
-static_assert(sizeof(WebMouseWheelEvent) ==
- sizeof(SameSizeAsWebMouseWheelEvent),
- "WebMouseWheelEvent should not have gaps");
-static_assert(sizeof(WebGestureEvent) == sizeof(SameSizeAsWebGestureEvent),
- "WebGestureEvent should not have gaps");
-static_assert(sizeof(WebTouchEvent) == sizeof(SameSizeAsWebTouchEvent),
- "WebTouchEvent should not have gaps");
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_isolate.cc b/chromium/third_party/blink/renderer/platform/exported/web_isolate.cc
new file mode 100644
index 00000000000..a61fda7ca44
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/exported/web_isolate.cc
@@ -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.
+
+#include "third_party/blink/renderer/platform/bindings/blink_isolate/blink_isolate.h"
+
+namespace blink {
+
+std::unique_ptr<WebIsolate> WebIsolate::Create() {
+ return std::unique_ptr<WebIsolate>(new BlinkIsolate());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_media_stream_audio_sink.cc b/chromium/third_party/blink/renderer/platform/exported/web_media_stream_audio_sink.cc
index 7276a8bd885..083bc2b1d8f 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_media_stream_audio_sink.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_media_stream_audio_sink.cc
@@ -5,9 +5,9 @@
#include "third_party/blink/public/platform/modules/mediastream/web_media_stream_audio_sink.h"
#include "base/logging.h"
-#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.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_track.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_media_stream_source.cc b/chromium/third_party/blink/renderer/platform/exported/web_media_stream_source.cc
index 75a6efcc795..27e4fda4194 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_media_stream_source.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_media_stream_source.cc
@@ -34,12 +34,12 @@
#include <utility>
#include "base/memory/ptr_util.h"
-#include "third_party/blink/public/platform/web_audio_destination_consumer.h"
-#include "third_party/blink/public/platform/web_media_constraints.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/renderer/platform/audio/audio_bus.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_source.h"
+#include "third_party/blink/renderer/platform/mediastream/webaudio_destination_consumer.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
@@ -182,7 +182,7 @@ void ConsumerWrapper::ConsumeAudio(AudioBus* bus, size_t number_of_frames) {
// Wrap AudioBus.
size_t number_of_channels = bus->NumberOfChannels();
- WebVector<const float*> bus_vector(number_of_channels);
+ Vector<const float*> bus_vector(number_of_channels);
for (size_t i = 0; i < number_of_channels; ++i)
bus_vector[i] = bus->Channel(i)->Data();
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_media_stream_track.cc b/chromium/third_party/blink/renderer/platform/exported/web_media_stream_track.cc
index 4e51ff18abc..340b06a12a9 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_media_stream_track.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_media_stream_track.cc
@@ -29,11 +29,11 @@
#include "base/memory/ptr_util.h"
#include "third_party/blink/public/platform/web_audio_source_provider.h"
-#include "third_party/blink/public/platform/web_media_constraints.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_string.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/media_stream_source.h"
@@ -84,13 +84,12 @@ WebMediaStreamTrack::ContentHintType WebMediaStreamTrack::ContentHint() const {
return private_->ContentHint();
}
-WebMediaConstraints WebMediaStreamTrack::Constraints() const {
+MediaConstraints WebMediaStreamTrack::Constraints() const {
DCHECK(!private_.IsNull());
return private_->Constraints();
}
-void WebMediaStreamTrack::SetConstraints(
- const WebMediaConstraints& constraints) {
+void WebMediaStreamTrack::SetConstraints(const MediaConstraints& constraints) {
DCHECK(!private_.IsNull());
return private_->SetConstraints(constraints);
}
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_mouse_event.cc b/chromium/third_party/blink/renderer/platform/exported/web_mouse_event.cc
deleted file mode 100644
index ff5338a2fd4..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_mouse_event.cc
+++ /dev/null
@@ -1,69 +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/public/platform/web_mouse_event.h"
-
-#include "third_party/blink/public/platform/web_gesture_event.h"
-
-namespace blink {
-
-WebMouseEvent::WebMouseEvent(WebInputEvent::Type type,
- const WebGestureEvent& gesture_event,
- Button button_param,
- int click_count_param,
- int modifiers,
- base::TimeTicks time_stamp,
- PointerId id_param)
- : WebInputEvent(sizeof(WebMouseEvent), type, modifiers, time_stamp),
- WebPointerProperties(id_param,
- WebPointerProperties::PointerType::kMouse,
- button_param),
- click_count(click_count_param) {
- DCHECK_GE(type, kMouseTypeFirst);
- DCHECK_LE(type, kMouseTypeLast);
- SetPositionInWidget(gesture_event.PositionInWidget());
- SetPositionInScreen(gesture_event.PositionInScreen());
- SetFrameScale(gesture_event.FrameScale());
- SetFrameTranslate(gesture_event.FrameTranslate());
- SetMenuSourceType(gesture_event.GetType());
-}
-
-WebFloatPoint WebMouseEvent::PositionInRootFrame() const {
- return WebFloatPoint(
- (position_in_widget_.x / frame_scale_) + frame_translate_.x,
- (position_in_widget_.y / frame_scale_) + frame_translate_.y);
-}
-
-WebMouseEvent WebMouseEvent::FlattenTransform() const {
- WebMouseEvent result = *this;
- result.FlattenTransformSelf();
- return result;
-}
-
-void WebMouseEvent::FlattenTransformSelf() {
- position_in_widget_ = PositionInRootFrame();
- frame_translate_.x = 0;
- frame_translate_.y = 0;
- frame_scale_ = 1;
-}
-
-void WebMouseEvent::SetMenuSourceType(WebInputEvent::Type type) {
- switch (type) {
- case kGestureTapDown:
- case kGestureTap:
- case kGestureDoubleTap:
- menu_source_type = kMenuSourceTouch;
- break;
- case kGestureLongPress:
- menu_source_type = kMenuSourceLongPress;
- break;
- case kGestureLongTap:
- menu_source_type = kMenuSourceLongTap;
- break;
- default:
- menu_source_type = kMenuSourceNone;
- }
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_mouse_wheel_event.cc b/chromium/third_party/blink/renderer/platform/exported/web_mouse_wheel_event.cc
deleted file mode 100644
index cc02b1e4947..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_mouse_wheel_event.cc
+++ /dev/null
@@ -1,25 +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/public/platform/web_mouse_wheel_event.h"
-
-namespace blink {
-
-float WebMouseWheelEvent::DeltaXInRootFrame() const {
- return delta_x / frame_scale_;
-}
-
-float WebMouseWheelEvent::DeltaYInRootFrame() const {
- return delta_y / frame_scale_;
-}
-
-WebMouseWheelEvent WebMouseWheelEvent::FlattenTransform() const {
- WebMouseWheelEvent result = *this;
- result.delta_x /= result.frame_scale_;
- result.delta_y /= result.frame_scale_;
- result.FlattenTransformSelf();
- return result;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_pointer_event.cc b/chromium/third_party/blink/renderer/platform/exported/web_pointer_event.cc
deleted file mode 100644
index 8c710c12480..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_pointer_event.cc
+++ /dev/null
@@ -1,101 +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/public/platform/web_pointer_event.h"
-
-#include "third_party/blink/public/platform/web_float_point.h"
-
-namespace blink {
-
-namespace {
-
-WebInputEvent::Type PointerEventTypeForTouchPointState(
- WebTouchPoint::State state) {
- switch (state) {
- case WebTouchPoint::kStateReleased:
- return WebInputEvent::Type::kPointerUp;
- case WebTouchPoint::kStateCancelled:
- return WebInputEvent::Type::kPointerCancel;
- case WebTouchPoint::kStatePressed:
- return WebInputEvent::Type::kPointerDown;
- case WebTouchPoint::kStateMoved:
- return WebInputEvent::Type::kPointerMove;
- case WebTouchPoint::kStateStationary:
- default:
- NOTREACHED();
- return WebInputEvent::Type::kUndefined;
- }
-}
-
-} // namespace
-
-WebPointerEvent::WebPointerEvent(const WebTouchEvent& touch_event,
- const WebTouchPoint& touch_point)
- : WebInputEvent(sizeof(WebPointerEvent),
- PointerEventTypeForTouchPointState(touch_point.state),
- touch_event.GetModifiers(),
- touch_event.TimeStamp()),
-
- WebPointerProperties(touch_point),
- hovering(touch_event.hovering),
- width(touch_point.radius_x * 2.f),
- height(touch_point.radius_y * 2.f) {
- // WebInutEvent attributes
- SetFrameScale(touch_event.FrameScale());
- SetFrameTranslate(touch_event.FrameTranslate());
- // WebTouchEvent attributes
- dispatch_type = touch_event.dispatch_type;
- moved_beyond_slop_region = touch_event.moved_beyond_slop_region;
- touch_start_or_first_touch_move = touch_event.touch_start_or_first_touch_move;
- unique_touch_event_id = touch_event.unique_touch_event_id;
- // WebTouchPoint attributes
- rotation_angle = touch_point.rotation_angle;
- // TODO(crbug.com/816504): Touch point button is not set at this point yet.
- button = (GetType() == WebInputEvent::kPointerDown ||
- GetType() == WebInputEvent::kPointerUp)
- ? WebPointerProperties::Button::kLeft
- : WebPointerProperties::Button::kNoButton;
-}
-
-WebPointerEvent::WebPointerEvent(WebInputEvent::Type type,
- const WebMouseEvent& mouse_event)
- : WebInputEvent(sizeof(WebPointerEvent),
- type,
- mouse_event.GetModifiers(),
- mouse_event.TimeStamp()),
- WebPointerProperties(mouse_event),
- hovering(true),
- width(std::numeric_limits<float>::quiet_NaN()),
- height(std::numeric_limits<float>::quiet_NaN()) {
- DCHECK_GE(type, WebInputEvent::kPointerTypeFirst);
- DCHECK_LE(type, WebInputEvent::kPointerTypeLast);
- SetFrameScale(mouse_event.FrameScale());
- SetFrameTranslate(mouse_event.FrameTranslate());
-}
-
-WebPointerEvent WebPointerEvent::CreatePointerCausesUaActionEvent(
- WebPointerProperties::PointerType type,
- base::TimeTicks time_stamp) {
- WebPointerEvent event;
- event.pointer_type = type;
- event.SetTimeStamp(time_stamp);
- event.SetType(WebInputEvent::Type::kPointerCausedUaAction);
- return event;
-}
-
-WebPointerEvent WebPointerEvent::WebPointerEventInRootFrame() const {
- WebPointerEvent transformed_event = *this;
- if (HasWidth())
- transformed_event.width /= frame_scale_;
- if (HasHeight())
- transformed_event.height /= frame_scale_;
- transformed_event.position_in_widget_ =
- WebFloatPoint((transformed_event.PositionInWidget().x / frame_scale_) +
- frame_translate_.x,
- (transformed_event.PositionInWidget().y / frame_scale_) +
- frame_translate_.y);
- return transformed_event;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_prerender.cc b/chromium/third_party/blink/renderer/platform/exported/web_prerender.cc
deleted file mode 100644
index 36f7daee909..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_prerender.cc
+++ /dev/null
@@ -1,132 +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/public/platform/web_prerender.h"
-
-#include <memory>
-
-#include "base/memory/ptr_util.h"
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/renderer/platform/prerender.h"
-#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
-
-namespace blink {
-
-namespace {
-
-class PrerenderExtraDataContainer : public Prerender::ExtraData {
- public:
- static scoped_refptr<PrerenderExtraDataContainer> Create(
- WebPrerender::ExtraData* extra_data) {
- return base::AdoptRef(new PrerenderExtraDataContainer(extra_data));
- }
-
- ~PrerenderExtraDataContainer() override = default;
-
- WebPrerender::ExtraData* GetExtraData() const { return extra_data_.get(); }
-
- private:
- explicit PrerenderExtraDataContainer(WebPrerender::ExtraData* extra_data)
- : extra_data_(base::WrapUnique(extra_data)) {}
-
- std::unique_ptr<WebPrerender::ExtraData> extra_data_;
-};
-
-} // namespace
-
-WebPrerender::WebPrerender(Prerender* prerender) : private_(prerender) {}
-
-const Prerender* WebPrerender::ToPrerender() const {
- return private_.Get();
-}
-
-void WebPrerender::Reset() {
- private_.Reset();
-}
-
-void WebPrerender::Assign(const WebPrerender& other) {
- private_ = other.private_;
-}
-
-bool WebPrerender::IsNull() const {
- return private_.IsNull();
-}
-
-WebURL WebPrerender::Url() const {
- return WebURL(private_->Url());
-}
-
-unsigned WebPrerender::RelTypes() const {
- return private_->RelTypes();
-}
-
-WebString WebPrerender::GetReferrer() const {
- return private_->GetReferrer();
-}
-
-url::Origin WebPrerender::SecurityOrigin() const {
- auto* security_origin = private_->GetSecurityOrigin();
- return security_origin ? security_origin->ToUrlOrigin() : url::Origin();
-}
-
-network::mojom::ReferrerPolicy WebPrerender::GetReferrerPolicy() const {
- return private_->GetReferrerPolicy();
-}
-
-void WebPrerender::SetExtraData(WebPrerender::ExtraData* extra_data) {
- private_->SetExtraData(PrerenderExtraDataContainer::Create(extra_data));
-}
-
-const WebPrerender::ExtraData* WebPrerender::GetExtraData() const {
- scoped_refptr<Prerender::ExtraData> webcore_extra_data =
- private_->GetExtraData();
- if (!webcore_extra_data)
- return nullptr;
- return static_cast<PrerenderExtraDataContainer*>(webcore_extra_data.get())
- ->GetExtraData();
-}
-
-void WebPrerender::DidStartPrerender() {
- private_->DidStartPrerender();
-}
-
-void WebPrerender::DidStopPrerender() {
- private_->DidStopPrerender();
-}
-
-void WebPrerender::DidSendLoadForPrerender() {
- private_->DidSendLoadForPrerender();
-}
-
-void WebPrerender::DidSendDOMContentLoadedForPrerender() {
- private_->DidSendDOMContentLoadedForPrerender();
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_prerendering_support.cc b/chromium/third_party/blink/renderer/platform/exported/web_prerendering_support.cc
deleted file mode 100644
index edc12ec2d3c..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_prerendering_support.cc
+++ /dev/null
@@ -1,52 +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/public/platform/web_prerendering_support.h"
-
-namespace blink {
-
-WebPrerenderingSupport* WebPrerenderingSupport::platform_ = nullptr;
-
-// static
-void WebPrerenderingSupport::Initialize(WebPrerenderingSupport* platform) {
- platform_ = platform;
-}
-
-// static
-void WebPrerenderingSupport::Shutdown() {
- platform_ = nullptr;
-}
-
-// static
-WebPrerenderingSupport* WebPrerenderingSupport::Current() {
- return platform_;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_resource_timing_info.cc b/chromium/third_party/blink/renderer/platform/exported/web_resource_timing_info.cc
deleted file mode 100644
index ac11337e73a..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_resource_timing_info.cc
+++ /dev/null
@@ -1,99 +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/public/platform/web_resource_timing_info.h"
-
-#include "third_party/blink/public/platform/web_url_load_timing.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-
-namespace {
-
-bool IsSameServerTimingInfo(const WebVector<WebServerTimingInfo>& lhs,
- const WebVector<WebServerTimingInfo>& rhs) {
- if (lhs.size() != rhs.size())
- return false;
- for (size_t i = 0; i < lhs.size(); ++i) {
- if (lhs[i] != rhs[i])
- return false;
- }
- return true;
-}
-
-} // namespace
-
-bool WebServerTimingInfo::operator==(const WebServerTimingInfo& other) const {
- return name == other.name && duration == other.duration &&
- description == other.description;
-}
-
-bool WebServerTimingInfo::operator!=(const WebServerTimingInfo& other) const {
- return !(*this == other);
-}
-
-bool WebResourceTimingInfo::operator==(
- const WebResourceTimingInfo& other) const {
- return name == other.name && start_time == other.start_time &&
- alpn_negotiated_protocol == other.alpn_negotiated_protocol &&
- connection_info == other.connection_info && timing == other.timing &&
- last_redirect_end_time == other.last_redirect_end_time &&
- response_end == other.response_end &&
- transfer_size == other.transfer_size &&
- encoded_body_size == other.encoded_body_size &&
- decoded_body_size == other.decoded_body_size &&
- context_type == other.context_type &&
- did_reuse_connection == other.did_reuse_connection &&
- is_secure_context == other.is_secure_context &&
- allow_timing_details == other.allow_timing_details &&
- allow_redirect_details == other.allow_redirect_details &&
- allow_negative_values == other.allow_negative_values &&
- IsSameServerTimingInfo(server_timing, other.server_timing);
-}
-
-} // namespace blink
-
-namespace WTF {
-#if INSIDE_BLINK
-CrossThreadCopier<blink::WebResourceTimingInfo>::Type
-CrossThreadCopier<blink::WebResourceTimingInfo>::Copy(
- const blink::WebResourceTimingInfo& info) {
- blink::WebResourceTimingInfo copy;
-
- copy.name = String(info.name).IsolatedCopy();
- copy.start_time = info.start_time;
-
- copy.alpn_negotiated_protocol =
- String(info.alpn_negotiated_protocol).IsolatedCopy();
- copy.connection_info = String(info.connection_info).IsolatedCopy();
-
- if (!info.timing.IsNull())
- copy.timing = CrossThreadCopier<blink::WebURLLoadTiming>::Copy(info.timing);
-
- copy.last_redirect_end_time = info.last_redirect_end_time;
- copy.response_end = info.response_end;
-
- copy.transfer_size = info.transfer_size;
- copy.encoded_body_size = info.encoded_body_size;
- copy.decoded_body_size = info.decoded_body_size;
- copy.context_type = info.context_type;
-
- copy.did_reuse_connection = info.did_reuse_connection;
- copy.is_secure_context = info.is_secure_context;
-
- copy.allow_timing_details = info.allow_timing_details;
- copy.allow_redirect_details = info.allow_redirect_details;
-
- copy.allow_negative_values = info.allow_negative_values;
- for (auto& entry : info.server_timing) {
- blink::WebServerTimingInfo entry_copy(
- String(entry.name).IsolatedCopy(), entry.duration,
- String(entry.description).IsolatedCopy());
- copy.server_timing.emplace_back(std::move(entry_copy));
- }
-
- return copy;
-}
-#endif
-} // namespace WTF
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_resource_timing_info_test.cc b/chromium/third_party/blink/renderer/platform/exported/web_resource_timing_info_test.cc
deleted file mode 100644
index 1caab47f81c..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_resource_timing_info_test.cc
+++ /dev/null
@@ -1,128 +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/public/platform/web_resource_timing_info.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/loader/fetch/resource_load_timing.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/testing_platform_support_with_mock_scheduler.h"
-#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
-
-namespace blink {
-
-namespace {
-
-scoped_refptr<ResourceLoadTiming> CreateResourceLoadTiming(
- const base::TimeTicks pseudo_time) {
- auto timing = ResourceLoadTiming::Create();
- timing->SetRequestTime(pseudo_time);
- timing->SetProxyStart(pseudo_time);
- timing->SetProxyEnd(pseudo_time);
- timing->SetDnsStart(pseudo_time);
- timing->SetDnsEnd(pseudo_time);
- timing->SetConnectStart(pseudo_time);
- timing->SetConnectEnd(pseudo_time);
- timing->SetWorkerStart(pseudo_time);
- timing->SetWorkerReady(pseudo_time);
- timing->SetSendStart(pseudo_time);
- timing->SetSendEnd(pseudo_time);
- timing->SetReceiveHeadersStart(pseudo_time);
- timing->SetReceiveHeadersEnd(pseudo_time);
- timing->SetSslStart(pseudo_time);
- timing->SetSslStart(pseudo_time);
- timing->SetSslEnd(pseudo_time);
- timing->SetPushEnd(pseudo_time);
- return timing;
-}
-
-WebResourceTimingInfo CreateWebResourceTimingInfo(
- const base::TimeTicks pseudo_time) {
- WebVector<WebServerTimingInfo> server_timing;
- server_timing.emplace_back(WebServerTimingInfo("server_timing_name", 1.0,
- "server_timing_description"));
-
- WebResourceTimingInfo info = {
- .name = "name",
- .start_time = pseudo_time,
-
- .alpn_negotiated_protocol = "protocol",
- .connection_info = "info",
-
- .timing = CreateResourceLoadTiming(pseudo_time),
- .last_redirect_end_time = pseudo_time,
- .response_end = pseudo_time,
-
- .transfer_size = 1,
- .encoded_body_size = 2,
- .decoded_body_size = 3,
-
- .did_reuse_connection = true,
- .is_secure_context = true,
-
- .allow_timing_details = true,
- .allow_redirect_details = true,
-
- .allow_negative_values = true,
-
- .server_timing = server_timing,
- };
- return info;
-}
-
-void CheckWebResourceTimingInfoOnThread(const WebResourceTimingInfo& info,
- const base::TimeTicks pseudo_time) {
- WebResourceTimingInfo expected = CreateWebResourceTimingInfo(pseudo_time);
- EXPECT_EQ(expected, info);
-
- EXPECT_EQ("name", info.name);
- EXPECT_EQ(pseudo_time, info.start_time);
-
- EXPECT_EQ("protocol", info.alpn_negotiated_protocol);
- EXPECT_EQ("info", info.connection_info);
-
- WebURLLoadTiming expected_timing(CreateResourceLoadTiming(pseudo_time));
- EXPECT_EQ(expected_timing, info.timing);
- EXPECT_EQ(pseudo_time, info.last_redirect_end_time);
- EXPECT_EQ(pseudo_time, info.response_end);
-
- EXPECT_EQ(1u, info.transfer_size);
- EXPECT_EQ(2u, info.encoded_body_size);
- EXPECT_EQ(3u, info.decoded_body_size);
-
- EXPECT_TRUE(info.did_reuse_connection);
- EXPECT_TRUE(info.is_secure_context);
-
- EXPECT_TRUE(info.allow_timing_details);
- EXPECT_TRUE(info.allow_redirect_details);
-
- EXPECT_TRUE(info.allow_negative_values);
-
- EXPECT_EQ(1u, info.server_timing.size());
-
- auto& entry = info.server_timing[0];
- EXPECT_EQ("server_timing_name", entry.name);
- EXPECT_EQ(1.0, entry.duration);
- EXPECT_EQ("server_timing_description", entry.description);
-}
-
-} // namespace
-
-TEST(WebResourceTimingInfoTest, CrossThreadCopy) {
- ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
- platform;
-
- base::TimeTicks pseudo_time = base::TimeTicks::Now();
- WebResourceTimingInfo info = CreateWebResourceTimingInfo(pseudo_time);
-
- std::unique_ptr<Thread> thread = Platform::Current()->CreateThread(
- ThreadCreationParams(ThreadType::kTestThread)
- .SetThreadNameForTest("TestThread"));
- PostCrossThreadTask(*thread->GetTaskRunner(), FROM_HERE,
- CrossThreadBindOnce(&CheckWebResourceTimingInfoOnThread,
- info, pseudo_time));
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_rtc_peer_connection_handler_client.cc b/chromium/third_party/blink/renderer/platform/exported/web_rtc_peer_connection_handler_client.cc
deleted file mode 100644
index 9b3be0525c0..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_rtc_peer_connection_handler_client.cc
+++ /dev/null
@@ -1,14 +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/public/platform/web_rtc_peer_connection_handler_client.h"
-
-namespace blink {
-
-WebRTCPeerConnectionHandlerClient::~WebRTCPeerConnectionHandlerClient() =
- default;
-
-void WebRTCPeerConnectionHandlerClient::ClosePeerConnection() {}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_rtc_stats.cc b/chromium/third_party/blink/renderer/platform/exported/web_rtc_stats.cc
deleted file mode 100644
index 52175634f23..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_rtc_stats.cc
+++ /dev/null
@@ -1,9 +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/public/platform/web_rtc_stats.h"
-
-namespace blink {
-
-} // namespace blink
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 a9da7db2638..8eae6d43357 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
@@ -40,6 +40,16 @@ void WebRuntimeFeatures::EnableBlockingFocusWithoutUserActivation(bool enable) {
RuntimeEnabledFeatures::SetBlockingFocusWithoutUserActivationEnabled(enable);
}
+void WebRuntimeFeatures::EnableBrowserVerifiedUserActivationKeyboard(
+ bool enable) {
+ RuntimeEnabledFeatures::SetBrowserVerifiedUserActivationKeyboardEnabled(
+ enable);
+}
+
+void WebRuntimeFeatures::EnableBrowserVerifiedUserActivationMouse(bool enable) {
+ RuntimeEnabledFeatures::SetBrowserVerifiedUserActivationMouseEnabled(enable);
+}
+
void WebRuntimeFeatures::EnableExperimentalFeatures(bool enable) {
RuntimeEnabledFeatures::SetExperimentalFeaturesEnabled(enable);
}
@@ -105,6 +115,10 @@ void WebRuntimeFeatures::EnableAccessibilityExposeDisplayNone(bool enable) {
RuntimeEnabledFeatures::SetAccessibilityExposeDisplayNoneEnabled(enable);
}
+void WebRuntimeFeatures::EnableAccessibilityExposeHTMLElement(bool enable) {
+ RuntimeEnabledFeatures::SetAccessibilityExposeHTMLElementEnabled(enable);
+}
+
void WebRuntimeFeatures::EnableAccessibilityObjectModel(bool enable) {
RuntimeEnabledFeatures::SetAccessibilityObjectModelEnabled(enable);
}
@@ -141,10 +155,6 @@ void WebRuntimeFeatures::EnableCookiesWithoutSameSiteMustBeSecure(bool enable) {
RuntimeEnabledFeatures::SetCookiesWithoutSameSiteMustBeSecureEnabled(enable);
}
-void WebRuntimeFeatures::EnableWasmCodeCache(bool enable) {
- RuntimeEnabledFeatures::SetWasmCodeCacheEnabled(enable);
-}
-
void WebRuntimeFeatures::EnableCanvas2dImageChromium(bool enable) {
RuntimeEnabledFeatures::SetCanvas2dImageChromiumEnabled(enable);
}
@@ -209,10 +219,6 @@ void WebRuntimeFeatures::EnableForceTallerSelectPopup(bool enable) {
RuntimeEnabledFeatures::SetForceTallerSelectPopupEnabled(enable);
}
-void WebRuntimeFeatures::EnableFormControlsRefresh(bool enable) {
- RuntimeEnabledFeatures::SetFormControlsRefreshEnabled(enable);
-}
-
void WebRuntimeFeatures::EnableGenericSensorExtraClasses(bool enable) {
RuntimeEnabledFeatures::SetSensorExtraClassesEnabled(enable);
}
@@ -229,18 +235,6 @@ void WebRuntimeFeatures::EnableInputMultipleFieldsUI(bool enable) {
RuntimeEnabledFeatures::SetInputMultipleFieldsUIEnabled(enable);
}
-void WebRuntimeFeatures::EnableBuiltInModuleAll(bool enable) {
- RuntimeEnabledFeatures::SetBuiltInModuleAllEnabled(enable);
-}
-
-void WebRuntimeFeatures::EnableBuiltInModuleInfra(bool enable) {
- RuntimeEnabledFeatures::SetBuiltInModuleInfraEnabled(enable);
-}
-
-void WebRuntimeFeatures::EnableBuiltInModuleKvStorage(bool enable) {
- RuntimeEnabledFeatures::SetBuiltInModuleKvStorageEnabled(enable);
-}
-
void WebRuntimeFeatures::EnableLayoutNG(bool enable) {
RuntimeEnabledFeatures::SetLayoutNGEnabled(enable);
}
@@ -329,15 +323,24 @@ void WebRuntimeFeatures::EnablePaymentApp(bool enable) {
RuntimeEnabledFeatures::SetPaymentAppEnabled(enable);
}
+void WebRuntimeFeatures::EnablePaymentHandlerMinimalUI(bool enable) {
+ RuntimeEnabledFeatures::SetPaymentHandlerMinimalUIEnabled(enable);
+}
+
void WebRuntimeFeatures::EnablePaymentRequest(bool enable) {
RuntimeEnabledFeatures::SetPaymentRequestEnabled(enable);
if (!enable) {
// Disable features that depend on Payment Request API.
- RuntimeEnabledFeatures::SetPaymentMethodChangeEventEnabled(false);
RuntimeEnabledFeatures::SetPaymentAppEnabled(false);
+ RuntimeEnabledFeatures::SetPaymentHandlerMinimalUIEnabled(false);
+ RuntimeEnabledFeatures::SetPaymentMethodChangeEventEnabled(false);
}
}
+void WebRuntimeFeatures::EnablePercentBasedScrolling(bool enable) {
+ RuntimeEnabledFeatures::SetPercentBasedScrollingEnabled(enable);
+}
+
void WebRuntimeFeatures::EnablePerformanceManagerInstrumentation(bool enable) {
RuntimeEnabledFeatures::SetPerformanceManagerInstrumentationEnabled(enable);
}
@@ -374,10 +377,6 @@ void WebRuntimeFeatures::EnableScriptedSpeechSynthesis(bool enable) {
RuntimeEnabledFeatures::SetScriptedSpeechSynthesisEnabled(enable);
}
-void WebRuntimeFeatures::EnableUpdateHoverAtBeginFrame(bool enable) {
- RuntimeEnabledFeatures::SetUpdateHoverAtBeginFrameEnabled(enable);
-}
-
void WebRuntimeFeatures::EnableUserActivationPostMessageTransfer(bool enable) {
RuntimeEnabledFeatures::SetUserActivationPostMessageTransferEnabled(enable);
}
@@ -430,10 +429,6 @@ void WebRuntimeFeatures::EnablePreciseMemoryInfo(bool enable) {
RuntimeEnabledFeatures::SetPreciseMemoryInfoEnabled(enable);
}
-void WebRuntimeFeatures::EnablePrintBrowser(bool enable) {
- RuntimeEnabledFeatures::SetPrintBrowserEnabled(enable);
-}
-
void WebRuntimeFeatures::EnableV8IdleTasks(bool enable) {
RuntimeEnabledFeatures::SetV8IdleTasksEnabled(enable);
}
@@ -466,24 +461,12 @@ void WebRuntimeFeatures::EnableWebXRARModule(bool enable) {
RuntimeEnabledFeatures::SetWebXRARModuleEnabled(enable);
}
-void WebRuntimeFeatures::EnableWebXRARDOMOverlay(bool enable) {
- RuntimeEnabledFeatures::SetWebXRARDOMOverlayEnabled(enable);
-}
-
-void WebRuntimeFeatures::EnableWebXRAnchors(bool enable) {
- RuntimeEnabledFeatures::SetWebXRAnchorsEnabled(enable);
-}
-
-void WebRuntimeFeatures::EnableWebXrGamepadModule(bool enable) {
- RuntimeEnabledFeatures::SetWebXrGamepadModuleEnabled(enable);
-}
-
void WebRuntimeFeatures::EnableWebXRHitTest(bool enable) {
RuntimeEnabledFeatures::SetWebXRHitTestEnabled(enable);
}
-void WebRuntimeFeatures::EnableWebXRPlaneDetection(bool enable) {
- RuntimeEnabledFeatures::SetWebXRPlaneDetectionEnabled(enable);
+void WebRuntimeFeatures::EnableWebXRIncubations(bool enable) {
+ RuntimeEnabledFeatures::SetWebXRIncubationsEnabled(enable);
}
void WebRuntimeFeatures::EnablePresentationAPI(bool enable) {
@@ -514,14 +497,6 @@ void WebRuntimeFeatures::EnableExpensiveBackgroundTimerThrottling(bool enable) {
RuntimeEnabledFeatures::SetExpensiveBackgroundTimerThrottlingEnabled(enable);
}
-void WebRuntimeFeatures::EnableFetchMetadata(bool enable) {
- RuntimeEnabledFeatures::SetFetchMetadataEnabled(enable);
-}
-
-void WebRuntimeFeatures::EnableFetchMetadataDestination(bool enable) {
- RuntimeEnabledFeatures::SetFetchMetadataDestinationEnabled(enable);
-}
-
void WebRuntimeFeatures::EnableTimerThrottlingForBackgroundTabs(bool enable) {
RuntimeEnabledFeatures::SetTimerThrottlingForBackgroundTabsEnabled(enable);
}
@@ -552,10 +527,6 @@ void WebRuntimeFeatures::EnableVideoRotateToFullscreen(bool enable) {
RuntimeEnabledFeatures::SetVideoRotateToFullscreenEnabled(enable);
}
-void WebRuntimeFeatures::EnableVideoFullscreenDetection(bool enable) {
- RuntimeEnabledFeatures::SetVideoFullscreenDetectionEnabled(enable);
-}
-
void WebRuntimeFeatures::EnableVideoPlaybackQuality(bool enable) {
RuntimeEnabledFeatures::SetVideoPlaybackQualityEnabled(enable);
}
@@ -668,10 +639,6 @@ void WebRuntimeFeatures::EnableSmsReceiver(bool enable) {
RuntimeEnabledFeatures::SetSmsReceiverEnabled(enable);
}
-void WebRuntimeFeatures::EnableDisplayLocking(bool enable) {
- RuntimeEnabledFeatures::SetDisplayLockingEnabled(enable);
-}
-
void WebRuntimeFeatures::EnableConsolidatedMovementXY(bool enable) {
RuntimeEnabledFeatures::SetConsolidatedMovementXYEnabled(enable);
}
@@ -696,4 +663,12 @@ void WebRuntimeFeatures::EnableAcceleratedSmallCanvases(bool enable) {
RuntimeEnabledFeatures::SetAcceleratedSmallCanvasesEnabled(enable);
}
+void WebRuntimeFeatures::EnableTrustTokens(bool enable) {
+ RuntimeEnabledFeatures::SetTrustTokensEnabled(enable);
+}
+
+void WebRuntimeFeatures::EnableInstalledApp(bool enable) {
+ RuntimeEnabledFeatures::SetInstalledAppEnabled(enable);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_touch_event.cc b/chromium/third_party/blink/renderer/platform/exported/web_touch_event.cc
deleted file mode 100644
index e358ccb9d5f..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_touch_event.cc
+++ /dev/null
@@ -1,37 +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/public/platform/web_touch_event.h"
-
-namespace blink {
-
-WebTouchEvent WebTouchEvent::FlattenTransform() const {
- WebTouchEvent transformed_event = *this;
- for (unsigned i = 0; i < touches_length; ++i) {
- transformed_event.touches[i] = TouchPointInRootFrame(i);
- }
- transformed_event.frame_translate_.x = 0;
- transformed_event.frame_translate_.y = 0;
- transformed_event.frame_scale_ = 1;
-
- return transformed_event;
-}
-
-WebTouchPoint WebTouchEvent::TouchPointInRootFrame(unsigned point) const {
- DCHECK_LT(point, touches_length);
- if (point >= touches_length)
- return WebTouchPoint();
-
- WebTouchPoint transformed_point = touches[point];
- transformed_point.radius_x /= frame_scale_;
- transformed_point.radius_y /= frame_scale_;
- transformed_point.SetPositionInWidget(
- (transformed_point.PositionInWidget().x / frame_scale_) +
- frame_translate_.x,
- (transformed_point.PositionInWidget().y / frame_scale_) +
- frame_translate_.y);
- return transformed_point;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_url_error.cc b/chromium/third_party/blink/renderer/platform/exported/web_url_error.cc
index 9bc40c70762..c06728263cb 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_url_error.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_url_error.cc
@@ -15,11 +15,13 @@ WebURLError::WebURLError(int reason, const WebURL& url)
WebURLError::WebURLError(int reason,
int extended_reason,
+ net::ResolveErrorInfo resolve_error_info,
HasCopyInCache has_copy_in_cache,
IsWebSecurityViolation is_web_security_violation,
const WebURL& url)
: reason_(reason),
extended_reason_(extended_reason),
+ resolve_error_info_(resolve_error_info),
has_copy_in_cache_(has_copy_in_cache == HasCopyInCache::kTrue),
is_web_security_violation_(is_web_security_violation ==
IsWebSecurityViolation::kTrue),
@@ -27,6 +29,18 @@ WebURLError::WebURLError(int reason,
DCHECK_NE(reason_, 0);
}
+WebURLError::WebURLError(network::BlockedByResponseReason blocked_reason,
+ net::ResolveErrorInfo resolve_error_info,
+ HasCopyInCache has_copy_in_cache,
+ const WebURL& url)
+ : reason_(net::ERR_BLOCKED_BY_RESPONSE),
+ extended_reason_(0),
+ resolve_error_info_(resolve_error_info),
+ has_copy_in_cache_(has_copy_in_cache == HasCopyInCache::kTrue),
+ is_web_security_violation_(false),
+ url_(url),
+ blocked_by_response_reason_(blocked_reason) {}
+
WebURLError::WebURLError(const network::CorsErrorStatus& cors_error_status,
HasCopyInCache has_copy_in_cache,
const WebURL& url)
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_url_load_timing.cc b/chromium/third_party/blink/renderer/platform/exported/web_url_load_timing.cc
deleted file mode 100644
index 861cbdc1f72..00000000000
--- a/chromium/third_party/blink/renderer/platform/exported/web_url_load_timing.cc
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright (C) 2010 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/public/platform/web_url_load_timing.h"
-
-#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h"
-
-namespace blink {
-
-void WebURLLoadTiming::Initialize() {
- private_ = ResourceLoadTiming::Create();
-}
-
-void WebURLLoadTiming::Reset() {
- private_.Reset();
-}
-
-void WebURLLoadTiming::Assign(const WebURLLoadTiming& other) {
- private_ = other.private_;
-}
-
-base::TimeTicks WebURLLoadTiming::RequestTime() const {
- return private_->RequestTime();
-}
-
-void WebURLLoadTiming::SetRequestTime(base::TimeTicks time) {
- private_->SetRequestTime(time);
-}
-
-base::TimeTicks WebURLLoadTiming::ProxyStart() const {
- return private_->ProxyStart();
-}
-
-void WebURLLoadTiming::SetProxyStart(base::TimeTicks start) {
- private_->SetProxyStart(start);
-}
-
-base::TimeTicks WebURLLoadTiming::ProxyEnd() const {
- return private_->ProxyEnd();
-}
-
-void WebURLLoadTiming::SetProxyEnd(base::TimeTicks end) {
- private_->SetProxyEnd(end);
-}
-
-base::TimeTicks WebURLLoadTiming::DnsStart() const {
- return private_->DnsStart();
-}
-
-void WebURLLoadTiming::SetDNSStart(base::TimeTicks start) {
- private_->SetDnsStart(start);
-}
-
-base::TimeTicks WebURLLoadTiming::DnsEnd() const {
- return private_->DnsEnd();
-}
-
-void WebURLLoadTiming::SetDNSEnd(base::TimeTicks end) {
- private_->SetDnsEnd(end);
-}
-
-base::TimeTicks WebURLLoadTiming::ConnectStart() const {
- return private_->ConnectStart();
-}
-
-void WebURLLoadTiming::SetConnectStart(base::TimeTicks start) {
- private_->SetConnectStart(start);
-}
-
-base::TimeTicks WebURLLoadTiming::ConnectEnd() const {
- return private_->ConnectEnd();
-}
-
-void WebURLLoadTiming::SetConnectEnd(base::TimeTicks end) {
- private_->SetConnectEnd(end);
-}
-
-base::TimeTicks WebURLLoadTiming::WorkerStart() const {
- return private_->WorkerStart();
-}
-
-void WebURLLoadTiming::SetWorkerStart(base::TimeTicks start) {
- private_->SetWorkerStart(start);
-}
-
-base::TimeTicks WebURLLoadTiming::WorkerReady() const {
- return private_->WorkerReady();
-}
-
-void WebURLLoadTiming::SetWorkerReady(base::TimeTicks ready) {
- private_->SetWorkerReady(ready);
-}
-
-base::TimeTicks WebURLLoadTiming::SendStart() const {
- return private_->SendStart();
-}
-
-void WebURLLoadTiming::SetSendStart(base::TimeTicks start) {
- private_->SetSendStart(start);
-}
-
-base::TimeTicks WebURLLoadTiming::SendEnd() const {
- return private_->SendEnd();
-}
-
-void WebURLLoadTiming::SetSendEnd(base::TimeTicks end) {
- private_->SetSendEnd(end);
-}
-
-base::TimeTicks WebURLLoadTiming::ReceiveHeadersStart() const {
- return private_->ReceiveHeadersStart();
-}
-
-void WebURLLoadTiming::SetReceiveHeadersStart(base::TimeTicks start) {
- private_->SetReceiveHeadersStart(start);
-}
-
-base::TimeTicks WebURLLoadTiming::ReceiveHeadersEnd() const {
- return private_->ReceiveHeadersEnd();
-}
-
-void WebURLLoadTiming::SetReceiveHeadersEnd(base::TimeTicks end) {
- private_->SetReceiveHeadersEnd(end);
-}
-
-base::TimeTicks WebURLLoadTiming::SslStart() const {
- return private_->SslStart();
-}
-
-void WebURLLoadTiming::SetSSLStart(base::TimeTicks start) {
- private_->SetSslStart(start);
-}
-
-base::TimeTicks WebURLLoadTiming::SslEnd() const {
- return private_->SslEnd();
-}
-
-void WebURLLoadTiming::SetSSLEnd(base::TimeTicks end) {
- private_->SetSslEnd(end);
-}
-
-base::TimeTicks WebURLLoadTiming::PushStart() const {
- return private_->PushStart();
-}
-
-void WebURLLoadTiming::SetPushStart(base::TimeTicks start) {
- private_->SetPushStart(start);
-}
-
-base::TimeTicks WebURLLoadTiming::PushEnd() const {
- return private_->PushEnd();
-}
-
-void WebURLLoadTiming::SetPushEnd(base::TimeTicks end) {
- private_->SetPushEnd(end);
-}
-
-WebURLLoadTiming::WebURLLoadTiming(scoped_refptr<ResourceLoadTiming> value)
- : private_(std::move(value)) {}
-
-WebURLLoadTiming& WebURLLoadTiming::operator=(
- scoped_refptr<ResourceLoadTiming> value) {
- private_ = std::move(value);
- return *this;
-}
-
-WebURLLoadTiming::operator scoped_refptr<ResourceLoadTiming>() const {
- return private_.Get();
-}
-
-WebURLLoadTiming WebURLLoadTiming::DeepCopy() const {
- return private_->DeepCopy();
-}
-
-bool WebURLLoadTiming::operator==(const WebURLLoadTiming& other) const {
- return *private_ == *other.private_;
-}
-
-} // namespace blink
-
-namespace WTF {
-
-CrossThreadCopier<blink::WebURLLoadTiming>::Type CrossThreadCopier<
- blink::WebURLLoadTiming>::Copy(const blink::WebURLLoadTiming& timing) {
- return timing.DeepCopy();
-}
-
-} // namespace WTF
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_url_request.cc b/chromium/third_party/blink/renderer/platform/exported/web_url_request.cc
index 50ebdbbad7c..651e79a8859 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_url_request.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_url_request.cc
@@ -35,12 +35,15 @@
#include "base/time/time.h"
#include "net/base/load_flags.h"
#include "services/network/public/cpp/features.h"
+#include "services/network/public/cpp/optional_trust_token_params.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
+#include "third_party/blink/public/platform/url_conversion.h"
#include "third_party/blink/public/platform/web_http_body.h"
#include "third_party/blink/public/platform/web_http_header_visitor.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/platform/web_url.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/weborigin/referrer.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -50,43 +53,74 @@ using blink::mojom::FetchCacheMode;
namespace blink {
-WebURLRequest::ExtraData::ExtraData() : render_frame_id_(MSG_ROUTING_NONE) {}
+// This is complementary to ConvertNetPriorityToWebKitPriority, defined in
+// service_worker_context_client.cc.
+net::RequestPriority ConvertWebKitPriorityToNetPriority(
+ WebURLRequest::Priority priority) {
+ switch (priority) {
+ case WebURLRequest::Priority::kVeryHigh:
+ return net::HIGHEST;
+
+ case WebURLRequest::Priority::kHigh:
+ return net::MEDIUM;
+
+ case WebURLRequest::Priority::kMedium:
+ return net::LOW;
-// The purpose of this struct is to permit allocating a ResourceRequest on the
-// heap, which is otherwise disallowed by DISALLOW_NEW annotation on
-// ResourceRequest.
-// TODO(keishi): Replace with GCWrapper<ResourceRequest>
-struct WebURLRequest::ResourceRequestContainer {
- ResourceRequestContainer() = default;
- explicit ResourceRequestContainer(const ResourceRequest& r)
- : resource_request(r) {}
+ case WebURLRequest::Priority::kLow:
+ return net::LOWEST;
- ResourceRequest resource_request;
-};
+ case WebURLRequest::Priority::kVeryLow:
+ return net::IDLE;
+
+ case WebURLRequest::Priority::kUnresolved:
+ default:
+ NOTREACHED();
+ return net::LOW;
+ }
+}
+
+WebURLRequest::ExtraData::ExtraData() : render_frame_id_(MSG_ROUTING_NONE) {}
WebURLRequest::~WebURLRequest() = default;
WebURLRequest::WebURLRequest()
- : owned_resource_request_(new ResourceRequestContainer()),
- resource_request_(&owned_resource_request_->resource_request) {}
+ : owned_resource_request_(std::make_unique<ResourceRequest>()),
+ resource_request_(owned_resource_request_.get()) {}
+
+WebURLRequest::WebURLRequest(WebURLRequest&& src) {
+ *this = std::move(src);
+}
-WebURLRequest::WebURLRequest(const WebURLRequest& r)
- : owned_resource_request_(
- new ResourceRequestContainer(*r.resource_request_)),
- resource_request_(&owned_resource_request_->resource_request) {}
+WebURLRequest& WebURLRequest::operator=(WebURLRequest&& src) {
+ if (this == &src) {
+ return *this;
+ }
+ if (src.owned_resource_request_) {
+ owned_resource_request_ = std::move(src.owned_resource_request_);
+ resource_request_ = owned_resource_request_.get();
+ } else {
+ owned_resource_request_ = std::make_unique<ResourceRequest>();
+ resource_request_ = owned_resource_request_.get();
+ CopyFrom(src);
+ }
+ src.resource_request_ = nullptr;
+ return *this;
+}
WebURLRequest::WebURLRequest(const WebURL& url) : WebURLRequest() {
SetUrl(url);
}
-WebURLRequest& WebURLRequest::operator=(const WebURLRequest& r) {
+void WebURLRequest::CopyFrom(const WebURLRequest& r) {
// Copying subclasses that have different m_resourceRequest ownership
// semantics via this operator is just not supported.
DCHECK(owned_resource_request_);
- DCHECK(resource_request_);
- if (&r != this)
- *resource_request_ = *r.resource_request_;
- return *this;
+ DCHECK_EQ(owned_resource_request_.get(), resource_request_);
+ DCHECK(owned_resource_request_->IsNull());
+ DCHECK(this != &r);
+ resource_request_->CopyHeadFrom(*r.resource_request_);
+ resource_request_->SetHttpBody(r.resource_request_->HttpBody());
}
bool WebURLRequest::IsNull() const {
@@ -101,11 +135,12 @@ void WebURLRequest::SetUrl(const WebURL& url) {
resource_request_->SetUrl(url);
}
-WebURL WebURLRequest::SiteForCookies() const {
+const net::SiteForCookies& WebURLRequest::SiteForCookies() const {
return resource_request_->SiteForCookies();
}
-void WebURLRequest::SetSiteForCookies(const WebURL& site_for_cookies) {
+void WebURLRequest::SetSiteForCookies(
+ const net::SiteForCookies& site_for_cookies) {
resource_request_->SetSiteForCookies(site_for_cookies);
}
@@ -166,24 +201,10 @@ WebString WebURLRequest::HttpHeaderField(const WebString& name) const {
void WebURLRequest::SetHttpHeaderField(const WebString& name,
const WebString& value) {
- CHECK(!DeprecatedEqualIgnoringCase(name, "referer"));
+ CHECK(!EqualIgnoringASCIICase(name, "referer"));
resource_request_->SetHttpHeaderField(name, value);
}
-void WebURLRequest::SetHttpReferrer(
- const WebString& web_referrer,
- network::mojom::ReferrerPolicy referrer_policy) {
- // WebString doesn't have the distinction between empty and null. We use
- // the null WTFString for referrer.
- DCHECK_EQ(Referrer::NoReferrer(), String());
- String referrer =
- web_referrer.IsEmpty() ? Referrer::NoReferrer() : String(web_referrer);
- // TODO(domfarolino): Stop storing ResourceRequest's generated referrer as a
- // header and instead use a separate member. See https://crbug.com/850813.
- resource_request_->SetHttpReferrer(Referrer(referrer, referrer_policy));
- resource_request_->SetReferrerString(referrer);
-}
-
void WebURLRequest::AddHttpHeaderField(const WebString& name,
const WebString& value) {
resource_request_->AddHttpHeaderField(name, value);
@@ -227,6 +248,24 @@ mojom::RequestContextType WebURLRequest::GetRequestContext() const {
return resource_request_->GetRequestContext();
}
+network::mojom::RequestDestination WebURLRequest::GetRequestDestination()
+ const {
+ return resource_request_->GetRequestDestination();
+}
+
+void WebURLRequest::SetReferrerString(const WebString& referrer) {
+ resource_request_->SetReferrerString(referrer);
+}
+
+void WebURLRequest::SetReferrerPolicy(
+ network::mojom::ReferrerPolicy referrer_policy) {
+ resource_request_->SetReferrerPolicy(referrer_policy);
+}
+
+WebString WebURLRequest::ReferrerString() const {
+ return resource_request_->ReferrerString();
+}
+
network::mojom::ReferrerPolicy WebURLRequest::GetReferrerPolicy() const {
return resource_request_->GetReferrerPolicy();
}
@@ -248,6 +287,11 @@ void WebURLRequest::SetRequestContext(
resource_request_->SetRequestContext(request_context);
}
+void WebURLRequest::SetRequestDestination(
+ network::mojom::RequestDestination destination) {
+ resource_request_->SetRequestDestination(destination);
+}
+
int WebURLRequest::RequestorID() const {
return resource_request_->RequestorID();
}
@@ -333,11 +377,12 @@ void WebURLRequest::SetPreviewsState(
return resource_request_->SetPreviewsState(previews_state);
}
-WebURLRequest::ExtraData* WebURLRequest::GetExtraData() const {
+const scoped_refptr<WebURLRequest::ExtraData>& WebURLRequest::GetExtraData()
+ const {
return resource_request_->GetExtraData();
}
-void WebURLRequest::SetExtraData(std::unique_ptr<ExtraData> extra_data) {
+void WebURLRequest::SetExtraData(scoped_refptr<ExtraData> extra_data) {
resource_request_->SetExtraData(std::move(extra_data));
}
@@ -504,6 +549,10 @@ base::Optional<base::UnguessableToken> WebURLRequest::RecursivePrefetchToken()
return resource_request_->RecursivePrefetchToken();
}
+network::OptionalTrustTokenParams WebURLRequest::TrustTokenParams() const {
+ return ConvertTrustTokenParams(resource_request_->TrustTokenParams());
+}
+
WebURLRequest::WebURLRequest(ResourceRequest& r) : resource_request_(&r) {}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_url_request_test.cc b/chromium/third_party/blink/renderer/platform/exported/web_url_request_test.cc
index bce21fa0f57..c03d48e319c 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_url_request_test.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_url_request_test.cc
@@ -40,9 +40,9 @@ class RequestTestExtraData : public WebURLRequest::ExtraData {
public:
explicit RequestTestExtraData(bool* alive) : alive_(alive) { *alive = true; }
+ private:
~RequestTestExtraData() override { *alive_ = false; }
- private:
bool* alive_;
};
@@ -52,14 +52,15 @@ TEST(WebURLRequestTest, ExtraData) {
bool alive = false;
{
WebURLRequest url_request;
- auto extra_data = std::make_unique<RequestTestExtraData>(&alive);
+ auto extra_data = base::MakeRefCounted<RequestTestExtraData>(&alive);
EXPECT_TRUE(alive);
auto* raw_extra_data_pointer = extra_data.get();
url_request.SetExtraData(std::move(extra_data));
EXPECT_EQ(raw_extra_data_pointer, url_request.GetExtraData());
{
- WebURLRequest other_url_request = url_request;
+ WebURLRequest other_url_request;
+ other_url_request.CopyFrom(url_request);
EXPECT_TRUE(alive);
EXPECT_EQ(raw_extra_data_pointer, other_url_request.GetExtraData());
EXPECT_EQ(raw_extra_data_pointer, url_request.GetExtraData());
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 e8eca6afa73..6723c059edb 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
@@ -36,11 +36,11 @@
#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
+#include "services/network/public/mojom/load_timing_info.mojom.h"
#include "third_party/blink/public/platform/web_http_header_visitor.h"
#include "third_party/blink/public/platform/web_http_load_info.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_url.h"
-#include "third_party/blink/public/platform/web_url_load_timing.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_load_info.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
@@ -99,10 +99,27 @@ void WebURLResponse::SetConnectionReused(bool connection_reused) {
resource_response_->SetConnectionReused(connection_reused);
}
-void WebURLResponse::SetLoadTiming(const WebURLLoadTiming& timing) {
- scoped_refptr<ResourceLoadTiming> load_timing =
- scoped_refptr<ResourceLoadTiming>(timing);
- resource_response_->SetResourceLoadTiming(std::move(load_timing));
+void WebURLResponse::SetLoadTiming(
+ const network::mojom::LoadTimingInfo& mojo_timing) {
+ auto timing = ResourceLoadTiming::Create();
+ timing->SetRequestTime(mojo_timing.request_start);
+ timing->SetProxyStart(mojo_timing.proxy_resolve_start);
+ timing->SetProxyEnd(mojo_timing.proxy_resolve_end);
+ timing->SetDnsStart(mojo_timing.connect_timing.dns_start);
+ timing->SetDnsEnd(mojo_timing.connect_timing.dns_end);
+ timing->SetConnectStart(mojo_timing.connect_timing.connect_start);
+ 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->SetSendStart(mojo_timing.send_start);
+ timing->SetSendEnd(mojo_timing.send_end);
+ timing->SetReceiveHeadersStart(mojo_timing.receive_headers_start);
+ timing->SetReceiveHeadersEnd(mojo_timing.receive_headers_end);
+ timing->SetSslStart(mojo_timing.connect_timing.ssl_start);
+ timing->SetSslEnd(mojo_timing.connect_timing.ssl_end);
+ timing->SetPushStart(mojo_timing.push_start);
+ timing->SetPushEnd(mojo_timing.push_end);
+ resource_response_->SetResourceLoadTiming(std::move(timing));
}
void WebURLResponse::SetHTTPLoadInfo(const WebHTTPLoadInfo& value) {
@@ -244,6 +261,10 @@ void WebURLResponse::SetIsLegacyTLSVersion(bool value) {
resource_response_->SetIsLegacyTLSVersion(value);
}
+void WebURLResponse::SetTimingAllowPassed(bool value) {
+ resource_response_->SetTimingAllowPassed(value);
+}
+
void WebURLResponse::SetSecurityStyle(SecurityStyle security_style) {
resource_response_->SetSecurityStyle(security_style);
}
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_video_frame_submitter.cc b/chromium/third_party/blink/renderer/platform/exported/web_video_frame_submitter.cc
index 93a3d2217ae..df11208b5df 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_video_frame_submitter.cc
+++ b/chromium/third_party/blink/renderer/platform/exported/web_video_frame_submitter.cc
@@ -26,10 +26,12 @@ namespace blink {
std::unique_ptr<WebVideoFrameSubmitter> WebVideoFrameSubmitter::Create(
WebContextProviderCallback context_provider_callback,
+ cc::PlaybackRoughnessReportingCallback roughness_reporting_callback,
const cc::LayerTreeSettings& settings,
bool use_sync_primitives) {
return std::make_unique<VideoFrameSubmitter>(
std::move(context_provider_callback),
+ std::move(roughness_reporting_callback),
std::make_unique<VideoFrameResourceProvider>(settings,
use_sync_primitives));
}
diff --git a/chromium/third_party/blink/renderer/platform/file_metadata.cc b/chromium/third_party/blink/renderer/platform/file_metadata.cc
index c78e471f403..51d0190b0b9 100644
--- a/chromium/third_party/blink/renderer/platform/file_metadata.cc
+++ b/chromium/third_party/blink/renderer/platform/file_metadata.cc
@@ -36,9 +36,9 @@
#include "base/optional.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/base/filename_util.h"
+#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/file/file_utilities.mojom-blink.h"
#include "third_party/blink/public/platform/file_path_conversion.h"
-#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/thread_specific.h"
@@ -92,14 +92,14 @@ void RebindFileUtilitiesForTesting() {
if (host) {
host.Unbind().reset();
}
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
host.BindNewPipeAndPassReceiver());
}
bool GetFileMetadata(const String& path, FileMetadata& metadata) {
auto& host = GetFileUtilitiesHost();
if (!host) {
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
host.BindNewPipeAndPassReceiver());
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.cc b/chromium/third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.cc
index c9a48d57f2f..48295090b57 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/platform/fonts/android/font_unique_name_lookup_android.h"
#include "mojo/public/mojom/base/shared_memory.mojom-blink.h"
-#include "third_party/blink/public/platform/interface_provider.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/renderer/platform/runtime_enabled_features.h"
@@ -86,7 +86,7 @@ void FontUniqueNameLookupAndroid::EnsureServiceConnected() {
if (service_)
return;
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
service_.BindNewPipeAndPassReceiver());
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font.cc b/chromium/third_party/blink/renderer/platform/fonts/font.cc
index 2b110b2e0e0..7a9414845a0 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font.cc
@@ -48,27 +48,20 @@
namespace blink {
-Font::Font() : can_shape_word_by_word_(0), shape_word_by_word_computed_(0) {}
-
-Font::Font(const FontDescription& fd)
- : font_description_(fd),
- can_shape_word_by_word_(0),
- shape_word_by_word_computed_(0) {}
-
-Font::Font(const Font& other)
- : font_description_(other.font_description_),
- font_fallback_list_(other.font_fallback_list_),
- // TODO(yosin): We should have a comment the reason why don't we copy
- // |m_canShapeWordByWord| and |m_shapeWordByWordComputed| from |other|,
- // since |operator=()| copies them from |other|.
- can_shape_word_by_word_(0),
- shape_word_by_word_computed_(0) {}
+Font::Font() = default;
+
+Font::Font(const FontDescription& fd) : font_description_(fd) {}
+
+Font::Font(const FontDescription& font_description, FontSelector* font_selector)
+ : font_description_(font_description),
+ font_fallback_list_(
+ font_selector ? FontFallbackList::Create(font_selector) : nullptr) {}
+
+Font::Font(const Font& other) = default;
Font& Font::operator=(const Font& other) {
font_description_ = other.font_description_;
font_fallback_list_ = other.font_fallback_list_;
- can_shape_word_by_word_ = other.can_shape_word_by_word_;
- shape_word_by_word_computed_ = other.shape_word_by_word_computed_;
return *this;
}
@@ -91,18 +84,6 @@ bool Font::operator==(const Font& other) const {
: 0);
}
-void Font::Update(FontSelector* font_selector) const {
- // FIXME: It is pretty crazy that we are willing to just poke into a RefPtr,
- // but it ends up being reasonably safe (because inherited fonts in the render
- // tree pick up the new style anyway. Other copies are transient, e.g., the
- // state in the GraphicsContext, and won't stick around long enough to get you
- // in trouble). Still, this is pretty disgusting, and could eventually be
- // rectified by using RefPtrs for Fonts themselves.
- if (!font_fallback_list_)
- font_fallback_list_ = FontFallbackList::Create();
- font_fallback_list_->Invalidate(font_selector);
-}
-
namespace {
void DrawBlobs(cc::PaintCanvas* canvas,
@@ -217,7 +198,10 @@ bool Font::DrawBidiText(cc::PaintCanvas* canvas,
TextRunPaintInfo subrun_info(subrun);
- ShapeResultBloberizer bloberizer(*this, device_scale_factor);
+ // Fix regression with -ftrivial-auto-var-init=pattern. See
+ // crbug.com/1055652.
+ STACK_UNINITIALIZED ShapeResultBloberizer bloberizer(*this,
+ device_scale_factor);
ShapeResultBuffer buffer;
word_shaper.FillResultBuffer(subrun_info, &buffer);
float run_width = bloberizer.FillGlyphs(subrun_info, buffer);
@@ -422,31 +406,15 @@ int Font::OffsetForPosition(const TextRun& run,
}
ShapeCache* Font::GetShapeCache() const {
- return font_fallback_list_->GetShapeCache(font_description_);
+ return EnsureFontFallbackList()->GetShapeCache(font_description_);
}
bool Font::CanShapeWordByWord() const {
- if (!shape_word_by_word_computed_) {
- can_shape_word_by_word_ = ComputeCanShapeWordByWord();
- shape_word_by_word_computed_ = true;
- }
- return can_shape_word_by_word_;
-}
-
-bool Font::ComputeCanShapeWordByWord() const {
- if (!GetFontDescription().GetTypesettingFeatures())
- return true;
-
- if (!PrimaryFont())
- return false;
-
- const FontPlatformData& platform_data = PrimaryFont()->PlatformData();
- TypesettingFeatures features = GetFontDescription().GetTypesettingFeatures();
- return !platform_data.HasSpaceInLigaturesOrKerning(features);
+ return EnsureFontFallbackList()->CanShapeWordByWord(GetFontDescription());
}
void Font::ReportNotDefGlyph() const {
- FontSelector* fontSelector = font_fallback_list_->GetFontSelector();
+ FontSelector* fontSelector = EnsureFontFallbackList()->GetFontSelector();
// We have a few non-DOM usages of Font code, for example in DragImage::Create
// and in EmbeddedObjectPainter::paintReplaced. In those cases, we can't
// retrieve a font selector as our connection to a Document object to report
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font.h b/chromium/third_party/blink/renderer/platform/fonts/font.h
index ca24f5f5e49..2aeb6057caa 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font.h
@@ -54,7 +54,6 @@ namespace blink {
struct CharacterRange;
class FloatPoint;
class FloatRect;
-class FontData;
class FontSelector;
class ShapeCache;
class TextRun;
@@ -66,7 +65,8 @@ class PLATFORM_EXPORT Font {
public:
Font();
- Font(const FontDescription&);
+ explicit Font(const FontDescription&);
+ Font(const FontDescription&, FontSelector*);
~Font();
Font(const Font&);
@@ -79,8 +79,6 @@ class PLATFORM_EXPORT Font {
return font_description_;
}
- void Update(FontSelector*) const;
-
enum CustomFontNotReadyAction {
kDoNotPaintIfFontNotReady,
kUseFallbackIfFontNotReady
@@ -203,7 +201,6 @@ class PLATFORM_EXPORT Font {
// loaded. This *should* not happen but in reality it does ever now and then
// when, for whatever reason, the last resort font cannot be loaded.
const SimpleFontData* PrimaryFont() const;
- const FontData* FontDataAt(unsigned) const;
// Access the shape cache associated with this particular font object.
// Should *not* be retained across layout calls as it may become invalid.
@@ -215,8 +212,7 @@ class PLATFORM_EXPORT Font {
bool CanShapeWordByWord() const;
void SetCanShapeWordByWordForTesting(bool b) {
- can_shape_word_by_word_ = b;
- shape_word_by_word_computed_ = true;
+ EnsureFontFallbackList()->SetCanShapeWordByWordForTesting(b);
}
void ReportNotDefGlyph() const;
@@ -226,12 +222,11 @@ class PLATFORM_EXPORT Font {
GlyphData GetEmphasisMarkGlyphData(const AtomicString&) const;
- bool ComputeCanShapeWordByWord() const;
-
public:
FontSelector* GetFontSelector() const;
FontFallbackIterator CreateFontFallbackIterator(
FontFallbackPriority fallback_priority) const {
+ EnsureFontFallbackList();
return FontFallbackIterator(font_description_, font_fallback_list_,
fallback_priority);
}
@@ -246,25 +241,20 @@ class PLATFORM_EXPORT Font {
}
private:
+ FontFallbackList* EnsureFontFallbackList() const {
+ if (!font_fallback_list_)
+ font_fallback_list_ = FontFallbackList::Create(nullptr);
+ return font_fallback_list_.get();
+ }
+
FontDescription font_description_;
mutable scoped_refptr<FontFallbackList> font_fallback_list_;
- mutable unsigned can_shape_word_by_word_ : 1;
- mutable unsigned shape_word_by_word_computed_ : 1;
-
- // For m_fontDescription & m_fontFallbackList access.
- friend class CachingWordShaper;
};
inline Font::~Font() = default;
inline const SimpleFontData* Font::PrimaryFont() const {
- DCHECK(font_fallback_list_);
- return font_fallback_list_->PrimarySimpleFontData(font_description_);
-}
-
-inline const FontData* Font::FontDataAt(unsigned index) const {
- DCHECK(font_fallback_list_);
- return font_fallback_list_->FontDataAt(font_description_, index);
+ return EnsureFontFallbackList()->PrimarySimpleFontData(font_description_);
}
inline FontSelector* Font::GetFontSelector() 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 b4a7e9509cf..396a27aa4fe 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_cache.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_cache.cc
@@ -386,6 +386,11 @@ void FontCache::InvalidateShapeCache() {
PurgeFallbackListShaperCache();
}
+void FontCache::InvalidateEnumerationCache() {
+ TRACE_EVENT0("fonts,ui", "FontCache::InvalidateEnumerationCache");
+ font_enumeration_cache_.clear();
+}
+
void FontCache::Purge(PurgeSeverity purge_severity) {
// Ideally we should never be forcing the purge while the
// FontCachePurgePreventer is in scope, but we call purge() at any timing
@@ -398,6 +403,7 @@ void FontCache::Purge(PurgeSeverity purge_severity) {
PurgePlatformFontDataCache();
PurgeFallbackListShaperCache();
+ InvalidateEnumerationCache();
}
void FontCache::AddClient(FontCacheClient* client) {
@@ -418,6 +424,10 @@ uint16_t FontCache::Generation() {
void FontCache::Invalidate() {
TRACE_EVENT0("fonts,ui", "FontCache::Invalidate");
font_platform_data_cache_.clear();
+ // TODO(https://crbug.com/1061630): Determine optimal cache invalidation
+ // strategy for enumeration. As implemented, the enumeration cache might not
+ // get invalidated when the system fonts change.
+ InvalidateEnumerationCache();
generation_++;
if (font_cache_clients_) {
@@ -524,4 +534,15 @@ FontCache::Bcp47Vector FontCache::GetBcp47LocaleForRequest(
return result;
}
+const std::vector<FontEnumerationEntry>& FontCache::EnumerateAvailableFonts() {
+ if (font_enumeration_cache_.size() == 0) {
+ base::TimeTicks enum_start = base::TimeTicks::Now();
+ font_enumeration_cache_ = EnumeratePlatformAvailableFonts();
+ base::TimeDelta time_taken = base::TimeTicks::Now() - enum_start;
+ UMA_HISTOGRAM_TIMES("Blink.Fonts.Enumeration.Duration", time_taken);
+ }
+
+ return font_enumeration_cache_;
+}
+
} // namespace blink
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 08c723bc646..41c63400fbb 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_cache.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_cache.h
@@ -90,21 +90,24 @@ enum class AlternateFontName {
kLastResort
};
+struct FontEnumerationEntry {
+ String postscript_name;
+ String full_name;
+ String family;
+};
+
typedef HashMap<unsigned,
std::unique_ptr<FontPlatformData>,
WTF::IntHash<unsigned>,
WTF::UnsignedWithZeroKeyHashTraits<unsigned>>
SizedFontPlatformDataSet;
-typedef HashMap<FontCacheKey,
- SizedFontPlatformDataSet,
- FontCacheKeyHash,
- FontCacheKeyTraits>
- FontPlatformDataCache;
+typedef HashMap<FontCacheKey, SizedFontPlatformDataSet> FontPlatformDataCache;
typedef HashMap<FallbackListCompositeKey,
std::unique_ptr<ShapeCache>,
FallbackListCompositeKeyHash,
FallbackListCompositeKeyTraits>
FallbackListShaperCache;
+typedef std::vector<FontEnumerationEntry> FontEnumerationCache;
class PLATFORM_EXPORT FontCache {
friend class FontCachePurgePreventer;
@@ -252,7 +255,13 @@ class PLATFORM_EXPORT FontCache {
ShouldRetain = kRetain,
bool subpixel_ascent_descent = false);
+ const std::vector<FontEnumerationEntry>& EnumerateAvailableFonts();
+ size_t EnumerationCacheSizeForTesting() {
+ return font_enumeration_cache_.size();
+ }
+
void InvalidateShapeCache();
+ void InvalidateEnumerationCache();
static void CrashWithFontInfo(const FontDescription*);
@@ -312,6 +321,7 @@ class PLATFORM_EXPORT FontCache {
const FontDescription&,
const FontFaceCreationParams&,
float font_size);
+ std::vector<FontEnumerationEntry> EnumeratePlatformAvailableFonts();
sk_sp<SkTypeface> CreateTypeface(const FontDescription&,
const FontFaceCreationParams&,
@@ -366,6 +376,9 @@ class PLATFORM_EXPORT FontCache {
FontPlatformDataCache font_platform_data_cache_;
FallbackListShaperCache fallback_list_shaper_cache_;
FontDataCache font_data_cache_;
+ // TODO(https://crbug.com/1061625): Move to the browser process for better
+ // resource utilization.
+ FontEnumerationCache font_enumeration_cache_;
void PurgePlatformFontDataCache();
void PurgeFallbackListShaperCache();
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 2160fcb2c3b..6b7c90a227d 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(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_cache_key.h b/chromium/third_party/blink/renderer/platform/fonts/font_cache_key.h
index 90063cb2eac..a860a0ad051 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_cache_key.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_cache_key.h
@@ -93,13 +93,19 @@ struct FontCacheKey {
}
bool operator==(const FontCacheKey& other) const {
+ bool variation_settings_equal =
+ (!variation_settings_ && !other.variation_settings_) ||
+ (variation_settings_ && other.variation_settings_ &&
+ *variation_settings_ == *other.variation_settings_);
return creation_params_ == other.creation_params_ &&
font_size_ == other.font_size_ && options_ == other.options_ &&
device_scale_factor_ == other.device_scale_factor_ &&
- variation_settings_ == other.variation_settings_ &&
+ variation_settings_equal &&
is_unique_match_ == other.is_unique_match_;
}
+ bool operator!=(const FontCacheKey& other) const { return !(*this == other); }
+
static constexpr unsigned PrecisionMultiplier() {
return kFontSizePrecisionMultiplier;
}
@@ -141,4 +147,23 @@ struct FontCacheKeyTraits : WTF::SimpleClassHashTraits<FontCacheKey> {
} // namespace blink
+namespace WTF {
+template <>
+struct DefaultHash<blink::FontCacheKey> {
+ STATIC_ONLY(DefaultHash);
+ typedef blink::FontCacheKeyHash Hash;
+};
+
+template <>
+struct HashTraits<blink::FontCacheKey>
+ : WTF::SimpleClassHashTraits<blink::FontCacheKey> {
+ STATIC_ONLY(HashTraits);
+
+ // std::string's empty state need not be zero in all implementations,
+ // and it is held within FontFaceCreationParams.
+ static const bool kEmptyValueIsZero = false;
+};
+
+} // namespace WTF
+
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_CACHE_KEY_H_
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 a9233996c15..0f2c270892c 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
@@ -89,4 +89,79 @@ TEST(FontCache, systemFont) {
}
#endif
+class EnumerationConsumer {
+ public:
+ explicit EnumerationConsumer(
+ const std::vector<FontEnumerationEntry>& expectations) {
+ for (const auto& f : expectations) {
+ ps_name_set_.insert(f.postscript_name.Utf8());
+ full_name_set_.insert(f.full_name.Utf8());
+ family_set_.insert(f.family.Utf8());
+ }
+ }
+
+ void Consume(const std::vector<FontEnumerationEntry>& entries) {
+ for (auto f : entries) {
+ ps_name_set_.erase(f.postscript_name.Utf8());
+ full_name_set_.erase(f.full_name.Utf8());
+ family_set_.erase(f.family.Utf8());
+ }
+ }
+
+ bool AllExpectationsMet() {
+ return ps_name_set_.empty() && full_name_set_.empty() &&
+ family_set_.empty();
+ }
+
+ private:
+ std::set<std::string> ps_name_set_;
+ std::set<std::string> full_name_set_;
+ std::set<std::string> family_set_;
+};
+
+TEST(FontCache, EnumerateAvailableFonts) {
+ FontCache* font_cache = FontCache::GetFontCache();
+ ASSERT_TRUE(font_cache);
+
+ std::vector<FontEnumerationEntry> expectations;
+
+#if defined(OS_MACOSX)
+ expectations.push_back(FontEnumerationEntry{"Monaco", "Monaco", "Monaco"});
+ expectations.push_back(
+ FontEnumerationEntry{"Menlo-Regular", "Menlo Regular", "Menlo"});
+ expectations.push_back(
+ FontEnumerationEntry{"Menlo-Bold", "Menlo Bold", "Menlo"});
+ expectations.push_back(
+ FontEnumerationEntry{"Menlo-BoldItalic", "Menlo Bold Italic", "Menlo"});
+#endif
+
+ auto entries = font_cache->EnumerateAvailableFonts();
+ auto consumer = EnumerationConsumer(expectations);
+
+ consumer.Consume(entries);
+ ASSERT_TRUE(consumer.AllExpectationsMet());
+}
+
+TEST(FontCache, EnumerateAvailableFontsInvalidation) {
+ FontCache* font_cache = FontCache::GetFontCache();
+ ASSERT_TRUE(font_cache);
+
+ // Make sure we start at zero.
+ font_cache->Invalidate();
+ size_t zero = 0;
+ ASSERT_EQ(zero, font_cache->EnumerationCacheSizeForTesting());
+
+ // The cache gets populated.
+ size_t enum_size_1 = font_cache->EnumerateAvailableFonts().size();
+ ASSERT_EQ(enum_size_1, font_cache->EnumerationCacheSizeForTesting());
+
+ // Invalidation clears the cache.
+ font_cache->Invalidate();
+ ASSERT_EQ(zero, font_cache->EnumerationCacheSizeForTesting());
+
+ // The cache gets re-populated.
+ size_t enum_size_2 = font_cache->EnumerateAvailableFonts().size();
+ ASSERT_EQ(enum_size_1, enum_size_2);
+}
+
} // namespace blink
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 ecc8454ff02..b00c9e9b10d 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
@@ -45,16 +45,6 @@
namespace blink {
-namespace {
-sk_sp<SkFontMgr> FontManagerForSubType(
- FontFormatCheck::VariableFontSubType font_sub_type) {
- CHECK_NE(font_sub_type, FontFormatCheck::VariableFontSubType::kNotVariable);
- if (font_sub_type == FontFormatCheck::VariableFontSubType::kVariableCFF2)
- return WebFontTypefaceFactory::FreeTypeFontManager();
- return WebFontTypefaceFactory::FontManagerForVariations();
-}
-} // namespace
-
FontCustomPlatformData::FontCustomPlatformData(sk_sp<SkTypeface> typeface,
size_t data_size)
: base_typeface_(std::move(typeface)), data_size_(data_size) {}
@@ -97,9 +87,14 @@ FontPlatformData FontCustomPlatformData::GetFontPlatformData(
SkSetFourByteTag('w', 'd', 't', 'h'),
SkFloatToScalar(selection_capabilities.width.clampToRange(
selection_request.width))};
+ // CSS and OpenType have opposite definitions of direction of slant
+ // angle. In OpenType positive values turn counter-clockwise, negative
+ // values clockwise - in CSS positive values are clockwise rotations /
+ // skew. See note in https://drafts.csswg.org/css-fonts/#font-style-prop -
+ // map value from CSS to OpenType here.
SkFontArguments::Axis slant_axis = {
SkSetFourByteTag('s', 'l', 'n', 't'),
- SkFloatToScalar(selection_capabilities.slope.clampToRange(
+ SkFloatToScalar(-selection_capabilities.slope.clampToRange(
selection_request.slope))};
axes.push_back(weight_axis);
@@ -124,12 +119,8 @@ FontPlatformData FontCustomPlatformData::GetFontPlatformData(
axes.push_back(opsz_axis);
}
- int index;
- std::unique_ptr<SkStreamAsset> stream(base_typeface_->openStream(&index));
- sk_sp<SkTypeface> sk_variation_font(FontManagerForSubType(font_sub_type)
- ->makeFromStream(std::move(stream),
- SkFontArguments().setCollectionIndex(index)
- .setAxes(axes.data(), axes.size())));
+ sk_sp<SkTypeface> sk_variation_font(base_typeface_->makeClone(
+ SkFontArguments().setAxes(axes.data(), axes.size())));
if (sk_variation_font) {
return_typeface = sk_variation_font;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_data.h b/chromium/third_party/blink/renderer/platform/fonts/font_data.h
index 3535115d1e4..d79e7fd5a70 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_data.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_data.h
@@ -57,15 +57,6 @@ class PLATFORM_EXPORT FontData : public RefCounted<FontData> {
DISALLOW_COPY_AND_ASSIGN(FontData);
};
-#define DEFINE_FONT_DATA_TYPE_CASTS(thisType, predicate) \
- template <typename T> \
- inline thisType* To##thisType(const scoped_refptr<T>& fontData) { \
- return To##thisType(fontData.get()); \
- } \
- DEFINE_TYPE_CASTS(thisType, FontData, fontData, \
- fontData->IsSegmented() == predicate, \
- fontData.IsSegmented() == predicate)
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_DATA_H_
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_data_cache.cc b/chromium/third_party/blink/renderer/platform/fonts/font_data_cache.cc
index 060207ea5e5..680da1679bd 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_data_cache.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_data_cache.cc
@@ -132,7 +132,7 @@ bool FontDataCache::PurgeLeastRecentlyUsed(int count) {
auto end = inactive_font_data_.end();
auto it = inactive_font_data_.begin();
for (int i = 0; i < count && it != end; ++it, ++i) {
- scoped_refptr<SimpleFontData>& font_data = *it.Get();
+ const scoped_refptr<SimpleFontData>& font_data = *it;
cache_.erase(&(font_data->PlatformData()));
// We should not delete SimpleFontData here because deletion can modify
// m_inactiveFontData. See http://trac.webkit.org/changeset/44011
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 6f20525f341..9e3ffe63834 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_description.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_description.cc
@@ -436,8 +436,6 @@ String FontDescription::ToString(GenericFamilyType familyType) {
return "Cursive";
case GenericFamilyType::kFantasyFamily:
return "Fantasy";
- case GenericFamilyType::kPictographFamily:
- return "Pictograph";
}
return "Unknown";
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_description.h b/chromium/third_party/blink/renderer/platform/fonts/font_description.h
index 8d19bd6873c..782b843707b 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_description.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_description.h
@@ -63,8 +63,7 @@ class PLATFORM_EXPORT FontDescription {
kSansSerifFamily,
kMonospaceFamily,
kCursiveFamily,
- kFantasyFamily,
- kPictographFamily
+ kFantasyFamily
};
static String ToString(GenericFamilyType);
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 737580ef6bf..1bb413937f9 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
@@ -63,6 +63,78 @@ TEST(FontDescriptionTest, TestHashCollision) {
}
}
+TEST(FontDescriptionTest, VariationSettingsIdentical) {
+ FontDescription a;
+ FontDescription b(a);
+
+ scoped_refptr<FontVariationSettings> settings_a =
+ FontVariationSettings::Create();
+ settings_a->Append(FontVariationAxis("test", 1));
+
+ scoped_refptr<FontVariationSettings> settings_b =
+ FontVariationSettings::Create();
+ settings_b->Append(FontVariationAxis("test", 1));
+
+ ASSERT_EQ(*settings_a, *settings_b);
+
+ a.SetVariationSettings(settings_a);
+ b.SetVariationSettings(settings_b);
+
+ ASSERT_EQ(a, b);
+
+ FontFaceCreationParams test_creation_params;
+ FontCacheKey cache_key_a = a.CacheKey(test_creation_params, false);
+ FontCacheKey cache_key_b = b.CacheKey(test_creation_params, false);
+
+ ASSERT_EQ(cache_key_a, cache_key_b);
+}
+
+TEST(FontDescriptionTest, VariationSettingsDifferent) {
+ FontDescription a;
+ FontDescription b(a);
+
+ scoped_refptr<FontVariationSettings> settings_a =
+ FontVariationSettings::Create();
+ settings_a->Append(FontVariationAxis("test", 1));
+
+ scoped_refptr<FontVariationSettings> settings_b =
+ FontVariationSettings::Create();
+ settings_b->Append(FontVariationAxis("0000", 1));
+
+ ASSERT_NE(*settings_a, *settings_b);
+
+ a.SetVariationSettings(settings_a);
+ b.SetVariationSettings(settings_b);
+
+ ASSERT_NE(a, b);
+
+ FontFaceCreationParams test_creation_params;
+
+ FontCacheKey cache_key_a = a.CacheKey(test_creation_params, false);
+ FontCacheKey cache_key_b = b.CacheKey(test_creation_params, false);
+
+ ASSERT_NE(cache_key_a, cache_key_b);
+
+ scoped_refptr<FontVariationSettings> second_settings_a =
+ FontVariationSettings::Create();
+ second_settings_a->Append(FontVariationAxis("test", 1));
+
+ scoped_refptr<FontVariationSettings> second_settings_b =
+ FontVariationSettings::Create();
+
+ ASSERT_NE(*second_settings_a, *second_settings_b);
+
+ a.SetVariationSettings(second_settings_a);
+ b.SetVariationSettings(second_settings_b);
+
+ ASSERT_NE(a, b);
+
+ FontCacheKey second_cache_key_a = a.CacheKey(test_creation_params, false);
+ FontCacheKey second_cache_key_b = b.CacheKey(test_creation_params, false);
+
+ ASSERT_NE(second_cache_key_a, second_cache_key_b);
+}
+
TEST(FontDescriptionTest, ToString) {
FontDescription description;
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 1362d480c4b..eb076725400 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
@@ -153,7 +153,7 @@ scoped_refptr<FontDataForRangeSet> FontFallbackIterator::Next(
current_font_data_index_++;
if (!font_data->IsLoading()) {
scoped_refptr<SimpleFontData> non_segmented =
- const_cast<SimpleFontData*>(ToSimpleFontData(font_data));
+ const_cast<SimpleFontData*>(To<SimpleFontData>(font_data));
// The fontData object that we have here is tracked in m_fontList of
// FontFallbackList and gets released in the font cache when the
// FontFallbackList is destroyed.
@@ -165,7 +165,7 @@ scoped_refptr<FontDataForRangeSet> FontFallbackIterator::Next(
// Iterate over ranges of a segmented font below.
- const SegmentedFontData* segmented = ToSegmentedFontData(font_data);
+ const auto* segmented = To<SegmentedFontData>(font_data);
if (fallback_stage_ != kSegmentedFace) {
segmented_face_index_ = 0;
fallback_stage_ = kSegmentedFace;
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 fa1a455e591..d00d18310bb 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
@@ -39,22 +39,24 @@
namespace blink {
-FontFallbackList::FontFallbackList()
+FontFallbackList::FontFallbackList(FontSelector* font_selector)
: cached_primary_simple_font_data_(nullptr),
- font_selector_(nullptr),
- font_selector_version_(0),
+ font_selector_(font_selector),
+ font_selector_version_(font_selector ? font_selector->Version() : 0),
family_index_(0),
generation_(FontCache::GetFontCache()->Generation()),
- has_loading_fallback_(false) {}
+ has_loading_fallback_(false),
+ can_shape_word_by_word_(false),
+ can_shape_word_by_word_computed_(false) {}
-void FontFallbackList::Invalidate(FontSelector* font_selector) {
+void FontFallbackList::Invalidate() {
ReleaseFontData();
font_list_.clear();
cached_primary_simple_font_data_ = nullptr;
family_index_ = 0;
has_loading_fallback_ = false;
- if (font_selector_ != font_selector)
- font_selector_ = font_selector;
+ can_shape_word_by_word_ = false;
+ can_shape_word_by_word_computed_ = false;
font_selector_version_ = font_selector_ ? font_selector_->Version() : 0;
generation_ = FontCache::GetFontCache()->Generation();
}
@@ -65,13 +67,18 @@ void FontFallbackList::ReleaseFontData() {
if (!font_list_[i]->IsCustomFont()) {
DCHECK(!font_list_[i]->IsSegmented());
FontCache::GetFontCache()->ReleaseFontData(
- ToSimpleFontData(font_list_[i]));
+ To<SimpleFontData>(font_list_[i].get()));
}
}
shape_cache_.reset(); // Clear the weak pointer to the cache instance.
}
bool FontFallbackList::LoadingCustomFonts() const {
+ // This function is only used for style and layout invalidation purposes. We
+ // don't need it for invalidation when the feature below is enabled.
+ if (RuntimeEnabledFeatures::CSSReducedFontLoadingInvalidationsEnabled())
+ return false;
+
if (!has_loading_fallback_)
return false;
@@ -84,6 +91,8 @@ bool FontFallbackList::LoadingCustomFonts() const {
}
bool FontFallbackList::ShouldSkipDrawing() const {
+ DCHECK(IsValid());
+
if (!has_loading_fallback_)
return false;
@@ -96,7 +105,7 @@ bool FontFallbackList::ShouldSkipDrawing() const {
}
const SimpleFontData* FontFallbackList::DeterminePrimarySimpleFontData(
- const FontDescription& font_description) const {
+ const FontDescription& font_description) {
bool should_load_custom_font = true;
for (unsigned font_index = 0;; ++font_index) {
@@ -114,8 +123,8 @@ const SimpleFontData* FontFallbackList::DeterminePrimarySimpleFontData(
return last_resort_fallback;
}
- if (font_data->IsSegmented() &&
- !ToSegmentedFontData(font_data)->ContainsCharacter(kSpaceCharacter))
+ const auto* segmented = DynamicTo<SegmentedFontData>(font_data);
+ if (segmented && !segmented->ContainsCharacter(kSpaceCharacter))
continue;
const SimpleFontData* font_data_for_space =
@@ -128,8 +137,7 @@ const SimpleFontData* FontFallbackList::DeterminePrimarySimpleFontData(
if (!font_data_for_space->IsLoadingFallback())
return font_data_for_space;
- if (font_data->IsSegmented()) {
- const SegmentedFontData* segmented = ToSegmentedFontData(font_data);
+ if (segmented) {
for (unsigned i = 0; i < segmented->NumFaces(); i++) {
const SimpleFontData* range_font_data =
segmented->FaceAt(i)->FontData();
@@ -212,8 +220,9 @@ FallbackListCompositeKey FontFallbackList::CompositeKey(
if (result) {
bool is_unique_match = false;
key.Add(font_description.CacheKey(params, is_unique_match));
- if (!result->IsSegmented() && !result->IsCustomFont())
- FontCache::GetFontCache()->ReleaseFontData(ToSimpleFontData(result));
+ auto* font_data = DynamicTo<SimpleFontData>(result.get());
+ if (!font_data && !result->IsCustomFont())
+ FontCache::GetFontCache()->ReleaseFontData(font_data);
}
}
current_family = current_family->Next();
@@ -224,7 +233,12 @@ FallbackListCompositeKey FontFallbackList::CompositeKey(
const FontData* FontFallbackList::FontDataAt(
const FontDescription& font_description,
- unsigned realized_font_index) const {
+ unsigned realized_font_index) {
+ if (RuntimeEnabledFeatures::CSSReducedFontLoadingInvalidationsEnabled()) {
+ if (!IsValid())
+ Invalidate();
+ }
+
// This fallback font is already in our list.
if (realized_font_index < font_list_.size())
return font_list_[realized_font_index].get();
@@ -250,6 +264,34 @@ const FontData* FontFallbackList::FontDataAt(
return result.get();
}
+bool FontFallbackList::ComputeCanShapeWordByWord(
+ const FontDescription& font_description) {
+ if (!font_description.GetTypesettingFeatures())
+ return true;
+
+ const SimpleFontData* primary_font = PrimarySimpleFontData(font_description);
+ if (!primary_font)
+ return false;
+
+ const FontPlatformData& platform_data = primary_font->PlatformData();
+ TypesettingFeatures features = font_description.GetTypesettingFeatures();
+ return !platform_data.HasSpaceInLigaturesOrKerning(features);
+}
+
+bool FontFallbackList::CanShapeWordByWord(
+ const FontDescription& font_description) {
+ if (RuntimeEnabledFeatures::CSSReducedFontLoadingInvalidationsEnabled()) {
+ if (!IsValid())
+ Invalidate();
+ }
+
+ if (!can_shape_word_by_word_computed_) {
+ can_shape_word_by_word_ = ComputeCanShapeWordByWord(font_description);
+ can_shape_word_by_word_computed_ = true;
+ }
+ return can_shape_word_by_word_;
+}
+
bool FontFallbackList::IsValid() const {
if (!font_selector_)
return font_selector_version_ == 0;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.h b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.h
index 4a604216015..6ef8c3774b8 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_fallback_list.h
@@ -28,6 +28,7 @@
#include "third_party/blink/renderer/platform/fonts/shaping/shape_cache.h"
#include "third_party/blink/renderer/platform/fonts/simple_font_data.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
@@ -42,13 +43,13 @@ class PLATFORM_EXPORT FontFallbackList : public RefCounted<FontFallbackList> {
USING_FAST_MALLOC(FontFallbackList);
public:
- static scoped_refptr<FontFallbackList> Create() {
- return base::AdoptRef(new FontFallbackList());
+ static scoped_refptr<FontFallbackList> Create(FontSelector* font_selector) {
+ return base::AdoptRef(new FontFallbackList(font_selector));
}
~FontFallbackList() { ReleaseFontData(); }
bool IsValid() const;
- void Invalidate(FontSelector*);
+ void Invalidate();
bool LoadingCustomFonts() const;
bool ShouldSkipDrawing() const;
@@ -58,7 +59,12 @@ class PLATFORM_EXPORT FontFallbackList : public RefCounted<FontFallbackList> {
unsigned FontSelectorVersion() const { return font_selector_version_; }
uint16_t Generation() const { return generation_; }
- ShapeCache* GetShapeCache(const FontDescription& font_description) const {
+ ShapeCache* GetShapeCache(const FontDescription& font_description) {
+ if (RuntimeEnabledFeatures::CSSReducedFontLoadingInvalidationsEnabled()) {
+ if (!IsValid())
+ Invalidate();
+ }
+
if (!shape_cache_) {
FallbackListCompositeKey key = CompositeKey(font_description);
shape_cache_ =
@@ -72,6 +78,11 @@ class PLATFORM_EXPORT FontFallbackList : public RefCounted<FontFallbackList> {
const SimpleFontData* PrimarySimpleFontData(
const FontDescription& font_description) {
+ if (RuntimeEnabledFeatures::CSSReducedFontLoadingInvalidationsEnabled()) {
+ if (!IsValid())
+ Invalidate();
+ }
+
if (!cached_primary_simple_font_data_) {
cached_primary_simple_font_data_ =
DeterminePrimarySimpleFontData(font_description);
@@ -79,28 +90,37 @@ class PLATFORM_EXPORT FontFallbackList : public RefCounted<FontFallbackList> {
}
return cached_primary_simple_font_data_;
}
- const FontData* FontDataAt(const FontDescription&, unsigned index) const;
+ const FontData* FontDataAt(const FontDescription&, unsigned index);
- FallbackListCompositeKey CompositeKey(const FontDescription&) const;
+ bool CanShapeWordByWord(const FontDescription&);
+
+ void SetCanShapeWordByWordForTesting(bool b) {
+ can_shape_word_by_word_ = b;
+ can_shape_word_by_word_computed_ = true;
+ }
private:
- FontFallbackList();
+ explicit FontFallbackList(FontSelector* font_selector);
scoped_refptr<FontData> GetFontData(const FontDescription&, int& family_index) const;
- const SimpleFontData* DeterminePrimarySimpleFontData(
- const FontDescription&) const;
+ const SimpleFontData* DeterminePrimarySimpleFontData(const FontDescription&);
+
+ FallbackListCompositeKey CompositeKey(const FontDescription&) const;
void ReleaseFontData();
+ bool ComputeCanShapeWordByWord(const FontDescription&);
- mutable Vector<scoped_refptr<FontData>, 1> font_list_;
- mutable const SimpleFontData* cached_primary_simple_font_data_;
- Persistent<FontSelector> font_selector_;
+ Vector<scoped_refptr<FontData>, 1> font_list_;
+ const SimpleFontData* cached_primary_simple_font_data_;
+ const Persistent<FontSelector> font_selector_;
unsigned font_selector_version_;
- mutable int family_index_;
+ int family_index_;
uint16_t generation_;
- mutable bool has_loading_fallback_ : 1;
- mutable base::WeakPtr<ShapeCache> shape_cache_;
+ bool has_loading_fallback_ : 1;
+ bool can_shape_word_by_word_ : 1;
+ bool can_shape_word_by_word_computed_ : 1;
+ base::WeakPtr<ShapeCache> shape_cache_;
DISALLOW_COPY_AND_ASSIGN(FontFallbackList);
};
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_global_context.cc b/chromium/third_party/blink/renderer/platform/fonts/font_global_context.cc
index ff2fd249e6c..ee1cb3b220c 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_global_context.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_global_context.cc
@@ -20,7 +20,9 @@ FontGlobalContext* FontGlobalContext::Get(CreateIfNeeded create_if_needed) {
return *font_persistent;
}
-FontGlobalContext::FontGlobalContext() : harfbuzz_font_funcs_(nullptr) {}
+FontGlobalContext::FontGlobalContext()
+ : harfbuzz_font_funcs_skia_advances_(nullptr),
+ harfbuzz_font_funcs_harfbuzz_advances_(nullptr) {}
FontGlobalContext::~FontGlobalContext() = default;
@@ -32,6 +34,15 @@ FontUniqueNameLookup* FontGlobalContext::GetFontUniqueNameLookup() {
return Get()->font_unique_name_lookup_.get();
}
+HarfBuzzFontCache* FontGlobalContext::GetHarfBuzzFontCache() {
+ std::unique_ptr<HarfBuzzFontCache>& global_context_harfbuzz_font_cache =
+ Get()->harfbuzz_font_cache_;
+ if (!global_context_harfbuzz_font_cache) {
+ global_context_harfbuzz_font_cache = std::make_unique<HarfBuzzFontCache>();
+ }
+ return global_context_harfbuzz_font_cache.get();
+}
+
void FontGlobalContext::ClearMemory() {
if (!Get(kDoNotCreate))
return;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_global_context.h b/chromium/third_party/blink/renderer/platform/fonts/font_global_context.h
index 63c3c861d6e..37e743c2264 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_global_context.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_global_context.h
@@ -6,7 +6,6 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_GLOBAL_CONTEXT_H_
#include "third_party/blink/renderer/platform/fonts/font_cache.h"
-#include "third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/text/layout_locale.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -17,6 +16,7 @@ namespace blink {
class FontCache;
class FontUniqueNameLookup;
+class HarfBuzzFontCache;
enum CreateIfNeeded { kDoNotCreate, kCreate };
@@ -30,16 +30,27 @@ class PLATFORM_EXPORT FontGlobalContext {
static inline FontCache& GetFontCache() { return Get()->font_cache_; }
- static inline HarfBuzzFontCache& GetHarfBuzzFontCache() {
- return Get()->harfbuzz_font_cache_;
- }
+ static HarfBuzzFontCache* GetHarfBuzzFontCache();
+
+ enum HorizontalAdvanceSource {
+ kSkiaHorizontalAdvances,
+ kHarfBuzzHorizontalAdvances
+ };
- static hb_font_funcs_t* GetHarfBuzzFontFuncs() {
- return Get()->harfbuzz_font_funcs_;
+ static hb_font_funcs_t* GetHarfBuzzFontFuncs(
+ HorizontalAdvanceSource advance_source) {
+ if (advance_source == kHarfBuzzHorizontalAdvances) {
+ return Get()->harfbuzz_font_funcs_harfbuzz_advances_;
+ }
+ return Get()->harfbuzz_font_funcs_skia_advances_;
}
- static void SetHarfBuzzFontFuncs(hb_font_funcs_t* funcs) {
- Get()->harfbuzz_font_funcs_ = funcs;
+ static void SetHarfBuzzFontFuncs(HorizontalAdvanceSource advance_source,
+ hb_font_funcs_t* funcs) {
+ if (advance_source == kHarfBuzzHorizontalAdvances) {
+ Get()->harfbuzz_font_funcs_harfbuzz_advances_ = funcs;
+ }
+ Get()->harfbuzz_font_funcs_skia_advances_ = funcs;
}
static FontUniqueNameLookup* GetFontUniqueNameLookup();
@@ -54,8 +65,9 @@ class PLATFORM_EXPORT FontGlobalContext {
~FontGlobalContext();
FontCache font_cache_;
- HarfBuzzFontCache harfbuzz_font_cache_;
- hb_font_funcs_t* harfbuzz_font_funcs_;
+ std::unique_ptr<HarfBuzzFontCache> harfbuzz_font_cache_;
+ hb_font_funcs_t* harfbuzz_font_funcs_skia_advances_;
+ hb_font_funcs_t* harfbuzz_font_funcs_harfbuzz_advances_;
std::unique_ptr<FontUniqueNameLookup> font_unique_name_lookup_;
DISALLOW_COPY_AND_ASSIGN(FontGlobalContext);
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc b/chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc
index 5e1005a2e4d..a9a0511de03 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc
@@ -28,6 +28,18 @@ HashSet<T> Intersection(const HashSet<T>& a, const HashSet<T>& b) {
namespace blink {
+FontMatchingMetrics::FontMatchingMetrics(bool top_level,
+ ukm::UkmRecorder* ukm_recorder,
+ ukm::SourceId source_id)
+ : top_level_(top_level),
+ ukm_recorder_(ukm_recorder),
+ source_id_(source_id) {
+ // Estimate of average page font use from anecdotal browsing session.
+ constexpr unsigned kEstimatedFontCount = 7;
+ local_fonts_succeeded_.ReserveCapacityForSize(kEstimatedFontCount);
+ local_fonts_failed_.ReserveCapacityForSize(kEstimatedFontCount);
+}
+
void FontMatchingMetrics::ReportSuccessfulFontFamilyMatch(
const AtomicString& font_family_name) {
successful_font_families_.insert(font_family_name);
@@ -48,6 +60,16 @@ void FontMatchingMetrics::ReportWebFontFamily(
web_font_families_.insert(font_family_name);
}
+void FontMatchingMetrics::ReportSuccessfulLocalFontMatch(
+ const AtomicString& font_name) {
+ local_fonts_succeeded_.insert(font_name);
+}
+
+void FontMatchingMetrics::ReportFailedLocalFontMatch(
+ const AtomicString& font_name) {
+ local_fonts_failed_.insert(font_name);
+}
+
void FontMatchingMetrics::PublishUkmMetrics() {
ukm::builders::FontMatchAttempts(source_id_)
.SetLoadContext(top_level_ ? kTopLevel : kSubFrame)
@@ -63,6 +85,10 @@ void FontMatchingMetrics::PublishUkmMetrics() {
.SetWebFontFamilyFailures(ukm::GetExponentialBucketMin(
Intersection(failed_font_families_, web_font_families_).size(),
kUkmFontLoadCountBucketSpacing))
+ .SetLocalFontFailures(ukm::GetExponentialBucketMin(
+ local_fonts_failed_.size(), kUkmFontLoadCountBucketSpacing))
+ .SetLocalFontSuccesses(ukm::GetExponentialBucketMin(
+ local_fonts_succeeded_.size(), kUkmFontLoadCountBucketSpacing))
.Record(ukm_recorder_);
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.h b/chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.h
index c31be1c51b5..59827c38e53 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_matching_metrics.h
@@ -27,10 +27,7 @@ class PLATFORM_EXPORT FontMatchingMetrics {
public:
FontMatchingMetrics(bool top_level,
ukm::UkmRecorder* ukm_recorder,
- ukm::SourceId source_id)
- : top_level_(top_level),
- ukm_recorder_(ukm_recorder),
- source_id_(source_id) {}
+ ukm::SourceId source_id);
// Called when a page attempts to match a font family, and the font family is
// available.
@@ -46,6 +43,14 @@ class PLATFORM_EXPORT FontMatchingMetrics {
// Called when a page attempts to match a web font family.
void ReportWebFontFamily(const AtomicString& font_family_name);
+ // Reports a font listed in a @font-face src:local rule that successfully
+ // matched.
+ void ReportSuccessfulLocalFontMatch(const AtomicString& font_name);
+
+ // Reports a font listed in a @font-face src:local rule that didn't
+ // successfully match.
+ void ReportFailedLocalFontMatch(const AtomicString& font_name);
+
// Publishes the number of font family matches attempted (both successful and
// otherwise) to UKM. Called at page unload.
void PublishUkmMetrics();
@@ -63,6 +68,12 @@ class PLATFORM_EXPORT FontMatchingMetrics {
// Web font families the page attempted to match.
HashSet<AtomicString> web_font_families_;
+ // @font-face src:local fonts that successfully matched.
+ HashSet<AtomicString> local_fonts_succeeded_;
+
+ // @font-face src:local fonts that didn't successfully match.
+ HashSet<AtomicString> local_fonts_failed_;
+
// True if this FontMatchingMetrics instance is for a top-level frame, false
// otherwise.
const bool top_level_ = false;
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 0eaaf9e94fb..0861e6e15c8 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/font_selector.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/font_selector.h
@@ -71,6 +71,15 @@ class PLATFORM_EXPORT FontSelector : public FontCacheClient {
virtual void ReportFailedFontFamilyMatch(
const AtomicString& font_family_name) = 0;
+ // Called when a page attempts to match a font name via a @font-face src:local
+ // rule, and the font is available.
+ virtual void ReportSuccessfulLocalFontMatch(
+ const AtomicString& font_name) = 0;
+
+ // Called when a page attempts to match a font name via a @font-face src:local
+ // rule, and the font is not available.
+ virtual void ReportFailedLocalFontMatch(const AtomicString& font_name) = 0;
+
virtual void RegisterForInvalidationCallbacks(FontSelectorClient*) = 0;
virtual void UnregisterForInvalidationCallbacks(FontSelectorClient*) = 0;
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 649b054fb68..b85832903ab 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
@@ -17,7 +17,7 @@ class FontSelectorClient : public GarbageCollectedMixin {
virtual void FontsNeedUpdate(FontSelector*) = 0;
- void Trace(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) override {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/linux/font_unique_name_lookup_linux.cc b/chromium/third_party/blink/renderer/platform/fonts/linux/font_unique_name_lookup_linux.cc
index 62d92b7f412..604a895c075 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/linux/font_unique_name_lookup_linux.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/linux/font_unique_name_lookup_linux.cc
@@ -19,7 +19,6 @@ sk_sp<SkTypeface> FontUniqueNameLookupLinux::MatchUniqueName(
if (!Platform::Current()->GetSandboxSupport()) {
LOG(ERROR) << "@font-face src: local() instantiation only available when "
"connected to browser process.";
- DCHECK(Platform::Current()->GetSandboxSupport());
return nullptr;
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/mac/core_text_font_format_support.h b/chromium/third_party/blink/renderer/platform/fonts/mac/core_text_font_format_support.h
index 1816f6f49d7..b5f3ffe9738 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/mac/core_text_font_format_support.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/mac/core_text_font_format_support.h
@@ -9,6 +9,7 @@ namespace blink {
bool CoreTextVersionSupportsVariations();
bool CoreTextVersionSupportsColrCpal();
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_MAC_CORE_TEXT_FONT_FORMAT_SUPPORT_H_
diff --git a/chromium/third_party/blink/renderer/platform/fonts/mac/font_cache_mac.mm b/chromium/third_party/blink/renderer/platform/fonts/mac/font_cache_mac.mm
index f50fc36281d..fedd1b91424 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/mac/font_cache_mac.mm
+++ b/chromium/third_party/blink/renderer/platform/fonts/mac/font_cache_mac.mm
@@ -29,8 +29,11 @@
#import "third_party/blink/renderer/platform/fonts/font_cache.h"
-#import <AppKit/AppKit.h>
#include <memory>
+
+#import <AppKit/AppKit.h>
+#import <CoreText/CoreText.h>
+
#include "base/location.h"
#include "base/mac/foundation_util.h"
#include "third_party/blink/public/platform/platform.h"
@@ -59,6 +62,22 @@
inLanguage:(id)useNil;
@end
+namespace {
+
+NSString* GetLocalizedString(CTFontDescriptorRef fd, CFStringRef attribute) {
+ base::ScopedCFTypeRef<CFStringRef> cf_str(base::mac::CFCast<CFStringRef>(
+ CTFontDescriptorCopyLocalizedAttribute(fd, attribute, nullptr)));
+ return [base::mac::CFToNSCast(cf_str.release()) autorelease];
+}
+
+NSString* GetString(CTFontDescriptorRef fd, CFStringRef attribute) {
+ base::ScopedCFTypeRef<CFStringRef> cf_str(base::mac::CFCast<CFStringRef>(
+ CTFontDescriptorCopyAttribute(fd, attribute)));
+ return [base::mac::CFToNSCast(cf_str.release()) autorelease];
+}
+
+} // namespace
+
namespace blink {
const char kColorEmojiFontMac[] = "Apple Color Emoji";
@@ -221,9 +240,12 @@ scoped_refptr<SimpleFontData> FontCache::PlatformFallbackFontForCharacter(
substitute_font, platform_data.size(), synthetic_bold,
(traits & NSFontItalicTrait) &&
!(substitute_font_traits & NSFontItalicTrait),
- platform_data.Orientation(),
+ platform_data.Orientation(), font_description.FontOpticalSizing(),
nullptr); // No variation paramaters in fallback.
+ if (!alternate_font)
+ return nullptr;
+
return FontDataFromFontPlatformData(alternate_font.get(), kDoNotRetain);
}
@@ -295,11 +317,43 @@ std::unique_ptr<FontPlatformData> FontCache::CreateFontPlatformData(
// the returned FontPlatformData since it will not have a valid SkTypeface.
std::unique_ptr<FontPlatformData> platform_data = FontPlatformDataFromNSFont(
platform_font, size, synthetic_bold, synthetic_italic,
- font_description.Orientation(), font_description.VariationSettings());
- if (!platform_data->Typeface()) {
+ font_description.Orientation(), font_description.FontOpticalSizing(),
+ font_description.VariationSettings());
+ if (!platform_data || !platform_data->Typeface()) {
return nullptr;
}
return platform_data;
}
+std::vector<FontEnumerationEntry> FontCache::EnumeratePlatformAvailableFonts() {
+ DCHECK(RuntimeEnabledFeatures::FontAccessEnabled());
+ @autoreleasepool {
+ std::vector<FontEnumerationEntry> output;
+
+ CFTypeRef values[1] = {kCFBooleanTrue};
+ base::ScopedCFTypeRef<CFDictionaryRef> options(CFDictionaryCreate(
+ kCFAllocatorDefault,
+ (const void**)kCTFontCollectionRemoveDuplicatesOption,
+ (const void**)&values,
+ /*numValues=*/1, &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks));
+ base::ScopedCFTypeRef<CTFontCollectionRef> collection(
+ CTFontCollectionCreateFromAvailableFonts(options));
+
+ base::ScopedCFTypeRef<CFArrayRef> font_descs(
+ CTFontCollectionCreateMatchingFontDescriptors(collection));
+
+ for (CFIndex i = 0; i < CFArrayGetCount(font_descs); ++i) {
+ CTFontDescriptorRef fd = base::mac::CFCast<CTFontDescriptorRef>(
+ CFArrayGetValueAtIndex(font_descs, i));
+ NSString* postscript_name = GetString(fd, kCTFontNameAttribute);
+ NSString* full_name = GetLocalizedString(fd, kCTFontDisplayNameAttribute);
+ NSString* family = GetLocalizedString(fd, kCTFontFamilyNameAttribute);
+ output.push_back(FontEnumerationEntry{String(postscript_name),
+ String(full_name), String(family)});
+ }
+ return output;
+ }
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm b/chromium/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm
index 8d01704041c..cf25ba022f2 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm
+++ b/chromium/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm
@@ -46,7 +46,7 @@
namespace {
-static CGFloat toYosemiteFontWeight(blink::FontSelectionValue font_weight) {
+static CGFloat toFontWeight(blink::FontSelectionValue font_weight) {
static uint64_t ns_font_weights[] = {
0xbfe99999a0000000, // NSFontWeightUltraLight
0xbfe3333340000000, // NSFontWeightThin
@@ -181,8 +181,7 @@ NSFont* MatchNSFontFamily(const AtomicString& desired_family_string,
// On OSX 10.10+, the default system font has more weights.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability"
- font = [NSFont systemFontOfSize:size
- weight:toYosemiteFontWeight(desired_weight)];
+ font = [NSFont systemFontOfSize:size weight:toFontWeight(desired_weight)];
#pragma clang diagnostic pop
if (desired_traits & IMPORTANT_FONT_TRAITS)
diff --git a/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.h b/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.h
index b1224beff2c..cd0e338cdb5 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.h
@@ -31,6 +31,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_MAC_FONT_PLATFORM_DATA_MAC_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_MAC_FONT_PLATFORM_DATA_MAC_H_
+#include "third_party/blink/renderer/platform/fonts/font_optical_sizing.h"
+
#include <memory>
@class NSFont;
@@ -47,6 +49,7 @@ std::unique_ptr<FontPlatformData> FontPlatformDataFromNSFont(
bool synthetic_bold,
bool synthetic_italic,
FontOrientation,
+ OpticalSizing,
FontVariationSettings*);
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm b/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm
index 16bcce4ba40..9bc59e46e5e 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm
+++ b/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm
@@ -27,21 +27,26 @@
#import <AvailabilityMacros.h>
#include "base/mac/foundation_util.h"
-#include "base/mac/scoped_cftyperef.h"
#include "base/mac/scoped_nsobject.h"
#include "base/stl_util.h"
#import "third_party/blink/public/platform/mac/web_sandbox_support.h"
#import "third_party/blink/public/platform/platform.h"
#import "third_party/blink/renderer/platform/fonts/font.h"
#import "third_party/blink/renderer/platform/fonts/font_platform_data.h"
+#import "third_party/blink/renderer/platform/fonts/mac/core_text_font_format_support.h"
#import "third_party/blink/renderer/platform/fonts/opentype/font_settings.h"
#import "third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.h"
#import "third_party/blink/renderer/platform/web_test_support.h"
#import "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#import "third_party/skia/include/core/SkFont.h"
#import "third_party/skia/include/core/SkStream.h"
+#import "third_party/skia/include/core/SkTypes.h"
#import "third_party/skia/include/ports/SkTypeface_mac.h"
+namespace {
+constexpr SkFourByteTag kOpszTag = SkSetFourByteTag('o', 'p', 's', 'z');
+}
+
namespace blink {
static bool CanLoadInProcess(NSFont* ns_font) {
@@ -53,10 +58,10 @@ static bool CanLoadInProcess(NSFont* ns_font) {
return ![font_name isEqualToString:@"LastResort"];
}
-static CTFontDescriptorRef CascadeToLastResortFontDescriptor() {
- static CTFontDescriptorRef descriptor;
- if (descriptor)
- return descriptor;
+static CFDictionaryRef CascadeToLastResortFontAttributes() {
+ static CFDictionaryRef attributes;
+ if (attributes)
+ return attributes;
base::ScopedCFTypeRef<CTFontDescriptorRef> last_resort(
CTFontDescriptorCreateWithNameAndSize(CFSTR("LastResort"), 0));
@@ -67,13 +72,10 @@ static CTFontDescriptorRef CascadeToLastResortFontDescriptor() {
const void* keys[] = {kCTFontCascadeListAttribute};
const void* values[] = {values_array};
- base::ScopedCFTypeRef<CFDictionaryRef> attributes(CFDictionaryCreate(
+ attributes = CFDictionaryCreate(
kCFAllocatorDefault, keys, values, base::size(keys),
- &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
-
- descriptor = CTFontDescriptorCreateWithAttributes(attributes);
-
- return descriptor;
+ &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ return attributes;
}
static sk_sp<SkTypeface> LoadFromBrowserProcess(NSFont* ns_font,
@@ -88,20 +90,23 @@ static sk_sp<SkTypeface> LoadFromBrowserProcess(NSFont* ns_font,
return nullptr;
}
- CGFontRef loaded_cg_font;
+ base::ScopedCFTypeRef<CTFontDescriptorRef> loaded_data_descriptor;
uint32_t font_id;
if (!sandbox_support->LoadFont(base::mac::NSToCFCast(ns_font),
- &loaded_cg_font, &font_id)) {
+ &loaded_data_descriptor, &font_id)) {
// TODO crbug.com/461279: Make this appear in the inspector console?
DLOG(ERROR)
<< "Loading user font \"" << [[ns_font familyName] UTF8String]
<< "\" from non system location failed. Corrupt or missing font file?";
return nullptr;
}
- base::ScopedCFTypeRef<CGFontRef> cg_font(loaded_cg_font);
- base::ScopedCFTypeRef<CTFontRef> ct_font(CTFontCreateWithGraphicsFont(
- cg_font, text_size, 0, CascadeToLastResortFontDescriptor()));
- sk_sp<SkTypeface> return_font(SkCreateTypefaceFromCTFont(ct_font, cg_font));
+
+ base::ScopedCFTypeRef<CTFontDescriptorRef> data_descriptor_with_cascade(
+ CTFontDescriptorCreateCopyWithAttributes(
+ loaded_data_descriptor, CascadeToLastResortFontAttributes()));
+ base::ScopedCFTypeRef<CTFontRef> ct_font(CTFontCreateWithFontDescriptor(
+ data_descriptor_with_cascade.get(), text_size, 0));
+ sk_sp<SkTypeface> return_font = SkMakeTypefaceFromCTFont(ct_font);
if (!return_font.get())
// TODO crbug.com/461279: Make this appear in the inspector console?
@@ -117,11 +122,12 @@ std::unique_ptr<FontPlatformData> FontPlatformDataFromNSFont(
bool synthetic_bold,
bool synthetic_italic,
FontOrientation orientation,
+ OpticalSizing optical_sizing,
FontVariationSettings* variation_settings) {
DCHECK(ns_font);
sk_sp<SkTypeface> typeface;
if (CanLoadInProcess(ns_font)) {
- typeface.reset(SkCreateTypefaceFromCTFont(base::mac::NSToCFCast(ns_font)));
+ typeface = SkMakeTypefaceFromCTFont(base::mac::NSToCFCast(ns_font));
} else {
// In process loading fails for cases where third party font manager
// software registers fonts in non system locations such as /Library/Fonts
@@ -129,26 +135,79 @@ std::unique_ptr<FontPlatformData> FontPlatformDataFromNSFont(
typeface = LoadFromBrowserProcess(ns_font, size);
}
- if (variation_settings && variation_settings->size() < UINT16_MAX) {
- SkFontArguments::Axis axes[variation_settings->size()];
- for (size_t i = 0; i < variation_settings->size(); ++i) {
- AtomicString feature_tag = variation_settings->at(i).Tag();
- axes[i] = {AtomicStringToFourByteTag(feature_tag),
- SkFloatToScalar(variation_settings->at(i).Value())};
+ auto make_typeface_fontplatformdata = [&typeface, &size, &synthetic_bold,
+ &synthetic_italic, &orientation]() {
+ return std::make_unique<FontPlatformData>(
+ std::move(typeface), std::string(), size, synthetic_bold,
+ synthetic_italic, orientation);
+ };
+
+ wtf_size_t valid_configured_axes =
+ variation_settings && variation_settings->size() < UINT16_MAX
+ ? variation_settings->size()
+ : 0;
+
+ // No variable font requested, return static font.
+ if (!valid_configured_axes && optical_sizing == kNoneOpticalSizing)
+ return make_typeface_fontplatformdata();
+
+ if (!typeface)
+ return nullptr;
+
+ int existing_axes = typeface->getVariationDesignPosition(nullptr, 0);
+ // Don't apply variation parameters if the font does not have axes or we
+ // fail to retrieve the existing ones.
+ if (existing_axes <= 0)
+ return make_typeface_fontplatformdata();
+
+ Vector<SkFontArguments::VariationPosition::Coordinate> coordinates_to_set;
+ coordinates_to_set.resize(existing_axes);
+
+ if (typeface->getVariationDesignPosition(coordinates_to_set.data(),
+ existing_axes) != existing_axes) {
+ return make_typeface_fontplatformdata();
+ }
+
+ // Iterate over the font's axes and find a missing tag from variation
+ // settings, special case opsz, track the number of axes reconfigured.
+ bool axes_reconfigured = false;
+ for (auto& coordinate : coordinates_to_set) {
+ // Set opsz to font size but allow having it overriden by
+ // font-variation-settings in case it has 'opsz'.
+ if (coordinate.axis == kOpszTag && optical_sizing == kAutoOpticalSizing) {
+ if (coordinate.value != SkFloatToScalar(size)) {
+ coordinate.value = SkFloatToScalar(size);
+ axes_reconfigured = true;
+ }
+ }
+ FontVariationAxis found_variation_setting(AtomicString(), 0);
+ if (variation_settings &&
+ variation_settings->FindPair(FourByteTagToAtomicString(coordinate.axis),
+ &found_variation_setting)) {
+ if (coordinate.value != found_variation_setting.Value()) {
+ coordinate.value = found_variation_setting.Value();
+ axes_reconfigured = true;
+ }
}
- sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
- // TODO crbug.com/670246: Refactor this to a future Skia API that acccepts
- // axis parameters on system fonts directly.
- typeface = fm->makeFromStream(
- typeface->openStream(nullptr)->duplicate(),
- SkFontArguments().setAxes(axes, variation_settings->size()));
}
- return std::make_unique<FontPlatformData>(
- std::move(typeface),
- std::string(), // family_ doesn't exist on Mac, this avoids conversion
- // from NSString which requires including a //base header
- size, synthetic_bold, synthetic_italic, orientation);
+ if (!axes_reconfigured) {
+ // No variable axes touched, return the previous typeface.
+ return make_typeface_fontplatformdata();
+ }
+
+ SkFontArguments::VariationPosition variation_design_position{
+ coordinates_to_set.data(), coordinates_to_set.size()};
+
+ sk_sp<SkTypeface> cloned_typeface(typeface->makeClone(
+ SkFontArguments().setVariationDesignPosition(variation_design_position)));
+
+ if (!cloned_typeface) {
+ // Applying varition parameters failed, return original typeface.
+ return make_typeface_fontplatformdata();
+ }
+ typeface = cloned_typeface;
+ return make_typeface_fontplatformdata();
}
void FontPlatformData::SetupSkFont(SkFont* skfont,
diff --git a/chromium/third_party/blink/renderer/platform/fonts/opentype/font_format_check.cc b/chromium/third_party/blink/renderer/platform/fonts/opentype/font_format_check.cc
index 964943fa0b2..2c11652ffcf 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/opentype/font_format_check.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/opentype/font_format_check.cc
@@ -4,32 +4,21 @@
#include "third_party/blink/renderer/platform/fonts/opentype/font_format_check.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
-#include "third_party/skia/include/core/SkTypeface.h"
-
// Include HarfBuzz to have a cross-platform way to retrieve table tags without
// having to rely on the platform being able to instantiate this font format.
#include <hb.h>
-namespace blink {
-
-namespace {
-
-struct HarfbuzzBlobDestroyer {
- inline void operator()(hb_blob_t* blob) { hb_blob_destroy(blob); }
-};
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+#include "third_party/harfbuzz-ng/utils/hb_scoped.h"
+#include "third_party/skia/include/core/SkTypeface.h"
-struct HarfbuzzFaceDestroyer {
- inline void operator()(hb_face_t* face) { hb_face_destroy(face); }
-};
-} // namespace
+namespace blink {
FontFormatCheck::FontFormatCheck(sk_sp<SkData> sk_data) {
- std::unique_ptr<hb_blob_t, HarfbuzzBlobDestroyer> font_blob(hb_blob_create(
+ HbScoped<hb_blob_t> font_blob(hb_blob_create(
reinterpret_cast<const char*>(sk_data->bytes()), sk_data->size(),
HB_MEMORY_MODE_READONLY, nullptr, nullptr));
- std::unique_ptr<hb_face_t, HarfbuzzFaceDestroyer> face(
- hb_face_create(font_blob.get(), 0));
+ HbScoped<hb_face_t> face(hb_face_create(font_blob.get(), 0));
unsigned table_count = 0;
table_count = hb_face_get_table_tags(face.get(), 0, nullptr, nullptr);
diff --git a/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings.cc b/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings.cc
index 733d76d0db4..84c34be7a02 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/platform/fonts/opentype/font_settings.h"
#include "third_party/blink/renderer/platform/wtf/hash_functions.h"
+#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string_hash.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hasher.h"
@@ -16,6 +17,13 @@ uint32_t AtomicStringToFourByteTag(AtomicString tag) {
return (((tag[0]) << 24) | ((tag[1]) << 16) | ((tag[2]) << 8) | (tag[3]));
}
+AtomicString FourByteTagToAtomicString(uint32_t tag) {
+ constexpr size_t tag_size = 4;
+ LChar tag_string[tag_size] = {(tag >> 24) & 0xFF, (tag >> 16) & 0xFF,
+ (tag >> 8) & 0xFF, tag & 0xFF};
+ return AtomicString(tag_string, tag_size);
+}
+
unsigned FontVariationSettings::GetHash() const {
unsigned computed_hash = size() ? 5381 : 0;
unsigned num_features = size();
diff --git a/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings.h b/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings.h
index 10ab2aec21e..ea5b8c942f8 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings.h
@@ -17,6 +17,7 @@
namespace blink {
uint32_t AtomicStringToFourByteTag(AtomicString tag);
+AtomicString FourByteTagToAtomicString(uint32_t tag);
template <typename T>
class FontTagValuePair {
@@ -34,7 +35,7 @@ class FontTagValuePair {
private:
AtomicString tag_;
- const T value_;
+ T value_;
};
template <typename T>
@@ -47,6 +48,7 @@ class FontSettings {
bool operator==(const FontSettings& other) const {
return list_ == other.list_;
}
+ bool operator!=(const FontSettings& other) const { return !(*this == other); }
String ToString() const {
StringBuilder builder;
wtf_size_t num_features = size();
@@ -60,6 +62,20 @@ class FontSettings {
}
return builder.ToString();
}
+
+ bool FindPair(AtomicString tag, T* found_pair) const {
+ if (!found_pair)
+ return false;
+
+ for (auto& pair : list_) {
+ if (pair.Tag() == tag) {
+ *found_pair = pair;
+ return true;
+ }
+ }
+ return false;
+ }
+
const T* begin() const { return list_.begin(); }
const T* end() const { return list_.end(); }
T* begin() { return list_.begin(); }
diff --git a/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings_test.cc b/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings_test.cc
index 5c2fa7d94e8..6a3e0457ac3 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/opentype/font_settings_test.cc
@@ -61,4 +61,30 @@ TEST(FontSettingsTest, ToString) {
}
}
+TEST(FontSettingsTest, FindTest) {
+ {
+ scoped_refptr<FontVariationSettings> settings =
+ MakeSettings<FontVariationSettings, FontVariationAxis>(
+ {FontVariationAxis{"a", 42}, FontVariationAxis{"b", 8118}});
+ FontVariationAxis found_axis(AtomicString(), 0);
+ ASSERT_FALSE(settings->FindPair("c", &found_axis));
+ ASSERT_FALSE(settings->FindPair("ddddd", &found_axis));
+ ASSERT_FALSE(settings->FindPair("", &found_axis));
+ ASSERT_EQ(found_axis.Value(), 0);
+ ASSERT_TRUE(settings->FindPair("a", &found_axis));
+ ASSERT_EQ(found_axis.Tag(), AtomicString("a"));
+ ASSERT_EQ(found_axis.Value(), 42);
+ ASSERT_TRUE(settings->FindPair("b", &found_axis));
+ ASSERT_EQ(found_axis.Tag(), AtomicString("b"));
+ ASSERT_EQ(found_axis.Value(), 8118);
+ }
+}
+
+TEST(FontSettingsTest, FindTestEmpty) {
+ scoped_refptr<FontVariationSettings> settings =
+ MakeSettings<FontVariationSettings, FontVariationAxis>({});
+ FontVariationAxis found_axis(AtomicString(), 0);
+ ASSERT_FALSE(settings->FindPair("a", &found_axis));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support.cc b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support.cc
index 4c18c37138f..542975a52ba 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support.cc
@@ -2,10 +2,13 @@
// 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/fonts/opentype/open_type_caps_support.h"
-
-#include <hb-aat.h>
+// clang-format off
#include <hb.h>
+#include <hb-aat.h>
+// clang-format on
+
+#include "third_party/blink/renderer/platform/fonts/opentype/open_type_caps_support.h"
+#include "third_party/harfbuzz-ng/utils/hb_scoped.h"
namespace blink {
@@ -138,12 +141,10 @@ OpenTypeCapsSupport::FontFormat OpenTypeCapsSupport::GetFontFormat() const {
hb_face_t* hb_face = hb_font_get_face(
harfbuzz_face_->GetScaledFont(nullptr, HarfBuzzFace::NoVerticalLayout));
- std::unique_ptr<hb_blob_t, decltype(&hb_blob_destroy)> morx_blob(
- hb_face_reference_table(hb_face, HB_TAG('m', 'o', 'r', 'x')),
- hb_blob_destroy);
- std::unique_ptr<hb_blob_t, decltype(&hb_blob_destroy)> mort_blob(
- hb_face_reference_table(hb_face, HB_TAG('m', 'o', 'r', 't')),
- hb_blob_destroy);
+ HbScoped<hb_blob_t> morx_blob(
+ hb_face_reference_table(hb_face, HB_TAG('m', 'o', 'r', 'x')));
+ HbScoped<hb_blob_t> mort_blob(
+ hb_face_reference_table(hb_face, HB_TAG('m', 'o', 'r', 't')));
// TODO(crbug.com/911149): Use hb_aat_layout_has_substitution() for
// has_morx_or_mort and hb_ot_layout_has_substitution() for has_gsub once is
diff --git a/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_stretch_data.h b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_stretch_data.h
new file mode 100644
index 00000000000..af3cc059903
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_stretch_data.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_OPENTYPE_OPEN_TYPE_MATH_STRETCH_DATA_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_OPENTYPE_OPEN_TYPE_MATH_STRETCH_DATA_H_
+
+#include "base/optional.h"
+#include "third_party/blink/renderer/platform/fonts/glyph.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace blink {
+
+class PLATFORM_EXPORT OpenTypeMathStretchData {
+ public:
+ enum StretchAxis : uint8_t { Horizontal = 0, Vertical = 1 };
+
+ // https://docs.microsoft.com/en-us/typography/opentype/spec/math#mathGlyphVariantRecordFormat
+ // Note: Only variantGlyph is considered as using advanceMeasurement can lead
+ // to inconsistent values compared to what SimpleFontData returns.
+ using GlyphVariantRecord = Glyph;
+
+ // https://docs.microsoft.com/en-us/typography/opentype/spec/math#glyphPartRecord
+ struct GlyphPartRecord {
+ Glyph glyph;
+ float start_connector_length;
+ float end_connector_length;
+ float full_advance;
+ bool is_extender;
+ };
+
+ // https://mathml-refresh.github.io/mathml-core/#the-glyphassembly-table
+ struct AssemblyParameters {
+ float connector_overlap{0};
+ unsigned repetition_count{0};
+ unsigned glyph_count{0};
+ float stretch_size{0};
+ Vector<GlyphPartRecord> parts;
+ };
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_OPENTYPE_OPEN_TYPE_MATH_STRETCH_DATA_H_
diff --git a/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.cc b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.cc
new file mode 100644
index 00000000000..80d94665ab7
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.cc
@@ -0,0 +1,258 @@
+// 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/fonts/opentype/open_type_math_support.h"
+
+// clang-format off
+#include <hb.h>
+#include <hb-ot.h>
+// clang-format on
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.h"
+
+namespace {
+// HarfBuzz' hb_position_t is a 16.16 fixed-point value.
+float HarfBuzzUnitsToFloat(hb_position_t value) {
+ static const float kFloatToHbRatio = 1.0f / (1 << 16);
+ return kFloatToHbRatio * value;
+}
+
+// Latin Modern, STIX Two, XITS, Asana, Deja Vu, Libertinus and TeX Gyre fonts
+// provide at most 13 size variant and 5 assembly parts.
+// See https://chromium-review.googlesource.com/c/chromium/src/+/2074678
+unsigned kMaxHarfBuzzRecords = 20;
+
+hb_direction_t HarfBuzzDirection(
+ blink::OpenTypeMathStretchData::StretchAxis stretch_axis) {
+ return stretch_axis == blink::OpenTypeMathStretchData::StretchAxis::Horizontal
+ ? HB_DIRECTION_LTR
+ : HB_DIRECTION_BTT;
+}
+
+} // namespace
+
+namespace blink {
+
+bool OpenTypeMathSupport::HasMathData(const HarfBuzzFace* harfbuzz_face) {
+ if (!harfbuzz_face)
+ return false;
+
+ hb_font_t* font =
+ harfbuzz_face->GetScaledFont(nullptr, HarfBuzzFace::NoVerticalLayout);
+ DCHECK(font);
+ hb_face_t* face = hb_font_get_face(font);
+ DCHECK(face);
+
+ return hb_ot_math_has_data(face);
+}
+
+base::Optional<float> OpenTypeMathSupport::MathConstant(
+ const HarfBuzzFace* harfbuzz_face,
+ MathConstants constant) {
+ if (!HasMathData(harfbuzz_face))
+ return base::nullopt;
+
+ hb_font_t* font =
+ harfbuzz_face->GetScaledFont(nullptr, HarfBuzzFace::NoVerticalLayout);
+ DCHECK(font);
+
+ hb_position_t harfbuzz_value = hb_ot_math_get_constant(
+ font, static_cast<hb_ot_math_constant_t>(constant));
+
+ switch (constant) {
+ case kScriptPercentScaleDown:
+ case kScriptScriptPercentScaleDown:
+ case kRadicalDegreeBottomRaisePercent:
+ return base::Optional<float>(harfbuzz_value / 100.0);
+ case kDelimitedSubFormulaMinHeight:
+ case kDisplayOperatorMinHeight:
+ case kMathLeading:
+ case kAxisHeight:
+ case kAccentBaseHeight:
+ case kFlattenedAccentBaseHeight:
+ case kSubscriptShiftDown:
+ case kSubscriptTopMax:
+ case kSubscriptBaselineDropMin:
+ case kSuperscriptShiftUp:
+ case kSuperscriptShiftUpCramped:
+ case kSuperscriptBottomMin:
+ case kSuperscriptBaselineDropMax:
+ case kSubSuperscriptGapMin:
+ case kSuperscriptBottomMaxWithSubscript:
+ case kSpaceAfterScript:
+ case kUpperLimitGapMin:
+ case kUpperLimitBaselineRiseMin:
+ case kLowerLimitGapMin:
+ case kLowerLimitBaselineDropMin:
+ case kStackTopShiftUp:
+ case kStackTopDisplayStyleShiftUp:
+ case kStackBottomShiftDown:
+ case kStackBottomDisplayStyleShiftDown:
+ case kStackGapMin:
+ case kStackDisplayStyleGapMin:
+ case kStretchStackTopShiftUp:
+ case kStretchStackBottomShiftDown:
+ case kStretchStackGapAboveMin:
+ case kStretchStackGapBelowMin:
+ case kFractionNumeratorShiftUp:
+ case kFractionNumeratorDisplayStyleShiftUp:
+ case kFractionDenominatorShiftDown:
+ case kFractionDenominatorDisplayStyleShiftDown:
+ case kFractionNumeratorGapMin:
+ case kFractionNumDisplayStyleGapMin:
+ case kFractionRuleThickness:
+ case kFractionDenominatorGapMin:
+ case kFractionDenomDisplayStyleGapMin:
+ case kSkewedFractionHorizontalGap:
+ case kSkewedFractionVerticalGap:
+ case kOverbarVerticalGap:
+ case kOverbarRuleThickness:
+ case kOverbarExtraAscender:
+ case kUnderbarVerticalGap:
+ case kUnderbarRuleThickness:
+ case kUnderbarExtraDescender:
+ case kRadicalVerticalGap:
+ case kRadicalDisplayStyleVerticalGap:
+ case kRadicalRuleThickness:
+ case kRadicalExtraAscender:
+ case kRadicalKernBeforeDegree:
+ case kRadicalKernAfterDegree:
+ return base::Optional<float>(HarfBuzzUnitsToFloat(harfbuzz_value));
+ default:
+ NOTREACHED();
+ }
+ return base::nullopt;
+}
+
+base::Optional<float> OpenTypeMathSupport::MathItalicCorrection(
+ const HarfBuzzFace* harfbuzz_face,
+ Glyph glyph) {
+ if (!harfbuzz_face)
+ return base::nullopt;
+
+ hb_font_t* font =
+ harfbuzz_face->GetScaledFont(nullptr, HarfBuzzFace::NoVerticalLayout);
+
+ return base::Optional<float>(HarfBuzzUnitsToFloat(
+ hb_ot_math_get_glyph_italics_correction(font, glyph)));
+}
+
+template <typename HarfBuzzRecordType>
+using GetHarfBuzzMathRecordGetter =
+ base::OnceCallback<unsigned int(hb_font_t* font,
+ hb_codepoint_t glyph,
+ hb_direction_t direction,
+ unsigned int start_offset,
+ unsigned int* record_count,
+ HarfBuzzRecordType* record_array)>;
+
+template <typename HarfBuzzRecordType, typename RecordType>
+using HarfBuzzMathRecordConverter =
+ base::RepeatingCallback<RecordType(HarfBuzzRecordType)>;
+
+template <typename HarfBuzzRecordType, typename RecordType>
+Vector<RecordType> GetHarfBuzzMathRecord(
+ const HarfBuzzFace* harfbuzz_face,
+ Glyph base_glyph,
+ OpenTypeMathStretchData::StretchAxis stretch_axis,
+ GetHarfBuzzMathRecordGetter<HarfBuzzRecordType> getter,
+ HarfBuzzMathRecordConverter<HarfBuzzRecordType, RecordType> converter,
+ base::Optional<RecordType> prepended_record) {
+ hb_font_t* hb_font =
+ harfbuzz_face->GetScaledFont(nullptr, HarfBuzzFace::NoVerticalLayout);
+ DCHECK(hb_font);
+
+ hb_direction_t hb_stretch_axis = HarfBuzzDirection(stretch_axis);
+
+ // In practice, math fonts have, for a given base glyph and stretch axis only
+ // provide a few GlyphVariantRecords (size variants of increasing sizes) and
+ // GlyphPartRecords (parts of a glyph assembly) so it is safe to truncate
+ // the result vector to a small size.
+ HarfBuzzRecordType chunk[kMaxHarfBuzzRecords];
+ unsigned int count = kMaxHarfBuzzRecords;
+ std::move(getter).Run(hb_font, base_glyph, hb_stretch_axis,
+ 0 /* start_offset */, &count, chunk);
+
+ // Create the vector to the determined size and initialize it with the results
+ // converted from HarfBuzz's ones, prepending any optional record.
+ Vector<RecordType> result;
+ result.ReserveInitialCapacity(prepended_record ? count + 1 : count);
+ if (prepended_record)
+ result.push_back(*prepended_record);
+ for (unsigned i = 0; i < count; i++) {
+ result.push_back(converter.Run(chunk[i]));
+ }
+ return result;
+}
+
+Vector<OpenTypeMathStretchData::GlyphVariantRecord>
+OpenTypeMathSupport::GetGlyphVariantRecords(
+ const HarfBuzzFace* harfbuzz_face,
+ Glyph base_glyph,
+ OpenTypeMathStretchData::StretchAxis stretch_axis) {
+ DCHECK(harfbuzz_face);
+ DCHECK(base_glyph);
+
+ auto getter = base::BindOnce(&hb_ot_math_get_glyph_variants);
+ auto converter =
+ base::BindRepeating([](hb_ot_math_glyph_variant_t record)
+ -> OpenTypeMathStretchData::GlyphVariantRecord {
+ return record.glyph;
+ });
+ return GetHarfBuzzMathRecord(
+ harfbuzz_face, base_glyph, stretch_axis, std::move(getter),
+ std::move(converter),
+ base::Optional<OpenTypeMathStretchData::GlyphVariantRecord>(base_glyph));
+}
+
+Vector<OpenTypeMathStretchData::GlyphPartRecord>
+OpenTypeMathSupport::GetGlyphPartRecords(
+ const HarfBuzzFace* harfbuzz_face,
+ Glyph base_glyph,
+ OpenTypeMathStretchData::StretchAxis stretch_axis,
+ float* italic_correction) {
+ DCHECK(harfbuzz_face);
+ DCHECK(base_glyph);
+
+ auto getter = base::BindOnce(
+ [](hb_font_t* font, hb_codepoint_t glyph, hb_direction_t direction,
+ unsigned int start_offset, unsigned int* parts_count,
+ hb_ot_math_glyph_part_t* parts) {
+ hb_position_t italic_correction;
+ return hb_ot_math_get_glyph_assembly(font, glyph, direction,
+ start_offset, parts_count, parts,
+ &italic_correction);
+ });
+ auto converter =
+ base::BindRepeating([](hb_ot_math_glyph_part_t record)
+ -> OpenTypeMathStretchData::GlyphPartRecord {
+ return {record.glyph,
+ HarfBuzzUnitsToFloat(record.start_connector_length),
+ HarfBuzzUnitsToFloat(record.end_connector_length),
+ HarfBuzzUnitsToFloat(record.full_advance),
+ record.flags & HB_MATH_GLYPH_PART_FLAG_EXTENDER};
+ });
+ Vector<OpenTypeMathStretchData::GlyphPartRecord> parts =
+ GetHarfBuzzMathRecord(
+ harfbuzz_face, base_glyph, stretch_axis, std::move(getter),
+ std::move(converter),
+ base::Optional<OpenTypeMathStretchData::GlyphPartRecord>());
+ if (italic_correction && !parts.IsEmpty()) {
+ hb_font_t* hb_font =
+ harfbuzz_face->GetScaledFont(nullptr, HarfBuzzFace::NoVerticalLayout);
+ // A GlyphAssembly subtable exists for the specified font, glyph and stretch
+ // axis since it has been possible to retrieve the GlyphPartRecords. This
+ // means that the following call is guaranteed to get an italic correction.
+ hb_position_t harfbuzz_italic_correction;
+ hb_ot_math_get_glyph_assembly(hb_font, base_glyph,
+ HarfBuzzDirection(stretch_axis), 0, nullptr,
+ nullptr, &harfbuzz_italic_correction);
+ *italic_correction = HarfBuzzUnitsToFloat(harfbuzz_italic_correction);
+ }
+ return parts;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.h b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.h
new file mode 100644
index 00000000000..633a4d11f2b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.h
@@ -0,0 +1,120 @@
+// 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_FONTS_OPENTYPE_OPEN_TYPE_MATH_SUPPORT_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_OPENTYPE_OPEN_TYPE_MATH_SUPPORT_H_
+
+#include "base/optional.h"
+#include "third_party/blink/renderer/platform/fonts/opentype/open_type_math_stretch_data.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace blink {
+
+class HarfBuzzFace;
+
+class PLATFORM_EXPORT OpenTypeMathSupport {
+ public:
+ static bool HasMathData(const HarfBuzzFace*);
+
+ // These constants are defined in the OpenType MATH table:
+ // https://docs.microsoft.com/en-us/typography/opentype/spec/math#mathconstants-table
+ // Their values match the indices in the MathConstants subtable.
+ enum MathConstants {
+ kScriptPercentScaleDown = 0,
+ kScriptScriptPercentScaleDown = 1,
+ kDelimitedSubFormulaMinHeight = 2,
+ kDisplayOperatorMinHeight = 3,
+ kMathLeading = 4,
+ kAxisHeight = 5,
+ kAccentBaseHeight = 6,
+ kFlattenedAccentBaseHeight = 7,
+ kSubscriptShiftDown = 8,
+ kSubscriptTopMax = 9,
+ kSubscriptBaselineDropMin = 10,
+ kSuperscriptShiftUp = 11,
+ kSuperscriptShiftUpCramped = 12,
+ kSuperscriptBottomMin = 13,
+ kSuperscriptBaselineDropMax = 14,
+ kSubSuperscriptGapMin = 15,
+ kSuperscriptBottomMaxWithSubscript = 16,
+ kSpaceAfterScript = 17,
+ kUpperLimitGapMin = 18,
+ kUpperLimitBaselineRiseMin = 19,
+ kLowerLimitGapMin = 20,
+ kLowerLimitBaselineDropMin = 21,
+ kStackTopShiftUp = 22,
+ kStackTopDisplayStyleShiftUp = 23,
+ kStackBottomShiftDown = 24,
+ kStackBottomDisplayStyleShiftDown = 25,
+ kStackGapMin = 26,
+ kStackDisplayStyleGapMin = 27,
+ kStretchStackTopShiftUp = 28,
+ kStretchStackBottomShiftDown = 29,
+ kStretchStackGapAboveMin = 30,
+ kStretchStackGapBelowMin = 31,
+ kFractionNumeratorShiftUp = 32,
+ kFractionNumeratorDisplayStyleShiftUp = 33,
+ kFractionDenominatorShiftDown = 34,
+ kFractionDenominatorDisplayStyleShiftDown = 35,
+ kFractionNumeratorGapMin = 36,
+ kFractionNumDisplayStyleGapMin = 37,
+ kFractionRuleThickness = 38,
+ kFractionDenominatorGapMin = 39,
+ kFractionDenomDisplayStyleGapMin = 40,
+ kSkewedFractionHorizontalGap = 41,
+ kSkewedFractionVerticalGap = 42,
+ kOverbarVerticalGap = 43,
+ kOverbarRuleThickness = 44,
+ kOverbarExtraAscender = 45,
+ kUnderbarVerticalGap = 46,
+ kUnderbarRuleThickness = 47,
+ kUnderbarExtraDescender = 48,
+ kRadicalVerticalGap = 49,
+ kRadicalDisplayStyleVerticalGap = 50,
+ kRadicalRuleThickness = 51,
+ kRadicalExtraAscender = 52,
+ kRadicalKernBeforeDegree = 53,
+ kRadicalKernAfterDegree = 54,
+ kRadicalDegreeBottomRaisePercent = 55
+ };
+
+ // Returns the value of the requested math constant or null if the font does
+ // not have any OpenType MATH table. All values are 16.16 fixed-point values
+ // converted to float except percentages (kScriptPercentScaleDown,
+ // kScriptScriptPercentScaleDown and kRadicalDegreeBottomRaisePercent) which
+ // are represented by a number between 0 and 1.
+ // https://docs.microsoft.com/en-us/typography/opentype/spec/math#mathconstants-table
+ static base::Optional<float> MathConstant(const HarfBuzzFace*, MathConstants);
+
+ // Returns the italic correction corresponding to the specified glyph or null
+ // if the font does not have any OpenType MATH table. This value provides an
+ // estimation of how much the glyph is slanted, which can be used e.g. when
+ // attaching scripts to the glyph.
+ // https://docs.microsoft.com/en-us/typography/opentype/spec/math#mathitalicscorrectioninfo-table
+ static base::Optional<float> MathItalicCorrection(const HarfBuzzFace*, Glyph);
+
+ // Returns a vector of GlyphVariantRecords corresponding to the specified
+ // glyph and stretch axis. The base glyph is always added as the first item.
+ // https://docs.microsoft.com/en-us/typography/opentype/spec/math#mathvariants-table
+ static Vector<OpenTypeMathStretchData::GlyphVariantRecord>
+ GetGlyphVariantRecords(const HarfBuzzFace*,
+ Glyph base_glyph,
+ OpenTypeMathStretchData::StretchAxis);
+
+ // Returns a vector of GlyphPartRecords corresponding to the specified
+ // glyph and stretch axis or an empty vector if there is no such construction.
+ // If the italic_correction parameter is specified and a construction is
+ // available, then it is set to the italic correction of the glyph assembly.
+ // https://docs.microsoft.com/en-us/typography/opentype/spec/math#mathvariants-table
+ static Vector<OpenTypeMathStretchData::GlyphPartRecord> GetGlyphPartRecords(
+ const HarfBuzzFace*,
+ Glyph base_glyph,
+ OpenTypeMathStretchData::StretchAxis,
+ float* italic_correction = nullptr);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_OPENTYPE_OPEN_TYPE_MATH_SUPPORT_H_
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
new file mode 100644
index 00000000000..c6493f48399
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/fonts/opentype/open_type_math_support_test.cc
@@ -0,0 +1,466 @@
+// 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/fonts/opentype/open_type_math_support.h"
+#include "base/memory/scoped_refptr.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/fonts/font.h"
+#include "third_party/blink/renderer/platform/fonts/opentype/open_type_types.h"
+#include "third_party/blink/renderer/platform/testing/font_test_helpers.h"
+#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+
+namespace {
+const UChar32 kLeftBraceCodePoint = '{';
+const UChar32 kOverBraceCodePoint = 0x23DE;
+const UChar32 kArabicMathOperatorHahWithDalCodePoint = 0x1EEF1;
+const UChar32 kNAryWhiteVerticalBarCodePoint = 0x2AFF;
+} // namespace
+
+namespace blink {
+
+class OpenTypeMathSupportTest : public testing::Test {
+ protected:
+ void SetUp() override {
+ font_description.SetComputedSize(10.0);
+ font = Font(font_description);
+ }
+
+ void TearDown() override {}
+
+ Font CreateMathFont(const String& name, float size = 1000) {
+ FontDescription::VariantLigatures ligatures;
+ return blink::test::CreateTestFont(
+ "MathTestFont",
+ blink::test::BlinkWebTestsFontsTestDataPath(String("math/") + name),
+ size, &ligatures);
+ }
+
+ bool HasMathData(const String& name) {
+ return OpenTypeMathSupport::HasMathData(
+ CreateMathFont(name).PrimaryFont()->PlatformData().GetHarfBuzzFace());
+ }
+
+ base::Optional<float> MathConstant(
+ const String& name,
+ OpenTypeMathSupport::MathConstants constant) {
+ Font math = CreateMathFont(name);
+ return OpenTypeMathSupport::MathConstant(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), constant);
+ }
+
+ FontDescription font_description;
+ Font font;
+};
+
+TEST_F(OpenTypeMathSupportTest, HasMathData) {
+ // Null parameter.
+ EXPECT_FALSE(OpenTypeMathSupport::HasMathData(nullptr));
+
+ // Font without a MATH table.
+ EXPECT_FALSE(HasMathData("math-text.woff"));
+
+ // Font with a MATH table.
+ EXPECT_TRUE(HasMathData("axisheight5000-verticalarrow14000.woff"));
+}
+
+TEST_F(OpenTypeMathSupportTest, MathConstantNullOpt) {
+ Font math_text = CreateMathFont("math-text.woff");
+
+ for (int i = OpenTypeMathSupport::MathConstants::kScriptPercentScaleDown;
+ i <=
+ OpenTypeMathSupport::MathConstants::kRadicalDegreeBottomRaisePercent;
+ i++) {
+ auto math_constant = static_cast<OpenTypeMathSupport::MathConstants>(i);
+
+ // Null parameter.
+ EXPECT_FALSE(OpenTypeMathSupport::MathConstant(nullptr, math_constant));
+
+ // Font without a MATH table.
+ EXPECT_FALSE(OpenTypeMathSupport::MathConstant(
+ math_text.PrimaryFont()->PlatformData().GetHarfBuzzFace(),
+ math_constant));
+ }
+}
+
+// See third_party/blink/web_tests/external/wpt/mathml/tools/percentscaledown.py
+TEST_F(OpenTypeMathSupportTest, MathConstantPercentScaleDown) {
+ {
+ auto result = MathConstant(
+ "scriptpercentscaledown80-scriptscriptpercentscaledown0.woff",
+ OpenTypeMathSupport::MathConstants::kScriptPercentScaleDown);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, .8);
+ }
+
+ {
+ auto result = MathConstant(
+ "scriptpercentscaledown0-scriptscriptpercentscaledown40.woff",
+ OpenTypeMathSupport::MathConstants::kScriptScriptPercentScaleDown);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, .4);
+ }
+}
+
+// See third_party/blink/web_tests/external/wpt/mathml/tools/fractions.py
+TEST_F(OpenTypeMathSupportTest, MathConstantFractions) {
+ {
+ auto result = MathConstant(
+ "fraction-numeratorshiftup11000-axisheight1000-rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::kFractionNumeratorShiftUp);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 11000);
+ }
+
+ {
+ auto result = MathConstant(
+ "fraction-numeratordisplaystyleshiftup2000-axisheight1000-"
+ "rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::
+ kFractionNumeratorDisplayStyleShiftUp);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 2000);
+ }
+
+ {
+ auto result = MathConstant(
+ "fraction-denominatorshiftdown3000-axisheight1000-rulethickness1000."
+ "woff",
+ OpenTypeMathSupport::MathConstants::kFractionDenominatorShiftDown);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 3000);
+ }
+
+ {
+ auto result = MathConstant(
+ "fraction-denominatordisplaystyleshiftdown6000-axisheight1000-"
+ "rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::
+ kFractionDenominatorDisplayStyleShiftDown);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 6000);
+ }
+
+ {
+ auto result = MathConstant(
+ "fraction-numeratorgapmin9000-rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::kFractionNumeratorGapMin);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 9000);
+ }
+
+ {
+ auto result = MathConstant(
+ "fraction-numeratordisplaystylegapmin8000-rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::kFractionNumDisplayStyleGapMin);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 8000);
+ }
+
+ {
+ auto result = MathConstant(
+ "fraction-rulethickness10000.woff",
+ OpenTypeMathSupport::MathConstants::kFractionRuleThickness);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 10000);
+ }
+
+ {
+ auto result = MathConstant(
+ "fraction-denominatorgapmin4000-rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::kFractionDenominatorGapMin);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 4000);
+ }
+
+ {
+ auto result = MathConstant(
+ "fraction-denominatordisplaystylegapmin5000-rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::kFractionDenomDisplayStyleGapMin);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 5000);
+ }
+}
+
+// See third_party/blink/web_tests/external/wpt/mathml/tools/radicals.py
+TEST_F(OpenTypeMathSupportTest, MathConstantRadicals) {
+ {
+ auto result = MathConstant(
+ "radical-degreebottomraisepercent25-rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::kRadicalDegreeBottomRaisePercent);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, .25);
+ }
+
+ {
+ auto result =
+ MathConstant("radical-verticalgap6000-rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::kRadicalVerticalGap);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 6000);
+ }
+
+ {
+ auto result = MathConstant(
+ "radical-displaystyleverticalgap7000-rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::kRadicalDisplayStyleVerticalGap);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 7000);
+ }
+
+ {
+ auto result =
+ MathConstant("radical-rulethickness8000.woff",
+ OpenTypeMathSupport::MathConstants::kRadicalRuleThickness);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 8000);
+ }
+
+ {
+ auto result =
+ MathConstant("radical-extraascender3000-rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::kRadicalExtraAscender);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 3000);
+ }
+
+ {
+ auto result = MathConstant(
+ "radical-kernbeforedegree4000-rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::kRadicalKernBeforeDegree);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, 4000);
+ }
+
+ {
+ auto result = MathConstant(
+ "radical-kernafterdegreeminus5000-rulethickness1000.woff",
+ OpenTypeMathSupport::MathConstants::kRadicalKernAfterDegree);
+ EXPECT_TRUE(result);
+ EXPECT_FLOAT_EQ(*result, -5000);
+ }
+}
+
+TEST_F(OpenTypeMathSupportTest, MathVariantsWithoutTable) {
+ Font math = CreateMathFont("math-text.woff");
+ auto glyph = math.PrimaryFont()->GlyphForCharacter('A');
+
+ // Horizontal variants.
+ {
+ auto variants = OpenTypeMathSupport::GetGlyphVariantRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), glyph,
+ OpenTypeMathStretchData::StretchAxis::Horizontal);
+ EXPECT_EQ(variants.size(), 1u);
+ EXPECT_EQ(variants[0], glyph);
+ }
+
+ // Vertical variants.
+ {
+ auto variants = OpenTypeMathSupport::GetGlyphVariantRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), glyph,
+ OpenTypeMathStretchData::StretchAxis::Vertical);
+ EXPECT_EQ(variants.size(), 1u);
+ EXPECT_EQ(variants[0], glyph);
+ }
+
+ // Horizontal parts.
+ {
+ auto parts = OpenTypeMathSupport::GetGlyphPartRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), glyph,
+ OpenTypeMathStretchData::StretchAxis::Horizontal);
+ EXPECT_TRUE(parts.IsEmpty());
+ }
+
+ // // Vertical parts.
+ {
+ auto parts = OpenTypeMathSupport::GetGlyphPartRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), glyph,
+ OpenTypeMathStretchData::StretchAxis::Vertical);
+ EXPECT_TRUE(parts.IsEmpty());
+ }
+}
+
+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
+ // respectively horizontal and vertical rectangles of increasing size.
+ // The MathVariants table contains the following data for horizontal
+ // (respectively vertical) operators:
+ // - Glyph variants: h0, h1, h2, h3 (respectively v0, v1, v2, v3).
+ // - Glyph parts: non-extender h2 and extender h1 (respectively v2 and v1).
+ // For details, see createSizeVariants() and createStretchy() from
+ // third_party/blink/web_tests/external/wpt/mathml/tools/operator-dictionary.py
+
+ Font math = CreateMathFont("operators.woff");
+ auto left_brace = math.PrimaryFont()->GlyphForCharacter(kLeftBraceCodePoint);
+ auto over_brace = math.PrimaryFont()->GlyphForCharacter(kOverBraceCodePoint);
+
+ // Calculate glyph indices from the last unicode character in the font.
+ // TODO(https://crbug.com/1057596): Find a better way to access these glyph
+ // indices.
+ auto v0 = math.PrimaryFont()->GlyphForCharacter(
+ kArabicMathOperatorHahWithDalCodePoint) +
+ 1;
+ auto h0 = v0 + 1;
+ auto v1 = h0 + 1;
+ auto h1 = v1 + 1;
+ auto v2 = h1 + 1;
+ auto h2 = v2 + 1;
+ auto v3 = h2 + 1;
+ auto h3 = v3 + 1;
+
+ // Vertical variants for vertical operator.
+ {
+ auto variants = OpenTypeMathSupport::GetGlyphVariantRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), left_brace,
+ OpenTypeMathStretchData::StretchAxis::Vertical);
+ EXPECT_EQ(variants.size(), 5u);
+ EXPECT_EQ(variants[0], left_brace);
+ EXPECT_EQ(variants[1], v0);
+ EXPECT_EQ(variants[2], v1);
+ EXPECT_EQ(variants[3], v2);
+ EXPECT_EQ(variants[4], v3);
+ }
+
+ // Horizontal variants for vertical operator.
+ {
+ auto variants = OpenTypeMathSupport::GetGlyphVariantRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), left_brace,
+ OpenTypeMathStretchData::StretchAxis::Horizontal);
+ EXPECT_EQ(variants.size(), 1u);
+ EXPECT_EQ(variants[0], left_brace);
+ }
+
+ // Horizontal variants for horizontal operator.
+ {
+ auto variants = OpenTypeMathSupport::GetGlyphVariantRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), over_brace,
+ OpenTypeMathStretchData::StretchAxis::Horizontal);
+ EXPECT_EQ(variants.size(), 5u);
+ EXPECT_EQ(variants[0], over_brace);
+ EXPECT_EQ(variants[1], h0);
+ EXPECT_EQ(variants[2], h1);
+ EXPECT_EQ(variants[3], h2);
+ EXPECT_EQ(variants[4], h3);
+ }
+
+ // Vertical variants for horizontal operator.
+ {
+ auto variants = OpenTypeMathSupport::GetGlyphVariantRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), over_brace,
+ OpenTypeMathStretchData::StretchAxis::Vertical);
+ EXPECT_EQ(variants.size(), 1u);
+ EXPECT_EQ(variants[0], over_brace);
+ }
+
+ // Vertical parts for vertical operator.
+ {
+ auto parts = OpenTypeMathSupport::GetGlyphPartRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), left_brace,
+ OpenTypeMathStretchData::StretchAxis::Vertical);
+ EXPECT_EQ(parts.size(), 2u);
+ EXPECT_EQ(parts[0].glyph, v2);
+ EXPECT_FLOAT_EQ(parts[0].start_connector_length, 0);
+ EXPECT_FLOAT_EQ(parts[0].end_connector_length, 1000);
+ EXPECT_FLOAT_EQ(parts[0].full_advance, 3000);
+ EXPECT_EQ(parts[0].is_extender, false);
+ EXPECT_EQ(parts[1].glyph, v1);
+ EXPECT_FLOAT_EQ(parts[1].start_connector_length, 1000);
+ EXPECT_FLOAT_EQ(parts[1].end_connector_length, 1000);
+ EXPECT_FLOAT_EQ(parts[1].full_advance, 2000);
+ EXPECT_EQ(parts[1].is_extender, true);
+ }
+
+ // Horizontal parts for vertical operator.
+ {
+ auto parts = OpenTypeMathSupport::GetGlyphPartRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), left_brace,
+ OpenTypeMathStretchData::StretchAxis::Horizontal);
+ EXPECT_TRUE(parts.IsEmpty());
+ }
+
+ // Horizontal parts for horizontal operator.
+ {
+ auto parts = OpenTypeMathSupport::GetGlyphPartRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), over_brace,
+ OpenTypeMathStretchData::StretchAxis::Horizontal);
+
+ EXPECT_EQ(parts.size(), 2u);
+ EXPECT_EQ(parts[0].glyph, h2);
+ EXPECT_FLOAT_EQ(parts[0].start_connector_length, 0);
+ EXPECT_FLOAT_EQ(parts[0].end_connector_length, 1000);
+ EXPECT_FLOAT_EQ(parts[0].full_advance, 3000);
+ EXPECT_EQ(parts[0].is_extender, false);
+
+ EXPECT_EQ(parts[1].glyph, h1);
+ EXPECT_FLOAT_EQ(parts[1].start_connector_length, 1000);
+ EXPECT_FLOAT_EQ(parts[1].end_connector_length, 1000);
+ EXPECT_FLOAT_EQ(parts[1].full_advance, 2000);
+ EXPECT_EQ(parts[1].is_extender, true);
+ }
+
+ // Vertical parts for horizontal operator.
+ {
+ auto parts = OpenTypeMathSupport::GetGlyphPartRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), over_brace,
+ OpenTypeMathStretchData::StretchAxis::Vertical);
+ EXPECT_TRUE(parts.IsEmpty());
+ }
+}
+
+// See third_party/blink/web_tests/external/wpt/mathml/tools/largeop.py
+TEST_F(OpenTypeMathSupportTest, MathItalicCorrection) {
+ {
+ Font math = CreateMathFont(
+ "largeop-displayoperatorminheight2000-2AFF-italiccorrection3000.woff");
+ Glyph base_glyph =
+ math.PrimaryFont()->GlyphForCharacter(kNAryWhiteVerticalBarCodePoint);
+
+ // Retrieve the glyph with italic correction.
+ Vector<OpenTypeMathStretchData::GlyphVariantRecord> variants =
+ OpenTypeMathSupport::GetGlyphVariantRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), base_glyph,
+ OpenTypeMathStretchData::StretchAxis::Vertical);
+ EXPECT_EQ(variants.size(), 3u);
+ EXPECT_EQ(variants[0], base_glyph);
+ EXPECT_EQ(variants[1], base_glyph);
+ Glyph glyph_with_italic_correction = variants[2];
+
+ // MathItalicCorrection with a value.
+ base::Optional<float> glyph_with_italic_correction_value =
+ OpenTypeMathSupport::MathItalicCorrection(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(),
+ glyph_with_italic_correction);
+ EXPECT_TRUE(glyph_with_italic_correction_value);
+ EXPECT_FLOAT_EQ(*glyph_with_italic_correction_value, 3000);
+
+ // GetGlyphPartRecords does not set italic correction when there is no
+ // construction available.
+ float italic_correction = -1000;
+ Vector<OpenTypeMathStretchData::GlyphPartRecord> parts =
+ OpenTypeMathSupport::GetGlyphPartRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), base_glyph,
+ OpenTypeMathStretchData::StretchAxis::Vertical, &italic_correction);
+ EXPECT_TRUE(parts.IsEmpty());
+ EXPECT_FLOAT_EQ(italic_correction, -1000);
+ }
+
+ {
+ Font math = CreateMathFont(
+ "largeop-displayoperatorminheight7000-2AFF-italiccorrection5000.woff");
+ Glyph base_glyph =
+ math.PrimaryFont()->GlyphForCharacter(kNAryWhiteVerticalBarCodePoint);
+
+ // OpenTypeMathSupport::GetGlyphPartRecords sets italic correction.
+ float italic_correction = -1000;
+ Vector<OpenTypeMathStretchData::GlyphPartRecord> parts =
+ OpenTypeMathSupport::GetGlyphPartRecords(
+ math.PrimaryFont()->PlatformData().GetHarfBuzzFace(), base_glyph,
+ OpenTypeMathStretchData::StretchAxis::Vertical, &italic_correction);
+ EXPECT_EQ(parts.size(), 3u);
+ EXPECT_FLOAT_EQ(italic_correction, 5000);
+ }
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/segmented_font_data.h b/chromium/third_party/blink/renderer/platform/fonts/segmented_font_data.h
index 61b2872c97b..17cc3ed89ec 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/segmented_font_data.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/segmented_font_data.h
@@ -29,6 +29,7 @@
#include "third_party/blink/renderer/platform/fonts/font_data.h"
#include "third_party/blink/renderer/platform/fonts/font_data_for_range_set.h"
#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
class SimpleFontData;
@@ -61,7 +62,12 @@ class PLATFORM_EXPORT SegmentedFontData : public FontData {
Vector<scoped_refptr<FontDataForRangeSet>, 1> faces_;
};
-DEFINE_FONT_DATA_TYPE_CASTS(SegmentedFontData, true);
+template <>
+struct DowncastTraits<SegmentedFontData> {
+ static bool AllowFrom(const FontData& fontData) {
+ return fontData.IsSegmented();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shape_iterator.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shape_iterator.cc
index 5b020364b1a..a9886bcd928 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shape_iterator.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shape_iterator.cc
@@ -13,8 +13,8 @@ scoped_refptr<const ShapeResult>
CachingWordShapeIterator::ShapeWordWithoutSpacing(const TextRun& word_run,
const Font* font) {
ShapeCacheEntry* cache_entry = shape_cache_->Add(word_run, ShapeCacheEntry());
- if (cache_entry && cache_entry->shape_result_)
- return cache_entry->shape_result_;
+ if (cache_entry && *cache_entry)
+ return *cache_entry;
const String word_text = word_run.NormalizedUTF16();
HarfBuzzShaper shaper(word_text);
@@ -25,7 +25,7 @@ CachingWordShapeIterator::ShapeWordWithoutSpacing(const TextRun& word_run,
shape_result->SetDeprecatedInkBounds(shape_result->ComputeInkBounds());
if (cache_entry)
- cache_entry->shape_result_ = shape_result;
+ *cache_entry = shape_result;
return shape_result;
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.cc
index 7e4e2bc6398..68972169da9 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.cc
@@ -37,7 +37,7 @@
namespace blink {
ShapeCache* CachingWordShaper::GetShapeCache() const {
- return font_.font_fallback_list_->GetShapeCache(font_.font_description_);
+ return font_.GetShapeCache();
}
// Returns the total advance width of the TextRun run. If glyph_bounds
@@ -157,7 +157,7 @@ GlyphData CachingWordShaper::EmphasisMarkGlyphData(
ShapeResultBuffer buffer;
ShapeResultsForRun(GetShapeCache(), &font_, emphasis_mark_run, &buffer);
- return buffer.EmphasisMarkGlyphData(font_.font_description_);
+ return buffer.EmphasisMarkGlyphData(font_.GetFontDescription());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper_test.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper_test.cc
index 89fea7e10c3..46137b2efdd 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper_test.cc
@@ -24,7 +24,6 @@ class CachingWordShaperTest : public testing::Test {
font_description.SetGenericFamily(FontDescription::kStandardFamily);
font = Font(font_description);
- font.Update(nullptr);
ASSERT_TRUE(font.CanShapeWordByWord());
fallback_fonts = nullptr;
cache = std::make_unique<ShapeCache>();
@@ -390,7 +389,6 @@ TEST_F(CachingWordShaperTest, TextOrientationFallbackShouldNotInFallbackList) {
font_description.SetOrientation(FontOrientation::kVerticalMixed);
Font vertical_mixed_font = Font(font_description);
- vertical_mixed_font.Update(nullptr);
ASSERT_TRUE(vertical_mixed_font.CanShapeWordByWord());
CachingWordShaper shaper(vertical_mixed_font);
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc
index 4d4a8227312..97fa173bb8b 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.cc
@@ -30,8 +30,10 @@
#include "third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.h"
-#include <hb-ot.h>
+// clang-format off
#include <hb.h>
+#include <hb-ot.h>
+// clang-format on
#include <memory>
@@ -50,6 +52,7 @@
#include "third_party/blink/renderer/platform/wtf/hash_map.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/harfbuzz-ng/utils/hb_scoped.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkPoint.h"
@@ -59,34 +62,40 @@
namespace blink {
-void HbFontDeleter::operator()(hb_font_t* font) {
- if (font)
- hb_font_destroy(font);
-}
+namespace {
-void HbFaceDeleter::operator()(hb_face_t* face) {
- if (face)
- hb_face_destroy(face);
-}
+#if defined(OS_MACOSX)
+void DetermineTrakSbix(SkTypeface* typeface, bool* has_trak, bool* has_sbix) {
+ int num_tags = typeface->countTables();
+
+ SkFontTableTag tags[num_tags];
+
+ int returned_tags = typeface->getTableTags(tags);
+ DCHECK_EQ(num_tags, returned_tags);
-struct HbSetDeleter {
- void operator()(hb_set_t* set) {
- if (set)
- hb_set_destroy(set);
+ for (auto& tag : tags) {
+ if (tag == SkSetFourByteTag('t', 'r', 'a', 'k'))
+ *has_trak = true;
+ if (tag == SkSetFourByteTag('s', 'b', 'i', 'x'))
+ *has_sbix = true;
}
-};
+}
+#endif
-using HbSetUniquePtr = std::unique_ptr<hb_set_t, HbSetDeleter>;
+} // namespace
-static scoped_refptr<HbFontCacheEntry> CreateHbFontCacheEntry(hb_face_t*);
+static scoped_refptr<HbFontCacheEntry> CreateHbFontCacheEntry(
+ hb_face_t*,
+ SkTypeface* typefaces);
HarfBuzzFace::HarfBuzzFace(FontPlatformData* platform_data, uint64_t unique_id)
: platform_data_(platform_data), unique_id_(unique_id) {
HarfBuzzFontCache::AddResult result =
- FontGlobalContext::GetHarfBuzzFontCache().insert(unique_id_, nullptr);
+ FontGlobalContext::GetHarfBuzzFontCache()->insert(unique_id_, nullptr);
if (result.is_new_entry) {
- HbFaceUniquePtr face(CreateFace());
- result.stored_value->value = CreateHbFontCacheEntry(face.get());
+ HbScoped<hb_face_t> face(CreateFace());
+ result.stored_value->value =
+ CreateHbFontCacheEntry(face.get(), platform_data->Typeface());
}
result.stored_value->value->AddRef();
unscaled_font_ = result.stored_value->value->HbFont();
@@ -94,13 +103,14 @@ HarfBuzzFace::HarfBuzzFace(FontPlatformData* platform_data, uint64_t unique_id)
}
HarfBuzzFace::~HarfBuzzFace() {
- HarfBuzzFontCache::iterator result =
- FontGlobalContext::GetHarfBuzzFontCache().find(unique_id_);
- SECURITY_DCHECK(result != FontGlobalContext::GetHarfBuzzFontCache().end());
+ HarfBuzzFontCache* harfbuzz_font_cache =
+ FontGlobalContext::GetHarfBuzzFontCache();
+ HarfBuzzFontCache::iterator result = harfbuzz_font_cache->find(unique_id_);
+ SECURITY_DCHECK(result != harfbuzz_font_cache->end());
DCHECK(!result.Get()->value->HasOneRef());
result.Get()->value->Release();
if (result.Get()->value->HasOneRef())
- FontGlobalContext::GetHarfBuzzFontCache().erase(unique_id_);
+ harfbuzz_font_cache->erase(unique_id_);
}
static hb_bool_t HarfBuzzGetGlyph(hb_font_t* hb_font,
@@ -228,7 +238,7 @@ bool HarfBuzzFace::HasSpaceInLigaturesOrKerning(TypesettingFeatures features) {
const hb_codepoint_t kInvalidCodepoint = static_cast<hb_codepoint_t>(-1);
hb_codepoint_t space = kInvalidCodepoint;
- HbSetUniquePtr glyphs(hb_set_create());
+ HbScoped<hb_set_t> glyphs(hb_set_create());
// Check whether computing is needed and compute for gpos/gsub.
if (features & kKerning &&
@@ -280,31 +290,43 @@ bool HarfBuzzFace::ShouldSubpixelPosition() {
return harfbuzz_font_data_->font_.isSubpixel();
}
-static hb_font_funcs_t* HarfBuzzSkiaGetFontFuncs() {
- hb_font_funcs_t* funcs = FontGlobalContext::GetHarfBuzzFontFuncs();
+static hb_font_funcs_t* create_populated_hb_font_funcs(
+ FontGlobalContext::HorizontalAdvanceSource horizontal_advance_source) {
+ hb_font_funcs_t* funcs = hb_font_funcs_create();
- // We don't set callback functions which we can't support.
- // HarfBuzz will use the fallback implementation if they aren't set.
- if (!funcs) {
- funcs = hb_font_funcs_create();
- hb_font_funcs_set_variation_glyph_func(funcs, HarfBuzzGetGlyph, nullptr,
- nullptr);
- hb_font_funcs_set_nominal_glyph_func(funcs, HarfBuzzGetNominalGlyph,
- nullptr, nullptr);
+ if (horizontal_advance_source == FontGlobalContext::kSkiaHorizontalAdvances) {
hb_font_funcs_set_glyph_h_advance_func(
funcs, HarfBuzzGetGlyphHorizontalAdvance, nullptr, nullptr);
hb_font_funcs_set_glyph_h_advances_func(
funcs, HarfBuzzGetGlyphHorizontalAdvances, nullptr, nullptr);
- // TODO(https://crbug.com/899718): Replace vertical metrics callbacks with
- // HarfBuzz VORG/VMTX internal implementation by deregistering those.
- hb_font_funcs_set_glyph_v_advance_func(
- funcs, HarfBuzzGetGlyphVerticalAdvance, nullptr, nullptr);
- hb_font_funcs_set_glyph_v_origin_func(funcs, HarfBuzzGetGlyphVerticalOrigin,
- nullptr, nullptr);
- hb_font_funcs_set_glyph_extents_func(funcs, HarfBuzzGetGlyphExtents,
+ }
+ hb_font_funcs_set_variation_glyph_func(funcs, HarfBuzzGetGlyph, nullptr,
+ nullptr);
+ hb_font_funcs_set_nominal_glyph_func(funcs, HarfBuzzGetNominalGlyph, nullptr,
+ nullptr);
+ // TODO(https://crbug.com/899718): Replace vertical metrics callbacks with
+ // HarfBuzz VORG/VMTX internal implementation by deregistering those.
+ hb_font_funcs_set_glyph_v_advance_func(funcs, HarfBuzzGetGlyphVerticalAdvance,
nullptr, nullptr);
- hb_font_funcs_make_immutable(funcs);
- FontGlobalContext::SetHarfBuzzFontFuncs(funcs);
+ hb_font_funcs_set_glyph_v_origin_func(funcs, HarfBuzzGetGlyphVerticalOrigin,
+ nullptr, nullptr);
+ hb_font_funcs_set_glyph_extents_func(funcs, HarfBuzzGetGlyphExtents, nullptr,
+ nullptr);
+
+ hb_font_funcs_make_immutable(funcs);
+ return funcs;
+}
+
+static hb_font_funcs_t* HarfBuzzSkiaGetFontFuncs(
+ FontGlobalContext::HorizontalAdvanceSource advance_source) {
+ hb_font_funcs_t* funcs =
+ FontGlobalContext::GetHarfBuzzFontFuncs(advance_source);
+
+ // We don't set callback functions which we can't support.
+ // HarfBuzz will use the fallback implementation if they aren't set.
+ if (!funcs) {
+ funcs = create_populated_hb_font_funcs(advance_source);
+ FontGlobalContext::SetHarfBuzzFontFuncs(advance_source, funcs);
}
DCHECK(funcs);
return funcs;
@@ -360,11 +382,10 @@ hb_face_t* HarfBuzzFace::CreateFace() {
if (tf_stream && tf_stream->getMemoryBase()) {
const void* tf_memory = tf_stream->getMemoryBase();
size_t tf_size = tf_stream->getLength();
- std::unique_ptr<hb_blob_t, void (*)(hb_blob_t*)> face_blob(
+ HbScoped<hb_blob_t> face_blob(
hb_blob_create(reinterpret_cast<const char*>(tf_memory),
SafeCast<unsigned int>(tf_size), HB_MEMORY_MODE_READONLY,
- tf_stream.release(), DeleteTypefaceStream),
- hb_blob_destroy);
+ tf_stream.release(), DeleteTypefaceStream));
face = hb_face_create(face_blob.get(), ttc_index);
}
#endif
@@ -382,15 +403,39 @@ hb_face_t* HarfBuzzFace::CreateFace() {
return face;
}
-scoped_refptr<HbFontCacheEntry> CreateHbFontCacheEntry(hb_face_t* face) {
- HbFontUniquePtr ot_font(hb_font_create(face));
+scoped_refptr<HbFontCacheEntry> CreateHbFontCacheEntry(hb_face_t* face,
+ SkTypeface* typeface) {
+ HbScoped<hb_font_t> ot_font(hb_font_create(face));
hb_ot_font_set_funcs(ot_font.get());
+
+ int axis_count = typeface->getVariationDesignPosition(nullptr, 0);
+ if (axis_count > 0) {
+ Vector<SkFontArguments::VariationPosition::Coordinate> axis_values;
+ axis_values.resize(axis_count);
+ if (typeface->getVariationDesignPosition(axis_values.data(),
+ axis_values.size()) > 0) {
+ hb_font_set_variations(
+ ot_font.get(), reinterpret_cast<hb_variation_t*>(axis_values.data()),
+ axis_values.size());
+ }
+ }
+
// Creating a sub font means that non-available functions
// are found from the parent.
hb_font_t* unscaled_font = hb_font_create_sub_font(ot_font.get());
scoped_refptr<HbFontCacheEntry> cache_entry =
HbFontCacheEntry::Create(unscaled_font);
- hb_font_set_funcs(unscaled_font, HarfBuzzSkiaGetFontFuncs(),
+
+ FontGlobalContext::HorizontalAdvanceSource advance_source =
+ FontGlobalContext::kSkiaHorizontalAdvances;
+#if defined(OS_MACOSX)
+ bool has_trak = false;
+ bool has_sbix = false;
+ DetermineTrakSbix(typeface, &has_trak, &has_sbix);
+ if (has_trak && !has_sbix)
+ advance_source = FontGlobalContext::kHarfBuzzHorizontalAdvances;
+#endif
+ hb_font_set_funcs(unscaled_font, HarfBuzzSkiaGetFontFuncs(advance_source),
cache_entry->HbFontData(), nullptr);
return cache_entry;
}
@@ -423,19 +468,6 @@ hb_font_t* HarfBuzzFace::GetScaledFont(
// equivalent of CSS pixels here.
hb_font_set_ptem(unscaled_font_, platform_data_->size());
- SkTypeface* typeface = harfbuzz_font_data_->font_.getTypeface();
- int axis_count = typeface->getVariationDesignPosition(nullptr, 0);
- if (axis_count > 0) {
- Vector<SkFontArguments::VariationPosition::Coordinate> axis_values;
- axis_values.resize(axis_count);
- if (typeface->getVariationDesignPosition(axis_values.data(),
- axis_values.size()) > 0) {
- hb_font_set_variations(
- unscaled_font_, reinterpret_cast<hb_variation_t*>(axis_values.data()),
- axis_values.size());
- }
- }
-
return unscaled_font_;
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.cc
index 02690dd9854..40ad779aaed 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.cc
@@ -8,7 +8,7 @@
namespace blink {
HbFontCacheEntry::HbFontCacheEntry(hb_font_t* font)
- : hb_font_(HbFontUniquePtr(font)),
+ : hb_font_(HbScoped<hb_font_t>(font)),
hb_font_data_(std::make_unique<HarfBuzzFontData>()) {}
HbFontCacheEntry::~HbFontCacheEntry() = default;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.h
index 5826f0a6bba..d8526a9352a 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.h
@@ -5,30 +5,18 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_HARFBUZZ_FONT_CACHE_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_HARFBUZZ_FONT_CACHE_H_
+#include <hb.h>
+
#include <memory>
#include "third_party/blink/renderer/platform/fonts/font_metrics.h"
#include "third_party/blink/renderer/platform/fonts/unicode_range_set.h"
-
-struct hb_font_t;
-struct hb_face_t;
+#include "third_party/harfbuzz-ng/utils/hb_scoped.h"
namespace blink {
struct HarfBuzzFontData;
-struct HbFontDeleter {
- void operator()(hb_font_t* font);
-};
-
-using HbFontUniquePtr = std::unique_ptr<hb_font_t, HbFontDeleter>;
-
-struct HbFaceDeleter {
- void operator()(hb_face_t* face);
-};
-
-using HbFaceUniquePtr = std::unique_ptr<hb_face_t, HbFaceDeleter>;
-
// Though we have FontCache class, which provides the cache mechanism for
// WebKit's font objects, we also need additional caching layer for HarfBuzz to
// reduce the number of hb_font_t objects created. Without it, we would create
@@ -50,15 +38,17 @@ class HbFontCacheEntry : public RefCounted<HbFontCacheEntry> {
private:
explicit HbFontCacheEntry(hb_font_t* font);
- HbFontUniquePtr hb_font_;
+ HbScoped<hb_font_t> hb_font_;
std::unique_ptr<HarfBuzzFontData> hb_font_data_;
};
-typedef HashMap<uint64_t,
- scoped_refptr<HbFontCacheEntry>,
- WTF::IntHash<uint64_t>,
- WTF::UnsignedWithZeroKeyHashTraits<uint64_t>>
- HarfBuzzFontCache;
+// Declare as derived class in order to be able to forward-declare it as class
+// in FontGlobalContext.
+class HarfBuzzFontCache
+ : public HashMap<uint64_t,
+ scoped_refptr<HbFontCacheEntry>,
+ WTF::IntHash<uint64_t>,
+ WTF::UnsignedWithZeroKeyHashTraits<uint64_t>> {};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_fuzzer.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_fuzzer.cc
index 186cb357c9c..b63c48d9513 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_fuzzer.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_fuzzer.cc
@@ -36,9 +36,8 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
Font font(font_description);
// Set font size to something other than the default 0 size in
// FontDescription, 16 matches the default text size in HTML.
+ // We don't use a FontSelector here. Only look for system fonts for now.
font_description.SetComputedSize(16.0f);
- // Only look for system fonts for now.
- font.Update(nullptr);
HarfBuzzShaper shaper(String(converted_input_buffer, converted_length));
scoped_refptr<ShapeResult> result = shaper.Shape(&font, TextDirection::kLtr);
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc
index 9cca0e58d2b..6c03756d4c4 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper_test.cc
@@ -83,7 +83,6 @@ class HarfBuzzShaperTest : public testing::Test {
void SetUp() override {
font_description.SetComputedSize(12.0);
font = Font(font_description);
- font.Update(nullptr);
}
void TearDown() override {}
@@ -101,7 +100,6 @@ class HarfBuzzShaperTest : public testing::Test {
font_description.SetFamily(devanagari_family);
font = Font(font_description);
- font.Update(nullptr);
}
Font CreateAhem(float size) {
@@ -472,7 +470,6 @@ TEST_F(HarfBuzzShaperTest, ShapeTabulationCharacters) {
TEST_F(HarfBuzzShaperTest, ShapeVerticalUpright) {
font_description.SetOrientation(FontOrientation::kVerticalUpright);
font = Font(font_description);
- font.Update(nullptr);
// This string should create 2 runs, ideographic and Latin, both in upright.
String string(u"\u65E5\u65E5\u65E5lllll");
@@ -496,7 +493,6 @@ TEST_F(HarfBuzzShaperTest, ShapeVerticalUpright) {
TEST_F(HarfBuzzShaperTest, ShapeVerticalUprightIdeograph) {
font_description.SetOrientation(FontOrientation::kVerticalUpright);
font = Font(font_description);
- font.Update(nullptr);
// This string should create one ideograph run.
String string(u"\u65E5\u65E6\u65E0\u65D3\u65D0");
@@ -527,7 +523,6 @@ TEST_F(HarfBuzzShaperTest, RangeShapeSmallCaps) {
font_description.SetVariantCaps(FontDescription::kSmallCaps);
font_description.SetComputedSize(12.0);
Font font(font_description);
- font.Update(nullptr);
// Shaping index 2 to 3 means that case splitting for small caps splits before
// character index 2 since the initial 'a' needs to be uppercased, but the
@@ -563,7 +558,6 @@ TEST_F(HarfBuzzShaperTest, RangeShapeSmallCaps) {
TEST_F(HarfBuzzShaperTest, ShapeVerticalMixed) {
font_description.SetOrientation(FontOrientation::kVerticalMixed);
font = Font(font_description);
- font.Update(nullptr);
// This string should create 2 runs, ideographic in upright and Latin in
// rotated horizontal.
@@ -1634,10 +1628,7 @@ static bool KerningIsHappening(const FontDescription& font_description,
kern.SetKerning(FontDescription::kAutoKerning);
Font font_no_kern(no_kern);
- font_no_kern.Update(nullptr);
-
Font font_kern(kern);
- font_kern.Update(nullptr);
HarfBuzzShaper shaper(str);
@@ -1749,7 +1740,6 @@ TEST_F(HarfBuzzShaperTest, ShapeVerticalWithoutSubpixelPositionIsRounded) {
font_description.SetOrientation(FontOrientation::kVerticalUpright);
font = Font(font_description);
- font.Update(nullptr);
String string(u"\u65E5\u65E5\u65E5");
TextDirection direction = TextDirection::kLtr;
@@ -1769,7 +1759,6 @@ TEST_F(HarfBuzzShaperTest, ShapeVerticalWithSubpixelPositionIsRounded) {
font_description.SetOrientation(FontOrientation::kVerticalUpright);
font = Font(font_description);
- font.Update(nullptr);
String string(u"\u65E5\u65E5\u65E5");
TextDirection direction = TextDirection::kLtr;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_cache.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_cache.h
index b6a3ff992b0..9dfd507dd0b 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_cache.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_cache.h
@@ -39,11 +39,7 @@
namespace blink {
-struct ShapeCacheEntry {
- DISALLOW_NEW();
- ShapeCacheEntry() { shape_result_ = nullptr; }
- scoped_refptr<const ShapeResult> shape_result_;
-};
+using ShapeCacheEntry = scoped_refptr<const ShapeResult>;
class ShapeCache {
USING_FAST_MALLOC(ShapeCache);
@@ -118,7 +114,7 @@ class ShapeCache {
if (run.length() > SmallStringKey::Capacity())
return nullptr;
- return AddSlowCase(run, entry);
+ return AddSlowCase(run, std::move(entry));
}
void ClearIfVersionChanged(unsigned version) {
@@ -140,10 +136,10 @@ class ShapeCache {
size_t ByteSize() const {
size_t self_byte_size = 0;
for (auto cache_entry : single_char_map_) {
- self_byte_size += cache_entry.value.shape_result_->ByteSize();
+ self_byte_size += cache_entry.value->ByteSize();
}
for (auto cache_entry : short_string_map_) {
- self_byte_size += cache_entry.value.shape_result_->ByteSize();
+ self_byte_size += cache_entry.value->ByteSize();
}
return self_byte_size;
}
@@ -160,7 +156,8 @@ class ShapeCache {
// as such use bit 31 (zero-based) to indicate direction.
if (run.Direction() == TextDirection::kRtl)
key |= (1u << 31);
- SingleCharMap::AddResult add_result = single_char_map_.insert(key, entry);
+ SingleCharMap::AddResult add_result =
+ single_char_map_.insert(key, std::move(entry));
is_new_entry = add_result.is_new_entry;
value = &add_result.stored_value->value;
} else {
@@ -170,9 +167,8 @@ class ShapeCache {
} else {
small_string_key = SmallStringKey(run.Span16(), run.Direction());
}
-
SmallStringMap::AddResult add_result =
- short_string_map_.insert(small_string_key, entry);
+ short_string_map_.insert(small_string_key, std::move(entry));
is_new_entry = add_result.is_new_entry;
value = &add_result.stored_value->value;
}
@@ -202,6 +198,7 @@ class ShapeCache {
struct SmallStringKeyHashTraits : WTF::SimpleClassHashTraits<SmallStringKey> {
STATIC_ONLY(SmallStringKeyHashTraits);
static const bool kHasIsEmptyValueFunction = true;
+ static const bool kEmptyValueIsZero = false;
static bool IsEmptyValue(const SmallStringKey& key) {
return key.IsHashTableEmptyValue();
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc
index 3a73c9a9d8e..81864362264 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc
@@ -565,7 +565,7 @@ unsigned ShapeResult::OffsetToFit(float x, TextDirection line_direction) const {
if (IsLtr(line_direction))
return result.left_character_index;
- if (x == result.origin_x && IsRtl(Direction()))
+ if (x == result.origin_x)
return result.left_character_index;
return result.right_character_index;
}
@@ -1450,6 +1450,96 @@ scoped_refptr<ShapeResult> ShapeResult::CreateForSpaces(const Font* font,
return result;
}
+scoped_refptr<ShapeResult> ShapeResult::CreateForStretchyMathOperator(
+ const Font* font,
+ TextDirection direction,
+ OpenTypeMathStretchData::StretchAxis stretch_axis,
+ Glyph glyph_variant,
+ float stretch_size) {
+ bool is_horizontal_assembly =
+ stretch_axis == OpenTypeMathStretchData::StretchAxis::Horizontal;
+ unsigned start_index = 0;
+ unsigned num_characters = 1;
+ scoped_refptr<ShapeResult> result =
+ ShapeResult::Create(font, start_index, num_characters, direction);
+
+ hb_direction_t hb_direction =
+ is_horizontal_assembly ? HB_DIRECTION_LTR : HB_DIRECTION_TTB;
+ unsigned glyph_index = 0;
+ scoped_refptr<ShapeResult::RunInfo> run = RunInfo::Create(
+ font->PrimaryFont(), hb_direction, CanvasRotationInVertical::kRegular,
+ HB_SCRIPT_COMMON, start_index, 1 /* num_glyph */, num_characters);
+ run->glyph_data_[glyph_index] = {glyph_variant, 0 /* character index */,
+ true /* IsSafeToBreakBefore */,
+ stretch_size};
+ run->width_ = std::max(0.0f, stretch_size);
+
+ result->width_ = run->width_;
+ result->num_glyphs_ = run->NumGlyphs();
+ result->runs_.push_back(std::move(run));
+
+ return result;
+}
+
+scoped_refptr<ShapeResult> ShapeResult::CreateForStretchyMathOperator(
+ const Font* font,
+ TextDirection direction,
+ OpenTypeMathStretchData::StretchAxis stretch_axis,
+ const OpenTypeMathStretchData::AssemblyParameters& assembly_parameters) {
+ DCHECK(!assembly_parameters.parts.IsEmpty());
+ DCHECK_LE(assembly_parameters.glyph_count, HarfBuzzRunGlyphData::kMaxGlyphs);
+
+ bool is_horizontal_assembly =
+ stretch_axis == OpenTypeMathStretchData::StretchAxis::Horizontal;
+ unsigned start_index = 0;
+ unsigned num_characters = 1;
+ scoped_refptr<ShapeResult> result =
+ ShapeResult::Create(font, start_index, num_characters, direction);
+
+ hb_direction_t hb_direction =
+ is_horizontal_assembly ? HB_DIRECTION_LTR : HB_DIRECTION_TTB;
+ scoped_refptr<ShapeResult::RunInfo> run = RunInfo::Create(
+ font->PrimaryFont(), hb_direction, CanvasRotationInVertical::kRegular,
+ HB_SCRIPT_COMMON, start_index, assembly_parameters.glyph_count,
+ num_characters);
+
+ float overlap = assembly_parameters.connector_overlap;
+ unsigned part_index = 0;
+ for (const auto& part : assembly_parameters.parts) {
+ unsigned repetition_count =
+ part.is_extender ? assembly_parameters.repetition_count : 1;
+ if (!repetition_count)
+ continue;
+ DCHECK(part_index < assembly_parameters.glyph_count);
+ for (unsigned repetition_index = 0; repetition_index < repetition_count;
+ repetition_index++) {
+ unsigned glyph_index =
+ is_horizontal_assembly
+ ? part_index
+ : assembly_parameters.glyph_count - 1 - part_index;
+ float full_advance = glyph_index == assembly_parameters.glyph_count - 1
+ ? part.full_advance
+ : part.full_advance - overlap;
+ run->glyph_data_[glyph_index] = {part.glyph, 0 /* character index */,
+ !glyph_index /* IsSafeToBreakBefore */,
+ full_advance};
+ if (!is_horizontal_assembly) {
+ GlyphOffset glyph_offset(
+ 0, -assembly_parameters.stretch_size + part.full_advance);
+ run->glyph_data_.SetOffsetAt(glyph_index, glyph_offset);
+ result->has_vertical_offsets_ |= (glyph_offset.Height() != 0);
+ }
+ part_index++;
+ }
+ }
+ run->width_ = std::max(0.0f, assembly_parameters.stretch_size);
+
+ result->width_ = run->width_;
+ result->num_glyphs_ = run->NumGlyphs();
+ result->runs_.push_back(std::move(run));
+ return result;
+}
+
void ShapeResult::ToString(StringBuilder* output) const {
output->Append("#chars=");
output->AppendNumber(num_characters_);
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.h
index eeb7e99b05f..d63fdd62f44 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.h
@@ -35,6 +35,7 @@
#include "base/containers/span.h"
#include "third_party/blink/renderer/platform/fonts/canvas_rotation_in_vertical.h"
#include "third_party/blink/renderer/platform/fonts/glyph.h"
+#include "third_party/blink/renderer/platform/fonts/opentype/open_type_math_stretch_data.h"
#include "third_party/blink/renderer/platform/fonts/simple_font_data.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/geometry/layout_unit.h"
@@ -142,6 +143,17 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> {
unsigned start_index,
unsigned length,
float width);
+ static scoped_refptr<ShapeResult> CreateForStretchyMathOperator(
+ const Font*,
+ TextDirection,
+ OpenTypeMathStretchData::StretchAxis,
+ Glyph,
+ float stretch_size);
+ static scoped_refptr<ShapeResult> CreateForStretchyMathOperator(
+ const Font*,
+ TextDirection,
+ OpenTypeMathStretchData::StretchAxis,
+ const OpenTypeMathStretchData::AssemblyParameters&);
~ShapeResult();
// Returns a mutable unique instance. If |this| has more than 1 ref count,
@@ -495,6 +507,7 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> {
friend class ShapeResultBloberizer;
friend class ShapeResultView;
friend class ShapeResultTest;
+ friend class StretchyOperatorShaper;
template <bool has_non_zero_glyph_offsets>
float ForEachGlyphImpl(float initial_advance,
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer_test.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer_test.cc
index 17be9dacea0..91a4ccffadc 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer_test.cc
@@ -39,7 +39,6 @@ class ShapeResultBloberizerTest : public testing::Test {
font_description.SetGenericFamily(FontDescription::kStandardFamily);
font = Font(font_description);
- font.Update(nullptr);
ASSERT_TRUE(font.CanShapeWordByWord());
fallback_fonts = nullptr;
cache = std::make_unique<ShapeCache>();
@@ -267,7 +266,6 @@ TEST_F(ShapeResultBloberizerTest, CommonAccentLeftToRightFillGlyphBuffer) {
bloberizer.FillGlyphs(run_info, buffer);
Font reference_font(font_description);
- reference_font.Update(nullptr);
reference_font.SetCanShapeWordByWordForTesting(false);
ShapeResultBloberizer reference_bloberizer(reference_font, 1);
@@ -305,7 +303,6 @@ TEST_F(ShapeResultBloberizerTest, CommonAccentRightToLeftFillGlyphBuffer) {
bloberizer.FillGlyphs(run_info, buffer);
Font reference_font(font_description);
- reference_font.Update(nullptr);
reference_font.SetCanShapeWordByWordForTesting(false);
ShapeResultBloberizer reference_bloberizer(reference_font, 1);
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.cc
index 73f8a4c0fe3..758065226be 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.cc
@@ -130,7 +130,7 @@ Vector<CharacterRange> ShapeResultBuffer::IndividualCharacterRanges(
float total_width) const {
Vector<CharacterRange> ranges;
float current_x = direction == TextDirection::kRtl ? total_width : 0;
- for (const scoped_refptr<const ShapeResult> result : results_)
+ for (const scoped_refptr<const ShapeResult>& result : results_)
current_x = result->IndividualCharacterRanges(&ranges, current_x);
return ranges;
}
@@ -192,7 +192,7 @@ Vector<double> ShapeResultBuffer::IndividualCharacterAdvances(
Vector<double> advances;
double current_x = direction == TextDirection::kRtl ? total_width : 0;
- for (const scoped_refptr<const ShapeResult> result : results_) {
+ for (const scoped_refptr<const ShapeResult>& result : results_) {
unsigned run_count = result->runs_.size();
result->EnsureGraphemes(
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h
index a1a6708907c..32fa8f2ab73 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h
@@ -211,7 +211,7 @@ struct ShapeResult::RunInfo : public RefCounted<ShapeResult::RunInfo> {
}
if (!Rtl())
- end = num_characters_;
+ end = offset + num_characters_;
else
end = start;
start = index;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_test.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_test.cc
index 3738a170f1d..8dac0939e7b 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_test.cc
@@ -21,7 +21,6 @@ class ShapeResultTest : public testing::Test {
void SetUp() override {
font_description.SetComputedSize(12.0);
font = Font(font_description);
- font.Update(nullptr);
FontDescription::VariantLigatures ligatures;
arabic_font = blink::test::CreateTestFont(
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.cc
index 9e558346965..dd4998fb3c0 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.cc
@@ -83,6 +83,15 @@ struct ShapeResultView::RunInfoPart {
// |base::span<RunInfoPart>|.
const RunInfoPart* get() const { return this; }
+ void ExpandRangeToIncludePartialGlyphs(unsigned offset,
+ unsigned* from,
+ unsigned* to) const {
+ DCHECK_GE(offset + start_index_, offset_);
+ unsigned part_offset = offset + start_index_ - offset_;
+ run_->ExpandRangeToIncludePartialGlyphs(
+ part_offset, reinterpret_cast<int*>(from), reinterpret_cast<int*>(to));
+ }
+
scoped_refptr<const ShapeResult::RunInfo> run_;
ShapeResult::RunInfo::GlyphDataRange range_;
@@ -633,4 +642,13 @@ FloatRect ShapeResultView::ComputeInkBounds() const {
return ink_bounds;
}
+void ShapeResultView::ExpandRangeToIncludePartialGlyphs(unsigned* from,
+ unsigned* to) const {
+ unsigned accumulated_offset = char_index_offset_;
+ for (const auto& part : Parts()) {
+ part.ExpandRangeToIncludePartialGlyphs(accumulated_offset, from, to);
+ accumulated_offset += part.NumCharacters();
+ }
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h
index 591dff49962..05c7fa1563d 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h
@@ -145,9 +145,11 @@ class PLATFORM_EXPORT ShapeResultView final
}
void GetRunFontData(Vector<ShapeResult::RunFontData>*) const;
+ void ExpandRangeToIncludePartialGlyphs(unsigned* from, unsigned* to) const;
+
private:
template <class ShapeResultType>
- ShapeResultView(const ShapeResultType*);
+ explicit ShapeResultView(const ShapeResultType*);
struct RunInfoPart;
template <class ShapeResultType>
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view_test.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view_test.cc
index ce0f6ccb82b..85c46054789 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_view_test.cc
@@ -21,7 +21,6 @@ class ShapeResultViewTest : public testing::Test {
void SetUp() override {
font_description.SetComputedSize(12.0);
font = Font(font_description);
- font.Update(nullptr);
}
void TearDown() override {}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker_test.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker_test.cc
index 82eeefad31b..b0296b7f786 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker_test.cc
@@ -52,7 +52,6 @@ class ShapingLineBreakerTest : public testing::Test {
void SetUp() override {
font_description.SetComputedSize(12.0);
font = Font(font_description);
- font.Update(nullptr);
}
void TearDown() override {}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.cc
new file mode 100644
index 00000000000..99c80b364f4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.cc
@@ -0,0 +1,223 @@
+// 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/fonts/shaping/stretchy_operator_shaper.h"
+
+#include <hb-ot.h>
+#include <hb.h>
+#include <unicode/uchar.h>
+
+#include "third_party/blink/renderer/platform/fonts/canvas_rotation_in_vertical.h"
+#include "third_party/blink/renderer/platform/fonts/font.h"
+#include "third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.h"
+#include "third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.h"
+#include "third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h"
+#include "third_party/blink/renderer/platform/geometry/float_rect.h"
+#include "third_party/blink/renderer/platform/wtf/text/unicode.h"
+#include "ui/gfx/skia_util.h"
+
+namespace blink {
+
+namespace {
+
+// HarfBuzz' hb_position_t is a 16.16 fixed-point value.
+inline float HarfBuzzUnitsToFloat(hb_position_t value) {
+ static const float kFloatToHbRatio = 1.0f / (1 << 16);
+ return kFloatToHbRatio * value;
+}
+
+inline float GetGlyphStretchSize(
+ FloatRect bounds,
+ OpenTypeMathStretchData::StretchAxis stretch_axis) {
+ return stretch_axis == OpenTypeMathStretchData::StretchAxis::Horizontal
+ ? bounds.Width()
+ : bounds.Height();
+}
+
+inline StretchyOperatorShaper::Metrics ToMetrics(FloatRect bounds) {
+ return {bounds.Width(), -bounds.Y(), bounds.MaxY()};
+}
+
+base::Optional<OpenTypeMathStretchData::AssemblyParameters>
+GetAssemblyParameters(const HarfBuzzFace* harfbuzz_face,
+ Glyph base_glyph,
+ OpenTypeMathStretchData::StretchAxis stretch_axis,
+ float target_size) {
+ Vector<OpenTypeMathStretchData::GlyphPartRecord> parts =
+ OpenTypeMathSupport::GetGlyphPartRecords(harfbuzz_face, base_glyph,
+ stretch_axis);
+ if (parts.IsEmpty())
+ return base::nullopt;
+
+ hb_font_t* hb_font =
+ harfbuzz_face->GetScaledFont(nullptr, HarfBuzzFace::NoVerticalLayout);
+
+ auto hb_stretch_axis =
+ stretch_axis == OpenTypeMathStretchData::StretchAxis::Horizontal
+ ? HB_DIRECTION_LTR
+ : HB_DIRECTION_BTT;
+
+ // Go over the assembly parts and determine parameters used below.
+ // https://mathml-refresh.github.io/mathml-core/#the-glyphassembly-table
+ float min_connector_overlap = HarfBuzzUnitsToFloat(
+ hb_ot_math_get_min_connector_overlap(hb_font, hb_stretch_axis));
+ float max_connector_overlap = std::numeric_limits<float>::max();
+ float non_extender_advance_sum = 0, extender_advance_sum = 0;
+ unsigned non_extender_count = 0, extender_count = 0;
+
+ for (auto& part : parts) {
+ // Calculate the count and advance sums of extender and non-extender glyphs.
+ if (part.is_extender) {
+ extender_count++;
+ extender_advance_sum += part.full_advance;
+ } else {
+ non_extender_count++;
+ non_extender_advance_sum += part.full_advance;
+ }
+
+ // Take into account start connector length for all but the first glyph.
+ if (part.is_extender || &part != &parts.front()) {
+ max_connector_overlap =
+ std::min(max_connector_overlap, part.start_connector_length);
+ }
+
+ // Take into account end connector length for all but the last glyph.
+ if (part.is_extender || &part != &parts.back()) {
+ max_connector_overlap =
+ std::min(max_connector_overlap, part.end_connector_length);
+ }
+ }
+
+ // Check validity conditions indicated in MathML core.
+ float extender_non_overlapping_advance_sum =
+ extender_advance_sum - min_connector_overlap * extender_count;
+ if (extender_count == 0 || max_connector_overlap < min_connector_overlap ||
+ extender_non_overlapping_advance_sum <= 0)
+ return base::nullopt;
+
+ // Calculate the minimal number of repetitions needed to obtain an assembly
+ // size of size at least target size (r_min in MathML Core).
+ unsigned repetition_count = std::max<float>(
+ std::ceil((target_size - non_extender_advance_sum +
+ min_connector_overlap * (non_extender_count - 1)) /
+ extender_non_overlapping_advance_sum),
+ 0);
+
+ // Calculate the number of glyphs, limiting repetition_count to ensure the
+ // assembly does not have more than HarfBuzzRunGlyphData::kMaxGlyphs.
+ DCHECK_LE(non_extender_count, HarfBuzzRunGlyphData::kMaxGlyphs);
+ repetition_count = std::min<unsigned>(
+ repetition_count,
+ (HarfBuzzRunGlyphData::kMaxGlyphs - non_extender_count) / extender_count);
+ unsigned glyph_count = non_extender_count + repetition_count * extender_count;
+ DCHECK_LE(glyph_count, HarfBuzzRunGlyphData::kMaxGlyphs);
+
+ // Calculate the maximum overlap (called o_max in MathML Core) and the number
+ // of glyph in such an assembly (called N in MathML Core).
+ float connector_overlap = max_connector_overlap;
+ if (glyph_count > 1) {
+ float max_connector_overlap_theorical =
+ (non_extender_advance_sum + repetition_count * extender_advance_sum -
+ target_size) /
+ (glyph_count - 1);
+ connector_overlap =
+ std::max(min_connector_overlap,
+ std::min(connector_overlap, max_connector_overlap_theorical));
+ }
+
+ // Calculate the assembly size (called AssemblySize(o, r) in MathML Core).
+ float stretch_size = non_extender_advance_sum +
+ repetition_count * extender_advance_sum -
+ connector_overlap * (glyph_count - 1);
+
+ return base::Optional<OpenTypeMathStretchData::AssemblyParameters>(
+ {connector_overlap, repetition_count, glyph_count, stretch_size,
+ std::move(parts)});
+}
+
+} // namespace
+
+StretchyOperatorShaper::Metrics StretchyOperatorShaper::GetMetrics(
+ const Font* font,
+ float target_size) const {
+ const SimpleFontData* primary_font = font->PrimaryFont();
+ const HarfBuzzFace* harfbuzz_face =
+ primary_font->PlatformData().GetHarfBuzzFace();
+ Glyph base_glyph = primary_font->GlyphForCharacter(stretchy_character_);
+
+ FloatRect bounds;
+
+ // Try different glyph variants.
+ for (auto& variant : OpenTypeMathSupport::GetGlyphVariantRecords(
+ harfbuzz_face, base_glyph, stretch_axis_)) {
+ bounds = primary_font->BoundsForGlyph(variant);
+ if (GetGlyphStretchSize(bounds, stretch_axis_) >= target_size)
+ return ToMetrics(bounds);
+ }
+
+ // Try a glyph assembly.
+ auto params = GetAssemblyParameters(harfbuzz_face, base_glyph, stretch_axis_,
+ target_size);
+ if (!params)
+ return ToMetrics(bounds);
+
+ bounds = stretch_axis_ == OpenTypeMathStretchData::StretchAxis::Horizontal
+ ? FloatRect(0, 0, params->stretch_size, 0)
+ : FloatRect(0, -params->stretch_size, 0, params->stretch_size);
+
+ for (auto& part : params->parts) {
+ // Include dimension of the part, orthogonal to the stretch axis.
+ auto glyph_bounds = primary_font->BoundsForGlyph(part.glyph);
+ if (stretch_axis_ == OpenTypeMathStretchData::StretchAxis::Horizontal) {
+ glyph_bounds.SetX(0);
+ glyph_bounds.SetWidth(0);
+ } else {
+ glyph_bounds.SetY(0);
+ glyph_bounds.SetHeight(0);
+ }
+ bounds.UniteEvenIfEmpty(glyph_bounds);
+ }
+
+ return ToMetrics(bounds);
+}
+
+scoped_refptr<ShapeResult> StretchyOperatorShaper::Shape(
+ const Font* font,
+ float target_size) const {
+ const SimpleFontData* primary_font = font->PrimaryFont();
+ const HarfBuzzFace* harfbuzz_face =
+ primary_font->PlatformData().GetHarfBuzzFace();
+ Glyph base_glyph = primary_font->GlyphForCharacter(stretchy_character_);
+
+ Glyph glyph_variant;
+ float glyph_variant_stretch_size;
+ TextDirection direction = TextDirection::kLtr;
+
+ // Try different glyph variants.
+ for (auto& variant : OpenTypeMathSupport::GetGlyphVariantRecords(
+ harfbuzz_face, base_glyph, stretch_axis_)) {
+ glyph_variant = variant;
+ auto bounds = primary_font->BoundsForGlyph(glyph_variant);
+ glyph_variant_stretch_size = GetGlyphStretchSize(bounds, stretch_axis_);
+ if (glyph_variant_stretch_size >= target_size) {
+ return ShapeResult::CreateForStretchyMathOperator(
+ font, direction, stretch_axis_, glyph_variant,
+ glyph_variant_stretch_size);
+ }
+ }
+
+ // Try a glyph assembly.
+ auto params = GetAssemblyParameters(harfbuzz_face, base_glyph, stretch_axis_,
+ target_size);
+ if (!params) {
+ return ShapeResult::CreateForStretchyMathOperator(
+ font, direction, stretch_axis_, glyph_variant,
+ glyph_variant_stretch_size);
+ }
+
+ return ShapeResult::CreateForStretchyMathOperator(
+ font, direction, stretch_axis_, std::move(*params));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.h
new file mode 100644
index 00000000000..4df0edaed15
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper.h
@@ -0,0 +1,59 @@
+// 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_FONTS_SHAPING_STRETCHY_OPERATOR_SHAPER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_STRETCHY_OPERATOR_SHAPER_H_
+
+#include <base/memory/scoped_refptr.h>
+#include <unicode/uchar.h>
+#include "third_party/blink/renderer/platform/fonts/glyph.h"
+#include "third_party/blink/renderer/platform/fonts/opentype/open_type_math_support.h"
+#include "third_party/blink/renderer/platform/text/text_direction.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+
+namespace blink {
+
+class Font;
+class ShapeResult;
+class StretchyOperatorShaper;
+
+// TODO(https://crbug.com/1057589): Add a TextDirection parameter, so that it's
+// possible to perform glyph-level (rtlm feature) or character-level mirroring
+// before stretching.
+// https://mathml-refresh.github.io/mathml-core/#algorithms-for-glyph-stretching
+class PLATFORM_EXPORT StretchyOperatorShaper final {
+ DISALLOW_NEW();
+
+ public:
+ StretchyOperatorShaper(UChar stretchy_character,
+ OpenTypeMathStretchData::StretchAxis stretch_axis)
+ : stretchy_character_(stretchy_character), stretch_axis_(stretch_axis) {}
+
+ // Returns the metrics of the stretched operator for layout purpose.
+ // May be called multiple times; font and direction may vary between calls.
+ // https://mathml-refresh.github.io/mathml-core/#dfn-box-metrics-of-a-stretchy-glyph
+ struct Metrics {
+ float advance;
+ float ascent;
+ float descent;
+ // TODO(https://crbug.com/1057592): Add italic correction.
+ };
+ Metrics GetMetrics(const Font*, float target_size) const;
+
+ // Shape the stretched operator. The coordinates of the glyph(s) use the same
+ // origin as the rectangle returned by GetMetrics.
+ // May be called multiple times; font and direction may vary between calls.
+ // https://mathml-refresh.github.io/mathml-core/#dfn-shape-a-stretchy-glyph
+ scoped_refptr<ShapeResult> Shape(const Font*, float target_size) const;
+
+ ~StretchyOperatorShaper() = default;
+
+ private:
+ const UChar stretchy_character_;
+ const OpenTypeMathStretchData::StretchAxis stretch_axis_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_STRETCHY_OPERATOR_SHAPER_H_
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
new file mode 100644
index 00000000000..1fd1aeaf8bb
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/stretchy_operator_shaper_test.cc
@@ -0,0 +1,264 @@
+// 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/fonts/shaping/stretchy_operator_shaper.h"
+#include "base/memory/scoped_refptr.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/fonts/font.h"
+#include "third_party/blink/renderer/platform/fonts/opentype/open_type_types.h"
+#include "third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h"
+#include "third_party/blink/renderer/platform/fonts/shaping/shape_result_test_info.h"
+#include "third_party/blink/renderer/platform/testing/font_test_helpers.h"
+#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+
+namespace blink {
+
+namespace {
+
+const UChar32 kLeftBraceCodePoint = '{';
+const UChar32 kOverBraceCodePoint = 0x23DE;
+const UChar32 kArabicMathOperatorHahWithDalCodePoint = 0x1EEF1;
+float kSizeError = .1;
+
+ShapeResultTestInfo* TestInfo(const scoped_refptr<ShapeResult>& result) {
+ return static_cast<ShapeResultTestInfo*>(result.get());
+}
+
+} // namespace
+
+class StretchyOperatorShaperTest : public testing::Test {
+ protected:
+ void SetUp() override {
+ font_description.SetComputedSize(10.0);
+ font = Font(font_description);
+ }
+
+ void TearDown() override {}
+
+ Font CreateMathFont(const String& name, float size = 1000) {
+ FontDescription::VariantLigatures ligatures;
+ return blink::test::CreateTestFont(
+ "MathTestFont",
+ blink::test::BlinkWebTestsFontsTestDataPath(String("math/") + name),
+ size, &ligatures);
+ }
+
+ FontDescription font_description;
+ Font font;
+};
+
+// See createStretchy() in
+// third_party/blink/web_tests/external/wpt/mathml/tools/operator-dictionary.py
+TEST_F(StretchyOperatorShaperTest, GlyphVariants) {
+ Font math = CreateMathFont("operators.woff");
+
+ StretchyOperatorShaper vertical_shaper(
+ kLeftBraceCodePoint, OpenTypeMathStretchData::StretchAxis::Vertical);
+ StretchyOperatorShaper horizontal_shaper(
+ kOverBraceCodePoint, OpenTypeMathStretchData::StretchAxis::Horizontal);
+
+ auto left_brace = math.PrimaryFont()->GlyphForCharacter(kLeftBraceCodePoint);
+ auto over_brace = math.PrimaryFont()->GlyphForCharacter(kOverBraceCodePoint);
+
+ // Calculate glyph indices from the last unicode character in the font.
+ // TODO(https://crbug.com/1057596): Find a better way to access these glyph
+ // indices.
+ auto v0 = math.PrimaryFont()->GlyphForCharacter(
+ kArabicMathOperatorHahWithDalCodePoint) +
+ 1;
+ auto h0 = v0 + 1;
+ auto v1 = h0 + 1;
+ auto h1 = v1 + 1;
+ auto v2 = h1 + 1;
+ auto h2 = v2 + 1;
+
+ // Stretch operators to target sizes (in font units) 125, 250, 375, 500, 625,
+ // 750, 875, 1000, 1125, ..., 3750, 3875, 4000.
+ //
+ // Shaper tries glyphs over_brace/left_brace, h0/v0, h1/v1, h2/v2, h3/v3 of
+ // respective sizes 1000, 1000, 2000, 3000 and 4000. It returns the smallest
+ // glyph larger than the target size.
+ const unsigned size_count = 4;
+ const unsigned subdivision = 8;
+ for (unsigned i = 0; i < size_count; i++) {
+ for (unsigned j = 1; j <= subdivision; j++) {
+ // Due to floating-point errors, the actual metrics of the size variants
+ // might actually be slightly smaller than expected. Reduce the
+ // target_size by kSizeError to ensure that the shaper picks the desired
+ // size variant.
+ float target_size = i * 1000 + (j * 1000 / subdivision) - kSizeError;
+
+ // Metrics of horizontal size variants.
+ {
+ auto metrics = horizontal_shaper.GetMetrics(&math, target_size);
+ EXPECT_NEAR(metrics.advance, (i + 1) * 1000, kSizeError);
+ EXPECT_NEAR(metrics.ascent, 1000, kSizeError);
+ EXPECT_FLOAT_EQ(metrics.descent, 0);
+ }
+
+ // Metrics of vertical size variants.
+
+ {
+ auto metrics = vertical_shaper.GetMetrics(&math, target_size);
+ EXPECT_NEAR(metrics.advance, 1000, kSizeError);
+ EXPECT_NEAR(metrics.ascent, (i + 1) * 1000, kSizeError);
+ EXPECT_FLOAT_EQ(metrics.descent, 0);
+ }
+
+ // Shaping of horizontal size variants.
+ {
+ scoped_refptr<ShapeResult> result =
+ horizontal_shaper.Shape(&math, target_size);
+ EXPECT_EQ(TestInfo(result)->NumberOfRunsForTesting(), 1u);
+ EXPECT_EQ(TestInfo(result)->RunInfoForTesting(0).NumGlyphs(), 1u);
+ Glyph expected_variant = i ? h0 + 2 * i : over_brace;
+ EXPECT_EQ(TestInfo(result)->GlyphForTesting(0, 0), expected_variant);
+ EXPECT_NEAR(TestInfo(result)->AdvanceForTesting(0, 0), (i + 1) * 1000,
+ kSizeError);
+ }
+
+ // Shaping of vertical size variants.
+ {
+ scoped_refptr<ShapeResult> result =
+ vertical_shaper.Shape(&math, target_size);
+ EXPECT_EQ(TestInfo(result)->NumberOfRunsForTesting(), 1u);
+ EXPECT_EQ(TestInfo(result)->RunInfoForTesting(0).NumGlyphs(), 1u);
+ Glyph expected_variant = i ? v0 + 2 * i : left_brace;
+ EXPECT_EQ(TestInfo(result)->GlyphForTesting(0, 0), expected_variant);
+ EXPECT_NEAR(TestInfo(result)->AdvanceForTesting(0, 0), (i + 1) * 1000,
+ kSizeError);
+ }
+ }
+ }
+
+ // Stretch an operator to target sizes (in font units) much larger than 4000.
+ //
+ // This will force an assembly with the following parts:
+ // _____________________________________________________________
+ // Part | MaxStartOverlap | MaxEndOverlap | Advance | Extender |
+ // h2/v2 | 0 | 1000 | 3000 | false |
+ // h1/v1 | 1000 | 1000 | 2000 | true |
+ //
+ // For an assembly made of one non-extender glyph h2/v2 and repetition_count
+ // copies of extenders h1/v1, the size is
+ // advance(h2/v2) + repetition_count * (advance(h1/v1) - overlap).
+ //
+ // For repetition_count = k and overlap = 750, the size is X = 1250k + 3000.
+ //
+ // Since the font min overlap is 500, for repetition_count = k - 1 the size
+ // is at most Y = 1500k + 1500.
+ //
+ // Since the max overlap of parts is 1000, for repetition_count = k + 1 the
+ // size is at least Z = 1000k + 4000.
+ //
+ // { X - 4000 = 1250k - 1000 >= 250 >> kSizeError for k >= 1.
+ // { X - Y = 1500 - 250k >= 250 >> kSizeError for k <= 5.
+ // Hence setting the target size to 1250k + 3000 will ensure an assembly of
+ // k + 1 glyphs and overlap close to 750 for 1 <= k <= 5.
+ //
+ // Additionally, X - Z = 250k - 1000 = 250 >> kSizeError for k = 5 so this
+ // case also verifies that the minimal number of repetitions is actually used.
+ //
+ for (unsigned repetition_count = 1; repetition_count <= 5;
+ repetition_count++) {
+ // It is not necessary to decrease the target_size by kSizeError here. The
+ // shaper can just increase overlap by kSizeError / repetition_count to
+ // reduce the actual size of the assembly.
+ float overlap = 750;
+ float target_size = 3000 + repetition_count * (2000 - overlap);
+
+ // Metrics of horizontal assembly.
+ {
+ auto metrics = horizontal_shaper.GetMetrics(&math, target_size);
+ EXPECT_NEAR(metrics.advance, target_size, kSizeError);
+ EXPECT_NEAR(metrics.ascent, 1000, kSizeError);
+ EXPECT_FLOAT_EQ(metrics.descent, 0);
+ }
+
+ // Metrics of vertical assembly.
+ {
+ auto metrics = vertical_shaper.GetMetrics(&math, target_size);
+ EXPECT_NEAR(metrics.advance, 1000, kSizeError);
+ EXPECT_NEAR(metrics.ascent, target_size, kSizeError);
+ EXPECT_FLOAT_EQ(metrics.descent, 0);
+ }
+
+ // Shaping of horizontal assembly.
+ // From left to right: h2, h1, h1, h1, ...
+ {
+ scoped_refptr<ShapeResult> result =
+ horizontal_shaper.Shape(&math, target_size);
+
+ EXPECT_EQ(TestInfo(result)->NumberOfRunsForTesting(), 1u);
+ EXPECT_EQ(TestInfo(result)->RunInfoForTesting(0).NumGlyphs(),
+ repetition_count + 1);
+ EXPECT_EQ(TestInfo(result)->GlyphForTesting(0, 0), h2);
+ EXPECT_NEAR(TestInfo(result)->AdvanceForTesting(0, 0), 3000 - overlap,
+ kSizeError);
+ for (unsigned i = 0; i < repetition_count - 1; i++) {
+ EXPECT_EQ(TestInfo(result)->GlyphForTesting(0, i + 1), h1);
+ EXPECT_NEAR(TestInfo(result)->AdvanceForTesting(0, i + 1),
+ 2000 - overlap, kSizeError);
+ }
+ EXPECT_EQ(TestInfo(result)->GlyphForTesting(0, repetition_count), h1);
+ EXPECT_NEAR(TestInfo(result)->AdvanceForTesting(0, repetition_count),
+ 2000, kSizeError);
+ }
+
+ // Shaping of vertical assembly.
+ // From bottom to top: v2, v1, v1, v1, ...
+ {
+ scoped_refptr<ShapeResult> result =
+ vertical_shaper.Shape(&math, target_size);
+
+ EXPECT_EQ(TestInfo(result)->NumberOfRunsForTesting(), 1u);
+ EXPECT_EQ(TestInfo(result)->RunInfoForTesting(0).NumGlyphs(),
+ repetition_count + 1);
+ for (unsigned i = 0; i < repetition_count; i++) {
+ EXPECT_EQ(TestInfo(result)->GlyphForTesting(0, i), v1);
+ EXPECT_NEAR(TestInfo(result)->AdvanceForTesting(0, i), 2000 - overlap,
+ kSizeError);
+ }
+ EXPECT_EQ(TestInfo(result)->GlyphForTesting(0, repetition_count), v2);
+ EXPECT_NEAR(TestInfo(result)->AdvanceForTesting(0, repetition_count),
+ 3000, kSizeError);
+ }
+ }
+
+ // Stretch an operator to edge target size values.
+ //
+ // These tests verify that it does not cause any assertion or crashes.
+ {
+ // Zero.
+ float target_size = 0;
+ horizontal_shaper.Shape(&math, target_size);
+ vertical_shaper.Shape(&math, target_size);
+
+ // Negative.
+ target_size = -5500;
+ horizontal_shaper.Shape(&math, target_size);
+ vertical_shaper.Shape(&math, target_size);
+
+ // Max limit.
+ target_size = std::numeric_limits<float>::max();
+ horizontal_shaper.Shape(&math, target_size);
+ vertical_shaper.Shape(&math, target_size);
+
+ // Min limit.
+ target_size = std::numeric_limits<float>::min();
+ horizontal_shaper.Shape(&math, target_size);
+ vertical_shaper.Shape(&math, target_size);
+
+ // More than the max number of glyphs.
+ // The size of an assembly with one non-extender v2/h2 and k - 1 extenders
+ // h1/v1 and minimal overlap 500 is Y = 1500k + 1500.
+ // So target_size - Y >= 250 >> kSizeError if the assembly does not have
+ // more than the max number of glyphs.
+ target_size = 1500 * HarfBuzzRunGlyphData::kMaxGlyphs + 1750;
+ horizontal_shaper.Shape(&math, target_size);
+ vertical_shaper.Shape(&math, target_size);
+ }
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/simple_font_data.h b/chromium/third_party/blink/renderer/platform/fonts/simple_font_data.h
index 7c5e9561c83..070cde2e8ba 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/simple_font_data.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/simple_font_data.h
@@ -39,6 +39,7 @@
#include "third_party/blink/renderer/platform/fonts/typesetting_features.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
#include "third_party/skia/include/core/SkFont.h"
@@ -245,7 +246,12 @@ ALWAYS_INLINE float SimpleFontData::WidthForGlyph(Glyph glyph) const {
#endif
}
-DEFINE_FONT_DATA_TYPE_CASTS(SimpleFontData, false);
+template <>
+struct DowncastTraits<SimpleFontData> {
+ static bool AllowFrom(const FontData& fontData) {
+ return !fontData.IsSegmented();
+ }
+};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SIMPLE_FONT_DATA_H_
diff --git a/chromium/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc b/chromium/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc
index 51bdbb7510c..7537fb4d036 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc
@@ -33,6 +33,7 @@
#include <memory>
#include <utility>
+#include "base/logging.h"
#include "build/build_config.h"
#include "third_party/blink/public/platform/linux/web_sandbox_support.h"
#include "third_party/blink/public/platform/platform.h"
@@ -245,6 +246,13 @@ sk_sp<SkTypeface> FontCache::CreateTypeface(
name.c_str(), font_description.SkiaFontStyle());
}
+#if !defined(OS_MACOSX)
+std::vector<FontEnumerationEntry> FontCache::EnumeratePlatformAvailableFonts() {
+ NOTIMPLEMENTED();
+ return std::vector<FontEnumerationEntry>();
+}
+#endif // !defined(OS_MACOSX)
+
#if !defined(OS_WIN)
std::unique_ptr<FontPlatformData> FontCache::CreateFontPlatformData(
const FontDescription& font_description,
diff --git a/chromium/third_party/blink/renderer/platform/fonts/skia/skia_text_metrics.h b/chromium/third_party/blink/renderer/platform/fonts/skia/skia_text_metrics.h
index 6a72122ee22..f638f1c8393 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/skia/skia_text_metrics.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/skia/skia_text_metrics.h
@@ -15,6 +15,10 @@ class SkFont;
namespace blink {
+// TODO: Width functions are affected by issue
+// https://bugs.chromium.org/p/skia/issues/detail?id=10123 in Skia, which
+// currently does not return trak-free advances on Mac OS 10.15.
+
void SkFontGetGlyphWidthForHarfBuzz(const SkFont&,
hb_codepoint_t,
hb_position_t* width);
diff --git a/chromium/third_party/blink/renderer/platform/fonts/web_font_decoder.cc b/chromium/third_party/blink/renderer/platform/fonts/web_font_decoder.cc
index 9b5a8ed881f..e72f801016a 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/web_font_decoder.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/web_font_decoder.cc
@@ -30,15 +30,12 @@
#include "third_party/blink/renderer/platform/fonts/web_font_decoder.h"
-#include "base/timer/elapsed_timer.h"
#include "build/build_config.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/fonts/font_cache.h"
#include "third_party/blink/renderer/platform/fonts/web_font_typeface_factory.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
-#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/ots/include/ots-memory-stream.h"
#include "third_party/skia/include/core/SkStream.h"
@@ -145,38 +142,6 @@ ots::TableAction BlinkOTSContext::GetTableAction(uint32_t tag) {
}
}
-void RecordDecodeSpeedHistogram(const char* data,
- size_t length,
- double decode_time,
- size_t decoded_size) {
- if (decode_time <= 0)
- return;
-
- double kb_per_second = decoded_size / (1000 * decode_time);
- if (length >= 4) {
- if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == 'F') {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, woff_histogram,
- ("WebFont.DecodeSpeed.WOFF", 1000, 300000, 50));
- woff_histogram.Count(kb_per_second);
- return;
- }
-
- if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == '2') {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, woff2_histogram,
- ("WebFont.DecodeSpeed.WOFF2", 1000, 300000, 50));
- woff2_histogram.Count(kb_per_second);
- return;
- }
- }
-
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- CustomCountHistogram, sfnt_histogram,
- ("WebFont.DecodeSpeed.SFNT", 1000, 300000, 50));
- sfnt_histogram.Count(kb_per_second);
-}
-
} // namespace
sk_sp<SkTypeface> WebFontDecoder::Decode(SharedBuffer* buffer) {
@@ -196,14 +161,13 @@ sk_sp<SkTypeface> WebFontDecoder::Decode(SharedBuffer* buffer) {
// Most web fonts are compressed, so the result can be much larger than
// the original.
ots::ExpandingMemoryStream output(buffer->size(), kMaxWebFontSize);
- base::ElapsedTimer timer;
BlinkOTSContext ots_context;
SharedBuffer::DeprecatedFlatData flattened_buffer(buffer);
- const char* data = flattened_buffer.Data();
TRACE_EVENT_BEGIN0("blink", "DecodeFont");
- bool ok = ots_context.Process(&output, reinterpret_cast<const uint8_t*>(data),
- buffer->size());
+ bool ok = ots_context.Process(
+ &output, reinterpret_cast<const uint8_t*>(flattened_buffer.Data()),
+ buffer->size());
TRACE_EVENT_END0("blink", "DecodeFont");
if (!ok) {
@@ -212,9 +176,6 @@ sk_sp<SkTypeface> WebFontDecoder::Decode(SharedBuffer* buffer) {
}
const size_t decoded_length = SafeCast<size_t>(output.Tell());
- RecordDecodeSpeedHistogram(data, buffer->size(), timer.Elapsed().InSecondsF(),
- decoded_length);
-
sk_sp<SkData> sk_data = SkData::MakeWithCopy(output.get(), decoded_length);
sk_sp<SkTypeface> new_typeface;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.cc b/chromium/third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.cc
index a563a80074d..9544a0ed0ab 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.cc
@@ -49,12 +49,11 @@ void FallbackFamilyStyleCache::Put(
String cache_key =
makeCacheKey(generic_family, bcp47_language_tag, fallback_priority);
- FallbackLruCache::TypefaceVector* existing_typefaces =
- recent_fallback_fonts_.Get(cache_key);
+ TypefaceVector* existing_typefaces = recent_fallback_fonts_.Get(cache_key);
if (existing_typefaces) {
existing_typefaces->insert(0, sk_ref_sp(typeface));
} else {
- FallbackLruCache::TypefaceVector typefaces;
+ TypefaceVector typefaces;
typefaces.push_back(sk_ref_sp(typeface));
recent_fallback_fonts_.Put(std::move(cache_key), std::move(typefaces));
}
@@ -67,7 +66,7 @@ void FallbackFamilyStyleCache::Get(
UChar32 character,
String* fallback_family,
SkFontStyle* fallback_style) {
- FallbackLruCache::TypefaceVector* typefaces = recent_fallback_fonts_.Get(
+ TypefaceVector* typefaces = recent_fallback_fonts_.Get(
makeCacheKey(generic_family, bcp47_language_tag, fallback_priority));
if (!typefaces)
return;
diff --git a/chromium/third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.h b/chromium/third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.h
index 5e8f86ebcf9..770702feb39 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.h
@@ -7,12 +7,15 @@
#include "third_party/blink/renderer/platform/fonts/font_description.h"
#include "third_party/blink/renderer/platform/fonts/font_fallback_priority.h"
-#include "third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win.h"
+#include "third_party/blink/renderer/platform/wtf/lru_cache.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkTypeface.h"
namespace blink {
+using TypefaceVector = Vector<sk_sp<SkTypeface>>;
+using FallbackLruCache = WTF::LruCache<String, TypefaceVector>;
+
class FallbackFamilyStyleCache {
USING_FAST_MALLOC(FallbackFamilyStyleCache);
diff --git a/chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win.cc b/chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win.cc
deleted file mode 100644
index 37b6a152785..00000000000
--- a/chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win.cc
+++ /dev/null
@@ -1,57 +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/fonts/win/fallback_lru_cache_win.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 {
-
-FallbackLruCache::FallbackLruCache(size_t max_size) : max_size_(max_size) {
- DCHECK_GT(max_size_, 0u);
-}
-
-FallbackLruCache::TypefaceVector* FallbackLruCache::Get(const String& key) {
- HashMapType::iterator find_result = map_.find(key);
- if (find_result == map_.end())
- return nullptr;
-
- // Move result to beginning of list.
- KeyListNode* node = find_result->value.ListNode();
- ordering_.Remove(node);
- ordering_.Push(node);
- return find_result->value.value();
-}
-
-void FallbackLruCache::Put(String&& key, TypefaceVector&& arg) {
- HashMapType::iterator find_result = map_.find(key);
- if (find_result != map_.end()) {
- ordering_.Remove(find_result->value.ListNode());
- map_.erase(find_result);
- }
-
- if (map_.size() >= max_size_) {
- RemoveLeastRecentlyUsed();
- }
-
- std::unique_ptr<KeyListNode> list_node = std::make_unique<KeyListNode>(key);
- HashMapType::AddResult add_result = map_.insert(
- std::move(key), MappedWithListNode(std::move(arg), std::move(list_node)));
- DCHECK(add_result.is_new_entry);
- ordering_.Push(add_result.stored_value->value.ListNode());
-}
-
-void FallbackLruCache::Clear() {
- map_.clear();
- ordering_.Clear();
-}
-
-void FallbackLruCache::RemoveLeastRecentlyUsed() {
- KeyListNode* tail = ordering_.Tail();
- ordering_.Remove(tail);
- map_.erase(tail->key());
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win.h b/chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win.h
deleted file mode 100644
index 90048e3319a..00000000000
--- a/chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win.h
+++ /dev/null
@@ -1,91 +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/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/doubly_linked_list.h"
-#include "third_party/blink/renderer/platform/wtf/hash_map.h"
-#include "third_party/blink/renderer/platform/wtf/hash_table_deleted_value_type.h"
-#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-#include "third_party/skia/include/core/SkRefCnt.h"
-#include "third_party/skia/include/core/SkTypeface.h"
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_WIN_FALLBACK_LRU_CACHE_WIN_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_WIN_FALLBACK_LRU_CACHE_WIN_H_
-
-namespace blink {
-
-/* A LRU cache for storing a a vector of typefaces for a particular key string,
- * which would usually be a locale plus potential additional parameters. Uses a
- * HashMap for storage and access and a DoublyLinkedList for managing age of
- * entries. TODO(https://crbug.com/1010925): Potentially move this to a generic
- * LRU Cache implementation once we have such in WTF. */
-class PLATFORM_EXPORT FallbackLruCache {
- USING_FAST_MALLOC(FallbackLruCache);
-
- public:
- FallbackLruCache(size_t max_size);
-
- using TypefaceVector = Vector<sk_sp<SkTypeface>>;
-
- TypefaceVector* Get(const String& key);
- void Put(String&& key, TypefaceVector&& arg);
-
- void Clear();
-
- size_t size() const { return map_.size(); }
-
- private:
- class KeyListNode final : public DoublyLinkedListNode<KeyListNode> {
- USING_FAST_MALLOC(KeyListNode);
-
- public:
- friend class DoublyLinkedListNode<KeyListNode>;
- KeyListNode(const String& key) : key_(key) {}
-
- const String& key() const { return key_; }
-
- private:
- String key_;
- KeyListNode* prev_{nullptr};
- KeyListNode* next_{nullptr};
- };
-
- class MappedWithListNode {
- USING_FAST_MALLOC(MappedWithListNode);
-
- public:
- MappedWithListNode(TypefaceVector&& mapped_arg,
- std::unique_ptr<KeyListNode>&& list_node)
- : mapped_value_(std::move(mapped_arg)),
- list_node_(std::move(list_node)) {}
-
- MappedWithListNode(WTF::HashTableDeletedValueType) {
- list_node_.reset(reinterpret_cast<KeyListNode*>(-1));
- }
-
- TypefaceVector* value() { return &mapped_value_; }
- KeyListNode* ListNode() { return list_node_.get(); }
-
- private:
- TypefaceVector mapped_value_;
- std::unique_ptr<KeyListNode> list_node_;
- };
-
- void RemoveLeastRecentlyUsed();
-
- using HashMapType = HashMap<String,
- MappedWithListNode,
- DefaultHash<String>::Hash,
- HashTraits<String>,
- SimpleClassHashTraits<MappedWithListNode>>;
-
- HashMapType map_;
- DoublyLinkedList<KeyListNode> ordering_;
- size_t max_size_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_WIN_FALLBACK_LRU_CACHE_WIN_H_
diff --git a/chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win_test.cc b/chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win_test.cc
index 92f78aa9e38..917f0111235 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win_test.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/win/fallback_lru_cache_win_test.cc
@@ -2,9 +2,12 @@
// 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/fonts/win/fallback_lru_cache_win.h"
+#include "third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/wtf/text/character_names.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/skia/include/core/SkFontMgr.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkTypeface.h"
@@ -29,7 +32,7 @@ void fillCacheWithDummies(blink::FallbackLruCache& lru_cache,
const char* format_string,
size_t count) {
for (size_t i = 0; i < count; ++i) {
- blink::FallbackLruCache::TypefaceVector dummy_typefaces;
+ blink::TypefaceVector dummy_typefaces;
dummy_typefaces.push_back(
SkTypeface::MakeFromName(kFontFamilyNameArial, SkFontStyle()));
lru_cache.Put(String::Format(format_string, i), std::move(dummy_typefaces));
@@ -48,7 +51,7 @@ TEST(FallbackLruCacheTest, KeepChineseWhenFetched) {
// the Chinese font and ensure it's gone.
FallbackLruCache lru_cache(kLruCacheTestSize);
EXPECT_EQ(lru_cache.size(), 0u);
- FallbackLruCache::TypefaceVector fallback_typefaces_zh;
+ TypefaceVector fallback_typefaces_zh;
fallback_typefaces_zh.push_back(
fallbackForLocale(kHanSimplifiedLocale, kFirstCJKIdeograph));
lru_cache.Put(kHanSimplifiedLocale, std::move(fallback_typefaces_zh));
@@ -56,8 +59,7 @@ TEST(FallbackLruCacheTest, KeepChineseWhenFetched) {
EXPECT_EQ(lru_cache.size(), 1u);
fillCacheWithDummies(lru_cache, "dummy_locale_%zu", kLruCacheTestSize - 1);
- FallbackLruCache::TypefaceVector* chinese_typefaces =
- lru_cache.Get(kHanSimplifiedLocale);
+ TypefaceVector* chinese_typefaces = lru_cache.Get(kHanSimplifiedLocale);
EXPECT_TRUE(chinese_typefaces);
EXPECT_TRUE(chinese_typefaces->at(0)->unicharToGlyph(0x4E01));
EXPECT_EQ(lru_cache.size(), kLruCacheTestSize);
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 821a6a7afc3..52427643b20 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
@@ -42,7 +42,7 @@
#include "base/debug/alias.h"
#include "base/stl_util.h"
#include "base/trace_event/trace_event.h"
-#include "third_party/blink/public/platform/interface_provider.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/renderer/platform/fonts/bitmap_glyphs_block_list.h"
#include "third_party/blink/renderer/platform/fonts/font_description.h"
@@ -229,7 +229,7 @@ void FontCache::SetStatusFontMetrics(const wchar_t* family_name,
void FontCache::EnsureServiceConnected() {
if (service_)
return;
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
service_.BindNewPipeAndPassReceiver());
}
diff --git a/chromium/third_party/blink/renderer/platform/fonts/win/font_unique_name_lookup_win.cc b/chromium/third_party/blink/renderer/platform/fonts/win/font_unique_name_lookup_win.cc
index 52555021f7b..13162712b2e 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/win/font_unique_name_lookup_win.cc
+++ b/chromium/third_party/blink/renderer/platform/fonts/win/font_unique_name_lookup_win.cc
@@ -9,8 +9,8 @@
#include "base/files/file_path.h"
#include "mojo/public/mojom/base/shared_memory.mojom-blink.h"
+#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/dwrite_font_proxy/dwrite_font_proxy.mojom-blink.h"
-#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -165,7 +165,7 @@ bool FontUniqueNameLookupWin::IsFontUniqueNameLookupReadyForSyncLookup() {
void FontUniqueNameLookupWin::EnsureServiceConnected() {
if (service_)
return;
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
service_.BindNewPipeAndPassReceiver());
}
diff --git a/chromium/third_party/blink/renderer/platform/geometry/float_point.h b/chromium/third_party/blink/renderer/platform/geometry/float_point.h
index cd1ddb8bf56..91b2d129008 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/float_point.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/float_point.h
@@ -34,6 +34,7 @@
#include "third_party/blink/renderer/platform/geometry/int_size.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
+#include "third_party/blink/renderer/platform/wtf/hash_traits.h"
#include "third_party/skia/include/core/SkPoint.h"
#include "ui/gfx/geometry/point3_f.h"
#include "ui/gfx/geometry/point_f.h"
@@ -71,6 +72,11 @@ class PLATFORM_EXPORT FloatPoint {
static FloatPoint NarrowPrecision(double x, double y);
+ bool IsValid() const {
+ return x_ != -std::numeric_limits<float>::infinity() &&
+ y_ != -std::numeric_limits<float>::infinity();
+ }
+
constexpr float X() const { return x_; }
constexpr float Y() const { return y_; }
@@ -139,6 +145,9 @@ class PLATFORM_EXPORT FloatPoint {
private:
float x_, y_;
+
+ friend struct ::WTF::DefaultHash<blink::FloatSize>;
+ friend struct ::WTF::HashTraits<blink::FloatSize>;
};
inline FloatPoint& operator+=(FloatPoint& a, const FloatSize& b) {
@@ -217,6 +226,10 @@ inline IntPoint FlooredIntPoint(const FloatPoint& p) {
return IntPoint(clampTo<int>(floorf(p.X())), clampTo<int>(floorf(p.Y())));
}
+inline IntPoint FlooredIntPoint(const gfx::PointF& p) {
+ return IntPoint(clampTo<int>(floorf(p.x())), clampTo<int>(floorf(p.y())));
+}
+
inline IntPoint CeiledIntPoint(const FloatPoint& p) {
return IntPoint(clampTo<int>(ceilf(p.X())), clampTo<int>(ceilf(p.Y())));
}
@@ -243,4 +256,42 @@ PLATFORM_EXPORT WTF::TextStream& operator<<(WTF::TextStream&,
} // namespace blink
-#endif
+namespace WTF {
+
+template <>
+struct DefaultHash<blink::FloatPoint> {
+ STATIC_ONLY(DefaultHash);
+ struct Hash {
+ STATIC_ONLY(Hash);
+ typedef typename IntTypes<sizeof(float)>::UnsignedType Bits;
+ static unsigned GetHash(const blink::FloatPoint& key) {
+ return HashInts(bit_cast<Bits>(key.X()), bit_cast<Bits>(key.Y()));
+ }
+ static bool Equal(const blink::FloatPoint& a, const blink::FloatPoint& b) {
+ return bit_cast<Bits>(a.X()) == bit_cast<Bits>(b.X()) &&
+ bit_cast<Bits>(a.Y()) == bit_cast<Bits>(b.Y());
+ }
+ static const bool safe_to_compare_to_empty_or_deleted = true;
+ };
+};
+
+template <>
+struct HashTraits<blink::FloatPoint> : GenericHashTraits<blink::FloatPoint> {
+ STATIC_ONLY(HashTraits);
+ static const bool kEmptyValueIsZero = false;
+ static blink::FloatPoint EmptyValue() {
+ return blink::FloatPoint(std::numeric_limits<float>::infinity(),
+ std::numeric_limits<float>::infinity());
+ }
+ static void ConstructDeletedValue(blink::FloatPoint& slot, bool) {
+ slot = blink::FloatPoint(-std::numeric_limits<float>::infinity(),
+ -std::numeric_limits<float>::infinity());
+ }
+ static bool IsDeletedValue(const blink::FloatPoint& value) {
+ return !value.IsValid();
+ }
+};
+
+} // namespace WTF
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_FLOAT_POINT_H_
diff --git a/chromium/third_party/blink/renderer/platform/geometry/float_rect.cc b/chromium/third_party/blink/renderer/platform/geometry/float_rect.cc
index 3b0b298bf7b..f9c90559557 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/float_rect.cc
+++ b/chromium/third_party/blink/renderer/platform/geometry/float_rect.cc
@@ -63,6 +63,10 @@ bool FloatRect::EqualWithinEpsilon(const FloatRect& other,
#endif
+bool FloatRect::IsFinite() const {
+ return static_cast<SkRect>(*this).isFinite();
+}
+
bool FloatRect::IsExpressibleAsIntRect() const {
return isWithinIntRange(X()) && isWithinIntRange(Y()) &&
isWithinIntRange(Width()) && isWithinIntRange(Height()) &&
diff --git a/chromium/third_party/blink/renderer/platform/geometry/float_rect.h b/chromium/third_party/blink/renderer/platform/geometry/float_rect.h
index 1e3c7b0787a..4271528c4b0 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/float_rect.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/float_rect.h
@@ -29,6 +29,7 @@
#include <iosfwd>
+#include "base/compiler_specific.h"
#include "base/numerics/clamped_math.h"
#include "build/build_config.h"
#include "third_party/blink/renderer/platform/geometry/float_point.h"
@@ -92,6 +93,8 @@ class PLATFORM_EXPORT FloatRect {
constexpr bool IsEmpty() const { return size_.IsEmpty(); }
constexpr bool IsZero() const { return size_.IsZero(); }
+ // True if no member is infinite or NaN.
+ bool IsFinite() const;
bool IsExpressibleAsIntRect() const;
FloatPoint Center() const {
@@ -130,8 +133,8 @@ class PLATFORM_EXPORT FloatRect {
location_.Y() + size_.Height());
} // typically bottomRight
- bool Intersects(const IntRect&) const;
- bool Intersects(const FloatRect&) const;
+ WARN_UNUSED_RESULT bool Intersects(const IntRect&) const;
+ WARN_UNUSED_RESULT bool Intersects(const FloatRect&) const;
bool Contains(const IntRect&) const;
bool Contains(const FloatRect&) const;
bool Contains(const FloatPoint&, ContainsMode = kInsideOrOnStroke) const;
diff --git a/chromium/third_party/blink/renderer/platform/geometry/int_rect.h b/chromium/third_party/blink/renderer/platform/geometry/int_rect.h
index 28a594d574e..9f891218aa4 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/int_rect.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/int_rect.h
@@ -28,6 +28,7 @@
#include <iosfwd>
+#include "base/compiler_specific.h"
#include "base/numerics/clamped_math.h"
#include "build/build_config.h"
#include "third_party/blink/renderer/platform/geometry/int_point.h"
@@ -133,7 +134,7 @@ class PLATFORM_EXPORT IntRect {
location_.Y() + size_.Height());
} // typically bottomRight
- bool Intersects(const IntRect&) const;
+ WARN_UNUSED_RESULT bool Intersects(const IntRect&) const;
bool Contains(const IntRect&) const;
// This checks to see if the rect contains x,y in the traditional sense.
diff --git a/chromium/third_party/blink/renderer/platform/geometry/layout_rect.h b/chromium/third_party/blink/renderer/platform/geometry/layout_rect.h
index f1b6f9b0798..6434c5d32f5 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/layout_rect.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/layout_rect.h
@@ -32,6 +32,8 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_LAYOUT_RECT_H_
#include <iosfwd>
+
+#include "base/compiler_specific.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
#include "third_party/blink/renderer/platform/geometry/layout_point.h"
@@ -196,7 +198,7 @@ class PLATFORM_EXPORT LayoutRect {
location_.Y() + size_.Height());
}
- bool Intersects(const LayoutRect&) const;
+ WARN_UNUSED_RESULT bool Intersects(const LayoutRect&) const;
bool Contains(const LayoutRect&) const;
// This checks to see if the rect contains x,y in the traditional sense.
diff --git a/chromium/third_party/blink/renderer/platform/geometry/layout_size.h b/chromium/third_party/blink/renderer/platform/geometry/layout_size.h
index 472784b000d..32a0c93f776 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/layout_size.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/layout_size.h
@@ -65,6 +65,8 @@ class PLATFORM_EXPORT LayoutSize {
: width_(size.Width()), height_(size.Height()) {}
constexpr explicit LayoutSize(const gfx::Size& size)
: width_(size.width()), height_(size.height()) {}
+ constexpr explicit LayoutSize(const gfx::SizeF& size)
+ : width_(size.width()), height_(size.height()) {}
constexpr explicit operator FloatSize() const {
return FloatSize(width_.ToFloat(), height_.ToFloat());
diff --git a/chromium/third_party/blink/renderer/platform/geometry/layout_unit.h b/chromium/third_party/blink/renderer/platform/geometry/layout_unit.h
index eaaff017795..8ffe3e11501 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/layout_unit.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/layout_unit.h
@@ -723,7 +723,12 @@ inline float& operator/=(float& a, const LayoutUnit& b) {
inline int SnapSizeToPixel(LayoutUnit size, LayoutUnit location) {
LayoutUnit fraction = location.Fraction();
- return (fraction + size).Round() - fraction.Round();
+ int result = (fraction + size).Round() - fraction.Round();
+ if (UNLIKELY(result == 0 &&
+ std::abs(size.ToFloat()) > LayoutUnit::Epsilon() * 4)) {
+ return size > 0 ? 1 : -1;
+ }
+ return result;
}
inline int RoundToInt(LayoutUnit value) {
diff --git a/chromium/third_party/blink/renderer/platform/geometry/layout_unit_test.cc b/chromium/third_party/blink/renderer/platform/geometry/layout_unit_test.cc
index db1fa1f610f..05d4a2f762e 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/layout_unit_test.cc
+++ b/chromium/third_party/blink/renderer/platform/geometry/layout_unit_test.cc
@@ -155,8 +155,20 @@ TEST(LayoutUnitTest, LayoutUnitSnapSizeToPixel) {
EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(1.5), LayoutUnit(0.99)));
EXPECT_EQ(2, SnapSizeToPixel(LayoutUnit(1.5), LayoutUnit(1)));
- EXPECT_EQ(0, SnapSizeToPixel(LayoutUnit(0.5), LayoutUnit(1.5)));
- EXPECT_EQ(0, SnapSizeToPixel(LayoutUnit(0.99), LayoutUnit(1.5)));
+ // 0.046875 is 3/64, lower than 4 * LayoutUnit::Epsilon()
+ EXPECT_EQ(0, SnapSizeToPixel(LayoutUnit(0.046875), LayoutUnit(0)));
+ // 0.078125 is 5/64, higher than 4 * LayoutUnit::Epsilon()
+ EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(0.078125), LayoutUnit(0)));
+
+ // Negative versions
+ EXPECT_EQ(0, SnapSizeToPixel(LayoutUnit(-0.046875), LayoutUnit(0)));
+ EXPECT_EQ(-1, SnapSizeToPixel(LayoutUnit(-0.078125), LayoutUnit(0)));
+
+ // The next 2 would snap to zero but for the requirement that we not snap
+ // sizes greater than 4 * LayoutUnit::Epsilon() to 0.
+ EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(0.5), LayoutUnit(1.5)));
+ EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(0.99), LayoutUnit(1.5)));
+
EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(1.0), LayoutUnit(1.5)));
EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(1.49), LayoutUnit(1.5)));
EXPECT_EQ(1, SnapSizeToPixel(LayoutUnit(1.5), LayoutUnit(1.5)));
diff --git a/chromium/third_party/blink/renderer/platform/geometry/length.h b/chromium/third_party/blink/renderer/platform/geometry/length.h
index 72d3979fb1a..a77de90a46a 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/length.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/length.h
@@ -60,7 +60,7 @@ class PLATFORM_EXPORT Length {
kExtendToZoom,
kDeviceWidth,
kDeviceHeight,
- kMaxSizeNone
+ kNone
};
Length() : int_value_(0), quirk_(false), type_(kAuto), is_float_(false) {}
@@ -114,7 +114,7 @@ class PLATFORM_EXPORT Length {
bool operator==(const Length& o) const {
return (type_ == o.type_) && (quirk_ == o.quirk_) &&
- (IsMaxSizeNone() || (GetFloatValue() == o.GetFloatValue()) ||
+ (IsNone() || (GetFloatValue() == o.GetFloatValue()) ||
IsCalculatedEqual(o));
}
bool operator!=(const Length& o) const { return !(*this == o); }
@@ -145,7 +145,7 @@ class PLATFORM_EXPORT Length {
static Length ExtendToZoom() { return Length(kExtendToZoom); }
static Length DeviceWidth() { return Length(kDeviceWidth); }
static Length DeviceHeight() { return Length(kDeviceHeight); }
- static Length MaxSizeNone() { return Length(kMaxSizeNone); }
+ static Length None() { return Length(kNone); }
static Length FitContent() { return Length(kFitContent); }
template <typename NUMBER_TYPE>
static Length Percent(NUMBER_TYPE number) {
@@ -191,21 +191,21 @@ class PLATFORM_EXPORT Length {
void SetQuirk(bool quirk) { quirk_ = quirk; }
- bool IsMaxSizeNone() const { return GetType() == kMaxSizeNone; }
+ bool IsNone() const { return GetType() == kNone; }
// FIXME calc: https://bugs.webkit.org/show_bug.cgi?id=80357. A calculated
// Length always contains a percentage, and without a maxValue passed to these
// functions it's impossible to determine the sign or zero-ness. We assume all
// calc values are positive and non-zero for now.
bool IsZero() const {
- DCHECK(!IsMaxSizeNone());
+ DCHECK(!IsNone());
if (IsCalculated())
return false;
return is_float_ ? !float_value_ : !int_value_;
}
bool IsPositive() const {
- if (IsMaxSizeNone())
+ if (IsNone())
return false;
if (IsCalculated())
return true;
@@ -213,7 +213,7 @@ class PLATFORM_EXPORT Length {
return GetFloatValue() > 0;
}
bool IsNegative() const {
- if (IsMaxSizeNone() || IsCalculated())
+ if (IsNone() || IsCalculated())
return false;
return GetFloatValue() < 0;
@@ -272,7 +272,7 @@ class PLATFORM_EXPORT Length {
}
float GetFloatValue() const {
- DCHECK(!IsMaxSizeNone());
+ DCHECK(!IsNone());
return is_float_ ? float_value_ : int_value_;
}
float NonNanCalculatedValue(LayoutUnit max_value) const;
@@ -283,7 +283,7 @@ class PLATFORM_EXPORT Length {
private:
int GetIntValue() const {
- DCHECK(!IsMaxSizeNone());
+ DCHECK(!IsNone());
return is_float_ ? static_cast<int>(float_value_) : int_value_;
}
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 6aef97e527d..dd5a6fed930 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/length_functions.cc
+++ b/chromium/third_party/blink/renderer/platform/geometry/length_functions.cc
@@ -52,7 +52,7 @@ float FloatValueForLength(const Length& length, float maximum_value) {
case Length::kExtendToZoom:
case Length::kDeviceWidth:
case Length::kDeviceHeight:
- case Length::kMaxSizeNone:
+ case Length::kNone:
NOTREACHED();
return 0;
}
@@ -80,7 +80,7 @@ LayoutUnit MinimumValueForLengthInternal(const Length& length,
case Length::kExtendToZoom:
case Length::kDeviceWidth:
case Length::kDeviceHeight:
- case Length::kMaxSizeNone:
+ case Length::kNone:
NOTREACHED();
return LayoutUnit();
}
@@ -103,7 +103,7 @@ LayoutUnit ValueForLength(const Length& length, LayoutUnit maximum_value) {
case Length::kExtendToZoom:
case Length::kDeviceWidth:
case Length::kDeviceHeight:
- case Length::kMaxSizeNone:
+ case Length::kNone:
NOTREACHED();
return LayoutUnit();
}
diff --git a/chromium/third_party/blink/renderer/platform/geometry/length_size.h b/chromium/third_party/blink/renderer/platform/geometry/length_size.h
index 8da2e50bbe9..a03152f6e2b 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/length_size.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/length_size.h
@@ -38,6 +38,7 @@ class LengthSize {
bool operator==(const LengthSize& o) const {
return width_ == o.width_ && height_ == o.height_;
}
+ bool operator!=(const LengthSize& o) const { return !(*this == o); }
void SetWidth(const Length& width) { width_ = width; }
const Length& Width() const { return width_; }
diff --git a/chromium/third_party/blink/renderer/platform/geometry/region.cc b/chromium/third_party/blink/renderer/platform/geometry/region.cc
index a90abdc2378..54a4ce33a34 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/region.cc
+++ b/chromium/third_party/blink/renderer/platform/geometry/region.cc
@@ -327,7 +327,7 @@ Region::Shape::SegmentIterator Region::Shape::SegmentsEnd(
return segments_.data() + segment_index;
}
-#ifndef NDEBUG
+#if DCHECK_IS_ON()
void Region::Shape::Dump() const {
for (Shape::SpanIterator span = SpansBegin(), end = SpansEnd(); span != end;
++span) {
@@ -570,7 +570,7 @@ Region::Shape Region::Shape::SubtractShapes(const Shape& shape1,
return ShapeOperation<SubtractOperation>(shape1, shape2);
}
-#ifndef NDEBUG
+#if DCHECK_IS_ON()
void Region::Dump() const {
printf("Bounds: (%d, %d, %d, %d)\n", bounds_.X(), bounds_.Y(),
bounds_.Width(), bounds_.Height());
diff --git a/chromium/third_party/blink/renderer/platform/geometry/region.h b/chromium/third_party/blink/renderer/platform/geometry/region.h
index d34815c7ca1..581d4df4574 100644
--- a/chromium/third_party/blink/renderer/platform/geometry/region.h
+++ b/chromium/third_party/blink/renderer/platform/geometry/region.h
@@ -73,7 +73,11 @@ class PLATFORM_EXPORT Region {
uint64_t Area() const;
-#ifndef NDEBUG
+ wtf_size_t Complexity() const {
+ return shape_.SpansSize() + shape_.SegmentsSize();
+ }
+
+#if DCHECK_IS_ON()
void Dump() const;
#endif
@@ -130,7 +134,7 @@ class PLATFORM_EXPORT Region {
static bool CompareShapes(const Shape& shape1, const Shape& shape2);
void TrimCapacities();
-#ifndef NDEBUG
+#if DCHECK_IS_ON()
void Dump() const;
#endif
diff --git a/chromium/third_party/blink/renderer/platform/graphics/DEPS b/chromium/third_party/blink/renderer/platform/graphics/DEPS
index 69ebb831274..9af9d13ba01 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/DEPS
+++ b/chromium/third_party/blink/renderer/platform/graphics/DEPS
@@ -19,9 +19,11 @@ include_rules = [
"+gpu/command_buffer/client/gpu_memory_buffer_manager.h",
"+gpu/command_buffer/client/raster_interface.h",
"+gpu/command_buffer/client/shared_image_interface.h",
+ "+gpu/command_buffer/common/gles2_cmd_copy_texture_chromium_utils.h",
"+gpu/command_buffer/common/gpu_memory_buffer_support.h",
"+gpu/command_buffer/common/capabilities.h",
"+gpu/command_buffer/common/mailbox.h",
+ "+gpu/command_buffer/common/mailbox_holder.h",
"+gpu/command_buffer/common/shared_image_usage.h",
"+gpu/command_buffer/common/sync_token.h",
"+gpu/ipc/common/mailbox.mojom-blink.h",
@@ -62,4 +64,5 @@ specific_include_rules = {
".*_test.cc": [
"+components/viz/test",
],
+ "(graphics_context|skia_utils)\.cc" : [ "+ui/base/ui_base_features.h" ]
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/OWNERS b/chromium/third_party/blink/renderer/platform/graphics/OWNERS
index 73a65352c7d..0bb32866bbe 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/OWNERS
+++ b/chromium/third_party/blink/renderer/platform/graphics/OWNERS
@@ -13,6 +13,7 @@ vollick@chromium.org
# For surface ID propagation and synchronization
samans@chromium.org
+jonross@chromium.org
# lowLatency canvas
mcasas@chromium.org
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 22135712d5d..08d74cb21d7 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
@@ -4,51 +4,88 @@
#include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h"
+#include <memory>
+#include <utility>
+
#include "components/viz/common/resources/single_release_callback.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/command_buffer/client/raster_interface.h"
+#include "gpu/command_buffer/client/shared_image_interface.h"
#include "gpu/command_buffer/common/sync_token.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/platform/graphics/canvas_resource_provider.h"
#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
-#include "third_party/blink/renderer/platform/graphics/mailbox_texture_holder.h"
#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
-#include "third_party/blink/renderer/platform/graphics/skia_texture_holder.h"
#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.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/skia/include/core/SkImage.h"
-#include "third_party/skia/include/gpu/GrTexture.h"
-
-#include <memory>
-#include <utility>
namespace blink {
+namespace {
-scoped_refptr<AcceleratedStaticBitmapImage>
-AcceleratedStaticBitmapImage::CreateFromSkImage(
- sk_sp<SkImage> image,
+void ReleaseCallbackOnContextThread(
+ std::unique_ptr<viz::SingleReleaseCallback> callback,
+ const gpu::SyncToken sync_token) {
+ callback->Run(sync_token, /* is_lost = */ false);
+}
+
+} // namespace
+
+AcceleratedStaticBitmapImage::MailboxRef::MailboxRef(
+ const gpu::SyncToken& sync_token,
+ base::PlatformThreadRef context_thread_ref,
+ scoped_refptr<base::SingleThreadTaskRunner> context_task_runner,
+ std::unique_ptr<viz::SingleReleaseCallback> release_callback)
+ : sync_token_(sync_token),
+ context_thread_ref_(context_thread_ref),
+ context_task_runner_(std::move(context_task_runner)),
+ release_callback_(std::move(release_callback)) {
+ DCHECK(!is_cross_thread() || sync_token_.verified_flush());
+}
+
+AcceleratedStaticBitmapImage::MailboxRef::~MailboxRef() {
+ if (context_thread_ref_ == base::PlatformThread::CurrentRef()) {
+ ReleaseCallbackOnContextThread(std::move(release_callback_), sync_token_);
+ } else {
+ context_task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&ReleaseCallbackOnContextThread,
+ std::move(release_callback_), sync_token_));
+ }
+}
+
+const gpu::SyncToken&
+AcceleratedStaticBitmapImage::MailboxRef::GetOrCreateSyncToken(
base::WeakPtr<WebGraphicsContext3DProviderWrapper>
context_provider_wrapper) {
- CHECK(image && image->isTextureBacked());
- return base::AdoptRef(new AcceleratedStaticBitmapImage(
- std::move(image), std::move(context_provider_wrapper)));
+ if (!sync_token_.HasData()) {
+ DCHECK(!is_cross_thread());
+ DCHECK(context_provider_wrapper);
+ context_provider_wrapper->ContextProvider()
+ ->InterfaceBase()
+ ->GenUnverifiedSyncTokenCHROMIUM(sync_token_.GetData());
+ }
+ return sync_token_;
}
-scoped_refptr<AcceleratedStaticBitmapImage>
-AcceleratedStaticBitmapImage::CreateFromWebGLContextImage(
- const gpu::Mailbox& mailbox,
- const gpu::SyncToken& sync_token,
- unsigned texture_id,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper>&&
- context_provider_wrapper,
- IntSize mailbox_size,
- bool is_origin_top_left) {
- return base::AdoptRef(new AcceleratedStaticBitmapImage(
- mailbox, sync_token, texture_id, std::move(context_provider_wrapper),
- mailbox_size, is_origin_top_left));
+// static
+void AcceleratedStaticBitmapImage::ReleaseTexture(void* ctx) {
+ auto* release_ctx = static_cast<ReleaseContext*>(ctx);
+ if (release_ctx->context_provider_wrapper) {
+ if (release_ctx->texture_id) {
+ auto* ri = release_ctx->context_provider_wrapper->ContextProvider()
+ ->RasterInterface();
+ ri->EndSharedImageAccessDirectCHROMIUM(release_ctx->texture_id);
+ ri->DeleteGpuRasterTexture(release_ctx->texture_id);
+ }
+ }
+
+ delete release_ctx;
}
+// static
scoped_refptr<AcceleratedStaticBitmapImage>
AcceleratedStaticBitmapImage::CreateFromCanvasMailbox(
const gpu::Mailbox& mailbox,
@@ -56,38 +93,16 @@ AcceleratedStaticBitmapImage::CreateFromCanvasMailbox(
GLuint shared_image_texture_id,
const SkImageInfo& sk_image_info,
GLenum texture_target,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper,
- PlatformThreadId context_thread_id,
bool is_origin_top_left,
+ base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper,
+ base::PlatformThreadRef context_thread_ref,
+ scoped_refptr<base::SingleThreadTaskRunner> context_task_runner,
std::unique_ptr<viz::SingleReleaseCallback> release_callback) {
return base::AdoptRef(new AcceleratedStaticBitmapImage(
mailbox, sync_token, shared_image_texture_id, sk_image_info,
- texture_target, std::move(context_provider_wrapper), context_thread_id,
- is_origin_top_left, std::move(release_callback)));
-}
-
-AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage(
- sk_sp<SkImage> image,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper>&&
- context_provider_wrapper)
- : paint_image_content_id_(cc::PaintImage::GetNextContentId()) {
- CHECK(image && image->isTextureBacked());
- skia_texture_holder_ = std::make_unique<SkiaTextureHolder>(
- std::move(image), std::move(context_provider_wrapper));
-}
-
-AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage(
- const gpu::Mailbox& mailbox,
- const gpu::SyncToken& sync_token,
- unsigned texture_id,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper>&&
- context_provider_wrapper,
- IntSize mailbox_size,
- bool is_origin_top_left)
- : paint_image_content_id_(cc::PaintImage::GetNextContentId()) {
- mailbox_texture_holder_ = std::make_unique<MailboxTextureHolder>(
- mailbox, sync_token, texture_id, std::move(context_provider_wrapper),
- mailbox_size, is_origin_top_left);
+ texture_target, is_origin_top_left, kDefaultImageOrientation,
+ std::move(context_provider_wrapper), context_thread_ref,
+ std::move(context_task_runner), std::move(release_callback)));
}
AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage(
@@ -96,92 +111,44 @@ AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage(
GLuint shared_image_texture_id,
const SkImageInfo& sk_image_info,
GLenum texture_target,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper>&&
- context_provider_wrapper,
- PlatformThreadId context_thread_id,
bool is_origin_top_left,
+ const ImageOrientation& orientation,
+ base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper,
+ base::PlatformThreadRef context_thread_ref,
+ scoped_refptr<base::SingleThreadTaskRunner> context_task_runner,
std::unique_ptr<viz::SingleReleaseCallback> release_callback)
- : mailbox_ref_(base::MakeRefCounted<TextureHolder::MailboxRef>(
- std::move(release_callback))),
+ : StaticBitmapImage(orientation),
+ mailbox_(mailbox),
+ sk_image_info_(sk_image_info),
+ texture_target_(texture_target),
+ is_origin_top_left_(is_origin_top_left),
+ context_provider_wrapper_(std::move(context_provider_wrapper)),
+ mailbox_ref_(
+ base::MakeRefCounted<MailboxRef>(sync_token,
+ context_thread_ref,
+ std::move(context_task_runner),
+ std::move(release_callback))),
paint_image_content_id_(cc::PaintImage::GetNextContentId()) {
- mailbox_texture_holder_ = std::make_unique<MailboxTextureHolder>(
- mailbox, sync_token, std::move(context_provider_wrapper), mailbox_ref_,
- context_thread_id, sk_image_info, texture_target, is_origin_top_left);
- if (shared_image_texture_id) {
- skia_texture_holder_ = std::make_unique<SkiaTextureHolder>(
- mailbox_texture_holder_.get(), shared_image_texture_id);
- }
-}
-
-namespace {
-
-void DestroySkImageOnOriginalThread(
- sk_sp<SkImage> image,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper,
- std::unique_ptr<gpu::SyncToken> sync_token) {
- if (context_provider_wrapper &&
- image->isValid(
- context_provider_wrapper->ContextProvider()->GetGrContext())) {
- if (sync_token->HasData()) {
- // To make sure skia does not recycle the texture while it is still in use
- // by another context.
- context_provider_wrapper->ContextProvider()
- ->ContextGL()
- ->WaitSyncTokenCHROMIUM(sync_token->GetData());
- }
- // In case texture was used by compositor, which may have changed params.
- image->getTexture()->textureParamsModified();
- }
- image.reset();
-}
-
-} // namespace
-
-AcceleratedStaticBitmapImage::~AcceleratedStaticBitmapImage() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(mailbox_.IsSharedImage());
- // If the original SkImage was retained, it must be destroyed on the thread
- // where it came from. In the same thread case, there is nothing to do because
- // the regular destruction flow is fine.
- if (original_skia_image_) {
- std::unique_ptr<gpu::SyncToken> sync_token =
- base::WrapUnique(new gpu::SyncToken(GetSyncToken()));
- if (!original_skia_image_task_runner_->BelongsToCurrentThread()) {
- PostCrossThreadTask(
- *original_skia_image_task_runner_, FROM_HERE,
- CrossThreadBindOnce(
- &DestroySkImageOnOriginalThread, std::move(original_skia_image_),
- std::move(original_skia_image_context_provider_wrapper_),
- WTF::Passed(std::move(sync_token))));
- } else {
- DestroySkImageOnOriginalThread(
- std::move(original_skia_image_),
- std::move(original_skia_image_context_provider_wrapper_),
- std::move(sync_token));
- }
- }
+ if (shared_image_texture_id)
+ InitializeSkImage(shared_image_texture_id);
}
-void AcceleratedStaticBitmapImage::RetainOriginalSkImage() {
+AcceleratedStaticBitmapImage::~AcceleratedStaticBitmapImage() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- DCHECK(skia_texture_holder_);
- original_skia_image_ = skia_texture_holder_->GetSkImage();
- original_skia_image_context_provider_wrapper_ = ContextProviderWrapper();
- DCHECK(original_skia_image_);
-
- original_skia_image_task_runner_ = Thread::Current()->GetTaskRunner();
}
IntSize AcceleratedStaticBitmapImage::Size() const {
- return texture_holder()->Size();
+ return IntSize(sk_image_info_.width(), sk_image_info_.height());
}
scoped_refptr<StaticBitmapImage>
AcceleratedStaticBitmapImage::MakeUnaccelerated() {
CreateImageFromMailboxIfNeeded();
return UnacceleratedStaticBitmapImage::Create(
- skia_texture_holder_->GetSkImage()->makeNonTextureImage());
+ sk_image_->makeNonTextureImage(), orientation_);
}
bool AcceleratedStaticBitmapImage::CopyToTexture(
@@ -197,49 +164,34 @@ bool AcceleratedStaticBitmapImage::CopyToTexture(
if (!IsValid())
return false;
- // TODO(junov) : could reduce overhead by using kOrderingBarrier when we know
- // that the source and destination context or on the same stream.
- EnsureMailbox(kUnverifiedSyncToken, GL_NEAREST);
-
// This method should only be used for cross-context copying, otherwise it's
// wasting overhead.
- DCHECK(mailbox_texture_holder_->IsCrossThread() ||
- dest_gl != ContextProviderWrapper()->ContextProvider()->ContextGL());
-
- bool is_shared_image = mailbox_texture_holder_->GetMailbox().IsSharedImage();
+ DCHECK(mailbox_ref_->is_cross_thread() ||
+ dest_gl != ContextProvider()->ContextGL());
+ DCHECK(mailbox_.IsSharedImage());
// Get a texture id that |destProvider| knows about and copy from it.
dest_gl->WaitSyncTokenCHROMIUM(
- mailbox_texture_holder_->GetSyncToken().GetConstData());
- GLuint source_texture_id;
- if (is_shared_image) {
- source_texture_id = dest_gl->CreateAndTexStorage2DSharedImageCHROMIUM(
- mailbox_texture_holder_->GetMailbox().name);
- dest_gl->BeginSharedImageAccessDirectCHROMIUM(
- source_texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM);
- } else {
- source_texture_id = dest_gl->CreateAndConsumeTextureCHROMIUM(
- mailbox_texture_holder_->GetMailbox().name);
- }
+ mailbox_ref_->GetOrCreateSyncToken(ContextProviderWrapper())
+ .GetConstData());
+ GLuint source_texture_id =
+ dest_gl->CreateAndTexStorage2DSharedImageCHROMIUM(mailbox_.name);
+ dest_gl->BeginSharedImageAccessDirectCHROMIUM(
+ source_texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM);
dest_gl->CopySubTextureCHROMIUM(
source_texture_id, 0, dest_target, dest_texture_id, dest_level,
dest_point.X(), dest_point.Y(), source_sub_rectangle.X(),
source_sub_rectangle.Y(), source_sub_rectangle.Width(),
source_sub_rectangle.Height(), unpack_flip_y ? GL_FALSE : GL_TRUE,
GL_FALSE, unpack_premultiply_alpha ? GL_FALSE : GL_TRUE);
- if (is_shared_image) {
- dest_gl->EndSharedImageAccessDirectCHROMIUM(source_texture_id);
- }
- // This drops the |destGL| context's reference on our |m_mailbox|, but it's
- // still held alive by our SkImage.
+ dest_gl->EndSharedImageAccessDirectCHROMIUM(source_texture_id);
dest_gl->DeleteTextures(1, &source_texture_id);
// We need to update the texture holder's sync token to ensure that when this
- // image is deleted, the texture resource will not be recycled by skia before
- // the above texture copy has completed.
+ // mailbox is recycled or deleted, it is done after the copy operation above.
gpu::SyncToken sync_token;
dest_gl->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData());
- mailbox_texture_holder_->UpdateSyncToken(sync_token);
+ mailbox_ref_->set_sync_token(sync_token);
return true;
}
@@ -251,31 +203,22 @@ PaintImage AcceleratedStaticBitmapImage::PaintImageForCurrentFrame() {
if (!IsValid())
return PaintImage();
- sk_sp<SkImage> image;
- if (original_skia_image_ &&
- original_skia_image_task_runner_->BelongsToCurrentThread()) {
- // We need to avoid consuming the mailbox in the context where it
- // originated. This avoids swapping back and forth between TextureHolder
- // types.
- image = original_skia_image_;
- } else {
- CreateImageFromMailboxIfNeeded();
- image = skia_texture_holder_->GetSkImage();
- }
+ CreateImageFromMailboxIfNeeded();
return CreatePaintImageBuilder()
- .set_image(image, paint_image_content_id_)
+ .set_image(sk_image_, paint_image_content_id_)
.set_completion_state(PaintImage::CompletionState::DONE)
.TakePaintImage();
}
-void AcceleratedStaticBitmapImage::Draw(cc::PaintCanvas* canvas,
- const cc::PaintFlags& flags,
- const FloatRect& dst_rect,
- const FloatRect& src_rect,
- RespectImageOrientationEnum,
- ImageClampingMode image_clamping_mode,
- ImageDecodingMode decode_mode) {
+void AcceleratedStaticBitmapImage::Draw(
+ cc::PaintCanvas* canvas,
+ const cc::PaintFlags& flags,
+ const FloatRect& dst_rect,
+ const FloatRect& src_rect,
+ RespectImageOrientationEnum should_respect_image_orientation,
+ ImageClampingMode image_clamping_mode,
+ ImageDecodingMode decode_mode) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
auto paint_image = PaintImageForCurrentFrame();
if (!paint_image)
@@ -287,68 +230,185 @@ void AcceleratedStaticBitmapImage::Draw(cc::PaintCanvas* canvas,
.TakePaintImage();
}
StaticBitmapImage::DrawHelper(canvas, flags, dst_rect, src_rect,
- image_clamping_mode, paint_image);
+ image_clamping_mode,
+ should_respect_image_orientation, paint_image);
}
bool AcceleratedStaticBitmapImage::IsValid() const {
- return texture_holder()->IsValid();
+ if (sk_image_ && (!skia_context_provider_wrapper_ ||
+ !sk_image_->isValid(ContextProvider()->GetGrContext()))) {
+ return false;
+ }
+
+ if (mailbox_ref_->is_cross_thread()) {
+ // If context is is from another thread, validity cannot be verified. Just
+ // assume valid. Potential problem will be detected later.
+ return true;
+ }
+
+ return !!context_provider_wrapper_;
}
WebGraphicsContext3DProvider* AcceleratedStaticBitmapImage::ContextProvider()
const {
- return texture_holder()->ContextProvider();
+ auto context = ContextProviderWrapper();
+ return context ? context->ContextProvider() : nullptr;
}
base::WeakPtr<WebGraphicsContext3DProviderWrapper>
AcceleratedStaticBitmapImage::ContextProviderWrapper() const {
- if (!IsValid())
- return nullptr;
-
- return texture_holder()->ContextProviderWrapper();
+ return sk_image_ ? skia_context_provider_wrapper_ : context_provider_wrapper_;
}
void AcceleratedStaticBitmapImage::CreateImageFromMailboxIfNeeded() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (skia_texture_holder_)
+ if (sk_image_)
+ return;
+ InitializeSkImage(0u);
+}
+
+void AcceleratedStaticBitmapImage::InitializeSkImage(
+ GLuint shared_image_texture_id) {
+ DCHECK(!shared_image_texture_id || !mailbox_ref_->is_cross_thread());
+
+ auto context_provider_wrapper = SharedGpuContext::ContextProviderWrapper();
+ if (!context_provider_wrapper)
return;
- DCHECK(mailbox_texture_holder_);
- skia_texture_holder_ =
- std::make_unique<SkiaTextureHolder>(mailbox_texture_holder_.get(), 0u);
+ gpu::raster::RasterInterface* shared_ri =
+ context_provider_wrapper->ContextProvider()->RasterInterface();
+ GrContext* shared_gr_context =
+ context_provider_wrapper->ContextProvider()->GetGrContext();
+ DCHECK(shared_ri &&
+ shared_gr_context); // context isValid already checked in callers
+
+ GLuint shared_context_texture_id = 0u;
+ bool should_delete_texture_on_release = true;
+
+ if (shared_image_texture_id) {
+ shared_context_texture_id = shared_image_texture_id;
+ should_delete_texture_on_release = false;
+ } else {
+ shared_ri->WaitSyncTokenCHROMIUM(
+ mailbox_ref_->GetOrCreateSyncToken(context_provider_wrapper)
+ .GetConstData());
+ shared_context_texture_id =
+ shared_ri->CreateAndConsumeForGpuRaster(mailbox_);
+ shared_ri->BeginSharedImageAccessDirectCHROMIUM(
+ shared_context_texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM);
+ }
+
+ GrGLTextureInfo texture_info;
+ texture_info.fTarget = texture_target_;
+ texture_info.fID = shared_context_texture_id;
+ texture_info.fFormat =
+ CanvasColorParams(sk_image_info_).GLSizedInternalFormat();
+ GrBackendTexture backend_texture(sk_image_info_.width(),
+ sk_image_info_.height(), GrMipMapped::kNo,
+ texture_info);
+
+ GrSurfaceOrigin origin = IsOriginTopLeft() ? kTopLeft_GrSurfaceOrigin
+ : kBottomLeft_GrSurfaceOrigin;
+
+ auto* release_ctx = new ReleaseContext;
+ release_ctx->mailbox_ref = mailbox_ref_;
+ if (should_delete_texture_on_release)
+ release_ctx->texture_id = shared_context_texture_id;
+ release_ctx->context_provider_wrapper = context_provider_wrapper;
+
+ sk_image_ = SkImage::MakeFromTexture(
+ shared_gr_context, backend_texture, origin, sk_image_info_.colorType(),
+ sk_image_info_.alphaType(), sk_image_info_.refColorSpace(),
+ &ReleaseTexture, release_ctx);
+ if (!sk_image_)
+ ReleaseTexture(release_ctx);
+ else
+ skia_context_provider_wrapper_ = std::move(context_provider_wrapper);
}
-void AcceleratedStaticBitmapImage::EnsureMailbox(MailboxSyncMode mode,
- GLenum filter) {
+void AcceleratedStaticBitmapImage::EnsureSyncTokenVerified() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (!mailbox_texture_holder_) {
- TRACE_EVENT0("blink", "AcceleratedStaticBitmapImage::EnsureMailbox");
-
- if (!original_skia_image_) {
- // To ensure that the texture resource stays alive we only really need
- // to retain the source SkImage until the mailbox is consumed, but this
- // works too.
- RetainOriginalSkImage();
- }
- mailbox_texture_holder_ = std::make_unique<MailboxTextureHolder>(
- skia_texture_holder_.get(), filter);
+ if (mailbox_ref_->verified_flush())
+ return;
+
+ if (mailbox_ref_->is_cross_thread()) {
+ // Was originally created on another thread. Should already have a sync
+ // token from the original source context, already verified if needed.
+ NOTREACHED() << "Cross-thread SyncToken should already be verified.";
+ return;
}
- mailbox_texture_holder_->Sync(mode);
+
+ if (!ContextProviderWrapper())
+ return;
+
+ auto sync_token =
+ mailbox_ref_->GetOrCreateSyncToken(ContextProviderWrapper());
+ int8_t* token_data = sync_token.GetData();
+ ContextProvider()->InterfaceBase()->VerifySyncTokensCHROMIUM(&token_data, 1);
+ sync_token.SetVerifyFlush();
+ mailbox_ref_->set_sync_token(sync_token);
+}
+
+gpu::MailboxHolder AcceleratedStaticBitmapImage::GetMailboxHolder() const {
+ if (!IsValid())
+ return gpu::MailboxHolder();
+
+ return gpu::MailboxHolder(
+ mailbox_, mailbox_ref_->GetOrCreateSyncToken(ContextProviderWrapper()),
+ texture_target_);
}
void AcceleratedStaticBitmapImage::Transfer() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- EnsureMailbox(kVerifiedSyncToken, GL_NEAREST);
+ EnsureSyncTokenVerified();
- // Release the SkiaTextureHolder, this SkImage is no longer valid to use
+ // SkImage is bound to the current thread so is no longer valid to use
// cross-thread.
- skia_texture_holder_.reset();
+ sk_image_.reset();
DETACH_FROM_THREAD(thread_checker_);
}
bool AcceleratedStaticBitmapImage::CurrentFrameKnownToBeOpaque() {
- return texture_holder()->CurrentFrameKnownToBeOpaque();
+ return sk_image_info_.isOpaque();
+}
+
+scoped_refptr<StaticBitmapImage>
+AcceleratedStaticBitmapImage::ConvertToColorSpace(
+ sk_sp<SkColorSpace> color_space,
+ SkColorType color_type) {
+ DCHECK(color_space);
+ DCHECK(color_type == kRGBA_F16_SkColorType ||
+ color_type == kRGBA_8888_SkColorType);
+
+ if (!ContextProviderWrapper())
+ return nullptr;
+
+ sk_sp<SkImage> skia_image = PaintImageForCurrentFrame().GetSkImage();
+ if (SkColorSpace::Equals(color_space.get(), skia_image->colorSpace()) &&
+ color_type == skia_image->colorType()) {
+ return this;
+ }
+
+ auto image_info = skia_image->imageInfo()
+ .makeColorSpace(color_space)
+ .makeColorType(color_type);
+
+ auto usage_flags = ContextProviderWrapper()
+ ->ContextProvider()
+ ->SharedImageInterface()
+ ->UsageForMailbox(mailbox_);
+ auto provider = CanvasResourceProvider::CreateSharedImageProvider(
+ Size(), ContextProviderWrapper(), kLow_SkFilterQuality,
+ CanvasColorParams(image_info), IsOriginTopLeft(),
+ CanvasResourceProvider::RasterMode::kGPU, usage_flags);
+ if (!provider) {
+ return nullptr;
+ }
+
+ provider->Canvas()->drawImage(PaintImageForCurrentFrame(), 0, 0, nullptr);
+ return provider->Snapshot(orientation_);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h b/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h
index f89408d112d..2b04e048281 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h
@@ -10,12 +10,9 @@
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
-#include "third_party/blink/renderer/platform/graphics/mailbox_texture_holder.h"
-#include "third_party/blink/renderer/platform/graphics/skia_texture_holder.h"
#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
-class GrContext;
struct SkImageInfo;
namespace viz {
@@ -30,29 +27,10 @@ class PLATFORM_EXPORT AcceleratedStaticBitmapImage final
public:
~AcceleratedStaticBitmapImage() override;
- // SkImage with a texture backing.
- // DO NOT USE. This is in the process of being removed. See crbug.com/962630.
- static scoped_refptr<AcceleratedStaticBitmapImage> CreateFromSkImage(
- sk_sp<SkImage>,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper>);
-
- // Can specify the GrContext that created the texture backing. Ideally all
- // callers would use this option.
- // The |mailbox| is a name for the texture backing, allowing other contexts to
- // use the same backing.
- static scoped_refptr<AcceleratedStaticBitmapImage>
- CreateFromWebGLContextImage(
- const gpu::Mailbox&,
- const gpu::SyncToken&,
- unsigned texture_id,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper>&&,
- IntSize mailbox_size,
- bool is_origin_top_left);
-
- // Creates an image wrapping a shared image mailbox. |release_callback| is a
- // callback to be invoked when this mailbox/texture can be safely destroyed.
- // It can be invoked on any thread. Note that it is assumed that the mailbox
- // can only be used for read operations, no writes are allowed.
+ // Creates an image wrapping a shared image mailbox.
+ //
+ // |sync_token| is the token that must be waited on before reading the
+ // contents of this mailbox.
//
// |shared_image_texture_id| is an optional texture bound to the shared image
// mailbox imported into the provided context. If provided the caller must
@@ -60,28 +38,42 @@ class PLATFORM_EXPORT AcceleratedStaticBitmapImage final
// and has a read lock on the shared image until the |release_callback| is
// invoked.
//
- // If the image is created on a different thread than |context_thread_id| then
- // the provided sync_token must be verified and no |shared_image_texture_id|
- // should be provided.
+ // |sk_image_info| provides the metadata associated with the backing.
+ //
+ // |texture_target| is the target that the texture should be bound to if the
+ // backing is used with GL.
+ //
+ // |is_origin_top_left| indicates whether the origin in texture space
+ // corresponds to the top-left content pixel.
+ //
+ // |context_provider| is the context that the mailbox was created with.
+ // |context_thread_ref| and |context_task_runner| refer to the thread the
+ // context is bound to. If the image is created on a different thread than
+ // |context_thread_ref| then the provided sync_token must be verified and no
+ // |shared_image_texture_id| should be provided.
+ //
+ // |release_callback| is a callback to be invoked when this mailbox can be
+ // safely destroyed. It is guaranteed to be invoked on the context thread.
+ //
+ // Note that it is assumed that the mailbox can only be used for read
+ // operations, no writes are allowed.
static scoped_refptr<AcceleratedStaticBitmapImage> CreateFromCanvasMailbox(
const gpu::Mailbox&,
const gpu::SyncToken&,
GLuint shared_image_texture_id,
const SkImageInfo& sk_image_info,
GLenum texture_target,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper>,
- PlatformThreadId context_thread_id,
bool is_origin_top_left,
+ base::WeakPtr<WebGraphicsContext3DProviderWrapper>,
+ base::PlatformThreadRef context_thread_ref,
+ scoped_refptr<base::SingleThreadTaskRunner> context_task_runner,
std::unique_ptr<viz::SingleReleaseCallback> release_callback);
bool CurrentFrameKnownToBeOpaque() override;
IntSize Size() const override;
bool IsTextureBacked() const override { return true; }
- scoped_refptr<StaticBitmapImage> MakeAccelerated(
- base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_wrapper)
- override {
- return this;
- }
+ scoped_refptr<StaticBitmapImage> ConvertToColorSpace(sk_sp<SkColorSpace>,
+ SkColorType) override;
void Draw(cc::PaintCanvas*,
const cc::PaintFlags&,
@@ -105,82 +97,90 @@ class PLATFORM_EXPORT AcceleratedStaticBitmapImage final
bool unpack_flip_y,
const IntPoint& dest_point,
const IntRect& source_sub_rectangle) override;
-
- bool HasMailbox() const final { return !!mailbox_texture_holder_; }
- // To be called on sender thread before performing a transfer
+ // To be called on sender thread before performing a transfer to a different
+ // thread.
void Transfer() final;
- void EnsureMailbox(MailboxSyncMode, GLenum filter) final;
+ // Makes sure that the sync token associated with this mailbox is verified.
+ void EnsureSyncTokenVerified() final;
- const gpu::Mailbox& GetMailbox() const final {
- static const gpu::Mailbox mailbox;
- return mailbox_texture_holder_ ? mailbox_texture_holder_->GetMailbox()
- : mailbox;
- }
- const gpu::SyncToken& GetSyncToken() const final {
- static const gpu::SyncToken sync_token;
- return mailbox_texture_holder_ ? mailbox_texture_holder_->GetSyncToken()
- : sync_token;
+ // Updates the sync token that must be waited on before recycling or deleting
+ // the mailbox for this image. This must be set by callers using the mailbox
+ // externally to this class.
+ void UpdateSyncToken(const gpu::SyncToken& sync_token) final {
+ mailbox_ref_->set_sync_token(sync_token);
}
+ // Provides the mailbox backing for this image. The caller must wait on the
+ // sync token before accessing this mailbox.
+ gpu::MailboxHolder GetMailboxHolder() const final;
+ bool IsOriginTopLeft() const final { return is_origin_top_left_; }
+
PaintImage PaintImageForCurrentFrame() override;
private:
- AcceleratedStaticBitmapImage(
- sk_sp<SkImage>,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper>&&);
- AcceleratedStaticBitmapImage(
- const gpu::Mailbox&,
- const gpu::SyncToken&,
- unsigned texture_id,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper>&&,
- IntSize mailbox_size,
- bool is_origin_top_left);
+ class MailboxRef : public ThreadSafeRefCounted<MailboxRef> {
+ public:
+ MailboxRef(const gpu::SyncToken& sync_token,
+ base::PlatformThreadRef context_thread_ref,
+ scoped_refptr<base::SingleThreadTaskRunner> context_task_runner,
+ std::unique_ptr<viz::SingleReleaseCallback> release_callback);
+ ~MailboxRef();
+
+ bool is_cross_thread() const {
+ return base::PlatformThread::CurrentRef() != context_thread_ref_;
+ }
+ void set_sync_token(gpu::SyncToken token) { sync_token_ = token; }
+ const gpu::SyncToken& GetOrCreateSyncToken(
+ base::WeakPtr<WebGraphicsContext3DProviderWrapper>);
+ bool verified_flush() { return sync_token_.verified_flush(); }
+
+ private:
+ gpu::SyncToken sync_token_;
+ const base::PlatformThreadRef context_thread_ref_;
+ const scoped_refptr<base::SingleThreadTaskRunner> context_task_runner_;
+ std::unique_ptr<viz::SingleReleaseCallback> release_callback_;
+ };
+
+ struct ReleaseContext {
+ scoped_refptr<MailboxRef> mailbox_ref;
+ GLuint texture_id = 0u;
+ base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper;
+ };
+
+ static void ReleaseTexture(void* ctx);
+
AcceleratedStaticBitmapImage(
const gpu::Mailbox&,
const gpu::SyncToken&,
GLuint shared_image_texture_id,
const SkImageInfo& sk_image_info,
GLenum texture_target,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper>&&,
- PlatformThreadId context_thread_id,
bool is_origin_top_left,
+ const ImageOrientation& orientation,
+ base::WeakPtr<WebGraphicsContext3DProviderWrapper>,
+ base::PlatformThreadRef context_thread_ref,
+ scoped_refptr<base::SingleThreadTaskRunner> context_task_runner,
std::unique_ptr<viz::SingleReleaseCallback> release_callback);
void CreateImageFromMailboxIfNeeded();
- void WaitSyncTokenIfNeeded();
- void RetainOriginalSkImage();
-
- // TODO(khushalsagar): Its unclear what to use here for calls checking IsValid
- // or querying the ContextProvider for the image. This can differ in the 2,
- // for instance if the image was transferred between threads.
- const TextureHolder* texture_holder() const {
- if (skia_texture_holder_)
- return skia_texture_holder_.get();
- return mailbox_texture_holder_.get();
- }
+ void InitializeSkImage(GLuint shared_image_texture_id);
- scoped_refptr<TextureHolder::MailboxRef> mailbox_ref_;
+ const gpu::Mailbox mailbox_;
+ const SkImageInfo sk_image_info_;
+ const GLenum texture_target_;
+ const bool is_origin_top_left_;
- // The image is created with one of the texture holders below while the other
- // one is created lazily if needed and then persisted for the lifetime of the
- // image on a particular thread.
- // When Transfer is called, the image is detached from its current thread to
- // allow it to be used on a different thread. We create(if needed) and cache
- // the mailbox in this case, so the texture can be used with a different
- // context. The skia texture holder is released since the mailbox needs to be
- // imported into the GrContext on the new thread.
- std::unique_ptr<SkiaTextureHolder> skia_texture_holder_;
- std::unique_ptr<MailboxTextureHolder> mailbox_texture_holder_;
+ base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper_;
+ scoped_refptr<MailboxRef> mailbox_ref_;
- THREAD_CHECKER(thread_checker_);
- PaintImage::ContentId paint_image_content_id_;
-
- // For RetainOriginalSkImageForCopyOnWrite()
- sk_sp<SkImage> original_skia_image_;
- scoped_refptr<base::SingleThreadTaskRunner> original_skia_image_task_runner_;
+ // The context this SkImage is bound to.
base::WeakPtr<WebGraphicsContext3DProviderWrapper>
- original_skia_image_context_provider_wrapper_;
+ skia_context_provider_wrapper_;
+ sk_sp<SkImage> sk_image_;
+
+ PaintImage::ContentId paint_image_content_id_;
+ THREAD_CHECKER(thread_checker_);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image_test.cc b/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image_test.cc
index 8f2ff90fddf..5fbfd9887e2 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image_test.cc
@@ -4,12 +4,17 @@
#include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h"
+#include "base/test/null_task_runner.h"
#include "base/test/task_environment.h"
+#include "components/viz/common/resources/single_release_callback.h"
+#include "components/viz/test/test_gles2_interface.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
#include "third_party/blink/renderer/platform/graphics/test/fake_gles2_interface.h"
#include "third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h"
+#include "third_party/blink/renderer/platform/graphics/test/gpu_test_utils.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/skia/include/core/SkSurface.h"
@@ -25,12 +30,16 @@ using testing::SetArgPointee;
using testing::SetArrayArgument;
using testing::Test;
-class MockGLES2InterfaceWithSyncTokenSupport : public FakeGLES2Interface {
+class MockGLES2InterfaceWithSyncTokenSupport : public viz::TestGLES2Interface {
public:
MOCK_METHOD1(GenUnverifiedSyncTokenCHROMIUM, void(GLbyte*));
MOCK_METHOD1(WaitSyncTokenCHROMIUM, void(const GLbyte*));
};
+GLbyte SyncTokenMatcher(const gpu::SyncToken& token) {
+ return reinterpret_cast<const GLbyte*>(&token)[0];
+}
+
gpu::SyncToken GenTestSyncToken(GLbyte id) {
gpu::SyncToken token;
// Store id in the first byte
@@ -38,89 +47,63 @@ gpu::SyncToken GenTestSyncToken(GLbyte id) {
return token;
}
-GLbyte SyncTokenMatcher(const gpu::SyncToken& token) {
- return reinterpret_cast<const GLbyte*>(&token)[0];
+scoped_refptr<StaticBitmapImage> CreateBitmap() {
+ auto mailbox = gpu::Mailbox::GenerateForSharedImage();
+ auto release_callback = viz::SingleReleaseCallback::Create(
+ base::BindOnce([](const gpu::SyncToken&, bool) {}));
+ return AcceleratedStaticBitmapImage::CreateFromCanvasMailbox(
+ mailbox, GenTestSyncToken(100), 0, SkImageInfo::MakeN32Premul(100, 100),
+ GL_TEXTURE_2D, true, SharedGpuContext::ContextProviderWrapper(),
+ base::PlatformThread::CurrentRef(),
+ base::MakeRefCounted<base::NullTaskRunner>(),
+ std::move(release_callback));
}
class AcceleratedStaticBitmapImageTest : public Test {
public:
void SetUp() override {
- auto factory = [](MockGLES2InterfaceWithSyncTokenSupport* gl,
- bool* gpu_compositing_disabled)
- -> std::unique_ptr<WebGraphicsContext3DProvider> {
- *gpu_compositing_disabled = false;
- return std::make_unique<FakeWebGraphicsContext3DProvider>(gl, nullptr);
- };
- SharedGpuContext::SetContextProviderFactoryForTesting(
- WTF::BindRepeating(factory, WTF::Unretained(&gl_)));
+ auto gl = std::make_unique<MockGLES2InterfaceWithSyncTokenSupport>();
+ gl_ = gl.get();
+ context_provider_ = viz::TestContextProvider::Create(std::move(gl));
+ InitializeSharedGpuContext(context_provider_.get());
+ }
+ void TearDown() override {
+ gl_ = nullptr;
+ SharedGpuContext::ResetForTesting();
}
- void TearDown() override { SharedGpuContext::ResetForTesting(); }
protected:
base::test::TaskEnvironment task_environment_;
- MockGLES2InterfaceWithSyncTokenSupport gl_;
+ MockGLES2InterfaceWithSyncTokenSupport* gl_;
+ scoped_refptr<viz::TestContextProvider> context_provider_;
};
-TEST_F(AcceleratedStaticBitmapImageTest, NoTextureHolderThrashing) {
- base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper =
- SharedGpuContext::ContextProviderWrapper();
- GrContext* gr = context_provider_wrapper->ContextProvider()->GetGrContext();
- SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(100, 100);
-
- sk_sp<SkSurface> surface =
- SkSurface::MakeRenderTarget(gr, SkBudgeted::kNo, imageInfo);
-
- SkPaint paint;
- surface->getCanvas()->drawRect(SkRect::MakeXYWH(0, 0, 1, 1), paint);
-
- sk_sp<SkImage> image = surface->makeImageSnapshot();
- scoped_refptr<AcceleratedStaticBitmapImage> bitmap =
- AcceleratedStaticBitmapImage::CreateFromSkImage(image,
- context_provider_wrapper);
+TEST_F(AcceleratedStaticBitmapImageTest, SkImageCached) {
+ auto bitmap = CreateBitmap();
sk_sp<SkImage> stored_image =
bitmap->PaintImageForCurrentFrame().GetSkImage();
- EXPECT_EQ(stored_image.get(), image.get());
-
- bitmap->EnsureMailbox(kUnverifiedSyncToken, GL_LINEAR);
-
- // Verify that calling PaintImageForCurrentFrame does not swap out of mailbox
- // mode. It should use the cached original image instead.
- stored_image = bitmap->PaintImageForCurrentFrame().GetSkImage();
-
- EXPECT_EQ(stored_image.get(), image.get());
+ auto stored_image2 = bitmap->PaintImageForCurrentFrame().GetSkImage();
+ EXPECT_EQ(stored_image.get(), stored_image2.get());
}
TEST_F(AcceleratedStaticBitmapImageTest, CopyToTextureSynchronization) {
- base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper =
- SharedGpuContext::ContextProviderWrapper();
- GrContext* gr = context_provider_wrapper->ContextProvider()->GetGrContext();
- SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(100, 100);
- sk_sp<SkSurface> surface =
- SkSurface::MakeRenderTarget(gr, SkBudgeted::kNo, imageInfo);
-
- sk_sp<SkImage> image = surface->makeImageSnapshot();
- scoped_refptr<AcceleratedStaticBitmapImage> bitmap =
- AcceleratedStaticBitmapImage::CreateFromSkImage(image,
- context_provider_wrapper);
+ auto bitmap = CreateBitmap();
MockGLES2InterfaceWithSyncTokenSupport destination_gl;
- testing::Mock::VerifyAndClearExpectations(&gl_);
+ testing::Mock::VerifyAndClearExpectations(gl_);
testing::Mock::VerifyAndClearExpectations(&destination_gl);
InSequence s; // Indicate to gmock that order of EXPECT_CALLs is important
- // Anterior synchronization
- const gpu::SyncToken sync_token1 = GenTestSyncToken(1);
- EXPECT_CALL(gl_, GenUnverifiedSyncTokenCHROMIUM(_))
- .WillOnce(SetArrayArgument<0>(
- sync_token1.GetConstData(),
- sync_token1.GetConstData() + sizeof(gpu::SyncToken)));
- EXPECT_CALL(destination_gl,
- WaitSyncTokenCHROMIUM(Pointee(SyncTokenMatcher(sync_token1))));
+ // Anterior synchronization. Wait on the sync token for the mailbox on the
+ // dest context.
+ EXPECT_CALL(destination_gl, WaitSyncTokenCHROMIUM(Pointee(SyncTokenMatcher(
+ bitmap->GetMailboxHolder().sync_token))));
- // Posterior synchronization
+ // Posterior synchronization. Generate a sync token on the destination context
+ // to ensure mailbox is destroyed after the copy.
const gpu::SyncToken sync_token2 = GenTestSyncToken(2);
EXPECT_CALL(destination_gl, GenUnverifiedSyncTokenCHROMIUM(_))
.WillOnce(SetArrayArgument<0>(
@@ -129,25 +112,16 @@ TEST_F(AcceleratedStaticBitmapImageTest, CopyToTextureSynchronization) {
IntPoint dest_point(0, 0);
IntRect source_sub_rectangle(0, 0, 10, 10);
- bitmap->CopyToTexture(
+ ASSERT_TRUE(bitmap->CopyToTexture(
&destination_gl, GL_TEXTURE_2D, 1 /*dest_texture_id*/,
0 /*dest_texture_level*/, false /*unpack_premultiply_alpha*/,
- false /*unpack_flip_y*/, dest_point, source_sub_rectangle);
+ false /*unpack_flip_y*/, dest_point, source_sub_rectangle));
testing::Mock::VerifyAndClearExpectations(&gl_);
testing::Mock::VerifyAndClearExpectations(&destination_gl);
- // Note the following expectation is commented-out because the
- // MailboxTextureHolder destructor skips it when the texture ID is 0.
- // The ID is zero because skia detected that it is being used with a fake
- // context, so this problem can't be solved by just mocking GenTextures to
- // make it produce non-zero IDs.
- // TODO(junov): fix this!
-
// Final wait is postponed until destruction.
- // EXPECT_CALL(gl_,
- // WaitSyncTokenCHROMIUM(Pointee(SyncTokenMatcher(sync_token2)))); bitmap =
- // nullptr;
+ EXPECT_EQ(bitmap->GetMailboxHolder().sync_token, sync_token2);
}
} // namespace
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 a35b7834192..deaa02ab7c3 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(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) override {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl.cc b/chromium/third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl.cc
index 64144689835..e34a9cccf59 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl.cc
@@ -199,9 +199,9 @@ void AnimationWorkletMutatorDispatcherImpl::MutateAsynchronouslyInternal(
DCHECK(host_queue_->BelongsToCurrentThread());
on_async_mutation_complete_ = std::move(done_callback);
int next_async_mutation_id = GetNextAsyncMutationId();
- TRACE_EVENT_ASYNC_BEGIN0("cc",
- "AnimationWorkletMutatorDispatcherImpl::MutateAsync",
- next_async_mutation_id);
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(
+ "cc", "AnimationWorkletMutatorDispatcherImpl::MutateAsync",
+ TRACE_ID_LOCAL(next_async_mutation_id));
CrossThreadOnceClosure on_done = CrossThreadBindOnce(
[](scoped_refptr<base::SingleThreadTaskRunner> host_queue,
@@ -239,9 +239,9 @@ void AnimationWorkletMutatorDispatcherImpl::AsyncMutationsDone(
}
// The trace event deos not include queuing time. It covers the interval
// between dispatching the request and retrieving the results.
- TRACE_EVENT_ASYNC_END0("cc",
- "AnimationWorkletMutatorDispatcherImpl::MutateAsync",
- async_mutation_id);
+ TRACE_EVENT_NESTABLE_ASYNC_END0(
+ "cc", "AnimationWorkletMutatorDispatcherImpl::MutateAsync",
+ TRACE_ID_LOCAL(async_mutation_id));
// The Async mutation duration is the total time between request and
// completion, and thus includes queuing time.
UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
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 9524ea33884..624f216a509 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
@@ -9,7 +9,7 @@
#include "base/bind.h"
#include "base/single_thread_task_runner.h"
#include "services/viz/public/mojom/compositing/frame_timing_details.mojom-blink.h"
-#include "third_party/blink/public/platform/interface_provider.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/renderer/platform/scheduler/public/thread_scheduler.h"
#include "ui/gfx/mojom/presentation_feedback.mojom-blink.h"
@@ -64,7 +64,7 @@ void BeginFrameProvider::CreateCompositorFrameSinkIfNeeded() {
base::PlatformThread::SetCurrentThreadPriority(base::ThreadPriority::DISPLAY);
mojo::Remote<mojom::blink::EmbeddedFrameSinkProvider> provider;
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
provider.BindNewPipeAndPassReceiver());
scoped_refptr<base::SingleThreadTaskRunner> task_runner =
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 effb974b2a2..e7faefdc617 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.cc
@@ -115,8 +115,7 @@ PaintImage BitmapImage::PaintImageForTesting() {
PaintImage BitmapImage::CreatePaintImage() {
sk_sp<PaintImageGenerator> generator =
- decoder_ ? decoder_->CreateGenerator(PaintImage::kDefaultFrameIndex)
- : nullptr;
+ decoder_ ? decoder_->CreateGenerator() : nullptr;
if (!generator)
return PaintImage();
@@ -157,6 +156,11 @@ IntSize BitmapImage::SizeRespectingOrientation() const {
return size_respecting_orientation_;
}
+bool BitmapImage::HasDefaultOrientation() const {
+ ImageOrientation orientation = CurrentFrameOrientation();
+ return orientation == kDefaultImageOrientation;
+}
+
bool BitmapImage::GetHotSpot(IntPoint& hot_spot) const {
return decoder_ && decoder_->HotSpot(hot_spot);
}
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 b73b4caf454..b36599efbd7 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.h
@@ -36,9 +36,9 @@
#include "third_party/blink/renderer/platform/graphics/deferred_image_decoder.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
#include "third_party/blink/renderer/platform/graphics/image_animation_policy.h"
-#include "third_party/blink/renderer/platform/graphics/image_orientation.h"
#include "third_party/blink/renderer/platform/image-decoders/image_animation.h"
#include "third_party/blink/renderer/platform/timer.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/skia/include/core/SkRefCnt.h"
@@ -65,7 +65,8 @@ class PLATFORM_EXPORT BitmapImage final : public Image {
bool CurrentFrameHasSingleSecurityOrigin() const override;
IntSize Size() const override;
- IntSize SizeRespectingOrientation() const;
+ IntSize SizeRespectingOrientation() const override;
+ bool HasDefaultOrientation() const override;
bool GetHotSpot(IntPoint&) const override;
String FilenameExtension() const override;
@@ -91,7 +92,7 @@ class PLATFORM_EXPORT BitmapImage final : public Image {
bool CurrentFrameIsLazyDecoded() override;
size_t FrameCount() override;
PaintImage PaintImageForCurrentFrame() override;
- ImageOrientation CurrentFrameOrientation() const;
+ ImageOrientation CurrentFrameOrientation() const override;
PaintImage PaintImageForTesting();
void AdvanceAnimationForTesting() override {
@@ -184,7 +185,10 @@ class PLATFORM_EXPORT BitmapImage final : public Image {
PaintImage::AnimationSequenceId reset_animation_sequence_id_ = 0;
};
-DEFINE_IMAGE_TYPE_CASTS(BitmapImage);
+template <>
+struct DowncastTraits<BitmapImage> {
+ static bool AllowFrom(const Image& image) { return image.IsBitmapImage(); }
+};
} // namespace blink
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 7960ab34ac8..dae80f756bc 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
@@ -38,7 +38,6 @@
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/renderer/platform/graphics/canvas_heuristic_parameters.h"
#include "third_party/blink/renderer/platform/graphics/canvas_resource.h"
#include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
#include "third_party/blink/renderer/platform/graphics/gpu/shared_context_rate_limiter.h"
@@ -75,17 +74,6 @@ Canvas2DLayerBridge::Canvas2DLayerBridge(const IntSize& size,
// Used by browser tests to detect the use of a Canvas2DLayerBridge.
TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation",
TRACE_EVENT_SCOPE_GLOBAL);
- StartRecording();
-
- // Clear the background transparent or opaque. Similar code at
- // CanvasResourceProvider::Clear().
- if (IsValid()) {
- DCHECK(recorder_);
- recorder_->getRecordingCanvas()->clear(
- color_params_.GetOpacityMode() == kOpaque ? SK_ColorBLACK
- : SK_ColorTRANSPARENT);
- DidDraw(FloatRect(0.f, 0.f, size_.Width(), size_.Height()));
- }
}
Canvas2DLayerBridge::~Canvas2DLayerBridge() {
@@ -98,7 +86,6 @@ Canvas2DLayerBridge::~Canvas2DLayerBridge() {
return;
if (acceleration_mode_ != kDisableAcceleration) {
- GraphicsLayer::UnregisterContentsLayer(layer_.get());
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,16 +96,12 @@ Canvas2DLayerBridge::~Canvas2DLayerBridge() {
layer_ = nullptr;
}
-void Canvas2DLayerBridge::StartRecording() {
- recorder_ = std::make_unique<PaintRecorder>();
- cc::PaintCanvas* canvas =
- recorder_->beginRecording(size_.Width(), size_.Height());
- // Always save an initial frame, to support resetting the top level matrix
- // and clip.
- canvas->save();
+void Canvas2DLayerBridge::SetCanvasResourceHost(CanvasResourceHost* host) {
+ resource_host_ = host;
- if (resource_host_)
- resource_host_->RestoreCanvasMatrixClipStack(canvas);
+ if (resource_host_ && GetOrCreateResourceProvider()) {
+ EnsureCleared();
+ }
}
void Canvas2DLayerBridge::ResetResourceProvider() {
@@ -297,9 +280,11 @@ CanvasResourceProvider* Canvas2DLayerBridge::GetOrCreateResourceProvider(
// circular callstack from HTMLCanvasElement.
resource_provider =
resource_host_->GetOrCreateCanvasResourceProviderImpl(adjusted_hint);
- if (!resource_provider)
+ if (!resource_provider || !resource_provider->IsValid())
return nullptr;
+ EnsureCleared();
+
if (IsAccelerated() && !layer_) {
layer_ = cc::TextureLayer::CreateForMailbox(this);
layer_->SetIsDrawable(true);
@@ -308,7 +293,6 @@ CanvasResourceProvider* Canvas2DLayerBridge::GetOrCreateResourceProvider(
layer_->SetBlendBackgroundColor(ColorParams().GetOpacityMode() != kOpaque);
layer_->SetNearestNeighbor(resource_host_->FilterQuality() ==
kNone_SkFilterQuality);
- GraphicsLayer::RegisterContentsLayer(layer_.get());
}
if (!IsHibernating())
@@ -325,13 +309,10 @@ CanvasResourceProvider* Canvas2DLayerBridge::GetOrCreateResourceProvider(
}
}
- PaintFlags copy_paint;
- copy_paint.setBlendMode(SkBlendMode::kSrc);
PaintImageBuilder builder = PaintImageBuilder::WithDefault();
builder.set_image(hibernation_image_, PaintImage::GetNextContentId());
builder.set_id(PaintImage::GetNextId());
- resource_provider->Canvas()->drawImage(builder.TakePaintImage(), 0, 0,
- &copy_paint);
+ resource_provider->RestoreBackBuffer(builder.TakePaintImage());
hibernation_image_.reset();
if (resource_host_) {
@@ -341,9 +322,14 @@ CanvasResourceProvider* Canvas2DLayerBridge::GetOrCreateResourceProvider(
return resource_provider;
}
-cc::PaintCanvas* Canvas2DLayerBridge::DrawingCanvas() {
+cc::PaintCanvas* Canvas2DLayerBridge::GetPaintCanvas() {
DCHECK(resource_host_);
- return recorder_->getRecordingCanvas();
+ // We avoid only using GetOrCreateResourceProvider() here to skip the
+ // IsValid/ContextLost checks since this is in hot code paths. The context
+ // does not need to be valid here since only the recording canvas is used.
+ if (!ResourceProvider() && !GetOrCreateResourceProvider())
+ return nullptr;
+ return ResourceProvider()->Canvas();
}
void Canvas2DLayerBridge::UpdateFilterQuality() {
@@ -418,7 +404,7 @@ void Canvas2DLayerBridge::SetIsBeingDisplayed(bool displayed) {
}
void Canvas2DLayerBridge::DrawFullImage(const cc::PaintImage& image) {
- DrawingCanvas()->drawImage(image, 0, 0);
+ GetPaintCanvas()->drawImage(image, 0, 0);
}
bool Canvas2DLayerBridge::WritePixels(const SkImageInfo& orig_info,
@@ -440,30 +426,27 @@ bool Canvas2DLayerBridge::WritePixels(const SkImageInfo& orig_info,
last_record_tainted_by_write_pixels_ = true;
have_recorded_draw_commands_ = false;
- // Add a save to initialize the transform/clip stack and then restore it after
- // the draw. This is needed because each recording initializes and the resets
- // this state after every flush.
- cc::PaintCanvas* canvas = ResourceProvider()->Canvas();
- PaintCanvasAutoRestore auto_restore(canvas, true);
- if (GetOrCreateResourceProvider()) {
- resource_host_->RestoreCanvasMatrixClipStack(canvas);
- }
ResourceProvider()->WritePixels(orig_info, pixels, row_bytes, x, y);
return true;
}
void Canvas2DLayerBridge::SkipQueuedDrawCommands() {
- if (have_recorded_draw_commands_) {
- recorder_->finishRecordingAsPicture();
- StartRecording();
- have_recorded_draw_commands_ = false;
- }
+ ResourceProvider()->SkipQueuedDrawCommands();
+ have_recorded_draw_commands_ = false;
if (rate_limiter_)
rate_limiter_->Reset();
}
+void Canvas2DLayerBridge::EnsureCleared() {
+ if (cleared_)
+ return;
+ cleared_ = true;
+ ResourceProvider()->Clear();
+ DidDraw(FloatRect(0.f, 0.f, size_.Width(), size_.Height()));
+}
+
void Canvas2DLayerBridge::ClearPendingRasterTimers() {
gpu::raster::RasterInterface* raster_interface = nullptr;
if (IsAccelerated() && SharedGpuContext::ContextProviderWrapper() &&
@@ -546,8 +529,14 @@ void Canvas2DLayerBridge::FlushRecording() {
// Sample one out of every kRasterMetricProbability frames to time
// If the canvas is accelerated, we also need access to the raster_interface
- bool measure_raster_metric = (raster_interface || !IsAccelerated()) &&
- bernoulli_distribution_(random_generator_);
+
+ // We are using @dont_use_idle_scheduling_for_testing_ temporarily to always
+ // measure while testing.
+ const bool will_measure = dont_use_idle_scheduling_for_testing_ ||
+ bernoulli_distribution_(random_generator_);
+ const bool measure_raster_metric =
+ (raster_interface || !IsAccelerated()) && will_measure;
+
RasterTimer rasterTimer;
base::Optional<base::ElapsedTimer> timer;
// Start Recording the raster duration
@@ -561,16 +550,11 @@ void Canvas2DLayerBridge::FlushRecording() {
timer.emplace();
}
- { // Make a new scope so that PaintRecord gets deleted and that gets timed
- cc::PaintCanvas* canvas = ResourceProvider()->Canvas();
- last_recording_ = recorder_->finishRecordingAsPicture();
- canvas->drawPicture(last_recording_);
- last_record_tainted_by_write_pixels_ = false;
- if (!clear_frame_ || !resource_host_ || !resource_host_->IsPrinting()) {
- last_recording_ = nullptr;
- clear_frame_ = false;
- }
- ResourceProvider()->FlushSkia();
+ last_recording_ = ResourceProvider()->FlushCanvas();
+ last_record_tainted_by_write_pixels_ = false;
+ if (!clear_frame_ || !resource_host_ || !resource_host_->IsPrinting()) {
+ last_recording_ = nullptr;
+ clear_frame_ = false;
}
// Finish up the timing operation
@@ -594,7 +578,6 @@ void Canvas2DLayerBridge::FlushRecording() {
if (GetOrCreateResourceProvider())
ResourceProvider()->ReleaseLockedImages();
- StartRecording();
have_recorded_draw_commands_ = false;
}
@@ -716,6 +699,8 @@ cc::Layer* Canvas2DLayerBridge::Layer() {
}
void Canvas2DLayerBridge::DidDraw(const FloatRect& /* rect */) {
+ if (ResourceProvider() && ResourceProvider()->needs_flush())
+ FinalizeFrame();
have_recorded_draw_commands_ = true;
}
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 16a2bcf63d9..8daad03dd61 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
@@ -44,7 +44,6 @@
#include "third_party/blink/renderer/platform/graphics/canvas_color_params.h"
#include "third_party/blink/renderer/platform/graphics/canvas_resource_host.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
-#include "third_party/blink/renderer/platform/graphics/paint/paint_recorder.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/deque.h"
@@ -113,7 +112,8 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient {
virtual void DidRestoreCanvasMatrixClipStack(cc::PaintCanvas*) {}
virtual bool IsAccelerated() const;
- cc::PaintCanvas* DrawingCanvas();
+ // This may recreate CanvasResourceProvider
+ cc::PaintCanvas* GetPaintCanvas();
bool IsValid();
bool WritePixels(const SkImageInfo&,
const void* pixels,
@@ -123,9 +123,7 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient {
void DontUseIdleSchedulingForTesting() {
dont_use_idle_scheduling_for_testing_ = true;
}
- void SetCanvasResourceHost(CanvasResourceHost* host) {
- resource_host_ = host;
- }
+ void SetCanvasResourceHost(CanvasResourceHost* host);
void Hibernate();
bool IsHibernating() const { return hibernation_image_ != nullptr; }
@@ -137,14 +135,6 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient {
cc::TextureLayer* layer_for_testing() { return layer_.get(); }
- // TODO(jochin): Remove this function completely once recorder_ has been
- // moved into CanvasResourceProvider.
- sk_sp<cc::PaintRecord> record_for_testing() {
- sk_sp<cc::PaintRecord> record = recorder_->finishRecordingAsPicture();
- StartRecording();
- return record;
- }
-
// The values of the enum entries must not change because they are used for
// usage metrics histograms. New values can be added to the end.
enum HibernationEvent {
@@ -198,12 +188,11 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient {
bool CheckResourceProviderValid();
void ResetResourceProvider();
- void StartRecording();
void SkipQueuedDrawCommands();
+ void EnsureCleared();
bool ShouldAccelerate(AccelerationHint) const;
- std::unique_ptr<PaintRecorder> recorder_;
sk_sp<SkImage> hibernation_image_;
scoped_refptr<cc::TextureLayer> layer_;
std::unique_ptr<SharedContextRateLimiter> rate_limiter_;
@@ -255,6 +244,10 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient {
sk_sp<cc::PaintRecord> last_recording_;
+ // This tracks whether the canvas has been cleared once after
+ // this bridge was created.
+ bool cleared_ = false;
+
base::WeakPtrFactory<Canvas2DLayerBridge> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(Canvas2DLayerBridge);
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 438e238d047..fa1c188fb95 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
@@ -186,7 +186,7 @@ TEST_F(Canvas2DLayerBridgeTest, NoDrawOnContextLost) {
EXPECT_TRUE(bridge->IsValid());
PaintFlags flags;
uint32_t gen_id = bridge->GetOrCreateResourceProvider()->ContentUniqueID();
- bridge->DrawingCanvas()->drawRect(SkRect::MakeXYWH(0, 0, 1, 1), flags);
+ bridge->GetPaintCanvas()->drawRect(SkRect::MakeXYWH(0, 0, 1, 1), flags);
EXPECT_EQ(gen_id, bridge->GetOrCreateResourceProvider()->ContentUniqueID());
test_context_provider_->TestContextGL()->set_context_lost(true);
EXPECT_EQ(nullptr, bridge->GetOrCreateResourceProvider());
@@ -306,7 +306,7 @@ TEST_F(Canvas2DLayerBridgeTest, AccelerationHint) {
MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
CanvasColorParams());
PaintFlags flags;
- bridge->DrawingCanvas()->drawRect(SkRect::MakeXYWH(0, 0, 1, 1), flags);
+ bridge->GetPaintCanvas()->drawRect(SkRect::MakeXYWH(0, 0, 1, 1), flags);
scoped_refptr<StaticBitmapImage> image =
bridge->NewImageSnapshot(kPreferAcceleration);
EXPECT_TRUE(bridge->IsValid());
@@ -318,7 +318,7 @@ TEST_F(Canvas2DLayerBridgeTest, AccelerationHint) {
MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
CanvasColorParams());
PaintFlags flags;
- bridge->DrawingCanvas()->drawRect(SkRect::MakeXYWH(0, 0, 1, 1), flags);
+ bridge->GetPaintCanvas()->drawRect(SkRect::MakeXYWH(0, 0, 1, 1), flags);
scoped_refptr<StaticBitmapImage> image =
bridge->NewImageSnapshot(kPreferNoAcceleration);
EXPECT_TRUE(bridge->IsValid());
@@ -330,7 +330,7 @@ TEST_F(Canvas2DLayerBridgeTest, AccelerationHint) {
MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kDisableAcceleration,
CanvasColorParams());
PaintFlags flags;
- bridge->DrawingCanvas()->drawRect(SkRect::MakeXYWH(0, 0, 1, 1), flags);
+ bridge->GetPaintCanvas()->drawRect(SkRect::MakeXYWH(0, 0, 1, 1), flags);
scoped_refptr<StaticBitmapImage> image =
bridge->NewImageSnapshot(kPreferAcceleration);
EXPECT_TRUE(bridge->IsValid());
@@ -342,7 +342,7 @@ TEST_F(Canvas2DLayerBridgeTest, AccelerationHint) {
MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kDisableAcceleration,
CanvasColorParams());
PaintFlags flags;
- bridge->DrawingCanvas()->drawRect(SkRect::MakeXYWH(0, 0, 1, 1), flags);
+ bridge->GetPaintCanvas()->drawRect(SkRect::MakeXYWH(0, 0, 1, 1), flags);
scoped_refptr<StaticBitmapImage> image =
bridge->NewImageSnapshot(kPreferNoAcceleration);
EXPECT_TRUE(bridge->IsValid());
@@ -359,6 +359,13 @@ TEST_F(Canvas2DLayerBridgeTest, FallbackToSoftwareIfContextLost) {
EXPECT_FALSE(bridge->IsAccelerated());
}
+void DrawSomething(Canvas2DLayerBridge* bridge) {
+ bridge->DidDraw(FloatRect(0, 0, 1, 1));
+ bridge->FinalizeFrame();
+ // Grabbing an image forces a flush
+ bridge->NewImageSnapshot(kPreferAcceleration);
+}
+
TEST_F(Canvas2DLayerBridgeTest, FallbackToSoftwareOnFailedTextureAlloc) {
{
// No fallback case.
@@ -379,14 +386,19 @@ TEST_F(Canvas2DLayerBridgeTest, FallbackToSoftwareOnFailedTextureAlloc) {
->ContextProvider()
->GetGrContext();
std::unique_ptr<Canvas2DLayerBridge> bridge =
- MakeBridge(IntSize(300, 150), Canvas2DLayerBridge::kEnableAcceleration,
- CanvasColorParams());
+ std::make_unique<Canvas2DLayerBridge>(
+ IntSize(300, 150), Canvas2DLayerBridge::kEnableAcceleration,
+ CanvasColorParams());
+ bridge->DontUseIdleSchedulingForTesting();
EXPECT_TRUE(bridge->IsValid());
EXPECT_TRUE(bridge->IsAccelerated()); // We don't yet know that
// allocation will fail.
// This will cause SkSurface_Gpu creation to fail without
// Canvas2DLayerBridge otherwise detecting that anything was disabled.
gr->abandonContext();
+ host_ = std::make_unique<FakeCanvasResourceHost>(IntSize(300, 150));
+ bridge->SetCanvasResourceHost(host_.get());
+ DrawSomething(bridge.get());
scoped_refptr<StaticBitmapImage> snapshot =
bridge->NewImageSnapshot(kPreferAcceleration);
EXPECT_FALSE(bridge->IsAccelerated());
@@ -402,13 +414,6 @@ class MockLogger : public Canvas2DLayerBridge::Logger {
~MockLogger() override = default;
};
-void DrawSomething(Canvas2DLayerBridge* bridge) {
- bridge->DidDraw(FloatRect(0, 0, 1, 1));
- bridge->FinalizeFrame();
- // Grabbing an image forces a flush
- bridge->NewImageSnapshot(kPreferAcceleration);
-}
-
#if CANVAS2D_HIBERNATION_ENABLED
TEST_F(Canvas2DLayerBridgeTest, HibernationLifeCycle)
#else
@@ -844,13 +849,17 @@ TEST_F(Canvas2DLayerBridgeTest, ResourceRecycling) {
viz::TransferableResource resources[3];
std::unique_ptr<viz::SingleReleaseCallback> callbacks[3];
+ PaintFlags flags;
std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(
IntSize(300, 150), Canvas2DLayerBridge::kForceAccelerationForTesting,
CanvasColorParams());
+ bridge->GetPaintCanvas()->drawLine(0, 0, 2, 2, flags);
DrawSomething(bridge.get());
ASSERT_TRUE(bridge->PrepareTransferableResource(nullptr, &resources[0],
&callbacks[0]));
+
+ bridge->GetPaintCanvas()->drawLine(0, 0, 2, 2, flags);
DrawSomething(bridge.get());
ASSERT_TRUE(bridge->PrepareTransferableResource(nullptr, &resources[1],
&callbacks[1]));
@@ -860,6 +869,7 @@ TEST_F(Canvas2DLayerBridgeTest, ResourceRecycling) {
// Now release the first resource and draw again. It should be reused due to
// recycling.
callbacks[0]->Run(gpu::SyncToken(), false);
+ bridge->GetPaintCanvas()->drawLine(0, 0, 2, 2, flags);
DrawSomething(bridge.get());
ASSERT_TRUE(bridge->PrepareTransferableResource(nullptr, &resources[2],
&callbacks[2]));
@@ -879,13 +889,16 @@ TEST_F(Canvas2DLayerBridgeTest, NoResourceRecyclingWhenPageHidden) {
viz::TransferableResource resources[2];
std::unique_ptr<viz::SingleReleaseCallback> callbacks[2];
+ PaintFlags flags;
std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(
IntSize(300, 150), Canvas2DLayerBridge::kForceAccelerationForTesting,
CanvasColorParams());
+ bridge->GetPaintCanvas()->drawLine(0, 0, 2, 2, flags);
DrawSomething(bridge.get());
ASSERT_TRUE(bridge->PrepareTransferableResource(nullptr, &resources[0],
&callbacks[0]));
+ bridge->GetPaintCanvas()->drawLine(0, 0, 2, 2, flags);
DrawSomething(bridge.get());
ASSERT_TRUE(bridge->PrepareTransferableResource(nullptr, &resources[1],
&callbacks[1]));
@@ -932,9 +945,8 @@ TEST_F(Canvas2DLayerBridgeTest, ReleaseResourcesAfterBridgeDestroyed) {
}
TEST_F(Canvas2DLayerBridgeTest, EnsureCCImageCacheUse) {
- auto color_params =
- CanvasColorParams(CanvasColorSpace::kSRGB, CanvasPixelFormat::kF16,
- kOpaque, CanvasForceRGBA::kNotForced);
+ auto color_params = CanvasColorParams(CanvasColorSpace::kSRGB,
+ CanvasPixelFormat::kF16, kOpaque);
std::unique_ptr<Canvas2DLayerBridge> bridge =
MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
@@ -948,8 +960,8 @@ TEST_F(Canvas2DLayerBridgeTest, EnsureCCImageCacheUse) {
SkIRect::MakeWH(5, 5), kNone_SkFilterQuality, SkMatrix::I(),
0u, expected_color_space)};
- bridge->DrawingCanvas()->drawImage(images[0].paint_image(), 0u, 0u, nullptr);
- bridge->DrawingCanvas()->drawImageRect(
+ 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);
@@ -958,9 +970,9 @@ TEST_F(Canvas2DLayerBridgeTest, EnsureCCImageCacheUse) {
}
TEST_F(Canvas2DLayerBridgeTest, EnsureCCImageCacheUseWithColorConversion) {
- auto color_params =
- CanvasColorParams(CanvasColorSpace::kSRGB, CanvasPixelFormat::kRGBA8,
- kOpaque, CanvasForceRGBA::kNotForced);
+ auto color_params = CanvasColorParams(
+ CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
+ kOpaque);
std::unique_ptr<Canvas2DLayerBridge> bridge =
MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
color_params);
@@ -972,8 +984,8 @@ TEST_F(Canvas2DLayerBridgeTest, EnsureCCImageCacheUseWithColorConversion) {
SkIRect::MakeWH(5, 5), kNone_SkFilterQuality, SkMatrix::I(),
0u, color_params.GetStorageGfxColorSpace())};
- bridge->DrawingCanvas()->drawImage(images[0].paint_image(), 0u, 0u, nullptr);
- bridge->DrawingCanvas()->drawImageRect(
+ 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);
@@ -982,9 +994,8 @@ TEST_F(Canvas2DLayerBridgeTest, EnsureCCImageCacheUseWithColorConversion) {
}
TEST_F(Canvas2DLayerBridgeTest, ImagesLockedUntilCacheLimit) {
- auto color_params =
- CanvasColorParams(CanvasColorSpace::kSRGB, CanvasPixelFormat::kF16,
- kOpaque, CanvasForceRGBA::kNotForced);
+ auto color_params = CanvasColorParams(CanvasColorSpace::kSRGB,
+ CanvasPixelFormat::kF16, kOpaque);
std::unique_ptr<Canvas2DLayerBridge> bridge =
MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
color_params);
@@ -1001,19 +1012,16 @@ TEST_F(Canvas2DLayerBridgeTest, ImagesLockedUntilCacheLimit) {
0u, color_params.GetStorageGfxColorSpace())};
// First 2 images are budgeted, they should remain locked after the op.
- bridge->DrawingCanvas()->drawImage(images[0].paint_image(), 0u, 0u, nullptr);
- bridge->DrawingCanvas()->drawImage(images[1].paint_image(), 0u, 0u, nullptr);
- // TODO(jochin): Can just call provider::FlushSkia() once we move recorder_
- // to the resource provider. The following is a temp workaround.
- cc::PaintCanvas* canvas = bridge->GetOrCreateResourceProvider()->Canvas();
- canvas->drawPicture(bridge->record_for_testing());
+ bridge->GetPaintCanvas()->drawImage(images[0].paint_image(), 0u, 0u, nullptr);
+ bridge->GetPaintCanvas()->drawImage(images[1].paint_image(), 0u, 0u, nullptr);
+ bridge->GetOrCreateResourceProvider()->FlushCanvas();
EXPECT_EQ(image_decode_cache_.num_locked_images(), 2);
// Next image is not budgeted, we should unlock all images other than the last
// image.
image_decode_cache_.set_budget_exceeded(true);
- bridge->DrawingCanvas()->drawImage(images[2].paint_image(), 0u, 0u, nullptr);
- canvas->drawPicture(bridge->record_for_testing());
+ bridge->GetPaintCanvas()->drawImage(images[2].paint_image(), 0u, 0u, nullptr);
+ bridge->GetOrCreateResourceProvider()->FlushCanvas();
EXPECT_EQ(image_decode_cache_.num_locked_images(), 1);
// Ask the provider to release everything, no locked images should remain.
@@ -1022,9 +1030,8 @@ TEST_F(Canvas2DLayerBridgeTest, ImagesLockedUntilCacheLimit) {
}
TEST_F(Canvas2DLayerBridgeTest, QueuesCleanupTaskForLockedImages) {
- auto color_params =
- CanvasColorParams(CanvasColorSpace::kSRGB, CanvasPixelFormat::kF16,
- kOpaque, CanvasForceRGBA::kNotForced);
+ auto color_params = CanvasColorParams(CanvasColorSpace::kSRGB,
+ CanvasPixelFormat::kF16, kOpaque);
std::unique_ptr<Canvas2DLayerBridge> bridge =
MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
color_params);
@@ -1033,12 +1040,9 @@ TEST_F(Canvas2DLayerBridgeTest, QueuesCleanupTaskForLockedImages) {
cc::DrawImage(cc::CreateDiscardablePaintImage(gfx::Size(10, 10)),
SkIRect::MakeWH(10, 10), kNone_SkFilterQuality,
SkMatrix::I(), 0u, color_params.GetStorageGfxColorSpace());
- bridge->DrawingCanvas()->drawImage(image.paint_image(), 0u, 0u, nullptr);
+ bridge->GetPaintCanvas()->drawImage(image.paint_image(), 0u, 0u, nullptr);
- // TODO(jochin): Can just call provider::FlushSkia() once we move recorder_
- // to the resource provider. The following is a temp workaround.
- cc::PaintCanvas* canvas = bridge->GetOrCreateResourceProvider()->Canvas();
- canvas->drawPicture(bridge->record_for_testing());
+ bridge->GetOrCreateResourceProvider()->FlushCanvas();
EXPECT_EQ(image_decode_cache_.num_locked_images(), 1);
base::RunLoop().RunUntilIdle();
@@ -1046,9 +1050,8 @@ TEST_F(Canvas2DLayerBridgeTest, QueuesCleanupTaskForLockedImages) {
}
TEST_F(Canvas2DLayerBridgeTest, ImageCacheOnContextLost) {
- auto color_params =
- CanvasColorParams(CanvasColorSpace::kSRGB, CanvasPixelFormat::kF16,
- kOpaque, CanvasForceRGBA::kNotForced);
+ auto color_params = CanvasColorParams(CanvasColorSpace::kSRGB,
+ CanvasPixelFormat::kF16, kOpaque);
std::unique_ptr<Canvas2DLayerBridge> bridge =
MakeBridge(IntSize(300, 300), Canvas2DLayerBridge::kEnableAcceleration,
color_params);
@@ -1060,14 +1063,14 @@ TEST_F(Canvas2DLayerBridgeTest, ImageCacheOnContextLost) {
cc::DrawImage(cc::CreateDiscardablePaintImage(gfx::Size(20, 20)),
SkIRect::MakeWH(5, 5), kNone_SkFilterQuality, SkMatrix::I(),
0u, color_params.GetStorageGfxColorSpace())};
- bridge->DrawingCanvas()->drawImage(images[0].paint_image(), 0u, 0u, nullptr);
+ bridge->GetPaintCanvas()->drawImage(images[0].paint_image(), 0u, 0u, nullptr);
// Lose the context and ensure that the image provider is not used.
bridge->GetOrCreateResourceProvider()->OnContextDestroyed();
// We should unref all images on the cache when the context is destroyed.
EXPECT_EQ(image_decode_cache_.num_locked_images(), 0);
image_decode_cache_.set_disallow_cache_use(true);
- bridge->DrawingCanvas()->drawImage(images[1].paint_image(), 0u, 0u, &flags);
+ bridge->GetPaintCanvas()->drawImage(images[1].paint_image(), 0u, 0u, &flags);
}
TEST_F(Canvas2DLayerBridgeTest,
@@ -1076,7 +1079,7 @@ TEST_F(Canvas2DLayerBridgeTest,
std::unique_ptr<Canvas2DLayerBridge> bridge = MakeBridge(
size, Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams());
- bridge->DrawingCanvas()->clear(SK_ColorRED);
+ bridge->GetPaintCanvas()->clear(SK_ColorRED);
DrawSomething(bridge.get());
ASSERT_TRUE(bridge->layer_for_testing());
@@ -1104,8 +1107,7 @@ class CustomFakeCanvasResourceHost : public FakeCanvasResourceHost {
TEST_F(Canvas2DLayerBridgeTest, WritePixelsRestoresClipStack) {
CanvasColorParams color_params(CanvasColorSpace::kSRGB,
- CanvasPixelFormat::kF16, kOpaque,
- CanvasForceRGBA::kNotForced);
+ CanvasPixelFormat::kF16, kOpaque);
IntSize size = IntSize(300, 300);
auto host = std::make_unique<CustomFakeCanvasResourceHost>(size);
std::unique_ptr<Canvas2DLayerBridge> bridge =
@@ -1113,23 +1115,26 @@ TEST_F(Canvas2DLayerBridgeTest, WritePixelsRestoresClipStack) {
std::move(host));
PaintFlags flags;
- EXPECT_EQ(bridge->DrawingCanvas()->getTotalMatrix().get(SkMatrix::kMTransX),
- 0);
+ // MakeBridge() results in a call to restore the matrix. So we already have 1.
+ EXPECT_EQ(bridge->GetPaintCanvas()->getTotalMatrix().get(SkMatrix::kMTransX),
+ 5);
+ // Drawline so WritePixels has something to flush
+ bridge->GetPaintCanvas()->drawLine(0, 0, 2, 2, flags);
+ bridge->DidDraw(FloatRect(0, 0, 1, 1));
- cc::PaintCanvas* canvas = bridge->GetOrCreateResourceProvider()->Canvas();
+ // WritePixels flushes recording. Post flush, a new drawing canvas is created
+ // that should have the matrix restored onto it.
bridge->WritePixels(SkImageInfo::MakeN32Premul(10, 10), nullptr, 10, 0, 0);
- // Recording canvas maintain clip stack, while underlying SkCanvas should not.
- EXPECT_EQ(canvas->getTotalMatrix().get(SkMatrix::kMTransX), 0);
- EXPECT_EQ(bridge->DrawingCanvas()->getTotalMatrix().get(SkMatrix::kMTransX),
+ EXPECT_EQ(bridge->GetPaintCanvas()->getTotalMatrix().get(SkMatrix::kMTransX),
5);
- bridge->DrawingCanvas()->drawLine(0, 0, 2, 2, flags);
- // Flush recording. Recording canvas should maintain matrix, while SkCanvas
- // should not.
+ bridge->GetPaintCanvas()->drawLine(0, 0, 2, 2, flags);
+ // Standard flush recording. Post flush, a new drawing canvas is created that
+ // should have the matrix restored onto it.
DrawSomething(bridge.get());
- EXPECT_EQ(bridge->DrawingCanvas()->getTotalMatrix().get(SkMatrix::kMTransX),
+
+ EXPECT_EQ(bridge->GetPaintCanvas()->getTotalMatrix().get(SkMatrix::kMTransX),
5);
- EXPECT_EQ(canvas->getTotalMatrix().get(SkMatrix::kMTransX), 0);
}
TEST_F(Canvas2DLayerBridgeTest, DisplayedCanvasIsRateLimited) {
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 a947db5fb56..d8868023915 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
@@ -40,12 +40,10 @@ CanvasColorParams::CanvasColorParams() = default;
CanvasColorParams::CanvasColorParams(CanvasColorSpace color_space,
CanvasPixelFormat pixel_format,
- OpacityMode opacity_mode,
- CanvasForceRGBA force_rgba)
+ OpacityMode opacity_mode)
: color_space_(color_space),
pixel_format_(pixel_format),
- opacity_mode_(opacity_mode),
- force_rgba_(force_rgba) {}
+ opacity_mode_(opacity_mode) {}
CanvasColorParams::CanvasColorParams(const SkImageInfo& info)
: CanvasColorParams(info.refColorSpace(), info.colorType()) {}
@@ -63,10 +61,16 @@ bool CanvasColorParams::NeedsColorConversion(
}
SkColorType CanvasColorParams::GetSkColorType() const {
- if (pixel_format_ == CanvasPixelFormat::kF16)
- return kRGBA_F16_SkColorType;
- return force_rgba_ == CanvasForceRGBA::kForced ? kRGBA_8888_SkColorType
- : kN32_SkColorType;
+ switch (pixel_format_) {
+ case CanvasPixelFormat::kF16:
+ return kRGBA_F16_SkColorType;
+ case CanvasPixelFormat::kRGBA8:
+ return kRGBA_8888_SkColorType;
+ case CanvasPixelFormat::kBGRA8:
+ return kBGRA_8888_SkColorType;
+ }
+ NOTREACHED();
+ return kN32_SkColorType;
}
SkAlphaType CanvasColorParams::GetSkAlphaType() const {
@@ -111,6 +115,9 @@ gfx::ColorSpace CanvasColorParams::GetStorageGfxColorSpace() const {
}
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_) {
@@ -132,10 +139,6 @@ sk_sp<SkColorSpace> CanvasColorParams::GetSkColorSpace() const {
}
gfx::BufferFormat CanvasColorParams::GetBufferFormat() const {
- static_assert(kN32_SkColorType == kRGBA_8888_SkColorType ||
- kN32_SkColorType == kBGRA_8888_SkColorType,
- "Unexpected kN32_SkColorType value.");
-
switch (GetSkColorType()) {
case kRGBA_8888_SkColorType:
return gfx::BufferFormat::RGBA_8888;
@@ -152,10 +155,6 @@ gfx::BufferFormat CanvasColorParams::GetBufferFormat() const {
GLenum CanvasColorParams::GLUnsizedInternalFormat() const {
// TODO(junov): try GL_RGB when opacity_mode_ == kOpaque
- static_assert(kN32_SkColorType == kRGBA_8888_SkColorType ||
- kN32_SkColorType == kBGRA_8888_SkColorType,
- "Unexpected kN32_SkColorType value.");
-
switch (GetSkColorType()) {
case kRGBA_8888_SkColorType:
return GL_RGBA;
@@ -171,10 +170,6 @@ GLenum CanvasColorParams::GLUnsizedInternalFormat() const {
}
GLenum CanvasColorParams::GLSizedInternalFormat() const {
- static_assert(kN32_SkColorType == kRGBA_8888_SkColorType ||
- kN32_SkColorType == kBGRA_8888_SkColorType,
- "Unexpected kN32_SkColorType value.");
-
switch (GetSkColorType()) {
case kRGBA_8888_SkColorType:
return GL_RGBA8;
@@ -210,10 +205,9 @@ viz::ResourceFormat CanvasColorParams::TransferableResourceFormat() const {
CanvasColorParams::CanvasColorParams(const sk_sp<SkColorSpace> color_space,
SkColorType color_type) {
color_space_ = CanvasColorSpace::kSRGB;
- pixel_format_ = CanvasPixelFormat::kRGBA8;
+ pixel_format_ = GetNativeCanvasPixelFormat();
// When there is no color space information, the SkImage is in legacy mode and
- // the color type is kN32_SkColorType (which translates to kRGBA8 canvas pixel
- // format).
+ // the color type is kRGBA8 canvas pixel format.
if (!color_space)
return;
@@ -239,7 +233,7 @@ CanvasColorParams::CanvasColorParams(const sk_sp<SkColorSpace> color_space,
if (color_type == kRGBA_F16_SkColorType)
pixel_format_ = CanvasPixelFormat::kF16;
else if (color_type == kRGBA_8888_SkColorType)
- force_rgba_ = CanvasForceRGBA::kForced;
+ pixel_format_ = CanvasPixelFormat::kRGBA8;
}
} // namespace blink
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 5c1dfde62a9..3920ea5c865 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
@@ -34,28 +34,29 @@ enum class CanvasColorSpace {
enum class CanvasPixelFormat {
kRGBA8,
+ kBGRA8,
kF16,
};
-// todo(crbug/1021986) remove force_rgba in canvasColorParams
-enum class CanvasForceRGBA { kForced, kNotForced };
-
class PLATFORM_EXPORT CanvasColorParams {
DISALLOW_NEW();
public:
// The default constructor will create an output-blended 8-bit surface.
CanvasColorParams();
- CanvasColorParams(CanvasColorSpace,
- CanvasPixelFormat,
- OpacityMode,
- CanvasForceRGBA);
+ CanvasColorParams(CanvasColorSpace, CanvasPixelFormat, OpacityMode);
explicit CanvasColorParams(const SkImageInfo&);
+ static CanvasPixelFormat GetNativeCanvasPixelFormat() {
+ if (kN32_SkColorType == kRGBA_8888_SkColorType)
+ return CanvasPixelFormat::kRGBA8;
+ else if (kN32_SkColorType == kBGRA_8888_SkColorType)
+ return CanvasPixelFormat::kBGRA8;
+ }
+
CanvasColorSpace ColorSpace() const { return color_space_; }
CanvasPixelFormat PixelFormat() const { return pixel_format_; }
OpacityMode GetOpacityMode() const { return opacity_mode_; }
- CanvasForceRGBA GetForceRGBA() const { return force_rgba_; }
void SetCanvasColorSpace(CanvasColorSpace c) { color_space_ = c; }
void SetCanvasPixelFormat(CanvasPixelFormat f) { pixel_format_ = f; }
@@ -99,9 +100,8 @@ class PLATFORM_EXPORT CanvasColorParams {
SkColorType color_type);
CanvasColorSpace color_space_ = CanvasColorSpace::kSRGB;
- CanvasPixelFormat pixel_format_ = CanvasPixelFormat::kRGBA8;
+ CanvasPixelFormat pixel_format_ = GetNativeCanvasPixelFormat();
OpacityMode opacity_mode_ = kNonOpaque;
- CanvasForceRGBA force_rgba_ = CanvasForceRGBA::kNotForced;
};
} // namespace blink
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 352fa6c89a0..b34686a8065 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
@@ -25,8 +25,7 @@ TEST(CanvasColorParamsTest, MatchSkColorSpaceWithGfxColorSpace) {
};
for (int iter_color_space = 0; iter_color_space < 4; iter_color_space++) {
CanvasColorParams color_params(canvas_color_spaces[iter_color_space],
- CanvasPixelFormat::kF16, kNonOpaque,
- CanvasForceRGBA::kNotForced);
+ CanvasPixelFormat::kF16, kNonOpaque);
sk_sp<SkColorSpace> canvas_drawing_color_space =
color_params.GetSkColorSpace();
sk_sp<SkColorSpace> canvas_media_color_space =
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_heuristic_parameters.h b/chromium/third_party/blink/renderer/platform/graphics/canvas_heuristic_parameters.h
deleted file mode 100644
index 417d0bf00d4..00000000000
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_heuristic_parameters.h
+++ /dev/null
@@ -1,67 +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_PLATFORM_GRAPHICS_CANVAS_HEURISTIC_PARAMETERS_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_CANVAS_HEURISTIC_PARAMETERS_H_
-
-#include "build/build_config.h"
-
-namespace blink {
-
-namespace canvas_heuristic_parameters {
-
-enum {
- // Disable Deferral overdraw parameters
- //======================================
-
- // Heuristic: Canvases that are overdrawn beyond this factor in a
- // single frame will be disabled deferral.
- kExpensiveOverdrawThreshold = 10,
-
- // GPU readback prevention heuristics
- //====================================
-
- // When a canvas is used as a source image, if its destination is
- // non-accelerated and the source canvas is accelerated, a readback
- // from the gpu is necessary. This option causes the source canvas to
- // switch to non-accelerated when this situation is encountered to
- // prevent future canvas-to-canvas draws from requiring a readback.
- kDisableAccelerationToAvoidReadbacks = 0,
-
- // See description of DisableAccelerationToAvoidReadbacks. This is the
- // opposite strategy : accelerate the destination canvas. If both
- // EnableAccelerationToAvoidReadbacks and
- // DisableAccelerationToAvoidReadbacks are specified, we try to enable
- // acceleration on the destination first. If that does not succeed,
- // we disable acceleration on the source canvas. Either way, future
- // readbacks are prevented.
- kEnableAccelerationToAvoidReadbacks = 1,
-
- // Accelerated rendering heuristics
- // =================================
-
- // Enables frequent flushing of the GrContext for accelerated canvas. Since
- // skia internally batches the GrOp list when flushing the recording onto the
- // SkCanvasand may only flush it the command buffer at the end of the frame,
- // it can lead to inefficient parallelization with the GPU. This enables
- // triggering context flushes at regular intervals, after a fixed number of
- // draws.
- kEnableGrContextFlushes = 1,
-
- // The maximum number of draw ops executed on the canvas, after which the
- // underlying GrContext is flushed.
- kMaxDrawsBeforeContextFlush = 50,
-
- // Canvas resource provider
- // ========================
-
- // The maximum number of inflight resources waiting to be used for recycling.
- kMaxRecycledCanvasResources = 2,
-}; // enum
-
-} // namespace canvas_heuristic_parameters
-
-} // namespace blink
-
-#endif
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 429b7c2fab1..c414406d28a 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.cc
@@ -15,6 +15,7 @@
#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
#include "gpu/command_buffer/client/raster_interface.h"
#include "gpu/command_buffer/client/shared_image_interface.h"
+#include "gpu/command_buffer/common/capabilities.h"
#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
#include "gpu/command_buffer/common/shared_image_usage.h"
#include "gpu/command_buffer/common/sync_token.h"
@@ -48,7 +49,8 @@ gpu::mojom::blink::MailboxPtr SharedBitmapIdToGpuMailboxPtr(
CanvasResource::CanvasResource(base::WeakPtr<CanvasResourceProvider> provider,
SkFilterQuality filter_quality,
const CanvasColorParams& color_params)
- : owning_thread_id_(base::PlatformThread::CurrentId()),
+ : owning_thread_ref_(base::PlatformThread::CurrentRef()),
+ owning_thread_task_runner_(Thread::Current()->GetTaskRunner()),
provider_(std::move(provider)),
filter_quality_(filter_quality),
color_params_(color_params) {}
@@ -60,12 +62,14 @@ CanvasResource::~CanvasResource() {
}
void CanvasResource::OnDestroy() {
- if (owning_thread_id_ != base::PlatformThread::CurrentId()) {
+ if (is_cross_thread()) {
// Destroyed on wrong thread. This can happen when the thread of origin was
// torn down, in which case the GPU context owning any underlying resources
// no longer exists.
Abandon();
} else {
+ if (provider_)
+ provider_->OnDestroyResource();
TearDown();
}
#if DCHECK_IS_ON()
@@ -111,7 +115,6 @@ static void ReleaseFrameResources(
// TODO(khushalsagar): If multiple readers had access to this resource, losing
// it once should make sure subsequent releases don't try to recycle this
// resource.
- // Also what about single buffered canvas?
if (lost_resource)
resource->NotifyResourceLost();
if (resource_provider && !lost_resource && resource->IsRecycleable())
@@ -286,6 +289,12 @@ void CanvasResourceSharedBitmap::Abandon() {
shared_mapping_ = {};
}
+void CanvasResourceSharedBitmap::NotifyResourceLost() {
+ // Release our reference to the shared memory mapping since the resource can
+ // no longer be safely recycled and this memory is needed for copy-on-write.
+ shared_mapping_ = {};
+}
+
const gpu::Mailbox& CanvasResourceSharedBitmap::GetOrCreateGpuMailbox(
MailboxSyncMode sync_mode) {
return shared_bitmap_id_;
@@ -315,16 +324,16 @@ CanvasResourceSharedImage::CanvasResourceSharedImage(
base::WeakPtr<CanvasResourceProvider> provider,
SkFilterQuality filter_quality,
const CanvasColorParams& color_params,
- bool is_overlay_candidate,
bool is_origin_top_left,
- bool allow_concurrent_read_write_access,
- bool is_accelerated)
+ bool is_accelerated,
+ uint32_t shared_image_usage_flags)
: CanvasResource(std::move(provider), filter_quality, color_params),
context_provider_wrapper_(std::move(context_provider_wrapper)),
- is_overlay_candidate_(is_overlay_candidate),
size_(size),
is_origin_top_left_(is_origin_top_left),
is_accelerated_(is_accelerated),
+ is_overlay_candidate_(shared_image_usage_flags &
+ gpu::SHARED_IMAGE_USAGE_SCANOUT),
texture_target_(
is_overlay_candidate_
? gpu::GetBufferTextureTarget(
@@ -333,14 +342,14 @@ CanvasResourceSharedImage::CanvasResourceSharedImage(
context_provider_wrapper_->ContextProvider()
->GetCapabilities())
: GL_TEXTURE_2D),
- owning_thread_task_runner_(Thread::Current()->GetTaskRunner()) {
- if (!context_provider_wrapper_)
- return;
-
+ use_oop_rasterization_(context_provider_wrapper_->ContextProvider()
+ ->GetCapabilities()
+ .supports_oop_raster) {
auto* gpu_memory_buffer_manager =
Platform::Current()->GetGpuMemoryBufferManager();
if (!is_accelerated_) {
DCHECK(gpu_memory_buffer_manager);
+ DCHECK(shared_image_usage_flags & gpu::SHARED_IMAGE_USAGE_DISPLAY);
gpu_memory_buffer_ = gpu_memory_buffer_manager->CreateGpuMemoryBuffer(
gfx::Size(size), ColorParams().GetBufferFormat(),
@@ -355,23 +364,26 @@ CanvasResourceSharedImage::CanvasResourceSharedImage(
context_provider_wrapper_->ContextProvider()->SharedImageInterface();
DCHECK(shared_image_interface);
- uint32_t flags = gpu::SHARED_IMAGE_USAGE_DISPLAY |
- gpu::SHARED_IMAGE_USAGE_GLES2 |
- gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT;
- if (is_overlay_candidate_)
- flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
- if (allow_concurrent_read_write_access)
- flags |= gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE;
+ // The GLES2 flag is needed for rendering via GL using a GrContext.
+ if (use_oop_rasterization_) {
+ shared_image_usage_flags = shared_image_usage_flags |
+ gpu::SHARED_IMAGE_USAGE_RASTER |
+ gpu::SHARED_IMAGE_USAGE_OOP_RASTERIZATION;
+ } else {
+ shared_image_usage_flags = shared_image_usage_flags |
+ gpu::SHARED_IMAGE_USAGE_GLES2 |
+ gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT;
+ }
gpu::Mailbox shared_image_mailbox;
if (gpu_memory_buffer_) {
shared_image_mailbox = shared_image_interface->CreateSharedImage(
gpu_memory_buffer_.get(), gpu_memory_buffer_manager,
- ColorParams().GetStorageGfxColorSpace(), flags);
+ ColorParams().GetStorageGfxColorSpace(), shared_image_usage_flags);
} else {
shared_image_mailbox = shared_image_interface->CreateSharedImage(
ColorParams().TransferableResourceFormat(), gfx::Size(size),
- ColorParams().GetStorageGfxColorSpace(), flags);
+ ColorParams().GetStorageGfxColorSpace(), shared_image_usage_flags);
}
// Wait for the mailbox to be ready to be used.
@@ -380,6 +392,10 @@ CanvasResourceSharedImage::CanvasResourceSharedImage(
auto* raster_interface = RasterInterface();
DCHECK(raster_interface);
owning_thread_data().shared_image_mailbox = shared_image_mailbox;
+
+ if (use_oop_rasterization_)
+ return;
+
owning_thread_data().texture_id_for_read_access =
raster_interface->CreateAndConsumeForGpuRaster(shared_image_mailbox);
@@ -387,7 +403,8 @@ CanvasResourceSharedImage::CanvasResourceSharedImage(
// a texture for writes.
if (!is_accelerated_)
return;
- if (allow_concurrent_read_write_access) {
+ if (shared_image_usage_flags &
+ gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE) {
owning_thread_data().texture_id_for_write_access =
raster_interface->CreateAndConsumeForGpuRaster(shared_image_mailbox);
} else {
@@ -402,15 +419,14 @@ scoped_refptr<CanvasResourceSharedImage> CanvasResourceSharedImage::Create(
base::WeakPtr<CanvasResourceProvider> provider,
SkFilterQuality filter_quality,
const CanvasColorParams& color_params,
- bool is_overlay_candidate,
bool is_origin_top_left,
- bool allow_concurrent_read_write_access,
- bool is_accelerated) {
+ bool is_accelerated,
+ uint32_t shared_image_usage_flags) {
TRACE_EVENT0("blink", "CanvasResourceSharedImage::Create");
auto resource = base::AdoptRef(new CanvasResourceSharedImage(
size, std::move(context_provider_wrapper), std::move(provider),
- filter_quality, color_params, is_overlay_candidate, is_origin_top_left,
- allow_concurrent_read_write_access, is_accelerated));
+ filter_quality, color_params, is_origin_top_left, is_accelerated,
+ shared_image_usage_flags));
return resource->IsValid() ? resource : nullptr;
}
@@ -422,13 +438,11 @@ CanvasResourceSharedImage::~CanvasResourceSharedImage() {
OnDestroy();
}
-GLenum CanvasResourceSharedImage::TextureTarget() const {
- return texture_target_;
-}
-
void CanvasResourceSharedImage::TearDown() {
DCHECK(!is_cross_thread());
+ // The context deletes all shared images on destruction which means no
+ // cleanup is needed if the context was lost.
if (ContextProviderWrapper()) {
auto* raster_interface = RasterInterface();
auto* shared_image_interface =
@@ -459,11 +473,8 @@ void CanvasResourceSharedImage::TearDown() {
}
void CanvasResourceSharedImage::Abandon() {
- if (auto context_provider = SharedGpuContext::ContextProviderWrapper()) {
- auto* sii = context_provider->ContextProvider()->SharedImageInterface();
- if (sii)
- sii->DestroySharedImage(gpu::SyncToken(), mailbox());
- }
+ // Called when the owning thread has been torn down which will destroy the
+ // context on which the shared image was created so no cleanup is necessary.
}
void CanvasResourceSharedImage::WillDraw() {
@@ -484,17 +495,10 @@ void CanvasResourceSharedImage::OnBitmapImageDestroyed(
bool has_read_ref_on_texture,
const gpu::SyncToken& sync_token,
bool is_lost) {
- if (resource->is_cross_thread()) {
- auto& task_runner = *resource->owning_thread_task_runner_;
- PostCrossThreadTask(
- task_runner, FROM_HERE,
- CrossThreadBindOnce(&CanvasResourceSharedImage::OnBitmapImageDestroyed,
- std::move(resource), has_read_ref_on_texture,
- sync_token, is_lost));
- return;
- }
+ DCHECK(!resource->is_cross_thread());
if (has_read_ref_on_texture) {
+ DCHECK(!resource->use_oop_rasterization_);
DCHECK_GT(resource->owning_thread_data().bitmap_image_read_refs, 0u);
resource->owning_thread_data().bitmap_image_read_refs--;
@@ -546,7 +550,8 @@ scoped_refptr<StaticBitmapImage> CanvasResourceSharedImage::Bitmap() {
// created here, the image will create a new representation from the mailbox
// rather than referring to the shared image's texture ID if it was provided
// below.
- const bool has_read_ref_on_texture = !is_cross_thread();
+ const bool has_read_ref_on_texture =
+ !is_cross_thread() && !use_oop_rasterization_;
GLuint texture_id_for_image = 0u;
if (has_read_ref_on_texture) {
texture_id_for_image = owning_thread_data().texture_id_for_read_access;
@@ -574,8 +579,8 @@ scoped_refptr<StaticBitmapImage> CanvasResourceSharedImage::Bitmap() {
gpu::SyncToken token = is_cross_thread() ? sync_token() : gpu::SyncToken();
image = AcceleratedStaticBitmapImage::CreateFromCanvasMailbox(
mailbox(), token, texture_id_for_image, image_info, texture_target_,
- context_provider_wrapper_, owning_thread_id_, is_origin_top_left_,
- std::move(release_callback));
+ is_origin_top_left_, context_provider_wrapper_, owning_thread_ref_,
+ owning_thread_task_runner_, std::move(release_callback));
DCHECK(image);
return image;
@@ -708,8 +713,9 @@ scoped_refptr<StaticBitmapImage> ExternalCanvasResource::Bitmap() {
return AcceleratedStaticBitmapImage::CreateFromCanvasMailbox(
mailbox_, GetSyncToken(), /*shared_image_texture_id=*/0u,
- CreateSkImageInfo(), texture_target_, context_provider_wrapper_,
- owning_thread_id_, is_origin_top_left_, std::move(release_callback));
+ CreateSkImageInfo(), texture_target_, is_origin_top_left_,
+ context_provider_wrapper_, owning_thread_ref_, owning_thread_task_runner_,
+ std::move(release_callback));
}
void ExternalCanvasResource::TearDown() {
@@ -793,7 +799,7 @@ scoped_refptr<StaticBitmapImage> CanvasResourceSwapChain::Bitmap() {
// It's safe to share the front 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 (base::PlatformThread::CurrentId() == owning_thread_id_)
+ if (!is_cross_thread())
shared_texture_id = front_buffer_texture_id_;
// The |release_callback| keeps a ref on this resource to ensure the backing
@@ -806,22 +812,22 @@ scoped_refptr<StaticBitmapImage> CanvasResourceSwapChain::Bitmap() {
return AcceleratedStaticBitmapImage::CreateFromCanvasMailbox(
front_buffer_mailbox_, sync_token_, shared_texture_id, image_info,
- GL_TEXTURE_2D, context_provider_wrapper_, owning_thread_id_,
- /*is_origin_top_left=*/true, std::move(release_callback));
+ GL_TEXTURE_2D, true /*is_origin_top_left*/, context_provider_wrapper_,
+ owning_thread_ref_, owning_thread_task_runner_,
+ std::move(release_callback));
}
void CanvasResourceSwapChain::Abandon() {
- if (auto context_provider = SharedGpuContext::ContextProviderWrapper()) {
- auto* sii = context_provider->ContextProvider()->SharedImageInterface();
- DCHECK(sii);
- sii->DestroySharedImage(gpu::SyncToken(), front_buffer_mailbox_);
- sii->DestroySharedImage(gpu::SyncToken(), back_buffer_mailbox_);
- }
+ // Called when the owning thread has been torn down which will destroy the
+ // context on which the shared image was created so no cleanup is necessary.
}
void CanvasResourceSwapChain::TearDown() {
+ // The context deletes all shared images on destruction which means no
+ // cleanup is needed if the context was lost.
if (!context_provider_wrapper_)
return;
+
auto* raster_interface =
context_provider_wrapper_->ContextProvider()->RasterInterface();
DCHECK(raster_interface);
@@ -855,7 +861,7 @@ const gpu::SyncToken CanvasResourceSwapChain::GetSyncToken() {
}
void CanvasResourceSwapChain::PresentSwapChain() {
- DCHECK_EQ(base::PlatformThread::CurrentId(), owning_thread_id_);
+ DCHECK(!is_cross_thread());
DCHECK(context_provider_wrapper_);
TRACE_EVENT0("blink", "CanvasResourceSwapChain::PresentSwapChain");
@@ -882,7 +888,8 @@ void CanvasResourceSwapChain::PresentSwapChain() {
// The wait sync token ensure that the present executes before we do the copy.
raster_interface->CopySubTexture(front_buffer_mailbox_, back_buffer_mailbox_,
GL_TEXTURE_2D, 0, 0, 0, 0, size_.Width(),
- size_.Height());
+ size_.Height(), false /* unpack_flip_y */,
+ false /* unpack_premultiply_alpha */);
}
base::WeakPtr<WebGraphicsContext3DProviderWrapper>
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 b5f09b1d63d..e68d38e845b 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.h
@@ -133,19 +133,6 @@ class PLATFORM_EXPORT CanvasResource
// CanvasResourceProvider and derivatives should call this.
virtual void TakeSkImage(sk_sp<SkImage> image) = 0;
- // Provides the texture ID that can be used to write to this resource.
- // TODO(khushalsagar): Won't work with OOPR.
- virtual GLuint GetBackingTextureHandleForOverwrite() {
- NOTREACHED();
- return 0;
- }
-
- // Returns the texture target for the ID provided above.
- virtual GLenum TextureTarget() const {
- NOTREACHED();
- return 0;
- }
-
// Called when the resource is marked lost. Losing a resource does not mean
// that the backing memory has been destroyed, since the resource itself keeps
// a ref on that memory.
@@ -153,12 +140,7 @@ class PLATFORM_EXPORT CanvasResource
// token for the resource to be safely recycled and its the GL state may be
// inconsistent with when the resource was given to the compositor. So it
// should not be recycled for writing again but can be safely read from.
- virtual void NotifyResourceLost() {
- // TODO(khushalsagar): Some implementations respect the don't write again
- // policy but some don't. Fix that once shared images replace all
- // accelerated use-cases.
- Abandon();
- }
+ virtual void NotifyResourceLost() = 0;
void SetFilterQuality(SkFilterQuality filter) { filter_quality_ = filter; }
// The filter quality to use when the resource is drawn by the compositor.
@@ -166,6 +148,10 @@ class PLATFORM_EXPORT CanvasResource
SkImageInfo CreateSkImageInfo() const;
+ bool is_cross_thread() const {
+ return base::PlatformThread::CurrentRef() != owning_thread_ref_;
+ }
+
protected:
CanvasResource(base::WeakPtr<CanvasResourceProvider>,
SkFilterQuality,
@@ -212,7 +198,15 @@ class PLATFORM_EXPORT CanvasResource
CanvasResourceProvider* Provider() { return provider_.get(); }
base::WeakPtr<CanvasResourceProvider> WeakProvider() { return provider_; }
- const base::PlatformThreadId owning_thread_id_;
+ const base::PlatformThreadRef owning_thread_ref_;
+ const scoped_refptr<base::SingleThreadTaskRunner> owning_thread_task_runner_;
+
+ protected:
+ // Returns the texture target for the resource.
+ virtual GLenum TextureTarget() const {
+ NOTREACHED();
+ return 0;
+ }
private:
// Sync token that was provided when resource was released
@@ -245,10 +239,11 @@ class PLATFORM_EXPORT CanvasResourceSharedBitmap final : public CanvasResource {
scoped_refptr<StaticBitmapImage> Bitmap() final;
bool OriginClean() const final { return is_origin_clean_; }
void SetOriginClean(bool flag) final { is_origin_clean_ = flag; }
+ const gpu::Mailbox& GetOrCreateGpuMailbox(MailboxSyncMode) override;
+ void NotifyResourceLost() override;
private:
void TearDown() override;
- const gpu::Mailbox& GetOrCreateGpuMailbox(MailboxSyncMode) override;
bool HasGpuMailbox() const override;
CanvasResourceSharedBitmap(const IntSize&,
@@ -271,10 +266,9 @@ class PLATFORM_EXPORT CanvasResourceSharedImage final : public CanvasResource {
base::WeakPtr<CanvasResourceProvider>,
SkFilterQuality,
const CanvasColorParams&,
- bool is_overlay_candidate,
bool is_origin_top_left,
- bool allow_concurrent_read_write_access,
- bool is_accelerated);
+ bool is_accelerated,
+ uint32_t shared_image_usage_flags);
~CanvasResourceSharedImage() override;
bool IsRecycleable() const final { return true; }
@@ -302,16 +296,15 @@ class PLATFORM_EXPORT CanvasResourceSharedImage final : public CanvasResource {
GLuint GetTextureIdForWriteAccess() const {
return owning_thread_data().texture_id_for_write_access;
}
+ GLenum TextureTarget() const override { return texture_target_; }
void WillDraw();
- bool is_cross_thread() const {
- return base::PlatformThread::CurrentId() != owning_thread_id_;
- }
bool has_read_access() const {
return owning_thread_data().bitmap_image_read_refs > 0u;
}
bool is_lost() const { return owning_thread_data().is_lost; }
void CopyRenderingResultsToGpuMemoryBuffer(const sk_sp<SkImage>& image);
+ const gpu::Mailbox& GetOrCreateGpuMailbox(MailboxSyncMode) override;
private:
// These members are either only accessed on the owning thread, or are only
@@ -345,8 +338,6 @@ class PLATFORM_EXPORT CanvasResourceSharedImage final : public CanvasResource {
void Abandon() override;
base::WeakPtr<WebGraphicsContext3DProviderWrapper> ContextProviderWrapper()
const override;
- const gpu::Mailbox& GetOrCreateGpuMailbox(MailboxSyncMode) override;
- GLenum TextureTarget() const final;
bool HasGpuMailbox() const override;
const gpu::SyncToken GetSyncToken() override;
bool IsOverlayCandidate() const final { return is_overlay_candidate_; }
@@ -356,17 +347,16 @@ class PLATFORM_EXPORT CanvasResourceSharedImage final : public CanvasResource {
base::WeakPtr<CanvasResourceProvider>,
SkFilterQuality,
const CanvasColorParams&,
- bool is_overlay_candidate,
bool is_origin_top_left,
- bool allow_concurrent_read_write_access,
- bool is_accelerated);
+ bool is_accelerated,
+ uint32_t shared_image_usage_flags);
OwningThreadData& owning_thread_data() {
- DCHECK_EQ(base::PlatformThread::CurrentId(), owning_thread_id_);
+ DCHECK(!is_cross_thread());
return owning_thread_data_;
}
const OwningThreadData& owning_thread_data() const {
- DCHECK_EQ(base::PlatformThread::CurrentId(), owning_thread_id_);
+ DCHECK(!is_cross_thread());
return owning_thread_data_;
}
@@ -394,12 +384,12 @@ class PLATFORM_EXPORT CanvasResourceSharedImage final : public CanvasResource {
std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_;
// Accessed on any thread.
- const bool is_overlay_candidate_;
const IntSize size_;
const bool is_origin_top_left_;
const bool is_accelerated_;
+ const bool is_overlay_candidate_;
const GLenum texture_target_;
- const scoped_refptr<base::SingleThreadTaskRunner> owning_thread_task_runner_;
+ const bool use_oop_rasterization_;
OwningThreadData owning_thread_data_;
};
@@ -428,14 +418,18 @@ class PLATFORM_EXPORT ExternalCanvasResource final : public CanvasResource {
void Abandon() final;
IntSize Size() const final { return size_; }
void TakeSkImage(sk_sp<SkImage> image) final;
+ void NotifyResourceLost() override {
+ // Used for single buffering mode which doesn't need to care about sync
+ // token synchronization.
+ }
scoped_refptr<StaticBitmapImage> Bitmap() override;
+ const gpu::Mailbox& GetOrCreateGpuMailbox(MailboxSyncMode) override;
private:
void TearDown() override;
GLenum TextureTarget() const final { return texture_target_; }
bool IsOverlayCandidate() const final { return true; }
- const gpu::Mailbox& GetOrCreateGpuMailbox(MailboxSyncMode) override;
bool HasGpuMailbox() const override;
const gpu::SyncToken GetSyncToken() override;
base::WeakPtr<WebGraphicsContext3DProviderWrapper> ContextProviderWrapper()
@@ -481,20 +475,24 @@ class PLATFORM_EXPORT CanvasResourceSwapChain final : public CanvasResource {
void Abandon() final;
IntSize Size() const final { return size_; }
void TakeSkImage(sk_sp<SkImage> image) final;
+ void NotifyResourceLost() override {
+ // Used for single buffering mode which doesn't need to care about sync
+ // token synchronization.
+ }
scoped_refptr<StaticBitmapImage> Bitmap() override;
GLenum TextureTarget() const final { return GL_TEXTURE_2D; }
- GLuint GetBackingTextureHandleForOverwrite() final {
+ GLuint GetBackingTextureHandleForOverwrite() {
return back_buffer_texture_id_;
}
void PresentSwapChain();
+ const gpu::Mailbox& GetOrCreateGpuMailbox(MailboxSyncMode) override;
private:
void TearDown() override;
bool IsOverlayCandidate() const final { return true; }
- const gpu::Mailbox& GetOrCreateGpuMailbox(MailboxSyncMode) override;
bool HasGpuMailbox() const override;
const gpu::SyncToken GetSyncToken() override;
base::WeakPtr<WebGraphicsContext3DProviderWrapper> ContextProviderWrapper()
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 48e1f492be5..2e0040edaca 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
@@ -14,8 +14,8 @@
#include "components/viz/common/resources/single_release_callback.h"
#include "services/viz/public/mojom/compositing/frame_timing_details.mojom-blink.h"
#include "services/viz/public/mojom/hit_test/hit_test_region_list.mojom-blink.h"
+#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/frame_sinks/embedded_frame_sink.mojom-blink.h"
-#include "third_party/blink/public/platform/interface_provider.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/platform/graphics/canvas_resource.h"
@@ -69,7 +69,7 @@ CanvasResourceDispatcher::CanvasResourceDispatcher(
DCHECK(!sink_.is_bound());
mojo::Remote<mojom::blink::EmbeddedFrameSinkProvider> provider;
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
provider.BindNewPipeAndPassReceiver());
DCHECK(provider);
@@ -216,8 +216,7 @@ bool CanvasResourceDispatcher::PrepareFrame(
// TODO(crbug.com/652931): update the device_scale_factor
frame->metadata.device_scale_factor = 1.0f;
- if (current_begin_frame_ack_.sequence_number ==
- viz::BeginFrameArgs::kInvalidFrameNumber) {
+ if (!current_begin_frame_ack_.frame_id.IsSequenceValid()) {
// TODO(eseckler): This shouldn't be necessary when OffscreenCanvas no
// longer submits CompositorFrames without prior BeginFrame.
current_begin_frame_ack_ = viz::BeginFrameAck::CreateManualAckWithDamage();
@@ -353,7 +352,7 @@ void CanvasResourceDispatcher::OnBeginFrame(
}
// TODO(fserb): Update this with the correct value if we are on RAF submit.
- current_begin_frame_ack_.sequence_number =
+ current_begin_frame_ack_.frame_id.sequence_number =
viz::BeginFrameArgs::kInvalidFrameNumber;
}
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 9a6ac41b2fb..b2b6d55dbc0 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
@@ -15,6 +15,8 @@
#include "mojo/public/cpp/bindings/remote.h"
#include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom-blink.h"
#include "third_party/blink/public/mojom/frame_sinks/embedded_frame_sink.mojom-blink.h"
+#include "third_party/blink/renderer/platform/geometry/int_size.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_host.cc b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_host.cc
index f7c20310f27..d63606224c1 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_host.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_host.cc
@@ -19,6 +19,18 @@ CanvasResourceHost::ReplaceResourceProvider(
std::move(resource_provider_);
resource_provider_ = std::move(new_resource_provider);
UpdateMemoryUsage();
+ if (resource_provider_) {
+ resource_provider_->Canvas()->restoreToCount(1);
+ InitializeForRecording(resource_provider_->Canvas());
+ // Using unretained here since CanvasResourceHost owns |resource_provider_|
+ // and is guaranteed to outlive it
+ resource_provider_->SetRestoreClipStackCallback(base::BindRepeating(
+ &CanvasResourceHost::InitializeForRecording, base::Unretained(this)));
+ }
+ if (old_resource_provider) {
+ old_resource_provider->SetRestoreClipStackCallback(
+ CanvasResourceProvider::RestoreMatrixClipStackCb());
+ }
return old_resource_provider;
}
@@ -27,4 +39,9 @@ void CanvasResourceHost::DiscardResourceProvider() {
UpdateMemoryUsage();
}
+void CanvasResourceHost::InitializeForRecording(cc::PaintCanvas* canvas) {
+ canvas->save();
+ RestoreCanvasMatrixClipStack(canvas);
+}
+
} // namespace blink
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 9c1e69a63b4..16dbe14e169 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
@@ -43,6 +43,8 @@ class PLATFORM_EXPORT CanvasResourceHost {
virtual bool IsPrinting() const { return false; }
private:
+ void InitializeForRecording(cc::PaintCanvas* canvas);
+
std::unique_ptr<CanvasResourceProvider> resource_provider_;
};
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 5ae4615f80f..7955722efa4 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
@@ -9,21 +9,66 @@
#include "base/stl_util.h"
#include "build/build_config.h"
#include "cc/paint/decode_stashing_image_provider.h"
+#include "cc/paint/display_item_list.h"
#include "cc/tiles/software_image_decode_cache.h"
#include "components/viz/common/resources/resource_format_utils.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/raster_interface.h"
#include "gpu/command_buffer/common/capabilities.h"
+#include "gpu/command_buffer/common/shared_image_usage.h"
#include "gpu/config/gpu_driver_bug_workaround_type.h"
#include "gpu/config/gpu_feature_info.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h"
-#include "third_party/blink/renderer/platform/graphics/canvas_heuristic_parameters.h"
#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/skia/include/core/SkSurface.h"
namespace blink {
+namespace {
+
+bool IsGMBAllowed(IntSize size,
+ const CanvasColorParams& color_params,
+ const gpu::Capabilities& caps) {
+ return gpu::IsImageSizeValidForGpuMemoryBufferFormat(
+ gfx::Size(size), color_params.GetBufferFormat()) &&
+ gpu::IsImageFromGpuMemoryBufferFormatSupported(
+ color_params.GetBufferFormat(), caps);
+}
+
+} // namespace
+
+class CanvasResourceProvider::CanvasImageProvider : public cc::ImageProvider {
+ public:
+ CanvasImageProvider(cc::ImageDecodeCache* cache_n32,
+ cc::ImageDecodeCache* cache_f16,
+ const gfx::ColorSpace& target_color_space,
+ SkColorType target_color_type,
+ bool is_hardware_decode_cache);
+ ~CanvasImageProvider() override = default;
+
+ // cc::ImageProvider implementation.
+ cc::ImageProvider::ScopedResult GetRasterContent(
+ const cc::DrawImage&) override;
+
+ void ReleaseLockedImages() { locked_images_.clear(); }
+
+ private:
+ void CanUnlockImage(ScopedResult);
+ void CleanupLockedImages();
+
+ 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_f16_;
+
+ base::WeakPtrFactory<CanvasImageProvider> weak_factory_{this};
+
+ DISALLOW_COPY_AND_ASSIGN(CanvasImageProvider);
+};
// * Renders to a Skia RAM-backed bitmap.
// * Mailboxing is not supported : cannot be directly composited.
@@ -33,16 +78,14 @@ class CanvasResourceProviderBitmap : public CanvasResourceProvider {
const IntSize& size,
SkFilterQuality filter_quality,
const CanvasColorParams& color_params,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper>
- context_provider_wrapper,
base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher)
: CanvasResourceProvider(kBitmap,
size,
- /*msaa_sample_count=*/0,
+ 0 /*msaa_sample_count*/,
filter_quality,
color_params,
- /*is_origin_top_left=*/true,
- std::move(context_provider_wrapper),
+ true /*is_origin_top_left*/,
+ nullptr /*context_provider_wrapper*/,
std::move(resource_dispatcher)) {}
~CanvasResourceProviderBitmap() override = default;
@@ -56,9 +99,10 @@ class CanvasResourceProviderBitmap : public CanvasResourceProvider {
return nullptr; // Does not support direct compositing
}
- scoped_refptr<StaticBitmapImage> Snapshot() override {
+ scoped_refptr<StaticBitmapImage> Snapshot(
+ const ImageOrientation& orientation) override {
TRACE_EVENT0("blink", "CanvasResourceProviderBitmap::Snapshot");
- return SnapshotInternal();
+ return SnapshotInternal(orientation);
}
sk_sp<SkSurface> CreateSkSurface() const override {
@@ -83,7 +127,6 @@ class CanvasResourceProviderSharedBitmap : public CanvasResourceProviderBitmap {
: CanvasResourceProviderBitmap(size,
filter_quality,
color_params,
- nullptr, // context_provider_wrapper
std::move(resource_dispatcher)) {
DCHECK(ResourceDispatcher());
type_ = kSharedBitmap;
@@ -97,7 +140,8 @@ class CanvasResourceProviderSharedBitmap : public CanvasResourceProviderBitmap {
if (!IsBitmapFormatSupported(color_params.TransferableResourceFormat())) {
// If the rendering format is not supported, downgrate to 8-bits.
// TODO(junov): Should we try 12-12-12-12 and 10-10-10-2?
- color_params.SetCanvasPixelFormat(CanvasPixelFormat::kRGBA8);
+ color_params.SetCanvasPixelFormat(
+ CanvasColorParams::GetNativeCanvasPixelFormat());
}
return CanvasResourceSharedBitmap::Create(Size(), color_params,
@@ -134,9 +178,8 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
context_provider_wrapper,
base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher,
bool is_origin_top_left,
- bool is_overlay_candidate,
- bool maybe_single_buffered,
- bool is_accelerated)
+ bool is_accelerated,
+ uint32_t shared_image_usage_flags)
: CanvasResourceProvider(
kSharedImage,
size,
@@ -145,16 +188,20 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
// TODO(khushalsagar): The software path seems to be assuming N32
// somewhere in the later pipeline but for offscreen canvas only.
CanvasColorParams(color_params.ColorSpace(),
- color_params.PixelFormat(),
- color_params.GetOpacityMode(),
- is_accelerated ? CanvasForceRGBA::kForced
- : CanvasForceRGBA::kNotForced),
+ is_accelerated && color_params.PixelFormat() !=
+ CanvasPixelFormat::kF16
+ ? CanvasPixelFormat::kRGBA8
+ : color_params.PixelFormat(),
+ color_params.GetOpacityMode()),
is_origin_top_left,
std::move(context_provider_wrapper),
std::move(resource_dispatcher)),
- is_overlay_candidate_(is_overlay_candidate),
- maybe_single_buffered_(maybe_single_buffered),
- is_accelerated_(is_accelerated) {
+ is_accelerated_(is_accelerated),
+ shared_image_usage_flags_(shared_image_usage_flags),
+ use_oop_rasterization_(ContextProviderWrapper()
+ ->ContextProvider()
+ ->GetCapabilities()
+ .supports_oop_raster) {
resource_ = NewOrRecycledResource();
if (resource_)
EnsureWriteAccess();
@@ -162,24 +209,32 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
~CanvasResourceProviderSharedImage() override {}
- bool IsValid() const final { return GetSkSurface() && !IsGpuContextLost(); }
bool IsAccelerated() const final { return is_accelerated_; }
bool SupportsDirectCompositing() const override { return true; }
+ bool IsValid() const final {
+ if (use_oop_rasterization_)
+ return !IsGpuContextLost();
+ else
+ return GetSkSurface() && !IsGpuContextLost();
+ }
+
bool SupportsSingleBuffering() const override {
- return maybe_single_buffered_;
+ return shared_image_usage_flags_ &
+ gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE;
}
- GLuint GetBackingTextureHandleForOverwrite() override {
+ gpu::Mailbox GetBackingMailboxForOverwrite(
+ MailboxSyncMode sync_mode) override {
DCHECK(is_accelerated_);
if (IsGpuContextLost())
- return 0u;
+ return gpu::Mailbox();
- FlushGrContext();
- WillDraw();
- return resource()->GetTextureIdForWriteAccess();
+ WillDrawInternal(false);
+ return resource_->GetOrCreateGpuMailbox(sync_mode);
}
+
GLenum GetBackingTextureTarget() const override {
- return resource_->TextureTarget();
+ return resource()->TextureTarget();
}
scoped_refptr<CanvasResource> CreateResource() final {
@@ -187,15 +242,14 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
if (IsGpuContextLost())
return nullptr;
- bool allow_concurrent_read_write_access = maybe_single_buffered_;
return CanvasResourceSharedImage::Create(
Size(), ContextProviderWrapper(), CreateWeakPtr(), FilterQuality(),
- ColorParams(), is_overlay_candidate_, IsOriginTopLeft(),
- allow_concurrent_read_write_access, is_accelerated_);
+ ColorParams(), IsOriginTopLeft(), is_accelerated_,
+ shared_image_usage_flags_);
}
void NotifyTexParamsModified(const CanvasResource* resource) override {
- if (!is_accelerated_)
+ if (!is_accelerated_ || use_oop_rasterization_)
return;
if (resource_.get() == resource) {
@@ -215,6 +269,7 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
if (IsGpuContextLost())
return nullptr;
+ FlushCanvas();
// Its important to end read access and ref the resource before the WillDraw
// call below. Since it relies on resource ref-count to trigger
// copy-on-write and asserts that we only have write access when the
@@ -237,7 +292,8 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
return resource;
}
- scoped_refptr<StaticBitmapImage> Snapshot() override {
+ scoped_refptr<StaticBitmapImage> Snapshot(
+ const ImageOrientation& orientation) override {
TRACE_EVENT0("blink", "CanvasResourceProviderSharedImage::Snapshot");
if (!IsValid())
return nullptr;
@@ -246,9 +302,10 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
// rendering results visible on the GpuMemoryBuffer while we return cpu
// memory, rendererd to by skia, here.
if (!is_accelerated_)
- return SnapshotInternal();
+ return SnapshotInternal(orientation);
if (!cached_snapshot_) {
+ FlushCanvas();
EndWriteAccess();
cached_snapshot_ = resource_->Bitmap();
}
@@ -258,7 +315,7 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
return cached_snapshot_;
}
- void WillDraw() override {
+ void WillDrawInternal(bool write_to_local_texture) {
DCHECK(resource_);
if (IsGpuContextLost())
@@ -293,9 +350,11 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
old_resource_shared_image->GetTextureIdForReadAccess(),
GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM);
}
+ UMA_HISTOGRAM_BOOLEAN("Blink.Canvas.ContentChangeMode",
+ mode_ == SkSurface::kRetain_ContentChangeMode);
surface_->replaceBackendTexture(CreateGrTextureForResource(),
- GetGrSurfaceOrigin());
- surface_->flush();
+ GetGrSurfaceOrigin(), mode_);
+ mode_ = SkSurface::kRetain_ContentChangeMode;
if (!old_resource_shared_image->has_read_access()) {
RasterInterface()->EndSharedImageAccessDirectCHROMIUM(
old_resource_shared_image->GetTextureIdForReadAccess());
@@ -303,10 +362,55 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
}
}
- EnsureWriteAccess();
+ if (write_to_local_texture)
+ EnsureWriteAccess();
+ else
+ EndWriteAccess();
+
resource()->WillDraw();
}
+ void WillDraw() override { WillDrawInternal(true); }
+
+ void RasterRecord(sk_sp<cc::PaintRecord> last_recording) override {
+ if (!use_oop_rasterization_) {
+ CanvasResourceProvider::RasterRecord(std::move(last_recording));
+ return;
+ }
+ gpu::raster::RasterInterface* ri = RasterInterface();
+ SkColor background_color = ColorParams().GetOpacityMode() == kOpaque
+ ? SK_ColorBLACK
+ : SK_ColorTRANSPARENT;
+
+ auto list = base::MakeRefCounted<cc::DisplayItemList>(
+ cc::DisplayItemList::kTopLevelDisplayItemList);
+
+ list->StartPaint();
+ list->push<cc::DrawRecordOp>(std::move(last_recording));
+ list->EndPaintOfUnpaired(gfx::Rect(Size().Width(), Size().Height()));
+ list->Finalize();
+
+ gfx::Size size(Size().Width(), Size().Height());
+ size_t max_op_size_hint =
+ gpu::raster::RasterInterface::kDefaultMaxOpSizeHint;
+ bool use_lcd = false;
+ gfx::Rect full_raster_rect(Size().Width(), Size().Height());
+ gfx::Rect playback_rect(Size().Width(), Size().Height());
+ gfx::Vector2dF post_translate(0.f, 0.f);
+
+ ri->BeginRasterCHROMIUM(
+ background_color, GetMSAASampleCount(), use_lcd,
+ ColorParams().GetStorageGfxColorSpace(),
+ resource()->GetOrCreateGpuMailbox(kUnverifiedSyncToken).name);
+
+ ri->RasterCHROMIUM(list.get(), GetOrCreateCanvasImageProvider(), size,
+ full_raster_rect, playback_rect, post_translate,
+ 1.f /* post_scale */, false /* requires_clear */,
+ &max_op_size_hint);
+
+ ri->EndRasterCHROMIUM();
+ }
+
bool DoCopyOnWrite() {
// If the canvas is single buffered, concurrent read/writes to the resource
// are allowed. Note that we ignore the resource lost case as well since
@@ -358,7 +462,7 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
GrGLTextureInfo texture_info = {};
texture_info.fID = resource()->GetTextureIdForWriteAccess();
- texture_info.fTarget = resource_->TextureTarget();
+ texture_info.fTarget = resource()->TextureTarget();
texture_info.fFormat = ColorParams().GLSizedInternalFormat();
return GrBackendTexture(Size().Width(), Size().Height(), GrMipMapped::kNo,
texture_info);
@@ -389,7 +493,8 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
DCHECK(!resource()->is_cross_thread())
<< "Write access is only allowed on the owning thread";
- if (current_resource_has_write_access_ || IsGpuContextLost())
+ if (current_resource_has_write_access_ || IsGpuContextLost() ||
+ use_oop_rasterization_)
return;
if (is_accelerated_) {
@@ -410,7 +515,13 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
if (!current_resource_has_write_access_ || IsGpuContextLost())
return;
+ DCHECK(!use_oop_rasterization_);
+
if (is_accelerated_) {
+ // We reset |mode_| here since the draw commands which overwrite the
+ // complete canvas must have been flushed at this point without triggering
+ // copy-on-write.
+ mode_ = SkSurface::kRetain_ContentChangeMode;
// Issue any skia work using this resource before releasing write access.
FlushGrContext();
auto texture_id = resource()->GetTextureIdForWriteAccess();
@@ -432,10 +543,10 @@ class CanvasResourceProviderSharedImage : public CanvasResourceProvider {
return static_cast<const CanvasResourceSharedImage*>(resource_.get());
}
- const bool is_overlay_candidate_;
- const bool maybe_single_buffered_;
const bool is_accelerated_;
+ const uint32_t shared_image_usage_flags_;
bool current_resource_has_write_access_ = false;
+ const bool use_oop_rasterization_;
scoped_refptr<CanvasResource> resource_;
scoped_refptr<StaticBitmapImage> cached_snapshot_;
};
@@ -486,7 +597,7 @@ class CanvasResourceProviderPassThrough final : public CanvasResourceProvider {
return nullptr;
}
- scoped_refptr<StaticBitmapImage> Snapshot() override {
+ scoped_refptr<StaticBitmapImage> Snapshot(const ImageOrientation&) override {
auto resource = GetImportedResource();
if (IsGpuContextLost() || !resource)
return nullptr;
@@ -513,7 +624,7 @@ class CanvasResourceProviderSwapChain final : public CanvasResourceProvider {
msaa_sample_count,
filter_quality,
color_params,
- /*is_origin_top_left=*/true,
+ true /*is_origin_top_left*/,
std::move(context_provider_wrapper),
std::move(resource_dispatcher)),
msaa_sample_count_(msaa_sample_count) {
@@ -542,15 +653,15 @@ class CanvasResourceProviderSwapChain final : public CanvasResourceProvider {
"CanvasResourceProviderSwapChain::ProduceCanvasResource");
if (!IsValid())
return nullptr;
+ FlushCanvas();
if (dirty_) {
- FlushSkia();
resource_->PresentSwapChain();
dirty_ = false;
}
return resource_;
}
- scoped_refptr<StaticBitmapImage> Snapshot() override {
+ scoped_refptr<StaticBitmapImage> Snapshot(const ImageOrientation&) override {
TRACE_EVENT0("blink", "CanvasResourceProviderSwapChain::Snapshot");
// Use ProduceCanvasResource to ensure any queued commands are flushed and
@@ -598,15 +709,6 @@ enum class CanvasResourceType {
const Vector<CanvasResourceType>& GetResourceTypeFallbackList(
CanvasResourceProvider::ResourceUsage usage) {
- static const Vector<CanvasResourceType> kSoftwareFallbackList({
- CanvasResourceType::kBitmap,
- });
-
- static const Vector<CanvasResourceType> kAcceleratedFallbackList({
- CanvasResourceType::kSharedImage,
- // Fallback to software
- CanvasResourceType::kBitmap,
- });
static const Vector<CanvasResourceType> kCompositedFallbackList({
CanvasResourceType::kSharedImage,
@@ -644,14 +746,16 @@ const Vector<CanvasResourceType>& GetResourceTypeFallbackList(
kCompositedFallbackList.begin(),
kCompositedFallbackList.end()));
+ static const Vector<CanvasResourceType> kEmptyList;
switch (usage) {
+ case CanvasResourceProvider::ResourceUsage::kAcceleratedResourceUsage:
case CanvasResourceProvider::ResourceUsage::kSoftwareResourceUsage:
- return kSoftwareFallbackList;
+ NOTREACHED();
+ return kEmptyList;
case CanvasResourceProvider::ResourceUsage::
kSoftwareCompositedResourceUsage:
return kCompositedFallbackList;
- case CanvasResourceProvider::ResourceUsage::kAcceleratedResourceUsage:
- return kAcceleratedFallbackList;
+
case CanvasResourceProvider::ResourceUsage::
kAcceleratedCompositedResourceUsage:
return kCompositedFallbackList;
@@ -663,39 +767,15 @@ const Vector<CanvasResourceType>& GetResourceTypeFallbackList(
return kAcceleratedDirect3DFallbackList;
case CanvasResourceProvider::ResourceUsage::
kSoftwareCompositedDirect2DResourceUsage:
- return kCompositedFallbackList;
+ NOTREACHED();
+ return kEmptyList;
}
NOTREACHED();
+ return kEmptyList;
}
} // unnamed namespace
-std::unique_ptr<CanvasResourceProvider> CanvasResourceProvider::CreateForCanvas(
- 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) {
- base::UmaHistogramEnumeration("Blink.Canvas.ResourceProviderUsage", usage);
-
- std::unique_ptr<CanvasResourceProvider> provider = Create(
- size, usage, context_provider_wrapper, msaa_sample_count, filter_quality,
- color_params, presentation_mode, resource_dispatcher, is_origin_top_left);
-
- if (provider && provider->IsValid()) {
- base::UmaHistogramBoolean("Blink.Canvas.ResourceProviderIsAccelerated",
- provider->IsAccelerated());
- base::UmaHistogramEnumeration("Blink.Canvas.ResourceProviderType",
- provider->type_);
- }
-
- return provider;
-}
-
std::unique_ptr<CanvasResourceProvider> CanvasResourceProvider::Create(
const IntSize& size,
ResourceUsage usage,
@@ -706,6 +786,9 @@ std::unique_ptr<CanvasResourceProvider> CanvasResourceProvider::Create(
uint8_t presentation_mode,
base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher,
bool is_origin_top_left) {
+ DCHECK_EQ(msaa_sample_count, 0u);
+ DCHECK(usage != ResourceUsage::kSoftwareResourceUsage);
+
std::unique_ptr<CanvasResourceProvider> provider;
bool is_gpu_memory_buffer_image_allowed = false;
@@ -718,15 +801,12 @@ std::unique_ptr<CanvasResourceProvider> CanvasResourceProvider::Create(
const int max_texture_size = context_capabilities.max_texture_size;
if (size.Width() > max_texture_size || size.Height() > max_texture_size)
- usage = ResourceUsage::kSoftwareResourceUsage;
+ return CreateBitmapProvider(size, filter_quality, color_params);
is_gpu_memory_buffer_image_allowed =
(presentation_mode & kAllowImageChromiumPresentationMode) &&
Platform::Current()->GetGpuMemoryBufferManager() &&
- gpu::IsImageSizeValidForGpuMemoryBufferFormat(
- gfx::Size(size), color_params.GetBufferFormat()) &&
- gpu::IsImageFromGpuMemoryBufferFormatSupported(
- color_params.GetBufferFormat(), context_capabilities);
+ IsGMBAllowed(size, color_params, context_capabilities);
is_swap_chain_allowed =
(presentation_mode & kAllowSwapChainPresentationMode) &&
@@ -764,54 +844,57 @@ std::unique_ptr<CanvasResourceProvider> CanvasResourceProvider::Create(
break;
case CanvasResourceType::kBitmap:
provider = std::make_unique<CanvasResourceProviderBitmap>(
- size, filter_quality, color_params, context_provider_wrapper,
- resource_dispatcher);
+ size, filter_quality, color_params, resource_dispatcher);
break;
case CanvasResourceType::kSharedImage: {
- DCHECK_NE(usage, ResourceUsage::kSoftwareResourceUsage);
-
if (!context_provider_wrapper)
continue;
- const bool is_accelerated =
- usage == ResourceUsage::kAcceleratedResourceUsage ||
- usage == ResourceUsage::kAcceleratedCompositedResourceUsage ||
- usage == ResourceUsage::kAcceleratedDirect2DResourceUsage ||
- usage == ResourceUsage::kAcceleratedDirect3DResourceUsage;
-
- // If the rendering will be in software and we don't have GMB support,
- // fallback to bitmap provider type.
- if (!is_accelerated && !is_gpu_memory_buffer_image_allowed)
- continue;
-
- // texture_storage_image is required to create shared images supporting
- // scanout usage.
const bool can_use_overlays =
is_gpu_memory_buffer_image_allowed &&
context_provider_wrapper->ContextProvider()
->GetCapabilities()
.texture_storage_image;
- const bool is_overlay_candidate =
- (usage == ResourceUsage::kAcceleratedDirect2DResourceUsage ||
- usage == ResourceUsage::kAcceleratedDirect3DResourceUsage ||
- usage == ResourceUsage::kAcceleratedCompositedResourceUsage ||
- usage == ResourceUsage::kSoftwareCompositedResourceUsage) &&
- can_use_overlays;
-
- // Single buffering requires concurrent read/write access to the
- // resource which is sub-optimal for software raster since that would
- // require concurrent access to the resource on the CPU and GPU, so
- // enable it for accelerated low latency canvas only.
- const bool maybe_single_buffered =
- (usage == ResourceUsage::kAcceleratedDirect2DResourceUsage ||
- usage == ResourceUsage::kAcceleratedDirect3DResourceUsage) &&
- is_gpu_memory_buffer_image_allowed;
+ 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_overlay_candidate, maybe_single_buffered, is_accelerated);
+ is_accelerated, shared_image_usage_flags);
} break;
}
if (!provider->IsValid())
@@ -822,35 +905,53 @@ std::unique_ptr<CanvasResourceProvider> CanvasResourceProvider::Create(
return nullptr;
}
-class CanvasResourceProvider::CanvasImageProvider : public cc::ImageProvider {
- public:
- CanvasImageProvider(cc::ImageDecodeCache* cache_n32,
- cc::ImageDecodeCache* cache_f16,
- const gfx::ColorSpace& target_color_space,
- SkColorType target_color_type,
- bool is_hardware_decode_cache);
- ~CanvasImageProvider() override = default;
-
- // cc::ImageProvider implementation.
- cc::ImageProvider::ScopedResult GetRasterContent(
- const cc::DrawImage&) override;
+std::unique_ptr<CanvasResourceProvider>
+CanvasResourceProvider::CreateBitmapProvider(
+ const IntSize& size,
+ SkFilterQuality filter_quality,
+ const CanvasColorParams& color_params) {
+ auto provider = std::make_unique<CanvasResourceProviderBitmap>(
+ size, filter_quality, color_params, nullptr /*resource_dispatcher*/);
+ if (provider->IsValid())
+ return provider;
- void ReleaseLockedImages() { locked_images_.clear(); }
+ return nullptr;
+}
- private:
- void CanUnlockImage(ScopedResult);
- void CleanupLockedImages();
+std::unique_ptr<CanvasResourceProvider>
+CanvasResourceProvider::CreateSharedImageProvider(
+ const IntSize& size,
+ base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper,
+ SkFilterQuality filter_quality,
+ const CanvasColorParams& color_params,
+ bool is_origin_top_left,
+ RasterMode raster_mode,
+ uint32_t shared_image_usage_flags) {
+ if (!context_provider_wrapper)
+ return nullptr;
- 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_f16_;
+ const auto& caps =
+ context_provider_wrapper->ContextProvider()->GetCapabilities();
+ if (size.Width() > caps.max_texture_size ||
+ size.Height() > caps.max_texture_size) {
+ return nullptr;
+ }
- base::WeakPtrFactory<CanvasImageProvider> weak_factory_{this};
+ bool can_use_overlays =
+ IsGMBAllowed(size, color_params, caps) && caps.texture_storage_image;
+ if (!can_use_overlays)
+ shared_image_usage_flags &= ~gpu::SHARED_IMAGE_USAGE_SCANOUT;
+
+ auto provider = std::make_unique<CanvasResourceProviderSharedImage>(
+ size, 0 /* msaa_sample_count */, filter_quality, color_params,
+ context_provider_wrapper, nullptr /*resource_dispatcher*/,
+ is_origin_top_left, raster_mode == RasterMode::kGPU,
+ shared_image_usage_flags);
+ if (provider->IsValid())
+ return provider;
- DISALLOW_COPY_AND_ASSIGN(CanvasImageProvider);
-};
+ return nullptr;
+}
CanvasResourceProvider::CanvasImageProvider::CanvasImageProvider(
cc::ImageDecodeCache* cache_n32,
@@ -962,6 +1063,8 @@ CanvasResourceProvider::CanvasResourceProvider(
}
CanvasResourceProvider::~CanvasResourceProvider() {
+ UMA_HISTOGRAM_EXACT_LINEAR("Blink.Canvas.MaximumInflightResources",
+ max_inflight_resources_, 20);
if (context_provider_wrapper_)
context_provider_wrapper_->RemoveObserver(this);
}
@@ -972,52 +1075,57 @@ SkSurface* CanvasResourceProvider::GetSkSurface() const {
return surface_.get();
}
-void CanvasResourceProvider::InitializePaintCanvas() {
- // Since canvas_ has a reference to canvas_image_provider_, canvas must be
- // deleted before the image_provider.
- canvas_ = nullptr;
- canvas_image_provider_ = nullptr;
-
- // Create an ImageDecodeCache for half float images only if the canvas is
- // using half float back storage.
- cc::ImageDecodeCache* cache_f16 = nullptr;
- if (ColorParams().GetSkColorType() == kRGBA_F16_SkColorType)
- cache_f16 = ImageDecodeCacheF16();
- canvas_image_provider_ = std::make_unique<CanvasImageProvider>(
- ImageDecodeCacheRGBA8(), cache_f16, gfx::ColorSpace::CreateSRGB(),
- color_params_.GetSkColorType(), use_hardware_decode_cache());
+void CanvasResourceProvider::EnsureSkiaCanvas() {
+ WillDraw();
+
+ if (skia_canvas_)
+ return;
cc::SkiaPaintCanvas::ContextFlushes context_flushes;
- if (IsAccelerated() &&
+ if (IsAccelerated() && ContextProviderWrapper() &&
!ContextProviderWrapper()
->ContextProvider()
->GetGpuFeatureInfo()
.IsWorkaroundEnabled(gpu::DISABLE_2D_CANVAS_AUTO_FLUSH)) {
- context_flushes.enable =
- canvas_heuristic_parameters::kEnableGrContextFlushes;
- context_flushes.max_draws_before_flush =
- canvas_heuristic_parameters::kMaxDrawsBeforeContextFlush;
+ context_flushes.enable = true;
+ context_flushes.max_draws_before_flush = kMaxDrawsBeforeContextFlush;
}
- canvas_ = std::make_unique<cc::SkiaPaintCanvas>(GetSkSurface()->getCanvas(),
- canvas_image_provider_.get(),
- context_flushes);
+ skia_canvas_ = std::make_unique<cc::SkiaPaintCanvas>(
+ GetSkSurface()->getCanvas(), GetOrCreateCanvasImageProvider(),
+ context_flushes);
+}
+
+CanvasResourceProvider::CanvasImageProvider*
+CanvasResourceProvider::GetOrCreateCanvasImageProvider() {
+ if (!canvas_image_provider_) {
+ // Create an ImageDecodeCache for half float images only if the canvas is
+ // using half float back storage.
+ cc::ImageDecodeCache* cache_f16 = nullptr;
+ if (ColorParams().GetSkColorType() == kRGBA_F16_SkColorType)
+ cache_f16 = ImageDecodeCacheF16();
+ canvas_image_provider_ = std::make_unique<CanvasImageProvider>(
+ ImageDecodeCacheRGBA8(), cache_f16, gfx::ColorSpace::CreateSRGB(),
+ color_params_.GetSkColorType(), use_hardware_decode_cache());
+ }
+ return canvas_image_provider_.get();
}
cc::PaintCanvas* CanvasResourceProvider::Canvas() {
- WillDraw();
+ if (!recorder_) {
+ // A raw pointer is safe here because the callback is only used by the
+ // |recorder_|.
+ recorder_ = std::make_unique<MemoryManagedPaintRecorder>(WTF::BindRepeating(
+ &CanvasResourceProvider::SetNeedsFlush, WTF::Unretained(this)));
- if (!canvas_) {
- TRACE_EVENT0("blink", "CanvasResourceProvider::Canvas");
- DCHECK(!canvas_image_provider_);
- InitializePaintCanvas();
+ return recorder_->beginRecording(Size().Width(), Size().Height());
}
- return canvas_.get();
+ return recorder_->getRecordingCanvas();
}
void CanvasResourceProvider::OnContextDestroyed() {
if (canvas_image_provider_) {
- DCHECK(canvas_);
- canvas_->reset_image_provider();
+ DCHECK(skia_canvas_);
+ skia_canvas_->reset_image_provider();
canvas_image_provider_.reset();
}
}
@@ -1027,16 +1135,19 @@ void CanvasResourceProvider::ReleaseLockedImages() {
canvas_image_provider_->ReleaseLockedImages();
}
-scoped_refptr<StaticBitmapImage> CanvasResourceProvider::SnapshotInternal() {
+scoped_refptr<StaticBitmapImage> CanvasResourceProvider::SnapshotInternal(
+ const ImageOrientation& orientation) {
if (!IsValid())
return nullptr;
auto paint_image = MakeImageSnapshot();
DCHECK(!paint_image.GetSkImage()->isTextureBacked());
- return UnacceleratedStaticBitmapImage::Create(std::move(paint_image));
+ return UnacceleratedStaticBitmapImage::Create(std::move(paint_image),
+ orientation);
}
cc::PaintImage CanvasResourceProvider::MakeImageSnapshot() {
+ FlushCanvas();
auto sk_image = GetSkSurface()->makeImageSnapshot();
if (!sk_image)
return cc::PaintImage();
@@ -1076,7 +1187,23 @@ GrContext* CanvasResourceProvider::GetGrContext() const {
return context_provider_wrapper_->ContextProvider()->GetGrContext();
}
-void CanvasResourceProvider::FlushSkia() const {
+sk_sp<cc::PaintRecord> CanvasResourceProvider::FlushCanvas() {
+ if (!HasRecordedDrawOps())
+ return nullptr;
+ sk_sp<cc::PaintRecord> last_recording = recorder_->finishRecordingAsPicture();
+ RasterRecord(last_recording);
+ needs_flush_ = false;
+ cc::PaintCanvas* canvas =
+ recorder_->beginRecording(Size().Width(), Size().Height());
+ if (restore_clip_stack_callback_)
+ restore_clip_stack_callback_.Run(canvas);
+ return last_recording;
+}
+
+void CanvasResourceProvider::RasterRecord(
+ sk_sp<cc::PaintRecord> last_recording) {
+ EnsureSkiaCanvas();
+ skia_canvas_->drawPicture(std::move(last_recording));
GetSkSurface()->flush();
}
@@ -1094,6 +1221,18 @@ bool CanvasResourceProvider::WritePixels(const SkImageInfo& orig_info,
TRACE_EVENT0("blink", "CanvasResourceProvider::WritePixels");
DCHECK(IsValid());
+ DCHECK(!HasRecordedDrawOps());
+
+ 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);
}
@@ -1142,7 +1281,7 @@ void CanvasResourceProvider::RecycleResource(
scoped_refptr<CanvasResource> resource) {
// We don't want to keep an arbitrary large number of canvases.
if (canvas_resources_.size() >
- canvas_heuristic_parameters::kMaxRecycledCanvasResources)
+ static_cast<unsigned int>(kMaxRecycledCanvasResources))
return;
// Need to check HasOneRef() because if there are outstanding references to
@@ -1163,9 +1302,17 @@ void CanvasResourceProvider::ClearRecycledResources() {
canvas_resources_.clear();
}
+void CanvasResourceProvider::OnDestroyResource() {
+ --num_inflight_resources_;
+}
+
scoped_refptr<CanvasResource> CanvasResourceProvider::NewOrRecycledResource() {
- if (canvas_resources_.IsEmpty())
+ if (canvas_resources_.IsEmpty()) {
canvas_resources_.push_back(CreateResource());
+ ++num_inflight_resources_;
+ if (num_inflight_resources_ > max_inflight_resources_)
+ max_inflight_resources_ = num_inflight_resources_;
+ }
if (IsSingleBuffered()) {
DCHECK_EQ(canvas_resources_.size(), 1u);
@@ -1203,4 +1350,37 @@ scoped_refptr<CanvasResource> CanvasResourceProvider::GetImportedResource()
return canvas_resources_.back();
}
+void CanvasResourceProvider::SkipQueuedDrawCommands() {
+ // Note that this function only gets called when canvas needs a full repaint,
+ // so always update the |mode_| to discard the old copy of canvas content.
+ mode_ = SkSurface::kDiscard_ContentChangeMode;
+
+ if (!HasRecordedDrawOps())
+ return;
+ recorder_->finishRecordingAsPicture();
+ cc::PaintCanvas* canvas =
+ recorder_->beginRecording(Size().Width(), Size().Height());
+ if (restore_clip_stack_callback_)
+ restore_clip_stack_callback_.Run(canvas);
+}
+
+void CanvasResourceProvider::SetRestoreClipStackCallback(
+ RestoreMatrixClipStackCb callback) {
+ DCHECK(restore_clip_stack_callback_.is_null() || callback.is_null());
+ restore_clip_stack_callback_ = std::move(callback);
+}
+
+void CanvasResourceProvider::RestoreBackBuffer(const cc::PaintImage& image) {
+ DCHECK_EQ(image.height(), Size().Height());
+ DCHECK_EQ(image.width(), Size().Width());
+ EnsureSkiaCanvas();
+ cc::PaintFlags copy_paint;
+ copy_paint.setBlendMode(SkBlendMode::kSrc);
+ skia_canvas_->drawImage(image, 0, 0, &copy_paint);
+}
+
+bool CanvasResourceProvider::HasRecordedDrawOps() const {
+ return recorder_ && recorder_->ListHasDrawOps();
+}
+
} // 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 910b0e526c0..e88d3511299 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
@@ -8,6 +8,8 @@
#include "cc/paint/skia_paint_canvas.h"
#include "cc/raster/playback_image_provider.h"
#include "third_party/blink/renderer/platform/graphics/canvas_resource.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/skia/include/core/SkSurface.h"
class GrContext;
@@ -56,8 +58,9 @@ class PLATFORM_EXPORT CanvasResourceProvider
public:
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
+ // todo(juanmihd@) ResourceUsage will be removed soon, try avoiding using this
enum class ResourceUsage {
- kSoftwareResourceUsage = 0,
+ kSoftwareResourceUsage = 0, // deprecated
kSoftwareCompositedResourceUsage = 1,
kAcceleratedResourceUsage = 2,
kAcceleratedCompositedResourceUsage = 3,
@@ -92,19 +95,33 @@ class PLATFORM_EXPORT CanvasResourceProvider
kMaxValue = kSwapChain,
};
- void static RecordTypeToUMA(ResourceProviderType type);
+ using RestoreMatrixClipStackCb =
+ base::RepeatingCallback<void(cc::PaintCanvas*)>;
- static std::unique_ptr<CanvasResourceProvider> CreateForCanvas(
+ // todo(juanmihd@) Check whether SkFilterQuality is needed in all of this, or
+ // just call setFilterQuality explicitly
+ static std::unique_ptr<CanvasResourceProvider> CreateBitmapProvider(
+ const IntSize&,
+ SkFilterQuality,
+ const CanvasColorParams&);
+
+ // 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&,
- 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,
+ RasterMode raster_mode,
+ uint32_t shared_image_usage_flags);
+ // TODO(juanmihd): Clean up creation methods/usage. See crbug.com/1035589.
static std::unique_ptr<CanvasResourceProvider> Create(
const IntSize&,
ResourceUsage,
@@ -119,16 +136,18 @@ class PLATFORM_EXPORT CanvasResourceProvider
// Use Snapshot() for capturing a frame that is intended to be displayed via
// the compositor. Cases that are destined to be transferred via a
// TransferableResource should call ProduceCanvasResource() instead.
+ // The ImageOrientationEnum conveys the desired orientation of the image, and
+ // should be derived from the source of the bitmap data.
virtual scoped_refptr<CanvasResource> ProduceCanvasResource() = 0;
- virtual scoped_refptr<StaticBitmapImage> Snapshot() = 0;
+ virtual scoped_refptr<StaticBitmapImage> Snapshot(
+ const ImageOrientation& = kDefaultImageOrientation) = 0;
// WebGraphicsContext3DProvider::DestructionObserver implementation.
void OnContextDestroyed() override;
cc::PaintCanvas* Canvas();
- void InitializePaintCanvas();
void ReleaseLockedImages();
- void FlushSkia() const;
+ sk_sp<cc::PaintRecord> FlushCanvas();
const CanvasColorParams& ColorParams() const { return color_params_; }
void SetFilterQuality(SkFilterQuality quality) { filter_quality_ = quality; }
const IntSize& Size() const { return size_; }
@@ -172,9 +191,11 @@ class PLATFORM_EXPORT CanvasResourceProvider
size_t row_bytes,
int x,
int y);
- virtual GLuint GetBackingTextureHandleForOverwrite() {
+
+ virtual gpu::Mailbox GetBackingMailboxForOverwrite(
+ MailboxSyncMode sync_mode) {
NOTREACHED();
- return 0;
+ return gpu::Mailbox();
}
virtual GLenum GetBackingTextureTarget() const { return GL_TEXTURE_2D; }
virtual void* GetPixelBufferAddressForOverwrite() {
@@ -196,7 +217,19 @@ class PLATFORM_EXPORT CanvasResourceProvider
return canvas_resources_.size();
}
+ void SkipQueuedDrawCommands();
+ void SetRestoreClipStackCallback(RestoreMatrixClipStackCb);
+ bool needs_flush() const { return needs_flush_; }
+ void RestoreBackBuffer(const cc::PaintImage&);
+
+ ResourceProviderType GetType() const { return type_; }
+ bool HasRecordedDrawOps() const;
+
+ void OnDestroyResource();
+
protected:
+ class CanvasImageProvider;
+
gpu::gles2::GLES2Interface* ContextGL() const;
gpu::raster::RasterInterface* RasterInterface() const;
GrContext* GetGrContext() const;
@@ -209,7 +242,7 @@ class PLATFORM_EXPORT CanvasResourceProvider
: kBottomLeft_GrSurfaceOrigin;
}
SkFilterQuality FilterQuality() const { return filter_quality_; }
- scoped_refptr<StaticBitmapImage> SnapshotInternal();
+ scoped_refptr<StaticBitmapImage> SnapshotInternal(const ImageOrientation&);
scoped_refptr<CanvasResource> GetImportedResource() const;
CanvasResourceProvider(const ResourceProviderType&,
@@ -227,13 +260,14 @@ class PLATFORM_EXPORT CanvasResourceProvider
// decodes/uploads in the cache is invalidated only when the canvas contents
// change.
cc::PaintImage MakeImageSnapshot();
+ virtual void RasterRecord(sk_sp<cc::PaintRecord>);
+ CanvasImageProvider* GetOrCreateCanvasImageProvider();
ResourceProviderType type_;
mutable sk_sp<SkSurface> surface_; // mutable for lazy init
+ SkSurface::ContentChangeMode mode_ = SkSurface::kRetain_ContentChangeMode;
private:
- class CanvasImageProvider;
-
virtual sk_sp<SkSurface> CreateSkSurface() const = 0;
virtual scoped_refptr<CanvasResource> CreateResource();
bool use_hardware_decode_cache() const {
@@ -245,6 +279,8 @@ class PLATFORM_EXPORT CanvasResourceProvider
cc::ImageDecodeCache* ImageDecodeCacheRGBA8();
cc::ImageDecodeCache* ImageDecodeCacheF16();
+ void EnsureSkiaCanvas();
+ void SetNeedsFlush() { needs_flush_ = true; }
base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper_;
base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher_;
@@ -254,7 +290,10 @@ class PLATFORM_EXPORT CanvasResourceProvider
const CanvasColorParams color_params_;
const bool is_origin_top_left_;
std::unique_ptr<CanvasImageProvider> canvas_image_provider_;
- std::unique_ptr<cc::SkiaPaintCanvas> canvas_;
+ std::unique_ptr<cc::SkiaPaintCanvas> skia_canvas_;
+ std::unique_ptr<PaintRecorder> recorder_;
+
+ bool needs_flush_ = false;
const cc::PaintImage::Id snapshot_paint_image_id_;
cc::PaintImage::ContentId snapshot_paint_image_content_id_ =
@@ -267,6 +306,17 @@ class PLATFORM_EXPORT CanvasResourceProvider
bool resource_recycling_enabled_ = true;
bool is_single_buffered_ = false;
+ // The maximum number of in-flight resources waiting to be used for recycling.
+ static constexpr int kMaxRecycledCanvasResources = 2;
+ // The maximum number of draw ops executed on the canvas, after which the
+ // underlying GrContext is flushed.
+ static constexpr int kMaxDrawsBeforeContextFlush = 50;
+
+ size_t num_inflight_resources_ = 0;
+ size_t max_inflight_resources_ = 0;
+
+ RestoreMatrixClipStackCb restore_clip_stack_callback_;
+
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 85b64c72473..2924293e7bd 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
@@ -74,9 +74,9 @@ class CanvasResourceProviderTest : public Test {
TEST_F(CanvasResourceProviderTest, CanvasResourceProviderAcceleratedOverlay) {
const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
- CanvasPixelFormat::kRGBA8, kNonOpaque,
- CanvasForceRGBA::kNotForced);
+ const CanvasColorParams kColorParams(
+ CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
+ kNonOpaque);
auto provider = CanvasResourceProvider::Create(
kSize,
@@ -92,7 +92,9 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderAcceleratedOverlay) {
EXPECT_TRUE(provider->SupportsDirectCompositing());
EXPECT_TRUE(provider->SupportsSingleBuffering());
EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace());
- EXPECT_EQ(provider->ColorParams().PixelFormat(), kColorParams.PixelFormat());
+ // 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());
@@ -103,16 +105,14 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderAcceleratedOverlay) {
TEST_F(CanvasResourceProviderTest, CanvasResourceProviderTexture) {
const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
- CanvasPixelFormat::kRGBA8, kNonOpaque,
- CanvasForceRGBA::kNotForced);
+ const CanvasColorParams kColorParams(
+ CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
+ kNonOpaque);
- auto provider = CanvasResourceProvider::Create(
- kSize, CanvasResourceProvider::ResourceUsage::kAcceleratedResourceUsage,
- context_provider_wrapper_, 0 /* msaa_sample_count */,
- kLow_SkFilterQuality, kColorParams,
- CanvasResourceProvider::kDefaultPresentationMode,
- nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
+ auto provider = CanvasResourceProvider::CreateSharedImageProvider(
+ kSize, context_provider_wrapper_, kLow_SkFilterQuality, kColorParams,
+ true /*is_origin_top_left*/, CanvasResourceProvider::RasterMode::kGPU,
+ 0u /*shared_image_usage_flags*/);
EXPECT_EQ(provider->Size(), kSize);
EXPECT_TRUE(provider->IsValid());
@@ -120,7 +120,9 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderTexture) {
EXPECT_TRUE(provider->SupportsDirectCompositing());
EXPECT_FALSE(provider->SupportsSingleBuffering());
EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace());
- EXPECT_EQ(provider->ColorParams().PixelFormat(), kColorParams.PixelFormat());
+ // 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());
@@ -129,14 +131,13 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderTexture) {
TEST_F(CanvasResourceProviderTest, CanvasResourceProviderUnacceleratedOverlay) {
const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
- CanvasPixelFormat::kRGBA8, kNonOpaque,
- CanvasForceRGBA::kNotForced);
+ const CanvasColorParams kColorParams(
+ CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
+ kNonOpaque);
auto provider = CanvasResourceProvider::Create(
kSize,
- CanvasResourceProvider::ResourceUsage::
- kSoftwareCompositedDirect2DResourceUsage,
+ CanvasResourceProvider::ResourceUsage::kSoftwareCompositedResourceUsage,
context_provider_wrapper_, 0 /* msaa_sample_count */,
kLow_SkFilterQuality, kColorParams,
CanvasResourceProvider::kAllowImageChromiumPresentationMode,
@@ -161,9 +162,9 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderUnacceleratedOverlay) {
TEST_F(CanvasResourceProviderTest,
CanvasResourceProviderSharedImageResourceRecycling) {
const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
- CanvasPixelFormat::kRGBA8, kNonOpaque,
- CanvasForceRGBA::kNotForced);
+ const CanvasColorParams kColorParams(
+ CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
+ kNonOpaque);
auto provider = CanvasResourceProvider::Create(
kSize,
@@ -180,7 +181,9 @@ TEST_F(CanvasResourceProviderTest,
EXPECT_FALSE(provider->IsSingleBuffered());
EXPECT_FALSE(provider->SupportsSingleBuffering());
EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace());
- EXPECT_EQ(provider->ColorParams().PixelFormat(), kColorParams.PixelFormat());
+ // 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());
@@ -215,9 +218,9 @@ TEST_F(CanvasResourceProviderTest,
TEST_F(CanvasResourceProviderTest,
CanvasResourceProviderSharedImageStaticBitmapImage) {
const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
- CanvasPixelFormat::kRGBA8, kNonOpaque,
- CanvasForceRGBA::kNotForced);
+ const CanvasColorParams kColorParams(
+ CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
+ kNonOpaque);
auto provider = CanvasResourceProvider::Create(
kSize,
@@ -233,21 +236,25 @@ TEST_F(CanvasResourceProviderTest,
auto image = provider->Snapshot();
ASSERT_TRUE(image);
auto new_image = provider->Snapshot();
- EXPECT_EQ(image->GetMailbox(), new_image->GetMailbox());
+ EXPECT_EQ(image->GetMailboxHolder().mailbox,
+ new_image->GetMailboxHolder().mailbox);
EXPECT_EQ(provider->ProduceCanvasResource()->GetOrCreateGpuMailbox(
kOrderingBarrier),
- image->GetMailbox());
+ image->GetMailboxHolder().mailbox);
// Resource updated after draw.
provider->Canvas()->clear(SK_ColorWHITE);
+ provider->FlushCanvas();
new_image = provider->Snapshot();
- EXPECT_NE(new_image->GetMailbox(), image->GetMailbox());
+ EXPECT_NE(new_image->GetMailboxHolder().mailbox,
+ image->GetMailboxHolder().mailbox);
// Resource recycled.
- auto original_mailbox = image->GetMailbox();
+ auto original_mailbox = image->GetMailboxHolder().mailbox;
image.reset();
provider->Canvas()->clear(SK_ColorBLACK);
- EXPECT_EQ(original_mailbox, provider->Snapshot()->GetMailbox());
+ provider->FlushCanvas();
+ EXPECT_EQ(original_mailbox, provider->Snapshot()->GetMailboxHolder().mailbox);
}
TEST_F(CanvasResourceProviderTest,
@@ -259,9 +266,9 @@ TEST_F(CanvasResourceProviderTest,
fake_context->SetCapabilities(caps);
const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
- CanvasPixelFormat::kRGBA8, kNonOpaque,
- CanvasForceRGBA::kNotForced);
+ const CanvasColorParams kColorParams(
+ CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
+ kNonOpaque);
auto provider = CanvasResourceProvider::Create(
kSize,
@@ -282,16 +289,12 @@ TEST_F(CanvasResourceProviderTest,
TEST_F(CanvasResourceProviderTest, CanvasResourceProviderBitmap) {
const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
- CanvasPixelFormat::kRGBA8, kNonOpaque,
- CanvasForceRGBA::kNotForced);
+ const CanvasColorParams kColorParams(
+ CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
+ kNonOpaque);
- auto provider = CanvasResourceProvider::Create(
- kSize, CanvasResourceProvider::ResourceUsage::kSoftwareResourceUsage,
- context_provider_wrapper_, 0 /* msaa_sample_count */,
- kLow_SkFilterQuality, kColorParams,
- CanvasResourceProvider::kAllowImageChromiumPresentationMode,
- nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
+ auto provider = CanvasResourceProvider::CreateBitmapProvider(
+ kSize, kLow_SkFilterQuality, kColorParams);
EXPECT_EQ(provider->Size(), kSize);
EXPECT_TRUE(provider->IsValid());
@@ -308,9 +311,9 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderBitmap) {
TEST_F(CanvasResourceProviderTest, CanvasResourceProviderSharedBitmap) {
const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
- CanvasPixelFormat::kRGBA8, kNonOpaque,
- CanvasForceRGBA::kNotForced);
+ const CanvasColorParams kColorParams(
+ CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
+ kNonOpaque);
MockCanvasResourceDispatcherClient client;
CanvasResourceDispatcher resource_dispatcher(
@@ -343,9 +346,9 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderSharedBitmap) {
TEST_F(CanvasResourceProviderTest,
CanvasResourceProviderDirect2DGpuMemoryBuffer) {
const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
- CanvasPixelFormat::kRGBA8, kNonOpaque,
- CanvasForceRGBA::kNotForced);
+ const CanvasColorParams kColorParams(
+ CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
+ kNonOpaque);
auto provider = CanvasResourceProvider::Create(
kSize,
@@ -361,7 +364,9 @@ TEST_F(CanvasResourceProviderTest,
EXPECT_TRUE(provider->SupportsDirectCompositing());
EXPECT_TRUE(provider->SupportsSingleBuffering());
EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace());
- EXPECT_EQ(provider->ColorParams().PixelFormat(), kColorParams.PixelFormat());
+ // 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());
@@ -373,9 +378,9 @@ TEST_F(CanvasResourceProviderTest,
TEST_F(CanvasResourceProviderTest,
CanvasResourceProviderDirect3DGpuMemoryBuffer) {
const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
- CanvasPixelFormat::kRGBA8, kNonOpaque,
- CanvasForceRGBA::kNotForced);
+ const CanvasColorParams kColorParams(
+ CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
+ kNonOpaque);
auto provider = CanvasResourceProvider::Create(
kSize,
@@ -404,7 +409,7 @@ TEST_F(CanvasResourceProviderTest,
ExternalCanvasResource::Create(
mailbox, kSize, GL_TEXTURE_2D, kColorParams,
SharedGpuContext::ContextProviderWrapper(), provider->CreateWeakPtr(),
- kMedium_SkFilterQuality, /*is_origin_top_left=*/true);
+ kMedium_SkFilterQuality, true /*is_origin_top_left*/);
// NewOrRecycledResource() would return nullptr before an ImportResource().
EXPECT_TRUE(provider->ImportResource(resource));
@@ -417,9 +422,9 @@ TEST_F(CanvasResourceProviderTest,
// https://crbug.com/985366
TEST_F(CanvasResourceProviderTest, CanvasResourceProviderDirect3DTexture) {
const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
- CanvasPixelFormat::kRGBA8, kNonOpaque,
- CanvasForceRGBA::kNotForced);
+ const CanvasColorParams kColorParams(
+ CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
+ kNonOpaque);
auto provider = CanvasResourceProvider::Create(
kSize,
@@ -435,7 +440,9 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderDirect3DTexture) {
EXPECT_TRUE(provider->SupportsDirectCompositing());
EXPECT_FALSE(provider->SupportsSingleBuffering());
EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace());
- EXPECT_EQ(provider->ColorParams().PixelFormat(), kColorParams.PixelFormat());
+ // 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());
@@ -453,10 +460,56 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderDirect3DTexture) {
callback->Run(gpu::SyncToken(), true /* is_lost */);
}
+TEST_F(CanvasResourceProviderTest, DimensionsExceedMaxTextureSize_Bitmap) {
+ const CanvasColorParams kColorParams(
+ CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
+ kNonOpaque);
+
+ auto provider = CanvasResourceProvider::CreateBitmapProvider(
+ IntSize(kMaxTextureSize - 1, kMaxTextureSize), kLow_SkFilterQuality,
+ kColorParams);
+ EXPECT_FALSE(provider->SupportsDirectCompositing());
+ provider = CanvasResourceProvider::CreateBitmapProvider(
+ IntSize(kMaxTextureSize, kMaxTextureSize), kLow_SkFilterQuality,
+ kColorParams);
+ EXPECT_FALSE(provider->SupportsDirectCompositing());
+ provider = CanvasResourceProvider::CreateBitmapProvider(
+ IntSize(kMaxTextureSize + 1, kMaxTextureSize), kLow_SkFilterQuality,
+ kColorParams);
+ EXPECT_FALSE(provider->SupportsDirectCompositing());
+}
+
+TEST_F(CanvasResourceProviderTest, DimensionsExceedMaxTextureSize_SharedImage) {
+ const CanvasColorParams kColorParams(
+ CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
+ kNonOpaque);
+
+ 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*/);
+ 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*/);
+ 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*/);
+ // 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) {
- const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
- CanvasPixelFormat::kRGBA8, kNonOpaque,
- CanvasForceRGBA::kNotForced);
+ const CanvasColorParams kColorParams(
+ CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
+ kNonOpaque);
for (int i = 0;
i < static_cast<int>(CanvasResourceProvider::ResourceUsage::kMaxValue);
@@ -464,18 +517,20 @@ TEST_F(CanvasResourceProviderTest, DimensionsExceedMaxTextureSize) {
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:
- should_support_compositing = false;
- break;
+ continue;
+ case CanvasResourceProvider::ResourceUsage::kAcceleratedResourceUsage:
+ continue;
case CanvasResourceProvider::ResourceUsage::
kSoftwareCompositedResourceUsage:
FALLTHROUGH;
case CanvasResourceProvider::ResourceUsage::
kSoftwareCompositedDirect2DResourceUsage:
FALLTHROUGH;
- case CanvasResourceProvider::ResourceUsage::kAcceleratedResourceUsage:
- FALLTHROUGH;
case CanvasResourceProvider::ResourceUsage::
kAcceleratedCompositedResourceUsage:
FALLTHROUGH;
@@ -488,39 +543,42 @@ TEST_F(CanvasResourceProviderTest, DimensionsExceedMaxTextureSize) {
break;
}
- auto 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 */);
+ 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 */);
+ 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 */);
+ 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());
}
}
TEST_F(CanvasResourceProviderTest, CanvasResourceProviderDirect2DSwapChain) {
const IntSize kSize(10, 10);
- const CanvasColorParams kColorParams(CanvasColorSpace::kSRGB,
- CanvasPixelFormat::kRGBA8, kNonOpaque,
- CanvasForceRGBA::kNotForced);
+ const CanvasColorParams kColorParams(
+ CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
+ kNonOpaque);
auto provider = CanvasResourceProvider::Create(
kSize,
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 680b810bf83..20929011633 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
@@ -194,7 +194,7 @@ void ColorCorrectionTestUtils::CompareColorCorrectedPixels(
bool ColorCorrectionTestUtils::ConvertPixelsToColorSpaceAndPixelFormatForTest(
void* src_data,
- int num_elements,
+ size_t num_elements,
CanvasColorSpace src_color_space,
ImageDataStorageFormat src_storage_format,
CanvasColorSpace dst_color_space,
@@ -221,14 +221,13 @@ bool ColorCorrectionTestUtils::ConvertPixelsToColorSpaceAndPixelFormatForTest(
(src_storage_format == kUint8ClampedArrayStorageFormat)
? CanvasPixelFormat::kRGBA8
: CanvasPixelFormat::kF16,
- kNonOpaque, CanvasForceRGBA::kNotForced)
+ kNonOpaque)
.GetSkColorSpaceForSkSurfaces();
if (!src_sk_color_space.get())
src_sk_color_space = SkColorSpace::MakeSRGB();
sk_sp<SkColorSpace> dst_sk_color_space =
- CanvasColorParams(dst_color_space, dst_canvas_pixel_format, kNonOpaque,
- CanvasForceRGBA::kNotForced)
+ CanvasColorParams(dst_color_space, dst_canvas_pixel_format, kNonOpaque)
.GetSkColorSpaceForSkSurfaces();
if (!dst_sk_color_space.get())
dst_sk_color_space = SkColorSpace::MakeSRGB();
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 30c6c677174..3323b5d2bf9 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
@@ -65,7 +65,7 @@ class ColorCorrectionTestUtils {
static bool ConvertPixelsToColorSpaceAndPixelFormatForTest(
void* src_data,
- int num_elements,
+ size_t num_elements,
CanvasColorSpace src_color_space,
ImageDataStorageFormat src_storage_format,
CanvasColorSpace dst_color_space,
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/README.md b/chromium/third_party/blink/renderer/platform/graphics/compositing/README.md
index f8334d739ce..d40b6ed2b7a 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing/README.md
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/README.md
@@ -16,7 +16,7 @@ Inputs: `PaintArtifact`
Outputs: List of `cc::Layer` objects and `cc::PropertyTree`'s.
The algorithm walks through the list of `PaintChunks` in the `PaintArtifact`,
-allocating new `c::Layers` if the `PaintChunk` cannot merge into an existing
+allocating new `cc::Layers` if the `PaintChunk` cannot merge into an existing
`cc::Layer`. The reasons why it would not be able to do so are:
1. The `PaintChunk` requires a foreign layer (see below)
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 70cd474d009..9f8c025c661 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
@@ -21,7 +21,7 @@ class ChunkToLayerMapperTest : public testing::Test {
DEFINE_STATIC_LOCAL(
base::Optional<PaintChunk::Id>, id,
(PaintChunk::Id(fake_client, DisplayItem::kDrawingFirst)));
- PaintChunk chunk(0, 0, *id, state);
+ PaintChunk chunk(0, 1, *id, state);
return chunk;
}
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 cdaf3e8115e..1e7e0c1f113 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
@@ -24,7 +24,7 @@ namespace blink {
ContentLayerClientImpl::ContentLayerClientImpl()
: cc_picture_layer_(cc::PictureLayer::Create(this)),
- raster_invalidator_(
+ raster_invalidation_function_(
base::BindRepeating(&ContentLayerClientImpl::InvalidateRect,
base::Unretained(this))),
layer_state_(PropertyTreeState::Uninitialized()) {}
@@ -42,9 +42,12 @@ void ContentLayerClientImpl::AppendAdditionalInfoAsJSON(
json.SetValue("paintChunkContents", paint_chunk_debug_data_->Clone());
#endif
- if ((flags & kLayerTreeIncludesPaintInvalidations) &&
- raster_invalidator_.GetTracking())
- raster_invalidator_.GetTracking()->AsJSON(&json);
+ if ((flags & (kLayerTreeIncludesInvalidations |
+ kLayerTreeIncludesDetailedInvalidations)) &&
+ raster_invalidator_.GetTracking()) {
+ raster_invalidator_.GetTracking()->AsJSON(
+ &json, flags & kLayerTreeIncludesDetailedInvalidations);
+ }
#if DCHECK_IS_ON()
if (flags & kLayerTreeIncludesPaintRecords) {
@@ -73,7 +76,7 @@ scoped_refptr<cc::PictureLayer> ContentLayerClientImpl::UpdateCcPictureLayer(
auto json = std::make_unique<JSONObject>();
json->SetString("data", chunk.ToString());
json->SetArray("displayItems",
- paint_artifact->GetDisplayItemList().SubsequenceAsJSON(
+ paint_artifact->GetDisplayItemList().DisplayItemsAsJSON(
chunk.begin_index, chunk.end_index,
DisplayItemList::kShowOnlyDisplayItemTypes));
paint_chunk_debug_data_->PushObject(std::move(json));
@@ -85,8 +88,8 @@ scoped_refptr<cc::PictureLayer> ContentLayerClientImpl::UpdateCcPictureLayer(
if (layer_state != layer_state_)
cc_picture_layer_->SetSubtreePropertyChanged();
- raster_invalidator_.Generate(paint_artifact, paint_chunks, layer_bounds,
- layer_state);
+ raster_invalidator_.Generate(raster_invalidation_function_, paint_artifact,
+ paint_chunks, layer_bounds, layer_state);
layer_state_ = layer_state;
// Note: cc::Layer API assumes the layer bounds start at (0, 0), but the
@@ -97,7 +100,6 @@ scoped_refptr<cc::PictureLayer> ContentLayerClientImpl::UpdateCcPictureLayer(
cc_picture_layer_->SetOffsetToTransformParent(
layer_bounds.OffsetFromOrigin());
cc_picture_layer_->SetBounds(layer_bounds.size());
- cc_picture_layer_->SetIsDrawable(true);
cc_picture_layer_->SetHitTestable(true);
base::Optional<RasterUnderInvalidationCheckingParams> params;
@@ -111,14 +113,20 @@ scoped_refptr<cc::PictureLayer> ContentLayerClientImpl::UpdateCcPictureLayer(
display_item_list, cc::DisplayItemList::kTopLevelDisplayItemList,
base::OptionalOrNullptr(params));
- cc_picture_layer_->SetSafeOpaqueBackgroundColor(
- paint_chunks[0].safe_opaque_background_color);
+ 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());
+
+ auto safe_opaque_background_color =
+ paint_artifact->SafeOpaqueBackgroundColor(paint_chunks);
+ cc_picture_layer_->SetSafeOpaqueBackgroundColor(safe_opaque_background_color);
// TODO(masonfreed): We don't need to set the background color here; only the
// safe opaque background color matters. But making that change would require
// rebaselining 787 tests to remove the "background_color" property from the
// layer dumps.
- cc_picture_layer_->SetBackgroundColor(
- paint_chunks[0].safe_opaque_background_color);
+ cc_picture_layer_->SetBackgroundColor(safe_opaque_background_color);
return cc_picture_layer_;
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h b/chromium/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h
index 5ce14faec81..aeb201b488f 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h
@@ -74,6 +74,8 @@ class PLATFORM_EXPORT ContentLayerClientImpl : public cc::ContentLayerClient,
scoped_refptr<cc::PictureLayer> cc_picture_layer_;
scoped_refptr<cc::DisplayItemList> cc_display_item_list_;
RasterInvalidator raster_invalidator_;
+ RasterInvalidator::RasterInvalidationFunction raster_invalidation_function_;
+
PropertyTreeState layer_state_;
String debug_name_;
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 318662e15cc..3502e78074f 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
@@ -25,10 +25,8 @@ String PointerAsString(const void* ptr) {
} // namespace
// Create a JSON version of the specified |layer|.
-std::unique_ptr<JSONObject> CCLayerAsJSON(
- const cc::Layer* layer,
- LayerTreeFlags flags,
- const FloatPoint& offset_from_transform_node) {
+std::unique_ptr<JSONObject> CCLayerAsJSON(const cc::Layer* layer,
+ LayerTreeFlags flags) {
auto json = std::make_unique<JSONObject>();
if (flags & kLayerTreeIncludesDebugInfo) {
@@ -38,8 +36,11 @@ std::unique_ptr<JSONObject> CCLayerAsJSON(
json->SetString("name", String(layer->DebugName().c_str()));
- if (offset_from_transform_node != FloatPoint())
- json->SetArray("position", PointAsJSONArray(offset_from_transform_node));
+ if (layer->offset_to_transform_parent() != gfx::Vector2dF()) {
+ json->SetArray(
+ "position",
+ PointAsJSONArray(FloatPoint(layer->offset_to_transform_parent())));
+ }
// This is testing against gfx::Size(), *not* whether the size is empty.
if (layer->bounds() != gfx::Size())
@@ -127,13 +128,15 @@ int LayersAsJSON::AddTransformJSON(
}
void LayersAsJSON::AddLayer(const cc::Layer& layer,
- const FloatPoint& offset,
const TransformPaintPropertyNode& transform,
const LayerAsJSONClient* json_client) {
- if (!(flags_ & kLayerTreeIncludesAllLayers) && !layer.DrawsContent())
+ if (!(flags_ & kLayerTreeIncludesAllLayers) && !layer.DrawsContent() &&
+ (layer.DebugName() == "LayoutView #document" ||
+ layer.DebugName() == "Inner Viewport Scroll Layer" ||
+ layer.DebugName() == "Scrolling Contents Layer"))
return;
- auto layer_json = CCLayerAsJSON(&layer, flags_, offset);
+ auto layer_json = CCLayerAsJSON(&layer, flags_);
if (json_client) {
json_client->AppendAdditionalInfoAsJSON(flags_, layer, *(layer_json.get()));
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/layers_as_json.h b/chromium/third_party/blink/renderer/platform/graphics/compositing/layers_as_json.h
index 0008f97f94a..4be8eed283d 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing/layers_as_json.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/layers_as_json.h
@@ -16,7 +16,6 @@ class Layer;
namespace blink {
-class FloatPoint;
class JSONArray;
class JSONObject;
class TransformPaintPropertyNode;
@@ -27,9 +26,10 @@ enum {
kLayerTreeNormal = 0,
// Dump extra debugging info like layer addresses.
kLayerTreeIncludesDebugInfo = 1 << 0,
- kLayerTreeIncludesPaintInvalidations = 1 << 1,
- kLayerTreeIncludesPaintingPhases = 1 << 2,
- kLayerTreeIncludesAllLayers = 1 << 3,
+ kLayerTreeIncludesInvalidations = 1 << 1,
+ kLayerTreeIncludesDetailedInvalidations = 1 << 2,
+ kLayerTreeIncludesPaintingPhases = 1 << 3,
+ kLayerTreeIncludesAllLayers = 1 << 4,
kLayerTreeIncludesCompositingReasons = 1 << 5,
kLayerTreeIncludesPaintRecords = 1 << 6,
// Outputs all layers as a layer tree. The default is output children
@@ -50,7 +50,6 @@ class PLATFORM_EXPORT LayersAsJSON {
LayersAsJSON(LayerTreeFlags);
void AddLayer(const cc::Layer& layer,
- const FloatPoint& offset,
const TransformPaintPropertyNode& transform,
const LayerAsJSONClient* json_client);
@@ -69,8 +68,7 @@ class PLATFORM_EXPORT LayersAsJSON {
PLATFORM_EXPORT std::unique_ptr<JSONObject> CCLayerAsJSON(
const cc::Layer* layer,
- LayerTreeFlags flags,
- const FloatPoint& position);
+ LayerTreeFlags flags);
} // namespace blink
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 76d426253a5..015e3f9418f 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
@@ -7,24 +7,26 @@
#include <memory>
#include <utility>
-#include "cc/layers/layer.h"
+#include "cc/layers/scrollbar_layer_base.h"
#include "cc/paint/display_item_list.h"
#include "cc/trees/effect_node.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/mutator_host.h"
#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/platform/geometry/geometry_as_json.h"
#include "third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
+#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.h"
#include "third_party/blink/renderer/platform/graphics/paint/display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h"
+#include "third_party/blink/renderer/platform/graphics/paint/graphics_layer_display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_artifact.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_chunk_subset.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_flags.h"
#include "third_party/blink/renderer/platform/graphics/paint/property_tree_state.h"
#include "third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h"
-#include "third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h"
#include "third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h"
@@ -60,6 +62,14 @@ void PaintArtifactCompositor::WillBeRemovedFromFrame() {
root_layer_->RemoveAllChildren();
}
+std::unique_ptr<JSONArray> PaintArtifactCompositor::GetPendingLayersAsJSON(
+ const PaintArtifact* paint_artifact) const {
+ std::unique_ptr<JSONArray> result = std::make_unique<JSONArray>();
+ for (const PendingLayer& pending_layer : pending_layers_)
+ result->PushObject(pending_layer.ToJSON(paint_artifact));
+ return result;
+}
+
// Get a JSON representation of what layers exist for this PAC. Note that
// |paint_artifact| is only needed for pre-CAP mode.
std::unique_ptr<JSONObject> PaintArtifactCompositor::GetLayersAsJSON(
@@ -67,6 +77,13 @@ std::unique_ptr<JSONObject> PaintArtifactCompositor::GetLayersAsJSON(
const PaintArtifact* paint_artifact) const {
DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
paint_artifact);
+
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
+ !tracks_raster_invalidations_) {
+ flags &= ~(kLayerTreeIncludesInvalidations |
+ kLayerTreeIncludesDetailedInvalidations);
+ }
+
LayersAsJSON layers_as_json(flags);
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
for (const auto& layer : root_layer_->children()) {
@@ -90,28 +107,47 @@ std::unique_ptr<JSONObject> PaintArtifactCompositor::GetLayersAsJSON(
}
}
DCHECK(transform);
- layers_as_json.AddLayer(*layer,
- FloatPoint(layer->offset_to_transform_parent()),
- *transform, json_client);
+ layers_as_json.AddLayer(*layer, *transform, json_client);
}
} else {
for (const auto& paint_chunk : paint_artifact->PaintChunks()) {
const auto& display_item =
paint_artifact->GetDisplayItemList()[paint_chunk.begin_index];
- DCHECK(display_item.IsForeignLayer());
- const auto& foreign_layer_display_item =
- static_cast<const ForeignLayerDisplayItem&>(display_item);
- cc::Layer* layer = foreign_layer_display_item.GetLayer();
- layers_as_json.AddLayer(
- *layer, foreign_layer_display_item.Offset(),
- paint_chunk.properties.Transform(),
- foreign_layer_display_item.GetLayerAsJSONClient());
+ cc::Layer* layer = nullptr;
+ const LayerAsJSONClient* json_client = nullptr;
+ if (display_item.IsGraphicsLayerWrapper()) {
+ const GraphicsLayerDisplayItem& graphics_layer_display_item =
+ static_cast<const GraphicsLayerDisplayItem&>(display_item);
+ layer = graphics_layer_display_item.GetGraphicsLayer().CcLayer();
+ json_client = &graphics_layer_display_item.GetGraphicsLayer();
+ } else {
+ DCHECK(display_item.IsForeignLayer());
+ 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
+ // offset_from_transform_parent and |paint_chunk|'s transform inside
+ // AddLayer.
+ const TransformPaintPropertyNode* transform = nullptr;
+ for (const auto& pending_layer : pending_layers_) {
+ if (pending_layer.property_tree_state.Transform().CcNodeId(
+ layer->property_tree_sequence_number()) ==
+ layer->transform_tree_index()) {
+ transform = &pending_layer.property_tree_state.Transform();
+ break;
+ }
+ }
+ DCHECK(transform);
+ layers_as_json.AddLayer(*layer, *transform, json_client);
}
}
return layers_as_json.Finalize();
}
-static scoped_refptr<cc::Layer> ForeignLayerForPaintChunk(
+static scoped_refptr<cc::Layer> CcLayerForPaintChunk(
const PaintArtifact& paint_artifact,
const PaintChunk& paint_chunk,
const FloatPoint& pending_layer_offset) {
@@ -120,33 +156,44 @@ static scoped_refptr<cc::Layer> ForeignLayerForPaintChunk(
const auto& display_item =
paint_artifact.GetDisplayItemList()[paint_chunk.begin_index];
- if (!display_item.IsForeignLayer())
+ if (!display_item.IsForeignLayer() &&
+ !display_item.IsGraphicsLayerWrapper()) {
return nullptr;
+ }
- // When a foreign layer's offset_to_transform_parent() changes, we don't
- // call PaintArtifaceCompositor::SetNeedsUpdate() because the update won't
- // change anything but cause unnecessary commit. Though
- // UpdateTouchActionRects() depends on offset_to_transform_parent(), a
- // foreign layer chunk doesn't have hit_test_data.
+ // UpdateTouchActionRects() depends on the layer's offset, but when the
+ // layer's offset changes, we do not call SetNeedsUpdate() (this is an
+ // optimization because the update would only cause an extra commit). This is
+ // only OK if the [Foreign|Graphics]Layer doesn't have hit test data.
DCHECK(!paint_chunk.hit_test_data);
- const auto& foreign_layer_display_item =
- static_cast<const ForeignLayerDisplayItem&>(display_item);
- auto* layer = foreign_layer_display_item.GetLayer();
- layer->SetOffsetToTransformParent(gfx::Vector2dF(
- foreign_layer_display_item.Offset() + pending_layer_offset));
+ cc::Layer* layer = nullptr;
+ FloatPoint layer_offset;
+ if (display_item.IsGraphicsLayerWrapper()) {
+ const auto& graphics_layer_display_item =
+ static_cast<const GraphicsLayerDisplayItem&>(display_item);
+ layer = graphics_layer_display_item.GetGraphicsLayer().CcLayer();
+ layer_offset = FloatPoint(graphics_layer_display_item.GetGraphicsLayer()
+ .GetOffsetFromTransformNode());
+ } else {
+ const auto& foreign_layer_display_item =
+ static_cast<const ForeignLayerDisplayItem&>(display_item);
+ layer = foreign_layer_display_item.GetLayer();
+ layer_offset = foreign_layer_display_item.Offset();
+ }
+ layer->SetOffsetToTransformParent(
+ gfx::Vector2dF(layer_offset + pending_layer_offset));
return layer;
}
const TransformPaintPropertyNode&
-PaintArtifactCompositor::ScrollOffsetTranslationForLayer(
+PaintArtifactCompositor::NearestScrollTranslationForLayer(
const PaintArtifact& paint_artifact,
const PendingLayer& pending_layer) {
- if (const auto* scroll_hit_test =
- ScrollHitTestForLayer(paint_artifact, pending_layer)) {
- if (scroll_hit_test->scroll_offset)
- return *scroll_hit_test->scroll_offset;
- }
+ if (const auto* scroll_translation =
+ ScrollTranslationForLayer(paint_artifact, pending_layer))
+ return *scroll_translation;
+
const auto& transform = pending_layer.property_tree_state.Transform();
// TODO(pdr): This could be a performance issue because it crawls up the
// transform tree for each pending layer. If this is on profiles, we should
@@ -154,41 +201,33 @@ PaintArtifactCompositor::ScrollOffsetTranslationForLayer(
return transform.NearestScrollTranslationNode();
}
-const HitTestData::ScrollHitTest*
-PaintArtifactCompositor::ScrollHitTestForLayer(
+const TransformPaintPropertyNode*
+PaintArtifactCompositor::ScrollTranslationForLayer(
const PaintArtifact& paint_artifact,
const PendingLayer& pending_layer) {
if (pending_layer.paint_chunk_indices.size() != 1)
return nullptr;
- const auto& paint_chunk =
- paint_artifact.PaintChunks()[pending_layer.paint_chunk_indices[0]];
- if (paint_chunk.size() != 1)
- return nullptr;
-
- const HitTestData* hit_test_data = paint_chunk.hit_test_data.get();
- if (!hit_test_data)
+ const auto& paint_chunk = pending_layer.FirstPaintChunk(paint_artifact);
+ if (!paint_chunk.hit_test_data)
return nullptr;
- return base::OptionalOrNullptr(hit_test_data->scroll_hit_test);
+ return paint_chunk.hit_test_data->scroll_translation;
}
scoped_refptr<cc::Layer>
PaintArtifactCompositor::ScrollHitTestLayerForPendingLayer(
const PaintArtifact& paint_artifact,
const PendingLayer& pending_layer) {
- const auto* scroll_hit_test =
- ScrollHitTestForLayer(paint_artifact, pending_layer);
- if (!scroll_hit_test)
- return nullptr;
- const auto* scroll_offset = scroll_hit_test->scroll_offset;
- if (!scroll_offset)
+ const auto* scroll_translation =
+ ScrollTranslationForLayer(paint_artifact, pending_layer);
+ if (!scroll_translation)
return nullptr;
// We shouldn't decomposite scroll transform nodes.
DCHECK_EQ(FloatPoint(), pending_layer.offset_of_decomposited_transforms);
- const auto& scroll_node = *scroll_offset->ScrollNode();
+ const auto& scroll_node = *scroll_translation->ScrollNode();
auto scroll_element_id = scroll_node.GetCompositorElementId();
scoped_refptr<cc::Layer> scroll_layer;
@@ -209,17 +248,20 @@ PaintArtifactCompositor::ScrollHitTestLayerForPendingLayer(
// match (see: crbug.com/753124). To do this, use
// |scroll_hit_test->scroll_container_bounds|.
auto bounds = scroll_node.ContainerRect().Size();
- // Mark the layer as scrollable.
- // TODO(pdr): When CAP launches this parameter for bounds will not be
- // needed.
- scroll_layer->SetScrollable(static_cast<gfx::Size>(bounds));
// Set the layer's bounds equal to the container because the scroll layer
// does not scroll.
scroll_layer->SetBounds(static_cast<gfx::Size>(bounds));
+
+ if (scroll_node.NodeChanged() != PaintPropertyChangeType::kUnchanged) {
+ scroll_layer->SetNeedsPushProperties();
+ scroll_layer->SetNeedsCommit();
+ }
+
return scroll_layer;
}
-scoped_refptr<cc::Layer> PaintArtifactCompositor::ScrollbarLayerForPendingLayer(
+scoped_refptr<cc::ScrollbarLayerBase>
+PaintArtifactCompositor::ScrollbarLayerForPendingLayer(
const PaintArtifact& paint_artifact,
const PendingLayer& pending_layer) {
if (pending_layer.paint_chunk_indices.size() != 1)
@@ -235,29 +277,11 @@ scoped_refptr<cc::Layer> PaintArtifactCompositor::ScrollbarLayerForPendingLayer(
if (!item.IsScrollbar())
return nullptr;
- const auto& scrollbar_item = static_cast<const ScrollbarDisplayItem&>(item);
- scoped_refptr<cc::Layer> scrollbar_layer;
- for (auto& existing_layer : scrollbar_layers_) {
- if (existing_layer->element_id() == scrollbar_item.ElementId())
- scrollbar_layer = existing_layer;
- }
- if (scrollbar_layer) {
- cc::Scrollbar* scrollbar = scrollbar_item.GetScrollbar();
- if (scrollbar->NeedsRepaintPart(cc::THUMB) ||
- scrollbar->NeedsRepaintPart(cc::TRACK_BUTTONS_TICKMARKS))
- scrollbar_layer->SetNeedsDisplay();
- } else {
- scrollbar_layer = scrollbar_item.CreateLayer();
- }
-
// We should never decomposite scroll translations, so we don't need to adjust
// the layer's offset for decomposited transforms.
DCHECK_EQ(FloatPoint(), pending_layer.offset_of_decomposited_transforms);
- const IntRect& rect = scrollbar_item.GetRect();
- scrollbar_layer->SetOffsetToTransformParent(
- gfx::Vector2dF(FloatPoint(rect.Location())));
- scrollbar_layer->SetBounds(gfx::Size(rect.Size()));
- return scrollbar_layer;
+
+ return static_cast<const ScrollbarDisplayItem&>(item).GetLayer();
}
std::unique_ptr<ContentLayerClientImpl>
@@ -281,20 +305,20 @@ PaintArtifactCompositor::CompositedLayerForPendingLayer(
scoped_refptr<const PaintArtifact> paint_artifact,
const PendingLayer& pending_layer,
Vector<std::unique_ptr<ContentLayerClientImpl>>& new_content_layer_clients,
- Vector<scoped_refptr<cc::Layer>>& new_scroll_hit_test_layers,
- Vector<scoped_refptr<cc::Layer>>& new_scrollbar_layers) {
+ Vector<scoped_refptr<cc::Layer>>& new_scroll_hit_test_layers) {
auto paint_chunks =
paint_artifact->GetPaintChunkSubset(pending_layer.paint_chunk_indices);
DCHECK(paint_chunks.size());
const PaintChunk& first_paint_chunk = paint_chunks[0];
- DCHECK(first_paint_chunk.size());
- // If the paint chunk is a foreign layer, just return that layer.
- if (scoped_refptr<cc::Layer> foreign_layer = ForeignLayerForPaintChunk(
- *paint_artifact, first_paint_chunk,
- pending_layer.offset_of_decomposited_transforms)) {
+ scoped_refptr<cc::Layer> cc_layer;
+ // If the paint chunk is a foreign layer or placeholder for a GraphicsLayer,
+ // just return its cc::Layer.
+ if ((cc_layer = CcLayerForPaintChunk(
+ *paint_artifact, first_paint_chunk,
+ pending_layer.offset_of_decomposited_transforms))) {
DCHECK_EQ(paint_chunks.size(), 1u);
- return foreign_layer;
+ return cc_layer;
}
// If the paint chunk is a scroll hit test layer, lookup/create the layer.
@@ -304,9 +328,8 @@ PaintArtifactCompositor::CompositedLayerForPendingLayer(
return scroll_layer;
}
- if (scoped_refptr<cc::Layer> scrollbar_layer =
+ if (auto scrollbar_layer =
ScrollbarLayerForPendingLayer(*paint_artifact, pending_layer)) {
- new_scrollbar_layers.push_back(scrollbar_layer);
return scrollbar_layer;
}
@@ -315,11 +338,9 @@ PaintArtifactCompositor::CompositedLayerForPendingLayer(
ClientForPaintChunk(first_paint_chunk);
IntRect cc_combined_bounds = EnclosingIntRect(pending_layer.bounds);
- auto cc_layer = content_layer_client->UpdateCcPictureLayer(
+ cc_layer = content_layer_client->UpdateCcPictureLayer(
paint_artifact, paint_chunks, cc_combined_bounds,
pending_layer.property_tree_state);
- if (cc_combined_bounds.IsEmpty())
- cc_layer->SetIsDrawable(false);
new_content_layer_clients.push_back(std::move(content_layer_client));
@@ -345,8 +366,7 @@ void PaintArtifactCompositor::UpdateTouchActionRects(
const auto& chunk_state = chunk.properties.GetPropertyTreeState();
for (const auto& touch_action_rect : hit_test_data->touch_action_rects) {
- auto rect =
- FloatClipRect(FloatRect(PixelSnappedIntRect(touch_action_rect.rect)));
+ auto rect = FloatClipRect(FloatRect(touch_action_rect.rect));
if (!GeometryMapper::LocalToAncestorVisualRect(chunk_state, layer_state,
rect)) {
continue;
@@ -364,12 +384,13 @@ void PaintArtifactCompositor::UpdateNonFastScrollableRegions(
cc::Layer* layer,
const gfx::Vector2dF& layer_offset,
const PropertyTreeState& layer_state,
- const PaintChunkSubset& paint_chunks) {
+ const PaintChunkSubset& paint_chunks,
+ PropertyTreeManager* property_tree_manager) {
cc::Region non_fast_scrollable_regions_in_layer_space;
for (const auto& chunk : paint_chunks) {
// Add any non-fast scrollable hit test data from the paint chunk.
const auto* hit_test_data = chunk.hit_test_data.get();
- if (!hit_test_data || !hit_test_data->scroll_hit_test)
+ if (!hit_test_data || hit_test_data->scroll_hit_test_rect.IsEmpty())
continue;
// Skip the scroll hit test rect if it is for scrolling this cc::Layer.
@@ -377,21 +398,21 @@ void PaintArtifactCompositor::UpdateNonFastScrollableRegions(
// pre-CompositeAfterPaint does not paint scroll hit test data for
// composited scrollers.
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
- if (layer->scrollable()) {
- const auto* scroll_offset =
- hit_test_data->scroll_hit_test->scroll_offset;
- if (scroll_offset) {
- const auto& scroll_node = *scroll_offset->ScrollNode();
- auto scroll_element_id = scroll_node.GetCompositorElementId();
- if (layer->element_id() == scroll_element_id)
- continue;
- }
+ if (const auto* scroll_translation = hit_test_data->scroll_translation) {
+ const auto& scroll_node = *scroll_translation->ScrollNode();
+ auto scroll_element_id = scroll_node.GetCompositorElementId();
+ if (layer->element_id() == scroll_element_id)
+ continue;
+ // Ensure the cc scroll node to prepare for possible descendant nodes
+ // referenced by later composited layers. This can't be done by ensuring
+ // parent transform node in EnsureCompositorTransformNode() if the
+ // transform tree and the scroll tree have different topologies.
+ DCHECK(property_tree_manager);
+ property_tree_manager->EnsureCompositorScrollNode(*scroll_translation);
}
}
- const auto& bounds =
- hit_test_data->scroll_hit_test->scroll_container_bounds;
- auto rect = FloatClipRect(FloatRect(bounds));
+ FloatClipRect rect(FloatRect(chunk.hit_test_data->scroll_hit_test_rect));
const auto& chunk_state = chunk.properties.GetPropertyTreeState();
if (!GeometryMapper::LocalToAncestorVisualRect(chunk_state, layer_state,
rect)) {
@@ -399,7 +420,7 @@ void PaintArtifactCompositor::UpdateNonFastScrollableRegions(
}
rect.MoveBy(FloatPoint(-layer_offset.x(), -layer_offset.y()));
non_fast_scrollable_regions_in_layer_space.Union(
- (gfx::Rect)EnclosingIntRect(rect.Rect()));
+ EnclosingIntRect(rect.Rect()));
}
layer->SetNonFastScrollableRegion(non_fast_scrollable_regions_in_layer_space);
}
@@ -436,53 +457,111 @@ PaintArtifactCompositor::PendingLayer::PendingLayer(
paint_chunk_indices.push_back(chunk_index);
}
-void PaintArtifactCompositor::PendingLayer::Merge(const PendingLayer& guest) {
- DCHECK(compositing_type != kRequiresOwnLayer &&
- guest.compositing_type != kRequiresOwnLayer);
- paint_chunk_indices.AppendVector(guest.paint_chunk_indices);
- FloatClipRect guest_bounds_in_home(guest.bounds);
- GeometryMapper::LocalToAncestorVisualRect(
- guest.property_tree_state, property_tree_state, guest_bounds_in_home);
- bounds.Unite(guest_bounds_in_home.Rect());
- // TODO(crbug.com/701991): Upgrade GeometryMapper.
- // If we knew the new bounds is enclosed by the mapped opaque region of
- // the guest layer, we can deduce the merged layer being opaque too, and
- // update rect_known_to_be_opaque accordingly.
+FloatRect PaintArtifactCompositor::PendingLayer::UniteRectsKnownToBeOpaque(
+ const FloatRect& a,
+ const FloatRect& b) {
+ // Check a or b by itself.
+ FloatRect maximum(a);
+ float maximum_area = a.Size().Area();
+ if (b.Size().Area() > maximum_area) {
+ maximum = b;
+ maximum_area = b.Size().Area();
+ }
+ // Check the regions that include the intersection of a and b. This can be
+ // done by taking the intersection and expanding it vertically and
+ // horizontally. These expanded intersections will both still be fully opaque.
+ FloatRect intersection = a;
+ intersection.InclusiveIntersect(b);
+ if (!intersection.IsZero()) {
+ FloatRect vert_expanded_intersection(intersection);
+ vert_expanded_intersection.ShiftYEdgeTo(std::min(a.Y(), b.Y()));
+ vert_expanded_intersection.ShiftMaxYEdgeTo(std::max(a.MaxY(), b.MaxY()));
+ if (vert_expanded_intersection.Size().Area() > maximum_area) {
+ maximum = vert_expanded_intersection;
+ maximum_area = vert_expanded_intersection.Size().Area();
+ }
+ FloatRect horiz_expanded_intersection(intersection);
+ horiz_expanded_intersection.ShiftXEdgeTo(std::min(a.X(), b.X()));
+ horiz_expanded_intersection.ShiftMaxXEdgeTo(std::max(a.MaxX(), b.MaxX()));
+ if (horiz_expanded_intersection.Size().Area() > maximum_area) {
+ maximum = horiz_expanded_intersection;
+ maximum_area = horiz_expanded_intersection.Size().Area();
+ }
+ }
+ return maximum;
}
-static bool CanUpcastTo(const PropertyTreeState& guest,
- const PropertyTreeState& home);
+FloatRect PaintArtifactCompositor::PendingLayer::MapRectKnownToBeOpaque(
+ const PropertyTreeState& new_state) const {
+ if (rect_known_to_be_opaque.IsEmpty())
+ return FloatRect();
-bool PaintArtifactCompositor::PendingLayer::CanMerge(
- const PendingLayer& guest,
- const PropertyTreeState& guest_state) const {
- if (compositing_type == kRequiresOwnLayer ||
- guest.compositing_type == kRequiresOwnLayer) {
- return false;
+ FloatClipRect float_clip_rect(rect_known_to_be_opaque);
+ GeometryMapper::LocalToAncestorVisualRect(property_tree_state, new_state,
+ float_clip_rect);
+ return float_clip_rect.IsTight() ? float_clip_rect.Rect() : FloatRect();
+}
+
+std::unique_ptr<JSONObject> PaintArtifactCompositor::PendingLayer::ToJSON(
+ const PaintArtifact* paint_artifact) const {
+ std::unique_ptr<JSONObject> result = std::make_unique<JSONObject>();
+ result->SetArray("bounds", RectAsJSONArray(bounds));
+ result->SetArray("rect_known_to_be_opaque",
+ RectAsJSONArray(rect_known_to_be_opaque));
+ result->SetObject("property_tree_state", property_tree_state.ToJSON());
+ result->SetArray("offset_of_decomposited_transforms",
+ PointAsJSONArray(offset_of_decomposited_transforms));
+ std::unique_ptr<JSONArray> chunks = std::make_unique<JSONArray>();
+ for (wtf_size_t chunk_index : paint_chunk_indices) {
+ if (paint_artifact) {
+ StringBuilder sb;
+ sb.AppendFormat("index=%i ", chunk_index);
+ sb.Append(paint_artifact->PaintChunks()[chunk_index].ToString());
+ chunks->PushString(sb.ToString());
+ } else {
+ chunks->PushInteger(chunk_index);
+ }
}
- if (&property_tree_state.Effect().Unalias() !=
- &guest_state.Effect().Unalias()) {
+ result->SetArray("paint_chunks", std::move(chunks));
+ return result;
+}
+
+FloatRect PaintArtifactCompositor::PendingLayer::VisualRectForOverlapTesting()
+ const {
+ FloatClipRect visual_rect(bounds);
+ GeometryMapper::LocalToAncestorVisualRect(
+ property_tree_state, PropertyTreeState::Root(), visual_rect,
+ kIgnorePlatformOverlayScrollbarSize, kNonInclusiveIntersect,
+ kExpandVisualRectForAnimation);
+ return visual_rect.Rect();
+}
+
+bool PaintArtifactCompositor::PendingLayer::Merge(const PendingLayer& guest) {
+ PropertyTreeState new_state = PropertyTreeState::Uninitialized();
+ if (!CanMerge(guest, guest.property_tree_state, &new_state, &bounds))
return false;
- }
- return CanUpcastTo(guest_state, property_tree_state);
+
+ paint_chunk_indices.AppendVector(guest.paint_chunk_indices);
+ rect_known_to_be_opaque =
+ UniteRectsKnownToBeOpaque(MapRectKnownToBeOpaque(new_state),
+ guest.MapRectKnownToBeOpaque(new_state));
+ property_tree_state = new_state;
+ return true;
}
void PaintArtifactCompositor::PendingLayer::Upcast(
const PropertyTreeState& new_state) {
DCHECK(compositing_type != kRequiresOwnLayer);
+ if (property_tree_state == new_state)
+ return;
+
FloatClipRect float_clip_rect(bounds);
GeometryMapper::LocalToAncestorVisualRect(property_tree_state, new_state,
float_clip_rect);
bounds = float_clip_rect.Rect();
+ rect_known_to_be_opaque = MapRectKnownToBeOpaque(new_state);
property_tree_state = new_state;
- // TODO(crbug.com/701991): Upgrade GeometryMapper.
- // A local visual rect mapped to an ancestor space may become a polygon
- // (e.g. consider transformed clip), also effects may affect the opaque
- // region. To determine whether the layer is still opaque, we need to
- // query conservative opaque rect after mapping to an ancestor space,
- // which is not supported by GeometryMapper yet.
- rect_known_to_be_opaque = FloatRect();
}
const PaintChunk& PaintArtifactCompositor::PendingLayer::FirstPaintChunk(
@@ -490,55 +569,127 @@ const PaintChunk& PaintArtifactCompositor::PendingLayer::FirstPaintChunk(
return paint_artifact.PaintChunks()[paint_chunk_indices[0]];
}
-static bool IsNonCompositingAncestorOf(
- const TransformPaintPropertyNode& unaliased_ancestor,
- const TransformPaintPropertyNode& node) {
- for (const auto* n = &node; n != &unaliased_ancestor;
+static bool HasCompositedTransformToAncestor(
+ const TransformPaintPropertyNode& node,
+ const TransformPaintPropertyNode& unaliased_ancestor) {
+ for (const auto* n = &node.Unalias(); n != &unaliased_ancestor;
n = SafeUnalias(n->Parent())) {
- if (!n || n->HasDirectCompositingReasons())
- return false;
+ if (n->HasDirectCompositingReasons())
+ return true;
}
- return true;
+ return false;
+}
+
+// Returns the lowest common ancestor if there is no composited transform
+// between the two transforms.
+static const TransformPaintPropertyNode* NonCompositedLowestCommonAncestor(
+ const TransformPaintPropertyNode& transform1,
+ const TransformPaintPropertyNode& transform2) {
+ const auto& lca = LowestCommonAncestor(transform1, transform2).Unalias();
+ if (HasCompositedTransformToAncestor(transform1, lca) ||
+ HasCompositedTransformToAncestor(transform2, lca))
+ return nullptr;
+ return &lca;
+}
+
+static bool ClipChainHasCompositedTransformTo(
+ const ClipPaintPropertyNode& node,
+ const ClipPaintPropertyNode& unaliased_ancestor,
+ const TransformPaintPropertyNode& transform) {
+ for (const auto* n = &node.Unalias(); n != &unaliased_ancestor;
+ n = SafeUnalias(n->Parent())) {
+ if (!NonCompositedLowestCommonAncestor(n->LocalTransformSpace(), transform))
+ return true;
+ }
+ return false;
}
// Determines whether drawings based on the 'guest' state can be painted into
-// a layer with the 'home' state. A number of criteria need to be met:
+// a layer with the 'home' state, and if yes, returns the common ancestor state
+// to which both layer will be upcasted.
+// A number of criteria need to be met:
// 1. The guest effect must be a descendant of the home effect. However this
// check is enforced by the layerization recursion. Here we assume the
// guest has already been upcasted to the same effect.
// 2. The guest transform and the home transform have compatible backface
// visibility.
-// 3. The guest clip must be a descendant of the home clip.
+// 3. The guest transform space must be within compositing boundary of the home
+// transform space.
// 4. The local space of each clip and effect node on the ancestor chain must
// be within compositing boundary of the home transform space.
-// 5. The guest transform space must be within compositing boundary of the
-// home
-// transform space.
-static bool CanUpcastTo(const PropertyTreeState& guest,
- const PropertyTreeState& home) {
+base::Optional<PropertyTreeState> CanUpcastWith(const PropertyTreeState& guest,
+ const PropertyTreeState& home) {
DCHECK_EQ(&home.Effect().Unalias(), &guest.Effect().Unalias());
if (home.Transform().IsBackfaceHidden() !=
guest.Transform().IsBackfaceHidden())
+ return base::nullopt;
+
+ auto* upcast_transform =
+ NonCompositedLowestCommonAncestor(home.Transform(), guest.Transform());
+ if (!upcast_transform)
+ return base::nullopt;
+
+ const auto& clip_lca =
+ LowestCommonAncestor(home.Clip(), guest.Clip()).Unalias();
+ if (ClipChainHasCompositedTransformTo(home.Clip(), clip_lca,
+ *upcast_transform) ||
+ ClipChainHasCompositedTransformTo(guest.Clip(), clip_lca,
+ *upcast_transform))
+ return base::nullopt;
+
+ return PropertyTreeState(*upcast_transform, clip_lca, home.Effect());
+}
+
+// We will only allow merging if the merged-area:home-area+guest-area doesn't
+// exceed the ratio |kMergingSparsityTolerance|:1.
+static constexpr float kMergeSparsityTolerance = 6;
+
+bool PaintArtifactCompositor::PendingLayer::CanMerge(
+ const PendingLayer& guest,
+ const PropertyTreeState& guest_state,
+ PropertyTreeState* out_merged_state,
+ FloatRect* out_merged_bounds) const {
+ if (compositing_type == kRequiresOwnLayer ||
+ guest.compositing_type == kRequiresOwnLayer) {
return false;
+ }
+ if (&property_tree_state.Effect().Unalias() !=
+ &guest_state.Effect().Unalias()) {
+ return false;
+ }
- const auto& home_clip = home.Clip().Unalias();
- for (const auto* current_clip = &guest.Clip().Unalias();
- current_clip != &home_clip;
- current_clip = SafeUnalias(current_clip->Parent())) {
- // If we had direct compositing reasons on a clip node, we would want to
- // return false here.
- if (!current_clip)
- return false;
- if (!IsNonCompositingAncestorOf(
- home.Transform().Unalias(),
- current_clip->LocalTransformSpace().Unalias())) {
+ const base::Optional<PropertyTreeState>& merged_state =
+ CanUpcastWith(guest_state, property_tree_state);
+ if (!merged_state)
+ return false;
+
+ FloatClipRect new_home_bounds(bounds);
+ GeometryMapper::LocalToAncestorVisualRect(property_tree_state, *merged_state,
+ new_home_bounds);
+ FloatClipRect new_guest_bounds(guest.bounds);
+ GeometryMapper::LocalToAncestorVisualRect(guest_state, *merged_state,
+ new_guest_bounds);
+
+ FloatRect merged_bounds =
+ UnionRect(new_home_bounds.Rect(), new_guest_bounds.Rect());
+ // Don't check for sparcity if we may further decomposite the effect, so that
+ // the merged layer may be merged to other layers with the decomposited
+ // effect, which is often better than not merging even if the merged layer is
+ // sparse because we may create less composited effects and render surfaces.
+ if (guest_state.Effect().IsRoot() ||
+ guest_state.Effect().HasDirectCompositingReasons()) {
+ float sum_area = new_home_bounds.Rect().Size().Area() +
+ new_guest_bounds.Rect().Size().Area();
+ if (merged_bounds.Size().Area() > kMergeSparsityTolerance * sum_area)
return false;
- }
}
- return IsNonCompositingAncestorOf(home.Transform().Unalias(),
- guest.Transform().Unalias());
+ if (out_merged_state)
+ *out_merged_state = *merged_state;
+ if (out_merged_bounds)
+ *out_merged_bounds = merged_bounds;
+ return true;
}
// Returns nullptr if 'ancestor' is not a strict ancestor of 'node'.
@@ -559,21 +710,15 @@ static const EffectPaintPropertyNode* StrictUnaliasedChildOfAlongPath(
bool PaintArtifactCompositor::MightOverlap(const PendingLayer& layer_a,
const PendingLayer& layer_b) {
- FloatClipRect bounds_a(layer_a.bounds);
- GeometryMapper::LocalToAncestorVisualRect(
- layer_a.property_tree_state, PropertyTreeState::Root(), bounds_a);
- FloatClipRect bounds_b(layer_b.bounds);
- GeometryMapper::LocalToAncestorVisualRect(
- layer_b.property_tree_state, PropertyTreeState::Root(), bounds_b);
-
- return bounds_a.Rect().Intersects(bounds_b.Rect());
+ return layer_a.VisualRectForOverlapTesting().Intersects(
+ layer_b.VisualRectForOverlapTesting());
}
bool PaintArtifactCompositor::DecompositeEffect(
const EffectPaintPropertyNode& unaliased_parent_effect,
- size_t first_layer_in_parent_group_index,
+ wtf_size_t first_layer_in_parent_group_index,
const EffectPaintPropertyNode& unaliased_effect,
- size_t layer_index) {
+ wtf_size_t layer_index) {
// The layer must be the last layer in pending_layers_.
DCHECK_EQ(layer_index, pending_layers_.size() - 1);
@@ -593,24 +738,29 @@ bool PaintArtifactCompositor::DecompositeEffect(
? *unaliased_effect.OutputClip()
: layer.property_tree_state.Clip(),
unaliased_effect);
- if (!CanUpcastTo(layer.property_tree_state, group_state))
+ base::Optional<PropertyTreeState> upcast_state =
+ CanUpcastWith(layer.property_tree_state, group_state);
+ if (!upcast_state)
return false;
- PropertyTreeState upcast_state = group_state;
- upcast_state.SetEffect(unaliased_parent_effect);
+ upcast_state->SetEffect(unaliased_parent_effect);
// Exotic blending layer can be decomposited only if its parent group
- // (which defines the scope of the blending) has only one layer before it,
+ // (which defines the scope of the blending) has zero or one layer before it,
// and it can be merged into that layer.
if (unaliased_effect.BlendMode() != SkBlendMode::kSrcOver) {
- if (layer_index - 1 != first_layer_in_parent_group_index)
- return false;
- if (!pending_layers_[first_layer_in_parent_group_index].CanMerge(
- layer, upcast_state))
- return false;
+ auto num_previous_siblings =
+ layer_index - first_layer_in_parent_group_index;
+ if (num_previous_siblings) {
+ if (num_previous_siblings > 1)
+ return false;
+ if (!pending_layers_[first_layer_in_parent_group_index].CanMerge(
+ layer, *upcast_state))
+ return false;
+ }
}
- layer.Upcast(upcast_state);
+ layer.Upcast(*upcast_state);
return true;
}
@@ -657,13 +807,12 @@ static bool SkipGroupIfEffectivelyInvisible(
return true;
}
-static bool IsCompositedScrollHitTest(const DisplayItem& item) {
- if (!item.IsScrollHitTest())
+static bool IsCompositedScrollHitTest(const PaintChunk& chunk) {
+ if (!chunk.hit_test_data)
return false;
- const auto* scroll_offset_node =
- static_cast<const ScrollHitTestDisplayItem&>(item).scroll_offset_node();
- return scroll_offset_node &&
- scroll_offset_node->HasDirectCompositingReasons();
+ const auto* scroll_translation = chunk.hit_test_data->scroll_translation;
+ return scroll_translation &&
+ scroll_translation->HasDirectCompositingReasons();
}
static bool IsCompositedScrollbar(const DisplayItem& item) {
@@ -697,10 +846,10 @@ void PaintArtifactCompositor::LayerizeGroup(
// Every paint chunk will be visited by the main loop below for exactly
// once, except for chunks that enter or exit groups (case B & C below). For
// normal chunk visit (case A), the only cost is determining squash, which
- // costs O(qd), where d came from "canUpcastTo" and geometry mapping.
+ // costs O(qd), where d came from |CanUpcastWith| and geometry mapping.
// Subtotal: O(pqd)
// For group entering and exiting, it could cost O(d) for each group, for
- // searching the shallowest subgroup (strictChildOfAlongPath), thus O(d^2)
+ // searching the shallowest subgroup (StrictChildOfAlongPath), thus O(d^2)
// in total.
// Also when exiting group, the group may be decomposited and squashed to a
// previous layer. Again finding the host costs O(qd). Merging would cost
@@ -714,12 +863,17 @@ void PaintArtifactCompositor::LayerizeGroup(
const auto& chunk_effect = chunk_it->properties.Effect().Unalias();
if (&chunk_effect == &unaliased_group) {
// Case A: The next chunk belongs to the current group but no subgroup.
- const auto& first_display_item =
- paint_artifact.GetDisplayItemList()[chunk_it->begin_index];
- bool requires_own_layer = first_display_item.IsForeignLayer() ||
- IsCompositedScrollHitTest(first_display_item) ||
- IsCompositedScrollbar(first_display_item);
- DCHECK(!requires_own_layer || chunk_it->size() == 1u);
+ bool requires_own_layer = false;
+ if (IsCompositedScrollHitTest(*chunk_it)) {
+ requires_own_layer = true;
+ } else if (chunk_it->size()) {
+ const auto& first_display_item =
+ paint_artifact.GetDisplayItemList()[chunk_it->begin_index];
+ requires_own_layer = first_display_item.IsForeignLayer() ||
+ first_display_item.IsGraphicsLayerWrapper() ||
+ IsCompositedScrollbar(first_display_item);
+ }
+ DCHECK(!requires_own_layer || chunk_it->size() <= 1u);
pending_layers_.emplace_back(
*chunk_it, chunk_it - paint_artifact.PaintChunks().begin(),
@@ -761,8 +915,7 @@ void PaintArtifactCompositor::LayerizeGroup(
for (wtf_size_t candidate_index = pending_layers_.size() - 1;
candidate_index-- > first_layer_in_current_group;) {
PendingLayer& candidate_layer = pending_layers_[candidate_index];
- if (candidate_layer.CanMerge(new_layer, new_layer.property_tree_state)) {
- candidate_layer.Merge(new_layer);
+ if (candidate_layer.Merge(new_layer)) {
pending_layers_.pop_back();
break;
}
@@ -788,8 +941,8 @@ void PaintArtifactCompositor::CollectPendingLayers(
}
void SynthesizedClip::UpdateLayer(bool needs_layer,
- const FloatRoundedRect& rrect,
- scoped_refptr<const RefCountedPath> path) {
+ const ClipPaintPropertyNode& clip,
+ const TransformPaintPropertyNode& transform) {
if (!needs_layer) {
layer_.reset();
return;
@@ -799,33 +952,40 @@ void SynthesizedClip::UpdateLayer(bool needs_layer,
layer_->SetIsDrawable(true);
}
- IntRect layer_bounds = EnclosingIntRect(rrect.Rect());
- gfx::Vector2dF new_layer_origin(layer_bounds.X(), layer_bounds.Y());
-
- SkRRect new_local_rrect = rrect;
- new_local_rrect.offset(-new_layer_origin.x(), -new_layer_origin.y());
-
- bool path_in_layer_changed = false;
- if (path_ == path) {
- path_in_layer_changed = path && layer_origin_ != new_layer_origin;
- } else if (!path_ || !path) {
- path_in_layer_changed = true;
+ const RefCountedPath* path = clip.ClipPath();
+ SkRRect new_rrect = clip.PixelSnappedClipRect();
+ IntRect layer_bounds = EnclosingIntRect(clip.PixelSnappedClipRect().Rect());
+ bool needs_display = false;
+
+ auto new_translation_2d_or_matrix =
+ GeometryMapper::SourceToDestinationProjection(clip.LocalTransformSpace(),
+ transform);
+ new_translation_2d_or_matrix.MapRect(layer_bounds);
+ new_translation_2d_or_matrix.PostTranslate(-layer_bounds.X(),
+ -layer_bounds.Y());
+
+ if (!path && new_translation_2d_or_matrix.IsIdentityOr2DTranslation()) {
+ const auto& translation = new_translation_2d_or_matrix.Translation2D();
+ new_rrect.offset(translation.Width(), translation.Height());
+ needs_display = !rrect_is_local_ || new_rrect != rrect_;
+ translation_2d_or_matrix_ = GeometryMapper::Translation2DOrMatrix();
+ rrect_is_local_ = true;
} else {
- SkPath new_path = path->GetSkPath();
- new_path.offset(layer_origin_.x() - new_layer_origin.x(),
- layer_origin_.y() - new_layer_origin.y());
- path_in_layer_changed = path_->GetSkPath() != new_path;
+ needs_display = rrect_is_local_ || new_rrect != rrect_ ||
+ new_translation_2d_or_matrix != translation_2d_or_matrix_ ||
+ (path_ != path && (!path_ || !path || *path_ != *path));
+ translation_2d_or_matrix_ = new_translation_2d_or_matrix;
+ rrect_is_local_ = false;
}
- if (local_rrect_ != new_local_rrect || path_in_layer_changed) {
+ if (needs_display)
layer_->SetNeedsDisplay();
- }
- layer_->SetOffsetToTransformParent(new_layer_origin);
- layer_->SetBounds(gfx::Size(layer_bounds.Width(), layer_bounds.Height()));
- layer_origin_ = new_layer_origin;
- local_rrect_ = new_local_rrect;
- path_ = std::move(path);
+ layer_->SetOffsetToTransformParent(
+ gfx::Vector2dF(layer_bounds.X(), layer_bounds.Y()));
+ layer_->SetBounds(gfx::Size(layer_bounds.Size()));
+ rrect_ = new_rrect;
+ path_ = path;
}
scoped_refptr<cc::DisplayItemList> SynthesizedClip::PaintContentsToDisplayList(
@@ -835,16 +995,22 @@ scoped_refptr<cc::DisplayItemList> SynthesizedClip::PaintContentsToDisplayList(
PaintFlags flags;
flags.setAntiAlias(true);
cc_list->StartPaint();
- if (!path_) {
- cc_list->push<cc::DrawRRectOp>(local_rrect_, flags);
+ if (rrect_is_local_) {
+ cc_list->push<cc::DrawRRectOp>(rrect_, flags);
} else {
cc_list->push<cc::SaveOp>();
- cc_list->push<cc::TranslateOp>(-layer_origin_.x(), -layer_origin_.y());
- cc_list->push<cc::ClipPathOp>(path_->GetSkPath(), SkClipOp::kIntersect,
- true);
- SkRRect rrect = local_rrect_;
- rrect.offset(layer_origin_.x(), layer_origin_.y());
- cc_list->push<cc::DrawRRectOp>(rrect, flags);
+ if (translation_2d_or_matrix_.IsIdentityOr2DTranslation()) {
+ const auto& translation = translation_2d_or_matrix_.Translation2D();
+ cc_list->push<cc::TranslateOp>(translation.Width(), translation.Height());
+ } else {
+ cc_list->push<cc::ConcatOp>(SkMatrix(TransformationMatrix::ToSkMatrix44(
+ translation_2d_or_matrix_.Matrix())));
+ }
+ if (path_) {
+ cc_list->push<cc::ClipPathOp>(path_->GetSkPath(), SkClipOp::kIntersect,
+ true);
+ }
+ cc_list->push<cc::DrawRRectOp>(rrect_, flags);
cc_list->push<cc::RestoreOp>();
}
cc_list->EndPaintOfUnpaired(gfx::Rect(layer_->bounds()));
@@ -853,26 +1019,26 @@ scoped_refptr<cc::DisplayItemList> SynthesizedClip::PaintContentsToDisplayList(
}
SynthesizedClip& PaintArtifactCompositor::CreateOrReuseSynthesizedClipLayer(
- const ClipPaintPropertyNode& node,
+ const ClipPaintPropertyNode& clip,
+ const TransformPaintPropertyNode& transform,
bool needs_layer,
CompositorElementId& mask_isolation_id,
CompositorElementId& mask_effect_id) {
auto* entry =
std::find_if(synthesized_clip_cache_.begin(),
- synthesized_clip_cache_.end(), [&node](const auto& entry) {
- return entry.key == &node && !entry.in_use;
+ synthesized_clip_cache_.end(), [&clip](const auto& entry) {
+ return entry.key == &clip && !entry.in_use;
});
if (entry == synthesized_clip_cache_.end()) {
- auto clip = std::make_unique<SynthesizedClip>();
- synthesized_clip_cache_.push_back(
- SynthesizedClipEntry{&node, std::move(clip), false});
+ synthesized_clip_cache_.push_back(SynthesizedClipEntry{
+ &clip, std::make_unique<SynthesizedClip>(), false});
entry = synthesized_clip_cache_.end() - 1;
}
entry->in_use = true;
SynthesizedClip& synthesized_clip = *entry->synthesized_clip;
if (needs_layer) {
- synthesized_clip.UpdateLayer(needs_layer, node.ClipRect(), node.ClipPath());
+ synthesized_clip.UpdateLayer(needs_layer, clip, transform);
synthesized_clip.Layer()->SetLayerTreeHost(root_layer_->layer_tree_host());
}
mask_isolation_id = synthesized_clip.GetMaskIsolationId();
@@ -903,14 +1069,14 @@ static void UpdateCompositorViewportProperties(
*properties.page_scale);
}
if (properties.inner_scroll_translation) {
- ids.inner_scroll = property_tree_manager.EnsureCompositorScrollNode(
+ ids.inner_scroll = property_tree_manager.EnsureCompositorInnerScrollNode(
*properties.inner_scroll_translation);
if (properties.outer_clip) {
ids.outer_clip = property_tree_manager.EnsureCompositorClipNode(
*properties.outer_clip);
}
if (properties.outer_scroll_translation) {
- ids.outer_scroll = property_tree_manager.EnsureCompositorScrollNode(
+ ids.outer_scroll = property_tree_manager.EnsureCompositorOuterScrollNode(
*properties.outer_scroll_translation);
}
}
@@ -995,11 +1161,9 @@ void PaintArtifactCompositor::DecompositeTransforms(
// The scroll translation node of a scroll hit test layer may not be
// referenced by any pending layer's property tree state. Disallow
// decomposition of it (and its ancestors).
- if (const auto* scroll_hit_test =
- ScrollHitTestForLayer(paint_artifact, pending_layer)) {
- if (const auto* scroll_offset = scroll_hit_test->scroll_offset)
- mark_not_decompositable(scroll_offset);
- }
+ if (const auto* scroll_translation =
+ ScrollTranslationForLayer(paint_artifact, pending_layer))
+ mark_not_decompositable(scroll_translation);
}
}
@@ -1053,7 +1217,6 @@ void PaintArtifactCompositor::Update(
Vector<std::unique_ptr<ContentLayerClientImpl>> new_content_layer_clients;
new_content_layer_clients.ReserveCapacity(pending_layers_.size());
Vector<scoped_refptr<cc::Layer>> new_scroll_hit_test_layers;
- Vector<scoped_refptr<cc::Layer>> new_scrollbar_layers;
// Maps from cc effect id to blink effects. Containing only the effects
// having composited layers.
@@ -1074,7 +1237,7 @@ void PaintArtifactCompositor::Update(
if (&clip.LocalTransformSpace() == &transform) {
// Limit layer bounds to hide the areas that will be never visible
// because of the clip.
- pending_layer.bounds.Intersect(clip.ClipRect().Rect());
+ pending_layer.bounds.Intersect(clip.PixelSnappedClipRect().Rect());
} else if (const auto* scroll = transform.ScrollNode()) {
// Limit layer bounds to the scroll range to hide the areas that will
// never be scrolled into the visible area.
@@ -1084,7 +1247,7 @@ void PaintArtifactCompositor::Update(
scoped_refptr<cc::Layer> layer = CompositedLayerForPendingLayer(
paint_artifact, pending_layer, new_content_layer_clients,
- new_scroll_hit_test_layers, new_scrollbar_layers);
+ new_scroll_hit_test_layers);
// In Pre-CompositeAfterPaint, touch action rects and non-fast scrollable
// regions are updated through ScrollingCoordinator.
@@ -1093,9 +1256,9 @@ void PaintArtifactCompositor::Update(
pending_layer.paint_chunk_indices);
UpdateTouchActionRects(layer.get(), layer->offset_to_transform_parent(),
property_state, paint_chunks);
- UpdateNonFastScrollableRegions(layer.get(),
- layer->offset_to_transform_parent(),
- property_state, paint_chunks);
+ UpdateNonFastScrollableRegions(
+ layer.get(), layer->offset_to_transform_parent(), property_state,
+ paint_chunks, &property_tree_manager);
}
layer->SetLayerTreeHost(root_layer_->layer_tree_host());
@@ -1110,7 +1273,7 @@ void PaintArtifactCompositor::Update(
// The compositor scroll node is not directly stored in the property tree
// state but can be created via the scroll offset translation node.
const auto& scroll_translation =
- ScrollOffsetTranslationForLayer(*paint_artifact, pending_layer);
+ NearestScrollTranslationForLayer(*paint_artifact, pending_layer);
int scroll_id =
property_tree_manager.EnsureCompositorScrollNode(scroll_translation);
@@ -1125,6 +1288,9 @@ void PaintArtifactCompositor::Update(
bool backface_hidden = property_state.Transform().IsBackfaceHidden();
layer->SetDoubleSided(!backface_hidden);
layer->SetShouldCheckBackfaceVisibility(backface_hidden);
+ bool has_will_change_transform =
+ property_state.Transform().RequiresCompositingForWillChangeTransform();
+ layer->SetHasWillChangeTransformHint(has_will_change_transform);
// If the property tree state has changed between the layer and the root,
// we need to inform the compositor so damage can be calculated. Calling
@@ -1164,7 +1330,6 @@ void PaintArtifactCompositor::Update(
property_tree_manager.Finalize();
content_layer_clients_.swap(new_content_layer_clients);
scroll_hit_test_layers_.swap(new_scroll_hit_test_layers);
- scrollbar_layers_.swap(new_scrollbar_layers);
auto pos = std::remove_if(synthesized_clip_cache_.begin(),
synthesized_clip_cache_.end(),
@@ -1207,20 +1372,14 @@ void PaintArtifactCompositor::Update(
#endif
}
-cc::PropertyTrees* PaintArtifactCompositor::GetPropertyTreesForDirectUpdate() {
+bool PaintArtifactCompositor::CanDirectlyUpdateProperties() const {
// Don't try to retrieve property trees if we need an update. The full
// update will update all of the nodes, so a direct update doesn't need to
// do anything.
if (needs_update_)
- return nullptr;
-
- if (!root_layer_)
- return nullptr;
+ return false;
- auto* host = root_layer_->layer_tree_host();
- if (!host)
- return nullptr;
- return host->property_trees();
+ return root_layer_ && root_layer_->layer_tree_host();
}
bool PaintArtifactCompositor::DirectlyUpdateCompositedOpacityValue(
@@ -1228,9 +1387,9 @@ bool PaintArtifactCompositor::DirectlyUpdateCompositedOpacityValue(
// We can only directly-update compositor values if all content associated
// with the node is known to be composited.
DCHECK(effect.HasDirectCompositingReasons());
- if (auto* property_trees = GetPropertyTreesForDirectUpdate()) {
+ if (CanDirectlyUpdateProperties()) {
return PropertyTreeManager::DirectlyUpdateCompositedOpacityValue(
- property_trees, *root_layer_->layer_tree_host(), effect);
+ *root_layer_->layer_tree_host(), effect);
}
return false;
}
@@ -1243,9 +1402,9 @@ bool PaintArtifactCompositor::DirectlyUpdateScrollOffsetTransform(
// CompositeAfterPaint because we cannot query CompositedLayerMapping here.
DCHECK(transform.HasDirectCompositingReasons());
}
- if (auto* property_trees = GetPropertyTreesForDirectUpdate()) {
+ if (CanDirectlyUpdateProperties()) {
return PropertyTreeManager::DirectlyUpdateScrollOffsetTransform(
- property_trees, *root_layer_->layer_tree_host(), transform);
+ *root_layer_->layer_tree_host(), transform);
}
return false;
}
@@ -1255,9 +1414,9 @@ bool PaintArtifactCompositor::DirectlyUpdateTransform(
// We can only directly-update compositor values if all content associated
// with the node is known to be composited.
DCHECK(transform.HasDirectCompositingReasons());
- if (auto* property_trees = GetPropertyTreesForDirectUpdate()) {
+ if (CanDirectlyUpdateProperties()) {
return PropertyTreeManager::DirectlyUpdateTransform(
- property_trees, *root_layer_->layer_tree_host(), transform);
+ *root_layer_->layer_tree_host(), transform);
}
return false;
}
@@ -1267,13 +1426,27 @@ bool PaintArtifactCompositor::DirectlyUpdatePageScaleTransform(
// We can only directly-update compositor values if all content associated
// with the node is known to be composited.
DCHECK(transform.HasDirectCompositingReasons());
- if (auto* property_trees = GetPropertyTreesForDirectUpdate()) {
+ if (CanDirectlyUpdateProperties()) {
return PropertyTreeManager::DirectlyUpdatePageScaleTransform(
- property_trees, *root_layer_->layer_tree_host(), transform);
+ *root_layer_->layer_tree_host(), transform);
}
return false;
}
+bool PaintArtifactCompositor::DirectlySetScrollOffset(
+ CompositorElementId element_id,
+ const FloatPoint& scroll_offset) {
+ if (!root_layer_ || !root_layer_->layer_tree_host())
+ return false;
+ auto* property_trees = root_layer_->layer_tree_host()->property_trees();
+ if (!property_trees->element_id_to_scroll_node_index.contains(element_id))
+ return false;
+ PropertyTreeManager::DirectlySetScrollOffset(
+ *root_layer_->layer_tree_host(), element_id,
+ gfx::ScrollOffset(scroll_offset));
+ return true;
+}
+
static cc::RenderSurfaceReason GetRenderSurfaceCandidateReason(
const cc::EffectNode& effect,
const Vector<const EffectPaintPropertyNode*>& blink_effects) {
@@ -1283,7 +1456,7 @@ static cc::RenderSurfaceReason GetRenderSurfaceCandidateReason(
return cc::RenderSurfaceReason::kBlendModeDstIn;
if (effect.opacity != 1.f)
return cc::RenderSurfaceReason::kOpacity;
- if (static_cast<size_t>(effect.id) < blink_effects.size() &&
+ if (static_cast<wtf_size_t>(effect.id) < blink_effects.size() &&
blink_effects[effect.id] &&
blink_effects[effect.id]->HasActiveOpacityAnimation())
return cc::RenderSurfaceReason::kOpacityAnimation;
@@ -1379,6 +1552,8 @@ void PaintArtifactCompositor::UpdateLayerDebugInfo(
debug_info.compositing_reasons =
CompositingReason::Descriptions(compositing_reasons);
+ debug_info.compositing_reason_ids =
+ CompositingReason::ShortNames(compositing_reasons);
debug_info.owner_node_id = id.client.OwnerNodeId();
if (RasterInvalidationTracking::IsTracingRasterInvalidations() &&
@@ -1398,9 +1573,11 @@ CompositingReasons PaintArtifactCompositor::GetCompositingReasons(
return CompositingReason::kOverlap;
if (layer.compositing_type == PendingLayer::kRequiresOwnLayer) {
+ const auto& first_chunk = layer.FirstPaintChunk(paint_artifact);
+ if (IsCompositedScrollHitTest(first_chunk))
+ return CompositingReason::kOverflowScrolling;
const auto& display_item =
- paint_artifact.GetDisplayItemList()
- [layer.FirstPaintChunk(paint_artifact).begin_index];
+ paint_artifact.GetDisplayItemList()[first_chunk.begin_index];
switch (display_item.GetType()) {
case DisplayItem::kForeignLayerCanvas:
return CompositingReason::kCanvas;
@@ -1408,8 +1585,6 @@ CompositingReasons PaintArtifactCompositor::GetCompositingReasons(
return CompositingReason::kPlugin;
case DisplayItem::kForeignLayerVideo:
return CompositingReason::kVideo;
- case DisplayItem::kScrollHitTest:
- return CompositingReason::kOverflowScrolling;
case DisplayItem::kScrollbarHorizontal:
return CompositingReason::kLayerForHorizontalScrollbar;
case DisplayItem::kScrollbarVertical:
@@ -1442,7 +1617,11 @@ Vector<cc::Layer*> PaintArtifactCompositor::SynthesizedClipLayersForTesting()
}
void LayerListBuilder::Add(scoped_refptr<cc::Layer> layer) {
+#if DCHECK_IS_ON()
DCHECK(list_valid_);
+ DCHECK(!layer_ids_.Contains(layer->id()));
+ layer_ids_.insert(layer->id());
+#endif
list_.push_back(layer);
}
@@ -1455,7 +1634,7 @@ cc::LayerList LayerListBuilder::Finalize() {
#if DCHECK_IS_ON()
void PaintArtifactCompositor::ShowDebugData() {
LOG(ERROR) << GetLayersAsJSON(kLayerTreeIncludesDebugInfo |
- kLayerTreeIncludesPaintInvalidations)
+ kLayerTreeIncludesDetailedInvalidations)
->ToPrettyJSONString()
.Utf8();
}
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 25abeddc235..766de18b6ae 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
@@ -18,10 +18,19 @@
#include "third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.h"
#include "third_party/blink/renderer/platform/graphics/compositing_reasons.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer_client.h"
+#include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
+#if DCHECK_IS_ON()
+#include "third_party/blink/renderer/platform/wtf/hash_set.h"
+#endif
+
+namespace cc {
+class ScrollbarLayerBase;
+}
+
namespace gfx {
class Vector2dF;
}
@@ -31,6 +40,7 @@ namespace blink {
class ContentLayerClientImpl;
class JSONObject;
class PaintArtifact;
+class PropertyTreeManager;
class SynthesizedClip;
struct PaintChunk;
@@ -45,6 +55,9 @@ class LayerListBuilder {
// The list becomes invalid once |Finalize| is called.
bool list_valid_ = true;
cc::LayerList list_;
+#if DCHECK_IS_ON()
+ HashSet<int> layer_ids_;
+#endif
};
// This class maintains unique stable cc effect IDs (and optionally a persistent
@@ -73,10 +86,10 @@ class SynthesizedClip : private cc::ContentLayerClient {
}
void UpdateLayer(bool needs_layer,
- const FloatRoundedRect& rrect,
- scoped_refptr<const RefCountedPath> path);
+ const ClipPaintPropertyNode&,
+ const TransformPaintPropertyNode&);
- cc::Layer* Layer() { return layer_.get(); }
+ cc::PictureLayer* Layer() { return layer_.get(); }
CompositorElementId GetMaskIsolationId() const { return mask_isolation_id_; }
CompositorElementId GetMaskEffectId() const { return mask_effect_id_; }
@@ -91,8 +104,9 @@ class SynthesizedClip : private cc::ContentLayerClient {
private:
scoped_refptr<cc::PictureLayer> layer_;
- gfx::Vector2dF layer_origin_;
- SkRRect local_rrect_ = SkRRect::MakeEmpty();
+ GeometryMapper::Translation2DOrMatrix translation_2d_or_matrix_;
+ bool rrect_is_local_ = false;
+ SkRRect rrect_;
scoped_refptr<const RefCountedPath> path_;
CompositorElementId mask_isolation_id_;
CompositorElementId mask_effect_id_;
@@ -139,6 +153,12 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
bool DirectlyUpdateTransform(const TransformPaintPropertyNode&);
bool DirectlyUpdatePageScaleTransform(const TransformPaintPropertyNode&);
+ // Directly sets cc::ScrollTree::current_scroll_offset. This doesn't affect
+ // cc::TransformNode::scroll_offset (which will be synched with blink
+ // transform node in DirectlyUpdateScrollOffsetTransform() or Update()).
+ bool DirectlySetScrollOffset(CompositorElementId,
+ const FloatPoint& scroll_offset);
+
// The root layer of the tree managed by this object.
cc::Layer* RootLayer() const { return root_layer_.get(); }
@@ -148,6 +168,9 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
// going to be removed from its frame.
void WillBeRemovedFromFrame();
+ std::unique_ptr<JSONArray> GetPendingLayersAsJSON(
+ const PaintArtifact* = nullptr) const;
+
std::unique_ptr<JSONObject> GetLayersAsJSON(
LayerTreeFlags,
const PaintArtifact* = nullptr) const;
@@ -174,7 +197,8 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
cc::Layer*,
const gfx::Vector2dF& layer_offset,
const PropertyTreeState& layer_state,
- const PaintChunkSubset& paint_chunks);
+ const PaintChunkSubset& paint_chunks,
+ PropertyTreeManager* = nullptr);
void SetNeedsUpdate() { needs_update_ = true; }
bool NeedsUpdate() const { return needs_update_; }
@@ -202,15 +226,23 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
PendingLayer(const PaintChunk& first_paint_chunk,
wtf_size_t first_chunk_index,
bool requires_own_layer);
- // Merge another pending layer after this one, appending all its paint
- // chunks after chunks in this layer, with appropriate space conversion
- // applied. The merged layer must have a property tree state that's deeper
- // than this layer, i.e. can "upcast" to this layer's state.
- void Merge(const PendingLayer& guest);
+
+ // Merges |guest| into |this| if it can, by appending chunks of |guest|
+ // after chunks of |this|, with appropriate space conversion applied to
+ // both layers from their original property tree states to |merged_state|.
+ // Returns whether the merge is successful.
+ bool Merge(const PendingLayer& guest);
+
+ // Returns true if |guest| can be merged into |this|, and sets the output
+ // paramsters with the property tree state and bounds of the merged layer.
// |guest_state| is for cases that we want to check if we can merge |guest|
- // if it has |guest_state| (which may be different from its current state).
+ // if it has |guest_state| in the future (which may be different from its
+ // current state).
bool CanMerge(const PendingLayer& guest,
- const PropertyTreeState& guest_state) const;
+ const PropertyTreeState& guest_state,
+ PropertyTreeState* merged_state = nullptr,
+ FloatRect* merged_bounds = nullptr) const;
+
// Mutate this layer's property tree state to a more general (shallower)
// state, thus the name "upcast". The concrete effect of this is to
// "decomposite" some of the properties, so that fewer properties will be
@@ -220,6 +252,15 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
const PaintChunk& FirstPaintChunk(const PaintArtifact&) const;
+ // Returns the largest rect known to be opaque given two opaque rects.
+ static FloatRect UniteRectsKnownToBeOpaque(const FloatRect&,
+ const FloatRect&);
+ FloatRect MapRectKnownToBeOpaque(const PropertyTreeState&) const;
+
+ std::unique_ptr<JSONObject> ToJSON(const PaintArtifact* = nullptr) const;
+
+ FloatRect VisualRectForOverlapTesting() const;
+
// The rects are in the space of property_tree_state.
FloatRect bounds;
FloatRect rect_known_to_be_opaque;
@@ -263,9 +304,9 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
Vector<PaintChunk>::const_iterator& chunk_cursor);
static bool MightOverlap(const PendingLayer&, const PendingLayer&);
bool DecompositeEffect(const EffectPaintPropertyNode& unaliased_parent_effect,
- size_t first_layer_in_parent_group_index,
+ wtf_size_t first_layer_in_parent_group_index,
const EffectPaintPropertyNode& unaliased_effect,
- size_t layer_index);
+ wtf_size_t layer_index);
// Builds a leaf layer that represents a single paint chunk.
scoped_refptr<cc::Layer> CompositedLayerForPendingLayer(
@@ -273,19 +314,19 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
const PendingLayer&,
Vector<std::unique_ptr<ContentLayerClientImpl>>&
new_content_layer_clients,
- Vector<scoped_refptr<cc::Layer>>& new_scroll_hit_test_layers,
- Vector<scoped_refptr<cc::Layer>>& new_scrollbar_layers);
+ Vector<scoped_refptr<cc::Layer>>& new_scroll_hit_test_layers);
bool PropertyTreeStateChanged(const PropertyTreeState&) const;
- const TransformPaintPropertyNode& ScrollOffsetTranslationForLayer(
+ const TransformPaintPropertyNode& NearestScrollTranslationForLayer(
const PaintArtifact&,
const PendingLayer&);
- // If the pending layer is a special scroll hit test layer, return the
- // associated hit test information.
- const HitTestData::ScrollHitTest* ScrollHitTestForLayer(const PaintArtifact&,
- const PendingLayer&);
+ // If the pending layer has scroll hit test data, return the associated
+ // scroll translation node.
+ const TransformPaintPropertyNode* ScrollTranslationForLayer(
+ const PaintArtifact&,
+ const PendingLayer&);
// Finds an existing or creates a new scroll hit test layer for the pending
// layer, returning nullptr if the layer is not a scroll hit test layer.
@@ -295,8 +336,9 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
// Finds an existing or creates a new scrollbar layer for the pending layer,
// returning nullptr if the layer is not a scrollbar layer.
- scoped_refptr<cc::Layer> ScrollbarLayerForPendingLayer(const PaintArtifact&,
- const PendingLayer&);
+ scoped_refptr<cc::ScrollbarLayerBase> ScrollbarLayerForPendingLayer(
+ const PaintArtifact&,
+ const PendingLayer&);
// Finds a client among the current vector of clients that matches the paint
// chunk's id, or otherwise allocates a new one.
@@ -309,6 +351,7 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
// However, |mask_isolation_id| is always set.
SynthesizedClip& CreateOrReuseSynthesizedClipLayer(
const ClipPaintPropertyNode&,
+ const TransformPaintPropertyNode&,
bool needs_layer,
CompositorElementId& mask_isolation_id,
CompositorElementId& mask_effect_id) final;
@@ -318,7 +361,7 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
const cc::LayerList&,
const Vector<const EffectPaintPropertyNode*>&);
- cc::PropertyTrees* GetPropertyTreesForDirectUpdate();
+ bool CanDirectlyUpdateProperties() const;
CompositingReasons GetCompositingReasons(const PendingLayer& layer,
const PendingLayer* previous_layer,
@@ -341,7 +384,6 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
Vector<SynthesizedClipEntry> synthesized_clip_cache_;
Vector<scoped_refptr<cc::Layer>> scroll_hit_test_layers_;
- Vector<scoped_refptr<cc::Layer>> scrollbar_layers_;
Vector<PendingLayer, 0> pending_layers_;
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 e5df1538463..34024cdd908 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
@@ -52,7 +52,7 @@ PaintChunk DefaultChunk() {
return PaintChunk(0, 1, DefaultId(), PropertyTreeState::Root());
}
-gfx::Transform Translation(SkMScalar x, SkMScalar y) {
+gfx::Transform Translation(SkScalar x, SkScalar y) {
gfx::Transform transform;
transform.Translate(x, y);
return transform;
@@ -122,7 +122,7 @@ class PaintArtifactCompositorTest : public testing::Test,
return *GetPropertyTrees().effect_tree.Node(layer->effect_tree_index());
}
- const cc::LayerTreeHost& GetLayerTreeHost() {
+ cc::LayerTreeHost& GetLayerTreeHost() {
return *layer_tree_->layer_tree_host();
}
@@ -159,12 +159,11 @@ class PaintArtifactCompositorTest : public testing::Test,
cc::Layer* RootLayer() { return paint_artifact_compositor_->RootLayer(); }
- // CompositeAfterPaint creates scroll hit test display items (which create
- // scroll hit test layers in PaintArtifactCompositor) whereas before
- // CompositeAfterPaint, scrollable foreign layers are created in
- // ScrollingCoordinator and passed to PaintArtifactCompositor. This function
- // is used to create a chunk representing the scrollable layer in either of
- // these modes.
+ // CompositeAfterPaint creates scroll hit test data (which create scroll hit
+ // test layers in PaintArtifactCompositor) whereas before CompositeAfterPaint,
+ // scrollable foreign layers are created in ScrollingCoordinator and passed
+ // to PaintArtifactCompositor. This function is used to create a chunk
+ // representing the scrollable layer in either of these modes.
void CreateScrollableChunk(TestPaintArtifact& artifact,
const TransformPaintPropertyNode& scroll_offset,
const ClipPaintPropertyNode& clip,
@@ -174,7 +173,6 @@ class PaintArtifactCompositorTest : public testing::Test,
const auto* scroll_node = scroll_offset.ScrollNode();
scoped_refptr<cc::Layer> layer = cc::Layer::Create();
auto rect = scroll_node->ContainerRect();
- layer->SetScrollable(gfx::Size(rect.Size()));
layer->SetBounds(gfx::Size(rect.Size()));
layer->SetElementId(scroll_node->GetCompositorElementId());
artifact.Chunk(scroll_offset, clip, effect)
@@ -184,8 +182,9 @@ class PaintArtifactCompositorTest : public testing::Test,
// Returns the |num|th scrollable layer. In CompositeAfterPaint, this will be
// a scroll hit test layer, whereas currently this will be a content layer.
cc::Layer* ScrollableLayerAt(size_t num) {
+ const cc::ScrollTree& scroll_tree = GetPropertyTrees().scroll_tree;
for (auto& layer : RootLayer()->children()) {
- if (layer->scrollable()) {
+ if (scroll_tree.FindNodeFromElementId(layer->element_id())) {
if (num == 0)
return layer.get();
num--;
@@ -199,8 +198,9 @@ class PaintArtifactCompositorTest : public testing::Test,
// content layers are scrollable and non-scrollable, so this will return the
// |num|th content layer that is not scrollable.
cc::Layer* NonScrollableLayerAt(size_t num) {
+ const cc::ScrollTree& scroll_tree = GetPropertyTrees().scroll_tree;
for (auto& layer : RootLayer()->children()) {
- if (!layer->scrollable()) {
+ if (!scroll_tree.FindNodeFromElementId(layer->element_id())) {
if (num == 0)
return layer.get();
num--;
@@ -240,7 +240,7 @@ class PaintArtifactCompositorTest : public testing::Test,
}
void AddSimpleRectChunk(TestPaintArtifact& artifact) {
- artifact.Chunk().RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack);
+ artifact.Chunk().RectDrawing(IntRect(100, 100, 200, 100), Color::kBlack);
}
void UpdateWithArtifactWithOpacity(float opacity,
@@ -251,7 +251,7 @@ class PaintArtifactCompositorTest : public testing::Test,
AddSimpleRectChunk(artifact);
auto effect = CreateOpacityEffect(e0(), opacity);
artifact.Chunk(t0(), c0(), *effect)
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
if (include_subsequent_chunk)
AddSimpleRectChunk(artifact);
Update(artifact.Build());
@@ -265,6 +265,10 @@ class PaintArtifactCompositorTest : public testing::Test,
MockScrollCallbacks& ScrollCallbacks() { return scroll_callbacks_; }
+ PaintArtifactCompositor& GetPaintArtifactCompositor() {
+ return *paint_artifact_compositor_;
+ }
+
private:
MockScrollCallbacks scroll_callbacks_;
std::unique_ptr<PaintArtifactCompositor> paint_artifact_compositor_;
@@ -274,7 +278,7 @@ class PaintArtifactCompositorTest : public testing::Test,
std::unique_ptr<LayerTreeHostEmbedder> layer_tree_;
};
-INSTANTIATE_LAYER_LIST_TEST_SUITE_P(PaintArtifactCompositorTest);
+INSTANTIATE_PAINT_TEST_SUITE_P(PaintArtifactCompositorTest);
const auto kNotScrollingOnMain =
cc::MainThreadScrollingReason::kNotScrollingOnMain;
@@ -286,7 +290,7 @@ TEST_P(PaintArtifactCompositorTest, EmptyPaintArtifact) {
TEST_P(PaintArtifactCompositorTest, OneChunkWithAnOffset) {
TestPaintArtifact artifact;
- artifact.Chunk().RectDrawing(FloatRect(50, -50, 100, 100), Color::kWhite);
+ artifact.Chunk().RectDrawing(IntRect(50, -50, 100, 100), Color::kWhite);
Update(artifact.Build());
ASSERT_EQ(1u, LayerCount());
@@ -307,10 +311,10 @@ TEST_P(PaintArtifactCompositorTest, OneTransform) {
TestPaintArtifact artifact;
artifact.Chunk(*transform, c0(), e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
- artifact.Chunk().RectDrawing(FloatRect(0, 0, 100, 100), Color::kGray);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite);
+ artifact.Chunk().RectDrawing(IntRect(0, 0, 100, 100), Color::kGray);
artifact.Chunk(*transform, c0(), e0())
- .RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack);
+ .RectDrawing(IntRect(100, 100, 200, 100), Color::kBlack);
Update(artifact.Build());
ASSERT_EQ(2u, LayerCount());
@@ -349,10 +353,10 @@ TEST_P(PaintArtifactCompositorTest, OneTransformWithAlias) {
TestPaintArtifact artifact;
artifact.Chunk(*transform, c0(), e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
- artifact.Chunk().RectDrawing(FloatRect(0, 0, 100, 100), Color::kGray);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite);
+ artifact.Chunk().RectDrawing(IntRect(0, 0, 100, 100), Color::kGray);
artifact.Chunk(*transform, c0(), e0())
- .RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack);
+ .RectDrawing(IntRect(100, 100, 200, 100), Color::kBlack);
Update(artifact.Build());
ASSERT_EQ(2u, LayerCount());
@@ -393,9 +397,9 @@ TEST_P(PaintArtifactCompositorTest, TransformCombining) {
TestPaintArtifact artifact;
artifact.Chunk(*transform1, c0(), e0())
- .RectDrawing(FloatRect(0, 0, 300, 200), Color::kWhite);
+ .RectDrawing(IntRect(0, 0, 300, 200), Color::kWhite);
artifact.Chunk(*transform2, c0(), e0())
- .RectDrawing(FloatRect(0, 0, 300, 200), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 300, 200), Color::kBlack);
Update(artifact.Build());
ASSERT_EQ(2u, LayerCount());
@@ -441,11 +445,11 @@ TEST_P(PaintArtifactCompositorTest, BackfaceVisibility) {
TestPaintArtifact artifact;
artifact.Chunk(*backface_hidden_transform, c0(), e0())
- .RectDrawing(FloatRect(0, 0, 300, 200), Color::kWhite);
+ .RectDrawing(IntRect(0, 0, 300, 200), Color::kWhite);
artifact.Chunk(*backface_inherited_transform, c0(), e0())
- .RectDrawing(FloatRect(100, 100, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(100, 100, 100, 100), Color::kBlack);
artifact.Chunk(*backface_visible_transform, c0(), e0())
- .RectDrawing(FloatRect(0, 0, 300, 200), Color::kDarkGray);
+ .RectDrawing(IntRect(0, 0, 300, 200), Color::kDarkGray);
Update(artifact.Build());
ASSERT_EQ(2u, LayerCount());
@@ -479,7 +483,7 @@ TEST_P(PaintArtifactCompositorTest, FlattensInheritedTransform) {
TestPaintArtifact artifact;
artifact.Chunk(*transform3, c0(), e0())
- .RectDrawing(FloatRect(0, 0, 300, 200), Color::kWhite);
+ .RectDrawing(IntRect(0, 0, 300, 200), Color::kWhite);
Update(artifact.Build());
ASSERT_EQ(1u, LayerCount());
@@ -534,7 +538,7 @@ TEST_P(PaintArtifactCompositorTest, FlattensInheritedTransformWithAlias) {
TestPaintArtifact artifact;
artifact.Chunk(*transform3, c0(), e0())
- .RectDrawing(FloatRect(0, 0, 300, 200), Color::kWhite);
+ .RectDrawing(IntRect(0, 0, 300, 200), Color::kWhite);
Update(artifact.Build());
ASSERT_EQ(1u, LayerCount());
@@ -588,13 +592,13 @@ TEST_P(PaintArtifactCompositorTest, SortingContextID) {
TestPaintArtifact artifact;
artifact.Chunk(*transform1, c0(), e0())
- .RectDrawing(FloatRect(0, 0, 300, 200), Color::kWhite);
+ .RectDrawing(IntRect(0, 0, 300, 200), Color::kWhite);
artifact.Chunk(*transform2, c0(), e0())
- .RectDrawing(FloatRect(0, 0, 300, 200), Color::kLightGray);
+ .RectDrawing(IntRect(0, 0, 300, 200), Color::kLightGray);
artifact.Chunk(*transform3, c0(), e0())
- .RectDrawing(FloatRect(0, 0, 300, 200), Color::kDarkGray);
+ .RectDrawing(IntRect(0, 0, 300, 200), Color::kDarkGray);
artifact.Chunk(*transform4, c0(), e0())
- .RectDrawing(FloatRect(0, 0, 300, 200), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 300, 200), Color::kBlack);
Update(artifact.Build());
ASSERT_EQ(4u, LayerCount());
@@ -646,7 +650,7 @@ TEST_P(PaintArtifactCompositorTest, OneClip) {
TestPaintArtifact artifact;
artifact.Chunk(t0(), *clip, e0())
- .RectDrawing(FloatRect(220, 80, 300, 200), Color::kBlack);
+ .RectDrawing(IntRect(220, 80, 300, 200), Color::kBlack);
Update(artifact.Build());
ASSERT_EQ(1u, LayerCount());
@@ -671,7 +675,7 @@ TEST_P(PaintArtifactCompositorTest, OneClipWithAlias) {
TestPaintArtifact artifact;
artifact.Chunk(t0(), *clip, e0())
- .RectDrawing(FloatRect(220, 80, 300, 200), Color::kBlack);
+ .RectDrawing(IntRect(220, 80, 300, 200), Color::kBlack);
Update(artifact.Build());
ASSERT_EQ(1u, LayerCount());
@@ -705,13 +709,13 @@ TEST_P(PaintArtifactCompositorTest, NestedClips) {
TestPaintArtifact artifact;
artifact.Chunk(*transform1, *clip1, e0())
- .RectDrawing(FloatRect(300, 350, 100, 100), Color::kWhite);
+ .RectDrawing(IntRect(300, 350, 100, 100), Color::kWhite);
artifact.Chunk(*transform2, *clip2, e0())
- .RectDrawing(FloatRect(300, 350, 100, 100), Color::kLightGray);
+ .RectDrawing(IntRect(300, 350, 100, 100), Color::kLightGray);
artifact.Chunk(*transform1, *clip1, e0())
- .RectDrawing(FloatRect(300, 350, 100, 100), Color::kDarkGray);
+ .RectDrawing(IntRect(300, 350, 100, 100), Color::kDarkGray);
artifact.Chunk(*transform2, *clip2, e0())
- .RectDrawing(FloatRect(300, 350, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(300, 350, 100, 100), Color::kBlack);
Update(artifact.Build());
ASSERT_EQ(4u, LayerCount());
@@ -771,13 +775,13 @@ TEST_P(PaintArtifactCompositorTest, NestedClipsWithAlias) {
TestPaintArtifact artifact;
artifact.Chunk(*transform1, *clip1, e0())
- .RectDrawing(FloatRect(300, 350, 100, 100), Color::kWhite);
+ .RectDrawing(IntRect(300, 350, 100, 100), Color::kWhite);
artifact.Chunk(*transform2, *clip2, e0())
- .RectDrawing(FloatRect(300, 350, 100, 100), Color::kLightGray);
+ .RectDrawing(IntRect(300, 350, 100, 100), Color::kLightGray);
artifact.Chunk(*transform1, *clip1, e0())
- .RectDrawing(FloatRect(300, 350, 100, 100), Color::kDarkGray);
+ .RectDrawing(IntRect(300, 350, 100, 100), Color::kDarkGray);
artifact.Chunk(*transform2, *clip2, e0())
- .RectDrawing(FloatRect(300, 350, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(300, 350, 100, 100), Color::kBlack);
Update(artifact.Build());
ASSERT_EQ(4u, LayerCount());
@@ -830,7 +834,7 @@ TEST_P(PaintArtifactCompositorTest, DeeplyNestedClips) {
TestPaintArtifact artifact;
artifact.Chunk(t0(), *clips.back(), e0())
- .RectDrawing(FloatRect(0, 0, 200, 200), Color::kWhite);
+ .RectDrawing(IntRect(0, 0, 200, 200), Color::kWhite);
Update(artifact.Build());
// Check the drawing layer. It's clipped.
@@ -849,20 +853,122 @@ TEST_P(PaintArtifactCompositorTest, DeeplyNestedClips) {
for (auto it = clips.rbegin(); it != clips.rend(); ++it) {
const ClipPaintPropertyNode* paint_clip_node = it->get();
EXPECT_EQ(cc::ClipNode::ClipType::APPLIES_LOCAL_CLIP, clip_node->clip_type);
- EXPECT_EQ(paint_clip_node->ClipRect().Rect(), clip_node->clip);
+ EXPECT_EQ(paint_clip_node->UnsnappedClipRect().Rect(), clip_node->clip);
clip_node = GetPropertyTrees().clip_tree.Node(clip_node->parent_id);
}
}
+TEST_P(PaintArtifactCompositorTest, SiblingClipsWithAlias) {
+ auto real_common_clip =
+ CreateClip(c0(), t0(), FloatRoundedRect(0, 0, 800, 600));
+ auto common_clip = ClipPaintPropertyNode::CreateAlias(*real_common_clip);
+ auto real_clip1 =
+ CreateClip(*common_clip, t0(), FloatRoundedRect(0, 0, 300, 200));
+ auto clip1 = ClipPaintPropertyNode::CreateAlias(*real_clip1);
+ auto real_clip2 =
+ CreateClip(*common_clip, t0(), FloatRoundedRect(400, 0, 400, 600));
+ auto clip2 = ClipPaintPropertyNode::CreateAlias(*real_clip2);
+
+ TestPaintArtifact artifact;
+ artifact.Chunk(t0(), *clip1, e0())
+ .RectDrawing(IntRect(0, 0, 111, 222), Color::kWhite);
+ artifact.Chunk(t0(), *clip2, e0())
+ .RectDrawing(IntRect(333, 444, 555, 666), Color::kBlack);
+ Update(artifact.Build());
+
+ // The two chunks are merged together.
+ ASSERT_EQ(1u, LayerCount());
+ const cc::Layer* layer = LayerAt(0);
+ EXPECT_THAT(
+ layer->GetPicture(),
+ Pointee(DrawsRectangles(Vector<RectWithColor>{
+ // This is the first RectDrawing with real_clip1 applied.
+ RectWithColor(FloatRect(0, 0, 111, 200), Color::kWhite),
+ // This is the second RectDrawing with real_clip2 applied.
+ RectWithColor(FloatRect(400, 444, 400, 156), Color::kBlack)})));
+ EXPECT_EQ(gfx::Transform(), layer->ScreenSpaceTransform());
+ const cc::ClipNode* clip_node =
+ GetPropertyTrees().clip_tree.Node(layer->clip_tree_index());
+ EXPECT_EQ(cc::ClipNode::ClipType::APPLIES_LOCAL_CLIP, clip_node->clip_type);
+ ASSERT_EQ(gfx::RectF(0, 0, 800, 600), clip_node->clip);
+}
+
+TEST_P(PaintArtifactCompositorTest, SiblingClipsWithCompositedTransform) {
+ auto t1 = CreateTransform(t0(), TransformationMatrix(), FloatPoint3D(),
+ CompositingReason::kWillChangeTransform);
+ auto t2 = CreateTransform(*t1, TransformationMatrix().Translate(1, 2));
+ auto c1 = CreateClip(c0(), t0(), FloatRoundedRect(0, 0, 400, 600));
+ auto c2 = CreateClip(c0(), *t2, FloatRoundedRect(400, 0, 400, 600));
+
+ TestPaintArtifact artifact;
+ artifact.Chunk(t0(), *c1, e0())
+ .RectDrawing(IntRect(0, 0, 640, 480), Color::kWhite);
+ artifact.Chunk(t0(), *c2, e0())
+ .RectDrawing(IntRect(0, 0, 640, 480), Color::kBlack);
+ Update(artifact.Build());
+
+ // We can't merge the two chunks because their clips have unmergeable
+ // transforms.
+ ASSERT_EQ(2u, LayerCount());
+}
+
+TEST_P(PaintArtifactCompositorTest, SiblingTransformsWithAlias) {
+ auto real_common_transform =
+ CreateTransform(t0(), TransformationMatrix().Translate(5, 6));
+ auto common_transform =
+ TransformPaintPropertyNode::CreateAlias(*real_common_transform);
+ auto real_transform1 =
+ CreateTransform(*common_transform, TransformationMatrix().Scale(2));
+ auto transform1 = TransformPaintPropertyNode::CreateAlias(*real_transform1);
+ auto real_transform2 =
+ CreateTransform(*common_transform, TransformationMatrix().Scale(0.5));
+ auto transform2 = TransformPaintPropertyNode::CreateAlias(*real_transform2);
+
+ TestPaintArtifact artifact;
+ artifact.Chunk(*transform1, c0(), e0())
+ .RectDrawing(IntRect(0, 0, 111, 222), Color::kWhite);
+ artifact.Chunk(*transform2, c0(), e0())
+ .RectDrawing(IntRect(0, 0, 333, 444), Color::kBlack);
+ Update(artifact.Build());
+
+ // The two chunks are merged together.
+ ASSERT_EQ(1u, LayerCount());
+ const cc::Layer* layer = LayerAt(0);
+ EXPECT_THAT(layer->GetPicture(),
+ Pointee(DrawsRectangles(Vector<RectWithColor>{
+ RectWithColor(FloatRect(0, 0, 222, 444), Color::kWhite),
+ RectWithColor(FloatRect(0, 0, 166.5, 222), Color::kBlack)})));
+ gfx::Transform expected_transform;
+ expected_transform.Translate(5, 6);
+ EXPECT_EQ(expected_transform, layer->ScreenSpaceTransform());
+}
+
+TEST_P(PaintArtifactCompositorTest, SiblingTransformsWithComposited) {
+ auto t1 = CreateTransform(t0(), TransformationMatrix(), FloatPoint3D(),
+ CompositingReason::kWillChangeTransform);
+ auto t2 = CreateTransform(*t1, TransformationMatrix().Translate(1, 2));
+ auto t3 = CreateTransform(t0(), TransformationMatrix().Translate(3, 4));
+
+ TestPaintArtifact artifact;
+ artifact.Chunk(*t2, c0(), e0())
+ .RectDrawing(IntRect(0, 0, 640, 480), Color::kWhite);
+ artifact.Chunk(*t3, c0(), e0())
+ .RectDrawing(IntRect(0, 0, 640, 480), Color::kBlack);
+ Update(artifact.Build());
+
+ // We can't merge the two chunks because their transforms are not mergeable.
+ ASSERT_EQ(2u, LayerCount());
+}
+
TEST_P(PaintArtifactCompositorTest, ForeignLayerPassesThrough) {
scoped_refptr<cc::Layer> layer = cc::Layer::Create();
layer->SetIsDrawable(true);
layer->SetBounds(gfx::Size(400, 300));
TestPaintArtifact test_artifact;
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite);
test_artifact.Chunk().ForeignLayer(layer, FloatPoint(50, 60));
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 100, 100), Color::kGray);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 100, 100), Color::kGray);
auto artifact = test_artifact.Build();
ASSERT_EQ(3u, artifact->PaintChunks().size());
@@ -877,7 +983,7 @@ TEST_P(PaintArtifactCompositorTest, ForeignLayerPassesThrough) {
TEST_P(PaintArtifactCompositorTest, EffectTreeConversionWithAlias) {
Update(TestPaintArtifact()
.Chunk()
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite)
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite)
.Build());
auto root_stable_id = GetPropertyTrees().effect_tree.Node(1)->stable_id;
@@ -892,11 +998,11 @@ TEST_P(PaintArtifactCompositorTest, EffectTreeConversionWithAlias) {
TestPaintArtifact artifact;
artifact.Chunk(t0(), c0(), *effect2)
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite);
artifact.Chunk(t0(), c0(), *effect1)
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite);
artifact.Chunk(t0(), c0(), *effect3)
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite);
Update(artifact.Build());
ASSERT_EQ(3u, LayerCount());
@@ -961,6 +1067,7 @@ static scoped_refptr<ScrollPaintPropertyNode> CreateScroll(
static void CheckCcScrollNode(const ScrollPaintPropertyNode& blink_scroll,
const cc::ScrollNode& cc_scroll) {
+ EXPECT_TRUE(cc_scroll.scrollable);
EXPECT_EQ(static_cast<gfx::Size>(blink_scroll.ContainerRect().Size()),
cc_scroll.container_bounds);
EXPECT_EQ(static_cast<gfx::Size>(blink_scroll.ContentsSize()),
@@ -983,7 +1090,7 @@ TEST_P(PaintArtifactCompositorTest, OneScrollNode) {
TestPaintArtifact artifact;
CreateScrollableChunk(artifact, *scroll_translation, c0(), e0());
artifact.Chunk(*scroll_translation, c0(), e0())
- .RectDrawing(FloatRect(-110, 12, 170, 19), Color::kWhite);
+ .RectDrawing(IntRect(-110, 12, 170, 19), Color::kWhite);
// Scroll node ElementIds are referenced by scroll animations.
Update(artifact.Build());
@@ -1017,7 +1124,6 @@ TEST_P(PaintArtifactCompositorTest, OneScrollNode) {
Pointee(DrawsRectangle(FloatRect(0, 0, 57, 19), Color::kWhite)));
auto* scroll_layer = ScrollableLayerAt(0);
- EXPECT_TRUE(scroll_layer->scrollable());
// The scroll layer should be sized to the container bounds.
// TODO(pdr): The container bounds will not include scrollbars but the scroll
// layer should extend below scrollbars.
@@ -1047,9 +1153,9 @@ TEST_P(PaintArtifactCompositorTest, TransformUnderScrollNode) {
TestPaintArtifact artifact;
artifact.Chunk(*scroll_translation, c0(), e0())
- .RectDrawing(FloatRect(-20, 4, 60, 8), Color::kBlack)
+ .RectDrawing(IntRect(-20, 4, 60, 8), Color::kBlack)
.Chunk(*transform, c0(), e0())
- .RectDrawing(FloatRect(1, -30, 5, 70), Color::kWhite);
+ .RectDrawing(IntRect(1, -30, 5, 70), Color::kWhite);
Update(artifact.Build());
const cc::ScrollTree& scroll_tree = GetPropertyTrees().scroll_tree;
@@ -1101,10 +1207,10 @@ TEST_P(PaintArtifactCompositorTest, NestedScrollNodes) {
CreateScrollTranslation(*scroll_translation_a, 37, 41, *scroll_b);
TestPaintArtifact artifact;
artifact.Chunk(*scroll_translation_a, c0(), *effect)
- .RectDrawing(FloatRect(7, 11, 13, 17), Color::kWhite);
+ .RectDrawing(IntRect(7, 11, 13, 17), Color::kWhite);
CreateScrollableChunk(artifact, *scroll_translation_a, c0(), *effect);
artifact.Chunk(*scroll_translation_b, c0(), *effect)
- .RectDrawing(FloatRect(1, 2, 3, 5), Color::kWhite);
+ .RectDrawing(IntRect(1, 2, 3, 5), Color::kWhite);
CreateScrollableChunk(artifact, *scroll_translation_b, c0(), *effect);
Update(artifact.Build());
@@ -1150,10 +1256,10 @@ TEST_P(PaintArtifactCompositorTest, ScrollHitTestLayerOrder) {
TestPaintArtifact artifact;
artifact.Chunk(*scroll_translation, *clip, e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite);
CreateScrollableChunk(artifact, *scroll_translation, *clip, e0());
artifact.Chunk(*transform, *clip, e0())
- .RectDrawing(FloatRect(0, 0, 50, 50), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 50, 50), Color::kBlack);
Update(artifact.Build());
// The first content layer (background) should not have the scrolling element
@@ -1197,7 +1303,7 @@ TEST_P(PaintArtifactCompositorTest, NestedScrollableLayerOrder) {
CreateScrollableChunk(artifact, *scroll_translation_2, *clip_2->Parent(),
e0());
artifact.Chunk(*scroll_translation_2, *clip_2, e0())
- .RectDrawing(FloatRect(0, 0, 50, 50), Color::kWhite);
+ .RectDrawing(IntRect(0, 0, 50, 50), Color::kWhite);
Update(artifact.Build());
// Two scroll layers should be created for each scroll translation node.
@@ -1281,8 +1387,8 @@ TEST_P(PaintArtifactCompositorTest, AncestorScrollNodes) {
TEST_P(PaintArtifactCompositorTest, MergeSimpleChunks) {
TestPaintArtifact test_artifact;
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 200, 300), Color::kGray);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 200, 300), Color::kGray);
auto artifact = test_artifact.Build();
ASSERT_EQ(2u, artifact->PaintChunks().size());
@@ -1306,10 +1412,10 @@ TEST_P(PaintArtifactCompositorTest, MergeClip) {
auto clip = CreateClip(c0(), t0(), FloatRoundedRect(10, 20, 50, 60));
TestPaintArtifact test_artifact;
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite);
test_artifact.Chunk(t0(), *clip, e0())
- .RectDrawing(FloatRect(0, 0, 200, 300), Color::kBlack);
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 300, 400), Color::kGray);
+ .RectDrawing(IntRect(0, 0, 200, 300), Color::kBlack);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 300, 400), Color::kGray);
auto artifact = test_artifact.Build();
@@ -1338,10 +1444,10 @@ TEST_P(PaintArtifactCompositorTest, Merge2DTransform) {
FloatPoint3D(100, 100, 0));
TestPaintArtifact test_artifact;
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite);
test_artifact.Chunk(*transform, c0(), e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 200, 300), Color::kGray);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 200, 300), Color::kGray);
auto artifact = test_artifact.Build();
ASSERT_EQ(3u, artifact->PaintChunks().size());
@@ -1373,11 +1479,11 @@ TEST_P(PaintArtifactCompositorTest, Merge2DTransformDirectAncestor) {
TestPaintArtifact test_artifact;
test_artifact.Chunk(*transform, c0(), e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite);
// The second chunk can merge into the first because it has a descendant
// state of the first's transform and no direct compositing reason.
test_artifact.Chunk(*transform2, c0(), e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
auto artifact = test_artifact.Build();
ASSERT_EQ(2u, artifact->PaintChunks().size());
@@ -1402,10 +1508,10 @@ TEST_P(PaintArtifactCompositorTest, MergeTransformOrigin) {
FloatPoint3D(100, 100, 0));
TestPaintArtifact test_artifact;
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite);
test_artifact.Chunk(*transform, c0(), e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 200, 300), Color::kGray);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 200, 300), Color::kGray);
auto artifact = test_artifact.Build();
ASSERT_EQ(3u, artifact->PaintChunks().size());
@@ -1432,10 +1538,10 @@ TEST_P(PaintArtifactCompositorTest, MergeOpacity) {
auto effect = CreateOpacityEffect(e0(), opacity);
TestPaintArtifact test_artifact;
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite);
test_artifact.Chunk(t0(), c0(), *effect)
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 200, 300), Color::kGray);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 200, 300), Color::kGray);
auto artifact = test_artifact.Build();
ASSERT_EQ(3u, artifact->PaintChunks().size());
@@ -1464,10 +1570,10 @@ TEST_P(PaintArtifactCompositorTest, MergeOpacityWithAlias) {
auto effect = EffectPaintPropertyNode::CreateAlias(*real_effect);
TestPaintArtifact test_artifact;
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite);
test_artifact.Chunk(t0(), c0(), *effect)
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 200, 300), Color::kGray);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 200, 300), Color::kGray);
auto artifact = test_artifact.Build();
ASSERT_EQ(3u, artifact->PaintChunks().size());
@@ -1505,10 +1611,10 @@ TEST_P(PaintArtifactCompositorTest, MergeNestedWithAlias) {
auto effect = EffectPaintPropertyNode::CreateAlias(*real_effect);
TestPaintArtifact test_artifact;
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite);
test_artifact.Chunk(*transform, *clip, *effect)
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 200, 300), Color::kGray);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 200, 300), Color::kGray);
auto artifact = test_artifact.Build();
ASSERT_EQ(3u, artifact->PaintChunks().size());
@@ -1544,10 +1650,10 @@ TEST_P(PaintArtifactCompositorTest, ClipPushedUp) {
auto clip = CreateClip(c0(), *transform2, FloatRoundedRect(10, 20, 50, 60));
TestPaintArtifact test_artifact;
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite);
test_artifact.Chunk(t0(), *clip, e0())
- .RectDrawing(FloatRect(0, 0, 300, 400), Color::kBlack);
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 200, 300), Color::kGray);
+ .RectDrawing(IntRect(0, 0, 300, 400), Color::kBlack);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 200, 300), Color::kGray);
auto artifact = test_artifact.Build();
ASSERT_EQ(3u, artifact->PaintChunks().size());
@@ -1570,10 +1676,7 @@ TEST_P(PaintArtifactCompositorTest, ClipPushedUp) {
}
}
-// TODO(crbug.com/696842): The effect refuses to "decomposite" because it's in
-// a deeper transform space than its chunk. We should allow decomposite if
-// the two transform nodes share the same direct compositing ancestor.
-TEST_P(PaintArtifactCompositorTest, DISABLED_EffectPushedUp) {
+TEST_P(PaintArtifactCompositorTest, EffectPushedUp) {
// Tests merging of an element which has an effect applied to it,
// but has an ancestor transform of them. This can happen for fixed-
// or absolute-position elements which escape scroll transforms.
@@ -1590,10 +1693,10 @@ TEST_P(PaintArtifactCompositorTest, DISABLED_EffectPushedUp) {
auto effect = CreateOpacityEffect(e0(), *transform2, &c0(), opacity);
TestPaintArtifact test_artifact;
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite);
test_artifact.Chunk(t0(), c0(), *effect)
- .RectDrawing(FloatRect(0, 0, 300, 400), Color::kBlack);
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 200, 300), Color::kGray);
+ .RectDrawing(IntRect(0, 0, 300, 400), Color::kBlack);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 200, 300), Color::kGray);
auto artifact = test_artifact.Build();
ASSERT_EQ(3u, artifact->PaintChunks().size());
@@ -1615,10 +1718,7 @@ TEST_P(PaintArtifactCompositorTest, DISABLED_EffectPushedUp) {
}
}
-// TODO(crbug.com/696842): The effect refuses to "decomposite" because it's in
-// a deeper transform space than its chunk. We should allow decomposite if
-// the two transform nodes share the same direct compositing ancestor.
-TEST_P(PaintArtifactCompositorTest, DISABLED_EffectAndClipPushedUp) {
+TEST_P(PaintArtifactCompositorTest, EffectAndClipPushedUp) {
// Tests merging of an element which has an effect applied to it,
// but has an ancestor transform of them. This can happen for fixed-
// or absolute-position elements which escape scroll transforms.
@@ -1634,10 +1734,10 @@ TEST_P(PaintArtifactCompositorTest, DISABLED_EffectAndClipPushedUp) {
auto effect = CreateOpacityEffect(e0(), *transform2, clip.get(), opacity);
TestPaintArtifact test_artifact;
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite);
test_artifact.Chunk(t0(), *clip, *effect)
- .RectDrawing(FloatRect(0, 0, 300, 400), Color::kBlack);
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 200, 300), Color::kGray);
+ .RectDrawing(IntRect(0, 0, 300, 400), Color::kBlack);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 200, 300), Color::kGray);
auto artifact = test_artifact.Build();
ASSERT_EQ(3u, artifact->PaintChunks().size());
@@ -1669,10 +1769,10 @@ TEST_P(PaintArtifactCompositorTest, ClipAndEffectNoTransform) {
auto effect = CreateOpacityEffect(e0(), t0(), clip.get(), opacity);
TestPaintArtifact test_artifact;
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite);
test_artifact.Chunk(t0(), *clip, *effect)
- .RectDrawing(FloatRect(0, 0, 300, 400), Color::kBlack);
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 200, 300), Color::kGray);
+ .RectDrawing(IntRect(0, 0, 300, 400), Color::kBlack);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 200, 300), Color::kGray);
auto artifact = test_artifact.Build();
ASSERT_EQ(3u, artifact->PaintChunks().size());
@@ -1701,10 +1801,10 @@ TEST_P(PaintArtifactCompositorTest, TwoClips) {
auto clip2 = CreateClip(*clip, t0(), FloatRoundedRect(10, 20, 50, 60));
TestPaintArtifact test_artifact;
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite);
test_artifact.Chunk(t0(), *clip2, e0())
- .RectDrawing(FloatRect(0, 0, 300, 400), Color::kBlack);
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 200, 300), Color::kGray);
+ .RectDrawing(IntRect(0, 0, 300, 400), Color::kBlack);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 200, 300), Color::kGray);
auto artifact = test_artifact.Build();
ASSERT_EQ(3u, artifact->PaintChunks().size());
@@ -1735,10 +1835,10 @@ TEST_P(PaintArtifactCompositorTest, TwoTransformsClipBetween) {
CreateTransform(*transform, TransformationMatrix().Translate(20, 25),
FloatPoint3D(100, 100, 0));
TestPaintArtifact test_artifact;
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite);
test_artifact.Chunk(*transform2, *clip, e0())
- .RectDrawing(FloatRect(0, 0, 300, 400), Color::kBlack);
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 200, 300), Color::kGray);
+ .RectDrawing(IntRect(0, 0, 300, 400), Color::kBlack);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 200, 300), Color::kGray);
auto artifact = test_artifact.Build();
ASSERT_EQ(3u, artifact->PaintChunks().size());
@@ -1764,10 +1864,10 @@ TEST_P(PaintArtifactCompositorTest, OverlapTransform) {
CompositingReason::k3DTransform);
TestPaintArtifact test_artifact;
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite);
test_artifact.Chunk(*transform, c0(), e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 200, 300), Color::kGray);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 200, 300), Color::kGray);
auto artifact = test_artifact.Build();
ASSERT_EQ(3u, artifact->PaintChunks().size());
@@ -1807,6 +1907,59 @@ TEST_P(PaintArtifactCompositorTest, MightOverlap) {
PendingLayer pending_layer2(paint_chunk2, 1, false);
EXPECT_FALSE(MightOverlap(pending_layer, pending_layer2));
}
+
+ auto transform3 =
+ CreateAnimatingTransform(t0(), TransformationMatrix().Translate(100, 0),
+ FloatPoint3D(100, 100, 0));
+ {
+ SetTransform(paint_chunk2, *transform3);
+ PendingLayer pending_layer2(paint_chunk2, 1, false);
+ EXPECT_TRUE(MightOverlap(pending_layer, pending_layer2));
+ }
+}
+
+TEST_P(PaintArtifactCompositorTest, UniteRectsKnownToBeOpaque) {
+ // X aligned and intersect: unite.
+ EXPECT_EQ(FloatRect(10, 20, 30, 60),
+ PendingLayer::UniteRectsKnownToBeOpaque(FloatRect(10, 20, 30, 40),
+ FloatRect(10, 30, 30, 50)));
+ // X aligned and adjacent: unite.
+ EXPECT_EQ(FloatRect(10, 20, 30, 90),
+ PendingLayer::UniteRectsKnownToBeOpaque(FloatRect(10, 20, 30, 40),
+ FloatRect(10, 60, 30, 50)));
+ // X aligned and separate: choose the bigger one.
+ EXPECT_EQ(FloatRect(10, 61, 30, 50),
+ PendingLayer::UniteRectsKnownToBeOpaque(FloatRect(10, 20, 30, 40),
+ FloatRect(10, 61, 30, 50)));
+ // Y aligned and intersect: unite.
+ EXPECT_EQ(FloatRect(10, 20, 60, 40),
+ PendingLayer::UniteRectsKnownToBeOpaque(FloatRect(10, 20, 30, 40),
+ FloatRect(30, 20, 40, 40)));
+ // Y aligned and adjacent: unite.
+ EXPECT_EQ(FloatRect(10, 20, 70, 40),
+ PendingLayer::UniteRectsKnownToBeOpaque(FloatRect(10, 20, 30, 40),
+ FloatRect(40, 20, 40, 40)));
+ // Y aligned and separate: choose the bigger one.
+ EXPECT_EQ(FloatRect(41, 20, 40, 40),
+ PendingLayer::UniteRectsKnownToBeOpaque(FloatRect(10, 20, 30, 40),
+ FloatRect(41, 20, 40, 40)));
+ // Get the biggest expanded intersection.
+ EXPECT_EQ(FloatRect(0, 0, 9, 19),
+ PendingLayer::UniteRectsKnownToBeOpaque(FloatRect(0, 0, 10, 10),
+ FloatRect(0, 9, 9, 10)));
+ EXPECT_EQ(FloatRect(0, 0, 19, 9),
+ PendingLayer::UniteRectsKnownToBeOpaque(FloatRect(0, 0, 10, 10),
+ FloatRect(9, 0, 10, 9)));
+ // Otherwise choose the bigger one.
+ EXPECT_EQ(FloatRect(20, 30, 40, 50),
+ PendingLayer::UniteRectsKnownToBeOpaque(FloatRect(10, 20, 30, 40),
+ FloatRect(20, 30, 40, 50)));
+ EXPECT_EQ(FloatRect(10, 20, 40, 50),
+ PendingLayer::UniteRectsKnownToBeOpaque(FloatRect(10, 20, 40, 50),
+ FloatRect(20, 30, 30, 40)));
+ EXPECT_EQ(FloatRect(10, 20, 40, 50),
+ PendingLayer::UniteRectsKnownToBeOpaque(FloatRect(10, 20, 40, 50),
+ FloatRect(20, 30, 40, 50)));
}
TEST_P(PaintArtifactCompositorTest, PendingLayer) {
@@ -1825,49 +1978,164 @@ TEST_P(PaintArtifactCompositorTest, PendingLayer) {
chunk2.properties = chunk1.properties;
chunk2.known_to_be_opaque = true;
chunk2.bounds = IntRect(10, 20, 30, 40);
- pending_layer.Merge(PendingLayer(chunk2, 1, false));
+ ASSERT_TRUE(pending_layer.Merge(PendingLayer(chunk2, 1, false)));
// Bounds not equal to one PaintChunk.
EXPECT_EQ(FloatRect(0, 0, 40, 60), pending_layer.bounds);
EXPECT_EQ((Vector<wtf_size_t>{0, 1}), pending_layer.paint_chunk_indices);
- EXPECT_NE(pending_layer.bounds, pending_layer.rect_known_to_be_opaque);
+ EXPECT_EQ(FloatRect(0, 0, 30, 40), pending_layer.rect_known_to_be_opaque);
PaintChunk chunk3 = DefaultChunk();
chunk3.properties = chunk1.properties;
chunk3.known_to_be_opaque = true;
chunk3.bounds = IntRect(-5, -25, 20, 20);
- pending_layer.Merge(PendingLayer(chunk3, 2, false));
+ ASSERT_TRUE(pending_layer.Merge(PendingLayer(chunk3, 2, false)));
EXPECT_EQ(FloatRect(-5, -25, 45, 85), pending_layer.bounds);
EXPECT_EQ((Vector<wtf_size_t>{0, 1, 2}), pending_layer.paint_chunk_indices);
- EXPECT_NE(pending_layer.bounds, pending_layer.rect_known_to_be_opaque);
+ EXPECT_EQ(FloatRect(0, 0, 30, 40), pending_layer.rect_known_to_be_opaque);
}
-TEST_P(PaintArtifactCompositorTest, PendingLayerWithGeometry) {
- auto transform =
- CreateTransform(t0(), TransformationMatrix().Translate(20, 25),
- FloatPoint3D(100, 100, 0));
+TEST_P(PaintArtifactCompositorTest, PendingLayerMergeWithGuestTransform) {
+ auto transform = Create2DTranslation(t0(), 20, 25);
PaintChunk chunk1 = DefaultChunk();
chunk1.properties = PropertyTreeState::Root();
chunk1.bounds = IntRect(0, 0, 30, 40);
+ PaintChunk chunk2 = DefaultChunk();
+ chunk2.properties = chunk1.properties;
+ SetTransform(chunk2, *transform);
+ chunk2.bounds = IntRect(0, 0, 50, 60);
+
PendingLayer pending_layer(chunk1, 0, false);
+ ASSERT_TRUE(pending_layer.Merge(PendingLayer(chunk2, 1, false)));
+ EXPECT_EQ(FloatRect(0, 0, 70, 85), pending_layer.bounds);
+ EXPECT_EQ(PropertyTreeState::Root(), pending_layer.property_tree_state);
+}
- EXPECT_EQ(FloatRect(0, 0, 30, 40), pending_layer.bounds);
+TEST_P(PaintArtifactCompositorTest, PendingLayerMergeWithHomeTransform) {
+ auto transform = Create2DTranslation(t0(), 20, 25);
+
+ PaintChunk chunk1 = DefaultChunk();
+ chunk1.properties = PropertyTreeState::Root();
+ SetTransform(chunk1, *transform);
+ chunk1.bounds = IntRect(0, 0, 30, 40);
+
+ PaintChunk chunk2 = DefaultChunk();
+ chunk2.properties = PropertyTreeState::Root();
+ chunk2.bounds = IntRect(0, 0, 50, 60);
+
+ PendingLayer pending_layer(chunk1, 0, false);
+ ASSERT_TRUE(pending_layer.Merge(PendingLayer(chunk2, 1, false)));
+ EXPECT_EQ(FloatRect(0, 0, 50, 65), pending_layer.bounds);
+ EXPECT_EQ(PropertyTreeState::Root(), pending_layer.property_tree_state);
+}
+
+TEST_P(PaintArtifactCompositorTest, PendingLayerMergeWithBothTransforms) {
+ auto t1 = Create2DTranslation(t0(), 20, 25);
+ auto t2 = Create2DTranslation(t0(), -20, -25);
+
+ PaintChunk chunk1 = DefaultChunk();
+ chunk1.properties = PropertyTreeState::Root();
+ SetTransform(chunk1, *t1);
+ chunk1.bounds = IntRect(0, 0, 30, 40);
+
+ PaintChunk chunk2 = DefaultChunk();
+ chunk2.properties = PropertyTreeState::Root();
+ SetTransform(chunk2, *t2);
+ chunk2.bounds = IntRect(0, 0, 50, 60);
+
+ PendingLayer pending_layer(chunk1, 0, false);
+ ASSERT_TRUE(pending_layer.Merge(PendingLayer(chunk2, 1, false)));
+ EXPECT_EQ(FloatRect(-20, -25, 70, 90), pending_layer.bounds);
+ EXPECT_EQ(PropertyTreeState::Root(), pending_layer.property_tree_state);
+}
+
+TEST_P(PaintArtifactCompositorTest, PendingLayerDontMergeSparse) {
+ PaintChunk chunk1 = DefaultChunk();
+ chunk1.properties = PropertyTreeState::Root(); // (t0(), c0(), *e1);
+ chunk1.known_to_be_opaque = true;
+ chunk1.bounds = IntRect(0, 0, 30, 40);
PaintChunk chunk2 = DefaultChunk();
chunk2.properties = chunk1.properties;
- SetTransform(chunk2, *transform);
+ chunk2.known_to_be_opaque = true;
+ chunk2.bounds = IntRect(200, 200, 30, 40);
+
+ PendingLayer pending_layer(chunk1, 0, false);
+ ASSERT_FALSE(pending_layer.Merge(PendingLayer(chunk2, 1, false)));
+ EXPECT_EQ(FloatRect(0, 0, 30, 40), pending_layer.bounds);
+ EXPECT_EQ(chunk1.properties, pending_layer.property_tree_state);
+ EXPECT_EQ(Vector<wtf_size_t>{0}, pending_layer.paint_chunk_indices);
+}
+
+TEST_P(PaintArtifactCompositorTest, PendingLayerDontMergeSparseWithTransforms) {
+ auto t1 = Create2DTranslation(t0(), 20, 25);
+ auto t2 = Create2DTranslation(t0(), 1000, 1000);
+
+ PaintChunk chunk1 = DefaultChunk();
+ chunk1.properties = PropertyTreeState::Root();
+ SetTransform(chunk1, *t1);
+ chunk1.bounds = IntRect(0, 0, 30, 40);
+
+ PaintChunk chunk2 = DefaultChunk();
+ chunk2.properties = PropertyTreeState::Root();
+ SetTransform(chunk2, *t2);
chunk2.bounds = IntRect(0, 0, 50, 60);
- pending_layer.Merge(PendingLayer(chunk2, 1, false));
- EXPECT_EQ(FloatRect(0, 0, 70, 85), pending_layer.bounds);
+ PendingLayer pending_layer(chunk1, 0, false);
+ ASSERT_FALSE(pending_layer.Merge(PendingLayer(chunk2, 1, false)));
+ EXPECT_EQ(FloatRect(0, 0, 30, 40), pending_layer.bounds);
+ EXPECT_EQ(chunk1.properties, pending_layer.property_tree_state);
+ EXPECT_EQ(Vector<wtf_size_t>{0}, pending_layer.paint_chunk_indices);
+}
+
+TEST_P(PaintArtifactCompositorTest,
+ PendingLayerDontMergeSparseInCompositedEffect) {
+ auto t1 = Create2DTranslation(t0(), 20, 25);
+ auto t2 = Create2DTranslation(t0(), 1000, 1000);
+ auto e1 =
+ CreateOpacityEffect(e0(), 1.0f, CompositingReason::kWillChangeOpacity);
+
+ PaintChunk chunk1 = DefaultChunk();
+ chunk1.properties = PropertyTreeState(*t1, c0(), *e1);
+ chunk1.bounds = IntRect(0, 0, 30, 40);
+
+ PaintChunk chunk2 = DefaultChunk();
+ chunk2.properties = PropertyTreeState(*t2, c0(), *e1);
+ chunk2.bounds = IntRect(0, 0, 50, 60);
+
+ PendingLayer pending_layer(chunk1, 0, false);
+ ASSERT_FALSE(pending_layer.Merge(PendingLayer(chunk2, 1, false)));
+ EXPECT_EQ(FloatRect(0, 0, 30, 40), pending_layer.bounds);
+ EXPECT_EQ(chunk1.properties, pending_layer.property_tree_state);
+ EXPECT_EQ(Vector<wtf_size_t>{0}, pending_layer.paint_chunk_indices);
+}
+
+TEST_P(PaintArtifactCompositorTest,
+ PendingLayerMergeSparseInNonCompositedEffect) {
+ auto t1 = Create2DTranslation(t0(), 20, 25);
+ auto t2 = Create2DTranslation(t0(), 1000, 1000);
+ auto e1 = CreateOpacityEffect(e0(), 1.0f, CompositingReason::kNone);
+
+ PaintChunk chunk1 = DefaultChunk();
+ chunk1.properties = PropertyTreeState(*t1, c0(), *e1);
+ chunk1.bounds = IntRect(0, 0, 30, 40);
+
+ PaintChunk chunk2 = DefaultChunk();
+ chunk2.properties = PropertyTreeState(*t2, c0(), *e1);
+ chunk2.bounds = IntRect(0, 0, 50, 60);
+
+ PendingLayer pending_layer(chunk1, 0, false);
+ ASSERT_TRUE(pending_layer.Merge(PendingLayer(chunk2, 1, false)));
+ EXPECT_EQ(FloatRect(20, 25, 1030, 1035), pending_layer.bounds);
+ EXPECT_EQ(PropertyTreeState(t0(), c0(), *e1),
+ pending_layer.property_tree_state);
+ EXPECT_EQ((Vector<wtf_size_t>{0, 1}), pending_layer.paint_chunk_indices);
}
-// TODO(crbug.com/701991):
-// The test is disabled because opaque rect mapping is not implemented yet.
-TEST_P(PaintArtifactCompositorTest, DISABLED_PendingLayerKnownOpaque) {
+TEST_P(PaintArtifactCompositorTest, PendingLayerKnownOpaque) {
PaintChunk chunk1 = DefaultChunk();
chunk1.properties = PropertyTreeState::Root();
chunk1.bounds = IntRect(0, 0, 30, 40);
@@ -1880,7 +2148,7 @@ TEST_P(PaintArtifactCompositorTest, DISABLED_PendingLayerKnownOpaque) {
chunk2.properties = chunk1.properties;
chunk2.bounds = IntRect(0, 0, 25, 35);
chunk2.known_to_be_opaque = true;
- pending_layer.Merge(PendingLayer(chunk2, 1, false));
+ ASSERT_TRUE(pending_layer.Merge(PendingLayer(chunk2, 1, false)));
// Chunk 2 doesn't cover the entire layer, so not opaque.
EXPECT_EQ(FloatRect(chunk2.bounds), pending_layer.rect_known_to_be_opaque);
@@ -1890,7 +2158,7 @@ TEST_P(PaintArtifactCompositorTest, DISABLED_PendingLayerKnownOpaque) {
chunk3.properties = chunk1.properties;
chunk3.bounds = IntRect(0, 0, 50, 60);
chunk3.known_to_be_opaque = true;
- pending_layer.Merge(PendingLayer(chunk3, 2, false));
+ ASSERT_TRUE(pending_layer.Merge(PendingLayer(chunk3, 2, false)));
// Chunk 3 covers the entire layer, so now it's opaque.
EXPECT_EQ(FloatRect(chunk3.bounds), pending_layer.bounds);
@@ -1921,7 +2189,7 @@ TEST_P(PaintArtifactCompositorTest, TransformWithElementId) {
auto transform = CreateSampleTransformNodeWithElementId();
TestPaintArtifact artifact;
artifact.Chunk(*transform, c0(), e0())
- .RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack);
+ .RectDrawing(IntRect(100, 100, 200, 100), Color::kBlack);
Update(artifact.Build());
EXPECT_EQ(2,
@@ -1932,7 +2200,7 @@ TEST_P(PaintArtifactCompositorTest, EffectWithElementId) {
auto effect = CreateSampleEffectNodeWithElementId();
TestPaintArtifact artifact;
artifact.Chunk(t0(), c0(), *effect)
- .RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack);
+ .RectDrawing(IntRect(100, 100, 200, 100), Color::kBlack);
Update(artifact.Build());
EXPECT_EQ(2, ElementIdToEffectNodeIndex(effect->GetCompositorElementId()));
@@ -1943,7 +2211,7 @@ TEST_P(PaintArtifactCompositorTest, EffectWithElementIdWithAlias) {
auto effect = EffectPaintPropertyNode::CreateAlias(*real_effect);
TestPaintArtifact artifact;
artifact.Chunk(t0(), c0(), *effect)
- .RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack);
+ .RectDrawing(IntRect(100, 100, 200, 100), Color::kBlack);
Update(artifact.Build());
EXPECT_EQ(2,
@@ -1963,9 +2231,9 @@ TEST_P(PaintArtifactCompositorTest, NonCompositedSimpleLuminanceMask) {
TestPaintArtifact artifact;
artifact.Chunk(t0(), c0(), *masked)
- .RectDrawing(FloatRect(100, 100, 200, 200), Color::kGray);
+ .RectDrawing(IntRect(100, 100, 200, 200), Color::kGray);
artifact.Chunk(t0(), c0(), *masking)
- .RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite);
+ .RectDrawing(IntRect(150, 150, 100, 100), Color::kWhite);
Update(artifact.Build());
ASSERT_EQ(1u, LayerCount());
@@ -1979,6 +2247,47 @@ TEST_P(PaintArtifactCompositorTest, NonCompositedSimpleLuminanceMask) {
const cc::EffectNode* masked_group =
GetPropertyTrees().effect_tree.Node(layer->effect_tree_index());
EXPECT_FALSE(masked_group->HasRenderSurface());
+ EXPECT_EQ(SkBlendMode::kSrcOver, masked_group->blend_mode);
+ EXPECT_TRUE(masked_group->filters.IsEmpty());
+ // It's the last effect node. |masking| has been decomposited.
+ EXPECT_EQ(masked_group, GetPropertyTrees().effect_tree.back());
+}
+
+TEST_P(PaintArtifactCompositorTest, CompositedLuminanceMaskOneChild) {
+ auto masked = CreateOpacityEffect(
+ e0(), 1.0, CompositingReason::kIsolateCompositedDescendants);
+ EffectPaintPropertyNode::State masking_state;
+ masking_state.local_transform_space = &t0();
+ masking_state.output_clip = &c0();
+ masking_state.color_filter = kColorFilterLuminanceToAlpha;
+ masking_state.blend_mode = SkBlendMode::kDstIn;
+ masking_state.direct_compositing_reasons = CompositingReason::kLayerForMask;
+ auto masking =
+ EffectPaintPropertyNode::Create(*masked, std::move(masking_state));
+
+ TestPaintArtifact artifact;
+ artifact.Chunk(t0(), c0(), *masked)
+ .RectDrawing(IntRect(100, 100, 200, 200), Color::kGray);
+ artifact.Chunk(t0(), c0(), *masking)
+ .RectDrawing(IntRect(150, 150, 100, 100), Color::kWhite);
+ Update(artifact.Build());
+ ASSERT_EQ(2u, LayerCount());
+
+ const cc::Layer* masking_layer = LayerAt(1);
+ const cc::EffectNode* masking_group =
+ GetPropertyTrees().effect_tree.Node(masking_layer->effect_tree_index());
+
+ // Render surface is not needed for one child.
+ EXPECT_FALSE(masking_group->HasRenderSurface());
+ ASSERT_EQ(1u, masking_group->filters.size());
+ EXPECT_EQ(cc::FilterOperation::REFERENCE,
+ masking_group->filters.at(0).type());
+ EXPECT_EQ(SkBlendMode::kDstIn, masking_group->blend_mode);
+
+ // The parent also has a render surface to define the scope of the backdrop
+ // of the kDstIn blend mode.
+ EXPECT_TRUE(
+ GetPropertyTrees().effect_tree.parent(masking_group)->HasRenderSurface());
}
TEST_P(PaintArtifactCompositorTest, CompositedLuminanceMaskTwoChildren) {
@@ -1997,11 +2306,11 @@ TEST_P(PaintArtifactCompositorTest, CompositedLuminanceMaskTwoChildren) {
TestPaintArtifact artifact;
artifact.Chunk(t0(), c0(), *masked)
- .RectDrawing(FloatRect(100, 100, 200, 200), Color::kGray);
+ .RectDrawing(IntRect(100, 100, 200, 200), Color::kGray);
artifact.Chunk(t0(), c0(), *child_of_masked)
- .RectDrawing(FloatRect(100, 100, 200, 200), Color::kGray);
+ .RectDrawing(IntRect(100, 100, 200, 200), Color::kGray);
artifact.Chunk(t0(), c0(), *masking)
- .RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite);
+ .RectDrawing(IntRect(150, 150, 100, 100), Color::kWhite);
Update(artifact.Build());
ASSERT_EQ(3u, LayerCount());
@@ -2014,6 +2323,82 @@ TEST_P(PaintArtifactCompositorTest, CompositedLuminanceMaskTwoChildren) {
ASSERT_EQ(1u, masking_group->filters.size());
EXPECT_EQ(cc::FilterOperation::REFERENCE,
masking_group->filters.at(0).type());
+ EXPECT_EQ(SkBlendMode::kDstIn, masking_group->blend_mode);
+
+ // The parent also has a render surface to define the scope of the backdrop
+ // of the kDstIn blend mode.
+ EXPECT_TRUE(
+ GetPropertyTrees().effect_tree.parent(masking_group)->HasRenderSurface());
+}
+
+TEST_P(PaintArtifactCompositorTest, CompositedMaskOneChild) {
+ auto masked = CreateOpacityEffect(
+ e0(), 1.0, CompositingReason::kIsolateCompositedDescendants);
+ EffectPaintPropertyNode::State masking_state;
+ masking_state.local_transform_space = &t0();
+ masking_state.output_clip = &c0();
+ masking_state.blend_mode = SkBlendMode::kDstIn;
+ masking_state.direct_compositing_reasons = CompositingReason::kLayerForMask;
+ auto masking =
+ EffectPaintPropertyNode::Create(*masked, std::move(masking_state));
+
+ TestPaintArtifact artifact;
+ artifact.Chunk(t0(), c0(), *masked)
+ .RectDrawing(IntRect(100, 100, 200, 200), Color::kGray);
+ artifact.Chunk(t0(), c0(), *masking)
+ .RectDrawing(IntRect(150, 150, 100, 100), Color::kWhite);
+ Update(artifact.Build());
+ ASSERT_EQ(2u, LayerCount());
+
+ const cc::Layer* masking_layer = LayerAt(1);
+ const cc::EffectNode* masking_group =
+ GetPropertyTrees().effect_tree.Node(masking_layer->effect_tree_index());
+
+ // Render surface is not needed for one child.
+ EXPECT_FALSE(masking_group->HasRenderSurface());
+ EXPECT_EQ(SkBlendMode::kDstIn, masking_group->blend_mode);
+
+ // The parent also has a render surface to define the scope of the backdrop
+ // of the kDstIn blend mode.
+ EXPECT_TRUE(
+ GetPropertyTrees().effect_tree.parent(masking_group)->HasRenderSurface());
+}
+
+TEST_P(PaintArtifactCompositorTest, CompositedMaskTwoChildren) {
+ auto masked = CreateOpacityEffect(
+ e0(), 1.0, CompositingReason::kIsolateCompositedDescendants);
+ EffectPaintPropertyNode::State masking_state;
+ masking_state.local_transform_space = &t0();
+ masking_state.output_clip = &c0();
+ masking_state.blend_mode = SkBlendMode::kDstIn;
+ auto masking =
+ EffectPaintPropertyNode::Create(*masked, std::move(masking_state));
+
+ auto child_of_masked = CreateOpacityEffect(
+ *masking, 1.0, CompositingReason::kIsolateCompositedDescendants);
+
+ TestPaintArtifact artifact;
+ artifact.Chunk(t0(), c0(), *masked)
+ .RectDrawing(IntRect(100, 100, 200, 200), Color::kGray);
+ artifact.Chunk(t0(), c0(), *child_of_masked)
+ .RectDrawing(IntRect(100, 100, 200, 200), Color::kGray);
+ artifact.Chunk(t0(), c0(), *masking)
+ .RectDrawing(IntRect(150, 150, 100, 100), Color::kWhite);
+ Update(artifact.Build());
+ ASSERT_EQ(3u, LayerCount());
+
+ const cc::Layer* masking_layer = LayerAt(2);
+ const cc::EffectNode* masking_group =
+ GetPropertyTrees().effect_tree.Node(masking_layer->effect_tree_index());
+
+ // There is a render surface because there are two children.
+ EXPECT_TRUE(masking_group->HasRenderSurface());
+ EXPECT_EQ(SkBlendMode::kDstIn, masking_group->blend_mode);
+
+ // The parent also has a render surface to define the scope of the backdrop
+ // of the kDstIn blend mode.
+ EXPECT_TRUE(
+ GetPropertyTrees().effect_tree.parent(masking_group)->HasRenderSurface());
}
TEST_P(PaintArtifactCompositorTest, NonCompositedSimpleExoticBlendMode) {
@@ -2028,9 +2413,9 @@ TEST_P(PaintArtifactCompositorTest, NonCompositedSimpleExoticBlendMode) {
TestPaintArtifact artifact;
artifact.Chunk(t0(), c0(), *masked)
- .RectDrawing(FloatRect(100, 100, 200, 200), Color::kGray);
+ .RectDrawing(IntRect(100, 100, 200, 200), Color::kGray);
artifact.Chunk(t0(), c0(), *masking)
- .RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite);
+ .RectDrawing(IntRect(150, 150, 100, 100), Color::kWhite);
Update(artifact.Build());
ASSERT_EQ(1u, LayerCount());
@@ -2038,6 +2423,9 @@ TEST_P(PaintArtifactCompositorTest, NonCompositedSimpleExoticBlendMode) {
const cc::EffectNode* group =
GetPropertyTrees().effect_tree.Node(layer->effect_tree_index());
EXPECT_FALSE(group->HasRenderSurface());
+ EXPECT_EQ(SkBlendMode::kSrcOver, group->blend_mode);
+ // It's the last effect node. |masking| has been decomposited.
+ EXPECT_EQ(group, GetPropertyTrees().effect_tree.back());
}
TEST_P(PaintArtifactCompositorTest, ForcedCompositedExoticBlendMode) {
@@ -2054,9 +2442,9 @@ TEST_P(PaintArtifactCompositorTest, ForcedCompositedExoticBlendMode) {
TestPaintArtifact artifact;
artifact.Chunk(t0(), c0(), *masked)
- .RectDrawing(FloatRect(100, 100, 200, 200), Color::kGray);
+ .RectDrawing(IntRect(100, 100, 200, 200), Color::kGray);
artifact.Chunk(t0(), c0(), *masking)
- .RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite);
+ .RectDrawing(IntRect(150, 150, 100, 100), Color::kWhite);
Update(artifact.Build());
ASSERT_EQ(2u, LayerCount());
@@ -2065,8 +2453,12 @@ TEST_P(PaintArtifactCompositorTest, ForcedCompositedExoticBlendMode) {
GetPropertyTrees().effect_tree.Node(masking_layer->effect_tree_index());
EXPECT_EQ(SkBlendMode::kXor, masking_group->blend_mode);
- /// This requires a render surface.
+ // This requires a render surface.
EXPECT_TRUE(masking_group->HasRenderSurface());
+ // The parent also requires a render surface to define the backdrop scope of
+ // the blend mode.
+ EXPECT_TRUE(
+ GetPropertyTrees().effect_tree.parent(masking_group)->HasRenderSurface());
}
TEST_P(PaintArtifactCompositorTest,
@@ -2086,11 +2478,11 @@ TEST_P(PaintArtifactCompositorTest,
TestPaintArtifact artifact;
artifact.Chunk(t0(), c0(), *masked_child1)
- .RectDrawing(FloatRect(100, 100, 200, 200), Color::kGray);
+ .RectDrawing(IntRect(100, 100, 200, 200), Color::kGray);
artifact.Chunk(t0(), c0(), *masked_child2)
- .RectDrawing(FloatRect(100, 100, 200, 200), Color::kBlack);
+ .RectDrawing(IntRect(100, 100, 200, 200), Color::kBlack);
artifact.Chunk(t0(), c0(), *masking)
- .RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite);
+ .RectDrawing(IntRect(150, 150, 100, 100), Color::kWhite);
Update(artifact.Build());
ASSERT_EQ(3u, LayerCount());
@@ -2099,8 +2491,12 @@ TEST_P(PaintArtifactCompositorTest,
GetPropertyTrees().effect_tree.Node(masking_layer->effect_tree_index());
EXPECT_EQ(SkBlendMode::kXor, masking_group->blend_mode);
- /// This requires a render surface.
+ // This requires a render surface.
EXPECT_TRUE(masking_group->HasRenderSurface());
+ // The parent also requires a render surface to define the backdrop scope of
+ // the blend mode.
+ EXPECT_TRUE(
+ GetPropertyTrees().effect_tree.parent(masking_group)->HasRenderSurface());
}
TEST_P(PaintArtifactCompositorTest,
@@ -2122,11 +2518,11 @@ TEST_P(PaintArtifactCompositorTest,
TestPaintArtifact artifact;
artifact.Chunk(*transform1, c0(), *masked)
- .RectDrawing(FloatRect(100, 100, 200, 200), Color::kGray);
+ .RectDrawing(IntRect(100, 100, 200, 200), Color::kGray);
artifact.Chunk(*transform2, c0(), *masked)
- .RectDrawing(FloatRect(100, 100, 200, 200), Color::kBlack);
+ .RectDrawing(IntRect(100, 100, 200, 200), Color::kBlack);
artifact.Chunk(t0(), c0(), *masking)
- .RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite);
+ .RectDrawing(IntRect(150, 150, 100, 100), Color::kWhite);
Update(artifact.Build());
ASSERT_EQ(3u, LayerCount());
@@ -2135,8 +2531,42 @@ TEST_P(PaintArtifactCompositorTest,
GetPropertyTrees().effect_tree.Node(masking_layer->effect_tree_index());
EXPECT_EQ(SkBlendMode::kXor, masking_group->blend_mode);
- /// This requires a render surface.
+ // This requires a render surface.
EXPECT_TRUE(masking_group->HasRenderSurface());
+ // The parent also requires a render surface to define the backdrop scope of
+ // the blend mode.
+ EXPECT_TRUE(
+ GetPropertyTrees().effect_tree.parent(masking_group)->HasRenderSurface());
+}
+
+TEST_P(PaintArtifactCompositorTest, DecompositeExoticBlendModeWithoutBackdrop) {
+ auto parent_effect = CreateOpacityEffect(
+ e0(), 1.0, CompositingReason::kIsolateCompositedDescendants);
+ EffectPaintPropertyNode::State blend_state1;
+ blend_state1.local_transform_space = &t0();
+ blend_state1.blend_mode = SkBlendMode::kScreen;
+ auto blend_effect1 =
+ EffectPaintPropertyNode::Create(*parent_effect, std::move(blend_state1));
+ EffectPaintPropertyNode::State blend_state2;
+ blend_state2.local_transform_space = &t0();
+ blend_state2.blend_mode = SkBlendMode::kScreen;
+ auto blend_effect2 =
+ EffectPaintPropertyNode::Create(*parent_effect, std::move(blend_state2));
+
+ Update(TestPaintArtifact()
+ .Chunk(t0(), c0(), *blend_effect1)
+ .RectDrawing(IntRect(100, 100, 200, 200), Color::kGray)
+ .Chunk(t0(), c0(), *blend_effect2)
+ .RectDrawing(IntRect(100, 100, 200, 200), Color::kBlack)
+ .Build());
+
+ ASSERT_EQ(1u, LayerCount());
+ const auto* effect =
+ GetPropertyTrees().effect_tree.Node(LayerAt(0)->effect_tree_index());
+ EXPECT_EQ(1.0f, effect->opacity);
+ EXPECT_EQ(SkBlendMode::kSrcOver, effect->blend_mode);
+ // Don't need a render surface because all blend effects are decomposited.
+ EXPECT_FALSE(effect->HasRenderSurface());
}
TEST_P(PaintArtifactCompositorTest, UpdateProducesNewSequenceNumber) {
@@ -2149,8 +2579,8 @@ TEST_P(PaintArtifactCompositorTest, UpdateProducesNewSequenceNumber) {
TestPaintArtifact test_artifact;
test_artifact.Chunk(*transform, *clip, *effect)
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite);
- test_artifact.Chunk().RectDrawing(FloatRect(0, 0, 100, 100), Color::kGray);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kWhite);
+ test_artifact.Chunk().RectDrawing(IntRect(0, 0, 100, 100), Color::kGray);
auto artifact = test_artifact.Build();
Update(artifact);
@@ -2189,9 +2619,9 @@ TEST_P(PaintArtifactCompositorTest, DecompositeClip) {
auto clip = CreateClip(c0(), t0(), FloatRoundedRect(75, 75, 100, 100));
TestPaintArtifact artifact;
- artifact.Chunk().RectDrawing(FloatRect(50, 50, 100, 100), Color::kGray);
+ artifact.Chunk().RectDrawing(IntRect(50, 50, 100, 100), Color::kGray);
artifact.Chunk(t0(), *clip, e0())
- .RectDrawing(FloatRect(100, 100, 100, 100), Color::kGray);
+ .RectDrawing(IntRect(100, 100, 100, 100), Color::kGray);
Update(artifact.Build());
ASSERT_EQ(1u, LayerCount());
@@ -2208,10 +2638,10 @@ TEST_P(PaintArtifactCompositorTest, DecompositeEffect) {
auto effect = CreateOpacityEffect(e0(), 0.5);
TestPaintArtifact artifact;
- artifact.Chunk().RectDrawing(FloatRect(50, 25, 100, 100), Color::kGray);
+ artifact.Chunk().RectDrawing(IntRect(50, 25, 100, 100), Color::kGray);
artifact.Chunk(t0(), c0(), *effect)
- .RectDrawing(FloatRect(25, 75, 100, 100), Color::kGray);
- artifact.Chunk().RectDrawing(FloatRect(75, 75, 100, 100), Color::kGray);
+ .RectDrawing(IntRect(25, 75, 100, 100), Color::kGray);
+ artifact.Chunk().RectDrawing(IntRect(75, 75, 100, 100), Color::kGray);
Update(artifact.Build());
ASSERT_EQ(1u, LayerCount());
@@ -2226,10 +2656,10 @@ TEST_P(PaintArtifactCompositorTest, DirectlyCompositedEffect) {
auto effect = CreateOpacityEffect(e0(), 0.5f, CompositingReason::kAll);
TestPaintArtifact artifact;
- artifact.Chunk().RectDrawing(FloatRect(50, 25, 100, 100), Color::kGray);
+ artifact.Chunk().RectDrawing(IntRect(50, 25, 100, 100), Color::kGray);
artifact.Chunk(t0(), c0(), *effect)
- .RectDrawing(FloatRect(25, 75, 100, 100), Color::kGray);
- artifact.Chunk().RectDrawing(FloatRect(75, 75, 100, 100), Color::kGray);
+ .RectDrawing(IntRect(25, 75, 100, 100), Color::kGray);
+ artifact.Chunk().RectDrawing(IntRect(75, 75, 100, 100), Color::kGray);
Update(artifact.Build());
ASSERT_EQ(3u, LayerCount());
@@ -2261,10 +2691,10 @@ TEST_P(PaintArtifactCompositorTest, DecompositeDeepEffect) {
auto effect3 = CreateOpacityEffect(*effect2, 0.3f);
TestPaintArtifact artifact;
- artifact.Chunk().RectDrawing(FloatRect(50, 25, 100, 100), Color::kGray);
+ artifact.Chunk().RectDrawing(IntRect(50, 25, 100, 100), Color::kGray);
artifact.Chunk(t0(), c0(), *effect3)
- .RectDrawing(FloatRect(25, 75, 100, 100), Color::kGray);
- artifact.Chunk().RectDrawing(FloatRect(75, 75, 100, 100), Color::kGray);
+ .RectDrawing(IntRect(25, 75, 100, 100), Color::kGray);
+ artifact.Chunk().RectDrawing(IntRect(75, 75, 100, 100), Color::kGray);
Update(artifact.Build());
ASSERT_EQ(3u, LayerCount());
@@ -2298,11 +2728,11 @@ TEST_P(PaintArtifactCompositorTest, IndirectlyCompositedEffect) {
CompositingReason::k3DTransform);
TestPaintArtifact artifact;
- artifact.Chunk().RectDrawing(FloatRect(50, 25, 100, 100), Color::kGray);
+ artifact.Chunk().RectDrawing(IntRect(50, 25, 100, 100), Color::kGray);
artifact.Chunk(t0(), c0(), *effect)
- .RectDrawing(FloatRect(25, 75, 100, 100), Color::kGray);
+ .RectDrawing(IntRect(25, 75, 100, 100), Color::kGray);
artifact.Chunk(*transform, c0(), *effect)
- .RectDrawing(FloatRect(75, 75, 100, 100), Color::kGray);
+ .RectDrawing(IntRect(75, 75, 100, 100), Color::kGray);
Update(artifact.Build());
ASSERT_EQ(3u, LayerCount());
@@ -2333,20 +2763,20 @@ TEST_P(PaintArtifactCompositorTest, DecompositedEffectNotMergingDueToOverlap) {
auto transform = CreateTransform(t0(), TransformationMatrix(), FloatPoint3D(),
CompositingReason::k3DTransform);
TestPaintArtifact artifact;
- artifact.Chunk().RectDrawing(FloatRect(0, 0, 50, 50), Color::kGray);
+ artifact.Chunk().RectDrawing(IntRect(0, 0, 50, 50), Color::kGray);
artifact.Chunk(t0(), c0(), *effect1)
- .RectDrawing(FloatRect(100, 0, 50, 50), Color::kGray);
+ .RectDrawing(IntRect(100, 0, 50, 50), Color::kGray);
// This chunk has a transform that must be composited, thus causing effect1
// to be composited too.
artifact.Chunk(*transform, c0(), *effect1)
- .RectDrawing(FloatRect(200, 0, 50, 50), Color::kGray);
+ .RectDrawing(IntRect(200, 0, 50, 50), Color::kGray);
artifact.Chunk(t0(), c0(), *effect2)
- .RectDrawing(FloatRect(200, 100, 50, 50), Color::kGray);
+ .RectDrawing(IntRect(200, 100, 50, 50), Color::kGray);
// This chunk overlaps with the 2nd chunk, but is seemingly safe to merge.
// However because effect1 gets composited due to a composited transform,
// we can't merge with effect1 nor skip it to merge with the first chunk.
artifact.Chunk(t0(), c0(), *effect2)
- .RectDrawing(FloatRect(100, 0, 50, 50), Color::kGray);
+ .RectDrawing(IntRect(100, 0, 50, 50), Color::kGray);
Update(artifact.Build());
ASSERT_EQ(4u, LayerCount());
@@ -2476,7 +2906,7 @@ TEST_P(PaintArtifactCompositorTest,
auto effect = CreateOpacityEffect(e0(), 0.0001f, CompositingReason::kCanvas);
TestPaintArtifact artifact;
artifact.Chunk(t0(), c0(), *effect)
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
Update(artifact.Build());
ASSERT_EQ(1u, LayerCount());
}
@@ -2489,7 +2919,7 @@ TEST_P(PaintArtifactCompositorTest,
CreateOpacityEffect(*tiny_effect, 0.5f, CompositingReason::kNone);
TestPaintArtifact artifact;
artifact.Chunk(t0(), c0(), *visible_effect)
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
Update(artifact.Build());
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
EXPECT_EQ(0u, LayerCount());
@@ -2505,7 +2935,7 @@ TEST_P(
auto visible_effect = CreateOpacityEffect(*tiny_effect, 0.5f);
TestPaintArtifact artifact;
artifact.Chunk(t0(), c0(), *visible_effect)
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
Update(artifact.Build());
ASSERT_EQ(1u, LayerCount());
}
@@ -2517,7 +2947,7 @@ TEST_P(PaintArtifactCompositorTest,
CreateOpacityEffect(*tiny_effect, 0.5f, CompositingReason::kCanvas);
TestPaintArtifact artifact;
artifact.Chunk(t0(), c0(), *visible_effect)
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
Update(artifact.Build());
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
EXPECT_EQ(0u, LayerCount());
@@ -2532,7 +2962,7 @@ TEST_P(PaintArtifactCompositorTest, UpdateManagesLayerElementIds) {
{
TestPaintArtifact artifact;
artifact.Chunk(*transform, c0(), e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
Update(artifact.Build());
ASSERT_EQ(1u, LayerCount());
@@ -2552,7 +2982,7 @@ TEST_P(PaintArtifactCompositorTest, UpdateManagesLayerElementIds) {
}
TEST_P(PaintArtifactCompositorTest, SynthesizedClipSimple) {
- // This tests the simplist case that a single layer needs to be clipped
+ // This tests the simplest case that a single layer needs to be clipped
// by a single composited rounded clip.
FloatSize corner(5, 5);
FloatRoundedRect rrect(FloatRect(50, 50, 300, 200), corner, corner, corner,
@@ -2561,55 +2991,20 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipSimple) {
TestPaintArtifact artifact;
artifact.Chunk(t0(), *c1, e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
Update(artifact.Build());
- if (RuntimeEnabledFeatures::FastBorderRadiusEnabled()) {
- // Expectation in effect stack diagram:
- // l0
- // [ mask_isolation_0 ]
- // [ e0 ]
- // One content layer.
- ASSERT_EQ(1u, LayerCount());
- // There is still a "synthesized layer" but it's null.
- ASSERT_EQ(1u, SynthesizedClipLayerCount());
- EXPECT_FALSE(SynthesizedClipLayerAt(0));
-
- const cc::Layer* content0 = LayerAt(0);
-
- constexpr int c0_id = 1;
- constexpr int e0_id = 1;
-
- int c1_id = content0->clip_tree_index();
- const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
- EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
- ASSERT_EQ(c0_id, cc_c1.parent_id);
- int mask_isolation_0_id = content0->effect_tree_index();
- const cc::EffectNode& mask_isolation_0 =
- *GetPropertyTrees().effect_tree.Node(mask_isolation_0_id);
- ASSERT_EQ(e0_id, mask_isolation_0.parent_id);
- EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode);
- EXPECT_TRUE(mask_isolation_0.is_fast_rounded_corner);
- EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
- mask_isolation_0.rounded_corner_bounds);
- EXPECT_FALSE(mask_isolation_0.HasRenderSurface());
- return;
- }
-
// Expectation in effect stack diagram:
- // l1
- // l0 [ mask_effect_0 ]
+ // content0
// [ mask_isolation_0 ]
// [ e0 ]
// One content layer.
- ASSERT_EQ(2u, LayerCount());
+ ASSERT_EQ(1u, LayerCount());
+ // There is still a "synthesized layer" but it's null.
ASSERT_EQ(1u, SynthesizedClipLayerCount());
+ EXPECT_FALSE(SynthesizedClipLayerAt(0));
const cc::Layer* content0 = LayerAt(0);
- const cc::Layer* clip_mask0 = LayerAt(1);
-
- constexpr int c0_id = 1;
- constexpr int e0_id = 1;
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
@@ -2620,20 +3015,10 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipSimple) {
*GetPropertyTrees().effect_tree.Node(mask_isolation_0_id);
ASSERT_EQ(e0_id, mask_isolation_0.parent_id);
EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode);
- EXPECT_TRUE(mask_isolation_0.HasRenderSurface());
-
- EXPECT_EQ(SynthesizedClipLayerAt(0), clip_mask0);
- EXPECT_EQ(gfx::Size(300, 200), clip_mask0->bounds());
- EXPECT_EQ(c1_id, clip_mask0->clip_tree_index());
- int mask_effect_0_id = clip_mask0->effect_tree_index();
- const cc::EffectNode& mask_effect_0 =
- *GetPropertyTrees().effect_tree.Node(mask_effect_0_id);
- ASSERT_EQ(mask_isolation_0_id, mask_effect_0.parent_id);
- EXPECT_EQ(SkBlendMode::kDstIn, mask_effect_0.blend_mode);
-
- // The masks DrawsContent because it has content that it masks which also
- // DrawsContent.
- EXPECT_TRUE(clip_mask0->DrawsContent());
+ EXPECT_TRUE(mask_isolation_0.is_fast_rounded_corner);
+ EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
+ mask_isolation_0.rounded_corner_bounds);
+ EXPECT_FALSE(mask_isolation_0.HasRenderSurface());
}
TEST_P(PaintArtifactCompositorTest, SynthesizedClipRotatedNotSupported) {
@@ -2650,14 +3035,14 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipRotatedNotSupported) {
TestPaintArtifact artifact;
artifact.Chunk(*transform, *c1, e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
Update(artifact.Build());
// Expectation in effect stack diagram:
- // l1
- // l0 [ mask_effect_0 ]
- // [ mask_isolation_0 ]
- // [ e0 ]
+ // clip_mask0
+ // content0 [ mask_effect_0 ]
+ // [ mask_isolation_0 ]
+ // [ e0 ]
// One content layer.
ASSERT_EQ(2u, LayerCount());
ASSERT_EQ(1u, SynthesizedClipLayerCount());
@@ -2665,9 +3050,6 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipRotatedNotSupported) {
const cc::Layer* content0 = LayerAt(0);
const cc::Layer* clip_mask0 = LayerAt(1);
- constexpr int c0_id = 1;
- constexpr int e0_id = 1;
-
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
@@ -2687,6 +3069,8 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipRotatedNotSupported) {
*GetPropertyTrees().effect_tree.Node(mask_effect_0_id);
ASSERT_EQ(mask_isolation_0_id, mask_effect_0.parent_id);
EXPECT_EQ(SkBlendMode::kDstIn, mask_effect_0.blend_mode);
+ // Render surface is not needed for DstIn controlling only one layer.
+ EXPECT_FALSE(mask_effect_0.HasRenderSurface());
}
TEST_P(PaintArtifactCompositorTest, SynthesizedClip90DegRotationSupported) {
@@ -2703,55 +3087,20 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClip90DegRotationSupported) {
TestPaintArtifact artifact;
artifact.Chunk(*transform, *c1, e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
Update(artifact.Build());
- if (RuntimeEnabledFeatures::FastBorderRadiusEnabled()) {
- // Expectation in effect stack diagram:
- // l0
- // [ mask_isolation_0 ]
- // [ e0 ]
- // One content layer.
- ASSERT_EQ(1u, LayerCount());
- // There is still a "synthesized layer" but it's null.
- ASSERT_EQ(1u, SynthesizedClipLayerCount());
- EXPECT_FALSE(SynthesizedClipLayerAt(0));
-
- const cc::Layer* content0 = LayerAt(0);
-
- constexpr int c0_id = 1;
- constexpr int e0_id = 1;
-
- int c1_id = content0->clip_tree_index();
- const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
- EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
- ASSERT_EQ(c0_id, cc_c1.parent_id);
- int mask_isolation_0_id = content0->effect_tree_index();
- const cc::EffectNode& mask_isolation_0 =
- *GetPropertyTrees().effect_tree.Node(mask_isolation_0_id);
- ASSERT_EQ(e0_id, mask_isolation_0.parent_id);
- EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode);
- EXPECT_TRUE(mask_isolation_0.is_fast_rounded_corner);
- EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
- mask_isolation_0.rounded_corner_bounds);
- EXPECT_FALSE(mask_isolation_0.HasRenderSurface());
- return;
- }
-
// Expectation in effect stack diagram:
- // l1
- // l0 [ mask_effect_0 ]
+ // content0
// [ mask_isolation_0 ]
// [ e0 ]
// One content layer.
- ASSERT_EQ(2u, LayerCount());
+ ASSERT_EQ(1u, LayerCount());
+ // There is still a "synthesized layer" but it's null.
ASSERT_EQ(1u, SynthesizedClipLayerCount());
+ EXPECT_FALSE(SynthesizedClipLayerAt(0));
const cc::Layer* content0 = LayerAt(0);
- const cc::Layer* clip_mask0 = LayerAt(1);
-
- constexpr int c0_id = 1;
- constexpr int e0_id = 1;
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
@@ -2762,21 +3111,15 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClip90DegRotationSupported) {
*GetPropertyTrees().effect_tree.Node(mask_isolation_0_id);
ASSERT_EQ(e0_id, mask_isolation_0.parent_id);
EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode);
- EXPECT_TRUE(mask_isolation_0.HasRenderSurface());
-
- EXPECT_EQ(SynthesizedClipLayerAt(0), clip_mask0);
- EXPECT_EQ(gfx::Size(300, 200), clip_mask0->bounds());
- EXPECT_EQ(c1_id, clip_mask0->clip_tree_index());
- int mask_effect_0_id = clip_mask0->effect_tree_index();
- const cc::EffectNode& mask_effect_0 =
- *GetPropertyTrees().effect_tree.Node(mask_effect_0_id);
- ASSERT_EQ(mask_isolation_0_id, mask_effect_0.parent_id);
- EXPECT_EQ(SkBlendMode::kDstIn, mask_effect_0.blend_mode);
+ EXPECT_TRUE(mask_isolation_0.is_fast_rounded_corner);
+ EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
+ mask_isolation_0.rounded_corner_bounds);
+ EXPECT_FALSE(mask_isolation_0.HasRenderSurface());
}
TEST_P(PaintArtifactCompositorTest,
- SynthesizedClipSimpleFastBorderNotSupported2) {
- // This tests the simplist case that a single layer needs to be clipped
+ SynthesizedClipShaderBasedBorderRadiusNotSupported2) {
+ // This tests the simplest case that a single layer needs to be clipped
// by a single composited rounded clip. Because the radius is unsymmetric,
// it falls back to a mask layer.
FloatSize corner(30, 40);
@@ -2786,14 +3129,14 @@ TEST_P(PaintArtifactCompositorTest,
TestPaintArtifact artifact;
artifact.Chunk(t0(), *c1, e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
Update(artifact.Build());
// Expectation in effect stack diagram:
- // l1
- // l0 [ mask_effect_0 ]
- // [ mask_isolation_0 ]
- // [ e0 ]
+ // clip_mask0
+ // content0 [ mask_effect_0 ]
+ // [ mask_isolation_0 ]
+ // [ e0 ]
// One content layer.
ASSERT_EQ(2u, LayerCount());
ASSERT_EQ(1u, SynthesizedClipLayerCount());
@@ -2801,9 +3144,6 @@ TEST_P(PaintArtifactCompositorTest,
const cc::Layer* content0 = LayerAt(0);
const cc::Layer* clip_mask0 = LayerAt(1);
- constexpr int c0_id = 1;
- constexpr int e0_id = 1;
-
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
@@ -2829,8 +3169,9 @@ TEST_P(PaintArtifactCompositorTest,
EXPECT_TRUE(clip_mask0->DrawsContent());
}
-TEST_P(PaintArtifactCompositorTest,
- SynthesizedClipSimpleFastBorderNotSupportedMacNonEqualCorners) {
+TEST_P(
+ PaintArtifactCompositorTest,
+ SynthesizedClipSimpleShaderBasedBorderRadiusNotSupportedMacNonEqualCorners) {
// Tests that on Mac, we fall back to a mask layer if the corners are not all
// the same radii.
FloatSize corner(30, 30);
@@ -2840,25 +3181,19 @@ TEST_P(PaintArtifactCompositorTest,
TestPaintArtifact artifact;
artifact.Chunk(t0(), *c1, e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
Update(artifact.Build());
#if defined(OS_MACOSX)
ASSERT_EQ(2u, LayerCount());
#else
- if (RuntimeEnabledFeatures::FastBorderRadiusEnabled())
- ASSERT_EQ(1u, LayerCount());
- else
- ASSERT_EQ(2u, LayerCount());
+ ASSERT_EQ(1u, LayerCount());
#endif
}
TEST_P(PaintArtifactCompositorTest, SynthesizedClipNested) {
- // This tests the simplist case that a single layer needs to be clipped
+ // This tests the simplest case that a single layer needs to be clipped
// by a single composited rounded clip.
- if (!RuntimeEnabledFeatures::FastBorderRadiusEnabled())
- return;
-
FloatSize corner(5, 5);
FloatRoundedRect rrect(FloatRect(50, 50, 300, 200), corner, corner, corner,
corner);
@@ -2873,18 +3208,18 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipNested) {
TestPaintArtifact artifact;
artifact.Chunk(t0(), *c1, *filter)
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
artifact.Chunk(*t1, *c3, *filter)
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
Update(artifact.Build());
// Expectation in effect stack diagram:
- // l0
- // [ mask_isolation_2 ]
- // l1 [ mask_isolation_1 ]
- // [ filter ]
- // [ mask_isolation_0 ]
- // [ e0 ]
+ // content1
+ // [ mask_isolation_2 ]
+ // content0 [ mask_isolation_1 ]
+ // [ filter ]
+ // [ mask_isolation_0 ]
+ // [ e0 ]
// Two content layers.
///
// mask_isolation_1 will have a render surface. mask_isolation_2 will not
@@ -2902,9 +3237,7 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipNested) {
const cc::Layer* content0 = LayerAt(0);
const cc::Layer* content1 = LayerAt(1);
- constexpr int c0_id = 1;
constexpr int c1_id = 2;
- constexpr int e0_id = 1;
constexpr int e1_id = 2;
int c3_id = content1->clip_tree_index();
@@ -2965,11 +3298,11 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipIsNotDrawable) {
TestPaintArtifact artifact;
artifact.Chunk(t0(), *c1, e0())
- .RectDrawing(FloatRect(0, 0, 0, 0), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 0, 0), Color::kBlack);
Update(artifact.Build());
// Expectation in effect stack diagram:
- // l1
+ // content0
// [ mask_isolation_0 ]
// [ e0 ]
// One content layer, no clip mask (because layer doesn't draw content).
@@ -2980,9 +3313,6 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipIsNotDrawable) {
const cc::Layer* content0 = LayerAt(0);
- constexpr int c0_id = 1;
- constexpr int e0_id = 1;
-
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
@@ -3005,7 +3335,7 @@ TEST_P(PaintArtifactCompositorTest, ReuseSyntheticClip) {
TestPaintArtifact artifact;
artifact.Chunk(t0(), *c1, e0())
- .RectDrawing(FloatRect(0, 0, 0, 0), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 0, 0), Color::kBlack);
Update(artifact.Build());
const cc::Layer* content0 = LayerAt(0);
@@ -3016,7 +3346,7 @@ TEST_P(PaintArtifactCompositorTest, ReuseSyntheticClip) {
TestPaintArtifact repeated_artifact;
repeated_artifact.Chunk(t0(), *c1, e0())
- .RectDrawing(FloatRect(0, 0, 0, 0), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 0, 0), Color::kBlack);
Update(repeated_artifact.Build());
const cc::Layer* content1 = LayerAt(0);
@@ -3028,7 +3358,7 @@ TEST_P(PaintArtifactCompositorTest, ReuseSyntheticClip) {
TestPaintArtifact changed_artifact;
changed_artifact.Chunk(t0(), *c2, e0())
- .RectDrawing(FloatRect(0, 0, 0, 0), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 0, 0), Color::kBlack);
Update(changed_artifact.Build());
const cc::Layer* content2 = LayerAt(0);
@@ -3050,14 +3380,14 @@ TEST_P(PaintArtifactCompositorTest,
TestPaintArtifact artifact;
artifact.Chunk(t0(), *c1, *e1)
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
Update(artifact.Build());
// Expectation in effect stack diagram:
- // l0 l1
- // [ e1 ][ mask_effect_0 ]
- // [ mask_isolation_0 ]
- // [ e0 ]
+ // content0 clip_mask0
+ // [ e1 ][ mask_effect_0 ]
+ // [ mask_isolation_0 ]
+ // [ e0 ]
// One content layer, one clip mask.
ASSERT_EQ(2u, LayerCount());
ASSERT_EQ(1u, SynthesizedClipLayerCount());
@@ -3065,9 +3395,6 @@ TEST_P(PaintArtifactCompositorTest,
const cc::Layer* content0 = LayerAt(0);
const cc::Layer* clip_mask0 = LayerAt(1);
- constexpr int c0_id = 1;
- constexpr int e0_id = 1;
-
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
@@ -3106,71 +3433,23 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipContiguous) {
TestPaintArtifact artifact;
artifact.Chunk(t0(), *c1, e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
artifact.Chunk(*t1, *c1, e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
Update(artifact.Build());
- if (RuntimeEnabledFeatures::FastBorderRadiusEnabled()) {
- // Expectation in effect stack diagram:
- // l2
- // l0 l1
- // [ mask_isolation_0 ]
- // [ e0 ]
- // Two content layers, one clip mask.
- ASSERT_EQ(2u, LayerCount());
- // There is still a "synthesized layer" but it's null.
- ASSERT_EQ(1u, SynthesizedClipLayerCount());
- EXPECT_FALSE(SynthesizedClipLayerAt(0));
-
- const cc::Layer* content0 = LayerAt(0);
- const cc::Layer* content1 = LayerAt(1);
-
- constexpr int t0_id = 1;
- constexpr int c0_id = 1;
- constexpr int e0_id = 1;
-
- EXPECT_EQ(t0_id, content0->transform_tree_index());
- int c1_id = content0->clip_tree_index();
- const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
- EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
- ASSERT_EQ(c0_id, cc_c1.parent_id);
- int mask_isolation_0_id = content0->effect_tree_index();
- const cc::EffectNode& mask_isolation_0 =
- *GetPropertyTrees().effect_tree.Node(mask_isolation_0_id);
- ASSERT_EQ(e0_id, mask_isolation_0.parent_id);
- EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode);
-
- int t1_id = content1->transform_tree_index();
- const cc::TransformNode& cc_t1 =
- *GetPropertyTrees().transform_tree.Node(t1_id);
- ASSERT_EQ(t0_id, cc_t1.parent_id);
- EXPECT_EQ(c1_id, content1->clip_tree_index());
- EXPECT_EQ(mask_isolation_0_id, content1->effect_tree_index());
-
- EXPECT_TRUE(mask_isolation_0.is_fast_rounded_corner);
- EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
- mask_isolation_0.rounded_corner_bounds);
- EXPECT_FALSE(mask_isolation_0.HasRenderSurface());
- return;
- }
-
// Expectation in effect stack diagram:
- // l2
- // l0 l1 [ mask_effect_0 ]
- // [ mask_isolation_0 ]
- // [ e0 ]
+ // content0 content1
+ // [ mask_isolation_0 ]
+ // [ e0 ]
// Two content layers, one clip mask.
- ASSERT_EQ(3u, LayerCount());
+ ASSERT_EQ(2u, LayerCount());
+ // There is still a "synthesized layer" but it's null.
ASSERT_EQ(1u, SynthesizedClipLayerCount());
+ EXPECT_FALSE(SynthesizedClipLayerAt(0));
const cc::Layer* content0 = LayerAt(0);
const cc::Layer* content1 = LayerAt(1);
- const cc::Layer* clip_mask0 = LayerAt(2);
-
- constexpr int t0_id = 1;
- constexpr int c0_id = 1;
- constexpr int e0_id = 1;
EXPECT_EQ(t0_id, content0->transform_tree_index());
int c1_id = content0->clip_tree_index();
@@ -3190,15 +3469,10 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipContiguous) {
EXPECT_EQ(c1_id, content1->clip_tree_index());
EXPECT_EQ(mask_isolation_0_id, content1->effect_tree_index());
- EXPECT_EQ(SynthesizedClipLayerAt(0), clip_mask0);
- EXPECT_EQ(gfx::Size(300, 200), clip_mask0->bounds());
- EXPECT_EQ(t0_id, clip_mask0->transform_tree_index());
- EXPECT_EQ(c1_id, clip_mask0->clip_tree_index());
- int mask_effect_0_id = clip_mask0->effect_tree_index();
- const cc::EffectNode& mask_effect_0 =
- *GetPropertyTrees().effect_tree.Node(mask_effect_0_id);
- ASSERT_EQ(mask_isolation_0_id, mask_effect_0.parent_id);
- EXPECT_EQ(SkBlendMode::kDstIn, mask_effect_0.blend_mode);
+ EXPECT_TRUE(mask_isolation_0.is_fast_rounded_corner);
+ EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
+ mask_isolation_0.rounded_corner_bounds);
+ EXPECT_FALSE(mask_isolation_0.HasRenderSurface());
}
TEST_P(PaintArtifactCompositorTest, SynthesizedClipDiscontiguous) {
@@ -3215,89 +3489,28 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDiscontiguous) {
TestPaintArtifact artifact;
artifact.Chunk(t0(), *c1, e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
artifact.Chunk(*t1, c0(), e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
artifact.Chunk(t0(), *c1, e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
Update(artifact.Build());
- if (RuntimeEnabledFeatures::FastBorderRadiusEnabled()) {
- // Expectation in effect stack diagram:
- // l1 l4
- // l0 l3
- // [ mask_isolation_0 ] l2 [ mask_isolation_1 ]
- // [ e0 ]
- // Three content layers.
- ASSERT_EQ(3u, LayerCount());
- // There are still "synthesized layers" but they're null.
- ASSERT_EQ(2u, SynthesizedClipLayerCount());
- EXPECT_FALSE(SynthesizedClipLayerAt(0));
- EXPECT_FALSE(SynthesizedClipLayerAt(1));
-
- const cc::Layer* content0 = LayerAt(0);
- const cc::Layer* content1 = LayerAt(1);
- const cc::Layer* content2 = LayerAt(2);
-
- constexpr int t0_id = 1;
- constexpr int c0_id = 1;
- constexpr int e0_id = 1;
-
- EXPECT_EQ(t0_id, content0->transform_tree_index());
- int c1_id = content0->clip_tree_index();
- const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
- EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
- ASSERT_EQ(c0_id, cc_c1.parent_id);
- int mask_isolation_0_id = content0->effect_tree_index();
- const cc::EffectNode& mask_isolation_0 =
- *GetPropertyTrees().effect_tree.Node(mask_isolation_0_id);
- ASSERT_EQ(e0_id, mask_isolation_0.parent_id);
- EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode);
- EXPECT_TRUE(mask_isolation_0.is_fast_rounded_corner);
- EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
- mask_isolation_0.rounded_corner_bounds);
- EXPECT_FALSE(mask_isolation_0.HasRenderSurface());
-
- int t1_id = content1->transform_tree_index();
- const cc::TransformNode& cc_t1 =
- *GetPropertyTrees().transform_tree.Node(t1_id);
- ASSERT_EQ(t0_id, cc_t1.parent_id);
- EXPECT_EQ(c0_id, content1->clip_tree_index());
- EXPECT_EQ(e0_id, content1->effect_tree_index());
-
- EXPECT_EQ(t0_id, content2->transform_tree_index());
- EXPECT_EQ(c1_id, content2->clip_tree_index());
- int mask_isolation_1_id = content2->effect_tree_index();
- const cc::EffectNode& mask_isolation_1 =
- *GetPropertyTrees().effect_tree.Node(mask_isolation_1_id);
- EXPECT_NE(mask_isolation_0_id, mask_isolation_1_id);
- ASSERT_EQ(e0_id, mask_isolation_1.parent_id);
- EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_1.blend_mode);
- EXPECT_TRUE(mask_isolation_1.is_fast_rounded_corner);
- EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
- mask_isolation_1.rounded_corner_bounds);
- EXPECT_FALSE(mask_isolation_1.HasRenderSurface());
- return;
- }
-
// Expectation in effect stack diagram:
- // l1 l4
- // l0 [ mask_effect_0 ] l3 [ mask_effect_1 ]
- // [ mask_isolation_0 ] l2 [ mask_isolation_1 ]
- // [ e0 ]
- // Three content layers, two clip mask.
- ASSERT_EQ(5u, LayerCount());
+ // content0 content2
+ // [ mask_isolation_0 ] content1 [ mask_isolation_1 ]
+ // [ e0 ]
+ // Three content layers.
+ ASSERT_EQ(3u, LayerCount());
+ // There are still "synthesized layers" but they're null because they use
+ // fast rounded corners.
ASSERT_EQ(2u, SynthesizedClipLayerCount());
+ EXPECT_FALSE(SynthesizedClipLayerAt(0));
+ EXPECT_FALSE(SynthesizedClipLayerAt(1));
const cc::Layer* content0 = LayerAt(0);
- const cc::Layer* clip_mask0 = LayerAt(1);
- const cc::Layer* content1 = LayerAt(2);
- const cc::Layer* content2 = LayerAt(3);
- const cc::Layer* clip_mask1 = LayerAt(4);
-
- constexpr int t0_id = 1;
- constexpr int c0_id = 1;
- constexpr int e0_id = 1;
+ const cc::Layer* content1 = LayerAt(1);
+ const cc::Layer* content2 = LayerAt(2);
EXPECT_EQ(t0_id, content0->transform_tree_index());
int c1_id = content0->clip_tree_index();
@@ -3309,17 +3522,10 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDiscontiguous) {
*GetPropertyTrees().effect_tree.Node(mask_isolation_0_id);
ASSERT_EQ(e0_id, mask_isolation_0.parent_id);
EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode);
- EXPECT_TRUE(mask_isolation_0.HasRenderSurface());
-
- EXPECT_EQ(SynthesizedClipLayerAt(0), clip_mask0);
- EXPECT_EQ(gfx::Size(300, 200), clip_mask0->bounds());
- EXPECT_EQ(t0_id, clip_mask0->transform_tree_index());
- EXPECT_EQ(c1_id, clip_mask0->clip_tree_index());
- int mask_effect_0_id = clip_mask0->effect_tree_index();
- const cc::EffectNode& mask_effect_0 =
- *GetPropertyTrees().effect_tree.Node(mask_effect_0_id);
- ASSERT_EQ(mask_isolation_0_id, mask_effect_0.parent_id);
- EXPECT_EQ(SkBlendMode::kDstIn, mask_effect_0.blend_mode);
+ EXPECT_TRUE(mask_isolation_0.is_fast_rounded_corner);
+ EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
+ mask_isolation_0.rounded_corner_bounds);
+ EXPECT_FALSE(mask_isolation_0.HasRenderSurface());
int t1_id = content1->transform_tree_index();
const cc::TransformNode& cc_t1 =
@@ -3336,17 +3542,10 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDiscontiguous) {
EXPECT_NE(mask_isolation_0_id, mask_isolation_1_id);
ASSERT_EQ(e0_id, mask_isolation_1.parent_id);
EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_1.blend_mode);
- EXPECT_TRUE(mask_isolation_1.HasRenderSurface());
-
- EXPECT_EQ(SynthesizedClipLayerAt(1), clip_mask1);
- EXPECT_EQ(gfx::Size(300, 200), clip_mask1->bounds());
- EXPECT_EQ(t0_id, clip_mask1->transform_tree_index());
- EXPECT_EQ(c1_id, clip_mask1->clip_tree_index());
- int mask_effect_1_id = clip_mask1->effect_tree_index();
- const cc::EffectNode& mask_effect_1 =
- *GetPropertyTrees().effect_tree.Node(mask_effect_1_id);
- ASSERT_EQ(mask_isolation_1_id, mask_effect_1.parent_id);
- EXPECT_EQ(SkBlendMode::kDstIn, mask_effect_1.blend_mode);
+ EXPECT_TRUE(mask_isolation_1.is_fast_rounded_corner);
+ EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
+ mask_isolation_1.rounded_corner_bounds);
+ EXPECT_FALSE(mask_isolation_1.HasRenderSurface());
}
TEST_P(PaintArtifactCompositorTest, SynthesizedClipAcrossChildEffect) {
@@ -3361,75 +3560,27 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipAcrossChildEffect) {
TestPaintArtifact artifact;
artifact.Chunk(t0(), *c1, e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
artifact.Chunk(t0(), *c1, *e1)
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
artifact.Chunk(t0(), *c1, e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
Update(artifact.Build());
- if (RuntimeEnabledFeatures::FastBorderRadiusEnabled()) {
- // Expectation in effect stack diagram:
- // l1 l3
- // l0 [ e1 ] l2
- // [ mask_isolation_0 ]
- // [ e0 ]
- // Three content layers.
- ASSERT_EQ(3u, LayerCount());
- // There is still a "synthesized layer" but it's null.
- ASSERT_EQ(1u, SynthesizedClipLayerCount());
- EXPECT_FALSE(SynthesizedClipLayerAt(0));
-
- const cc::Layer* content0 = LayerAt(0);
- const cc::Layer* content1 = LayerAt(1);
- const cc::Layer* content2 = LayerAt(2);
-
- constexpr int c0_id = 1;
- constexpr int e0_id = 1;
-
- int c1_id = content0->clip_tree_index();
- const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
- EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
- ASSERT_EQ(c0_id, cc_c1.parent_id);
- int mask_isolation_0_id = content0->effect_tree_index();
- const cc::EffectNode& mask_isolation_0 =
- *GetPropertyTrees().effect_tree.Node(mask_isolation_0_id);
- ASSERT_EQ(e0_id, mask_isolation_0.parent_id);
- EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode);
- EXPECT_FALSE(mask_isolation_0.HasRenderSurface());
-
- EXPECT_EQ(c1_id, content1->clip_tree_index());
- int e1_id = content1->effect_tree_index();
- const cc::EffectNode& cc_e1 = *GetPropertyTrees().effect_tree.Node(e1_id);
- ASSERT_EQ(mask_isolation_0_id, cc_e1.parent_id);
-
- EXPECT_EQ(c1_id, content2->clip_tree_index());
- EXPECT_EQ(mask_isolation_0_id, content2->effect_tree_index());
-
- int e2_id = content2->effect_tree_index();
- const cc::EffectNode& cc_e2 = *GetPropertyTrees().effect_tree.Node(e2_id);
- EXPECT_TRUE(cc_e2.is_fast_rounded_corner);
- EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
- mask_isolation_0.rounded_corner_bounds);
- return;
- }
-
// Expectation in effect stack diagram:
- // l1 l3
- // l0 [ e1 ] l2 [ mask_effect_0 ]
- // [ mask_isolation_0 ]
- // [ e0 ]
- // Three content layers, one clip mask.
- ASSERT_EQ(4u, LayerCount());
+ // content1
+ // content0 [ e1 ] content2
+ // [ mask_isolation_0 ]
+ // [ e0 ]
+ // Three content layers.
+ ASSERT_EQ(3u, LayerCount());
+ // There is still a "synthesized layer" but it's null.
ASSERT_EQ(1u, SynthesizedClipLayerCount());
+ EXPECT_FALSE(SynthesizedClipLayerAt(0));
const cc::Layer* content0 = LayerAt(0);
const cc::Layer* content1 = LayerAt(1);
const cc::Layer* content2 = LayerAt(2);
- const cc::Layer* clip_mask0 = LayerAt(3);
-
- constexpr int c0_id = 1;
- constexpr int e0_id = 1;
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
@@ -3440,7 +3591,7 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipAcrossChildEffect) {
*GetPropertyTrees().effect_tree.Node(mask_isolation_0_id);
ASSERT_EQ(e0_id, mask_isolation_0.parent_id);
EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode);
- EXPECT_TRUE(mask_isolation_0.HasRenderSurface());
+ EXPECT_FALSE(mask_isolation_0.HasRenderSurface());
EXPECT_EQ(c1_id, content1->clip_tree_index());
int e1_id = content1->effect_tree_index();
@@ -3450,14 +3601,11 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipAcrossChildEffect) {
EXPECT_EQ(c1_id, content2->clip_tree_index());
EXPECT_EQ(mask_isolation_0_id, content2->effect_tree_index());
- EXPECT_EQ(SynthesizedClipLayerAt(0), clip_mask0);
- EXPECT_EQ(gfx::Size(300, 200), clip_mask0->bounds());
- EXPECT_EQ(c1_id, clip_mask0->clip_tree_index());
- int mask_effect_0_id = clip_mask0->effect_tree_index();
- const cc::EffectNode& mask_effect_0 =
- *GetPropertyTrees().effect_tree.Node(mask_effect_0_id);
- ASSERT_EQ(mask_isolation_0_id, mask_effect_0.parent_id);
- EXPECT_EQ(SkBlendMode::kDstIn, mask_effect_0.blend_mode);
+ int e2_id = content2->effect_tree_index();
+ const cc::EffectNode& cc_e2 = *GetPropertyTrees().effect_tree.Node(e2_id);
+ EXPECT_TRUE(cc_e2.is_fast_rounded_corner);
+ EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
+ mask_isolation_0.rounded_corner_bounds);
}
TEST_P(PaintArtifactCompositorTest, SynthesizedClipRespectOutputClip) {
@@ -3476,97 +3624,30 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipRespectOutputClip) {
TestPaintArtifact artifact;
artifact.Chunk(t0(), *c1, e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
artifact.Chunk(t0(), *c1, *e1)
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
artifact.Chunk(t0(), *c1, e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
Update(artifact.Build());
- if (RuntimeEnabledFeatures::FastBorderRadiusEnabled()) {
- // Expectation in effect stack diagram:
- // l3
- // l1 l2 l5
- // l0 [ mask_isolation_1 ] l4
- // [ mask_isolation_0 ][ e1 ][ mask_isolation_2 ]
- // [ e0 ]
- // Three content layers.
- ASSERT_EQ(3u, LayerCount());
- // There are still "synthesized layers" but they're null.
- ASSERT_EQ(3u, SynthesizedClipLayerCount());
- EXPECT_FALSE(SynthesizedClipLayerAt(0));
- EXPECT_FALSE(SynthesizedClipLayerAt(1));
- EXPECT_FALSE(SynthesizedClipLayerAt(2));
-
- const cc::Layer* content0 = LayerAt(0);
- const cc::Layer* content1 = LayerAt(1);
- const cc::Layer* content2 = LayerAt(2);
-
- constexpr int c0_id = 1;
- constexpr int e0_id = 1;
-
- int c1_id = content0->clip_tree_index();
- const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
- EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
- ASSERT_EQ(c0_id, cc_c1.parent_id);
- int mask_isolation_0_id = content0->effect_tree_index();
- const cc::EffectNode& mask_isolation_0 =
- *GetPropertyTrees().effect_tree.Node(mask_isolation_0_id);
- ASSERT_EQ(e0_id, mask_isolation_0.parent_id);
- EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode);
- EXPECT_TRUE(mask_isolation_0.is_fast_rounded_corner);
- EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
- mask_isolation_0.rounded_corner_bounds);
- EXPECT_FALSE(mask_isolation_0.HasRenderSurface());
-
- EXPECT_EQ(c1_id, content1->clip_tree_index());
- int mask_isolation_1_id = content1->effect_tree_index();
- const cc::EffectNode& mask_isolation_1 =
- *GetPropertyTrees().effect_tree.Node(mask_isolation_1_id);
- EXPECT_NE(mask_isolation_0_id, mask_isolation_1_id);
- EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_1.blend_mode);
- int e1_id = mask_isolation_1.parent_id;
- const cc::EffectNode& cc_e1 = *GetPropertyTrees().effect_tree.Node(e1_id);
- ASSERT_EQ(e0_id, cc_e1.parent_id);
- EXPECT_TRUE(mask_isolation_1.is_fast_rounded_corner);
- EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
- mask_isolation_1.rounded_corner_bounds);
- EXPECT_FALSE(mask_isolation_1.HasRenderSurface());
-
- EXPECT_EQ(c1_id, content2->clip_tree_index());
- int mask_isolation_2_id = content2->effect_tree_index();
- const cc::EffectNode& mask_isolation_2 =
- *GetPropertyTrees().effect_tree.Node(mask_isolation_2_id);
- EXPECT_NE(mask_isolation_0_id, mask_isolation_2_id);
- EXPECT_NE(mask_isolation_1_id, mask_isolation_2_id);
- ASSERT_EQ(e0_id, mask_isolation_2.parent_id);
- EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_2.blend_mode);
- EXPECT_TRUE(mask_isolation_2.is_fast_rounded_corner);
- EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
- mask_isolation_2.rounded_corner_bounds);
- EXPECT_FALSE(mask_isolation_2.HasRenderSurface());
- return;
- }
-
// Expectation in effect stack diagram:
- // l3
- // l1 l2 [ mask_effect_1 ] l5
- // l0 [ mask_effect_0 ][ mask_isolation_1 ] l4 [ mask_effect_2 ]
+ // content1
+ // content0 [ mask_isolation_1 ] content2
// [ mask_isolation_0 ][ e1 ][ mask_isolation_2 ]
// [ e0 ]
- // Three content layers, three clip mask.
- ASSERT_EQ(6u, LayerCount());
+ // Three content layers.
+ ASSERT_EQ(3u, LayerCount());
+ // There are still "synthesized layers" but they're null because they use
+ // fast rounded corners.
ASSERT_EQ(3u, SynthesizedClipLayerCount());
+ EXPECT_FALSE(SynthesizedClipLayerAt(0));
+ EXPECT_FALSE(SynthesizedClipLayerAt(1));
+ EXPECT_FALSE(SynthesizedClipLayerAt(2));
const cc::Layer* content0 = LayerAt(0);
- const cc::Layer* clip_mask0 = LayerAt(1);
- const cc::Layer* content1 = LayerAt(2);
- const cc::Layer* clip_mask1 = LayerAt(3);
- const cc::Layer* content2 = LayerAt(4);
- const cc::Layer* clip_mask2 = LayerAt(5);
-
- constexpr int c0_id = 1;
- constexpr int e0_id = 1;
+ const cc::Layer* content1 = LayerAt(1);
+ const cc::Layer* content2 = LayerAt(2);
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
@@ -3577,15 +3658,10 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipRespectOutputClip) {
*GetPropertyTrees().effect_tree.Node(mask_isolation_0_id);
ASSERT_EQ(e0_id, mask_isolation_0.parent_id);
EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode);
-
- EXPECT_EQ(SynthesizedClipLayerAt(0), clip_mask0);
- EXPECT_EQ(gfx::Size(300, 200), clip_mask0->bounds());
- EXPECT_EQ(c1_id, clip_mask0->clip_tree_index());
- int mask_effect_0_id = clip_mask0->effect_tree_index();
- const cc::EffectNode& mask_effect_0 =
- *GetPropertyTrees().effect_tree.Node(mask_effect_0_id);
- ASSERT_EQ(mask_isolation_0_id, mask_effect_0.parent_id);
- EXPECT_EQ(SkBlendMode::kDstIn, mask_effect_0.blend_mode);
+ EXPECT_TRUE(mask_isolation_0.is_fast_rounded_corner);
+ EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
+ mask_isolation_0.rounded_corner_bounds);
+ EXPECT_FALSE(mask_isolation_0.HasRenderSurface());
EXPECT_EQ(c1_id, content1->clip_tree_index());
int mask_isolation_1_id = content1->effect_tree_index();
@@ -3596,15 +3672,10 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipRespectOutputClip) {
int e1_id = mask_isolation_1.parent_id;
const cc::EffectNode& cc_e1 = *GetPropertyTrees().effect_tree.Node(e1_id);
ASSERT_EQ(e0_id, cc_e1.parent_id);
-
- EXPECT_EQ(SynthesizedClipLayerAt(1), clip_mask1);
- EXPECT_EQ(gfx::Size(300, 200), clip_mask1->bounds());
- EXPECT_EQ(c1_id, clip_mask1->clip_tree_index());
- int mask_effect_1_id = clip_mask1->effect_tree_index();
- const cc::EffectNode& mask_effect_1 =
- *GetPropertyTrees().effect_tree.Node(mask_effect_1_id);
- ASSERT_EQ(mask_isolation_1_id, mask_effect_1.parent_id);
- EXPECT_EQ(SkBlendMode::kDstIn, mask_effect_1.blend_mode);
+ EXPECT_TRUE(mask_isolation_1.is_fast_rounded_corner);
+ EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
+ mask_isolation_1.rounded_corner_bounds);
+ EXPECT_FALSE(mask_isolation_1.HasRenderSurface());
EXPECT_EQ(c1_id, content2->clip_tree_index());
int mask_isolation_2_id = content2->effect_tree_index();
@@ -3614,15 +3685,10 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipRespectOutputClip) {
EXPECT_NE(mask_isolation_1_id, mask_isolation_2_id);
ASSERT_EQ(e0_id, mask_isolation_2.parent_id);
EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_2.blend_mode);
-
- EXPECT_EQ(SynthesizedClipLayerAt(2), clip_mask2);
- EXPECT_EQ(gfx::Size(300, 200), clip_mask2->bounds());
- EXPECT_EQ(c1_id, clip_mask2->clip_tree_index());
- int mask_effect_2_id = clip_mask2->effect_tree_index();
- const cc::EffectNode& mask_effect_2 =
- *GetPropertyTrees().effect_tree.Node(mask_effect_2_id);
- ASSERT_EQ(mask_isolation_2_id, mask_effect_2.parent_id);
- EXPECT_EQ(SkBlendMode::kDstIn, mask_effect_2.blend_mode);
+ EXPECT_TRUE(mask_isolation_2.is_fast_rounded_corner);
+ EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
+ mask_isolation_2.rounded_corner_bounds);
+ EXPECT_FALSE(mask_isolation_2.HasRenderSurface());
}
TEST_P(PaintArtifactCompositorTest, SynthesizedClipDelegateBlending) {
@@ -3643,94 +3709,30 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDelegateBlending) {
TestPaintArtifact artifact;
artifact.Chunk(t0(), *c1, e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
artifact.Chunk(t0(), *c1, *e1)
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
artifact.Chunk(t0(), *c1, e0())
- .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
Update(artifact.Build());
- if (RuntimeEnabledFeatures::FastBorderRadiusEnabled()) {
- // Expectation in effect stack diagram:
- // l1 l2 l3 l5
- // l0 [ e1 ] l4
- // [ mask_isolation_0 ][ mask_isolation_1 ][ mask_isolation_2 ]
- // [ e0 ]
- // Three content layers.
- ASSERT_EQ(3u, LayerCount());
- // There are still "synthesized layers" but they're null.
- ASSERT_EQ(3u, SynthesizedClipLayerCount());
- EXPECT_FALSE(SynthesizedClipLayerAt(0));
- EXPECT_FALSE(SynthesizedClipLayerAt(1));
- EXPECT_FALSE(SynthesizedClipLayerAt(2));
-
- const cc::Layer* content0 = LayerAt(0);
- const cc::Layer* content1 = LayerAt(1);
- const cc::Layer* content2 = LayerAt(2);
-
- constexpr int c0_id = 1;
- constexpr int e0_id = 1;
-
- int c1_id = content0->clip_tree_index();
- const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
- EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
- ASSERT_EQ(c0_id, cc_c1.parent_id);
- int mask_isolation_0_id = content0->effect_tree_index();
- const cc::EffectNode& mask_isolation_0 =
- *GetPropertyTrees().effect_tree.Node(mask_isolation_0_id);
- ASSERT_EQ(e0_id, mask_isolation_0.parent_id);
- EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode);
- EXPECT_TRUE(mask_isolation_0.is_fast_rounded_corner);
- EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
- mask_isolation_0.rounded_corner_bounds);
-
- EXPECT_EQ(c1_id, content1->clip_tree_index());
- int e1_id = content1->effect_tree_index();
- const cc::EffectNode& cc_e1 = *GetPropertyTrees().effect_tree.Node(e1_id);
- EXPECT_EQ(SkBlendMode::kSrcOver, cc_e1.blend_mode);
- int mask_isolation_1_id = cc_e1.parent_id;
- const cc::EffectNode& mask_isolation_1 =
- *GetPropertyTrees().effect_tree.Node(mask_isolation_1_id);
- EXPECT_NE(mask_isolation_0_id, mask_isolation_1_id);
- ASSERT_EQ(e0_id, mask_isolation_1.parent_id);
- EXPECT_EQ(SkBlendMode::kMultiply, mask_isolation_1.blend_mode);
- EXPECT_TRUE(mask_isolation_1.is_fast_rounded_corner);
- EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
- mask_isolation_1.rounded_corner_bounds);
-
- EXPECT_EQ(c1_id, content2->clip_tree_index());
- int mask_isolation_2_id = content2->effect_tree_index();
- const cc::EffectNode& mask_isolation_2 =
- *GetPropertyTrees().effect_tree.Node(mask_isolation_2_id);
- EXPECT_NE(mask_isolation_0_id, mask_isolation_2_id);
- EXPECT_NE(mask_isolation_1_id, mask_isolation_2_id);
- ASSERT_EQ(e0_id, mask_isolation_2.parent_id);
- EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode);
- EXPECT_TRUE(mask_isolation_2.is_fast_rounded_corner);
- EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
- mask_isolation_2.rounded_corner_bounds);
-
- return;
- }
-
// Expectation in effect stack diagram:
- // l1 l2 l3 l5
- // l0 [ mask_effect_0 ][ e1 ][ mask_effect_1 ] l4 [ mask_effect_2 ]
+ // content1
+ // content0 [ e1 ] content2
// [ mask_isolation_0 ][ mask_isolation_1 ][ mask_isolation_2 ]
// [ e0 ]
- // Three content layers, three clip mask.
- ASSERT_EQ(6u, LayerCount());
+ // Three content layers.
+ ASSERT_EQ(3u, LayerCount());
+ // There are still "synthesized layers" but they're null because they use
+ // fast rounded corners.
ASSERT_EQ(3u, SynthesizedClipLayerCount());
+ EXPECT_FALSE(SynthesizedClipLayerAt(0));
+ EXPECT_FALSE(SynthesizedClipLayerAt(1));
+ EXPECT_FALSE(SynthesizedClipLayerAt(2));
const cc::Layer* content0 = LayerAt(0);
- const cc::Layer* clip_mask0 = LayerAt(1);
- const cc::Layer* content1 = LayerAt(2);
- const cc::Layer* clip_mask1 = LayerAt(3);
- const cc::Layer* content2 = LayerAt(4);
- const cc::Layer* clip_mask2 = LayerAt(5);
-
- constexpr int c0_id = 1;
- constexpr int e0_id = 1;
+ const cc::Layer* content1 = LayerAt(1);
+ const cc::Layer* content2 = LayerAt(2);
int c1_id = content0->clip_tree_index();
const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
@@ -3741,15 +3743,9 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDelegateBlending) {
*GetPropertyTrees().effect_tree.Node(mask_isolation_0_id);
ASSERT_EQ(e0_id, mask_isolation_0.parent_id);
EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode);
-
- EXPECT_EQ(SynthesizedClipLayerAt(0), clip_mask0);
- EXPECT_EQ(gfx::Size(300, 200), clip_mask0->bounds());
- EXPECT_EQ(c1_id, clip_mask0->clip_tree_index());
- int mask_effect_0_id = clip_mask0->effect_tree_index();
- const cc::EffectNode& mask_effect_0 =
- *GetPropertyTrees().effect_tree.Node(mask_effect_0_id);
- ASSERT_EQ(mask_isolation_0_id, mask_effect_0.parent_id);
- EXPECT_EQ(SkBlendMode::kDstIn, mask_effect_0.blend_mode);
+ EXPECT_TRUE(mask_isolation_0.is_fast_rounded_corner);
+ EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
+ mask_isolation_0.rounded_corner_bounds);
EXPECT_EQ(c1_id, content1->clip_tree_index());
int e1_id = content1->effect_tree_index();
@@ -3761,15 +3757,9 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDelegateBlending) {
EXPECT_NE(mask_isolation_0_id, mask_isolation_1_id);
ASSERT_EQ(e0_id, mask_isolation_1.parent_id);
EXPECT_EQ(SkBlendMode::kMultiply, mask_isolation_1.blend_mode);
-
- EXPECT_EQ(SynthesizedClipLayerAt(1), clip_mask1);
- EXPECT_EQ(gfx::Size(300, 200), clip_mask1->bounds());
- EXPECT_EQ(c1_id, clip_mask1->clip_tree_index());
- int mask_effect_1_id = clip_mask1->effect_tree_index();
- const cc::EffectNode& mask_effect_1 =
- *GetPropertyTrees().effect_tree.Node(mask_effect_1_id);
- ASSERT_EQ(mask_isolation_1_id, mask_effect_1.parent_id);
- EXPECT_EQ(SkBlendMode::kDstIn, mask_effect_1.blend_mode);
+ EXPECT_TRUE(mask_isolation_1.is_fast_rounded_corner);
+ EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
+ mask_isolation_1.rounded_corner_bounds);
EXPECT_EQ(c1_id, content2->clip_tree_index());
int mask_isolation_2_id = content2->effect_tree_index();
@@ -3779,22 +3769,123 @@ TEST_P(PaintArtifactCompositorTest, SynthesizedClipDelegateBlending) {
EXPECT_NE(mask_isolation_1_id, mask_isolation_2_id);
ASSERT_EQ(e0_id, mask_isolation_2.parent_id);
EXPECT_EQ(SkBlendMode::kSrcOver, mask_isolation_0.blend_mode);
+ EXPECT_TRUE(mask_isolation_2.is_fast_rounded_corner);
+ EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
+ mask_isolation_2.rounded_corner_bounds);
+}
+
+TEST_P(PaintArtifactCompositorTest, SynthesizedClipDelegateBackdropFilter) {
+ // This tests the case that an effect with backdrop filter cannot share
+ // the synthesized mask with its siblings because its backdrop filter has to
+ // be applied by the outermost mask in the correct transform space.
+ FloatSize corner(5, 5);
+ FloatRoundedRect rrect(FloatRect(50, 50, 300, 200), corner, corner, corner,
+ corner);
+ auto c1 = CreateClip(c0(), t0(), rrect);
+
+ auto t1 = Create2DTranslation(t0(), 10, 20);
+ CompositorFilterOperations blur_filter;
+ blur_filter.AppendBlurFilter(5);
+ auto e1 = CreateBackdropFilterEffect(e0(), *t1, c1.get(), blur_filter,
+ FloatPoint());
+
+ TestPaintArtifact artifact;
+ artifact.Chunk(*t1, *c1, e0())
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
+ artifact.Chunk(*t1, *c1, *e1)
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
+ artifact.Chunk(*t1, *c1, e0())
+ .RectDrawing(IntRect(0, 0, 100, 100), Color::kBlack);
+ Update(artifact.Build());
+
+ // Expectation in effect stack diagram:
+ // content1
+ // content0 [ e1 ] clip_mask1 content2
+ // [ mask_isolation_0 ][ mask_isolation_1 ][ mask_isolation_2 ]
+ // [ e0 ]
+ // Three content layers.
+ ASSERT_EQ(4u, LayerCount());
+ const cc::Layer* content0 = LayerAt(0);
+ const cc::Layer* content1 = LayerAt(1);
+ 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.
+ EXPECT_FALSE(SynthesizedClipLayerAt(0));
+ EXPECT_EQ(clip_mask1, SynthesizedClipLayerAt(1));
+ EXPECT_FALSE(SynthesizedClipLayerAt(2));
+
+ int t1_id = content0->transform_tree_index();
+ EXPECT_EQ(t0_id, GetPropertyTrees().transform_tree.Node(t1_id)->parent_id);
+ int c1_id = content0->clip_tree_index();
+ const cc::ClipNode& cc_c1 = *GetPropertyTrees().clip_tree.Node(c1_id);
+ EXPECT_EQ(gfx::RectF(50, 50, 300, 200), cc_c1.clip);
+ ASSERT_EQ(c0_id, cc_c1.parent_id);
+ EXPECT_EQ(t0_id, cc_c1.transform_id);
+ int mask_isolation_0_id = content0->effect_tree_index();
+ const cc::EffectNode& mask_isolation_0 =
+ *GetPropertyTrees().effect_tree.Node(mask_isolation_0_id);
+ ASSERT_EQ(e0_id, mask_isolation_0.parent_id);
+ EXPECT_EQ(t0_id, mask_isolation_0.transform_id);
+ EXPECT_TRUE(mask_isolation_0.backdrop_filters.IsEmpty());
+ EXPECT_TRUE(mask_isolation_0.is_fast_rounded_corner);
+ EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
+ mask_isolation_0.rounded_corner_bounds);
+
+ EXPECT_EQ(t1_id, content1->transform_tree_index());
+ EXPECT_EQ(c1_id, content1->clip_tree_index());
+ 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(t1_id, cc_e1.transform_id);
+ EXPECT_EQ(c1_id, cc_e1.clip_id);
+ EXPECT_FALSE(cc_e1.backdrop_mask_element_id);
+
+ int mask_isolation_1_id = cc_e1.parent_id;
+ const cc::EffectNode& mask_isolation_1 =
+ *GetPropertyTrees().effect_tree.Node(mask_isolation_1_id);
+ EXPECT_NE(mask_isolation_0_id, mask_isolation_1_id);
+ ASSERT_EQ(e0_id, mask_isolation_1.parent_id);
+ EXPECT_EQ(t1_id, mask_isolation_1.transform_id);
+ EXPECT_EQ(c1_id, mask_isolation_1.clip_id);
+ EXPECT_FALSE(mask_isolation_1.backdrop_filters.IsEmpty());
+ EXPECT_FALSE(mask_isolation_1.is_fast_rounded_corner);
+ EXPECT_EQ(gfx::RRectF(), mask_isolation_1.rounded_corner_bounds);
- EXPECT_EQ(SynthesizedClipLayerAt(2), clip_mask2);
- EXPECT_EQ(gfx::Size(300, 200), clip_mask2->bounds());
- EXPECT_EQ(c1_id, clip_mask2->clip_tree_index());
- int mask_effect_2_id = clip_mask2->effect_tree_index();
- const cc::EffectNode& mask_effect_2 =
- *GetPropertyTrees().effect_tree.Node(mask_effect_2_id);
- ASSERT_EQ(mask_isolation_2_id, mask_effect_2.parent_id);
- EXPECT_EQ(SkBlendMode::kDstIn, mask_effect_2.blend_mode);
+ EXPECT_EQ(t0_id, clip_mask1->transform_tree_index());
+ EXPECT_EQ(c1_id, clip_mask1->clip_tree_index());
+ const cc::EffectNode& mask =
+ *GetPropertyTrees().effect_tree.Node(clip_mask1->effect_tree_index());
+ ASSERT_EQ(mask_isolation_1_id, mask.parent_id);
+ EXPECT_EQ(SkBlendMode::kDstIn, mask.blend_mode);
+ EXPECT_TRUE(static_cast<const cc::PictureLayer*>(clip_mask1)
+ ->is_backdrop_filter_mask());
+ EXPECT_TRUE(clip_mask1->element_id());
+ EXPECT_EQ(clip_mask1->element_id(),
+ mask_isolation_1.backdrop_mask_element_id);
+
+ EXPECT_EQ(t1_id, content2->transform_tree_index());
+ EXPECT_EQ(c1_id, content2->clip_tree_index());
+ int mask_isolation_2_id = content2->effect_tree_index();
+ const cc::EffectNode& mask_isolation_2 =
+ *GetPropertyTrees().effect_tree.Node(mask_isolation_2_id);
+ EXPECT_NE(mask_isolation_0_id, mask_isolation_2_id);
+ EXPECT_NE(mask_isolation_1_id, mask_isolation_2_id);
+ ASSERT_EQ(e0_id, mask_isolation_2.parent_id);
+ EXPECT_EQ(t0_id, mask_isolation_2.transform_id);
+ EXPECT_TRUE(mask_isolation_2.backdrop_filters.IsEmpty());
+ EXPECT_TRUE(mask_isolation_2.is_fast_rounded_corner);
+ EXPECT_EQ(gfx::RRectF(50, 50, 300, 200, 5),
+ mask_isolation_2.rounded_corner_bounds);
}
TEST_P(PaintArtifactCompositorTest, WillBeRemovedFromFrame) {
auto effect = CreateSampleEffectNodeWithElementId();
TestPaintArtifact artifact;
artifact.Chunk(t0(), c0(), *effect)
- .RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack);
+ .RectDrawing(IntRect(100, 100, 200, 100), Color::kBlack);
Update(artifact.Build());
ASSERT_EQ(1u, LayerCount());
@@ -3806,7 +3897,7 @@ TEST_P(PaintArtifactCompositorTest, WillBeRemovedFromFrame) {
TEST_P(PaintArtifactCompositorTest, ContentsNonOpaque) {
TestPaintArtifact artifact;
- artifact.Chunk().RectDrawing(FloatRect(100, 100, 200, 200), Color::kBlack);
+ artifact.Chunk().RectDrawing(IntRect(100, 100, 200, 200), Color::kBlack);
Update(artifact.Build());
ASSERT_EQ(1u, LayerCount());
EXPECT_FALSE(LayerAt(0)->contents_opaque());
@@ -3815,7 +3906,7 @@ TEST_P(PaintArtifactCompositorTest, ContentsNonOpaque) {
TEST_P(PaintArtifactCompositorTest, ContentsOpaque) {
TestPaintArtifact artifact;
artifact.Chunk()
- .RectDrawing(FloatRect(100, 100, 200, 200), Color::kBlack)
+ .RectDrawing(IntRect(100, 100, 200, 200), Color::kBlack)
.KnownToBeOpaque();
Update(artifact.Build());
ASSERT_EQ(1u, LayerCount());
@@ -3825,10 +3916,10 @@ TEST_P(PaintArtifactCompositorTest, ContentsOpaque) {
TEST_P(PaintArtifactCompositorTest, ContentsOpaqueUnitedNonOpaque) {
TestPaintArtifact artifact;
artifact.Chunk()
- .RectDrawing(FloatRect(100, 100, 200, 200), Color::kBlack)
+ .RectDrawing(IntRect(100, 100, 210, 210), Color::kBlack)
.KnownToBeOpaque()
.Chunk()
- .RectDrawing(FloatRect(200, 200, 200, 200), Color::kBlack)
+ .RectDrawing(IntRect(200, 200, 200, 200), Color::kBlack)
.KnownToBeOpaque();
Update(artifact.Build());
ASSERT_EQ(1u, LayerCount());
@@ -3836,13 +3927,30 @@ TEST_P(PaintArtifactCompositorTest, ContentsOpaqueUnitedNonOpaque) {
EXPECT_FALSE(LayerAt(0)->contents_opaque());
}
+TEST_P(PaintArtifactCompositorTest, ContentsOpaqueUnitedClippedToOpaque) {
+ // Almost the same as ContentsOpaqueUnitedNonOpaque, but with a clip which
+ // removes the non-opaque part of the layer, making the layer opaque.
+ auto clip1 = CreateClip(c0(), t0(), FloatRoundedRect(175, 175, 100, 100));
+ TestPaintArtifact artifact;
+ artifact.Chunk(t0(), *clip1, e0())
+ .RectDrawing(IntRect(100, 100, 210, 210), Color::kBlack)
+ .KnownToBeOpaque()
+ .Chunk(t0(), *clip1, e0())
+ .RectDrawing(IntRect(200, 200, 200, 200), Color::kBlack)
+ .KnownToBeOpaque();
+ Update(artifact.Build());
+ ASSERT_EQ(1u, LayerCount());
+ EXPECT_EQ(gfx::Size(100, 100), LayerAt(0)->bounds());
+ EXPECT_TRUE(LayerAt(0)->contents_opaque());
+}
+
TEST_P(PaintArtifactCompositorTest, ContentsOpaqueUnitedOpaque1) {
TestPaintArtifact artifact;
artifact.Chunk()
- .RectDrawing(FloatRect(100, 100, 300, 300), Color::kBlack)
+ .RectDrawing(IntRect(100, 100, 300, 300), Color::kBlack)
.KnownToBeOpaque()
.Chunk()
- .RectDrawing(FloatRect(200, 200, 200, 200), Color::kBlack)
+ .RectDrawing(IntRect(200, 200, 200, 200), Color::kBlack)
.KnownToBeOpaque();
Update(artifact.Build());
ASSERT_EQ(1u, LayerCount());
@@ -3850,20 +3958,38 @@ TEST_P(PaintArtifactCompositorTest, ContentsOpaqueUnitedOpaque1) {
EXPECT_TRUE(LayerAt(0)->contents_opaque());
}
+TEST_P(PaintArtifactCompositorTest, ContentsOpaqueUnitedWithRoundedClip) {
+ // Almost the same as ContentsOpaqueUnitedOpaque1, but the first layer has a
+ // rounded clip.
+ FloatSize corner(5, 5);
+ auto clip1 = CreateClip(c0(), t0(),
+ FloatRoundedRect(FloatRect(175, 175, 100, 100),
+ corner, corner, corner, corner));
+ TestPaintArtifact artifact;
+ artifact.Chunk(t0(), *clip1, e0())
+ .RectDrawing(IntRect(100, 100, 210, 210), Color::kBlack)
+ .KnownToBeOpaque()
+ .Chunk(t0(), c0(), e0())
+ .RectDrawing(IntRect(200, 200, 100, 100), Color::kBlack)
+ .KnownToBeOpaque();
+ Update(artifact.Build());
+ ASSERT_EQ(1u, LayerCount());
+ EXPECT_EQ(gfx::Size(125, 125), LayerAt(0)->bounds());
+ EXPECT_FALSE(LayerAt(0)->contents_opaque());
+}
+
TEST_P(PaintArtifactCompositorTest, ContentsOpaqueUnitedOpaque2) {
TestPaintArtifact artifact;
artifact.Chunk()
- .RectDrawing(FloatRect(100, 100, 200, 200), Color::kBlack)
+ .RectDrawing(IntRect(100, 100, 200, 200), Color::kBlack)
.KnownToBeOpaque()
.Chunk()
- .RectDrawing(FloatRect(100, 100, 300, 300), Color::kBlack)
+ .RectDrawing(IntRect(100, 100, 300, 300), Color::kBlack)
.KnownToBeOpaque();
Update(artifact.Build());
ASSERT_EQ(1u, LayerCount());
EXPECT_EQ(gfx::Size(300, 300), LayerAt(0)->bounds());
- // TODO(crbug.com/701991): Upgrade GeometryMapper to make this test pass with
- // the following EXPECT_FALSE changed to EXPECT_TRUE.
- EXPECT_FALSE(LayerAt(0)->contents_opaque());
+ EXPECT_TRUE(LayerAt(0)->contents_opaque());
}
TEST_P(PaintArtifactCompositorTest, DecompositeEffectWithNoOutputClip) {
@@ -3873,9 +3999,9 @@ TEST_P(PaintArtifactCompositorTest, DecompositeEffectWithNoOutputClip) {
auto effect1 = CreateOpacityEffect(e0(), t0(), nullptr, 0.5);
TestPaintArtifact artifact;
- artifact.Chunk().RectDrawing(FloatRect(50, 50, 100, 100), Color::kGray);
+ artifact.Chunk().RectDrawing(IntRect(50, 50, 100, 100), Color::kGray);
artifact.Chunk(t0(), *clip1, *effect1)
- .RectDrawing(FloatRect(100, 100, 100, 100), Color::kGray);
+ .RectDrawing(IntRect(100, 100, 100, 100), Color::kGray);
Update(artifact.Build());
ASSERT_EQ(1u, LayerCount());
@@ -3895,9 +4021,9 @@ TEST_P(PaintArtifactCompositorTest, CompositedEffectWithNoOutputClip) {
TestPaintArtifact artifact;
artifact.Chunk(t0(), c0(), *effect1)
- .RectDrawing(FloatRect(50, 50, 100, 100), Color::kGray);
+ .RectDrawing(IntRect(50, 50, 100, 100), Color::kGray);
artifact.Chunk(t0(), *clip1, *effect1)
- .RectDrawing(FloatRect(100, 100, 100, 100), Color::kGray);
+ .RectDrawing(IntRect(100, 100, 100, 100), Color::kGray);
Update(artifact.Build());
ASSERT_EQ(1u, LayerCount());
@@ -3918,7 +4044,7 @@ TEST_P(PaintArtifactCompositorTest, LayerRasterInvalidationWithClip) {
auto clip = CreateClip(c0(), t0(), FloatRoundedRect(10, 20, 300, 400));
TestPaintArtifact artifact1;
artifact1.Chunk(t0(), *clip, e0())
- .RectDrawing(FloatRect(50, 50, 200, 200), Color::kBlack);
+ .RectDrawing(IntRect(50, 50, 200, 200), Color::kBlack);
artifact1.Client(0).Validate();
artifact1.Client(1).Validate();
Update(artifact1.Build());
@@ -3936,7 +4062,7 @@ TEST_P(PaintArtifactCompositorTest, LayerRasterInvalidationWithClip) {
.Chunk(artifact1.Client(0))
.Properties(t0(), *clip, e0())
.RectDrawing(artifact1.Client(1),
- FloatRect(0, 0, 400, 200), Color::kBlack)
+ IntRect(0, 0, 400, 200), Color::kBlack)
.Build();
// Simluate commit to the compositor thread.
layer->PushPropertiesTo(
@@ -3958,7 +4084,7 @@ TEST_P(PaintArtifactCompositorTest, LayerRasterInvalidationWithClip) {
TestPaintArtifact()
.Chunk(artifact1.Client(0))
.Properties(t0(), *clip, e0())
- .RectDrawing(artifact1.Client(1), FloatRect(-100, -200, 500, 800),
+ .RectDrawing(artifact1.Client(1), IntRect(-100, -200, 500, 800),
Color::kBlack)
.Build();
// Simluate commit to the compositor thread.
@@ -4031,7 +4157,7 @@ TEST_P(PaintArtifactCompositorTest, InSubtreeOfPageScale) {
TestPaintArtifact artifact;
artifact.Chunk(*descendant_transform, c0(), e0())
- .RectDrawing(FloatRect(0, 0, 10, 10), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 10, 10), Color::kBlack);
ViewportProperties viewport_properties;
viewport_properties.page_scale = page_scale_transform.get();
Update(artifact.Build(), viewport_properties);
@@ -4085,7 +4211,7 @@ TEST_P(PaintArtifactCompositorTest, ViewportPageScale) {
TestPaintArtifact artifact;
artifact.Chunk(*scroll_translation, c0(), e0())
- .RectDrawing(FloatRect(0, 0, 10, 10), Color::kBlack);
+ .RectDrawing(IntRect(0, 0, 10, 10), Color::kBlack);
ViewportProperties viewport_properties;
viewport_properties.page_scale = scale_transform_node.get();
Update(artifact.Build(), viewport_properties);
@@ -4135,7 +4261,7 @@ TEST_P(PaintArtifactCompositorTest, OpacityRenderSurfaces) {
FloatPoint3D(), CompositingReason::k3DTransform);
TestPaintArtifact artifact;
- FloatRect r(150, 150, 100, 100);
+ IntRect r(150, 150, 100, 100);
artifact.Chunk(t0(), c0(), *aa).RectDrawing(r, Color::kWhite);
artifact.Chunk(t0(), c0(), *ab).RectDrawing(r, Color::kWhite);
artifact.Chunk(t0(), c0(), *b).RectDrawing(r, Color::kWhite);
@@ -4184,7 +4310,7 @@ TEST_P(PaintArtifactCompositorTest, OpacityRenderSurfacesWithFilterChildren) {
auto filter2 = CreateFilterEffect(*opacity, filter, FloatPoint(),
CompositingReason::kActiveFilterAnimation);
- FloatRect r(150, 150, 100, 100);
+ IntRect r(150, 150, 100, 100);
Update(TestPaintArtifact()
.Chunk(t0(), c0(), *filter1)
.RectDrawing(r, Color::kWhite)
@@ -4222,7 +4348,7 @@ TEST_P(PaintArtifactCompositorTest, OpacityAnimationRenderSurfaces) {
FloatPoint3D(), CompositingReason::k3DTransform);
TestPaintArtifact artifact;
- FloatRect r(150, 150, 100, 100);
+ IntRect r(150, 150, 100, 100);
artifact.Chunk(t0(), c0(), *aa).RectDrawing(r, Color::kWhite);
artifact.Chunk(t0(), c0(), *ab).RectDrawing(r, Color::kWhite);
artifact.Chunk(t0(), c0(), *b).RectDrawing(r, Color::kWhite);
@@ -4273,12 +4399,10 @@ TEST_P(PaintArtifactCompositorTest, OpacityRenderSurfacesWithBackdropChildren) {
auto a = CreateOpacityEffect(*e, 0.5f);
CompositorFilterOperations blur_filter;
blur_filter.AppendBlurFilter(5);
- auto bd = CreateBackdropFilterEffect(
- *a, blur_filter, FloatPoint(),
- CompositingReason::kActiveBackdropFilterAnimation);
+ auto bd = CreateBackdropFilterEffect(*a, blur_filter, FloatPoint());
TestPaintArtifact artifact;
- FloatRect r(150, 150, 100, 100);
+ IntRect r(150, 150, 100, 100);
artifact.Chunk(t0(), c0(), *a).RectDrawing(r, Color::kWhite);
artifact.Chunk(t0(), c0(), *bd).RectDrawing(r, Color::kWhite);
Update(artifact.Build());
@@ -4292,12 +4416,11 @@ TEST_P(PaintArtifactCompositorTest,
DirectTransformAnimationCausesRenderSurfaceFor2dAxisMisalignedClip) {
// When a clip is affected by an animated transform, we should get a render
// surface for the effect node.
- auto t1 = CreateTransform(t0(), TransformationMatrix(), FloatPoint3D(),
- CompositingReason::kActiveTransformAnimation);
+ auto t1 = CreateAnimatingTransform(t0());
auto e1 = CreateOpacityEffect(e0(), *t1, nullptr, 1.f);
auto c1 = CreateClip(c0(), t0(), FloatRoundedRect(50, 50, 50, 50));
TestPaintArtifact artifact;
- FloatRect r(150, 150, 100, 100);
+ IntRect r(150, 150, 100, 100);
artifact.Chunk(t0(), c0(), e0()).RectDrawing(r, Color::kWhite);
artifact.Chunk(t0(), *c1, *e1).RectDrawing(r, Color::kWhite);
Update(artifact.Build());
@@ -4312,13 +4435,12 @@ TEST_P(PaintArtifactCompositorTest,
IndirectTransformAnimationCausesRenderSurfaceFor2dAxisMisalignedClip) {
// When a clip is affected by an animated transform, we should get a render
// surface for the effect node.
- auto t1 = CreateTransform(t0(), TransformationMatrix(), FloatPoint3D(),
- CompositingReason::kActiveTransformAnimation);
+ auto t1 = CreateAnimatingTransform(t0());
auto t2 = Create2DTranslation(*t1, 10, 20);
auto e1 = CreateOpacityEffect(e0(), *t2, nullptr, 1.f);
auto c1 = CreateClip(c0(), t0(), FloatRoundedRect(50, 50, 50, 50));
TestPaintArtifact artifact;
- FloatRect r(150, 150, 100, 100);
+ IntRect r(150, 150, 100, 100);
artifact.Chunk(t0(), c0(), e0()).RectDrawing(r, Color::kWhite);
artifact.Chunk(t0(), *c1, *e1).RectDrawing(r, Color::kWhite);
Update(artifact.Build());
@@ -4338,9 +4460,9 @@ TEST_P(PaintArtifactCompositorTest, OpacityIndirectlyAffectingTwoLayers) {
TestPaintArtifact artifact;
artifact.Chunk(t0(), c0(), *child_composited_effect)
- .RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite);
+ .RectDrawing(IntRect(150, 150, 100, 100), Color::kWhite);
artifact.Chunk(t0(), c0(), *grandchild_composited_effect)
- .RectDrawing(FloatRect(150, 150, 100, 100), Color::kGray);
+ .RectDrawing(IntRect(150, 150, 100, 100), Color::kGray);
Update(artifact.Build());
ASSERT_EQ(2u, LayerCount());
@@ -4364,9 +4486,9 @@ TEST_P(PaintArtifactCompositorTest,
TestPaintArtifact artifact;
artifact.Chunk(t0(), c0(), *child_composited_effect)
- .RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite);
+ .RectDrawing(IntRect(150, 150, 100, 100), Color::kWhite);
artifact.Chunk(t0(), c0(), *grandchild_composited_effect)
- .RectDrawing(FloatRect(150, 150, 100, 100), Color::kGray);
+ .RectDrawing(IntRect(150, 150, 100, 100), Color::kGray);
Update(artifact.Build());
ASSERT_EQ(2u, LayerCount());
@@ -4399,7 +4521,7 @@ TEST_P(PaintArtifactCompositorTest,
Update(TestPaintArtifact()
.Chunk(t0(), c0(), *e1)
- .RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite)
+ .RectDrawing(IntRect(150, 150, 100, 100), Color::kWhite)
.Build());
ASSERT_EQ(1u, LayerCount());
EXPECT_OPACITY(LayerAt(0)->effect_tree_index(), 1.f, kNoRenderSurface);
@@ -4412,7 +4534,7 @@ TEST_P(PaintArtifactCompositorTest, FilterCreatesRenderSurface) {
CompositingReason::kActiveFilterAnimation);
Update(TestPaintArtifact()
.Chunk(t0(), c0(), *e1)
- .RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite)
+ .RectDrawing(IntRect(150, 150, 100, 100), Color::kWhite)
.Build());
ASSERT_EQ(1u, LayerCount());
EXPECT_OPACITY(LayerAt(0)->effect_tree_index(), 1.f, kHasRenderSurface);
@@ -4422,7 +4544,7 @@ TEST_P(PaintArtifactCompositorTest, FilterAnimationCreatesRenderSurface) {
auto e1 = CreateAnimatingFilterEffect(e0());
Update(TestPaintArtifact()
.Chunk(t0(), c0(), *e1)
- .RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite)
+ .RectDrawing(IntRect(150, 150, 100, 100), Color::kWhite)
.Build());
ASSERT_EQ(1u, LayerCount());
EXPECT_OPACITY(LayerAt(0)->effect_tree_index(), 1.f, kHasRenderSurface);
@@ -4431,11 +4553,10 @@ TEST_P(PaintArtifactCompositorTest, FilterAnimationCreatesRenderSurface) {
TEST_P(PaintArtifactCompositorTest, BackdropFilterCreatesRenderSurface) {
CompositorFilterOperations filter;
filter.AppendBlurFilter(5);
- auto e1 = CreateBackdropFilterEffect(e0(), filter, FloatPoint(),
- CompositingReason::kBackdropFilter);
+ auto e1 = CreateBackdropFilterEffect(e0(), filter, FloatPoint());
Update(TestPaintArtifact()
.Chunk(t0(), c0(), *e1)
- .RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite)
+ .RectDrawing(IntRect(150, 150, 100, 100), Color::kWhite)
.Build());
ASSERT_EQ(1u, LayerCount());
EXPECT_OPACITY(LayerAt(0)->effect_tree_index(), 1.f, kHasRenderSurface);
@@ -4446,7 +4567,7 @@ TEST_P(PaintArtifactCompositorTest,
auto e1 = CreateAnimatingBackdropFilterEffect(e0());
Update(TestPaintArtifact()
.Chunk(t0(), c0(), *e1)
- .RectDrawing(FloatRect(150, 150, 100, 100), Color::kWhite)
+ .RectDrawing(IntRect(150, 150, 100, 100), Color::kWhite)
.Build());
ASSERT_EQ(1u, LayerCount());
EXPECT_OPACITY(LayerAt(0)->effect_tree_index(), 1.f, kHasRenderSurface);
@@ -4460,7 +4581,7 @@ TEST_P(PaintArtifactCompositorTest, Non2dAxisAlignedClip) {
TestPaintArtifact artifact;
artifact.Chunk(t0(), *clip, *opacity)
- .RectDrawing(FloatRect(50, 50, 50, 50), Color::kWhite);
+ .RectDrawing(IntRect(50, 50, 50, 50), Color::kWhite);
Update(artifact.Build());
ASSERT_EQ(1u, LayerCount());
@@ -4485,7 +4606,7 @@ TEST_P(PaintArtifactCompositorTest, Non2dAxisAlignedRoundedRectClip) {
TestPaintArtifact artifact;
artifact.Chunk(t0(), *clip, *opacity)
- .RectDrawing(FloatRect(50, 50, 50, 50), Color::kWhite);
+ .RectDrawing(IntRect(50, 50, 50, 50), Color::kWhite);
Update(artifact.Build());
ASSERT_EQ(1u, LayerCount());
@@ -4520,11 +4641,11 @@ TEST_P(PaintArtifactCompositorTest,
TestPaintArtifact artifact;
artifact.Chunk(t0(), c0(), *opacity)
- .RectDrawing(FloatRect(50, 50, 50, 50), Color::kWhite);
+ .RectDrawing(IntRect(50, 50, 50, 50), Color::kWhite);
artifact.Chunk(*rotate1, c0(), *opacity)
- .RectDrawing(FloatRect(50, 50, 50, 50), Color::kWhite);
+ .RectDrawing(IntRect(50, 50, 50, 50), Color::kWhite);
artifact.Chunk(*rotate2, *clip, *opacity)
- .RectDrawing(FloatRect(50, 50, 50, 50), Color::kWhite);
+ .RectDrawing(IntRect(50, 50, 50, 50), Color::kWhite);
Update(artifact.Build());
ASSERT_EQ(3u, LayerCount());
@@ -4549,7 +4670,7 @@ TEST_P(PaintArtifactCompositorTest, TransformChange) {
Update(TestPaintArtifact()
.Chunk(1)
.Properties(*t2, c0(), e0())
- .RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack)
+ .RectDrawing(IntRect(100, 100, 200, 100), Color::kBlack)
.Build());
ASSERT_EQ(1u, LayerCount());
cc::Layer* layer = LayerAt(0);
@@ -4564,7 +4685,7 @@ TEST_P(PaintArtifactCompositorTest, TransformChange) {
Update(TestPaintArtifact()
.Chunk(1)
.Properties(*t2, c0(), e0())
- .RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack)
+ .RectDrawing(IntRect(100, 100, 200, 100), Color::kBlack)
.Build());
ASSERT_EQ(1u, LayerCount());
@@ -4589,7 +4710,7 @@ TEST_P(PaintArtifactCompositorTest, TransformChange) {
Update(TestPaintArtifact()
.Chunk(1)
.Properties(*t2, c0(), e0())
- .RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack)
+ .RectDrawing(IntRect(100, 100, 200, 100), Color::kBlack)
.Build());
ASSERT_EQ(1u, LayerCount());
@@ -4611,7 +4732,7 @@ TEST_P(PaintArtifactCompositorTest, TransformChange) {
Update(TestPaintArtifact()
.Chunk(1)
.Properties(*t2, c0(), e0())
- .RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack)
+ .RectDrawing(IntRect(100, 100, 200, 100), Color::kBlack)
.Build());
ASSERT_EQ(1u, LayerCount());
@@ -4631,7 +4752,7 @@ TEST_P(PaintArtifactCompositorTest, EffectChange) {
Update(TestPaintArtifact()
.Chunk(1)
.Properties(t0(), c0(), *e2)
- .RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack)
+ .RectDrawing(IntRect(100, 100, 200, 100), Color::kBlack)
.Build());
ASSERT_EQ(1u, LayerCount());
cc::Layer* layer = LayerAt(0);
@@ -4650,7 +4771,7 @@ TEST_P(PaintArtifactCompositorTest, EffectChange) {
Update(TestPaintArtifact()
.Chunk(1)
.Properties(t0(), c0(), *e2)
- .RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack)
+ .RectDrawing(IntRect(100, 100, 200, 100), Color::kBlack)
.Build());
ASSERT_EQ(1u, LayerCount());
@@ -4678,7 +4799,7 @@ TEST_P(PaintArtifactCompositorTest, EffectChange) {
Update(TestPaintArtifact()
.Chunk(1)
.Properties(t0(), c0(), *e2)
- .RectDrawing(FloatRect(100, 100, 200, 100), Color::kBlack)
+ .RectDrawing(IntRect(100, 100, 200, 100), Color::kBlack)
.Build());
ASSERT_EQ(1u, LayerCount());
@@ -4691,4 +4812,44 @@ TEST_P(PaintArtifactCompositorTest, EffectChange) {
->effect_changed);
}
+TEST_P(PaintArtifactCompositorTest, DirectlySetScrollOffset) {
+ CompositorElementId scroll_element_id = ScrollElementId(123);
+ auto scroll = CreateScroll(ScrollPaintPropertyNode::Root(), ScrollState1(),
+ kNotScrollingOnMain, scroll_element_id);
+ auto scroll_translation = CreateScrollTranslation(
+ t0(), 7, 9, *scroll, CompositingReason::kWillChangeTransform);
+
+ TestPaintArtifact artifact;
+ CreateScrollableChunk(artifact, *scroll_translation, c0(), e0());
+ Update(artifact.Build());
+
+ auto& scroll_tree = GetPropertyTrees().scroll_tree;
+ auto* scroll_layer = ScrollableLayerAt(0);
+ auto* scroll_node = scroll_tree.FindNodeFromElementId(scroll_element_id);
+ auto& transform_tree = GetPropertyTrees().transform_tree;
+ auto* transform_node = transform_tree.Node(scroll_node->transform_id);
+ EXPECT_EQ(scroll_element_id, scroll_node->element_id);
+ EXPECT_EQ(scroll_element_id, scroll_layer->element_id());
+ EXPECT_EQ(scroll_node->id, scroll_layer->scroll_tree_index());
+ EXPECT_EQ(gfx::ScrollOffset(-7, -9),
+ scroll_tree.current_scroll_offset(scroll_element_id));
+ EXPECT_EQ(gfx::ScrollOffset(-7, -9), transform_node->scroll_offset);
+
+ auto& host = GetLayerTreeHost();
+ host.Composite(base::TimeTicks::Now(), true);
+ ASSERT_FALSE(host.LayersThatShouldPushProperties().contains(scroll_layer));
+ ASSERT_FALSE(host.proxy()->CommitRequested());
+ ASSERT_FALSE(transform_tree.needs_update());
+
+ ASSERT_TRUE(GetPaintArtifactCompositor().DirectlySetScrollOffset(
+ scroll_element_id, FloatPoint(-10, -20)));
+ EXPECT_TRUE(host.LayersThatShouldPushProperties().contains(scroll_layer));
+ EXPECT_TRUE(host.proxy()->CommitRequested());
+ EXPECT_EQ(gfx::ScrollOffset(-10, -20),
+ scroll_tree.current_scroll_offset(scroll_element_id));
+ // DirectlySetScrollOffset doesn't update transform node.
+ EXPECT_EQ(gfx::ScrollOffset(-7, -9), transform_node->scroll_offset);
+ EXPECT_FALSE(transform_tree.needs_update());
+}
+
} // namespace blink
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 1bc279443be..7ea7c8ab662 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,7 +158,7 @@ class ConversionContext {
*current_transform_);
}
- void AppendRestore(size_t n) {
+ void AppendRestore(wtf_size_t n) {
cc_list_.StartPaint();
while (n--)
cc_list_.push<cc::RestoreOp>();
@@ -172,8 +172,7 @@ class ConversionContext {
// Ends the effect on the top of the state stack if the stack is not empty,
// and update the bounds of the SaveLayer[Alpha]Op of the effect.
void EndEffect();
- void UpdateEffectBounds(const base::Optional<FloatRect>&,
- const TransformPaintPropertyNode&);
+ void UpdateEffectBounds(const FloatRect&, const TransformPaintPropertyNode&);
// Starts a clip state by adjusting the transform state, applying
// |combined_clip_rect| which is combined from one or more consecutive clips,
@@ -244,7 +243,7 @@ class ConversionContext {
// Records the bounds of the effect which initiated the entry. Note that
// the effect is not |this->effect| (which is the previous effect), but the
// |current_effect_| when this entry is the top of the stack.
- base::Optional<FloatRect> bounds;
+ FloatRect bounds;
};
Vector<EffectBoundsInfo> effect_bounds_stack_;
@@ -278,6 +277,7 @@ void ConversionContext::TranslateForLayerOffsetOnce() {
}
void ConversionContext::SwitchToChunkState(const PaintChunk& chunk) {
+ TranslateForLayerOffsetOnce();
chunk_to_layer_mapper_.SwitchToChunk(chunk);
const auto& chunk_state = chunk.properties;
@@ -304,18 +304,21 @@ static bool CombineClip(const ClipPaintPropertyNode& clip,
return false;
// Don't combine two rounded clip rects.
- bool clip_is_rounded = clip.ClipRect().IsRounded();
+ bool clip_is_rounded = clip.PixelSnappedClipRect().IsRounded();
bool combined_is_rounded = combined_clip_rect.IsRounded();
if (clip_is_rounded && combined_is_rounded)
return false;
// If one is rounded and the other contains the rounded bounds, use the
// rounded as the combined.
- if (combined_is_rounded)
- return clip.ClipRect().Rect().Contains(combined_clip_rect.Rect());
+ if (combined_is_rounded) {
+ return clip.PixelSnappedClipRect().Rect().Contains(
+ combined_clip_rect.Rect());
+ }
if (clip_is_rounded) {
- if (combined_clip_rect.Rect().Contains(clip.ClipRect().Rect())) {
- combined_clip_rect = clip.ClipRect();
+ if (combined_clip_rect.Rect().Contains(
+ clip.PixelSnappedClipRect().Rect())) {
+ combined_clip_rect = clip.PixelSnappedClipRect();
return true;
}
return false;
@@ -323,8 +326,8 @@ static bool CombineClip(const ClipPaintPropertyNode& clip,
// The combined is the intersection if both are rectangular.
DCHECK(!combined_is_rounded && !clip_is_rounded);
- combined_clip_rect = FloatRoundedRect(
- Intersection(combined_clip_rect.Rect(), clip.ClipRect().Rect()));
+ combined_clip_rect = FloatRoundedRect(Intersection(
+ combined_clip_rect.Rect(), clip.PixelSnappedClipRect().Rect()));
return true;
}
@@ -380,9 +383,10 @@ void ConversionContext::SwitchToClip(
// Step 3: Now apply the list of clips in top-down order.
DCHECK(pending_clips.size());
- auto pending_combined_clip_rect = pending_clips.back()->ClipRect();
+ auto pending_combined_clip_rect =
+ pending_clips.back()->PixelSnappedClipRect();
const auto* lowest_combined_clip_node = pending_clips.back();
- for (size_t i = pending_clips.size() - 1; i--;) {
+ for (auto i = pending_clips.size() - 1; i--;) {
const auto* sub_clip = pending_clips[i];
if (CombineClip(*sub_clip, pending_combined_clip_rect)) {
// Continue to combine.
@@ -391,7 +395,7 @@ void ConversionContext::SwitchToClip(
// |sub_clip| can't be combined to previous clips. Output the current
// combined clip, and start new combination.
StartClip(pending_combined_clip_rect, *lowest_combined_clip_node);
- pending_combined_clip_rect = sub_clip->ClipRect();
+ pending_combined_clip_rect = sub_clip->PixelSnappedClipRect();
lowest_combined_clip_node = sub_clip;
}
}
@@ -493,7 +497,7 @@ void ConversionContext::SwitchToEffect(
}
// Step 3: Now apply the list of effects in top-down order.
- for (size_t i = pending_effects.size(); i--;) {
+ for (auto i = pending_effects.size(); i--;) {
const EffectPaintPropertyNode* sub_effect = pending_effects[i];
#if DCHECK_IS_ON()
if (!has_pre_cap_effect_hierarchy_issue)
@@ -538,9 +542,8 @@ void ConversionContext::StartEffect(const EffectPaintPropertyNode& effect) {
bool has_other_effects = effect.BlendMode() != SkBlendMode::kSrcOver ||
effect.GetColorFilter() != kColorFilterNone;
DCHECK(!has_filter || !(has_opacity || has_other_effects));
-
- // TODO(crbug.com/904592): Add support for non-composited backdrop-filter
- // here.
+ // We always composite backdrop filters.
+ DCHECK(effect.BackdropFilter().IsEmpty());
// Apply effects.
cc_list_.StartPaint();
@@ -590,25 +593,35 @@ void ConversionContext::StartEffect(const EffectPaintPropertyNode& effect) {
const ClipPaintPropertyNode* input_clip = current_clip_;
PushState(StateEntry::kEffect, saved_count);
effect_bounds_stack_.emplace_back(
- EffectBoundsInfo{save_layer_id, current_transform_, base::nullopt});
+ EffectBoundsInfo{save_layer_id, current_transform_});
current_clip_ = input_clip;
current_effect_ = &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
+ // to layer space) to the visual rect of the filter's SaveLayerOp.
+ cc_list_.StartPaint();
+ cc_list_.EndPaintOfUnpaired(chunk_to_layer_mapper_.MapVisualRect(
+ EnclosingIntRect(reference_box)));
+ }
+ }
}
void ConversionContext::UpdateEffectBounds(
- const base::Optional<FloatRect>& bounds,
+ const FloatRect& bounds,
const TransformPaintPropertyNode& transform) {
- if (effect_bounds_stack_.IsEmpty() || !bounds)
+ if (effect_bounds_stack_.IsEmpty() || bounds.IsEmpty())
return;
auto& effect_bounds_info = effect_bounds_stack_.back();
- FloatRect mapped_bounds = *bounds;
+ FloatRect mapped_bounds = bounds;
GeometryMapper::SourceToDestinationRect(
transform, *effect_bounds_info.transform, mapped_bounds);
- if (effect_bounds_info.bounds)
- effect_bounds_info.bounds->Unite(mapped_bounds);
- else
- effect_bounds_info.bounds = mapped_bounds;
+ effect_bounds_info.bounds.Unite(mapped_bounds);
}
void ConversionContext::EndEffect() {
@@ -622,21 +635,21 @@ void ConversionContext::EndEffect() {
DCHECK(effect_bounds_stack_.size());
const auto& bounds_info = effect_bounds_stack_.back();
- base::Optional<FloatRect> bounds = bounds_info.bounds;
- if (bounds) {
- if (current_effect_->Filter().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;
+ FloatRect bounds = bounds_info.bounds;
+ if (current_effect_->Filter().IsEmpty()) {
+ 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 to propagate the filtered bounds to the parent.
- bounds = current_effect_->MapRect(*bounds);
- }
+ cc_list_.UpdateSaveLayerBounds(bounds_info.save_layer_id,
+ save_layer_bounds);
+ // We need to propagate the filtered bounds to the parent.
+ bounds = current_effect_->MapRect(bounds);
}
effect_bounds_stack_.pop_back();
@@ -732,17 +745,16 @@ void ConversionContext::Convert(const PaintChunkSubset& paint_chunks,
else
continue;
- // If we have an empty paint record, then we would prefer not to draw it.
- // However, if we also have a non-root effect, it means that the filter
- // applied might draw something even if the record is empty. We need to
- // "draw" this record in order to ensure that the effect has correct
- // visual rects.
+ // If we have an empty paint record, then we would prefer ignoring it.
+ // However, if we also have a non-root effect, the empty paint record
+ // might be for a mask with empty content which should make the masked
+ // content fully invisible. We need to "draw" this record to ensure that
+ // the effect has correct visual rect.
if ((!record || record->size() == 0) &&
&chunk_state.Effect() == &EffectPaintPropertyNode::Root()) {
continue;
}
- TranslateForLayerOffsetOnce();
if (!switched_to_chunk_state) {
SwitchToChunkState(chunk);
switched_to_chunk_state = true;
@@ -755,16 +767,17 @@ void ConversionContext::Convert(const PaintChunkSubset& paint_chunks,
chunk_to_layer_mapper_.MapVisualRect(item.VisualRect()));
}
- // Chunk bounds are only important when we are actually drawing. There may
- // also be cases when we only generate a paint record and do not draw,
- // for example, to implement an SVG clip. In such cases, we can safely
- // ignore effect bounds.
- base::Optional<FloatRect> chunk_bounds;
- if (cc_list_.GetUsageHint() ==
- cc::DisplayItemList::kTopLevelDisplayItemList) {
- chunk_bounds = FloatRect(chunk.bounds);
- }
- UpdateEffectBounds(chunk_bounds, chunk_state.Transform());
+ // If we have an empty paint chunk, then we would prefer ignoring it.
+ // However, a reference filter can generate visible effect from invisible
+ // source, and we need to emit paint operations for it.
+ if (!switched_to_chunk_state && &chunk_state.Effect() != current_effect_)
+ SwitchToChunkState(chunk);
+
+ // Most effects apply to drawable contents only. Reference filters are
+ // exceptions, for which we have already added the reference box to the
+ // bounds of the effect in StartEffect().
+ UpdateEffectBounds(FloatRect(chunk.drawable_bounds),
+ chunk_state.Transform());
}
}
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 7953f485235..1291b765dde 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
@@ -7,6 +7,7 @@
#include <initializer_list>
#include "cc/paint/display_item_list.h"
+#include "cc/paint/paint_filter.h"
#include "cc/paint/paint_flags.h"
#include "cc/paint/paint_op_buffer.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -101,7 +102,7 @@ class PaintRecordMatcher
Vector<cc::PaintOpType> expected_ops_;
};
-#define EXPECT_EFFECT_BOUNDS(rect, op_buffer, index) \
+#define EXPECT_EFFECT_BOUNDS(x, y, width, height, op_buffer, index) \
do { \
FloatRect bounds; \
if (const auto* save_layer_alpha = \
@@ -113,7 +114,7 @@ class PaintRecordMatcher
} else { \
FAIL() << "No SaveLayer[Alpha]Op at " << index; \
} \
- EXPECT_EQ(rect, bounds); \
+ EXPECT_EQ(FloatRect(x, y, width, height), bounds); \
} while (false)
#define EXPECT_TRANSFORM_MATRIX(transform, op_buffer, index) \
@@ -160,32 +161,45 @@ struct TestChunks {
DisplayItemList items = DisplayItemList(0);
// Add a paint chunk with a non-empty paint record and given property nodes.
- void AddChunk(const TransformPaintPropertyNode& t,
- const ClipPaintPropertyNode& c,
- const EffectPaintPropertyNode& e,
- const IntRect& bounds = IntRect(0, 0, 100, 100)) {
+ void AddChunk(
+ const TransformPaintPropertyNode& t,
+ const ClipPaintPropertyNode& c,
+ const EffectPaintPropertyNode& e,
+ const IntRect& bounds = IntRect(0, 0, 100, 100),
+ const base::Optional<IntRect>& drawable_bounds = base::nullopt) {
auto record = sk_make_sp<PaintRecord>();
- record->push<cc::DrawRectOp>(bounds, cc::PaintFlags());
- AddChunk(std::move(record), t, c, e, bounds);
+ record->push<cc::DrawRectOp>(drawable_bounds ? *drawable_bounds : bounds,
+ cc::PaintFlags());
+ AddChunk(std::move(record), t, c, e, bounds, drawable_bounds);
}
// Add a paint chunk with a given paint record and property nodes.
- void AddChunk(sk_sp<PaintRecord> record,
- const TransformPaintPropertyNode& t,
- const ClipPaintPropertyNode& c,
- const EffectPaintPropertyNode& e,
- const IntRect& bounds = IntRect(0, 0, 100, 100)) {
- size_t i = items.size();
+ void AddChunk(
+ sk_sp<PaintRecord> record,
+ const TransformPaintPropertyNode& t,
+ const ClipPaintPropertyNode& c,
+ const EffectPaintPropertyNode& e,
+ const IntRect& bounds = IntRect(0, 0, 100, 100),
+ const base::Optional<IntRect>& drawable_bounds = base::nullopt) {
+ auto i = items.size();
items.AllocateAndConstruct<DrawingDisplayItem>(
DefaultId().client, DefaultId().type, std::move(record));
+ if (drawable_bounds)
+ items.Last().SetVisualRectForTesting(*drawable_bounds);
chunks.emplace_back(i, i + 1, DefaultId(), PropertyTreeState(t, c, e));
chunks.back().bounds = bounds;
+ chunks.back().drawable_bounds = drawable_bounds ? *drawable_bounds : bounds;
}
-};
-const cc::DisplayItemList::UsageHint kUsageHints[] = {
- cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer,
- cc::DisplayItemList::kTopLevelDisplayItemList};
+ void AddEmptyChunk(const TransformPaintPropertyNode& t,
+ const ClipPaintPropertyNode& c,
+ const EffectPaintPropertyNode& e,
+ const IntRect& bounds = IntRect(0, 0, 100, 100)) {
+ auto i = items.size();
+ chunks.emplace_back(i, i, DefaultId(), PropertyTreeState(t, c, e));
+ chunks.back().bounds = bounds;
+ }
+};
TEST_P(PaintChunksToCcLayerTest, EffectGroupingSimple) {
// This test verifies effects are applied as a group.
@@ -194,23 +208,18 @@ TEST_P(PaintChunksToCcLayerTest, EffectGroupingSimple) {
chunks.AddChunk(t0(), c0(), *e1, IntRect(0, 0, 50, 50));
chunks.AddChunk(t0(), c0(), *e1, IntRect(20, 20, 70, 70));
- const FloatRect kExpectedBounds[] = {FloatRect(cc::PaintOp::kUnsetRect),
- FloatRect(0, 0, 90, 90)};
-
- for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
- sk_sp<PaintRecord> output =
- PaintChunksToCcLayer::Convert(chunks.chunks, PropertyTreeState::Root(),
- gfx::Vector2dF(), chunks.items,
- kUsageHints[hint])
- ->ReleaseAsRecord();
- EXPECT_THAT(
- *output,
- PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e1>
- cc::PaintOpType::DrawRecord, // <p0/>
- cc::PaintOpType::DrawRecord, // <p1/>
- cc::PaintOpType::Restore})); // </e1>
- EXPECT_EFFECT_BOUNDS(kExpectedBounds[hint], *output, 0);
- }
+ sk_sp<PaintRecord> output =
+ PaintChunksToCcLayer::Convert(
+ chunks.chunks, PropertyTreeState::Root(), gfx::Vector2dF(),
+ chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
+ ->ReleaseAsRecord();
+ EXPECT_THAT(
+ *output,
+ PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e1>
+ cc::PaintOpType::DrawRecord, // <p0/>
+ cc::PaintOpType::DrawRecord, // <p1/>
+ cc::PaintOpType::Restore})); // </e1>
+ EXPECT_EFFECT_BOUNDS(0, 0, 90, 90, *output, 0);
}
TEST_P(PaintChunksToCcLayerTest, EffectGroupingNested) {
@@ -222,39 +231,30 @@ TEST_P(PaintChunksToCcLayerTest, EffectGroupingNested) {
chunks.AddChunk(t0(), c0(), *e2);
chunks.AddChunk(t0(), c0(), *e3, IntRect(111, 222, 333, 444));
- const FloatRect kExpectedBounds1[] = {FloatRect(cc::PaintOp::kUnsetRect),
- FloatRect(0, 0, 444, 666)};
- const FloatRect kExpectedBounds2[] = {FloatRect(cc::PaintOp::kUnsetRect),
- FloatRect(0, 0, 100, 100)};
- const FloatRect kExpectedBounds3[] = {FloatRect(cc::PaintOp::kUnsetRect),
- FloatRect(111, 222, 333, 444)};
-
- for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
- sk_sp<PaintRecord> output =
- PaintChunksToCcLayer::Convert(chunks.chunks, PropertyTreeState::Root(),
- gfx::Vector2dF(), chunks.items,
- kUsageHints[hint])
- ->ReleaseAsRecord();
- EXPECT_THAT(
- *output,
- PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e1>
- cc::PaintOpType::SaveLayerAlpha, // <e2>
- cc::PaintOpType::DrawRecord, // <p0/>
- cc::PaintOpType::Restore, // </e2>
- cc::PaintOpType::SaveLayerAlpha, // <e3>
- cc::PaintOpType::DrawRecord, // <p1/>
- cc::PaintOpType::Restore, // </e3>
- cc::PaintOpType::Restore})); // </e1>
- EXPECT_EFFECT_BOUNDS(kExpectedBounds1[hint], *output, 0);
- EXPECT_EFFECT_BOUNDS(kExpectedBounds2[hint], *output, 1);
- EXPECT_EFFECT_BOUNDS(kExpectedBounds3[hint], *output, 4);
- }
+ sk_sp<PaintRecord> output =
+ PaintChunksToCcLayer::Convert(
+ chunks.chunks, PropertyTreeState::Root(), gfx::Vector2dF(),
+ chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
+ ->ReleaseAsRecord();
+ EXPECT_THAT(
+ *output,
+ PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e1>
+ cc::PaintOpType::SaveLayerAlpha, // <e2>
+ cc::PaintOpType::DrawRecord, // <p0/>
+ cc::PaintOpType::Restore, // </e2>
+ cc::PaintOpType::SaveLayerAlpha, // <e3>
+ cc::PaintOpType::DrawRecord, // <p1/>
+ cc::PaintOpType::Restore, // </e3>
+ cc::PaintOpType::Restore})); // </e1>
+ EXPECT_EFFECT_BOUNDS(0, 0, 444, 666, *output, 0);
+ EXPECT_EFFECT_BOUNDS(0, 0, 100, 100, *output, 1);
+ EXPECT_EFFECT_BOUNDS(111, 222, 333, 444, *output, 4);
}
TEST_P(PaintChunksToCcLayerTest, EffectFilterGroupingNestedWithTransforms) {
// This test verifies nested effects with transforms are grouped properly.
auto t1 = CreateTransform(t0(), TransformationMatrix().Scale(2.f));
- auto t2 = CreateTransform(*t1, TransformationMatrix().Translate(-50, -50));
+ auto t2 = Create2DTranslation(*t1, -50, -50);
auto e1 = CreateOpacityEffect(e0(), *t2, &c0(), 0.5);
CompositorFilterOperations filter;
@@ -264,47 +264,40 @@ TEST_P(PaintChunksToCcLayerTest, EffectFilterGroupingNestedWithTransforms) {
chunks.AddChunk(*t2, c0(), *e1, IntRect(0, 0, 50, 50));
chunks.AddChunk(*t1, c0(), *e2, IntRect(20, 20, 70, 70));
- const FloatRect kExpectedBounds1[] = {FloatRect(cc::PaintOp::kUnsetRect),
- FloatRect(0, 0, 155, 155)};
- const FloatRect kExpectedBounds2[] = {FloatRect(cc::PaintOp::kUnsetRect),
- FloatRect(10, 10, 70, 70)};
-
- for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
- sk_sp<PaintRecord> output =
- PaintChunksToCcLayer::Convert(chunks.chunks, PropertyTreeState::Root(),
- gfx::Vector2dF(), chunks.items,
- kUsageHints[hint])
- ->ReleaseAsRecord();
- EXPECT_THAT(
- *output,
- PaintRecordMatcher::Make(
- {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(kExpectedBounds1[hint], *output, 2);
- // e2_offset
- EXPECT_TRANSLATE(60, 60, *output, 5);
- // t2^-1(chunk2.bounds) - e2_offset
- EXPECT_EFFECT_BOUNDS(kExpectedBounds2[hint], *output, 6);
- // -e2_offset
- EXPECT_TRANSLATE(-e2->FiltersOrigin().X(), -e2->FiltersOrigin().Y(),
- *output, 7);
- // t2^1
- EXPECT_TRANSLATE(-t2->Translation2D().Width(),
- -t2->Translation2D().Height(), *output, 9);
- }
+ sk_sp<PaintRecord> output =
+ PaintChunksToCcLayer::Convert(
+ chunks.chunks, PropertyTreeState::Root(), gfx::Vector2dF(),
+ chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
+ ->ReleaseAsRecord();
+ EXPECT_THAT(
+ *output,
+ PaintRecordMatcher::Make(
+ {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
+ EXPECT_TRANSLATE(-t2->Translation2D().Width(), -t2->Translation2D().Height(),
+ *output, 9);
}
TEST_P(PaintChunksToCcLayerTest, InterleavedClipEffect) {
@@ -326,45 +319,38 @@ TEST_P(PaintChunksToCcLayerTest, InterleavedClipEffect) {
chunks.AddChunk(t0(), *c3, *e1, IntRect(20, 20, 70, 70));
chunks.AddChunk(t0(), *c4, e0());
- const FloatRect kExpectedBounds1[] = {FloatRect(cc::PaintOp::kUnsetRect),
- FloatRect(0, 0, 90, 90)};
- const FloatRect kExpectedBounds2[] = {FloatRect(cc::PaintOp::kUnsetRect),
- FloatRect(0, 0, 50, 50)};
-
- for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
- sk_sp<PaintRecord> output =
- PaintChunksToCcLayer::Convert(chunks.chunks, PropertyTreeState::Root(),
- gfx::Vector2dF(), chunks.items,
- kUsageHints[hint])
- ->ReleaseAsRecord();
- EXPECT_THAT(*output, PaintRecordMatcher::Make(
- {cc::PaintOpType::Save,
- cc::PaintOpType::ClipRect, // <c1+c2>
- cc::PaintOpType::DrawRecord, // <p0/>
- cc::PaintOpType::Save,
- cc::PaintOpType::ClipRect, // <c3>
- cc::PaintOpType::DrawRecord, // <p1/>
- cc::PaintOpType::Restore, // </c3>
- cc::PaintOpType::SaveLayerAlpha, // <e1>
- cc::PaintOpType::Save,
- cc::PaintOpType::ClipRect, // <c3+c4>
- cc::PaintOpType::SaveLayerAlpha, // <e2>
- cc::PaintOpType::DrawRecord, // <p2/>
- cc::PaintOpType::Restore, // </e2>
- cc::PaintOpType::Restore, // </c3+c4>
- cc::PaintOpType::Save,
- cc::PaintOpType::ClipRect, // <c3>
- cc::PaintOpType::DrawRecord, // <p3/>
- cc::PaintOpType::Restore, // </c3>
- cc::PaintOpType::Restore, // </e1>
- cc::PaintOpType::Save,
- cc::PaintOpType::ClipRect, // <c3+c4>
- cc::PaintOpType::DrawRecord, // <p4/>
- cc::PaintOpType::Restore, // </c3+c4>
- cc::PaintOpType::Restore})); // </c1+c2>
- EXPECT_EFFECT_BOUNDS(kExpectedBounds1[hint], *output, 7);
- EXPECT_EFFECT_BOUNDS(kExpectedBounds2[hint], *output, 10);
- }
+ sk_sp<PaintRecord> output =
+ PaintChunksToCcLayer::Convert(
+ chunks.chunks, PropertyTreeState::Root(), gfx::Vector2dF(),
+ chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
+ ->ReleaseAsRecord();
+ EXPECT_THAT(*output, PaintRecordMatcher::Make(
+ {cc::PaintOpType::Save,
+ cc::PaintOpType::ClipRect, // <c1+c2>
+ cc::PaintOpType::DrawRecord, // <p0/>
+ cc::PaintOpType::Save,
+ cc::PaintOpType::ClipRect, // <c3>
+ cc::PaintOpType::DrawRecord, // <p1/>
+ cc::PaintOpType::Restore, // </c3>
+ cc::PaintOpType::SaveLayerAlpha, // <e1>
+ cc::PaintOpType::Save,
+ cc::PaintOpType::ClipRect, // <c3+c4>
+ cc::PaintOpType::SaveLayerAlpha, // <e2>
+ cc::PaintOpType::DrawRecord, // <p2/>
+ cc::PaintOpType::Restore, // </e2>
+ cc::PaintOpType::Restore, // </c3+c4>
+ cc::PaintOpType::Save,
+ cc::PaintOpType::ClipRect, // <c3>
+ cc::PaintOpType::DrawRecord, // <p3/>
+ cc::PaintOpType::Restore, // </c3>
+ cc::PaintOpType::Restore, // </e1>
+ cc::PaintOpType::Save,
+ cc::PaintOpType::ClipRect, // <c3+c4>
+ cc::PaintOpType::DrawRecord, // <p4/>
+ cc::PaintOpType::Restore, // </c3+c4>
+ cc::PaintOpType::Restore})); // </c1+c2>
+ EXPECT_EFFECT_BOUNDS(0, 0, 90, 90, *output, 7);
+ EXPECT_EFFECT_BOUNDS(0, 0, 50, 50, *output, 10);
}
TEST_P(PaintChunksToCcLayerTest, ClipSpaceInversion) {
@@ -407,29 +393,24 @@ TEST_P(PaintChunksToCcLayerTest, OpacityEffectSpaceInversion) {
chunks.AddChunk(t0(), c0(), *e1);
chunks.AddChunk(*t1, c0(), *e1);
- const FloatRect kExpectedBounds[] = {FloatRect(cc::PaintOp::kUnsetRect),
- FloatRect(0, 0, 100, 100)};
-
- for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
- sk_sp<PaintRecord> output =
- PaintChunksToCcLayer::Convert(chunks.chunks, PropertyTreeState::Root(),
- gfx::Vector2dF(), chunks.items,
- kUsageHints[hint])
- ->ReleaseAsRecord();
- EXPECT_THAT(*output,
- PaintRecordMatcher::Make(
- {cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1>
- cc::PaintOpType::SaveLayerAlpha, // <e1>
- cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1^-1>
- cc::PaintOpType::DrawRecord, // <p0/>
- cc::PaintOpType::Restore, // </t1^-1>
- cc::PaintOpType::DrawRecord, // <p1/>
- cc::PaintOpType::Restore, // </e1>
- cc::PaintOpType::Restore})); // </t1>
- EXPECT_EFFECT_BOUNDS(kExpectedBounds[hint], *output, 2);
- EXPECT_TRANSFORM_MATRIX(t1->Matrix(), *output, 1);
- EXPECT_TRANSFORM_MATRIX(t1->Matrix().Inverse(), *output, 4);
- }
+ sk_sp<PaintRecord> output =
+ PaintChunksToCcLayer::Convert(
+ chunks.chunks, PropertyTreeState::Root(), gfx::Vector2dF(),
+ chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
+ ->ReleaseAsRecord();
+ EXPECT_THAT(*output,
+ PaintRecordMatcher::Make(
+ {cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1>
+ cc::PaintOpType::SaveLayerAlpha, // <e1>
+ cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1^-1>
+ cc::PaintOpType::DrawRecord, // <p0/>
+ cc::PaintOpType::Restore, // </t1^-1>
+ cc::PaintOpType::DrawRecord, // <p1/>
+ cc::PaintOpType::Restore, // </e1>
+ cc::PaintOpType::Restore})); // </t1>
+ EXPECT_EFFECT_BOUNDS(0, 0, 100, 100, *output, 2);
+ EXPECT_TRANSFORM_MATRIX(t1->Matrix(), *output, 1);
+ EXPECT_TRANSFORM_MATRIX(t1->Matrix().Inverse(), *output, 4);
}
TEST_P(PaintChunksToCcLayerTest, FilterEffectSpaceInversion) {
@@ -447,33 +428,29 @@ TEST_P(PaintChunksToCcLayerTest, FilterEffectSpaceInversion) {
TestChunks chunks;
chunks.AddChunk(t0(), c0(), *e1);
- const FloatRect kExpectedBounds[] = {FloatRect(cc::PaintOp::kUnsetRect),
- FloatRect(-66, -88, 50, 50)};
-
- for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
- auto output = PaintChunksToCcLayer::Convert(
- chunks.chunks, PropertyTreeState::Root(),
- gfx::Vector2dF(), chunks.items, kUsageHints[hint])
- ->ReleaseAsRecord();
- EXPECT_THAT(
- *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(kExpectedBounds[hint], *output, 4);
- EXPECT_TRANSLATE(-66, -88, *output, 5);
- EXPECT_TRANSFORM_MATRIX(t1->Matrix().Inverse(), *output, 7);
- }
+ auto output =
+ PaintChunksToCcLayer::Convert(
+ chunks.chunks, PropertyTreeState::Root(), gfx::Vector2dF(),
+ chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
+ ->ReleaseAsRecord();
+ EXPECT_THAT(
+ *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);
}
TEST_P(PaintChunksToCcLayerTest, NonRootLayerSimple) {
@@ -523,25 +500,20 @@ TEST_P(PaintChunksToCcLayerTest, EffectWithNoOutputClip) {
TestChunks chunks;
chunks.AddChunk(t0(), *c2, *e1);
- const FloatRect kExpectedBounds[] = {FloatRect(cc::PaintOp::kUnsetRect),
- FloatRect(0, 0, 100, 100)};
-
- for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
- sk_sp<PaintRecord> output =
- PaintChunksToCcLayer::Convert(
- chunks.chunks, PropertyTreeState(t0(), *c1, e0()), gfx::Vector2dF(),
- chunks.items, kUsageHints[hint])
- ->ReleaseAsRecord();
- EXPECT_THAT(
- *output,
- PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e1>
- cc::PaintOpType::Save,
- cc::PaintOpType::ClipRect, // <c2>
- cc::PaintOpType::DrawRecord, // <p0/>
- cc::PaintOpType::Restore, // </c2>
- cc::PaintOpType::Restore})); // </e1>
- EXPECT_EFFECT_BOUNDS(kExpectedBounds[hint], *output, 0);
- }
+ sk_sp<PaintRecord> output =
+ PaintChunksToCcLayer::Convert(
+ chunks.chunks, PropertyTreeState(t0(), *c1, e0()), gfx::Vector2dF(),
+ chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
+ ->ReleaseAsRecord();
+ EXPECT_THAT(
+ *output,
+ PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e1>
+ cc::PaintOpType::Save,
+ cc::PaintOpType::ClipRect, // <c2>
+ cc::PaintOpType::DrawRecord, // <p0/>
+ cc::PaintOpType::Restore, // </c2>
+ cc::PaintOpType::Restore})); // </e1>
+ EXPECT_EFFECT_BOUNDS(0, 0, 100, 100, *output, 0);
}
TEST_P(PaintChunksToCcLayerTest,
@@ -553,30 +525,23 @@ TEST_P(PaintChunksToCcLayerTest,
TestChunks chunks;
chunks.AddChunk(t0(), *c1, *e2);
- const FloatRect kExpectedBounds1[] = {FloatRect(cc::PaintOp::kUnsetRect),
- FloatRect(0, 0, 100, 100)};
- const FloatRect kExpectedBounds2[] = {FloatRect(cc::PaintOp::kUnsetRect),
- FloatRect(0, 0, 100, 100)};
-
- for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
- sk_sp<PaintRecord> output =
- PaintChunksToCcLayer::Convert(chunks.chunks, PropertyTreeState::Root(),
- gfx::Vector2dF(), chunks.items,
- kUsageHints[hint])
- ->ReleaseAsRecord();
- EXPECT_THAT(
- *output,
- PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e1>
- cc::PaintOpType::SaveLayerAlpha, // <e2>
- cc::PaintOpType::Save,
- cc::PaintOpType::ClipRect, // <c1>
- cc::PaintOpType::DrawRecord, // <p0/>
- cc::PaintOpType::Restore, // </c1>
- cc::PaintOpType::Restore, // </e2>
- cc::PaintOpType::Restore})); // </e1>
- EXPECT_EFFECT_BOUNDS(kExpectedBounds1[hint], *output, 0);
- EXPECT_EFFECT_BOUNDS(kExpectedBounds2[hint], *output, 1);
- }
+ sk_sp<PaintRecord> output =
+ PaintChunksToCcLayer::Convert(
+ chunks.chunks, PropertyTreeState::Root(), gfx::Vector2dF(),
+ chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
+ ->ReleaseAsRecord();
+ EXPECT_THAT(
+ *output,
+ PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e1>
+ cc::PaintOpType::SaveLayerAlpha, // <e2>
+ cc::PaintOpType::Save,
+ cc::PaintOpType::ClipRect, // <c1>
+ cc::PaintOpType::DrawRecord, // <p0/>
+ cc::PaintOpType::Restore, // </c1>
+ cc::PaintOpType::Restore, // </e2>
+ cc::PaintOpType::Restore})); // </e1>
+ EXPECT_EFFECT_BOUNDS(0, 0, 100, 100, *output, 0);
+ EXPECT_EFFECT_BOUNDS(0, 0, 100, 100, *output, 1);
}
TEST_P(PaintChunksToCcLayerTest,
@@ -588,25 +553,20 @@ TEST_P(PaintChunksToCcLayerTest,
TestChunks chunks;
chunks.AddChunk(t0(), *c1, *e2);
- const FloatRect kExpectedBounds[] = {FloatRect(cc::PaintOp::kUnsetRect),
- FloatRect(0, 0, 100, 100)};
-
- for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
- sk_sp<PaintRecord> output =
- PaintChunksToCcLayer::Convert(
- chunks.chunks, PropertyTreeState(t0(), c0(), *e1), gfx::Vector2dF(),
- chunks.items, kUsageHints[hint])
- ->ReleaseAsRecord();
- EXPECT_THAT(
- *output,
- PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e2>
- cc::PaintOpType::Save,
- cc::PaintOpType::ClipRect, // <c1>
- cc::PaintOpType::DrawRecord, // <p0/>
- cc::PaintOpType::Restore, // </c1>
- cc::PaintOpType::Restore})); // </e2>
- EXPECT_EFFECT_BOUNDS(kExpectedBounds[hint], *output, 0);
- }
+ sk_sp<PaintRecord> output =
+ PaintChunksToCcLayer::Convert(
+ chunks.chunks, PropertyTreeState(t0(), c0(), *e1), gfx::Vector2dF(),
+ chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
+ ->ReleaseAsRecord();
+ EXPECT_THAT(
+ *output,
+ PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e2>
+ cc::PaintOpType::Save,
+ cc::PaintOpType::ClipRect, // <c1>
+ cc::PaintOpType::DrawRecord, // <p0/>
+ cc::PaintOpType::Restore, // </c1>
+ cc::PaintOpType::Restore})); // </e2>
+ EXPECT_EFFECT_BOUNDS(0, 0, 100, 100, *output, 0);
}
TEST_P(PaintChunksToCcLayerTest,
@@ -618,29 +578,23 @@ TEST_P(PaintChunksToCcLayerTest,
TestChunks chunks;
chunks.AddChunk(t0(), *c1, *e2);
- const FloatRect kExpectedBounds[] = {FloatRect(cc::PaintOp::kUnsetRect),
- FloatRect(0, 0, 100, 100)};
-
- for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
- sk_sp<PaintRecord> output =
- PaintChunksToCcLayer::Convert(
- chunks.chunks, PropertyTreeState(t0(), *c1, *e1), gfx::Vector2dF(),
- chunks.items, kUsageHints[hint])
- ->ReleaseAsRecord();
- EXPECT_THAT(
- *output,
- PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e2>
- cc::PaintOpType::DrawRecord, // <p0/>
- cc::PaintOpType::Restore})); // </e2>
- EXPECT_EFFECT_BOUNDS(kExpectedBounds[hint], *output, 0);
- }
+ sk_sp<PaintRecord> output =
+ PaintChunksToCcLayer::Convert(
+ chunks.chunks, PropertyTreeState(t0(), *c1, *e1), gfx::Vector2dF(),
+ chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
+ ->ReleaseAsRecord();
+ EXPECT_THAT(
+ *output,
+ PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e2>
+ cc::PaintOpType::DrawRecord, // <p0/>
+ cc::PaintOpType::Restore})); // </e2>
+ EXPECT_EFFECT_BOUNDS(0, 0, 100, 100, *output, 0);
}
TEST_P(PaintChunksToCcLayerTest, VisualRect) {
auto layer_transform =
CreateTransform(t0(), TransformationMatrix().Scale(20));
- auto chunk_transform = CreateTransform(
- *layer_transform, TransformationMatrix().Translate(50, 100));
+ auto chunk_transform = Create2DTranslation(*layer_transform, 50, 100);
TestChunks chunks;
chunks.AddChunk(*chunk_transform, c0(), e0());
@@ -751,22 +705,17 @@ TEST_P(PaintChunksToCcLayerTest, EmptyEffectsAreStored) {
chunks.AddChunk(nullptr, t0(), c0(), e0());
chunks.AddChunk(nullptr, t0(), c0(), *e1);
- const FloatRect kExpectedBounds[] = {FloatRect(cc::PaintOp::kUnsetRect),
- FloatRect(0, 0, 100, 100)};
-
- for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
- sk_sp<PaintRecord> output =
- PaintChunksToCcLayer::Convert(chunks.chunks, PropertyTreeState::Root(),
- gfx::Vector2dF(), chunks.items,
- kUsageHints[hint])
- ->ReleaseAsRecord();
-
- EXPECT_THAT(*output, PaintRecordMatcher::Make({
- cc::PaintOpType::SaveLayerAlpha, // <e1>
- cc::PaintOpType::Restore, // </e1>
- }));
- EXPECT_EFFECT_BOUNDS(kExpectedBounds[hint], *output, 0);
- }
+ sk_sp<PaintRecord> output =
+ PaintChunksToCcLayer::Convert(
+ chunks.chunks, PropertyTreeState::Root(), gfx::Vector2dF(),
+ chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
+ ->ReleaseAsRecord();
+
+ EXPECT_THAT(*output, PaintRecordMatcher::Make({
+ cc::PaintOpType::SaveLayerAlpha, // <e1>
+ cc::PaintOpType::Restore, // </e1>
+ }));
+ EXPECT_EFFECT_BOUNDS(0, 0, 100, 100, *output, 0);
}
TEST_P(PaintChunksToCcLayerTest, CombineClips) {
@@ -808,7 +757,7 @@ TEST_P(PaintChunksToCcLayerTest, CombineClips) {
TEST_P(PaintChunksToCcLayerTest, CombineClipsAcrossTransform) {
FloatRoundedRect clip_rect(0, 0, 100, 100);
- auto identity = CreateTransform(t0(), TransformationMatrix());
+ auto identity = Create2DTranslation(t0(), 0, 0);
auto non_identity =
CreateTransform(*identity, TransformationMatrix().Scale(2));
auto non_invertible =
@@ -935,9 +884,9 @@ TEST_P(PaintChunksToCcLayerTest, ChunksSamePropertyTreeState) {
}
TEST_P(PaintChunksToCcLayerTest, NoOpForIdentityTransforms) {
- auto t1 = CreateTransform(t0(), TransformationMatrix());
- auto t2 = CreateTransform(*t1, TransformationMatrix());
- auto t3 = CreateTransform(*t2, TransformationMatrix());
+ auto t1 = Create2DTranslation(t0(), 0, 0);
+ auto t2 = Create2DTranslation(*t1, 0, 0);
+ auto t3 = Create2DTranslation(*t2, 0, 0);
auto c1 = CreateClip(c0(), *t2, FloatRoundedRect(0, 0, 100, 100));
auto c2 = CreateClip(*c1, *t3, FloatRoundedRect(0, 0, 200, 50));
@@ -1381,27 +1330,105 @@ TEST_P(PaintChunksToCcLayerTest, AllowChunkEscapeLayerNoopEffects) {
}));
}
-// https://crbug.com/918240
-TEST_P(PaintChunksToCcLayerTest, EmptyChunkRectDoesntTurnToUnsetOne) {
+TEST_P(PaintChunksToCcLayerTest, EmptyChunkRect) {
CompositorFilterOperations filter;
filter.AppendBlurFilter(5);
auto e1 = CreateFilterEffect(e0(), t0(), &c0(), filter, FloatPoint(0, 0));
TestChunks chunks;
chunks.AddChunk(nullptr, t0(), c0(), *e1, {0, 0, 0, 0});
- const FloatRect kExpectedBounds[] = {FloatRect(cc::PaintOp::kUnsetRect),
- FloatRect(0, 0, 0, 0)};
-
- for (size_t hint = 0; hint < base::size(kUsageHints); ++hint) {
- auto output = PaintChunksToCcLayer::Convert(
- chunks.chunks, PropertyTreeState::Root(),
- gfx::Vector2dF(), chunks.items, kUsageHints[hint])
- ->ReleaseAsRecord();
- EXPECT_THAT(*output,
- PaintRecordMatcher::Make({cc::PaintOpType::SaveLayer, // <e1>
- cc::PaintOpType::Restore})); // </e1>
- EXPECT_EFFECT_BOUNDS(kExpectedBounds[hint], *output, 0);
+ auto output =
+ PaintChunksToCcLayer::Convert(
+ chunks.chunks, PropertyTreeState::Root(), gfx::Vector2dF(),
+ chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)
+ ->ReleaseAsRecord();
+ EXPECT_THAT(*output,
+ PaintRecordMatcher::Make({cc::PaintOpType::SaveLayer, // <e1>
+ cc::PaintOpType::Restore})); // </e1>
+ EXPECT_EFFECT_BOUNDS(0, 0, 0, 0, *output, 0);
+}
+
+TEST_P(PaintChunksToCcLayerTest, ReferenceFilterOnEmptyChunk) {
+ CompositorFilterOperations filter;
+ filter.AppendReferenceFilter(sk_make_sp<cc::RecordPaintFilter>(
+ 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));
+ TestChunks chunks;
+ chunks.AddEmptyChunk(t0(), c0(), *e1, IntRect(0, 0, 200, 300));
+
+ auto cc_list = base::MakeRefCounted<cc::DisplayItemList>(
+ cc::DisplayItemList::kTopLevelDisplayItemList);
+ 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);
+ 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);
+}
+
+TEST_P(PaintChunksToCcLayerTest, ReferenceFilterOnChunkWithDrawingDisplayItem) {
+ CompositorFilterOperations filter;
+ filter.AppendReferenceFilter(sk_make_sp<cc::RecordPaintFilter>(
+ 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));
+ TestChunks chunks;
+ chunks.AddChunk(t0(), c0(), *e1, IntRect(5, 10, 200, 300),
+ IntRect(10, 15, 20, 30));
+
+ auto cc_list = base::MakeRefCounted<cc::DisplayItemList>(
+ cc::DisplayItemList::kTopLevelDisplayItemList);
+ PaintChunksToCcLayer::ConvertInto(chunks.chunks, PropertyTreeState::Root(),
+ gfx::Vector2dF(5, 10), FloatSize(),
+ chunks.items, *cc_list);
+ ASSERT_EQ(11u, 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);
+ // 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,
+ 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, //
+ 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}));
+ // 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);
}
} // 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 757e737fa3b..07ded512b38 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
@@ -34,12 +34,6 @@ static constexpr int kSecondaryRootNodeId = 1;
} // namespace
-inline const TransformPaintPropertyNode&
-PropertyTreeManager::EffectState::Transform() const {
- return effect_type == CcEffectType::kEffect ? effect->LocalTransformSpace()
- : clip->LocalTransformSpace();
-}
-
PropertyTreeManager::PropertyTreeManager(
PropertyTreeManagerClient& client,
cc::PropertyTrees& property_trees,
@@ -113,9 +107,9 @@ static void SetTransformTreePageScaleFactor(
}
bool PropertyTreeManager::DirectlyUpdateCompositedOpacityValue(
- cc::PropertyTrees* property_trees,
cc::LayerTreeHost& host,
const EffectPaintPropertyNode& effect) {
+ auto* property_trees = host.property_trees();
auto* cc_effect = property_trees->effect_tree.Node(
effect.CcNodeId(property_trees->sequence_number));
if (!cc_effect)
@@ -134,7 +128,6 @@ bool PropertyTreeManager::DirectlyUpdateCompositedOpacityValue(
}
bool PropertyTreeManager::DirectlyUpdateScrollOffsetTransform(
- cc::PropertyTrees* property_trees,
cc::LayerTreeHost& host,
const TransformPaintPropertyNode& transform) {
auto* scroll_node = transform.ScrollNode();
@@ -142,6 +135,7 @@ bool PropertyTreeManager::DirectlyUpdateScrollOffsetTransform(
if (!scroll_node)
return false;
+ auto* property_trees = host.property_trees();
auto* cc_scroll_node = property_trees->scroll_tree.Node(
scroll_node->CcNodeId(property_trees->sequence_number));
if (!cc_scroll_node)
@@ -155,24 +149,22 @@ bool PropertyTreeManager::DirectlyUpdateScrollOffsetTransform(
DCHECK(!cc_transform->is_currently_animating);
UpdateCcTransformLocalMatrix(*cc_transform, transform);
- property_trees->scroll_tree.SetScrollOffset(
- scroll_node->GetCompositorElementId(), cc_transform->scroll_offset);
-
+ DirectlySetScrollOffset(host, scroll_node->GetCompositorElementId(),
+ cc_transform->scroll_offset);
cc_transform->transform_changed = true;
property_trees->transform_tree.set_needs_update(true);
- property_trees->scroll_tree.set_needs_update(true);
host.SetNeedsCommit();
return true;
}
bool PropertyTreeManager::DirectlyUpdateTransform(
- cc::PropertyTrees* property_trees,
cc::LayerTreeHost& host,
const TransformPaintPropertyNode& transform) {
// If we have a ScrollNode, we should be using
// DirectlyUpdateScrollOffsetTransform().
DCHECK(!transform.ScrollNode());
+ auto* property_trees = host.property_trees();
auto* cc_transform = property_trees->transform_tree.Node(
transform.CcNodeId(property_trees->sequence_number));
if (!cc_transform)
@@ -192,11 +184,11 @@ bool PropertyTreeManager::DirectlyUpdateTransform(
}
bool PropertyTreeManager::DirectlyUpdatePageScaleTransform(
- cc::PropertyTrees* property_trees,
cc::LayerTreeHost& host,
const TransformPaintPropertyNode& transform) {
DCHECK(!transform.ScrollNode());
+ auto* property_trees = host.property_trees();
auto* cc_transform = property_trees->transform_tree.Node(
transform.CcNodeId(property_trees->sequence_number));
if (!cc_transform)
@@ -211,6 +203,19 @@ bool PropertyTreeManager::DirectlyUpdatePageScaleTransform(
return true;
}
+// static
+void PropertyTreeManager::DirectlySetScrollOffset(
+ cc::LayerTreeHost& host,
+ CompositorElementId element_id,
+ const gfx::ScrollOffset& scroll_offset) {
+ auto* property_trees = host.property_trees();
+ if (property_trees->scroll_tree.SetScrollOffset(element_id, scroll_offset)) {
+ if (auto* layer = host.LayerByElementId(element_id))
+ layer->SetNeedsPushProperties();
+ host.SetNeedsCommit();
+ }
+}
+
cc::TransformTree& PropertyTreeManager::GetTransformTree() {
return property_trees_.transform_tree;
}
@@ -298,9 +303,9 @@ void PropertyTreeManager::SetupRootEffectNode() {
EffectPaintPropertyNode::Root().SetCcNodeId(new_sequence_number_,
effect_node.id);
- SetCurrentEffectState(effect_node, CcEffectType::kEffect,
- EffectPaintPropertyNode::Root(),
- ClipPaintPropertyNode::Root());
+ SetCurrentEffectState(
+ effect_node, CcEffectType::kEffect, EffectPaintPropertyNode::Root(),
+ ClipPaintPropertyNode::Root(), TransformPaintPropertyNode::Root());
}
void PropertyTreeManager::SetupRootScrollNode() {
@@ -351,15 +356,17 @@ void PropertyTreeManager::SetCurrentEffectState(
const cc::EffectNode& cc_effect_node,
CcEffectType effect_type,
const EffectPaintPropertyNode& effect,
- const ClipPaintPropertyNode& clip) {
+ const ClipPaintPropertyNode& clip,
+ const TransformPaintPropertyNode& transform) {
const auto* previous_transform =
- effect.IsRoot() ? nullptr : &current_.Transform();
+ effect.IsRoot() ? nullptr : current_.transform;
current_.effect_id = cc_effect_node.id;
current_.effect_type = effect_type;
DCHECK(!effect.IsParentAlias() || !effect.Parent());
current_.effect = &effect;
DCHECK(!clip.IsParentAlias() || !clip.Parent());
current_.clip = &clip;
+ current_.transform = &transform;
if (cc_effect_node.HasRenderSurface()) {
current_.may_be_2d_axis_misaligned_to_render_surface =
@@ -368,7 +375,7 @@ void PropertyTreeManager::SetCurrentEffectState(
} else {
if (current_.may_be_2d_axis_misaligned_to_render_surface ==
EffectState::kAligned &&
- previous_transform != &current_.Transform()) {
+ previous_transform != current_.transform) {
current_.may_be_2d_axis_misaligned_to_render_surface =
EffectState::kUnknown;
}
@@ -422,7 +429,9 @@ int PropertyTreeManager::EnsureCompositorTransformNode(
// cache a lookup of transform node to scroll translation transform node.
const auto& scroll_ancestor = transform_node.NearestScrollTranslationNode();
sticky_data.scroll_ancestor = EnsureCompositorScrollNode(scroll_ancestor);
- if (scroll_ancestor.ScrollNode()->ScrollsOuterViewport())
+ const auto& scroll_ancestor_compositor_node =
+ *GetScrollTree().Node(sticky_data.scroll_ancestor);
+ if (scroll_ancestor_compositor_node.scrolls_outer_viewport)
GetTransformTree().AddNodeAffectedByOuterViewportBoundsDelta(id);
if (auto shifting_sticky_box_element_id =
sticky_data.constraints.nearest_element_shifting_sticky_box) {
@@ -466,8 +475,8 @@ int PropertyTreeManager::EnsureCompositorTransformNode(
transform_node.FlattensInheritedTransform() && transform_node.Parent() &&
transform_node.Parent()->RenderingContextId() &&
!transform_node.Parent()->FlattensInheritedTransform()) {
- SetCurrentEffectRenderSurfaceReason(
- cc::RenderSurfaceReason::k3dTransformFlattening);
+ current_cc_effect->render_surface_reason =
+ cc::RenderSurfaceReason::k3dTransformFlattening;
}
transform_node.SetCcNodeId(new_sequence_number_, id);
@@ -502,7 +511,7 @@ int PropertyTreeManager::EnsureCompositorClipNode(
cc::ClipNode& compositor_node = *GetClipTree().Node(id);
- compositor_node.clip = clip_node.ClipRect().Rect();
+ compositor_node.clip = clip_node.PixelSnappedClipRect().Rect();
compositor_node.transform_id =
EnsureCompositorTransformNode(clip_node.LocalTransformSpace());
compositor_node.clip_type = cc::ClipNode::ClipType::APPLIES_LOCAL_CLIP;
@@ -534,15 +543,9 @@ void PropertyTreeManager::CreateCompositorScrollNode(
scroll_node.UserScrollableHorizontal();
compositor_node.user_scrollable_vertical =
scroll_node.UserScrollableVertical();
- compositor_node.scrolls_inner_viewport = scroll_node.ScrollsInnerViewport();
- compositor_node.scrolls_outer_viewport = scroll_node.ScrollsOuterViewport();
compositor_node.prevent_viewport_scrolling_from_inner =
scroll_node.PreventViewportScrollingFromInner();
- // |scrolls_using_viewport| should only ever be set on the inner scroll node.
- DCHECK(!compositor_node.prevent_viewport_scrolling_from_inner ||
- compositor_node.scrolls_inner_viewport);
-
compositor_node.max_scroll_offset_affected_by_page_scale =
scroll_node.MaxScrollOffsetAffectedByPageScale();
compositor_node.main_thread_scrolling_reasons =
@@ -562,13 +565,10 @@ void PropertyTreeManager::CreateCompositorScrollNode(
compositor_node.transform_id = scroll_offset_translation.id;
- // TODO(pdr): Set the scroll node's non_fast_scrolling_region value.
-
scroll_node.SetCcNodeId(new_sequence_number_, id);
GetScrollTree().SetScrollOffset(compositor_element_id,
scroll_offset_translation.scroll_offset);
- GetScrollTree().set_needs_update(true);
}
int PropertyTreeManager::EnsureCompositorScrollNode(
@@ -581,24 +581,38 @@ int PropertyTreeManager::EnsureCompositorScrollNode(
return id;
}
-void PropertyTreeManager::EmitClipMaskLayer() {
- cc::EffectNode& mask_isolation = *GetEffectTree().Node(current_.effect_id);
+int PropertyTreeManager::EnsureCompositorInnerScrollNode(
+ const TransformPaintPropertyNode& scroll_offset_translation) {
+ int node_id = EnsureCompositorScrollNode(scroll_offset_translation);
+ GetScrollTree().Node(node_id)->scrolls_inner_viewport = true;
+ return node_id;
+}
+int PropertyTreeManager::EnsureCompositorOuterScrollNode(
+ const TransformPaintPropertyNode& scroll_offset_translation) {
+ int node_id = EnsureCompositorScrollNode(scroll_offset_translation);
+ GetScrollTree().Node(node_id)->scrolls_outer_viewport = true;
+ return node_id;
+}
+
+void PropertyTreeManager::EmitClipMaskLayer() {
+ cc::EffectNode* mask_isolation = GetEffectTree().Node(current_.effect_id);
+ DCHECK(mask_isolation);
bool needs_layer =
- !pending_synthetic_mask_layers_.Contains(mask_isolation.id) &&
- mask_isolation.rounded_corner_bounds.IsEmpty();
+ !pending_synthetic_mask_layers_.Contains(mask_isolation->id) &&
+ mask_isolation->rounded_corner_bounds.IsEmpty();
int clip_id = EnsureCompositorClipNode(*current_.clip);
CompositorElementId mask_isolation_id, mask_effect_id;
SynthesizedClip& clip = client_.CreateOrReuseSynthesizedClipLayer(
- *current_.clip, needs_layer, mask_isolation_id, mask_effect_id);
+ *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);
-
- mask_isolation.stable_id = mask_isolation_id.GetStableId();
+ mask_isolation->stable_id);
+ mask_isolation->stable_id = mask_isolation_id.GetStableId();
if (!needs_layer)
return;
@@ -609,7 +623,11 @@ void PropertyTreeManager::EmitClipMaskLayer() {
mask_effect.clip_id = clip_id;
mask_effect.blend_mode = SkBlendMode::kDstIn;
- cc::Layer* mask_layer = clip.Layer();
+ // The address of mask_isolation may have changed when we insert
+ // |mask_effect| into the tree.
+ mask_isolation = GetEffectTree().Node(current_.effect_id);
+
+ cc::PictureLayer* mask_layer = clip.Layer();
const auto& clip_space = current_.clip->LocalTransformSpace();
layer_list_builder_.Add(mask_layer);
@@ -624,21 +642,29 @@ void PropertyTreeManager::EmitClipMaskLayer() {
mask_layer->SetScrollTreeIndex(scroll_id);
mask_layer->SetClipTreeIndex(clip_id);
mask_layer->SetEffectTreeIndex(mask_effect.id);
+
+ if (!mask_isolation->backdrop_filters.IsEmpty()) {
+ mask_layer->SetIsBackdropFilterMask(true);
+ auto element_id = CompositorElementIdFromUniqueObjectId(
+ mask_effect.stable_id, CompositorElementIdNamespace::kEffectMask);
+ mask_layer->SetElementId(element_id);
+ mask_isolation->backdrop_mask_element_id = element_id;
+ }
}
void PropertyTreeManager::CloseCcEffect() {
DCHECK(effect_stack_.size());
const auto& previous_state = effect_stack_.back();
- // An effect with exotic blending or backdrop-filter that is masked by a
- // synthesized clip must have its blending to the outermost synthesized clip.
+ // A backdrop effect (exotic blending or backdrop filter) that is masked by a
+ // synthesized clip must have its effect to the outermost synthesized clip.
// These operations need access to the backdrop of the enclosing effect. With
// the isolation for a synthesized clip, a blank backdrop will be seen.
- // Therefore the blending is delegated to the outermost synthesized clip, thus
- // the clip can't be shared with sibling layers, and must be closed now.
+ // Therefore the backdrop effect is delegated to the outermost synthesized
+ // clip, thus the clip can't be shared with sibling layers, and must be
+ // closed now.
bool clear_synthetic_effects =
- !IsCurrentCcEffectSynthetic() &&
- current_.effect->BlendMode() != SkBlendMode::kSrcOver;
+ !IsCurrentCcEffectSynthetic() && current_.effect->HasBackdropEffect();
// We are about to close an effect that was synthesized for isolating
// a clip mask. Now emit the actual clip mask that will be composited on
@@ -715,7 +741,7 @@ int PropertyTreeManager::SwitchToEffectNodeWithSynthesizedClip(
CloseCcEffect();
BuildEffectNodesRecursively(next_effect);
- SynthesizeCcEffectsForClipsIfNeeded(next_clip, SkBlendMode::kSrcOver);
+ SynthesizeCcEffectsForClipsIfNeeded(next_clip, /*next_effect*/ nullptr);
if (layer_draws_content)
pending_synthetic_mask_layers_.clear();
@@ -741,7 +767,7 @@ static bool IsNodeOnAncestorChain(const ClipPaintPropertyNode& find,
bool PropertyTreeManager::EffectStateMayBe2dAxisMisalignedToRenderSurface(
EffectState& state,
- size_t index) {
+ wtf_size_t index) {
if (state.may_be_2d_axis_misaligned_to_render_surface ==
EffectState::kUnknown) {
// The root effect has render surface, so it's always kAligned.
@@ -752,8 +778,8 @@ bool PropertyTreeManager::EffectStateMayBe2dAxisMisalignedToRenderSurface(
EffectState::kMisaligned;
} else {
state.may_be_2d_axis_misaligned_to_render_surface =
- TransformsMayBe2dAxisMisaligned(effect_stack_[index - 1].Transform(),
- current_.Transform())
+ TransformsMayBe2dAxisMisaligned(*effect_stack_[index - 1].transform,
+ *current_.transform)
? EffectState::kMisaligned
: EffectState::kAligned;
}
@@ -771,14 +797,14 @@ bool PropertyTreeManager::CurrentEffectMayBe2dAxisMisalignedToRenderSurface() {
PropertyTreeManager::CcEffectType PropertyTreeManager::SyntheticEffectType(
const ClipPaintPropertyNode& clip) {
unsigned effect_type = CcEffectType::kEffect;
- if (clip.ClipRect().IsRounded() || clip.ClipPath())
+ if (clip.PixelSnappedClipRect().IsRounded() || clip.ClipPath())
effect_type |= CcEffectType::kSyntheticForNonTrivialClip;
// Cc requires that a rectangluar clip is 2d-axis-aligned with the render
// surface to correctly apply the clip.
if (CurrentEffectMayBe2dAxisMisalignedToRenderSurface() ||
TransformsMayBe2dAxisMisaligned(clip.LocalTransformSpace(),
- current_.Transform()))
+ *current_.transform))
effect_type |= CcEffectType::kSyntheticFor2dAxisAlignment;
return static_cast<CcEffectType>(effect_type);
}
@@ -793,21 +819,26 @@ void PropertyTreeManager::ForceRenderSurfaceIfSyntheticRoundedCornerClip(
bool PropertyTreeManager::SupportsShaderBasedRoundedCorner(
const ClipPaintPropertyNode& clip,
- PropertyTreeManager::CcEffectType type) {
- if (!RuntimeEnabledFeatures::FastBorderRadiusEnabled())
- return false;
-
+ PropertyTreeManager::CcEffectType type,
+ const EffectPaintPropertyNode* next_effect) {
if (type & CcEffectType::kSyntheticFor2dAxisAlignment)
return false;
if (clip.ClipPath())
return false;
+ // Don't use shader based rounded corner if the next effect has backdrop
+ // filter and the clip is in different transform space, because we will use
+ // the effect's transform space for the mask isolation effect node.
+ if (next_effect && !next_effect->BackdropFilter().IsEmpty() &&
+ &next_effect->LocalTransformSpace() != &clip.LocalTransformSpace())
+ return false;
+
auto WidthAndHeightAreTheSame = [](const FloatSize& size) {
return size.Width() == size.Height();
};
- const FloatRoundedRect::Radii& radii = clip.ClipRect().GetRadii();
+ const FloatRoundedRect::Radii& radii = clip.PixelSnappedClipRect().GetRadii();
if (!WidthAndHeightAreTheSame(radii.TopLeft()) ||
!WidthAndHeightAreTheSame(radii.TopRight()) ||
!WidthAndHeightAreTheSame(radii.BottomRight()) ||
@@ -815,11 +846,10 @@ bool PropertyTreeManager::SupportsShaderBasedRoundedCorner(
return false;
}
- // Rounded corners that differ are not supported by the
- // CALayerOverlay system on Mac. Instead of letting it fall back
- // to the (worse for memory and battery) non-CALayerOverlay system
- // for such cases, fall back to a non-fast border-radius mask for
- // the effect node.
+ // Rounded corners that differ are not supported by the CALayerOverlay system
+ // on Mac. Instead of letting it fall back to the (worse for memory and
+ // battery) non-CALayerOverlay system for such cases, fall back to a
+ // non-shader border-radius mask for the effect node.
#if defined(OS_MACOSX)
if (radii.TopLeft() != radii.TopRight() ||
radii.TopLeft() != radii.BottomRight() ||
@@ -831,20 +861,55 @@ bool PropertyTreeManager::SupportsShaderBasedRoundedCorner(
return true;
}
-SkBlendMode PropertyTreeManager::SynthesizeCcEffectsForClipsIfNeeded(
+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(
const ClipPaintPropertyNode& target_clip_arg,
- SkBlendMode delegated_blend) {
+ const EffectPaintPropertyNode* next_effect) {
const auto* target_clip = &target_clip_arg.Unalias();
- if (delegated_blend != SkBlendMode::kSrcOver) {
- // Exit all synthetic effect node if the next child has exotic blending mode
- // because it has to access the backdrop of enclosing effect.
+ auto backdrop_effect_state = kNoBackdropEffect;
+ 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
+ // backdrop of enclosing effect.
while (IsCurrentCcEffectSynthetic())
CloseCcEffect();
- // An effect node can't omit render surface if it has child with exotic
- // blending mode. See comments below for more detail.
- // TODO(crbug.com/504464): Remove premature optimization here.
- SetCurrentEffectRenderSurfaceReason(cc::RenderSurfaceReason::kBlendMode);
+ // An effect node can't omit render surface if it has child with backdrop
+ // effect, in order to define the scope of the backdrop.
+ SetCurrentEffectRenderSurfaceReason(
+ cc::RenderSurfaceReason::kBackdropScope);
+ backdrop_effect_state = kBackdropEffectToBeSetOnCcEffectNode;
} else {
// Exit synthetic effects until there are no more synthesized clips below
// our lowest common ancestor.
@@ -857,7 +922,7 @@ SkBlendMode PropertyTreeManager::SynthesizeCcEffectsForClipsIfNeeded(
// In CompositeAfterPaint this should never happen.
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
NOTREACHED();
- return delegated_blend;
+ return backdrop_effect_state;
}
const auto* pre_exit_clip = current_.clip;
CloseCcEffect();
@@ -886,10 +951,13 @@ SkBlendMode PropertyTreeManager::SynthesizeCcEffectsForClipsIfNeeded(
// In CompositeAfterPaint this should never happen.
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
NOTREACHED();
- return delegated_blend;
+ return backdrop_effect_state;
}
- for (size_t i = pending_clips.size(); i--;) {
+ if (pending_clips.IsEmpty())
+ return backdrop_effect_state;
+
+ for (auto i = pending_clips.size(); i--;) {
const auto& pending_clip = pending_clips[i];
// For a non-trivial clip, the synthetic effect is an isolation to enclose
@@ -898,29 +966,16 @@ SkBlendMode PropertyTreeManager::SynthesizeCcEffectsForClipsIfNeeded(
// surface which is axis-aligned with the clip.
cc::EffectNode& synthetic_effect = *GetEffectTree().Node(
GetEffectTree().Insert(cc::EffectNode(), current_.effect_id));
+
if (pending_clip.type & CcEffectType::kSyntheticForNonTrivialClip) {
synthetic_effect.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().
- } else {
- synthetic_effect.stable_id =
- CompositorElementIdFromUniqueObjectId(NewUniqueObjectId())
- .GetStableId();
- // 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());
- }
- const auto& transform = pending_clip.clip->LocalTransformSpace();
- synthetic_effect.transform_id = EnsureCompositorTransformNode(transform);
- synthetic_effect.double_sided = !transform.IsBackfaceHidden();
- if (pending_clip.type & CcEffectType::kSyntheticForNonTrivialClip) {
if (SupportsShaderBasedRoundedCorner(*pending_clip.clip,
- pending_clip.type)) {
+ pending_clip.type, next_effect)) {
synthetic_effect.rounded_corner_bounds =
- gfx::RRectF(pending_clip.clip->ClipRect());
+ gfx::RRectF(pending_clip.clip->PixelSnappedClipRect());
synthetic_effect.is_fast_rounded_corner = true;
// Nested rounded corner clips need to force render surfaces for
@@ -938,31 +993,50 @@ SkBlendMode PropertyTreeManager::SynthesizeCcEffectsForClipsIfNeeded(
}
} else {
synthetic_effect.render_surface_reason =
- pending_clip.clip->ClipRect().IsRounded()
+ pending_clip.clip->PixelSnappedClipRect().IsRounded()
? cc::RenderSurfaceReason::kRoundedCorner
: cc::RenderSurfaceReason::kClipPath;
}
pending_synthetic_mask_layers_.insert(synthetic_effect.id);
+ } else {
+ DCHECK(pending_clip.type & CcEffectType::kSyntheticFor2dAxisAlignment);
+ synthetic_effect.stable_id =
+ CompositorElementIdFromUniqueObjectId(NewUniqueObjectId())
+ .GetStableId();
+ // 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());
}
+
if (pending_clip.type & CcEffectType::kSyntheticFor2dAxisAlignment) {
synthetic_effect.render_surface_reason =
cc::RenderSurfaceReason::kClipAxisAlignment;
}
- // Clip and kDstIn do not commute. This shall never be reached because
- // kDstIn is only used internally to implement CSS clip-path and mask,
- // and there is never a difference between the output clip of the effect
- // and the mask content.
- DCHECK(delegated_blend != SkBlendMode::kDstIn);
- synthetic_effect.blend_mode = delegated_blend;
- delegated_blend = SkBlendMode::kSrcOver;
+ 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
+ // backdrop.
+ DCHECK(next_effect);
+ transform = &next_effect->LocalTransformSpace();
+ PopulateCcEffectNodeBackdropEffect(synthetic_effect, *next_effect);
+ backdrop_effect_state = kBackdropEffectHasSetOnSyntheticEffect;
+ } else {
+ transform = &pending_clip.clip->LocalTransformSpace();
+ }
+
+ synthetic_effect.transform_id = EnsureCompositorTransformNode(*transform);
+ synthetic_effect.double_sided = !transform->IsBackfaceHidden();
effect_stack_.emplace_back(current_);
SetCurrentEffectState(synthetic_effect, pending_clip.type, *current_.effect,
- *pending_clip.clip);
+ *pending_clip.clip, *transform);
}
- return delegated_blend;
+ return backdrop_effect_state;
}
void PropertyTreeManager::BuildEffectNodesRecursively(
@@ -981,26 +1055,35 @@ void PropertyTreeManager::BuildEffectNodesRecursively(
"be contiguous.";
#endif
- // If we don't have an output clip, then we'll use the clip of the last
- // non-synthetic effect. This means we should close all synthetic effects on
- // the stack first.
- if (!next_effect.OutputClip()) {
+ auto backdrop_effect_state = kNoBackdropEffect;
+ int output_clip_id = 0;
+ const auto* output_clip = SafeUnalias(next_effect.OutputClip());
+ if (output_clip) {
+ backdrop_effect_state =
+ SynthesizeCcEffectsForClipsIfNeeded(*output_clip, &next_effect);
+ output_clip_id = EnsureCompositorClipNode(*output_clip);
+ } else {
+ // If we don't have an output clip, then we'll use the clip of the last
+ // non-synthetic effect. This means we should close all synthetic effects
+ // on the stack first.
while (IsCurrentCcEffectSynthetic())
CloseCcEffect();
- }
- SkBlendMode blend_mode;
- const ClipPaintPropertyNode* output_clip;
- int output_clip_id;
- std::tie(blend_mode, output_clip, output_clip_id) =
- GetBlendModeAndOutputClipForEffect(next_effect);
+ 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);
next_effect.SetCcNodeId(new_sequence_number_, effect_node_id);
- PopulateCcEffectNode(effect_node, next_effect, output_clip_id, blend_mode);
+ PopulateCcEffectNode(effect_node, next_effect, output_clip_id,
+ backdrop_effect_state);
CompositorElementId compositor_element_id =
next_effect.GetCompositorElementId();
@@ -1013,45 +1096,18 @@ void PropertyTreeManager::BuildEffectNodesRecursively(
effect_stack_.emplace_back(current_);
SetCurrentEffectState(effect_node, CcEffectType::kEffect, next_effect,
- *output_clip);
-}
-
-std::tuple<SkBlendMode, const ClipPaintPropertyNode*, int>
-PropertyTreeManager::GetBlendModeAndOutputClipForEffect(
- const EffectPaintPropertyNode& effect) {
- SkBlendMode blend_mode;
- int output_clip_id;
- const auto* output_clip = SafeUnalias(effect.OutputClip());
- if (output_clip) {
- blend_mode =
- SynthesizeCcEffectsForClipsIfNeeded(*output_clip, effect.BlendMode());
- output_clip_id = EnsureCompositorClipNode(*output_clip);
- } else {
- DCHECK(!IsCurrentCcEffectSynthetic());
- // An effect node can't omit render surface if it has child with exotic
- // blending mode.
- // TODO(crbug.com/504464): Remove premature optimization here.
- if (effect.BlendMode() != SkBlendMode::kSrcOver)
- SetCurrentEffectRenderSurfaceReason(cc::RenderSurfaceReason::kBlendMode);
-
- blend_mode = effect.BlendMode();
- 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));
- }
- return std::make_tuple(blend_mode, output_clip, output_clip_id);
+ *output_clip, next_effect.LocalTransformSpace());
}
void PropertyTreeManager::PopulateCcEffectNode(
cc::EffectNode& effect_node,
const EffectPaintPropertyNode& effect,
int output_clip_id,
- SkBlendMode blend_mode) {
+ BackdropEffectState backdrop_effect_state) {
effect_node.stable_id = effect.GetCompositorElementId().GetStableId();
effect_node.clip_id = output_clip_id;
- // An effect with filters or backdrop filters needs a render surface.
+ // 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.
@@ -1060,38 +1116,34 @@ void PropertyTreeManager::PopulateCcEffectNode(
} else if (effect.HasActiveFilterAnimation()) {
effect_node.render_surface_reason =
cc::RenderSurfaceReason::kFilterAnimation;
- } else if (!effect.BackdropFilter().IsEmpty()) {
- effect_node.render_surface_reason =
- cc::RenderSurfaceReason::kBackdropFilter;
- } else if (effect.HasActiveBackdropFilterAnimation()) {
- effect_node.render_surface_reason =
- cc::RenderSurfaceReason::kBackdropFilterAnimation;
- } else if (blend_mode != SkBlendMode::kSrcOver &&
- blend_mode != SkBlendMode::kDstIn) {
- effect_node.render_surface_reason = cc::RenderSurfaceReason::kBlendMode;
}
+ // If needed, render surface reason for backdrop effect will be set in
+ // PopuluateCcEffectNodeBackdropEffect() below.
effect_node.opacity = effect.Opacity();
if (effect.GetColorFilter() != kColorFilterNone) {
// Currently color filter is only used by SVG masks.
// We are cutting corner here by support only specific configuration.
- DCHECK(effect.GetColorFilter() == kColorFilterLuminanceToAlpha);
- DCHECK(blend_mode == SkBlendMode::kDstIn);
+ DCHECK_EQ(effect.GetColorFilter(), kColorFilterLuminanceToAlpha);
+ DCHECK_EQ(effect.BlendMode(), SkBlendMode::kDstIn);
DCHECK(effect.Filter().IsEmpty());
effect_node.filters.Append(cc::FilterOperation::CreateReferenceFilter(
sk_make_sp<ColorFilterPaintFilter>(SkLumaColorFilter::Make(),
nullptr)));
+ effect_node.blend_mode = SkBlendMode::kDstIn;
} else {
- effect_node.filters = effect.Filter().AsCcFilterOperations();
- effect_node.backdrop_filters =
- effect.BackdropFilter().AsCcFilterOperations();
- effect_node.backdrop_filter_bounds = effect.BackdropFilterBounds();
- effect_node.backdrop_mask_element_id = effect.BackdropMaskElementId();
- effect_node.filters_origin = effect.FiltersOrigin();
effect_node.transform_id =
EnsureCompositorTransformNode(effect.LocalTransformSpace());
+ if (backdrop_effect_state == kBackdropEffectToBeSetOnCcEffectNode) {
+ // We never have backdrop effect and filter on the same effect node.
+ DCHECK(effect.Filter().IsEmpty());
+ PopulateCcEffectNodeBackdropEffect(effect_node, effect);
+ effect_node.backdrop_mask_element_id = effect.BackdropMaskElementId();
+ } else {
+ effect_node.filters = effect.Filter().AsCcFilterOperations();
+ effect_node.filters_origin = effect.FiltersOrigin();
+ }
}
- effect_node.blend_mode = blend_mode;
effect_node.double_sided = !effect.LocalTransformSpace().IsBackfaceHidden();
effect_node.effect_changed = effect.NodeChangeAffectsRaster();
}
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 09b99c7d1f2..4c807b5c0f6 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
@@ -11,7 +11,6 @@
#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"
-#include "third_party/skia/include/core/SkBlendMode.h"
namespace cc {
class ClipTree;
@@ -26,6 +25,10 @@ struct TransformNode;
enum class RenderSurfaceReason : uint8_t;
}
+namespace gfx {
+class ScrollOffset;
+}
+
namespace blink {
class ClipPaintPropertyNode;
@@ -39,6 +42,7 @@ class PropertyTreeManagerClient {
public:
virtual SynthesizedClip& CreateOrReuseSynthesizedClipLayer(
const ClipPaintPropertyNode&,
+ const TransformPaintPropertyNode&,
bool needs_layer,
CompositorElementId& mask_isolation_id,
CompositorElementId& mask_effect_id) = 0;
@@ -99,6 +103,12 @@ class PropertyTreeManager {
int EnsureCompositorScrollNode(
const TransformPaintPropertyNode& scroll_offset_translation);
+ // Same as above but marks the scroll nodes as being the viewport.
+ int EnsureCompositorInnerScrollNode(
+ const TransformPaintPropertyNode& scroll_offset_translation);
+ int EnsureCompositorOuterScrollNode(
+ const TransformPaintPropertyNode& scroll_offset_translation);
+
int EnsureCompositorPageScaleTransformNode(const TransformPaintPropertyNode&);
// This function is expected to be invoked right before emitting each layer.
@@ -119,21 +129,21 @@ class PropertyTreeManager {
void Finalize();
static bool DirectlyUpdateCompositedOpacityValue(
- cc::PropertyTrees*,
cc::LayerTreeHost&,
const EffectPaintPropertyNode&);
static bool DirectlyUpdateScrollOffsetTransform(
- cc::PropertyTrees*,
cc::LayerTreeHost&,
const TransformPaintPropertyNode&);
- static bool DirectlyUpdateTransform(cc::PropertyTrees*,
- cc::LayerTreeHost&,
+ static bool DirectlyUpdateTransform(cc::LayerTreeHost&,
const TransformPaintPropertyNode&);
static bool DirectlyUpdatePageScaleTransform(
- cc::PropertyTrees*,
cc::LayerTreeHost&,
const TransformPaintPropertyNode&);
+ static void DirectlySetScrollOffset(cc::LayerTreeHost&,
+ CompositorElementId,
+ const gfx::ScrollOffset&);
+
private:
void SetupRootTransformNode();
void SetupRootClipNode();
@@ -156,8 +166,10 @@ class PropertyTreeManager {
kSyntheticFor2dAxisAlignment = 1 << 1
};
- static bool SupportsShaderBasedRoundedCorner(const ClipPaintPropertyNode&,
- CcEffectType type);
+ static bool SupportsShaderBasedRoundedCorner(
+ const ClipPaintPropertyNode&,
+ CcEffectType type,
+ const EffectPaintPropertyNode* next_effect);
struct EffectState {
// The cc effect node that has the corresponding drawing state to the
@@ -177,6 +189,12 @@ class PropertyTreeManager {
// It's never nullptr.
const ClipPaintPropertyNode* clip;
+ // The transform space of this state. It's |&effect->LocalTransformSpace()|
+ // if this state is of kEffect type or synthetic with backdrop filters
+ // moved up from the original effect.
+ // Otherwise it's |&clip->LocalTransformSpace()|.
+ const TransformPaintPropertyNode* transform;
+
// Whether the transform space of this state may be 2d axis misaligned to
// the containing render surface. As there may be new render surfaces
// created between this state and the current known ancestor render surface
@@ -201,28 +219,35 @@ class PropertyTreeManager {
// self and the next render surface. This is used to force a render surface
// for all ancestor synthetic rounded clips if a descendant is found.
bool contained_by_non_render_surface_synthetic_rounded_clip;
-
- // The transform space of the state.
- const TransformPaintPropertyNode& Transform() const;
};
void CollectAnimationElementId(CompositorElementId);
void BuildEffectNodesRecursively(const EffectPaintPropertyNode& next_effect);
void ForceRenderSurfaceIfSyntheticRoundedCornerClip(EffectState& state);
- SkBlendMode SynthesizeCcEffectsForClipsIfNeeded(
+
+ // 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(
const ClipPaintPropertyNode& target_clip,
- SkBlendMode delegated_blend);
+ const EffectPaintPropertyNode* next_effect);
+
void EmitClipMaskLayer();
void CloseCcEffect();
-
- // For a given effect node, this returns the blend mode, clip property node,
- // and an int indicating cc clip node's id.
- std::tuple<SkBlendMode, const ClipPaintPropertyNode*, int>
- GetBlendModeAndOutputClipForEffect(const EffectPaintPropertyNode&);
void PopulateCcEffectNode(cc::EffectNode&,
- const EffectPaintPropertyNode&,
+ const EffectPaintPropertyNode& effect,
int output_clip_id,
- SkBlendMode);
+ BackdropEffectState);
+ void PopulateCcEffectNodeBackdropEffect(
+ cc::EffectNode& effect_node,
+ const EffectPaintPropertyNode& backdrop_effect);
bool IsCurrentCcEffectSynthetic() const { return current_.effect_type; }
bool IsCurrentCcEffectSyntheticForNonTrivialClip() const {
@@ -230,14 +255,15 @@ class PropertyTreeManager {
}
bool EffectStateMayBe2dAxisMisalignedToRenderSurface(EffectState&,
- size_t index);
+ wtf_size_t index);
bool CurrentEffectMayBe2dAxisMisalignedToRenderSurface();
CcEffectType SyntheticEffectType(const ClipPaintPropertyNode&);
void SetCurrentEffectState(const cc::EffectNode&,
CcEffectType,
const EffectPaintPropertyNode&,
- const ClipPaintPropertyNode&);
+ const ClipPaintPropertyNode&,
+ const TransformPaintPropertyNode&);
void SetCurrentEffectRenderSurfaceReason(cc::RenderSurfaceReason);
cc::TransformTree& GetTransformTree();
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 86bd4d15537..dfa0ae804e9 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.cc
@@ -36,7 +36,7 @@ constexpr CompositingReasonStringMap kCompositingReasonsStringMap[] = {
{CompositingReason::kActiveBackdropFilterAnimation,
"activeBackdropFilterAnimation",
"Has an active accelerated backdrop filter animation or transition"},
- {CompositingReason::kImmersiveArOverlay, "immersiveArOverlay",
+ {CompositingReason::kXrOverlay, "xrOverlay",
"Is DOM overlay for WebXR immersive-ar mode"},
{CompositingReason::kScrollDependentPosition, "scrollDependentPosition",
"Is fixed or sticky position"},
@@ -58,8 +58,6 @@ constexpr CompositingReasonStringMap kCompositingReasonsStringMap[] = {
"Has a backdrop filter"},
{CompositingReason::kRootScroller, "rootScroller",
"Is the document.rootScroller"},
- {CompositingReason::kCrossOriginIframe, "crossOriginIframe",
- "Is a cross-origin iframe"},
{CompositingReason::kAssumedOverlap, "assumedOverlap",
"Might overlap other composited content"},
{CompositingReason::kOverlap, "overlap",
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 5df7a4e83d1..144640a6ddc 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.h
@@ -27,7 +27,6 @@ using CompositingReasons = uint64_t;
V(ActiveOpacityAnimation) \
V(ActiveFilterAnimation) \
V(ActiveBackdropFilterAnimation) \
- V(ImmersiveArOverlay) \
V(ScrollDependentPosition) \
V(OverflowScrolling) \
V(OverflowScrollingParent) \
@@ -40,7 +39,7 @@ using CompositingReasons = uint64_t;
V(WillChangeOther) \
V(BackdropFilter) \
V(RootScroller) \
- V(CrossOriginIframe) \
+ V(XrOverlay) \
\
/* Overlap reasons that require knowing what's behind you in paint-order \
before knowing the answer. */ \
@@ -124,8 +123,8 @@ class PLATFORM_EXPORT CompositingReason {
kComboAllDirectNonStyleDeterminedReasons =
kVideo | kCanvas | kPlugin | kIFrame | kOverflowScrollingParent |
- kOutOfFlowClipping | kVideoOverlay | kImmersiveArOverlay | kRoot |
- kRootScroller | kScrollDependentPosition | kCrossOriginIframe,
+ kOutOfFlowClipping | kVideoOverlay | kXrOverlay | kRoot |
+ kRootScroller | kScrollDependentPosition,
kComboAllDirectReasons = kComboAllDirectStyleDeterminedReasons |
kComboAllDirectNonStyleDeterminedReasons,
@@ -149,6 +148,9 @@ class PLATFORM_EXPORT CompositingReason {
kComboSquashableReasons =
kOverlap | kAssumedOverlap | kOverflowScrollingParent,
+ kDirectReasonsForPaintOffsetTranslationProperty =
+ kScrollDependentPosition | kVideo | kCanvas | kPlugin | kIFrame,
+
kDirectReasonsForTransformProperty =
k3DTransform | kWillChangeTransform | kWillChangeOther |
kPerspectiveWith3DDescendants | kPreserve3DWith3DDescendants |
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositor_element_id.h b/chromium/third_party/blink/renderer/platform/graphics/compositor_element_id.h
index 957fbf2b7fe..25b0f8227d6 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositor_element_id.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositor_element_id.h
@@ -25,8 +25,9 @@ enum class CompositorElementIdNamespace {
kEffectClipPath,
kVerticalScrollbar,
kHorizontalScrollbar,
+ kDOMNodeId,
// The following values are for internal usage only.
- kMax = kHorizontalScrollbar,
+ kMax = kDOMNodeId,
// A sentinel to indicate the maximum representable namespace id
// (the maximum is one less than this value).
kMaxRepresentable = 1 << kCompositorNamespaceBitCount
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositor_filter_operations.cc b/chromium/third_party/blink/renderer/platform/graphics/compositor_filter_operations.cc
index 243b9a1c0e0..9eec39764c9 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositor_filter_operations.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositor_filter_operations.cc
@@ -110,6 +110,10 @@ bool CompositorFilterOperations::HasFilterThatMovesPixels() const {
return filter_operations_.HasFilterThatMovesPixels();
}
+bool CompositorFilterOperations::HasReferenceFilter() const {
+ return filter_operations_.HasReferenceFilter();
+}
+
bool CompositorFilterOperations::operator==(
const CompositorFilterOperations& o) const {
return reference_box_ == o.reference_box_ &&
diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositor_filter_operations.h b/chromium/third_party/blink/renderer/platform/graphics/compositor_filter_operations.h
index c943a2619f9..4c3a334f655 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/compositor_filter_operations.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/compositor_filter_operations.h
@@ -49,9 +49,10 @@ class PLATFORM_EXPORT CompositorFilterOperations {
FloatRect MapRect(const FloatRect& input_rect) const;
bool HasFilterThatMovesPixels() const;
+ bool HasReferenceFilter() const;
void SetReferenceBox(const FloatRect& r) { reference_box_ = r; }
- FloatRect ReferenceBox() const { return reference_box_; }
+ const FloatRect& ReferenceBox() const { return reference_box_; }
// For reference filters, this equality operator compares pointers of the
// image_filter fields instead of their values.
diff --git a/chromium/third_party/blink/renderer/platform/graphics/contiguous_container.cc b/chromium/third_party/blink/renderer/platform/graphics/contiguous_container.cc
index 19cb6f21032..9ea0c88d694 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/contiguous_container.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/contiguous_container.cc
@@ -22,7 +22,7 @@ class ContiguousContainerBase::Buffer {
USING_FAST_MALLOC(Buffer);
public:
- Buffer(size_t buffer_size, const char* type_name) {
+ Buffer(wtf_size_t buffer_size, const char* type_name) {
capacity_ = WTF::Partitions::BufferActualSize(buffer_size);
begin_ = end_ =
static_cast<char*>(WTF::Partitions::BufferMalloc(capacity_, type_name));
@@ -34,12 +34,12 @@ class ContiguousContainerBase::Buffer {
WTF::Partitions::BufferFree(begin_);
}
- size_t Capacity() const { return capacity_; }
- size_t UsedCapacity() const { return end_ - begin_; }
- size_t UnusedCapacity() const { return Capacity() - UsedCapacity(); }
+ wtf_size_t Capacity() const { return capacity_; }
+ wtf_size_t UsedCapacity() const { return end_ - begin_; }
+ wtf_size_t UnusedCapacity() const { return Capacity() - UsedCapacity(); }
bool IsEmpty() const { return UsedCapacity() == 0; }
- void* Allocate(size_t object_size) {
+ void* Allocate(wtf_size_t object_size) {
DCHECK_GE(UnusedCapacity(), object_size);
ANNOTATE_CHANGE_SIZE(begin_, capacity_, UsedCapacity(),
UsedCapacity() + object_size);
@@ -60,12 +60,12 @@ class ContiguousContainerBase::Buffer {
// m_begin <= m_end <= m_begin + m_capacity
char* begin_;
char* end_;
- size_t capacity_;
+ wtf_size_t capacity_;
DISALLOW_COPY_AND_ASSIGN(Buffer);
};
-ContiguousContainerBase::ContiguousContainerBase(size_t max_object_size)
+ContiguousContainerBase::ContiguousContainerBase(wtf_size_t max_object_size)
: end_index_(0), max_object_size_(max_object_size) {}
ContiguousContainerBase::ContiguousContainerBase(
@@ -82,31 +82,31 @@ ContiguousContainerBase& ContiguousContainerBase::operator=(
return *this;
}
-size_t ContiguousContainerBase::CapacityInBytes() const {
- size_t capacity = 0;
+wtf_size_t ContiguousContainerBase::CapacityInBytes() const {
+ wtf_size_t capacity = 0;
for (const auto& buffer : buffers_)
capacity += buffer->Capacity();
return capacity;
}
-size_t ContiguousContainerBase::UsedCapacityInBytes() const {
- size_t used_capacity = 0;
+wtf_size_t ContiguousContainerBase::UsedCapacityInBytes() const {
+ wtf_size_t used_capacity = 0;
for (const auto& buffer : buffers_)
used_capacity += buffer->UsedCapacity();
return used_capacity;
}
-size_t ContiguousContainerBase::MemoryUsageInBytes() const {
+wtf_size_t ContiguousContainerBase::MemoryUsageInBytes() const {
return sizeof(*this) + CapacityInBytes() +
elements_.capacity() * sizeof(elements_[0]);
}
-void ContiguousContainerBase::ReserveInitialCapacity(size_t buffer_size,
+void ContiguousContainerBase::ReserveInitialCapacity(wtf_size_t buffer_size,
const char* type_name) {
AllocateNewBufferForNextAllocation(buffer_size, type_name);
}
-void* ContiguousContainerBase::Allocate(size_t object_size,
+void* ContiguousContainerBase::Allocate(wtf_size_t object_size,
const char* type_name) {
DCHECK_LE(object_size, max_object_size_);
@@ -120,9 +120,9 @@ void* ContiguousContainerBase::Allocate(size_t object_size,
}
if (!buffer_for_alloc) {
- size_t new_buffer_size = buffers_.IsEmpty()
- ? kDefaultInitialBufferSize * max_object_size_
- : 2 * buffers_.back()->Capacity();
+ wtf_size_t new_buffer_size =
+ buffers_.IsEmpty() ? kDefaultInitialBufferSize * max_object_size_
+ : 2 * buffers_.back()->Capacity();
buffer_for_alloc =
AllocateNewBufferForNextAllocation(new_buffer_size, type_name);
}
@@ -169,7 +169,7 @@ void ContiguousContainerBase::ShrinkToFit() {
ContiguousContainerBase::Buffer*
ContiguousContainerBase::AllocateNewBufferForNextAllocation(
- size_t buffer_size,
+ wtf_size_t buffer_size,
const char* type_name) {
DCHECK(buffers_.IsEmpty() || end_index_ == buffers_.size() - 1);
std::unique_ptr<Buffer> new_buffer =
diff --git a/chromium/third_party/blink/renderer/platform/graphics/contiguous_container.h b/chromium/third_party/blink/renderer/platform/graphics/contiguous_container.h
index 3eee5589124..c81241eb708 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/contiguous_container.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/contiguous_container.h
@@ -41,21 +41,21 @@ class PLATFORM_EXPORT ContiguousContainerBase {
DISALLOW_NEW();
protected:
- explicit ContiguousContainerBase(size_t max_object_size);
+ explicit ContiguousContainerBase(wtf_size_t max_object_size);
ContiguousContainerBase(ContiguousContainerBase&&);
~ContiguousContainerBase();
ContiguousContainerBase& operator=(ContiguousContainerBase&&);
- size_t size() const { return elements_.size(); }
+ wtf_size_t size() const { return elements_.size(); }
bool IsEmpty() const { return !size(); }
- size_t CapacityInBytes() const;
- size_t UsedCapacityInBytes() const;
- size_t MemoryUsageInBytes() const;
+ wtf_size_t CapacityInBytes() const;
+ wtf_size_t UsedCapacityInBytes() const;
+ wtf_size_t MemoryUsageInBytes() const;
// These do not invoke constructors or destructors.
- void ReserveInitialCapacity(size_t, const char* type_name);
- void* Allocate(size_t object_size, const char* type_name);
+ void ReserveInitialCapacity(wtf_size_t, const char* type_name);
+ void* Allocate(wtf_size_t object_size, const char* type_name);
void RemoveLast();
void Clear();
void Swap(ContiguousContainerBase&);
@@ -69,11 +69,11 @@ class PLATFORM_EXPORT ContiguousContainerBase {
private:
class Buffer;
- Buffer* AllocateNewBufferForNextAllocation(size_t, const char* type_name);
+ Buffer* AllocateNewBufferForNextAllocation(wtf_size_t, const char* type_name);
Vector<std::unique_ptr<Buffer>> buffers_;
unsigned end_index_;
- size_t max_object_size_;
+ wtf_size_t max_object_size_;
DISALLOW_COPY_AND_ASSIGN(ContiguousContainerBase);
};
@@ -138,10 +138,10 @@ class ContiguousContainer : public ContiguousContainerBase {
using value_type = BaseElementType;
- explicit ContiguousContainer(size_t max_object_size)
+ explicit ContiguousContainer(wtf_size_t max_object_size)
: ContiguousContainerBase(Align(max_object_size)) {}
- ContiguousContainer(size_t max_object_size, size_t initial_size_bytes)
+ ContiguousContainer(wtf_size_t max_object_size, wtf_size_t initial_size_bytes)
: ContiguousContainer(max_object_size) {
ReserveInitialCapacity(std::max(max_object_size, initial_size_bytes),
WTF_HEAP_PROFILER_TYPE_NAME(BaseElementType));
@@ -190,8 +190,8 @@ class ContiguousContainer : public ContiguousContainerBase {
const BaseElementType& First() const { return *begin(); }
BaseElementType& Last() { return *rbegin(); }
const BaseElementType& Last() const { return *rbegin(); }
- BaseElementType& operator[](size_t index) { return *(begin() + index); }
- const BaseElementType& operator[](size_t index) const {
+ BaseElementType& operator[](wtf_size_t index) { return *(begin() + index); }
+ const BaseElementType& operator[](wtf_size_t index) const {
return *(begin() + index);
}
@@ -226,7 +226,7 @@ class ContiguousContainer : public ContiguousContainerBase {
// Appends a new element using memcpy, then default-constructs a base
// element in its place. Use with care.
- BaseElementType& AppendByMoving(BaseElementType& item, size_t size) {
+ BaseElementType& AppendByMoving(BaseElementType& item, wtf_size_t size) {
DCHECK_GE(size, sizeof(BaseElementType));
void* new_item = AlignedAllocate(size);
memcpy(new_item, static_cast<void*>(&item), size);
@@ -235,15 +235,15 @@ class ContiguousContainer : public ContiguousContainerBase {
}
private:
- void* AlignedAllocate(size_t size) {
+ void* AlignedAllocate(wtf_size_t size) {
void* result = ContiguousContainerBase::Allocate(
Align(size), WTF_HEAP_PROFILER_TYPE_NAME(BaseElementType));
DCHECK_EQ(reinterpret_cast<intptr_t>(result) & (alignment - 1), 0u);
return result;
}
- static size_t Align(size_t size) {
- size_t aligned_size = alignment * ((size + alignment - 1) / alignment);
+ static wtf_size_t Align(wtf_size_t size) {
+ wtf_size_t aligned_size = alignment * ((size + alignment - 1) / alignment);
DCHECK_EQ(aligned_size % alignment, 0u);
DCHECK_GE(aligned_size, size);
DCHECK_LT(aligned_size, size + alignment);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/crossfade_generated_image.cc b/chromium/third_party/blink/renderer/platform/graphics/crossfade_generated_image.cc
index 59c68f69182..c1a01c9a1a3 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/crossfade_generated_image.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/crossfade_generated_image.cc
@@ -43,10 +43,12 @@ CrossfadeGeneratedImage::CrossfadeGeneratedImage(
percentage_(percentage),
crossfade_size_(crossfade_size) {}
-void CrossfadeGeneratedImage::DrawCrossfade(cc::PaintCanvas* canvas,
- const PaintFlags& flags,
- ImageClampingMode clamp_mode,
- ImageDecodingMode decode_mode) {
+void CrossfadeGeneratedImage::DrawCrossfade(
+ cc::PaintCanvas* canvas,
+ const PaintFlags& flags,
+ RespectImageOrientationEnum respect_orientation,
+ ImageClampingMode clamp_mode,
+ ImageDecodingMode decode_mode) {
FloatRect from_image_rect(FloatPoint(), FloatSize(from_image_->Size()));
FloatRect to_image_rect(FloatPoint(), FloatSize(to_image_->Size()));
FloatRect dest_rect((FloatPoint()), crossfade_size_);
@@ -72,33 +74,32 @@ void CrossfadeGeneratedImage::DrawCrossfade(cc::PaintCanvas* canvas,
image_flags.setBlendMode(SkBlendMode::kPlus);
image_flags.setColor(ScaleAlpha(flags.getColor(), percentage_));
to_image_->Draw(canvas, image_flags, dest_rect, to_image_rect,
- kDoNotRespectImageOrientation, clamp_mode, decode_mode);
+ respect_orientation, clamp_mode, decode_mode);
}
-void CrossfadeGeneratedImage::Draw(cc::PaintCanvas* canvas,
- const PaintFlags& flags,
- const FloatRect& dst_rect,
- const FloatRect& src_rect,
- RespectImageOrientationEnum,
- ImageClampingMode clamp_mode,
- ImageDecodingMode decode_mode) {
+void CrossfadeGeneratedImage::Draw(
+ cc::PaintCanvas* canvas,
+ const PaintFlags& flags,
+ const FloatRect& dst_rect,
+ const FloatRect& src_rect,
+ RespectImageOrientationEnum respect_orientation,
+ ImageClampingMode clamp_mode,
+ ImageDecodingMode decode_mode) {
// Draw nothing if either of the images hasn't loaded yet.
if (from_image_ == Image::NullImage() || to_image_ == Image::NullImage())
return;
PaintCanvasAutoRestore ar(canvas, true);
canvas->clipRect(dst_rect);
- canvas->translate(dst_rect.X(), dst_rect.Y());
- if (dst_rect.Size() != src_rect.Size())
- canvas->scale(dst_rect.Width() / src_rect.Width(),
- dst_rect.Height() / src_rect.Height());
- canvas->translate(-src_rect.X(), -src_rect.Y());
-
- DrawCrossfade(canvas, flags, clamp_mode, decode_mode);
+ canvas->concat(
+ SkMatrix::MakeRectToRect(src_rect, dst_rect, SkMatrix::kFill_ScaleToFit));
+ DrawCrossfade(canvas, flags, respect_orientation, clamp_mode, decode_mode);
}
-void CrossfadeGeneratedImage::DrawTile(GraphicsContext& context,
- const FloatRect& src_rect) {
+void CrossfadeGeneratedImage::DrawTile(
+ GraphicsContext& context,
+ const FloatRect& src_rect,
+ RespectImageOrientationEnum respect_orientation) {
// Draw nothing if either of the images hasn't loaded yet.
if (from_image_ == Image::NullImage() || to_image_ == Image::NullImage())
return;
@@ -108,7 +109,8 @@ void CrossfadeGeneratedImage::DrawTile(GraphicsContext& context,
FloatRect dest_rect((FloatPoint()), crossfade_size_);
flags.setFilterQuality(
context.ComputeFilterQuality(this, dest_rect, src_rect));
- DrawCrossfade(context.Canvas(), flags, kClampImageToSourceRect, kSyncDecode);
+ DrawCrossfade(context.Canvas(), flags, respect_orientation,
+ kClampImageToSourceRect, kSyncDecode);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/crossfade_generated_image.h b/chromium/third_party/blink/renderer/platform/graphics/crossfade_generated_image.h
index 55c37030884..17fb61c5692 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/crossfade_generated_image.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/crossfade_generated_image.h
@@ -59,7 +59,9 @@ class PLATFORM_EXPORT CrossfadeGeneratedImage final : public GeneratedImage {
RespectImageOrientationEnum,
ImageClampingMode,
ImageDecodingMode) override;
- void DrawTile(GraphicsContext&, const FloatRect&) final;
+ void DrawTile(GraphicsContext&,
+ const FloatRect&,
+ RespectImageOrientationEnum) final;
CrossfadeGeneratedImage(scoped_refptr<Image> from_image,
scoped_refptr<Image> to_image,
@@ -70,6 +72,7 @@ class PLATFORM_EXPORT CrossfadeGeneratedImage final : public GeneratedImage {
private:
void DrawCrossfade(cc::PaintCanvas*,
const cc::PaintFlags&,
+ RespectImageOrientationEnum,
ImageClampingMode,
ImageDecodingMode);
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 0c2a478ca67..8b05ce0ff90 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
@@ -13,6 +13,7 @@
#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/skia/include/core/SkColorFilter.h"
#include "third_party/skia/include/effects/SkColorMatrix.h"
@@ -129,7 +130,13 @@ void DarkModeFilter::UpdateSettings(const DarkModeSettings& new_settings) {
Color DarkModeFilter::InvertColorIfNeeded(const Color& color,
ElementRole role) {
- if (IsDarkModeActive() && ShouldApplyToColor(color, role))
+ if (!IsDarkModeActive())
+ return color;
+
+ if (role_override_.has_value())
+ role = role_override_.value();
+
+ if (ShouldApplyToColor(color, role))
return color_filter_->InvertColor(color);
return color;
}
@@ -150,6 +157,9 @@ base::Optional<cc::PaintFlags> DarkModeFilter::ApplyToFlagsIfNeeded(
if (!IsDarkModeActive())
return base::nullopt;
+ if (role_override_.has_value())
+ role = role_override_.value();
+
cc::PaintFlags dark_mode_flags = flags;
if (flags.HasShader()) {
dark_mode_flags.setColorFilter(color_filter_->ToSkColorFilter());
@@ -177,6 +187,13 @@ bool DarkModeFilter::ShouldApplyToColor(const Color& color, ElementRole role) {
DCHECK(text_classifier_);
return text_classifier_->ShouldInvertColor(color) ==
DarkModeClassification::kApplyFilter;
+ case ElementRole::kListSymbol:
+ // TODO(prashant.n): Rename text_classifier_ to foreground_classifier_,
+ // so that same classifier can be used for all roles which are supposed
+ // to be at foreground.
+ DCHECK(text_classifier_);
+ return text_classifier_->ShouldInvertColor(color) ==
+ DarkModeClassification::kApplyFilter;
case ElementRole::kBackground:
DCHECK(background_classifier_);
return background_classifier_->ShouldInvertColor(color) ==
@@ -195,4 +212,18 @@ bool DarkModeFilter::ShouldApplyToColor(const Color& color, ElementRole role) {
NOTREACHED();
}
+ScopedDarkModeElementRoleOverride::ScopedDarkModeElementRoleOverride(
+ GraphicsContext* graphics_context,
+ DarkModeFilter::ElementRole role)
+ : graphics_context_(graphics_context) {
+ DarkModeFilter& dark_mode_filter = graphics_context->dark_mode_filter_;
+ previous_role_override_ = dark_mode_filter.role_override_;
+ dark_mode_filter.role_override_ = role;
+}
+
+ScopedDarkModeElementRoleOverride::~ScopedDarkModeElementRoleOverride() {
+ DarkModeFilter& dark_mode_filter = graphics_context_->dark_mode_filter_;
+ dark_mode_filter.role_override_ = previous_role_override_;
+}
+
} // namespace blink
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 b46d2e35b75..56a926f5f0d 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
@@ -21,6 +21,7 @@ namespace blink {
class DarkModeColorClassifier;
class DarkModeColorFilter;
+class ScopedDarkModeElementRoleOverride;
class PLATFORM_EXPORT DarkModeFilter {
public:
@@ -37,7 +38,7 @@ 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, kBackground, kSVG };
+ enum class ElementRole { kText, kListSymbol, kBackground, kSVG };
Color InvertColorIfNeeded(const Color& color, ElementRole element_role);
base::Optional<cc::PaintFlags> ApplyToFlagsIfNeeded(
const cc::PaintFlags& flags,
@@ -52,6 +53,8 @@ class PLATFORM_EXPORT DarkModeFilter {
SkColorFilter* GetImageFilterForTesting() { return image_filter_.get(); }
private:
+ friend class ScopedDarkModeElementRoleOverride;
+
DarkModeSettings settings_;
bool ShouldApplyToColor(const Color& color, ElementRole role);
@@ -60,6 +63,20 @@ class PLATFORM_EXPORT DarkModeFilter {
std::unique_ptr<DarkModeColorClassifier> background_classifier_;
std::unique_ptr<DarkModeColorFilter> color_filter_;
sk_sp<SkColorFilter> image_filter_;
+ base::Optional<ElementRole> role_override_;
+};
+
+// Temporarily override the element role for the scope of this object's
+// lifetime - for example when drawing symbols that play the role of text.
+class PLATFORM_EXPORT ScopedDarkModeElementRoleOverride {
+ public:
+ ScopedDarkModeElementRoleOverride(GraphicsContext* graphics_context,
+ DarkModeFilter::ElementRole role);
+ ~ScopedDarkModeElementRoleOverride();
+
+ private:
+ GraphicsContext* graphics_context_;
+ base::Optional<DarkModeFilter::ElementRole> previous_role_override_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder.cc b/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder.cc
index da6f2259314..b99ac19e445 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder.cc
@@ -175,15 +175,11 @@ String DeferredImageDecoder::FilenameExtension() const {
: filename_extension_;
}
-sk_sp<PaintImageGenerator> DeferredImageDecoder::CreateGenerator(size_t index) {
+sk_sp<PaintImageGenerator> DeferredImageDecoder::CreateGenerator() {
if (frame_generator_ && frame_generator_->DecodeFailed())
return nullptr;
- PrepareLazyDecodedFrames();
-
- // PrepareLazyDecodedFrames should populate the metadata for each frame in
- // this image and create the |frame_generator_|, if enough data is available.
- if (index >= frame_data_.size())
+ if (invalid_image_ || frame_data_.IsEmpty())
return nullptr;
DCHECK(frame_generator_);
@@ -196,10 +192,16 @@ sk_sp<PaintImageGenerator> DeferredImageDecoder::CreateGenerator(size_t index) {
SegmentReader::CreateFromSkROBuffer(std::move(ro_buffer));
// ImageFrameGenerator has the latest known alpha state. There will be a
- // performance boost if this frame is opaque.
- SkAlphaType alpha_type = frame_generator_->HasAlpha(index)
- ? kPremul_SkAlphaType
- : kOpaque_SkAlphaType;
+ // performance boost if the image is opaque since we can avoid painting
+ // the background in this case.
+ // For multi-frame images, these maybe animated on the compositor thread.
+ // So we can not mark them as opaque unless all frames are opaque.
+ // TODO(khushalsagar): Check whether all frames being added to the
+ // generator are opaque when populating FrameMetadata below.
+ SkAlphaType alpha_type = kPremul_SkAlphaType;
+ if (frame_data_.size() == 1u && !frame_generator_->HasAlpha(0u))
+ alpha_type = kOpaque_SkAlphaType;
+
SkImageInfo info =
SkImageInfo::MakeN32(decoded_size.width(), decoded_size.height(),
alpha_type, color_space_for_sk_images_);
@@ -396,14 +398,19 @@ void DeferredImageDecoder::PrepareLazyDecodedFrames() {
if (!metadata_decoder_ || !metadata_decoder_->IsSizeAvailable())
return;
+ if (invalid_image_)
+ return;
+
if (!image_metadata_)
image_metadata_ = metadata_decoder_->MakeMetadataForDecodeAcceleration();
// If the image contains a coded size with zero in either or both size
// dimensions, the image is invalid.
if (image_metadata_->coded_size.has_value() &&
- image_metadata_->coded_size.value().IsEmpty())
+ image_metadata_->coded_size.value().IsEmpty()) {
+ invalid_image_ = true;
return;
+ }
ActivateLazyDecoding();
@@ -411,12 +418,16 @@ void DeferredImageDecoder::PrepareLazyDecodedFrames() {
frame_data_.resize(metadata_decoder_->FrameCount());
// The decoder may be invalidated during a FrameCount(). Simply bail if so.
- if (metadata_decoder_->Failed())
+ if (metadata_decoder_->Failed()) {
+ invalid_image_ = true;
return;
+ }
// We have encountered a broken image file. Simply bail.
- if (frame_data_.size() < previous_size)
+ if (frame_data_.size() < previous_size) {
+ invalid_image_ = true;
return;
+ }
for (size_t i = previous_size; i < frame_data_.size(); ++i) {
frame_data_[i].duration_ = metadata_decoder_->FrameDurationAtIndex(i);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder.h b/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder.h
index d7a069b0590..76a5fa15af1 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder.h
@@ -62,7 +62,7 @@ class PLATFORM_EXPORT DeferredImageDecoder final {
String FilenameExtension() const;
- sk_sp<PaintImageGenerator> CreateGenerator(size_t index);
+ sk_sp<PaintImageGenerator> CreateGenerator();
scoped_refptr<SharedBuffer> Data();
void SetData(scoped_refptr<SharedBuffer> data, bool all_data_received);
@@ -120,6 +120,10 @@ class PLATFORM_EXPORT DeferredImageDecoder final {
const PaintImage::ContentId complete_frame_content_id_;
base::Optional<bool> incremental_decode_needed_;
+ // Set to true if the image is detected to be invalid after parsing the
+ // metadata.
+ bool invalid_image_ = false;
+
// Caches an image's metadata so it can outlive |metadata_decoder_| after all
// data is received in cases where multiple generators are created.
base::Optional<cc::ImageHeaderMetadata> image_metadata_;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test.cc b/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test.cc
index d515c956a31..7e81cb95bc4 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder_test.cc
@@ -131,8 +131,7 @@ class DeferredImageDecoderTest : public testing::Test,
.set_id(paint_image_id_)
.set_animation_type(type)
.set_completion_state(state)
- .set_paint_image_generator(
- decoder->CreateGenerator(PaintImage::kDefaultFrameIndex))
+ .set_paint_image_generator(decoder->CreateGenerator())
.TakePaintImage();
}
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 2283a6378e3..a8cc839fa98 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
@@ -19,7 +19,7 @@ namespace {
sk_sp<SkImage> CreateFrameAtIndex(DeferredImageDecoder* decoder, size_t index) {
return SkImage::MakeFromGenerator(std::make_unique<SkiaPaintImageGenerator>(
- decoder->CreateGenerator(index), index,
+ decoder->CreateGenerator(), index,
cc::PaintImage::kDefaultGeneratorClientId));
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.cc
index ce5709eb94f..aa24b6a28ab 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.cc
@@ -34,8 +34,8 @@ static const unsigned kColorMatrixSize = 20;
FEColorMatrix::FEColorMatrix(Filter* filter,
ColorMatrixType type,
- const Vector<float>& values)
- : FilterEffect(filter), type_(type), values_(values) {}
+ Vector<float> values)
+ : FilterEffect(filter), type_(type), values_(std::move(values)) {}
ColorMatrixType FEColorMatrix::GetType() const {
return type_;
@@ -52,10 +52,10 @@ const Vector<float>& FEColorMatrix::Values() const {
return values_;
}
-bool FEColorMatrix::SetValues(const Vector<float>& values) {
+bool FEColorMatrix::SetValues(Vector<float> values) {
if (values_ == values)
return false;
- values_ = values;
+ values_ = std::move(values);
return true;
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.h b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.h
index 1621b60ea8c..76c9ffc155b 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.h
@@ -38,22 +38,17 @@ enum ColorMatrixType {
class PLATFORM_EXPORT FEColorMatrix final : public FilterEffect {
public:
- FEColorMatrix(Filter*, ColorMatrixType, const Vector<float>&);
+ FEColorMatrix(Filter*, ColorMatrixType, Vector<float>);
ColorMatrixType GetType() const;
bool SetType(ColorMatrixType);
const Vector<float>& Values() const;
- bool SetValues(const Vector<float>&);
+ bool SetValues(Vector<float>);
WTF::TextStream& ExternalRepresentation(WTF::TextStream&,
int indention) const override;
- static inline void CalculateSaturateComponents(float* components,
- float value);
- static inline void CalculateHueRotateComponents(float* components,
- float value);
-
private:
sk_sp<PaintFilter> CreateImageFilter() override;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_tile.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_tile.cc
index 8ea49549dc5..b2bff044da0 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_tile.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_tile.cc
@@ -34,18 +34,21 @@ FloatRect FETile::MapInputs(const FloatRect& rect) const {
return AbsoluteBounds();
}
+FloatRect FETile::GetSourceRect() const {
+ const FilterEffect* input = InputEffect(0);
+ if (input->GetFilterEffectType() == kFilterEffectTypeSourceInput)
+ return GetFilter()->FilterRegion();
+ return input->FilterPrimitiveSubregion();
+}
+
sk_sp<PaintFilter> FETile::CreateImageFilter() {
sk_sp<PaintFilter> input(paint_filter_builder::Build(
InputEffect(0), OperatingInterpolationSpace()));
if (!input)
return nullptr;
-
- FloatRect src_rect;
- if (InputEffect(0)->GetFilterEffectType() == kFilterEffectTypeSourceInput)
- src_rect = GetFilter()->FilterRegion();
- else
- src_rect = InputEffect(0)->FilterPrimitiveSubregion();
- FloatRect dst_rect = FilterPrimitiveSubregion();
+ FloatRect src_rect = GetFilter()->MapLocalRectToAbsoluteRect(GetSourceRect());
+ FloatRect dst_rect =
+ GetFilter()->MapLocalRectToAbsoluteRect(FilterPrimitiveSubregion());
return sk_make_sp<TilePaintFilter>(src_rect, dst_rect, std::move(input));
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_tile.h b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_tile.h
index b20b4bfb99e..95732d35988 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_tile.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_tile.h
@@ -40,6 +40,7 @@ class PLATFORM_EXPORT FETile final : public FilterEffect {
}
FloatRect MapInputs(const FloatRect&) const final;
+ FloatRect GetSourceRect() const;
sk_sp<PaintFilter> CreateImageFilter() override;
};
diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_turbulence.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_turbulence.cc
index df7735c1182..488aa17c8bb 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_turbulence.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_turbulence.cc
@@ -131,10 +131,14 @@ sk_sp<PaintFilter> FETurbulence::CreateImageFilter() {
// a frequency, not a period.
float base_frequency_x = base_frequency_x_ / GetFilter()->Scale();
float base_frequency_y = base_frequency_y_ / GetFilter()->Scale();
+
+ // Cap the number of octaves to the maximum detectable when rendered with
+ // 8 bits per pixel, plus one for higher bit depth.
+ int capped_num_octaves = std::min(NumOctaves(), 9);
return sk_make_sp<TurbulencePaintFilter>(
type, SkFloatToScalar(base_frequency_x),
- SkFloatToScalar(base_frequency_y), NumOctaves(), SkFloatToScalar(Seed()),
- StitchTiles() ? &size : nullptr, &rect);
+ SkFloatToScalar(base_frequency_y), capped_num_octaves,
+ SkFloatToScalar(Seed()), StitchTiles() ? &size : nullptr, &rect);
}
static WTF::TextStream& operator<<(WTF::TextStream& ts,
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 515d6d72cb2..c1ae00d3ba2 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(blink::Visitor* visitor) {
+void Filter::Trace(Visitor* visitor) {
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 d5073d5c854..efd30aa6721 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(blink::Visitor*);
+ void Trace(Visitor*);
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 513efef32de..1b8dd7a802e 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(blink::Visitor* visitor) {
+void FilterEffect::Trace(Visitor* visitor) {
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 cec2f5c1208..1f3e99d19fe 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(blink::Visitor*);
+ virtual void Trace(Visitor*);
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 6efb7a02915..666cc1d5925 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/generated_image.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/generated_image.cc
@@ -38,13 +38,15 @@
namespace blink {
-void GeneratedImage::DrawPattern(GraphicsContext& dest_context,
- const FloatRect& src_rect,
- const FloatSize& scale,
- const FloatPoint& phase,
- SkBlendMode composite_op,
- const FloatRect& dest_rect,
- const FloatSize& repeat_spacing) {
+void GeneratedImage::DrawPattern(
+ GraphicsContext& dest_context,
+ const FloatRect& src_rect,
+ const FloatSize& scale,
+ const FloatPoint& phase,
+ SkBlendMode composite_op,
+ const FloatRect& dest_rect,
+ const FloatSize& repeat_spacing,
+ RespectImageOrientationEnum respect_orientation) {
FloatRect tile_rect = src_rect;
tile_rect.Expand(repeat_spacing);
@@ -53,7 +55,7 @@ void GeneratedImage::DrawPattern(GraphicsContext& dest_context,
pattern_matrix.preTranslate(tile_rect.X(), tile_rect.Y());
sk_sp<PaintShader> tile_shader =
- CreateShader(tile_rect, &pattern_matrix, src_rect);
+ CreateShader(tile_rect, &pattern_matrix, src_rect, respect_orientation);
PaintFlags fill_flags = dest_context.FillFlags();
fill_flags.setShader(std::move(tile_shader));
@@ -63,13 +65,15 @@ void GeneratedImage::DrawPattern(GraphicsContext& dest_context,
dest_context.DrawRect(dest_rect, fill_flags);
}
-sk_sp<PaintShader> GeneratedImage::CreateShader(const FloatRect& tile_rect,
- const SkMatrix* pattern_matrix,
- const FloatRect& src_rect) {
+sk_sp<PaintShader> GeneratedImage::CreateShader(
+ const FloatRect& tile_rect,
+ const SkMatrix* pattern_matrix,
+ const FloatRect& src_rect,
+ RespectImageOrientationEnum respect_orientation) {
auto paint_controller = std::make_unique<PaintController>();
GraphicsContext context(*paint_controller);
context.BeginRecording(tile_rect);
- DrawTile(context, src_rect);
+ DrawTile(context, src_rect, respect_orientation);
sk_sp<PaintRecord> record = context.EndRecording();
return PaintShader::MakePaintRecord(std::move(record), tile_rect,
diff --git a/chromium/third_party/blink/renderer/platform/graphics/generated_image.h b/chromium/third_party/blink/renderer/platform/graphics/generated_image.h
index 21d225cf0cc..fd645ff5e07 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/generated_image.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/generated_image.h
@@ -39,6 +39,9 @@ class PLATFORM_EXPORT GeneratedImage : public Image {
bool HasIntrinsicSize() const override { return false; }
IntSize Size() const override { return RoundedIntSize(size_); }
+ FloatSize SizeAsFloat(RespectImageOrientationEnum) const override {
+ return size_;
+ }
// Assume that generated content has no decoded data we need to worry about
void DestroyDecodedData() override {}
@@ -52,17 +55,21 @@ class PLATFORM_EXPORT GeneratedImage : public Image {
const FloatPoint&,
SkBlendMode,
const FloatRect&,
- const FloatSize& repeat_spacing) final;
+ const FloatSize& repeat_spacing,
+ RespectImageOrientationEnum) final;
virtual sk_sp<cc::PaintShader> CreateShader(const FloatRect& tile_rect,
const SkMatrix* pattern_matrix,
- const FloatRect& src_rect);
+ const FloatRect& src_rect,
+ RespectImageOrientationEnum);
// FIXME: Implement this to be less conservative.
bool CurrentFrameKnownToBeOpaque() override { return false; }
GeneratedImage(const FloatSize& size) : size_(size) {}
- virtual void DrawTile(GraphicsContext&, const FloatRect&) = 0;
+ virtual void DrawTile(GraphicsContext&,
+ const FloatRect&,
+ RespectImageOrientationEnum) = 0;
FloatSize size_;
};
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/DEPS b/chromium/third_party/blink/renderer/platform/graphics/gpu/DEPS
index aa252c3bb21..3238ca1d6d7 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/DEPS
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/DEPS
@@ -1,6 +1,5 @@
include_rules = [
"+components/viz/test/test_context_provider.h",
- "+mojo/public/cpp/bindings/binding.h",
"+mojo/public/cpp/system/platform_handle.h",
"+device/vr/public/mojom/vr_service.mojom-blink.h",
"+gpu/command_buffer/client/gles2_interface.h",
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 261c1b0512d..ee8aba554c6 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
@@ -41,8 +41,6 @@
#include "components/viz/common/resources/bitmap_allocation.h"
#include "components/viz/common/resources/shared_bitmap.h"
#include "components/viz/common/resources/transferable_resource.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
#include "gpu/command_buffer/client/shared_image_interface.h"
#include "gpu/command_buffer/common/capabilities.h"
@@ -54,6 +52,7 @@
#include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/canvas_resource.h"
#include "third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h"
+#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h"
@@ -64,7 +63,6 @@
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/GrContext.h"
#include "third_party/skia/include/gpu/gl/GrGLTypes.h"
-#include "ui/gl/gpu_preference.h"
#include "v8/include/v8.h"
namespace blink {
@@ -193,7 +191,8 @@ DrawingBuffer::DrawingBuffer(
opengl_flip_y_extension_(
ContextProvider()->GetCapabilities().mesa_framebuffer_flip_y),
initial_gpu_(gpu_preference),
- current_active_gpu_(gpu_preference) {
+ current_active_gpu_(gpu_preference),
+ weak_factory_(this) {
// Used by browser tests to detect the use of a DrawingBuffer.
TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation",
TRACE_EVENT_SCOPE_GLOBAL);
@@ -393,11 +392,12 @@ bool DrawingBuffer::FinishPrepareTransferableResourceSoftware(
// This holds a ref on the DrawingBuffer that will keep it alive until the
// mailbox is released (and while the release callback is running). It also
// owns the SharedBitmap.
- auto func = WTF::Bind(&DrawingBuffer::MailboxReleasedSoftware,
- scoped_refptr<DrawingBuffer>(this),
- WTF::Passed(std::move(registered)));
+ auto func = base::BindOnce(&DrawingBuffer::MailboxReleasedSoftware,
+ weak_factory_.GetWeakPtr(),
+ WTF::Passed(std::move(registered)));
*out_release_callback = viz::SingleReleaseCallback::Create(std::move(func));
+ contents_changed_ = false;
ResetBuffersToAutoClear();
return true;
}
@@ -504,9 +504,8 @@ bool DrawingBuffer::FinishPrepareTransferableResourceGpu(
// This holds a ref on the DrawingBuffer that will keep it alive until the
// mailbox is released (and while the release callback is running).
- auto func =
- WTF::Bind(&DrawingBuffer::MailboxReleasedGpu,
- scoped_refptr<DrawingBuffer>(this), color_buffer_for_mailbox);
+ auto func = base::BindOnce(&DrawingBuffer::NotifyMailboxReleasedGpu,
+ color_buffer_for_mailbox);
*out_release_callback = viz::SingleReleaseCallback::Create(std::move(func));
}
@@ -518,18 +517,29 @@ bool DrawingBuffer::FinishPrepareTransferableResourceGpu(
return true;
}
+// static
+void DrawingBuffer::NotifyMailboxReleasedGpu(
+ scoped_refptr<ColorBuffer> color_buffer,
+ const gpu::SyncToken& sync_token,
+ bool lost_resource) {
+ DCHECK(color_buffer->owning_thread_ref == base::PlatformThread::CurrentRef());
+
+ // Update the SyncToken to ensure that we will wait for it even if we
+ // immediately destroy this buffer.
+ color_buffer->receive_sync_token = sync_token;
+ if (color_buffer->drawing_buffer) {
+ color_buffer->drawing_buffer->MailboxReleasedGpu(color_buffer,
+ lost_resource);
+ }
+}
+
void DrawingBuffer::MailboxReleasedGpu(scoped_refptr<ColorBuffer> color_buffer,
- const gpu::SyncToken& sync_token,
bool lost_resource) {
// If the mailbox has been returned by the compositor then it is no
// longer being presented, and so is no longer the front buffer.
if (color_buffer == front_color_buffer_)
front_color_buffer_ = nullptr;
- // Update the SyncToken to ensure that we will wait for it even if we
- // immediately destroy this buffer.
- color_buffer->receive_sync_token = sync_token;
-
if (destruction_in_progress_ || color_buffer->size != size_ ||
gl_->GetGraphicsResetStatusKHR() != GL_NO_ERROR || lost_resource ||
is_hidden_) {
@@ -561,8 +571,7 @@ void DrawingBuffer::MailboxReleasedSoftware(RegisteredBitmap registered,
recycled_bitmaps_.push_back(std::move(registered));
}
-scoped_refptr<StaticBitmapImage> DrawingBuffer::TransferToStaticBitmapImage(
- std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback) {
+scoped_refptr<StaticBitmapImage> DrawingBuffer::TransferToStaticBitmapImage() {
ScopedStateRestorer scoped_state_restorer(this);
viz::TransferableResource transferable_resource;
@@ -583,35 +592,10 @@ scoped_refptr<StaticBitmapImage> DrawingBuffer::TransferToStaticBitmapImage(
SkImage::MakeFromBitmap(black_bitmap));
}
+ DCHECK(release_callback);
DCHECK_EQ(size_.Width(), transferable_resource.size.width());
DCHECK_EQ(size_.Height(), transferable_resource.size.height());
- // Make our own textureId that is a reference on the same texture backing
- // being used as the front buffer (which was returned from
- // PrepareTransferableResourceInternal()). We do not need to wait on the sync
- // token in |transferable_resource| since the mailbox was produced on the same
- // |m_gl| context that we are using here. Similarly, the |release_callback|
- // will run on the same context so we don't need to send a sync token for this
- // consume action back to it.
- // TODO(danakj): Instead of using PrepareTransferableResourceInternal(), we
- // could just use the actual texture id and avoid needing to produce/consume a
- // mailbox.
- GLuint texture_id = gl_->CreateAndTexStorage2DSharedImageCHROMIUM(
- transferable_resource.mailbox_holder.mailbox.name);
-
- if (out_release_callback) {
- // Allow the consumer to release the resource when done using it, so it can
- // be recycled.
- *out_release_callback = std::move(release_callback);
- } else {
- // Return the mailbox but report that the resource is lost to prevent trying
- // to use the backing for future frames. We keep it alive with our own
- // reference to the backing via our |textureId|.
- gpu::SyncToken sync_token;
- gl_->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData());
- release_callback->Run(sync_token, true /* lost_resource */);
- }
-
// We reuse the same mailbox name from above since our texture id was consumed
// from it.
const auto& sk_image_mailbox = transferable_resource.mailbox_holder.mailbox;
@@ -623,12 +607,18 @@ scoped_refptr<StaticBitmapImage> DrawingBuffer::TransferToStaticBitmapImage(
const auto& sk_image_sync_token =
transferable_resource.mailbox_holder.sync_token;
+ const SkImageInfo sk_image_info =
+ SkImageInfo::MakeN32Premul(size_.Width(), size_.Height());
+
// TODO(xidachen): Create a small pool of recycled textures from
// ImageBitmapRenderingContext's transferFromImageBitmap, and try to use them
// in DrawingBuffer.
- return AcceleratedStaticBitmapImage::CreateFromWebGLContextImage(
- sk_image_mailbox, sk_image_sync_token, texture_id,
- context_provider_->GetWeakPtr(), size_, opengl_flip_y_extension_);
+ return AcceleratedStaticBitmapImage::CreateFromCanvasMailbox(
+ sk_image_mailbox, sk_image_sync_token, /* shared_image_texture_id = */ 0,
+ sk_image_info, transferable_resource.mailbox_holder.texture_target,
+ /* is_origin_top_left = */ opengl_flip_y_extension_,
+ context_provider_->GetWeakPtr(), base::PlatformThread::CurrentRef(),
+ Thread::Current()->GetTaskRunner(), std::move(release_callback));
}
scoped_refptr<DrawingBuffer::ColorBuffer>
@@ -678,18 +668,29 @@ scoped_refptr<CanvasResource> DrawingBuffer::AsCanvasResource(
}
DrawingBuffer::ColorBuffer::ColorBuffer(
- DrawingBuffer* drawing_buffer,
+ base::WeakPtr<DrawingBuffer> drawing_buffer,
const IntSize& size,
GLuint texture_id,
std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer,
gpu::Mailbox mailbox)
- : drawing_buffer(drawing_buffer),
+ : owning_thread_ref(base::PlatformThread::CurrentRef()),
+ drawing_buffer(std::move(drawing_buffer)),
size(size),
texture_id(texture_id),
gpu_memory_buffer(std::move(gpu_memory_buffer)),
mailbox(mailbox) {}
DrawingBuffer::ColorBuffer::~ColorBuffer() {
+ if (base::PlatformThread::CurrentRef() != owning_thread_ref ||
+ !drawing_buffer) {
+ // If the context has been destroyed no cleanup is necessary since all
+ // resources below are automatically destroyed. Note that if a ColorBuffer
+ // is being destroyed on a different thread, it implies that the owning
+ // thread was destroyed which means the associated context was also
+ // destroyed.
+ return;
+ }
+
gpu::gles2::GLES2Interface* gl = drawing_buffer->gl_;
gpu::SharedImageInterface* sii =
drawing_buffer->ContextProvider()->SharedImageInterface();
@@ -777,7 +778,7 @@ bool DrawingBuffer::Initialize(const IntSize& size, bool use_multisampling) {
if (ShouldUseChromiumImage()) {
// A CHROMIUM_image backed texture requires a specialized set of parameters
// on OSX.
- texture_target_ = GC3D_TEXTURE_RECTANGLE_ARB;
+ texture_target_ = gpu::GetPlatformSpecificTextureTarget();
}
#endif
@@ -850,15 +851,10 @@ bool DrawingBuffer::Initialize(const IntSize& size, bool use_multisampling) {
return true;
}
-bool DrawingBuffer::CopyToPlatformTexture(gpu::gles2::GLES2Interface* dst_gl,
- GLenum dst_texture_target,
- GLuint dst_texture,
- GLint dst_level,
- bool premultiply_alpha,
- bool flip_y,
- const IntPoint& dst_texture_offset,
- const IntRect& src_sub_rectangle,
- SourceDrawingBuffer src_buffer) {
+template <typename CopyFunction>
+bool DrawingBuffer::CopyToPlatformInternal(gpu::InterfaceBase* dst_interface,
+ SourceDrawingBuffer src_buffer,
+ const CopyFunction& copy_function) {
ScopedStateRestorer scoped_state_restorer(this);
gpu::gles2::GLES2Interface* src_gl = gl_;
@@ -868,9 +864,6 @@ bool DrawingBuffer::CopyToPlatformTexture(gpu::gles2::GLES2Interface* dst_gl,
src_gl->Flush();
}
- if (!Extensions3DUtil::CanUseCopyTextureCHROMIUM(dst_texture_target))
- return false;
-
// Contexts may be in a different share group. We must transfer the texture
// through a mailbox first.
gpu::Mailbox mailbox;
@@ -899,31 +892,12 @@ bool DrawingBuffer::CopyToPlatformTexture(gpu::gles2::GLES2Interface* dst_gl,
return false;
}
- dst_gl->WaitSyncTokenCHROMIUM(produce_sync_token.GetConstData());
-
- GLuint src_texture =
- dst_gl->CreateAndTexStorage2DSharedImageCHROMIUM(mailbox.name);
-
- GLboolean unpack_premultiply_alpha_needed = GL_FALSE;
- GLboolean unpack_unpremultiply_alpha_needed = GL_FALSE;
- if (want_alpha_channel_ && premultiplied_alpha_ && !premultiply_alpha)
- unpack_unpremultiply_alpha_needed = GL_TRUE;
- else if (want_alpha_channel_ && !premultiplied_alpha_ && premultiply_alpha)
- unpack_premultiply_alpha_needed = GL_TRUE;
+ dst_interface->WaitSyncTokenCHROMIUM(produce_sync_token.GetConstData());
- dst_gl->BeginSharedImageAccessDirectCHROMIUM(
- src_texture, GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM);
- dst_gl->CopySubTextureCHROMIUM(
- src_texture, 0, dst_texture_target, dst_texture, dst_level,
- dst_texture_offset.X(), dst_texture_offset.Y(), src_sub_rectangle.X(),
- src_sub_rectangle.Y(), src_sub_rectangle.Width(),
- src_sub_rectangle.Height(), flip_y, unpack_premultiply_alpha_needed,
- unpack_unpremultiply_alpha_needed);
- dst_gl->EndSharedImageAccessDirectCHROMIUM(src_texture);
- dst_gl->DeleteTextures(1, &src_texture);
+ copy_function(mailbox);
gpu::SyncToken sync_token;
- dst_gl->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData());
+ dst_interface->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData());
src_gl->WaitSyncTokenCHROMIUM(sync_token.GetData());
if (texture_id_to_restore_access) {
src_gl->BeginSharedImageAccessDirectCHROMIUM(
@@ -933,6 +907,66 @@ bool DrawingBuffer::CopyToPlatformTexture(gpu::gles2::GLES2Interface* dst_gl,
return true;
}
+bool DrawingBuffer::CopyToPlatformTexture(gpu::gles2::GLES2Interface* dst_gl,
+ GLenum dst_texture_target,
+ GLuint dst_texture,
+ GLint dst_level,
+ bool premultiply_alpha,
+ bool flip_y,
+ const IntPoint& dst_texture_offset,
+ const IntRect& src_sub_rectangle,
+ SourceDrawingBuffer src_buffer) {
+ if (!Extensions3DUtil::CanUseCopyTextureCHROMIUM(dst_texture_target))
+ return false;
+
+ GLboolean unpack_premultiply_alpha_needed = GL_FALSE;
+ GLboolean unpack_unpremultiply_alpha_needed = GL_FALSE;
+ if (want_alpha_channel_ && premultiplied_alpha_ && !premultiply_alpha)
+ unpack_unpremultiply_alpha_needed = GL_TRUE;
+ else if (want_alpha_channel_ && !premultiplied_alpha_ && premultiply_alpha)
+ unpack_premultiply_alpha_needed = GL_TRUE;
+
+ auto copy_function = [&](gpu::Mailbox src_mailbox) {
+ GLuint src_texture =
+ dst_gl->CreateAndTexStorage2DSharedImageCHROMIUM(src_mailbox.name);
+ dst_gl->BeginSharedImageAccessDirectCHROMIUM(
+ src_texture, GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM);
+ dst_gl->CopySubTextureCHROMIUM(
+ src_texture, 0, dst_texture_target, dst_texture, dst_level,
+ dst_texture_offset.X(), dst_texture_offset.Y(), src_sub_rectangle.X(),
+ src_sub_rectangle.Y(), src_sub_rectangle.Width(),
+ src_sub_rectangle.Height(), flip_y, unpack_premultiply_alpha_needed,
+ unpack_unpremultiply_alpha_needed);
+ dst_gl->EndSharedImageAccessDirectCHROMIUM(src_texture);
+ dst_gl->DeleteTextures(1, &src_texture);
+ };
+ return CopyToPlatformInternal(dst_gl, src_buffer, copy_function);
+}
+
+bool DrawingBuffer::CopyToPlatformMailbox(
+ gpu::raster::RasterInterface* dst_raster_interface,
+ gpu::Mailbox dst_mailbox,
+ GLenum dst_texture_target,
+ bool flip_y,
+ const IntPoint& dst_texture_offset,
+ const IntRect& src_sub_rectangle,
+ SourceDrawingBuffer src_buffer) {
+ GLboolean unpack_premultiply_alpha_needed = GL_FALSE;
+ if (want_alpha_channel_ && !premultiplied_alpha_)
+ unpack_premultiply_alpha_needed = GL_TRUE;
+
+ auto copy_function = [&](gpu::Mailbox src_mailbox) {
+ dst_raster_interface->CopySubTexture(
+ src_mailbox, dst_mailbox, dst_texture_target, dst_texture_offset.X(),
+ dst_texture_offset.Y(), src_sub_rectangle.X(), src_sub_rectangle.Y(),
+ src_sub_rectangle.Width(), src_sub_rectangle.Height(), flip_y,
+ unpack_premultiply_alpha_needed);
+ };
+
+ return CopyToPlatformInternal(dst_raster_interface, src_buffer,
+ copy_function);
+}
+
cc::Layer* DrawingBuffer::CcLayer() {
if (!layer_) {
layer_ = cc::TextureLayer::CreateForMailbox(this);
@@ -957,8 +991,6 @@ cc::Layer* DrawingBuffer::CcLayer() {
if (opengl_flip_y_extension_)
layer_->SetFlipped(false);
-
- GraphicsLayer::RegisterContentsLayer(layer_.get());
}
return layer_.get();
@@ -1012,9 +1044,6 @@ void DrawingBuffer::BeginDestruction() {
multisample_fbo_ = 0;
fbo_ = 0;
- if (layer_)
- GraphicsLayer::UnregisterContentsLayer(layer_.get());
-
client_ = nullptr;
}
@@ -1052,7 +1081,8 @@ bool DrawingBuffer::ResizeDefaultFramebuffer(const IntSize& size) {
premultiplied_alpha_false_mailbox_ = sii->CreateSharedImage(
format, static_cast<gfx::Size>(size), storage_color_space_,
gpu::SHARED_IMAGE_USAGE_GLES2 |
- gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT);
+ gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT |
+ gpu::SHARED_IMAGE_USAGE_RASTER);
gpu::SyncToken sync_token = sii->GenUnverifiedSyncToken();
gl_->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
premultiplied_alpha_false_texture_ =
@@ -1618,8 +1648,9 @@ scoped_refptr<DrawingBuffer::ColorBuffer> DrawingBuffer::CreateColorBuffer(
// Import frontbuffer of swap chain into GL.
texture_id = gl_->CreateAndTexStorage2DSharedImageCHROMIUM(
front_buffer_mailbox.name);
- front_color_buffer_ = base::AdoptRef(
- new ColorBuffer(this, size, texture_id, nullptr, front_buffer_mailbox));
+ front_color_buffer_ = base::MakeRefCounted<ColorBuffer>(
+ weak_factory_.GetWeakPtr(), size, texture_id, nullptr,
+ front_buffer_mailbox);
}
// Import the backbuffer of swap chain or allocated SharedImage into GL.
texture_id =
@@ -1646,9 +1677,9 @@ scoped_refptr<DrawingBuffer::ColorBuffer> DrawingBuffer::CreateColorBuffer(
gl_->DeleteFramebuffers(1, &fbo);
}
- return base::AdoptRef(new ColorBuffer(this, size, texture_id,
- std::move(gpu_memory_buffer),
- back_buffer_mailbox));
+ return base::MakeRefCounted<ColorBuffer>(
+ weak_factory_.GetWeakPtr(), size, texture_id,
+ std::move(gpu_memory_buffer), back_buffer_mailbox);
}
void DrawingBuffer::AttachColorBufferToReadFramebuffer() {
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 c4f0e99a8a9..9ac03f51f68 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
@@ -37,6 +37,9 @@
#include "cc/layers/texture_layer_client.h"
#include "cc/resources/cross_thread_shared_bitmap.h"
#include "cc/resources/shared_bitmap_id_registrar.h"
+#include "gpu/GLES2/gl2extchromium.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/command_buffer/client/raster_interface.h"
#include "gpu/command_buffer/common/mailbox.h"
#include "gpu/command_buffer/common/sync_token.h"
#include "gpu/config/gpu_feature_info.h"
@@ -225,10 +228,7 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
// contents of the front buffer. This is done without any pixel copies. The
// texture in the ImageBitmap is from the active ContextProvider on the
// DrawingBuffer.
- // If out_release_callback is null, the image is discarded. If it is non-null
- // the image must be recycled or discarded by calling *out_release_callback.
- scoped_refptr<StaticBitmapImage> TransferToStaticBitmapImage(
- std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback);
+ scoped_refptr<StaticBitmapImage> TransferToStaticBitmapImage();
bool CopyToPlatformTexture(gpu::gles2::GLES2Interface*,
GLenum dst_target,
@@ -240,6 +240,14 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
const IntRect& src_sub_rectangle,
SourceDrawingBuffer);
+ bool CopyToPlatformMailbox(gpu::raster::RasterInterface*,
+ gpu::Mailbox dst_mailbox,
+ GLenum dst_texture_target,
+ bool flip_y,
+ const IntPoint& dst_texture_offset,
+ const IntRect& src_sub_rectangle,
+ SourceDrawingBuffer src_buffer);
+
sk_sp<SkData> PaintRenderingResultsToDataArray(SourceDrawingBuffer);
int SampleCount() const { return sample_count_; }
@@ -345,18 +353,22 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
bool pixel_pack_buffer_binding_dirty_ = false;
};
- struct ColorBuffer : public RefCounted<ColorBuffer> {
- ColorBuffer(DrawingBuffer*,
+ struct ColorBuffer : public base::RefCountedThreadSafe<ColorBuffer> {
+ ColorBuffer(base::WeakPtr<DrawingBuffer> drawing_buffer,
const IntSize&,
GLuint texture_id,
std::unique_ptr<gfx::GpuMemoryBuffer>,
gpu::Mailbox mailbox);
~ColorBuffer();
+ // The thread on which the ColorBuffer is created and the DrawingBuffer is
+ // bound to.
+ const base::PlatformThreadRef owning_thread_ref;
+
// The owning DrawingBuffer. Note that DrawingBuffer is explicitly destroyed
// by the beginDestruction method, which will eventually drain all of its
// ColorBuffers.
- scoped_refptr<DrawingBuffer> drawing_buffer;
+ base::WeakPtr<DrawingBuffer> drawing_buffer;
const IntSize size;
const GLuint texture_id = 0;
std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer;
@@ -385,6 +397,11 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
DISALLOW_COPY_AND_ASSIGN(ColorBuffer);
};
+ template <typename CopyFunction>
+ bool CopyToPlatformInternal(gpu::InterfaceBase* dst_interface,
+ SourceDrawingBuffer src_buffer,
+ const CopyFunction& copy_function);
+
enum ClearOption { ClearOnlyMultisampledFBO, ClearAllFBOs };
// Clears out newly-allocated framebuffers (really, renderbuffers / textures).
@@ -420,8 +437,10 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
// Callbacks for mailboxes given to the compositor from
// FinishPrepareTransferableResource{Gpu,Software}.
+ static void NotifyMailboxReleasedGpu(scoped_refptr<ColorBuffer>,
+ const gpu::SyncToken&,
+ bool lost_resource);
void MailboxReleasedGpu(scoped_refptr<ColorBuffer>,
- const gpu::SyncToken&,
bool lost_resource);
void MailboxReleasedSoftware(RegisteredBitmap,
const gpu::SyncToken&,
@@ -617,9 +636,11 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
bool opengl_flip_y_extension_;
- gl::GpuPreference initial_gpu_;
+ const gl::GpuPreference initial_gpu_;
gl::GpuPreference current_active_gpu_;
+ base::WeakPtrFactory<DrawingBuffer> weak_factory_;
+
DISALLOW_COPY_AND_ASSIGN(DrawingBuffer);
};
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 19d15ce32c4..537c1af0001 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
@@ -203,9 +203,8 @@ TEST_F(DrawingBufferTest, VerifyResizingProperlyAffectsResources) {
drawing_buffer_->BeginDestruction();
}
-TEST_F(DrawingBufferTest, VerifyDestructionCompleteAfterAllResourceReleased) {
- bool live = true;
- drawing_buffer_->live_ = &live;
+TEST_F(DrawingBufferTest, VerifySharedImagesReleasedAfterReleaseCallback) {
+ auto* sii = drawing_buffer_->SharedImageInterfaceForTests();
viz::TransferableResource resource1;
std::unique_ptr<viz::SingleReleaseCallback> release_callback1;
@@ -231,67 +230,20 @@ TEST_F(DrawingBufferTest, VerifyDestructionCompleteAfterAllResourceReleased) {
EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(nullptr, &resource3,
&release_callback3));
- EXPECT_TRUE(drawing_buffer_->MarkContentsChanged());
- release_callback1->Run(gpu::SyncToken(), false /* lostResource */);
-
- drawing_buffer_->BeginDestruction();
- ASSERT_EQ(live, true);
-
- DrawingBufferForTests* raw_pointer = drawing_buffer_.get();
- drawing_buffer_ = nullptr;
- ASSERT_EQ(live, true);
-
- EXPECT_FALSE(raw_pointer->MarkContentsChanged());
- release_callback2->Run(gpu::SyncToken(), false /* lostResource */);
- ASSERT_EQ(live, true);
-
- EXPECT_FALSE(raw_pointer->MarkContentsChanged());
- release_callback3->Run(gpu::SyncToken(), false /* lostResource */);
- ASSERT_EQ(live, false);
-}
-
-TEST_F(DrawingBufferTest, verifyDrawingBufferStaysAliveIfResourcesAreLost) {
- bool live = true;
- drawing_buffer_->live_ = &live;
-
- 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;
-
- EXPECT_FALSE(drawing_buffer_->MarkContentsChanged());
- EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(nullptr, &resource1,
- &release_callback1));
- VerifyStateWasRestored();
- EXPECT_TRUE(drawing_buffer_->MarkContentsChanged());
- EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(nullptr, &resource2,
- &release_callback2));
- VerifyStateWasRestored();
- EXPECT_TRUE(drawing_buffer_->MarkContentsChanged());
- EXPECT_TRUE(drawing_buffer_->PrepareTransferableResource(nullptr, &resource3,
- &release_callback3));
- VerifyStateWasRestored();
+ EXPECT_EQ(sii->shared_image_count(), 4u);
EXPECT_TRUE(drawing_buffer_->MarkContentsChanged());
release_callback1->Run(gpu::SyncToken(), true /* lostResource */);
- EXPECT_EQ(live, true);
+ EXPECT_EQ(sii->shared_image_count(), 3u);
- drawing_buffer_->BeginDestruction();
- EXPECT_EQ(live, true);
+ release_callback2->Run(gpu::SyncToken(), true /* lostResource */);
+ EXPECT_EQ(sii->shared_image_count(), 2u);
- EXPECT_FALSE(drawing_buffer_->MarkContentsChanged());
- release_callback2->Run(gpu::SyncToken(), false /* lostResource */);
- EXPECT_EQ(live, true);
-
- DrawingBufferForTests* raw_ptr = drawing_buffer_.get();
- drawing_buffer_ = nullptr;
- EXPECT_EQ(live, true);
+ // The resource is not marked lost so it's recycled after the callback.
+ release_callback3->Run(gpu::SyncToken(), false /* lostResource */);
+ EXPECT_EQ(sii->shared_image_count(), 2u);
- EXPECT_FALSE(raw_ptr->MarkContentsChanged());
- release_callback3->Run(gpu::SyncToken(), true /* lostResource */);
- EXPECT_EQ(live, false);
+ drawing_buffer_->BeginDestruction();
}
TEST_F(DrawingBufferTest, VerifyOnlyOneRecycledResourceMustBeKept) {
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 61445894ffc..bf4f933c401 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
@@ -60,8 +60,8 @@ class WebGraphicsContext3DProviderForTests
const WebglPreferences& GetWebglPreferences() const override {
return webgl_preferences_;
}
- viz::GLHelper* GetGLHelper() override { return nullptr; }
- void SetLostContextCallback(base::Closure) override {}
+ gpu::GLHelper* GetGLHelper() override { return nullptr; }
+ void SetLostContextCallback(base::RepeatingClosure) override {}
void SetErrorMessageCallback(
base::RepeatingCallback<void(const char*, int32_t id)>) override {}
cc::ImageDecodeCache* ImageDecodeCache(SkColorType color_type) override {
@@ -279,9 +279,9 @@ class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub,
// ImplementationBase implementation
void GenSyncTokenCHROMIUM(GLbyte* sync_token) override {
- static uint64_t unique_id = 1;
- gpu::SyncToken source(
- gpu::GPU_IO, gpu::CommandBufferId::FromUnsafeValue(unique_id++), 2);
+ static gpu::CommandBufferId::Generator command_buffer_id_generator;
+ gpu::SyncToken source(gpu::GPU_IO,
+ command_buffer_id_generator.GenerateNextId(), 2);
memcpy(sync_token, &source, sizeof(source));
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.cc
index 50308ffc6b2..388559e7630 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.cc
@@ -9,6 +9,7 @@
#include "base/memory/ptr_util.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/command_buffer/common/gles2_cmd_copy_texture_chromium_utils.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
namespace blink {
@@ -75,6 +76,12 @@ bool Extensions3DUtil::IsExtensionEnabled(const String& name) {
return enabled_extensions_.Contains(name);
}
+// static
+bool Extensions3DUtil::CopyTextureCHROMIUMNeedsESSL3(GLenum dest_format) {
+ return gpu::gles2::CopyTextureCHROMIUMNeedsESSL3(dest_format);
+}
+
+// static
bool Extensions3DUtil::CanUseCopyTextureCHROMIUM(GLenum dest_target) {
switch (dest_target) {
case GL_TEXTURE_2D:
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h
index 062807c497f..6a214156502 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h
@@ -38,6 +38,7 @@ class PLATFORM_EXPORT Extensions3DUtil final {
bool EnsureExtensionEnabled(const String& name);
bool IsExtensionEnabled(const String& name);
+ static bool CopyTextureCHROMIUMNeedsESSL3(GLenum dest_format);
static bool CanUseCopyTextureCHROMIUM(GLenum dest_target);
private:
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/graphics_context_3d_utils.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/graphics_context_3d_utils.cc
index 68c1c5063ca..2d15555c764 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/graphics_context_3d_utils.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/graphics_context_3d_utils.cc
@@ -12,94 +12,8 @@
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/gpu/GrContext.h"
-namespace {
-
-struct GrTextureMailboxReleaseProcData {
- GrTexture* gr_texture_;
- base::WeakPtr<blink::WebGraphicsContext3DProviderWrapper>
- context_provider_wrapper_;
-};
-
-void GrTextureMailboxReleaseProc(void* data) {
- GrTextureMailboxReleaseProcData* release_proc_data =
- static_cast<GrTextureMailboxReleaseProcData*>(data);
-
- if (release_proc_data->context_provider_wrapper_) {
- release_proc_data->context_provider_wrapper_->Utils()->RemoveCachedMailbox(
- release_proc_data->gr_texture_);
- }
-
- delete release_proc_data;
-}
-
-} // unnamed namespace
-
namespace blink {
-bool GraphicsContext3DUtils::GetMailboxForSkImage(gpu::Mailbox& out_mailbox,
- GLenum& out_texture_target,
- const sk_sp<SkImage>& image,
- GLenum filter) {
- // This object is owned by context_provider_wrapper_, so that weak ref
- // should never be null.
- DCHECK(context_provider_wrapper_);
- DCHECK(image->isTextureBacked());
- GrContext* gr = context_provider_wrapper_->ContextProvider()->GetGrContext();
- gpu::gles2::GLES2Interface* gl =
- context_provider_wrapper_->ContextProvider()->ContextGL();
-
- DCHECK(gr);
- DCHECK(gl);
- GrTexture* gr_texture = image->getTexture();
- if (!gr_texture)
- return false;
-
- DCHECK(gr == gr_texture->getContext());
-
- GrBackendTexture backend_texture = image->getBackendTexture(true);
- DCHECK(backend_texture.isValid());
-
- GrGLTextureInfo info;
- bool result = backend_texture.getGLTextureInfo(&info);
- DCHECK(result);
-
- GLuint texture_id = info.fID;
- GLenum texture_target = info.fTarget;
- out_texture_target = texture_target;
-
- auto it = cached_mailboxes_.find(gr_texture);
- if (it != cached_mailboxes_.end()) {
- out_mailbox = it->value;
- } else {
- gl->ProduceTextureDirectCHROMIUM(texture_id, out_mailbox.name);
-
- GrTextureMailboxReleaseProcData* release_proc_data =
- new GrTextureMailboxReleaseProcData();
- release_proc_data->gr_texture_ = gr_texture;
- release_proc_data->context_provider_wrapper_ = context_provider_wrapper_;
- gr_texture->setRelease(GrTextureMailboxReleaseProc, release_proc_data);
- cached_mailboxes_.insert(gr_texture, out_mailbox);
- }
- gl->BindTexture(texture_target, texture_id);
- gl->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, filter);
- gl->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, filter);
- gl->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- gl->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- gl->BindTexture(texture_target, 0);
- gr_texture->textureParamsModified();
- return true;
-}
-
-void GraphicsContext3DUtils::RegisterMailbox(GrTexture* gr_texture,
- const gpu::Mailbox& mailbox) {
- DCHECK(cached_mailboxes_.find(gr_texture) == cached_mailboxes_.end());
- cached_mailboxes_.insert(gr_texture, mailbox);
-}
-
-void GraphicsContext3DUtils::RemoveCachedMailbox(GrTexture* gr_texture) {
- cached_mailboxes_.erase(gr_texture);
-}
-
bool GraphicsContext3DUtils::Accelerated2DCanvasFeatureEnabled() {
// Don't use accelerated canvas if compositor is in software mode.
if (!SharedGpuContext::IsGpuCompositingEnabled())
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/graphics_context_3d_utils.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/graphics_context_3d_utils.h
index 403becdd9f4..f18a0a18cd2 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/graphics_context_3d_utils.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/graphics_context_3d_utils.h
@@ -12,7 +12,6 @@
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/skia/include/core/SkImage.h"
-#include "third_party/skia/include/gpu/GrTexture.h"
typedef unsigned int GLenum;
@@ -30,22 +29,10 @@ class PLATFORM_EXPORT GraphicsContext3DUtils {
context_provider_wrapper)
: context_provider_wrapper_(std::move(context_provider_wrapper)) {}
- // Use this service to create a new mailbox or possibly obtain a pre-existing
- // mailbox for a given texture. The caching of pre-existing mailboxes survives
- // when the texture gets recycled by skia for creating a new SkSurface or
- // SkImage with a pre-existing GrTexture backing.
- bool GetMailboxForSkImage(gpu::Mailbox&,
- GLenum&,
- const sk_sp<SkImage>&,
- GLenum filter);
- void RegisterMailbox(GrTexture*, const gpu::Mailbox&);
- void RemoveCachedMailbox(GrTexture*);
-
bool Accelerated2DCanvasFeatureEnabled();
private:
base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper_;
- WTF::HashMap<GrTexture*, gpu::Mailbox> cached_mailboxes_;
};
} // namespace blink
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 966ee2547d7..e8a21596af5 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
@@ -11,10 +11,13 @@
#include "components/viz/common/resources/shared_bitmap.h"
#include "components/viz/common/resources/transferable_resource.h"
#include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/command_buffer/client/shared_image_interface.h"
+#include "gpu/command_buffer/common/shared_image_usage.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/platform/graphics/accelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/canvas_color_params.h"
+#include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
#include "third_party/blink/renderer/platform/graphics/color_behavior.h"
#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
@@ -24,6 +27,29 @@
#include "ui/gfx/geometry/size.h"
namespace blink {
+namespace {
+
+scoped_refptr<StaticBitmapImage> MakeAccelerated(
+ const scoped_refptr<StaticBitmapImage>& source,
+ base::WeakPtr<WebGraphicsContext3DProviderWrapper>
+ context_provider_wrapper) {
+ if (source->IsTextureBacked())
+ return source;
+
+ auto paint_image = source->PaintImageForCurrentFrame();
+ auto provider = CanvasResourceProvider::CreateSharedImageProvider(
+ source->Size(), context_provider_wrapper, kLow_SkFilterQuality,
+ CanvasColorParams(paint_image.GetSkImage()->imageInfo()),
+ source->IsOriginTopLeft(), CanvasResourceProvider::RasterMode::kGPU,
+ gpu::SHARED_IMAGE_USAGE_DISPLAY);
+ if (!provider || !provider->IsAccelerated())
+ return nullptr;
+
+ provider->Canvas()->drawImage(paint_image, 0, 0, nullptr);
+ return provider->Snapshot();
+}
+
+} // namespace
ImageLayerBridge::ImageLayerBridge(OpacityMode opacity_mode)
: opacity_mode_(opacity_mode) {
@@ -35,7 +61,6 @@ ImageLayerBridge::ImageLayerBridge(OpacityMode opacity_mode)
layer_->SetContentsOpaque(true);
layer_->SetBlendBackgroundColor(false);
}
- GraphicsLayer::RegisterContentsLayer(layer_.get());
}
ImageLayerBridge::~ImageLayerBridge() {
@@ -86,7 +111,6 @@ void ImageLayerBridge::SetUV(const FloatPoint& left_top,
void ImageLayerBridge::Dispose() {
if (layer_) {
- GraphicsLayer::UnregisterContentsLayer(layer_.get());
layer_->ClearClient();
layer_ = nullptr;
}
@@ -122,19 +146,22 @@ bool ImageLayerBridge::PrepareTransferableResource(
if (gpu_compositing) {
scoped_refptr<StaticBitmapImage> image_for_compositor =
- image_->MakeAccelerated(SharedGpuContext::ContextProviderWrapper());
- if (!image_for_compositor)
+ MakeAccelerated(image_, SharedGpuContext::ContextProviderWrapper());
+ if (!image_for_compositor || !image_for_compositor->ContextProvider())
return false;
const gfx::Size size(image_for_compositor->width(),
image_for_compositor->height());
uint32_t filter =
filter_quality_ == kNone_SkFilterQuality ? GL_NEAREST : GL_LINEAR;
- image_for_compositor->EnsureMailbox(kUnverifiedSyncToken, filter);
+ auto mailbox_holder = image_for_compositor->GetMailboxHolder();
+ auto* sii = image_for_compositor->ContextProvider()->SharedImageInterface();
+ bool is_overlay_candidate = sii->UsageForMailbox(mailbox_holder.mailbox) &
+ gpu::SHARED_IMAGE_USAGE_SCANOUT;
+
*out_resource = viz::TransferableResource::MakeGL(
- image_for_compositor->GetMailbox(), filter, GL_TEXTURE_2D,
- image_for_compositor->GetSyncToken(), size,
- false /* is_overlay_candidate */);
+ mailbox_holder.mailbox, filter, mailbox_holder.texture_target,
+ mailbox_holder.sync_token, size, is_overlay_candidate);
auto func =
WTF::Bind(&ImageLayerBridge::ResourceReleasedGpu,
WrapWeakPersistent(this), std::move(image_for_compositor));
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 d550eb47af5..acfd1b59240 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(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
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 1592804d496..82b5c4a5fd9 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
@@ -9,6 +9,7 @@
#include "base/test/null_task_runner.h"
#include "components/viz/test/test_gles2_interface.h"
#include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/command_buffer/common/capabilities.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h"
@@ -38,7 +39,12 @@ class SharedGpuContextTestBase : public Test {
-> std::unique_ptr<WebGraphicsContext3DProvider> {
*gpu_compositing_disabled = false;
gl->SetIsContextLost(false);
- return std::make_unique<FakeWebGraphicsContext3DProvider>(gl);
+ auto fake_context =
+ std::make_unique<FakeWebGraphicsContext3DProvider>(gl);
+ gpu::Capabilities capabilities;
+ capabilities.max_texture_size = 20;
+ fake_context->SetCapabilities(capabilities);
+ return fake_context;
};
SharedGpuContext::SetContextProviderFactoryForTesting(
WTF::BindRepeating(factory, WTF::Unretained(&gl_)));
@@ -120,6 +126,27 @@ class SoftwareCompositingTest : public Test {
FakeGLES2Interface gl_;
};
+class SharedGpuContextTestViz : public Test {
+ public:
+ void SetUp() override {
+ task_runner_ = base::MakeRefCounted<base::NullTaskRunner>();
+ handle_ = std::make_unique<base::ThreadTaskRunnerHandle>(task_runner_);
+ test_context_provider_ = viz::TestContextProvider::Create();
+ InitializeSharedGpuContext(test_context_provider_.get(),
+ /*cache = */ nullptr,
+ SetIsContextLost::kSetToFalse);
+ }
+
+ void TearDown() override {
+ handle_.reset();
+ task_runner_.reset();
+ SharedGpuContext::ResetForTesting();
+ }
+ scoped_refptr<base::NullTaskRunner> task_runner_;
+ std::unique_ptr<base::ThreadTaskRunnerHandle> handle_;
+ scoped_refptr<viz::TestContextProvider> test_context_provider_;
+};
+
TEST_F(SharedGpuContextTest, contextLossAutoRecovery) {
EXPECT_NE(SharedGpuContext::ContextProviderWrapper(), nullptr);
base::WeakPtr<WebGraphicsContext3DProviderWrapper> context =
@@ -133,26 +160,6 @@ TEST_F(SharedGpuContextTest, contextLossAutoRecovery) {
EXPECT_FALSE(!!context);
}
-TEST_F(SharedGpuContextTest, AccelerateImageBufferSurfaceAutoRecovery) {
- // Verifies that after a context loss, attempting to allocate an
- // AcceleratedImageBufferSurface will restore the context and succeed
- gl_.SetIsContextLost(true);
- EXPECT_FALSE(SharedGpuContext::IsValidWithoutRestoring());
- IntSize size(10, 10);
- std::unique_ptr<CanvasResourceProvider> resource_provider =
- CanvasResourceProvider::Create(
- size,
- CanvasResourceProvider::ResourceUsage::kAcceleratedResourceUsage,
- SharedGpuContext::ContextProviderWrapper(),
- 0, // msaa_sample_count
- kLow_SkFilterQuality, CanvasColorParams(),
- CanvasResourceProvider::kDefaultPresentationMode,
- nullptr // canvas_resource_dispatcher
- );
- EXPECT_TRUE(resource_provider && resource_provider->IsValid());
- EXPECT_TRUE(SharedGpuContext::IsValidWithoutRestoring());
-}
-
TEST_F(SharedGpuContextTest, Canvas2DLayerBridgeAutoRecovery) {
// Verifies that after a context loss, attempting to allocate a
// Canvas2DLayerBridge will restore the context and succeed.
@@ -181,20 +188,16 @@ TEST_F(BadSharedGpuContextTest, AllowSoftwareToAcceleratedCanvasUpgrade) {
}
TEST_F(BadSharedGpuContextTest, AccelerateImageBufferSurfaceCreationFails) {
- // With a bad shared context, AccelerateImageBufferSurface creation should
- // fail gracefully
+ // With a bad shared context, AccelerateImageBufferSurface should fail and
+ // return a nullptr provider
IntSize size(10, 10);
std::unique_ptr<CanvasResourceProvider> resource_provider =
- CanvasResourceProvider::Create(
- size,
- CanvasResourceProvider::ResourceUsage::kAcceleratedResourceUsage,
- SharedGpuContext::ContextProviderWrapper(),
- 0, // msaa_sample_count
+ CanvasResourceProvider::CreateSharedImageProvider(
+ size, SharedGpuContext::ContextProviderWrapper(),
kLow_SkFilterQuality, CanvasColorParams(),
- CanvasResourceProvider::kDefaultPresentationMode,
- nullptr // canvas_resource_dispatcher
- );
- EXPECT_FALSE(!resource_provider);
+ true /*is_origin_top_left*/, CanvasResourceProvider::RasterMode::kGPU,
+ 0u /*shared_image_usage_flags*/);
+ EXPECT_FALSE(resource_provider);
}
TEST_F(SharedGpuContextTest, CompositingMode) {
@@ -209,51 +212,21 @@ TEST_F(SoftwareCompositingTest, CompositingMode) {
EXPECT_FALSE(SharedGpuContext::IsGpuCompositingEnabled());
}
-class MailboxSharedGpuContextTest : public Test {
- public:
- void SetUp() override {
- task_runner_ = base::MakeRefCounted<base::NullTaskRunner>();
- handle_ = std::make_unique<base::ThreadTaskRunnerHandle>(task_runner_);
- context_ = viz::TestContextProvider::Create();
- InitializeSharedGpuContext(context_.get());
- }
-
- scoped_refptr<viz::TestContextProvider> context_;
- scoped_refptr<base::NullTaskRunner> task_runner_;
- std::unique_ptr<base::ThreadTaskRunnerHandle> handle_;
-};
-
-TEST_F(MailboxSharedGpuContextTest, MailboxCaching) {
+TEST_F(SharedGpuContextTestViz, AccelerateImageBufferSurfaceAutoRecovery) {
+ // Verifies that after a context loss, attempting to allocate an
+ // AcceleratedImageBufferSurface will restore the context and succeed
+ test_context_provider_->TestContextGL()->set_context_lost(true);
+ EXPECT_FALSE(SharedGpuContext::IsValidWithoutRestoring());
IntSize size(10, 10);
std::unique_ptr<CanvasResourceProvider> resource_provider =
- CanvasResourceProvider::Create(
- size,
- CanvasResourceProvider::ResourceUsage::kAcceleratedResourceUsage,
- SharedGpuContext::ContextProviderWrapper(),
- 0, // msaa_sample_count
+ CanvasResourceProvider::CreateSharedImageProvider(
+ size, SharedGpuContext::ContextProviderWrapper(),
kLow_SkFilterQuality, CanvasColorParams(),
- CanvasResourceProvider::kDefaultPresentationMode,
- nullptr // canvas_resource_dispatcher
- );
- ASSERT_TRUE(resource_provider->IsAccelerated());
+ true /*is_origin_top_left*/, CanvasResourceProvider::RasterMode::kGPU,
+ 0u /*shared_image_usage_flags*/);
EXPECT_TRUE(resource_provider && resource_provider->IsValid());
- scoped_refptr<StaticBitmapImage> image = resource_provider->Snapshot();
- GLenum texture_target = GL_TEXTURE_2D;
- gpu::Mailbox mailbox[3];
-
- // Creating the SkImage representation from the shared image mailbox registers
- // the same mailbox mapping to this SkImage with the cache. This ensures we
- // don't recreate a non-shared image mailbox if going from SkImage to mailbox.
- mailbox[0] = image->GetMailbox();
- SharedGpuContext::ContextProviderWrapper()->Utils()->GetMailboxForSkImage(
- mailbox[1], texture_target,
- image->PaintImageForCurrentFrame().GetSkImage(), GL_NEAREST);
- EXPECT_EQ(mailbox[0], mailbox[1]);
-
- SharedGpuContext::ContextProviderWrapper()->Utils()->GetMailboxForSkImage(
- mailbox[2], texture_target,
- image->PaintImageForCurrentFrame().GetSkImage(), GL_NEAREST);
- EXPECT_EQ(mailbox[1], mailbox[2]);
+ EXPECT_TRUE(resource_provider->IsAccelerated());
+ EXPECT_TRUE(SharedGpuContext::IsValidWithoutRestoring());
}
} // unnamed namespace
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 08aea5a6e62..0736906278c 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
@@ -2858,7 +2858,11 @@ void WebGLImageConversion::ImageExtractor::ExtractImage(
if (!skia_image)
return;
- image_source_format_ = SK_B32_SHIFT ? kDataFormatRGBA8 : kDataFormatBGRA8;
+#if SK_B32_SHIFT
+ image_source_format_ = kDataFormatRGBA8;
+#else
+ image_source_format_ = kDataFormatBGRA8;
+#endif
image_source_unpack_alignment_ =
0; // FIXME: this seems to always be zero - why use at all?
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
new file mode 100644
index 00000000000..241c2c76d2a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.cc
@@ -0,0 +1,82 @@
+// 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/gpu/webgpu_image_bitmap_handler.h"
+
+#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
+
+namespace blink {
+
+namespace {
+static constexpr uint64_t kDawnRowPitchAlignmentBits = 8;
+
+// Calculate row pitch for T2B/B2T copy
+// TODO(shaobo.yan@intel.com): Using Dawn's constants once they are exposed
+uint64_t AlignWebGPURowPitch(uint64_t bytesPerRow) {
+ return (((bytesPerRow - 1) >> kDawnRowPitchAlignmentBits) + 1)
+ << kDawnRowPitchAlignmentBits;
+}
+
+} // anonymous namespace
+
+WebGPUImageUploadSizeInfo ComputeImageBitmapWebGPUUploadSizeInfo(
+ const IntRect& rect,
+ const CanvasColorParams& color_params) {
+ WebGPUImageUploadSizeInfo info;
+ uint64_t bytes_per_pixel = color_params.BytesPerPixel();
+
+ uint64_t row_pitch = AlignWebGPURowPitch(rect.Width() * bytes_per_pixel);
+
+ // Currently, row pitch for buffer copy view in WebGPU is an uint32_t type
+ // value and the maximum value is std::numeric_limits<uint32_t>::max().
+ DCHECK(row_pitch <= std::numeric_limits<uint32_t>::max());
+
+ info.wgpu_row_pitch = static_cast<uint32_t>(row_pitch);
+ info.size_in_bytes = row_pitch * rect.Height();
+
+ return info;
+}
+
+bool CopyBytesFromImageBitmapForWebGPU(scoped_refptr<StaticBitmapImage> image,
+ base::span<uint8_t> dst,
+ const IntRect& rect,
+ const CanvasColorParams& color_params) {
+ 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);
+ 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;
+
+ // Read pixel request dst info.
+ SkImageInfo info = SkImageInfo::Make(
+ rect.Width(), rect.Height(), color_type, kUnpremul_SkAlphaType,
+ color_params.GetSkColorSpaceForSkSurfaces());
+
+ sk_sp<SkImage> sk_image = image->PaintImageForCurrentFrame().GetSkImage();
+
+ if (!sk_image)
+ return false;
+
+ bool read_pixels_successful = sk_image->readPixels(
+ info, dst.data(), wgpu_info.wgpu_row_pitch, rect.X(), rect.Y());
+
+ if (!read_pixels_successful) {
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..4f6c690d7b3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler.h
@@ -0,0 +1,32 @@
+// 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_GPU_WEBGPU_IMAGE_BITMAP_HANDLER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_WEBGPU_IMAGE_BITMAP_HANDLER_H_
+
+#include "base/containers/span.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
+
+namespace blink {
+
+struct WebGPUImageUploadSizeInfo {
+ uint64_t size_in_bytes;
+ uint32_t wgpu_row_pitch;
+};
+
+class CanvasColorParams;
+class IntRect;
+class StaticBitmapImage;
+
+WebGPUImageUploadSizeInfo PLATFORM_EXPORT
+ComputeImageBitmapWebGPUUploadSizeInfo(const IntRect& rect,
+ const CanvasColorParams& color_params);
+bool PLATFORM_EXPORT
+CopyBytesFromImageBitmapForWebGPU(scoped_refptr<StaticBitmapImage> image,
+ base::span<uint8_t> dst,
+ const IntRect& rect,
+ const CanvasColorParams& color_params);
+} // namespace blink
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_WEBGPU_IMAGE_BITMAP_HANDLER_H_
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
new file mode 100644
index 00000000000..f2c4766e921
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_image_bitmap_handler_test.cc
@@ -0,0 +1,110 @@
+// 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/gpu/webgpu_image_bitmap_handler.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
+
+namespace blink {
+
+static constexpr uint64_t kMaxArrayLength = 40000;
+
+class WebGPUImageBitmapHandlerTest : public testing::Test {
+ protected:
+ void SetUp() override {}
+
+ void VerifyCopyBytesForWebGPU(uint64_t width,
+ uint64_t height,
+ SkImageInfo info,
+ CanvasColorParams param,
+ IntRect copyRect) {
+ const uint64_t content_length = width * height * param.BytesPerPixel();
+ std::array<uint8_t, kMaxArrayLength> contents = {0};
+ // Initialize contents.
+ for (size_t i = 0; i < content_length; ++i) {
+ contents[i] = i % std::numeric_limits<uint8_t>::max();
+ }
+
+ sk_sp<SkData> image_pixels =
+ SkData::MakeWithCopy(contents.data(), content_length);
+ scoped_refptr<StaticBitmapImage> image =
+ StaticBitmapImage::Create(std::move(image_pixels), info);
+
+ WebGPUImageUploadSizeInfo wgpu_info =
+ ComputeImageBitmapWebGPUUploadSizeInfo(copyRect, param);
+
+ const uint64_t result_length = wgpu_info.size_in_bytes;
+ std::array<uint8_t, kMaxArrayLength> results = {0};
+ bool success = CopyBytesFromImageBitmapForWebGPU(
+ image, base::span<uint8_t>(results.data(), result_length), copyRect,
+ param);
+ ASSERT_EQ(success, true);
+
+ // Compare content and results
+ uint32_t row_pitch = wgpu_info.wgpu_row_pitch;
+ uint32_t content_row_index =
+ (copyRect.Y() * width + copyRect.X()) * param.BytesPerPixel();
+ 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();
+ result_row_index += row_pitch;
+ }
+ }
+};
+
+// Test calculate size
+TEST_F(WebGPUImageBitmapHandlerTest, VerifyGetWGPUResourceInfo) {
+ uint64_t imageWidth = 63;
+ uint64_t imageHeight = 1;
+ CanvasColorParams param(CanvasColorSpace::kSRGB, CanvasPixelFormat::kRGBA8,
+ OpacityMode::kNonOpaque);
+
+ // Prebaked expected values.
+ uint32_t expected_row_pitch = 256;
+ uint64_t expected_size = 256;
+
+ IntRect test_rect(0, 0, imageWidth, imageHeight);
+ WebGPUImageUploadSizeInfo info =
+ ComputeImageBitmapWebGPUUploadSizeInfo(test_rect, param);
+ ASSERT_EQ(expected_size, info.size_in_bytes);
+ ASSERT_EQ(expected_row_pitch, info.wgpu_row_pitch);
+}
+
+// Copy full image bitmap test
+TEST_F(WebGPUImageBitmapHandlerTest, VerifyCopyBytesFromImageBitmapForWebGPU) {
+ uint64_t imageWidth = 4;
+ uint64_t imageHeight = 2;
+ SkImageInfo info = SkImageInfo::Make(
+ imageWidth, imageHeight, SkColorType::kRGBA_8888_SkColorType,
+ SkAlphaType::kUnpremul_SkAlphaType, SkColorSpace::MakeSRGB());
+
+ IntRect image_data_rect(0, 0, imageWidth, imageHeight);
+ CanvasColorParams color_params(CanvasColorSpace::kSRGB,
+ CanvasPixelFormat::kRGBA8,
+ OpacityMode::kNonOpaque);
+ VerifyCopyBytesForWebGPU(imageWidth, imageHeight, info, color_params,
+ image_data_rect);
+}
+
+// Copy sub image bitmap test
+TEST_F(WebGPUImageBitmapHandlerTest, VerifyCopyBytesFromSubImageBitmap) {
+ uint64_t imageWidth = 63;
+ uint64_t imageHeight = 4;
+ SkImageInfo info = SkImageInfo::Make(
+ imageWidth, imageHeight, 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);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc
index d2fd96c760f..98dc0c889fc 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc
@@ -29,10 +29,12 @@ viz::ResourceFormat WGPUFormatToViz(WGPUTextureFormat format) {
WebGPUSwapBufferProvider::WebGPUSwapBufferProvider(
Client* client,
scoped_refptr<DawnControlClientHolder> dawn_control_client,
+ uint64_t device_client_id,
WGPUTextureUsage usage,
WGPUTextureFormat format)
: dawn_control_client_(dawn_control_client),
client_(client),
+ device_client_id_(device_client_id),
usage_(usage),
format_(WGPUFormatToViz(format)) {
// Create a layer that will be used by the canvas and will ask for a
@@ -48,8 +50,6 @@ WebGPUSwapBufferProvider::WebGPUSwapBufferProvider(
// paths to keep the rendering correct in that cases.
layer_->SetContentsOpaque(true);
layer_->SetPremultipliedAlpha(true);
-
- GraphicsLayer::RegisterContentsLayer(layer_.get());
}
WebGPUSwapBufferProvider::~WebGPUSwapBufferProvider() {
@@ -67,7 +67,6 @@ void WebGPUSwapBufferProvider::Neuter() {
}
if (layer_) {
- GraphicsLayer::UnregisterContentsLayer(layer_.get());
layer_->ClearClient();
layer_ = nullptr;
}
@@ -85,8 +84,7 @@ void WebGPUSwapBufferProvider::Neuter() {
neutered_ = true;
}
-WGPUTexture WebGPUSwapBufferProvider::GetNewTexture(WGPUDevice device,
- const IntSize& size) {
+WGPUTexture WebGPUSwapBufferProvider::GetNewTexture(const IntSize& size) {
DCHECK(!current_swap_buffer_ && !dawn_control_client_->IsDestroyed());
gpu::webgpu::WebGPUInterface* webgpu = dawn_control_client_->GetInterface();
@@ -97,28 +95,27 @@ WGPUTexture WebGPUSwapBufferProvider::GetNewTexture(WGPUDevice device,
// TODO(cwallez@chromium.org): have some recycling mechanism.
gpu::Mailbox mailbox = sii->CreateSharedImage(
format_, static_cast<gfx::Size>(size), gfx::ColorSpace::CreateSRGB(),
- gpu::SHARED_IMAGE_USAGE_WEBGPU | gpu::SHARED_IMAGE_USAGE_DISPLAY);
+ gpu::SHARED_IMAGE_USAGE_WEBGPU |
+ gpu::SHARED_IMAGE_USAGE_WEBGPU_SWAP_CHAIN_TEXTURE |
+ gpu::SHARED_IMAGE_USAGE_DISPLAY);
gpu::SyncToken creation_token = sii->GenUnverifiedSyncToken();
current_swap_buffer_ = base::AdoptRef(new SwapBuffer(
this, mailbox, creation_token, static_cast<gfx::Size>(size)));
- // Make sure previous Dawn wire commands are sent so that for example the ID
- // is freed before we associate the SharedImage.
- webgpu->FlushCommands();
-
// Ensure the shared image is allocated service-side before working with it
webgpu->WaitSyncTokenCHROMIUM(
current_swap_buffer_->access_finished_token.GetConstData());
// Associate the mailbox to a dawn_wire client DawnTexture object
- gpu::webgpu::ReservedTexture reservation = webgpu->ReserveTexture(device);
+ gpu::webgpu::ReservedTexture reservation =
+ webgpu->ReserveTexture(device_client_id_);
DCHECK(reservation.texture);
wire_texture_id_ = reservation.id;
wire_texture_generation_ = reservation.generation;
webgpu->AssociateMailbox(
- 0, 0, reservation.id, reservation.generation, usage_,
+ device_client_id_, 0, reservation.id, reservation.generation, usage_,
reinterpret_cast<GLbyte*>(&current_swap_buffer_->mailbox));
// When the page request a texture it means we'll need to present it on the
@@ -146,7 +143,8 @@ bool WebGPUSwapBufferProvider::PrepareTransferableResource(
// to the texture are errors.
gpu::webgpu::WebGPUInterface* webgpu = dawn_control_client_->GetInterface();
DCHECK_NE(wire_texture_id_, 0u);
- webgpu->DissociateMailbox(wire_texture_id_, wire_texture_generation_);
+ webgpu->DissociateMailbox(device_client_id_, wire_texture_id_,
+ wire_texture_generation_);
// Make the compositor wait on previous Dawn commands.
webgpu->GenUnverifiedSyncTokenCHROMIUM(
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h
index 601e49b0f6c..e1a6ae443cf 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h
@@ -35,13 +35,14 @@ class PLATFORM_EXPORT WebGPUSwapBufferProvider
WebGPUSwapBufferProvider(
Client* client,
scoped_refptr<DawnControlClientHolder> dawn_control_client,
+ uint64_t device_client_id,
WGPUTextureUsage usage,
WGPUTextureFormat format);
~WebGPUSwapBufferProvider() override;
cc::Layer* CcLayer();
void Neuter();
- WGPUTexture GetNewTexture(WGPUDevice device, const IntSize& size);
+ WGPUTexture GetNewTexture(const IntSize& size);
// cc::TextureLayerClient implementation.
bool PrepareTransferableResource(
@@ -81,6 +82,7 @@ class PLATFORM_EXPORT WebGPUSwapBufferProvider
scoped_refptr<DawnControlClientHolder> dawn_control_client_;
Client* client_;
+ uint64_t device_client_id_;
scoped_refptr<cc::TextureLayer> layer_;
bool neutered_ = false;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider_test.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider_test.cc
index 6ff93d7e300..19100740ef6 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider_test.cc
@@ -19,7 +19,8 @@ namespace {
class MockWebGPUInterface : public gpu::webgpu::WebGPUInterfaceStub {
public:
- MOCK_METHOD1(ReserveTexture, gpu::webgpu::ReservedTexture(WGPUDevice device));
+ MOCK_METHOD1(ReserveTexture,
+ gpu::webgpu::ReservedTexture(uint64_t device_client_id));
// It is hard to use GMock with SyncTokens represented as GLByte*, instead we
// remember which were the last sync tokens generated or waited upon.
@@ -57,10 +58,15 @@ class WebGPUSwapBufferProviderForTests : public WebGPUSwapBufferProvider {
WebGPUSwapBufferProviderForTests(
bool* alive,
Client* client,
+ uint64_t client_device_id_,
scoped_refptr<DawnControlClientHolder> dawn_control_client,
WGPUTextureUsage usage,
WGPUTextureFormat format)
- : WebGPUSwapBufferProvider(client, dawn_control_client, usage, format),
+ : WebGPUSwapBufferProvider(client,
+ dawn_control_client,
+ client_device_id_,
+ usage,
+ format),
alive_(alive) {}
~WebGPUSwapBufferProviderForTests() override { *alive_ = false; }
@@ -82,8 +88,10 @@ class WebGPUSwapBufferProviderTest : public testing::Test {
dawn_control_client_ =
base::MakeRefCounted<DawnControlClientHolder>(std::move(provider));
+
+ static const uint64_t kDeviceClientID = 1;
provider_ = base::MakeRefCounted<WebGPUSwapBufferProviderForTests>(
- &provider_alive_, &client_, dawn_control_client_,
+ &provider_alive_, &client_, kDeviceClientID, dawn_control_client_,
WGPUTextureUsage_OutputAttachment, WGPUTextureFormat_RGBA8Unorm);
}
@@ -116,17 +124,17 @@ TEST_F(WebGPUSwapBufferProviderTest,
// Produce resources.
EXPECT_CALL(*webgpu_, ReserveTexture(_)).WillOnce(Return(reservation1));
- provider_->GetNewTexture(nullptr, kSize);
+ provider_->GetNewTexture(kSize);
EXPECT_TRUE(provider_->PrepareTransferableResource(nullptr, &resource1,
&release_callback1));
EXPECT_CALL(*webgpu_, ReserveTexture(_)).WillOnce(Return(reservation2));
- provider_->GetNewTexture(nullptr, kSize);
+ provider_->GetNewTexture(kSize);
EXPECT_TRUE(provider_->PrepareTransferableResource(nullptr, &resource2,
&release_callback2));
EXPECT_CALL(*webgpu_, ReserveTexture(_)).WillOnce(Return(reservation3));
- provider_->GetNewTexture(nullptr, kSize);
+ provider_->GetNewTexture(kSize);
EXPECT_TRUE(provider_->PrepareTransferableResource(nullptr, &resource3,
&release_callback3));
@@ -154,7 +162,7 @@ TEST_F(WebGPUSwapBufferProviderTest, VerifyResizingProperlyAffectsResources) {
// Produce one resource of size kSize.
EXPECT_CALL(*webgpu_, ReserveTexture(_)).WillOnce(Return(reservation));
- provider_->GetNewTexture(nullptr, static_cast<IntSize>(kSize));
+ provider_->GetNewTexture(static_cast<IntSize>(kSize));
EXPECT_TRUE(provider_->PrepareTransferableResource(nullptr, &resource,
&release_callback));
EXPECT_EQ(static_cast<gfx::Size>(kSize), sii_->MostRecentSize());
@@ -162,7 +170,7 @@ TEST_F(WebGPUSwapBufferProviderTest, VerifyResizingProperlyAffectsResources) {
// Produce one resource of size kOtherSize.
EXPECT_CALL(*webgpu_, ReserveTexture(_)).WillOnce(Return(reservation));
- provider_->GetNewTexture(nullptr, static_cast<IntSize>(kOtherSize));
+ provider_->GetNewTexture(static_cast<IntSize>(kOtherSize));
EXPECT_TRUE(provider_->PrepareTransferableResource(nullptr, &resource,
&release_callback));
EXPECT_EQ(static_cast<gfx::Size>(kOtherSize), sii_->MostRecentSize());
@@ -170,7 +178,7 @@ TEST_F(WebGPUSwapBufferProviderTest, VerifyResizingProperlyAffectsResources) {
// Produce one resource of size kSize again.
EXPECT_CALL(*webgpu_, ReserveTexture(_)).WillOnce(Return(reservation));
- provider_->GetNewTexture(nullptr, static_cast<IntSize>(kSize));
+ provider_->GetNewTexture(static_cast<IntSize>(kSize));
EXPECT_TRUE(provider_->PrepareTransferableResource(nullptr, &resource,
&release_callback));
EXPECT_EQ(static_cast<gfx::Size>(kSize), sii_->MostRecentSize());
@@ -188,7 +196,7 @@ TEST_F(WebGPUSwapBufferProviderTest, VerifyInsertAndWaitSyncTokenCorrectly) {
// Produce the first resource, check that WebGPU will wait for the creation of
// the shared image
EXPECT_CALL(*webgpu_, ReserveTexture(_)).WillOnce(Return(reservation));
- provider_->GetNewTexture(nullptr, static_cast<IntSize>(kSize));
+ provider_->GetNewTexture(static_cast<IntSize>(kSize));
EXPECT_EQ(sii_->MostRecentGeneratedToken(),
webgpu_->most_recent_waited_token);
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 63b92488b08..e456c90a383 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
@@ -18,9 +18,7 @@ namespace blink {
XRFrameTransport::XRFrameTransport() : submit_frame_client_receiver_(this) {}
-XRFrameTransport::~XRFrameTransport() {
- CallPreviousFrameCallback();
-}
+XRFrameTransport::~XRFrameTransport() = default;
void XRFrameTransport::PresentChange() {
frame_copier_ = nullptr;
@@ -79,13 +77,6 @@ void XRFrameTransport::FramePreImage(gpu::gles2::GLES2Interface* gl) {
}
}
-void XRFrameTransport::CallPreviousFrameCallback() {
- if (previous_image_release_callback_) {
- previous_image_release_callback_->Run(gpu::SyncToken(), false);
- previous_image_release_callback_ = nullptr;
- }
-}
-
void XRFrameTransport::FrameSubmitMissing(
device::mojom::blink::XRPresentationProvider* vr_presentation_provider,
gpu::gles2::GLES2Interface* gl,
@@ -101,7 +92,6 @@ void XRFrameTransport::FrameSubmit(
gpu::gles2::GLES2Interface* gl,
DrawingBuffer::Client* drawing_buffer_client,
scoped_refptr<Image> image_ref,
- std::unique_ptr<viz::SingleReleaseCallback> release_callback,
int16_t vr_frame_id) {
DCHECK(transport_options_);
@@ -114,8 +104,6 @@ void XRFrameTransport::FrameSubmit(
// without waiting.
if (transport_options_->wait_for_transfer_notification)
WaitForPreviousTransfer();
- CallPreviousFrameCallback();
- previous_image_release_callback_ = std::move(release_callback);
if (!frame_copier_ || !last_transfer_succeeded_) {
frame_copier_ = std::make_unique<GpuMemoryBufferImageCopy>(gl);
}
@@ -137,12 +125,11 @@ void XRFrameTransport::FrameSubmit(
}
// We decompose the cloned handle, and use it to create a
- // mojo::ScopedHandle which will own cleanup of the handle, and will be
+ // mojo::PlatformHandle which will own cleanup of the handle, and will be
// passed over IPC.
gfx::GpuMemoryBufferHandle gpu_handle = gpu_memory_buffer->CloneHandle();
vr_presentation_provider->SubmitFrameWithTextureHandle(
- vr_frame_id,
- mojo::WrapPlatformFile(gpu_handle.dxgi_handle.GetHandle()));
+ vr_frame_id, mojo::PlatformHandle(std::move(gpu_handle.dxgi_handle)));
#else
NOTIMPLEMENTED();
#endif
@@ -155,9 +142,7 @@ void XRFrameTransport::FrameSubmit(
// image until the mailbox was consumed.
StaticBitmapImage* static_image =
static_cast<StaticBitmapImage*>(image_ref.get());
- TRACE_EVENT_BEGIN0("gpu", "XRFrameTransport::EnsureMailbox");
- static_image->EnsureMailbox(kVerifiedSyncToken, GL_NEAREST);
- TRACE_EVENT_END0("gpu", "XRFrameTransport::EnsureMailbox");
+ static_image->EnsureSyncTokenVerified();
// Conditionally wait for the previous render to finish. A late wait here
// attempts to overlap work in parallel with the previous frame's
@@ -173,19 +158,15 @@ void XRFrameTransport::FrameSubmit(
if (transport_options_->wait_for_transfer_notification)
WaitForPreviousTransfer();
previous_image_ = std::move(image_ref);
- CallPreviousFrameCallback();
- previous_image_release_callback_ = std::move(release_callback);
// Create mailbox and sync token for transfer.
TRACE_EVENT_BEGIN0("gpu", "XRFrameTransport::GetMailbox");
- auto mailbox = static_image->GetMailbox();
+ auto mailbox_holder = static_image->GetMailboxHolder();
TRACE_EVENT_END0("gpu", "XRFrameTransport::GetMailbox");
- auto sync_token = static_image->GetSyncToken();
TRACE_EVENT_BEGIN0("gpu", "XRFrameTransport::SubmitFrame");
- vr_presentation_provider->SubmitFrame(
- vr_frame_id, gpu::MailboxHolder(mailbox, sync_token, GL_TEXTURE_2D),
- frame_wait_time_);
+ vr_presentation_provider->SubmitFrame(vr_frame_id, mailbox_holder,
+ frame_wait_time_);
TRACE_EVENT_END0("gpu", "XRFrameTransport::SubmitFrame");
} else if (transport_options_->transport_method ==
device::mojom::blink::XRPresentationTransportMethod::
@@ -264,6 +245,6 @@ base::TimeDelta XRFrameTransport::WaitForGpuFenceReceived() {
return base::TimeTicks::Now() - start;
}
-void XRFrameTransport::Trace(blink::Visitor* visitor) {}
+void XRFrameTransport::Trace(Visitor* visitor) {}
} // namespace blink
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 f0fa0523692..982f5ad3d33 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
@@ -52,20 +52,18 @@ class PLATFORM_EXPORT XRFrameTransport final
gpu::gles2::GLES2Interface*,
DrawingBuffer::Client*,
scoped_refptr<Image> image_ref,
- std::unique_ptr<viz::SingleReleaseCallback>,
int16_t vr_frame_id);
void FrameSubmitMissing(device::mojom::blink::XRPresentationProvider*,
gpu::gles2::GLES2Interface*,
int16_t vr_frame_id);
- virtual void Trace(blink::Visitor*);
+ virtual void Trace(Visitor*);
private:
void WaitForPreviousTransfer();
base::TimeDelta WaitForPreviousRenderToFinish();
base::TimeDelta WaitForGpuFenceReceived();
- void CallPreviousFrameCallback();
// XRPresentationClient
void OnSubmitFrameTransferred(bool success) override;
@@ -78,7 +76,6 @@ class PLATFORM_EXPORT XRFrameTransport final
// Used to keep the image alive until the next frame if using
// waitForPreviousTransferToFinish.
scoped_refptr<Image> previous_image_;
- std::unique_ptr<viz::SingleReleaseCallback> previous_image_release_callback_;
bool waiting_for_previous_frame_transfer_ = false;
bool last_transfer_succeeded_ = false;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.cc
index f4660896cee..9578314ff56 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.cc
@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h"
#include "third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h"
+#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -25,16 +26,27 @@ namespace blink {
// some of the common bits into a base class?
XRWebGLDrawingBuffer::ColorBuffer::ColorBuffer(
- XRWebGLDrawingBuffer* drawing_buffer,
+ base::WeakPtr<XRWebGLDrawingBuffer> drawing_buffer,
const IntSize& size,
const gpu::Mailbox& mailbox,
GLuint texture_id)
- : drawing_buffer(drawing_buffer),
+ : owning_thread_ref(base::PlatformThread::CurrentRef()),
+ drawing_buffer(std::move(drawing_buffer)),
size(size),
texture_id(texture_id),
mailbox(mailbox) {}
XRWebGLDrawingBuffer::ColorBuffer::~ColorBuffer() {
+ if (base::PlatformThread::CurrentRef() != owning_thread_ref ||
+ !drawing_buffer) {
+ // If the context has been destroyed no cleanup is necessary since all
+ // resources below are automatically destroyed. Note that if a ColorBuffer
+ // is being destroyed on a different thread, it implies that the owning
+ // thread was destroyed which means the associated context was also
+ // destroyed.
+ return;
+ }
+
gpu::gles2::GLES2Interface* gl = drawing_buffer->ContextGL();
if (receive_sync_token.HasData())
gl->WaitSyncTokenCHROMIUM(receive_sync_token.GetConstData());
@@ -105,68 +117,6 @@ scoped_refptr<XRWebGLDrawingBuffer> XRWebGLDrawingBuffer::Create(
return xr_drawing_buffer;
}
-void XRWebGLDrawingBuffer::MirrorClient::OnMirrorImageAvailable(
- scoped_refptr<StaticBitmapImage> image,
- std::unique_ptr<viz::SingleReleaseCallback> callback) {
- // Replace the next image if we have one already.
- if (next_image_ && next_release_callback_) {
- next_release_callback_->Run(gpu::SyncToken(), false);
- }
-
- // Set our new image.
- next_image_ = image;
- next_release_callback_ = std::move(callback);
-}
-
-void XRWebGLDrawingBuffer::MirrorClient::BeginDestruction() {
- // Call all callbacks we have to clean up associated resources. For
- // next_release_callback_, we report the previous image as "not lost", meaning
- // we can reuse the texture/image. For previous_release_callback_
- // and current_release_callback_, we report the image as lost, because we
- // don't know if the consumer is still using them, so they should not be
- // reused.
- if (previous_release_callback_) {
- previous_release_callback_->Run(gpu::SyncToken(), true);
- previous_release_callback_ = nullptr;
- }
-
- if (current_release_callback_) {
- current_release_callback_->Run(gpu::SyncToken(), true);
- current_release_callback_ = nullptr;
- }
-
- if (next_release_callback_) {
- next_release_callback_->Run(gpu::SyncToken(), false);
- next_release_callback_ = nullptr;
- }
-
- next_image_ = nullptr;
-}
-
-scoped_refptr<StaticBitmapImage>
-XRWebGLDrawingBuffer::MirrorClient::GetLastImage() {
- if (!next_image_)
- return nullptr;
-
- scoped_refptr<StaticBitmapImage> ret = next_image_;
- next_image_ = nullptr;
- DCHECK(!previous_release_callback_);
- previous_release_callback_ = std::move(current_release_callback_);
- DCHECK(!current_release_callback_);
- current_release_callback_ = std::move(next_release_callback_);
- return ret;
-}
-
-void XRWebGLDrawingBuffer::MirrorClient::CallLastReleaseCallback() {
- if (previous_release_callback_)
- previous_release_callback_->Run(gpu::SyncToken(), false);
- previous_release_callback_ = nullptr;
-}
-
-XRWebGLDrawingBuffer::MirrorClient::~MirrorClient() {
- BeginDestruction();
-}
-
XRWebGLDrawingBuffer::XRWebGLDrawingBuffer(DrawingBuffer* drawing_buffer,
GLuint framebuffer,
bool discard_framebuffer_supported,
@@ -178,11 +128,10 @@ XRWebGLDrawingBuffer::XRWebGLDrawingBuffer(DrawingBuffer* drawing_buffer,
discard_framebuffer_supported_(discard_framebuffer_supported),
depth_(want_depth_buffer),
stencil_(want_stencil_buffer),
- alpha_(want_alpha_channel) {}
+ alpha_(want_alpha_channel),
+ weak_factory_(this) {}
void XRWebGLDrawingBuffer::BeginDestruction() {
- mirror_client_ = nullptr;
-
if (back_color_buffer_) {
gpu::gles2::GLES2Interface* gl = drawing_buffer_->ContextGL();
gl->EndSharedImageAccessDirectCHROMIUM(back_color_buffer_->texture_id);
@@ -242,18 +191,6 @@ gpu::gles2::GLES2Interface* XRWebGLDrawingBuffer::ContextGL() {
return drawing_buffer_->ContextGL();
}
-void XRWebGLDrawingBuffer::SetMirrorClient(scoped_refptr<MirrorClient> client) {
- mirror_client_ = client;
- if (mirror_client_) {
- // Immediately send a black 1x1 image to the mirror client to ensure that
- // it has content to show.
- sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(1, 1);
- mirror_client_->OnMirrorImageAvailable(
- UnacceleratedStaticBitmapImage::Create(surface->makeImageSnapshot()),
- nullptr);
- }
-}
-
bool XRWebGLDrawingBuffer::ContextLost() {
return drawing_buffer_->destroyed();
}
@@ -523,7 +460,8 @@ XRWebGLDrawingBuffer::CreateColorBuffer() {
DrawingBuffer::Client* client = drawing_buffer_->client();
client->DrawingBufferClientRestoreTexture2DBinding();
- return base::AdoptRef(new ColorBuffer(this, size_, mailbox, texture_id));
+ return base::MakeRefCounted<ColorBuffer>(weak_factory_.GetWeakPtr(), size_,
+ mailbox, texture_id);
}
scoped_refptr<XRWebGLDrawingBuffer::ColorBuffer>
@@ -626,8 +564,7 @@ void XRWebGLDrawingBuffer::SwapColorBuffers() {
}
scoped_refptr<StaticBitmapImage>
-XRWebGLDrawingBuffer::TransferToStaticBitmapImage(
- std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback) {
+XRWebGLDrawingBuffer::TransferToStaticBitmapImage() {
gpu::gles2::GLES2Interface* gl = drawing_buffer_->ContextGL();
scoped_refptr<ColorBuffer> buffer;
bool success = false;
@@ -661,47 +598,45 @@ XRWebGLDrawingBuffer::TransferToStaticBitmapImage(
// This holds a ref on the XRWebGLDrawingBuffer that will keep it alive
// until the mailbox is released (and while the callback is running).
auto func =
- WTF::Bind(mirror_client_ ? &XRWebGLDrawingBuffer::MailboxReleasedToMirror
- : &XRWebGLDrawingBuffer::MailboxReleased,
- scoped_refptr<XRWebGLDrawingBuffer>(this), buffer);
+ base::BindOnce(&XRWebGLDrawingBuffer::NotifyMailboxReleased, buffer);
std::unique_ptr<viz::SingleReleaseCallback> release_callback =
viz::SingleReleaseCallback::Create(std::move(func));
+ const SkImageInfo sk_image_info =
+ SkImageInfo::MakeN32Premul(size_.Width(), size_.Height());
+
+ return AcceleratedStaticBitmapImage::CreateFromCanvasMailbox(
+ buffer->mailbox, buffer->produce_sync_token,
+ /* shared_image_texture_id = */ 0, sk_image_info, GL_TEXTURE_2D,
+ /* is_origin_top_left = */ false,
+ drawing_buffer_->ContextProviderWeakPtr(),
+ base::PlatformThread::CurrentRef(), Thread::Current()->GetTaskRunner(),
+ std::move(release_callback));
+}
- // Make our own textureId that is a reference on the same shared image being
- // used as the front buffer. We do not need a
- // Begin/EndSharedImageAccessDirectCHROMIUM as the texture id is just for
- // lifetime, not actual access. We do not need to wait on the sync token
- // since the GL context has already waited on it. Similarly, the release
- // callback will run on the same context so we don't need to send a sync token
- // for this consume action back to it.
- GLuint texture_id =
- gl->CreateAndTexStorage2DSharedImageCHROMIUM(buffer->mailbox.name);
+// static
+void XRWebGLDrawingBuffer::NotifyMailboxReleased(
+ scoped_refptr<ColorBuffer> color_buffer,
+ const gpu::SyncToken& sync_token,
+ bool lost_resource) {
+ DCHECK(color_buffer->owning_thread_ref == base::PlatformThread::CurrentRef());
- if (out_release_callback) {
- *out_release_callback = std::move(release_callback);
- } else {
- release_callback->Run(gpu::SyncToken(), true /* lost_resource */);
+ // Update the SyncToken to ensure that we will wait for it even if we
+ // immediately destroy this buffer.
+ color_buffer->receive_sync_token = sync_token;
+ if (color_buffer->drawing_buffer) {
+ color_buffer->drawing_buffer->MailboxReleased(color_buffer, lost_resource);
}
-
- return AcceleratedStaticBitmapImage::CreateFromWebGLContextImage(
- buffer->mailbox, buffer->produce_sync_token, texture_id,
- drawing_buffer_->ContextProviderWeakPtr(), size_, false);
}
void XRWebGLDrawingBuffer::MailboxReleased(
scoped_refptr<ColorBuffer> color_buffer,
- const gpu::SyncToken& sync_token,
bool lost_resource) {
// If the mailbox has been returned by the compositor then it is no
// longer being presented, and so is no longer the front buffer.
if (color_buffer == front_color_buffer_)
front_color_buffer_ = nullptr;
- // Update the SyncToken to ensure that we will wait for it even if we
- // immediately destroy this buffer.
- color_buffer->receive_sync_token = sync_token;
-
if (drawing_buffer_->destroyed() || color_buffer->size != size_ ||
lost_resource) {
return;
@@ -714,35 +649,4 @@ void XRWebGLDrawingBuffer::MailboxReleased(
recycled_color_buffer_queue_.push_front(color_buffer);
}
-void XRWebGLDrawingBuffer::MailboxReleasedToMirror(
- scoped_refptr<ColorBuffer> color_buffer,
- const gpu::SyncToken& sync_token,
- bool lost_resource) {
- if (!mirror_client_ || lost_resource) {
- MailboxReleased(std::move(color_buffer), sync_token, lost_resource);
- return;
- }
-
- gpu::gles2::GLES2Interface* gl = drawing_buffer_->ContextGL();
- color_buffer->receive_sync_token = sync_token;
-
- auto func =
- WTF::Bind(&XRWebGLDrawingBuffer::MailboxReleased,
- scoped_refptr<XRWebGLDrawingBuffer>(this), color_buffer);
-
- std::unique_ptr<viz::SingleReleaseCallback> release_callback =
- viz::SingleReleaseCallback::Create(std::move(func));
-
- GLuint texture_id =
- gl->CreateAndTexStorage2DSharedImageCHROMIUM(color_buffer->mailbox.name);
-
- scoped_refptr<StaticBitmapImage> image =
- AcceleratedStaticBitmapImage::CreateFromWebGLContextImage(
- color_buffer->mailbox, color_buffer->produce_sync_token, texture_id,
- drawing_buffer_->ContextProviderWeakPtr(), color_buffer->size, false);
-
- mirror_client_->OnMirrorImageAvailable(std::move(image),
- std::move(release_callback));
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.h
index 44649d80dd6..26f28d0cc11 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/xr_webgl_drawing_buffer.h
@@ -43,28 +43,7 @@ class PLATFORM_EXPORT XRWebGLDrawingBuffer
void Resize(const IntSize&);
- scoped_refptr<StaticBitmapImage> TransferToStaticBitmapImage(
- std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback);
-
- class PLATFORM_EXPORT MirrorClient : public RefCounted<MirrorClient> {
- public:
- void OnMirrorImageAvailable(scoped_refptr<StaticBitmapImage>,
- std::unique_ptr<viz::SingleReleaseCallback>);
-
- void BeginDestruction();
- scoped_refptr<StaticBitmapImage> GetLastImage();
- void CallLastReleaseCallback();
-
- ~MirrorClient();
-
- private:
- scoped_refptr<StaticBitmapImage> next_image_;
- std::unique_ptr<viz::SingleReleaseCallback> next_release_callback_;
- std::unique_ptr<viz::SingleReleaseCallback> current_release_callback_;
- std::unique_ptr<viz::SingleReleaseCallback> previous_release_callback_;
- };
-
- void SetMirrorClient(scoped_refptr<MirrorClient> mirror_client);
+ scoped_refptr<StaticBitmapImage> TransferToStaticBitmapImage();
void UseSharedBuffer(const gpu::MailboxHolder&);
void DoneWithSharedBuffer();
@@ -75,17 +54,22 @@ class PLATFORM_EXPORT XRWebGLDrawingBuffer
void BeginDestruction();
private:
- struct PLATFORM_EXPORT ColorBuffer : public RefCounted<ColorBuffer> {
- ColorBuffer(XRWebGLDrawingBuffer*,
+ struct PLATFORM_EXPORT ColorBuffer
+ : public base::RefCountedThreadSafe<ColorBuffer> {
+ ColorBuffer(base::WeakPtr<XRWebGLDrawingBuffer>,
const IntSize&,
const gpu::Mailbox& mailbox,
GLuint texture_id);
~ColorBuffer();
+ // The thread on which the ColorBuffer is created and the DrawingBuffer is
+ // bound to.
+ const base::PlatformThreadRef owning_thread_ref;
+
// The owning XRWebGLDrawingBuffer. Note that DrawingBuffer is explicitly
// destroyed by the BeginDestruction method, which will eventually drain all
// of its ColorBuffers.
- scoped_refptr<XRWebGLDrawingBuffer> drawing_buffer;
+ base::WeakPtr<XRWebGLDrawingBuffer> drawing_buffer;
const IntSize size;
// The id of the texture that imports the shared image into the
@@ -126,12 +110,10 @@ class PLATFORM_EXPORT XRWebGLDrawingBuffer
void ClearBoundFramebuffer();
- void MailboxReleased(scoped_refptr<ColorBuffer>,
- const gpu::SyncToken&,
- bool lost_resource);
- void MailboxReleasedToMirror(scoped_refptr<ColorBuffer>,
- const gpu::SyncToken&,
- bool lost_resource);
+ static void NotifyMailboxReleased(scoped_refptr<ColorBuffer>,
+ const gpu::SyncToken&,
+ bool lost_resource);
+ void MailboxReleased(scoped_refptr<ColorBuffer>, bool lost_resource);
// Reference to the DrawingBuffer that owns the GL context for this object.
scoped_refptr<DrawingBuffer> drawing_buffer_;
@@ -174,7 +156,7 @@ class PLATFORM_EXPORT XRWebGLDrawingBuffer
int max_texture_size_ = 0;
int sample_count_ = 0;
- scoped_refptr<MirrorClient> mirror_client_;
+ base::WeakPtrFactory<XRWebGLDrawingBuffer> weak_factory_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu_memory_buffer_image_copy.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu_memory_buffer_image_copy.cc
index 6e0c7398786..00925bfa333 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu_memory_buffer_image_copy.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu_memory_buffer_image_copy.cc
@@ -72,21 +72,21 @@ gfx::GpuMemoryBuffer* GpuMemoryBufferImageCopy::CopyImage(Image* image) {
// Bind the read framebuffer to our image.
StaticBitmapImage* static_image = static_cast<StaticBitmapImage*>(image);
- static_image->EnsureMailbox(kOrderingBarrier, GL_NEAREST);
- auto mailbox = static_image->GetMailbox();
- auto sync_token = static_image->GetSyncToken();
+ auto mailbox_holder = static_image->GetMailboxHolder();
+
// Not strictly necessary since we are on the same context, but keeping
// for cleanliness and in case we ever move off the same context.
- gl_->WaitSyncTokenCHROMIUM(sync_token.GetData());
+ gl_->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetData());
GLuint source_texture_id;
- if (mailbox.IsSharedImage()) {
- source_texture_id =
- gl_->CreateAndTexStorage2DSharedImageCHROMIUM(mailbox.name);
+ if (mailbox_holder.mailbox.IsSharedImage()) {
+ source_texture_id = gl_->CreateAndTexStorage2DSharedImageCHROMIUM(
+ mailbox_holder.mailbox.name);
gl_->BeginSharedImageAccessDirectCHROMIUM(
source_texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM);
} else {
- source_texture_id = gl_->CreateAndConsumeTextureCHROMIUM(mailbox.name);
+ source_texture_id =
+ gl_->CreateAndConsumeTextureCHROMIUM(mailbox_holder.mailbox.name);
}
gl_->BindTexture(GL_TEXTURE_2D, 0);
@@ -97,10 +97,14 @@ gfx::GpuMemoryBuffer* GpuMemoryBufferImageCopy::CopyImage(Image* image) {
// Cleanup the read framebuffer, associated image and texture.
gl_->BindTexture(GL_TEXTURE_2D, 0);
- if (mailbox.IsSharedImage())
+ if (mailbox_holder.mailbox.IsSharedImage())
gl_->EndSharedImageAccessDirectCHROMIUM(source_texture_id);
gl_->DeleteTextures(1, &source_texture_id);
+ gpu::SyncToken copy_done_sync_token;
+ gl_->GenSyncTokenCHROMIUM(copy_done_sync_token.GetData());
+ static_image->UpdateSyncToken(copy_done_sync_token);
+
// Cleanup the draw framebuffer, associated image and texture.
gl_->BindTexture(target, dest_texture_id);
gl_->ReleaseTexImage2DCHROMIUM(target, image_id);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gradient_generated_image.cc b/chromium/third_party/blink/renderer/platform/graphics/gradient_generated_image.cc
index f9fd7b25ee8..dbd7b216fc2 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gradient_generated_image.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gradient_generated_image.cc
@@ -54,7 +54,8 @@ void GradientGeneratedImage::Draw(cc::PaintCanvas* canvas,
}
void GradientGeneratedImage::DrawTile(GraphicsContext& context,
- const FloatRect& src_rect) {
+ const FloatRect& src_rect,
+ RespectImageOrientationEnum) {
// TODO(ccameron): This function should not ignore |context|'s color behavior.
// https://crbug.com/672306
PaintFlags gradient_flags(context.FillFlags());
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 66641fb359c..072a19c233b 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
@@ -59,7 +59,9 @@ class PLATFORM_EXPORT GradientGeneratedImage final : public GeneratedImage {
RespectImageOrientationEnum,
ImageClampingMode,
ImageDecodingMode) override;
- void DrawTile(GraphicsContext&, const FloatRect&) override;
+ void DrawTile(GraphicsContext&,
+ const FloatRect&,
+ RespectImageOrientationEnum) override;
GradientGeneratedImage(scoped_refptr<Gradient> generator,
const FloatSize& size)
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 3bf0b074a5b..8473a8d0f75 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_context.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_context.cc
@@ -58,6 +58,7 @@
#include "third_party/skia/include/effects/SkTableColorFilter.h"
#include "third_party/skia/include/pathops/SkPathOps.h"
#include "third_party/skia/include/utils/SkNullCanvas.h"
+#include "ui/base/ui_base_features.h"
namespace blink {
@@ -89,7 +90,6 @@ class GraphicsContext::DarkModeFlags final {
};
GraphicsContext::GraphicsContext(PaintController& paint_controller,
- DisabledMode disable_context_or_painting,
printing::MetafileSkia* metafile,
paint_preview::PaintPreviewTracker* tracker)
: canvas_(nullptr),
@@ -102,7 +102,6 @@ GraphicsContext::GraphicsContext(PaintController& paint_controller,
layer_count_(0),
disable_destruction_checks_(false),
#endif
- disabled_state_(disable_context_or_painting),
device_scale_factor_(1.0f),
printing_(false),
is_painting_preview_(false),
@@ -111,13 +110,6 @@ GraphicsContext::GraphicsContext(PaintController& paint_controller,
// allocate several here.
paint_state_stack_.push_back(std::make_unique<GraphicsContextState>());
paint_state_ = paint_state_stack_.back().get();
-
- if (ContextDisabled()) {
- DEFINE_STATIC_LOCAL(SkCanvas*, null_sk_canvas,
- (SkMakeNullCanvas().release()));
- DEFINE_STATIC_LOCAL(SkiaPaintCanvas, null_canvas, (null_sk_canvas));
- canvas_ = &null_canvas;
- }
}
GraphicsContext::~GraphicsContext() {
@@ -132,9 +124,6 @@ GraphicsContext::~GraphicsContext() {
}
void GraphicsContext::Save() {
- if (ContextDisabled())
- return;
-
paint_state_->IncrementSaveCount();
DCHECK(canvas_);
@@ -142,9 +131,6 @@ void GraphicsContext::Save() {
}
void GraphicsContext::Restore() {
- if (ContextDisabled())
- return;
-
if (!paint_state_index_ && !paint_state_->SaveCount()) {
DLOG(ERROR) << "ERROR void GraphicsContext::restore() stack is empty";
return;
@@ -179,19 +165,12 @@ void GraphicsContext::SetDarkMode(const DarkModeSettings& settings) {
}
void GraphicsContext::SaveLayer(const SkRect* bounds, const PaintFlags* flags) {
- if (ContextDisabled())
- return;
-
DCHECK(canvas_);
canvas_->saveLayer(bounds, flags);
}
void GraphicsContext::RestoreLayer() {
- if (ContextDisabled())
- return;
-
DCHECK(canvas_);
-
canvas_->restore();
}
@@ -201,6 +180,17 @@ void GraphicsContext::SetInDrawingRecorder(bool val) {
in_drawing_recorder_ = val;
}
+void GraphicsContext::SetDOMNodeId(DOMNodeId new_node_id) {
+ if (canvas_)
+ canvas_->setNodeId(new_node_id);
+
+ dom_node_id_ = new_node_id;
+}
+
+DOMNodeId GraphicsContext::GetDOMNodeId() const {
+ return dom_node_id_;
+}
+
void GraphicsContext::SetShadow(
const FloatSize& offset,
float blur,
@@ -208,9 +198,6 @@ void GraphicsContext::SetShadow(
DrawLooperBuilder::ShadowTransformMode shadow_transform_mode,
DrawLooperBuilder::ShadowAlphaMode shadow_alpha_mode,
ShadowMode shadow_mode) {
- if (ContextDisabled())
- return;
-
DrawLooperBuilder draw_looper_builder;
if (!color.Alpha()) {
// When shadow-only but there is no shadow, we use an empty draw looper
@@ -231,9 +218,6 @@ void GraphicsContext::SetShadow(
}
void GraphicsContext::SetDrawLooper(sk_sp<SkDrawLooper> draw_looper) {
- if (ContextDisabled())
- return;
-
MutableState()->SetDrawLooper(std::move(draw_looper));
}
@@ -253,11 +237,7 @@ void GraphicsContext::SetColorFilter(ColorFilter color_filter) {
}
void GraphicsContext::Concat(const SkMatrix& matrix) {
- if (ContextDisabled())
- return;
-
DCHECK(canvas_);
-
canvas_->concat(matrix);
}
@@ -266,9 +246,6 @@ void GraphicsContext::BeginLayer(float opacity,
const FloatRect* bounds,
ColorFilter color_filter,
sk_sp<PaintFilter> image_filter) {
- if (ContextDisabled())
- return;
-
PaintFlags layer_flags;
layer_flags.setAlpha(static_cast<unsigned char>(opacity * 255));
layer_flags.setBlendMode(xfermode);
@@ -288,9 +265,6 @@ void GraphicsContext::BeginLayer(float opacity,
}
void GraphicsContext::EndLayer() {
- if (ContextDisabled())
- return;
-
RestoreLayer();
#if DCHECK_IS_ON()
@@ -299,9 +273,6 @@ void GraphicsContext::EndLayer() {
}
void GraphicsContext::BeginRecording(const FloatRect& bounds) {
- if (ContextDisabled())
- return;
-
DCHECK(!canvas_);
canvas_ = paint_recorder_.beginRecording(bounds);
if (metafile_)
@@ -310,25 +281,7 @@ void GraphicsContext::BeginRecording(const FloatRect& bounds) {
canvas_->SetPaintPreviewTracker(tracker_);
}
-namespace {
-
-sk_sp<PaintRecord> CreateEmptyPaintRecord() {
- PaintRecorder recorder;
- recorder.beginRecording(SkRect::MakeEmpty());
- return recorder.finishRecordingAsPicture();
-}
-
-} // anonymous namespace
-
sk_sp<PaintRecord> GraphicsContext::EndRecording() {
- if (ContextDisabled()) {
- // Clients expect endRecording() to always return a non-null paint record.
- // Cache an empty one to minimize overhead when disabled.
- DEFINE_STATIC_LOCAL(const sk_sp<PaintRecord>, empty_paint_record,
- (CreateEmptyPaintRecord()));
- return empty_paint_record;
- }
-
sk_sp<PaintRecord> record = paint_recorder_.finishRecordingAsPicture();
canvas_ = nullptr;
DCHECK(record);
@@ -336,7 +289,7 @@ sk_sp<PaintRecord> GraphicsContext::EndRecording() {
}
void GraphicsContext::DrawRecord(sk_sp<const PaintRecord> record) {
- if (ContextDisabled() || !record || !record->size())
+ if (!record || !record->size())
return;
DCHECK(canvas_);
@@ -347,7 +300,7 @@ void GraphicsContext::CompositeRecord(sk_sp<PaintRecord> record,
const FloatRect& dest,
const FloatRect& src,
SkBlendMode op) {
- if (ContextDisabled() || !record)
+ if (!record)
return;
DCHECK(canvas_);
@@ -369,7 +322,16 @@ void GraphicsContext::CompositeRecord(sk_sp<PaintRecord> record,
namespace {
-int AdjustedFocusRingOffset(int offset, int width, bool is_outset) {
+int AdjustedFocusRingOffset(int offset,
+ int default_offset,
+ int width,
+ bool is_outset) {
+ if (::features::IsFormControlsRefreshEnabled()) {
+ // For FormControlsRefresh the focus ring has a default offset that
+ // depends on the element type.
+ return default_offset;
+ }
+
#if defined(OS_MACOSX)
return offset + 2;
#else
@@ -382,34 +344,45 @@ int AdjustedFocusRingOffset(int offset, int width, bool is_outset) {
} // namespace
int GraphicsContext::FocusRingOutsetExtent(int offset,
+ int default_offset,
int width,
bool is_outset) {
// 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 half of the width is outside of the offset.
- return AdjustedFocusRingOffset(offset, width, is_outset) + (width + 1) / 2;
+ if (::features::IsFormControlsRefreshEnabled()) {
+ // For FormControlsRefresh 2/3 of the width is outside of the offset.
+ return AdjustedFocusRingOffset(offset, default_offset, width, is_outset) +
+ std::ceil(width / 3.f) * 2;
+ }
+
+ return AdjustedFocusRingOffset(offset, /*default_offset=*/0, width,
+ is_outset) +
+ (width + 1) / 2;
}
void GraphicsContext::DrawFocusRingPath(const SkPath& path,
const Color& color,
- float width) {
+ float width,
+ float border_radius) {
DrawPlatformFocusRing(
path, canvas_,
dark_mode_filter_
.InvertColorIfNeeded(color, DarkModeFilter::ElementRole::kBackground)
.Rgb(),
- width);
+ width, border_radius);
}
void GraphicsContext::DrawFocusRingRect(const SkRect& rect,
const Color& color,
- float width) {
+ float width,
+ float border_radius) {
DrawPlatformFocusRing(
rect, canvas_,
dark_mode_filter_
.InvertColorIfNeeded(color, DarkModeFilter::ElementRole::kBackground)
.Rgb(),
- width);
+ width, border_radius);
}
void GraphicsContext::DrawFocusRing(const Path& focus_ring_path,
@@ -417,26 +390,27 @@ void GraphicsContext::DrawFocusRing(const Path& focus_ring_path,
int offset,
const Color& color) {
// FIXME: Implement support for offset.
- if (ContextDisabled())
- return;
-
- DrawFocusRingPath(focus_ring_path.GetSkPath(), color, width);
+ DrawFocusRingPath(focus_ring_path.GetSkPath(), color, /*width=*/width,
+ /*radius=*/width);
}
void GraphicsContext::DrawFocusRingInternal(const Vector<IntRect>& rects,
float width,
int offset,
+ float border_radius,
const Color& color,
bool is_outset) {
- if (ContextDisabled())
- return;
-
unsigned rect_count = rects.size();
if (!rect_count)
return;
SkRegion focus_ring_region;
- offset = AdjustedFocusRingOffset(offset, std::ceil(width), is_outset);
+ if (!::features::IsFormControlsRefreshEnabled()) {
+ // For FormControlsRefresh the offset is already adjusted by
+ // GraphicsContext::DrawFocusRing.
+ offset = AdjustedFocusRingOffset(offset, /*default_offset=*/0,
+ std::ceil(width), is_outset);
+ }
for (unsigned i = 0; i < rect_count; i++) {
SkIRect r = rects[i];
if (r.isEmpty())
@@ -449,12 +423,12 @@ void GraphicsContext::DrawFocusRingInternal(const Vector<IntRect>& rects,
return;
if (focus_ring_region.isRect()) {
- DrawFocusRingRect(SkRect::Make(focus_ring_region.getBounds()), color,
- width);
+ DrawFocusRingRect(SkRect::Make(focus_ring_region.getBounds()), color, width,
+ border_radius);
} else {
SkPath path;
if (focus_ring_region.getBoundaryPath(&path))
- DrawFocusRingPath(path, color, width);
+ DrawFocusRingPath(path, color, width, border_radius);
}
}
@@ -478,22 +452,48 @@ bool ShouldDrawInnerFocusRingForContrast(bool is_outset,
void GraphicsContext::DrawFocusRing(const Vector<IntRect>& rects,
float width,
int offset,
+ int default_offset,
+ float border_radius,
+ float min_border_width,
const Color& color,
bool is_outset) {
- // If a focus ring is outset and the color is dark, it may be hard to see on
- // dark backgrounds. In this case, we'll actually draw two focus rings, the
- // outset focus ring with a white inner ring for contrast.
- if (ShouldDrawInnerFocusRingForContrast(is_outset, width, color)) {
- int contrast_offset = static_cast<int>(std::floor(width * 0.5));
- // We create a 1px gap for the contrast ring. The contrast ring is drawn
- // first, and we overdraw by a pixel to ensure no gaps or AA artifacts.
- DrawFocusRingInternal(rects, contrast_offset, offset, SK_ColorWHITE,
- is_outset);
- DrawFocusRingInternal(rects, width - contrast_offset,
- offset + contrast_offset, color, is_outset);
-
+ 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;
+ const float second_border_width = width - first_border_width;
+
+ offset = AdjustedFocusRingOffset(offset, default_offset, std::ceil(width),
+ is_outset);
+ // How much space the focus ring would like to take from the actual border.
+ const float inside_border_width = 1;
+ 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
+ // artifacts.
+ DrawFocusRingInternal(rects, first_border_width,
+ offset + std::ceil(second_border_width),
+ border_radius, SK_ColorWHITE, is_outset);
+ DrawFocusRingInternal(rects, first_border_width, offset, border_radius,
+ color, is_outset);
} else {
- DrawFocusRingInternal(rects, width, offset, color, is_outset);
+ // If a focus ring is outset and the color is dark, it may be hard to see on
+ // dark backgrounds. In this case, we'll actually draw two focus rings, the
+ // outset focus ring with a white inner ring for contrast.
+ if (ShouldDrawInnerFocusRingForContrast(is_outset, width, color)) {
+ int contrast_offset = static_cast<int>(std::floor(width * 0.5));
+ // We create a 1px gap for the contrast ring. The contrast ring is drawn
+ // first, and we overdraw by a pixel to ensure no gaps or AA artifacts.
+ DrawFocusRingInternal(rects, contrast_offset, offset, border_radius,
+ SK_ColorWHITE, is_outset);
+ DrawFocusRingInternal(rects, width - contrast_offset,
+ offset + contrast_offset, border_radius, color,
+ is_outset);
+
+ } else {
+ DrawFocusRingInternal(rects, width, offset, border_radius, color,
+ is_outset);
+ }
}
}
@@ -520,9 +520,6 @@ void GraphicsContext::DrawInnerShadow(const FloatRoundedRect& rect,
float shadow_blur,
float shadow_spread,
Edges clipped_edges) {
- if (ContextDisabled())
- return;
-
Color shadow_color = dark_mode_filter_.InvertColorIfNeeded(
orig_shadow_color, DarkModeFilter::ElementRole::kBackground);
@@ -679,8 +676,6 @@ static void EnforceDotsAtEndpoints(GraphicsContext& context,
void GraphicsContext::DrawLine(const IntPoint& point1,
const IntPoint& point2,
const DarkModeFilter::ElementRole role) {
- if (ContextDisabled())
- return;
DCHECK(canvas_);
StrokeStyle pen_style = GetStrokeStyle();
@@ -728,9 +723,6 @@ void GraphicsContext::DrawLine(const IntPoint& point1,
}
void GraphicsContext::DrawLineForText(const FloatPoint& pt, float width) {
- if (ContextDisabled())
- return;
-
if (width <= 0)
return;
@@ -739,7 +731,7 @@ void GraphicsContext::DrawLineForText(const FloatPoint& pt, float width) {
case kNoStroke:
case kSolidStroke:
case kDoubleStroke: {
- int thickness = SkMax32(static_cast<int>(StrokeThickness()), 1);
+ int thickness = std::max(static_cast<int>(StrokeThickness()), 1);
SkRect r;
r.fLeft = WebCoreFloatToSkScalar(pt.X());
// Avoid anti-aliasing lines. Currently, these are always horizontal.
@@ -770,9 +762,6 @@ void GraphicsContext::DrawLineForText(const FloatPoint& pt, float width) {
// Draws a filled rectangle with a stroked border.
void GraphicsContext::DrawRect(const IntRect& rect) {
- if (ContextDisabled())
- return;
-
if (rect.IsEmpty())
return;
@@ -798,9 +787,6 @@ void GraphicsContext::DrawText(const Font& font,
const FloatPoint& point,
const PaintFlags& flags,
DOMNodeId node_id) {
- if (ContextDisabled())
- return;
-
font.DrawText(canvas_, text_info, point, device_scale_factor_, node_id,
DarkModeFlags(this, flags, DarkModeFilter::ElementRole::kText));
}
@@ -829,9 +815,6 @@ void GraphicsContext::DrawTextInternal(const Font& font,
const TextPaintInfo& text_info,
const FloatPoint& point,
DOMNodeId node_id) {
- if (ContextDisabled())
- return;
-
DrawTextPasses([&](const PaintFlags& flags) {
font.DrawText(
canvas_, text_info, point, device_scale_factor_, node_id,
@@ -858,9 +841,6 @@ void GraphicsContext::DrawEmphasisMarksInternal(const Font& font,
const TextPaintInfo& text_info,
const AtomicString& mark,
const FloatPoint& point) {
- if (ContextDisabled())
- return;
-
DrawTextPasses(
[&font, &text_info, &mark, &point, this](const PaintFlags& flags) {
font.DrawEmphasisMarks(
@@ -889,9 +869,6 @@ void GraphicsContext::DrawBidiText(
const TextRunPaintInfo& run_info,
const FloatPoint& point,
Font::CustomFontNotReadyAction custom_font_not_ready_action) {
- if (ContextDisabled())
- return;
-
DrawTextPasses([&font, &run_info, &point, custom_font_not_ready_action,
this](const PaintFlags& flags) {
if (font.DrawBidiText(
@@ -910,9 +887,6 @@ void GraphicsContext::DrawHighlightForText(const Font& font,
const Color& background_color,
int from,
int to) {
- if (ContextDisabled())
- return;
-
FillRect(font.SelectionRectForText(run, point, h, from, to),
background_color);
}
@@ -925,7 +899,7 @@ void GraphicsContext::DrawImage(
bool has_filter_property,
SkBlendMode op,
RespectImageOrientationEnum should_respect_image_orientation) {
- if (ContextDisabled() || !image)
+ if (!image)
return;
const FloatRect src = src_ptr ? *src_ptr : FloatRect(image->Rect());
@@ -952,7 +926,7 @@ void GraphicsContext::DrawImageRRect(
bool has_filter_property,
SkBlendMode op,
RespectImageOrientationEnum respect_orientation) {
- if (ContextDisabled() || !image)
+ if (!image)
return;
if (!dest.IsRounded()) {
@@ -978,7 +952,8 @@ void GraphicsContext::DrawImageRRect(
&image_flags);
bool use_shader = (visible_src == src_rect) &&
- (respect_orientation == kDoNotRespectImageOrientation);
+ (respect_orientation == kDoNotRespectImageOrientation ||
+ image->HasDefaultOrientation());
if (use_shader) {
const SkMatrix local_matrix = SkMatrix::MakeRectToRect(
visible_src, dest.Rect(), SkMatrix::kFill_ScaleToFit);
@@ -1026,62 +1001,52 @@ SkFilterQuality GraphicsContext::ComputeFilterQuality(
std::min(resampling, ImageInterpolationQuality()));
}
-void GraphicsContext::DrawImageTiled(Image* image,
- const FloatRect& dest_rect,
- const FloatRect& src_rect,
- const FloatSize& scale_src_to_dest,
- const FloatPoint& phase,
- const FloatSize& repeat_spacing,
- SkBlendMode op) {
- if (ContextDisabled() || !image)
+void GraphicsContext::DrawImageTiled(
+ Image* image,
+ const FloatRect& dest_rect,
+ const FloatRect& src_rect,
+ const FloatSize& scale_src_to_dest,
+ const FloatPoint& phase,
+ const FloatSize& repeat_spacing,
+ SkBlendMode op,
+ RespectImageOrientationEnum respect_orientation) {
+ if (!image)
return;
image->DrawPattern(*this, src_rect, scale_src_to_dest, phase, op, dest_rect,
- repeat_spacing);
+ repeat_spacing, respect_orientation);
paint_controller_.SetImagePainted();
}
void GraphicsContext::DrawOval(const SkRect& oval,
const PaintFlags& flags,
const DarkModeFilter::ElementRole role) {
- if (ContextDisabled())
- return;
DCHECK(canvas_);
-
canvas_->drawOval(oval, DarkModeFlags(this, flags, role));
}
void GraphicsContext::DrawPath(const SkPath& path,
const PaintFlags& flags,
const DarkModeFilter::ElementRole role) {
- if (ContextDisabled())
- return;
DCHECK(canvas_);
-
canvas_->drawPath(path, DarkModeFlags(this, flags, role));
}
void GraphicsContext::DrawRect(const SkRect& rect,
const PaintFlags& flags,
const DarkModeFilter::ElementRole role) {
- if (ContextDisabled())
- return;
DCHECK(canvas_);
-
canvas_->drawRect(rect, DarkModeFlags(this, flags, role));
}
void GraphicsContext::DrawRRect(const SkRRect& rrect, const PaintFlags& flags) {
- if (ContextDisabled())
- return;
DCHECK(canvas_);
-
canvas_->drawRRect(
rrect,
DarkModeFlags(this, flags, DarkModeFilter::ElementRole::kBackground));
}
void GraphicsContext::FillPath(const Path& path_to_fill) {
- if (ContextDisabled() || path_to_fill.IsEmpty())
+ if (path_to_fill.IsEmpty())
return;
DrawPath(path_to_fill.GetSkPath(), ImmutableState()->FillFlags());
@@ -1098,9 +1063,6 @@ void GraphicsContext::FillRect(const IntRect& rect,
}
void GraphicsContext::FillRect(const FloatRect& rect) {
- if (ContextDisabled())
- return;
-
DrawRect(rect, ImmutableState()->FillFlags());
}
@@ -1114,9 +1076,6 @@ void GraphicsContext::FillRect(const FloatRect& rect,
const Color& color,
SkBlendMode xfer_mode,
DarkModeFilter::ElementRole role) {
- if (ContextDisabled())
- return;
-
PaintFlags flags = ImmutableState()->FillFlags();
flags.setColor(color.Rgb());
flags.setBlendMode(xfer_mode);
@@ -1126,9 +1085,6 @@ void GraphicsContext::FillRect(const FloatRect& rect,
void GraphicsContext::FillRoundedRect(const FloatRoundedRect& rrect,
const Color& color) {
- if (ContextDisabled())
- return;
-
if (!rrect.IsRounded() || !rrect.IsRenderable()) {
FillRect(rrect.Rect(), color);
return;
@@ -1191,8 +1147,6 @@ bool IsSimpleDRRect(const FloatRoundedRect& outer,
void GraphicsContext::FillDRRect(const FloatRoundedRect& outer,
const FloatRoundedRect& inner,
const Color& color) {
- if (ContextDisabled())
- return;
DCHECK(canvas_);
if (!IsSimpleDRRect(outer, inner)) {
@@ -1227,16 +1181,13 @@ void GraphicsContext::FillDRRect(const FloatRoundedRect& outer,
}
void GraphicsContext::FillEllipse(const FloatRect& ellipse) {
- if (ContextDisabled())
- return;
-
DrawOval(ellipse, ImmutableState()->FillFlags());
}
void GraphicsContext::StrokePath(const Path& path_to_stroke,
const int length,
const int dash_thickness) {
- if (ContextDisabled() || path_to_stroke.IsEmpty())
+ if (path_to_stroke.IsEmpty())
return;
DrawPath(path_to_stroke.GetSkPath(),
@@ -1244,9 +1195,6 @@ void GraphicsContext::StrokePath(const Path& path_to_stroke,
}
void GraphicsContext::StrokeRect(const FloatRect& rect, float line_width) {
- if (ContextDisabled())
- return;
-
PaintFlags flags(ImmutableState()->StrokeFlags());
flags.setStrokeWidth(WebCoreFloatToSkScalar(line_width));
// Reset the dash effect to account for the width
@@ -1271,18 +1219,12 @@ void GraphicsContext::StrokeRect(const FloatRect& rect, float line_width) {
}
void GraphicsContext::StrokeEllipse(const FloatRect& ellipse) {
- if (ContextDisabled())
- return;
-
DrawOval(ellipse, ImmutableState()->StrokeFlags());
}
void GraphicsContext::ClipRoundedRect(const FloatRoundedRect& rrect,
SkClipOp clip_op,
AntiAliasingMode should_antialias) {
- if (ContextDisabled())
- return;
-
if (!rrect.IsRounded()) {
ClipRect(rrect.Rect(), should_antialias, clip_op);
return;
@@ -1292,9 +1234,6 @@ void GraphicsContext::ClipRoundedRect(const FloatRoundedRect& rrect,
}
void GraphicsContext::ClipOut(const Path& path_to_clip) {
- if (ContextDisabled())
- return;
-
// Use const_cast and temporarily toggle the inverse fill type instead of
// copying the path.
SkPath& path = const_cast<SkPath&>(path_to_clip.GetSkPath());
@@ -1304,54 +1243,37 @@ void GraphicsContext::ClipOut(const Path& path_to_clip) {
}
void GraphicsContext::ClipOutRoundedRect(const FloatRoundedRect& rect) {
- if (ContextDisabled())
- return;
-
ClipRoundedRect(rect, SkClipOp::kDifference);
}
void GraphicsContext::ClipRect(const SkRect& rect,
AntiAliasingMode aa,
SkClipOp op) {
- if (ContextDisabled())
- return;
DCHECK(canvas_);
-
canvas_->clipRect(rect, op, aa == kAntiAliased);
}
void GraphicsContext::ClipPath(const SkPath& path,
AntiAliasingMode aa,
SkClipOp op) {
- if (ContextDisabled())
- return;
DCHECK(canvas_);
-
canvas_->clipPath(path, op, aa == kAntiAliased);
}
void GraphicsContext::ClipRRect(const SkRRect& rect,
AntiAliasingMode aa,
SkClipOp op) {
- if (ContextDisabled())
- return;
DCHECK(canvas_);
-
canvas_->clipRRect(rect, op, aa == kAntiAliased);
}
void GraphicsContext::Rotate(float angle_in_radians) {
- if (ContextDisabled())
- return;
DCHECK(canvas_);
-
canvas_->rotate(
WebCoreFloatToSkScalar(angle_in_radians * (180.0f / 3.14159265f)));
}
void GraphicsContext::Translate(float x, float y) {
- if (ContextDisabled())
- return;
DCHECK(canvas_);
if (!x && !y)
@@ -1361,18 +1283,13 @@ void GraphicsContext::Translate(float x, float y) {
}
void GraphicsContext::Scale(float x, float y) {
- if (ContextDisabled())
- return;
DCHECK(canvas_);
-
canvas_->scale(WebCoreFloatToSkScalar(x), WebCoreFloatToSkScalar(y));
}
void GraphicsContext::SetURLForRect(const KURL& link,
const IntRect& dest_rect) {
- if (ContextDisabled())
- return;
- DCHECK(canvas_);
+ DCHECK(canvas_ || tracker_);
// Intercept URL rects when painting previews.
if (IsPaintingPreview() && tracker_) {
@@ -1387,9 +1304,7 @@ void GraphicsContext::SetURLForRect(const KURL& link,
void GraphicsContext::SetURLFragmentForRect(const String& dest_name,
const IntRect& rect) {
- if (ContextDisabled())
- return;
- DCHECK(canvas_);
+ DCHECK(canvas_ || tracker_);
// Intercept URL rects when painting previews.
if (IsPaintingPreview() && tracker_) {
@@ -1404,8 +1319,6 @@ void GraphicsContext::SetURLFragmentForRect(const String& dest_name,
void GraphicsContext::SetURLDestinationLocation(const String& name,
const IntPoint& location) {
- if (ContextDisabled())
- return;
DCHECK(canvas_);
SkRect rect = SkRect::MakeXYWH(location.X(), location.Y(), 0, 0);
@@ -1422,9 +1335,6 @@ void GraphicsContext::FillRectWithRoundedHole(
const FloatRect& rect,
const FloatRoundedRect& rounded_hole_rect,
const Color& color) {
- if (ContextDisabled())
- return;
-
PaintFlags flags(ImmutableState()->FillFlags());
flags.setColor(
dark_mode_filter_
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 b33ed07b357..6e943b9810e 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_context.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_context.h
@@ -70,14 +70,7 @@ class PLATFORM_EXPORT GraphicsContext {
USING_FAST_MALLOC(GraphicsContext);
public:
- enum DisabledMode {
- kNothingDisabled = 0, // Run as normal.
- kFullyDisabled = 1 // Do absolutely minimal work to remove the cost of
- // the context from performance tests.
- };
-
explicit GraphicsContext(PaintController&,
- DisabledMode = kNothingDisabled,
printing::MetafileSkia* = nullptr,
paint_preview::PaintPreviewTracker* = nullptr);
@@ -91,8 +84,6 @@ class PLATFORM_EXPORT GraphicsContext {
return paint_controller_;
}
- bool ContextDisabled() const { return disabled_state_; }
-
const DarkModeSettings& dark_mode_settings() const {
return dark_mode_filter_.settings();
}
@@ -242,22 +233,22 @@ class PLATFORM_EXPORT GraphicsContext {
const FloatRect* src_rect = nullptr,
bool has_filter_property = false,
SkBlendMode = SkBlendMode::kSrcOver,
- RespectImageOrientationEnum = kDoNotRespectImageOrientation);
- void DrawImageRRect(
- Image*,
- Image::ImageDecodingMode,
- const FloatRoundedRect& dest,
- const FloatRect& src_rect,
- bool has_filter_property = false,
- SkBlendMode = SkBlendMode::kSrcOver,
- RespectImageOrientationEnum = kDoNotRespectImageOrientation);
+ RespectImageOrientationEnum = kRespectImageOrientation);
+ void DrawImageRRect(Image*,
+ Image::ImageDecodingMode,
+ const FloatRoundedRect& dest,
+ const FloatRect& src_rect,
+ bool has_filter_property = false,
+ SkBlendMode = SkBlendMode::kSrcOver,
+ RespectImageOrientationEnum = kRespectImageOrientation);
void DrawImageTiled(Image* image,
const FloatRect& dest_rect,
const FloatRect& src_rect,
const FloatSize& scale_src_to_dest,
const FloatPoint& phase,
const FloatSize& repeat_spacing,
- SkBlendMode = SkBlendMode::kSrcOver);
+ SkBlendMode = SkBlendMode::kSrcOver,
+ RespectImageOrientationEnum = kRespectImageOrientation);
// These methods write to the canvas.
// Also drawLine(const IntPoint& point1, const IntPoint& point2) and
@@ -371,6 +362,9 @@ class PLATFORM_EXPORT GraphicsContext {
void DrawFocusRing(const Vector<IntRect>&,
float width,
int offset,
+ int default_offset,
+ float border_radius,
+ float min_border_width,
const Color&,
bool is_outset);
void DrawFocusRing(const Path&, float width, int offset, const Color&);
@@ -428,14 +422,25 @@ class PLATFORM_EXPORT GraphicsContext {
FloatPoint& p2,
float stroke_width);
- static int FocusRingOutsetExtent(int offset, int width, bool is_outset);
+ static int FocusRingOutsetExtent(int offset,
+ int default_offset,
+ int width,
+ bool is_outset);
void SetInDrawingRecorder(bool);
bool InDrawingRecorder() const { return in_drawing_recorder_; }
+ // Set the DOM Node Id on the canvas. This is used to associate
+ // the drawing commands with the structure tree for the page when
+ // creating a tagged PDF. Callers are responsible for restoring it.
+ void SetDOMNodeId(DOMNodeId);
+ DOMNodeId GetDOMNodeId() const;
+
static sk_sp<SkColorFilter> WebCoreColorFilterToSkiaColorFilter(ColorFilter);
private:
+ friend class ScopedDarkModeElementRoleOverride;
+
const GraphicsContextState* ImmutableState() const { return paint_state_; }
GraphicsContextState* MutableState() {
@@ -462,12 +467,19 @@ class PLATFORM_EXPORT GraphicsContext {
void RestoreLayer();
// Helpers for drawing a focus ring (drawFocusRing)
- void DrawFocusRingPath(const SkPath&, const Color&, float width);
- void DrawFocusRingRect(const SkRect&, const Color&, float width);
+ void DrawFocusRingPath(const SkPath&,
+ const Color&,
+ float width,
+ float border_radius);
+ void DrawFocusRingRect(const SkRect&,
+ const Color&,
+ float width,
+ float border_radius);
void DrawFocusRingInternal(const Vector<IntRect>&,
float width,
int offset,
+ float border_radius,
const Color&,
bool is_outset);
@@ -479,9 +491,6 @@ class PLATFORM_EXPORT GraphicsContext {
// Apply deferred paint state saves
void RealizePaintSave() {
- if (ContextDisabled())
- return;
-
if (paint_state_->SaveCount()) {
paint_state_->DecrementSaveCount();
++paint_state_index_;
@@ -503,7 +512,9 @@ class PLATFORM_EXPORT GraphicsContext {
class DarkModeFlags;
- // null indicates painting is contextDisabled. Never delete this object.
+ // This is owned by paint_recorder_. Never delete this object.
+ // Drawing operations are allowed only after the first BeginRecording() which
+ // initializes this to not null.
cc::PaintCanvas* canvas_;
PaintController& paint_controller_;
@@ -529,8 +540,6 @@ class PLATFORM_EXPORT GraphicsContext {
bool disable_destruction_checks_;
#endif
- const DisabledMode disabled_state_;
-
float device_scale_factor_;
// TODO(gilmanmh): Investigate making this base::Optional<DarkModeFilter>
@@ -540,6 +549,9 @@ class PLATFORM_EXPORT GraphicsContext {
unsigned is_painting_preview_ : 1;
unsigned in_drawing_recorder_ : 1;
+ // The current node ID, which is used for marked content in a tagged PDF.
+ DOMNodeId dom_node_id_ = kInvalidDOMNodeId;
+
DISALLOW_COPY_AND_ASSIGN(GraphicsContext);
};
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 7f39c9e8911..8cafc6b08ac 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.cc
@@ -37,9 +37,7 @@
#include "cc/layers/picture_layer.h"
#include "cc/paint/display_item_list.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_float_point.h"
#include "third_party/blink/public/platform/web_float_rect.h"
-#include "third_party/blink/public/platform/web_point.h"
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/geometry/geometry_as_json.h"
@@ -76,12 +74,18 @@ GraphicsLayer::GraphicsLayer(GraphicsLayerClient& client)
contents_visible_(true),
hit_testable_(false),
needs_check_raster_invalidation_(false),
+ contents_layer_is_picture_image_layer_(false),
painted_(false),
painting_phase_(kGraphicsLayerPaintAllWithOverflowClip),
parent_(nullptr),
mask_layer_(nullptr),
- contents_layer_(nullptr),
- contents_layer_id_(0) {
+ raster_invalidation_function_(
+ base::BindRepeating(&GraphicsLayer::SetNeedsDisplayInRect,
+ base::Unretained(this))) {
+ // TODO(crbug.com/1033240): Debugging information for the referenced bug.
+ // Remove when it is fixed.
+ CHECK(&client_);
+
#if DCHECK_IS_ON()
DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
client.VerifyNotPainting();
@@ -95,7 +99,7 @@ GraphicsLayer::GraphicsLayer(GraphicsLayerClient& client)
GraphicsLayer::~GraphicsLayer() {
CcLayer()->ClearClient();
- SetContentsLayer(nullptr);
+ contents_layer_ = nullptr;
#if DCHECK_IS_ON()
client_.VerifyNotPainting();
@@ -125,10 +129,12 @@ void GraphicsLayer::AppendAdditionalInfoAsJSON(LayerTreeFlags flags,
if (&layer != layer_.get())
return;
- if ((flags & kLayerTreeIncludesPaintInvalidations) &&
+ if ((flags & (kLayerTreeIncludesInvalidations |
+ kLayerTreeIncludesDetailedInvalidations)) &&
Client().IsTrackingRasterInvalidations() &&
GetRasterInvalidationTracking()) {
- GetRasterInvalidationTracking()->AsJSON(&json);
+ GetRasterInvalidationTracking()->AsJSON(
+ &json, flags & kLayerTreeIncludesDetailedInvalidations);
}
GraphicsLayerPaintingPhase painting_phase = PaintingPhase();
@@ -206,11 +212,10 @@ bool GraphicsLayer::SetChildren(const GraphicsLayerVector& new_children) {
RemoveAllChildren();
- size_t list_size = new_children.size();
- for (size_t i = 0; i < list_size; ++i)
- AddChildInternal(new_children[i]);
+ for (auto* new_child : new_children)
+ AddChildInternal(new_child);
- UpdateChildList();
+ NotifyChildListChange();
return true;
}
@@ -224,13 +229,13 @@ void GraphicsLayer::AddChildInternal(GraphicsLayer* child_layer) {
child_layer->SetParent(this);
children_.push_back(child_layer);
- // Don't call updateChildList here, this function is used in cases where it
- // should not be called until all children are processed.
+ // Don't call NotifyChildListChange here, this function is used in cases where
+ // it should not be called until all children are processed.
}
void GraphicsLayer::AddChild(GraphicsLayer* child_layer) {
AddChildInternal(child_layer);
- UpdateChildList();
+ NotifyChildListChange();
}
void GraphicsLayer::RemoveAllChildren() {
@@ -258,8 +263,6 @@ void GraphicsLayer::SetOffsetFromLayoutObject(const IntSize& offset) {
return;
offset_from_layout_object_ = offset;
- CcLayer()->SetFiltersOrigin(FloatPoint() -
- FloatSize(offset_from_layout_object_));
// If the compositing layer offset changes, we need to repaint.
SetNeedsDisplay();
@@ -287,6 +290,9 @@ bool GraphicsLayer::PaintRecursively() {
void GraphicsLayer::PaintRecursivelyInternal(
Vector<GraphicsLayer*>& repainted_layers) {
+ // TODO(crbug.com/1033240): Debugging information for the referenced bug.
+ // Remove when it is fixed.
+ CHECK(&client_);
if (client_.PaintBlockedByDisplayLockIncludingAncestors(
DisplayLockContextLifecycleTarget::kSelf)) {
return;
@@ -304,7 +310,7 @@ void GraphicsLayer::PaintRecursivelyInternal(
child->PaintRecursivelyInternal(repainted_layers);
}
-bool GraphicsLayer::Paint(GraphicsContext::DisabledMode disabled_mode) {
+bool GraphicsLayer::Paint() {
#if !DCHECK_IS_ON()
// TODO(crbug.com/853096): Investigate why we can ever reach here without
// a valid layer state. Seems to only happen on Android builds.
@@ -312,7 +318,7 @@ bool GraphicsLayer::Paint(GraphicsContext::DisabledMode disabled_mode) {
return false;
#endif
- if (PaintWithoutCommit(disabled_mode)) {
+ if (PaintWithoutCommit()) {
GetPaintController().CommitNewDisplayItems();
UpdateSafeOpaqueBackgroundColor();
} else if (!needs_check_raster_invalidation_) {
@@ -330,6 +336,7 @@ bool GraphicsLayer::Paint(GraphicsContext::DisabledMode disabled_mode) {
// Generate raster invalidations for SPv1.
IntRect layer_bounds(layer_state_->offset, IntSize(Size()));
EnsureRasterInvalidator().Generate(
+ raster_invalidation_function_,
GetPaintController().GetPaintArtifactShared(), layer_bounds,
layer_state_->state, VisualRectSubpixelOffset(), this);
@@ -354,21 +361,17 @@ bool GraphicsLayer::Paint(GraphicsContext::DisabledMode disabled_mode) {
void GraphicsLayer::UpdateSafeOpaqueBackgroundColor() {
if (!DrawsContent())
return;
- // Copy the first chunk's safe opaque background color over to the cc::Layer.
- const auto& chunks = GetPaintController().GetPaintArtifact().PaintChunks();
CcLayer()->SetSafeOpaqueBackgroundColor(
- chunks.size() ? chunks[0].safe_opaque_background_color : SK_ColorWHITE);
+ GetPaintController().GetPaintArtifact().SafeOpaqueBackgroundColor(
+ GetPaintController().GetPaintArtifact().PaintChunks()));
}
bool GraphicsLayer::PaintWithoutCommitForTesting(
const base::Optional<IntRect>& interest_rect) {
- return PaintWithoutCommit(GraphicsContext::kNothingDisabled,
- base::OptionalOrNullptr(interest_rect));
+ return PaintWithoutCommit(base::OptionalOrNullptr(interest_rect));
}
-bool GraphicsLayer::PaintWithoutCommit(
- GraphicsContext::DisabledMode disabled_mode,
- const IntRect* interest_rect) {
+bool GraphicsLayer::PaintWithoutCommit(const IntRect* interest_rect) {
DCHECK(PaintsContentOrHitTest());
if (client_.ShouldThrottleRendering() || client_.IsUnderSVGHiddenContainer())
@@ -381,7 +384,7 @@ bool GraphicsLayer::PaintWithoutCommit(
interest_rect = &new_interest_rect;
}
- if (!GetPaintController().SubsequenceCachingIsDisabled() &&
+ if (!GetPaintController().ShouldForcePaintForBenchmark() &&
!client_.NeedsRepaint(*this) &&
!GetPaintController().CacheIsAllInvalid() &&
previous_interest_rect_ == *interest_rect) {
@@ -389,9 +392,9 @@ bool GraphicsLayer::PaintWithoutCommit(
return false;
}
- GraphicsContext context(GetPaintController(), disabled_mode, nullptr);
+ GraphicsContext context(GetPaintController());
DCHECK(layer_state_) << "No layer state for GraphicsLayer: " << DebugName();
- GetPaintController().UpdateCurrentPaintChunkProperties(base::nullopt,
+ GetPaintController().UpdateCurrentPaintChunkProperties(nullptr,
layer_state_->state);
previous_interest_rect_ = *interest_rect;
@@ -399,7 +402,7 @@ bool GraphicsLayer::PaintWithoutCommit(
return true;
}
-void GraphicsLayer::UpdateChildList() {
+void GraphicsLayer::NotifyChildListChange() {
// cc::Layers are created in PaintArtifactCompositor.
client_.GraphicsLayersDidChange();
}
@@ -412,125 +415,56 @@ void GraphicsLayer::UpdateLayerIsDrawable() {
// contentsVisible.
CcLayer()->SetIsDrawable(draws_content_ && contents_visible_);
- if (cc::Layer* contents_layer = ContentsLayerIfRegistered())
- contents_layer->SetIsDrawable(contents_visible_);
+ if (contents_layer_)
+ contents_layer_->SetIsDrawable(contents_visible_);
if (draws_content_)
CcLayer()->SetNeedsDisplay();
}
-void GraphicsLayer::UpdateContentsRect() {
- cc::Layer* contents_layer = ContentsLayerIfRegistered();
- if (!contents_layer)
+void GraphicsLayer::UpdateContentsLayerBounds() {
+ if (!contents_layer_)
return;
- contents_layer->SetPosition(
- FloatPoint(contents_rect_.X(), contents_rect_.Y()));
- if (!image_layer_) {
- contents_layer->SetBounds(static_cast<gfx::Size>(contents_rect_.Size()));
- } else {
- DCHECK_EQ(image_layer_.get(), contents_layer_);
- // The image_layer_ has fixed bounds, and we apply bounds changes via the
- // transform instead. Since we never change the transform on the
- // |image_layer_| otherwise, we can assume it is identity and just apply
- // the bounds to it directly. Same thing for transform origin.
- DCHECK(image_layer_->transform_origin() == gfx::Point3F());
-
- if (contents_rect_.Size().IsEmpty() || image_size_.IsEmpty()) {
- image_layer_->SetTransform(gfx::Transform());
- contents_layer->SetBounds(static_cast<gfx::Size>(contents_rect_.Size()));
- } else {
- gfx::Transform image_transform;
- image_transform.Scale(
- static_cast<float>(contents_rect_.Width()) / image_size_.Width(),
- static_cast<float>(contents_rect_.Height()) / image_size_.Height());
- image_layer_->SetTransform(image_transform);
- image_layer_->SetBounds(static_cast<gfx::Size>(image_size_));
- }
+ IntSize contents_size = contents_rect_.Size();
+ if (contents_layer_is_picture_image_layer_) {
+ if (!contents_size.IsEmpty() && !image_size_.IsEmpty())
+ contents_size = image_size_;
}
+ contents_layer_->SetBounds(gfx::Size(contents_size));
}
-static HashSet<int>* g_registered_layer_set;
-
-void GraphicsLayer::RegisterContentsLayer(cc::Layer* layer) {
- if (!g_registered_layer_set)
- g_registered_layer_set = new HashSet<int>;
- CHECK(!g_registered_layer_set->Contains(layer->id()));
- g_registered_layer_set->insert(layer->id());
-}
-
-void GraphicsLayer::UnregisterContentsLayer(cc::Layer* layer) {
- DCHECK(g_registered_layer_set);
- CHECK(g_registered_layer_set->Contains(layer->id()));
- g_registered_layer_set->erase(layer->id());
+void GraphicsLayer::SetContentsToCcLayer(
+ scoped_refptr<cc::Layer> contents_layer,
+ bool prevent_contents_opaque_changes) {
+ DCHECK_NE(contents_layer, layer_);
+ SetContentsTo(std::move(contents_layer), prevent_contents_opaque_changes);
+ contents_layer_is_picture_image_layer_ = false;
}
-void GraphicsLayer::SetContentsTo(cc::Layer* layer,
+void GraphicsLayer::SetContentsTo(scoped_refptr<cc::Layer> layer,
bool prevent_contents_opaque_changes) {
- bool children_changed = false;
if (layer) {
- DCHECK(g_registered_layer_set);
- CHECK(g_registered_layer_set->Contains(layer->id()));
- if (contents_layer_id_ != layer->id()) {
- SetupContentsLayer(layer);
- children_changed = true;
+ if (contents_layer_ != layer) {
+ contents_layer_ = std::move(layer);
+ // It is necessary to call SetDrawsContent() as soon as we receive the new
+ // contents_layer, for the correctness of early exit conditions in
+ // SetDrawsContent() and SetContentsVisible().
+ contents_layer_->SetIsDrawable(contents_visible_);
+ contents_layer_->SetHitTestable(contents_visible_);
+ NotifyChildListChange();
}
- UpdateContentsRect();
+ UpdateContentsLayerBounds();
prevent_contents_opaque_changes_ = prevent_contents_opaque_changes;
- } else {
- if (contents_layer_) {
- children_changed = true;
-
- // The old contents layer will be removed via updateChildList.
- SetContentsLayer(nullptr);
- }
+ } else if (contents_layer_) {
+ contents_layer_ = nullptr;
+ NotifyChildListChange();
}
-
- if (children_changed)
- UpdateChildList();
-}
-
-void GraphicsLayer::SetupContentsLayer(cc::Layer* contents_layer) {
- DCHECK(contents_layer);
- SetContentsLayer(contents_layer);
-
- contents_layer_->SetTransformOrigin(FloatPoint3D());
- contents_layer_->SetUseParentBackfaceVisibility(true);
-
- // It is necessary to call SetDrawsContent() as soon as we receive the new
- // contents_layer, for the correctness of early exit conditions in
- // SetDrawsContent() and SetContentsVisible().
- contents_layer_->SetIsDrawable(contents_visible_);
- contents_layer_->SetHitTestable(contents_visible_);
-}
-
-void GraphicsLayer::ClearContentsLayerIfUnregistered() {
- if (!contents_layer_id_ ||
- g_registered_layer_set->Contains(contents_layer_id_))
- return;
-
- SetContentsLayer(nullptr);
-}
-
-void GraphicsLayer::SetContentsLayer(cc::Layer* contents_layer) {
- contents_layer_ = contents_layer;
- if (!contents_layer_) {
- contents_layer_id_ = 0;
- return;
- }
- contents_layer_id_ = contents_layer_->id();
-}
-
-cc::Layer* GraphicsLayer::ContentsLayerIfRegistered() {
- ClearContentsLayerIfUnregistered();
- return contents_layer_;
}
RasterInvalidator& GraphicsLayer::EnsureRasterInvalidator() {
if (!raster_invalidator_) {
- raster_invalidator_ =
- std::make_unique<RasterInvalidator>(base::BindRepeating(
- &GraphicsLayer::SetNeedsDisplayInRect, base::Unretained(this)));
+ raster_invalidator_ = std::make_unique<RasterInvalidator>();
raster_invalidator_->SetTracksRasterInvalidations(
client_.IsTrackingRasterInvalidations());
}
@@ -575,7 +509,7 @@ void GraphicsLayer::TrackRasterInvalidation(const DisplayItemClient& client,
}
String GraphicsLayer::DebugName(const cc::Layer* layer) const {
- if (layer->id() == contents_layer_id_)
+ if (layer == contents_layer_.get())
return "ContentsLayer for " + client_.DebugName(this);
if (layer == layer_.get())
@@ -601,15 +535,6 @@ void GraphicsLayer::SetSize(const gfx::Size& size) {
// Note that we don't resize m_contentsLayer. It's up the caller to do that.
}
-
-bool GraphicsLayer::MasksToBounds() const {
- return CcLayer()->masks_to_bounds();
-}
-
-void GraphicsLayer::SetMasksToBounds(bool masks_to_bounds) {
- CcLayer()->SetMasksToBounds(masks_to_bounds);
-}
-
void GraphicsLayer::SetDrawsContent(bool draws_content) {
// NOTE: This early-exit is only correct because we also properly call
// cc::Layer::SetIsDrawable() whenever |contents_layer_| is set to a new
@@ -651,7 +576,6 @@ bool GraphicsLayer::ContentsOpaque() const {
void GraphicsLayer::SetContentsOpaque(bool opaque) {
CcLayer()->SetContentsOpaque(opaque);
- ClearContentsLayerIfUnregistered();
if (contents_layer_ && !prevent_contents_opaque_changes_)
contents_layer_->SetContentsOpaque(opaque);
}
@@ -675,8 +599,8 @@ void GraphicsLayer::SetHitTestable(bool should_hit_test) {
}
void GraphicsLayer::SetContentsNeedsDisplay() {
- if (cc::Layer* contents_layer = ContentsLayerIfRegistered()) {
- contents_layer->SetNeedsDisplay();
+ if (contents_layer_) {
+ contents_layer_->SetNeedsDisplay();
TrackRasterInvalidation(*this, contents_rect_,
PaintInvalidationReason::kFullLayer);
}
@@ -710,7 +634,7 @@ void GraphicsLayer::SetContentsRect(const IntRect& rect) {
return;
contents_rect_ = rect;
- UpdateContentsRect();
+ UpdateContentsLayerBounds();
client_.GraphicsLayersDidChange();
}
@@ -724,16 +648,17 @@ void GraphicsLayer::SetContentsToImage(
ImageOrientation image_orientation = kOriginTopLeft;
SkMatrix matrix;
- if (paint_image && image->IsBitmapImage() &&
+ auto* bitmap_image = DynamicTo<BitmapImage>(image);
+ if (paint_image && bitmap_image &&
respect_image_orientation == kRespectImageOrientation) {
- image_orientation = ToBitmapImage(image)->CurrentFrameOrientation();
+ image_orientation = bitmap_image->CurrentFrameOrientation();
image_size_ = IntSize(paint_image.width(), paint_image.height());
if (image_orientation.UsesWidthAsHeight())
image_size_ = image_size_.TransposedSize();
auto affine =
image_orientation.TransformFromDefault(FloatSize(image_size_));
auto transform = affine.ToTransformationMatrix();
- matrix = TransformationMatrix::ToSkMatrix44(transform);
+ matrix = SkMatrix(TransformationMatrix::ToSkMatrix44(transform));
} else if (paint_image) {
matrix = SkMatrix::I();
image_size_ = IntSize(paint_image.width(), paint_image.height());
@@ -742,27 +667,28 @@ void GraphicsLayer::SetContentsToImage(
image_size_ = IntSize();
}
+ scoped_refptr<cc::PictureImageLayer> image_layer;
if (paint_image) {
paint_image =
PaintImageBuilder::WithCopy(std::move(paint_image))
.set_decoding_mode(Image::ToPaintImageDecodingMode(decode_mode))
.TakePaintImage();
- if (!image_layer_) {
- image_layer_ = cc::PictureImageLayer::Create();
- RegisterContentsLayer(image_layer_.get());
+ if (!contents_layer_is_picture_image_layer_) {
+ image_layer = cc::PictureImageLayer::Create();
+ contents_layer_is_picture_image_layer_ = true;
+ } else {
+ image_layer = static_cast<cc::PictureImageLayer*>(contents_layer_.get());
}
- image_layer_->SetImage(std::move(paint_image), matrix,
- image_orientation.UsesWidthAsHeight());
+ image_layer->SetImage(std::move(paint_image), matrix,
+ image_orientation.UsesWidthAsHeight());
// Image layers can not be marked as opaque due to crbug.com/870857.
- image_layer_->SetContentsOpaque(false);
- UpdateContentsRect();
- } else if (image_layer_) {
- UnregisterContentsLayer(image_layer_.get());
- image_layer_ = nullptr;
+ image_layer->SetContentsOpaque(false);
+ } else {
+ contents_layer_is_picture_image_layer_ = false;
}
- SetContentsTo(image_layer_.get(),
- /*prevent_contents_opaque_changes=*/true);
+ SetContentsTo(std::move(image_layer),
+ /* prevent_contents_opaque_changes=*/true);
}
cc::PictureLayer* GraphicsLayer::CcLayer() const {
@@ -770,8 +696,10 @@ cc::PictureLayer* GraphicsLayer::CcLayer() const {
}
void GraphicsLayer::SetFilterQuality(SkFilterQuality filter_quality) {
- if (image_layer_)
- image_layer_->SetNearestNeighbor(filter_quality == kNone_SkFilterQuality);
+ if (contents_layer_is_picture_image_layer_) {
+ static_cast<cc::PictureImageLayer*>(contents_layer_.get())
+ ->SetNearestNeighbor(filter_quality == kNone_SkFilterQuality);
+ }
}
void GraphicsLayer::SetPaintingPhase(GraphicsLayerPaintingPhase phase) {
@@ -857,35 +785,24 @@ scoped_refptr<cc::DisplayItemList> GraphicsLayer::PaintContentsToDisplayList(
PaintingControlSetting painting_control) {
TRACE_EVENT0("blink,benchmark", "GraphicsLayer::PaintContents");
- PaintController& paint_controller = GetPaintController();
- paint_controller.SetDisplayItemConstructionIsDisabled(
- painting_control == DISPLAY_LIST_CONSTRUCTION_DISABLED);
- paint_controller.SetSubsequenceCachingIsDisabled(
- painting_control == SUBSEQUENCE_CACHING_DISABLED);
-
- if (painting_control == PARTIAL_INVALIDATION)
- client_.InvalidateTargetElementForTesting();
+ if (painting_control == SUBSEQUENCE_CACHING_DISABLED)
+ PaintController::SetSubsequenceCachingDisabledForBenchmark();
+ else if (painting_control == PARTIAL_INVALIDATION)
+ PaintController::SetPartialInvalidationForBenchmark();
+ PaintController& paint_controller = GetPaintController();
// We also disable caching when Painting or Construction are disabled. In both
// cases we would like to compare assuming the full cost of recording, not the
// cost of re-using cached content.
- if (painting_control == DISPLAY_LIST_CACHING_DISABLED ||
- painting_control == DISPLAY_LIST_PAINTING_DISABLED ||
- painting_control == DISPLAY_LIST_CONSTRUCTION_DISABLED)
+ if (painting_control == DISPLAY_LIST_CACHING_DISABLED)
paint_controller.InvalidateAll();
- GraphicsContext::DisabledMode disabled_mode =
- GraphicsContext::kNothingDisabled;
- if (painting_control == DISPLAY_LIST_PAINTING_DISABLED ||
- painting_control == DISPLAY_LIST_CONSTRUCTION_DISABLED)
- disabled_mode = GraphicsContext::kFullyDisabled;
-
// Anything other than PAINTING_BEHAVIOR_NORMAL is for testing. In non-testing
// scenarios, it is an error to call GraphicsLayer::Paint. Actual painting
// occurs in LocalFrameView::PaintTree() which calls GraphicsLayer::Paint();
// this method merely copies the painted output to the cc::DisplayItemList.
if (painting_control != PAINTING_BEHAVIOR_NORMAL)
- Paint(disabled_mode);
+ Paint();
auto display_list = base::MakeRefCounted<cc::DisplayItemList>();
@@ -896,8 +813,7 @@ scoped_refptr<cc::DisplayItemList> GraphicsLayer::PaintContentsToDisplayList(
VisualRectSubpixelOffset(),
paint_controller.GetPaintArtifact().GetDisplayItemList(), *display_list);
- paint_controller.SetDisplayItemConstructionIsDisabled(false);
- paint_controller.SetSubsequenceCachingIsDisabled(false);
+ PaintController::ClearFlagsForBenchmark();
display_list->Finalize();
return display_list;
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 269eb43a3ef..14ed1bad11b 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.h
@@ -47,6 +47,7 @@
#include "third_party/blink/renderer/platform/graphics/image_orientation.h"
#include "third_party/blink/renderer/platform/graphics/paint/display_item_client.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
+#include "third_party/blink/renderer/platform/graphics/paint/raster_invalidator.h"
#include "third_party/blink/renderer/platform/graphics/paint_invalidation_reason.h"
#include "third_party/blink/renderer/platform/graphics/squashing_disallowed_reasons.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
@@ -57,7 +58,6 @@
#include "third_party/skia/include/core/SkRefCnt.h"
namespace cc {
-class PictureImageLayer;
class PictureLayer;
} // namespace cc
@@ -127,15 +127,12 @@ class PLATFORM_EXPORT GraphicsLayer : public DisplayItemClient,
void SetRenderingContext(int id);
- bool MasksToBounds() const;
- void SetMasksToBounds(bool);
-
bool DrawsContent() const { return draws_content_; }
void SetDrawsContent(bool);
- // False if no hit test display items will be painted onto this GraphicsLayer.
- // This is different from |DrawsContent| because hit test display items are
- // internal to blink and are not copied to the cc::Layer's display list.
+ // False if no hit test data will be recorded onto this GraphicsLayer.
+ // This is different from |DrawsContent| because hit test data are internal
+ // to blink and are not copied to the cc::Layer's display list.
bool PaintsHitTest() const { return paints_hit_test_; }
void SetPaintsHitTest(bool paints) { paints_hit_test_ = paints; }
@@ -177,19 +174,15 @@ class PLATFORM_EXPORT GraphicsLayer : public DisplayItemClient,
void SetContentsToImage(
Image*,
Image::ImageDecodingMode decode_mode,
- RespectImageOrientationEnum = kDoNotRespectImageOrientation);
+ RespectImageOrientationEnum = kRespectImageOrientation);
// If |prevent_contents_opaque_changes| is set to true, then calls to
- // SetContentsOpaque() will not be passed on to the |layer|. Use when
- // the client wants to have control of the opaqueness of the contents
- // |layer| independently of what outcome painting produces.
- void SetContentsToCcLayer(cc::Layer* layer,
- bool prevent_contents_opaque_changes) {
- SetContentsTo(layer, prevent_contents_opaque_changes);
- }
+ // SetContentsOpaque() will not be passed on to |contents_layer|. Use when
+ // the client wants to have control of the opaqueness of |contents_layer|
+ // independently of what outcome painting produces.
+ void SetContentsToCcLayer(scoped_refptr<cc::Layer> contents_layer,
+ bool prevent_contents_opaque_changes);
bool HasContentsLayer() const { return ContentsLayer(); }
- cc::Layer* ContentsLayer() const {
- return const_cast<GraphicsLayer*>(this)->ContentsLayerIfRegistered();
- }
+ cc::Layer* ContentsLayer() const { return contents_layer_.get(); }
const IntRect& ContentsRect() const { return contents_rect_; }
@@ -204,13 +197,10 @@ class PLATFORM_EXPORT GraphicsLayer : public DisplayItemClient,
const IntRect&,
PaintInvalidationReason);
- static void RegisterContentsLayer(cc::Layer*);
- static void UnregisterContentsLayer(cc::Layer*);
-
IntRect InterestRect();
bool PaintRecursively();
// Returns true if this layer is repainted.
- bool Paint(GraphicsContext::DisabledMode = GraphicsContext::kNothingDisabled);
+ bool Paint();
PaintController& GetPaintController() const;
@@ -275,12 +265,10 @@ class PLATFORM_EXPORT GraphicsLayer : public DisplayItemClient,
void UpdateSafeOpaqueBackgroundColor();
// Returns true if PaintController::PaintArtifact() changed and needs commit.
- bool PaintWithoutCommit(
- GraphicsContext::DisabledMode = GraphicsContext::kNothingDisabled,
- const IntRect* interest_rect = nullptr);
+ bool PaintWithoutCommit(const IntRect* interest_rect = nullptr);
- // Adds a child without calling updateChildList(), so that adding children
- // can be batched before updating.
+ // Adds a child without calling NotifyChildListChange(), so that adding
+ // children can be batched before updating.
void AddChildInternal(GraphicsLayer*);
#if DCHECK_IS_ON()
@@ -288,15 +276,12 @@ class PLATFORM_EXPORT GraphicsLayer : public DisplayItemClient,
#endif
// Helper functions used by settors to keep layer's the state consistent.
- void UpdateChildList();
+ void NotifyChildListChange();
void UpdateLayerIsDrawable();
- void UpdateContentsRect();
+ void UpdateContentsLayerBounds();
- void SetContentsTo(cc::Layer*, bool prevent_contents_opaque_changes);
- void SetupContentsLayer(cc::Layer*);
- void ClearContentsLayerIfUnregistered();
- cc::Layer* ContentsLayerIfRegistered();
- void SetContentsLayer(cc::Layer*);
+ void SetContentsTo(scoped_refptr<cc::Layer>,
+ bool prevent_contents_opaque_changes);
RasterInvalidator& EnsureRasterInvalidator();
void SetNeedsDisplayInRect(const IntRect&);
@@ -316,6 +301,7 @@ class PLATFORM_EXPORT GraphicsLayer : public DisplayItemClient,
bool contents_visible_ : 1;
bool hit_testable_ : 1;
bool needs_check_raster_invalidation_ : 1;
+ bool contents_layer_is_picture_image_layer_ : 1;
bool painted_ : 1;
@@ -330,15 +316,8 @@ class PLATFORM_EXPORT GraphicsLayer : public DisplayItemClient,
IntRect contents_rect_;
scoped_refptr<cc::PictureLayer> layer_;
- scoped_refptr<cc::PictureImageLayer> image_layer_;
IntSize image_size_;
- cc::Layer* contents_layer_;
- // We don't have ownership of contents_layer_, but we do want to know if a
- // given layer is the same as our current layer in SetContentsTo(). Since
- // |contents_layer_| may be deleted at this point, we stash an ID away when we
- // know |contents_layer_| is alive and use that for comparisons from that
- // point on.
- int contents_layer_id_;
+ scoped_refptr<cc::Layer> contents_layer_;
SquashingDisallowedReasons squashing_disallowed_reasons_ =
SquashingDisallowedReason::kNone;
@@ -355,6 +334,7 @@ class PLATFORM_EXPORT GraphicsLayer : public DisplayItemClient,
std::unique_ptr<LayerState> contents_layer_state_;
std::unique_ptr<RasterInvalidator> raster_invalidator_;
+ RasterInvalidator::RasterInvalidationFunction raster_invalidation_function_;
DOMNodeId owner_node_id_ = kInvalidDOMNodeId;
CompositingReasons compositing_reasons_ = CompositingReason::kNone;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer_client.h b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer_client.h
index 091a8e66c36..0106ae1c9be 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer_client.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer_client.h
@@ -56,8 +56,6 @@ class PLATFORM_EXPORT GraphicsLayerClient {
public:
virtual ~GraphicsLayerClient() = default;
- virtual void InvalidateTargetElementForTesting() {}
-
virtual IntRect ComputeInterestRect(
const GraphicsLayer*,
const IntRect& previous_interest_rect) const = 0;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer_test.cc b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer_test.cc
index e1c3148b159..35ea37342e2 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer_test.cc
@@ -149,11 +149,10 @@ TEST_P(GraphicsLayerTest, SetDrawsContentFalse) {
TEST_P(GraphicsLayerTest, ContentsLayer) {
auto& graphics_layer = layers_.graphics_layer();
auto contents_layer = cc::Layer::Create();
- GraphicsLayer::RegisterContentsLayer(contents_layer.get());
- graphics_layer.SetContentsToCcLayer(contents_layer.get(), true);
+ graphics_layer.SetContentsToCcLayer(contents_layer, true);
EXPECT_TRUE(graphics_layer.HasContentsLayer());
EXPECT_EQ(contents_layer.get(), graphics_layer.ContentsLayer());
- GraphicsLayer::UnregisterContentsLayer(contents_layer.get());
+ graphics_layer.SetContentsToCcLayer(nullptr, true);
EXPECT_FALSE(graphics_layer.HasContentsLayer());
EXPECT_EQ(nullptr, graphics_layer.ContentsLayer());
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/hit_test_rect.cc b/chromium/third_party/blink/renderer/platform/graphics/hit_test_rect.cc
deleted file mode 100644
index ce10491b66e..00000000000
--- a/chromium/third_party/blink/renderer/platform/graphics/hit_test_rect.cc
+++ /dev/null
@@ -1,32 +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/graphics/hit_test_rect.h"
-
-#include "cc/base/region.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-
-// static
-LayoutRect HitTestRect::GetBounds(const Vector<HitTestRect>& hit_test_rects) {
- cc::Region region;
- for (const HitTestRect& hit_test_rect : hit_test_rects) {
- const LayoutRect& rect = hit_test_rect.rect;
- region.Union(EnclosingIntRect(rect));
- }
- const auto& rect = region.bounds();
- return LayoutRect(IntRect(rect));
-}
-
-String HitTestRect::ToString() const {
- // TODO(pdr): Print the value of |allowed_touch_action|.
- return rect.ToString();
-}
-
-std::ostream& operator<<(std::ostream& os, const HitTestRect& hit_test_rect) {
- return os << hit_test_rect.ToString();
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/hit_test_rect.h b/chromium/third_party/blink/renderer/platform/graphics/hit_test_rect.h
deleted file mode 100644
index 258b6848f7d..00000000000
--- a/chromium/third_party/blink/renderer/platform/graphics/hit_test_rect.h
+++ /dev/null
@@ -1,39 +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_PLATFORM_GRAPHICS_HIT_TEST_RECT_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_HIT_TEST_RECT_H_
-
-#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
-#include "third_party/blink/renderer/platform/graphics/touch_action.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-
-namespace blink {
-
-// TODO(pdr): Rename this TouchActionRect.
-struct PLATFORM_EXPORT HitTestRect {
- LayoutRect rect;
- TouchAction allowed_touch_action;
-
- HitTestRect(const LayoutRect& layout_rect)
- : HitTestRect(layout_rect, TouchAction::kTouchActionNone) {}
- HitTestRect(const LayoutRect& layout_rect, TouchAction action)
- : rect(layout_rect), allowed_touch_action(action) {}
-
- static LayoutRect GetBounds(const Vector<HitTestRect>&);
-
- bool operator==(const HitTestRect& rhs) const {
- return rect == rhs.rect && allowed_touch_action == rhs.allowed_touch_action;
- }
-
- bool operator!=(const HitTestRect& rhs) const { return !(*this == rhs); }
-
- String ToString() const;
-};
-
-PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, const HitTestRect&);
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_HIT_TEST_RECT_H_
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image.cc b/chromium/third_party/blink/renderer/platform/graphics/image.cc
index bcb20fdcc85..444fec9627d 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/image.cc
@@ -215,7 +215,8 @@ void Image::DrawPattern(GraphicsContext& context,
const FloatPoint& phase,
SkBlendMode composite_op,
const FloatRect& dest_rect,
- const FloatSize& repeat_spacing) {
+ const FloatSize& repeat_spacing,
+ RespectImageOrientationEnum) {
TRACE_EVENT0("skia", "Image::drawPattern");
if (dest_rect.IsEmpty())
@@ -325,16 +326,22 @@ bool Image::ApplyShader(PaintFlags& flags, const SkMatrix& local_matrix) {
return true;
}
+IntSize Image::Size(
+ RespectImageOrientationEnum respect_image_orientation) const {
+ if (respect_image_orientation == kRespectImageOrientation)
+ return SizeRespectingOrientation();
+ return Size();
+}
+
SkBitmap Image::AsSkBitmapForCurrentFrame(
- RespectImageOrientationEnum should_respect_image_orientation) {
+ RespectImageOrientationEnum respect_image_orientation) {
PaintImage paint_image = PaintImageForCurrentFrame();
if (!paint_image)
return {};
- if (should_respect_image_orientation == kRespectImageOrientation &&
- IsBitmapImage()) {
- ImageOrientation orientation =
- ToBitmapImage(this)->CurrentFrameOrientation();
+ auto* bitmap_image = DynamicTo<BitmapImage>(this);
+ if (respect_image_orientation == kRespectImageOrientation && bitmap_image) {
+ ImageOrientation orientation = bitmap_image->CurrentFrameOrientation();
paint_image = ResizeAndOrientImage(paint_image, orientation);
if (!paint_image)
return {};
@@ -372,6 +379,15 @@ bool Image::GetBitmap(const FloatRect& src_rect, SkBitmap* bitmap) {
return true;
}
+FloatRect Image::CorrectSrcRectForImageOrientation(FloatSize image_size,
+ FloatRect src_rect) const {
+ ImageOrientation orientation = CurrentFrameOrientation();
+ DCHECK(orientation != kDefaultImageOrientation);
+ AffineTransform forward_map = orientation.TransformFromDefault(image_size);
+ AffineTransform inverse_map = forward_map.Inverse();
+ 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
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image.h b/chromium/third_party/blink/renderer/platform/graphics/image.h
index 445dbd8f71f..40cce084170 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/image.h
@@ -30,6 +30,7 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
+#include "third_party/blink/renderer/platform/geometry/float_point.h"
#include "third_party/blink/renderer/platform/geometry/float_size.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
@@ -57,7 +58,6 @@ class ImageDecodeCache;
namespace blink {
class DarkModeImageClassifier;
-class FloatPoint;
class FloatRect;
class GraphicsContext;
class Image;
@@ -109,9 +109,16 @@ class PLATFORM_EXPORT Image : public ThreadSafeRefCounted<Image> {
virtual bool HasIntrinsicSize() const { return true; }
virtual IntSize Size() const = 0;
+ IntSize Size(RespectImageOrientationEnum) const;
+ virtual IntSize SizeRespectingOrientation() const { return Size(); }
+ virtual FloatSize SizeAsFloat(
+ RespectImageOrientationEnum respect_orientation) const {
+ return FloatSize(Size(respect_orientation));
+ }
IntRect Rect() const { return IntRect(IntPoint(), Size()); }
int width() const { return Size().Width(); }
int height() const { return Size().Height(); }
+
virtual bool GetHotSpot(IntPoint&) const { return false; }
enum SizeAvailability {
@@ -201,6 +208,22 @@ class PLATFORM_EXPORT Image : public ThreadSafeRefCounted<Image> {
virtual PaintImage PaintImageForCurrentFrame() = 0;
+ virtual bool HasDefaultOrientation() const { return true; }
+
+ // Most image types have the default orientation. Only bitmap derived image
+ // types need to override this method.
+ virtual ImageOrientation CurrentFrameOrientation() const {
+ return kDefaultImageOrientation;
+ }
+
+ // Correct the src rect (rotate and maybe translate it) to account for a
+ // non-default image orientation. The image must have non-default orientation
+ // to call this method. The image_size is the oriented size of the image (i.e.
+ // after orientation has been applied). src_rect may be a subset of the image,
+ // also oriented.
+ FloatRect CorrectSrcRectForImageOrientation(FloatSize image_size,
+ FloatRect src_rect) const;
+
enum ImageClampingMode {
kClampImageToSourceRect,
kDoNotClampImageToSourceRect
@@ -276,7 +299,8 @@ class PLATFORM_EXPORT Image : public ThreadSafeRefCounted<Image> {
const FloatPoint& phase,
SkBlendMode,
const FloatRect&,
- const FloatSize& repeat_spacing);
+ const FloatSize& repeat_spacing,
+ RespectImageOrientationEnum);
// Creates and initializes a PaintImageBuilder with the metadata flags for the
// PaintImage.
@@ -285,7 +309,7 @@ class PLATFORM_EXPORT Image : public ThreadSafeRefCounted<Image> {
// Whether or not size is available yet.
virtual bool IsSizeAvailable() { return true; }
- typedef FloatSize ClassificationKey;
+ typedef FloatPoint ClassificationKey;
HashMap<ClassificationKey, DarkModeClassification> dark_mode_classifications_;
private:
@@ -304,10 +328,6 @@ class PLATFORM_EXPORT Image : public ThreadSafeRefCounted<Image> {
DISALLOW_COPY_AND_ASSIGN(Image);
};
-#define DEFINE_IMAGE_TYPE_CASTS(typeName) \
- DEFINE_TYPE_CASTS(typeName, Image, image, image->Is##typeName(), \
- image.Is##typeName())
-
} // namespace blink
#endif
diff --git a/chromium/third_party/blink/renderer/platform/graphics/image_decoder_wrapper.cc b/chromium/third_party/blink/renderer/platform/graphics/image_decoder_wrapper.cc
index 5a6dab40814..4c261b515a9 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/image_decoder_wrapper.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/image_decoder_wrapper.cc
@@ -112,7 +112,7 @@ bool ImageDecoderWrapper::Decode(ImageDecoderFactory* factory,
// For multi-frame image decoders, we need to know how many frames are
// in that image in order to release the decoder when all frames are
- // decoded. frameCount() is reliable only if all data is received and set in
+ // decoded. FrameCount() is reliable only if all data is received and set in
// decoder, particularly with GIF.
if (all_data_received_)
*frame_count = decoder->FrameCount();
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 db0a5275b0a..1cf6d753c4d 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(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) override {}
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/intercepting_canvas.h b/chromium/third_party/blink/renderer/platform/graphics/intercepting_canvas.h
index bb7e49923e7..8ede5551e3c 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/intercepting_canvas.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/intercepting_canvas.h
@@ -86,19 +86,6 @@ class InterceptingCanvasBase : public SkCanvas {
void onDrawOval(const SkRect&, const SkPaint&) override = 0;
void onDrawRRect(const SkRRect&, const SkPaint&) override = 0;
void onDrawPath(const SkPath&, const SkPaint&) override = 0;
- void onDrawBitmap(const SkBitmap&,
- SkScalar left,
- SkScalar top,
- const SkPaint*) override = 0;
- void onDrawBitmapRect(const SkBitmap&,
- const SkRect* src,
- const SkRect& dst,
- const SkPaint*,
- SrcRectConstraint) override = 0;
- void onDrawBitmapNine(const SkBitmap&,
- const SkIRect& center,
- const SkRect& dst,
- const SkPaint*) override = 0;
void onDrawImage(const SkImage*,
SkScalar,
SkScalar,
@@ -127,7 +114,10 @@ class InterceptingCanvasBase : public SkCanvas {
const SkMatrix*,
const SkPaint*) override = 0;
void didSetMatrix(const SkMatrix&) override = 0;
+ void didConcat44(const SkScalar[16]) override = 0;
void didConcat(const SkMatrix&) override = 0;
+ void didScale(SkScalar, SkScalar) override = 0;
+ void didTranslate(SkScalar, SkScalar) override = 0;
void willSave() override = 0;
SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override = 0;
void willRestore() override = 0;
@@ -187,31 +177,6 @@ class InterceptingCanvas : public InterceptingCanvasBase {
this->SkCanvas::onDrawPath(path, paint);
}
- void onDrawBitmap(const SkBitmap& bitmap,
- SkScalar left,
- SkScalar top,
- const SkPaint* paint) override {
- Interceptor interceptor(this);
- this->SkCanvas::onDrawBitmap(bitmap, left, top, paint);
- }
-
- void onDrawBitmapRect(const SkBitmap& bitmap,
- const SkRect* src,
- const SkRect& dst,
- const SkPaint* paint,
- SrcRectConstraint constraint) override {
- Interceptor interceptor(this);
- this->SkCanvas::onDrawBitmapRect(bitmap, src, dst, paint, constraint);
- }
-
- void onDrawBitmapNine(const SkBitmap& bitmap,
- const SkIRect& center,
- const SkRect& dst,
- const SkPaint* paint) override {
- Interceptor interceptor(this);
- this->SkCanvas::onDrawBitmapNine(bitmap, center, dst, paint);
- }
-
void onDrawImage(const SkImage* image,
SkScalar x,
SkScalar y,
@@ -285,12 +250,22 @@ class InterceptingCanvas : public InterceptingCanvasBase {
void didSetMatrix(const SkMatrix& matrix) override {
Interceptor interceptor(this);
- this->SkCanvas::didSetMatrix(matrix);
+ }
+
+ void didConcat44(const SkScalar m[16]) override {
+ Interceptor interceptor(this);
}
void didConcat(const SkMatrix& matrix) override {
Interceptor interceptor(this);
- this->SkCanvas::didConcat(matrix);
+ }
+
+ void didScale(SkScalar x, SkScalar y) override {
+ Interceptor interceptor(this);
+ }
+
+ void didTranslate(SkScalar x, SkScalar y) override {
+ Interceptor interceptor(this);
}
void willSave() override {
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 b22ea1d9e6d..9fe75a4f661 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.cc
@@ -73,15 +73,6 @@ std::unique_ptr<JSONObject> ObjectForSkRect(const SkRect& rect) {
return rect_item;
}
-std::unique_ptr<JSONObject> ObjectForSkIRect(const SkIRect& rect) {
- auto rect_item = std::make_unique<JSONObject>();
- rect_item->SetDouble("left", rect.left());
- rect_item->SetDouble("top", rect.top());
- rect_item->SetDouble("right", rect.right());
- rect_item->SetDouble("bottom", rect.bottom());
- return rect_item;
-}
-
String PointModeName(SkCanvas::PointMode mode) {
switch (mode) {
case SkCanvas::kPoints_PointMode:
@@ -248,57 +239,6 @@ std::unique_ptr<JSONObject> ObjectForSkPath(const SkPath& path) {
return path_item;
}
-String ColorTypeName(SkColorType color_type) {
- switch (color_type) {
- case kUnknown_SkColorType:
- return "None";
- case kAlpha_8_SkColorType:
- return "A8";
- case kRGB_565_SkColorType:
- return "RGB565";
- case kARGB_4444_SkColorType:
- return "ARGB4444";
- case kN32_SkColorType:
- return "ARGB8888";
- default:
- NOTREACHED();
- return "?";
- };
-}
-
-std::unique_ptr<JSONObject> ObjectForBitmapData(const SkBitmap& bitmap) {
- Vector<unsigned char> output;
-
- SkPixmap src;
- bool peekResult = bitmap.peekPixels(&src);
- DCHECK(peekResult);
-
- SkPngEncoder::Options options;
- options.fFilterFlags = SkPngEncoder::FilterFlag::kSub;
- options.fZLibLevel = 3;
- if (!ImageEncoder::Encode(&output, src, options)) {
- return nullptr;
- }
-
- auto data_item = std::make_unique<JSONObject>();
- data_item->SetString("base64", Base64Encode(output));
- data_item->SetString("mimeType", "image/png");
- return data_item;
-}
-
-std::unique_ptr<JSONObject> ObjectForSkBitmap(const SkBitmap& bitmap) {
- auto bitmap_item = std::make_unique<JSONObject>();
- bitmap_item->SetInteger("width", bitmap.width());
- bitmap_item->SetInteger("height", bitmap.height());
- bitmap_item->SetString("config", ColorTypeName(bitmap.colorType()));
- bitmap_item->SetBoolean("opaque", bitmap.isOpaque());
- bitmap_item->SetBoolean("immutable", bitmap.isImmutable());
- bitmap_item->SetBoolean("volatile", bitmap.isVolatile());
- bitmap_item->SetInteger("genID", bitmap.getGenerationID());
- bitmap_item->SetObject("data", ObjectForBitmapData(bitmap));
- return bitmap_item;
-}
-
std::unique_ptr<JSONObject> ObjectForSkImage(const SkImage* image) {
auto image_item = std::make_unique<JSONObject>();
image_item->SetInteger("width", image->width());
@@ -315,6 +255,14 @@ std::unique_ptr<JSONArray> ArrayForSkMatrix(const SkMatrix& matrix) {
return matrix_array;
}
+std::unique_ptr<JSONArray> ArrayForSkScalars(size_t count,
+ const SkScalar array[]) {
+ auto points_array_item = std::make_unique<JSONArray>();
+ for (size_t i = 0; i < count; ++i)
+ points_array_item->PushDouble(array[i]);
+ return points_array_item;
+}
+
std::unique_ptr<JSONObject> ObjectForSkShader(const SkShader& shader) {
return std::make_unique<JSONObject>();
}
@@ -520,51 +468,6 @@ void LoggingCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
this->SkCanvas::onDrawPath(path, paint);
}
-void LoggingCanvas::onDrawBitmap(const SkBitmap& bitmap,
- SkScalar left,
- SkScalar top,
- const SkPaint* paint) {
- AutoLogger logger(this);
- JSONObject* params = logger.LogItemWithParams("drawBitmap");
- params->SetDouble("left", left);
- params->SetDouble("top", top);
- params->SetObject("bitmap", ObjectForSkBitmap(bitmap));
- if (paint)
- params->SetObject("paint", ObjectForSkPaint(*paint));
- this->SkCanvas::onDrawBitmap(bitmap, left, top, paint);
-}
-
-void LoggingCanvas::onDrawBitmapRect(const SkBitmap& bitmap,
- const SkRect* src,
- const SkRect& dst,
- const SkPaint* paint,
- SrcRectConstraint constraint) {
- AutoLogger logger(this);
- JSONObject* params = logger.LogItemWithParams("drawBitmapRectToRect");
- params->SetObject("bitmap", ObjectForSkBitmap(bitmap));
- if (src)
- params->SetObject("src", ObjectForSkRect(*src));
- params->SetObject("dst", ObjectForSkRect(dst));
- if (paint)
- params->SetObject("paint", ObjectForSkPaint(*paint));
- params->SetInteger("flags", constraint);
- this->SkCanvas::onDrawBitmapRect(bitmap, src, dst, paint, constraint);
-}
-
-void LoggingCanvas::onDrawBitmapNine(const SkBitmap& bitmap,
- const SkIRect& center,
- const SkRect& dst,
- const SkPaint* paint) {
- AutoLogger logger(this);
- JSONObject* params = logger.LogItemWithParams("drawBitmapNine");
- params->SetObject("bitmap", ObjectForSkBitmap(bitmap));
- params->SetObject("center", ObjectForSkIRect(center));
- params->SetObject("dst", ObjectForSkRect(dst));
- if (paint)
- params->SetObject("paint", ObjectForSkPaint(*paint));
- this->SkCanvas::onDrawBitmapNine(bitmap, center, dst, paint);
-}
-
void LoggingCanvas::onDrawImage(const SkImage* image,
SkScalar left,
SkScalar top,
@@ -677,7 +580,12 @@ void LoggingCanvas::didSetMatrix(const SkMatrix& matrix) {
AutoLogger logger(this);
JSONObject* params = logger.LogItemWithParams("setMatrix");
params->SetArray("matrix", ArrayForSkMatrix(matrix));
- this->SkCanvas::didSetMatrix(matrix);
+}
+
+void LoggingCanvas::didConcat44(const SkScalar m[16]) {
+ AutoLogger logger(this);
+ JSONObject* params = logger.LogItemWithParams("concat44");
+ params->SetArray("matrix44", ArrayForSkScalars(16, m));
}
void LoggingCanvas::didConcat(const SkMatrix& matrix) {
@@ -701,7 +609,20 @@ void LoggingCanvas::didConcat(const SkMatrix& matrix) {
params = logger.LogItemWithParams("concat");
params->SetArray("matrix", ArrayForSkMatrix(matrix));
}
- this->SkCanvas::didConcat(matrix);
+}
+
+void LoggingCanvas::didScale(SkScalar x, SkScalar y) {
+ AutoLogger logger(this);
+ JSONObject* params = logger.LogItemWithParams("scale");
+ params->SetDouble("scaleX", x);
+ params->SetDouble("scaleY", y);
+}
+
+void LoggingCanvas::didTranslate(SkScalar x, SkScalar y) {
+ AutoLogger logger(this);
+ JSONObject* params = logger.LogItemWithParams("translate");
+ params->SetDouble("dx", x);
+ params->SetDouble("dy", y);
}
void LoggingCanvas::willSave() {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.h b/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.h
index 3951bbf51da..82b00979c9f 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.h
@@ -53,19 +53,6 @@ class LoggingCanvas : public InterceptingCanvasBase {
void onDrawOval(const SkRect&, const SkPaint&) override;
void onDrawRRect(const SkRRect&, const SkPaint&) override;
void onDrawPath(const SkPath&, const SkPaint&) override;
- void onDrawBitmap(const SkBitmap&,
- SkScalar left,
- SkScalar top,
- const SkPaint*) override;
- void onDrawBitmapRect(const SkBitmap&,
- const SkRect* src,
- const SkRect& dst,
- const SkPaint*,
- SrcRectConstraint) override;
- void onDrawBitmapNine(const SkBitmap&,
- const SkIRect& center,
- const SkRect& dst,
- const SkPaint*) override;
void onDrawImage(const SkImage*, SkScalar, SkScalar, const SkPaint*) override;
void onDrawImageRect(const SkImage*,
const SkRect* src,
@@ -91,7 +78,10 @@ class LoggingCanvas : public InterceptingCanvasBase {
const SkMatrix*,
const SkPaint*) override;
void didSetMatrix(const SkMatrix&) override;
+ void didConcat44(const SkScalar[16]) override;
void didConcat(const SkMatrix&) override;
+ void didScale(SkScalar, SkScalar) override;
+ void didTranslate(SkScalar, SkScalar) override;
void willSave() override;
SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
void willRestore() override;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/mailbox_texture_holder.cc b/chromium/third_party/blink/renderer/platform/graphics/mailbox_texture_holder.cc
deleted file mode 100644
index d0ac4be0f10..00000000000
--- a/chromium/third_party/blink/renderer/platform/graphics/mailbox_texture_holder.cc
+++ /dev/null
@@ -1,196 +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/graphics/mailbox_texture_holder.h"
-
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
-#include "third_party/blink/renderer/platform/graphics/skia_texture_holder.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/skia/include/gpu/GrContext.h"
-
-namespace blink {
-
-namespace {
-
-void ReleaseTexture(
- bool is_converted_from_skia_texture,
- unsigned texture_id,
- std::unique_ptr<gpu::Mailbox> mailbox,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider,
- std::unique_ptr<gpu::SyncToken> sync_token) {
- if (!is_converted_from_skia_texture && texture_id && context_provider) {
- context_provider->ContextProvider()->ContextGL()->WaitSyncTokenCHROMIUM(
- sync_token->GetData());
- context_provider->ContextProvider()->ContextGL()->DeleteTextures(
- 1, &texture_id);
- }
-}
-
-} // namespace
-
-MailboxTextureHolder::MailboxTextureHolder(
- const gpu::Mailbox& mailbox,
- const gpu::SyncToken& sync_token,
- unsigned texture_id_to_delete_after_mailbox_consumed,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper>&&
- context_provider_wrapper,
- IntSize mailbox_size,
- bool is_origin_top_left)
- : TextureHolder(std::move(context_provider_wrapper),
- base::MakeRefCounted<MailboxRef>(nullptr),
- is_origin_top_left),
- mailbox_(mailbox),
- texture_id_(texture_id_to_delete_after_mailbox_consumed),
- is_converted_from_skia_texture_(false),
- thread_id_(0),
- sk_image_info_(SkImageInfo::MakeN32Premul(mailbox_size.Width(),
- mailbox_size.Height())),
- texture_target_(GL_TEXTURE_2D) {
- mailbox_ref()->set_sync_token(sync_token);
- InitCommon();
-}
-
-MailboxTextureHolder::MailboxTextureHolder(
- const gpu::Mailbox& mailbox,
- const gpu::SyncToken& sync_token,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper>&&
- context_provider_wrapper,
- scoped_refptr<MailboxRef> mailbox_ref,
- PlatformThreadId context_thread_id,
- const SkImageInfo& sk_image_info,
- GLenum texture_target,
- bool is_origin_top_left)
- : TextureHolder(std::move(context_provider_wrapper),
- std::move(mailbox_ref),
- is_origin_top_left),
- mailbox_(mailbox),
- texture_id_(0),
- is_converted_from_skia_texture_(false),
- thread_id_(context_thread_id),
- sk_image_info_(sk_image_info),
- texture_target_(texture_target) {
- DCHECK(thread_id_);
- DCHECK(!IsCrossThread() || sync_token.verified_flush());
- this->mailbox_ref()->set_sync_token(sync_token);
-}
-
-MailboxTextureHolder::MailboxTextureHolder(
- const SkiaTextureHolder* texture_holder,
- GLenum filter)
- : TextureHolder(texture_holder->ContextProviderWrapper(),
- texture_holder->mailbox_ref(),
- texture_holder->IsOriginTopLeft()),
- texture_id_(0),
- is_converted_from_skia_texture_(true),
- thread_id_(0) {
- sk_sp<SkImage> image = texture_holder->GetSkImage();
- DCHECK(image);
- sk_image_info_ = image->imageInfo();
-
- if (!ContextProviderWrapper())
- return;
-
- if (!ContextProviderWrapper()->Utils()->GetMailboxForSkImage(
- mailbox_, texture_target_, image, filter))
- return;
-
- InitCommon();
-}
-
-void MailboxTextureHolder::Sync(MailboxSyncMode mode) {
- gpu::SyncToken sync_token = mailbox_ref()->sync_token();
-
- if (IsCrossThread()) {
- // Was originally created on another thread. Should already have a sync
- // token from the original source context, already verified if needed.
- DCHECK(sync_token.HasData());
- DCHECK(mode != kVerifiedSyncToken || sync_token.verified_flush());
- return;
- }
-
- if (!ContextProviderWrapper())
- return;
-
- TRACE_EVENT0("blink", "MailboxTextureHolder::Sync");
-
- gpu::gles2::GLES2Interface* gl =
- ContextProviderWrapper()->ContextProvider()->ContextGL();
-
- if (mode == kOrderingBarrier) {
- if (!did_issue_ordering_barrier_) {
- gl->OrderingBarrierCHROMIUM();
- did_issue_ordering_barrier_ = true;
- }
- return;
- }
-
- if (!sync_token.HasData()) {
- if (mode == kVerifiedSyncToken) {
- gl->GenSyncTokenCHROMIUM(sync_token.GetData());
- } else {
- gl->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData());
- }
- mailbox_ref()->set_sync_token(sync_token);
- return;
- }
-
- // At this point we have a pre-existing sync token. We just need to verify
- // it if needed. Providing a verified sync token when unverified is requested
- // is fine.
- if (mode == kVerifiedSyncToken && !sync_token.verified_flush()) {
- int8_t* token_data = sync_token.GetData();
- // TODO(junov): Batch this verification in the case where there are multiple
- // offscreen canvases being committed.
- gl->ShallowFlushCHROMIUM();
- gl->VerifySyncTokensCHROMIUM(&token_data, 1);
- sync_token.SetVerifyFlush();
- mailbox_ref()->set_sync_token(sync_token);
- }
-}
-
-void MailboxTextureHolder::InitCommon() {
- DCHECK(!thread_id_);
- thread_id_ = base::PlatformThread::CurrentId();
- texture_thread_task_runner_ = Thread::Current()->GetTaskRunner();
-}
-
-bool MailboxTextureHolder::IsValid() const {
- if (IsCrossThread()) {
- // If context is is from another thread, validity cannot be verified.
- // Just assume valid. Potential problem will be detected later.
- return true;
- }
- return !!ContextProviderWrapper();
-}
-
-bool MailboxTextureHolder::IsCrossThread() const {
- return thread_id_ != base::PlatformThread::CurrentId();
-}
-
-MailboxTextureHolder::~MailboxTextureHolder() {
- std::unique_ptr<gpu::SyncToken> passed_sync_token(
- new gpu::SyncToken(mailbox_ref()->sync_token()));
- std::unique_ptr<gpu::Mailbox> passed_mailbox(new gpu::Mailbox(mailbox_));
-
- if (texture_thread_task_runner_ && IsCrossThread()) {
- PostCrossThreadTask(
- *texture_thread_task_runner_, FROM_HERE,
- CrossThreadBindOnce(&ReleaseTexture, is_converted_from_skia_texture_,
- texture_id_, WTF::Passed(std::move(passed_mailbox)),
- WTF::Passed(ContextProviderWrapper()),
- WTF::Passed(std::move(passed_sync_token))));
- } else {
- ReleaseTexture(is_converted_from_skia_texture_, texture_id_,
- std::move(passed_mailbox), ContextProviderWrapper(),
- std::move(passed_sync_token));
- }
-
- texture_id_ = 0u; // invalidate the texture.
- texture_thread_task_runner_ = nullptr;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/mailbox_texture_holder.h b/chromium/third_party/blink/renderer/platform/graphics/mailbox_texture_holder.h
deleted file mode 100644
index da4d6800f99..00000000000
--- a/chromium/third_party/blink/renderer/platform/graphics/mailbox_texture_holder.h
+++ /dev/null
@@ -1,83 +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_PLATFORM_GRAPHICS_MAILBOX_TEXTURE_HOLDER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_MAILBOX_TEXTURE_HOLDER_H_
-
-#include "base/memory/weak_ptr.h"
-#include "base/single_thread_task_runner.h"
-#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
-#include "third_party/blink/renderer/platform/graphics/texture_holder.h"
-#include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
-#include "third_party/khronos/GLES2/gl2.h"
-#include "third_party/skia/include/core/SkImageInfo.h"
-
-namespace blink {
-class SkiaTextureHolder;
-
-class PLATFORM_EXPORT MailboxTextureHolder final : public TextureHolder {
- public:
- ~MailboxTextureHolder() override;
-
- // TextureHolder impl.
- IntSize Size() const final {
- return IntSize(sk_image_info_.width(), sk_image_info_.height());
- }
- bool CurrentFrameKnownToBeOpaque() const final { return false; }
- bool IsValid() const final;
-
- bool IsCrossThread() const;
- const gpu::Mailbox& GetMailbox() const { return mailbox_; }
- const gpu::SyncToken& GetSyncToken() const {
- return mailbox_ref()->sync_token();
- }
- void UpdateSyncToken(gpu::SyncToken sync_token) {
- mailbox_ref()->set_sync_token(sync_token);
- }
- const SkImageInfo& sk_image_info() const { return sk_image_info_; }
- GLenum texture_target() const { return texture_target_; }
-
- void Sync(MailboxSyncMode);
- // In WebGL's commit or transferToImageBitmap calls, it will call the
- // DrawingBuffer::transferToStaticBitmapImage function, which produces the
- // input parameters for this method.
- MailboxTextureHolder(const gpu::Mailbox&,
- const gpu::SyncToken&,
- unsigned texture_id_to_delete_after_mailbox_consumed,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper>&&,
- IntSize mailbox_size,
- bool is_origin_top_left);
- // This function turns a texture-backed SkImage into a mailbox and a
- // syncToken.
- MailboxTextureHolder(const SkiaTextureHolder*, GLenum filter);
- // This function may be used when the MailboxTextureHolder is created on a
- // different thread. The caller must provide a verified sync token if it is
- // created cross-thread.
- MailboxTextureHolder(const gpu::Mailbox&,
- const gpu::SyncToken&,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper>&&,
- scoped_refptr<MailboxRef> mailbox_ref,
- PlatformThreadId context_thread_id,
- const SkImageInfo& sk_image_info,
- GLenum texture_target,
- bool is_origin_top_left);
-
- private:
- void InitCommon();
-
- gpu::Mailbox mailbox_;
- unsigned texture_id_;
- bool is_converted_from_skia_texture_;
- scoped_refptr<base::SingleThreadTaskRunner> texture_thread_task_runner_;
- base::PlatformThreadId thread_id_;
- bool did_issue_ordering_barrier_ = false;
- SkImageInfo sk_image_info_;
- GLenum texture_target_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_MAILBOX_TEXTURE_HOLDER_H_
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
new file mode 100644
index 00000000000..3659a862b3e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.cc
@@ -0,0 +1,49 @@
+// 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/memory_managed_paint_canvas.h"
+
+namespace blink {
+
+MemoryManagedPaintCanvas::MemoryManagedPaintCanvas(
+ cc::DisplayItemList* list,
+ const SkRect& bounds,
+ base::RepeatingClosure set_needs_flush_callback)
+ : RecordPaintCanvas(list, bounds),
+ set_needs_flush_callback_(std::move(set_needs_flush_callback)) {}
+
+MemoryManagedPaintCanvas::~MemoryManagedPaintCanvas() = default;
+
+void MemoryManagedPaintCanvas::drawImage(const cc::PaintImage& image,
+ SkScalar left,
+ SkScalar top,
+ const cc::PaintFlags* flags) {
+ DCHECK(!image.IsPaintWorklet());
+ RecordPaintCanvas::drawImage(image, left, top, flags);
+ UpdateMemoryUsage(image);
+}
+
+void MemoryManagedPaintCanvas::drawImageRect(
+ const cc::PaintImage& image,
+ const SkRect& src,
+ const SkRect& dst,
+ const cc::PaintFlags* flags,
+ PaintCanvas::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)))
+ return;
+
+ cached_image_ids_.insert(image.GetContentIdForFrame(0u));
+ total_stored_image_memory_ +=
+ image.GetSkImage()->imageInfo().computeMinByteSize();
+
+ if (total_stored_image_memory_ > kMaxPinnedMemory)
+ set_needs_flush_callback_.Run();
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..444d771f899
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.h
@@ -0,0 +1,52 @@
+// 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_MEMORY_MANAGED_PAINT_CANVAS_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_MEMORY_MANAGED_PAINT_CANVAS_H_
+
+#include <memory>
+
+#include "cc/paint/record_paint_canvas.h"
+#include "third_party/blink/public/platform/platform.h"
+
+namespace blink {
+
+// MemoryManagedPaintCanvas overrides the potentially memory intensive image
+// drawing methods of PaintCanvas and keeps track of how much memory is
+// being pinned between flushes. This allows the rendering context to flush if
+// too much memory is used.
+class PLATFORM_EXPORT MemoryManagedPaintCanvas final
+ : public cc::RecordPaintCanvas {
+ public:
+ MemoryManagedPaintCanvas(cc::DisplayItemList* list,
+ const SkRect& bounds,
+ base::RepeatingClosure set_needs_flush_callback);
+ explicit MemoryManagedPaintCanvas(const cc::RecordPaintCanvas&) = delete;
+ ~MemoryManagedPaintCanvas() override;
+
+ void drawImage(const cc::PaintImage& image,
+ SkScalar left,
+ SkScalar top,
+ const cc::PaintFlags* flags) override;
+ void drawImageRect(const cc::PaintImage& image,
+ const SkRect& src,
+ const SkRect& dst,
+ const cc::PaintFlags* flags,
+ SrcRectConstraint constraint) override;
+
+ private:
+ void UpdateMemoryUsage(const cc::PaintImage& image);
+
+ base::flat_set<int> cached_image_ids_;
+ uint64_t total_stored_image_memory_ = 0;
+
+ base::RepeatingClosure set_needs_flush_callback_;
+
+ // The same value as is used in content::WebGraphicsConext3DProviderImpl.
+ static constexpr uint64_t kMaxPinnedMemory = 64 * 1024 * 1024;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_MEMORY_MANAGED_PAINT_CANVAS_H_
diff --git a/chromium/third_party/blink/renderer/platform/graphics/memory_managed_paint_recorder.cc b/chromium/third_party/blink/renderer/platform/graphics/memory_managed_paint_recorder.cc
new file mode 100644
index 00000000000..1f179973d11
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/graphics/memory_managed_paint_recorder.cc
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 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.
+ *
+ * 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.
+ */
+
+#include "third_party/blink/renderer/platform/graphics/memory_managed_paint_recorder.h"
+
+namespace blink {
+
+MemoryManagedPaintRecorder::MemoryManagedPaintRecorder(
+ base::RepeatingClosure set_needs_flush_callback)
+ : set_needs_flush_callback_(std::move(set_needs_flush_callback)) {}
+
+std::unique_ptr<cc::RecordPaintCanvas> MemoryManagedPaintRecorder::CreateCanvas(
+ cc::DisplayItemList* list,
+ const SkRect& bounds) {
+ return std::make_unique<MemoryManagedPaintCanvas>(list, bounds,
+ set_needs_flush_callback_);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/memory_managed_paint_recorder.h b/chromium/third_party/blink/renderer/platform/graphics/memory_managed_paint_recorder.h
new file mode 100644
index 00000000000..1450219da57
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/graphics/memory_managed_paint_recorder.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 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.
+ *
+ * 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.
+ */
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_MEMORY_MANAGED_PAINT_RECORDER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_MEMORY_MANAGED_PAINT_RECORDER_H_
+
+#include "cc/paint/paint_recorder.h"
+#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/platform/graphics/memory_managed_paint_canvas.h"
+
+namespace blink {
+
+class PLATFORM_EXPORT MemoryManagedPaintRecorder : public cc::PaintRecorder {
+ public:
+ MemoryManagedPaintRecorder(base::RepeatingClosure set_needs_flush_callback);
+
+ protected:
+ std::unique_ptr<cc::RecordPaintCanvas> CreateCanvas(
+ cc::DisplayItemList* list,
+ const SkRect& bounds) override;
+
+ private:
+ base::RepeatingClosure set_needs_flush_callback_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_MEMORY_MANAGED_PAINT_RECORDER_H_
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/README.md b/chromium/third_party/blink/renderer/platform/graphics/paint/README.md
index 6d367c9d5d3..ea389f5ca03 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/README.md
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/README.md
@@ -156,6 +156,13 @@ emit display items to a `PaintController` (using `GraphicsContext`).
Holds a `PaintRecord` which contains the paint operations required to draw some
atom of content.
+#### [GraphicsLayerDisplayItem](graphics_layer_display_item.h)
+
+Placeholder for `GraphicsLayers` allocated by the pre-CompositeAfterPaint
+compositing logic. Each one of these may or may not ultimately produce a
+`cc::PictureLayer`, depending on the layer squashing mechanism. This class
+becomes obsolete with CompositeAfterPaint.
+
#### [ForeignLayerDisplayItem](foreign_layer_display_item.h)
Draws an atom of content, but using a `cc::Layer` produced by some agent outside
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.h b/chromium/third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.h
index b4094008ba1..79156919709 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.h
@@ -9,6 +9,7 @@
#include "base/memory/scoped_refptr.h"
#include "base/optional.h"
#include "third_party/blink/renderer/platform/geometry/float_rounded_rect.h"
+#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
#include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper_clip_cache.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_property_node.h"
#include "third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h"
@@ -32,14 +33,32 @@ class PLATFORM_EXPORT ClipPaintPropertyNode
// To make it less verbose and more readable to construct and update a node,
// a struct with default values is used to represent the state.
struct State {
+ State(scoped_refptr<const TransformPaintPropertyNode> local_transform_space,
+ const FloatRoundedRect& clip_rect)
+ : State(local_transform_space, clip_rect, clip_rect) {}
+
+ State(scoped_refptr<const TransformPaintPropertyNode>
+ local_transform_space_arg,
+ const FloatRoundedRect& clip_rect,
+ const FloatRoundedRect& pixel_snapped_clip_rect)
+ : local_transform_space(local_transform_space_arg) {
+ SetClipRect(clip_rect, pixel_snapped_clip_rect);
+ }
+
scoped_refptr<const TransformPaintPropertyNode> local_transform_space;
- FloatRoundedRect clip_rect;
base::Optional<FloatClipRect> clip_rect_excluding_overlay_scrollbars;
scoped_refptr<const RefCountedPath> clip_path;
+ void SetClipRect(const FloatRoundedRect& clip_rect_arg,
+ const FloatRoundedRect& pixel_snapped_clip_rect_arg) {
+ clip_rect = clip_rect_arg;
+ pixel_snapped_clip_rect = pixel_snapped_clip_rect_arg;
+ }
+
PaintPropertyChangeType ComputeChange(const State& other) const {
if (local_transform_space != other.local_transform_space ||
- clip_rect != other.clip_rect || clip_path != other.clip_path) {
+ pixel_snapped_clip_rect != other.pixel_snapped_clip_rect ||
+ clip_path != other.clip_path) {
return PaintPropertyChangeType::kChangedOnlyValues;
}
if (clip_rect_excluding_overlay_scrollbars !=
@@ -48,6 +67,12 @@ class PLATFORM_EXPORT ClipPaintPropertyNode
}
return PaintPropertyChangeType::kUnchanged;
}
+
+ friend class ClipPaintPropertyNode;
+
+ private:
+ FloatRoundedRect clip_rect;
+ FloatRoundedRect pixel_snapped_clip_rect;
};
// This node is really a sentinel, and does not represent a real clip space.
@@ -109,8 +134,13 @@ class PLATFORM_EXPORT ClipPaintPropertyNode
// a parent alias.
return *Unalias().state_.local_transform_space;
}
- const FloatRoundedRect& ClipRect() const { return state_.clip_rect; }
- const FloatClipRect ClipRectExcludingOverlayScrollbars() const {
+ // The pixel-snapped clip rect may be the same as the unsnapped one, in cases
+ // where pixel snapping is not desirable for a clip, such as for SVG.
+ const FloatRoundedRect& PixelSnappedClipRect() const {
+ return state_.pixel_snapped_clip_rect;
+ }
+ const FloatRoundedRect UnsnappedClipRect() const { return state_.clip_rect; }
+ const FloatClipRect UnsnappedClipRectExcludingOverlayScrollbars() const {
return state_.clip_rect_excluding_overlay_scrollbars
? *state_.clip_rect_excluding_overlay_scrollbars
: FloatClipRect(state_.clip_rect);
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 bb0ae38e08c..83d30acbb8b 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
@@ -42,7 +42,7 @@ static WTF::String PaintPhaseAsDebugString(int paint_phase) {
case 8:
return "PaintPhaseDescendantOutlinesOnly";
case 9:
- return "PaintPhaseOverlayScrollbars";
+ return "PaintPhaseOverlayOverflowControls";
case 10:
return "PaintPhaseSelection";
case 11:
@@ -78,10 +78,10 @@ static WTF::String SpecialDrawingTypeAsDebugString(DisplayItem::Type type) {
DEBUG_STRING_CASE(ClippingMask);
DEBUG_STRING_CASE(ColumnRules);
DEBUG_STRING_CASE(DebugDrawing);
+ DEBUG_STRING_CASE(DocumentRootBackdrop);
DEBUG_STRING_CASE(DocumentBackground);
DEBUG_STRING_CASE(DragImage);
DEBUG_STRING_CASE(DragCaret);
- DEBUG_STRING_CASE(EmptyContentForFilters);
DEBUG_STRING_CASE(ForcedColorsModeBackplate);
DEBUG_STRING_CASE(SVGImage);
DEBUG_STRING_CASE(LinkHighlight);
@@ -123,7 +123,7 @@ static String ForeignLayerTypeAsDebugString(DisplayItem::Type type) {
DEBUG_STRING_CASE(ForeignLayerDevToolsOverlay);
DEBUG_STRING_CASE(ForeignLayerPlugin);
DEBUG_STRING_CASE(ForeignLayerVideo);
- DEBUG_STRING_CASE(ForeignLayerWrapper);
+ DEBUG_STRING_CASE(ForeignLayerRemoteFrame);
DEBUG_STRING_CASE(ForeignLayerContentsWrapper);
DEBUG_STRING_CASE(ForeignLayerLinkHighlight);
DEBUG_STRING_CASE(ForeignLayerViewportScroll);
@@ -132,6 +132,13 @@ static String ForeignLayerTypeAsDebugString(DisplayItem::Type type) {
}
}
+static String GraphicsLayerWrapperTypeAsDebugString(DisplayItem::Type type) {
+ switch (type) {
+ DEBUG_STRING_CASE(GraphicsLayerWrapper);
+ DEFAULT_CASE;
+ }
+}
+
WTF::String DisplayItem::TypeAsDebugString(Type type) {
if (IsDrawingType(type))
return DrawingTypeAsDebugString(type);
@@ -139,6 +146,9 @@ WTF::String DisplayItem::TypeAsDebugString(Type type) {
if (IsForeignLayerType(type))
return ForeignLayerTypeAsDebugString(type);
+ if (IsGraphicsLayerWrapperType(type))
+ return GraphicsLayerWrapperTypeAsDebugString(type);
+
PAINT_PHASE_BASED_DEBUG_STRINGS(Clip);
PAINT_PHASE_BASED_DEBUG_STRINGS(Scroll);
PAINT_PHASE_BASED_DEBUG_STRINGS(SVGTransform);
@@ -149,12 +159,8 @@ WTF::String DisplayItem::TypeAsDebugString(Type type) {
DEBUG_STRING_CASE(ScrollHitTest);
DEBUG_STRING_CASE(ResizerScrollHitTest);
DEBUG_STRING_CASE(PluginScrollHitTest);
- DEBUG_STRING_CASE(LayerChunkBackground);
- DEBUG_STRING_CASE(LayerChunkNegativeZOrderChildren);
- DEBUG_STRING_CASE(LayerChunkDescendantBackgrounds);
- DEBUG_STRING_CASE(LayerChunkFloat);
+ DEBUG_STRING_CASE(LayerChunk);
DEBUG_STRING_CASE(LayerChunkForeground);
- DEBUG_STRING_CASE(LayerChunkNormalFlowAndPositiveZOrderChildren);
DEBUG_STRING_CASE(ScrollbarHorizontal);
DEBUG_STRING_CASE(ScrollbarVertical);
DEBUG_STRING_CASE(UninitializedType);
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 320f0d0bee5..6d9a09eff7e 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
@@ -61,10 +61,10 @@ class PLATFORM_EXPORT DisplayItem {
kClippingMask,
kColumnRules,
kDebugDrawing,
+ kDocumentRootBackdrop,
kDocumentBackground,
kDragImage,
kDragCaret,
- kEmptyContentForFilters,
kForcedColorsModeBackplate,
kSVGImage,
kLinkHighlight,
@@ -100,13 +100,17 @@ class PLATFORM_EXPORT DisplayItem {
kForeignLayerDevToolsOverlay,
kForeignLayerPlugin,
kForeignLayerVideo,
- kForeignLayerWrapper,
+ kForeignLayerRemoteFrame,
kForeignLayerContentsWrapper,
kForeignLayerLinkHighlight,
kForeignLayerViewportScroll,
kForeignLayerViewportScrollbar,
kForeignLayerLast = kForeignLayerViewportScrollbar,
+ kGraphicsLayerWrapperFirst,
+ kGraphicsLayerWrapper = kGraphicsLayerWrapperFirst,
+ kGraphicsLayerWrapperLast = kGraphicsLayerWrapper,
+
kClipPaintPhaseFirst,
kClipPaintPhaseLast = kClipPaintPhaseFirst + kPaintPhaseMax,
@@ -119,26 +123,29 @@ class PLATFORM_EXPORT DisplayItem {
kSVGEffectPaintPhaseFirst,
kSVGEffectPaintPhaseLast = kSVGEffectPaintPhaseFirst + kPaintPhaseMax,
+ // The following hit test types are for paint chunks containing hit test
+ // data, when we don't have an previously set explicit chunk id when
+ // creating the paint chunk, or we need dedicated paint chunk for the hit
+ // test data.
+
// Compositor hit testing requires that layers are created and sized to
- // include content that does not paint. Hit test display items ensure
- // a layer exists and is sized properly even if no content would otherwise
- // be painted.
+ // include content that does not paint. Hit test data ensure a layer exists
+ // and is sized properly even if no content would otherwise be painted.
kHitTest,
// Used both for specifying the paint-order scroll location, and for non-
- // composited scroll hit testing (see: scroll_hit_test_display_item.h).
+ // composited scroll hit testing (see: hit_test_data.h).
kScrollHitTest,
// Used to prevent composited scrolling on the resize handle.
kResizerScrollHitTest,
// Used to prevent composited scrolling on plugins with wheel handlers.
kPluginScrollHitTest,
- kLayerChunkBackground,
- kLayerChunkNegativeZOrderChildren,
- kLayerChunkDescendantBackgrounds,
- kLayerChunkFloat,
+ // These are for paint chunks that are forced for layers.
+ kLayerChunk,
+ // This is used if a layer has any negative-z-index children. Otherwise the
+ // foreground is in the kLayerChunk chunk.
kLayerChunkForeground,
- kLayerChunkNormalFlowAndPositiveZOrderChildren,
// The following 2 types are For ScrollbarDisplayItem.
kScrollbarHorizontal,
@@ -152,7 +159,7 @@ class PLATFORM_EXPORT DisplayItem {
// later paint cycles when |client| may have been destroyed.
DisplayItem(const DisplayItemClient& client,
Type type,
- size_t derived_size,
+ wtf_size_t derived_size,
bool draws_content = false)
: client_(&client),
visual_rect_(client.VisualRect()),
@@ -161,10 +168,11 @@ class PLATFORM_EXPORT DisplayItem {
draws_content_(draws_content),
fragment_(0),
is_cacheable_(client.IsCacheable()),
- is_tombstone_(false) {
+ 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 << 8));
+ SECURITY_DCHECK(derived_size < (1 << 7));
SECURITY_DCHECK(derived_size >= sizeof(*this));
derived_size_ = static_cast<unsigned>(derived_size);
}
@@ -211,7 +219,7 @@ class PLATFORM_EXPORT DisplayItem {
// This is not sizeof(*this), because it needs to account for the size of
// the derived class (i.e. runtime type). Derived classes are expected to
// supply this to the DisplayItem constructor.
- size_t DerivedSize() const { return derived_size_; }
+ wtf_size_t DerivedSize() const { return derived_size_; }
// The fragment is part of the id, to uniquely identify display items in
// different fragments for the same client and type.
@@ -221,6 +229,8 @@ class PLATFORM_EXPORT DisplayItem {
fragment_ = fragment;
}
+ void SetVisualRectForTesting(const IntRect& r) { visual_rect_ = r; }
+
// See comments of enum Type for usage of the following macros.
#define DEFINE_CATEGORY_METHODS(Category) \
static constexpr bool Is##Category##Type(Type type) { \
@@ -243,20 +253,13 @@ class PLATFORM_EXPORT DisplayItem {
DEFINE_PAINT_PHASE_CONVERSION_METHOD(Drawing)
DEFINE_CATEGORY_METHODS(ForeignLayer)
+ DEFINE_CATEGORY_METHODS(GraphicsLayerWrapper)
DEFINE_PAINT_PHASE_CONVERSION_METHOD(Clip)
DEFINE_PAINT_PHASE_CONVERSION_METHOD(Scroll)
DEFINE_PAINT_PHASE_CONVERSION_METHOD(SVGTransform)
DEFINE_PAINT_PHASE_CONVERSION_METHOD(SVGEffect)
- bool IsHitTest() const { return type_ == kHitTest; }
- bool IsScrollHitTest() const {
- return type_ == kScrollHitTest || IsResizerScrollHitTest() ||
- IsPluginScrollHitTest();
- }
- bool IsResizerScrollHitTest() const { return type_ == kResizerScrollHitTest; }
- bool IsPluginScrollHitTest() const { return type_ == kPluginScrollHitTest; }
-
bool IsScrollbar() const {
return type_ == kScrollbarHorizontal || type_ == kScrollbarVertical;
}
@@ -264,6 +267,13 @@ class PLATFORM_EXPORT DisplayItem {
bool IsCacheable() const { return is_cacheable_; }
void SetUncacheable() { is_cacheable_ = false; }
+ bool IsMovedFromCachedSubsequence() const {
+ return is_moved_from_cached_subsequence_;
+ }
+ void SetMovedFromCachedSubsequence(bool b) {
+ is_moved_from_cached_subsequence_ = b;
+ }
+
virtual bool Equals(const DisplayItem& other) const {
// Failure of this DCHECK would cause bad casts in subclasses.
SECURITY_CHECK(!is_tombstone_);
@@ -304,10 +314,11 @@ class PLATFORM_EXPORT DisplayItem {
static_assert(kTypeLast < (1 << 7), "DisplayItem::Type should fit in 7 bits");
unsigned type_ : 7;
unsigned draws_content_ : 1;
- unsigned derived_size_ : 8; // size of the actual derived class
+ 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;
};
inline bool operator==(const DisplayItem::Id& a, const DisplayItem::Id& b) {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_cache_skipper.h b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_cache_skipper.h
index 5ded583d929..d702c6c758f 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_cache_skipper.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_cache_skipper.h
@@ -13,10 +13,11 @@
namespace blink {
class DisplayItemCacheSkipper final {
- DISALLOW_NEW();
+ STACK_ALLOCATED();
public:
- DisplayItemCacheSkipper(GraphicsContext& context) : context_(context) {
+ explicit DisplayItemCacheSkipper(GraphicsContext& context)
+ : context_(context) {
context.GetPaintController().BeginSkippingCache();
}
~DisplayItemCacheSkipper() {
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 d29f0ecee1f..6e108747031 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
@@ -66,20 +66,6 @@ class PLATFORM_EXPORT DisplayItemClient {
// Called by PaintController::FinishCycle() for all clients after painting.
virtual void ClearPartialInvalidationVisualRect() const {}
- // This is declared here instead of in LayoutObject for verifying the
- // condition in DrawingRecorder.
- // Returns true if the object itself will not generate any effective painted
- // output no matter what size the object is. For example, this function can
- // return false for an object whose size is currently 0x0 but would have
- // effective painted output if it was set a non-empty size. It's used to skip
- // unforced paint invalidation of LayoutObjects (which is when
- // shouldDoFullPaintInvalidation is false, but mayNeedPaintInvalidation or
- // childShouldCheckForPaintInvalidation is true) to avoid unnecessary paint
- // invalidations of empty areas covered by such objects.
- virtual bool PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const {
- return false;
- }
-
// Indicates that the client will paint display items different from the ones
// cached by PaintController. However, PaintController allows a client to
// paint new display items that are not cached or to no longer paint some
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_list.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_list.cc
index bb15ec6a712..d2f05789294 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_list.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_list.cc
@@ -24,17 +24,17 @@ DisplayItemList::ItemsInPaintChunk(const PaintChunk& paint_chunk) const {
#if DCHECK_IS_ON()
-std::unique_ptr<JSONArray> DisplayItemList::SubsequenceAsJSON(
- size_t begin_index,
- size_t end_index,
+std::unique_ptr<JSONArray> DisplayItemList::DisplayItemsAsJSON(
+ wtf_size_t begin_index,
+ wtf_size_t end_index,
JsonFlags flags) const {
auto json_array = std::make_unique<JSONArray>();
AppendSubsequenceAsJSON(begin_index, end_index, flags, *json_array);
return json_array;
}
-void DisplayItemList::AppendSubsequenceAsJSON(size_t begin_index,
- size_t end_index,
+void DisplayItemList::AppendSubsequenceAsJSON(wtf_size_t begin_index,
+ wtf_size_t end_index,
JsonFlags flags,
JSONArray& json_array) const {
if (flags & kCompact) {
@@ -42,12 +42,12 @@ void DisplayItemList::AppendSubsequenceAsJSON(size_t begin_index,
<< "kCompact cannot show paint records";
DCHECK(!(flags & kShowOnlyDisplayItemTypes))
<< "kCompact cannot show display item types";
- for (size_t i = begin_index; i < end_index; ++i) {
+ for (auto i = begin_index; i < end_index; ++i) {
const auto& item = (*this)[i];
json_array.PushString(item.GetId().ToString());
}
} else {
- for (size_t i = begin_index; i < end_index; ++i) {
+ for (auto i = begin_index; i < end_index; ++i) {
auto json = std::make_unique<JSONObject>();
const auto& item = (*this)[i];
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_list.h b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_list.h
index d1f45b6e0d9..78b664c7902 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_list.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_list.h
@@ -19,14 +19,16 @@ struct PaintChunk;
// each derived display item; the ideal value is the least common multiple.
// The validity of kDisplayItemAlignment and kMaximumDisplayItemSize are checked
// in PaintController::CreateAndAppend().
-static const size_t kDisplayItemAlignment = alignof(ScrollbarDisplayItem);
-static const size_t kMaximumDisplayItemSize = sizeof(ScrollbarDisplayItem);
+static constexpr wtf_size_t kDisplayItemAlignment =
+ alignof(ScrollbarDisplayItem);
+static constexpr wtf_size_t kMaximumDisplayItemSize =
+ sizeof(ScrollbarDisplayItem);
// A container for a list of display items.
class PLATFORM_EXPORT DisplayItemList
: public ContiguousContainer<DisplayItem, kDisplayItemAlignment> {
public:
- DisplayItemList(size_t initial_size_bytes)
+ DisplayItemList(wtf_size_t initial_size_bytes)
: ContiguousContainer(kMaximumDisplayItemSize, initial_size_bytes) {}
DisplayItemList(DisplayItemList&& source)
: ContiguousContainer(std::move(source)) {}
@@ -42,7 +44,8 @@ class PLATFORM_EXPORT DisplayItemList
ContiguousContainer::AppendByMoving(item, item.DerivedSize());
// ContiguousContainer::AppendByMoving() calls an in-place constructor
// on item which replaces it with a tombstone/"dead display item" that
- // can be safely destructed but should never be used except for debugging.
+ // can be safely destructed but should never be used except for debugging
+ // and raster invalidation (see below).
DCHECK(item.IsTombstone());
// We need |visual_rect_| and |outset_for_raster_effects_| of the old
// display item for raster invalidation. Also, the fields that make up the
@@ -56,6 +59,7 @@ class PLATFORM_EXPORT DisplayItemList
DCHECK(item.GetId() == result.GetId());
item.visual_rect_ = result.visual_rect_;
item.outset_for_raster_effects_ = result.outset_for_raster_effects_;
+ result.SetMovedFromCachedSubsequence(false);
return result;
}
@@ -87,11 +91,11 @@ class PLATFORM_EXPORT DisplayItemList
};
typedef unsigned JsonFlags;
- std::unique_ptr<JSONArray> SubsequenceAsJSON(size_t begin_index,
- size_t end_index,
- JsonFlags) const;
- void AppendSubsequenceAsJSON(size_t begin_index,
- size_t end_index,
+ std::unique_ptr<JSONArray> DisplayItemsAsJSON(wtf_size_t begin_index,
+ wtf_size_t end_index,
+ JsonFlags) const;
+ void AppendSubsequenceAsJSON(wtf_size_t begin_index,
+ wtf_size_t end_index,
JsonFlags,
JSONArray&) const;
#endif // DCHECK_IS_ON()
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_raster_invalidator.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_raster_invalidator.cc
index 2d2433bf88a..4cba6b8b266 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_raster_invalidator.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_raster_invalidator.cc
@@ -22,12 +22,12 @@ void DisplayItemRasterInvalidator::Generate() {
Vector<bool> old_display_items_matched;
old_display_items_matched.resize(old_chunk_.size());
- size_t next_old_item_to_match = old_chunk_.begin_index;
- size_t max_cached_old_index = next_old_item_to_match;
+ auto next_old_item_to_match = old_chunk_.begin_index;
+ auto max_cached_old_index = next_old_item_to_match;
for (const auto& new_item :
new_paint_artifact_.GetDisplayItemList().ItemsInPaintChunk(new_chunk_)) {
- size_t matched_old_index =
+ auto matched_old_index =
MatchNewDisplayItemInOldChunk(new_item, next_old_item_to_match);
if (matched_old_index == kNotFound) {
if (new_item.DrawsContent()) {
@@ -69,7 +69,7 @@ void DisplayItemRasterInvalidator::Generate() {
value.reason = reason;
}
- size_t offset = matched_old_index - old_chunk_.begin_index;
+ wtf_size_t offset = matched_old_index - old_chunk_.begin_index;
DCHECK(!old_display_items_matched[offset]);
old_display_items_matched[offset] = true;
@@ -80,7 +80,7 @@ void DisplayItemRasterInvalidator::Generate() {
}
// Invalidate remaining unmatched (disappeared or uncacheable) old items.
- for (size_t i = old_chunk_.begin_index; i < old_chunk_.end_index; ++i) {
+ for (auto i = old_chunk_.begin_index; i < old_chunk_.end_index; ++i) {
if (old_display_items_matched[i - old_chunk_.begin_index])
continue;
@@ -97,9 +97,9 @@ void DisplayItemRasterInvalidator::Generate() {
}
}
-size_t DisplayItemRasterInvalidator::MatchNewDisplayItemInOldChunk(
+wtf_size_t DisplayItemRasterInvalidator::MatchNewDisplayItemInOldChunk(
const DisplayItem& new_item,
- size_t& next_old_item_to_match) {
+ wtf_size_t& next_old_item_to_match) {
if (!new_item.IsCacheable())
return kNotFound;
for (; next_old_item_to_match < old_chunk_.end_index;
@@ -111,7 +111,7 @@ size_t DisplayItemRasterInvalidator::MatchNewDisplayItemInOldChunk(
if (old_item.GetId() == new_item.GetId())
return next_old_item_to_match++;
// Add the skipped old item into index.
- old_display_items_index_.insert(&old_item.Client(), Vector<size_t>())
+ old_display_items_index_.insert(&old_item.Client(), Vector<wtf_size_t>())
.stored_value->value.push_back(next_old_item_to_match);
}
@@ -119,7 +119,7 @@ size_t DisplayItemRasterInvalidator::MatchNewDisplayItemInOldChunk(
auto it = old_display_items_index_.find(&new_item.Client());
if (it == old_display_items_index_.end())
return kNotFound;
- for (size_t i : it->value) {
+ for (auto i : it->value) {
const auto& old_item = old_paint_artifact_.GetDisplayItemList()[i];
if (old_item.GetId() == new_item.GetId())
return i;
@@ -136,7 +136,8 @@ void DisplayItemRasterInvalidator::AddRasterInvalidation(
if (r.IsEmpty())
return;
- invalidator_.AddRasterInvalidation(r, client, reason, old_or_new);
+ invalidator_.AddRasterInvalidation(raster_invalidation_function_, r, client,
+ reason, old_or_new);
}
void DisplayItemRasterInvalidator::GenerateRasterInvalidation(
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_raster_invalidator.h b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_raster_invalidator.h
index b37e15998eb..10828508e58 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_raster_invalidator.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_raster_invalidator.h
@@ -15,13 +15,16 @@ class DisplayItemRasterInvalidator {
STACK_ALLOCATED();
public:
- DisplayItemRasterInvalidator(RasterInvalidator& invalidator,
- const PaintArtifact& old_paint_artifact,
- const PaintArtifact& new_paint_artifact,
- const PaintChunk& old_chunk,
- const PaintChunk& new_chunk,
- const ChunkToLayerMapper& mapper)
+ DisplayItemRasterInvalidator(
+ RasterInvalidator& invalidator,
+ RasterInvalidator::RasterInvalidationFunction function,
+ const PaintArtifact& old_paint_artifact,
+ const PaintArtifact& new_paint_artifact,
+ const PaintChunk& old_chunk,
+ const PaintChunk& new_chunk,
+ const ChunkToLayerMapper& mapper)
: invalidator_(invalidator),
+ raster_invalidation_function_(function),
old_paint_artifact_(old_paint_artifact),
new_paint_artifact_(new_paint_artifact),
old_chunk_(old_chunk),
@@ -40,9 +43,9 @@ class DisplayItemRasterInvalidator {
const IntRect&,
PaintInvalidationReason,
RasterInvalidator::ClientIsOldOrNew);
- ALWAYS_INLINE size_t
+ ALWAYS_INLINE wtf_size_t
MatchNewDisplayItemInOldChunk(const DisplayItem& new_item,
- size_t& next_old_item_to_match);
+ wtf_size_t& next_old_item_to_match);
ALWAYS_INLINE void GenerateRasterInvalidation(const DisplayItemClient&,
const IntRect* old_visual_rect,
const IntRect* new_visual_rect,
@@ -58,13 +61,15 @@ class DisplayItemRasterInvalidator {
PaintInvalidationReason reason);
RasterInvalidator& invalidator_;
+ RasterInvalidator::RasterInvalidationFunction raster_invalidation_function_;
const PaintArtifact& old_paint_artifact_;
const PaintArtifact& new_paint_artifact_;
const PaintChunk& old_chunk_;
const PaintChunk& new_chunk_;
const ChunkToLayerMapper& mapper_;
// Maps clients to indices of display items in old_chunk_.
- HashMap<const DisplayItemClient*, Vector<size_t>> old_display_items_index_;
+ HashMap<const DisplayItemClient*, Vector<wtf_size_t>>
+ old_display_items_index_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_raster_invalidator_test.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_raster_invalidator_test.cc
index f3d5ff7a79f..b0eee71af71 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_raster_invalidator_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/display_item_raster_invalidator_test.cc
@@ -19,12 +19,12 @@ using ::testing::UnorderedElementsAre;
class DisplayItemRasterInvalidatorTest : public PaintControllerTestBase,
public PaintTestConfigurations {
protected:
- DisplayItemRasterInvalidatorTest() : invalidator_(base::DoNothing()) {}
+ DisplayItemRasterInvalidatorTest() = default;
Vector<RasterInvalidationInfo> GenerateRasterInvalidations() {
GetPaintController().CommitNewDisplayItems();
invalidator_.Generate(
- GetPaintController().GetPaintArtifactShared(),
+ base::DoNothing(), GetPaintController().GetPaintArtifactShared(),
// The layer rect is big enough not to clip display item raster
// invalidation rects.
IntRect(0, 0, 20000, 20000), PropertyTreeState::Root());
@@ -461,25 +461,27 @@ TEST_P(DisplayItemRasterInvalidatorTest, SwapOrderCrossingChunks) {
auto container2_properties = DefaultPaintChunkProperties();
container2_properties.SetEffect(*container2_effect);
- GetPaintController().UpdateCurrentPaintChunkProperties(
- PaintChunk::Id(container1, kBackgroundType), container1_properties);
+ PaintChunk::Id container1_id(container1, kBackgroundType);
+ PaintChunk::Id container2_id(container2, kBackgroundType);
+ GetPaintController().UpdateCurrentPaintChunkProperties(&container1_id,
+ container1_properties);
DrawRect(context, container1, kBackgroundType, FloatRect(100, 100, 100, 100));
DrawRect(context, content1, kBackgroundType, FloatRect(100, 100, 50, 200));
- GetPaintController().UpdateCurrentPaintChunkProperties(
- PaintChunk::Id(container2, kBackgroundType), container2_properties);
+ GetPaintController().UpdateCurrentPaintChunkProperties(&container2_id,
+ container2_properties);
DrawRect(context, container2, kBackgroundType, FloatRect(100, 200, 100, 100));
DrawRect(context, content2, kBackgroundType, FloatRect(100, 200, 50, 200));
GenerateRasterInvalidations();
// Move content2 into container1, without invalidation.
invalidator_.SetTracksRasterInvalidations(true);
- GetPaintController().UpdateCurrentPaintChunkProperties(
- PaintChunk::Id(container1, kBackgroundType), container1_properties);
+ GetPaintController().UpdateCurrentPaintChunkProperties(&container1_id,
+ container1_properties);
DrawRect(context, container1, kBackgroundType, FloatRect(100, 100, 100, 100));
DrawRect(context, content1, kBackgroundType, FloatRect(100, 100, 50, 200));
DrawRect(context, content2, kBackgroundType, FloatRect(100, 200, 50, 200));
- GetPaintController().UpdateCurrentPaintChunkProperties(
- PaintChunk::Id(container2, kBackgroundType), container2_properties);
+ GetPaintController().UpdateCurrentPaintChunkProperties(&container2_id,
+ container2_properties);
DrawRect(context, container2, kBackgroundType, FloatRect(100, 200, 100, 100));
EXPECT_THAT(GenerateRasterInvalidations(),
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_display_item.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_display_item.cc
index 0ab4e34249c..5e150bb70f9 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_display_item.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_display_item.cc
@@ -11,14 +11,9 @@
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkData.h"
-namespace blink {
+#include "third_party/blink/renderer/platform/graphics/logging_canvas.h"
-#if DCHECK_IS_ON()
-void DrawingDisplayItem::PropertiesAsJSON(JSONObject& json) const {
- DisplayItem::PropertiesAsJSON(json);
- json.SetBoolean("opaque", known_to_be_opaque_);
-}
-#endif
+namespace blink {
static SkBitmap RecordToBitmap(sk_sp<const PaintRecord> record,
const IntRect& bounds) {
@@ -83,4 +78,114 @@ bool DrawingDisplayItem::Equals(const DisplayItem& other) const {
return BitmapsEqual(std::move(record), std::move(other_record), bounds);
}
+SkColor DrawingDisplayItem::BackgroundColor() const {
+ if (GetType() != DisplayItem::kBoxDecorationBackground &&
+ GetType() != DisplayItem::kDocumentBackground)
+ return SK_ColorTRANSPARENT;
+
+ if (!record_)
+ return SK_ColorTRANSPARENT;
+
+ for (cc::PaintOpBuffer::Iterator it(record_.get()); it; ++it) {
+ const auto* op = *it;
+ if (op->GetType() == cc::PaintOpType::DrawRect ||
+ op->GetType() == cc::PaintOpType::DrawRRect) {
+ const auto& flags = static_cast<const cc::PaintOpWithFlags*>(op)->flags;
+ // Skip op with looper or shader which may modify the color.
+ if (!flags.getLooper() && !flags.getShader() &&
+ flags.getStyle() == cc::PaintFlags::kFill_Style)
+ return flags.getColor();
+ }
+ }
+ return SK_ColorTRANSPARENT;
+}
+
+// This is not a PaintRecord method because it's not a general opaqueness
+// detection algorithm (which might be more complex and slower), but works well
+// and fast for most blink painted results.
+bool DrawingDisplayItem::CalculateKnownToBeOpaque(
+ const PaintRecord* record) const {
+ if (!record)
+ return false;
+
+ // This limit keeps the algorithm fast, while allowing check of enough paint
+ // operations for most blink painted results.
+ constexpr wtf_size_t kOpCountLimit = 4;
+ wtf_size_t op_count = 0;
+ for (cc::PaintOpBuffer::Iterator it(record); it; ++it) {
+ if (++op_count > kOpCountLimit)
+ return false;
+
+ const auto* op = *it;
+ // Deal with the common pattern of clipped bleed avoiding images like:
+ // Save, ClipRect, Draw..., Restore.
+ if (op->GetType() == cc::PaintOpType::Save)
+ continue;
+ if (op->GetType() == cc::PaintOpType::ClipRect) {
+ const auto* clip_rect_op = static_cast<const cc::ClipRectOp*>(op);
+ if (!EnclosedIntRect(clip_rect_op->rect).Contains(VisualRect()))
+ return false;
+ continue;
+ }
+
+ if (!op->IsDrawOp())
+ return false;
+
+ if (op->GetType() == cc::PaintOpType::DrawRecord) {
+ return CalculateKnownToBeOpaque(
+ static_cast<const cc::DrawRecordOp*>(op)->record.get());
+ }
+
+ if (!op->IsPaintOpWithFlags())
+ continue;
+
+ const auto& flags = static_cast<const cc::PaintOpWithFlags*>(op)->flags;
+ if (flags.getStyle() != cc::PaintFlags::kFill_Style || flags.getLooper() ||
+ (flags.getBlendMode() != SkBlendMode::kSrc &&
+ flags.getBlendMode() != SkBlendMode::kSrcOver) ||
+ flags.getMaskFilter() || flags.getColorFilter() ||
+ flags.getImageFilter() || flags.getAlpha() != SK_AlphaOPAQUE ||
+ (flags.getShader() && !flags.getShader()->IsOpaque()))
+ continue;
+
+ IntRect opaque_rect;
+ switch (op->GetType()) {
+ case cc::PaintOpType::DrawRect:
+ opaque_rect =
+ EnclosedIntRect(static_cast<const cc::DrawRectOp*>(op)->rect);
+ break;
+ case cc::PaintOpType::DrawIRect:
+ opaque_rect = IntRect(static_cast<const cc::DrawIRectOp*>(op)->rect);
+ break;
+ case cc::PaintOpType::DrawImage: {
+ const auto* draw_image_op = static_cast<const cc::DrawImageOp*>(op);
+ const auto& image = draw_image_op->image;
+ if (!image.IsOpaque())
+ continue;
+ opaque_rect = IntRect(draw_image_op->left, draw_image_op->top,
+ image.width(), image.height());
+ break;
+ }
+ case cc::PaintOpType::DrawImageRect: {
+ const auto* draw_image_rect_op =
+ static_cast<const cc::DrawImageRectOp*>(op);
+ const auto& image = draw_image_rect_op->image;
+ DCHECK(SkRect::MakeWH(image.width(), image.height())
+ .contains(draw_image_rect_op->src));
+ if (!image.IsOpaque())
+ continue;
+ opaque_rect = EnclosedIntRect(draw_image_rect_op->dst);
+ break;
+ }
+ default:
+ continue;
+ }
+
+ // We should never paint outside of the visual rect.
+ if (opaque_rect.Contains(VisualRect()))
+ return true;
+ }
+ return false;
+}
+
} // namespace blink
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 9f3c691c5ff..a6fa2cd2fa4 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
@@ -25,46 +25,45 @@ namespace blink {
// PaintRecord, and is in the space of the DisplayItemList. This allows the
// visual_rect to be compared between DrawingDisplayItems, and to give bounds
// around what the user can actually see from the PaintRecord.
-class PLATFORM_EXPORT DrawingDisplayItem final : public DisplayItem {
+class PLATFORM_EXPORT DrawingDisplayItem : public DisplayItem {
public:
DISABLE_CFI_PERF
DrawingDisplayItem(const DisplayItemClient& client,
Type type,
- sk_sp<const PaintRecord> record,
- bool known_to_be_opaque = false);
+ sk_sp<const PaintRecord> record);
const sk_sp<const PaintRecord>& GetPaintRecord() const { return record_; }
+ bool Equals(const DisplayItem& other) const final;
+
bool KnownToBeOpaque() const {
- DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
- return known_to_be_opaque_;
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ return false;
+ if (!known_to_be_opaque_.has_value())
+ known_to_be_opaque_.emplace(CalculateKnownToBeOpaque(record_.get()));
+ return *known_to_be_opaque_;
}
+ void SetKnownToBeOpaqueForTesting() { known_to_be_opaque_.emplace(true); }
- bool Equals(const DisplayItem& other) const final;
+ SkColor BackgroundColor() const;
private:
-#if DCHECK_IS_ON()
- void PropertiesAsJSON(JSONObject&) const final;
-#endif
+ bool CalculateKnownToBeOpaque(const PaintRecord*) const;
sk_sp<const PaintRecord> record_;
-
- // True if there are no transparent areas. Only used for CompositeAfterPaint.
- const bool known_to_be_opaque_;
+ mutable base::Optional<bool> known_to_be_opaque_;
};
// TODO(dcheng): Move this ctor back inline once the clang plugin is fixed.
DISABLE_CFI_PERF
inline DrawingDisplayItem::DrawingDisplayItem(const DisplayItemClient& client,
Type type,
- sk_sp<const PaintRecord> record,
- bool known_to_be_opaque)
+ sk_sp<const PaintRecord> record)
: DisplayItem(client,
type,
sizeof(*this),
/* draws_content*/ record && record->size()),
- record_(DrawsContent() ? std::move(record) : nullptr),
- known_to_be_opaque_(known_to_be_opaque) {
+ record_(DrawsContent() ? std::move(record) : nullptr) {
DCHECK(IsDrawingType(type));
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_recorder.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_recorder.cc
index ccf85e0d22f..837a65d6dc8 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_recorder.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_recorder.cc
@@ -23,31 +23,36 @@ DrawingRecorder::DrawingRecorder(GraphicsContext& context,
DisplayItem::Type display_item_type)
: context_(context),
client_(display_item_client),
- type_(display_item_type),
- known_to_be_opaque_(false)
+ type_(display_item_type)
#if DCHECK_IS_ON()
,
initial_display_item_list_size_(
context_.GetPaintController().NewDisplayItemList().size())
#endif
{
- if (context.GetPaintController().DisplayItemConstructionIsDisabled())
- return;
-
// Must check DrawingRecorder::UseCachedDrawingIfPossible before creating the
// DrawingRecorder.
DCHECK(RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() ||
+ context_.GetPaintController().ShouldForcePaintForBenchmark() ||
!UseCachedDrawingIfPossible(context_, client_, type_));
DCHECK(DisplayItem::IsDrawingType(display_item_type));
context.SetInDrawingRecorder(true);
context.BeginRecording(FloatRect());
+
+ if (context.Printing()) {
+ DOMNodeId dom_node_id = display_item_client.OwnerNodeId();
+ if (dom_node_id != kInvalidDOMNodeId) {
+ dom_node_id_to_restore_ = context.GetDOMNodeId();
+ context.SetDOMNodeId(dom_node_id);
+ }
+ }
}
DrawingRecorder::~DrawingRecorder() {
- if (context_.GetPaintController().DisplayItemConstructionIsDisabled())
- return;
+ if (context_.Printing() && dom_node_id_to_restore_)
+ context_.SetDOMNodeId(dom_node_id_to_restore_.value());
context_.SetInDrawingRecorder(false);
@@ -58,20 +63,8 @@ DrawingRecorder::~DrawingRecorder() {
}
#endif
- sk_sp<const PaintRecord> picture = context_.EndRecording();
-
-#if DCHECK_IS_ON()
- // When skipping cache (e.g. in PaintRecordBuilder with a temporary
- // PaintController), the client's painting might be different from its normal
- // painting.
- if (!context_.GetPaintController().IsSkippingCache() &&
- client_.PaintedOutputOfObjectHasNoEffectRegardlessOfSize()) {
- DCHECK_EQ(0u, picture->size()) << client_.DebugName();
- }
-#endif
-
context_.GetPaintController().CreateAndAppend<DrawingDisplayItem>(
- client_, type_, std::move(picture), known_to_be_opaque_);
+ client_, type_, context_.EndRecording());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h b/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h
index 3c97d2c2445..3437f8d6ed6 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h
@@ -21,7 +21,7 @@ namespace blink {
class GraphicsContext;
class PLATFORM_EXPORT DrawingRecorder final {
- DISALLOW_NEW();
+ STACK_ALLOCATED();
public:
static bool UseCachedDrawingIfPossible(GraphicsContext& context,
@@ -50,22 +50,15 @@ class PLATFORM_EXPORT DrawingRecorder final {
~DrawingRecorder();
- void SetKnownToBeOpaque() {
- DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
- known_to_be_opaque_ = true;
- }
-
private:
GraphicsContext& context_;
const DisplayItemClient& client_;
const DisplayItem::Type type_;
-
- // True if there are no transparent areas. Only used for CompositeAfterPaint.
- bool known_to_be_opaque_;
+ base::Optional<DOMNodeId> dom_node_id_to_restore_;
#if DCHECK_IS_ON()
// Ensures the list size does not change during the recorder's scope.
- size_t initial_display_item_list_size_;
+ wtf_size_t initial_display_item_list_size_;
#endif
DISALLOW_COPY_AND_ASSIGN(DrawingRecorder);
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 480ff218deb..9c039137fd9 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
@@ -249,6 +249,13 @@ class PLATFORM_EXPORT EffectPaintPropertyNode
// CompositingReason::kActiveBackdropFilterAnimation;
}
+ // Whether the effect node uses the backdrop as an input. This includes
+ // exotic blending modes and backdrop filters.
+ bool HasBackdropEffect() const {
+ return BlendMode() != SkBlendMode::kSrcOver ||
+ !BackdropFilter().IsEmpty() || HasActiveBackdropFilterAnimation();
+ }
+
CompositingReasons DirectCompositingReasonsForDebugging() const {
return DirectCompositingReasons();
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/float_clip_rect.h b/chromium/third_party/blink/renderer/platform/graphics/paint/float_clip_rect.h
index c11b72e0597..d25a8428606 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/float_clip_rect.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/float_clip_rect.h
@@ -132,6 +132,16 @@ inline bool operator!=(const FloatClipRect& a, const FloatClipRect& b) {
return !(a == b);
}
+// The difference between FloatClipRect() (infinite by default) and
+// InfiniteLooseFloatClipRect() is that the former means no clip at all, and the
+// latter means a clip with unknown bounds. The intersection of the former with
+// a tight clip rect is tight, and that of the latter is loose.
+inline FloatClipRect InfiniteLooseFloatClipRect() {
+ FloatClipRect rect;
+ rect.ClearIsTight();
+ return rect;
+}
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_FLOAT_CLIP_RECT_H_
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 daa76c1b077..690644d7dd0 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
@@ -93,30 +93,25 @@ 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 base::Optional<PropertyTreeState>& properties) {
+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) {
PaintController& paint_controller = context.GetPaintController();
- if (paint_controller.DisplayItemConstructionIsDisabled())
- return;
-
// This is like ScopedPaintChunkProperties but uses null id because foreign
// layer chunk doesn't need an id nor a client.
base::Optional<PropertyTreeState> previous_properties;
if (properties) {
previous_properties.emplace(paint_controller.CurrentPaintChunkProperties());
- paint_controller.UpdateCurrentPaintChunkProperties(base::nullopt,
- *properties);
+ paint_controller.UpdateCurrentPaintChunkProperties(nullptr, *properties);
}
paint_controller.CreateAndAppend<ForeignLayerDisplayItem>(
client, type, std::move(layer), offset, json_client);
if (properties) {
- paint_controller.UpdateCurrentPaintChunkProperties(base::nullopt,
+ paint_controller.UpdateCurrentPaintChunkProperties(nullptr,
*previous_properties);
}
}
@@ -126,25 +121,9 @@ void RecordForeignLayer(GraphicsContext& context,
DisplayItem::Type type,
scoped_refptr<cc::Layer> layer,
const FloatPoint& offset,
- const base::Optional<PropertyTreeState>& properties) {
+ const PropertyTreeState* properties) {
RecordForeignLayerInternal(context, client, type, std::move(layer), offset,
nullptr, properties);
}
-void RecordGraphicsLayerAsForeignLayer(GraphicsContext& context,
- DisplayItem::Type type,
- const GraphicsLayer& graphics_layer) {
- // In pre-CompositeAfterPaint, the GraphicsLayer hierarchy is still built
- // during CompositingUpdate, and we have to clear them here to ensure no
- // extraneous layers are still attached. In future we will disable all
- // those layer hierarchy code so we won't need this line.
- DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
- graphics_layer.CcLayer()->RemoveAllChildren();
-
- RecordForeignLayerInternal(
- context, graphics_layer, type, graphics_layer.CcLayer(),
- FloatPoint(graphics_layer.GetOffsetFromTransformNode()), &graphics_layer,
- graphics_layer.GetPropertyTreeState());
-}
-
} // 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 95e3c4162f5..7e662a566ef 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 GraphicsLayer;
class LayerAsJSONClient;
// Represents foreign content (produced outside Blink) which draws to a layer.
@@ -22,7 +21,7 @@ class LayerAsJSONClient;
//
// Before CAP, this content is not painted, but is instead inserted into the
// GraphicsLayer tree.
-class PLATFORM_EXPORT ForeignLayerDisplayItem final : public DisplayItem {
+class PLATFORM_EXPORT ForeignLayerDisplayItem : public DisplayItem {
public:
ForeignLayerDisplayItem(const DisplayItemClient& client,
Type,
@@ -36,9 +35,9 @@ class PLATFORM_EXPORT ForeignLayerDisplayItem final : public DisplayItem {
const LayerAsJSONClient* GetLayerAsJSONClient() const;
// DisplayItem
- bool Equals(const DisplayItem&) const override;
+ bool Equals(const DisplayItem&) const final;
#if DCHECK_IS_ON()
- void PropertiesAsJSON(JSONObject&) const override;
+ void PropertiesAsJSON(JSONObject&) const final;
#endif
FloatPoint Offset() const { return offset_; }
@@ -75,13 +74,7 @@ PLATFORM_EXPORT void RecordForeignLayer(
DisplayItem::Type type,
scoped_refptr<cc::Layer> layer,
const FloatPoint& offset,
- const base::Optional<PropertyTreeState>& = base::nullopt);
-
-// Records a graphics layer into a GraphicsContext.
-PLATFORM_EXPORT void RecordGraphicsLayerAsForeignLayer(
- GraphicsContext& context,
- DisplayItem::Type type,
- const GraphicsLayer& graphics_layer);
+ const PropertyTreeState* properties = nullptr);
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.cc
index 901ab3cfdfe..ba8f4937747 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.cc
@@ -13,8 +13,10 @@ GeometryMapper::Translation2DOrMatrix
GeometryMapper::SourceToDestinationProjection(
const TransformPaintPropertyNode& source,
const TransformPaintPropertyNode& destination) {
- bool success;
- return SourceToDestinationProjectionInternal(source, destination, success);
+ bool has_animation = false;
+ bool success = false;
+ return SourceToDestinationProjectionInternal(source, destination,
+ has_animation, success);
}
// Returns flatten(destination_to_screen)^-1 * flatten(source_to_screen)
@@ -60,32 +62,35 @@ GeometryMapper::Translation2DOrMatrix
GeometryMapper::SourceToDestinationProjectionInternal(
const TransformPaintPropertyNode& source_arg,
const TransformPaintPropertyNode& destination_arg,
+ bool& has_animation,
bool& success) {
const auto& source = source_arg.Unalias();
const auto& destination = destination_arg.Unalias();
+ has_animation = false;
+ success = true;
- if (&source == &destination) {
- success = true;
+ if (&source == &destination)
return Translation2DOrMatrix();
- }
if (source.Parent() && &destination == &source.Parent()->Unalias()) {
if (source.IsIdentityOr2DTranslation()) {
- success = true;
+ // We always use full matrix for animating transforms.
+ DCHECK(!source.HasActiveTransformAnimation());
return Translation2DOrMatrix(source.Translation2D());
}
// The result will be translate(origin)*matrix*translate(-origin) which
// equals to matrix if the origin is zero or if the matrix is just
// identity or 2d translation.
if (source.Origin().IsZero()) {
- success = true;
+ has_animation = source.HasActiveTransformAnimation();
return Translation2DOrMatrix(source.Matrix());
}
}
if (destination.IsIdentityOr2DTranslation() && destination.Parent() &&
&source == &destination.Parent()->Unalias()) {
- success = true;
+ // We always use full matrix for animating transforms.
+ DCHECK(!destination.HasActiveTransformAnimation());
return Translation2DOrMatrix(-destination.Translation2D());
}
@@ -96,7 +101,7 @@ GeometryMapper::SourceToDestinationProjectionInternal(
// the same 2d translation root.
if (source_cache.root_of_2d_translation() ==
destination_cache.root_of_2d_translation()) {
- success = true;
+ // We always use full matrix for animating transforms.
return Translation2DOrMatrix(source_cache.to_2d_translation_root() -
destination_cache.to_2d_translation_root());
}
@@ -105,7 +110,8 @@ GeometryMapper::SourceToDestinationProjectionInternal(
// Even if destination may have invertible screen projection,
// this formula is likely to be numerically more stable.
if (source_cache.plane_root() == destination_cache.plane_root()) {
- success = true;
+ has_animation = source_cache.has_animation_to_plane_root() ||
+ destination_cache.has_animation_to_plane_root();
if (&source == destination_cache.plane_root()) {
return Translation2DOrMatrix(destination_cache.from_plane_root());
}
@@ -124,6 +130,8 @@ GeometryMapper::SourceToDestinationProjectionInternal(
// Screen transform data are updated lazily because they are rarely used.
source.UpdateScreenTransform();
destination.UpdateScreenTransform();
+ has_animation = source_cache.has_animation_to_screen() ||
+ destination_cache.has_animation_to_screen();
if (!destination_cache.projection_from_screen_is_valid()) {
success = false;
return Translation2DOrMatrix();
@@ -132,7 +140,6 @@ GeometryMapper::SourceToDestinationProjectionInternal(
// Case 3: Compute:
// flatten(destination_to_screen)^-1 * flatten(source_to_screen)
const auto& root = TransformPaintPropertyNode::Root();
- success = true;
if (&source == &root)
return Translation2DOrMatrix(destination_cache.projection_from_screen());
TransformationMatrix matrix;
@@ -147,11 +154,12 @@ bool GeometryMapper::LocalToAncestorVisualRect(
const PropertyTreeState& ancestor_state,
FloatClipRect& mapping_rect,
OverlayScrollbarClipBehavior clip_behavior,
- InclusiveIntersectOrNot inclusive_behavior) {
+ InclusiveIntersectOrNot inclusive_behavior,
+ ExpandVisualRectForAnimationOrNot expand_for_animation) {
bool success = false;
- bool result = LocalToAncestorVisualRectInternal(local_state, ancestor_state,
- mapping_rect, clip_behavior,
- inclusive_behavior, success);
+ bool result = LocalToAncestorVisualRectInternal(
+ local_state, ancestor_state, mapping_rect, clip_behavior,
+ inclusive_behavior, expand_for_animation, success);
DCHECK(success);
return result;
}
@@ -162,6 +170,7 @@ bool GeometryMapper::LocalToAncestorVisualRectInternal(
FloatClipRect& rect_to_map,
OverlayScrollbarClipBehavior clip_behavior,
InclusiveIntersectOrNot inclusive_behavior,
+ ExpandVisualRectForAnimationOrNot expand_for_animation,
bool& success) {
if (local_state == ancestor_state) {
success = true;
@@ -171,11 +180,13 @@ bool GeometryMapper::LocalToAncestorVisualRectInternal(
if (&local_state.Effect().Unalias() != &ancestor_state.Effect().Unalias()) {
return SlowLocalToAncestorVisualRectWithEffects(
local_state, ancestor_state, rect_to_map, clip_behavior,
- inclusive_behavior, success);
+ inclusive_behavior, expand_for_animation, success);
}
+ bool has_animation = false;
const auto& translation_2d_or_matrix = SourceToDestinationProjectionInternal(
- local_state.Transform(), ancestor_state.Transform(), success);
+ local_state.Transform(), ancestor_state.Transform(), has_animation,
+ success);
if (!success) {
// A failure implies either source-to-plane or destination-to-plane being
// singular. A notable example of singular source-to-plane from valid CSS:
@@ -192,11 +203,19 @@ bool GeometryMapper::LocalToAncestorVisualRectInternal(
rect_to_map = FloatClipRect(FloatRect());
return false;
}
- translation_2d_or_matrix.MapFloatClipRect(rect_to_map);
+
+ if (has_animation && expand_for_animation == kExpandVisualRectForAnimation) {
+ // Assume during the animation the transform can map |rect_to_map| to
+ // anywhere. Ancestor clips will still apply.
+ // TODO(crbug.com/1026653): Use animation bounds instead of infinite rect.
+ rect_to_map = InfiniteLooseFloatClipRect();
+ } else {
+ translation_2d_or_matrix.MapFloatClipRect(rect_to_map);
+ }
FloatClipRect clip_rect = LocalToAncestorClipRectInternal(
local_state.Clip(), ancestor_state.Clip(), ancestor_state.Transform(),
- clip_behavior, inclusive_behavior, success);
+ clip_behavior, inclusive_behavior, expand_for_animation, success);
if (success) {
// This is where we propagate the roundedness and tightness of |clip_rect|
// to |rect_to_map|.
@@ -225,6 +244,7 @@ bool GeometryMapper::SlowLocalToAncestorVisualRectWithEffects(
FloatClipRect& mapping_rect,
OverlayScrollbarClipBehavior clip_behavior,
InclusiveIntersectOrNot inclusive_behavior,
+ ExpandVisualRectForAnimationOrNot expand_for_animation,
bool& success) {
PropertyTreeState last_transform_and_clip_state(
local_state.Transform(), local_state.Clip(),
@@ -234,16 +254,26 @@ bool GeometryMapper::SlowLocalToAncestorVisualRectWithEffects(
for (const auto* effect = &local_state.Effect().Unalias();
effect && effect != &ancestor_effect;
effect = SafeUnalias(effect->Parent())) {
+ if (effect->HasActiveFilterAnimation() &&
+ expand_for_animation == kExpandVisualRectForAnimation) {
+ // Assume during the animation the filter can map |rect_to_map| to
+ // anywhere. Ancestor clips will still apply.
+ // TODO(crbug.com/1026653): Use animation bounds instead of infinite rect.
+ mapping_rect = InfiniteLooseFloatClipRect();
+ last_transform_and_clip_state.SetTransform(effect->LocalTransformSpace());
+ last_transform_and_clip_state.SetClip(*effect->OutputClip());
+ continue;
+ }
+
if (!effect->HasFilterThatMovesPixels())
continue;
- DCHECK(effect->OutputClip());
PropertyTreeState transform_and_clip_state(effect->LocalTransformSpace(),
*effect->OutputClip(),
EffectPaintPropertyNode::Root());
bool intersects = LocalToAncestorVisualRectInternal(
last_transform_and_clip_state, transform_and_clip_state, mapping_rect,
- clip_behavior, inclusive_behavior, success);
+ clip_behavior, inclusive_behavior, expand_for_animation, success);
if (!success || !intersects) {
success = true;
mapping_rect = FloatClipRect(FloatRect());
@@ -259,7 +289,8 @@ bool GeometryMapper::SlowLocalToAncestorVisualRectWithEffects(
EffectPaintPropertyNode::Root());
bool intersects = LocalToAncestorVisualRectInternal(
last_transform_and_clip_state, final_transform_and_clip_state,
- mapping_rect, clip_behavior, inclusive_behavior, success);
+ mapping_rect, clip_behavior, inclusive_behavior, expand_for_animation,
+ success);
// Many effects (e.g. filters, clip-paths) can make a clip rect not tight.
mapping_rect.ClearIsTight();
@@ -278,7 +309,7 @@ FloatClipRect GeometryMapper::LocalToAncestorClipRect(
bool success = false;
auto result = LocalToAncestorClipRectInternal(
local_clip, ancestor_clip, ancestor_state.Transform(), clip_behavior,
- kNonInclusiveIntersect, success);
+ kNonInclusiveIntersect, kDontExpandVisualRectForAnimation, success);
DCHECK(success);
// Many effects (e.g. filters, clip-paths) can make a clip rect not tight.
@@ -293,8 +324,8 @@ static FloatClipRect GetClipRect(const ClipPaintPropertyNode& clip_node_arg,
const auto& clip_node = clip_node_arg.Unalias();
FloatClipRect clip_rect(
UNLIKELY(clip_behavior == kExcludeOverlayScrollbarSizeForHitTesting)
- ? clip_node.ClipRectExcludingOverlayScrollbars()
- : FloatClipRect(clip_node.ClipRect()));
+ ? clip_node.UnsnappedClipRectExcludingOverlayScrollbars()
+ : FloatClipRect(clip_node.UnsnappedClipRect()));
if (clip_node.ClipPath())
clip_rect.ClearIsTight();
return clip_rect;
@@ -306,6 +337,7 @@ FloatClipRect GeometryMapper::LocalToAncestorClipRectInternal(
const TransformPaintPropertyNode& ancestor_transform_arg,
OverlayScrollbarClipBehavior clip_behavior,
InclusiveIntersectOrNot inclusive_behavior,
+ ExpandVisualRectForAnimationOrNot expand_for_animation,
bool& success) {
const auto& descendant_clip = descendant_clip_arg.Unalias();
const auto& ancestor_clip = ancestor_clip_arg.Unalias();
@@ -330,13 +362,19 @@ FloatClipRect GeometryMapper::LocalToAncestorClipRectInternal(
// Iterate over the path from localState.clip to ancestor_state.clip. Stop if
// we've found a memoized (precomputed) clip for any particular node.
while (clip_node && clip_node != &ancestor_clip) {
- const FloatClipRect* cached_clip = nullptr;
+ const GeometryMapperClipCache::ClipCacheEntry* cached_clip = nullptr;
// Inclusive intersected clips are not cached at present.
if (inclusive_behavior != kInclusiveIntersect)
cached_clip = clip_node->GetClipCache().GetCachedClip(clip_and_transform);
+ if (cached_clip && cached_clip->has_transform_animation &&
+ expand_for_animation == kExpandVisualRectForAnimation) {
+ // Don't use cached clip if it's transformed by any animating transform.
+ cached_clip = nullptr;
+ }
+
if (cached_clip) {
- clip = *cached_clip;
+ clip = cached_clip->clip_rect;
break;
}
@@ -354,23 +392,27 @@ FloatClipRect GeometryMapper::LocalToAncestorClipRectInternal(
// Ignore it for SPv1 for now.
success = true;
}
- FloatClipRect loose_infinite;
- loose_infinite.ClearIsTight();
- return loose_infinite;
+ return InfiniteLooseFloatClipRect();
}
// Iterate down from the top intermediate node found in the previous loop,
// computing and memoizing clip rects as we go.
for (auto it = intermediate_nodes.rbegin(); it != intermediate_nodes.rend();
++it) {
+ bool has_animation = false;
const auto& translation_2d_or_matrix =
SourceToDestinationProjectionInternal((*it)->LocalTransformSpace(),
- ancestor_transform, success);
+ ancestor_transform, has_animation,
+ success);
if (!success) {
success = true;
return FloatClipRect(FloatRect());
}
+ // Don't apply this clip if it's transformed by any animating transform.
+ if (has_animation && expand_for_animation == kExpandVisualRectForAnimation)
+ continue;
+
// This is where we generate the roundedness and tightness of clip rect
// from clip and transform properties, and propagate them to |clip|.
FloatClipRect mapped_rect(GetClipRect(**it, clip_behavior));
@@ -380,13 +422,18 @@ FloatClipRect GeometryMapper::LocalToAncestorClipRectInternal(
} else {
clip.Intersect(mapped_rect);
// Inclusive intersected clips are not cached at present.
- (*it)->GetClipCache().SetCachedClip(clip_and_transform, clip);
+ (*it)->GetClipCache().SetCachedClip(
+ GeometryMapperClipCache::ClipCacheEntry{clip_and_transform, clip,
+ has_animation});
}
}
- // Inclusive intersected clips are not cached at present.
+ // Clips that are inclusive intersected or expanded for animation are not
+ // cached at present.
DCHECK(inclusive_behavior == kInclusiveIntersect ||
- *descendant_clip.GetClipCache().GetCachedClip(clip_and_transform) ==
- clip);
+ expand_for_animation == kExpandVisualRectForAnimation ||
+ descendant_clip.GetClipCache()
+ .GetCachedClip(clip_and_transform)
+ ->clip_rect == clip);
success = true;
return clip;
}
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 30c98a0280e..7a55af4fdb5 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
@@ -18,6 +18,17 @@ namespace blink {
// Clips can use FloatRect::Intersect or FloatRect::InclusiveIntersect.
enum InclusiveIntersectOrNot { kNonInclusiveIntersect, kInclusiveIntersect };
+// Whether to expand the visual or clip rect to infinity when we meet any
+// animating transform or filter when walking from a descendant state to an
+// ancestor state, when mapping a visual rect or getting the accumulated clip
+// rect. After we expanded the rect, we will still apply ancestor clips when
+// continuing walking up the tree. TODO(crbug.com/1026653): Consider animation
+// bounds instead of using infinite rect.
+enum ExpandVisualRectForAnimationOrNot {
+ kDontExpandVisualRectForAnimation,
+ kExpandVisualRectForAnimation,
+};
+
// GeometryMapper is a helper class for fast computations of transformed and
// visual rects in different PropertyTreeStates. The design document has a
// number of details on use cases, algorithmic definitions, and running times.
@@ -100,7 +111,16 @@ class PLATFORM_EXPORT GeometryMapper {
return SkMatrix::MakeTrans(Translation2D().Width(),
Translation2D().Height());
}
- return TransformationMatrix::ToSkMatrix44(Matrix());
+ return SkMatrix(TransformationMatrix::ToSkMatrix44(Matrix()));
+ }
+
+ bool operator==(const Translation2DOrMatrix& other) {
+ return translation_2d_ == other.translation_2d_ &&
+ matrix_ == other.matrix_;
+ }
+
+ bool operator!=(const Translation2DOrMatrix& other) {
+ return !(*this == other);
}
private:
@@ -149,9 +169,10 @@ class PLATFORM_EXPORT GeometryMapper {
return;
}
+ bool has_animation = false;
bool success = false;
- const auto& source_to_destination =
- SourceToDestinationProjectionInternal(source, destination, success);
+ const auto& source_to_destination = SourceToDestinationProjectionInternal(
+ source, destination, has_animation, success);
if (!success)
mapping_rect = Rect();
else
@@ -164,6 +185,9 @@ class PLATFORM_EXPORT GeometryMapper {
// on contents of |local_state|, it's not affected by any effect nodes between
// |local_state| and |ancestor_state|.
//
+ // The UnsnappedClipRect of any clip nodes is used, *not* the
+ // PixelSnappedClipRect.
+ //
// Note that the clip of |ancestor_state| is *not* applied.
//
// The output FloatClipRect may contain false positives for rounded-ness
@@ -215,7 +239,8 @@ class PLATFORM_EXPORT GeometryMapper {
const PropertyTreeState& ancestor_state,
FloatClipRect& mapping_rect,
OverlayScrollbarClipBehavior = kIgnorePlatformOverlayScrollbarSize,
- InclusiveIntersectOrNot = kNonInclusiveIntersect);
+ InclusiveIntersectOrNot = kNonInclusiveIntersect,
+ ExpandVisualRectForAnimationOrNot = kDontExpandVisualRectForAnimation);
static void ClearCache();
@@ -228,6 +253,7 @@ class PLATFORM_EXPORT GeometryMapper {
static Translation2DOrMatrix SourceToDestinationProjectionInternal(
const TransformPaintPropertyNode& source,
const TransformPaintPropertyNode& destination,
+ bool& has_animation,
bool& success);
static FloatClipRect LocalToAncestorClipRectInternal(
@@ -236,6 +262,7 @@ class PLATFORM_EXPORT GeometryMapper {
const TransformPaintPropertyNode& ancestor_transform,
OverlayScrollbarClipBehavior,
InclusiveIntersectOrNot,
+ ExpandVisualRectForAnimationOrNot,
bool& success);
// The return value has the same meaning as that for
@@ -246,6 +273,7 @@ class PLATFORM_EXPORT GeometryMapper {
FloatClipRect& mapping_rect,
OverlayScrollbarClipBehavior,
InclusiveIntersectOrNot,
+ ExpandVisualRectForAnimationOrNot,
bool& success);
// The return value has the same meaning as that for
@@ -256,6 +284,7 @@ class PLATFORM_EXPORT GeometryMapper {
FloatClipRect& mapping_rect,
OverlayScrollbarClipBehavior,
InclusiveIntersectOrNot,
+ ExpandVisualRectForAnimationOrNot,
bool& success);
static void MoveRect(FloatRect& rect, const FloatSize& delta) {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_clip_cache.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_clip_cache.cc
index 374c7b41ad4..5feb0102cc1 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_clip_cache.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_clip_cache.cc
@@ -31,28 +31,23 @@ void GeometryMapperClipCache::InvalidateCacheIfNeeded() {
}
}
-const FloatClipRect* GeometryMapperClipCache::GetCachedClip(
+const GeometryMapperClipCache::ClipCacheEntry*
+GeometryMapperClipCache::GetCachedClip(
const ClipAndTransform& clip_and_transform) {
InvalidateCacheIfNeeded();
for (const auto& entry : clip_cache_) {
if (entry.clip_and_transform == clip_and_transform) {
- return &entry.clip_rect;
+ return &entry;
}
}
return nullptr;
}
-void GeometryMapperClipCache::SetCachedClip(
- const ClipAndTransform& clip_and_transform,
- const FloatClipRect& clip) {
+void GeometryMapperClipCache::SetCachedClip(const ClipCacheEntry& entry) {
InvalidateCacheIfNeeded();
-#if DCHECK_IS_ON()
- for (const auto& entry : clip_cache_) {
- if (entry.clip_and_transform == clip_and_transform)
- DCHECK(false); // There should be no existing entry.
- }
-#endif
- clip_cache_.push_back(ClipCacheEntry(clip_and_transform, clip));
+ // There should be no existing entry.
+ DCHECK(!GetCachedClip(entry.clip_and_transform));
+ clip_cache_.push_back(entry);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_clip_cache.h b/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_clip_cache.h
index 470b482e760..820475aca56 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_clip_cache.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_clip_cache.h
@@ -45,28 +45,29 @@ class PLATFORM_EXPORT GeometryMapperClipCache {
}
};
+ struct ClipCacheEntry {
+ const ClipAndTransform clip_and_transform;
+ // The clip visual rect of the associated clip node in the space of
+ // |clip_and_transform|.
+ const FloatClipRect clip_rect;
+ // Whether there is any transform animation between the transform space
+ // of the associated clip node and |clip_and_transform|.
+ const bool has_transform_animation;
+ };
+
// Returns the clip visual rect of the owning
// clip of |this| in the space of |ancestors|, if there is one cached.
// Otherwise returns null.
- const FloatClipRect* GetCachedClip(const ClipAndTransform& ancestors);
+ const ClipCacheEntry* GetCachedClip(const ClipAndTransform& ancestors);
- // Stores the "clip visual rect" of |this in the space of |ancestors|,
+ // Stores cached the "clip visual rect" of |this| in the space of |ancestors|,
// into a local cache.
- void SetCachedClip(const ClipAndTransform&, const FloatClipRect&);
+ void SetCachedClip(const ClipCacheEntry&);
static void ClearCache();
bool IsValid() const;
private:
- struct ClipCacheEntry {
- const ClipAndTransform clip_and_transform;
- const FloatClipRect clip_rect;
- ClipCacheEntry(const ClipAndTransform& clip_and_transform_arg,
- const FloatClipRect& clip_rect_arg)
- : clip_and_transform(clip_and_transform_arg),
- clip_rect(clip_rect_arg) {}
- };
-
void InvalidateCacheIfNeeded();
Vector<ClipCacheEntry> clip_cache_;
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 fea4d4d387c..9e32de68f0c 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
@@ -20,7 +20,7 @@ namespace blink {
class GeometryMapperTest : public testing::Test,
public PaintTestConfigurations {
public:
- const FloatClipRect* GetCachedClip(
+ const GeometryMapperClipCache::ClipCacheEntry* GetCachedClip(
const ClipPaintPropertyNode& descendant_clip,
const PropertyTreeState& ancestor_property_tree_state) {
GeometryMapperClipCache::ClipAndTransform clip_and_transform(
@@ -37,18 +37,28 @@ class GeometryMapperTest : public testing::Test,
bool& success) {
GeometryMapper::LocalToAncestorVisualRectInternal(
local_state, ancestor_state, mapping_rect,
- kIgnorePlatformOverlayScrollbarSize, kNonInclusiveIntersect, success);
+ kIgnorePlatformOverlayScrollbarSize, kNonInclusiveIntersect,
+ kDontExpandVisualRectForAnimation, success);
}
- // Variables required by CHECK_MAPPINGS(). The tests should set these
- // variables with proper values before calling CHECK_MAPPINGS().
+ void CheckMappings();
+ void CheckLocalToAncestorVisualRect();
+ void CheckLocalToAncestorClipRect();
+ void CheckSourceToDestinationRect();
+ void CheckSourceToDestinationProjection();
+ void CheckCachedClip();
+
+ // Variables required by CheckMappings(). The tests should set these
+ // variables with proper values before calling CheckMappings().
PropertyTreeState local_state = PropertyTreeState::Root();
PropertyTreeState ancestor_state = PropertyTreeState::Root();
FloatRect input_rect;
FloatClipRect expected_visual_rect;
+ base::Optional<FloatClipRect> expected_visual_rect_expanded_for_animation;
FloatSize expected_translation_2d;
base::Optional<TransformationMatrix> expected_transform;
FloatClipRect expected_clip;
+ bool expected_clip_has_transform_animation = false;
FloatRect expected_transformed_rect;
};
@@ -76,89 +86,88 @@ INSTANTIATE_PAINT_TEST_SUITE_P(GeometryMapperTest);
EXPECT_FLOAT_RECT_NEAR((expected).Rect(), (actual).Rect()); \
} while (false)
-#define CHECK_LOCAL_TO_ANCESTOR_VISUAL_RECT() \
- do { \
- SCOPED_TRACE("Check LocalToAncestorVisualRect"); \
- FloatClipRect actual_visual_rect(input_rect); \
- GeometryMapper::LocalToAncestorVisualRect(local_state, ancestor_state, \
- actual_visual_rect); \
- EXPECT_CLIP_RECT_EQ(expected_visual_rect, actual_visual_rect); \
- } while (false)
+void GeometryMapperTest::CheckLocalToAncestorVisualRect() {
+ FloatClipRect actual_visual_rect(input_rect);
+ GeometryMapper::LocalToAncestorVisualRect(local_state, ancestor_state,
+ actual_visual_rect);
+ EXPECT_CLIP_RECT_EQ(expected_visual_rect, actual_visual_rect);
-#define CHECK_LOCAL_TO_ANCESTOR_CLIP_RECT() \
- do { \
- SCOPED_TRACE("Check LocalToAncestorClipRect"); \
- FloatClipRect actual_clip_rect; \
- actual_clip_rect = \
- GeometryMapper::LocalToAncestorClipRect(local_state, ancestor_state); \
- EXPECT_CLIP_RECT_EQ(expected_clip, actual_clip_rect); \
- } while (false)
+ actual_visual_rect = FloatClipRect(input_rect);
+ GeometryMapper::LocalToAncestorVisualRect(
+ local_state, ancestor_state, actual_visual_rect,
+ kIgnorePlatformOverlayScrollbarSize, kNonInclusiveIntersect,
+ kExpandVisualRectForAnimation);
+ EXPECT_CLIP_RECT_EQ(expected_visual_rect_expanded_for_animation
+ ? *expected_visual_rect_expanded_for_animation
+ : expected_visual_rect,
+ actual_visual_rect);
+}
-#define CHECK_SOURCE_TO_DESTINATION_RECT() \
- do { \
- SCOPED_TRACE("Check SourceToDestinationRect"); \
- auto actual_transformed_rect = input_rect; \
- GeometryMapper::SourceToDestinationRect(local_state.Transform(), \
- ancestor_state.Transform(), \
- actual_transformed_rect); \
- EXPECT_FLOAT_RECT_NEAR(expected_transformed_rect, \
- actual_transformed_rect); \
- } while (false)
+void GeometryMapperTest::CheckLocalToAncestorClipRect() {
+ FloatClipRect actual_clip_rect =
+ GeometryMapper::LocalToAncestorClipRect(local_state, ancestor_state);
+ EXPECT_CLIP_RECT_EQ(expected_clip, actual_clip_rect);
+}
-#define CHECK_SOURCE_TO_DESTINATION_PROJECTION() \
- do { \
- SCOPED_TRACE("Check SourceToDestinationProjection"); \
- const auto& actual_transform_to_ancestor = \
- GeometryMapper::SourceToDestinationProjection( \
- local_state.Transform(), ancestor_state.Transform()); \
- if (expected_transform) { \
- EXPECT_EQ(*expected_transform, actual_transform_to_ancestor.Matrix()); \
- } else { \
- EXPECT_EQ(expected_translation_2d, \
- actual_transform_to_ancestor.Translation2D()); \
- } \
- } while (false)
+void GeometryMapperTest::CheckSourceToDestinationRect() {
+ auto actual_transformed_rect = input_rect;
+ GeometryMapper::SourceToDestinationRect(local_state.Transform(),
+ ancestor_state.Transform(),
+ actual_transformed_rect);
+ EXPECT_FLOAT_RECT_NEAR(expected_transformed_rect, actual_transformed_rect);
+}
-#define CHECK_CACHED_CLIP() \
- do { \
- if (&ancestor_state.Effect() != &local_state.Effect()) \
- break; \
- SCOPED_TRACE("Check cached clip"); \
- const auto& local_clip = local_state.Clip().Unalias(); \
- const auto* cached_clip = GetCachedClip(local_clip, ancestor_state); \
- if (&ancestor_state.Clip() == &local_clip || \
- (&ancestor_state.Clip() == local_clip.Parent() && \
- &ancestor_state.Transform() == &local_clip.LocalTransformSpace())) { \
- EXPECT_EQ(nullptr, cached_clip); \
- break; \
- } \
- ASSERT_NE(nullptr, cached_clip); \
- EXPECT_CLIP_RECT_EQ(expected_clip, *cached_clip); \
- } while (false)
+void GeometryMapperTest::CheckSourceToDestinationProjection() {
+ const auto& actual_transform_to_ancestor =
+ GeometryMapper::SourceToDestinationProjection(local_state.Transform(),
+ ancestor_state.Transform());
+ if (expected_transform) {
+ EXPECT_EQ(*expected_transform, actual_transform_to_ancestor.Matrix());
+ } else {
+ EXPECT_EQ(expected_translation_2d,
+ actual_transform_to_ancestor.Translation2D());
+ }
+}
+
+void GeometryMapperTest::CheckCachedClip() {
+ if (&ancestor_state.Effect() != &local_state.Effect())
+ return;
+ const auto& local_clip = local_state.Clip().Unalias();
+ const auto* cached_clip = GetCachedClip(local_clip, ancestor_state);
+ if (&ancestor_state.Clip() == &local_clip ||
+ (&ancestor_state.Clip() == local_clip.Parent() &&
+ &ancestor_state.Transform() == &local_clip.LocalTransformSpace())) {
+ EXPECT_EQ(nullptr, cached_clip);
+ return;
+ }
+ ASSERT_NE(nullptr, cached_clip);
+ EXPECT_CLIP_RECT_EQ(expected_clip, cached_clip->clip_rect);
+ EXPECT_EQ(expected_clip_has_transform_animation,
+ cached_clip->has_transform_animation);
+}
// See the data fields of GeometryMapperTest for variables that will be used in
// this macro.
-#define CHECK_MAPPINGS() \
- do { \
- CHECK_LOCAL_TO_ANCESTOR_VISUAL_RECT(); \
- CHECK_LOCAL_TO_ANCESTOR_CLIP_RECT(); \
- CHECK_SOURCE_TO_DESTINATION_RECT(); \
- CHECK_SOURCE_TO_DESTINATION_PROJECTION(); \
- { \
- SCOPED_TRACE("Repeated check to test caching"); \
- CHECK_LOCAL_TO_ANCESTOR_VISUAL_RECT(); \
- CHECK_LOCAL_TO_ANCESTOR_CLIP_RECT(); \
- CHECK_SOURCE_TO_DESTINATION_RECT(); \
- CHECK_SOURCE_TO_DESTINATION_PROJECTION(); \
- } \
- CHECK_CACHED_CLIP(); \
- } while (false)
+void GeometryMapperTest::CheckMappings() {
+ CheckLocalToAncestorVisualRect();
+ CheckLocalToAncestorClipRect();
+ CheckSourceToDestinationRect();
+ CheckSourceToDestinationProjection();
+ {
+ SCOPED_TRACE("Repeated check to test caching");
+ CheckLocalToAncestorVisualRect();
+ CheckLocalToAncestorClipRect();
+ CheckSourceToDestinationRect();
+ CheckSourceToDestinationProjection();
+ }
+ CheckCachedClip();
+}
TEST_P(GeometryMapperTest, Root) {
input_rect = FloatRect(0, 0, 100, 100);
expected_visual_rect = FloatClipRect(input_rect);
expected_transformed_rect = input_rect;
- CHECK_MAPPINGS();
+ CheckMappings();
}
TEST_P(GeometryMapperTest, IdentityTransform) {
@@ -168,7 +177,7 @@ TEST_P(GeometryMapperTest, IdentityTransform) {
input_rect = FloatRect(0, 0, 100, 100);
expected_transformed_rect = input_rect;
expected_visual_rect = FloatClipRect(input_rect);
- CHECK_MAPPINGS();
+ CheckMappings();
}
TEST_P(GeometryMapperTest, TranslationTransform) {
@@ -180,7 +189,7 @@ TEST_P(GeometryMapperTest, TranslationTransform) {
expected_transformed_rect = input_rect;
expected_transformed_rect.Move(expected_translation_2d);
expected_visual_rect = FloatClipRect(expected_transformed_rect);
- CHECK_MAPPINGS();
+ CheckMappings();
FloatRect rect = expected_transformed_rect;
GeometryMapper::SourceToDestinationRect(t0(), local_state.Transform(), rect);
@@ -197,7 +206,7 @@ TEST_P(GeometryMapperTest, TranslationTransformWithAlias) {
expected_transformed_rect = input_rect;
expected_transformed_rect.Move(expected_translation_2d);
expected_visual_rect = FloatClipRect(expected_transformed_rect);
- CHECK_MAPPINGS();
+ CheckMappings();
FloatRect rect = expected_transformed_rect;
GeometryMapper::SourceToDestinationRect(t0(), local_state.Transform(), rect);
@@ -213,7 +222,7 @@ TEST_P(GeometryMapperTest, RotationAndScaleTransform) {
expected_transformed_rect = expected_transform->MapRect(input_rect);
expected_visual_rect = FloatClipRect(expected_transformed_rect);
expected_visual_rect.ClearIsTight();
- CHECK_MAPPINGS();
+ CheckMappings();
}
TEST_P(GeometryMapperTest, RotationAndScaleTransformWithAlias) {
@@ -226,7 +235,7 @@ TEST_P(GeometryMapperTest, RotationAndScaleTransformWithAlias) {
expected_transformed_rect = expected_transform->MapRect(input_rect);
expected_visual_rect = FloatClipRect(expected_transformed_rect);
expected_visual_rect.ClearIsTight();
- CHECK_MAPPINGS();
+ CheckMappings();
}
TEST_P(GeometryMapperTest, RotationAndScaleTransformWithTransformOrigin) {
@@ -240,7 +249,7 @@ TEST_P(GeometryMapperTest, RotationAndScaleTransformWithTransformOrigin) {
expected_transformed_rect = expected_transform->MapRect(input_rect);
expected_visual_rect = FloatClipRect(expected_transformed_rect);
expected_visual_rect.ClearIsTight();
- CHECK_MAPPINGS();
+ CheckMappings();
}
TEST_P(GeometryMapperTest, NestedTransforms) {
@@ -256,7 +265,7 @@ TEST_P(GeometryMapperTest, NestedTransforms) {
expected_transformed_rect = expected_transform->MapRect(input_rect);
expected_visual_rect = FloatClipRect(expected_transformed_rect);
expected_visual_rect.ClearIsTight();
- CHECK_MAPPINGS();
+ CheckMappings();
}
TEST_P(GeometryMapperTest, NestedTransformsFlattening) {
@@ -277,7 +286,7 @@ TEST_P(GeometryMapperTest, NestedTransformsFlattening) {
expected_transformed_rect = expected_transform->MapRect(input_rect);
expected_visual_rect = FloatClipRect(expected_transformed_rect);
expected_visual_rect.ClearIsTight();
- CHECK_MAPPINGS();
+ CheckMappings();
}
TEST_P(GeometryMapperTest, NestedTransformsScaleAndTranslation) {
@@ -295,7 +304,7 @@ TEST_P(GeometryMapperTest, NestedTransformsScaleAndTranslation) {
expected_transformed_rect = expected_transform->MapRect(input_rect);
expected_visual_rect = FloatClipRect(expected_transformed_rect);
expected_visual_rect.ClearIsTight();
- CHECK_MAPPINGS();
+ CheckMappings();
}
TEST_P(GeometryMapperTest, NestedTransformsIntermediateDestination) {
@@ -313,7 +322,7 @@ TEST_P(GeometryMapperTest, NestedTransformsIntermediateDestination) {
expected_transformed_rect = expected_transform->MapRect(input_rect);
expected_visual_rect = FloatClipRect(expected_transformed_rect);
expected_visual_rect.ClearIsTight();
- CHECK_MAPPINGS();
+ CheckMappings();
}
TEST_P(GeometryMapperTest, SimpleClip) {
@@ -322,9 +331,23 @@ TEST_P(GeometryMapperTest, SimpleClip) {
input_rect = FloatRect(0, 0, 100, 100);
expected_transformed_rect = input_rect; // not clipped.
- expected_clip = FloatClipRect(clip->ClipRect());
+ expected_clip = FloatClipRect(clip->UnsnappedClipRect());
expected_visual_rect = expected_clip;
- CHECK_MAPPINGS();
+ CheckMappings();
+}
+
+TEST_P(GeometryMapperTest, SimpleClipPixelSnapped) {
+ auto clip = CreateClip(c0(), t0(), FloatRoundedRect(10, 10, 50.5, 50.5),
+ FloatRoundedRect(10, 10, 50, 51));
+ local_state.SetClip(*clip);
+
+ input_rect = FloatRect(0, 0, 100, 100);
+ expected_transformed_rect = input_rect; // not clipped.
+
+ // GeometryMapper does not use the PixelSnappedClipRect.
+ expected_clip = FloatClipRect(clip->UnsnappedClipRect());
+ expected_visual_rect = expected_clip;
+ CheckMappings();
}
TEST_P(GeometryMapperTest, SimpleClipWithAlias) {
@@ -334,15 +357,14 @@ TEST_P(GeometryMapperTest, SimpleClipWithAlias) {
input_rect = FloatRect(0, 0, 100, 100);
expected_transformed_rect = input_rect; // not clipped.
- expected_clip = FloatClipRect(clip->Unalias().ClipRect());
+ expected_clip = FloatClipRect(clip->Unalias().UnsnappedClipRect());
expected_visual_rect = expected_clip;
- CHECK_MAPPINGS();
+ CheckMappings();
}
TEST_P(GeometryMapperTest, SimpleClipOverlayScrollbars) {
- ClipPaintPropertyNode::State clip_state;
- clip_state.local_transform_space = &t0();
- clip_state.clip_rect = FloatRoundedRect(10, 10, 50, 50);
+ ClipPaintPropertyNode::State clip_state(&t0(),
+ FloatRoundedRect(10, 10, 50, 50));
clip_state.clip_rect_excluding_overlay_scrollbars =
FloatClipRect(FloatRect(10, 10, 45, 43));
auto clip = ClipPaintPropertyNode::Create(c0(), std::move(clip_state));
@@ -439,10 +461,10 @@ TEST_P(GeometryMapperTest, RoundedClip) {
input_rect = FloatRect(0, 0, 100, 100);
expected_transformed_rect = input_rect;
- expected_clip = FloatClipRect(clip->ClipRect());
+ expected_clip = FloatClipRect(clip->UnsnappedClipRect());
EXPECT_TRUE(expected_clip.HasRadius());
expected_visual_rect = expected_clip;
- CHECK_MAPPINGS();
+ CheckMappings();
}
TEST_P(GeometryMapperTest, ClipPath) {
@@ -457,7 +479,7 @@ TEST_P(GeometryMapperTest, ClipPath) {
expected_clip = FloatClipRect(FloatRect(10, 10, 50, 50));
expected_clip.ClearIsTight();
expected_visual_rect = expected_clip;
- CHECK_MAPPINGS();
+ CheckMappings();
}
TEST_P(GeometryMapperTest, TwoClips) {
@@ -472,19 +494,19 @@ TEST_P(GeometryMapperTest, TwoClips) {
input_rect = FloatRect(0, 0, 100, 100);
expected_transformed_rect = input_rect;
- expected_clip = FloatClipRect(clip1->ClipRect());
+ expected_clip = FloatClipRect(clip1->UnsnappedClipRect());
EXPECT_TRUE(expected_clip.HasRadius());
expected_visual_rect = expected_clip;
- CHECK_MAPPINGS();
+ CheckMappings();
ancestor_state.SetClip(*clip1);
- expected_clip = FloatClipRect(clip2->ClipRect());
+ expected_clip = FloatClipRect(clip2->UnsnappedClipRect());
expected_visual_rect = expected_clip;
- CHECK_MAPPINGS();
+ CheckMappings();
}
TEST_P(GeometryMapperTest, TwoClipsTransformAbove) {
- auto transform = CreateTransform(t0(), TransformationMatrix());
+ auto transform = Create2DTranslation(t0(), 0, 0);
FloatRoundedRect clip_rect1(
FloatRect(10, 10, 50, 50),
@@ -497,16 +519,16 @@ TEST_P(GeometryMapperTest, TwoClipsTransformAbove) {
input_rect = FloatRect(0, 0, 100, 100);
expected_transformed_rect = input_rect;
- expected_clip = FloatClipRect(clip2->ClipRect());
+ expected_clip = FloatClipRect(clip2->UnsnappedClipRect());
expected_clip.SetHasRadius();
expected_visual_rect = expected_clip;
- CHECK_MAPPINGS();
+ CheckMappings();
- expected_clip = FloatClipRect(clip1->ClipRect());
+ expected_clip = FloatClipRect(clip1->UnsnappedClipRect());
EXPECT_TRUE(expected_clip.HasRadius());
local_state.SetClip(*clip1);
expected_visual_rect = expected_clip;
- CHECK_MAPPINGS();
+ CheckMappings();
}
TEST_P(GeometryMapperTest, ClipBeforeTransform) {
@@ -518,14 +540,36 @@ TEST_P(GeometryMapperTest, ClipBeforeTransform) {
input_rect = FloatRect(0, 0, 100, 100);
expected_visual_rect = FloatClipRect(input_rect);
- expected_visual_rect.Intersect(FloatClipRect(clip->ClipRect()));
+ expected_visual_rect.Intersect(FloatClipRect(clip->UnsnappedClipRect()));
+ expected_visual_rect.Map(*expected_transform);
+ EXPECT_FALSE(expected_visual_rect.IsTight());
+ expected_clip = FloatClipRect(clip->UnsnappedClipRect());
+ expected_clip.Map(*expected_transform);
+ EXPECT_FALSE(expected_clip.IsTight());
+ expected_transformed_rect = expected_transform->MapRect(input_rect);
+ CheckMappings();
+}
+
+TEST_P(GeometryMapperTest, ExpandVisualRectWithClipBeforeAnimatingTransform) {
+ expected_transform = TransformationMatrix().Rotate(45);
+ auto transform = CreateAnimatingTransform(t0(), *expected_transform);
+ auto clip = CreateClip(c0(), *transform, FloatRoundedRect(10, 10, 50, 50));
+ local_state.SetClip(*clip);
+ local_state.SetTransform(*transform);
+
+ input_rect = FloatRect(0, 0, 100, 100);
+ expected_visual_rect = FloatClipRect(input_rect);
+ expected_visual_rect.Intersect(FloatClipRect(clip->UnsnappedClipRect()));
expected_visual_rect.Map(*expected_transform);
+ // The clip has animating transform, so it doesn't apply to the visual rect.
+ expected_visual_rect_expanded_for_animation = InfiniteLooseFloatClipRect();
EXPECT_FALSE(expected_visual_rect.IsTight());
- expected_clip = FloatClipRect(clip->ClipRect());
+ expected_clip = FloatClipRect(clip->UnsnappedClipRect());
expected_clip.Map(*expected_transform);
EXPECT_FALSE(expected_clip.IsTight());
+ expected_clip_has_transform_animation = true;
expected_transformed_rect = expected_transform->MapRect(input_rect);
- CHECK_MAPPINGS();
+ CheckMappings();
}
TEST_P(GeometryMapperTest, ClipAfterTransform) {
@@ -539,11 +583,33 @@ TEST_P(GeometryMapperTest, ClipAfterTransform) {
expected_transformed_rect = expected_transform->MapRect(input_rect);
expected_visual_rect = FloatClipRect(input_rect);
expected_visual_rect.Map(*expected_transform);
- expected_visual_rect.Intersect(FloatClipRect(clip->ClipRect()));
+ expected_visual_rect.Intersect(FloatClipRect(clip->UnsnappedClipRect()));
EXPECT_FALSE(expected_visual_rect.IsTight());
- expected_clip = FloatClipRect(clip->ClipRect());
+ expected_clip = FloatClipRect(clip->UnsnappedClipRect());
EXPECT_TRUE(expected_clip.IsTight());
- CHECK_MAPPINGS();
+ CheckMappings();
+}
+
+TEST_P(GeometryMapperTest, ExpandVisualRectWithClipAfterAnimatingTransform) {
+ expected_transform = TransformationMatrix().Rotate(45);
+ auto transform = CreateAnimatingTransform(t0(), *expected_transform);
+ auto clip = CreateClip(c0(), t0(), FloatRoundedRect(10, 10, 200, 200));
+ local_state.SetClip(*clip);
+ local_state.SetTransform(*transform);
+
+ input_rect = FloatRect(0, 0, 100, 100);
+ expected_transformed_rect = expected_transform->MapRect(input_rect);
+ expected_visual_rect = FloatClipRect(input_rect);
+ expected_visual_rect.Map(*expected_transform);
+ expected_visual_rect.Intersect(FloatClipRect(clip->UnsnappedClipRect()));
+ EXPECT_FALSE(expected_visual_rect.IsTight());
+ expected_clip = FloatClipRect(clip->UnsnappedClipRect());
+ EXPECT_TRUE(expected_clip.IsTight());
+ // The visual rect is expanded first to infinity because of the transform
+ // animation, then clipped by the clip.
+ expected_visual_rect_expanded_for_animation = expected_clip;
+ expected_visual_rect_expanded_for_animation->ClearIsTight();
+ CheckMappings();
}
TEST_P(GeometryMapperTest, TwoClipsWithTransformBetween) {
@@ -552,43 +618,58 @@ TEST_P(GeometryMapperTest, TwoClipsWithTransformBetween) {
auto transform = CreateTransform(t0(), *expected_transform);
auto clip2 =
CreateClip(*clip1, *transform, FloatRoundedRect(10, 10, 200, 200));
+ local_state.SetClip(*clip2);
+ local_state.SetTransform(*transform);
input_rect = FloatRect(0, 0, 100, 100);
expected_transformed_rect = expected_transform->MapRect(input_rect);
- {
- local_state.SetClip(*clip1);
- local_state.SetTransform(*transform);
-
- expected_visual_rect = FloatClipRect(input_rect);
- expected_visual_rect.Map(*expected_transform);
- expected_visual_rect.Intersect(FloatClipRect(clip1->ClipRect()));
- EXPECT_FALSE(expected_visual_rect.IsTight());
- expected_clip = FloatClipRect(clip1->ClipRect());
- EXPECT_TRUE(expected_clip.IsTight());
- CHECK_MAPPINGS();
- }
+ expected_clip = FloatClipRect(clip2->UnsnappedClipRect());
+ expected_clip.Map(*expected_transform);
+ expected_clip.Intersect(FloatClipRect(clip1->UnsnappedClipRect()));
+ EXPECT_FALSE(expected_clip.IsTight());
- {
- local_state.SetClip(*clip2);
- local_state.SetTransform(*transform);
-
- expected_clip = FloatClipRect(clip2->ClipRect());
- expected_clip.Map(*expected_transform);
- expected_clip.Intersect(FloatClipRect(clip1->ClipRect()));
- EXPECT_FALSE(expected_clip.IsTight());
-
- // All clips are performed in the space of the ancestor. In cases such as
- // this, this means the clip is not tight.
- expected_visual_rect = FloatClipRect(input_rect);
- expected_visual_rect.Map(*expected_transform);
- // Intersect with all clips between local and ancestor, independently mapped
- // to ancestor space.
- expected_visual_rect.Intersect(expected_clip);
- EXPECT_FALSE(expected_visual_rect.IsTight());
-
- CHECK_MAPPINGS();
- }
+ // All clips are performed in the space of the ancestor. In cases such as
+ // this, this means the clip is not tight.
+ expected_visual_rect = FloatClipRect(input_rect);
+ expected_visual_rect.Map(*expected_transform);
+ // Intersect with all clips between local and ancestor, independently mapped
+ // to ancestor space.
+ expected_visual_rect.Intersect(expected_clip);
+ EXPECT_FALSE(expected_visual_rect.IsTight());
+
+ CheckMappings();
+}
+
+TEST_P(GeometryMapperTest,
+ ExpandVisualRectWithTwoClipsWithAnimatingTransformBetween) {
+ auto clip1 = CreateClip(c0(), t0(), FloatRoundedRect(10, 10, 200, 200));
+ expected_transform = TransformationMatrix().Rotate(45);
+ auto transform = CreateAnimatingTransform(t0(), *expected_transform);
+ auto clip2 =
+ CreateClip(*clip1, *transform, FloatRoundedRect(10, 10, 200, 200));
+ local_state.SetClip(*clip2);
+ local_state.SetTransform(*transform);
+
+ input_rect = FloatRect(0, 0, 100, 100);
+ expected_transformed_rect = expected_transform->MapRect(input_rect);
+
+ expected_clip = FloatClipRect(clip2->UnsnappedClipRect());
+ expected_clip.Map(*expected_transform);
+ expected_clip.Intersect(FloatClipRect(clip1->UnsnappedClipRect()));
+ EXPECT_FALSE(expected_clip.IsTight());
+ expected_clip_has_transform_animation = true;
+ expected_visual_rect = FloatClipRect(input_rect);
+ expected_visual_rect.Map(*expected_transform);
+ expected_visual_rect.Intersect(expected_clip);
+ EXPECT_FALSE(expected_visual_rect.IsTight());
+ // The visual rect is expanded to infinity because of the transform animation,
+ // then clipped by clip1. clip2 doesn't apply because it's below the animating
+ // transform.
+ expected_visual_rect_expanded_for_animation =
+ FloatClipRect(clip1->UnsnappedClipRect());
+ expected_visual_rect_expanded_for_animation->ClearIsTight();
+ CheckMappings();
}
TEST_P(GeometryMapperTest, SiblingTransforms) {
@@ -701,13 +782,13 @@ TEST_P(GeometryMapperTest, FilterWithClipsAndTransforms) {
auto output = input_rect;
output.Move(transform_below_effect->Translation2D());
// 2. clipBelowEffect
- output.Intersect(clip_below_effect->ClipRect().Rect());
+ output.Intersect(clip_below_effect->UnsnappedClipRect().Rect());
EXPECT_EQ(FloatRect(20, 30, 90, 80), output);
// 3. effect (the outset is 3 times of blur amount).
output = filters.MapRect(output);
EXPECT_EQ(FloatRect(-40, -30, 210, 200), output);
// 4. clipAboveEffect
- output.Intersect(clip_above_effect->ClipRect().Rect());
+ output.Intersect(clip_above_effect->UnsnappedClipRect().Rect());
EXPECT_EQ(FloatRect(-40, -30, 140, 130), output);
// 5. transformAboveEffect
output.Move(transform_above_effect->Translation2D());
@@ -721,7 +802,7 @@ TEST_P(GeometryMapperTest, FilterWithClipsAndTransforms) {
expected_visual_rect.ClearIsTight();
expected_clip = FloatClipRect(FloatRect(50, 60, 90, 90));
expected_clip.ClearIsTight();
- CHECK_MAPPINGS();
+ CheckMappings();
}
TEST_P(GeometryMapperTest, FilterWithClipsAndTransformsWithAlias) {
@@ -751,13 +832,13 @@ TEST_P(GeometryMapperTest, FilterWithClipsAndTransformsWithAlias) {
auto output = input_rect;
output.Move(transform_below_effect->Translation2D());
// 2. clipBelowEffect
- output.Intersect(clip_below_effect->ClipRect().Rect());
+ output.Intersect(clip_below_effect->UnsnappedClipRect().Rect());
EXPECT_EQ(FloatRect(20, 30, 90, 80), output);
// 3. effect (the outset is 3 times of blur amount).
output = filters.MapRect(output);
EXPECT_EQ(FloatRect(-40, -30, 210, 200), output);
// 4. clipAboveEffect
- output.Intersect(clip_above_effect->ClipRect().Rect());
+ output.Intersect(clip_above_effect->UnsnappedClipRect().Rect());
EXPECT_EQ(FloatRect(-40, -30, 140, 130), output);
// 5. transformAboveEffect
output.Move(transform_above_effect->Translation2D());
@@ -771,7 +852,36 @@ TEST_P(GeometryMapperTest, FilterWithClipsAndTransformsWithAlias) {
expected_visual_rect.ClearIsTight();
expected_clip = FloatClipRect(FloatRect(50, 60, 90, 90));
expected_clip.ClearIsTight();
- CHECK_MAPPINGS();
+ CheckMappings();
+}
+
+TEST_P(GeometryMapperTest,
+ ExpandVisualRectWithTwoClipsWithAnimatingFilterBetween) {
+ auto clip1 = CreateClip(c0(), t0(), FloatRoundedRect(10, 10, 200, 200));
+ auto effect = CreateAnimatingFilterEffect(e0(), CompositorFilterOperations(),
+ clip1.get());
+ auto clip2 = CreateClip(*clip1, t0(), FloatRoundedRect(50, 0, 200, 50));
+ local_state.SetClip(*clip2);
+ local_state.SetEffect(*effect);
+
+ input_rect = FloatRect(0, 0, 100, 100);
+ expected_transformed_rect = input_rect;
+ auto output = input_rect;
+ output.Intersect(clip2->UnsnappedClipRect().Rect());
+ output.Intersect(clip1->UnsnappedClipRect().Rect());
+ EXPECT_EQ(FloatRect(50, 10, 50, 40), output);
+ expected_visual_rect = FloatClipRect(output);
+ expected_visual_rect.ClearIsTight();
+ expected_clip = FloatClipRect(clip2->UnsnappedClipRect());
+ expected_clip.Intersect(FloatClipRect(clip1->UnsnappedClipRect()));
+ expected_clip.ClearIsTight();
+ // The visual rect is expanded to infinity because of the filter animation,
+ // the clipped by clip1. clip2 doesn't apply because it's below the animating
+ // filter.
+ expected_visual_rect_expanded_for_animation =
+ FloatClipRect(clip1->UnsnappedClipRect());
+ expected_visual_rect_expanded_for_animation->ClearIsTight();
+ CheckMappings();
}
TEST_P(GeometryMapperTest, ReflectionWithPaintOffset) {
@@ -787,7 +897,7 @@ TEST_P(GeometryMapperTest, ReflectionWithPaintOffset) {
expected_visual_rect = FloatClipRect(FloatRect(50, 100, 100, 50));
expected_visual_rect.ClearIsTight();
- CHECK_MAPPINGS();
+ CheckMappings();
}
TEST_P(GeometryMapperTest, InvertedClip) {
@@ -814,8 +924,8 @@ TEST_P(GeometryMapperTest, InvertedClip) {
TEST_P(GeometryMapperTest, Precision) {
auto t1 = CreateTransform(t0(), TransformationMatrix().Scale(32767));
auto t2 = CreateTransform(*t1, TransformationMatrix().Rotate(1));
- auto t3 = CreateTransform(*t2, TransformationMatrix());
- auto t4 = CreateTransform(*t3, TransformationMatrix());
+ auto t3 = Create2DTranslation(*t2, 0, 0);
+ auto t4 = Create2DTranslation(*t3, 0, 0);
EXPECT_TRUE(
GeometryMapper::SourceToDestinationProjection(*t4, *t4).IsIdentity());
EXPECT_TRUE(
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache.cc
index e6bb3172f6f..1a8bdc3cb94 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache.cc
@@ -42,6 +42,8 @@ void GeometryMapperTransformCache::Update(
screen_transform_ = nullptr;
if (node.IsIdentityOr2DTranslation()) {
+ // We always use full matrix for animating transforms.
+ DCHECK(!node.HasActiveTransformAnimation());
root_of_2d_translation_ = parent.root_of_2d_translation_;
to_2d_translation_root_ = parent.to_2d_translation_root_;
const auto& translation = node.Translation2D();
@@ -57,6 +59,9 @@ void GeometryMapperTransformCache::Update(
plane_root_transform_->from_plane_root = parent.from_plane_root();
plane_root_transform_->from_plane_root.PostTranslate(
-translation.Width(), -translation.Height());
+ plane_root_transform_->has_animation =
+ parent.plane_root_transform_->has_animation ||
+ node.HasActiveTransformAnimation();
} else {
// The parent doesn't have plane_root_transform_ means that the parent's
// plane root is the same as the 2d translation root, so this node
@@ -86,6 +91,7 @@ void GeometryMapperTransformCache::Update(
plane_root_transform_->plane_root = &node;
plane_root_transform_->to_plane_root.MakeIdentity();
plane_root_transform_->from_plane_root.MakeIdentity();
+ plane_root_transform_->has_animation = false;
} else {
plane_root_transform_->plane_root = parent.plane_root();
plane_root_transform_->to_plane_root.MakeIdentity();
@@ -93,6 +99,9 @@ void GeometryMapperTransformCache::Update(
plane_root_transform_->to_plane_root.Multiply(local);
plane_root_transform_->from_plane_root = local.Inverse();
parent.ApplyFromPlaneRoot(plane_root_transform_->from_plane_root);
+ plane_root_transform_->has_animation =
+ parent.has_animation_to_plane_root() ||
+ node.HasActiveTransformAnimation();
}
}
@@ -130,6 +139,8 @@ void GeometryMapperTransformCache::UpdateScreenTransform(
to_screen_flattened.IsInvertible();
if (screen_transform_->projection_from_screen_is_valid)
screen_transform_->projection_from_screen = to_screen_flattened.Inverse();
+
+ screen_transform_->has_animation |= node.HasActiveTransformAnimation();
}
#if DCHECK_IS_ON()
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache.h b/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache.h
index ec25d6d76cf..b722bbf64ab 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache.h
@@ -71,6 +71,13 @@ class PLATFORM_EXPORT GeometryMapperTransformCache {
else
ApplyFromPlaneRoot(m);
}
+ bool has_animation_to_screen() const {
+#if DCHECK_IS_ON()
+ CheckScreenTransformUpdated();
+#endif
+ return UNLIKELY(screen_transform_) ? screen_transform_->has_animation
+ : has_animation_to_plane_root();
+ }
const TransformationMatrix& to_plane_root() const {
DCHECK(plane_root_transform_);
@@ -100,6 +107,10 @@ class PLATFORM_EXPORT GeometryMapperTransformCache {
return UNLIKELY(plane_root_transform_) ? plane_root_transform_->plane_root
: root_of_2d_translation();
}
+ bool has_animation_to_plane_root() const {
+ return UNLIKELY(plane_root_transform_) &&
+ plane_root_transform_->has_animation;
+ }
private:
friend class GeometryMapperTransformCacheTest;
@@ -180,6 +191,7 @@ class PLATFORM_EXPORT GeometryMapperTransformCache {
TransformationMatrix to_plane_root;
TransformationMatrix from_plane_root;
const TransformPaintPropertyNode* plane_root;
+ bool has_animation;
};
std::unique_ptr<PlaneRootTransform> plane_root_transform_;
@@ -187,6 +199,7 @@ class PLATFORM_EXPORT GeometryMapperTransformCache {
TransformationMatrix to_screen;
TransformationMatrix projection_from_screen;
bool projection_from_screen_is_valid;
+ bool has_animation;
};
std::unique_ptr<ScreenTransform> screen_transform_;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache_test.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache_test.cc
index f04c76e4759..90511afcc61 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_transform_cache_test.cc
@@ -137,9 +137,9 @@ class GeometryMapperTransformCacheTest : public testing::Test {
};
TEST_F(GeometryMapperTransformCacheTest, All2dTranslations) {
- auto t1 = CreateTransform(t0(), TransformationMatrix().Translate(1, 2));
- auto t2 = CreateTransform(*t1, TransformationMatrix());
- auto t3 = CreateTransform(*t2, TransformationMatrix().Translate(7, 8));
+ auto t1 = Create2DTranslation(t0(), 1, 2);
+ auto t2 = Create2DTranslation(*t1, 0, 0);
+ auto t3 = Create2DTranslation(*t2, 7, 8);
Check2dTranslationToRoot(t0(), 0, 0);
Check2dTranslationToRoot(*t1, 1, 2);
@@ -148,9 +148,9 @@ TEST_F(GeometryMapperTransformCacheTest, All2dTranslations) {
}
TEST_F(GeometryMapperTransformCacheTest, RootAsPlaneRootWithIntermediateScale) {
- auto t1 = CreateTransform(t0(), TransformationMatrix().Translate(1, 2));
+ auto t1 = Create2DTranslation(t0(), 1, 2);
auto t2 = CreateTransform(*t1, TransformationMatrix().Scale(3));
- auto t3 = CreateTransform(*t2, TransformationMatrix().Translate(7, 8));
+ auto t3 = Create2DTranslation(*t2, 7, 8);
Check2dTranslationToRoot(t0(), 0, 0);
Check2dTranslationToRoot(*t1, 1, 2);
@@ -162,9 +162,9 @@ TEST_F(GeometryMapperTransformCacheTest, RootAsPlaneRootWithIntermediateScale) {
TEST_F(GeometryMapperTransformCacheTest,
IntermediatePlaneRootSameAs2dTranslationRoot) {
- auto t1 = CreateTransform(t0(), TransformationMatrix().Translate(1, 2));
+ auto t1 = Create2DTranslation(t0(), 1, 2);
auto t2 = CreateTransform(*t1, TransformationMatrix().Rotate3d(0, 45, 0));
- auto t3 = CreateTransform(*t2, TransformationMatrix().Translate(7, 8));
+ auto t3 = Create2DTranslation(*t2, 7, 8);
Check2dTranslationToRoot(t0(), 0, 0);
Check2dTranslationToRoot(*t1, 1, 2);
@@ -176,10 +176,10 @@ TEST_F(GeometryMapperTransformCacheTest,
TEST_F(GeometryMapperTransformCacheTest,
IntermediatePlaneRootDifferent2dTranslationRoot) {
- auto t1 = CreateTransform(t0(), TransformationMatrix().Translate(1, 2));
+ auto t1 = Create2DTranslation(t0(), 1, 2);
auto t2 = CreateTransform(*t1, TransformationMatrix().Rotate3d(0, 45, 0));
auto t3 = CreateTransform(*t2, TransformationMatrix().Scale(3));
- auto t4 = CreateTransform(*t3, TransformationMatrix().Translate(7, 8));
+ auto t4 = Create2DTranslation(*t3, 7, 8);
Check2dTranslationToRoot(t0(), 0, 0);
Check2dTranslationToRoot(*t1, 1, 2);
@@ -199,9 +199,9 @@ TEST_F(GeometryMapperTransformCacheTest,
}
TEST_F(GeometryMapperTransformCacheTest, TransformUpdate) {
- auto t1 = CreateTransform(t0(), TransformationMatrix().Translate(1, 2));
- auto t2 = CreateTransform(*t1, TransformationMatrix());
- auto t3 = CreateTransform(*t2, TransformationMatrix().Translate(7, 8));
+ auto t1 = Create2DTranslation(t0(), 1, 2);
+ auto t2 = Create2DTranslation(*t1, 0, 0);
+ auto t3 = Create2DTranslation(*t2, 7, 8);
Check2dTranslationToRoot(t0(), 0, 0);
Check2dTranslationToRoot(*t1, 1, 2);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/graphics_layer_display_item.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/graphics_layer_display_item.cc
new file mode 100644
index 00000000000..5550c716901
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/graphics_layer_display_item.cc
@@ -0,0 +1,63 @@
+// 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/paint/graphics_layer_display_item.h"
+
+#include <utility>
+
+#include "cc/layers/layer.h"
+#include "cc/layers/picture_layer.h"
+#include "third_party/blink/renderer/platform/graphics/compositing/layers_as_json.h"
+#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
+#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
+#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
+#include "third_party/blink/renderer/platform/wtf/assertions.h"
+
+namespace blink {
+
+GraphicsLayerDisplayItem::GraphicsLayerDisplayItem(
+ const GraphicsLayer& graphics_layer)
+ : DisplayItem(graphics_layer, kGraphicsLayerWrapper, sizeof(*this)),
+ graphics_layer_(graphics_layer) {}
+
+bool GraphicsLayerDisplayItem::Equals(const DisplayItem& other) const {
+ return GetType() == other.GetType() &&
+ GetGraphicsLayer() ==
+ static_cast<const GraphicsLayerDisplayItem&>(other)
+ .GetGraphicsLayer();
+}
+
+#if DCHECK_IS_ON()
+void GraphicsLayerDisplayItem::PropertiesAsJSON(JSONObject& json) const {
+ DisplayItem::PropertiesAsJSON(json);
+ json.SetInteger("layer", graphics_layer_.CcLayer()->id());
+ FloatPoint offset(graphics_layer_.GetOffsetFromTransformNode());
+ json.SetDouble("offset_x", offset.X());
+ json.SetDouble("offset_y", offset.Y());
+}
+#endif
+
+void RecordGraphicsLayer(GraphicsContext& context,
+ const GraphicsLayer& graphics_layer) {
+ // In pre-CompositeAfterPaint, the GraphicsLayer hierarchy is still built
+ // during CompositingUpdate, and we have to clear them here to ensure no
+ // extraneous layers are still attached. In future we will disable all
+ // those layer hierarchy code so we won't need this line.
+ DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
+ graphics_layer.CcLayer()->RemoveAllChildren();
+
+ PaintController& paint_controller = context.GetPaintController();
+
+ // This is like ScopedPaintChunkProperties but uses null id because graphics
+ // layer chunk doesn't need an id nor a client.
+ const PropertyTreeState& properties = graphics_layer.GetPropertyTreeState();
+ PropertyTreeState previous_properties(
+ paint_controller.CurrentPaintChunkProperties());
+ paint_controller.UpdateCurrentPaintChunkProperties(nullptr, properties);
+ paint_controller.CreateAndAppend<GraphicsLayerDisplayItem>(graphics_layer);
+ paint_controller.UpdateCurrentPaintChunkProperties(nullptr,
+ previous_properties);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/graphics_layer_display_item.h b/chromium/third_party/blink/renderer/platform/graphics/paint/graphics_layer_display_item.h
new file mode 100644
index 00000000000..2e468dd629c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/graphics_layer_display_item.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_PLATFORM_GRAPHICS_PAINT_GRAPHICS_LAYER_DISPLAY_ITEM_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_GRAPHICS_LAYER_DISPLAY_ITEM_H_
+
+#include "cc/layers/layer.h"
+#include "third_party/blink/renderer/platform/graphics/paint/display_item.h"
+#include "third_party/blink/renderer/platform/graphics/paint/property_tree_state.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+
+namespace blink {
+
+class GraphicsContext;
+class GraphicsLayer;
+
+// Before CompositeAfterPaint, this is a placeholder for a GraphicsLayer
+// allocated before paint. With CompositeAfterPaint, this class will be
+// obsolete and should be removed.
+//
+// Before SquashAfterPaint, a cc::Layer will always be allocated to draw the
+// GraphicsLayer's contents. With SquashAfter Paint, that may not be true; the
+// GraphicsLayer may end up getting squashed by PaintArtifactCompositor.
+class PLATFORM_EXPORT GraphicsLayerDisplayItem final : public DisplayItem {
+ public:
+ GraphicsLayerDisplayItem(const GraphicsLayer&);
+
+ const GraphicsLayer& GetGraphicsLayer() const { return graphics_layer_; }
+
+ // DisplayItem
+ bool Equals(const DisplayItem&) const override;
+#if DCHECK_IS_ON()
+ void PropertiesAsJSON(JSONObject&) const override;
+#endif
+
+ private:
+ const GraphicsLayer& graphics_layer_;
+};
+
+// Records a graphics layer into a GraphicsContext.
+PLATFORM_EXPORT void RecordGraphicsLayer(GraphicsContext& context,
+ const GraphicsLayer& graphics_layer);
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_GRAPHICS_LAYER_DISPLAY_ITEM_H_
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/hit_test_data.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/hit_test_data.cc
index 6e5c25573ad..b5aee1a0c7c 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/hit_test_data.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/hit_test_data.cc
@@ -9,7 +9,7 @@
namespace blink {
-static String HitTestRectsAsString(const Vector<HitTestRect>& rects) {
+static String TouchActionRectsAsString(const Vector<TouchActionRect>& rects) {
StringBuilder sb;
sb.Append("[");
bool first = true;
@@ -32,22 +32,25 @@ String HitTestData::ToString() const {
bool printed_top_level_field = false;
if (!touch_action_rects.IsEmpty()) {
sb.Append("touch_action_rects: ");
- sb.Append(HitTestRectsAsString(touch_action_rects));
+ sb.Append(TouchActionRectsAsString(touch_action_rects));
printed_top_level_field = true;
}
- if (scroll_hit_test) {
+ if (!scroll_hit_test_rect.IsEmpty()) {
if (printed_top_level_field)
sb.Append(", ");
- sb.AppendFormat(
- "scroll_hit_test: \"%s\" with offset %p",
- scroll_hit_test->scroll_container_bounds.ToString().Utf8().data(),
- scroll_hit_test->scroll_offset);
+ sb.Append("scroll_hit_test_rect: ");
+ sb.Append(scroll_hit_test_rect.ToString());
printed_top_level_field = true;
}
- sb.Append("}");
+ if (scroll_translation) {
+ if (printed_top_level_field)
+ sb.Append(", ");
+ sb.AppendFormat("scroll_translation: %p", scroll_translation);
+ }
+ sb.Append("}");
return sb.ToString();
}
@@ -55,4 +58,8 @@ std::ostream& operator<<(std::ostream& os, const HitTestData& data) {
return os << data.ToString().Utf8();
}
+std::ostream& operator<<(std::ostream& os, const HitTestData* data) {
+ return os << (data ? data->ToString().Utf8() : "null");
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/hit_test_data.h b/chromium/third_party/blink/renderer/platform/graphics/paint/hit_test_data.h
index 824d9397133..cc785893ca5 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/hit_test_data.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/hit_test_data.h
@@ -5,51 +5,35 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_HIT_TEST_DATA_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_HIT_TEST_DATA_H_
-#include "third_party/blink/renderer/platform/graphics/hit_test_rect.h"
#include "third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h"
+#include "third_party/blink/renderer/platform/graphics/touch_action_rect.h"
#include "third_party/blink/renderer/platform/platform_export.h"
namespace blink {
struct PLATFORM_EXPORT HitTestData {
- Vector<HitTestRect> touch_action_rects;
- struct ScrollHitTest {
- const TransformPaintPropertyNode* scroll_offset;
- IntRect scroll_container_bounds;
- bool operator==(const ScrollHitTest& rhs) const {
- return scroll_offset == rhs.scroll_offset &&
- scroll_container_bounds == rhs.scroll_container_bounds;
- }
- };
- base::Optional<ScrollHitTest> scroll_hit_test;
-
- HitTestData() = default;
- HitTestData(const HitTestData& other)
- : touch_action_rects(other.touch_action_rects),
- scroll_hit_test(other.scroll_hit_test) {}
+ Vector<TouchActionRect> touch_action_rects;
+
+ // If scroll_translation is nullptr or in pre-CompositeAfterPaint, this marks
+ // a region in which composited scroll is not allowed. In CompositeAfterPaint
+ // when scroll_translation is not nullptr, this is the bounds of the scroll
+ // container, and whether the region allows composited scrolling depends
+ // whether the scroll_translation is composited.
+ IntRect scroll_hit_test_rect;
+ const TransformPaintPropertyNode* scroll_translation = nullptr;
bool operator==(const HitTestData& rhs) const {
return touch_action_rects == rhs.touch_action_rects &&
- scroll_hit_test == rhs.scroll_hit_test;
- }
-
- void AppendTouchActionRect(const HitTestRect& rect) {
- touch_action_rects.push_back(rect);
+ scroll_hit_test_rect == rhs.scroll_hit_test_rect &&
+ scroll_translation == rhs.scroll_translation;
}
-
- void SetScrollHitTest(const TransformPaintPropertyNode* scroll_offset,
- const IntRect& scroll_container_bounds) {
- DCHECK(!scroll_offset || scroll_offset->ScrollNode());
- scroll_hit_test = base::make_optional(
- ScrollHitTest{scroll_offset, scroll_container_bounds});
- }
-
bool operator!=(const HitTestData& rhs) const { return !(*this == rhs); }
String ToString() const;
};
PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, const HitTestData&);
+PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, const HitTestData*);
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/hit_test_display_item.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/hit_test_display_item.cc
deleted file mode 100644
index 679754ff661..00000000000
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/hit_test_display_item.cc
+++ /dev/null
@@ -1,38 +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/graphics/paint/hit_test_display_item.h"
-
-#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
-#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
-
-namespace blink {
-
-void HitTestDisplayItem::Record(GraphicsContext& context,
- const DisplayItemClient& client,
- const HitTestRect& hit_test_rect) {
- auto& paint_controller = context.GetPaintController();
- if (paint_controller.DisplayItemConstructionIsDisabled())
- return;
-
- if (paint_controller.UseCachedItemIfPossible(client, DisplayItem::kHitTest))
- return;
-
- paint_controller.CreateAndAppend<HitTestDisplayItem>(client, hit_test_rect);
-}
-
-#if DCHECK_IS_ON()
-void HitTestDisplayItem::PropertiesAsJSON(JSONObject& json) const {
- DisplayItem::PropertiesAsJSON(json);
- json.SetString("hitTestRect", hit_test_rect_.ToString());
-}
-#endif
-
-bool HitTestDisplayItem::Equals(const DisplayItem& other) const {
- return DisplayItem::Equals(other) &&
- hit_test_rect_ ==
- static_cast<const HitTestDisplayItem&>(other).hit_test_rect_;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/hit_test_display_item.h b/chromium/third_party/blink/renderer/platform/graphics/paint/hit_test_display_item.h
deleted file mode 100644
index cd9a9676def..00000000000
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/hit_test_display_item.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_PLATFORM_GRAPHICS_PAINT_HIT_TEST_DISPLAY_ITEM_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_HIT_TEST_DISPLAY_ITEM_H_
-
-#include "third_party/blink/renderer/platform/graphics/paint/display_item.h"
-
-#include "third_party/blink/renderer/platform/graphics/hit_test_rect.h"
-
-namespace blink {
-
-class GraphicsContext;
-
-// A special DisplayItem containing hit test data.
-class PLATFORM_EXPORT HitTestDisplayItem final : public DisplayItem {
- public:
- HitTestDisplayItem(const DisplayItemClient& client,
- const HitTestRect& hit_test_rect)
- : DisplayItem(client, kHitTest, sizeof(*this)),
- hit_test_rect_(hit_test_rect) {
- }
-
- const HitTestRect& GetHitTestRect() const { return hit_test_rect_; }
-
- static void Record(GraphicsContext&,
- const DisplayItemClient&,
- const HitTestRect&);
-
- bool Equals(const DisplayItem& other) const final;
-
- private:
-#if DCHECK_IS_ON()
- void PropertiesAsJSON(JSONObject&) const override;
-#endif
-
- HitTestRect hit_test_rect_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_HIT_TEST_DISPLAY_ITEM_H_
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 58a1eaa2b76..648cba4ab0b 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
@@ -7,98 +7,14 @@
#include "cc/paint/display_item_list.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
#include "third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.h"
-#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
+#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h"
-#include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h"
-#include "third_party/blink/renderer/platform/graphics/paint/hit_test_display_item.h"
-#include "third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
-#include "third_party/skia/include/core/SkRegion.h"
namespace blink {
namespace {
-static SkColor DisplayItemBackgroundColor(const DisplayItem& item) {
- if (item.GetType() != DisplayItem::kBoxDecorationBackground &&
- item.GetType() != DisplayItem::kDocumentBackground)
- return SK_ColorTRANSPARENT;
-
- const auto& drawing_item = static_cast<const DrawingDisplayItem&>(item);
- const auto record = drawing_item.GetPaintRecord();
- if (!record)
- return SK_ColorTRANSPARENT;
-
- for (cc::PaintOpBuffer::Iterator it(record.get()); it; ++it) {
- const auto* op = *it;
- if (op->GetType() == cc::PaintOpType::DrawRect ||
- op->GetType() == cc::PaintOpType::DrawRRect) {
- const auto& flags = static_cast<const cc::PaintOpWithFlags*>(op)->flags;
- // Skip op with looper which may modify the color.
- if (!flags.getLooper() && flags.getStyle() == cc::PaintFlags::kFill_Style)
- return flags.getColor();
- }
- }
- return SK_ColorTRANSPARENT;
-}
-
-void ComputeChunkDerivedData(const DisplayItemList& display_items,
- PaintChunk& chunk) {
- // This happens in tests testing paint chunks without display items.
- if (!chunk.size())
- return;
-
- SkRegion known_to_be_opaque_region;
- auto items = display_items.ItemsInPaintChunk(chunk);
- for (const DisplayItem& item : items) {
- chunk.bounds.Unite(item.VisualRect());
- chunk.outset_for_raster_effects = std::max(chunk.outset_for_raster_effects,
- item.OutsetForRasterEffects());
-
- if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
- item.IsDrawing()) {
- const auto& drawing = static_cast<const DrawingDisplayItem&>(item);
- if (drawing.GetPaintRecord() && drawing.KnownToBeOpaque()) {
- known_to_be_opaque_region.op(SkIRect(drawing.VisualRect()),
- SkRegion::kUnion_Op);
- }
- }
-
- if (item.IsHitTest()) {
- const auto& hit_test = static_cast<const HitTestDisplayItem&>(item);
- if (!chunk.hit_test_data)
- chunk.hit_test_data = std::make_unique<HitTestData>();
- chunk.hit_test_data->AppendTouchActionRect(hit_test.GetHitTestRect());
- }
-
- // Because ScrollHitTestDisplayItems force new paint chunks (see:
- // PaintChunker::IncrementDisplayItemIndex), they should only be the first
- // item in a paint chunk.
- DCHECK(!item.IsScrollHitTest() || item.Equals(*items.begin()));
- }
-
- // Because ScrollHitTestDisplayItems force new paint chunks (see:
- // PaintChunker::IncrementDisplayItemIndex), they should only be the first
- // item in a paint chunk.
- if (items.begin()->IsScrollHitTest()) {
- const auto& scroll_hit_test_item =
- static_cast<const ScrollHitTestDisplayItem&>(*items.begin());
- if (!chunk.hit_test_data)
- chunk.hit_test_data = std::make_unique<HitTestData>();
- chunk.hit_test_data->SetScrollHitTest(
- scroll_hit_test_item.scroll_offset_node(),
- scroll_hit_test_item.scroll_container_bounds());
- }
-
- if (known_to_be_opaque_region.contains(chunk.bounds))
- chunk.known_to_be_opaque = true;
-
- if (items.begin() != items.end()) {
- chunk.safe_opaque_background_color =
- DisplayItemBackgroundColor(*items.begin());
- }
-}
-
// For PaintArtifact::AppendDebugDrawing().
class DebugDrawingClient final : public DisplayItemClient {
public:
@@ -114,8 +30,6 @@ PaintArtifact::PaintArtifact() : display_item_list_(0) {}
PaintArtifact::PaintArtifact(DisplayItemList display_items,
Vector<PaintChunk> chunks)
: display_item_list_(std::move(display_items)), chunks_(std::move(chunks)) {
- for (auto& chunk : chunks_)
- ComputeChunkDerivedData(display_item_list_, chunk);
}
PaintArtifact::~PaintArtifact() = default;
@@ -153,7 +67,8 @@ void PaintArtifact::AppendDebugDrawing(
// Create a PaintChunk for the debug drawing.
chunks_.emplace_back(display_item_list_.size() - 1, display_item_list_.size(),
display_item.GetId(), property_tree_state);
- ComputeChunkDerivedData(display_item_list_, chunks_.back());
+ chunks_.back().bounds = chunks_.back().drawable_bounds =
+ display_item_list_.Last().VisualRect();
}
void PaintArtifact::Replay(GraphicsContext& graphics_context,
@@ -179,6 +94,18 @@ sk_sp<PaintRecord> PaintArtifact::GetPaintRecord(
->ReleaseAsRecord();
}
+SkColor PaintArtifact::SafeOpaqueBackgroundColor(
+ const PaintChunkSubset& chunks) const {
+ // Find the background color from the first drawing display item.
+ for (const auto& chunk : chunks) {
+ for (const auto& item : display_item_list_.ItemsInPaintChunk(chunk)) {
+ if (item.IsDrawing() && item.DrawsContent())
+ return static_cast<const DrawingDisplayItem&>(item).BackgroundColor();
+ }
+ }
+ return SK_ColorTRANSPARENT;
+}
+
void PaintArtifact::FinishCycle() {
// Until CompositeAfterPaint, PaintController::ClearPropertyTreeChangedStateTo
// is used for clearing the property tree changed state at the end of paint
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_artifact.h b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_artifact.h
index ee3be027d50..e6b18b20343 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_artifact.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_artifact.h
@@ -12,6 +12,7 @@
#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/vector.h"
+#include "third_party/skia/include/core/SkColor.h"
namespace cc {
class PaintCanvas;
@@ -60,11 +61,6 @@ class PLATFORM_EXPORT PaintArtifact final : public RefCounted<PaintArtifact> {
return PaintChunkSubset(PaintChunks(), subset_indices);
}
- Vector<PaintChunk>::const_iterator FindChunkByDisplayItemIndex(
- size_t index) const {
- return FindChunkInVectorByDisplayItemIndex(PaintChunks(), index);
- }
-
// Returns the approximate memory usage, excluding memory likely to be
// shared with the embedder after copying to cc::DisplayItemList.
size_t ApproximateUnsharedMemoryUsage() const;
@@ -86,6 +82,8 @@ class PLATFORM_EXPORT PaintArtifact final : public RefCounted<PaintArtifact> {
sk_sp<PaintRecord> GetPaintRecord(const PropertyTreeState& replay_state,
const IntPoint& offset = IntPoint()) const;
+ SkColor SafeOpaqueBackgroundColor(const PaintChunkSubset&) const;
+
// Called when the caller finishes updating a full document life cycle.
// Will cleanup data (e.g. raster invalidations) that will no longer be used
// for the next cycle, and update status to be ready for the next cycle.
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk.cc
index c5926d2f284..2b14e465929 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk.cc
@@ -10,13 +10,13 @@
namespace blink {
struct SameSizeAsPaintChunk {
- size_t begin_index;
- size_t end_index;
+ wtf_size_t begin_index;
+ wtf_size_t end_index;
PaintChunk::Id id;
PropertyTreeState properties;
- FloatRect bounds;
+ IntRect bounds;
+ IntRect drawable_bounds;
float outset_for_raster_effects;
- SkColor safe_opaque_background_color;
unsigned bools; // known_to_be_opaque, is_cacheable, client_is_just_created
void* pointers[1]; // hit_test_data
};
@@ -24,10 +24,34 @@ struct SameSizeAsPaintChunk {
static_assert(sizeof(PaintChunk) == sizeof(SameSizeAsPaintChunk),
"PaintChunk should stay small");
+bool PaintChunk::EqualsForUnderInvalidationChecking(
+ const PaintChunk& other) const {
+ return size() == other.size() && id == other.id &&
+ properties == other.properties && bounds == other.bounds &&
+ drawable_bounds == other.drawable_bounds &&
+ outset_for_raster_effects == other.outset_for_raster_effects &&
+ ((!hit_test_data && !other.hit_test_data) ||
+ (hit_test_data && other.hit_test_data &&
+ *hit_test_data == *other.hit_test_data));
+ // known_to_be_opaque is not checked because it's updated when we create the
+ // next chunk or release chunks. We ensure its correctness with unit tests and
+ // under-invalidation checking of display items.
+}
+
+size_t PaintChunk::MemoryUsageInBytes() const {
+ size_t total_size = sizeof(*this);
+ if (hit_test_data) {
+ total_size += sizeof(*hit_test_data);
+ total_size +=
+ hit_test_data->touch_action_rects.capacity() * sizeof(TouchActionRect);
+ }
+ return total_size;
+}
+
String PaintChunk::ToString() const {
StringBuilder sb;
sb.AppendFormat(
- "PaintChunk(begin=%zu, end=%zu, id=%s cacheable=%d props=(%s) bounds=%s "
+ "PaintChunk(begin=%u, end=%u, id=%s cacheable=%d props=(%s) bounds=%s "
"known_to_be_opaque=%d",
begin_index, end_index, id.ToString().Utf8().c_str(), is_cacheable,
properties.ToString().Utf8().c_str(), bounds.ToString().Utf8().c_str(),
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk.h b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk.h
index 2024df32a40..277bc25e0cc 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk.h
@@ -28,8 +28,8 @@ struct PLATFORM_EXPORT PaintChunk {
using Id = DisplayItem::Id;
- PaintChunk(size_t begin,
- size_t end,
+ PaintChunk(wtf_size_t begin,
+ wtf_size_t end,
const Id& id,
const PropertyTreeState& props)
: begin_index(begin),
@@ -39,7 +39,27 @@ struct PLATFORM_EXPORT PaintChunk {
is_cacheable(id.client.IsCacheable()),
client_is_just_created(id.client.IsJustCreated()) {}
- size_t size() const {
+ // Move a paint chunk from a cached subsequence.
+ PaintChunk(wtf_size_t begin, PaintChunk&& other)
+ : begin_index(begin),
+ end_index(begin + other.size()),
+ id(other.id),
+ properties(other.properties),
+ hit_test_data(std::move(other.hit_test_data)),
+ bounds(other.bounds),
+ drawable_bounds(other.drawable_bounds),
+ outset_for_raster_effects(other.outset_for_raster_effects),
+ known_to_be_opaque(other.known_to_be_opaque),
+ is_cacheable(other.is_cacheable),
+ client_is_just_created(false),
+ is_moved_from_cached_subsequence(true) {
+#if DCHECK_IS_ON()
+ DCHECK(other.id.client.IsAlive());
+ DCHECK(!other.id.client.IsJustCreated());
+#endif
+ }
+
+ wtf_size_t size() const {
DCHECK_GE(end_index, begin_index);
return end_index - begin_index;
}
@@ -63,24 +83,24 @@ struct PLATFORM_EXPORT PaintChunk {
return !client_is_just_created;
}
- size_t MemoryUsageInBytes() const {
- size_t total_size = sizeof(*this);
- if (hit_test_data) {
- total_size += sizeof(*hit_test_data);
- total_size +=
- hit_test_data->touch_action_rects.capacity() * sizeof(HitTestRect);
- }
- return total_size;
+ bool EqualsForUnderInvalidationChecking(const PaintChunk& other) const;
+
+ HitTestData& EnsureHitTestData() {
+ if (!hit_test_data)
+ hit_test_data = std::make_unique<HitTestData>();
+ return *hit_test_data;
}
+ size_t MemoryUsageInBytes() const;
+
String ToString() const;
// Index of the first drawing in this chunk.
- size_t begin_index;
+ wtf_size_t begin_index;
// Index of the first drawing not in this chunk, so that there are
// |endIndex - beginIndex| drawings in the chunk.
- size_t end_index;
+ wtf_size_t end_index;
// Identifier of this chunk. It should be unique if |is_cacheable| is true.
// This is used to match a new chunk to a cached old chunk to track changes
@@ -90,23 +110,27 @@ struct PLATFORM_EXPORT PaintChunk {
// The paint properties which apply to this chunk.
RefCountedPropertyTreeState properties;
- // The following fields are not initialized when the chunk is created because
- // they depend on the display items in this chunk. They are updated by the
- // constructor of PaintArtifact.
-
std::unique_ptr<HitTestData> hit_test_data;
- // The total bounds of this paint chunk's contents, in the coordinate space of
- // the containing transform node.
+ // The following fields depend on the display items in this chunk.
+ // They are updated when a display item is added into the chunk.
+
+ // The total bounds of visual rects of all display items in this paint chunk,
+ // and extra bounds that are not from display items for e.g. hit test.
+ // It's in the coordinate space of the containing transform node. This can be
+ // larger than |drawble_bounds|, because of non-drawable display items and
+ // extra bounds.
IntRect bounds;
+ // The total bounds of visual rects of drawable display items in this paint
+ // chunk.
+ IntRect drawable_bounds;
+
// Some raster effects can exceed |bounds| in the rasterization space. This
// is the maximum DisplayItemClient::VisualRectOutsetForRasterEffects() of
// all clients of items in this chunk.
float outset_for_raster_effects = 0;
- SkColor safe_opaque_background_color = 0;
-
// True if the bounds are filled entirely with opaque contents.
bool known_to_be_opaque = false;
@@ -114,29 +138,9 @@ struct PLATFORM_EXPORT PaintChunk {
// The following fields are put here to avoid memory gap.
bool is_cacheable;
bool client_is_just_created;
+ bool is_moved_from_cached_subsequence = false;
};
-inline bool ChunkLessThanIndex(const PaintChunk& chunk, size_t index) {
- return chunk.end_index <= index;
-}
-
-inline Vector<PaintChunk>::iterator FindChunkInVectorByDisplayItemIndex(
- Vector<PaintChunk>& chunks,
- size_t index) {
- auto* chunk =
- std::lower_bound(chunks.begin(), chunks.end(), index, ChunkLessThanIndex);
- DCHECK(chunk == chunks.end() ||
- (index >= chunk->begin_index && index < chunk->end_index));
- return chunk;
-}
-
-inline Vector<PaintChunk>::const_iterator FindChunkInVectorByDisplayItemIndex(
- const Vector<PaintChunk>& chunks,
- size_t index) {
- return FindChunkInVectorByDisplayItemIndex(
- const_cast<Vector<PaintChunk>&>(chunks), index);
-}
-
PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, const PaintChunk&);
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk_subset.h b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk_subset.h
index 7c9f1c75117..c28b7285818 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk_subset.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk_subset.h
@@ -42,7 +42,7 @@ class PaintChunkSubset {
}
// The index in the whole paint chunks set.
- size_t OriginalIndex() const { return subset_.OriginalIndex(offset_); }
+ wtf_size_t OriginalIndex() const { return subset_.OriginalIndex(offset_); }
private:
friend class PaintChunkSubset;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker.cc
index 67168a48af8..8766927440c 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker.cc
@@ -4,11 +4,13 @@
#include "third_party/blink/renderer/platform/graphics/paint/paint_chunker.h"
+#include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h"
+
namespace blink {
PaintChunker::PaintChunker()
: current_properties_(PropertyTreeState::Uninitialized()),
- force_new_chunk_(false) {}
+ force_new_chunk_(true) {}
PaintChunker::~PaintChunker() = default;
@@ -23,7 +25,7 @@ bool PaintChunker::IsInInitialState() const {
#endif
void PaintChunker::UpdateCurrentPaintChunkProperties(
- const base::Optional<PaintChunk::Id>& chunk_id,
+ const PaintChunk::Id* chunk_id,
const PropertyTreeState& properties) {
// If properties are the same, continue to use the previously set
// |next_chunk_id_| because the id of the outer painting is likely to be
@@ -37,14 +39,14 @@ void PaintChunker::UpdateCurrentPaintChunkProperties(
current_properties_ = properties;
}
-void PaintChunker::ForceNewChunk() {
- force_new_chunk_ = true;
- // Always use a new chunk id for a force chunk which may be for a subsequence
- // which needs the chunk id to be independence with previous chunks.
- next_chunk_id_ = base::nullopt;
+void PaintChunker::AppendByMoving(PaintChunk&& chunk) {
+ UpdateLastChunkKnownToBeOpaque();
+ wtf_size_t next_chunk_begin_index =
+ chunks_.IsEmpty() ? 0 : LastChunk().end_index;
+ chunks_.emplace_back(next_chunk_begin_index, std::move(chunk));
}
-bool PaintChunker::IncrementDisplayItemIndex(const DisplayItem& item) {
+PaintChunk& PaintChunker::EnsureCurrentChunk(const PaintChunk::Id& id) {
#if DCHECK_IS_ON()
// If this DCHECKs are hit we are missing a call to update the properties.
// See: ScopedPaintChunkProperties.
@@ -53,47 +55,118 @@ bool PaintChunker::IncrementDisplayItemIndex(const DisplayItem& item) {
DCHECK(current_properties_.IsInitialized());
#endif
- bool item_forces_new_chunk =
- item.IsForeignLayer() || item.IsScrollHitTest() || item.IsScrollbar();
+ if (WillForceNewChunk() || current_properties_ != LastChunk().properties) {
+ if (!next_chunk_id_)
+ next_chunk_id_.emplace(id);
+ UpdateLastChunkKnownToBeOpaque();
+ wtf_size_t begin = chunks_.IsEmpty() ? 0 : LastChunk().end_index;
+ chunks_.emplace_back(begin, begin, *next_chunk_id_, current_properties_);
+ next_chunk_id_ = base::nullopt;
+ force_new_chunk_ = false;
+ }
+ return LastChunk();
+}
+
+bool PaintChunker::IncrementDisplayItemIndex(const DisplayItem& item) {
+ bool item_forces_new_chunk = item.IsForeignLayer() ||
+ item.IsGraphicsLayerWrapper() ||
+ item.IsScrollbar();
+ if (item_forces_new_chunk)
+ SetForceNewChunk(true);
+
+ auto previous_size = size();
+ auto& chunk = EnsureCurrentChunk(item.GetId());
+ bool created_new_chunk = size() > previous_size;
+
+ chunk.bounds.Unite(item.VisualRect());
+ if (item.DrawsContent())
+ chunk.drawable_bounds.Unite(item.VisualRect());
+
+ constexpr wtf_size_t kMaxRegionComplexity = 10;
+ if (item.IsDrawing() &&
+ static_cast<const DrawingDisplayItem&>(item).KnownToBeOpaque() &&
+ last_chunk_known_to_be_opaque_region_.Complexity() < kMaxRegionComplexity)
+ last_chunk_known_to_be_opaque_region_.Unite(item.VisualRect());
+
+ chunk.outset_for_raster_effects =
+ std::max(chunk.outset_for_raster_effects, item.OutsetForRasterEffects());
+
+ chunk.end_index++;
+
+ // When forcing a new chunk, we still need to force new chunk for the next
+ // display item. Otherwise reset force_new_chunk_ to false.
+ DCHECK(!force_new_chunk_);
if (item_forces_new_chunk) {
- force_new_chunk_ = true;
- next_chunk_id_.emplace(item.GetId());
+ DCHECK(created_new_chunk);
+ SetForceNewChunk(true);
+ }
+
+ return created_new_chunk;
+}
+
+void PaintChunker::AddHitTestDataToCurrentChunk(const PaintChunk::Id& id,
+ const IntRect& rect,
+ TouchAction touch_action) {
+ // In CompositeAfterPaint, we ensure a paint chunk for correct composited
+ // hit testing. In pre-CompositeAfterPaint, this is unnecessary, except that
+ // there is special touch action, and that we have a non-root effect so that
+ // PaintChunksToCcLayer will emit paint operations for filters.
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
+ touch_action == TouchAction::kAuto &&
+ &current_properties_.Effect() == &EffectPaintPropertyNode::Root())
+ return;
+
+ auto& chunk = EnsureCurrentChunk(id);
+ chunk.bounds.Unite(rect);
+ if (touch_action != TouchAction::kAuto) {
+ chunk.EnsureHitTestData().touch_action_rects.push_back(
+ TouchActionRect{rect, touch_action});
}
+}
- size_t new_chunk_begin_index;
- if (chunks_.IsEmpty()) {
- new_chunk_begin_index = 0;
+void PaintChunker::CreateScrollHitTestChunk(
+ const PaintChunk::Id& id,
+ const TransformPaintPropertyNode* scroll_translation,
+ const IntRect& rect) {
+#if DCHECK_IS_ON()
+ if (id.type == DisplayItem::Type::kResizerScrollHitTest ||
+ id.type == DisplayItem::Type::kPluginScrollHitTest) {
+ // Resizer and plugin scroll hit tests are only used to prevent composited
+ // scrolling and should not have a scroll offset node.
+ DCHECK(!scroll_translation);
+ } else if (id.type == DisplayItem::Type::kScrollHitTest) {
+ DCHECK(scroll_translation);
+ // The scroll offset transform node should have an associated scroll node.
+ DCHECK(scroll_translation->ScrollNode());
} else {
- auto& last_chunk = LastChunk();
- if (!force_new_chunk_ && current_properties_ == last_chunk.properties) {
- // Continue the current chunk.
- last_chunk.end_index++;
- // We don't create a new chunk when UpdateCurrentPaintChunkProperties()
- // just changed |next_chunk_id_| but not |current_properties_|. Clear
- // |next_chunk_id_| which has been ignored.
- next_chunk_id_ = base::nullopt;
- return false;
- }
- new_chunk_begin_index = last_chunk.end_index;
+ NOTREACHED();
}
+#endif
- chunks_.emplace_back(new_chunk_begin_index, new_chunk_begin_index + 1,
- next_chunk_id_ ? *next_chunk_id_ : item.GetId(),
- current_properties_);
- next_chunk_id_ = base::nullopt;
+ SetForceNewChunk(true);
+ auto& chunk = EnsureCurrentChunk(id);
+ chunk.bounds.Unite(rect);
+ auto& hit_test_data = chunk.EnsureHitTestData();
+ hit_test_data.scroll_translation = scroll_translation;
+ hit_test_data.scroll_hit_test_rect = rect;
+ SetForceNewChunk(true);
+}
- // When forcing a new chunk, we still need to force new chunk for the next
- // display item. Otherwise reset force_new_chunk_ to false.
- if (!item_forces_new_chunk)
- force_new_chunk_ = false;
+void PaintChunker::UpdateLastChunkKnownToBeOpaque() {
+ if (chunks_.IsEmpty() || LastChunk().is_moved_from_cached_subsequence)
+ return;
- return true;
+ LastChunk().known_to_be_opaque =
+ last_chunk_known_to_be_opaque_region_.Contains(LastChunk().bounds);
+ last_chunk_known_to_be_opaque_region_ = Region();
}
Vector<PaintChunk> PaintChunker::ReleasePaintChunks() {
+ UpdateLastChunkKnownToBeOpaque();
next_chunk_id_ = base::nullopt;
current_properties_ = PropertyTreeState::Uninitialized();
chunks_.ShrinkToFit();
+ force_new_chunk_ = true;
return std::move(chunks_);
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker.h b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker.h
index c65ebe79e87..2b2dcdb57be 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker.h
@@ -7,6 +7,7 @@
#include "base/macros.h"
#include "base/optional.h"
+#include "third_party/blink/renderer/platform/geometry/region.h"
#include "third_party/blink/renderer/platform/graphics/paint/display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_artifact.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_chunk.h"
@@ -34,38 +35,50 @@ class PLATFORM_EXPORT PaintChunker final {
const PropertyTreeState& CurrentPaintChunkProperties() const {
return current_properties_;
}
- void UpdateCurrentPaintChunkProperties(const base::Optional<PaintChunk::Id>&,
+ void UpdateCurrentPaintChunkProperties(const PaintChunk::Id*,
const PropertyTreeState&);
- void ForceNewChunk();
+ // Sets the forcing new chunk status on or off. If the status is on, even the
+ // properties haven't change, we'll force a new paint chunk for the next
+ // display item and then automatically resets the status. Some special display
+ // item (e.g. ForeignLayerDisplayItem) also automatically sets the status on
+ // before and after the item to force a dedicated paint chunk.
+ void SetForceNewChunk(bool force) {
+ force_new_chunk_ = force;
+ next_chunk_id_ = base::nullopt;
+ }
+ bool WillForceNewChunk() const {
+ return force_new_chunk_ || chunks_.IsEmpty();
+ }
+
+ void AppendByMoving(PaintChunk&&);
// Returns true if a new chunk is created.
bool IncrementDisplayItemIndex(const DisplayItem&);
const Vector<PaintChunk>& PaintChunks() const { return chunks_; }
+ wtf_size_t size() const { return chunks_.size(); }
- PaintChunk& PaintChunkAt(wtf_size_t i) { return chunks_[i]; }
- wtf_size_t LastChunkIndex() const {
- return chunks_.IsEmpty() ? kNotFound : chunks_.size() - 1;
- }
PaintChunk& LastChunk() { return chunks_.back(); }
-
- PaintChunk& FindChunkByDisplayItemIndex(size_t index) {
- auto* chunk = FindChunkInVectorByDisplayItemIndex(chunks_, index);
- DCHECK(chunk != chunks_.end());
- return *chunk;
- }
+ const PaintChunk& LastChunk() const { return chunks_.back(); }
+
+ // The id will be used when we need to create a new current chunk.
+ // Otherwise it's ignored.
+ void AddHitTestDataToCurrentChunk(const PaintChunk::Id&,
+ const IntRect&,
+ TouchAction);
+ void CreateScrollHitTestChunk(
+ const PaintChunk::Id&,
+ const TransformPaintPropertyNode* scroll_translation,
+ const IntRect&);
// Releases the generated paint chunk list and raster invalidations and
// resets the state of this object.
Vector<PaintChunk> ReleasePaintChunks();
private:
- size_t ChunkIndex(const PaintChunk& chunk) const {
- size_t index = &chunk - &chunks_.front();
- DCHECK_LT(index, chunks_.size());
- return index;
- }
+ PaintChunk& EnsureCurrentChunk(const PaintChunk::Id&);
+ void UpdateLastChunkKnownToBeOpaque();
Vector<PaintChunk> chunks_;
@@ -79,6 +92,8 @@ class PLATFORM_EXPORT PaintChunker final {
PropertyTreeState current_properties_;
+ Region last_chunk_known_to_be_opaque_region_;
+
// True when an item forces a new chunk (e.g., foreign display items), and for
// the item following a forced chunk. PaintController also forces new chunks
// before and after subsequences by calling ForceNewChunk().
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 38c19a5348b..d474d4ea698 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
@@ -6,8 +6,12 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h"
+#include "third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_controller_test.h"
+#include "third_party/blink/renderer/platform/testing/fake_display_item_client.h"
#include "third_party/blink/renderer/platform/testing/paint_property_test_helpers.h"
+#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
using testing::ElementsAre;
@@ -17,28 +21,43 @@ namespace {
class PaintChunkerTest : public testing::Test {
protected:
- class TestDisplayItemClient : public DisplayItemClient {
- String DebugName() const final { return "Test"; }
- IntRect VisualRect() const final { return IntRect(); }
- };
- TestDisplayItemClient client_;
+ FakeDisplayItemClient client_;
};
DisplayItem::Type DisplayItemType(int offset) {
- return static_cast<DisplayItem::Type>(DisplayItem::kDrawingFirst + offset);
+ auto type =
+ static_cast<DisplayItem::Type>(DisplayItem::kDrawingFirst + offset);
+ DCHECK(DisplayItem::IsDrawingType(type));
+ return type;
}
-class TestChunkerDisplayItem : public DisplayItem {
+class TestChunkerDisplayItem : public DrawingDisplayItem {
public:
- TestChunkerDisplayItem(const DisplayItemClient& client,
- DisplayItem::Type type = DisplayItem::kDrawingFirst)
- : DisplayItem(client, type, sizeof(*this)) {}
+ explicit TestChunkerDisplayItem(
+ const DisplayItemClient& client,
+ DisplayItem::Type type = DisplayItem::kDrawingFirst)
+ : DrawingDisplayItem(client, type, nullptr) {}
};
-class TestDisplayItemRequiringSeparateChunk : public TestChunkerDisplayItem {
+class TestChunkerOpaqueDisplayItem : public DrawingDisplayItem {
public:
- TestDisplayItemRequiringSeparateChunk(const DisplayItemClient& client)
- : TestChunkerDisplayItem(client, DisplayItem::kForeignLayerPlugin) {}
+ explicit TestChunkerOpaqueDisplayItem(
+ const DisplayItemClient& client,
+ DisplayItem::Type type = DisplayItem::kDrawingFirst)
+ : DrawingDisplayItem(client, type, nullptr) {
+ SetKnownToBeOpaqueForTesting();
+ }
+};
+
+class TestDisplayItemRequiringSeparateChunk : public ForeignLayerDisplayItem {
+ public:
+ explicit TestDisplayItemRequiringSeparateChunk(
+ const DisplayItemClient& client)
+ : ForeignLayerDisplayItem(client,
+ DisplayItem::kForeignLayerPlugin,
+ cc::Layer::Create(),
+ FloatPoint(),
+ nullptr) {}
};
TEST_F(PaintChunkerTest, Empty) {
@@ -52,7 +71,7 @@ TEST_F(PaintChunkerTest, Empty) {
TEST_F(PaintChunkerTest, SingleNonEmptyRange) {
PaintChunker chunker;
PaintChunk::Id id(client_, DisplayItemType(1));
- chunker.UpdateCurrentPaintChunkProperties(id, DefaultPaintChunkProperties());
+ chunker.UpdateCurrentPaintChunkProperties(&id, DefaultPaintChunkProperties());
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
@@ -69,10 +88,10 @@ TEST_F(PaintChunkerTest, SingleNonEmptyRange) {
TEST_F(PaintChunkerTest, SamePropertiesTwiceCombineIntoOneChunk) {
PaintChunker chunker;
PaintChunk::Id id(client_, DisplayItemType(1));
- chunker.UpdateCurrentPaintChunkProperties(id, DefaultPaintChunkProperties());
+ chunker.UpdateCurrentPaintChunkProperties(&id, DefaultPaintChunkProperties());
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
- chunker.UpdateCurrentPaintChunkProperties(id, DefaultPaintChunkProperties());
+ chunker.UpdateCurrentPaintChunkProperties(&id, DefaultPaintChunkProperties());
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
const auto& chunks = chunker.PaintChunks();
@@ -88,7 +107,8 @@ TEST_F(PaintChunkerTest, SamePropertiesTwiceCombineIntoOneChunk) {
TEST_F(PaintChunkerTest, BuildMultipleChunksWithSinglePropertyChanging) {
PaintChunker chunker;
PaintChunk::Id id1(client_, DisplayItemType(1));
- chunker.UpdateCurrentPaintChunkProperties(id1, DefaultPaintChunkProperties());
+ chunker.UpdateCurrentPaintChunkProperties(&id1,
+ DefaultPaintChunkProperties());
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
@@ -98,7 +118,7 @@ TEST_F(PaintChunkerTest, BuildMultipleChunksWithSinglePropertyChanging) {
simple_transform.SetTransform(*simple_transform_node);
PaintChunk::Id id2(client_, DisplayItemType(2));
- chunker.UpdateCurrentPaintChunkProperties(id2, simple_transform);
+ chunker.UpdateCurrentPaintChunkProperties(&id2, simple_transform);
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
auto another_transform_node = CreateTransform(
@@ -106,7 +126,7 @@ TEST_F(PaintChunkerTest, BuildMultipleChunksWithSinglePropertyChanging) {
auto another_transform = DefaultPaintChunkProperties();
another_transform.SetTransform(*another_transform_node);
PaintChunk::Id id3(client_, DisplayItemType(3));
- chunker.UpdateCurrentPaintChunkProperties(id3, another_transform);
+ chunker.UpdateCurrentPaintChunkProperties(&id3, another_transform);
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
EXPECT_THAT(
@@ -119,7 +139,8 @@ TEST_F(PaintChunkerTest, BuildMultipleChunksWithSinglePropertyChanging) {
TEST_F(PaintChunkerTest, BuildMultipleChunksWithDifferentPropertyChanges) {
PaintChunker chunker;
PaintChunk::Id id1(client_, DisplayItemType(1));
- chunker.UpdateCurrentPaintChunkProperties(id1, DefaultPaintChunkProperties());
+ chunker.UpdateCurrentPaintChunkProperties(&id1,
+ DefaultPaintChunkProperties());
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
auto simple_transform_node = CreateTransform(
@@ -127,7 +148,7 @@ TEST_F(PaintChunkerTest, BuildMultipleChunksWithDifferentPropertyChanges) {
auto simple_transform = DefaultPaintChunkProperties();
simple_transform.SetTransform(*simple_transform_node);
PaintChunk::Id id2(client_, DisplayItemType(2));
- chunker.UpdateCurrentPaintChunkProperties(id2, simple_transform);
+ chunker.UpdateCurrentPaintChunkProperties(&id2, simple_transform);
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
@@ -136,7 +157,7 @@ TEST_F(PaintChunkerTest, BuildMultipleChunksWithDifferentPropertyChanges) {
simple_transform_and_effect.SetTransform(*simple_transform_node);
simple_transform_and_effect.SetEffect(*simple_effect_node);
PaintChunk::Id id3(client_, DisplayItemType(3));
- chunker.UpdateCurrentPaintChunkProperties(id3, simple_transform_and_effect);
+ chunker.UpdateCurrentPaintChunkProperties(&id3, simple_transform_and_effect);
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
@@ -151,13 +172,13 @@ TEST_F(PaintChunkerTest, BuildMultipleChunksWithDifferentPropertyChanges) {
*new_effect_node);
PaintChunk::Id id4(client_, DisplayItemType(4));
chunker.UpdateCurrentPaintChunkProperties(
- id4, simple_transform_and_effect_with_updated_transform);
+ &id4, simple_transform_and_effect_with_updated_transform);
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
// Test that going back to a previous chunk property still creates a new
// chunk.
- chunker.UpdateCurrentPaintChunkProperties(base::nullopt,
+ chunker.UpdateCurrentPaintChunkProperties(nullptr,
simple_transform_and_effect);
TestChunkerDisplayItem item_after_restore(client_, DisplayItemType(10));
chunker.IncrementDisplayItemIndex(item_after_restore);
@@ -187,7 +208,8 @@ TEST_F(PaintChunkerTest, BuildChunksFromNestedTransforms) {
// </root xform>
PaintChunker chunker;
PaintChunk::Id id1(client_, DisplayItemType(1));
- chunker.UpdateCurrentPaintChunkProperties(id1, DefaultPaintChunkProperties());
+ chunker.UpdateCurrentPaintChunkProperties(&id1,
+ DefaultPaintChunkProperties());
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
auto simple_transform_node = CreateTransform(
@@ -195,11 +217,11 @@ TEST_F(PaintChunkerTest, BuildChunksFromNestedTransforms) {
auto simple_transform = DefaultPaintChunkProperties();
simple_transform.SetTransform(*simple_transform_node);
PaintChunk::Id id2(client_, DisplayItemType(2));
- chunker.UpdateCurrentPaintChunkProperties(id2, simple_transform);
+ chunker.UpdateCurrentPaintChunkProperties(&id2, simple_transform);
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
- chunker.UpdateCurrentPaintChunkProperties(base::nullopt,
+ chunker.UpdateCurrentPaintChunkProperties(nullptr,
DefaultPaintChunkProperties());
TestChunkerDisplayItem item_after_restore(client_, DisplayItemType(10));
chunker.IncrementDisplayItemIndex(item_after_restore);
@@ -216,7 +238,8 @@ TEST_F(PaintChunkerTest, ChangingPropertiesWithoutItems) {
// Test that properties can change without display items being generated.
PaintChunker chunker;
PaintChunk::Id id1(client_, DisplayItemType(1));
- chunker.UpdateCurrentPaintChunkProperties(id1, DefaultPaintChunkProperties());
+ chunker.UpdateCurrentPaintChunkProperties(&id1,
+ DefaultPaintChunkProperties());
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
auto first_transform_node = CreateTransform(
@@ -224,14 +247,14 @@ TEST_F(PaintChunkerTest, ChangingPropertiesWithoutItems) {
auto first_transform = DefaultPaintChunkProperties();
first_transform.SetTransform(*first_transform_node);
PaintChunk::Id id2(client_, DisplayItemType(2));
- chunker.UpdateCurrentPaintChunkProperties(base::nullopt, first_transform);
+ chunker.UpdateCurrentPaintChunkProperties(nullptr, first_transform);
auto second_transform_node = CreateTransform(
t0(), TransformationMatrix(9, 8, 7, 6, 5, 4), FloatPoint3D(3, 2, 1));
auto second_transform = DefaultPaintChunkProperties();
second_transform.SetTransform(*second_transform_node);
PaintChunk::Id id3(client_, DisplayItemType(3));
- chunker.UpdateCurrentPaintChunkProperties(id3, second_transform);
+ chunker.UpdateCurrentPaintChunkProperties(&id3, second_transform);
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
EXPECT_THAT(
@@ -244,22 +267,24 @@ TEST_F(PaintChunkerTest, CreatesSeparateChunksWhenRequested) {
// Tests that the chunker creates a separate chunks for display items which
// require it.
PaintChunker chunker;
- TestDisplayItemClient client1;
+ FakeDisplayItemClient client1;
TestDisplayItemRequiringSeparateChunk i1(client1);
- TestDisplayItemClient client2;
+ FakeDisplayItemClient client2;
TestDisplayItemRequiringSeparateChunk i2(client2);
- TestDisplayItemClient client3;
+ FakeDisplayItemClient client3;
TestDisplayItemRequiringSeparateChunk i3(client3);
PaintChunk::Id id0(client_, DisplayItemType(0));
- chunker.UpdateCurrentPaintChunkProperties(id0, DefaultPaintChunkProperties());
+ chunker.UpdateCurrentPaintChunkProperties(&id0,
+ DefaultPaintChunkProperties());
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
chunker.IncrementDisplayItemIndex(i1);
chunker.IncrementDisplayItemIndex(i2);
TestChunkerDisplayItem after_i2(client_, DisplayItemType(10));
chunker.IncrementDisplayItemIndex(after_i2);
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
- chunker.UpdateCurrentPaintChunkProperties(id0, DefaultPaintChunkProperties());
+ chunker.UpdateCurrentPaintChunkProperties(&id0,
+ DefaultPaintChunkProperties());
chunker.IncrementDisplayItemIndex(i3);
EXPECT_THAT(
@@ -275,20 +300,36 @@ TEST_F(PaintChunkerTest, CreatesSeparateChunksWhenRequested) {
TEST_F(PaintChunkerTest, ForceNewChunkWithNewId) {
PaintChunker chunker;
PaintChunk::Id id0(client_, DisplayItemType(0));
- chunker.UpdateCurrentPaintChunkProperties(id0, DefaultPaintChunkProperties());
+ chunker.UpdateCurrentPaintChunkProperties(&id0,
+ DefaultPaintChunkProperties());
+ EXPECT_TRUE(chunker.WillForceNewChunk());
+ EXPECT_EQ(0u, chunker.size());
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
+ EXPECT_FALSE(chunker.WillForceNewChunk());
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
+ EXPECT_EQ(1u, chunker.size());
- chunker.ForceNewChunk();
- PaintChunk::Id id1(client_, DisplayItemType(10));
- chunker.UpdateCurrentPaintChunkProperties(id1, DefaultPaintChunkProperties());
+ chunker.SetForceNewChunk(true);
+ EXPECT_TRUE(chunker.WillForceNewChunk());
+ EXPECT_EQ(1u, chunker.size());
+ PaintChunk::Id id1(client_, DisplayItemType(1));
+ chunker.UpdateCurrentPaintChunkProperties(&id1,
+ DefaultPaintChunkProperties());
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
+ EXPECT_EQ(2u, chunker.size());
+ EXPECT_FALSE(chunker.WillForceNewChunk());
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
+ EXPECT_EQ(2u, chunker.size());
- chunker.ForceNewChunk();
- PaintChunk::Id id2(client_, DisplayItemType(20));
- chunker.UpdateCurrentPaintChunkProperties(id2, DefaultPaintChunkProperties());
+ chunker.SetForceNewChunk(true);
+ PaintChunk::Id id2(client_, DisplayItemType(2));
+ EXPECT_TRUE(chunker.WillForceNewChunk());
+ chunker.UpdateCurrentPaintChunkProperties(&id2,
+ DefaultPaintChunkProperties());
+ EXPECT_EQ(2u, chunker.size());
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
+ EXPECT_EQ(3u, chunker.size());
+ EXPECT_FALSE(chunker.WillForceNewChunk());
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
EXPECT_THAT(
@@ -301,25 +342,37 @@ TEST_F(PaintChunkerTest, ForceNewChunkWithNewId) {
TEST_F(PaintChunkerTest, ForceNewChunkWithoutNewId) {
PaintChunker chunker;
PaintChunk::Id id0(client_, DisplayItemType(0));
- chunker.UpdateCurrentPaintChunkProperties(base::nullopt,
+ chunker.UpdateCurrentPaintChunkProperties(nullptr,
DefaultPaintChunkProperties());
+ EXPECT_TRUE(chunker.WillForceNewChunk());
+ EXPECT_EQ(0u, chunker.size());
chunker.IncrementDisplayItemIndex(
TestChunkerDisplayItem(id0.client, id0.type));
+ EXPECT_FALSE(chunker.WillForceNewChunk());
+ EXPECT_EQ(1u, chunker.size());
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
- chunker.ForceNewChunk();
- PaintChunk::Id id1(client_, DisplayItemType(10));
+ chunker.SetForceNewChunk(true);
+ EXPECT_TRUE(chunker.WillForceNewChunk());
+ EXPECT_EQ(1u, chunker.size());
+ PaintChunk::Id id1(client_, DisplayItemType(1));
chunker.IncrementDisplayItemIndex(
TestChunkerDisplayItem(id1.client, id1.type));
+ EXPECT_FALSE(chunker.WillForceNewChunk());
+ EXPECT_EQ(2u, chunker.size());
chunker.IncrementDisplayItemIndex(
- TestChunkerDisplayItem(client_, DisplayItemType(11)));
+ TestChunkerDisplayItem(client_, DisplayItemType(2)));
- chunker.ForceNewChunk();
- PaintChunk::Id id2(client_, DisplayItemType(20));
+ chunker.SetForceNewChunk(true);
+ EXPECT_TRUE(chunker.WillForceNewChunk());
+ EXPECT_EQ(2u, chunker.size());
+ PaintChunk::Id id2(client_, DisplayItemType(3));
chunker.IncrementDisplayItemIndex(
TestChunkerDisplayItem(id2.client, id2.type));
+ EXPECT_FALSE(chunker.WillForceNewChunk());
+ EXPECT_EQ(3u, chunker.size());
chunker.IncrementDisplayItemIndex(
- TestChunkerDisplayItem(client_, DisplayItemType(21)));
+ TestChunkerDisplayItem(client_, DisplayItemType(4)));
EXPECT_THAT(
chunker.PaintChunks(),
@@ -328,19 +381,48 @@ TEST_F(PaintChunkerTest, ForceNewChunkWithoutNewId) {
IsPaintChunk(4, 6, id2, DefaultPaintChunkProperties())));
}
+TEST_F(PaintChunkerTest, SetAndImmediatelyUnsetForceNewChunk) {
+ PaintChunker chunker;
+ PaintChunk::Id id0(client_, DisplayItemType(0));
+ chunker.UpdateCurrentPaintChunkProperties(nullptr,
+ DefaultPaintChunkProperties());
+ EXPECT_TRUE(chunker.WillForceNewChunk());
+ EXPECT_EQ(0u, chunker.size());
+ chunker.IncrementDisplayItemIndex(
+ TestChunkerDisplayItem(id0.client, id0.type));
+ EXPECT_FALSE(chunker.WillForceNewChunk());
+ EXPECT_EQ(1u, chunker.size());
+ chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
+
+ // This should not force a new chunk. Simulates a ScopedPaintChunkHint
+ // without any painting in the scope.
+ chunker.SetForceNewChunk(true);
+ chunker.SetForceNewChunk(false);
+ EXPECT_FALSE(chunker.WillForceNewChunk());
+ chunker.IncrementDisplayItemIndex(
+ TestChunkerDisplayItem(client_, DisplayItemType(1)));
+ EXPECT_EQ(1u, chunker.size());
+
+ EXPECT_THAT(
+ chunker.PaintChunks(),
+ ElementsAre(IsPaintChunk(0, 3, id0, DefaultPaintChunkProperties())));
+}
+
TEST_F(PaintChunkerTest, NoNewChunkForSamePropertyDifferentIds) {
PaintChunker chunker;
PaintChunk::Id id0(client_, DisplayItemType(0));
- chunker.UpdateCurrentPaintChunkProperties(id0, DefaultPaintChunkProperties());
+ chunker.UpdateCurrentPaintChunkProperties(&id0,
+ DefaultPaintChunkProperties());
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
PaintChunk::Id id1(client_, DisplayItemType(1));
- chunker.UpdateCurrentPaintChunkProperties(id1, DefaultPaintChunkProperties());
+ chunker.UpdateCurrentPaintChunkProperties(&id1,
+ DefaultPaintChunkProperties());
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
- chunker.UpdateCurrentPaintChunkProperties(base::nullopt,
+ chunker.UpdateCurrentPaintChunkProperties(nullptr,
DefaultPaintChunkProperties());
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
@@ -350,29 +432,24 @@ TEST_F(PaintChunkerTest, NoNewChunkForSamePropertyDifferentIds) {
ElementsAre(IsPaintChunk(0, 6, id0, DefaultPaintChunkProperties())));
}
-class TestScrollHitTestRequiringSeparateChunk : public TestChunkerDisplayItem {
- public:
- TestScrollHitTestRequiringSeparateChunk(const DisplayItemClient& client)
- : TestChunkerDisplayItem(client, DisplayItem::kScrollHitTest) {}
-};
-
// Ensure that items following a forced chunk begin using the next display
// item's id.
TEST_F(PaintChunkerTest, ChunksFollowingForcedChunk) {
PaintChunker chunker;
- TestDisplayItemClient client;
- TestChunkerDisplayItem before_forced1(client, DisplayItemType(9));
- TestChunkerDisplayItem before_forced2(client, DisplayItemType(10));
- TestScrollHitTestRequiringSeparateChunk forced(client);
- TestChunkerDisplayItem after_forced1(client, DisplayItemType(11));
- TestChunkerDisplayItem after_forced2(client, DisplayItemType(12));
-
- PaintChunk::Id id0(client, DisplayItemType(8));
- chunker.UpdateCurrentPaintChunkProperties(id0, DefaultPaintChunkProperties());
+ FakeDisplayItemClient client;
+ TestChunkerDisplayItem before_forced1(client, DisplayItemType(1));
+ TestChunkerDisplayItem before_forced2(client, DisplayItemType(2));
+ TestDisplayItemRequiringSeparateChunk forced(client);
+ TestChunkerDisplayItem after_forced1(client, DisplayItemType(3));
+ TestChunkerDisplayItem after_forced2(client, DisplayItemType(4));
+
+ PaintChunk::Id id0(client, DisplayItemType(5));
+ chunker.UpdateCurrentPaintChunkProperties(&id0,
+ DefaultPaintChunkProperties());
// Both before_forced items should be in a chunk together.
chunker.IncrementDisplayItemIndex(before_forced1);
chunker.IncrementDisplayItemIndex(before_forced2);
- // The forced scroll hit test item should be in its own chunk.
+ // |forced| forces a dedicted paint chunk.
chunker.IncrementDisplayItemIndex(forced);
// Both after_forced items should be in a chunk together.
chunker.IncrementDisplayItemIndex(after_forced1);
@@ -391,7 +468,8 @@ TEST_F(PaintChunkerTest, ChunkIdsSkippingCache) {
PaintChunker chunker;
PaintChunk::Id id1(client_, DisplayItemType(1));
- chunker.UpdateCurrentPaintChunkProperties(id1, DefaultPaintChunkProperties());
+ chunker.UpdateCurrentPaintChunkProperties(&id1,
+ DefaultPaintChunkProperties());
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_));
@@ -400,10 +478,10 @@ TEST_F(PaintChunkerTest, ChunkIdsSkippingCache) {
auto simple_transform = DefaultPaintChunkProperties();
simple_transform.SetTransform(*simple_transform_node);
- TestDisplayItemClient uncacheable_client;
+ FakeDisplayItemClient uncacheable_client;
uncacheable_client.Invalidate(PaintInvalidationReason::kUncacheable);
PaintChunk::Id id2(uncacheable_client, DisplayItemType(2));
- chunker.UpdateCurrentPaintChunkProperties(id2, simple_transform);
+ chunker.UpdateCurrentPaintChunkProperties(&id2, simple_transform);
TestChunkerDisplayItem uncacheable_item(uncacheable_client);
chunker.IncrementDisplayItemIndex(uncacheable_item);
@@ -416,7 +494,7 @@ TEST_F(PaintChunkerTest, ChunkIdsSkippingCache) {
TestChunkerDisplayItem after_separate_chunk(client_, DisplayItemType(3));
chunker.IncrementDisplayItemIndex(after_separate_chunk);
- chunker.UpdateCurrentPaintChunkProperties(base::nullopt,
+ chunker.UpdateCurrentPaintChunkProperties(nullptr,
DefaultPaintChunkProperties());
TestChunkerDisplayItem after_restore(client_, DisplayItemType(4));
chunker.IncrementDisplayItemIndex(after_restore);
@@ -439,5 +517,205 @@ TEST_F(PaintChunkerTest, ChunkIdsSkippingCache) {
EXPECT_TRUE(chunks[4].is_cacheable);
}
+TEST_F(PaintChunkerTest, AddHitTestDataToCurrentChunk) {
+ PaintChunker chunker;
+ client_.SetVisualRect(IntRect(0, 0, 10, 10));
+
+ PaintChunk::Id id1(client_, DisplayItemType(1));
+
+ chunker.UpdateCurrentPaintChunkProperties(&id1,
+ DefaultPaintChunkProperties());
+ chunker.IncrementDisplayItemIndex(
+ TestChunkerDisplayItem(client_, DisplayItemType(2)));
+
+ PaintChunk::Id id2(client_, DisplayItemType(3));
+ auto transform = Create2DTranslation(t0(), 10, 20);
+ PropertyTreeState properties(*transform, c0(), e0());
+ chunker.UpdateCurrentPaintChunkProperties(&id2, properties);
+ // This is not used as id of the chunk because we already have |id2|.
+ PaintChunk::Id hit_test_id(client_, DisplayItem::kHitTest);
+ chunker.AddHitTestDataToCurrentChunk(hit_test_id, IntRect(10, 20, 30, 40),
+ TouchAction::kAuto);
+ chunker.AddHitTestDataToCurrentChunk(hit_test_id, IntRect(20, 30, 40, 50),
+ TouchAction::kPan);
+
+ chunker.SetForceNewChunk(true);
+ PaintChunk::Id id3(client_, DisplayItemType(4));
+ chunker.AddHitTestDataToCurrentChunk(id3, IntRect(40, 50, 60, 70),
+ TouchAction::kAuto);
+ chunker.IncrementDisplayItemIndex(
+ TestChunkerDisplayItem(client_, DisplayItemType(5)));
+
+ HitTestData hit_test_data;
+ hit_test_data.touch_action_rects = {
+ {IntRect(20, 30, 40, 50), TouchAction::kPan}};
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ EXPECT_THAT(
+ chunker.PaintChunks(),
+ ElementsAre(IsPaintChunk(0, 1, id1, DefaultPaintChunkProperties(),
+ nullptr, IntRect(0, 0, 10, 10)),
+ IsPaintChunk(1, 1, id2, properties, &hit_test_data,
+ IntRect(10, 20, 50, 60)),
+ IsPaintChunk(1, 2, id3, properties, nullptr,
+ IntRect(0, 0, 100, 120))));
+ } else {
+ EXPECT_THAT(
+ chunker.PaintChunks(),
+ ElementsAre(
+ IsPaintChunk(0, 1, id1, DefaultPaintChunkProperties(), nullptr,
+ IntRect(0, 0, 10, 10)),
+ IsPaintChunk(1, 1, id2, properties, &hit_test_data,
+ IntRect(20, 30, 40, 50)),
+ IsPaintChunk(1, 2, PaintChunk::Id(client_, DisplayItemType(5)),
+ properties, nullptr, IntRect(0, 0, 10, 10))));
+ }
+}
+
+TEST_F(PaintChunkerTest, ChunkBoundsAndKnownToBeOpaqueAllOpaqueItems) {
+ ScopedCompositeAfterPaintForTest cap(true);
+ PaintChunker chunker;
+ FakeDisplayItemClient client1("client1", IntRect(0, 0, 100, 100));
+ FakeDisplayItemClient client2("client2", IntRect(0, 100, 100, 50));
+ FakeDisplayItemClient client3("client3", IntRect(50, 50, 100, 100));
+
+ auto properties = DefaultPaintChunkProperties();
+ chunker.UpdateCurrentPaintChunkProperties(nullptr, properties);
+ // Single opaque item.
+ chunker.IncrementDisplayItemIndex(
+ TestChunkerOpaqueDisplayItem(client1, DisplayItemType(0)));
+ chunker.SetForceNewChunk(true);
+ // Two opaque items. No empty area in the united bounds.
+ chunker.IncrementDisplayItemIndex(
+ TestChunkerOpaqueDisplayItem(client1, DisplayItemType(1)));
+ chunker.IncrementDisplayItemIndex(
+ TestChunkerOpaqueDisplayItem(client2, DisplayItemType(2)));
+ chunker.SetForceNewChunk(true);
+ // Two opaque items. Has empty area in the united bounds.
+ chunker.IncrementDisplayItemIndex(
+ TestChunkerOpaqueDisplayItem(client1, DisplayItemType(3)));
+ chunker.IncrementDisplayItemIndex(
+ TestChunkerOpaqueDisplayItem(client3, DisplayItemType(4)));
+
+ Vector<PaintChunk> chunks = chunker.ReleasePaintChunks();
+ EXPECT_THAT(
+ chunks,
+ ElementsAre(
+ IsPaintChunk(0, 1, PaintChunk::Id(client1, DisplayItemType(0)),
+ properties, nullptr, IntRect(0, 0, 100, 100)),
+ IsPaintChunk(1, 3, PaintChunk::Id(client1, DisplayItemType(1)),
+ properties, nullptr, IntRect(0, 0, 100, 150)),
+ IsPaintChunk(3, 5, PaintChunk::Id(client1, DisplayItemType(3)),
+ properties, nullptr, IntRect(0, 0, 150, 150))));
+ ASSERT_EQ(3u, chunks.size());
+ EXPECT_TRUE(chunks[0].known_to_be_opaque);
+ EXPECT_TRUE(chunks[1].known_to_be_opaque);
+ EXPECT_FALSE(chunks[2].known_to_be_opaque);
+}
+
+TEST_F(PaintChunkerTest, ChunkBoundsAndKnownToBeOpaqueWithHitTest) {
+ ScopedCompositeAfterPaintForTest cap(true);
+ PaintChunker chunker;
+ FakeDisplayItemClient client1("client1", IntRect(0, 0, 100, 100));
+ FakeDisplayItemClient client2("client2", IntRect(0, 100, 100, 50));
+ FakeDisplayItemClient client3("client3", IntRect(50, 50, 100, 100));
+
+ auto properties = DefaultPaintChunkProperties();
+ chunker.UpdateCurrentPaintChunkProperties(nullptr, properties);
+ // Hit test rect only.
+ chunker.AddHitTestDataToCurrentChunk(
+ PaintChunk::Id(client1, DisplayItemType(0)), IntRect(10, 20, 30, 40),
+ TouchAction::kAuto);
+ chunker.SetForceNewChunk(true);
+ // Hit test rect is smaller than the opaque item.
+ chunker.IncrementDisplayItemIndex(
+ TestChunkerOpaqueDisplayItem(client1, DisplayItemType(1)));
+ chunker.AddHitTestDataToCurrentChunk(
+ PaintChunk::Id(client1, DisplayItemType(2)), IntRect(0, 0, 50, 100),
+ TouchAction::kAuto);
+ chunker.SetForceNewChunk(true);
+ // Hit test rect is the same as the opaque item.
+ chunker.IncrementDisplayItemIndex(
+ TestChunkerOpaqueDisplayItem(client1, DisplayItemType(3)));
+ chunker.AddHitTestDataToCurrentChunk(
+ PaintChunk::Id(client1, DisplayItemType(4)), IntRect(0, 0, 100, 100),
+ TouchAction::kAuto);
+ chunker.SetForceNewChunk(true);
+ // Hit test rect is bigger than the opaque item.
+ chunker.IncrementDisplayItemIndex(
+ TestChunkerOpaqueDisplayItem(client1, DisplayItemType(5)));
+ chunker.AddHitTestDataToCurrentChunk(
+ PaintChunk::Id(client1, DisplayItemType(6)), IntRect(0, 100, 200, 100),
+ TouchAction::kAuto);
+
+ Vector<PaintChunk> chunks = chunker.ReleasePaintChunks();
+ EXPECT_THAT(
+ chunks,
+ ElementsAre(
+ IsPaintChunk(0, 0, PaintChunk::Id(client1, DisplayItemType(0)),
+ properties, nullptr, IntRect(10, 20, 30, 40)),
+ IsPaintChunk(0, 1, PaintChunk::Id(client1, DisplayItemType(1)),
+ properties, nullptr, IntRect(0, 0, 100, 100)),
+ IsPaintChunk(1, 2, PaintChunk::Id(client1, DisplayItemType(3)),
+ properties, nullptr, IntRect(0, 0, 100, 100)),
+ IsPaintChunk(2, 3, PaintChunk::Id(client1, DisplayItemType(5)),
+ properties, nullptr, IntRect(0, 0, 200, 200))));
+ ASSERT_EQ(4u, chunks.size());
+ EXPECT_FALSE(chunks[0].known_to_be_opaque);
+ EXPECT_TRUE(chunks[1].known_to_be_opaque);
+ EXPECT_TRUE(chunks[2].known_to_be_opaque);
+ EXPECT_FALSE(chunks[3].known_to_be_opaque);
+}
+
+TEST_F(PaintChunkerTest, ChunkBoundsAndKnownToBeOpaqueMixedOpaquenessItems) {
+ ScopedCompositeAfterPaintForTest cap(true);
+ PaintChunker chunker;
+ FakeDisplayItemClient client1("client1", IntRect(0, 0, 100, 100));
+ FakeDisplayItemClient client3("client2", IntRect(50, 50, 50, 50));
+
+ auto properties = DefaultPaintChunkProperties();
+ chunker.UpdateCurrentPaintChunkProperties(nullptr, properties);
+ // Single translucent item .
+ chunker.IncrementDisplayItemIndex(
+ TestChunkerDisplayItem(client1, DisplayItemType(1)));
+ chunker.SetForceNewChunk(true);
+ // Two items, one translucent, one opaque. The opaque item doesn't contain
+ // the translucent item.
+ chunker.IncrementDisplayItemIndex(
+ TestChunkerDisplayItem(client1, DisplayItemType(2)));
+ chunker.IncrementDisplayItemIndex(
+ TestChunkerOpaqueDisplayItem(client3, DisplayItemType(3)));
+ chunker.SetForceNewChunk(true);
+ // Two items, one translucent, one opaque, with the same visual rect.
+ chunker.IncrementDisplayItemIndex(
+ TestChunkerDisplayItem(client1, DisplayItemType(4)));
+ chunker.IncrementDisplayItemIndex(
+ TestChunkerOpaqueDisplayItem(client1, DisplayItemType(5)));
+ chunker.SetForceNewChunk(true);
+ // Two items, one opaque, one translucent. The opaque item contains the
+ // translucent item.
+ chunker.IncrementDisplayItemIndex(
+ TestChunkerOpaqueDisplayItem(client1, DisplayItemType(6)));
+ chunker.IncrementDisplayItemIndex(
+ TestChunkerDisplayItem(client3, DisplayItemType(7)));
+
+ Vector<PaintChunk> chunks = chunker.ReleasePaintChunks();
+ EXPECT_THAT(
+ chunks,
+ ElementsAre(
+ IsPaintChunk(0, 1, PaintChunk::Id(client1, DisplayItemType(1)),
+ properties, nullptr, IntRect(0, 0, 100, 100)),
+ IsPaintChunk(1, 3, PaintChunk::Id(client1, DisplayItemType(2)),
+ properties, nullptr, IntRect(0, 0, 100, 100)),
+ IsPaintChunk(3, 5, PaintChunk::Id(client1, DisplayItemType(4)),
+ properties, nullptr, IntRect(0, 0, 100, 100)),
+ IsPaintChunk(5, 7, PaintChunk::Id(client1, DisplayItemType(6)),
+ properties, nullptr, IntRect(0, 0, 100, 100))));
+ ASSERT_EQ(4u, chunks.size());
+ EXPECT_FALSE(chunks[0].known_to_be_opaque);
+ EXPECT_FALSE(chunks[1].known_to_be_opaque);
+ EXPECT_TRUE(chunks[2].known_to_be_opaque);
+ EXPECT_TRUE(chunks[3].known_to_be_opaque);
+}
+
} // namespace
} // namespace blink
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 ff52743090b..fa69422b443 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
@@ -31,15 +31,57 @@ PaintController::~PaintController() {
DCHECK(usage_ == kTransient || new_display_item_list_.IsEmpty());
}
+// For micro benchmarks of record time.
+static bool g_subsequence_caching_disabled = false;
+static bool g_partial_invalidation = false;
+static int g_partial_invalidation_display_item_count = 0;
+static int g_partial_invalidation_subsequence_count = 0;
+
+// This is used to invalidate one out of every |kInvalidateDisplayItemInterval|
+// display items for the micro benchmark of record time with partial
+// invalidation.
+static bool ShouldInvalidateDisplayItemForBenchmark() {
+ constexpr int kInvalidateDisplayItemInterval = 8;
+ return g_partial_invalidation &&
+ !(g_partial_invalidation_display_item_count++ %
+ kInvalidateDisplayItemInterval);
+}
+// Similar to the above, but for subsequences.
+static bool ShouldInvalidateSubsequenceForBenchmark() {
+ constexpr int kInvalidateSubsequenceInterval = 2;
+ return g_partial_invalidation &&
+ !(g_partial_invalidation_subsequence_count++ %
+ kInvalidateSubsequenceInterval);
+}
+
+void PaintController::SetSubsequenceCachingDisabledForBenchmark() {
+ g_subsequence_caching_disabled = true;
+}
+
+void PaintController::SetPartialInvalidationForBenchmark() {
+ g_partial_invalidation = true;
+ g_partial_invalidation_display_item_count = 0;
+ g_partial_invalidation_subsequence_count = 0;
+}
+
+bool PaintController::ShouldForcePaintForBenchmark() {
+ return g_subsequence_caching_disabled || g_partial_invalidation;
+}
+
+void PaintController::ClearFlagsForBenchmark() {
+ g_subsequence_caching_disabled = false;
+ g_partial_invalidation = false;
+}
+
bool PaintController::UseCachedItemIfPossible(const DisplayItemClient& client,
DisplayItem::Type type) {
if (usage_ == kTransient)
return false;
- if (DisplayItemConstructionIsDisabled())
+ if (!ClientCacheIsValid(client))
return false;
- if (!ClientCacheIsValid(client))
+ if (ShouldInvalidateDisplayItemForBenchmark())
return false;
if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() &&
@@ -49,7 +91,7 @@ bool PaintController::UseCachedItemIfPossible(const DisplayItemClient& client,
return false;
}
- size_t cached_item =
+ auto cached_item =
FindCachedItem(DisplayItem::Id(client, type, current_fragment_));
if (cached_item == kNotFound) {
// See FindOutOfOrderCachedItemForward() for explanation of the situation.
@@ -89,7 +131,10 @@ bool PaintController::UseCachedSubsequenceIfPossible(
if (usage_ == kTransient)
return false;
- if (DisplayItemConstructionIsDisabled() || SubsequenceCachingIsDisabled())
+ if (g_subsequence_caching_disabled)
+ return false;
+
+ if (ShouldInvalidateSubsequenceForBenchmark())
return false;
if (!ClientCacheIsValid(client))
@@ -109,7 +154,14 @@ bool PaintController::UseCachedSubsequenceIfPossible(
return false;
}
- if (current_paint_artifact_->GetDisplayItemList()[markers->start]
+ wtf_size_t start_item_index =
+ current_paint_artifact_->PaintChunks()[markers->start_chunk_index]
+ .begin_index;
+ wtf_size_t end_item_index =
+ current_paint_artifact_->PaintChunks()[markers->end_chunk_index - 1]
+ .end_index;
+ if (end_item_index > start_item_index &&
+ current_paint_artifact_->GetDisplayItemList()[start_item_index]
.IsTombstone()) {
// The subsequence has already been copied, indicating that the same client
// created multiple subsequences. If DCHECK_IS_ON(), then we should have
@@ -121,23 +173,23 @@ bool PaintController::UseCachedSubsequenceIfPossible(
EnsureNewDisplayItemListInitialCapacity();
- if (next_item_to_match_ == markers->start) {
+ if (next_item_to_match_ == start_item_index) {
// We are matching new and cached display items sequentially. Skip the
// subsequence for later sequential matching of individual display items.
- next_item_to_match_ = markers->end;
+ next_item_to_match_ = end_item_index;
// Items before |next_item_to_match_| have been copied so we don't need to
// index them.
if (next_item_to_match_ > next_item_to_index_)
next_item_to_index_ = next_item_to_match_;
}
- num_cached_new_items_ += markers->end - markers->start;
+ num_cached_new_items_ += end_item_index - start_item_index;
++num_cached_new_subsequences_;
if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) {
DCHECK(!IsCheckingUnderInvalidation());
- under_invalidation_checking_begin_ = markers->start;
- under_invalidation_checking_end_ = markers->end;
+ under_invalidation_checking_begin_ = start_item_index;
+ under_invalidation_checking_end_ = end_item_index;
under_invalidation_message_prefix_ =
"(In cached subsequence for " + client.DebugName() + ")";
// Return false to let the painter actually paint. We will check if the new
@@ -145,9 +197,9 @@ bool PaintController::UseCachedSubsequenceIfPossible(
return false;
}
- size_t start = BeginSubsequence();
- CopyCachedSubsequence(markers->start, markers->end);
- EndSubsequence(client, start);
+ auto new_start_chunk_index = BeginSubsequence();
+ CopyCachedSubsequence(markers->start_chunk_index, markers->end_chunk_index);
+ EndSubsequence(client, new_start_chunk_index);
return true;
}
@@ -159,33 +211,50 @@ PaintController::SubsequenceMarkers* PaintController::GetSubsequenceMarkers(
return &result->value;
}
-size_t PaintController::BeginSubsequence() {
+wtf_size_t PaintController::BeginSubsequence() {
// Force new paint chunk which is required for subsequence caching.
- new_paint_chunks_.ForceNewChunk();
- return new_display_item_list_.size();
+ SetForceNewChunk(true);
+ return new_paint_chunks_.size();
}
void PaintController::EndSubsequence(const DisplayItemClient& client,
- size_t start) {
- size_t end = new_display_item_list_.size();
+ wtf_size_t start_chunk_index) {
+ auto end_chunk_index = new_paint_chunks_.size();
if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() &&
IsCheckingUnderInvalidation()) {
SubsequenceMarkers* markers = GetSubsequenceMarkers(client);
- if (!markers && start != end) {
- ShowSequenceUnderInvalidationError(
- "under-invalidation : unexpected subsequence", client, start, end);
- CHECK(false);
- }
- if (markers && markers->end - markers->start != end - start) {
- ShowSequenceUnderInvalidationError(
- "under-invalidation: new subsequence wrong length", client, start,
- end);
- CHECK(false);
+ if (!markers) {
+ if (start_chunk_index != end_chunk_index) {
+ ShowSequenceUnderInvalidationError(
+ "under-invalidation : unexpected subsequence", client);
+ CHECK(false);
+ }
+ } else {
+ if (markers->end_chunk_index - markers->start_chunk_index !=
+ end_chunk_index - start_chunk_index) {
+ ShowSequenceUnderInvalidationError(
+ "under-invalidation: new subsequence wrong length", client);
+ CHECK(false);
+ }
+ auto old_chunk_index = markers->start_chunk_index;
+ for (auto new_chunk_index = start_chunk_index;
+ new_chunk_index < end_chunk_index;
+ ++new_chunk_index, ++old_chunk_index) {
+ const auto& old_chunk =
+ current_paint_artifact_->PaintChunks()[old_chunk_index];
+ const auto& new_chunk =
+ new_paint_chunks_.PaintChunks()[new_chunk_index];
+ if (!old_chunk.EqualsForUnderInvalidationChecking(new_chunk)) {
+ ShowSequenceUnderInvalidationError(
+ "under-invalidation: chunk changed", client);
+ CHECK(false) << "Changed chunk: " << new_chunk;
+ }
+ }
}
}
- if (start == end) {
+ if (start_chunk_index == end_chunk_index) {
// Omit the empty subsequence. The forcing-new-chunk flag set by
// BeginSubsequence() still applies, but this not a big deal because empty
// subsequences are not common. Also we should not clear the flag because
@@ -194,35 +263,24 @@ void PaintController::EndSubsequence(const DisplayItemClient& client,
}
// Force new paint chunk which is required for subsequence caching.
- new_paint_chunks_.ForceNewChunk();
+ SetForceNewChunk(true);
DCHECK(!new_cached_subsequences_.Contains(&client))
<< "Multiple subsequences for client: " << client.DebugName();
- new_cached_subsequences_.insert(&client, SubsequenceMarkers(start, end));
+ new_cached_subsequences_.insert(
+ &client, SubsequenceMarkers{start_chunk_index, end_chunk_index});
}
-void PaintController::ProcessNewItem(DisplayItem& display_item) {
- DCHECK(!construction_disabled_);
-
- if (IsSkippingCache() && usage_ == kMultiplePaints) {
- display_item.Client().Invalidate(PaintInvalidationReason::kUncacheable);
- display_item.SetUncacheable();
- }
-
- bool chunk_added = new_paint_chunks_.IncrementDisplayItemIndex(display_item);
+void PaintController::DidAppendItem(DisplayItem& display_item) {
+ if (usage_ == kTransient)
+ return;
#if DCHECK_IS_ON()
- if (chunk_added && CurrentPaintChunk().is_cacheable) {
- AddToIndicesByClientMap(CurrentPaintChunk().id.client,
- new_paint_chunks_.LastChunkIndex(),
- new_paint_chunk_indices_by_client_);
- }
-
- if (usage_ == kMultiplePaints && display_item.IsCacheable()) {
- size_t index = FindMatchingItemFromIndex(
- display_item.GetId(), new_display_item_indices_by_client_,
- new_display_item_list_);
+ if (display_item.IsCacheable()) {
+ auto index = FindMatchingItemFromIndex(display_item.GetId(),
+ new_display_item_indices_by_client_,
+ new_display_item_list_);
if (index != kNotFound) {
ShowDebugData();
NOTREACHED() << "DisplayItem " << display_item.AsDebugString().Utf8()
@@ -234,13 +292,20 @@ void PaintController::ProcessNewItem(DisplayItem& display_item) {
new_display_item_list_.size() - 1,
new_display_item_indices_by_client_);
}
-#else // DCHECK_IS_ON()
- std::ignore = chunk_added;
#endif
- if (usage_ == kMultiplePaints &&
- RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled())
+ if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled())
CheckUnderInvalidation();
+}
+
+void PaintController::ProcessNewItem(DisplayItem& display_item) {
+ if (IsSkippingCache() && usage_ == kMultiplePaints) {
+ display_item.Client().Invalidate(PaintInvalidationReason::kUncacheable);
+ display_item.SetUncacheable();
+ }
+
+ if (new_paint_chunks_.IncrementDisplayItemIndex(display_item))
+ DidAppendChunk();
if (!frame_first_paints_.back().first_painted && display_item.IsDrawing() &&
// Here we ignore all document-background paintings because we don't
@@ -251,13 +316,26 @@ void PaintController::ProcessNewItem(DisplayItem& display_item) {
display_item.DrawsContent()) {
SetFirstPainted();
}
+
+ DidAppendItem(display_item);
}
-DisplayItem& PaintController::MoveItemFromCurrentListToNewList(size_t index) {
+DisplayItem& PaintController::MoveItemFromCurrentListToNewList(
+ wtf_size_t index) {
return new_display_item_list_.AppendByMoving(
current_paint_artifact_->GetDisplayItemList()[index]);
}
+void PaintController::DidAppendChunk() {
+#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_);
+ }
+#endif
+}
+
void PaintController::InvalidateAll() {
DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
InvalidateAllInternal();
@@ -278,6 +356,25 @@ bool PaintController::CacheIsAllInvalid() const {
return cache_is_all_invalid_;
}
+void PaintController::UpdateCurrentPaintChunkProperties(
+ const PaintChunk::Id* id,
+ const PropertyTreeState& properties) {
+ if (id) {
+ PaintChunk::Id id_with_fragment(*id, current_fragment_);
+ new_paint_chunks_.UpdateCurrentPaintChunkProperties(&id_with_fragment,
+ properties);
+ CheckDuplicatePaintChunkId(id_with_fragment);
+ } else {
+ new_paint_chunks_.UpdateCurrentPaintChunkProperties(nullptr, properties);
+ }
+}
+
+void PaintController::AppendChunkByMoving(PaintChunk&& chunk) {
+ CheckDuplicatePaintChunkId(chunk.id);
+ new_paint_chunks_.AppendByMoving(std::move(chunk));
+ DidAppendChunk();
+}
+
bool PaintController::ClientCacheIsValid(
const DisplayItemClient& client) const {
#if DCHECK_IS_ON()
@@ -288,7 +385,7 @@ bool PaintController::ClientCacheIsValid(
return client.IsValid();
}
-size_t PaintController::FindMatchingItemFromIndex(
+wtf_size_t PaintController::FindMatchingItemFromIndex(
const DisplayItem::Id& id,
const IndicesByClientMap& display_item_indices_by_client,
const DisplayItemList& list) {
@@ -297,8 +394,7 @@ size_t PaintController::FindMatchingItemFromIndex(
if (it == display_item_indices_by_client.end())
return kNotFound;
- const Vector<size_t>& indices = it->value;
- for (size_t index : indices) {
+ for (auto index : it->value) {
const DisplayItem& existing_item = list[index];
if (existing_item.IsTombstone())
continue;
@@ -311,17 +407,17 @@ size_t PaintController::FindMatchingItemFromIndex(
}
void PaintController::AddToIndicesByClientMap(const DisplayItemClient& client,
- size_t index,
+ wtf_size_t index,
IndicesByClientMap& map) {
auto it = map.find(&client);
auto& indices =
it == map.end()
- ? map.insert(&client, Vector<size_t>()).stored_value->value
+ ? map.insert(&client, Vector<wtf_size_t>()).stored_value->value
: it->value;
indices.push_back(index);
}
-size_t PaintController::FindCachedItem(const DisplayItem::Id& id) {
+wtf_size_t PaintController::FindCachedItem(const DisplayItem::Id& id) {
DCHECK(ClientCacheIsValid(id.client));
if (next_item_to_match_ <
@@ -342,7 +438,7 @@ size_t PaintController::FindCachedItem(const DisplayItem::Id& id) {
}
}
- size_t found_index =
+ wtf_size_t found_index =
FindMatchingItemFromIndex(id, out_of_order_item_indices_,
current_paint_artifact_->GetDisplayItemList());
if (found_index != kNotFound) {
@@ -356,9 +452,9 @@ size_t PaintController::FindCachedItem(const DisplayItem::Id& id) {
}
// Find forward for the item and index all skipped indexable items.
-size_t PaintController::FindOutOfOrderCachedItemForward(
+wtf_size_t PaintController::FindOutOfOrderCachedItemForward(
const DisplayItem::Id& id) {
- for (size_t i = next_item_to_index_;
+ for (auto i = next_item_to_index_;
i < current_paint_artifact_->GetDisplayItemList().size(); ++i) {
const DisplayItem& item = current_paint_artifact_->GetDisplayItemList()[i];
if (item.IsTombstone())
@@ -398,64 +494,48 @@ size_t PaintController::FindOutOfOrderCachedItemForward(
// When paintUnderInvaldiationCheckingEnabled() we'll not actually
// copy the subsequence, but mark the begin and end of the subsequence for
// under-invalidation checking.
-void PaintController::CopyCachedSubsequence(size_t begin_index,
- size_t end_index) {
+void PaintController::CopyCachedSubsequence(wtf_size_t start_chunk_index,
+ wtf_size_t end_chunk_index) {
+#if DCHECK_IS_ON()
DCHECK(!RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled());
-
- const DisplayItem* cached_item =
- &current_paint_artifact_->GetDisplayItemList()[begin_index];
-
- auto* cached_chunk =
- current_paint_artifact_->FindChunkByDisplayItemIndex(begin_index);
- DCHECK(cached_chunk != current_paint_artifact_->PaintChunks().end());
auto properties_before_subsequence =
new_paint_chunks_.CurrentPaintChunkProperties();
- UpdateCurrentPaintChunkPropertiesUsingIdWithFragment(
- cached_chunk->id, cached_chunk->properties.GetPropertyTreeState());
-
- for (size_t current_index = begin_index; current_index < end_index;
- ++current_index) {
- cached_item = &current_paint_artifact_->GetDisplayItemList()[current_index];
- SECURITY_CHECK(!cached_item->IsTombstone());
-#if DCHECK_IS_ON()
- DCHECK(cached_item->Client().IsAlive());
#endif
- if (current_index == cached_chunk->end_index) {
- ++cached_chunk;
- DCHECK(cached_chunk != current_paint_artifact_->PaintChunks().end());
- new_paint_chunks_.ForceNewChunk();
- UpdateCurrentPaintChunkPropertiesUsingIdWithFragment(
- cached_chunk->id, cached_chunk->properties.GetPropertyTreeState());
- }
-
+ for (auto chunk_index = start_chunk_index; chunk_index < end_chunk_index;
+ ++chunk_index) {
+ auto& cached_chunk = current_paint_artifact_->PaintChunks()[chunk_index];
+ auto cached_item_index = cached_chunk.begin_index;
+ for (auto& cached_item :
+ current_paint_artifact_->GetDisplayItemList().ItemsInPaintChunk(
+ cached_chunk)) {
+ SECURITY_CHECK(!cached_item.IsTombstone());
#if DCHECK_IS_ON()
- // Visual rect change should not happen in a cached subsequence.
- // However, because of different method of pixel snapping in different
- // paths, there are false positives. Just log an error.
- if (cached_item->VisualRect() != cached_item->Client().VisualRect()) {
- DLOG(ERROR) << "Visual rect changed in a cached subsequence: "
- << cached_item->Client().DebugName()
- << " old=" << cached_item->VisualRect()
- << " new=" << cached_item->Client().VisualRect();
- }
+ DCHECK(cached_item.Client().IsAlive());
+ // Visual rect change should not happen in a cached subsequence.
+ // However, because of different method of pixel snapping in different
+ // paths, there are false positives. Just log an error.
+ if (cached_item.VisualRect() != cached_item.Client().VisualRect()) {
+ DLOG(ERROR) << "Visual rect changed in a cached subsequence: "
+ << cached_item.Client().DebugName()
+ << " old=" << cached_item.VisualRect()
+ << " new=" << cached_item.Client().VisualRect();
+ }
#endif
+ auto& item = MoveItemFromCurrentListToNewList(cached_item_index++);
+ item.SetMovedFromCachedSubsequence(true);
+ DidAppendItem(item);
+ }
- ProcessNewItem(MoveItemFromCurrentListToNewList(current_index));
- DCHECK((!CurrentPaintChunk().is_cacheable && !cached_chunk->is_cacheable) ||
- CurrentPaintChunk().Matches(*cached_chunk));
+ DCHECK_EQ(cached_item_index, cached_chunk.end_index);
+ AppendChunkByMoving(std::move(cached_chunk));
}
- if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) {
- under_invalidation_checking_end_ = end_index;
- DCHECK(IsCheckingUnderInvalidation());
- } else {
- // Restore properties and force new chunk for any trailing display items
- // after the cached subsequence without new properties.
- new_paint_chunks_.ForceNewChunk();
- UpdateCurrentPaintChunkProperties(base::nullopt,
- properties_before_subsequence);
- }
+ SetForceNewChunk(true);
+
+#if DCHECK_IS_ON()
+ DCHECK_EQ(properties_before_subsequence, CurrentPaintChunkProperties());
+#endif
}
void PaintController::ResetCurrentListIndices() {
@@ -527,13 +607,31 @@ void PaintController::FinishCycle() {
}
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());
+#endif
+ continue;
+ }
client.ClearPartialInvalidationVisualRect();
if (client.IsCacheable())
client.Validate();
}
for (const auto& chunk : current_paint_artifact_->PaintChunks()) {
- if (chunk.id.client.IsCacheable())
- chunk.id.client.Validate();
+ 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());
+#endif
+ continue;
+ }
+ if (client.IsCacheable())
+ client.Validate();
}
}
@@ -638,9 +736,7 @@ void PaintController::ShowUnderInvalidationError(
void PaintController::ShowSequenceUnderInvalidationError(
const char* reason,
- const DisplayItemClient& client,
- int start,
- int end) {
+ const DisplayItemClient& client) {
LOG(ERROR) << under_invalidation_message_prefix_ << " " << reason;
LOG(ERROR) << "Subsequence client: " << client.DebugName();
#if DCHECK_IS_ON()
@@ -669,7 +765,7 @@ void PaintController::CheckUnderInvalidation() {
}
const DisplayItem& new_item = new_display_item_list_.Last();
- size_t old_item_index = under_invalidation_checking_begin_;
+ auto old_item_index = under_invalidation_checking_begin_;
DisplayItem* old_item =
old_item_index < current_paint_artifact_->GetDisplayItemList().size()
? &current_paint_artifact_->GetDisplayItemList()[old_item_index]
@@ -720,19 +816,21 @@ FrameFirstPaint PaintController::EndFrame(const void* frame) {
return result;
}
-#if DCHECK_IS_ON()
void PaintController::CheckDuplicatePaintChunkId(const PaintChunk::Id& id) {
+#if DCHECK_IS_ON()
if (IsSkippingCache())
return;
- if (DisplayItem::IsForeignLayerType(id.type))
+ if (DisplayItem::IsGraphicsLayerWrapperType(id.type) ||
+ DisplayItem::IsForeignLayerType(id.type)) {
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_.PaintChunkAt(index);
+ const auto& chunk = new_paint_chunks_.PaintChunks()[index];
if (chunk.id == id) {
ShowDebugData();
NOTREACHED() << "New paint chunk id " << id
@@ -740,8 +838,8 @@ void PaintController::CheckDuplicatePaintChunkId(const PaintChunk::Id& id) {
}
}
}
-}
#endif
+}
size_t PaintController::sum_num_items_ = 0;
size_t PaintController::sum_num_cached_items_ = 0;
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 118f538d49e..1aaea13fdda 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
@@ -28,7 +28,7 @@
namespace blink {
-static const size_t kInitialDisplayItemListCapacityBytes = 512;
+static constexpr wtf_size_t kInitialDisplayItemListCapacityBytes = 512;
// FrameFirstPaint stores first-paint, text or image painted for the
// corresponding frame. They are never reset to false. First-paint is defined in
@@ -73,33 +73,42 @@ class PLATFORM_EXPORT PaintController {
// These methods are called during painting.
// Provide a new set of paint chunk properties to apply to recorded display
- // items.
- void UpdateCurrentPaintChunkProperties(
- const base::Optional<PaintChunk::Id>& id,
- const PropertyTreeState& properties) {
- if (id) {
- PaintChunk::Id id_with_fragment(*id, current_fragment_);
- UpdateCurrentPaintChunkPropertiesUsingIdWithFragment(id_with_fragment,
- properties);
-#if DCHECK_IS_ON()
- CheckDuplicatePaintChunkId(id_with_fragment);
-#endif
- } else {
- new_paint_chunks_.UpdateCurrentPaintChunkProperties(base::nullopt,
- properties);
- }
- }
-
+ // items. If id is nullptr, the id of the first display item will be used as
+ // the id of the paint chunk if needed.
+ void UpdateCurrentPaintChunkProperties(const PaintChunk::Id*,
+ const PropertyTreeState&);
const PropertyTreeState& CurrentPaintChunkProperties() const {
return new_paint_chunks_.CurrentPaintChunkProperties();
}
+ // See PaintChunker for documentation of the following methods.
+ wtf_size_t NumNewChunks() const { return new_paint_chunks_.size(); }
+ void SetForceNewChunk(bool force) {
+ new_paint_chunks_.SetForceNewChunk(force);
+ }
+ bool WillForceNewChunk() const {
+ return new_paint_chunks_.WillForceNewChunk();
+ }
+ const IntRect& LastChunkBounds() const {
+ return new_paint_chunks_.LastChunk().bounds;
+ }
- PaintChunk& CurrentPaintChunk() { return new_paint_chunks_.LastChunk(); }
-
- void ForceNewChunk(const DisplayItemClient& client, DisplayItem::Type type) {
- new_paint_chunks_.ForceNewChunk();
- new_paint_chunks_.UpdateCurrentPaintChunkProperties(
- PaintChunk::Id(client, type), CurrentPaintChunkProperties());
+ void RecordHitTestData(const DisplayItemClient& client,
+ const IntRect& rect,
+ TouchAction touch_action) {
+ if (rect.IsEmpty())
+ return;
+ PaintChunk::Id id(client, DisplayItem::kHitTest, current_fragment_);
+ CheckDuplicatePaintChunkId(id);
+ new_paint_chunks_.AddHitTestDataToCurrentChunk(id, rect, touch_action);
+ }
+ void RecordScrollHitTestData(
+ const DisplayItemClient& client,
+ DisplayItem::Type type,
+ const TransformPaintPropertyNode* scroll_translation,
+ const IntRect& rect) {
+ PaintChunk::Id id(client, type, current_fragment_);
+ CheckDuplicatePaintChunkId(id);
+ new_paint_chunks_.CreateScrollHitTestChunk(id, scroll_translation, rect);
}
template <typename DisplayItemClass, typename... Args>
@@ -113,9 +122,6 @@ class PLATFORM_EXPORT PaintController {
"DisplayItem subclass alignment is not a factor of "
"kDisplayItemAlignment.");
- if (DisplayItemConstructionIsDisabled())
- return;
-
EnsureNewDisplayItemListInitialCapacity();
DisplayItemClass& display_item =
new_display_item_list_.AllocateAndConstruct<DisplayItemClass>(
@@ -134,10 +140,11 @@ class PLATFORM_EXPORT PaintController {
// true. Otherwise returns false.
bool UseCachedSubsequenceIfPossible(const DisplayItemClient&);
- size_t BeginSubsequence();
+ // Returns the index of the paint chunk that is forced for the subsequence.
+ wtf_size_t BeginSubsequence();
// The |start| parameter should be the return value of the corresponding
// BeginSubsequence().
- void EndSubsequence(const DisplayItemClient&, size_t start);
+ void EndSubsequence(const DisplayItemClient&, wtf_size_t start_chunk_index);
void BeginSkippingCache() {
if (usage_ == kTransient)
@@ -197,23 +204,11 @@ class PLATFORM_EXPORT PaintController {
return GetPaintArtifact().PaintChunks();
}
- // For micro benchmarking of record time. If true, display item construction
- // is disabled to isolate the costs of construction in performance metrics.
- bool DisplayItemConstructionIsDisabled() const {
- return construction_disabled_;
- }
- void SetDisplayItemConstructionIsDisabled(bool disable) {
- construction_disabled_ = disable;
- }
-
- // For micro benchmarking of record time. If true, subsequence caching is
- // disabled to test the cost of display item caching.
- bool SubsequenceCachingIsDisabled() const {
- return subsequence_caching_disabled_;
- }
- void SetSubsequenceCachingIsDisabled(bool disable) {
- subsequence_caching_disabled_ = disable;
- }
+ // For micro benchmarks of record time.
+ static void SetSubsequenceCachingDisabledForBenchmark();
+ static void SetPartialInvalidationForBenchmark();
+ static bool ShouldForcePaintForBenchmark();
+ static void ClearFlagsForBenchmark();
void SetFirstPainted();
void SetTextPainted();
@@ -278,30 +273,29 @@ class PLATFORM_EXPORT PaintController {
}
}
- // Set new item state (cache skipping, etc) for a new item.
+ // Set new item state (cache skipping, etc) for the last new display item.
void ProcessNewItem(DisplayItem&);
- DisplayItem& MoveItemFromCurrentListToNewList(size_t);
+
+ void DidAppendItem(DisplayItem&);
+ 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<size_t>>;
+ using IndicesByClientMap =
+ HashMap<const DisplayItemClient*, Vector<wtf_size_t>>;
- static size_t FindMatchingItemFromIndex(const DisplayItem::Id&,
- const IndicesByClientMap&,
- const DisplayItemList&);
+ static wtf_size_t FindMatchingItemFromIndex(const DisplayItem::Id&,
+ const IndicesByClientMap&,
+ const DisplayItemList&);
static void AddToIndicesByClientMap(const DisplayItemClient&,
- size_t index,
+ wtf_size_t index,
IndicesByClientMap&);
- size_t FindCachedItem(const DisplayItem::Id&);
- size_t FindOutOfOrderCachedItemForward(const DisplayItem::Id&);
- void CopyCachedSubsequence(size_t begin_index, size_t end_index);
-
- void UpdateCurrentPaintChunkPropertiesUsingIdWithFragment(
- const PaintChunk::Id& id_with_fragment,
- const PropertyTreeState& properties) {
- new_paint_chunks_.UpdateCurrentPaintChunkProperties(id_with_fragment,
- properties);
- }
+ wtf_size_t FindCachedItem(const DisplayItem::Id&);
+ wtf_size_t FindOutOfOrderCachedItemForward(const DisplayItem::Id&);
+ void CopyCachedSubsequence(wtf_size_t start_chunk_index,
+ wtf_size_t end_chunk_index);
+ void AppendChunkByMoving(PaintChunk&&);
// Resets the indices (e.g. next_item_to_match_) of
// current_paint_artifact_.GetDisplayItemList() to their initial values. This
@@ -316,9 +310,7 @@ class PLATFORM_EXPORT PaintController {
const DisplayItem* old_item) const;
void ShowSequenceUnderInvalidationError(const char* reason,
- const DisplayItemClient&,
- int start,
- int end);
+ const DisplayItemClient&);
void CheckUnderInvalidation();
bool IsCheckingUnderInvalidation() const {
@@ -327,19 +319,17 @@ class PLATFORM_EXPORT PaintController {
}
struct SubsequenceMarkers {
- SubsequenceMarkers() : start(0), end(0) {}
- SubsequenceMarkers(size_t start_arg, size_t end_arg)
- : start(start_arg), end(end_arg) {}
- // The start and end (not included) index within current_paint_artifact_
- // of this subsequence.
- size_t start;
- size_t end;
+ // The start and end (not included) index of paint chunks in this
+ // subsequence.
+ wtf_size_t start_chunk_index = 0;
+ wtf_size_t end_chunk_index = 0;
};
SubsequenceMarkers* GetSubsequenceMarkers(const DisplayItemClient&);
-#if DCHECK_IS_ON()
void CheckDuplicatePaintChunkId(const PaintChunk::Id&);
+
+#if DCHECK_IS_ON()
void ShowDebugDataInternal(DisplayItemList::JsonFlags) const;
#endif
@@ -355,9 +345,6 @@ class PLATFORM_EXPORT PaintController {
DisplayItemList new_display_item_list_;
PaintChunker new_paint_chunks_;
- bool construction_disabled_ = false;
- bool subsequence_caching_disabled_ = false;
-
bool cache_is_all_invalid_ = true;
bool committed_ = false;
@@ -366,8 +353,8 @@ class PLATFORM_EXPORT PaintController {
unsigned skipping_cache_count_ = 0;
- size_t num_cached_new_items_ = 0;
- size_t num_cached_new_subsequences_ = 0;
+ wtf_size_t num_cached_new_items_ = 0;
+ wtf_size_t num_cached_new_subsequences_ = 0;
// Stores indices to valid cacheable display items in
// current_paint_artifact_.GetDisplayItemList() that have not been matched by
@@ -381,16 +368,16 @@ class PLATFORM_EXPORT PaintController {
IndicesByClientMap out_of_order_item_indices_;
// The next item in the current list for sequential match.
- size_t next_item_to_match_ = 0;
+ wtf_size_t next_item_to_match_ = 0;
// The next item in the current list to be indexed for out-of-order cache
// requests.
- size_t next_item_to_index_ = 0;
+ wtf_size_t next_item_to_index_ = 0;
#if DCHECK_IS_ON()
- size_t num_indexed_items_ = 0;
- size_t num_sequential_matches_ = 0;
- size_t num_out_of_order_matches_ = 0;
+ wtf_size_t num_indexed_items_ = 0;
+ wtf_size_t num_sequential_matches_ = 0;
+ 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_;
@@ -404,8 +391,8 @@ class PLATFORM_EXPORT PaintController {
// end of the cached drawing or subsequence in the current list. The functions
// return false to let the client do actual painting, and PaintController will
// check if the actual painting results are the same as the cached.
- size_t under_invalidation_checking_begin_ = 0;
- size_t under_invalidation_checking_end_ = 0;
+ wtf_size_t under_invalidation_checking_begin_ = 0;
+ wtf_size_t under_invalidation_checking_end_ = 0;
String under_invalidation_message_prefix_;
@@ -413,7 +400,7 @@ class PLATFORM_EXPORT PaintController {
HashMap<const DisplayItemClient*, SubsequenceMarkers>;
CachedSubsequenceMap current_cached_subsequences_;
CachedSubsequenceMap new_cached_subsequences_;
- size_t last_cached_subsequence_end_ = 0;
+ wtf_size_t last_cached_subsequence_end_ = 0;
unsigned current_fragment_ = 0;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_debug_data.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_debug_data.cc
index 938214c8573..a0fe789b49b 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_debug_data.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_debug_data.cc
@@ -20,29 +20,25 @@ class PaintController::DisplayItemListAsJSON {
DisplayItemList::JsonFlags);
String ToString() {
- return SubsequenceAsJSONArrayRecursive(0, list_.size())
- ->ToPrettyJSONString();
+ return ChunksAsJSONArrayRecursive(0, chunks_.size())->ToPrettyJSONString();
}
private:
std::unique_ptr<JSONObject> SubsequenceAsJSONObjectRecursive();
- std::unique_ptr<JSONArray> SubsequenceAsJSONArrayRecursive(size_t, size_t);
- void AppendSubsequenceAsJSON(size_t, size_t, JSONArray&);
+ std::unique_ptr<JSONArray> ChunksAsJSONArrayRecursive(wtf_size_t, wtf_size_t);
+ void AppendChunksAsJSON(wtf_size_t, wtf_size_t, JSONArray&);
String ClientName(const DisplayItemClient&) const;
struct SubsequenceInfo {
- SubsequenceInfo(const DisplayItemClient* client, size_t start, size_t end)
- : client(client), start(start), end(end) {}
const DisplayItemClient* client;
- size_t start;
- size_t end;
+ wtf_size_t start_chunk_index;
+ wtf_size_t end_chunk_index;
};
const DisplayItemList& list_;
Vector<SubsequenceInfo> subsequences_;
Vector<SubsequenceInfo>::const_iterator current_subsequence_;
const Vector<PaintChunk>& chunks_;
- Vector<PaintChunk>::const_iterator current_chunk_;
DisplayItemList::JsonFlags flags_;
};
@@ -53,15 +49,16 @@ PaintController::DisplayItemListAsJSON::DisplayItemListAsJSON(
DisplayItemList::JsonFlags flags)
: list_(list),
chunks_(chunks),
- current_chunk_(chunks.begin()),
flags_(flags) {
for (const auto& item : subsequence_map) {
- subsequences_.push_back(
- SubsequenceInfo(item.key, item.value.start, item.value.end));
+ subsequences_.push_back(SubsequenceInfo{
+ item.key, item.value.start_chunk_index, item.value.end_chunk_index});
}
std::sort(subsequences_.begin(), subsequences_.end(),
[](const SubsequenceInfo& a, const SubsequenceInfo& b) {
- return a.start == b.start ? a.end > b.end : a.start < b.start;
+ return a.start_chunk_index == b.start_chunk_index
+ ? a.end_chunk_index > b.end_chunk_index
+ : a.start_chunk_index < b.start_chunk_index;
});
current_subsequence_ = subsequences_.begin();
@@ -77,70 +74,59 @@ PaintController::DisplayItemListAsJSON::SubsequenceAsJSONObjectRecursive() {
json_object->SetString("subsequence",
String::Format("client: %p ", subsequence.client) +
ClientName(*subsequence.client));
- json_object->SetArray("chunks", SubsequenceAsJSONArrayRecursive(
- subsequence.start, subsequence.end));
+ json_object->SetArray(
+ "chunks", ChunksAsJSONArrayRecursive(subsequence.start_chunk_index,
+ subsequence.end_chunk_index));
return json_object;
}
std::unique_ptr<JSONArray>
-PaintController::DisplayItemListAsJSON::SubsequenceAsJSONArrayRecursive(
- size_t start_item,
- size_t end_item) {
+PaintController::DisplayItemListAsJSON::ChunksAsJSONArrayRecursive(
+ wtf_size_t start_chunk_index,
+ wtf_size_t end_chunk_index) {
auto array = std::make_unique<JSONArray>();
- size_t item_index = start_item;
+ auto chunk_index = start_chunk_index;
while (current_subsequence_ != subsequences_.end() &&
- current_subsequence_->start < end_item) {
+ current_subsequence_->start_chunk_index < end_chunk_index) {
const auto& subsequence = *current_subsequence_;
- DCHECK(subsequence.start >= item_index);
- DCHECK(subsequence.end <= end_item);
+ DCHECK_GE(subsequence.start_chunk_index, chunk_index);
+ DCHECK_LE(subsequence.end_chunk_index, end_chunk_index);
- if (item_index < subsequence.start)
- AppendSubsequenceAsJSON(item_index, subsequence.start, *array);
+ if (chunk_index < subsequence.start_chunk_index)
+ AppendChunksAsJSON(chunk_index, subsequence.start_chunk_index, *array);
array->PushObject(SubsequenceAsJSONObjectRecursive());
- item_index = subsequence.end;
+ chunk_index = subsequence.end_chunk_index;
}
- if (item_index < end_item)
- AppendSubsequenceAsJSON(item_index, end_item, *array);
+ if (chunk_index < end_chunk_index)
+ AppendChunksAsJSON(chunk_index, end_chunk_index, *array);
return array;
}
-void PaintController::DisplayItemListAsJSON::AppendSubsequenceAsJSON(
- size_t start_item,
- size_t end_item,
+void PaintController::DisplayItemListAsJSON::AppendChunksAsJSON(
+ wtf_size_t start_chunk_index,
+ wtf_size_t end_chunk_index,
JSONArray& json_array) {
- DCHECK(end_item > start_item);
- if (current_chunk_ == chunks_.end()) {
- // We are in the middle of painting with incomplete chunks.
- auto json_object = std::make_unique<JSONObject>();
- json_object->SetString("chunk", "incomplete");
- json_object->SetArray(
- "displayItems", list_.SubsequenceAsJSON(start_item, end_item, flags_));
- json_array.PushObject(std::move(json_object));
- return;
- }
-
- DCHECK(current_chunk_->begin_index == start_item);
- while (current_chunk_ != chunks_.end() &&
- current_chunk_->end_index <= end_item) {
- const auto& chunk = *current_chunk_;
+ DCHECK_GT(end_chunk_index, start_chunk_index);
+ for (auto i = start_chunk_index; i < end_chunk_index; ++i) {
+ const auto& chunk = chunks_[i];
auto json_object = std::make_unique<JSONObject>();
json_object->SetString(
"chunk", ClientName(chunk.id.client) + " " + chunk.id.ToString());
json_object->SetString("state", chunk.properties.ToString());
+ json_object->SetString("bounds", chunk.bounds.ToString());
if (flags_ & DisplayItemList::kShowPaintRecords)
json_object->SetString("chunkData", chunk.ToString());
json_object->SetArray(
"displayItems",
- list_.SubsequenceAsJSON(chunk.begin_index, chunk.end_index, flags_));
+ list_.DisplayItemsAsJSON(chunk.begin_index, chunk.end_index, flags_));
json_array.PushObject(std::move(json_object));
- ++current_chunk_;
}
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.cc
index 098e3f3182e..cacaa2c7a95 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.cc
@@ -565,7 +565,7 @@ TEST_P(PaintControllerTest, CachedSubsequenceForcePaintChunk) {
FakeDisplayItemClient root("root");
auto root_properties = DefaultPaintChunkProperties();
PaintChunk::Id root_id(root, DisplayItem::kCaret);
- GetPaintController().UpdateCurrentPaintChunkProperties(root_id,
+ GetPaintController().UpdateCurrentPaintChunkProperties(&root_id,
root_properties);
DrawRect(context, root, kBackgroundType, FloatRect(100, 100, 100, 100));
@@ -575,7 +575,7 @@ TEST_P(PaintControllerTest, CachedSubsequenceForcePaintChunk) {
{
SubsequenceRecorder r(context, container);
GetPaintController().UpdateCurrentPaintChunkProperties(
- container_id, container_properties);
+ &container_id, container_properties);
DrawRect(context, container, kBackgroundType,
FloatRect(100, 100, 100, 100));
DrawRect(context, container, kForegroundType,
@@ -595,7 +595,7 @@ TEST_P(PaintControllerTest, CachedSubsequenceForcePaintChunk) {
IsPaintChunk(3, 4, PaintChunk::Id(root, kForegroundType),
root_properties)));
- GetPaintController().UpdateCurrentPaintChunkProperties(root_id,
+ GetPaintController().UpdateCurrentPaintChunkProperties(&root_id,
root_properties);
DrawRect(context, root, kBackgroundType, FloatRect(100, 100, 100, 100));
EXPECT_TRUE(GetPaintController().UseCachedSubsequenceIfPossible(container));
@@ -631,7 +631,7 @@ TEST_P(PaintControllerTest, CachedSubsequenceSwapOrder) {
{
GetPaintController().UpdateCurrentPaintChunkProperties(
- container1_id, container1_properties);
+ &container1_id, container1_properties);
SubsequenceRecorder r(context, container1);
DrawRect(context, container1, kBackgroundType,
@@ -643,7 +643,7 @@ TEST_P(PaintControllerTest, CachedSubsequenceSwapOrder) {
}
{
GetPaintController().UpdateCurrentPaintChunkProperties(
- container2_id, container2_properties);
+ &container2_id, container2_properties);
SubsequenceRecorder r(context, container2);
DrawRect(context, container2, kBackgroundType,
@@ -666,15 +666,10 @@ TEST_P(PaintControllerTest, CachedSubsequenceSwapOrder) {
IsSameId(&content2, kForegroundType),
IsSameId(&container2, kForegroundType)));
- auto* markers = GetSubsequenceMarkers(container1);
- CHECK(markers);
- EXPECT_EQ(0u, markers->start);
- EXPECT_EQ(4u, markers->end);
-
- markers = GetSubsequenceMarkers(container2);
- CHECK(markers);
- EXPECT_EQ(4u, markers->start);
- EXPECT_EQ(8u, markers->end);
+ EXPECT_SUBSEQUENCE(container1, 0, 1);
+ EXPECT_NO_SUBSEQUENCE(content1);
+ EXPECT_SUBSEQUENCE(container2, 1, 2);
+ EXPECT_NO_SUBSEQUENCE(content2);
EXPECT_THAT(
GetPaintController().PaintChunks(),
@@ -685,13 +680,13 @@ TEST_P(PaintControllerTest, CachedSubsequenceSwapOrder) {
// than that of |container2|.
if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) {
// When under-invalidation-checking is enabled,
- // useCachedSubsequenceIfPossible is forced off, and the client is expected
+ // UseCachedSubsequenceIfPossible is forced off, and the client is expected
// to create the same painting as in the previous paint.
EXPECT_FALSE(SubsequenceRecorder::UseCachedSubsequenceIfPossible(
context, container2));
{
GetPaintController().UpdateCurrentPaintChunkProperties(
- container2_id, container2_properties);
+ &container2_id, container2_properties);
SubsequenceRecorder r(context, container2);
DrawRect(context, container2, kBackgroundType,
@@ -707,7 +702,7 @@ TEST_P(PaintControllerTest, CachedSubsequenceSwapOrder) {
context, container1));
{
GetPaintController().UpdateCurrentPaintChunkProperties(
- container1_id, container1_properties);
+ &container1_id, container1_properties);
SubsequenceRecorder r(context, container1);
DrawRect(context, container1, kBackgroundType,
@@ -746,15 +741,10 @@ TEST_P(PaintControllerTest, CachedSubsequenceSwapOrder) {
IsSameId(&content1, kForegroundType),
IsSameId(&container1, kForegroundType)));
- markers = GetSubsequenceMarkers(container2);
- CHECK(markers);
- EXPECT_EQ(0u, markers->start);
- EXPECT_EQ(4u, markers->end);
-
- markers = GetSubsequenceMarkers(container1);
- CHECK(markers);
- EXPECT_EQ(4u, markers->start);
- EXPECT_EQ(8u, markers->end);
+ EXPECT_SUBSEQUENCE(container1, 1, 2);
+ EXPECT_NO_SUBSEQUENCE(content1);
+ EXPECT_SUBSEQUENCE(container2, 0, 1);
+ EXPECT_NO_SUBSEQUENCE(content2);
EXPECT_THAT(
GetPaintController().PaintChunks(),
@@ -763,12 +753,15 @@ TEST_P(PaintControllerTest, CachedSubsequenceSwapOrder) {
}
TEST_P(PaintControllerTest, CachedSubsequenceAndDisplayItemsSwapOrder) {
- FakeDisplayItemClient root("root", IntRect(0, 0, 300, 300));
FakeDisplayItemClient content1("content1", IntRect(100, 100, 50, 200));
FakeDisplayItemClient container2("container2", IntRect(100, 200, 100, 100));
FakeDisplayItemClient content2("content2", IntRect(100, 200, 50, 200));
GraphicsContext context(GetPaintController());
+ PaintChunk::Id content1_id(content1, kBackgroundType);
+ PaintChunk::Id container2_id(container2, kBackgroundType);
+ PaintChunk::Id content2_id(content2, kBackgroundType);
+
InitRootChunk();
DrawRect(context, content1, kBackgroundType, FloatRect(100, 100, 50, 200));
@@ -792,17 +785,26 @@ TEST_P(PaintControllerTest, CachedSubsequenceAndDisplayItemsSwapOrder) {
IsSameId(&container2, kForegroundType),
IsSameId(&content1, kForegroundType)));
- auto* markers = GetSubsequenceMarkers(container2);
- CHECK(markers);
- EXPECT_EQ(1u, markers->start);
- EXPECT_EQ(5u, markers->end);
+ EXPECT_NO_SUBSEQUENCE(content1);
+ EXPECT_SUBSEQUENCE(container2, 1, 2);
+ EXPECT_NO_SUBSEQUENCE(content2);
+
+ EXPECT_THAT(
+ GetPaintController().PaintChunks(),
+ ElementsAre(
+ IsPaintChunk(0, 1, DefaultRootChunkId(),
+ DefaultPaintChunkProperties()),
+ IsPaintChunk(1, 5, PaintChunk::Id(container2, kBackgroundType),
+ DefaultPaintChunkProperties()),
+ IsPaintChunk(5, 6, PaintChunk::Id(content1, kForegroundType),
+ DefaultPaintChunkProperties())));
// Simulate the situation when |container2| gets a z-index that is smaller
// than that of |content1|.
InitRootChunk();
if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) {
// When under-invalidation-checking is enabled,
- // useCachedSubsequenceIfPossible is forced off, and the client is expected
+ // UseCachedSubsequenceIfPossible is forced off, and the client is expected
// to create the same painting as in the previous paint.
EXPECT_FALSE(SubsequenceRecorder::UseCachedSubsequenceIfPossible(
context, container2));
@@ -846,22 +848,29 @@ TEST_P(PaintControllerTest, CachedSubsequenceAndDisplayItemsSwapOrder) {
IsSameId(&content1, kBackgroundType),
IsSameId(&content1, kForegroundType)));
- markers = GetSubsequenceMarkers(container2);
- CHECK(markers);
- EXPECT_EQ(0u, markers->start);
- EXPECT_EQ(4u, markers->end);
+ EXPECT_NO_SUBSEQUENCE(content1);
+ EXPECT_SUBSEQUENCE(container2, 0, 1);
+ EXPECT_NO_SUBSEQUENCE(content2);
+
+ EXPECT_THAT(
+ GetPaintController().PaintChunks(),
+ ElementsAre(
+ IsPaintChunk(0, 4, PaintChunk::Id(container2, kBackgroundType),
+ DefaultPaintChunkProperties()),
+ IsPaintChunk(4, 6, PaintChunk::Id(content1, kBackgroundType),
+ DefaultPaintChunkProperties())));
}
TEST_P(PaintControllerTest, CachedSubsequenceContainingFragments) {
GraphicsContext context(GetPaintController());
FakeDisplayItemClient root("root");
- constexpr size_t kFragmentCount = 3;
+ constexpr wtf_size_t kFragmentCount = 3;
FakeDisplayItemClient container("container");
// The first paint.
auto paint_container = [this, &context, &container]() {
SubsequenceRecorder r(context, container);
- for (size_t i = 0; i < kFragmentCount; ++i) {
+ for (wtf_size_t i = 0; i < kFragmentCount; ++i) {
ScopedDisplayItemFragment scoped_fragment(context, i);
ScopedPaintChunkProperties content_chunk_properties(
GetPaintController(), DefaultPaintChunkProperties(), container,
@@ -936,11 +945,11 @@ TEST_P(PaintControllerTest, UpdateSwapOrderCrossingChunks) {
auto container2_properties = DefaultPaintChunkProperties();
container2_properties.SetEffect(*container2_effect);
- GetPaintController().UpdateCurrentPaintChunkProperties(container1_id,
+ GetPaintController().UpdateCurrentPaintChunkProperties(&container1_id,
container1_properties);
DrawRect(context, container1, kBackgroundType, FloatRect(100, 100, 100, 100));
DrawRect(context, content1, kBackgroundType, FloatRect(100, 100, 50, 200));
- GetPaintController().UpdateCurrentPaintChunkProperties(container2_id,
+ GetPaintController().UpdateCurrentPaintChunkProperties(&container2_id,
container2_properties);
DrawRect(context, container2, kBackgroundType, FloatRect(100, 200, 100, 100));
DrawRect(context, content2, kBackgroundType, FloatRect(100, 200, 50, 200));
@@ -958,12 +967,12 @@ TEST_P(PaintControllerTest, UpdateSwapOrderCrossingChunks) {
IsPaintChunk(2, 4, container2_id, container2_properties)));
// Move content2 into container1, without invalidation.
- GetPaintController().UpdateCurrentPaintChunkProperties(container1_id,
+ GetPaintController().UpdateCurrentPaintChunkProperties(&container1_id,
container1_properties);
DrawRect(context, container1, kBackgroundType, FloatRect(100, 100, 100, 100));
DrawRect(context, content1, kBackgroundType, FloatRect(100, 100, 50, 200));
DrawRect(context, content2, kBackgroundType, FloatRect(100, 200, 50, 200));
- GetPaintController().UpdateCurrentPaintChunkProperties(container2_id,
+ GetPaintController().UpdateCurrentPaintChunkProperties(&container2_id,
container2_properties);
DrawRect(context, container2, kBackgroundType, FloatRect(100, 200, 100, 100));
@@ -1051,34 +1060,34 @@ TEST_P(PaintControllerTest, CachedNestedSubsequenceUpdate) {
{
SubsequenceRecorder r(context, container1);
GetPaintController().UpdateCurrentPaintChunkProperties(
- container1_background_id, container1_background_properties);
+ &container1_background_id, container1_background_properties);
DrawRect(context, container1, kBackgroundType,
FloatRect(100, 100, 100, 100));
{
SubsequenceRecorder r(context, content1);
GetPaintController().UpdateCurrentPaintChunkProperties(
- content1_id, content1_properties);
+ &content1_id, content1_properties);
DrawRect(context, content1, kBackgroundType,
FloatRect(100, 100, 50, 200));
DrawRect(context, content1, kForegroundType,
FloatRect(100, 100, 50, 200));
}
GetPaintController().UpdateCurrentPaintChunkProperties(
- container1_foreground_id, container1_foreground_properties);
+ &container1_foreground_id, container1_foreground_properties);
DrawRect(context, container1, kForegroundType,
FloatRect(100, 100, 100, 100));
}
{
SubsequenceRecorder r(context, container2);
GetPaintController().UpdateCurrentPaintChunkProperties(
- container2_background_id, container2_background_properties);
+ &container2_background_id, container2_background_properties);
DrawRect(context, container2, kBackgroundType,
FloatRect(100, 200, 100, 100));
{
SubsequenceRecorder r(context, content2);
GetPaintController().UpdateCurrentPaintChunkProperties(
- content2_id, content2_properties);
+ &content2_id, content2_properties);
DrawRect(context, content2, kBackgroundType,
FloatRect(100, 200, 50, 200));
}
@@ -1093,25 +1102,10 @@ TEST_P(PaintControllerTest, CachedNestedSubsequenceUpdate) {
IsSameId(&container2, kBackgroundType),
IsSameId(&content2, kBackgroundType)));
- auto* markers = GetSubsequenceMarkers(container1);
- CHECK(markers);
- EXPECT_EQ(0u, markers->start);
- EXPECT_EQ(4u, markers->end);
-
- markers = GetSubsequenceMarkers(content1);
- CHECK(markers);
- EXPECT_EQ(1u, markers->start);
- EXPECT_EQ(3u, markers->end);
-
- markers = GetSubsequenceMarkers(container2);
- CHECK(markers);
- EXPECT_EQ(4u, markers->start);
- EXPECT_EQ(6u, markers->end);
-
- markers = GetSubsequenceMarkers(content2);
- CHECK(markers);
- EXPECT_EQ(5u, markers->start);
- EXPECT_EQ(6u, markers->end);
+ EXPECT_SUBSEQUENCE(container1, 0, 3);
+ EXPECT_SUBSEQUENCE(content1, 1, 2);
+ EXPECT_SUBSEQUENCE(container2, 3, 5);
+ EXPECT_SUBSEQUENCE(content2, 4, 5);
EXPECT_THAT(
GetPaintController().PaintChunks(),
@@ -1139,7 +1133,7 @@ TEST_P(PaintControllerTest, CachedNestedSubsequenceUpdate) {
// Content2 now outputs foreground only.
{
SubsequenceRecorder r(context, content2);
- GetPaintController().UpdateCurrentPaintChunkProperties(content2_id,
+ GetPaintController().UpdateCurrentPaintChunkProperties(&content2_id,
content2_properties);
DrawRect(context, content2, kForegroundType, FloatRect(100, 200, 50, 200));
}
@@ -1151,13 +1145,13 @@ TEST_P(PaintControllerTest, CachedNestedSubsequenceUpdate) {
// Use cached subsequence of content1.
if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) {
// When under-invalidation-checking is enabled,
- // useCachedSubsequenceIfPossible is forced off, and the client is
+ // UseCachedSubsequenceIfPossible is forced off, and the client is
// expected to create the same painting as in the previous paint.
EXPECT_FALSE(SubsequenceRecorder::UseCachedSubsequenceIfPossible(
context, content1));
SubsequenceRecorder r(context, content1);
GetPaintController().UpdateCurrentPaintChunkProperties(
- content1_id, content1_properties);
+ &content1_id, content1_properties);
DrawRect(context, content1, kBackgroundType,
FloatRect(100, 100, 50, 200));
DrawRect(context, content1, kForegroundType,
@@ -1167,7 +1161,7 @@ TEST_P(PaintControllerTest, CachedNestedSubsequenceUpdate) {
context, content1));
}
GetPaintController().UpdateCurrentPaintChunkProperties(
- container1_foreground_id, container1_foreground_properties);
+ &container1_foreground_id, container1_foreground_properties);
DrawRect(context, container1, kForegroundType,
FloatRect(100, 100, 100, 100));
}
@@ -1188,20 +1182,10 @@ TEST_P(PaintControllerTest, CachedNestedSubsequenceUpdate) {
IsSameId(&content1, kForegroundType),
IsSameId(&container1, kForegroundType)));
- markers = GetSubsequenceMarkers(content2);
- CHECK(markers);
- EXPECT_EQ(0u, markers->start);
- EXPECT_EQ(1u, markers->end);
-
- markers = GetSubsequenceMarkers(container1);
- CHECK(markers);
- EXPECT_EQ(1u, markers->start);
- EXPECT_EQ(4u, markers->end);
-
- markers = GetSubsequenceMarkers(content1);
- CHECK(markers);
- EXPECT_EQ(1u, markers->start);
- EXPECT_EQ(3u, markers->end);
+ EXPECT_NO_SUBSEQUENCE(container2);
+ EXPECT_SUBSEQUENCE(content2, 0, 1);
+ EXPECT_SUBSEQUENCE(container1, 1, 3);
+ EXPECT_SUBSEQUENCE(content1, 1, 2);
EXPECT_THAT(GetPaintController().PaintChunks(),
ElementsAre(IsPaintChunk(0, 1, content2_id, content2_properties),
@@ -1637,9 +1621,7 @@ TEST_P(PaintControllerTest, DuplicatedSubsequences) {
#if DCHECK_IS_ON()
EXPECT_DEATH(paint_duplicated_subsequences(),
"Multiple subsequences for client: \"test\"");
- return;
-#endif
-
+#else
// The following is for non-DCHECK path. No security CHECK should trigger.
paint_duplicated_subsequences();
// Paint again.
@@ -1658,6 +1640,37 @@ TEST_P(PaintControllerTest, DuplicatedSubsequences) {
DrawRect(context, client, kForegroundType, FloatRect(100, 100, 100, 100));
}
CommitAndFinishCycle();
+#endif
+}
+
+TEST_P(PaintControllerTest, DeletedClientInUnderInvaldiatedSubsequence) {
+ if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled())
+ return;
+
+ FakeDisplayItemClient container("container");
+ auto content = std::make_unique<FakeDisplayItemClient>("content");
+ GraphicsContext context(GetPaintController());
+
+ InitRootChunk();
+ {
+ SubsequenceRecorder r(context, container);
+ DrawRect(context, *content, kBackgroundType, FloatRect(100, 100, 300, 300));
+ }
+ CommitAndFinishCycle();
+
+ content = nullptr;
+ InitRootChunk();
+ // Leave container not invalidated.
+#if DCHECK_IS_ON()
+ ASSERT_DEATH(
+ SubsequenceRecorder::UseCachedSubsequenceIfPossible(context, container),
+ "");
+#else
+ // This should not crash.
+ EXPECT_TRUE(
+ SubsequenceRecorder::UseCachedSubsequenceIfPossible(context, container));
+ CommitAndFinishCycle();
+#endif
}
class PaintControllerUnderInvalidationTest
@@ -1863,7 +1876,7 @@ TEST_F(PaintControllerUnderInvalidationTest, MoreDrawingInSubsequence) {
TEST_F(PaintControllerUnderInvalidationTest, LessDrawingInSubsequence) {
EXPECT_DEATH(TestLessDrawingInSubsequence(),
"In cached subsequence for first.*"
- "under-invalidation: new subsequence wrong length");
+ "under-invalidation: chunk changed");
}
TEST_F(PaintControllerUnderInvalidationTest, InvalidationInSubsequence) {
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 11f903de4e0..3f1b1142cce 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
@@ -8,6 +8,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
+#include "third_party/blink/renderer/platform/graphics/paint/hit_test_data.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
#include "third_party/blink/renderer/platform/testing/fake_display_item_client.h"
#include "third_party/blink/renderer/platform/testing/paint_property_test_helpers.h"
@@ -47,7 +48,7 @@ class PaintControllerTestBase : public testing::Test {
void InitRootChunk() { InitRootChunk(GetPaintController()); }
void InitRootChunk(PaintController& paint_controller) {
paint_controller.UpdateCurrentPaintChunkProperties(
- root_paint_chunk_id_, DefaultPaintChunkProperties());
+ &root_paint_chunk_id_, DefaultPaintChunkProperties());
}
const PaintChunk::Id DefaultRootChunkId() const {
return root_paint_chunk_id_;
@@ -55,20 +56,20 @@ class PaintControllerTestBase : public testing::Test {
PaintController& GetPaintController() { return *paint_controller_; }
- size_t NumCachedNewItems() const {
+ wtf_size_t NumCachedNewItems() const {
return paint_controller_->num_cached_new_items_;
}
- size_t NumCachedNewSubsequences() const {
+ wtf_size_t NumCachedNewSubsequences() const {
return paint_controller_->num_cached_new_subsequences_;
}
#if DCHECK_IS_ON()
- size_t NumIndexedItems() const {
+ wtf_size_t NumIndexedItems() const {
return paint_controller_->num_indexed_items_;
}
- size_t NumSequentialMatches() const {
+ wtf_size_t NumSequentialMatches() const {
return paint_controller_->num_sequential_matches_;
}
- size_t NumOutOfOrderMatches() const {
+ wtf_size_t NumOutOfOrderMatches() const {
return paint_controller_->num_out_of_order_matches_;
}
#endif
@@ -116,22 +117,42 @@ MATCHER_P2(IsSameId, client, type, "") {
// ELementsAre(IsPaintChunk(0, 1, id1, properties1),
// IsPaintChunk(1, 3, id2, properties2)));
inline bool CheckChunk(const PaintChunk& chunk,
- size_t begin,
- size_t end,
+ wtf_size_t begin,
+ wtf_size_t end) {
+ return chunk.begin_index == begin && chunk.end_index == end;
+}
+inline bool CheckChunk(const PaintChunk& chunk,
+ wtf_size_t begin,
+ wtf_size_t end,
const PaintChunk::Id& id,
const PropertyTreeState& properties,
- const HitTestData* hit_test_data = nullptr) {
+ const HitTestData* hit_test_data = nullptr,
+ const IntRect* bounds = nullptr) {
return chunk.begin_index == begin && chunk.end_index == end &&
chunk.id == id && chunk.properties == properties &&
((!chunk.hit_test_data && !hit_test_data) ||
(chunk.hit_test_data && hit_test_data &&
- *chunk.hit_test_data == *hit_test_data));
+ *chunk.hit_test_data == *hit_test_data)) &&
+ (!bounds || chunk.bounds == *bounds);
+}
+MATCHER_P2(IsPaintChunk, begin, end, "") {
+ return CheckChunk(arg, begin, end);
}
MATCHER_P4(IsPaintChunk, begin, end, id, properties, "") {
return CheckChunk(arg, begin, end, id, properties);
}
MATCHER_P5(IsPaintChunk, begin, end, id, properties, hit_test_data, "") {
- return CheckChunk(arg, begin, end, id, properties, &hit_test_data);
+ return CheckChunk(arg, begin, end, id, properties, hit_test_data);
+}
+MATCHER_P6(IsPaintChunk,
+ begin,
+ end,
+ id,
+ properties,
+ hit_test_data,
+ bounds,
+ "") {
+ return CheckChunk(arg, begin, end, id, properties, hit_test_data, &bounds);
}
// Shorter names for frequently used display item types in tests.
@@ -140,9 +161,22 @@ const DisplayItem::Type kForegroundType =
static_cast<DisplayItem::Type>(DisplayItem::kDrawingPaintPhaseFirst + 5);
const DisplayItem::Type kDocumentBackgroundType =
DisplayItem::kDocumentBackground;
-const DisplayItem::Type kScrollHitTestType = DisplayItem::kScrollHitTest;
const DisplayItem::Type kClipType = DisplayItem::kClipPaintPhaseFirst;
+#define EXPECT_SUBSEQUENCE(client, expected_start_chunk_index, \
+ expected_end_chunk_index) \
+ do { \
+ auto* subsequence = GetSubsequenceMarkers(client); \
+ ASSERT_NE(nullptr, subsequence); \
+ EXPECT_EQ(static_cast<wtf_size_t>(expected_start_chunk_index), \
+ subsequence->start_chunk_index); \
+ EXPECT_EQ(static_cast<wtf_size_t>(expected_end_chunk_index), \
+ subsequence->end_chunk_index); \
+ } while (false)
+
+#define EXPECT_NO_SUBSEQUENCE(client) \
+ EXPECT_EQ(nullptr, GetSubsequenceMarkers(client))
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_PAINT_CONTROLLER_TEST_H_
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_property_node_test.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_property_node_test.cc
index 85133e1a387..3228623d6bd 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_property_node_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_property_node_test.cc
@@ -32,16 +32,11 @@ class PaintPropertyNodeTest : public testing::Test {
// grandchild1 grandchild2
transform.root = &TransformPaintPropertyNode::Root();
- transform.ancestor =
- CreateTransform(*transform.root, TransformationMatrix());
- transform.child1 =
- CreateTransform(*transform.ancestor, TransformationMatrix());
- transform.child2 =
- CreateTransform(*transform.ancestor, TransformationMatrix());
- transform.grandchild1 =
- CreateTransform(*transform.child1, TransformationMatrix());
- transform.grandchild2 =
- CreateTransform(*transform.child2, TransformationMatrix());
+ transform.ancestor = Create2DTranslation(*transform.root, 0, 0);
+ transform.child1 = Create2DTranslation(*transform.ancestor, 0, 0);
+ transform.child2 = Create2DTranslation(*transform.ancestor, 0, 0);
+ transform.grandchild1 = Create2DTranslation(*transform.child1, 0, 0);
+ transform.grandchild2 = Create2DTranslation(*transform.child2, 0, 0);
clip.root = &ClipPaintPropertyNode::Root();
clip.ancestor =
@@ -321,8 +316,7 @@ TEST_F(PaintPropertyNodeTest, ChangeDirectCompositingReason) {
ResetAllChanged();
ExpectUnchangedState();
TransformPaintPropertyNode::State state;
- state.direct_compositing_reasons =
- CompositingReason::kActiveTransformAnimation;
+ state.direct_compositing_reasons = CompositingReason::kWillChangeTransform;
transform.child1->Update(*transform.ancestor, std::move(state));
EXPECT_CHANGE_EQ(PaintPropertyChangeType::kChangedOnlyNonRerasterValues,
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_record_builder.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_record_builder.cc
index b7b3241f107..58b6468fa91 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_record_builder.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_record_builder.cc
@@ -16,11 +16,6 @@ PaintRecordBuilder::PaintRecordBuilder(
PaintController* paint_controller,
paint_preview::PaintPreviewTracker* tracker)
: paint_controller_(nullptr) {
- GraphicsContext::DisabledMode disabled_mode =
- GraphicsContext::kNothingDisabled;
- if (containing_context && containing_context->ContextDisabled())
- disabled_mode = GraphicsContext::kFullyDisabled;
-
if (paint_controller) {
paint_controller_ = paint_controller;
} else {
@@ -30,10 +25,10 @@ PaintRecordBuilder::PaintRecordBuilder(
}
paint_controller_->UpdateCurrentPaintChunkProperties(
- base::nullopt, PropertyTreeState::Root());
+ nullptr, PropertyTreeState::Root());
- context_ = std::make_unique<GraphicsContext>(
- *paint_controller_, disabled_mode, metafile, tracker);
+ context_ =
+ std::make_unique<GraphicsContext>(*paint_controller_, metafile, tracker);
if (containing_context) {
context_->SetDarkMode(containing_context->dark_mode_settings());
context_->SetDeviceScaleFactor(containing_context->DeviceScaleFactor());
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/property_tree_state.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/property_tree_state.cc
index 690447f4d70..94372310848 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/property_tree_state.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/property_tree_state.cc
@@ -12,9 +12,11 @@ const PropertyTreeState& PropertyTreeState::Uninitialized() {
DEFINE_STATIC_REF(const TransformPaintPropertyNode, transform,
TransformPaintPropertyNode::Create(
TransformPaintPropertyNode::Root(), {}));
- DEFINE_STATIC_REF(const ClipPaintPropertyNode, clip,
- ClipPaintPropertyNode::Create(ClipPaintPropertyNode::Root(),
- {transform}));
+ DEFINE_STATIC_REF(
+ const ClipPaintPropertyNode, clip,
+ ClipPaintPropertyNode::Create(
+ ClipPaintPropertyNode::Root(),
+ ClipPaintPropertyNode::State(transform, FloatRoundedRect())));
DEFINE_STATIC_REF(const EffectPaintPropertyNode, effect,
EffectPaintPropertyNode::Create(
EffectPaintPropertyNode::Root(), {transform}));
@@ -49,6 +51,14 @@ String PropertyTreeState::ToTreeString() const {
#endif
+std::unique_ptr<JSONObject> PropertyTreeState::ToJSON() const {
+ std::unique_ptr<JSONObject> result = std::make_unique<JSONObject>();
+ result->SetObject("transform", transform_->ToJSON());
+ result->SetObject("clip", clip_->ToJSON());
+ result->SetObject("effect", effect_->ToJSON());
+ return result;
+}
+
size_t PropertyTreeState::CacheMemoryUsageInBytes() const {
return Clip().CacheMemoryUsageInBytes() +
Transform().CacheMemoryUsageInBytes();
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/property_tree_state.h b/chromium/third_party/blink/renderer/platform/graphics/paint/property_tree_state.h
index 5fa7473122c..d8ac00926b3 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/property_tree_state.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/property_tree_state.h
@@ -79,6 +79,7 @@ class PLATFORM_EXPORT PropertyTreeState {
// Dumps the tree from this state up to the root as a string.
String ToTreeString() const;
#endif
+ std::unique_ptr<JSONObject> ToJSON() const;
// Returns memory usage of the transform & clip caches of this state plus
// ancestors.
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.cc
index 1a65460c14d..b987497e0fd 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.cc
@@ -78,47 +78,48 @@ static bool CompareRasterInvalidationInfo(const RasterInvalidationInfo& a,
return a.reason < b.reason;
}
-void RasterInvalidationTracking::AsJSON(JSONObject* json) const {
+void RasterInvalidationTracking::AsJSON(JSONObject* json, bool detailed) const {
if (!invalidations_.IsEmpty()) {
// Sort to make the output more readable and easier to see the differences
// by a human.
- auto sorted_invalidations = invalidations_;
- std::sort(sorted_invalidations.begin(), sorted_invalidations.end(),
- &CompareRasterInvalidationInfo);
- auto paint_invalidations_json = std::make_unique<JSONArray>();
- for (auto& info : sorted_invalidations) {
- auto info_json = std::make_unique<JSONObject>();
- info_json->SetString("object", info.client_debug_name);
- if (!info.rect.IsEmpty()) {
- if (info.rect == LayoutRect::InfiniteIntRect())
- info_json->SetString("rect", "infinite");
- else
- info_json->SetArray("rect", RectAsJSONArray(info.rect));
+ auto sorted = invalidations_;
+ std::sort(sorted.begin(), sorted.end(), &CompareRasterInvalidationInfo);
+ auto invalidations_json = std::make_unique<JSONArray>();
+ IntRect last_rect;
+ for (auto* it = sorted.begin(); it != sorted.end(); it++) {
+ const auto& info = *it;
+ if (detailed) {
+ auto info_json = std::make_unique<JSONObject>();
+ info_json->SetArray("rect", RectAsJSONArray(info.rect));
+ info_json->SetString("object", info.client_debug_name);
+ info_json->SetString("reason",
+ PaintInvalidationReasonToString(info.reason));
+ invalidations_json->PushObject(std::move(info_json));
+ } else if (std::none_of(sorted.begin(), it, [&info](auto& previous) {
+ return previous.rect.Contains(info.rect);
+ })) {
+ invalidations_json->PushArray(RectAsJSONArray(info.rect));
+ last_rect = info.rect;
}
- info_json->SetString("reason",
- PaintInvalidationReasonToString(info.reason));
- paint_invalidations_json->PushObject(std::move(info_json));
}
- json->SetArray("paintInvalidations", std::move(paint_invalidations_json));
+ json->SetArray("invalidations", std::move(invalidations_json));
}
if (!under_invalidations_.IsEmpty()) {
- auto under_paint_invalidations_json = std::make_unique<JSONArray>();
- for (auto& under_paint_invalidation : under_invalidations_) {
- auto under_paint_invalidation_json = std::make_unique<JSONObject>();
- under_paint_invalidation_json->SetDouble("x", under_paint_invalidation.x);
- under_paint_invalidation_json->SetDouble("y", under_paint_invalidation.y);
- under_paint_invalidation_json->SetString(
+ auto under_invalidations_json = std::make_unique<JSONArray>();
+ for (auto& under_invalidation : under_invalidations_) {
+ auto under_invalidation_json = std::make_unique<JSONObject>();
+ under_invalidation_json->SetDouble("x", under_invalidation.x);
+ under_invalidation_json->SetDouble("y", under_invalidation.y);
+ under_invalidation_json->SetString(
"oldPixel",
- Color(under_paint_invalidation.old_pixel).NameForLayoutTreeAsText());
- under_paint_invalidation_json->SetString(
+ Color(under_invalidation.old_pixel).NameForLayoutTreeAsText());
+ under_invalidation_json->SetString(
"newPixel",
- Color(under_paint_invalidation.new_pixel).NameForLayoutTreeAsText());
- under_paint_invalidations_json->PushObject(
- std::move(under_paint_invalidation_json));
+ Color(under_invalidation.new_pixel).NameForLayoutTreeAsText());
+ under_invalidations_json->PushObject(std::move(under_invalidation_json));
}
- json->SetArray("underPaintInvalidations",
- std::move(under_paint_invalidations_json));
+ json->SetArray("underInvalidations", std::move(under_invalidations_json));
}
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h b/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h
index 94bf0a526ce..29047835625 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h
@@ -95,7 +95,7 @@ class PLATFORM_EXPORT RasterInvalidationTracking {
sk_sp<PaintRecord> new_record,
const IntRect& new_interest_rect);
- void AsJSON(JSONObject*) const;
+ void AsJSON(JSONObject*, bool detailed) const;
void AddToLayerDebugInfo(cc::LayerDebugInfo&) const;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc
index a7033cf5adb..54f8b52e774 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc
@@ -48,7 +48,7 @@ void RasterInvalidator::SetTracksRasterInvalidations(bool should_track) {
}
}
-const PaintChunk& RasterInvalidator::GetOldChunk(size_t index) const {
+const PaintChunk& RasterInvalidator::GetOldChunk(wtf_size_t index) const {
DCHECK(old_paint_artifact_);
const auto& old_chunk_info = old_paint_chunks_info_[index];
const auto& old_chunk =
@@ -60,13 +60,14 @@ const PaintChunk& RasterInvalidator::GetOldChunk(size_t index) const {
return old_chunk;
}
-size_t RasterInvalidator::MatchNewChunkToOldChunk(const PaintChunk& new_chunk,
- size_t old_index) const {
- for (size_t i = old_index; i < old_paint_chunks_info_.size(); i++) {
+wtf_size_t RasterInvalidator::MatchNewChunkToOldChunk(
+ const PaintChunk& new_chunk,
+ wtf_size_t old_index) const {
+ for (wtf_size_t i = old_index; i < old_paint_chunks_info_.size(); i++) {
if (new_chunk.Matches(GetOldChunk(i)))
return i;
}
- for (size_t i = 0; i < old_index; i++) {
+ for (wtf_size_t i = 0; i < old_index; i++) {
if (new_chunk.Matches(GetOldChunk(i)))
return i;
}
@@ -170,6 +171,7 @@ bool ShouldSkipForRasterInvalidation(const PaintArtifact& paint_artifact,
// common cases that most of the chunks can be matched in-order, the complexity
// is slightly larger than O(n).
void RasterInvalidator::GenerateRasterInvalidations(
+ RasterInvalidationFunction function,
const PaintArtifact& new_paint_artifact,
const PaintChunkSubset& new_chunks,
const PropertyTreeState& layer_state,
@@ -179,8 +181,8 @@ void RasterInvalidator::GenerateRasterInvalidations(
visual_rect_subpixel_offset);
Vector<bool> old_chunks_matched;
old_chunks_matched.resize(old_paint_chunks_info_.size());
- size_t old_index = 0;
- size_t max_matched_old_index = 0;
+ wtf_size_t old_index = 0;
+ wtf_size_t max_matched_old_index = 0;
for (auto it = new_chunks.begin(); it != new_chunks.end(); ++it) {
const auto& new_chunk = *it;
if (ShouldSkipForRasterInvalidation(new_paint_artifact, new_chunk))
@@ -189,23 +191,26 @@ void RasterInvalidator::GenerateRasterInvalidations(
mapper.SwitchToChunk(new_chunk);
auto& new_chunk_info = new_chunks_info.emplace_back(*this, mapper, it);
- // Foreign layers take care of raster invalidation by themselves.
- if (DisplayItem::IsForeignLayerType(new_chunk.id.type))
+ // Foreign layers and GraphicsLayers take care of raster invalidation by
+ // themselves.
+ if (DisplayItem::IsGraphicsLayerWrapperType(new_chunk.id.type) ||
+ DisplayItem::IsForeignLayerType(new_chunk.id.type)) {
continue;
+ }
if (!new_chunk.is_cacheable) {
- AddRasterInvalidation(new_chunk_info.bounds_in_layer, new_chunk.id.client,
- PaintInvalidationReason::kChunkUncacheable,
- kClientIsNew);
+ AddRasterInvalidation(
+ function, new_chunk_info.bounds_in_layer, new_chunk.id.client,
+ PaintInvalidationReason::kChunkUncacheable, kClientIsNew);
continue;
}
- size_t matched_old_index = MatchNewChunkToOldChunk(new_chunk, old_index);
+ auto matched_old_index = MatchNewChunkToOldChunk(new_chunk, old_index);
if (matched_old_index == kNotFound) {
// The new chunk doesn't match any old chunk.
- AddRasterInvalidation(new_chunk_info.bounds_in_layer, new_chunk.id.client,
- PaintInvalidationReason::kChunkAppeared,
- kClientIsNew);
+ AddRasterInvalidation(
+ function, new_chunk_info.bounds_in_layer, new_chunk.id.client,
+ PaintInvalidationReason::kChunkAppeared, kClientIsNew);
continue;
}
@@ -229,10 +234,10 @@ void RasterInvalidator::GenerateRasterInvalidations(
// Invalidate both old and new bounds of the chunk if the chunk's paint
// properties changed, or is moved backward and may expose area that was
// previously covered by it.
- AddRasterInvalidation(old_chunk_info.bounds_in_layer, new_chunk.id.client,
- reason, kClientIsNew);
+ AddRasterInvalidation(function, old_chunk_info.bounds_in_layer,
+ new_chunk.id.client, reason, kClientIsNew);
if (old_chunk_info.bounds_in_layer != new_chunk_info.bounds_in_layer) {
- AddRasterInvalidation(new_chunk_info.bounds_in_layer,
+ AddRasterInvalidation(function, new_chunk_info.bounds_in_layer,
new_chunk.id.client, reason, kClientIsNew);
}
// Ignore the display item raster invalidations because we have fully
@@ -246,12 +251,12 @@ void RasterInvalidator::GenerateRasterInvalidations(
old_chunk_info.chunk_to_layer_transform;
if (reason == PaintInvalidationReason::kIncremental) {
- IncrementallyInvalidateChunk(old_chunk_info, new_chunk_info,
+ IncrementallyInvalidateChunk(function, old_chunk_info, new_chunk_info,
new_chunk.id.client);
}
if (&new_paint_artifact != old_paint_artifact_) {
- DisplayItemRasterInvalidator(*this, *old_paint_artifact_,
+ DisplayItemRasterInvalidator(*this, function, *old_paint_artifact_,
new_paint_artifact, old_chunk, new_chunk,
mapper)
.Generate();
@@ -265,7 +270,7 @@ void RasterInvalidator::GenerateRasterInvalidations(
}
// Invalidate remaining unmatched (disappeared or uncacheable) old chunks.
- for (size_t i = 0; i < old_paint_chunks_info_.size(); ++i) {
+ for (wtf_size_t i = 0; i < old_paint_chunks_info_.size(); ++i) {
if (old_chunks_matched[i])
continue;
@@ -273,19 +278,20 @@ void RasterInvalidator::GenerateRasterInvalidations(
auto reason = old_chunk.is_cacheable
? PaintInvalidationReason::kChunkDisappeared
: PaintInvalidationReason::kChunkUncacheable;
- AddRasterInvalidation(old_paint_chunks_info_[i].bounds_in_layer,
+ AddRasterInvalidation(function, old_paint_chunks_info_[i].bounds_in_layer,
old_chunk.id.client, reason, kClientIsOld);
}
}
void RasterInvalidator::IncrementallyInvalidateChunk(
+ RasterInvalidationFunction function,
const PaintChunkInfo& old_chunk_info,
const PaintChunkInfo& new_chunk_info,
const DisplayItemClient& client) {
SkRegion diff(old_chunk_info.bounds_in_layer);
diff.op(new_chunk_info.bounds_in_layer, SkRegion::kXOR_Op);
for (SkRegion::Iterator it(diff); !it.done(); it.next()) {
- AddRasterInvalidation(IntRect(it.rect()), client,
+ AddRasterInvalidation(function, IntRect(it.rect()), client,
PaintInvalidationReason::kIncremental, kClientIsNew);
}
}
@@ -308,16 +314,19 @@ RasterInvalidationTracking& RasterInvalidator::EnsureTracking() {
}
void RasterInvalidator::Generate(
+ RasterInvalidationFunction raster_invalidation_function,
scoped_refptr<const PaintArtifact> new_paint_artifact,
const gfx::Rect& layer_bounds,
const PropertyTreeState& layer_state,
const FloatSize& visual_rect_subpixel_offset,
const DisplayItemClient* layer_client) {
- Generate(new_paint_artifact, new_paint_artifact->PaintChunks(), layer_bounds,
- layer_state, visual_rect_subpixel_offset, layer_client);
+ Generate(raster_invalidation_function, new_paint_artifact,
+ new_paint_artifact->PaintChunks(), layer_bounds, layer_state,
+ visual_rect_subpixel_offset, layer_client);
}
void RasterInvalidator::Generate(
+ RasterInvalidationFunction raster_invalidation_function,
scoped_refptr<const PaintArtifact> new_paint_artifact,
const PaintChunkSubset& paint_chunks,
const gfx::Rect& layer_bounds,
@@ -352,7 +361,8 @@ void RasterInvalidator::Generate(
layer_client ? *layer_client : paint_chunks[0].id.client);
}
} else {
- GenerateRasterInvalidations(*new_paint_artifact, paint_chunks, layer_state,
+ GenerateRasterInvalidations(raster_invalidation_function,
+ *new_paint_artifact, paint_chunks, layer_state,
visual_rect_subpixel_offset, new_chunks_info);
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.h b/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.h
index 55229e99ca1..35b7fabef0c 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.h
@@ -27,10 +27,7 @@ class PLATFORM_EXPORT RasterInvalidator {
using RasterInvalidationFunction =
base::RepeatingCallback<void(const IntRect&)>;
- RasterInvalidator(RasterInvalidationFunction raster_invalidation_function)
- : raster_invalidation_function_(std::move(raster_invalidation_function)) {
- DCHECK(!raster_invalidation_function_.is_null());
- }
+ RasterInvalidator() = default;
void SetTracksRasterInvalidations(bool);
RasterInvalidationTracking* GetTracking() const {
@@ -41,7 +38,8 @@ class PLATFORM_EXPORT RasterInvalidator {
// Generate raster invalidations for all of the changed paint chunks and
// display items in the paint artifact.
- void Generate(scoped_refptr<const PaintArtifact>,
+ void Generate(RasterInvalidationFunction,
+ scoped_refptr<const PaintArtifact>,
const gfx::Rect& layer_bounds,
const PropertyTreeState& layer_state,
const FloatSize& visual_rect_subpixel_offset = FloatSize(),
@@ -49,7 +47,8 @@ class PLATFORM_EXPORT RasterInvalidator {
// Generate raster invalidations for a subset of the paint chunks in the
// paint artifact.
- void Generate(scoped_refptr<const PaintArtifact>,
+ void Generate(RasterInvalidationFunction,
+ scoped_refptr<const PaintArtifact>,
const PaintChunkSubset&,
const gfx::Rect& layer_bounds,
const PropertyTreeState& layer_state,
@@ -77,7 +76,7 @@ class PLATFORM_EXPORT RasterInvalidator {
id(chunk_it->id),
#endif
bounds_in_layer(invalidator.ClipByLayerBounds(
- mapper.MapVisualRect(chunk_it->bounds))),
+ mapper.MapVisualRect(chunk_it->drawable_bounds))),
chunk_to_layer_clip(mapper.ClipRect()),
chunk_to_layer_transform(mapper.Transform()) {
}
@@ -85,7 +84,7 @@ class PLATFORM_EXPORT RasterInvalidator {
// The index of the chunk in the PaintArtifact. It may be different from
// the index of this PaintChunkInfo in paint_chunks_info_ when a subset of
// the paint chunks is handled by the RasterInvalidator.
- size_t index_in_paint_artifact;
+ wtf_size_t index_in_paint_artifact;
#if DCHECK_IS_ON()
PaintChunk::Id id;
@@ -96,17 +95,19 @@ class PLATFORM_EXPORT RasterInvalidator {
SkMatrix chunk_to_layer_transform;
};
- void GenerateRasterInvalidations(const PaintArtifact&,
+ void GenerateRasterInvalidations(RasterInvalidationFunction,
+ const PaintArtifact&,
const PaintChunkSubset&,
const PropertyTreeState& layer_state,
const FloatSize& visual_rect_subpixel_offset,
Vector<PaintChunkInfo>& new_chunks_info);
- ALWAYS_INLINE const PaintChunk& GetOldChunk(size_t index) const;
- ALWAYS_INLINE size_t MatchNewChunkToOldChunk(const PaintChunk& new_chunk,
- size_t old_index) const;
+ ALWAYS_INLINE const PaintChunk& GetOldChunk(wtf_size_t index) const;
+ ALWAYS_INLINE wtf_size_t MatchNewChunkToOldChunk(const PaintChunk& new_chunk,
+ wtf_size_t old_index) const;
ALWAYS_INLINE void IncrementallyInvalidateChunk(
+ RasterInvalidationFunction,
const PaintChunkInfo& old_chunk_info,
const PaintChunkInfo& new_chunk_info,
const DisplayItemClient&);
@@ -115,13 +116,14 @@ class PLATFORM_EXPORT RasterInvalidator {
// get DebugName() directly or should get from |tracking_info_
// ->old_client_debug_names|.
enum ClientIsOldOrNew { kClientIsOld, kClientIsNew };
- void AddRasterInvalidation(const IntRect& rect,
+ void AddRasterInvalidation(RasterInvalidationFunction function,
+ const IntRect& rect,
const DisplayItemClient& client,
PaintInvalidationReason reason,
ClientIsOldOrNew old_or_new) {
if (rect.IsEmpty())
return;
- raster_invalidation_function_.Run(rect);
+ function.Run(rect);
if (tracking_info_)
TrackRasterInvalidation(rect, client, reason, old_or_new);
}
@@ -146,7 +148,6 @@ class PLATFORM_EXPORT RasterInvalidator {
void TrackImplicitFullLayerInvalidation(const DisplayItemClient&);
- RasterInvalidationFunction raster_invalidation_function_;
gfx::Rect layer_bounds_;
Vector<PaintChunkInfo> old_paint_chunks_info_;
scoped_refptr<const PaintArtifact> old_paint_artifact_;
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 f4ad986d71a..d4598f77c81 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
@@ -6,6 +6,7 @@
#include <utility>
#include "base/bind_helpers.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_artifact.h"
@@ -13,6 +14,8 @@
#include "third_party/blink/renderer/platform/testing/paint_test_configurations.h"
#include "third_party/blink/renderer/platform/testing/test_paint_artifact.h"
+using testing::ElementsAre;
+
namespace blink {
static const IntRect kDefaultLayerBounds(-9999, -7777, 18888, 16666);
@@ -20,7 +23,7 @@ static const IntRect kDefaultLayerBounds(-9999, -7777, 18888, 16666);
class RasterInvalidatorTest : public testing::Test,
public PaintTestConfigurations {
public:
- RasterInvalidatorTest() : invalidator_(base::DoNothing()) {}
+ RasterInvalidatorTest() = default;
static PropertyTreeState DefaultPropertyTreeState() {
return PropertyTreeState::Root();
@@ -47,58 +50,60 @@ class RasterInvalidatorTest : public testing::Test,
return invalidator_.GetTracking()->Invalidations();
}
- using MapFunction = base::RepeatingCallback<void(IntRect&)>;
- static IntRect ChunkRectToLayer(
- const IntRect& rect,
- const IntPoint& layer_offset,
- const MapFunction& mapper = base::DoNothing()) {
- auto r = rect;
- mapper.Run(r);
- r.MoveBy(layer_offset);
- return r;
- }
-
RasterInvalidator invalidator_;
};
INSTANTIATE_PAINT_TEST_SUITE_P(RasterInvalidatorTest);
-#define EXPECT_CHUNK_INVALIDATION_CUSTOM( \
- invalidations, index, chunk, expected_reason, layer_offset, mapper) \
- do { \
- const auto& info = (invalidations)[index]; \
- EXPECT_EQ(ChunkRectToLayer((chunk).bounds, layer_offset, mapper), \
- info.rect); \
- EXPECT_EQ(&(chunk).id.client, info.client); \
- EXPECT_EQ(expected_reason, info.reason); \
- } while (false)
-
-#define EXPECT_CHUNK_INVALIDATION(invalidations, index, chunk, reason) \
- EXPECT_CHUNK_INVALIDATION_CUSTOM(invalidations, index, chunk, reason, \
- -kDefaultLayerBounds.Location(), \
- base::DoNothing())
-
-#define EXPECT_INCREMENTAL_INVALIDATION(invalidations, index, chunk, \
- chunk_rect) \
- do { \
- const auto& info = (invalidations)[index]; \
- EXPECT_EQ(ChunkRectToLayer(chunk_rect, -kDefaultLayerBounds.Location()), \
- info.rect); \
- EXPECT_EQ(&(chunk).id.client, info.client); \
- EXPECT_EQ(PaintInvalidationReason::kIncremental, info.reason); \
- } while (false)
+using MapFunction = base::RepeatingCallback<void(IntRect&)>;
+static IntRect ChunkRectToLayer(const IntRect& rect,
+ const IntPoint& layer_offset,
+ const MapFunction& mapper = base::DoNothing()) {
+ auto r = rect;
+ mapper.Run(r);
+ r.MoveBy(layer_offset);
+ return r;
+}
+
+static bool CheckChunkInvalidation(
+ const RasterInvalidationInfo& info,
+ const PaintChunk& chunk,
+ const IntRect& chunk_rect,
+ PaintInvalidationReason reason,
+ const IntPoint& layer_offset,
+ const MapFunction& mapper = base::DoNothing()) {
+ return ChunkRectToLayer(chunk_rect, layer_offset, mapper) == info.rect &&
+ &chunk.id.client == info.client && reason == info.reason;
+}
+
+MATCHER_P4(ChunkInvalidation, chunk, reason, layer_offset, mapper, "") {
+ return CheckChunkInvalidation(arg, *chunk, chunk->drawable_bounds, reason,
+ layer_offset, mapper);
+}
+
+MATCHER_P2(ChunkInvalidation, chunk, reason, "") {
+ return CheckChunkInvalidation(arg, *chunk, chunk->drawable_bounds, reason,
+ -kDefaultLayerBounds.Location());
+}
+
+MATCHER_P2(IncrementalInvalidation, chunk, chunk_rect, "") {
+ return CheckChunkInvalidation(arg, *chunk, chunk_rect,
+ PaintInvalidationReason::kIncremental,
+ -kDefaultLayerBounds.Location());
+}
TEST_P(RasterInvalidatorTest, ImplicitFullLayerInvalidation) {
auto artifact = TestPaintArtifact().Chunk(0).Build();
invalidator_.SetTracksRasterInvalidations(true);
- invalidator_.Generate(artifact, kDefaultLayerBounds,
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
DefaultPropertyTreeState());
- const auto& invalidations = TrackedRasterInvalidations();
- ASSERT_EQ(1u, invalidations.size());
- EXPECT_EQ(IntRect(IntPoint(), kDefaultLayerBounds.Size()),
- invalidations[0].rect);
- EXPECT_EQ(PaintInvalidationReason::kFullLayer, invalidations[0].reason);
+ const auto& client = artifact->PaintChunks()[0].id.client;
+ EXPECT_THAT(TrackedRasterInvalidations(),
+ ElementsAre(RasterInvalidationInfo{
+ &client, client.DebugName(),
+ IntRect(IntPoint(), kDefaultLayerBounds.Size()),
+ PaintInvalidationReason::kFullLayer}));
FinishCycle(*artifact);
invalidator_.SetTracksRasterInvalidations(false);
}
@@ -106,34 +111,35 @@ TEST_P(RasterInvalidatorTest, ImplicitFullLayerInvalidation) {
TEST_P(RasterInvalidatorTest, LayerBounds) {
auto artifact = TestPaintArtifact().Chunk(0).Build();
- invalidator_.Generate(artifact, kDefaultLayerBounds,
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
DefaultPropertyTreeState());
FinishCycle(*artifact);
invalidator_.SetTracksRasterInvalidations(true);
- invalidator_.Generate(artifact, kDefaultLayerBounds,
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
DefaultPropertyTreeState());
// No raster invalidations needed if layer origin doesn't change.
EXPECT_TRUE(TrackedRasterInvalidations().IsEmpty());
auto new_layer_bounds = kDefaultLayerBounds;
new_layer_bounds.Move(66, 77);
- invalidator_.Generate(artifact, new_layer_bounds, DefaultPropertyTreeState());
+ invalidator_.Generate(base::DoNothing(), artifact, new_layer_bounds,
+ DefaultPropertyTreeState());
// Change of layer origin causes change of chunk0's transform to layer.
- const auto& invalidations = TrackedRasterInvalidations();
- ASSERT_EQ(2u, invalidations.size());
- EXPECT_CHUNK_INVALIDATION(invalidations, 0, artifact->PaintChunks()[0],
- PaintInvalidationReason::kPaintProperty);
- EXPECT_CHUNK_INVALIDATION_CUSTOM(invalidations, 1, artifact->PaintChunks()[0],
- PaintInvalidationReason::kPaintProperty,
- -new_layer_bounds.Location(),
- base::DoNothing());
+ EXPECT_THAT(
+ TrackedRasterInvalidations(),
+ ElementsAre(
+ ChunkInvalidation(&artifact->PaintChunks()[0],
+ PaintInvalidationReason::kPaintProperty),
+ ChunkInvalidation(&artifact->PaintChunks()[0],
+ PaintInvalidationReason::kPaintProperty,
+ -new_layer_bounds.Location(), base::DoNothing())));
FinishCycle(*artifact);
}
TEST_P(RasterInvalidatorTest, ReorderChunks) {
auto artifact = TestPaintArtifact().Chunk(0).Chunk(1).Chunk(2).Build();
- invalidator_.Generate(artifact, kDefaultLayerBounds,
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
DefaultPropertyTreeState());
FinishCycle(*artifact);
@@ -145,23 +151,23 @@ TEST_P(RasterInvalidatorTest, ReorderChunks) {
.Chunk(1)
.Bounds(IntRect(11, 22, 33, 44))
.Build();
- invalidator_.Generate(new_artifact, kDefaultLayerBounds,
+ invalidator_.Generate(base::DoNothing(), new_artifact, kDefaultLayerBounds,
DefaultPropertyTreeState());
- const auto& invalidations = TrackedRasterInvalidations();
- ASSERT_EQ(2u, invalidations.size());
// Invalidated new chunk 2's old (as artifact->PaintChunks()[1]) and new
// (as new_artifact->PaintChunks()[2]) bounds.
- EXPECT_CHUNK_INVALIDATION(invalidations, 0, artifact->PaintChunks()[1],
- PaintInvalidationReason::kChunkReordered);
- EXPECT_CHUNK_INVALIDATION(invalidations, 1, new_artifact->PaintChunks()[2],
- PaintInvalidationReason::kChunkReordered);
+ EXPECT_THAT(
+ TrackedRasterInvalidations(),
+ ElementsAre(ChunkInvalidation(&artifact->PaintChunks()[1],
+ PaintInvalidationReason::kChunkReordered),
+ ChunkInvalidation(&new_artifact->PaintChunks()[2],
+ PaintInvalidationReason::kChunkReordered)));
FinishCycle(*new_artifact);
}
TEST_P(RasterInvalidatorTest, ReorderChunkSubsequences) {
auto artifact =
TestPaintArtifact().Chunk(0).Chunk(1).Chunk(2).Chunk(3).Chunk(4).Build();
- invalidator_.Generate(artifact, kDefaultLayerBounds,
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
DefaultPropertyTreeState());
FinishCycle(*artifact);
@@ -175,63 +181,98 @@ TEST_P(RasterInvalidatorTest, ReorderChunkSubsequences) {
.Bounds(IntRect(11, 22, 33, 44))
.Chunk(2)
.Build();
- invalidator_.Generate(new_artifact, kDefaultLayerBounds,
+ invalidator_.Generate(base::DoNothing(), new_artifact, kDefaultLayerBounds,
DefaultPropertyTreeState());
- const auto& invalidations = TrackedRasterInvalidations();
- ASSERT_EQ(3u, invalidations.size());
// Invalidated new chunk 3's old (as artifact->PaintChunks()[1] and new
// (as new_artifact->PaintChunks()[3]) bounds.
- EXPECT_CHUNK_INVALIDATION(invalidations, 0, artifact->PaintChunks()[1],
- PaintInvalidationReason::kChunkReordered);
- EXPECT_CHUNK_INVALIDATION(invalidations, 1, new_artifact->PaintChunks()[3],
- PaintInvalidationReason::kChunkReordered);
// Invalidated new chunk 4's new bounds. Didn't invalidate old bounds because
// it's the same as the new bounds.
- EXPECT_CHUNK_INVALIDATION(invalidations, 2, new_artifact->PaintChunks()[4],
- PaintInvalidationReason::kChunkReordered);
+ EXPECT_THAT(
+ TrackedRasterInvalidations(),
+ ElementsAre(ChunkInvalidation(&artifact->PaintChunks()[1],
+ PaintInvalidationReason::kChunkReordered),
+ ChunkInvalidation(&new_artifact->PaintChunks()[3],
+ PaintInvalidationReason::kChunkReordered),
+ ChunkInvalidation(&new_artifact->PaintChunks()[4],
+ PaintInvalidationReason::kChunkReordered)));
FinishCycle(*new_artifact);
}
TEST_P(RasterInvalidatorTest, ChunkAppearAndDisappear) {
auto artifact = TestPaintArtifact().Chunk(0).Chunk(1).Chunk(2).Build();
- invalidator_.Generate(artifact, kDefaultLayerBounds,
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
DefaultPropertyTreeState());
FinishCycle(*artifact);
// Chunk 1 and 2 disappeared, 3 and 4 appeared.
invalidator_.SetTracksRasterInvalidations(true);
auto new_artifact = TestPaintArtifact().Chunk(0).Chunk(3).Chunk(4).Build();
- invalidator_.Generate(new_artifact, kDefaultLayerBounds,
+ invalidator_.Generate(base::DoNothing(), new_artifact, kDefaultLayerBounds,
+ DefaultPropertyTreeState());
+ EXPECT_THAT(
+ TrackedRasterInvalidations(),
+ ElementsAre(
+ ChunkInvalidation(&new_artifact->PaintChunks()[1],
+ PaintInvalidationReason::kChunkAppeared),
+ ChunkInvalidation(&new_artifact->PaintChunks()[2],
+ PaintInvalidationReason::kChunkAppeared),
+ ChunkInvalidation(&artifact->PaintChunks()[1],
+ PaintInvalidationReason::kChunkDisappeared),
+ ChunkInvalidation(&artifact->PaintChunks()[2],
+ PaintInvalidationReason::kChunkDisappeared)));
+ FinishCycle(*new_artifact);
+}
+
+TEST_P(RasterInvalidatorTest, InvalidateDrawableBounds) {
+ IntRect drawable_bounds(11, 22, 33, 44);
+ IntRect bounds(0, 0, 100, 100);
+ auto artifact = TestPaintArtifact()
+ .Chunk(0)
+ .Chunk(1)
+ .Bounds(bounds)
+ .DrawableBounds(drawable_bounds)
+ .Build();
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ DefaultPropertyTreeState());
+ FinishCycle(*artifact);
+
+ invalidator_.SetTracksRasterInvalidations(true);
+ auto new_artifact = TestPaintArtifact()
+ .Chunk(0)
+ .Chunk(2)
+ .Bounds(bounds)
+ .DrawableBounds(drawable_bounds)
+ .Build();
+ invalidator_.Generate(base::DoNothing(), new_artifact, kDefaultLayerBounds,
DefaultPropertyTreeState());
- const auto& invalidations = TrackedRasterInvalidations();
- ASSERT_EQ(4u, invalidations.size());
- EXPECT_CHUNK_INVALIDATION(invalidations, 0, new_artifact->PaintChunks()[1],
- PaintInvalidationReason::kChunkAppeared);
- EXPECT_CHUNK_INVALIDATION(invalidations, 1, new_artifact->PaintChunks()[2],
- PaintInvalidationReason::kChunkAppeared);
- EXPECT_CHUNK_INVALIDATION(invalidations, 2, artifact->PaintChunks()[1],
- PaintInvalidationReason::kChunkDisappeared);
- EXPECT_CHUNK_INVALIDATION(invalidations, 3, artifact->PaintChunks()[2],
- PaintInvalidationReason::kChunkDisappeared);
+ // ChunkInvalidation uses the drawable_bounds. We expect raster invalidations
+ // based on drawable_bounds instead of bounds.
+ EXPECT_THAT(
+ TrackedRasterInvalidations(),
+ ElementsAre(
+ ChunkInvalidation(&new_artifact->PaintChunks()[1],
+ PaintInvalidationReason::kChunkAppeared),
+ ChunkInvalidation(&artifact->PaintChunks()[1],
+ PaintInvalidationReason::kChunkDisappeared)));
FinishCycle(*new_artifact);
}
TEST_P(RasterInvalidatorTest, ChunkAppearAtEnd) {
auto artifact = TestPaintArtifact().Chunk(0).Build();
- invalidator_.Generate(artifact, kDefaultLayerBounds,
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
DefaultPropertyTreeState());
FinishCycle(*artifact);
invalidator_.SetTracksRasterInvalidations(true);
auto new_artifact = TestPaintArtifact().Chunk(0).Chunk(1).Chunk(2).Build();
- invalidator_.Generate(new_artifact, kDefaultLayerBounds,
+ invalidator_.Generate(base::DoNothing(), new_artifact, kDefaultLayerBounds,
DefaultPropertyTreeState());
- const auto& invalidations = TrackedRasterInvalidations();
- ASSERT_EQ(2u, invalidations.size());
- EXPECT_CHUNK_INVALIDATION(invalidations, 0, new_artifact->PaintChunks()[1],
- PaintInvalidationReason::kChunkAppeared);
- EXPECT_CHUNK_INVALIDATION(invalidations, 1, new_artifact->PaintChunks()[2],
- PaintInvalidationReason::kChunkAppeared);
+ EXPECT_THAT(
+ TrackedRasterInvalidations(),
+ ElementsAre(ChunkInvalidation(&new_artifact->PaintChunks()[1],
+ PaintInvalidationReason::kChunkAppeared),
+ ChunkInvalidation(&new_artifact->PaintChunks()[2],
+ PaintInvalidationReason::kChunkAppeared)));
FinishCycle(*new_artifact);
}
@@ -239,21 +280,22 @@ TEST_P(RasterInvalidatorTest, UncacheableChunks) {
auto artifact =
TestPaintArtifact().Chunk(0).Chunk(1).Uncacheable().Chunk(2).Build();
- invalidator_.Generate(artifact, kDefaultLayerBounds,
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
DefaultPropertyTreeState());
FinishCycle(*artifact);
invalidator_.SetTracksRasterInvalidations(true);
auto new_artifact =
TestPaintArtifact().Chunk(0).Chunk(2).Chunk(1).Uncacheable().Build();
- invalidator_.Generate(new_artifact, kDefaultLayerBounds,
+ invalidator_.Generate(base::DoNothing(), new_artifact, kDefaultLayerBounds,
DefaultPropertyTreeState());
- const auto& invalidations = TrackedRasterInvalidations();
- ASSERT_EQ(2u, invalidations.size());
- EXPECT_CHUNK_INVALIDATION(invalidations, 0, new_artifact->PaintChunks()[2],
- PaintInvalidationReason::kChunkUncacheable);
- EXPECT_CHUNK_INVALIDATION(invalidations, 1, artifact->PaintChunks()[1],
- PaintInvalidationReason::kChunkUncacheable);
+ EXPECT_THAT(
+ TrackedRasterInvalidations(),
+ ElementsAre(
+ ChunkInvalidation(&new_artifact->PaintChunks()[2],
+ PaintInvalidationReason::kChunkUncacheable),
+ ChunkInvalidation(&artifact->PaintChunks()[1],
+ PaintInvalidationReason::kChunkUncacheable)));
FinishCycle(*new_artifact);
}
@@ -275,7 +317,8 @@ TEST_P(RasterInvalidatorTest, ClipPropertyChangeRounded) {
.Properties(t0(), *clip2, e0())
.Build();
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
FinishCycle(*artifact);
// Change both clip0 and clip2.
@@ -288,13 +331,14 @@ TEST_P(RasterInvalidatorTest, ClipPropertyChangeRounded) {
ClipPaintPropertyNode::State{&clip2->LocalTransformSpace(),
new_clip_rect});
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
- const auto& invalidations = TrackedRasterInvalidations();
- ASSERT_EQ(1u, invalidations.size());
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
// Property change in the layer state should not trigger raster invalidation.
// |clip2| change should trigger raster invalidation.
- EXPECT_CHUNK_INVALIDATION(invalidations, 0, artifact->PaintChunks()[2],
- PaintInvalidationReason::kPaintProperty);
+ EXPECT_THAT(
+ TrackedRasterInvalidations(),
+ ElementsAre(ChunkInvalidation(&artifact->PaintChunks()[2],
+ PaintInvalidationReason::kPaintProperty)));
invalidator_.SetTracksRasterInvalidations(false);
FinishCycle(*artifact);
@@ -309,11 +353,12 @@ TEST_P(RasterInvalidatorTest, ClipPropertyChangeRounded) {
.Build();
invalidator_.SetTracksRasterInvalidations(true);
- invalidator_.Generate(new_artifact1, kDefaultLayerBounds, layer_state);
- const auto& invalidations1 = TrackedRasterInvalidations();
- ASSERT_EQ(1u, invalidations1.size());
- EXPECT_CHUNK_INVALIDATION(invalidations1, 0, new_artifact1->PaintChunks()[1],
- PaintInvalidationReason::kPaintProperty);
+ invalidator_.Generate(base::DoNothing(), new_artifact1, kDefaultLayerBounds,
+ layer_state);
+ EXPECT_THAT(
+ TrackedRasterInvalidations(),
+ ElementsAre(ChunkInvalidation(&new_artifact1->PaintChunks()[1],
+ PaintInvalidationReason::kPaintProperty)));
invalidator_.SetTracksRasterInvalidations(false);
FinishCycle(*new_artifact1);
}
@@ -334,7 +379,8 @@ TEST_P(RasterInvalidatorTest, ClipPropertyChangeSimple) {
.Bounds(EnclosingIntRect(clip_rect.Rect()))
.Build();
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
FinishCycle(*artifact);
// Change clip1 to bigger, which is still bound by clip0, resulting no actual
@@ -345,7 +391,8 @@ TEST_P(RasterInvalidatorTest, ClipPropertyChangeSimple) {
ClipPaintPropertyNode::State{&clip1->LocalTransformSpace(),
new_clip_rect1});
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
EXPECT_TRUE(TrackedRasterInvalidations().IsEmpty());
FinishCycle(*artifact);
@@ -355,18 +402,19 @@ TEST_P(RasterInvalidatorTest, ClipPropertyChangeSimple) {
ClipPaintPropertyNode::State{&clip1->LocalTransformSpace(),
new_clip_rect2});
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
- const auto& invalidations = TrackedRasterInvalidations();
- ASSERT_EQ(4u, invalidations.size());
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
// |clip1| change should trigger incremental raster invalidation.
- EXPECT_INCREMENTAL_INVALIDATION(invalidations, 0, artifact->PaintChunks()[1],
- IntRect(-1000, -1000, 2000, 500));
- EXPECT_INCREMENTAL_INVALIDATION(invalidations, 1, artifact->PaintChunks()[1],
- IntRect(-1000, -500, 500, 1000));
- EXPECT_INCREMENTAL_INVALIDATION(invalidations, 2, artifact->PaintChunks()[1],
- IntRect(500, -500, 500, 1000));
- EXPECT_INCREMENTAL_INVALIDATION(invalidations, 3, artifact->PaintChunks()[1],
- IntRect(-1000, 500, 2000, 500));
+ EXPECT_THAT(
+ TrackedRasterInvalidations(),
+ ElementsAre(IncrementalInvalidation(&artifact->PaintChunks()[1],
+ IntRect(-1000, -1000, 2000, 500)),
+ IncrementalInvalidation(&artifact->PaintChunks()[1],
+ IntRect(-1000, -500, 500, 1000)),
+ IncrementalInvalidation(&artifact->PaintChunks()[1],
+ IntRect(500, -500, 500, 1000)),
+ IncrementalInvalidation(&artifact->PaintChunks()[1],
+ IntRect(-1000, 500, 2000, 500))));
invalidator_.SetTracksRasterInvalidations(false);
FinishCycle(*artifact);
@@ -377,12 +425,12 @@ TEST_P(RasterInvalidatorTest, ClipPropertyChangeSimple) {
new_clip_rect3});
invalidator_.SetTracksRasterInvalidations(true);
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
- const auto& invalidations1 = TrackedRasterInvalidations();
- ASSERT_EQ(1u, invalidations1.size());
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
// |clip1| change should trigger incremental raster invalidation.
- EXPECT_INCREMENTAL_INVALIDATION(invalidations1, 0, artifact->PaintChunks()[1],
- IntRect(500, -500, 500, 1000));
+ EXPECT_THAT(TrackedRasterInvalidations(),
+ ElementsAre(IncrementalInvalidation(
+ &artifact->PaintChunks()[1], IntRect(500, -500, 500, 1000))));
invalidator_.SetTracksRasterInvalidations(false);
FinishCycle(*artifact);
}
@@ -402,21 +450,22 @@ TEST_P(RasterInvalidatorTest, ClipPropertyChangeWithOutsetForRasterEffects) {
.OutsetForRasterEffects(2)
.Build();
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
FinishCycle(*artifact);
invalidator_.SetTracksRasterInvalidations(true);
FloatRoundedRect new_clip_rect(-2000, -2000, 4000, 4000);
clip->Update(c0(), ClipPaintPropertyNode::State{&t0(), new_clip_rect});
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
- const auto& invalidations = TrackedRasterInvalidations();
- ASSERT_EQ(1u, invalidations.size());
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
auto mapper = [](IntRect& r) { r.Inflate(2); };
- EXPECT_CHUNK_INVALIDATION_CUSTOM(invalidations, 0, artifact->PaintChunks()[0],
- PaintInvalidationReason::kPaintProperty,
- -kDefaultLayerBounds.Location(),
- base::BindRepeating(mapper));
+ EXPECT_THAT(
+ TrackedRasterInvalidations(),
+ ElementsAre(ChunkInvalidation(
+ &artifact->PaintChunks()[0], PaintInvalidationReason::kPaintProperty,
+ -kDefaultLayerBounds.Location(), base::BindRepeating(mapper))));
invalidator_.SetTracksRasterInvalidations(false);
FinishCycle(*artifact);
}
@@ -434,7 +483,8 @@ TEST_P(RasterInvalidatorTest, ClipLocalTransformSpaceChange) {
auto artifact =
TestPaintArtifact().Chunk(0).Properties(*t2, *c1, e0()).Build();
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
FinishCycle(*artifact);
// Change both t1 and t2 but keep t1*t2 unchanged, to test change of
@@ -443,11 +493,12 @@ TEST_P(RasterInvalidatorTest, ClipLocalTransformSpaceChange) {
t1->Update(t0(), TransformPaintPropertyNode::State{FloatSize(-10, -20)});
t2->Update(*t1, TransformPaintPropertyNode::State{FloatSize(10, 20)});
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
- const auto& invalidations = TrackedRasterInvalidations();
- ASSERT_EQ(1u, invalidations.size());
- EXPECT_CHUNK_INVALIDATION(invalidations, 0, artifact->PaintChunks()[0],
- PaintInvalidationReason::kPaintProperty);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
+ EXPECT_THAT(
+ TrackedRasterInvalidations(),
+ ElementsAre(ChunkInvalidation(&artifact->PaintChunks()[0],
+ PaintInvalidationReason::kPaintProperty)));
invalidator_.SetTracksRasterInvalidations(false);
}
@@ -468,7 +519,8 @@ TEST_P(RasterInvalidatorTest, ClipLocalTransformSpaceChangeNoInvalidation) {
auto artifact =
TestPaintArtifact().Chunk(0).Properties(*t2, *c1, e0()).Build();
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
FinishCycle(*artifact);
// Change both t1 and t2 but keep t1*t2 unchanged.
@@ -476,7 +528,8 @@ TEST_P(RasterInvalidatorTest, ClipLocalTransformSpaceChangeNoInvalidation) {
t1->Update(t0(), TransformPaintPropertyNode::State{FloatSize(-10, -20)});
t2->Update(*t1, TransformPaintPropertyNode::State{FloatSize(10, 20)});
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
EXPECT_TRUE(TrackedRasterInvalidations().IsEmpty());
FinishCycle(*artifact);
}
@@ -494,7 +547,8 @@ TEST_P(RasterInvalidatorTest, TransformPropertyChange) {
.Properties(*transform1, c0(), e0())
.Build();
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
FinishCycle(*artifact);
// Change layer_transform should not cause raster invalidation in the layer.
@@ -503,7 +557,8 @@ TEST_P(RasterInvalidatorTest, TransformPropertyChange) {
*layer_transform->Parent(),
TransformPaintPropertyNode::State{TransformationMatrix().Scale(10)});
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
EXPECT_TRUE(TrackedRasterInvalidations().IsEmpty());
FinishCycle(*artifact);
@@ -516,7 +571,8 @@ TEST_P(RasterInvalidatorTest, TransformPropertyChange) {
transform0->Update(*new_layer_transform, TransformPaintPropertyNode::State{
transform0->Translation2D()});
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
EXPECT_TRUE(TrackedRasterInvalidations().IsEmpty());
FinishCycle(*artifact);
@@ -526,7 +582,8 @@ TEST_P(RasterInvalidatorTest, TransformPropertyChange) {
transform0->Update(layer_state.Transform(), TransformPaintPropertyNode::State{
transform0->Translation2D()});
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
EXPECT_TRUE(TrackedRasterInvalidations().IsEmpty());
FinishCycle(*artifact);
@@ -540,19 +597,20 @@ TEST_P(RasterInvalidatorTest, TransformPropertyChange) {
TransformPaintPropertyNode::State{
transform1->Translation2D() + FloatSize(-20, -30)});
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
- const auto& invalidations = TrackedRasterInvalidations();
- ASSERT_EQ(2u, invalidations.size());
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
auto mapper0 = [](IntRect& r) { r.Move(10, 20); };
- EXPECT_CHUNK_INVALIDATION_CUSTOM(invalidations, 0, artifact->PaintChunks()[0],
- PaintInvalidationReason::kPaintProperty,
- -kDefaultLayerBounds.Location(),
- base::BindRepeating(mapper0));
auto mapper1 = [](IntRect& r) { r.Move(30, 50); };
- EXPECT_CHUNK_INVALIDATION_CUSTOM(invalidations, 1, artifact->PaintChunks()[0],
- PaintInvalidationReason::kPaintProperty,
- -kDefaultLayerBounds.Location(),
- base::BindRepeating(mapper1));
+ EXPECT_THAT(
+ TrackedRasterInvalidations(),
+ ElementsAre(ChunkInvalidation(&artifact->PaintChunks()[0],
+ PaintInvalidationReason::kPaintProperty,
+ -kDefaultLayerBounds.Location(),
+ base::BindRepeating(mapper0)),
+ ChunkInvalidation(&artifact->PaintChunks()[0],
+ PaintInvalidationReason::kPaintProperty,
+ -kDefaultLayerBounds.Location(),
+ base::BindRepeating(mapper1))));
invalidator_.SetTracksRasterInvalidations(false);
FinishCycle(*artifact);
}
@@ -567,7 +625,8 @@ TEST_P(RasterInvalidatorTest, TransformPropertyTinyChange) {
.Properties(*chunk_transform, c0(), e0())
.Build();
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
FinishCycle(*artifact);
// Change chunk_transform by tiny difference, which should be ignored.
@@ -579,7 +638,8 @@ TEST_P(RasterInvalidatorTest, TransformPropertyTinyChange) {
.Scale(1.0000001)
.Rotate(0.0000001)});
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
EXPECT_TRUE(TrackedRasterInvalidations().IsEmpty());
FinishCycle(*artifact);
@@ -593,7 +653,8 @@ TEST_P(RasterInvalidatorTest, TransformPropertyTinyChange) {
.Translate(0.0000001, -0.0000001)
.Scale(1.0000001)
.Rotate(0.0000001)});
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
invalidated = !TrackedRasterInvalidations().IsEmpty();
FinishCycle(*artifact);
}
@@ -613,7 +674,8 @@ TEST_P(RasterInvalidatorTest, TransformPropertyTinyChangeScale) {
.Bounds(chunk_bounds)
.Build();
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
FinishCycle(*artifact);
// Scale change from 1e-6 to 2e-6 should be treated as significant.
@@ -622,7 +684,8 @@ TEST_P(RasterInvalidatorTest, TransformPropertyTinyChangeScale) {
layer_state.Transform(),
TransformPaintPropertyNode::State{TransformationMatrix().Scale(2e-6)});
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
EXPECT_FALSE(TrackedRasterInvalidations().IsEmpty());
invalidator_.SetTracksRasterInvalidations(false);
FinishCycle(*artifact);
@@ -633,7 +696,8 @@ TEST_P(RasterInvalidatorTest, TransformPropertyTinyChangeScale) {
TransformPaintPropertyNode::State{
TransformationMatrix().Scale(2e-6 + 1e-15)});
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
EXPECT_TRUE(TrackedRasterInvalidations().IsEmpty());
invalidator_.SetTracksRasterInvalidations(false);
FinishCycle(*artifact);
@@ -650,7 +714,8 @@ TEST_P(RasterInvalidatorTest, EffectLocalTransformSpaceChange) {
auto artifact =
TestPaintArtifact().Chunk(0).Properties(*t2, c0(), *e1).Build();
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
FinishCycle(*artifact);
// Change both t1 and t2 but keep t1*t2 unchanged, to test change of
@@ -659,14 +724,14 @@ TEST_P(RasterInvalidatorTest, EffectLocalTransformSpaceChange) {
t1->Update(t0(), TransformPaintPropertyNode::State{FloatSize(-10, -20)});
t2->Update(*t1, TransformPaintPropertyNode::State{FloatSize(10, 20)});
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
- const auto& invalidations = TrackedRasterInvalidations();
- ASSERT_EQ(1u, invalidations.size());
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
auto mapper = [](IntRect& r) { r.Inflate(60); };
- EXPECT_CHUNK_INVALIDATION_CUSTOM(invalidations, 0, artifact->PaintChunks()[0],
- PaintInvalidationReason::kPaintProperty,
- -kDefaultLayerBounds.Location(),
- base::BindRepeating(mapper));
+ EXPECT_THAT(
+ TrackedRasterInvalidations(),
+ ElementsAre(ChunkInvalidation(
+ &artifact->PaintChunks()[0], PaintInvalidationReason::kPaintProperty,
+ -kDefaultLayerBounds.Location(), base::BindRepeating(mapper))));
invalidator_.SetTracksRasterInvalidations(false);
FinishCycle(*artifact);
}
@@ -686,7 +751,8 @@ TEST_P(RasterInvalidatorTest, EffectLocalTransformSpaceChangeNoInvalidation) {
auto artifact =
TestPaintArtifact().Chunk(0).Properties(*t2, c0(), *e1).Build();
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
FinishCycle(*artifact);
// Change both t1 and t2 but keep t1*t2 unchanged.
@@ -694,7 +760,8 @@ TEST_P(RasterInvalidatorTest, EffectLocalTransformSpaceChangeNoInvalidation) {
t1->Update(t0(), TransformPaintPropertyNode::State{FloatSize(-10, -20)});
t2->Update(*t1, TransformPaintPropertyNode::State{FloatSize(10, 20)});
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
EXPECT_TRUE(TrackedRasterInvalidations().IsEmpty());
FinishCycle(*artifact);
}
@@ -711,7 +778,8 @@ TEST_P(RasterInvalidatorTest, AliasEffectParentChanges) {
PropertyTreeState chunk_state(t0(), c0(), *alias_effect);
auto artifact = TestPaintArtifact().Chunk(0).Properties(chunk_state).Build();
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
FinishCycle(*artifact);
invalidator_.SetTracksRasterInvalidations(true);
@@ -721,11 +789,12 @@ TEST_P(RasterInvalidatorTest, AliasEffectParentChanges) {
// We expect to get invalidations since the effect unaliased effect is
// actually different now.
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
- const auto& invalidations = TrackedRasterInvalidations();
- ASSERT_EQ(1u, invalidations.size());
- EXPECT_CHUNK_INVALIDATION(invalidations, 0, artifact->PaintChunks()[0],
- PaintInvalidationReason::kPaintProperty);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
+ EXPECT_THAT(
+ TrackedRasterInvalidations(),
+ ElementsAre(ChunkInvalidation(&artifact->PaintChunks()[0],
+ PaintInvalidationReason::kPaintProperty)));
FinishCycle(*artifact);
}
@@ -742,7 +811,8 @@ TEST_P(RasterInvalidatorTest, NestedAliasEffectParentChanges) {
PropertyTreeState chunk_state(t0(), c0(), *alias_effect_2);
auto artifact = TestPaintArtifact().Chunk(0).Properties(chunk_state).Build();
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
FinishCycle(*artifact);
invalidator_.SetTracksRasterInvalidations(true);
@@ -753,11 +823,12 @@ TEST_P(RasterInvalidatorTest, NestedAliasEffectParentChanges) {
// We expect to get invalidations since the effect unaliased effect is
// actually different now.
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
- const auto& invalidations = TrackedRasterInvalidations();
- ASSERT_EQ(1u, invalidations.size());
- EXPECT_CHUNK_INVALIDATION(invalidations, 0, artifact->PaintChunks()[0],
- PaintInvalidationReason::kPaintProperty);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
+ EXPECT_THAT(
+ TrackedRasterInvalidations(),
+ ElementsAre(ChunkInvalidation(&artifact->PaintChunks()[0],
+ PaintInvalidationReason::kPaintProperty)));
FinishCycle(*artifact);
}
@@ -775,7 +846,8 @@ TEST_P(RasterInvalidatorTest, EffectWithAliasTransformWhoseParentChanges) {
PropertyTreeState chunk_state(t0(), c0(), *e1);
auto artifact = TestPaintArtifact().Chunk(0).Properties(chunk_state).Build();
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
FinishCycle(*artifact);
invalidator_.SetTracksRasterInvalidations(true);
@@ -785,11 +857,12 @@ TEST_P(RasterInvalidatorTest, EffectWithAliasTransformWhoseParentChanges) {
// We expect to get invalidations since the effect unaliased effect is
// actually different now.
- invalidator_.Generate(artifact, kDefaultLayerBounds, layer_state);
- const auto& invalidations = TrackedRasterInvalidations();
- ASSERT_EQ(1u, invalidations.size());
- EXPECT_CHUNK_INVALIDATION(invalidations, 0, artifact->PaintChunks()[0],
- PaintInvalidationReason::kPaintProperty);
+ invalidator_.Generate(base::DoNothing(), artifact, kDefaultLayerBounds,
+ layer_state);
+ EXPECT_THAT(
+ TrackedRasterInvalidations(),
+ ElementsAre(ChunkInvalidation(&artifact->PaintChunks()[0],
+ PaintInvalidationReason::kPaintProperty)));
FinishCycle(*artifact);
}
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 334ca46377b..23ff52e3096 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
@@ -13,7 +13,7 @@
namespace blink {
class ScopedDisplayItemFragment final {
- DISALLOW_NEW();
+ STACK_ALLOCATED();
public:
ScopedDisplayItemFragment(GraphicsContext& context, unsigned fragment)
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_hint.h b/chromium/third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_hint.h
new file mode 100644
index 00000000000..5d4e7190e26
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_hint.h
@@ -0,0 +1,74 @@
+// 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_PAINT_SCOPED_PAINT_CHUNK_HINT_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_SCOPED_PAINT_CHUNK_HINT_H_
+
+#include "third_party/blink/renderer/platform/graphics/paint/display_item.h"
+#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
+#include "third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_properties.h"
+
+namespace blink {
+
+// Hints for new paint chunks for a scope during paint. Will create new paint
+// chunks if we create any display items in the paint scope and
+// - paint chunk properties are different from the current chunk, or
+// - If the client's visual rect isn't fully contained by the current chunk's
+// bounds. This is a heuristic to create only paint chunks that are meaningful
+// to CompositeAfterPaint layerization, i.e. avoid unnecessary forced paint
+// chunks that will definitely be merged into the previous paint chunk.
+// Hinted paint chunks are never required for correctness and rendering should
+// be the same without this class. These hints are for performance: by causing
+// additional paint chunks (while avoiding some unnecessary ones) with explicit
+// ids, we can improve raster invalidation and layerization.
+class ScopedPaintChunkHint {
+ STACK_ALLOCATED();
+
+ public:
+ ScopedPaintChunkHint(PaintController& paint_controller,
+ const DisplayItemClient& client,
+ DisplayItem::Type type)
+ : ScopedPaintChunkHint(paint_controller,
+ paint_controller.CurrentPaintChunkProperties(),
+ client,
+ type) {}
+
+ ScopedPaintChunkHint(PaintController& paint_controller,
+ const PropertyTreeState& properties,
+ const DisplayItemClient& client,
+ DisplayItem::Type type)
+ : paint_controller_(paint_controller),
+ previous_num_chunks_(paint_controller_.NumNewChunks()),
+ previous_force_new_chunk_(paint_controller_.WillForceNewChunk()) {
+ if (!previous_force_new_chunk_ && previous_num_chunks_ &&
+ !paint_controller_.LastChunkBounds().Contains(client.VisualRect()))
+ paint_controller_.SetForceNewChunk(true);
+ // This is after SetForceNewChunk(true) so that the possible new chunk will
+ // use the specified id.
+ paint_chunk_properties_.emplace(paint_controller, properties, client, type);
+ }
+
+ ~ScopedPaintChunkHint() {
+ paint_chunk_properties_ = base::nullopt;
+ if (!HasCreatedPaintChunk())
+ paint_controller_.SetForceNewChunk(previous_force_new_chunk_);
+ }
+
+ bool HasCreatedPaintChunk() const {
+ DCHECK_GE(paint_controller_.NumNewChunks(), previous_num_chunks_);
+ return paint_controller_.NumNewChunks() > previous_num_chunks_;
+ }
+
+ private:
+ PaintController& paint_controller_;
+ // This is actually always emplaced, but is wrapped in base::Optional<> to
+ // control its lifetime related to SetForceNewChunk().
+ base::Optional<ScopedPaintChunkProperties> paint_chunk_properties_;
+ wtf_size_t previous_num_chunks_;
+ bool previous_force_new_chunk_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_SCOPED_PAINT_CHUNK_HINT_H_
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_properties.h b/chromium/third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_properties.h
index 0b0b87f5456..4df836d70c6 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_properties.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_properties.h
@@ -6,7 +6,6 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_SCOPED_PAINT_CHUNK_PROPERTIES_H_
#include "base/macros.h"
-#include "base/optional.h"
#include "third_party/blink/renderer/platform/graphics/paint/display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_chunk.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
@@ -16,7 +15,7 @@
namespace blink {
class ScopedPaintChunkProperties {
- DISALLOW_NEW();
+ STACK_ALLOCATED();
public:
// Use new PropertyTreeState for the scope.
@@ -26,8 +25,8 @@ class ScopedPaintChunkProperties {
DisplayItem::Type type)
: paint_controller_(paint_controller),
previous_properties_(paint_controller.CurrentPaintChunkProperties()) {
- paint_controller_.UpdateCurrentPaintChunkProperties(
- PaintChunk::Id(client, type), properties);
+ PaintChunk::Id id(client, type);
+ paint_controller_.UpdateCurrentPaintChunkProperties(&id, properties);
}
// Use new transform state, and keep the current other properties.
@@ -69,7 +68,7 @@ class ScopedPaintChunkProperties {
// ScopedPaintChunkProperties. The painter should create another scope of
// paint properties with new id, or the new chunk will use the id of the
// first display item as its id.
- paint_controller_.UpdateCurrentPaintChunkProperties(base::nullopt,
+ paint_controller_.UpdateCurrentPaintChunkProperties(nullptr,
previous_properties_);
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.cc
deleted file mode 100644
index 3c8cd82d14a..00000000000
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.cc
+++ /dev/null
@@ -1,80 +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/graphics/paint/scroll_hit_test_display_item.h"
-
-#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
-#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
-#include "third_party/blink/renderer/platform/wtf/assertions.h"
-
-namespace blink {
-
-ScrollHitTestDisplayItem::ScrollHitTestDisplayItem(
- const DisplayItemClient& client,
- DisplayItem::Type type,
- const TransformPaintPropertyNode* scroll_offset_node,
- const IntRect& scroll_container_bounds)
- : DisplayItem(client, type, sizeof(*this)),
- scroll_offset_node_(scroll_offset_node),
- scroll_container_bounds_(scroll_container_bounds) {
-#if DCHECK_IS_ON()
- if (type == DisplayItem::Type::kResizerScrollHitTest ||
- type == DisplayItem::Type::kPluginScrollHitTest) {
- // Resizer and plugin scroll hit tests are only used to prevent composited
- // scrolling and should not have a scroll offset node.
- DCHECK(!scroll_offset_node);
- } else if (type == DisplayItem::Type::kScrollHitTest) {
- DCHECK(scroll_offset_node);
- // The scroll offset transform node should have an associated scroll node.
- DCHECK(scroll_offset_node_->ScrollNode());
- } else {
- NOTREACHED();
- }
-#endif
-}
-
-ScrollHitTestDisplayItem::~ScrollHitTestDisplayItem() = default;
-
-bool ScrollHitTestDisplayItem::Equals(const DisplayItem& other) const {
- return DisplayItem::Equals(other) &&
- scroll_offset_node() ==
- static_cast<const ScrollHitTestDisplayItem&>(other)
- .scroll_offset_node() &&
- scroll_container_bounds() ==
- static_cast<const ScrollHitTestDisplayItem&>(other)
- .scroll_container_bounds();
-}
-
-#if DCHECK_IS_ON()
-void ScrollHitTestDisplayItem::PropertiesAsJSON(JSONObject& json) const {
- DisplayItem::PropertiesAsJSON(json);
- json.SetString("scrollOffsetNode", String::Format("%p", scroll_offset_node_));
- json.SetString("scrollContainerBounds", scroll_container_bounds_.ToString());
-}
-#endif
-
-void ScrollHitTestDisplayItem::Record(
- GraphicsContext& context,
- const DisplayItemClient& client,
- DisplayItem::Type type,
- const TransformPaintPropertyNode* scroll_offset_node,
- const IntRect& scroll_container_bounds) {
- PaintController& paint_controller = context.GetPaintController();
-
- // The scroll hit test should be in the non-scrolled transform space and
- // therefore should not be scrolled by the associated scroll offset.
- DCHECK_NE(&paint_controller.CurrentPaintChunkProperties().Transform(),
- scroll_offset_node);
-
- if (paint_controller.DisplayItemConstructionIsDisabled())
- return;
-
- if (paint_controller.UseCachedItemIfPossible(client, type))
- return;
-
- paint_controller.CreateAndAppend<ScrollHitTestDisplayItem>(
- client, type, scroll_offset_node, scroll_container_bounds);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h b/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h
deleted file mode 100644
index b2bfbe00b4d..00000000000
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h
+++ /dev/null
@@ -1,88 +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_PLATFORM_GRAPHICS_PAINT_SCROLL_HIT_TEST_DISPLAY_ITEM_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_SCROLL_HIT_TEST_DISPLAY_ITEM_H_
-
-#include "base/memory/ref_counted.h"
-#include "third_party/blink/renderer/platform/graphics/paint/display_item.h"
-#include "third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-
-namespace blink {
-
-class GraphicsContext;
-
-// Display item for marking a region as scrollable. This should be emitted in
-// the non-scrolling paint property tree state (in other words, this item should
-// not scroll). A display item is needed because hit testing is in paint order.
-//
-// This serves three purposes:
-// 1. Creating non-fast scrollable regions for non-composited scrollers.
-// Scrollable areas create a non-fast scrollable region in the
-// non-scrolling paint property tree state. Pre-CompositeAfterPaint, we skip
-// painting these for composited scrollers. With CompositeAfterPaint, we
-// paint the non-fast item and later ignore it if the scroller was composited
-// (see: PaintArtifactCompositor::UpdateNonFastScrollableRegions).
-//
-// 2. Creating non-fast scrollable regions for plugins and resize handles.
-// Plugins that have blocking event handlers and resize handles both need to
-// prevent composited scrolling. A different display item type is used
-// (kPluginScrollHitTest and kResizerScrollHitTest) to disambiguate multiple
-// scroll hit test display items (e.g., if a scroller is non-composited and
-// has a resizer).
-//
-// 3. Creating cc::Layers marked as being scrollable.
-// (when CompositeAfterPaint is enabled).
-// A single cc::Layer must be marked as being "scrollable", and this display
-// item is used by PaintArtifactCompositor to create the scrollable cc::Layer.
-class PLATFORM_EXPORT ScrollHitTestDisplayItem final : public DisplayItem {
- public:
- ScrollHitTestDisplayItem(const DisplayItemClient&,
- DisplayItem::Type,
- const TransformPaintPropertyNode* scroll_offset_node,
- const IntRect& scroll_container_bounds);
- ~ScrollHitTestDisplayItem() override;
-
- const TransformPaintPropertyNode* scroll_offset_node() const {
- return scroll_offset_node_;
- }
-
- const IntRect& scroll_container_bounds() const {
- return scroll_container_bounds_;
- }
-
- // DisplayItem
- bool Equals(const DisplayItem&) const override;
-#if DCHECK_IS_ON()
- void PropertiesAsJSON(JSONObject&) const override;
-#endif
-
- // Create and append a ScrollHitTestDisplayItem onto the context. This is
- // similar to a recorder class (e.g., DrawingRecorder) but just emits a single
- // item. If no |scroll_offset_node| is passed in, this display item will only
- // be used for creating a non-fast-scrollable-region.
- static void Record(GraphicsContext&,
- const DisplayItemClient&,
- DisplayItem::Type,
- const TransformPaintPropertyNode* scroll_offset_node,
- const IntRect& scroll_container_bounds);
-
- const ScrollPaintPropertyNode* scroll_node() const {
- return scroll_offset_node_->ScrollNode();
- }
-
- private:
- // The scroll offset transform node if this ScrollHitTestDisplayItem could be
- // used for composited scrolling, or null if it is only used to prevent
- // composited scrolling.
- const TransformPaintPropertyNode* scroll_offset_node_;
- // The bounds of the scroll container, including scrollbars. We cannot use
- // scroll_node().container_rect() because it does not include scrollbars.
- const IntRect scroll_container_bounds_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_SCROLL_HIT_TEST_DISPLAY_ITEM_H_
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.cc
index 4aa3435f851..a91ac0fa9d9 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.cc
@@ -52,10 +52,6 @@ std::unique_ptr<JSONObject> ScrollPaintPropertyNode::ToJSON() const {
state_.main_thread_scrolling_reasons)
.c_str());
}
- if (state_.scrolls_inner_viewport)
- json->SetString("scrollsInnerViewport", "true");
- if (state_.scrolls_outer_viewport)
- json->SetString("scrollsOuterViewport", "true");
if (state_.max_scroll_offset_affected_by_page_scale)
json->SetString("maxScrollOffsetAffectedByPageScale", "true");
if (state_.compositor_element_id) {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h b/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h
index c1ebe1b0f61..75e7b5c3d4b 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h
@@ -43,8 +43,6 @@ class PLATFORM_EXPORT ScrollPaintPropertyNode
IntSize contents_size;
bool user_scrollable_horizontal = false;
bool user_scrollable_vertical = false;
- bool scrolls_inner_viewport = false;
- bool scrolls_outer_viewport = false;
// This bit tells the compositor whether the inner viewport should be
// scrolled using the full viewport mechanism (overscroll, top control
@@ -69,8 +67,6 @@ class PLATFORM_EXPORT ScrollPaintPropertyNode
contents_size != other.contents_size ||
user_scrollable_horizontal != other.user_scrollable_horizontal ||
user_scrollable_vertical != other.user_scrollable_vertical ||
- scrolls_inner_viewport != other.scrolls_inner_viewport ||
- scrolls_outer_viewport != other.scrolls_outer_viewport ||
prevent_viewport_scrolling_from_inner !=
other.prevent_viewport_scrolling_from_inner ||
max_scroll_offset_affected_by_page_scale !=
@@ -145,8 +141,6 @@ class PLATFORM_EXPORT ScrollPaintPropertyNode
bool UserScrollableVertical() const {
return state_.user_scrollable_vertical;
}
- bool ScrollsInnerViewport() const { return state_.scrolls_inner_viewport; }
- bool ScrollsOuterViewport() const { return state_.scrolls_outer_viewport; }
bool PreventViewportScrollingFromInner() const {
return state_.prevent_viewport_scrolling_from_inner;
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.cc
index 72d3fb4c053..eeb5932afc5 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.cc
@@ -34,6 +34,9 @@ ScrollbarDisplayItem::ScrollbarDisplayItem(
}
sk_sp<const PaintRecord> ScrollbarDisplayItem::Paint() const {
+ // We are painting a non-composited scrollbar, so we don't need layer_.
+ layer_ = nullptr;
+
if (record_) {
DCHECK(!scrollbar_->NeedsRepaintPart(cc::TRACK_BUTTONS_TICKMARKS));
DCHECK(!scrollbar_->NeedsRepaintPart(cc::THUMB));
@@ -52,7 +55,27 @@ sk_sp<const PaintRecord> ScrollbarDisplayItem::Paint() const {
return record_;
}
-scoped_refptr<cc::Layer> ScrollbarDisplayItem::CreateLayer() const {
+scoped_refptr<cc::ScrollbarLayerBase> ScrollbarDisplayItem::GetLayer() const {
+ // This function is called when the scrollbar is composited. We don't need
+ // record_ which is for non-composited scrollbars.
+ record_ = nullptr;
+
+ if (!layer_ || layer_->is_left_side_vertical_scrollbar() !=
+ scrollbar_->IsLeftSideVerticalScrollbar())
+ layer_ = CreateLayer();
+
+ layer_->SetOffsetToTransformParent(
+ gfx::Vector2dF(FloatPoint(rect_.Location())));
+ layer_->SetBounds(gfx::Size(rect_.Size()));
+
+ if (scrollbar_->NeedsRepaintPart(cc::THUMB) ||
+ scrollbar_->NeedsRepaintPart(cc::TRACK_BUTTONS_TICKMARKS))
+ layer_->SetNeedsDisplay();
+ return layer_;
+}
+
+scoped_refptr<cc::ScrollbarLayerBase> ScrollbarDisplayItem::CreateLayer()
+ const {
scoped_refptr<cc::ScrollbarLayerBase> layer;
if (scrollbar_->IsSolidColor()) {
DCHECK(scrollbar_->IsOverlay());
@@ -74,10 +97,10 @@ scoped_refptr<cc::Layer> ScrollbarDisplayItem::CreateLayer() const {
layer->SetIsDrawable(true);
layer->SetElementId(element_id_);
- if (scroll_translation_) {
- layer->SetScrollElementId(
- scroll_translation_->ScrollNode()->GetCompositorElementId());
- }
+ layer->SetScrollElementId(
+ scroll_translation_
+ ? scroll_translation_->ScrollNode()->GetCompositorElementId()
+ : CompositorElementId());
return layer;
}
@@ -114,9 +137,6 @@ void ScrollbarDisplayItem::Record(
const TransformPaintPropertyNode* scroll_translation,
CompositorElementId element_id) {
PaintController& paint_controller = context.GetPaintController();
- if (paint_controller.DisplayItemConstructionIsDisabled())
- return;
-
// Must check PaintController::UseCachedItemIfPossible before this function.
DCHECK(RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() ||
!paint_controller.UseCachedItemIfPossible(client, type));
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.h b/chromium/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.h
index c8e214c8007..1ddb96941c8 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.h
@@ -12,7 +12,7 @@
#include "third_party/skia/include/core/SkRefCnt.h"
namespace cc {
-class Layer;
+class ScrollbarLayerBase;
}
namespace blink {
@@ -35,8 +35,6 @@ class PLATFORM_EXPORT ScrollbarDisplayItem final : public DisplayItem {
const TransformPaintPropertyNode* scroll_translation,
CompositorElementId element_id);
- cc::Scrollbar* GetScrollbar() const { return scrollbar_.get(); }
- const IntRect& GetRect() const { return rect_; }
const TransformPaintPropertyNode* ScrollTranslation() const {
return scroll_translation_;
}
@@ -46,8 +44,8 @@ class PLATFORM_EXPORT ScrollbarDisplayItem final : public DisplayItem {
// scrollbar.
sk_sp<const PaintRecord> Paint() const;
- // Creates cc layer for composited scrollbar.
- scoped_refptr<cc::Layer> CreateLayer() const;
+ // Create or reuse the cc scrollbar layer, for composited scrollbar.
+ scoped_refptr<cc::ScrollbarLayerBase> GetLayer() const;
// DisplayItem
bool Equals(const DisplayItem&) const override;
@@ -67,12 +65,16 @@ class PLATFORM_EXPORT ScrollbarDisplayItem final : public DisplayItem {
CompositorElementId element_id);
private:
+ scoped_refptr<cc::ScrollbarLayerBase> CreateLayer() const;
+
scoped_refptr<cc::Scrollbar> scrollbar_;
IntRect rect_;
const TransformPaintPropertyNode* scroll_translation_;
CompositorElementId element_id_;
// This is lazily created for non-composited scrollbar.
mutable sk_sp<const PaintRecord> record_;
+ // This is lazily created for composited scrollbar.
+ mutable scoped_refptr<cc::ScrollbarLayerBase> layer_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item_test.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item_test.cc
new file mode 100644
index 00000000000..18148c28b3e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item_test.cc
@@ -0,0 +1,155 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by node BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.h"
+
+#include "cc/layers/painted_overlay_scrollbar_layer.h"
+#include "cc/layers/painted_scrollbar_layer.h"
+#include "cc/layers/solid_color_scrollbar_layer.h"
+#include "cc/test/fake_scrollbar.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h"
+#include "third_party/blink/renderer/platform/testing/fake_display_item_client.h"
+#include "third_party/blink/renderer/platform/testing/paint_property_test_helpers.h"
+
+namespace blink {
+
+CompositorElementId ScrollbarElementId(const cc::Scrollbar& scrollbar) {
+ return CompositorElementIdFromUniqueObjectId(
+ 13579, scrollbar.Orientation() == cc::HORIZONTAL
+ ? CompositorElementIdNamespace::kHorizontalScrollbar
+ : CompositorElementIdNamespace::kVerticalScrollbar);
+}
+
+CompositorElementId ScrollElementId() {
+ return CompositorElementIdFromUniqueObjectId(
+ 24680, CompositorElementIdNamespace::kScroll);
+}
+
+scoped_refptr<TransformPaintPropertyNode> CreateScrollTranslation() {
+ ScrollPaintPropertyNode::State state{IntRect(0, 0, 100, 100),
+ IntSize(1000, 1000)};
+ state.compositor_element_id = ScrollElementId();
+ auto scroll = ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(),
+ std::move(state));
+ return CreateScrollTranslation(t0(), 0, 0, *scroll);
+}
+
+TEST(ScrollbarDisplayItemTest, HorizontalSolidColorScrollbar) {
+ auto scrollbar = base::MakeRefCounted<cc::FakeScrollbar>();
+ scrollbar->set_orientation(cc::HORIZONTAL);
+ scrollbar->set_is_solid_color(true);
+ scrollbar->set_is_overlay(true);
+ scrollbar->set_track_rect(gfx::Rect(2, 90, 96, 10));
+ scrollbar->set_thumb_size(gfx::Size(30, 7));
+
+ FakeDisplayItemClient client;
+ IntRect scrollbar_rect(0, 90, 100, 10);
+ auto scroll_translation = CreateScrollTranslation();
+ auto element_id = ScrollbarElementId(*scrollbar);
+ ScrollbarDisplayItem display_item(client, DisplayItem::kScrollbarHorizontal,
+ scrollbar, scrollbar_rect,
+ scroll_translation.get(), element_id);
+ auto layer = display_item.GetLayer();
+ ASSERT_EQ(cc::ScrollbarLayerBase::kSolidColor,
+ layer->ScrollbarLayerTypeForTesting());
+ auto* scrollbar_layer =
+ static_cast<cc::SolidColorScrollbarLayer*>(layer.get());
+ EXPECT_EQ(cc::HORIZONTAL, scrollbar_layer->orientation());
+ EXPECT_EQ(7, scrollbar_layer->thumb_thickness());
+ EXPECT_EQ(2, scrollbar_layer->track_start());
+ EXPECT_EQ(element_id, scrollbar_layer->element_id());
+ EXPECT_EQ(ScrollElementId(), scrollbar_layer->scroll_element_id());
+
+ EXPECT_EQ(layer.get(), display_item.GetLayer().get());
+}
+
+TEST(ScrollbarDisplayItemTest, VerticalSolidColorScrollbar) {
+ auto scrollbar = base::MakeRefCounted<cc::FakeScrollbar>();
+ scrollbar->set_orientation(cc::VERTICAL);
+ scrollbar->set_is_solid_color(true);
+ scrollbar->set_is_overlay(true);
+ scrollbar->set_track_rect(gfx::Rect(90, 2, 10, 96));
+ scrollbar->set_thumb_size(gfx::Size(7, 30));
+
+ FakeDisplayItemClient client;
+ IntRect scrollbar_rect(90, 0, 10, 100);
+ auto scroll_translation = CreateScrollTranslation();
+ auto element_id = ScrollbarElementId(*scrollbar);
+ ScrollbarDisplayItem display_item(client, DisplayItem::kScrollbarHorizontal,
+ scrollbar, scrollbar_rect,
+ scroll_translation.get(), element_id);
+ auto layer = display_item.GetLayer();
+ ASSERT_EQ(cc::ScrollbarLayerBase::kSolidColor,
+ layer->ScrollbarLayerTypeForTesting());
+ auto* scrollbar_layer =
+ static_cast<cc::SolidColorScrollbarLayer*>(layer.get());
+ EXPECT_EQ(cc::VERTICAL, scrollbar_layer->orientation());
+ EXPECT_EQ(7, scrollbar_layer->thumb_thickness());
+ EXPECT_EQ(2, scrollbar_layer->track_start());
+ EXPECT_EQ(element_id, scrollbar_layer->element_id());
+ EXPECT_EQ(ScrollElementId(), scrollbar_layer->scroll_element_id());
+
+ EXPECT_EQ(layer.get(), display_item.GetLayer().get());
+}
+
+TEST(ScrollbarDisplayItemTest, PaintedColorScrollbar) {
+ auto scrollbar = base::MakeRefCounted<cc::FakeScrollbar>();
+
+ FakeDisplayItemClient client;
+ IntRect scrollbar_rect(0, 90, 100, 10);
+ auto scroll_translation = CreateScrollTranslation();
+ auto element_id = ScrollbarElementId(*scrollbar);
+ ScrollbarDisplayItem display_item(client, DisplayItem::kScrollbarHorizontal,
+ scrollbar, scrollbar_rect,
+ scroll_translation.get(), element_id);
+ auto layer = display_item.GetLayer();
+ ASSERT_EQ(cc::ScrollbarLayerBase::kPainted,
+ layer->ScrollbarLayerTypeForTesting());
+
+ EXPECT_EQ(layer.get(), display_item.GetLayer().get());
+}
+
+TEST(ScrollbarDisplayItemTest, PaintedColorScrollbarOverlayNonNinePatch) {
+ auto scrollbar = base::MakeRefCounted<cc::FakeScrollbar>();
+ scrollbar->set_has_thumb(true);
+ scrollbar->set_is_overlay(true);
+
+ FakeDisplayItemClient client;
+ IntRect scrollbar_rect(0, 90, 100, 10);
+ auto scroll_translation = CreateScrollTranslation();
+ auto element_id = ScrollbarElementId(*scrollbar);
+ ScrollbarDisplayItem display_item(client, DisplayItem::kScrollbarHorizontal,
+ scrollbar, scrollbar_rect,
+ scroll_translation.get(), element_id);
+ auto layer = display_item.GetLayer();
+ // We should create PaintedScrollbarLayer instead of
+ // PaintedOverlayScrollbarLayer for non-nine-patch overlay scrollbars.
+ ASSERT_EQ(cc::ScrollbarLayerBase::kPainted,
+ layer->ScrollbarLayerTypeForTesting());
+
+ EXPECT_EQ(layer.get(), display_item.GetLayer().get());
+}
+
+TEST(ScrollbarDisplayItemTest, PaintedColorScrollbarOverlayNinePatch) {
+ auto scrollbar = base::MakeRefCounted<cc::FakeScrollbar>();
+ scrollbar->set_has_thumb(true);
+ scrollbar->set_is_overlay(true);
+ scrollbar->set_uses_nine_patch_thumb_resource(true);
+
+ FakeDisplayItemClient client;
+ IntRect scrollbar_rect(0, 90, 100, 10);
+ auto scroll_translation = CreateScrollTranslation();
+ auto element_id = ScrollbarElementId(*scrollbar);
+ ScrollbarDisplayItem display_item(client, DisplayItem::kScrollbarHorizontal,
+ scrollbar, scrollbar_rect,
+ scroll_translation.get(), element_id);
+ auto layer = display_item.GetLayer();
+ ASSERT_EQ(cc::ScrollbarLayerBase::kPaintedOverlay,
+ layer->ScrollbarLayerTypeForTesting());
+
+ EXPECT_EQ(layer.get(), display_item.GetLayer().get());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/subsequence_recorder.h b/chromium/third_party/blink/renderer/platform/graphics/paint/subsequence_recorder.h
index e2e6288cce1..1e1666c9e92 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint/subsequence_recorder.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint/subsequence_recorder.h
@@ -21,13 +21,13 @@ class PaintController;
// of DisplayItems, and supports caching via a CachedDisplayItem with the
// CachedSubsequence DisplayItem type.
//
-// Also note that useCachedSubsequenceIfPossible is not sufficient to determine
+// Also note that UseCachedSubsequenceIfPossible is not sufficient to determine
// whether a CachedSubsequence can be used. In particular, the client is
// responsible for checking that none of the DisplayItemClients that contribute
// to the subsequence have been invalidated.
//
class SubsequenceRecorder final {
- DISALLOW_NEW();
+ STACK_ALLOCATED();
public:
static bool UseCachedSubsequenceIfPossible(GraphicsContext& context,
@@ -39,19 +39,15 @@ class SubsequenceRecorder final {
: paint_controller_(context.GetPaintController()),
client_(client),
start_(0) {
- if (!paint_controller_.DisplayItemConstructionIsDisabled())
- start_ = paint_controller_.BeginSubsequence();
+ start_ = paint_controller_.BeginSubsequence();
}
- ~SubsequenceRecorder() {
- if (!paint_controller_.DisplayItemConstructionIsDisabled())
- paint_controller_.EndSubsequence(client_, start_);
- }
+ ~SubsequenceRecorder() { paint_controller_.EndSubsequence(client_, start_); }
private:
PaintController& paint_controller_;
const DisplayItemClient& client_;
- size_t start_;
+ wtf_size_t start_;
DISALLOW_COPY_AND_ASSIGN(SubsequenceRecorder);
};
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 802a8acba3e..b44b2c24da8 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
@@ -59,12 +59,8 @@ class PLATFORM_EXPORT TransformPaintPropertyNode
// the transform is identity or a 2d translation, the translation_2d version
// should be used instead.
TransformAndOrigin(const TransformationMatrix& matrix,
- const FloatPoint3D& origin = FloatPoint3D(),
- bool disable_optimization = false) {
- if (!disable_optimization && matrix.IsIdentityOr2DTranslation())
- translation_2d_ = matrix.To2DTranslation();
- else
- matrix_and_origin_.reset(new MatrixAndOrigin{matrix, origin});
+ const FloatPoint3D& origin = FloatPoint3D()) {
+ matrix_and_origin_.reset(new MatrixAndOrigin{matrix, origin});
}
bool IsIdentityOr2DTranslation() const { return !matrix_and_origin_; }
@@ -381,6 +377,11 @@ class PLATFORM_EXPORT TransformPaintPropertyNode
return state_.direct_compositing_reasons & CompositingReason::kRootScroller;
}
+ bool RequiresCompositingForWillChangeTransform() const {
+ return state_.direct_compositing_reasons &
+ CompositingReason::kWillChangeTransform;
+ }
+
const CompositorElementId& GetCompositorElementId() const {
return state_.compositor_element_id;
}
@@ -421,6 +422,7 @@ class PLATFORM_EXPORT TransformPaintPropertyNode
// The scroll compositor element id should be stored on the scroll node.
DCHECK(!state_.compositor_element_id);
}
+ DCHECK(!HasActiveTransformAnimation() || !IsIdentityOr2DTranslation());
#endif
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint_generated_image.cc b/chromium/third_party/blink/renderer/platform/graphics/paint_generated_image.cc
index 45dbceb5bad..084304ea8cc 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint_generated_image.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint_generated_image.cc
@@ -20,18 +20,16 @@ void PaintGeneratedImage::Draw(cc::PaintCanvas* canvas,
ImageDecodingMode) {
PaintCanvasAutoRestore ar(canvas, true);
canvas->clipRect(dest_rect);
- canvas->translate(dest_rect.X(), dest_rect.Y());
- if (dest_rect.Size() != src_rect.Size())
- canvas->scale(dest_rect.Width() / src_rect.Width(),
- dest_rect.Height() / src_rect.Height());
- canvas->translate(-src_rect.X(), -src_rect.Y());
+ canvas->concat(SkMatrix::MakeRectToRect(src_rect, dest_rect,
+ SkMatrix::kFill_ScaleToFit));
SkRect bounds = src_rect;
canvas->saveLayer(&bounds, &flags);
canvas->drawPicture(record_);
}
void PaintGeneratedImage::DrawTile(GraphicsContext& context,
- const FloatRect& src_rect) {
+ const FloatRect& src_rect,
+ RespectImageOrientationEnum) {
context.DrawRecord(record_);
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint_generated_image.h b/chromium/third_party/blink/renderer/platform/graphics/paint_generated_image.h
index 06fb89c4dd4..6978106580e 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/paint_generated_image.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/paint_generated_image.h
@@ -28,7 +28,9 @@ class PLATFORM_EXPORT PaintGeneratedImage : public GeneratedImage {
RespectImageOrientationEnum,
ImageClampingMode,
ImageDecodingMode) override;
- void DrawTile(GraphicsContext&, const FloatRect&) final;
+ void DrawTile(GraphicsContext&,
+ const FloatRect&,
+ RespectImageOrientationEnum) final;
PaintGeneratedImage(sk_sp<PaintRecord> record, const FloatSize& size)
: GeneratedImage(size), record_(std::move(record)) {}
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 43a015c670f..ab027f02901 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/placeholder_image.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/placeholder_image.cc
@@ -177,7 +177,6 @@ class PlaceholderImage::SharedFont : public RefCounted<SharedFont> {
explicit SharedFont(float scale_factor)
: font_(CreatePlaceholderFontDescription(scale_factor)),
scale_factor_(scale_factor) {
- font_.Update(nullptr);
}
~SharedFont() {
@@ -191,7 +190,6 @@ class PlaceholderImage::SharedFont : public RefCounted<SharedFont> {
scale_factor_ = scale_factor;
font_ = Font(CreatePlaceholderFontDescription(scale_factor_));
- font_.Update(nullptr);
}
const Font& font() const { return font_; }
@@ -252,8 +250,8 @@ PaintImage PlaceholderImage::PaintImageForCurrentFrame() {
PaintRecorder paint_recorder;
Draw(paint_recorder.beginRecording(FloatRect(dest_rect)), PaintFlags(),
- FloatRect(dest_rect), FloatRect(dest_rect),
- kDoNotRespectImageOrientation, kClampImageToSourceRect, kSyncDecode);
+ FloatRect(dest_rect), FloatRect(dest_rect), kRespectImageOrientation,
+ kClampImageToSourceRect, kSyncDecode);
paint_record_for_current_frame_ = paint_recorder.finishRecordingAsPicture();
paint_record_content_id_ = PaintImage::GetNextContentId();
@@ -359,13 +357,15 @@ void PlaceholderImage::Draw(cc::PaintCanvas* canvas,
Font::kUseFallbackIfFontNotReady, 1.0f, flags);
}
-void PlaceholderImage::DrawPattern(GraphicsContext& context,
- const FloatRect& src_rect,
- const FloatSize& scale,
- const FloatPoint& phase,
- SkBlendMode mode,
- const FloatRect& dest_rect,
- const FloatSize& repeat_spacing) {
+void PlaceholderImage::DrawPattern(
+ GraphicsContext& context,
+ const FloatRect& src_rect,
+ const FloatSize& scale,
+ const FloatPoint& phase,
+ SkBlendMode mode,
+ const FloatRect& dest_rect,
+ const FloatSize& repeat_spacing,
+ RespectImageOrientationEnum respect_orientation) {
DCHECK(context.Canvas());
PaintFlags flags = context.FillFlags();
@@ -374,9 +374,8 @@ void PlaceholderImage::DrawPattern(GraphicsContext& context,
// Ignore the pattern specifications and just draw a single placeholder image
// over the whole |dest_rect|. This is done in order to prevent repeated icons
// from cluttering tiled background images.
- Draw(context.Canvas(), flags, dest_rect, src_rect,
- kDoNotRespectImageOrientation, kClampImageToSourceRect,
- kUnspecifiedDecode);
+ Draw(context.Canvas(), flags, dest_rect, src_rect, respect_orientation,
+ kClampImageToSourceRect, kUnspecifiedDecode);
}
void PlaceholderImage::DestroyDecodedData() {
diff --git a/chromium/third_party/blink/renderer/platform/graphics/placeholder_image.h b/chromium/third_party/blink/renderer/platform/graphics/placeholder_image.h
index e6a2647bbba..e1e706801b4 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/placeholder_image.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/placeholder_image.h
@@ -83,7 +83,8 @@ class PLATFORM_EXPORT PlaceholderImage final : public Image {
const FloatPoint& phase,
SkBlendMode,
const FloatRect& dest_rect,
- const FloatSize& repeat_spacing) override;
+ const FloatSize& repeat_spacing,
+ RespectImageOrientationEnum) override;
// SetData does nothing, and the passed in buffer is ignored.
SizeAvailability SetData(scoped_refptr<SharedBuffer>, bool) override;
diff --git a/chromium/third_party/blink/renderer/platform/graphics/placeholder_image_test.cc b/chromium/third_party/blink/renderer/platform/graphics/placeholder_image_test.cc
index 81fb9df438a..eb5c0622151 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/placeholder_image_test.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/placeholder_image_test.cc
@@ -75,9 +75,8 @@ void DrawImageExpectingGrayBoxOnly(PlaceholderImage& image,
EXPECT_CALL(canvas, drawTextBlob(_, _, _, _)).Times(0);
image.Draw(&canvas, PaintFlags(), dest_rect,
- FloatRect(0.0f, 0.0f, 100.0f, 100.0f),
- kDoNotRespectImageOrientation, Image::kClampImageToSourceRect,
- Image::kUnspecifiedDecode);
+ FloatRect(0.0f, 0.0f, 100.0f, 100.0f), kRespectImageOrientation,
+ Image::kClampImageToSourceRect, Image::kUnspecifiedDecode);
}
void DrawImageExpectingIconOnly(PlaceholderImage& image,
@@ -134,7 +133,6 @@ float GetExpectedPlaceholderTextWidth(const StringView& text,
description.SetWeight(FontSelectionValue(500));
Font font(description);
- font.Update(nullptr);
return font.Width(TextRun(text));
}
diff --git a/chromium/third_party/blink/renderer/platform/graphics/skia/skia_utils.cc b/chromium/third_party/blink/renderer/platform/graphics/skia/skia_utils.cc
index 1e8ae93ee66..a254d06c0cf 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/skia/skia_utils.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/skia/skia_utils.cc
@@ -38,6 +38,7 @@
#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
#include "third_party/skia/include/effects/SkCornerPathEffect.h"
#include "third_party/skia/include/third_party/skcms/skcms.h"
+#include "ui/base/ui_base_features.h"
#include <algorithm>
#include <cmath>
@@ -374,13 +375,19 @@ template <typename PrimitiveType>
void DrawPlatformFocusRing(const PrimitiveType& primitive,
cc::PaintCanvas* canvas,
SkColor color,
- float width) {
+ float width,
+ float border_radius) {
PaintFlags flags;
flags.setAntiAlias(true);
flags.setStyle(PaintFlags::kStroke_Style);
flags.setColor(color);
flags.setStrokeWidth(width);
+ if (::features::IsFormControlsRefreshEnabled()) {
+ DrawFocusRingPrimitive(primitive, canvas, flags, border_radius);
+ return;
+ }
+
#if defined(OS_MACOSX)
flags.setAlpha(64);
const float corner_radius = (width - 1) * 0.5f;
@@ -398,14 +405,18 @@ void DrawPlatformFocusRing(const PrimitiveType& primitive,
#endif
}
-template void PLATFORM_EXPORT DrawPlatformFocusRing<SkRect>(const SkRect&,
- cc::PaintCanvas*,
- SkColor,
- float width);
-template void PLATFORM_EXPORT DrawPlatformFocusRing<SkPath>(const SkPath&,
- cc::PaintCanvas*,
- SkColor,
- float width);
+template void PLATFORM_EXPORT
+DrawPlatformFocusRing<SkRect>(const SkRect&,
+ cc::PaintCanvas*,
+ SkColor,
+ float width,
+ float border_radius);
+template void PLATFORM_EXPORT
+DrawPlatformFocusRing<SkPath>(const SkPath&,
+ cc::PaintCanvas*,
+ SkColor,
+ float width,
+ float border_radius);
sk_sp<SkData> TryAllocateSkData(size_t size) {
void* buffer = WTF::Partitions::BufferPartition()->AllocFlags(
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 b5f81ee0f40..b35b6ce5449 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
@@ -144,7 +144,8 @@ template <typename PrimitiveType>
void DrawPlatformFocusRing(const PrimitiveType&,
cc::PaintCanvas*,
SkColor,
- float width);
+ float width,
+ float border_radius);
// TODO(fmalita): remove in favor of direct SrcRectConstraint use.
inline cc::PaintCanvas::SrcRectConstraint
diff --git a/chromium/third_party/blink/renderer/platform/graphics/skia_texture_holder.cc b/chromium/third_party/blink/renderer/platform/graphics/skia_texture_holder.cc
deleted file mode 100644
index f59034399e6..00000000000
--- a/chromium/third_party/blink/renderer/platform/graphics/skia_texture_holder.cc
+++ /dev/null
@@ -1,149 +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/graphics/skia_texture_holder.h"
-
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/renderer/platform/graphics/canvas_color_params.h"
-#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
-#include "third_party/blink/renderer/platform/graphics/mailbox_texture_holder.h"
-#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
-#include "third_party/khronos/GLES2/gl2ext.h"
-#include "third_party/skia/include/gpu/GrBackendSurface.h"
-#include "third_party/skia/include/gpu/GrContext.h"
-
-namespace blink {
-
-namespace {
-bool IsSkImageOriginTopLeft(sk_sp<SkImage> image) {
- GrSurfaceOrigin origin;
- image->getBackendTexture(false, &origin);
- return origin == kTopLeft_GrSurfaceOrigin;
-}
-
-struct ReleaseContext {
- scoped_refptr<TextureHolder::MailboxRef> mailbox_ref;
- GLuint texture_id = 0u;
- bool is_shared_image = false;
- GrTexture* gr_texture = nullptr;
- base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper;
-};
-
-void ReleaseTexture(void* ctx) {
- auto* release_ctx = static_cast<ReleaseContext*>(ctx);
- if (release_ctx->context_provider_wrapper) {
- if (release_ctx->gr_texture) {
- release_ctx->context_provider_wrapper->Utils()->RemoveCachedMailbox(
- release_ctx->gr_texture);
- }
-
- if (release_ctx->texture_id) {
- auto* gl =
- release_ctx->context_provider_wrapper->ContextProvider()->ContextGL();
- if (release_ctx->is_shared_image)
- gl->EndSharedImageAccessDirectCHROMIUM(release_ctx->texture_id);
- gl->DeleteTextures(1u, &release_ctx->texture_id);
- }
- }
-
- delete release_ctx;
-}
-
-} // namespace
-
-SkiaTextureHolder::SkiaTextureHolder(
- sk_sp<SkImage> image,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper>&&
- context_provider_wrapper)
- : TextureHolder(std::move(context_provider_wrapper),
- base::MakeRefCounted<MailboxRef>(nullptr),
- IsSkImageOriginTopLeft(image)),
- image_(std::move(image)) {}
-
-SkiaTextureHolder::SkiaTextureHolder(
- const MailboxTextureHolder* mailbox_texture_holder,
- GLuint shared_image_texture_id)
- : TextureHolder(SharedGpuContext::ContextProviderWrapper(),
- mailbox_texture_holder->mailbox_ref(),
- mailbox_texture_holder->IsOriginTopLeft()) {
- const gpu::Mailbox mailbox = mailbox_texture_holder->GetMailbox();
- DCHECK(!shared_image_texture_id || mailbox.IsSharedImage());
- DCHECK(!shared_image_texture_id || !mailbox_texture_holder->IsCrossThread());
-
- const gpu::SyncToken sync_token = mailbox_texture_holder->GetSyncToken();
- const auto& sk_image_info = mailbox_texture_holder->sk_image_info();
- GLenum texture_target = mailbox_texture_holder->texture_target();
-
- if (!ContextProvider())
- return;
-
- gpu::gles2::GLES2Interface* shared_gl = ContextProvider()->ContextGL();
- GrContext* shared_gr_context = ContextProvider()->GetGrContext();
- DCHECK(shared_gl &&
- shared_gr_context); // context isValid already checked in callers
-
- GLuint shared_context_texture_id = 0u;
- bool should_delete_texture_on_release = true;
-
- if (shared_image_texture_id) {
- shared_context_texture_id = shared_image_texture_id;
- should_delete_texture_on_release = false;
- } else {
- shared_gl->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
- if (mailbox.IsSharedImage()) {
- shared_context_texture_id =
- shared_gl->CreateAndTexStorage2DSharedImageCHROMIUM(mailbox.name);
- shared_gl->BeginSharedImageAccessDirectCHROMIUM(
- shared_context_texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM);
- } else {
- shared_context_texture_id =
- shared_gl->CreateAndConsumeTextureCHROMIUM(mailbox.name);
- }
- }
-
- GrGLTextureInfo texture_info;
- texture_info.fTarget = texture_target;
- texture_info.fID = shared_context_texture_id;
- texture_info.fFormat =
- CanvasColorParams(sk_image_info).GLSizedInternalFormat();
- GrBackendTexture backend_texture(sk_image_info.width(),
- sk_image_info.height(), GrMipMapped::kNo,
- texture_info);
-
- GrSurfaceOrigin origin = IsOriginTopLeft() ? kTopLeft_GrSurfaceOrigin
- : kBottomLeft_GrSurfaceOrigin;
-
- auto* release_ctx = new ReleaseContext;
- release_ctx->mailbox_ref = mailbox_ref();
- if (should_delete_texture_on_release)
- release_ctx->texture_id = shared_context_texture_id;
- release_ctx->is_shared_image = mailbox.IsSharedImage();
- release_ctx->context_provider_wrapper = ContextProviderWrapper();
-
- image_ = SkImage::MakeFromTexture(
- shared_gr_context, backend_texture, origin, sk_image_info.colorType(),
- sk_image_info.alphaType(), sk_image_info.refColorSpace(), &ReleaseTexture,
- release_ctx);
- if (image_) {
- release_ctx->gr_texture = image_->getTexture();
- DCHECK(release_ctx->gr_texture);
- ContextProviderWrapper()->Utils()->RegisterMailbox(image_->getTexture(),
- mailbox);
- } else {
- ReleaseTexture(release_ctx);
- }
-}
-
-SkiaTextureHolder::~SkiaTextureHolder() {
- // Object must be destroyed on the same thread where it was created.
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-}
-
-bool SkiaTextureHolder::IsValid() const {
- return !!image_ && !!ContextProviderWrapper() &&
- image_->isValid(ContextProvider()->GetGrContext());
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/skia_texture_holder.h b/chromium/third_party/blink/renderer/platform/graphics/skia_texture_holder.h
deleted file mode 100644
index 4aa252996c0..00000000000
--- a/chromium/third_party/blink/renderer/platform/graphics/skia_texture_holder.h
+++ /dev/null
@@ -1,60 +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_PLATFORM_GRAPHICS_SKIA_TEXTURE_HOLDER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_SKIA_TEXTURE_HOLDER_H_
-
-#include "base/memory/weak_ptr.h"
-#include "base/threading/thread_checker.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "third_party/blink/renderer/platform/graphics/texture_holder.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-
-namespace blink {
-class MailboxTextureHolder;
-class WebGraphicsContext3DProviderWrapper;
-
-class PLATFORM_EXPORT SkiaTextureHolder final : public TextureHolder {
- public:
- ~SkiaTextureHolder() override;
-
- // TextureHolder impl.
- IntSize Size() const final {
- if (image_)
- return IntSize(image_->width(), image_->height());
- return IntSize();
- }
- bool IsValid() const final;
- bool CurrentFrameKnownToBeOpaque() const final {
- return image_ && image_->isOpaque();
- }
-
- const sk_sp<SkImage>& GetSkImage() const { return image_; }
-
- // When creating a AcceleratedStaticBitmap from a texture-backed SkImage, this
- // function will be called to create a TextureHolder object.
- SkiaTextureHolder(sk_sp<SkImage>,
- base::WeakPtr<WebGraphicsContext3DProviderWrapper>&&);
-
- // This function consumes the mailbox in the input parameter and turn it into
- // a texture-backed SkImage.
- // |shared_image_texture_id| is an optional texture bound to the
- // |texture_holder|'s mailbox and imported into its context. Note that if a
- // texture is provided it must:
- // 1) Be associated with a shared image mailbox.
- // 2) Stay alive and have a read lock on the shared image until the
- // |MailboxRef| is destroyed.
- SkiaTextureHolder(const MailboxTextureHolder* texture_holder,
- GLuint shared_image_texture_id);
-
- private:
- // The image_ should always be texture-backed.
- sk_sp<SkImage> image_;
-
- THREAD_CHECKER(thread_checker_);
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_SKIA_TEXTURE_HOLDER_H_
diff --git a/chromium/third_party/blink/renderer/platform/graphics/squashing_disallowed_reasons.cc b/chromium/third_party/blink/renderer/platform/graphics/squashing_disallowed_reasons.cc
index 6605e4258a3..f1f66e3a6d3 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/squashing_disallowed_reasons.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/squashing_disallowed_reasons.cc
@@ -56,10 +56,6 @@ constexpr SquashingDisallowedReasonStringMap
"squashingNearestFixedPositionMismatch",
"Cannot be squashed because this layer has a different nearest fixed "
"position layer than the squashing layer"},
- {SquashingDisallowedReason::kScrollChildWithCompositedDescendants,
- "scrollChildWithCompositedDescendants",
- "Squashing a scroll child with composited descendants is not "
- "supported."},
{SquashingDisallowedReason::kSquashingLayerIsAnimating,
"squashingLayerIsAnimating",
"Cannot squash into a layer that is animating."},
diff --git a/chromium/third_party/blink/renderer/platform/graphics/squashing_disallowed_reasons.h b/chromium/third_party/blink/renderer/platform/graphics/squashing_disallowed_reasons.h
index 21357fae5cf..46b6e780942 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/squashing_disallowed_reasons.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/squashing_disallowed_reasons.h
@@ -24,7 +24,6 @@ using SquashingDisallowedReasons = unsigned;
V(SquashingLayoutEmbeddedContentIsDisallowed) \
V(SquashingBlendingIsDisallowed) \
V(NearestFixedPositionMismatch) \
- V(ScrollChildWithCompositedDescendants) \
V(SquashingLayerIsAnimating) \
V(RenderingContextMismatch) \
V(FragmentedContent) \
diff --git a/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc b/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc
index ae6cb2afc46..fce932e5648 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc
@@ -20,53 +20,64 @@
namespace blink {
-scoped_refptr<StaticBitmapImage> StaticBitmapImage::Create(PaintImage image) {
+scoped_refptr<StaticBitmapImage> StaticBitmapImage::Create(
+ PaintImage image,
+ ImageOrientation orientation) {
DCHECK(!image.GetSkImage()->isTextureBacked());
- return UnacceleratedStaticBitmapImage::Create(std::move(image));
+ return UnacceleratedStaticBitmapImage::Create(std::move(image), orientation);
}
scoped_refptr<StaticBitmapImage> StaticBitmapImage::Create(
sk_sp<SkData> data,
- const SkImageInfo& info) {
+ const SkImageInfo& info,
+ ImageOrientation orientation) {
return UnacceleratedStaticBitmapImage::Create(
- SkImage::MakeRasterData(info, std::move(data), info.minRowBytes()));
+ SkImage::MakeRasterData(info, std::move(data), info.minRowBytes()),
+ orientation);
+}
+
+IntSize StaticBitmapImage::SizeRespectingOrientation() const {
+ if (orientation_.UsesWidthAsHeight())
+ return Size().TransposedSize();
+ else
+ return Size();
}
-void StaticBitmapImage::DrawHelper(cc::PaintCanvas* canvas,
- const PaintFlags& flags,
- const FloatRect& dst_rect,
- const FloatRect& src_rect,
- ImageClampingMode clamp_mode,
- const PaintImage& image) {
+void StaticBitmapImage::DrawHelper(
+ cc::PaintCanvas* canvas,
+ const PaintFlags& flags,
+ const FloatRect& dst_rect,
+ const FloatRect& src_rect,
+ ImageClampingMode clamp_mode,
+ RespectImageOrientationEnum respect_orientation,
+ const PaintImage& image) {
FloatRect adjusted_src_rect = src_rect;
adjusted_src_rect.Intersect(SkRect::MakeWH(image.width(), image.height()));
if (dst_rect.IsEmpty() || adjusted_src_rect.IsEmpty())
return; // Nothing to draw.
- canvas->drawImageRect(image, adjusted_src_rect, dst_rect, &flags,
- WebCoreClampingModeToSkiaRectConstraint(clamp_mode));
-}
+ cc::PaintCanvasAutoRestore auto_restore(canvas, false);
+ FloatRect adjusted_dst_rect = dst_rect;
+ if (respect_orientation && orientation_ != kDefaultImageOrientation) {
+ canvas->save();
-scoped_refptr<StaticBitmapImage> StaticBitmapImage::ConvertToColorSpace(
- sk_sp<SkColorSpace> color_space,
- SkColorType color_type) {
- DCHECK(color_space);
- sk_sp<SkImage> skia_image = PaintImageForCurrentFrame().GetSkImage();
-
- // If we don't need to change the color type, use SkImage::makeColorSpace()
- if (skia_image->colorType() == color_type) {
- skia_image = skia_image->makeColorSpace(color_space);
- } else {
- skia_image =
- skia_image->makeColorTypeAndColorSpace(color_type, color_space);
- }
+ // ImageOrientation expects the origin to be at (0, 0)
+ canvas->translate(adjusted_dst_rect.X(), adjusted_dst_rect.Y());
+ adjusted_dst_rect.SetLocation(FloatPoint());
- if (skia_image->isTextureBacked()) {
- return AcceleratedStaticBitmapImage::CreateFromSkImage(
- skia_image, ContextProviderWrapper());
+ canvas->concat(AffineTransformToSkMatrix(
+ orientation_.TransformFromDefault(adjusted_dst_rect.Size())));
+
+ if (orientation_.UsesWidthAsHeight()) {
+ adjusted_dst_rect =
+ FloatRect(adjusted_dst_rect.X(), adjusted_dst_rect.Y(),
+ adjusted_dst_rect.Height(), adjusted_dst_rect.Width());
+ }
}
- return UnacceleratedStaticBitmapImage::Create(skia_image);
+
+ canvas->drawImageRect(image, adjusted_src_rect, adjusted_dst_rect, &flags,
+ WebCoreClampingModeToSkiaRectConstraint(clamp_mode));
}
base::CheckedNumeric<size_t> StaticBitmapImage::GetSizeInBytes(
@@ -120,9 +131,4 @@ bool StaticBitmapImage::CopyToByteArray(
return true;
}
-const gpu::SyncToken& StaticBitmapImage::GetSyncToken() const {
- static const gpu::SyncToken sync_token;
- return sync_token;
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image.h b/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image.h
index 7366bdebcdc..f14b5b86cc3 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/static_bitmap_image.h
@@ -6,11 +6,11 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_STATIC_BITMAP_IMAGE_H_
#include "base/memory/weak_ptr.h"
-#include "gpu/command_buffer/common/mailbox.h"
-#include "gpu/command_buffer/common/sync_token.h"
+#include "gpu/command_buffer/common/mailbox_holder.h"
#include "third_party/blink/renderer/platform/graphics/canvas_color_params.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/skia/include/core/SkRefCnt.h"
@@ -22,23 +22,29 @@ class GLES2Interface;
namespace blink {
-class WebGraphicsContext3DProviderWrapper;
-
class PLATFORM_EXPORT StaticBitmapImage : public Image {
public:
- static scoped_refptr<StaticBitmapImage> Create(PaintImage);
- static scoped_refptr<StaticBitmapImage> Create(sk_sp<SkData> data,
- const SkImageInfo&);
+ // The ImageOrientation should be derived from the source of the image data.
+ static scoped_refptr<StaticBitmapImage> Create(
+ PaintImage,
+ ImageOrientation = kDefaultImageOrientation);
+ static scoped_refptr<StaticBitmapImage> Create(
+ sk_sp<SkData> data,
+ const SkImageInfo&,
+ ImageOrientation = kDefaultImageOrientation);
+
+ StaticBitmapImage(ImageOrientation orientation) : orientation_(orientation) {}
bool IsStaticBitmapImage() const override { return true; }
// Methods overridden by all sub-classes
~StaticBitmapImage() override = default;
- // Creates a gpu copy of the image using the given ContextProvider. Should
- // not be called if IsTextureBacked() is already true. May return null if the
- // conversion failed (for instance if the context had an error).
- virtual scoped_refptr<StaticBitmapImage> MakeAccelerated(
- base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_wrapper) = 0;
+
+ IntSize SizeRespectingOrientation() const override;
+
+ virtual scoped_refptr<StaticBitmapImage> ConvertToColorSpace(
+ sk_sp<SkColorSpace>,
+ SkColorType = kN32_SkColorType) = 0;
// Methods have common implementation for all sub-classes
bool CurrentFrameIsComplete() override { return true; }
@@ -46,9 +52,9 @@ class PLATFORM_EXPORT StaticBitmapImage : public Image {
// Methods that have a default implementation, and overridden by only one
// sub-class
- virtual bool HasMailbox() const { return false; }
virtual bool IsValid() const { return true; }
virtual void Transfer() {}
+ virtual bool IsOriginTopLeft() const { return true; }
// Creates a non-gpu copy of the image, or returns this if image is already
// non-gpu.
@@ -68,37 +74,27 @@ class PLATFORM_EXPORT StaticBitmapImage : public Image {
return false;
}
- // EnsureMailbox modifies the internal state of an accelerated static bitmap
- // image to make sure that it is represented by a Mailbox. This must be
- // called whenever the image is intende to be used in a differen GPU context.
- // It is important to use the correct MailboxSyncMode in order to achieve
- // optimal performance without compromising security or causeing graphics
- // glitches. Here is how to select the aprropriate mode:
- //
- // Case 1: Passing to a gpu context that is on a separate channel.
- // Note: a context in a separate process is necessarily on another channel.
- // Use kVerifiedSyncToken. Or use kUnverifiedSyncToken with a later call
- // to VerifySyncTokensCHROMIUM()
- // Case 2: Passing to a gpu context that is on the same channel but not the
- // same stream.
- // Use kUnverifiedSyncToken
- // Case 3: Passing to a gpu context on the same stream.
- // Use kOrderingBarrier
- virtual void EnsureMailbox(MailboxSyncMode, GLenum filter) { NOTREACHED(); }
- virtual const gpu::Mailbox& GetMailbox() const {
+ virtual void EnsureSyncTokenVerified() { NOTREACHED(); }
+ virtual gpu::MailboxHolder GetMailboxHolder() const {
NOTREACHED();
- static const gpu::Mailbox mailbox;
- return mailbox;
+ return gpu::MailboxHolder();
}
- virtual const gpu::SyncToken& GetSyncToken() const;
+ virtual void UpdateSyncToken(const gpu::SyncToken&) { NOTREACHED(); }
virtual bool IsPremultiplied() const { return true; }
// Methods have exactly the same implementation for all sub-classes
bool OriginClean() const { return is_origin_clean_; }
void SetOriginClean(bool flag) { is_origin_clean_ = flag; }
- scoped_refptr<StaticBitmapImage> ConvertToColorSpace(
- sk_sp<SkColorSpace>,
- SkColorType = kN32_SkColorType);
+
+ // StaticBitmapImage needs to store the orientation of the image itself,
+ // because the underlying representations do not. If the bitmap represents
+ // a non-default orientation it must be explicitly given in the constructor.
+ ImageOrientation CurrentFrameOrientation() const override {
+ return orientation_;
+ }
+ bool HasDefaultOrientation() const override {
+ return orientation_ == kDefaultImageOrientation;
+ }
static base::CheckedNumeric<size_t> GetSizeInBytes(
const IntRect& rect,
@@ -119,8 +115,15 @@ class PLATFORM_EXPORT StaticBitmapImage : public Image {
const FloatRect&,
const FloatRect&,
ImageClampingMode,
+ RespectImageOrientationEnum,
const PaintImage&);
+ // The image orientation is stored here because it is only available when the
+ // static image is created and the underlying representations do not store
+ // the information. The property is set at construction based on the source of
+ // the image data.
+ ImageOrientation orientation_ = kDefaultImageOrientation;
+
// The following property is here because the SkImage API doesn't expose the
// info. It is applied to both UnacceleratedStaticBitmapImage and
// AcceleratedStaticBitmapImage. To change this property, the call site would
@@ -128,7 +131,12 @@ class PLATFORM_EXPORT StaticBitmapImage : public Image {
bool is_origin_clean_ = true;
};
-DEFINE_IMAGE_TYPE_CASTS(StaticBitmapImage);
+template <>
+struct DowncastTraits<StaticBitmapImage> {
+ static bool AllowFrom(const Image& image) {
+ return image.IsStaticBitmapImage();
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/surface_layer_bridge.cc b/chromium/third_party/blink/renderer/platform/graphics/surface_layer_bridge.cc
index 4f3d1cc74ec..5b851f0e695 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/surface_layer_bridge.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/surface_layer_bridge.cc
@@ -14,8 +14,8 @@
#include "components/viz/common/surfaces/surface_info.h"
#include "media/base/media_switches.h"
#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/frame_sinks/embedded_frame_sink.mojom-blink.h"
-#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/mojo/mojo_helper.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -33,7 +33,7 @@ SurfaceLayerBridge::SurfaceLayerBridge(
frame_sink_id_(Platform::Current()->GenerateFrameSinkId()),
parent_frame_sink_id_(parent_frame_sink_id) {
mojo::Remote<mojom::blink::EmbeddedFrameSinkProvider> provider;
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
provider.BindNewPipeAndPassReceiver());
// TODO(xlai): Ensure OffscreenCanvas commit() is still functional when a
// frame-less HTML canvas's document is reparenting under another frame.
diff --git a/chromium/third_party/blink/renderer/platform/graphics/texture_holder.h b/chromium/third_party/blink/renderer/platform/graphics/texture_holder.h
deleted file mode 100644
index a1ba07e2056..00000000000
--- a/chromium/third_party/blink/renderer/platform/graphics/texture_holder.h
+++ /dev/null
@@ -1,85 +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_PLATFORM_GRAPHICS_TEXTURE_HOLDER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_TEXTURE_HOLDER_H_
-
-#include "base/memory/weak_ptr.h"
-#include "components/viz/common/resources/single_release_callback.h"
-#include "gpu/command_buffer/common/mailbox.h"
-#include "gpu/command_buffer/common/sync_token.h"
-#include "third_party/blink/renderer/platform/geometry/int_size.h"
-#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
-#include "third_party/blink/renderer/platform/graphics/image.h"
-#include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
-#include "third_party/skia/include/core/SkImage.h"
-#include "third_party/skia/include/core/SkRefCnt.h"
-
-namespace blink {
-
-class PLATFORM_EXPORT TextureHolder {
- public:
- class MailboxRef : public ThreadSafeRefCounted<MailboxRef> {
- public:
- explicit MailboxRef(
- std::unique_ptr<viz::SingleReleaseCallback> release_callback)
- : release_callback_(std::move(release_callback)) {}
- ~MailboxRef() {
- if (release_callback_)
- release_callback_->Run(sync_token_, false /* resource_lost */);
- }
-
- void set_sync_token(gpu::SyncToken token) { sync_token_ = token; }
- const gpu::SyncToken& sync_token() const { return sync_token_; }
-
- private:
- gpu::SyncToken sync_token_;
- std::unique_ptr<viz::SingleReleaseCallback> release_callback_;
- };
-
- virtual ~TextureHolder() = default;
-
- // Methods overridden by all sub-classes
- virtual IntSize Size() const = 0;
- virtual bool CurrentFrameKnownToBeOpaque() const = 0;
- virtual bool IsValid() const = 0;
-
- // Methods that have exactly the same impelmentation for all sub-classes
- base::WeakPtr<WebGraphicsContext3DProviderWrapper> ContextProviderWrapper()
- const {
- return context_provider_wrapper_;
- }
-
- WebGraphicsContext3DProvider* ContextProvider() const {
- return context_provider_wrapper_
- ? context_provider_wrapper_->ContextProvider()
- : nullptr;
- }
-
- bool IsOriginTopLeft() const { return is_origin_top_left_; }
-
- const scoped_refptr<MailboxRef>& mailbox_ref() const { return mailbox_ref_; }
-
- protected:
- TextureHolder(base::WeakPtr<WebGraphicsContext3DProviderWrapper>&&
- context_provider_wrapper,
- scoped_refptr<MailboxRef> mailbox_ref,
- bool is_origin_top_left)
- : context_provider_wrapper_(std::move(context_provider_wrapper)),
- mailbox_ref_(std::move(mailbox_ref)),
- is_origin_top_left_(is_origin_top_left) {
- DCHECK(mailbox_ref_);
- }
-
- private:
- base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper_;
- scoped_refptr<MailboxRef> mailbox_ref_;
- bool is_origin_top_left_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_TEXTURE_HOLDER_H_
diff --git a/chromium/third_party/blink/renderer/platform/graphics/touch_action_rect.cc b/chromium/third_party/blink/renderer/platform/graphics/touch_action_rect.cc
new file mode 100644
index 00000000000..1b18032e09f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/graphics/touch_action_rect.cc
@@ -0,0 +1,21 @@
+// 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/graphics/touch_action_rect.h"
+
+#include "cc/base/region.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+String TouchActionRect::ToString() const {
+ return rect.ToString() + " " + cc::TouchActionToString(allowed_touch_action);
+}
+
+std::ostream& operator<<(std::ostream& os,
+ const TouchActionRect& hit_test_rect) {
+ return os << hit_test_rect.ToString();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/touch_action_rect.h b/chromium/third_party/blink/renderer/platform/graphics/touch_action_rect.h
new file mode 100644
index 00000000000..578b2bbbe10
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/graphics/touch_action_rect.h
@@ -0,0 +1,31 @@
+// 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_PLATFORM_GRAPHICS_TOUCH_ACTION_RECT_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_TOUCH_ACTION_RECT_H_
+
+#include "third_party/blink/renderer/platform/geometry/int_rect.h"
+#include "third_party/blink/renderer/platform/graphics/touch_action.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+
+namespace blink {
+
+struct PLATFORM_EXPORT TouchActionRect {
+ IntRect rect;
+ TouchAction allowed_touch_action = TouchAction::kNone;
+
+ bool operator==(const TouchActionRect& rhs) const {
+ return rect == rhs.rect && allowed_touch_action == rhs.allowed_touch_action;
+ }
+
+ bool operator!=(const TouchActionRect& rhs) const { return !(*this == rhs); }
+
+ String ToString() const;
+};
+
+PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, const TouchActionRect&);
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_TOUCH_ACTION_RECT_H_
diff --git a/chromium/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.cc b/chromium/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.cc
index 01253176e58..5a0e96f8d48 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.cc
@@ -17,13 +17,17 @@
namespace blink {
scoped_refptr<UnacceleratedStaticBitmapImage>
-UnacceleratedStaticBitmapImage::Create(sk_sp<SkImage> image) {
+UnacceleratedStaticBitmapImage::Create(sk_sp<SkImage> image,
+ ImageOrientation orientation) {
DCHECK(!image->isTextureBacked());
- return base::AdoptRef(new UnacceleratedStaticBitmapImage(std::move(image)));
+ return base::AdoptRef(
+ new UnacceleratedStaticBitmapImage(std::move(image), orientation));
}
UnacceleratedStaticBitmapImage::UnacceleratedStaticBitmapImage(
- sk_sp<SkImage> image) {
+ sk_sp<SkImage> image,
+ ImageOrientation orientation)
+ : StaticBitmapImage(orientation) {
CHECK(image);
DCHECK(!image->isLazyGenerated());
paint_image_ =
@@ -33,12 +37,16 @@ UnacceleratedStaticBitmapImage::UnacceleratedStaticBitmapImage(
}
scoped_refptr<UnacceleratedStaticBitmapImage>
-UnacceleratedStaticBitmapImage::Create(PaintImage image) {
- return base::AdoptRef(new UnacceleratedStaticBitmapImage(std::move(image)));
+UnacceleratedStaticBitmapImage::Create(PaintImage image,
+ ImageOrientation orientation) {
+ return base::AdoptRef(
+ new UnacceleratedStaticBitmapImage(std::move(image), orientation));
}
-UnacceleratedStaticBitmapImage::UnacceleratedStaticBitmapImage(PaintImage image)
- : paint_image_(std::move(image)) {
+UnacceleratedStaticBitmapImage::UnacceleratedStaticBitmapImage(
+ PaintImage image,
+ ImageOrientation orientation)
+ : StaticBitmapImage(orientation), paint_image_(std::move(image)) {
CHECK(paint_image_.GetSkImage());
}
@@ -66,40 +74,21 @@ bool UnacceleratedStaticBitmapImage::IsPremultiplied() const {
SkAlphaType::kPremul_SkAlphaType;
}
-scoped_refptr<StaticBitmapImage>
-UnacceleratedStaticBitmapImage::MakeAccelerated(
- base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_wrapper) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- if (!context_wrapper)
- return nullptr; // Can happen if the context is lost.
-
- GrContext* grcontext = context_wrapper->ContextProvider()->GetGrContext();
- if (!grcontext)
- return nullptr; // Can happen if the context is lost.
-
- sk_sp<SkImage> sk_image = paint_image_.GetSkImage();
- sk_sp<SkImage> gpu_skimage = sk_image->makeTextureImage(grcontext);
- if (!gpu_skimage)
- return nullptr;
-
- return AcceleratedStaticBitmapImage::CreateFromSkImage(
- std::move(gpu_skimage), std::move(context_wrapper));
-}
-
bool UnacceleratedStaticBitmapImage::CurrentFrameKnownToBeOpaque() {
return paint_image_.GetSkImage()->isOpaque();
}
-void UnacceleratedStaticBitmapImage::Draw(cc::PaintCanvas* canvas,
- const cc::PaintFlags& flags,
- const FloatRect& dst_rect,
- const FloatRect& src_rect,
- RespectImageOrientationEnum,
- ImageClampingMode clamp_mode,
- ImageDecodingMode) {
+void UnacceleratedStaticBitmapImage::Draw(
+ cc::PaintCanvas* canvas,
+ const cc::PaintFlags& flags,
+ const FloatRect& dst_rect,
+ const FloatRect& src_rect,
+ RespectImageOrientationEnum should_respect_image_orientation,
+ ImageClampingMode clamp_mode,
+ ImageDecodingMode) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
StaticBitmapImage::DrawHelper(canvas, flags, dst_rect, src_rect, clamp_mode,
+ should_respect_image_orientation,
PaintImageForCurrentFrame());
}
@@ -114,4 +103,21 @@ void UnacceleratedStaticBitmapImage::Transfer() {
original_skia_image_task_runner_ = Thread::Current()->GetTaskRunner();
}
+scoped_refptr<StaticBitmapImage>
+UnacceleratedStaticBitmapImage::ConvertToColorSpace(
+ sk_sp<SkColorSpace> color_space,
+ SkColorType color_type) {
+ DCHECK(color_space);
+
+ sk_sp<SkImage> skia_image = PaintImageForCurrentFrame().GetSkImage();
+ // If we don't need to change the color type, use SkImage::makeColorSpace()
+ if (skia_image->colorType() == color_type) {
+ skia_image = skia_image->makeColorSpace(color_space);
+ } else {
+ skia_image =
+ skia_image->makeColorTypeAndColorSpace(color_type, color_space);
+ }
+ return UnacceleratedStaticBitmapImage::Create(skia_image, orientation_);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h b/chromium/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h
index d5ec71b3c44..d7c50181397 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h
@@ -17,15 +17,20 @@ class PLATFORM_EXPORT UnacceleratedStaticBitmapImage final
: public StaticBitmapImage {
public:
~UnacceleratedStaticBitmapImage() override;
- static scoped_refptr<UnacceleratedStaticBitmapImage> Create(sk_sp<SkImage>);
- static scoped_refptr<UnacceleratedStaticBitmapImage> Create(PaintImage);
+
+ // The ImageOrientation should be derived from the source of the image data.
+ static scoped_refptr<UnacceleratedStaticBitmapImage> Create(
+ sk_sp<SkImage>,
+ ImageOrientation orientation = kDefaultImageOrientation);
+ static scoped_refptr<UnacceleratedStaticBitmapImage> Create(
+ PaintImage,
+ ImageOrientation orientation = kDefaultImageOrientation);
bool CurrentFrameKnownToBeOpaque() override;
IntSize Size() const override;
bool IsPremultiplied() const override;
- scoped_refptr<StaticBitmapImage> MakeAccelerated(
- base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_wrapper)
- override;
+ scoped_refptr<StaticBitmapImage> ConvertToColorSpace(sk_sp<SkColorSpace>,
+ SkColorType) override;
void Draw(cc::PaintCanvas*,
const cc::PaintFlags&,
@@ -40,8 +45,8 @@ class PLATFORM_EXPORT UnacceleratedStaticBitmapImage final
void Transfer() final;
private:
- UnacceleratedStaticBitmapImage(sk_sp<SkImage>);
- UnacceleratedStaticBitmapImage(PaintImage);
+ UnacceleratedStaticBitmapImage(sk_sp<SkImage>, ImageOrientation);
+ UnacceleratedStaticBitmapImage(PaintImage, ImageOrientation);
PaintImage paint_image_;
THREAD_CHECKER(thread_checker_);
diff --git a/chromium/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc b/chromium/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc
index 38028ad0d5b..7fe9c308b58 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc
@@ -36,8 +36,7 @@ void VideoFrameResourceProvider::Initialize(
viz::RasterContextProvider* media_context_provider,
viz::SharedBitmapReporter* shared_bitmap_reporter) {
context_provider_ = media_context_provider;
- resource_provider_ = std::make_unique<viz::ClientResourceProvider>(
- /*delegated_sync_points_required=*/true);
+ resource_provider_ = std::make_unique<viz::ClientResourceProvider>();
int max_texture_size;
if (context_provider_) {
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 1f551556454..e0cb8886ddd 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
@@ -10,6 +10,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
+#include "cc/metrics/video_playback_roughness_reporter.h"
#include "components/viz/common/resources/resource_id.h"
#include "components/viz/common/resources/returned_resource.h"
#include "media/base/video_frame.h"
@@ -18,8 +19,8 @@
#include "services/viz/public/cpp/gpu/context_provider_command_buffer.h"
#include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom-blink.h"
#include "services/viz/public/mojom/hit_test/hit_test_region_list.mojom-blink.h"
+#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/frame_sinks/embedded_frame_sink.mojom-blink.h"
-#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/graphics/canvas_resource.h"
#include "ui/gfx/presentation_feedback.h"
@@ -28,10 +29,13 @@ namespace blink {
VideoFrameSubmitter::VideoFrameSubmitter(
WebContextProviderCallback context_provider_callback,
+ cc::PlaybackRoughnessReportingCallback roughness_reporting_callback,
std::unique_ptr<VideoFrameResourceProvider> resource_provider)
: context_provider_callback_(context_provider_callback),
resource_provider_(std::move(resource_provider)),
rotation_(media::VIDEO_ROTATION_0),
+ roughness_reporter_(std::make_unique<cc::VideoPlaybackRoughnessReporter>(
+ std::move(roughness_reporting_callback))),
frame_trackers_(false, nullptr) {
DETACH_FROM_THREAD(thread_checker_);
}
@@ -72,6 +76,7 @@ void VideoFrameSubmitter::StopRendering() {
is_rendering_ = false;
frame_trackers_.StopSequence(cc::FrameSequenceTrackerType::kVideo);
+ roughness_reporter_->Reset();
UpdateSubmissionState();
}
@@ -182,31 +187,39 @@ void VideoFrameSubmitter::OnBeginFrame(
if (viz::FrameTokenGT(pair.key, *next_frame_token_))
continue;
- if (base::Contains(frame_token_to_timestamp_map_, pair.key) &&
- !(pair.value->presentation_feedback->flags &
- gfx::PresentationFeedback::kFailure)) {
- if (!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));
- }
- UMA_HISTOGRAM_TIMES("Media.VideoFrameSubmitter",
- pair.value->presentation_feedback->timestamp -
- frame_token_to_timestamp_map_[pair.key]);
- frame_token_to_timestamp_map_.erase(pair.key);
+#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);
+#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);
}
ignorable_submitted_frames_.erase(pair.key);
-
- TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0(
- "media", "VideoFrameSubmitter", pair.key,
+ TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0(
+ "media", "VideoFrameSubmitter", TRACE_ID_LOCAL(pair.key),
pair.value->presentation_feedback->timestamp);
}
-
frame_trackers_.NotifyBeginImplFrame(args);
+ base::ScopedClosureRunner end_frame(
+ base::BindOnce(&cc::FrameSequenceTrackerCollection::NotifyFrameEnd,
+ base::Unretained(&frame_trackers_), args, args));
+ base::ScopedClosureRunner roughness_processing(
+ base::BindOnce(&cc::VideoPlaybackRoughnessReporter::ProcessFrameWindow,
+ base::Unretained(roughness_reporter_.get())));
+
// Don't call UpdateCurrentFrame() for MISSED BeginFrames. Also don't call it
// after StopRendering() has been called (forbidden by API contract).
viz::BeginFrameAck current_begin_frame_ack(args, false);
@@ -274,6 +287,8 @@ void VideoFrameSubmitter::OnReceivedContextProvider(
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (!use_gpu_compositing) {
resource_provider_->Initialize(nullptr, this);
+ if (frame_sink_id_.is_valid())
+ StartSubmitting();
return;
}
@@ -317,7 +332,7 @@ void VideoFrameSubmitter::StartSubmitting() {
DCHECK(frame_sink_id_.is_valid());
mojo::Remote<mojom::blink::EmbeddedFrameSinkProvider> provider;
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
provider.BindNewPipeAndPassReceiver());
provider->CreateCompositorFrameSink(
@@ -437,8 +452,15 @@ bool VideoFrameSubmitter::SubmitFrame(
frame_size_ = frame_size;
}
- auto compositor_frame =
- CreateCompositorFrame(begin_frame_ack, std::move(video_frame));
+ auto frame_token = ++next_frame_token_;
+ auto source_id = begin_frame_ack.frame_id.source_id;
+ if (source_id != viz::BeginFrameArgs::kManualSourceId) {
+ // Roughness reporter only cares about true video frames.
+ roughness_reporter_->FrameSubmitted(frame_token, *video_frame.get(),
+ last_begin_frame_args_.interval);
+ }
+ auto compositor_frame = CreateCompositorFrame(frame_token, begin_frame_ack,
+ std::move(video_frame));
WebVector<viz::ResourceId> resources;
const auto& quad_list = compositor_frame.render_pass_list.back()->quad_list;
@@ -453,7 +475,6 @@ bool VideoFrameSubmitter::SubmitFrame(
// We can pass nullptr for the HitTestData as the CompositorFram will not
// contain any SurfaceDrawQuads.
- auto frame_token = compositor_frame.metadata.frame_token;
compositor_frame_sink_->SubmitCompositorFrame(
child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation()
.local_surface_id(),
@@ -479,9 +500,10 @@ void VideoFrameSubmitter::SubmitEmptyFrame() {
last_frame_id_.reset();
auto begin_frame_ack = viz::BeginFrameAck::CreateManualAckWithDamage();
- auto compositor_frame = CreateCompositorFrame(begin_frame_ack, nullptr);
+ auto frame_token = ++next_frame_token_;
+ auto compositor_frame =
+ CreateCompositorFrame(frame_token, begin_frame_ack, nullptr);
- auto frame_token = compositor_frame.metadata.frame_token;
compositor_frame_sink_->SubmitCompositorFrame(
child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation()
.local_surface_id(),
@@ -520,13 +542,14 @@ bool VideoFrameSubmitter::ShouldSubmit() const {
}
viz::CompositorFrame VideoFrameSubmitter::CreateCompositorFrame(
+ uint32_t frame_token,
const viz::BeginFrameAck& begin_frame_ack,
scoped_refptr<media::VideoFrame> video_frame) {
DCHECK(!frame_size_.IsEmpty());
viz::CompositorFrame compositor_frame;
compositor_frame.metadata.begin_frame_ack = begin_frame_ack;
- compositor_frame.metadata.frame_token = ++next_frame_token_;
+ compositor_frame.metadata.frame_token = frame_token;
compositor_frame.metadata.preferred_frame_interval =
video_frame_provider_
? video_frame_provider_->GetPreferredRenderInterval()
@@ -535,22 +558,23 @@ viz::CompositorFrame VideoFrameSubmitter::CreateCompositorFrame(
base::TimeTicks value;
if (video_frame && video_frame->metadata()->GetTimeTicks(
media::VideoFrameMetadata::DECODE_END_TIME, &value)) {
- TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0("media", "VideoFrameSubmitter",
- *next_frame_token_, value);
- TRACE_EVENT_ASYNC_STEP_PAST0("media", "VideoFrameSubmitter",
- *next_frame_token_, "Pre-submit buffering");
-
- frame_token_to_timestamp_map_[*next_frame_token_] = value;
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0(
+ "media", "VideoFrameSubmitter", TRACE_ID_LOCAL(frame_token), value);
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0(
+ "media", "Pre-submit buffering", TRACE_ID_LOCAL(frame_token), value);
+ TRACE_EVENT_NESTABLE_ASYNC_END0("media", "Pre-submit buffering",
+ TRACE_ID_LOCAL(frame_token));
- if (begin_frame_ack.source_id == viz::BeginFrameArgs::kManualSourceId)
- ignorable_submitted_frames_.insert(*next_frame_token_);
+ if (begin_frame_ack.frame_id.source_id ==
+ viz::BeginFrameArgs::kManualSourceId)
+ ignorable_submitted_frames_.insert(frame_token);
UMA_HISTOGRAM_TIMES("Media.VideoFrameSubmitter.PreSubmitBuffering",
base::TimeTicks::Now() - value);
} else {
- TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1(
- "media", "VideoFrameSubmitter", *next_frame_token_,
- base::TimeTicks::Now(), "empty video frame?", !video_frame);
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("media", "VideoFrameSubmitter",
+ TRACE_ID_LOCAL(frame_token),
+ "empty video frame?", !video_frame);
}
// We don't assume that the ack is marked as having damage. However, we're
@@ -567,6 +591,8 @@ viz::CompositorFrame VideoFrameSubmitter::CreateCompositorFrame(
gfx::Transform());
if (video_frame) {
+ compositor_frame.metadata.content_color_usage =
+ video_frame->ColorSpace().GetContentColorUsage();
const bool is_opaque = media::IsOpaque(video_frame->format());
resource_provider_->AppendQuads(render_pass.get(), std::move(video_frame),
rotation_, is_opaque);
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 0953c624df4..90207762377 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
@@ -14,6 +14,7 @@
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "cc/metrics/frame_sequence_tracker.h"
+#include "cc/metrics/video_playback_roughness_reporter.h"
#include "components/viz/client/shared_bitmap_reporter.h"
#include "components/viz/common/gpu/context_provider.h"
#include "components/viz/common/resources/shared_bitmap.h"
@@ -44,6 +45,7 @@ class PLATFORM_EXPORT VideoFrameSubmitter
public viz::mojom::blink::CompositorFrameSinkClient {
public:
VideoFrameSubmitter(WebContextProviderCallback,
+ cc::PlaybackRoughnessReportingCallback,
std::unique_ptr<VideoFrameResourceProvider>);
~VideoFrameSubmitter() override;
@@ -127,6 +129,7 @@ class PLATFORM_EXPORT VideoFrameSubmitter
// Helper method for creating viz::CompositorFrame. If |video_frame| is null
// then the frame will be empty.
viz::CompositorFrame CreateCompositorFrame(
+ uint32_t frame_token,
const viz::BeginFrameAck& begin_frame_ack,
scoped_refptr<media::VideoFrame> video_frame);
@@ -172,9 +175,7 @@ class PLATFORM_EXPORT VideoFrameSubmitter
viz::FrameTokenGenerator next_frame_token_;
- // Timestamps indexed by frame token for histogram purposes.
- using FrameTokenType = decltype(*std::declval<viz::FrameTokenGenerator>());
- base::flat_map<FrameTokenType, base::TimeTicks> frame_token_to_timestamp_map_;
+ std::unique_ptr<cc::VideoPlaybackRoughnessReporter> roughness_reporter_;
base::OneShotTimer empty_frame_timer_;
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 742b9d0cc98..8a772fda9b0 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
@@ -12,10 +12,12 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/read_only_shared_memory_region.h"
+#include "base/test/bind_test_util.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "cc/layers/video_frame_provider.h"
+#include "cc/metrics/video_playback_roughness_reporter.h"
#include "cc/test/layer_test_common.h"
#include "cc/trees/layer_tree_settings.h"
#include "cc/trees/task_runner_provider.h"
@@ -37,6 +39,7 @@
using testing::_;
using testing::AnyNumber;
+using testing::Invoke;
using testing::Return;
using testing::StrictMock;
@@ -169,11 +172,13 @@ class VideoFrameSubmitterTest : public testing::Test {
task_environment_.RunUntilIdle();
}
- void MakeSubmitter() {
+ void MakeSubmitter() { MakeSubmitter(base::DoNothing()); }
+
+ void MakeSubmitter(cc::PlaybackRoughnessReportingCallback reporting_cb) {
resource_provider_ = new StrictMock<MockVideoFrameResourceProvider>(
context_provider_.get(), nullptr);
submitter_ = std::make_unique<VideoFrameSubmitter>(
- base::DoNothing(),
+ base::DoNothing(), reporting_cb,
base::WrapUnique<MockVideoFrameResourceProvider>(resource_provider_));
submitter_->Initialize(video_frame_provider_.get());
@@ -307,8 +312,8 @@ TEST_F(VideoFrameSubmitterTest, StopRenderingSkipsUpdateCurrentFrame) {
// No frames should be produced after StopRendering().
EXPECT_CALL(*sink_, DidNotProduceFrame(_));
- begin_frame_source_->CreateBeginFrameArgs(BEGINFRAME_FROM_HERE,
- now_src_.get());
+ args = begin_frame_source_->CreateBeginFrameArgs(BEGINFRAME_FROM_HERE,
+ now_src_.get());
submitter_->OnBeginFrame(args, {});
task_environment_.RunUntilIdle();
}
@@ -498,6 +503,8 @@ TEST_F(VideoFrameSubmitterTest, RotationInformationPassedToResourceProvider) {
EXPECT_CALL(*resource_provider_, PrepareSendToParent(_, _));
EXPECT_CALL(*resource_provider_, ReleaseFrameResources());
+ args = begin_frame_source_->CreateBeginFrameArgs(BEGINFRAME_FROM_HERE,
+ now_src_.get());
submitter_->OnBeginFrame(args, {});
task_environment_.RunUntilIdle();
}
@@ -640,6 +647,27 @@ TEST_F(VideoFrameSubmitterTest, RecreateCompositorFrameSinkAfterContextLost) {
task_environment_.RunUntilIdle();
}
+// Test that after context is lost, the CompositorFrameSink is recreated but the
+// SurfaceEmbedder isn't even with software compositing.
+TEST_F(VideoFrameSubmitterTest,
+ RecreateCompositorFrameSinkAfterContextLostSoftwareCompositing) {
+ MockEmbeddedFrameSinkProvider mock_embedded_frame_sink_provider;
+ mojo::Receiver<mojom::blink::EmbeddedFrameSinkProvider>
+ embedded_frame_sink_provider_binding(&mock_embedded_frame_sink_provider);
+ auto override =
+ mock_embedded_frame_sink_provider.CreateScopedOverrideMojoInterface(
+ &embedded_frame_sink_provider_binding);
+
+ EXPECT_CALL(*resource_provider_, Initialize(_, _));
+ EXPECT_CALL(mock_embedded_frame_sink_provider, ConnectToEmbedder(_, _))
+ .Times(0);
+ EXPECT_CALL(mock_embedded_frame_sink_provider, CreateCompositorFrameSink_(_))
+ .Times(1);
+ submitter_->OnContextLost();
+ OnReceivedContextProvider(false, nullptr);
+ task_environment_.RunUntilIdle();
+}
+
// This test simulates a race condition in which the |video_frame_provider_| is
// destroyed before OnReceivedContextProvider returns.
TEST_F(VideoFrameSubmitterTest, StopUsingProviderDuringContextLost) {
@@ -662,7 +690,7 @@ TEST_F(VideoFrameSubmitterTest, StopUsingProviderDuringContextLost) {
}
// Test the behaviour of the ChildLocalSurfaceIdAllocator instance. It checks
-// that the LocalSurfaceId is propoerly set at creation and updated when the
+// that the LocalSurfaceId is properly set at creation and updated when the
// video frames change.
TEST_F(VideoFrameSubmitterTest, FrameSizeChangeUpdatesLocalSurfaceId) {
{
@@ -893,6 +921,8 @@ TEST_F(VideoFrameSubmitterTest, NoDuplicateFramesOnBeginFrame) {
.WillOnce(Return(true));
EXPECT_CALL(*video_frame_provider_, GetCurrentFrame()).WillOnce(Return(vf));
EXPECT_CALL(*sink_, DidNotProduceFrame(_));
+ args = begin_frame_source_->CreateBeginFrameArgs(BEGINFRAME_FROM_HERE,
+ now_src_.get());
submitter_->OnBeginFrame(args, {});
task_environment_.RunUntilIdle();
}
@@ -928,4 +958,66 @@ TEST_F(VideoFrameSubmitterTest, ZeroSizedFramesAreNotSubmitted) {
task_environment_.RunUntilIdle();
}
+// Check that given enough frames with wallclock duration and enough
+// presentation feedback data, VideoFrameSubmitter will call the video roughness
+// reporting callback.
+TEST_F(VideoFrameSubmitterTest, ProcessTimingDetails) {
+ int fps = 24;
+ 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;
+
+ MakeSubmitter(
+ base::BindLambdaForTesting([&](int frames, base::TimeDelta duration,
+ double roughness) { reports++; }));
+ EXPECT_CALL(*sink_, SetNeedsBeginFrame(true));
+ submitter_->StartRendering();
+ task_environment_.RunUntilIdle();
+ EXPECT_TRUE(IsRendering());
+
+ 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 =
+ base::TimeTicks() + frame_duration * token;
+ timing_details.clear();
+ timing_details.Set(token, std::move(details));
+ };
+
+ EXPECT_CALL(*video_frame_provider_, UpdateCurrentFrame)
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(*video_frame_provider_, PutCurrentFrame).Times(AnyNumber());
+ EXPECT_CALL(*sink_, DoSubmitCompositorFrame)
+ .WillRepeatedly(Invoke(sink_submit));
+ EXPECT_CALL(*resource_provider_, AppendQuads).Times(AnyNumber());
+ EXPECT_CALL(*resource_provider_, PrepareSendToParent).Times(AnyNumber());
+ EXPECT_CALL(*resource_provider_, ReleaseFrameResources).Times(AnyNumber());
+
+ for (int i = 0; i < frames_to_run; i++) {
+ 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);
+ 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));
+ task_environment_.RunUntilIdle();
+ AckSubmittedFrame();
+ }
+ submitter_->StopRendering();
+ EXPECT_EQ(reports, 1);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/BUILD.gn b/chromium/third_party/blink/renderer/platform/heap/BUILD.gn
index c21068565d3..d868c461141 100644
--- a/chromium/third_party/blink/renderer/platform/heap/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/heap/BUILD.gn
@@ -3,20 +3,39 @@
# found in the LICENSE file.
import("//build/buildflag_header.gni")
+import("//build/config/compiler/compiler.gni")
import("//build/config/jumbo.gni")
+import("//build/config/sanitizers/sanitizers.gni")
import("//testing/test.gni")
+import("//third_party/blink/public/public_features.gni")
import("//third_party/blink/renderer/platform/platform.gni")
-declare_args() {
- # Enables heap verification.
- enable_blink_heap_verification = false
-}
-
buildflag_header("blink_heap_buildflags") {
header = "heap_buildflags.h"
header_dir = "third_party/blink/renderer/platform/heap"
- flags = [ "BLINK_HEAP_VERIFICATION=$enable_blink_heap_verification" ]
+ flags = [
+ "BLINK_HEAP_VERIFICATION=$enable_blink_heap_verification",
+ "BLINK_HEAP_YOUNG_GENERATION=$enable_blink_heap_young_generation",
+ ]
+}
+
+jumbo_source_set("heap_unsanitized") {
+ if (is_asan) {
+ configs -= [ "//build/config/sanitizers:default_sanitizer_flags" ]
+ }
+ configs +=
+ [ "//third_party/blink/renderer/platform:blink_platform_implementation" ]
+
+ sources = [
+ "unsanitized_atomic.cc",
+ "unsanitized_atomic.h",
+ ]
+
+ deps = [
+ "//base",
+ "//third_party/blink/renderer/platform/wtf",
+ ]
}
blink_platform_sources("heap") {
@@ -28,6 +47,9 @@ blink_platform_sources("heap") {
"blink_gc_memory_dump_provider.h",
"cancelable_task_scheduler.cc",
"cancelable_task_scheduler.h",
+ "collection_support/heap_hash_table_backing.h",
+ "collection_support/heap_linked_stack.h",
+ "collection_support/heap_vector_backing.h",
"disallow_new_wrapper.h",
"finalizer_traits.h",
"garbage_collected.h",
@@ -41,7 +63,6 @@ blink_platform_sources("heap") {
"heap_allocator.h",
"heap_compact.cc",
"heap_compact.h",
- "heap_linked_stack.h",
"heap_page.cc",
"heap_page.h",
"heap_stats_collector.cc",
@@ -83,10 +104,16 @@ blink_platform_sources("heap") {
":blink_heap_buildflags",
"//base",
"//third_party/blink/renderer/platform:make_platform_generated",
+ "//third_party/blink/renderer/platform/heap:heap_unsanitized",
"//third_party/blink/renderer/platform/heap/asm",
"//third_party/icu",
"//v8",
]
+
+ if (!is_debug && !optimize_for_size) {
+ configs -= [ "//build/config/compiler:default_optimization" ]
+ configs += [ "//build/config/compiler:optimize_max" ]
+ }
}
jumbo_source_set("test_support") {
@@ -98,6 +125,7 @@ jumbo_source_set("test_support") {
]
deps = [
+ ":blink_heap_buildflags",
"//testing/gtest",
"//third_party/blink/public/mojom:mojom_platform_blink_headers",
"//third_party/blink/renderer/platform:bindings_buildflags",
@@ -105,9 +133,7 @@ jumbo_source_set("test_support") {
}
test("blink_heap_unittests") {
- deps = [
- ":blink_heap_unittests_sources",
- ]
+ deps = [ ":blink_heap_unittests_sources" ]
if (is_android) {
deps += [
"//base:base_java",
@@ -124,6 +150,8 @@ jumbo_source_set("blink_heap_unittests_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",
@@ -142,6 +170,10 @@ jumbo_source_set("blink_heap_unittests_sources") {
"write_barrier_perftest.cc",
]
+ if (enable_blink_heap_young_generation) {
+ sources += [ "minor_gc_test.cc" ]
+ }
+
configs += [
"//third_party/blink/renderer/platform/wtf:wtf_config",
"//third_party/blink/renderer:config",
diff --git a/chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md b/chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md
index f1415c771a5..eb532cd733c 100644
--- a/chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md
+++ b/chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md
@@ -201,7 +201,7 @@ Especially, avoid defining a pre-finalizer in a class that can be allocated a lo
### STACK_ALLOCATED
-Class level annotation that should be used if the object is only stack allocated; it disallows use of `operator new`. Any fields holding garbage-collected objects should use `Member<T>` references, but you do not need to define a `Trace()` method as they are on the stack, and automatically traced and kept alive should a conservative GC be required.
+Class level annotation that should be used if the object is only stack allocated; it disallows use of `operator new`. Any fields holding garbage-collected objects should use regular pointers or references and you do not need to define a `Trace()` method as they are on the stack, and automatically traced and kept alive should a conservative GC be required.
Classes with this annotation do not need a `Trace()` method and must not inherit a on-heap garbage collected class.
@@ -275,7 +275,7 @@ You need to trace every `Member<T>` and `WeakMember<T>` in your class. See [Trac
Unlike 'Member<T>', 'UntracedMember<T>' will not keep an object alive. However, unlike 'WeakMember<T>', the reference will not be cleared (i.e. set to 'nullptr') if the referenced object dies.
Furthermore, class fields of type 'UntracedMember<T>' should not be traced by the class' tracing method.
-Users should use 'UntracedMember<T>' when implementing [custom weakness semantics](#Custom weak callbacks).
+Users should use 'UntracedMember<T>' when implementing [custom weakness semantics](#Custom-weak-callbacks).
### Persistent, WeakPersistent, CrossThreadPersistent, CrossThreadWeakPersistent
diff --git a/chromium/third_party/blink/renderer/platform/heap/DEPS b/chromium/third_party/blink/renderer/platform/heap/DEPS
index eda4c2ea500..5814f38e1e9 100644
--- a/chromium/third_party/blink/renderer/platform/heap/DEPS
+++ b/chromium/third_party/blink/renderer/platform/heap/DEPS
@@ -12,8 +12,9 @@ include_rules = [
"+base/strings/string_number_conversions.h",
"+base/synchronization/lock.h",
"+base/task_runner.h",
+ "+base/task/post_job.h",
"+base/template_util.h",
- "+testing/perf/perf_test.h",
+ "+testing/perf/perf_result_reporter.h",
"+third_party/blink/renderer/platform/bindings",
"+third_party/blink/renderer/platform/instrumentation/histogram.h",
diff --git a/chromium/third_party/blink/renderer/platform/heap/OWNERS b/chromium/third_party/blink/renderer/platform/heap/OWNERS
index bca3233e2e4..dafb539f11d 100644
--- a/chromium/third_party/blink/renderer/platform/heap/OWNERS
+++ b/chromium/third_party/blink/renderer/platform/heap/OWNERS
@@ -2,6 +2,7 @@ bikineev@chromium.org
haraken@chromium.org
kouhei@chromium.org
mlippautz@chromium.org
+omerkatz@chromium.org
# TEAM: oilpan-reviews@chromium.org
# COMPONENT: Blink>MemoryAllocator>GarbageCollection
diff --git a/chromium/third_party/blink/renderer/platform/heap/asm/BUILD.gn b/chromium/third_party/blink/renderer/platform/heap/asm/BUILD.gn
index 8aa2cbe249d..fe44daf27a5 100644
--- a/chromium/third_party/blink/renderer/platform/heap/asm/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/heap/asm/BUILD.gn
@@ -8,9 +8,7 @@ if (current_cpu == "x86" || current_cpu == "x64") {
nasm_assemble("asm") {
assert(current_cpu == "x86" || current_cpu == "x64")
- sources = [
- "SaveRegisters_x86.asm",
- ]
+ sources = [ "SaveRegisters_x86.asm" ]
defines = []
if (is_mac) {
@@ -31,25 +29,15 @@ if (current_cpu == "x86" || current_cpu == "x64") {
} else { # current_cpu == "x86" || current_cpu == "x64"
source_set("asm") {
if (current_cpu == "arm") {
- sources = [
- "SaveRegisters_arm.S",
- ]
+ sources = [ "SaveRegisters_arm.S" ]
} else if (current_cpu == "arm64") {
- sources = [
- "SaveRegisters_arm64.S",
- ]
+ sources = [ "SaveRegisters_arm64.S" ]
} else if (current_cpu == "mipsel") {
- sources = [
- "SaveRegisters_mips.S",
- ]
+ sources = [ "SaveRegisters_mips.S" ]
} else if (current_cpu == "mips64el") {
- sources = [
- "SaveRegisters_mips64.S",
- ]
+ sources = [ "SaveRegisters_mips64.S" ]
} else if (current_cpu == "ppc64") {
- sources = [
- "SaveRegisters_ppc64.S",
- ]
+ sources = [ "SaveRegisters_ppc64.S" ]
}
if (current_cpu == "arm") {
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 a1ba0e53a23..ccc1bfb0443 100644
--- a/chromium/third_party/blink/renderer/platform/heap/blink_gc.h
+++ b/chromium/third_party/blink/renderer/platform/heap/blink_gc.h
@@ -19,17 +19,18 @@ class MarkingVisitor;
class Visitor;
using Address = uint8_t*;
+using ConstAddress = const uint8_t*;
using FinalizationCallback = void (*)(void*);
-using VisitorCallback = void (*)(Visitor*, void*);
-using MarkingVisitorCallback = void (*)(MarkingVisitor*, void*);
+using VisitorCallback = void (*)(Visitor*, const void*);
+using MarkingVisitorCallback = void (*)(MarkingVisitor*, const void*);
using TraceCallback = VisitorCallback;
-using WeakCallback = void (*)(const WeakCallbackInfo&, void*);
+using WeakCallback = void (*)(const WeakCallbackInfo&, const void*);
using EphemeronCallback = VisitorCallback;
// Simple alias to avoid heap compaction type signatures turning into
// a sea of generic |void*|s.
-using MovableReference = void*;
+using MovableReference = const void*;
// Heap compaction supports registering callbacks that are to be invoked
// when an object is moved during compaction. This is to support internal
@@ -64,6 +65,11 @@ class PLATFORM_EXPORT BlinkGC final {
STATIC_ONLY(BlinkGC);
public:
+ // CollectionType represents generational collection. kMinor collects objects
+ // in the young generation (i.e. allocated since the previous collection
+ // cycle, since we use sticky bits), kMajor collects the entire heap.
+ enum class CollectionType { kMinor, kMajor };
+
// When garbage collecting we need to know whether or not there
// can be pointers to Blink GC managed objects on the stack for
// each thread. When threads reach a safe point they record
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
index 23df65f74ed..97f4c8bf38d 100644
--- 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
@@ -25,8 +25,6 @@ class ParallelTaskRunner : public base::TaskRunner {
return true;
}
- bool RunsTasksInCurrentSequence() const override { return false; }
-
void RunUntilIdle() {}
};
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
new file mode 100644
index 00000000000..a4620eadf0a
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/card_table_test.cc
@@ -0,0 +1,181 @@
+// 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
new file mode 100644
index 00000000000..8b91764b10d
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h
@@ -0,0 +1,315 @@
+// 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_COLLECTION_SUPPORT_HEAP_HASH_TABLE_BACKING_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_COLLECTION_SUPPORT_HEAP_HASH_TABLE_BACKING_H_
+
+#include "third_party/blink/renderer/platform/heap/heap_page.h"
+#include "third_party/blink/renderer/platform/heap/threading_traits.h"
+#include "third_party/blink/renderer/platform/heap/trace_traits.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+
+namespace blink {
+
+template <typename Table>
+class HeapHashTableBacking {
+ DISALLOW_NEW();
+ IS_GARBAGE_COLLECTED_TYPE();
+
+ public:
+ template <typename Backing>
+ static void* AllocateObject(size_t size);
+
+ static void Finalize(void* pointer);
+ void FinalizeGarbageCollectedObject() { Finalize(this); }
+};
+
+template <typename Table>
+struct ThreadingTrait<HeapHashTableBacking<Table>> {
+ STATIC_ONLY(ThreadingTrait);
+ using Key = typename Table::KeyType;
+ using Value = typename Table::ValueType;
+ static const ThreadAffinity kAffinity =
+ (ThreadingTrait<Key>::kAffinity == kMainThreadOnly) &&
+ (ThreadingTrait<Value>::kAffinity == kMainThreadOnly)
+ ? kMainThreadOnly
+ : kAnyThread;
+};
+
+// static
+template <typename Table>
+template <typename Backing>
+void* HeapHashTableBacking<Table>::AllocateObject(size_t size) {
+ ThreadState* state =
+ ThreadStateFor<ThreadingTrait<Backing>::kAffinity>::GetState();
+ DCHECK(state->IsAllocationAllowed());
+ const char* type_name = WTF_HEAP_PROFILER_TYPE_NAME(Backing);
+ return state->Heap().AllocateOnArenaIndex(
+ state, size, BlinkGC::kHashTableArenaIndex, GCInfoTrait<Backing>::Index(),
+ type_name);
+}
+
+template <typename Table>
+void HeapHashTableBacking<Table>::Finalize(void* pointer) {
+ using Value = typename Table::ValueType;
+ static_assert(
+ !std::is_trivially_destructible<Value>::value,
+ "Finalization of trivially destructible classes should not happen.");
+ HeapObjectHeader* header = HeapObjectHeader::FromPayload(pointer);
+ // Use the payload size as recorded by the heap to determine how many
+ // elements to finalize.
+ size_t length = header->PayloadSize() / sizeof(Value);
+ Value* table = reinterpret_cast<Value*>(pointer);
+ for (unsigned i = 0; i < length; ++i) {
+ if (!Table::IsEmptyOrDeletedBucket(table[i]))
+ table[i].~Value();
+ }
+}
+
+template <typename Table>
+struct MakeGarbageCollectedTrait<HeapHashTableBacking<Table>> {
+ static HeapHashTableBacking<Table>* Call(size_t num_elements) {
+ CHECK_GT(num_elements, 0u);
+ void* memory = HeapHashTableBacking<Table>::template AllocateObject<
+ HeapHashTableBacking<Table>>(num_elements *
+ sizeof(typename Table::ValueType));
+ HeapObjectHeader* header = HeapObjectHeader::FromPayload(memory);
+ // Placement new as regular operator new() is deleted.
+ HeapHashTableBacking<Table>* object =
+ ::new (memory) HeapHashTableBacking<Table>();
+ header->MarkFullyConstructed<HeapObjectHeader::AccessMode::kAtomic>();
+ return object;
+ }
+};
+
+template <typename Table>
+struct FinalizerTrait<HeapHashTableBacking<Table>> {
+ STATIC_ONLY(FinalizerTrait);
+ static const bool kNonTrivialFinalizer =
+ !std::is_trivially_destructible<typename Table::ValueType>::value;
+ static void Finalize(void* obj) {
+ internal::FinalizerTraitImpl<HeapHashTableBacking<Table>,
+ kNonTrivialFinalizer>::Finalize(obj);
+ }
+};
+
+// The trace trait for the heap hashtable backing is used when we find a
+// direct pointer to the backing from the conservative stack scanner. This
+// normally indicates that there is an ongoing iteration over the table, and so
+// we disable weak processing of table entries. When the backing is found
+// through the owning hash table we mark differently, in order to do weak
+// processing.
+template <typename Table>
+struct TraceTrait<HeapHashTableBacking<Table>> {
+ STATIC_ONLY(TraceTrait);
+ using Backing = HeapHashTableBacking<Table>;
+ using ValueType = typename Table::ValueTraits::TraitType;
+ using Traits = typename Table::ValueTraits;
+
+ public:
+ static TraceDescriptor GetTraceDescriptor(const void* self) {
+ return {self, Trace<WTF::kNoWeakHandling>};
+ }
+
+ static TraceDescriptor GetWeakTraceDescriptor(const void* self) {
+ return GetWeakTraceDescriptorImpl<ValueType>::GetWeakTraceDescriptor(self);
+ }
+
+ template <WTF::WeakHandlingFlag WeakHandling = WTF::kNoWeakHandling>
+ static void Trace(Visitor* visitor, const void* self) {
+ if (visitor->ConcurrentTracingBailOut({self, &Trace}))
+ return;
+
+ static_assert(WTF::IsTraceableInCollectionTrait<Traits>::value ||
+ WTF::IsWeak<ValueType>::value,
+ "T should not be traced");
+ WTF::TraceInCollectionTrait<WeakHandling, Backing, void>::Trace(visitor,
+ self);
+ }
+
+ private:
+ template <typename ValueType>
+ struct GetWeakTraceDescriptorImpl {
+ static TraceDescriptor GetWeakTraceDescriptor(const void* backing) {
+ return {backing, nullptr};
+ }
+ };
+
+ template <typename K, typename V>
+ struct GetWeakTraceDescriptorImpl<WTF::KeyValuePair<K, V>> {
+ static TraceDescriptor GetWeakTraceDescriptor(const void* backing) {
+ return GetWeakTraceDescriptorKVPImpl<K, V>::GetWeakTraceDescriptor(
+ backing);
+ }
+
+ template <typename KeyType,
+ typename ValueType,
+ bool ephemeron_semantics = (WTF::IsWeak<KeyType>::value &&
+ !WTF::IsWeak<ValueType>::value &&
+ WTF::IsTraceable<ValueType>::value) ||
+ (WTF::IsWeak<ValueType>::value &&
+ !WTF::IsWeak<KeyType>::value &&
+ WTF::IsTraceable<KeyType>::value)>
+ struct GetWeakTraceDescriptorKVPImpl {
+ static TraceDescriptor GetWeakTraceDescriptor(const void* backing) {
+ return {backing, nullptr};
+ }
+ };
+
+ template <typename KeyType, typename ValueType>
+ struct GetWeakTraceDescriptorKVPImpl<KeyType, ValueType, true> {
+ static TraceDescriptor GetWeakTraceDescriptor(const void* backing) {
+ return {backing, Trace<WTF::kWeakHandling>};
+ }
+ };
+ };
+};
+
+} // namespace blink
+
+namespace WTF {
+
+// This trace method is for tracing a HashTableBacking either through regular
+// tracing (via the relevant TraceTraits) or when finding a HashTableBacking
+// through conservative stack scanning (which will treat all references in the
+// backing strongly).
+template <WTF::WeakHandlingFlag WeakHandling, typename Table>
+struct TraceHashTableBackingInCollectionTrait {
+ using Value = typename Table::ValueType;
+ using Traits = typename Table::ValueTraits;
+
+ static bool Trace(blink::Visitor* visitor, const void* self) {
+ static_assert(IsTraceableInCollectionTrait<Traits>::value ||
+ WTF::IsWeak<Value>::value,
+ "Table should not be traced");
+ const Value* array = reinterpret_cast<const Value*>(self);
+ blink::HeapObjectHeader* header =
+ blink::HeapObjectHeader::FromPayload(self);
+ // Use the payload size as recorded by the heap to determine how many
+ // elements to trace.
+ size_t length = header->PayloadSize() / sizeof(Value);
+ const bool is_concurrent = visitor->IsConcurrent();
+ for (size_t i = 0; i < length; ++i) {
+ // If tracing concurrently, use a concurrent-safe version of
+ // IsEmptyOrDeletedBucket (check performed on a local copy instead
+ // of directly on the bucket).
+ if (is_concurrent) {
+ if (!HashTableHelper<Value, typename Table::ExtractorType,
+ typename Table::KeyTraitsType>::
+ IsEmptyOrDeletedBucketSafe(array[i])) {
+ blink::TraceCollectionIfEnabled<WeakHandling, Value, Traits>::Trace(
+ visitor, &array[i]);
+ }
+ } else {
+ if (!HashTableHelper<Value, typename Table::ExtractorType,
+ typename Table::KeyTraitsType>::
+ IsEmptyOrDeletedBucket(array[i])) {
+ blink::TraceCollectionIfEnabled<WeakHandling, Value, Traits>::Trace(
+ visitor, &array[i]);
+ }
+ }
+ }
+ return false;
+ }
+};
+
+template <typename Table>
+struct TraceInCollectionTrait<kNoWeakHandling,
+ blink::HeapHashTableBacking<Table>,
+ void> {
+ static bool Trace(blink::Visitor* visitor, const void* self) {
+ return TraceHashTableBackingInCollectionTrait<kNoWeakHandling,
+ Table>::Trace(visitor, self);
+ }
+};
+
+template <typename Table>
+struct TraceInCollectionTrait<kWeakHandling,
+ blink::HeapHashTableBacking<Table>,
+ void> {
+ static bool Trace(blink::Visitor* visitor, const void* self) {
+ return TraceHashTableBackingInCollectionTrait<kWeakHandling, Table>::Trace(
+ visitor, self);
+ }
+};
+
+// Key value pairs, as used in HashMap. To disambiguate template choice we have
+// to have two versions, first the one with no special weak handling, then the
+// one with weak handling.
+template <typename Key, typename Value, typename Traits>
+struct TraceInCollectionTrait<kNoWeakHandling,
+ KeyValuePair<Key, Value>,
+ Traits> {
+ using EphemeronHelper =
+ blink::EphemeronKeyValuePair<Key,
+ Value,
+ typename Traits::KeyTraits,
+ typename Traits::ValueTraits>;
+
+ static bool Trace(blink::Visitor* visitor,
+ const KeyValuePair<Key, Value>& self) {
+ if (WTF::IsWeak<Key>::value != WTF::IsWeak<Value>::value) {
+ // Strongification of Weak/Strong and Strong/Weak.
+ EphemeronHelper helper(&self.key, &self.value);
+ visitor->VisitEphemeronKeyValuePair(
+ helper.key, helper.value,
+ blink::TraceCollectionIfEnabled<
+ kNoWeakHandling, typename EphemeronHelper::KeyType,
+ typename EphemeronHelper::KeyTraits>::Trace,
+ blink::TraceCollectionIfEnabled<
+ kNoWeakHandling, typename EphemeronHelper::ValueType,
+ typename EphemeronHelper::ValueTraits>::Trace);
+ } else {
+ // Strongification of 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);
+ }
+ return false;
+ }
+};
+
+template <typename Key, typename Value, typename Traits>
+struct TraceInCollectionTrait<kWeakHandling, KeyValuePair<Key, Value>, Traits> {
+ using EphemeronHelper =
+ blink::EphemeronKeyValuePair<Key,
+ Value,
+ typename Traits::KeyTraits,
+ typename Traits::ValueTraits>;
+
+ static bool IsAlive(const KeyValuePair<Key, Value>& self) {
+ // Needed for Weak/Weak, Strong/Weak (reverse ephemeron), and Weak/Strong
+ // (ephemeron). Order of invocation does not matter as tracing weak key or
+ // value does not have any side effects.
+ return blink::TraceCollectionIfEnabled<
+ WeakHandlingTrait<Key>::value, Key,
+ typename Traits::KeyTraits>::IsAlive(self.key) &&
+ blink::TraceCollectionIfEnabled<
+ WeakHandlingTrait<Value>::value, Value,
+ typename Traits::ValueTraits>::IsAlive(self.value);
+ }
+
+ static bool Trace(blink::Visitor* visitor,
+ const KeyValuePair<Key, Value>& self) {
+ EphemeronHelper helper(&self.key, &self.value);
+ return visitor->VisitEphemeronKeyValuePair(
+ helper.key, helper.value,
+ blink::TraceCollectionIfEnabled<
+ WeakHandlingTrait<typename EphemeronHelper::KeyType>::value,
+ typename EphemeronHelper::KeyType,
+ typename EphemeronHelper::KeyTraits>::Trace,
+ blink::TraceCollectionIfEnabled<
+ WeakHandlingTrait<typename EphemeronHelper::ValueType>::value,
+ typename EphemeronHelper::ValueType,
+ typename EphemeronHelper::ValueTraits>::Trace);
+ }
+};
+
+} // namespace WTF
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_COLLECTION_SUPPORT_HEAP_HASH_TABLE_BACKING_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_linked_stack.h b/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_linked_stack.h
index b1ad5a367cd..c0b4e95350a 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_linked_stack.h
+++ b/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_linked_stack.h
@@ -28,10 +28,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_LINKED_STACK_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_LINKED_STACK_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_COLLECTION_SUPPORT_HEAP_LINKED_STACK_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_COLLECTION_SUPPORT_HEAP_LINKED_STACK_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/visitor.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -44,36 +45,40 @@ namespace blink {
// (now removed: https://codereview.chromium.org/2761853003/).
// See https://codereview.chromium.org/17314010 for the original use-case.
template <typename T>
-class HeapLinkedStack : public GarbageCollected<HeapLinkedStack<T>> {
+class HeapLinkedStack final : public GarbageCollected<HeapLinkedStack<T>> {
public:
- HeapLinkedStack() : size_(0) {}
+ static void CheckType() {
+ static_assert(internal::IsMember<T>,
+ "HeapLinkedStack supports only Member.");
+ }
- bool IsEmpty();
+ HeapLinkedStack() { CheckType(); }
- void Push(const T&);
- const T& Peek();
- void Pop();
+ inline size_t size() const;
+ inline bool IsEmpty() const;
- size_t size();
+ inline void Push(const T&);
+ inline const T& Peek() const;
+ inline void Pop();
- void Trace(blink::Visitor* visitor) {
- for (Node* current = head_; current; current = current->next_)
- visitor->Trace(current);
- }
+ void Trace(Visitor* visitor) { visitor->Trace(head_); }
private:
- class Node : public GarbageCollected<Node> {
+ class Node final : public GarbageCollected<Node> {
public:
- Node(const T&, Node* next);
+ Node(const T&, Node*);
- void Trace(blink::Visitor* visitor) { visitor->Trace(data_); }
+ void Trace(Visitor* visitor) {
+ visitor->Trace(data_);
+ visitor->Trace(next_);
+ }
T data_;
Member<Node> next_;
};
Member<Node> head_;
- size_t size_;
+ size_t size_ = 0;
};
template <typename T>
@@ -81,23 +86,23 @@ HeapLinkedStack<T>::Node::Node(const T& data, Node* next)
: data_(data), next_(next) {}
template <typename T>
-inline bool HeapLinkedStack<T>::IsEmpty() {
+bool HeapLinkedStack<T>::IsEmpty() const {
return !head_;
}
template <typename T>
-inline void HeapLinkedStack<T>::Push(const T& data) {
+void HeapLinkedStack<T>::Push(const T& data) {
head_ = MakeGarbageCollected<Node>(data, head_);
++size_;
}
template <typename T>
-inline const T& HeapLinkedStack<T>::Peek() {
+const T& HeapLinkedStack<T>::Peek() const {
return head_->data_;
}
template <typename T>
-inline void HeapLinkedStack<T>::Pop() {
+void HeapLinkedStack<T>::Pop() {
DCHECK(head_);
DCHECK(size_);
head_ = head_->next_;
@@ -105,10 +110,10 @@ inline void HeapLinkedStack<T>::Pop() {
}
template <typename T>
-inline size_t HeapLinkedStack<T>::size() {
+size_t HeapLinkedStack<T>::size() const {
return size_;
}
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_LINKED_STACK_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_COLLECTION_SUPPORT_HEAP_LINKED_STACK_H_
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
new file mode 100644
index 00000000000..27b3f0dbf06
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_linked_stack_test.cc
@@ -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.
+
+#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
new file mode 100644
index 00000000000..eeba5dbc259
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h
@@ -0,0 +1,203 @@
+// 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_COLLECTION_SUPPORT_HEAP_VECTOR_BACKING_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_COLLECTION_SUPPORT_HEAP_VECTOR_BACKING_H_
+
+#include "base/logging.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"
+#include "third_party/blink/renderer/platform/heap/thread_state.h"
+#include "third_party/blink/renderer/platform/heap/threading_traits.h"
+#include "third_party/blink/renderer/platform/heap/trace_traits.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace blink {
+
+template <typename T, typename Traits = WTF::VectorTraits<T>>
+class HeapVectorBacking final {
+ DISALLOW_NEW();
+ IS_GARBAGE_COLLECTED_TYPE();
+
+ public:
+ template <typename Backing>
+ static void* AllocateObject(size_t size) {
+ ThreadState* state =
+ ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
+ DCHECK(state->IsAllocationAllowed());
+ const char* type_name = WTF_HEAP_PROFILER_TYPE_NAME(Backing);
+ return state->Heap().AllocateOnArenaIndex(
+ state, size, BlinkGC::kVectorArenaIndex, GCInfoTrait<Backing>::Index(),
+ type_name);
+ }
+
+ static void Finalize(void* pointer);
+ void FinalizeGarbageCollectedObject() { Finalize(this); }
+};
+
+template <typename T, typename Traits>
+void HeapVectorBacking<T, Traits>::Finalize(void* pointer) {
+ static_assert(Traits::kNeedsDestruction,
+ "Only vector buffers with items requiring destruction should "
+ "be finalized");
+ static_assert(
+ Traits::kCanClearUnusedSlotsWithMemset || std::is_polymorphic<T>::value,
+ "HeapVectorBacking doesn't support objects that cannot be cleared as "
+ "unused with memset or don't have a vtable");
+
+ static_assert(
+ !std::is_trivially_destructible<T>::value,
+ "Finalization of trivially destructible classes should not happen.");
+ HeapObjectHeader* header = HeapObjectHeader::FromPayload(pointer);
+ // Use the payload size as recorded by the heap to determine how many
+ // elements to finalize.
+ size_t length = header->PayloadSize() / sizeof(T);
+ char* payload = static_cast<char*>(pointer);
+#ifdef ANNOTATE_CONTIGUOUS_CONTAINER
+ ANNOTATE_CHANGE_SIZE(payload, length * sizeof(T), 0, length * sizeof(T));
+#endif
+ // As commented above, HeapVectorBacking calls finalizers for unused slots
+ // (which are already zeroed out).
+ if (std::is_polymorphic<T>::value) {
+ for (unsigned i = 0; i < length; ++i) {
+ char* element = payload + i * sizeof(T);
+ if (blink::VTableInitialized(element))
+ reinterpret_cast<T*>(element)->~T();
+ }
+ } else {
+ T* buffer = reinterpret_cast<T*>(payload);
+ for (unsigned i = 0; i < length; ++i)
+ buffer[i].~T();
+ }
+}
+
+template <typename T>
+struct MakeGarbageCollectedTrait<HeapVectorBacking<T>> {
+ static HeapVectorBacking<T>* Call(size_t num_elements) {
+ CHECK_GT(num_elements, 0u);
+ void* memory =
+ HeapVectorBacking<T>::template AllocateObject<HeapVectorBacking<T>>(
+ num_elements * sizeof(T));
+ HeapObjectHeader* header = HeapObjectHeader::FromPayload(memory);
+ // Placement new as regular operator new() is deleted.
+ HeapVectorBacking<T>* object = ::new (memory) HeapVectorBacking<T>();
+ header->MarkFullyConstructed<HeapObjectHeader::AccessMode::kAtomic>();
+ return object;
+ }
+};
+
+template <typename T, typename Traits>
+struct FinalizerTrait<HeapVectorBacking<T, Traits>> {
+ STATIC_ONLY(FinalizerTrait);
+ static const bool kNonTrivialFinalizer = Traits::kNeedsDestruction;
+ static void Finalize(void* obj) {
+ internal::FinalizerTraitImpl<HeapVectorBacking<T, Traits>,
+ kNonTrivialFinalizer>::Finalize(obj);
+ }
+};
+
+template <typename T, typename Traits>
+struct ThreadingTrait<HeapVectorBacking<T, Traits>> {
+ STATIC_ONLY(ThreadingTrait);
+ static const ThreadAffinity kAffinity = ThreadingTrait<T>::Affinity;
+};
+
+template <typename T, typename Traits>
+struct TraceTrait<HeapVectorBacking<T, Traits>> {
+ STATIC_ONLY(TraceTrait);
+ using Backing = HeapVectorBacking<T, Traits>;
+
+ public:
+ static TraceDescriptor GetTraceDescriptor(const void* self) {
+ return {self, TraceTrait<Backing>::Trace};
+ }
+
+ static void Trace(Visitor* visitor, const void* self) {
+ if (visitor->ConcurrentTracingBailOut({self, &Trace}))
+ return;
+
+ static_assert(!WTF::IsWeak<T>::value,
+ "Weakness is not supported in HeapVector and HeapDeque");
+ if (WTF::IsTraceableInCollectionTrait<Traits>::value) {
+ WTF::TraceInCollectionTrait<WTF::kNoWeakHandling,
+ HeapVectorBacking<T, Traits>,
+ void>::Trace(visitor, self);
+ }
+ }
+};
+
+} // namespace blink
+
+namespace WTF {
+
+// This trace method is used only for on-stack HeapVectors found in
+// conservative scanning. On-heap HeapVectors are traced by Vector::trace.
+template <typename T, typename Traits>
+struct TraceInCollectionTrait<kNoWeakHandling,
+ blink::HeapVectorBacking<T, Traits>,
+ void> {
+ static bool Trace(blink::Visitor* visitor, const void* self) {
+ // HeapVectorBacking does not know the exact size of the vector
+ // and just knows the capacity of the vector. Due to the constraint,
+ // HeapVectorBacking can support only the following objects:
+ //
+ // - An object that has a vtable. In this case, HeapVectorBacking
+ // traces only slots that are not zeroed out. This is because if
+ // the object has a vtable, the zeroed slot means that it is
+ // an unused slot (Remember that the unused slots are guaranteed
+ // to be zeroed out by VectorUnusedSlotClearer).
+ //
+ // - An object that can be initialized with memset. In this case,
+ // HeapVectorBacking traces all slots including unused slots.
+ // This is fine because the fact that the object can be initialized
+ // with memset indicates that it is safe to treat the zerod slot
+ // as a valid object.
+ static_assert(!IsTraceableInCollectionTrait<Traits>::value ||
+ Traits::kCanClearUnusedSlotsWithMemset ||
+ std::is_polymorphic<T>::value,
+ "HeapVectorBacking doesn't support objects that cannot be "
+ "cleared as unused with memset.");
+
+ // This trace method is instantiated for vectors where
+ // IsTraceableInCollectionTrait<Traits>::value is false, but the trace
+ // method should not be called. Thus we cannot static-assert
+ // IsTraceableInCollectionTrait<Traits>::value but should runtime-assert it.
+ DCHECK(IsTraceableInCollectionTrait<Traits>::value);
+
+ const T* array = reinterpret_cast<const T*>(self);
+ blink::HeapObjectHeader* header =
+ blink::HeapObjectHeader::FromPayload(self);
+ // Use the payload size as recorded by the heap to determine how many
+ // elements to trace.
+ size_t length = header->PayloadSize() / sizeof(T);
+#ifdef ANNOTATE_CONTIGUOUS_CONTAINER
+ // As commented above, HeapVectorBacking can trace unused slots
+ // (which are already zeroed out).
+ ANNOTATE_CHANGE_SIZE(array, length, 0, length);
+#endif
+ if (std::is_polymorphic<T>::value) {
+ const char* pointer = reinterpret_cast<const char*>(array);
+ for (unsigned i = 0; i < length; ++i) {
+ const char* element = pointer + i * sizeof(T);
+ if (blink::VTableInitialized(element)) {
+ blink::TraceIfNeeded<
+ T, IsTraceableInCollectionTrait<Traits>::value>::Trace(visitor,
+ array[i]);
+ }
+ }
+ } else {
+ for (size_t i = 0; i < length; ++i) {
+ blink::TraceIfNeeded<
+ T, IsTraceableInCollectionTrait<Traits>::value>::Trace(visitor,
+ array[i]);
+ }
+ }
+ return false;
+ }
+};
+
+} // namespace WTF
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_COLLECTION_SUPPORT_HEAP_VECTOR_BACKING_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
index af57b2607c2..8f02fc2e91c 100644
--- a/chromium/third_party/blink/renderer/platform/heap/concurrent_marking_test.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/concurrent_marking_test.cc
@@ -2,6 +2,8 @@
// 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"
@@ -31,157 +33,294 @@ class CollectionWrapper : public GarbageCollected<CollectionWrapper<T>> {
};
// =============================================================================
-// Tests that expose data races when modifying collections ================
+// Tests that expose data races when modifying collections =====================
// =============================================================================
-TEST_F(ConcurrentMarkingTest, AddToHashMap) {
+template <typename C>
+void AddToCollection() {
+ constexpr int kIterations = 100;
IncrementalMarkingTestDriver driver(ThreadState::Current());
- using Map = HeapHashMap<Member<IntegerObject>, Member<IntegerObject>>;
- Persistent<CollectionWrapper<Map>> persistent =
- MakeGarbageCollected<CollectionWrapper<Map>>();
- Map* map = persistent->GetCollection();
+ Persistent<CollectionWrapper<C>> persistent =
+ MakeGarbageCollected<CollectionWrapper<C>>();
+ C* collection = persistent->GetCollection();
driver.Start();
- for (int i = 0; i < 100; ++i) {
+ for (int i = 0; i < kIterations; ++i) {
driver.SingleConcurrentStep();
- for (int j = 0; j < 100; ++j) {
- int num = 100 * i + j;
- map->insert(MakeGarbageCollected<IntegerObject>(num),
- MakeGarbageCollected<IntegerObject>(num));
+ for (int j = 0; j < kIterations; ++j) {
+ int num = kIterations * i + j;
+ collection->insert(MakeGarbageCollected<IntegerObject>(num));
}
}
driver.FinishSteps();
driver.FinishGC();
}
-TEST_F(ConcurrentMarkingTest, RemoveFromHashMap) {
+template <typename C, typename GetLocation>
+void RemoveFromCollectionAtLocation(GetLocation location) {
+ constexpr int kIterations = 100;
IncrementalMarkingTestDriver driver(ThreadState::Current());
- using Map = HeapHashMap<Member<IntegerObject>, Member<IntegerObject>>;
- Persistent<CollectionWrapper<Map>> persistent =
- MakeGarbageCollected<CollectionWrapper<Map>>();
- Map* map = persistent->GetCollection();
- for (int i = 0; i < 10000; ++i) {
- map->insert(MakeGarbageCollected<IntegerObject>(i),
- MakeGarbageCollected<IntegerObject>(i));
+ 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 < 100; ++i) {
+ for (int i = 0; i < kIterations; ++i) {
driver.SingleConcurrentStep();
- for (int j = 0; j < 100; ++j) {
- map->erase(map->begin());
+ for (int j = 0; j < kIterations; ++j) {
+ collection->erase(location(collection));
}
}
driver.FinishSteps();
driver.FinishGC();
}
-TEST_F(ConcurrentMarkingTest, SwapHashMaps) {
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- using Map = HeapHashMap<Member<IntegerObject>, Member<IntegerObject>>;
- Persistent<CollectionWrapper<Map>> persistent =
- MakeGarbageCollected<CollectionWrapper<Map>>();
- Map* map = persistent->GetCollection();
- driver.Start();
- for (int i = 0; i < 100; ++i) {
- Map new_map;
- for (int j = 0; j < 10 * i; ++j) {
- new_map.insert(MakeGarbageCollected<IntegerObject>(j),
- MakeGarbageCollected<IntegerObject>(j));
- }
- driver.SingleConcurrentStep();
- map->swap(new_map);
- }
- driver.FinishSteps();
- driver.FinishGC();
+template <typename C>
+void RemoveFromBeginningOfCollection() {
+ RemoveFromCollectionAtLocation<C>(
+ [](C* collection) { return collection->begin(); });
}
-TEST_F(ConcurrentMarkingTest, AddToHashSet) {
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- using Set = HeapHashSet<Member<IntegerObject>>;
- Persistent<CollectionWrapper<Set>> persistent =
- MakeGarbageCollected<CollectionWrapper<Set>>();
- Set* set = persistent->GetCollection();
- driver.Start();
- for (int i = 0; i < 100; ++i) {
- driver.SingleConcurrentStep();
- for (int j = 0; j < 100; ++j) {
- int num = 100 * i + j;
- set->insert(MakeGarbageCollected<IntegerObject>(num));
+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;
}
- }
- driver.FinishSteps();
- driver.FinishGC();
+ return iterator;
+ });
+}
+
+template <typename C>
+void RemoveFromEndOfCollection() {
+ RemoveFromCollectionAtLocation<C>([](C* collection) {
+ auto iterator = collection->end();
+ return --iterator;
+ });
}
-TEST_F(ConcurrentMarkingTest, RemoveFromHashSet) {
+template <typename C>
+void ClearCollection() {
+ constexpr int kIterations = 10;
IncrementalMarkingTestDriver driver(ThreadState::Current());
- using Set = HeapHashSet<Member<IntegerObject>>;
- Persistent<CollectionWrapper<Set>> persistent =
- MakeGarbageCollected<CollectionWrapper<Set>>();
- Set* set = persistent->GetCollection();
- for (int i = 0; i < 10000; ++i) {
- set->insert(MakeGarbageCollected<IntegerObject>(i));
- }
+ Persistent<CollectionWrapper<C>> persistent =
+ MakeGarbageCollected<CollectionWrapper<C>>();
+ C* collection = persistent->GetCollection();
driver.Start();
- for (int i = 0; i < 100; ++i) {
+ for (int i = 0; i < kIterations; ++i) {
driver.SingleConcurrentStep();
- for (int j = 0; j < 100; ++j) {
- set->erase(set->begin());
+ for (int j = 0; j < kIterations; ++j) {
+ collection->insert(MakeGarbageCollected<IntegerObject>(i));
}
+ collection->clear();
}
driver.FinishSteps();
driver.FinishGC();
}
-TEST_F(ConcurrentMarkingTest, SwapHashSets) {
+template <typename C>
+void SwapCollections() {
+ constexpr int kIterations = 10;
IncrementalMarkingTestDriver driver(ThreadState::Current());
- using Set = HeapHashSet<Member<IntegerObject>>;
- Persistent<CollectionWrapper<Set>> persistent =
- MakeGarbageCollected<CollectionWrapper<Set>>();
- Set* set = persistent->GetCollection();
+ Persistent<CollectionWrapper<C>> persistent =
+ MakeGarbageCollected<CollectionWrapper<C>>();
+ C* collection = persistent->GetCollection();
driver.Start();
- for (int i = 0; i < 100; ++i) {
- Set new_set;
- for (int j = 0; j < 10 * i; ++j) {
- new_set.insert(MakeGarbageCollected<IntegerObject>(j));
+ 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();
- set->swap(new_set);
+ collection->swap(*new_collection);
}
driver.FinishSteps();
driver.FinishGC();
}
-TEST_F(ConcurrentMarkingTest, AddToVector) {
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- using V = HeapVector<Member<IntegerObject>>;
- Persistent<CollectionWrapper<V>> persistent =
- MakeGarbageCollected<CollectionWrapper<V>>();
- V* vector = persistent->GetCollection();
- driver.Start();
- for (int i = 0; i < 100; ++i) {
- driver.SingleConcurrentStep();
- for (int j = 0; j < 100; ++j) {
- int num = 100 * i + j;
- vector->push_back(MakeGarbageCollected<IntegerObject>(num));
- }
+// 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);
}
- driver.FinishSteps();
- driver.FinishGC();
+};
+
+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>>>();
}
-TEST_F(ConcurrentMarkingTest, RemoveFromVector) {
+// 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 = 100;
IncrementalMarkingTestDriver driver(ThreadState::Current());
- using V = HeapVector<Member<IntegerObject>>;
Persistent<CollectionWrapper<V>> persistent =
MakeGarbageCollected<CollectionWrapper<V>>();
V* vector = persistent->GetCollection();
- for (int i = 0; i < 10000; ++i) {
- vector->push_back(MakeGarbageCollected<IntegerObject>(i));
+ for (int i = 0; i < (kIterations * kIterations); ++i) {
+ vector->insert(MakeGarbageCollected<IntegerObject>(i));
}
driver.Start();
- for (int i = 0; i < 100; ++i) {
+ for (int i = 0; i < kIterations; ++i) {
driver.SingleConcurrentStep();
- for (int j = 0; j < 100; ++j) {
+ for (int j = 0; j < kIterations; ++j) {
vector->pop_back();
}
}
@@ -189,24 +328,160 @@ TEST_F(ConcurrentMarkingTest, RemoveFromVector) {
driver.FinishGC();
}
-TEST_F(ConcurrentMarkingTest, SwapVectors) {
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- using V = HeapVector<Member<IntegerObject>>;
- Persistent<CollectionWrapper<V>> persistent =
- MakeGarbageCollected<CollectionWrapper<V>>();
- V* vector = persistent->GetCollection();
- driver.Start();
- for (int i = 0; i < 100; ++i) {
- V new_vector;
- for (int j = 0; j < 10 * i; ++j) {
- new_vector.push_back(MakeGarbageCollected<IntegerObject>(j));
- }
- driver.SingleConcurrentStep();
- vector->swap(new_vector);
+#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);
}
- driver.FinishSteps();
- driver.FinishGC();
+};
+
+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, 100> {};
+
+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/finalizer_traits.h b/chromium/third_party/blink/renderer/platform/heap/finalizer_traits.h
index 03ff1d959fb..232c3b95b68 100644
--- a/chromium/third_party/blink/renderer/platform/heap/finalizer_traits.h
+++ b/chromium/third_party/blink/renderer/platform/heap/finalizer_traits.h
@@ -91,10 +91,6 @@ struct FinalizerTrait {
};
class HeapAllocator;
-template <typename T, typename Traits>
-class HeapVectorBacking;
-template <typename Table>
-class HeapHashTableBacking;
template <typename T, typename U, typename V>
struct FinalizerTrait<LinkedHashSet<T, U, V, HeapAllocator>> {
@@ -139,27 +135,6 @@ struct FinalizerTrait<Deque<T, inlineCapacity, HeapAllocator>> {
}
};
-template <typename Table>
-struct FinalizerTrait<HeapHashTableBacking<Table>> {
- STATIC_ONLY(FinalizerTrait);
- static const bool kNonTrivialFinalizer =
- !std::is_trivially_destructible<typename Table::ValueType>::value;
- static void Finalize(void* obj) {
- internal::FinalizerTraitImpl<HeapHashTableBacking<Table>,
- kNonTrivialFinalizer>::Finalize(obj);
- }
-};
-
-template <typename T, typename Traits>
-struct FinalizerTrait<HeapVectorBacking<T, Traits>> {
- STATIC_ONLY(FinalizerTrait);
- static const bool kNonTrivialFinalizer = Traits::kNeedsDestruction;
- static void Finalize(void* obj) {
- internal::FinalizerTraitImpl<HeapVectorBacking<T, Traits>,
- kNonTrivialFinalizer>::Finalize(obj);
- }
-};
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_FINALIZER_TRAITS_H_
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 d0f4d272e94..4f0495c4f3b 100644
--- a/chromium/third_party/blink/renderer/platform/heap/garbage_collected.h
+++ b/chromium/third_party/blink/renderer/platform/heap/garbage_collected.h
@@ -53,7 +53,7 @@ struct TraceDescriptor {
public:
// The adjusted base pointer of the object that should be traced.
- void* base_object_payload;
+ const void* base_object_payload;
// A callback for tracing the object.
TraceCallback callback;
};
diff --git a/chromium/third_party/blink/renderer/platform/heap/gc_info.cc b/chromium/third_party/blink/renderer/platform/heap/gc_info.cc
index b6ea60e7f93..61b0f2e43b3 100644
--- a/chromium/third_party/blink/renderer/platform/heap/gc_info.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/gc_info.cc
@@ -43,43 +43,46 @@ constexpr size_t MaxTableSize() {
} // namespace
GCInfoTable* GCInfoTable::global_table_ = nullptr;
-constexpr uint32_t GCInfoTable::kMaxIndex;
+constexpr GCInfoIndex GCInfoTable::kMaxIndex;
+constexpr GCInfoIndex GCInfoTable::kMinIndex;
void GCInfoTable::CreateGlobalTable() {
DEFINE_STATIC_LOCAL(GCInfoTable, table, ());
global_table_ = &table;
}
-uint32_t GCInfoTable::EnsureGCInfoIndex(
+GCInfoIndex GCInfoTable::EnsureGCInfoIndex(
const GCInfo* gc_info,
- std::atomic<uint32_t>* gc_info_index_slot) {
+ std::atomic<GCInfoIndex>* gc_info_index_slot) {
DCHECK(gc_info);
DCHECK(gc_info_index_slot);
- // Ensuring a new index involves current index adjustment as well
- // as potentially resizing the table, both operations that require
- // a lock.
+ // Ensuring a new index involves current index adjustment as well as
+ // potentially resizing the table. For simplicity we use a lock.
MutexLocker locker(table_mutex_);
- // If more than one thread ends up allocating a slot for
- // the same GCInfo, have later threads reuse the slot
- // allocated by the first.
- uint32_t gc_info_index = gc_info_index_slot->load(std::memory_order_acquire);
+ // If more than one thread ends up allocating a slot for the same GCInfo, have
+ // later threads reuse the slot allocated by the first.
+ GCInfoIndex gc_info_index =
+ gc_info_index_slot->load(std::memory_order_relaxed);
if (gc_info_index)
return gc_info_index;
- gc_info_index = ++current_index_;
- CHECK(gc_info_index < GCInfoTable::kMaxIndex);
- if (current_index_ >= limit_)
+ if (current_index_ == limit_)
Resize();
+ gc_info_index = current_index_++;
+ CHECK_LT(gc_info_index, GCInfoTable::kMaxIndex);
+
table_[gc_info_index] = gc_info;
gc_info_index_slot->store(gc_info_index, std::memory_order_release);
return gc_info_index;
}
void GCInfoTable::Resize() {
- const size_t new_limit = (limit_) ? 2 * limit_ : ComputeInitialTableLimit();
+ const GCInfoIndex new_limit =
+ (limit_) ? 2 * limit_ : ComputeInitialTableLimit();
+ CHECK_GT(new_limit, limit_);
const size_t old_committed_size = limit_ * kEntrySize;
const size_t new_committed_size = new_limit * kEntrySize;
CHECK(table_);
@@ -107,11 +110,10 @@ void GCInfoTable::Resize() {
}
#endif // DCHECK_IS_ON()
- limit_ = static_cast<uint32_t>(new_limit);
+ limit_ = new_limit;
}
GCInfoTable::GCInfoTable() {
- CHECK(!table_);
table_ = reinterpret_cast<GCInfo const**>(base::AllocPages(
nullptr, MaxTableSize(), base::kPageAllocationGranularity,
base::PageInaccessible, base::PageTag::kBlinkGC));
@@ -119,16 +121,4 @@ GCInfoTable::GCInfoTable() {
Resize();
}
-#if DCHECK_IS_ON()
-void AssertObjectHasGCInfo(const void* payload, size_t gc_info_index) {
- HeapObjectHeader::CheckFromPayload(payload);
-#if !defined(COMPONENT_BUILD)
- // On component builds we cannot compare the gcInfos as they are statically
- // defined in each of the components and hence will not match.
- DCHECK_EQ(HeapObjectHeader::FromPayload(payload)->GcInfoIndex(),
- gc_info_index);
-#endif
-}
-#endif
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/gc_info.h b/chromium/third_party/blink/renderer/platform/heap/gc_info.h
index 36b53cc0c17..cf4d5a01c94 100644
--- a/chromium/third_party/blink/renderer/platform/heap/gc_info.h
+++ b/chromium/third_party/blink/renderer/platform/heap/gc_info.h
@@ -9,35 +9,26 @@
#include "base/gtest_prod_util.h"
#include "third_party/blink/renderer/platform/heap/finalizer_traits.h"
#include "third_party/blink/renderer/platform/heap/name_traits.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"
-#include "third_party/blink/renderer/platform/wtf/deque.h"
-#include "third_party/blink/renderer/platform/wtf/hash_counted_set.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/hash_table.h"
-#include "third_party/blink/renderer/platform/wtf/linked_hash_set.h"
-#include "third_party/blink/renderer/platform/wtf/list_hash_set.h"
-#include "third_party/blink/renderer/platform/wtf/type_traits.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
+template <typename T>
+struct TraceTrait;
+
+using GCInfoIndex = uint32_t;
+
// GCInfo contains metadata for objects that are instantiated from classes that
// inherit from GarbageCollected.
-struct GCInfo {
+struct PLATFORM_EXPORT GCInfo final {
+ static inline const GCInfo& From(GCInfoIndex);
+
const TraceCallback trace;
const FinalizationCallback finalize;
const NameCallback name;
const bool has_v_table;
};
-#if DCHECK_IS_ON()
-PLATFORM_EXPORT void AssertObjectHasGCInfo(const void*, uint32_t gc_info_index);
-#endif
-
-class PLATFORM_EXPORT GCInfoTable {
+class PLATFORM_EXPORT GCInfoTable final {
public:
// At maximum |kMaxIndex - 1| indices are supported.
//
@@ -46,29 +37,36 @@ class PLATFORM_EXPORT GCInfoTable {
// of the Oilpan GC Clang plugin, there appear to be at most about 6,000
// types. Thus 14 bits should be more than twice as many bits as we will ever
// need.
- static constexpr uint32_t kMaxIndex = 1 << 14;
+ static constexpr GCInfoIndex kMaxIndex = 1 << 14;
+
+ // Minimum index returned. Values smaller |kMinIndex| may be used as
+ // sentinels.
+ static constexpr GCInfoIndex kMinIndex = 1;
// Sets up a singleton table that can be acquired using Get().
static void CreateGlobalTable();
- static GCInfoTable& Get() { return *global_table_; }
+ static GCInfoTable* GetMutable() { return global_table_; }
+ static const GCInfoTable& Get() { return *global_table_; }
- inline const GCInfo* GCInfoFromIndex(uint32_t index) {
- DCHECK_GE(index, 1u);
+ const GCInfo& GCInfoFromIndex(GCInfoIndex index) const {
+ DCHECK_GE(index, kMinIndex);
DCHECK_LT(index, kMaxIndex);
DCHECK(table_);
const GCInfo* info = table_[index];
DCHECK(info);
- return info;
+ return *info;
}
- uint32_t EnsureGCInfoIndex(const GCInfo*, std::atomic<std::uint32_t>*);
+ GCInfoIndex EnsureGCInfoIndex(const GCInfo*, std::atomic<GCInfoIndex>*);
- uint32_t GcInfoIndex() const { return current_index_; }
+ // Returns the number of recorded GCInfo objects, including |kMinIndex|.
+ GCInfoIndex NumberOfGCInfos() const { return current_index_; }
private:
FRIEND_TEST_ALL_PREFIXES(GCInfoTest, InitialEmpty);
FRIEND_TEST_ALL_PREFIXES(GCInfoTest, ResizeToMaxIndex);
+ FRIEND_TEST_ALL_PREFIXES(GCInfoDeathTest, MoreThanMaxIndexInfos);
// Singleton for each process. Retrieved through Get().
static GCInfoTable* global_table_;
@@ -83,20 +81,25 @@ class PLATFORM_EXPORT GCInfoTable {
// index into this table.
const GCInfo** table_ = nullptr;
- // GCInfo indices start from 1 for heap objects, with 0 being treated
- // specially as the index for freelist entries and large heap objects.
- uint32_t current_index_ = 0;
+ // Current index used when requiring a new GCInfo object.
+ GCInfoIndex current_index_ = kMinIndex;
// The limit (exclusive) of the currently allocated table.
- uint32_t limit_ = 0;
+ GCInfoIndex limit_ = 0;
Mutex table_mutex_;
};
+// static
+const GCInfo& GCInfo::From(GCInfoIndex index) {
+ return GCInfoTable::Get().GCInfoFromIndex(index);
+}
+
template <typename T>
struct GCInfoTrait {
STATIC_ONLY(GCInfoTrait);
- static uint32_t Index() {
+
+ static GCInfoIndex Index() {
static_assert(sizeof(T), "T must be fully defined");
static const GCInfo kGcInfo = {
TraceTrait<T>::Trace,
@@ -105,11 +108,13 @@ struct GCInfoTrait {
NameTrait<T>::GetName, std::is_polymorphic<T>::value};
// This is more complicated than using threadsafe initialization, but this
// is instantiated many times (once for every GC type).
- static std::atomic<std::uint32_t> gc_info_index{0};
- uint32_t index = gc_info_index.load(std::memory_order_acquire);
- if (!index)
- index = GCInfoTable::Get().EnsureGCInfoIndex(&kGcInfo, &gc_info_index);
- DCHECK_GE(index, 1u);
+ static std::atomic<GCInfoIndex> gc_info_index{0};
+ GCInfoIndex index = gc_info_index.load(std::memory_order_acquire);
+ if (!index) {
+ index = GCInfoTable::GetMutable()->EnsureGCInfoIndex(&kGcInfo,
+ &gc_info_index);
+ }
+ DCHECK_GE(index, GCInfoTable::kMinIndex);
DCHECK_LT(index, GCInfoTable::kMaxIndex);
return index;
}
@@ -118,49 +123,6 @@ struct GCInfoTrait {
template <typename U>
class GCInfoTrait<const U> : public GCInfoTrait<U> {};
-template <typename T, typename U, typename V, typename W, typename X>
-class HeapHashMap;
-template <typename T, typename U, typename V>
-class HeapHashSet;
-template <typename T, typename U, typename V>
-class HeapLinkedHashSet;
-template <typename T, wtf_size_t inlineCapacity, typename U>
-class HeapListHashSet;
-template <typename ValueArg, wtf_size_t inlineCapacity>
-class HeapListHashSetAllocator;
-template <typename T, wtf_size_t inlineCapacity>
-class HeapVector;
-template <typename T, wtf_size_t inlineCapacity>
-class HeapDeque;
-template <typename T, typename U, typename V>
-class HeapHashCountedSet;
-
-template <typename T, typename U, typename V, typename W, typename X>
-struct GCInfoTrait<HeapHashMap<T, U, V, W, X>>
- : public GCInfoTrait<HashMap<T, U, V, W, X, HeapAllocator>> {};
-template <typename T, typename U, typename V>
-struct GCInfoTrait<HeapHashSet<T, U, V>>
- : public GCInfoTrait<HashSet<T, U, V, HeapAllocator>> {};
-template <typename T, typename U, typename V>
-struct GCInfoTrait<HeapLinkedHashSet<T, U, V>>
- : public GCInfoTrait<LinkedHashSet<T, U, V, HeapAllocator>> {};
-template <typename T, wtf_size_t inlineCapacity, typename U>
-struct GCInfoTrait<HeapListHashSet<T, inlineCapacity, U>>
- : public GCInfoTrait<
- ListHashSet<T,
- inlineCapacity,
- U,
- HeapListHashSetAllocator<T, inlineCapacity>>> {};
-template <typename T, wtf_size_t inlineCapacity>
-struct GCInfoTrait<HeapVector<T, inlineCapacity>>
- : public GCInfoTrait<Vector<T, inlineCapacity, HeapAllocator>> {};
-template <typename T, wtf_size_t inlineCapacity>
-struct GCInfoTrait<HeapDeque<T, inlineCapacity>>
- : public GCInfoTrait<Deque<T, inlineCapacity, HeapAllocator>> {};
-template <typename T, typename U, typename V>
-struct GCInfoTrait<HeapHashCountedSet<T, U, V>>
- : public GCInfoTrait<HashCountedSet<T, U, V, HeapAllocator>> {};
-
} // namespace blink
#endif
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
index d6786ef34ab..0a4e667c914 100644
--- a/chromium/third_party/blink/renderer/platform/heap/gc_info_test.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/gc_info_test.cc
@@ -10,20 +10,36 @@ namespace blink {
TEST(GCInfoTest, InitialEmpty) {
GCInfoTable table;
- EXPECT_EQ(0u, table.GcInfoIndex());
+ EXPECT_EQ(GCInfoTable::kMinIndex, table.NumberOfGCInfos());
}
TEST(GCInfoTest, ResizeToMaxIndex) {
GCInfoTable table;
GCInfo info = {nullptr, nullptr, nullptr, false};
- std::atomic<std::uint32_t> slot{0};
- for (uint32_t i = 0; i < (GCInfoTable::kMaxIndex - 1); i++) {
+ std::atomic<GCInfoIndex> slot{0};
+ for (GCInfoIndex i = GCInfoTable::kMinIndex; i < GCInfoTable::kMaxIndex;
+ i++) {
slot = 0;
- uint32_t index = table.EnsureGCInfoIndex(&info, &slot);
+ GCInfoIndex index = table.EnsureGCInfoIndex(&info, &slot);
EXPECT_EQ(index, slot);
EXPECT_LT(0u, slot);
- EXPECT_EQ(&info, table.GCInfoFromIndex(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 6f4ce3f280d..b1c28d9798c 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap.cc
@@ -102,8 +102,9 @@ ThreadHeap::ThreadHeap(ThreadState* thread_state)
main_thread_heap_ = this;
for (int arena_index = 0; arena_index < BlinkGC::kLargeObjectArenaIndex;
- arena_index++)
+ arena_index++) {
arenas_[arena_index] = new NormalPageArena(thread_state_, arena_index);
+ }
arenas_[BlinkGC::kLargeObjectArenaIndex] =
new LargeObjectArena(thread_state_, BlinkGC::kLargeObjectArenaIndex);
@@ -138,18 +139,47 @@ Address ThreadHeap::CheckAndMarkPointer(MarkingVisitor* visitor,
return nullptr;
}
-void ThreadHeap::SetupWorklists() {
+void ThreadHeap::VisitRememberedSets(MarkingVisitor* visitor) {
+ static_assert(BlinkGC::kLargeObjectArenaIndex + 1 == BlinkGC::kNumberOfArenas,
+ "LargeObject arena must be the last one.");
+ const auto visit_header = [visitor](HeapObjectHeader* header) {
+ // Process only old objects.
+ if (header->IsOld<HeapObjectHeader::AccessMode::kNonAtomic>()) {
+ // The design of young generation requires collections to be executed at
+ // the top level (with the guarantee that no objects are currently being
+ // in construction). This can be ensured by running young GCs from safe
+ // points or by reintroducing nested allocation scopes that avoid
+ // finalization.
+ DCHECK(header->IsMarked());
+ DCHECK(!MarkingVisitor::IsInConstruction(header));
+ const GCInfo& gc_info = GCInfo::From(header->GcInfoIndex());
+ gc_info.trace(visitor, header->Payload());
+ }
+ };
+ for (size_t i = 0; i < BlinkGC::kLargeObjectArenaIndex; ++i) {
+ static_cast<NormalPageArena*>(arenas_[i])
+ ->IterateAndClearCardTables(visit_header);
+ }
+ static_cast<LargeObjectArena*>(arenas_[BlinkGC::kLargeObjectArenaIndex])
+ ->IterateAndClearRememberedPages(visit_header);
+}
+
+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());
- movable_reference_worklist_.reset(new MovableReferenceWorklist());
weak_table_worklist_.reset(new WeakTableWorklist);
- backing_store_callback_worklist_.reset(new BackingStoreCallbackWorklist());
v8_references_worklist_.reset(new V8ReferencesWorklist());
+ not_safe_to_concurrently_trace_worklist_.reset(
+ new NotSafeToConcurrentlyTraceWorklist());
DCHECK(ephemeron_callbacks_.IsEmpty());
+ if (should_initialize_compaction_worklists) {
+ movable_reference_worklist_.reset(new MovableReferenceWorklist());
+ backing_store_callback_worklist_.reset(new BackingStoreCallbackWorklist());
+ }
}
void ThreadHeap::DestroyMarkingWorklists(BlinkGC::StackState stack_state) {
@@ -159,6 +189,7 @@ void ThreadHeap::DestroyMarkingWorklists(BlinkGC::StackState stack_state) {
weak_callback_worklist_.reset(nullptr);
weak_table_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.
@@ -201,8 +232,8 @@ HeapCompact* ThreadHeap::Compaction() {
return compaction_.get();
}
-bool ThreadHeap::ShouldRegisterMovingAddress(Address address) {
- return Compaction()->ShouldRegisterMovingAddress(address);
+bool ThreadHeap::ShouldRegisterMovingAddress() {
+ return Compaction()->ShouldRegisterMovingAddress();
}
void ThreadHeap::FlushNotFullyConstructedObjects() {
@@ -226,40 +257,8 @@ void ThreadHeap::MarkNotFullyConstructedObjects(MarkingVisitor* visitor) {
while (not_fully_constructed_worklist_->Pop(WorklistTaskId::MutatorThread,
&item)) {
BasePage* const page = PageFromObject(item);
- visitor->ConservativelyMarkAddress(page, reinterpret_cast<Address>(item));
- }
-}
-
-void ThreadHeap::InvokeEphemeronCallbacks(MarkingVisitor* visitor) {
- // 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.
- for (auto& tuple : ephemeron_callbacks_)
- tuple.value(visitor, tuple.key);
-
- 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).
- while (
- !weak_table_worklist_->IsLocalViewEmpty(WorklistTaskId::MutatorThread)) {
- // Read ephemeron callbacks from worklist to ephemeron_callbacks_ hashmap.
- WeakTableWorklist::View ephemerons_worklist(weak_table_worklist_.get(),
- WorklistTaskId::MutatorThread);
- WeakTableItem item;
- while (ephemerons_worklist.Pop(&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);
- }
- }
+ visitor->ConservativelyMarkAddress(page,
+ reinterpret_cast<ConstAddress>(item));
}
}
@@ -288,6 +287,45 @@ bool DrainWorklistWithDeadline(base::TimeTicks deadline,
} // namespace
+bool ThreadHeap::InvokeEphemeronCallbacks(MarkingVisitor* visitor,
+ base::TimeTicks deadline) {
+ // 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);
+ }
+ },
+ WorklistTaskId::MutatorThread);
+}
+
bool ThreadHeap::AdvanceMarking(MarkingVisitor* visitor,
base::TimeTicks deadline) {
DCHECK_EQ(WorklistTaskId::MutatorThread, visitor->task_id());
@@ -301,6 +339,39 @@ bool ThreadHeap::AdvanceMarking(MarkingVisitor* visitor,
ThreadHeapStatsCollector::Scope stats_scope(
stats_collector(), ThreadHeapStatsCollector::kMarkProcessWorklist);
+ // 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);
+ finished = DrainWorklistWithDeadline(
+ deadline, not_safe_to_concurrently_trace_worklist_.get(),
+ [visitor](const MarkingItem& item) {
+ item.callback(visitor, item.base_object_payload);
+ },
+ WorklistTaskId::MutatorThread);
+ if (!finished)
+ break;
+ }
+
+ finished = FlushV8References(deadline);
+ if (!finished)
+ break;
+
finished = DrainWorklistWithDeadline(
deadline, marking_worklist_.get(),
[visitor](const MarkingItem& item) {
@@ -318,66 +389,61 @@ bool ThreadHeap::AdvanceMarking(MarkingVisitor* visitor,
deadline, write_barrier_worklist_.get(),
[visitor](HeapObjectHeader* header) {
DCHECK(!MarkingVisitor::IsInConstruction(header));
- GCInfoTable::Get()
- .GCInfoFromIndex(header->GcInfoIndex())
- ->trace(visitor, header->Payload());
+ GCInfo::From(header->GcInfoIndex())
+ .trace(visitor, header->Payload());
visitor->AccountMarkedBytes(header);
},
WorklistTaskId::MutatorThread);
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](const NotFullyConstructedItem& item) {
- visitor->DynamicallyMarkAddress(reinterpret_cast<Address>(item));
- },
- WorklistTaskId::MutatorThread);
- if (!finished)
- break;
}
- InvokeEphemeronCallbacks(visitor);
+ finished = InvokeEphemeronCallbacks(visitor, deadline);
+ if (!finished)
+ break;
// Rerun loop if ephemeron processing queued more objects for tracing.
} while (!marking_worklist_->IsLocalViewEmpty(WorklistTaskId::MutatorThread));
- FlushV8References();
-
return finished;
}
+bool ThreadHeap::HasWorkForConcurrentMarking() const {
+ return !marking_worklist_->IsGlobalPoolEmpty() ||
+ !write_barrier_worklist_->IsGlobalPoolEmpty();
+}
+
bool ThreadHeap::AdvanceConcurrentMarking(ConcurrentMarkingVisitor* visitor,
base::TimeTicks deadline) {
- bool finished = false;
- // Iteratively mark all objects that are reachable from the objects
- // currently pushed onto the marking worklist.
- finished = DrainWorklistWithDeadline(
- deadline, marking_worklist_.get(),
- [visitor](const MarkingItem& item) {
- HeapObjectHeader* header =
- HeapObjectHeader::FromPayload(item.base_object_payload);
- DCHECK(!ConcurrentMarkingVisitor::IsInConstruction(header));
- item.callback(visitor, item.base_object_payload);
- visitor->AccountMarkedBytes(header);
- },
- visitor->task_id());
- if (!finished)
- return false;
-
- finished = DrainWorklistWithDeadline(
- deadline, write_barrier_worklist_.get(),
- [visitor](HeapObjectHeader* header) {
- DCHECK(!ConcurrentMarkingVisitor::IsInConstruction(header));
- GCInfoTable::Get()
- .GCInfoFromIndex(header->GcInfoIndex())
- ->trace(visitor, header->Payload());
- visitor->AccountMarkedBytes(header);
- },
- visitor->task_id());
+ bool finished;
+ do {
+ // Iteratively mark all objects that are reachable from the objects
+ // currently pushed onto the marking worklist.
+ finished = DrainWorklistWithDeadline(
+ deadline, marking_worklist_.get(),
+ [visitor](const MarkingItem& item) {
+ HeapObjectHeader* header =
+ HeapObjectHeader::FromPayload(item.base_object_payload);
+ DCHECK(!ConcurrentMarkingVisitor::IsInConstruction(header));
+ item.callback(visitor, item.base_object_payload);
+ visitor->AccountMarkedBytesSafe(header);
+ },
+ visitor->task_id());
+ if (!finished)
+ break;
+
+ finished = DrainWorklistWithDeadline(
+ deadline, write_barrier_worklist_.get(),
+ [visitor](HeapObjectHeader* header) {
+ DCHECK(!ConcurrentMarkingVisitor::IsInConstruction(header));
+ GCInfo::From(header->GcInfoIndex()).trace(visitor, header->Payload());
+ visitor->AccountMarkedBytesSafe(header);
+ },
+ visitor->task_id());
+ if (!finished)
+ break;
+ } while (HasWorkForConcurrentMarking());
+
return finished;
}
@@ -413,7 +479,7 @@ size_t ThreadHeap::ObjectPayloadSizeForTesting() {
size_t object_payload_size = 0;
thread_state_->SetGCPhase(ThreadState::GCPhase::kMarking);
thread_state_->Heap().MakeConsistentForGC();
- thread_state_->Heap().PrepareForSweep();
+ thread_state_->Heap().PrepareForSweep(BlinkGC::CollectionType::kMajor);
for (int i = 0; i < BlinkGC::kNumberOfArenas; ++i)
object_payload_size += arenas_[i]->ObjectPayloadSizeForTesting();
MakeConsistentForMutator();
@@ -427,7 +493,7 @@ void ThreadHeap::ResetAllocationPointForTesting() {
arenas_[i]->ResetAllocationPoint();
}
-BasePage* ThreadHeap::LookupPageForAddress(Address address) {
+BasePage* ThreadHeap::LookupPageForAddress(ConstAddress address) {
if (PageMemoryRegion* region = region_tree_->Lookup(address)) {
return region->PageFromAddress(address);
}
@@ -436,14 +502,23 @@ BasePage* ThreadHeap::LookupPageForAddress(Address address) {
void ThreadHeap::MakeConsistentForGC() {
DCHECK(thread_state_->InAtomicMarkingPause());
- for (int i = 0; i < BlinkGC::kNumberOfArenas; ++i)
- arenas_[i]->MakeConsistentForGC();
+ for (BaseArena* arena : arenas_) {
+ arena->MakeConsistentForGC();
+ }
}
void ThreadHeap::MakeConsistentForMutator() {
DCHECK(thread_state_->InAtomicMarkingPause());
- for (int i = 0; i < BlinkGC::kNumberOfArenas; ++i)
- arenas_[i]->MakeConsistentForMutator();
+ for (BaseArena* arena : arenas_) {
+ arena->MakeConsistentForMutator();
+ }
+}
+
+void ThreadHeap::Unmark() {
+ DCHECK(thread_state_->InAtomicMarkingPause());
+ for (BaseArena* arena : arenas_) {
+ arena->Unmark();
+ }
}
void ThreadHeap::Compact() {
@@ -468,11 +543,11 @@ void ThreadHeap::Compact() {
Compaction()->Finish();
}
-void ThreadHeap::PrepareForSweep() {
+void ThreadHeap::PrepareForSweep(BlinkGC::CollectionType collection_type) {
DCHECK(thread_state_->InAtomicMarkingPause());
DCHECK(thread_state_->CheckThread());
for (int i = 0; i < BlinkGC::kNumberOfArenas; i++)
- arenas_[i]->PrepareForSweep();
+ arenas_[i]->PrepareForSweep(collection_type);
}
void ThreadHeap::RemoveAllPages() {
@@ -519,45 +594,53 @@ void ThreadHeap::CollectStatistics(ThreadState::Statistics* stats) {
#undef SNAPSHOT_ARENA
}
-bool ThreadHeap::AdvanceSweep(SweepingType sweeping_type,
- base::TimeTicks deadline) {
+bool ThreadHeap::AdvanceLazySweep(base::TimeTicks deadline) {
static constexpr base::TimeDelta slack = base::TimeDelta::FromSecondsD(0.001);
- auto sweeping_function = sweeping_type == SweepingType::kMutator
- ? &BaseArena::LazySweepWithDeadline
- : &BaseArena::ConcurrentSweepWithDeadline;
for (size_t i = 0; i < BlinkGC::kNumberOfArenas; i++) {
// lazySweepWithDeadline() won't check the deadline until it sweeps
// 10 pages. So we give a small slack for safety.
const base::TimeDelta remaining_budget =
deadline - slack - base::TimeTicks::Now();
if (remaining_budget <= base::TimeDelta() ||
- !(arenas_[i]->*sweeping_function)(deadline)) {
+ !arenas_[i]->LazySweepWithDeadline(deadline)) {
return false;
}
}
return true;
}
+bool ThreadHeap::AdvanceConcurrentSweep(base::JobDelegate* job) {
+ for (size_t i = 0; i < BlinkGC::kNumberOfArenas; i++) {
+ while (!arenas_[i]->ConcurrentSweepOnePage()) {
+ if (job->ShouldYield())
+ return false;
+ }
+ }
+ return true;
+}
+
// TODO(omerkatz): Temporary solution until concurrent marking is ready. see
// https://crrev.com/c/1730054 for details. Eventually this will be removed.
-void ThreadHeap::FlushV8References() {
+bool ThreadHeap::FlushV8References(base::TimeTicks deadline) {
if (!thread_state_->IsUnifiedGCMarkingInProgress())
- return;
+ return true;
DCHECK(base::FeatureList::IsEnabled(
blink::features::kBlinkHeapConcurrentMarking) ||
v8_references_worklist_->IsGlobalEmpty());
- V8ReferencesWorklist::View v8_references(v8_references_worklist_.get(),
- WorklistTaskId::MutatorThread);
- V8Reference reference;
v8::EmbedderHeapTracer* controller =
reinterpret_cast<v8::EmbedderHeapTracer*>(
thread_state_->unified_heap_controller());
- while (v8_references.Pop(&reference)) {
- controller->RegisterEmbedderReference(
- reference->template Cast<v8::Data>().Get());
- }
+ return DrainWorklistWithDeadline(
+ deadline, v8_references_worklist_.get(),
+ [controller](const V8Reference& reference) {
+ if (!reference->Get().IsEmpty()) {
+ controller->RegisterEmbedderReference(
+ reference->template Cast<v8::Data>().Get());
+ }
+ },
+ WorklistTaskId::MutatorThread);
}
ThreadHeap* ThreadHeap::main_thread_heap_ = nullptr;
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap.h b/chromium/third_party/blink/renderer/platform/heap/heap.h
index 5fa69d97c07..953dd7839f0 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap.h
+++ b/chromium/third_party/blink/renderer/platform/heap/heap.h
@@ -68,17 +68,17 @@ class ProcessHeapReporter;
class RegionTree;
using MarkingItem = TraceDescriptor;
-using NotFullyConstructedItem = void*;
+using NotFullyConstructedItem = const void*;
using WeakTableItem = MarkingItem;
struct BackingStoreCallbackItem {
- void* backing;
+ const void* backing;
MovingObjectCallback callback;
};
struct CustomCallbackItem {
WeakCallback callback;
- void* parameter;
+ const void* parameter;
};
using V8Reference = const TraceWrapperV8Reference<v8::Value>*;
@@ -86,19 +86,21 @@ using V8Reference = const TraceWrapperV8Reference<v8::Value>*;
// Segment size of 512 entries necessary to avoid throughput regressions. Since
// the work list is currently a temporary object this is not a problem.
using MarkingWorklist = Worklist<MarkingItem, 512 /* local entries */>;
-using WriteBarrierWorklist = Worklist<HeapObjectHeader*, 256>;
+using WriteBarrierWorklist = Worklist<HeapObjectHeader*, 64>;
using NotFullyConstructedWorklist =
Worklist<NotFullyConstructedItem, 16 /* local entries */>;
using WeakCallbackWorklist =
- Worklist<CustomCallbackItem, 256 /* local entries */>;
+ Worklist<CustomCallbackItem, 64 /* local entries */>;
// Using large local segments here (sized 512 entries) to avoid throughput
// regressions.
using MovableReferenceWorklist =
- Worklist<MovableReference*, 512 /* local entries */>;
+ Worklist<const MovableReference*, 256 /* local entries */>;
using WeakTableWorklist = Worklist<WeakTableItem, 16 /* local entries */>;
using BackingStoreCallbackWorklist =
Worklist<BackingStoreCallbackItem, 16 /* local entries */>;
using V8ReferencesWorklist = Worklist<V8Reference, 16 /* local entries */>;
+using NotSafeToConcurrentlyTraceWorklist =
+ Worklist<MarkingItem, 64 /* local entries */>;
class PLATFORM_EXPORT HeapAllocHooks {
STATIC_ONLY(HeapAllocHooks);
@@ -260,6 +262,10 @@ class PLATFORM_EXPORT ThreadHeap {
return v8_references_worklist_.get();
}
+ NotSafeToConcurrentlyTraceWorklist* GetNotSafeToConcurrentlyTraceWorklist()
+ const {
+ return not_safe_to_concurrently_trace_worklist_.get();
+ }
// Register an ephemeron table for fixed-point iteration.
void RegisterWeakTable(void* container_object,
EphemeronCallback);
@@ -268,7 +274,7 @@ class PLATFORM_EXPORT ThreadHeap {
// Checks whether we need to register |addr| as a backing store or a slot
// containing reference to it.
- bool ShouldRegisterMovingAddress(Address addr);
+ bool ShouldRegisterMovingAddress();
RegionTree* GetRegionTree() { return region_tree_.get(); }
@@ -302,6 +308,8 @@ class PLATFORM_EXPORT ThreadHeap {
bool AdvanceMarking(MarkingVisitor*, base::TimeTicks deadline);
void VerifyMarking();
+ // Returns true if concurrent markers will have work to steal
+ bool HasWorkForConcurrentMarking() const;
// Returns true if marker is done
bool AdvanceConcurrentMarking(ConcurrentMarkingVisitor*, base::TimeTicks);
@@ -309,6 +317,9 @@ class PLATFORM_EXPORT ThreadHeap {
// thread heaps. If so marks the object pointed to as live.
Address CheckAndMarkPointer(MarkingVisitor*, Address);
+ // Visits remembered sets.
+ void VisitRememberedSets(MarkingVisitor*);
+
size_t ObjectPayloadSizeForTesting();
void ResetAllocationPointForTesting();
@@ -317,7 +328,7 @@ class PLATFORM_EXPORT ThreadHeap {
// This look-up uses the region search tree and a negative contains cache to
// provide an efficient mapping from arbitrary addresses to the containing
// heap-page if one exists.
- BasePage* LookupPageForAddress(Address);
+ BasePage* LookupPageForAddress(ConstAddress);
HeapCompact* Compaction();
@@ -341,12 +352,16 @@ class PLATFORM_EXPORT ThreadHeap {
// the executions of mutators.
void MakeConsistentForMutator();
+ // Unmarks all objects in the entire heap. This is supposed to be called in
+ // the beginning of major GC.
+ void Unmark();
+
void Compact();
- enum class SweepingType : uint8_t { kMutator, kConcurrent };
- bool AdvanceSweep(SweepingType sweeping_type, base::TimeTicks deadline);
+ bool AdvanceLazySweep(base::TimeTicks deadline);
+ bool AdvanceConcurrentSweep(base::JobDelegate*);
- void PrepareForSweep();
+ void PrepareForSweep(BlinkGC::CollectionType);
void RemoveAllPages();
void InvokeFinalizersOnSweptPages();
void CompleteSweep();
@@ -374,16 +389,24 @@ class PLATFORM_EXPORT ThreadHeap {
PageBloomFilter* page_bloom_filter() { return page_bloom_filter_.get(); }
+ bool IsInLastAllocatedRegion(Address address) const;
+ void SetLastAllocatedRegion(Address start, size_t length);
+
private:
+ struct LastAllocatedRegion {
+ Address start = nullptr;
+ size_t length = 0;
+ };
+
static int ArenaIndexForObjectSize(size_t);
- void SetupWorklists();
+ void SetupWorklists(bool);
void DestroyMarkingWorklists(BlinkGC::StackState);
void DestroyCompactionWorklists();
- void InvokeEphemeronCallbacks(MarkingVisitor*);
+ bool InvokeEphemeronCallbacks(MarkingVisitor*, base::TimeTicks);
- void FlushV8References();
+ bool FlushV8References(base::TimeTicks);
ThreadState* thread_state_;
std::unique_ptr<ThreadHeapStatsCollector> heap_stats_collector_;
@@ -436,12 +459,17 @@ class PLATFORM_EXPORT ThreadHeap {
// to V8.
std::unique_ptr<V8ReferencesWorklist> v8_references_worklist_;
+ 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<void*, EphemeronCallback> ephemeron_callbacks_;
+ WTF::HashMap<const void*, EphemeronCallback> ephemeron_callbacks_;
std::unique_ptr<HeapCompact> compaction_;
+ LastAllocatedRegion last_allocated_region_;
+
BaseArena* arenas_[BlinkGC::kNumberOfArenas];
static ThreadHeap* main_thread_heap_;
@@ -457,31 +485,22 @@ template <typename T>
class GarbageCollected {
IS_GARBAGE_COLLECTED_TYPE();
- // For now direct allocation of arrays on the heap is not allowed.
- void* operator new[](size_t size);
-
-#if defined(OS_WIN) && defined(COMPILER_MSVC)
- // Due to some quirkiness in the MSVC compiler we have to provide
- // the delete[] operator in the GarbageCollected subclasses as it
- // is called when a class is exported in a DLL.
- protected:
- void operator delete[](void* p) { NOTREACHED(); }
-#else
- void operator delete[](void* p);
-#endif
-
public:
using ParentMostGarbageCollectedType = T;
- void* operator new(size_t size) = delete; // Must use MakeGarbageCollected.
+ // Must use MakeGarbageCollected.
+ void* operator new(size_t) = delete;
+ void* operator new[](size_t) = delete;
+ // The garbage collector is taking care of reclaiming the object. Also,
+ // virtual destructor requires an unambiguous, accessible 'operator delete'.
+ void operator delete(void*) { NOTREACHED(); }
+ void operator delete[](void*) = delete;
template <typename Derived>
static void* AllocateObject(size_t size) {
return ThreadHeap::Allocate<GCInfoFoldedType<Derived>>(size);
}
- void operator delete(void* p) { NOTREACHED(); }
-
protected:
// This trait in theory can be moved to gc_info.h, but that would cause
// significant memory bloat caused by huge number of ThreadHeap::Allocate<>
@@ -513,61 +532,75 @@ class GarbageCollected {
DISALLOW_COPY_AND_ASSIGN(GarbageCollected);
};
-// Default MakeGarbageCollected: Constructs an instance of T, which is a garbage
-// collected type.
-template <typename T, typename... Args>
-T* MakeGarbageCollected(Args&&... args) {
- static_assert(WTF::IsGarbageCollectedType<T>::value,
- "T needs to be a garbage collected object");
- static_assert(std::is_trivially_destructible<T>::value ||
- std::has_virtual_destructor<T>::value ||
- std::is_final<T>::value ||
- internal::IsGarbageCollectedContainer<T>::value ||
- internal::HasFinalizeGarbageCollectedObject<T>::value,
- "Finalized GarbageCollected class should either have a virtual "
- "destructor or be marked as final");
- static_assert(!IsGarbageCollectedMixin<T>::value ||
- sizeof(T) <= kLargeObjectSizeThreshold,
- "GarbageCollectedMixin may not be a large object");
- void* memory = T::template AllocateObject<T>(sizeof(T));
- HeapObjectHeader* header = HeapObjectHeader::FromPayload(memory);
- // Placement new as regular operator new() is deleted.
- T* object = ::new (memory) T(std::forward<Args>(args)...);
- header->MarkFullyConstructed<HeapObjectHeader::AccessMode::kAtomic>();
- return object;
-}
-
// Used for passing custom sizes to MakeGarbageCollected.
struct AdditionalBytes {
explicit AdditionalBytes(size_t bytes) : value(bytes) {}
const size_t value;
};
+template <typename T>
+struct MakeGarbageCollectedTrait {
+ template <typename... Args>
+ static T* Call(Args&&... args) {
+ static_assert(WTF::IsGarbageCollectedType<T>::value,
+ "T needs to be a garbage collected object");
+ static_assert(
+ std::is_trivially_destructible<T>::value ||
+ std::has_virtual_destructor<T>::value || std::is_final<T>::value ||
+ internal::IsGarbageCollectedContainer<T>::value ||
+ internal::HasFinalizeGarbageCollectedObject<T>::value,
+ "Finalized GarbageCollected class should either have a virtual "
+ "destructor or be marked as final");
+ static_assert(!IsGarbageCollectedMixin<T>::value ||
+ sizeof(T) <= kLargeObjectSizeThreshold,
+ "GarbageCollectedMixin may not be a large object");
+ void* memory = T::template AllocateObject<T>(sizeof(T));
+ HeapObjectHeader* header = HeapObjectHeader::FromPayload(memory);
+ // Placement new as regular operator new() is deleted.
+ T* object = ::new (memory) T(std::forward<Args>(args)...);
+ header->MarkFullyConstructed<HeapObjectHeader::AccessMode::kAtomic>();
+ return object;
+ }
+
+ template <typename... Args>
+ static T* Call(AdditionalBytes additional_bytes, Args&&... args) {
+ static_assert(WTF::IsGarbageCollectedType<T>::value,
+ "T needs to be a garbage collected object");
+ static_assert(
+ std::is_trivially_destructible<T>::value ||
+ std::has_virtual_destructor<T>::value || std::is_final<T>::value ||
+ internal::IsGarbageCollectedContainer<T>::value ||
+ internal::HasFinalizeGarbageCollectedObject<T>::value,
+ "Finalized GarbageCollected class should either have a virtual "
+ "destructor or be marked as final.");
+ const size_t size = sizeof(T) + additional_bytes.value;
+ if (IsGarbageCollectedMixin<T>::value) {
+ // Ban large mixin so we can use PageFromObject() on them.
+ CHECK_GE(kLargeObjectSizeThreshold, size)
+ << "GarbageCollectedMixin may not be a large object";
+ }
+ void* memory = T::template AllocateObject<T>(size);
+ HeapObjectHeader* header = HeapObjectHeader::FromPayload(memory);
+ // Placement new as regular operator new() is deleted.
+ T* object = ::new (memory) T(std::forward<Args>(args)...);
+ header->MarkFullyConstructed<HeapObjectHeader::AccessMode::kAtomic>();
+ return object;
+ }
+};
+
+// Default MakeGarbageCollected: Constructs an instance of T, which is a garbage
+// collected type.
+template <typename T, typename... Args>
+T* MakeGarbageCollected(Args&&... args) {
+ return MakeGarbageCollectedTrait<T>::Call(std::forward<Args>(args)...);
+}
+
// Constructs an instance of T, which is a garbage collected type. This special
// version takes size which enables constructing inline objects.
template <typename T, typename... Args>
T* MakeGarbageCollected(AdditionalBytes additional_bytes, Args&&... args) {
- static_assert(WTF::IsGarbageCollectedType<T>::value,
- "T needs to be a garbage collected object");
- static_assert(std::is_trivially_destructible<T>::value ||
- std::has_virtual_destructor<T>::value ||
- std::is_final<T>::value ||
- internal::IsGarbageCollectedContainer<T>::value ||
- internal::HasFinalizeGarbageCollectedObject<T>::value,
- "Finalized GarbageCollected class should either have a virtual "
- "destructor or be marked as final.");
- const size_t size = sizeof(T) + additional_bytes.value;
- if (IsGarbageCollectedMixin<T>::value) {
- // Ban large mixin so we can use PageFromObject() on them.
- CHECK_GE(kLargeObjectSizeThreshold, size)
- << "GarbageCollectedMixin may not be a large object";
- }
- void* memory = T::template AllocateObject<T>(size);
- HeapObjectHeader* header = HeapObjectHeader::FromPayload(memory);
- // Placement new as regular operator new() is deleted.
- T* object = ::new (memory) T(std::forward<Args>(args)...);
- header->MarkFullyConstructed<HeapObjectHeader::AccessMode::kAtomic>();
- return object;
+ return MakeGarbageCollectedTrait<T>::Call(additional_bytes,
+ std::forward<Args>(args)...);
}
// Assigning class types to their arenas.
@@ -620,9 +653,21 @@ Address ThreadHeap::Allocate(size_t size) {
GCInfoTrait<T>::Index(), type_name);
}
+inline bool ThreadHeap::IsInLastAllocatedRegion(Address address) const {
+ return last_allocated_region_.start <= address &&
+ address <
+ (last_allocated_region_.start + last_allocated_region_.length);
+}
+
+inline void ThreadHeap::SetLastAllocatedRegion(Address start, size_t length) {
+ last_allocated_region_.start = start;
+ last_allocated_region_.length = length;
+}
+
template <typename T>
-void Visitor::HandleWeakCell(const WeakCallbackInfo&, void* object) {
- WeakMember<T>* weak_member = reinterpret_cast<WeakMember<T>*>(object);
+void Visitor::HandleWeakCell(const WeakCallbackInfo&, const void* object) {
+ WeakMember<T>* weak_member =
+ reinterpret_cast<WeakMember<T>*>(const_cast<void*>(object));
if (weak_member->Get()) {
if (weak_member->IsHashTableDeletedValue()) {
// This can happen when weak fields are deleted while incremental marking
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_allocator.h b/chromium/third_party/blink/renderer/platform/heap/heap_allocator.h
index d41fe4e422c..867165c8079 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_allocator.h
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_allocator.h
@@ -8,6 +8,8 @@
#include <type_traits>
#include "build/build_config.h"
+#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h"
+#include "third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
#include "third_party/blink/renderer/platform/heap/marking_visitor.h"
@@ -45,26 +47,6 @@ template <typename T>
struct IsAllowedInContainer<T, typename T::IsDisallowedInContainerMarker>
: std::false_type {};
-template <typename T, typename Traits = WTF::VectorTraits<T>>
-class HeapVectorBacking {
- DISALLOW_NEW();
- IS_GARBAGE_COLLECTED_TYPE();
-
- public:
- static void Finalize(void* pointer);
- void FinalizeGarbageCollectedObject() { Finalize(this); }
-};
-
-template <typename Table>
-class HeapHashTableBacking {
- DISALLOW_NEW();
- IS_GARBAGE_COLLECTED_TYPE();
-
- public:
- static void Finalize(void* pointer);
- void FinalizeGarbageCollectedObject() { Finalize(this); }
-};
-
// This is a static-only class used as a trait on collections to make them heap
// allocated. However see also HeapListHashSetAllocator.
class PLATFORM_EXPORT HeapAllocator {
@@ -88,16 +70,8 @@ class PLATFORM_EXPORT HeapAllocator {
}
template <typename T>
static T* AllocateVectorBacking(size_t size) {
- ThreadState* state =
- ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
- DCHECK(state->IsAllocationAllowed());
- uint32_t gc_info_index = GCInfoTrait<HeapVectorBacking<T>>::Index();
- const char* type_name =
- WTF_HEAP_PROFILER_TYPE_NAME(HeapHashTableBacking<HeapVectorBacking<T>>);
return reinterpret_cast<T*>(
- MarkAsConstructed(state->Heap().AllocateOnArenaIndex(
- state, ThreadHeap::AllocationSizeFromSize(size),
- BlinkGC::kVectorArenaIndex, gc_info_index, type_name)));
+ MakeGarbageCollected<HeapVectorBacking<T>>(size / sizeof(T)));
}
static void FreeVectorBacking(void*);
static bool ExpandVectorBacking(void*, size_t);
@@ -107,16 +81,9 @@ class PLATFORM_EXPORT HeapAllocator {
template <typename T, typename HashTable>
static T* AllocateHashTableBacking(size_t size) {
- uint32_t gc_info_index =
- GCInfoTrait<HeapHashTableBacking<HashTable>>::Index();
- ThreadState* state =
- ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
- const char* type_name =
- WTF_HEAP_PROFILER_TYPE_NAME(HeapHashTableBacking<HashTable>);
return reinterpret_cast<T*>(
- MarkAsConstructed(state->Heap().AllocateOnArenaIndex(
- state, size, BlinkGC::kHashTableArenaIndex, gc_info_index,
- type_name)));
+ MakeGarbageCollected<HeapHashTableBacking<HashTable>>(
+ size / sizeof(typename HashTable::ValueType)));
}
template <typename T, typename HashTable>
static T* AllocateZeroedHashTableBacking(size_t size) {
@@ -125,19 +92,27 @@ class PLATFORM_EXPORT HeapAllocator {
static void FreeHashTableBacking(void* address);
static bool ExpandHashTableBacking(void*, size_t);
- static void TraceMarkedBackingStore(void* address) {
- MarkingVisitor::TraceMarkedBackingStore(address);
+ static void TraceBackingStoreIfMarked(const void* address) {
+ // Trace backing store elements only if backing store was marked. The
+ // sweeper may be active on the backing store which requires atomic mark bit
+ // access. A precise filter is performed in
+ // MarkingVisitor::TraceMarkedBackingStore.
+ if (HeapObjectHeader::FromPayload(address)
+ ->IsMarked<HeapObjectHeader::AccessMode::kAtomic>()) {
+ MarkingVisitor::TraceMarkedBackingStore(address);
+ }
}
- static void BackingWriteBarrier(void* address) {
- MarkingVisitor::WriteBarrier(address);
+ template <typename T>
+ static void BackingWriteBarrier(T** slot) {
+ MarkingVisitor::WriteBarrier(slot);
}
- template <typename HashTable>
- static void BackingWriteBarrierForHashTable(void* address) {
- if (MarkingVisitor::WriteBarrier(address)) {
+ template <typename HashTable, typename T>
+ static void BackingWriteBarrierForHashTable(T** slot) {
+ if (MarkingVisitor::WriteBarrier(slot)) {
AddMovingCallback<HashTable>(
- static_cast<typename HashTable::ValueType*>(address));
+ static_cast<typename HashTable::ValueType*>(*slot));
}
}
@@ -167,13 +142,18 @@ class PLATFORM_EXPORT HeapAllocator {
return ThreadState::Current()->SweepForbidden();
}
+ static bool IsIncrementalMarking() {
+ return ThreadState::IsAnyIncrementalMarking() &&
+ ThreadState::Current()->IsIncrementalMarking();
+ }
+
template <typename T>
static bool IsHeapObjectAlive(T* object) {
return ThreadHeap::IsHeapObjectAlive(object);
}
template <typename T, typename Traits>
- static void Trace(blink::Visitor* visitor, T& t) {
+ static void Trace(Visitor* visitor, const T& t) {
TraceCollectionIfEnabled<WTF::WeakHandlingTrait<T>::value, T,
Traits>::Trace(visitor, &t);
}
@@ -195,84 +175,106 @@ class PLATFORM_EXPORT HeapAllocator {
template <typename T, typename Traits>
static void NotifyNewObject(T* object) {
+#if BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
+ ThreadState* const thread_state = ThreadState::Current();
+ if (!thread_state->IsIncrementalMarking()) {
+ MarkingVisitor::GenerationalBarrier(reinterpret_cast<Address>(object),
+ thread_state);
+ return;
+ }
+#else
if (!ThreadState::IsAnyIncrementalMarking())
return;
// The object may have been in-place constructed as part of a large object.
// It is not safe to retrieve the page from the object here.
ThreadState* const thread_state = ThreadState::Current();
- if (thread_state->IsIncrementalMarking()) {
- // Eagerly trace the object ensuring that the object and all its children
- // are discovered by the marker.
- ThreadState::NoAllocationScope no_allocation_scope(thread_state);
- DCHECK(thread_state->CurrentVisitor());
- // No weak handling for write barriers. Modifying weakly reachable objects
- // strongifies them for the current cycle.
- DCHECK(!Traits::kCanHaveDeletedValue || !Traits::IsDeletedValue(*object));
- TraceCollectionIfEnabled<WTF::kNoWeakHandling, T, Traits>::Trace(
- thread_state->CurrentVisitor(), object);
+ if (!thread_state->IsIncrementalMarking()) {
+ return;
}
+#endif // BLINK_HEAP_YOUNG_GENERATION
+ // Eagerly trace the object ensuring that the object and all its children
+ // are discovered by the marker.
+ ThreadState::NoAllocationScope no_allocation_scope(thread_state);
+ DCHECK(thread_state->CurrentVisitor());
+ // No weak handling for write barriers. Modifying weakly reachable objects
+ // strongifies them for the current cycle.
+ DCHECK(!Traits::kCanHaveDeletedValue || !Traits::IsDeletedValue(*object));
+ TraceCollectionIfEnabled<WTF::kNoWeakHandling, T, Traits>::Trace(
+ thread_state->CurrentVisitor(), object);
}
template <typename T, typename Traits>
static void NotifyNewObjects(T* array, size_t len) {
+#if BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
+ ThreadState* const thread_state = ThreadState::Current();
+ if (!thread_state->IsIncrementalMarking()) {
+ MarkingVisitor::GenerationalBarrier(reinterpret_cast<Address>(array),
+ thread_state);
+ return;
+ }
+#else
if (!ThreadState::IsAnyIncrementalMarking())
return;
// The object may have been in-place constructed as part of a large object.
// It is not safe to retrieve the page from the object here.
ThreadState* const thread_state = ThreadState::Current();
- if (thread_state->IsIncrementalMarking()) {
- // See |NotifyNewObject| for details.
- ThreadState::NoAllocationScope no_allocation_scope(thread_state);
- DCHECK(thread_state->CurrentVisitor());
- // No weak handling for write barriers. Modifying weakly reachable objects
- // strongifies them for the current cycle.
- while (len-- > 0) {
- DCHECK(!Traits::kCanHaveDeletedValue ||
- !Traits::IsDeletedValue(*array));
- TraceCollectionIfEnabled<WTF::kNoWeakHandling, T, Traits>::Trace(
- thread_state->CurrentVisitor(), array);
- array++;
- }
+ if (!thread_state->IsIncrementalMarking()) {
+ return;
+ }
+#endif // BLINK_HEAP_YOUNG_GENERATION
+ // See |NotifyNewObject| for details.
+ ThreadState::NoAllocationScope no_allocation_scope(thread_state);
+ DCHECK(thread_state->CurrentVisitor());
+ // No weak handling for write barriers. Modifying weakly reachable objects
+ // strongifies them for the current cycle.
+ while (len-- > 0) {
+ DCHECK(!Traits::kCanHaveDeletedValue || !Traits::IsDeletedValue(*array));
+ TraceCollectionIfEnabled<WTF::kNoWeakHandling, T, Traits>::Trace(
+ thread_state->CurrentVisitor(), array);
+ array++;
}
}
template <typename T>
static void TraceVectorBacking(Visitor* visitor,
- T* backing,
- T** backing_slot) {
+ const T* backing,
+ const T* const* backing_slot) {
visitor->TraceBackingStoreStrongly(
- reinterpret_cast<HeapVectorBacking<T>*>(backing),
- reinterpret_cast<HeapVectorBacking<T>**>(backing_slot));
+ reinterpret_cast<const HeapVectorBacking<T>*>(backing),
+ reinterpret_cast<const HeapVectorBacking<T>* const*>(backing_slot));
}
template <typename T, typename HashTable>
static void TraceHashTableBackingStrongly(Visitor* visitor,
- T* backing,
- T** backing_slot) {
+ const T* backing,
+ const T* const* backing_slot) {
visitor->TraceBackingStoreStrongly(
- reinterpret_cast<HeapHashTableBacking<HashTable>*>(backing),
- reinterpret_cast<HeapHashTableBacking<HashTable>**>(backing_slot));
+ reinterpret_cast<const HeapHashTableBacking<HashTable>*>(backing),
+ reinterpret_cast<const HeapHashTableBacking<HashTable>* const*>(
+ backing_slot));
}
template <typename T, typename HashTable>
static void TraceHashTableBackingWeakly(Visitor* visitor,
- T* backing,
- T** backing_slot,
+ const T* backing,
+ const T* const* backing_slot,
WeakCallback callback,
- void* parameter) {
+ const void* parameter) {
visitor->TraceBackingStoreWeakly<HashTable>(
- reinterpret_cast<HeapHashTableBacking<HashTable>*>(backing),
- reinterpret_cast<HeapHashTableBacking<HashTable>**>(backing_slot),
+ reinterpret_cast<const HeapHashTableBacking<HashTable>*>(backing),
+ reinterpret_cast<const HeapHashTableBacking<HashTable>* const*>(
+ backing_slot),
callback, parameter);
}
template <typename T, typename HashTable>
static void TraceHashTableBackingOnly(Visitor* visitor,
- T* backing,
- T** backing_slot) {
+ const T* backing,
+ const T* const* backing_slot) {
visitor->TraceBackingStoreOnly(
- reinterpret_cast<HeapHashTableBacking<HashTable>*>(backing),
- reinterpret_cast<HeapHashTableBacking<HashTable>**>(backing_slot));
+ reinterpret_cast<const HeapHashTableBacking<HashTable>*>(backing),
+ reinterpret_cast<const HeapHashTableBacking<HashTable>* const*>(
+ backing_slot));
}
private:
@@ -318,7 +320,8 @@ class PLATFORM_EXPORT HeapAllocator {
};
template <typename VisitorDispatcher, typename Value>
-static void TraceListHashSetValue(VisitorDispatcher visitor, Value& value) {
+static void TraceListHashSetValue(VisitorDispatcher visitor,
+ const Value& value) {
// We use the default hash traits for the value in the node, because
// ListHashSet does not let you specify any specific ones.
// We don't allow ListHashSet of WeakMember, so we set that one false
@@ -376,64 +379,22 @@ class HeapListHashSetAllocator : public HeapAllocator {
}
template <typename VisitorDispatcher>
- static void TraceValue(VisitorDispatcher visitor, Node* node) {
+ static void TraceValue(VisitorDispatcher visitor, const Node* node) {
TraceListHashSetValue(visitor, node->value_);
}
};
-template <typename T, typename Traits>
-void HeapVectorBacking<T, Traits>::Finalize(void* pointer) {
- static_assert(Traits::kNeedsDestruction,
- "Only vector buffers with items requiring destruction should "
- "be finalized");
- // See the comment in HeapVectorBacking::trace.
- static_assert(
- Traits::kCanClearUnusedSlotsWithMemset || std::is_polymorphic<T>::value,
- "HeapVectorBacking doesn't support objects that cannot be cleared as "
- "unused with memset or don't have a vtable");
-
- static_assert(
- !std::is_trivially_destructible<T>::value,
- "Finalization of trivially destructible classes should not happen.");
- HeapObjectHeader* header = HeapObjectHeader::FromPayload(pointer);
- // Use the payload size as recorded by the heap to determine how many
- // elements to finalize.
- size_t length = header->PayloadSize() / sizeof(T);
- char* payload = static_cast<char*>(pointer);
-#ifdef ANNOTATE_CONTIGUOUS_CONTAINER
- ANNOTATE_CHANGE_SIZE(payload, length * sizeof(T), 0, length * sizeof(T));
-#endif
- // As commented above, HeapVectorBacking calls finalizers for unused slots
- // (which are already zeroed out).
- if (std::is_polymorphic<T>::value) {
- for (unsigned i = 0; i < length; ++i) {
- char* element = payload + i * sizeof(T);
- if (blink::VTableInitialized(element))
- reinterpret_cast<T*>(element)->~T();
- }
- } else {
- T* buffer = reinterpret_cast<T*>(payload);
- for (unsigned i = 0; i < length; ++i)
- buffer[i].~T();
- }
-}
+namespace internal {
-template <typename Table>
-void HeapHashTableBacking<Table>::Finalize(void* pointer) {
- using Value = typename Table::ValueType;
- static_assert(
- !std::is_trivially_destructible<Value>::value,
- "Finalization of trivially destructible classes should not happen.");
- HeapObjectHeader* header = HeapObjectHeader::FromPayload(pointer);
- // Use the payload size as recorded by the heap to determine how many
- // elements to finalize.
- size_t length = header->PayloadSize() / sizeof(Value);
- Value* table = reinterpret_cast<Value*>(pointer);
- for (unsigned i = 0; i < length; ++i) {
- if (!Table::IsEmptyOrDeletedBucket(table[i]))
- table[i].~Value();
- }
-}
+template <typename T>
+constexpr bool IsMember = WTF::IsSubclassOfTemplate<T, Member>::value;
+
+template <typename T>
+constexpr bool IsMemberOrWeakMemberType =
+ WTF::IsSubclassOfTemplate<T, Member>::value ||
+ WTF::IsSubclassOfTemplate<T, WeakMember>::value;
+
+} // namespace internal
template <typename KeyArg,
typename MappedArg,
@@ -475,6 +436,10 @@ class HeapHashMap : public HashMap<KeyArg,
HeapHashMap() { CheckType(); }
};
+template <typename T, typename U, typename V, typename W, typename X>
+struct GCInfoTrait<HeapHashMap<T, U, V, W, X>>
+ : public GCInfoTrait<HashMap<T, U, V, W, X, HeapAllocator>> {};
+
template <typename ValueArg,
typename HashArg = typename DefaultHash<ValueArg>::Hash,
typename TraitsArg = HashTraits<ValueArg>>
@@ -484,6 +449,8 @@ class HeapHashSet
DISALLOW_NEW();
static void CheckType() {
+ static_assert(internal::IsMemberOrWeakMemberType<ValueArg>,
+ "HeapHashSet supports only Member and WeakMember.");
static_assert(std::is_trivially_destructible<HeapHashSet>::value,
"HeapHashSet must be trivially destructible.");
static_assert(
@@ -504,6 +471,10 @@ class HeapHashSet
HeapHashSet() { CheckType(); }
};
+template <typename T, typename U, typename V>
+struct GCInfoTrait<HeapHashSet<T, U, V>>
+ : public GCInfoTrait<HashSet<T, U, V, HeapAllocator>> {};
+
template <typename ValueArg,
typename HashArg = typename DefaultHash<ValueArg>::Hash,
typename TraitsArg = HashTraits<ValueArg>>
@@ -516,6 +487,8 @@ class HeapLinkedHashSet
DISALLOW_IN_CONTAINER();
static void CheckType() {
+ static_assert(internal::IsMemberOrWeakMemberType<ValueArg>,
+ "HeapLinkedHashSet supports only Member and WeakMember.");
static_assert(
IsAllowedInContainer<ValueArg>::value,
"Not allowed to directly nest type. Use Member<> indirection instead.");
@@ -534,6 +507,45 @@ class HeapLinkedHashSet
HeapLinkedHashSet() { CheckType(); }
};
+template <typename T, typename U, typename V>
+struct GCInfoTrait<HeapLinkedHashSet<T, U, V>>
+ : public GCInfoTrait<LinkedHashSet<T, U, V, HeapAllocator>> {};
+
+// This class is still experimental. Do not use this class.
+template <typename ValueArg>
+class HeapNewLinkedHashSet : public NewLinkedHashSet<ValueArg, HeapAllocator> {
+ IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
+ DISALLOW_NEW();
+
+ static void CheckType() {
+ // TODO(keinakashima): support WeakMember<T>
+ static_assert(internal::IsMember<ValueArg>,
+ "HeapNewLinkedHashSet supports only Member.");
+ // If not trivially destructible, we have to add a destructor which will
+ // hinder performance.
+ static_assert(std::is_trivially_destructible<HeapNewLinkedHashSet>::value,
+ "HeapNewLinkedHashSet must be trivially destructible.");
+ static_assert(
+ IsAllowedInContainer<ValueArg>::value,
+ "Not allowed to directly nest type. Use Member<> indirection instead.");
+ static_assert(WTF::IsTraceable<ValueArg>::value,
+ "For sets without traceable elements, use NewLinkedHashSet<> "
+ "instead of HeapNewLinkedHashSet<>.");
+ }
+
+ public:
+ template <typename>
+ static void* AllocateObject(size_t size) {
+ return ThreadHeap::Allocate<HeapNewLinkedHashSet<ValueArg>>(size);
+ }
+
+ HeapNewLinkedHashSet() { CheckType(); }
+};
+
+template <typename T>
+struct GCInfoTrait<HeapNewLinkedHashSet<T>>
+ : public GCInfoTrait<NewLinkedHashSet<T, HeapAllocator>> {};
+
template <typename ValueArg,
wtf_size_t inlineCapacity =
0, // The inlineCapacity is just a dummy to
@@ -548,6 +560,8 @@ class HeapListHashSet
DISALLOW_NEW();
static void CheckType() {
+ static_assert(internal::IsMemberOrWeakMemberType<ValueArg>,
+ "HeapListHashSet supports only Member and WeakMember.");
static_assert(std::is_trivially_destructible<HeapListHashSet>::value,
"HeapListHashSet must be trivially destructible.");
static_assert(
@@ -568,6 +582,14 @@ class HeapListHashSet
HeapListHashSet() { CheckType(); }
};
+template <typename T, wtf_size_t inlineCapacity, typename U>
+struct GCInfoTrait<HeapListHashSet<T, inlineCapacity, U>>
+ : public GCInfoTrait<
+ ListHashSet<T,
+ inlineCapacity,
+ U,
+ HeapListHashSetAllocator<T, inlineCapacity>>> {};
+
template <typename Value,
typename HashFunctions = typename DefaultHash<Value>::Hash,
typename Traits = HashTraits<Value>>
@@ -577,6 +599,8 @@ class HeapHashCountedSet
DISALLOW_NEW();
static void CheckType() {
+ static_assert(internal::IsMemberOrWeakMemberType<Value>,
+ "HeapHashCountedSet supports only Member and WeakMember.");
static_assert(std::is_trivially_destructible<HeapHashCountedSet>::value,
"HeapHashCountedSet must be trivially destructible.");
static_assert(
@@ -597,6 +621,10 @@ class HeapHashCountedSet
HeapHashCountedSet() { CheckType(); }
};
+template <typename T, typename U, typename V>
+struct GCInfoTrait<HeapHashCountedSet<T, U, V>>
+ : public GCInfoTrait<HashCountedSet<T, U, V, HeapAllocator>> {};
+
template <typename T, wtf_size_t inlineCapacity = 0>
class HeapVector : public Vector<T, inlineCapacity, HeapAllocator> {
IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
@@ -612,6 +640,8 @@ class HeapVector : public Vector<T, inlineCapacity, HeapAllocator> {
static_assert(WTF::IsTraceable<T>::value,
"For vectors without traceable elements, use Vector<> "
"instead of HeapVector<>.");
+ static_assert(!WTF::IsWeak<T>::value,
+ "Weak types are not allowed in HeapVector.");
}
public:
@@ -649,15 +679,19 @@ class HeapVector : public Vector<T, inlineCapacity, HeapAllocator> {
}
};
-template <typename T, wtf_size_t inlineCapacity = 0>
-class HeapDeque : public Deque<T, inlineCapacity, HeapAllocator> {
+template <typename T, wtf_size_t inlineCapacity>
+struct GCInfoTrait<HeapVector<T, inlineCapacity>>
+ : public GCInfoTrait<Vector<T, inlineCapacity, HeapAllocator>> {};
+
+template <typename T>
+class HeapDeque : public Deque<T, 0, HeapAllocator> {
IS_GARBAGE_COLLECTED_CONTAINER_TYPE();
DISALLOW_NEW();
static void CheckType() {
- static_assert(
- std::is_trivially_destructible<HeapDeque>::value || inlineCapacity,
- "HeapDeque must be trivially destructible.");
+ static_assert(internal::IsMember<T>, "HeapDeque supports only Member.");
+ static_assert(std::is_trivially_destructible<HeapDeque>::value,
+ "HeapDeque must be trivially destructible.");
static_assert(
IsAllowedInContainer<T>::value,
"Not allowed to directly nest type. Use Member<> indirection instead.");
@@ -669,37 +703,33 @@ class HeapDeque : public Deque<T, inlineCapacity, HeapAllocator> {
public:
template <typename>
static void* AllocateObject(size_t size) {
- // On-heap HeapDeques generally should not have inline capacity, but it is
- // hard to avoid when using a type alias. Hence we only disallow the
- // VectorTraits<T>::kNeedsDestruction case for now.
- static_assert(inlineCapacity == 0 || !VectorTraits<T>::kNeedsDestruction,
- "on-heap HeapDeque<> should not have an inline capacity");
- return ThreadHeap::Allocate<HeapDeque<T, inlineCapacity>>(size);
+ return ThreadHeap::Allocate<HeapDeque<T>>(size);
}
HeapDeque() { CheckType(); }
- explicit HeapDeque(wtf_size_t size)
- : Deque<T, inlineCapacity, HeapAllocator>(size) {
+ explicit HeapDeque(wtf_size_t size) : Deque<T, 0, HeapAllocator>(size) {
CheckType();
}
HeapDeque(wtf_size_t size, const T& val)
- : Deque<T, inlineCapacity, HeapAllocator>(size, val) {
+ : Deque<T, 0, HeapAllocator>(size, val) {
CheckType();
}
HeapDeque& operator=(const HeapDeque& other) {
HeapDeque<T> copy(other);
- Deque<T, inlineCapacity, HeapAllocator>::Swap(copy);
+ Deque<T, 0, HeapAllocator>::Swap(copy);
return *this;
}
- template <wtf_size_t otherCapacity>
- HeapDeque(const HeapDeque<T, otherCapacity>& other)
- : Deque<T, inlineCapacity, HeapAllocator>(other) {}
+ HeapDeque(const HeapDeque<T>& other) : Deque<T, 0, HeapAllocator>(other) {}
};
+template <typename T>
+struct GCInfoTrait<HeapDeque<T>>
+ : public GCInfoTrait<Deque<T, 0, HeapAllocator>> {};
+
} // namespace blink
namespace WTF {
@@ -745,8 +775,8 @@ struct VectorTraits<blink::HeapVector<T, 0>>
};
template <typename T>
-struct VectorTraits<blink::HeapDeque<T, 0>>
- : VectorTraitsBase<blink::HeapDeque<T, 0>> {
+struct VectorTraits<blink::HeapDeque<T>>
+ : VectorTraitsBase<blink::HeapDeque<T>> {
STATIC_ONLY(VectorTraits);
static const bool kNeedsDestruction = false;
static const bool kCanInitializeWithMemset = true;
@@ -766,18 +796,6 @@ struct VectorTraits<blink::HeapVector<T, inlineCapacity>>
static const bool kCanMoveWithMemcpy = VectorTraits<T>::kCanMoveWithMemcpy;
};
-template <typename T, wtf_size_t inlineCapacity>
-struct VectorTraits<blink::HeapDeque<T, inlineCapacity>>
- : VectorTraitsBase<blink::HeapDeque<T, inlineCapacity>> {
- STATIC_ONLY(VectorTraits);
- static const bool kNeedsDestruction = VectorTraits<T>::kNeedsDestruction;
- static const bool kCanInitializeWithMemset =
- VectorTraits<T>::kCanInitializeWithMemset;
- static const bool kCanClearUnusedSlotsWithMemset =
- VectorTraits<T>::kCanClearUnusedSlotsWithMemset;
- static const bool kCanMoveWithMemcpy = VectorTraits<T>::kCanMoveWithMemcpy;
-};
-
template <typename T>
struct HashTraits<blink::Member<T>> : SimpleClassHashTraits<blink::Member<T>> {
STATIC_ONLY(HashTraits);
@@ -808,9 +826,6 @@ struct HashTraits<blink::Member<T>> : SimpleClassHashTraits<blink::Member<T>> {
static void ConstructDeletedValue(blink::Member<T>& slot, bool) {
slot = WTF::kHashTableDeletedValue;
}
- static bool IsDeletedValue(const blink::Member<T>& value) {
- return value.IsHashTableDeletedValue();
- }
};
template <typename T>
@@ -841,6 +856,10 @@ struct HashTraits<blink::WeakMember<T>>
}
static PeekOutType Peek(const blink::WeakMember<T>& value) { return value; }
+
+ static void ConstructDeletedValue(blink::WeakMember<T>& slot, bool) {
+ slot = WTF::kHashTableDeletedValue;
+ }
};
template <typename T>
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_compact.cc b/chromium/third_party/blink/renderer/platform/heap/heap_compact.cc
index 1d9a577d2e3..24194d0db0b 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_compact.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_compact.cc
@@ -38,7 +38,7 @@ class HeapCompact::MovableObjectFixups final {
void AddCompactingPage(BasePage* page);
// Adds a slot for compaction. Filters slots in dead objects.
- void AddOrFilter(MovableReference* slot);
+ void AddOrFilter(const MovableReference*);
// Relocates a backing store |from| -> |to|.
void Relocate(Address from, Address to);
@@ -89,7 +89,7 @@ class HeapCompact::MovableObjectFixups final {
#if DCHECK_IS_ON()
// The following two collections are used to allow refer back from a slot to
// an already moved object.
- HashSet<void*> moved_objects_;
+ HashSet<const void*> moved_objects_;
HashMap<MovableReference*, MovableReference> interior_slot_to_object_;
#endif // DCHECK_IS_ON()
};
@@ -99,8 +99,9 @@ void HeapCompact::MovableObjectFixups::AddCompactingPage(BasePage* page) {
relocatable_pages_.insert(page);
}
-void HeapCompact::MovableObjectFixups::AddOrFilter(MovableReference* slot) {
- MovableReference value = *slot;
+void HeapCompact::MovableObjectFixups::AddOrFilter(
+ const MovableReference* const_slot) {
+ const void* value = *const_slot;
CHECK(value);
// All slots and values are part of Oilpan's heap.
@@ -111,13 +112,13 @@ void HeapCompact::MovableObjectFixups::AddOrFilter(MovableReference* slot) {
// Slots handling.
BasePage* const slot_page =
- heap_->LookupPageForAddress(reinterpret_cast<Address>(slot));
+ heap_->LookupPageForAddress(reinterpret_cast<ConstAddress>(const_slot));
CHECK(slot_page);
HeapObjectHeader* const header =
slot_page->IsLargeObjectPage()
? static_cast<LargeObjectPage*>(slot_page)->ObjectHeader()
: static_cast<NormalPage*>(slot_page)->FindHeaderFromAddress(
- reinterpret_cast<Address>(slot));
+ reinterpret_cast<ConstAddress>(const_slot));
CHECK(header);
// Filter the slot since the object that contains the slot is dead.
if (!header->IsMarked())
@@ -125,7 +126,7 @@ void HeapCompact::MovableObjectFixups::AddOrFilter(MovableReference* slot) {
// Value handling.
BasePage* const value_page =
- heap_->LookupPageForAddress(reinterpret_cast<Address>(value));
+ heap_->LookupPageForAddress(reinterpret_cast<ConstAddress>(value));
CHECK(value_page);
// The following cases are not compacted and do not require recording:
@@ -142,7 +143,7 @@ void HeapCompact::MovableObjectFixups::AddOrFilter(MovableReference* slot) {
// dynamic header lookup is required.
HeapObjectHeader* const value_header =
static_cast<NormalPage*>(value_page)
- ->FindHeaderFromAddress(reinterpret_cast<Address>(value));
+ ->FindHeaderFromAddress(reinterpret_cast<ConstAddress>(value));
CHECK(value_header);
CHECK(value_header->IsMarked());
@@ -151,11 +152,12 @@ void HeapCompact::MovableObjectFixups::AddOrFilter(MovableReference* slot) {
// times.
auto fixup_it = fixups_.find(value);
if (UNLIKELY(fixup_it != fixups_.end())) {
- CHECK_EQ(slot, fixup_it->value);
+ CHECK_EQ(const_slot, fixup_it->value);
return;
}
// Add regular fixup.
+ MovableReference* slot = const_cast<MovableReference*>(const_slot);
fixups_.insert(value, slot);
// Check whether the slot itself resides on a page that is compacted.
@@ -301,7 +303,7 @@ void HeapCompact::MovableObjectFixups::VerifyUpdatedSlot(
if (!*slot)
return;
BasePage* slot_page =
- heap_->LookupPageForAddress(reinterpret_cast<Address>(*slot));
+ heap_->LookupPageForAddress(reinterpret_cast<ConstAddress>(*slot));
// ref_page is null if *slot is pointing to an off-heap region. This may
// happy if *slot is pointing to an inline buffer of HeapVector with
// inline capacity.
@@ -373,9 +375,7 @@ void HeapCompact::Initialize(ThreadState* state) {
force_for_next_gc_ = false;
}
-bool HeapCompact::ShouldRegisterMovingAddress(Address address) {
- CHECK(heap_->LookupPageForAddress(reinterpret_cast<Address>(address)));
-
+bool HeapCompact::ShouldRegisterMovingAddress() {
return do_compact_;
}
@@ -442,8 +442,9 @@ void HeapCompact::FilterNonLiveSlots() {
last_fixup_count_for_testing_ = 0;
MovableReferenceWorklist::View traced_slots(
heap_->GetMovableReferenceWorklist(), WorklistTaskId::MutatorThread);
- MovableReference* slot;
+ const MovableReference* slot;
while (traced_slots.Pop(&slot)) {
+ CHECK(heap_->LookupPageForAddress(reinterpret_cast<ConstAddress>(slot)));
if (*slot) {
Fixups().AddOrFilter(slot);
last_fixup_count_for_testing_++;
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_compact.h b/chromium/third_party/blink/renderer/platform/heap/heap_compact.h
index be7b142e17b..93624129098 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_compact.h
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_compact.h
@@ -64,7 +64,7 @@ class PLATFORM_EXPORT HeapCompact final {
}
// See |Heap::ShouldRegisterMovingAddress()| documentation.
- bool ShouldRegisterMovingAddress(Address address);
+ bool ShouldRegisterMovingAddress();
// Slots that are not contained within live objects are filtered. This can
// happen when the write barrier for in-payload objects triggers but the outer
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
index e2eef4b7e05..f87e00b143f 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_compact_test.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_compact_test.cc
@@ -224,26 +224,6 @@ TEST_F(HeapCompactTest, CompactDeques) {
EXPECT_EQ(static_cast<int>(7 - i), deque->at(i)->Value());
}
-TEST_F(HeapCompactTest, CompactDequeVectors) {
- Persistent<HeapDeque<IntVector>> deque =
- MakeGarbageCollected<HeapDeque<IntVector>>();
- for (int i = 0; i < 8; ++i) {
- IntWrapper* value = IntWrapper::Create(i, VectorsAreCompacted);
- IntVector vector = IntVector(8, value);
- deque->push_front(vector);
- }
- 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).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).at(i)->Value());
-}
-
TEST_F(HeapCompactTest, CompactLinkedHashSet) {
using OrderedHashSet = HeapLinkedHashSet<Member<IntWrapper>>;
Persistent<OrderedHashSet> set = MakeGarbageCollected<OrderedHashSet>();
@@ -357,6 +337,135 @@ TEST_F(HeapCompactTest, CompactLinkedHashSetNested) {
}
}
+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
//
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 953d4214834..ae8472c80d1 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_page.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_page.cc
@@ -89,21 +89,19 @@ namespace blink {
void HeapObjectHeader::Finalize(Address object, size_t object_size) {
HeapAllocHooks::FreeHookIfEnabled(object);
- const GCInfo* gc_info = GCInfoTable::Get().GCInfoFromIndex(GcInfoIndex());
- if (gc_info->finalize)
- gc_info->finalize(object);
+ const GCInfo& gc_info = GCInfo::From(GcInfoIndex());
+ if (gc_info.finalize)
+ gc_info.finalize(object);
ASAN_RETIRE_CONTAINER_ANNOTATION(object, object_size);
}
bool HeapObjectHeader::HasNonTrivialFinalizer() const {
- const GCInfo* gc_info = GCInfoTable::Get().GCInfoFromIndex(GcInfoIndex());
- return gc_info->finalize;
+ return GCInfo::From(GcInfoIndex()).finalize;
}
const char* HeapObjectHeader::Name() const {
- const GCInfo* gc_info = GCInfoTable::Get().GCInfoFromIndex(GcInfoIndex());
- return gc_info->name(Payload()).value;
+ return GCInfo::From(GcInfoIndex()).name(Payload()).value;
}
BaseArena::BaseArena(ThreadState* state, int index)
@@ -132,7 +130,7 @@ void BaseArena::CollectStatistics(std::string name,
ResetAllocationPoint();
if (!NameClient::HideInternalName()) {
- size_t num_types = GCInfoTable::Get().GcInfoIndex() + 1;
+ const size_t num_types = GCInfoTable::Get().NumberOfGCInfos();
arena_stats.object_stats.num_types = num_types;
arena_stats.object_stats.type_name.resize(num_types);
arena_stats.object_stats.type_count.resize(num_types);
@@ -156,7 +154,7 @@ void NormalPageArena::CollectFreeListStatistics(
}
#if DCHECK_IS_ON()
-BasePage* BaseArena::FindPageFromAddress(Address address) {
+BasePage* BaseArena::FindPageFromAddress(ConstAddress address) const {
for (BasePage* page : swept_pages_) {
if (page->Contains(address))
return page;
@@ -215,6 +213,15 @@ void BaseArena::MakeConsistentForMutator() {
VerifyObjectStartBitmap();
}
+void BaseArena::Unmark() {
+ DCHECK(GetThreadState()->InAtomicMarkingPause());
+ DCHECK(SweepingAndFinalizationCompleted());
+
+ for (BasePage* page : swept_pages_) {
+ page->Unmark();
+ }
+}
+
size_t BaseArena::ObjectPayloadSizeForTesting() {
#if DCHECK_IS_ON()
DCHECK(IsConsistentForGC());
@@ -228,7 +235,7 @@ size_t BaseArena::ObjectPayloadSizeForTesting() {
return object_payload_size;
}
-void BaseArena::PrepareForSweep() {
+void BaseArena::PrepareForSweep(BlinkGC::CollectionType collection_type) {
DCHECK(GetThreadState()->InAtomicMarkingPause());
DCHECK(SweepingAndFinalizationCompleted());
@@ -237,10 +244,23 @@ void BaseArena::PrepareForSweep() {
// Verification depends on the allocation point being cleared.
VerifyObjectStartBitmap();
+ if (collection_type == BlinkGC::CollectionType::kMinor) {
+ auto** first_young =
+ std::partition(swept_pages_.begin(), swept_pages_.end(),
+ [](BasePage* page) { return !page->IsYoung(); });
+ for (auto** it = first_young; it != swept_pages_.end(); ++it) {
+ BasePage* page = *it;
+ page->MarkAsUnswept();
+ page->SetAsYoung(false);
+ unswept_pages_.Push(page);
+ }
+ swept_pages_.erase(first_young, swept_pages_.end());
+ return;
+ }
+
for (BasePage* page : swept_pages_) {
page->MarkAsUnswept();
}
-
// Move all pages to a list of unswept pages.
unswept_pages_.MoveFrom(std::move(swept_pages_));
DCHECK(swept_pages_.IsEmpty());
@@ -268,7 +288,7 @@ Address BaseArena::LazySweep(size_t allocation_size, size_t gc_info_index) {
if (GetThreadState()->SweepForbidden())
return nullptr;
- ThreadHeapStatsCollector::Scope stats_scope(
+ ThreadHeapStatsCollector::EnabledScope stats_scope(
GetThreadState()->Heap().stats_collector(),
ThreadHeapStatsCollector::kLazySweepOnAllocation);
ThreadState::SweepForbiddenScope sweep_forbidden(GetThreadState());
@@ -311,11 +331,9 @@ bool BaseArena::LazySweepWithDeadline(base::TimeTicks deadline) {
DCHECK(ScriptForbiddenScope::IsScriptForbidden());
size_t page_count = 1;
- // TODO(bikineev): We should probably process pages in the reverse order. This
- // will leave more work for concurrent sweeper and reduce memory footprint
- // faster.
- while (BasePage* page = unswept_pages_.PopLocked()) {
- SweepUnsweptPage(page);
+ // First, process empty pages to faster reduce memory footprint.
+ while (BasePage* page = swept_unfinalized_empty_pages_.PopLocked()) {
+ page->FinalizeSweep(SweepResult::kPageEmpty);
if (page_count % kDeadlineCheckInterval == 0) {
if (deadline <= base::TimeTicks::Now()) {
// Deadline has come.
@@ -324,6 +342,7 @@ bool BaseArena::LazySweepWithDeadline(base::TimeTicks deadline) {
}
page_count++;
}
+ // Second, execute finalizers to leave more work for concurrent sweeper.
while (BasePage* page = swept_unfinalized_pages_.PopLocked()) {
swept_pages_.PushLocked(page);
page->FinalizeSweep(SweepResult::kPageNotEmpty);
@@ -335,8 +354,9 @@ bool BaseArena::LazySweepWithDeadline(base::TimeTicks deadline) {
}
page_count++;
}
- while (BasePage* page = swept_unfinalized_empty_pages_.PopLocked()) {
- page->FinalizeSweep(SweepResult::kPageEmpty);
+ // Help concurrent sweeper.
+ while (BasePage* page = unswept_pages_.PopLocked()) {
+ SweepUnsweptPage(page);
if (page_count % kDeadlineCheckInterval == 0) {
if (deadline <= base::TimeTicks::Now()) {
// Deadline has come.
@@ -362,18 +382,12 @@ void BaseArena::InvokeFinalizersOnSweptPages() {
}
}
-bool BaseArena::ConcurrentSweepWithDeadline(base::TimeTicks deadline) {
- static constexpr size_t kDeadlineCheckInterval = 10;
- size_t page_count = 1;
- while (BasePage* page = unswept_pages_.PopLocked()) {
- SweepUnsweptPageOnConcurrentThread(page);
- if (page_count % kDeadlineCheckInterval == 0 &&
- deadline <= base::TimeTicks::Now()) {
- return SweepingCompleted();
- }
- ++page_count;
- }
- return true;
+bool BaseArena::ConcurrentSweepOnePage() {
+ BasePage* page = unswept_pages_.PopLocked();
+ if (!page)
+ return true;
+ SweepUnsweptPageOnConcurrentThread(page);
+ return false;
}
void BaseArena::CompleteSweep() {
@@ -384,14 +398,14 @@ void BaseArena::CompleteSweep() {
// Some phases, e.g. verification, require iterability of a page.
MakeIterable();
- // First, sweep and finalize pages.
+ // First, finalize pages that have been processed by concurrent sweepers.
+ InvokeFinalizersOnSweptPages();
+
+ // Then, sweep and finalize pages.
while (BasePage* page = unswept_pages_.PopLocked()) {
SweepUnsweptPage(page);
}
- // Then, finalize pages that have been processed by concurrent sweepers.
- InvokeFinalizersOnSweptPages();
-
// Verify object start bitmap after all freelists have been merged.
VerifyObjectStartBitmap();
}
@@ -410,9 +424,17 @@ NormalPageArena::NormalPageArena(ThreadState* state, int index)
: BaseArena(state, index),
current_allocation_point_(nullptr),
remaining_allocation_size_(0),
- last_remaining_allocation_size_(0),
- promptly_freed_size_(0) {
- ClearFreeLists();
+ promptly_freed_size_(0) {}
+
+void NormalPageArena::AddToFreeList(Address address, size_t size) {
+#if DCHECK_IS_ON()
+ DCHECK(FindPageFromAddress(address));
+ DCHECK(FindPageFromAddress(address + size - 1));
+#endif
+ free_list_.Add(address, size);
+ static_cast<NormalPage*>(PageFromObject(address))
+ ->object_start_bit_map()
+ ->SetBit(address);
}
void NormalPageArena::MakeConsistentForGC() {
@@ -621,7 +643,7 @@ bool NormalPageArena::IsConsistentForGC() {
return true;
}
-bool NormalPageArena::PagesToBeSweptContains(Address address) {
+bool NormalPageArena::PagesToBeSweptContains(ConstAddress address) const {
for (BasePage* page : unswept_pages_) {
if (page->Contains(address))
return true;
@@ -716,7 +738,7 @@ void NormalPageArena::PromptlyFreeObject(HeapObjectHeader* header) {
if (IsObjectAllocatedAtAllocationPoint(header)) {
current_allocation_point_ -= size;
DCHECK_EQ(address, current_allocation_point_);
- SetRemainingAllocationSize(remaining_allocation_size_ + size);
+ remaining_allocation_size_ += size;
SET_MEMORY_INACCESSIBLE(address, size);
// Memory that is part of the allocation point is not allowed to be part
// of the object start bit map.
@@ -763,7 +785,7 @@ bool NormalPageArena::ExpandObject(HeapObjectHeader* header, size_t new_size) {
expand_size <= remaining_allocation_size_) {
current_allocation_point_ += expand_size;
DCHECK_GE(remaining_allocation_size_, expand_size);
- SetRemainingAllocationSize(remaining_allocation_size_ - expand_size);
+ remaining_allocation_size_ -= expand_size;
// Unpoison the memory used for the object (payload).
SET_MEMORY_ACCESSIBLE(header->PayloadEnd(), expand_size);
header->SetSize(allocation_size);
@@ -782,7 +804,7 @@ bool NormalPageArena::ShrinkObject(HeapObjectHeader* header, size_t new_size) {
size_t shrink_size = header->size() - allocation_size;
if (IsObjectAllocatedAtAllocationPoint(header)) {
current_allocation_point_ -= shrink_size;
- SetRemainingAllocationSize(remaining_allocation_size_ + shrink_size);
+ remaining_allocation_size_ += shrink_size;
SET_MEMORY_INACCESSIBLE(current_allocation_point_, shrink_size);
header->SetSize(allocation_size);
return true;
@@ -790,9 +812,9 @@ bool NormalPageArena::ShrinkObject(HeapObjectHeader* header, size_t new_size) {
DCHECK_GE(shrink_size, sizeof(HeapObjectHeader));
DCHECK_GT(header->GcInfoIndex(), 0u);
Address shrink_address = header->PayloadEnd() - shrink_size;
- HeapObjectHeader* freed_header =
- new (NotNull, shrink_address) HeapObjectHeader(
- shrink_size, header->GcInfoIndex(), HeapObjectHeader::kNormalPage);
+ HeapObjectHeader* freed_header = new (NotNull, shrink_address)
+ HeapObjectHeader(shrink_size, header->GcInfoIndex());
+ // Since only size has been changed, we don't need to update object starts.
PromptlyFreeObjectInFreeList(freed_header, shrink_size);
#if DCHECK_IS_ON()
DCHECK_EQ(PageFromObject(reinterpret_cast<Address>(header)),
@@ -843,24 +865,6 @@ Address NormalPageArena::LazySweepPages(size_t allocation_size,
return result;
}
-void NormalPageArena::SetRemainingAllocationSize(
- size_t new_remaining_allocation_size) {
- remaining_allocation_size_ = new_remaining_allocation_size;
-
- // Sync recorded allocated-object size using the recorded checkpoint in
- // |remaining_allocation_size_|:
- // - If checkpoint is larger, the allocated size has increased.
- // - The allocated size has decreased, otherwise.
- if (last_remaining_allocation_size_ > remaining_allocation_size_) {
- GetThreadState()->Heap().stats_collector()->IncreaseAllocatedObjectSize(
- last_remaining_allocation_size_ - remaining_allocation_size_);
- } else if (last_remaining_allocation_size_ != remaining_allocation_size_) {
- GetThreadState()->Heap().stats_collector()->DecreaseAllocatedObjectSize(
- remaining_allocation_size_ - last_remaining_allocation_size_);
- }
- last_remaining_allocation_size_ = remaining_allocation_size_;
-}
-
void NormalPageArena::SetAllocationPoint(Address point, size_t size) {
#if DCHECK_IS_ON()
if (point) {
@@ -878,7 +882,11 @@ void NormalPageArena::SetAllocationPoint(Address point, size_t size) {
}
// Set up a new linear allocation area.
current_allocation_point_ = point;
- last_remaining_allocation_size_ = remaining_allocation_size_ = size;
+ remaining_allocation_size_ = size;
+ // Update last allocated region in ThreadHeap. This must also be done if the
+ // allocation point is set to 0 (before doing GC), so that the last allocated
+ // region is automatically reset after GC.
+ GetThreadState()->Heap().SetLastAllocatedRegion(point, size);
if (point) {
// Only, update allocated size and object start bitmap if the area is
// actually set up with a non-null address.
@@ -889,6 +897,8 @@ void NormalPageArena::SetAllocationPoint(Address point, size_t size) {
// clearing the allocation point.
NormalPage* page = reinterpret_cast<NormalPage*>(PageFromObject(point));
page->object_start_bit_map()->ClearBit(point);
+ // Mark page as containing young objects.
+ page->SetAsYoung(true);
}
}
@@ -985,8 +995,8 @@ Address LargeObjectArena::DoAllocateLargeObjectPage(size_t allocation_size,
DCHECK_GT(gc_info_index, 0u);
LargeObjectPage* large_object = new (large_object_address)
LargeObjectPage(page_memory, this, allocation_size);
- HeapObjectHeader* header = new (NotNull, header_address) HeapObjectHeader(
- kLargeObjectSizeInHeader, gc_info_index, HeapObjectHeader::kLargePage);
+ HeapObjectHeader* header = new (NotNull, header_address)
+ HeapObjectHeader(kLargeObjectSizeInHeader, gc_info_index);
Address result = header_address + sizeof(*header);
DCHECK(!(reinterpret_cast<uintptr_t>(result) & kAllocationMask));
@@ -997,6 +1007,10 @@ Address LargeObjectArena::DoAllocateLargeObjectPage(size_t allocation_size,
swept_pages_.PushLocked(large_object);
+ // Update last allocated region in ThreadHeap.
+ GetThreadState()->Heap().SetLastAllocatedRegion(large_object->Payload(),
+ large_object->PayloadSize());
+
// Add all segments of kBlinkPageSize to the bloom filter so that the large
// object can be kept by derived pointers on stack. An alternative might be to
// prohibit derived pointers to large objects, but that is dangerous since the
@@ -1009,6 +1023,8 @@ Address LargeObjectArena::DoAllocateLargeObjectPage(size_t allocation_size,
large_object->size());
GetThreadState()->Heap().stats_collector()->IncreaseAllocatedObjectSize(
large_object->PayloadSize());
+ // Add page to the list of young pages.
+ large_object->SetAsYoung(true);
return result;
}
@@ -1053,7 +1069,9 @@ Address LargeObjectArena::LazySweepPages(size_t allocation_size,
return result;
}
-FreeList::FreeList() : biggest_free_list_index_(0) {}
+FreeList::FreeList() : biggest_free_list_index_(0) {
+ Clear();
+}
void FreeList::Add(Address address, size_t size) {
DCHECK_LT(size, BlinkPagePayloadSize());
@@ -1062,15 +1080,15 @@ void FreeList::Add(Address address, size_t size) {
DCHECK(!((reinterpret_cast<uintptr_t>(address) + sizeof(HeapObjectHeader)) &
kAllocationMask));
DCHECK(!(size & kAllocationMask));
+ DCHECK(!PageFromObject(address)->IsLargeObjectPage());
ASAN_UNPOISON_MEMORY_REGION(address, size);
FreeListEntry* entry;
if (size < sizeof(*entry)) {
// Create a dummy header with only a size and freelist bit set.
DCHECK_GE(size, sizeof(HeapObjectHeader));
// Free list encode the size to mark the lost memory as freelist memory.
- new (NotNull, address) HeapObjectHeader(size, kGcInfoIndexForFreeListHeader,
- HeapObjectHeader::kNormalPage);
-
+ new (NotNull, address)
+ HeapObjectHeader(size, kGcInfoIndexForFreeListHeader);
ASAN_POISON_MEMORY_REGION(address, size);
// This memory gets lost. Sweeping can reclaim it.
return;
@@ -1381,11 +1399,18 @@ void NormalPage::ToBeFinalizedObject::Finalize() {
}
void NormalPage::FinalizeSweep(SweepResult action) {
+ // Call finalizers.
for (ToBeFinalizedObject& object : to_be_finalized_objects_) {
object.Finalize();
}
to_be_finalized_objects_.clear();
-
+#if BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
+ // Copy object start bit map.
+ DCHECK(cached_object_start_bit_map_);
+ object_start_bit_map_ = *cached_object_start_bit_map_;
+ cached_object_start_bit_map_.reset();
+#endif
+ // Merge freelists or unmap the page.
if (action == SweepResult::kPageNotEmpty) {
MergeFreeLists();
MarkAsSwept();
@@ -1407,6 +1432,11 @@ void NormalPage::AddToFreeList(Address start,
unfinalized_freelist_.push_back(std::move(entry));
} else {
cached_freelist_.Add(start, size);
+#if BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
+ cached_object_start_bit_map_->SetBit(start);
+#else
+ object_start_bit_map_.SetBit(start);
+#endif
#if !DCHECK_IS_ON() && !defined(LEAK_SANITIZER) && !defined(ADDRESS_SANITIZER)
if (Arena()->GetThreadState()->IsMemoryReducingGC()) {
DiscardPages(start + sizeof(FreeListEntry), start + size);
@@ -1433,7 +1463,14 @@ void NormalPage::MergeFreeLists() {
}
bool NormalPage::Sweep(FinalizeType finalize_type) {
+ ObjectStartBitmap* bitmap;
+#if BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
+ cached_object_start_bit_map_ = std::make_unique<ObjectStartBitmap>(Payload());
+ bitmap = cached_object_start_bit_map_.get();
+#else
object_start_bit_map()->Clear();
+ bitmap = object_start_bit_map();
+#endif
cached_freelist_.Clear();
unfinalized_freelist_.clear();
Address start_of_gap = Payload();
@@ -1478,8 +1515,10 @@ bool NormalPage::Sweep(FinalizeType finalize_type) {
found_finalizer);
found_finalizer = false;
}
- object_start_bit_map()->SetBit(header_address);
+ bitmap->SetBit(header_address);
+#if !BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
header->Unmark<HeapObjectHeader::AccessMode::kAtomic>();
+#endif
header_address += size;
start_of_gap = header_address;
}
@@ -1543,7 +1582,9 @@ void NormalPage::SweepAndCompact(CompactionContext& context) {
header_address += size;
continue;
}
+#if !BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
header->Unmark();
+#endif
// Allocate and copy over the live object.
Address compact_frontier = current_page->Payload() + allocation_point;
if (compact_frontier + size > current_page->PayloadEnd()) {
@@ -1570,8 +1611,9 @@ void NormalPage::SweepAndCompact(CompactionContext& context) {
// store object, let go of the container annotations.
// Do that by unpoisoning the payload entirely.
ASAN_UNPOISON_MEMORY_REGION(header, sizeof(HeapObjectHeader));
- if (is_vector_arena)
+ if (is_vector_arena) {
ASAN_UNPOISON_MEMORY_REGION(payload, payload_size);
+ }
#endif
// Use a non-overlapping copy, if possible.
if (current_page == this)
@@ -1635,6 +1677,30 @@ void NormalPage::MakeConsistentForMutator() {
VerifyObjectStartBitmapIsConsistentWithPayload();
}
+// This is assumed to be called from the atomic pause, so no concurrency should
+// be involved here.
+void NormalPage::Unmark() {
+ const Address current_allocation_point =
+ ArenaForNormalPage()->CurrentAllocationPoint();
+ const size_t allocation_area_size =
+ ArenaForNormalPage()->RemainingAllocationSize();
+ for (Address header_address = Payload(); header_address < PayloadEnd();) {
+ // Since unmarking can happen inside IncrementalMarkingStart, the current
+ // allocation point can be set and we need to skip over it.
+ if (header_address == current_allocation_point && allocation_area_size) {
+ header_address += allocation_area_size;
+ continue;
+ }
+ HeapObjectHeader* header =
+ reinterpret_cast<HeapObjectHeader*>(header_address);
+ if (header->IsMarked()) {
+ header->Unmark();
+ }
+ header_address += header->size();
+ }
+ ClearCardTable();
+}
+
#if defined(ADDRESS_SANITIZER)
void NormalPage::PoisonUnmarkedObjects() {
for (Address header_address = Payload(); header_address < PayloadEnd();) {
@@ -1647,8 +1713,9 @@ void NormalPage::PoisonUnmarkedObjects() {
header_address += header->size();
continue;
}
- if (!header->IsMarked())
+ if (!header->IsMarked()) {
ASAN_POISON_MEMORY_REGION(header->Payload(), header->PayloadSize());
+ }
header_address += header->size();
}
}
@@ -1693,7 +1760,7 @@ void LargeObjectPage::VerifyMarking() {
}
Address ObjectStartBitmap::FindHeader(
- Address address_maybe_pointing_to_the_middle_of_object) {
+ 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;
@@ -1716,7 +1783,7 @@ Address ObjectStartBitmap::FindHeader(
}
HeapObjectHeader* NormalPage::ConservativelyFindHeaderFromAddress(
- Address address) {
+ ConstAddress address) const {
if (!ContainedInObjectPayload(address))
return nullptr;
if (ArenaForNormalPage()->IsInCurrentAllocationPointRegion(address))
@@ -1759,7 +1826,7 @@ void NormalPage::CollectStatistics(
}
#if DCHECK_IS_ON()
-bool NormalPage::Contains(Address addr) {
+bool NormalPage::Contains(ConstAddress addr) const {
Address blink_page_start = RoundToBlinkPageStart(GetAddress());
// Page is at aligned address plus guard page size.
DCHECK_EQ(blink_page_start, GetAddress() - kBlinkGuardPageSize);
@@ -1791,15 +1858,22 @@ bool LargeObjectPage::Sweep(FinalizeType) {
if (!ObjectHeader()->IsMarked()) {
return true;
}
+#if !BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
ObjectHeader()->Unmark();
+#endif
return false;
}
-void LargeObjectPage::MakeConsistentForMutator() {
+void LargeObjectPage::Unmark() {
HeapObjectHeader* header = ObjectHeader();
if (header->IsMarked()) {
header->Unmark();
}
+ SetRemembered(false);
+}
+
+void LargeObjectPage::MakeConsistentForMutator() {
+ Unmark();
}
void LargeObjectPage::FinalizeSweep(SweepResult action) {
@@ -1814,8 +1888,9 @@ void LargeObjectPage::FinalizeSweep(SweepResult action) {
#if defined(ADDRESS_SANITIZER)
void LargeObjectPage::PoisonUnmarkedObjects() {
HeapObjectHeader* header = ObjectHeader();
- if (!header->IsMarked())
+ if (!header->IsMarked()) {
ASAN_POISON_MEMORY_REGION(header->Payload(), header->PayloadSize());
+ }
}
#endif
@@ -1840,7 +1915,7 @@ void LargeObjectPage::CollectStatistics(
}
#if DCHECK_IS_ON()
-bool LargeObjectPage::Contains(Address object) {
+bool LargeObjectPage::Contains(ConstAddress object) const {
return RoundToBlinkPageStart(GetAddress()) <= object &&
object < RoundToBlinkPageEnd(GetAddress() + size());
}
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 4a937e53c1d..f9f0076112c 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_page.h
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_page.h
@@ -32,6 +32,7 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_PAGE_H_
#include <stdint.h>
+#include <array>
#include <atomic>
#include "base/bits.h"
@@ -39,8 +40,10 @@
#include "build/build_config.h"
#include "third_party/blink/renderer/platform/heap/blink_gc.h"
#include "third_party/blink/renderer/platform/heap/gc_info.h"
+#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
#include "third_party/blink/renderer/platform/heap/thread_state.h"
#include "third_party/blink/renderer/platform/heap/thread_state_statistics.h"
+#include "third_party/blink/renderer/platform/heap/unsanitized_atomic.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -179,28 +182,6 @@ static_assert(
namespace internal {
-// This is needed due to asan complaining deep from std::atomic<>::load/store
-// stacktraces.
-class AsanUnpoisonScope {
- public:
- AsanUnpoisonScope(const void* addr, size_t size)
- : addr_(addr), size_(size), was_poisoned_(false) {
- if (!ASAN_REGION_IS_POISONED(const_cast<void*>(addr_), size_))
- return;
- ASAN_UNPOISON_MEMORY_REGION(addr_, size_);
- was_poisoned_ = true;
- }
- ~AsanUnpoisonScope() {
- if (was_poisoned_)
- ASAN_POISON_MEMORY_REGION(addr_, size_);
- }
-
- private:
- const void* addr_;
- size_t size_;
- bool was_poisoned_;
-};
-
NO_SANITIZE_ADDRESS constexpr uint16_t EncodeSize(size_t size) {
// Essentially, gets optimized to >> 1.
return static_cast<uint16_t>((size << kHeaderSizeShift) /
@@ -219,7 +200,6 @@ class PLATFORM_EXPORT HeapObjectHeader {
DISALLOW_NEW();
public:
- enum HeaderLocation : uint8_t { kNormalPage, kLargePage };
enum class AccessMode : uint8_t { kNonAtomic, kAtomic };
static HeapObjectHeader* FromPayload(const void*);
@@ -230,7 +210,7 @@ class PLATFORM_EXPORT HeapObjectHeader {
static void CheckFromPayload(const void*);
// If |gc_info_index| is 0, this header is interpreted as a free list header.
- HeapObjectHeader(size_t, size_t, HeaderLocation);
+ HeapObjectHeader(size_t, size_t);
template <AccessMode mode = AccessMode::kNonAtomic>
NO_SANITIZE_ADDRESS bool IsFree() const {
@@ -239,7 +219,8 @@ class PLATFORM_EXPORT HeapObjectHeader {
template <AccessMode mode = AccessMode::kNonAtomic>
NO_SANITIZE_ADDRESS uint32_t GcInfoIndex() const {
- const uint16_t encoded = LoadEncoded<mode, EncodedHalf::kHigh>();
+ const uint16_t encoded =
+ LoadEncoded<mode, EncodedHalf::kHigh, std::memory_order_acquire>();
return (encoded & kHeaderGCInfoIndexMask) >> kHeaderGCInfoIndexShift;
}
@@ -247,18 +228,20 @@ class PLATFORM_EXPORT HeapObjectHeader {
size_t size() const;
void SetSize(size_t size);
+ template <AccessMode = AccessMode::kNonAtomic>
bool IsLargeObject() const;
template <AccessMode = AccessMode::kNonAtomic>
bool IsMarked() const;
template <AccessMode = AccessMode::kNonAtomic>
- void Mark();
- template <AccessMode = AccessMode::kNonAtomic>
void Unmark();
template <AccessMode = AccessMode::kNonAtomic>
bool TryMark();
template <AccessMode = AccessMode::kNonAtomic>
+ bool IsOld() const;
+
+ template <AccessMode = AccessMode::kNonAtomic>
bool IsInConstruction() const;
template <AccessMode = AccessMode::kNonAtomic>
void MarkFullyConstructed();
@@ -281,9 +264,13 @@ class PLATFORM_EXPORT HeapObjectHeader {
private:
enum class EncodedHalf : uint8_t { kLow, kHigh };
- template <AccessMode, EncodedHalf>
+ template <AccessMode,
+ EncodedHalf part,
+ std::memory_order = std::memory_order_seq_cst>
uint16_t LoadEncoded() const;
- template <AccessMode mode, EncodedHalf>
+ template <AccessMode mode,
+ EncodedHalf part,
+ std::memory_order = std::memory_order_seq_cst>
void StoreEncoded(uint16_t bits, uint16_t mask);
#if defined(ARCH_CPU_64_BITS)
@@ -297,11 +284,7 @@ class FreeListEntry final : public HeapObjectHeader {
public:
NO_SANITIZE_ADDRESS
explicit FreeListEntry(size_t size)
- : HeapObjectHeader(size,
- kGcInfoIndexForFreeListHeader,
- HeapObjectHeader::kNormalPage),
- next_(nullptr) {
- }
+ : HeapObjectHeader(size, kGcInfoIndexForFreeListHeader), next_(nullptr) {}
Address GetAddress() { return reinterpret_cast<Address>(this); }
@@ -386,7 +369,7 @@ class FreeList {
};
// Blink heap pages are set up with a guard page before and after the payload.
-inline size_t BlinkPagePayloadSize() {
+constexpr size_t BlinkPagePayloadSize() {
return kBlinkPageSize - 2 * kBlinkGuardPageSize;
}
@@ -410,8 +393,8 @@ inline Address BlinkPageAddress(Address address) {
kBlinkPageBaseMask);
}
-inline bool VTableInitialized(void* object_pointer) {
- return !!(*reinterpret_cast<Address*>(object_pointer));
+inline bool VTableInitialized(const void* object_pointer) {
+ return !!(*reinterpret_cast<const ConstAddress*>(object_pointer));
}
#if DCHECK_IS_ON()
@@ -465,6 +448,7 @@ class BasePage {
// Does not create free list entries for empty pages.
virtual bool Sweep(FinalizeType) = 0;
virtual void MakeConsistentForMutator() = 0;
+ virtual void Unmark() = 0;
// Calls finalizers after sweeping is done.
virtual void FinalizeSweep(SweepResult) = 0;
@@ -477,11 +461,13 @@ class BasePage {
ThreadState::Statistics::ArenaStatistics* arena_stats) = 0;
#if DCHECK_IS_ON()
- virtual bool Contains(Address) = 0;
+ virtual bool Contains(ConstAddress) const = 0;
#endif
- virtual size_t size() = 0;
+ virtual size_t size() const = 0;
- Address GetAddress() { return reinterpret_cast<Address>(this); }
+ Address GetAddress() const {
+ return reinterpret_cast<Address>(const_cast<BasePage*>(this));
+ }
PageMemory* Storage() const { return storage_; }
BaseArena* Arena() const { return arena_; }
ThreadState* thread_state() const { return thread_state_; }
@@ -505,6 +491,11 @@ class BasePage {
return page_type_ == PageType::kLargeObjectPage;
}
+ // Young pages are pages that contain at least a single young object.
+ bool IsYoung() const { return is_young_; }
+
+ void SetAsYoung(bool young) { is_young_ = young; }
+
virtual void VerifyMarking() = 0;
private:
@@ -515,6 +506,7 @@ class BasePage {
// Track the sweeping state of a page. Set to false at the start of a sweep,
// true upon completion of sweeping that page.
bool swept_ = true;
+ bool is_young_ = false;
PageType page_type_;
@@ -544,8 +536,11 @@ class PageStack : Vector<BasePage*> {
}
using Base::begin;
- using Base::clear;
using Base::end;
+
+ using Base::clear;
+ using Base::erase;
+
using Base::IsEmpty;
using Base::size;
};
@@ -581,7 +576,7 @@ class PageStackThreadSafe : public PageStack {
// - kBlinkPageSize
// - kAllocationGranularity
class PLATFORM_EXPORT ObjectStartBitmap {
- DISALLOW_NEW();
+ USING_FAST_MALLOC(ObjectStartBitmap);
public:
// Granularity of addresses added to the bitmap.
@@ -597,7 +592,8 @@ 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.
- Address FindHeader(Address address_maybe_pointing_to_the_middle_of_object);
+ Address FindHeader(
+ ConstAddress address_maybe_pointing_to_the_middle_of_object) const;
inline void SetBit(Address);
inline void ClearBit(Address);
@@ -625,7 +621,7 @@ class PLATFORM_EXPORT ObjectStartBitmap {
inline void ObjectStartIndexAndBit(Address, size_t*, size_t*) const;
- const Address offset_;
+ Address offset_;
// The bitmap contains a bit for every kGranularity aligned address on a
// a NormalPage, i.e., for a page of size kBlinkPageSize.
uint8_t object_start_bit_map_[kReservedForBitmap];
@@ -636,12 +632,12 @@ class PLATFORM_EXPORT NormalPage final : public BasePage {
NormalPage(PageMemory*, BaseArena*);
~NormalPage() override;
- Address Payload() { return GetAddress() + PageHeaderSize(); }
- size_t PayloadSize() {
+ Address Payload() const { return GetAddress() + PageHeaderSize(); }
+ static constexpr size_t PayloadSize() {
return (BlinkPagePayloadSize() - PageHeaderSize()) & ~kAllocationMask;
}
- Address PayloadEnd() { return Payload() + PayloadSize(); }
- bool ContainedInObjectPayload(Address address) {
+ Address PayloadEnd() const { return Payload() + PayloadSize(); }
+ bool ContainedInObjectPayload(ConstAddress address) const {
return Payload() <= address && address < PayloadEnd();
}
@@ -649,6 +645,7 @@ class PLATFORM_EXPORT NormalPage final : public BasePage {
void RemoveFromHeap() override;
bool Sweep(FinalizeType) override;
void MakeConsistentForMutator() override;
+ void Unmark() override;
void FinalizeSweep(SweepResult) override;
#if defined(ADDRESS_SANITIZER)
void PoisonUnmarkedObjects() override;
@@ -661,17 +658,17 @@ class PLATFORM_EXPORT NormalPage final : public BasePage {
// Returns true for the whole |kBlinkPageSize| page that the page is on, even
// for the header, and the unmapped guard page at the start. That ensures the
// result can be used to populate the negative page cache.
- bool Contains(Address) override;
+ bool Contains(ConstAddress) const override;
#endif
- size_t size() override { return kBlinkPageSize; }
- static size_t PageHeaderSize() {
+ size_t size() const override { return kBlinkPageSize; }
+ static constexpr size_t PageHeaderSize() {
// Compute the amount of padding we have to add to a header to make the size
// of the header plus the padding a multiple of 8 bytes.
- size_t padding_size =
+ constexpr size_t kPaddingSize =
(sizeof(NormalPage) + kAllocationGranularity -
(sizeof(HeapObjectHeader) % kAllocationGranularity)) %
kAllocationGranularity;
- return sizeof(NormalPage) + padding_size;
+ return sizeof(NormalPage) + kPaddingSize;
}
inline NormalPageArena* ArenaForNormalPage() const;
@@ -698,6 +695,9 @@ class PLATFORM_EXPORT NormalPage final : public BasePage {
// Object start bitmap of this page.
ObjectStartBitmap* object_start_bit_map() { return &object_start_bit_map_; }
+ const ObjectStartBitmap* object_start_bit_map() const {
+ return &object_start_bit_map_;
+ }
// Verifies that the object start bitmap only contains a bit iff the object
// is also reachable through iteration on the page.
@@ -706,18 +706,87 @@ 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.
- HeapObjectHeader* ConservativelyFindHeaderFromAddress(Address);
+ HeapObjectHeader* ConservativelyFindHeaderFromAddress(ConstAddress) const;
// Uses the object_start_bit_map_ to find an object for a given address. It is
// assumed that the address points into a valid heap object. Use the
// conservative version if that assumption does not hold.
template <
HeapObjectHeader::AccessMode = HeapObjectHeader::AccessMode::kNonAtomic>
- HeapObjectHeader* FindHeaderFromAddress(Address);
+ HeapObjectHeader* FindHeaderFromAddress(ConstAddress) const;
void VerifyMarking() override;
+ // Marks a card corresponding to address.
+ void MarkCard(Address address);
+
+ // Iterates over all objects in marked cards.
+ template <typename Function>
+ void IterateCardTable(Function function) const;
+
+ // Clears all bits in the card table.
+ void ClearCardTable() { card_table_.Clear(); }
+
private:
+ // Data structure that divides a page in a number of cards each of 512 bytes
+ // size. Marked cards are stored in bytes, not bits, to make write barrier
+ // faster and reduce chances of false sharing. This gives only ~0.1% of memory
+ // overhead. Also, since there are guard pages before and after a Blink page,
+ // some of card bits are wasted and unneeded.
+ class CardTable final {
+ public:
+ struct value_type {
+ uint8_t bit;
+ size_t index;
+ };
+
+ struct iterator {
+ iterator& operator++() {
+ ++index;
+ return *this;
+ }
+ value_type operator*() const { return {table->table_[index], index}; }
+ bool operator!=(iterator other) const {
+ return table != other.table || index != other.index;
+ }
+
+ size_t index = 0;
+ const CardTable* table = nullptr;
+ };
+
+ using const_iterator = iterator;
+
+ static constexpr size_t kBitsPerCard = 9;
+ static constexpr size_t kCardSize = 1 << kBitsPerCard;
+
+ const_iterator begin() const { return {FirstPayloadCard(), this}; }
+ const_iterator end() const { return {LastPayloadCard(), this}; }
+
+ void Mark(size_t card) {
+ DCHECK_LE(FirstPayloadCard(), card);
+ DCHECK_GT(LastPayloadCard(), card);
+ table_[card] = 1;
+ }
+
+ bool IsMarked(size_t card) const {
+ DCHECK_LE(FirstPayloadCard(), card);
+ DCHECK_GT(LastPayloadCard(), card);
+ return table_[card];
+ }
+
+ void Clear() { std::fill(table_.begin(), table_.end(), 0); }
+
+ private:
+ static constexpr size_t FirstPayloadCard() {
+ return (kBlinkGuardPageSize + NormalPage::PageHeaderSize()) / kCardSize;
+ }
+ static constexpr size_t LastPayloadCard() {
+ return (kBlinkGuardPageSize + BlinkPagePayloadSize()) / kCardSize;
+ }
+
+ std::array<uint8_t, kBlinkPageSize / kCardSize> table_{};
+ };
+
struct ToBeFinalizedObject {
HeapObjectHeader* header;
void Finalize();
@@ -727,16 +796,25 @@ class PLATFORM_EXPORT NormalPage final : public BasePage {
size_t size;
};
+ template <typename Function>
+ void IterateOnCard(Function function, size_t card_number) const;
+
void MergeFreeLists();
void AddToFreeList(Address start,
size_t size,
FinalizeType finalize_type,
bool found_finalizer);
+ CardTable card_table_;
ObjectStartBitmap object_start_bit_map_;
+#if BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
+ std::unique_ptr<ObjectStartBitmap> cached_object_start_bit_map_;
+#endif
Vector<ToBeFinalizedObject> to_be_finalized_objects_;
FreeList cached_freelist_;
Vector<FutureFreelistEntry> unfinalized_freelist_;
+
+ friend class CardTableTest;
};
// Large allocations are allocated as separate objects and linked in a list.
@@ -771,7 +849,7 @@ class PLATFORM_EXPORT LargeObjectPage final : public BasePage {
// ObjectSize(): PayloadSize() + sizeof(HeapObjectHeader)
// size(): ObjectSize() + PageHeaderSize()
- HeapObjectHeader* ObjectHeader() {
+ HeapObjectHeader* ObjectHeader() const {
Address header_address = GetAddress() + PageHeaderSize();
return reinterpret_cast<HeapObjectHeader*>(header_address);
}
@@ -781,18 +859,18 @@ class PLATFORM_EXPORT LargeObjectPage final : public BasePage {
size_t ObjectSize() const { return object_size_; }
// Returns the size of the page including the header.
- size_t size() override { return PageHeaderSize() + object_size_; }
+ size_t size() const override { return PageHeaderSize() + object_size_; }
// Returns the payload start of the underlying object.
- Address Payload() { return ObjectHeader()->Payload(); }
+ Address Payload() const { return ObjectHeader()->Payload(); }
// Returns the payload size of the underlying object.
- size_t PayloadSize() { return object_size_ - sizeof(HeapObjectHeader); }
+ size_t PayloadSize() const { return object_size_ - sizeof(HeapObjectHeader); }
// Points to the payload end of the underlying object.
- Address PayloadEnd() { return Payload() + PayloadSize(); }
+ Address PayloadEnd() const { return Payload() + PayloadSize(); }
- bool ContainedInObjectPayload(Address address) {
+ bool ContainedInObjectPayload(ConstAddress address) const {
return Payload() <= address && address < PayloadEnd();
}
@@ -800,6 +878,7 @@ class PLATFORM_EXPORT LargeObjectPage final : public BasePage {
void RemoveFromHeap() override;
bool Sweep(FinalizeType) override;
void MakeConsistentForMutator() override;
+ void Unmark() override;
void FinalizeSweep(SweepResult) override;
void CollectStatistics(
@@ -815,7 +894,7 @@ class PLATFORM_EXPORT LargeObjectPage final : public BasePage {
// Returns true for any address that is on one of the pages that this large
// object uses. That ensures that we can use a negative result to populate the
// negative page cache.
- bool Contains(Address) override;
+ bool Contains(ConstAddress) const override;
#endif
#ifdef ANNOTATE_CONTIGUOUS_CONTAINER
@@ -823,12 +902,19 @@ class PLATFORM_EXPORT LargeObjectPage final : public BasePage {
bool IsVectorBackingPage() const { return is_vector_backing_page_; }
#endif
+ // Remembers the page as containing inter-generational pointers.
+ void SetRemembered(bool remembered) {
+ is_remembered_ = remembered;
+ }
+ bool IsRemembered() const { return is_remembered_; }
+
private:
// The size of the underlying object including HeapObjectHeader.
size_t object_size_;
#ifdef ANNOTATE_CONTIGUOUS_CONTAINER
bool is_vector_backing_page_;
#endif
+ bool is_remembered_ = false;
};
// Each thread has a number of thread arenas (e.g., Generic arenas, typed arenas
@@ -852,17 +938,18 @@ class PLATFORM_EXPORT BaseArena {
ThreadState::Statistics::FreeListStatistics*) {}
#if DCHECK_IS_ON()
- BasePage* FindPageFromAddress(Address);
+ BasePage* FindPageFromAddress(ConstAddress) const;
#endif
virtual void ClearFreeLists() {}
virtual void MakeIterable() {}
virtual void MakeConsistentForGC();
void MakeConsistentForMutator();
+ void Unmark();
#if DCHECK_IS_ON()
virtual bool IsConsistentForGC() = 0;
#endif
size_t ObjectPayloadSizeForTesting();
- void PrepareForSweep();
+ void PrepareForSweep(BlinkGC::CollectionType);
#if defined(ADDRESS_SANITIZER)
void PoisonUnmarkedObjects();
#endif
@@ -872,7 +959,8 @@ class PLATFORM_EXPORT BaseArena {
// Returns true if we have swept all pages within the deadline. Returns false
// otherwise.
bool LazySweepWithDeadline(base::TimeTicks deadline);
- bool ConcurrentSweepWithDeadline(base::TimeTicks deadline);
+ // Returns true if the arena has been fully swept.
+ bool ConcurrentSweepOnePage();
void CompleteSweep();
void InvokeFinalizersOnSweptPages();
@@ -919,15 +1007,7 @@ class PLATFORM_EXPORT BaseArena {
class PLATFORM_EXPORT NormalPageArena final : public BaseArena {
public:
NormalPageArena(ThreadState*, int index);
- void AddToFreeList(Address address, size_t size) {
-#if DCHECK_IS_ON()
- DCHECK(FindPageFromAddress(address));
- // TODO(palmer): Do we need to handle about integer overflow here (and in
- // similar expressions elsewhere)?
- DCHECK(FindPageFromAddress(address + size - 1));
-#endif
- free_list_.Add(address, size);
- }
+ void AddToFreeList(Address address, size_t size);
void AddToFreeList(FreeList* other) { free_list_.MoveFrom(other); }
void ClearFreeLists() override;
void CollectFreeListStatistics(
@@ -936,7 +1016,7 @@ class PLATFORM_EXPORT NormalPageArena final : public BaseArena {
#if DCHECK_IS_ON()
bool IsConsistentForGC() override;
- bool PagesToBeSweptContains(Address);
+ bool PagesToBeSweptContains(ConstAddress) const;
#endif
Address AllocateObject(size_t allocation_size, size_t gc_info_index);
@@ -964,7 +1044,7 @@ class PLATFORM_EXPORT NormalPageArena final : public BaseArena {
Address CurrentAllocationPoint() const { return current_allocation_point_; }
- bool IsInCurrentAllocationPointRegion(Address address) const {
+ bool IsInCurrentAllocationPointRegion(ConstAddress address) const {
return HasCurrentAllocationArea() &&
(CurrentAllocationPoint() <= address) &&
(address < (CurrentAllocationPoint() + RemainingAllocationSize()));
@@ -974,6 +1054,9 @@ class PLATFORM_EXPORT NormalPageArena final : public BaseArena {
void MakeConsistentForGC() override;
+ template <typename Function>
+ void IterateAndClearCardTables(Function function);
+
private:
void AllocatePage();
@@ -992,14 +1075,9 @@ class PLATFORM_EXPORT NormalPageArena final : public BaseArena {
}
void SetAllocationPoint(Address, size_t);
- // Only use when adjusting the area from allocation and free and not when
- // returning it to free list.
- void SetRemainingAllocationSize(size_t);
-
FreeList free_list_;
Address current_allocation_point_;
size_t remaining_allocation_size_;
- size_t last_remaining_allocation_size_;
// The size of promptly freed objects in the heap. This counter is set to
// zero before sweeping when clearing the free list and after coalescing.
@@ -1017,6 +1095,9 @@ class LargeObjectArena final : public BaseArena {
bool IsConsistentForGC() override { return true; }
#endif
+ template <typename Function>
+ void IterateAndClearRememberedPages(Function function);
+
private:
Address DoAllocateLargeObjectPage(size_t, size_t gc_info_index);
Address LazySweepPages(size_t, size_t gc_info_index) override;
@@ -1053,7 +1134,7 @@ inline HeapObjectHeader* HeapObjectHeader::FromInnerAddress(
return page->IsLargeObjectPage()
? static_cast<LargeObjectPage*>(page)->ObjectHeader()
: static_cast<NormalPage*>(page)->FindHeaderFromAddress<mode>(
- reinterpret_cast<Address>(const_cast<void*>(address)));
+ reinterpret_cast<ConstAddress>(address));
}
inline void HeapObjectHeader::CheckFromPayload(const void* payload) {
@@ -1062,19 +1143,10 @@ inline void HeapObjectHeader::CheckFromPayload(const void* payload) {
template <HeapObjectHeader::AccessMode mode>
NO_SANITIZE_ADDRESS inline size_t HeapObjectHeader::size() const {
- uint16_t encoded_low_value;
- if (mode == AccessMode::kNonAtomic) {
- encoded_low_value = encoded_low_;
- } else {
- // mode == AccessMode::kAtomic
- // Relaxed load as size is immutable after construction while either
- // marking or sweeping is running
- internal::AsanUnpoisonScope unpoison_scope(
- static_cast<const void*>(&encoded_low_), sizeof(encoded_low_));
- encoded_low_value =
- reinterpret_cast<const std::atomic<uint16_t>&>(encoded_low_)
- .load(std::memory_order_relaxed);
- }
+ // Size is immutable after construction while either marking or sweeping
+ // is running so relaxed load (if mode == kAtomic) is enough.
+ uint16_t encoded_low_value =
+ LoadEncoded<mode, EncodedHalf::kLow, std::memory_order_relaxed>();
const size_t result = internal::DecodeSize(encoded_low_value);
// Large objects should not refer to header->size() but use
// LargeObjectPage::PayloadSize().
@@ -1090,21 +1162,24 @@ NO_SANITIZE_ADDRESS inline void HeapObjectHeader::SetSize(size_t size) {
(encoded_low_ & ~kHeaderSizeMask));
}
+template <HeapObjectHeader::AccessMode mode>
NO_SANITIZE_ADDRESS inline bool HeapObjectHeader::IsLargeObject() const {
- return internal::DecodeSize(encoded_low_) == kLargeObjectSizeInHeader;
+ uint16_t encoded_low_value =
+ LoadEncoded<mode, EncodedHalf::kLow, std::memory_order_relaxed>();
+ return internal::DecodeSize(encoded_low_value) == kLargeObjectSizeInHeader;
}
template <HeapObjectHeader::AccessMode mode>
NO_SANITIZE_ADDRESS inline bool HeapObjectHeader::IsInConstruction() const {
- return (LoadEncoded<mode, EncodedHalf::kHigh>() &
+ return (LoadEncoded<mode, EncodedHalf::kHigh, std::memory_order_acquire>() &
kHeaderIsInConstructionMask) == 0;
}
template <HeapObjectHeader::AccessMode mode>
NO_SANITIZE_ADDRESS inline void HeapObjectHeader::MarkFullyConstructed() {
DCHECK(IsInConstruction());
- StoreEncoded<mode, EncodedHalf::kHigh>(kHeaderIsInConstructionMask,
- kHeaderIsInConstructionMask);
+ StoreEncoded<mode, EncodedHalf::kHigh, std::memory_order_release>(
+ kHeaderIsInConstructionMask, kHeaderIsInConstructionMask);
}
inline Address HeapObjectHeader::Payload() const {
@@ -1130,20 +1205,22 @@ NO_SANITIZE_ADDRESS inline size_t HeapObjectHeader::PayloadSize() const {
template <HeapObjectHeader::AccessMode mode>
NO_SANITIZE_ADDRESS inline bool HeapObjectHeader::IsMarked() const {
- const uint16_t encoded = LoadEncoded<mode, EncodedHalf::kLow>();
+ const uint16_t encoded =
+ LoadEncoded<mode, EncodedHalf::kLow, std::memory_order_relaxed>();
return encoded & kHeaderMarkBitMask;
}
template <HeapObjectHeader::AccessMode mode>
-NO_SANITIZE_ADDRESS inline void HeapObjectHeader::Mark() {
- DCHECK(!IsMarked<mode>());
- StoreEncoded<mode, EncodedHalf::kLow>(kHeaderMarkBitMask, kHeaderMarkBitMask);
+NO_SANITIZE_ADDRESS inline bool HeapObjectHeader::IsOld() const {
+ // Oilpan uses the sticky-mark-bits technique to encode old objects.
+ return IsMarked<mode>();
}
template <HeapObjectHeader::AccessMode mode>
NO_SANITIZE_ADDRESS inline void HeapObjectHeader::Unmark() {
DCHECK(IsMarked<mode>());
- StoreEncoded<mode, EncodedHalf::kLow>(0u, kHeaderMarkBitMask);
+ StoreEncoded<mode, EncodedHalf::kLow, std::memory_order_relaxed>(
+ 0u, kHeaderMarkBitMask);
}
// The function relies on size bits being unmodified when the function is
@@ -1156,16 +1233,12 @@ NO_SANITIZE_ADDRESS inline bool HeapObjectHeader::TryMark() {
encoded_low_ |= kHeaderMarkBitMask;
return true;
}
- internal::AsanUnpoisonScope unpoison_scope(
- static_cast<const void*>(&encoded_low_), sizeof(encoded_low_));
- auto* atomic_encoded =
- reinterpret_cast<std::atomic<uint16_t>*>(&encoded_low_);
+ auto* atomic_encoded = internal::AsUnsanitizedAtomic(&encoded_low_);
uint16_t old_value = atomic_encoded->load(std::memory_order_relaxed);
if (old_value & kHeaderMarkBitMask)
return false;
const uint16_t new_value = old_value | kHeaderMarkBitMask;
return atomic_encoded->compare_exchange_strong(old_value, new_value,
- std::memory_order_acq_rel,
std::memory_order_relaxed);
}
@@ -1176,8 +1249,12 @@ inline Address NormalPageArena::AllocateObject(size_t allocation_size,
current_allocation_point_ += allocation_size;
remaining_allocation_size_ -= allocation_size;
DCHECK_GT(gc_info_index, 0u);
- new (NotNull, header_address) HeapObjectHeader(
- allocation_size, gc_info_index, HeapObjectHeader::kNormalPage);
+ new (NotNull, header_address)
+ HeapObjectHeader(allocation_size, gc_info_index);
+ DCHECK(!PageFromObject(header_address)->IsLargeObjectPage());
+ static_cast<NormalPage*>(PageFromObject(header_address))
+ ->object_start_bit_map()
+ ->SetBit(header_address);
Address result = header_address + sizeof(HeapObjectHeader);
DCHECK(!(reinterpret_cast<uintptr_t>(result) & kAllocationMask));
@@ -1194,6 +1271,29 @@ inline NormalPageArena* NormalPage::ArenaForNormalPage() const {
return static_cast<NormalPageArena*>(Arena());
}
+// Iterates over all card tables and clears them.
+template <typename Function>
+inline void NormalPageArena::IterateAndClearCardTables(Function function) {
+ for (BasePage* page : swept_pages_) {
+ auto* normal_page = static_cast<NormalPage*>(page);
+ normal_page->IterateCardTable(function);
+ normal_page->ClearCardTable();
+ }
+}
+
+// Iterates over all pages that may contain inter-generational pointers.
+template <typename Function>
+inline void LargeObjectArena::IterateAndClearRememberedPages(
+ Function function) {
+ for (BasePage* page : swept_pages_) {
+ auto* large_page = static_cast<LargeObjectPage*>(page);
+ if (large_page->IsRemembered()) {
+ function(large_page->ObjectHeader());
+ large_page->SetRemembered(false);
+ }
+ }
+}
+
inline void ObjectStartBitmap::SetBit(Address header_address) {
size_t cell_index, object_bit;
ObjectStartIndexAndBit(header_address, &cell_index, &object_bit);
@@ -1248,8 +1348,7 @@ inline void ObjectStartBitmap::Iterate(Callback callback) const {
NO_SANITIZE_ADDRESS inline HeapObjectHeader::HeapObjectHeader(
size_t size,
- size_t gc_info_index,
- HeaderLocation header_location) {
+ size_t gc_info_index) {
// sizeof(HeapObjectHeader) must be equal to or smaller than
// |kAllocationGranularity|, because |HeapObjectHeader| is used as a header
// for a freed entry. Given that the smallest entry size is
@@ -1264,52 +1363,44 @@ NO_SANITIZE_ADDRESS inline HeapObjectHeader::HeapObjectHeader(
encoded_high_ =
static_cast<uint16_t>(gc_info_index << kHeaderGCInfoIndexShift);
encoded_low_ = internal::EncodeSize(size);
- if (header_location == kNormalPage) {
- DCHECK(!PageFromObject(this)->IsLargeObjectPage());
- static_cast<NormalPage*>(PageFromObject(this))
- ->object_start_bit_map()
- ->SetBit(reinterpret_cast<Address>(this));
- } else {
- DCHECK(PageFromObject(this)->IsLargeObjectPage());
- }
DCHECK(IsInConstruction());
}
-template <HeapObjectHeader::AccessMode mode, HeapObjectHeader::EncodedHalf part>
+template <HeapObjectHeader::AccessMode mode,
+ HeapObjectHeader::EncodedHalf part,
+ std::memory_order memory_order>
NO_SANITIZE_ADDRESS inline uint16_t HeapObjectHeader::LoadEncoded() const {
const uint16_t& half =
- (part == EncodedHalf::kLow ? encoded_low_ : encoded_high_);
- internal::AsanUnpoisonScope unpoison_scope(static_cast<const void*>(&half),
- sizeof(half));
+ part == EncodedHalf::kLow ? encoded_low_ : encoded_high_;
if (mode == AccessMode::kNonAtomic)
return half;
- return reinterpret_cast<const std::atomic<uint16_t>&>(half).load(
- std::memory_order_acquire);
+ return internal::AsUnsanitizedAtomic(&half)->load(memory_order);
}
// Sets bits selected by the mask to the given value. Please note that atomicity
// of the whole operation is not guaranteed.
-template <HeapObjectHeader::AccessMode mode, HeapObjectHeader::EncodedHalf part>
+template <HeapObjectHeader::AccessMode mode,
+ HeapObjectHeader::EncodedHalf part,
+ std::memory_order memory_order>
NO_SANITIZE_ADDRESS inline void HeapObjectHeader::StoreEncoded(uint16_t bits,
uint16_t mask) {
DCHECK_EQ(static_cast<uint16_t>(0u), bits & ~mask);
- uint16_t* half = (part == EncodedHalf::kLow ? &encoded_low_ : &encoded_high_);
- internal::AsanUnpoisonScope unpoison_scope(static_cast<void*>(half),
- sizeof(&half));
+ uint16_t& half = part == EncodedHalf::kLow ? encoded_low_ : encoded_high_;
if (mode == AccessMode::kNonAtomic) {
- *half = (*half & ~mask) | bits;
+ half = (half & ~mask) | bits;
return;
}
// We don't perform CAS loop here assuming that the data is constant and no
// one except for us can change this half concurrently.
- auto* atomic_encoded = reinterpret_cast<std::atomic<uint16_t>*>(half);
+ auto* atomic_encoded = internal::AsUnsanitizedAtomic(&half);
uint16_t value = atomic_encoded->load(std::memory_order_relaxed);
value = (value & ~mask) | bits;
- atomic_encoded->store(value, std::memory_order_release);
+ atomic_encoded->store(value, memory_order);
}
template <HeapObjectHeader::AccessMode mode>
-HeapObjectHeader* NormalPage::FindHeaderFromAddress(Address address) {
+HeapObjectHeader* NormalPage::FindHeaderFromAddress(
+ ConstAddress address) const {
DCHECK(ContainedInObjectPayload(address));
DCHECK(!ArenaForNormalPage()->IsInCurrentAllocationPointRegion(address));
HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(
@@ -1319,6 +1410,54 @@ HeapObjectHeader* NormalPage::FindHeaderFromAddress(Address address) {
return header;
}
+template <typename Function>
+void NormalPage::IterateCardTable(Function function) const {
+ // TODO(bikineev): Consider introducing a "dirty" per-page bit to avoid
+ // the loop (this may in turn pessimize barrier implementation).
+ for (auto card : card_table_) {
+ if (UNLIKELY(card.bit)) {
+ IterateOnCard(std::move(function), card.index);
+ }
+ }
+}
+
+// Iterates over all objects in the specified marked card. Please note that
+// since objects are not aligned by the card boundary, it starts from the
+// object which may reside on a previous card.
+template <typename Function>
+void NormalPage::IterateOnCard(Function function, size_t card_number) const {
+#if DCHECK_IS_ON()
+ DCHECK(card_table_.IsMarked(card_number));
+ DCHECK(ArenaForNormalPage()->IsConsistentForGC());
+#endif
+
+ const Address card_begin = RoundToBlinkPageStart(GetAddress()) +
+ (card_number << CardTable::kBitsPerCard);
+ const Address card_end = card_begin + CardTable::kCardSize;
+ // Generational barrier marks cards corresponding to slots (not source
+ // objects), therefore the potential source object may reside on a
+ // previous card.
+ HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(
+ card_number == card_table_.begin().index
+ ? Payload()
+ : object_start_bit_map_.FindHeader(card_begin));
+ for (; header < reinterpret_cast<HeapObjectHeader*>(card_end);
+ reinterpret_cast<Address&>(header) += header->size()) {
+ if (!header->IsFree()) {
+ function(header);
+ }
+ }
+}
+
+inline void NormalPage::MarkCard(Address address) {
+#if DCHECK_IS_ON()
+ DCHECK(Contains(address));
+#endif
+ const size_t byte = reinterpret_cast<size_t>(address) & kBlinkPageOffsetMask;
+ const size_t card = byte / CardTable::kCardSize;
+ card_table_.Mark(card);
+}
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_PAGE_H_
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 6b8dc5c4cfd..41b2a28062d 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
@@ -14,11 +14,13 @@ namespace blink {
void ThreadHeapStatsCollector::IncreaseCompactionFreedSize(size_t bytes) {
DCHECK(is_started_);
current_.compaction_freed_bytes += bytes;
+ current_.compaction_recorded_events = true;
}
void ThreadHeapStatsCollector::IncreaseCompactionFreedPages(size_t pages) {
DCHECK(is_started_);
current_.compaction_freed_pages += pages;
+ current_.compaction_recorded_events = true;
}
void ThreadHeapStatsCollector::IncreaseAllocatedObjectSize(size_t bytes) {
@@ -100,11 +102,14 @@ void ThreadHeapStatsCollector::IncreaseCollectedWrapperCount(size_t count) {
collected_wrapper_count_ += count;
}
-void ThreadHeapStatsCollector::NotifyMarkingStarted(BlinkGC::GCReason reason) {
+void ThreadHeapStatsCollector::NotifyMarkingStarted(
+ BlinkGC::CollectionType collection_type,
+ BlinkGC::GCReason reason) {
DCHECK(!is_started_);
DCHECK(current_.marking_time().is_zero());
is_started_ = true;
current_.reason = reason;
+ current_.collection_type = collection_type;
}
void ThreadHeapStatsCollector::NotifyMarkingCompleted(size_t marked_bytes) {
@@ -170,6 +175,10 @@ 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];
+}
+
base::TimeDelta ThreadHeapStatsCollector::Event::incremental_marking_time()
const {
return scope_data[kIncrementalMarkingStartMarking] +
@@ -195,8 +204,8 @@ base::TimeDelta ThreadHeapStatsCollector::Event::foreground_marking_time()
base::TimeDelta ThreadHeapStatsCollector::Event::background_marking_time()
const {
- return base::TimeDelta::FromMicroseconds(
- base::subtle::NoBarrier_Load(&concurrent_scope_data[kConcurrentMark]));
+ return base::TimeDelta::FromMicroseconds(base::subtle::NoBarrier_Load(
+ &concurrent_scope_data[kConcurrentMarkingStep]));
}
base::TimeDelta ThreadHeapStatsCollector::Event::marking_time() const {
@@ -229,7 +238,7 @@ base::TimeDelta ThreadHeapStatsCollector::Event::foreground_sweeping_time()
base::TimeDelta ThreadHeapStatsCollector::Event::background_sweeping_time()
const {
return base::TimeDelta::FromMicroseconds(
- concurrent_scope_data[kConcurrentSweep]);
+ concurrent_scope_data[kConcurrentSweepingStep]);
}
base::TimeDelta ThreadHeapStatsCollector::Event::sweeping_time() const {
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 e5e7207f379..c7fa3f9b571 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
@@ -54,6 +54,7 @@ class PLATFORM_EXPORT ThreadHeapStatsObserver {
V(InvokePreFinalizers) \
V(LazySweepInIdle) \
V(LazySweepOnAllocation) \
+ V(MarkBailOutObjects) \
V(MarkInvokeEphemeronCallbacks) \
V(MarkProcessWorklist) \
V(MarkNotFullyConstructedObjects) \
@@ -63,17 +64,20 @@ class PLATFORM_EXPORT ThreadHeapStatsObserver {
V(VisitDOMWrappers) \
V(VisitPersistentRoots) \
V(VisitPersistents) \
- V(VisitStackRoots)
+ V(VisitRoots) \
+ V(VisitStackRoots) \
+ V(VisitRememberedSets)
#define FOR_ALL_CONCURRENT_SCOPES(V) \
- V(ConcurrentMark) \
- V(ConcurrentSweep)
+ V(ConcurrentMarkingStep) \
+ V(ConcurrentSweepingStep)
// Manages counters and statistics across garbage collection cycles.
//
// Usage:
// ThreadHeapStatsCollector stats_collector;
-// stats_collector.NotifyMarkingStarted(<BlinkGC::GCReason>);
+// stats_collector.NotifyMarkingStarted(<BlinkGC::CollectionType>,
+// <BlinkGC::GCReason>);
// // Use tracer.
// stats_collector.NotifySweepingCompleted();
// // Previous event is available using stats_collector.previous().
@@ -96,12 +100,13 @@ class PLATFORM_EXPORT ThreadHeapStatsCollector {
kNumConcurrentScopeIds
};
- constexpr static const char* ToString(Id id) {
+ constexpr static const char* ToString(Id id, BlinkGC::CollectionType type) {
switch (id) {
-#define CASE(name) \
- case k##name: \
- return "BlinkGC." #name;
-
+#define CASE(name) \
+ case k##name: \
+ return type == BlinkGC::CollectionType::kMajor ? "BlinkGC." #name \
+ : "BlinkGC." #name \
+ ".Minor";
FOR_ALL_SCOPES(CASE)
#undef CASE
default:
@@ -110,12 +115,14 @@ class PLATFORM_EXPORT ThreadHeapStatsCollector {
return nullptr;
}
- constexpr static const char* ToString(ConcurrentId id) {
+ constexpr static const char* ToString(ConcurrentId id,
+ BlinkGC::CollectionType type) {
switch (id) {
-#define CASE(name) \
- case k##name: \
- return "BlinkGC." #name;
-
+#define CASE(name) \
+ case k##name: \
+ return type == BlinkGC::CollectionType::kMajor ? "BlinkGC." #name \
+ : "BlinkGC." #name \
+ ".Minor";
FOR_ALL_CONCURRENT_SCOPES(CASE)
#undef CASE
default:
@@ -140,60 +147,31 @@ class PLATFORM_EXPORT ThreadHeapStatsCollector {
public:
template <typename... Args>
- inline InternalScope(ThreadHeapStatsCollector* tracer,
- IdType id,
- Args... args)
+ InternalScope(ThreadHeapStatsCollector* tracer, IdType id, Args... args)
: tracer_(tracer), start_time_(base::TimeTicks::Now()), id_(id) {
- StartTrace(id, args...);
+ StartTrace(args...);
}
- inline ~InternalScope() {
- StopTrace(id_);
+ ~InternalScope() {
+ StopTrace();
IncreaseScopeTime(id_);
}
private:
- constexpr static const char* TraceCategory() {
- switch (trace_category) {
- case kEnabled:
- return "blink_gc";
- case kDisabled:
- return TRACE_DISABLED_BY_DEFAULT("blink_gc");
- case kDevTools:
- return "blink_gc,devtools.timeline";
- }
- }
-
- void StartTrace(IdType id) {
- TRACE_EVENT_BEGIN0(TraceCategory(), ToString(id));
- }
+ inline constexpr static const char* TraceCategory();
+ inline void StartTrace();
template <typename Value1>
- void StartTrace(IdType id, const char* k1, Value1 v1) {
- TRACE_EVENT_BEGIN1(TraceCategory(), ToString(id), k1, v1);
- }
-
+ inline void StartTrace(const char* k1, Value1 v1);
template <typename Value1, typename Value2>
- void StartTrace(IdType id,
- const char* k1,
- Value1 v1,
- const char* k2,
- Value2 v2) {
- TRACE_EVENT_BEGIN2(TraceCategory(), ToString(id), k1, v1, k2, v2);
- }
+ inline void StartTrace(const char* k1,
+ Value1 v1,
+ const char* k2,
+ Value2 v2);
+ inline void StopTrace();
- void StopTrace(IdType id) {
- TRACE_EVENT_END0(TraceCategory(), ToString(id));
- }
-
- void IncreaseScopeTime(Id) {
- tracer_->IncreaseScopeTime(id_, base::TimeTicks::Now() - start_time_);
- }
-
- void IncreaseScopeTime(ConcurrentId) {
- tracer_->IncreaseConcurrentScopeTime(
- id_, base::TimeTicks::Now() - start_time_);
- }
+ inline void IncreaseScopeTime(Id);
+ inline void IncreaseScopeTime(ConcurrentId);
ThreadHeapStatsCollector* const tracer_;
const base::TimeTicks start_time_;
@@ -250,6 +228,9 @@ class PLATFORM_EXPORT ThreadHeapStatsCollector {
// Time spent in the final atomic pause in sweeping and compacting the heap.
base::TimeDelta atomic_sweep_and_compact_time() const;
+ // Time spent marking the roots.
+ base::TimeDelta roots_marking_time() const;
+
// Time spent incrementally marking the heap.
base::TimeDelta incremental_marking_time() const;
@@ -278,9 +259,11 @@ class PLATFORM_EXPORT ThreadHeapStatsCollector {
size_t marked_bytes = 0;
size_t compaction_freed_bytes = 0;
size_t compaction_freed_pages = 0;
+ bool compaction_recorded_events = false;
base::TimeDelta scope_data[kNumScopeIds];
base::subtle::Atomic32 concurrent_scope_data[kNumConcurrentScopeIds]{0};
BlinkGC::GCReason reason = static_cast<BlinkGC::GCReason>(0);
+ BlinkGC::CollectionType collection_type = BlinkGC::CollectionType::kMajor;
size_t object_size_in_bytes_before_sweeping = 0;
size_t allocated_space_in_bytes_before_sweeping = 0;
size_t partition_alloc_bytes_before_sweeping = 0;
@@ -290,7 +273,7 @@ class PLATFORM_EXPORT ThreadHeapStatsCollector {
};
// Indicates a new garbage collection cycle.
- void NotifyMarkingStarted(BlinkGC::GCReason);
+ void NotifyMarkingStarted(BlinkGC::CollectionType, BlinkGC::GCReason);
// Indicates that marking of the current garbage collection cycle is
// completed.
@@ -405,6 +388,71 @@ class PLATFORM_EXPORT ThreadHeapStatsCollector {
FRIEND_TEST_ALL_PREFIXES(ThreadHeapStatsCollectorTest, StopResetsCurrent);
};
+template <ThreadHeapStatsCollector::TraceCategory trace_category,
+ ThreadHeapStatsCollector::ScopeContext scope_category>
+constexpr const char*
+ThreadHeapStatsCollector::InternalScope<trace_category,
+ scope_category>::TraceCategory() {
+ switch (trace_category) {
+ case kEnabled:
+ return "blink_gc";
+ case kDisabled:
+ return TRACE_DISABLED_BY_DEFAULT("blink_gc");
+ case kDevTools:
+ return "blink_gc,devtools.timeline";
+ }
+}
+
+template <ThreadHeapStatsCollector::TraceCategory trace_category,
+ ThreadHeapStatsCollector::ScopeContext scope_category>
+void ThreadHeapStatsCollector::InternalScope<trace_category,
+ scope_category>::StartTrace() {
+ TRACE_EVENT_BEGIN0(TraceCategory(),
+ ToString(id_, tracer_->current_.collection_type));
+}
+
+template <ThreadHeapStatsCollector::TraceCategory trace_category,
+ ThreadHeapStatsCollector::ScopeContext scope_category>
+template <typename Value1>
+void ThreadHeapStatsCollector::InternalScope<trace_category, scope_category>::
+ StartTrace(const char* k1, Value1 v1) {
+ TRACE_EVENT_BEGIN1(TraceCategory(),
+ ToString(id_, tracer_->current_.collection_type), k1, v1);
+}
+
+template <ThreadHeapStatsCollector::TraceCategory trace_category,
+ ThreadHeapStatsCollector::ScopeContext scope_category>
+template <typename Value1, typename Value2>
+void ThreadHeapStatsCollector::InternalScope<trace_category, scope_category>::
+ StartTrace(const char* k1, Value1 v1, const char* k2, Value2 v2) {
+ TRACE_EVENT_BEGIN2(TraceCategory(),
+ ToString(id_, tracer_->current_.collection_type), k1, v1,
+ k2, v2);
+}
+
+template <ThreadHeapStatsCollector::TraceCategory trace_category,
+ ThreadHeapStatsCollector::ScopeContext scope_category>
+void ThreadHeapStatsCollector::InternalScope<trace_category,
+ scope_category>::StopTrace() {
+ TRACE_EVENT_END0(TraceCategory(),
+ ToString(id_, tracer_->current_.collection_type));
+}
+
+template <ThreadHeapStatsCollector::TraceCategory trace_category,
+ ThreadHeapStatsCollector::ScopeContext scope_category>
+void ThreadHeapStatsCollector::InternalScope<trace_category, scope_category>::
+ IncreaseScopeTime(Id) {
+ tracer_->IncreaseScopeTime(id_, base::TimeTicks::Now() - start_time_);
+}
+
+template <ThreadHeapStatsCollector::TraceCategory trace_category,
+ ThreadHeapStatsCollector::ScopeContext scope_category>
+void ThreadHeapStatsCollector::InternalScope<trace_category, scope_category>::
+ IncreaseScopeTime(ConcurrentId) {
+ tracer_->IncreaseConcurrentScopeTime(id_,
+ base::TimeTicks::Now() - start_time_);
+}
+
#undef FOR_ALL_SCOPES
#undef FOR_ALL_CONCURRENT_SCOPES
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
index 314f68f9520..493a5d1658b 100644
--- 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
@@ -21,7 +21,8 @@ constexpr size_t kNoMarkedBytes = 0;
TEST(ThreadHeapStatsCollectorTest, InitialEmpty) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ 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]);
}
@@ -31,7 +32,8 @@ TEST(ThreadHeapStatsCollectorTest, InitialEmpty) {
TEST(ThreadHeapStatsCollectorTest, IncreaseScopeTime) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::kIncrementalMarkingStep,
base::TimeDelta::FromMilliseconds(1));
@@ -44,7 +46,8 @@ TEST(ThreadHeapStatsCollectorTest, IncreaseScopeTime) {
TEST(ThreadHeapStatsCollectorTest, StopMovesCurrentToPrevious) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::kIncrementalMarkingStep,
base::TimeDelta::FromMilliseconds(1));
@@ -57,7 +60,8 @@ TEST(ThreadHeapStatsCollectorTest, StopMovesCurrentToPrevious) {
TEST(ThreadHeapStatsCollectorTest, StopResetsCurrent) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::kIncrementalMarkingStep,
base::TimeDelta::FromMilliseconds(1));
@@ -71,7 +75,8 @@ TEST(ThreadHeapStatsCollectorTest, StopResetsCurrent) {
TEST(ThreadHeapStatsCollectorTest, StartStop) {
ThreadHeapStatsCollector stats_collector;
EXPECT_FALSE(stats_collector.is_started());
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
EXPECT_TRUE(stats_collector.is_started());
stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
stats_collector.NotifySweepingCompleted();
@@ -81,12 +86,14 @@ TEST(ThreadHeapStatsCollectorTest, StartStop) {
TEST(ThreadHeapStatsCollectorTest, ScopeToString) {
EXPECT_STREQ("BlinkGC.IncrementalMarkingStartMarking",
ThreadHeapStatsCollector::ToString(
- ThreadHeapStatsCollector::kIncrementalMarkingStartMarking));
+ ThreadHeapStatsCollector::kIncrementalMarkingStartMarking,
+ BlinkGC::CollectionType::kMajor));
}
TEST(ThreadHeapStatsCollectorTest, UpdateReason) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
stats_collector.UpdateReason(BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.NotifySweepingCompleted();
@@ -96,7 +103,8 @@ TEST(ThreadHeapStatsCollectorTest, UpdateReason) {
TEST(ThreadHeapStatsCollectorTest, InitialEstimatedObjectSize) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ 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();
@@ -104,7 +112,8 @@ TEST(ThreadHeapStatsCollectorTest, InitialEstimatedObjectSize) {
TEST(ThreadHeapStatsCollectorTest, EstimatedObjectSizeNoMarkedBytes) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ 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);
@@ -113,10 +122,12 @@ TEST(ThreadHeapStatsCollectorTest, EstimatedObjectSizeNoMarkedBytes) {
TEST(ThreadHeapStatsCollectorTest, EstimatedObjectSizeWithMarkedBytes) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.NotifyMarkingCompleted(128);
stats_collector.NotifySweepingCompleted();
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ 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());
@@ -126,10 +137,12 @@ TEST(ThreadHeapStatsCollectorTest, EstimatedObjectSizeWithMarkedBytes) {
TEST(ThreadHeapStatsCollectorTest,
EstimatedObjectSizeDoNotCountCurrentlyMarkedBytes) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.NotifyMarkingCompleted(128);
stats_collector.NotifySweepingCompleted();
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ 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);
@@ -141,7 +154,8 @@ 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::GCReason::kForcedGCForTesting);
+ 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();
@@ -149,13 +163,15 @@ TEST(ThreadHeapStatsCollectorTest, PreInitializedEstimatedMarkingTime) {
TEST(ThreadHeapStatsCollectorTest, EstimatedMarkingTime1) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ 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::GCReason::kForcedGCForTesting);
+ 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();
@@ -163,13 +179,15 @@ TEST(ThreadHeapStatsCollectorTest, EstimatedMarkingTime1) {
TEST(ThreadHeapStatsCollectorTest, EstimatedMarkingTime2) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ 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::GCReason::kForcedGCForTesting);
+ 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);
@@ -178,7 +196,8 @@ TEST(ThreadHeapStatsCollectorTest, EstimatedMarkingTime2) {
TEST(ThreadHeapStatsCollectorTest, SubMilliSecondMarkingTime) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::kIncrementalMarkingStartMarking,
base::TimeDelta::FromMillisecondsD(.5));
@@ -191,7 +210,8 @@ TEST(ThreadHeapStatsCollectorTest, SubMilliSecondMarkingTime) {
TEST(ThreadHeapStatsCollectorTest, AllocatedSpaceInBytesInitialZero) {
ThreadHeapStatsCollector stats_collector;
EXPECT_EQ(0u, stats_collector.allocated_space_bytes());
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ 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());
@@ -218,7 +238,8 @@ TEST(ThreadHeapStatsCollectorTest, AllocatedSpaceInBytesDecrease) {
TEST(ThreadHeapStatsCollectorTest, EventPrevGCMarkedObjectSize) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.NotifyMarkingCompleted(1024);
stats_collector.NotifySweepingCompleted();
EXPECT_EQ(1024u, stats_collector.previous().marked_bytes);
@@ -227,7 +248,8 @@ TEST(ThreadHeapStatsCollectorTest, EventPrevGCMarkedObjectSize) {
TEST(ThreadHeapStatsCollectorTest,
EventMarkingTimeFromIncrementalStandAloneGC) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::kIncrementalMarkingStartMarking,
base::TimeDelta::FromMilliseconds(7));
@@ -245,7 +267,8 @@ TEST(ThreadHeapStatsCollectorTest,
TEST(ThreadHeapStatsCollectorTest, EventMarkingTimeFromIncrementalUnifiedGC) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::kIncrementalMarkingStartMarking,
base::TimeDelta::FromMilliseconds(7));
@@ -272,7 +295,8 @@ TEST(ThreadHeapStatsCollectorTest, EventMarkingTimeFromIncrementalUnifiedGC) {
TEST(ThreadHeapStatsCollectorTest, EventMarkingTime) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::kIncrementalMarkingStep,
base::TimeDelta::FromMilliseconds(2));
@@ -287,7 +311,8 @@ TEST(ThreadHeapStatsCollectorTest, EventMarkingTime) {
TEST(ThreadHeapStatsCollectorTest, EventAtomicMarkingTime) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::kAtomicPauseMarkPrologue,
base::TimeDelta::FromMilliseconds(5));
@@ -305,7 +330,8 @@ TEST(ThreadHeapStatsCollectorTest, EventAtomicMarkingTime) {
TEST(ThreadHeapStatsCollectorTest, EventAtomicPause) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure,
base::TimeDelta::FromMilliseconds(17));
@@ -320,7 +346,8 @@ TEST(ThreadHeapStatsCollectorTest, EventAtomicPause) {
TEST(ThreadHeapStatsCollectorTest, EventMarkingTimePerByteInS) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.IncreaseScopeTime(
ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure,
base::TimeDelta::FromSeconds(1));
@@ -332,7 +359,8 @@ TEST(ThreadHeapStatsCollectorTest, EventMarkingTimePerByteInS) {
TEST(ThreadHeapStatsCollectorTest, EventSweepingTime) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
stats_collector.IncreaseScopeTime(ThreadHeapStatsCollector::kLazySweepInIdle,
base::TimeDelta::FromMilliseconds(1));
@@ -352,7 +380,8 @@ TEST(ThreadHeapStatsCollectorTest, EventSweepingTime) {
TEST(ThreadHeapStatsCollectorTest, EventCompactionFreedBytes) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
stats_collector.IncreaseCompactionFreedSize(512);
stats_collector.NotifySweepingCompleted();
@@ -361,7 +390,8 @@ TEST(ThreadHeapStatsCollectorTest, EventCompactionFreedBytes) {
TEST(ThreadHeapStatsCollectorTest, EventCompactionFreedPages) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
stats_collector.IncreaseCompactionFreedPages(3);
stats_collector.NotifySweepingCompleted();
@@ -370,7 +400,8 @@ TEST(ThreadHeapStatsCollectorTest, EventCompactionFreedPages) {
TEST(ThreadHeapStatsCollectorTest, EventInitialEstimatedLiveObjectRate) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ 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);
@@ -379,10 +410,12 @@ TEST(ThreadHeapStatsCollectorTest, EventInitialEstimatedLiveObjectRate) {
TEST(ThreadHeapStatsCollectorTest,
EventEstimatedLiveObjectRateSameMarkedBytes) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.NotifyMarkingCompleted(128);
stats_collector.NotifySweepingCompleted();
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ 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);
@@ -391,10 +424,12 @@ TEST(ThreadHeapStatsCollectorTest,
TEST(ThreadHeapStatsCollectorTest,
EventEstimatedLiveObjectRateHalfMarkedBytes) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.NotifyMarkingCompleted(256);
stats_collector.NotifySweepingCompleted();
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ 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);
@@ -402,10 +437,12 @@ TEST(ThreadHeapStatsCollectorTest,
TEST(ThreadHeapStatsCollectorTest, EventEstimatedLiveObjectRateNoMarkedBytes) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.NotifyMarkingCompleted(256);
stats_collector.NotifySweepingCompleted();
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.NotifySweepingCompleted();
EXPECT_DOUBLE_EQ(0.0, stats_collector.previous().live_object_rate);
}
@@ -413,11 +450,13 @@ TEST(ThreadHeapStatsCollectorTest, EventEstimatedLiveObjectRateNoMarkedBytes) {
TEST(ThreadHeapStatsCollectorTest,
EventEstimatedLiveObjectRateWithAllocatedBytes1) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.NotifyMarkingCompleted(128);
stats_collector.NotifySweepingCompleted();
stats_collector.IncreaseAllocatedObjectSize(128);
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ 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);
@@ -426,11 +465,13 @@ TEST(ThreadHeapStatsCollectorTest,
TEST(ThreadHeapStatsCollectorTest,
EventEstimatedLiveObjectRateWithAllocatedBytes2) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
stats_collector.NotifySweepingCompleted();
stats_collector.IncreaseAllocatedObjectSize(128);
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ 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);
@@ -439,7 +480,8 @@ TEST(ThreadHeapStatsCollectorTest,
TEST(ThreadHeapStatsCollectorTest,
EventEstimatedLiveObjectRateWithAllocatedBytes3) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ 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);
@@ -448,10 +490,12 @@ TEST(ThreadHeapStatsCollectorTest,
TEST(ThreadHeapStatsCollectorTest,
EventEstimatedLiveObjectRateWithAllocatedBytes4) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.NotifyMarkingCompleted(128);
stats_collector.NotifySweepingCompleted();
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ 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);
@@ -459,7 +503,8 @@ TEST(ThreadHeapStatsCollectorTest,
TEST(ThreadHeapStatsCollectorTest, EventAllocatedSpaceBeforeSweeping1) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.IncreaseAllocatedSpace(1024);
stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
stats_collector.IncreaseAllocatedSpace(2048);
@@ -471,7 +516,8 @@ TEST(ThreadHeapStatsCollectorTest, EventAllocatedSpaceBeforeSweeping1) {
TEST(ThreadHeapStatsCollectorTest, EventAllocatedSpaceBeforeSweeping2) {
ThreadHeapStatsCollector stats_collector;
- stats_collector.NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector.IncreaseAllocatedSpace(1024);
stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
stats_collector.DecreaseAllocatedSpace(1024);
@@ -497,7 +543,8 @@ class MockThreadHeapStatsObserver : public ThreadHeapStatsObserver {
};
void FakeGC(ThreadHeapStatsCollector* stats_collector, size_t marked_bytes) {
- stats_collector->NotifyMarkingStarted(BlinkGC::GCReason::kForcedGCForTesting);
+ stats_collector->NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
+ BlinkGC::GCReason::kForcedGCForTesting);
stats_collector->NotifyMarkingCompleted(marked_bytes);
stats_collector->NotifySweepingCompleted();
}
diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_test.cc b/chromium/third_party/blink/renderer/platform/heap/heap_test.cc
index b9bf108f948..bc9a3c031e7 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_test.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_test.cc
@@ -45,9 +45,9 @@
#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_linked_stack.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"
@@ -76,7 +76,7 @@ class IntWrapper : public GarbageCollected<IntWrapper> {
}
static std::atomic_int destructor_calls_;
- void Trace(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
int Value() const { return x_; }
@@ -262,14 +262,17 @@ class TestGCScope : public TestGCCollectGarbageScope {
explicit TestGCScope(BlinkGC::StackState state)
: TestGCCollectGarbageScope(state) {
ThreadState::Current()->Heap().stats_collector()->NotifyMarkingStarted(
+ BlinkGC::CollectionType::kMajor,
BlinkGC::GCReason::kForcedGCForTesting);
ThreadState::Current()->AtomicPauseMarkPrologue(
- state, BlinkGC::kAtomicMarking, BlinkGC::GCReason::kPreciseGC);
+ BlinkGC::CollectionType::kMajor, state, BlinkGC::kAtomicMarking,
+ BlinkGC::GCReason::kPreciseGC);
}
~TestGCScope() {
ThreadState::Current()->AtomicPauseMarkEpilogue(BlinkGC::kAtomicMarking);
- ThreadState::Current()->AtomicPauseSweepAndCompact(BlinkGC::kAtomicMarking,
- BlinkGC::kEagerSweeping);
+ ThreadState::Current()->AtomicPauseSweepAndCompact(
+ BlinkGC::CollectionType::kMajor, BlinkGC::kAtomicMarking,
+ BlinkGC::kEagerSweeping);
ThreadState::Current()->AtomicPauseEpilogue();
}
};
@@ -277,7 +280,7 @@ class TestGCScope : public TestGCCollectGarbageScope {
class SimpleObject : public GarbageCollected<SimpleObject> {
public:
SimpleObject() = default;
- void Trace(blink::Visitor* visitor) {}
+ 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
@@ -297,7 +300,7 @@ class HeapTestSuperClass : public GarbageCollected<HeapTestSuperClass> {
virtual ~HeapTestSuperClass() { ++destructor_calls_; }
static int destructor_calls_;
- void Trace(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
};
int HeapTestSuperClass::destructor_calls_ = 0;
@@ -335,7 +338,7 @@ class HeapAllocatedArray : public GarbageCollected<HeapAllocatedArray> {
}
int8_t at(size_t i) { return array_[i]; }
- void Trace(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
private:
static const int kArraySize = 1000;
@@ -533,7 +536,7 @@ class ThreadPersistentHeapTester : public ThreadedTesterBase {
public:
Local() = default;
- void Trace(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
};
class PersistentChain;
@@ -561,7 +564,7 @@ class ThreadPersistentHeapTester : public ThreadedTesterBase {
ref_counted_chain_ = base::AdoptRef(RefCountedChain::Create(count));
}
- void Trace(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
private:
scoped_refptr<RefCountedChain> ref_counted_chain_;
@@ -590,7 +593,7 @@ class TraceCounter final : public GarbageCollected<TraceCounter> {
public:
TraceCounter() : trace_count_(0) {}
- void Trace(blink::Visitor* visitor) { trace_count_++; }
+ void Trace(Visitor* visitor) { trace_count_++; }
int TraceCount() const { return trace_count_; }
private:
@@ -601,7 +604,7 @@ TEST_F(HeapTest, IsHeapObjectAliveForConstPointer) {
// See http://crbug.com/661363.
auto* object = MakeGarbageCollected<SimpleObject>();
HeapObjectHeader* header = HeapObjectHeader::FromPayload(object);
- header->Mark();
+ EXPECT_TRUE(header->TryMark());
EXPECT_TRUE(ThreadHeap::IsHeapObjectAlive(object));
const SimpleObject* const_object = const_cast<const SimpleObject*>(object);
EXPECT_TRUE(ThreadHeap::IsHeapObjectAlive(const_object));
@@ -611,9 +614,7 @@ class ClassWithMember : public GarbageCollected<ClassWithMember> {
public:
ClassWithMember() : trace_counter_(MakeGarbageCollected<TraceCounter>()) {}
- void Trace(blink::Visitor* visitor) {
- visitor->Trace(trace_counter_);
- }
+ void Trace(Visitor* visitor) { visitor->Trace(trace_counter_); }
int TraceCount() const { return trace_counter_->TraceCount(); }
private:
@@ -628,7 +629,7 @@ class SimpleFinalizedObject final
static int destructor_calls_;
- void Trace(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
};
int SimpleFinalizedObject::destructor_calls_ = 0;
@@ -654,7 +655,7 @@ class IntNode : public GarbageCollected<IntNode> {
static IntNode* Create(int i) { return new IntNode(i); }
- void Trace(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
int Value() { return value_; }
@@ -674,7 +675,7 @@ class Bar : public GarbageCollected<Bar> {
}
bool HasBeenFinalized() const { return !magic_; }
- virtual void Trace(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
static unsigned live_;
protected:
@@ -688,7 +689,7 @@ class Baz : public GarbageCollected<Baz> {
public:
explicit Baz(Bar* bar) : bar_(bar) {}
- void Trace(blink::Visitor* visitor) { visitor->Trace(bar_); }
+ void Trace(Visitor* visitor) { visitor->Trace(bar_); }
void Clear() { bar_.Release(); }
@@ -705,16 +706,16 @@ class Foo : public Bar {
Foo(Foo* foo) : Bar(), bar_(foo), points_to_foo_(true) {}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
if (points_to_foo_)
- visitor->Trace(static_cast<Foo*>(bar_));
+ visitor->Trace(static_cast<const Foo*>(bar_));
else
visitor->Trace(bar_);
}
private:
- Bar* bar_;
- bool points_to_foo_;
+ const Bar* bar_;
+ const bool points_to_foo_;
};
class Bars : public Bar {
@@ -726,7 +727,7 @@ class Bars : public Bar {
}
}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
for (unsigned i = 0; i < width_; i++)
visitor->Trace(bars_[i]);
}
@@ -746,7 +747,7 @@ class ConstructorAllocation : public GarbageCollected<ConstructorAllocation> {
int_wrapper_ = MakeGarbageCollected<IntWrapper>(42);
}
- void Trace(blink::Visitor* visitor) { visitor->Trace(int_wrapper_); }
+ void Trace(Visitor* visitor) { visitor->Trace(int_wrapper_); }
private:
Member<IntWrapper> int_wrapper_;
@@ -760,7 +761,7 @@ class LargeHeapObject final : public GarbageCollected<LargeHeapObject> {
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(blink::Visitor* visitor) { visitor->Trace(int_wrapper_); }
+ void Trace(Visitor* visitor) { visitor->Trace(int_wrapper_); }
static int destructor_calls_;
private:
@@ -805,7 +806,7 @@ class RefCountedAndGarbageCollected final
keep_alive_.Clear();
}
- void Trace(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
static int destructor_calls_;
@@ -840,7 +841,7 @@ class RefCountedAndGarbageCollected2 final
keep_alive_.Clear();
}
- void Trace(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
static int destructor_calls_;
@@ -856,7 +857,7 @@ class Weak : public Bar {
Weak(Bar* strong_bar, Bar* weak_bar)
: Bar(), strong_bar_(strong_bar), weak_bar_(weak_bar) {}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(strong_bar_);
visitor->template RegisterWeakCallbackMethod<Weak, &Weak::ZapWeakMembers>(
this);
@@ -880,7 +881,7 @@ class WithWeakMember : public Bar {
WithWeakMember(Bar* strong_bar, Bar* weak_bar)
: Bar(), strong_bar_(strong_bar), weak_bar_(weak_bar) {}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(strong_bar_);
visitor->Trace(weak_bar_);
}
@@ -899,7 +900,7 @@ class Observable final : public GarbageCollected<Observable> {
public:
explicit Observable(Bar* bar) : bar_(bar), was_destructed_(false) {}
~Observable() { was_destructed_ = true; }
- void Trace(blink::Visitor* visitor) { visitor->Trace(bar_); }
+ void Trace(Visitor* visitor) { visitor->Trace(bar_); }
// willFinalize is called by FinalizationObserver. willFinalize can touch
// other on-heap objects.
@@ -924,7 +925,7 @@ class ObservableWithPreFinalizer final
public:
ObservableWithPreFinalizer() : was_destructed_(false) {}
~ObservableWithPreFinalizer() { was_destructed_ = true; }
- void Trace(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
void Dispose() {
EXPECT_FALSE(was_destructed_);
dispose_was_called_ = true;
@@ -947,7 +948,7 @@ class PreFinalizerBase : public GarbageCollected<PreFinalizerBase> {
public:
PreFinalizerBase() : was_destructed_(false) {}
virtual ~PreFinalizerBase() { was_destructed_ = true; }
- virtual void Trace(blink::Visitor* visitor) {}
+ 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);
@@ -965,7 +966,7 @@ class PreFinalizerMixin : public GarbageCollectedMixin {
public:
~PreFinalizerMixin() { was_destructed_ = true; }
- void Trace(blink::Visitor* visitor) override {}
+ 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);
@@ -986,7 +987,7 @@ class PreFinalizerSubClass : public PreFinalizerBase, public PreFinalizerMixin {
public:
PreFinalizerSubClass() : was_destructed_(false) {}
~PreFinalizerSubClass() override { was_destructed_ = true; }
- void Trace(blink::Visitor* visitor) override {}
+ 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);
@@ -1006,7 +1007,7 @@ class FinalizationObserver : public GarbageCollected<FinalizationObserver<T>> {
bool DidCallWillFinalize() const { return did_call_will_finalize_; }
- void Trace(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
visitor->template RegisterWeakCallbackMethod<
FinalizationObserver<T>, &FinalizationObserver<T>::ZapWeakMembers>(
this);
@@ -1087,7 +1088,7 @@ class PointsBack final : public GarbageCollected<PointsBack> {
SuperClass* BackPointer() const { return back_pointer_; }
- void Trace(blink::Visitor* visitor) { visitor->Trace(back_pointer_); }
+ void Trace(Visitor* visitor) { visitor->Trace(back_pointer_); }
static int alive_count_;
@@ -1113,7 +1114,7 @@ class SuperClass : public GarbageCollected<SuperClass> {
EXPECT_EQ(super_class_count, SuperClass::alive_count_);
}
- virtual void Trace(blink::Visitor* visitor) { visitor->Trace(points_back_); }
+ virtual void Trace(Visitor* visitor) { visitor->Trace(points_back_); }
PointsBack* GetPointsBack() const { return points_back_.Get(); }
@@ -1129,7 +1130,7 @@ class SubData final : public GarbageCollected<SubData> {
SubData() { ++alive_count_; }
~SubData() { --alive_count_; }
- void Trace(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
static int alive_count_;
};
@@ -1144,7 +1145,7 @@ class SubClass : public SuperClass {
}
~SubClass() override { --alive_count_; }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(data_);
SuperClass::Trace(visitor);
}
@@ -1159,7 +1160,7 @@ int SubClass::alive_count_ = 0;
class Mixin : public GarbageCollectedMixin {
public:
- void Trace(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) override {}
virtual char GetPayload(int i) { return padding_[i]; }
@@ -1179,7 +1180,7 @@ class UseMixin : public SimpleObject, public Mixin {
}
static int trace_count_;
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
SimpleObject::Trace(visitor);
Mixin::Trace(visitor);
++trace_count_;
@@ -1194,7 +1195,7 @@ class VectorObject {
public:
VectorObject() { value_ = MakeGarbageCollected<SimpleFinalizedObject>(); }
- void Trace(blink::Visitor* visitor) { visitor->Trace(value_); }
+ void Trace(Visitor* visitor) { visitor->Trace(value_); }
private:
Member<SimpleFinalizedObject> value_;
@@ -1221,7 +1222,7 @@ class TerminatedArrayItem {
TerminatedArrayItem(IntWrapper* payload)
: payload_(payload), is_last_(false) {}
- void Trace(blink::Visitor* visitor) { visitor->Trace(payload_); }
+ void Trace(Visitor* visitor) { visitor->Trace(payload_); }
bool IsLastInArray() const { return is_last_; }
void SetLastInArray(bool value) { is_last_ = value; }
@@ -1247,7 +1248,7 @@ class OneKiloByteObject final : public GarbageCollected<OneKiloByteObject> {
public:
~OneKiloByteObject() { destructor_calls_++; }
char* Data() { return data_; }
- void Trace(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
static int destructor_calls_;
private:
@@ -1268,7 +1269,7 @@ class DynamicallySizedObject : public GarbageCollected<DynamicallySizedObject> {
uint8_t Get(int i) { return *(reinterpret_cast<uint8_t*>(this) + i); }
- void Trace(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
private:
DynamicallySizedObject() = default;
@@ -1288,7 +1289,7 @@ class FinalizationAllocator final
MakeGarbageCollected<LargeHeapObject>();
}
- void Trace(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
private:
Persistent<IntWrapper>* wrapper_;
@@ -1333,7 +1334,7 @@ class PreFinalizerBackingShrinkForbidden final
EXPECT_EQ(0ul, map_.Capacity());
}
- void Trace(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
visitor->Trace(vector_);
visitor->Trace(map_);
}
@@ -1369,7 +1370,7 @@ class PreFinalizerVectorBackingExpandForbidden final
}
}
- void Trace(blink::Visitor* visitor) { visitor->Trace(vector_); }
+ void Trace(Visitor* visitor) { visitor->Trace(vector_); }
private:
HeapVector<Member<IntWrapper>> vector_;
@@ -1398,7 +1399,7 @@ class PreFinalizerHashTableBackingExpandForbidden final
}
}
- void Trace(blink::Visitor* visitor) { visitor->Trace(map_); }
+ void Trace(Visitor* visitor) { visitor->Trace(map_); }
private:
HeapHashMap<int, Member<IntWrapper>> map_;
@@ -1422,7 +1423,7 @@ class PreFinalizerAllocationForbidden
#endif // DCHECK_IS_ON()
}
- void Trace(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
};
TEST(HeapDeathTest, PreFinalizerAllocationForbidden) {
@@ -1827,8 +1828,8 @@ TEST_F(HeapTest, LazySweepingPages) {
for (int i = 0; i < 1000; i++)
MakeGarbageCollected<SimpleFinalizedObject>();
ThreadState::Current()->CollectGarbage(
- BlinkGC::kNoHeapPointersOnStack, BlinkGC::kAtomicMarking,
- BlinkGC::kConcurrentAndLazySweeping,
+ 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++)
@@ -1861,8 +1862,8 @@ TEST_F(HeapTest, LazySweepingLargeObjectPages) {
for (int i = 0; i < 10; i++)
MakeGarbageCollected<LargeHeapObject>();
ThreadState::Current()->CollectGarbage(
- BlinkGC::kNoHeapPointersOnStack, BlinkGC::kAtomicMarking,
- BlinkGC::kConcurrentAndLazySweeping,
+ 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++) {
@@ -1873,8 +1874,8 @@ TEST_F(HeapTest, LazySweepingLargeObjectPages) {
MakeGarbageCollected<LargeHeapObject>();
EXPECT_EQ(10, LargeHeapObject::destructor_calls_);
ThreadState::Current()->CollectGarbage(
- BlinkGC::kNoHeapPointersOnStack, BlinkGC::kAtomicMarking,
- BlinkGC::kConcurrentAndLazySweeping,
+ BlinkGC::CollectionType::kMajor, BlinkGC::kNoHeapPointersOnStack,
+ BlinkGC::kAtomicMarking, BlinkGC::kConcurrentAndLazySweeping,
BlinkGC::GCReason::kForcedGCForTesting);
EXPECT_EQ(10, LargeHeapObject::destructor_calls_);
PreciselyCollectGarbage();
@@ -2242,10 +2243,8 @@ class Container final : public GarbageCollected<Container> {
HeapVector<Member<IntWrapper>, 2> vector;
HeapVector<PairWrappedUnwrapped, 2> vector_wu;
HeapVector<PairUnwrappedWrapped, 2> vector_uw;
- HeapDeque<Member<IntWrapper>, 0> deque;
- HeapDeque<PairWrappedUnwrapped, 0> deque_wu;
- HeapDeque<PairUnwrappedWrapped, 0> deque_uw;
- void Trace(blink::Visitor* visitor) {
+ HeapDeque<Member<IntWrapper>> deque;
+ void Trace(Visitor* visitor) {
visitor->Trace(map);
visitor->Trace(set);
visitor->Trace(set2);
@@ -2254,14 +2253,12 @@ class Container final : public GarbageCollected<Container> {
visitor->Trace(vector_wu);
visitor->Trace(vector_uw);
visitor->Trace(deque);
- visitor->Trace(deque_wu);
- visitor->Trace(deque_uw);
}
};
struct NeedsTracingTrait {
explicit NeedsTracingTrait(IntWrapper* wrapper) : wrapper_(wrapper) {}
- void Trace(blink::Visitor* visitor) { visitor->Trace(wrapper_); }
+ void Trace(Visitor* visitor) { visitor->Trace(wrapper_); }
Member<IntWrapper> wrapper_;
};
@@ -2406,9 +2403,9 @@ TEST_F(HeapTest, HeapVectorOnStackLargeObjectPageSized) {
ConservativelyCollectGarbage();
}
-template <typename T, wtf_size_t inlineCapacity, typename U>
-bool DequeContains(HeapDeque<T, inlineCapacity>& deque, U u) {
- typedef typename HeapDeque<T, inlineCapacity>::iterator iterator;
+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;
@@ -2427,12 +2424,10 @@ TEST_F(HeapTest, HeapCollectionTypes) {
typedef HeapHashCountedSet<Member<IntWrapper>> MemberCountedSet;
typedef HeapVector<Member<IntWrapper>, 2> MemberVector;
- typedef HeapDeque<Member<IntWrapper>, 0> MemberDeque;
+ typedef HeapDeque<Member<IntWrapper>> MemberDeque;
typedef HeapVector<PairWrappedUnwrapped, 2> VectorWU;
typedef HeapVector<PairUnwrappedWrapped, 2> VectorUW;
- typedef HeapDeque<PairWrappedUnwrapped, 0> DequeWU;
- typedef HeapDeque<PairUnwrappedWrapped, 0> DequeUW;
Persistent<MemberMember> member_member = MakeGarbageCollected<MemberMember>();
Persistent<MemberMember> member_member2 =
@@ -2454,10 +2449,6 @@ TEST_F(HeapTest, HeapCollectionTypes) {
Persistent<VectorUW> vector_uw2 = MakeGarbageCollected<VectorUW>();
Persistent<MemberDeque> deque = MakeGarbageCollected<MemberDeque>();
Persistent<MemberDeque> deque2 = MakeGarbageCollected<MemberDeque>();
- Persistent<DequeWU> deque_wu = MakeGarbageCollected<DequeWU>();
- Persistent<DequeWU> deque_wu2 = MakeGarbageCollected<DequeWU>();
- Persistent<DequeUW> deque_uw = MakeGarbageCollected<DequeUW>();
- Persistent<DequeUW> deque_uw2 = MakeGarbageCollected<DequeUW>();
Persistent<Container> container = MakeGarbageCollected<Container>();
ClearOutOldGarbage();
@@ -2475,18 +2466,14 @@ TEST_F(HeapTest, HeapCollectionTypes) {
auto* three_c(MakeGarbageCollected<IntWrapper>(3));
auto* three_d(MakeGarbageCollected<IntWrapper>(3));
auto* three_e(MakeGarbageCollected<IntWrapper>(3));
- auto* three_f(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_f(MakeGarbageCollected<IntWrapper>(4));
auto* four(MakeGarbageCollected<IntWrapper>(4));
auto* five_c(MakeGarbageCollected<IntWrapper>(5));
auto* five_d(MakeGarbageCollected<IntWrapper>(5));
- auto* five_e(MakeGarbageCollected<IntWrapper>(5));
- auto* five_f(MakeGarbageCollected<IntWrapper>(5));
// Member Collections.
member_member2->insert(one, two);
@@ -2515,21 +2502,13 @@ TEST_F(HeapTest, HeapCollectionTypes) {
deque2->push_back(three_e);
deque2->push_back(four_e);
vector_wu->push_back(PairWrappedUnwrapped(&*one_c, 42));
- deque_wu->push_back(PairWrappedUnwrapped(&*one_e, 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));
- deque_wu2->push_back(PairWrappedUnwrapped(&*three_e, 43));
- deque_wu2->push_back(PairWrappedUnwrapped(&*four_e, 44));
- deque_wu2->push_back(PairWrappedUnwrapped(&*five_e, 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));
- deque_uw->push_back(PairUnwrappedWrapped(1, &*one_f));
- deque_uw2->push_back(PairUnwrappedWrapped(103, &*three_f));
- deque_uw2->push_back(PairUnwrappedWrapped(104, &*four_f));
- deque_uw2->push_back(PairUnwrappedWrapped(105, &*five_f));
EXPECT_TRUE(DequeContains(*deque, one_b));
@@ -2554,10 +2533,6 @@ TEST_F(HeapTest, HeapCollectionTypes) {
EXPECT_EQ(3u, vector_uw2->size());
EXPECT_EQ(1u, deque->size());
EXPECT_EQ(2u, deque2->size());
- EXPECT_EQ(1u, deque_wu->size());
- EXPECT_EQ(3u, deque_wu2->size());
- EXPECT_EQ(1u, deque_uw->size());
- EXPECT_EQ(3u, deque_uw2->size());
MemberVector& cvec = container->vector;
cvec.swap(*vector.Get());
@@ -2579,16 +2554,6 @@ TEST_F(HeapTest, HeapCollectionTypes) {
deque2->Swap(c_deque);
deque->Swap(c_deque);
- DequeWU& c_deque_wu = container->deque_wu;
- c_deque_wu.Swap(*deque_wu.Get());
- deque_wu2->Swap(c_deque_wu);
- deque_wu->Swap(c_deque_wu);
-
- DequeUW& c_deque_uw = container->deque_uw;
- c_deque_uw.Swap(*deque_uw.Get());
- deque_uw2->Swap(c_deque_uw);
- deque_uw->Swap(c_deque_uw);
-
// Swap set and set2 in a roundabout way.
MemberSet& cset1 = container->set;
MemberSet& cset2 = container->set2;
@@ -2645,22 +2610,6 @@ TEST_F(HeapTest, HeapCollectionTypes) {
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)));
- EXPECT_TRUE(
- DequeContains(*deque_wu, PairWrappedUnwrapped(&*three_e, 43)));
- EXPECT_TRUE(DequeContains(*deque_wu, PairWrappedUnwrapped(&*four_e, 44)));
- EXPECT_TRUE(DequeContains(*deque_wu, PairWrappedUnwrapped(&*five_e, 45)));
- EXPECT_TRUE(DequeContains(*deque_wu2, PairWrappedUnwrapped(&*one_e, 42)));
- EXPECT_FALSE(
- DequeContains(*deque_wu2, PairWrappedUnwrapped(&*three_e, 43)));
- EXPECT_TRUE(
- DequeContains(*deque_uw, PairUnwrappedWrapped(103, &*three_f)));
- EXPECT_TRUE(
- DequeContains(*deque_uw, PairUnwrappedWrapped(104, &*four_f)));
- EXPECT_TRUE(
- DequeContains(*deque_uw, PairUnwrappedWrapped(105, &*five_f)));
- EXPECT_TRUE(DequeContains(*deque_uw2, PairUnwrappedWrapped(1, &*one_f)));
- EXPECT_FALSE(
- DequeContains(*deque_uw2, PairUnwrappedWrapped(103, &*three_f)));
}
PreciselyCollectGarbage();
@@ -2678,7 +2627,6 @@ TEST_F(HeapTest, HeapCollectionTypes) {
EXPECT_EQ(1u, vector2->size());
EXPECT_EQ(2u, deque->size());
EXPECT_EQ(1u, deque2->size());
- EXPECT_EQ(3u, deque_uw->size());
EXPECT_EQ(1u, deque2->size());
EXPECT_TRUE(member_member->at(one) == two);
@@ -2713,10 +2661,6 @@ TEST_F(HeapTest, HeapCollectionTypes) {
EXPECT_EQ(1u, vector_uw2->size());
EXPECT_EQ(2u, deque->size());
EXPECT_EQ(1u, deque2->size());
- EXPECT_EQ(3u, deque_wu->size());
- EXPECT_EQ(1u, deque_wu2->size());
- EXPECT_EQ(3u, deque_uw->size());
- EXPECT_EQ(1u, deque_uw2->size());
}
TEST_F(HeapTest, PersistentVector) {
@@ -2962,7 +2906,7 @@ class NonTrivialObject final {
deque_.push_back(MakeGarbageCollected<IntWrapper>(num));
vector_.push_back(MakeGarbageCollected<IntWrapper>(num));
}
- void Trace(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
visitor->Trace(deque_);
visitor->Trace(vector_);
}
@@ -3184,6 +3128,9 @@ TEST_F(HeapTest, HeapWeakLinkedHashSet) {
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 {
@@ -3311,6 +3258,7 @@ 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;
@@ -3383,70 +3331,6 @@ void CheckPairSets(Persistent<WSSet>& weak_strong,
EXPECT_TRUE(unwrapped_weak->Contains(PairUnwrappedWeak(2, &*two)));
}
-template <typename WSSet, typename SWSet, typename WUSet, typename UWSet>
-void WeakPairsHelper() {
- IntWrapper::destructor_calls_ = 0;
-
- Persistent<HeapVector<Member<IntWrapper>>> keep_numbers_alive =
- MakeGarbageCollected<HeapVector<Member<IntWrapper>>>();
-
- Persistent<WSSet> weak_strong = MakeGarbageCollected<WSSet>();
- Persistent<SWSet> strong_weak = MakeGarbageCollected<SWSet>();
- Persistent<WUSet> weak_unwrapped = MakeGarbageCollected<WUSet>();
- Persistent<UWSet> unwrapped_weak = MakeGarbageCollected<UWSet>();
-
- Persistent<IntWrapper> two = MakeGarbageCollected<IntWrapper>(2);
-
- weak_strong->insert(
- PairWeakStrong(MakeGarbageCollected<IntWrapper>(1), &*two));
- weak_strong->insert(PairWeakStrong(&*two, &*two));
- strong_weak->insert(
- PairStrongWeak(&*two, MakeGarbageCollected<IntWrapper>(1)));
- strong_weak->insert(PairStrongWeak(&*two, &*two));
- weak_unwrapped->insert(
- PairWeakUnwrapped(MakeGarbageCollected<IntWrapper>(1), 2));
- weak_unwrapped->insert(PairWeakUnwrapped(&*two, 2));
- unwrapped_weak->insert(
- PairUnwrappedWeak(2, MakeGarbageCollected<IntWrapper>(1)));
- unwrapped_weak->insert(PairUnwrappedWeak(2, &*two));
-
- CheckPairSets<WSSet, SWSet, WUSet, UWSet>(
- weak_strong, strong_weak, weak_unwrapped, unwrapped_weak, true, two);
-
- TestSupportingGC::PreciselyCollectGarbage();
- CheckPairSets<WSSet, SWSet, WUSet, UWSet>(
- weak_strong, strong_weak, weak_unwrapped, unwrapped_weak, false, two);
-}
-
-TEST_F(HeapTest, HeapWeakPairs) {
- {
- typedef HeapHashSet<PairWeakStrong> WeakStrongSet;
- typedef HeapHashSet<PairWeakUnwrapped> WeakUnwrappedSet;
- typedef HeapHashSet<PairStrongWeak> StrongWeakSet;
- typedef HeapHashSet<PairUnwrappedWeak> UnwrappedWeakSet;
- WeakPairsHelper<WeakStrongSet, StrongWeakSet, WeakUnwrappedSet,
- UnwrappedWeakSet>();
- }
-
- {
- typedef HeapListHashSet<PairWeakStrong> WeakStrongSet;
- typedef HeapListHashSet<PairWeakUnwrapped> WeakUnwrappedSet;
- typedef HeapListHashSet<PairStrongWeak> StrongWeakSet;
- typedef HeapListHashSet<PairUnwrappedWeak> UnwrappedWeakSet;
- WeakPairsHelper<WeakStrongSet, StrongWeakSet, WeakUnwrappedSet,
- UnwrappedWeakSet>();
- }
-
- {
- typedef HeapLinkedHashSet<PairWeakStrong> WeakStrongSet;
- typedef HeapLinkedHashSet<PairWeakUnwrapped> WeakUnwrappedSet;
- typedef HeapLinkedHashSet<PairStrongWeak> StrongWeakSet;
- typedef HeapLinkedHashSet<PairUnwrappedWeak> UnwrappedWeakSet;
- WeakPairsHelper<WeakStrongSet, StrongWeakSet, WeakUnwrappedSet,
- UnwrappedWeakSet>();
- }
-}
-
TEST_F(HeapTest, HeapWeakCollectionTypes) {
IntWrapper::destructor_calls_ = 0;
@@ -3455,6 +3339,7 @@ TEST_F(HeapTest, HeapWeakCollectionTypes) {
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();
@@ -4026,28 +3911,19 @@ TEST_F(HeapTest, CollectionNesting3) {
ClearOutOldGarbage();
IntWrapper::destructor_calls_ = 0;
typedef HeapVector<Member<IntWrapper>> IntVector;
- typedef HeapDeque<Member<IntWrapper>> IntDeque;
HeapVector<IntVector>* vector = MakeGarbageCollected<HeapVector<IntVector>>();
- HeapDeque<IntDeque>* deque = MakeGarbageCollected<HeapDeque<IntDeque>>();
vector->push_back(IntVector());
- deque->push_back(IntDeque());
HeapVector<IntVector>::iterator it = vector->begin();
- HeapDeque<IntDeque>::iterator it2 = deque->begin();
EXPECT_EQ(0u, it->size());
- EXPECT_EQ(0u, it2->size());
it->push_back(MakeGarbageCollected<IntWrapper>(42));
- it2->push_back(MakeGarbageCollected<IntWrapper>(42));
EXPECT_EQ(1u, it->size());
- EXPECT_EQ(1u, it2->size());
Persistent<HeapVector<IntVector>> keep_alive(vector);
- Persistent<HeapDeque<IntDeque>> keep_alive2(deque);
PreciselyCollectGarbage();
EXPECT_EQ(1u, it->size());
- EXPECT_EQ(1u, it2->size());
EXPECT_EQ(0, IntWrapper::destructor_calls_);
}
@@ -4080,42 +3956,13 @@ TEST_F(HeapTest, EmbeddedInVector) {
EXPECT_EQ(6, SimpleFinalizedObject::destructor_calls_);
}
-TEST_F(HeapTest, EmbeddedInDeque) {
- ClearOutOldGarbage();
- SimpleFinalizedObject::destructor_calls_ = 0;
- {
- Persistent<HeapDeque<VectorObject, 2>> inline_deque =
- MakeGarbageCollected<HeapDeque<VectorObject, 2>>();
- Persistent<HeapDeque<VectorObject>> outline_deque =
- MakeGarbageCollected<HeapDeque<VectorObject>>();
- VectorObject i1, i2;
- inline_deque->push_back(i1);
- inline_deque->push_back(i2);
-
- VectorObject o1, o2;
- outline_deque->push_back(o1);
- outline_deque->push_back(o2);
-
- Persistent<HeapDeque<VectorObjectInheritedTrace>> deque_inherited_trace =
- MakeGarbageCollected<HeapDeque<VectorObjectInheritedTrace>>();
- VectorObjectInheritedTrace it1, it2;
- deque_inherited_trace->push_back(it1);
- deque_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(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
static int destructor_calls_;
};
@@ -4129,7 +3976,7 @@ class InlinedVectorObjectWithVtable {
InlinedVectorObjectWithVtable() = default;
virtual ~InlinedVectorObjectWithVtable() { destructor_calls_++; }
virtual void VirtualMethod() {}
- void Trace(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
static int destructor_calls_;
};
@@ -4155,7 +4002,7 @@ class InlinedVectorObjectWrapper final
vector3_.push_back(i2);
}
- void Trace(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
visitor->Trace(vector1_);
visitor->Trace(vector2_);
visitor->Trace(vector3_);
@@ -4180,7 +4027,7 @@ class InlinedVectorObjectWithVtableWrapper final
vector3_.push_back(i2);
}
- void Trace(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
visitor->Trace(vector1_);
visitor->Trace(vector2_);
visitor->Trace(vector3_);
@@ -4298,34 +4145,6 @@ void RawPtrInHashHelper() {
}
}
-TEST_F(HeapTest, HeapLinkedStack) {
- ClearOutOldGarbage();
- IntWrapper::destructor_calls_ = 0;
-
- HeapLinkedStack<TerminatedArrayItem>* stack =
- MakeGarbageCollected<HeapLinkedStack<TerminatedArrayItem>>();
-
- const wtf_size_t kStackSize = 10;
-
- for (wtf_size_t i = 0; i < kStackSize; i++)
- stack->Push(TerminatedArrayItem(MakeGarbageCollected<IntWrapper>(i)));
-
- ConservativelyCollectGarbage();
- EXPECT_EQ(0, IntWrapper::destructor_calls_);
- EXPECT_EQ(kStackSize, stack->size());
- while (!stack->IsEmpty()) {
- EXPECT_EQ(stack->size() - 1,
- static_cast<size_t>(stack->Peek().Payload()->Value()));
- stack->Pop();
- }
-
- Persistent<HeapLinkedStack<TerminatedArrayItem>> p_stack = stack;
-
- PreciselyCollectGarbage();
- EXPECT_EQ(kStackSize, static_cast<size_t>(IntWrapper::destructor_calls_));
- EXPECT_EQ(0u, p_stack->size());
-}
-
TEST_F(HeapTest, AllocationDuringFinalization) {
ClearOutOldGarbage();
IntWrapper::destructor_calls_ = 0;
@@ -4430,7 +4249,7 @@ TEST_F(HeapTest, DestructorsCalled) {
class MixinA : public GarbageCollectedMixin {
public:
MixinA() : obj_(MakeGarbageCollected<IntWrapper>(100)) {}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
trace_count_++;
visitor->Trace(obj_);
}
@@ -4445,7 +4264,7 @@ int MixinA::trace_count_ = 0;
class MixinB : public GarbageCollectedMixin {
public:
MixinB() : obj_(MakeGarbageCollected<IntWrapper>(101)) {}
- void Trace(blink::Visitor* visitor) override { visitor->Trace(obj_); }
+ void Trace(Visitor* visitor) override { visitor->Trace(obj_); }
Member<IntWrapper> obj_;
};
@@ -4456,7 +4275,7 @@ class MultipleMixins : public GarbageCollected<MultipleMixins>,
public:
MultipleMixins() : obj_(MakeGarbageCollected<IntWrapper>(102)) {}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(obj_);
MixinA::Trace(visitor);
MixinB::Trace(visitor);
@@ -4468,7 +4287,7 @@ class DerivedMultipleMixins : public MultipleMixins {
public:
DerivedMultipleMixins() : obj_(MakeGarbageCollected<IntWrapper>(103)) {}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
trace_called_++;
visitor->Trace(obj_);
MultipleMixins::Trace(visitor);
@@ -4686,7 +4505,7 @@ TEST_F(HeapTest, EphemeronsInEphemerons) {
class EphemeronWrapper : public GarbageCollected<EphemeronWrapper> {
public:
- void Trace(blink::Visitor* visitor) { visitor->Trace(map_); }
+ void Trace(Visitor* visitor) { visitor->Trace(map_); }
typedef HeapHashMap<WeakMember<IntWrapper>, Member<EphemeronWrapper>> Map;
Map& GetMap() { return map_; }
@@ -4778,7 +4597,7 @@ class Link1 : public GarbageCollected<Link1> {
public:
Link1(IntWrapper* link) : link_(link) {}
- void Trace(blink::Visitor* visitor) { visitor->Trace(link_); }
+ void Trace(Visitor* visitor) { visitor->Trace(link_); }
IntWrapper* Link() { return link_; }
@@ -4820,9 +4639,7 @@ class TraceIfNeededTester final
TraceIfNeededTester() = default;
explicit TraceIfNeededTester(const T& obj) : obj_(obj) {}
- void Trace(blink::Visitor* visitor) {
- TraceIfNeeded<T>::Trace(visitor, obj_);
- }
+ void Trace(Visitor* visitor) { TraceIfNeeded<T>::Trace(visitor, obj_); }
T& Obj() { return obj_; }
~TraceIfNeededTester() = default;
@@ -4835,7 +4652,7 @@ class PartObject {
public:
PartObject() : obj_(MakeGarbageCollected<SimpleObject>()) {}
- void Trace(blink::Visitor* visitor) { visitor->Trace(obj_); }
+ void Trace(Visitor* visitor) { visitor->Trace(obj_); }
private:
Member<SimpleObject> obj_;
@@ -4864,7 +4681,7 @@ class AllocatesOnAssignment {
inline bool IsDeleted() const { return value_.IsHashTableDeletedValue(); }
- void Trace(blink::Visitor* visitor) { visitor->Trace(value_); }
+ void Trace(Visitor* visitor) { visitor->Trace(value_); }
int Value() { return value_->Value(); }
@@ -4940,14 +4757,14 @@ TEST_F(HeapTest, GCInHashMapOperations) {
class PartObjectWithVirtualMethod {
public:
- virtual void Trace(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
};
class ObjectWithVirtualPartObject
: public GarbageCollected<ObjectWithVirtualPartObject> {
public:
ObjectWithVirtualPartObject() : dummy_(AllocateAndReturnBool()) {}
- void Trace(blink::Visitor* visitor) { visitor->Trace(part_); }
+ void Trace(Visitor* visitor) { visitor->Trace(part_); }
private:
bool dummy_;
@@ -4965,7 +4782,7 @@ class AllocInSuperConstructorArgumentSuper
public:
AllocInSuperConstructorArgumentSuper(bool value) : value_(value) {}
virtual ~AllocInSuperConstructorArgumentSuper() = default;
- virtual void Trace(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
bool Value() { return value_; }
private:
@@ -4995,7 +4812,7 @@ class NonNodeAllocatingNodeInDestructor final
node_ = new Persistent<IntNode>(IntNode::Create(10));
}
- void Trace(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
static Persistent<IntNode>* node_;
};
@@ -5014,7 +4831,7 @@ class DeepEagerly final : public GarbageCollected<DeepEagerly> {
public:
DeepEagerly(DeepEagerly* next) : next_(next) {}
- void Trace(blink::Visitor* visitor) {
+ void Trace(Visitor* visitor) {
int calls = ++s_trace_calls_;
if (s_trace_lazy_ <= 2)
visitor->Trace(next_);
@@ -5118,7 +4935,7 @@ class PartObjectWithRef {
public:
PartObjectWithRef(int i) : value_(SimpleRefValue::Create(i)) {}
- void Trace(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
int Value() const { return value_->Value(); }
@@ -5132,68 +4949,6 @@ WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::PartObjectWithRef)
namespace blink {
-TEST_F(HeapTest, DequePartObjectsExpand) {
- // Test expansion of HeapDeque<PartObject>
-
- using PartDeque = HeapDeque<PartObjectWithRef>;
-
- Persistent<PartDeque> deque = MakeGarbageCollected<PartDeque>();
- // Auxillary Deque used to prevent 'inline' buffer expansion.
- Persistent<PartDeque> deque_unused = MakeGarbageCollected<PartDeque>();
-
- // Append a sequence, bringing about repeated expansions of the
- // deque's buffer.
- int i = 0;
- for (; i < 60; ++i) {
- deque->push_back(PartObjectWithRef(i));
- deque_unused->push_back(PartObjectWithRef(i));
- }
-
- EXPECT_EQ(60u, deque->size());
- i = 0;
- for (const PartObjectWithRef& part : *deque) {
- EXPECT_EQ(i, part.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 PartObjectWithRef& part : *deque) {
- EXPECT_EQ(50 + i, part.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(PartObjectWithRef(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 PartObjectWithRef& part : *deque) {
- EXPECT_EQ(i + 50, part.Value());
- i++;
- }
-
- for (i = 0; i < 70; ++i)
- deque->push_back(PartObjectWithRef(130 + i));
-
- EXPECT_EQ(150u, deque->size());
- i = 0;
- for (const PartObjectWithRef& part : *deque) {
- EXPECT_EQ(i + 50, part.Value());
- i++;
- }
-}
-
TEST_F(HeapTest, HeapVectorPartObjects) {
HeapVector<PartObjectWithRef> vector1;
HeapVector<PartObjectWithRef> vector2;
@@ -5234,7 +4989,7 @@ class TestMixinAllocationA : public GarbageCollected<TestMixinAllocationA>,
public:
TestMixinAllocationA() = default;
- void Trace(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) override {}
};
class TestMixinAllocationB : public TestMixinAllocationA {
@@ -5245,7 +5000,7 @@ class TestMixinAllocationB : public TestMixinAllocationA {
// Construct object during a mixin construction.
: a_(MakeGarbageCollected<TestMixinAllocationA>()) {}
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(a_);
TestMixinAllocationA::Trace(visitor);
}
@@ -5260,7 +5015,7 @@ class TestMixinAllocationC final : public TestMixinAllocationB {
public:
TestMixinAllocationC() { DCHECK(!ThreadState::Current()->IsGCForbidden()); }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
TestMixinAllocationB::Trace(visitor);
}
};
@@ -5368,7 +5123,7 @@ class ThreadedClearOnShutdownTester::HeapObject final
GetHeapObjectSet().insert(MakeGarbageCollected<HeapObject>(false));
}
- void Trace(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
private:
bool test_destructor_;
@@ -5415,7 +5170,7 @@ class WithWeakConstObject final : public GarbageCollected<WithWeakConstObject> {
public:
WithWeakConstObject(const IntWrapper* int_wrapper) : wrapper_(int_wrapper) {}
- void Trace(blink::Visitor* visitor) { visitor->Trace(wrapper_); }
+ void Trace(Visitor* visitor) { visitor->Trace(wrapper_); }
const IntWrapper* Value() const { return wrapper_; }
@@ -5473,6 +5228,9 @@ TEST_F(HeapTest, IsGarbageCollected) {
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");
@@ -5549,6 +5307,8 @@ TEST_F(HeapTest, GarbageCollectedMixinIsAliveDuringConstruction) {
using P = HeapVector<Member<HeapLinkedHashSet<Member<IntWrapper>>>>;
MakeGarbageCollected<P>();
+ using Q = HeapVector<Member<HeapNewLinkedHashSet<Member<IntWrapper>>>>;
+ MakeGarbageCollected<Q>();
}
TEST_F(HeapTest, PersistentAssignsDeletedValue) {
@@ -5602,7 +5362,8 @@ TEST_F(HeapTest, AccessDeletedBackingStore) {
}
BaseArena* map_arena = PageFromObject(map)->Arena();
// Sweep normal arena, but don't call finalizers.
- map_arena->ConcurrentSweepWithDeadline(base::TimeTicks::Max());
+ while (!map_arena->ConcurrentSweepOnePage()) {
+ }
// Now complete sweeping with PerformIdleLazySweep and call finalizers.
while (thread_state->IsSweepingInProgress()) {
thread_state->PerformIdleLazySweep(base::TimeTicks::Max());
@@ -5629,4 +5390,25 @@ TEST_F(HeapTest, CallMostDerivedFinalizer) {
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 3292be44245..2efb5e40779 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
@@ -11,11 +11,14 @@
namespace blink {
+std::atomic_int IntegerObject::destructor_calls{0};
+
// static
void TestSupportingGC::PreciselyCollectGarbage(
BlinkGC::SweepingType sweeping_type) {
ThreadState::Current()->CollectGarbage(
- BlinkGC::kNoHeapPointersOnStack, BlinkGC::kAtomicMarking, sweeping_type,
+ BlinkGC::CollectionType::kMajor, BlinkGC::kNoHeapPointersOnStack,
+ BlinkGC::kAtomicMarking, sweeping_type,
BlinkGC::GCReason::kForcedGCForTesting);
}
@@ -23,10 +26,16 @@ void TestSupportingGC::PreciselyCollectGarbage(
void TestSupportingGC::ConservativelyCollectGarbage(
BlinkGC::SweepingType sweeping_type) {
ThreadState::Current()->CollectGarbage(
- BlinkGC::kHeapPointersOnStack, BlinkGC::kAtomicMarking, sweeping_type,
+ BlinkGC::CollectionType::kMajor, BlinkGC::kHeapPointersOnStack,
+ BlinkGC::kAtomicMarking, sweeping_type,
BlinkGC::GCReason::kForcedGCForTesting);
}
+TestSupportingGC::~TestSupportingGC() {
+ // Complete sweeping before |task_environment_| is destroyed.
+ CompleteSweepingIfNeeded();
+}
+
void TestSupportingGC::ClearOutOldGarbage() {
PreciselyCollectGarbage();
ThreadHeap& heap = ThreadState::Current()->Heap();
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 a9d37305606..a2a53e2e96e 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
@@ -29,6 +29,8 @@ class TestSupportingGC : public testing::Test {
static void ConservativelyCollectGarbage(
BlinkGC::SweepingType sweeping_type = BlinkGC::kEagerSweeping);
+ ~TestSupportingGC() override;
+
// Performs multiple rounds of garbage collections until no more memory can be
// freed. This is useful to avoid other garbage collections having to deal
// with stale memory.
@@ -171,7 +173,15 @@ class IncrementalMarkingTestDriver {
class IntegerObject : public GarbageCollected<IntegerObject> {
public:
- void Trace(blink::Visitor* visitor) {}
+ static std::atomic_int destructor_calls;
+
+ explicit IntegerObject(int x) : x_(x) {}
+
+ virtual ~IntegerObject() {
+ destructor_calls.fetch_add(1, std::memory_order_relaxed);
+ }
+
+ virtual void Trace(Visitor* visitor) {}
int Value() const { return x_; }
@@ -181,8 +191,6 @@ class IntegerObject : public GarbageCollected<IntegerObject> {
unsigned GetHash() { return IntHash<int>::GetHash(x_); }
- explicit IntegerObject(int x) : x_(x) {}
-
private:
int 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
index 80ef9b05470..c1fbe2d720b 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_thread_test.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_thread_test.cc
@@ -17,7 +17,13 @@
namespace blink {
class HeapThreadTest : public TestSupportingGC {};
-class HeapThreadDeathTest : public TestSupportingGC {};
+
+class HeapThreadDeathTest : public TestSupportingGC {
+ public:
+ HeapThreadDeathTest() {
+ testing::FLAGS_gtest_death_test_style = "threadsafe";
+ }
+};
namespace heap_thread_test {
@@ -69,7 +75,7 @@ static void ParkWorkerThread() {
class Object : public GarbageCollected<Object> {
public:
Object() {}
- void Trace(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
};
class AlternatingThreadTester {
@@ -136,14 +142,10 @@ class MemberSameThreadCheckTester : public AlternatingThreadTester {
};
#if DCHECK_IS_ON()
-// TODO(keishi) This test is flaky on mac-rel bot.
-// crbug.com/709069
-#if !defined(OS_MACOSX)
TEST_F(HeapThreadDeathTest, MemberSameThreadCheck) {
EXPECT_DEATH(MemberSameThreadCheckTester().Test(), "");
}
#endif
-#endif
class PersistentSameThreadCheckTester : public AlternatingThreadTester {
private:
@@ -159,20 +161,16 @@ class PersistentSameThreadCheckTester : public AlternatingThreadTester {
};
#if DCHECK_IS_ON()
-// TODO(keishi) This test is flaky on mac-rel bot.
-// crbug.com/709069
-#if !defined(OS_MACOSX)
TEST_F(HeapThreadDeathTest, PersistentSameThreadCheck) {
EXPECT_DEATH(PersistentSameThreadCheckTester().Test(), "");
}
#endif
-#endif
class MarkingSameThreadCheckTester : public AlternatingThreadTester {
private:
class MainThreadObject final : public GarbageCollected<MainThreadObject> {
public:
- void Trace(blink::Visitor* visitor) { visitor->Trace(set_); }
+ void Trace(Visitor* visitor) { visitor->Trace(set_); }
void AddToSet(Object* object) { set_.insert(42, object); }
private:
@@ -199,8 +197,6 @@ class MarkingSameThreadCheckTester : public AlternatingThreadTester {
};
#if DCHECK_IS_ON()
-// TODO(keishi) This test is flaky on mac-rel bot. https://crbug.com/709069, and
-// times out on other bots. https://crbug.com/993148.
TEST_F(HeapThreadDeathTest, DISABLED_MarkingSameThreadCheck) {
// This will crash during marking, at the DCHECK in Visitor::markHeader() or
// earlier.
@@ -215,7 +211,7 @@ class DestructorLockingObject
virtual ~DestructorLockingObject() { ++destructor_calls_; }
static int destructor_calls_;
- void Trace(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
};
int DestructorLockingObject::destructor_calls_ = 0;
@@ -254,8 +250,9 @@ class CrossThreadWeakPersistentTester : public AlternatingThreadTester {
// Step 4: Run a GC.
ThreadState::Current()->CollectGarbage(
- BlinkGC::kNoHeapPointersOnStack, BlinkGC::kAtomicMarking,
- BlinkGC::kEagerSweeping, BlinkGC::GCReason::kForcedGCForTesting);
+ BlinkGC::CollectionType::kMajor, BlinkGC::kNoHeapPointersOnStack,
+ BlinkGC::kAtomicMarking, BlinkGC::kEagerSweeping,
+ BlinkGC::GCReason::kForcedGCForTesting);
SwitchToMainThread();
}
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
index 539c26c3757..2e50a064992 100644
--- a/chromium/third_party/blink/renderer/platform/heap/heap_traits_test.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/heap_traits_test.cc
@@ -22,12 +22,12 @@ struct Empty {};
// Similar to an IDL union or dictionary, which have Trace() methods but are
// not garbage-collected types themselves.
struct StructWithTraceMethod {
- void Trace(blink::Visitor*) {}
+ void Trace(Visitor*) {}
};
struct GarbageCollectedStruct
: public GarbageCollected<GarbageCollectedStruct> {
- void Trace(blink::Visitor*) {}
+ void Trace(Visitor*) {}
};
// AddMemberIfNeeded<T>
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
index c3725ad1524..5132cc58f40 100644
--- a/chromium/third_party/blink/renderer/platform/heap/incremental_marking_test.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/incremental_marking_test.cc
@@ -39,12 +39,11 @@ class BackingVisitor : public Visitor {
void ProcessBackingStore(HeapObjectHeader* header) {
EXPECT_TRUE(header->IsMarked());
header->Unmark();
- GCInfoTable::Get()
- .GCInfoFromIndex(header->GcInfoIndex())
- ->trace(this, header->Payload());
+
+ GCInfo::From(header->GcInfoIndex()).trace(this, header->Payload());
}
- void Visit(void* obj, TraceDescriptor desc) final {
+ void Visit(const void* obj, TraceDescriptor desc) final {
EXPECT_TRUE(obj);
auto** pos = std::find(objects_->begin(), objects_->end(), obj);
if (objects_->end() != pos)
@@ -53,12 +52,12 @@ class BackingVisitor : public Visitor {
HeapObjectHeader* const header =
HeapObjectHeader::FromPayload(desc.base_object_payload);
if (!header->IsMarked())
- header->Mark();
+ EXPECT_TRUE(header->TryMark());
}
bool VisitEphemeronKeyValuePair(
- void* key,
- void* value,
+ const void* key,
+ const void* value,
EphemeronTracingCallback key_trace_callback,
EphemeronTracingCallback value_trace_callback) final {
const bool key_is_dead = key_trace_callback(this, key);
@@ -70,22 +69,23 @@ class BackingVisitor : public Visitor {
}
// Unused overrides.
- void VisitWeak(void* object,
- void* object_weak_ref,
+ void VisitWeak(const void* object,
+ const void* object_weak_ref,
TraceDescriptor desc,
WeakCallback callback) final {}
- void VisitBackingStoreStrongly(void* object,
- void** object_slot,
+ void VisitBackingStoreStrongly(const void* object,
+ const void* const* object_slot,
TraceDescriptor desc) final {}
- void VisitBackingStoreWeakly(void*,
- void**,
+ void VisitBackingStoreWeakly(const void*,
+ const void* const*,
TraceDescriptor,
TraceDescriptor,
WeakCallback,
- void*) final {}
- void VisitBackingStoreOnly(void*, void**) final {}
- void RegisterBackingStoreCallback(void* slot, MovingObjectCallback) final {}
- void RegisterWeakCallback(WeakCallback, void*) final {}
+ const void*) final {}
+ void VisitBackingStoreOnly(const void*, const void* const*) final {}
+ void RegisterBackingStoreCallback(const void* slot,
+ MovingObjectCallback) final {}
+ void RegisterWeakCallback(WeakCallback, const void*) final {}
void Visit(const TraceWrapperV8Reference<v8::Value>&) final {}
private:
@@ -103,7 +103,7 @@ class IncrementalMarkingScopeBase {
thread_state_->IsSweepingInProgress()) {
TestSupportingGC::PreciselyCollectGarbage();
}
- heap_.SetupWorklists();
+ heap_.SetupWorklists(false);
}
~IncrementalMarkingScopeBase() {
@@ -280,6 +280,20 @@ class Object : public LinkedObject {
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. ===============================================
// =============================================================================
@@ -294,20 +308,22 @@ TEST_F(IncrementalMarkingTest, EnableDisableBarrier) {
}
TEST_F(IncrementalMarkingTest, ManualWriteBarrierTriggersWhenMarkingIsOn) {
- auto* object = MakeGarbageCollected<Object>();
+ auto* object1 = MakeGarbageCollected<Object>();
+ auto* object2 = MakeGarbageCollected<RawPtrObjectWithManualWriteBarrier>();
{
- ExpectWriteBarrierFires scope(ThreadState::Current(), {object});
- EXPECT_FALSE(object->IsMarked());
- MarkingVisitor::WriteBarrier(object);
- EXPECT_TRUE(object->IsMarked());
+ ExpectWriteBarrierFires scope(ThreadState::Current(), {object1});
+ EXPECT_FALSE(object1->IsMarked());
+ object2->Set(object1);
+ EXPECT_TRUE(object1->IsMarked());
}
}
TEST_F(IncrementalMarkingTest, ManualWriteBarrierBailoutWhenMarkingIsOff) {
- auto* object = MakeGarbageCollected<Object>();
- EXPECT_FALSE(object->IsMarked());
- MarkingVisitor::WriteBarrier(object);
- EXPECT_FALSE(object->IsMarked());
+ auto* object1 = MakeGarbageCollected<Object>();
+ auto* object2 = MakeGarbageCollected<RawPtrObjectWithManualWriteBarrier>();
+ EXPECT_FALSE(object1->IsMarked());
+ object2->Set(object1);
+ EXPECT_FALSE(object1->IsMarked());
}
// =============================================================================
@@ -328,7 +344,7 @@ TEST_F(IncrementalMarkingTest, MemberSetUnmarkedObject) {
TEST_F(IncrementalMarkingTest, MemberSetMarkedObjectNoBarrier) {
auto* parent = MakeGarbageCollected<Object>();
auto* child = MakeGarbageCollected<Object>();
- HeapObjectHeader::FromPayload(child)->Mark();
+ EXPECT_TRUE(HeapObjectHeader::FromPayload(child)->TryMark());
{
ExpectNoWriteBarrierFires scope(ThreadState::Current(), {child});
parent->set_next(child);
@@ -349,10 +365,10 @@ TEST_F(IncrementalMarkingTest, MemberInitializingStoreNoBarrier) {
}
TEST_F(IncrementalMarkingTest, MemberReferenceAssignMember) {
- auto* obj = MakeGarbageCollected<Object>();
- Member<Object> m1;
- Member<Object>& m2 = m1;
- Member<Object> m3(obj);
+ 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;
@@ -360,7 +376,8 @@ TEST_F(IncrementalMarkingTest, MemberReferenceAssignMember) {
}
TEST_F(IncrementalMarkingTest, MemberSetDeletedValueNoBarrier) {
- Member<Object> m;
+ auto* obj = MakeGarbageCollected<LinkedObject>();
+ Member<LinkedObject>& m = obj->next_ref();
{
ExpectNoWriteBarrierFires scope(ThreadState::Current(), {});
m = WTF::kHashTableDeletedValue;
@@ -368,26 +385,32 @@ TEST_F(IncrementalMarkingTest, MemberSetDeletedValueNoBarrier) {
}
TEST_F(IncrementalMarkingTest, MemberCopyDeletedValueNoBarrier) {
- Member<Object> m1(WTF::kHashTableDeletedValue);
+ auto* obj1 = MakeGarbageCollected<LinkedObject>();
+ Member<LinkedObject>& m1 = obj1->next_ref();
+ m1 = WTF::kHashTableDeletedValue;
{
ExpectNoWriteBarrierFires scope(ThreadState::Current(), {});
- Member<Object> m2(m1);
+ auto* obj2 = MakeGarbageCollected<LinkedObject>();
+ obj2->next_ref() = m1;
}
}
TEST_F(IncrementalMarkingTest, MemberHashTraitConstructDeletedValueNoBarrier) {
- Member<Object> m1;
+ auto* obj = MakeGarbageCollected<LinkedObject>();
+ Member<LinkedObject>& m = obj->next_ref();
{
ExpectNoWriteBarrierFires scope(ThreadState::Current(), {});
- HashTraits<Member<Object>>::ConstructDeletedValue(m1, false);
+ HashTraits<Member<LinkedObject>>::ConstructDeletedValue(m, false);
}
}
TEST_F(IncrementalMarkingTest, MemberHashTraitIsDeletedValueNoBarrier) {
- Member<Object> m1(MakeGarbageCollected<Object>());
+ auto* obj =
+ MakeGarbageCollected<LinkedObject>(MakeGarbageCollected<LinkedObject>());
+ Member<LinkedObject>& m = obj->next_ref();
{
ExpectNoWriteBarrierFires scope(ThreadState::Current(), {});
- EXPECT_FALSE(HashTraits<Member<Object>>::IsDeletedValue(m1));
+ EXPECT_FALSE(HashTraits<Member<LinkedObject>>::IsDeletedValue(m));
}
}
@@ -402,7 +425,7 @@ class Mixin : public GarbageCollectedMixin {
Mixin() : next_(nullptr) {}
virtual ~Mixin() {}
- void Trace(blink::Visitor* visitor) override { visitor->Trace(next_); }
+ void Trace(Visitor* visitor) override { visitor->Trace(next_); }
virtual void Bar() {}
@@ -424,7 +447,7 @@ class Child : public GarbageCollected<Child>,
Child() : ClassWithVirtual(), Mixin() {}
~Child() override {}
- void Trace(blink::Visitor* visitor) override { Mixin::Trace(visitor); }
+ void Trace(Visitor* visitor) override { Mixin::Trace(visitor); }
void Foo() override {}
void Bar() override {}
@@ -436,7 +459,7 @@ class ParentWithMixinPointer : public GarbageCollected<ParentWithMixinPointer> {
void set_mixin(Mixin* mixin) { mixin_ = mixin; }
- virtual void Trace(blink::Visitor* visitor) { visitor->Trace(mixin_); }
+ virtual void Trace(Visitor* visitor) { visitor->Trace(mixin_); }
protected:
Member<Mixin> mixin_;
@@ -460,7 +483,7 @@ TEST_F(IncrementalMarkingTest, NoWriteBarrierOnMarkedMixinApplication) {
ParentWithMixinPointer* parent =
MakeGarbageCollected<ParentWithMixinPointer>();
auto* child = MakeGarbageCollected<Child>();
- HeapObjectHeader::FromPayload(child)->Mark();
+ EXPECT_TRUE(HeapObjectHeader::FromPayload(child)->TryMark());
Mixin* mixin = static_cast<Mixin*>(child);
EXPECT_NE(static_cast<void*>(child), static_cast<void*>(mixin));
{
@@ -484,7 +507,7 @@ class NonGarbageCollectedContainer {
NonGarbageCollectedContainer(Object* obj, int y) : obj_(obj), y_(y) {}
virtual ~NonGarbageCollectedContainer() {}
- virtual void Trace(blink::Visitor* visitor) { visitor->Trace(obj_); }
+ virtual void Trace(Visitor* visitor) { visitor->Trace(obj_); }
private:
Member<Object> obj_;
@@ -499,7 +522,7 @@ class NonGarbageCollectedContainerRoot {
: next_(obj1, y), obj_(obj2) {}
virtual ~NonGarbageCollectedContainerRoot() {}
- virtual void Trace(blink::Visitor* visitor) {
+ virtual void Trace(Visitor* visitor) {
visitor->Trace(next_);
visitor->Trace(obj_);
}
@@ -513,158 +536,168 @@ class NonGarbageCollectedContainerRoot {
TEST_F(IncrementalMarkingTest, HeapVectorPushBackMember) {
auto* obj = MakeGarbageCollected<Object>();
- HeapVector<Member<Object>> vec;
+ auto* vec = MakeGarbageCollected<HeapVector<Member<Object>>>();
{
ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
- vec.push_back(obj);
+ vec->push_back(obj);
}
}
TEST_F(IncrementalMarkingTest, HeapVectorPushBackNonGCedContainer) {
auto* obj = MakeGarbageCollected<Object>();
- HeapVector<NonGarbageCollectedContainer> vec;
+ auto* vec = MakeGarbageCollected<HeapVector<NonGarbageCollectedContainer>>();
{
ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
- vec.push_back(NonGarbageCollectedContainer(obj, 1));
+ vec->push_back(NonGarbageCollectedContainer(obj, 1));
}
}
TEST_F(IncrementalMarkingTest, HeapVectorPushBackStdPair) {
auto* obj1 = MakeGarbageCollected<Object>();
auto* obj2 = MakeGarbageCollected<Object>();
- HeapVector<std::pair<Member<Object>, Member<Object>>> vec;
+ 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)));
+ vec->push_back(std::make_pair(Member<Object>(obj1), Member<Object>(obj2)));
}
}
TEST_F(IncrementalMarkingTest, HeapVectorEmplaceBackMember) {
auto* obj = MakeGarbageCollected<Object>();
- HeapVector<Member<Object>> vec;
+ auto* vec = MakeGarbageCollected<HeapVector<Member<Object>>>();
{
ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
- vec.emplace_back(obj);
+ vec->emplace_back(obj);
}
}
TEST_F(IncrementalMarkingTest, HeapVectorEmplaceBackNonGCedContainer) {
auto* obj = MakeGarbageCollected<Object>();
- HeapVector<NonGarbageCollectedContainer> vec;
+ auto* vec = MakeGarbageCollected<HeapVector<NonGarbageCollectedContainer>>();
{
ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
- vec.emplace_back(obj, 1);
+ vec->emplace_back(obj, 1);
}
}
TEST_F(IncrementalMarkingTest, HeapVectorEmplaceBackStdPair) {
auto* obj1 = MakeGarbageCollected<Object>();
auto* obj2 = MakeGarbageCollected<Object>();
- HeapVector<std::pair<Member<Object>, Member<Object>>> vec;
+ auto* vec = MakeGarbageCollected<
+ HeapVector<std::pair<Member<Object>, Member<Object>>>>();
{
ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- vec.emplace_back(obj1, obj2);
+ vec->emplace_back(obj1, obj2);
}
}
TEST_F(IncrementalMarkingTest, HeapVectorCopyMember) {
auto* object = MakeGarbageCollected<Object>();
- HeapVector<Member<Object>> vec1;
- vec1.push_back(object);
+ auto* vec1 = MakeGarbageCollected<HeapVector<Member<Object>>>();
+ vec1->push_back(object);
{
ExpectWriteBarrierFires scope(ThreadState::Current(), {object});
- HeapVector<Member<Object>> vec2(vec1);
+ MakeGarbageCollected<HeapVector<Member<Object>>>(*vec1);
}
}
TEST_F(IncrementalMarkingTest, HeapVectorCopyNonGCedContainer) {
auto* obj = MakeGarbageCollected<Object>();
- HeapVector<NonGarbageCollectedContainer> vec1;
- vec1.emplace_back(obj, 1);
+ auto* vec1 = MakeGarbageCollected<HeapVector<NonGarbageCollectedContainer>>();
+ vec1->emplace_back(obj, 1);
{
ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
- HeapVector<NonGarbageCollectedContainer> vec2(vec1);
+ MakeGarbageCollected<HeapVector<NonGarbageCollectedContainer>>(*vec1);
}
}
TEST_F(IncrementalMarkingTest, HeapVectorCopyStdPair) {
+ using ValueType = std::pair<Member<Object>, Member<Object>>;
auto* obj1 = MakeGarbageCollected<Object>();
auto* obj2 = MakeGarbageCollected<Object>();
- HeapVector<std::pair<Member<Object>, Member<Object>>> vec1;
- vec1.emplace_back(obj1, obj2);
+ auto* vec1 = MakeGarbageCollected<HeapVector<ValueType>>();
+ vec1->emplace_back(obj1, obj2);
{
ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- HeapVector<std::pair<Member<Object>, Member<Object>>> vec2(vec1);
+ MakeGarbageCollected<HeapVector<ValueType>>(*vec1);
}
}
TEST_F(IncrementalMarkingTest, HeapVectorMoveMember) {
auto* obj = MakeGarbageCollected<Object>();
- HeapVector<Member<Object>> vec1;
- vec1.push_back(obj);
+ auto* vec1 = MakeGarbageCollected<HeapVector<Member<Object>>>();
+ vec1->push_back(obj);
{
ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
- HeapVector<Member<Object>> vec2(std::move(vec1));
+ MakeGarbageCollected<HeapVector<Member<Object>>>(std::move(*vec1));
}
}
TEST_F(IncrementalMarkingTest, HeapVectorMoveNonGCedContainer) {
auto* obj = MakeGarbageCollected<Object>();
- HeapVector<NonGarbageCollectedContainer> vec1;
- vec1.emplace_back(obj, 1);
+ auto* vec1 = MakeGarbageCollected<HeapVector<NonGarbageCollectedContainer>>();
+ vec1->emplace_back(obj, 1);
{
ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
- HeapVector<NonGarbageCollectedContainer> vec2(std::move(vec1));
+ 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>();
- HeapVector<std::pair<Member<Object>, Member<Object>>> vec1;
- vec1.emplace_back(obj1, obj2);
+ auto* vec1 = MakeGarbageCollected<VectorType>();
+ vec1->emplace_back(obj1, obj2);
{
ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- HeapVector<std::pair<Member<Object>, Member<Object>>> vec2(std::move(vec1));
+ MakeGarbageCollected<VectorType>(std::move(*vec1));
}
}
TEST_F(IncrementalMarkingTest, HeapVectorSwapMember) {
+ using VectorType = HeapVector<Member<Object>>;
auto* obj1 = MakeGarbageCollected<Object>();
auto* obj2 = MakeGarbageCollected<Object>();
- HeapVector<Member<Object>> vec1;
- vec1.push_back(obj1);
- HeapVector<Member<Object>> vec2;
- vec2.push_back(obj2);
+ 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);
+ std::swap(*vec1, *vec2);
}
}
TEST_F(IncrementalMarkingTest, HeapVectorSwapNonGCedContainer) {
+ using VectorType = HeapVector<NonGarbageCollectedContainer>;
auto* obj1 = MakeGarbageCollected<Object>();
auto* obj2 = MakeGarbageCollected<Object>();
- HeapVector<NonGarbageCollectedContainer> vec1;
- vec1.emplace_back(obj1, 1);
- HeapVector<NonGarbageCollectedContainer> vec2;
- vec2.emplace_back(obj2, 2);
+ 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);
+ 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>();
- HeapVector<std::pair<Member<Object>, Member<Object>>> vec1;
- vec1.emplace_back(obj1, nullptr);
- HeapVector<std::pair<Member<Object>, Member<Object>>> vec2;
- vec2.emplace_back(nullptr, obj2);
+ 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);
+ std::swap(*vec1, *vec2);
}
}
@@ -826,23 +859,23 @@ void CopyNoBarrier() {
template <typename Container>
void Move() {
auto* obj = MakeGarbageCollected<Object>();
- Container container1;
- Container container2;
- container1.insert(obj);
+ auto* container1 = MakeGarbageCollected<Container>();
+ auto* container2 = MakeGarbageCollected<Container>();
+ container1->insert(obj);
{
ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
- container2 = std::move(container1);
+ *container2 = std::move(*container1);
}
}
template <typename Container>
void MoveNoBarrier() {
auto* obj = MakeGarbageCollected<Object>();
- Container container1;
- container1.insert(obj);
+ auto* container1 = MakeGarbageCollected<Container>();
+ container1->insert(obj);
{
ExpectNoWriteBarrierFires scope(ThreadState::Current(), {obj});
- Container container2(std::move(container1));
+ auto* container2 = MakeGarbageCollected<Container>(std::move(*container1));
}
}
@@ -850,13 +883,13 @@ template <typename Container>
void Swap() {
auto* obj1 = MakeGarbageCollected<Object>();
auto* obj2 = MakeGarbageCollected<Object>();
- Container container1;
- container1.insert(obj1);
- Container container2;
- container2.insert(obj2);
+ auto* container1 = MakeGarbageCollected<Container>();
+ container1->insert(obj1);
+ auto* container2 = MakeGarbageCollected<Container>();
+ container2->insert(obj2);
{
ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- std::swap(container1, container2);
+ std::swap(*container1, *container2);
}
}
@@ -864,13 +897,13 @@ template <typename Container>
void SwapNoBarrier() {
auto* obj1 = MakeGarbageCollected<Object>();
auto* obj2 = MakeGarbageCollected<Object>();
- Container container1;
- container1.insert(obj1);
- Container container2;
- container2.insert(obj2);
+ auto* container1 = MakeGarbageCollected<Container>();
+ container1->insert(obj1);
+ auto* container2 = MakeGarbageCollected<Container>();
+ container2->insert(obj2);
{
ExpectNoWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- std::swap(container1, container2);
+ std::swap(*container1, *container2);
}
}
@@ -928,6 +961,9 @@ TEST_F(IncrementalMarkingTest, HeapLinkedHashSetSwap) {
Swap<HeapLinkedHashSet<WeakMember<Object>>>();
}
+// TODO(keinakashima): add tests for NewLinkedHashSet after supporting
+// WeakMember
+
// =============================================================================
// HeapHashCountedSet support. =================================================
// =============================================================================
@@ -945,26 +981,30 @@ TEST_F(IncrementalMarkingTest, HeapHashCountedSetSwap) {
{
auto* obj1 = MakeGarbageCollected<Object>();
auto* obj2 = MakeGarbageCollected<Object>();
- HeapHashCountedSet<Member<Object>> container1;
- container1.insert(obj1);
- HeapHashCountedSet<Member<Object>> container2;
- container2.insert(obj2);
+ 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);
+ container1->swap(*container2);
}
}
{
auto* obj1 = MakeGarbageCollected<Object>();
auto* obj2 = MakeGarbageCollected<Object>();
- HeapHashCountedSet<WeakMember<Object>> container1;
- container1.insert(obj1);
- HeapHashCountedSet<WeakMember<Object>> container2;
- container2.insert(obj2);
+ 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);
+ container1->swap(*container2);
}
}
}
@@ -1132,47 +1172,55 @@ TEST_F(IncrementalMarkingTest, HeapHashMapCopyWeakMemberMember) {
TEST_F(IncrementalMarkingTest, HeapHashMapMoveMember) {
auto* obj1 = MakeGarbageCollected<Object>();
auto* obj2 = MakeGarbageCollected<Object>();
- HeapHashMap<Member<Object>, Member<Object>> map1;
- map1.insert(obj1, obj2);
+ auto* map1 =
+ MakeGarbageCollected<HeapHashMap<Member<Object>, Member<Object>>>();
+ map1->insert(obj1, obj2);
{
ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2});
- HeapHashMap<Member<Object>, Member<Object>> map2(std::move(map1));
+ MakeGarbageCollected<HeapHashMap<Member<Object>, Member<Object>>>(
+ std::move(*map1));
}
}
TEST_F(IncrementalMarkingTest, HeapHashMapMoveWeakMember) {
auto* obj1 = MakeGarbageCollected<Object>();
auto* obj2 = MakeGarbageCollected<Object>();
- HeapHashMap<WeakMember<Object>, WeakMember<Object>> map1;
- map1.insert(obj1, obj2);
+ 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});
- HeapHashMap<WeakMember<Object>, WeakMember<Object>> map2(std::move(map1));
+ MakeGarbageCollected<HeapHashMap<WeakMember<Object>, WeakMember<Object>>>(
+ std::move(*map1));
}
}
TEST_F(IncrementalMarkingTest, HeapHashMapMoveMemberWeakMember) {
auto* obj1 = MakeGarbageCollected<Object>();
auto* obj2 = MakeGarbageCollected<Object>();
- HeapHashMap<Member<Object>, WeakMember<Object>> map1;
- map1.insert(obj1, obj2);
+ 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});
- HeapHashMap<Member<Object>, WeakMember<Object>> map2(std::move(map1));
+ MakeGarbageCollected<HeapHashMap<Member<Object>, WeakMember<Object>>>(
+ std::move(*map1));
}
}
TEST_F(IncrementalMarkingTest, HeapHashMapMoveWeakMemberMember) {
auto* obj1 = MakeGarbageCollected<Object>();
auto* obj2 = MakeGarbageCollected<Object>();
- HeapHashMap<WeakMember<Object>, Member<Object>> map1;
- map1.insert(obj1, obj2);
+ 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});
- HeapHashMap<WeakMember<Object>, Member<Object>> map2(std::move(map1));
+ MakeGarbageCollected<HeapHashMap<WeakMember<Object>, Member<Object>>>(
+ std::move(*map1));
}
}
@@ -1181,14 +1229,16 @@ TEST_F(IncrementalMarkingTest, HeapHashMapSwapMemberMember) {
auto* obj2 = MakeGarbageCollected<Object>();
auto* obj3 = MakeGarbageCollected<Object>();
auto* obj4 = MakeGarbageCollected<Object>();
- HeapHashMap<Member<Object>, Member<Object>> map1;
- map1.insert(obj1, obj2);
- HeapHashMap<Member<Object>, Member<Object>> map2;
- map2.insert(obj3, obj4);
+ 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);
+ std::swap(*map1, *map2);
}
}
@@ -1197,15 +1247,17 @@ TEST_F(IncrementalMarkingTest, HeapHashMapSwapWeakMemberWeakMember) {
auto* obj2 = MakeGarbageCollected<Object>();
auto* obj3 = MakeGarbageCollected<Object>();
auto* obj4 = MakeGarbageCollected<Object>();
- HeapHashMap<WeakMember<Object>, WeakMember<Object>> map1;
- map1.insert(obj1, obj2);
- HeapHashMap<WeakMember<Object>, WeakMember<Object>> map2;
- map2.insert(obj3, obj4);
+ 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);
+ std::swap(*map1, *map2);
}
}
@@ -1214,15 +1266,17 @@ TEST_F(IncrementalMarkingTest, HeapHashMapSwapMemberWeakMember) {
auto* obj2 = MakeGarbageCollected<Object>();
auto* obj3 = MakeGarbageCollected<Object>();
auto* obj4 = MakeGarbageCollected<Object>();
- HeapHashMap<Member<Object>, WeakMember<Object>> map1;
- map1.insert(obj1, obj2);
- HeapHashMap<Member<Object>, WeakMember<Object>> map2;
- map2.insert(obj3, obj4);
+ 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);
+ std::swap(*map1, *map2);
}
}
@@ -1231,15 +1285,17 @@ TEST_F(IncrementalMarkingTest, HeapHashMapSwapWeakMemberMember) {
auto* obj2 = MakeGarbageCollected<Object>();
auto* obj3 = MakeGarbageCollected<Object>();
auto* obj4 = MakeGarbageCollected<Object>();
- HeapHashMap<WeakMember<Object>, Member<Object>> map1;
- map1.insert(obj1, obj2);
- HeapHashMap<WeakMember<Object>, Member<Object>> map2;
- map2.insert(obj3, obj4);
+ 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);
+ std::swap(*map1, *map2);
}
}
@@ -1415,57 +1471,21 @@ TEST_F(IncrementalMarkingTest, DropBackingStore) {
driver.FinishGC();
}
-TEST_F(IncrementalMarkingTest, WeakCallbackDoesNotReviveDeletedValue) {
- // Regression test: https://crbug.com/870196
-
- // std::pair avoids treating the hashset backing as weak backing.
- using WeakStore = HeapHashCountedSet<std::pair<WeakMember<Object>, size_t>>;
-
- Persistent<WeakStore> persistent(MakeGarbageCollected<WeakStore>());
- // Create at least two entries to avoid completely emptying out the data
- // structure. The values for .second are chosen to be non-null as they
- // would otherwise count as empty and be skipped during iteration after the
- // first part died.
- persistent->insert({MakeGarbageCollected<Object>(), 1});
- persistent->insert({MakeGarbageCollected<Object>(), 2});
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- driver.Start();
- // The backing is not treated as weak backing and thus eagerly processed,
- // effectively registering the slots of WeakMembers.
- driver.FinishSteps();
- // The following deletes the first found entry. The second entry is left
- // untouched.
- for (auto& entries : *persistent) {
- persistent->erase(entries.key);
- break;
- }
- driver.FinishGC();
-
- size_t count = 0;
- for (const auto& entry : *persistent) {
- count++;
- // Use the entry to keep compilers happy.
- if (entry.key.second > 0) {
- }
- }
- CHECK_EQ(1u, count);
-}
-
TEST_F(IncrementalMarkingTest, NoBackingFreeDuringIncrementalMarking) {
// Regression test: https://crbug.com/870306
// Only reproduces in ASAN configurations.
- using WeakStore = HeapHashCountedSet<std::pair<WeakMember<Object>, size_t>>;
+ using WeakStore = HeapHashCountedSet<WeakMember<Object>>;
Persistent<WeakStore> persistent(MakeGarbageCollected<WeakStore>());
- // Prefill the collection to grow backing store. A new backing store allocaton
- // would trigger the write barrier, mitigating the bug where a backing store
- // is promptly freed.
+ // 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>(), i});
+ persistent->insert(MakeGarbageCollected<Object>());
}
IncrementalMarkingTestDriver driver(ThreadState::Current());
driver.Start();
- persistent->insert({MakeGarbageCollected<Object>(), 8});
+ persistent->insert(MakeGarbageCollected<Object>());
// Is not allowed to free the backing store as the previous insert may have
// registered a slot.
persistent->clear();
@@ -1536,8 +1556,9 @@ TEST_F(IncrementalMarkingTest, ConservativeGCWhileCompactionScheduled) {
driver.Start();
driver.FinishSteps();
ThreadState::Current()->CollectGarbage(
- BlinkGC::kHeapPointersOnStack, BlinkGC::kAtomicMarking,
- BlinkGC::kConcurrentAndLazySweeping, BlinkGC::GCReason::kConservativeGC);
+ BlinkGC::CollectionType::kMajor, BlinkGC::kHeapPointersOnStack,
+ BlinkGC::kAtomicMarking, BlinkGC::kConcurrentAndLazySweeping,
+ BlinkGC::GCReason::kConservativeGC);
// Heap compaction should be canceled if incremental marking finishes with a
// conservative GC.
@@ -1792,11 +1813,12 @@ class Destructed final : public GarbageCollected<Destructed> {
size_t Destructed::n_destructed = 0;
-class Wrapper final : public GarbageCollected<Wrapper> {
+class LinkedHashSetWrapper final
+ : public GarbageCollected<LinkedHashSetWrapper> {
public:
using HashType = HeapLinkedHashSet<Member<Destructed>>;
- Wrapper() {
+ LinkedHashSetWrapper() {
for (size_t i = 0; i < 10; ++i) {
hash_set_.insert(MakeGarbageCollected<Destructed>());
}
@@ -1812,7 +1834,7 @@ class Wrapper final : public GarbageCollected<Wrapper> {
HashType hash_set_;
};
-TEST_F(IncrementalMarkingTest, MovingCallback) {
+TEST_F(IncrementalMarkingTest, LinkedHashSetMovingCallback) {
ClearOutOldGarbage();
Destructed::n_destructed = 0;
@@ -1820,14 +1842,15 @@ TEST_F(IncrementalMarkingTest, MovingCallback) {
HeapHashSet<Member<Destructed>> to_be_destroyed;
to_be_destroyed.ReserveCapacityForSize(100);
}
- Persistent<Wrapper> wrapper = MakeGarbageCollected<Wrapper>();
+ 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 backign
+ // Destroy the link between original HeapLinkedHashSet object and its backing
// store.
wrapper->Swap();
DCHECK(wrapper->hash_set_.IsEmpty());
@@ -1837,5 +1860,52 @@ TEST_F(IncrementalMarkingTest, MovingCallback) {
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_verifier.cc b/chromium/third_party/blink/renderer/platform/heap/marking_verifier.cc
index 5e0e7fed6db..eb900719237 100644
--- a/chromium/third_party/blink/renderer/platform/heap/marking_verifier.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/marking_verifier.cc
@@ -14,22 +14,21 @@ void MarkingVerifier::VerifyObject(HeapObjectHeader* header) {
if (header->IsFree() || !header->IsMarked())
return;
- const GCInfo* info =
- GCInfoTable::Get().GCInfoFromIndex(header->GcInfoIndex());
+ const GCInfo& info = GCInfo::From(header->GcInfoIndex());
const bool can_verify =
- !info->has_v_table || blink::VTableInitialized(header->Payload());
+ !info.has_v_table || blink::VTableInitialized(header->Payload());
if (can_verify) {
parent_ = header;
- info->trace(this, header->Payload());
+ info.trace(this, header->Payload());
}
}
-void MarkingVerifier::Visit(void* object, TraceDescriptor desc) {
+void MarkingVerifier::Visit(const void* object, TraceDescriptor desc) {
VerifyChild(object, desc.base_object_payload);
}
-void MarkingVerifier::VisitWeak(void* object,
- void* object_weak_ref,
+void MarkingVerifier::VisitWeak(const void* object,
+ const void* object_weak_ref,
TraceDescriptor desc,
WeakCallback callback) {
// Weak objects should have been cleared at this point. As a consequence, all
@@ -38,8 +37,8 @@ void MarkingVerifier::VisitWeak(void* object,
VerifyChild(object, desc.base_object_payload);
}
-void MarkingVerifier::VisitBackingStoreStrongly(void* object,
- void**,
+void MarkingVerifier::VisitBackingStoreStrongly(const void* object,
+ const void* const*,
TraceDescriptor desc) {
if (!object)
return;
@@ -50,12 +49,12 @@ void MarkingVerifier::VisitBackingStoreStrongly(void* object,
VerifyChild(object, desc.base_object_payload);
}
-void MarkingVerifier::VisitBackingStoreWeakly(void* object,
- void**,
+void MarkingVerifier::VisitBackingStoreWeakly(const void* object,
+ const void* const*,
TraceDescriptor strong_desc,
TraceDescriptor weak_desc,
WeakCallback,
- void*) {
+ const void*) {
if (!object)
return;
@@ -67,7 +66,8 @@ void MarkingVerifier::VisitBackingStoreWeakly(void* object,
VerifyChild(object, weak_desc.base_object_payload);
}
-void MarkingVerifier::VerifyChild(void* object, void* base_object_payload) {
+void MarkingVerifier::VerifyChild(const void* object,
+ const void* base_object_payload) {
CHECK(object);
// Verification may check objects that are currently under construction and
// would require vtable access to figure out their headers. A nullptr in
@@ -82,15 +82,10 @@ void MarkingVerifier::VerifyChild(void* object, void* base_object_payload) {
// ones.
CHECK(child_header);
if (!child_header->IsMarked()) {
- // Pre-finalizers may allocate. In that case the newly allocated objects
- // reside on a page that is not scheduled for sweeping.
- if (PageFromObject(child_header->Payload())->HasBeenSwept())
- return;
-
+ CHECK(!PageFromObject(child_header->Payload())->HasBeenSwept());
LOG(FATAL) << "MarkingVerifier: Encountered unmarked object. " << std::endl
<< std::endl
- << "Hint (use v8_enable_raw_heap_snapshots for better naming): "
- << std::endl
+ << "Hint: " << std::endl
<< parent_->Name() << std::endl
<< "\\-> " << child_header->Name() << std::endl;
}
diff --git a/chromium/third_party/blink/renderer/platform/heap/marking_verifier.h b/chromium/third_party/blink/renderer/platform/heap/marking_verifier.h
index 14e53676d96..495e8dd4c1b 100644
--- a/chromium/third_party/blink/renderer/platform/heap/marking_verifier.h
+++ b/chromium/third_party/blink/renderer/platform/heap/marking_verifier.h
@@ -17,29 +17,31 @@ class MarkingVerifier final : public Visitor {
void VerifyObject(HeapObjectHeader* header);
- void Visit(void* object, TraceDescriptor desc) final;
- void VisitWeak(void* object,
- void* object_weak_ref,
+ void Visit(const void* object, TraceDescriptor desc) final;
+ void VisitWeak(const void* object,
+ const void* object_weak_ref,
TraceDescriptor desc,
WeakCallback callback) final;
- void VisitBackingStoreStrongly(void*, void**, TraceDescriptor) final;
+ void VisitBackingStoreStrongly(const void*,
+ const void* const*,
+ TraceDescriptor) final;
- void VisitBackingStoreWeakly(void*,
- void**,
+ void VisitBackingStoreWeakly(const void*,
+ const void* const*,
TraceDescriptor,
TraceDescriptor,
WeakCallback,
- void*) final;
+ const void*) final;
// Unused overrides.
- void VisitBackingStoreOnly(void*, void**) final {}
- void RegisterBackingStoreCallback(void*, MovingObjectCallback) final {}
- void RegisterWeakCallback(WeakCallback, void*) final {}
+ void VisitBackingStoreOnly(const void*, const void* const*) final {}
+ void RegisterBackingStoreCallback(const void*, MovingObjectCallback) final {}
+ void RegisterWeakCallback(WeakCallback, const void*) final {}
void Visit(const TraceWrapperV8Reference<v8::Value>&) final {}
private:
- void VerifyChild(void* object, void* base_object_payload);
+ void VerifyChild(const void* object, const void* base_object_payload);
HeapObjectHeader* parent_ = nullptr;
};
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 8ed5a880494..d0c5db8b742 100644
--- a/chromium/third_party/blink/renderer/platform/heap/marking_visitor.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/marking_visitor.cc
@@ -10,19 +10,12 @@
namespace blink {
-namespace {
-
-ALWAYS_INLINE bool IsHashTableDeleteValue(const void* value) {
- return value == reinterpret_cast<void*>(-1);
-}
-
-} // namespace
-
MarkingVisitorCommon::MarkingVisitorCommon(ThreadState* state,
MarkingMode marking_mode,
int task_id)
: Visitor(state),
marking_worklist_(Heap().GetMarkingWorklist(), task_id),
+ write_barrier_worklist_(Heap().GetWriteBarrierWorklist(), task_id),
not_fully_constructed_worklist_(Heap().GetNotFullyConstructedWorklist(),
task_id),
weak_callback_worklist_(Heap().GetWeakCallbackWorklist(), task_id),
@@ -35,38 +28,38 @@ MarkingVisitorCommon::MarkingVisitorCommon(ThreadState* state,
task_id_(task_id) {}
void MarkingVisitorCommon::FlushCompactionWorklists() {
+ if (marking_mode_ != kGlobalMarkingWithCompaction)
+ return;
movable_reference_worklist_.FlushToGlobal();
backing_store_callback_worklist_.FlushToGlobal();
}
void MarkingVisitorCommon::RegisterWeakCallback(WeakCallback callback,
- void* object) {
+ const void* object) {
weak_callback_worklist_.Push({callback, object});
}
-void MarkingVisitorCommon::RegisterBackingStoreReference(void** slot) {
+void MarkingVisitorCommon::RegisterBackingStoreReference(
+ const void* const* slot) {
if (marking_mode_ != kGlobalMarkingWithCompaction)
return;
- MovableReference* movable_reference =
- reinterpret_cast<MovableReference*>(slot);
- if (Heap().ShouldRegisterMovingAddress(
- reinterpret_cast<Address>(movable_reference))) {
- movable_reference_worklist_.Push(movable_reference);
+ if (Heap().ShouldRegisterMovingAddress()) {
+ movable_reference_worklist_.Push(slot);
}
}
void MarkingVisitorCommon::RegisterBackingStoreCallback(
- void* backing,
+ const void* backing,
MovingObjectCallback callback) {
if (marking_mode_ != kGlobalMarkingWithCompaction)
return;
- if (Heap().ShouldRegisterMovingAddress(reinterpret_cast<Address>(backing))) {
+ if (Heap().ShouldRegisterMovingAddress()) {
backing_store_callback_worklist_.Push({backing, callback});
}
}
-void MarkingVisitorCommon::VisitWeak(void* object,
- void* object_weak_ref,
+void MarkingVisitorCommon::VisitWeak(const void* object,
+ const void* object_weak_ref,
TraceDescriptor desc,
WeakCallback callback) {
// Filter out already marked values. The write barrier for WeakMember
@@ -79,9 +72,10 @@ void MarkingVisitorCommon::VisitWeak(void* object,
RegisterWeakCallback(callback, object_weak_ref);
}
-void MarkingVisitorCommon::VisitBackingStoreStrongly(void* object,
- void** object_slot,
- TraceDescriptor desc) {
+void MarkingVisitorCommon::VisitBackingStoreStrongly(
+ const void* object,
+ const void* const* object_slot,
+ TraceDescriptor desc) {
RegisterBackingStoreReference(object_slot);
if (!object)
return;
@@ -90,24 +84,30 @@ void MarkingVisitorCommon::VisitBackingStoreStrongly(void* object,
// All work is registered through RegisterWeakCallback.
void MarkingVisitorCommon::VisitBackingStoreWeakly(
- void* object,
- void** object_slot,
+ const void* object,
+ const void* const* object_slot,
TraceDescriptor strong_desc,
TraceDescriptor weak_desc,
WeakCallback weak_callback,
- void* weak_callback_parameter) {
+ const void* weak_callback_parameter) {
RegisterBackingStoreReference(object_slot);
+
+ // In case there's no object present, weakness processing is omitted. The GC
+ // relies on the fact that in such cases touching the weak data structure will
+ // strongify its references.
if (!object)
return;
- RegisterWeakCallback(weak_callback, weak_callback_parameter);
+ // Register final weak processing of the backing store.
+ RegisterWeakCallback(weak_callback, weak_callback_parameter);
+ // Register ephemeron callbacks if necessary.
if (weak_desc.callback)
weak_table_worklist_.Push(weak_desc);
}
bool MarkingVisitorCommon::VisitEphemeronKeyValuePair(
- void* key,
- void* value,
+ const void* key,
+ const void* value,
EphemeronTracingCallback key_trace_callback,
EphemeronTracingCallback value_trace_callback) {
const bool key_is_dead = key_trace_callback(this, key);
@@ -118,8 +118,9 @@ bool MarkingVisitorCommon::VisitEphemeronKeyValuePair(
return false;
}
-void MarkingVisitorCommon::VisitBackingStoreOnly(void* object,
- void** object_slot) {
+void MarkingVisitorCommon::VisitBackingStoreOnly(
+ const void* object,
+ const void* const* object_slot) {
RegisterBackingStoreReference(object_slot);
if (!object)
return;
@@ -129,19 +130,9 @@ void MarkingVisitorCommon::VisitBackingStoreOnly(void* object,
}
// static
-bool MarkingVisitor::WriteBarrierSlow(void* value) {
- if (!value || IsHashTableDeleteValue(value))
- return false;
-
- // It is guaranteed that managed references point to either GarbageCollected
- // or GarbageCollectedMixin. Mixins are restricted to regular objects sizes.
- // It is thus possible to get to the page header by aligning properly.
- BasePage* base_page = PageFromObject(value);
-
- ThreadState* const thread_state = base_page->thread_state();
- if (!thread_state->IsIncrementalMarking())
- return false;
-
+bool MarkingVisitor::MarkValue(void* value,
+ BasePage* base_page,
+ ThreadState* thread_state) {
HeapObjectHeader* header;
if (LIKELY(!base_page->IsLargeObjectPage())) {
header = reinterpret_cast<HeapObjectHeader*>(
@@ -169,7 +160,47 @@ bool MarkingVisitor::WriteBarrierSlow(void* value) {
return true;
}
-void MarkingVisitor::TraceMarkedBackingStoreSlow(void* value) {
+// static
+bool MarkingVisitor::WriteBarrierSlow(void* value) {
+ if (!value || IsHashTableDeleteValue(value))
+ return false;
+
+ // It is guaranteed that managed references point to either GarbageCollected
+ // or GarbageCollectedMixin. Mixins are restricted to regular objects sizes.
+ // It is thus possible to get to the page header by aligning properly.
+ BasePage* base_page = PageFromObject(value);
+
+ ThreadState* const thread_state = base_page->thread_state();
+ if (!thread_state->IsIncrementalMarking())
+ return false;
+
+ return MarkValue(value, base_page, thread_state);
+}
+
+void MarkingVisitor::GenerationalBarrierSlow(Address slot,
+ ThreadState* thread_state) {
+ BasePage* slot_page = thread_state->Heap().LookupPageForAddress(slot);
+ DCHECK(slot_page);
+
+ if (UNLIKELY(slot_page->IsLargeObjectPage())) {
+ auto* large_page = static_cast<LargeObjectPage*>(slot_page);
+ if (UNLIKELY(large_page->ObjectHeader()->IsOld())) {
+ large_page->SetRemembered(true);
+ }
+ return;
+ }
+
+ auto* normal_page = static_cast<NormalPage*>(slot_page);
+ const HeapObjectHeader* source_header = reinterpret_cast<HeapObjectHeader*>(
+ normal_page->object_start_bit_map()->FindHeader(slot));
+ DCHECK_LT(0u, source_header->GcInfoIndex());
+ DCHECK_GT(source_header->PayloadEnd(), slot);
+ if (UNLIKELY(source_header->IsOld())) {
+ normal_page->MarkCard(slot);
+ }
+}
+
+void MarkingVisitor::TraceMarkedBackingStoreSlow(const void* value) {
if (!value)
return;
@@ -183,33 +214,29 @@ void MarkingVisitor::TraceMarkedBackingStoreSlow(void* value) {
DCHECK(thread_state->CurrentVisitor());
// No weak handling for write barriers. Modifying weakly reachable objects
// strongifies them for the current cycle.
- GCInfoTable::Get()
- .GCInfoFromIndex(header->GcInfoIndex())
- ->trace(thread_state->CurrentVisitor(), value);
+
+ GCInfo::From(header->GcInfoIndex())
+ .trace(thread_state->CurrentVisitor(), value);
}
MarkingVisitor::MarkingVisitor(ThreadState* state, MarkingMode marking_mode)
- : MarkingVisitorBase(state, marking_mode, WorklistTaskId::MutatorThread),
- write_barrier_worklist_(Heap().GetWriteBarrierWorklist(),
- WorklistTaskId::MutatorThread) {
+ : MarkingVisitorBase(state, marking_mode, WorklistTaskId::MutatorThread) {
DCHECK(state->InAtomicMarkingPause());
DCHECK(state->CheckThread());
}
-void MarkingVisitor::DynamicallyMarkAddress(Address address) {
+void MarkingVisitor::DynamicallyMarkAddress(ConstAddress address) {
HeapObjectHeader* const header = HeapObjectHeader::FromInnerAddress(address);
DCHECK(header);
DCHECK(!IsInConstruction(header));
- const GCInfo* gc_info =
- GCInfoTable::Get().GCInfoFromIndex(header->GcInfoIndex());
if (MarkHeaderNoTracing(header)) {
- marking_worklist_.Push(
- {reinterpret_cast<void*>(header->Payload()), gc_info->trace});
+ marking_worklist_.Push({reinterpret_cast<void*>(header->Payload()),
+ GCInfo::From(header->GcInfoIndex()).trace});
}
}
void MarkingVisitor::ConservativelyMarkAddress(BasePage* page,
- Address address) {
+ ConstAddress address) {
#if DCHECK_IS_ON()
DCHECK(page->Contains(address));
#endif
@@ -223,10 +250,9 @@ void MarkingVisitor::ConservativelyMarkAddress(BasePage* page,
// Simple case for fully constructed objects. This just adds the object to the
// regular marking worklist.
- const GCInfo* gc_info =
- GCInfoTable::Get().GCInfoFromIndex(header->GcInfoIndex());
if (!IsInConstruction(header)) {
- MarkHeader(header, {header->Payload(), gc_info->trace});
+ MarkHeader(header,
+ {header->Payload(), GCInfo::From(header->GcInfoIndex()).trace});
return;
}
@@ -260,14 +286,18 @@ void MarkingVisitor::ConservativelyMarkAddress(BasePage* page,
AccountMarkedBytes(header);
}
-void MarkingVisitor::FlushMarkingWorklist() {
+void MarkingVisitor::FlushMarkingWorklists() {
marking_worklist_.FlushToGlobal();
+ write_barrier_worklist_.FlushToGlobal();
}
ConcurrentMarkingVisitor::ConcurrentMarkingVisitor(ThreadState* state,
MarkingMode marking_mode,
int task_id)
- : MarkingVisitorBase(state, marking_mode, task_id) {
+ : MarkingVisitorBase(state, marking_mode, task_id),
+ not_safe_to_concurrently_trace_worklist_(
+ Heap().GetNotSafeToConcurrentlyTraceWorklist(),
+ task_id) {
DCHECK(!state->CheckThread());
DCHECK_NE(WorklistTaskId::MutatorThread, task_id);
}
@@ -275,12 +305,16 @@ ConcurrentMarkingVisitor::ConcurrentMarkingVisitor(ThreadState* state,
void ConcurrentMarkingVisitor::FlushWorklists() {
// Flush marking worklists for further marking on the mutator thread.
marking_worklist_.FlushToGlobal();
+ write_barrier_worklist_.FlushToGlobal();
not_fully_constructed_worklist_.FlushToGlobal();
weak_callback_worklist_.FlushToGlobal();
weak_table_worklist_.FlushToGlobal();
+ not_safe_to_concurrently_trace_worklist_.FlushToGlobal();
// Flush compaction worklists.
- movable_reference_worklist_.FlushToGlobal();
- backing_store_callback_worklist_.FlushToGlobal();
+ if (marking_mode_ == kGlobalMarkingWithCompaction) {
+ movable_reference_worklist_.FlushToGlobal();
+ backing_store_callback_worklist_.FlushToGlobal();
+ }
}
} // namespace blink
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 0bb441d6b6a..24ff86413cb 100644
--- a/chromium/third_party/blink/renderer/platform/heap/marking_visitor.h
+++ b/chromium/third_party/blink/renderer/platform/heap/marking_visitor.h
@@ -12,6 +12,14 @@
namespace blink {
+namespace {
+
+ALWAYS_INLINE bool IsHashTableDeleteValue(const void* value) {
+ return value == reinterpret_cast<void*>(-1);
+}
+
+} // namespace
+
class BasePage;
// Base visitor used to mark Oilpan objects on any thread.
@@ -24,23 +32,25 @@ class PLATFORM_EXPORT MarkingVisitorCommon : public Visitor {
kGlobalMarkingWithCompaction,
};
- void VisitWeak(void*, void*, TraceDescriptor, WeakCallback) final;
- void VisitBackingStoreStrongly(void*, void**, TraceDescriptor) final;
- void VisitBackingStoreWeakly(void*,
- void**,
+ void VisitWeak(const void*, const void*, TraceDescriptor, WeakCallback) final;
+ void VisitBackingStoreStrongly(const void*,
+ const void* const*,
+ TraceDescriptor) final;
+ void VisitBackingStoreWeakly(const void*,
+ const void* const*,
TraceDescriptor,
TraceDescriptor,
WeakCallback,
- void*) final;
- bool VisitEphemeronKeyValuePair(void*,
- void*,
+ const void*) final;
+ bool VisitEphemeronKeyValuePair(const void*,
+ const void*,
EphemeronTracingCallback,
EphemeronTracingCallback) final;
// Used to only mark the backing store when it has been registered for weak
// processing. In this case, the contents are processed separately using
// the corresponding traits but the backing store requires marking.
- void VisitBackingStoreOnly(void*, void**) final;
+ void VisitBackingStoreOnly(const void*, const void* const*) final;
// This callback mechanism is needed to account for backing store objects
// containing intra-object pointers, all of which must be relocated/rebased
@@ -48,8 +58,8 @@ class PLATFORM_EXPORT MarkingVisitorCommon : public Visitor {
//
// For Blink, |HeapLinkedHashSet<>| is currently the only abstraction which
// relies on this feature.
- void RegisterBackingStoreCallback(void*, MovingObjectCallback) final;
- void RegisterWeakCallback(WeakCallback, void*) final;
+ void RegisterBackingStoreCallback(const void*, MovingObjectCallback) final;
+ void RegisterWeakCallback(WeakCallback, const void*) final;
// Flush private segments remaining in visitor's worklists to global pools.
void FlushCompactionWorklists();
@@ -71,9 +81,10 @@ class PLATFORM_EXPORT MarkingVisitorCommon : public Visitor {
// marked upon calling.
bool MarkHeaderNoTracing(HeapObjectHeader*);
- void RegisterBackingStoreReference(void** slot);
+ void RegisterBackingStoreReference(const void* const* slot);
MarkingWorklist::View marking_worklist_;
+ WriteBarrierWorklist::View write_barrier_worklist_;
NotFullyConstructedWorklist::View not_fully_constructed_worklist_;
WeakCallbackWorklist::View weak_callback_worklist_;
MovableReferenceWorklist::View movable_reference_worklist_;
@@ -88,7 +99,8 @@ ALWAYS_INLINE void MarkingVisitorCommon::AccountMarkedBytes(
HeapObjectHeader* header) {
marked_bytes_ +=
header->IsLargeObject()
- ? reinterpret_cast<LargeObjectPage*>(PageFromObject(header))->size()
+ ? reinterpret_cast<LargeObjectPage*>(PageFromObject(header))
+ ->ObjectSize()
: header->size();
}
@@ -110,7 +122,7 @@ ALWAYS_INLINE bool MarkingVisitorCommon::MarkHeaderNoTracing(
template <class Specialized>
class PLATFORM_EXPORT MarkingVisitorBase : public MarkingVisitorCommon {
public:
- void Visit(void* object, TraceDescriptor desc) final;
+ void Visit(const void* object, TraceDescriptor desc) final;
// Unused cross-component visit methods.
void Visit(const TraceWrapperV8Reference<v8::Value>&) override {}
@@ -125,7 +137,7 @@ class PLATFORM_EXPORT MarkingVisitorBase : public MarkingVisitorCommon {
};
template <class Specialized>
-inline void MarkingVisitorBase<Specialized>::Visit(void* object,
+inline void MarkingVisitorBase<Specialized>::Visit(const void* object,
TraceDescriptor desc) {
DCHECK(object);
if (desc.base_object_payload == BlinkGC::kNotFullyConstructedObject) {
@@ -161,17 +173,20 @@ class PLATFORM_EXPORT MarkingVisitor
// Returns whether an object is in construction.
static bool IsInConstruction(HeapObjectHeader* header);
- // Write barrier that adds |value| 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 object was marked on this call.
- static bool WriteBarrier(void* value);
+ // 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
// children are discovered by the marker. The barrier bails out if marking
// is off and on individual objects reachable if they are already marked. The
// barrier uses the callback function through GcInfo, so it will not inline
// any templated type-specific code.
- static void TraceMarkedBackingStore(void* value);
+ static void TraceMarkedBackingStore(const void* value);
MarkingVisitor(ThreadState*, MarkingMode);
~MarkingVisitor() override = default;
@@ -179,21 +194,21 @@ class PLATFORM_EXPORT MarkingVisitor
// Conservatively marks an object if pointed to by Address. The object may
// be in construction as the scan is conservative without relying on a
// Trace method.
- void ConservativelyMarkAddress(BasePage*, Address);
+ 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(Address);
+ void DynamicallyMarkAddress(ConstAddress);
- void FlushMarkingWorklist();
+ void FlushMarkingWorklists();
private:
- // Exact version of the marking write barriers.
+ // Exact version of the marking and generational write barriers.
static bool WriteBarrierSlow(void*);
- static void TraceMarkedBackingStoreSlow(void*);
-
- WriteBarrierWorklist::View write_barrier_worklist_;
+ static void GenerationalBarrierSlow(Address, ThreadState*);
+ static bool MarkValue(void*, BasePage*, ThreadState*);
+ static void TraceMarkedBackingStoreSlow(const void*);
};
// static
@@ -204,17 +219,45 @@ ALWAYS_INLINE bool MarkingVisitor::IsInConstruction(HeapObjectHeader* header) {
}
// static
-ALWAYS_INLINE bool MarkingVisitor::WriteBarrier(void* value) {
+template <typename T>
+ALWAYS_INLINE bool MarkingVisitor::WriteBarrier(T** slot) {
+#if BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
+ void* value = *slot;
+ if (!value || IsHashTableDeleteValue(value))
+ return false;
+
+ // Dijkstra barrier if concurrent marking is in progress.
+ BasePage* value_page = PageFromObject(value);
+ ThreadState* thread_state = value_page->thread_state();
+
+ if (UNLIKELY(thread_state->IsIncrementalMarking()))
+ return MarkValue(value, value_page, thread_state);
+
+ GenerationalBarrier(reinterpret_cast<Address>(slot), thread_state);
+ return false;
+#else
if (!ThreadState::IsAnyIncrementalMarking())
return false;
// Avoid any further checks and dispatch to a call at this point. Aggressive
// inlining otherwise pollutes the regular execution paths.
- return WriteBarrierSlow(value);
+ return WriteBarrierSlow(*slot);
+#endif
}
// static
-ALWAYS_INLINE void MarkingVisitor::TraceMarkedBackingStore(void* value) {
+ALWAYS_INLINE void MarkingVisitor::GenerationalBarrier(Address slot,
+ ThreadState* state) {
+ // First, check if the source object is in the last allocated region of heap.
+ if (LIKELY(state->Heap().IsInLastAllocatedRegion(slot)))
+ return;
+ if (UNLIKELY(state->IsOnStack(slot)))
+ return;
+ GenerationalBarrierSlow(slot, state);
+}
+
+// static
+ALWAYS_INLINE void MarkingVisitor::TraceMarkedBackingStore(const void* value) {
if (!ThreadState::IsAnyIncrementalMarking())
return;
@@ -234,8 +277,30 @@ class PLATFORM_EXPORT ConcurrentMarkingVisitor
~ConcurrentMarkingVisitor() override = default;
virtual void FlushWorklists();
+
+ // Concurrent variant of MarkingVisitorCommon::AccountMarkedBytes.
+ void AccountMarkedBytesSafe(HeapObjectHeader*);
+
+ bool IsConcurrent() const override { return true; }
+
+ bool ConcurrentTracingBailOut(TraceDescriptor desc) override {
+ not_safe_to_concurrently_trace_worklist_.Push(desc);
+ return true;
+ }
+
+ private:
+ NotSafeToConcurrentlyTraceWorklist::View
+ not_safe_to_concurrently_trace_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) {
diff --git a/chromium/third_party/blink/renderer/platform/heap/member.h b/chromium/third_party/blink/renderer/platform/heap/member.h
index 6c6f324271f..1610b12d7f2 100644
--- a/chromium/third_party/blink/renderer/platform/heap/member.h
+++ b/chromium/third_party/blink/renderer/platform/heap/member.h
@@ -113,21 +113,21 @@ class MemberBase {
MemberBase(const MemberBase& other) : raw_(other) {
SaveCreationThreadState();
CheckPointer();
- WriteBarrier();
+ // No write barrier for initializing stores.
}
template <typename U>
MemberBase(const Persistent<U>& other) : raw_(other) {
SaveCreationThreadState();
CheckPointer();
- WriteBarrier();
+ // No write barrier for initializing stores.
}
template <typename U>
MemberBase(const MemberBase<U>& other) : raw_(other) {
SaveCreationThreadState();
CheckPointer();
- WriteBarrier();
+ // No write barrier for initializing stores.
}
template <typename U>
@@ -195,16 +195,37 @@ class MemberBase {
return result;
}
+ static bool IsMemberHashTableDeletedValue(const T* t) {
+ return t == reinterpret_cast<T*>(kHashTableDeletedRawValue);
+ }
+
bool IsHashTableDeletedValue() const {
- return GetRaw() == reinterpret_cast<T*>(kHashTableDeletedRawValue);
+ return IsMemberHashTableDeletedValue(GetRaw());
}
protected:
static constexpr intptr_t kHashTableDeletedRawValue = -1;
+ enum class AtomicCtorTag { Atomic };
+
+ // MemberBase ctors that use atomic write to set raw_.
+
+ MemberBase(AtomicCtorTag, T* raw) {
+ SetRaw(raw);
+ SaveCreationThreadState();
+ CheckPointer();
+ // No write barrier for initializing stores.
+ }
+
+ MemberBase(AtomicCtorTag, T& raw) {
+ SetRaw(&raw);
+ SaveCreationThreadState();
+ CheckPointer();
+ // No write barrier for initializing stores.
+ }
+
void WriteBarrier() const {
- MarkingVisitor::WriteBarrier(
- const_cast<typename std::remove_const<T>::type*>(GetRaw()));
+ MarkingVisitor::WriteBarrier(const_cast<std::remove_const_t<T>**>(&raw_));
}
void CheckPointer() {
@@ -224,10 +245,7 @@ class MemberBase {
}
ALWAYS_INLINE void SetRaw(T* raw) {
- // TOOD(omerkatz): replace this cast with std::atomic_ref (C++20) once it
- // becomes available
- reinterpret_cast<std::atomic<T*>*>(&raw_)->store(raw,
- std::memory_order_relaxed);
+ WTF::AsAtomicPtr(&raw_)->store(raw, std::memory_order_relaxed);
}
ALWAYS_INLINE T* GetRaw() const { return raw_; }
@@ -235,17 +253,10 @@ class MemberBase {
// Thread safe version of Get() for marking visitors.
// This is used to prevent data races between concurrent marking visitors
// and writes on the main thread.
- T* GetSafe() const {
+ const T* GetSafe() const {
// TOOD(omerkatz): replace this cast with std::atomic_ref (C++20) once it
// becomes available
- return reinterpret_cast<std::atomic<T*>*>(
- const_cast<typename std::remove_const<T>::type**>(&raw_))
- ->load(std::memory_order_relaxed);
- }
-
- // Thread safe version of IsHashTableDeletedValue for use while tracing.
- bool IsHashTableDeletedValueSafe() const {
- return GetSafe() == reinterpret_cast<T*>(kHashTableDeletedRawValue);
+ return WTF::AsAtomicPtr(&raw_)->load(std::memory_order_relaxed);
}
T* raw_;
@@ -321,7 +332,11 @@ class Member : public MemberBase<T, TracenessMemberConfiguration::kTraced> {
return *this;
}
- protected:
+ private:
+ using typename Parent::AtomicCtorTag;
+ Member(AtomicCtorTag atomic, T* raw) : Parent(atomic, raw) {}
+ Member(AtomicCtorTag atomic, T& raw) : Parent(atomic, raw) {}
+
template <typename P, typename Traits, typename Allocator>
friend class WTF::ConstructTraits;
};
@@ -404,6 +419,12 @@ class UntracedMember final
UntracedMember(WTF::HashTableDeletedValueType x) : Parent(x) {}
+ UntracedMember& operator=(const UntracedMember& other) {
+ this->SetRaw(other);
+ this->CheckPointer();
+ return *this;
+ }
+
template <typename U>
UntracedMember& operator=(const Persistent<U>& other) {
this->SetRaw(other);
@@ -500,7 +521,12 @@ class ConstructTraits<blink::Member<T>, Traits, Allocator> {
template <typename... Args>
static blink::Member<T>* ConstructAndNotifyElement(void* location,
Args&&... args) {
- blink::Member<T>* object = Construct(location, std::forward<Args>(args)...);
+ // ConstructAndNotifyElement updates an existing Member which might
+ // also be comncurrently traced while we update it. The regular ctors
+ // for Member don't use an atomic write which can lead to data races.
+ blink::Member<T>* object =
+ Construct(location, blink::Member<T>::AtomicCtorTag::Atomic,
+ std::forward<Args>(args)...);
NotifyNewElement(object);
return object;
}
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
new file mode 100644
index 00000000000..c30e976d294
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/minor_gc_test.cc
@@ -0,0 +1,295 @@
+// 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/page_memory.cc b/chromium/third_party/blink/renderer/platform/heap/page_memory.cc
index c94a5866657..6552456eebc 100644
--- a/chromium/third_party/blink/renderer/platform/heap/page_memory.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/page_memory.cc
@@ -56,7 +56,8 @@ void PageMemoryRegion::PageDeleted(Address page) {
// we should probably have a way to distinguish physical memory OOM from
// virtual address space OOM.
static NOINLINE void BlinkGCOutOfMemory() {
- OOM_CRASH();
+ // TODO(lizeb): Add the real allocation size here as well.
+ OOM_CRASH(0);
}
PageMemoryRegion* PageMemoryRegion::Allocate(size_t size,
@@ -72,7 +73,7 @@ PageMemoryRegion* PageMemoryRegion::Allocate(size_t size,
return new PageMemoryRegion(base, size, num_pages, region_tree);
}
-PageMemoryRegion* RegionTree::Lookup(Address address) {
+PageMemoryRegion* RegionTree::Lookup(ConstAddress address) {
auto it = set_.upper_bound(address);
// This check also covers set_.size() > 0, since for empty vectors it is
// guaranteed that begin() == end().
diff --git a/chromium/third_party/blink/renderer/platform/heap/page_memory.h b/chromium/third_party/blink/renderer/platform/heap/page_memory.h
index 40884d69b93..249a1eb668c 100644
--- a/chromium/third_party/blink/renderer/platform/heap/page_memory.h
+++ b/chromium/third_party/blink/renderer/platform/heap/page_memory.h
@@ -24,7 +24,7 @@ class MemoryRegion {
DCHECK_GT(size, 0u);
}
- bool Contains(Address addr) const {
+ bool Contains(ConstAddress addr) const {
return base_ <= addr && addr < (base_ + size_);
}
@@ -73,7 +73,7 @@ class PageMemoryRegion : public MemoryRegion {
region_tree);
}
- BasePage* PageFromAddress(Address address) {
+ BasePage* PageFromAddress(ConstAddress address) {
DCHECK(Contains(address));
if (!in_use_[Index(address)])
return nullptr;
@@ -85,11 +85,11 @@ class PageMemoryRegion : public MemoryRegion {
private:
PageMemoryRegion(Address base, size_t, unsigned num_pages, RegionTree*);
- unsigned Index(Address address) const {
+ unsigned Index(ConstAddress address) const {
DCHECK(Contains(address));
if (is_large_page_)
return 0;
- size_t offset = BlinkPageAddress(address) - Base();
+ size_t offset = BlinkPageAddress(const_cast<Address>(address)) - Base();
DCHECK_EQ(offset % kBlinkPageSize, 0u);
return static_cast<unsigned>(offset / kBlinkPageSize);
}
@@ -112,12 +112,12 @@ class RegionTree {
public:
void Add(PageMemoryRegion*);
void Remove(PageMemoryRegion*);
- PageMemoryRegion* Lookup(Address);
+ PageMemoryRegion* Lookup(ConstAddress);
private:
// Using flat_map allows to improve locality to minimize cache misses and
// balance binary lookup.
- base::flat_map<Address, PageMemoryRegion*> set_;
+ base::flat_map<ConstAddress, PageMemoryRegion*> set_;
};
// Representation of the memory used for a Blink heap page.
diff --git a/chromium/third_party/blink/renderer/platform/heap/persistent.h b/chromium/third_party/blink/renderer/platform/heap/persistent.h
index 0b098c10186..fdc613835af 100644
--- a/chromium/third_party/blink/renderer/platform/heap/persistent.h
+++ b/chromium/third_party/blink/renderer/platform/heap/persistent.h
@@ -39,10 +39,16 @@ class PersistentLocation final {
base::Location location_;
};
-#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
+#if !BUILDFLAG(FROM_HERE_USES_LOCATION_BUILTINS) && \
+ BUILDFLAG(RAW_HEAP_SNAPSHOTS)
+#if !BUILDFLAG(ENABLE_LOCATION_SOURCE)
+#define PERSISTENT_FROM_HERE \
+ PersistentLocation(::base::Location::CreateFromHere(__FILE__))
+#else
#define PERSISTENT_FROM_HERE \
PersistentLocation( \
::base::Location::CreateFromHere(__func__, __FILE__, __LINE__))
+#endif
#else
#define PERSISTENT_FROM_HERE PersistentLocation()
#endif // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
@@ -298,7 +304,7 @@ class PersistentBase {
UninitializeUnsafe();
}
- void TracePersistent(Visitor* visitor) {
+ void TracePersistent(Visitor* visitor) const {
static_assert(sizeof(T), "T must be fully defined");
static_assert(IsGarbageCollectedType<T>::value,
"T needs to be a garbage collected object");
@@ -385,11 +391,12 @@ class PersistentBase {
}
static void HandleWeakPersistent(const WeakCallbackInfo&,
- void* persistent_pointer) {
+ const void* persistent_pointer) {
using Base =
PersistentBase<typename std::remove_const<T>::type,
weaknessConfiguration, crossThreadnessConfiguration>;
- Base* persistent = reinterpret_cast<Base*>(persistent_pointer);
+ Base* persistent =
+ reinterpret_cast<Base*>(const_cast<void*>(persistent_pointer));
T* object = persistent->Get();
if (object && !ThreadHeap::IsHeapObjectAlive(object))
ClearWeakPersistent(persistent);
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 a0a6bb8c996..1449205eeb5 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(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
};
}
diff --git a/chromium/third_party/blink/renderer/platform/heap/persistent_node.h b/chromium/third_party/blink/renderer/platform/heap/persistent_node.h
index bc76a0174b1..b591db1e793 100644
--- a/chromium/third_party/blink/renderer/platform/heap/persistent_node.h
+++ b/chromium/third_party/blink/renderer/platform/heap/persistent_node.h
@@ -74,7 +74,7 @@ class PersistentNode final {
// Instead we call the constructor with a TraceCallback which knows the
// type of the most specific child and calls trace directly. See
// TraceMethodDelegate in Visitor.h for how this is done.
- void TracePersistentNode(Visitor* visitor) {
+ void TracePersistentNode(Visitor* visitor) const {
DCHECK(!IsUnused());
DCHECK(trace_);
trace_(visitor, self_);
diff --git a/chromium/third_party/blink/renderer/platform/heap/persistent_test.cc b/chromium/third_party/blink/renderer/platform/heap/persistent_test.cc
index bc30d02baba..474509cd185 100644
--- a/chromium/third_party/blink/renderer/platform/heap/persistent_test.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/persistent_test.cc
@@ -21,7 +21,7 @@ class Receiver : public GarbageCollected<Receiver> {
public:
void Increment(int* counter) { ++*counter; }
- void Trace(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
};
TEST_F(PersistentTest, BindCancellation) {
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 27c2a8b8d19..477223077e2 100644
--- a/chromium/third_party/blink/renderer/platform/heap/thread_state.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/thread_state.cc
@@ -109,7 +109,7 @@ constexpr base::TimeDelta kConcurrentMarkingStepDuration =
//
// TODO(omerkatz): kNumberOfMarkingTasks should be set heuristically
// instead of a constant.
-constexpr uint8_t kNumberOfConcurrentMarkingTasks = 1u;
+constexpr uint8_t kNumberOfConcurrentMarkingTasks = 3u;
constexpr size_t kMaxTerminationGCLoops = 20;
@@ -127,8 +127,6 @@ class WorkerPoolTaskRunner : public base::TaskRunner {
worker_pool::PostTask(location, WTF::CrossThreadBindOnce(std::move(task)));
return true;
}
-
- bool RunsTasksInCurrentSequence() const override { return false; }
};
} // namespace
@@ -147,6 +145,11 @@ class ThreadState::IncrementalMarkingScheduler {
ScheduleTask();
}
+ void Restart() {
+ DCHECK(!task_.IsActive());
+ ScheduleTask();
+ }
+
// Cancels incremental marking task in case there is any pending.
void Cancel() { task_.Cancel(); }
@@ -169,16 +172,15 @@ class ThreadState::IncrementalMarkingScheduler {
void Dispatch() {
switch (thread_state_->GetGCState()) {
- case ThreadState::kIncrementalGCScheduled:
- thread_state_->IncrementalMarkingStart(reason_);
- ScheduleTask();
- break;
case ThreadState::kIncrementalMarkingStepScheduled:
thread_state_->IncrementalMarkingStep(
BlinkGC::kNoHeapPointersOnStack,
next_incremental_marking_step_duration_);
UpdateIncrementalMarkingStepDuration();
- ScheduleTask();
+ if (thread_state_->GetGCState() !=
+ ThreadState::kIncrementalMarkingStepPaused) {
+ ScheduleTask();
+ }
break;
case ThreadState::kIncrementalMarkingFinalizeScheduled:
thread_state_->IncrementalMarkingFinalize();
@@ -221,8 +223,6 @@ ThreadState::ThreadState()
incremental_marking_scheduler_(
std::make_unique<IncrementalMarkingScheduler>(this)),
marker_scheduler_(std::make_unique<CancelableTaskScheduler>(
- base::MakeRefCounted<WorkerPoolTaskRunner>())),
- sweeper_scheduler_(std::make_unique<CancelableTaskScheduler>(
base::MakeRefCounted<WorkerPoolTaskRunner>())) {
DCHECK(CheckThread());
DCHECK(!**thread_specific_);
@@ -265,6 +265,7 @@ void ThreadState::AttachToIsolate(
v8_build_embedder_graph_ = v8_build_embedder_graph;
unified_heap_controller_.reset(new UnifiedHeapController(this));
isolate_->SetEmbedderHeapTracer(unified_heap_controller_.get());
+ unified_heap_controller_.get()->SetStackStart(WTF::GetStackStart());
if (v8::HeapProfiler* profiler = isolate->GetHeapProfiler()) {
profiler->AddBuildEmbedderGraphCallback(v8_build_embedder_graph, nullptr);
}
@@ -288,7 +289,8 @@ void ThreadState::RunTerminationGC() {
DCHECK(!IsMainThread());
DCHECK(CheckThread());
- FinishIncrementalMarkingIfRunning(BlinkGC::kNoHeapPointersOnStack,
+ FinishIncrementalMarkingIfRunning(BlinkGC::CollectionType::kMajor,
+ BlinkGC::kNoHeapPointersOnStack,
BlinkGC::kIncrementalAndConcurrentMarking,
BlinkGC::kConcurrentAndLazySweeping,
BlinkGC::GCReason::kThreadTerminationGC);
@@ -309,7 +311,8 @@ void ThreadState::RunTerminationGC() {
int current_count = GetPersistentRegion()->NodesInUse();
DCHECK_GE(current_count, 0);
while (current_count != old_count) {
- CollectGarbage(BlinkGC::kNoHeapPointersOnStack, BlinkGC::kAtomicMarking,
+ CollectGarbage(BlinkGC::CollectionType::kMajor,
+ BlinkGC::kNoHeapPointersOnStack, BlinkGC::kAtomicMarking,
BlinkGC::kEagerSweeping,
BlinkGC::GCReason::kThreadTerminationGC);
// Release the thread-local static persistents that were
@@ -328,7 +331,8 @@ void ThreadState::RunTerminationGC() {
i < kMaxTerminationGCLoops && GetPersistentRegion()->NodesInUse();
i++) {
GetPersistentRegion()->PrepareForThreadStateTermination(this);
- CollectGarbage(BlinkGC::kNoHeapPointersOnStack, BlinkGC::kAtomicMarking,
+ CollectGarbage(BlinkGC::CollectionType::kMajor,
+ BlinkGC::kNoHeapPointersOnStack, BlinkGC::kAtomicMarking,
BlinkGC::kEagerSweeping,
BlinkGC::GCReason::kThreadTerminationGC);
}
@@ -375,7 +379,9 @@ void ThreadState::VisitAsanFakeStackForPointer(MarkingVisitor* visitor,
NO_SANITIZE_ADDRESS
NO_SANITIZE_HWADDRESS
NO_SANITIZE_THREAD
-void ThreadState::VisitStack(MarkingVisitor* visitor, Address* end_of_stack) {
+void ThreadState::VisitStackImpl(MarkingVisitor* visitor,
+ Address* start_of_stack,
+ Address* end_of_stack) {
DCHECK_EQ(current_gc_data_.stack_state, BlinkGC::kHeapPointersOnStack);
// Ensure that current is aligned by address size otherwise the loop below
@@ -383,7 +389,7 @@ void ThreadState::VisitStack(MarkingVisitor* visitor, Address* end_of_stack) {
Address* current = reinterpret_cast<Address*>(
reinterpret_cast<intptr_t>(end_of_stack) & ~(sizeof(Address) - 1));
- for (; current < start_of_stack_; ++current) {
+ for (; current < start_of_stack; ++current) {
Address ptr = *current;
#if defined(MEMORY_SANITIZER)
// |ptr| may be uninitialized by design. Mark it as initialized to keep
@@ -394,10 +400,22 @@ void ThreadState::VisitStack(MarkingVisitor* visitor, Address* end_of_stack) {
__msan_unpoison(&ptr, sizeof(ptr));
#endif
heap_->CheckAndMarkPointer(visitor, ptr);
- VisitAsanFakeStackForPointer(visitor, ptr, start_of_stack_, end_of_stack);
+ VisitAsanFakeStackForPointer(visitor, ptr, start_of_stack, end_of_stack);
}
}
+void ThreadState::VisitStack(MarkingVisitor* visitor, Address* end_of_stack) {
+ VisitStackImpl(visitor, start_of_stack_, end_of_stack);
+}
+
+void ThreadState::VisitUnsafeStack(MarkingVisitor* visitor) {
+#if HAS_FEATURE(safe_stack)
+ VisitStackImpl(visitor,
+ static_cast<Address*>(__builtin___get_unsafe_stack_top()),
+ static_cast<Address*>(__builtin___get_unsafe_stack_ptr()));
+#endif // HAS_FEATURE(safe_stack)
+}
+
void ThreadState::VisitDOMWrappers(Visitor* visitor) {
if (v8_trace_roots_) {
ThreadHeapStatsCollector::Scope stats_scope(
@@ -424,6 +442,12 @@ void ThreadState::VisitPersistents(Visitor* visitor) {
}
}
+void ThreadState::VisitRememberedSets(MarkingVisitor* visitor) {
+ ThreadHeapStatsCollector::EnabledScope stats_scope(
+ Heap().stats_collector(), ThreadHeapStatsCollector::kVisitRememberedSets);
+ Heap().VisitRememberedSets(visitor);
+}
+
void ThreadState::VisitWeakPersistents(Visitor* visitor) {
ProcessHeap::GetCrossThreadWeakPersistentRegion().TraceNodes(visitor);
weak_persistent_region_->TraceNodes(visitor);
@@ -503,8 +527,7 @@ void ThreadState::PerformIdleLazySweep(base::TimeTicks deadline) {
ThreadHeapStatsCollector::EnabledScope stats_scope(
Heap().stats_collector(), ThreadHeapStatsCollector::kLazySweepInIdle,
"idleDeltaInSeconds", (deadline - base::TimeTicks::Now()).InSecondsF());
- sweep_completed =
- Heap().AdvanceSweep(ThreadHeap::SweepingType::kMutator, deadline);
+ sweep_completed = Heap().AdvanceLazySweep(deadline);
// We couldn't finish the sweeping within the deadline.
// We request another idle task for the remaining sweeping.
if (sweep_completed) {
@@ -519,28 +542,15 @@ void ThreadState::PerformIdleLazySweep(base::TimeTicks deadline) {
}
}
-void ThreadState::PerformConcurrentSweep() {
+void ThreadState::PerformConcurrentSweep(base::JobDelegate* job) {
VLOG(2) << "[state:" << this << "] [threadid:" << CurrentThread() << "] "
<< "ConcurrentSweep";
- // As opposed to PerformIdleLazySweep, this function doesn't receive deadline
- // from the scheduler, but defines it itself.
- static constexpr base::TimeDelta kConcurrentSweepStepDuration =
- base::TimeDelta::FromMilliseconds(2);
- // Concurrent sweeper doesn't call finalizers - this guarantees that sweeping
- // is not called recursively.
ThreadHeapStatsCollector::EnabledConcurrentScope stats_scope(
- Heap().stats_collector(), ThreadHeapStatsCollector::kConcurrentSweep);
- const bool finished = Heap().AdvanceSweep(
- ThreadHeap::SweepingType::kConcurrent,
- base::TimeTicks::Now() + kConcurrentSweepStepDuration);
- if (!finished) {
- // Reschedule itself. It is safe even if the task timeouts and reposts
- // itself while the mutator thread is waiting on CancelAndWait(). The
- // mutator thread will simply wake up and cancel the newly post task itself.
- sweeper_scheduler_->ScheduleTask(
- WTF::CrossThreadBindOnce(&ThreadState::PerformConcurrentSweep,
- WTF::CrossThreadUnretained(this)));
- }
+ Heap().stats_collector(),
+ ThreadHeapStatsCollector::kConcurrentSweepingStep);
+
+ if (Heap().AdvanceConcurrentSweep(job))
+ has_unswept_pages_.store(false, std::memory_order_relaxed);
}
void ThreadState::StartIncrementalMarking(BlinkGC::GCReason reason) {
@@ -570,13 +580,21 @@ void ThreadState::ScheduleConcurrentAndLazySweep() {
return;
}
- static constexpr size_t kNumberOfSweepingTasks = 1u;
-
- for (size_t i = 0; i < kNumberOfSweepingTasks; ++i) {
- sweeper_scheduler_->ScheduleTask(
- WTF::CrossThreadBindOnce(&ThreadState::PerformConcurrentSweep,
- WTF::CrossThreadUnretained(this)));
- }
+ has_unswept_pages_ = true;
+ sweeper_handle_ = base::PostJob(
+ FROM_HERE,
+ {base::TaskPriority::USER_VISIBLE,
+ base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
+ ConvertToBaseRepeatingCallback(
+ WTF::CrossThreadBindRepeating(&ThreadState::PerformConcurrentSweep,
+ WTF::CrossThreadUnretained(this))),
+ ConvertToBaseRepeatingCallback(WTF::CrossThreadBindRepeating(
+ [](ThreadState* state) -> size_t {
+ return state->has_unswept_pages_.load(std::memory_order_relaxed)
+ ? 1
+ : 0;
+ },
+ WTF::CrossThreadUnretained(this))));
}
void ThreadState::SchedulePreciseGC() {
@@ -628,7 +646,8 @@ void ThreadState::SetGCState(GCState gc_state) {
DCHECK(CheckThread());
VERIFY_STATE_TRANSITION(gc_state_ == kNoGCScheduled ||
gc_state_ == kIncrementalMarkingStepScheduled ||
- gc_state_ == kIncrementalGCScheduled);
+ gc_state_ == kIncrementalGCScheduled ||
+ gc_state_ == kIncrementalMarkingStepPaused);
break;
case kIncrementalMarkingFinalizeScheduled:
DCHECK(CheckThread());
@@ -700,7 +719,8 @@ void ThreadState::RunScheduledGC(BlinkGC::StackState stack_state) {
CollectAllGarbageForTesting();
break;
case kPreciseGCScheduled:
- CollectGarbage(BlinkGC::kNoHeapPointersOnStack, BlinkGC::kAtomicMarking,
+ CollectGarbage(BlinkGC::CollectionType::kMajor,
+ BlinkGC::kNoHeapPointersOnStack, BlinkGC::kAtomicMarking,
BlinkGC::kConcurrentAndLazySweeping,
BlinkGC::GCReason::kPreciseGC);
break;
@@ -709,9 +729,11 @@ void ThreadState::RunScheduledGC(BlinkGC::StackState stack_state) {
}
}
-void ThreadState::AtomicPauseMarkPrologue(BlinkGC::StackState stack_state,
- BlinkGC::MarkingType marking_type,
- BlinkGC::GCReason reason) {
+void ThreadState::AtomicPauseMarkPrologue(
+ BlinkGC::CollectionType collection_type,
+ BlinkGC::StackState stack_state,
+ BlinkGC::MarkingType marking_type,
+ BlinkGC::GCReason reason) {
ThreadHeapStatsCollector::EnabledScope mark_prologue_scope(
Heap().stats_collector(),
ThreadHeapStatsCollector::kAtomicPauseMarkPrologue, "epoch", gc_age_,
@@ -719,10 +741,10 @@ void ThreadState::AtomicPauseMarkPrologue(BlinkGC::StackState stack_state,
EnterAtomicPause();
EnterNoAllocationScope();
EnterGCForbiddenScope();
- // Compaction needs to be canceled when incremental marking ends with a
- // conservative GC.
- if (stack_state == BlinkGC::kHeapPointersOnStack)
- Heap().Compaction()->Cancel();
+
+ if (HeapPointersOnStackForced()) {
+ stack_state = BlinkGC::kHeapPointersOnStack;
+ }
if (IsMarkingInProgress()) {
// Incremental marking is already in progress. Only update the state
@@ -736,18 +758,26 @@ void ThreadState::AtomicPauseMarkPrologue(BlinkGC::StackState stack_state,
available_concurrent_marking_task_ids_.clear();
}
#if DCHECK_IS_ON()
- MarkingWorklist* worklist = Heap().GetMarkingWorklist();
+ MarkingWorklist* marking_worklist = Heap().GetMarkingWorklist();
+ WriteBarrierWorklist* write_barrier_worklist =
+ Heap().GetWriteBarrierWorklist();
for (int concurrent_task = WorklistTaskId::ConcurrentThreadBase;
- concurrent_task < worklist->num_tasks(); ++concurrent_task) {
- DCHECK(worklist->IsLocalEmpty(concurrent_task));
+ concurrent_task < MarkingWorklist::kNumTasks; ++concurrent_task) {
+ DCHECK(marking_worklist->IsLocalEmpty(concurrent_task));
+ DCHECK(write_barrier_worklist->IsLocalEmpty(concurrent_task));
}
#endif // DCHECK_IS_ON()
+ // Compaction needs to be canceled when incremental marking ends with a
+ // conservative GC.
+ if (stack_state == BlinkGC::kHeapPointersOnStack)
+ Heap().Compaction()->Cancel();
DisableIncrementalMarkingBarrier();
current_gc_data_.reason = reason;
current_gc_data_.stack_state = stack_state;
Heap().stats_collector()->UpdateReason(reason);
} else {
- MarkPhasePrologue(stack_state, marking_type, reason);
+ DCHECK(!Heap().Compaction()->IsCompacting());
+ MarkPhasePrologue(collection_type, stack_state, marking_type, reason);
}
if (stack_state == BlinkGC::kNoHeapPointersOnStack) {
@@ -776,7 +806,7 @@ void ThreadState::CompleteSweep() {
if (!IsSweepingInProgress())
return;
- // completeSweep() can be called recursively if finalizers can allocate
+ // CompleteSweep() can be called recursively if finalizers can allocate
// memory and the allocation triggers completeSweep(). This check prevents
// the sweeping from being executed recursively.
if (SweepForbidden())
@@ -794,6 +824,10 @@ void ThreadState::CompleteSweep() {
ThreadHeapStatsCollector::EnabledScope stats_scope(
Heap().stats_collector(), ThreadHeapStatsCollector::kCompleteSweep,
"forced", IsForcedGC(current_gc_data_.reason));
+ // Boost priority of sweeping job to complete ASAP and avoid taking time on
+ // the main thread.
+ if (sweeper_handle_)
+ sweeper_handle_.UpdatePriority(base::TaskPriority::USER_BLOCKING);
Heap().CompleteSweep();
SynchronizeAndFinishConcurrentSweeping();
@@ -809,7 +843,8 @@ void ThreadState::SynchronizeAndFinishConcurrentSweeping() {
DCHECK(SweepForbidden());
// Wait for concurrent sweepers.
- sweeper_scheduler_->CancelAndWait();
+ if (sweeper_handle_)
+ sweeper_handle_.Cancel();
// Concurrent sweepers may perform some work at the last stage (e.g.
// sweeping the last page and preparing finalizers).
@@ -890,6 +925,8 @@ void UpdateHistograms(const ThreadHeapStatsCollector::Event& event) {
UMA_HISTOGRAM_TIMES("BlinkGC.TimeForAtomicPhaseMarking",
event.atomic_marking_time());
UMA_HISTOGRAM_TIMES("BlinkGC.TimeForGCCycle", event.gc_cycle_time());
+ UMA_HISTOGRAM_TIMES("BlinkGC.TimeForMarkingRoots",
+ event.roots_marking_time());
UMA_HISTOGRAM_TIMES("BlinkGC.TimeForIncrementalMarking",
event.incremental_marking_time());
UMA_HISTOGRAM_TIMES("BlinkGC.TimeForMarking.Foreground",
@@ -916,15 +953,14 @@ void UpdateHistograms(const ThreadHeapStatsCollector::Event& event) {
"BlinkGC.TimeForGlobalWeakProcessing",
event.scope_data[ThreadHeapStatsCollector::kMarkWeakProcessing]);
- base::TimeDelta marking_duration = event.marking_time();
- constexpr size_t kMinObjectSizeForReportingThroughput = 1024 * 1024;
+ base::TimeDelta marking_duration = event.foreground_marking_time();
+ constexpr size_t kMinMarkedBytesForReportingThroughput = 1024 * 1024;
if (base::TimeTicks::IsHighResolution() &&
- (event.object_size_in_bytes_before_sweeping >
- kMinObjectSizeForReportingThroughput) &&
+ (event.marked_bytes > kMinMarkedBytesForReportingThroughput) &&
!marking_duration.is_zero()) {
DCHECK_GT(marking_duration.InMillisecondsF(), 0.0);
const int main_thread_marking_throughput_mb_per_s = static_cast<int>(
- static_cast<double>(event.object_size_in_bytes_before_sweeping) /
+ static_cast<double>(event.marked_bytes) /
marking_duration.InMillisecondsF() * 1000 / 1024 / 1024);
UMA_HISTOGRAM_COUNTS_100000("BlinkGC.MainThreadMarkingThroughput",
main_thread_marking_throughput_mb_per_s);
@@ -933,8 +969,10 @@ void UpdateHistograms(const ThreadHeapStatsCollector::Event& event) {
DEFINE_STATIC_LOCAL(
CustomCountHistogram, object_size_freed_by_heap_compaction,
("BlinkGC.ObjectSizeFreedByHeapCompaction", 1, 4 * 1024 * 1024, 50));
- object_size_freed_by_heap_compaction.Count(
- CappedSizeInKB(event.compaction_freed_bytes));
+ if (event.compaction_recorded_events) {
+ object_size_freed_by_heap_compaction.Count(
+ CappedSizeInKB(event.compaction_freed_bytes));
+ }
DEFINE_STATIC_LOCAL(CustomCountHistogram, object_size_before_gc_histogram,
("BlinkGC.ObjectSizeBeforeGC", 1, 4 * 1024 * 1024, 50));
@@ -1024,7 +1062,10 @@ void ThreadState::PushRegistersAndVisitStack() {
DCHECK(CheckThread());
DCHECK(IsGCForbidden());
DCHECK_EQ(current_gc_data_.stack_state, BlinkGC::kHeapPointersOnStack);
+ // Visit registers, native stack, and asan fake stack.
PushAllRegisters(this, ThreadState::VisitStackAfterPushingRegisters);
+ // For builds that use safe stack, also visit the unsafe stack.
+ VisitUnsafeStack(static_cast<MarkingVisitor*>(CurrentVisitor()));
}
void ThreadState::AddObserver(BlinkGCObserver* observer) {
@@ -1077,21 +1118,6 @@ void ThreadState::FreePersistentNode(PersistentRegion* persistent_region,
DCHECK(!static_persistents_.Contains(persistent_node));
}
-void ThreadState::RegisterPreFinalizer(void* object,
- PreFinalizerCallback callback) {
-#if DCHECK_IS_ON()
- DCHECK(CheckThread());
-#endif
- DCHECK(!SweepForbidden());
-
- HeapObjectHeader* header = HeapObjectHeader::FromInnerAddress(object);
- DCHECK(ordered_pre_finalizers_.end() ==
- std::find(ordered_pre_finalizers_.begin(),
- ordered_pre_finalizers_.end(),
- PreFinalizer{header, object, callback}));
- ordered_pre_finalizers_.push_back(PreFinalizer{header, object, callback});
-}
-
void ThreadState::InvokePreFinalizers() {
DCHECK(CheckThread());
DCHECK(!SweepForbidden());
@@ -1099,22 +1125,23 @@ void ThreadState::InvokePreFinalizers() {
ThreadHeapStatsCollector::Scope stats_scope(
Heap().stats_collector(), ThreadHeapStatsCollector::kInvokePreFinalizers);
SweepForbiddenScope sweep_forbidden(this);
- // Pre finalizers are forbidden from allocating objects.
+ // Pre finalizers are forbidden from allocating objects
NoAllocationScope no_allocation_scope(this);
// Call the prefinalizers in the opposite order to their registration.
+ //
+ // Deque does not support modification during iteration, so
+ // copy items first.
+ //
+ // The prefinalizer callback wrapper returns |true| when its associated
+ // object is unreachable garbage and the prefinalizer callback has run.
+ // The registered prefinalizer entry must then be removed and deleted.
Deque<PreFinalizer> remaining_ordered_pre_finalizers;
for (auto rit = ordered_pre_finalizers_.rbegin();
rit != ordered_pre_finalizers_.rend(); ++rit) {
const PreFinalizer& pre_finalizer = *rit;
- // Check if pre-finalizer should be executed.
- if (pre_finalizer.header->IsMarked()) {
- // Re-queue for checking in next garbage collection.
+ if (!(pre_finalizer.second)(pre_finalizer.first))
remaining_ordered_pre_finalizers.push_front(pre_finalizer);
- } else {
- // Execute pre-finalizer.
- pre_finalizer.callback(pre_finalizer.object);
- }
}
ordered_pre_finalizers_ = std::move(remaining_ordered_pre_finalizers);
@@ -1151,7 +1178,8 @@ void ThreadState::IncrementalMarkingStart(BlinkGC::GCReason reason) {
DCHECK(!IsMarkingInProgress());
// Sweeping is performed in driver functions.
DCHECK(!IsSweepingInProgress());
- Heap().stats_collector()->NotifyMarkingStarted(reason);
+ Heap().stats_collector()->NotifyMarkingStarted(
+ BlinkGC::CollectionType::kMajor, reason);
{
ThreadHeapStatsCollector::EnabledScope stats_scope(
Heap().stats_collector(),
@@ -1159,7 +1187,8 @@ void ThreadState::IncrementalMarkingStart(BlinkGC::GCReason reason) {
BlinkGC::ToString(reason));
AtomicPauseScope atomic_pause_scope(this);
ScriptForbiddenScope script_forbidden_scope;
- MarkPhasePrologue(BlinkGC::kNoHeapPointersOnStack,
+ MarkPhasePrologue(BlinkGC::CollectionType::kMajor,
+ BlinkGC::kNoHeapPointersOnStack,
BlinkGC::kIncrementalAndConcurrentMarking, reason);
{
MutexLocker persistent_lock(ProcessHeap::CrossThreadPersistentMutex());
@@ -1172,14 +1201,19 @@ void ThreadState::IncrementalMarkingStart(BlinkGC::GCReason reason) {
// 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->FlushMarkingWorklist();
+ current_gc_data_.visitor->FlushMarkingWorklists();
// Check that the marking worklist has enough private segments for all
// concurrent marking tasks.
const uint8_t max_concurrent_task_id =
WorklistTaskId::ConcurrentThreadBase +
kNumberOfConcurrentMarkingTasks;
- DCHECK_LE(max_concurrent_task_id,
- Heap().GetMarkingWorklist()->num_tasks());
+ static_assert(
+ MarkingWorklist::kNumTasks == WriteBarrierWorklist::kNumTasks,
+ "Marking worklist and write-barrier worklist should be the "
+ "same size");
+ static_assert(max_concurrent_task_id <= MarkingWorklist::kNumTasks,
+ "Number of concurrent marking tasks should not exceed "
+ "number of tasks in worlkist");
// Initialize concurrent marking task ids.
for (uint8_t i = WorklistTaskId::ConcurrentThreadBase;
i < max_concurrent_task_id; ++i) {
@@ -1218,7 +1252,7 @@ void ThreadState::IncrementalMarkingStep(BlinkGC::StackState stack_state,
if (base::FeatureList::IsEnabled(
blink::features::kBlinkHeapConcurrentMarking)) {
- complete = complete && ConcurrentMarkingStep();
+ complete = ConcurrentMarkingStep() && complete;
}
if (complete) {
@@ -1239,8 +1273,8 @@ void ThreadState::IncrementalMarkingStep(BlinkGC::StackState stack_state,
}
bool ThreadState::ConcurrentMarkingStep() {
- current_gc_data_.visitor->FlushMarkingWorklist();
- if (!Heap().GetMarkingWorklist()->IsGlobalPoolEmpty()) {
+ current_gc_data_.visitor->FlushMarkingWorklists();
+ if (Heap().HasWorkForConcurrentMarking()) {
ScheduleConcurrentMarking();
return false;
}
@@ -1263,11 +1297,13 @@ void ThreadState::IncrementalMarkingFinalize() {
// UMA accounting and allow follow up GCs if necessary.
DCHECK_EQ(BlinkGC::kIncrementalAndConcurrentMarking,
current_gc_data_.marking_type);
- CollectGarbage(BlinkGC::kNoHeapPointersOnStack, current_gc_data_.marking_type,
+ CollectGarbage(current_gc_data_.collection_type,
+ BlinkGC::kNoHeapPointersOnStack, current_gc_data_.marking_type,
BlinkGC::kConcurrentAndLazySweeping, current_gc_data_.reason);
}
bool ThreadState::FinishIncrementalMarkingIfRunning(
+ BlinkGC::CollectionType collection_type,
BlinkGC::StackState stack_state,
BlinkGC::MarkingType marking_type,
BlinkGC::SweepingType sweeping_type,
@@ -1279,14 +1315,23 @@ bool ThreadState::FinishIncrementalMarkingIfRunning(
if (IsUnifiedGCMarkingInProgress()) {
unified_heap_controller()->FinalizeTracing();
} else {
- RunAtomicPause(stack_state, marking_type, sweeping_type, reason);
+ RunAtomicPause(collection_type, stack_state, marking_type, sweeping_type,
+ reason);
}
return true;
}
return false;
}
-void ThreadState::CollectGarbage(BlinkGC::StackState stack_state,
+void ThreadState::RestartIncrementalMarkingIfPaused() {
+ if (GetGCState() != ThreadState::kIncrementalMarkingStepPaused)
+ return;
+ SetGCState(ThreadState::kIncrementalMarkingStepScheduled);
+ incremental_marking_scheduler_->Restart();
+}
+
+void ThreadState::CollectGarbage(BlinkGC::CollectionType collection_type,
+ BlinkGC::StackState stack_state,
BlinkGC::MarkingType marking_type,
BlinkGC::SweepingType sweeping_type,
BlinkGC::GCReason reason) {
@@ -1302,7 +1347,7 @@ void ThreadState::CollectGarbage(BlinkGC::StackState stack_state,
GetIsolate(), RuntimeCallStats::CounterId::kCollectGarbage);
const bool was_incremental_marking = FinishIncrementalMarkingIfRunning(
- stack_state, marking_type, sweeping_type, reason);
+ collection_type, stack_state, marking_type, sweeping_type, reason);
// We don't want floating garbage for the specific garbage collection types
// mentioned below. In this case we will follow up with a regular full
@@ -1315,8 +1360,9 @@ void ThreadState::CollectGarbage(BlinkGC::StackState stack_state,
if (should_do_full_gc) {
CompleteSweep();
SetGCState(kNoGCScheduled);
- Heap().stats_collector()->NotifyMarkingStarted(reason);
- RunAtomicPause(stack_state, marking_type, sweeping_type, reason);
+ Heap().stats_collector()->NotifyMarkingStarted(collection_type, reason);
+ RunAtomicPause(collection_type, stack_state, marking_type, sweeping_type,
+ reason);
}
const base::TimeDelta total_collect_garbage_time =
@@ -1423,6 +1469,7 @@ class ClearReferencesInDeadObjectsVisitor final
} // namespace
void ThreadState::AtomicPauseSweepAndCompact(
+ BlinkGC::CollectionType collection_type,
BlinkGC::MarkingType marking_type,
BlinkGC::SweepingType sweeping_type) {
ThreadHeapStatsCollector::EnabledScope stats(
@@ -1434,7 +1481,7 @@ void ThreadState::AtomicPauseSweepAndCompact(
DCHECK(InAtomicMarkingPause());
DCHECK(CheckThread());
- Heap().PrepareForSweep();
+ Heap().PrepareForSweep(collection_type);
// We have to set the GCPhase to Sweeping before calling pre-finalizers
// to disallow a GC during the pre-finalizers.
@@ -1449,14 +1496,11 @@ void ThreadState::AtomicPauseSweepAndCompact(
unified_heap_controller()->IterateTracedGlobalHandles(&visitor);
}
- // Allocation is allowed during the pre-finalizers and destructors.
- // However, they must not mutate an object graph in a way in which
- // a dead object gets resurrected.
InvokePreFinalizers();
- // Slots filtering requires liveness information which is only present before
- // sweeping any arena.
- {
+ if (collection_type == BlinkGC::CollectionType::kMajor) {
+ // Slots filtering requires liveness information which is only present
+ // before sweeping any arena.
ThreadHeapStatsCollector::Scope stats_scope(
Heap().stats_collector(),
ThreadHeapStatsCollector::kAtomicPauseCompaction);
@@ -1467,14 +1511,14 @@ void ThreadState::AtomicPauseSweepAndCompact(
// Last point where all mark bits are present.
VerifyMarking(marking_type);
- // Any sweep compaction must happen after pre-finalizers, as it will
- // finalize dead objects in compactable arenas (e.g., backing stores
- // for container objects.)
- //
- // As per-contract for prefinalizers, those finalizable objects must
- // still be accessible when the prefinalizer runs, hence we cannot
- // schedule compaction until those have run.
- {
+ if (collection_type == BlinkGC::CollectionType::kMajor) {
+ // Any sweep compaction must happen after pre-finalizers, as it will
+ // finalize dead objects in compactable arenas (e.g., backing stores
+ // for container objects.)
+ //
+ // As per-contract for prefinalizers, those finalizable objects must
+ // still be accessible when the prefinalizer runs, hence we cannot
+ // schedule compaction until those have run.
SweepForbiddenScope scope(this);
NoAllocationScope no_allocation_scope(this);
Heap().Compact();
@@ -1573,7 +1617,8 @@ void ThreadState::PoisonUnmarkedObjects() {
}
#endif // ADDRESS_SANITIZER
-void ThreadState::RunAtomicPause(BlinkGC::StackState stack_state,
+void ThreadState::RunAtomicPause(BlinkGC::CollectionType collection_type,
+ BlinkGC::StackState stack_state,
BlinkGC::MarkingType marking_type,
BlinkGC::SweepingType sweeping_type,
BlinkGC::GCReason reason) {
@@ -1582,11 +1627,11 @@ void ThreadState::RunAtomicPause(BlinkGC::StackState stack_state,
TRACE_EVENT1("blink_gc,devtools.timeline", "BlinkGC.AtomicPhase", "forced",
IsForcedGC(reason));
- AtomicPauseMarkPrologue(stack_state, marking_type, reason);
+ AtomicPauseMarkPrologue(collection_type, stack_state, marking_type, reason);
AtomicPauseMarkRoots(stack_state, marking_type, reason);
AtomicPauseMarkTransitiveClosure();
AtomicPauseMarkEpilogue(marking_type);
- AtomicPauseSweepAndCompact(marking_type, sweeping_type);
+ AtomicPauseSweepAndCompact(collection_type, marking_type, sweeping_type);
AtomicPauseEpilogue();
}
@@ -1599,19 +1644,30 @@ MarkingVisitor::MarkingMode GetMarkingMode(bool should_compact) {
} // namespace
-void ThreadState::MarkPhasePrologue(BlinkGC::StackState stack_state,
+void ThreadState::MarkPhasePrologue(BlinkGC::CollectionType collection_type,
+ BlinkGC::StackState stack_state,
BlinkGC::MarkingType marking_type,
BlinkGC::GCReason reason) {
SetGCPhase(GCPhase::kMarking);
- Heap().SetupWorklists();
const bool compaction_enabled =
Heap().Compaction()->ShouldCompact(stack_state, marking_type, reason);
+
+ Heap().SetupWorklists(compaction_enabled);
+
if (compaction_enabled) {
Heap().Compaction()->Initialize(this);
}
+#if BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
+ if (collection_type == BlinkGC::CollectionType::kMajor) {
+ // Unmark heap before doing major collection cycle.
+ Heap().Unmark();
+ }
+#endif
+
current_gc_data_.reason = reason;
+ current_gc_data_.collection_type = collection_type;
current_gc_data_.visitor =
IsUnifiedGCMarkingInProgress()
? std::make_unique<UnifiedHeapMarkingVisitor>(
@@ -1623,6 +1679,9 @@ void ThreadState::MarkPhasePrologue(BlinkGC::StackState stack_state,
}
void ThreadState::MarkPhaseVisitRoots() {
+ ThreadHeapStatsCollector::EnabledScope stats_scope(
+ Heap().stats_collector(), ThreadHeapStatsCollector::kVisitRoots);
+
Visitor* visitor = current_gc_data_.visitor.get();
VisitPersistents(visitor);
@@ -1644,10 +1703,15 @@ void ThreadState::MarkPhaseVisitRoots() {
}
if (current_gc_data_.stack_state == BlinkGC::kHeapPointersOnStack) {
- ThreadHeapStatsCollector::Scope stats_scope(
+ ThreadHeapStatsCollector::Scope stack_stats_scope(
Heap().stats_collector(), ThreadHeapStatsCollector::kVisitStackRoots);
PushRegistersAndVisitStack();
}
+
+ // Visit remembered sets (card tables) for minor collections.
+ if (current_gc_data_.collection_type == BlinkGC::CollectionType::kMinor) {
+ VisitRememberedSets(static_cast<MarkingVisitor*>(visitor));
+ }
}
bool ThreadState::MarkPhaseAdvanceMarking(base::TimeTicks deadline) {
@@ -1710,8 +1774,8 @@ void ThreadState::CollectAllGarbageForTesting(BlinkGC::StackState stack_state) {
// We need to run multiple GCs to collect a chain of persistent handles.
size_t previous_live_objects = 0;
for (int i = 0; i < 5; ++i) {
- CollectGarbage(stack_state, BlinkGC::kAtomicMarking,
- BlinkGC::kEagerSweeping,
+ CollectGarbage(BlinkGC::CollectionType::kMajor, stack_state,
+ BlinkGC::kAtomicMarking, BlinkGC::kEagerSweeping,
BlinkGC::GCReason::kForcedGCForTesting);
const size_t live_objects =
Heap().stats_collector()->previous().marked_bytes;
@@ -1743,7 +1807,8 @@ void ThreadState::PerformConcurrentMark() {
VLOG(2) << "[state:" << this << "] [threadid:" << CurrentThread() << "] "
<< "ConcurrentMark";
ThreadHeapStatsCollector::EnabledConcurrentScope stats_scope(
- Heap().stats_collector(), ThreadHeapStatsCollector::kConcurrentMark);
+ Heap().stats_collector(),
+ ThreadHeapStatsCollector::kConcurrentMarkingStep);
uint8_t task_id;
{
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 42b55d95df5..f41cd050868 100644
--- a/chromium/third_party/blink/renderer/platform/heap/thread_state.h
+++ b/chromium/third_party/blink/renderer/platform/heap/thread_state.h
@@ -31,10 +31,12 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREAD_STATE_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREAD_STATE_H_
+#include <atomic>
#include <memory>
#include "base/macros.h"
#include "base/synchronization/lock.h"
+#include "base/task/post_job.h"
#include "third_party/blink/renderer/platform/heap/atomic_entry_flag.h"
#include "third_party/blink/renderer/platform/heap/blink_gc.h"
#include "third_party/blink/renderer/platform/heap/threading_traits.h"
@@ -62,7 +64,6 @@ class IncrementalMarkingScope;
} // namespace incremental_marking_test
class CancelableTaskScheduler;
-class HeapObjectHeader;
class MarkingVisitor;
class PersistentNode;
class PersistentRegion;
@@ -94,13 +95,17 @@ class Visitor;
// Member<Bar> bar_;
// };
#define USING_PRE_FINALIZER(Class, preFinalizer) \
- private: \
- static void PreFinalizerDispatch(void* object) { \
- reinterpret_cast<Class*>(object)->Class::preFinalizer(); \
+ public: \
+ static bool InvokePreFinalizer(void* object) { \
+ Class* self = reinterpret_cast<Class*>(object); \
+ if (ThreadHeap::IsHeapObjectAlive(self)) \
+ return false; \
+ self->Class::preFinalizer(); \
+ return true; \
} \
\
- friend class ThreadState::PreFinalizerRegistration<Class>; \
- ThreadState::PreFinalizerRegistration<Class> prefinalizer_dummy_{this}; \
+ private: \
+ ThreadState::PrefinalizerRegistration<Class> prefinalizer_dummy_{this}; \
using UsingPreFinalizerMacroNeedsTrailingSemiColon = char
class PLATFORM_EXPORT BlinkGCObserver {
@@ -130,16 +135,24 @@ class PLATFORM_EXPORT ThreadState final {
// Register the pre-finalizer for the |self| object. The class T be using
// USING_PRE_FINALIZER() macro.
template <typename T>
- class PreFinalizerRegistration final {
+ class PrefinalizerRegistration final {
DISALLOW_NEW();
public:
- PreFinalizerRegistration(T* self) {
- static_assert(sizeof(&T::PreFinalizerDispatch) > 0,
+ PrefinalizerRegistration(T* self) {
+ static_assert(sizeof(&T::InvokePreFinalizer) > 0,
"USING_PRE_FINALIZER(T) must be defined.");
ThreadState* state =
ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
- state->RegisterPreFinalizer(self, T::PreFinalizerDispatch);
+#if DCHECK_IS_ON()
+ DCHECK(state->CheckThread());
+#endif
+ DCHECK(!state->SweepForbidden());
+ DCHECK(std::find(state->ordered_pre_finalizers_.begin(),
+ state->ordered_pre_finalizers_.end(),
+ PreFinalizer(self, T::InvokePreFinalizer)) ==
+ state->ordered_pre_finalizers_.end());
+ state->ordered_pre_finalizers_.emplace_back(self, T::InvokePreFinalizer);
}
};
@@ -169,11 +182,11 @@ class PLATFORM_EXPORT ThreadState final {
class AtomicPauseScope;
class GCForbiddenScope;
class LsanDisabledScope;
- class MainThreadGCForbiddenScope;
class NoAllocationScope;
class StatisticsCollector;
struct Statistics;
class SweepForbiddenScope;
+ class HeapPointersOnStackScope;
using V8TraceRootsCallback = void (*)(v8::Isolate*, Visitor*);
using V8BuildEmbedderGraphCallback = void (*)(v8::Isolate*,
@@ -240,7 +253,7 @@ class PLATFORM_EXPORT ThreadState final {
}
void PerformIdleLazySweep(base::TimeTicks deadline);
- void PerformConcurrentSweep();
+ void PerformConcurrentSweep(base::JobDelegate*);
void SchedulePreciseGC();
void ScheduleForcedGCForTesting();
@@ -279,7 +292,8 @@ class PLATFORM_EXPORT ThreadState final {
void EnableCompactionForNextGCForTesting();
- bool FinishIncrementalMarkingIfRunning(BlinkGC::StackState,
+ bool FinishIncrementalMarkingIfRunning(BlinkGC::CollectionType,
+ BlinkGC::StackState,
BlinkGC::MarkingType,
BlinkGC::SweepingType,
BlinkGC::GCReason);
@@ -287,6 +301,8 @@ class PLATFORM_EXPORT ThreadState final {
void EnableIncrementalMarkingBarrier();
void DisableIncrementalMarkingBarrier();
+ void RestartIncrementalMarkingIfPaused();
+
void CompleteSweep();
// Returns whether it is currently allowed to allocate an object. Mainly used
@@ -335,7 +351,8 @@ class PLATFORM_EXPORT ThreadState final {
v8::Isolate* GetIsolate() const { return isolate_; }
// Use CollectAllGarbageForTesting below for testing!
- void CollectGarbage(BlinkGC::StackState,
+ void CollectGarbage(BlinkGC::CollectionType,
+ BlinkGC::StackState,
BlinkGC::MarkingType,
BlinkGC::SweepingType,
BlinkGC::GCReason);
@@ -354,6 +371,12 @@ class PLATFORM_EXPORT ThreadState final {
return &FromObject(object)->Heap() == &Heap();
}
+ ALWAYS_INLINE bool IsOnStack(Address address) const {
+ return reinterpret_cast<Address>(start_of_stack_) >= address &&
+ address >= (reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(
+ WTF::GetCurrentStackPosition())));
+ }
+
int GcAge() const { return gc_age_; }
MarkingVisitor* CurrentVisitor() const {
@@ -366,17 +389,6 @@ class PLATFORM_EXPORT ThreadState final {
private:
class IncrementalMarkingScheduler;
- using PreFinalizerCallback = void (*)(void*);
- struct PreFinalizer {
- HeapObjectHeader* header;
- void* object;
- PreFinalizerCallback callback;
-
- bool operator==(const PreFinalizer& other) const {
- return object == other.object && callback == other.callback;
- }
- };
-
// 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 =
@@ -428,7 +440,8 @@ class PLATFORM_EXPORT ThreadState final {
// The following methods are used to compose RunAtomicPause. Public users
// should use the CollectGarbage entrypoint. Internal users should use these
// methods to compose a full garbage collection.
- void AtomicPauseMarkPrologue(BlinkGC::StackState,
+ void AtomicPauseMarkPrologue(BlinkGC::CollectionType,
+ BlinkGC::StackState,
BlinkGC::MarkingType,
BlinkGC::GCReason);
void AtomicPauseMarkRoots(BlinkGC::StackState,
@@ -436,20 +449,23 @@ class PLATFORM_EXPORT ThreadState final {
BlinkGC::GCReason);
void AtomicPauseMarkTransitiveClosure();
void AtomicPauseMarkEpilogue(BlinkGC::MarkingType);
- void AtomicPauseSweepAndCompact(BlinkGC::MarkingType marking_type,
+ void AtomicPauseSweepAndCompact(BlinkGC::CollectionType,
+ BlinkGC::MarkingType marking_type,
BlinkGC::SweepingType sweeping_type);
void AtomicPauseEpilogue();
// RunAtomicPause composes the final atomic pause that finishes a mark-compact
// phase of a garbage collection. Depending on SweepingType it may also finish
// sweeping or schedule lazy/concurrent sweeping.
- void RunAtomicPause(BlinkGC::StackState,
+ void RunAtomicPause(BlinkGC::CollectionType,
+ BlinkGC::StackState,
BlinkGC::MarkingType,
BlinkGC::SweepingType,
BlinkGC::GCReason);
// The version is needed to be able to start incremental marking.
- void MarkPhasePrologue(BlinkGC::StackState,
+ void MarkPhasePrologue(BlinkGC::CollectionType,
+ BlinkGC::StackState,
BlinkGC::MarkingType,
BlinkGC::GCReason);
void MarkPhaseEpilogue(BlinkGC::MarkingType);
@@ -463,7 +479,9 @@ class PLATFORM_EXPORT ThreadState final {
// Visit local thread stack and trace all pointers conservatively. Never call
// directly but always call through |PushRegistersAndVisitStack|.
+ void VisitStackImpl(MarkingVisitor*, Address*, Address*);
void VisitStack(MarkingVisitor*, Address*);
+ void VisitUnsafeStack(MarkingVisitor*);
// Visit the asan fake stack frame corresponding to a slot on the real machine
// stack if there is one. Never call directly but always call through
@@ -482,6 +500,9 @@ class PLATFORM_EXPORT ThreadState final {
// Visit all DOM wrappers allocatd on this thread.
void VisitDOMWrappers(Visitor*);
+ // Visit card tables (remembered sets) containing inter-generational pointers.
+ void VisitRememberedSets(MarkingVisitor*);
+
// Incremental marking implementation functions.
void IncrementalMarkingStartForTesting();
void IncrementalMarkingStart(BlinkGC::GCReason);
@@ -513,7 +534,6 @@ class PLATFORM_EXPORT ThreadState final {
void SynchronizeAndFinishConcurrentSweeping();
- void RegisterPreFinalizer(void*, PreFinalizerCallback);
void InvokePreFinalizers();
// Adds the given observer to the ThreadState's observer list. This doesn't
@@ -531,6 +551,13 @@ class PLATFORM_EXPORT ThreadState final {
reason == BlinkGC::GCReason::kForcedGCForTesting;
}
+ // Returns whether stack scanning is forced. This is currently only used in
+ // platform tests where non nested tasks can be run with heap pointers on
+ // stack.
+ bool HeapPointersOnStackForced() const {
+ return heap_pointers_on_stack_forced_;
+ }
+
#if defined(ADDRESS_SANITIZER)
// Poisons payload of unmarked objects.
//
@@ -551,6 +578,7 @@ class PLATFORM_EXPORT ThreadState final {
bool in_atomic_pause_ = false;
bool sweep_forbidden_ = false;
+ bool heap_pointers_on_stack_forced_ = false;
bool incremental_marking_ = false;
bool should_optimize_for_load_time_ = false;
size_t no_allocation_count_ = 0;
@@ -562,6 +590,9 @@ class PLATFORM_EXPORT ThreadState final {
BlinkGC::GCReason reason_for_scheduled_gc_ =
BlinkGC::GCReason::kForcedGCForTesting;
+ using PreFinalizerCallback = bool (*)(void*);
+ using PreFinalizer = std::pair<void*, PreFinalizerCallback>;
+
// Pre-finalizers are called in the reverse order in which they are
// registered by the constructors (including constructors of Mixin objects)
// for an object, by processing the ordered_pre_finalizers_ back-to-front.
@@ -587,6 +618,7 @@ class PLATFORM_EXPORT ThreadState final {
int gc_age_ = 0;
struct GCData {
+ BlinkGC::CollectionType collection_type;
BlinkGC::StackState stack_state;
BlinkGC::MarkingType marking_type;
BlinkGC::GCReason reason;
@@ -602,14 +634,15 @@ class PLATFORM_EXPORT ThreadState final {
base::Lock concurrent_marker_bootstrapping_lock_;
size_t concurrently_marked_bytes_ = 0;
- std::unique_ptr<CancelableTaskScheduler> sweeper_scheduler_;
+ base::JobHandle sweeper_handle_;
+ std::atomic_bool has_unswept_pages_{false};
friend class BlinkGCObserver;
friend class incremental_marking_test::IncrementalMarkingScope;
friend class IncrementalMarkingTestDriver;
friend class HeapAllocator;
template <typename T>
- friend class PreFinalizerRegistration;
+ friend class PrefinalizerRegistration;
friend class TestGCScope;
friend class TestSupportingGC;
friend class ThreadStateSchedulingTest;
diff --git a/chromium/third_party/blink/renderer/platform/heap/thread_state_scopes.h b/chromium/third_party/blink/renderer/platform/heap/thread_state_scopes.h
index 0dea83fe654..bde958dc4ad 100644
--- a/chromium/third_party/blink/renderer/platform/heap/thread_state_scopes.h
+++ b/chromium/third_party/blink/renderer/platform/heap/thread_state_scopes.h
@@ -47,19 +47,6 @@ class ThreadState::SweepForbiddenScope final {
ThreadState* const state_;
};
-class ThreadState::MainThreadGCForbiddenScope final {
- STACK_ALLOCATED();
-
- public:
- MainThreadGCForbiddenScope() : thread_state_(ThreadState::MainThreadState()) {
- thread_state_->EnterGCForbiddenScope();
- }
- ~MainThreadGCForbiddenScope() { thread_state_->LeaveGCForbiddenScope(); }
-
- private:
- ThreadState* const thread_state_;
-};
-
class ThreadState::GCForbiddenScope final {
STACK_ALLOCATED();
@@ -90,6 +77,23 @@ class ThreadState::AtomicPauseScope final {
GCForbiddenScope gc_forbidden_scope;
};
+class ThreadState::HeapPointersOnStackScope final {
+ STACK_ALLOCATED();
+
+ public:
+ explicit HeapPointersOnStackScope(ThreadState* state) : state_(state) {
+ DCHECK(!state_->heap_pointers_on_stack_forced_);
+ state_->heap_pointers_on_stack_forced_ = true;
+ }
+ ~HeapPointersOnStackScope() {
+ DCHECK(state_->heap_pointers_on_stack_forced_);
+ state_->heap_pointers_on_stack_forced_ = false;
+ }
+
+ private:
+ ThreadState* const state_;
+};
+
#if defined(LEAK_SANITIZER)
class ThreadState::LsanDisabledScope final {
STACK_ALLOCATED();
diff --git a/chromium/third_party/blink/renderer/platform/heap/threading_traits.h b/chromium/third_party/blink/renderer/platform/heap/threading_traits.h
index 3c5579ff1f7..95fa0c7e20a 100644
--- a/chromium/third_party/blink/renderer/platform/heap/threading_traits.h
+++ b/chromium/third_party/blink/renderer/platform/heap/threading_traits.h
@@ -32,7 +32,7 @@ enum ThreadAffinity {
// Remove them.
class Node;
class NodeList;
-class NodeRareDataBase;
+class NodeRareData;
template <
typename T,
@@ -40,7 +40,7 @@ template <
WTF::IsSubclass<typename std::remove_const<T>::type, Node>::value ||
WTF::IsSubclass<typename std::remove_const<T>::type, NodeList>::value ||
WTF::IsSubclass<typename std::remove_const<T>::type,
- NodeRareDataBase>::value>
+ NodeRareData>::value>
struct DefaultThreadingTrait;
template <typename T>
@@ -56,10 +56,6 @@ struct DefaultThreadingTrait<T, true> {
};
class HeapAllocator;
-template <typename Table>
-class HeapHashTableBacking;
-template <typename T, typename Traits>
-class HeapVectorBacking;
template <typename T>
class Member;
template <typename T>
@@ -118,12 +114,6 @@ struct ThreadingTrait<Vector<T, inlineCapacity, HeapAllocator>> {
static const ThreadAffinity kAffinity = ThreadingTrait<T>::kAffinity;
};
-template <typename T, typename Traits>
-struct ThreadingTrait<HeapVectorBacking<T, Traits>> {
- STATIC_ONLY(ThreadingTrait);
- static const ThreadAffinity kAffinity = ThreadingTrait<T>::Affinity;
-};
-
template <typename T, size_t inlineCapacity>
struct ThreadingTrait<Deque<T, inlineCapacity, HeapAllocator>> {
STATIC_ONLY(ThreadingTrait);
@@ -136,25 +126,13 @@ struct ThreadingTrait<HashCountedSet<T, U, V, HeapAllocator>> {
static const ThreadAffinity kAffinity = ThreadingTrait<T>::kAffinity;
};
-template <typename Table>
-struct ThreadingTrait<HeapHashTableBacking<Table>> {
- STATIC_ONLY(ThreadingTrait);
- using Key = typename Table::KeyType;
- using Value = typename Table::ValueType;
- static const ThreadAffinity kAffinity =
- (ThreadingTrait<Key>::Affinity == kMainThreadOnly) &&
- (ThreadingTrait<Value>::Affinity == kMainThreadOnly)
- ? kMainThreadOnly
- : kAnyThread;
-};
-
template <typename T, typename U, typename V, typename W, typename X>
class HeapHashMap;
template <typename T, typename U, typename V>
class HeapHashSet;
template <typename T, wtf_size_t inlineCapacity>
class HeapVector;
-template <typename T, wtf_size_t inlineCapacity>
+template <typename T>
class HeapDeque;
template <typename T, typename U, typename V>
class HeapHashCountedSet;
@@ -174,9 +152,9 @@ struct ThreadingTrait<HeapVector<T, inlineCapacity>>
: public ThreadingTrait<Vector<T, inlineCapacity, HeapAllocator>> {
STATIC_ONLY(ThreadingTrait);
};
-template <typename T, size_t inlineCapacity>
-struct ThreadingTrait<HeapDeque<T, inlineCapacity>>
- : public ThreadingTrait<Deque<T, inlineCapacity, HeapAllocator>> {
+template <typename T>
+struct ThreadingTrait<HeapDeque<T>>
+ : public ThreadingTrait<Deque<T, 0, HeapAllocator>> {
STATIC_ONLY(ThreadingTrait);
};
template <typename T, typename U, typename V>
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 583aa7f78d3..4333dbf1edb 100644
--- a/chromium/third_party/blink/renderer/platform/heap/trace_traits.h
+++ b/chromium/third_party/blink/renderer/platform/heap/trace_traits.h
@@ -21,6 +21,8 @@
namespace blink {
+template <typename Table>
+class HeapHashTableBacking;
template <typename ValueArg, wtf_size_t inlineCapacity>
class HeapListHashSetAllocator;
template <typename T>
@@ -35,11 +37,11 @@ template <typename T>
struct AdjustPointerTrait<T, false> {
STATIC_ONLY(AdjustPointerTrait);
- static TraceDescriptor GetTraceDescriptor(void* self) {
+ static TraceDescriptor GetTraceDescriptor(const void* self) {
return {self, TraceTrait<T>::Trace};
}
- static HeapObjectHeader* GetHeapObjectHeader(void* self) {
+ static HeapObjectHeader* GetHeapObjectHeader(const void* self) {
return HeapObjectHeader::FromPayload(self);
}
};
@@ -48,12 +50,12 @@ template <typename T>
struct AdjustPointerTrait<T, true> {
STATIC_ONLY(AdjustPointerTrait);
- static TraceDescriptor GetTraceDescriptor(void* self) {
- return static_cast<T*>(self)->GetTraceDescriptor();
+ static TraceDescriptor GetTraceDescriptor(const void* self) {
+ return static_cast<const T*>(self)->GetTraceDescriptor();
}
- static HeapObjectHeader* GetHeapObjectHeader(void* self) {
- return static_cast<T*>(self)->GetHeapObjectHeader();
+ static HeapObjectHeader* GetHeapObjectHeader(const void* self) {
+ return static_cast<const T*>(self)->GetHeapObjectHeader();
}
};
@@ -63,13 +65,13 @@ struct TraceIfNeeded;
template <typename T>
struct TraceIfNeeded<T, false> {
STATIC_ONLY(TraceIfNeeded);
- static void Trace(blink::Visitor*, T&) {}
+ static void Trace(Visitor*, const T&) {}
};
template <typename T>
struct TraceIfNeeded<T, true> {
STATIC_ONLY(TraceIfNeeded);
- static void Trace(blink::Visitor* visitor, T& t) { visitor->Trace(t); }
+ static void Trace(Visitor* visitor, const T& t) { visitor->Trace(t); }
};
template <WTF::WeakHandlingFlag weakness,
@@ -87,9 +89,9 @@ struct TraceCollectionIfEnabled<weakness,
WTF::kNoWeakHandling> {
STATIC_ONLY(TraceCollectionIfEnabled);
- static bool IsAlive(T&) { return true; }
+ static bool IsAlive(const T&) { return true; }
- static bool Trace(blink::Visitor*, void*) {
+ static bool Trace(Visitor*, const void*) {
static_assert(!WTF::IsTraceableInCollectionTrait<Traits>::value,
"T should not be traced");
return false;
@@ -104,9 +106,9 @@ struct TraceCollectionIfEnabled<WTF::kNoWeakHandling,
WTF::kWeakHandling> {
STATIC_ONLY(TraceCollectionIfEnabled);
- static bool Trace(blink::Visitor* visitor, void* t) {
+ static bool Trace(Visitor* visitor, const void* t) {
return WTF::TraceInCollectionTrait<WTF::kNoWeakHandling, T, Traits>::Trace(
- visitor, *reinterpret_cast<T*>(t));
+ visitor, *reinterpret_cast<const T*>(t));
}
};
@@ -118,16 +120,16 @@ template <WTF::WeakHandlingFlag weakness,
struct TraceCollectionIfEnabled {
STATIC_ONLY(TraceCollectionIfEnabled);
- static bool IsAlive(T& traceable) {
+ static bool IsAlive(const T& traceable) {
return WTF::TraceInCollectionTrait<weakness, T, Traits>::IsAlive(traceable);
}
- static bool Trace(blink::Visitor* visitor, void* t) {
+ static bool Trace(Visitor* visitor, const void* t) {
static_assert(WTF::IsTraceableInCollectionTrait<Traits>::value ||
weakness == WTF::kWeakHandling,
"Traits should be traced");
return WTF::TraceInCollectionTrait<weakness, T, Traits>::Trace(
- visitor, *reinterpret_cast<T*>(t));
+ visitor, *reinterpret_cast<const T*>(t));
}
};
@@ -148,120 +150,32 @@ struct TraceTrait {
STATIC_ONLY(TraceTrait);
public:
- static TraceDescriptor GetTraceDescriptor(void* self) {
- return AdjustPointerTrait<T>::GetTraceDescriptor(static_cast<T*>(self));
+ static TraceDescriptor GetTraceDescriptor(const void* self) {
+ return AdjustPointerTrait<T>::GetTraceDescriptor(
+ static_cast<const T*>(self));
}
- static TraceDescriptor GetWeakTraceDescriptor(void* self) {
+ static TraceDescriptor GetWeakTraceDescriptor(const void* self) {
return {self, nullptr};
}
- static HeapObjectHeader* GetHeapObjectHeader(void* self) {
- return AdjustPointerTrait<T>::GetHeapObjectHeader(static_cast<T*>(self));
+ static HeapObjectHeader* GetHeapObjectHeader(const void* self) {
+ return AdjustPointerTrait<T>::GetHeapObjectHeader(
+ static_cast<const T*>(self));
}
- static void Trace(Visitor*, void* self);
+ static void Trace(Visitor*, const void* self);
};
template <typename T>
struct TraceTrait<const T> : public TraceTrait<T> {};
template <typename T>
-void TraceTrait<T>::Trace(Visitor* visitor, void* self) {
+void TraceTrait<T>::Trace(Visitor* visitor, const void* self) {
static_assert(WTF::IsTraceable<T>::value, "T should not be traced");
- static_cast<T*>(self)->Trace(visitor);
+ static_cast<T*>(const_cast<void*>(self))->Trace(visitor);
}
-template <typename T, typename Traits>
-struct TraceTrait<HeapVectorBacking<T, Traits>> {
- STATIC_ONLY(TraceTrait);
- using Backing = HeapVectorBacking<T, Traits>;
-
- public:
- static TraceDescriptor GetTraceDescriptor(void* self) {
- return {self, TraceTrait<Backing>::Trace};
- }
-
- static void Trace(blink::Visitor* visitor, void* self) {
- static_assert(!WTF::IsWeak<T>::value,
- "Weakness is not supported in HeapVector and HeapDeque");
- if (WTF::IsTraceableInCollectionTrait<Traits>::value) {
- WTF::TraceInCollectionTrait<WTF::kNoWeakHandling,
- HeapVectorBacking<T, Traits>,
- void>::Trace(visitor, self);
- }
- }
-};
-
-// The trace trait for the heap hashtable backing is used when we find a
-// direct pointer to the backing from the conservative stack scanner. This
-// normally indicates that there is an ongoing iteration over the table, and so
-// we disable weak processing of table entries. When the backing is found
-// through the owning hash table we mark differently, in order to do weak
-// processing.
-template <typename Table>
-struct TraceTrait<HeapHashTableBacking<Table>> {
- STATIC_ONLY(TraceTrait);
- using Backing = HeapHashTableBacking<Table>;
- using ValueType = typename Table::ValueTraits::TraitType;
- using Traits = typename Table::ValueTraits;
-
- public:
- static TraceDescriptor GetTraceDescriptor(void* self) {
- return {self, Trace<WTF::kNoWeakHandling>};
- }
-
- static TraceDescriptor GetWeakTraceDescriptor(void* self) {
- return GetWeakTraceDescriptorImpl<ValueType>::GetWeakTraceDescriptor(self);
- }
-
- template <WTF::WeakHandlingFlag WeakHandling = WTF::kNoWeakHandling>
- static void Trace(Visitor* visitor, void* self) {
- static_assert(WTF::IsTraceableInCollectionTrait<Traits>::value ||
- WTF::IsWeak<ValueType>::value,
- "T should not be traced");
- WTF::TraceInCollectionTrait<WeakHandling, Backing, void>::Trace(visitor,
- self);
- }
-
- private:
- template <typename ValueType>
- struct GetWeakTraceDescriptorImpl {
- static TraceDescriptor GetWeakTraceDescriptor(void* backing) {
- return {backing, nullptr};
- }
- };
-
- template <typename K, typename V>
- struct GetWeakTraceDescriptorImpl<WTF::KeyValuePair<K, V>> {
- static TraceDescriptor GetWeakTraceDescriptor(void* backing) {
- return GetWeakTraceDescriptorKVPImpl<K, V>::GetWeakTraceDescriptor(
- backing);
- }
-
- template <typename KeyType,
- typename ValueType,
- bool ephemeron_semantics = (WTF::IsWeak<KeyType>::value &&
- !WTF::IsWeak<ValueType>::value &&
- WTF::IsTraceable<ValueType>::value) ||
- (WTF::IsWeak<ValueType>::value &&
- !WTF::IsWeak<KeyType>::value &&
- WTF::IsTraceable<KeyType>::value)>
- struct GetWeakTraceDescriptorKVPImpl {
- static TraceDescriptor GetWeakTraceDescriptor(void* backing) {
- return {backing, nullptr};
- }
- };
-
- template <typename KeyType, typename ValueType>
- struct GetWeakTraceDescriptorKVPImpl<KeyType, ValueType, true> {
- static TraceDescriptor GetWeakTraceDescriptor(void* backing) {
- return {backing, Trace<WTF::kWeakHandling>};
- }
- };
- };
-};
-
// This trace trait for std::pair will null weak members if their referent is
// collected. If you have a collection that contain weakness it does not remove
// entries from the collection that contain nulled weak members.
@@ -270,7 +184,7 @@ struct TraceTrait<std::pair<T, U>> {
STATIC_ONLY(TraceTrait);
public:
- static void Trace(blink::Visitor* visitor, std::pair<T, U>* pair) {
+ static void Trace(Visitor* visitor, const std::pair<T, U>* pair) {
TraceIfNeeded<T>::Trace(visitor, pair->first);
TraceIfNeeded<U>::Trace(visitor, pair->second);
}
@@ -285,7 +199,7 @@ struct TraceTrait<base::Optional<T>> {
STATIC_ONLY(TraceTrait);
public:
- static void Trace(blink::Visitor* visitor, base::Optional<T>* optional) {
+ static void Trace(Visitor* visitor, const base::Optional<T>* optional) {
if (*optional != base::nullopt) {
TraceIfNeeded<T>::Trace(visitor, optional->value());
}
@@ -304,9 +218,10 @@ struct EphemeronKeyValuePair {
using KeyTraits = _KeyTraits;
using ValueTraits = _ValueTraits;
- EphemeronKeyValuePair(KeyType* k, ValueType* v) : key(k), value(v) {}
- KeyType* key;
- ValueType* value;
+ EphemeronKeyValuePair(const KeyType* k, const ValueType* v)
+ : key(k), value(v) {}
+ const KeyType* key;
+ const ValueType* value;
};
template <typename _KeyType,
@@ -322,7 +237,7 @@ struct EphemeronKeyValuePair<_KeyType,
_ValueTraits,
_KeyTraits,
false> {
- EphemeronKeyValuePair(_KeyType* k, _ValueType* v)
+ EphemeronKeyValuePair(const _KeyType* k, const _ValueType* v)
: EphemeronKeyValuePair<_ValueType,
_KeyType,
_ValueTraits,
@@ -342,9 +257,9 @@ namespace WTF {
// weak elements.
template <typename T, typename Traits>
struct TraceInCollectionTrait<kNoWeakHandling, T, Traits> {
- static bool IsAlive(T& t) { return true; }
+ static bool IsAlive(const T& t) { return true; }
- static bool Trace(blink::Visitor* visitor, T& t) {
+ static bool Trace(blink::Visitor* visitor, const T& t) {
static_assert(IsTraceableInCollectionTrait<Traits>::value,
"T should not be traced");
visitor->Trace(t);
@@ -353,142 +268,45 @@ struct TraceInCollectionTrait<kNoWeakHandling, T, Traits> {
};
template <typename T, typename Traits>
-struct TraceInCollectionTrait<kNoWeakHandling, blink::WeakMember<T>, Traits> {
- static bool Trace(blink::Visitor* visitor, blink::WeakMember<T>& t) {
- // Extract raw pointer to avoid using the WeakMember<> overload in Visitor.
- visitor->Trace(t.Get());
+struct TraceInCollectionTrait<kNoWeakHandling, blink::Member<T>, Traits> {
+ static bool IsAlive(const blink::Member<T>& t) { return true; }
+ static bool Trace(blink::Visitor* visitor, const blink::Member<T>& t) {
+ visitor->TraceMaybeDeleted(t);
return false;
}
};
-// Catch-all for types that have HashTrait support for tracing with weakness.
-// Empty to enforce specialization.
-template <typename T, typename Traits>
-struct TraceInCollectionTrait<kWeakHandling, T, Traits> {};
-
template <typename T, typename Traits>
-struct TraceInCollectionTrait<kWeakHandling, blink::WeakMember<T>, Traits> {
- static bool IsAlive(blink::WeakMember<T>& value) {
- return blink::ThreadHeap::IsHeapObjectAlive(value);
- }
-
- static bool Trace(blink::Visitor* visitor, blink::WeakMember<T>& value) {
- return !blink::ThreadHeap::IsHeapObjectAlive(value);
+struct TraceInCollectionTrait<kWeakHandling, blink::Member<T>, Traits> {
+ static bool IsAlive(const blink::Member<T>& t) { return true; }
+ static bool Trace(blink::Visitor* visitor, const blink::Member<T>& t) {
+ visitor->TraceMaybeDeleted(t);
+ return false;
}
};
-// This trace method is used only for on-stack HeapVectors found in
-// conservative scanning. On-heap HeapVectors are traced by Vector::trace.
template <typename T, typename Traits>
-struct TraceInCollectionTrait<kNoWeakHandling,
- blink::HeapVectorBacking<T, Traits>,
- void> {
- static bool Trace(blink::Visitor* visitor, void* self) {
- // HeapVectorBacking does not know the exact size of the vector
- // and just knows the capacity of the vector. Due to the constraint,
- // HeapVectorBacking can support only the following objects:
- //
- // - An object that has a vtable. In this case, HeapVectorBacking
- // traces only slots that are not zeroed out. This is because if
- // the object has a vtable, the zeroed slot means that it is
- // an unused slot (Remember that the unused slots are guaranteed
- // to be zeroed out by VectorUnusedSlotClearer).
- //
- // - An object that can be initialized with memset. In this case,
- // HeapVectorBacking traces all slots including unused slots.
- // This is fine because the fact that the object can be initialized
- // with memset indicates that it is safe to treat the zerod slot
- // as a valid object.
- static_assert(!IsTraceableInCollectionTrait<Traits>::value ||
- Traits::kCanClearUnusedSlotsWithMemset ||
- std::is_polymorphic<T>::value,
- "HeapVectorBacking doesn't support objects that cannot be "
- "cleared as unused with memset.");
-
- // This trace method is instantiated for vectors where
- // IsTraceableInCollectionTrait<Traits>::value is false, but the trace
- // method should not be called. Thus we cannot static-assert
- // IsTraceableInCollectionTrait<Traits>::value but should runtime-assert it.
- DCHECK(IsTraceableInCollectionTrait<Traits>::value);
-
- T* array = reinterpret_cast<T*>(self);
- blink::HeapObjectHeader* header =
- blink::HeapObjectHeader::FromPayload(self);
- // Use the payload size as recorded by the heap to determine how many
- // elements to trace.
- size_t length = header->PayloadSize() / sizeof(T);
-#ifdef ANNOTATE_CONTIGUOUS_CONTAINER
- // As commented above, HeapVectorBacking can trace unused slots
- // (which are already zeroed out).
- ANNOTATE_CHANGE_SIZE(array, length, 0, length);
-#endif
- if (std::is_polymorphic<T>::value) {
- char* pointer = reinterpret_cast<char*>(array);
- for (unsigned i = 0; i < length; ++i) {
- char* element = pointer + i * sizeof(T);
- if (blink::VTableInitialized(element))
- blink::TraceIfNeeded<
- T, IsTraceableInCollectionTrait<Traits>::value>::Trace(visitor,
- array[i]);
- }
- } else {
- for (size_t i = 0; i < length; ++i)
- blink::TraceIfNeeded<
- T, IsTraceableInCollectionTrait<Traits>::value>::Trace(visitor,
- array[i]);
- }
+struct TraceInCollectionTrait<kNoWeakHandling, blink::WeakMember<T>, Traits> {
+ static bool Trace(blink::Visitor* visitor, const blink::WeakMember<T>& t) {
+ visitor->TraceMaybeDeleted(t);
return false;
}
};
-// This trace method is for tracing a HashTableBacking either through regular
-// tracing (via the relevant TraceTraits) or when finding a HashTableBacking
-// through conservative stack scanning (which will treat all references in the
-// backing strongly).
-template <WTF::WeakHandlingFlag WeakHandling, typename Table>
-struct TraceHashTableBackingInCollectionTrait {
- using Value = typename Table::ValueType;
- using Traits = typename Table::ValueTraits;
-
- static bool Trace(blink::Visitor* visitor, void* self) {
- static_assert(IsTraceableInCollectionTrait<Traits>::value ||
- WTF::IsWeak<Value>::value,
- "Table should not be traced");
- Value* array = reinterpret_cast<Value*>(self);
- blink::HeapObjectHeader* header =
- blink::HeapObjectHeader::FromPayload(self);
- // Use the payload size as recorded by the heap to determine how many
- // elements to trace.
- size_t length = header->PayloadSize() / sizeof(Value);
- for (size_t i = 0; i < length; ++i) {
- if (!HashTableHelper<Value, typename Table::ExtractorType,
- typename Table::KeyTraitsType>::
- IsEmptyOrDeletedBucket(array[i])) {
- blink::TraceCollectionIfEnabled<WeakHandling, Value, Traits>::Trace(
- visitor, &array[i]);
- }
- }
- return false;
- }
-};
+// Catch-all for types that have HashTrait support for tracing with weakness.
+// Empty to enforce specialization.
+template <typename T, typename Traits>
+struct TraceInCollectionTrait<kWeakHandling, T, Traits> {};
-template <typename Table>
-struct TraceInCollectionTrait<kNoWeakHandling,
- blink::HeapHashTableBacking<Table>,
- void> {
- static bool Trace(blink::Visitor* visitor, void* self) {
- return TraceHashTableBackingInCollectionTrait<kNoWeakHandling,
- Table>::Trace(visitor, self);
+template <typename T, typename Traits>
+struct TraceInCollectionTrait<kWeakHandling, blink::WeakMember<T>, Traits> {
+ static bool IsAlive(const blink::WeakMember<T>& value) {
+ return blink::ThreadHeap::IsHeapObjectAlive(value);
}
-};
-template <typename Table>
-struct TraceInCollectionTrait<kWeakHandling,
- blink::HeapHashTableBacking<Table>,
- void> {
- static bool Trace(blink::Visitor* visitor, void* self) {
- return TraceHashTableBackingInCollectionTrait<kWeakHandling, Table>::Trace(
- visitor, self);
+ static bool Trace(blink::Visitor* visitor,
+ const blink::WeakMember<T>& value) {
+ return !blink::ThreadHeap::IsHeapObjectAlive(value);
}
};
@@ -522,109 +340,46 @@ struct TraceInCollectionTrait<
blink::HeapListHashSetAllocator<T, inlineCapacity>>;
using Table = HashTable<Node*, U, V, W, X, Y, blink::HeapAllocator>;
- static bool Trace(blink::Visitor* visitor, void* self) {
- Node** array = reinterpret_cast<Node**>(self);
+ static bool Trace(blink::Visitor* visitor, const void* self) {
+ const Node* const* array = reinterpret_cast<const Node* const*>(self);
blink::HeapObjectHeader* header =
blink::HeapObjectHeader::FromPayload(self);
size_t length = header->PayloadSize() / sizeof(Node*);
+ const bool is_concurrent = visitor->IsConcurrent();
for (size_t i = 0; i < length; ++i) {
- if (!HashTableHelper<Node*, typename Table::ExtractorType,
- typename Table::KeyTraitsType>::
- IsEmptyOrDeletedBucket(array[i])) {
- visitor->Trace(array[i]);
+ const Node* node;
+ if (is_concurrent) {
+ // If tracing concurrently, IsEmptyOrDeletedBucket can cause data
+ // races. Loading array[i] atomically prevents possible data races.
+ // array[i] is of type Node* so can directly loaded atomically.
+ node = AsAtomicPtr(&array[i])->load(std::memory_order_relaxed);
+ } else {
+ node = array[i];
+ }
+ if (!HashTableHelper<
+ const Node*, typename Table::ExtractorType,
+ typename Table::KeyTraitsType>::IsEmptyOrDeletedBucket(node)) {
+ visitor->Trace(node);
}
}
return false;
}
};
-// Key value pairs, as used in HashMap. To disambiguate template choice we have
-// to have two versions, first the one with no special weak handling, then the
-// one with weak handling.
-template <typename Key, typename Value, typename Traits>
-struct TraceInCollectionTrait<kNoWeakHandling,
- KeyValuePair<Key, Value>,
- Traits> {
- using EphemeronHelper =
- blink::EphemeronKeyValuePair<Key,
- Value,
- typename Traits::KeyTraits,
- typename Traits::ValueTraits>;
-
- static bool Trace(blink::Visitor* visitor, KeyValuePair<Key, Value>& self) {
- if (WTF::IsWeak<Key>::value != WTF::IsWeak<Value>::value) {
- // Strongification of Weak/Strong and Strong/Weak.
- EphemeronHelper helper(&self.key, &self.value);
- visitor->VisitEphemeronKeyValuePair(
- helper.key, helper.value,
- blink::TraceCollectionIfEnabled<
- kNoWeakHandling, typename EphemeronHelper::KeyType,
- typename EphemeronHelper::KeyTraits>::Trace,
- blink::TraceCollectionIfEnabled<
- kNoWeakHandling, typename EphemeronHelper::ValueType,
- typename EphemeronHelper::ValueTraits>::Trace);
- } else {
- // Strongification of 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);
- }
- return false;
- }
-};
-
-template <typename Key, typename Value, typename Traits>
-struct TraceInCollectionTrait<kWeakHandling, KeyValuePair<Key, Value>, Traits> {
- using EphemeronHelper =
- blink::EphemeronKeyValuePair<Key,
- Value,
- typename Traits::KeyTraits,
- typename Traits::ValueTraits>;
-
- static bool IsAlive(KeyValuePair<Key, Value>& self) {
- // Needed for Weak/Weak, Strong/Weak (reverse ephemeron), and Weak/Strong
- // (ephemeron). Order of invocation does not matter as tracing weak key or
- // value does not have any side effects.
- return blink::TraceCollectionIfEnabled<
- WeakHandlingTrait<Key>::value, Key,
- typename Traits::KeyTraits>::IsAlive(self.key) &&
- blink::TraceCollectionIfEnabled<
- WeakHandlingTrait<Value>::value, Value,
- typename Traits::ValueTraits>::IsAlive(self.value);
- }
-
- static bool Trace(blink::Visitor* visitor, KeyValuePair<Key, Value>& self) {
- EphemeronHelper helper(&self.key, &self.value);
- return visitor->VisitEphemeronKeyValuePair(
- helper.key, helper.value,
- blink::TraceCollectionIfEnabled<
- WeakHandlingTrait<typename EphemeronHelper::KeyType>::value,
- typename EphemeronHelper::KeyType,
- typename EphemeronHelper::KeyTraits>::Trace,
- blink::TraceCollectionIfEnabled<
- WeakHandlingTrait<typename EphemeronHelper::ValueType>::value,
- typename EphemeronHelper::ValueType,
- typename EphemeronHelper::ValueTraits>::Trace);
- }
-};
-
// Nodes used by LinkedHashSet. Again we need two versions to disambiguate the
// template.
template <typename Value, typename Traits>
struct TraceInCollectionTrait<kNoWeakHandling,
LinkedHashSetNode<Value>,
Traits> {
- static bool IsAlive(LinkedHashSetNode<Value>& self) {
+ static bool IsAlive(const LinkedHashSetNode<Value>& self) {
return TraceInCollectionTrait<
kNoWeakHandling, Value,
typename Traits::ValueTraits>::IsAlive(self.value_);
}
- static bool Trace(blink::Visitor* visitor, LinkedHashSetNode<Value>& self) {
+ static bool Trace(blink::Visitor* visitor,
+ const LinkedHashSetNode<Value>& self) {
static_assert(
IsTraceableInCollectionTrait<Traits>::value || IsWeak<Value>::value,
"T should not be traced");
@@ -636,13 +391,14 @@ struct TraceInCollectionTrait<kNoWeakHandling,
template <typename Value, typename Traits>
struct TraceInCollectionTrait<kWeakHandling, LinkedHashSetNode<Value>, Traits> {
- static bool IsAlive(LinkedHashSetNode<Value>& self) {
+ static bool IsAlive(const LinkedHashSetNode<Value>& self) {
return TraceInCollectionTrait<
kWeakHandling, Value,
typename Traits::ValueTraits>::IsAlive(self.value_);
}
- static bool Trace(blink::Visitor* visitor, LinkedHashSetNode<Value>& self) {
+ static bool Trace(blink::Visitor* visitor,
+ const LinkedHashSetNode<Value>& self) {
return TraceInCollectionTrait<
kWeakHandling, Value, typename Traits::ValueTraits>::Trace(visitor,
self.value_);
@@ -661,7 +417,7 @@ struct TraceInCollectionTrait<
ListHashSetNode<Value,
blink::HeapListHashSetAllocator<Value, inlineCapacity>>;
- static bool Trace(blink::Visitor* visitor, Node* node) {
+ static bool Trace(blink::Visitor* visitor, const Node* node) {
static_assert(!IsWeak<Node>::value,
"ListHashSet does not support weakness");
static_assert(IsTraceableInCollectionTrait<Traits>::value,
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 d618263c29e..a607b88200a 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
@@ -46,7 +46,8 @@ void UnifiedHeapController::TracePrologue(
// Be conservative here as a new garbage collection gets started right away.
thread_state_->FinishIncrementalMarkingIfRunning(
- BlinkGC::kHeapPointersOnStack, BlinkGC::kIncrementalAndConcurrentMarking,
+ BlinkGC::CollectionType::kMajor, BlinkGC::kHeapPointersOnStack,
+ BlinkGC::kIncrementalAndConcurrentMarking,
BlinkGC::kConcurrentAndLazySweeping,
thread_state_->current_gc_data_.reason);
@@ -65,7 +66,7 @@ void UnifiedHeapController::EnterFinalPause(EmbedderStackState stack_state) {
ThreadHeapStatsCollector::BlinkGCInV8Scope nested_scope(
thread_state_->Heap().stats_collector());
thread_state_->AtomicPauseMarkPrologue(
- ToBlinkGCStackState(stack_state),
+ BlinkGC::CollectionType::kMajor, ToBlinkGCStackState(stack_state),
BlinkGC::kIncrementalAndConcurrentMarking,
thread_state_->current_gc_data_.reason);
thread_state_->AtomicPauseMarkRoots(ToBlinkGCStackState(stack_state),
@@ -82,6 +83,7 @@ void UnifiedHeapController::TraceEpilogue(
thread_state_->AtomicPauseMarkEpilogue(
BlinkGC::kIncrementalAndConcurrentMarking);
thread_state_->AtomicPauseSweepAndCompact(
+ BlinkGC::CollectionType::kMajor,
BlinkGC::kIncrementalAndConcurrentMarking,
BlinkGC::kConcurrentAndLazySweeping);
@@ -104,9 +106,9 @@ void UnifiedHeapController::RegisterV8References(
const bool was_in_atomic_pause = thread_state()->in_atomic_pause();
if (!was_in_atomic_pause)
ThreadState::Current()->EnterAtomicPause();
- for (auto& internal_fields : internal_fields_of_potential_wrappers) {
- WrapperTypeInfo* wrapper_type_info =
- reinterpret_cast<WrapperTypeInfo*>(internal_fields.first);
+ for (const auto& internal_fields : internal_fields_of_potential_wrappers) {
+ const WrapperTypeInfo* wrapper_type_info =
+ reinterpret_cast<const WrapperTypeInfo*>(internal_fields.first);
if (wrapper_type_info->gin_embedder != gin::GinEmbedder::kEmbedderBlink) {
continue;
}
@@ -123,7 +125,7 @@ bool UnifiedHeapController::AdvanceTracing(double deadline_in_ms) {
ThreadHeapStatsCollector::BlinkGCInV8Scope nested_scope(
thread_state_->Heap().stats_collector());
if (!thread_state_->in_atomic_pause()) {
- ThreadHeapStatsCollector::Scope advance_tracing_scope(
+ ThreadHeapStatsCollector::EnabledScope advance_tracing_scope(
thread_state_->Heap().stats_collector(),
ThreadHeapStatsCollector::kUnifiedMarkingStep);
// V8 calls into embedder tracing from its own marking to ensure
@@ -133,6 +135,14 @@ bool UnifiedHeapController::AdvanceTracing(double deadline_in_ms) {
base::TimeTicks deadline =
base::TimeTicks() + base::TimeDelta::FromMillisecondsD(deadline_in_ms);
is_tracing_done_ = thread_state_->MarkPhaseAdvanceMarking(deadline);
+ if (!is_tracing_done_) {
+ 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/unified_heap_marking_visitor.cc b/chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc
index ce94f8becfd..62f9340f754 100644
--- a/chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.cc
@@ -28,8 +28,6 @@ UnifiedHeapMarkingVisitorBase::UnifiedHeapMarkingVisitorBase(
void UnifiedHeapMarkingVisitorBase::VisitImpl(
const TraceWrapperV8Reference<v8::Value>& v8_reference) {
- if (v8_reference.Get().IsEmpty())
- return;
DCHECK(isolate_);
if (task_id_ != WorklistTaskId::MutatorThread) {
// This is a temporary solution. Pushing directly from concurrent threads
@@ -40,6 +38,8 @@ void UnifiedHeapMarkingVisitorBase::VisitImpl(
v8_references_worklist_.Push(&v8_reference);
return;
}
+ if (v8_reference.Get().IsEmpty())
+ return;
controller_->RegisterEmbedderReference(
v8_reference.template Cast<v8::Data>().Get());
}
@@ -69,7 +69,7 @@ void UnifiedHeapMarkingVisitor::WriteBarrier(
void UnifiedHeapMarkingVisitor::WriteBarrier(
v8::Isolate* isolate,
const WrapperTypeInfo* wrapper_type_info,
- void* object) {
+ const void* object) {
// |object| here is either ScriptWrappable or CustomWrappable.
if (!ThreadState::IsAnyIncrementalMarking())
diff --git a/chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h b/chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h
index b396d3c59c1..d2e663116cc 100644
--- a/chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h
+++ b/chromium/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h
@@ -49,7 +49,7 @@ class PLATFORM_EXPORT UnifiedHeapMarkingVisitor
public:
// Write barriers for annotating a write during incremental marking.
static void WriteBarrier(const TraceWrapperV8Reference<v8::Value>&);
- static void WriteBarrier(v8::Isolate*, const WrapperTypeInfo*, void*);
+ static void WriteBarrier(v8::Isolate*, const WrapperTypeInfo*, const void*);
UnifiedHeapMarkingVisitor(ThreadState*, MarkingMode, v8::Isolate*);
~UnifiedHeapMarkingVisitor() override = default;
diff --git a/chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.cc b/chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.cc
new file mode 100644
index 00000000000..a33e2b21ee0
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.cc
@@ -0,0 +1,63 @@
+// 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/unsanitized_atomic.h"
+
+#include "cstdint"
+
+#include "base/compiler_specific.h"
+
+#if HAS_FEATURE(address_sanitizer)
+#error "Must be built without asan."
+#endif
+
+namespace blink {
+namespace internal {
+
+template <typename T>
+void UnsanitizedAtomic<T>::store(T value, std::memory_order order) {
+ Base::store(value, order);
+}
+
+template <typename T>
+T UnsanitizedAtomic<T>::load(std::memory_order order) const {
+ return Base::load(order);
+}
+
+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);
+}
+
+template <typename T>
+bool UnsanitizedAtomic<T>::compare_exchange_strong(
+ T& expected,
+ T desired,
+ std::memory_order succ_order,
+ std::memory_order fail_order) {
+ return Base::compare_exchange_strong(expected, desired, succ_order,
+ 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);
+}
+
+template <typename T>
+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);
+}
+
+template class PLATFORM_EXPORT UnsanitizedAtomic<uint16_t>;
+
+} // namespace internal
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.h b/chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.h
new file mode 100644
index 00000000000..fc93c9b4dd8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/unsanitized_atomic.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_PLATFORM_HEAP_UNSANITIZED_ATOMIC_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_UNSANITIZED_ATOMIC_H_
+
+#include <atomic>
+
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+
+namespace blink {
+namespace internal {
+
+// Simple wrapper for std::atomic<> that makes sure that accesses to underlying
+// data are not sanitized. This is needed because the no_sanitize_address
+// attribute doesn't propagate down to callees. Must be used with care.
+// 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>;
+
+ public:
+ void store(T, std::memory_order = std::memory_order_seq_cst);
+ T load(std::memory_order = std::memory_order_seq_cst) const;
+
+ bool compare_exchange_strong(T&,
+ T,
+ std::memory_order = std::memory_order_seq_cst);
+ bool compare_exchange_strong(T&, T, std::memory_order, std::memory_order);
+
+ bool compare_exchange_weak(T&,
+ T,
+ std::memory_order = std::memory_order_seq_cst);
+ bool compare_exchange_weak(T&, T, std::memory_order, std::memory_order);
+};
+
+template <typename T>
+auto* AsUnsanitizedAtomic(T* ptr) {
+#if defined(ADDRESS_SANITIZER)
+ return reinterpret_cast<UnsanitizedAtomic<T>*>(ptr);
+#else
+ return WTF::AsAtomicPtr(ptr);
+#endif
+}
+
+template <typename T>
+const auto* AsUnsanitizedAtomic(const T* ptr) {
+#if defined(ADDRESS_SANITIZER)
+ return reinterpret_cast<const UnsanitizedAtomic<T>*>(ptr);
+#else
+ return WTF::AsAtomicPtr(ptr);
+#endif
+}
+
+} // namespace internal
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_UNSANITIZED_ATOMIC_H_
diff --git a/chromium/third_party/blink/renderer/platform/heap/visitor.h b/chromium/third_party/blink/renderer/platform/heap/visitor.h
index 67e195fe821..d0d6e096441 100644
--- a/chromium/third_party/blink/renderer/platform/heap/visitor.h
+++ b/chromium/third_party/blink/renderer/platform/heap/visitor.h
@@ -69,19 +69,19 @@ class TraceWrapperV8Reference;
//
// This interface is safe to use on concurrent threads. All accesses (reads)
// from member are done atomically.
-template <typename T, void (T::*method)(Visitor*)>
+template <typename T, void (T::*method)(Visitor*) const>
struct TraceMethodDelegate {
STATIC_ONLY(TraceMethodDelegate);
- static void Trampoline(Visitor* visitor, void* self) {
- (reinterpret_cast<T*>(self)->*method)(visitor);
+ static void Trampoline(Visitor* visitor, const void* self) {
+ (reinterpret_cast<T*>(const_cast<void*>(self))->*method)(visitor);
}
};
template <typename T, void (T::*method)(const WeakCallbackInfo&)>
struct WeakCallbackMethodDelegate {
STATIC_ONLY(WeakCallbackMethodDelegate);
- static void Trampoline(const WeakCallbackInfo& info, void* self) {
- (reinterpret_cast<T*>(self)->*method)(info);
+ static void Trampoline(const WeakCallbackInfo& info, const void* self) {
+ (reinterpret_cast<T*>(const_cast<void*>(self))->*method)(info);
}
};
@@ -105,24 +105,47 @@ class PLATFORM_EXPORT Visitor {
"T needs to be a garbage collected object");
if (!t)
return;
- VisitRoot(const_cast<T*>(t), TraceDescriptorFor(t), location);
+ VisitRoot(t, TraceDescriptorFor(t), location);
}
template <typename T>
void Trace(const Member<T>& t) {
- DCHECK(!t.IsHashTableDeletedValueSafe());
- Trace(t.GetSafe());
+ const T* value = t.GetSafe();
+
+ DCHECK(!Member<T>::IsMemberHashTableDeletedValue(value));
+
+ Trace(value);
}
- // Fallback methods used only when we need to trace raw pointers of T. This is
- // the case when a member is a union where we do not support members.
template <typename T>
- void Trace(const T* t) {
- Trace(const_cast<T*>(t));
+ ALWAYS_INLINE void TraceMaybeDeleted(const Member<T>& t) {
+ const T* value = t.GetSafe();
+
+ if (Member<T>::IsMemberHashTableDeletedValue(value))
+ return;
+
+ Trace<T>(value);
}
+ // TraceMayBeDeleted strongifies WeakMembers.
+ template <typename T>
+ ALWAYS_INLINE void TraceMaybeDeleted(const WeakMember<T>& t) {
+ const T* value = t.GetSafe();
+
+ if (WeakMember<T>::IsMemberHashTableDeletedValue(value))
+ return;
+
+ Trace<T>(value);
+ }
+
+ // Fallback methods used only when we need to trace raw pointers of T. This is
+ // the case when a member is a union where we do not support members.
template <typename T>
void Trace(T* t) {
+ Trace(const_cast<const T*>(t));
+ }
+ template <typename T>
+ void Trace(const T* t) {
static_assert(sizeof(T), "T must be fully defined");
static_assert(IsGarbageCollectedType<T>::value,
"T needs to be a garbage collected object");
@@ -132,40 +155,42 @@ class PLATFORM_EXPORT Visitor {
}
template <typename T>
- void TraceBackingStoreStrongly(T* backing_store, T** backing_store_slot) {
+ void TraceBackingStoreStrongly(const T* backing_store,
+ const T* const* backing_store_slot) {
static_assert(sizeof(T), "T must be fully defined");
static_assert(IsGarbageCollectedType<T>::value,
"T needs to be a garbage collected object");
- VisitBackingStoreStrongly(backing_store,
- reinterpret_cast<void**>(backing_store_slot),
- TraceDescriptorFor(backing_store));
+ VisitBackingStoreStrongly(
+ backing_store, reinterpret_cast<const void* const*>(backing_store_slot),
+ TraceDescriptorFor(backing_store));
}
template <typename HashTable, typename T>
- void TraceBackingStoreWeakly(T* backing_store,
- T** backing_store_slot,
+ void TraceBackingStoreWeakly(const T* backing_store,
+ const T* const* backing_store_slot,
WeakCallback weak_callback,
- void* weak_callback_parameter) {
+ const void* weak_callback_parameter) {
static_assert(sizeof(T), "T must be fully defined");
static_assert(IsGarbageCollectedType<T>::value,
"T needs to be a garbage collected object");
- VisitBackingStoreWeakly(backing_store,
- reinterpret_cast<void**>(backing_store_slot),
- TraceDescriptorFor(backing_store),
- WeakTraceDescriptorFor(backing_store),
- weak_callback, weak_callback_parameter);
+ VisitBackingStoreWeakly(
+ backing_store, reinterpret_cast<const void* const*>(backing_store_slot),
+ TraceDescriptorFor(backing_store),
+ WeakTraceDescriptorFor(backing_store), weak_callback,
+ weak_callback_parameter);
}
template <typename T>
- void TraceBackingStoreOnly(T* backing_store, T** backing_store_slot) {
+ void TraceBackingStoreOnly(const T* backing_store,
+ const T* const* backing_store_slot) {
static_assert(sizeof(T), "T must be fully defined");
static_assert(IsGarbageCollectedType<T>::value,
"T needs to be a garbage collected object");
- VisitBackingStoreOnly(backing_store,
- reinterpret_cast<void**>(backing_store_slot));
+ VisitBackingStoreOnly(backing_store, reinterpret_cast<const void* const*>(
+ backing_store_slot));
}
// WeakMember version of the templated trace method. It doesn't keep
@@ -175,19 +200,17 @@ class PLATFORM_EXPORT Visitor {
// picking the correct overload, so all these trace methods have to have
// the same constness on their argument to allow the type to decide.
template <typename T>
- void Trace(const WeakMember<T>& const_weak_member) {
+ void Trace(const WeakMember<T>& weak_member) {
static_assert(sizeof(T), "T must be fully defined");
static_assert(IsGarbageCollectedType<T>::value,
"T needs to be a garbage collected object");
- WeakMember<T>& weak_member = const_cast<WeakMember<T>&>(const_weak_member);
- std::remove_const_t<T>* value =
- const_cast<std::remove_const_t<T>*>(weak_member.GetSafe());
+ const T* value = weak_member.GetSafe();
if (!value)
return;
- DCHECK(!weak_member.IsHashTableDeletedValueSafe());
+ DCHECK(!WeakMember<T>::IsMemberHashTableDeletedValue(value));
VisitWeak(value, &weak_member, TraceDescriptorFor(value),
&HandleWeakCell<T>);
}
@@ -204,11 +227,11 @@ class PLATFORM_EXPORT Visitor {
void Trace(const T& t) {
static_assert(sizeof(T), "T must be fully defined");
if (std::is_polymorphic<T>::value) {
- intptr_t vtable = *reinterpret_cast<const intptr_t*>(&t);
+ const intptr_t vtable = *reinterpret_cast<const intptr_t*>(&t);
if (!vtable)
return;
}
- TraceTrait<T>::Trace(this, &const_cast<T&>(t));
+ TraceTrait<T>::Trace(this, &t);
}
// Registers an instance method using |RegisterWeakCallback|. See description
@@ -216,7 +239,7 @@ class PLATFORM_EXPORT Visitor {
template <typename T, void (T::*method)(const WeakCallbackInfo&)>
void RegisterWeakCallbackMethod(const T* obj) {
RegisterWeakCallback(&WeakCallbackMethodDelegate<T, method>::Trampoline,
- const_cast<T*>(obj));
+ obj);
}
// Cross-component tracing interface.
@@ -228,32 +251,39 @@ class PLATFORM_EXPORT Visitor {
// Dynamic visitor interface.
- virtual void VisitRoot(void* t, TraceDescriptor desc, const base::Location&) {
+ virtual void VisitRoot(const void* t,
+ TraceDescriptor desc,
+ const base::Location&) {
Visit(t, desc);
}
// Visits an object through a strong reference.
- virtual void Visit(void*, TraceDescriptor) = 0;
+ virtual void Visit(const void*, TraceDescriptor) = 0;
// Visits an object through a weak reference.
- virtual void VisitWeak(void*, void*, TraceDescriptor, WeakCallback) = 0;
+ virtual void VisitWeak(const void*,
+ const void*,
+ TraceDescriptor,
+ WeakCallback) = 0;
// Visitors for collection backing stores.
- virtual void VisitBackingStoreStrongly(void*, void**, TraceDescriptor) = 0;
- virtual void VisitBackingStoreWeakly(void*,
- void**,
+ virtual void VisitBackingStoreStrongly(const void*,
+ const void* const*,
+ TraceDescriptor) = 0;
+ virtual void VisitBackingStoreWeakly(const void*,
+ const void* const*,
TraceDescriptor,
TraceDescriptor,
WeakCallback,
- void*) = 0;
- virtual void VisitBackingStoreOnly(void*, void**) = 0;
+ const void*) = 0;
+ virtual void VisitBackingStoreOnly(const void*, const void* const*) = 0;
// Visits ephemeron pairs which are a combination of weak and strong keys and
// values.
- using EphemeronTracingCallback = bool (*)(Visitor*, void*);
+ using EphemeronTracingCallback = bool (*)(Visitor*, const void*);
virtual bool VisitEphemeronKeyValuePair(
- void* key,
- void* value,
+ const void* key,
+ const void* value,
EphemeronTracingCallback key_trace_callback,
EphemeronTracingCallback value_trace_callback) {
return true;
@@ -265,7 +295,7 @@ class PLATFORM_EXPORT Visitor {
// Registers backing store pointers so that they can be moved and properly
// updated.
- virtual void RegisterBackingStoreCallback(void* backing,
+ virtual void RegisterBackingStoreCallback(const void* backing,
MovingObjectCallback) = 0;
// Adds a |callback| that is invoked with |parameter| after liveness has been
@@ -280,22 +310,32 @@ class PLATFORM_EXPORT Visitor {
// - Clearing out pointers is allowed.
// - Removing elements from heap collections is allowed as these collections
// are aware of custom weakness and won't resize their backings.
- virtual void RegisterWeakCallback(WeakCallback callback, void* parameter) = 0;
+ virtual void RegisterWeakCallback(WeakCallback callback,
+ const void* parameter) = 0;
+
+ virtual bool IsConcurrent() const { return false; }
+
+ // TODO(crbug/986235): ConcurrentTracingBailOut is part of a temporary
+ // bailout mechanism to avoid tracing collections on concurrent threads.
+ // This method and any usage of it will be removed as soon as making all
+ // collections cuncurrent-safe is finished.
+ // The same also applies to NotSafeToConcurrentlyTraceWorklist in heap.h.
+ virtual bool ConcurrentTracingBailOut(TraceDescriptor desc) { return false; }
protected:
template <typename T>
static inline TraceDescriptor TraceDescriptorFor(const T* traceable) {
- return TraceTrait<T>::GetTraceDescriptor(const_cast<T*>(traceable));
+ return TraceTrait<T>::GetTraceDescriptor(traceable);
}
template <typename T>
static inline TraceDescriptor WeakTraceDescriptorFor(const T* traceable) {
- return TraceTrait<T>::GetWeakTraceDescriptor(const_cast<T*>(traceable));
+ return TraceTrait<T>::GetWeakTraceDescriptor(traceable);
}
private:
template <typename T>
- static void HandleWeakCell(const WeakCallbackInfo&, void*);
+ static void HandleWeakCell(const WeakCallbackInfo&, const void*);
ThreadState* const state_;
};
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
index 2a8869b664c..86408b94779 100644
--- a/chromium/third_party/blink/renderer/platform/heap/weakness_marking_test.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/weakness_marking_test.cc
@@ -198,6 +198,50 @@ TEST_F(WeaknessMarkingTest, TracableEphemeronIsRegsitered) {
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 7664cacf6be..b3f341077ae 100644
--- a/chromium/third_party/blink/renderer/platform/heap/worklist.h
+++ b/chromium/third_party/blink/renderer/platform/heap/worklist.h
@@ -11,6 +11,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_WORKLIST_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_WORKLIST_H_
+#include <atomic>
#include <cstddef>
#include <utility>
@@ -30,14 +31,16 @@ namespace blink {
//
// Work stealing is best effort, i.e., there is no way to inform other tasks
// of the need of items.
-template <typename _EntryType, int segment_size, int max_tasks = 2>
+template <typename _EntryType, int segment_size, int num_tasks = 4>
class Worklist {
USING_FAST_MALLOC(Worklist);
- using WorklistType = Worklist<_EntryType, segment_size, max_tasks>;
+ using WorklistType = Worklist<_EntryType, segment_size, num_tasks>;
public:
using EntryType = _EntryType;
+ static constexpr int kNumTasks = num_tasks;
+
class View {
DISALLOW_NEW();
@@ -79,11 +82,8 @@ class Worklist {
static constexpr size_t kSegmentCapacity = segment_size;
- Worklist() : Worklist(max_tasks) {}
-
- explicit Worklist(int num_tasks) : num_tasks_(num_tasks) {
- CHECK_LE(num_tasks, max_tasks);
- for (int i = 0; i < num_tasks_; i++) {
+ Worklist() {
+ for (int i = 0; i < kNumTasks; i++) {
private_push_segment(i) = NewSegment();
private_pop_segment(i) = NewSegment();
}
@@ -91,7 +91,7 @@ class Worklist {
~Worklist() {
CHECK(IsGlobalEmpty());
- for (int i = 0; i < num_tasks_; i++) {
+ for (int i = 0; i < kNumTasks; i++) {
DCHECK(private_push_segment(i));
DCHECK(private_pop_segment(i));
delete private_push_segment(i);
@@ -100,7 +100,7 @@ class Worklist {
}
bool Push(int task_id, EntryType entry) {
- DCHECK_LT(task_id, num_tasks_);
+ DCHECK_LT(task_id, kNumTasks);
DCHECK(private_push_segment(task_id));
if (!private_push_segment(task_id)->Push(entry)) {
PublishPushSegmentToGlobal(task_id);
@@ -112,7 +112,7 @@ class Worklist {
}
bool Pop(int task_id, EntryType* entry) {
- DCHECK_LT(task_id, num_tasks_);
+ DCHECK_LT(task_id, kNumTasks);
DCHECK(private_pop_segment(task_id));
if (!private_pop_segment(task_id)->Pop(entry)) {
if (!private_push_segment(task_id)->IsEmpty()) {
@@ -137,7 +137,7 @@ class Worklist {
bool IsGlobalPoolEmpty() const { return global_pool_.IsEmpty(); }
bool IsGlobalEmpty() const {
- for (int i = 0; i < num_tasks_; i++) {
+ for (int i = 0; i < kNumTasks; i++) {
if (!IsLocalEmpty(i))
return false;
}
@@ -153,6 +153,9 @@ class Worklist {
private_push_segment(task_id)->Size();
}
+ // Thread-safe but may return an outdated result.
+ size_t GlobalPoolSize() const { return global_pool_.Size(); }
+
size_t LocalPushSegmentSize(int task_id) const {
return private_push_segment(task_id)->Size();
}
@@ -161,7 +164,7 @@ class Worklist {
//
// Assumes that no other tasks are running.
void Clear() {
- for (int i = 0; i < num_tasks_; i++) {
+ for (int i = 0; i < kNumTasks; i++) {
private_pop_segment(i)->Clear();
private_push_segment(i)->Clear();
}
@@ -178,7 +181,7 @@ class Worklist {
// Assumes that no other tasks are running.
template <typename Callback>
void Update(Callback callback) {
- for (int i = 0; i < num_tasks_; i++) {
+ for (int i = 0; i < kNumTasks; i++) {
private_pop_segment(i)->Update(callback);
private_push_segment(i)->Update(callback);
}
@@ -196,12 +199,9 @@ class Worklist {
}
void MergeGlobalPool(Worklist* other) {
- auto pair = other->global_pool_.Extract();
- global_pool_.MergeList(pair.first, pair.second);
+ global_pool_.Merge(&other->global_pool_);
}
- int num_tasks() const { return num_tasks_; }
-
private:
FRIEND_TEST_ALL_PREFIXES(WorklistTest, SegmentCreate);
FRIEND_TEST_ALL_PREFIXES(WorklistTest, SegmentPush);
@@ -284,11 +284,14 @@ class Worklist {
base::AutoLock guard(lock_);
segment->set_next(top_);
set_top(segment);
+ size_.fetch_add(1, std::memory_order_relaxed);
}
inline bool Pop(Segment** segment) {
base::AutoLock guard(lock_);
if (top_) {
+ DCHECK_LT(0U, size_);
+ size_.fetch_sub(1, std::memory_order_relaxed);
*segment = top_;
set_top(top_->next());
return true;
@@ -301,8 +304,16 @@ class Worklist {
reinterpret_cast<const base::subtle::AtomicWord*>(&top_)) == 0;
}
+ inline size_t Size() const {
+ // It is safe to read |size_| without a lock since this variable is
+ // atomic, keeping in mind that threads may not immediately see the new
+ // value when it is updated.
+ return TS_UNCHECKED_READ(size_).load(std::memory_order_relaxed);
+ }
+
void Clear() {
base::AutoLock guard(lock_);
+ size_.store(0, std::memory_order_relaxed);
Segment* current = top_;
while (current) {
Segment* tmp = current;
@@ -321,6 +332,8 @@ class Worklist {
while (current) {
current->Update(callback);
if (current->IsEmpty()) {
+ DCHECK_LT(0U, size_);
+ size_.fetch_sub(1, std::memory_order_relaxed);
if (!prev) {
top_ = current->next();
} else {
@@ -345,28 +358,28 @@ class Worklist {
}
}
- std::pair<Segment*, Segment*> Extract() {
+ void Merge(GlobalPool* other) {
Segment* top = nullptr;
+ size_t other_size = 0;
{
- base::AutoLock guard(lock_);
- if (!top_)
- return std::make_pair(nullptr, nullptr);
- top = top_;
- set_top(nullptr);
+ base::AutoLock guard(other->lock_);
+ if (!other->top_)
+ return;
+ top = other->top_;
+ other_size = other->size_.load(std::memory_order_relaxed);
+ other->size_.store(0, std::memory_order_relaxed);
+ other->set_top(nullptr);
}
+
Segment* end = top;
while (end->next())
end = end->next();
- return std::make_pair(top, end);
- }
- void MergeList(Segment* start, Segment* end) {
- if (!start)
- return;
{
base::AutoLock guard(lock_);
+ size_.fetch_add(other_size, std::memory_order_relaxed);
end->set_next(top_);
- set_top(start);
+ set_top(top);
}
}
@@ -378,7 +391,8 @@ class Worklist {
}
mutable base::Lock lock_;
- Segment* top_;
+ Segment* top_ GUARDED_BY(lock_);
+ std::atomic<size_t> size_ GUARDED_BY(lock_){0};
};
ALWAYS_INLINE Segment*& private_push_segment(int task_id) {
@@ -430,9 +444,8 @@ class Worklist {
return new Segment();
}
- PrivateSegmentHolder private_segments_[max_tasks];
+ PrivateSegmentHolder private_segments_[kNumTasks];
GlobalPool global_pool_;
- int num_tasks_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/heap/worklist_test.cc b/chromium/third_party/blink/renderer/platform/heap/worklist_test.cc
index f563a75c199..1030cbab9ac 100644
--- a/chromium/third_party/blink/renderer/platform/heap/worklist_test.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/worklist_test.cc
@@ -155,13 +155,16 @@ TEST(WorklistTest, LocalPushStaysPrivate) {
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) {
@@ -175,6 +178,7 @@ TEST(WorklistTest, GlobalUpdateNull) {
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) {
@@ -216,6 +220,7 @@ TEST(WorklistTest, FlushToGlobalPushSegment) {
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));
}
@@ -230,6 +235,7 @@ TEST(WorklistTest, FlushToGlobalPopSegment) {
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));
}
@@ -242,8 +248,10 @@ TEST(WorklistTest, Clear) {
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) {
@@ -259,6 +267,7 @@ TEST(WorklistTest, SingleSegmentSteal) {
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));
@@ -266,6 +275,7 @@ TEST(WorklistTest, SingleSegmentSteal) {
EXPECT_FALSE(worklist_view1.Pop(&retrieved));
}
EXPECT_TRUE(worklist.IsGlobalEmpty());
+ EXPECT_EQ(0U, worklist.GlobalPoolSize());
}
TEST(WorklistTest, MultipleSegmentsStolen) {
@@ -287,11 +297,13 @@ TEST(WorklistTest, MultipleSegmentsStolen) {
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);
@@ -320,10 +332,13 @@ TEST(WorklistTest, MergeGlobalPool) {
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));
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
index 2cc9848ddbd..92bf0523d47 100644
--- a/chromium/third_party/blink/renderer/platform/heap/write_barrier_perftest.cc
+++ b/chromium/third_party/blink/renderer/platform/heap/write_barrier_perftest.cc
@@ -4,7 +4,7 @@
#include "base/callback.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/perf/perf_test.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"
@@ -14,6 +14,21 @@ 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;
@@ -61,19 +76,16 @@ TEST_F(WriteBarrierPerfTest, MemberWritePerformance) {
PreciselyCollectGarbage();
// Reporting.
- perf_test::PrintResult(
- "WriteBarrierPerfTest", " writes during GC", "",
- static_cast<double>(kNumElements) / during_gc_duration.InMillisecondsF(),
- "writes/ms", true);
- perf_test::PrintResult(
- "WriteBarrierPerfTest", " writes outside GC", "",
- static_cast<double>(kNumElements) / outside_gc_duration.InMillisecondsF(),
- "writes/ms", true);
- perf_test::PrintResult("WriteBarrierPerfTest", " relative speed difference",
- "",
- during_gc_duration.InMillisecondsF() /
- outside_gc_duration.InMillisecondsF(),
- "times", true);
+ 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
new file mode 100644
index 00000000000..1c439a68ae8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap_observer_list.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_OBSERVER_LIST_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_OBSERVER_LIST_H_
+
+#include "base/auto_reset.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
+
+namespace blink {
+
+// A list of observers. Ensures list is not mutated while iterating. Observers
+// are not retained.
+template <class ObserverType>
+class PLATFORM_EXPORT HeapObserverList {
+ DISALLOW_NEW();
+
+ public:
+ // Add an observer to this list. An observer should not be added to the same
+ // list more than once.
+ void AddObserver(ObserverType* observer) {
+ CHECK(iteration_state_ & kAllowingAddition);
+ DCHECK(!HasObserver(observer));
+ observers_.insert(observer);
+ }
+
+ // Removes the given observer from this list. Does nothing if this observer is
+ // not in this list.
+ void RemoveObserver(ObserverType* observer) {
+ CHECK(iteration_state_ & kAllowingRemoval);
+ observers_.erase(observer);
+ }
+
+ // Determine whether a particular observer is in the list.
+ bool HasObserver(ObserverType* observer) const {
+ DCHECK(!IsIteratingOverObservers());
+ return observers_.Contains(observer);
+ }
+
+ // Returns true if the list is being iterated over.
+ bool IsIteratingOverObservers() const {
+ return iteration_state_ != kNotIterating;
+ }
+
+ // Removes all the observers from this list.
+ void Clear() {
+ CHECK(iteration_state_ & kAllowingRemoval);
+ observers_.clear();
+ }
+
+ // Safely iterate over the registered lifecycle observers.
+ //
+ // Adding or removing observers is not allowed during iteration. The callable
+ // will only be called synchronously inside ForEachObserver().
+ //
+ // Sample usage:
+ // ForEachObserver([](ObserverType* observer) {
+ // observer->SomeMethod();
+ // });
+ template <typename ForEachCallable>
+ void ForEachObserver(const ForEachCallable& callable) const {
+ base::AutoReset<IterationState> scope(&iteration_state_, kAllowingNone);
+ for (ObserverType* observer : observers_) {
+ callable(observer);
+ }
+ }
+
+ void Trace(Visitor* visitor) { visitor->Trace(observers_); }
+
+ private:
+ using ObserverSet = HeapLinkedHashSet<WeakMember<ObserverType>>;
+
+ // TODO(keishi): Clean up iteration state once transition from
+ // LifecycleObserver is complete.
+ enum IterationState {
+ kAllowingNone = 0,
+ kAllowingAddition = 1,
+ kAllowingRemoval = 1 << 1,
+ kNotIterating = kAllowingAddition | kAllowingRemoval,
+ };
+
+ // Iteration state is recorded while iterating the observer set,
+ // optionally barring add or remove mutations.
+ mutable IterationState iteration_state_ = kNotIterating;
+ ObserverSet observers_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_OBSERVER_LIST_H_
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
new file mode 100644
index 00000000000..1797cf0482f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap_observer_list_test.cc
@@ -0,0 +1,165 @@
+/*
+ * 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:
+ * 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.
+ *
+ */
+
+#include "third_party/blink/renderer/platform/heap_observer_list.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/heap/thread_state.h"
+
+namespace blink {
+
+class TestingObserver;
+
+class TestingNotifier final : public GarbageCollected<TestingNotifier> {
+ public:
+ TestingNotifier() = default;
+
+ HeapObserverList<TestingObserver>& ObserverList() { return observer_list_; }
+
+ void Trace(Visitor* visitor) { visitor->Trace(observer_list_); }
+
+ private:
+ HeapObserverList<TestingObserver> observer_list_;
+};
+
+class TestingObserver final : public GarbageCollected<TestingObserver> {
+ public:
+ TestingObserver() = default;
+ void OnNotification() { count_++; }
+ int Count() { return count_; }
+ void Trace(Visitor* visitor) {}
+
+ private:
+ int count_ = 0;
+};
+
+void Notify(HeapObserverList<TestingObserver>& observer_list) {
+ observer_list.ForEachObserver(
+ [](TestingObserver* observer) { observer->OnNotification(); });
+}
+
+TEST(HeapObserverListTest, AddRemove) {
+ Persistent<TestingNotifier> notifier =
+ MakeGarbageCollected<TestingNotifier>();
+ Persistent<TestingObserver> observer =
+ MakeGarbageCollected<TestingObserver>();
+
+ notifier->ObserverList().AddObserver(observer);
+
+ EXPECT_EQ(observer->Count(), 0);
+ Notify(notifier->ObserverList());
+ EXPECT_EQ(observer->Count(), 1);
+
+ notifier->ObserverList().RemoveObserver(observer);
+
+ Notify(notifier->ObserverList());
+ EXPECT_EQ(observer->Count(), 1);
+}
+
+TEST(HeapObserverListTest, HasObserver) {
+ Persistent<TestingNotifier> notifier =
+ MakeGarbageCollected<TestingNotifier>();
+ Persistent<TestingObserver> observer =
+ MakeGarbageCollected<TestingObserver>();
+
+ EXPECT_FALSE(notifier->ObserverList().HasObserver(observer));
+
+ notifier->ObserverList().AddObserver(observer);
+ EXPECT_TRUE(notifier->ObserverList().HasObserver(observer.Get()));
+
+ notifier->ObserverList().RemoveObserver(observer);
+ EXPECT_FALSE(notifier->ObserverList().HasObserver(observer.Get()));
+}
+
+TEST(HeapObserverListTest, GarbageCollect) {
+ Persistent<TestingNotifier> notifier =
+ MakeGarbageCollected<TestingNotifier>();
+ Persistent<TestingObserver> observer =
+ MakeGarbageCollected<TestingObserver>();
+ notifier->ObserverList().AddObserver(observer);
+
+ ThreadState::Current()->CollectAllGarbageForTesting();
+ Notify(notifier->ObserverList());
+ EXPECT_EQ(observer->Count(), 1);
+
+ WeakPersistent<TestingObserver> weak_ref = observer.Get();
+ observer = nullptr;
+ ThreadState::Current()->CollectAllGarbageForTesting();
+ EXPECT_EQ(weak_ref.Get(), nullptr);
+}
+
+TEST(HeapObserverListTest, IsIteratingOverObservers) {
+ Persistent<TestingNotifier> notifier =
+ MakeGarbageCollected<TestingNotifier>();
+ Persistent<TestingObserver> observer =
+ MakeGarbageCollected<TestingObserver>();
+ notifier->ObserverList().AddObserver(observer);
+
+ EXPECT_FALSE(notifier->ObserverList().IsIteratingOverObservers());
+ notifier->ObserverList().ForEachObserver([&](TestingObserver* observer) {
+ EXPECT_TRUE(notifier->ObserverList().IsIteratingOverObservers());
+ });
+}
+
+TEST(HeapObserverListTest, ForEachObserverOrder) {
+ Persistent<TestingNotifier> notifier =
+ MakeGarbageCollected<TestingNotifier>();
+ Persistent<TestingObserver> observer1 =
+ MakeGarbageCollected<TestingObserver>();
+ Persistent<TestingObserver> observer2 =
+ MakeGarbageCollected<TestingObserver>();
+
+ HeapVector<Member<TestingObserver>> seen_observers;
+
+ notifier->ObserverList().AddObserver(observer1);
+ notifier->ObserverList().AddObserver(observer2);
+ notifier->ObserverList().ForEachObserver(
+ [&](TestingObserver* observer) { seen_observers.push_back(observer); });
+
+ ASSERT_EQ(2u, seen_observers.size());
+ EXPECT_EQ(observer1.Get(), seen_observers[0].Get());
+ EXPECT_EQ(observer2.Get(), seen_observers[1].Get());
+
+ seen_observers.clear();
+
+ notifier->ObserverList().RemoveObserver(observer1);
+ notifier->ObserverList().AddObserver(observer1);
+ notifier->ObserverList().ForEachObserver(
+ [&](TestingObserver* observer) { seen_observers.push_back(observer); });
+
+ ASSERT_EQ(2u, seen_observers.size());
+ EXPECT_EQ(observer2.Get(), seen_observers[0].Get());
+ EXPECT_EQ(observer1.Get(), seen_observers[1].Get());
+
+ seen_observers.clear();
+
+ notifier->ObserverList().Clear();
+ notifier->ObserverList().ForEachObserver(
+ [&](TestingObserver* observer) { seen_observers.push_back(observer); });
+ ASSERT_EQ(0u, seen_observers.size());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/OWNERS b/chromium/third_party/blink/renderer/platform/image-decoders/OWNERS
index 9cf2710a1d5..f6310a37e22 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/OWNERS
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/OWNERS
@@ -1,6 +1,6 @@
urvang@chromium.org
pkasting@chromium.org
noel@chromium.org
-scroggo@chromium.org
+scroggo@google.com
# COMPONENT: Internals>Images>Codecs
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 f99b89349df..b5e12645ec5 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
@@ -261,9 +261,9 @@ class PLATFORM_EXPORT ImageDecoder {
// method, i.e., IsDecodedSizeAvailable() must return true.
virtual cc::ImageHeaderMetadata MakeMetadataForDecodeAcceleration() const;
- // This will only differ from size() for ICO (where each frame is a
+ // This will only differ from Size() for ICO (where each frame is a
// different icon) or other formats where different frames are different
- // sizes. This does NOT differ from size() for GIF or WebP, since
+ // sizes. This does NOT differ from Size() for GIF or WebP, since
// decoding GIF or WebP composites any smaller frames against previous
// frames to create full-size frames.
virtual IntSize FrameSizeAtIndex(size_t) const { return Size(); }
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/image_frame_test.cc b/chromium/third_party/blink/renderer/platform/image-decoders/image_frame_test.cc
index 37abdaf7376..ba51a4ba05b 100644
--- a/chromium/third_party/blink/renderer/platform/image-decoders/image_frame_test.cc
+++ b/chromium/third_party/blink/renderer/platform/image-decoders/image_frame_test.cc
@@ -26,9 +26,11 @@ class ImageFrameTest : public testing::Test {
src_8888 = SkPackARGB32(src_8888_a, src_8888_r, src_8888_g, src_8888_b);
dst_8888 = SkPackARGB32(0xA0, 0x60, 0x70, 0x80);
+#if SK_PMCOLOR_BYTE_ORDER(B, G, R, A)
+ pixel_format_n32 = skcms_PixelFormat_BGRA_8888;
+#else
pixel_format_n32 = skcms_PixelFormat_RGBA_8888;
- if (kN32_SkColorType == kRGBA_8888_SkColorType)
- pixel_format_n32 = skcms_PixelFormat_BGRA_8888;
+#endif
skcms_Transform(&src_8888, pixel_format_n32, skcms_AlphaFormat_Unpremul,
nullptr, &src_f16, skcms_PixelFormat_RGBA_hhhh,
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 7c01efc1273..1a7ed7d26d2 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
@@ -892,6 +892,8 @@ bool JPEGImageDecoder::SetSize(unsigned width, unsigned height) {
}
void JPEGImageDecoder::OnSetData(SegmentReader* data) {
+ if (reader_)
+ reader_->SetData(data);
// TODO(crbug.com/943519): Incremental YUV decoding is not currently
// supported.
if (IsAllDataReceived()) {
@@ -903,8 +905,6 @@ void JPEGImageDecoder::OnSetData(SegmentReader* data) {
allow_decode_to_yuv_ &=
IsSizeAvailable() && reader_->Info()->out_color_space == JCS_YCbCr;
}
- if (reader_)
- reader_->SetData(data);
}
void JPEGImageDecoder::SetDecodedSize(unsigned width, unsigned height) {
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 a82cb44e183..a25603243b9 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
@@ -49,10 +49,13 @@ static const size_t kLargeEnoughSize = 1000 * 1000;
namespace {
-std::unique_ptr<JPEGImageDecoder> CreateJPEGDecoder(size_t max_decoded_bytes) {
+std::unique_ptr<JPEGImageDecoder> CreateJPEGDecoder(
+ size_t max_decoded_bytes,
+ ImageDecoder::OverrideAllowDecodeToYuv decodeToYUV =
+ ImageDecoder::OverrideAllowDecodeToYuv::kDeny) {
return std::make_unique<JPEGImageDecoder>(
ImageDecoder::kAlphaNotPremultiplied, ColorBehavior::TransformToSRGB(),
- max_decoded_bytes, ImageDecoder::OverrideAllowDecodeToYuv::kDefault);
+ max_decoded_bytes, decodeToYUV);
}
std::unique_ptr<ImageDecoder> CreateJPEGDecoder() {
@@ -87,8 +90,8 @@ void ReadYUV(size_t max_decoded_bytes,
scoped_refptr<SharedBuffer> data = ReadFile(image_file_path);
ASSERT_TRUE(data);
- std::unique_ptr<JPEGImageDecoder> decoder =
- CreateJPEGDecoder(max_decoded_bytes);
+ std::unique_ptr<JPEGImageDecoder> decoder = CreateJPEGDecoder(
+ max_decoded_bytes, ImageDecoder::OverrideAllowDecodeToYuv::kDefault);
decoder->SetDecodeToYuvForTesting(true);
decoder->SetData(data.get(), true);
@@ -274,7 +277,8 @@ TEST(JPEGImageDecoderTest, yuv) {
scoped_refptr<SharedBuffer> data = ReadFile(jpeg_file);
ASSERT_TRUE(data);
- std::unique_ptr<JPEGImageDecoder> decoder = CreateJPEGDecoder(230 * 230 * 4);
+ std::unique_ptr<JPEGImageDecoder> decoder = CreateJPEGDecoder(
+ 230 * 230 * 4, ImageDecoder::OverrideAllowDecodeToYuv::kDefault);
decoder->SetDecodeToYuvForTesting(true);
decoder->SetData(data.get(), true);
@@ -552,4 +556,23 @@ INSTANTIATE_TEST_SUITE_P(JPEGImageDecoderTest,
ColorSpaceUMATest,
::testing::ValuesIn(kColorSpaceUMATestParams));
+TEST(JPEGImageDecoderTest, PartialDataWithoutSize) {
+ const char* jpeg_file = "/images/resources/lenna.jpg";
+ scoped_refptr<SharedBuffer> full_data = ReadFile(jpeg_file);
+ ASSERT_TRUE(full_data);
+
+ constexpr size_t kDataLengthWithoutSize = 4;
+ ASSERT_LT(kDataLengthWithoutSize, full_data->size());
+ scoped_refptr<SharedBuffer> partial_data =
+ SharedBuffer::Create(full_data->Data(), kDataLengthWithoutSize);
+
+ std::unique_ptr<ImageDecoder> decoder = CreateJPEGDecoder();
+ decoder->SetData(partial_data.get(), false);
+ EXPECT_FALSE(decoder->IsSizeAvailable());
+ EXPECT_FALSE(decoder->Failed());
+ decoder->SetData(full_data.get(), true);
+ EXPECT_TRUE(decoder->IsSizeAvailable());
+ EXPECT_FALSE(decoder->Failed());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder_utils.cc b/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder_utils.cc
index 7ecb3436e48..97cf9c92a25 100644
--- a/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder_utils.cc
+++ b/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder_utils.cc
@@ -33,7 +33,7 @@ enum RequestedImageMimeType {
ImageEncodingMimeType ImageEncoderUtils::ToEncodingMimeType(
const String& mime_type_name,
const EncodeReason encode_reason) {
- String lowercase_mime_type = mime_type_name.DeprecatedLower();
+ String lowercase_mime_type = mime_type_name.LowerASCII();
RequestedImageMimeType requested_mime_type;
if (mime_type_name.IsNull())
diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/instance_counters.h b/chromium/third_party/blink/renderer/platform/instrumentation/instance_counters.h
index 7ccf114c838..6a3443121a5 100644
--- a/chromium/third_party/blink/renderer/platform/instrumentation/instance_counters.h
+++ b/chromium/third_party/blink/renderer/platform/instrumentation/instance_counters.h
@@ -38,33 +38,24 @@
namespace blink {
-#define INSTANCE_COUNTERS_LIST(V) \
- V(AudioHandler) \
- V(Document) \
- V(Frame) \
- V(JSEventListener) \
- V(LayoutObject) \
- V(MediaKeySession) \
- V(MediaKeys) \
- V(Node) \
- V(Resource) \
- V(ContextLifecycleStateObserver) \
- V(V8PerContextData) \
- V(WorkerGlobalScope) \
- V(UACSSResource) \
- V(RTCPeerConnection) \
- V(ResourceFetcher) \
- V(AdSubframe) \
- V(DetachedScriptState) \
- V(V8CallInDetachedWindowByNavigation) \
- V(V8CallInDetachedWindowByNavigationAfter10s) \
- V(V8CallInDetachedWindowByNavigationAfter1min) \
- V(V8CallInDetachedWindowByClosing) \
- V(V8CallInDetachedWindowByClosingAfter10s) \
- V(V8CallInDetachedWindowByClosingAfter1min) \
- V(V8CallInDetachedWindowByOtherReason) \
- V(V8CallInDetachedWindowByOtherReasonAfter10s) \
- V(V8CallInDetachedWindowByOtherReasonAfter1min)
+#define INSTANCE_COUNTERS_LIST(V) \
+ V(AudioHandler) \
+ V(Document) \
+ V(Frame) \
+ V(JSEventListener) \
+ V(LayoutObject) \
+ V(MediaKeySession) \
+ V(MediaKeys) \
+ V(Node) \
+ V(Resource) \
+ V(ContextLifecycleStateObserver) \
+ V(V8PerContextData) \
+ V(WorkerGlobalScope) \
+ V(UACSSResource) \
+ V(RTCPeerConnection) \
+ V(ResourceFetcher) \
+ V(AdSubframe) \
+ V(DetachedScriptState)
// Atomic counters of the number of instances of objects that exist.
//
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 074c7272786..8db183664dc 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
@@ -7,6 +7,7 @@
#include "base/allocator/partition_allocator/memory_reclaimer.h"
#include "base/feature_list.h"
#include "base/system/sys_info.h"
+#include "base/trace_event/common/trace_event_common.h"
#include "build/build_config.h"
#include "third_party/blink/public/common/device_memory/approximated_device_memory.h"
#include "third_party/blink/public/common/features.h"
@@ -100,7 +101,8 @@ void MemoryPressureListenerRegistry::UnregisterClient(
void MemoryPressureListenerRegistry::OnMemoryPressure(
WebMemoryPressureLevel level) {
- TRACE_EVENT0("blink", "MemoryPressureListenerRegistry::onMemoryPressure");
+ TRACE_EVENT1("blink", "MemoryPressureListenerRegistry::onMemoryPressure",
+ "level", level);
CHECK(IsMainThread());
for (auto& client : clients_)
client->OnMemoryPressure(level);
@@ -131,7 +133,7 @@ void MemoryPressureListenerRegistry::ClearThreadSpecificMemory() {
FontGlobalContext::ClearMemory();
}
-void MemoryPressureListenerRegistry::Trace(blink::Visitor* visitor) {
+void MemoryPressureListenerRegistry::Trace(Visitor* visitor) {
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 9bab204ceeb..cc24601b37a 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
@@ -31,7 +31,9 @@ class PLATFORM_EXPORT MemoryPressureListenerRegistry final
public:
static MemoryPressureListenerRegistry& Instance();
- // Whether the device Blink runs on is a low-end device.
+ // See: SysUtils::IsLowEndDevice for the full details of what "low-end" means.
+ // This returns true for devices that can use more extreme tradeoffs for
+ // performance. Many low memory devices (<=1GB) are not considered low-end.
// Can be overridden in web tests via internals.
static bool IsLowEndDevice();
@@ -57,7 +59,7 @@ class PLATFORM_EXPORT MemoryPressureListenerRegistry final
void OnPurgeMemory();
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
friend class Internals;
diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.cc b/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.cc
index 93e6ae85dba..9991d6abb44 100644
--- a/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.cc
+++ b/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.cc
@@ -63,4 +63,13 @@ void DocumentResourceCoordinator::OnNonPersistentNotificationCreated() {
service_->OnNonPersistentNotificationCreated();
}
+void DocumentResourceCoordinator::SetHadFormInteraction() {
+ // Only send this signal for the first interaction as it doesn't get cleared
+ // for the lifetime of the frame and it's inefficient to send this message
+ // for every keystroke.
+ if (!had_form_interaction_)
+ service_->SetHadFormInteraction();
+ had_form_interaction_ = true;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.h b/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.h
index 5d0ee9e07fd..73797f732ca 100644
--- a/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.h
+++ b/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.h
@@ -34,6 +34,7 @@ class PLATFORM_EXPORT DocumentResourceCoordinator final {
// A one way switch that marks a frame as being an adframe.
void SetIsAdFrame();
void OnNonPersistentNotificationCreated();
+ void SetHadFormInteraction();
private:
explicit DocumentResourceCoordinator(const BrowserInterfaceBrokerProxy&);
@@ -41,6 +42,8 @@ class PLATFORM_EXPORT DocumentResourceCoordinator final {
mojo::Remote<performance_manager::mojom::blink::DocumentCoordinationUnit>
service_;
+ bool had_form_interaction_ = false;
+
DISALLOW_COPY_AND_ASSIGN(DocumentResourceCoordinator);
};
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 f94bc634a74..37ca752b695 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(blink::Visitor* visitor) {}
+void MemoryCacheDumpClient::Trace(Visitor* visitor) {}
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 c99c5dc3e6d..e996a368083 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
};
// This class is wrapper around MemoryCache to take memory snapshots. It dumps
diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/traced_value.cc b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/traced_value.cc
index 6d75c7dfc91..c36eafdad5d 100644
--- a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/traced_value.cc
+++ b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/traced_value.cc
@@ -12,113 +12,128 @@
namespace blink {
-TracedValue::TracedValue() = default;
+TracedValue::TracedValue()
+ : TracedValue(std::make_unique<base::trace_event::TracedValue>()) {}
TracedValue::~TracedValue() = default;
void TracedValue::SetInteger(const char* name, int value) {
- traced_value_.SetInteger(name, value);
+ traced_value_->SetInteger(name, value);
}
void TracedValue::SetIntegerWithCopiedName(const char* name, int value) {
- traced_value_.SetIntegerWithCopiedName(name, value);
+ traced_value_->SetIntegerWithCopiedName(name, value);
}
void TracedValue::SetDouble(const char* name, double value) {
- traced_value_.SetDouble(name, value);
+ traced_value_->SetDouble(name, value);
}
void TracedValue::SetDoubleWithCopiedName(const char* name, double value) {
- traced_value_.SetDoubleWithCopiedName(name, value);
+ traced_value_->SetDoubleWithCopiedName(name, value);
}
void TracedValue::SetBoolean(const char* name, bool value) {
- traced_value_.SetBoolean(name, value);
+ traced_value_->SetBoolean(name, value);
}
void TracedValue::SetBooleanWithCopiedName(const char* name, bool value) {
- traced_value_.SetBooleanWithCopiedName(name, value);
+ traced_value_->SetBooleanWithCopiedName(name, value);
}
void TracedValue::SetString(const char* name, const String& value) {
StringUTF8Adaptor adaptor(value);
- traced_value_.SetString(name, adaptor.AsStringPiece());
+ traced_value_->SetString(name, adaptor.AsStringPiece());
}
void TracedValue::SetValue(const char* name, TracedValue* value) {
- traced_value_.SetValue(name, &value->traced_value_);
+ traced_value_->SetValue(name, value->traced_value_.get());
}
void TracedValue::SetStringWithCopiedName(const char* name,
const String& value) {
StringUTF8Adaptor adaptor(value);
- traced_value_.SetStringWithCopiedName(name, adaptor.AsStringPiece());
+ traced_value_->SetStringWithCopiedName(name, adaptor.AsStringPiece());
}
void TracedValue::BeginDictionary(const char* name) {
- traced_value_.BeginDictionary(name);
+ traced_value_->BeginDictionary(name);
}
void TracedValue::BeginDictionaryWithCopiedName(const char* name) {
- traced_value_.BeginDictionaryWithCopiedName(name);
+ traced_value_->BeginDictionaryWithCopiedName(name);
}
void TracedValue::BeginArray(const char* name) {
- traced_value_.BeginArray(name);
+ traced_value_->BeginArray(name);
}
void TracedValue::BeginArrayWithCopiedName(const char* name) {
- traced_value_.BeginArrayWithCopiedName(name);
+ traced_value_->BeginArrayWithCopiedName(name);
}
void TracedValue::EndDictionary() {
- traced_value_.EndDictionary();
+ traced_value_->EndDictionary();
}
void TracedValue::PushInteger(int value) {
- traced_value_.AppendInteger(value);
+ traced_value_->AppendInteger(value);
}
void TracedValue::PushDouble(double value) {
- traced_value_.AppendDouble(value);
+ traced_value_->AppendDouble(value);
}
void TracedValue::PushBoolean(bool value) {
- traced_value_.AppendBoolean(value);
+ traced_value_->AppendBoolean(value);
}
void TracedValue::PushString(const String& value) {
StringUTF8Adaptor adaptor(value);
- traced_value_.AppendString(adaptor.AsStringPiece());
+ traced_value_->AppendString(adaptor.AsStringPiece());
}
void TracedValue::BeginArray() {
- traced_value_.BeginArray();
+ traced_value_->BeginArray();
}
void TracedValue::BeginDictionary() {
- traced_value_.BeginDictionary();
+ traced_value_->BeginDictionary();
}
void TracedValue::EndArray() {
- traced_value_.EndArray();
-}
-
-String TracedValue::ToString() const {
- return String(traced_value_.ToString().c_str());
+ traced_value_->EndArray();
}
void TracedValue::AppendAsTraceFormat(std::string* out) const {
- traced_value_.AppendAsTraceFormat(out);
+ traced_value_->AppendAsTraceFormat(out);
}
bool TracedValue::AppendToProto(ProtoAppender* appender) {
- return traced_value_.AppendToProto(appender);
+ return traced_value_->AppendToProto(appender);
}
void TracedValue::EstimateTraceMemoryOverhead(
base::trace_event::TraceEventMemoryOverhead* overhead) {
- traced_value_.EstimateTraceMemoryOverhead(overhead);
+ traced_value_->EstimateTraceMemoryOverhead(overhead);
+}
+
+TracedValueJSON::TracedValueJSON()
+ : TracedValue(std::make_unique<base::trace_event::TracedValueJSON>()) {}
+TracedValueJSON::~TracedValueJSON() = default;
+
+String TracedValueJSON::ToJSON() const {
+ return String(
+ static_cast<base::trace_event::TracedValueJSON*>(traced_value_.get())
+ ->ToJSON()
+ .c_str());
+}
+
+String TracedValueJSON::ToFormattedJSON() const {
+ return String(
+ static_cast<base::trace_event::TracedValueJSON*>(traced_value_.get())
+ ->ToFormattedJSON()
+ .c_str());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h
index d496bf52855..effbd5f6857 100644
--- a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h
+++ b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h
@@ -5,6 +5,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_INSTRUMENTATION_TRACING_TRACED_VALUE_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_INSTRUMENTATION_TRACING_TRACED_VALUE_H_
+#include <memory>
+#include <string>
+
#include "base/macros.h"
#include "base/trace_event/traced_value.h"
#include "third_party/blink/renderer/platform/platform_export.h"
@@ -13,7 +16,7 @@
namespace blink {
// Thin wrapper around base::trace_event::TracedValue.
-class PLATFORM_EXPORT TracedValue final
+class PLATFORM_EXPORT TracedValue
: public base::trace_event::ConvertableToTraceFormat {
public:
TracedValue();
@@ -44,21 +47,32 @@ class PLATFORM_EXPORT TracedValue final
void BeginArray();
void BeginDictionary();
- String ToString() const;
+ protected:
+ explicit TracedValue(
+ std::unique_ptr<base::trace_event::TracedValue> traced_value)
+ : traced_value_(std::move(traced_value)) {}
+ std::unique_ptr<base::trace_event::TracedValue> traced_value_;
private:
// ConvertableToTraceFormat
-
void AppendAsTraceFormat(std::string*) const final;
bool AppendToProto(ProtoAppender* appender) final;
void EstimateTraceMemoryOverhead(
base::trace_event::TraceEventMemoryOverhead*) final;
- base::trace_event::TracedValue traced_value_;
-
DISALLOW_COPY_AND_ASSIGN(TracedValue);
};
+// Thin wrapper around base::trace_event::TracedValueJSON.
+class PLATFORM_EXPORT TracedValueJSON final : public TracedValue {
+ public:
+ TracedValueJSON();
+ ~TracedValueJSON() final;
+
+ String ToJSON() const;
+ String ToFormattedJSON() const;
+};
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_INSTRUMENTATION_TRACING_TRACED_VALUE_H_
diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/traced_value_test.cc b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/traced_value_test.cc
index ee380f810b6..3544b8cf0e6 100644
--- a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/traced_value_test.cc
+++ b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/traced_value_test.cc
@@ -4,27 +4,27 @@
#include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h"
+#include <utility>
+
#include "base/json/json_reader.h"
#include "base/values.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include <memory>
namespace blink {
-std::unique_ptr<base::Value> ParseTracedValue(
- std::unique_ptr<TracedValue> value) {
- base::JSONReader reader;
- return reader.ReadDeprecated(value->ToString().Utf8());
+base::Optional<base::Value> ParseTracedValue(
+ std::unique_ptr<TracedValueJSON> value) {
+ return base::JSONReader::Read(value->ToJSON().Utf8());
}
TEST(TracedValueTest, FlatDictionary) {
- auto value = std::make_unique<TracedValue>();
+ auto value = std::make_unique<TracedValueJSON>();
value->SetIntegerWithCopiedName("int", 2014);
value->SetDoubleWithCopiedName("double", 0.0);
value->SetBooleanWithCopiedName("bool", true);
value->SetStringWithCopiedName("string", "string");
- std::unique_ptr<base::Value> parsed = ParseTracedValue(std::move(value));
+ base::Optional<base::Value> parsed = ParseTracedValue(std::move(value));
base::DictionaryValue* dictionary;
ASSERT_TRUE(parsed->GetAsDictionary(&dictionary));
int int_value;
@@ -39,7 +39,7 @@ TEST(TracedValueTest, FlatDictionary) {
}
TEST(TracedValueTest, Hierarchy) {
- auto value = std::make_unique<TracedValue>();
+ auto value = std::make_unique<TracedValueJSON>();
value->SetIntegerWithCopiedName("i0", 2014);
value->BeginDictionaryWithCopiedName("dict1");
value->SetIntegerWithCopiedName("i1", 2014);
@@ -59,7 +59,7 @@ TEST(TracedValueTest, Hierarchy) {
value->EndArray();
value->SetStringWithCopiedName("s0", "foo");
- std::unique_ptr<base::Value> parsed = ParseTracedValue(std::move(value));
+ base::Optional<base::Value> parsed = ParseTracedValue(std::move(value));
base::DictionaryValue* dictionary;
ASSERT_TRUE(parsed->GetAsDictionary(&dictionary));
int i0;
@@ -99,14 +99,14 @@ TEST(TracedValueTest, Hierarchy) {
}
TEST(TracedValueTest, Escape) {
- auto value = std::make_unique<TracedValue>();
+ auto value = std::make_unique<TracedValueJSON>();
value->SetStringWithCopiedName("s0", "value0\\");
value->SetStringWithCopiedName("s1", "value\n1");
value->SetStringWithCopiedName("s2", "\"value2\"");
value->SetStringWithCopiedName("s3\\", "value3");
value->SetStringWithCopiedName("\"s4\"", "value4");
- std::unique_ptr<base::Value> parsed = ParseTracedValue(std::move(value));
+ base::Optional<base::Value> parsed = ParseTracedValue(std::move(value));
base::DictionaryValue* dictionary;
ASSERT_TRUE(parsed->GetAsDictionary(&dictionary));
std::string s0;
@@ -127,7 +127,7 @@ TEST(TracedValueTest, Escape) {
}
TEST(TracedValueTest, NonCopiedNames) {
- auto value = std::make_unique<TracedValue>();
+ auto value = std::make_unique<TracedValueJSON>();
const char* int_str = "int";
const char* double_str = "double";
const char* bool_str = "bool";
@@ -142,7 +142,7 @@ TEST(TracedValueTest, NonCopiedNames) {
value->PushInteger(2);
value->EndArray();
- std::unique_ptr<base::Value> parsed = ParseTracedValue(std::move(value));
+ base::Optional<base::Value> parsed = ParseTracedValue(std::move(value));
base::DictionaryValue* dictionary;
ASSERT_TRUE(parsed->GetAsDictionary(&dictionary));
int int_value;
diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.cc b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.cc
index e1e24170879..54c702cb6e2 100644
--- a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.cc
+++ b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.cc
@@ -14,8 +14,6 @@ WebMemoryAllocatorDump::WebMemoryAllocatorDump(
: memory_allocator_dump_(memory_allocator_dump),
guid_(memory_allocator_dump->guid().ToUint64()) {}
-WebMemoryAllocatorDump::~WebMemoryAllocatorDump() = default;
-
void WebMemoryAllocatorDump::AddScalar(const char* name,
const char* units,
uint64_t value) {
diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.h b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.h
index a9af22ee206..75180ada990 100644
--- a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.h
+++ b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.h
@@ -30,7 +30,6 @@ class PLATFORM_EXPORT WebMemoryAllocatorDump final {
public:
explicit WebMemoryAllocatorDump(
base::trace_event::MemoryAllocatorDump* memory_allocator_dump);
- ~WebMemoryAllocatorDump();
// Adds a scalar attribute to the dump.
// Arguments:
diff --git a/chromium/third_party/blink/renderer/platform/lifecycle_context_test.cc b/chromium/third_party/blink/renderer/platform/lifecycle_context_test.cc
deleted file mode 100644
index 94a9886d12b..00000000000
--- a/chromium/third_party/blink/renderer/platform/lifecycle_context_test.cc
+++ /dev/null
@@ -1,192 +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:
- * 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.
- *
- */
-
-#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/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"
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/lifecycle_notifier.h"
-#include "third_party/blink/renderer/platform/lifecycle_observer.h"
-#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
-
-namespace blink {
-
-class TestingObserver;
-
-class DummyContext final
- : public GarbageCollected<DummyContext>,
- public LifecycleNotifier<DummyContext, TestingObserver> {
- USING_GARBAGE_COLLECTED_MIXIN(DummyContext);
-
- public:
- void Trace(blink::Visitor* visitor) override {
- LifecycleNotifier<DummyContext, TestingObserver>::Trace(visitor);
- }
-
- // Make the protected method public for testing.
- using LifecycleNotifier<DummyContext, TestingObserver>::ForEachObserver;
-};
-
-class TestingObserver final
- : public GarbageCollected<TestingObserver>,
- public LifecycleObserver<DummyContext, TestingObserver> {
- USING_GARBAGE_COLLECTED_MIXIN(TestingObserver);
-
- public:
- explicit TestingObserver(DummyContext* context)
- : LifecycleObserver(context), context_destroyed_called_(false) {}
-
- void ContextDestroyed(DummyContext* destroyed_context) {
- if (observer_to_remove_on_destruct_) {
- destroyed_context->RemoveObserver(observer_to_remove_on_destruct_);
- observer_to_remove_on_destruct_.Clear();
- }
- context_destroyed_called_ = true;
- }
-
- void Trace(blink::Visitor* visitor) override {
- visitor->Trace(observer_to_remove_on_destruct_);
- LifecycleObserver::Trace(visitor);
- }
-
- void Unobserve() { SetContext(nullptr); }
-
- void SetObserverToRemoveAndDestroy(
- TestingObserver* observer_to_remove_on_destruct) {
- DCHECK(!observer_to_remove_on_destruct_);
- observer_to_remove_on_destruct_ = observer_to_remove_on_destruct;
- }
-
- TestingObserver* InnerObserver() const {
- return observer_to_remove_on_destruct_;
- }
- bool ContextDestroyedCalled() const { return context_destroyed_called_; }
-
- private:
- Member<TestingObserver> observer_to_remove_on_destruct_;
- bool context_destroyed_called_;
-};
-
-TEST(LifecycleContextTest, ShouldObserveContextDestroyed) {
- auto* context = MakeGarbageCollected<DummyContext>();
- Persistent<TestingObserver> observer =
- MakeGarbageCollected<TestingObserver>(context);
-
- EXPECT_EQ(observer->LifecycleContext(), context);
- EXPECT_FALSE(observer->ContextDestroyedCalled());
- context->NotifyContextDestroyed();
- context = nullptr;
- ThreadState::Current()->CollectAllGarbageForTesting();
- EXPECT_EQ(observer->LifecycleContext(), static_cast<DummyContext*>(nullptr));
- EXPECT_TRUE(observer->ContextDestroyedCalled());
-}
-
-TEST(LifecycleContextTest, ShouldNotObserveContextDestroyedIfUnobserve) {
- auto* context = MakeGarbageCollected<DummyContext>();
- Persistent<TestingObserver> observer =
- MakeGarbageCollected<TestingObserver>(context);
- observer->Unobserve();
- context->NotifyContextDestroyed();
- context = nullptr;
- ThreadState::Current()->CollectAllGarbageForTesting();
- EXPECT_EQ(observer->LifecycleContext(), static_cast<DummyContext*>(nullptr));
- EXPECT_FALSE(observer->ContextDestroyedCalled());
-}
-
-TEST(LifecycleContextTest, ObserverRemovedDuringNotifyDestroyed) {
- auto* context = MakeGarbageCollected<DummyContext>();
- Persistent<TestingObserver> observer =
- MakeGarbageCollected<TestingObserver>(context);
- auto* inner_observer = MakeGarbageCollected<TestingObserver>(context);
- // Attach the observer to the other. When 'observer' is notified
- // of destruction, it will remove & destroy 'innerObserver'.
- observer->SetObserverToRemoveAndDestroy(inner_observer);
-
- EXPECT_EQ(observer->LifecycleContext(), context);
- EXPECT_EQ(observer->InnerObserver()->LifecycleContext(), context);
- EXPECT_FALSE(observer->ContextDestroyedCalled());
- EXPECT_FALSE(observer->InnerObserver()->ContextDestroyedCalled());
-
- context->NotifyContextDestroyed();
- EXPECT_EQ(observer->InnerObserver(), nullptr);
- context = nullptr;
- ThreadState::Current()->CollectAllGarbageForTesting();
- EXPECT_EQ(observer->LifecycleContext(), static_cast<DummyContext*>(nullptr));
- EXPECT_TRUE(observer->ContextDestroyedCalled());
-}
-
-// This is a regression test for http://crbug.com/854639.
-TEST(LifecycleContextTest, ShouldNotHitCFICheckOnIncrementalMarking) {
- base::test::ScopedFeatureList scoped_feature_list;
- // Disable concurrent marking and concurrent sweeping as worker_pool task
- // environment is not set.
- scoped_feature_list.InitWithFeatures(
- {blink::features::kBlinkHeapIncrementalMarking},
- {blink::features::kBlinkHeapConcurrentMarking,
- blink::features::kBlinkHeapConcurrentSweeping});
- IncrementalMarkingTestDriver driver(ThreadState::Current());
- driver.Start();
-
- auto* context = MakeGarbageCollected<DummyContext>();
-
- // This should not cause a CFI check failure.
- Persistent<TestingObserver> observer =
- MakeGarbageCollected<TestingObserver>(context);
-
- EXPECT_FALSE(observer->ContextDestroyedCalled());
- context->NotifyContextDestroyed();
- EXPECT_TRUE(observer->ContextDestroyedCalled());
- context = nullptr;
-
- driver.FinishGC();
-}
-
-TEST(LifecycleContextTest, ForEachObserver) {
- Persistent<DummyContext> context = MakeGarbageCollected<DummyContext>();
- Persistent<TestingObserver> observer =
- MakeGarbageCollected<TestingObserver>(context);
-
- HeapVector<Member<TestingObserver>> seen_observers;
- context->ForEachObserver(
- [&](TestingObserver* observer) { seen_observers.push_back(observer); });
-
- ASSERT_EQ(1u, seen_observers.size());
- EXPECT_EQ(observer.Get(), seen_observers[0].Get());
-
- seen_observers.clear();
- observer.Clear();
- ThreadState::Current()->CollectAllGarbageForTesting();
-
- context->ForEachObserver(
- [&](TestingObserver* observer) { seen_observers.push_back(observer); });
- ASSERT_EQ(0u, seen_observers.size());
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/lifecycle_notifier.h b/chromium/third_party/blink/renderer/platform/lifecycle_notifier.h
deleted file mode 100644
index d105761b4b8..00000000000
--- a/chromium/third_party/blink/renderer/platform/lifecycle_notifier.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- * 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:
- * 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_PLATFORM_LIFECYCLE_NOTIFIER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LIFECYCLE_NOTIFIER_H_
-
-#include "base/auto_reset.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
-
-namespace blink {
-
-class LifecycleObserverBase;
-
-template <typename T, typename Observer>
-class LifecycleNotifier : public GarbageCollectedMixin {
- public:
- virtual ~LifecycleNotifier();
-
- void AddObserver(LifecycleObserverBase*);
- void RemoveObserver(LifecycleObserverBase*);
-
- // NotifyContextDestroyed() should be explicitly dispatched from an
- // observed context to detach its observers and, if the observer kind
- // requires it, notify each observer by invoking ContextDestroyed().
- //
- // When ContextDestroyed() is called, it is supplied the context as
- // an argument, but the observer's LifecycleContext() is still valid
- // and safe to use while handling the notification.
- virtual void NotifyContextDestroyed();
-
- void Trace(blink::Visitor* visitor) override { visitor->Trace(observers_); }
-
- bool IsIteratingOverObservers() const {
- return iteration_state_ != kNotIterating;
- }
-
- protected:
- LifecycleNotifier() : iteration_state_(kNotIterating) {}
-
- T* Context() { return static_cast<T*>(this); }
-
- // Safely iterate over the registered lifecycle observers.
- //
- // Adding or removing observers is not allowed during iteration. The callable
- // will only be called synchronously inside ForEachObserver().
- //
- // Sample usage:
- // ForEachObserver([](ObserverType* observer) {
- // observer->SomeMethod();
- // });
- template <typename ForEachCallable>
- void ForEachObserver(const ForEachCallable& callable) const {
- base::AutoReset<IterationState> scope(&iteration_state_, kAllowingNone);
- for (LifecycleObserverBase* observer_base : observers_) {
- Observer* observer = static_cast<Observer*>(observer_base);
- callable(observer);
- }
- }
-
- private:
- using ObserverSet = HeapLinkedHashSet<WeakMember<LifecycleObserverBase>>;
-
- enum IterationState {
- kAllowingNone = 0,
- kAllowingAddition = 1,
- kAllowingRemoval = 2,
- kNotIterating = kAllowingAddition | kAllowingRemoval,
- };
-
- // Iteration state is recorded while iterating the observer set,
- // optionally barring add or remove mutations.
- mutable IterationState iteration_state_;
- ObserverSet observers_;
-};
-
-template <typename T, typename Observer>
-inline LifecycleNotifier<T, Observer>::~LifecycleNotifier() {
- // FIXME: Enable the following ASSERT. Also see a FIXME in
- // Document::detachLayoutTree().
- // DCHECK(!m_observers.size());
-}
-
-// Determine if |contextDestroyed(Observer*) is a public method on
-// class type |Observer|, or any of the class types it derives from.
-template <typename Observer, typename T>
-class HasContextDestroyed {
- using YesType = char;
- using NoType = int;
-
- template <typename V>
- static YesType CheckHasContextDestroyedMethod(
- V* observer,
- T* context = nullptr,
- typename std::enable_if<
- std::is_same<decltype(observer->ContextDestroyed(context)),
- void>::value>::type* g = nullptr);
- template <typename V>
- static NoType CheckHasContextDestroyedMethod(...);
-
- public:
- static_assert(sizeof(Observer), "Observer's class declaration not in scope");
- static const bool value =
- sizeof(YesType) ==
- sizeof(CheckHasContextDestroyedMethod<Observer>(nullptr));
-};
-
-// If |Observer::contextDestroyed()| is present, invoke it.
-template <typename Observer,
- typename T,
- bool = HasContextDestroyed<Observer, T>::value>
-class ContextDestroyedNotifier {
- STATIC_ONLY(ContextDestroyedNotifier);
-
- public:
- static void Call(Observer* observer, T* context) {
- observer->ContextDestroyed(context);
- }
-};
-
-template <typename Observer, typename T>
-class ContextDestroyedNotifier<Observer, T, false> {
- STATIC_ONLY(ContextDestroyedNotifier);
-
- public:
- static void Call(Observer*, T*) {}
-};
-
-template <typename T, typename Observer>
-inline void LifecycleNotifier<T, Observer>::NotifyContextDestroyed() {
- // Observer unregistration is allowed, but effectively a no-op.
- base::AutoReset<IterationState> scope(&iteration_state_, kAllowingRemoval);
- ObserverSet observers;
- observers_.Swap(observers);
- for (LifecycleObserverBase* observer_base : observers) {
- Observer* observer = static_cast<Observer*>(observer_base);
- DCHECK(observer->LifecycleContext() == Context());
- ContextDestroyedNotifier<Observer, T>::Call(observer, Context());
- observer->ClearContext();
- }
- // Explicitly free the backing store to avoid memory regressions.
- // TODO(bikineev): Revisit after young generation is done.
- observers.clear();
-}
-
-template <typename T, typename Observer>
-inline void LifecycleNotifier<T, Observer>::AddObserver(
- LifecycleObserverBase* observer) {
- CHECK(iteration_state_ & kAllowingAddition);
- observers_.insert(observer);
-}
-
-template <typename T, typename Observer>
-inline void LifecycleNotifier<T, Observer>::RemoveObserver(
- LifecycleObserverBase* observer) {
- CHECK(iteration_state_ & kAllowingRemoval);
- observers_.erase(observer);
-}
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_LIFECYCLE_NOTIFIER_H_
diff --git a/chromium/third_party/blink/renderer/platform/lifecycle_observer.h b/chromium/third_party/blink/renderer/platform/lifecycle_observer.h
deleted file mode 100644
index 491550573f6..00000000000
--- a/chromium/third_party/blink/renderer/platform/lifecycle_observer.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2008 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_PLATFORM_LIFECYCLE_OBSERVER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LIFECYCLE_OBSERVER_H_
-
-#include "third_party/blink/renderer/platform/heap/handle.h"
-
-namespace blink {
-
-template <typename Context, typename Observer>
-class LifecycleNotifier;
-
-class LifecycleObserverBase : public GarbageCollectedMixin {};
-
-template <typename Context, typename Observer>
-class LifecycleObserver : public LifecycleObserverBase {
- public:
- void Trace(blink::Visitor* visitor) override {
- visitor->Trace(lifecycle_context_);
- }
-
- Context* LifecycleContext() const { return lifecycle_context_; }
-
- void ClearContext() { SetContext(nullptr); }
-
- protected:
- explicit LifecycleObserver(Context* context) : lifecycle_context_(nullptr) {
- SetContext(context);
- }
-
- void SetContext(Context*);
-
- private:
- WeakMember<Context> lifecycle_context_;
-};
-
-template <typename Context, typename Observer>
-inline void LifecycleObserver<Context, Observer>::SetContext(Context* context) {
- using Notifier = LifecycleNotifier<Context, Observer>;
-
- if (lifecycle_context_ == context)
- return;
-
- if (lifecycle_context_) {
- static_cast<Notifier*>(lifecycle_context_)->RemoveObserver(this);
- }
-
- lifecycle_context_ = context;
-
- if (lifecycle_context_) {
- static_cast<Notifier*>(lifecycle_context_)->AddObserver(this);
- }
-}
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_LIFECYCLE_OBSERVER_H_
diff --git a/chromium/third_party/blink/renderer/platform/loader/BUILD.gn b/chromium/third_party/blink/renderer/platform/loader/BUILD.gn
index 731514c2914..c050053f89d 100644
--- a/chromium/third_party/blink/renderer/platform/loader/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/loader/BUILD.gn
@@ -103,8 +103,12 @@ blink_platform_sources("loader") {
"fetch/stale_revalidation_resource_client.h",
"fetch/text_resource_decoder_options.cc",
"fetch/text_resource_decoder_options.h",
+ "fetch/trust_token_params_conversion.cc",
+ "fetch/trust_token_params_conversion.h",
"fetch/unique_identifier.cc",
"fetch/unique_identifier.h",
+ "fetch/url_loader/request_conversion.cc",
+ "fetch/url_loader/request_conversion.h",
"fetch/worker_resource_timing_notifier.h",
"ftp_directory_listing.cc",
"ftp_directory_listing.h",
diff --git a/chromium/third_party/blink/renderer/platform/loader/DEPS b/chromium/third_party/blink/renderer/platform/loader/DEPS
index bea7ce0ccd6..e99fddc126d 100644
--- a/chromium/third_party/blink/renderer/platform/loader/DEPS
+++ b/chromium/third_party/blink/renderer/platform/loader/DEPS
@@ -63,4 +63,13 @@ specific_include_rules = {
"replaying_web_data_consumer_handle.h": [
"+third_party/blink/renderer/platform/waitable_event.h",
],
+ "request_conversion.cc": [
+ # This file consists of conversion functions and hence needs to access
+ # both the blink and chromium mojom variants.
+ "+net/base/request_priority.h",
+ "+net/http/http_request_headers.h",
+ "+net/http/http_util.h",
+ "+third_party/blink/public/mojom/blob/blob.mojom.h",
+ "+services/network/public/mojom/data_pipe_getter.mojom.h",
+ ]
}
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 42c442fb1d9..4b4c2cc6c9d 100644
--- a/chromium/third_party/blink/renderer/platform/loader/cors/cors.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/cors/cors.cc
@@ -25,6 +25,7 @@
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
#include "third_party/blink/renderer/platform/wtf/thread_specific.h"
#include "url/gurl.h"
+#include "url/origin.h"
namespace blink {
@@ -89,7 +90,7 @@ class HTTPHeaderNameListParser {
// in |output| when successful. Otherwise, returns with |output| kept empty.
//
// |output| must be empty.
- void Parse(WebHTTPHeaderSet& output) {
+ void Parse(HTTPHeaderSet& output) {
DCHECK(output.empty());
while (true) {
@@ -160,12 +161,11 @@ namespace cors {
base::Optional<network::CorsErrorStatus> CheckAccess(
const KURL& response_url,
- const int response_status_code,
const HTTPHeaderMap& response_header,
network::mojom::CredentialsMode credentials_mode,
const SecurityOrigin& origin) {
return network::cors::CheckAccess(
- response_url, response_status_code,
+ response_url,
GetHeaderValue(response_header, http_names::kAccessControlAllowOrigin),
GetHeaderValue(response_header,
http_names::kAccessControlAllowCredentials),
@@ -201,11 +201,6 @@ base::Optional<network::CorsErrorStatus> CheckRedirectLocation(
url, request_mode, origin_to_pass, cors_flag == CorsFlag::Set, false);
}
-base::Optional<network::mojom::CorsError> CheckPreflight(
- const int preflight_response_status_code) {
- return network::cors::CheckPreflight(preflight_response_status_code);
-}
-
base::Optional<network::CorsErrorStatus> CheckExternalPreflight(
const HTTPHeaderMap& response_header) {
return network::cors::CheckExternalPreflight(
@@ -253,8 +248,9 @@ base::Optional<network::CorsErrorStatus> EnsurePreflightResultAndCacheOnSuccess(
if (status)
return status;
- GetPerThreadPreflightCache().AppendEntry(origin.Ascii(), request_url,
- std::move(result));
+ GetPerThreadPreflightCache().AppendEntry(
+ url::Origin::Create(GURL(origin.Ascii())), request_url,
+ net::NetworkIsolationKey(), std::move(result));
return base::nullopt;
}
@@ -270,7 +266,8 @@ bool CheckIfRequestCanSkipPreflight(
// |is_revalidating| is not needed for blink-side CORS.
constexpr bool is_revalidating = false;
return GetPerThreadPreflightCache().CheckIfRequestCanSkipPreflight(
- origin.Ascii(), url, credentials_mode, method.Ascii(),
+ url::Origin::Create(GURL(origin.Ascii())), url,
+ net::NetworkIsolationKey(), credentials_mode, method.Ascii(),
*CreateNetHttpRequestHeaders(request_header_map), is_revalidating);
}
@@ -392,7 +389,7 @@ bool CalculateCorsFlag(const KURL& url,
const SecurityOrigin* initiator_origin,
const SecurityOrigin* isolated_world_origin,
network::mojom::RequestMode request_mode) {
- if (network::IsNavigationRequestMode(request_mode) ||
+ if (request_mode == network::mojom::RequestMode::kNavigate ||
request_mode == network::mojom::RequestMode::kNoCors) {
return false;
}
@@ -410,7 +407,7 @@ bool CalculateCorsFlag(const KURL& url,
return true;
}
-WebHTTPHeaderSet ExtractCorsExposedHeaderNamesList(
+HTTPHeaderSet ExtractCorsExposedHeaderNamesList(
network::mojom::CredentialsMode credentials_mode,
const ResourceResponse& response) {
// If a response was fetched via a service worker, it will always have
@@ -418,13 +415,13 @@ WebHTTPHeaderSet ExtractCorsExposedHeaderNamesList(
// For requests that didn't come from a service worker, just parse the CORS
// header.
if (response.WasFetchedViaServiceWorker()) {
- WebHTTPHeaderSet header_set;
+ HTTPHeaderSet header_set;
for (const auto& header : response.CorsExposedHeaderNames())
header_set.insert(header.Ascii());
return header_set;
}
- WebHTTPHeaderSet header_set;
+ HTTPHeaderSet header_set;
HTTPHeaderNameListParser parser(
response.HttpHeaderField(http_names::kAccessControlExposeHeaders));
parser.Parse(header_set);
@@ -441,7 +438,7 @@ WebHTTPHeaderSet ExtractCorsExposedHeaderNamesList(
bool IsCorsSafelistedResponseHeader(const String& name) {
// https://fetch.spec.whatwg.org/#cors-safelisted-response-header-name
// TODO(dcheng): Consider using a flat_set here with a transparent comparator.
- DEFINE_THREAD_SAFE_STATIC_LOCAL(WebHTTPHeaderSet,
+ DEFINE_THREAD_SAFE_STATIC_LOCAL(HTTPHeaderSet,
allowed_cross_origin_response_headers,
({
"cache-control",
diff --git a/chromium/third_party/blink/renderer/platform/loader/cors/cors.h b/chromium/third_party/blink/renderer/platform/loader/cors/cors.h
index 84998f9c4b2..610c2c75c3f 100644
--- a/chromium/third_party/blink/renderer/platform/loader/cors/cors.h
+++ b/chromium/third_party/blink/renderer/platform/loader/cors/cors.h
@@ -10,7 +10,7 @@
#include "services/network/public/mojom/cors.mojom-blink-forward.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/platform/web_http_header_set.h"
+#include "third_party/blink/renderer/platform/network/http_header_set.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -35,7 +35,6 @@ namespace cors {
// be removed.
PLATFORM_EXPORT base::Optional<network::CorsErrorStatus> CheckAccess(
const KURL&,
- const int response_status_code,
const HTTPHeaderMap&,
network::mojom::CredentialsMode,
const SecurityOrigin&);
@@ -53,9 +52,6 @@ PLATFORM_EXPORT base::Optional<network::CorsErrorStatus> CheckRedirectLocation(
const SecurityOrigin*,
CorsFlag);
-PLATFORM_EXPORT base::Optional<network::mojom::CorsError> CheckPreflight(
- const int preflight_response_status_code);
-
PLATFORM_EXPORT base::Optional<network::CorsErrorStatus> CheckExternalPreflight(
const HTTPHeaderMap&);
@@ -124,7 +120,7 @@ PLATFORM_EXPORT bool CalculateCorsFlag(
const SecurityOrigin* isolated_world_origin,
network::mojom::RequestMode request_mode);
-PLATFORM_EXPORT WebHTTPHeaderSet
+PLATFORM_EXPORT HTTPHeaderSet
ExtractCorsExposedHeaderNamesList(network::mojom::CredentialsMode,
const ResourceResponse&);
diff --git a/chromium/third_party/blink/renderer/platform/loader/cors/cors_test.cc b/chromium/third_party/blink/renderer/platform/loader/cors/cors_test.cc
index e68e93c56b7..173f852a577 100644
--- a/chromium/third_party/blink/renderer/platform/loader/cors/cors_test.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/cors/cors_test.cc
@@ -17,8 +17,8 @@ class CorsExposedHeadersTest : public testing::Test {
public:
using CredentialsMode = network::mojom::CredentialsMode;
- WebHTTPHeaderSet Parse(CredentialsMode credentials_mode,
- const AtomicString& header) const {
+ HTTPHeaderSet Parse(CredentialsMode credentials_mode,
+ const AtomicString& header) const {
ResourceResponse response;
response.AddHttpHeaderField("access-control-expose-headers", header);
@@ -27,25 +27,24 @@ class CorsExposedHeadersTest : public testing::Test {
};
TEST_F(CorsExposedHeadersTest, ValidInput) {
- EXPECT_EQ(Parse(CredentialsMode::kOmit, "valid"),
- WebHTTPHeaderSet({"valid"}));
+ EXPECT_EQ(Parse(CredentialsMode::kOmit, "valid"), HTTPHeaderSet({"valid"}));
- EXPECT_EQ(Parse(CredentialsMode::kOmit, "a,b"), WebHTTPHeaderSet({"a", "b"}));
+ EXPECT_EQ(Parse(CredentialsMode::kOmit, "a,b"), HTTPHeaderSet({"a", "b"}));
EXPECT_EQ(Parse(CredentialsMode::kOmit, " a , b "),
- WebHTTPHeaderSet({"a", "b"}));
+ HTTPHeaderSet({"a", "b"}));
EXPECT_EQ(Parse(CredentialsMode::kOmit, " \t \t\t a"),
- WebHTTPHeaderSet({"a"}));
+ HTTPHeaderSet({"a"}));
- EXPECT_EQ(Parse(CredentialsMode::kOmit, "a , "), WebHTTPHeaderSet({"a", ""}));
+ EXPECT_EQ(Parse(CredentialsMode::kOmit, "a , "), HTTPHeaderSet({"a", ""}));
}
TEST_F(CorsExposedHeadersTest, DuplicatedEntries) {
- EXPECT_EQ(Parse(CredentialsMode::kOmit, "a, a"), WebHTTPHeaderSet{"a"});
+ EXPECT_EQ(Parse(CredentialsMode::kOmit, "a, a"), HTTPHeaderSet{"a"});
EXPECT_EQ(Parse(CredentialsMode::kOmit, "a, a, b"),
- WebHTTPHeaderSet({"a", "b"}));
+ HTTPHeaderSet({"a", "b"}));
}
TEST_F(CorsExposedHeadersTest, InvalidInput) {
@@ -81,12 +80,12 @@ TEST_F(CorsExposedHeadersTest, Wildcard) {
EXPECT_EQ(
cors::ExtractCorsExposedHeaderNamesList(CredentialsMode::kOmit, response),
- WebHTTPHeaderSet({"access-control-expose-headers", "b", "c", "d", "*"}));
+ HTTPHeaderSet({"access-control-expose-headers", "b", "c", "d", "*"}));
EXPECT_EQ(
cors::ExtractCorsExposedHeaderNamesList(CredentialsMode::kSameOrigin,
response),
- WebHTTPHeaderSet({"access-control-expose-headers", "b", "c", "d", "*"}));
+ HTTPHeaderSet({"access-control-expose-headers", "b", "c", "d", "*"}));
}
TEST_F(CorsExposedHeadersTest, Asterisk) {
@@ -99,7 +98,7 @@ TEST_F(CorsExposedHeadersTest, Asterisk) {
EXPECT_EQ(cors::ExtractCorsExposedHeaderNamesList(CredentialsMode::kInclude,
response),
- WebHTTPHeaderSet({"a", "b", "*"}));
+ HTTPHeaderSet({"a", "b", "*"}));
}
// Keep this in sync with the CalculateResponseTainting test in
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/DEPS b/chromium/third_party/blink/renderer/platform/loader/fetch/DEPS
index d430e11a2d9..35694fdca61 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/DEPS
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/DEPS
@@ -1,3 +1,5 @@
include_rules = [
+ "+net/dns/public",
"+services/network/public/cpp/fetch_api_utils.h",
+ "+services/network/public/cpp/optional_trust_token_params.h",
]
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 923c1903f67..e8411eddd6c 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
@@ -6,23 +6,22 @@
#include "base/feature_list.h"
#include "base/metrics/field_trial_params.h"
-#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
namespace blink {
+namespace {
+constexpr int32_t kDelayMilliseconds = 50;
+} // namespace
+
// static
BufferingBytesConsumer* BufferingBytesConsumer::CreateWithDelay(
BytesConsumer* bytes_consumer,
scoped_refptr<base::SingleThreadTaskRunner> timer_task_runner) {
- if (!base::FeatureList::IsEnabled(features::kBufferingBytesConsumerDelay))
- return Create(bytes_consumer);
-
return MakeGarbageCollected<BufferingBytesConsumer>(
util::PassKey<BufferingBytesConsumer>(), bytes_consumer,
std::move(timer_task_runner),
- base::TimeDelta::FromMilliseconds(
- features::kBufferingBytesConsumerDelayMilliseconds.Get()));
+ base::TimeDelta::FromMilliseconds(kDelayMilliseconds));
}
// static
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 194590efe87..49155275231 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(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
void OnTimerFired(TimerBase*);
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/buffering_bytes_consumer_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/buffering_bytes_consumer_test.cc
index 1f17f0aadfc..8c298b58301 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/buffering_bytes_consumer_test.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/buffering_bytes_consumer_test.cc
@@ -7,7 +7,6 @@
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.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/loader/fetch/data_pipe_bytes_consumer.h"
#include "third_party/blink/renderer/platform/loader/testing/bytes_consumer_test_reader.h"
@@ -74,10 +73,6 @@ TEST_F(BufferingBytesConsumerTest, ReadWithDelay) {
auto* replaying_bytes_consumer =
MakeGarbageCollected<ReplayingBytesConsumer>(task_runner);
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeatureWithParameters(
- features::kBufferingBytesConsumerDelay, {{"milliseconds", "10"}});
-
replaying_bytes_consumer->Add(Command(Command::kWait));
replaying_bytes_consumer->Add(Command(Command::kData, "1"));
replaying_bytes_consumer->Add(Command(Command::kWait));
@@ -143,10 +138,6 @@ TEST_F(BufferingBytesConsumerTest, Buffering) {
}
TEST_F(BufferingBytesConsumerTest, BufferingWithDelay) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeatureWithParameters(
- features::kBufferingBytesConsumerDelay, {{"milliseconds", "10"}});
-
auto task_runner = base::MakeRefCounted<scheduler::FakeTaskRunner>();
auto* replaying_bytes_consumer =
MakeGarbageCollected<ReplayingBytesConsumer>(task_runner);
@@ -175,7 +166,7 @@ TEST_F(BufferingBytesConsumerTest, BufferingWithDelay) {
EXPECT_EQ(PublicState::kReadableOrWaiting,
replaying_bytes_consumer->GetPublicState());
- task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(11));
+ task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(51));
task_runner->RunUntilIdle();
// After the delay expires the underlying consumer should be completely read.
@@ -242,10 +233,6 @@ TEST_F(BufferingBytesConsumerTest, DrainAsDataPipeFailsWithoutDelay) {
}
TEST_F(BufferingBytesConsumerTest, DrainAsDataPipeSucceedsWithDelay) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeatureWithParameters(
- features::kBufferingBytesConsumerDelay, {{"milliseconds", "10"}});
-
auto task_runner = base::MakeRefCounted<scheduler::FakeTaskRunner>();
DataPipeBytesConsumer::CompletionNotifier* notifier = nullptr;
@@ -262,10 +249,6 @@ TEST_F(BufferingBytesConsumerTest, DrainAsDataPipeSucceedsWithDelay) {
}
TEST_F(BufferingBytesConsumerTest, DrainAsDataPipeFailsWithExpiredDelay) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeatureWithParameters(
- features::kBufferingBytesConsumerDelay, {{"milliseconds", "10"}});
-
auto task_runner = base::MakeRefCounted<scheduler::FakeTaskRunner>();
DataPipeBytesConsumer::CompletionNotifier* notifier = nullptr;
@@ -276,7 +259,7 @@ TEST_F(BufferingBytesConsumerTest, DrainAsDataPipeFailsWithExpiredDelay) {
auto* bytes_consumer = BufferingBytesConsumer::CreateWithDelay(
data_pipe_consumer, scheduler::GetSingleThreadTaskRunnerForTesting());
- task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(11));
+ task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(51));
EXPECT_EQ(PublicState::kReadableOrWaiting, bytes_consumer->GetPublicState());
auto drained_consumer_handle = bytes_consumer->DrainAsDataPipe();
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 c557ed1495d..5ec8bba5dd9 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
@@ -177,7 +177,7 @@ class PLATFORM_EXPORT BytesConsumer : public GarbageCollected<BytesConsumer> {
// Returns a BytesConsumer whose state is Errored.
static BytesConsumer* CreateErrored(const Error&);
- virtual void Trace(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
protected:
// This InternalState directly corresponds to the states in the class
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 3aea5dc8784..c0a819c63b0 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
@@ -20,8 +20,9 @@ class CachedMetadata;
class ResourceResponse;
class WebProcessMemoryDump;
-// A callback for sending the serialized data of cached metadata back to the
-// platform.
+// A callback for sending the serialized data of cached metadata to the
+// persistent storage.
+// TODO(pasko): rename this class to CachedMetadataPersister.
class PLATFORM_EXPORT CachedMetadataSender {
USING_FAST_MALLOC(CachedMetadataSender);
@@ -46,9 +47,19 @@ PLATFORM_EXPORT bool ShouldUseIsolatedCodeCache(mojom::RequestContextType,
// Handler class for caching operations.
class CachedMetadataHandler : public GarbageCollected<CachedMetadataHandler> {
public:
- enum CacheType {
- kSendToPlatform, // send cache data to blink::Platform::cacheMetadata
- kCacheLocally // cache only in Resource's member variables
+ enum ClearCacheType {
+ // Clears the in-memory cache, but doesn't update persistent storage. The
+ // old cached metadata is considered invalid.
+ kClearLocally,
+
+ // Discards the in-memory cache for memory reduction, preventing any further
+ // uses or updates. The cached metadata will no longer be available, but
+ // should not be considered invalid.
+ kDiscardLocally,
+
+ // Clears the metadata in both memory and persistent storage via
+ // blink::Platform::CacheMetadata.
+ kClearPersistentStorage
};
// Enum for marking serialized cached metadatas so that the deserializers
@@ -60,10 +71,11 @@ class CachedMetadataHandler : public GarbageCollected<CachedMetadataHandler> {
};
virtual ~CachedMetadataHandler() = default;
- virtual void Trace(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
- // Reset existing metadata, to allow setting new data.
- virtual void ClearCachedMetadata(CacheType = kCacheLocally) = 0;
+ // Reset existing metadata. Subclasses can ignore setting new metadata after
+ // clearing with |kDiscardLocally| to save memory.
+ virtual void ClearCachedMetadata(ClearCacheType) = 0;
// Returns the encoding to which the cache is specific.
virtual String Encoding() const = 0;
@@ -88,8 +100,13 @@ class SingleCachedMetadataHandler : public CachedMetadataHandler {
// identifier that is used to distinguish data generated by the caller.
virtual void SetCachedMetadata(uint32_t data_type_id,
const uint8_t*,
- size_t,
- CacheType = kSendToPlatform) = 0;
+ size_t) = 0;
+
+ // Permanently disable persisting CachedMetadata in the platform only when it
+ // is set.
+ void DisableSendToPlatformForTesting() {
+ disable_send_to_platform_for_testing_ = true;
+ }
// Returns cached metadata of the given type associated with this resource.
// This cached metadata can be pruned at any time.
@@ -98,6 +115,7 @@ class SingleCachedMetadataHandler : public CachedMetadataHandler {
protected:
SingleCachedMetadataHandler() = default;
+ bool disable_send_to_platform_for_testing_ = false;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.cc
index 3af7c4975b2..b49dc9e74a1 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.cc
@@ -14,64 +14,6 @@
namespace blink {
-namespace {
-
-void ParseAcceptChHeader(const String& header_value,
- WebEnabledClientHints& enabled_hints) {
- CommaDelimitedHeaderSet accept_client_hints_header;
- ParseCommaDelimitedHeader(header_value, accept_client_hints_header);
-
- for (size_t i = 0;
- i < static_cast<int>(mojom::WebClientHintsType::kMaxValue) + 1; ++i) {
- enabled_hints.SetIsEnabled(
- static_cast<mojom::WebClientHintsType>(i),
- accept_client_hints_header.Contains(kClientHintsNameMapping[i]));
- }
-
- enabled_hints.SetIsEnabled(
- mojom::WebClientHintsType::kDeviceMemory,
- enabled_hints.IsEnabled(mojom::WebClientHintsType::kDeviceMemory));
-
- enabled_hints.SetIsEnabled(
- mojom::WebClientHintsType::kRtt,
- enabled_hints.IsEnabled(mojom::WebClientHintsType::kRtt));
-
- enabled_hints.SetIsEnabled(
- mojom::WebClientHintsType::kDownlink,
- enabled_hints.IsEnabled(mojom::WebClientHintsType::kDownlink));
-
- enabled_hints.SetIsEnabled(
- mojom::WebClientHintsType::kEct,
- enabled_hints.IsEnabled(mojom::WebClientHintsType::kEct));
-
- enabled_hints.SetIsEnabled(
- mojom::WebClientHintsType::kLang,
- enabled_hints.IsEnabled(mojom::WebClientHintsType::kLang) &&
- RuntimeEnabledFeatures::LangClientHintHeaderEnabled());
-
- enabled_hints.SetIsEnabled(
- mojom::WebClientHintsType::kUA,
- enabled_hints.IsEnabled(mojom::WebClientHintsType::kUA) &&
- RuntimeEnabledFeatures::UserAgentClientHintEnabled());
-
- enabled_hints.SetIsEnabled(
- mojom::WebClientHintsType::kUAArch,
- enabled_hints.IsEnabled(mojom::WebClientHintsType::kUAArch) &&
- RuntimeEnabledFeatures::UserAgentClientHintEnabled());
-
- enabled_hints.SetIsEnabled(
- mojom::WebClientHintsType::kUAPlatform,
- enabled_hints.IsEnabled(mojom::WebClientHintsType::kUAPlatform) &&
- RuntimeEnabledFeatures::UserAgentClientHintEnabled());
-
- enabled_hints.SetIsEnabled(
- mojom::WebClientHintsType::kUAModel,
- enabled_hints.IsEnabled(mojom::WebClientHintsType::kUAModel) &&
- RuntimeEnabledFeatures::UserAgentClientHintEnabled());
-}
-
-} // namespace
-
ClientHintsPreferences::ClientHintsPreferences() {
DCHECK_EQ(static_cast<size_t>(mojom::WebClientHintsType::kMaxValue) + 1,
kClientHintsMappingsCount);
@@ -97,16 +39,24 @@ void ClientHintsPreferences::UpdateFromAcceptClientHintsHeader(
if (!IsClientHintsAllowed(url))
return;
- WebEnabledClientHints new_enabled_types;
+ // 8-bit conversions from String can turn non-ASCII characters into ?,
+ // turning syntax errors into "correct" syntax, so reject those first.
+ // (.Utf8() doesn't have this problem, but it does a lot of expensive
+ // work that would be wasted feeding to an ASCII-only syntax).
+ if (!header_value.ContainsOnlyASCIIOrEmpty())
+ return;
- ParseAcceptChHeader(header_value, new_enabled_types);
+ // Note: .Ascii() would convert tab to ?, which is undesirable.
+ base::Optional<std::vector<blink::mojom::WebClientHintsType>> parsed_ch =
+ ParseAcceptCH(header_value.Latin1(),
+ RuntimeEnabledFeatures::LangClientHintHeaderEnabled(),
+ RuntimeEnabledFeatures::UserAgentClientHintEnabled());
+ if (!parsed_ch.has_value())
+ return;
- for (size_t i = 0;
- i < static_cast<int>(mojom::WebClientHintsType::kMaxValue) + 1; ++i) {
- mojom::WebClientHintsType type = static_cast<mojom::WebClientHintsType>(i);
- enabled_hints_.SetIsEnabled(type, enabled_hints_.IsEnabled(type) ||
- new_enabled_types.IsEnabled(type));
- }
+ // Note: this keeps previously enabled hints.
+ for (blink::mojom::WebClientHintsType newly_enabled : parsed_ch.value())
+ enabled_hints_.SetIsEnabled(newly_enabled, true);
if (context) {
for (size_t i = 0;
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences_test.cc
index e3e328e565d..1b6afccf66a 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences_test.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/client_hints_preferences_test.cc
@@ -28,31 +28,33 @@ TEST_F(ClientHintsPreferencesTest, BasicSecure) {
bool expectation_ua_arch;
bool expectation_ua_platform;
bool expectation_ua_model;
+ bool expectation_ua_full_version;
} cases[] = {
{"width, dpr, viewportWidth", true, true, false, false, false, false,
- false, false, false, false, false},
+ false, false, false, false, false, false},
{"WiDtH, dPr, viewport-width, rtt, downlink, ect, lang", true, true, true,
- true, true, true, true, false, false, false, false},
+ true, true, true, true, false, false, false, false, false},
{"WiDtH, dPr, viewport-width, rtt, downlink, effective-connection-type",
- true, true, true, true, true, false, false, false, false, false, false},
+ true, true, true, true, true, false, false, false, false, false, false,
+ false},
{"WIDTH, DPR, VIWEPROT-Width", true, true, false, false, false, false,
- false, false, false, false, false},
+ false, false, false, false, false, false},
{"VIewporT-Width, wutwut, width", true, false, true, false, false, false,
- false, false, false, false, false},
+ false, false, false, false, false, false},
{"dprw", false, false, false, false, false, false, false, false, false,
- false, false},
+ false, false, false},
{"DPRW", false, false, false, false, false, false, false, false, false,
- false, false},
+ false, false, false},
{"ua", false, false, false, false, false, false, false, true, false,
- false, false},
- {"arch", false, false, false, false, false, false, false, false, true,
- false, false},
- {"platform", false, false, false, false, false, false, false, false,
- false, true, false},
- {"model", false, false, false, false, false, false, false, false, false,
- false, true},
- {"ua, arch, platform, model", false, false, false, false, false, false,
- false, true, true, true, true},
+ false, false, false},
+ {"ua-arch", false, false, false, false, false, false, false, false, true,
+ false, false, false},
+ {"ua-platform", false, false, false, false, false, false, false, false,
+ false, true, false, false},
+ {"ua-model", false, false, false, false, false, false, false, false,
+ false, false, true, false},
+ {"ua, ua-arch, ua-platform, ua-model, ua-full-version", false, false,
+ false, false, false, false, false, true, true, true, true, true},
};
for (const auto& test_case : cases) {
@@ -214,23 +216,25 @@ TEST_F(ClientHintsPreferencesTest, ParseHeaders) {
bool expect_ua_arch;
bool expect_ua_platform;
bool expect_ua_model;
+ bool expect_ua_full_version;
} test_cases[] = {
{"width, dpr, viewportWidth, lang", "", 0, false, true, true, false,
- false, false, false, true, false, false, false, false},
+ false, false, false, true, false, false, false, false, false},
{"width, dpr, viewportWidth", "-1000", 0, false, true, true, false, false,
- false, false, false, false, false, false, false},
+ false, false, false, false, false, false, false, false},
{"width, dpr, viewportWidth", "1000s", 0, false, true, true, false, false,
- false, false, false, false, false, false, false},
- {"width, dpr, viewportWidth", "1000.5", 0, false, true, true, false,
false, false, false, false, false, false, false, false},
+ {"width, dpr, viewportWidth", "1000.5", 0, false, true, true, false,
+ false, false, false, false, false, false, false, false, false},
{"width, dpr, rtt, downlink, ect", "1000", 1000, false, true, true, false,
- true, true, true, false, false, false, false, false},
+ true, true, true, false, false, false, false, false, false},
{"device-memory", "-1000", 0, true, false, false, false, false, false,
- false, false, false, false, false, false},
+ false, false, false, false, false, false, false},
{"dpr rtt", "1000", 1000, false, false, false, false, false, false, false,
- false, false, false, false, false},
- {"ua, arch, platform, model", "1000", 1000, false, false, false, false,
- false, false, false, false, true, true, true, true},
+ false, false, false, false, false, false},
+ {"ua, ua-arch, ua-platform, ua-model, ua-full-version", "1000", 1000,
+ false, false, false, false, false, false, false, false, true, true, true,
+ true, true},
};
for (const auto& test : test_cases) {
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 42054403a7b..c36b32b18fc 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
@@ -153,7 +153,7 @@ BytesConsumer::PublicState DataPipeBytesConsumer::GetPublicState() const {
return GetPublicStateFromInternalState(state_);
}
-void DataPipeBytesConsumer::Trace(blink::Visitor* visitor) {
+void DataPipeBytesConsumer::Trace(Visitor* visitor) {
visitor->Trace(client_);
BytesConsumer::Trace(visitor);
}
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 4d84e2b8205..9bfc9775f21 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
@@ -40,7 +40,7 @@ class PLATFORM_EXPORT DataPipeBytesConsumer final : public BytesConsumer {
// written into the pipe.
void SignalComplete();
void SignalError(const BytesConsumer::Error& error);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
const WeakMember<DataPipeBytesConsumer> bytes_consumer_;
@@ -65,7 +65,7 @@ class PLATFORM_EXPORT DataPipeBytesConsumer final : public BytesConsumer {
}
String DebugName() const override { return "DataPipeBytesConsumer"; }
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
private:
bool IsReadableOrWaiting() const;
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 3ffd87b8aba..9f5f505218e 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
@@ -8,7 +8,7 @@
#include "base/optional.h"
#include "services/network/public/mojom/ip_address_space.mojom-blink-forward.h"
#include "services/network/public/mojom/referrer_policy.mojom-blink.h"
-#include "third_party/blink/public/platform/web_insecure_request_policy.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink-forward.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/loader/allowed_by_nosniff.h"
@@ -81,7 +81,8 @@ class PLATFORM_EXPORT FetchClientSettingsObject
virtual network::mojom::IPAddressSpace GetAddressSpace() const = 0;
// https://w3c.github.io/webappsec-upgrade-insecure-requests/#insecure-requests-policy
- virtual WebInsecureRequestPolicy GetInsecureRequestsPolicy() const = 0;
+ virtual mojom::blink::InsecureRequestPolicy GetInsecureRequestsPolicy()
+ const = 0;
// https://w3c.github.io/webappsec-upgrade-insecure-requests/#upgrade-insecure-navigations-set
using InsecureNavigationsSet = HashSet<unsigned, WTF::AlreadyHashed>;
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.cc
index ad064d1dba4..e11f91fc064 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
#include "third_party/blink/renderer/platform/heap/trace_traits.h"
namespace blink {
@@ -45,7 +46,7 @@ FetchClientSettingsObjectSnapshot::FetchClientSettingsObjectSnapshot(
HttpsState https_state,
AllowedByNosniff::MimeTypeCheck mime_type_check_for_classic_worker_script,
network::mojom::IPAddressSpace address_space,
- WebInsecureRequestPolicy insecure_requests_policy,
+ mojom::blink::InsecureRequestPolicy insecure_requests_policy,
InsecureNavigationsSet insecure_navigations_set)
: global_object_url_(global_object_url),
base_url_(base_url),
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h
index 84a9a1b9cc1..b4ae59e5550 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_FETCH_CLIENT_SETTINGS_OBJECT_SNAPSHOT_H_
#include "services/network/public/mojom/referrer_policy.mojom-blink.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink-forward.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -37,7 +38,7 @@ struct CrossThreadFetchClientSettingsObjectData {
HttpsState https_state,
AllowedByNosniff::MimeTypeCheck mime_type_check_for_classic_worker_script,
network::mojom::IPAddressSpace address_space,
- WebInsecureRequestPolicy insecure_requests_policy,
+ mojom::blink::InsecureRequestPolicy insecure_requests_policy,
FetchClientSettingsObject::InsecureNavigationsSet
insecure_navigations_set)
: global_object_url(std::move(global_object_url)),
@@ -61,7 +62,7 @@ struct CrossThreadFetchClientSettingsObjectData {
const AllowedByNosniff::MimeTypeCheck
mime_type_check_for_classic_worker_script;
const network::mojom::IPAddressSpace address_space;
- const WebInsecureRequestPolicy insecure_requests_policy;
+ const mojom::blink::InsecureRequestPolicy insecure_requests_policy;
const FetchClientSettingsObject::InsecureNavigationsSet
insecure_navigations_set;
@@ -94,7 +95,7 @@ class PLATFORM_EXPORT FetchClientSettingsObjectSnapshot final
HttpsState https_state,
AllowedByNosniff::MimeTypeCheck,
network::mojom::IPAddressSpace,
- WebInsecureRequestPolicy,
+ mojom::blink::InsecureRequestPolicy,
InsecureNavigationsSet);
~FetchClientSettingsObjectSnapshot() override = default;
@@ -116,7 +117,8 @@ class PLATFORM_EXPORT FetchClientSettingsObjectSnapshot final
return address_space_;
}
- WebInsecureRequestPolicy GetInsecureRequestsPolicy() const override {
+ mojom::blink::InsecureRequestPolicy GetInsecureRequestsPolicy()
+ const override {
return insecure_requests_policy_;
}
@@ -151,7 +153,7 @@ class PLATFORM_EXPORT FetchClientSettingsObjectSnapshot final
mime_type_check_for_classic_worker_script_;
const network::mojom::IPAddressSpace address_space_;
- const WebInsecureRequestPolicy insecure_requests_policy_;
+ const mojom::blink::InsecureRequestPolicy insecure_requests_policy_;
const InsecureNavigationsSet insecure_navigations_set_;
};
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 cb44fc15e85..916041c76e1 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
@@ -47,7 +47,7 @@
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h"
#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/weborigin/security_violation_reporting_policy.h"
+#include "third_party/blink/renderer/platform/weborigin/reporting_disposition.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
namespace blink {
@@ -75,7 +75,7 @@ class PLATFORM_EXPORT FetchContext : public GarbageCollected<FetchContext> {
virtual ~FetchContext() = default;
- virtual void Trace(blink::Visitor*) {}
+ virtual void Trace(Visitor*) {}
virtual void AddAdditionalRequestHeaders(ResourceRequest&);
@@ -112,7 +112,7 @@ class PLATFORM_EXPORT FetchContext : public GarbageCollected<FetchContext> {
const ResourceRequest&,
const KURL&,
const ResourceLoaderOptions&,
- SecurityViolationReportingPolicy,
+ ReportingDisposition,
ResourceRequest::RedirectStatus) const {
return ResourceRequestBlockedReason::kOther;
}
@@ -120,7 +120,7 @@ class PLATFORM_EXPORT FetchContext : public GarbageCollected<FetchContext> {
mojom::RequestContextType,
const KURL&,
const ResourceLoaderOptions&,
- SecurityViolationReportingPolicy,
+ ReportingDisposition,
ResourceRequest::RedirectStatus) const {
return ResourceRequestBlockedReason::kOther;
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc
index eea543633a1..c57dfd3b668 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.cc
@@ -33,16 +33,16 @@
namespace blink {
-FetchParameters::FetchParameters(const ResourceRequest& resource_request)
- : resource_request_(resource_request),
+FetchParameters::FetchParameters(ResourceRequest resource_request)
+ : resource_request_(std::move(resource_request)),
decoder_options_(TextResourceDecoderOptions::kPlainTextContent),
speculative_preload_type_(SpeculativePreloadType::kNotSpeculative),
defer_(kNoDefer),
image_request_optimization_(kNone) {}
-FetchParameters::FetchParameters(const ResourceRequest& resource_request,
+FetchParameters::FetchParameters(ResourceRequest resource_request,
const ResourceLoaderOptions& options)
- : resource_request_(resource_request),
+ : resource_request_(std::move(resource_request)),
decoder_options_(TextResourceDecoderOptions::kPlainTextContent),
options_(options),
speculative_preload_type_(SpeculativePreloadType::kNotSpeculative),
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h
index de0d27f225b..a1e29fbe9b6 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h
@@ -71,8 +71,8 @@ class PLATFORM_EXPORT FetchParameters {
ResourceWidth() : width(0), is_set(false) {}
};
- explicit FetchParameters(const ResourceRequest&);
- FetchParameters(const ResourceRequest&, const ResourceLoaderOptions&);
+ explicit FetchParameters(ResourceRequest);
+ FetchParameters(ResourceRequest, const ResourceLoaderOptions&);
FetchParameters(const FetchParameters&) = delete;
FetchParameters& operator=(const FetchParameters&) = delete;
FetchParameters(FetchParameters&&);
@@ -88,6 +88,10 @@ class PLATFORM_EXPORT FetchParameters {
resource_request_.SetRequestContext(context);
}
+ void SetRequestDestination(network::mojom::RequestDestination destination) {
+ resource_request_.SetRequestDestination(destination);
+ }
+
void SetFetchImportanceMode(mojom::FetchImportanceMode importance_mode) {
resource_request_.SetFetchImportanceMode(importance_mode);
}
@@ -139,7 +143,7 @@ class PLATFORM_EXPORT FetchParameters {
}
void SetContentSecurityCheck(
- ContentSecurityPolicyDisposition content_security_policy_option) {
+ network::mojom::CSPDisposition content_security_policy_option) {
options_.content_security_policy_option = content_security_policy_option;
}
// Configures the request to use the "cors" mode and the credentials mode
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 216c0f02ba1..f43766d2fcd 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(blink::Visitor* visitor) {
+void MemoryCacheEntry::Trace(Visitor* visitor) {
visitor->template RegisterWeakCallbackMethod<
MemoryCacheEntry, &MemoryCacheEntry::ClearResourceWeak>(this);
}
@@ -93,7 +93,7 @@ MemoryCache::MemoryCache(
MemoryCache::~MemoryCache() = default;
-void MemoryCache::Trace(blink::Visitor* visitor) {
+void MemoryCache::Trace(Visitor* visitor) {
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 bc8e09b6442..d797ba16873 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(blink::Visitor*);
+ void Trace(Visitor*);
Resource* GetResource() const { return resource_; }
private:
@@ -71,7 +71,7 @@ class PLATFORM_EXPORT MemoryCache final : public GarbageCollected<MemoryCache>,
explicit MemoryCache(scoped_refptr<base::SingleThreadTaskRunner> task_runner);
~MemoryCache() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
struct TypeStatistic {
STACK_ALLOCATED();
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache_correctness_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache_correctness_test.cc
index 814e5c4b38f..96a01d2843c 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache_correctness_test.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache_correctness_test.cc
@@ -95,13 +95,13 @@ class MemoryCacheCorrectnessTest : public testing::Test {
ResourceRequest resource_request{KURL(kResourceURL)};
resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
resource_request.SetRequestorOrigin(GetSecurityOrigin());
- FetchParameters fetch_params(resource_request);
+ FetchParameters fetch_params(std::move(resource_request));
return RawResource::Fetch(fetch_params, Fetcher(), nullptr);
}
MockResource* FetchMockResource() {
ResourceRequest resource_request{KURL(kResourceURL)};
resource_request.SetRequestorOrigin(GetSecurityOrigin());
- FetchParameters fetch_params(resource_request);
+ FetchParameters fetch_params(std::move(resource_request));
return MockResource::Fetch(fetch_params, Fetcher(), nullptr);
}
ResourceFetcher* Fetcher() const { return fetcher_.Get(); }
@@ -318,7 +318,7 @@ TEST_F(MemoryCacheCorrectnessTest, RequestWithNoCache) {
no_cache_request.SetHttpHeaderField(http_names::kCacheControl, "no-cache");
no_cache_request.SetRequestorOrigin(GetSecurityOrigin());
MockResource* no_cache_resource =
- ResourceFromResourceRequest(no_cache_request);
+ ResourceFromResourceRequest(std::move(no_cache_request));
MockResource* fetched = FetchMockResource();
EXPECT_NE(no_cache_resource, fetched);
}
@@ -349,7 +349,7 @@ TEST_F(MemoryCacheCorrectnessTest, RequestWithNoStore) {
no_store_request.SetHttpHeaderField(http_names::kCacheControl, "no-store");
no_store_request.SetRequestorOrigin(GetSecurityOrigin());
MockResource* no_store_resource =
- ResourceFromResourceRequest(no_store_request);
+ ResourceFromResourceRequest(std::move(no_store_request));
MockResource* fetched = FetchMockResource();
EXPECT_NE(no_store_resource, fetched);
}
@@ -469,7 +469,7 @@ TEST_F(MemoryCacheCorrectnessTest, PostToSameURLTwice) {
ResourceRequest request2{KURL(kResourceURL)};
request2.SetHttpMethod(http_names::kPOST);
request2.SetRequestorOrigin(GetSecurityOrigin());
- FetchParameters fetch2(request2);
+ FetchParameters fetch2(std::move(request2));
RawResource* resource2 = RawResource::FetchSynchronously(fetch2, Fetcher());
EXPECT_NE(resource1, resource2);
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache_test.cc
index fe682869223..73ce6bdb973 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache_test.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/memory_cache_test.cc
@@ -30,7 +30,6 @@
#include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
-#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/heap.h"
@@ -126,13 +125,7 @@ TEST_F(MemoryCacheTest, CapacityAccounting) {
EXPECT_EQ(kTotalCapacity, GetMemoryCache()->Capacity());
}
-// TODO(crbug.com/850788): Reenable this.
-#if defined(OS_ANDROID)
-#define MAYBE_VeryLargeResourceAccounting DISABLED_VeryLargeResourceAccounting
-#else
-#define MAYBE_VeryLargeResourceAccounting VeryLargeResourceAccounting
-#endif
-TEST_F(MemoryCacheTest, MAYBE_VeryLargeResourceAccounting) {
+TEST_F(MemoryCacheTest, VeryLargeResourceAccounting) {
const size_t kSizeMax = ~static_cast<size_t>(0);
const size_t kTotalCapacity = kSizeMax / 4;
const size_t kResourceSize1 = kSizeMax / 16;
@@ -140,7 +133,12 @@ TEST_F(MemoryCacheTest, MAYBE_VeryLargeResourceAccounting) {
GetMemoryCache()->SetCapacity(kTotalCapacity);
Persistent<MockResourceClient> client =
MakeGarbageCollected<MockResourceClient>();
- FetchParameters params(ResourceRequest("data:text/html,"));
+ // Here and below, use an image MIME type. This is because on Android
+ // non-image MIME types trigger a query to Java to check which video codecs
+ // are supported. This fails in tests. The solution is either to use an image
+ // type, or disable the tests on Android.
+ // crbug.com/850788.
+ FetchParameters params(ResourceRequest("data:image/jpeg,"));
FakeDecodedResource* cached_resource =
FakeDecodedResource::Fetch(params, fetcher_, client);
cached_resource->FakeEncodedSize(kResourceSize1);
@@ -200,14 +198,14 @@ static void TestResourcePruningLater(ResourceFetcher* fetcher,
EXPECT_EQ(0u, GetMemoryCache()->size());
const char kData[6] = "abcde";
- FetchParameters params1(ResourceRequest("data:text/html,resource1"));
+ FetchParameters params1(ResourceRequest("data:image/jpeg,resource1"));
Resource* resource1 = FakeDecodedResource::Fetch(params1, fetcher, nullptr);
GetMemoryCache()->Remove(resource1);
if (!identifier1.IsEmpty())
resource1->SetCacheIdentifier(identifier1);
resource1->AppendData(kData, 3u);
resource1->FinishForTest();
- FetchParameters params2(ResourceRequest("data:text/html,resource2"));
+ FetchParameters params2(ResourceRequest("data:image/jpeg,resource2"));
Persistent<MockResourceClient> client =
MakeGarbageCollected<MockResourceClient>();
Resource* resource2 = FakeDecodedResource::Fetch(params2, fetcher, client);
@@ -230,25 +228,11 @@ static void TestResourcePruningLater(ResourceFetcher* fetcher,
}
// Verified that when ordering a prune in a runLoop task, the prune is deferred.
-// TODO(crbug.com/850788): Reenable this.
-#if defined(OS_ANDROID)
-#define MAYBE_ResourcePruningLater_Basic DISABLED_ResourcePruningLater_Basic
-#else
-#define MAYBE_ResourcePruningLater_Basic ResourcePruningLater_Basic
-#endif
-TEST_F(MemoryCacheTest, MAYBE_ResourcePruningLater_Basic) {
+TEST_F(MemoryCacheTest, ResourcePruningLater_Basic) {
TestResourcePruningLater(fetcher_, "", "");
}
-// TODO(crbug.com/850788): Reenable this.
-#if defined(OS_ANDROID)
-#define MAYBE_ResourcePruningLater_MultipleResourceMaps \
- DISABLED_ResourcePruningLater_MultipleResourceMaps
-#else
-#define MAYBE_ResourcePruningLater_MultipleResourceMaps \
- ResourcePruningLater_MultipleResourceMaps
-#endif
-TEST_F(MemoryCacheTest, MAYBE_ResourcePruningLater_MultipleResourceMaps) {
+TEST_F(MemoryCacheTest, ResourcePruningLater_MultipleResourceMaps) {
{
TestResourcePruningLater(fetcher_, "foo", "");
GetMemoryCache()->EvictResources();
@@ -272,9 +256,9 @@ static void TestClientRemoval(ResourceFetcher* fetcher,
MakeGarbageCollected<MockResourceClient>();
Persistent<MockResourceClient> client2 =
MakeGarbageCollected<MockResourceClient>();
- FetchParameters params1(ResourceRequest("data:text/html,foo"));
+ FetchParameters params1(ResourceRequest("data:image/jpeg,foo"));
Resource* resource1 = FakeDecodedResource::Fetch(params1, fetcher, client1);
- FetchParameters params2(ResourceRequest("data:text/html,bar"));
+ FetchParameters params2(ResourceRequest("data:image/jpeg,bar"));
Resource* resource2 = FakeDecodedResource::Fetch(params2, fetcher, client2);
resource1->AppendData(kData, 4u);
resource2->AppendData(kData, 4u);
@@ -327,25 +311,11 @@ static void TestClientRemoval(ResourceFetcher* fetcher,
EXPECT_EQ(0u, GetMemoryCache()->size());
}
-// TODO(crbug.com/850788): Reenable this.
-#if defined(OS_ANDROID)
-#define MAYBE_ClientRemoval_Basic DISABLED_ClientRemoval_Basic
-#else
-#define MAYBE_ClientRemoval_Basic ClientRemoval_Basic
-#endif
-TEST_F(MemoryCacheTest, MAYBE_ClientRemoval_Basic) {
+TEST_F(MemoryCacheTest, ClientRemoval_Basic) {
TestClientRemoval(fetcher_, "", "");
}
-// TODO(crbug.com/850788): Reenable this.
-#if defined(OS_ANDROID)
-#define MAYBE_ClientRemoval_MultipleResourceMaps \
- DISABLED_ClientRemoval_MultipleResourceMaps
-#else
-#define MAYBE_ClientRemoval_MultipleResourceMaps \
- ClientRemoval_MultipleResourceMaps
-#endif
-TEST_F(MemoryCacheTest, MAYBE_ClientRemoval_MultipleResourceMaps) {
+TEST_F(MemoryCacheTest, ClientRemoval_MultipleResourceMaps) {
{
TestClientRemoval(fetcher_, "foo", "");
GetMemoryCache()->EvictResources();
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 8a00bb48575..3a93692ce8b 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
@@ -6,6 +6,7 @@
#include "services/network/public/mojom/ip_address_space.mojom-blink.h"
#include "services/network/public/mojom/referrer_policy.mojom-blink.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
#include "third_party/blink/renderer/platform/loader/allowed_by_nosniff.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h"
#include "third_party/blink/renderer/platform/loader/fetch/https_state.h"
@@ -25,7 +26,7 @@ NullResourceFetcherProperties::NullResourceFetcherProperties()
HttpsState::kNone,
AllowedByNosniff::MimeTypeCheck::kStrict,
network::mojom::IPAddressSpace::kPublic,
- kLeaveInsecureRequestsAlone,
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone,
FetchClientSettingsObject::InsecureNavigationsSet())) {}
void NullResourceFetcherProperties::Trace(Visitor* visitor) {
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 4d15c82e932..449d18c456b 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
@@ -55,6 +55,7 @@ RawResource* RawResource::FetchImport(FetchParameters& params,
ResourceFetcher* fetcher,
RawResourceClient* client) {
params.SetRequestContext(mojom::RequestContextType::IMPORT);
+ params.SetRequestDestination(network::mojom::RequestDestination::kEmpty);
return ToRawResource(fetcher->RequestResource(
params, RawResourceFactory(ResourceType::kImportResource), client));
}
@@ -85,6 +86,7 @@ RawResource* RawResource::FetchTextTrack(FetchParameters& params,
ResourceFetcher* fetcher,
RawResourceClient* client) {
params.SetRequestContext(mojom::RequestContextType::TRACK);
+ params.SetRequestDestination(network::mojom::RequestDestination::kTrack);
return ToRawResource(fetcher->RequestResource(
params, RawResourceFactory(ResourceType::kTextTrack), client));
}
@@ -171,8 +173,8 @@ void RawResource::DidAddClient(ResourceClient* c) {
RevalidationStartForbiddenScope revalidation_start_forbidden_scope(this);
RawResourceClient* client = static_cast<RawResourceClient*>(c);
for (const auto& redirect : RedirectChain()) {
- ResourceRequest request(redirect.request_);
- client->RedirectReceived(this, request, redirect.redirect_response_);
+ client->RedirectReceived(this, ResourceRequest(redirect.request_),
+ redirect.redirect_response_);
if (!HasClient(c))
return;
}
@@ -406,8 +408,6 @@ void RawResourceClient::DidDownloadToBlob(Resource*,
RawResourceClientStateChecker::RawResourceClientStateChecker()
: state_(kNotAddedAsClient) {}
-RawResourceClientStateChecker::~RawResourceClientStateChecker() = default;
-
NOINLINE void RawResourceClientStateChecker::WillAddClient() {
SECURITY_CHECK(state_ == kNotAddedAsClient);
state_ = kStarted;
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 11aa7531c9a..3a22921c1f3 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
@@ -63,7 +63,7 @@ class PLATFORM_EXPORT RawResource final : public Resource {
RawResourceClient*);
// Exposed for testing
- static RawResource* CreateForTest(ResourceRequest request,
+ static RawResource* CreateForTest(const ResourceRequest& request,
ResourceType type) {
ResourceLoaderOptions options;
return MakeGarbageCollected<RawResource>(request, type, options);
@@ -207,7 +207,6 @@ class PLATFORM_EXPORT RawResourceClientStateChecker final {
public:
RawResourceClientStateChecker();
- ~RawResourceClientStateChecker();
// Call before addClient()/removeClient() is called.
void WillAddClient();
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 4a1276b11b0..a469fe6ae20 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
@@ -92,7 +92,7 @@ TEST_F(RawResourceTest, DontIgnoreAcceptForCacheReuse) {
ResourceRequest png_request;
png_request.SetHTTPAccept("image/png");
png_request.SetRequestorOrigin(source_origin);
- EXPECT_NE(jpeg_resource->CanReuse(FetchParameters(png_request)),
+ EXPECT_NE(jpeg_resource->CanReuse(FetchParameters(std::move(png_request))),
Resource::MatchStatus::kOk);
}
@@ -124,9 +124,7 @@ class DummyClient final : public GarbageCollected<DummyClient>,
return number_of_redirects_received_;
}
const Vector<char>& Data() { return data_; }
- void Trace(blink::Visitor* visitor) override {
- RawResourceClient::Trace(visitor);
- }
+ void Trace(Visitor* visitor) override { RawResourceClient::Trace(visitor); }
private:
bool called_;
@@ -162,7 +160,7 @@ class AddingClient final : public GarbageCollected<AddingClient>,
void RemoveClient() { resource_->RemoveClient(dummy_client_); }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(dummy_client_);
visitor->Trace(resource_);
RawResourceClient::Trace(visitor);
@@ -207,7 +205,7 @@ class RemovingClient : public GarbageCollected<RemovingClient>,
resource->RemoveClient(this);
}
String DebugName() const override { return "RemovingClient"; }
- void Trace(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(dummy_client_);
RawResourceClient::Trace(visitor);
}
@@ -255,7 +253,7 @@ TEST_F(RawResourceTest, PreloadWithAsynchronousAddClient) {
// Set the response first to make ResourceClient addition asynchronous.
raw->SetResponse(ResourceResponse(KURL("http://600.613/")));
- FetchParameters params(request);
+ FetchParameters params(std::move(request));
params.MutableResourceRequest().SetUseStreamOnResponse(false);
raw->MatchPreload(params, platform_->test_task_runner().get());
raw->AddClient(dummy_client, platform_->test_task_runner().get());
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 a94e9665eaf..d7c24f32f9e 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource.cc
@@ -122,8 +122,7 @@ const char* const kHeaderPrefixesToIgnoreAfterRevalidation[] = {
static inline bool ShouldUpdateHeaderAfterRevalidation(
const AtomicString& header) {
for (size_t i = 0; i < base::size(kHeadersToIgnoreAfterRevalidation); i++) {
- if (DeprecatedEqualIgnoringCase(header,
- kHeadersToIgnoreAfterRevalidation[i]))
+ if (EqualIgnoringASCIICase(header, kHeadersToIgnoreAfterRevalidation[i]))
return false;
}
for (size_t i = 0; i < base::size(kHeaderPrefixesToIgnoreAfterRevalidation);
@@ -146,7 +145,7 @@ static inline base::Time Now() {
return clock->Now();
}
-Resource::Resource(const ResourceRequest& request,
+Resource::Resource(const ResourceRequestHead& request,
ResourceType type,
const ResourceLoaderOptions& options)
: type_(type),
@@ -174,7 +173,7 @@ Resource::~Resource() {
InstanceCounters::DecrementCounter(InstanceCounters::kResourceCounter);
}
-void Resource::Trace(blink::Visitor* visitor) {
+void Resource::Trace(Visitor* visitor) {
visitor->Trace(loader_);
visitor->Trace(cache_handler_);
visitor->Trace(clients_);
@@ -472,7 +471,7 @@ static bool CanUseResponse(const ResourceResponse& response,
return CurrentAge(response, response_timestamp) <= max_life;
}
-const ResourceRequest& Resource::LastResourceRequest() const {
+const ResourceRequestHead& Resource::LastResourceRequest() const {
if (!redirect_chain_.size())
return GetResourceRequest();
return redirect_chain_.back().request_;
@@ -484,7 +483,7 @@ const ResourceResponse* Resource::LastResourceResponse() const {
return &redirect_chain_.back().redirect_response_;
}
-void Resource::SetRevalidatingRequest(const ResourceRequest& request) {
+void Resource::SetRevalidatingRequest(const ResourceRequestHead& request) {
SECURITY_CHECK(redirect_chain_.IsEmpty());
SECURITY_CHECK(!is_unused_preload_);
DCHECK(!request.IsNull());
@@ -567,22 +566,23 @@ String Resource::ReasonNotDeletable() const {
return builder.ToString();
}
-void Resource::DidAddClient(ResourceClient* c) {
+void Resource::DidAddClient(ResourceClient* client) {
if (scoped_refptr<SharedBuffer> data = Data()) {
for (const auto& span : *data) {
- c->DataReceived(this, span.data(), span.size());
+ client->DataReceived(this, span.data(), span.size());
// Stop pushing data if the client removed itself.
- if (!HasClient(c))
+ if (!HasClient(client))
break;
}
}
- if (!HasClient(c))
+ if (!HasClient(client))
return;
if (IsFinishedInternal()) {
- c->NotifyFinished(this);
- if (clients_.Contains(c)) {
- finished_clients_.insert(c);
- clients_.erase(c);
+ client->SetHasFinishedFromMemoryCache();
+ client->NotifyFinished(this);
+ if (clients_.Contains(client)) {
+ finished_clients_.insert(client);
+ clients_.erase(client);
}
}
}
@@ -823,12 +823,13 @@ Resource::MatchStatus Resource::CanReuse(const FetchParameters& params) const {
if (resource_request_.GetKeepalive() || new_request.GetKeepalive())
return MatchStatus::kKeepaliveSet;
- if (GetResourceRequest().HttpMethod() != new_request.HttpMethod())
+ if (GetResourceRequest().HttpMethod() != http_names::kGET ||
+ new_request.HttpMethod() != http_names::kGET) {
return MatchStatus::kRequestMethodDoesNotMatch;
+ }
- if (GetResourceRequest().HttpBody() != new_request.HttpBody())
- return MatchStatus::kUnknownFailure;
-
+ // A GET request doesn't have a request body.
+ DCHECK(!new_request.HttpBody());
// Don't reuse an existing resource when the source origin is different.
if (!existing_origin->IsSameOriginWith(new_origin.get()))
@@ -851,8 +852,6 @@ Resource::MatchStatus Resource::CanReuse(const FetchParameters& params) const {
switch (new_mode) {
case network::mojom::RequestMode::kNoCors:
case network::mojom::RequestMode::kNavigate:
- case network::mojom::RequestMode::kNavigateNestedFrame:
- case network::mojom::RequestMode::kNavigateNestedObject:
break;
case network::mojom::RequestMode::kCors:
@@ -887,7 +886,7 @@ void Resource::OnPurgeMemory() {
Prune();
if (!cache_handler_)
return;
- cache_handler_->ClearCachedMetadata(CachedMetadataHandler::kCacheLocally);
+ cache_handler_->ClearCachedMetadata(CachedMetadataHandler::kClearLocally);
}
void Resource::OnMemoryDump(WebMemoryDumpLevelOfDetail level_of_detail,
@@ -1068,8 +1067,7 @@ bool Resource::MustRevalidateDueToCacheHeaders(bool allow_stale) const {
GetResourceRequest().CacheControlContainsNoStore();
}
-static bool ShouldRevalidateStaleResponse(const ResourceRequest& request,
- const ResourceResponse& response,
+static bool ShouldRevalidateStaleResponse(const ResourceResponse& response,
base::Time response_timestamp) {
base::TimeDelta staleness = response.CacheControlStaleWhileRevalidate();
if (staleness.is_zero())
@@ -1083,15 +1081,14 @@ bool Resource::ShouldRevalidateStaleResponse() const {
for (auto& redirect : redirect_chain_) {
// Use |response_timestamp_| since we don't store the timestamp
// of each redirect response.
- if (blink::ShouldRevalidateStaleResponse(redirect.request_,
- redirect.redirect_response_,
+ if (blink::ShouldRevalidateStaleResponse(redirect.redirect_response_,
response_timestamp_)) {
return true;
}
}
- return blink::ShouldRevalidateStaleResponse(
- GetResourceRequest(), GetResponse(), response_timestamp_);
+ return blink::ShouldRevalidateStaleResponse(GetResponse(),
+ response_timestamp_);
}
bool Resource::StaleRevalidationRequested() const {
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 9b83d433ec0..4dc121198b8 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource.h
@@ -157,7 +157,7 @@ class PLATFORM_EXPORT Resource : public GarbageCollected<Resource>,
~Resource() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
virtual WTF::TextEncoding Encoding() const { return WTF::TextEncoding(); }
virtual void AppendData(const char*, size_t);
@@ -176,13 +176,13 @@ class PLATFORM_EXPORT Resource : public GarbageCollected<Resource>,
virtual bool ShouldIgnoreHTTPStatusCodeErrors() const { return false; }
- const ResourceRequest& GetResourceRequest() const {
+ const ResourceRequestHead& GetResourceRequest() const {
return resource_request_;
}
- const ResourceRequest& LastResourceRequest() const;
+ const ResourceRequestHead& LastResourceRequest() const;
const ResourceResponse* LastResourceResponse() const;
- virtual void SetRevalidatingRequest(const ResourceRequest&);
+ virtual void SetRevalidatingRequest(const ResourceRequestHead&);
// This url can have a fragment, but it can match resources that differ by the
// fragment only.
@@ -374,13 +374,6 @@ class PLATFORM_EXPORT Resource : public GarbageCollected<Resource>,
// be triggered right away in ResourceLoader.
virtual void WillReloadAfterDiskCacheMiss() {}
- // TODO(shaochuan): This is for saving back the actual ResourceRequest sent
- // in ResourceFetcher::StartLoad() for retry in cache-aware loading, remove
- // once ResourceRequest is not modified in StartLoad(). crbug.com/632580
- void SetResourceRequest(const ResourceRequest& resource_request) {
- resource_request_ = resource_request;
- }
-
// Used by the MemoryCache to reduce the memory consumption of the entry.
void Prune();
@@ -426,8 +419,14 @@ class PLATFORM_EXPORT Resource : public GarbageCollected<Resource>,
// The caller owns the |clock| which must outlive the Resource.
static void SetClockForTesting(const base::Clock* clock);
+ size_t CalculateOverheadSizeForTest() const {
+ return CalculateOverheadSize();
+ }
+
protected:
- Resource(const ResourceRequest&, ResourceType, const ResourceLoaderOptions&);
+ Resource(const ResourceRequestHead&,
+ 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
@@ -473,11 +472,11 @@ class PLATFORM_EXPORT Resource : public GarbageCollected<Resource>,
DISALLOW_NEW();
public:
- explicit RedirectPair(const ResourceRequest& request,
+ explicit RedirectPair(const ResourceRequestHead& request,
const ResourceResponse& redirect_response)
: request_(request), redirect_response_(redirect_response) {}
- ResourceRequest request_;
+ ResourceRequestHead request_;
ResourceResponse redirect_response_;
};
const Vector<RedirectPair>& RedirectChain() const { return redirect_chain_; }
@@ -566,7 +565,7 @@ class PLATFORM_EXPORT Resource : public GarbageCollected<Resource>,
TaskHandle async_finish_pending_clients_task_;
- ResourceRequest resource_request_;
+ ResourceRequestHead resource_request_;
// Resource::CalculateOverheadSize() is affected by changes in
// |m_resourceRequest.url()|, but |m_overheadSize| is not updated after
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 dced85b7646..a4ea28e5e0f 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
@@ -64,6 +64,9 @@ class PLATFORM_EXPORT ResourceClient : public GarbageCollectedMixin {
Resource* GetResource() const { return resource_; }
+ bool FinishedFromMemoryCache() const { return finished_from_memory_cache_; }
+ void SetHasFinishedFromMemoryCache() { finished_from_memory_cache_ = true; }
+
// Name for debugging, e.g. shown in memory-infra.
virtual String DebugName() const = 0;
@@ -86,6 +89,10 @@ class PLATFORM_EXPORT ResourceClient : public GarbageCollectedMixin {
base::SingleThreadTaskRunner* task_runner);
Member<Resource> resource_;
+
+ // If true, the Resource was already available from the memory cache when this
+ // ResourceClient was setup, so that the request finished immediately.
+ bool finished_from_memory_cache_ = false;
};
} // namespace blink
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 8451bf18965..a6706847ef4 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
@@ -96,10 +96,12 @@ ResourceError::ResourceError(const KURL& url,
ResourceError::ResourceError(const WebURLError& error)
: error_code_(error.reason()),
extended_error_code_(error.extended_reason()),
+ resolve_error_info_(error.resolve_error_info()),
failing_url_(error.url()),
is_access_check_(error.is_web_security_violation()),
has_copy_in_cache_(error.has_copy_in_cache()),
- cors_error_status_(error.cors_error_status()) {
+ cors_error_status_(error.cors_error_status()),
+ blocked_by_response_reason_(error.blocked_by_response_reason()) {
DCHECK_NE(error_code_, 0);
InitializeDescription();
}
@@ -108,6 +110,7 @@ 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_;
@@ -124,11 +127,11 @@ ResourceError::operator WebURLError() const {
return WebURLError(*cors_error_status_, has_copy_in_cache, failing_url_);
}
- return WebURLError(error_code_, extended_error_code_, has_copy_in_cache,
- is_access_check_
- ? WebURLError::IsWebSecurityViolation::kTrue
- : WebURLError::IsWebSecurityViolation::kFalse,
- failing_url_);
+ return WebURLError(
+ error_code_, extended_error_code_, resolve_error_info_, has_copy_in_cache,
+ is_access_check_ ? WebURLError::IsWebSecurityViolation::kTrue
+ : WebURLError::IsWebSecurityViolation::kFalse,
+ failing_url_);
}
bool ResourceError::Compare(const ResourceError& a, const ResourceError& b) {
@@ -153,6 +156,9 @@ bool ResourceError::Compare(const ResourceError& a, const ResourceError& b) {
if (a.extended_error_code_ != b.extended_error_code_)
return false;
+ if (a.resolve_error_info_ != b.resolve_error_info_)
+ return false;
+
return true;
}
@@ -178,12 +184,45 @@ bool ResourceError::ShouldCollapseInitiator() const {
ResourceRequestBlockedReason::kCollapsedByClient;
}
+namespace {
+
+blink::ResourceRequestBlockedReason
+BlockedByResponseReasonToResourceRequestBlockedReason(
+ network::BlockedByResponseReason reason) {
+ switch (reason) {
+ case network::BlockedByResponseReason::kCoepFrameResourceNeedsCoepHeader:
+ return blink::ResourceRequestBlockedReason::
+ kCoepFrameResourceNeedsCoepHeader;
+ case network::BlockedByResponseReason::
+ kCoopSandboxedIFrameCannotNavigateToCoopPage:
+ return blink::ResourceRequestBlockedReason::
+ kCoopSandboxedIFrameCannotNavigateToCoopPage;
+ case network::BlockedByResponseReason::kCorpNotSameOrigin:
+ return blink::ResourceRequestBlockedReason::kCorpNotSameOrigin;
+ case network::BlockedByResponseReason::
+ kCorpNotSameOriginAfterDefaultedToSameOriginByCoep:
+ return blink::ResourceRequestBlockedReason::
+ kCorpNotSameOriginAfterDefaultedToSameOriginByCoep;
+ break;
+ case network::BlockedByResponseReason::kCorpNotSameSite:
+ return blink::ResourceRequestBlockedReason::kCorpNotSameSite;
+ break;
+ }
+ NOTREACHED();
+ return blink::ResourceRequestBlockedReason::kOther;
+}
+
+} // namespace
base::Optional<ResourceRequestBlockedReason>
ResourceError::GetResourceRequestBlockedReason() const {
if (error_code_ != net::ERR_BLOCKED_BY_CLIENT &&
error_code_ != net::ERR_BLOCKED_BY_RESPONSE) {
return base::nullopt;
}
+ if (blocked_by_response_reason_) {
+ return BlockedByResponseReasonToResourceRequestBlockedReason(
+ *blocked_by_response_reason_);
+ }
return static_cast<ResourceRequestBlockedReason>(extended_error_code_);
}
@@ -217,6 +256,23 @@ String DescriptionForBlockedByClientOrResponse(int error, int extended_error) {
case ResourceRequestBlockedReason::kCollapsedByClient:
detail = "Collapsed";
break;
+ case ResourceRequestBlockedReason::kCoepFrameResourceNeedsCoepHeader:
+ detail = "ResponseNeedsCrossOriginEmbedderPolicy";
+ break;
+ case ResourceRequestBlockedReason::
+ kCoopSandboxedIFrameCannotNavigateToCoopPage:
+ detail = "SandboxedIFrameCannotNavigateToOriginIsolatedPage";
+ break;
+ case ResourceRequestBlockedReason::kCorpNotSameOrigin:
+ detail = "NotSameOrigin";
+ break;
+ case ResourceRequestBlockedReason::
+ kCorpNotSameOriginAfterDefaultedToSameOriginByCoep:
+ detail = "NotSameOriginAfterDefaultedToSameOriginByCoep";
+ break;
+ case ResourceRequestBlockedReason::kCorpNotSameSite:
+ detail = "NotSameSite";
+ break;
}
return WebString::FromASCII(net::ErrorToString(error) + "." + detail);
}
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 592174eae92..19c60919c24 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
@@ -29,6 +29,8 @@
#include <iosfwd>
#include "base/optional.h"
+#include "net/dns/public/resolve_error_info.h"
+#include "services/network/public/cpp/blocked_by_response_reason.h"
#include "services/network/public/cpp/cors/cors_error_status.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -99,12 +101,15 @@ class PLATFORM_EXPORT ResourceError final {
int error_code_;
int extended_error_code_ = 0;
+ net::ResolveErrorInfo resolve_error_info_;
KURL failing_url_;
String localized_description_;
bool is_access_check_ = false;
bool has_copy_in_cache_ = false;
bool blocked_by_subresource_filter_ = false;
base::Optional<network::CorsErrorStatus> cors_error_status_;
+
+ base::Optional<network::BlockedByResponseReason> blocked_by_response_reason_;
};
inline bool operator==(const ResourceError& a, const ResourceError& b) {
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 d55eaa3ac98..04ed5036553 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
@@ -34,15 +34,15 @@
#include "base/auto_reset.h"
#include "base/debug/dump_without_crashing.h"
#include "base/feature_list.h"
+#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
#include "services/network/public/cpp/request_mode.h"
#include "third_party/blink/public/common/features.h"
-#include "third_party/blink/public/common/loader/request_destination.h"
#include "third_party/blink/public/common/mime_util/mime_util.h"
+#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/devtools/console_message.mojom-blink.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/public/mojom/web_feature/web_feature.mojom-blink.h"
-#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/scheduler/web_scoped_virtual_time_pauser.h"
#include "third_party/blink/public/platform/web_url.h"
@@ -78,10 +78,10 @@
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/weborigin/known_ports.h"
#include "third_party/blink/renderer/platform/weborigin/origin_access_entry.h"
+#include "third_party/blink/renderer/platform/weborigin/reporting_disposition.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/weborigin/security_policy.h"
-#include "third_party/blink/renderer/platform/weborigin/security_violation_reporting_policy.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -98,13 +98,12 @@ namespace {
constexpr base::TimeDelta kKeepaliveLoadersTimeout =
base::TimeDelta::FromSeconds(30);
-#define DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, name) \
- case ResourceType::k##name: { \
- DEFINE_THREAD_SAFE_STATIC_LOCAL( \
- EnumerationHistogram, _single_resource_histogram, \
- ("Blink.MemoryCache.RevalidationPolicy." prefix #name, kLoad + 1)); \
- _single_resource_histogram.Count(policy); \
- break; \
+#define RESOURCE_HISTOGRAM_PREFIX "Blink.MemoryCache.RevalidationPolicy."
+
+#define DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, name) \
+ case ResourceType::k##name: { \
+ UMA_HISTOGRAM_ENUMERATION(RESOURCE_HISTOGRAM_PREFIX prefix #name, policy); \
+ break; \
}
#define DEFINE_RESOURCE_HISTOGRAM(prefix) \
@@ -159,24 +158,12 @@ ResourceLoadPriority TypeToPriority(ResourceType type) {
return ResourceLoadPriority::kUnresolved;
}
-static bool IsCacheableHTTPMethod(const AtomicString& method) {
- // Per http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.10,
- // these methods always invalidate the cache entry.
- return method != http_names::kPOST && method != http_names::kPUT &&
- method != "DELETE";
-}
-
bool ShouldResourceBeAddedToMemoryCache(const FetchParameters& params,
Resource* resource) {
- if (!IsMainThread())
- return false;
- if (params.Options().data_buffering_policy == kDoNotBufferData)
- return false;
- if (IsRawResource(*resource))
- return false;
- if (!IsCacheableHTTPMethod(params.GetResourceRequest().HttpMethod()))
- return false;
- return true;
+ return IsMainThread() &&
+ params.GetResourceRequest().HttpMethod() == http_names::kGET &&
+ params.Options().data_buffering_policy != kDoNotBufferData &&
+ !IsRawResource(*resource);
}
static ResourceFetcher::ResourceFetcherSet& MainThreadFetchersSet() {
@@ -204,7 +191,7 @@ static ThreadSpecific<PriorityObserverMap>& PriorityObservers() {
ResourceLoadPriority AdjustPriorityWithPriorityHint(
ResourceLoadPriority priority_so_far,
ResourceType type,
- const ResourceRequest& resource_request,
+ const ResourceRequestHead& resource_request,
FetchParameters::DeferOption defer_option,
bool is_link_preload) {
mojom::FetchImportanceMode importance_mode =
@@ -254,7 +241,7 @@ ResourceLoadPriority AdjustPriorityWithDeferScriptIntervention(
const FetchContext& fetch_context,
ResourceLoadPriority priority_so_far,
ResourceType type,
- const ResourceRequest& resource_request,
+ const ResourceRequestHead& resource_request,
FetchParameters::DeferOption defer_option,
bool is_link_preload) {
if (!base::FeatureList::IsEnabled(
@@ -307,65 +294,20 @@ std::unique_ptr<TracedValue> ResourcePrioritySetData(
void SetReferrer(
ResourceRequest& request,
const FetchClientSettingsObject& fetch_client_settings_object) {
- if (!request.DidSetHttpReferrer()) {
- String referrer_to_use = request.ReferrerString();
- network::mojom::ReferrerPolicy referrer_policy_to_use =
- request.GetReferrerPolicy();
-
- if (referrer_to_use == Referrer::ClientReferrerString())
- referrer_to_use = fetch_client_settings_object.GetOutgoingReferrer();
-
- if (referrer_policy_to_use == network::mojom::ReferrerPolicy::kDefault)
- referrer_policy_to_use = fetch_client_settings_object.GetReferrerPolicy();
-
- request.SetReferrerString(referrer_to_use);
- request.SetReferrerPolicy(referrer_policy_to_use);
- // TODO(domfarolino): Stop storing ResourceRequest's referrer as a header
- // and store it elsewhere. See https://crbug.com/850813.
- request.SetHttpReferrer(SecurityPolicy::GenerateReferrer(
- referrer_policy_to_use, request.Url(), referrer_to_use));
- } else {
- // In the case of stale requests that are being revalidated, these requests
- // will already have their HttpReferrer set, and we will end up here. We
- // won't regenerate the referrer, but instead check that it's still correct.
- CHECK_EQ(SecurityPolicy::GenerateReferrer(request.GetReferrerPolicy(),
- request.Url(),
- request.ReferrerString())
- .referrer,
- request.HttpReferrer());
- }
-}
+ String referrer_to_use = request.ReferrerString();
+ network::mojom::ReferrerPolicy referrer_policy_to_use =
+ request.GetReferrerPolicy();
-void SetSecFetchHeaders(
- ResourceRequest& request,
- const FetchClientSettingsObject& fetch_client_settings_object) {
- scoped_refptr<SecurityOrigin> url_origin =
- SecurityOrigin::Create(request.Url());
- if (blink::RuntimeEnabledFeatures::FetchMetadataEnabled() &&
- url_origin->IsPotentiallyTrustworthy()) {
- const char* destination_value =
- GetRequestDestinationFromContext(request.GetRequestContext());
-
- // If the request's destination is the empty string (e.g. `fetch()`), then
- // we'll use the identifier "empty" instead.
- if (strlen(destination_value) == 0)
- destination_value = "empty";
-
- // We'll handle adding these headers to navigations outside of Blink.
- if ((strncmp(destination_value, "document", 8) != 0 ||
- strncmp(destination_value, "iframe", 6) != 0 ||
- strncmp(destination_value, "frame", 5) != 0) &&
- request.GetRequestContext() != mojom::RequestContextType::INTERNAL) {
- if (blink::RuntimeEnabledFeatures::FetchMetadataDestinationEnabled()) {
- request.SetHttpHeaderField("Sec-Fetch-Dest", destination_value);
- }
+ if (referrer_to_use == Referrer::ClientReferrerString())
+ referrer_to_use = fetch_client_settings_object.GetOutgoingReferrer();
- // Note that the `Sec-Fetch-User` header is always false (and therefore
- // omitted) for subresource requests. Likewise, note that we rely on
- // Blink's embedder to set `Sec-Fetch-Site`, as we don't want to trust the
- // renderer to assert its own origin. Ditto for `Sec-Fetch-Mode`.
- }
- }
+ if (referrer_policy_to_use == network::mojom::ReferrerPolicy::kDefault)
+ referrer_policy_to_use = fetch_client_settings_object.GetReferrerPolicy();
+
+ Referrer generated_referrer = SecurityPolicy::GenerateReferrer(
+ referrer_policy_to_use, request.Url(), referrer_to_use);
+ request.SetReferrerString(generated_referrer.referrer);
+ request.SetReferrerPolicy(generated_referrer.referrer_policy);
}
} // namespace
@@ -375,7 +317,7 @@ ResourceFetcherInit::ResourceFetcherInit(
FetchContext* context,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
ResourceFetcher::LoaderFactory* loader_factory)
- : properties(properties),
+ : properties(&properties),
context(context),
task_runner(std::move(task_runner)),
loader_factory(loader_factory) {
@@ -426,6 +368,40 @@ mojom::RequestContextType ResourceFetcher::DetermineRequestContext(
return mojom::RequestContextType::SUBRESOURCE;
}
+network::mojom::RequestDestination ResourceFetcher::DetermineRequestDestination(
+ ResourceType type) {
+ switch (type) {
+ case ResourceType::kXSLStyleSheet:
+ DCHECK(RuntimeEnabledFeatures::XSLTEnabled());
+ FALLTHROUGH;
+ case ResourceType::kCSSStyleSheet:
+ return network::mojom::RequestDestination::kStyle;
+ case ResourceType::kScript:
+ return network::mojom::RequestDestination::kScript;
+ case ResourceType::kFont:
+ return network::mojom::RequestDestination::kFont;
+ case ResourceType::kImage:
+ return network::mojom::RequestDestination::kImage;
+ case ResourceType::kTextTrack:
+ return network::mojom::RequestDestination::kTrack;
+ case ResourceType::kSVGDocument:
+ return network::mojom::RequestDestination::kImage;
+ case ResourceType::kAudio:
+ return network::mojom::RequestDestination::kAudio;
+ case ResourceType::kVideo:
+ return network::mojom::RequestDestination::kVideo;
+ case ResourceType::kManifest:
+ return network::mojom::RequestDestination::kManifest;
+ case ResourceType::kRaw:
+ case ResourceType::kImportResource:
+ case ResourceType::kLinkPrefetch:
+ case ResourceType::kMock:
+ return network::mojom::RequestDestination::kEmpty;
+ }
+ NOTREACHED();
+ return network::mojom::RequestDestination::kEmpty;
+}
+
// static
void ResourceFetcher::AddPriorityObserverForTesting(
const KURL& resource_url,
@@ -441,7 +417,7 @@ void ResourceFetcher::AddPriorityObserverForTesting(
// images, which may need to be reprioritized.
ResourceLoadPriority ResourceFetcher::ComputeLoadPriority(
ResourceType type,
- const ResourceRequest& resource_request,
+ const ResourceRequestHead& resource_request,
ResourcePriority::VisibilityStatus visibility,
FetchParameters::DeferOption defer_option,
FetchParameters::SpeculativePreloadType speculative_preload_type,
@@ -524,17 +500,13 @@ ResourceLoadPriority ResourceFetcher::ComputeLoadPriority(
if (properties_->IsSubframeDeprioritizationEnabled()) {
if (properties_->IsMainFrame()) {
- DEFINE_STATIC_LOCAL(
- EnumerationHistogram, main_frame_priority_histogram,
- ("LowPriorityIframes.MainFrameRequestPriority",
- static_cast<int>(ResourceLoadPriority::kHighest) + 1));
- main_frame_priority_histogram.Count(static_cast<int>(priority));
+ UMA_HISTOGRAM_ENUMERATION(
+ "LowPriorityIframes.MainFrameRequestPriority", priority,
+ static_cast<int>(ResourceLoadPriority::kHighest) + 1);
} else {
- DEFINE_STATIC_LOCAL(
- EnumerationHistogram, iframe_priority_histogram,
- ("LowPriorityIframes.IframeRequestPriority",
- static_cast<int>(ResourceLoadPriority::kHighest) + 1));
- iframe_priority_histogram.Count(static_cast<int>(priority));
+ UMA_HISTOGRAM_ENUMERATION(
+ "LowPriorityIframes.IframeRequestPriority", priority,
+ static_cast<int>(ResourceLoadPriority::kHighest) + 1);
// When enabled, the priority of all resources in subframe is dropped.
// Non-delayable resources are assigned a priority of kLow, and the rest
// of them are assigned a priority of kLowest. This ensures that if the
@@ -556,10 +528,10 @@ ResourceFetcher::ResourceFetcher(const ResourceFetcherInit& init)
context_(init.context),
task_runner_(init.task_runner),
use_counter_(init.use_counter
- ? init.use_counter.Get()
+ ? init.use_counter
: MakeGarbageCollected<DetachableUseCounter>(nullptr)),
console_logger_(init.console_logger
- ? init.console_logger.Get()
+ ? init.console_logger
: MakeGarbageCollected<DetachableConsoleLogger>()),
loader_factory_(init.loader_factory),
scheduler_(MakeGarbageCollected<ResourceLoadScheduler>(
@@ -622,7 +594,7 @@ bool ResourceFetcher::ResourceNeedsLoad(Resource* resource,
FetchParameters::kDeferImageLoad)) {
return false;
}
- return policy != kUse || resource->StillNeedsLoad();
+ return policy != RevalidationPolicy::kUse || resource->StillNeedsLoad();
}
void ResourceFetcher::DidLoadResourceFromMemoryCache(
@@ -653,7 +625,7 @@ void ResourceFetcher::DidLoadResourceFromMemoryCache(
// they're used.
scoped_refptr<ResourceTimingInfo> info = ResourceTimingInfo::Create(
resource->Options().initiator_info.name, base::TimeTicks::Now(),
- request.GetRequestContext());
+ request.GetRequestContext(), request.GetRequestDestination());
// TODO(yoav): GetInitialUrlForResourceTiming() is only needed until
// Out-of-Blink CORS lands: https://crbug.com/736308
info->SetInitialURL(
@@ -772,11 +744,6 @@ void ResourceFetcher::UpdateMemoryCacheStats(Resource* resource,
if (is_static_data)
return;
- DEFINE_THREAD_SAFE_STATIC_LOCAL(
- BooleanHistogram, resource_histogram,
- ("Blink.ResourceFetcher.StaleWhileRevalidate"));
- resource_histogram.Count(params.IsStaleRevalidation());
-
if (params.IsSpeculativePreload() || params.IsLinkPreload()) {
DEFINE_RESOURCE_HISTOGRAM("Preload.");
} else {
@@ -790,6 +757,13 @@ void ResourceFetcher::UpdateMemoryCacheStats(Resource* resource,
if (resource && !resource->IsAlive() && !ContainsAsPreload(resource)) {
DEFINE_RESOURCE_HISTOGRAM("Dead.");
}
+
+ // Async (and defer) scripts may have more cache misses, track them
+ // separately. See https://crbug.com/1043679 for context.
+ if (params.Defer() != FetchParameters::DeferOption::kNoDefer &&
+ factory.GetType() == ResourceType::kScript) {
+ UMA_HISTOGRAM_ENUMERATION(RESOURCE_HISTOGRAM_PREFIX "AsyncScript", policy);
+ }
}
bool ResourceFetcher::ContainsAsPreload(Resource* resource) const {
@@ -821,10 +795,9 @@ base::Optional<ResourceRequestBlockedReason> ResourceFetcher::PrepareRequest(
params.OverrideContentType(factory.ContentType());
// Don't send security violation reports for speculative preloads.
- SecurityViolationReportingPolicy reporting_policy =
- params.IsSpeculativePreload()
- ? SecurityViolationReportingPolicy::kSuppressReporting
- : SecurityViolationReportingPolicy::kReport;
+ ReportingDisposition reporting_disposition =
+ params.IsSpeculativePreload() ? ReportingDisposition::kSuppressReporting
+ : ReportingDisposition::kReport;
// Note that resource_request.GetRedirectStatus() may return kFollowedRedirect
// here since e.g. ThreadableLoader may create a new Resource from
@@ -837,7 +810,7 @@ base::Optional<ResourceRequestBlockedReason> ResourceFetcher::PrepareRequest(
Context().CheckCSPForRequest(
resource_request.GetRequestContext(),
MemoryCache::RemoveFragmentIdentifierIfNeeded(params.Url()), options,
- reporting_policy, resource_request.GetRedirectStatus());
+ reporting_disposition, resource_request.GetRedirectStatus());
// This may modify params.Url() (via the resource_request argument).
Context().PopulateResourceRequest(
@@ -868,6 +841,8 @@ base::Optional<ResourceRequestBlockedReason> ResourceFetcher::PrepareRequest(
mojom::RequestContextType::UNSPECIFIED) {
resource_request.SetRequestContext(
DetermineRequestContext(resource_type, kImageNotImageSet));
+ resource_request.SetRequestDestination(
+ DetermineRequestDestination(resource_type));
}
if (resource_type == ResourceType::kLinkPrefetch)
resource_request.SetPurposeHeader("prefetch");
@@ -885,9 +860,6 @@ base::Optional<ResourceRequestBlockedReason> ResourceFetcher::PrepareRequest(
resource_request.SetExternalRequestStateFromRequestorAddressSpace(
properties_->GetFetchClientSettingsObject().GetAddressSpace());
- SetSecFetchHeaders(resource_request,
- properties_->GetFetchClientSettingsObject());
-
Context().AddAdditionalRequestHeaders(resource_request);
TRACE_EVENT_NESTABLE_ASYNC_INSTANT1(
@@ -898,7 +870,7 @@ base::Optional<ResourceRequestBlockedReason> ResourceFetcher::PrepareRequest(
KURL url = MemoryCache::RemoveFragmentIdentifierIfNeeded(params.Url());
base::Optional<ResourceRequestBlockedReason> blocked_reason =
Context().CanRequest(resource_type, resource_request, url, options,
- reporting_policy,
+ reporting_disposition,
resource_request.GetRedirectStatus());
if (Context().CalculateIfAdSubresource(resource_request, resource_type))
@@ -952,10 +924,6 @@ Resource* ResourceFetcher::RequestResource(FetchParameters& params,
if (should_log_request_as_invalid_in_imported_document_) {
DCHECK(properties_->IsDetached());
- // We don't expect the fetcher to be used, so count such unexpected use.
- UMA_HISTOGRAM_ENUMERATION("HTMLImport.UnexpectedRequest",
- factory.GetType());
-
base::debug::DumpWithoutCrashing();
}
@@ -1012,7 +980,7 @@ Resource* ResourceFetcher::RequestResource(FetchParameters& params,
}
Resource* resource = nullptr;
- RevalidationPolicy policy = kLoad;
+ RevalidationPolicy policy = RevalidationPolicy::kLoad;
bool is_data_url = resource_request.Url().ProtocolIsData();
bool is_static_data = is_data_url || archive_;
@@ -1035,7 +1003,7 @@ Resource* ResourceFetcher::RequestResource(FetchParameters& params,
if (!is_stale_revalidation && !resource) {
resource = MatchPreload(params, resource_type);
if (resource) {
- policy = kUse;
+ policy = RevalidationPolicy::kUse;
// If |params| is for a blocking resource and a preloaded resource is
// found, we may need to make it block the onload event.
MakePreloadedResourceBlockOnloadIfNeeded(resource, params);
@@ -1052,16 +1020,16 @@ Resource* ResourceFetcher::RequestResource(FetchParameters& params,
UpdateMemoryCacheStats(resource, policy, params, factory, is_static_data);
switch (policy) {
- case kReload:
+ case RevalidationPolicy::kReload:
GetMemoryCache()->Remove(resource);
FALLTHROUGH;
- case kLoad:
+ case RevalidationPolicy::kLoad:
resource = CreateResourceForLoading(params, factory);
break;
- case kRevalidate:
+ case RevalidationPolicy::kRevalidate:
InitializeRevalidation(resource_request, resource);
break;
- case kUse:
+ case RevalidationPolicy::kUse:
if (resource_request.AllowsStaleResponse() &&
resource->ShouldRevalidateStaleResponse()) {
ScheduleStaleRevalidate(resource);
@@ -1072,7 +1040,7 @@ Resource* ResourceFetcher::RequestResource(FetchParameters& params,
DCHECK(resource);
DCHECK_EQ(resource->GetType(), resource_type);
- if (policy != kUse)
+ if (policy != RevalidationPolicy::kUse)
resource->VirtualTimePauser() = std::move(pauser);
if (client)
@@ -1080,7 +1048,7 @@ Resource* ResourceFetcher::RequestResource(FetchParameters& params,
// TODO(yoav): It is not clear why preloads are exempt from this check. Can we
// remove the exemption?
- if (!params.IsSpeculativePreload() || policy != kUse) {
+ if (!params.IsSpeculativePreload() || policy != RevalidationPolicy::kUse) {
// When issuing another request for a resource that is already in-flight
// make sure to not demote the priority of the in-flight request. If the new
// request isn't at the same priority as the in-flight request, only allow
@@ -1095,7 +1063,8 @@ Resource* ResourceFetcher::RequestResource(FetchParameters& params,
// If only the fragment identifiers differ, it is the same resource.
DCHECK(EqualIgnoringFragmentIdentifier(resource->Url(), params.Url()));
- if (policy == kUse && resource->GetStatus() == ResourceStatus::kCached &&
+ if (policy == RevalidationPolicy::kUse &&
+ resource->GetStatus() == ResourceStatus::kCached &&
!cached_resources_map_.Contains(
MemoryCache::RemoveFragmentIdentifierIfNeeded(params.Url()))) {
// Loaded from MemoryCache.
@@ -1124,13 +1093,14 @@ Resource* ResourceFetcher::RequestResource(FetchParameters& params,
// the resource was already initialized for the revalidation here, but won't
// start loading.
if (ResourceNeedsLoad(resource, params, policy)) {
- if (!StartLoad(resource)) {
+ if (!StartLoad(resource,
+ std::move(params.MutableResourceRequest().MutableBody()))) {
resource->FinishAsError(ResourceError::CancelledError(params.Url()),
task_runner_.get());
}
}
- if (policy != kUse)
+ if (policy != RevalidationPolicy::kUse)
InsertAsPreloadIfNecessary(resource, params, resource_type);
if (resource->InspectorId() != identifier ||
@@ -1240,7 +1210,8 @@ void ResourceFetcher::StorePerformanceTimingInitiatorInformation(
scoped_refptr<ResourceTimingInfo> info = ResourceTimingInfo::Create(
fetch_initiator, base::TimeTicks::Now(),
- resource->GetResourceRequest().GetRequestContext());
+ resource->GetResourceRequest().GetRequestContext(),
+ resource->GetResourceRequest().GetRequestDestination());
resource_timing_info_map_.insert(resource, std::move(info));
}
@@ -1430,13 +1401,13 @@ ResourceFetcher::DetermineRevalidationPolicy(
const char* ResourceFetcher::GetNameFor(RevalidationPolicy policy) {
switch (policy) {
- case kUse:
+ case RevalidationPolicy::kUse:
return "use";
- case kRevalidate:
+ case RevalidationPolicy::kRevalidate:
return "revalidate";
- case kReload:
+ case RevalidationPolicy::kReload:
return "reload";
- case kLoad:
+ case RevalidationPolicy::kLoad:
return "load";
}
NOTREACHED();
@@ -1451,11 +1422,13 @@ ResourceFetcher::DetermineRevalidationPolicyInternal(
const ResourceRequest& request = fetch_params.GetResourceRequest();
if (IsDownloadOrStreamRequest(request)) {
- return std::make_pair(kReload, "It is for download or for streaming.");
+ return {RevalidationPolicy::kReload,
+ "It is for download or for streaming."};
}
if (IsImageResourceDisallowedToBeReused(existing_resource)) {
- return std::make_pair(kReload, "Reload due to 'allow image' settings.");
+ return {RevalidationPolicy::kReload,
+ "Reload due to 'allow image' settings."};
}
// If the existing resource is loading and the associated fetcher is not equal
@@ -1463,8 +1436,8 @@ ResourceFetcher::DetermineRevalidationPolicyInternal(
// happen in redirect handling.
if (existing_resource.Loader() &&
existing_resource.Loader()->Fetcher() != this) {
- return std::make_pair(
- kReload, "The existing resource is loading in a foreign fetcher.");
+ return {RevalidationPolicy::kReload,
+ "The existing resource is loading in a foreign fetcher."};
}
// It's hard to share a not-yet-referenced preloads via MemoryCache correctly.
@@ -1472,9 +1445,9 @@ ResourceFetcher::DetermineRevalidationPolicyInternal(
// the memory cache could be used without this block.
if ((fetch_params.IsLinkPreload() || fetch_params.IsSpeculativePreload()) &&
existing_resource.IsUnusedPreload()) {
- return std::make_pair(kReload,
- "The existing resource is an unused preload made "
- "from a foreign fetcher.");
+ return {RevalidationPolicy::kReload,
+ "The existing resource is an unused preload made "
+ "from a foreign fetcher."};
}
// Checks if the resource has an explicit policy about integrity metadata.
@@ -1493,7 +1466,7 @@ ResourceFetcher::DetermineRevalidationPolicyInternal(
// uncommon case, however, as it implies two same-origin requests to the same
// resource, but with different integrity metadata.
if (existing_resource.MustRefetchDueToIntegrityMetadata(fetch_params)) {
- return std::make_pair(kReload, "Reload due to resource integrity.");
+ return {RevalidationPolicy::kReload, "Reload due to resource integrity."};
}
// If the same URL has been loaded as a different type, we need to reload.
@@ -1502,35 +1475,36 @@ ResourceFetcher::DetermineRevalidationPolicyInternal(
// We really should discard the new prefetch since the preload has more
// specific type information! crbug.com/379893
// fast/dom/HTMLLinkElement/link-and-subresource-test hits this case.
- return std::make_pair(kReload, "Reload due to type mismatch.");
+ return {RevalidationPolicy::kReload, "Reload due to type mismatch."};
}
// If resource was populated from archive or data: url, use it.
// This doesn't necessarily mean that |resource| was just created by using
// ResourceForStaticData().
if (is_static_data) {
- return std::make_pair(kUse, "Use the existing static resource.");
+ return {RevalidationPolicy::kUse, "Use the existing static resource."};
}
if (existing_resource.CanReuse(fetch_params) != Resource::MatchStatus::kOk) {
- return std::make_pair(kReload, "Reload due to Resource::CanReuse.");
+ return {RevalidationPolicy::kReload, "Reload due to Resource::CanReuse."};
}
// Don't reload resources while pasting.
if (allow_stale_resources_) {
- return std::make_pair(
- kUse, "Use the existing resource due to |allow_stale_resources_|.");
+ return {RevalidationPolicy::kUse,
+ "Use the existing resource due to |allow_stale_resources_|."};
}
// FORCE_CACHE uses the cache no matter what.
if (request.GetCacheMode() == mojom::FetchCacheMode::kForceCache) {
- return std::make_pair(
- kUse, "Use the existing resource due to cache-mode: 'force-cache'.");
+ return {RevalidationPolicy::kUse,
+ "Use the existing resource due to cache-mode: 'force-cache'."};
}
// Don't reuse resources with Cache-control: no-store.
if (existing_resource.HasCacheControlNoStoreHeader()) {
- return std::make_pair(kReload, "Reload due to cache-control: no-sotre.");
+ return {RevalidationPolicy::kReload,
+ "Reload due to cache-control: no-sotre."};
}
// During the initial load, avoid loading the same resource multiple times for
@@ -1543,25 +1517,25 @@ ResourceFetcher::DetermineRevalidationPolicyInternal(
cached_resources_map_.Contains(
MemoryCache::RemoveFragmentIdentifierIfNeeded(
existing_resource.Url()))) {
- return std::make_pair(kUse,
- "Avoid making multiple requests for the same URL "
- "during the initial load.");
+ return {RevalidationPolicy::kUse,
+ "Avoid making multiple requests for the same URL "
+ "during the initial load."};
}
if (existing_resource.IsLoading()) {
- return std::make_pair(
- kUse, "Use the existing resource because it's being loaded.");
+ return {RevalidationPolicy::kUse,
+ "Use the existing resource because it's being loaded."};
}
}
// RELOAD always reloads
if (request.GetCacheMode() == mojom::FetchCacheMode::kBypassCache) {
- return std::make_pair(kReload, "Reload due to cache-mode: 'reload'.");
+ return {RevalidationPolicy::kReload, "Reload due to cache-mode: 'reload'."};
}
// We'll try to reload the resource if it failed last time.
if (existing_resource.ErrorOccurred()) {
- return std::make_pair(
- kReload, "Reload because the existing resource has failed loading.");
+ return {RevalidationPolicy::kReload,
+ "Reload because the existing resource has failed loading."};
}
// List of available images logic allows images to be re-used without cache
@@ -1569,18 +1543,19 @@ ResourceFetcher::DetermineRevalidationPolicyInternal(
// same as the version in the current document.
if (type == ResourceType::kImage &&
&existing_resource == CachedResource(request.Url())) {
- return std::make_pair(kUse,
- "Images can be reused without cache validation.");
+ return {RevalidationPolicy::kUse,
+ "Images can be reused without cache validation."};
}
if (existing_resource.MustReloadDueToVaryHeader(request)) {
- return std::make_pair(kReload, "Reload due to vary header.");
+ return {RevalidationPolicy::kReload, "Reload due to vary header."};
}
// If any of the redirects in the chain to loading the resource were not
// cacheable, we cannot reuse our cached resource.
if (!existing_resource.CanReuseRedirectChain()) {
- return std::make_pair(kReload, "Reload due to an uncacheable redirect.");
+ return {RevalidationPolicy::kReload,
+ "Reload due to an uncacheable redirect."};
}
// Check if the cache headers requires us to revalidate (cache expiration for
@@ -1592,8 +1567,8 @@ ResourceFetcher::DetermineRevalidationPolicyInternal(
// Revalidation is harmful for non-matched preloads because it may lead to
// sharing one preloaded resource among multiple ResourceFetchers.
if (existing_resource.IsUnusedPreload()) {
- return std::make_pair(
- kReload, "Revalidation is harmful for non-matched preloads.");
+ return {RevalidationPolicy::kReload,
+ "Revalidation is harmful for non-matched preloads."};
}
// See if the resource has usable ETag or Last-modified headers. If the page
@@ -1612,20 +1587,19 @@ ResourceFetcher::DetermineRevalidationPolicyInternal(
// |Use| policy should be applied to subsequent requests.
if (existing_resource.IsCacheValidator()) {
DCHECK(existing_resource.StillNeedsLoad());
- return std::make_pair(
- kUse,
- "Merged to the revalidate request which has not yet started.");
+ return {RevalidationPolicy::kUse,
+ "Merged to the revalidate request which has not yet started."};
}
- return std::make_pair(kRevalidate, "");
+ return {RevalidationPolicy::kRevalidate, ""};
}
// No, must reload.
- return std::make_pair(kReload, "Reload due to missing cache validators.");
+ return {RevalidationPolicy::kReload,
+ "Reload due to missing cache validators."};
}
- return std::make_pair(
- kUse,
- "Use the existing resource because there is no reason not to do so.");
+ return {RevalidationPolicy::kUse,
+ "Use the existing resource because there is no reason not to do so."};
}
void ResourceFetcher::SetAutoLoadImages(bool enable) {
@@ -1877,6 +1851,11 @@ void ResourceFetcher::MoveResourceLoaderToNonBlocking(ResourceLoader* loader) {
}
bool ResourceFetcher::StartLoad(Resource* resource) {
+ return StartLoad(resource, ResourceRequestBody());
+}
+
+bool ResourceFetcher::StartLoad(Resource* resource,
+ ResourceRequestBody request_body) {
DCHECK(resource);
DCHECK(resource->StillNeedsLoad());
@@ -1894,11 +1873,13 @@ bool ResourceFetcher::StartLoad(Resource* resource) {
return false;
}
- const auto& request = resource->GetResourceRequest();
- ResourceResponse response;
+ const ResourceRequestHead& request_head = resource->GetResourceRequest();
if (resource_load_observer_) {
DCHECK(!IsDetached());
+ ResourceRequest request(request_head);
+ request.SetHttpBody(request_body.FormBody());
+ ResourceResponse response;
resource_load_observer_->WillSendRequest(
resource->InspectorId(), request, response, resource->GetType(),
resource->Options().initiator_info);
@@ -1906,8 +1887,8 @@ bool ResourceFetcher::StartLoad(Resource* resource) {
using QuotaType = decltype(inflight_keepalive_bytes_);
QuotaType size = 0;
- if (request.GetKeepalive() && request.HttpBody()) {
- auto original_size = request.HttpBody()->SizeInBytes();
+ if (request_head.GetKeepalive() && request_body.FormBody()) {
+ auto original_size = request_body.FormBody()->SizeInBytes();
DCHECK_LE(inflight_keepalive_bytes_, kKeepaliveInflightBytesQuota);
if (original_size > std::numeric_limits<QuotaType>::max())
return false;
@@ -1918,8 +1899,8 @@ bool ResourceFetcher::StartLoad(Resource* resource) {
inflight_keepalive_bytes_ += size;
}
- loader =
- MakeGarbageCollected<ResourceLoader>(this, scheduler_, resource, size);
+ loader = MakeGarbageCollected<ResourceLoader>(
+ this, scheduler_, resource, std::move(request_body), size);
// Preload requests should not block the load event. IsLinkPreload()
// actually continues to return true for Resources matched from the preload
// cache that must block the load event, but that is OK because this method
@@ -2037,12 +2018,14 @@ void ResourceFetcher::EmulateLoadStartedForInspector(
Resource* resource,
const KURL& url,
mojom::RequestContextType request_context,
+ network::mojom::RequestDestination request_destination,
const AtomicString& initiator_name) {
base::AutoReset<bool> r(&is_in_request_resource_, true);
if (CachedResource(url))
return;
ResourceRequest resource_request(url);
resource_request.SetRequestContext(request_context);
+ resource_request.SetRequestDestination(request_destination);
if (!resource_request.PriorityHasBeenSet()) {
resource_request.SetPriority(ComputeLoadPriority(
resource->GetType(), resource_request, ResourcePriority::kNotVisible,
@@ -2050,14 +2033,17 @@ void ResourceFetcher::EmulateLoadStartedForInspector(
FetchParameters::SpeculativePreloadType::kNotSpeculative,
false /* is_link_preload */));
}
+ resource_request.SetReferrerString(Referrer::NoReferrer());
+ resource_request.SetReferrerPolicy(network::mojom::ReferrerPolicy::kNever);
ResourceLoaderOptions options = resource->Options();
options.initiator_info.name = initiator_name;
- FetchParameters params(resource_request, options);
- Context().CanRequest(resource->GetType(), resource->LastResourceRequest(),
- resource->LastResourceRequest().Url(), params.Options(),
- SecurityViolationReportingPolicy::kReport,
- resource->LastResourceRequest().GetRedirectStatus());
+ FetchParameters params(std::move(resource_request), options);
+ ResourceRequest last_resource_request(resource->LastResourceRequest());
+ Context().CanRequest(resource->GetType(), last_resource_request,
+ last_resource_request.Url(), params.Options(),
+ ReportingDisposition::kReport,
+ last_resource_request.GetRedirectStatus());
DidLoadResourceFromMemoryCache(resource->InspectorId(), resource,
params.GetResourceRequest(),
false /* is_static_data */);
@@ -2113,7 +2099,9 @@ void ResourceFetcher::RevalidateStaleResource(Resource* stale_resource) {
// purpose this is probably fine.
// TODO(dtapuska): revisit this when we have a better way to re-dispatch
// requests.
- FetchParameters params(stale_resource->GetResourceRequest());
+ ResourceRequest request;
+ request.CopyHeadFrom(stale_resource->GetResourceRequest());
+ FetchParameters params(std::move(request));
params.SetStaleRevalidation(true);
params.MutableResourceRequest().SetSkipServiceWorker(true);
// Stale revalidation resource requests should be very low regardless of
@@ -2126,7 +2114,7 @@ void ResourceFetcher::RevalidateStaleResource(Resource* stale_resource) {
mojom::blink::BlobRegistry* ResourceFetcher::GetBlobRegistry() {
if (!blob_registry_remote_) {
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
blob_registry_remote_.BindNewPipeAndPassReceiver(task_runner_));
}
return blob_registry_remote_.get();
@@ -2136,7 +2124,7 @@ FrameScheduler* ResourceFetcher::GetFrameScheduler() {
return frame_scheduler_.get();
}
-void ResourceFetcher::Trace(blink::Visitor* visitor) {
+void ResourceFetcher::Trace(Visitor* visitor) {
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 9c3ad282fc6..75ac2446bee 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
@@ -102,7 +102,7 @@ class PLATFORM_EXPORT ResourceFetcher
// in ResourceFetcherInit to ensure correctness of this ResourceFetcher.
explicit ResourceFetcher(const ResourceFetcherInit&);
virtual ~ResourceFetcher();
- virtual void Trace(blink::Visitor*);
+ virtual void Trace(Visitor*);
// - This function returns the same object throughout this fetcher's
// entire life.
@@ -168,6 +168,7 @@ class PLATFORM_EXPORT ResourceFetcher
// call this method explicitly on cases such as ResourceNeedsLoad() returning
// false.
bool StartLoad(Resource*);
+ bool StartLoad(Resource*, ResourceRequestBody);
void SetAutoLoadImages(bool);
void SetImagesEnabled(bool);
@@ -223,6 +224,9 @@ class PLATFORM_EXPORT ResourceFetcher
ResourceType,
IsImageSet);
+ static network::mojom::RequestDestination DetermineRequestDestination(
+ ResourceType);
+
void UpdateAllImageResourcePriorities();
// Returns whether the given resource is contained as a preloaded resource.
@@ -237,6 +241,7 @@ class PLATFORM_EXPORT ResourceFetcher
void EmulateLoadStartedForInspector(Resource*,
const KURL&,
mojom::RequestContextType,
+ network::mojom::RequestDestination,
const AtomicString& initiator_name);
// This is called from leak detectors (Real-world leak detector & web test
@@ -253,7 +258,7 @@ class PLATFORM_EXPORT ResourceFetcher
ResourceLoadPriority ComputeLoadPriorityForTesting(
ResourceType type,
- const ResourceRequest& request,
+ const ResourceRequestHead& request,
ResourcePriority::VisibilityStatus visibility_statue,
FetchParameters::DeferOption defer_option,
FetchParameters::SpeculativePreloadType speculative_preload_type,
@@ -284,7 +289,7 @@ class PLATFORM_EXPORT ResourceFetcher
void StorePerformanceTimingInitiatorInformation(Resource*);
ResourceLoadPriority ComputeLoadPriority(
ResourceType,
- const ResourceRequest&,
+ const ResourceRequestHead&,
ResourcePriority::VisibilityStatus,
FetchParameters::DeferOption = FetchParameters::kNoDefer,
FetchParameters::SpeculativePreloadType =
@@ -319,7 +324,13 @@ class PLATFORM_EXPORT ResourceFetcher
void StopFetchingIncludingKeepaliveLoaders();
// RevalidationPolicy enum values are used in UMAs https://crbug.com/579496.
- enum RevalidationPolicy { kUse, kRevalidate, kReload, kLoad };
+ enum class RevalidationPolicy {
+ kUse,
+ kRevalidate,
+ kReload,
+ kLoad,
+ kMaxValue = kLoad
+ };
// A wrapper just for placing a trace_event macro.
RevalidationPolicy DetermineRevalidationPolicy(
@@ -445,7 +456,7 @@ class ResourceCacheValidationSuppressor {
}
private:
- Member<ResourceFetcher> loader_;
+ ResourceFetcher* loader_;
bool previous_state_;
DISALLOW_COPY_AND_ASSIGN(ResourceCacheValidationSuppressor);
@@ -465,15 +476,15 @@ struct PLATFORM_EXPORT ResourceFetcherInit final {
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
ResourceFetcher::LoaderFactory* loader_factory);
- const Member<DetachableResourceFetcherProperties> properties;
- const Member<FetchContext> context;
+ DetachableResourceFetcherProperties* const properties;
+ FetchContext* const context;
const scoped_refptr<base::SingleThreadTaskRunner> task_runner;
- const Member<ResourceFetcher::LoaderFactory> loader_factory;
- Member<DetachableUseCounter> use_counter;
- Member<DetachableConsoleLogger> console_logger;
+ ResourceFetcher::LoaderFactory* const loader_factory;
+ DetachableUseCounter* use_counter = nullptr;
+ DetachableConsoleLogger* console_logger = nullptr;
ResourceLoadScheduler::ThrottlingPolicy initial_throttling_policy =
ResourceLoadScheduler::ThrottlingPolicy::kNormal;
- Member<MHTMLArchive> archive;
+ MHTMLArchive* archive = nullptr;
FrameScheduler* frame_scheduler = nullptr;
DISALLOW_COPY_AND_ASSIGN(ResourceFetcherInit);
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties_test.cc
index 3b14d081582..8890de7be67 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties_test.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties_test.cc
@@ -6,6 +6,7 @@
#include "services/network/public/mojom/ip_address_space.mojom-blink.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
#include "third_party/blink/public/mojom/service_worker/controller_service_worker_mode.mojom-blink.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h"
@@ -26,7 +27,7 @@ class DetachableResourceFetcherPropertiesTest : public testing::Test {
network::mojom::ReferrerPolicy::kDefault,
"https://example.com/foo.html", HttpsState::kModern,
AllowedByNosniff::MimeTypeCheck::kStrict, address_space,
- kLeaveInsecureRequestsAlone,
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone,
FetchClientSettingsObject::InsecureNavigationsSet());
}
};
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 bb529c83964..980d15a3fd0 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
@@ -37,6 +37,7 @@
#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/mojom/loader/request_context_frame_type.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/public/platform/web_url_loader.h"
#include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
@@ -103,10 +104,26 @@ const FetchClientSettingsObjectSnapshot& CreateFetchClientSettingsObject(
SecurityOrigin::Create(KURL("https://example.com/")),
network::mojom::ReferrerPolicy::kDefault, "https://example.com/foo.html",
HttpsState::kModern, AllowedByNosniff::MimeTypeCheck::kStrict,
- address_space, kLeaveInsecureRequestsAlone,
+ address_space,
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone,
FetchClientSettingsObject::InsecureNavigationsSet());
}
+class PartialResourceRequest {
+ public:
+ PartialResourceRequest() : PartialResourceRequest(ResourceRequest()) {}
+ PartialResourceRequest(const ResourceRequest& request)
+ : is_ad_resource_(request.IsAdResource()),
+ priority_(request.Priority()) {}
+
+ bool IsAdResource() const { return is_ad_resource_; }
+ ResourceLoadPriority Priority() const { return priority_; }
+
+ private:
+ bool is_ad_resource_;
+ ResourceLoadPriority priority_;
+};
+
} // namespace
class ResourceFetcherTest : public testing::Test {
@@ -123,7 +140,7 @@ class ResourceFetcherTest : public testing::Test {
const ResourceResponse& redirect_response,
ResourceType,
const FetchInitiatorInfo&) override {
- request_ = request;
+ request_ = PartialResourceRequest(request);
}
void DidChangePriority(uint64_t identifier,
ResourceLoadPriority,
@@ -149,12 +166,12 @@ class ResourceFetcherTest : public testing::Test {
int64_t encoded_data_length,
IsInternalRequest is_internal_request) override {}
- const base::Optional<ResourceRequest>& GetLastRequest() const {
+ const base::Optional<PartialResourceRequest>& GetLastRequest() const {
return request_;
}
private:
- base::Optional<ResourceRequest> request_;
+ base::Optional<PartialResourceRequest> request_;
};
protected:
@@ -194,7 +211,7 @@ TEST_F(ResourceFetcherTest, StartLoadAfterFrameDetach) {
fetcher->ClearContext();
ResourceRequest resource_request(secure_url);
resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
- FetchParameters fetch_params(resource_request);
+ FetchParameters fetch_params(std::move(resource_request));
Resource* resource = RawResource::Fetch(fetch_params, fetcher, nullptr);
ASSERT_TRUE(resource);
EXPECT_TRUE(resource->ErrorOccurred());
@@ -256,12 +273,13 @@ TEST_F(ResourceFetcherTest, WillSendRequestAdBit) {
ResourceRequest resource_request(url);
resource_request.SetIsAdResource();
resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
- FetchParameters fetch_params(resource_request);
+ FetchParameters fetch_params(std::move(resource_request));
platform_->GetURLLoaderMockFactory()->RegisterURL(url, WebURLResponse(), "");
Resource* new_resource = RawResource::Fetch(fetch_params, fetcher, nullptr);
EXPECT_EQ(resource, new_resource);
- base::Optional<ResourceRequest> new_request = observer->GetLastRequest();
+ base::Optional<PartialResourceRequest> new_request =
+ observer->GetLastRequest();
EXPECT_TRUE(new_request.has_value());
EXPECT_TRUE(new_request.value().IsAdResource());
}
@@ -286,7 +304,7 @@ TEST_F(ResourceFetcherTest, Vary) {
*MakeGarbageCollected<TestResourceFetcherProperties>(source_origin));
ResourceRequest resource_request(url);
resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
- FetchParameters fetch_params(resource_request);
+ FetchParameters fetch_params(std::move(resource_request));
platform_->GetURLLoaderMockFactory()->RegisterURL(url, WebURLResponse(), "");
Resource* new_resource = RawResource::Fetch(fetch_params, fetcher, nullptr);
EXPECT_NE(resource, new_resource);
@@ -296,7 +314,8 @@ TEST_F(ResourceFetcherTest, Vary) {
TEST_F(ResourceFetcherTest, ResourceTimingInfo) {
auto info = ResourceTimingInfo::Create(
fetch_initiator_type_names::kDocument, base::TimeTicks::Now(),
- mojom::RequestContextType::UNSPECIFIED);
+ mojom::RequestContextType::UNSPECIFIED,
+ network::mojom::RequestDestination::kEmpty);
info->AddFinalTransferSize(5);
EXPECT_EQ(info->TransferSize(), static_cast<uint64_t>(5));
ResourceResponse redirect_response(KURL("https://example.com/original"));
@@ -328,7 +347,7 @@ TEST_F(ResourceFetcherTest, VaryOnBack) {
ResourceRequest resource_request(url);
resource_request.SetCacheMode(mojom::FetchCacheMode::kForceCache);
resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
- FetchParameters fetch_params(resource_request);
+ FetchParameters fetch_params(std::move(resource_request));
Resource* new_resource = RawResource::Fetch(fetch_params, fetcher, nullptr);
EXPECT_EQ(resource, new_resource);
}
@@ -383,7 +402,7 @@ class RequestSameResourceOnComplete
MakeGarbageCollected<TestLoaderFactory>()));
ResourceRequest resource_request2(GetResource()->Url());
resource_request2.SetCacheMode(mojom::FetchCacheMode::kValidateCache);
- FetchParameters fetch_params2(resource_request2);
+ FetchParameters fetch_params2(std::move(resource_request2));
Resource* resource2 = MockResource::Fetch(fetch_params2, fetcher2, nullptr);
EXPECT_EQ(GetResource(), resource2);
notify_finished_called_ = true;
@@ -391,9 +410,7 @@ class RequestSameResourceOnComplete
}
bool NotifyFinishedCalled() const { return notify_finished_called_; }
- void Trace(blink::Visitor* visitor) override {
- RawResourceClient::Trace(visitor);
- }
+ void Trace(Visitor* visitor) override { RawResourceClient::Trace(visitor); }
String DebugName() const override { return "RequestSameResourceOnComplete"; }
@@ -419,7 +436,7 @@ TEST_F(ResourceFetcherTest, RevalidateWhileFinishingLoading) {
*MakeGarbageCollected<TestResourceFetcherProperties>(source_origin));
ResourceRequest request1(url);
request1.SetHttpHeaderField(http_names::kCacheControl, "no-cache");
- FetchParameters fetch_params1(request1);
+ FetchParameters fetch_params1(std::move(request1));
Persistent<RequestSameResourceOnComplete> client =
MakeGarbageCollected<RequestSameResourceOnComplete>(fetch_params1,
fetcher1);
@@ -440,7 +457,7 @@ TEST_F(ResourceFetcherTest, MAYBE_DontReuseMediaDataUrl) {
ResourceLoaderOptions options;
options.data_buffering_policy = kDoNotBufferData;
options.initiator_info.name = fetch_initiator_type_names::kInternal;
- FetchParameters fetch_params(request, options);
+ FetchParameters fetch_params(std::move(request), options);
Resource* resource1 = RawResource::FetchMedia(fetch_params, fetcher, nullptr);
Resource* resource2 = RawResource::FetchMedia(fetch_params, fetcher, nullptr);
EXPECT_NE(resource1, resource2);
@@ -477,9 +494,7 @@ class ServeRequestsOnCompleteClient final
}
void DataDownloaded(Resource*, uint64_t) override { ASSERT_TRUE(false); }
- void Trace(blink::Visitor* visitor) override {
- RawResourceClient::Trace(visitor);
- }
+ void Trace(Visitor* visitor) override { RawResourceClient::Trace(visitor); }
String DebugName() const override { return "ServeRequestsOnCompleteClient"; }
};
@@ -496,7 +511,7 @@ TEST_F(ResourceFetcherTest, ResponseOnCancel) {
auto* fetcher = CreateFetcher();
ResourceRequest resource_request(url);
resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
- FetchParameters fetch_params(resource_request);
+ FetchParameters fetch_params(std::move(resource_request));
Persistent<ServeRequestsOnCompleteClient> client =
MakeGarbageCollected<ServeRequestsOnCompleteClient>();
Resource* resource = RawResource::Fetch(fetch_params, fetcher, client);
@@ -536,13 +551,13 @@ class ScopedMockRedirectRequester {
MakeGarbageCollected<TestLoaderFactory>()));
ResourceRequest resource_request(url);
resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
- FetchParameters fetch_params(resource_request);
+ FetchParameters fetch_params(std::move(resource_request));
RawResource::Fetch(fetch_params, fetcher, nullptr);
url_test_helpers::ServeAsynchronousRequests();
}
private:
- Member<MockFetchContext> context_;
+ MockFetchContext* context_;
const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
DISALLOW_COPY_AND_ASSIGN(ScopedMockRedirectRequester);
@@ -596,7 +611,7 @@ TEST_F(ResourceFetcherTest, SynchronousRequest) {
auto* fetcher = CreateFetcher();
ResourceRequest resource_request(url);
resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
- FetchParameters fetch_params(resource_request);
+ FetchParameters fetch_params(std::move(resource_request));
fetch_params.MakeSynchronous();
Resource* resource = RawResource::Fetch(fetch_params, fetcher, nullptr);
EXPECT_TRUE(resource->IsLoaded());
@@ -611,7 +626,7 @@ TEST_F(ResourceFetcherTest, PingPriority) {
auto* fetcher = CreateFetcher();
ResourceRequest resource_request(url);
resource_request.SetRequestContext(mojom::RequestContextType::PING);
- FetchParameters fetch_params(resource_request);
+ FetchParameters fetch_params(std::move(resource_request));
Resource* resource = RawResource::Fetch(fetch_params, fetcher, nullptr);
EXPECT_EQ(ResourceLoadPriority::kVeryLow,
resource->GetResourceRequest().Priority());
@@ -849,7 +864,7 @@ TEST_F(ResourceFetcherTest, Revalidate304) {
*MakeGarbageCollected<TestResourceFetcherProperties>(source_origin));
ResourceRequest resource_request(url);
resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
- FetchParameters fetch_params(resource_request);
+ FetchParameters fetch_params(std::move(resource_request));
platform_->GetURLLoaderMockFactory()->RegisterURL(url, WebURLResponse(), "");
Resource* new_resource = RawResource::Fetch(fetch_params, fetcher, nullptr);
fetcher->StopFetching();
@@ -918,7 +933,7 @@ TEST_F(ResourceFetcherTest, ContentIdURL) {
{
ResourceRequest resource_request(url);
resource_request.SetRequestContext(mojom::RequestContextType::VIDEO);
- FetchParameters fetch_params(resource_request);
+ FetchParameters fetch_params(std::move(resource_request));
RawResource* resource =
RawResource::FetchMedia(fetch_params, fetcher, nullptr);
ASSERT_NE(nullptr, resource);
@@ -956,7 +971,7 @@ TEST_F(ResourceFetcherTest, StaleWhileRevalidate) {
ResourceRequest resource_request(url);
resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL);
- FetchParameters fetch_params2 = FetchParameters(resource_request);
+ FetchParameters fetch_params2 = FetchParameters(std::move(resource_request));
Resource* new_resource = MockResource::Fetch(fetch_params2, fetcher, nullptr);
EXPECT_EQ(resource, new_resource);
platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
@@ -976,7 +991,8 @@ TEST_F(ResourceFetcherTest, StaleWhileRevalidate) {
EXPECT_TRUE(GetMemoryCache()->Contains(resource));
static_cast<scheduler::FakeTaskRunner*>(fetcher->GetTaskRunner().get())
->RunUntilIdle();
- base::Optional<ResourceRequest> swr_request = observer->GetLastRequest();
+ base::Optional<PartialResourceRequest> swr_request =
+ observer->GetLastRequest();
ASSERT_TRUE(swr_request.has_value());
EXPECT_EQ(ResourceLoadPriority::kVeryLow, swr_request->Priority());
platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
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 72cfbda8334..376800c68cd 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
@@ -14,12 +14,13 @@ namespace blink {
// ResourceFinishObserver is different from ResourceClient in several ways.
// - NotifyFinished is dispatched asynchronously.
// - ResourceFinishObservers will be removed from Resource when the load
-// finishes. - This class is not intended to be "subclassed" per each Resource
-// subclass.
+// finishes.
+// - This class is not intended to be "subclassed" per each Resource subclass.
// There is no ImageResourceFinishObserver, for example.
// ResourceFinishObserver should be quite simple. All notifications must be
// notified AFTER the loading finishes.
-class PLATFORM_EXPORT ResourceFinishObserver : public GarbageCollectedMixin {
+class PLATFORM_EXPORT ResourceFinishObserver
+ : public GarbageCollected<ResourceFinishObserver> {
public:
virtual ~ResourceFinishObserver() = default;
@@ -30,7 +31,7 @@ class PLATFORM_EXPORT ResourceFinishObserver : public GarbageCollectedMixin {
// Name for debugging
virtual String DebugName() const = 0;
- void Trace(blink::Visitor* visitor) override {}
+ virtual void Trace(Visitor* visitor) {}
};
} // 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 6496f9fe7e8..c79595b9005 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
@@ -235,7 +235,7 @@ ResourceLoadScheduler::ResourceLoadScheduler(
ResourceLoadScheduler::~ResourceLoadScheduler() = default;
-void ResourceLoadScheduler::Trace(blink::Visitor* visitor) {
+void ResourceLoadScheduler::Trace(Visitor* visitor) {
visitor->Trace(pending_request_map_);
visitor->Trace(resource_fetcher_properties_);
visitor->Trace(console_logger_);
@@ -275,7 +275,7 @@ void ResourceLoadScheduler::Request(ResourceLoadSchedulerClient* client,
// Check if the request can be throttled.
ClientIdWithPriority request_info(*id, priority, intra_priority);
- if (!IsClientDelayable(request_info, option)) {
+ if (!IsClientDelayable(option)) {
Run(*id, client, false);
return;
}
@@ -356,27 +356,15 @@ void ResourceLoadScheduler::SetOutstandingLimitForTesting(size_t tight_limit,
MaybeRun();
}
-bool ResourceLoadScheduler::IsClientDelayable(const ClientIdWithPriority& info,
- ThrottleOption option) const {
- const bool throttleable = option == ThrottleOption::kThrottleable &&
- info.priority < ResourceLoadPriority::kHigh;
- const bool stoppable = option != ThrottleOption::kCanNotBeStoppedOrThrottled;
-
- // Also takes the lifecycle state of the associated FrameScheduler
- // into account to determine if the request should be throttled
- // regardless of the priority.
+bool ResourceLoadScheduler::IsClientDelayable(ThrottleOption option) const {
switch (frame_scheduler_lifecycle_state_) {
case scheduler::SchedulingLifecycleState::kNotThrottled:
- return throttleable;
case scheduler::SchedulingLifecycleState::kHidden:
case scheduler::SchedulingLifecycleState::kThrottled:
return option == ThrottleOption::kThrottleable;
case scheduler::SchedulingLifecycleState::kStopped:
- return stoppable;
+ return option != ThrottleOption::kCanNotBeStoppedOrThrottled;
}
-
- NOTREACHED() << static_cast<int>(frame_scheduler_lifecycle_state_);
- return throttleable;
}
void ResourceLoadScheduler::OnLifecycleStateChanged(
@@ -419,9 +407,6 @@ bool ResourceLoadScheduler::IsPendingRequestEffectivelyEmpty(
}
bool ResourceLoadScheduler::GetNextPendingRequest(ClientId* id) {
- bool needs_throttling =
- running_throttleable_requests_.size() >= GetOutstandingLimit();
-
auto& stoppable_queue = pending_requests_[ThrottleOption::kStoppable];
auto& throttleable_queue = pending_requests_[ThrottleOption::kThrottleable];
@@ -429,14 +414,16 @@ bool ResourceLoadScheduler::GetNextPendingRequest(ClientId* id) {
auto stoppable_it = stoppable_queue.begin();
bool has_runnable_stoppable_request =
stoppable_it != stoppable_queue.end() &&
- (!IsClientDelayable(*stoppable_it, ThrottleOption::kStoppable) ||
- !needs_throttling);
+ (!IsClientDelayable(ThrottleOption::kStoppable) ||
+ running_throttleable_requests_.size() <
+ GetOutstandingLimit(stoppable_it->priority));
auto throttleable_it = throttleable_queue.begin();
bool has_runnable_throttleable_request =
throttleable_it != throttleable_queue.end() &&
- (!IsClientDelayable(*throttleable_it, ThrottleOption::kThrottleable) ||
- !needs_throttling);
+ (!IsClientDelayable(ThrottleOption::kThrottleable) ||
+ running_throttleable_requests_.size() <
+ GetOutstandingLimit(throttleable_it->priority));
if (!has_runnable_throttleable_request && !has_runnable_stoppable_request)
return false;
@@ -489,7 +476,8 @@ void ResourceLoadScheduler::Run(ResourceLoadScheduler::ClientId id,
client->Run();
}
-size_t ResourceLoadScheduler::GetOutstandingLimit() const {
+size_t ResourceLoadScheduler::GetOutstandingLimit(
+ ResourceLoadPriority priority) const {
size_t limit = kOutstandingUnlimited;
switch (frame_scheduler_lifecycle_state_) {
@@ -506,7 +494,9 @@ size_t ResourceLoadScheduler::GetOutstandingLimit() const {
switch (policy_) {
case ThrottlingPolicy::kTight:
- limit = std::min(limit, tight_outstanding_limit_);
+ limit = std::min(limit, priority < ResourceLoadPriority::kHigh
+ ? tight_outstanding_limit_
+ : normal_outstanding_limit_);
break;
case ThrottlingPolicy::kNormal:
limit = std::min(limit, normal_outstanding_limit_);
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 b951ecfd303..eb66476c349 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(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) override {}
};
// ResourceLoadScheduler provides a unified per-frame infrastructure to schedule
@@ -157,7 +157,7 @@ class PLATFORM_EXPORT ResourceLoadScheduler final
DetachableConsoleLogger& console_logger);
~ResourceLoadScheduler() override;
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
// Changes the policy from |kTight| to |kNormal|. This function can be called
// multiple times, and does nothing when the scheduler is already working with
@@ -245,7 +245,7 @@ class PLATFORM_EXPORT ResourceLoadScheduler final
priority(priority),
intra_priority(intra_priority) {}
- void Trace(blink::Visitor* visitor) { visitor->Trace(client); }
+ void Trace(Visitor* visitor) { visitor->Trace(client); }
Member<ResourceLoadSchedulerClient> client;
ThrottleOption option;
@@ -261,10 +261,9 @@ class PLATFORM_EXPORT ResourceLoadScheduler final
// Gets the highest priority pending request that is allowed to be run.
bool GetNextPendingRequest(ClientId* id);
- // Returns whether we can throttle a request with the given client info based
+ // Returns whether we can throttle a request with the given option based
// on life cycle state.
- bool IsClientDelayable(const ClientIdWithPriority& info,
- ThrottleOption option) const;
+ bool IsClientDelayable(ThrottleOption option) const;
// Generates the next ClientId.
ClientId GenerateClientId();
@@ -275,7 +274,7 @@ class PLATFORM_EXPORT ResourceLoadScheduler final
// Grants a client to run,
void Run(ClientId, ResourceLoadSchedulerClient*, bool throttleable);
- size_t GetOutstandingLimit() const;
+ size_t GetOutstandingLimit(ResourceLoadPriority priority) const;
void ShowConsoleMessageIfNeeded();
@@ -283,7 +282,6 @@ class PLATFORM_EXPORT ResourceLoadScheduler final
resource_fetcher_properties_;
// A flag to indicate an internal running state.
- // TODO(toyoshim): We may want to use enum once we start to have more states.
bool is_shutdown_ = false;
ThrottlingPolicy policy_ = ThrottlingPolicy::kNormal;
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 a5056c1becf..ffe0d245cfc 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(blink::Visitor* visitor) { visitor->Trace(client_order_); }
+ void Trace(Visitor* visitor) { 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
ResourceLoadSchedulerClient::Trace(visitor);
visitor->Trace(console_logger_);
}
@@ -349,7 +349,8 @@ TEST_F(ResourceLoadSchedulerTest, PriorityIsConsidered) {
// Push three requests.
MockClient* client1 = MakeGarbageCollected<MockClient>();
- Scheduler()->SetOutstandingLimitForTesting(0);
+ // Allows one kHigh priority request by limits below.
+ Scheduler()->SetOutstandingLimitForTesting(0, 1);
ResourceLoadScheduler::ClientId id1 = ResourceLoadScheduler::kInvalidClientId;
Scheduler()->Request(client1, ThrottleOption::kThrottleable,
@@ -383,23 +384,21 @@ TEST_F(ResourceLoadSchedulerTest, PriorityIsConsidered) {
EXPECT_FALSE(client3->WasRun());
EXPECT_TRUE(client4->WasRun());
- // Client 4 does not count against the limit as it was not delayable when it
- // was created.
- Scheduler()->SetOutstandingLimitForTesting(1);
+ Scheduler()->SetOutstandingLimitForTesting(2);
EXPECT_FALSE(client1->WasRun());
EXPECT_FALSE(client2->WasRun());
EXPECT_TRUE(client3->WasRun());
EXPECT_TRUE(client4->WasRun());
- Scheduler()->SetOutstandingLimitForTesting(2);
+ Scheduler()->SetOutstandingLimitForTesting(3);
EXPECT_FALSE(client1->WasRun());
EXPECT_TRUE(client2->WasRun());
EXPECT_TRUE(client3->WasRun());
EXPECT_TRUE(client4->WasRun());
- Scheduler()->SetOutstandingLimitForTesting(3);
+ Scheduler()->SetOutstandingLimitForTesting(4);
EXPECT_TRUE(client1->WasRun());
EXPECT_TRUE(client2->WasRun());
@@ -407,7 +406,6 @@ TEST_F(ResourceLoadSchedulerTest, PriorityIsConsidered) {
EXPECT_TRUE(client4->WasRun());
// Release the rest.
- EXPECT_TRUE(Release(id4));
EXPECT_TRUE(Release(id3));
EXPECT_TRUE(Release(id2));
EXPECT_TRUE(Release(id1));
@@ -511,12 +509,11 @@ TEST_F(ResourceLoadSchedulerTest, StoppableRequestResumesWhenThrottled) {
}
TEST_F(ResourceLoadSchedulerTest, SetPriority) {
- // Start with the normal scheduling policy.
- Scheduler()->LoosenThrottlingPolicy();
// Push three requests.
MockClient* client1 = MakeGarbageCollected<MockClient>();
- Scheduler()->SetOutstandingLimitForTesting(0);
+ // Allows one kHigh priority request by limits below.
+ Scheduler()->SetOutstandingLimitForTesting(0, 1);
ResourceLoadScheduler::ClientId id1 = ResourceLoadScheduler::kInvalidClientId;
Scheduler()->Request(client1, ThrottleOption::kThrottleable,
@@ -554,7 +551,16 @@ TEST_F(ResourceLoadSchedulerTest, SetPriority) {
EXPECT_FALSE(client2->WasRun());
EXPECT_FALSE(client3->WasRun());
- Scheduler()->SetOutstandingLimitForTesting(2);
+ // Loosen the policy to adopt the normal limit for all.
+ Scheduler()->LoosenThrottlingPolicy();
+ Scheduler()->SetOutstandingLimitForTesting(0, 2);
+
+ EXPECT_TRUE(client1->WasRun());
+ EXPECT_TRUE(client2->WasRun());
+ EXPECT_FALSE(client3->WasRun());
+
+ // kHigh priority does not help here.
+ Scheduler()->SetPriority(id3, ResourceLoadPriority::kHigh, 0);
EXPECT_TRUE(client1->WasRun());
EXPECT_TRUE(client2->WasRun());
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 838094ab45a..d09e6c051fb 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
@@ -4,35 +4,79 @@
#include "third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h"
+#include "services/network/public/mojom/load_timing_info.mojom-blink.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
namespace blink {
-ResourceLoadTiming::ResourceLoadTiming() {}
+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)
+ : request_time_(request_time),
+ proxy_start_(proxy_start),
+ proxy_end_(proxy_end),
+ dns_start_(dns_start),
+ dns_end_(dns_end),
+ connect_start_(connect_start),
+ connect_end_(connect_end),
+ worker_start_(worker_start),
+ worker_ready_(worker_ready),
+ send_start_(send_start),
+ send_end_(send_end),
+ receive_headers_start_(receive_headers_start),
+ receive_headers_end_(receive_headers_end),
+ ssl_start_(ssl_start),
+ ssl_end_(ssl_end),
+ push_start_(push_start),
+ push_end_(push_end) {}
scoped_refptr<ResourceLoadTiming> ResourceLoadTiming::Create() {
return base::AdoptRef(new ResourceLoadTiming);
}
-scoped_refptr<ResourceLoadTiming> ResourceLoadTiming::DeepCopy() {
- scoped_refptr<ResourceLoadTiming> timing = Create();
- timing->request_time_ = request_time_;
- timing->proxy_start_ = proxy_start_;
- timing->proxy_end_ = proxy_end_;
- timing->dns_start_ = dns_start_;
- timing->dns_end_ = dns_end_;
- timing->connect_start_ = connect_start_;
- timing->connect_end_ = connect_end_;
- timing->worker_start_ = worker_start_;
- timing->worker_ready_ = worker_ready_;
- timing->send_start_ = send_start_;
- timing->send_end_ = send_end_;
- timing->receive_headers_start_ = receive_headers_start_;
- timing->receive_headers_end_ = receive_headers_end_;
- timing->ssl_start_ = ssl_start_;
- timing->ssl_end_ = ssl_end_;
- timing->push_start_ = push_start_;
- timing->push_end_ = push_end_;
+scoped_refptr<ResourceLoadTiming> ResourceLoadTiming::FromMojo(
+ const network::mojom::blink::LoadTimingInfo* mojo_timing) {
+ if (!mojo_timing)
+ return ResourceLoadTiming::Create();
+ return base::AdoptRef(new ResourceLoadTiming(
+ mojo_timing->request_start, mojo_timing->proxy_resolve_start,
+ mojo_timing->proxy_resolve_end, mojo_timing->connect_timing->dns_start,
+ mojo_timing->connect_timing->dns_end,
+ 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->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,
+ mojo_timing->push_end));
+}
+
+network::mojom::blink::LoadTimingInfoPtr ResourceLoadTiming::ToMojo() const {
+ network::mojom::blink::LoadTimingInfoPtr timing =
+ network::mojom::blink::LoadTimingInfo::New(
+ false, 0, base::Time(), request_time_, proxy_start_, proxy_end_,
+ network::mojom::blink::LoadTimingInfoConnectTiming::New(
+ 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_);
return timing;
}
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 ef8321289d3..b87da1d183f 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
@@ -27,6 +27,7 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_RESOURCE_LOAD_TIMING_H_
#include "base/memory/scoped_refptr.h"
+#include "services/network/public/mojom/load_timing_info.mojom-blink-forward.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/ref_counted.h"
@@ -37,10 +38,13 @@ class PLATFORM_EXPORT ResourceLoadTiming
public:
static scoped_refptr<ResourceLoadTiming> Create();
- scoped_refptr<ResourceLoadTiming> DeepCopy();
bool operator==(const ResourceLoadTiming&) const;
bool operator!=(const ResourceLoadTiming&) const;
+ static scoped_refptr<ResourceLoadTiming> FromMojo(
+ const network::mojom::blink::LoadTimingInfo*);
+ network::mojom::blink::LoadTimingInfoPtr ToMojo() const;
+
void SetDnsStart(base::TimeTicks);
void SetRequestTime(base::TimeTicks);
void SetProxyStart(base::TimeTicks);
@@ -81,6 +85,23 @@ class PLATFORM_EXPORT ResourceLoadTiming
private:
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);
// We want to present a unified timeline to Javascript. Using walltime is
// problematic, because the clock may skew while resources load. To prevent
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 58399f33fd1..7f1a04c6fe4 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
@@ -41,6 +41,7 @@
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/mojom/fetch_api.mojom-blink.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/blob/blob_registry.mojom-blink.h"
#include "third_party/blink/public/mojom/devtools/console_message.mojom-blink.h"
@@ -67,6 +68,7 @@
#include "third_party/blink/renderer/platform/loader/fetch/resource_load_observer.h"
#include "third_party/blink/renderer/platform/loader/fetch/response_body_loader.h"
#include "third_party/blink/renderer/platform/loader/fetch/shared_buffer_bytes_consumer.h"
+#include "third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.h"
#include "third_party/blink/renderer/platform/loader/mixed_content_autoupgrade_status.h"
#include "third_party/blink/renderer/platform/network/http_names.h"
#include "third_party/blink/renderer/platform/network/http_parsers.h"
@@ -74,8 +76,8 @@
#include "third_party/blink/renderer/platform/network/network_utils.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
+#include "third_party/blink/renderer/platform/weborigin/reporting_disposition.h"
#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
-#include "third_party/blink/renderer/platform/weborigin/security_violation_reporting_policy.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
@@ -147,7 +149,7 @@ void LogMixedAutoupgradeMetrics(blink::MixedContentAutoupgradeStatus status,
builder.Record(recorder);
}
-bool CanHandleDataURLRequestLocally(const ResourceRequest& request) {
+bool CanHandleDataURLRequestLocally(const ResourceRequestHead& request) {
if (!request.Url().ProtocolIsData())
return false;
@@ -156,11 +158,6 @@ bool CanHandleDataURLRequestLocally(const ResourceRequest& request) {
if (request.DownloadToBlob())
return false;
- // Data url requests from object tags may need to be intercepted as streams
- // and so need to be sent to the browser.
- if (request.GetRequestContext() == mojom::RequestContextType::OBJECT)
- return false;
-
// Main resources are handled in the browser, so we can handle data url
// subresources locally.
return true;
@@ -178,6 +175,18 @@ bool RequestContextObserveResponse(mojom::RequestContextType type) {
}
}
+SchedulingPolicy::Feature GetFeatureFromRequestContextType(
+ mojom::RequestContextType type) {
+ switch (type) {
+ case mojom::RequestContextType::FETCH:
+ return SchedulingPolicy::Feature::kOutstandingNetworkRequestFetch;
+ case mojom::RequestContextType::XML_HTTP_REQUEST:
+ return SchedulingPolicy::Feature::kOutstandingNetworkRequestXHR;
+ default:
+ return SchedulingPolicy::Feature::kOutstandingNetworkRequestOthers;
+ }
+}
+
} // namespace
// CodeCacheRequest handles the requests to fetch data from code cache.
@@ -372,11 +381,13 @@ void ResourceLoader::CodeCacheRequest::MaybeSendCachedCode(
ResourceLoader::ResourceLoader(ResourceFetcher* fetcher,
ResourceLoadScheduler* scheduler,
Resource* resource,
+ ResourceRequestBody request_body,
uint32_t inflight_keepalive_bytes)
: scheduler_client_id_(ResourceLoadScheduler::kInvalidClientId),
fetcher_(fetcher),
scheduler_(scheduler),
resource_(resource),
+ request_body_(std::move(request_body)),
inflight_keepalive_bytes_(inflight_keepalive_bytes),
is_cache_aware_loading_activated_(false),
cancel_timer_(fetcher_->GetTaskRunner(),
@@ -389,11 +400,12 @@ ResourceLoader::ResourceLoader(ResourceFetcher* fetcher,
// If they are keepalive request && their responses are not observable to web
// content, we can have them survive without breaking web content when the
// page is put into BackForwardCache.
- auto request = resource_->GetResourceRequest();
- if (!RequestContextObserveResponse(request.GetRequestContext())) {
+ auto& request = resource_->GetResourceRequest();
+ auto request_context = request.GetRequestContext();
+ if (!RequestContextObserveResponse(request_context)) {
if (FrameScheduler* frame_scheduler = fetcher->GetFrameScheduler()) {
feature_handle_for_scheduler_ = frame_scheduler->RegisterFeature(
- SchedulingPolicy::Feature::kOutstandingNetworkRequest,
+ GetFeatureFromRequestContextType(request_context),
{SchedulingPolicy::RecordMetricsForBackForwardCache()});
}
}
@@ -403,7 +415,7 @@ ResourceLoader::ResourceLoader(ResourceFetcher* fetcher,
ResourceLoader::~ResourceLoader() = default;
-void ResourceLoader::Trace(blink::Visitor* visitor) {
+void ResourceLoader::Trace(Visitor* visitor) {
visitor->Trace(fetcher_);
visitor->Trace(scheduler_);
visitor->Trace(resource_);
@@ -415,11 +427,8 @@ void ResourceLoader::Trace(blink::Visitor* visitor) {
bool ResourceLoader::ShouldFetchCodeCache() {
if (!RuntimeEnabledFeatures::IsolatedCodeCacheEnabled())
return false;
- if (resource_->GetType() == ResourceType::kRaw &&
- !RuntimeEnabledFeatures::WasmCodeCacheEnabled())
- return false;
- const ResourceRequest& request = resource_->GetResourceRequest();
+ const ResourceRequestHead& request = resource_->GetResourceRequest();
if (!request.Url().ProtocolIsInHTTPFamily())
return false;
// When loading the service worker scripts, we don't need to check the
@@ -448,9 +457,12 @@ bool ResourceLoader::ShouldFetchCodeCache() {
}
void ResourceLoader::Start() {
- const ResourceRequest& request = resource_->GetResourceRequest();
+ const ResourceRequestHead& request = resource_->GetResourceRequest();
ActivateCacheAwareLoadingIfNeeded(request);
- loader_ = fetcher_->CreateURLLoader(request, resource_->Options());
+ // TODO(yoichio): Have CreateURLLoader take a ResourceRequestHead, not
+ // ResourceRequest.
+ loader_ =
+ fetcher_->CreateURLLoader(ResourceRequest(request), resource_->Options());
task_runner_for_body_loader_ = loader_->GetTaskRunner();
DCHECK_EQ(ResourceLoadScheduler::kInvalidClientId, scheduler_client_id_);
auto throttle_option = ResourceLoadScheduler::ThrottleOption::kThrottleable;
@@ -547,7 +559,7 @@ void ResourceLoader::DidCancelLoadingBody() {
Cancel();
}
-void ResourceLoader::StartWith(const ResourceRequest& request) {
+void ResourceLoader::StartWith(const ResourceRequestHead& request) {
DCHECK_NE(ResourceLoadScheduler::kInvalidClientId, scheduler_client_id_);
DCHECK(loader_);
@@ -570,7 +582,7 @@ void ResourceLoader::StartWith(const ResourceRequest& request) {
if (is_cache_aware_loading_activated_) {
// Override cache policy for cache-aware loading. If this request fails, a
// reload with original request will be triggered in DidFail().
- ResourceRequest cache_aware_request(request);
+ ResourceRequestHead cache_aware_request(request);
cache_aware_request.SetCacheMode(
mojom::FetchCacheMode::kUnspecifiedOnlyIfCachedStrict);
RequestAsynchronously(cache_aware_request);
@@ -594,9 +606,10 @@ void ResourceLoader::Release(
feature_handle_for_scheduler_.reset();
}
-void ResourceLoader::Restart(const ResourceRequest& request) {
+void ResourceLoader::Restart(const ResourceRequestHead& request) {
CHECK_EQ(resource_->Options().synchronous_policy, kRequestAsynchronously);
- loader_ = fetcher_->CreateURLLoader(request, resource_->Options());
+ loader_ =
+ fetcher_->CreateURLLoader(ResourceRequest(request), resource_->Options());
task_runner_for_body_loader_ = loader_->GetTaskRunner();
StartWith(request);
}
@@ -678,14 +691,14 @@ void ResourceLoader::CancelForRedirectAccessCheckError(
}
}
-static bool IsManualRedirectFetchRequest(const ResourceRequest& request) {
+static bool IsManualRedirectFetchRequest(const ResourceRequestHead& request) {
return request.GetRedirectMode() == network::mojom::RedirectMode::kManual &&
request.GetRequestContext() == mojom::RequestContextType::FETCH;
}
bool ResourceLoader::WillFollowRedirect(
const WebURL& new_url,
- const WebURL& new_site_for_cookies,
+ const net::SiteForCookies& new_site_for_cookies,
const WebString& new_referrer,
network::mojom::ReferrerPolicy new_referrer_policy,
const WebString& new_method,
@@ -704,12 +717,16 @@ bool ResourceLoader::WillFollowRedirect(
resource_->LastResourceRequest().CreateRedirectRequest(
new_url, new_method, new_site_for_cookies, new_referrer,
new_referrer_policy,
-
!passed_redirect_response.WasFetchedViaServiceWorker());
+ if (!RuntimeEnabledFeatures::OutOfBlinkCorsEnabled() &&
+ (new_request->HttpMethod() != http_names::kGET &&
+ new_request->HttpMethod() != http_names::kHEAD)) {
+ new_request->SetHttpBody(request_body_.FormBody());
+ }
ResourceType resource_type = resource_->GetType();
- const ResourceRequest& initial_request = resource_->GetResourceRequest();
+ const ResourceRequestHead& initial_request = resource_->GetResourceRequest();
// The following parameters never change during the lifetime of a request.
mojom::RequestContextType request_context =
initial_request.GetRequestContext();
@@ -726,19 +743,20 @@ bool ResourceLoader::WillFollowRedirect(
bool unused_preload = resource_->IsUnusedPreload();
// Don't send security violation reports for unused preloads.
- SecurityViolationReportingPolicy reporting_policy =
- unused_preload ? SecurityViolationReportingPolicy::kSuppressReporting
- : SecurityViolationReportingPolicy::kReport;
+ ReportingDisposition reporting_disposition =
+ unused_preload ? ReportingDisposition::kSuppressReporting
+ : ReportingDisposition::kReport;
// CanRequest() checks only enforced CSP, so check report-only here to
// ensure that violations are sent.
Context().CheckCSPForRequest(
- request_context, new_url, options, reporting_policy,
+ request_context, new_url, options, reporting_disposition,
ResourceRequest::RedirectStatus::kFollowedRedirect);
base::Optional<ResourceRequestBlockedReason> blocked_reason =
Context().CanRequest(
- resource_type, *new_request, new_url, options, reporting_policy,
+ resource_type, *new_request, new_url, options,
+ reporting_disposition,
ResourceRequest::RedirectStatus::kFollowedRedirect);
if (Context().CalculateIfAdSubresource(*new_request, resource_type))
@@ -756,9 +774,9 @@ bool ResourceLoader::WillFollowRedirect(
new_url, request_mode, origin.get(),
GetCorsFlag() ? CorsFlag::Set : CorsFlag::Unset);
if (!cors_error && GetCorsFlag()) {
- cors_error = cors::CheckAccess(
- new_url, redirect_response.HttpStatusCode(),
- redirect_response.HttpHeaderFields(), credentials_mode, *origin);
+ cors_error =
+ cors::CheckAccess(new_url, redirect_response.HttpHeaderFields(),
+ credentials_mode, *origin);
}
if (cors_error) {
HandleError(
@@ -809,18 +827,20 @@ bool ResourceLoader::WillFollowRedirect(
redirect_response_with_type ? *redirect_response_with_type
: redirect_response;
- // The following two calls may rewrite the new_request.Url() to
+ // The following two calls may rewrite the new_request->Url() to
// something else not for rejecting redirect but for other reasons.
// E.g. WebFrameTestClient::WillSendRequest() and
// RenderFrameImpl::WillSendRequest(). We should reflect the
- // rewriting but currently we cannot. So, compare new_request.Url() and
+ // rewriting but currently we cannot. So, compare new_request->Url() and
// new_url after calling them, and return false to make the redirect fail on
// mismatch.
WebScopedVirtualTimePauser unused_virtual_time_pauser;
+ // TODO(yoichio): Have PrepareRequest use ResourceRequestHead.
Context().PrepareRequest(*new_request, resource_->Options().initiator_info,
- unused_virtual_time_pauser,
- resource_->GetType());
+ unused_virtual_time_pauser, resource_->GetType());
+ if (RuntimeEnabledFeatures::OutOfBlinkCorsEnabled())
+ DCHECK(!new_request->HttpBody());
if (auto* observer = fetcher_->GetResourceLoadObserver()) {
observer->WillSendRequest(resource_->InspectorId(), *new_request,
redirect_response_to_pass, resource_->GetType(),
@@ -830,7 +850,7 @@ bool ResourceLoader::WillFollowRedirect(
// First-party cookie logic moved from DocumentLoader in Blink to
// net::URLRequest in the browser. Assert that Blink didn't try to change it
// to something else.
- DCHECK(KURL(new_site_for_cookies) == new_request->SiteForCookies());
+ DCHECK(new_request->SiteForCookies().IsEquivalent(new_site_for_cookies));
// The following parameters never change during the lifetime of a request.
DCHECK_EQ(new_request->GetRequestContext(), request_context);
@@ -909,7 +929,7 @@ void ResourceLoader::DidReceiveResponse(const WebURLResponse& response) {
void ResourceLoader::DidReceiveResponseInternal(
const ResourceResponse& response) {
- const ResourceRequest& request = resource_->GetResourceRequest();
+ const ResourceRequestHead& request = resource_->GetResourceRequest();
if (request.IsAutomaticUpgrade()) {
mojo::PendingRemote<ukm::mojom::UkmRecorderInterface> pending_recorder;
@@ -932,7 +952,7 @@ void ResourceLoader::DidReceiveResponseInternal(
ResourceType resource_type = resource_->GetType();
- const ResourceRequest& initial_request = resource_->GetResourceRequest();
+ const ResourceRequestHead& initial_request = resource_->GetResourceRequest();
// The following parameters never change during the lifetime of a request.
mojom::RequestContextType request_context =
initial_request.GetRequestContext();
@@ -957,12 +977,25 @@ void ResourceLoader::DidReceiveResponseInternal(
return;
}
+ // https://wicg.github.io/cross-origin-embedder-policy/#integration-html
+ // TODO(crbug.com/1064920): Remove this once PlzDedicatedWorker ships.
+ if (options.reject_coep_unsafe_none &&
+ response.GetCrossOriginEmbedderPolicy() !=
+ network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp &&
+ !response.CurrentRequestUrl().ProtocolIsData() &&
+ !response.CurrentRequestUrl().ProtocolIs("blob")) {
+ DCHECK(!base::FeatureList::IsEnabled(features::kPlzDedicatedWorker));
+ HandleError(ResourceError::Failure(response.CurrentRequestUrl()));
+ return;
+ }
+
if (response.WasFetchedViaServiceWorker()) {
if (options.cors_handling_by_resource_fetcher ==
kEnableCorsHandlingByResourceFetcher &&
request_mode == network::mojom::RequestMode::kCors &&
response.WasFallbackRequiredByServiceWorker()) {
- ResourceRequest last_request = resource_->LastResourceRequest();
+ DCHECK(resource_->RedirectChain().IsEmpty());
+ ResourceRequestHead last_request(resource_->GetResourceRequest());
DCHECK(!last_request.GetSkipServiceWorker());
// This code handles the case when a controlling service worker doesn't
// handle a cross origin request.
@@ -999,14 +1032,13 @@ void ResourceLoader::DidReceiveResponseInternal(
// CanRequest() below only checks enforced policies: check report-only
// here to ensure violations are sent.
Context().CheckCSPForRequest(
- request_context, response_url, options,
- SecurityViolationReportingPolicy::kReport,
+ request_context, response_url, options, ReportingDisposition::kReport,
ResourceRequest::RedirectStatus::kFollowedRedirect);
base::Optional<ResourceRequestBlockedReason> blocked_reason =
Context().CanRequest(
- resource_type, initial_request, response_url, options,
- SecurityViolationReportingPolicy::kReport,
+ resource_type, ResourceRequest(initial_request), response_url,
+ options, ReportingDisposition::kReport,
ResourceRequest::RedirectStatus::kFollowedRedirect);
if (blocked_reason) {
HandleError(ResourceError::CancelledDueToAccessCheckError(
@@ -1021,9 +1053,8 @@ void ResourceLoader::DidReceiveResponseInternal(
!(resource_->IsCacheValidator() && response.HttpStatusCode() == 304)) {
if (GetCorsFlag()) {
base::Optional<network::CorsErrorStatus> cors_error = cors::CheckAccess(
- response.CurrentRequestUrl(), response.HttpStatusCode(),
- response.HttpHeaderFields(), initial_request.GetCredentialsMode(),
- *resource_->GetOrigin());
+ response.CurrentRequestUrl(), response.HttpHeaderFields(),
+ initial_request.GetCredentialsMode(), *resource_->GetOrigin());
if (cors_error) {
HandleError(ResourceError(response.CurrentRequestUrl(), *cors_error));
return;
@@ -1040,9 +1071,12 @@ void ResourceLoader::DidReceiveResponseInternal(
// FrameType never changes during the lifetime of a request.
if (auto* observer = fetcher_->GetResourceLoadObserver()) {
+ ResourceRequest request_for_obserber(initial_request);
+ // TODO(yoichio): Have DidReceiveResponse take a ResourceResponseHead, not
+ // ResourceRequest.
observer->DidReceiveResponse(
- resource_->InspectorId(), initial_request, response_to_pass, resource_,
- ResourceLoadObserver::ResponseSource::kNotFromMemoryCache);
+ resource_->InspectorId(), request_for_obserber, response_to_pass,
+ resource_, ResourceLoadObserver::ResponseSource::kNotFromMemoryCache);
}
resource_->ResponseReceived(response_to_pass);
@@ -1182,7 +1216,7 @@ void ResourceLoader::DidFail(const WebURLError& error,
int64_t encoded_data_length,
int64_t encoded_body_length,
int64_t decoded_body_length) {
- const ResourceRequest& request = resource_->GetResourceRequest();
+ const ResourceRequestHead& request = resource_->GetResourceRequest();
if (request.IsAutomaticUpgrade()) {
mojo::PendingRemote<ukm::mojom::UkmRecorderInterface> pending_recorder;
@@ -1242,11 +1276,16 @@ void ResourceLoader::HandleError(const ResourceError& error) {
inflight_keepalive_bytes_);
}
-void ResourceLoader::RequestSynchronously(const ResourceRequest& request) {
+void ResourceLoader::RequestSynchronously(const ResourceRequestHead& request) {
DCHECK(loader_);
DCHECK_EQ(request.Priority(), ResourceLoadPriority::kHighest);
- WrappedResourceRequest request_in(request);
+ auto network_resource_request = std::make_unique<network::ResourceRequest>();
+ scoped_refptr<EncodedFormData> form_body = request_body_.FormBody();
+ PopulateResourceRequest(request, std::move(request_body_),
+ network_resource_request.get());
+ if (form_body)
+ request_body_ = ResourceRequestBody(std::move(form_body));
WebURLResponse response_out;
base::Optional<WebURLError> error_out;
WebData data_out;
@@ -1271,9 +1310,15 @@ void ResourceLoader::RequestSynchronously(const ResourceRequest& request) {
data_out = WebData(std::move(data));
}
} else {
- loader_->LoadSynchronously(request_in, this, response_out, error_out,
- data_out, encoded_data_length,
- encoded_body_length, downloaded_blob);
+ // Don't do mime sniffing for fetch (crbug.com/2016)
+ bool no_mime_sniffing =
+ request.GetRequestContext() == blink::mojom::RequestContextType::FETCH;
+ loader_->LoadSynchronously(
+ std::move(network_resource_request), request.GetExtraData(),
+ request.RequestorID(), request.IsDownloadToNetworkCacheOnly(),
+ request.DownloadToBlob(), no_mime_sniffing, request.TimeoutInterval(),
+ this, response_out, error_out, data_out, encoded_data_length,
+ encoded_body_length, downloaded_blob);
}
// A message dispatched while synchronously fetching the resource
// can bring about the cancellation of this load.
@@ -1312,7 +1357,7 @@ void ResourceLoader::RequestSynchronously(const ResourceRequest& request) {
encoded_body_length, decoded_body_length, false);
}
-void ResourceLoader::RequestAsynchronously(const ResourceRequest& request) {
+void ResourceLoader::RequestAsynchronously(const ResourceRequestHead& request) {
DCHECK(loader_);
if (CanHandleDataURLRequestLocally(request)) {
DCHECK(!code_cache_request_);
@@ -1323,7 +1368,19 @@ void ResourceLoader::RequestAsynchronously(const ResourceRequest& request) {
return;
}
- loader_->LoadAsynchronously(WrappedResourceRequest(request), this);
+ auto network_resource_request = std::make_unique<network::ResourceRequest>();
+ // Don't do mime sniffing for fetch (crbug.com/2016)
+ bool no_mime_sniffing =
+ request.GetRequestContext() == blink::mojom::RequestContextType::FETCH;
+ scoped_refptr<EncodedFormData> form_body = request_body_.FormBody();
+ PopulateResourceRequest(request, std::move(request_body_),
+ network_resource_request.get());
+ if (form_body)
+ request_body_ = ResourceRequestBody(std::move(form_body));
+ loader_->LoadAsynchronously(std::move(network_resource_request),
+ request.GetExtraData(), request.RequestorID(),
+ request.IsDownloadToNetworkCacheOnly(),
+ no_mime_sniffing, this);
if (code_cache_request_) {
// Sets defers loading and initiates a fetch from code cache.
code_cache_request_->FetchFromCodeCache(loader_.get(), this);
@@ -1346,7 +1403,7 @@ void ResourceLoader::Dispose() {
}
void ResourceLoader::ActivateCacheAwareLoadingIfNeeded(
- const ResourceRequest& request) {
+ const ResourceRequestHead& request) {
DCHECK(!is_cache_aware_loading_activated_);
if (resource_->Options().cache_aware_loading_enabled !=
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 0046f323f2e..ba73d21ca9d 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
@@ -75,9 +75,10 @@ class PLATFORM_EXPORT ResourceLoader final
ResourceLoader(ResourceFetcher*,
ResourceLoadScheduler*,
Resource*,
+ ResourceRequestBody request_body = ResourceRequestBody(),
uint32_t inflight_keepalive_bytes = 0);
~ResourceLoader() override;
- void Trace(blink::Visitor*) override;
+ void Trace(Visitor*) override;
void Start();
@@ -90,7 +91,7 @@ class PLATFORM_EXPORT ResourceLoader final
// Called before start() to activate cache-aware loading if enabled in
// |m_resource->options()| and applicable.
- void ActivateCacheAwareLoadingIfNeeded(const ResourceRequest&);
+ void ActivateCacheAwareLoadingIfNeeded(const ResourceRequestHead&);
bool IsCacheAwareLoadingActivated() const {
return is_cache_aware_loading_activated_;
@@ -113,14 +114,13 @@ class PLATFORM_EXPORT ResourceLoader final
// A failed load is indicated by 1 DidFail(), which can occur at any time
// before DidFinishLoading(), including synchronous inside one of the other
// callbacks via ResourceLoader::cancel()
- bool WillFollowRedirect(
- const WebURL& new_url,
- const WebURL& new_site_for_cookies,
- const WebString& new_referrer,
- network::mojom::ReferrerPolicy new_referrer_policy,
- const WebString& new_method,
- const WebURLResponse& passed_redirect_response,
- bool& report_raw_headers) override;
+ bool WillFollowRedirect(const WebURL& new_url,
+ const net::SiteForCookies& new_site_for_cookies,
+ const WebString& new_referrer,
+ network::mojom::ReferrerPolicy new_referrer_policy,
+ const WebString& new_method,
+ const WebURLResponse& passed_redirect_response,
+ bool& report_raw_headers) override;
void DidSendData(uint64_t bytes_sent,
uint64_t total_bytes_to_be_sent) override;
void DidReceiveResponse(const WebURLResponse&) override;
@@ -166,7 +166,7 @@ class PLATFORM_EXPORT ResourceLoader final
void DidCancelLoadingBody() override;
bool ShouldFetchCodeCache();
- void StartWith(const ResourceRequest&);
+ void StartWith(const ResourceRequestHead&);
void Release(ResourceLoadScheduler::ReleaseOption,
const ResourceLoadScheduler::TrafficReportHints&);
@@ -174,7 +174,7 @@ class PLATFORM_EXPORT ResourceLoader final
// This method is currently only used for service worker fallback request and
// cache-aware loading, other users should be careful not to break
// ResourceLoader state.
- void Restart(const ResourceRequest&);
+ void Restart(const ResourceRequestHead&);
FetchContext& Context() const;
@@ -184,8 +184,8 @@ class PLATFORM_EXPORT ResourceLoader final
void CancelForRedirectAccessCheckError(const KURL&,
ResourceRequestBlockedReason);
- void RequestSynchronously(const ResourceRequest&);
- void RequestAsynchronously(const ResourceRequest&);
+ void RequestSynchronously(const ResourceRequestHead&);
+ void RequestAsynchronously(const ResourceRequestHead&);
void Dispose();
void DidReceiveResponseInternal(const ResourceResponse&);
@@ -211,6 +211,7 @@ class PLATFORM_EXPORT ResourceLoader final
Member<ResourceFetcher> fetcher_;
Member<ResourceLoadScheduler> scheduler_;
Member<Resource> resource_;
+ ResourceRequestBody request_body_;
Member<ResponseBodyLoader> response_body_loader_;
Member<DataPipeBytesConsumer::CompletionNotifier>
data_pipe_completion_notifier_;
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_defer_loading_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_defer_loading_test.cc
index 16769297a2d..b074e42e062 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_defer_loading_test.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_defer_loading_test.cc
@@ -91,17 +91,30 @@ class ResourceLoaderDefersLoadingTest::TestWebURLLoader final
: defers_flag_ptr_(defers_flag_ptr) {}
~TestWebURLLoader() override = default;
- void LoadSynchronously(const WebURLRequest&,
- WebURLLoaderClient*,
- WebURLResponse&,
- base::Optional<WebURLError>&,
- WebData&,
- int64_t& encoded_data_length,
- int64_t& encoded_body_length,
- WebBlobInfo& downloaded_blob) override {
+ void LoadSynchronously(
+ std::unique_ptr<network::ResourceRequest> request,
+ scoped_refptr<WebURLRequest::ExtraData> request_extra_data,
+ int requestor_id,
+ bool download_to_network_cache_only,
+ bool pass_response_pipe_to_client,
+ bool no_mime_sniffing,
+ base::TimeDelta timeout_interval,
+ WebURLLoaderClient*,
+ WebURLResponse&,
+ base::Optional<WebURLError>&,
+ WebData&,
+ int64_t& encoded_data_length,
+ int64_t& encoded_body_length,
+ WebBlobInfo& downloaded_blob) override {
NOTREACHED();
}
- void LoadAsynchronously(const WebURLRequest&, WebURLLoaderClient*) override {}
+ void LoadAsynchronously(
+ std::unique_ptr<network::ResourceRequest> request,
+ scoped_refptr<WebURLRequest::ExtraData> request_extra_data,
+ int requestor_id,
+ bool download_to_network_cache_only,
+ bool no_mime_sniffing,
+ WebURLLoaderClient*) override {}
void SetDefersLoading(bool defers) override { *defers_flag_ptr_ = defers; }
void DidChangePriority(WebURLRequest::Priority, int) override {
@@ -177,7 +190,7 @@ TEST_F(ResourceLoaderDefersLoadingTest, CodeCacheFetchCheckDefers) {
ResourceRequest request;
request.SetUrl(test_url_);
request.SetRequestContext(mojom::RequestContextType::FETCH);
- FetchParameters fetch_parameters(request);
+ FetchParameters fetch_parameters(std::move(request));
Resource* resource = RawResource::Fetch(fetch_parameters, fetcher, nullptr);
@@ -200,7 +213,7 @@ TEST_F(ResourceLoaderDefersLoadingTest, CodeCacheFetchSyncReturn) {
ResourceRequest request;
request.SetUrl(test_url_);
request.SetRequestContext(mojom::RequestContextType::FETCH);
- FetchParameters fetch_parameters(request);
+ FetchParameters fetch_parameters(std::move(request));
Resource* resource = RawResource::Fetch(fetch_parameters, fetcher, nullptr);
DCHECK(resource);
@@ -214,7 +227,7 @@ TEST_F(ResourceLoaderDefersLoadingTest, ChangeDefersToFalse) {
ResourceRequest request;
request.SetUrl(test_url_);
request.SetRequestContext(mojom::RequestContextType::FETCH);
- FetchParameters fetch_parameters(request);
+ FetchParameters fetch_parameters(std::move(request));
Resource* resource = RawResource::Fetch(fetch_parameters, fetcher, nullptr);
DCHECK(web_url_loader_defers_);
@@ -232,7 +245,7 @@ TEST_F(ResourceLoaderDefersLoadingTest, ChangeDefersToTrue) {
ResourceRequest request;
request.SetUrl(test_url_);
request.SetRequestContext(mojom::RequestContextType::FETCH);
- FetchParameters fetch_parameters(request);
+ FetchParameters fetch_parameters(std::move(request));
Resource* resource = RawResource::Fetch(fetch_parameters, fetcher, nullptr);
DCHECK(web_url_loader_defers_);
@@ -254,7 +267,7 @@ TEST_F(ResourceLoaderDefersLoadingTest, ChangeDefersMultipleTimes) {
request.SetUrl(test_url_);
request.SetRequestContext(mojom::RequestContextType::FETCH);
- FetchParameters fetch_parameters(request);
+ FetchParameters fetch_parameters(std::move(request));
Resource* resource = RawResource::Fetch(fetch_parameters, fetcher, nullptr);
DCHECK(web_url_loader_defers_);
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_options.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_options.cc
index df25cab69b1..cb2c29d1c77 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_options.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_options.cc
@@ -36,7 +36,7 @@ namespace blink {
ResourceLoaderOptions::ResourceLoaderOptions()
: data_buffering_policy(kBufferData),
- content_security_policy_option(kCheckContentSecurityPolicy),
+ content_security_policy_option(network::mojom::CSPDisposition::CHECK),
request_initiator_context(kDocumentContext),
synchronous_policy(kRequestAsynchronously),
cors_handling_by_resource_fetcher(kEnableCorsHandlingByResourceFetcher),
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h
index b233ca5deed..8cc09706c37 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h
@@ -32,7 +32,9 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_RESOURCE_LOADER_OPTIONS_H_
#include "base/memory/scoped_refptr.h"
+#include "base/util/type_safety/strong_alias.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "services/network/public/mojom/content_security_policy.mojom-blink-forward.h"
#include "services/network/public/mojom/url_loader_factory.mojom-blink-forward.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_info.h"
#include "third_party/blink/renderer/platform/loader/fetch/integrity_metadata.h"
@@ -44,11 +46,6 @@ namespace blink {
enum DataBufferingPolicy : uint8_t { kBufferData, kDoNotBufferData };
-enum ContentSecurityPolicyDisposition : uint8_t {
- kCheckContentSecurityPolicy,
- kDoNotCheckContentSecurityPolicy
-};
-
enum RequestInitiatorContext : uint8_t {
kDocumentContext,
kWorkerContext,
@@ -75,6 +72,12 @@ enum CacheAwareLoadingEnabled : uint8_t {
kIsCacheAwareLoadingEnabled
};
+// https://github.com/WICG/cross-origin-embedder-policy/pull/13
+// When true, a response is blocked unless it has
+// cross-origin-embedder-policy: require-corp.
+using RejectCoepUnsafeNone =
+ util::StrongAlias<class RejectCoepUnsafeNoneTag, bool>;
+
// This class is thread-bound. Do not copy/pass an instance across threads.
struct PLATFORM_EXPORT ResourceLoaderOptions {
USING_FAST_MALLOC(ResourceLoaderOptions);
@@ -93,7 +96,7 @@ struct PLATFORM_EXPORT ResourceLoaderOptions {
DataBufferingPolicy data_buffering_policy;
- ContentSecurityPolicyDisposition content_security_policy_option;
+ network::mojom::CSPDisposition content_security_policy_option;
RequestInitiatorContext request_initiator_context;
SynchronousPolicy synchronous_policy;
@@ -105,6 +108,9 @@ struct PLATFORM_EXPORT ResourceLoaderOptions {
// Corresponds to the CORS flag in the Fetch spec.
bool cors_flag;
+ // TODO(crbug.com/1064920): Remove this once PlzDedicatedWorker ships.
+ RejectCoepUnsafeNone reject_coep_unsafe_none = RejectCoepUnsafeNone(false);
+
String content_security_policy_nonce;
IntegrityMetadataSet integrity_metadata;
ParserDisposition parser_disposition;
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 9a88c03ab81..7d307cefc7c 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
@@ -75,21 +75,34 @@ class ResourceLoaderTest : public testing::Test {
private:
class NoopWebURLLoader final : public WebURLLoader {
public:
- NoopWebURLLoader(scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ explicit NoopWebURLLoader(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner)
: task_runner_(task_runner) {}
~NoopWebURLLoader() override = default;
- void LoadSynchronously(const WebURLRequest&,
- WebURLLoaderClient*,
- WebURLResponse&,
- base::Optional<WebURLError>&,
- WebData&,
- int64_t& encoded_data_length,
- int64_t& encoded_body_length,
- WebBlobInfo& downloaded_blob) override {
+ void LoadSynchronously(
+ std::unique_ptr<network::ResourceRequest> request,
+ scoped_refptr<WebURLRequest::ExtraData> request_extra_data,
+ int requestor_id,
+ bool download_to_network_cache_only,
+ bool pass_response_pipe_to_client,
+ bool no_mime_sniffing,
+ base::TimeDelta timeout_interval,
+ WebURLLoaderClient*,
+ WebURLResponse&,
+ base::Optional<WebURLError>&,
+ WebData&,
+ int64_t& encoded_data_length,
+ int64_t& encoded_body_length,
+ WebBlobInfo& downloaded_blob) override {
NOTREACHED();
}
- void LoadAsynchronously(const WebURLRequest&,
- WebURLLoaderClient*) override {}
+ void LoadAsynchronously(
+ std::unique_ptr<network::ResourceRequest> request,
+ scoped_refptr<WebURLRequest::ExtraData> request_extra_data,
+ int requestor_id,
+ bool download_to_network_cache_only,
+ bool no_mime_sniffing,
+ WebURLLoaderClient*) override {}
void SetDefersLoading(bool) override {}
void DidChangePriority(WebURLRequest::Priority, int) override {
@@ -182,7 +195,7 @@ TEST_F(ResourceLoaderTest, ResponseType) {
request.SetMode(test.request_mode);
request.SetRequestContext(mojom::RequestContextType::FETCH);
- FetchParameters fetch_parameters(request);
+ FetchParameters fetch_parameters(std::move(request));
if (test.request_mode == network::mojom::RequestMode::kCors) {
fetch_parameters.SetCrossOriginAccessControl(
origin.get(), network::mojom::CredentialsMode::kOmit);
@@ -216,7 +229,7 @@ TEST_F(ResourceLoaderTest, LoadResponseBody) {
ResourceRequest request(url);
request.SetRequestContext(mojom::RequestContextType::FETCH);
- FetchParameters params(request);
+ FetchParameters params(std::move(request));
Resource* resource = RawResource::Fetch(params, fetcher, nullptr);
ResourceLoader* loader = resource->Loader();
@@ -280,7 +293,7 @@ TEST_F(ResourceLoaderTest, LoadDataURL_AsyncAndNonStream) {
KURL url("data:text/plain,Hello%20World!");
ResourceRequest request(url);
request.SetRequestContext(mojom::RequestContextType::FETCH);
- FetchParameters params(request);
+ FetchParameters params(std::move(request));
Resource* resource = RawResource::Fetch(params, fetcher, nullptr);
EXPECT_EQ(resource->GetStatus(), ResourceStatus::kPending);
static_cast<scheduler::FakeTaskRunner*>(fetcher->GetTaskRunner().get())
@@ -338,7 +351,7 @@ TEST_F(ResourceLoaderTest, LoadDataURL_AsyncAndStream) {
ResourceRequest request(url);
request.SetRequestContext(mojom::RequestContextType::FETCH);
request.SetUseStreamOnResponse(true);
- FetchParameters params(request);
+ FetchParameters params(std::move(request));
auto* raw_resource_client = MakeGarbageCollected<TestRawResourceClient>();
Resource* resource = RawResource::Fetch(params, fetcher, raw_resource_client);
EXPECT_EQ(resource->GetStatus(), ResourceStatus::kPending);
@@ -374,7 +387,7 @@ TEST_F(ResourceLoaderTest, LoadDataURL_AsyncEmptyData) {
KURL url("data:text/html,");
ResourceRequest request(url);
request.SetRequestContext(mojom::RequestContextType::FETCH);
- FetchParameters params(request);
+ FetchParameters params(std::move(request));
Resource* resource = RawResource::Fetch(params, fetcher, nullptr);
EXPECT_EQ(resource->GetStatus(), ResourceStatus::kPending);
static_cast<scheduler::FakeTaskRunner*>(fetcher->GetTaskRunner().get())
@@ -397,7 +410,7 @@ TEST_F(ResourceLoaderTest, LoadDataURL_Sync) {
KURL url("data:text/plain,Hello%20World!");
ResourceRequest request(url);
request.SetRequestContext(mojom::RequestContextType::FETCH);
- FetchParameters params(request);
+ FetchParameters params(std::move(request));
Resource* resource =
RawResource::FetchSynchronously(params, fetcher, nullptr);
@@ -422,7 +435,7 @@ TEST_F(ResourceLoaderTest, LoadDataURL_SyncEmptyData) {
KURL url("data:text/html,");
ResourceRequest request(url);
request.SetRequestContext(mojom::RequestContextType::FETCH);
- FetchParameters params(request);
+ FetchParameters params(std::move(request));
Resource* resource =
RawResource::FetchSynchronously(params, fetcher, nullptr);
@@ -445,7 +458,7 @@ TEST_F(ResourceLoaderTest, LoadDataURL_DefersAsyncAndNonStream) {
KURL url("data:text/plain,Hello%20World!");
ResourceRequest request(url);
request.SetRequestContext(mojom::RequestContextType::FETCH);
- FetchParameters params(request);
+ FetchParameters params(std::move(request));
Resource* resource = RawResource::Fetch(params, fetcher, nullptr);
EXPECT_EQ(resource->GetStatus(), ResourceStatus::kPending);
@@ -492,7 +505,7 @@ TEST_F(ResourceLoaderTest, LoadDataURL_DefersAsyncAndStream) {
ResourceRequest request(url);
request.SetRequestContext(mojom::RequestContextType::FETCH);
request.SetUseStreamOnResponse(true);
- FetchParameters params(request);
+ FetchParameters params(std::move(request));
auto* raw_resource_client = MakeGarbageCollected<TestRawResourceClient>();
Resource* resource = RawResource::Fetch(params, fetcher, raw_resource_client);
EXPECT_EQ(resource->GetStatus(), ResourceStatus::kPending);
@@ -561,7 +574,7 @@ class ResourceLoaderIsolatedCodeCacheTest : public ResourceLoaderTest {
request.SetUrl(foo_url_);
request.SetRequestContext(mojom::RequestContextType::FETCH);
- FetchParameters fetch_parameters(request);
+ FetchParameters fetch_parameters(std::move(request));
Resource* resource = RawResource::Fetch(fetch_parameters, fetcher, nullptr);
ResourceLoader* loader = resource->Loader();
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 b36dbcf738b..8ee020a6df7 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
@@ -40,15 +40,12 @@
namespace blink {
-const base::TimeDelta ResourceRequest::default_timeout_interval_ =
+const base::TimeDelta ResourceRequestHead::default_timeout_interval_ =
base::TimeDelta::Max();
-ResourceRequest::ResourceRequest() : ResourceRequest(NullURL()) {}
+ResourceRequestHead::ResourceRequestHead() : ResourceRequestHead(NullURL()) {}
-ResourceRequest::ResourceRequest(const String& url_string)
- : ResourceRequest(KURL(url_string)) {}
-
-ResourceRequest::ResourceRequest(const KURL& url)
+ResourceRequestHead::ResourceRequestHead(const KURL& url)
: url_(url),
timeout_interval_(default_timeout_interval_),
http_method_(http_names::kGET),
@@ -64,33 +61,86 @@ ResourceRequest::ResourceRequest(const KURL& url)
cache_mode_(mojom::FetchCacheMode::kDefault),
skip_service_worker_(false),
download_to_cache_only_(false),
+ site_for_cookies_set_(false),
priority_(ResourceLoadPriority::kUnresolved),
intra_priority_value_(0),
requestor_id_(0),
previews_state_(WebURLRequest::kPreviewsUnspecified),
request_context_(mojom::RequestContextType::UNSPECIFIED),
+ destination_(network::mojom::RequestDestination::kEmpty),
mode_(network::mojom::RequestMode::kNoCors),
fetch_importance_mode_(mojom::FetchImportanceMode::kImportanceAuto),
credentials_mode_(network::mojom::CredentialsMode::kInclude),
redirect_mode_(network::mojom::RedirectMode::kFollow),
referrer_string_(Referrer::ClientReferrerString()),
referrer_policy_(network::mojom::ReferrerPolicy::kDefault),
- did_set_http_referrer_(false),
is_external_request_(false),
cors_preflight_policy_(
network::mojom::CorsPreflightPolicy::kConsiderPreflight),
redirect_status_(RedirectStatus::kNoRedirect) {}
-ResourceRequest::ResourceRequest(const ResourceRequest&) = default;
+ResourceRequestHead::ResourceRequestHead(const ResourceRequestHead&) = default;
+
+ResourceRequestHead& ResourceRequestHead::operator=(
+ const ResourceRequestHead&) = default;
+
+ResourceRequestHead::ResourceRequestHead(ResourceRequestHead&&) = default;
+
+ResourceRequestHead& ResourceRequestHead::operator=(ResourceRequestHead&&) =
+ default;
+
+ResourceRequestHead::~ResourceRequestHead() = default;
+
+ResourceRequestBody::ResourceRequestBody() : ResourceRequestBody(nullptr) {}
+
+ResourceRequestBody::ResourceRequestBody(
+ scoped_refptr<EncodedFormData> form_body)
+ : form_body_(form_body) {}
+
+ResourceRequestBody::ResourceRequestBody(ResourceRequestBody&& src)
+ : ResourceRequestBody(std::move(src.form_body_)) {}
+
+ResourceRequestBody& ResourceRequestBody::operator=(ResourceRequestBody&& src) {
+ form_body_ = std::move(src.form_body_);
+ return *this;
+}
+
+ResourceRequestBody::~ResourceRequestBody() = default;
+
+ResourceRequest::ResourceRequest() : ResourceRequestHead(NullURL()) {}
+
+ResourceRequest::ResourceRequest(const String& url_string)
+ : ResourceRequestHead(KURL(url_string)) {}
+
+ResourceRequest::ResourceRequest(const KURL& url) : ResourceRequestHead(url) {}
+
+ResourceRequest::ResourceRequest(const ResourceRequestHead& head)
+ : ResourceRequestHead(head) {}
+
+ResourceRequest& ResourceRequest::operator=(const ResourceRequest& src) {
+ this->ResourceRequestHead::operator=(src);
+ body_.SetFormBody(src.body_.FormBody());
+ return *this;
+}
+
+ResourceRequest::ResourceRequest(ResourceRequest&&) = default;
+
+ResourceRequest& ResourceRequest::operator=(ResourceRequest&&) = default;
ResourceRequest::~ResourceRequest() = default;
-ResourceRequest& ResourceRequest::operator=(const ResourceRequest&) = default;
+void ResourceRequest::CopyFrom(const ResourceRequest& src) {
+ *this = src;
+}
-std::unique_ptr<ResourceRequest> ResourceRequest::CreateRedirectRequest(
+void ResourceRequest::CopyHeadFrom(const ResourceRequestHead& src) {
+ this->ResourceRequestHead::operator=(src);
+}
+
+std::unique_ptr<ResourceRequest> ResourceRequestHead::CreateRedirectRequest(
const KURL& new_url,
const AtomicString& new_method,
- const KURL& new_site_for_cookies,
+ const net::SiteForCookies& new_site_for_cookies,
const String& new_referrer,
network::mojom::ReferrerPolicy new_referrer_policy,
bool skip_service_worker) const {
@@ -102,9 +152,8 @@ std::unique_ptr<ResourceRequest> ResourceRequest::CreateRedirectRequest(
request->SetSiteForCookies(new_site_for_cookies);
String referrer =
new_referrer.IsEmpty() ? Referrer::NoReferrer() : String(new_referrer);
- // TODO(domfarolino): Stop storing ResourceRequest's generated referrer as a
- // header and instead use a separate member. See https://crbug.com/850813.
- request->SetHttpReferrer(Referrer(referrer, new_referrer_policy));
+ request->SetReferrerString(referrer);
+ request->SetReferrerPolicy(new_referrer_policy);
request->SetSkipServiceWorker(skip_service_worker);
request->SetRedirectStatus(RedirectStatus::kFollowedRedirect);
@@ -118,8 +167,6 @@ std::unique_ptr<ResourceRequest> ResourceRequest::CreateRedirectRequest(
request->SetKeepalive(GetKeepalive());
request->SetPriority(Priority());
- if (request->HttpMethod() == HttpMethod())
- request->SetHttpBody(HttpBody());
request->SetCorsPreflightPolicy(CorsPreflightPolicy());
if (IsAdResource())
request->SetIsAdResource();
@@ -138,27 +185,27 @@ std::unique_ptr<ResourceRequest> ResourceRequest::CreateRedirectRequest(
return request;
}
-bool ResourceRequest::IsNull() const {
+bool ResourceRequestHead::IsNull() const {
return url_.IsNull();
}
-const KURL& ResourceRequest::Url() const {
+const KURL& ResourceRequestHead::Url() const {
return url_;
}
-void ResourceRequest::SetUrl(const KURL& url) {
+void ResourceRequestHead::SetUrl(const KURL& url) {
url_ = url;
}
-const KURL& ResourceRequest::GetInitialUrlForResourceTiming() const {
+const KURL& ResourceRequestHead::GetInitialUrlForResourceTiming() const {
return initial_url_for_resource_timing_;
}
-void ResourceRequest::SetInitialUrlForResourceTiming(const KURL& url) {
+void ResourceRequestHead::SetInitialUrlForResourceTiming(const KURL& url) {
initial_url_for_resource_timing_ = url;
}
-void ResourceRequest::RemoveUserAndPassFromURL() {
+void ResourceRequestHead::RemoveUserAndPassFromURL() {
if (url_.User().IsEmpty() && url_.Pass().IsEmpty())
return;
@@ -166,155 +213,146 @@ void ResourceRequest::RemoveUserAndPassFromURL() {
url_.SetPass(String());
}
-mojom::FetchCacheMode ResourceRequest::GetCacheMode() const {
+mojom::FetchCacheMode ResourceRequestHead::GetCacheMode() const {
return cache_mode_;
}
-void ResourceRequest::SetCacheMode(mojom::FetchCacheMode cache_mode) {
+void ResourceRequestHead::SetCacheMode(mojom::FetchCacheMode cache_mode) {
cache_mode_ = cache_mode;
}
-base::TimeDelta ResourceRequest::TimeoutInterval() const {
+base::TimeDelta ResourceRequestHead::TimeoutInterval() const {
return timeout_interval_;
}
-void ResourceRequest::SetTimeoutInterval(
+void ResourceRequestHead::SetTimeoutInterval(
base::TimeDelta timout_interval_seconds) {
timeout_interval_ = timout_interval_seconds;
}
-const KURL& ResourceRequest::SiteForCookies() const {
+const net::SiteForCookies& ResourceRequestHead::SiteForCookies() const {
return site_for_cookies_;
}
-void ResourceRequest::SetSiteForCookies(const KURL& site_for_cookies) {
+void ResourceRequestHead::SetSiteForCookies(
+ const net::SiteForCookies& site_for_cookies) {
site_for_cookies_ = site_for_cookies;
+ site_for_cookies_set_ = true;
}
-const SecurityOrigin* ResourceRequest::TopFrameOrigin() const {
+const SecurityOrigin* ResourceRequestHead::TopFrameOrigin() const {
return top_frame_origin_.get();
}
-void ResourceRequest::SetTopFrameOrigin(
+void ResourceRequestHead::SetTopFrameOrigin(
scoped_refptr<const SecurityOrigin> origin) {
top_frame_origin_ = std::move(origin);
}
-const AtomicString& ResourceRequest::HttpMethod() const {
+const AtomicString& ResourceRequestHead::HttpMethod() const {
return http_method_;
}
-void ResourceRequest::SetHttpMethod(const AtomicString& http_method) {
+void ResourceRequestHead::SetHttpMethod(const AtomicString& http_method) {
http_method_ = http_method;
}
-const HTTPHeaderMap& ResourceRequest::HttpHeaderFields() const {
+const HTTPHeaderMap& ResourceRequestHead::HttpHeaderFields() const {
return http_header_fields_;
}
-const AtomicString& ResourceRequest::HttpHeaderField(
+const AtomicString& ResourceRequestHead::HttpHeaderField(
const AtomicString& name) const {
return http_header_fields_.Get(name);
}
-void ResourceRequest::SetHttpHeaderField(const AtomicString& name,
- const AtomicString& value) {
+void ResourceRequestHead::SetHttpHeaderField(const AtomicString& name,
+ const AtomicString& value) {
http_header_fields_.Set(name, value);
}
-void ResourceRequest::SetHttpReferrer(const Referrer& referrer) {
- if (referrer.referrer.IsEmpty())
- http_header_fields_.Remove(http_names::kReferer);
- else
- SetHttpHeaderField(http_names::kReferer, referrer.referrer);
- referrer_policy_ = referrer.referrer_policy;
- did_set_http_referrer_ = true;
-}
-
-void ResourceRequest::ClearHTTPReferrer() {
- http_header_fields_.Remove(http_names::kReferer);
- referrer_policy_ = network::mojom::ReferrerPolicy::kDefault;
- did_set_http_referrer_ = false;
-}
-
-void ResourceRequest::SetHTTPOrigin(const SecurityOrigin* origin) {
+void ResourceRequestHead::SetHTTPOrigin(const SecurityOrigin* origin) {
SetHttpHeaderField(http_names::kOrigin, origin->ToAtomicString());
}
-void ResourceRequest::ClearHTTPOrigin() {
+void ResourceRequestHead::ClearHTTPOrigin() {
http_header_fields_.Remove(http_names::kOrigin);
}
-void ResourceRequest::SetHttpOriginIfNeeded(const SecurityOrigin* origin) {
+void ResourceRequestHead::SetHttpOriginIfNeeded(const SecurityOrigin* origin) {
if (NeedsHTTPOrigin())
SetHTTPOrigin(origin);
}
-void ResourceRequest::SetHTTPOriginToMatchReferrerIfNeeded() {
+void ResourceRequestHead::SetHTTPOriginToMatchReferrerIfNeeded() {
if (NeedsHTTPOrigin()) {
- SetHTTPOrigin(
- SecurityOrigin::CreateFromString(HttpHeaderField(http_names::kReferer))
- .get());
+ SetHTTPOrigin(SecurityOrigin::CreateFromString(ReferrerString()).get());
}
}
-void ResourceRequest::ClearHTTPUserAgent() {
+void ResourceRequestHead::ClearHTTPUserAgent() {
http_header_fields_.Remove(http_names::kUserAgent);
}
-EncodedFormData* ResourceRequest::HttpBody() const {
- return http_body_.get();
+void ResourceRequestBody::SetFormBody(
+ scoped_refptr<EncodedFormData> form_body) {
+ form_body_ = std::move(form_body);
+}
+
+const scoped_refptr<EncodedFormData>& ResourceRequest::HttpBody() const {
+ return body_.FormBody();
}
void ResourceRequest::SetHttpBody(scoped_refptr<EncodedFormData> http_body) {
- http_body_ = std::move(http_body);
+ body_.SetFormBody(std::move(http_body));
}
-bool ResourceRequest::AllowStoredCredentials() const {
+bool ResourceRequestHead::AllowStoredCredentials() const {
return allow_stored_credentials_;
}
-void ResourceRequest::SetAllowStoredCredentials(bool allow_credentials) {
+void ResourceRequestHead::SetAllowStoredCredentials(bool allow_credentials) {
allow_stored_credentials_ = allow_credentials;
}
-ResourceLoadPriority ResourceRequest::Priority() const {
+ResourceLoadPriority ResourceRequestHead::Priority() const {
return priority_;
}
-int ResourceRequest::IntraPriorityValue() const {
+int ResourceRequestHead::IntraPriorityValue() const {
return intra_priority_value_;
}
-bool ResourceRequest::PriorityHasBeenSet() const {
+bool ResourceRequestHead::PriorityHasBeenSet() const {
return priority_ != ResourceLoadPriority::kUnresolved;
}
-void ResourceRequest::SetPriority(ResourceLoadPriority priority,
- int intra_priority_value) {
+void ResourceRequestHead::SetPriority(ResourceLoadPriority priority,
+ int intra_priority_value) {
priority_ = priority;
intra_priority_value_ = intra_priority_value;
}
-void ResourceRequest::AddHttpHeaderField(const AtomicString& name,
- const AtomicString& value) {
+void ResourceRequestHead::AddHttpHeaderField(const AtomicString& name,
+ const AtomicString& value) {
HTTPHeaderMap::AddResult result = http_header_fields_.Add(name, value);
if (!result.is_new_entry)
result.stored_value->value = result.stored_value->value + ", " + value;
}
-void ResourceRequest::AddHTTPHeaderFields(const HTTPHeaderMap& header_fields) {
+void ResourceRequestHead::AddHTTPHeaderFields(
+ const HTTPHeaderMap& header_fields) {
HTTPHeaderMap::const_iterator end = header_fields.end();
for (HTTPHeaderMap::const_iterator it = header_fields.begin(); it != end;
++it)
AddHttpHeaderField(it->key, it->value);
}
-void ResourceRequest::ClearHttpHeaderField(const AtomicString& name) {
+void ResourceRequestHead::ClearHttpHeaderField(const AtomicString& name) {
http_header_fields_.Remove(name);
}
-void ResourceRequest::SetExternalRequestStateFromRequestorAddressSpace(
+void ResourceRequestHead::SetExternalRequestStateFromRequestorAddressSpace(
network::mojom::IPAddressSpace requestor_space) {
static_assert(network::mojom::IPAddressSpace::kLocal <
network::mojom::IPAddressSpace::kPrivate,
@@ -344,7 +382,7 @@ void ResourceRequest::SetExternalRequestStateFromRequestorAddressSpace(
is_external_request_ = requestor_space > target_space;
}
-bool ResourceRequest::IsConditional() const {
+bool ResourceRequestHead::IsConditional() const {
return (http_header_fields_.Contains(http_names::kIfMatch) ||
http_header_fields_.Contains(http_names::kIfModifiedSince) ||
http_header_fields_.Contains(http_names::kIfNoneMatch) ||
@@ -352,11 +390,11 @@ bool ResourceRequest::IsConditional() const {
http_header_fields_.Contains(http_names::kIfUnmodifiedSince));
}
-void ResourceRequest::SetHasUserGesture(bool has_user_gesture) {
+void ResourceRequestHead::SetHasUserGesture(bool has_user_gesture) {
has_user_gesture_ |= has_user_gesture;
}
-bool ResourceRequest::CanDisplay(const KURL& url) const {
+bool ResourceRequestHead::CanDisplay(const KURL& url) const {
if (RequestorOrigin()->CanDisplay(url))
return true;
@@ -366,7 +404,7 @@ bool ResourceRequest::CanDisplay(const KURL& url) const {
return false;
}
-const CacheControlHeader& ResourceRequest::GetCacheControlHeader() const {
+const CacheControlHeader& ResourceRequestHead::GetCacheControlHeader() const {
if (!cache_control_header_cache_.parsed) {
cache_control_header_cache_ = ParseCacheControlDirectives(
http_header_fields_.Get(http_names::kCacheControl),
@@ -375,20 +413,20 @@ const CacheControlHeader& ResourceRequest::GetCacheControlHeader() const {
return cache_control_header_cache_;
}
-bool ResourceRequest::CacheControlContainsNoCache() const {
+bool ResourceRequestHead::CacheControlContainsNoCache() const {
return GetCacheControlHeader().contains_no_cache;
}
-bool ResourceRequest::CacheControlContainsNoStore() const {
+bool ResourceRequestHead::CacheControlContainsNoStore() const {
return GetCacheControlHeader().contains_no_store;
}
-bool ResourceRequest::HasCacheValidatorFields() const {
+bool ResourceRequestHead::HasCacheValidatorFields() const {
return !http_header_fields_.Get(http_names::kLastModified).IsEmpty() ||
!http_header_fields_.Get(http_names::kETag).IsEmpty();
}
-bool ResourceRequest::NeedsHTTPOrigin() const {
+bool ResourceRequestHead::NeedsHTTPOrigin() const {
if (!HttpOrigin().IsEmpty())
return false; // Request already has an Origin header.
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 4148460ef54..71139b093a3 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
@@ -34,10 +34,12 @@
#include "base/optional.h"
#include "base/time/time.h"
#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/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"
+#include "services/network/public/mojom/trust_tokens.mojom-blink.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink-forward.h"
#include "third_party/blink/public/platform/resource_request_blocked_reason.h"
#include "third_party/blink/public/platform/web_url_request.h"
@@ -52,36 +54,34 @@
namespace blink {
class EncodedFormData;
-struct Referrer;
-// A ResourceRequest is a "request" object for ResourceLoader. Conceptually
-// it is https://fetch.spec.whatwg.org/#concept-request, but it contains
-// a lot of blink specific fields. WebURLRequest is the "public version"
-// of this class and WebURLLoader needs it. See WebURLRequest and
-// WrappedResourceRequest.
-//
-// This class is thread-bound. Do not copy/pass an instance across threads.
-class PLATFORM_EXPORT ResourceRequest final {
- USING_FAST_MALLOC(ResourceRequest);
+// ResourceRequestHead represents request without request body.
+// See ResourceRequest below to see what request is.
+// ResourceRequestHead is implicitly copyable while ResourceRequest is not.
+// TODO(yoichio) : Migrate existing ResourceRequest occurrence not using request
+// body to ResourceRequestHead.
+class PLATFORM_EXPORT ResourceRequestHead {
+ DISALLOW_NEW();
public:
enum class RedirectStatus : uint8_t { kFollowedRedirect, kNoRedirect };
- ResourceRequest();
- explicit ResourceRequest(const String& url_string);
- explicit ResourceRequest(const KURL&);
+ ResourceRequestHead();
+ explicit ResourceRequestHead(const KURL&);
- // TODO(toyoshim): Use std::unique_ptr as much as possible, and hopefully
- // make ResourceRequest DISALLOW_COPY_AND_ASSIGN. See crbug.com/787704.
- ResourceRequest(const ResourceRequest&);
- ResourceRequest& operator=(const ResourceRequest&);
+ ResourceRequestHead(const ResourceRequestHead&);
+ ResourceRequestHead& operator=(const ResourceRequestHead&);
+ ResourceRequestHead(ResourceRequestHead&&);
+ ResourceRequestHead& operator=(ResourceRequestHead&&);
- ~ResourceRequest();
+ ~ResourceRequestHead();
// Constructs a new ResourceRequest for a redirect from this instance.
+ // Since body for a redirect request is kept and handled in the network
+ // service, the returned instance here in blink side doesn't contain body.
std::unique_ptr<ResourceRequest> CreateRedirectRequest(
const KURL& new_url,
const AtomicString& new_method,
- const KURL& new_site_for_cookies,
+ const net::SiteForCookies& new_site_for_cookies,
const String& new_referrer,
network::mojom::ReferrerPolicy new_referrer_policy,
bool skip_service_worker) const;
@@ -107,8 +107,12 @@ class PLATFORM_EXPORT ResourceRequest final {
base::TimeDelta TimeoutInterval() const;
void SetTimeoutInterval(base::TimeDelta);
- const KURL& SiteForCookies() const;
- void SetSiteForCookies(const KURL&);
+ const net::SiteForCookies& SiteForCookies() const;
+ void SetSiteForCookies(const net::SiteForCookies&);
+
+ // Returns true if SiteForCookies() was set either via SetSiteForCookies or
+ // CreateRedirectRequest.
+ bool SiteForCookiesSet() const { return site_for_cookies_set_; }
const SecurityOrigin* TopFrameOrigin() const;
void SetTopFrameOrigin(scoped_refptr<const SecurityOrigin>);
@@ -151,16 +155,6 @@ class PLATFORM_EXPORT ResourceRequest final {
SetHttpHeaderField(http_names::kContentType, http_content_type);
}
- // TODO(domfarolino): Remove this once we stop storing the generated referrer
- // as a header, and instead use a separate member. See
- // https://crbug.com/850813.
- const AtomicString& HttpReferrer() const {
- return HttpHeaderField(http_names::kReferer);
- }
- void SetHttpReferrer(const Referrer&);
- bool DidSetHttpReferrer() const { return did_set_http_referrer_; }
- void ClearHTTPReferrer();
-
void SetReferrerPolicy(network::mojom::ReferrerPolicy referrer_policy) {
referrer_policy_ = referrer_policy;
}
@@ -190,9 +184,6 @@ class PLATFORM_EXPORT ResourceRequest final {
SetHttpHeaderField(http_names::kAccept, http_accept);
}
- EncodedFormData* HttpBody() const;
- void SetHttpBody(scoped_refptr<EncodedFormData>);
-
bool AllowStoredCredentials() const;
void SetAllowStoredCredentials(bool allow_credentials);
@@ -256,16 +247,11 @@ class PLATFORM_EXPORT ResourceRequest final {
}
// Extra data associated with this request.
- WebURLRequest::ExtraData* GetExtraData() const {
- return sharable_extra_data_ ? sharable_extra_data_->data.get() : nullptr;
+ const scoped_refptr<WebURLRequest::ExtraData>& GetExtraData() const {
+ return extra_data_;
}
- void SetExtraData(std::unique_ptr<WebURLRequest::ExtraData> extra_data) {
- if (extra_data) {
- sharable_extra_data_ =
- base::MakeRefCounted<SharableExtraData>(std::move(extra_data));
- } else {
- sharable_extra_data_ = nullptr;
- }
+ void SetExtraData(scoped_refptr<WebURLRequest::ExtraData> extra_data) {
+ extra_data_ = extra_data;
}
bool IsDownloadToNetworkCacheOnly() const { return download_to_cache_only_; }
@@ -281,6 +267,13 @@ class PLATFORM_EXPORT ResourceRequest final {
request_context_ = context;
}
+ network::mojom::RequestDestination GetRequestDestination() const {
+ return destination_;
+ }
+ void SetRequestDestination(network::mojom::RequestDestination destination) {
+ destination_ = destination;
+ }
+
network::mojom::RequestMode GetMode() const { return mode_; }
void SetMode(network::mojom::RequestMode mode) { mode_ = mode; }
@@ -448,14 +441,20 @@ class PLATFORM_EXPORT ResourceRequest final {
prefetch_maybe_for_top_level_navigation;
}
+ const base::Optional<network::mojom::blink::TrustTokenParams>&
+ TrustTokenParams() const {
+ return trust_token_params_;
+ }
+ void SetTrustTokenParams(
+ base::Optional<network::mojom::blink::TrustTokenParams> params) {
+ trust_token_params_ = std::move(params);
+ }
+
// Whether either RequestorOrigin or IsolatedWorldOrigin can display the
// |url|,
bool CanDisplay(const KURL&) const;
private:
- using SharableExtraData =
- base::RefCountedData<std::unique_ptr<WebURLRequest::ExtraData>>;
-
const CacheControlHeader& GetCacheControlHeader() const;
bool NeedsHTTPOrigin() const;
@@ -467,7 +466,7 @@ class PLATFORM_EXPORT ResourceRequest final {
// base::TimeDelta::Max() represents the default timeout on platforms that
// have one.
base::TimeDelta timeout_interval_;
- KURL site_for_cookies_;
+ net::SiteForCookies site_for_cookies_;
scoped_refptr<const SecurityOrigin> top_frame_origin_;
scoped_refptr<const SecurityOrigin> requestor_origin_;
@@ -475,7 +474,6 @@ class PLATFORM_EXPORT ResourceRequest final {
AtomicString http_method_;
HTTPHeaderMap http_header_fields_;
- scoped_refptr<EncodedFormData> http_body_;
bool allow_stored_credentials_ : 1;
bool report_upload_progress_ : 1;
bool report_raw_headers_ : 1;
@@ -488,12 +486,14 @@ class PLATFORM_EXPORT ResourceRequest final {
mojom::FetchCacheMode cache_mode_;
bool skip_service_worker_ : 1;
bool download_to_cache_only_ : 1;
+ bool site_for_cookies_set_ : 1;
ResourceLoadPriority priority_;
int intra_priority_value_;
int requestor_id_;
WebURLRequest::PreviewsState previews_state_;
- scoped_refptr<SharableExtraData> sharable_extra_data_;
+ scoped_refptr<WebURLRequest::ExtraData> extra_data_;
mojom::RequestContextType request_context_;
+ network::mojom::RequestDestination destination_;
network::mojom::RequestMode mode_;
mojom::FetchImportanceMode fetch_importance_mode_;
network::mojom::CredentialsMode credentials_mode_;
@@ -501,10 +501,10 @@ class PLATFORM_EXPORT ResourceRequest final {
String fetch_integrity_;
String referrer_string_;
network::mojom::ReferrerPolicy referrer_policy_;
- bool did_set_http_referrer_;
bool is_external_request_;
network::mojom::CorsPreflightPolicy cors_preflight_policy_;
RedirectStatus redirect_status_;
+ base::Optional<network::mojom::blink::TrustTokenParams> trust_token_params_;
base::Optional<String> suggested_filename_;
@@ -547,6 +547,70 @@ class PLATFORM_EXPORT ResourceRequest final {
base::Optional<base::UnguessableToken> recursive_prefetch_token_;
};
+class PLATFORM_EXPORT ResourceRequestBody {
+ public:
+ ResourceRequestBody();
+ explicit ResourceRequestBody(scoped_refptr<EncodedFormData> form_body);
+ ResourceRequestBody(const ResourceRequestBody&) = delete;
+ ResourceRequestBody(ResourceRequestBody&&);
+
+ ResourceRequestBody& operator=(const ResourceRequestBody&) = delete;
+ ResourceRequestBody& operator=(ResourceRequestBody&&);
+
+ ~ResourceRequestBody();
+
+ const scoped_refptr<EncodedFormData>& FormBody() const { return form_body_; }
+ void SetFormBody(scoped_refptr<EncodedFormData>);
+
+ private:
+ scoped_refptr<EncodedFormData> form_body_;
+};
+
+// A ResourceRequest is a "request" object for ResourceLoader. Conceptually
+// it is https://fetch.spec.whatwg.org/#concept-request, but it contains
+// a lot of blink specific fields. WebURLRequest is the "public version"
+// of this class and WebURLLoader needs it. See WebURLRequest and
+// WrappedResourceRequest.
+//
+// This class is thread-bound. Do not copy/pass an instance across threads.
+//
+// Although request consists head and body, ResourceRequest is implemented by
+// inheriting ResourceRequestHead due in order to make it possible to use
+// property accessors through both ResourceRequestHead and ResourceRequest while
+// avoiding duplicate accessor definitions.
+// For those who want to add a new property in request, please implement its
+// member and accessors in ResourceRequestHead instead of ResourceRequest.
+class PLATFORM_EXPORT ResourceRequest final : public ResourceRequestHead {
+ USING_FAST_MALLOC(ResourceRequest);
+
+ public:
+ ResourceRequest();
+ explicit ResourceRequest(const String& url_string);
+ explicit ResourceRequest(const KURL&);
+ explicit ResourceRequest(const ResourceRequestHead&);
+
+ ResourceRequest(const ResourceRequest&) = delete;
+ ResourceRequest(ResourceRequest&&);
+ ResourceRequest& operator=(ResourceRequest&&);
+
+ ~ResourceRequest();
+
+ // TODO(yoichio): Use move semantics as much as possible.
+ // See crbug.com/787704.
+ void CopyFrom(const ResourceRequest&);
+ void CopyHeadFrom(const ResourceRequestHead&);
+
+ const scoped_refptr<EncodedFormData>& HttpBody() const;
+ void SetHttpBody(scoped_refptr<EncodedFormData>);
+
+ ResourceRequestBody& MutableBody() { return body_; }
+
+ private:
+ ResourceRequest& operator=(const ResourceRequest&);
+
+ ResourceRequestBody body_;
+};
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_RESOURCE_REQUEST_H_
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_request_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_request_test.cc
index ffb5fbcea4d..cde5b01c787 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_request_test.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_request_test.cc
@@ -33,7 +33,7 @@ TEST(ResourceRequestTest, SetIsAdResource) {
std::unique_ptr<ResourceRequest> redirect_request =
original.CreateRedirectRequest(
KURL("https://example.test/redirect"), original.HttpMethod(),
- original.SiteForCookies(), original.HttpReferrer(),
+ original.SiteForCookies(), original.ReferrerString(),
original.GetReferrerPolicy(), original.GetSkipServiceWorker());
EXPECT_TRUE(redirect_request->IsAdResource());
}
@@ -48,7 +48,7 @@ TEST(ResourceRequestTest, UpgradeIfInsecureAcrossRedirects) {
std::unique_ptr<ResourceRequest> redirect_request =
original.CreateRedirectRequest(
KURL("https://example.test/redirect"), original.HttpMethod(),
- original.SiteForCookies(), original.HttpReferrer(),
+ original.SiteForCookies(), original.ReferrerString(),
original.GetReferrerPolicy(), original.GetSkipServiceWorker());
EXPECT_TRUE(redirect_request->UpgradeIfInsecure());
}
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 e7a8fbad67f..f7848a110e7 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
@@ -31,6 +31,7 @@
#include <memory>
#include <string>
+#include "net/http/structured_headers.h"
#include "services/network/public/cpp/cors/cors.h"
#include "services/network/public/mojom/fetch_api.mojom-blink.h"
#include "third_party/blink/public/platform/web_url_response.h"
@@ -207,16 +208,16 @@ void ResourceResponse::UpdateHeaderParsedState(const AtomicString& name) {
static const char kExpiresHeader[] = "expires";
static const char kLastModifiedHeader[] = "last-modified";
- if (DeprecatedEqualIgnoringCase(name, kAgeHeader))
+ if (EqualIgnoringASCIICase(name, kAgeHeader))
have_parsed_age_header_ = false;
- else if (DeprecatedEqualIgnoringCase(name, kCacheControlHeader) ||
- DeprecatedEqualIgnoringCase(name, kPragmaHeader))
+ else if (EqualIgnoringASCIICase(name, kCacheControlHeader) ||
+ EqualIgnoringASCIICase(name, kPragmaHeader))
cache_control_header_ = CacheControlHeader();
- else if (DeprecatedEqualIgnoringCase(name, kDateHeader))
+ else if (EqualIgnoringASCIICase(name, kDateHeader))
have_parsed_date_header_ = false;
- else if (DeprecatedEqualIgnoringCase(name, kExpiresHeader))
+ else if (EqualIgnoringASCIICase(name, kExpiresHeader))
have_parsed_expires_header_ = false;
- else if (DeprecatedEqualIgnoringCase(name, kLastModifiedHeader))
+ else if (EqualIgnoringASCIICase(name, kLastModifiedHeader))
have_parsed_last_modified_header_ = false;
}
@@ -415,7 +416,7 @@ bool ResourceResponse::IsAttachment() const {
if (loc != kNotFound)
value = value.Left(loc);
value = value.StripWhiteSpace();
- return DeprecatedEqualIgnoringCase(value, kAttachmentString);
+ return EqualIgnoringASCIICase(value, kAttachmentString);
}
AtomicString ResourceResponse::HttpContentType() const {
@@ -489,6 +490,19 @@ void ResourceResponse::SetDecodedBodyLength(int64_t value) {
decoded_body_length_ = value;
}
+network::mojom::CrossOriginEmbedderPolicyValue
+ResourceResponse::GetCrossOriginEmbedderPolicy() const {
+ static constexpr char kHeaderName[] = "cross-origin-embedder-policy";
+ const std::string value = HttpHeaderField(kHeaderName).Utf8();
+ using Item = net::structured_headers::Item;
+ const auto item = net::structured_headers::ParseItem(value);
+ if (!item || item->item.Type() != Item::kTokenType ||
+ item->item.GetString() != "require-corp") {
+ return network::mojom::CrossOriginEmbedderPolicyValue::kNone;
+ }
+ return network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp;
+}
+
STATIC_ASSERT_ENUM(WebURLResponse::kHTTPVersionUnknown,
ResourceResponse::kHTTPVersionUnknown);
STATIC_ASSERT_ENUM(WebURLResponse::kHTTPVersion_0_9,
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 9ba1090ee2e..4028c6341d2 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
@@ -33,6 +33,7 @@
#include "base/memory/scoped_refptr.h"
#include "base/optional.h"
#include "base/time/time.h"
+#include "services/network/public/mojom/cross_origin_embedder_policy.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"
@@ -282,6 +283,9 @@ class PLATFORM_EXPORT ResourceResponse final {
bool IsLegacyTLSVersion() const { return is_legacy_tls_version_; }
void SetIsLegacyTLSVersion(bool value) { is_legacy_tls_version_ = value; }
+ bool TimingAllowPassed() const { return timing_allow_passed_; }
+ void SetTimingAllowPassed(bool value) { timing_allow_passed_ = value; }
+
SecurityStyle GetSecurityStyle() const { return security_style_; }
void SetSecurityStyle(SecurityStyle security_style) {
security_style_ = security_style;
@@ -465,6 +469,9 @@ class PLATFORM_EXPORT ResourceResponse final {
was_in_prefetch_cache_ = was_in_prefetch_cache;
}
+ network::mojom::CrossOriginEmbedderPolicyValue GetCrossOriginEmbedderPolicy()
+ const;
+
private:
void UpdateHeaderParsedState(const AtomicString& name);
@@ -504,6 +511,10 @@ class PLATFORM_EXPORT ResourceResponse final {
// will be removed in the future.
bool is_legacy_tls_version_ = false;
+ // True if the Timing-Allow-Origin check passes.
+ // https://fetch.spec.whatwg.org/#concept-response-timing-allow-passed
+ bool timing_allow_passed_ = false;
+
// The time at which the resource's certificate expires. Null if there was no
// certificate.
base::Time cert_validity_start_;
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_test.cc
index 599ec997269..4353c202b8a 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_test.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_test.cc
@@ -575,4 +575,11 @@ TEST(ResourceTest, StaleWhileRevalidateCacheControlWithRedirect) {
EXPECT_TRUE(resource->StaleRevalidationRequested());
}
+// This is a regression test for https://crbug.com/1062837.
+TEST(ResourceTest, DefaultOverheadSize) {
+ const KURL url("http://127.0.0.1:8000/foo.html");
+ auto* resource = MakeGarbageCollected<MockResource>(url);
+ EXPECT_EQ(resource->CalculateOverheadSizeForTest(), resource->OverheadSize());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h
index 32f53487f19..9eaba1ab7fc 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h
@@ -51,8 +51,10 @@ class PLATFORM_EXPORT ResourceTimingInfo
static scoped_refptr<ResourceTimingInfo> Create(
const AtomicString& type,
const base::TimeTicks time,
- mojom::RequestContextType context) {
- return base::AdoptRef(new ResourceTimingInfo(type, time, context));
+ mojom::RequestContextType context,
+ network::mojom::RequestDestination destination) {
+ return base::AdoptRef(
+ new ResourceTimingInfo(type, time, context, destination));
}
base::TimeTicks InitialTime() const { return initial_time_; }
@@ -91,6 +93,9 @@ class PLATFORM_EXPORT ResourceTimingInfo
}
bool NegativeAllowed() const { return negative_allowed_; }
mojom::RequestContextType ContextType() const { return context_type_; }
+ network::mojom::RequestDestination RequestDestination() const {
+ return request_destination_;
+ }
void SetWorkerTimingReceiver(
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
@@ -106,12 +111,17 @@ class PLATFORM_EXPORT ResourceTimingInfo
private:
ResourceTimingInfo(const AtomicString& type,
const base::TimeTicks time,
- mojom::RequestContextType context_type)
- : type_(type), initial_time_(time), context_type_(context_type) {}
+ mojom::RequestContextType context_type,
+ network::mojom::RequestDestination request_destination)
+ : type_(type),
+ initial_time_(time),
+ context_type_(context_type),
+ request_destination_(request_destination) {}
AtomicString type_;
base::TimeTicks initial_time_;
mojom::RequestContextType context_type_;
+ network::mojom::RequestDestination request_destination_;
base::TimeTicks load_response_end_;
KURL initial_url_;
ResourceResponse final_response_;
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 07882629bc3..33cedf848d7 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
@@ -4,45 +4,73 @@
#include "third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.h"
+#include "base/metrics/histogram_macros.h"
#include "third_party/blink/renderer/platform/loader/fetch/cached_metadata.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource.h"
namespace blink {
+namespace {
+
+void RecordState(StateOnGet state) {
+ UMA_HISTOGRAM_ENUMERATION("Memory.Renderer.BlinkCachedMetadataGetResult",
+ state);
+}
+
+} // namespace
+
ScriptCachedMetadataHandler::ScriptCachedMetadataHandler(
const WTF::TextEncoding& encoding,
std::unique_ptr<CachedMetadataSender> sender)
: sender_(std::move(sender)), encoding_(encoding) {}
-void ScriptCachedMetadataHandler::Trace(blink::Visitor* visitor) {
+void ScriptCachedMetadataHandler::Trace(Visitor* visitor) {
CachedMetadataHandler::Trace(visitor);
}
-void ScriptCachedMetadataHandler::SetCachedMetadata(
- uint32_t data_type_id,
- const uint8_t* data,
- size_t size,
- CachedMetadataHandler::CacheType cache_type) {
- // Currently, only one type of cached metadata per resource is supported. If
- // the need arises for multiple types of metadata per resource this could be
- // enhanced to store types of metadata in a map.
+void ScriptCachedMetadataHandler::SetCachedMetadata(uint32_t data_type_id,
+ const uint8_t* data,
+ size_t size) {
DCHECK(!cached_metadata_);
+ // Having been discarded once, the further attempts to overwrite the
+ // CachedMetadata are ignored. This behavior is slightly easier to simulate in
+ // tests. Should happen rarely enough not to affect performance. The
+ // JSModuleScript behaves similarly by preventing the creation of the code
+ // cache.
+ if (cached_metadata_discarded_)
+ return;
cached_metadata_ = CachedMetadata::Create(data_type_id, data, size);
- if (cache_type == CachedMetadataHandler::kSendToPlatform)
- SendToPlatform();
+ if (!disable_send_to_platform_for_testing_)
+ CommitToPersistentStorage();
}
void ScriptCachedMetadataHandler::ClearCachedMetadata(
- CachedMetadataHandler::CacheType cache_type) {
+ ClearCacheType cache_type) {
cached_metadata_ = nullptr;
- if (cache_type == CachedMetadataHandler::kSendToPlatform)
- SendToPlatform();
+ switch (cache_type) {
+ case kClearLocally:
+ break;
+ case kDiscardLocally:
+ cached_metadata_discarded_ = true;
+ break;
+ case kClearPersistentStorage:
+ CommitToPersistentStorage();
+ break;
+ }
}
scoped_refptr<CachedMetadata> ScriptCachedMetadataHandler::GetCachedMetadata(
uint32_t data_type_id) const {
- if (!cached_metadata_ || cached_metadata_->DataTypeID() != data_type_id)
+ if (!cached_metadata_) {
+ RecordState(cached_metadata_discarded_ ? StateOnGet::kWasDiscarded
+ : StateOnGet::kWasNeverPresent);
+ return nullptr;
+ }
+ if (cached_metadata_->DataTypeID() != data_type_id) {
+ RecordState(StateOnGet::kDataTypeMismatch);
return nullptr;
+ }
+ RecordState(StateOnGet::kPresent);
return cached_metadata_;
}
@@ -79,7 +107,7 @@ size_t ScriptCachedMetadataHandler::GetCodeCacheSize() const {
return (cached_metadata_) ? cached_metadata_->SerializedData().size() : 0;
}
-void ScriptCachedMetadataHandler::SendToPlatform() {
+void ScriptCachedMetadataHandler::CommitToPersistentStorage() {
if (cached_metadata_) {
base::span<const uint8_t> serialized_data =
cached_metadata_->SerializedData();
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 4d1099b6625..df5ca5535a1 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,9 +33,9 @@ class PLATFORM_EXPORT ScriptCachedMetadataHandler final
ScriptCachedMetadataHandler(const WTF::TextEncoding&,
std::unique_ptr<CachedMetadataSender>);
~ScriptCachedMetadataHandler() override = default;
- void Trace(blink::Visitor*) override;
- void SetCachedMetadata(uint32_t, const uint8_t*, size_t, CacheType) override;
- void ClearCachedMetadata(CacheType) override;
+ void Trace(Visitor*) override;
+ void SetCachedMetadata(uint32_t, const uint8_t*, size_t) override;
+ void ClearCachedMetadata(ClearCacheType) override;
scoped_refptr<CachedMetadata> GetCachedMetadata(uint32_t) const override;
// This returns the encoding at the time of ResponseReceived(). Therefore this
@@ -56,14 +56,31 @@ class PLATFORM_EXPORT ScriptCachedMetadataHandler final
size_t GetCodeCacheSize() const override;
private:
- void SendToPlatform();
+ friend class ModuleScriptTest;
+
+ void CommitToPersistentStorage();
scoped_refptr<CachedMetadata> cached_metadata_;
+ bool cached_metadata_discarded_ = false;
std::unique_ptr<CachedMetadataSender> sender_;
const WTF::TextEncoding encoding_;
};
+// Describes a few interesting states of the ScriptCachedMetadataHandler when
+// GetCachedMetadata() is called. These values are written to logs. New enum
+// values can be added, but existing enums must never be renumbered or deleted
+// and reused.
+enum class StateOnGet : int {
+ kPresent = 0,
+ kDataTypeMismatch = 1,
+ kWasNeverPresent = 2,
+ kWasDiscarded = 3,
+
+ // Must be equal to the greatest among enumeraiton values.
+ kMaxValue = kWasDiscarded
+};
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_SCRIPT_CACHED_METADATA_HANDLER_H_
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.cc
index f5aebce8964..f2647226f07 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.cc
@@ -23,8 +23,10 @@ FetchParameters ScriptFetchOptions::CreateFetchParameters(
// Step 1. ... "script", ... [spec text]
ResourceLoaderOptions resource_loader_options;
resource_loader_options.initiator_info.name = "script";
- FetchParameters params(resource_request, resource_loader_options);
+ resource_loader_options.reject_coep_unsafe_none = reject_coep_unsafe_none_;
+ FetchParameters params(std::move(resource_request), resource_loader_options);
params.SetRequestContext(mojom::RequestContextType::SCRIPT);
+ params.SetRequestDestination(network::mojom::RequestDestination::kScript);
// Step 1. ... and CORS setting. [spec text]
if (cross_origin != kCrossOriginAttributeNotSet)
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.h b/chromium/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.h
index 24e2efe2f92..45977a46229 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.h
@@ -48,14 +48,17 @@ class PLATFORM_EXPORT ScriptFetchOptions final {
ParserDisposition parser_state,
network::mojom::CredentialsMode credentials_mode,
network::mojom::ReferrerPolicy referrer_policy,
- mojom::FetchImportanceMode importance)
+ mojom::FetchImportanceMode importance,
+ RejectCoepUnsafeNone reject_coep_unsafe_none =
+ RejectCoepUnsafeNone(false))
: nonce_(nonce),
integrity_metadata_(integrity_metadata),
integrity_attribute_(integrity_attribute),
parser_state_(parser_state),
credentials_mode_(credentials_mode),
referrer_policy_(referrer_policy),
- importance_(importance) {}
+ importance_(importance),
+ reject_coep_unsafe_none_(reject_coep_unsafe_none) {}
~ScriptFetchOptions() = default;
const String& Nonce() const { return nonce_; }
@@ -73,6 +76,9 @@ class PLATFORM_EXPORT ScriptFetchOptions final {
return referrer_policy_;
}
mojom::FetchImportanceMode Importance() const { return importance_; }
+ RejectCoepUnsafeNone GetRejectCoepUnsafeNone() const {
+ return reject_coep_unsafe_none_;
+ }
// https://html.spec.whatwg.org/C/#fetch-a-classic-script
// Steps 1 and 3.
@@ -104,6 +110,13 @@ class PLATFORM_EXPORT ScriptFetchOptions final {
// https://github.com/whatwg/html/issues/3670 for some discussion on adding an
// "importance" member to the script fetch options struct.
const mojom::FetchImportanceMode importance_;
+
+ // True when we should reject a response with COEP: none.
+ // https://wicg.github.io/cross-origin-embedder-policy/#integration-html
+ // This is for dedicated workers.
+ // TODO(crbug.com/1064920): Remove this once PlzDedicatedWorker ships.
+ const RejectCoepUnsafeNone reject_coep_unsafe_none_ =
+ RejectCoepUnsafeNone(false);
};
} // namespace blink
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 db355819f3d..58cc557ec78 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
@@ -28,18 +28,17 @@ class SourceKeyedCachedMetadataHandler::SingleKeyHandler final
void SetCachedMetadata(uint32_t data_type_id,
const uint8_t* data,
- size_t size,
- CacheType cache_type) override {
+ size_t size) override {
DCHECK(!parent_->cached_metadata_map_.Contains(key_));
parent_->cached_metadata_map_.insert(
key_, CachedMetadata::Create(data_type_id, data, size));
- if (cache_type == CachedMetadataHandler::kSendToPlatform)
+ if (!disable_send_to_platform_for_testing_)
parent_->SendToPlatform();
}
- void ClearCachedMetadata(CacheType cache_type) override {
+ void ClearCachedMetadata(ClearCacheType cache_type) override {
parent_->cached_metadata_map_.erase(key_);
- if (cache_type == CachedMetadataHandler::kSendToPlatform)
+ if (cache_type == CachedMetadataHandler::kClearPersistentStorage)
parent_->SendToPlatform();
}
@@ -104,9 +103,9 @@ SingleCachedMetadataHandler* SourceKeyedCachedMetadataHandler::HandlerForSource(
}
void SourceKeyedCachedMetadataHandler::ClearCachedMetadata(
- CachedMetadataHandler::CacheType cache_type) {
+ CachedMetadataHandler::ClearCacheType cache_type) {
cached_metadata_map_.clear();
- if (cache_type == CachedMetadataHandler::kSendToPlatform)
+ if (cache_type == CachedMetadataHandler::kClearPersistentStorage)
SendToPlatform();
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler.h b/chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler.h
index 045a52d8670..4460985757c 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler.h
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler.h
@@ -32,7 +32,7 @@ class PLATFORM_EXPORT SourceKeyedCachedMetadataHandler final
SingleCachedMetadataHandler* HandlerForSource(const String& source);
void ClearCachedMetadata(
- CachedMetadataHandler::CacheType cache_type) override;
+ CachedMetadataHandler::ClearCacheType cache_type) override;
String Encoding() const override;
bool IsServedFromCacheStorage() const override {
return sender_->IsServedFromCacheStorage();
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler_test.cc
index 287d8ec84cf..eec248b7b95 100644
--- a/chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler_test.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler_test.cc
@@ -236,7 +236,7 @@ TEST(SourceKeyedCachedMetadataHandlerTest, Serialize_EmptyClearDoesSend) {
WTF::TextEncoding(), std::make_unique<MockCachedMetadataSender>(url));
// Clear and send to the platform
- handler->ClearCachedMetadata(CachedMetadataHandler::kSendToPlatform);
+ handler->ClearCachedMetadata(CachedMetadataHandler::kClearPersistentStorage);
// Load from platform
Vector<CacheMetadataEntry> cache_metadatas =
@@ -293,8 +293,8 @@ TEST(SourceKeyedCachedMetadataHandlerTest, Serialize_SetWithNoSendDoesNotSend) {
handler->HandlerForSource(source2);
Vector<uint8_t> data1 = {1, 2, 3};
- source1_handler->SetCachedMetadata(0xbeef, data1.data(), data1.size(),
- CachedMetadataHandler::kCacheLocally);
+ source1_handler->DisableSendToPlatformForTesting();
+ source1_handler->SetCachedMetadata(0xbeef, data1.data(), data1.size());
Vector<uint8_t> data2 = {3, 4, 5, 6};
source2_handler->SetCachedMetadata(0x5eed, data2.data(), data2.size());
@@ -320,8 +320,9 @@ TEST(SourceKeyedCachedMetadataHandlerTest,
WTF::TextEncoding(),
std::make_unique<MockCachedMetadataSender>(url));
- // Clear and send to the platform
- handler->ClearCachedMetadata(CachedMetadataHandler::kSendToPlatform);
+ // Clear and persist in the platform.
+ handler->ClearCachedMetadata(
+ CachedMetadataHandler::kClearPersistentStorage);
}
// Reload from platform
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 c20cf6b3f02..bd1ead40055 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(blink::Visitor* visitor) {
+void StaleRevalidationResourceClient::Trace(Visitor* visitor) {
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 6ef734efb47..b1b9a3eb226 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(blink::Visitor* visitor) override;
+ void Trace(Visitor* visitor) 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
new file mode 100644
index 00000000000..6654f8e72d5
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/trust_token_params_conversion.cc
@@ -0,0 +1,33 @@
+// 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/trust_token_params_conversion.h"
+#include "services/network/public/cpp/optional_trust_token_params.h"
+#include "services/network/public/mojom/trust_tokens.mojom-blink.h"
+
+namespace blink {
+
+network::OptionalTrustTokenParams ConvertTrustTokenParams(
+ const base::Optional<network::mojom::blink::TrustTokenParams>& maybe_in) {
+ if (!maybe_in)
+ return base::nullopt;
+ const network::mojom::blink::TrustTokenParams& in = *maybe_in;
+
+ network::mojom::TrustTokenParamsPtr out =
+ network::mojom::TrustTokenParams::New();
+ out->type = in.type;
+ out->refresh_policy = in.refresh_policy;
+ out->sign_request_data = in.sign_request_data;
+ out->include_timestamp_header = in.include_timestamp_header;
+ // Optional value:
+ if (in.issuer)
+ out->issuer = in.issuer->ToUrlOrigin();
+ for (const String& additional_header : in.additional_signed_headers) {
+ out->additional_signed_headers.push_back(additional_header.Latin1());
+ }
+
+ return network::OptionalTrustTokenParams(std::move(out));
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/trust_token_params_conversion.h b/chromium/third_party/blink/renderer/platform/loader/fetch/trust_token_params_conversion.h
new file mode 100644
index 00000000000..9ba5fe77806
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/trust_token_params_conversion.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_PLATFORM_LOADER_FETCH_TRUST_TOKEN_PARAMS_CONVERSION_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_TRUST_TOKEN_PARAMS_CONVERSION_H_
+
+#include "base/optional.h"
+#include "services/network/public/cpp/optional_trust_token_params.h"
+#include "third_party/blink/public/platform/web_common.h"
+
+namespace network {
+namespace mojom {
+namespace blink {
+class TrustTokenParams;
+
+} // namespace blink
+} // namespace mojom
+} // namespace network
+
+namespace blink {
+
+// Converts a mojom::blink TrustTokenParams object to its non-Blink counterpart
+// by directly copying all fields, converting types where necessary.
+network::OptionalTrustTokenParams ConvertTrustTokenParams(
+ const base::Optional<network::mojom::blink::TrustTokenParams>& maybe_in);
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_TRUST_TOKEN_PARAMS_CONVERSION_H_
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
new file mode 100644
index 00000000000..e3fe5379677
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc
@@ -0,0 +1,353 @@
+// 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/url_loader/request_conversion.h"
+
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "mojo/public/cpp/system/data_pipe.h"
+#include "net/base/request_priority.h"
+#include "net/http/http_request_headers.h"
+#include "net/http/http_util.h"
+#include "services/network/public/cpp/constants.h"
+#include "services/network/public/cpp/optional_trust_token_params.h"
+#include "services/network/public/cpp/resource_request.h"
+#include "services/network/public/cpp/resource_request_body.h"
+#include "services/network/public/mojom/data_pipe_getter.mojom-blink.h"
+#include "services/network/public/mojom/data_pipe_getter.mojom.h"
+#include "services/network/public/mojom/trust_tokens.mojom-blink.h"
+#include "services/network/public/mojom/trust_tokens.mojom.h"
+#include "third_party/blink/public/mojom/blob/blob.mojom.h"
+#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-shared.h"
+#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h"
+#include "third_party/blink/public/platform/file_path_conversion.h"
+#include "third_party/blink/public/platform/url_conversion.h"
+#include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/renderer/platform/blob/blob_data.h"
+#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/wrapped_data_pipe_getter.h"
+
+namespace blink {
+
+namespace {
+
+constexpr char kStylesheetAcceptHeader[] = "text/css,*/*;q=0.1";
+constexpr char kImageAcceptHeader[] = "image/webp,image/apng,image/*,*/*;q=0.8";
+
+// TODO(yhirano): Unify these with variables in
+// content/public/common/content_constants.h.
+constexpr char kCorsExemptPurposeHeaderName[] = "Purpose";
+constexpr char kCorsExemptRequestedWithHeaderName[] = "X-Requested-With";
+
+// This is complementary to ConvertNetPriorityToWebKitPriority, defined in
+// service_worker_context_client.cc.
+net::RequestPriority ConvertWebKitPriorityToNetPriority(
+ WebURLRequest::Priority priority) {
+ switch (priority) {
+ case WebURLRequest::Priority::kVeryHigh:
+ return net::HIGHEST;
+
+ case WebURLRequest::Priority::kHigh:
+ return net::MEDIUM;
+
+ case WebURLRequest::Priority::kMedium:
+ return net::LOW;
+
+ case WebURLRequest::Priority::kLow:
+ return net::LOWEST;
+
+ case WebURLRequest::Priority::kVeryLow:
+ return net::IDLE;
+
+ case WebURLRequest::Priority::kUnresolved:
+ default:
+ NOTREACHED();
+ return net::LOW;
+ }
+}
+
+// TODO(yhirano) Dedupe this and the same-name function in
+// web_url_request_util.cc.
+std::string TrimLWSAndCRLF(const base::StringPiece& input) {
+ base::StringPiece string = net::HttpUtil::TrimLWS(input);
+ const char* begin = string.data();
+ const char* end = string.data() + string.size();
+ while (begin < end && (end[-1] == '\r' || end[-1] == '\n'))
+ --end;
+ return std::string(base::StringPiece(begin, end - begin));
+}
+
+mojom::ResourceType RequestContextToResourceType(
+ mojom::RequestContextType request_context) {
+ switch (request_context) {
+ // CSP report
+ case mojom::RequestContextType::CSP_REPORT:
+ return mojom::ResourceType::kCspReport;
+
+ // Favicon
+ case mojom::RequestContextType::FAVICON:
+ return mojom::ResourceType::kFavicon;
+
+ // Font
+ case mojom::RequestContextType::FONT:
+ return mojom::ResourceType::kFontResource;
+
+ // Image
+ case mojom::RequestContextType::IMAGE:
+ case mojom::RequestContextType::IMAGE_SET:
+ return mojom::ResourceType::kImage;
+
+ // Media
+ case mojom::RequestContextType::AUDIO:
+ case mojom::RequestContextType::VIDEO:
+ return mojom::ResourceType::kMedia;
+
+ // Object
+ case mojom::RequestContextType::EMBED:
+ case mojom::RequestContextType::OBJECT:
+ return mojom::ResourceType::kObject;
+
+ // Ping
+ case mojom::RequestContextType::BEACON:
+ case mojom::RequestContextType::PING:
+ return mojom::ResourceType::kPing;
+
+ // Subresource of plugins
+ case mojom::RequestContextType::PLUGIN:
+ return mojom::ResourceType::kPluginResource;
+
+ // Prefetch
+ case mojom::RequestContextType::PREFETCH:
+ return mojom::ResourceType::kPrefetch;
+
+ // Script
+ case mojom::RequestContextType::IMPORT:
+ case mojom::RequestContextType::SCRIPT:
+ return mojom::ResourceType::kScript;
+
+ // Style
+ case mojom::RequestContextType::XSLT:
+ case mojom::RequestContextType::STYLE:
+ return mojom::ResourceType::kStylesheet;
+
+ // Subresource
+ case mojom::RequestContextType::DOWNLOAD:
+ case mojom::RequestContextType::MANIFEST:
+ case mojom::RequestContextType::SUBRESOURCE:
+ return mojom::ResourceType::kSubResource;
+
+ // TextTrack
+ case mojom::RequestContextType::TRACK:
+ return mojom::ResourceType::kMedia;
+
+ // Workers
+ case mojom::RequestContextType::SERVICE_WORKER:
+ return mojom::ResourceType::kServiceWorker;
+ case mojom::RequestContextType::SHARED_WORKER:
+ return mojom::ResourceType::kSharedWorker;
+ case mojom::RequestContextType::WORKER:
+ return mojom::ResourceType::kWorker;
+
+ // Unspecified
+ case mojom::RequestContextType::INTERNAL:
+ case mojom::RequestContextType::UNSPECIFIED:
+ return mojom::ResourceType::kSubResource;
+
+ // XHR
+ case mojom::RequestContextType::EVENT_SOURCE:
+ case mojom::RequestContextType::FETCH:
+ case mojom::RequestContextType::XML_HTTP_REQUEST:
+ return mojom::ResourceType::kXhr;
+
+ // Navigation requests should not go through WebURLLoader.
+ case mojom::RequestContextType::FORM:
+ case mojom::RequestContextType::HYPERLINK:
+ case mojom::RequestContextType::LOCATION:
+ case mojom::RequestContextType::FRAME:
+ case mojom::RequestContextType::IFRAME:
+ NOTREACHED();
+ return mojom::ResourceType::kSubResource;
+
+ default:
+ NOTREACHED();
+ return mojom::ResourceType::kSubResource;
+ }
+}
+
+} // namespace
+
+void PopulateResourceRequestBody(const EncodedFormData& src,
+ network::ResourceRequestBody* dest) {
+ for (const auto& element : src.Elements()) {
+ switch (element.type_) {
+ case FormDataElement::kData:
+ dest->AppendBytes(element.data_.data(), element.data_.size());
+ break;
+ case FormDataElement::kEncodedFile:
+ if (element.file_length_ == -1) {
+ dest->AppendFileRange(
+ WebStringToFilePath(element.filename_), 0,
+ std::numeric_limits<uint64_t>::max(),
+ element.expected_file_modification_time_.value_or(base::Time()));
+ } else {
+ dest->AppendFileRange(
+ WebStringToFilePath(element.filename_),
+ static_cast<uint64_t>(element.file_start_),
+ static_cast<uint64_t>(element.file_length_),
+ element.expected_file_modification_time_.value_or(base::Time()));
+ }
+ break;
+ case FormDataElement::kEncodedBlob: {
+ DCHECK(element.optional_blob_data_handle_);
+ mojo::Remote<mojom::Blob> blob_remote(mojo::PendingRemote<mojom::Blob>(
+ element.optional_blob_data_handle_->CloneBlobRemote().PassPipe(),
+ mojom::Blob::Version_));
+ mojo::PendingRemote<network::mojom::DataPipeGetter>
+ data_pipe_getter_remote;
+ blob_remote->AsDataPipeGetter(
+ data_pipe_getter_remote.InitWithNewPipeAndPassReceiver());
+ dest->AppendDataPipe(std::move(data_pipe_getter_remote));
+ break;
+ }
+ case FormDataElement::kDataPipe: {
+ // Convert network::mojom::blink::DataPipeGetter to
+ // network::mojom::DataPipeGetter through a raw message pipe.
+ mojo::PendingRemote<network::mojom::blink::DataPipeGetter>
+ pending_data_pipe_getter;
+ element.data_pipe_getter_->GetDataPipeGetter()->Clone(
+ pending_data_pipe_getter.InitWithNewPipeAndPassReceiver());
+ dest->AppendDataPipe(
+ mojo::PendingRemote<network::mojom::DataPipeGetter>(
+ pending_data_pipe_getter.PassPipe(), 0u));
+ break;
+ }
+ }
+ }
+}
+
+void PopulateResourceRequest(const ResourceRequestHead& src,
+ ResourceRequestBody src_body,
+ network::ResourceRequest* dest) {
+ dest->method = src.HttpMethod().Latin1();
+ dest->url = src.Url();
+ dest->site_for_cookies = src.SiteForCookies();
+ dest->upgrade_if_insecure = src.UpgradeIfInsecure();
+ dest->is_revalidating = src.IsRevalidating();
+ if (src.RequestorOrigin()->ToString() == "null") {
+ // "file:" origin is treated like an opaque unique origin when
+ // allow-file-access-from-files is not specified. Such origin is not
+ // opaque (i.e., IsOpaque() returns false) but still serializes to
+ // "null".
+ dest->request_initiator = url::Origin();
+ } else {
+ dest->request_initiator = src.RequestorOrigin()->ToUrlOrigin();
+ }
+ if (src.IsolatedWorldOrigin()) {
+ dest->isolated_world_origin = src.IsolatedWorldOrigin()->ToUrlOrigin();
+ }
+ dest->referrer = WebStringToGURL(src.ReferrerString());
+
+ // "default" referrer policy has already been resolved.
+ DCHECK_NE(src.GetReferrerPolicy(), network::mojom::ReferrerPolicy::kDefault);
+ dest->referrer_policy =
+ network::ReferrerPolicyForUrlRequest(src.GetReferrerPolicy());
+
+ for (const auto& item : src.HttpHeaderFields()) {
+ const std::string name = item.key.Latin1();
+ const std::string value = TrimLWSAndCRLF(item.value.Latin1());
+ dest->headers.SetHeader(name, value);
+ }
+ // Set X-Requested-With header to cors_exempt_headers rather than headers to
+ // be exempted from CORS checks.
+ if (!src.GetRequestedWithHeader().IsEmpty()) {
+ dest->cors_exempt_headers.SetHeader(kCorsExemptRequestedWithHeaderName,
+ src.GetRequestedWithHeader().Utf8());
+ }
+ // Set Purpose header to cors_exempt_headers rather than headers to be
+ // exempted from CORS checks.
+ if (!src.GetPurposeHeader().IsEmpty()) {
+ dest->cors_exempt_headers.SetHeader(kCorsExemptPurposeHeaderName,
+ src.GetPurposeHeader().Utf8());
+ }
+
+ // TODO(yhirano): Remove this WrappedResourceRequest.
+ dest->load_flags = WrappedResourceRequest(ResourceRequest(src))
+ .GetLoadFlagsForWebUrlRequest();
+ dest->recursive_prefetch_token = src.RecursivePrefetchToken();
+ dest->priority = ConvertWebKitPriorityToNetPriority(src.Priority());
+ dest->should_reset_appcache = src.ShouldResetAppCache();
+ dest->is_external_request = src.IsExternalRequest();
+ dest->cors_preflight_policy = src.CorsPreflightPolicy();
+ dest->skip_service_worker = src.GetSkipServiceWorker();
+ dest->mode = src.GetMode();
+ dest->destination = src.GetRequestDestination();
+ dest->credentials_mode = src.GetCredentialsMode();
+ dest->redirect_mode = src.GetRedirectMode();
+ dest->fetch_integrity = src.GetFetchIntegrity().Utf8();
+
+ mojom::ResourceType resource_type =
+ RequestContextToResourceType(src.GetRequestContext());
+
+ // TODO(kinuko): Deprecate these.
+ dest->fetch_request_context_type = static_cast<int>(src.GetRequestContext());
+ dest->resource_type = static_cast<int>(resource_type);
+
+ if (resource_type == mojom::ResourceType::kXhr &&
+ (dest->url.has_username() || dest->url.has_password())) {
+ dest->do_not_prompt_for_login = true;
+ }
+ if (resource_type == mojom::ResourceType::kPrefetch ||
+ resource_type == mojom::ResourceType::kFavicon) {
+ dest->do_not_prompt_for_login = true;
+ }
+
+ dest->keepalive = src.GetKeepalive();
+ dest->has_user_gesture = src.HasUserGesture();
+ dest->enable_load_timing = true;
+ dest->enable_upload_progress = src.ReportUploadProgress();
+ dest->report_raw_headers = src.ReportRawHeaders();
+ // TODO(ryansturm): Remove dest->previews_state once it is no
+ // longer used in a network delegate. https://crbug.com/842233
+ dest->previews_state = static_cast<int>(src.GetPreviewsState());
+ dest->throttling_profile_id = src.GetDevToolsToken();
+ dest->trust_token_params = ConvertTrustTokenParams(src.TrustTokenParams());
+
+ if (base::UnguessableToken window_id = src.GetFetchWindowId())
+ dest->fetch_window_id = base::make_optional(window_id);
+
+ if (src.GetDevToolsId().has_value()) {
+ dest->devtools_request_id = src.GetDevToolsId().value().Ascii();
+ }
+
+ if (src.IsSignedExchangePrefetchCacheEnabled()) {
+ DCHECK_EQ(src.GetRequestContext(), mojom::RequestContextType::PREFETCH);
+ dest->is_signed_exchange_prefetch_cache_enabled = true;
+ }
+
+ if (const EncodedFormData* body = src_body.FormBody().get()) {
+ DCHECK_NE(dest->method, net::HttpRequestHeaders::kGetMethod);
+ DCHECK_NE(dest->method, net::HttpRequestHeaders::kHeadMethod);
+ dest->request_body = base::MakeRefCounted<network::ResourceRequestBody>();
+
+ PopulateResourceRequestBody(*body, dest->request_body.get());
+ }
+
+ if (resource_type == mojom::ResourceType::kStylesheet) {
+ dest->headers.SetHeader(net::HttpRequestHeaders::kAccept,
+ kStylesheetAcceptHeader);
+ } else if (resource_type == mojom::ResourceType::kImage ||
+ resource_type == mojom::ResourceType::kFavicon) {
+ dest->headers.SetHeader(net::HttpRequestHeaders::kAccept,
+ kImageAcceptHeader);
+ } else {
+ // Calling SetHeaderIfMissing() instead of SetHeader() because JS can
+ // manually set an accept header on an XHR.
+ dest->headers.SetHeaderIfMissing(net::HttpRequestHeaders::kAccept,
+ network::kDefaultAcceptHeaderValue);
+ }
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.h b/chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.h
new file mode 100644
index 00000000000..a94fba68d4c
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.h
@@ -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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_URL_LOADER_REQUEST_CONVERSION_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_URL_LOADER_REQUEST_CONVERSION_H_
+
+// This file consists of request conversion functions between blink and network.
+
+namespace network {
+class ResourceRequestBody;
+struct ResourceRequest;
+} // namespace network
+
+namespace blink {
+
+class ResourceRequestHead;
+class ResourceRequestBody;
+class EncodedFormData;
+
+void PopulateResourceRequestBody(const EncodedFormData& src,
+ network::ResourceRequestBody* dest);
+
+void PopulateResourceRequest(const ResourceRequestHead& src,
+ ResourceRequestBody src_body,
+ network::ResourceRequest* dest);
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_URL_LOADER_REQUEST_CONVERSION_H_
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 918a3528df8..92271f1c6ed 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
@@ -5,14 +5,13 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_WORKER_RESOURCE_TIMING_NOTIFIER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_WORKER_RESOURCE_TIMING_NOTIFIER_H_
+#include "third_party/blink/public/mojom/timing/resource_timing.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/timing/worker_timing_container.mojom-blink-forward.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
namespace blink {
-struct WebResourceTimingInfo;
-
// This class is used by WorkerFetchContext to add a resource timing to an
// appropriate Performance Timeline.
// https://w3c.github.io/performance-timeline/#performance-timeline
@@ -27,7 +26,7 @@ class WorkerResourceTimingNotifier
// Timeline which may be associated with a different thread from the current
// running thread.
virtual void AddResourceTiming(
- const WebResourceTimingInfo&,
+ mojom::blink::ResourceTimingInfoPtr,
const AtomicString& initiator_type,
mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
worker_timing_receiver) = 0;
diff --git a/chromium/third_party/blink/renderer/platform/loader/subresource_integrity_test.cc b/chromium/third_party/blink/renderer/platform/loader/subresource_integrity_test.cc
index 5b3753c2fdb..cf9e2d5fbf2 100644
--- a/chromium/third_party/blink/renderer/platform/loader/subresource_integrity_test.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/subresource_integrity_test.cc
@@ -220,18 +220,17 @@ class SubresourceIntegrityTest : public testing::Test {
const KURL& url,
network::mojom::RequestMode request_mode,
network::mojom::FetchResponseType response_type) {
- Resource* resource = RawResource::CreateForTest(
- url, SecurityOrigin::CreateUniqueOpaque(), ResourceType::kRaw);
-
ResourceRequest request;
request.SetUrl(url);
request.SetMode(request_mode);
+ request.SetRequestorOrigin(SecurityOrigin::CreateUniqueOpaque());
+ Resource* resource =
+ RawResource::CreateForTest(request, ResourceType::kRaw);
ResourceResponse response(url);
response.SetHttpStatusCode(200);
response.SetType(response_type);
- resource->SetResourceRequest(request);
resource->SetResponse(response);
return resource;
}
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 6a321b75317..5fd5c9b36ac 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(blink::Visitor* visitor) override {
+ void Trace(Visitor* visitor) override {
visitor->Trace(consumer_);
BytesConsumer::Client::Trace(visitor);
}
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 7f634061276..d98ded9ee9f 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
@@ -39,7 +39,7 @@ class MockFetchContext : public FetchContext {
const ResourceRequest&,
const KURL&,
const ResourceLoaderOptions&,
- SecurityViolationReportingPolicy,
+ ReportingDisposition,
ResourceRequest::RedirectStatus redirect_status) const override {
return base::nullopt;
}
@@ -47,7 +47,7 @@ class MockFetchContext : public FetchContext {
mojom::RequestContextType,
const KURL& url,
const ResourceLoaderOptions& options,
- SecurityViolationReportingPolicy reporting_policy,
+ ReportingDisposition reporting_disposition,
ResourceRequest::RedirectStatus redirect_status) const override {
return base::nullopt;
}
diff --git a/chromium/third_party/blink/renderer/platform/loader/testing/mock_resource.cc b/chromium/third_party/blink/renderer/platform/loader/testing/mock_resource.cc
index 197807baa5d..773060d3bd5 100644
--- a/chromium/third_party/blink/renderer/platform/loader/testing/mock_resource.cc
+++ b/chromium/third_party/blink/renderer/platform/loader/testing/mock_resource.cc
@@ -80,8 +80,8 @@ void MockCacheHandler::Set(const uint8_t* data, size_t size) {
}
void MockCacheHandler::ClearCachedMetadata(
- CachedMetadataHandler::CacheType cache_type) {
- if (cache_type == CachedMetadataHandler::kSendToPlatform) {
+ CachedMetadataHandler::ClearCacheType cache_type) {
+ if (cache_type == CachedMetadataHandler::kClearPersistentStorage) {
Send();
}
data_.reset();
diff --git a/chromium/third_party/blink/renderer/platform/loader/testing/mock_resource.h b/chromium/third_party/blink/renderer/platform/loader/testing/mock_resource.h
index 5c1e0690529..991860b1079 100644
--- a/chromium/third_party/blink/renderer/platform/loader/testing/mock_resource.h
+++ b/chromium/third_party/blink/renderer/platform/loader/testing/mock_resource.h
@@ -23,7 +23,7 @@ class MockCacheHandler : public CachedMetadataHandler {
MockCacheHandler(std::unique_ptr<CachedMetadataSender> send_callback);
void Set(const uint8_t* data, size_t);
- void ClearCachedMetadata(CachedMetadataHandler::CacheType) override;
+ void ClearCachedMetadata(CachedMetadataHandler::ClearCacheType) override;
void Send();
String Encoding() const override { return "mock encoding"; }
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 401bed1de75..d699ef377ea 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(blink::Visitor* visitor) {
+void ReplayingBytesConsumer::Trace(Visitor* visitor) {
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 e3dc0ae9af2..de29497afc4 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(blink::Visitor*) override;
+ void Trace(Visitor*) 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 723d4c721e0..9b222e3c600 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
@@ -6,6 +6,7 @@
#include "services/network/public/mojom/ip_address_space.mojom-blink.h"
#include "services/network/public/mojom/referrer_policy.mojom-blink.h"
+#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h"
#include "third_party/blink/renderer/platform/loader/allowed_by_nosniff.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h"
#include "third_party/blink/renderer/platform/loader/fetch/https_state.h"
@@ -29,7 +30,7 @@ TestResourceFetcherProperties::TestResourceFetcherProperties(
HttpsState::kNone,
AllowedByNosniff::MimeTypeCheck::kStrict,
network::mojom::IPAddressSpace::kPublic,
- kLeaveInsecureRequestsAlone,
+ mojom::blink::InsecureRequestPolicy::kLeaveInsecureRequestsAlone,
FetchClientSettingsObject::InsecureNavigationsSet())) {}
TestResourceFetcherProperties::TestResourceFetcherProperties(
diff --git a/chromium/third_party/blink/renderer/platform/media/web_audio_source_provider_client.h b/chromium/third_party/blink/renderer/platform/media/web_audio_source_provider_client.h
new file mode 100644
index 00000000000..748e189444e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/media/web_audio_source_provider_client.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2011, 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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.
+ */
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIA_WEB_AUDIO_SOURCE_PROVIDER_CLIENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIA_WEB_AUDIO_SOURCE_PROVIDER_CLIENT_H_
+
+namespace blink {
+
+class WebAudioSourceProviderClient {
+ public:
+ virtual void SetFormat(uint32_t number_of_channels, float sample_rate) = 0;
+
+ protected:
+ virtual ~WebAudioSourceProviderClient() = default;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIA_WEB_AUDIO_SOURCE_PROVIDER_CLIENT_H_
diff --git a/chromium/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc b/chromium/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc
index 979fb044f71..a38efb3e55b 100644
--- a/chromium/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl.cc
@@ -16,7 +16,7 @@
#include "media/base/audio_timestamp_helper.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/media_log.h"
-#include "third_party/blink/public/platform/web_audio_source_provider_client.h"
+#include "third_party/blink/renderer/platform/media/web_audio_source_provider_client.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
@@ -74,8 +74,34 @@ class WebAudioSourceProviderImpl::TeeFilter
int Render(base::TimeDelta delay,
base::TimeTicks delay_timestamp,
int prior_frames_skipped,
- media::AudioBus* dest) override;
- void OnRenderError() override;
+ media::AudioBus* audio_bus) override {
+ DCHECK(initialized());
+
+ const int num_rendered_frames = renderer_->Render(
+ delay, delay_timestamp, prior_frames_skipped, audio_bus);
+
+ // Avoid taking the copy lock for the vast majority of cases.
+ if (copy_required_) {
+ base::AutoLock auto_lock(copy_lock_);
+ if (!copy_audio_bus_callback_.is_null()) {
+ const int64_t frames_delayed =
+ media::AudioTimestampHelper::TimeToFrames(delay, sample_rate_);
+ std::unique_ptr<media::AudioBus> bus_copy =
+ media::AudioBus::Create(audio_bus->channels(), audio_bus->frames());
+ audio_bus->CopyTo(bus_copy.get());
+ copy_audio_bus_callback_.Run(std::move(bus_copy),
+ static_cast<uint32_t>(frames_delayed),
+ sample_rate_);
+ }
+ }
+
+ return num_rendered_frames;
+ }
+
+ void OnRenderError() override {
+ DCHECK(initialized());
+ renderer_->OnRenderError();
+ }
bool initialized() const { return !!renderer_; }
int channels() const { return channels_; }
@@ -134,7 +160,7 @@ void WebAudioSourceProviderImpl::SetClient(
// The client will now take control by calling provideInput() periodically.
client_ = client;
- set_format_cb_ = media::BindToCurrentLoop(WTF::Bind(
+ set_format_cb_ = media::BindToCurrentLoop(WTF::BindRepeating(
&WebAudioSourceProviderImpl::OnSetFormat, weak_factory_.GetWeakPtr()));
// If |tee_filter_| is Initialize()d - then run |set_format_cb_| to send
@@ -142,13 +168,17 @@ void WebAudioSourceProviderImpl::SetClient(
// called when Initialize() is called. Note: Always using |set_format_cb_|
// ensures we have the same locking order when calling into |client_|.
if (tee_filter_->initialized())
- std::move(set_format_cb_).Run();
+ set_format_cb_.Run();
return;
}
// Drop client, but normal playback can't be restored. This is okay, the only
// way to disconnect a client is internally at time of destruction.
client_ = nullptr;
+
+ // We need to invalidate WeakPtr references on the renderer thread.
+ set_format_cb_.Reset();
+ weak_factory_.InvalidateWeakPtrs();
}
void WebAudioSourceProviderImpl::ProvideInput(
@@ -196,7 +226,7 @@ void WebAudioSourceProviderImpl::Initialize(
sink_->Initialize(params, tee_filter_.get());
if (set_format_cb_)
- std::move(set_format_cb_).Run();
+ set_format_cb_.Run();
}
void WebAudioSourceProviderImpl::Start() {
@@ -310,37 +340,4 @@ void WebAudioSourceProviderImpl::OnSetFormat() {
client_->SetFormat(tee_filter_->channels(), tee_filter_->sample_rate());
}
-int WebAudioSourceProviderImpl::TeeFilter::Render(
- base::TimeDelta delay,
- base::TimeTicks delay_timestamp,
- int prior_frames_skipped,
- media::AudioBus* audio_bus) {
- DCHECK(initialized());
-
- const int num_rendered_frames = renderer_->Render(
- delay, delay_timestamp, prior_frames_skipped, audio_bus);
-
- // Avoid taking the copy lock for the vast majority of cases.
- if (copy_required_) {
- base::AutoLock auto_lock(copy_lock_);
- if (!copy_audio_bus_callback_.is_null()) {
- const int64_t frames_delayed =
- media::AudioTimestampHelper::TimeToFrames(delay, sample_rate_);
- std::unique_ptr<media::AudioBus> bus_copy =
- media::AudioBus::Create(audio_bus->channels(), audio_bus->frames());
- audio_bus->CopyTo(bus_copy.get());
- copy_audio_bus_callback_.Run(std::move(bus_copy),
- static_cast<uint32_t>(frames_delayed),
- sample_rate_);
- }
- }
-
- return num_rendered_frames;
-}
-
-void WebAudioSourceProviderImpl::TeeFilter::OnRenderError() {
- DCHECK(initialized());
- renderer_->OnRenderError();
-}
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl_test.cc b/chromium/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl_test.cc
index f45ebe3f666..1f0c69d7143 100644
--- a/chromium/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl_test.cc
+++ b/chromium/third_party/blink/renderer/platform/media/webaudiosourceprovider_impl_test.cc
@@ -14,8 +14,8 @@
#include "media/base/mock_audio_renderer_sink.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/web_audio_source_provider_client.h"
#include "third_party/blink/public/platform/webaudiosourceprovider_impl.h"
+#include "third_party/blink/renderer/platform/media/web_audio_source_provider_client.h"
using ::testing::_;
@@ -253,7 +253,7 @@ TEST_F(WebAudioSourceProviderImplTest, ProvideInput) {
TEST_F(WebAudioSourceProviderImplTest, CopyAudioCB) {
testing::InSequence s;
wasp_impl_->Initialize(params_, &fake_callback_);
- wasp_impl_->SetCopyAudioCallback(base::Bind(
+ wasp_impl_->SetCopyAudioCallback(WTF::BindRepeating(
&WebAudioSourceProviderImplTest::OnAudioBus, base::Unretained(this)));
const auto bus1 = media::AudioBus::Create(params_);
@@ -267,4 +267,57 @@ TEST_F(WebAudioSourceProviderImplTest, CopyAudioCB) {
testing::Mock::VerifyAndClear(mock_sink_.get());
}
+TEST_F(WebAudioSourceProviderImplTest, MultipleInitializeWithSetClient) {
+ // setClient() with a nullptr client should do nothing if no client is set.
+ wasp_impl_->SetClient(nullptr);
+
+ // When Initialize() is called after setClient(), the params should propagate
+ // to the client via setFormat() during the call.
+ EXPECT_TRUE(wasp_impl_->IsOptimizedForHardwareParameters());
+ EXPECT_CALL(*this, SetFormat(params_.channels(), params_.sample_rate()));
+ wasp_impl_->Initialize(params_, &fake_callback_);
+ base::RunLoop().RunUntilIdle();
+
+ // If |mock_sink_| is not null, it should be stopped during setClient(this).
+ if (mock_sink_)
+ EXPECT_CALL(*mock_sink_.get(), Stop());
+
+ // setClient() with the same client should do nothing.
+ wasp_impl_->SetClient(this);
+ base::RunLoop().RunUntilIdle();
+
+ // Stop allows Initialize() to be called again.
+ wasp_impl_->Stop();
+
+ // It's possible that due to media change or just the change in the return
+ // value for IsOptimizedForHardwareParameters() that different params are
+ // given. Ensure this doesn't crash.
+ EXPECT_FALSE(wasp_impl_->IsOptimizedForHardwareParameters());
+ auto stream_params = media::AudioParameters(
+ media::AudioParameters::AUDIO_PCM_LINEAR, media::CHANNEL_LAYOUT_MONO,
+ kTestSampleRate * 2, 64);
+
+ EXPECT_CALL(*this,
+ SetFormat(stream_params.channels(), stream_params.sample_rate()));
+ wasp_impl_->Initialize(stream_params, &fake_callback_);
+ base::RunLoop().RunUntilIdle();
+
+ wasp_impl_->Start();
+ wasp_impl_->Play();
+
+ auto bus1 = media::AudioBus::Create(stream_params);
+ auto bus2 = media::AudioBus::Create(stream_params);
+
+ // Point the WebVector into memory owned by |bus1|.
+ WebVector<float*> audio_data(static_cast<size_t>(bus1->channels()));
+ for (size_t i = 0; i < audio_data.size(); ++i)
+ audio_data[i] = bus1->channel(static_cast<int>(i));
+
+ // Verify provideInput() doesn't return silence and doesn't crash.
+ bus1->channel(0)[0] = 1;
+ bus2->Zero();
+ wasp_impl_->ProvideInput(audio_data, params_.frames_per_buffer());
+ ASSERT_FALSE(CompareBusses(bus1.get(), bus2.get()));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/DEPS b/chromium/third_party/blink/renderer/platform/mediastream/DEPS
index 22e08dbd4d9..3298a7464b4 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/DEPS
+++ b/chromium/third_party/blink/renderer/platform/mediastream/DEPS
@@ -6,6 +6,7 @@ include_rules = [
"+third_party/blink/renderer/platform/mediastream",
# Dependencies.
+ "+base/atomicops.h",
"+media/base",
"+media/webrtc/audio_processor_controls.h",
"+third_party/blink/renderer/platform/audio",
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/aec_dump_agent_impl.cc b/chromium/third_party/blink/renderer/platform/mediastream/aec_dump_agent_impl.cc
index d0254a6fdb1..13ade0a00cf 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/aec_dump_agent_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/mediastream/aec_dump_agent_impl.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/platform/mediastream/aec_dump_agent_impl.h"
+#include "base/memory/ptr_util.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/platform/platform.h"
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/audio_service_audio_processor_proxy.cc b/chromium/third_party/blink/renderer/platform/mediastream/audio_service_audio_processor_proxy.cc
index 771bad73b57..aa8c19862a3 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/audio_service_audio_processor_proxy.cc
+++ b/chromium/third_party/blink/renderer/platform/mediastream/audio_service_audio_processor_proxy.cc
@@ -12,7 +12,6 @@
#include <utility>
#include <vector>
-#include "base/bind.h"
#include "base/single_thread_task_runner.h"
#include "base/task/post_task.h"
#include "base/timer/timer.h"
@@ -20,6 +19,7 @@
#include "third_party/blink/renderer/platform/mediastream/aec_dump_agent_impl.h"
#include "third_party/blink/renderer/platform/scheduler/public/worker_pool.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
@@ -62,8 +62,7 @@ void AudioServiceAudioProcessorProxy::OnStartDump(base::File dump_file) {
} else {
// Post the file close to avoid blocking the main thread.
worker_pool::PostTask(
- FROM_HERE,
- {base::ThreadPool(), base::TaskPriority::LOWEST, base::MayBlock()},
+ FROM_HERE, {base::TaskPriority::LOWEST, base::MayBlock()},
CrossThreadBindOnce([](base::File) {}, std::move(dump_file)));
}
}
@@ -119,16 +118,16 @@ void AudioServiceAudioProcessorProxy::RescheduleStatsUpdateTimer(
// Unretained is safe since |this| owns |stats_update_timer_|.
stats_update_timer_.Start(
FROM_HERE, new_interval,
- base::BindRepeating(&AudioServiceAudioProcessorProxy::RequestStats,
- base::Unretained(this)));
+ WTF::BindRepeating(&AudioServiceAudioProcessorProxy::RequestStats,
+ WTF::Unretained(this)));
}
void AudioServiceAudioProcessorProxy::RequestStats() {
DCHECK(main_thread_runner_->BelongsToCurrentThread());
if (processor_controls_) {
processor_controls_->GetStats(
- base::BindOnce(&AudioServiceAudioProcessorProxy::UpdateStats,
- weak_ptr_factory_.GetWeakPtr()));
+ WTF::Bind(&AudioServiceAudioProcessorProxy::UpdateStats,
+ weak_ptr_factory_.GetWeakPtr()));
}
}
diff --git a/chromium/third_party/blink/renderer/platform/exported/web_media_constraints.cc b/chromium/third_party/blink/renderer/platform/mediastream/media_constraints.cc
index dcad673ac67..e23da0b73e5 100644
--- a/chromium/third_party/blink/renderer/platform/exported/web_media_constraints.cc
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_constraints.cc
@@ -28,7 +28,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "third_party/blink/public/platform/web_media_constraints.h"
+#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
#include <math.h>
#include "base/memory/scoped_refptr.h"
@@ -76,66 +76,66 @@ const char kEchoCancellationTypeBrowser[] = "browser";
const char kEchoCancellationTypeAec3[] = "aec3";
const char kEchoCancellationTypeSystem[] = "system";
-class WebMediaConstraintsPrivate final
- : public ThreadSafeRefCounted<WebMediaConstraintsPrivate> {
+class MediaConstraintsPrivate final
+ : public ThreadSafeRefCounted<MediaConstraintsPrivate> {
public:
- static scoped_refptr<WebMediaConstraintsPrivate> Create();
- static scoped_refptr<WebMediaConstraintsPrivate> Create(
- const WebMediaTrackConstraintSet& basic,
- const WebVector<WebMediaTrackConstraintSet>& advanced);
+ static scoped_refptr<MediaConstraintsPrivate> Create();
+ static scoped_refptr<MediaConstraintsPrivate> Create(
+ const MediaTrackConstraintSetPlatform& basic,
+ const Vector<MediaTrackConstraintSetPlatform>& advanced);
bool IsEmpty() const;
- const WebMediaTrackConstraintSet& Basic() const;
- const WebVector<WebMediaTrackConstraintSet>& Advanced() const;
+ const MediaTrackConstraintSetPlatform& Basic() const;
+ const Vector<MediaTrackConstraintSetPlatform>& Advanced() const;
const String ToString() const;
private:
- WebMediaConstraintsPrivate(
- const WebMediaTrackConstraintSet& basic,
- const WebVector<WebMediaTrackConstraintSet>& advanced);
+ MediaConstraintsPrivate(
+ const MediaTrackConstraintSetPlatform& basic,
+ const Vector<MediaTrackConstraintSetPlatform>& advanced);
- WebMediaTrackConstraintSet basic_;
- WebVector<WebMediaTrackConstraintSet> advanced_;
+ MediaTrackConstraintSetPlatform basic_;
+ Vector<MediaTrackConstraintSetPlatform> advanced_;
};
-scoped_refptr<WebMediaConstraintsPrivate> WebMediaConstraintsPrivate::Create() {
- WebMediaTrackConstraintSet basic;
- WebVector<WebMediaTrackConstraintSet> advanced;
- return base::AdoptRef(new WebMediaConstraintsPrivate(basic, advanced));
+scoped_refptr<MediaConstraintsPrivate> MediaConstraintsPrivate::Create() {
+ MediaTrackConstraintSetPlatform basic;
+ Vector<MediaTrackConstraintSetPlatform> advanced;
+ return base::AdoptRef(new MediaConstraintsPrivate(basic, advanced));
}
-scoped_refptr<WebMediaConstraintsPrivate> WebMediaConstraintsPrivate::Create(
- const WebMediaTrackConstraintSet& basic,
- const WebVector<WebMediaTrackConstraintSet>& advanced) {
- return base::AdoptRef(new WebMediaConstraintsPrivate(basic, advanced));
+scoped_refptr<MediaConstraintsPrivate> MediaConstraintsPrivate::Create(
+ const MediaTrackConstraintSetPlatform& basic,
+ const Vector<MediaTrackConstraintSetPlatform>& advanced) {
+ return base::AdoptRef(new MediaConstraintsPrivate(basic, advanced));
}
-WebMediaConstraintsPrivate::WebMediaConstraintsPrivate(
- const WebMediaTrackConstraintSet& basic,
- const WebVector<WebMediaTrackConstraintSet>& advanced)
+MediaConstraintsPrivate::MediaConstraintsPrivate(
+ const MediaTrackConstraintSetPlatform& basic,
+ const Vector<MediaTrackConstraintSetPlatform>& advanced)
: basic_(basic), advanced_(advanced) {}
-bool WebMediaConstraintsPrivate::IsEmpty() const {
+bool MediaConstraintsPrivate::IsEmpty() const {
// TODO(hta): When generating advanced constraints, make sure no empty
// elements can be added to the m_advanced vector.
- return basic_.IsEmpty() && advanced_.empty();
+ return basic_.IsEmpty() && advanced_.IsEmpty();
}
-const WebMediaTrackConstraintSet& WebMediaConstraintsPrivate::Basic() const {
+const MediaTrackConstraintSetPlatform& MediaConstraintsPrivate::Basic() const {
return basic_;
}
-const WebVector<WebMediaTrackConstraintSet>&
-WebMediaConstraintsPrivate::Advanced() const {
+const Vector<MediaTrackConstraintSetPlatform>&
+MediaConstraintsPrivate::Advanced() const {
return advanced_;
}
-const String WebMediaConstraintsPrivate::ToString() const {
+const String MediaConstraintsPrivate::ToString() const {
StringBuilder builder;
if (!IsEmpty()) {
builder.Append('{');
builder.Append(Basic().ToString());
- if (!Advanced().empty()) {
+ if (!Advanced().IsEmpty()) {
if (builder.length() > 1)
builder.Append(", ");
builder.Append("advanced: [");
@@ -193,7 +193,7 @@ bool LongConstraint::IsEmpty() const {
return !has_min_ && !has_max_ && !has_exact_ && !has_ideal_;
}
-WebString LongConstraint::ToString() const {
+String LongConstraint::ToString() const {
StringBuilder builder;
builder.Append('{');
MaybeEmitNamedValue(builder, has_min_, "min", min_);
@@ -235,7 +235,7 @@ bool DoubleConstraint::IsEmpty() const {
return !has_min_ && !has_max_ && !has_exact_ && !has_ideal_;
}
-WebString DoubleConstraint::ToString() const {
+String DoubleConstraint::ToString() const {
StringBuilder builder;
builder.Append('{');
MaybeEmitNamedValue(builder, has_min_, "min", min_);
@@ -249,8 +249,8 @@ WebString DoubleConstraint::ToString() const {
StringConstraint::StringConstraint(const char* name)
: BaseConstraint(name), exact_(), ideal_() {}
-bool StringConstraint::Matches(WebString value) const {
- if (exact_.empty()) {
+bool StringConstraint::Matches(String value) const {
+ if (exact_.IsEmpty()) {
return true;
}
for (const auto& choice : exact_) {
@@ -262,21 +262,21 @@ bool StringConstraint::Matches(WebString value) const {
}
bool StringConstraint::IsEmpty() const {
- return exact_.empty() && ideal_.empty();
+ return exact_.IsEmpty() && ideal_.IsEmpty();
}
-const WebVector<WebString>& StringConstraint::Exact() const {
+const Vector<String>& StringConstraint::Exact() const {
return exact_;
}
-const WebVector<WebString>& StringConstraint::Ideal() const {
+const Vector<String>& StringConstraint::Ideal() const {
return ideal_;
}
-WebString StringConstraint::ToString() const {
+String StringConstraint::ToString() const {
StringBuilder builder;
builder.Append('{');
- if (!ideal_.empty()) {
+ if (!ideal_.IsEmpty()) {
builder.Append("ideal: [");
bool first = true;
for (const auto& iter : ideal_) {
@@ -289,7 +289,7 @@ WebString StringConstraint::ToString() const {
}
builder.Append(']');
}
- if (!exact_.empty()) {
+ if (!exact_.IsEmpty()) {
if (builder.length() > 1)
builder.Append(", ");
builder.Append("exact: [");
@@ -325,7 +325,7 @@ bool BooleanConstraint::IsEmpty() const {
return !has_ideal_ && !has_exact_;
}
-WebString BooleanConstraint::ToString() const {
+String BooleanConstraint::ToString() const {
StringBuilder builder;
builder.Append('{');
MaybeEmitNamedBoolean(builder, has_exact_, "exact", Exact());
@@ -334,7 +334,7 @@ WebString BooleanConstraint::ToString() const {
return builder.ToString();
}
-WebMediaTrackConstraintSet::WebMediaTrackConstraintSet()
+MediaTrackConstraintSetPlatform::MediaTrackConstraintSetPlatform()
: width("width"),
height("height"),
aspect_ratio("aspectRatio"),
@@ -389,64 +389,62 @@ WebMediaTrackConstraintSet::WebMediaTrackConstraintSet()
goog_payload_padding("googPayloadPadding"),
goog_latency_ms("latencyMs") {}
-std::vector<const BaseConstraint*> WebMediaTrackConstraintSet::AllConstraints()
+Vector<const BaseConstraint*> MediaTrackConstraintSetPlatform::AllConstraints()
const {
- const BaseConstraint* temp[] = {&width,
- &height,
- &aspect_ratio,
- &frame_rate,
- &facing_mode,
- &resize_mode,
- &volume,
- &sample_rate,
- &sample_size,
- &echo_cancellation,
- &echo_cancellation_type,
- &latency,
- &channel_count,
- &device_id,
- &group_id,
- &video_kind,
- &media_stream_source,
- &disable_local_echo,
- &render_to_associated_sink,
- &goog_echo_cancellation,
- &goog_experimental_echo_cancellation,
- &goog_auto_gain_control,
- &goog_experimental_auto_gain_control,
- &goog_noise_suppression,
- &goog_highpass_filter,
- &goog_experimental_noise_suppression,
- &goog_audio_mirroring,
- &goog_da_echo_cancellation,
- &goog_noise_reduction,
- &offer_to_receive_audio,
- &offer_to_receive_video,
- &voice_activity_detection,
- &ice_restart,
- &goog_use_rtp_mux,
- &enable_dtls_srtp,
- &enable_rtp_data_channels,
- &enable_dscp,
- &enable_i_pv6,
- &goog_enable_video_suspend_below_min_bitrate,
- &goog_num_unsignalled_recv_streams,
- &goog_combined_audio_video_bwe,
- &goog_screencast_min_bitrate,
- &goog_cpu_overuse_detection,
- &goog_cpu_underuse_threshold,
- &goog_cpu_overuse_threshold,
- &goog_cpu_underuse_encode_rsd_threshold,
- &goog_cpu_overuse_encode_rsd_threshold,
- &goog_cpu_overuse_encode_usage,
- &goog_high_start_bitrate,
- &goog_payload_padding,
- &goog_latency_ms};
- const int element_count = sizeof(temp) / sizeof(temp[0]);
- return std::vector<const BaseConstraint*>(&temp[0], &temp[element_count]);
-}
-
-bool WebMediaTrackConstraintSet::IsEmpty() const {
+ return {&width,
+ &height,
+ &aspect_ratio,
+ &frame_rate,
+ &facing_mode,
+ &resize_mode,
+ &volume,
+ &sample_rate,
+ &sample_size,
+ &echo_cancellation,
+ &echo_cancellation_type,
+ &latency,
+ &channel_count,
+ &device_id,
+ &group_id,
+ &video_kind,
+ &media_stream_source,
+ &disable_local_echo,
+ &render_to_associated_sink,
+ &goog_echo_cancellation,
+ &goog_experimental_echo_cancellation,
+ &goog_auto_gain_control,
+ &goog_experimental_auto_gain_control,
+ &goog_noise_suppression,
+ &goog_highpass_filter,
+ &goog_experimental_noise_suppression,
+ &goog_audio_mirroring,
+ &goog_da_echo_cancellation,
+ &goog_noise_reduction,
+ &offer_to_receive_audio,
+ &offer_to_receive_video,
+ &voice_activity_detection,
+ &ice_restart,
+ &goog_use_rtp_mux,
+ &enable_dtls_srtp,
+ &enable_rtp_data_channels,
+ &enable_dscp,
+ &enable_i_pv6,
+ &goog_enable_video_suspend_below_min_bitrate,
+ &goog_num_unsignalled_recv_streams,
+ &goog_combined_audio_video_bwe,
+ &goog_screencast_min_bitrate,
+ &goog_cpu_overuse_detection,
+ &goog_cpu_underuse_threshold,
+ &goog_cpu_overuse_threshold,
+ &goog_cpu_underuse_encode_rsd_threshold,
+ &goog_cpu_overuse_encode_rsd_threshold,
+ &goog_cpu_overuse_encode_usage,
+ &goog_high_start_bitrate,
+ &goog_payload_padding,
+ &goog_latency_ms};
+}
+
+bool MediaTrackConstraintSetPlatform::IsEmpty() const {
for (auto* const constraint : AllConstraints()) {
if (!constraint->IsEmpty())
return false;
@@ -454,9 +452,9 @@ bool WebMediaTrackConstraintSet::IsEmpty() const {
return true;
}
-bool WebMediaTrackConstraintSet::HasMandatoryOutsideSet(
- const std::vector<std::string>& good_names,
- std::string& found_name) const {
+bool MediaTrackConstraintSetPlatform::HasMandatoryOutsideSet(
+ const Vector<String>& good_names,
+ String& found_name) const {
for (auto* const constraint : AllConstraints()) {
if (constraint->HasMandatory()) {
if (std::find(good_names.begin(), good_names.end(),
@@ -469,12 +467,12 @@ bool WebMediaTrackConstraintSet::HasMandatoryOutsideSet(
return false;
}
-bool WebMediaTrackConstraintSet::HasMandatory() const {
- std::string dummy_string;
- return HasMandatoryOutsideSet(std::vector<std::string>(), dummy_string);
+bool MediaTrackConstraintSetPlatform::HasMandatory() const {
+ String dummy_string;
+ return HasMandatoryOutsideSet(Vector<String>(), dummy_string);
}
-bool WebMediaTrackConstraintSet::HasMin() const {
+bool MediaTrackConstraintSetPlatform::HasMin() const {
for (auto* const constraint : AllConstraints()) {
if (constraint->HasMin())
return true;
@@ -482,7 +480,7 @@ bool WebMediaTrackConstraintSet::HasMin() const {
return false;
}
-bool WebMediaTrackConstraintSet::HasExact() const {
+bool MediaTrackConstraintSetPlatform::HasExact() const {
for (auto* const constraint : AllConstraints()) {
if (constraint->HasExact())
return true;
@@ -490,7 +488,7 @@ bool WebMediaTrackConstraintSet::HasExact() const {
return false;
}
-WebString WebMediaTrackConstraintSet::ToString() const {
+String MediaTrackConstraintSetPlatform::ToString() const {
StringBuilder builder;
bool first = true;
for (auto* const constraint : AllConstraints()) {
@@ -506,46 +504,46 @@ WebString WebMediaTrackConstraintSet::ToString() const {
return builder.ToString();
}
-// WebMediaConstraints
+// MediaConstraints
-void WebMediaConstraints::Assign(const WebMediaConstraints& other) {
+void MediaConstraints::Assign(const MediaConstraints& other) {
private_ = other.private_;
}
-void WebMediaConstraints::Reset() {
+void MediaConstraints::Reset() {
private_.Reset();
}
-bool WebMediaConstraints::IsEmpty() const {
+bool MediaConstraints::IsEmpty() const {
return private_.IsNull() || private_->IsEmpty();
}
-void WebMediaConstraints::Initialize() {
+void MediaConstraints::Initialize() {
DCHECK(IsNull());
- private_ = WebMediaConstraintsPrivate::Create();
+ private_ = MediaConstraintsPrivate::Create();
}
-void WebMediaConstraints::Initialize(
- const WebMediaTrackConstraintSet& basic,
- const WebVector<WebMediaTrackConstraintSet>& advanced) {
+void MediaConstraints::Initialize(
+ const MediaTrackConstraintSetPlatform& basic,
+ const Vector<MediaTrackConstraintSetPlatform>& advanced) {
DCHECK(IsNull());
- private_ = WebMediaConstraintsPrivate::Create(basic, advanced);
+ private_ = MediaConstraintsPrivate::Create(basic, advanced);
}
-const WebMediaTrackConstraintSet& WebMediaConstraints::Basic() const {
+const MediaTrackConstraintSetPlatform& MediaConstraints::Basic() const {
DCHECK(!IsNull());
return private_->Basic();
}
-const WebVector<WebMediaTrackConstraintSet>& WebMediaConstraints::Advanced()
+const Vector<MediaTrackConstraintSetPlatform>& MediaConstraints::Advanced()
const {
DCHECK(!IsNull());
return private_->Advanced();
}
-const WebString WebMediaConstraints::ToString() const {
+const String MediaConstraints::ToString() const {
if (IsNull())
- return WebString("");
+ return String("");
return private_->ToString();
}
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/media_constraints.h b/chromium/third_party/blink/renderer/platform/mediastream/media_constraints.h
new file mode 100644
index 00000000000..ed536a694d6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_constraints.h
@@ -0,0 +1,326 @@
+/*
+ * 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.
+ */
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_MEDIA_CONSTRAINTS_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_MEDIA_CONSTRAINTS_H_
+
+#include "third_party/blink/public/platform/web_private_ptr.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace blink {
+
+// Possible values of the echo canceller type constraint.
+PLATFORM_EXPORT extern const char kEchoCancellationTypeBrowser[];
+PLATFORM_EXPORT extern const char kEchoCancellationTypeAec3[];
+PLATFORM_EXPORT extern const char kEchoCancellationTypeSystem[];
+
+class MediaConstraintsPrivate;
+
+class PLATFORM_EXPORT BaseConstraint {
+ public:
+ explicit BaseConstraint(const char* name);
+ virtual ~BaseConstraint();
+ virtual bool IsEmpty() const = 0;
+ bool HasMandatory() const;
+ virtual bool HasMin() const { return false; }
+ virtual bool HasMax() const { return false; }
+ virtual bool HasExact() const = 0;
+ const char* GetName() const { return name_; }
+ virtual String ToString() const = 0;
+
+ private:
+ const char* name_;
+};
+
+// Note this class refers to the "long" WebIDL definition which is
+// equivalent to int32_t.
+class PLATFORM_EXPORT LongConstraint : public BaseConstraint {
+ public:
+ explicit LongConstraint(const char* name);
+
+ void SetMin(int32_t value) {
+ min_ = value;
+ has_min_ = true;
+ }
+
+ void SetMax(int32_t value) {
+ max_ = value;
+ has_max_ = true;
+ }
+
+ void SetExact(int32_t value) {
+ exact_ = value;
+ has_exact_ = true;
+ }
+
+ void SetIdeal(int32_t value) {
+ ideal_ = value;
+ has_ideal_ = true;
+ }
+
+ bool Matches(int32_t value) const;
+ bool IsEmpty() const override;
+ bool HasMin() const override { return has_min_; }
+ bool HasMax() const override { return has_max_; }
+ bool HasExact() const override { return has_exact_; }
+ String ToString() const override;
+ int32_t Min() const { return min_; }
+ int32_t Max() const { return max_; }
+ int32_t Exact() const { return exact_; }
+ bool HasIdeal() const { return has_ideal_; }
+ int32_t Ideal() const { return ideal_; }
+
+ private:
+ int32_t min_;
+ int32_t max_;
+ int32_t exact_;
+ int32_t ideal_;
+ unsigned has_min_ : 1;
+ unsigned has_max_ : 1;
+ unsigned has_exact_ : 1;
+ unsigned has_ideal_ : 1;
+};
+
+class PLATFORM_EXPORT DoubleConstraint : public BaseConstraint {
+ public:
+ // Permit a certain leeway when comparing floats. The offset of 0.00001
+ // is chosen based on observed behavior of doubles formatted with
+ // rtc::ToString.
+ static const double kConstraintEpsilon;
+
+ explicit DoubleConstraint(const char* name);
+
+ void SetMin(double value) {
+ min_ = value;
+ has_min_ = true;
+ }
+
+ void SetMax(double value) {
+ max_ = value;
+ has_max_ = true;
+ }
+
+ void SetExact(double value) {
+ exact_ = value;
+ has_exact_ = true;
+ }
+
+ void SetIdeal(double value) {
+ ideal_ = value;
+ has_ideal_ = true;
+ }
+
+ bool Matches(double value) const;
+ bool IsEmpty() const override;
+ bool HasMin() const override { return has_min_; }
+ bool HasMax() const override { return has_max_; }
+ bool HasExact() const override { return has_exact_; }
+ String ToString() const override;
+ double Min() const { return min_; }
+ double Max() const { return max_; }
+ double Exact() const { return exact_; }
+ bool HasIdeal() const { return has_ideal_; }
+ double Ideal() const { return ideal_; }
+
+ private:
+ double min_;
+ double max_;
+ double exact_;
+ double ideal_;
+ unsigned has_min_ : 1;
+ unsigned has_max_ : 1;
+ unsigned has_exact_ : 1;
+ unsigned has_ideal_ : 1;
+};
+
+class PLATFORM_EXPORT StringConstraint : public BaseConstraint {
+ public:
+ // String-valued options don't have min or max, but can have multiple
+ // values for ideal and exact.
+ explicit StringConstraint(const char* name);
+
+ void SetExact(const String& exact) { exact_ = {exact}; }
+
+ void SetExact(const Vector<String>& exact) { exact_ = exact; }
+
+ void SetIdeal(const String& ideal) { ideal_ = {ideal}; }
+
+ void SetIdeal(const Vector<String>& ideal) { ideal_ = ideal; }
+
+ bool Matches(String value) const;
+ bool IsEmpty() const override;
+ bool HasExact() const override { return !exact_.IsEmpty(); }
+ String ToString() const override;
+ bool HasIdeal() const { return !ideal_.IsEmpty(); }
+ const Vector<String>& Exact() const;
+ const Vector<String>& Ideal() const;
+
+ private:
+ Vector<String> exact_;
+ Vector<String> ideal_;
+};
+
+class PLATFORM_EXPORT BooleanConstraint : public BaseConstraint {
+ public:
+ explicit BooleanConstraint(const char* name);
+
+ bool Exact() const { return exact_; }
+ bool Ideal() const { return ideal_; }
+ void SetIdeal(bool value) {
+ ideal_ = value;
+ has_ideal_ = true;
+ }
+
+ void SetExact(bool value) {
+ exact_ = value;
+ has_exact_ = true;
+ }
+
+ bool Matches(bool value) const;
+ bool IsEmpty() const override;
+ bool HasExact() const override { return has_exact_; }
+ String ToString() const override;
+ bool HasIdeal() const { return has_ideal_; }
+
+ private:
+ unsigned ideal_ : 1;
+ unsigned exact_ : 1;
+ unsigned has_ideal_ : 1;
+ unsigned has_exact_ : 1;
+};
+
+struct MediaTrackConstraintSetPlatform {
+ public:
+ PLATFORM_EXPORT MediaTrackConstraintSetPlatform();
+
+ LongConstraint width;
+ LongConstraint height;
+ DoubleConstraint aspect_ratio;
+ DoubleConstraint frame_rate;
+ StringConstraint facing_mode;
+ StringConstraint resize_mode;
+ DoubleConstraint volume;
+ LongConstraint sample_rate;
+ LongConstraint sample_size;
+ BooleanConstraint echo_cancellation;
+ StringConstraint echo_cancellation_type;
+ DoubleConstraint latency;
+ LongConstraint channel_count;
+ StringConstraint device_id;
+ BooleanConstraint disable_local_echo;
+ StringConstraint group_id;
+ // https://w3c.github.io/mediacapture-depth/#mediatrackconstraints
+ StringConstraint video_kind;
+ // Constraints not exposed in Blink at the moment, only through
+ // the legacy name interface.
+ StringConstraint media_stream_source; // tab, screen, desktop, system
+ BooleanConstraint render_to_associated_sink;
+ BooleanConstraint goog_echo_cancellation;
+ BooleanConstraint goog_experimental_echo_cancellation;
+ BooleanConstraint goog_auto_gain_control;
+ BooleanConstraint goog_experimental_auto_gain_control;
+ BooleanConstraint goog_noise_suppression;
+ BooleanConstraint goog_highpass_filter;
+ BooleanConstraint goog_experimental_noise_suppression;
+ BooleanConstraint goog_audio_mirroring;
+ BooleanConstraint goog_da_echo_cancellation;
+ BooleanConstraint goog_noise_reduction;
+ LongConstraint offer_to_receive_audio;
+ LongConstraint offer_to_receive_video;
+ BooleanConstraint voice_activity_detection;
+ BooleanConstraint ice_restart;
+ BooleanConstraint goog_use_rtp_mux;
+ BooleanConstraint enable_dtls_srtp;
+ BooleanConstraint enable_rtp_data_channels;
+ BooleanConstraint enable_dscp;
+ BooleanConstraint enable_i_pv6;
+ BooleanConstraint goog_enable_video_suspend_below_min_bitrate;
+ LongConstraint goog_num_unsignalled_recv_streams;
+ BooleanConstraint goog_combined_audio_video_bwe;
+ LongConstraint goog_screencast_min_bitrate;
+ BooleanConstraint goog_cpu_overuse_detection;
+ LongConstraint goog_cpu_underuse_threshold;
+ LongConstraint goog_cpu_overuse_threshold;
+ LongConstraint goog_cpu_underuse_encode_rsd_threshold;
+ LongConstraint goog_cpu_overuse_encode_rsd_threshold;
+ BooleanConstraint goog_cpu_overuse_encode_usage;
+ LongConstraint goog_high_start_bitrate;
+ BooleanConstraint goog_payload_padding;
+ LongConstraint goog_latency_ms;
+
+ PLATFORM_EXPORT bool IsEmpty() const;
+ PLATFORM_EXPORT bool HasMandatory() const;
+ PLATFORM_EXPORT bool HasMandatoryOutsideSet(const Vector<String>&,
+ String&) const;
+ PLATFORM_EXPORT bool HasMin() const;
+ PLATFORM_EXPORT bool HasExact() const;
+ PLATFORM_EXPORT String ToString() const;
+
+ private:
+ Vector<const BaseConstraint*> AllConstraints() const;
+};
+
+class MediaConstraints {
+ public:
+ MediaConstraints() = default;
+ MediaConstraints(const MediaConstraints& other) { Assign(other); }
+ ~MediaConstraints() { Reset(); }
+
+ MediaConstraints& operator=(const MediaConstraints& other) {
+ Assign(other);
+ return *this;
+ }
+
+ PLATFORM_EXPORT void Assign(const MediaConstraints&);
+
+ PLATFORM_EXPORT void Reset();
+ bool IsNull() const { return private_.IsNull(); }
+ PLATFORM_EXPORT bool IsEmpty() const;
+
+ PLATFORM_EXPORT void Initialize();
+ PLATFORM_EXPORT void Initialize(
+ const MediaTrackConstraintSetPlatform& basic,
+ const Vector<MediaTrackConstraintSetPlatform>& advanced);
+
+ PLATFORM_EXPORT const MediaTrackConstraintSetPlatform& Basic() const;
+ PLATFORM_EXPORT const Vector<MediaTrackConstraintSetPlatform>& Advanced()
+ const;
+
+ PLATFORM_EXPORT const String ToString() const;
+
+ private:
+ WebPrivatePtr<MediaConstraintsPrivate> private_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_MEDIA_CONSTRAINTS_H_
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_deliverer.h b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_deliverer.h
new file mode 100644
index 00000000000..9ff7615bb73
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_deliverer.h
@@ -0,0 +1,158 @@
+// 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_PLATFORM_MEDIASTREAM_MEDIA_STREAM_AUDIO_DELIVERER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_MEDIA_STREAM_AUDIO_DELIVERER_H_
+
+#include <algorithm>
+
+#include "base/synchronization/lock.h"
+#include "base/threading/thread_checker.h"
+#include "base/trace_event/trace_event.h"
+#include "media/base/audio_parameters.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace blink {
+
+// Template containing functionality common to both MediaStreamAudioSource and
+// MediaStreamAudioTrack. This is used for managing the connections between
+// objects through which audio data flows, and doing so in a thread-safe manner.
+//
+// The Consumer parameter of the template is the type of the objects to which
+// audio data is delivered: MediaStreamAudioTrack or MediaStreamAudioSink. It's
+// assumed the Consumer class defines methods named OnSetFormat() and OnData()
+// that have the same signature as the ones defined in this template.
+// MediaStreamAudioDeliverer will always guarantee the Consumer's OnSetFormat()
+// and OnData() methods are called sequentially.
+template <typename Consumer>
+class MediaStreamAudioDeliverer {
+ public:
+ MediaStreamAudioDeliverer() {}
+ ~MediaStreamAudioDeliverer() {}
+
+ // Returns the current audio parameters. These will be invalid before the
+ // first call to OnSetFormat(). This method is thread-safe.
+ media::AudioParameters GetAudioParameters() const {
+ base::AutoLock auto_lock(params_lock_);
+ return params_;
+ }
+
+ // Begin delivering audio to |consumer|. The caller must guarantee |consumer|
+ // is not destroyed until after calling RemoveConsumer(consumer). This method
+ // must be called on the main thread.
+ void AddConsumer(Consumer* consumer) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK(consumer);
+ base::AutoLock auto_lock(consumers_lock_);
+ DCHECK(!base::Contains(consumers_, consumer));
+ DCHECK(!base::Contains(pending_consumers_, consumer));
+ pending_consumers_.push_back(consumer);
+ }
+
+ // Stop delivering audio to |consumer|. Returns true if |consumer| was the
+ // last consumer removed, false otherwise. When this method returns, no
+ // further calls will be made to OnSetFormat() or OnData() on any thread.
+ // This method must be called on the main thread.
+ bool RemoveConsumer(Consumer* consumer) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ base::AutoLock auto_lock(consumers_lock_);
+ const bool had_consumers =
+ !consumers_.IsEmpty() || !pending_consumers_.IsEmpty();
+ auto it = std::find(consumers_.begin(), consumers_.end(), consumer);
+ if (it != consumers_.end()) {
+ consumers_.erase(it);
+ } else {
+ it = std::find(pending_consumers_.begin(), pending_consumers_.end(),
+ consumer);
+ if (it != pending_consumers_.end())
+ pending_consumers_.erase(it);
+ }
+ return had_consumers && consumers_.IsEmpty() &&
+ pending_consumers_.IsEmpty();
+ }
+
+ // Returns the current list of connected Consumers. This is normally used to
+ // send a notification to all consumers. This method must be called on the
+ // main thread.
+ void GetConsumerList(Vector<Consumer*>* consumer_list) const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ base::AutoLock auto_lock(consumers_lock_);
+ *consumer_list = consumers_;
+ consumer_list->AppendRange(pending_consumers_.begin(),
+ pending_consumers_.end());
+ }
+
+ // Change the format of the audio passed in the next call to OnData(). This
+ // method may be called on any thread but, logically, should only be called
+ // between calls to OnData().
+ void OnSetFormat(const media::AudioParameters& params) {
+ DCHECK(params.IsValid());
+ base::AutoLock auto_lock(consumers_lock_);
+ {
+ base::AutoLock auto_params_lock(params_lock_);
+ if (params_.Equals(params))
+ return;
+ params_ = params;
+ }
+ pending_consumers_.AppendRange(consumers_.begin(), consumers_.end());
+ consumers_.clear();
+ }
+
+ // Deliver data to all consumers. This method may be called on any thread.
+ void OnData(const media::AudioBus& audio_bus,
+ base::TimeTicks reference_time) {
+ TRACE_EVENT1("audio", "MediaStreamAudioDeliverer::OnData",
+ "reference time (ms)",
+ (reference_time - base::TimeTicks()).InMillisecondsF());
+ base::AutoLock auto_lock(consumers_lock_);
+
+ // Call OnSetFormat() for all pending consumers and move them to the
+ // active-delivery list.
+ if (!pending_consumers_.IsEmpty()) {
+ const media::AudioParameters params = GetAudioParameters();
+ DCHECK(params.IsValid());
+ for (Consumer* consumer : pending_consumers_)
+ consumer->OnSetFormat(params);
+ consumers_.AppendRange(pending_consumers_.begin(),
+ pending_consumers_.end());
+ pending_consumers_.clear();
+ }
+
+ // Deliver the audio data to each consumer.
+ for (Consumer* consumer : consumers_)
+ consumer->OnData(audio_bus, reference_time);
+ }
+
+ private:
+ // In debug builds, check that all methods that could cause object graph or
+ // data flow changes are being called on the main thread.
+ THREAD_CHECKER(thread_checker_);
+
+ // Protects concurrent access to |pending_consumers_| and |consumers_|.
+ mutable base::Lock consumers_lock_;
+
+ // Any consumers needing a call to OnSetFormat(), to be notified of the
+ // changed audio format, are placed in this list. This includes consumers
+ // added via AddConsumer() that need to have an initial OnSetFormat() call
+ // before audio data is first delivered. Consumers are moved from this list to
+ // |consumers_| on the audio thread.
+ Vector<Consumer*> pending_consumers_;
+
+ // Consumers that are up to date on the current audio format and are receiving
+ // audio data are placed in this list.
+ Vector<Consumer*> consumers_;
+
+ // Protects concurrent access to |params_|.
+ mutable base::Lock params_lock_;
+
+ // Specifies the current format of the audio passing through this
+ // MediaStreamAudioDeliverer.
+ media::AudioParameters params_;
+
+ DISALLOW_COPY_AND_ASSIGN(MediaStreamAudioDeliverer);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_MEDIA_STREAM_AUDIO_DELIVERER_H_
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.h b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.h
index 923bc2a2a47..f25d1e2abbe 100644
--- a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.h
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.h
@@ -15,7 +15,7 @@
#include "media/base/audio_point.h"
#include "media/base/audio_processing.h"
#include "third_party/blink/public/common/mediastream/media_stream_request.h"
-#include "third_party/blink/public/platform/web_media_constraints.h"
+#include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/webrtc/api/media_stream_interface.h"
#include "third_party/webrtc/media/base/media_channel.h"
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 783587fdaee..4c60ce0cff0 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
@@ -6,17 +6,27 @@
#include "base/bind.h"
#include "base/single_thread_task_runner.h"
+#include "base/strings/stringprintf.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
-#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.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/public/platform/web_string.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"
#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
+namespace {
+
+void SendLogMessage(const std::string& message) {
+ blink::WebRtcLogMessage("MSAS::" + message);
+}
+
+} // namespace
+
const int kMaxAudioLatencyMs = 5000;
static_assert(std::numeric_limits<int>::max() / media::limits::kMaxSampleRate >
kMaxAudioLatencyMs,
@@ -45,8 +55,9 @@ MediaStreamAudioSource::MediaStreamAudioSource(
disable_local_echo_(disable_local_echo),
is_stopped_(false),
task_runner_(std::move(task_runner)) {
- DVLOG(1) << "MediaStreamAudioSource@" << this << "::MediaStreamAudioSource("
- << (is_local_source_ ? "local" : "remote") << " source)";
+ SendLogMessage(base::StringPrintf(
+ "MediaStreamAudioSource([this=%p] {is_local_source=%s})", this,
+ (is_local_source ? "local" : "remote")));
}
MediaStreamAudioSource::MediaStreamAudioSource(
@@ -58,7 +69,8 @@ MediaStreamAudioSource::MediaStreamAudioSource(
MediaStreamAudioSource::~MediaStreamAudioSource() {
DCHECK(task_runner_->BelongsToCurrentThread());
- DVLOG(1) << "MediaStreamAudioSource@" << this << " is being destroyed.";
+ SendLogMessage(
+ base::StringPrintf("~MediaStreamAudioSource([this=%p])", this));
}
// static
@@ -74,6 +86,8 @@ bool MediaStreamAudioSource::ConnectToTrack(
const WebMediaStreamTrack& blink_track) {
DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK(!blink_track.IsNull());
+ SendLogMessage(base::StringPrintf("ConnectToTrack({track_id=%s})",
+ blink_track.Id().Utf8().c_str()));
// Sanity-check that there is not already a MediaStreamAudioTrack instance
// associated with |blink_track|.
@@ -167,6 +181,8 @@ void MediaStreamAudioSource::DoChangeSource(
std::unique_ptr<MediaStreamAudioTrack>
MediaStreamAudioSource::CreateMediaStreamAudioTrack(const std::string& id) {
DCHECK(task_runner_->BelongsToCurrentThread());
+ SendLogMessage(
+ base::StringPrintf("CreateMediaStreamAudioTrack({id=%s})", id.c_str()));
return std::unique_ptr<MediaStreamAudioTrack>(
new MediaStreamAudioTrack(is_local_source()));
}
@@ -190,9 +206,10 @@ void MediaStreamAudioSource::ChangeSourceImpl(
}
void MediaStreamAudioSource::SetFormat(const media::AudioParameters& params) {
- DVLOG(1) << "MediaStreamAudioSource@" << this << "::SetFormat("
- << params.AsHumanReadableString() << "), was previously set to {"
- << deliverer_.GetAudioParameters().AsHumanReadableString() << "}.";
+ SendLogMessage(base::StringPrintf(
+ "SetFormat([this=%p] {params=[%s]}, {old_params=[%s]})", this,
+ params.AsHumanReadableString().c_str(),
+ deliverer_.GetAudioParameters().AsHumanReadableString().c_str()));
deliverer_.OnSetFormat(params);
}
@@ -210,6 +227,7 @@ void MediaStreamAudioSource::DoStopSource() {
void MediaStreamAudioSource::StopAudioDeliveryTo(MediaStreamAudioTrack* track) {
DCHECK(task_runner_->BelongsToCurrentThread());
+ SendLogMessage(base::StringPrintf("StopAudioDeliveryTo([this=%p])", this));
const bool did_remove_last_track = deliverer_.RemoveConsumer(track);
DVLOG(1) << "Removed MediaStreamAudioTrack@" << track
@@ -222,8 +240,8 @@ void MediaStreamAudioSource::StopAudioDeliveryTo(MediaStreamAudioTrack* track) {
}
void MediaStreamAudioSource::StopSourceOnError(const std::string& why) {
- VLOG(1) << why;
-
+ SendLogMessage(base::StringPrintf("StopSourceOnError([this=%p] {why=%s})",
+ this, why.c_str()));
// Stop source when error occurs.
PostCrossThreadTask(
*task_runner_, FROM_HERE,
@@ -232,7 +250,8 @@ void MediaStreamAudioSource::StopSourceOnError(const std::string& why) {
}
void MediaStreamAudioSource::SetMutedState(bool muted_state) {
- DVLOG(3) << "MediaStreamAudioSource::SetMutedState state=" << muted_state;
+ SendLogMessage(base::StringPrintf("SetMutedState([this=%p] {muted_state=%s})",
+ this, (muted_state ? "true" : "false")));
PostCrossThreadTask(
*task_runner_, FROM_HERE,
WTF::CrossThreadBindOnce(&WebPlatformMediaStreamSource::SetSourceMuted,
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 24a2227e573..1dfc87329a2 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
@@ -12,10 +12,10 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "media/base/limits.h"
-#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_deliverer.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"
diff --git a/chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_track.cc b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_track.cc
index 1b6c6e1578f..24f05b8fc4e 100644
--- a/chromium/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_track.cc
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_track.cc
@@ -2,27 +2,37 @@
// 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/platform/modules/mediastream/media_stream_audio_track.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h"
#include <utility>
-#include <vector>
#include "base/logging.h"
+#include "base/strings/stringprintf.h"
#include "media/base/audio_bus.h"
#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"
namespace blink {
+namespace {
+
+void SendLogMessage(const std::string& message) {
+ blink::WebRtcLogMessage("MSAT::" + message);
+}
+
+} // namespace
+
MediaStreamAudioTrack::MediaStreamAudioTrack(bool is_local_track)
: WebPlatformMediaStreamTrack(is_local_track), is_enabled_(1) {
- DVLOG(1) << "MediaStreamAudioTrack@" << this << "::MediaStreamAudioTrack("
- << (is_local_track ? "local" : "remote") << " track)";
+ SendLogMessage(
+ base::StringPrintf("MediaStreamAudioTrack([this=%p] {is_local_track=%s})",
+ this, (is_local_track ? "true" : "false")));
}
MediaStreamAudioTrack::~MediaStreamAudioTrack() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DVLOG(1) << "MediaStreamAudioTrack@" << this << " is being destroyed.";
+ SendLogMessage(base::StringPrintf("~MediaStreamAudioTrack([this=%p])", this));
Stop();
}
@@ -38,9 +48,7 @@ MediaStreamAudioTrack* MediaStreamAudioTrack::From(
void MediaStreamAudioTrack::AddSink(WebMediaStreamAudioSink* sink) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- DVLOG(1) << "Adding WebMediaStreamAudioSink@" << sink
- << " to MediaStreamAudioTrack@" << this << '.';
+ SendLogMessage(base::StringPrintf("AddSink([this=%p])", this));
// If the track has already stopped, just notify the sink of this fact without
// adding it.
@@ -55,9 +63,8 @@ void MediaStreamAudioTrack::AddSink(WebMediaStreamAudioSink* sink) {
void MediaStreamAudioTrack::RemoveSink(WebMediaStreamAudioSink* sink) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ SendLogMessage(base::StringPrintf("RemoveSink([this=%p])", this));
deliverer_.RemoveConsumer(sink);
- DVLOG(1) << "Removed WebMediaStreamAudioSink@" << sink
- << " from MediaStreamAudioTrack@" << this << '.';
}
media::AudioParameters MediaStreamAudioTrack::GetOutputFormat() const {
@@ -66,15 +73,15 @@ media::AudioParameters MediaStreamAudioTrack::GetOutputFormat() const {
void MediaStreamAudioTrack::SetEnabled(bool enabled) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DVLOG(1) << "MediaStreamAudioTrack@" << this << "::SetEnabled("
- << (enabled ? 'Y' : 'N') << ')';
+ SendLogMessage(base::StringPrintf("SetEnabled([this=%p] {enabled=%s})", this,
+ (enabled ? "true" : "false")));
const bool previously_enabled =
!!base::subtle::NoBarrier_AtomicExchange(&is_enabled_, enabled ? 1 : 0);
if (enabled == previously_enabled)
return;
- std::vector<WebMediaStreamAudioSink*> sinks_to_notify;
+ Vector<WebMediaStreamAudioSink*> sinks_to_notify;
deliverer_.GetConsumerList(&sinks_to_notify);
for (WebMediaStreamAudioSink* sink : sinks_to_notify)
sink->OnEnabledChanged(enabled);
@@ -84,7 +91,7 @@ void MediaStreamAudioTrack::SetContentHint(
WebMediaStreamTrack::ContentHintType content_hint) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- std::vector<WebMediaStreamAudioSink*> sinks_to_notify;
+ Vector<WebMediaStreamAudioSink*> sinks_to_notify;
deliverer_.GetConsumerList(&sinks_to_notify);
for (WebMediaStreamAudioSink* sink : sinks_to_notify)
sink->OnContentHintChanged(content_hint);
@@ -98,18 +105,18 @@ void MediaStreamAudioTrack::Start(base::OnceClosure stop_callback) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(!stop_callback.is_null());
DCHECK(stop_callback_.is_null());
- DVLOG(1) << "Starting MediaStreamAudioTrack@" << this << '.';
+ SendLogMessage(base::StringPrintf("Start([this=%p])", this));
stop_callback_ = std::move(stop_callback);
}
void MediaStreamAudioTrack::StopAndNotify(base::OnceClosure callback) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DVLOG(1) << "Stopping MediaStreamAudioTrack@" << this << '.';
+ SendLogMessage(base::StringPrintf("StopAndNotify([this=%p])", this));
if (!stop_callback_.is_null())
std::move(stop_callback_).Run();
- std::vector<WebMediaStreamAudioSink*> sinks_to_end;
+ Vector<WebMediaStreamAudioSink*> sinks_to_end;
deliverer_.GetConsumerList(&sinks_to_end);
for (WebMediaStreamAudioSink* sink : sinks_to_end) {
deliverer_.RemoveConsumer(sink);
@@ -122,11 +129,22 @@ void MediaStreamAudioTrack::StopAndNotify(base::OnceClosure callback) {
}
void MediaStreamAudioTrack::OnSetFormat(const media::AudioParameters& params) {
+ SendLogMessage(base::StringPrintf("OnSetFormat([this=%p] {params: [%s]})",
+ this,
+ params.AsHumanReadableString().c_str()));
deliverer_.OnSetFormat(params);
}
void MediaStreamAudioTrack::OnData(const media::AudioBus& audio_bus,
base::TimeTicks reference_time) {
+ if (!received_audio_callback_) {
+ // Add log message with unique this pointer id to mark the audio track as
+ // alive at the first data callback.
+ SendLogMessage(base::StringPrintf(
+ "OnData([this=%p] => (audio track is alive))", this));
+ received_audio_callback_ = true;
+ }
+
// Note: Using NoBarrier_Load because the timing of when the audio thread sees
// a changed |is_enabled_| value can be relaxed.
const bool deliver_data = !!base::subtle::NoBarrier_Load(&is_enabled_);
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
new file mode 100644
index 00000000000..5981a2aa271
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h
@@ -0,0 +1,126 @@
+// 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_MEDIASTREAM_MEDIA_STREAM_AUDIO_TRACK_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_MEDIA_STREAM_AUDIO_TRACK_H_
+
+#include <memory>
+
+#include "base/atomicops.h"
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/synchronization/lock.h"
+#include "base/threading/thread_checker.h"
+#include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_track.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_deliverer.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+
+namespace blink {
+
+class WebMediaStreamAudioSink;
+class MediaStreamAudioSource;
+
+// 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.
+class PLATFORM_EXPORT MediaStreamAudioTrack
+ : public WebPlatformMediaStreamTrack {
+ public:
+ explicit MediaStreamAudioTrack(bool is_local_track);
+
+ ~MediaStreamAudioTrack() override;
+
+ // Returns the MediaStreamAudioTrack instance owned by the given blink |track|
+ // or null.
+ static MediaStreamAudioTrack* From(const WebMediaStreamTrack& track);
+
+ // Provides a weak reference to this MediaStreamAudioTrack which is
+ // invalidated when Stop() is called. The weak pointer may only be
+ // dereferenced on the main thread.
+ base::WeakPtr<MediaStreamAudioTrack> GetWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+ }
+
+ // Add a sink to the track. This function will trigger a OnSetFormat()
+ // call on the |sink| before the first chunk of audio is delivered.
+ void AddSink(WebMediaStreamAudioSink* sink);
+
+ // Remove a sink from the track. When this method returns, the sink's
+ // OnSetFormat() and OnData() methods will not be called again on any thread.
+ void RemoveSink(WebMediaStreamAudioSink* sink);
+
+ // Returns the output format of the capture source. May return an invalid
+ // AudioParameters if the format is not yet available.
+ // Called on the main render thread.
+ // TODO(tommi): This method appears to only be used by Pepper and in fact
+ // does not appear to be necessary there. We should remove it since it adds
+ // to the complexity of all types of audio tracks+source implementations.
+ // https://crbug.com/577874
+ media::AudioParameters GetOutputFormat() const;
+
+ // Halts the flow of audio data from the source (and to the sinks), and then
+ // notifies all sinks of the "ended" state.
+ void StopAndNotify(base::OnceClosure callback) final;
+
+ // MediaStreamTrack override.
+ void SetEnabled(bool enabled) override;
+ void SetContentHint(
+ WebMediaStreamTrack::ContentHintType content_hint) override;
+
+ // Returns a unique class identifier. Some subclasses override and use this
+ // method to provide safe down-casting to their type.
+ virtual void* GetClassIdentifier() const;
+
+ private:
+ friend class MediaStreamAudioSource;
+ friend class MediaStreamAudioDeliverer<MediaStreamAudioTrack>;
+
+ // Called by MediaStreamAudioSource to notify this track that the flow of
+ // audio data has started from the source. |stop_callback| is run by Stop()
+ // when the source must halt the flow of audio data to this track.
+ void Start(base::OnceClosure stop_callback);
+
+ // Called by the MediaStreamAudioDeliverer to notify this track of an audio
+ // format change. In turn, all WebMediaStreamAudioSinks will be notified
+ // before the next chunk of audio is delivered to them.
+ void OnSetFormat(const media::AudioParameters& params);
+
+ // Called by the MediaStreamAudioDeliverer to deliver audio data to this
+ // track, which in turn delivers the audio to one or more
+ // WebMediaStreamAudioSinks. While this track is disabled, silent audio will
+ // be delivered to the sinks instead of the content of |audio_bus|.
+ void OnData(const media::AudioBus& audio_bus, base::TimeTicks reference_time);
+
+ private:
+ // In debug builds, check that all methods that could cause object graph
+ // or data flow changes are being called on the main thread.
+ THREAD_CHECKER(thread_checker_);
+
+ // Callback provided to Start() which is run when the audio flow must halt.
+ base::OnceClosure stop_callback_;
+
+ // Manages sinks connected to this track and the audio format and data flow.
+ MediaStreamAudioDeliverer<WebMediaStreamAudioSink> deliverer_;
+
+ // While false (0), silent audio is delivered to the sinks.
+ base::subtle::Atomic32 is_enabled_;
+
+ // Buffer used to deliver silent audio data while this track is disabled.
+ std::unique_ptr<media::AudioBus> silent_bus_;
+
+ // Set to true once at first audio callback after calling Start().
+ // Only used for logging purposes.
+ bool received_audio_callback_ = false;
+
+ // Provides weak pointers that are valid until Stop() is called.
+ base::WeakPtrFactory<MediaStreamAudioTrack> weak_factory_{this};
+
+ DISALLOW_COPY_AND_ASSIGN(MediaStreamAudioTrack);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_MEDIA_STREAM_AUDIO_TRACK_H_
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 0e48a233069..bec6546fb21 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(blink::Visitor* visitor) {
+void MediaStreamComponent::Trace(Visitor* visitor) {
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 b4643ea7cb6..6515d8bb8df 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
@@ -35,10 +35,10 @@
#include <memory>
#include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_track.h"
-#include "third_party/blink/public/platform/web_media_constraints.h"
#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/renderer/platform/audio/audio_source_provider.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/mediastream/media_constraints.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/threading_primitives.h"
@@ -84,8 +84,8 @@ class PLATFORM_EXPORT MediaStreamComponent final
void SetMuted(bool muted) { muted_ = muted; }
WebMediaStreamTrack::ContentHintType ContentHint() { return content_hint_; }
void SetContentHint(WebMediaStreamTrack::ContentHintType);
- const WebMediaConstraints& Constraints() const { return constraints_; }
- void SetConstraints(const WebMediaConstraints& constraints) {
+ const MediaConstraints& Constraints() const { return constraints_; }
+ void SetConstraints(const MediaConstraints& constraints) {
constraints_ = constraints;
}
AudioSourceProvider* GetAudioSourceProvider() { return &source_provider_; }
@@ -102,7 +102,7 @@ class PLATFORM_EXPORT MediaStreamComponent final
}
void GetSettings(WebMediaStreamTrack::Settings&);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
// AudioSourceProviderImpl wraps a WebAudioSourceProvider::provideInput()
@@ -135,7 +135,7 @@ class PLATFORM_EXPORT MediaStreamComponent final
bool muted_ = false;
WebMediaStreamTrack::ContentHintType content_hint_ =
WebMediaStreamTrack::ContentHintType::kNone;
- WebMediaConstraints constraints_;
+ MediaConstraints constraints_;
std::unique_ptr<WebPlatformMediaStreamTrack> platform_track_;
};
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 0f3c348d4aa..970dd08e6f6 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(blink::Visitor* visitor) {
+void MediaStreamDescriptor::Trace(Visitor* visitor) {
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 ea3e04c6d18..80141ceea79 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(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) override {}
};
class PLATFORM_EXPORT MediaStreamDescriptor final
@@ -111,7 +111,7 @@ class PLATFORM_EXPORT MediaStreamDescriptor final
void AddObserver(WebMediaStreamObserver*);
void RemoveObserver(WebMediaStreamObserver*);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
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 df7371c24a7..a80d97c398f 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
@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
+#include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
@@ -37,6 +38,36 @@ namespace blink {
namespace {
+void SendLogMessage(const std::string& message) {
+ blink::WebRtcLogMessage("MSS::" + message);
+}
+
+const char* StreamTypeToString(MediaStreamSource::StreamType type) {
+ switch (type) {
+ case MediaStreamSource::kTypeAudio:
+ return "Audio";
+ case MediaStreamSource::kTypeVideo:
+ return "Video";
+ default:
+ NOTREACHED();
+ }
+ return "Invalid";
+}
+
+const char* ReadyStateToString(MediaStreamSource::ReadyState state) {
+ switch (state) {
+ case MediaStreamSource::kReadyStateLive:
+ return "Live";
+ case MediaStreamSource::kReadyStateMuted:
+ return "Muted";
+ case MediaStreamSource::kReadyStateEnded:
+ return "Ended";
+ default:
+ NOTREACHED();
+ }
+ return "Invalid";
+}
+
void GetSourceSettings(const blink::WebMediaStreamSource& web_source,
blink::WebMediaStreamTrack::Settings& settings) {
blink::MediaStreamAudioSource* const source =
@@ -68,13 +99,28 @@ MediaStreamSource::MediaStreamSource(const String& id,
name_(name),
remote_(remote),
ready_state_(ready_state),
- requires_consumer_(requires_consumer) {}
+ requires_consumer_(requires_consumer) {
+ SendLogMessage(
+ String::Format(
+ "MediaStreamSource({id=%s}, {type=%s}, {name=%s}, {remote=%d}, "
+ "{ready_state=%s}",
+ id.Utf8().c_str(), StreamTypeToString(type), name.Utf8().c_str(),
+ remote, ReadyStateToString(ready_state))
+ .Utf8());
+}
void MediaStreamSource::SetGroupId(const String& group_id) {
+ SendLogMessage(
+ String::Format("SetGroupId({group_id=%s})", group_id.Utf8().c_str())
+ .Utf8());
group_id_ = group_id;
}
void MediaStreamSource::SetReadyState(ReadyState ready_state) {
+ SendLogMessage(String::Format("SetReadyState({id=%s}, {ready_state=%s})",
+ Id().Utf8().c_str(),
+ ReadyStateToString(ready_state))
+ .Utf8());
if (ready_state_ != kReadyStateEnded && ready_state_ != ready_state) {
ready_state_ = ready_state;
@@ -171,6 +217,12 @@ void MediaStreamSource::GetSettings(WebMediaStreamTrack::Settings& settings) {
void MediaStreamSource::SetAudioFormat(size_t number_of_channels,
float sample_rate) {
+ SendLogMessage(
+ String::Format(
+ "SetAudioFormat({id=%s}, {number_of_channels=%d}, {sample_rate=%f})",
+ Id().Utf8().c_str(), static_cast<int>(number_of_channels),
+ sample_rate)
+ .Utf8());
DCHECK(requires_consumer_);
MutexLocker locker(audio_consumers_lock_);
for (AudioDestinationConsumer* consumer : audio_consumers_)
@@ -184,7 +236,7 @@ void MediaStreamSource::ConsumeAudio(AudioBus* bus, size_t number_of_frames) {
consumer->ConsumeAudio(bus, number_of_frames);
}
-void MediaStreamSource::Trace(blink::Visitor* visitor) {
+void MediaStreamSource::Trace(Visitor* visitor) {
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 2e4edff6f0b..2cc1f159f49 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
@@ -37,10 +37,10 @@
#include "base/optional.h"
#include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h"
-#include "third_party/blink/public/platform/web_media_constraints.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/audio/audio_destination_consumer.h"
+#include "third_party/blink/renderer/platform/mediastream/media_constraints.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/text/wtf_string.h"
@@ -121,7 +121,7 @@ class PLATFORM_EXPORT MediaStreamSource final
return audio_consumers_;
}
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
void Dispose();
@@ -138,7 +138,7 @@ class PLATFORM_EXPORT MediaStreamSource final
HashSet<AudioDestinationConsumer*> audio_consumers_
GUARDED_BY(audio_consumers_lock_);
std::unique_ptr<WebPlatformMediaStreamSource> platform_source_;
- WebMediaConstraints constraints_;
+ MediaConstraints constraints_;
WebMediaStreamSource::Capabilities capabilities_;
base::Optional<EchoCancellationMode> echo_cancellation_mode_;
base::Optional<bool> auto_gain_control_;
diff --git a/chromium/third_party/blink/renderer/platform/mediastream/webaudio_destination_consumer.h b/chromium/third_party/blink/renderer/platform/mediastream/webaudio_destination_consumer.h
new file mode 100644
index 00000000000..d6184f918fb
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/mediastream/webaudio_destination_consumer.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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.
+ */
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_WEBAUDIO_DESTINATION_CONSUMER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_WEBAUDIO_DESTINATION_CONSUMER_H_
+
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace blink {
+
+class WebAudioDestinationConsumer {
+ public:
+ virtual ~WebAudioDestinationConsumer() = default;
+
+ virtual void SetFormat(size_t number_of_channels, float sample_rate) = 0;
+
+ // The size of the vector is the number of audio channels, and
+ // |number_of_frames| is the number of audio frames in the (possibly
+ // multi-channel) buffer in a planar format.
+ virtual void ConsumeAudio(const Vector<const float*>&,
+ size_t number_of_frames) = 0;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIASTREAM_WEBAUDIO_DESTINATION_CONSUMER_H_
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 8d294a3c5ed..7ae4e9ea83b 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
@@ -6,9 +6,9 @@
#include <utility>
-#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
namespace blink {
@@ -17,8 +17,9 @@ WebAudioMediaStreamSource::WebAudioMediaStreamSource(
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
: MediaStreamAudioSource(std::move(task_runner), false /* is_remote */),
is_registered_consumer_(false),
- fifo_(base::Bind(&WebAudioMediaStreamSource::DeliverRebufferedAudio,
- base::Unretained(this))),
+ fifo_(ConvertToBaseRepeatingCallback(CrossThreadBindRepeating(
+ &WebAudioMediaStreamSource::DeliverRebufferedAudio,
+ WTF::CrossThreadUnretained(this)))),
blink_source_(*blink_source) {
DVLOG(1) << "WebAudioMediaStreamSource::WebAudioMediaStreamSource()";
}
@@ -83,7 +84,7 @@ void WebAudioMediaStreamSource::EnsureSourceIsStopped() {
}
void WebAudioMediaStreamSource::ConsumeAudio(
- const WebVector<const float*>& audio_data,
+ const Vector<const float*>& audio_data,
size_t number_of_frames) {
// TODO(miu): Plumbing is needed to determine the actual capture timestamp
// of the audio, instead of just snapshotting base::TimeTicks::Now(), for
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 e5de09a72b2..afdfc6e7c58 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
@@ -10,10 +10,10 @@
#include "base/time/time.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_push_fifo.h"
-#include "third_party/blink/public/platform/web_audio_destination_consumer.h"
#include "third_party/blink/public/platform/web_media_stream_source.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
+#include "third_party/blink/renderer/platform/mediastream/webaudio_destination_consumer.h"
#include "third_party/blink/renderer/platform/platform_export.h"
namespace blink {
@@ -39,7 +39,7 @@ class PLATFORM_EXPORT WebAudioMediaStreamSource final
// concurrently across threads, but these methods could be called on any
// thread.
void SetFormat(size_t number_of_channels, float sample_rate) override;
- void ConsumeAudio(const WebVector<const float*>& audio_data,
+ void ConsumeAudio(const Vector<const float*>& audio_data,
size_t number_of_frames) override;
// Called by AudioPushFifo zero or more times during the call to
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 10b339edd88..fde61b92783 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(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
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 94d98b13a53..9021739bd00 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(blink::Visitor* visitor) {
+void MHTMLArchive::Trace(Visitor* visitor) {
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 985d346276c..c1edc8d5764 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(blink::Visitor*);
+ void Trace(Visitor*);
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 f08d30dab9c..c055297ed18 100644
--- a/chromium/third_party/blink/renderer/platform/mhtml/mhtml_parser.cc
+++ b/chromium/third_party/blink/renderer/platform/mhtml/mhtml_parser.cc
@@ -124,7 +124,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(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
private:
static Encoding ParseContentTransferEncoding(const String&);
@@ -234,7 +234,7 @@ MIMEHeader* MIMEHeader::ParseHeader(SharedBufferChunkReader* buffer) {
MIMEHeader::Encoding MIMEHeader::ParseContentTransferEncoding(
const String& text) {
- String encoding = text.StripWhiteSpace().DeprecatedLower();
+ String encoding = text.StripWhiteSpace().LowerASCII();
if (encoding == "base64")
return Encoding::kBase64;
if (encoding == "quoted-printable")
diff --git a/chromium/third_party/blink/renderer/platform/mojo/DEPS b/chromium/third_party/blink/renderer/platform/mojo/DEPS
index ee6991fbfd1..0520c841e8c 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/DEPS
+++ b/chromium/third_party/blink/renderer/platform/mojo/DEPS
@@ -13,7 +13,6 @@ include_rules = [
"+base/strings/latin1_string_conversions.h",
"+base/strings/string16.h",
"+mojo/public/cpp/base/time_mojom_traits.h",
- "+mojo/public/cpp/bindings/binding.h",
"+mojo/public/mojom/base/string16.mojom-blink.h",
"+skia/public/mojom/bitmap_skbitmap_mojom_traits.h",
@@ -22,6 +21,10 @@ include_rules = [
"+third_party/blink/renderer/platform/platform_export.h",
"+third_party/blink/renderer/platform/weborigin",
"+third_party/blink/renderer/platform/wtf",
+ "+third_party/blink/renderer/platform/context_lifecycle_observer.h",
+ "+third_party/blink/renderer/platform/context_lifecycle_notifier.h",
+ "+third_party/blink/renderer/platform/heap_observer_list.h",
+ "+third_party/blink/renderer/platform/heap",
]
specific_include_rules = {
diff --git a/chromium/third_party/blink/renderer/platform/mojo/big_string.typemap b/chromium/third_party/blink/renderer/platform/mojo/big_string.typemap
deleted file mode 100644
index bd4bac7b3f7..00000000000
--- a/chromium/third_party/blink/renderer/platform/mojo/big_string.typemap
+++ /dev/null
@@ -1,11 +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.
-
-mojom = "//mojo/public/mojom/base/big_string.mojom"
-public_headers =
- [ "//third_party/blink/renderer/platform/wtf/text/wtf_string.h" ]
-traits_headers =
- [ "//third_party/blink/renderer/platform/mojo/big_string_mojom_traits.h" ]
-type_mappings =
- [ "mojo_base.mojom.BigString=::WTF::String[nullable_is_same_type]" ]
diff --git a/chromium/third_party/blink/renderer/platform/mojo/big_string_mojom_traits.h b/chromium/third_party/blink/renderer/platform/mojo/big_string_mojom_traits.h
index dda183cb6c9..2b0f1388aaa 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/big_string_mojom_traits.h
+++ b/chromium/third_party/blink/renderer/platform/mojo/big_string_mojom_traits.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_BIG_STRING_MOJOM_TRAITS_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_BIG_STRING_MOJOM_TRAITS_H_
+#include "mojo/public/cpp/base/big_buffer.h"
#include "mojo/public/cpp/bindings/struct_traits.h"
#include "mojo/public/mojom/base/big_string.mojom-blink-forward.h"
#include "third_party/blink/renderer/platform/platform_export.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 176545f7ecb..8af90056cf9 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/blink_typemaps.gni
+++ b/chromium/third_party/blink/renderer/platform/mojo/blink_typemaps.gni
@@ -3,33 +3,27 @@
# found in the LICENSE file.
typemaps = [
- "//media/capture/mojom/video_capture_types_for_blink.typemap",
+ "//media/capture/mojom/video_capture_types.typemap",
"//media/mojo/mojom/audio_parameters.typemap",
- "//mojo/public/cpp/base/values.typemap",
- "//services/network/public/cpp/http_request_headers.typemap",
- "//services/network/public/cpp/ip_address_for_blink.typemap",
- "//services/network/public/cpp/ip_endpoint_for_blink.typemap",
- "//services/network/public/cpp/network_interface_for_blink.typemap",
- "//services/network/public/cpp/mutable_network_traffic_annotation_tag.typemap",
- "//services/network/public/cpp/p2p.typemap",
+ "//third_party/blink/common/feature_policy/feature_policy.typemap",
+ "//third_party/blink/common/frame/frame_policy.typemap",
+ "//third_party/blink/public/common/loader/url_loader_factory_bundle.typemap",
+ "//third_party/blink/public/common/messaging/message_port_descriptor.typemap",
"//third_party/blink/renderer/core/messaging/blink_cloneable_message.typemap",
"//third_party/blink/renderer/core/messaging/blink_transferable_message.typemap",
"//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/mojo/big_string.typemap",
"//third_party/blink/renderer/platform/mojo/fetch_api_request_headers.typemap",
- "//third_party/blink/renderer/platform/mojo/geometry.typemap",
- "//third_party/blink/renderer/platform/mojo/kurl.typemap",
- "//third_party/blink/renderer/platform/mojo/security_origin.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",
"//third_party/blink/public/mojom/bluetooth/bluetooth.typemap",
- "//ui/gfx/mojom/buffer_types_for_blink.typemap",
- "//ui/gfx/mojom/color_space_for_blink.typemap",
+ "//ui/gfx/geometry/mojom/geometry.typemap",
+ "//ui/gfx/mojom/color_space.typemap",
"//ui/gfx/mojom/transform.typemap",
]
diff --git a/chromium/third_party/blink/renderer/platform/mojo/geometry.typemap b/chromium/third_party/blink/renderer/platform/mojo/geometry.typemap
deleted file mode 100644
index 8029163748a..00000000000
--- a/chromium/third_party/blink/renderer/platform/mojo/geometry.typemap
+++ /dev/null
@@ -1,44 +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.
-
-mojom = "//ui/gfx/geometry/mojom/geometry.mojom"
-public_headers = [
- "//ui/gfx/geometry/quaternion.h",
- "//ui/gfx/geometry/vector3d_f.h",
- "//third_party/blink/public/platform/web_float_rect.h",
- "//third_party/blink/public/platform/web_float_point.h",
- "//third_party/blink/public/platform/web_point.h",
- "//third_party/blink/public/platform/web_rect.h",
- "//third_party/blink/public/platform/web_size.h",
- "//third_party/blink/renderer/platform/geometry/float_point_3d.h",
-]
-traits_headers = [
- "//third_party/blink/renderer/platform/mojo/geometry_mojom_traits.h",
- "//ui/gfx/geometry/mojom/geometry_mojom_traits.h",
-]
-
-# Note: consumers of this typemap must themselves depend on platform.
-deps = [
- "//mojo/public/cpp/bindings",
-]
-
-public_deps = [
- "//third_party/blink/public:blink_headers",
- "//third_party/blink/renderer/platform:geometry_mojom_traits",
- "//ui/gfx/geometry",
- "//ui/gfx/geometry/mojom:mojom_traits",
-]
-
-# TODO(zqzhang): ideally, gfx.mojom.Size should be mapped into ::blink::IntSize.
-# However that introduces an link issue on Windows. See https://crbug.com/653323
-type_mappings = [
- "gfx.mojom.Point=::blink::WebPoint",
- "gfx.mojom.PointF=::blink::WebFloatPoint",
- "gfx.mojom.Point3F=::blink::FloatPoint3D",
- "gfx.mojom.Quaternion=::gfx::Quaternion",
- "gfx.mojom.RectF=::blink::WebFloatRect",
- "gfx.mojom.Rect=::blink::WebRect",
- "gfx.mojom.Size=::blink::WebSize",
- "gfx.mojom.Vector3dF=::gfx::Vector3dF",
-]
diff --git a/chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits.cc b/chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits.cc
deleted file mode 100644
index 29128e0055d..00000000000
--- a/chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits.cc
+++ /dev/null
@@ -1,73 +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/mojo/geometry_mojom_traits.h"
-
-namespace mojo {
-
-// static
-bool StructTraits<gfx::mojom::RectFDataView, ::blink::WebFloatRect>::Read(
- gfx::mojom::RectFDataView data,
- ::blink::WebFloatRect* out) {
- if (data.width() < 0 || data.height() < 0)
- return false;
- out->x = data.x();
- out->y = data.y();
- out->width = data.width();
- out->height = data.height();
- return true;
-}
-
-// static
-bool StructTraits<gfx::mojom::RectDataView, ::blink::WebRect>::Read(
- gfx::mojom::RectDataView data,
- ::blink::WebRect* out) {
- if (data.width() < 0 || data.height() < 0)
- return false;
- out->x = data.x();
- out->y = data.y();
- out->width = data.width();
- out->height = data.height();
- return true;
-}
-
-// static
-bool StructTraits<gfx::mojom::PointDataView, ::blink::WebPoint>::Read(
- gfx::mojom::PointDataView data,
- ::blink::WebPoint* out) {
- out->x = data.x();
- out->y = data.y();
- return true;
-}
-
-// static
-bool StructTraits<gfx::mojom::PointFDataView, ::blink::WebFloatPoint>::Read(
- gfx::mojom::PointFDataView data,
- ::blink::WebFloatPoint* out) {
- out->x = data.x();
- out->y = data.y();
- return true;
-}
-
-bool StructTraits<gfx::mojom::Point3FDataView, ::blink::FloatPoint3D>::Read(
- gfx::mojom::Point3FDataView data,
- ::blink::FloatPoint3D* out) {
- out->SetX(data.x());
- out->SetY(data.y());
- out->SetZ(data.z());
- return true;
-}
-
-// static
-bool StructTraits<gfx::mojom::SizeDataView, ::blink::WebSize>::Read(
- gfx::mojom::SizeDataView data,
- ::blink::WebSize* out) {
- if (data.width() < 0 || data.height() < 0)
- return false;
- out->width = data.width();
- out->height = data.height();
- return true;
-}
-
-} // namespace mojo
diff --git a/chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits.h b/chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits.h
deleted file mode 100644
index eb16fc06bb1..00000000000
--- a/chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits.h
+++ /dev/null
@@ -1,68 +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_PLATFORM_MOJO_GEOMETRY_MOJOM_TRAITS_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_GEOMETRY_MOJOM_TRAITS_H_
-
-#include "third_party/blink/public/platform/web_float_point.h"
-#include "third_party/blink/public/platform/web_float_rect.h"
-#include "third_party/blink/public/platform/web_point.h"
-#include "third_party/blink/public/platform/web_rect.h"
-#include "third_party/blink/public/platform/web_size.h"
-#include "third_party/blink/renderer/platform/geometry/float_point_3d.h"
-#include "ui/gfx/geometry/mojom/geometry.mojom-shared.h"
-
-namespace mojo {
-
-template <>
-struct StructTraits<gfx::mojom::PointDataView, ::blink::WebPoint> {
- static int x(const ::blink::WebPoint& point) { return point.x; }
- static int y(const ::blink::WebPoint& point) { return point.y; }
- static bool Read(gfx::mojom::PointDataView, ::blink::WebPoint* out);
-};
-
-template <>
-struct StructTraits<gfx::mojom::PointFDataView, ::blink::WebFloatPoint> {
- static float x(const ::blink::WebFloatPoint& point) { return point.x; }
- static float y(const ::blink::WebFloatPoint& point) { return point.y; }
- static bool Read(gfx::mojom::PointFDataView, ::blink::WebFloatPoint* out);
-};
-
-template <>
-struct StructTraits<gfx::mojom::Point3FDataView, ::blink::FloatPoint3D> {
- static float x(const gfx::Point3F& p) { return p.x(); }
- static float y(const gfx::Point3F& p) { return p.y(); }
- static float z(const gfx::Point3F& p) { return p.z(); }
- static bool Read(gfx::mojom::Point3FDataView data,
- ::blink::FloatPoint3D* out);
-};
-
-template <>
-struct StructTraits<gfx::mojom::RectFDataView, ::blink::WebFloatRect> {
- static float x(const ::blink::WebFloatRect& rect) { return rect.x; }
- static float y(const ::blink::WebFloatRect& rect) { return rect.y; }
- static float width(const ::blink::WebFloatRect& rect) { return rect.width; }
- static float height(const ::blink::WebFloatRect& rect) { return rect.height; }
- static bool Read(gfx::mojom::RectFDataView, ::blink::WebFloatRect* out);
-};
-
-template <>
-struct StructTraits<gfx::mojom::RectDataView, ::blink::WebRect> {
- static int x(const ::blink::WebRect& rect) { return rect.x; }
- static int y(const ::blink::WebRect& rect) { return rect.y; }
- static int width(const ::blink::WebRect& rect) { return rect.width; }
- static int height(const ::blink::WebRect& rect) { return rect.height; }
- static bool Read(gfx::mojom::RectDataView, ::blink::WebRect* out);
-};
-
-template <>
-struct StructTraits<gfx::mojom::SizeDataView, ::blink::WebSize> {
- static int width(const ::blink::WebSize& size) { return size.width; }
- static int height(const ::blink::WebSize& size) { return size.height; }
- static bool Read(gfx::mojom::SizeDataView, ::blink::WebSize* out);
-};
-
-} // namespace mojo
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_GEOMETRY_MOJOM_TRAITS_H_
diff --git a/chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits_test.cc b/chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits_test.cc
deleted file mode 100644
index 0c1d8a69650..00000000000
--- a/chromium/third_party/blink/renderer/platform/mojo/geometry_mojom_traits_test.cc
+++ /dev/null
@@ -1,180 +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 <utility>
-
-#include "base/test/task_environment.h"
-#include "mojo/public/cpp/bindings/receiver_set.h"
-#include "mojo/public/cpp/bindings/remote.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/geometry/float_point_3d.h"
-#include "ui/gfx/geometry/mojom/geometry.mojom-blink.h"
-#include "ui/gfx/geometry/mojom/geometry_traits_test_service.mojom-blink.h"
-
-namespace blink {
-
-namespace {
-
-class GeometryStructTraitsTest
- : public testing::Test,
- public gfx::mojom::blink::GeometryTraitsTestService {
- public:
- GeometryStructTraitsTest() {}
-
- protected:
- mojo::Remote<gfx::mojom::blink::GeometryTraitsTestService>
- GetTraitsTestProxy() {
- mojo::Remote<gfx::mojom::blink::GeometryTraitsTestService> proxy;
- traits_test_receivers_.Add(this, proxy.BindNewPipeAndPassReceiver());
- return proxy;
- }
-
- private:
- // GeometryTraitsTestService:
- void EchoPoint(const WebPoint& p, EchoPointCallback callback) override {
- std::move(callback).Run(p);
- }
-
- void EchoPointF(const WebFloatPoint& p,
- EchoPointFCallback callback) override {
- std::move(callback).Run(p);
- }
-
- void EchoPoint3F(const FloatPoint3D& p,
- EchoPoint3FCallback callback) override {
- std::move(callback).Run(p);
- }
-
- void EchoSize(const WebSize& s, EchoSizeCallback callback) override {
- std::move(callback).Run(s);
- }
-
- void EchoSizeF(gfx::mojom::blink::SizeFPtr, EchoSizeFCallback) override {
- // The type map is not specified.
- NOTREACHED();
- }
-
- void EchoRect(const WebRect& r, EchoRectCallback callback) override {
- std::move(callback).Run(r);
- }
-
- void EchoRectF(const WebFloatRect& r, EchoRectFCallback callback) override {
- std::move(callback).Run(r);
- }
-
- void EchoInsets(gfx::mojom::blink::InsetsPtr, EchoInsetsCallback) override {
- // The type map is not specified.
- NOTREACHED();
- }
-
- void EchoInsetsF(gfx::mojom::blink::InsetsFPtr,
- EchoInsetsFCallback) override {
- // The type map is not specified.
- NOTREACHED();
- }
-
- void EchoVector2d(gfx::mojom::blink::Vector2dPtr,
- EchoVector2dCallback) override {
- // The type map is not specified.
- NOTREACHED();
- }
-
- void EchoVector2dF(gfx::mojom::blink::Vector2dFPtr,
- EchoVector2dFCallback) override {
- // The type map is not specified.
- NOTREACHED();
- }
-
- void EchoVector3dF(const gfx::Vector3dF& v,
- EchoVector3dFCallback callback) override {
- std::move(callback).Run(v);
- }
-
- void EchoQuaternion(const gfx::Quaternion& q,
- EchoQuaternionCallback callback) override {
- std::move(callback).Run(q);
- }
-
- mojo::ReceiverSet<gfx::mojom::blink::GeometryTraitsTestService>
- traits_test_receivers_;
-
- base::test::TaskEnvironment task_environment_;
-
- DISALLOW_COPY_AND_ASSIGN(GeometryStructTraitsTest);
-};
-
-} // namespace
-
-TEST_F(GeometryStructTraitsTest, Size) {
- const int32_t kWidth = 1234;
- const int32_t kHeight = 5678;
- WebSize input(kWidth, kHeight);
- mojo::Remote<gfx::mojom::blink::GeometryTraitsTestService> proxy =
- GetTraitsTestProxy();
- WebSize output;
- proxy->EchoSize(input, &output);
- EXPECT_EQ(input, output);
-}
-
-TEST_F(GeometryStructTraitsTest, Point) {
- const float kX = 1234;
- const float kY = 5678;
- WebPoint input(kX, kY);
- mojo::Remote<gfx::mojom::blink::GeometryTraitsTestService> proxy =
- GetTraitsTestProxy();
- WebPoint output;
- proxy->EchoPoint(input, &output);
- EXPECT_EQ(input, output);
-}
-
-TEST_F(GeometryStructTraitsTest, PointF) {
- const float kX = 1.234;
- const float kY = 5.678;
- WebFloatPoint input(kX, kY);
- mojo::Remote<gfx::mojom::blink::GeometryTraitsTestService> proxy =
- GetTraitsTestProxy();
- WebFloatPoint output;
- proxy->EchoPointF(input, &output);
- EXPECT_EQ(input, output);
-}
-
-TEST_F(GeometryStructTraitsTest, Point3D) {
- const float kX = 1.234;
- const float kY = 5.678;
- const float kZ = 9.098;
- FloatPoint3D input(kX, kY, kZ);
- mojo::Remote<gfx::mojom::blink::GeometryTraitsTestService> proxy =
- GetTraitsTestProxy();
- FloatPoint3D output;
- proxy->EchoPoint3F(input, &output);
- EXPECT_EQ(input, output);
-}
-
-TEST_F(GeometryStructTraitsTest, Rect) {
- const float kX = 1;
- const float kY = 2;
- const float kWidth = 3;
- const float kHeight = 4;
- WebRect input(kX, kY, kWidth, kHeight);
- mojo::Remote<gfx::mojom::blink::GeometryTraitsTestService> proxy =
- GetTraitsTestProxy();
- WebRect output;
- proxy->EchoRect(input, &output);
- EXPECT_EQ(input, output);
-}
-
-TEST_F(GeometryStructTraitsTest, RectF) {
- const float kX = 1.234;
- const float kY = 2.345;
- const float kWidth = 3.456;
- const float kHeight = 4.567;
- WebFloatRect input(kX, kY, kWidth, kHeight);
- mojo::Remote<gfx::mojom::blink::GeometryTraitsTestService> proxy =
- GetTraitsTestProxy();
- WebFloatRect output;
- proxy->EchoRectF(input, &output);
- EXPECT_EQ(input, output);
-}
-
-} // namespace blink
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
new file mode 100644
index 00000000000..bfc774c962b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h
@@ -0,0 +1,94 @@
+// 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_HEAP_MOJO_RECEIVER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_HEAP_MOJO_RECEIVER_H_
+
+#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/heap_mojo_wrapper_mode.h"
+
+namespace blink {
+
+// HeapMojoReceiver is a wrapper for mojo::Receiver to be owned by a
+// garbage-collected object. Blink is expected to use HeapMojoReceiver by
+// default. HeapMojoReceiver must be associated with context.
+// HeapMojoReceiver's constructor takes context as a mandatory parameter.
+// HeapMojoReceiver resets the mojo connection when 1) the owner object is
+// garbage-collected and 2) the associated ExecutionContext is detached.
+
+// TODO(crbug.com/1058076) HeapMojoWrapperMode should be removed once we ensure
+// that the interface is not used after ContextDestroyed().
+template <typename Interface,
+ HeapMojoWrapperMode Mode = HeapMojoWrapperMode::kWithContextObserver>
+class HeapMojoReceiver {
+ DISALLOW_NEW();
+
+ public:
+ using ImplPointerType = typename mojo::Receiver<Interface>::ImplPointerType;
+
+ HeapMojoReceiver(ImplPointerType impl, ContextLifecycleNotifier* context)
+ : wrapper_(MakeGarbageCollected<Wrapper>(std::move(impl), context)) {}
+
+ // Methods to redirect to mojo::Receiver:
+ ImplPointerType operator->() const { return get(); }
+ ImplPointerType get() { return wrapper_->receiver().get(); }
+ bool is_bound() const { return wrapper_->receiver().is_bound(); }
+ void reset() { wrapper_->receiver().reset(); }
+ void set_disconnect_handler(base::OnceClosure handler) {
+ wrapper_->receiver().set_disconnect_handler(std::move(handler));
+ }
+ mojo::PendingRemote<Interface> BindNewPipeAndPassRemote(
+ scoped_refptr<base::SequencedTaskRunner> task_runner) WARN_UNUSED_RESULT {
+ DCHECK(task_runner);
+ return wrapper_->receiver().BindNewPipeAndPassRemote(
+ std::move(task_runner));
+ }
+ void Bind(mojo::PendingReceiver<Interface> pending_receiver,
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
+ DCHECK(task_runner);
+ wrapper_->receiver().Bind(std::move(pending_receiver),
+ std::move(task_runner));
+ }
+
+ void Trace(Visitor* visitor) { visitor->Trace(wrapper_); }
+
+ private:
+ // Garbage collected wrapper class to add a prefinalizer.
+ class Wrapper final : public GarbageCollected<Wrapper>,
+ public ContextLifecycleObserver {
+ USING_PRE_FINALIZER(Wrapper, Dispose);
+ USING_GARBAGE_COLLECTED_MIXIN(Wrapper);
+
+ public:
+ Wrapper(ImplPointerType impl, ContextLifecycleNotifier* notifier)
+ : receiver_(std::move(impl)) {
+ SetContextLifecycleNotifier(notifier);
+ }
+
+ void Trace(Visitor* visitor) override {
+ ContextLifecycleObserver::Trace(visitor);
+ }
+
+ void Dispose() { receiver_.reset(); }
+
+ mojo::Receiver<Interface>& receiver() { return receiver_; }
+
+ // ContextLifecycleObserver methods
+ void ContextDestroyed() override {
+ if (Mode == HeapMojoWrapperMode::kWithContextObserver)
+ receiver_.reset();
+ }
+
+ private:
+ mojo::Receiver<Interface> receiver_;
+ };
+
+ Member<Wrapper> wrapper_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_HEAP_MOJO_RECEIVER_H_
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
new file mode 100644
index 00000000000..36b7a74aa76
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set.h
@@ -0,0 +1,94 @@
+// 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_HEAP_MOJO_RECEIVER_SET_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_HEAP_MOJO_RECEIVER_SET_H_
+
+#include "mojo/public/cpp/bindings/receiver.h"
+#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/heap_mojo_wrapper_mode.h"
+
+namespace blink {
+
+// HeapMojoReceiverSet is a wrapper for mojo::ReceiverSet to be owned by a
+// garbage-collected object. Blink is expected to use HeapMojoReceiverSet by
+// default. HeapMojoReceiverSet must be associated with context.
+// HeapMojoReceiverSet's constructor takes context as a mandatory parameter.
+// HeapMojoReceiverSet resets the mojo connection when 1) the owner object is
+// garbage-collected or 2) the associated ExecutionContext is detached.
+
+// TODO(crbug.com/1058076) HeapMojoWrapperMode should be removed once we ensure
+// that the interface is not used after ContextDestroyed().
+template <typename Interface,
+ HeapMojoWrapperMode Mode = HeapMojoWrapperMode::kWithContextObserver>
+class HeapMojoReceiverSet {
+ DISALLOW_NEW();
+
+ public:
+ using ImplPointerType = typename mojo::Receiver<Interface>::ImplPointerType;
+
+ explicit HeapMojoReceiverSet(ContextLifecycleNotifier* context)
+ : wrapper_(MakeGarbageCollected<Wrapper>(context)) {
+ DCHECK(context);
+ }
+
+ // Methods to redirect to mojo::ReceiverSet:
+ mojo::ReceiverId Add(ImplPointerType impl,
+ mojo::PendingReceiver<Interface> receiver,
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
+ DCHECK(task_runner);
+ return wrapper_->receiver_set().Add(std::move(impl), std::move(receiver),
+ task_runner);
+ }
+
+ bool Remove(mojo::ReceiverId id) {
+ return wrapper_->receiver_set().Remove(id);
+ }
+
+ void Clear() { wrapper_->receiver_set().Clear(); }
+
+ bool HasReceiver(mojo::ReceiverId id) {
+ return wrapper_->receiver_set().HasReceiver(id);
+ }
+
+ void Trace(Visitor* visitor) { visitor->Trace(wrapper_); }
+
+ private:
+ // Garbage collected wrapper class to add a prefinalizer.
+ class Wrapper final : public GarbageCollected<Wrapper>,
+ public ContextLifecycleObserver {
+ USING_PRE_FINALIZER(Wrapper, Dispose);
+ USING_GARBAGE_COLLECTED_MIXIN(Wrapper);
+
+ public:
+ explicit Wrapper(ContextLifecycleNotifier* notifier) {
+ SetContextLifecycleNotifier(notifier);
+ }
+
+ void Trace(Visitor* visitor) override {
+ ContextLifecycleObserver::Trace(visitor);
+ }
+
+ void Dispose() { receiver_set_.Clear(); }
+
+ mojo::ReceiverSet<Interface>& receiver_set() { return receiver_set_; }
+
+ // ContextLifecycleObserver methods
+ void ContextDestroyed() override {
+ if (Mode == HeapMojoWrapperMode::kWithContextObserver)
+ receiver_set_.Clear();
+ }
+
+ private:
+ mojo::ReceiverSet<Interface> receiver_set_;
+ };
+
+ Member<Wrapper> wrapper_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_HEAP_MOJO_RECEIVER_SET_H_
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
new file mode 100644
index 00000000000..aa13bc2b39b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set_test.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/mojo/heap_mojo_receiver_set.h"
+
+#include "base/test/null_task_runner.h"
+#include "mojo/public/cpp/bindings/receiver_set.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"
+#include "third_party/blink/renderer/platform/context_lifecycle_notifier.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_observer_list.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
+
+namespace blink {
+
+namespace {
+
+class FakeContextNotifier final : public GarbageCollected<FakeContextNotifier>,
+ public ContextLifecycleNotifier {
+ USING_GARBAGE_COLLECTED_MIXIN(FakeContextNotifier);
+
+ public:
+ FakeContextNotifier() = default;
+
+ void AddContextLifecycleObserver(
+ ContextLifecycleObserver* observer) override {
+ observers_.AddObserver(observer);
+ }
+ void RemoveContextLifecycleObserver(
+ ContextLifecycleObserver* observer) override {
+ observers_.RemoveObserver(observer);
+ }
+
+ void NotifyContextDestroyed() {
+ observers_.ForEachObserver([](ContextLifecycleObserver* observer) {
+ observer->ContextDestroyed();
+ });
+ }
+
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(observers_);
+ ContextLifecycleNotifier::Trace(visitor);
+ }
+
+ private:
+ HeapObserverList<ContextLifecycleObserver> observers_;
+};
+
+class MockService : public sample::blink::Service {
+ public:
+ MockService() = default;
+
+ void Frobinate(sample::blink::FooPtr foo,
+ Service::BazOptions baz,
+ mojo::PendingRemote<sample::blink::Port> port,
+ FrobinateCallback callback) override {}
+ void GetPort(mojo::PendingReceiver<sample::blink::Port> receiver) override {}
+};
+
+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_); }
+
+ HeapMojoReceiverSet<sample::blink::Service, Mode>& receiver_set() {
+ return receiver_set_;
+ }
+
+ private:
+ HeapMojoReceiverSet<sample::blink::Service, Mode> receiver_set_;
+};
+
+template <HeapMojoWrapperMode Mode>
+class HeapMojoReceiverSetGCBaseTest : public TestSupportingGC {
+ public:
+ FakeContextNotifier* context() { return context_; }
+ scoped_refptr<base::NullTaskRunner> task_runner() {
+ return null_task_runner_;
+ }
+ GCOwner<Mode>* owner() { return owner_; }
+
+ void ClearOwner() { owner_ = nullptr; }
+
+ protected:
+ void SetUp() override {
+ context_ = MakeGarbageCollected<FakeContextNotifier>();
+ owner_ = MakeGarbageCollected<GCOwner<Mode>>(context());
+ }
+ void TearDown() override {}
+
+ Persistent<FakeContextNotifier> context_;
+ Persistent<GCOwner<Mode>> owner_;
+ scoped_refptr<base::NullTaskRunner> null_task_runner_ =
+ base::MakeRefCounted<base::NullTaskRunner>();
+};
+
+} // namespace
+
+class HeapMojoReceiverSetGCWithContextObserverTest
+ : public HeapMojoReceiverSetGCBaseTest<
+ HeapMojoWrapperMode::kWithContextObserver> {};
+class HeapMojoReceiverSetGCWithoutContextObserverTest
+ : public HeapMojoReceiverSetGCBaseTest<
+ HeapMojoWrapperMode::kWithoutContextObserver> {};
+
+// GC the HeapMojoReceiverSet with context observer and verify that the receiver
+// is no longer part of the set, and that the service was deleted.
+TEST_F(HeapMojoReceiverSetGCWithContextObserverTest, RemovesReceiver) {
+ auto receiver_set = owner()->receiver_set();
+ MockService service;
+ auto receiver = mojo::PendingReceiver<sample::blink::Service>(
+ mojo::MessagePipe().handle0);
+
+ mojo::ReceiverId rid =
+ receiver_set.Add(&service, std::move(receiver), task_runner());
+ EXPECT_TRUE(receiver_set.HasReceiver(rid));
+
+ receiver_set.Remove(rid);
+
+ EXPECT_FALSE(receiver_set.HasReceiver(rid));
+}
+
+// GC the HeapMojoReceiverSet without context observer and verify that the
+// receiver is no longer part of the set, and that the service was deleted.
+TEST_F(HeapMojoReceiverSetGCWithoutContextObserverTest, RemovesReceiver) {
+ auto receiver_set = owner()->receiver_set();
+ MockService service;
+ auto receiver = mojo::PendingReceiver<sample::blink::Service>(
+ mojo::MessagePipe().handle0);
+
+ mojo::ReceiverId rid =
+ receiver_set.Add(&service, std::move(receiver), task_runner());
+ EXPECT_TRUE(receiver_set.HasReceiver(rid));
+
+ receiver_set.Remove(rid);
+
+ EXPECT_FALSE(receiver_set.HasReceiver(rid));
+}
+
+// GC the HeapMojoReceiverSet with context observer and verify that the receiver
+// is no longer part of the set, and that the service was deleted.
+TEST_F(HeapMojoReceiverSetGCWithContextObserverTest, ClearLeavesSetEmpty) {
+ auto receiver_set = owner()->receiver_set();
+ MockService service;
+ auto receiver = mojo::PendingReceiver<sample::blink::Service>(
+ mojo::MessagePipe().handle0);
+
+ mojo::ReceiverId rid =
+ receiver_set.Add(&service, std::move(receiver), task_runner());
+ EXPECT_TRUE(receiver_set.HasReceiver(rid));
+
+ receiver_set.Clear();
+
+ EXPECT_FALSE(receiver_set.HasReceiver(rid));
+}
+
+// GC the HeapMojoReceiverSet without context observer and verify that the
+// receiver is no longer part of the set, and that the service was deleted.
+TEST_F(HeapMojoReceiverSetGCWithoutContextObserverTest, ClearLeavesSetEmpty) {
+ auto receiver_set = owner()->receiver_set();
+ MockService service;
+ auto receiver = mojo::PendingReceiver<sample::blink::Service>(
+ mojo::MessagePipe().handle0);
+
+ mojo::ReceiverId rid =
+ receiver_set.Add(&service, std::move(receiver), task_runner());
+ EXPECT_TRUE(receiver_set.HasReceiver(rid));
+
+ receiver_set.Clear();
+
+ EXPECT_FALSE(receiver_set.HasReceiver(rid));
+}
+
+} // 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
new file mode 100644
index 00000000000..2f348ab5b4f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_test.cc
@@ -0,0 +1,176 @@
+
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h"
+#include "base/test/null_task_runner.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"
+#include "third_party/blink/renderer/platform/context_lifecycle_notifier.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_observer_list.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
+
+namespace blink {
+
+namespace {
+
+class MockContext final : public GarbageCollected<MockContext>,
+ public ContextLifecycleNotifier {
+ USING_GARBAGE_COLLECTED_MIXIN(MockContext);
+
+ public:
+ MockContext() = default;
+
+ void AddContextLifecycleObserver(
+ ContextLifecycleObserver* observer) override {
+ observers_.AddObserver(observer);
+ }
+ void RemoveContextLifecycleObserver(
+ ContextLifecycleObserver* observer) override {
+ observers_.RemoveObserver(observer);
+ }
+
+ void NotifyContextDestroyed() {
+ observers_.ForEachObserver([](ContextLifecycleObserver* observer) {
+ observer->ContextDestroyed();
+ });
+ }
+
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(observers_);
+ ContextLifecycleNotifier::Trace(visitor);
+ }
+
+ private:
+ HeapObserverList<ContextLifecycleObserver> observers_;
+};
+
+template <HeapMojoWrapperMode Mode>
+class ReceiverOwner : public GarbageCollected<ReceiverOwner<Mode>>,
+ public sample::blink::Service {
+ public:
+ explicit ReceiverOwner(MockContext* context) : receiver_(this, context) {}
+
+ HeapMojoReceiver<sample::blink::Service, Mode>& receiver() {
+ return receiver_;
+ }
+
+ void Trace(Visitor* visitor) { visitor->Trace(receiver_); }
+
+ private:
+ // sample::blink::Service implementation
+ void Frobinate(sample::blink::FooPtr foo,
+ sample::blink::Service::BazOptions options,
+ mojo::PendingRemote<sample::blink::Port> port,
+ sample::blink::Service::FrobinateCallback callback) override {}
+ void GetPort(mojo::PendingReceiver<sample::blink::Port> port) override {}
+
+ HeapMojoReceiver<sample::blink::Service, Mode> receiver_;
+};
+
+template <HeapMojoWrapperMode Mode>
+class HeapMojoReceiverGCBaseTest : 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<ReceiverOwner<Mode>>(context_);
+ scoped_refptr<base::NullTaskRunner> null_task_runner =
+ base::MakeRefCounted<base::NullTaskRunner>();
+ remote_ = mojo::Remote<sample::blink::Service>(
+ owner_->receiver().BindNewPipeAndPassRemote(null_task_runner));
+ remote_.set_disconnect_handler(WTF::Bind(
+ [](HeapMojoReceiverGCBaseTest* receiver_test) {
+ receiver_test->run_loop().Quit();
+ receiver_test->disconnected() = true;
+ },
+ WTF::Unretained(this)));
+ }
+ void TearDown() override { CHECK(disconnected_); }
+
+ Persistent<MockContext> context_;
+ Persistent<ReceiverOwner<Mode>> owner_;
+ base::RunLoop run_loop_;
+ mojo::Remote<sample::blink::Service> remote_;
+ bool disconnected_ = false;
+};
+
+template <HeapMojoWrapperMode Mode>
+class HeapMojoReceiverDestroyContextBaseTest : public TestSupportingGC {
+ protected:
+ void SetUp() override {
+ context_ = MakeGarbageCollected<MockContext>();
+ owner_ = MakeGarbageCollected<ReceiverOwner<Mode>>(context_);
+ scoped_refptr<base::NullTaskRunner> null_task_runner =
+ base::MakeRefCounted<base::NullTaskRunner>();
+ remote_ = mojo::Remote<sample::blink::Service>(
+ owner_->receiver().BindNewPipeAndPassRemote(null_task_runner));
+ }
+
+ Persistent<MockContext> context_;
+ Persistent<ReceiverOwner<Mode>> owner_;
+ mojo::Remote<sample::blink::Service> remote_;
+};
+
+} // namespace
+
+class HeapMojoReceiverGCWithContextObserverTest
+ : public HeapMojoReceiverGCBaseTest<
+ HeapMojoWrapperMode::kWithContextObserver> {};
+class HeapMojoReceiverGCWithoutContextObserverTest
+ : public HeapMojoReceiverGCBaseTest<
+ HeapMojoWrapperMode::kWithoutContextObserver> {};
+class HeapMojoReceiverDestroyContextWithContextObserverTest
+ : public HeapMojoReceiverDestroyContextBaseTest<
+ HeapMojoWrapperMode::kWithContextObserver> {};
+class HeapMojoReceiverDestroyContextWithoutContextObserverTest
+ : public HeapMojoReceiverDestroyContextBaseTest<
+ HeapMojoWrapperMode::kWithoutContextObserver> {};
+
+// Make HeapMojoReceiver with context observer garbage collected and check that
+// the connection is disconnected right after the marking phase.
+TEST_F(HeapMojoReceiverGCWithContextObserverTest, ResetsOnGC) {
+ ClearOwner();
+ EXPECT_FALSE(disconnected());
+ PreciselyCollectGarbage();
+ run_loop().Run();
+ EXPECT_TRUE(disconnected());
+ CompleteSweepingIfNeeded();
+}
+
+// Make HeapMojoReceiver without context observer garbage collected and check
+// that the connection is disconnected right after the marking phase.
+TEST_F(HeapMojoReceiverGCWithoutContextObserverTest, ResetsOnGC) {
+ ClearOwner();
+ EXPECT_FALSE(disconnected());
+ PreciselyCollectGarbage();
+ run_loop().Run();
+ EXPECT_TRUE(disconnected());
+ CompleteSweepingIfNeeded();
+}
+
+// Destroy the context with context observer and check that the connection is
+// disconnected.
+TEST_F(HeapMojoReceiverDestroyContextWithContextObserverTest,
+ ResetsOnContextDestroyed) {
+ 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,
+ ResetsOnContextDestroyed) {
+ EXPECT_TRUE(owner_->receiver().is_bound());
+ context_->NotifyContextDestroyed();
+ EXPECT_TRUE(owner_->receiver().is_bound());
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..dd5da3c5d23
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_remote.h
@@ -0,0 +1,95 @@
+// 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_HEAP_MOJO_REMOTE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_HEAP_MOJO_REMOTE_H_
+
+#include <utility>
+
+#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/heap_mojo_wrapper_mode.h"
+
+namespace blink {
+
+// HeapMojoRemote is a wrapper for mojo::Remote to be owned by a
+// 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.
+
+// TODO(crbug.com/1058076) HeapMojoWrapperMode should be removed once we ensure
+// that the interface is not used after ContextDestroyed().
+template <typename Interface,
+ HeapMojoWrapperMode Mode = HeapMojoWrapperMode::kWithContextObserver>
+class HeapMojoRemote {
+ DISALLOW_NEW();
+
+ public:
+ explicit HeapMojoRemote(ContextLifecycleNotifier* notifier)
+ : wrapper_(MakeGarbageCollected<Wrapper>(notifier)) {}
+
+ // Methods to redirect to mojo::Remote.
+ using Proxy = typename Interface::Proxy_;
+ Proxy* operator->() const { return get(); }
+ Proxy* get() const { return wrapper_->remote().get(); }
+ bool is_bound() const { return wrapper_->remote().is_bound(); }
+ bool is_connected() const { return wrapper_->remote().is_connected(); }
+ void reset() { wrapper_->remote().reset(); }
+ void set_disconnect_handler(base::OnceClosure handler) {
+ wrapper_->remote().set_disconnect_handler(std::move(handler));
+ }
+ mojo::PendingReceiver<Interface> BindNewPipeAndPassReceiver(
+ scoped_refptr<base::SequencedTaskRunner> task_runner) WARN_UNUSED_RESULT {
+ DCHECK(task_runner);
+ return wrapper_->remote().BindNewPipeAndPassReceiver(
+ std::move(task_runner));
+ }
+ void Bind(mojo::PendingRemote<Interface> pending_remote,
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
+ DCHECK(task_runner);
+ wrapper_->remote().Bind(std::move(pending_remote), std::move(task_runner));
+ }
+ void FlushForTesting() { return wrapper_->remote().FlushForTesting(); }
+
+ void Trace(Visitor* visitor) { visitor->Trace(wrapper_); }
+
+ private:
+ // Garbage collected wrapper class to add a prefinalizer.
+ class Wrapper final : public GarbageCollected<Wrapper>,
+ public ContextLifecycleObserver {
+ USING_PRE_FINALIZER(Wrapper, Dispose);
+ USING_GARBAGE_COLLECTED_MIXIN(Wrapper);
+
+ public:
+ explicit Wrapper(ContextLifecycleNotifier* notifier) {
+ SetContextLifecycleNotifier(notifier);
+ }
+
+ void Trace(Visitor* visitor) override {
+ ContextLifecycleObserver::Trace(visitor);
+ }
+
+ void Dispose() { remote_.reset(); }
+
+ mojo::Remote<Interface>& remote() { return remote_; }
+
+ // ContextLifecycleObserver methods
+ void ContextDestroyed() override {
+ if (Mode == HeapMojoWrapperMode::kWithContextObserver)
+ remote_.reset();
+ }
+
+ private:
+ mojo::Remote<Interface> remote_;
+ };
+
+ Member<Wrapper> wrapper_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_HEAP_MOJO_REMOTE_H_
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
new file mode 100644
index 00000000000..5af34d07ac9
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_remote_test.cc
@@ -0,0 +1,181 @@
+
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
+#include "base/test/null_task_runner.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"
+#include "third_party/blink/renderer/platform/context_lifecycle_notifier.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_observer_list.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
+
+namespace blink {
+
+namespace {
+
+class MockContext final : public GarbageCollected<MockContext>,
+ public ContextLifecycleNotifier {
+ USING_GARBAGE_COLLECTED_MIXIN(MockContext);
+
+ public:
+ MockContext() = default;
+
+ void AddContextLifecycleObserver(
+ ContextLifecycleObserver* observer) override {
+ observers_.AddObserver(observer);
+ }
+ void RemoveContextLifecycleObserver(
+ ContextLifecycleObserver* observer) override {
+ observers_.RemoveObserver(observer);
+ }
+
+ void NotifyContextDestroyed() {
+ observers_.ForEachObserver([](ContextLifecycleObserver* observer) {
+ observer->ContextDestroyed();
+ });
+ }
+
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(observers_);
+ ContextLifecycleNotifier::Trace(visitor);
+ }
+
+ private:
+ HeapObserverList<ContextLifecycleObserver> observers_;
+};
+
+class ServiceImpl : public sample::blink::Service {
+ public:
+ explicit ServiceImpl() = default;
+
+ mojo::Receiver<sample::blink::Service>& receiver() { return receiver_; }
+
+ private:
+ // sample::blink::Service implementation
+ void Frobinate(sample::blink::FooPtr foo,
+ sample::blink::Service::BazOptions options,
+ mojo::PendingRemote<sample::blink::Port> port,
+ sample::blink::Service::FrobinateCallback callback) override {}
+ void GetPort(mojo::PendingReceiver<sample::blink::Port> port) override {}
+
+ mojo::Receiver<sample::blink::Service> receiver_{this};
+};
+
+template <HeapMojoWrapperMode Mode>
+class RemoteOwner : public GarbageCollected<RemoteOwner<Mode>> {
+ public:
+ explicit RemoteOwner(MockContext* context) : remote_(context) {}
+
+ HeapMojoRemote<sample::blink::Service, Mode>& remote() { return remote_; }
+
+ void Trace(Visitor* visitor) { 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 {
+ 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));
+ }
+
+ ServiceImpl impl_;
+ Persistent<MockContext> context_;
+ Persistent<RemoteOwner<Mode>> owner_;
+};
+
+} // 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> {};
+
+// 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();
+}
+
+// Destroy the context with context observer and check that the connection is
+// disconnected.
+TEST_F(HeapMojoRemoteDestroyContextWithContextObserverTest,
+ ResetsOnContextDestroyed) {
+ 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,
+ ResetsOnContextDestroyed) {
+ EXPECT_TRUE(owner_->remote().is_bound());
+ context_->NotifyContextDestroyed();
+ EXPECT_TRUE(owner_->remote().is_bound());
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..8479bf54e25
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set.h
@@ -0,0 +1,96 @@
+// 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_HEAP_MOJO_UNIQUE_RECEIVER_SET_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_HEAP_MOJO_UNIQUE_RECEIVER_SET_H_
+
+#include "mojo/public/cpp/bindings/receiver.h"
+#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/heap_mojo_wrapper_mode.h"
+
+namespace blink {
+
+// HeapMojoUniqueReceiverSet is a wrapper for mojo::UniqueReceiverSet to be
+// owned by a garbage-collected object. Blink is expected to use
+// 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.
+template <typename Interface,
+ typename Deleter = std::default_delete<Interface>,
+ HeapMojoWrapperMode Mode = HeapMojoWrapperMode::kWithContextObserver>
+class HeapMojoUniqueReceiverSet {
+ DISALLOW_NEW();
+
+ public:
+ using ImplPointerType = typename mojo::Receiver<
+ Interface,
+ mojo::UniquePtrImplRefTraits<Interface, Deleter>>::ImplPointerType;
+
+ explicit HeapMojoUniqueReceiverSet(ContextLifecycleNotifier* context)
+ : wrapper_(MakeGarbageCollected<Wrapper>(context)) {
+ DCHECK(context);
+ }
+
+ // Methods to redirect to mojo::ReceiverSet:
+ mojo::ReceiverId Add(ImplPointerType impl,
+ mojo::PendingReceiver<Interface> receiver,
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
+ return wrapper_->receiver_set().Add(std::move(impl), std::move(receiver),
+ task_runner);
+ }
+
+ bool Remove(mojo::ReceiverId id) {
+ return wrapper_->receiver_set().Remove(id);
+ }
+
+ void Clear() { wrapper_->receiver_set().Clear(); }
+
+ bool HasReceiver(mojo::ReceiverId id) {
+ return wrapper_->receiver_set().HasReceiver(id);
+ }
+
+ void Trace(Visitor* visitor) { visitor->Trace(wrapper_); }
+
+ private:
+ // Garbage collected wrapper class to add a prefinalizer.
+ class Wrapper final : public GarbageCollected<Wrapper>,
+ public ContextLifecycleObserver {
+ USING_PRE_FINALIZER(Wrapper, Dispose);
+ USING_GARBAGE_COLLECTED_MIXIN(Wrapper);
+
+ public:
+ explicit Wrapper(ContextLifecycleNotifier* notifier) {
+ SetContextLifecycleNotifier(notifier);
+ }
+
+ void Trace(Visitor* visitor) 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)
+ receiver_set_.Clear();
+ }
+
+ private:
+ mojo::UniqueReceiverSet<Interface, void, Deleter> receiver_set_;
+ };
+
+ Member<Wrapper> wrapper_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_HEAP_MOJO_UNIQUE_RECEIVER_SET_H_
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
new file mode 100644
index 00000000000..5438160d598
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set_test.cc
@@ -0,0 +1,214 @@
+// 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/heap_mojo_unique_receiver_set.h"
+#include "base/test/null_task_runner.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"
+#include "third_party/blink/renderer/platform/context_lifecycle_notifier.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_observer_list.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
+
+namespace blink {
+
+namespace {
+
+class FakeContextNotifier final : public GarbageCollected<FakeContextNotifier>,
+ public ContextLifecycleNotifier {
+ USING_GARBAGE_COLLECTED_MIXIN(FakeContextNotifier);
+
+ public:
+ FakeContextNotifier() = default;
+
+ void AddContextLifecycleObserver(
+ ContextLifecycleObserver* observer) override {
+ observers_.AddObserver(observer);
+ }
+ void RemoveContextLifecycleObserver(
+ ContextLifecycleObserver* observer) override {
+ observers_.RemoveObserver(observer);
+ }
+
+ void NotifyContextDestroyed() {
+ observers_.ForEachObserver([](ContextLifecycleObserver* observer) {
+ observer->ContextDestroyed();
+ });
+ }
+
+ void Trace(Visitor* visitor) override {
+ visitor->Trace(observers_);
+ ContextLifecycleNotifier::Trace(visitor);
+ }
+
+ private:
+ HeapObserverList<ContextLifecycleObserver> observers_;
+};
+
+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_); }
+
+ HeapMojoUniqueReceiverSet<sample::blink::Service,
+ std::default_delete<sample::blink::Service>,
+ Mode>&
+ receiver_set() {
+ return receiver_set_;
+ }
+
+ private:
+ HeapMojoUniqueReceiverSet<sample::blink::Service,
+ std::default_delete<sample::blink::Service>,
+ Mode>
+ receiver_set_;
+};
+
+template <HeapMojoWrapperMode Mode>
+class HeapMojoUniqueReceiverSetBaseTest : public TestSupportingGC {
+ public:
+ FakeContextNotifier* context() { return context_; }
+ scoped_refptr<base::NullTaskRunner> task_runner() {
+ return null_task_runner_;
+ }
+ GCOwner<Mode>* owner() { return owner_; }
+
+ void ClearOwner() { owner_ = nullptr; }
+
+ void MarkServiceDeleted() { service_deleted_ = true; }
+
+ protected:
+ void SetUp() override {
+ context_ = MakeGarbageCollected<FakeContextNotifier>();
+ owner_ = MakeGarbageCollected<GCOwner<Mode>>(context());
+ }
+ void TearDown() override {}
+
+ Persistent<FakeContextNotifier> context_;
+ Persistent<GCOwner<Mode>> owner_;
+ scoped_refptr<base::NullTaskRunner> null_task_runner_ =
+ base::MakeRefCounted<base::NullTaskRunner>();
+ bool service_deleted_ = false;
+};
+
+class HeapMojoUniqueReceiverSetWithContextObserverTest
+ : public HeapMojoUniqueReceiverSetBaseTest<
+ HeapMojoWrapperMode::kWithContextObserver> {};
+class HeapMojoUniqueReceiverSetWithoutContextObserverTest
+ : public HeapMojoUniqueReceiverSetBaseTest<
+ HeapMojoWrapperMode::kWithoutContextObserver> {};
+
+} // namespace
+
+namespace {
+
+template <typename T>
+class MockService : public sample::blink::Service {
+ public:
+ explicit MockService(T* test) : test_(test) {}
+ // Notify the test when the service is deleted by the UniqueReceiverSet.
+ ~MockService() override { test_->MarkServiceDeleted(); }
+
+ void Frobinate(sample::blink::FooPtr foo,
+ Service::BazOptions baz,
+ mojo::PendingRemote<sample::blink::Port> port,
+ FrobinateCallback callback) override {}
+ void GetPort(mojo::PendingReceiver<sample::blink::Port> receiver) override {}
+
+ private:
+ T* test_;
+};
+
+} // 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,
+ ResetsOnContextDestroyed) {
+ HeapMojoUniqueReceiverSet<sample::blink::Service> receiver_set(context());
+ 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_);
+
+ context_->NotifyContextDestroyed();
+
+ EXPECT_FALSE(receiver_set.HasReceiver(rid));
+ EXPECT_TRUE(service_deleted_);
+}
+
+// Destroy the context without context observer and verify that the receiver is
+// no longer part of the set, and that the service was deleted.
+TEST_F(HeapMojoUniqueReceiverSetWithoutContextObserverTest,
+ ResetsOnContextDestroyed) {
+ HeapMojoUniqueReceiverSet<sample::blink::Service> receiver_set(context());
+ 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_);
+
+ context_->NotifyContextDestroyed();
+
+ EXPECT_FALSE(receiver_set.HasReceiver(rid));
+ EXPECT_TRUE(service_deleted_);
+}
+
+} // namespace blink
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
new file mode 100644
index 00000000000..f59f0e0e8dc
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h
@@ -0,0 +1,25 @@
+// 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_HEAP_MOJO_WRAPPER_MODE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_HEAP_MOJO_WRAPPER_MODE_H_
+
+namespace blink {
+
+// A list of modes for HeapMojo wrappers.
+// TODO(crbug.com/1058076) This is just a temporary thing to keep the existing
+// behavior during the release freeze.
+enum class HeapMojoWrapperMode {
+ // Resets the mojo connection when 1) the owner object is garbage-collected
+ // and 2) the associated ExecutionContext is detached.
+ kWithContextObserver,
+ // Resets the mojo connection when the owner object is garbage-collected.
+ // But, it will not reset the mojo connection when the associated
+ // ExecutionContext is detached.
+ kWithoutContextObserver,
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_HEAP_MOJO_WRAPPER_MODE_H_
diff --git a/chromium/third_party/blink/renderer/platform/mojo/kurl.typemap b/chromium/third_party/blink/renderer/platform/mojo/kurl.typemap
deleted file mode 100644
index 8a25d18986b..00000000000
--- a/chromium/third_party/blink/renderer/platform/mojo/kurl.typemap
+++ /dev/null
@@ -1,18 +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.
-
-mojom = "//url/mojom/url.mojom"
-public_headers = [
- "//third_party/blink/renderer/platform/weborigin/kurl.h",
- "//third_party/blink/renderer/platform/weborigin/kurl_hash.h",
-]
-traits_headers =
- [ "//third_party/blink/renderer/platform/mojo/kurl_mojom_traits.h" ]
-
-# Note: consumers of this typemap must themselves depend on platform.
-deps = [
- "//mojo/public/cpp/bindings",
- "//url",
-]
-type_mappings = [ "url.mojom.Url=::blink::KURL[force_serialize]" ]
diff --git a/chromium/third_party/blink/renderer/platform/mojo/kurl_mojom_traits.h b/chromium/third_party/blink/renderer/platform/mojo/kurl_mojom_traits.h
index bcd6a69e8df..f50dd8444e6 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/kurl_mojom_traits.h
+++ b/chromium/third_party/blink/renderer/platform/mojo/kurl_mojom_traits.h
@@ -5,15 +5,16 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_KURL_MOJOM_TRAITS_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_KURL_MOJOM_TRAITS_H_
+#include "mojo/public/cpp/bindings/string_traits_wtf.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-#include "url/mojom/url.mojom-blink-forward.h"
+#include "url/mojom/url.mojom-shared.h"
#include "url/url_constants.h"
namespace mojo {
template <>
-struct StructTraits<url::mojom::blink::Url::DataView, ::blink::KURL> {
+struct StructTraits<url::mojom::UrlDataView, ::blink::KURL> {
static WTF::String url(const ::blink::KURL& blinkUrl) {
if (!blinkUrl.IsValid() ||
blinkUrl.GetString().length() > url::kMaxURLChars) {
@@ -22,7 +23,7 @@ struct StructTraits<url::mojom::blink::Url::DataView, ::blink::KURL> {
return blinkUrl.GetString();
}
- static bool Read(url::mojom::blink::Url::DataView data, ::blink::KURL* out) {
+ static bool Read(url::mojom::UrlDataView data, ::blink::KURL* out) {
WTF::String urlString;
if (!data.ReadUrl(&urlString))
return false;
diff --git a/chromium/third_party/blink/renderer/platform/mojo/security_origin.typemap b/chromium/third_party/blink/renderer/platform/mojo/security_origin.typemap
deleted file mode 100644
index f94a2bb7732..00000000000
--- a/chromium/third_party/blink/renderer/platform/mojo/security_origin.typemap
+++ /dev/null
@@ -1,17 +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.
-
-mojom = "//url/mojom/origin.mojom"
-public_headers =
- [ "//third_party/blink/renderer/platform/weborigin/security_origin.h" ]
-traits_headers = [
- "//third_party/blink/renderer/platform/mojo/security_origin_mojom_traits.h",
-]
-
-# Note: consumers of this typemap must themselves depend on platform.
-deps = [
- "//mojo/public/cpp/bindings",
- "//url",
-]
-type_mappings = [ "url.mojom.Origin=::scoped_refptr<const ::blink::SecurityOrigin>[nullable_is_same_type]" ]
diff --git a/chromium/third_party/blink/renderer/platform/mojo/security_origin_mojom_traits.h b/chromium/third_party/blink/renderer/platform/mojo/security_origin_mojom_traits.h
index 386bc631ecd..925965d09b5 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/security_origin_mojom_traits.h
+++ b/chromium/third_party/blink/renderer/platform/mojo/security_origin_mojom_traits.h
@@ -5,10 +5,12 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_SECURITY_ORIGIN_MOJOM_TRAITS_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_SECURITY_ORIGIN_MOJOM_TRAITS_H_
+#include "mojo/public/cpp/base/unguessable_token_mojom_traits.h"
+#include "mojo/public/cpp/bindings/string_traits_wtf.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/wtf_string.h"
-#include "url/mojom/origin.mojom-blink-forward.h"
+#include "url/mojom/origin.mojom-shared.h"
#include "url/scheme_host_port.h"
namespace mojo {
@@ -22,7 +24,7 @@ struct UrlOriginAdapter {
const url::SchemeHostPort& tuple,
const base::Optional<base::UnguessableToken>& nonce_if_opaque) {
scoped_refptr<blink::SecurityOrigin> tuple_origin;
- if (!tuple.IsInvalid()) {
+ if (tuple.IsValid()) {
// url::SchemeHostPort is percent encoded and SecurityOrigin is percent
// decoded.
String host = blink::DecodeURLEscapeSequences(
@@ -45,7 +47,7 @@ struct UrlOriginAdapter {
};
template <>
-struct StructTraits<url::mojom::blink::Origin::DataView,
+struct StructTraits<url::mojom::OriginDataView,
scoped_refptr<const ::blink::SecurityOrigin>> {
static WTF::String scheme(
const scoped_refptr<const ::blink::SecurityOrigin>& origin) {
@@ -65,7 +67,7 @@ struct StructTraits<url::mojom::blink::Origin::DataView,
const scoped_refptr<const ::blink::SecurityOrigin>& origin) {
return UrlOriginAdapter::nonce_if_opaque(origin);
}
- static bool Read(url::mojom::blink::Origin::DataView data,
+ static bool Read(url::mojom::OriginDataView data,
scoped_refptr<const ::blink::SecurityOrigin>* out) {
// This implementation is very close to
// SecurityOrigin::CreateFromUrlOrigin, so keep in sync if modifications
@@ -79,7 +81,7 @@ struct StructTraits<url::mojom::blink::Origin::DataView,
const url::SchemeHostPort& tuple =
url::SchemeHostPort(scheme, host, data.port());
- if (tuple.IsInvalid()) {
+ if (!tuple.IsValid()) {
// If the tuple is invalid, it is a valid case if and only if it is an
// opaque origin and the scheme, host, and port are empty.
if (!nonce_if_opaque)
diff --git a/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits_test.cc b/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits_test.cc
index 07be8469c2d..9efcde17184 100644
--- a/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits_test.cc
+++ b/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits_test.cc
@@ -7,7 +7,6 @@
#include "base/macros.h"
#include "base/rand_util.h"
#include "mojo/public/cpp/base/big_buffer_mojom_traits.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
#include "mojo/public/cpp/test_support/test_utils.h"
#include "mojo/public/mojom/base/string16.mojom-blink.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/third_party/blink/renderer/platform/network/BUILD.gn b/chromium/third_party/blink/renderer/platform/network/BUILD.gn
index 2bc375f8c61..983c4aba408 100644
--- a/chromium/third_party/blink/renderer/platform/network/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/network/BUILD.gn
@@ -18,9 +18,7 @@ group("make_generated") {
"//third_party/blink/renderer/platform:*",
]
- public_deps = [
- ":http_names",
- ]
+ public_deps = [ ":http_names" ]
}
blink_platform_sources("network") {
@@ -41,6 +39,7 @@ blink_platform_sources("network") {
"header_field_tokenizer.h",
"http_header_map.cc",
"http_header_map.h",
+ "http_header_set.h",
"http_parsers.cc",
"http_parsers.h",
"http_request_headers_mojom_traits.cc",
@@ -69,9 +68,7 @@ blink_platform_sources("network") {
sources += get_target_outputs(":http_names")
- deps = [
- "//media",
- ]
+ deps = [ "//media" ]
}
jumbo_source_set("unit_tests") {
@@ -91,21 +88,15 @@ jumbo_source_set("unit_tests") {
configs += [ "//third_party/blink/renderer/platform:blink_platform_config" ]
- deps = [
- "//testing/gtest",
- ]
- public_deps = [
- "//third_party/blink/renderer/platform:platform",
- ]
+ deps = [ "//testing/gtest" ]
+ public_deps = [ "//third_party/blink/renderer/platform:platform" ]
}
jumbo_source_set("test_support") {
visibility = [ "//third_party/blink/renderer/platform:test_support" ]
testonly = true
- sources = [
- "mime/mock_mime_registry.h",
- ]
+ sources = [ "mime/mock_mime_registry.h" ]
configs += [
"//third_party/blink/renderer:non_test_config",
diff --git a/chromium/third_party/blink/renderer/platform/network/content_security_policy_parsers.cc b/chromium/third_party/blink/renderer/platform/network/content_security_policy_parsers.cc
index 3d106e98802..212c2b97594 100644
--- a/chromium/third_party/blink/renderer/platform/network/content_security_policy_parsers.cc
+++ b/chromium/third_party/blink/renderer/platform/network/content_security_policy_parsers.cc
@@ -5,7 +5,6 @@
#include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h"
#include "services/network/public/mojom/content_security_policy.mojom-blink.h"
-#include "third_party/blink/public/platform/web_content_security_policy.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/text/ascii_ctype.h"
#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
@@ -58,16 +57,4 @@ bool IsMediaTypeCharacter(UChar c) {
return !IsASCIISpace(c) && c != '/';
}
-STATIC_ASSERT_ENUM(network::mojom::ContentSecurityPolicyType::kReport,
- kContentSecurityPolicyHeaderTypeReport);
-STATIC_ASSERT_ENUM(network::mojom::ContentSecurityPolicyType::kEnforce,
- kContentSecurityPolicyHeaderTypeEnforce);
-
-STATIC_ASSERT_ENUM(network::mojom::ContentSecurityPolicySource::kHTTP,
- kContentSecurityPolicyHeaderSourceHTTP);
-STATIC_ASSERT_ENUM(network::mojom::ContentSecurityPolicySource::kMeta,
- kContentSecurityPolicyHeaderSourceMeta);
-STATIC_ASSERT_ENUM(network::mojom::ContentSecurityPolicySource::kOriginPolicy,
- kContentSecurityPolicyHeaderSourceOriginPolicy);
-
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/network/content_security_policy_parsers.h b/chromium/third_party/blink/renderer/platform/network/content_security_policy_parsers.h
index e352fa904e3..4165e180916 100644
--- a/chromium/third_party/blink/renderer/platform/network/content_security_policy_parsers.h
+++ b/chromium/third_party/blink/renderer/platform/network/content_security_policy_parsers.h
@@ -13,17 +13,6 @@ namespace blink {
typedef std::pair<unsigned, DigestValue> CSPHashValue;
-enum ContentSecurityPolicyHeaderType {
- kContentSecurityPolicyHeaderTypeReport,
- kContentSecurityPolicyHeaderTypeEnforce
-};
-
-enum ContentSecurityPolicyHeaderSource {
- kContentSecurityPolicyHeaderSourceHTTP,
- kContentSecurityPolicyHeaderSourceMeta,
- kContentSecurityPolicyHeaderSourceOriginPolicy
-};
-
enum ContentSecurityPolicyHashAlgorithm {
kContentSecurityPolicyHashAlgorithmNone = 0,
kContentSecurityPolicyHashAlgorithmSha256 = 1 << 2,
diff --git a/chromium/third_party/blink/renderer/platform/network/encoded_form_data.cc b/chromium/third_party/blink/renderer/platform/network/encoded_form_data.cc
index 03a6c6d3aac..eb21bafdb1f 100644
--- a/chromium/third_party/blink/renderer/platform/network/encoded_form_data.cc
+++ b/chromium/third_party/blink/renderer/platform/network/encoded_form_data.cc
@@ -175,9 +175,11 @@ void EncodedFormData::AppendData(const void* data, wtf_size_t size) {
memcpy(e.data_.data() + old_size, data, size);
}
-void EncodedFormData::AppendFile(const String& filename) {
- elements_.push_back(
- FormDataElement(filename, 0, BlobData::kToEndOfFile, base::nullopt));
+void EncodedFormData::AppendFile(
+ const String& filename,
+ const base::Optional<base::Time>& expected_modification_time) {
+ elements_.push_back(FormDataElement(filename, 0, BlobData::kToEndOfFile,
+ expected_modification_time));
}
void EncodedFormData::AppendFileRange(
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 a3de079f0ce..cbb1eed257e 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
@@ -110,7 +110,8 @@ class PLATFORM_EXPORT EncodedFormData : public RefCounted<EncodedFormData> {
~EncodedFormData();
void AppendData(const void* data, wtf_size_t);
- void AppendFile(const String& file_path);
+ void AppendFile(const String& file_path,
+ const base::Optional<base::Time>& expected_modification_time);
void AppendFileRange(
const String& filename,
int64_t start,
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
index 4807a6de7a7..d95ad2f00f0 100644
--- 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
@@ -18,7 +18,6 @@
#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/interface_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/network/wrapped_data_pipe_getter.h"
diff --git a/chromium/third_party/blink/renderer/platform/network/http_header_set.h b/chromium/third_party/blink/renderer/platform/network/http_header_set.h
new file mode 100644
index 00000000000..80a501f9dad
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/network/http_header_set.h
@@ -0,0 +1,24 @@
+// 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_PLATFORM_NETWORK_HTTP_HEADER_SET_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_HTTP_HEADER_SET_H_
+
+#include <set>
+#include <string>
+#include "base/strings/string_util.h"
+
+namespace blink {
+
+struct CompareIgnoreCase {
+ bool operator()(const std::string& left, const std::string& right) const {
+ return base::CompareCaseInsensitiveASCII(left, right) < 0;
+ }
+};
+
+using HTTPHeaderSet = std::set<std::string, CompareIgnoreCase>;
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_HTTP_HEADER_SET_H_
diff --git a/chromium/third_party/blink/renderer/platform/network/http_names.json5 b/chromium/third_party/blink/renderer/platform/network/http_names.json5
index 248c5e8a11c..fa2fda6cc0d 100644
--- a/chromium/third_party/blink/renderer/platform/network/http_names.json5
+++ b/chromium/third_party/blink/renderer/platform/network/http_names.json5
@@ -31,6 +31,8 @@
"Content-Security-Policy",
"Content-Security-Policy-Report-Only",
"Content-Type",
+ "Document-Policy",
+ "Document-Policy-Report-Only",
"ETag",
"Expires",
"Date",
@@ -51,11 +53,11 @@
"Ping-To",
"Pragma",
"Range",
- // TODO(domfarolino): Remove "Referer" as part of https://crbug.com/850813.
"Referer",
"Referrer-Policy",
"Refresh",
"Resource-Freshness",
+ "Require-Document-Policy",
"Save-Data",
"Sec-CH-Lang",
"Sec-Required-CSP",
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 9c376f04607..49218661ef4 100644
--- a/chromium/third_party/blink/renderer/platform/network/http_parsers.cc
+++ b/chromium/third_party/blink/renderer/platform/network/http_parsers.cc
@@ -409,17 +409,17 @@ CacheControlHeader ParseCacheControlDirectives(
for (wtf_size_t i = 0; i < directives_size; ++i) {
// RFC2616 14.9.1: A no-cache directive with a value is only meaningful
// for proxy caches. It should be ignored by a browser level cache.
- if (DeprecatedEqualIgnoringCase(directives[i].first, kNoCacheDirective) &&
+ if (EqualIgnoringASCIICase(directives[i].first, kNoCacheDirective) &&
directives[i].second.IsEmpty()) {
cache_control_header.contains_no_cache = true;
- } else if (DeprecatedEqualIgnoringCase(directives[i].first,
- kNoStoreDirective)) {
+ } else if (EqualIgnoringASCIICase(directives[i].first,
+ kNoStoreDirective)) {
cache_control_header.contains_no_store = true;
- } else if (DeprecatedEqualIgnoringCase(directives[i].first,
- kMustRevalidateDirective)) {
+ } else if (EqualIgnoringASCIICase(directives[i].first,
+ kMustRevalidateDirective)) {
cache_control_header.contains_must_revalidate = true;
- } else if (DeprecatedEqualIgnoringCase(directives[i].first,
- kMaxAgeDirective)) {
+ } else if (EqualIgnoringASCIICase(directives[i].first,
+ kMaxAgeDirective)) {
if (cache_control_header.max_age) {
// First max-age directive wins if there are multiple ones.
continue;
@@ -428,8 +428,8 @@ CacheControlHeader ParseCacheControlDirectives(
double max_age = directives[i].second.ToDouble(&ok);
if (ok)
cache_control_header.max_age = base::TimeDelta::FromSecondsD(max_age);
- } else if (DeprecatedEqualIgnoringCase(directives[i].first,
- kStaleWhileRevalidateDirective)) {
+ } else if (EqualIgnoringASCIICase(directives[i].first,
+ kStaleWhileRevalidateDirective)) {
if (cache_control_header.stale_while_revalidate) {
// First stale-while-revalidate directive wins if there are multiple
// ones.
diff --git a/chromium/third_party/blink/renderer/platform/network/mime/content_type.cc b/chromium/third_party/blink/renderer/platform/network/mime/content_type.cc
index 95072e109fa..5a3c8b0fa5e 100644
--- a/chromium/third_party/blink/renderer/platform/network/mime/content_type.cc
+++ b/chromium/third_party/blink/renderer/platform/network/mime/content_type.cc
@@ -32,35 +32,29 @@ namespace blink {
ContentType::ContentType(const String& content_type) : type_(content_type) {}
+static bool IsASCIIQuote(UChar c) {
+ return c == '"';
+}
+
String ContentType::Parameter(const String& parameter_name) const {
- String parameter_value;
- String stripped_type = type_.StripWhiteSpace();
+ Vector<String> parameters;
+ ParseParameters(parameters);
- // a MIME type can have one or more "param=value" after a semi-colon, and
- // separated from each other by semi-colons
- wtf_size_t semi = stripped_type.find(';');
- if (semi != kNotFound) {
- wtf_size_t start =
- stripped_type.FindIgnoringASCIICase(parameter_name, semi + 1);
- if (start != kNotFound) {
- start = stripped_type.find('=', start + parameter_name.length());
- if (start != kNotFound) {
- wtf_size_t quote = stripped_type.find('\"', start + 1);
- wtf_size_t end = stripped_type.find('\"', start + 2);
- if (quote != kNotFound && end != kNotFound) {
- start = quote;
- } else {
- end = stripped_type.find(';', start + 1);
- if (end == kNotFound)
- end = stripped_type.length();
- }
- parameter_value = stripped_type.Substring(start + 1, end - (start + 1))
- .StripWhiteSpace();
+ for (auto& parameter : parameters) {
+ String stripped_parameter = parameter.StripWhiteSpace();
+ wtf_size_t separator_pos = stripped_parameter.find('=');
+ if (separator_pos != kNotFound) {
+ String attribute =
+ stripped_parameter.Left(separator_pos).StripWhiteSpace();
+ if (EqualIgnoringASCIICase(attribute, parameter_name)) {
+ return stripped_parameter.Substring(separator_pos + 1)
+ .StripWhiteSpace()
+ .RemoveCharacters(IsASCIIQuote);
}
}
}
- return parameter_value;
+ return String();
}
String ContentType::GetType() const {
@@ -74,4 +68,29 @@ String ContentType::GetType() const {
return stripped_type;
}
+void ContentType::ParseParameters(Vector<String>& result) const {
+ String stripped_type = type_.StripWhiteSpace();
+
+ unsigned cur_pos = 0;
+ unsigned end_pos = stripped_type.length();
+ unsigned start_pos = 0;
+ bool is_quote = false;
+
+ while (cur_pos < end_pos) {
+ if (!is_quote && stripped_type[cur_pos] == ';') {
+ if (cur_pos != start_pos) {
+ result.push_back(
+ stripped_type.Substring(start_pos, cur_pos - start_pos));
+ }
+ start_pos = cur_pos + 1;
+ } else if (stripped_type[cur_pos] == '"') {
+ is_quote = !is_quote;
+ }
+ cur_pos++;
+ }
+
+ if (start_pos != end_pos)
+ result.push_back(stripped_type.Substring(start_pos));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/network/mime/content_type.h b/chromium/third_party/blink/renderer/platform/network/mime/content_type.h
index e1d5bbc6a75..e02b0986537 100644
--- a/chromium/third_party/blink/renderer/platform/network/mime/content_type.h
+++ b/chromium/third_party/blink/renderer/platform/network/mime/content_type.h
@@ -44,6 +44,8 @@ class PLATFORM_EXPORT ContentType {
const String& Raw() const { return type_; }
private:
+ void ParseParameters(Vector<String>& result) const;
+
String type_;
};
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 9f56c4b2da6..e35ee692fe3 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
@@ -11,9 +11,9 @@
#include "mojo/public/cpp/bindings/remote.h"
#include "net/base/mime_util.h"
#include "third_party/blink/public/common/mime_util/mime_util.h"
+#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/mime/mime_registry.mojom-blink.h"
#include "third_party/blink/public/platform/file_path_conversion.h"
-#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -25,7 +25,7 @@ namespace {
struct MimeRegistryPtrHolder {
public:
MimeRegistryPtrHolder() {
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
mime_registry.BindNewPipeAndPassReceiver());
}
~MimeRegistryPtrHolder() = default;
@@ -193,7 +193,7 @@ bool MIMETypeRegistry::IsSupportedFontMIMEType(const String& mime_type) {
static const unsigned kFontLen = 5;
if (!mime_type.StartsWithIgnoringASCIICase("font/"))
return false;
- String sub_type = mime_type.Substring(kFontLen).DeprecatedLower();
+ String sub_type = mime_type.Substring(kFontLen).LowerASCII();
return sub_type == "woff" || sub_type == "woff2" || sub_type == "otf" ||
sub_type == "ttf" || sub_type == "sfnt";
}
diff --git a/chromium/third_party/blink/renderer/platform/p2p/OWNERS b/chromium/third_party/blink/renderer/platform/p2p/OWNERS
index 70573c449d9..eabc2b276ea 100644
--- a/chromium/third_party/blink/renderer/platform/p2p/OWNERS
+++ b/chromium/third_party/blink/renderer/platform/p2p/OWNERS
@@ -1,4 +1,5 @@
+guidou@chromium.org
sergeyu@chromium.org
-juberti@chromium.org
+steveanton@chromium.org
# COMPONENT: Blink>WebRTC
diff --git a/chromium/third_party/blink/renderer/platform/p2p/filtering_network_manager.cc b/chromium/third_party/blink/renderer/platform/p2p/filtering_network_manager.cc
index c5131f81207..d2407625650 100644
--- a/chromium/third_party/blink/renderer/platform/p2p/filtering_network_manager.cc
+++ b/chromium/third_party/blink/renderer/platform/p2p/filtering_network_manager.cc
@@ -6,22 +6,20 @@
#include <utility>
-#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/threading/thread_task_runner_handle.h"
#include "media/base/media_permission.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
FilteringNetworkManager::FilteringNetworkManager(
rtc::NetworkManager* network_manager,
- const GURL& requesting_origin,
media::MediaPermission* media_permission,
bool allow_mdns_obfuscation)
: network_manager_(network_manager),
media_permission_(media_permission),
- requesting_origin_(requesting_origin),
allow_mdns_obfuscation_(allow_mdns_obfuscation) {
DETACH_FROM_THREAD(thread_checker_);
set_enumeration_permission(ENUMERATION_BLOCKED);
@@ -117,12 +115,10 @@ void FilteringNetworkManager::CheckPermission() {
// Request for media permission asynchronously.
media_permission_->HasPermission(
media::MediaPermission::AUDIO_CAPTURE,
- base::BindOnce(&FilteringNetworkManager::OnPermissionStatus,
- GetWeakPtr()));
+ WTF::Bind(&FilteringNetworkManager::OnPermissionStatus, GetWeakPtr()));
media_permission_->HasPermission(
media::MediaPermission::VIDEO_CAPTURE,
- base::BindOnce(&FilteringNetworkManager::OnPermissionStatus,
- GetWeakPtr()));
+ WTF::Bind(&FilteringNetworkManager::OnPermissionStatus, GetWeakPtr()));
}
void FilteringNetworkManager::OnPermissionStatus(bool granted) {
@@ -210,9 +206,8 @@ void FilteringNetworkManager::FireEventIfStarted() {
//
// TODO(crbug.com/787254): Use Frame-based TaskRunner here.
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(&FilteringNetworkManager::SendNetworksChangedSignal,
- GetWeakPtr()));
+ FROM_HERE, WTF::Bind(&FilteringNetworkManager::SendNetworksChangedSignal,
+ GetWeakPtr()));
sent_first_update_ = true;
}
diff --git a/chromium/third_party/blink/renderer/platform/p2p/filtering_network_manager.h b/chromium/third_party/blink/renderer/platform/p2p/filtering_network_manager.h
index 1bc21566bab..8243e2f0046 100644
--- a/chromium/third_party/blink/renderer/platform/p2p/filtering_network_manager.h
+++ b/chromium/third_party/blink/renderer/platform/p2p/filtering_network_manager.h
@@ -13,7 +13,6 @@
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/webrtc/rtc_base/network.h"
#include "third_party/webrtc/rtc_base/third_party/sigslot/sigslot.h"
-#include "url/gurl.h"
namespace media {
class MediaPermission;
@@ -34,8 +33,6 @@ namespace blink {
// rtc::NetworkManagerBase to have the same implementation of
// GetAnyAddressNetworks(). We can't mark the whole class PLATFORM_EXPORT
// as it requires all super classes to be PLATFORM_EXPORT as well.
-//
-// TODO(crbug.com/787254): Also, move it away from url/gurl.h.
class FilteringNetworkManager : public rtc::NetworkManagerBase,
public sigslot::has_slots<> {
public:
@@ -43,7 +40,6 @@ class FilteringNetworkManager : public rtc::NetworkManagerBase,
// worker thread |task_runner|.
PLATFORM_EXPORT FilteringNetworkManager(
rtc::NetworkManager* network_manager,
- const GURL& requesting_origin,
media::MediaPermission* media_permission,
bool allow_mdns_obfuscation);
@@ -116,8 +112,6 @@ class FilteringNetworkManager : public rtc::NetworkManagerBase,
// the setup time.
base::TimeTicks start_updating_time_;
- GURL requesting_origin_;
-
// When the mDNS obfuscation is allowed, access to the mDNS responder provided
// by the base network manager is provided to conceal IPs with mDNS hostnames.
bool allow_mdns_obfuscation_ = true;
diff --git a/chromium/third_party/blink/renderer/platform/p2p/filtering_network_manager_test.cc b/chromium/third_party/blink/renderer/platform/p2p/filtering_network_manager_test.cc
index 6b2da1ad524..177722fa4ae 100644
--- a/chromium/third_party/blink/renderer/platform/p2p/filtering_network_manager_test.cc
+++ b/chromium/third_party/blink/renderer/platform/p2p/filtering_network_manager_test.cc
@@ -171,7 +171,7 @@ class FilteringNetworkManagerTest : public testing::Test,
SetNewNetworkForBaseNetworkManager();
if (multiple_routes_requested) {
network_manager_ = std::make_unique<FilteringNetworkManager>(
- base_network_manager_.get(), GURL(), media_permission_.get(),
+ base_network_manager_.get(), media_permission_.get(),
allow_mdns_obfuscation_);
network_manager_->Initialize();
} else {
diff --git a/chromium/third_party/blink/renderer/platform/p2p/host_address_request.cc b/chromium/third_party/blink/renderer/platform/p2p/host_address_request.cc
index eca457b7ee7..1e36c27d132 100644
--- a/chromium/third_party/blink/renderer/platform/p2p/host_address_request.cc
+++ b/chromium/third_party/blink/renderer/platform/p2p/host_address_request.cc
@@ -6,12 +6,12 @@
#include <utility>
-#include "base/bind.h"
#include "base/feature_list.h"
#include "base/location.h"
#include "jingle/glue/utils.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/platform/p2p/socket_dispatcher.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
@@ -19,7 +19,6 @@ namespace blink {
P2PAsyncAddressResolver::P2PAsyncAddressResolver(
P2PSocketDispatcher* dispatcher)
: dispatcher_(dispatcher), state_(STATE_CREATED) {
- AddRef(); // Balanced in Destroy().
}
P2PAsyncAddressResolver::~P2PAsyncAddressResolver() {
@@ -37,8 +36,8 @@ void P2PAsyncAddressResolver::Start(const rtc::SocketAddress& host_name,
blink::features::kWebRtcHideLocalIpsWithMdns);
dispatcher_->GetP2PSocketManager()->GetHostAddress(
String(host_name.hostname().data()), enable_mdns,
- base::BindOnce(&P2PAsyncAddressResolver::OnResponse,
- base::Unretained(this)));
+ WTF::Bind(&P2PAsyncAddressResolver::OnResponse,
+ scoped_refptr<P2PAsyncAddressResolver>(this)));
}
void P2PAsyncAddressResolver::Cancel() {
diff --git a/chromium/third_party/blink/renderer/platform/p2p/ipc_network_manager.cc b/chromium/third_party/blink/renderer/platform/p2p/ipc_network_manager.cc
index 1ac806df97a..8a125da49e4 100644
--- a/chromium/third_party/blink/renderer/platform/p2p/ipc_network_manager.cc
+++ b/chromium/third_party/blink/renderer/platform/p2p/ipc_network_manager.cc
@@ -8,7 +8,6 @@
#include <utility>
#include <vector>
-#include "base/bind.h"
#include "base/location.h"
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
@@ -19,6 +18,7 @@
#include "net/base/network_change_notifier.h"
#include "net/base/network_interfaces.h"
#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/webrtc/rtc_base/socket_address.h"
namespace blink {
@@ -62,8 +62,8 @@ void IpcNetworkManager::StartUpdating() {
if (network_list_received_) {
// Post a task to avoid reentrancy.
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(&IpcNetworkManager::SendNetworksChangedSignal,
- weak_factory_.GetWeakPtr()));
+ FROM_HERE, WTF::Bind(&IpcNetworkManager::SendNetworksChangedSignal,
+ weak_factory_.GetWeakPtr()));
} else {
VLOG(1) << "IpcNetworkManager::StartUpdating called; still waiting for "
"network list from browser process.";
diff --git a/chromium/third_party/blink/renderer/platform/p2p/ipc_socket_factory.cc b/chromium/third_party/blink/renderer/platform/p2p/ipc_socket_factory.cc
index a28777e90c0..57c834e7e52 100644
--- a/chromium/third_party/blink/renderer/platform/p2p/ipc_socket_factory.cc
+++ b/chromium/third_party/blink/renderer/platform/p2p/ipc_socket_factory.cc
@@ -9,12 +9,10 @@
#include <algorithm>
#include <list>
-#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
-#include "base/sequence_checker.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_checker.h"
#include "base/trace_event/trace_event.h"
@@ -25,6 +23,7 @@
#include "third_party/blink/renderer/platform/p2p/socket_client_delegate.h"
#include "third_party/blink/renderer/platform/p2p/socket_client_impl.h"
#include "third_party/blink/renderer/platform/p2p/socket_dispatcher.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "third_party/webrtc/rtc_base/async_packet_socket.h"
@@ -226,7 +225,7 @@ class AsyncAddressResolverImpl : public rtc::AsyncResolverInterface {
scoped_refptr<P2PAsyncAddressResolver> resolver_;
- SEQUENCE_CHECKER(sequence_checker_);
+ THREAD_CHECKER(thread_checker_);
rtc::SocketAddress addr_; // Address to resolve.
std::vector<rtc::IPAddress> addresses_; // Resolved addresses.
@@ -423,9 +422,8 @@ int IpcPacketSocket::SendTo(const void* data,
send_bytes_available_ -= data_size;
- const int8_t* data_char = reinterpret_cast<const int8_t*>(data);
Vector<int8_t> data_vector;
- data_vector.AppendRange(data_char, data_char + data_size);
+ data_vector.Append(reinterpret_cast<const int8_t*>(data), data_size);
uint64_t packet_id = client_->Send(address_chrome, data_vector, options);
// Ensure packet_id is not 0. It can't be the case according to
@@ -651,27 +649,26 @@ void IpcPacketSocket::OnDataReceived(const net::IPEndPoint& address,
AsyncAddressResolverImpl::AsyncAddressResolverImpl(
P2PSocketDispatcher* dispatcher)
- : resolver_(new P2PAsyncAddressResolver(dispatcher)) {}
+ : resolver_(base::MakeRefCounted<P2PAsyncAddressResolver>(dispatcher)) {}
AsyncAddressResolverImpl::~AsyncAddressResolverImpl() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
}
void AsyncAddressResolverImpl::Start(const rtc::SocketAddress& addr) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// Port and hostname must be copied to the resolved address returned from
// GetResolvedAddress.
addr_ = addr;
- resolver_->Start(addr,
- base::BindOnce(&AsyncAddressResolverImpl::OnAddressResolved,
- base::Unretained(this)));
+ resolver_->Start(addr, WTF::Bind(&AsyncAddressResolverImpl::OnAddressResolved,
+ WTF::Unretained(this)));
}
bool AsyncAddressResolverImpl::GetResolvedAddress(
int family,
rtc::SocketAddress* addr) const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (addresses_.empty())
return false;
@@ -687,12 +684,12 @@ bool AsyncAddressResolverImpl::GetResolvedAddress(
}
int AsyncAddressResolverImpl::GetError() const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return addresses_.empty() ? -1 : 0;
}
void AsyncAddressResolverImpl::Destroy(bool wait) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
resolver_->Cancel();
// Libjingle doesn't need this object any more and it's not going to delete
// it explicitly.
@@ -701,7 +698,7 @@ void AsyncAddressResolverImpl::Destroy(bool wait) {
void AsyncAddressResolverImpl::OnAddressResolved(
const Vector<net::IPAddress>& addresses) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
for (size_t i = 0; i < addresses.size(); ++i) {
rtc::SocketAddress socket_address;
if (!jingle_glue::IPEndPointToSocketAddress(
diff --git a/chromium/third_party/blink/renderer/platform/p2p/mdns_responder_adapter.cc b/chromium/third_party/blink/renderer/platform/p2p/mdns_responder_adapter.cc
index ffb14185658..3c725d7bd96 100644
--- a/chromium/third_party/blink/renderer/platform/p2p/mdns_responder_adapter.cc
+++ b/chromium/third_party/blink/renderer/platform/p2p/mdns_responder_adapter.cc
@@ -6,7 +6,6 @@
#include <string>
-#include "base/bind.h"
#include "jingle/glue/utils.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "net/base/ip_address.h"
@@ -14,6 +13,7 @@
#include "services/network/public/mojom/mdns_responder.mojom-blink.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/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/webrtc/rtc_base/ip_address.h"
@@ -56,14 +56,14 @@ void MdnsResponderAdapter::CreateNameForAddress(const rtc::IPAddress& addr,
NameCreatedCallback callback) {
shared_remote_client_->CreateNameForAddress(
jingle_glue::RtcIPAddressToNetIPAddress(addr),
- base::BindOnce(&OnNameCreatedForAddress, callback, addr));
+ WTF::Bind(&OnNameCreatedForAddress, callback, addr));
}
void MdnsResponderAdapter::RemoveNameForAddress(const rtc::IPAddress& addr,
NameRemovedCallback callback) {
shared_remote_client_->RemoveNameForAddress(
jingle_glue::RtcIPAddressToNetIPAddress(addr),
- base::BindOnce(&OnNameRemovedForAddress, callback));
+ WTF::Bind(&OnNameRemovedForAddress, callback));
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/p2p/socket_client_impl.cc b/chromium/third_party/blink/renderer/platform/p2p/socket_client_impl.cc
index cbf7777bd9d..eb405977fad 100644
--- a/chromium/third_party/blink/renderer/platform/p2p/socket_client_impl.cc
+++ b/chromium/third_party/blink/renderer/platform/p2p/socket_client_impl.cc
@@ -4,13 +4,13 @@
#include "third_party/blink/renderer/platform/p2p/socket_client_impl.h"
-#include "base/bind.h"
#include "base/location.h"
#include "base/time/time.h"
#include "crypto/random.h"
#include "services/network/public/cpp/p2p_param_traits.h"
#include "third_party/blink/renderer/platform/p2p/socket_client_delegate.h"
#include "third_party/blink/renderer/platform/p2p/socket_dispatcher.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace {
@@ -60,8 +60,8 @@ void P2PSocketClientImpl::Init(
type, local_address, network::P2PPortRange(min_port, max_port),
remote_address, receiver_.BindNewPipeAndPassRemote(),
socket_.BindNewPipeAndPassReceiver());
- receiver_.set_disconnect_handler(base::BindOnce(
- &P2PSocketClientImpl::OnConnectionError, base::Unretained(this)));
+ receiver_.set_disconnect_handler(WTF::Bind(
+ &P2PSocketClientImpl::OnConnectionError, WTF::Unretained(this)));
}
uint64_t P2PSocketClientImpl::Send(const net::IPEndPoint& address,
@@ -82,7 +82,7 @@ void P2PSocketClientImpl::SendWithPacketId(const net::IPEndPoint& address,
const Vector<int8_t>& data,
const rtc::PacketOptions& options,
uint64_t packet_id) {
- TRACE_EVENT_ASYNC_BEGIN0("p2p", "Send", packet_id);
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("p2p", "Send", packet_id);
socket_->Send(data, network::P2PPacketInfo(address, options, packet_id),
net::MutableNetworkTrafficAnnotationTag(traffic_annotation_));
@@ -143,8 +143,8 @@ void P2PSocketClientImpl::IncomingTcpConnection(
new_client->socket_.Bind(std::move(socket));
new_client->receiver_.Bind(std::move(client_receiver));
- new_client->receiver_.set_disconnect_handler(base::BindOnce(
- &P2PSocketClientImpl::OnConnectionError, base::Unretained(this)));
+ new_client->receiver_.set_disconnect_handler(WTF::Bind(
+ &P2PSocketClientImpl::OnConnectionError, WTF::Unretained(this)));
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (delegate_) {
diff --git a/chromium/third_party/blink/renderer/platform/p2p/socket_dispatcher.cc b/chromium/third_party/blink/renderer/platform/p2p/socket_dispatcher.cc
index 370e34ed1ac..6c3adda46f7 100644
--- a/chromium/third_party/blink/renderer/platform/p2p/socket_dispatcher.cc
+++ b/chromium/third_party/blink/renderer/platform/p2p/socket_dispatcher.cc
@@ -4,13 +4,14 @@
#include "third_party/blink/renderer/platform/p2p/socket_dispatcher.h"
-#include "base/bind.h"
#include "base/memory/scoped_refptr.h"
#include "services/network/public/cpp/p2p_param_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/renderer/platform/p2p/network_list_observer.h"
#include "third_party/blink/renderer/platform/p2p/socket_client_impl.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"
namespace blink {
@@ -24,10 +25,10 @@ P2PSocketDispatcher::~P2PSocketDispatcher() {}
void P2PSocketDispatcher::AddNetworkListObserver(
blink::NetworkListObserver* network_list_observer) {
network_list_observers_->AddObserver(network_list_observer);
- main_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&P2PSocketDispatcher::RequestNetworkEventsIfNecessary,
- this));
+ PostCrossThreadTask(
+ *main_task_runner_.get(), FROM_HERE,
+ CrossThreadBindOnce(&P2PSocketDispatcher::RequestNetworkEventsIfNecessary,
+ scoped_refptr<P2PSocketDispatcher>(this)));
}
void P2PSocketDispatcher::RemoveNetworkListObserver(
@@ -47,13 +48,14 @@ P2PSocketDispatcher::GetP2PSocketManager() {
mojo::SharedRemote<network::mojom::blink::P2PSocketManager>(
std::move(p2p_socket_manager));
p2p_socket_manager_.set_disconnect_handler(
- base::BindOnce(&P2PSocketDispatcher::OnConnectionError,
- base::Unretained(this)),
+ WTF::Bind(&P2PSocketDispatcher::OnConnectionError,
+ WTF::Unretained(this)),
main_task_runner_);
}
- main_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&P2PSocketDispatcher::RequestInterfaceIfNecessary, this));
+ PostCrossThreadTask(
+ *main_task_runner_.get(), FROM_HERE,
+ CrossThreadBindOnce(&P2PSocketDispatcher::RequestInterfaceIfNecessary,
+ scoped_refptr<P2PSocketDispatcher>(this)));
return p2p_socket_manager_.get();
}
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/DEPS b/chromium/third_party/blink/renderer/platform/peerconnection/DEPS
index 705fa3fe2c3..d6fd407fe98 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/DEPS
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/DEPS
@@ -14,10 +14,12 @@ include_rules = [
"+base/strings/string_split.h",
"+base/threading/thread_restrictions.h",
"+media/base",
+ "+media/capture/capture_switches.h",
"+media/media_buildflags.h",
"+media/video/gpu_video_accelerator_factories.h",
"+media/video/video_decode_accelerator.h",
"+media/video/h264_parser.h",
+ "+media/video/supported_video_decoder_config.h",
"+media/video/video_encode_accelerator.h",
"+third_party/blink/renderer/platform/bindings/script_wrappable.h",
"+third_party/blink/renderer/platform/heap",
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 6f841c8a270..d88a917ed73 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(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
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 86aa4a620e2..dd0ff33cf06 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(blink::Visitor* visitor) override {}
+ void Trace(Visitor* visitor) override {}
};
RtcDtmfSenderHandler(scoped_refptr<base::SingleThreadTaskRunner> main_thread,
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_audio_stream_transformer.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_audio_stream_transformer.cc
new file mode 100644
index 00000000000..18f46d1d094
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_audio_stream_transformer.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/platform/peerconnection/rtc_encoded_audio_stream_transformer.h"
+
+#include <utility>
+
+#include "base/memory/ptr_util.h"
+#include "base/single_thread_task_runner.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_scoped_refptr_cross_thread_copier.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/webrtc/api/frame_transformer_interface.h"
+#include "third_party/webrtc/rtc_base/ref_counted_object.h"
+
+namespace blink {
+
+namespace {
+
+// This delegate class exists to work around the fact that
+// RTCEncodedAudioStreamTransformer cannot derive from rtc::RefCountedObject
+// and post tasks referencing itself as an rtc::scoped_refptr. Instead,
+// RTCEncodedAudioStreamTransformer creates a delegate using
+// rtc::RefCountedObject and posts tasks referencing the delegate, which invokes
+// the RTCEncodedAudioStreamTransformer via callbacks.
+class RTCEncodedAudioStreamTransformerDelegate
+ : public webrtc::FrameTransformerInterface {
+ public:
+ RTCEncodedAudioStreamTransformerDelegate(
+ const base::WeakPtr<RTCEncodedAudioStreamTransformer>& transformer,
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner)
+ : transformer_(transformer),
+ main_task_runner_(std::move(main_task_runner)) {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ }
+
+ // webrtc::FrameTransformerInterface
+ void RegisterTransformedFrameCallback(
+ rtc::scoped_refptr<webrtc::TransformedFrameCallback>
+ send_frame_to_sink_callback) override {
+ PostCrossThreadTask(
+ *main_task_runner_, FROM_HERE,
+ CrossThreadBindOnce(
+ &RTCEncodedAudioStreamTransformer::RegisterTransformedFrameCallback,
+ transformer_, std::move(send_frame_to_sink_callback)));
+ }
+
+ void UnregisterTransformedFrameCallback() override {
+ PostCrossThreadTask(
+ *main_task_runner_, FROM_HERE,
+ CrossThreadBindOnce(&RTCEncodedAudioStreamTransformer::
+ UnregisterTransformedFrameCallback,
+ transformer_));
+ }
+
+ void Transform(
+ std::unique_ptr<webrtc::TransformableFrameInterface> frame) override {
+ auto audio_frame = base::WrapUnique(
+ static_cast<webrtc::TransformableFrameInterface*>(frame.release()));
+ PostCrossThreadTask(
+ *main_task_runner_, FROM_HERE,
+ CrossThreadBindOnce(&RTCEncodedAudioStreamTransformer::TransformFrame,
+ transformer_, std::move(audio_frame)));
+ }
+
+ private:
+ base::WeakPtr<RTCEncodedAudioStreamTransformer> transformer_;
+ const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+};
+
+} // namespace
+
+RTCEncodedAudioStreamTransformer::RTCEncodedAudioStreamTransformer(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) {
+ DCHECK(main_task_runner->BelongsToCurrentThread());
+ delegate_ =
+ new rtc::RefCountedObject<RTCEncodedAudioStreamTransformerDelegate>(
+ weak_factory_.GetWeakPtr(), std::move(main_task_runner));
+}
+
+void RTCEncodedAudioStreamTransformer::RegisterTransformedFrameCallback(
+ rtc::scoped_refptr<webrtc::TransformedFrameCallback> callback) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ send_frame_to_sink_cb_ = callback;
+}
+
+void RTCEncodedAudioStreamTransformer::UnregisterTransformedFrameCallback() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ send_frame_to_sink_cb_ = nullptr;
+}
+
+void RTCEncodedAudioStreamTransformer::TransformFrame(
+ std::unique_ptr<webrtc::TransformableFrameInterface> frame) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ // If no transformer callback has been set, drop the frame.
+ if (!transformer_callback_)
+ return;
+
+ transformer_callback_.Run(std::move(frame));
+}
+
+void RTCEncodedAudioStreamTransformer::SendFrameToSink(
+ std::unique_ptr<webrtc::TransformableFrameInterface> frame) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ if (send_frame_to_sink_cb_)
+ send_frame_to_sink_cb_->OnTransformedFrame(std::move(frame));
+}
+
+void RTCEncodedAudioStreamTransformer::SetTransformerCallback(
+ TransformerCallback callback) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ transformer_callback_ = std::move(callback);
+}
+
+void RTCEncodedAudioStreamTransformer::ResetTransformerCallback() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ transformer_callback_.Reset();
+}
+
+bool RTCEncodedAudioStreamTransformer::HasTransformerCallback() const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return !transformer_callback_.is_null();
+}
+
+bool RTCEncodedAudioStreamTransformer::HasTransformedFrameCallback() const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return !!send_frame_to_sink_cb_;
+}
+
+rtc::scoped_refptr<webrtc::FrameTransformerInterface>
+RTCEncodedAudioStreamTransformer::Delegate() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return delegate_;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_audio_stream_transformer.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_audio_stream_transformer.h
new file mode 100644
index 00000000000..f1beece05fd
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_audio_stream_transformer.h
@@ -0,0 +1,84 @@
+// 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_PEERCONNECTION_RTC_ENCODED_AUDIO_STREAM_TRANSFORMER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_ENCODED_AUDIO_STREAM_TRANSFORMER_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/thread_checker.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/webrtc/api/scoped_refptr.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+} // namespace base
+
+namespace webrtc {
+class FrameTransformerInterface;
+class TransformedFrameCallback;
+class TransformableFrameInterface;
+} // namespace webrtc
+
+namespace blink {
+
+class PLATFORM_EXPORT RTCEncodedAudioStreamTransformer {
+ public:
+ using TransformerCallback = base::RepeatingCallback<void(
+ std::unique_ptr<webrtc::TransformableFrameInterface>)>;
+ explicit RTCEncodedAudioStreamTransformer(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner);
+
+ // Called by WebRTC to let us know about a callback object to send transformed
+ // frames to the WebRTC decoder. Runs on an internal WebRTC thread.
+ // The callback can run on any thread.
+ void RegisterTransformedFrameCallback(
+ rtc::scoped_refptr<webrtc::TransformedFrameCallback>);
+
+ // Called by WebRTC to let us know that any reference to the callback object
+ // reported by RegisterTransformedFrameCallback() should be released since
+ // the callback is no longer useful and is intended for destruction.
+ void UnregisterTransformedFrameCallback();
+
+ // Called by WebRTC to notify of new untransformed frames from the WebRTC
+ // stack. Runs on an internal WebRTC thread.
+ void TransformFrame(std::unique_ptr<webrtc::TransformableFrameInterface>);
+
+ // Send a transformed frame to the WebRTC sink. Must run on the main
+ // thread.
+ void SendFrameToSink(
+ std::unique_ptr<webrtc::TransformableFrameInterface> frame);
+
+ // Set a callback to be invoked on every untransformed frame. Must run on the
+ // main thread.
+ void SetTransformerCallback(TransformerCallback);
+
+ // Removes the callback
+ void ResetTransformerCallback();
+
+ // Returns true if a callback has been set with SetTransformerCallback(),
+ // false otherwise. Must run on the main thread.
+ bool HasTransformerCallback() const;
+
+ // Returns true if a webrtc::TransformedFrameCallback is registered.
+ bool HasTransformedFrameCallback() const;
+
+ rtc::scoped_refptr<webrtc::FrameTransformerInterface> Delegate();
+
+ private:
+ THREAD_CHECKER(thread_checker_);
+ rtc::scoped_refptr<webrtc::FrameTransformerInterface> delegate_;
+ rtc::scoped_refptr<webrtc::TransformedFrameCallback> send_frame_to_sink_cb_;
+ TransformerCallback transformer_callback_;
+ base::WeakPtrFactory<RTCEncodedAudioStreamTransformer> weak_factory_{this};
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_ENCODED_AUDIO_STREAM_TRANSFORMER_H_
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_audio_stream_transformer_test.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_audio_stream_transformer_test.cc
new file mode 100644
index 00000000000..bd72fe57397
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_audio_stream_transformer_test.cc
@@ -0,0 +1,105 @@
+// 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/peerconnection/rtc_encoded_audio_stream_transformer.h"
+
+#include <stdint.h>
+
+#include <memory>
+#include <vector>
+
+#include "base/memory/scoped_refptr.h"
+#include "base/single_thread_task_runner.h"
+#include "base/test/task_environment.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/peerconnection/rtc_scoped_refptr_cross_thread_copier.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"
+#include "third_party/webrtc/api/frame_transformer_interface.h"
+#include "third_party/webrtc/rtc_base/ref_counted_object.h"
+
+namespace blink {
+
+namespace {
+
+class MockWebRtcTransformedFrameCallback
+ : public webrtc::TransformedFrameCallback {
+ public:
+ MOCK_METHOD1(OnTransformedFrame,
+ void(std::unique_ptr<webrtc::TransformableFrameInterface>));
+};
+
+class MockTransformerCallbackHolder {
+ public:
+ MOCK_METHOD1(OnEncodedFrame,
+ void(std::unique_ptr<webrtc::TransformableFrameInterface>));
+};
+
+} // namespace
+
+class RTCEncodedAudioStreamTransformerTest : public ::testing::Test {
+ public:
+ RTCEncodedAudioStreamTransformerTest()
+ : main_task_runner_(
+ blink::scheduler::GetSingleThreadTaskRunnerForTesting()),
+ webrtc_task_runner_(base::ThreadPool::CreateSingleThreadTaskRunner({})),
+ webrtc_callback_(
+ new rtc::RefCountedObject<MockWebRtcTransformedFrameCallback>()),
+ encoded_audio_stream_transformer_(main_task_runner_) {}
+
+ void SetUp() override {
+ EXPECT_FALSE(
+ encoded_audio_stream_transformer_.HasTransformedFrameCallback());
+ encoded_audio_stream_transformer_.RegisterTransformedFrameCallback(
+ webrtc_callback_);
+ EXPECT_TRUE(
+ encoded_audio_stream_transformer_.HasTransformedFrameCallback());
+ }
+
+ void TearDown() override {
+ encoded_audio_stream_transformer_.UnregisterTransformedFrameCallback();
+ EXPECT_FALSE(
+ encoded_audio_stream_transformer_.HasTransformedFrameCallback());
+ }
+
+ protected:
+ base::test::TaskEnvironment task_environment_;
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> webrtc_task_runner_;
+ rtc::scoped_refptr<MockWebRtcTransformedFrameCallback> webrtc_callback_;
+ MockTransformerCallbackHolder mock_transformer_callback_holder_;
+ RTCEncodedAudioStreamTransformer encoded_audio_stream_transformer_;
+};
+
+TEST_F(RTCEncodedAudioStreamTransformerTest,
+ TransformerForwardsFrameToTransformerCallback) {
+ EXPECT_FALSE(encoded_audio_stream_transformer_.HasTransformerCallback());
+ encoded_audio_stream_transformer_.SetTransformerCallback(
+ WTF::BindRepeating(&MockTransformerCallbackHolder::OnEncodedFrame,
+ WTF::Unretained(&mock_transformer_callback_holder_)));
+ EXPECT_TRUE(encoded_audio_stream_transformer_.HasTransformerCallback());
+
+ EXPECT_CALL(mock_transformer_callback_holder_, OnEncodedFrame);
+ // Frames are pushed to the RTCEncodedAudioStreamTransformer via its delegate,
+ // which would normally be registered with a WebRTC sender or receiver.
+ // In this test, manually send the frame to the transformer on the simulated
+ // WebRTC thread.
+ PostCrossThreadTask(
+ *webrtc_task_runner_, FROM_HERE,
+ CrossThreadBindOnce(&webrtc::FrameTransformerInterface::Transform,
+ encoded_audio_stream_transformer_.Delegate(),
+ nullptr));
+ task_environment_.RunUntilIdle();
+}
+
+TEST_F(RTCEncodedAudioStreamTransformerTest, TransformerForwardsFrameToWebRTC) {
+ EXPECT_CALL(*webrtc_callback_, OnTransformedFrame);
+ encoded_audio_stream_transformer_.SendFrameToSink(nullptr);
+ task_environment_.RunUntilIdle();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_video_stream_transformer.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_video_stream_transformer.cc
new file mode 100644
index 00000000000..ba9c8507154
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_video_stream_transformer.cc
@@ -0,0 +1,191 @@
+// 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/peerconnection/rtc_encoded_video_stream_transformer.h"
+
+#include <utility>
+
+#include "base/memory/ptr_util.h"
+#include "base/single_thread_task_runner.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_scoped_refptr_cross_thread_copier.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/webrtc/api/frame_transformer_interface.h"
+#include "third_party/webrtc/rtc_base/ref_counted_object.h"
+
+namespace blink {
+
+namespace {
+
+// This delegate class exists to work around the fact that
+// RTCEncodedVideoStreamTransformer cannot derive from rtc::RefCountedObject
+// and post tasks referencing itself as an rtc::scoped_refptr. Instead,
+// RTCEncodedVideoStreamTransformer creates a delegate using
+// rtc::RefCountedObject and posts tasks referencing the delegate, which invokes
+// the RTCEncodedVideoStreamTransformer via callbacks.
+class RTCEncodedVideoStreamTransformerDelegate
+ : public webrtc::FrameTransformerInterface {
+ public:
+ RTCEncodedVideoStreamTransformerDelegate(
+ const base::WeakPtr<RTCEncodedVideoStreamTransformer>& transformer,
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner)
+ : transformer_(transformer),
+ main_task_runner_(std::move(main_task_runner)) {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ }
+
+ // webrtc::FrameTransformerInterface
+ // TODO(crbug.com/1065838): Remove the non-ssrc version of the registration
+ // and unregistration methods once WebRTC uses the ssrc version in all cases.
+ void RegisterTransformedFrameCallback(
+ rtc::scoped_refptr<webrtc::TransformedFrameCallback>
+ send_frame_to_sink_callback) override {
+ PostCrossThreadTask(
+ *main_task_runner_, FROM_HERE,
+ CrossThreadBindOnce(&RTCEncodedVideoStreamTransformer::
+ RegisterTransformedFrameSinkCallback,
+ transformer_,
+ std::move(send_frame_to_sink_callback), 0));
+ }
+
+ void UnregisterTransformedFrameCallback() override {
+ PostCrossThreadTask(
+ *main_task_runner_, FROM_HERE,
+ CrossThreadBindOnce(&RTCEncodedVideoStreamTransformer::
+ UnregisterTransformedFrameSinkCallback,
+ transformer_, 0));
+ }
+
+ void RegisterTransformedFrameSinkCallback(
+ rtc::scoped_refptr<webrtc::TransformedFrameCallback>
+ send_frame_to_sink_callback,
+ uint32_t ssrc) override {
+ PostCrossThreadTask(
+ *main_task_runner_, FROM_HERE,
+ CrossThreadBindOnce(&RTCEncodedVideoStreamTransformer::
+ RegisterTransformedFrameSinkCallback,
+ transformer_,
+ std::move(send_frame_to_sink_callback), ssrc));
+ }
+
+ void UnregisterTransformedFrameSinkCallback(uint32_t ssrc) override {
+ PostCrossThreadTask(
+ *main_task_runner_, FROM_HERE,
+ CrossThreadBindOnce(&RTCEncodedVideoStreamTransformer::
+ UnregisterTransformedFrameSinkCallback,
+ transformer_, ssrc));
+ }
+
+ void Transform(
+ std::unique_ptr<webrtc::TransformableFrameInterface> frame) override {
+ auto video_frame =
+ base::WrapUnique(static_cast<webrtc::TransformableVideoFrameInterface*>(
+ frame.release()));
+ PostCrossThreadTask(
+ *main_task_runner_, FROM_HERE,
+ CrossThreadBindOnce(&RTCEncodedVideoStreamTransformer::TransformFrame,
+ transformer_, std::move(video_frame)));
+ }
+
+ private:
+ base::WeakPtr<RTCEncodedVideoStreamTransformer> transformer_;
+ const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+};
+
+} // namespace
+
+RTCEncodedVideoStreamTransformer::RTCEncodedVideoStreamTransformer(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) {
+ DCHECK(main_task_runner->BelongsToCurrentThread());
+ delegate_ =
+ new rtc::RefCountedObject<RTCEncodedVideoStreamTransformerDelegate>(
+ weak_factory_.GetWeakPtr(), std::move(main_task_runner));
+}
+
+void RTCEncodedVideoStreamTransformer::RegisterTransformedFrameSinkCallback(
+ rtc::scoped_refptr<webrtc::TransformedFrameCallback> callback,
+ uint32_t ssrc) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ for (auto& sink_callback : send_frame_to_sink_callbacks_) {
+ if (sink_callback.first == ssrc) {
+ sink_callback.second = std::move(callback);
+ return;
+ }
+ }
+ send_frame_to_sink_callbacks_.push_back(std::make_pair(ssrc, callback));
+}
+
+void RTCEncodedVideoStreamTransformer::UnregisterTransformedFrameSinkCallback(
+ uint32_t ssrc) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ for (wtf_size_t i = 0; i < send_frame_to_sink_callbacks_.size(); ++i) {
+ if (send_frame_to_sink_callbacks_[i].first == ssrc) {
+ send_frame_to_sink_callbacks_.EraseAt(i);
+ return;
+ }
+ }
+}
+
+void RTCEncodedVideoStreamTransformer::TransformFrame(
+ std::unique_ptr<webrtc::TransformableVideoFrameInterface> frame) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ // If no transformer callback has been set, drop the frame.
+ if (!transformer_callback_)
+ return;
+
+ transformer_callback_.Run(std::move(frame));
+}
+
+void RTCEncodedVideoStreamTransformer::SendFrameToSink(
+ std::unique_ptr<webrtc::TransformableVideoFrameInterface> frame) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ // TODO(crbug.com/1069275): Remove this section once WebRTC reports ssrc in
+ // all sink callback registrations.
+ if (send_frame_to_sink_callbacks_.size() == 1 &&
+ send_frame_to_sink_callbacks_[0].first == 0) {
+ send_frame_to_sink_callbacks_[0].second->OnTransformedFrame(
+ std::move(frame));
+ return;
+ }
+ for (const auto& sink_callback : send_frame_to_sink_callbacks_) {
+ if (sink_callback.first == frame->GetSsrc()) {
+ sink_callback.second->OnTransformedFrame(std::move(frame));
+ return;
+ }
+ }
+}
+
+void RTCEncodedVideoStreamTransformer::SetTransformerCallback(
+ TransformerCallback callback) {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ transformer_callback_ = std::move(callback);
+}
+
+void RTCEncodedVideoStreamTransformer::ResetTransformerCallback() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ transformer_callback_.Reset();
+}
+
+bool RTCEncodedVideoStreamTransformer::HasTransformerCallback() const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return !transformer_callback_.is_null();
+}
+
+bool RTCEncodedVideoStreamTransformer::HasTransformedFrameSinkCallback(
+ uint32_t ssrc) const {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ for (const auto& sink_callbacks : send_frame_to_sink_callbacks_) {
+ if (sink_callbacks.first == ssrc)
+ return true;
+ }
+ return false;
+}
+
+rtc::scoped_refptr<webrtc::FrameTransformerInterface>
+RTCEncodedVideoStreamTransformer::Delegate() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ return delegate_;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_video_stream_transformer.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_video_stream_transformer.h
new file mode 100644
index 00000000000..6da970263a4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_video_stream_transformer.h
@@ -0,0 +1,93 @@
+// 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_PEERCONNECTION_RTC_ENCODED_VIDEO_STREAM_TRANSFORMER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_ENCODED_VIDEO_STREAM_TRANSFORMER_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <utility>
+
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/thread_checker.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+#include "third_party/webrtc/api/scoped_refptr.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+} // namespace base
+
+namespace webrtc {
+class FrameTransformerInterface;
+class TransformedFrameCallback;
+class TransformableVideoFrameInterface;
+} // namespace webrtc
+
+namespace blink {
+
+class PLATFORM_EXPORT RTCEncodedVideoStreamTransformer {
+ public:
+ using TransformerCallback = base::RepeatingCallback<void(
+ std::unique_ptr<webrtc::TransformableVideoFrameInterface>)>;
+ explicit RTCEncodedVideoStreamTransformer(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner);
+
+ // Called by WebRTC to let us know about a callback object to send transformed
+ // frames to the WebRTC decoder. Runs on an internal WebRTC thread.
+ // The callback can run on any thread.
+ void RegisterTransformedFrameSinkCallback(
+ rtc::scoped_refptr<webrtc::TransformedFrameCallback>,
+ uint32_t ssrc);
+
+ // Called by WebRTC to let us know that any reference to the callback object
+ // reported by RegisterTransformedFrameCallback() should be released since
+ // the callback is no longer useful and is intended for destruction.
+ // TODO(crbug.com/1065838): Remove the non-ssrc version once WebRTC uses the
+ // ssrc version in all cases.
+ // void UnregisterTransformedFrameCallback();
+ void UnregisterTransformedFrameSinkCallback(uint32_t ssrc);
+
+ // Called by WebRTC to notify of new untransformed frames from the WebRTC
+ // stack. Runs on an internal WebRTC thread.
+ void TransformFrame(
+ std::unique_ptr<webrtc::TransformableVideoFrameInterface>);
+
+ // Send a transformed frame to the WebRTC sink. Must run on the main
+ // thread.
+ void SendFrameToSink(
+ std::unique_ptr<webrtc::TransformableVideoFrameInterface> frame);
+
+ // Set a callback to be invoked on every untransformed frame. Must run on the
+ // main thread.
+ void SetTransformerCallback(TransformerCallback);
+
+ // Removes the callback
+ void ResetTransformerCallback();
+
+ // Returns true if a callback has been set with SetTransformerCallback(),
+ // false otherwise. Must run on the main thread.
+ bool HasTransformerCallback() const;
+
+ // Returns true if a webrtc::TransformedFrameCallback is registered for
+ // the given ssrc.
+ bool HasTransformedFrameSinkCallback(uint32_t ssrc) const;
+
+ rtc::scoped_refptr<webrtc::FrameTransformerInterface> Delegate();
+
+ private:
+ THREAD_CHECKER(thread_checker_);
+ rtc::scoped_refptr<webrtc::FrameTransformerInterface> delegate_;
+ Vector<
+ std::pair<uint32_t, rtc::scoped_refptr<webrtc::TransformedFrameCallback>>>
+ send_frame_to_sink_callbacks_;
+ TransformerCallback transformer_callback_;
+ base::WeakPtrFactory<RTCEncodedVideoStreamTransformer> weak_factory_{this};
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_ENCODED_VIDEO_STREAM_TRANSFORMER_H_
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
new file mode 100644
index 00000000000..01f1af1a521
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_encoded_video_stream_transformer_test.cc
@@ -0,0 +1,140 @@
+// 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/peerconnection/rtc_encoded_video_stream_transformer.h"
+
+#include <stdint.h>
+
+#include <memory>
+#include <vector>
+
+#include "base/memory/scoped_refptr.h"
+#include "base/single_thread_task_runner.h"
+#include "base/test/task_environment.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/peerconnection/rtc_scoped_refptr_cross_thread_copier.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"
+#include "third_party/webrtc/api/frame_transformer_interface.h"
+#include "third_party/webrtc/rtc_base/ref_counted_object.h"
+
+namespace blink {
+
+namespace {
+
+const uint32_t kSSRC = 1;
+const uint32_t kNonexistentSSRC = 0;
+
+class MockWebRtcTransformedFrameCallback
+ : public webrtc::TransformedFrameCallback {
+ public:
+ MOCK_METHOD1(OnTransformedFrame,
+ void(std::unique_ptr<webrtc::TransformableFrameInterface>));
+};
+
+class MockTransformerCallbackHolder {
+ public:
+ MOCK_METHOD1(OnEncodedFrame,
+ 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);
+}
+
+} // namespace
+
+class RTCEncodedVideoStreamTransformerTest : public ::testing::Test {
+ public:
+ RTCEncodedVideoStreamTransformerTest()
+ : main_task_runner_(
+ blink::scheduler::GetSingleThreadTaskRunnerForTesting()),
+ webrtc_task_runner_(base::ThreadPool::CreateSingleThreadTaskRunner({})),
+ webrtc_callback_(
+ new rtc::RefCountedObject<MockWebRtcTransformedFrameCallback>()),
+ encoded_video_stream_transformer_(main_task_runner_) {}
+
+ void SetUp() override {
+ EXPECT_FALSE(
+ encoded_video_stream_transformer_.HasTransformedFrameSinkCallback(
+ kSSRC));
+ encoded_video_stream_transformer_.RegisterTransformedFrameSinkCallback(
+ webrtc_callback_, kSSRC);
+ EXPECT_TRUE(
+ encoded_video_stream_transformer_.HasTransformedFrameSinkCallback(
+ kSSRC));
+ EXPECT_FALSE(
+ encoded_video_stream_transformer_.HasTransformedFrameSinkCallback(
+ kNonexistentSSRC));
+ }
+
+ void TearDown() override {
+ encoded_video_stream_transformer_.UnregisterTransformedFrameSinkCallback(
+ kSSRC);
+ EXPECT_FALSE(
+ encoded_video_stream_transformer_.HasTransformedFrameSinkCallback(
+ kSSRC));
+ }
+
+ protected:
+ base::test::TaskEnvironment task_environment_;
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> webrtc_task_runner_;
+ rtc::scoped_refptr<MockWebRtcTransformedFrameCallback> webrtc_callback_;
+ MockTransformerCallbackHolder mock_transformer_callback_holder_;
+ RTCEncodedVideoStreamTransformer encoded_video_stream_transformer_;
+};
+
+TEST_F(RTCEncodedVideoStreamTransformerTest,
+ TransformerForwardsFrameToTransformerCallback) {
+ EXPECT_FALSE(encoded_video_stream_transformer_.HasTransformerCallback());
+ encoded_video_stream_transformer_.SetTransformerCallback(
+ WTF::BindRepeating(&MockTransformerCallbackHolder::OnEncodedFrame,
+ WTF::Unretained(&mock_transformer_callback_holder_)));
+ EXPECT_TRUE(encoded_video_stream_transformer_.HasTransformerCallback());
+
+ EXPECT_CALL(mock_transformer_callback_holder_, OnEncodedFrame);
+ // Frames are pushed to the RTCEncodedVideoStreamTransformer via its delegate,
+ // which would normally be registered with a WebRTC sender or receiver.
+ // In this test, manually send the frame to the transformer on the simulated
+ // WebRTC thread.
+ PostCrossThreadTask(
+ *webrtc_task_runner_, FROM_HERE,
+ CrossThreadBindOnce(&webrtc::FrameTransformerInterface::Transform,
+ encoded_video_stream_transformer_.Delegate(),
+ CreateFakeFrame()));
+ task_environment_.RunUntilIdle();
+}
+
+TEST_F(RTCEncodedVideoStreamTransformerTest, TransformerForwardsFrameToWebRTC) {
+ EXPECT_CALL(*webrtc_callback_, OnTransformedFrame);
+ encoded_video_stream_transformer_.SendFrameToSink(CreateFakeFrame());
+ task_environment_.RunUntilIdle();
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink.h
index be9e3f265a3..8e60db6aae9 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink.h
@@ -5,15 +5,16 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_EVENT_LOG_OUTPUT_SINK_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_EVENT_LOG_OUTPUT_SINK_H_
+#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/platform_export.h"
namespace blink {
-class PLATFORM_EXPORT RtcEventLogOutputSink {
+class PLATFORM_EXPORT RtcEventLogOutputSink : public GarbageCollectedMixin {
public:
virtual ~RtcEventLogOutputSink() = default;
- virtual void OnWebRtcEventLogWrite(const std::string& output) = 0;
+ virtual void OnWebRtcEventLogWrite(const WTF::Vector<uint8_t>& output) = 0;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink_proxy.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink_proxy.cc
index 4a8649ad39c..f4c9b54ff52 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink_proxy.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink_proxy.cc
@@ -22,7 +22,10 @@ bool RtcEventLogOutputSinkProxy::IsActive() const {
}
bool RtcEventLogOutputSinkProxy::Write(const std::string& output) {
- sink_->OnWebRtcEventLogWrite(output);
+ WTF::Vector<uint8_t> converted_output;
+ converted_output.AppendRange(output.begin(), output.end());
+
+ sink_->OnWebRtcEventLogWrite(converted_output);
return true;
}
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink_proxy.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink_proxy.h
index 8ecdf912ee2..40b38869bf7 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink_proxy.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink_proxy.h
@@ -7,6 +7,7 @@
#include <memory>
+#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/webrtc/api/rtc_event_log_output.h"
@@ -29,7 +30,7 @@ class PLATFORM_EXPORT RtcEventLogOutputSinkProxy final
bool Write(const std::string& output) override;
private:
- RtcEventLogOutputSink* const sink_;
+ CrossThreadWeakPersistent<RtcEventLogOutputSink> sink_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.cc
index 74d1d404a04..e9cbb3e94c5 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/webrtc/api/candidate.h"
#include "third_party/webrtc/p2p/base/p2p_constants.h"
#include "third_party/webrtc/p2p/base/port.h"
@@ -39,27 +40,6 @@ String CandidateTypeToString(const std::string& type) {
} // namespace
-// static
-scoped_refptr<RTCIceCandidatePlatform> RTCIceCandidatePlatform::Create(
- String candidate,
- String sdp_mid,
- base::Optional<uint16_t> sdp_m_line_index,
- String username_fragment) {
- return base::AdoptRef(new RTCIceCandidatePlatform(
- std::move(candidate), std::move(sdp_mid), std::move(sdp_m_line_index),
- std::move(username_fragment)));
-}
-
-scoped_refptr<RTCIceCandidatePlatform> RTCIceCandidatePlatform::Create(
- String candidate,
- String sdp_mid,
- int sdp_m_line_index) {
- return base::AdoptRef(new RTCIceCandidatePlatform(
- std::move(candidate), std::move(sdp_mid),
- sdp_m_line_index < 0 ? base::Optional<uint16_t>()
- : base::Optional<uint16_t>(sdp_m_line_index)));
-}
-
RTCIceCandidatePlatform::RTCIceCandidatePlatform(
String candidate,
String sdp_mid,
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 6baacd5ae97..2751f57f056 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
@@ -32,29 +32,29 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_ICE_CANDIDATE_PLATFORM_H_
#include "base/optional.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
namespace blink {
class PLATFORM_EXPORT RTCIceCandidatePlatform final
- : public WTF::ThreadSafeRefCounted<RTCIceCandidatePlatform> {
+ : public GarbageCollected<RTCIceCandidatePlatform> {
public:
// Creates a new RTCIceCandidatePlatform using |candidate|, |sdp_mid| and
// |sdp_m_line_index|. If |sdp_m_line_index| is negative, it is
// considered as having no value.
- static scoped_refptr<RTCIceCandidatePlatform> Create(String candidate,
- String sdp_mid,
- int sdp_m_line_index);
+ RTCIceCandidatePlatform(String candidate,
+ String sdp_mid,
+ base::Optional<uint16_t> sdp_m_line_index);
// Creates a new RTCIceCandidatePlatform using |candidate|, |sdp_mid|,
// |sdp_m_line_index|, and |username_fragment|.
- static scoped_refptr<RTCIceCandidatePlatform> Create(
- String candidate,
- String sdp_mid,
- base::Optional<uint16_t> sdp_m_line_index,
- String username_fragment);
+ RTCIceCandidatePlatform(String candidate,
+ String sdp_mid,
+ base::Optional<uint16_t> sdp_m_line_index,
+ String username_fragment);
+ ~RTCIceCandidatePlatform() = default;
const String& Candidate() const { return candidate_; }
const String& SdpMid() const { return sdp_mid_; }
@@ -73,22 +73,11 @@ class PLATFORM_EXPORT RTCIceCandidatePlatform final
const base::Optional<uint16_t>& RelatedPort() const { return related_port_; }
const String& UsernameFragment() const { return username_fragment_; }
- private:
- friend class WTF::ThreadSafeRefCounted<RTCIceCandidatePlatform>;
-
- RTCIceCandidatePlatform(String candidate,
- String sdp_mid,
- base::Optional<uint16_t> sdp_m_line_index);
-
- RTCIceCandidatePlatform(String candidate,
- String sdp_mid,
- base::Optional<uint16_t> sdp_m_line_index,
- String username_fragment);
+ void Trace(Visitor*) {}
+ private:
void PopulateFields(bool use_username_from_candidate);
- ~RTCIceCandidatePlatform() = default;
-
String candidate_;
String sdp_mid_;
base::Optional<uint16_t> sdp_m_line_index_;
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 a986b96c3c0..9e8e23a538a 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(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
private:
int32_t offer_to_receive_video_;
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_client.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_client.cc
new file mode 100644
index 00000000000..2b1e5693839
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_client.cc
@@ -0,0 +1,13 @@
+// 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/peerconnection/rtc_peer_connection_handler_client.h"
+
+namespace blink {
+
+RTCPeerConnectionHandlerClient::~RTCPeerConnectionHandlerClient() = default;
+
+void RTCPeerConnectionHandlerClient::ClosePeerConnection() {}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_client.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_client.h
new file mode 100644
index 00000000000..f7f61d75818
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_client.h
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_PEER_CONNECTION_HANDLER_CLIENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_PEER_CONNECTION_HANDLER_CLIENT_H_
+
+#include <memory>
+
+#include "base/memory/scoped_refptr.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+#include "third_party/webrtc/api/peer_connection_interface.h"
+#include "third_party/webrtc/api/sctp_transport_interface.h"
+
+namespace blink {
+
+class RTCIceCandidatePlatform;
+class RTCRtpTransceiverPlatform;
+class RTCRtpReceiverPlatform;
+
+struct PLATFORM_EXPORT WebRTCSctpTransportSnapshot {
+ rtc::scoped_refptr<webrtc::SctpTransportInterface> transport;
+ webrtc::SctpTransportInformation sctp_transport_state =
+ webrtc::SctpTransportInformation(webrtc::SctpTransportState::kNew);
+ webrtc::DtlsTransportInformation dtls_transport_state =
+ webrtc::DtlsTransportInformation(webrtc::DtlsTransportState::kNew);
+};
+
+class PLATFORM_EXPORT RTCPeerConnectionHandlerClient {
+ public:
+ virtual ~RTCPeerConnectionHandlerClient();
+
+ virtual void NegotiationNeeded() = 0;
+ virtual void DidGenerateICECandidate(RTCIceCandidatePlatform*) = 0;
+ virtual void DidFailICECandidate(const String& address,
+ base::Optional<uint16_t> port,
+ const String& host_candidate,
+ const String& url,
+ int error_code,
+ const String& error_text) = 0;
+ virtual void DidChangeSignalingState(
+ webrtc::PeerConnectionInterface::SignalingState) = 0;
+ virtual void DidChangeIceGatheringState(
+ webrtc::PeerConnectionInterface::IceGatheringState) = 0;
+ virtual void DidChangeIceConnectionState(
+ webrtc::PeerConnectionInterface::IceConnectionState) = 0;
+ virtual void DidChangePeerConnectionState(
+ webrtc::PeerConnectionInterface::PeerConnectionState) {}
+ virtual void DidAddReceiverPlanB(std::unique_ptr<RTCRtpReceiverPlatform>) = 0;
+ virtual void DidRemoveReceiverPlanB(
+ std::unique_ptr<RTCRtpReceiverPlatform>) = 0;
+ virtual void DidModifyTransceivers(
+ Vector<std::unique_ptr<RTCRtpTransceiverPlatform>>,
+ Vector<uintptr_t>,
+ bool is_remote_description) = 0;
+ virtual void DidModifySctpTransport(WebRTCSctpTransportSnapshot) = 0;
+ virtual void DidAddRemoteDataChannel(
+ scoped_refptr<webrtc::DataChannelInterface>) = 0;
+ virtual void DidNoteInterestingUsage(int usage_pattern) = 0;
+ virtual void UnregisterPeerConnectionHandler() = 0;
+ virtual void ClosePeerConnection();
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_PEER_CONNECTION_HANDLER_CLIENT_H_
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_platform.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_platform.h
new file mode 100644
index 00000000000..870ea35c526
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_platform.h
@@ -0,0 +1,174 @@
+/*
+ * 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.
+ */
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_PEER_CONNECTION_HANDLER_PLATFORM_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_PEER_CONNECTION_HANDLER_PLATFORM_H_
+
+#include <memory>
+
+#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+#include "third_party/webrtc/api/peer_connection_interface.h"
+#include "third_party/webrtc/api/rtc_error.h"
+#include "third_party/webrtc/api/rtp_transceiver_interface.h"
+#include "third_party/webrtc/api/stats/rtc_stats.h"
+
+namespace webrtc {
+enum class RTCErrorType;
+struct DataChannelInit;
+} // namespace webrtc
+
+namespace blink {
+
+class MediaConstraints;
+class RTCAnswerOptionsPlatform;
+class RTCIceCandidatePlatform;
+class RTCOfferOptionsPlatform;
+class RTCRtpSenderPlatform;
+class RTCRtpTransceiverPlatform;
+class RTCSessionDescriptionPlatform;
+class RTCSessionDescriptionRequest;
+class RTCStatsRequest;
+class RTCVoidRequest;
+class WebLocalFrame;
+class WebMediaStream;
+class WebMediaStreamTrack;
+
+class PLATFORM_EXPORT RTCPeerConnectionHandlerPlatform {
+ public:
+ enum class IceConnectionStateVersion {
+ // Only applicable in Unified Plan when the JavaScript-exposed
+ // iceConnectionState is calculated in blink. In this case, kLegacy is used
+ // to report the webrtc::PeerConnectionInterface implementation which is not
+ // visible in JavaScript, but still useful to track for debugging purposes.
+ kLegacy,
+ // The JavaScript-visible iceConnectionState. In Plan B, this is the same as
+ // the webrtc::PeerConnectionInterface implementation.
+ kDefault,
+ };
+
+ virtual ~RTCPeerConnectionHandlerPlatform() = default;
+
+ virtual bool Initialize(
+ const webrtc::PeerConnectionInterface::RTCConfiguration&,
+ const MediaConstraints&,
+ WebLocalFrame*) = 0;
+
+ virtual void Stop() = 0;
+ // This function should be called when the object is taken out of service.
+ // There might be functions that need to return through the object, so it
+ // cannot be deleted yet, but no new operations should be allowed.
+ // All references to the object except the owning reference are deleted
+ // by this function.
+ virtual void StopAndUnregister() = 0;
+
+ // Unified Plan: The list of transceivers after the createOffer() call.
+ // Because of offerToReceive[Audio/Video] it is possible for createOffer() to
+ // create new transceivers or update the direction of existing transceivers.
+ // https://w3c.github.io/webrtc-pc/#legacy-configuration-extensions
+ // Plan B: Returns an empty list.
+ virtual Vector<std::unique_ptr<RTCRtpTransceiverPlatform>> CreateOffer(
+ RTCSessionDescriptionRequest*,
+ const MediaConstraints&) = 0;
+ virtual Vector<std::unique_ptr<RTCRtpTransceiverPlatform>> CreateOffer(
+ RTCSessionDescriptionRequest*,
+ RTCOfferOptionsPlatform*) = 0;
+ virtual void CreateAnswer(RTCSessionDescriptionRequest*,
+ const MediaConstraints&) = 0;
+ virtual void CreateAnswer(RTCSessionDescriptionRequest*,
+ RTCAnswerOptionsPlatform*) = 0;
+ virtual void SetLocalDescription(RTCVoidRequest*) = 0;
+ virtual void SetLocalDescription(RTCVoidRequest*,
+ RTCSessionDescriptionPlatform*) = 0;
+ virtual void SetRemoteDescription(RTCVoidRequest*,
+ RTCSessionDescriptionPlatform*) = 0;
+ virtual RTCSessionDescriptionPlatform* LocalDescription() = 0;
+ virtual RTCSessionDescriptionPlatform* RemoteDescription() = 0;
+ virtual RTCSessionDescriptionPlatform* CurrentLocalDescription() = 0;
+ virtual RTCSessionDescriptionPlatform* CurrentRemoteDescription() = 0;
+ virtual RTCSessionDescriptionPlatform* PendingLocalDescription() = 0;
+ virtual RTCSessionDescriptionPlatform* PendingRemoteDescription() = 0;
+ virtual const webrtc::PeerConnectionInterface::RTCConfiguration&
+ GetConfiguration() const = 0;
+ virtual webrtc::RTCErrorType SetConfiguration(
+ const webrtc::PeerConnectionInterface::RTCConfiguration&) = 0;
+
+ virtual void AddICECandidate(RTCVoidRequest*, RTCIceCandidatePlatform*) = 0;
+ virtual void RestartIce() = 0;
+ virtual void GetStats(RTCStatsRequest*) = 0;
+ // Gets stats using the new stats collection API, see
+ // third_party/webrtc/api/stats/. These will replace the old stats collection
+ // API when the new API has matured enough.
+ virtual void GetStats(RTCStatsReportCallback,
+ const Vector<webrtc::NonStandardGroupId>&) = 0;
+ virtual scoped_refptr<webrtc::DataChannelInterface> CreateDataChannel(
+ const String& label,
+ const webrtc::DataChannelInit&) = 0;
+ virtual webrtc::RTCErrorOr<std::unique_ptr<RTCRtpTransceiverPlatform>>
+ AddTransceiverWithTrack(const WebMediaStreamTrack&,
+ const webrtc::RtpTransceiverInit&) = 0;
+ virtual webrtc::RTCErrorOr<std::unique_ptr<RTCRtpTransceiverPlatform>>
+ AddTransceiverWithKind(
+ // webrtc::MediaStreamTrackInterface::kAudioKind or kVideoKind
+ const String& kind,
+ const webrtc::RtpTransceiverInit&) = 0;
+ // Adds the track to the peer connection, returning the resulting transceiver
+ // or error.
+ virtual webrtc::RTCErrorOr<std::unique_ptr<RTCRtpTransceiverPlatform>>
+ AddTrack(const WebMediaStreamTrack&, const Vector<WebMediaStream>&) = 0;
+ // Removes the sender.
+ // In Plan B: Returns OK() with value nullptr on success. The sender's track
+ // must be nulled by the caller.
+ // In Unified Plan: Returns OK() with the updated transceiver state.
+ virtual webrtc::RTCErrorOr<std::unique_ptr<RTCRtpTransceiverPlatform>>
+ RemoveTrack(RTCRtpSenderPlatform*) = 0;
+
+ // Returns a pointer to the underlying native PeerConnection object.
+ virtual webrtc::PeerConnectionInterface* NativePeerConnection() = 0;
+
+ virtual void RunSynchronousOnceClosureOnSignalingThread(
+ CrossThreadOnceClosure closure,
+ const char* trace_event_name) = 0;
+ virtual void RunSynchronousRepeatingClosureOnSignalingThread(
+ const base::RepeatingClosure& closure,
+ const char* trace_event_name) = 0;
+
+ // Inform chrome://webrtc-internals/ that the iceConnectionState has changed.
+ virtual void TrackIceConnectionStateChange(
+ IceConnectionStateVersion version,
+ webrtc::PeerConnectionInterface::IceConnectionState state) = 0;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_PEER_CONNECTION_HANDLER_PLATFORM_H_
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 ad18bf33776..882a6893b69 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
@@ -8,16 +8,18 @@
#include <memory>
#include "base/optional.h"
-#include "third_party/blink/public/platform/web_common.h"
-#include "third_party/blink/public/platform/web_rtc_stats.h"
-#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/public/platform/web_vector.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "third_party/webrtc/api/dtls_transport_interface.h"
#include "third_party/webrtc/api/rtp_parameters.h"
#include "third_party/webrtc/api/stats/rtc_stats.h"
namespace blink {
+class RTCEncodedAudioStreamTransformer;
+class RTCEncodedVideoStreamTransformer;
class RTCRtpSource;
class WebMediaStreamTrack;
@@ -25,7 +27,7 @@ class WebMediaStreamTrack;
// receiver alive through reference counting. Multiple |RTCRtpReceiverPlatform|s
// could reference the same receiver, see |id|.
// https://w3c.github.io/webrtc-pc/#rtcrtpreceiver-interface
-class BLINK_PLATFORM_EXPORT RTCRtpReceiverPlatform {
+class PLATFORM_EXPORT RTCRtpReceiverPlatform {
public:
virtual ~RTCRtpReceiverPlatform();
@@ -39,13 +41,21 @@ class BLINK_PLATFORM_EXPORT RTCRtpReceiverPlatform {
// The information is only interesting if DtlsTransport() is non-null.
virtual webrtc::DtlsTransportInformation DtlsTransportInformation() = 0;
virtual const WebMediaStreamTrack& Track() const = 0;
- virtual WebVector<WebString> StreamIds() const = 0;
- virtual WebVector<std::unique_ptr<RTCRtpSource>> GetSources() = 0;
- virtual void GetStats(blink::WebRTCStatsReportCallback,
- const WebVector<webrtc::NonStandardGroupId>&) = 0;
+ virtual Vector<String> StreamIds() const = 0;
+ virtual Vector<std::unique_ptr<RTCRtpSource>> GetSources() = 0;
+ virtual void GetStats(RTCStatsReportCallback,
+ const Vector<webrtc::NonStandardGroupId>&) = 0;
virtual std::unique_ptr<webrtc::RtpParameters> GetParameters() const = 0;
virtual void SetJitterBufferMinimumDelay(
base::Optional<double> delay_seconds) = 0;
+ virtual RTCEncodedAudioStreamTransformer* GetEncodedAudioStreamTransformer()
+ const {
+ return nullptr;
+ }
+ virtual RTCEncodedVideoStreamTransformer* GetEncodedVideoStreamTransformer()
+ const {
+ return nullptr;
+ }
};
} // namespace blink
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 e2db21cc70f..b39bca799ea 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
@@ -7,18 +7,21 @@
#include <memory>
-#include "third_party/blink/public/platform/web_rtc_stats.h"
-#include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "third_party/webrtc/api/dtls_transport_interface.h"
#include "third_party/webrtc/api/rtp_parameters.h"
#include "third_party/webrtc/api/stats/rtc_stats.h"
namespace blink {
+class RtcDtmfSenderHandler;
+class RTCEncodedAudioStreamTransformer;
+class RTCEncodedVideoStreamTransformer;
class RTCVoidRequest;
class WebMediaStreamTrack;
-class RtcDtmfSenderHandler;
// Implementations of this interface keep the corresponding WebRTC-layer sender
// alive through reference counting. Multiple |RTCRtpSenderPlatform|s could
@@ -39,19 +42,27 @@ class PLATFORM_EXPORT RTCRtpSenderPlatform {
// The information is only interesting if DtlsTransport() is non-null.
virtual webrtc::DtlsTransportInformation DtlsTransportInformation() = 0;
virtual WebMediaStreamTrack Track() const = 0;
- virtual WebVector<WebString> StreamIds() 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 std::unique_ptr<RtcDtmfSenderHandler> GetDtmfSender() const = 0;
virtual std::unique_ptr<webrtc::RtpParameters> GetParameters() const = 0;
- virtual void SetParameters(blink::WebVector<webrtc::RtpEncodingParameters>,
- webrtc::DegradationPreference,
+ virtual void SetParameters(Vector<webrtc::RtpEncodingParameters>,
+ absl::optional<webrtc::DegradationPreference>,
RTCVoidRequest*) = 0;
- virtual void GetStats(blink::WebRTCStatsReportCallback,
- const WebVector<webrtc::NonStandardGroupId>&) = 0;
- virtual void SetStreams(const WebVector<WebString>& stream_ids) = 0;
+ virtual void GetStats(RTCStatsReportCallback,
+ const Vector<webrtc::NonStandardGroupId>&) = 0;
+ virtual void SetStreams(const Vector<String>& stream_ids) = 0;
+ virtual RTCEncodedAudioStreamTransformer* GetEncodedAudioStreamTransformer()
+ const {
+ return nullptr;
+ }
+ virtual RTCEncodedVideoStreamTransformer* GetEncodedVideoStreamTransformer()
+ const {
+ return nullptr;
+ }
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.cc
index be6a3c88bf9..704a4e90670 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.cc
@@ -9,6 +9,7 @@
#include "base/logging.h"
#include "base/time/time.h"
#include "third_party/webrtc/api/scoped_refptr.h"
+#include "third_party/webrtc/system_wrappers/include/ntp_time.h"
namespace blink {
@@ -54,4 +55,11 @@ uint32_t RTCRtpSource::RtpTimestamp() const {
return source_.rtp_timestamp();
}
+base::Optional<int64_t> RTCRtpSource::CaptureTimestamp() const {
+ if (!source_.absolute_capture_time())
+ return base::nullopt;
+ return webrtc::UQ32x32ToInt64Ms(
+ source_.absolute_capture_time()->absolute_capture_timestamp);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.h
index a36dd370c77..551ac0b3779 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.h
@@ -35,6 +35,7 @@ class PLATFORM_EXPORT RTCRtpSource {
uint32_t Source() const;
base::Optional<double> AudioLevel() const;
uint32_t RtpTimestamp() const;
+ base::Optional<int64_t> CaptureTimestamp() const;
private:
const webrtc::RtpSource source_;
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.h
index 91e1c1a8b85..1ba93246f10 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_rtp_transceiver_platform.h
@@ -8,9 +8,10 @@
#include <memory>
#include "base/optional.h"
-#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_receiver_platform.h"
#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "third_party/webrtc/api/rtp_transceiver_interface.h"
namespace blink {
@@ -51,8 +52,8 @@ class PLATFORM_EXPORT RTCRtpTransceiverPlatform {
// Identifies the webrtc-layer transceiver. Multiple RTCRtpTransceiverPlatform
// can exist for the same webrtc-layer transceiver.
virtual uintptr_t Id() const = 0;
- virtual WebString Mid() const = 0;
- virtual void SetMid(base::Optional<WebString>) {}
+ virtual String Mid() const = 0;
+ virtual void SetMid(base::Optional<String>) {}
virtual std::unique_ptr<RTCRtpSenderPlatform> Sender() const = 0;
virtual std::unique_ptr<RTCRtpReceiverPlatform> Receiver() const = 0;
virtual bool Stopped() const = 0;
@@ -63,7 +64,7 @@ class PLATFORM_EXPORT RTCRtpTransceiverPlatform {
virtual base::Optional<webrtc::RtpTransceiverDirection> FiredDirection()
const = 0;
virtual webrtc::RTCError SetCodecPreferences(
- WebVector<webrtc::RtpCodecCapability>) {
+ Vector<webrtc::RtpCodecCapability>) {
return {};
}
};
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_scoped_refptr_cross_thread_copier.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_scoped_refptr_cross_thread_copier.h
new file mode 100644
index 00000000000..753bb216047
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_scoped_refptr_cross_thread_copier.h
@@ -0,0 +1,22 @@
+// 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_PEERCONNECTION_RTC_SCOPED_REFPTR_CROSS_THREAD_COPIER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_SCOPED_REFPTR_CROSS_THREAD_COPIER_H_
+
+#include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h"
+#include "third_party/webrtc/api/scoped_refptr.h"
+
+namespace WTF {
+
+template <typename T>
+struct CrossThreadCopier<rtc::scoped_refptr<T>> {
+ STATIC_ONLY(CrossThreadCopier);
+ using Type = rtc::scoped_refptr<T>;
+ static Type Copy(Type pointer) { return pointer; }
+};
+
+} // namespace WTF
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_SCOPED_REFPTR_CROSS_THREAD_COPIER_H_
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 6c003142933..69ea1e6b320 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(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
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 9d88696043e..6bc18622c67 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(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
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 6093874c03c..a1f66c44901 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc
@@ -9,24 +9,15 @@
#include <string>
#include "base/logging.h"
+#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/time/time.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_scoped_refptr_cross_thread_copier.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/webrtc/api/stats/rtc_stats.h"
#include "third_party/webrtc/api/stats/rtcstats_objects.h"
-namespace WTF {
-
-template <typename T>
-struct CrossThreadCopier<rtc::scoped_refptr<T>> {
- STATIC_ONLY(CrossThreadCopier);
- using Type = rtc::scoped_refptr<T>;
- static Type Copy(Type pointer) { return pointer; }
-};
-
-} // namespace WTF
-
namespace blink {
namespace {
@@ -82,7 +73,7 @@ bool IsWhitelistedStats(const webrtc::RTCStats& stats) {
// including one of its group IDs in |exposed_group_ids|.
std::vector<const webrtc::RTCStatsMemberInterface*> FilterMembers(
std::vector<const webrtc::RTCStatsMemberInterface*> stats_members,
- const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids) {
+ const Vector<webrtc::NonStandardGroupId>& exposed_group_ids) {
// Note that using "is_standarized" avoids having to maintain a whitelist of
// every single standardized member, as we do at the "stats object" level
// with "RTCStatsWhitelist".
@@ -93,7 +84,7 @@ std::vector<const webrtc::RTCStatsMemberInterface*> FilterMembers(
return false;
}
- const blink::WebVector<webrtc::NonStandardGroupId>& ids =
+ const std::vector<webrtc::NonStandardGroupId>& ids =
member->group_ids();
for (const webrtc::NonStandardGroupId& id : exposed_group_ids) {
if (std::find(ids.begin(), ids.end(), id) != ids.end()) {
@@ -116,11 +107,18 @@ size_t CountWhitelistedStats(
return size;
}
+template <typename T>
+Vector<T> ToWTFVector(const std::vector<T>& vector) {
+ Vector<T> wtf_vector(SafeCast<WTF::wtf_size_t>(vector.size()));
+ std::move(vector.begin(), vector.end(), wtf_vector.begin());
+ return wtf_vector;
+}
+
} // namespace
RTCStatsReportPlatform::RTCStatsReportPlatform(
const scoped_refptr<const webrtc::RTCStatsReport>& stats_report,
- const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids)
+ const Vector<webrtc::NonStandardGroupId>& exposed_group_ids)
: stats_report_(stats_report),
it_(stats_report_->begin()),
end_(stats_report_->end()),
@@ -164,7 +162,7 @@ size_t RTCStatsReportPlatform::Size() const {
RTCStats::RTCStats(
const scoped_refptr<const webrtc::RTCStatsReport>& stats_owner,
const webrtc::RTCStats* stats,
- const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids)
+ const Vector<webrtc::NonStandardGroupId>& exposed_group_ids)
: stats_owner_(stats_owner),
stats_(stats),
stats_members_(FilterMembers(stats->Members(), exposed_group_ids)) {
@@ -255,63 +253,63 @@ String RTCStatsMember::ValueString() const {
*member_->cast_to<webrtc::RTCStatsMember<std::string>>());
}
-blink::WebVector<int> RTCStatsMember::ValueSequenceBool() const {
+Vector<bool> RTCStatsMember::ValueSequenceBool() const {
DCHECK(IsDefined());
- const std::vector<bool>& vector =
+ const std::vector<bool> vector =
*member_->cast_to<webrtc::RTCStatsMember<std::vector<bool>>>();
- std::vector<int> uint32_vector;
- uint32_vector.reserve(vector.size());
- for (size_t i = 0; i < vector.size(); ++i) {
- uint32_vector.push_back(vector[i] ? 1 : 0);
- }
- return blink::WebVector<int>(uint32_vector);
+ return ToWTFVector(vector);
}
-blink::WebVector<int32_t> RTCStatsMember::ValueSequenceInt32() const {
+Vector<int32_t> RTCStatsMember::ValueSequenceInt32() const {
DCHECK(IsDefined());
- return blink::WebVector<int32_t>(
- *member_->cast_to<webrtc::RTCStatsMember<std::vector<int32_t>>>());
+ const std::vector<int32_t> vector =
+ *member_->cast_to<webrtc::RTCStatsMember<std::vector<int32_t>>>();
+ return ToWTFVector(vector);
}
-blink::WebVector<uint32_t> RTCStatsMember::ValueSequenceUint32() const {
+Vector<uint32_t> RTCStatsMember::ValueSequenceUint32() const {
DCHECK(IsDefined());
- return blink::WebVector<uint32_t>(
- *member_->cast_to<webrtc::RTCStatsMember<std::vector<uint32_t>>>());
+ const std::vector<uint32_t> vector =
+ *member_->cast_to<webrtc::RTCStatsMember<std::vector<uint32_t>>>();
+ return ToWTFVector(vector);
}
-blink::WebVector<int64_t> RTCStatsMember::ValueSequenceInt64() const {
+Vector<int64_t> RTCStatsMember::ValueSequenceInt64() const {
DCHECK(IsDefined());
- return blink::WebVector<int64_t>(
- *member_->cast_to<webrtc::RTCStatsMember<std::vector<int64_t>>>());
+ const std::vector<int64_t> vector =
+ *member_->cast_to<webrtc::RTCStatsMember<std::vector<int64_t>>>();
+ return ToWTFVector(vector);
}
-blink::WebVector<uint64_t> RTCStatsMember::ValueSequenceUint64() const {
+Vector<uint64_t> RTCStatsMember::ValueSequenceUint64() const {
DCHECK(IsDefined());
- return blink::WebVector<uint64_t>(
- *member_->cast_to<webrtc::RTCStatsMember<std::vector<uint64_t>>>());
+ const std::vector<uint64_t> vector =
+ *member_->cast_to<webrtc::RTCStatsMember<std::vector<uint64_t>>>();
+ return ToWTFVector(vector);
}
-blink::WebVector<double> RTCStatsMember::ValueSequenceDouble() const {
+Vector<double> RTCStatsMember::ValueSequenceDouble() const {
DCHECK(IsDefined());
- return blink::WebVector<double>(
- *member_->cast_to<webrtc::RTCStatsMember<std::vector<double>>>());
+ const std::vector<double> vector =
+ *member_->cast_to<webrtc::RTCStatsMember<std::vector<double>>>();
+ return ToWTFVector(vector);
}
-blink::WebVector<String> RTCStatsMember::ValueSequenceString() const {
+Vector<String> RTCStatsMember::ValueSequenceString() const {
DCHECK(IsDefined());
const std::vector<std::string>& sequence =
*member_->cast_to<webrtc::RTCStatsMember<std::vector<std::string>>>();
- blink::WebVector<String> web_sequence(sequence.size());
+ Vector<String> wtf_sequence(sequence.size());
for (size_t i = 0; i < sequence.size(); ++i)
- web_sequence[i] = String::FromUTF8(sequence[i]);
- return web_sequence;
+ wtf_sequence[i] = String::FromUTF8(sequence[i]);
+ return wtf_sequence;
}
rtc::scoped_refptr<webrtc::RTCStatsCollectorCallback>
CreateRTCStatsCollectorCallback(
scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- blink::WebRTCStatsReportCallback callback,
- const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids) {
+ RTCStatsReportCallback callback,
+ const Vector<webrtc::NonStandardGroupId>& exposed_group_ids) {
return rtc::scoped_refptr<RTCStatsCollectorCallbackImpl>(
new rtc::RefCountedObject<RTCStatsCollectorCallbackImpl>(
std::move(main_thread), std::move(callback), exposed_group_ids));
@@ -319,8 +317,8 @@ CreateRTCStatsCollectorCallback(
RTCStatsCollectorCallbackImpl::RTCStatsCollectorCallbackImpl(
scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- blink::WebRTCStatsReportCallback callback,
- const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids)
+ RTCStatsReportCallback callback,
+ const Vector<webrtc::NonStandardGroupId>& exposed_group_ids)
: main_thread_(std::move(main_thread)),
callback_(std::move(callback)),
exposed_group_ids_(exposed_group_ids) {}
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 e518f20d4d0..e6e85007988 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats.h
@@ -5,15 +5,26 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_STATS_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_STATS_H_
-#include "base/memory/ref_counted.h"
-#include "base/single_thread_task_runner.h"
-#include "third_party/blink/public/platform/web_rtc_stats.h"
+#include "base/callback.h"
+#include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/platform/web_vector.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/webrtc/api/scoped_refptr.h"
#include "third_party/webrtc/api/stats/rtc_stats.h"
#include "third_party/webrtc/api/stats/rtc_stats_collector_callback.h"
#include "third_party/webrtc/api/stats/rtc_stats_report.h"
+namespace base {
+class SingleThreadTaskRunner;
+}
+
+namespace webrtc {
+class RTCStatsCollectorCallback;
+enum class NonStandardGroupId;
+} // namespace webrtc
+
namespace blink {
class RTCStats;
@@ -26,14 +37,11 @@ class RTCStatsMember;
//
// Note: This class is named |RTCStatsReportPlatform| not to collide with class
// |RTCStatsReport|, from renderer/modules/peerconnection/rtc_stats_report.cc|h.
-//
-// TODO(crbug.com/787254): Switch over the classes below from using WebVector
-// to WTF::Vector, when their respective parent classes are gone.
class PLATFORM_EXPORT RTCStatsReportPlatform {
public:
RTCStatsReportPlatform(
const scoped_refptr<const webrtc::RTCStatsReport>& stats_report,
- const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids);
+ const Vector<webrtc::NonStandardGroupId>& exposed_group_ids);
virtual ~RTCStatsReportPlatform();
// Creates a new report object that is a handle to the same underlying stats
// report (the stats are not copied). The new report's iterator is reset,
@@ -53,17 +61,16 @@ class PLATFORM_EXPORT RTCStatsReportPlatform {
const scoped_refptr<const webrtc::RTCStatsReport> stats_report_;
webrtc::RTCStatsReport::ConstIterator it_;
const webrtc::RTCStatsReport::ConstIterator end_;
- blink::WebVector<webrtc::NonStandardGroupId> exposed_group_ids_;
+ Vector<webrtc::NonStandardGroupId> exposed_group_ids_;
// Number of whitelisted webrtc::RTCStats in |stats_report_|.
const size_t size_;
};
class PLATFORM_EXPORT RTCStats {
public:
- RTCStats(
- const scoped_refptr<const webrtc::RTCStatsReport>& stats_owner,
- const webrtc::RTCStats* stats,
- const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids);
+ RTCStats(const scoped_refptr<const webrtc::RTCStatsReport>& stats_owner,
+ const webrtc::RTCStats* stats,
+ const Vector<webrtc::NonStandardGroupId>& exposed_group_ids);
virtual ~RTCStats();
String Id() const;
@@ -99,13 +106,13 @@ class PLATFORM_EXPORT RTCStatsMember {
uint64_t ValueUint64() const;
double ValueDouble() const;
String ValueString() const;
- blink::WebVector<int> ValueSequenceBool() const;
- blink::WebVector<int32_t> ValueSequenceInt32() const;
- blink::WebVector<uint32_t> ValueSequenceUint32() const;
- blink::WebVector<int64_t> ValueSequenceInt64() const;
- blink::WebVector<uint64_t> ValueSequenceUint64() const;
- blink::WebVector<double> ValueSequenceDouble() const;
- blink::WebVector<String> ValueSequenceString() const;
+ Vector<bool> ValueSequenceBool() const;
+ Vector<int32_t> ValueSequenceInt32() const;
+ Vector<uint32_t> ValueSequenceUint32() const;
+ Vector<int64_t> ValueSequenceInt64() const;
+ Vector<uint64_t> ValueSequenceUint64() const;
+ Vector<double> ValueSequenceDouble() const;
+ Vector<String> ValueSequenceString() const;
private:
// Reference to keep the report that owns |member_|'s stats object alive.
@@ -114,6 +121,16 @@ class PLATFORM_EXPORT RTCStatsMember {
const webrtc::RTCStatsMemberInterface* const member_;
};
+using RTCStatsReportCallback =
+ base::OnceCallback<void(std::unique_ptr<RTCStatsReportPlatform>)>;
+
+PLATFORM_EXPORT
+rtc::scoped_refptr<webrtc::RTCStatsCollectorCallback>
+CreateRTCStatsCollectorCallback(
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread,
+ RTCStatsReportCallback callback,
+ const Vector<webrtc::NonStandardGroupId>& exposed_group_ids);
+
// A stats collector callback.
// It is invoked on the WebRTC signaling thread and will post a task to invoke
// |callback| on the thread given in the |main_thread| argument.
@@ -127,18 +144,20 @@ class PLATFORM_EXPORT RTCStatsCollectorCallbackImpl
protected:
RTCStatsCollectorCallbackImpl(
scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- blink::WebRTCStatsReportCallback callback2,
- const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids);
+ RTCStatsReportCallback callback,
+ const Vector<webrtc::NonStandardGroupId>& exposed_group_ids);
~RTCStatsCollectorCallbackImpl() override;
void OnStatsDeliveredOnMainThread(
rtc::scoped_refptr<const webrtc::RTCStatsReport> report);
const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- blink::WebRTCStatsReportCallback callback_;
- blink::WebVector<webrtc::NonStandardGroupId> exposed_group_ids_;
+ RTCStatsReportCallback callback_;
+ Vector<webrtc::NonStandardGroupId> exposed_group_ids_;
};
+PLATFORM_EXPORT void WhitelistStatsForTesting(const char* type);
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_STATS_H_
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 5c83bbd6d7f..e013c6b151d 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(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
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 12678fb053f..98ec0d03b41 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
@@ -7,7 +7,7 @@
#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/web_rtc_stats.h"
+#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
#include "third_party/webrtc/api/stats/rtc_stats_report.h"
#include "third_party/webrtc/api/stats/rtcstats_objects.h"
#include "third_party/webrtc/stats/test/rtc_test_stats.h"
@@ -103,7 +103,7 @@ TEST(RTCStatsTest, IncludeAllMembers) {
// Include both standard and non-standard member.
RTCStatsReportPlatform report(
- webrtc_report.get(), std::vector<webrtc::NonStandardGroupId>{
+ webrtc_report.get(), Vector<webrtc::NonStandardGroupId>{
webrtc::NonStandardGroupId::kGroupIdForTesting});
std::unique_ptr<RTCStats> stats = report.GetStats("id");
ASSERT_NE(nullptr, stats);
@@ -127,7 +127,7 @@ TEST(RTCStatsTest, CopyHandle) {
ASSERT_EQ(1u, standard_members_copy->GetStats("id")->MembersCount());
RTCStatsReportPlatform all_members_report(
- webrtc_report.get(), std::vector<webrtc::NonStandardGroupId>{
+ webrtc_report.get(), Vector<webrtc::NonStandardGroupId>{
webrtc::NonStandardGroupId::kGroupIdForTesting});
std::unique_ptr<RTCStatsReportPlatform> all_members_copy =
all_members_report.CopyHandle();
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 3783f4c79f8..c61e2df1da5 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
@@ -8,6 +8,7 @@
#include <functional>
#include <utility>
+#include "base/bind_helpers.h"
#include "base/feature_list.h"
#include "base/location.h"
#include "base/logging.h"
@@ -18,6 +19,7 @@
#include "base/stl_util.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread_restrictions.h"
+#include "base/time/time.h"
#include "build/build_config.h"
#include "media/base/media_log.h"
#include "media/base/media_switches.h"
@@ -68,12 +70,6 @@ const int32_t kMaxDecodeHistory = 32;
// requesting fallback to software decode.
const int32_t kMaxConsecutiveErrors = 5;
-// 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.
-constexpr media::VideoDecoderImplementation kImplementation =
- media::VideoDecoderImplementation::kDefault;
-
// Map webrtc::VideoCodecType to media::VideoCodec.
media::VideoCodec ToVideoCodec(webrtc::VideoCodecType video_codec_type) {
switch (video_codec_type) {
@@ -123,10 +119,10 @@ void FinishWait(base::WaitableEvent* waiter, bool* result_out, bool result) {
}
void OnRequestOverlayInfo(bool decoder_requires_restart_for_overlay,
- const media::ProvideOverlayInfoCB& overlay_info_cb) {
+ media::ProvideOverlayInfoCB overlay_info_cb) {
// Android overlays are not supported.
if (overlay_info_cb)
- overlay_info_cb.Run(media::OverlayInfo());
+ std::move(overlay_info_cb).Run(media::OverlayInfo());
}
} // namespace
@@ -157,8 +153,9 @@ std::unique_ptr<RTCVideoDecoderAdapter> RTCVideoDecoderAdapter::Create(
kDefaultSize, media::EmptyExtraData(),
media::EncryptionScheme::kUnencrypted);
if (gpu_factories->IsDecoderConfigSupported(kImplementation, config) ==
- media::GpuVideoAcceleratorFactories::Supported::kFalse)
+ media::GpuVideoAcceleratorFactories::Supported::kFalse) {
return nullptr;
+ }
// Synchronously verify that the decoder can be initialized.
std::unique_ptr<RTCVideoDecoderAdapter> rtc_video_decoder_adapter =
@@ -209,7 +206,9 @@ bool RTCVideoDecoderAdapter::InitializeSync(
CrossThreadBindOnce(&RTCVideoDecoderAdapter::InitializeOnMediaThread,
CrossThreadUnretained(this), config,
std::move(init_cb)))) {
- waiter.Wait();
+ // TODO(crbug.com/1076817) Remove if a root cause is found.
+ if (!waiter.TimedWait(base::TimeDelta::FromSeconds(10)))
+ return false;
}
return result;
}
@@ -225,6 +224,10 @@ int32_t RTCVideoDecoderAdapter::InitDecode(
base::AutoLock auto_lock(lock_);
UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoDecoderInitDecodeSuccess", !has_error_);
+ if (!has_error_) {
+ UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoDecoderProfile",
+ GuessVideoCodecProfile(format_));
+ }
return has_error_ ? WEBRTC_VIDEO_CODEC_UNINITIALIZED : WEBRTC_VIDEO_CODEC_OK;
}
@@ -388,9 +391,17 @@ void RTCVideoDecoderAdapter::InitializeOnMediaThread(
media::VideoDecoder::OutputCB output_cb = ConvertToBaseRepeatingCallback(
CrossThreadBindRepeating(&RTCVideoDecoderAdapter::OnOutput, weak_this_));
- video_decoder_->Initialize(config, low_delay, cdm_context,
- ConvertToBaseOnceCallback(std::move(init_cb)),
- output_cb, base::DoNothing());
+ video_decoder_->Initialize(
+ config, low_delay, cdm_context,
+ base::BindOnce(&RTCVideoDecoderAdapter::OnInitializeDone,
+ ConvertToBaseOnceCallback(std::move(init_cb))),
+ output_cb, base::DoNothing());
+}
+
+// static
+void RTCVideoDecoderAdapter::OnInitializeDone(base::OnceCallback<void(bool)> cb,
+ media::Status status) {
+ std::move(cb).Run(status.is_ok());
}
void RTCVideoDecoderAdapter::DecodeOnMediaThread() {
@@ -454,7 +465,8 @@ void RTCVideoDecoderAdapter::OnOutput(scoped_refptr<media::VideoFrame> frame) {
webrtc::VideoFrame::Builder()
.set_video_frame_buffer(
new rtc::RefCountedObject<blink::WebRtcVideoFrameAdapter>(
- std::move(frame)))
+ std::move(frame),
+ WebRtcVideoFrameAdapter::LogStatus::kNoLogging))
.set_timestamp_rtp(static_cast<uint32_t>(timestamp.InMicroseconds()))
.set_timestamp_us(0)
.set_rotation(webrtc::kVideoRotation_0)
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 89bb76c62f2..9d67fb60e8b 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
@@ -14,9 +14,11 @@
#include "base/sequence_checker.h"
#include "base/synchronization/lock.h"
#include "media/base/decode_status.h"
+#include "media/base/status.h"
#include "media/base/video_codecs.h"
#include "media/base/video_decoder.h"
#include "media/base/video_decoder_config.h"
+#include "media/video/supported_video_decoder_config.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/deque.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
@@ -51,6 +53,12 @@ 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;
// Creates and initializes an RTCVideoDecoderAdapter. Returns nullptr if
// |format| cannot be supported.
// Called on the worker thread.
@@ -92,6 +100,8 @@ class PLATFORM_EXPORT RTCVideoDecoderAdapter : public webrtc::VideoDecoder {
bool InitializeSync(const media::VideoDecoderConfig& config);
void InitializeOnMediaThread(const media::VideoDecoderConfig& config,
InitCB init_cb);
+ static void OnInitializeDone(base::OnceCallback<void(bool)> cb,
+ media::Status status);
void DecodeOnMediaThread();
void OnDecodeDone(media::DecodeStatus status);
void OnOutput(scoped_refptr<media::VideoFrame> frame);
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter_test.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter_test.cc
index 213daa35f8a..37becc9aaf0 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter_test.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter_test.cc
@@ -162,8 +162,12 @@ class RTCVideoDecoderAdapterTest : public ::testing::Test {
bool CreateAndInitialize(bool init_cb_result = true) {
EXPECT_CALL(*video_decoder_, Initialize_(_, _, _, _, _, _))
- .WillOnce(DoAll(SaveArg<0>(&vda_config_), SaveArg<4>(&output_cb_),
- base::test::RunOnceCallback<3>(init_cb_result)));
+ .WillOnce(DoAll(
+ SaveArg<0>(&vda_config_), SaveArg<4>(&output_cb_),
+ base::test::RunOnceCallback<3>(
+ init_cb_result
+ ? media::OkStatus()
+ : media::Status(media::StatusCode::kCodeOnlyForTesting))));
rtc_video_decoder_adapter_ =
RTCVideoDecoderAdapter::Create(&gpu_factories_, sdp_format_);
return !!rtc_video_decoder_adapter_;
@@ -363,7 +367,7 @@ TEST_F(RTCVideoDecoderAdapterTest, ReinitializesForHDRColorSpaceInitially) {
// First Decode() should cause a reinitialize as new color space is given.
EXPECT_CALL(*video_decoder_, Initialize_(_, _, _, _, _, _))
.WillOnce(DoAll(SaveArg<0>(&vda_config_),
- base::test::RunOnceCallback<3>(true)));
+ base::test::RunOnceCallback<3>(media::OkStatus())));
webrtc::EncodedImage first_input_image = GetEncodedImageWithColorSpace(0);
ASSERT_EQ(rtc_video_decoder_adapter_->Decode(first_input_image, false, 0),
WEBRTC_VIDEO_CODEC_OK);
@@ -395,7 +399,8 @@ TEST_F(RTCVideoDecoderAdapterTest, HandlesReinitializeFailure) {
// Set Initialize() to fail.
EXPECT_CALL(*video_decoder_, Initialize_(_, _, _, _, _, _))
- .WillOnce(base::test::RunOnceCallback<3>(false));
+ .WillOnce(base::test::RunOnceCallback<3>(
+ media::Status(media::StatusCode::kCodeOnlyForTesting)));
ASSERT_EQ(rtc_video_decoder_adapter_->Decode(input_image, false, 0),
WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
}
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 2ab30075132..cb12d36124c 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
@@ -4,17 +4,128 @@
#include "third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_factory.h"
+#include <array>
#include <memory>
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "build/build_config.h"
+#include "media/base/media_util.h"
+#include "media/base/video_codecs.h"
#include "media/video/gpu_video_accelerator_factories.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.h"
+#include "third_party/webrtc/media/base/h264_profile_level_id.h"
+#include "third_party/webrtc/media/base/media_constants.h"
+#include "third_party/webrtc/media/base/vp9_profile.h"
+#include "ui/gfx/color_space.h"
+#include "ui/gfx/geometry/size.h"
namespace blink {
namespace {
+const int kDefaultFps = 30;
+// Any reasonable size, will be overridden by the decoder anyway.
+const gfx::Size kDefaultSize(640, 480);
+
+struct CodecConfig {
+ media::VideoCodec codec;
+ media::VideoCodecProfile profile;
+};
+
+constexpr std::array<CodecConfig, 6> kCodecConfigs = {{
+ {media::kCodecVP8, media::VP8PROFILE_ANY},
+ {media::kCodecVP9, media::VP9PROFILE_PROFILE0},
+ {media::kCodecVP9, media::VP9PROFILE_PROFILE2},
+ {media::kCodecH264, media::H264PROFILE_BASELINE},
+ {media::kCodecH264, media::H264PROFILE_MAIN},
+ {media::kCodecH264, media::H264PROFILE_HIGH},
+}};
+
+// Translate from media::VideoDecoderConfig to webrtc::SdpVideoFormat, or return
+// nothing if the profile isn't supported.
+base::Optional<webrtc::SdpVideoFormat> VdcToWebRtcFormat(
+ const media::VideoDecoderConfig& config) {
+ switch (config.codec()) {
+ case media::VideoCodec::kCodecVP8:
+ return webrtc::SdpVideoFormat("VP8");
+ case media::VideoCodec::kCodecVP9: {
+ webrtc::VP9Profile vp9_profile;
+ switch (config.profile()) {
+ case media::VP9PROFILE_PROFILE0:
+ vp9_profile = webrtc::VP9Profile::kProfile0;
+ break;
+ case media::VP9PROFILE_PROFILE2:
+ vp9_profile = webrtc::VP9Profile::kProfile2;
+ break;
+ default:
+ // Unsupported profile in WebRTC.
+ return base::nullopt;
+ }
+ return webrtc::SdpVideoFormat(
+ "VP9", {{webrtc::kVP9FmtpProfileId,
+ webrtc::VP9ProfileToString(vp9_profile)}});
+ }
+ case media::VideoCodec::kCodecH264: {
+ webrtc::H264::Profile h264_profile;
+ switch (config.profile()) {
+ case media::H264PROFILE_BASELINE:
+ h264_profile = webrtc::H264::kProfileBaseline;
+ break;
+ case media::H264PROFILE_MAIN:
+ h264_profile = webrtc::H264::kProfileMain;
+ break;
+ case media::H264PROFILE_HIGH:
+ h264_profile = webrtc::H264::kProfileHigh;
+ break;
+ default:
+ // Unsupported H264 profile in WebRTC.
+ return base::nullopt;
+ }
+
+ const int width = config.visible_rect().width();
+ const int height = config.visible_rect().height();
+
+ const absl::optional<webrtc::H264::Level> h264_level =
+ webrtc::H264::SupportedLevel(width * height, kDefaultFps);
+ const webrtc::H264::ProfileLevelId profile_level_id(
+ h264_profile, h264_level.value_or(webrtc::H264::kLevel1));
+
+ webrtc::SdpVideoFormat format("H264");
+ format.parameters = {
+ {cricket::kH264FmtpProfileLevelId,
+ *webrtc::H264::ProfileLevelIdToString(profile_level_id)},
+ {cricket::kH264FmtpLevelAsymmetryAllowed, "1"},
+ {cricket::kH264FmtpPacketizationMode, "1"}};
+ return format;
+ }
+ default:
+ return base::nullopt;
+ }
+}
+
+// Due to https://crbug.com/345569, HW decoders do not distinguish between
+// Constrained Baseline(CBP) and Baseline(BP) profiles. Since CBP is a subset of
+// BP, we can report support for both. It is safe to do so when SW fallback is
+// available.
+// TODO(emircan): Remove this when the bug referred above is fixed.
+void MapBaselineProfile(
+ std::vector<webrtc::SdpVideoFormat>* supported_formats) {
+ for (const auto& format : *supported_formats) {
+ const absl::optional<webrtc::H264::ProfileLevelId> profile_level_id =
+ webrtc::H264::ParseSdpProfileLevelId(format.parameters);
+ if (profile_level_id &&
+ profile_level_id->profile == webrtc::H264::kProfileBaseline) {
+ webrtc::SdpVideoFormat cbp_format = format;
+ webrtc::H264::ProfileLevelId cbp_profile = *profile_level_id;
+ cbp_profile.profile = webrtc::H264::kProfileConstrainedBaseline;
+ cbp_format.parameters[cricket::kH264FmtpProfileLevelId] =
+ *webrtc::H264::ProfileLevelIdToString(cbp_profile);
+ supported_formats->push_back(cbp_format);
+ return;
+ }
+ }
+}
+
// This extra indirection is needed so that we can delete the decoder on the
// correct thread.
class ScopedVideoDecoder : public webrtc::VideoDecoder {
@@ -66,8 +177,25 @@ RTCVideoDecoderFactory::RTCVideoDecoderFactory(
std::vector<webrtc::SdpVideoFormat>
RTCVideoDecoderFactory::GetSupportedFormats() const {
- NOTREACHED();
- return std::vector<webrtc::SdpVideoFormat>();
+ std::vector<webrtc::SdpVideoFormat> supported_formats;
+ for (auto& codec_config : kCodecConfigs) {
+ media::VideoDecoderConfig config(
+ codec_config.codec, codec_config.profile,
+ media::VideoDecoderConfig::AlphaMode::kIsOpaque,
+ 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);
+ }
+ }
+ }
+ MapBaselineProfile(&supported_formats);
+ return supported_formats;
}
RTCVideoDecoderFactory::~RTCVideoDecoderFactory() {
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder.cc
index fdb679f48a6..9f7a84d505d 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder.cc
@@ -20,19 +20,19 @@
#include "base/strings/stringprintf.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
+#include "base/thread_annotations.h"
#include "base/threading/thread_checker.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/bitstream_buffer.h"
-#include "media/base/media_switches.h"
#include "media/base/video_bitrate_allocation.h"
#include "media/base/video_frame.h"
#include "media/base/video_util.h"
+#include "media/capture/capture_switches.h"
#include "media/video/gpu_video_accelerator_factories.h"
#include "media/video/h264_parser.h"
#include "media/video/video_encode_accelerator.h"
-#include "mojo/public/cpp/base/shared_memory_utils.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.h"
@@ -61,6 +61,38 @@ namespace blink {
namespace {
+webrtc::VideoEncoder::EncoderInfo CopyToWebrtcEncoderInfo(
+ const media::VideoEncoderInfo& enc_info) {
+ webrtc::VideoEncoder::EncoderInfo info;
+ info.implementation_name = enc_info.implementation_name;
+ info.supports_native_handle = enc_info.supports_native_handle;
+ info.has_trusted_rate_controller = enc_info.has_trusted_rate_controller;
+ info.is_hardware_accelerated = enc_info.is_hardware_accelerated;
+ info.supports_simulcast = enc_info.supports_simulcast;
+ // TODO(crbug.com/1034686): Copy ScalingSettings once getStats() hang issue
+ // is resolved.
+ // info.scaling_settings = webrtc::VideoEncoder::ScalingSettings(
+ // enc_info.scaling_settings.min_qp, enc_info.scaling_settings.max_qp);
+ static_assert(
+ webrtc::kMaxSpatialLayers >= media::VideoEncoderInfo::kMaxSpatialLayers,
+ "webrtc::kMaxSpatiallayers is less than "
+ "media::VideoEncoderInfo::kMaxSpatialLayers");
+ for (size_t i = 0; i < base::size(enc_info.fps_allocation); ++i) {
+ if (enc_info.fps_allocation[i].empty())
+ continue;
+ info.fps_allocation[i] =
+ absl::InlinedVector<uint8_t, webrtc::kMaxTemporalStreams>(
+ enc_info.fps_allocation[i].begin(),
+ enc_info.fps_allocation[i].end());
+ }
+ for (const auto& limit : enc_info.resolution_bitrate_limits) {
+ info.resolution_bitrate_limits.emplace_back(
+ limit.frame_size.GetArea(), limit.min_start_bitrate_bps,
+ limit.min_bitrate_bps, limit.max_bitrate_bps);
+ }
+ return info;
+}
+
struct RTCTimestamps {
RTCTimestamps(const base::TimeDelta& media_timestamp,
int32_t rtp_timestamp,
@@ -156,6 +188,9 @@ class RTCVideoEncoder::Impl
media::VideoCodecProfile profile,
base::WaitableEvent* async_waiter,
int32_t* async_retval);
+
+ webrtc::VideoEncoder::EncoderInfo GetEncoderInfo() const;
+
// Enqueue a frame from WebRTC for encoding.
// RTCVideoEncoder expects to be able to call this function synchronously from
// its own thread, hence the |async_waiter| and |async_retval| arguments.
@@ -196,6 +231,7 @@ class RTCVideoEncoder::Impl
int32_t bitstream_buffer_id,
const media::BitstreamBufferMetadata& metadata) override;
void NotifyError(media::VideoEncodeAccelerator::Error error) override;
+ void NotifyEncoderInfoChange(const media::VideoEncoderInfo& info) override;
private:
friend class base::RefCountedThreadSafe<Impl>;
@@ -319,15 +355,18 @@ class RTCVideoEncoder::Impl
// The content type, as reported to WebRTC (screenshare vs realtime video).
const webrtc::VideoContentType video_content_type_;
- // Protect |status_|. |status_| is read or written on |gpu_task_runner_| in
- // Impl. It can be read in RTCVideoEncoder on other threads.
- mutable base::Lock status_lock_;
+ webrtc::VideoEncoder::EncoderInfo encoder_info_ GUARDED_BY(lock_);
+
+ // Protect |status_| and |encoder_info_|. |status_| is read or written on
+ // |gpu_task_runner_| in Impl. It can be read in RTCVideoEncoder on other
+ // threads.
+ mutable base::Lock lock_;
// We cannot immediately return error conditions to the WebRTC user of this
// class, as there is no error callback in the webrtc::VideoEncoder interface.
// Instead, we cache an error status here and return it the next time an
- // interface entry point is called. This is protected by |status_lock_|.
- int32_t status_;
+ // interface entry point is called. This is protected by |lock_|.
+ int32_t status_ GUARDED_BY(lock_);
DISALLOW_COPY_AND_ASSIGN(Impl);
};
@@ -348,6 +387,13 @@ RTCVideoEncoder::Impl::Impl(media::GpuVideoAcceleratorFactories* gpu_factories,
video_content_type_(video_content_type),
status_(WEBRTC_VIDEO_CODEC_UNINITIALIZED) {
DETACH_FROM_THREAD(thread_checker_);
+
+ // The default values of EncoderInfo.
+ encoder_info_.implementation_name =
+ RTCVideoEncoder::Impl::ImplementationName();
+ encoder_info_.supports_native_handle = true;
+ encoder_info_.is_hardware_accelerated = true;
+ encoder_info_.has_internal_source = false;
}
void RTCVideoEncoder::Impl::CreateAndInitializeVEA(
@@ -369,8 +415,10 @@ void RTCVideoEncoder::Impl::CreateAndInitializeVEA(
// Check that |profile| supports |input_visible_size|.
if (base::FeatureList::IsEnabled(features::kWebRtcUseMinMaxVEADimensions)) {
const auto vea_supported_profiles =
- gpu_factories_->GetVideoEncodeAcceleratorSupportedProfiles();
- for (const auto vea_profile : vea_supported_profiles) {
+ gpu_factories_->GetVideoEncodeAcceleratorSupportedProfiles().value_or(
+ media::VideoEncodeAccelerator::SupportedProfiles());
+
+ for (const auto& vea_profile : vea_supported_profiles) {
if (vea_profile.profile == profile &&
(input_visible_size.width() > vea_profile.max_resolution.width() ||
input_visible_size.height() > vea_profile.max_resolution.height() ||
@@ -424,6 +472,18 @@ void RTCVideoEncoder::Impl::CreateAndInitializeVEA(
// be signaled.
}
+webrtc::VideoEncoder::EncoderInfo RTCVideoEncoder::Impl::GetEncoderInfo()
+ const {
+ base::AutoLock lock(lock_);
+ return encoder_info_;
+}
+
+void RTCVideoEncoder::Impl::NotifyEncoderInfoChange(
+ const media::VideoEncoderInfo& info) {
+ base::AutoLock lock(lock_);
+ encoder_info_ = CopyToWebrtcEncoderInfo(info);
+}
+
void RTCVideoEncoder::Impl::Enqueue(const webrtc::VideoFrame* input_frame,
bool force_keyframe,
base::WaitableEvent* async_waiter,
@@ -542,12 +602,12 @@ void RTCVideoEncoder::Impl::Destroy(base::WaitableEvent* async_waiter) {
}
int32_t RTCVideoEncoder::Impl::GetStatus() const {
- base::AutoLock lock(status_lock_);
+ base::AutoLock lock(lock_);
return status_;
}
void RTCVideoEncoder::Impl::SetStatus(int32_t status) {
- base::AutoLock lock(status_lock_);
+ base::AutoLock lock(lock_);
status_ = status;
}
@@ -571,9 +631,9 @@ void RTCVideoEncoder::Impl::RequireBitstreamBuffers(
input_frame_coded_size_ = input_coded_size;
for (unsigned int i = 0; i < input_count + kInputBufferExtraCount; ++i) {
- base::UnsafeSharedMemoryRegion shm =
- mojo::CreateUnsafeSharedMemoryRegion(media::VideoFrame::AllocationSize(
- media::PIXEL_FORMAT_I420, input_coded_size));
+ base::UnsafeSharedMemoryRegion shm = base::UnsafeSharedMemoryRegion::Create(
+ media::VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420,
+ input_coded_size));
if (!shm.IsValid()) {
LogAndNotifyError(FROM_HERE, "failed to create input buffer ",
media::VideoEncodeAccelerator::kPlatformFailureError);
@@ -1223,11 +1283,10 @@ void RTCVideoEncoder::SetRates(
}
webrtc::VideoEncoder::EncoderInfo RTCVideoEncoder::GetEncoderInfo() const {
- EncoderInfo info;
- info.implementation_name = RTCVideoEncoder::Impl::ImplementationName();
- info.supports_native_handle = true;
- info.is_hardware_accelerated = true;
- info.has_internal_source = false;
+ webrtc::VideoEncoder::EncoderInfo info;
+ if (impl_)
+ info = impl_->GetEncoderInfo();
+
return info;
}
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_factory.cc b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_factory.cc
index 5ba62ba4f96..2ad849e639a 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_factory.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_factory.cc
@@ -21,6 +21,31 @@ namespace blink {
namespace {
+base::Optional<media::VideoCodecProfile> WebRTCFormatToCodecProfile(
+ const webrtc::SdpVideoFormat& sdp) {
+ if (sdp.name == "H264") {
+#if !defined(OS_ANDROID)
+ // Enable H264 HW encode for WebRTC when SW fallback is available, which is
+ // checked by kWebRtcH264WithOpenH264FFmpeg flag. This check should be
+ // removed when SW implementation is fully enabled.
+ bool webrtc_h264_sw_enabled = false;
+#if BUILDFLAG(RTC_USE_H264) && BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
+ webrtc_h264_sw_enabled = base::FeatureList::IsEnabled(
+ blink::features::kWebRtcH264WithOpenH264FFmpeg);
+#endif // BUILDFLAG(RTC_USE_H264) && BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
+ if (!webrtc_h264_sw_enabled)
+ return base::nullopt;
+#endif
+
+ return media::VideoCodecProfile::H264PROFILE_MIN;
+ } else if (sdp.name == "VP8") {
+ return media::VideoCodecProfile::VP8PROFILE_MIN;
+ } else if (sdp.name == "VP9") {
+ return media::VideoCodecProfile::VP9PROFILE_MIN;
+ }
+ return base::nullopt;
+}
+
// Translate from media::VideoEncodeAccelerator::SupportedProfile to
// webrtc::SdpVideoFormat, or return nothing if the profile isn't supported.
base::Optional<webrtc::SdpVideoFormat> VEAToWebRTCFormat(
@@ -101,38 +126,63 @@ bool IsSameFormat(const webrtc::SdpVideoFormat& format1,
format2.parameters);
}
-} // anonymous namespace
-
-RTCVideoEncoderFactory::RTCVideoEncoderFactory(
- media::GpuVideoAcceleratorFactories* gpu_factories)
- : gpu_factories_(gpu_factories) {
- const media::VideoEncodeAccelerator::SupportedProfiles& profiles =
- gpu_factories_->GetVideoEncodeAcceleratorSupportedProfiles();
- for (const auto& profile : profiles) {
+struct SupportedFormats {
+ bool unknown = true;
+ std::vector<media::VideoCodecProfile> profiles;
+ std::vector<webrtc::SdpVideoFormat> sdp_formats;
+};
+
+SupportedFormats GetSupportedFormatsInternal(
+ media::GpuVideoAcceleratorFactories* gpu_factories) {
+ SupportedFormats supported_formats;
+ auto profiles = gpu_factories->GetVideoEncodeAcceleratorSupportedProfiles();
+ if (!profiles)
+ return supported_formats;
+
+ // |profiles| are either the info at GpuInfo instance or the info got by
+ // querying GPU process.
+ supported_formats.unknown = false;
+ for (const auto& profile : *profiles) {
base::Optional<webrtc::SdpVideoFormat> format = VEAToWebRTCFormat(profile);
if (format) {
- supported_formats_.push_back(std::move(*format));
- profiles_.push_back(profile.profile);
+ supported_formats.profiles.push_back(profile.profile);
+ supported_formats.sdp_formats.push_back(std::move(*format));
}
}
+ return supported_formats;
}
+} // anonymous namespace
+
+RTCVideoEncoderFactory::RTCVideoEncoderFactory(
+ media::GpuVideoAcceleratorFactories* gpu_factories)
+ : gpu_factories_(gpu_factories) {}
+
RTCVideoEncoderFactory::~RTCVideoEncoderFactory() {}
std::unique_ptr<webrtc::VideoEncoder>
RTCVideoEncoderFactory::CreateVideoEncoder(
const webrtc::SdpVideoFormat& format) {
- for (size_t i = 0; i < supported_formats_.size(); ++i) {
- if (IsSameFormat(format, supported_formats_[i])) {
- return std::make_unique<RTCVideoEncoder>(profiles_[i], gpu_factories_);
+ std::unique_ptr<webrtc::VideoEncoder> encoder;
+ auto supported_formats = GetSupportedFormatsInternal(gpu_factories_);
+ if (!supported_formats.unknown) {
+ for (size_t i = 0; i < supported_formats.sdp_formats.size(); ++i) {
+ if (IsSameFormat(format, supported_formats.sdp_formats[i])) {
+ encoder = std::make_unique<RTCVideoEncoder>(
+ supported_formats.profiles[i], gpu_factories_);
+ }
}
+ } else {
+ auto profile = WebRTCFormatToCodecProfile(format);
+ if (profile)
+ encoder = std::make_unique<RTCVideoEncoder>(*profile, gpu_factories_);
}
- return nullptr;
+ return encoder;
}
std::vector<webrtc::SdpVideoFormat>
RTCVideoEncoderFactory::GetSupportedFormats() const {
- return supported_formats_;
+ return GetSupportedFormatsInternal(gpu_factories_).sdp_formats;
}
webrtc::VideoEncoderFactory::CodecInfo
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_factory.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_factory.h
index 06236092987..72f0768a1db 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_factory.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_video_encoder_factory.h
@@ -9,6 +9,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/optional.h"
#include "media/base/video_codecs.h"
#include "third_party/webrtc/api/video_codecs/video_encoder_factory.h"
@@ -36,12 +37,6 @@ class RTCVideoEncoderFactory : public webrtc::VideoEncoderFactory {
private:
media::GpuVideoAcceleratorFactories* gpu_factories_;
- // List of supported webrtc::SdpVideoFormat. |profiles_| and
- // |supported_formats_| have the same length and the profile for
- // |supported_formats_[i]| is |profiles_[i]|.
- std::vector<media::VideoCodecProfile> profiles_;
- std::vector<webrtc::SdpVideoFormat> supported_formats_;
-
DISALLOW_COPY_AND_ASSIGN(RTCVideoEncoderFactory);
};
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 173a1bddab5..9376feb9ced 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(blink::Visitor* visitor) {}
+ virtual void Trace(Visitor* visitor) {}
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 792fc6562b7..75e3561bd2b 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
@@ -5,11 +5,12 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_TWO_KEYS_ADAPTER_MAP_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_TWO_KEYS_ADAPTER_MAP_H_
-#include <map>
#include <memory>
#include <utility>
#include "base/logging.h"
+#include "base/optional.h"
+#include "third_party/blink/renderer/platform/wtf/hash_map.h"
namespace blink {
@@ -27,10 +28,6 @@ namespace blink {
// webrtc/blink object that was used to create the adapter and the secondary key
// is based on the resulting blink/webrtc object after the adapter has been
// initialized.
-//
-// TODO(crbug.com/787254): Move this class out of the Blink exposed API when
-// its clients get Onion souped, and change the use of std::map below to
-// WTF::HashMap.
template <typename PrimaryKey, typename SecondaryKey, typename Value>
class TwoKeysAdapterMap {
public:
@@ -41,13 +38,13 @@ class TwoKeysAdapterMap {
// words |!FindByPrimary(primary)| must hold.
Value* Insert(PrimaryKey primary, Value value) {
DCHECK(entries_by_primary_.find(primary) == entries_by_primary_.end());
- auto it = entries_by_primary_
- .insert(std::make_pair(
- std::move(primary),
- std::unique_ptr<Entry>(new Entry(std::move(value)))))
- .first;
- it->second->primary_it = it;
- return &it->second->value;
+ auto* add_result =
+ entries_by_primary_
+ .insert(std::move(primary),
+ std::unique_ptr<Entry>(new Entry(std::move(value))))
+ .stored_value;
+ add_result->value->primary_key = add_result->key;
+ return &add_result->value->value;
}
// Maps the secondary key to the value mapped by the primary key, increasing
@@ -61,11 +58,10 @@ class TwoKeysAdapterMap {
DCHECK(it != entries_by_primary_.end());
DCHECK(entries_by_secondary_.find(secondary) ==
entries_by_secondary_.end());
- Entry* entry = it->second.get();
- entry->secondary_it =
- entries_by_secondary_
- .insert(std::make_pair(std::move(secondary), entry))
- .first;
+ Entry* entry = it->value.get();
+ auto* add_result =
+ entries_by_secondary_.insert(std::move(secondary), entry).stored_value;
+ entry->secondary_key = add_result->key;
}
// Returns a pointer to the value mapped by the primary key, or null if the
@@ -75,7 +71,7 @@ class TwoKeysAdapterMap {
auto it = entries_by_primary_.find(primary);
if (it == entries_by_primary_.end())
return nullptr;
- return &it->second->value;
+ return &it->value->value;
}
// Returns a pointer to the value mapped by the secondary key, or null if the
@@ -85,7 +81,7 @@ class TwoKeysAdapterMap {
auto it = entries_by_secondary_.find(secondary);
if (it == entries_by_secondary_.end())
return nullptr;
- return &it->second->value;
+ return &it->value->value;
}
// Erases the value associated with the primary key, removing the mapping of
@@ -95,8 +91,13 @@ class TwoKeysAdapterMap {
auto primary_it = entries_by_primary_.find(primary);
if (primary_it == entries_by_primary_.end())
return false;
- if (primary_it->second->secondary_it != entries_by_secondary_.end())
- entries_by_secondary_.erase(primary_it->second->secondary_it);
+
+ if (primary_it->value->secondary_key.has_value()) {
+ auto secondary_it =
+ entries_by_secondary_.find(*primary_it->value->secondary_key);
+ if (secondary_it != entries_by_secondary_.end())
+ entries_by_secondary_.erase(secondary_it);
+ }
entries_by_primary_.erase(primary_it);
return true;
}
@@ -108,7 +109,10 @@ class TwoKeysAdapterMap {
auto secondary_it = entries_by_secondary_.find(secondary);
if (secondary_it == entries_by_secondary_.end())
return false;
- entries_by_primary_.erase(secondary_it->second->primary_it);
+
+ auto primary_it =
+ entries_by_primary_.find(secondary_it->value->primary_key);
+ entries_by_primary_.erase(primary_it);
entries_by_secondary_.erase(secondary_it);
return true;
}
@@ -117,21 +121,34 @@ class TwoKeysAdapterMap {
size_t PrimarySize() const { return entries_by_primary_.size(); }
// The number of elements in the map which have secondary keys.
size_t SecondarySize() const { return entries_by_secondary_.size(); }
- bool empty() const { return entries_by_primary_.empty(); }
+ bool empty() const { return entries_by_primary_.IsEmpty(); }
private:
- // TODO(crbug.com/787254): Move this class out of the Blink exposed API when
- // its clients get Onion souped.
struct Entry {
Entry(Value value) : value(std::move(value)) {}
Value value;
- typename std::map<PrimaryKey, std::unique_ptr<Entry>>::iterator primary_it;
- typename std::map<SecondaryKey, Entry*>::iterator secondary_it;
+
+ // The primary and secondary keys are cached here, instead of the
+ // respective iterators, because WTF::HashMap invalidates iterators
+ // upon changes on the set (eg insertion, deletions).
+ //
+ // Entries are only created in TwoKeysAdapterMap::Insert, which initializes
+ // |primary_key| right afterward (so it can never be read while
+ // uninitialized).
+ PrimaryKey primary_key;
+
+ // However, for |secondary_key|, calling EraseByPrimaryKey() can
+ // read an uninitialized secondary_key in case it is left uninitialized.
+ // Hence, it is guarded with base::Optional.
+ base::Optional<SecondaryKey> secondary_key;
};
- typename std::map<PrimaryKey, std::unique_ptr<Entry>> entries_by_primary_;
- typename std::map<SecondaryKey, Entry*> entries_by_secondary_;
+ using PrimaryMap = WTF::HashMap<PrimaryKey, std::unique_ptr<Entry>>;
+ using SecondaryMap = WTF::HashMap<SecondaryKey, Entry*>;
+
+ PrimaryMap entries_by_primary_;
+ SecondaryMap entries_by_secondary_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/two_keys_adapter_map_unittest.cc b/chromium/third_party/blink/renderer/platform/peerconnection/two_keys_adapter_map_unittest.cc
index 0d27ce7e9ae..511f5322f13 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/two_keys_adapter_map_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/two_keys_adapter_map_unittest.cc
@@ -6,25 +6,27 @@
#include "base/macros.h"
#include "testing/gtest/include/gtest/gtest.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 {
class TwoKeysAdapterMapTest : public ::testing::Test {
public:
struct MoveOnlyValue {
- explicit MoveOnlyValue(std::string str) : str(std::move(str)) {}
+ explicit MoveOnlyValue(String str) : str(std::move(str)) {}
MoveOnlyValue(MoveOnlyValue&& other) : str(std::move(other.str)) {}
MoveOnlyValue& operator=(MoveOnlyValue&& other) {
str = std::move(other.str);
return *this;
}
- std::string str;
+ String str;
DISALLOW_COPY_AND_ASSIGN(MoveOnlyValue);
};
- TwoKeysAdapterMap<std::string, std::string, MoveOnlyValue> map_;
+ TwoKeysAdapterMap<String, String, MoveOnlyValue> map_;
};
TEST_F(TwoKeysAdapterMapTest, ShouldInitiallyBeEmpty) {
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc
index 0f6c85f8258..2de94cef8fa 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc
@@ -11,10 +11,21 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/stl_util.h"
+#include "base/strings/stringprintf.h"
+#include "media/base/audio_timestamp_helper.h"
+#include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.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/webrtc/rtc_base/ref_counted_object.h"
+namespace {
+
+void SendLogMessage(const std::string& message) {
+ blink::WebRtcLogMessage("WRAS::" + message);
+}
+
+} // namespace
+
namespace WTF {
template <>
@@ -48,12 +59,14 @@ WebRtcAudioSink::WebRtcAudioSink(
fifo_(ConvertToBaseRepeatingCallback(
CrossThreadBindRepeating(&WebRtcAudioSink::DeliverRebufferedAudio,
CrossThreadUnretained(this)))) {
- DVLOG(1) << "WebRtcAudioSink::WebRtcAudioSink()";
+ SendLogMessage(base::StringPrintf("WebRtcAudioSink({label=%s})",
+ adapter_->label().c_str()));
}
WebRtcAudioSink::~WebRtcAudioSink() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DVLOG(1) << "WebRtcAudioSink::~WebRtcAudioSink()";
+ SendLogMessage(base::StringPrintf("~WebRtcAudioSink([label=%s])",
+ adapter_->label().c_str()));
}
void WebRtcAudioSink::SetAudioProcessor(
@@ -72,6 +85,9 @@ void WebRtcAudioSink::SetLevel(
void WebRtcAudioSink::OnEnabledChanged(bool enabled) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ SendLogMessage(base::StringPrintf("OnEnabledChanged([label=%s] {enabled=%s})",
+ adapter_->label().c_str(),
+ (enabled ? "true" : "false")));
PostCrossThreadTask(
*adapter_->signaling_task_runner(), FROM_HERE,
CrossThreadBindOnce(
@@ -83,6 +99,16 @@ void WebRtcAudioSink::OnData(const media::AudioBus& audio_bus,
base::TimeTicks estimated_capture_time) {
// No thread check: OnData might be called on different threads (but not
// concurrently).
+
+ // TODO(crbug.com/1054769): Better to let |fifo_| handle the estimated capture
+ // time and let it return a corrected interpolated capture time to
+ // DeliverRebufferedAudio(). Current, similar treatment is used at different
+ // places where |AudioPushFifo| is applied. So a update to |AudioPushFifo|
+ // will be a joint effort, and should be carefully carried out.
+ last_estimated_capture_time_ = estimated_capture_time;
+
+ adapter_->UpdateTimestampAligner(estimated_capture_time);
+
// The following will result in zero, one, or multiple synchronous calls to
// DeliverRebufferedAudio().
fifo_.Push(audio_bus);
@@ -90,6 +116,9 @@ void WebRtcAudioSink::OnData(const media::AudioBus& audio_bus,
void WebRtcAudioSink::OnSetFormat(const media::AudioParameters& params) {
DCHECK(params.IsValid());
+ SendLogMessage(base::StringPrintf("OnSetFormat([label=%s] {params=[%s]})",
+ adapter_->label().c_str(),
+ params.AsHumanReadableString().c_str()));
params_ = params;
// Make sure that our params always reflect a buffer size of 10ms.
params_.set_frames_per_buffer(params_.sample_rate() / 100);
@@ -112,9 +141,14 @@ void WebRtcAudioSink::DeliverRebufferedAudio(const media::AudioBus& audio_bus,
"ToInterleaved expects 2 bytes.");
audio_bus.ToInterleaved<media::SignedInt16SampleTypeTraits>(
audio_bus.frames(), interleaved_data_.get());
+
+ const base::TimeTicks estimated_capture_time =
+ last_estimated_capture_time_ + media::AudioTimestampHelper::FramesToTime(
+ frame_delay, params_.sample_rate());
+
adapter_->DeliverPCMToWebRtcSinks(interleaved_data_.get(),
params_.sample_rate(), audio_bus.channels(),
- audio_bus.frames());
+ audio_bus.frames(), estimated_capture_time);
}
namespace {
@@ -129,14 +163,19 @@ WebRtcAudioSink::Adapter::Adapter(
scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner)
: webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>(label),
+ label_(label),
source_(std::move(source)),
signaling_task_runner_(std::move(signaling_task_runner)),
main_task_runner_(std::move(main_task_runner)) {
DCHECK(signaling_task_runner_);
DCHECK(main_task_runner_);
+ SendLogMessage(
+ base::StringPrintf("Adapter::Adapter({label=%s})", label_.c_str()));
}
WebRtcAudioSink::Adapter::~Adapter() {
+ SendLogMessage(
+ base::StringPrintf("Adapter::~Adapter([label=%s])", label_.c_str()));
if (audio_processor_) {
PostCrossThreadTask(*main_task_runner_.get(), FROM_HERE,
CrossThreadBindOnce(&DereferenceOnMainThread,
@@ -148,11 +187,20 @@ void WebRtcAudioSink::Adapter::DeliverPCMToWebRtcSinks(
const int16_t* audio_data,
int sample_rate,
size_t number_of_channels,
- size_t number_of_frames) {
+ size_t number_of_frames,
+ base::TimeTicks estimated_capture_time) {
base::AutoLock auto_lock(lock_);
+
+ // This use |timestamp_aligner_| to transform |estimated_capture_timestamp| to
+ // rtc::TimeMicros(). See the comment at UpdateTimestampAligner() for more
+ // details.
+ const int64_t capture_timestamp_us = timestamp_aligner_.TranslateTimestamp(
+ estimated_capture_time.since_origin().InMicroseconds());
+
for (webrtc::AudioTrackSinkInterface* sink : sinks_) {
sink->OnData(audio_data, sizeof(int16_t) * 8, sample_rate,
- number_of_channels, number_of_frames);
+ number_of_channels, number_of_frames,
+ capture_timestamp_us / rtc::kNumMicrosecsPerMillisec);
}
}
@@ -163,6 +211,9 @@ std::string WebRtcAudioSink::Adapter::kind() const {
bool WebRtcAudioSink::Adapter::set_enabled(bool enable) {
DCHECK(!signaling_task_runner_ ||
signaling_task_runner_->RunsTasksInCurrentSequence());
+ SendLogMessage(
+ base::StringPrintf("Adapter::set_enabled([label=%s] {enable=%s})",
+ label_.c_str(), (enable ? "true" : "false")));
return webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>::set_enabled(
enable);
}
@@ -171,6 +222,8 @@ void WebRtcAudioSink::Adapter::AddSink(webrtc::AudioTrackSinkInterface* sink) {
DCHECK(!signaling_task_runner_ ||
signaling_task_runner_->RunsTasksInCurrentSequence());
DCHECK(sink);
+ SendLogMessage(
+ base::StringPrintf("Adapter::AddSink({label=%s})", label_.c_str()));
base::AutoLock auto_lock(lock_);
DCHECK(!base::Contains(sinks_, sink));
sinks_.push_back(sink);
@@ -180,6 +233,8 @@ void WebRtcAudioSink::Adapter::RemoveSink(
webrtc::AudioTrackSinkInterface* sink) {
DCHECK(!signaling_task_runner_ ||
signaling_task_runner_->RunsTasksInCurrentSequence());
+ SendLogMessage(
+ base::StringPrintf("Adapter::RemoveSink([label=%s])", label_.c_str()));
base::AutoLock auto_lock(lock_);
const auto it = std::find(sinks_.begin(), sinks_.end(), sink);
if (it != sinks_.end())
@@ -200,6 +255,8 @@ bool WebRtcAudioSink::Adapter::GetSignalLevel(int* level) {
// Convert from float in range [0.0,1.0] to an int in range [0,32767].
*level = static_cast<int>(signal_level * std::numeric_limits<int16_t>::max() +
0.5f /* rounding to nearest int */);
+ // TODO(crbug/1073391): possibly log the signal level but first check the
+ // calling frequency of this method to avoid creating too much data.
return true;
}
@@ -216,4 +273,16 @@ webrtc::AudioSourceInterface* WebRtcAudioSink::Adapter::GetSource() const {
return source_.get();
}
+void WebRtcAudioSink::Adapter::UpdateTimestampAligner(
+ base::TimeTicks capture_time) {
+ // The |timestamp_aligner_| stamps an audio frame as if it is captured 'now',
+ // taking rtc::TimeMicros as the reference clock. It does not provide the time
+ // that the frame was originally captured, Using |timestamp_aligner_| rather
+ // than calling rtc::TimeMicros is to take the advantage that it aligns its
+ // output timestamps such that the time spacing in the |capture_time| is
+ // maintained.
+ timestamp_aligner_.TranslateTimestamp(
+ capture_time.since_origin().InMicroseconds(), rtc::TimeMicros());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.h b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.h
index b405636dffe..20782171732 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.h
@@ -24,6 +24,8 @@
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/webrtc/api/media_stream_interface.h"
#include "third_party/webrtc/pc/media_stream_track.h"
+#include "third_party/webrtc/rtc_base/time_utils.h"
+#include "third_party/webrtc/rtc_base/timestamp_aligner.h"
namespace blink {
@@ -100,7 +102,10 @@ class PLATFORM_EXPORT WebRtcAudioSink : public WebMediaStreamAudioSink {
void DeliverPCMToWebRtcSinks(const int16_t* audio_data,
int sample_rate,
size_t number_of_channels,
- size_t number_of_frames);
+ size_t number_of_frames,
+ base::TimeTicks estimated_capture_time);
+
+ std::string label() const { return label_; }
// webrtc::MediaStreamTrack implementation.
std::string kind() const override;
@@ -114,10 +119,14 @@ class PLATFORM_EXPORT WebRtcAudioSink : public WebMediaStreamAudioSink {
override;
webrtc::AudioSourceInterface* GetSource() const override;
+ void UpdateTimestampAligner(base::TimeTicks capture_time);
+
protected:
~Adapter() override;
private:
+ const std::string label_;
+
const scoped_refptr<webrtc::AudioSourceInterface> source_;
// Task runner for operations that must be done on libjingle's signaling
@@ -147,6 +156,11 @@ class PLATFORM_EXPORT WebRtcAudioSink : public WebMediaStreamAudioSink {
// receive the audio data.
std::vector<webrtc::AudioTrackSinkInterface*> sinks_;
+ // Used for getting capture timestamps referenced on the rtc::TimeMicros()
+ // clock. See the comment at the implementation of UpdateTimestampAligner()
+ // for more details.
+ rtc::TimestampAligner timestamp_aligner_;
+
DISALLOW_COPY_AND_ASSIGN(Adapter);
};
@@ -178,6 +192,8 @@ class PLATFORM_EXPORT WebRtcAudioSink : public WebMediaStreamAudioSink {
// interleaved samples.
std::unique_ptr<int16_t[]> interleaved_data_;
+ base::TimeTicks last_estimated_capture_time_;
+
// In debug builds, check that WebRtcAudioSink's public methods are all being
// called on the main render thread.
THREAD_CHECKER(thread_checker_);
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink_test.cc b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink_test.cc
new file mode 100644
index 00000000000..0088ef19091
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink_test.cc
@@ -0,0 +1,126 @@
+// 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/peerconnection/webrtc_audio_sink.h"
+
+#include "media/base/fake_single_thread_task_runner.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::_;
+
+namespace blink {
+
+namespace {
+
+class MockAudioSink : public webrtc::AudioTrackSinkInterface {
+ public:
+ MockAudioSink() = default;
+ ~MockAudioSink() override = default;
+ MOCK_METHOD6(OnData,
+ void(const void* audio_data,
+ int bits_per_sample,
+ int sample_rate,
+ size_t number_of_channels,
+ size_t number_of_samples,
+ absl::optional<int64_t> absolute_capture_timestamp_ms));
+};
+
+class ScopedFakeClock : public rtc::ClockInterface {
+ public:
+ explicit ScopedFakeClock(int64_t init_time_ms)
+ : prev_clock_(rtc::SetClockForTesting(this)),
+ time_ns_(init_time_ms * rtc::kNumNanosecsPerMillisec) {}
+
+ ~ScopedFakeClock() override { rtc::SetClockForTesting(prev_clock_); }
+
+ int64_t TimeNanos() const override { return time_ns_; }
+
+ void AdvanceTimeMilliseconds(int64_t time_ms) {
+ time_ns_ += time_ms * rtc::kNumNanosecsPerMillisec;
+ }
+
+ private:
+ ClockInterface* const prev_clock_;
+ int64_t time_ns_;
+};
+
+} // namespace
+
+TEST(WebRtcAudioSinkTest, CaptureTimestamp) {
+ MockAudioSink sink_1;
+ MockAudioSink sink_2;
+ base::SimpleTestTickClock dummy_clock;
+ std::unique_ptr<WebRtcAudioSink> webrtc_audio_sink(
+ new WebRtcAudioSink("test_sink", nullptr,
+ /*signaling_task_runner=*/
+ new media::FakeSingleThreadTaskRunner(&dummy_clock),
+ /*main_task_runner=*/
+ new media::FakeSingleThreadTaskRunner(&dummy_clock)));
+
+ // |web_media_stream_audio_sink| is to access methods that are privately
+ // inherited by WebRtcAudioSink.
+ WebMediaStreamAudioSink* const web_media_stream_audio_sink =
+ static_cast<WebMediaStreamAudioSink*>(webrtc_audio_sink.get());
+
+ webrtc_audio_sink->webrtc_audio_track()->AddSink(&sink_1);
+ webrtc_audio_sink->webrtc_audio_track()->AddSink(&sink_2);
+
+ constexpr int kInputChannels = 2;
+ constexpr int kInputFramesPerBuffer = 96;
+ constexpr int kSampleRateHz = 8000;
+ constexpr int kOutputFramesPerBuffer = kSampleRateHz / 100;
+ constexpr int kEnqueueFrames = kInputFramesPerBuffer - kOutputFramesPerBuffer;
+
+ constexpr int64_t kStartRtcTimestampMs = 87654321;
+ constexpr int64_t kStartCaptureTimestampMs = 12345678;
+ constexpr int64_t kCaptureIntervalMs = 567;
+
+ web_media_stream_audio_sink->OnSetFormat(media::AudioParameters(
+ media::AudioParameters::AUDIO_PCM_LINEAR, media::CHANNEL_LAYOUT_STEREO,
+ kSampleRateHz, kOutputFramesPerBuffer));
+ std::unique_ptr<media::AudioBus> bus =
+ media::AudioBus::Create(kInputChannels, kInputFramesPerBuffer);
+ bus->Zero();
+
+ {
+ ScopedFakeClock clock(kStartRtcTimestampMs);
+
+ base::TimeTicks capture_time =
+ base::TimeTicks() +
+ base::TimeDelta::FromMilliseconds(kStartCaptureTimestampMs);
+
+ // The first time to the call OnData(), the TimestampAligner should have no
+ // effect work. So expected capture timestamp is from fake_clock.
+ EXPECT_CALL(
+ sink_1,
+ OnData(_, _, kSampleRateHz, kInputChannels, kOutputFramesPerBuffer,
+ absl::make_optional<int64_t>(kStartRtcTimestampMs)));
+ EXPECT_CALL(
+ sink_2,
+ OnData(_, _, kSampleRateHz, kInputChannels, kOutputFramesPerBuffer,
+ absl::make_optional<int64_t>(kStartRtcTimestampMs)));
+
+ web_media_stream_audio_sink->OnData(*bus, capture_time);
+
+ capture_time += base::TimeDelta::FromMilliseconds(kCaptureIntervalMs);
+ clock.AdvanceTimeMilliseconds(kCaptureIntervalMs);
+
+ constexpr int64_t kExpectedTimestampMs =
+ kStartRtcTimestampMs + kCaptureIntervalMs -
+ kEnqueueFrames * 1000 / kSampleRateHz;
+ EXPECT_CALL(
+ sink_1,
+ OnData(_, _, kSampleRateHz, kInputChannels, kOutputFramesPerBuffer,
+ absl::make_optional<int64_t>(kExpectedTimestampMs)));
+ EXPECT_CALL(
+ sink_2,
+ OnData(_, _, kSampleRateHz, kInputChannels, kOutputFramesPerBuffer,
+ absl::make_optional<int64_t>(kExpectedTimestampMs)));
+
+ web_media_stream_audio_sink->OnData(*bus, capture_time);
+ }
+}
+
+} // namespace blink
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 0fcc39afecb..3ed4b1a517a 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
@@ -67,12 +67,18 @@ gfx::Rect ScaleRectangle(const gfx::Rect& input_rect,
namespace blink {
+const base::Feature kWebRtcLogWebRtcVideoFrameAdapter{
+ "WebRtcLogWebRtcVideoFrameAdapter", base::FEATURE_DISABLED_BY_DEFAULT};
+
WebRtcVideoTrackSource::WebRtcVideoTrackSource(
bool is_screencast,
absl::optional<bool> needs_denoising)
: AdaptedVideoTrackSource(/*required_alignment=*/1),
is_screencast_(is_screencast),
- needs_denoising_(needs_denoising) {
+ needs_denoising_(needs_denoising),
+ log_to_webrtc_(is_screencast &&
+ base::FeatureList::IsEnabled(
+ blink::kWebRtcLogWebRtcVideoFrameAdapter)) {
DETACH_FROM_THREAD(thread_checker_);
}
@@ -325,7 +331,11 @@ void WebRtcVideoTrackSource::DeliverFrame(
webrtc::VideoFrame::Builder frame_builder =
webrtc::VideoFrame::Builder()
.set_video_frame_buffer(
- new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(frame))
+ new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(
+ frame,
+ (log_to_webrtc_
+ ? WebRtcVideoFrameAdapter::LogStatus::kLogToWebRtc
+ : WebRtcVideoFrameAdapter::LogStatus::kNoLogging)))
.set_rotation(webrtc::kVideoRotation_0)
.set_timestamp_us(timestamp_us);
if (update_rect) {
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.h b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.h
index 9a6c26f42cb..5fada0dbf5b 100644
--- a/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.h
+++ b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_WEBRTC_VIDEO_TRACK_SOURCE_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_WEBRTC_VIDEO_TRACK_SOURCE_H_
+#include "base/feature_list.h"
#include "base/memory/scoped_refptr.h"
#include "base/threading/thread_checker.h"
#include "media/base/video_frame_pool.h"
@@ -14,6 +15,8 @@
namespace blink {
+PLATFORM_EXPORT extern const base::Feature kWebRtcLogWebRtcVideoFrameAdapter;
+
// This class implements webrtc's VideoTrackSourceInterface. To pass frames down
// the webrtc video pipeline, each received a media::VideoFrame is converted to
// a webrtc::VideoFrame, taking any adaptation requested by downstream classes
@@ -80,6 +83,8 @@ class PLATFORM_EXPORT WebRtcVideoTrackSource
absl::optional<FrameAdaptationParams>
custom_frame_adaptation_params_for_testing_;
+ const bool log_to_webrtc_;
+
DISALLOW_COPY_AND_ASSIGN(WebRtcVideoTrackSource);
};
diff --git a/chromium/third_party/blink/renderer/platform/platform.gni b/chromium/third_party/blink/renderer/platform/platform.gni
index 1afa35e16a2..aa108489f23 100644
--- a/chromium/third_party/blink/renderer/platform/platform.gni
+++ b/chromium/third_party/blink/renderer/platform/platform.gni
@@ -25,9 +25,8 @@ template("blink_platform_sources") {
assert(
!defined(invoker.public_deps),
"$target_name's public_deps should be moved to //third_party/blink/renderer/platform:blink_platform_public_deps")
- deps = [
- "//third_party/blink/renderer/platform:blink_platform_public_deps",
- ]
+ deps =
+ [ "//third_party/blink/renderer/platform:blink_platform_public_deps" ]
if (defined(invoker.deps)) {
deps += invoker.deps
}
diff --git a/chromium/third_party/blink/renderer/platform/prerender.cc b/chromium/third_party/blink/renderer/platform/prerender.cc
deleted file mode 100644
index 5f2e2ce8b63..00000000000
--- a/chromium/third_party/blink/renderer/platform/prerender.cc
+++ /dev/null
@@ -1,97 +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/platform/prerender.h"
-
-#include "third_party/blink/public/platform/web_prerender.h"
-#include "third_party/blink/public/platform/web_prerendering_support.h"
-#include "third_party/blink/renderer/platform/prerender_client.h"
-
-namespace blink {
-
-Prerender::Prerender(PrerenderClient* client,
- const KURL& url,
- const unsigned rel_types,
- const Referrer& referrer,
- const SecurityOrigin* security_origin)
- : client_(client),
- url_(url),
- rel_types_(rel_types),
- referrer_(referrer),
- security_origin_(security_origin) {}
-
-Prerender::~Prerender() = default;
-
-void Prerender::Trace(blink::Visitor* visitor) {
- visitor->Trace(client_);
-}
-
-void Prerender::Dispose() {
- client_ = nullptr;
- extra_data_ = nullptr;
-}
-
-void Prerender::Add() {
- if (WebPrerenderingSupport* platform = WebPrerenderingSupport::Current())
- platform->Add(WebPrerender(this));
-}
-
-void Prerender::Cancel() {
- if (WebPrerenderingSupport* platform = WebPrerenderingSupport::Current())
- platform->Cancel(WebPrerender(this));
-}
-
-void Prerender::Abandon() {
- if (WebPrerenderingSupport* platform = WebPrerenderingSupport::Current())
- platform->Abandon(WebPrerender(this));
-}
-
-void Prerender::DidStartPrerender() {
- if (client_)
- client_->DidStartPrerender();
-}
-
-void Prerender::DidStopPrerender() {
- if (client_)
- client_->DidStopPrerender();
-}
-
-void Prerender::DidSendLoadForPrerender() {
- if (client_)
- client_->DidSendLoadForPrerender();
-}
-
-void Prerender::DidSendDOMContentLoadedForPrerender() {
- if (client_)
- client_->DidSendDOMContentLoadedForPrerender();
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/prerender.h b/chromium/third_party/blink/renderer/platform/prerender.h
deleted file mode 100644
index 06b32a45f55..00000000000
--- a/chromium/third_party/blink/renderer/platform/prerender.h
+++ /dev/null
@@ -1,108 +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.
- *
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_PRERENDER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PRERENDER_H_
-
-#include "base/macros.h"
-#include "base/memory/scoped_refptr.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/platform_export.h"
-#include "third_party/blink/renderer/platform/weborigin/kurl.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/wtf/ref_counted.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-
-class PrerenderClient;
-
-class PLATFORM_EXPORT Prerender final : public GarbageCollected<Prerender> {
- DISALLOW_COPY_AND_ASSIGN(Prerender);
-
- public:
- class ExtraData : public RefCounted<ExtraData> {
- public:
- virtual ~ExtraData() = default;
- };
-
- Prerender(PrerenderClient*,
- const KURL&,
- unsigned rel_types,
- const Referrer&,
- const SecurityOrigin* security_origin);
- ~Prerender();
- void Trace(blink::Visitor*);
-
- void Dispose();
-
- void Add();
- void Cancel();
- void Abandon();
-
- const KURL& Url() const { return url_; }
- unsigned RelTypes() const { return rel_types_; }
- const String& GetReferrer() const { return referrer_.referrer; }
- network::mojom::ReferrerPolicy GetReferrerPolicy() const {
- return referrer_.referrer_policy;
- }
- const SecurityOrigin* GetSecurityOrigin() const { return security_origin_; }
-
- void SetExtraData(scoped_refptr<ExtraData> extra_data) {
- extra_data_ = std::move(extra_data);
- }
- ExtraData* GetExtraData() { return extra_data_.get(); }
-
- void DidStartPrerender();
- void DidStopPrerender();
- void DidSendLoadForPrerender();
- void DidSendDOMContentLoadedForPrerender();
-
- private:
- // The embedder's prerendering support holds on to pending Prerender objects;
- // those references should not keep the PrerenderClient alive -- if the client
- // becomes otherwise unreachable it should be GCed (at which point it will
- // abandon this Prerender object.)
- WeakMember<PrerenderClient> client_;
-
- const KURL url_;
- const unsigned rel_types_;
- const Referrer referrer_;
- const SecurityOrigin* const security_origin_;
-
- scoped_refptr<ExtraData> extra_data_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PRERENDER_H_
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 fb78dd6dfb9..502ead1d51b 100644
--- a/chromium/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/chromium/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -94,11 +94,6 @@
valid_type: "bool",
},
- // Set to true to have customised {feature}Enabled() method implementation.
- custom: {
- valid_type: "bool",
- },
-
// Feature policy IDL extended attribute (see crrev.com/2247923004).
feature_policy: {
},
@@ -116,14 +111,17 @@
},
{
name: "AccessibilityExposeARIAAnnotations",
- origin_trial_feature_name: "AccessibilityExposeARIAAnnotations",
- status: "experimental",
+ status: "stable",
},
{
name: "AccessibilityExposeDisplayNone",
status: "test",
},
{
+ name: "AccessibilityExposeHTMLElement",
+ status: "experimental",
+ },
+ {
name: "AccessibilityObjectModel",
status: "experimental",
},
@@ -147,22 +145,25 @@
{
name: "AllowSyncXHRInPageDismissal",
origin_trial_feature_name: "AllowSyncXHRInPageDismissal",
- status: "experimental",
},
{
name: "AnimationWorklet",
- origin_trial_feature_name: "AnimationWorklet",
status: "experimental",
},
{
name: "AOMAriaProperties",
- status: "experimental",
+ status: "stable",
},
{
name: "AOMAriaRelationshipProperties",
status: "experimental",
},
{
+ // Enabled when blink::features::kAppCache is enabled.
+ name: "AppCache",
+ status: "stable",
+ },
+ {
// Use an aspect ratio from the HTML attributes even when we use sizing
// from CSS.
// https://github.com/WICG/intrinsicsize-attribute/issues/16
@@ -170,10 +171,6 @@
status: "stable",
},
{
- name: "AsyncClipboard",
- status: "stable",
- },
- {
name: "AudioOutputDevices",
// Android does not yet support switching of audio output devices
status: {"Android": "", "default": "stable"},
@@ -228,56 +225,41 @@
},
{
name: "Badging",
- origin_trial_feature_name: "BadgingV2",
- status: "experimental",
+ status: "stable",
},
{
- name: "BidiCaretAffinity",
+ name: "BarcodeDetector",
+ status: "stable",
},
{
- name: "BlinkRuntimeCallStats",
+ name: "BidiCaretAffinity",
},
{
- // Adding simpler reading methods - stream(), text(), and arrayBuffer() -
- // to the Blob interface. See: https://github.com/w3c/FileAPI/pull/117
- name: "BlobReadMethods",
- status: "stable"
+ name: "BlinkRuntimeCallStats",
},
{
name: "BlockCredentialedSubresources",
status: "stable",
},
{
+ name: "BlockFlowHandlesWebkitLineClamp",
+ },
+ {
name: "BlockHTMLParserOnStyleSheets",
},
{
name: "BlockingDownloadsInSandbox",
- status: "test",
+ status: "stable",
},
{
name: "BlockingFocusWithoutUserActivation",
status: "experimental",
},
{
- name: "BuiltInModuleAll",
- implied_by: ["ExperimentalProductivityFeatures"],
- },
- {
- name: "BuiltInModuleInfra",
- origin_trial_feature_name: "BuiltInModuleInfra",
- implied_by: ["ExperimentalProductivityFeatures",
- "BuiltInModuleAll",
- "BuiltInModuleKvStorage",
- "BuiltInModuleSwitchElement"],
- },
- {
- name: "BuiltInModuleKvStorage",
- origin_trial_feature_name: "BuiltInModuleKvStorage",
- implied_by: ["ExperimentalProductivityFeatures"],
+ name: "BrowserVerifiedUserActivationKeyboard",
},
{
- name: "BuiltInModuleSwitchElement",
- implied_by: ["BuiltInModuleAll"],
+ name: "BrowserVerifiedUserActivationMouse",
},
{
name: "CacheInlineScriptCode"
@@ -311,6 +293,10 @@
status: "experimental",
},
{
+ name: "CaptureTimeInCsrc",
+ status: "stable",
+ },
+ {
name: "ClickPointerEvent",
status: "experimental",
},
@@ -324,6 +310,8 @@
// 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",
@@ -364,12 +352,19 @@
status: "experimental",
},
{
+ name: "ConversionMeasurement",
+ status: "test",
+ },
+ {
name: "CookieDeprecationMessages",
status: "experimental",
},
{
- name: "CookieStore",
- origin_trial_feature_name: "CookieStore",
+ name: "CookieStoreDocument",
+ status: "experimental",
+ },
+ {
+ name: "CookieStoreWorker",
status: "experimental",
},
{
@@ -381,7 +376,6 @@
},
{
name: "CorsRFC1918",
- depends_on: ["AddressSpace"],
},
{
name: "CSS3Text",
@@ -392,9 +386,8 @@
status: "stable",
},
{
- name: "CSSAdditiveAnimations",
- depends_on: ["StackedCSSPropertyAnimations"],
- status: "experimental",
+ name: "CSSAspectRatioProperty",
+ status: "test",
},
{
name: "CSSCalcAsInt",
@@ -402,17 +395,21 @@
},
{
name: "CSSCascade",
+ status: "stable",
},
- // Support for the CSS color-scheme property from the css-color-adjust spec.
- // https://drafts.csswg.org/css-color-adjust/#color-scheme-prop
{
+ // Support for the CSS color-scheme property from the css-color-adjust spec.
+ // https://drafts.csswg.org/css-color-adjust/#color-scheme-prop
name: "CSSColorScheme",
+ status: "stable",
},
{
- // CSS min(), max() and clamp()
- // https://drafts.csswg.org/css-values-4/#comp-func
- name: "CSSComparisonFunctions",
- status: "stable",
+ // When the color-scheme is supported via the CSS color-scheme property
+ // (CSSColorScheme) or the meta tag (MetaColorScheme), the only UA
+ // rendering change is for the canvas background and the :root element
+ // color property. Enabling this runtime flag will enable dark UA
+ // rendering for form controls, scrollbars, etc.
+ name: "CSSColorSchemeUARendering",
},
{
name: "CSSFocusVisible",
@@ -434,11 +431,11 @@
status: "experimental",
},
{
- // Support for CSS intrinsic-* sizing properties.
- // https://drafts.csswg.org/css-sizing-4/#intrinsic-size-override
+ // Support for CSS contain-intrinsic-size property.
+ // https://wicg.github.io/display-locking/contain-intrinsic-size.html
name: "CSSIntrinsicSize",
- implied_by: ["DisplayLocking"],
- status: "experimental",
+ implied_by: ["CSSSubtreeVisibility"],
+ status: "stable",
},
{
name: "CSSLayoutAPI",
@@ -462,6 +459,15 @@
status: "experimental",
},
{
+ name: "CSSMathStyle",
+ status: "experimental",
+ implied_by: ["MathMLCore"],
+ },
+ {
+ name: "CSSModules",
+ status: "experimental",
+ },
+ {
name: "CSSOffsetPathRay",
status: "experimental",
},
@@ -496,7 +502,9 @@
status: "experimental",
},
{
- name: "CSSRenderSubtree",
+ // Perform partial style and layout invalidation on web font loading.
+ // See https://crbug.com/441925 and https://bit.ly/35JjPmq for details.
+ name: "CSSReducedFontLoadingInvalidations",
status: "test",
},
{
@@ -504,6 +512,32 @@
status: "experimental",
},
{
+ // The main subtree-visibility feature.
+ // https://wicg.github.io/display-locking/
+ name: "CSSSubtreeVisibility",
+ status: "experimental",
+ implied_by: ["CSSSubtreeVisibilityHiddenMatchable"]
+ },
+ {
+ // The subtree-visibility activation event which will be replaced by
+ // the beforematch event. When beforematch is available, this feaure
+ // will be removed.
+ name: "CSSSubtreeVisibilityActivationEvent",
+ implied_by: ["CSSSubtreeVisibility"]
+ },
+ {
+ // The subtree-visibility: hidden-matchable feature. This is a planned
+ // follow-up to the main CSSSubtreeVisibility feature, thus it is gated
+ // by a different flag.
+ // https://wicg.github.io/display-locking/
+ name: "CSSSubtreeVisibilityHiddenMatchable",
+ status: "experimental"
+ },
+ {
+ name: "CSSSupportsSelector",
+ status: "stable",
+ },
+ {
name: "CSSVariables2",
status: "stable",
},
@@ -551,7 +585,12 @@
status: "stable",
},
{
+ name: "DeclarativeShadowDOM",
+ status: "experimental",
+ },
+ {
name: "DecodeJpeg420ImagesToYUV",
+ status: "test",
},
{
name: "DecodeLossyWebPImagesToYUV",
@@ -571,19 +610,10 @@
status: "experimental",
},
{
- name: "DiscardInputToMovingIframes",
- status: "stable",
- },
- {
name: "DisplayCutoutAPI",
settable_from_internals: true,
},
{
- name: "DisplayLocking",
- origin_trial_feature_name: "DisplayLocking",
- status: "experimental",
- },
- {
name: "DocumentCookie",
},
{
@@ -591,6 +621,8 @@
},
{
name: "DocumentPolicy",
+ origin_trial_feature_name: "DocumentPolicy",
+ status: "experimental",
},
{
name: "DocumentWrite",
@@ -605,12 +637,8 @@
name: "EditingNG",
},
{
- name: "EmbeddedVTTStylesheets",
- status: "experimental",
- },
- {
name: "EncryptedMediaEncryptionSchemeQuery",
- status: "test",
+ status: "stable",
},
{
name: "EncryptedMediaHdcpPolicyCheck",
@@ -679,11 +707,11 @@
name: "ExtraWebGLVideoTextureMetadata",
},
{
- name: "FallbackCursorMode",
+ name: "FaceDetector",
+ status: "experimental",
},
{
- name: "FastBorderRadius",
- status: "experimental",
+ name: "FallbackCursorMode",
},
{
name: "FeaturePolicyForClientHints",
@@ -707,18 +735,13 @@
name: "FeaturePolicyVibrateFeature"
},
{
- name: "FetchMetadata",
- status: "stable"
- },
- {
- name: "FetchMetadataDestination",
- status: "experimental"
- },
- {
+ // Also enabled when blink::features::kFileHandlingAPI is overridden
+ // on the command line (or via chrome://flags).
name: "FileHandling",
- // 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"]
+ depends_on: ["NativeFileSystem"],
+ status: {"Android": "test", "default": "experimental"},
+ origin_trial_feature_name: "FileHandling",
+ origin_trial_os: ["win", "macosx", "linux", "chromeos"],
},
{
name: "FileSystem",
@@ -735,6 +758,10 @@
settable_from_internals: true,
},
{
+ name: "FontAccess",
+ status: "experimental",
+ },
+ {
name: "FontSrcLocalMatching",
// No status, as the web platform runtime enabled feature is controlled by
// a Chromium level feature.
@@ -748,22 +775,23 @@
name: "ForceDeferScriptIntervention",
},
{
- name: "ForceOverlayFullscreenVideo",
+ // This is used in tests to perform memory measurement without
+ // waiting for GC.
+ name:"ForceEagerMeasureMemory",
},
{
- name: "ForceSynchronousHTMLParsing",
+ name: "ForceLoadAtTop",
+ origin_trial_feature_name: "ForceLoadAtTop",
},
{
- name: "ForceTallerSelectPopup",
- status: {"ChromeOS": "stable"},
+ name: "ForceOverlayFullscreenVideo",
},
- // This is to communicate features::FormControlsRefresh from ui (and can be
- // removed when the feature launches).
{
- name: "FormControlsRefresh",
+ name: "ForceSynchronousHTMLParsing",
},
{
- name: "FractionalMouseEvent",
+ name: "ForceTallerSelectPopup",
+ status: {"ChromeOS": "stable"},
},
{
name: "FractionalScrollOffsets",
@@ -779,7 +807,7 @@
},
{
name: "GetDisplayMedia",
- status: "stable",
+ status: {"Android": "", "default": "stable"},
},
{
name: "GroupEffect",
@@ -789,7 +817,7 @@
name: "HrefTranslate",
depends_on: ["TranslateService"],
origin_trial_feature_name: "HrefTranslate",
- status: "experimental",
+ status: "stable",
},
// TODO(937746): Web Components v0 is disabled by default, and will be
// removed after M87.
@@ -806,7 +834,7 @@
},
{
name: "IDBRelaxedDurability",
- status: "experimental",
+ status: "stable",
},
{
name: "IdleDetection",
@@ -818,7 +846,7 @@
},
{
name: "ImageOrientation",
- status: "test",
+ status: "stable",
},
{
name: "ImplicitRootScroller",
@@ -827,13 +855,17 @@
},
{
name: "ImportMaps",
- implied_by: ["ExperimentalProductivityFeatures", "BuiltInModuleInfra"],
+ implied_by: ["ExperimentalProductivityFeatures"],
},
{
name: "InertAttribute",
status: "experimental",
},
{
+ name: "InputElementRawValue",
+ status: "experimental",
+ },
+ {
name: "InputMultipleFieldsUI",
// No plan to support complex UI for date/time INPUT types on Android.
status: {"Android": "test", "default": "stable"},
@@ -844,7 +876,7 @@
},
{
name: "IntersectionObserverDocumentScrollingElementRoot",
- status: "experimental",
+ status: "stable",
},
{
name: "IntersectionObserverV2",
@@ -866,9 +898,6 @@
name: "IsolatedWorldCSP"
},
{
- name: "JSONModules",
- },
- {
name: "KeyboardFocusableScrollers",
status: "experimental",
},
@@ -880,8 +909,14 @@
status: "experimental",
},
{
+ // LayoutNG has been enabled in M76, but we still keep this flag for
+ // testing. See web_tests/FlagExpectations/disable-layout-ng for more
+ // details about running web tests with LayoutNG disabled. This flag also
+ // provides a convenient way for testing legacy layout code path in blink
+ // unit tests.
name: "LayoutNG",
- implied_by: ["LayoutNGBlockFragmentation", "LayoutNGFieldset", "LayoutNGFlexBox", "LayoutNGFragmentItem", "LayoutNGLineCache", "EditingNG", "BidiCaretAffinity", "LayoutNGTable"],
+ // Keep this list in sync with the one in LayoutNGFlexBox below.
+ implied_by: ["LayoutNGBlockFragmentation", "LayoutNGFieldset", "LayoutNGFragmentItem", "LayoutNGLineCache", "EditingNG", "BidiCaretAffinity", "LayoutNGTable", "LayoutNGFragmentTraversal"],
status: "stable",
},
{
@@ -892,17 +927,22 @@
},
{
name: "LayoutNGFlexBox",
+ implied_by: ["LayoutNGBlockFragmentation", "LayoutNGFieldset", "LayoutNGFragmentItem", "LayoutNGLineCache", "EditingNG", "BidiCaretAffinity", "LayoutNGTable", "LayoutNGFragmentTraversal"],
+ status: "experimental",
},
{
- name: "LayoutNGFragmentCaching",
- implied_by: ["LayoutNG"],
+ name: "LayoutNGForControls",
+ depends_on: ["LayoutNG"],
+ status: "experimental",
},
{
name: "LayoutNGFragmentItem",
+ implied_by: ["LayoutNGBlockFragmentation", "LayoutNGFragmentTraversal"],
},
{
- name: "LayoutNGFragmentPaint",
- implied_by: ["LayoutNG"],
+ // Traverse the fragment tree when painting and hit-testing, instead of
+ // the layout object tree.
+ name: "LayoutNGFragmentTraversal",
},
{
name: "LayoutNGLineCache",
@@ -937,20 +977,17 @@
// Enabled by features::kLegacyWindowsDWriteFontFallback;
},
{
- name: "LinkSystemColors",
- status: "stable",
- },
- {
name:"ManualSlotting",
status:"experimental",
},
{
name: "MathMLCore",
- status:"test",
+ status:"experimental",
depends_on: ["LayoutNG"],
},
{
name:"MeasureMemory",
+ origin_trial_feature_name: "MeasureMemory",
status:"experimental",
},
{
@@ -1007,10 +1044,6 @@
name: "MediaQueryNavigationControls",
},
{
- name: "MediaQueryPrefersColorScheme",
- status: "stable",
- },
- {
name: "MediaQueryShape",
status: "experimental",
},
@@ -1020,7 +1053,7 @@
},
{
name: "MediaSessionPosition",
- status: "experimental",
+ status: "stable",
},
{
name: "MediaSessionSeeking",
@@ -1051,6 +1084,7 @@
// https://drafts.csswg.org/css-color-adjust/#color-scheme-meta
{
name: "MetaColorScheme",
+ status: "stable",
},
// This is enabled by default on Windows only. The only part that's
// "experimental" is the support on other platforms.
@@ -1063,14 +1097,14 @@
name: "MobileLayoutTheme",
},
{
- name: "ModuleDedicatedWorker",
- status: "stable",
- },
- {
name: "ModuleServiceWorker",
status: "test",
},
{
+ name: "ModuleSharedWorker",
+ status: "stable",
+ },
+ {
name: "MojoJS",
status: "test",
},
@@ -1085,14 +1119,23 @@
name: "MouseSubframeNoImplicitCapture",
},
{
+ // Named pages for pagination (the "page" CSS property).
+ name: "NamedPages",
+ status: "experimental",
+ },
+ {
// Also enabled when blink::features::kNativeFileSystemAPI is overridden
// on the command line (or via chrome://flags).
name: "NativeFileSystem",
status: {"Android": "test", "default": "experimental"},
- origin_trial_feature_name: "NativeFileSystem",
+ origin_trial_feature_name: "NativeFileSystem2",
origin_trial_os: ["win", "macosx", "linux", "chromeos"],
},
{
+ name: "NativeIO",
+ status: "experimental",
+ },
+ {
name: "NavigatorContentUtils",
// Android does not yet support NavigatorContentUtils.
status: {"Android": "", "default": "stable"},
@@ -1118,10 +1161,6 @@
name: "NewRemotePlaybackPipeline",
},
{
- name: "NewSystemColors",
- status: "stable",
- },
- {
name: "NoIdleEncodingForWebTests",
status: "test",
},
@@ -1148,6 +1187,7 @@
},
{
name: "OffMainThreadCSSPaint",
+ status: "stable",
},
{
name: "OffscreenCanvasCommit",
@@ -1162,6 +1202,10 @@
name: "OrientationEvent",
status: {"Android": "stable"},
},
+ {
+ name: "OriginPolicy",
+ status: "experimental",
+ },
// Define a sample API for testing integration with the Origin Trials
// Framework. The sample API is used in both unit and web tests for the
@@ -1251,7 +1295,6 @@
// This is to add an option to enable the Reveal button on password inputs while waiting ::reveal gets standardized.
{
name: "PasswordReveal",
- depends_on: ["FormControlsRefresh"],
},
{
name: "PaymentApp",
@@ -1266,6 +1309,10 @@
status: "stable",
},
{
+ name: "PaymentHandlerMinimalUI",
+ status: "experimental",
+ },
+ {
name: "PaymentMethodChangeEvent",
status: "stable",
},
@@ -1283,14 +1330,11 @@
status: "stable",
},
{
- name: "PerformanceManagerInstrumentation",
+ name: "PercentBasedScrolling",
+ settable_from_internals: true,
},
{
- // Flag enabling the performance observers buffered flag. The buffered
- // flag indicates whether or not the buffered entries should be loaded
- // into the observer's buffer upon registration. See crbug.com/725567.
- name: "PerformanceObserverBufferedFlag",
- status: "stable",
+ name: "PerformanceManagerInstrumentation",
},
{
name: "PeriodicBackgroundSync",
@@ -1344,6 +1388,7 @@
{
name: "Portals",
status: "test",
+ origin_trial_feature_name: "Portals",
},
{
name: "PostAnimationFrame",
@@ -1367,9 +1412,6 @@
status: "stable",
},
{
- name: "PrintBrowser",
- },
- {
name: "PriorityHints",
origin_trial_feature_name: "PriorityHints",
status: "experimental",
@@ -1387,7 +1429,12 @@
status: "experimental",
},
{
+ // Enabled when blink::features::kRawClipboard is enabled.
+ name: "RawClipboard",
+ },
+ {
name: "ReducedReferrerGranularity",
+ status: "experimental",
},
{
name: "RemotePlayback",
@@ -1400,6 +1447,15 @@
status: {"Android": "stable", "default": ""},
},
{
+ // See https://crbug.com/1012063
+ name: "RequestVideoFrameCallback",
+ status: "stable",
+ },
+ {
+ name: "ResizeObserverUpdates",
+ status: "test",
+ },
+ {
name: "RestrictAppCacheToSecureContexts",
status: "stable",
},
@@ -1414,10 +1470,6 @@
status: "stable",
},
{
- name: "RestrictedWebkitAppearance",
- status: "stable",
- },
- {
name: "RtcAudioJitterBufferMaxPackets",
origin_trial_feature_name: "RtcAudioJitterBufferMaxPackets",
status: "experimental",
@@ -1427,28 +1479,24 @@
origin_trial_feature_name: "RtcAudioJitterBufferRtxHandling",
status: "experimental",
},
- // Enables the use of the RTCDtlsTransport object.
- {
- name: "RTCDtlsTransport",
- status: "stable",
- },
// Enables the use of the RTCIceTransport with extensions.
{
name: "RTCIceTransportExtension",
origin_trial_feature_name: "RTCQuicTransport",
status: "experimental",
},
+ // Enables the use of Insertable Streams.
+ {
+ name: "RTCInsertableStreams",
+ origin_trial_feature_name: "RTCInsertableStreams",
+ status: "experimental",
+ },
// Enables the use of the RTCQuicTransport object.
{
name: "RTCQuicTransport",
origin_trial_feature_name: "RTCQuicTransport",
status: "experimental",
},
- // Enables the use of the RTCSctpTransport object.
- {
- name: "RTCSctpTransport",
- status: "stable",
- },
{
name: "RTCStatsRelativePacketArrivalDelay",
origin_trial_feature_name: "RTCStatsRelativePacketArrivalDelay",
@@ -1481,6 +1529,11 @@
name: "ScreenEnumeration",
status: "experimental",
},
+ {
+ name: "ScreenWakeLock",
+ origin_trial_feature_name: "WakeLock",
+ status: "experimental",
+ },
// WebSpeech API with both speech recognition and synthesis functionality
// is not fully enabled on all platforms.
{
@@ -1499,12 +1552,11 @@
},
{
name: "ScrollSnapAfterLayout",
- status: "experimental",
+ status: "stable",
},
{
name: "ScrollTimeline",
status: "experimental",
- origin_trial_feature_name: "AnimationWorklet",
implied_by: ['AnimationWorklet']
},
// Implements documentElement.scrollTop/Left and bodyElement.scrollTop/Left
@@ -1556,10 +1608,6 @@
status: "experimental",
},
{
- name: "ShapeDetection",
- status: "experimental",
- },
- {
name: "SharedArrayBuffer",
status: "stable",
},
@@ -1594,9 +1642,10 @@
},
{
name: "SmsReceiver",
- origin_trial_feature_name: "SmsReceiver",
- origin_trial_os: ["android"],
- status: {"default": "experimental"},
+ status: {"default": "experimental", "Android": "experimental"},
+ },
+ {
+ name: "SquashAfterPaint",
},
// Used as argument in attribute of stable-release functions/interfaces
// where a runtime-enabled feature name is required for correct IDL syntax.
@@ -1606,19 +1655,11 @@
status: "stable",
},
{
- name: "StackedCSSPropertyAnimations",
- status: "experimental",
- },
- {
// Enabled when blink::features::kStorageAccessAPI is enabled.
name: "StorageAccessAPI",
status: "test",
},
{
- name: "StorageQuotaDetails",
- status: "stable"
- },
- {
name: "StrictMimeTypesForWorkers",
status: "experimental"
},
@@ -1627,9 +1668,31 @@
status: "stable",
},
{
+ name: "SystemWakeLock",
+ status: "experimental",
+ },
+ // For unit tests.
+ {
+ name: "TestFeature",
+ },
+ // For unit tests.
+ {
+ name: "TestFeatureDependent",
+ depends_on: ["TestFeatureImplied"],
+ },
+ // For unit tests.
+ {
+ name: "TestFeatureImplied",
+ implied_by: ["TestFeature"],
+ },
+ {
+ name: "TextDetector",
+ status: "experimental",
+ },
+ {
name: "TextFragmentIdentifiers",
origin_trial_feature_name: "TextFragmentIdentifiers",
- status: "experimental",
+ status: "stable",
},
{
name: "TimerThrottlingForBackgroundTabs",
@@ -1639,6 +1702,10 @@
name: "TimerThrottlingForHiddenFrames",
status: "stable",
},
+ {
+ name: "TimeZoneChangeEvent",
+ status: "experimental",
+ },
// Many websites disable mouse support when touch APIs are available. We'd
// like to enable this always but can't until more websites fix this bug.
// Chromium sets this conditionally (eg. based on the presence of a
@@ -1657,6 +1724,8 @@
{
name: "TransferableStreams",
status: "experimental",
+ origin_trial_feature_name: "RTCInsertableStreams",
+ implied_by: ["RTCInsertableStreams"],
},
// This is conditionally set if the platform supports translation.
{
@@ -1664,13 +1733,21 @@
},
{
name: "TrustedDOMTypes",
- status: "experimental",
+ status: "stable",
+ },
+ {
+ name: "TrustTokens",
+ status: "test",
},
{
name: "UnclosedFormControlIsInvalid",
status: "experimental",
},
{
+ name: "UnderlineOffsetThickness",
+ status: "test",
+ },
+ {
name: "UnifiedPointerCaptureInBlink",
status: "stable",
},
@@ -1691,10 +1768,6 @@
implied_by: ["ExperimentalProductivityFeatures"]
},
{
- name: "UpdateHoverAtBeginFrame",
- settable_from_internals: true,
- },
- {
name: "UserActivationAPI",
status: "stable",
},
@@ -1722,9 +1795,6 @@
settable_from_internals: true,
},
{
- name: "VideoFullscreenDetection",
- },
- {
name: "VideoFullscreenOrientationLock",
},
{
@@ -1732,11 +1802,6 @@
status: "stable",
},
{
- // See https://crbug.com/1012063
- name: "VideoRequestAnimationFrame",
- status: "experimental",
- },
- {
name: "VideoRotateToFullscreen",
},
{
@@ -1745,11 +1810,7 @@
{
name: "WakeLock",
origin_trial_feature_name: "WakeLock",
- status: "experimental",
- },
- {
- name: "WasmCodeCache",
- status: "experimental",
+ implied_by: ['ScreenWakeLock', 'SystemWakeLock'],
},
{
name: "WebAnimationsAPI",
@@ -1787,10 +1848,22 @@
},
},
{
+ name: "WebBluetoothGetDevices",
+ status: "experimental",
+ },
+ {
name: "WebBluetoothScanning",
status: "experimental",
},
{
+ name: "WebCodecs",
+ status: "test",
+ },
+ {
+ name: "WebCryptoCurve25519",
+ status: "experimental",
+ },
+ {
name: "WebGL2ComputeContext",
status: "experimental",
},
@@ -1814,15 +1887,14 @@
status: "experimental",
},
{
- name: "WebkitBoxLayoutUsesFlexLayout",
- status: "stable",
- },
- {
name: "WebNFC",
+ origin_trial_feature_name: "WebNFC",
+ origin_trial_os: ["android"],
status: "experimental",
},
{
name: "WebScheduler",
+ origin_trial_feature_name: "WebScheduler",
status: "experimental",
},
// WebShare is enabled by default on Android.
@@ -1858,32 +1930,24 @@
status: "stable",
},
{
- name: "WebXRAnchors",
- // depends_on: ["WebXRARModule"], // TODO(https://crbug.com/954679): uncomment once bug is fixed
- },
- {
- name: "WebXRARDOMOverlay",
- // depends_on: ["WebXRARModule"], // TODO(https://crbug.com/954679): uncomment once bug is fixed
- status: "experimental",
- },
- {
name: "WebXRARModule",
depends_on: ["WebXR"],
- status: "experimental",
+ status: "stable",
},
{
- name: "WebXrGamepadModule",
- // depends_on: ["WebXR"], // TODO(https://crbug.com/954679): uncomment once bug is fixed
+ name: "WebXRHitTest",
+ depends_on: ["WebXRARModule"],
status: "stable",
},
{
- name: "WebXRHitTest",
- // depends_on: ["WebXRARModule"], // TODO(https://crbug.com/954679): uncomment once bug is fixed
+ name: "WebXRHitTestEntityTypes",
+ depends_on: ["WebXRHitTest"],
status: "experimental"
},
{
- name: "WebXRPlaneDetection",
- // depends_on: ["WebXRARModule"], // TODO(https://crbug.com/954679): uncomment once bug is fixed
+ name: "WebXRIncubations",
+ depends_on: ["WebXRARModule"],
+ status: "experimental",
},
// Extends window placement functionality for multi-screen devices.
{
@@ -1891,6 +1955,15 @@
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: "XSLT",
status: "stable",
},
diff --git a/chromium/third_party/blink/renderer/platform/runtime_enabled_features_test.cc b/chromium/third_party/blink/renderer/platform/runtime_enabled_features_test.cc
new file mode 100644
index 00000000000..099680c6127
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/runtime_enabled_features_test.cc
@@ -0,0 +1,275 @@
+// 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/runtime_enabled_features.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
+
+namespace blink {
+namespace {
+
+class RuntimeEnabledFeaturesTest : public testing::Test {
+ void CheckAllDisabled() {
+ CHECK(!RuntimeEnabledFeatures::TestFeatureEnabled());
+ CHECK(!RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ CHECK(!RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+ CHECK(!RuntimeEnabledFeatures::OriginTrialsSampleAPIEnabledByRuntimeFlag());
+ CHECK(!RuntimeEnabledFeatures::
+ OriginTrialsSampleAPIImpliedEnabledByRuntimeFlag());
+ CHECK(!RuntimeEnabledFeatures::
+ OriginTrialsSampleAPIDependentEnabledByRuntimeFlag());
+ }
+ void SetUp() override { CheckAllDisabled(); }
+ void TearDown() override {
+ backup_.Restore();
+ CheckAllDisabled();
+ }
+ RuntimeEnabledFeatures::Backup backup_;
+};
+
+// Test setup:
+// TestFeatureDependent
+// depends_on
+// TestFeatureImplied
+// implied_by
+// TestFeature
+
+TEST_F(RuntimeEnabledFeaturesTest, Relationship) {
+ // Internal status: false, false, false.
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+
+ RuntimeEnabledFeatures::SetTestFeatureEnabled(true);
+ // Internal status: true, false, false.
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ // Implied by TestFeature.
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+
+ RuntimeEnabledFeatures::SetTestFeatureImpliedEnabled(true);
+ // Internal status: true, true, false.
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+
+ RuntimeEnabledFeatures::SetTestFeatureDependentEnabled(true);
+ // Internal status: true, true, true.
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+
+ RuntimeEnabledFeatures::SetTestFeatureImpliedEnabled(false);
+ // Internal status: true, false, true.
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ // Implied by TestFeature.
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+
+ RuntimeEnabledFeatures::SetTestFeatureEnabled(false);
+ // Internal status: false, false, true.
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ // Depends on TestFeatureImplied.
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+
+ RuntimeEnabledFeatures::SetTestFeatureImpliedEnabled(true);
+ // Internal status: false, true, true.
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+
+ RuntimeEnabledFeatures::SetTestFeatureDependentEnabled(false);
+ // Internal status: false, true, false.
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+}
+
+TEST_F(RuntimeEnabledFeaturesTest, ScopedForTest) {
+ // Internal status: false, false, false.
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+ {
+ ScopedTestFeatureForTest f1(true);
+ // Internal status: true, false, false.
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ // Implied by TestFeature.
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+ {
+ ScopedTestFeatureImpliedForTest f2(true);
+ // Internal status: true, true, false.
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+ {
+ ScopedTestFeatureDependentForTest f3(true);
+ // Internal status: true, true, true.
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+ {
+ ScopedTestFeatureDependentForTest f3a(false);
+ // Internal status: true, true, true.
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+ }
+ // Internal status: true, true, true.
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+ }
+ }
+ // Internal status: true, false, false.
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ // Implied by TestFeature.
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+ {
+ ScopedTestFeatureImpliedForTest f2a(false);
+ // Internal status: true, false, false.
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ // Implied by TestFeature.
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+ }
+ }
+ // Internal status: false, false, false.
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+
+ {
+ ScopedTestFeatureDependentForTest f3(true);
+ // Internal status: false, false, true.
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ // Depends on TestFeatureImplied.
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+ {
+ ScopedTestFeatureImpliedForTest f2(true);
+ // Internal status: false, true, true.
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+ {
+ ScopedTestFeatureForTest f1(true);
+ // Internal status: true, true, true.
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+ }
+ // Internal status: false, true, true.
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+ }
+ // Internal status: false, false, true.
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ // Depends on TestFeatureImplied.
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+ {
+ ScopedTestFeatureImpliedForTest f2(true);
+ // Internal status: false, true, true.
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+ }
+ }
+ // Internal status: false, false, false.
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+}
+
+TEST_F(RuntimeEnabledFeaturesTest, BackupRestore) {
+ // Internal status: false, false, false.
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+
+ RuntimeEnabledFeatures::SetTestFeatureEnabled(true);
+ RuntimeEnabledFeatures::SetTestFeatureDependentEnabled(true);
+ // Internal status: true, false, true.
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ // Implied by TestFeature.
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+
+ RuntimeEnabledFeatures::Backup backup;
+
+ RuntimeEnabledFeatures::SetTestFeatureEnabled(false);
+ RuntimeEnabledFeatures::SetTestFeatureImpliedEnabled(true);
+ RuntimeEnabledFeatures::SetTestFeatureDependentEnabled(false);
+ // Internal status: false, true, false.
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+
+ backup.Restore();
+ // Should restore the internal status to: true, false, true.
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ // Implied by TestFeature.
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ EXPECT_TRUE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+
+ RuntimeEnabledFeatures::SetTestFeatureEnabled(false);
+ // Internal status: false, false, true.
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureEnabled());
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureImpliedEnabled());
+ // Depends on TestFeatureImplied.
+ EXPECT_FALSE(RuntimeEnabledFeatures::TestFeatureDependentEnabled());
+}
+
+// Test setup:
+// OriginTrialsSampleAPIImplied impled_by \
+// OriginTrialsSampleAPI
+// OriginTrialsSampleAPIDependent depends_on /
+TEST_F(RuntimeEnabledFeaturesTest, OriginTrialsByRuntimeEnabled) {
+ // Internal status: false, false, false.
+ EXPECT_FALSE(
+ RuntimeEnabledFeatures::OriginTrialsSampleAPIEnabledByRuntimeFlag());
+ EXPECT_FALSE(RuntimeEnabledFeatures::
+ OriginTrialsSampleAPIImpliedEnabledByRuntimeFlag());
+ EXPECT_FALSE(RuntimeEnabledFeatures::
+ OriginTrialsSampleAPIDependentEnabledByRuntimeFlag());
+
+ RuntimeEnabledFeatures::SetOriginTrialsSampleAPIEnabled(true);
+ // Internal status: true, false, false.
+ EXPECT_TRUE(
+ RuntimeEnabledFeatures::OriginTrialsSampleAPIEnabledByRuntimeFlag());
+ // Implied by OriginTrialsSampleAPI.
+ EXPECT_TRUE(RuntimeEnabledFeatures::
+ OriginTrialsSampleAPIImpliedEnabledByRuntimeFlag());
+ EXPECT_FALSE(RuntimeEnabledFeatures::
+ OriginTrialsSampleAPIDependentEnabledByRuntimeFlag());
+
+ RuntimeEnabledFeatures::SetOriginTrialsSampleAPIImpliedEnabled(true);
+ RuntimeEnabledFeatures::SetOriginTrialsSampleAPIDependentEnabled(true);
+ // Internal status: true, true, true.
+ EXPECT_TRUE(
+ RuntimeEnabledFeatures::OriginTrialsSampleAPIEnabledByRuntimeFlag());
+ EXPECT_TRUE(RuntimeEnabledFeatures::
+ OriginTrialsSampleAPIImpliedEnabledByRuntimeFlag());
+ EXPECT_TRUE(RuntimeEnabledFeatures::
+ OriginTrialsSampleAPIDependentEnabledByRuntimeFlag());
+
+ RuntimeEnabledFeatures::SetOriginTrialsSampleAPIEnabled(false);
+ // Internal status: false, true, true.
+ EXPECT_FALSE(
+ RuntimeEnabledFeatures::OriginTrialsSampleAPIEnabledByRuntimeFlag());
+ EXPECT_TRUE(RuntimeEnabledFeatures::
+ OriginTrialsSampleAPIImpliedEnabledByRuntimeFlag());
+ // Depends on OriginTrialsSampleAPI.
+ EXPECT_FALSE(RuntimeEnabledFeatures::
+ OriginTrialsSampleAPIDependentEnabledByRuntimeFlag());
+}
+
+} // namespace
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn b/chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn
index 751e13bde93..0d5114005ab 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn
@@ -14,7 +14,6 @@ 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",
@@ -69,6 +68,8 @@ blink_platform_sources("scheduler") {
"main_thread/compositor_priority_experiments.h",
"main_thread/deadline_task_runner.cc",
"main_thread/deadline_task_runner.h",
+ "main_thread/find_in_page_budget_pool_controller.cc",
+ "main_thread/find_in_page_budget_pool_controller.h",
"main_thread/frame_origin_type.cc",
"main_thread/frame_origin_type.h",
"main_thread/frame_scheduler_impl.cc",
@@ -90,6 +91,8 @@ blink_platform_sources("scheduler") {
"main_thread/main_thread_task_queue.h",
"main_thread/memory_purge_manager.cc",
"main_thread/memory_purge_manager.h",
+ "main_thread/non_waking_time_domain.cc",
+ "main_thread/non_waking_time_domain.h",
"main_thread/page_scheduler_impl.cc",
"main_thread/page_scheduler_impl.h",
"main_thread/page_visibility_state.cc",
@@ -114,6 +117,8 @@ blink_platform_sources("scheduler") {
"main_thread/web_scheduling_task_queue_impl.cc",
"main_thread/web_scheduling_task_queue_impl.h",
"main_thread/web_scoped_virtual_time_pauser.cc",
+ "main_thread/widget_scheduler.cc",
+ "main_thread/widget_scheduler.h",
"public/aggregated_metric_reporter.h",
"public/cooperative_scheduling_manager.h",
"public/dummy_schedulers.h",
@@ -188,6 +193,8 @@ jumbo_source_set("test_support") {
"test/test_queueing_time_estimator_client.cc",
"test/test_queueing_time_estimator_client.h",
"test/web_fake_thread_scheduler.cc",
+ "test/web_fake_widget_scheduler.cc",
+ "test/web_fake_widget_scheduler.h",
]
deps = [
@@ -232,7 +239,6 @@ jumbo_source_set("unit_tests") {
"main_thread/queueing_time_estimator_unittest.cc",
"main_thread/render_widget_signals_unittest.cc",
"main_thread/user_model_unittest.cc",
- "worker/compositor_thread_scheduler_unittest.cc",
"worker/worker_scheduler_proxy_unittest.cc",
"worker/worker_scheduler_unittest.cc",
"worker/worker_thread_scheduler_unittest.cc",
@@ -253,9 +259,7 @@ jumbo_source_set("unit_tests") {
source_set("perf_tests") {
testonly = true
- sources = [
- "test/queueing_time_estimator_perf_test.cc",
- ]
+ sources = [ "test/queueing_time_estimator_perf_test.cc" ]
deps = [
"//base",
@@ -327,7 +331,5 @@ fuzzer_test("sequence_manager_fuzzer") {
}
proto_library("sequence_manager_test_description_proto") {
- sources = [
- "test/fuzzer/proto/sequence_manager_test_description.proto",
- ]
+ sources = [ "test/fuzzer/proto/sequence_manager_test_description.proto" ]
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/DEPS b/chromium/third_party/blink/renderer/platform/scheduler/DEPS
index a42789826bd..09f3deab389 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/DEPS
+++ b/chromium/third_party/blink/renderer/platform/scheduler/DEPS
@@ -52,7 +52,6 @@ include_rules = [
"+services/metrics",
"+third_party/blink/renderer/platform/bindings/parkable_string_manager.h",
- "+third_party/blink/renderer/platform/instrumentation/histogram.h",
"+third_party/blink/renderer/platform/instrumentation",
"+third_party/blink/renderer/platform/platform_export.h",
"+third_party/blink/renderer/platform/runtime_enabled_features.h",
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/OWNERS b/chromium/third_party/blink/renderer/platform/scheduler/OWNERS
index 3df140deab0..a1de77fc540 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/OWNERS
+++ b/chromium/third_party/blink/renderer/platform/scheduler/OWNERS
@@ -1,6 +1,5 @@
# LON scheduling team
altimin@chromium.org
-alexclarke@chromium.org
carlscab@google.com
rmcilroy@chromium.org
skyostil@chromium.org
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/cooperative_scheduling_manager.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/cooperative_scheduling_manager.cc
index 0413fe7b99a..f6a029de1f6 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/cooperative_scheduling_manager.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/cooperative_scheduling_manager.cc
@@ -47,15 +47,17 @@ CooperativeSchedulingManager::CooperativeSchedulingManager()
}
void CooperativeSchedulingManager::EnterAllowedStackScope() {
- TRACE_EVENT_ASYNC_BEGIN0("renderer.scheduler", "PreemptionAllowedStackScope",
- this);
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("renderer.scheduler",
+ "PreemptionAllowedStackScope",
+ TRACE_ID_LOCAL(this));
allowed_stack_scope_depth_++;
}
void CooperativeSchedulingManager::LeaveAllowedStackScope() {
- TRACE_EVENT_ASYNC_END0("renderer.scheduler", "PreemptionAllowedStackScope",
- this);
+ TRACE_EVENT_NESTABLE_ASYNC_END0("renderer.scheduler",
+ "PreemptionAllowedStackScope",
+ TRACE_ID_LOCAL(this));
allowed_stack_scope_depth_--;
DCHECK_GE(allowed_stack_scope_depth_, 0);
}
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 4633243ee58..c456a695bac 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
@@ -37,8 +37,8 @@ class DummyFrameScheduler : public FrameScheduler {
bool IsPageVisible() const override { return true; }
void SetPaused(bool) override {}
void SetShouldReportPostedTasksWhenDisabled(bool) override {}
- void SetCrossOrigin(bool) override {}
- bool IsCrossOrigin() const override { return false; }
+ void SetCrossOriginToMainFrame(bool) override {}
+ bool IsCrossOriginToMainFrame() const override { return false; }
void SetIsAdFrame() override {}
bool IsAdFrame() const override { return false; }
void TraceUrlChange(const String&) override {}
@@ -175,6 +175,10 @@ class DummyThreadScheduler : public ThreadScheduler {
return base::ThreadTaskRunnerHandle::Get();
}
+ scoped_refptr<base::SingleThreadTaskRunner> NonWakingTaskRunner() override {
+ return base::ThreadTaskRunnerHandle::Get();
+ }
+
std::unique_ptr<PageScheduler> CreatePageScheduler(
PageScheduler::Delegate*) override {
return std::make_unique<DummyPageScheduler>();
@@ -231,11 +235,6 @@ class DummyWebThreadScheduler : public WebThreadScheduler,
return base::ThreadTaskRunnerHandle::Get();
}
- scoped_refptr<base::SingleThreadTaskRunner> InputTaskRunner() override {
- DCHECK(WTF::IsMainThread());
- return base::ThreadTaskRunnerHandle::Get();
- }
-
scoped_refptr<base::SingleThreadTaskRunner> IPCTaskRunner() override {
DCHECK(WTF::IsMainThread());
return base::ThreadTaskRunnerHandle::Get();
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/features.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/features.cc
deleted file mode 100644
index b49ffd20c5b..00000000000
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/features.cc
+++ /dev/null
@@ -1,19 +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/scheduler/common/features.h"
-
-namespace blink {
-namespace scheduler {
-
-// Field trial parameters associated with |kThrottleAndFreezeTaskTypes| feature.
-// These override the throttleable and freezable QueueTraits bits for the tasks
-// specified in the parameters. The parameters are comma separated lists, of the
-// the form: "throttleable": "name1,name2", "freezable": "name1,name3". The
-// names should be those returned by TaskTypeNames::TaskTypeToString().
-const char kThrottleableTaskTypesListParam[] = "ThrottleableTasks";
-const char kFreezableTaskTypesListParam[] = "FreezableTasks";
-
-} // 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 b65ab55a0a4..6f12fc5f39a 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/features.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/features.h
@@ -12,9 +12,6 @@
namespace blink {
namespace scheduler {
-const base::Feature kHighPriorityInputOnMainThread{
- "BlinkSchedulerHighPriorityInput", base::FEATURE_ENABLED_BY_DEFAULT};
-
const base::Feature kHighPriorityInputOnCompositorThread{
"BlinkSchedulerHighPriorityInputOnCompositorThread",
base::FEATURE_DISABLED_BY_DEFAULT};
@@ -22,6 +19,10 @@ const base::Feature kHighPriorityInputOnCompositorThread{
const base::Feature kDedicatedWorkerThrottling{
"BlinkSchedulerWorkerThrottling", base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kBestEffortPriorityForFindInPage{
+ "BlinkSchedulerBestEffortPriorityForFindInPage",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
// COMPOSITING PRIORITY EXPERIMENT CONTROLS
// Enables experiment to increase priority of the compositing tasks during
@@ -76,7 +77,7 @@ const base::Feature kVeryHighPriorityForCompositingAlternating{
// to kNormalPriority.
const base::Feature kVeryHighPriorityForCompositingAfterDelay{
"BlinkSchedulerVeryHighPriorityForCompositingAfterDelay",
- base::FEATURE_DISABLED_BY_DEFAULT};
+ base::FEATURE_ENABLED_BY_DEFAULT};
// Param for kVeryHighPriorityForCompositingAfterDelay experiment. How long
// in ms the compositor will wait to be prioritized if no compositor tasks run.
@@ -197,32 +198,11 @@ const base::Feature kLowPriorityForCrossOriginOnlyWhenLoading{
"BlinkSchedulerLowPriorityForCrossOriginOnlyWhenLoading",
base::FEATURE_DISABLED_BY_DEFAULT};
-// Enable setting throttleable and freezable task types from field trial
-// parameters.
-const base::Feature kThrottleAndFreezeTaskTypes{
- "ThrottleAndFreezeTaskTypes", base::FEATURE_DISABLED_BY_DEFAULT};
-
// Prioritizes loading and compositing tasks while loading.
const base::Feature kPrioritizeCompositingAndLoadingDuringEarlyLoading{
"PrioritizeCompositingAndLoadingDuringEarlyLoading",
base::FEATURE_DISABLED_BY_DEFAULT};
-// Parameters for |kThrottleAndFreezeTaskTypes|.
-extern const char PLATFORM_EXPORT kThrottleableTaskTypesListParam[];
-extern const char PLATFORM_EXPORT kFreezableTaskTypesListParam[];
-
-// If enabled, the scheduler will bypass the priority-based anti-starvation
-// logic that prevents indefinite starvation of lower priority tasks in the
-// presence of higher priority tasks by occasionally selecting lower
-// priority task queues over higher priority task queues.
-//
-// Note: this does not affect the anti-starvation logic that is in place for
-// preventing delayed tasks from starving immediate tasks, which is always
-// enabled.
-const base::Feature kBlinkSchedulerDisableAntiStarvationForPriorities{
- "BlinkSchedulerDisableAntiStarvationForPriorities",
- base::FEATURE_ENABLED_BY_DEFAULT};
-
// Enable setting high priority database task type from field trial parameters.
const base::Feature kHighPriorityDatabaseTaskType{
"HighPriorityDatabaseTaskType", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper.cc
index 23246956a95..4f769b7a650 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper.cc
@@ -439,9 +439,15 @@ void IdleHelper::State::TraceEventIdlePeriodStateChange(
!new_running_idle_task) {
running_idle_task_for_tracing_ = false;
if (!idle_period_deadline_.is_null() && now > idle_period_deadline_) {
- TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0(
- "renderer.scheduler", idle_period_tracing_name_, this,
- "DeadlineOverrun",
+ if (last_sub_trace_event_name_) {
+ TRACE_EVENT_NESTABLE_ASYNC_END0("renderer.scheduler",
+ last_sub_trace_event_name_,
+ TRACE_ID_LOCAL(this));
+ }
+ last_sub_trace_event_name_ = "DeadlineOverrun";
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0(
+ "renderer.scheduler", last_sub_trace_event_name_,
+ TRACE_ID_LOCAL(this),
std::max(idle_period_deadline_, last_idle_task_trace_time_));
}
}
@@ -449,35 +455,46 @@ void IdleHelper::State::TraceEventIdlePeriodStateChange(
if (IsInIdlePeriod(new_state)) {
if (!idle_period_trace_event_started_) {
idle_period_trace_event_started_ = true;
- TRACE_EVENT_ASYNC_BEGIN1("renderer.scheduler", idle_period_tracing_name_,
- this, "idle_period_length_ms",
- (new_deadline - now).InMillisecondsF());
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(
+ "renderer.scheduler", idle_period_tracing_name_, TRACE_ID_LOCAL(this),
+ "idle_period_length_ms", (new_deadline - now).InMillisecondsF());
}
+ const char* new_sub_trace_event_name = nullptr;
+
if (new_running_idle_task) {
last_idle_task_trace_time_ = now;
running_idle_task_for_tracing_ = true;
- TRACE_EVENT_ASYNC_STEP_INTO0("renderer.scheduler",
- idle_period_tracing_name_, this,
- "RunningIdleTask");
+ new_sub_trace_event_name = "RunningIdleTask";
} else if (new_state == IdlePeriodState::kInShortIdlePeriod) {
- TRACE_EVENT_ASYNC_STEP_INTO0("renderer.scheduler",
- idle_period_tracing_name_, this,
- "ShortIdlePeriod");
+ new_sub_trace_event_name = "ShortIdlePeriod";
} else if (IsInLongIdlePeriod(new_state) &&
new_state != IdlePeriodState::kInLongIdlePeriodPaused) {
- TRACE_EVENT_ASYNC_STEP_INTO0("renderer.scheduler",
- idle_period_tracing_name_, this,
- "LongIdlePeriod");
+ new_sub_trace_event_name = "LongIdlePeriod";
} else if (new_state == IdlePeriodState::kInLongIdlePeriodPaused) {
- TRACE_EVENT_ASYNC_STEP_INTO0("renderer.scheduler",
- idle_period_tracing_name_, this,
- "LongIdlePeriodPaused");
+ new_sub_trace_event_name = "LongIdlePeriodPaused";
+ }
+
+ if (new_sub_trace_event_name) {
+ if (last_sub_trace_event_name_) {
+ TRACE_EVENT_NESTABLE_ASYNC_END0("renderer.scheduler",
+ last_sub_trace_event_name_,
+ TRACE_ID_LOCAL(this));
+ }
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(
+ "renderer.scheduler", new_sub_trace_event_name, TRACE_ID_LOCAL(this));
+ last_sub_trace_event_name_ = new_sub_trace_event_name;
}
} else if (idle_period_trace_event_started_) {
+ if (last_sub_trace_event_name_) {
+ TRACE_EVENT_NESTABLE_ASYNC_END0("renderer.scheduler",
+ last_sub_trace_event_name_,
+ TRACE_ID_LOCAL(this));
+ last_sub_trace_event_name_ = nullptr;
+ }
+ TRACE_EVENT_NESTABLE_ASYNC_END0(
+ "renderer.scheduler", idle_period_tracing_name_, TRACE_ID_LOCAL(this));
idle_period_trace_event_started_ = false;
- TRACE_EVENT_ASYNC_END0("renderer.scheduler", idle_period_tracing_name_,
- this);
}
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper.h b/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper.h
index aa80c6a2e39..51c7593d95e 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper.h
@@ -195,6 +195,7 @@ class PLATFORM_EXPORT IdleHelper : public base::TaskObserver,
bool idle_period_trace_event_started_;
bool running_idle_task_for_tracing_;
const char* idle_period_tracing_name_;
+ const char* last_sub_trace_event_name_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(State);
};
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper_unittest.cc
index 8d6f03efff5..5110c90ee31 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/idle_helper_unittest.cc
@@ -172,26 +172,12 @@ class IdleHelperForTest : public IdleHelper, public IdleHelper::Delegate {
class BaseIdleHelperTest : public testing::Test {
public:
- BaseIdleHelperTest(
- std::unique_ptr<base::MessageLoop> message_loop,
+ explicit BaseIdleHelperTest(
base::TimeDelta required_quiescence_duration_before_long_idle_period)
- : message_loop_(std::move(message_loop)),
- test_task_runner_(base::MakeRefCounted<base::TestMockTimeTaskRunner>(
+ : test_task_runner_(base::MakeRefCounted<base::TestMockTimeTaskRunner>(
base::TestMockTimeTaskRunner::Type::kStandalone)) {
- if (!message_loop_) {
- sequence_manager_ =
- base::sequence_manager::SequenceManagerForTest::Create(
- nullptr, test_task_runner_,
- test_task_runner_->GetMockTickClock());
- } else {
- // It's okay to use |test_task_runner_| just as a mock clock because
- // it isn't bound to thread and all tasks will go through a MessageLoop.
- sequence_manager_ =
- base::sequence_manager::SequenceManagerForTest::CreateOnCurrentThread(
- base::sequence_manager::SequenceManager::Settings::Builder()
- .SetTickClock(test_task_runner_->GetMockTickClock())
- .Build());
- }
+ sequence_manager_ = base::sequence_manager::SequenceManagerForTest::Create(
+ nullptr, test_task_runner_, test_task_runner_->GetMockTickClock());
scheduler_helper_ = std::make_unique<NonMainThreadSchedulerHelper>(
sequence_manager_.get(), nullptr, TaskType::kInternalTest);
idle_helper_ = std::make_unique<IdleHelperForTest>(
@@ -275,7 +261,6 @@ class BaseIdleHelperTest : public testing::Test {
return idle_helper_->idle_queue_;
}
- std::unique_ptr<base::MessageLoop> message_loop_;
scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner_;
std::unique_ptr<SequenceManager> sequence_manager_;
std::unique_ptr<NonMainThreadSchedulerHelper> scheduler_helper_;
@@ -289,7 +274,7 @@ class BaseIdleHelperTest : public testing::Test {
class IdleHelperTest : public BaseIdleHelperTest {
public:
- IdleHelperTest() : BaseIdleHelperTest(nullptr, base::TimeDelta()) {}
+ IdleHelperTest() : BaseIdleHelperTest(base::TimeDelta()) {}
~IdleHelperTest() override = default;
@@ -400,7 +385,7 @@ TEST_F(IdleHelperTest, TestIdleTaskExceedsDeadline) {
class IdleHelperTestWithIdlePeriodObserver : public BaseIdleHelperTest {
public:
IdleHelperTestWithIdlePeriodObserver()
- : BaseIdleHelperTest(nullptr, base::TimeDelta()) {}
+ : BaseIdleHelperTest(base::TimeDelta()) {}
~IdleHelperTestWithIdlePeriodObserver() override = default;
@@ -785,7 +770,6 @@ class IdleHelperWithQuiescencePeriodTest : public BaseIdleHelperTest {
IdleHelperWithQuiescencePeriodTest()
: BaseIdleHelperTest(
- nullptr,
base::TimeDelta::FromMilliseconds(kQuiescenceDelayMs)) {}
~IdleHelperWithQuiescencePeriodTest() override = default;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/pollable_thread_safe_flag.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/pollable_thread_safe_flag.cc
index d26f6d7ac75..aab5cf3e5cf 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/pollable_thread_safe_flag.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/pollable_thread_safe_flag.cc
@@ -7,8 +7,6 @@
PollableThreadSafeFlag::PollableThreadSafeFlag(base::Lock* write_lock_)
: flag_(false), write_lock_(write_lock_) {}
-PollableThreadSafeFlag::~PollableThreadSafeFlag() = default;
-
void PollableThreadSafeFlag::SetWhileLocked(bool value) {
write_lock_->AssertAcquired();
base::subtle::Release_Store(&flag_, value);
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/pollable_thread_safe_flag.h b/chromium/third_party/blink/renderer/platform/scheduler/common/pollable_thread_safe_flag.h
index a78dc2bb7ff..1fdd4a2eefb 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/pollable_thread_safe_flag.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/pollable_thread_safe_flag.h
@@ -21,7 +21,6 @@ class PollableThreadSafeFlag {
public:
explicit PollableThreadSafeFlag(base::Lock* write_lock);
- ~PollableThreadSafeFlag();
// Set the flag. May only be called if |write_lock| is held.
void SetWhileLocked(bool value);
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.cc
index ef55b44c5ee..c751d9ccc24 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.cc
@@ -41,7 +41,7 @@ void SchedulerHelper::InitDefaultQueues(
DCHECK(sequence_manager_);
sequence_manager_->SetDefaultTaskRunner(default_task_runner_);
- blink_task_executor_.emplace(default_task_runner_, sequence_manager_);
+ simple_task_executor_.emplace(default_task_runner_);
}
SchedulerHelper::~SchedulerHelper() {
@@ -182,18 +182,5 @@ bool SchedulerHelper::HasCPUTimingForEachTask() const {
return false;
}
-SchedulerHelper::BlinkTaskExecutor::BlinkTaskExecutor(
- scoped_refptr<base::SingleThreadTaskRunner> default_task_queue,
- base::sequence_manager::SequenceManager* sequence_manager)
- : base::SimpleTaskExecutor(sequence_manager, std::move(default_task_queue)),
- sequence_manager_(sequence_manager) {}
-
-SchedulerHelper::BlinkTaskExecutor::~BlinkTaskExecutor() = default;
-
-const scoped_refptr<base::SequencedTaskRunner>&
-SchedulerHelper::BlinkTaskExecutor::GetContinuationTaskRunner() {
- return sequence_manager_->GetTaskRunnerForCurrentTask();
-}
-
} // namespace scheduler
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h b/chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h
index 52b84746c4b..3f2267ef8ec 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h
@@ -130,29 +130,12 @@ class PLATFORM_EXPORT SchedulerHelper
private:
friend class SchedulerHelperTest;
- // Like SimpleTaskExecutor except it knows how to get the current task runner
- // from the SequenceManager to implement GetContinuationTaskRunner.
- class BlinkTaskExecutor : public base::SimpleTaskExecutor {
- public:
- BlinkTaskExecutor(
- scoped_refptr<base::SingleThreadTaskRunner> default_task_queue,
- base::sequence_manager::SequenceManager* sequence_manager);
-
- ~BlinkTaskExecutor() override;
-
- // base::TaskExecutor implementation.
- const scoped_refptr<base::SequencedTaskRunner>& GetContinuationTaskRunner()
- override;
-
- private:
- base::sequence_manager::SequenceManager* sequence_manager_; // NOT OWNED
- };
scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
Observer* observer_; // NOT OWNED
UkmTaskSampler ukm_task_sampler_;
- base::Optional<BlinkTaskExecutor> blink_task_executor_;
+ base::Optional<base::SimpleTaskExecutor> simple_task_executor_;
DISALLOW_COPY_AND_ASSIGN(SchedulerHelper);
};
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 24d577ddcd3..ca7327cff8f 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
@@ -13,15 +13,18 @@ bool SchedulingPolicy::IsFeatureSticky(SchedulingPolicy::Feature feature) {
case Feature::kWebSocket:
case Feature::kWebRTC:
case Feature::kDedicatedWorkerOrWorklet:
- case Feature::kOutstandingNetworkRequest:
+ case Feature::kOutstandingNetworkRequestFetch:
+ case Feature::kOutstandingNetworkRequestXHR:
+ case Feature::kOutstandingNetworkRequestOthers:
case Feature::kOutstandingIndexedDBTransaction:
- case Feature::kHasScriptableFramesInMultipleTabs:
case Feature::kBroadcastChannel:
case Feature::kIndexedDBConnection:
case Feature::kWebGL:
case Feature::kWebVR:
case Feature::kWebXR:
case Feature::kSharedWorker:
+ case Feature::kWebHID:
+ case Feature::kWebShare:
return false;
case Feature::kMainResourceHasCacheControlNoStore:
case Feature::kMainResourceHasCacheControlNoCache:
@@ -44,6 +47,10 @@ bool SchedulingPolicy::IsFeatureSticky(SchedulingPolicy::Feature feature) {
case Feature::kRequestedBackForwardCacheBlockedSensors:
case Feature::kRequestedBackgroundWorkPermission:
case Feature::kWebLocks:
+ case Feature::kWakeLock:
+ case Feature::kRequestedStorageAccessGrant:
+ case Feature::kWebNfc:
+ case Feature::kWebFileSystem:
return true;
}
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.cc
index 920153dc8b1..97dbeaa9d3b 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.cc
@@ -61,6 +61,11 @@ SimpleThreadScheduler::DeprecatedDefaultTaskRunner() {
return base::ThreadTaskRunnerHandle::Get();
}
+scoped_refptr<base::SingleThreadTaskRunner>
+SimpleThreadScheduler::NonWakingTaskRunner() {
+ return base::ThreadTaskRunnerHandle::Get();
+}
+
std::unique_ptr<PageScheduler> SimpleThreadScheduler::CreatePageScheduler(
PageScheduler::Delegate* delegate) {
return nullptr;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.h b/chromium/third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.h
index 35c83b2c291..1111310914d 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/simple_thread_scheduler.h
@@ -55,6 +55,7 @@ class SimpleThreadScheduler : public ThreadScheduler {
scoped_refptr<base::SingleThreadTaskRunner> V8TaskRunner() override;
scoped_refptr<base::SingleThreadTaskRunner> CompositorTaskRunner() override;
scoped_refptr<base::SingleThreadTaskRunner> IPCTaskRunner() override;
+ scoped_refptr<base::SingleThreadTaskRunner> NonWakingTaskRunner() override;
scoped_refptr<base::SingleThreadTaskRunner> DeprecatedDefaultTaskRunner()
override;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/thread_cpu_throttler.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/thread_cpu_throttler.cc
index c184e225ab1..655b96a1802 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/thread_cpu_throttler.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/thread_cpu_throttler.cc
@@ -106,6 +106,9 @@ void ThreadCPUThrottler::ThrottlingThread::InstallSignalHandler() {
struct sigaction sa;
sa.sa_handler = &HandleSignal;
sigemptyset(&sa.sa_mask);
+ // Block SIGPROF while our handler is running so that the V8 CPU profiler
+ // doesn't try to sample the stack while our signal handler is active.
+ sigaddset(&sa.sa_mask, SIGPROF);
sa.sa_flags = SA_RESTART;
signal_handler_installed_ =
(sigaction(SIGUSR2, &sa, &old_signal_handler_) == 0);
@@ -164,15 +167,16 @@ void ThreadCPUThrottler::ThrottlingThread::Throttle() {
}
void ThreadCPUThrottler::ThrottlingThread::Start() {
-#ifdef USE_SIGNALS
+#if defined(USE_SIGNALS) || defined(OS_WIN)
+#if defined(USE_SIGNALS)
InstallSignalHandler();
-#elif !defined(OS_WIN)
- LOG(ERROR) << "CPU throttling is not supported.";
- return;
#endif
if (!base::PlatformThread::Create(0, this, &throttling_thread_handle_)) {
LOG(ERROR) << "Failed to create throttling thread.";
}
+#else
+ LOG(ERROR) << "CPU throttling is not supported.";
+#endif
}
void ThreadCPUThrottler::ThrottlingThread::Sleep(base::TimeDelta duration) {
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 0dc678298e4..9570477f5f0 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
@@ -602,9 +602,6 @@ bool TaskQueueThrottler::Metadata::DecrementRefCount() {
return false;
}
-void TaskQueueThrottler::Metadata::OnPostTask(base::Location from_here,
- base::TimeDelta delay) {}
-
void TaskQueueThrottler::Metadata::OnQueueNextWakeUpChanged(
base::TimeTicks wake_up) {
throttler_->OnQueueNextWakeUpChanged(queue_, wake_up);
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 449e843172b..ad6775949d2 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
@@ -143,7 +143,6 @@ class PLATFORM_EXPORT TaskQueueThrottler : public BudgetPoolController {
bool DecrementRefCount();
// TaskQueue::Observer implementation:
- void OnPostTask(base::Location from_here, base::TimeDelta delay) override;
void OnQueueNextWakeUpChanged(base::TimeTicks wake_up) override;
size_t throttling_ref_count() const { return throttling_ref_count_; }
@@ -157,6 +156,8 @@ class PLATFORM_EXPORT TaskQueueThrottler : public BudgetPoolController {
TaskQueueThrottler* const throttler_;
size_t throttling_ref_count_ = 0;
HashSet<BudgetPool*> budget_pools_;
+
+ DISALLOW_COPY_AND_ASSIGN(Metadata);
};
using TaskQueueMap =
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/tracing_helper.h b/chromium/third_party/blink/renderer/platform/scheduler/common/tracing_helper.h
index e957afa1292..d82b092c265 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/tracing_helper.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/tracing_helper.h
@@ -100,7 +100,7 @@ class StateTracer {
~StateTracer() {
if (slice_is_open_)
- TRACE_EVENT_ASYNC_END0(category, name_, object_);
+ TRACE_EVENT_NESTABLE_ASYNC_END0(category, name_, TRACE_ID_LOCAL(object_));
}
// String will be copied before leaving this function.
@@ -122,22 +122,19 @@ class StateTracer {
private:
void TraceImpl(const char* state, bool need_copy) {
if (slice_is_open_) {
- TRACE_EVENT_ASYNC_END0(category, name_, object_);
+ TRACE_EVENT_NESTABLE_ASYNC_END0(category, name_, TRACE_ID_LOCAL(object_));
slice_is_open_ = false;
}
if (!state || !is_enabled())
return;
- // Trace viewer logic relies on subslice starting at the exact same time
- // as the async event.
- base::TimeTicks now = TRACE_TIME_TICKS_NOW();
- TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0(category, name_, object_, now);
if (need_copy) {
- TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0(category, name_, object_,
- TRACE_STR_COPY(state), now);
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(category, name_,
+ TRACE_ID_LOCAL(object_), "state",
+ TRACE_STR_COPY(state));
} else {
- TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0(category, name_, object_,
- state, now);
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(
+ category, name_, TRACE_ID_LOCAL(object_), "state", state);
}
slice_is_open_ = true;
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/web_thread_scheduler.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/web_thread_scheduler.cc
index ac27cae4d42..641f84cc4b8 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/web_thread_scheduler.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/web_thread_scheduler.cc
@@ -10,6 +10,8 @@
#include "base/message_loop/message_pump_type.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
+#include "third_party/blink/public/common/input/web_input_event_attribution.h"
+#include "third_party/blink/public/platform/scheduler/web_widget_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/common/features.h"
#include "third_party/blink/renderer/platform/scheduler/common/tracing_helper.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
@@ -29,9 +31,6 @@ WebThreadScheduler::CreateMainThreadScheduler(
.SetMessagePumpType(base::MessagePumpType::DEFAULT)
.SetRandomisedSamplingEnabled(true)
.SetAddQueueTimeToTasks(true)
- .SetAntiStarvationLogicForPrioritiesDisabled(
- base::FeatureList::IsEnabled(
- kBlinkSchedulerDisableAntiStarvationForPriorities))
.Build();
auto sequence_manager =
message_pump
@@ -74,12 +73,6 @@ WebThreadScheduler::CompositorTaskRunner() {
}
scoped_refptr<base::SingleThreadTaskRunner>
-WebThreadScheduler::InputTaskRunner() {
- NOTREACHED();
- return nullptr;
-}
-
-scoped_refptr<base::SingleThreadTaskRunner>
WebThreadScheduler::IPCTaskRunner() {
NOTREACHED();
return nullptr;
@@ -102,6 +95,12 @@ std::unique_ptr<Thread> WebThreadScheduler::CreateMainThread() {
return nullptr;
}
+std::unique_ptr<WebWidgetScheduler>
+WebThreadScheduler::CreateWidgetScheduler() {
+ NOTREACHED();
+ return nullptr;
+}
+
std::unique_ptr<WebRenderWidgetSchedulingState>
WebThreadScheduler::NewRenderWidgetSchedulingState() {
NOTREACHED();
@@ -131,12 +130,14 @@ void WebThreadScheduler::DidHandleInputEventOnCompositorThread(
}
void WebThreadScheduler::WillPostInputEventToMainThread(
- WebInputEvent::Type web_input_event_type) {
+ WebInputEvent::Type web_input_event_type,
+ const WebInputEventAttribution& attribution) {
NOTREACHED();
}
void WebThreadScheduler::WillHandleInputEventOnMainThread(
- WebInputEvent::Type web_input_event_type) {
+ WebInputEvent::Type web_input_event_type,
+ const WebInputEventAttribution& attribution) {
NOTREACHED();
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/worker_pool.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/worker_pool.cc
index 50634f1db7f..c5492c3f3cf 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/worker_pool.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/worker_pool.cc
@@ -5,24 +5,22 @@
#include "third_party/blink/renderer/platform/scheduler/public/worker_pool.h"
#include "base/location.h"
-#include "base/task/post_task.h"
+#include "base/task/thread_pool.h"
namespace blink {
namespace worker_pool {
void PostTask(const base::Location& location, CrossThreadOnceClosure closure) {
- PostTask(
- location,
- {base::ThreadPool(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
- std::move(closure));
+ PostTask(location, {base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
+ std::move(closure));
}
void PostTask(const base::Location& location,
const base::TaskTraits& traits,
CrossThreadOnceClosure closure) {
- base::PostTask(location, traits,
- ConvertToBaseOnceCallback(std::move(closure)));
+ base::ThreadPool::PostTask(location, traits,
+ ConvertToBaseOnceCallback(std::move(closure)));
}
} // namespace worker_pool
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.cc
index 8564cbca5b1..f755622d8dc 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.cc
@@ -15,17 +15,14 @@ CompositorPriorityExperiments::CompositorPriorityExperiments(
MainThreadSchedulerImpl* scheduler)
: scheduler_(scheduler),
experiment_(GetExperimentFromFeatureList()),
+ last_compositor_task_time_(scheduler_->GetTickClock()->NowTicks()),
prioritize_compositing_after_delay_length_(
base::TimeDelta::FromMilliseconds(kCompositingDelayLength.Get())),
stop_signal_(base::FeatureList::IsEnabled(
kPrioritizeCompositingUntilBeginMainFrame)
? StopSignalType::kBeginMainFrameTask
- : StopSignalType::kAnyCompositorTask) {
- do_prioritize_compositing_after_delay_callback_.Reset(base::BindRepeating(
- &CompositorPriorityExperiments::DoPrioritizeCompositingAfterDelay,
- base::Unretained(this)));
-}
-CompositorPriorityExperiments::~CompositorPriorityExperiments() {}
+ : StopSignalType::kAnyCompositorTask) {}
+CompositorPriorityExperiments::~CompositorPriorityExperiments() = default;
CompositorPriorityExperiments::Experiment
CompositorPriorityExperiments::GetExperimentFromFeatureList() {
@@ -38,11 +35,11 @@ CompositorPriorityExperiments::GetExperimentFromFeatureList() {
kVeryHighPriorityForCompositingAlternating)) {
return Experiment::kVeryHighPriorityForCompositingAlternating;
} else if (base::FeatureList::IsEnabled(
- kVeryHighPriorityForCompositingAfterDelay)) {
- return Experiment::kVeryHighPriorityForCompositingAfterDelay;
- } else if (base::FeatureList::IsEnabled(
kVeryHighPriorityForCompositingBudget)) {
return Experiment::kVeryHighPriorityForCompositingBudget;
+ } else if (base::FeatureList::IsEnabled(
+ kVeryHighPriorityForCompositingAfterDelay)) {
+ return Experiment::kVeryHighPriorityForCompositingAfterDelay;
} else {
return Experiment::kNone;
}
@@ -75,15 +72,7 @@ QueuePriority CompositorPriorityExperiments::GetCompositorPriority() const {
}
}
-void CompositorPriorityExperiments::DoPrioritizeCompositingAfterDelay() {
- delay_compositor_priority_ = QueuePriority::kVeryHighPriority;
- scheduler_->OnCompositorPriorityExperimentUpdateCompositorPriority();
-}
-
void CompositorPriorityExperiments::OnMainThreadSchedulerInitialized() {
- if (experiment_ == Experiment::kVeryHighPriorityForCompositingAfterDelay) {
- PostPrioritizeCompositingAfterDelayTask();
- }
if (experiment_ == Experiment::kVeryHighPriorityForCompositingBudget) {
budget_pool_controller_.reset(new CompositorBudgetPoolController(
this, scheduler_, scheduler_->CompositorTaskQueue().get(),
@@ -102,14 +91,6 @@ void CompositorPriorityExperiments::OnWillBeginMainFrame() {
will_begin_main_frame_ = true;
}
-void CompositorPriorityExperiments::PostPrioritizeCompositingAfterDelayTask() {
- DCHECK_EQ(experiment_, Experiment::kVeryHighPriorityForCompositingAfterDelay);
-
- scheduler_->ControlTaskRunner()->PostDelayedTask(
- FROM_HERE, do_prioritize_compositing_after_delay_callback_.GetCallback(),
- prioritize_compositing_after_delay_length_);
-}
-
void CompositorPriorityExperiments::OnTaskCompleted(
MainThreadTaskQueue* queue,
QueuePriority current_compositor_priority,
@@ -150,12 +131,15 @@ void CompositorPriorityExperiments::OnTaskCompleted(
case Experiment::kVeryHighPriorityForCompositingAfterDelay:
if (have_seen_stop_signal) {
delay_compositor_priority_ = QueuePriority::kNormalPriority;
- do_prioritize_compositing_after_delay_callback_.Cancel();
- PostPrioritizeCompositingAfterDelayTask();
-
- if (current_compositor_priority != delay_compositor_priority_)
- scheduler_->OnCompositorPriorityExperimentUpdateCompositorPriority();
+ last_compositor_task_time_ = task_timing->end_time();
+ } else {
+ if (task_timing->end_time() - last_compositor_task_time_ >=
+ prioritize_compositing_after_delay_length_) {
+ delay_compositor_priority_ = QueuePriority::kVeryHighPriority;
+ }
}
+ if (current_compositor_priority != delay_compositor_priority_)
+ scheduler_->OnCompositorPriorityExperimentUpdateCompositorPriority();
return;
case Experiment::kVeryHighPriorityForCompositingBudget:
budget_pool_controller_->OnTaskCompleted(queue, task_timing,
@@ -188,7 +172,7 @@ CompositorPriorityExperiments::CompositorBudgetPoolController::
TraceableVariableController* tracing_controller,
base::TimeDelta min_budget,
double budget_recovery_rate)
- : experiment_(experiment), tick_clock_(scheduler->GetTickClock()) {
+ : experiment_(experiment) {
DCHECK_EQ(compositor_queue->queue_type(),
MainThreadTaskQueue::QueueType::kCompositor);
base::TimeTicks now = scheduler->GetTickClock()->NowTicks();
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.h
index bb034bf4713..725d31d8f3f 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/compositor_priority_experiments.h
@@ -93,16 +93,10 @@ class PLATFORM_EXPORT CompositorPriorityExperiments {
CompositorPriorityExperiments* experiment_;
std::unique_ptr<CPUTimeBudgetPool> compositor_budget_pool_;
bool is_exhausted_ = false;
-
- const base::TickClock* tick_clock_; // Not owned.
};
static Experiment GetExperimentFromFeatureList();
- void DoPrioritizeCompositingAfterDelay();
-
- void PostPrioritizeCompositingAfterDelayTask();
-
enum class StopSignalType { kAnyCompositorTask, kBeginMainFrameTask };
MainThreadSchedulerImpl* scheduler_; // Not owned.
@@ -113,7 +107,7 @@ class PLATFORM_EXPORT CompositorPriorityExperiments {
QueuePriority::kVeryHighPriority;
QueuePriority delay_compositor_priority_ = QueuePriority::kNormalPriority;
- CancelableClosureHolder do_prioritize_compositing_after_delay_callback_;
+ base::TimeTicks last_compositor_task_time_;
base::TimeDelta prioritize_compositing_after_delay_length_;
QueuePriority budget_compositor_priority_ = QueuePriority::kVeryHighPriority;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.cc
new file mode 100644
index 00000000000..3fc1cfd2f2b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.cc
@@ -0,0 +1,87 @@
+// 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/find_in_page_budget_pool_controller.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_scheduler_impl.h"
+
+namespace blink {
+namespace scheduler {
+
+namespace {
+// We will accumulate at most 1000ms for find-in-page budget.
+constexpr base::TimeDelta kFindInPageMaxBudget =
+ base::TimeDelta::FromSeconds(1);
+// At least 25% of the total CPU time will go to find-in-page tasks.
+// TODO(rakina): Experiment with this number to figure out the right percentage
+// for find-in-page. Currently this is following CompositorPriorityExperiments.
+const double kFindInPageBudgetRecoveryRate = 0.25;
+} // namespace
+
+const QueuePriority
+ FindInPageBudgetPoolController::kFindInPageBudgetNotExhaustedPriority;
+const QueuePriority
+ FindInPageBudgetPoolController::kFindInPageBudgetExhaustedPriority;
+
+FindInPageBudgetPoolController::FindInPageBudgetPoolController(
+ MainThreadSchedulerImpl* scheduler)
+ : scheduler_(scheduler),
+ best_effort_budget_experiment_enabled_(
+ base::FeatureList::IsEnabled(kBestEffortPriorityForFindInPage)) {
+ if (best_effort_budget_experiment_enabled_) {
+ task_priority_ = QueuePriority::kBestEffortPriority;
+ } else {
+ task_priority_ = kFindInPageBudgetNotExhaustedPriority;
+ }
+}
+
+FindInPageBudgetPoolController::~FindInPageBudgetPoolController() = default;
+
+void FindInPageBudgetPoolController::EnsureBudgetPoolInitialized() {
+ DCHECK(!best_effort_budget_experiment_enabled_);
+ if (find_in_page_budget_pool_)
+ return;
+ base::TimeTicks now = scheduler_->GetTickClock()->NowTicks();
+ find_in_page_budget_pool_.reset(new CPUTimeBudgetPool(
+ "FindInPageBudgetPool", this, &scheduler_->tracing_controller_, now));
+ // Set no minimum budget for find-in-page, so that we won't delay running
+ // find-in-page tasks when budget is available.
+ find_in_page_budget_pool_->SetMinBudgetLevelToRun(now, base::TimeDelta());
+ find_in_page_budget_pool_->SetMaxBudgetLevel(now, kFindInPageMaxBudget);
+ find_in_page_budget_pool_->SetTimeBudgetRecoveryRate(
+ now, kFindInPageBudgetRecoveryRate);
+}
+
+void FindInPageBudgetPoolController::OnTaskCompleted(
+ MainThreadTaskQueue* queue,
+ TaskQueue::TaskTiming* task_timing) {
+ if (!queue || best_effort_budget_experiment_enabled_)
+ return;
+ EnsureBudgetPoolInitialized();
+ if (queue->GetPrioritisationType() ==
+ MainThreadTaskQueue::QueueTraits::PrioritisationType::kFindInPage) {
+ find_in_page_budget_pool_->RecordTaskRunTime(
+ queue, task_timing->start_time(), task_timing->end_time());
+ }
+
+ bool is_exhausted = !find_in_page_budget_pool_->CanRunTasksAt(
+ task_timing->end_time(), false /* is_wake_up */);
+ QueuePriority task_priority = is_exhausted
+ ? kFindInPageBudgetExhaustedPriority
+ : kFindInPageBudgetNotExhaustedPriority;
+
+ if (task_priority != task_priority_) {
+ task_priority_ = task_priority;
+ // If the priority changed, we need to make sure all find-in-page task
+ // queues across all frames get updated. Note that UpdatePolicy will
+ // update all task queues for all frames, which is a bit overkill - this
+ // should probably be optimized in the future.
+ scheduler_->UpdatePolicy();
+ }
+}
+
+} // namespace scheduler
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.h
new file mode 100644
index 00000000000..5fd8f296d48
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.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_PLATFORM_SCHEDULER_MAIN_THREAD_FIND_IN_PAGE_BUDGET_POOL_CONTROLLER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_FIND_IN_PAGE_BUDGET_POOL_CONTROLLER_H_
+
+#include "base/task/sequence_manager/task_queue.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool_controller.h"
+#include "third_party/blink/renderer/platform/scheduler/common/throttling/cpu_time_budget_pool.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
+
+namespace blink {
+namespace scheduler {
+
+using TaskQueue = base::sequence_manager::TaskQueue;
+using QueuePriority = base::sequence_manager::TaskQueue::QueuePriority;
+
+class CPUTimeBudgetPool;
+class MainThreadSchedulerImpl;
+
+class PLATFORM_EXPORT FindInPageBudgetPoolController
+ : public BudgetPoolController {
+ public:
+ static constexpr auto kFindInPageBudgetNotExhaustedPriority =
+ QueuePriority::kVeryHighPriority;
+ static constexpr auto kFindInPageBudgetExhaustedPriority =
+ QueuePriority::kNormalPriority;
+
+ explicit FindInPageBudgetPoolController(MainThreadSchedulerImpl* scheduler);
+ ~FindInPageBudgetPoolController() override;
+
+ void OnTaskCompleted(MainThreadTaskQueue* queue,
+ MainThreadTaskQueue::TaskTiming* task_timing);
+
+ QueuePriority CurrentTaskPriority() { return task_priority_; }
+
+ // Unimplemented methods.
+ // TODO(crbug.com/1056512): Remove these functions once we factor out the
+ // budget calculating logic from BudgetPoolController.
+ void UpdateQueueSchedulingLifecycleState(base::TimeTicks now,
+ TaskQueue* queue) override {}
+ void AddQueueToBudgetPool(TaskQueue* queue,
+ BudgetPool* budget_pool) override {}
+ void RemoveQueueFromBudgetPool(TaskQueue* queue,
+ BudgetPool* budget_pool) override {}
+ void UnregisterBudgetPool(BudgetPool* budget_pool) override {}
+ bool IsThrottled(TaskQueue* queue) const override { return false; }
+
+ private:
+ // We need to call this from OnTaskCompleted, because PartitionAlloc might not
+ // be initialized yet when we got constructed.
+ // TODO(crbug.com/1058645): Initialize |find_in_page_budget_pool_| from the
+ // constructor and remove this function.
+ void EnsureBudgetPoolInitialized();
+
+ MainThreadSchedulerImpl* scheduler_; // Not owned.
+ std::unique_ptr<CPUTimeBudgetPool> find_in_page_budget_pool_;
+ QueuePriority task_priority_;
+ const bool best_effort_budget_experiment_enabled_;
+};
+
+} // namespace scheduler
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_FIND_IN_PAGE_BUDGET_POOL_CONTROLLER_H_
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.cc
index fa4f2fc7761..631724eda29 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.cc
@@ -16,10 +16,10 @@ FrameOriginType GetFrameOriginType(FrameScheduler* scheduler) {
if (scheduler->GetFrameType() == FrameScheduler::FrameType::kMainFrame)
return FrameOriginType::kMainFrame;
- if (scheduler->IsCrossOrigin()) {
- return FrameOriginType::kCrossOriginFrame;
+ if (scheduler->IsCrossOriginToMainFrame()) {
+ return FrameOriginType::kCrossOriginToMainFrame;
} else {
- return FrameOriginType::kSameOriginFrame;
+ return FrameOriginType::kSameOriginToMainFrame;
}
}
@@ -27,10 +27,10 @@ const char* FrameOriginTypeToString(FrameOriginType origin) {
switch (origin) {
case FrameOriginType::kMainFrame:
return "main-frame";
- case FrameOriginType::kSameOriginFrame:
- return "same-origin";
- case FrameOriginType::kCrossOriginFrame:
- return "cross-origin";
+ case FrameOriginType::kSameOriginToMainFrame:
+ return "same-origin-to-main-frame";
+ case FrameOriginType::kCrossOriginToMainFrame:
+ return "cross-origin-to-main-frame";
case FrameOriginType::kCount:
NOTREACHED();
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.h
index 4739e0e0fac..573ba2f4afd 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.h
@@ -14,9 +14,10 @@ namespace scheduler {
// and should not be renumbered.
enum class FrameOriginType {
kMainFrame = 0,
- kSameOriginFrame = 1,
- kCrossOriginFrame = 2,
- kCount = 3
+ kSameOriginToMainFrame = 1,
+ kCrossOriginToMainFrame = 2,
+ // TODO(dcheng): Get rid of this and use the kMaxValue idiom.
+ kCount = 3,
};
FrameOriginType GetFrameOriginType(FrameScheduler* frame_scheduler);
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 0e52953485d..2f15127c778 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
@@ -10,6 +10,7 @@
#include "base/metrics/histogram_macros.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"
#include "third_party/blink/public/platform/blame_context.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -17,6 +18,7 @@
#include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h"
#include "third_party/blink/renderer/platform/scheduler/common/tracing_helper.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/find_in_page_budget_pool_controller.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/page_visibility_state.h"
@@ -77,45 +79,6 @@ void UpdatePriority(MainThreadTaskQueue* task_queue) {
task_queue->SetQueuePriority(frame_scheduler->ComputePriority(task_queue));
}
-// Extract a substring from |source| from [start to end), trimming leading
-// whitespace.
-String ExtractAndTrimString(String source, size_t start, size_t end) {
- DCHECK(start < source.length());
- DCHECK(end <= source.length());
- DCHECK(start <= end);
- // Trim whitespace
- while (start < end && source[start] == ' ')
- ++start;
- if (start < end)
- return source.Substring(start, end - start);
- return "";
-}
-
-HashSet<String> TaskTypesFromFieldTrialParam(const char* param) {
- HashSet<String> result;
- String task_type_list =
- String::FromUTF8(base::GetFieldTrialParamValueByFeature(
- kThrottleAndFreezeTaskTypes, param));
- if (!task_type_list.length())
- return result;
- // Extract the individual names, separated by ",".
- size_t pos = 0, start = 0;
- while ((pos = task_type_list.find(',', start)) != kNotFound) {
- String task_type = ExtractAndTrimString(task_type_list, start, pos);
- // Not valid to start with "," or have ",," in the list.
- DCHECK(task_type.length());
- result.insert(task_type);
- start = pos + 1;
- }
- // Handle the last or only task type name.
- String task_type =
- ExtractAndTrimString(task_type_list, start, task_type_list.length());
- DCHECK(task_type.length());
- result.insert(task_type);
-
- return result;
-}
-
} // namespace
FrameSchedulerImpl::PauseSubresourceLoadingHandleImpl::
@@ -169,7 +132,7 @@ FrameSchedulerImpl::FrameSchedulerImpl(
PausedStateToString),
frame_origin_type_(frame_type == FrameType::kMainFrame
? FrameOriginType::kMainFrame
- : FrameOriginType::kSameOriginFrame,
+ : FrameOriginType::kSameOriginToMainFrame,
"FrameScheduler.Origin",
this,
&tracing_controller_,
@@ -321,16 +284,16 @@ bool FrameSchedulerImpl::IsFrameVisible() const {
return frame_visible_;
}
-void FrameSchedulerImpl::SetCrossOrigin(bool cross_origin) {
+void FrameSchedulerImpl::SetCrossOriginToMainFrame(bool cross_origin) {
DCHECK(parent_page_scheduler_);
if (frame_origin_type_ == FrameOriginType::kMainFrame) {
DCHECK(!cross_origin);
return;
}
if (cross_origin) {
- frame_origin_type_ = FrameOriginType::kCrossOriginFrame;
+ frame_origin_type_ = FrameOriginType::kCrossOriginToMainFrame;
} else {
- frame_origin_type_ = FrameOriginType::kSameOriginFrame;
+ frame_origin_type_ = FrameOriginType::kSameOriginToMainFrame;
}
UpdatePolicy();
}
@@ -344,8 +307,8 @@ bool FrameSchedulerImpl::IsAdFrame() const {
return is_ad_frame_;
}
-bool FrameSchedulerImpl::IsCrossOrigin() const {
- return frame_origin_type_ == FrameOriginType::kCrossOriginFrame;
+bool FrameSchedulerImpl::IsCrossOriginToMainFrame() const {
+ return frame_origin_type_ == FrameOriginType::kCrossOriginToMainFrame;
}
void FrameSchedulerImpl::TraceUrlChange(const String& url) {
@@ -370,42 +333,8 @@ FrameScheduler::FrameType FrameSchedulerImpl::GetFrameType() const {
return frame_type_;
}
-void FrameSchedulerImpl::InitializeTaskTypeQueueTraitsMap(
- FrameTaskTypeToQueueTraitsArray& frame_task_types_to_queue_traits) {
- DCHECK_EQ(frame_task_types_to_queue_traits.size(),
- static_cast<size_t>(TaskType::kCount));
- // Using std set and strings here because field trial parameters are std
- // strings, and we cannot use WTF strings as Blink is not yet initialized.
- HashSet<String> throttleable_task_type_names;
- HashSet<String> freezable_task_type_names;
- if (base::FeatureList::IsEnabled(kThrottleAndFreezeTaskTypes)) {
- throttleable_task_type_names =
- TaskTypesFromFieldTrialParam(kThrottleableTaskTypesListParam);
- freezable_task_type_names =
- TaskTypesFromFieldTrialParam(kFreezableTaskTypesListParam);
- }
- for (size_t i = 0; i < static_cast<size_t>(TaskType::kCount); i++) {
- TaskType type = static_cast<TaskType>(i);
- base::Optional<QueueTraits> queue_traits =
- CreateQueueTraitsForTaskType(type);
- if (queue_traits && (!throttleable_task_type_names.IsEmpty() ||
- !freezable_task_type_names.IsEmpty())) {
- const char* task_type_name = TaskTypeNames::TaskTypeToString(type);
- if (!throttleable_task_type_names.Take(task_type_name).IsEmpty())
- queue_traits->SetCanBeThrottled(true);
- if (freezable_task_type_names.Take(task_type_name).IsEmpty())
- queue_traits->SetCanBeFrozen(true);
- }
- frame_task_types_to_queue_traits[i] = queue_traits;
- }
- // Protect against configuration errors.
- DCHECK(throttleable_task_type_names.IsEmpty());
- DCHECK(freezable_task_type_names.IsEmpty());
-}
-
// static
-base::Optional<QueueTraits> FrameSchedulerImpl::CreateQueueTraitsForTaskType(
- TaskType type) {
+QueueTraits FrameSchedulerImpl::CreateQueueTraitsForTaskType(TaskType type) {
// TODO(haraken): Optimize the mapping from TaskTypes to task runners.
// TODO(sreejakshetty): Clean up the PrioritisationType QueueTrait and
// QueueType for kInternalContinueScriptLoading and kInternalContentCapture.
@@ -464,13 +393,15 @@ base::Optional<QueueTraits> FrameSchedulerImpl::CreateQueueTraitsForTaskType(
case TaskType::kInternalUserInteraction:
case TaskType::kInternalIntersectionObserver:
return PausableTaskQueueTraits();
+ case TaskType::kInternalFindInPage:
+ return FindInPageTaskQueueTraits();
case TaskType::kInternalContinueScriptLoading:
return PausableTaskQueueTraits().SetPrioritisationType(
QueueTraits::PrioritisationType::kVeryHigh);
case TaskType::kDatabaseAccess:
if (base::FeatureList::IsEnabled(kHighPriorityDatabaseTaskType)) {
return PausableTaskQueueTraits().SetPrioritisationType(
- QueueTraits::PrioritisationType::kHigh);
+ QueueTraits::PrioritisationType::kExperimentalDatabase);
} else {
return PausableTaskQueueTraits();
}
@@ -508,19 +439,22 @@ base::Optional<QueueTraits> FrameSchedulerImpl::CreateQueueTraitsForTaskType(
case TaskType::kWorkerThreadTaskQueueDefault:
case TaskType::kWorkerThreadTaskQueueV8:
case TaskType::kWorkerThreadTaskQueueCompositor:
+ case TaskType::kMainThreadTaskQueueNonWaking:
// The web scheduling API task types are used by WebSchedulingTaskQueues.
// The associated TaskRunner should be obtained by creating a
// WebSchedulingTaskQueue with CreateWebSchedulingTaskQueue().
case TaskType::kExperimentalWebScheduling:
case TaskType::kCount:
// Not a valid frame-level TaskType.
- return base::nullopt;
+ NOTREACHED();
+ return QueueTraits();
}
// This method is called for all values between 0 and kCount. TaskType,
// however, has numbering gaps, so even though all enumerated TaskTypes are
// handled in the switch and return a value, we fall through for some values
// of |type|.
- return base::nullopt;
+ NOTREACHED();
+ return QueueTraits();
}
scoped_refptr<base::SingleThreadTaskRunner> FrameSchedulerImpl::GetTaskRunner(
@@ -532,17 +466,8 @@ scoped_refptr<base::SingleThreadTaskRunner> FrameSchedulerImpl::GetTaskRunner(
scoped_refptr<MainThreadTaskQueue> FrameSchedulerImpl::GetTaskQueue(
TaskType type) {
- DCHECK_LT(static_cast<size_t>(type),
- main_thread_scheduler_->scheduling_settings()
- .frame_task_types_to_queue_traits.size());
- base::Optional<QueueTraits> queue_traits =
- main_thread_scheduler_->scheduling_settings()
- .frame_task_types_to_queue_traits[static_cast<size_t>(type)];
- // We don't have a QueueTraits mapping for |task_type| if it is not a
- // frame-level task type.
- DCHECK(queue_traits);
- return frame_task_queue_controller_->GetTaskQueue(
- queue_traits.value());
+ QueueTraits queue_traits = CreateQueueTraitsForTaskType(type);
+ return frame_task_queue_controller_->GetTaskQueue(queue_traits);
}
std::unique_ptr<WebResourceLoadingTaskRunnerHandle>
@@ -638,6 +563,13 @@ WebScopedVirtualTimePauser FrameSchedulerImpl::CreateWebScopedVirtualTimePauser(
void FrameSchedulerImpl::ResetForNavigation() {
document_bound_weak_factory_.InvalidateWeakPtrs();
+ for (const auto& it : back_forward_cache_opt_out_counts_) {
+ TRACE_EVENT_NESTABLE_ASYNC_END0(
+ "renderer.scheduler", "ActiveSchedulerTrackedFeature",
+ TRACE_ID_LOCAL(reinterpret_cast<intptr_t>(this) ^
+ static_cast<int>(it.first)));
+ }
+
back_forward_cache_opt_out_counts_.clear();
back_forward_cache_opt_outs_.reset();
last_uploaded_active_features_ = 0;
@@ -650,13 +582,20 @@ void FrameSchedulerImpl::OnStartedUsingFeature(
if (policy.disable_aggressive_throttling)
OnAddedAggressiveThrottlingOptOut();
- if (policy.disable_back_forward_cache)
+ if (policy.disable_back_forward_cache) {
OnAddedBackForwardCacheOptOut(feature);
+ }
uint64_t new_mask = GetActiveFeaturesTrackedForBackForwardCacheMetricsMask();
- if (old_mask != new_mask)
+ if (old_mask != new_mask) {
NotifyDelegateAboutFeaturesAfterCurrentTask();
+ TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(
+ "renderer.scheduler", "ActiveSchedulerTrackedFeature",
+ TRACE_ID_LOCAL(reinterpret_cast<intptr_t>(this) ^
+ static_cast<int>(feature)),
+ "feature", FeatureToString(feature));
+ }
}
void FrameSchedulerImpl::OnStoppedUsingFeature(
@@ -671,8 +610,13 @@ void FrameSchedulerImpl::OnStoppedUsingFeature(
uint64_t new_mask = GetActiveFeaturesTrackedForBackForwardCacheMetricsMask();
- if (old_mask != new_mask)
+ if (old_mask != new_mask) {
NotifyDelegateAboutFeaturesAfterCurrentTask();
+ TRACE_EVENT_NESTABLE_ASYNC_END0(
+ "renderer.scheduler", "ActiveSchedulerTrackedFeature",
+ TRACE_ID_LOCAL(reinterpret_cast<intptr_t>(this) ^
+ static_cast<int>(feature)));
+ }
}
void FrameSchedulerImpl::NotifyDelegateAboutFeaturesAfterCurrentTask() {
@@ -743,7 +687,7 @@ void FrameSchedulerImpl::AsValueInto(
base::trace_event::TracedValue* state) const {
state->SetBoolean("frame_visible", frame_visible_);
state->SetBoolean("page_visible", parent_page_scheduler_->IsPageVisible());
- state->SetBoolean("cross_origin", IsCrossOrigin());
+ state->SetBoolean("cross_origin_to_main_frame", IsCrossOriginToMainFrame());
state->SetString("frame_type",
frame_type_ == FrameScheduler::FrameType::kMainFrame
? "MainFrame"
@@ -892,7 +836,7 @@ bool FrameSchedulerImpl::ShouldThrottleTaskQueues() const {
if (!parent_page_scheduler_->IsPageVisible())
return true;
return RuntimeEnabledFeatures::TimerThrottlingForHiddenFramesEnabled() &&
- !frame_visible_ && IsCrossOrigin();
+ !frame_visible_ && IsCrossOriginToMainFrame();
}
void FrameSchedulerImpl::UpdateTaskQueueThrottling(
@@ -938,16 +882,12 @@ TaskQueue::QueuePriority FrameSchedulerImpl::ComputePriority(
// and add a range of new priorities less than low.
if (task_queue->web_scheduling_priority()) {
switch (task_queue->web_scheduling_priority().value()) {
- case WebSchedulingPriority::kImmediatePriority:
- return TaskQueue::QueuePriority::kHighestPriority;
- case WebSchedulingPriority::kHighPriority:
+ case WebSchedulingPriority::kUserBlockingPriority:
return TaskQueue::QueuePriority::kHighPriority;
- case WebSchedulingPriority::kDefaultPriority:
+ case WebSchedulingPriority::kUserVisiblePriority:
return TaskQueue::QueuePriority::kNormalPriority;
- case WebSchedulingPriority::kLowPriority:
+ case WebSchedulingPriority::kBackgroundPriority:
return TaskQueue::QueuePriority::kLowPriority;
- case WebSchedulingPriority::kIdlePriority:
- return TaskQueue::QueuePriority::kBestEffortPriority;
}
}
@@ -1022,7 +962,7 @@ TaskQueue::QueuePriority FrameSchedulerImpl::ComputePriority(
}
// Frame origin type experiment.
- if (IsCrossOrigin()) {
+ if (IsCrossOriginToMainFrame()) {
if (main_thread_scheduler_->scheduling_settings()
.low_priority_cross_origin ||
(main_thread_scheduler_->scheduling_settings()
@@ -1046,6 +986,21 @@ TaskQueue::QueuePriority FrameSchedulerImpl::ComputePriority(
return main_thread_scheduler_->compositor_priority();
}
+ if (task_queue->GetPrioritisationType() ==
+ MainThreadTaskQueue::QueueTraits::PrioritisationType::kFindInPage) {
+ return main_thread_scheduler_->find_in_page_priority();
+ }
+
+ if (task_queue->GetPrioritisationType() ==
+ MainThreadTaskQueue::QueueTraits::PrioritisationType::
+ kExperimentalDatabase) {
+ // TODO(shaseley): This decision should probably be based on Agent
+ // visibility. Consider changing this before shipping anything.
+ return parent_page_scheduler_->IsPageVisible()
+ ? TaskQueue::QueuePriority::kHighPriority
+ : TaskQueue::QueuePriority::kNormalPriority;
+ }
+
return TaskQueue::QueuePriority::kNormalPriority;
}
@@ -1242,5 +1197,10 @@ FrameSchedulerImpl::LoadingControlTaskQueueTraits() {
QueueTraits::PrioritisationType::kLoadingControl);
}
+MainThreadTaskQueue::QueueTraits
+FrameSchedulerImpl::FindInPageTaskQueueTraits() {
+ return PausableTaskQueueTraits().SetPrioritisationType(
+ QueueTraits::PrioritisationType::kFindInPage);
+}
} // namespace scheduler
} // namespace blink
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 860cd684172..cb6d72cf306 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
@@ -93,8 +93,8 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
void SetPaused(bool frame_paused) override;
void SetShouldReportPostedTasksWhenDisabled(bool should_report) override;
- void SetCrossOrigin(bool cross_origin) override;
- bool IsCrossOrigin() const override;
+ void SetCrossOriginToMainFrame(bool cross_origin) override;
+ bool IsCrossOriginToMainFrame() const override;
void SetIsAdFrame() override;
bool IsAdFrame() const override;
@@ -160,16 +160,6 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
MainThreadTaskQueue*,
base::sequence_manager::TaskQueue::QueueEnabledVoter*) override;
- using FrameTaskTypeToQueueTraitsArray =
- std::array<base::Optional<MainThreadTaskQueue::QueueTraits>,
- static_cast<size_t>(TaskType::kCount)>;
-
- // Initializes the mapping from TaskType to QueueTraits for frame-level tasks.
- // We control the policy and initialize this, but the map is stored with main
- // thread scheduling settings to avoid redundancy.
- static void InitializeTaskTypeQueueTraitsMap(
- FrameTaskTypeToQueueTraitsArray&);
-
// Returns the list of active features which currently tracked by the
// scheduler for back-forward cache metrics.
WTF::HashSet<SchedulingPolicy::Feature>
@@ -269,8 +259,8 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
// Create the QueueTraits for a specific TaskType. This returns base::nullopt
// for loading tasks and non-frame-level tasks.
- static base::Optional<MainThreadTaskQueue::QueueTraits>
- CreateQueueTraitsForTaskType(TaskType);
+ static MainThreadTaskQueue::QueueTraits CreateQueueTraitsForTaskType(
+ TaskType);
// Reset the state which should not persist across navigations.
void ResetForNavigation();
@@ -294,6 +284,7 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
DoesNotUseVirtualTimeTaskQueueTraits();
static MainThreadTaskQueue::QueueTraits LoadingTaskQueueTraits();
static MainThreadTaskQueue::QueueTraits LoadingControlTaskQueueTraits();
+ static MainThreadTaskQueue::QueueTraits FindInPageTaskQueueTraits();
const FrameScheduler::FrameType frame_type_;
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 43efd83327e..6411d32f558 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
@@ -40,6 +40,11 @@ namespace scheduler {
namespace frame_scheduler_impl_unittest {
using FeatureHandle = FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle;
+using PrioritisationType = MainThreadTaskQueue::QueueTraits::PrioritisationType;
+
+void AppendToVectorTestTask(Vector<String>* vector, String value) {
+ vector->push_back(std::move(value));
+}
class FrameSchedulerDelegateForTesting : public FrameScheduler::Delegate {
public:
@@ -126,6 +131,49 @@ class FrameSchedulerImplTest : public testing::Test {
UseCase::kLoading);
}
+ // Helper for posting several tasks of specific prioritisation types for
+ // testing the relative order of tasks. |task_descriptor| is a string with
+ // space delimited task identifiers. The first letter of each task identifier
+ // specifies the prioritisation type:
+ // - 'R': Regular (normal priority)
+ // - 'V': Very high
+ // - 'B': Best-effort
+ // - 'D': Database
+ void PostTestTasksForPrioritisationType(Vector<String>* run_order,
+ const String& task_descriptor) {
+ std::istringstream stream(task_descriptor.Utf8());
+ PrioritisationType prioritisation_type;
+ while (!stream.eof()) {
+ std::string task;
+ stream >> task;
+ switch (task[0]) {
+ case 'R':
+ prioritisation_type = PrioritisationType::kRegular;
+ break;
+ case 'V':
+ prioritisation_type = PrioritisationType::kVeryHigh;
+ break;
+ case 'B':
+ prioritisation_type = PrioritisationType::kBestEffort;
+ break;
+ case 'D':
+ prioritisation_type = PrioritisationType::kExperimentalDatabase;
+ break;
+ default:
+ EXPECT_FALSE(true);
+ return;
+ }
+ auto queue_traits =
+ FrameSchedulerImpl::PausableTaskQueueTraits().SetPrioritisationType(
+ prioritisation_type);
+ GetTaskQueue(queue_traits)
+ ->task_runner()
+ ->PostTask(FROM_HERE,
+ base::BindOnce(&AppendToVectorTestTask, run_order,
+ String::FromUTF8(task)));
+ }
+ }
+
static void ResetForNavigation(FrameSchedulerImpl* frame_scheduler) {
frame_scheduler->ResetForNavigation();
}
@@ -306,19 +354,10 @@ void IncrementCounter(int* counter) {
++*counter;
}
-void ExpectAndIncrementCounter(int expected, int* actual) {
- EXPECT_EQ(expected, *actual);
- IncrementCounter(actual);
-}
-
void RecordQueueName(String name, Vector<String>* tasks) {
tasks->push_back(std::move(name));
}
-void AppendToVectorTestTask(Vector<String>* vector, String value) {
- vector->push_back(std::move(value));
-}
-
// Simulate running a task of a particular length by fast forwarding the task
// environment clock, which is used to determine the wall time of a task.
void RunTaskOfLength(base::test::TaskEnvironment* task_environment,
@@ -374,10 +413,10 @@ TEST_F(FrameSchedulerImplTest,
LazyInitThrottleableTaskQueue();
EXPECT_FALSE(IsThrottled());
frame_scheduler_->SetFrameVisible(false);
- frame_scheduler_->SetCrossOrigin(true);
- frame_scheduler_->SetCrossOrigin(false);
+ frame_scheduler_->SetCrossOriginToMainFrame(true);
+ frame_scheduler_->SetCrossOriginToMainFrame(false);
EXPECT_FALSE(IsThrottled());
- frame_scheduler_->SetCrossOrigin(true);
+ frame_scheduler_->SetCrossOriginToMainFrame(true);
EXPECT_TRUE(IsThrottled());
frame_scheduler_->SetFrameVisible(true);
EXPECT_FALSE(IsThrottled());
@@ -388,7 +427,7 @@ TEST_F(FrameSchedulerImplTest,
TEST_F(FrameSchedulerImplTest, FrameHidden_CrossOrigin_LazyInit) {
ScopedTimerThrottlingForHiddenFramesForTest throttle_hidden_frames(true);
frame_scheduler_->SetFrameVisible(false);
- frame_scheduler_->SetCrossOrigin(true);
+ frame_scheduler_->SetCrossOriginToMainFrame(true);
LazyInitThrottleableTaskQueue();
EXPECT_TRUE(IsThrottled());
}
@@ -399,14 +438,14 @@ TEST_F(FrameSchedulerImplTest,
LazyInitThrottleableTaskQueue();
EXPECT_FALSE(IsThrottled());
frame_scheduler_->SetFrameVisible(false);
- frame_scheduler_->SetCrossOrigin(true);
+ frame_scheduler_->SetCrossOriginToMainFrame(true);
EXPECT_FALSE(IsThrottled());
}
TEST_F(FrameSchedulerImplTest, FrameHidden_CrossOrigin_NoThrottling_LazyInit) {
ScopedTimerThrottlingForHiddenFramesForTest throttle_hidden_frames(false);
frame_scheduler_->SetFrameVisible(false);
- frame_scheduler_->SetCrossOrigin(true);
+ frame_scheduler_->SetCrossOriginToMainFrame(true);
LazyInitThrottleableTaskQueue();
EXPECT_FALSE(IsThrottled());
}
@@ -433,14 +472,14 @@ TEST_F(FrameSchedulerImplTest, FrameVisible_CrossOrigin_ExplicitInit) {
EXPECT_TRUE(throttleable_task_queue());
frame_scheduler_->SetFrameVisible(true);
EXPECT_FALSE(IsThrottled());
- frame_scheduler_->SetCrossOrigin(true);
+ frame_scheduler_->SetCrossOriginToMainFrame(true);
EXPECT_FALSE(IsThrottled());
}
TEST_F(FrameSchedulerImplTest, FrameVisible_CrossOrigin_LazyInit) {
ScopedTimerThrottlingForHiddenFramesForTest throttle_hidden_frames(true);
frame_scheduler_->SetFrameVisible(true);
- frame_scheduler_->SetCrossOrigin(true);
+ frame_scheduler_->SetCrossOriginToMainFrame(true);
LazyInitThrottleableTaskQueue();
EXPECT_FALSE(IsThrottled());
}
@@ -1678,7 +1717,7 @@ class LowPriorityCrossOriginTaskExperimentTest : public FrameSchedulerImplTest {
};
TEST_F(LowPriorityCrossOriginTaskExperimentTest, FrameQueuesPriorities) {
- EXPECT_FALSE(frame_scheduler_->IsCrossOrigin());
+ EXPECT_FALSE(frame_scheduler_->IsCrossOriginToMainFrame());
// Same Origin Task Queues.
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
@@ -1694,8 +1733,8 @@ TEST_F(LowPriorityCrossOriginTaskExperimentTest, FrameQueuesPriorities) {
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
- frame_scheduler_->SetCrossOrigin(true);
- EXPECT_TRUE(frame_scheduler_->IsCrossOrigin());
+ frame_scheduler_->SetCrossOriginToMainFrame(true);
+ EXPECT_TRUE(frame_scheduler_->IsCrossOriginToMainFrame());
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
@@ -1737,8 +1776,8 @@ TEST_F(LowPriorityCrossOriginTaskDuringLoadingExperimentTest,
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
- frame_scheduler_->SetCrossOrigin(true);
- EXPECT_TRUE(frame_scheduler_->IsCrossOrigin());
+ frame_scheduler_->SetCrossOriginToMainFrame(true);
+ EXPECT_TRUE(frame_scheduler_->IsCrossOriginToMainFrame());
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
@@ -1787,191 +1826,6 @@ TEST_F(FrameSchedulerImplTest, TaskTypeToTaskQueueMapping) {
ForegroundOnlyTaskQueue());
}
-class ThrottleAndFreezeTaskTypesExperimentTest : public FrameSchedulerImplTest {
- public:
- ThrottleAndFreezeTaskTypesExperimentTest(const base::FieldTrialParams& params,
- const char* group_name) {
- scoped_feature_list().InitAndEnableFeatureWithParameters(
- kThrottleAndFreezeTaskTypes, params);
- }
-};
-
-class ThrottleableAndFreezableTaskTypesTest
- : public ThrottleAndFreezeTaskTypesExperimentTest {
- public:
- ThrottleableAndFreezableTaskTypesTest()
- : ThrottleAndFreezeTaskTypesExperimentTest(
- base::FieldTrialParams{
- // Leading spaces are allowed.
- {kThrottleableTaskTypesListParam, "PostedMessage"},
- {kFreezableTaskTypesListParam,
- "PostedMessage, MediaElementEvent,DOMManipulation"}},
- "Group1") {}
-};
-
-TEST_F(ThrottleableAndFreezableTaskTypesTest, QueueTraitsFromFieldTrialParams) {
- if (base::FeatureList::IsEnabled(blink::features::kStopNonTimersInBackground))
- return;
- // These tests will start to fail if the default task queues or queue traits
- // change for these task types.
-
- // Check that the overrides work.
- auto task_queue = GetTaskQueue(TaskType::kPostedMessage);
- EXPECT_EQ(task_queue->GetQueueTraits(),
- MainThreadTaskQueue::QueueTraits()
- .SetCanBeThrottled(true)
- .SetCanBeFrozen(true)
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(false));
-
- task_queue = GetTaskQueue(TaskType::kMediaElementEvent);
- EXPECT_EQ(task_queue->GetQueueTraits(),
- MainThreadTaskQueue::QueueTraits()
- .SetCanBeFrozen(true)
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(false));
-
- task_queue = GetTaskQueue(TaskType::kDatabaseAccess);
- EXPECT_EQ(task_queue->GetQueueTraits(),
- MainThreadTaskQueue::QueueTraits()
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(false));
-
- task_queue = GetTaskQueue(TaskType::kDOMManipulation);
- EXPECT_EQ(task_queue->GetQueueTraits(),
- MainThreadTaskQueue::QueueTraits()
- .SetCanBeFrozen(true)
- .SetCanBeDeferred(true)
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(false));
-
- // Test some task types that were not configured through field trial
- // parameters.
- task_queue = GetTaskQueue(TaskType::kWebLocks);
- EXPECT_EQ(
- task_queue->GetQueueTraits(),
- MainThreadTaskQueue::QueueTraits().SetCanRunWhenVirtualTimePaused(false));
-
- task_queue = GetTaskQueue(TaskType::kMiscPlatformAPI);
- EXPECT_EQ(task_queue->GetQueueTraits(),
- MainThreadTaskQueue::QueueTraits()
- .SetCanBeDeferred(true)
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(false));
-}
-
-
-class FreezableOnlyTaskTypesTest
- : public ThrottleAndFreezeTaskTypesExperimentTest {
- public:
- FreezableOnlyTaskTypesTest()
- : ThrottleAndFreezeTaskTypesExperimentTest(
- base::FieldTrialParams{
- {kThrottleableTaskTypesListParam, ""},
- {kFreezableTaskTypesListParam,
- "PostedMessage,MediaElementEvent,DOMManipulation"}},
- "Group2") {}
-};
-
-TEST_F(FreezableOnlyTaskTypesTest, QueueTraitsFromFieldTrialParams) {
- if (base::FeatureList::IsEnabled(blink::features::kStopNonTimersInBackground))
- return;
-
- // These tests will start to fail if the default task queues or queue traits
- // change for these task types.
-
- // Check that the overrides work.
- auto task_queue = GetTaskQueue(TaskType::kPostedMessage);
- EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits()
- .SetCanBeFrozen(true)
- .SetCanBePaused(true));
-
- task_queue = GetTaskQueue(TaskType::kMediaElementEvent);
- EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits()
- .SetCanBeFrozen(true)
- .SetCanBePaused(true));
-
- task_queue = GetTaskQueue(TaskType::kDatabaseAccess);
- EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits()
- .SetCanBePaused(true));
-
- task_queue = GetTaskQueue(TaskType::kDOMManipulation);
- EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits()
- .SetCanBeFrozen(true)
- .SetCanBeDeferred(true)
- .SetCanBePaused(true));
-
- // Test some task types that were not configured through field trial
- // parameters.
- task_queue = GetTaskQueue(TaskType::kWebLocks);
- EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits());
-
- task_queue = GetTaskQueue(TaskType::kMiscPlatformAPI);
- EXPECT_EQ(task_queue->GetQueueTraits(), MainThreadTaskQueue::QueueTraits()
- .SetCanBeDeferred(true)
- .SetCanBePaused(true));
-}
-
-class ThrottleableOnlyTaskTypesTest
- : public ThrottleAndFreezeTaskTypesExperimentTest {
- public:
- ThrottleableOnlyTaskTypesTest()
- : ThrottleAndFreezeTaskTypesExperimentTest(
- base::FieldTrialParams{
- {kFreezableTaskTypesListParam, ""},
- {kThrottleableTaskTypesListParam, "PostedMessage"}},
- "Group3") {}
-};
-
-TEST_F(ThrottleableOnlyTaskTypesTest, QueueTraitsFromFieldTrialParams) {
- if (base::FeatureList::IsEnabled(blink::features::kStopNonTimersInBackground))
- return;
-
- // These tests will start to fail if the default task queues or queue traits
- // change for these task types.
-
- // Check that the overrides work.
- auto task_queue = GetTaskQueue(TaskType::kPostedMessage);
- EXPECT_EQ(task_queue->GetQueueTraits(),
- MainThreadTaskQueue::QueueTraits()
- .SetCanBeThrottled(true)
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(false));
-
- task_queue = GetTaskQueue(TaskType::kMediaElementEvent);
- EXPECT_EQ(task_queue->GetQueueTraits(),
- MainThreadTaskQueue::QueueTraits()
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(false));
-
- task_queue = GetTaskQueue(TaskType::kDatabaseAccess);
- EXPECT_EQ(task_queue->GetQueueTraits(),
- MainThreadTaskQueue::QueueTraits()
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(false));
-
- task_queue = GetTaskQueue(TaskType::kDOMManipulation);
- EXPECT_EQ(task_queue->GetQueueTraits(),
- MainThreadTaskQueue::QueueTraits()
- .SetCanBeDeferred(true)
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(false));
-
- // Test some task types that were not configured through field trial
- // parameters.
- task_queue = GetTaskQueue(TaskType::kWebLocks);
- EXPECT_EQ(
- task_queue->GetQueueTraits(),
- MainThreadTaskQueue::QueueTraits().SetCanRunWhenVirtualTimePaused(false));
-
- task_queue = GetTaskQueue(TaskType::kMiscPlatformAPI);
- EXPECT_EQ(task_queue->GetQueueTraits(),
- MainThreadTaskQueue::QueueTraits()
- .SetCanBeDeferred(true)
- .SetCanBePaused(true)
- .SetCanRunWhenVirtualTimePaused(false));
-}
-
class FrameSchedulerImplDatabaseAccessWithoutHighPriority
: public FrameSchedulerImplTest {
public:
@@ -1980,37 +1834,11 @@ class FrameSchedulerImplDatabaseAccessWithoutHighPriority
};
TEST_F(FrameSchedulerImplDatabaseAccessWithoutHighPriority, QueueTraits) {
- // These tests will start to fail if the default task queues or queue traits
- // change for these task types.
-
- int counter = 0;
-
- auto loading_queue = GetTaskQueue(TaskType::kInternalContinueScriptLoading);
- EXPECT_EQ(loading_queue->GetQueuePriority(),
- TaskQueue::QueuePriority::kVeryHighPriority);
- loading_queue->task_runner()->PostTask(
- FROM_HERE, base::BindOnce(&ExpectAndIncrementCounter, 0,
- base::Unretained(&counter)));
-
auto da_queue = GetTaskQueue(TaskType::kDatabaseAccess);
EXPECT_EQ(da_queue->GetQueueTraits().prioritisation_type,
MainThreadTaskQueue::QueueTraits::PrioritisationType::kRegular);
EXPECT_EQ(da_queue->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
- da_queue->task_runner()->PostTask(
- FROM_HERE, base::BindOnce(&ExpectAndIncrementCounter, 1,
- base::Unretained(&counter)));
-
- auto content_queue = GetTaskQueue(TaskType::kInternalContentCapture);
- EXPECT_EQ(content_queue->GetQueuePriority(),
- TaskQueue::QueuePriority::kBestEffortPriority);
- content_queue->task_runner()->PostTask(
- FROM_HERE, base::BindOnce(&ExpectAndIncrementCounter, 2,
- base::Unretained(&counter)));
-
- EXPECT_EQ(0, counter);
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(3, counter);
}
class FrameSchedulerImplDatabaseAccessWithHighPriority
@@ -2021,37 +1849,31 @@ class FrameSchedulerImplDatabaseAccessWithHighPriority
};
TEST_F(FrameSchedulerImplDatabaseAccessWithHighPriority, QueueTraits) {
- // These tests will start to fail if the default task queues or queue traits
- // change for these task types.
-
- int counter = 0;
-
- auto loading_queue = GetTaskQueue(TaskType::kInternalContinueScriptLoading);
- EXPECT_EQ(loading_queue->GetQueuePriority(),
- TaskQueue::QueuePriority::kVeryHighPriority);
- loading_queue->task_runner()->PostTask(
- FROM_HERE, base::BindOnce(&ExpectAndIncrementCounter, 0,
- base::Unretained(&counter)));
-
auto da_queue = GetTaskQueue(TaskType::kDatabaseAccess);
EXPECT_EQ(da_queue->GetQueueTraits().prioritisation_type,
- MainThreadTaskQueue::QueueTraits::PrioritisationType::kHigh);
+ MainThreadTaskQueue::QueueTraits::PrioritisationType::
+ kExperimentalDatabase);
EXPECT_EQ(da_queue->GetQueuePriority(),
TaskQueue::QueuePriority::kHighPriority);
- da_queue->task_runner()->PostTask(
- FROM_HERE, base::BindOnce(&ExpectAndIncrementCounter, 1,
- base::Unretained(&counter)));
+}
- auto pausable_queue = PausableTaskQueue();
- EXPECT_EQ(pausable_queue->GetQueuePriority(),
- TaskQueue::QueuePriority::kNormalPriority);
- pausable_queue->task_runner()->PostTask(
- FROM_HERE, base::BindOnce(&ExpectAndIncrementCounter, 2,
- base::Unretained(&counter)));
+TEST_F(FrameSchedulerImplDatabaseAccessWithHighPriority, RunOrder) {
+ Vector<String> run_order;
+ PostTestTasksForPrioritisationType(&run_order, "D1 R1 D2 V1 B1");
- EXPECT_EQ(0, counter);
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(3, counter);
+ EXPECT_THAT(run_order, testing::ElementsAre("V1", "D1", "D2", "R1", "B1"));
+}
+
+TEST_F(FrameSchedulerImplDatabaseAccessWithHighPriority,
+ NormalPriorityInBackground) {
+ page_scheduler_->SetPageVisible(false);
+
+ Vector<String> run_order;
+ PostTestTasksForPrioritisationType(&run_order, "D1 R1 D2 V1 B1");
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_THAT(run_order, testing::ElementsAre("V1", "D1", "R1", "D2", "B1"));
}
TEST_F(FrameSchedulerImplTest, ContentCaptureHasIdleTaskQueue) {
@@ -2314,11 +2136,9 @@ class WebSchedulingTaskQueueTest : public FrameSchedulerImplTest {
// Helper for posting tasks to a WebSchedulingTaskQueue. |task_descriptor| is
// a string with space delimited task identifiers. The first letter of each
// task identifier specifies the task queue priority:
- // - 'I': Immediate
- // - 'H': High
- // - 'D': Default
- // - 'L': Low
- // - 'E': Idle
+ // - 'U': UserBlocking
+ // - 'V': UserVisible
+ // - 'B': Background
void PostWebSchedulingTestTasks(Vector<String>* run_order,
const String& task_descriptor) {
std::istringstream stream(task_descriptor.Utf8());
@@ -2327,20 +2147,14 @@ class WebSchedulingTaskQueueTest : public FrameSchedulerImplTest {
stream >> task;
WebSchedulingPriority priority;
switch (task[0]) {
- case 'I':
- priority = WebSchedulingPriority::kImmediatePriority;
- break;
- case 'H':
- priority = WebSchedulingPriority::kHighPriority;
+ case 'U':
+ priority = WebSchedulingPriority::kUserBlockingPriority;
break;
- case 'D':
- priority = WebSchedulingPriority::kDefaultPriority;
+ case 'V':
+ priority = WebSchedulingPriority::kUserVisiblePriority;
break;
- case 'L':
- priority = WebSchedulingPriority::kLowPriority;
- break;
- case 'E':
- priority = WebSchedulingPriority::kIdlePriority;
+ case 'B':
+ priority = WebSchedulingPriority::kBackgroundPriority;
break;
default:
EXPECT_FALSE(true);
@@ -2361,23 +2175,23 @@ class WebSchedulingTaskQueueTest : public FrameSchedulerImplTest {
TEST_F(WebSchedulingTaskQueueTest, TasksRunInPriorityOrder) {
Vector<String> run_order;
- PostWebSchedulingTestTasks(&run_order, "E1 E2 L1 L2 D1 D2 H1 H2 I1 I2");
+ PostWebSchedulingTestTasks(&run_order, "B1 B2 V1 V2 U1 U2");
base::RunLoop().RunUntilIdle();
- EXPECT_THAT(run_order, testing::ElementsAre("I1", "I2", "H1", "H2", "D1",
- "D2", "L1", "L2", "E1", "E2"));
+ EXPECT_THAT(run_order,
+ testing::ElementsAre("U1", "U2", "V1", "V2", "B1", "B2"));
}
TEST_F(WebSchedulingTaskQueueTest, DynamicTaskPriorityOrder) {
Vector<String> run_order;
- PostWebSchedulingTestTasks(&run_order, "E1 E2 D1 D2 I1 I2");
- task_queues_[static_cast<int>(WebSchedulingPriority::kImmediatePriority)]
- ->SetPriority(WebSchedulingPriority::kLowPriority);
+ PostWebSchedulingTestTasks(&run_order, "B1 B2 V1 V2 U1 U2");
+ task_queues_[static_cast<int>(WebSchedulingPriority::kUserBlockingPriority)]
+ ->SetPriority(WebSchedulingPriority::kBackgroundPriority);
base::RunLoop().RunUntilIdle();
EXPECT_THAT(run_order,
- testing::ElementsAre("D1", "D2", "I1", "I2", "E1", "E2"));
+ testing::ElementsAre("V1", "V2", "B1", "B2", "U1", "U2"));
}
} // namespace frame_scheduler_impl_unittest
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_status.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_status.cc
index cfda104e005..d8a1c929c2b 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_status.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_status.cc
@@ -26,9 +26,10 @@ enum class FrameThrottlingState {
enum class FrameOriginState {
kMainFrame = 0,
- kSameOrigin = 1,
- kCrossOrigin = 2,
+ kSameOriginToMainFrame = 1,
+ kCrossOriginToMainFrame = 2,
+ // TODO(dcheng): get rid of kCount here.
kCount = 3
};
@@ -60,9 +61,9 @@ FrameOriginState GetFrameOriginState(const FrameScheduler& frame_scheduler) {
if (frame_scheduler.GetFrameType() == FrameScheduler::FrameType::kMainFrame) {
return FrameOriginState::kMainFrame;
}
- if (frame_scheduler.IsCrossOrigin())
- return FrameOriginState::kCrossOrigin;
- return FrameOriginState::kSameOrigin;
+ if (frame_scheduler.IsCrossOriginToMainFrame())
+ return FrameOriginState::kCrossOriginToMainFrame;
+ return FrameOriginState::kSameOriginToMainFrame;
}
} // namespace
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.cc
index 710f3d595b9..362b0e1b5f1 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.cc
@@ -107,10 +107,6 @@ void FrameTaskQueueController::CreateTaskQueue(
queue_creation_params = queue_creation_params.SetFixedPriority(
TaskQueue::QueuePriority::kVeryHighPriority);
break;
- case QueueTraits::PrioritisationType::kHigh:
- queue_creation_params = queue_creation_params.SetFixedPriority(
- TaskQueue::QueuePriority::kHighPriority);
- break;
case QueueTraits::PrioritisationType::kBestEffort:
queue_creation_params = queue_creation_params.SetFixedPriority(
TaskQueue::QueuePriority::kBestEffortPriority);
@@ -179,7 +175,7 @@ bool FrameTaskQueueController::RemoveResourceLoadingTaskQueue(
void FrameTaskQueueController::AsValueInto(
base::trace_event::TracedValue* state) const {
state->BeginArray("task_queues");
- for (const auto it : task_queues_) {
+ for (const auto& it : task_queues_) {
state->AppendString(PointerToString(it.value.get()));
}
state->EndArray();
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 18f4199534c..28f6af4d89a 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
@@ -260,38 +260,24 @@ TEST_F(FrameTaskQueueControllerTest,
TEST_F(FrameTaskQueueControllerTest, AddWebSchedulingTaskQueues) {
scoped_refptr<MainThreadTaskQueue> task_queue =
frame_task_queue_controller_->NewWebSchedulingTaskQueue(
- QueueTraits(), WebSchedulingPriority::kImmediatePriority);
+ QueueTraits(), WebSchedulingPriority::kUserBlockingPriority);
EXPECT_EQ(1u,
frame_task_queue_controller_->GetAllTaskQueuesAndVoters().size());
- EXPECT_EQ(WebSchedulingPriority::kImmediatePriority,
+ EXPECT_EQ(WebSchedulingPriority::kUserBlockingPriority,
task_queue->web_scheduling_priority().value());
task_queue = frame_task_queue_controller_->NewWebSchedulingTaskQueue(
- QueueTraits(), WebSchedulingPriority::kHighPriority);
+ QueueTraits(), WebSchedulingPriority::kUserVisiblePriority);
EXPECT_EQ(2u,
frame_task_queue_controller_->GetAllTaskQueuesAndVoters().size());
- EXPECT_EQ(WebSchedulingPriority::kHighPriority,
+ EXPECT_EQ(WebSchedulingPriority::kUserVisiblePriority,
task_queue->web_scheduling_priority().value());
task_queue = frame_task_queue_controller_->NewWebSchedulingTaskQueue(
- QueueTraits(), WebSchedulingPriority::kDefaultPriority);
+ QueueTraits(), WebSchedulingPriority::kBackgroundPriority);
EXPECT_EQ(3u,
frame_task_queue_controller_->GetAllTaskQueuesAndVoters().size());
- EXPECT_EQ(WebSchedulingPriority::kDefaultPriority,
- task_queue->web_scheduling_priority().value());
-
- task_queue = frame_task_queue_controller_->NewWebSchedulingTaskQueue(
- QueueTraits(), WebSchedulingPriority::kLowPriority);
- EXPECT_EQ(4u,
- frame_task_queue_controller_->GetAllTaskQueuesAndVoters().size());
- EXPECT_EQ(WebSchedulingPriority::kLowPriority,
- task_queue->web_scheduling_priority().value());
-
- task_queue = frame_task_queue_controller_->NewWebSchedulingTaskQueue(
- QueueTraits(), WebSchedulingPriority::kIdlePriority);
- EXPECT_EQ(5u,
- frame_task_queue_controller_->GetAllTaskQueuesAndVoters().size());
- EXPECT_EQ(WebSchedulingPriority::kIdlePriority,
+ EXPECT_EQ(WebSchedulingPriority::kBackgroundPriority,
task_queue->web_scheduling_priority().value());
}
@@ -299,18 +285,18 @@ TEST_F(FrameTaskQueueControllerTest,
AddMultipleSamePriorityWebSchedulingTaskQueues) {
scoped_refptr<MainThreadTaskQueue> task_queue1 =
frame_task_queue_controller_->NewWebSchedulingTaskQueue(
- QueueTraits(), WebSchedulingPriority::kImmediatePriority);
+ QueueTraits(), WebSchedulingPriority::kUserBlockingPriority);
EXPECT_EQ(1u,
frame_task_queue_controller_->GetAllTaskQueuesAndVoters().size());
- EXPECT_EQ(WebSchedulingPriority::kImmediatePriority,
+ EXPECT_EQ(WebSchedulingPriority::kUserBlockingPriority,
task_queue1->web_scheduling_priority().value());
scoped_refptr<MainThreadTaskQueue> task_queue2 =
frame_task_queue_controller_->NewWebSchedulingTaskQueue(
- QueueTraits(), WebSchedulingPriority::kImmediatePriority);
+ QueueTraits(), WebSchedulingPriority::kUserBlockingPriority);
EXPECT_EQ(2u,
frame_task_queue_controller_->GetAllTaskQueuesAndVoters().size());
- EXPECT_EQ(WebSchedulingPriority::kImmediatePriority,
+ EXPECT_EQ(WebSchedulingPriority::kUserBlockingPriority,
task_queue2->web_scheduling_priority().value());
EXPECT_NE(task_queue1.get(), task_queue2.get());
@@ -338,11 +324,12 @@ INSTANTIATE_TEST_SUITE_P(
All,
TaskQueueCreationFromQueueTraitsTest,
::testing::Values(QueueTraits::PrioritisationType::kVeryHigh,
- QueueTraits::PrioritisationType::kHigh,
QueueTraits::PrioritisationType::kBestEffort,
QueueTraits::PrioritisationType::kRegular,
QueueTraits::PrioritisationType::kLoading,
- QueueTraits::PrioritisationType::kLoadingControl));
+ QueueTraits::PrioritisationType::kLoadingControl,
+ QueueTraits::PrioritisationType::kFindInPage,
+ QueueTraits::PrioritisationType::kExperimentalDatabase));
TEST_P(TaskQueueCreationFromQueueTraitsTest,
AddAndRetrieveAllTaskQueues) {
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper_unittest.cc
index 2adac49f386..9b7e85a92b6 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper_unittest.cc
@@ -191,38 +191,38 @@ class MainThreadMetricsHelperTest : public testing::Test {
break;
case FrameStatus::kCrossOriginVisible:
builder.SetFrameType(FrameScheduler::FrameType::kSubframe)
- .SetIsCrossOrigin(true)
+ .SetIsCrossOriginToMainFrame(true)
.SetIsPageVisible(true)
.SetIsFrameVisible(true);
break;
case FrameStatus::kCrossOriginVisibleService:
builder.SetFrameType(FrameScheduler::FrameType::kSubframe)
- .SetIsCrossOrigin(true)
+ .SetIsCrossOriginToMainFrame(true)
.SetPageScheduler(playing_view_.get())
.SetIsFrameVisible(true);
break;
case FrameStatus::kCrossOriginHidden:
builder.SetFrameType(FrameScheduler::FrameType::kSubframe)
- .SetIsCrossOrigin(true)
+ .SetIsCrossOriginToMainFrame(true)
.SetIsPageVisible(true);
break;
case FrameStatus::kCrossOriginHiddenService:
builder.SetFrameType(FrameScheduler::FrameType::kSubframe)
- .SetIsCrossOrigin(true)
+ .SetIsCrossOriginToMainFrame(true)
.SetPageScheduler(playing_view_.get());
break;
case FrameStatus::kCrossOriginBackground:
builder.SetFrameType(FrameScheduler::FrameType::kSubframe)
- .SetIsCrossOrigin(true);
+ .SetIsCrossOriginToMainFrame(true);
break;
case FrameStatus::kCrossOriginBackgroundExemptSelf:
builder.SetFrameType(FrameScheduler::FrameType::kSubframe)
- .SetIsCrossOrigin(true)
+ .SetIsCrossOriginToMainFrame(true)
.SetIsExemptFromThrottling(true);
break;
case FrameStatus::kCrossOriginBackgroundExemptOther:
builder.SetFrameType(FrameScheduler::FrameType::kSubframe)
- .SetIsCrossOrigin(true)
+ .SetIsCrossOriginToMainFrame(true)
.SetPageScheduler(throtting_exempt_view_.get());
break;
case FrameStatus::kCount:
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 1c1a13067ab..9bf6ae8538a 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
@@ -22,10 +22,11 @@
#include "build/build_config.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "services/metrics/public/cpp/ukm_builders.h"
+#include "third_party/blink/public/common/input/web_input_event_attribution.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"
#include "third_party/blink/public/platform/scheduler/web_renderer_process_type.h"
-#include "third_party/blink/public/platform/web_mouse_wheel_event.h"
-#include "third_party/blink/public/platform/web_touch_event.h"
#include "third_party/blink/renderer/platform/bindings/parkable_string_manager.h"
#include "third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -37,6 +38,7 @@
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h"
#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 "v8/include/v8.h"
@@ -201,24 +203,15 @@ MainThreadSchedulerImpl::MainThreadSchedulerImpl(
.SetFixedPriority(
TaskQueue::QueuePriority::kBestEffortPriority))),
render_widget_scheduler_signals_(this),
+ find_in_page_budget_pool_controller_(
+ new FindInPageBudgetPoolController(this)),
control_task_queue_(helper_.ControlMainThreadTaskQueue()),
compositor_task_queue_(
helper_.NewTaskQueue(MainThreadTaskQueue::QueueCreationParams(
MainThreadTaskQueue::QueueType::kCompositor)
.SetShouldMonitorQuiescence(true))),
- input_task_queue_(helper_.NewTaskQueue(
- MainThreadTaskQueue::QueueCreationParams(
- MainThreadTaskQueue::QueueType::kInput)
- .SetShouldMonitorQuiescence(true)
- .SetFixedPriority(
- scheduling_settings_.high_priority_input
- ? base::make_optional(
- TaskQueue::QueuePriority::kHighestPriority)
- : base::nullopt))),
compositor_task_queue_enabled_voter_(
compositor_task_queue_->CreateQueueEnabledVoter()),
- input_task_queue_enabled_voter_(
- input_task_queue_->CreateQueueEnabledVoter()),
memory_purge_task_queue_(helper_.NewTaskQueue(
MainThreadTaskQueue::QueueCreationParams(
MainThreadTaskQueue::QueueType::kIdle)
@@ -226,6 +219,7 @@ MainThreadSchedulerImpl::MainThreadSchedulerImpl(
TaskQueue::QueuePriority::kBestEffortPriority))),
memory_purge_manager_(memory_purge_task_queue_->CreateTaskRunner(
TaskType::kMainThreadTaskQueueMemoryPurge)),
+ non_waking_time_domain_(tick_clock()),
delayed_update_policy_runner_(
base::BindRepeating(&MainThreadSchedulerImpl::UpdatePolicy,
base::Unretained(this)),
@@ -246,8 +240,8 @@ MainThreadSchedulerImpl::MainThreadSchedulerImpl(
task_runners_.emplace(helper_.DefaultMainThreadTaskQueue(), nullptr);
task_runners_.emplace(compositor_task_queue_,
compositor_task_queue_->CreateQueueEnabledVoter());
- task_runners_.emplace(input_task_queue_,
- input_task_queue_->CreateQueueEnabledVoter());
+
+ RegisterTimeDomain(&non_waking_time_domain_);
v8_task_queue_ = NewTaskQueue(MainThreadTaskQueue::QueueCreationParams(
MainThreadTaskQueue::QueueType::kV8));
@@ -255,6 +249,10 @@ MainThreadSchedulerImpl::MainThreadSchedulerImpl(
MainThreadTaskQueue::QueueType::kIPC));
cleanup_task_queue_ = NewTaskQueue(MainThreadTaskQueue::QueueCreationParams(
MainThreadTaskQueue::QueueType::kCleanup));
+ non_waking_task_queue_ =
+ NewTaskQueue(MainThreadTaskQueue::QueueCreationParams(
+ MainThreadTaskQueue::QueueType::kNonWaking)
+ .SetTimeDomain(&non_waking_time_domain_));
v8_task_runner_ =
v8_task_queue_->CreateTaskRunner(TaskType::kMainThreadTaskQueueV8);
@@ -262,12 +260,12 @@ MainThreadSchedulerImpl::MainThreadSchedulerImpl(
TaskType::kMainThreadTaskQueueCompositor);
control_task_runner_ = helper_.ControlMainThreadTaskQueue()->CreateTaskRunner(
TaskType::kMainThreadTaskQueueControl);
- input_task_runner_ =
- input_task_queue_->CreateTaskRunner(TaskType::kMainThreadTaskQueueInput);
ipc_task_runner_ =
ipc_task_queue_->CreateTaskRunner(TaskType::kMainThreadTaskQueueIPC);
cleanup_task_runner_ = cleanup_task_queue_->CreateTaskRunner(
TaskType::kMainThreadTaskQueueCleanup);
+ non_waking_task_runner_ = non_waking_task_queue_->CreateTaskRunner(
+ TaskType::kMainThreadTaskQueueNonWaking);
// TaskQueueThrottler requires some task runners, then initialize
// TaskQueueThrottler after task queues/runners are initialized.
@@ -307,6 +305,9 @@ MainThreadSchedulerImpl::MainThreadSchedulerImpl(
main_thread_only()
.compositor_priority_experiments.OnMainThreadSchedulerInitialized();
+ main_thread_only().current_policy.find_in_page_priority() =
+ find_in_page_budget_pool_controller_->CurrentTaskPriority();
+
g_main_thread_scheduler = this;
}
@@ -319,6 +320,8 @@ MainThreadSchedulerImpl::~MainThreadSchedulerImpl() {
pair.first->ShutdownTaskQueue();
}
+ UnregisterTimeDomain(&non_waking_time_domain_);
+
if (virtual_time_domain_)
UnregisterTimeDomain(virtual_time_domain_.get());
@@ -552,9 +555,6 @@ MainThreadSchedulerImpl::AnyThread::AnyThread(
&main_thread_scheduler_impl->tracing_controller_) {}
MainThreadSchedulerImpl::SchedulingSettings::SchedulingSettings() {
- high_priority_input =
- base::FeatureList::IsEnabled(kHighPriorityInputOnMainThread);
-
low_priority_background_page =
base::FeatureList::IsEnabled(kLowPriorityForBackgroundPages);
best_effort_background_page =
@@ -607,9 +607,6 @@ MainThreadSchedulerImpl::SchedulingSettings::SchedulingSettings() {
}
}
}
-
- FrameSchedulerImpl::InitializeTaskTypeQueueTraitsMap(
- frame_task_types_to_queue_traits);
}
MainThreadSchedulerImpl::AnyThread::~AnyThread() = default;
@@ -662,6 +659,11 @@ std::unique_ptr<Thread> MainThreadSchedulerImpl::CreateMainThread() {
return std::make_unique<MainThread>(this);
}
+std::unique_ptr<WebWidgetScheduler>
+MainThreadSchedulerImpl::CreateWidgetScheduler() {
+ return std::make_unique<WidgetScheduler>(this);
+}
+
scoped_refptr<base::SingleThreadTaskRunner>
MainThreadSchedulerImpl::ControlTaskRunner() {
return control_task_runner_;
@@ -672,12 +674,6 @@ MainThreadSchedulerImpl::DefaultTaskRunner() {
return helper_.DefaultTaskRunner();
}
-scoped_refptr<base::SingleThreadTaskRunner>
-MainThreadSchedulerImpl::InputTaskRunner() {
- helper_.CheckOnValidThread();
- return input_task_runner_;
-}
-
scoped_refptr<SingleThreadIdleTaskRunner>
MainThreadSchedulerImpl::IdleTaskRunner() {
return idle_helper_.IdleTaskRunner();
@@ -709,11 +705,6 @@ MainThreadSchedulerImpl::CompositorTaskQueue() {
return compositor_task_queue_;
}
-scoped_refptr<MainThreadTaskQueue> MainThreadSchedulerImpl::InputTaskQueue() {
- helper_.CheckOnValidThread();
- return input_task_queue_;
-}
-
scoped_refptr<MainThreadTaskQueue> MainThreadSchedulerImpl::V8TaskQueue() {
helper_.CheckOnValidThread();
return v8_task_queue_;
@@ -1269,13 +1260,15 @@ void MainThreadSchedulerImpl::UpdateForInputEventOnCompositorThread(
}
void MainThreadSchedulerImpl::WillPostInputEventToMainThread(
- WebInputEvent::Type web_input_event_type) {
+ WebInputEvent::Type web_input_event_type,
+ const WebInputEventAttribution& web_input_event_attribution) {
base::AutoLock lock(any_thread_lock_);
any_thread().pending_input_monitor.OnEnqueue(web_input_event_type);
}
void MainThreadSchedulerImpl::WillHandleInputEventOnMainThread(
- WebInputEvent::Type web_input_event_type) {
+ WebInputEvent::Type web_input_event_type,
+ const WebInputEventAttribution& web_input_event_attribution) {
helper_.CheckOnValidThread();
base::AutoLock lock(any_thread_lock_);
@@ -1484,7 +1477,7 @@ void MainThreadSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) {
break;
case UseCase::kNone:
- // It's only safe to block tasks that if we are expecting a compositor
+ // It's only safe to block tasks if we are expecting a compositor
// driven gesture.
if (main_thread_only().blocking_input_expected_soon &&
any_thread().last_gesture_was_compositor_driven) {
@@ -1549,6 +1542,9 @@ void MainThreadSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) {
new_policy.should_disable_throttling() = main_thread_only().use_virtual_time;
+ new_policy.find_in_page_priority() =
+ find_in_page_budget_pool_controller_->CurrentTaskPriority();
+
// Tracing is done before the early out check, because it's quite possible we
// will otherwise miss this information in traces.
CreateTraceEventObjectSnapshotLocked();
@@ -1810,6 +1806,9 @@ void MainThreadSchedulerImpl::DisableVirtualTimeForTesting() {
virtual_time_control_task_queue_ = nullptr;
ApplyVirtualTimePolicy();
+ main_thread_only().initial_virtual_time = base::Time();
+ main_thread_only().initial_virtual_time_ticks = base::TimeTicks();
+
// Reset the MetricsHelper because it gets confused by time going backwards.
base::TimeTicks now = tick_clock()->NowTicks();
main_thread_only().metrics_helper.ResetForTest(now);
@@ -1954,13 +1953,26 @@ void MainThreadSchedulerImpl::CreateTraceEventObjectSnapshotLocked() const {
std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
MainThreadSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const {
+ auto state = std::make_unique<base::trace_event::TracedValue>();
+ AsValueIntoLocked(state.get(), optional_now);
+ return std::move(state);
+}
+
+std::string MainThreadSchedulerImpl::ToString() const {
+ base::AutoLock lock(any_thread_lock_);
+ base::trace_event::TracedValueJSON value;
+ AsValueIntoLocked(&value, base::TimeTicks());
+ return value.ToJSON();
+}
+
+void MainThreadSchedulerImpl::AsValueIntoLocked(
+ base::trace_event::TracedValue* state,
+ base::TimeTicks optional_now) const {
helper_.CheckOnValidThread();
any_thread_lock_.AssertAcquired();
if (optional_now.is_null())
optional_now = helper_.NowTicks();
- std::unique_ptr<base::trace_event::TracedValue> state(
- new base::trace_event::TracedValue());
state->SetBoolean(
"has_visible_render_widget_with_touch_handler",
main_thread_only().has_visible_render_widget_with_touch_handler);
@@ -2024,13 +2036,13 @@ MainThreadSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const {
state->BeginDictionary("page_schedulers");
for (PageSchedulerImpl* page_scheduler : main_thread_only().page_schedulers) {
state->BeginDictionaryWithCopiedName(PointerToString(page_scheduler));
- page_scheduler->AsValueInto(state.get());
+ page_scheduler->AsValueInto(state);
state->EndDictionary();
}
state->EndDictionary();
state->BeginDictionary("policy");
- main_thread_only().current_policy.AsValueInto(state.get());
+ main_thread_only().current_policy.AsValueInto(state);
state->EndDictionary();
// TODO(skyostil): Can we somehow trace how accurate these estimates were?
@@ -2046,14 +2058,12 @@ MainThreadSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const {
.InMillisecondsF());
state->SetBoolean("in_idle_period", any_thread().in_idle_period);
- any_thread().user_model.AsValueInto(state.get());
- render_widget_scheduler_signals_.AsValueInto(state.get());
+ any_thread().user_model.AsValueInto(state);
+ render_widget_scheduler_signals_.AsValueInto(state);
state->BeginDictionary("task_queue_throttler");
- task_queue_throttler_->AsValueInto(state.get(), optional_now);
+ task_queue_throttler_->AsValueInto(state, optional_now);
state->EndDictionary();
-
- return std::move(state);
}
bool MainThreadSchedulerImpl::TaskQueuePolicy::IsQueueEnabled(
@@ -2090,6 +2100,8 @@ MainThreadSchedulerImpl::Policy::Policy()
should_prioritize_loading_with_compositing_(false),
compositor_priority_(
base::sequence_manager::TaskQueue::QueuePriority::kNormalPriority),
+ find_in_page_priority_(FindInPageBudgetPoolController::
+ kFindInPageBudgetNotExhaustedPriority),
use_case_(UseCase::kNone) {}
void MainThreadSchedulerImpl::Policy::AsValueInto(
@@ -2336,6 +2348,11 @@ MainThreadSchedulerImpl::CompositorTaskRunner() {
return compositor_task_runner_;
}
+scoped_refptr<base::SingleThreadTaskRunner>
+MainThreadSchedulerImpl::NonWakingTaskRunner() {
+ return non_waking_task_runner_;
+}
+
std::unique_ptr<PageScheduler> MainThreadSchedulerImpl::CreatePageScheduler(
PageScheduler::Delegate* delegate) {
return std::make_unique<PageSchedulerImpl>(delegate, this);
@@ -2482,6 +2499,9 @@ void MainThreadSchedulerImpl::OnTaskCompleted(
main_thread_only().compositor_priority_experiments.OnTaskCompleted(
queue.get(), main_thread_only().current_policy.compositor_priority(),
task_timing);
+
+ find_in_page_budget_pool_controller_->OnTaskCompleted(queue.get(),
+ task_timing);
}
void MainThreadSchedulerImpl::RecordTaskUkm(
@@ -2577,7 +2597,7 @@ TaskQueue::QueuePriority MainThreadSchedulerImpl::ComputePriority(
MainThreadTaskQueue* task_queue) const {
DCHECK(task_queue);
- // If |task_queue| is associated to a frame, the the frame scheduler computes
+ // If |task_queue| is associated to a frame, then the frame scheduler computes
// the priority.
FrameSchedulerImpl* frame_scheduler = task_queue->GetFrameScheduler();
@@ -2735,7 +2755,9 @@ bool MainThreadSchedulerImpl::ShouldUpdateTaskQueuePriorities(
return old_policy.use_case() !=
main_thread_only().current_policy.use_case() ||
old_policy.compositor_priority() !=
- main_thread_only().current_policy.compositor_priority();
+ main_thread_only().current_policy.compositor_priority() ||
+ old_policy.find_in_page_priority() !=
+ main_thread_only().current_policy.find_in_page_priority();
}
UseCase MainThreadSchedulerImpl::current_use_case() const {
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 612cd8ea852..5914b7f7175 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
@@ -32,11 +32,13 @@
#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"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/non_waking_time_domain.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/pending_user_input.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/prioritize_compositing_after_input_experiment.h"
@@ -96,9 +98,6 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
struct SchedulingSettings {
SchedulingSettings();
- // High priority input experiment.
- bool high_priority_input;
-
// Background page priority experiment (crbug.com/848835).
bool low_priority_background_page;
bool best_effort_background_page;
@@ -137,14 +136,6 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
std::array<base::sequence_manager::TaskQueue::QueuePriority,
net::RequestPrioritySize::NUM_PRIORITIES>
net_to_blink_priority;
-
- using FrameTaskTypeToQueueTraitsArray =
- std::array<base::Optional<MainThreadTaskQueue::QueueTraits>,
- static_cast<size_t>(TaskType::kCount)>;
- // Array of QueueTraits indexed by TaskType, containing TaskType::kCount
- // entries. This is initialized early with all valid entries. Entries that
- // aren't valid task types, i.e. non-frame level, are base::nullopt.
- FrameTaskTypeToQueueTraitsArray frame_task_types_to_queue_traits;
};
static const char* UseCaseToString(UseCase use_case);
@@ -170,9 +161,11 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
// WebThreadScheduler implementation:
std::unique_ptr<Thread> CreateMainThread() override;
+ std::unique_ptr<WebWidgetScheduler> CreateWidgetScheduler() override;
// Note: this is also shared by the ThreadScheduler interface.
scoped_refptr<base::SingleThreadTaskRunner> IPCTaskRunner() override;
scoped_refptr<base::SingleThreadTaskRunner> CleanupTaskRunner() override;
+ scoped_refptr<base::SingleThreadTaskRunner> NonWakingTaskRunner() override;
scoped_refptr<base::SingleThreadTaskRunner> DeprecatedDefaultTaskRunner()
override;
std::unique_ptr<WebRenderWidgetSchedulingState>
@@ -185,9 +178,11 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
const WebInputEvent& web_input_event,
InputEventState event_state) override;
void WillPostInputEventToMainThread(
- WebInputEvent::Type web_input_event_type) override;
+ WebInputEvent::Type web_input_event_type,
+ const WebInputEventAttribution& web_input_event_attribution) override;
void WillHandleInputEventOnMainThread(
- WebInputEvent::Type web_input_event_type) override;
+ WebInputEvent::Type web_input_event_type,
+ const WebInputEventAttribution& web_input_event_attribution) override;
void DidHandleInputEventOnMainThread(const WebInputEvent& web_input_event,
WebInputEventResult result) override;
void DidAnimateForInputOnCompositorThread() override;
@@ -240,7 +235,6 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
// WebThreadScheduler implementation:
scoped_refptr<base::SingleThreadTaskRunner> DefaultTaskRunner() override;
- scoped_refptr<base::SingleThreadTaskRunner> InputTaskRunner() override;
// The following functions are defined in both WebThreadScheduler and
// ThreadScheduler, and have the same function signatures -- see above.
@@ -428,11 +422,14 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
return main_thread_only().main_thread_compositing_is_fast;
}
+ QueuePriority find_in_page_priority() const {
+ return main_thread_only().current_policy.find_in_page_priority();
+ }
+
protected:
scoped_refptr<MainThreadTaskQueue> ControlTaskQueue();
scoped_refptr<MainThreadTaskQueue> DefaultTaskQueue();
scoped_refptr<MainThreadTaskQueue> CompositorTaskQueue();
- scoped_refptr<MainThreadTaskQueue> InputTaskQueue();
scoped_refptr<MainThreadTaskQueue> V8TaskQueue();
// A control task queue which also respects virtual time. Only available if
// virtual time has been enabled.
@@ -459,6 +456,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
friend class main_thread_scheduler_impl_unittest::MainThreadSchedulerImplTest;
friend class CompositorPriorityExperiments;
+ friend class FindInPageBudgetPoolController;
FRIEND_TEST_ALL_PREFIXES(
main_thread_scheduler_impl_unittest::MainThreadSchedulerImplTest,
@@ -577,6 +575,14 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
return compositor_priority_;
}
+ base::sequence_manager::TaskQueue::QueuePriority& find_in_page_priority() {
+ return find_in_page_priority_;
+ }
+ base::sequence_manager::TaskQueue::QueuePriority find_in_page_priority()
+ const {
+ return find_in_page_priority_;
+ }
+
UseCase& use_case() { return use_case_; }
UseCase use_case() const { return use_case_; }
@@ -587,6 +593,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
should_prioritize_loading_with_compositing_ ==
other.should_prioritize_loading_with_compositing_ &&
compositor_priority_ == other.compositor_priority_ &&
+ find_in_page_priority_ == other.find_in_page_priority_ &&
use_case_ == other.use_case_;
}
@@ -602,6 +609,8 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
// MainThread::QueueClass).
base::sequence_manager::TaskQueue::QueuePriority compositor_priority_;
+ base::sequence_manager::TaskQueue::QueuePriority find_in_page_priority_;
+
UseCase use_case_;
std::array<TaskQueuePolicy,
@@ -647,6 +656,8 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
base::TimeTicks optional_now) const;
void CreateTraceEventObjectSnapshotLocked() const;
+ std::string ToString() const;
+
static bool ShouldPrioritizeInputEvent(const WebInputEvent& web_input_event);
// The amount of time which idle periods can continue being scheduled when the
@@ -775,6 +786,9 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
// task.
void DispatchOnTaskCompletionCallbacks();
+ void AsValueIntoLocked(base::trace_event::TracedValue*,
+ base::TimeTicks optional_now) const;
+
// Indicates that scheduler has been shutdown.
// It should be accessed only on the main thread, but couldn't be a member
// of MainThreadOnly struct because last might be destructed before we
@@ -799,14 +813,14 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
std::unique_ptr<TaskQueueThrottler> task_queue_throttler_;
RenderWidgetSignals render_widget_scheduler_signals_;
+ std::unique_ptr<FindInPageBudgetPoolController>
+ find_in_page_budget_pool_controller_;
+
const scoped_refptr<MainThreadTaskQueue> control_task_queue_;
const scoped_refptr<MainThreadTaskQueue> compositor_task_queue_;
- const scoped_refptr<MainThreadTaskQueue> input_task_queue_;
scoped_refptr<MainThreadTaskQueue> virtual_time_control_task_queue_;
std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter>
compositor_task_queue_enabled_voter_;
- std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter>
- input_task_queue_enabled_voter_;
using TaskQueueVoterMap = std::map<
scoped_refptr<MainThreadTaskQueue>,
@@ -818,20 +832,22 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
scoped_refptr<MainThreadTaskQueue> ipc_task_queue_;
scoped_refptr<MainThreadTaskQueue> cleanup_task_queue_;
scoped_refptr<MainThreadTaskQueue> memory_purge_task_queue_;
+ scoped_refptr<MainThreadTaskQueue> non_waking_task_queue_;
scoped_refptr<base::SingleThreadTaskRunner> v8_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> control_task_runner_;
- scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> cleanup_task_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> non_waking_task_runner_;
MemoryPurgeManager memory_purge_manager_;
// Note |virtual_time_domain_| is lazily created.
std::unique_ptr<AutoAdvancingVirtualTimeDomain> virtual_time_domain_;
+ NonWakingTimeDomain non_waking_time_domain_;
- base::Closure update_policy_closure_;
+ base::RepeatingClosure update_policy_closure_;
DeadlineTaskRunner delayed_update_policy_runner_;
CancelableClosureHolder end_renderer_hidden_idle_period_closure_;
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 807506d92e1..1f4d240aa79 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
@@ -11,6 +11,7 @@
#include "base/bind.h"
#include "base/callback.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/task/post_task.h"
@@ -18,7 +19,6 @@
#include "base/task/sequence_manager/test/sequence_manager_for_test.h"
#include "base/task/task_executor.h"
#include "base/test/bind_test_util.h"
-#include "base/test/gtest_util.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_tick_clock.h"
@@ -27,12 +27,14 @@
#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_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"
-#include "third_party/blink/public/platform/web_mouse_wheel_event.h"
-#include "third_party/blink/public/platform/web_touch_event.h"
+#include "third_party/blink/public/platform/scheduler/web_widget_scheduler.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/main_thread/auto_advancing_virtual_time_domain.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h"
#include "third_party/blink/renderer/platform/scheduler/test/recording_task_time_observer.h"
@@ -46,40 +48,23 @@ namespace scheduler {
// To avoid symbol collisions in jumbo builds.
namespace main_thread_scheduler_impl_unittest {
-using testing::IsNull;
using testing::Mock;
using testing::NotNull;
using InputEventState = WebThreadScheduler::InputEventState;
using base::sequence_manager::FakeTask;
using base::sequence_manager::FakeTaskTiming;
-enum class AntiStarvationLogic {
- kEnabled,
- kDisabled,
-};
-
-std::string ToString(AntiStarvationLogic type) {
- switch (type) {
- case AntiStarvationLogic::kEnabled:
- return "AntiStarvationLogicEnabled";
- case AntiStarvationLogic::kDisabled:
- return "AntiStarvationLogicDisabled";
- }
-}
-
-std::string GetTestNameSuffix(
- const testing::TestParamInfo<AntiStarvationLogic>& info) {
- return "With" + ToString(info.param);
-}
-
class FakeInputEvent : public blink::WebInputEvent {
public:
explicit FakeInputEvent(blink::WebInputEvent::Type event_type,
int modifiers = WebInputEvent::kNoModifiers)
- : WebInputEvent(sizeof(FakeInputEvent),
- event_type,
+ : WebInputEvent(event_type,
modifiers,
WebInputEvent::GetStaticTimeStampForTests()) {}
+
+ std::unique_ptr<WebInputEvent> Clone() const override {
+ return std::make_unique<FakeInputEvent>(*this);
+ }
};
class FakeTouchEvent : public blink::WebTouchEvent {
@@ -254,7 +239,6 @@ class MainThreadSchedulerImplForTest : public MainThreadSchedulerImpl {
using MainThreadSchedulerImpl::ControlTaskQueue;
using MainThreadSchedulerImpl::DefaultTaskQueue;
using MainThreadSchedulerImpl::EstimateLongestJankFreeTaskDuration;
- using MainThreadSchedulerImpl::InputTaskQueue;
using MainThreadSchedulerImpl::OnIdlePeriodEnded;
using MainThreadSchedulerImpl::OnIdlePeriodStarted;
using MainThreadSchedulerImpl::OnPendingTasksChanged;
@@ -332,8 +316,7 @@ class MainThreadSchedulerImplForTest : public MainThreadSchedulerImpl {
return os << MainThreadSchedulerImpl::UseCaseToString(use_case);
}
-class MainThreadSchedulerImplTest
- : public testing::TestWithParam<AntiStarvationLogic> {
+class MainThreadSchedulerImplTest : public testing::Test {
public:
MainThreadSchedulerImplTest(std::vector<base::Feature> features_to_enable,
std::vector<base::Feature> features_to_disable) {
@@ -341,8 +324,7 @@ class MainThreadSchedulerImplTest
}
MainThreadSchedulerImplTest()
- : MainThreadSchedulerImplTest({kHighPriorityInputOnMainThread},
- {kPrioritizeCompositingAfterInput}) {}
+ : MainThreadSchedulerImplTest({}, {kPrioritizeCompositingAfterInput}) {}
~MainThreadSchedulerImplTest() override = default;
@@ -353,8 +335,6 @@ class MainThreadSchedulerImplTest
nullptr, test_task_runner_, test_task_runner_->GetMockTickClock(),
base::sequence_manager::SequenceManager::Settings::Builder()
.SetRandomisedSamplingEnabled(true)
- .SetAntiStarvationLogicForPrioritiesDisabled(
- GetParam() == AntiStarvationLogic::kDisabled)
.Build()),
base::nullopt));
if (initially_ensure_usecase_none_)
@@ -381,7 +361,6 @@ class MainThreadSchedulerImplTest
default_task_runner_ = scheduler_->DefaultTaskQueue()->task_runner();
compositor_task_runner_ = scheduler_->CompositorTaskQueue()->task_runner();
- input_task_runner_ = scheduler_->InputTaskQueue()->task_runner();
idle_task_runner_ = scheduler_->IdleTaskRunner();
v8_task_runner_ = scheduler_->V8TaskQueue()->task_runner();
@@ -391,12 +370,17 @@ class MainThreadSchedulerImplTest
FrameSchedulerImpl::Create(page_scheduler_.get(), nullptr, nullptr,
FrameScheduler::FrameType::kMainFrame);
+ widget_scheduler_ = scheduler_->CreateWidgetScheduler();
+ input_task_runner_ = widget_scheduler_->InputTaskRunner();
+
loading_control_task_runner_ =
main_frame_scheduler_->FrameTaskQueueControllerForTest()
->GetTaskQueue(
main_frame_scheduler_->LoadingControlTaskQueueTraits())
->task_runner();
timer_task_runner_ = timer_task_queue()->task_runner();
+ find_in_page_task_runner_ = main_frame_scheduler_->GetTaskRunner(
+ blink::TaskType::kInternalFindInPage);
}
TaskQueue* loading_task_queue() {
@@ -414,7 +398,17 @@ class MainThreadSchedulerImplTest
.get();
}
+ MainThreadTaskQueue* find_in_page_task_queue() {
+ auto* frame_task_queue_controller =
+ main_frame_scheduler_->FrameTaskQueueControllerForTest();
+
+ return frame_task_queue_controller
+ ->GetTaskQueue(main_frame_scheduler_->FindInPageTaskQueueTraits())
+ .get();
+ }
+
void TearDown() override {
+ widget_scheduler_.reset();
main_frame_scheduler_.reset();
page_scheduler_.reset();
scheduler_->Shutdown();
@@ -768,6 +762,11 @@ class MainThreadSchedulerImplTest
FROM_HERE, base::BindOnce(&AppendToVectorTestTask, run_order,
String::FromUTF8(task)));
break;
+ case 'F':
+ find_in_page_task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&AppendToVectorTestTask, run_order,
+ String::FromUTF8(task)));
+ break;
default:
NOTREACHED();
}
@@ -846,6 +845,7 @@ class MainThreadSchedulerImplTest
std::unique_ptr<MainThreadSchedulerImplForTest> scheduler_;
std::unique_ptr<PageSchedulerImpl> page_scheduler_;
std::unique_ptr<FrameSchedulerImpl> main_frame_scheduler_;
+ std::unique_ptr<WebWidgetScheduler> widget_scheduler_;
scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
@@ -854,6 +854,7 @@ class MainThreadSchedulerImplTest
scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> timer_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> v8_task_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> find_in_page_task_runner_;
bool simulate_timer_task_ran_;
bool initially_ensure_usecase_none_ = true;
uint64_t next_begin_frame_number_ = viz::BeginFrameArgs::kStartingFrameNumber;
@@ -861,13 +862,7 @@ class MainThreadSchedulerImplTest
DISALLOW_COPY_AND_ASSIGN(MainThreadSchedulerImplTest);
};
-INSTANTIATE_TEST_SUITE_P(All,
- MainThreadSchedulerImplTest,
- testing::Values(AntiStarvationLogic::kEnabled,
- AntiStarvationLogic::kDisabled),
- GetTestNameSuffix);
-
-TEST_P(MainThreadSchedulerImplTest, TestPostDefaultTask) {
+TEST_F(MainThreadSchedulerImplTest, TestPostDefaultTask) {
Vector<String> run_order;
PostTestTasks(&run_order, "D1 D2 D3 D4");
@@ -875,7 +870,7 @@ TEST_P(MainThreadSchedulerImplTest, TestPostDefaultTask) {
EXPECT_THAT(run_order, testing::ElementsAre("D1", "D2", "D3", "D4"));
}
-TEST_P(MainThreadSchedulerImplTest, TestPostDefaultAndCompositor) {
+TEST_F(MainThreadSchedulerImplTest, TestPostDefaultAndCompositor) {
Vector<String> run_order;
PostTestTasks(&run_order, "D1 C1 P1");
base::RunLoop().RunUntilIdle();
@@ -884,7 +879,7 @@ TEST_P(MainThreadSchedulerImplTest, TestPostDefaultAndCompositor) {
EXPECT_THAT(run_order, testing::Contains("P1"));
}
-TEST_P(MainThreadSchedulerImplTest, TestRentrantTask) {
+TEST_F(MainThreadSchedulerImplTest, TestRentrantTask) {
int count = 0;
Vector<int> run_order;
default_task_runner_->PostTask(
@@ -896,7 +891,7 @@ TEST_P(MainThreadSchedulerImplTest, TestRentrantTask) {
EXPECT_THAT(run_order, testing::ElementsAre(0, 1, 2, 3, 4));
}
-TEST_P(MainThreadSchedulerImplTest, TestPostIdleTask) {
+TEST_F(MainThreadSchedulerImplTest, TestPostIdleTask) {
int run_count = 0;
base::TimeTicks expected_deadline =
Now() + base::TimeDelta::FromMilliseconds(2300);
@@ -935,7 +930,7 @@ TEST_P(MainThreadSchedulerImplTest, TestPostIdleTask) {
EXPECT_EQ(expected_deadline, deadline_in_task);
}
-TEST_P(MainThreadSchedulerImplTest, TestRepostingIdleTask) {
+TEST_F(MainThreadSchedulerImplTest, TestRepostingIdleTask) {
int run_count = 0;
g_max_idle_task_reposts = 2;
@@ -956,7 +951,7 @@ TEST_P(MainThreadSchedulerImplTest, TestRepostingIdleTask) {
EXPECT_EQ(2, run_count);
}
-TEST_P(MainThreadSchedulerImplTest, TestIdleTaskExceedsDeadline) {
+TEST_F(MainThreadSchedulerImplTest, TestIdleTaskExceedsDeadline) {
int run_count = 0;
// Post two UpdateClockToDeadlineIdleTestTask tasks.
@@ -978,7 +973,7 @@ TEST_P(MainThreadSchedulerImplTest, TestIdleTaskExceedsDeadline) {
EXPECT_EQ(2, run_count);
}
-TEST_P(MainThreadSchedulerImplTest, TestDelayedEndIdlePeriodCanceled) {
+TEST_F(MainThreadSchedulerImplTest, TestDelayedEndIdlePeriodCanceled) {
int run_count = 0;
base::TimeTicks deadline_in_task;
@@ -1018,7 +1013,7 @@ TEST_P(MainThreadSchedulerImplTest, TestDelayedEndIdlePeriodCanceled) {
EXPECT_EQ(1, run_count); // We should still be in the new idle period.
}
-TEST_P(MainThreadSchedulerImplTest, TestDefaultPolicy) {
+TEST_F(MainThreadSchedulerImplTest, TestDefaultPolicy) {
EnsureUseCaseNone();
Vector<String> run_order;
@@ -1034,7 +1029,7 @@ TEST_P(MainThreadSchedulerImplTest, TestDefaultPolicy) {
EXPECT_EQ(UseCase::kNone, CurrentUseCase());
}
-TEST_P(MainThreadSchedulerImplTest, TestDefaultPolicyWithSlowCompositor) {
+TEST_F(MainThreadSchedulerImplTest, TestDefaultPolicyWithSlowCompositor) {
RunSlowCompositorTask();
Vector<String> run_order;
@@ -1048,7 +1043,7 @@ TEST_P(MainThreadSchedulerImplTest, TestDefaultPolicyWithSlowCompositor) {
EXPECT_EQ(UseCase::kNone, CurrentUseCase());
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
TestCompositorPolicy_CompositorHandlesInput_WithTouchHandler) {
Vector<String> run_order;
PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
@@ -1062,7 +1057,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_EQ(UseCase::kCompositorGesture, CurrentUseCase());
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
TestCompositorPolicy_MainThreadHandlesInput_WithoutScrollUpdates) {
Vector<String> run_order;
PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
@@ -1076,7 +1071,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase());
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
TestCompositorPolicy_MainThreadHandlesInput_WithoutPreventDefault) {
Vector<String> run_order;
PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
@@ -1090,7 +1085,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_EQ(UseCase::kCompositorGesture, CurrentUseCase());
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
TestCompositorPolicy_CompositorHandlesInput_LongGestureDuration) {
EnableIdleTasks();
SimulateCompositorGestureStart(TouchEventPolicy::kSendTouchStart);
@@ -1120,7 +1115,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_EQ(UseCase::kCompositorGesture, CurrentUseCase());
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
TestCompositorPolicy_CompositorHandlesInput_WithoutTouchHandler) {
Vector<String> run_order;
PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
@@ -1133,7 +1128,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_EQ(UseCase::kCompositorGesture, CurrentUseCase());
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
TestCompositorPolicy_MainThreadHandlesInput_WithTouchHandler) {
Vector<String> run_order;
PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
@@ -1151,7 +1146,7 @@ TEST_P(MainThreadSchedulerImplTest,
WebInputEventResult::kHandledSystem);
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
TestCompositorPolicy_MainThreadHandlesInput_WithoutTouchHandler) {
Vector<String> run_order;
PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
@@ -1168,7 +1163,7 @@ TEST_P(MainThreadSchedulerImplTest,
WebInputEventResult::kHandledSystem);
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
TestCompositorPolicy_MainThreadHandlesInput_SingleEvent_PreventDefault) {
Vector<String> run_order;
PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
@@ -1189,7 +1184,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase());
}
-TEST_P(
+TEST_F(
MainThreadSchedulerImplTest,
TestCompositorPolicy_MainThreadHandlesInput_SingleEvent_NoPreventDefault) {
Vector<String> run_order;
@@ -1210,7 +1205,7 @@ TEST_P(
EXPECT_EQ(UseCase::kTouchstart, CurrentUseCase());
}
-TEST_P(MainThreadSchedulerImplTest, TestCompositorPolicy_DidAnimateForInput) {
+TEST_F(MainThreadSchedulerImplTest, TestCompositorPolicy_DidAnimateForInput) {
Vector<String> run_order;
PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
@@ -1226,7 +1221,7 @@ TEST_P(MainThreadSchedulerImplTest, TestCompositorPolicy_DidAnimateForInput) {
EXPECT_EQ(UseCase::kCompositorGesture, CurrentUseCase());
}
-TEST_P(MainThreadSchedulerImplTest, Navigation_ResetsTaskCostEstimations) {
+TEST_F(MainThreadSchedulerImplTest, Navigation_ResetsTaskCostEstimations) {
Vector<String> run_order;
scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
@@ -1245,7 +1240,7 @@ TEST_P(MainThreadSchedulerImplTest, Navigation_ResetsTaskCostEstimations) {
EXPECT_THAT(run_order, testing::ElementsAre("C1", "T1"));
}
-TEST_P(MainThreadSchedulerImplTest, TestTouchstartPolicy_Compositor) {
+TEST_F(MainThreadSchedulerImplTest, TestTouchstartPolicy_Compositor) {
Vector<String> run_order;
PostTestTasks(&run_order, "L1 D1 C1 D2 C2 T1 T2");
@@ -1282,7 +1277,7 @@ TEST_P(MainThreadSchedulerImplTest, TestTouchstartPolicy_Compositor) {
EXPECT_THAT(run_order, testing::ElementsAre("L1", "T1", "T2"));
}
-TEST_P(MainThreadSchedulerImplTest, TestTouchstartPolicy_MainThread) {
+TEST_F(MainThreadSchedulerImplTest, TestTouchstartPolicy_MainThread) {
Vector<String> run_order;
PostTestTasks(&run_order, "L1 D1 C1 D2 C2 T1 T2");
@@ -1336,13 +1331,7 @@ class DefaultUseCaseTest : public MainThreadSchedulerImplTest {
}
};
-INSTANTIATE_TEST_SUITE_P(All,
- DefaultUseCaseTest,
- testing::Values(AntiStarvationLogic::kEnabled,
- AntiStarvationLogic::kDisabled),
- GetTestNameSuffix);
-
-TEST_P(DefaultUseCaseTest, InitiallyInEarlyLoadingUseCase) {
+TEST_F(DefaultUseCaseTest, InitiallyInEarlyLoadingUseCase) {
// Should be early loading by default.
EXPECT_EQ(UseCase::kEarlyLoading, ForceUpdatePolicyAndGetCurrentUseCase());
@@ -1362,7 +1351,7 @@ class PrioritizeCompositingAndLoadingInUseCaseLoadingTest
{}) {}
};
-TEST_P(PrioritizeCompositingAndLoadingInUseCaseLoadingTest, LoadingUseCase) {
+TEST_F(PrioritizeCompositingAndLoadingInUseCaseLoadingTest, LoadingUseCase) {
Vector<String> run_order;
PostTestTasks(&run_order, "I1 D1 C1 T1 L1 D2 C2 T2 L2");
@@ -1386,15 +1375,8 @@ TEST_P(PrioritizeCompositingAndLoadingInUseCaseLoadingTest, LoadingUseCase) {
EnableIdleTasks();
base::RunLoop().RunUntilIdle();
- String default_order_expected[] = {"D1",
- "C1"
- "T1",
- "L1",
- "D2",
- "C2",
- "T2",
- "L2",
- "I1"};
+ String default_order_expected[] = {"D1", "C1", "T1", "L1", "D2",
+ "C2", "T2", "L2", "I1"};
EXPECT_THAT(run_order, testing::ElementsAreArray(default_order_expected));
EXPECT_EQ(UseCase::kLoading, CurrentUseCase());
@@ -1413,7 +1395,7 @@ TEST_P(PrioritizeCompositingAndLoadingInUseCaseLoadingTest, LoadingUseCase) {
EXPECT_EQ(UseCase::kNone, CurrentUseCase());
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
EventConsumedOnCompositorThread_IgnoresMouseMove_WhenMouseUp) {
RunSlowCompositorTask();
@@ -1430,7 +1412,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_THAT(run_order, testing::ElementsAre("D1", "C1", "D2", "C2", "I1"));
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
EventForwardedToMainThread_IgnoresMouseMove_WhenMouseUp) {
RunSlowCompositorTask();
@@ -1447,7 +1429,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_THAT(run_order, testing::ElementsAre("D1", "C1", "D2", "C2", "I1"));
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
EventConsumedOnCompositorThread_MouseMove_WhenMouseDown) {
Vector<String> run_order;
PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
@@ -1465,7 +1447,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_THAT(run_order, testing::ElementsAre("D1", "D2", "C1", "C2", "I1"));
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
EventForwardedToMainThread_MouseMove_WhenMouseDown) {
Vector<String> run_order;
PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
@@ -1484,7 +1466,7 @@ TEST_P(MainThreadSchedulerImplTest,
WebInputEventResult::kHandledSystem);
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
EventForwardedToMainThread_MouseMove_WhenMouseDown_AfterMouseWheel) {
// Simulate a main thread driven mouse wheel scroll gesture.
SimulateMainThreadGestureStart(TouchEventPolicy::kSendTouchStart,
@@ -1515,7 +1497,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_THAT(run_order, testing::ElementsAre("C1", "C2", "D1", "D2", "I1"));
}
-TEST_P(MainThreadSchedulerImplTest, EventForwardedToMainThread_MouseClick) {
+TEST_F(MainThreadSchedulerImplTest, EventForwardedToMainThread_MouseClick) {
// A mouse click should be detected as main thread input handling, which means
// we won't try to defer expensive tasks because of one. We can, however,
// prioritize compositing/input handling.
@@ -1539,7 +1521,7 @@ TEST_P(MainThreadSchedulerImplTest, EventForwardedToMainThread_MouseClick) {
EXPECT_THAT(run_order, testing::ElementsAre("C1", "C2", "D1", "D2", "I1"));
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
EventConsumedOnCompositorThread_MouseWheel) {
Vector<String> run_order;
PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
@@ -1554,7 +1536,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_EQ(UseCase::kCompositorGesture, CurrentUseCase());
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
EventForwardedToMainThread_MouseWheel_PreventDefault) {
Vector<String> run_order;
PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
@@ -1569,7 +1551,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase());
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
EventForwardedToMainThread_NoPreventDefault) {
Vector<String> run_order;
PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
@@ -1593,7 +1575,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_EQ(UseCase::kMainThreadGesture, CurrentUseCase());
}
-TEST_P(
+TEST_F(
MainThreadSchedulerImplTest,
EventForwardedToMainThreadAndBackToCompositor_MouseWheel_NoPreventDefault) {
Vector<String> run_order;
@@ -1618,7 +1600,7 @@ TEST_P(
EXPECT_EQ(UseCase::kCompositorGesture, CurrentUseCase());
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
EventConsumedOnCompositorThread_IgnoresKeyboardEvents) {
RunSlowCompositorTask();
@@ -1635,7 +1617,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_EQ(UseCase::kNone, CurrentUseCase());
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
EventForwardedToMainThread_IgnoresKeyboardEvents) {
RunSlowCompositorTask();
@@ -1656,7 +1638,7 @@ TEST_P(MainThreadSchedulerImplTest,
WebInputEventResult::kHandledSystem);
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
TestMainthreadScrollingUseCaseDoesNotStarveDefaultTasks) {
SimulateMainThreadGestureStart(TouchEventPolicy::kDontSendTouchStart,
blink::WebInputEvent::kGestureScrollBegin);
@@ -1675,21 +1657,10 @@ TEST_P(MainThreadSchedulerImplTest,
InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
base::RunLoop().RunUntilIdle();
- switch (GetParam()) {
- case AntiStarvationLogic::kEnabled:
- // Ensure that the default D1 task gets to run at some point before the
- // final C2 compositor task.
- EXPECT_THAT(run_order, testing::ElementsAre("C1", "D1", "C2"));
- break;
- case AntiStarvationLogic::kDisabled:
- // Without anti-starvation logic, the default D1 task should get stuck at
- // the end.
- EXPECT_THAT(run_order, testing::ElementsAre("C1", "C2", "D1"));
- break;
- }
+ EXPECT_THAT(run_order, testing::ElementsAre("C1", "C2", "D1"));
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
TestCompositorPolicyEnds_CompositorHandlesInput) {
SimulateCompositorGestureStart(TouchEventPolicy::kDontSendTouchStart);
EXPECT_EQ(UseCase::kCompositorGesture,
@@ -1699,7 +1670,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase());
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
TestCompositorPolicyEnds_MainThreadHandlesInput) {
SimulateMainThreadGestureStart(TouchEventPolicy::kDontSendTouchStart,
blink::WebInputEvent::kGestureScrollBegin);
@@ -1710,7 +1681,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase());
}
-TEST_P(MainThreadSchedulerImplTest, TestTouchstartPolicyEndsAfterTimeout) {
+TEST_F(MainThreadSchedulerImplTest, TestTouchstartPolicyEndsAfterTimeout) {
Vector<String> run_order;
PostTestTasks(&run_order, "L1 D1 C1 D2 C2");
@@ -1732,7 +1703,7 @@ TEST_P(MainThreadSchedulerImplTest, TestTouchstartPolicyEndsAfterTimeout) {
EXPECT_THAT(run_order, testing::ElementsAre("L1", "D1", "D2"));
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
TestTouchstartPolicyEndsAfterConsecutiveTouchmoves) {
Vector<String> run_order;
PostTestTasks(&run_order, "L1 D1 C1 D2 C2");
@@ -1761,7 +1732,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_THAT(run_order, testing::ElementsAre("L1"));
}
-TEST_P(MainThreadSchedulerImplTest, TestIsHighPriorityWorkAnticipated) {
+TEST_F(MainThreadSchedulerImplTest, TestIsHighPriorityWorkAnticipated) {
bool is_anticipated_before = false;
bool is_anticipated_after = false;
@@ -1829,7 +1800,7 @@ TEST_P(MainThreadSchedulerImplTest, TestIsHighPriorityWorkAnticipated) {
EXPECT_FALSE(is_anticipated_after);
}
-TEST_P(MainThreadSchedulerImplTest, TestShouldYield) {
+TEST_F(MainThreadSchedulerImplTest, TestShouldYield) {
bool should_yield_before = false;
bool should_yield_after = false;
@@ -1863,7 +1834,7 @@ TEST_P(MainThreadSchedulerImplTest, TestShouldYield) {
EXPECT_TRUE(should_yield_after);
}
-TEST_P(MainThreadSchedulerImplTest, TestShouldYield_TouchStart) {
+TEST_F(MainThreadSchedulerImplTest, TestShouldYield_TouchStart) {
// Receiving a touchstart should immediately trigger yielding, even if
// there's no immediately pending work in the compositor queue.
EXPECT_FALSE(scheduler_->ShouldYieldForHighPriorityWork());
@@ -1874,7 +1845,7 @@ TEST_P(MainThreadSchedulerImplTest, TestShouldYield_TouchStart) {
base::RunLoop().RunUntilIdle();
}
-TEST_P(MainThreadSchedulerImplTest, SlowMainThreadInputEvent) {
+TEST_F(MainThreadSchedulerImplTest, SlowMainThreadInputEvent) {
EXPECT_EQ(UseCase::kNone, CurrentUseCase());
// An input event should bump us into input priority.
@@ -1903,7 +1874,7 @@ TEST_P(MainThreadSchedulerImplTest, SlowMainThreadInputEvent) {
EXPECT_EQ(UseCase::kNone, CurrentUseCase());
}
-TEST_P(MainThreadSchedulerImplTest, OnlyOnePendingUrgentPolicyUpdate) {
+TEST_F(MainThreadSchedulerImplTest, OnlyOnePendingUrgentPolicyUpdate) {
for (int i = 0; i < 4; i++) {
scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread();
}
@@ -1911,7 +1882,7 @@ TEST_P(MainThreadSchedulerImplTest, OnlyOnePendingUrgentPolicyUpdate) {
EXPECT_EQ(1, scheduler_->update_policy_count_);
}
-TEST_P(MainThreadSchedulerImplTest, OnePendingDelayedAndOneUrgentUpdatePolicy) {
+TEST_F(MainThreadSchedulerImplTest, OnePendingDelayedAndOneUrgentUpdatePolicy) {
scheduler_->ScheduleDelayedPolicyUpdate(Now(),
base::TimeDelta::FromMilliseconds(1));
scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread();
@@ -1921,7 +1892,7 @@ TEST_P(MainThreadSchedulerImplTest, OnePendingDelayedAndOneUrgentUpdatePolicy) {
EXPECT_EQ(2, scheduler_->update_policy_count_);
}
-TEST_P(MainThreadSchedulerImplTest, OneUrgentAndOnePendingDelayedUpdatePolicy) {
+TEST_F(MainThreadSchedulerImplTest, OneUrgentAndOnePendingDelayedUpdatePolicy) {
scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread();
scheduler_->ScheduleDelayedPolicyUpdate(Now(),
base::TimeDelta::FromMilliseconds(1));
@@ -1931,7 +1902,7 @@ TEST_P(MainThreadSchedulerImplTest, OneUrgentAndOnePendingDelayedUpdatePolicy) {
EXPECT_EQ(2, scheduler_->update_policy_count_);
}
-TEST_P(MainThreadSchedulerImplTest, UpdatePolicyCountTriggeredByOneInputEvent) {
+TEST_F(MainThreadSchedulerImplTest, UpdatePolicyCountTriggeredByOneInputEvent) {
// We expect DidHandleInputEventOnCompositorThread to post an urgent policy
// update.
scheduler_->DidHandleInputEventOnCompositorThread(
@@ -1952,7 +1923,7 @@ TEST_P(MainThreadSchedulerImplTest, UpdatePolicyCountTriggeredByOneInputEvent) {
EXPECT_EQ(2, scheduler_->update_policy_count_);
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
UpdatePolicyCountTriggeredByThreeInputEvents) {
// We expect DidHandleInputEventOnCompositorThread to post
// an urgent policy update.
@@ -2002,7 +1973,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_EQ(3, scheduler_->update_policy_count_);
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
UpdatePolicyCountTriggeredByTwoInputEventsWithALongSeparatingDelay) {
// We expect DidHandleInputEventOnCompositorThread to post an urgent policy
// update.
@@ -2040,7 +2011,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_EQ(4, scheduler_->update_policy_count_);
}
-TEST_P(MainThreadSchedulerImplTest, EnsureUpdatePolicyNotTriggeredTooOften) {
+TEST_F(MainThreadSchedulerImplTest, EnsureUpdatePolicyNotTriggeredTooOften) {
EXPECT_EQ(0, scheduler_->update_policy_count_);
scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
EXPECT_EQ(1, scheduler_->update_policy_count_);
@@ -2094,7 +2065,7 @@ TEST_P(MainThreadSchedulerImplTest, EnsureUpdatePolicyNotTriggeredTooOften) {
"none blocking input expected", "none"));
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
BlockingInputExpectedSoonWhenBlockInputEventSeen) {
SimulateCompositorGestureStart(TouchEventPolicy::kSendTouchStart);
EXPECT_TRUE(HaveSeenABlockingGesture());
@@ -2102,7 +2073,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_TRUE(BlockingInputExpectedSoon());
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
BlockingInputNotExpectedSoonWhenNoBlockInputEventSeen) {
SimulateCompositorGestureStart(TouchEventPolicy::kDontSendTouchStart);
EXPECT_FALSE(HaveSeenABlockingGesture());
@@ -2110,7 +2081,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_FALSE(BlockingInputExpectedSoon());
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
GetTaskExecutorForCurrentThreadInPostedTask) {
base::TaskExecutor* task_executor = base::GetTaskExecutorForCurrentThread();
EXPECT_THAT(task_executor, NotNull());
@@ -2126,36 +2097,7 @@ TEST_P(MainThreadSchedulerImplTest,
run_loop.Run();
}
-TEST_P(MainThreadSchedulerImplTest, CurrentThread) {
- EXPECT_EQ(scheduler_->DeprecatedDefaultTaskRunner(),
- base::CreateSingleThreadTaskRunner({base::CurrentThread()}));
-
- // base::TaskPriority is currently ignored in blink.
- EXPECT_EQ(scheduler_->DeprecatedDefaultTaskRunner(),
- base::CreateSingleThreadTaskRunner(
- {base::CurrentThread(), base::TaskPriority::BEST_EFFORT}));
-}
-
-TEST_P(MainThreadSchedulerImplTest, GetContinuationTaskRunner) {
- scoped_refptr<MainThreadTaskQueue> timer_tq = scheduler_->NewTimerTaskQueue(
- MainThreadTaskQueue::QueueType::kFrameThrottleable, nullptr);
- auto task_runner = timer_tq->CreateTaskRunner(TaskType::kJavascriptTimer);
-
- base::RunLoop run_loop;
- task_runner->PostTask(FROM_HERE, base::BindLambdaForTesting([&]() {
- EXPECT_EQ(task_runner,
- base::GetContinuationTaskRunner());
- run_loop.Quit();
- }));
- run_loop.Run();
-}
-
-TEST_P(MainThreadSchedulerImplTest,
- GetContinuationTaskRunnerWithNoTaskRunning) {
- EXPECT_DCHECK_DEATH(base::GetContinuationTaskRunner());
-}
-
-TEST_P(MainThreadSchedulerImplTest, TestBeginMainFrameNotExpectedUntil) {
+TEST_F(MainThreadSchedulerImplTest, TestBeginMainFrameNotExpectedUntil) {
base::TimeDelta ten_millis(base::TimeDelta::FromMilliseconds(10));
base::TimeTicks expected_deadline = Now() + ten_millis;
base::TimeTicks deadline_in_task;
@@ -2177,7 +2119,7 @@ TEST_P(MainThreadSchedulerImplTest, TestBeginMainFrameNotExpectedUntil) {
EXPECT_EQ(expected_deadline, deadline_in_task);
}
-TEST_P(MainThreadSchedulerImplTest, TestLongIdlePeriod) {
+TEST_F(MainThreadSchedulerImplTest, TestLongIdlePeriod) {
base::TimeTicks expected_deadline = Now() + maximum_idle_period_duration();
base::TimeTicks deadline_in_task;
int run_count = 0;
@@ -2194,7 +2136,7 @@ TEST_P(MainThreadSchedulerImplTest, TestLongIdlePeriod) {
EXPECT_EQ(expected_deadline, deadline_in_task);
}
-TEST_P(MainThreadSchedulerImplTest, TestLongIdlePeriodWithPendingDelayedTask) {
+TEST_F(MainThreadSchedulerImplTest, TestLongIdlePeriodWithPendingDelayedTask) {
base::TimeDelta pending_task_delay = base::TimeDelta::FromMilliseconds(30);
base::TimeTicks expected_deadline = Now() + pending_task_delay;
base::TimeTicks deadline_in_task;
@@ -2211,7 +2153,7 @@ TEST_P(MainThreadSchedulerImplTest, TestLongIdlePeriodWithPendingDelayedTask) {
EXPECT_EQ(expected_deadline, deadline_in_task);
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
TestLongIdlePeriodWithLatePendingDelayedTask) {
base::TimeDelta pending_task_delay = base::TimeDelta::FromMilliseconds(10);
base::TimeTicks deadline_in_task;
@@ -2238,7 +2180,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_EQ(1, run_count);
}
-TEST_P(MainThreadSchedulerImplTest, TestLongIdlePeriodRepeating) {
+TEST_F(MainThreadSchedulerImplTest, TestLongIdlePeriodRepeating) {
Vector<base::TimeTicks> actual_deadlines;
int run_count = 0;
@@ -2277,7 +2219,7 @@ TEST_P(MainThreadSchedulerImplTest, TestLongIdlePeriodRepeating) {
EXPECT_EQ(4, run_count);
}
-TEST_P(MainThreadSchedulerImplTest, TestLongIdlePeriodInTouchStartPolicy) {
+TEST_F(MainThreadSchedulerImplTest, TestLongIdlePeriodInTouchStartPolicy) {
base::TimeTicks deadline_in_task;
int run_count = 0;
@@ -2305,7 +2247,7 @@ void TestCanExceedIdleDeadlineIfRequiredTask(ThreadScheduler* scheduler,
(*run_count)++;
}
-TEST_P(MainThreadSchedulerImplTest, CanExceedIdleDeadlineIfRequired) {
+TEST_F(MainThreadSchedulerImplTest, CanExceedIdleDeadlineIfRequired) {
int run_count = 0;
bool can_exceed_idle_deadline = false;
@@ -2355,7 +2297,7 @@ TEST_P(MainThreadSchedulerImplTest, CanExceedIdleDeadlineIfRequired) {
EXPECT_FALSE(scheduler_->CanExceedIdleDeadlineIfRequired());
}
-TEST_P(MainThreadSchedulerImplTest, TestRendererHiddenIdlePeriod) {
+TEST_F(MainThreadSchedulerImplTest, TestRendererHiddenIdlePeriod) {
int run_count = 0;
g_max_idle_task_reposts = 2;
@@ -2387,14 +2329,14 @@ TEST_P(MainThreadSchedulerImplTest, TestRendererHiddenIdlePeriod) {
EXPECT_EQ(2, run_count);
}
-TEST_P(MainThreadSchedulerImplTest, TimerQueueEnabledByDefault) {
+TEST_F(MainThreadSchedulerImplTest, TimerQueueEnabledByDefault) {
Vector<String> run_order;
PostTestTasks(&run_order, "T1 T2");
base::RunLoop().RunUntilIdle();
EXPECT_THAT(run_order, testing::ElementsAre("T1", "T2"));
}
-TEST_P(MainThreadSchedulerImplTest, StopAndResumeRenderer) {
+TEST_F(MainThreadSchedulerImplTest, StopAndResumeRenderer) {
Vector<String> run_order;
PostTestTasks(&run_order, "T1 T2");
@@ -2407,7 +2349,7 @@ TEST_P(MainThreadSchedulerImplTest, StopAndResumeRenderer) {
EXPECT_THAT(run_order, testing::ElementsAre("T1", "T2"));
}
-TEST_P(MainThreadSchedulerImplTest, StopAndThrottleTimerQueue) {
+TEST_F(MainThreadSchedulerImplTest, StopAndThrottleTimerQueue) {
Vector<String> run_order;
PostTestTasks(&run_order, "T1 T2");
@@ -2419,7 +2361,7 @@ TEST_P(MainThreadSchedulerImplTest, StopAndThrottleTimerQueue) {
EXPECT_THAT(run_order, testing::ElementsAre());
}
-TEST_P(MainThreadSchedulerImplTest, ThrottleAndPauseRenderer) {
+TEST_F(MainThreadSchedulerImplTest, ThrottleAndPauseRenderer) {
Vector<String> run_order;
PostTestTasks(&run_order, "T1 T2");
@@ -2431,7 +2373,7 @@ TEST_P(MainThreadSchedulerImplTest, ThrottleAndPauseRenderer) {
EXPECT_THAT(run_order, testing::ElementsAre());
}
-TEST_P(MainThreadSchedulerImplTest, MultipleStopsNeedMultipleResumes) {
+TEST_F(MainThreadSchedulerImplTest, MultipleStopsNeedMultipleResumes) {
Vector<String> run_order;
PostTestTasks(&run_order, "T1 T2");
@@ -2454,7 +2396,7 @@ TEST_P(MainThreadSchedulerImplTest, MultipleStopsNeedMultipleResumes) {
EXPECT_THAT(run_order, testing::ElementsAre("T1", "T2"));
}
-TEST_P(MainThreadSchedulerImplTest, PauseRenderer) {
+TEST_F(MainThreadSchedulerImplTest, PauseRenderer) {
// Tasks in some queues don't fire when the renderer is paused.
Vector<String> run_order;
PostTestTasks(&run_order, "D1 C1 L1 I1 T1");
@@ -2470,11 +2412,11 @@ TEST_P(MainThreadSchedulerImplTest, PauseRenderer) {
EXPECT_THAT(run_order, testing::ElementsAre("L1", "T1"));
}
-TEST_P(MainThreadSchedulerImplTest, UseCaseToString) {
+TEST_F(MainThreadSchedulerImplTest, UseCaseToString) {
CheckAllUseCaseToString();
}
-TEST_P(MainThreadSchedulerImplTest, MismatchedDidHandleInputEventOnMainThread) {
+TEST_F(MainThreadSchedulerImplTest, MismatchedDidHandleInputEventOnMainThread) {
// This should not DCHECK because there was no corresponding compositor side
// call to DidHandleInputEventOnCompositorThread with
// INPUT_EVENT_ACK_STATE_NOT_CONSUMED. There are legitimate reasons for the
@@ -2484,7 +2426,7 @@ TEST_P(MainThreadSchedulerImplTest, MismatchedDidHandleInputEventOnMainThread) {
WebInputEventResult::kHandledSystem);
}
-TEST_P(MainThreadSchedulerImplTest, BeginMainFrameOnCriticalPath) {
+TEST_F(MainThreadSchedulerImplTest, BeginMainFrameOnCriticalPath) {
ASSERT_FALSE(scheduler_->BeginMainFrameOnCriticalPath());
viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
@@ -2499,7 +2441,7 @@ TEST_P(MainThreadSchedulerImplTest, BeginMainFrameOnCriticalPath) {
ASSERT_FALSE(scheduler_->BeginMainFrameOnCriticalPath());
}
-TEST_P(MainThreadSchedulerImplTest, ShutdownPreventsPostingOfNewTasks) {
+TEST_F(MainThreadSchedulerImplTest, ShutdownPreventsPostingOfNewTasks) {
main_frame_scheduler_.reset();
page_scheduler_.reset();
scheduler_->Shutdown();
@@ -2509,7 +2451,7 @@ TEST_P(MainThreadSchedulerImplTest, ShutdownPreventsPostingOfNewTasks) {
EXPECT_THAT(run_order, testing::ElementsAre());
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
EstimateLongestJankFreeTaskDuration_UseCase_NONE) {
EnsureUseCaseNone();
EXPECT_EQ(UseCase::kNone, CurrentUseCase());
@@ -2517,7 +2459,7 @@ TEST_P(MainThreadSchedulerImplTest,
scheduler_->EstimateLongestJankFreeTaskDuration());
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
EstimateLongestJankFreeTaskDuration_UseCase_kCompositorGesture) {
SimulateCompositorGestureStart(TouchEventPolicy::kDontSendTouchStart);
EXPECT_EQ(UseCase::kCompositorGesture,
@@ -2526,7 +2468,7 @@ TEST_P(MainThreadSchedulerImplTest,
scheduler_->EstimateLongestJankFreeTaskDuration());
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
EstimateLongestJankFreeTaskDuration_UseCase_EarlyLoading) {
scheduler_->DidStartProvisionalLoad(true);
EXPECT_EQ(UseCase::kEarlyLoading, ForceUpdatePolicyAndGetCurrentUseCase());
@@ -2534,7 +2476,7 @@ TEST_P(MainThreadSchedulerImplTest,
scheduler_->EstimateLongestJankFreeTaskDuration());
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
EstimateLongestJankFreeTaskDuration_UseCase_Loading) {
scheduler_->DidStartProvisionalLoad(true);
scheduler_->OnFirstContentfulPaint();
@@ -2543,7 +2485,7 @@ TEST_P(MainThreadSchedulerImplTest,
scheduler_->EstimateLongestJankFreeTaskDuration());
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
EstimateLongestJankFreeTaskDuration_UseCase_MAIN_THREAD_GESTURE) {
SimulateMainThreadGestureStart(TouchEventPolicy::kSendTouchStart,
blink::WebInputEvent::kGestureScrollUpdate);
@@ -2569,7 +2511,7 @@ TEST_P(MainThreadSchedulerImplTest,
scheduler_->EstimateLongestJankFreeTaskDuration());
}
-TEST_P(
+TEST_F(
MainThreadSchedulerImplTest,
EstimateLongestJankFreeTaskDuration_UseCase_MAIN_THREAD_CUSTOM_INPUT_HANDLING) {
viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
@@ -2594,7 +2536,7 @@ TEST_P(
scheduler_->EstimateLongestJankFreeTaskDuration());
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
EstimateLongestJankFreeTaskDuration_UseCase_SYNCHRONIZED_GESTURE) {
SimulateCompositorGestureStart(TouchEventPolicy::kDontSendTouchStart);
@@ -2654,7 +2596,7 @@ void SlowCountingTask(size_t* count,
}
} // namespace
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
SYNCHRONIZED_GESTURE_TimerTaskThrottling_TimersStopped) {
SimulateCompositorGestureStart(TouchEventPolicy::kSendTouchStart);
@@ -2711,7 +2653,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_EQ(2u, count);
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
SYNCHRONIZED_GESTURE_TimerTaskThrottling_task_not_expensive) {
SimulateCompositorGestureStart(TouchEventPolicy::kSendTouchStart);
@@ -2749,7 +2691,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_EQ(500u, count);
}
-TEST_P(MainThreadSchedulerImplTest, DenyLongIdleDuringTouchStart) {
+TEST_F(MainThreadSchedulerImplTest, DenyLongIdleDuringTouchStart) {
scheduler_->DidHandleInputEventOnCompositorThread(
FakeTouchEvent(blink::WebInputEvent::kTouchStart),
InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
@@ -2769,7 +2711,7 @@ TEST_P(MainThreadSchedulerImplTest, DenyLongIdleDuringTouchStart) {
EXPECT_GE(next_time_to_check, base::TimeDelta());
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
TestCompositorPolicy_TouchStartDuringFling) {
scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
scheduler_->DidAnimateForInputOnCompositorThread();
@@ -2785,7 +2727,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_EQ(UseCase::kTouchstart, ForceUpdatePolicyAndGetCurrentUseCase());
}
-TEST_P(MainThreadSchedulerImplTest, SYNCHRONIZED_GESTURE_CompositingExpensive) {
+TEST_F(MainThreadSchedulerImplTest, SYNCHRONIZED_GESTURE_CompositingExpensive) {
SimulateCompositorGestureStart(TouchEventPolicy::kSendTouchStart);
// With the compositor task taking 20ms, there is not enough time to run
@@ -2824,7 +2766,7 @@ TEST_P(MainThreadSchedulerImplTest, SYNCHRONIZED_GESTURE_CompositingExpensive) {
EXPECT_EQ(1000u, run_order.size());
}
-TEST_P(MainThreadSchedulerImplTest, MAIN_THREAD_CUSTOM_INPUT_HANDLING) {
+TEST_F(MainThreadSchedulerImplTest, MAIN_THREAD_CUSTOM_INPUT_HANDLING) {
SimulateMainThreadGestureStart(TouchEventPolicy::kSendTouchStart,
blink::WebInputEvent::kGestureScrollBegin);
@@ -2865,7 +2807,7 @@ TEST_P(MainThreadSchedulerImplTest, MAIN_THREAD_CUSTOM_INPUT_HANDLING) {
EXPECT_EQ(1000u, run_order.size());
}
-TEST_P(MainThreadSchedulerImplTest, MAIN_THREAD_GESTURE) {
+TEST_F(MainThreadSchedulerImplTest, MAIN_THREAD_GESTURE) {
SimulateMainThreadGestureStart(TouchEventPolicy::kDontSendTouchStart,
blink::WebInputEvent::kGestureScrollBegin);
@@ -2909,7 +2851,7 @@ class MockRAILModeObserver : public RAILModeObserver {
MOCK_METHOD1(OnRAILModeChanged, void(RAILMode rail_mode));
};
-TEST_P(MainThreadSchedulerImplTest, TestResponseRAILMode) {
+TEST_F(MainThreadSchedulerImplTest, TestResponseRAILMode) {
MockRAILModeObserver observer;
scheduler_->AddRAILModeObserver(&observer);
EXPECT_CALL(observer, OnRAILModeChanged(RAILMode::kResponse));
@@ -2921,7 +2863,7 @@ TEST_P(MainThreadSchedulerImplTest, TestResponseRAILMode) {
scheduler_->RemoveRAILModeObserver(&observer);
}
-TEST_P(MainThreadSchedulerImplTest, TestAnimateRAILMode) {
+TEST_F(MainThreadSchedulerImplTest, TestAnimateRAILMode) {
MockRAILModeObserver observer;
scheduler_->AddRAILModeObserver(&observer);
EXPECT_CALL(observer, OnRAILModeChanged(RAILMode::kAnimation)).Times(0);
@@ -2932,7 +2874,7 @@ TEST_P(MainThreadSchedulerImplTest, TestAnimateRAILMode) {
scheduler_->RemoveRAILModeObserver(&observer);
}
-TEST_P(MainThreadSchedulerImplTest, TestIdleRAILMode) {
+TEST_F(MainThreadSchedulerImplTest, TestIdleRAILMode) {
MockRAILModeObserver observer;
scheduler_->AddRAILModeObserver(&observer);
EXPECT_CALL(observer, OnRAILModeChanged(RAILMode::kAnimation));
@@ -2947,7 +2889,7 @@ TEST_P(MainThreadSchedulerImplTest, TestIdleRAILMode) {
scheduler_->RemoveRAILModeObserver(&observer);
}
-TEST_P(MainThreadSchedulerImplTest, TestLoadRAILMode) {
+TEST_F(MainThreadSchedulerImplTest, TestLoadRAILMode) {
MockRAILModeObserver observer;
scheduler_->AddRAILModeObserver(&observer);
EXPECT_CALL(observer, OnRAILModeChanged(RAILMode::kAnimation));
@@ -2964,7 +2906,7 @@ TEST_P(MainThreadSchedulerImplTest, TestLoadRAILMode) {
scheduler_->RemoveRAILModeObserver(&observer);
}
-TEST_P(MainThreadSchedulerImplTest, InputTerminatesLoadRAILMode) {
+TEST_F(MainThreadSchedulerImplTest, InputTerminatesLoadRAILMode) {
MockRAILModeObserver observer;
scheduler_->AddRAILModeObserver(&observer);
EXPECT_CALL(observer, OnRAILModeChanged(RAILMode::kAnimation));
@@ -2985,7 +2927,7 @@ TEST_P(MainThreadSchedulerImplTest, InputTerminatesLoadRAILMode) {
scheduler_->RemoveRAILModeObserver(&observer);
}
-TEST_P(MainThreadSchedulerImplTest, UnthrottledTaskRunner) {
+TEST_F(MainThreadSchedulerImplTest, UnthrottledTaskRunner) {
// Ensure neither suspension nor timer task throttling affects an unthrottled
// task runner.
SimulateCompositorGestureStart(TouchEventPolicy::kSendTouchStart);
@@ -3030,7 +2972,7 @@ TEST_P(MainThreadSchedulerImplTest, UnthrottledTaskRunner) {
EXPECT_EQ(500u, unthrottled_count);
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
VirtualTimePolicyDoesNotAffectNewTimerTaskQueueIfVirtualTimeNotEnabled) {
scheduler_->SetVirtualTimePolicy(
PageSchedulerImpl::VirtualTimePolicy::kPause);
@@ -3039,7 +2981,7 @@ TEST_P(MainThreadSchedulerImplTest,
EXPECT_FALSE(timer_tq->HasActiveFence());
}
-TEST_P(MainThreadSchedulerImplTest, EnableVirtualTime) {
+TEST_F(MainThreadSchedulerImplTest, EnableVirtualTime) {
EXPECT_FALSE(scheduler_->IsVirtualTimeEnabled());
scheduler_->EnableVirtualTime(
MainThreadSchedulerImpl::BaseTimeOverridePolicy::DO_NOT_OVERRIDE);
@@ -3101,7 +3043,7 @@ TEST_P(MainThreadSchedulerImplTest, EnableVirtualTime) {
scheduler_->GetVirtualTimeDomain());
}
-TEST_P(MainThreadSchedulerImplTest, EnableVirtualTimeAfterThrottling) {
+TEST_F(MainThreadSchedulerImplTest, EnableVirtualTimeAfterThrottling) {
std::unique_ptr<PageSchedulerImpl> page_scheduler =
base::WrapUnique(new PageSchedulerImpl(nullptr, scheduler_.get()));
scheduler_->AddPageScheduler(page_scheduler.get());
@@ -3112,7 +3054,7 @@ TEST_P(MainThreadSchedulerImplTest, EnableVirtualTimeAfterThrottling) {
TaskQueue* timer_tq = ThrottleableTaskQueue(frame_scheduler.get()).get();
- frame_scheduler->SetCrossOrigin(true);
+ frame_scheduler->SetCrossOriginToMainFrame(true);
frame_scheduler->SetFrameVisible(false);
EXPECT_TRUE(scheduler_->task_queue_throttler()->IsThrottled(timer_tq));
@@ -3122,7 +3064,7 @@ TEST_P(MainThreadSchedulerImplTest, EnableVirtualTimeAfterThrottling) {
EXPECT_FALSE(scheduler_->task_queue_throttler()->IsThrottled(timer_tq));
}
-TEST_P(MainThreadSchedulerImplTest, DisableVirtualTimeForTesting) {
+TEST_F(MainThreadSchedulerImplTest, DisableVirtualTimeForTesting) {
scheduler_->EnableVirtualTime(
MainThreadSchedulerImpl::BaseTimeOverridePolicy::DO_NOT_OVERRIDE);
@@ -3148,7 +3090,7 @@ TEST_P(MainThreadSchedulerImplTest, DisableVirtualTimeForTesting) {
EXPECT_FALSE(scheduler_->VirtualTimeControlTaskQueue());
}
-TEST_P(MainThreadSchedulerImplTest, VirtualTimePauser) {
+TEST_F(MainThreadSchedulerImplTest, VirtualTimePauser) {
scheduler_->EnableVirtualTime(
MainThreadSchedulerImpl::BaseTimeOverridePolicy::DO_NOT_OVERRIDE);
scheduler_->SetVirtualTimePolicy(
@@ -3169,7 +3111,7 @@ TEST_P(MainThreadSchedulerImplTest, VirtualTimePauser) {
EXPECT_EQ(after, before);
}
-TEST_P(MainThreadSchedulerImplTest, VirtualTimePauserNonInstantTask) {
+TEST_F(MainThreadSchedulerImplTest, VirtualTimePauserNonInstantTask) {
scheduler_->EnableVirtualTime(
MainThreadSchedulerImpl::BaseTimeOverridePolicy::DO_NOT_OVERRIDE);
scheduler_->SetVirtualTimePolicy(
@@ -3186,7 +3128,7 @@ TEST_P(MainThreadSchedulerImplTest, VirtualTimePauserNonInstantTask) {
EXPECT_GT(after, before);
}
-TEST_P(MainThreadSchedulerImplTest, VirtualTimeWithOneQueueWithoutVirtualTime) {
+TEST_F(MainThreadSchedulerImplTest, VirtualTimeWithOneQueueWithoutVirtualTime) {
// This test ensures that we do not do anything strange like stopping
// processing task queues after we encountered one task queue with
// DoNotUseVirtualTime trait.
@@ -3232,7 +3174,7 @@ TEST_P(MainThreadSchedulerImplTest, VirtualTimeWithOneQueueWithoutVirtualTime) {
EXPECT_EQ(counter, kTaskQueueCount);
}
-TEST_P(MainThreadSchedulerImplTest, Tracing) {
+TEST_F(MainThreadSchedulerImplTest, Tracing) {
// This test sets renderer scheduler to some non-trivial state
// (by posting tasks, creating child schedulers, etc) and converts it into a
// traced value. This test checks that no internal checks fire during this.
@@ -3260,10 +3202,7 @@ TEST_P(MainThreadSchedulerImplTest, Tracing) {
FROM_HERE, base::BindOnce(NullTask),
base::TimeDelta::FromMilliseconds(10));
- std::unique_ptr<base::trace_event::ConvertableToTraceFormat> value =
- scheduler_->AsValue(base::TimeTicks());
- EXPECT_TRUE(value);
- EXPECT_FALSE(value->ToString().empty());
+ EXPECT_FALSE(scheduler_->ToString().empty());
}
void RecordingTimeTestTask(
@@ -3285,7 +3224,7 @@ void RecordingTimeTestTask(
//
// MaxEQT1 = 500ms is recorded and observed in histogram.
// MaxEQT2 is recorded but not yet in histogram for not being flushed.
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
MaxQueueingTimeMetricRecordedOnlyDuringNavigation) {
base::HistogramTester tester;
// Start with a long task whose queueing time will be ignored.
@@ -3305,7 +3244,7 @@ TEST_P(MainThreadSchedulerImplTest,
}
// Only the max of all the queueing times is recorded.
-TEST_P(MainThreadSchedulerImplTest, MaxQueueingTimeMetricRecordTheMax) {
+TEST_F(MainThreadSchedulerImplTest, MaxQueueingTimeMetricRecordTheMax) {
base::HistogramTester tester;
scheduler_->DidCommitProvisionalLoad(false, false, false);
// The smaller queuing time will be ignored.
@@ -3318,7 +3257,7 @@ TEST_P(MainThreadSchedulerImplTest, MaxQueueingTimeMetricRecordTheMax) {
tester.ExpectUniqueSample("RendererScheduler.MaxQueueingTime", 500, 1);
}
-TEST_P(MainThreadSchedulerImplTest, DidCommitProvisionalLoad) {
+TEST_F(MainThreadSchedulerImplTest, DidCommitProvisionalLoad) {
scheduler_->OnFirstMeaningfulPaint();
EXPECT_FALSE(scheduler_->waiting_for_meaningful_paint());
@@ -3372,7 +3311,7 @@ TEST_P(MainThreadSchedulerImplTest, DidCommitProvisionalLoad) {
EXPECT_TRUE(scheduler_->waiting_for_meaningful_paint()); // State cleared.
}
-TEST_P(MainThreadSchedulerImplTest, LoadingControlTasks) {
+TEST_F(MainThreadSchedulerImplTest, LoadingControlTasks) {
// Expect control loading tasks (M) to jump ahead of any regular loading
// tasks (L).
Vector<String> run_order;
@@ -3382,7 +3321,7 @@ TEST_P(MainThreadSchedulerImplTest, LoadingControlTasks) {
"L4", "L5", "L6"));
}
-TEST_P(MainThreadSchedulerImplTest, RequestBeginMainFrameNotExpected) {
+TEST_F(MainThreadSchedulerImplTest, RequestBeginMainFrameNotExpected) {
std::unique_ptr<PageSchedulerImplForTest> page_scheduler =
std::make_unique<PageSchedulerImplForTest>(scheduler_.get());
scheduler_->AddPageScheduler(page_scheduler.get());
@@ -3404,7 +3343,7 @@ TEST_P(MainThreadSchedulerImplTest, RequestBeginMainFrameNotExpected) {
Mock::VerifyAndClearExpectations(page_scheduler.get());
}
-TEST_P(MainThreadSchedulerImplTest,
+TEST_F(MainThreadSchedulerImplTest,
RequestBeginMainFrameNotExpected_MultipleCalls) {
std::unique_ptr<PageSchedulerImplForTest> page_scheduler =
std::make_unique<PageSchedulerImplForTest>(scheduler_.get());
@@ -3422,7 +3361,7 @@ TEST_P(MainThreadSchedulerImplTest,
}
#if defined(OS_ANDROID)
-TEST_P(MainThreadSchedulerImplTest, PauseTimersForAndroidWebView) {
+TEST_F(MainThreadSchedulerImplTest, PauseTimersForAndroidWebView) {
// Tasks in some queues don't fire when the timers are paused.
Vector<String> run_order;
PostTestTasks(&run_order, "D1 C1 L1 I1 T1");
@@ -3448,20 +3387,12 @@ class MainThreadSchedulerImplWithInitalVirtualTimeTest
nullptr, test_task_runner_, test_task_runner_->GetMockTickClock(),
base::sequence_manager::SequenceManager::Settings::Builder()
.SetRandomisedSamplingEnabled(true)
- .SetAntiStarvationLogicForPrioritiesDisabled(
- GetParam() == AntiStarvationLogic::kDisabled)
.Build()),
base::Time::FromJsTime(1000000.0)));
}
};
-INSTANTIATE_TEST_SUITE_P(All,
- MainThreadSchedulerImplWithInitalVirtualTimeTest,
- testing::Values(AntiStarvationLogic::kEnabled,
- AntiStarvationLogic::kDisabled),
- GetTestNameSuffix);
-
-TEST_P(MainThreadSchedulerImplWithInitalVirtualTimeTest, VirtualTimeOverride) {
+TEST_F(MainThreadSchedulerImplWithInitalVirtualTimeTest, VirtualTimeOverride) {
EXPECT_TRUE(scheduler_->IsVirtualTimeEnabled());
EXPECT_EQ(PageSchedulerImpl::VirtualTimePolicy::kPause,
scheduler_->virtual_time_policy());
@@ -3473,19 +3404,13 @@ class CompositingExperimentWithExplicitSignalsTest
public:
CompositingExperimentWithExplicitSignalsTest()
: MainThreadSchedulerImplTest(
- {kHighPriorityInputOnMainThread, kPrioritizeCompositingAfterInput,
+ {kPrioritizeCompositingAfterInput,
kUseExplicitSignalForTriggeringCompositingPrioritization,
kUseWillBeginMainFrameForCompositingPrioritization},
{}) {}
};
-INSTANTIATE_TEST_SUITE_P(All,
- CompositingExperimentWithExplicitSignalsTest,
- testing::Values(AntiStarvationLogic::kEnabled,
- AntiStarvationLogic::kDisabled),
- GetTestNameSuffix);
-
-TEST_P(CompositingExperimentWithExplicitSignalsTest, CompositingAfterInput) {
+TEST_F(CompositingExperimentWithExplicitSignalsTest, CompositingAfterInput) {
Vector<String> run_order;
PostTestTasks(&run_order, "P1 T1 C1");
base::RunLoop().RunUntilIdle();
@@ -3515,19 +3440,13 @@ class CompositingExperimentWithImplicitSignalsTest
public:
CompositingExperimentWithImplicitSignalsTest()
: MainThreadSchedulerImplTest(
- {kHighPriorityInputOnMainThread, kPrioritizeCompositingAfterInput},
+ {kPrioritizeCompositingAfterInput},
{kHighestPriorityForCompositingAfterInput,
kUseExplicitSignalForTriggeringCompositingPrioritization,
kUseWillBeginMainFrameForCompositingPrioritization}) {}
};
-INSTANTIATE_TEST_SUITE_P(All,
- CompositingExperimentWithImplicitSignalsTest,
- testing::Values(AntiStarvationLogic::kEnabled,
- AntiStarvationLogic::kDisabled),
- GetTestNameSuffix);
-
-TEST_P(CompositingExperimentWithImplicitSignalsTest, CompositingAfterInput) {
+TEST_F(CompositingExperimentWithImplicitSignalsTest, CompositingAfterInput) {
Vector<String> run_order;
PostTestTasks(&run_order, "T1 C1 C2 P1 P2");
base::RunLoop().RunUntilIdle();
@@ -3535,7 +3454,7 @@ TEST_P(CompositingExperimentWithImplicitSignalsTest, CompositingAfterInput) {
EXPECT_THAT(run_order, testing::ElementsAre("P1", "P2", "C1", "T1", "C2"));
}
-TEST_P(MainThreadSchedulerImplTest, EQTWithNestedLoop) {
+TEST_F(MainThreadSchedulerImplTest, EQTWithNestedLoop) {
AdvanceMockTickClockBy(base::TimeDelta::FromMilliseconds(100));
RunTask(base::BindLambdaForTesting([&] {
@@ -3574,7 +3493,7 @@ TEST_P(MainThreadSchedulerImplTest, EQTWithNestedLoop) {
base::TimeDelta::FromMicroseconds(400 + 50 + 50 + 1250)));
}
-TEST_P(MainThreadSchedulerImplTest, TaskQueueReferenceClearedOnShutdown) {
+TEST_F(MainThreadSchedulerImplTest, TaskQueueReferenceClearedOnShutdown) {
// Ensure that the scheduler clears its references to a task queue after
// |shutdown| and doesn't try to update its policies.
scoped_refptr<MainThreadTaskQueue> queue1 = scheduler_->NewTimerTaskQueue(
@@ -3596,7 +3515,7 @@ TEST_P(MainThreadSchedulerImplTest, TaskQueueReferenceClearedOnShutdown) {
EXPECT_EQ(queue2->GetTimeDomain(), scheduler_->GetVirtualTimeDomain());
}
-TEST_P(MainThreadSchedulerImplTest, MicrotaskCheckpointTiming) {
+TEST_F(MainThreadSchedulerImplTest, MicrotaskCheckpointTiming) {
base::RunLoop().RunUntilIdle();
base::TimeTicks start_time = Now();
@@ -3623,7 +3542,7 @@ TEST_P(MainThreadSchedulerImplTest, MicrotaskCheckpointTiming) {
observer.result().front().second);
}
-TEST_P(MainThreadSchedulerImplTest, IsBeginMainFrameScheduled) {
+TEST_F(MainThreadSchedulerImplTest, IsBeginMainFrameScheduled) {
EXPECT_FALSE(scheduler_->IsBeginMainFrameScheduled());
scheduler_->DidScheduleBeginMainFrame();
EXPECT_TRUE(scheduler_->IsBeginMainFrameScheduled());
@@ -3638,6 +3557,119 @@ TEST_P(MainThreadSchedulerImplTest, IsBeginMainFrameScheduled) {
EXPECT_FALSE(scheduler_->IsBeginMainFrameScheduled());
}
+TEST_F(MainThreadSchedulerImplTest, NonWakingTaskQueue) {
+ std::vector<std::pair<std::string, base::TimeTicks>> log;
+ base::TimeTicks start = scheduler_->GetTickClock()->NowTicks();
+
+ scheduler_->DefaultTaskQueue()->task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](std::vector<std::pair<std::string, base::TimeTicks>>* log,
+ const base::TickClock* clock) {
+ log->emplace_back("regular (immediate)", clock->NowTicks());
+ },
+ &log, scheduler_->GetTickClock()));
+ scheduler_->NonWakingTaskRunner()->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](std::vector<std::pair<std::string, base::TimeTicks>>* log,
+ const base::TickClock* clock) {
+ log->emplace_back("non-waking", clock->NowTicks());
+ },
+ &log, scheduler_->GetTickClock()),
+ base::TimeDelta::FromSeconds(3));
+ scheduler_->DefaultTaskQueue()->task_runner()->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](std::vector<std::pair<std::string, base::TimeTicks>>* log,
+ const base::TickClock* clock) {
+ log->emplace_back("regular (delayed)", clock->NowTicks());
+ },
+ &log, scheduler_->GetTickClock()),
+ base::TimeDelta::FromSeconds(5));
+
+ test_task_runner_->FastForwardUntilNoTasksRemain();
+
+ // Check that the non-waking task runner didn't generate an unnecessary
+ // wake-up.
+ // Note: the exact order of these tasks is not fixed and depends on the time
+ // domain iteration order.
+ EXPECT_THAT(
+ log,
+ testing::UnorderedElementsAre(
+ std::make_pair("regular (immediate)", start),
+ std::make_pair("non-waking", start + base::TimeDelta::FromSeconds(5)),
+ std::make_pair("regular (delayed)",
+ start + base::TimeDelta::FromSeconds(5))));
+}
+
+class BestEffortPriorityForFindInPageExperimentTest
+ : public MainThreadSchedulerImplTest {
+ public:
+ BestEffortPriorityForFindInPageExperimentTest()
+ : MainThreadSchedulerImplTest({kBestEffortPriorityForFindInPage}, {}) {}
+};
+
+TEST_F(BestEffortPriorityForFindInPageExperimentTest,
+ FindInPageTasksAreBestEffortPriorityUnderExperiment) {
+ Vector<String> run_order;
+ PostTestTasks(&run_order, "F1 D1 F2 D2 F3 D3");
+ EnableIdleTasks();
+ EXPECT_EQ(scheduler_->find_in_page_priority(),
+ QueuePriority::kBestEffortPriority);
+ base::RunLoop().RunUntilIdle();
+ // Find-in-page tasks have "best-effort" priority, so they will be done after
+ // the default tasks (which have normal priority).
+ EXPECT_THAT(run_order,
+ testing::ElementsAre("D1", "D2", "D3", "F1", "F2", "F3"));
+}
+
+TEST_F(MainThreadSchedulerImplTest, FindInPageTasksAreVeryHighPriority) {
+ Vector<String> run_order;
+ PostTestTasks(&run_order, "D1 D2 D3 F1 F2 F3");
+ EnableIdleTasks();
+ EXPECT_EQ(
+ scheduler_->find_in_page_priority(),
+ FindInPageBudgetPoolController::kFindInPageBudgetNotExhaustedPriority);
+ base::RunLoop().RunUntilIdle();
+ // Find-in-page tasks have very high task priority, so we will do them before
+ // the default tasks.
+ EXPECT_THAT(run_order,
+ testing::ElementsAre("F1", "F2", "F3", "D1", "D2", "D3"));
+}
+
+TEST_F(MainThreadSchedulerImplTest, FindInPageTasksChangeToNormalPriority) {
+ EXPECT_EQ(
+ scheduler_->find_in_page_priority(),
+ FindInPageBudgetPoolController::kFindInPageBudgetNotExhaustedPriority);
+ EnableIdleTasks();
+ // Simulate a really long find-in-page task that takes 30% of CPU time
+ // (300ms out of 1000 ms).
+ base::TimeTicks task_start_time = Now();
+ base::TimeTicks task_end_time =
+ task_start_time + base::TimeDelta::FromMilliseconds(300);
+ FakeTask fake_task;
+ fake_task.set_enqueue_order(
+ base::sequence_manager::EnqueueOrder::FromIntForTesting(42));
+ FakeTaskTiming task_timing(task_start_time, task_end_time);
+ scheduler_->OnTaskStarted(find_in_page_task_queue(), fake_task, task_timing);
+ AdvanceMockTickClockTo(task_start_time +
+ base::TimeDelta::FromMilliseconds(1000));
+ scheduler_->OnTaskCompleted(find_in_page_task_queue()->AsWeakPtr(), fake_task,
+ &task_timing, nullptr);
+
+ // Now the find-in-page tasks have normal priority (same priority as default
+ // tasks, so we will do them in order).
+ EXPECT_EQ(scheduler_->find_in_page_priority(),
+ FindInPageBudgetPoolController::kFindInPageBudgetExhaustedPriority);
+ Vector<String> run_order;
+ PostTestTasks(&run_order, "D1 D2 F1 F2 D3 F3");
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_THAT(run_order,
+ testing::ElementsAre("D1", "D2", "F1", "F2", "D3", "F3"));
+}
+
class VeryHighPriorityForCompositingAlwaysExperimentTest
: public MainThreadSchedulerImplTest {
public:
@@ -3646,13 +3678,7 @@ class VeryHighPriorityForCompositingAlwaysExperimentTest
{}) {}
};
-INSTANTIATE_TEST_SUITE_P(All,
- VeryHighPriorityForCompositingAlwaysExperimentTest,
- testing::Values(AntiStarvationLogic::kEnabled,
- AntiStarvationLogic::kDisabled),
- GetTestNameSuffix);
-
-TEST_P(VeryHighPriorityForCompositingAlwaysExperimentTest,
+TEST_F(VeryHighPriorityForCompositingAlwaysExperimentTest,
TestCompositorPolicy) {
Vector<String> run_order;
PostTestTasks(&run_order, "I1 D1 C1 D2 C2 P1");
@@ -3672,13 +3698,7 @@ class VeryHighPriorityForCompositingWhenFastExperimentTest
{}) {}
};
-INSTANTIATE_TEST_SUITE_P(All,
- VeryHighPriorityForCompositingWhenFastExperimentTest,
- testing::Values(AntiStarvationLogic::kEnabled,
- AntiStarvationLogic::kDisabled),
- GetTestNameSuffix);
-
-TEST_P(VeryHighPriorityForCompositingWhenFastExperimentTest,
+TEST_F(VeryHighPriorityForCompositingWhenFastExperimentTest,
TestCompositorPolicy_FastCompositing) {
Vector<String> run_order;
PostTestTasks(&run_order, "I1 D1 C1 D2 C2 P1");
@@ -3690,7 +3710,7 @@ TEST_P(VeryHighPriorityForCompositingWhenFastExperimentTest,
EXPECT_EQ(UseCase::kNone, CurrentUseCase());
}
-TEST_P(VeryHighPriorityForCompositingWhenFastExperimentTest,
+TEST_F(VeryHighPriorityForCompositingWhenFastExperimentTest,
TestCompositorPolicy_SlowCompositing) {
RunSlowCompositorTask();
Vector<String> run_order;
@@ -3703,7 +3723,7 @@ TEST_P(VeryHighPriorityForCompositingWhenFastExperimentTest,
EXPECT_EQ(UseCase::kNone, CurrentUseCase());
}
-TEST_P(VeryHighPriorityForCompositingWhenFastExperimentTest,
+TEST_F(VeryHighPriorityForCompositingWhenFastExperimentTest,
TestCompositorPolicy_CompositingStaysAtHighest) {
Vector<String> run_order;
PostTestTasks(&run_order, "L1 I1 D1 C1 D2 P1 C2");
@@ -3727,14 +3747,7 @@ class VeryHighPriorityForCompositingAlternatingExperimentTest
{}) {}
};
-INSTANTIATE_TEST_SUITE_P(
- All,
- VeryHighPriorityForCompositingAlternatingExperimentTest,
- testing::Values(AntiStarvationLogic::kEnabled,
- AntiStarvationLogic::kDisabled),
- GetTestNameSuffix);
-
-TEST_P(VeryHighPriorityForCompositingAlternatingExperimentTest,
+TEST_F(VeryHighPriorityForCompositingAlternatingExperimentTest,
TestCompositorPolicy_AlternatingCompositorTasks) {
Vector<String> run_order;
PostTestTasks(&run_order, "D1 D2 D3 C1 C2 C3");
@@ -3746,7 +3759,7 @@ TEST_P(VeryHighPriorityForCompositingAlternatingExperimentTest,
EXPECT_EQ(UseCase::kNone, CurrentUseCase());
}
-TEST_P(VeryHighPriorityForCompositingAlternatingExperimentTest,
+TEST_F(VeryHighPriorityForCompositingAlternatingExperimentTest,
TestCompositorPolicy_AlternatingCompositorStaysAtHighest) {
Vector<String> run_order;
PostTestTasks(&run_order, "D1 D2 D3 C1 C2 C3");
@@ -3769,13 +3782,7 @@ class VeryHighPriorityForCompositingAfterDelayExperimentTest
{}) {}
};
-INSTANTIATE_TEST_SUITE_P(All,
- VeryHighPriorityForCompositingAfterDelayExperimentTest,
- testing::Values(AntiStarvationLogic::kEnabled,
- AntiStarvationLogic::kDisabled),
- GetTestNameSuffix);
-
-TEST_P(VeryHighPriorityForCompositingAfterDelayExperimentTest,
+TEST_F(VeryHighPriorityForCompositingAfterDelayExperimentTest,
TestCompositorPolicy_CompositorStaysAtNormalPriority) {
Vector<String> run_order;
PostTestTasks(&run_order, "I1 D1 C1 D2 C2 P1");
@@ -3787,7 +3794,7 @@ TEST_P(VeryHighPriorityForCompositingAfterDelayExperimentTest,
EXPECT_EQ(UseCase::kNone, CurrentUseCase());
}
-TEST_P(VeryHighPriorityForCompositingAfterDelayExperimentTest,
+TEST_F(VeryHighPriorityForCompositingAfterDelayExperimentTest,
TestCompositorPolicy_FirstCompositorTaskSetToVeryHighPriority) {
// 150ms task to complete the countdown and prioritze compositing.
AdvanceTimeWithTask(0.15);
@@ -3802,7 +3809,7 @@ TEST_P(VeryHighPriorityForCompositingAfterDelayExperimentTest,
EXPECT_EQ(UseCase::kNone, CurrentUseCase());
}
-TEST_P(VeryHighPriorityForCompositingAfterDelayExperimentTest,
+TEST_F(VeryHighPriorityForCompositingAfterDelayExperimentTest,
TestCompositorPolicy_FirstCompositorTaskStaysAtNormalPriority) {
// 0.5ms task should not prioritize compositing.
AdvanceTimeWithTask(0.05);
@@ -3825,13 +3832,7 @@ class VeryHighPriorityForCompositingBudgetExperimentTest
{}) {}
};
-INSTANTIATE_TEST_SUITE_P(All,
- VeryHighPriorityForCompositingBudgetExperimentTest,
- testing::Values(AntiStarvationLogic::kEnabled,
- AntiStarvationLogic::kDisabled),
- GetTestNameSuffix);
-
-TEST_P(VeryHighPriorityForCompositingBudgetExperimentTest,
+TEST_F(VeryHighPriorityForCompositingBudgetExperimentTest,
TestCompositorPolicy_CompositorPriorityVeryHighToNormal) {
Vector<String> run_order;
PostTestTasks(&run_order, "I1 D1 C1 D2 C2 P1");
@@ -3858,7 +3859,7 @@ TEST_P(VeryHighPriorityForCompositingBudgetExperimentTest,
EXPECT_EQ(UseCase::kNone, CurrentUseCase());
}
-TEST_P(VeryHighPriorityForCompositingBudgetExperimentTest,
+TEST_F(VeryHighPriorityForCompositingBudgetExperimentTest,
TestCompositorPolicy_CompositorPriorityNormalToVeryHigh) {
// 1000ms compositor task will exhaust the budget.
RunSlowCompositorTask();
@@ -3897,14 +3898,7 @@ class VeryHighPriorityForCompositingAlternatingBeginMainFrameExperimentTest
{}) {}
};
-INSTANTIATE_TEST_SUITE_P(
- ,
- VeryHighPriorityForCompositingAlternatingBeginMainFrameExperimentTest,
- testing::Values(AntiStarvationLogic::kEnabled,
- AntiStarvationLogic::kDisabled),
- GetTestNameSuffix);
-
-TEST_P(VeryHighPriorityForCompositingAlternatingBeginMainFrameExperimentTest,
+TEST_F(VeryHighPriorityForCompositingAlternatingBeginMainFrameExperimentTest,
TestCompositorPolicy_AlternatingCompositorTasks) {
Vector<String> run_order;
PostTestTasks(&run_order, "C1 D1 C2 D2");
@@ -3934,14 +3928,7 @@ class VeryHighPriorityForCompositingAfterDelayUntilBeginMainFrameExperimentTest
{}) {}
};
-INSTANTIATE_TEST_SUITE_P(
- ,
- VeryHighPriorityForCompositingAfterDelayUntilBeginMainFrameExperimentTest,
- testing::Values(AntiStarvationLogic::kEnabled,
- AntiStarvationLogic::kDisabled),
- GetTestNameSuffix);
-
-TEST_P(
+TEST_F(
VeryHighPriorityForCompositingAfterDelayUntilBeginMainFrameExperimentTest,
TestCompositorPolicy_FirstCompositorTaskSetToVeryHighPriority) {
// 150ms task to complete the countdown and prioritze compositing.
@@ -3973,14 +3960,7 @@ class VeryHighPriorityForCompositingBudgetBeginMainFrameExperimentTest
{}) {}
};
-INSTANTIATE_TEST_SUITE_P(
- ,
- VeryHighPriorityForCompositingBudgetBeginMainFrameExperimentTest,
- testing::Values(AntiStarvationLogic::kEnabled,
- AntiStarvationLogic::kDisabled),
- GetTestNameSuffix);
-
-TEST_P(
+TEST_F(
VeryHighPriorityForCompositingBudgetBeginMainFrameExperimentTest,
TestCompositorPolicy_CompositorPriorityNonBeginMainFrameDoesntExhaustBudget) {
// 1000ms compositor task will not exhaust the budget.
@@ -3994,7 +3974,7 @@ TEST_P(
EXPECT_EQ(UseCase::kNone, CurrentUseCase());
}
-TEST_P(VeryHighPriorityForCompositingBudgetBeginMainFrameExperimentTest,
+TEST_F(VeryHighPriorityForCompositingBudgetBeginMainFrameExperimentTest,
TestCompositorPolicy_CompositorPriorityBeginMainFrameExhaustsBudget) {
// 1000ms BeginMainFrame will exhaust the budget.
DoMainFrame();
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc
index d008643dc43..0d54d317672 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc
@@ -63,6 +63,8 @@ const char* MainThreadTaskQueue::NameForQueueType(
return "other_tq";
case MainThreadTaskQueue::QueueType::kWebScheduling:
return "web_scheduling_tq";
+ case MainThreadTaskQueue::QueueType::kNonWaking:
+ return "non_waking_tq";
case MainThreadTaskQueue::QueueType::kCount:
NOTREACHED();
return nullptr;
@@ -95,6 +97,7 @@ bool MainThreadTaskQueue::IsPerFrameTaskQueue(
case MainThreadTaskQueue::QueueType::kInput:
case MainThreadTaskQueue::QueueType::kDetached:
case MainThreadTaskQueue::QueueType::kCleanup:
+ case MainThreadTaskQueue::QueueType::kNonWaking:
case MainThreadTaskQueue::QueueType::kOther:
return false;
case MainThreadTaskQueue::QueueType::kCount:
@@ -114,6 +117,7 @@ MainThreadTaskQueue::QueueClass MainThreadTaskQueue::QueueClassForQueueType(
case QueueType::kTest:
case QueueType::kV8:
case QueueType::kIPC:
+ case QueueType::kNonWaking:
case QueueType::kCleanup:
return QueueClass::kNone;
case QueueType::kFrameLoading:
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 c1ea93cd184..b9c51d21ea8 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
@@ -76,10 +76,11 @@ class PLATFORM_EXPORT MainThreadTaskQueue
// 22 : kWebSchedulingBestEffort, obsolete.
kWebScheduling = 24,
+ kNonWaking = 25,
// Used to group multiple types when calculating Expected Queueing Time.
kOther = 23,
- kCount = 25
+ kCount = 26
};
// Returns name of the given queue type. Returned string has application
@@ -123,13 +124,14 @@ class PLATFORM_EXPORT MainThreadTaskQueue
// Separate enum class for handling prioritisation decisions in task queues.
enum class PrioritisationType {
kVeryHigh = 0,
- kHigh = 1,
- kBestEffort = 2,
- kRegular = 3,
- kLoading = 4,
- kLoadingControl = 5,
-
- kCount = 6
+ kBestEffort = 1,
+ kRegular = 2,
+ kLoading = 3,
+ kLoadingControl = 4,
+ kFindInPage = 5,
+ kExperimentalDatabase = 6,
+
+ kCount = 7
};
// kPrioritisationTypeWidthBits is the number of bits required
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager.cc
index 811cc0cb55f..07afb6e13a7 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager.cc
@@ -76,6 +76,10 @@ void MemoryPurgeManager::OnPageDestroyed(PageLifecycleState state) {
total_page_count_--;
if (state == PageLifecycleState::kFrozen)
frozen_page_count_--;
+
+ if (!CanPurge())
+ purge_timer_.Stop();
+
DCHECK_LE(frozen_page_count_, total_page_count_);
}
@@ -110,6 +114,10 @@ void MemoryPurgeManager::OnRendererBackgrounded() {
if (!base::FeatureList::IsEnabled(
features::kPurgeRendererMemoryWhenBackgrounded))
return;
+ // A spare renderer has no pages. We would like to avoid purging memory
+ // on a spare renderer.
+ if (total_page_count_ == 0)
+ return;
backgrounded_purge_pending_ = true;
RequestMemoryPurgeWithDelay(GetTimeToPurgeAfterBackgrounded());
@@ -145,6 +153,9 @@ void MemoryPurgeManager::PerformMemoryPurge() {
}
bool MemoryPurgeManager::CanPurge() const {
+ if (total_page_count_ == 0)
+ return false;
+
if (backgrounded_purge_pending_)
return true;
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 3293c3151d3..3dea63c3bbb 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
@@ -25,8 +25,7 @@ class MemoryPurgeManagerTest : public testing::Test {
MemoryPurgeManagerTest()
: task_environment_(base::test::TaskEnvironment::MainThreadType::UI,
base::test::TaskEnvironment::TimeSource::MOCK_TIME),
- memory_purge_manager_(task_environment_.GetMainThreadTaskRunner()),
- observed_memory_pressure_(false) {}
+ memory_purge_manager_(task_environment_.GetMainThreadTaskRunner()) {}
void SetUp() override {
memory_pressure_listener_ =
@@ -49,34 +48,23 @@ class MemoryPurgeManagerTest : public testing::Test {
{features::kPurgeRendererMemoryWhenBackgrounded});
}
- void ExpectMemoryPressure(
- base::TimeDelta delay = base::TimeDelta::FromMinutes(0)) {
- FastForwardBy(delay);
- EXPECT_TRUE(observed_memory_pressure_);
- observed_memory_pressure_ = false;
- }
-
- void ExpectNoMemoryPressure(
- base::TimeDelta delay = base::TimeDelta::FromMinutes(0)) {
- FastForwardBy(delay);
- EXPECT_FALSE(observed_memory_pressure_);
- }
-
void FastForwardBy(base::TimeDelta delta) {
task_environment_.FastForwardBy(delta);
}
+ unsigned MemoryPressureCount() const { return memory_pressure_count_; }
+
base::test::ScopedFeatureList scoped_feature_list_;
base::test::TaskEnvironment task_environment_;
std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
MemoryPurgeManager memory_purge_manager_;
- bool observed_memory_pressure_;
+ unsigned memory_pressure_count_ = 0;
private:
void OnMemoryPressure(base::MemoryPressureListener::MemoryPressureLevel) {
- observed_memory_pressure_ = true;
+ memory_pressure_count_++;
}
DISALLOW_COPY_AND_ASSIGN(MemoryPurgeManagerTest);
@@ -92,7 +80,8 @@ TEST_F(MemoryPurgeManagerTest, PageFrozenInBackgroundedRenderer) {
memory_purge_manager_.OnPageCreated(PageLifecycleState::kActive);
memory_purge_manager_.SetRendererBackgrounded(true);
memory_purge_manager_.OnPageFrozen();
- ExpectMemoryPressure();
+ FastForwardBy(base::TimeDelta::FromMinutes(0));
+ EXPECT_EQ(1U, MemoryPressureCount());
}
// Verify that OnPageFrozen() does not trigger a memory pressure notification in
@@ -105,7 +94,8 @@ TEST_F(MemoryPurgeManagerTest, PageFrozenInForegroundedRenderer) {
memory_purge_manager_.OnPageCreated(PageLifecycleState::kActive);
memory_purge_manager_.SetRendererBackgrounded(false);
memory_purge_manager_.OnPageFrozen();
- ExpectNoMemoryPressure();
+ FastForwardBy(base::TimeDelta::FromMinutes(0));
+ EXPECT_EQ(0U, MemoryPressureCount());
}
TEST_F(MemoryPurgeManagerTest, PageResumedUndoMemoryPressureSuppression) {
@@ -117,7 +107,9 @@ TEST_F(MemoryPurgeManagerTest, PageResumedUndoMemoryPressureSuppression) {
memory_purge_manager_.SetRendererBackgrounded(true);
memory_purge_manager_.OnPageFrozen();
- ExpectMemoryPressure();
+ FastForwardBy(base::TimeDelta::FromMinutes(0));
+ EXPECT_EQ(1U, MemoryPressureCount());
+
EXPECT_TRUE(base::MemoryPressureListener::AreNotificationsSuppressed());
memory_purge_manager_.OnPageResumed();
EXPECT_FALSE(base::MemoryPressureListener::AreNotificationsSuppressed());
@@ -139,15 +131,18 @@ TEST_F(MemoryPurgeManagerTest, PageFrozenPurgeMemoryAllPagesFrozenDisabled) {
memory_purge_manager_.OnPageCreated(PageLifecycleState::kActive);
memory_purge_manager_.OnPageFrozen();
- ExpectMemoryPressure();
+ FastForwardBy(base::TimeDelta::FromMinutes(0));
+ EXPECT_EQ(1U, MemoryPressureCount());
EXPECT_FALSE(base::MemoryPressureListener::AreNotificationsSuppressed());
memory_purge_manager_.OnPageFrozen();
- ExpectMemoryPressure();
+ FastForwardBy(base::TimeDelta::FromMinutes(0));
+ EXPECT_EQ(2U, MemoryPressureCount());
EXPECT_FALSE(base::MemoryPressureListener::AreNotificationsSuppressed());
memory_purge_manager_.OnPageFrozen();
- ExpectMemoryPressure();
+ FastForwardBy(base::TimeDelta::FromMinutes(0));
+ EXPECT_EQ(3U, MemoryPressureCount());
EXPECT_TRUE(base::MemoryPressureListener::AreNotificationsSuppressed());
memory_purge_manager_.OnPageResumed();
@@ -177,15 +172,18 @@ TEST_F(MemoryPurgeManagerTest, PageFrozenPurgeMemoryAllPagesFrozenEnabled) {
memory_purge_manager_.OnPageCreated(PageLifecycleState::kActive);
memory_purge_manager_.OnPageFrozen();
- ExpectNoMemoryPressure();
+ FastForwardBy(base::TimeDelta::FromMinutes(0));
+ EXPECT_EQ(0U, MemoryPressureCount());
EXPECT_FALSE(base::MemoryPressureListener::AreNotificationsSuppressed());
memory_purge_manager_.OnPageFrozen();
- ExpectNoMemoryPressure();
+ FastForwardBy(base::TimeDelta::FromMinutes(0));
+ EXPECT_EQ(0U, MemoryPressureCount());
EXPECT_FALSE(base::MemoryPressureListener::AreNotificationsSuppressed());
memory_purge_manager_.OnPageFrozen();
- ExpectMemoryPressure();
+ FastForwardBy(base::TimeDelta::FromMinutes(0));
+ EXPECT_EQ(1U, MemoryPressureCount());
EXPECT_TRUE(base::MemoryPressureListener::AreNotificationsSuppressed());
memory_purge_manager_.OnPageResumed();
@@ -211,10 +209,12 @@ TEST_F(MemoryPurgeManagerTest, MemoryPurgeWithDelay) {
memory_purge_manager_.OnPageFrozen();
// The memory pressure notification should not occur immediately
- ExpectNoMemoryPressure();
+ FastForwardBy(base::TimeDelta::FromMinutes(0));
+ EXPECT_EQ(0U, MemoryPressureCount());
// The memory pressure notification should occur after 1 minute
- ExpectMemoryPressure(kDelayForPurgeAfterFreeze);
+ FastForwardBy(kDelayForPurgeAfterFreeze);
+ EXPECT_EQ(1U, MemoryPressureCount());
memory_purge_manager_.OnPageDestroyed(PageLifecycleState::kFrozen);
}
@@ -227,12 +227,13 @@ TEST_F(MemoryPurgeManagerTest, CancelMemoryPurgeWithDelay) {
memory_purge_manager_.SetRendererBackgrounded(true);
memory_purge_manager_.OnPageFrozen();
FastForwardBy(base::TimeDelta::FromSeconds(40));
- ExpectNoMemoryPressure();
+ EXPECT_EQ(0U, MemoryPressureCount());
// If the page is resumed before the memory purge timer expires, the purge
// should be cancelled.
memory_purge_manager_.OnPageResumed();
- ExpectNoMemoryPressure(kDelayForPurgeAfterFreeze);
+ FastForwardBy(base::TimeDelta::FromMinutes(0));
+ EXPECT_EQ(0U, MemoryPressureCount());
memory_purge_manager_.OnPageDestroyed(PageLifecycleState::kActive);
}
@@ -245,11 +246,12 @@ TEST_F(MemoryPurgeManagerTest, MemoryPurgeWithDelayNewActivePageCreated) {
memory_purge_manager_.SetRendererBackgrounded(true);
memory_purge_manager_.OnPageFrozen();
FastForwardBy(base::TimeDelta::FromSeconds(40));
- ExpectNoMemoryPressure();
+ EXPECT_EQ(0U, MemoryPressureCount());
// All pages are no longer frozen, the memory purge should be cancelled.
memory_purge_manager_.OnPageCreated(PageLifecycleState::kActive);
- ExpectNoMemoryPressure(kDelayForPurgeAfterFreeze);
+ FastForwardBy(kDelayForPurgeAfterFreeze);
+ EXPECT_EQ(0U, MemoryPressureCount());
memory_purge_manager_.OnPageDestroyed(PageLifecycleState::kFrozen);
memory_purge_manager_.OnPageDestroyed(PageLifecycleState::kActive);
@@ -263,11 +265,12 @@ TEST_F(MemoryPurgeManagerTest, MemoryPurgeWithDelayNewFrozenPageCreated) {
memory_purge_manager_.SetRendererBackgrounded(true);
memory_purge_manager_.OnPageFrozen();
FastForwardBy(base::TimeDelta::FromSeconds(40));
- ExpectNoMemoryPressure();
+ EXPECT_EQ(0U, MemoryPressureCount());
// All pages are still frozen and the memory purge should occur.
memory_purge_manager_.OnPageCreated(PageLifecycleState::kFrozen);
- ExpectMemoryPressure(kDelayForPurgeAfterFreeze);
+ FastForwardBy(kDelayForPurgeAfterFreeze);
+ EXPECT_EQ(1U, MemoryPressureCount());
memory_purge_manager_.OnPageDestroyed(PageLifecycleState::kFrozen);
memory_purge_manager_.OnPageDestroyed(PageLifecycleState::kFrozen);
@@ -281,7 +284,8 @@ TEST_F(MemoryPurgeManagerTest, PurgeRendererMemoryWhenBackgroundedEnabled) {
memory_purge_manager_.SetRendererBackgrounded(true);
FastForwardBy(base::TimeDelta::FromMinutes(
MemoryPurgeManager::kDefaultMaxTimeToPurgeAfterBackgrounded));
- ExpectMemoryPressure();
+ // No page, no memory pressure.
+ EXPECT_EQ(0U, MemoryPressureCount());
}
TEST_F(MemoryPurgeManagerTest, PurgeRendererMemoryWhenBackgroundedDisabled) {
@@ -291,7 +295,7 @@ TEST_F(MemoryPurgeManagerTest, PurgeRendererMemoryWhenBackgroundedDisabled) {
memory_purge_manager_.SetRendererBackgrounded(true);
FastForwardBy(base::TimeDelta::Max());
- ExpectNoMemoryPressure();
+ EXPECT_EQ(0U, MemoryPressureCount());
}
TEST_F(MemoryPurgeManagerTest,
@@ -302,11 +306,11 @@ TEST_F(MemoryPurgeManagerTest,
memory_purge_manager_.SetRendererBackgrounded(true);
FastForwardBy(base::TimeDelta::FromSeconds(30));
- ExpectNoMemoryPressure();
+ EXPECT_EQ(0U, MemoryPressureCount());
memory_purge_manager_.SetRendererBackgrounded(false);
FastForwardBy(base::TimeDelta::Max());
- ExpectNoMemoryPressure();
+ EXPECT_EQ(0U, MemoryPressureCount());
}
TEST_F(MemoryPurgeManagerTest, PageFrozenAndResumedWhileBackgrounded) {
@@ -329,7 +333,8 @@ TEST_F(MemoryPurgeManagerTest, PageFrozenAndResumedWhileBackgrounded) {
memory_purge_manager_.SetRendererBackgrounded(true);
memory_purge_manager_.OnPageFrozen();
FastForwardBy(kBeforeBackgroundPurgeDelay);
- ExpectNoMemoryPressure();
+ EXPECT_EQ(0U, MemoryPressureCount());
+
memory_purge_manager_.OnPageResumed();
FastForwardBy(
base::TimeDelta::FromMinutes(
@@ -337,7 +342,7 @@ TEST_F(MemoryPurgeManagerTest, PageFrozenAndResumedWhileBackgrounded) {
kBeforeBackgroundPurgeDelay);
// Since the renderer is still backgrounded, the memory purge should happen
// even though there are no frozen pages.
- ExpectMemoryPressure();
+ EXPECT_EQ(1U, MemoryPressureCount());
memory_purge_manager_.OnPageDestroyed(PageLifecycleState::kActive);
}
@@ -357,10 +362,12 @@ TEST_F(MemoryPurgeManagerTest,
memory_purge_manager_.SetRendererBackgrounded(true);
memory_purge_manager_.OnPageFrozen();
- ExpectMemoryPressure(base::TimeDelta::FromMinutes(
+ FastForwardBy(base::TimeDelta::FromMinutes(
MemoryPurgeManager::kDefaultMaxTimeToPurgeAfterBackgrounded));
+ EXPECT_EQ(1U, MemoryPressureCount());
+
FastForwardBy(kFreezePurgeDelay);
- ExpectNoMemoryPressure();
+ EXPECT_EQ(1U, MemoryPressureCount());
memory_purge_manager_.OnPageDestroyed(PageLifecycleState::kFrozen);
}
@@ -380,11 +387,29 @@ TEST_F(MemoryPurgeManagerTest,
memory_purge_manager_.SetRendererBackgrounded(true);
memory_purge_manager_.OnPageFrozen();
- ExpectMemoryPressure(kFreezePurgeDelay);
+ FastForwardBy(kFreezePurgeDelay);
+ EXPECT_EQ(1U, MemoryPressureCount());
+
FastForwardBy(base::TimeDelta::Max());
- ExpectNoMemoryPressure();
+ EXPECT_EQ(1U, MemoryPressureCount());
+
+ memory_purge_manager_.OnPageDestroyed(PageLifecycleState::kFrozen);
+}
+
+TEST_F(MemoryPurgeManagerTest, NoMemoryPurgeIfNoPage) {
+ scoped_feature_list_.InitWithFeatures(
+ {features::kFreezePurgeMemoryAllPagesFrozen} /* enabled */,
+ {features::kPurgeRendererMemoryWhenBackgrounded} /* disabled */);
+ memory_purge_manager_.SetRendererBackgrounded(true);
+ memory_purge_manager_.OnPageCreated(PageLifecycleState::kActive);
+
+ memory_purge_manager_.SetRendererBackgrounded(true);
+ memory_purge_manager_.OnPageFrozen();
memory_purge_manager_.OnPageDestroyed(PageLifecycleState::kFrozen);
+
+ FastForwardBy(base::TimeDelta::FromMinutes(0));
+ EXPECT_EQ(0U, MemoryPressureCount());
}
} // namespace
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/non_waking_time_domain.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/non_waking_time_domain.cc
new file mode 100644
index 00000000000..13d6f4a9871
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/non_waking_time_domain.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/platform/scheduler/main_thread/non_waking_time_domain.h"
+
+namespace blink {
+namespace scheduler {
+
+NonWakingTimeDomain::NonWakingTimeDomain(const base::TickClock* tick_clock)
+ : tick_clock_(tick_clock) {}
+
+NonWakingTimeDomain::~NonWakingTimeDomain() = default;
+
+base::sequence_manager::LazyNow NonWakingTimeDomain::CreateLazyNow() const {
+ return base::sequence_manager::LazyNow(tick_clock_);
+}
+
+base::TimeTicks NonWakingTimeDomain::Now() const {
+ return tick_clock_->NowTicks();
+}
+
+base::Optional<base::TimeDelta> NonWakingTimeDomain::DelayTillNextTask(
+ base::sequence_manager::LazyNow* lazy_now) {
+ // NonWakingTimeDomain should never generate wakeups on its own.
+ return base::nullopt;
+}
+
+bool NonWakingTimeDomain::MaybeFastForwardToNextTask(
+ bool quit_when_idle_requested) {
+ return false;
+}
+
+const char* NonWakingTimeDomain::GetName() const {
+ return "non_waking_time_domain";
+}
+
+void NonWakingTimeDomain::SetNextDelayedDoWork(
+ base::sequence_manager::LazyNow* lazy_now,
+ base::TimeTicks run_time) {
+ // Do not request a wake-up, unlike a regular TimeDomain.
+}
+
+} // namespace scheduler
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/non_waking_time_domain.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/non_waking_time_domain.h
new file mode 100644
index 00000000000..9641ed9aa1b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/non_waking_time_domain.h
@@ -0,0 +1,38 @@
+// 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_NON_WAKING_TIME_DOMAIN_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_NON_WAKING_TIME_DOMAIN_H_
+
+#include "base/task/sequence_manager/time_domain.h"
+#include "base/time/tick_clock.h"
+
+namespace blink {
+namespace scheduler {
+
+// A time domain which never generates wake-ups on its own. Useful for tasks
+// which should run only when the system is non-idle.
+class NonWakingTimeDomain : public base::sequence_manager::TimeDomain {
+ public:
+ explicit NonWakingTimeDomain(const base::TickClock* tick_clock);
+ ~NonWakingTimeDomain() override;
+
+ // TimeDomain:
+ base::sequence_manager::LazyNow CreateLazyNow() const override;
+ base::TimeTicks Now() const override;
+ base::Optional<base::TimeDelta> DelayTillNextTask(
+ base::sequence_manager::LazyNow* lazy_now) override;
+ bool MaybeFastForwardToNextTask(bool quit_when_idle_requested) override;
+ const char* GetName() const override;
+ void SetNextDelayedDoWork(base::sequence_manager::LazyNow* lazy_now,
+ base::TimeTicks run_time) override;
+
+ private:
+ const base::TickClock* tick_clock_;
+};
+
+} // namespace scheduler
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_NON_WAKING_TIME_DOMAIN_H_
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/pending_user_input.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/pending_user_input.h
index 64608d7eebb..62498217237 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/pending_user_input.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/pending_user_input.h
@@ -7,7 +7,7 @@
#include <array>
-#include "third_party/blink/public/platform/web_input_event.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/renderer/platform/scheduler/public/pending_user_input_type.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc
index 46cbd2b9c41..98927259f7b 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc
@@ -107,6 +107,8 @@ const char* TaskTypeNames::TaskTypeToString(TaskType task_type) {
return "MainThreadTaskQueueCleanup";
case TaskType::kMainThreadTaskQueueMemoryPurge:
return "MainThreadTaskQueueMemoryPurge";
+ case TaskType::kMainThreadTaskQueueNonWaking:
+ return "MainThreadTaskQueueNonWaking";
case TaskType::kInternalIntersectionObserver:
return "InternalIntersectionObserver";
case TaskType::kCompositorThreadTaskQueueDefault:
@@ -135,6 +137,8 @@ const char* TaskTypeNames::TaskTypeToString(TaskType task_type) {
return "ExperimentalWebScheduling";
case TaskType::kInternalFrameLifecycleControl:
return "InternalFrameLifecycleControl";
+ case TaskType::kInternalFindInPage:
+ return "InternalFindInPage";
case TaskType::kCount:
return "Count";
}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.cc
index 361b57ef706..0b04962ea63 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.cc
@@ -11,7 +11,6 @@ UserModel::UserModel()
: pending_input_event_count_(0),
is_gesture_active_(false),
is_gesture_expected_(false) {}
-UserModel::~UserModel() = default;
void UserModel::DidStartProcessingInputEvent(blink::WebInputEvent::Type type,
const base::TimeTicks now) {
@@ -99,8 +98,7 @@ bool UserModel::IsGestureExpectedSoonImpl(
base::TimeDelta::FromMilliseconds(kExpectSubsequentGestureMillis);
return true;
} else {
- // If we've have a finished a gesture then a subsequent gesture is deemed
- // likely.
+ // If we have finished a gesture then a subsequent gesture is deemed likely.
base::TimeDelta expect_subsequent_gesture_for =
base::TimeDelta::FromMilliseconds(kExpectSubsequentGestureMillis);
if (last_continuous_gesture_time_.is_null() ||
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.h
index e29de4b9202..fb7d2b79468 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.h
@@ -8,8 +8,8 @@
#include "base/macros.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/traced_value.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
-#include "third_party/blink/public/platform/web_input_event.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -21,7 +21,6 @@ class PLATFORM_EXPORT UserModel {
public:
UserModel();
- ~UserModel();
// Tells us that the system started processing an input event. Must be paired
// with a call to DidFinishProcessingInputEvent.
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 c3c98447ec4..d680bb7669a 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
@@ -8,45 +8,33 @@ namespace blink {
namespace {
-const AtomicString& ImmediatePriorityKeyword() {
- DEFINE_STATIC_LOCAL(const AtomicString, immediate_priority, ("immediate"));
- return immediate_priority;
+const AtomicString& UserBlockingPriorityKeyword() {
+ DEFINE_STATIC_LOCAL(const AtomicString, user_blocking_priority,
+ ("user-blocking"));
+ return user_blocking_priority;
}
-const AtomicString& HighPriorityKeyword() {
- DEFINE_STATIC_LOCAL(const AtomicString, high_priority, ("high"));
- return high_priority;
+const AtomicString& UserVisiblePriorityKeyword() {
+ DEFINE_STATIC_LOCAL(const AtomicString, user_visible_priority,
+ ("user-visible"));
+ return user_visible_priority;
}
-const AtomicString& DefaultPriorityKeyword() {
- DEFINE_STATIC_LOCAL(const AtomicString, default_priority, ("default"));
- return default_priority;
-}
-
-const AtomicString& LowPriorityKeyword() {
- DEFINE_STATIC_LOCAL(const AtomicString, low_priority, ("low"));
- return low_priority;
-}
-
-const AtomicString& IdlePriorityKeyword() {
- DEFINE_STATIC_LOCAL(const AtomicString, idle_priority, ("idle"));
- return idle_priority;
+const AtomicString& BackgroundPriorityKeyword() {
+ DEFINE_STATIC_LOCAL(const AtomicString, background_priority, ("background"));
+ return background_priority;
}
} // namespace
AtomicString WebSchedulingPriorityToString(WebSchedulingPriority priority) {
switch (priority) {
- case WebSchedulingPriority::kImmediatePriority:
- return ImmediatePriorityKeyword();
- case WebSchedulingPriority::kHighPriority:
- return HighPriorityKeyword();
- case WebSchedulingPriority::kDefaultPriority:
- return DefaultPriorityKeyword();
- case WebSchedulingPriority::kLowPriority:
- return LowPriorityKeyword();
- case WebSchedulingPriority::kIdlePriority:
- return IdlePriorityKeyword();
+ case WebSchedulingPriority::kUserBlockingPriority:
+ return UserBlockingPriorityKeyword();
+ case WebSchedulingPriority::kUserVisiblePriority:
+ return UserVisiblePriorityKeyword();
+ case WebSchedulingPriority::kBackgroundPriority:
+ return BackgroundPriorityKeyword();
}
NOTREACHED();
@@ -55,19 +43,14 @@ AtomicString WebSchedulingPriorityToString(WebSchedulingPriority priority) {
WebSchedulingPriority WebSchedulingPriorityFromString(
const AtomicString& priority) {
- if (priority == ImmediatePriorityKeyword())
- return WebSchedulingPriority::kImmediatePriority;
- if (priority == HighPriorityKeyword())
- return WebSchedulingPriority::kHighPriority;
- if (priority == DefaultPriorityKeyword())
- return WebSchedulingPriority::kDefaultPriority;
- if (priority == LowPriorityKeyword())
- return WebSchedulingPriority::kLowPriority;
- if (priority == IdlePriorityKeyword())
- return WebSchedulingPriority::kIdlePriority;
-
+ if (priority == UserBlockingPriorityKeyword())
+ return WebSchedulingPriority::kUserBlockingPriority;
+ if (priority == UserVisiblePriorityKeyword())
+ return WebSchedulingPriority::kUserVisiblePriority;
+ if (priority == BackgroundPriorityKeyword())
+ return WebSchedulingPriority::kBackgroundPriority;
NOTREACHED();
- return WebSchedulingPriority::kDefaultPriority;
+ return WebSchedulingPriority::kUserVisiblePriority;
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/widget_scheduler.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/widget_scheduler.cc
new file mode 100644
index 00000000000..0e7bc1f23a5
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/widget_scheduler.cc
@@ -0,0 +1,35 @@
+// 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/scheduler/main_thread/widget_scheduler.h"
+
+#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
+
+namespace blink {
+namespace scheduler {
+
+WidgetScheduler::WidgetScheduler(
+ MainThreadSchedulerImpl* main_thread_scheduler) {
+ input_task_queue_ = main_thread_scheduler->NewTaskQueue(
+ MainThreadTaskQueue::QueueCreationParams(
+ MainThreadTaskQueue::QueueType::kInput)
+ .SetShouldMonitorQuiescence(true)
+ .SetFixedPriority(
+ base::make_optional(TaskQueue::QueuePriority::kHighestPriority)));
+ input_task_runner_ =
+ input_task_queue_->CreateTaskRunner(TaskType::kMainThreadTaskQueueInput);
+ input_task_queue_enabled_voter_ =
+ input_task_queue_->CreateQueueEnabledVoter();
+}
+
+WidgetScheduler::~WidgetScheduler() {
+ input_task_queue_->ShutdownTaskQueue();
+}
+
+scoped_refptr<base::SingleThreadTaskRunner> WidgetScheduler::InputTaskRunner() {
+ return input_task_runner_;
+}
+
+} // namespace scheduler
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/widget_scheduler.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/widget_scheduler.h
new file mode 100644
index 00000000000..83a5fdecb26
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/widget_scheduler.h
@@ -0,0 +1,37 @@
+// 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_SCHEDULER_MAIN_THREAD_WIDGET_SCHEDULER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_WIDGET_SCHEDULER_H_
+
+#include <memory>
+
+#include "base/task/sequence_manager/task_queue.h"
+#include "third_party/blink/public/platform/scheduler/web_widget_scheduler.h"
+
+namespace blink {
+namespace scheduler {
+
+class MainThreadSchedulerImpl;
+class MainThreadTaskQueue;
+
+class WidgetScheduler : public WebWidgetScheduler {
+ public:
+ WidgetScheduler(MainThreadSchedulerImpl*);
+ ~WidgetScheduler() override;
+ scoped_refptr<base::SingleThreadTaskRunner> InputTaskRunner() override;
+
+ private:
+ scoped_refptr<MainThreadTaskQueue> input_task_queue_;
+ scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_;
+ std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter>
+ input_task_queue_enabled_voter_;
+
+ DISALLOW_COPY_AND_ASSIGN(WidgetScheduler);
+};
+
+} // namespace scheduler
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_WIDGET_SCHEDULER_H_
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 7aec66e6e0f..c9f33ee112b 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
@@ -89,8 +89,8 @@ class FrameScheduler : public FrameOrWorkerScheduler {
// Set whether this frame is cross origin w.r.t. the top level frame. Cross
// origin frames may use a different scheduling policy from same origin
// frames.
- virtual void SetCrossOrigin(bool) = 0;
- virtual bool IsCrossOrigin() const = 0;
+ virtual void SetCrossOriginToMainFrame(bool) = 0;
+ virtual bool IsCrossOriginToMainFrame() const = 0;
virtual void SetIsAdFrame() = 0;
virtual bool IsAdFrame() const = 0;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/public/pending_user_input_type.h b/chromium/third_party/blink/renderer/platform/scheduler/public/pending_user_input_type.h
index 17c9a3baa13..ab1b52d776a 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/public/pending_user_input_type.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/public/pending_user_input_type.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_PENDING_USER_INPUT_TYPE_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_PENDING_USER_INPUT_TYPE_H_
+#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h b/chromium/third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h
index 9eb6426a100..20e3e743837 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h
@@ -9,8 +9,8 @@
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/time/time.h"
+#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
-#include "third_party/blink/public/platform/web_input_event.h"
#include "third_party/blink/renderer/platform/scheduler/public/page_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/pending_user_input_type.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
@@ -89,6 +89,11 @@ class PLATFORM_EXPORT ThreadScheduler {
// Returns a task runner for kV8 tasks. Can be called from any thread.
virtual scoped_refptr<base::SingleThreadTaskRunner> V8TaskRunner() = 0;
+ // Returns a task runner which does not generate system wakeups on its own.
+ // This means that if a delayed task is posted to it, it will run when
+ // the delay expires AND another task runs.
+ virtual scoped_refptr<base::SingleThreadTaskRunner> NonWakingTaskRunner() = 0;
+
// Returns a task runner for compositor tasks. This is intended only to be
// used by specific animation and rendering related tasks (e.g. animated GIFS)
// and should not generally be used.
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/public/web_scheduling_priority.h b/chromium/third_party/blink/renderer/platform/scheduler/public/web_scheduling_priority.h
index fde66f54035..049ecb25117 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/public/web_scheduling_priority.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/public/web_scheduling_priority.h
@@ -13,13 +13,11 @@ namespace blink {
// Priorities for the experimental scheduling API (see
// https://github.com/WICG/main-thread-scheduling).
enum class WebSchedulingPriority {
- kImmediatePriority = 0,
- kHighPriority = 1,
- kDefaultPriority = 2,
- kLowPriority = 3,
- kIdlePriority = 4,
+ kUserBlockingPriority = 0,
+ kUserVisiblePriority = 1,
+ kBackgroundPriority = 2,
- kLastPriority = kIdlePriority
+ kLastPriority = kBackgroundPriority
};
PLATFORM_EXPORT AtomicString
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/public/worker_pool.h b/chromium/third_party/blink/renderer/platform/scheduler/public/worker_pool.h
index e801685efad..ca7c72f301f 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/public/worker_pool.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/public/worker_pool.h
@@ -15,9 +15,9 @@ namespace blink {
namespace worker_pool {
-// These are a thin wrapper around base::ThreadPoolInstance to ensure that all
-// callers use CrossThreadBindOnce instead of base::Bind to ensure that
-// all non-thread-safe objects are copied properly.
+// These are a thin wrapper around base::ThreadPool to ensure that all callers
+// use CrossThreadBindOnce instead of base::Bind to ensure that all
+// non-thread-safe objects are copied properly.
//
// All tasks that do not care about which thread they are running on
// (e.g. compressing/uncompressing tasks) use this API.
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.cc b/chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.cc
index ef04e64744c..0bc371afa11 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.cc
@@ -33,21 +33,7 @@ CompositorThreadScheduler::CompositorThreadScheduler(
base::sequence_manager::SequenceManager* sequence_manager)
: NonMainThreadSchedulerImpl(sequence_manager,
TaskType::kCompositorThreadTaskQueueDefault),
- input_task_queue_(
- base::FeatureList::IsEnabled(kHighPriorityInputOnCompositorThread)
- ? helper()->NewTaskQueue(
- base::sequence_manager::TaskQueue::Spec("input_tq")
- .SetShouldMonitorQuiescence(true))
- : nullptr),
- input_task_runner_(input_task_queue_
- ? input_task_queue_->CreateTaskRunner(
- TaskType::kCompositorThreadTaskQueueInput)
- : nullptr),
compositor_metrics_helper_(helper()->HasCPUTimingForEachTask()) {
- if (input_task_queue_) {
- input_task_queue_->SetQueuePriority(
- base::sequence_manager::TaskQueue::QueuePriority::kHighestPriority);
- }
DCHECK(!g_compositor_thread_scheduler);
g_compositor_thread_scheduler = this;
}
@@ -85,26 +71,30 @@ CompositorThreadScheduler::IdleTaskRunner() {
}
scoped_refptr<base::SingleThreadTaskRunner>
-CompositorThreadScheduler::InputTaskRunner() {
- if (input_task_runner_)
- return input_task_runner_;
+CompositorThreadScheduler::V8TaskRunner() {
+ NOTREACHED();
+ return nullptr;
+}
+
+scoped_refptr<base::SingleThreadTaskRunner>
+CompositorThreadScheduler::DefaultTaskRunner() {
return helper()->DefaultTaskRunner();
}
scoped_refptr<base::SingleThreadTaskRunner>
-CompositorThreadScheduler::V8TaskRunner() {
+CompositorThreadScheduler::CompositorTaskRunner() {
NOTREACHED();
return nullptr;
}
scoped_refptr<base::SingleThreadTaskRunner>
-CompositorThreadScheduler::CompositorTaskRunner() {
+CompositorThreadScheduler::IPCTaskRunner() {
NOTREACHED();
return nullptr;
}
scoped_refptr<base::SingleThreadTaskRunner>
-CompositorThreadScheduler::IPCTaskRunner() {
+CompositorThreadScheduler::NonWakingTaskRunner() {
NOTREACHED();
return nullptr;
}
@@ -128,7 +118,6 @@ void CompositorThreadScheduler::RemoveTaskObserver(
}
void CompositorThreadScheduler::Shutdown() {
- input_task_queue_->ShutdownTaskQueue();
}
void CompositorThreadScheduler::OnIdleTaskPosted() {}
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.h b/chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.h
index 984cb2d01cc..3c808170630 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.h
@@ -40,9 +40,10 @@ class PLATFORM_EXPORT CompositorThreadScheduler
// WebThreadScheduler:
scoped_refptr<base::SingleThreadTaskRunner> V8TaskRunner() override;
+ scoped_refptr<base::SingleThreadTaskRunner> DefaultTaskRunner() override;
scoped_refptr<base::SingleThreadTaskRunner> CompositorTaskRunner() override;
scoped_refptr<base::SingleThreadTaskRunner> IPCTaskRunner() override;
- scoped_refptr<base::SingleThreadTaskRunner> InputTaskRunner() override;
+ scoped_refptr<base::SingleThreadTaskRunner> NonWakingTaskRunner() override;
bool ShouldYieldForHighPriorityWork() override;
bool CanExceedIdleDeadlineIfRequired() const override;
void AddTaskObserver(base::TaskObserver* task_observer) override;
@@ -66,9 +67,6 @@ class PLATFORM_EXPORT CompositorThreadScheduler
void InitImpl() override;
private:
- scoped_refptr<NonMainThreadTaskQueue> input_task_queue_;
- scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_;
-
CompositorMetricsHelper compositor_metrics_helper_;
DISALLOW_COPY_AND_ASSIGN(CompositorThreadScheduler);
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler_unittest.cc
deleted file mode 100644
index 55385f02784..00000000000
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler_unittest.cc
+++ /dev/null
@@ -1,121 +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/scheduler/worker/compositor_thread_scheduler.h"
-#include <algorithm>
-#include <memory>
-#include "base/bind.h"
-#include "base/macros.h"
-#include "base/task/sequence_manager/test/sequence_manager_for_test.h"
-#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 "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/wtf/functional.h"
-
-using testing::ElementsAre;
-using testing::ElementsAreArray;
-
-namespace blink {
-namespace scheduler {
-// To avoid symbol collisions in jumbo builds.
-namespace compositor_thread_scheduler_unittest {
-
-class CompositorThreadSchedulerTest : public testing::Test {
- public:
- CompositorThreadSchedulerTest(
- std::vector<base::Feature> features_to_enable,
- std::vector<base::Feature> features_to_disable) {
- feature_list_.InitWithFeatures(features_to_enable, features_to_disable);
- }
-
- CompositorThreadSchedulerTest() : CompositorThreadSchedulerTest({}, {}) {}
-
- ~CompositorThreadSchedulerTest() override = default;
-
- void SetUp() override {
- mock_task_runner_ = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
- mock_task_runner_->AdvanceMockTickClock(
- base::TimeDelta::FromMicroseconds(5000));
- sequence_manager_ = base::sequence_manager::SequenceManagerForTest::Create(
- nullptr, mock_task_runner_, mock_task_runner_->GetMockTickClock());
- scheduler_ =
- std::make_unique<CompositorThreadScheduler>(sequence_manager_.get());
- scheduler_->Init();
- }
-
- void TearDown() override {}
-
- protected:
- base::test::ScopedFeatureList feature_list_;
-
- scoped_refptr<base::TestMockTimeTaskRunner> mock_task_runner_;
- std::unique_ptr<base::sequence_manager::SequenceManagerForTest>
- sequence_manager_;
- std::unique_ptr<CompositorThreadScheduler> scheduler_;
-
- DISALLOW_COPY_AND_ASSIGN(CompositorThreadSchedulerTest);
-};
-
-class CompositorThreadInputPriorityTest : public CompositorThreadSchedulerTest {
- public:
- CompositorThreadInputPriorityTest()
- : CompositorThreadSchedulerTest(
- {kHighPriorityInputOnCompositorThread} /* features_to_enable */,
- {} /* features_to_disable */) {}
- ~CompositorThreadInputPriorityTest() override = default;
-};
-
-namespace {
-
-void RunTestTask(String name, Vector<String>* log) {
- log->push_back(name);
-}
-
-} // namespace
-
-TEST_F(CompositorThreadInputPriorityTest, HighestPriorityInput) {
- Vector<String> run_order;
-
- scheduler_->DefaultTaskQueue()->task_runner()->PostTask(
- FROM_HERE,
- base::BindOnce(&RunTestTask, "default", base::Unretained(&run_order)));
- scheduler_->InputTaskRunner()->PostTask(
- FROM_HERE,
- base::BindOnce(&RunTestTask, "input", base::Unretained(&run_order)));
-
- mock_task_runner_->RunUntilIdle();
-
- EXPECT_THAT(run_order, testing::ElementsAre("input", "default"));
-}
-
-class CompositorThreadNoInputPriorityTest
- : public CompositorThreadSchedulerTest {
- public:
- CompositorThreadNoInputPriorityTest()
- : CompositorThreadSchedulerTest(
- {} /* features_to_enable */,
- {kHighPriorityInputOnCompositorThread} /* features_to_disable */) {}
- ~CompositorThreadNoInputPriorityTest() override = default;
-};
-
-TEST_F(CompositorThreadNoInputPriorityTest, InputNotPrioritized) {
- Vector<String> run_order;
-
- scheduler_->DefaultTaskQueue()->task_runner()->PostTask(
- FROM_HERE,
- base::BindOnce(&RunTestTask, "default", base::Unretained(&run_order)));
- scheduler_->InputTaskRunner()->PostTask(
- FROM_HERE,
- base::BindOnce(&RunTestTask, "input", base::Unretained(&run_order)));
-
- mock_task_runner_->RunUntilIdle();
-
- EXPECT_THAT(run_order, testing::ElementsAre("default", "input"));
-}
-} // namespace compositor_thread_scheduler_unittest
-} // namespace scheduler
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc
index b9a44ecca6e..d63485495f5 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc
@@ -197,6 +197,7 @@ scoped_refptr<base::SingleThreadTaskRunner> WorkerScheduler::GetTaskRunner(
case TaskType::kMainThreadTaskQueueControl:
case TaskType::kMainThreadTaskQueueCleanup:
case TaskType::kMainThreadTaskQueueMemoryPurge:
+ case TaskType::kMainThreadTaskQueueNonWaking:
case TaskType::kCompositorThreadTaskQueueDefault:
case TaskType::kCompositorThreadTaskQueueInput:
case TaskType::kWorkerThreadTaskQueueDefault:
@@ -207,6 +208,7 @@ scoped_refptr<base::SingleThreadTaskRunner> WorkerScheduler::GetTaskRunner(
case TaskType::kInternalContentCapture:
case TaskType::kExperimentalWebScheduling:
case TaskType::kInternalFrameLifecycleControl:
+ case TaskType::kInternalFindInPage:
case TaskType::kCount:
NOTREACHED();
break;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc
index 478c3cb030f..4434805d26a 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc
@@ -21,7 +21,6 @@
#include "services/metrics/public/cpp/ukm_builders.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/renderer/platform/instrumentation/histogram.h"
#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"
@@ -156,6 +155,12 @@ WorkerThreadScheduler::IPCTaskRunner() {
return nullptr;
}
+scoped_refptr<base::SingleThreadTaskRunner>
+WorkerThreadScheduler::NonWakingTaskRunner() {
+ NOTREACHED() << "Not implemented";
+ return nullptr;
+}
+
bool WorkerThreadScheduler::CanExceedIdleDeadlineIfRequired() const {
DCHECK(initialized_);
return idle_helper_.CanExceedIdleDeadlineIfRequired();
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h
index fb26754d227..130a125f9fb 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h
@@ -50,6 +50,7 @@ class PLATFORM_EXPORT WorkerThreadScheduler : public NonMainThreadSchedulerImpl,
scoped_refptr<base::SingleThreadTaskRunner> V8TaskRunner() override;
scoped_refptr<base::SingleThreadTaskRunner> CompositorTaskRunner() override;
scoped_refptr<base::SingleThreadTaskRunner> IPCTaskRunner() override;
+ scoped_refptr<base::SingleThreadTaskRunner> NonWakingTaskRunner() override;
bool ShouldYieldForHighPriorityWork() override;
bool CanExceedIdleDeadlineIfRequired() const override;
void AddTaskObserver(base::TaskObserver* task_observer) override;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler_unittest.cc
index d4142d207c2..76cce482184 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler_unittest.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler_unittest.cc
@@ -490,10 +490,10 @@ class WorkerThreadSchedulerWithProxyTest : public testing::Test {
frame_scheduler_ = FakeFrameScheduler::Builder()
.SetIsPageVisible(false)
.SetFrameType(FrameScheduler::FrameType::kSubframe)
- .SetIsCrossOrigin(true)
+ .SetIsCrossOriginToMainFrame(true)
.SetDelegate(frame_scheduler_delegate_.get())
.Build();
- frame_scheduler_->SetCrossOrigin(true);
+ frame_scheduler_->SetCrossOriginToMainFrame(true);
worker_scheduler_proxy_ =
std::make_unique<WorkerSchedulerProxy>(frame_scheduler_.get());
diff --git a/chromium/third_party/blink/renderer/platform/supplementable.h b/chromium/third_party/blink/renderer/platform/supplementable.h
index ff971f12334..dbbd63044f5 100644
--- a/chromium/third_party/blink/renderer/platform/supplementable.h
+++ b/chromium/third_party/blink/renderer/platform/supplementable.h
@@ -147,9 +147,7 @@ class Supplement : public GarbageCollectedMixin {
: nullptr;
}
- void Trace(blink::Visitor* visitor) override {
- visitor->Trace(supplementable_);
- }
+ void Trace(Visitor* visitor) override { visitor->Trace(supplementable_); }
private:
Member<T> supplementable_;
@@ -201,7 +199,7 @@ class Supplementable : public GarbageCollectedMixin {
#endif
}
- void Trace(blink::Visitor* visitor) override { visitor->Trace(supplements_); }
+ void Trace(Visitor* visitor) override { visitor->Trace(supplements_); }
protected:
using SupplementMap =
diff --git a/chromium/third_party/blink/renderer/platform/testing/DEPS b/chromium/third_party/blink/renderer/platform/testing/DEPS
index 19b3458859d..63b1f17bcd4 100644
--- a/chromium/third_party/blink/renderer/platform/testing/DEPS
+++ b/chromium/third_party/blink/renderer/platform/testing/DEPS
@@ -13,10 +13,12 @@ include_rules = [
"+base/process",
"+base/run_loop.h",
"+base/metrics/statistics_recorder.h",
+ "+base/strings/string_number_conversions.h",
"+base/task/single_thread_task_executor.h",
"+base/test/test_io_thread.h",
"+cc",
"+mojo/core/embedder",
+ "+services/network/public",
'+testing',
"+third_party/blink/renderer/platform/exported",
diff --git a/chromium/third_party/blink/renderer/platform/testing/blink_fuzzer_test_support.cc b/chromium/third_party/blink/renderer/platform/testing/blink_fuzzer_test_support.cc
index a01f3006487..1a8a8a1a5f0 100644
--- a/chromium/third_party/blink/renderer/platform/testing/blink_fuzzer_test_support.cc
+++ b/chromium/third_party/blink/renderer/platform/testing/blink_fuzzer_test_support.cc
@@ -10,7 +10,6 @@
#include "base/test/test_timeouts.h"
#include "content/public/test/blink_test_environment.h"
#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
namespace blink {
@@ -30,8 +29,6 @@ BlinkFuzzerTestSupport::BlinkFuzzerTestSupport(int argc, char** argv) {
TestTimeouts::Initialize();
content::SetUpBlinkTestEnvironment();
-
- blink::SchemeRegistry::Initialize();
}
BlinkFuzzerTestSupport::~BlinkFuzzerTestSupport() {
diff --git a/chromium/third_party/blink/renderer/platform/testing/empty_web_media_player.cc b/chromium/third_party/blink/renderer/platform/testing/empty_web_media_player.cc
index 76f39b5545e..119e0ff710d 100644
--- a/chromium/third_party/blink/renderer/platform/testing/empty_web_media_player.cc
+++ b/chromium/third_party/blink/renderer/platform/testing/empty_web_media_player.cc
@@ -22,12 +22,12 @@ WebTimeRanges EmptyWebMediaPlayer::Seekable() const {
return WebTimeRanges();
}
-WebSize EmptyWebMediaPlayer::NaturalSize() const {
- return WebSize(0, 0);
+gfx::Size EmptyWebMediaPlayer::NaturalSize() const {
+ return gfx::Size();
}
-WebSize EmptyWebMediaPlayer::VisibleRect() const {
- return WebSize();
+gfx::Size EmptyWebMediaPlayer::VisibleSize() const {
+ return gfx::Size();
}
WebString EmptyWebMediaPlayer::GetErrorMessage() const {
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 1322171e57a..e6692af38be 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
@@ -30,6 +30,7 @@ class EmptyWebMediaPlayer : public WebMediaPlayer {
void SetVolume(double) override {}
void SetLatencyHint(double) override {}
void OnRequestPictureInPicture() override {}
+ void OnPictureInPictureAvailabilityChanged(bool available) override {}
SurfaceLayerMode GetVideoSurfaceLayerMode() const override {
return SurfaceLayerMode::kNever;
}
@@ -39,13 +40,14 @@ class EmptyWebMediaPlayer : public WebMediaPlayer {
WebSetSinkIdCompleteCallback) override {}
bool HasVideo() const override { return false; }
bool HasAudio() const override { return false; }
- WebSize NaturalSize() const override;
- WebSize VisibleRect() const override;
+ gfx::Size NaturalSize() const override;
+ gfx::Size VisibleSize() const override;
bool Paused() const override { return false; }
bool Seeking() const override { return false; }
double Duration() const override { return 0.0; }
double CurrentTime() const override { return 0.0; }
- NetworkState GetNetworkState() const override { return kNetworkStateEmpty; }
+ bool IsEnded() const override { return false; }
+ NetworkState GetNetworkState() const override { return kNetworkStateIdle; }
ReadyState GetReadyState() const override { return kReadyStateHaveNothing; }
WebString GetErrorMessage() const override;
bool DidLoadingProgress() override { return false; }
diff --git a/chromium/third_party/blink/renderer/platform/testing/font_test_helpers.cc b/chromium/third_party/blink/renderer/platform/testing/font_test_helpers.cc
index 08dc5f8c1b5..1272d0fb9fc 100644
--- a/chromium/third_party/blink/renderer/platform/testing/font_test_helpers.cc
+++ b/chromium/third_party/blink/renderer/platform/testing/font_test_helpers.cc
@@ -61,6 +61,8 @@ class TestFontSelector : public FontSelector {
const AtomicString& font_family_name) override {}
void ReportFailedFontFamilyMatch(
const AtomicString& font_family_name) override {}
+ void ReportSuccessfulLocalFontMatch(const AtomicString& font_name) override {}
+ void ReportFailedLocalFontMatch(const AtomicString& font_name) override {}
ExecutionContext* GetExecutionContext() const override { return nullptr; }
FontFaceCache* GetFontFaceCache() override { return nullptr; }
@@ -93,9 +95,7 @@ Font CreateTestFont(const AtomicString& family_name,
if (ligatures)
font_description.SetVariantLigatures(*ligatures);
- Font font(font_description);
- font.Update(TestFontSelector::Create(font_path));
- return font;
+ return Font(font_description, TestFontSelector::Create(font_path));
}
} // namespace test
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 9738516ca21..6da9d8037a9 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
@@ -23,6 +23,10 @@ inline const EffectPaintPropertyNode& e0() {
return EffectPaintPropertyNode::Root();
}
+constexpr int c0_id = 1;
+constexpr int e0_id = 1;
+constexpr int t0_id = 1;
+
inline scoped_refptr<EffectPaintPropertyNode> CreateOpacityEffect(
const EffectPaintPropertyNode& parent,
const TransformPaintPropertyNode& local_transform_space,
@@ -111,14 +115,13 @@ inline scoped_refptr<EffectPaintPropertyNode> CreateBackdropFilterEffect(
const TransformPaintPropertyNode& local_transform_space,
const ClipPaintPropertyNode* output_clip,
CompositorFilterOperations backdrop_filter,
- const FloatPoint& filters_origin = FloatPoint(),
- CompositingReasons compositing_reasons = CompositingReason::kNone) {
+ const FloatPoint& filters_origin = FloatPoint()) {
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 = compositing_reasons;
+ state.direct_compositing_reasons = CompositingReason::kBackdropFilter;
state.compositor_element_id = CompositorElementIdFromUniqueObjectId(
NewUniqueObjectId(), CompositorElementIdNamespace::kPrimary);
return EffectPaintPropertyNode::Create(parent, std::move(state));
@@ -127,12 +130,10 @@ inline scoped_refptr<EffectPaintPropertyNode> CreateBackdropFilterEffect(
inline scoped_refptr<EffectPaintPropertyNode> CreateBackdropFilterEffect(
const EffectPaintPropertyNode& parent,
CompositorFilterOperations backdrop_filter,
- const FloatPoint& paint_offset = FloatPoint(),
- CompositingReasons compositing_reasons = CompositingReason::kNone) {
+ const FloatPoint& paint_offset = FloatPoint()) {
return CreateBackdropFilterEffect(
parent, parent.Unalias().LocalTransformSpace(),
- parent.Unalias().OutputClip(), backdrop_filter, paint_offset,
- compositing_reasons);
+ parent.Unalias().OutputClip(), backdrop_filter, paint_offset);
}
inline scoped_refptr<EffectPaintPropertyNode>
@@ -156,9 +157,17 @@ inline scoped_refptr<ClipPaintPropertyNode> CreateClip(
const ClipPaintPropertyNode& parent,
const TransformPaintPropertyNode& local_transform_space,
const FloatRoundedRect& clip_rect) {
- ClipPaintPropertyNode::State state;
- state.local_transform_space = &local_transform_space;
- state.clip_rect = clip_rect;
+ ClipPaintPropertyNode::State state(&local_transform_space, clip_rect);
+ return ClipPaintPropertyNode::Create(parent, std::move(state));
+}
+
+inline scoped_refptr<ClipPaintPropertyNode> CreateClip(
+ const ClipPaintPropertyNode& parent,
+ const TransformPaintPropertyNode& local_transform_space,
+ const FloatRoundedRect& clip_rect,
+ const FloatRoundedRect& pixel_snapped_clip_rect) {
+ ClipPaintPropertyNode::State state(&local_transform_space, clip_rect,
+ pixel_snapped_clip_rect);
return ClipPaintPropertyNode::Create(parent, std::move(state));
}
@@ -166,9 +175,7 @@ inline scoped_refptr<ClipPaintPropertyNode> CreateClipPathClip(
const ClipPaintPropertyNode& parent,
const TransformPaintPropertyNode& local_transform_space,
const FloatRoundedRect& clip_rect) {
- ClipPaintPropertyNode::State state;
- state.local_transform_space = &local_transform_space;
- state.clip_rect = clip_rect;
+ ClipPaintPropertyNode::State state(&local_transform_space, clip_rect);
state.clip_path = base::AdoptRef(new RefCountedPath);
return ClipPaintPropertyNode::Create(parent, std::move(state));
}
@@ -186,8 +193,7 @@ inline scoped_refptr<TransformPaintPropertyNode> CreateTransform(
const TransformationMatrix& matrix,
const FloatPoint3D& origin = FloatPoint3D(),
CompositingReasons compositing_reasons = CompositingReason::kNone) {
- TransformPaintPropertyNode::State state{
- TransformPaintPropertyNode::TransformAndOrigin(matrix, origin)};
+ TransformPaintPropertyNode::State state{{matrix, origin}};
state.direct_compositing_reasons = compositing_reasons;
return TransformPaintPropertyNode::Create(parent, std::move(state));
}
@@ -196,8 +202,7 @@ inline scoped_refptr<TransformPaintPropertyNode> CreateAnimatingTransform(
const TransformPaintPropertyNode& parent,
const TransformationMatrix& matrix = TransformationMatrix(),
const FloatPoint3D& origin = FloatPoint3D()) {
- TransformPaintPropertyNode::State state{
- TransformPaintPropertyNode::TransformAndOrigin(matrix, origin)};
+ TransformPaintPropertyNode::State state{{matrix, origin}};
state.direct_compositing_reasons =
CompositingReason::kActiveTransformAnimation;
state.compositor_element_id = CompositorElementIdFromUniqueObjectId(
diff --git a/chromium/third_party/blink/renderer/platform/testing/paint_test_configurations.h b/chromium/third_party/blink/renderer/platform/testing/paint_test_configurations.h
index 00b0da0c002..f5b9d63ee7b 100644
--- a/chromium/third_party/blink/renderer/platform/testing/paint_test_configurations.h
+++ b/chromium/third_party/blink/renderer/platform/testing/paint_test_configurations.h
@@ -11,24 +11,17 @@
namespace blink {
-enum {
- kCompositeAfterPaint = 1 << 0,
- kUnderInvalidationChecking = 1 << 1,
- kFastBorderRadius = 1 << 2,
- kDoNotCompositeTrivial3D = 1 << 3,
-};
+enum { kCompositeAfterPaint = 1 << 0, kUnderInvalidationChecking = 1 << 1 };
class PaintTestConfigurations
: public testing::WithParamInterface<unsigned>,
private ScopedCompositeAfterPaintForTest,
- private ScopedPaintUnderInvalidationCheckingForTest,
- private ScopedFastBorderRadiusForTest {
+ private ScopedPaintUnderInvalidationCheckingForTest {
public:
PaintTestConfigurations()
: ScopedCompositeAfterPaintForTest(GetParam() & kCompositeAfterPaint),
- ScopedPaintUnderInvalidationCheckingForTest(GetParam() &
- kUnderInvalidationChecking),
- ScopedFastBorderRadiusForTest(GetParam() & kFastBorderRadius) {}
+ ScopedPaintUnderInvalidationCheckingForTest(
+ GetParam() & kUnderInvalidationChecking) {}
~PaintTestConfigurations() {
// Must destruct all objects before toggling back feature flags.
WebHeap::CollectAllGarbageForTesting();
@@ -43,21 +36,6 @@ class PaintTestConfigurations
INSTANTIATE_TEST_SUITE_P(All, test_class, \
::testing::Values(kCompositeAfterPaint))
-#define INSTANTIATE_LAYER_LIST_TEST_SUITE_P(test_class) \
- INSTANTIATE_TEST_SUITE_P( \
- All, test_class, \
- ::testing::Values(0, kCompositeAfterPaint, kFastBorderRadius))
-
-#define INSTANTIATE_SCROLL_HIT_TEST_SUITE_P(test_class) \
- INSTANTIATE_TEST_SUITE_P(All, test_class, \
- ::testing::Values(0, kCompositeAfterPaint))
-
-#define INSTANTIATE_DO_NOT_COMPOSITE_TRIVIAL_3D_P(test_class) \
- INSTANTIATE_TEST_SUITE_P( \
- All, test_class, \
- ::testing::Values(0, kCompositeAfterPaint, kDoNotCompositeTrivial3D, \
- kCompositeAfterPaint | kDoNotCompositeTrivial3D))
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_PAINT_TEST_CONFIGURATIONS_H_
diff --git a/chromium/third_party/blink/renderer/platform/testing/shape_result_perf_test.cc b/chromium/third_party/blink/renderer/platform/testing/shape_result_perf_test.cc
index 2e35ebbb57b..32e03c72ae4 100644
--- a/chromium/third_party/blink/renderer/platform/testing/shape_result_perf_test.cc
+++ b/chromium/third_party/blink/renderer/platform/testing/shape_result_perf_test.cc
@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
#include "base/timer/lap_timer.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/perf/perf_test.h"
+#include "testing/perf/perf_result_reporter.h"
#include "third_party/blink/renderer/platform/fonts/font.h"
#include "third_party/blink/renderer/platform/fonts/font_description.h"
#include "third_party/blink/renderer/platform/testing/font_test_helpers.h"
@@ -21,6 +22,14 @@ static const int kTimeLimitMillis = 3000;
static const int kWarmupRuns = 10000;
static const int kTimeCheckInterval = 1000000;
+namespace {
+
+constexpr char kMetricPrefixOffsetForPosition[] = "OffsetForPosition.";
+constexpr char kMetricPrefixCharacterRange[] = "CharacterRange.";
+constexpr char kMetricThroughput[] = "throughput";
+
+} // namespace
+
class ShapeResultPerfTest {
USING_FAST_MALLOC(ShapeResultPerfTest);
@@ -52,6 +61,14 @@ class ShapeResultPerfTest {
ltr ? TextDirection::kLtr : TextDirection::kRtl, false);
}
+ void ReportResult(const std::string& metric_prefix,
+ const std::string& story_prefix) {
+ std::string story = story_prefix + "_" + param_string;
+ perf_test::PerfResultReporter reporter(metric_prefix, story);
+ reporter.RegisterImportantMetric(kMetricThroughput, "runs/s");
+ reporter.AddResult(kMetricThroughput, timer.LapsPerSecond());
+ }
+
Font font;
HashMap<FontName, String, WTF::IntHash<FontName>> font_path = {
@@ -62,6 +79,7 @@ class ShapeResultPerfTest {
};
base::LapTimer timer;
+ std::string param_string;
};
class OffsetForPositionPerfTest : public ShapeResultPerfTest,
@@ -72,11 +90,18 @@ class OffsetForPositionPerfTest : public ShapeResultPerfTest,
BreakGlyphsOption breakopt) {
timer.Reset();
float position = GetParam();
+ param_string = base::NumberToString(position);
do {
font.OffsetForPosition(run, position, partial, breakopt);
timer.NextLap();
} while (!timer.HasTimeLimitExpired());
}
+
+ protected:
+ void ReportResult(const std::string& story_prefix) {
+ ShapeResultPerfTest::ReportResult(kMetricPrefixOffsetForPosition,
+ story_prefix);
+ }
};
class CharacterRangePerfTest : public ShapeResultPerfTest,
@@ -85,67 +110,66 @@ class CharacterRangePerfTest : public ShapeResultPerfTest,
void GetCharacter(TextRun& run) {
timer.Reset();
int endpos = GetParam();
+ param_string = base::NumberToString(endpos);
do {
font.SelectionRectForText(run, FloatPoint(), 100, 0, endpos);
timer.NextLap();
} while (!timer.HasTimeLimitExpired());
}
+
+ protected:
+ void ReportResult(const std::string& story_prefix) {
+ ShapeResultPerfTest::ReportResult(kMetricPrefixCharacterRange,
+ story_prefix);
+ }
};
TEST_P(OffsetForPositionPerfTest, LTROffsetForPositionFullBreak) {
TextRun run = SetupFont(ahem, "FURACOLO", true);
OffsetForPosition(run, OnlyFullGlyphs, BreakGlyphs);
- perf_test::PrintResult("OffsetForPositionPerfTest", " LTR full break", "",
- timer.LapsPerSecond(), "runs/s", true);
+ ReportResult("LTR_full_break");
}
TEST_P(OffsetForPositionPerfTest, LTROffsetForPositionFullDontBreak) {
TextRun run = SetupFont(ahem, "FURACOLO", true);
OffsetForPosition(run, OnlyFullGlyphs, DontBreakGlyphs);
- perf_test::PrintResult("OffsetForPositionPerfTest", " LTR full", "",
- timer.LapsPerSecond(), "runs/s", true);
+ ReportResult("LTR_full");
}
TEST_P(OffsetForPositionPerfTest, LTROffsetForPositionIncludePartialBreak) {
TextRun run = SetupFont(ahem, "FURACOLO", true);
OffsetForPosition(run, IncludePartialGlyphs, BreakGlyphs);
- perf_test::PrintResult("OffsetForPositionPerfTest", " LTR partial break", "",
- timer.LapsPerSecond(), "runs/s", true);
+ ReportResult("LTR_partial_break");
}
TEST_P(OffsetForPositionPerfTest, LTROffsetForPositionIncludePartialDontBreak) {
TextRun run = SetupFont(ahem, "FURACOLO", true);
OffsetForPosition(run, IncludePartialGlyphs, DontBreakGlyphs);
- perf_test::PrintResult("OffsetForPositionPerfTest", " LTR partial", "",
- timer.LapsPerSecond(), "runs/s", true);
+ ReportResult("LTR_partial");
}
TEST_P(OffsetForPositionPerfTest, RTLOffsetForPositionFullBreak) {
TextRun run = SetupFont(ahem, "OLOCARUF", false);
OffsetForPosition(run, OnlyFullGlyphs, BreakGlyphs);
- perf_test::PrintResult("OffsetForPositionPerfTest", " RTL full break", "",
- timer.LapsPerSecond(), "runs/s", true);
+ ReportResult("RTL_full_break");
}
TEST_P(OffsetForPositionPerfTest, RTLOffsetForPositionFullDontBreak) {
TextRun run = SetupFont(ahem, "OLOCARUF", false);
OffsetForPosition(run, OnlyFullGlyphs, DontBreakGlyphs);
- perf_test::PrintResult("OffsetForPositionPerfTest", " RTL full", "",
- timer.LapsPerSecond(), "runs/s", true);
+ ReportResult("RTL_full");
}
TEST_P(OffsetForPositionPerfTest, RTLOffsetForPositionIncludePartialBreak) {
TextRun run = SetupFont(ahem, "OLOCARUF", false);
OffsetForPosition(run, IncludePartialGlyphs, BreakGlyphs);
- perf_test::PrintResult("OffsetForPositionPerfTest", " RTL partial break", "",
- timer.LapsPerSecond(), "runs/s", true);
+ ReportResult("RTL_partial_break");
}
TEST_P(OffsetForPositionPerfTest, RTLOffsetForPositionIncludePartialDontBreak) {
TextRun run = SetupFont(ahem, "OLOCARUF", false);
OffsetForPosition(run, IncludePartialGlyphs, DontBreakGlyphs);
- perf_test::PrintResult("OffsetForPositionPerfTest", " RTL partial", "",
- timer.LapsPerSecond(), "runs/s", true);
+ ReportResult("RTL_partial");
}
INSTANTIATE_TEST_SUITE_P(OffsetForPosition,
@@ -155,15 +179,13 @@ INSTANTIATE_TEST_SUITE_P(OffsetForPosition,
TEST_P(CharacterRangePerfTest, LTRCharacterForPosition) {
TextRun run = SetupFont(ahem, "FURACOLO", true);
GetCharacter(run);
- perf_test::PrintResult("CharacterRangePerfTest", " LTR", "",
- timer.LapsPerSecond(), "runs/s", true);
+ ReportResult("LTR");
}
TEST_P(CharacterRangePerfTest, RTLCharacterForPosition) {
TextRun run = SetupFont(ahem, "OLOCARUF", false);
GetCharacter(run);
- perf_test::PrintResult("CharacterRangePerfTest", " RTL", "",
- timer.LapsPerSecond(), "runs/s", true);
+ ReportResult("RTL");
}
INSTANTIATE_TEST_SUITE_P(CharacterRange,
diff --git a/chromium/third_party/blink/renderer/platform/testing/shaping_line_breaker_perf_test.cc b/chromium/third_party/blink/renderer/platform/testing/shaping_line_breaker_perf_test.cc
index c265e21a38e..4fb43e6a2cb 100644
--- a/chromium/third_party/blink/renderer/platform/testing/shaping_line_breaker_perf_test.cc
+++ b/chromium/third_party/blink/renderer/platform/testing/shaping_line_breaker_perf_test.cc
@@ -17,7 +17,7 @@
#include "third_party/blink/renderer/platform/text/text_run.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/perf/perf_test.h"
+#include "testing/perf/perf_result_reporter.h"
namespace blink {
namespace {
@@ -26,6 +26,16 @@ static const int kTimeLimitMillis = 2000;
static const int kWarmupRuns = 5;
static const int kTimeCheckInterval = 10;
+constexpr char kMetricPrefixShapingLineBreaker[] = "ShapingLineBreaker.";
+constexpr char kMetricThroughput[] = "throughput";
+
+perf_test::PerfResultReporter SetUpReporter(const std::string& story) {
+ perf_test::PerfResultReporter reporter(kMetricPrefixShapingLineBreaker,
+ story);
+ reporter.RegisterImportantMetric(kMetricThroughput, "runs/s");
+ return reporter;
+}
+
struct HarfBuzzShaperCallbackContext {
const HarfBuzzShaper* shaper;
const Font* font;
@@ -67,7 +77,6 @@ class ShapingLineBreakerPerfTest : public testing::Test {
void SetUp() override {
font_description.SetComputedSize(12.0);
font = Font(font_description);
- font.Update(nullptr);
}
void TearDown() override {}
@@ -164,8 +173,8 @@ TEST_F(ShapingLineBreakerPerfTest, ShapeLatinText) {
timer_.NextLap();
} while (!timer_.HasTimeLimitExpired());
- perf_test::PrintResult("ShapingLineBreakerPerfTest", "shape latin text", "",
- timer_.LapsPerSecond(), "runs/s", true);
+ SetUpReporter("latin_text")
+ .AddResult(kMetricThroughput, timer_.LapsPerSecond());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/testing/stub_graphics_layer_client.h b/chromium/third_party/blink/renderer/platform/testing/stub_graphics_layer_client.h
index 36ccdd9b42d..9d3841aa77b 100644
--- a/chromium/third_party/blink/renderer/platform/testing/stub_graphics_layer_client.h
+++ b/chromium/third_party/blink/renderer/platform/testing/stub_graphics_layer_client.h
@@ -11,7 +11,6 @@ class StubGraphicsLayerClient : public GraphicsLayerClient {
~StubGraphicsLayerClient() override = default;
// GraphicsLayerClient implementation.
- void InvalidateTargetElementForTesting() override {}
IntRect ComputeInterestRect(
const GraphicsLayer*,
const IntRect& previous_interest_rect) const override {
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 1f0238b9157..badc81ac3fe 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
@@ -13,38 +13,34 @@
#include "third_party/blink/renderer/platform/graphics/paint/paint_flags.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_record.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_recorder.h"
-#include "third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h"
#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
namespace blink {
-class TestPaintArtifact::DummyRectClient : public FakeDisplayItemClient {
- public:
- IntRect VisualRect() const final { return rect_; }
- void SetVisualRect(const IntRect& rect) { rect_ = rect; }
-
- sk_sp<PaintRecord> MakeRecord(const FloatRect& rect, Color color) {
- rect_ = EnclosingIntRect(rect);
- PaintRecorder recorder;
- cc::PaintCanvas* canvas = recorder.beginRecording(rect);
- PaintFlags flags;
- flags.setColor(color.Rgb());
- canvas->drawRect(rect, flags);
- return recorder.finishRecordingAsPicture();
- }
-
- private:
- IntRect rect_;
-};
+sk_sp<PaintRecord> DummyRectClient::MakeRecord(const IntRect& rect,
+ Color color) {
+ rect_ = rect;
+ PaintRecorder recorder;
+ cc::PaintCanvas* canvas = recorder.beginRecording(rect);
+ PaintFlags flags;
+ flags.setColor(color.Rgb());
+ canvas->drawRect(rect, flags);
+ return recorder.finishRecordingAsPicture();
+}
TestPaintArtifact::TestPaintArtifact() : display_item_list_(0) {}
TestPaintArtifact::~TestPaintArtifact() = default;
-TestPaintArtifact& TestPaintArtifact::Chunk(int id) {
+static DummyRectClient& StaticDummyClient() {
DEFINE_STATIC_LOCAL(DummyRectClient, client, ());
- Chunk(client,
+ client.Validate();
+ return client;
+}
+
+TestPaintArtifact& TestPaintArtifact::Chunk(int id) {
+ Chunk(StaticDummyClient(),
static_cast<DisplayItem::Type>(DisplayItem::kDrawingFirst + id));
// The default bounds with magic numbers make the chunks have different bounds
// from each other, for e.g. RasterInvalidatorTest to check the tracked raster
@@ -55,13 +51,11 @@ TestPaintArtifact& TestPaintArtifact::Chunk(int id) {
return *this;
}
-TestPaintArtifact& TestPaintArtifact::Chunk(FakeDisplayItemClient& client,
+TestPaintArtifact& TestPaintArtifact::Chunk(DummyRectClient& client,
DisplayItem::Type type) {
- if (!paint_chunks_.IsEmpty())
- paint_chunks_.back().end_index = display_item_list_.size();
- paint_chunks_.push_back(PaintChunk(display_item_list_.size(), 0,
- PaintChunk::Id(client, type),
- PropertyTreeState::Root()));
+ paint_chunks_.push_back(
+ PaintChunk(display_item_list_.size(), display_item_list_.size(),
+ PaintChunk::Id(client, type), PropertyTreeState::Root()));
// Assume PaintController has processed this chunk.
paint_chunks_.back().client_is_just_created = false;
return *this;
@@ -73,7 +67,7 @@ TestPaintArtifact& TestPaintArtifact::Properties(
return *this;
}
-TestPaintArtifact& TestPaintArtifact::RectDrawing(const FloatRect& bounds,
+TestPaintArtifact& TestPaintArtifact::RectDrawing(const IntRect& bounds,
Color color) {
return RectDrawing(NewClient(), bounds, color);
}
@@ -84,15 +78,6 @@ TestPaintArtifact& TestPaintArtifact::ScrollHitTest(
return ScrollHitTest(NewClient(), scroll_offset, scroll_container_bounds);
}
-TestPaintArtifact& TestPaintArtifact::RectDrawing(FakeDisplayItemClient& client,
- const FloatRect& bounds,
- Color color) {
- display_item_list_.AllocateAndConstruct<DrawingDisplayItem>(
- client, DisplayItem::kDrawingFirst,
- static_cast<DummyRectClient&>(client).MakeRecord(bounds, color));
- return *this;
-}
-
TestPaintArtifact& TestPaintArtifact::ForeignLayer(
scoped_refptr<cc::Layer> layer,
const FloatPoint& offset) {
@@ -100,16 +85,25 @@ TestPaintArtifact& TestPaintArtifact::ForeignLayer(
display_item_list_.AllocateAndConstruct<ForeignLayerDisplayItem>(
client, DisplayItem::kForeignLayerFirst, std::move(layer), offset,
nullptr);
+ DidAddDisplayItem();
+ return *this;
+}
+
+TestPaintArtifact& TestPaintArtifact::RectDrawing(DummyRectClient& client,
+ const IntRect& bounds,
+ Color color) {
+ display_item_list_.AllocateAndConstruct<DrawingDisplayItem>(
+ client, DisplayItem::kDrawingFirst, client.MakeRecord(bounds, color));
+ DidAddDisplayItem();
return *this;
}
TestPaintArtifact& TestPaintArtifact::ScrollHitTest(
- FakeDisplayItemClient& client,
- const TransformPaintPropertyNode* scroll_offset,
+ DummyRectClient& client,
+ const TransformPaintPropertyNode* scroll_translation,
const IntRect& scroll_container_bounds) {
- display_item_list_.AllocateAndConstruct<ScrollHitTestDisplayItem>(
- client, DisplayItem::kScrollHitTest, scroll_offset,
- scroll_container_bounds);
+ paint_chunks_.back().EnsureHitTestData().scroll_translation =
+ scroll_translation;
return *this;
}
@@ -125,6 +119,14 @@ TestPaintArtifact& TestPaintArtifact::KnownToBeOpaque() {
TestPaintArtifact& TestPaintArtifact::Bounds(const IntRect& bounds) {
paint_chunks_.back().bounds = bounds;
+ paint_chunks_.back().drawable_bounds = bounds;
+ return *this;
+}
+
+TestPaintArtifact& TestPaintArtifact::DrawableBounds(
+ const IntRect& drawable_bounds) {
+ paint_chunks_.back().drawable_bounds = drawable_bounds;
+ DCHECK(paint_chunks_.back().bounds.Contains(drawable_bounds));
return *this;
}
@@ -134,19 +136,27 @@ TestPaintArtifact& TestPaintArtifact::Uncacheable() {
}
scoped_refptr<PaintArtifact> TestPaintArtifact::Build() {
- if (!paint_chunks_.IsEmpty())
- paint_chunks_.back().end_index = display_item_list_.size();
return PaintArtifact::Create(std::move(display_item_list_),
std::move(paint_chunks_));
}
-FakeDisplayItemClient& TestPaintArtifact::NewClient() {
+DummyRectClient& TestPaintArtifact::NewClient() {
dummy_clients_.push_back(std::make_unique<DummyRectClient>());
return *dummy_clients_.back();
}
-FakeDisplayItemClient& TestPaintArtifact::Client(wtf_size_t i) const {
+DummyRectClient& TestPaintArtifact::Client(wtf_size_t i) const {
return *dummy_clients_[i];
}
+void TestPaintArtifact::DidAddDisplayItem() {
+ auto& chunk = paint_chunks_.back();
+ DCHECK_EQ(chunk.end_index, display_item_list_.size() - 1);
+ const auto& item = display_item_list_.Last();
+ chunk.bounds.Unite(item.VisualRect());
+ if (item.DrawsContent())
+ chunk.drawable_bounds.Unite(item.VisualRect());
+ chunk.end_index++;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/testing/test_paint_artifact.h b/chromium/third_party/blink/renderer/platform/testing/test_paint_artifact.h
index 838ab969e8d..2e7a1f1108d 100644
--- a/chromium/third_party/blink/renderer/platform/testing/test_paint_artifact.h
+++ b/chromium/third_party/blink/renderer/platform/testing/test_paint_artifact.h
@@ -22,10 +22,20 @@ namespace blink {
class ClipPaintPropertyNode;
class EffectPaintPropertyNode;
-class FloatRect;
class PaintArtifact;
class TransformPaintPropertyNode;
+class DummyRectClient : public FakeDisplayItemClient {
+ public:
+ IntRect VisualRect() const final { return rect_; }
+ void SetVisualRect(const IntRect& rect) { rect_ = rect; }
+
+ sk_sp<PaintRecord> MakeRecord(const IntRect& rect, Color color);
+
+ private:
+ IntRect rect_;
+};
+
// Useful for quickly making a paint artifact in unit tests.
//
// If any method that automatically creates display item client is called, the
@@ -58,7 +68,7 @@ class TestPaintArtifact {
TestPaintArtifact& Chunk() { return Chunk(NewClient()); }
// Add a chunk with the specified client.
- TestPaintArtifact& Chunk(FakeDisplayItemClient&,
+ TestPaintArtifact& Chunk(DummyRectClient&,
DisplayItem::Type = DisplayItem::kDrawingFirst);
// This is for RasterInvalidatorTest, to create a chunk with specific id and
@@ -92,7 +102,7 @@ class TestPaintArtifact {
// Add display item in the chunk. Each display item will have a different
// automatically created client.
- TestPaintArtifact& RectDrawing(const FloatRect& bounds, Color color);
+ TestPaintArtifact& RectDrawing(const IntRect& bounds, Color color);
TestPaintArtifact& ScrollHitTest(
const TransformPaintPropertyNode* scroll_offset,
const IntRect& scroll_container_bounds);
@@ -101,18 +111,20 @@ class TestPaintArtifact {
const FloatPoint& offset);
// Add display item with the specified client in the chunk.
- TestPaintArtifact& RectDrawing(FakeDisplayItemClient&,
- const FloatRect& bounds,
- Color);
+ TestPaintArtifact& RectDrawing(DummyRectClient&,
+ const IntRect& bounds,
+ Color color);
TestPaintArtifact& ScrollHitTest(
- FakeDisplayItemClient&,
+ DummyRectClient&,
const TransformPaintPropertyNode* scroll_offset,
const IntRect& scroll_container_bounds);
// Sets fake bounds for the last paint chunk. Note that the bounds will be
// overwritten when the PaintArtifact is constructed if the chunk has any
- // display items.
+ // display items. Bounds() sets both bounds and drawable_bounds, while
+ // DrawableBounds() sets drawable_bounds only.
TestPaintArtifact& Bounds(const IntRect&);
+ TestPaintArtifact& DrawableBounds(const IntRect&);
TestPaintArtifact& OutsetForRasterEffects(float);
TestPaintArtifact& KnownToBeOpaque();
@@ -124,12 +136,13 @@ class TestPaintArtifact {
scoped_refptr<PaintArtifact> Build();
// Create a new display item client which is owned by this TestPaintArtifact.
- FakeDisplayItemClient& NewClient();
+ DummyRectClient& NewClient();
- FakeDisplayItemClient& Client(wtf_size_t) const;
+ DummyRectClient& Client(wtf_size_t) const;
private:
- class DummyRectClient;
+ void DidAddDisplayItem();
+
Vector<std::unique_ptr<DummyRectClient>> dummy_clients_;
DisplayItemList display_item_list_;
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 70a486d1bcb..7464c9cd52f 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
@@ -39,8 +39,7 @@
#include "base/test/icu_test_util.h"
#include "base/test/test_discardable_memory_allocator.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
-#include "third_party/blink/public/platform/interface_provider.h"
+#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/platform/web_runtime_features.h"
#include "third_party/blink/renderer/platform/font_family_names.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
@@ -55,23 +54,24 @@
namespace blink {
-class TestingPlatformSupport::TestingInterfaceProvider
- : public blink::InterfaceProvider {
+class TestingPlatformSupport::TestingBrowserInterfaceBroker
+ : public ThreadSafeBrowserInterfaceBrokerProxy {
public:
- TestingInterfaceProvider() = default;
- virtual ~TestingInterfaceProvider() = default;
+ TestingBrowserInterfaceBroker() = default;
+ ~TestingBrowserInterfaceBroker() override = default;
- void GetInterface(const char* name,
- mojo::ScopedMessagePipeHandle handle) override {
+ void GetInterfaceImpl(mojo::GenericPendingReceiver receiver) override {
auto& override_callback = GetOverrideCallback();
+ auto interface_name = receiver.interface_name().value_or("");
if (!override_callback.is_null()) {
- override_callback.Run(name, std::move(handle));
+ override_callback.Run(interface_name.c_str(), receiver.PassPipe());
return;
}
- if (std::string(name) == mojom::blink::MimeRegistry::Name_) {
+ if (interface_name == mojom::blink::MimeRegistry::Name_) {
mojo::MakeSelfOwnedReceiver(
std::make_unique<MockMimeRegistry>(),
- mojo::PendingReceiver<mojom::blink::MimeRegistry>(std::move(handle)));
+ mojo::PendingReceiver<mojom::blink::MimeRegistry>(
+ receiver.PassPipe()));
return;
}
}
@@ -86,7 +86,7 @@ class TestingPlatformSupport::TestingInterfaceProvider
TestingPlatformSupport::ScopedOverrideMojoInterface::
ScopedOverrideMojoInterface(GetInterfaceCallback callback)
- : auto_reset_(&TestingInterfaceProvider::GetOverrideCallback(),
+ : auto_reset_(&TestingBrowserInterfaceBroker::GetOverrideCallback(),
std::move(callback)) {}
TestingPlatformSupport::ScopedOverrideMojoInterface::
@@ -94,7 +94,7 @@ TestingPlatformSupport::ScopedOverrideMojoInterface::
TestingPlatformSupport::TestingPlatformSupport()
: old_platform_(Platform::Current()),
- interface_provider_(new TestingInterfaceProvider) {
+ interface_broker_(base::MakeRefCounted<TestingBrowserInterfaceBroker>()) {
DCHECK(old_platform_);
DCHECK(WTF::IsMainThread());
}
@@ -129,11 +129,13 @@ WebData TestingPlatformSupport::UncompressDataResource(int resource_id) {
: WebData();
}
-InterfaceProvider* TestingPlatformSupport::GetInterfaceProvider() {
- return interface_provider_.get();
+ThreadSafeBrowserInterfaceBrokerProxy*
+TestingPlatformSupport::GetBrowserInterfaceBroker() {
+ return interface_broker_.get();
}
void TestingPlatformSupport::RunUntilIdle() {
+ ThreadState::HeapPointersOnStackScope scan_stack(ThreadState::Current());
base::RunLoop().RunUntilIdle();
}
@@ -169,7 +171,7 @@ ScopedUnittestsEnvironmentSetup::ScopedUnittestsEnvironmentSetup(int argc,
Platform::SetCurrentPlatformForTesting(dummy_platform_.get());
WTF::Partitions::Initialize();
- WTF::Initialize(nullptr);
+ WTF::Initialize();
// This must be called after WTF::Initialize(), because ThreadSpecific<>
// used in this function depends on WTF::IsMainThread().
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 eb1f8a94884..17ea8b4e183 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
@@ -37,6 +37,7 @@
#include "base/auto_reset.h"
#include "base/callback.h"
#include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/testing/code_cache_loader_mock.h"
@@ -69,7 +70,7 @@ class TestingPlatformSupport : public Platform {
WebData GetDataResource(int resource_id,
ui::ScaleFactor scale_factor) override;
WebData UncompressDataResource(int resource_id) override;
- InterfaceProvider* GetInterfaceProvider() override;
+ ThreadSafeBrowserInterfaceBrokerProxy* GetBrowserInterfaceBroker() override;
bool IsThreadedAnimationEnabled() override;
virtual void RunUntilIdle();
@@ -90,10 +91,10 @@ class TestingPlatformSupport : public Platform {
};
protected:
- class TestingInterfaceProvider;
+ class TestingBrowserInterfaceBroker;
Platform* const old_platform_;
- std::unique_ptr<TestingInterfaceProvider> interface_provider_;
+ scoped_refptr<TestingBrowserInterfaceBroker> interface_broker_;
private:
bool is_threaded_animation_enabled_ = false;
diff --git a/chromium/third_party/blink/renderer/platform/testing/unit_test_helpers.cc b/chromium/third_party/blink/renderer/platform/testing/unit_test_helpers.cc
index f78ee319d2c..1215543c54b 100644
--- a/chromium/third_party/blink/renderer/platform/testing/unit_test_helpers.cc
+++ b/chromium/third_party/blink/renderer/platform/testing/unit_test_helpers.cc
@@ -64,9 +64,9 @@ void RunPendingTasks() {
Thread::Current()->GetTaskRunner()->PostTask(FROM_HERE,
WTF::Bind(&ExitRunLoop));
- // We forbid GC in the tasks. Otherwise the registered GCTaskObserver tries
- // to run GC with NoHeapPointerOnStack.
- ThreadState::GCForbiddenScope gc_forbidden(ThreadState::Current());
+ // The following runloop can execute non-nested tasks with heap pointers
+ // living on stack, so we force both Oilpan and Unified GC to visit the stack.
+ ThreadState::HeapPointersOnStackScope scan_stack(ThreadState::Current());
EnterRunLoop();
}
@@ -131,6 +131,13 @@ scoped_refptr<SharedBuffer> ReadFromFile(const String& path) {
return SharedBuffer::Create(buffer.data(), buffer.size());
}
+String BlinkWebTestsFontsTestDataPath(const String& relative_path) {
+ return FilePathToWebString(
+ WebTestsFilePath()
+ .Append(FILE_PATH_LITERAL("external/wpt/fonts"))
+ .Append(WebStringToFilePath(relative_path)));
+}
+
LineReader::LineReader(const String& text) : text_(text), index_(0) {}
bool LineReader::GetNextLine(String* line) {
diff --git a/chromium/third_party/blink/renderer/platform/testing/unit_test_helpers.h b/chromium/third_party/blink/renderer/platform/testing/unit_test_helpers.h
index 87d71599901..a964623e478 100644
--- a/chromium/third_party/blink/renderer/platform/testing/unit_test_helpers.h
+++ b/chromium/third_party/blink/renderer/platform/testing/unit_test_helpers.h
@@ -75,6 +75,12 @@ String PlatformTestDataPath(const String& relative_path = String());
// specified.
String AccessibilityTestDataPath(const String& relative_path = String());
+// Returns Blink web_tests fonts as an absolute path, i.e.
+// <blinkRootDir>/src/third_party/blink/web_tests/external/wpt/fonts/<relative_path>.
+// It returns the top fonts test directory if |relative_path| was not
+// specified.
+String BlinkWebTestsFontsTestDataPath(const String& relative_path = String());
+
scoped_refptr<SharedBuffer> ReadFromFile(const String& path);
class LineReader {
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 653acd538f2..e07b21c2cf3 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
@@ -33,10 +33,10 @@
#include <string>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
+#include "services/network/public/mojom/load_timing_info.mojom.h"
#include "third_party/blink/public/platform/file_path_conversion.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_url_error.h"
-#include "third_party/blink/public/platform/web_url_load_timing.h"
#include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader.h"
#include "third_party/blink/renderer/platform/network/http_names.h"
@@ -64,27 +64,27 @@ WebURL RegisterMockedURLLoadFromBase(const WebString& base_url,
void RegisterMockedURLLoad(const WebURL& full_url,
const WebString& file_path,
const WebString& mime_type) {
- WebURLLoadTiming timing;
- timing.Initialize();
+ network::mojom::LoadTimingInfoPtr timing =
+ network::mojom::LoadTimingInfo::New();
WebURLResponse response(full_url);
response.SetMimeType(mime_type);
response.SetHttpHeaderField(http_names::kContentType, mime_type);
response.SetHttpStatusCode(200);
- response.SetLoadTiming(timing);
+ response.SetLoadTiming(*timing);
RegisterMockedURLLoadWithCustomResponse(full_url, file_path, response);
}
void RegisterMockedErrorURLLoad(const WebURL& full_url) {
- WebURLLoadTiming timing;
- timing.Initialize();
+ network::mojom::LoadTimingInfoPtr timing =
+ network::mojom::LoadTimingInfo::New();
WebURLResponse response;
response.SetMimeType("image/png");
response.SetHttpHeaderField(http_names::kContentType, "image/png");
response.SetHttpStatusCode(404);
- response.SetLoadTiming(timing);
+ response.SetLoadTiming(*timing);
ResourceError error = ResourceError::Failure(full_url);
Platform::Current()->GetURLLoaderMockFactory()->RegisterErrorURL(
diff --git a/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock.cc b/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock.cc
index a58efcf47f6..a4bf13cebbe 100644
--- a/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock.cc
+++ b/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock.cc
@@ -6,6 +6,8 @@
#include <utility>
+#include "net/cookies/site_for_cookies.h"
+#include "services/network/public/cpp/resource_request.h"
#include "third_party/blink/public/platform/url_conversion.h"
#include "third_party/blink/public/platform/web_data.h"
#include "third_party/blink/public/platform/web_security_origin.h"
@@ -70,7 +72,7 @@ void WebURLLoaderMock::ServeAsynchronousRequest(
}
WebURL WebURLLoaderMock::ServeRedirect(
- const WebURLRequest& request,
+ const WebString& method,
const WebURLResponse& redirect_response) {
KURL redirect_url(redirect_response.HttpHeaderField("Location"));
@@ -78,9 +80,9 @@ WebURL WebURLLoaderMock::ServeRedirect(
bool report_raw_headers = false;
bool follow = client_->WillFollowRedirect(
- redirect_url, redirect_url, WebString(),
- network::mojom::ReferrerPolicy::kDefault, request.HttpMethod(),
- redirect_response, report_raw_headers);
+ redirect_url, net::SiteForCookies::FromUrl(redirect_url), WebString(),
+ network::mojom::ReferrerPolicy::kDefault, method, redirect_response,
+ report_raw_headers);
// |this| might be deleted in willFollowRedirect().
if (!self)
return redirect_url;
@@ -92,7 +94,13 @@ WebURL WebURLLoaderMock::ServeRedirect(
}
void WebURLLoaderMock::LoadSynchronously(
- const WebURLRequest& request,
+ std::unique_ptr<network::ResourceRequest> request,
+ scoped_refptr<WebURLRequest::ExtraData> request_extra_data,
+ int requestor_id,
+ bool download_to_network_cache_only,
+ bool pass_response_pipe_to_client,
+ bool no_mime_sniffing,
+ base::TimeDelta timeout_interval,
WebURLLoaderClient* client,
WebURLResponse& response,
base::Optional<WebURLError>& error,
@@ -100,17 +108,22 @@ void WebURLLoaderMock::LoadSynchronously(
int64_t& encoded_data_length,
int64_t& encoded_body_length,
blink::WebBlobInfo& downloaded_blob) {
- DCHECK(factory_->IsMockedURL(request.Url()));
- factory_->LoadSynchronously(request, &response, &error, &data,
+ DCHECK(factory_->IsMockedURL(WebURL(KURL(request->url)))) << request->url;
+ factory_->LoadSynchronously(std::move(request), &response, &error, &data,
&encoded_data_length);
}
-void WebURLLoaderMock::LoadAsynchronously(const WebURLRequest& request,
- WebURLLoaderClient* client) {
+void WebURLLoaderMock::LoadAsynchronously(
+ std::unique_ptr<network::ResourceRequest> request,
+ scoped_refptr<WebURLRequest::ExtraData> request_extra_data,
+ int requestor_id,
+ bool download_to_network_cache_only,
+ bool no_mime_sniffing,
+ WebURLLoaderClient* client) {
DCHECK(client);
- DCHECK(factory_->IsMockedURL(request.Url())) << request.Url();
+ DCHECK(factory_->IsMockedURL(WebURL(KURL(request->url)))) << request->url;
client_ = client;
- factory_->LoadAsynchronouly(request, this);
+ factory_->LoadAsynchronouly(std::move(request), this);
}
void WebURLLoaderMock::Cancel() {
diff --git a/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock.h b/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock.h
index 45d418e8766..0181a0889f9 100644
--- a/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock.h
+++ b/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock.h
@@ -39,20 +39,32 @@ class WebURLLoaderMock : public WebURLLoader {
const base::Optional<WebURLError>& error);
// Simulates the redirect being served.
- WebURL ServeRedirect(const WebURLRequest& request,
+ WebURL ServeRedirect(const WebString& method,
const WebURLResponse& redirect_response);
// WebURLLoader methods:
- void LoadSynchronously(const WebURLRequest&,
- WebURLLoaderClient* client,
- WebURLResponse&,
- base::Optional<WebURLError>&,
- WebData&,
- int64_t& encoded_data_length,
- int64_t& encoded_body_length,
- blink::WebBlobInfo& downloaded_blob) override;
- void LoadAsynchronously(const WebURLRequest& request,
- WebURLLoaderClient* client) override;
+ void LoadSynchronously(
+ std::unique_ptr<network::ResourceRequest> request,
+ scoped_refptr<WebURLRequest::ExtraData> request_extra_data,
+ int requestor_id,
+ bool download_to_network_cache_only,
+ bool pass_response_pipe_to_client,
+ bool no_mime_sniffing,
+ base::TimeDelta timeout_interval,
+ WebURLLoaderClient* client,
+ WebURLResponse&,
+ base::Optional<WebURLError>&,
+ WebData&,
+ int64_t& encoded_data_length,
+ int64_t& encoded_body_length,
+ blink::WebBlobInfo& downloaded_blob) override;
+ void LoadAsynchronously(
+ std::unique_ptr<network::ResourceRequest> request,
+ scoped_refptr<WebURLRequest::ExtraData> request_extra_data,
+ int requestor_id,
+ bool download_to_network_cache_only,
+ bool no_mime_sniffing,
+ WebURLLoaderClient* client) override;
void SetDefersLoading(bool defer) override;
void DidChangePriority(WebURLRequest::Priority new_priority,
int intra_priority_value) override;
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 71d4ab676d5..c8d802cd025 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
@@ -118,17 +118,18 @@ void WebURLLoaderMockFactoryImpl::ServeAsynchronousRequests() {
while (!pending_loaders_.IsEmpty()) {
LoaderToRequestMap::iterator iter = pending_loaders_.begin();
base::WeakPtr<WebURLLoaderMock> loader(iter->key->GetWeakPtr());
- const WebURLRequest request = iter->value;
+ std::unique_ptr<network::ResourceRequest> request = std::move(iter->value);
pending_loaders_.erase(loader.get());
WebURLResponse response;
base::Optional<WebURLError> error;
WebData data;
- LoadRequest(request.Url(), &response, &error, &data);
+ LoadRequest(WebURL(KURL(request->url)), &response, &error, &data);
// Follow any redirects while the loader is still active.
while (response.HttpStatusCode() >= 300 &&
response.HttpStatusCode() < 400) {
- WebURL new_url = loader->ServeRedirect(request, response);
+ WebURL new_url = loader->ServeRedirect(
+ WebString::FromLatin1(request->method), response);
RunUntilIdle();
if (!loader || loader->is_cancelled() || loader->is_deferred())
break;
@@ -204,20 +205,20 @@ void WebURLLoaderMockFactoryImpl::CancelLoad(WebURLLoaderMock* loader) {
}
void WebURLLoaderMockFactoryImpl::LoadSynchronously(
- const WebURLRequest& request,
+ std::unique_ptr<network::ResourceRequest> request,
WebURLResponse* response,
base::Optional<WebURLError>* error,
WebData* data,
int64_t* encoded_data_length) {
- LoadRequest(request.Url(), response, error, data);
+ LoadRequest(WebURL(KURL(request->url)), response, error, data);
*encoded_data_length = data->size();
}
void WebURLLoaderMockFactoryImpl::LoadAsynchronouly(
- const WebURLRequest& request,
+ std::unique_ptr<network::ResourceRequest> request,
WebURLLoaderMock* loader) {
DCHECK(!pending_loaders_.Contains(loader));
- pending_loaders_.Set(loader, request);
+ pending_loaders_.Set(loader, std::move(request));
}
void WebURLLoaderMockFactoryImpl::RunUntilIdle() {
diff --git a/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.h b/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.h
index 2af483ea74d..3fdebfd5142 100644
--- a/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.h
+++ b/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.h
@@ -18,6 +18,10 @@
#include "third_party/blink/renderer/platform/weborigin/kurl_hash.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
+namespace network {
+struct ResourceRequest;
+} // namespace network
+
namespace blink {
class TestingPlatformSupport;
@@ -58,12 +62,12 @@ class WebURLLoaderMockFactoryImpl : public WebURLLoaderMockFactory {
bool IsMockedURL(const WebURL& url);
// Called by the loader to load a resource.
- void LoadSynchronously(const WebURLRequest& request,
+ void LoadSynchronously(std::unique_ptr<network::ResourceRequest> request,
WebURLResponse* response,
base::Optional<WebURLError>* error,
WebData* data,
int64_t* encoded_data_length);
- void LoadAsynchronouly(const WebURLRequest& request,
+ void LoadAsynchronouly(std::unique_ptr<network::ResourceRequest> request,
WebURLLoaderMock* loader);
// Removes the loader from the list of pending loaders.
@@ -101,7 +105,8 @@ class WebURLLoaderMockFactoryImpl : public WebURLLoaderMockFactory {
WebURLLoaderTestDelegate* delegate_ = nullptr;
// The loaders that have not being served data yet.
- using LoaderToRequestMap = HashMap<WebURLLoaderMock*, WebURLRequest>;
+ using LoaderToRequestMap =
+ HashMap<WebURLLoaderMock*, std::unique_ptr<network::ResourceRequest>>;
LoaderToRequestMap pending_loaders_;
// All values must be valid, but we use Optional because HashMap requires
diff --git a/chromium/third_party/blink/renderer/platform/text/DEPS b/chromium/third_party/blink/renderer/platform/text/DEPS
index e6709d4f7a1..8cfc5a48108 100644
--- a/chromium/third_party/blink/renderer/platform/text/DEPS
+++ b/chromium/third_party/blink/renderer/platform/text/DEPS
@@ -6,6 +6,7 @@ include_rules = [
"+third_party/blink/renderer/platform/text",
# Dependencies.
+ "+base/i18n/rtl.h",
"+base/mac",
"+third_party/blink/renderer/platform/text/date_components.h",
"+third_party/blink/renderer/platform/heap",
@@ -16,4 +17,5 @@ include_rules = [
"+third_party/blink/renderer/platform/web_test_support.h",
"+third_party/blink/renderer/platform/weborigin",
"+third_party/blink/renderer/platform/wtf",
+ "+ui/base/ui_base_features.h",
]
diff --git a/chromium/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.cc b/chromium/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.cc
index abe78aa5062..4d24ad93a59 100644
--- a/chromium/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.cc
+++ b/chromium/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.cc
@@ -12,8 +12,8 @@
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/hyphenation/hyphenation.mojom-blink.h"
-#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/text/character.h"
#include "third_party/blink/renderer/platform/text/hyphenation/hyphenator_aosp.h"
@@ -51,7 +51,7 @@ using Hyphenator = android::Hyphenator;
static mojo::Remote<mojom::blink::Hyphenation> ConnectToRemoteService() {
mojo::Remote<mojom::blink::Hyphenation> service;
- Platform::Current()->GetInterfaceProvider()->GetInterface(
+ Platform::Current()->GetBrowserInterfaceBroker()->GetInterface(
service.BindNewPipeAndPassReceiver());
return service;
}
diff --git a/chromium/third_party/blink/renderer/platform/text/icu_error.cc b/chromium/third_party/blink/renderer/platform/text/icu_error.cc
index 1aad8529944..ec72aac3447 100644
--- a/chromium/third_party/blink/renderer/platform/text/icu_error.cc
+++ b/chromium/third_party/blink/renderer/platform/text/icu_error.cc
@@ -11,7 +11,7 @@ namespace blink {
// Distinguish memory allocation failures from other errors.
// https://groups.google.com/a/chromium.org/d/msg/platform-architecture-dev/MP0k9WGnCjA/zIBiJtilBwAJ
static NOINLINE void ICUOutOfMemory() {
- OOM_CRASH();
+ OOM_CRASH(0);
}
void ICUError::HandleFailure() {
diff --git a/chromium/third_party/blink/renderer/platform/text/locale_icu.cc b/chromium/third_party/blink/renderer/platform/text/locale_icu.cc
index 514931f881c..92fb99e0cc0 100644
--- a/chromium/third_party/blink/renderer/platform/text/locale_icu.cc
+++ b/chromium/third_party/blink/renderer/platform/text/locale_icu.cc
@@ -42,6 +42,7 @@
#include "third_party/blink/renderer/platform/wtf/date_math.h"
#include "third_party/blink/renderer/platform/wtf/text/string_buffer.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
+#include "ui/base/ui_base_features.h"
namespace blink {
@@ -249,7 +250,7 @@ void LocaleICU::InitializeCalendar() {
UCAL_FIRST_DAY_OF_WEEK) -
UCAL_SUNDAY;
- if (RuntimeEnabledFeatures::FormControlsRefreshEnabled()) {
+ if (features::IsFormControlsRefreshEnabled()) {
week_day_short_labels_ = CreateLabelVector(
short_date_format_, UDAT_NARROW_WEEKDAYS, UCAL_SUNDAY, 7);
} else {
diff --git a/chromium/third_party/blink/renderer/platform/text/locale_mac.mm b/chromium/third_party/blink/renderer/platform/text/locale_mac.mm
index 5f721423e39..c72f103fa1a 100644
--- a/chromium/third_party/blink/renderer/platform/text/locale_mac.mm
+++ b/chromium/third_party/blink/renderer/platform/text/locale_mac.mm
@@ -41,6 +41,7 @@
#include "third_party/blink/renderer/platform/web_test_support.h"
#include "third_party/blink/renderer/platform/wtf/date_math.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
+#include "ui/base/ui_base_features.h"
namespace blink {
@@ -136,7 +137,7 @@ const Vector<String>& LocaleMac::WeekDayShortLabels() {
if (!week_day_short_labels_.IsEmpty())
return week_day_short_labels_;
week_day_short_labels_.ReserveCapacity(7);
- NSArray* array = RuntimeEnabledFeatures::FormControlsRefreshEnabled()
+ NSArray* array = features::IsFormControlsRefreshEnabled()
? [ShortDateFormatter() veryShortWeekdaySymbols]
: [ShortDateFormatter() shortWeekdaySymbols];
if ([array count] == 7) {
diff --git a/chromium/third_party/blink/renderer/platform/text/locale_mac_test.mm b/chromium/third_party/blink/renderer/platform/text/locale_mac_test.mm
index 5daadce443d..588ebb56372 100644
--- a/chromium/third_party/blink/renderer/platform/text/locale_mac_test.mm
+++ b/chromium/third_party/blink/renderer/platform/text/locale_mac_test.mm
@@ -291,13 +291,13 @@ TEST_F(LocaleMacTest, monthLabels) {
}
TEST_F(LocaleMacTest, weekDayShortLabels) {
- EXPECT_EQ("Sun", WeekDayShortLabel("en_US", kSunday));
- EXPECT_EQ("Wed", WeekDayShortLabel("en_US", kWednesday));
- EXPECT_EQ("Sat", WeekDayShortLabel("en_US", kSaturday));
+ EXPECT_EQ("S", WeekDayShortLabel("en_US", kSunday));
+ EXPECT_EQ("W", WeekDayShortLabel("en_US", kWednesday));
+ EXPECT_EQ("S", WeekDayShortLabel("en_US", kSaturday));
- EXPECT_EQ("dim.", WeekDayShortLabel("fr_FR", kSunday));
- EXPECT_EQ("mer.", WeekDayShortLabel("fr_FR", kWednesday));
- EXPECT_EQ("sam.", WeekDayShortLabel("fr_FR", kSaturday));
+ EXPECT_EQ("D", WeekDayShortLabel("fr_FR", kSunday));
+ EXPECT_EQ("M", WeekDayShortLabel("fr_FR", kWednesday));
+ EXPECT_EQ("S", WeekDayShortLabel("fr_FR", kSaturday));
EXPECT_EQ("\xE6\x97\xA5", WeekDayShortLabel("ja_JP", kSunday).Utf8());
EXPECT_EQ("\xE6\xB0\xB4", WeekDayShortLabel("ja_JP", kWednesday).Utf8());
diff --git a/chromium/third_party/blink/renderer/platform/text/locale_win.cc b/chromium/third_party/blink/renderer/platform/text/locale_win.cc
index 2464478de20..3c86b59300d 100644
--- a/chromium/third_party/blink/renderer/platform/text/locale_win.cc
+++ b/chromium/third_party/blink/renderer/platform/text/locale_win.cc
@@ -45,6 +45,7 @@
#include "third_party/blink/renderer/platform/wtf/text/string_buffer.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
+#include "ui/base/ui_base_features.h"
namespace blink {
@@ -304,7 +305,7 @@ void LocaleWin::EnsureWeekDayShortLabels() {
LOCALE_SSHORTESTDAYNAME6};
week_day_short_labels_.ReserveCapacity(base::size(kTypes));
for (unsigned i = 0; i < base::size(kTypes); ++i) {
- if (RuntimeEnabledFeatures::FormControlsRefreshEnabled()) {
+ if (features::IsFormControlsRefreshEnabled()) {
week_day_short_labels_.push_back(GetLocaleInfoString(kTypesRefresh[i]));
} else {
week_day_short_labels_.push_back(GetLocaleInfoString(kTypes[i]));
diff --git a/chromium/third_party/blink/renderer/platform/text/locale_win_test.cc b/chromium/third_party/blink/renderer/platform/text/locale_win_test.cc
index d614168111c..2b132b226c7 100644
--- a/chromium/third_party/blink/renderer/platform/text/locale_win_test.cc
+++ b/chromium/third_party/blink/renderer/platform/text/locale_win_test.cc
@@ -35,6 +35,7 @@
#include "third_party/blink/renderer/platform/text/date_components.h"
#include "third_party/blink/renderer/platform/wtf/date_math.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
+#include "ui/base/ui_base_features.h"
namespace blink {
@@ -188,14 +189,23 @@ TEST_F(LocaleWinTest, monthLabels) {
}
TEST_F(LocaleWinTest, weekDayShortLabels) {
- EXPECT_EQ("Sun", WeekDayShortLabel(kEnglishUS, kSunday));
- EXPECT_EQ("Wed", WeekDayShortLabel(kEnglishUS, kWednesday));
- EXPECT_EQ("Sat", WeekDayShortLabel(kEnglishUS, kSaturday));
-
- EXPECT_EQ("dim.", WeekDayShortLabel(kFrenchFR, kSunday));
- EXPECT_EQ("mer.", WeekDayShortLabel(kFrenchFR, kWednesday));
- EXPECT_EQ("sam.", WeekDayShortLabel(kFrenchFR, kSaturday));
-
+ if (features::IsFormControlsRefreshEnabled()) {
+ EXPECT_EQ("Su", WeekDayShortLabel(kEnglishUS, kSunday));
+ EXPECT_EQ("We", WeekDayShortLabel(kEnglishUS, kWednesday));
+ EXPECT_EQ("Sa", WeekDayShortLabel(kEnglishUS, kSaturday));
+
+ EXPECT_EQ("di", WeekDayShortLabel(kFrenchFR, kSunday));
+ EXPECT_EQ("me", WeekDayShortLabel(kFrenchFR, kWednesday));
+ EXPECT_EQ("sa", WeekDayShortLabel(kFrenchFR, kSaturday));
+ } else {
+ EXPECT_EQ("Sun", WeekDayShortLabel(kEnglishUS, kSunday));
+ EXPECT_EQ("Wed", WeekDayShortLabel(kEnglishUS, kWednesday));
+ EXPECT_EQ("Sat", WeekDayShortLabel(kEnglishUS, kSaturday));
+
+ EXPECT_EQ("dim.", WeekDayShortLabel(kFrenchFR, kSunday));
+ EXPECT_EQ("mer.", WeekDayShortLabel(kFrenchFR, kWednesday));
+ EXPECT_EQ("sam.", WeekDayShortLabel(kFrenchFR, kSaturday));
+ }
EXPECT_EQ("\xE6\x97\xA5", WeekDayShortLabel(kJapaneseJP, kSunday).Utf8());
EXPECT_EQ("\xE6\xB0\xB4", WeekDayShortLabel(kJapaneseJP, kWednesday).Utf8());
EXPECT_EQ("\xE5\x9C\x9F", WeekDayShortLabel(kJapaneseJP, kSaturday).Utf8());
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 a3f71b81b58..e92eed0ad8a 100644
--- a/chromium/third_party/blink/renderer/platform/text/text_direction.h
+++ b/chromium/third_party/blink/renderer/platform/text/text_direction.h
@@ -28,6 +28,8 @@
#include <cstdint>
#include <iosfwd>
+#include "base/i18n/rtl.h"
+#include "base/logging.h"
#include "third_party/blink/renderer/platform/platform_export.h"
namespace blink {
@@ -57,6 +59,17 @@ inline TextDirection DirectionFromLevel(unsigned level) {
PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, TextDirection);
+inline base::i18n::TextDirection ToBaseTextDirection(TextDirection direction) {
+ switch (direction) {
+ case TextDirection::kLtr:
+ return base::i18n::TextDirection::LEFT_TO_RIGHT;
+ case TextDirection::kRtl:
+ return base::i18n::TextDirection::RIGHT_TO_LEFT;
+ }
+ NOTREACHED();
+ return base::i18n::TextDirection::UNKNOWN_DIRECTION;
+}
+
} // namespace blink
-#endif
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_TEXT_DIRECTION_H_
diff --git a/chromium/third_party/blink/renderer/platform/theme_types.h b/chromium/third_party/blink/renderer/platform/theme_types.h
index 76f20d1e953..b5ed8c14e6e 100644
--- a/chromium/third_party/blink/renderer/platform/theme_types.h
+++ b/chromium/third_party/blink/renderer/platform/theme_types.h
@@ -45,8 +45,10 @@ enum ControlState {
typedef unsigned ControlStates;
// Must follow css_value_keywords.json5 order
+// kAutoPart is never returned by ComputedStyle::EffectiveAppearance()
enum ControlPart {
kNoControlPart,
+ kAutoPart,
kCheckboxPart,
kRadioPart,
kPushButtonPart,
diff --git a/chromium/third_party/blink/renderer/platform/timer_test.cc b/chromium/third_party/blink/renderer/platform/timer_test.cc
index 0511f0f9bda..54e9b1c6792 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(blink::Visitor* visitor) {}
+ void Trace(Visitor* visitor) {}
private:
void Fired(TimerBase*) {
@@ -655,8 +655,8 @@ TEST_F(TimerTest, MarkOnHeapTimerAsUnreachable) {
owner = nullptr;
// Explicit regular GC call to allow lazy sweeping.
ThreadState::Current()->CollectGarbage(
- BlinkGC::kNoHeapPointersOnStack, BlinkGC::kAtomicMarking,
- BlinkGC::kConcurrentAndLazySweeping,
+ BlinkGC::CollectionType::kMajor, BlinkGC::kNoHeapPointersOnStack,
+ BlinkGC::kAtomicMarking, BlinkGC::kConcurrentAndLazySweeping,
BlinkGC::GCReason::kForcedGCForTesting);
// Since the heap is laziy swept, owner is not yet destructed.
EXPECT_FALSE(record->OwnerIsDestructed());
@@ -667,6 +667,7 @@ TEST_F(TimerTest, MarkOnHeapTimerAsUnreachable) {
platform_->RunUntilIdle();
EXPECT_FALSE(record->TimerHasFired());
EXPECT_FALSE(record->OwnerIsDestructed());
+ ThreadState::Current()->CompleteSweep();
}
}
diff --git a/chromium/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.cc b/chromium/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.cc
index 1ee49fe627f..2d8da85b813 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.cc
+++ b/chromium/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.cc
@@ -35,7 +35,7 @@ namespace blink {
scoped_refptr<TransformOperation> Matrix3DTransformOperation::Accumulate(
const TransformOperation& other_op) {
DCHECK(other_op.IsSameType(*this));
- const auto& other = ToMatrix3DTransformOperation(other_op);
+ const auto& other = To<Matrix3DTransformOperation>(other_op);
// If either matrix is non-invertible, fail and fallback to replace.
if (!matrix_.IsInvertible() || !other.matrix_.IsInvertible())
diff --git a/chromium/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.h b/chromium/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.h
index 9c61b1265e2..81d3fd814f5 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.h
+++ b/chromium/third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.h
@@ -27,6 +27,7 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TRANSFORMS_MATRIX_3D_TRANSFORM_OPERATION_H_
#include "third_party/blink/renderer/platform/transforms/transform_operation.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -81,7 +82,13 @@ class PLATFORM_EXPORT Matrix3DTransformOperation final
TransformationMatrix matrix_;
};
-DEFINE_TRANSFORM_TYPE_CASTS(Matrix3DTransformOperation);
+template <>
+struct DowncastTraits<Matrix3DTransformOperation> {
+ static bool AllowFrom(const TransformOperation& transform) {
+ return Matrix3DTransformOperation::IsMatchingOperationType(
+ transform.GetType());
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/transforms/matrix_transform_operation.cc b/chromium/third_party/blink/renderer/platform/transforms/matrix_transform_operation.cc
index 7ac6a31d386..ba42dc2947a 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/matrix_transform_operation.cc
+++ b/chromium/third_party/blink/renderer/platform/transforms/matrix_transform_operation.cc
@@ -28,7 +28,7 @@ namespace blink {
scoped_refptr<TransformOperation> MatrixTransformOperation::Accumulate(
const TransformOperation& other_op) {
DCHECK(other_op.IsSameType(*this));
- const MatrixTransformOperation& other = ToMatrixTransformOperation(other_op);
+ const auto& other = To<MatrixTransformOperation>(other_op);
TransformationMatrix from_t(other.a_, other.b_, other.c_, other.d_, other.e_,
other.f_);
diff --git a/chromium/third_party/blink/renderer/platform/transforms/matrix_transform_operation.h b/chromium/third_party/blink/renderer/platform/transforms/matrix_transform_operation.h
index bb943c2a603..d601a30c3fd 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/matrix_transform_operation.h
+++ b/chromium/third_party/blink/renderer/platform/transforms/matrix_transform_operation.h
@@ -27,6 +27,7 @@
#include "third_party/blink/renderer/platform/transforms/transform_operation.h"
#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -109,7 +110,13 @@ class PLATFORM_EXPORT MatrixTransformOperation final
double f_;
};
-DEFINE_TRANSFORM_TYPE_CASTS(MatrixTransformOperation);
+template <>
+struct DowncastTraits<MatrixTransformOperation> {
+ static bool AllowFrom(const TransformOperation& transform) {
+ return MatrixTransformOperation::IsMatchingOperationType(
+ transform.GetType());
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/transforms/perspective_transform_operation.cc b/chromium/third_party/blink/renderer/platform/transforms/perspective_transform_operation.cc
index 7a491ab9d84..83fe6f2b0a0 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/perspective_transform_operation.cc
+++ b/chromium/third_party/blink/renderer/platform/transforms/perspective_transform_operation.cc
@@ -33,7 +33,7 @@ namespace blink {
scoped_refptr<TransformOperation> PerspectiveTransformOperation::Accumulate(
const TransformOperation& other) {
DCHECK(other.IsSameType(*this));
- double other_p = ToPerspectiveTransformOperation(other).p_;
+ double other_p = To<PerspectiveTransformOperation>(other).p_;
if (p_ == 0 && other_p == 0)
return nullptr;
diff --git a/chromium/third_party/blink/renderer/platform/transforms/perspective_transform_operation.h b/chromium/third_party/blink/renderer/platform/transforms/perspective_transform_operation.h
index 24628650440..e89ec30853f 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/perspective_transform_operation.h
+++ b/chromium/third_party/blink/renderer/platform/transforms/perspective_transform_operation.h
@@ -27,6 +27,7 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TRANSFORMS_PERSPECTIVE_TRANSFORM_OPERATION_H_
#include "third_party/blink/renderer/platform/transforms/transform_operation.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -78,7 +79,13 @@ class PLATFORM_EXPORT PerspectiveTransformOperation final
double p_;
};
-DEFINE_TRANSFORM_TYPE_CASTS(PerspectiveTransformOperation);
+template <>
+struct DowncastTraits<PerspectiveTransformOperation> {
+ static bool AllowFrom(const TransformOperation& transform) {
+ return PerspectiveTransformOperation::IsMatchingOperationType(
+ transform.GetType());
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/transforms/rotate_transform_operation.cc b/chromium/third_party/blink/renderer/platform/transforms/rotate_transform_operation.cc
index 4910951d0e3..648e24665ae 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/rotate_transform_operation.cc
+++ b/chromium/third_party/blink/renderer/platform/transforms/rotate_transform_operation.cc
@@ -43,7 +43,7 @@ bool RotateTransformOperation::operator==(
const TransformOperation& other) const {
if (!IsSameType(other))
return false;
- const Rotation& other_rotation = ToRotateTransformOperation(other).rotation_;
+ const auto& other_rotation = To<RotateTransformOperation>(other).rotation_;
return rotation_.axis == other_rotation.axis &&
rotation_.angle == other_rotation.angle;
}
@@ -62,7 +62,7 @@ scoped_refptr<TransformOperation> RotateTransformOperation::Accumulate(
const TransformOperation& other) {
DCHECK(IsMatchingOperationType(other.GetType()));
Rotation new_rotation =
- Rotation::Add(rotation_, ToRotateTransformOperation(other).rotation_);
+ Rotation::Add(rotation_, To<RotateTransformOperation>(other).rotation_);
return RotateTransformOperation::Create(new_rotation,
GetTypeForRotation(new_rotation));
}
@@ -91,8 +91,7 @@ scoped_refptr<TransformOperation> RotateTransformOperation::Blend(
DCHECK(from->PrimitiveType() == OperationType::kRotate3D);
OperationType type =
from->IsSameType(*this) ? type_ : OperationType::kRotate3D;
- const RotateTransformOperation& from_rotate =
- ToRotateTransformOperation(*from);
+ const auto& from_rotate = To<RotateTransformOperation>(*from);
return RotateTransformOperation::Create(
Rotation::Slerp(from_rotate.rotation_, rotation_, progress), type);
}
@@ -123,8 +122,7 @@ bool RotateAroundOriginTransformOperation::operator==(
const TransformOperation& other) const {
if (!IsSameType(other))
return false;
- const RotateAroundOriginTransformOperation& other_rotate =
- ToRotateAroundOriginTransformOperation(other);
+ const auto& other_rotate = To<RotateAroundOriginTransformOperation>(other);
const Rotation& other_rotation = other_rotate.rotation_;
return rotation_.axis == other_rotation.axis &&
rotation_.angle == other_rotation.angle &&
@@ -146,8 +144,7 @@ scoped_refptr<TransformOperation> RotateAroundOriginTransformOperation::Blend(
return RotateAroundOriginTransformOperation::Create(Angle() * progress,
origin_x_, origin_y_);
}
- const RotateAroundOriginTransformOperation& from_rotate =
- ToRotateAroundOriginTransformOperation(*from);
+ const auto& from_rotate = To<RotateAroundOriginTransformOperation>(*from);
return RotateAroundOriginTransformOperation::Create(
blink::Blend(from_rotate.Angle(), Angle(), progress),
blink::Blend(from_rotate.origin_x_, origin_x_, progress),
diff --git a/chromium/third_party/blink/renderer/platform/transforms/rotate_transform_operation.h b/chromium/third_party/blink/renderer/platform/transforms/rotate_transform_operation.h
index d5f7bdd8d1e..b0e054ca1fe 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/rotate_transform_operation.h
+++ b/chromium/third_party/blink/renderer/platform/transforms/rotate_transform_operation.h
@@ -28,6 +28,7 @@
#include "third_party/blink/renderer/platform/geometry/float_point_3d.h"
#include "third_party/blink/renderer/platform/transforms/rotation.h"
#include "third_party/blink/renderer/platform/transforms/transform_operation.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -107,7 +108,13 @@ class PLATFORM_EXPORT RotateTransformOperation : public TransformOperation {
const OperationType type_;
};
-DEFINE_TRANSFORM_TYPE_CASTS(RotateTransformOperation);
+template <>
+struct DowncastTraits<RotateTransformOperation> {
+ static bool AllowFrom(const TransformOperation& transform) {
+ return RotateTransformOperation::IsMatchingOperationType(
+ transform.GetType());
+ }
+};
class PLATFORM_EXPORT RotateAroundOriginTransformOperation final
: public RotateTransformOperation {
@@ -141,7 +148,13 @@ class PLATFORM_EXPORT RotateAroundOriginTransformOperation final
double origin_y_;
};
-DEFINE_TRANSFORM_TYPE_CASTS(RotateAroundOriginTransformOperation);
+template <>
+struct DowncastTraits<RotateAroundOriginTransformOperation> {
+ static bool AllowFrom(const TransformOperation& transform) {
+ return RotateAroundOriginTransformOperation::IsMatchingOperationType(
+ transform.GetType());
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/transforms/scale_transform_operation.cc b/chromium/third_party/blink/renderer/platform/transforms/scale_transform_operation.cc
index 0f326e4ce8a..b6fb9a86cd5 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/scale_transform_operation.cc
+++ b/chromium/third_party/blink/renderer/platform/transforms/scale_transform_operation.cc
@@ -49,7 +49,7 @@ TransformOperation::OperationType GetTypeForScale(double x,
scoped_refptr<TransformOperation> ScaleTransformOperation::Accumulate(
const TransformOperation& other) {
DCHECK(other.CanBlendWith(*this));
- const auto& other_op = ToScaleTransformOperation(other);
+ const auto& other_op = To<ScaleTransformOperation>(other);
// Scale parameters are one in the identity transform function so use
// accumulation for one-based values.
double new_x = x_ + other_op.x_ - 1;
@@ -76,9 +76,11 @@ scoped_refptr<TransformOperation> ScaleTransformOperation::Blend(
double from_x = from_op ? from_op->x_ : 1.0;
double from_y = from_op ? from_op->y_ : 1.0;
double from_z = from_op ? from_op->z_ : 1.0;
+
+ bool is_3d = Is3DOperation() || (from && from->Is3DOperation());
return ScaleTransformOperation::Create(
blink::Blend(from_x, x_, progress), blink::Blend(from_y, y_, progress),
- blink::Blend(from_z, z_, progress), type_);
+ blink::Blend(from_z, z_, progress), is_3d ? kScale3D : kScale);
}
bool ScaleTransformOperation::CanBlendWith(
diff --git a/chromium/third_party/blink/renderer/platform/transforms/scale_transform_operation.h b/chromium/third_party/blink/renderer/platform/transforms/scale_transform_operation.h
index 874e3efd558..39c678804c4 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/scale_transform_operation.h
+++ b/chromium/third_party/blink/renderer/platform/transforms/scale_transform_operation.h
@@ -26,6 +26,7 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TRANSFORMS_SCALE_TRANSFORM_OPERATION_H_
#include "third_party/blink/renderer/platform/transforms/transform_operation.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -99,7 +100,13 @@ class PLATFORM_EXPORT ScaleTransformOperation final
OperationType type_;
};
-DEFINE_TRANSFORM_TYPE_CASTS(ScaleTransformOperation);
+template <>
+struct DowncastTraits<ScaleTransformOperation> {
+ static bool AllowFrom(const TransformOperation& transform) {
+ return ScaleTransformOperation::IsMatchingOperationType(
+ transform.GetType());
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/transforms/skew_transform_operation.cc b/chromium/third_party/blink/renderer/platform/transforms/skew_transform_operation.cc
index 15eeabb0ed9..30c27055dfd 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/skew_transform_operation.cc
+++ b/chromium/third_party/blink/renderer/platform/transforms/skew_transform_operation.cc
@@ -28,7 +28,7 @@ namespace blink {
scoped_refptr<TransformOperation> SkewTransformOperation::Accumulate(
const TransformOperation& other) {
DCHECK(other.CanBlendWith(*this));
- const SkewTransformOperation& skew_other = ToSkewTransformOperation(other);
+ const auto& skew_other = To<SkewTransformOperation>(other);
return SkewTransformOperation::Create(angle_x_ + skew_other.angle_x_,
angle_y_ + skew_other.angle_y_, type_);
}
diff --git a/chromium/third_party/blink/renderer/platform/transforms/skew_transform_operation.h b/chromium/third_party/blink/renderer/platform/transforms/skew_transform_operation.h
index 368ddfcb371..ab38b71f6ef 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/skew_transform_operation.h
+++ b/chromium/third_party/blink/renderer/platform/transforms/skew_transform_operation.h
@@ -27,6 +27,7 @@
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/platform/transforms/transform_operation.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -78,7 +79,12 @@ class PLATFORM_EXPORT SkewTransformOperation final : public TransformOperation {
OperationType type_;
};
-DEFINE_TRANSFORM_TYPE_CASTS(SkewTransformOperation);
+template <>
+struct DowncastTraits<SkewTransformOperation> {
+ static bool AllowFrom(const TransformOperation& transform) {
+ return SkewTransformOperation::IsMatchingOperationType(transform.GetType());
+ }
+};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/transforms/transform_operation.h b/chromium/third_party/blink/renderer/platform/transforms/transform_operation.h
index 6ccfd1d7c04..9ab8a4cd9bf 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/transform_operation.h
+++ b/chromium/third_party/blink/renderer/platform/transforms/transform_operation.h
@@ -114,11 +114,6 @@ class PLATFORM_EXPORT TransformOperation
DISALLOW_COPY_AND_ASSIGN(TransformOperation);
};
-#define DEFINE_TRANSFORM_TYPE_CASTS(thisType) \
- DEFINE_TYPE_CASTS(thisType, TransformOperation, transform, \
- thisType::IsMatchingOperationType(transform->GetType()), \
- thisType::IsMatchingOperationType(transform.GetType()))
-
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TRANSFORMS_TRANSFORM_OPERATION_H_
diff --git a/chromium/third_party/blink/renderer/platform/transforms/translate_transform_operation.cc b/chromium/third_party/blink/renderer/platform/transforms/translate_transform_operation.cc
index 86fc8ff89ec..43dfa1f4ef9 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/translate_transform_operation.cc
+++ b/chromium/third_party/blink/renderer/platform/transforms/translate_transform_operation.cc
@@ -46,15 +46,15 @@ TransformOperation::OperationType GetTypeForTranslate(const Length& x,
bool x_zero = x.IsZero();
bool y_zero = x.IsZero();
bool z_zero = !z;
- if (!x_zero && !y_zero && !z_zero)
- return TransformOperation::kTranslate3D;
if (y_zero && z_zero)
return TransformOperation::kTranslateX;
if (x_zero && z_zero)
return TransformOperation::kTranslateY;
if (x_zero && y_zero)
return TransformOperation::kTranslateZ;
- return TransformOperation::kTranslate;
+ if (z_zero)
+ return TransformOperation::kTranslate;
+ return TransformOperation::kTranslate3D;
}
} // namespace
@@ -62,7 +62,7 @@ scoped_refptr<TransformOperation> TranslateTransformOperation::Accumulate(
const TransformOperation& other) {
DCHECK(other.CanBlendWith(*this));
- const auto& other_op = ToTranslateTransformOperation(other);
+ const auto& other_op = To<TranslateTransformOperation>(other);
Length new_x = AddLengths(x_, other_op.x_);
Length new_y = AddLengths(y_, other_op.y_);
double new_z = z_ + other_op.z_;
@@ -85,14 +85,16 @@ scoped_refptr<TransformOperation> TranslateTransformOperation::Blend(
blink::Blend(z_, 0., progress), type_);
}
- const auto* from_op = ToTranslateTransformOperation(from);
+ const auto* from_op = To<TranslateTransformOperation>(from);
const Length& from_x = from_op ? from_op->x_ : zero_length;
const Length& from_y = from_op ? from_op->y_ : zero_length;
double from_z = from_op ? from_op->z_ : 0;
+
+ bool is_3d = Is3DOperation() || (from && from->Is3DOperation());
return TranslateTransformOperation::Create(
x_.Blend(from_x, progress, kValueRangeAll),
y_.Blend(from_y, progress, kValueRangeAll),
- blink::Blend(from_z, z_, progress), type_);
+ blink::Blend(from_z, z_, progress), is_3d ? kTranslate3D : kTranslate);
}
bool TranslateTransformOperation::CanBlendWith(
diff --git a/chromium/third_party/blink/renderer/platform/transforms/translate_transform_operation.h b/chromium/third_party/blink/renderer/platform/transforms/translate_transform_operation.h
index b73cb80331e..6cdf6d9d37b 100644
--- a/chromium/third_party/blink/renderer/platform/transforms/translate_transform_operation.h
+++ b/chromium/third_party/blink/renderer/platform/transforms/translate_transform_operation.h
@@ -28,6 +28,7 @@
#include "third_party/blink/renderer/platform/geometry/length.h"
#include "third_party/blink/renderer/platform/geometry/length_functions.h"
#include "third_party/blink/renderer/platform/transforms/transform_operation.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -119,7 +120,13 @@ class PLATFORM_EXPORT TranslateTransformOperation final
OperationType type_;
};
-DEFINE_TRANSFORM_TYPE_CASTS(TranslateTransformOperation);
+template <>
+struct DowncastTraits<TranslateTransformOperation> {
+ static bool AllowFrom(const TransformOperation& transform) {
+ return TranslateTransformOperation::IsMatchingOperationType(
+ transform.GetType());
+ }
+};
} // namespace blink
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 e88c93054d6..4be9b4f4f6a 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
@@ -17,6 +17,7 @@
#include <utility>
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/macros.h"
#include "base/stl_util.h"
#include "base/trace_event/trace_event.h"
@@ -553,17 +554,16 @@ void VideoCaptureImpl::OnBufferReady(
uint8_t* u_data =
y_data + (media::VideoFrame::Rows(media::VideoFrame::kYPlane,
info->pixel_format,
- info->coded_size.height) *
+ info->coded_size.height()) *
info->strides->stride_by_plane[0]);
uint8_t* v_data =
u_data + (media::VideoFrame::Rows(media::VideoFrame::kUPlane,
info->pixel_format,
- info->coded_size.height) *
+ info->coded_size.height()) *
info->strides->stride_by_plane[1]);
frame = media::VideoFrame::WrapExternalYuvData(
info->pixel_format, gfx::Size(info->coded_size),
- gfx::Rect(info->visible_rect),
- gfx::Size(info->visible_rect.width, info->visible_rect.height),
+ gfx::Rect(info->visible_rect), info->visible_rect.size(),
info->strides->stride_by_plane[0],
info->strides->stride_by_plane[1],
info->strides->stride_by_plane[2], y_data, u_data, v_data,
@@ -571,8 +571,7 @@ void VideoCaptureImpl::OnBufferReady(
} else {
frame = media::VideoFrame::WrapExternalData(
info->pixel_format, gfx::Size(info->coded_size),
- gfx::Rect(info->visible_rect),
- gfx::Size(info->visible_rect.width, info->visible_rect.height),
+ gfx::Rect(info->visible_rect), info->visible_rect.size(),
const_cast<uint8_t*>(buffer_context->data()),
buffer_context->data_size(), info->timestamp);
}
@@ -582,8 +581,7 @@ void VideoCaptureImpl::OnBufferReady(
// the data without attaching the shared region to the frame.
frame = media::VideoFrame::WrapExternalData(
info->pixel_format, gfx::Size(info->coded_size),
- gfx::Rect(info->visible_rect),
- gfx::Size(info->visible_rect.width, info->visible_rect.height),
+ gfx::Rect(info->visible_rect), info->visible_rect.size(),
const_cast<uint8_t*>(buffer_context->data()),
buffer_context->data_size(), info->timestamp);
break;
@@ -600,8 +598,7 @@ void VideoCaptureImpl::OnBufferReady(
frame = media::VideoFrame::WrapNativeTextures(
info->pixel_format, mailbox_holder_array,
media::VideoFrame::ReleaseMailboxCB(), gfx::Size(info->coded_size),
- gfx::Rect(info->visible_rect),
- gfx::Size(info->visible_rect.width, info->visible_rect.height),
+ gfx::Rect(info->visible_rect), info->visible_rect.size(),
info->timestamp);
break;
}
@@ -641,8 +638,7 @@ void VideoCaptureImpl::OnBufferReady(
FROM_HERE,
base::BindOnce(
&BufferContext::BindBufferToTextureOnMediaThread,
- std::move(buffer_context), base::Passed(&info),
- base::Passed(&gmb), frame,
+ std::move(buffer_context), std::move(info), std::move(gmb), frame,
media::BindToCurrentLoop(base::BindOnce(
&VideoCaptureImpl::OnVideoFrameReady,
weak_factory_.GetWeakPtr(), buffer_id, reference_time))));
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 2a1682941ce..650f0da130d 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
@@ -148,10 +148,10 @@ class VideoCaptureImplTest : public ::testing::Test {
void(const Vector<media::VideoCaptureFormat>&));
void StartCapture(int client_id, const media::VideoCaptureParams& params) {
- const auto state_update_callback = base::Bind(
+ const auto state_update_callback = WTF::BindRepeating(
&VideoCaptureImplTest::OnStateUpdate, base::Unretained(this));
- const auto frame_ready_callback =
- base::Bind(&VideoCaptureImplTest::OnFrameReady, base::Unretained(this));
+ const auto frame_ready_callback = WTF::BindRepeating(
+ &VideoCaptureImplTest::OnFrameReady, base::Unretained(this));
video_capture_impl_->StartCapture(client_id, params, state_update_callback,
frame_ready_callback);
@@ -199,8 +199,8 @@ class VideoCaptureImplTest : public ::testing::Test {
info->timestamp = now - base::TimeTicks();
info->pixel_format = pixel_format;
- info->coded_size = WebSize(size);
- info->visible_rect = WebRect(gfx::Rect(size));
+ info->coded_size = size;
+ info->visible_rect = gfx::Rect(size);
info->color_space = gfx::ColorSpace();
video_capture_impl_->OnBufferReady(buffer_id, std::move(info));
@@ -211,17 +211,14 @@ class VideoCaptureImplTest : public ::testing::Test {
}
void GetDeviceSupportedFormats() {
- const base::Callback<void(const Vector<media::VideoCaptureFormat>&)>
- callback = base::Bind(&VideoCaptureImplTest::OnDeviceSupportedFormats,
- base::Unretained(this));
- video_capture_impl_->GetDeviceSupportedFormats(callback);
+ video_capture_impl_->GetDeviceSupportedFormats(
+ WTF::Bind(&VideoCaptureImplTest::OnDeviceSupportedFormats,
+ base::Unretained(this)));
}
void GetDeviceFormatsInUse() {
- const base::Callback<void(const Vector<media::VideoCaptureFormat>&)>
- callback = base::Bind(&VideoCaptureImplTest::OnDeviceFormatsInUse,
- base::Unretained(this));
- video_capture_impl_->GetDeviceFormatsInUse(callback);
+ video_capture_impl_->GetDeviceFormatsInUse(WTF::Bind(
+ &VideoCaptureImplTest::OnDeviceFormatsInUse, base::Unretained(this)));
}
void OnStateChanged(media::mojom::VideoCaptureState state) {
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/DEPS b/chromium/third_party/blink/renderer/platform/weborigin/DEPS
index 0d5faf41ba0..ee4bd6ccd3e 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/DEPS
+++ b/chromium/third_party/blink/renderer/platform/weborigin/DEPS
@@ -18,3 +18,7 @@ include_rules = [
"+third_party/blink/renderer/platform/testing",
"+third_party/blink/renderer/platform/wtf",
]
+
+specific_include_rules = {
+ "kurl_test.cc": [ "+third_party/blink/renderer/platform/scheduler/public/thread.h" ],
+} \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/kurl.cc b/chromium/third_party/blink/renderer/platform/weborigin/kurl.cc
index 4ab44fc6c7d..ce96d1bef63 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/kurl.cc
+++ b/chromium/third_party/blink/renderer/platform/weborigin/kurl.cc
@@ -36,6 +36,7 @@
#include "third_party/blink/renderer/platform/wtf/text/string_statics.h"
#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
#include "third_party/blink/renderer/platform/wtf/text/text_encoding.h"
+#include "third_party/blink/renderer/platform/wtf/thread_specific.h"
#include "url/gurl.h"
#include "url/url_util.h"
#ifndef NDEBUG
@@ -125,12 +126,6 @@ bool IsValidProtocol(const String& protocol) {
return true;
}
-void KURL::Initialize() {
- // This must be called before we create other threads to
- // avoid racy static local initialization.
- BlankURL();
-}
-
String KURL::StrippedForUseAsReferrer() const {
if (!ProtocolIsInHTTPFamily())
return String();
@@ -169,8 +164,11 @@ bool ProtocolIsJavaScript(const String& url) {
}
const KURL& BlankURL() {
- DEFINE_STATIC_LOCAL(KURL, static_blank_url, ("about:blank"));
- return static_blank_url;
+ DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<KURL>, static_blank_url, ());
+ KURL& blank_url = *static_blank_url;
+ if (blank_url.IsNull())
+ blank_url = KURL(AtomicString("about:blank"));
+ return blank_url;
}
bool KURL::IsAboutBlankURL() const {
@@ -178,8 +176,11 @@ bool KURL::IsAboutBlankURL() const {
}
const KURL& SrcdocURL() {
- DEFINE_STATIC_LOCAL(KURL, static_srcdoc_url, ("about:srcdoc"));
- return static_srcdoc_url;
+ DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<KURL>, static_srcdoc_url, ());
+ KURL& srcdoc_url = *static_srcdoc_url;
+ if (srcdoc_url.IsNull())
+ srcdoc_url = KURL(AtomicString("about:srcdoc"));
+ return srcdoc_url;
}
bool KURL::IsAboutSrcdocURL() const {
@@ -187,8 +188,8 @@ bool KURL::IsAboutSrcdocURL() const {
}
const KURL& NullURL() {
- DEFINE_THREAD_SAFE_STATIC_LOCAL(KURL, static_null_url, ());
- return static_null_url;
+ DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<KURL>, static_null_url, ());
+ return *static_null_url;
}
String KURL::ElidedString() const {
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/kurl.h b/chromium/third_party/blink/renderer/platform/weborigin/kurl.h
index 6500b29d892..8ddb31a682b 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/kurl.h
+++ b/chromium/third_party/blink/renderer/platform/weborigin/kurl.h
@@ -77,10 +77,6 @@ class PLATFORM_EXPORT KURL {
USING_FAST_MALLOC(KURL);
public:
- // This must be called during initialization (before we create
- // other threads).
- static void Initialize();
-
KURL();
KURL(const KURL&);
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 32b3ae8a580..94a471da823 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/kurl_test.cc
+++ b/chromium/third_party/blink/renderer/platform/weborigin/kurl_test.cc
@@ -37,6 +37,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/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "url/url_util.h"
@@ -873,6 +874,43 @@ TEST(KURLTest, strippedForUseAsReferrer) {
}
}
+TEST(KURLTest, ThreadSafesStaticKurlGetters) {
+#if DCHECK_IS_ON()
+ // Simulate the static getters being called during/after threads have been
+ // started, so that StaticSingleton's thread checks will be applied.
+ WTF::WillCreateThread();
+#endif
+
+ // Take references to the static KURLs, so that each has two references to
+ // its internal StringImpl, rather than one.
+ KURL blank_url = BlankURL();
+ EXPECT_FALSE(blank_url.IsEmpty());
+ KURL srcdoc_url = SrcdocURL();
+ EXPECT_FALSE(srcdoc_url.IsEmpty());
+ KURL null_url = NullURL();
+ EXPECT_TRUE(null_url.IsNull());
+
+ auto thread =
+ Thread::CreateThread(ThreadCreationParams(ThreadType::kTestThread));
+ thread->GetTaskRunner()->PostTask(FROM_HERE, base::BindOnce([]() {
+ // Reference each of the static KURLs
+ // again, from the background thread,
+ // which should succeed without thread
+ // verifier checks firing.
+ KURL blank_url = BlankURL();
+ EXPECT_FALSE(blank_url.IsEmpty());
+ KURL srcdoc_url = SrcdocURL();
+ EXPECT_FALSE(srcdoc_url.IsEmpty());
+ KURL null_url = NullURL();
+ EXPECT_TRUE(null_url.IsNull());
+ }));
+
+#if DCHECK_IS_ON()
+ // Restore the IsBeforeThreadCreated() flag.
+ WTF::SetIsBeforeThreadCreatedForTest();
+#endif
+}
+
enum class PortIsValid {
// The constructor does strict checking. Ports which are considered valid by
// the constructor are kAlways valid.
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/reporting_disposition.h b/chromium/third_party/blink/renderer/platform/weborigin/reporting_disposition.h
new file mode 100644
index 00000000000..54060e075c4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/weborigin/reporting_disposition.h
@@ -0,0 +1,17 @@
+// 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_PLATFORM_WEBORIGIN_REPORTING_DISPOSITION_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEBORIGIN_REPORTING_DISPOSITION_H_
+
+namespace blink {
+
+enum class ReportingDisposition {
+ kSuppressReporting,
+ kReport,
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEBORIGIN_REPORTING_DISPOSITION_H_
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.cc b/chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.cc
index 3903a94f5df..5e53886a855 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.cc
+++ b/chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.cc
@@ -112,12 +112,6 @@ URLSchemesRegistry& GetMutableURLSchemesRegistry() {
} // namespace
-// Must be called before we create other threads to avoid racy static local
-// initialization.
-void SchemeRegistry::Initialize() {
- GetURLSchemesRegistry();
-}
-
void SchemeRegistry::RegisterURLSchemeAsLocal(const String& scheme) {
DCHECK_EQ(scheme, scheme.LowerASCII());
GetMutableURLSchemesRegistry().local_schemes.insert(scheme);
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.h b/chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.h
index 4ef1bdfd07f..3a6f7734f19 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.h
+++ b/chromium/third_party/blink/renderer/platform/weborigin/scheme_registry.h
@@ -49,8 +49,6 @@ class PLATFORM_EXPORT SchemeRegistry {
STATIC_ONLY(SchemeRegistry);
public:
- static void Initialize();
-
static void RegisterURLSchemeAsLocal(const String&);
static bool ShouldTreatURLSchemeAsLocal(const String&);
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/security_origin.cc b/chromium/third_party/blink/renderer/platform/weborigin/security_origin.cc
index e71853c7d3c..c448d326226 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/security_origin.cc
+++ b/chromium/third_party/blink/renderer/platform/weborigin/security_origin.cc
@@ -237,7 +237,7 @@ scoped_refptr<SecurityOrigin> SecurityOrigin::CreateFromUrlOrigin(
DCHECK(String::FromUTF8(tuple.host()).ContainsOnlyASCIIOrEmpty());
scoped_refptr<SecurityOrigin> tuple_origin;
- if (!tuple.IsInvalid()) {
+ if (tuple.IsValid()) {
String scheme = String::FromUTF8(tuple.scheme());
String host = String::FromUTF8(tuple.host());
uint16_t port = tuple.port();
@@ -327,58 +327,7 @@ bool SecurityOrigin::CanAccess(const SecurityOrigin* other,
return true;
}
- // This is needed to ensure an origin can access to itself under nullified
- // document.domain.
- // TODO(tzik): Update the nulled domain handling and remove this condition.
- if (this == other) {
- detail = AccessResultDomainDetail::kDomainNotRelevant;
- return true;
- }
-
- if (IsOpaque() || other->IsOpaque()) {
- detail = AccessResultDomainDetail::kDomainNotRelevant;
- return nonce_if_opaque_ == other->nonce_if_opaque_;
- }
-
- // document.domain handling, as per
- // https://html.spec.whatwg.org/C/#dom-document-domain:
- //
- // 1) Neither document has set document.domain. In this case, we insist
- // that the scheme, host, and port of the URLs match.
- //
- // 2) Both documents have set document.domain. In this case, we insist
- // that the documents have set document.domain to the same value and
- // that the scheme of the URLs match. Ports do not need to match.
- bool can_access = false;
- if (protocol_ == other->protocol_) {
- if (!domain_was_set_in_dom_ && !other->domain_was_set_in_dom_) {
- detail = AccessResultDomainDetail::kDomainNotSet;
- if (host_ == other->host_ && port_ == other->port_)
- can_access = true;
- } else if (domain_was_set_in_dom_ && other->domain_was_set_in_dom_) {
- if (domain_ == other->domain_) {
- can_access = true;
- detail = (host_ == other->host_ && port_ == other->port_)
- ? AccessResultDomainDetail::kDomainMatchUnnecessary
- : AccessResultDomainDetail::kDomainMatchNecessary;
- } else {
- detail = (host_ == other->host_ && port_ == other->port_)
- ? AccessResultDomainDetail::kDomainMismatch
- : AccessResultDomainDetail::kDomainNotRelevant;
- }
- } else {
- detail = (host_ == other->host_ && port_ == other->port_)
- ? AccessResultDomainDetail::kDomainSetByOnlyOneOrigin
- : AccessResultDomainDetail::kDomainNotRelevant;
- }
- } else {
- detail = AccessResultDomainDetail::kDomainNotRelevant;
- }
-
- if (can_access && IsLocal() && !PassesFileCheck(other)) {
- detail = AccessResultDomainDetail::kDomainNotRelevant;
- can_access = false;
- }
+ bool can_access = IsSameOriginDomainWith(other, detail);
// Compare that the clusters are the same.
if (can_access && !cross_agent_cluster_access_ &&
@@ -629,6 +578,65 @@ bool SecurityOrigin::AreSameOrigin(const KURL& a, const KURL& b) {
return origin_b->IsSameOriginWith(origin_a.get());
}
+bool SecurityOrigin::IsSameOriginDomainWith(
+ const SecurityOrigin* other,
+ AccessResultDomainDetail& detail) const {
+ // This is needed to ensure an origin can access to itself under nullified
+ // document.domain.
+ // TODO(tzik): Update the nulled domain handling and remove this condition.
+ if (this == other) {
+ detail = AccessResultDomainDetail::kDomainNotRelevant;
+ return true;
+ }
+
+ if (IsOpaque() || other->IsOpaque()) {
+ detail = AccessResultDomainDetail::kDomainNotRelevant;
+ return nonce_if_opaque_ == other->nonce_if_opaque_;
+ }
+
+ // document.domain handling, as per
+ // https://html.spec.whatwg.org/C/#dom-document-domain:
+ //
+ // 1) Neither document has set document.domain. In this case, we insist
+ // that the scheme, host, and port of the URLs match.
+ //
+ // 2) Both documents have set document.domain. In this case, we insist
+ // that the documents have set document.domain to the same value and
+ // that the scheme of the URLs match. Ports do not need to match.
+ bool can_access = false;
+ if (protocol_ == other->protocol_) {
+ if (!domain_was_set_in_dom_ && !other->domain_was_set_in_dom_) {
+ detail = AccessResultDomainDetail::kDomainNotSet;
+ if (host_ == other->host_ && port_ == other->port_)
+ can_access = true;
+ } else if (domain_was_set_in_dom_ && other->domain_was_set_in_dom_) {
+ if (domain_ == other->domain_) {
+ can_access = true;
+ detail = (host_ == other->host_ && port_ == other->port_)
+ ? AccessResultDomainDetail::kDomainMatchUnnecessary
+ : AccessResultDomainDetail::kDomainMatchNecessary;
+ } else {
+ detail = (host_ == other->host_ && port_ == other->port_)
+ ? AccessResultDomainDetail::kDomainMismatch
+ : AccessResultDomainDetail::kDomainNotRelevant;
+ }
+ } else {
+ detail = (host_ == other->host_ && port_ == other->port_)
+ ? AccessResultDomainDetail::kDomainSetByOnlyOneOrigin
+ : AccessResultDomainDetail::kDomainNotRelevant;
+ }
+ } else {
+ detail = AccessResultDomainDetail::kDomainNotRelevant;
+ }
+
+ if (can_access && IsLocal() && !PassesFileCheck(other)) {
+ detail = AccessResultDomainDetail::kDomainNotRelevant;
+ can_access = false;
+ }
+
+ return can_access;
+}
+
const KURL& SecurityOrigin::UrlWithUniqueOpaqueOrigin() {
DCHECK(IsMainThread());
DEFINE_STATIC_LOCAL(const KURL, url, ("data:,"));
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/security_origin.h b/chromium/third_party/blink/renderer/platform/weborigin/security_origin.h
index 7a02c33ca25..f2ee4da33cf 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/security_origin.h
+++ b/chromium/third_party/blink/renderer/platform/weborigin/security_origin.h
@@ -139,19 +139,22 @@ class PLATFORM_EXPORT SecurityOrigin : public RefCounted<SecurityOrigin> {
static bool IsSecure(const KURL&);
// Returns true if this SecurityOrigin can script objects in the given
- // SecurityOrigin. For example, call this function before allowing
- // script from one security origin to read or write objects from
- // another SecurityOrigin.
+ // SecurityOrigin. This check is similar to `IsSameOriginDomainWith()`, but
+ // additionally takes "universal access" flag into account, as well as the
+ // origin's agent cluster (see https://tc39.es/ecma262/#sec-agent-clusters).
+ //
+ // Note: This kind of access check should be rare; `IsSameOriginWith()` is
+ // almost certainly the right choice for new security checks.
+ //
+ // TODO(1027191): We're currently calling this method in a number of places
+ // where either `IsSameOriginWith()` or `IsSameOriginDomainWith()` might
+ // be more appropriate. We should audit its existing usage, and it might
+ // make sense to move it out of SecurityOrigin entirely to align it more
+ // tightly with `BindingSecurity` where it's clearly necessary.
bool CanAccess(const SecurityOrigin* other) const {
AccessResultDomainDetail unused_detail;
return CanAccess(other, unused_detail);
}
-
- // Returns true if this SecurityOrigin can script objects in |other|, just
- // as above, but also returns the category into which the access check fell.
- //
- // TODO(crbug.com/787905): Remove this variant once we have enough data to
- // make decisions about `document.domain`.
bool CanAccess(const SecurityOrigin* other, AccessResultDomainDetail&) const;
// Returns true if this SecurityOrigin can read content retrieved from
@@ -294,6 +297,25 @@ class PLATFORM_EXPORT SecurityOrigin : public RefCounted<SecurityOrigin> {
bool IsSameOriginWith(const SecurityOrigin*) const;
static bool AreSameOrigin(const KURL& a, const KURL& b);
+ // This method implements HTML's "same origin-domain" check, which takes
+ // `document.domain` into account when comparing two origins.
+ //
+ // This method does not take the "universal access" flag into account. It does
+ // take the "local access" flag into account, considering `file:` origins that
+ // set the flag to be same origin-domain with all other `file:` origins that
+ // set the flag (assuming no `document.domain` mismatch).
+ //
+ // Note: Same origin-domain checks should be rare, and `IsSameOriginWith()`
+ // is almost certainly the right choice for new security checks.
+ //
+ // https://html.spec.whatwg.org/#same-origin-domain
+ bool IsSameOriginDomainWith(const SecurityOrigin* other) const {
+ AccessResultDomainDetail unused_detail;
+ return IsSameOriginDomainWith(other, unused_detail);
+ }
+ bool IsSameOriginDomainWith(const SecurityOrigin*,
+ AccessResultDomainDetail&) const;
+
static const KURL& UrlWithUniqueOpaqueOrigin();
// Transfer origin privileges from another security origin.
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/security_origin_test.cc b/chromium/third_party/blink/renderer/platform/weborigin/security_origin_test.cc
index 3c10ca1288f..879eef2c67e 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/security_origin_test.cc
+++ b/chromium/third_party/blink/renderer/platform/weborigin/security_origin_test.cc
@@ -662,6 +662,7 @@ TEST_F(SecurityOriginTest, CanonicalizeHost) {
}
TEST_F(SecurityOriginTest, UrlOriginConversions) {
+ url::ScopedSchemeRegistryForTests scoped_registry;
url::AddLocalScheme("nonstandard-but-local");
SchemeRegistry::RegisterURLSchemeAsLocal("nonstandard-but-local");
struct TestCases {
@@ -884,6 +885,7 @@ TEST_F(SecurityOriginTest, NonStandardScheme) {
}
TEST_F(SecurityOriginTest, NonStandardSchemeWithAndroidWebViewHack) {
+ url::ScopedSchemeRegistryForTests scoped_registry;
url::EnableNonStandardSchemesForAndroidWebView();
scoped_refptr<const SecurityOrigin> origin =
SecurityOrigin::CreateFromString("cow://");
@@ -891,7 +893,6 @@ TEST_F(SecurityOriginTest, NonStandardSchemeWithAndroidWebViewHack) {
EXPECT_EQ("cow", origin->Protocol());
EXPECT_EQ("", origin->Host());
EXPECT_EQ(0, origin->Port());
- url::ResetForTests();
}
TEST_F(SecurityOriginTest, OpaqueIsolatedCopy) {
@@ -960,7 +961,7 @@ TEST_F(SecurityOriginTest, IsSameOriginWith) {
// Opaque
{false, "data:text/html,whatever", "data:text/html,whatever"}};
- for (auto test : tests) {
+ for (const auto& test : tests) {
SCOPED_TRACE(testing::Message() << "Origin 1: `" << test.a << "` "
<< "Origin 2: `" << test.b << "`\n");
scoped_refptr<SecurityOrigin> a = SecurityOrigin::CreateFromString(test.a);
@@ -1036,4 +1037,136 @@ TEST_F(SecurityOriginTest, IsSameOriginWithWithLocalScheme) {
EXPECT_FALSE(b->IsSameOriginWith(a.get()));
}
+TEST_F(SecurityOriginTest, IsSameOriginDomainWith) {
+ struct TestCase {
+ bool same_origin_domain;
+ const char* a;
+ const char* domain_a; // empty string === no `domain` set.
+ const char* b;
+ const char* domain_b;
+ } tests[] = {
+ {true, "https://a.com", "", "https://a.com", ""},
+ {false, "https://a.com", "a.com", "https://a.com", ""},
+ {true, "https://a.com", "a.com", "https://a.com", "a.com"},
+ {false, "https://sub.a.com", "", "https://a.com", ""},
+ {false, "https://sub.a.com", "a.com", "https://a.com", ""},
+ {true, "https://sub.a.com", "a.com", "https://a.com", "a.com"},
+ {true, "https://sub.a.com", "a.com", "https://sub.a.com", "a.com"},
+ {true, "https://sub.a.com", "a.com", "https://sub.sub.a.com", "a.com"},
+
+ // Schemes.
+ {false, "https://a.com", "", "http://a.com", ""},
+ {false, "https://a.com", "a.com", "http://a.com", ""},
+ {false, "https://a.com", "a.com", "http://a.com", "a.com"},
+ {false, "https://sub.a.com", "a.com", "http://a.com", ""},
+ {false, "https://a.com", "a.com", "http://sub.a.com", "a.com"},
+
+ // Ports? Why would they matter?
+ {true, "https://a.com:443", "", "https://a.com", ""},
+ {false, "https://a.com:444", "", "https://a.com", ""},
+ {false, "https://a.com:444", "", "https://a.com:442", ""},
+
+ {false, "https://a.com:443", "a.com", "https://a.com", ""},
+ {false, "https://a.com:444", "a.com", "https://a.com", ""},
+ {false, "https://a.com:444", "a.com", "https://a.com:442", ""},
+
+ {true, "https://a.com:443", "a.com", "https://a.com", "a.com"},
+ {true, "https://a.com:444", "a.com", "https://a.com", "a.com"},
+ {true, "https://a.com:444", "a.com", "https://a.com:442", "a.com"},
+
+ {false, "https://sub.a.com:443", "", "https://a.com", ""},
+ {false, "https://sub.a.com:444", "", "https://a.com", ""},
+ {false, "https://sub.a.com:444", "", "https://a.com:442", ""},
+
+ {false, "https://sub.a.com:443", "a.com", "https://a.com", ""},
+ {false, "https://sub.a.com:444", "a.com", "https://a.com", ""},
+ {false, "https://sub.a.com:444", "a.com", "https://a.com:442", ""},
+
+ {true, "https://sub.a.com:443", "a.com", "https://a.com", "a.com"},
+ {true, "https://sub.a.com:444", "a.com", "https://a.com", "a.com"},
+ {true, "https://sub.a.com:444", "a.com", "https://a.com:442", "a.com"},
+ };
+
+ for (const auto& test : tests) {
+ SCOPED_TRACE(testing::Message()
+ << "Origin 1: `" << test.a << "` (`" << test.domain_a << "`)\n"
+ << "Origin 2: `" << test.b << "` (`" << test.domain_b
+ << "`)\n");
+ scoped_refptr<SecurityOrigin> a = SecurityOrigin::CreateFromString(test.a);
+ if (strlen(test.domain_a))
+ a->SetDomainFromDOM(test.domain_a);
+ scoped_refptr<SecurityOrigin> b = SecurityOrigin::CreateFromString(test.b);
+ if (strlen(test.domain_b))
+ b->SetDomainFromDOM(test.domain_b);
+ EXPECT_EQ(test.same_origin_domain, a->IsSameOriginDomainWith(b.get()));
+ EXPECT_EQ(test.same_origin_domain, b->IsSameOriginDomainWith(a.get()));
+
+ // Self-comparison
+ EXPECT_TRUE(a->IsSameOriginDomainWith(a.get()));
+ EXPECT_TRUE(b->IsSameOriginDomainWith(b.get()));
+
+ // DeriveNewOpaqueOrigin
+ EXPECT_FALSE(a->DeriveNewOpaqueOrigin()->IsSameOriginDomainWith(a.get()));
+ EXPECT_FALSE(b->DeriveNewOpaqueOrigin()->IsSameOriginDomainWith(a.get()));
+ EXPECT_FALSE(a->DeriveNewOpaqueOrigin()->IsSameOriginDomainWith(b.get()));
+ EXPECT_FALSE(b->DeriveNewOpaqueOrigin()->IsSameOriginDomainWith(b.get()));
+ EXPECT_FALSE(b->IsSameOriginDomainWith(a->DeriveNewOpaqueOrigin().get()));
+ EXPECT_FALSE(b->IsSameOriginDomainWith(a->DeriveNewOpaqueOrigin().get()));
+ EXPECT_FALSE(a->IsSameOriginDomainWith(b->DeriveNewOpaqueOrigin().get()));
+ EXPECT_FALSE(b->IsSameOriginDomainWith(b->DeriveNewOpaqueOrigin().get()));
+ EXPECT_FALSE(a->DeriveNewOpaqueOrigin()->IsSameOriginDomainWith(
+ a->DeriveNewOpaqueOrigin().get()));
+ EXPECT_FALSE(b->DeriveNewOpaqueOrigin()->IsSameOriginDomainWith(
+ b->DeriveNewOpaqueOrigin().get()));
+
+ // UniversalAccess does not override.
+ a->GrantUniversalAccess();
+ EXPECT_EQ(test.same_origin_domain, a->IsSameOriginDomainWith(b.get()));
+ EXPECT_EQ(test.same_origin_domain, b->IsSameOriginDomainWith(a.get()));
+ }
+}
+
+TEST_F(SecurityOriginTest, IsSameOriginDomainWithWithLocalScheme) {
+ scoped_refptr<SecurityOrigin> a =
+ SecurityOrigin::CreateFromString("file:///etc/passwd");
+ scoped_refptr<SecurityOrigin> b =
+ SecurityOrigin::CreateFromString("file:///etc/hosts");
+
+ // Self-comparison
+ EXPECT_TRUE(a->IsSameOriginDomainWith(a.get()));
+ EXPECT_TRUE(b->IsSameOriginDomainWith(b.get()));
+
+ // block_local_access_from_local_origin_ defaults to `false`:
+ EXPECT_TRUE(a->IsSameOriginDomainWith(b.get()));
+ EXPECT_TRUE(b->IsSameOriginDomainWith(a.get()));
+
+ // DeriveNewOpaqueOrigin
+ EXPECT_FALSE(a->DeriveNewOpaqueOrigin()->IsSameOriginDomainWith(a.get()));
+ EXPECT_FALSE(b->DeriveNewOpaqueOrigin()->IsSameOriginDomainWith(a.get()));
+ EXPECT_FALSE(a->DeriveNewOpaqueOrigin()->IsSameOriginDomainWith(b.get()));
+ EXPECT_FALSE(b->DeriveNewOpaqueOrigin()->IsSameOriginDomainWith(b.get()));
+ EXPECT_FALSE(b->IsSameOriginDomainWith(a->DeriveNewOpaqueOrigin().get()));
+ EXPECT_FALSE(b->IsSameOriginDomainWith(a->DeriveNewOpaqueOrigin().get()));
+ EXPECT_FALSE(a->IsSameOriginDomainWith(b->DeriveNewOpaqueOrigin().get()));
+ EXPECT_FALSE(b->IsSameOriginDomainWith(b->DeriveNewOpaqueOrigin().get()));
+ EXPECT_FALSE(a->DeriveNewOpaqueOrigin()->IsSameOriginDomainWith(
+ a->DeriveNewOpaqueOrigin().get()));
+ EXPECT_FALSE(b->DeriveNewOpaqueOrigin()->IsSameOriginDomainWith(
+ b->DeriveNewOpaqueOrigin().get()));
+
+ // Set block_local_access_from_local_origin_ to `true`:
+ a->BlockLocalAccessFromLocalOrigin();
+ EXPECT_FALSE(a->IsSameOriginDomainWith(b.get()));
+ EXPECT_FALSE(b->IsSameOriginDomainWith(a.get()));
+
+ // Self-comparison should still be true.
+ EXPECT_TRUE(a->IsSameOriginDomainWith(a.get()));
+ EXPECT_TRUE(b->IsSameOriginDomainWith(b.get()));
+
+ // UniversalAccess does not override
+ a->GrantUniversalAccess();
+ EXPECT_FALSE(a->IsSameOriginDomainWith(b.get()));
+ EXPECT_FALSE(b->IsSameOriginDomainWith(a.get()));
+}
+
} // namespace blink
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 6f93952427c..a1d26ce91c1 100644
--- a/chromium/third_party/blink/renderer/platform/weborigin/security_policy.cc
+++ b/chromium/third_party/blink/renderer/platform/weborigin/security_policy.cc
@@ -72,8 +72,7 @@ network::mojom::ReferrerPolicy ReferrerPolicyResolveDefault(
network::mojom::ReferrerPolicy referrer_policy) {
if (referrer_policy == network::mojom::ReferrerPolicy::kDefault) {
if (RuntimeEnabledFeatures::ReducedReferrerGranularityEnabled()) {
- return network::mojom::ReferrerPolicy::
- kNoReferrerWhenDowngradeOriginWhenCrossOrigin;
+ return network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin;
} else {
return network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade;
}
@@ -160,8 +159,7 @@ Referrer SecurityPolicy::GenerateReferrer(
: origin + "/",
referrer_policy_no_default);
}
- case network::mojom::ReferrerPolicy::
- kNoReferrerWhenDowngradeOriginWhenCrossOrigin: {
+ case network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin: {
scoped_refptr<const SecurityOrigin> referrer_origin =
SecurityOrigin::Create(referrer_url);
scoped_refptr<const SecurityOrigin> url_origin =
@@ -328,8 +326,7 @@ bool SecurityPolicy::ReferrerPolicyFromString(
return true;
}
if (EqualIgnoringASCIICase(policy, "strict-origin-when-cross-origin")) {
- *result = network::mojom::ReferrerPolicy::
- kNoReferrerWhenDowngradeOriginWhenCrossOrigin;
+ *result = network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin;
return true;
}
if (EqualIgnoringASCIICase(policy, "no-referrer-when-downgrade") ||
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 2c6e996fef8..ecc706ea8ea 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
@@ -32,10 +32,15 @@
#include "services/network/public/mojom/cors.mojom-blink.h"
#include "services/network/public/mojom/cors_origin_pattern.mojom-blink.h"
+#include "services/network/public/mojom/referrer_policy.mojom-shared.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
+#include "url/url_canon.h"
+#include "url/url_util.h"
namespace blink {
@@ -97,6 +102,9 @@ TEST(SecurityPolicyTest, GenerateReferrer) {
"blob:http://a.test/b3aae9c8-7f90-440d-8d7c-43aa20d72fde";
const char kFilesystemURL[] = "filesystem:http://a.test/path/t/file.html";
+ bool reduced_granularity =
+ RuntimeEnabledFeatures::ReducedReferrerGranularityEnabled();
+
TestCase inputs[] = {
// HTTP -> HTTP: Same Origin
{network::mojom::ReferrerPolicy::kAlways, kInsecureURLA, kInsecureURLA,
@@ -115,15 +123,14 @@ TEST(SecurityPolicyTest, GenerateReferrer) {
kInsecureURLA, kInsecureURLA},
{network::mojom::ReferrerPolicy::kStrictOrigin, kInsecureURLA,
kInsecureURLA, kInsecureOriginA},
- {network::mojom::ReferrerPolicy::
- kNoReferrerWhenDowngradeOriginWhenCrossOrigin,
+ {network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin,
kInsecureURLA, kInsecureURLA, kInsecureURLA},
// HTTP -> HTTP: Cross Origin
{network::mojom::ReferrerPolicy::kAlways, kInsecureURLA, kInsecureURLB,
kInsecureURLA},
{network::mojom::ReferrerPolicy::kDefault, kInsecureURLA, kInsecureURLB,
- kInsecureURLA},
+ reduced_granularity ? kInsecureOriginA : kInsecureURLA},
{network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade, kInsecureURLA,
kInsecureURLB, kInsecureURLA},
{network::mojom::ReferrerPolicy::kNever, kInsecureURLA, kInsecureURLB,
@@ -136,8 +143,7 @@ TEST(SecurityPolicyTest, GenerateReferrer) {
kInsecureURLB, nullptr},
{network::mojom::ReferrerPolicy::kStrictOrigin, kInsecureURLA,
kInsecureURLB, kInsecureOriginA},
- {network::mojom::ReferrerPolicy::
- kNoReferrerWhenDowngradeOriginWhenCrossOrigin,
+ {network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin,
kInsecureURLA, kInsecureURLB, kInsecureOriginA},
// HTTPS -> HTTPS: Same Origin
@@ -157,15 +163,14 @@ TEST(SecurityPolicyTest, GenerateReferrer) {
kSecureURLA},
{network::mojom::ReferrerPolicy::kStrictOrigin, kSecureURLA, kSecureURLA,
kSecureOriginA},
- {network::mojom::ReferrerPolicy::
- kNoReferrerWhenDowngradeOriginWhenCrossOrigin,
+ {network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin,
kSecureURLA, kSecureURLA, kSecureURLA},
// HTTPS -> HTTPS: Cross Origin
{network::mojom::ReferrerPolicy::kAlways, kSecureURLA, kSecureURLB,
kSecureURLA},
{network::mojom::ReferrerPolicy::kDefault, kSecureURLA, kSecureURLB,
- kSecureURLA},
+ reduced_granularity ? kSecureOriginA : kSecureURLA},
{network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade, kSecureURLA,
kSecureURLB, kSecureURLA},
{network::mojom::ReferrerPolicy::kNever, kSecureURLA, kSecureURLB,
@@ -178,15 +183,14 @@ TEST(SecurityPolicyTest, GenerateReferrer) {
nullptr},
{network::mojom::ReferrerPolicy::kStrictOrigin, kSecureURLA, kSecureURLB,
kSecureOriginA},
- {network::mojom::ReferrerPolicy::
- kNoReferrerWhenDowngradeOriginWhenCrossOrigin,
+ {network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin,
kSecureURLA, kSecureURLB, kSecureOriginA},
// HTTP -> HTTPS
{network::mojom::ReferrerPolicy::kAlways, kInsecureURLA, kSecureURLB,
kInsecureURLA},
{network::mojom::ReferrerPolicy::kDefault, kInsecureURLA, kSecureURLB,
- kInsecureURLA},
+ reduced_granularity ? kInsecureOriginA : kInsecureURLA},
{network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade, kInsecureURLA,
kSecureURLB, kInsecureURLA},
{network::mojom::ReferrerPolicy::kNever, kInsecureURLA, kSecureURLB,
@@ -199,8 +203,7 @@ TEST(SecurityPolicyTest, GenerateReferrer) {
nullptr},
{network::mojom::ReferrerPolicy::kStrictOrigin, kInsecureURLA,
kSecureURLB, kInsecureOriginA},
- {network::mojom::ReferrerPolicy::
- kNoReferrerWhenDowngradeOriginWhenCrossOrigin,
+ {network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin,
kInsecureURLA, kSecureURLB, kInsecureOriginA},
// HTTPS -> HTTP
@@ -220,8 +223,7 @@ TEST(SecurityPolicyTest, GenerateReferrer) {
nullptr},
{network::mojom::ReferrerPolicy::kStrictOrigin, kSecureURLA,
kInsecureURLB, nullptr},
- {network::mojom::ReferrerPolicy::
- kNoReferrerWhenDowngradeOriginWhenCrossOrigin,
+ {network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin,
kSecureURLA, kInsecureURLB, nullptr},
// blob and filesystem URL handling
@@ -250,10 +252,18 @@ TEST(SecurityPolicyTest, GenerateReferrer) {
<< "' should have been empty: was '" << result.referrer.Utf8()
<< "'.";
}
- EXPECT_EQ(test.policy == network::mojom::ReferrerPolicy::kDefault
- ? network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade
- : test.policy,
- result.referrer_policy);
+
+ network::mojom::ReferrerPolicy expected_policy = test.policy;
+ if (expected_policy == network::mojom::ReferrerPolicy::kDefault) {
+ if (RuntimeEnabledFeatures::ReducedReferrerGranularityEnabled()) {
+ expected_policy =
+ network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin;
+ } else {
+ expected_policy =
+ network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade;
+ }
+ }
+ EXPECT_EQ(expected_policy, result.referrer_policy);
}
}
@@ -550,4 +560,47 @@ TEST_F(SecurityPolicyAccessTest, IsOriginAccessAllowedPriority) {
https_chromium_origin(), https_sub_example_origin()));
}
+// Test that referrers for custom hierarchical (standard) schemes are correctly
+// handled by the new policy. (For instance, this covers android-app://.)
+TEST(SecurityPolicyTest, ReferrerForCustomScheme) {
+ url::ScopedSchemeRegistryForTests scoped_registry;
+ const char kCustomStandardScheme[] = "my-new-scheme";
+ url::AddStandardScheme(kCustomStandardScheme, url::SCHEME_WITH_HOST);
+ SchemeRegistry::RegisterURLSchemeAsAllowedForReferrer(kCustomStandardScheme);
+
+ String kFullReferrer = "my-new-scheme://com.foo.me/this-should-be-truncated";
+ String kTruncatedReferrer = "my-new-scheme://com.foo.me/";
+
+ bool initially_enabled =
+ RuntimeEnabledFeatures::ReducedReferrerGranularityEnabled();
+
+ {
+ // With the feature off, the old default policy of
+ // no-referrer-when-downgrade should preserve the entire URL.
+ RuntimeEnabledFeatures::SetReducedReferrerGranularityEnabled(false);
+
+ EXPECT_EQ(SecurityPolicy::GenerateReferrer(
+ network::mojom::ReferrerPolicy::kDefault,
+ KURL("https://www.example.com/"), kFullReferrer)
+ .referrer,
+ kFullReferrer);
+ }
+
+ {
+ // With the feature on, the new default policy of
+ // strict-origin-when-cross-origin should truncate the referrer.
+ RuntimeEnabledFeatures::SetReducedReferrerGranularityEnabled(true);
+
+ ASSERT_TRUE(RuntimeEnabledFeatures::ReducedReferrerGranularityEnabled());
+ EXPECT_EQ(SecurityPolicy::GenerateReferrer(
+ network::mojom::ReferrerPolicy::kDefault,
+ KURL("https://www.example.com/"), kFullReferrer)
+ .referrer,
+ kTruncatedReferrer);
+ }
+
+ RuntimeEnabledFeatures::SetReducedReferrerGranularityEnabled(
+ initially_enabled);
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/weborigin/security_violation_reporting_policy.h b/chromium/third_party/blink/renderer/platform/weborigin/security_violation_reporting_policy.h
deleted file mode 100644
index 363658cbca8..00000000000
--- a/chromium/third_party/blink/renderer/platform/weborigin/security_violation_reporting_policy.h
+++ /dev/null
@@ -1,17 +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_PLATFORM_WEBORIGIN_SECURITY_VIOLATION_REPORTING_POLICY_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEBORIGIN_SECURITY_VIOLATION_REPORTING_POLICY_H_
-
-namespace blink {
-
-enum class SecurityViolationReportingPolicy {
- kSuppressReporting,
- kReport,
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEBORIGIN_SECURITY_VIOLATION_REPORTING_POLICY_H_
diff --git a/chromium/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.cc b/chromium/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.cc
index 0fc04e446e0..7a775eb7467 100644
--- a/chromium/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.cc
+++ b/chromium/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.cc
@@ -4,9 +4,14 @@
#include "third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.h"
+#include <string>
+#include <utility>
+
#include "base/logging.h"
+#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "media/base/audio_bus.h"
+#include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h"
namespace blink {
@@ -14,19 +19,26 @@ namespace {
// Used as an identifier for the down-casters.
void* const kPeerConnectionRemoteTrackIdentifier =
const_cast<void**>(&kPeerConnectionRemoteTrackIdentifier);
+
+void SendLogMessage(const std::string& message) {
+ blink::WebRtcLogMessage("PCRAS::" + message);
+}
+
} // namespace
PeerConnectionRemoteAudioTrack::PeerConnectionRemoteAudioTrack(
scoped_refptr<webrtc::AudioTrackInterface> track_interface)
: MediaStreamAudioTrack(false /* is_local_track */),
track_interface_(std::move(track_interface)) {
- DVLOG(1)
- << "PeerConnectionRemoteAudioTrack::PeerConnectionRemoteAudioTrack()";
+ blink::WebRtcLogMessage(
+ base::StringPrintf("PCRAT::PeerConnectionRemoteAudioTrack({id=%s})",
+ track_interface_->id().c_str()));
}
PeerConnectionRemoteAudioTrack::~PeerConnectionRemoteAudioTrack() {
- DVLOG(1)
- << "PeerConnectionRemoteAudioTrack::~PeerConnectionRemoteAudioTrack()";
+ blink::WebRtcLogMessage(
+ base::StringPrintf("PCRAT::~PeerConnectionRemoteAudioTrack([id=%s])",
+ track_interface_->id().c_str()));
// Ensure the track is stopped.
MediaStreamAudioTrack::Stop();
}
@@ -42,6 +54,9 @@ PeerConnectionRemoteAudioTrack* PeerConnectionRemoteAudioTrack::From(
void PeerConnectionRemoteAudioTrack::SetEnabled(bool enabled) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ blink::WebRtcLogMessage(base::StringPrintf(
+ "PCRAT::SetEnabled([id=%s] {enabled=%s})", track_interface_->id().c_str(),
+ (enabled ? "true" : "false")));
// This affects the shared state of the source for whether or not it's a part
// of the mixed audio that's rendered for remote tracks from WebRTC.
@@ -67,13 +82,13 @@ PeerConnectionRemoteAudioSource::PeerConnectionRemoteAudioSource(
track_interface_(std::move(track_interface)),
is_sink_of_peer_connection_(false) {
DCHECK(track_interface_);
- DVLOG(1)
- << "PeerConnectionRemoteAudioSource::PeerConnectionRemoteAudioSource()";
+ SendLogMessage(base::StringPrintf("PeerConnectionRemoteAudioSource([id=%s])",
+ track_interface_->id().c_str()));
}
PeerConnectionRemoteAudioSource::~PeerConnectionRemoteAudioSource() {
- DVLOG(1)
- << "PeerConnectionRemoteAudioSource::~PeerConnectionRemoteAudioSource()";
+ SendLogMessage(base::StringPrintf("~PeerConnectionRemoteAudioSource([id=%s])",
+ track_interface_->id().c_str()));
EnsureSourceIsStopped();
}
@@ -88,8 +103,8 @@ bool PeerConnectionRemoteAudioSource::EnsureSourceIsStarted() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (is_sink_of_peer_connection_)
return true;
- VLOG(1) << "Starting PeerConnection remote audio source with id="
- << track_interface_->id();
+ SendLogMessage(base::StringPrintf("EnsureSourceIsStarted([id=%s])",
+ track_interface_->id().c_str()));
track_interface_->AddSink(this);
is_sink_of_peer_connection_ = true;
return true;
@@ -98,10 +113,10 @@ bool PeerConnectionRemoteAudioSource::EnsureSourceIsStarted() {
void PeerConnectionRemoteAudioSource::EnsureSourceIsStopped() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (is_sink_of_peer_connection_) {
+ SendLogMessage(base::StringPrintf("EnsureSourceIsStopped([id=%s])",
+ track_interface_->id().c_str()));
track_interface_->RemoveSink(this);
is_sink_of_peer_connection_ = false;
- VLOG(1) << "Stopped PeerConnection remote audio source with id="
- << track_interface_->id();
}
}
@@ -149,7 +164,8 @@ void PeerConnectionRemoteAudioSource::OnData(const void* audio_data,
MediaStreamAudioSource::DeliverDataToTracks(*audio_bus_, playout_time);
#ifndef NDEBUG
- single_audio_thread_guard_.Release();
+ if (is_only_thread_here)
+ single_audio_thread_guard_.Release();
#endif
}
diff --git a/chromium/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.h b/chromium/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.h
index 46305d1b6b4..b831df797b2 100644
--- a/chromium/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.h
+++ b/chromium/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.h
@@ -9,8 +9,8 @@
#include "base/memory/scoped_refptr.h"
#include "base/synchronization/lock.h"
-#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.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/platform_export.h"
#include "third_party/webrtc/api/media_stream_interface.h"
diff --git a/chromium/third_party/blink/renderer/platform/webrtc/webrtc_source.h b/chromium/third_party/blink/renderer/platform/webrtc/webrtc_source.h
index 8ef336fe2e4..ac942e2642a 100644
--- a/chromium/third_party/blink/renderer/platform/webrtc/webrtc_source.h
+++ b/chromium/third_party/blink/renderer/platform/webrtc/webrtc_source.h
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEBRTC_WEBRTC_SOURCE_H_
#include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace base {
class UnguessableToken;
@@ -39,7 +40,7 @@ class PLATFORM_EXPORT WebRtcAudioRendererSource {
virtual void AudioRendererThreadStopped() = 0;
// Callback to notify the client of the output device the renderer is using.
- virtual void SetOutputDeviceForAec(const std::string& output_device_id) = 0;
+ virtual void SetOutputDeviceForAec(const String& output_device_id) = 0;
// Returns the UnguessableToken used to connect this stream to an input stream
// for echo cancellation.
diff --git a/chromium/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.cc b/chromium/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.cc
index bda303b71c9..d73e43710f4 100644
--- a/chromium/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.cc
+++ b/chromium/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.cc
@@ -6,6 +6,9 @@
#include "base/bind_helpers.h"
#include "base/logging.h"
+#include "base/strings/stringprintf.h"
+#include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/webrtc/common_video/include/video_frame_buffer.h"
#include "third_party/webrtc/common_video/libyuv/include/webrtc_libyuv.h"
#include "third_party/webrtc/rtc_base/ref_counted_object.h"
@@ -82,7 +85,8 @@ void IsValidFrame(const media::VideoFrame& frame) {
}
scoped_refptr<media::VideoFrame> ConstructI420VideoFrame(
- const media::VideoFrame& source_frame) {
+ const media::VideoFrame& source_frame,
+ blink::WebRtcVideoFrameAdapter::LogStatus log_to_webrtc) {
// NV12 is the only supported format.
DCHECK_EQ(source_frame.format(), media::PIXEL_FORMAT_NV12);
DCHECK_EQ(source_frame.storage_type(),
@@ -101,6 +105,22 @@ scoped_refptr<media::VideoFrame> ConstructI420VideoFrame(
((source_frame.visible_rect().x() / 2) * 2) +
((source_frame.visible_rect().y() / 2) * gmb->stride(1)));
+ if (log_to_webrtc ==
+ blink::WebRtcVideoFrameAdapter::LogStatus::kLogToWebRtc) {
+ blink::WebRtcLogMessage(base::StringPrintf(
+ "VFC::WebRtcVideoFrameAdapter : ConstructI420VideoFrame "
+ "pixel_format %d "
+ "natural_size %s coded_size %s visible_rect %s "
+ "source_plane_y %p source_plane_uv %p "
+ "source_stride_y %d, source_stride_uv %d "
+ "visible_y %p visible_uv %p",
+ static_cast<int>(source_frame.format()),
+ source_frame.natural_size().ToString().c_str(),
+ source_frame.coded_size().ToString().c_str(),
+ source_frame.visible_rect().ToString().c_str(), gmb->memory(0),
+ gmb->memory(1), gmb->stride(0), gmb->stride(1), src_y, src_uv));
+ }
+
// Convert to I420 and scale to the natural size specified in |source_frame|.
scoped_refptr<media::VideoFrame> i420_frame = media::VideoFrame::CreateFrame(
media::PIXEL_FORMAT_I420, source_frame.natural_size(),
@@ -130,8 +150,9 @@ scoped_refptr<media::VideoFrame> ConstructI420VideoFrame(
namespace blink {
WebRtcVideoFrameAdapter::WebRtcVideoFrameAdapter(
- scoped_refptr<media::VideoFrame> frame)
- : frame_(std::move(frame)) {}
+ scoped_refptr<media::VideoFrame> frame,
+ LogStatus log_to_webrtc)
+ : frame_(std::move(frame)), log_to_webrtc_(log_to_webrtc) {}
WebRtcVideoFrameAdapter::~WebRtcVideoFrameAdapter() {}
@@ -157,8 +178,12 @@ rtc::scoped_refptr<webrtc::I420BufferInterface>
WebRtcVideoFrameAdapter::CreateFrameAdapter() const {
if (frame_->storage_type() ==
media::VideoFrame::StorageType::STORAGE_GPU_MEMORY_BUFFER) {
- auto i420_frame = ConstructI420VideoFrame(*frame_);
+ auto i420_frame = ConstructI420VideoFrame(*frame_, log_to_webrtc_);
if (!i420_frame) {
+ if (log_to_webrtc_ == LogStatus::kLogToWebRtc) {
+ blink::WebRtcLogMessage(
+ "VFC::WebRtcVideoFrameAdapter couldn't contruct I420 frame");
+ }
return new rtc::RefCountedObject<
FrameAdapter<webrtc::I420BufferInterface>>(
media::VideoFrame::CreateColorFrame(frame_->natural_size(), 0u, 0x80,
@@ -166,8 +191,10 @@ WebRtcVideoFrameAdapter::CreateFrameAdapter() const {
}
// Keep |frame_| alive until |i420_frame| is destroyed.
- i420_frame->AddDestructionObserver(base::BindOnce(
- base::DoNothing::Once<scoped_refptr<media::VideoFrame>>(), frame_));
+ i420_frame->AddDestructionObserver(
+ ConvertToBaseOnceCallback(CrossThreadBindOnce(
+ base::DoNothing::Once<scoped_refptr<media::VideoFrame>>(),
+ frame_)));
IsValidFrame(*i420_frame);
return new rtc::RefCountedObject<FrameAdapter<webrtc::I420BufferInterface>>(
@@ -185,7 +212,29 @@ WebRtcVideoFrameAdapter::CreateFrameAdapter() const {
}
IsValidFrame(*frame_);
+ if (log_to_webrtc_ == LogStatus::kLogToWebRtc) {
+ blink::WebRtcLogMessage(base::StringPrintf(
+ "VFC::WebRtcVideoFrameAdapter created I420 adapter: "
+ "natural_size %s coded_size %s visible_rect %s "
+ "PlaneY %p PlaneU %p PlaneY %p StrideY %d StrideU %d StrideY %d ",
+ frame_->natural_size().ToString().c_str(),
+ frame_->coded_size().ToString().c_str(),
+ frame_->visible_rect().ToString().c_str(),
+ frame_->visible_data(media::VideoFrame::kYPlane),
+ frame_->visible_data(media::VideoFrame::kUPlane),
+ frame_->visible_data(media::VideoFrame::kVPlane),
+ frame_->stride(media::VideoFrame::kYPlane),
+ frame_->stride(media::VideoFrame::kUPlane),
+ frame_->stride(media::VideoFrame::kVPlane)));
+ }
if (media::PIXEL_FORMAT_I420A == frame_->format()) {
+ if (log_to_webrtc_ == LogStatus::kLogToWebRtc) {
+ blink::WebRtcLogMessage(base::StringPrintf(
+ "VFC::WebRtcVideoFrameAdapter pixel format is I420A. "
+ "PlaneA %p StrideA %d",
+ frame_->visible_data(media::VideoFrame::kAPlane),
+ frame_->stride(media::VideoFrame::kAPlane)));
+ }
return new rtc::RefCountedObject<
FrameAdapterWithA<webrtc::I420ABufferInterface>>(frame_);
}
diff --git a/chromium/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.h b/chromium/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.h
index 3b674a25230..e0cb044a583 100644
--- a/chromium/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.h
+++ b/chromium/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.h
@@ -12,6 +12,7 @@
#include "third_party/webrtc/api/video/video_frame_buffer.h"
namespace blink {
+
// Thin adapter from media::VideoFrame to webrtc::VideoFrameBuffer. This
// implementation is read-only and will return null if trying to get a
// non-const pointer to the pixel data. This object will be accessed from
@@ -19,7 +20,10 @@ namespace blink {
class PLATFORM_EXPORT WebRtcVideoFrameAdapter
: public webrtc::VideoFrameBuffer {
public:
- explicit WebRtcVideoFrameAdapter(scoped_refptr<media::VideoFrame> frame);
+ enum class LogStatus { kNoLogging, kLogToWebRtc };
+
+ WebRtcVideoFrameAdapter(scoped_refptr<media::VideoFrame> frame,
+ LogStatus log_to_webrtc);
scoped_refptr<media::VideoFrame> getMediaVideoFrame() const { return frame_; }
@@ -41,6 +45,8 @@ class PLATFORM_EXPORT WebRtcVideoFrameAdapter
mutable rtc::scoped_refptr<webrtc::I420BufferInterface> frame_adapter_;
scoped_refptr<media::VideoFrame> frame_;
+
+ const LogStatus log_to_webrtc_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter_test.cc b/chromium/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter_test.cc
index d65df0e8adb..f7380df85e6 100644
--- a/chromium/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter_test.cc
+++ b/chromium/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter_test.cc
@@ -25,7 +25,8 @@ TEST(WebRtcVideoFrameAdapterTest, WidthAndHeight) {
media::VideoFrame::STORAGE_OWNED_MEMORY);
rtc::scoped_refptr<webrtc::VideoFrameBuffer> owned_memory_frame_adapter(
new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(
- std::move(owned_memory_frame)));
+ std::move(owned_memory_frame),
+ WebRtcVideoFrameAdapter::LogStatus::kNoLogging));
EXPECT_EQ(owned_memory_frame_adapter->width(), kVisibleRect.width());
EXPECT_EQ(owned_memory_frame_adapter->height(), kVisibleRect.height());
@@ -35,7 +36,9 @@ TEST(WebRtcVideoFrameAdapterTest, WidthAndHeight) {
CreateTestFrame(kCodedSize, kVisibleRect, kNaturalSize,
media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER);
rtc::scoped_refptr<webrtc::VideoFrameBuffer> gmb_frame_adapter(
- new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(std::move(gmb_frame)));
+ new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(
+ std::move(gmb_frame),
+ WebRtcVideoFrameAdapter::LogStatus::kNoLogging));
EXPECT_EQ(gmb_frame_adapter->width(), kNaturalSize.width());
EXPECT_EQ(gmb_frame_adapter->height(), kNaturalSize.height());
}
@@ -52,7 +55,9 @@ TEST(WebRtcVideoFrameAdapterTest, ToI420DownScale) {
// The adapter should report width and height from the natural size for
// VideoFrame backed by GpuMemoryBuffer.
rtc::scoped_refptr<webrtc::VideoFrameBuffer> gmb_frame_adapter(
- new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(std::move(gmb_frame)));
+ new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(
+ std::move(gmb_frame),
+ WebRtcVideoFrameAdapter::LogStatus::kNoLogging));
EXPECT_EQ(gmb_frame_adapter->width(), kNaturalSize.width());
EXPECT_EQ(gmb_frame_adapter->height(), kNaturalSize.height());
diff --git a/chromium/third_party/blink/renderer/platform/widget/frame_widget.cc b/chromium/third_party/blink/renderer/platform/widget/frame_widget.cc
new file mode 100644
index 00000000000..2f471eeeba8
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/widget/frame_widget.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/widget/frame_widget.h"
+
+namespace blink {
+
+FrameWidget::~FrameWidget() = default;
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/widget/frame_widget.h b/chromium/third_party/blink/renderer/platform/widget/frame_widget.h
new file mode 100644
index 00000000000..fffcf36f899
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/widget/frame_widget.h
@@ -0,0 +1,81 @@
+// 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_WIDGET_FRAME_WIDGET_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_FRAME_WIDGET_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"
+
+namespace cc {
+class AnimationHost;
+class Layer;
+class PaintImage;
+} // namespace cc
+
+namespace blink {
+
+// In interface exposed within Blink from local root frames that provides
+// local-root specific things related to compositing and input.
+class PLATFORM_EXPORT FrameWidget {
+ public:
+ virtual ~FrameWidget();
+
+ // Returns the WebWidgetClient, which is implemented outside of blink.
+ virtual WebWidgetClient* Client() const = 0;
+
+ // Returns the compositors's AnimationHost for the widget.
+ virtual cc::AnimationHost* AnimationHost() const = 0;
+
+ // Set the browser's behavior when overscroll happens, e.g. whether to glow
+ // or navigate.
+ virtual void SetOverscrollBehavior(
+ const cc::OverscrollBehavior& overscroll_behavior) = 0;
+
+ // Posts a task with the given delay, then calls ScheduleAnimation() on the
+ // Client().
+ virtual void RequestAnimationAfterDelay(const base::TimeDelta&) = 0;
+
+ // Sets the root layer. The |layer| can be null when detaching the root layer.
+ virtual void SetRootLayer(scoped_refptr<cc::Layer> layer) = 0;
+
+ // Used to update the active selection bounds. Pass a default-constructed
+ // LayerSelection to clear it.
+ virtual void RegisterSelection(cc::LayerSelection selection) = 0;
+
+ // Image decode functionality.
+ virtual void RequestDecode(const cc::PaintImage&,
+ base::OnceCallback<void(bool)>) = 0;
+
+ // Forwards to WebFrameWidget::NotifySwapAndPresentationTime().
+ // The |callback| will be fired when the corresponding renderer frame is
+ // submitted (still called "swapped") to the display compositor (either with
+ // DidSwap or DidNotSwap).
+ virtual void NotifySwapAndPresentationTimeInBlink(
+ WebReportTimeCallback swap_callback,
+ WebReportTimeCallback presentation_callback) = 0;
+
+ // Enable or disable BeginMainFrameNotExpected signals from the compositor,
+ // which are consumed by the blink scheduler.
+ virtual void RequestBeginMainFrameNotExpected(bool request) = 0;
+
+ // A stable numeric Id for the local root's compositor. For tracing/debugging
+ // purposes.
+ virtual int GetLayerTreeId() = 0;
+
+ // Set or get what event handlers exist in the document contained in the
+ // WebWidget in order to inform the compositor thread if it is able to handle
+ // an input event, or it needs to pass it to the main thread to be handled.
+ // The class is the type of input event, and for each class there is a
+ // properties defining if the compositor thread can handle the event.
+ virtual void SetEventListenerProperties(cc::EventListenerClass,
+ cc::EventListenerProperties) = 0;
+ virtual cc::EventListenerProperties EventListenerProperties(
+ cc::EventListenerClass) const = 0;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_FRAME_WIDGET_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
new file mode 100644
index 00000000000..800bb29a8d5
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/widget/widget_base.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/platform/widget/widget_base.h"
+
+#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
+#include "mojo/public/cpp/bindings/pending_associated_remote.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
+#include "third_party/blink/renderer/platform/widget/widget_base_client.h"
+
+namespace blink {
+
+WidgetBase::WidgetBase(
+ WidgetBaseClient* client,
+ CrossVariantMojoAssociatedRemote<mojom::WidgetHostInterfaceBase>
+ widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::WidgetInterfaceBase> widget)
+ : client_(client),
+ widget_host_(std::move(widget_host)),
+ receiver_(this, std::move(widget)) {}
+
+WidgetBase::~WidgetBase() = default;
+
+void WidgetBase::SetCompositorHosts(cc::LayerTreeHost* layer_tree_host,
+ cc::AnimationHost* animation_host) {
+ layer_tree_host_ = layer_tree_host;
+ animation_host_ = animation_host;
+}
+
+cc::LayerTreeHost* WidgetBase::LayerTreeHost() const {
+ return layer_tree_host_;
+}
+
+cc::AnimationHost* WidgetBase::AnimationHost() const {
+ return animation_host_;
+}
+
+void WidgetBase::SetCompositorVisible(bool visible) {
+ if (visible)
+ was_shown_time_ = base::TimeTicks::Now();
+ else
+ first_update_visual_state_after_hidden_ = true;
+}
+
+void WidgetBase::UpdateVisualState() {
+ // When recording main frame metrics set the lifecycle reason to
+ // kBeginMainFrame, because this is the calller of UpdateLifecycle
+ // for the main frame. Otherwise, set the reason to kTests, which is
+ // the only other reason this method is called.
+ DocumentUpdateReason lifecycle_reason =
+ ShouldRecordBeginMainFrameMetrics()
+ ? DocumentUpdateReason::kBeginMainFrame
+ : DocumentUpdateReason::kTest;
+ client_->UpdateLifecycle(WebLifecycleUpdate::kAll, lifecycle_reason);
+ client_->SetSuppressFrameRequestsWorkaroundFor704763Only(false);
+ if (first_update_visual_state_after_hidden_) {
+ client_->RecordTimeToFirstActivePaint(base::TimeTicks::Now() -
+ was_shown_time_);
+ first_update_visual_state_after_hidden_ = false;
+ }
+}
+
+void WidgetBase::WillBeginCompositorFrame() {
+ client_->SetSuppressFrameRequestsWorkaroundFor704763Only(true);
+}
+
+void WidgetBase::BeginMainFrame(base::TimeTicks frame_time) {
+ client_->DispatchRafAlignedInput(frame_time);
+ client_->BeginMainFrame(frame_time);
+}
+
+bool WidgetBase::ShouldRecordBeginMainFrameMetrics() {
+ // We record metrics only when running in multi-threaded mode, not
+ // single-thread mode for testing.
+ return Thread::CompositorThread();
+}
+
+} // 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
new file mode 100644
index 00000000000..3d70fae9378
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/widget/widget_base.h
@@ -0,0 +1,75 @@
+// 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_WIDGET_WIDGET_BASE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_WIDGET_BASE_H_
+
+#include "base/time/time.h"
+#include "mojo/public/cpp/bindings/associated_receiver.h"
+#include "mojo/public/cpp/bindings/associated_remote.h"
+#include "third_party/blink/public/mojom/page/widget.mojom-blink.h"
+#include "third_party/blink/public/platform/cross_variant_mojo_util.h"
+#include "third_party/blink/renderer/platform/platform_export.h"
+
+namespace cc {
+class AnimationHost;
+class LayerTreeHost;
+} // namespace cc
+
+namespace blink {
+class WidgetBaseClient;
+
+// This class is the foundational class for all widgets that blink creates.
+// (WebPagePopupImpl, WebFrameWidgetBase) will contain an instance of this
+// class. For simplicity purposes this class will be a member of those classes.
+// It will eventually host compositing, input and emulation. See design doc:
+// https://docs.google.com/document/d/10uBnSWBaitGsaROOYO155Wb83rjOPtrgrGTrQ_pcssY/edit?ts=5e3b26f7
+class PLATFORM_EXPORT WidgetBase : public mojom::blink::Widget {
+ public:
+ WidgetBase(
+ WidgetBaseClient* client,
+ CrossVariantMojoAssociatedRemote<mojom::WidgetHostInterfaceBase>
+ widget_host,
+ CrossVariantMojoAssociatedReceiver<mojom::WidgetInterfaceBase> widget);
+ ~WidgetBase() override;
+
+ // Set the current compositor hosts.
+ void SetCompositorHosts(cc::LayerTreeHost*, cc::AnimationHost*);
+
+ // Set the compositor as visible. If |visible| is true, then the compositor
+ // will request a new layer frame sink, begin producing frames from the
+ // compositor scheduler, and in turn will update the document lifecycle.
+ void SetCompositorVisible(bool visible);
+
+ // Called to update the document lifecycle, advance the state of animations
+ // and dispatch rAF.
+ void BeginMainFrame(base::TimeTicks frame_time);
+
+ // Update the visual state of the document, running the document lifecycle.
+ void UpdateVisualState();
+
+ // Called when a compositor frame will begin.
+ void WillBeginCompositorFrame();
+
+ cc::AnimationHost* AnimationHost() const;
+ cc::LayerTreeHost* LayerTreeHost() const;
+
+ // Returns if we should gather begin main frame metrics. If there is no
+ // compositor thread this returns false.
+ static bool ShouldRecordBeginMainFrameMetrics();
+
+ private:
+ // Not owned, they are owned by the RenderWidget.
+ cc::LayerTreeHost* layer_tree_host_ = nullptr;
+ cc::AnimationHost* animation_host_ = nullptr;
+ WidgetBaseClient* client_;
+ mojo::AssociatedRemote<mojom::blink::WidgetHost> widget_host_;
+ mojo::AssociatedReceiver<mojom::blink::Widget> receiver_;
+ bool first_update_visual_state_after_hidden_ = false;
+ base::TimeTicks was_shown_time_ = base::TimeTicks::Now();
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_WIDGET_BASE_H_
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
new file mode 100644
index 00000000000..4d9d8036357
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/widget/widget_base_client.h
@@ -0,0 +1,41 @@
+// 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_WIDGET_WIDGET_BASE_CLIENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_WIDGET_BASE_CLIENT_H_
+
+#include "base/time/time.h"
+#include "third_party/blink/public/common/metrics/document_update_reason.h"
+#include "third_party/blink/public/web/web_lifecycle_update.h"
+
+namespace blink {
+
+// 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.
+class WidgetBaseClient {
+ public:
+ // Dispatch any pending input. This method will called before
+ // dispatching a RequestAnimationFrame to the widget.
+ virtual void DispatchRafAlignedInput(base::TimeTicks frame_time) = 0;
+
+ // Called to update the document lifecycle, advance the state of animations
+ // and dispatch rAF.
+ virtual void BeginMainFrame(base::TimeTicks frame_time) = 0;
+
+ // Called to record the time between when the widget was marked visible
+ // until the compositor begain producing a frame.
+ virtual void RecordTimeToFirstActivePaint(base::TimeDelta duration) = 0;
+
+ // Requests that the lifecycle of the widget be updated.
+ virtual void UpdateLifecycle(WebLifecycleUpdate requested_update,
+ DocumentUpdateReason reason) = 0;
+
+ // TODO(crbug.com/704763): Remove the need for this.
+ virtual void SetSuppressFrameRequestsWorkaroundFor704763Only(bool) {}
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_WIDGET_BASE_CLIENT_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/BUILD.gn b/chromium/third_party/blink/renderer/platform/wtf/BUILD.gn
index 6e9a1056bfa..4c07d2e881b 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/BUILD.gn
+++ b/chromium/third_party/blink/renderer/platform/wtf/BUILD.gn
@@ -4,6 +4,7 @@
assert(!is_ios)
+import("//build/config/compiler/compiler.gni")
import("//build/config/jumbo.gni")
import("//testing/test.gni")
import("//third_party/blink/renderer/config.gni")
@@ -42,6 +43,7 @@ jumbo_component("wtf") {
"allocator/partitions.h",
"assertions.cc",
"assertions.h",
+ "bit_field.h",
"bloom_filter.h",
"casting.h",
"conditional_destructor.h",
@@ -74,6 +76,7 @@ jumbo_component("wtf") {
"leak_annotations.h",
"linked_hash_set.h",
"list_hash_set.h",
+ "lru_cache.h",
"math_extras.h",
"pod_arena.h",
"pod_free_list_arena.h",
@@ -174,6 +177,7 @@ jumbo_component("wtf") {
"uuid.cc",
"uuid.h",
"vector.h",
+ "vector_backed_linked_list.h",
"vector_traits.h",
"wtf.cc",
"wtf.h",
@@ -235,14 +239,17 @@ jumbo_component("wtf") {
sources -= [ "text/atomic_string_cf.cc" ]
}
+ if (!is_debug && !optimize_for_size) {
+ configs -= [ "//build/config/compiler:default_optimization" ]
+ configs += [ "//build/config/compiler:optimize_max" ]
+ }
+
configs -= [ "//build/config/compiler:default_symbols" ]
configs += blink_symbols_config
}
test("wtf_unittests") {
- deps = [
- ":wtf_unittests_sources",
- ]
+ deps = [ ":wtf_unittests_sources" ]
}
jumbo_source_set("wtf_unittests_sources") {
@@ -251,9 +258,11 @@ jumbo_source_set("wtf_unittests_sources") {
testonly = true
sources = [
+ "allocator/atomic_operations_test.cc",
"allocator/partitions_test.cc",
"ascii_ctype_test.cc",
"assertions_test.cc",
+ "bit_field_test.cc",
"cross_thread_functional_test.cc",
"decimal_test.cc",
"deque_test.cc",
@@ -262,7 +271,9 @@ jumbo_source_set("wtf_unittests_sources") {
"functional_test.cc",
"hash_map_test.cc",
"hash_set_test.cc",
+ "linked_hash_set_test.cc",
"list_hash_set_test.cc",
+ "lru_cache_test.cc",
"math_extras_test.cc",
"pod_arena_test.cc",
"pod_arena_test_helpers.h",
@@ -294,6 +305,7 @@ jumbo_source_set("wtf_unittests_sources") {
"tree_node_test.cc",
"type_traits_test.cc",
"uuid_test.cc",
+ "vector_backed_linked_list_test.cc",
"vector_test.cc",
]
diff --git a/chromium/third_party/blink/renderer/platform/wtf/allocator/allocator.cc b/chromium/third_party/blink/renderer/platform/wtf/allocator/allocator.cc
index b69702742d8..11349c5e44f 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/allocator/allocator.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/allocator/allocator.cc
@@ -18,3 +18,57 @@ static_assert(WTF::IsStackAllocatedType<StackAllocatedType>::value,
"Failed to detect STACK_ALLOCATED macro.");
} // namespace
+
+namespace WTF {
+
+void AtomicReadMemcpy(void* to, const void* from, size_t bytes) {
+ // Check alignment of |to| and |from|
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(to) & (sizeof(size_t) - 1));
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(from) & (sizeof(size_t) - 1));
+ size_t* sizet_to = reinterpret_cast<size_t*>(to);
+ const size_t* sizet_from = reinterpret_cast<const size_t*>(from);
+ for (; bytes > sizeof(size_t);
+ bytes -= sizeof(size_t), ++sizet_to, ++sizet_from) {
+ *sizet_to = AsAtomicPtr(sizet_from)->load(std::memory_order_relaxed);
+ }
+ uint8_t* uint8t_to = reinterpret_cast<uint8_t*>(sizet_to);
+ const uint8_t* uint8t_from = reinterpret_cast<const uint8_t*>(sizet_from);
+ for (; bytes > 0; bytes -= sizeof(uint8_t), ++uint8t_to, ++uint8t_from) {
+ *uint8t_to = AsAtomicPtr(uint8t_from)->load(std::memory_order_relaxed);
+ }
+ DCHECK_EQ(0u, bytes);
+}
+
+void AtomicWriteMemcpy(void* to, const void* from, size_t bytes) {
+ // Check alignment of |to| and |from|
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(to) & (sizeof(size_t) - 1));
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(from) & (sizeof(size_t) - 1));
+ size_t* sizet_to = reinterpret_cast<size_t*>(to);
+ const size_t* sizet_from = reinterpret_cast<const size_t*>(from);
+ for (; bytes > sizeof(size_t);
+ bytes -= sizeof(size_t), ++sizet_to, ++sizet_from) {
+ AsAtomicPtr(sizet_to)->store(*sizet_from, std::memory_order_relaxed);
+ }
+ uint8_t* uint8t_to = reinterpret_cast<uint8_t*>(sizet_to);
+ const uint8_t* uint8t_from = reinterpret_cast<const uint8_t*>(sizet_from);
+ for (; bytes > 0; bytes -= sizeof(uint8_t), ++uint8t_to, ++uint8t_from) {
+ AsAtomicPtr(uint8t_to)->store(*uint8t_from, std::memory_order_relaxed);
+ }
+ DCHECK_EQ(0u, bytes);
+}
+
+void AtomicMemzero(void* buf, size_t bytes) {
+ // Check alignment of |buf|
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(buf) & (sizeof(size_t) - 1));
+ size_t* sizet_buf = reinterpret_cast<size_t*>(buf);
+ for (; bytes > sizeof(size_t); bytes -= sizeof(size_t), ++sizet_buf) {
+ AsAtomicPtr(sizet_buf)->store(0, std::memory_order_relaxed);
+ }
+ uint8_t* uint8t_buf = reinterpret_cast<uint8_t*>(sizet_buf);
+ for (; bytes > 0; bytes -= sizeof(uint8_t), ++uint8t_buf) {
+ AsAtomicPtr(uint8t_buf)->store(0, std::memory_order_relaxed);
+ }
+ DCHECK_EQ(0u, bytes);
+}
+
+} // namespace WTF
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 af536529a6d..66fc9943d46 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/allocator/allocator.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/allocator/allocator.h
@@ -5,6 +5,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_ALLOCATOR_ALLOCATOR_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_ALLOCATOR_ALLOCATOR_H_
+#include <atomic>
+
+#include "build/build_config.h"
#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/type_traits.h"
@@ -147,6 +150,205 @@ class __thisIsHereToForceASemicolonAfterThisMacro;
#define USING_FAST_MALLOC_WITH_TYPE_NAME(type) \
USING_FAST_MALLOC_INTERNAL(type, #type)
+// TOOD(omerkatz): replace these casts with std::atomic_ref (C++20) once it
+// becomes available
+template <typename T>
+ALWAYS_INLINE std::atomic<T>* AsAtomicPtr(T* t) {
+ return reinterpret_cast<std::atomic<T>*>(t);
+}
+template <typename T>
+ALWAYS_INLINE const std::atomic<T>* AsAtomicPtr(const T* t) {
+ return reinterpret_cast<const std::atomic<T>*>(t);
+}
+
+// Copies |bytes| bytes from |from| to |to| using atomic reads. Assumes |to|
+// and |from| are size_t-aligned and point to buffers of size |bytes|. Note
+// that atomicity is guaranteed only per word, not for the entire |bytes|
+// bytes as a whole. When copying arrays of elements, If |to| and |from|
+// are overlapping, should move the elements one by one.
+WTF_EXPORT void AtomicReadMemcpy(void* to, const void* from, size_t bytes);
+template <size_t bytes>
+ALWAYS_INLINE void AtomicReadMemcpy(void* to, const void* from) {
+ static_assert(bytes > 0, "Number of copied bytes should be greater than 0");
+ AtomicReadMemcpy(to, from, bytes);
+}
+
+// AtomicReadMemcpy specializations:
+
+#if defined(ARCH_CPU_X86_64)
+template <>
+ALWAYS_INLINE void AtomicReadMemcpy<sizeof(uint32_t)>(void* to,
+ const void* from) {
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(to) & (sizeof(uint32_t) - 1));
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(from) & (sizeof(uint32_t) - 1));
+ *reinterpret_cast<uint32_t*>(to) =
+ AsAtomicPtr(reinterpret_cast<const uint32_t*>(from))
+ ->load(std::memory_order_relaxed);
+}
+#endif // ARCH_CPU_X86_64
+
+template <>
+ALWAYS_INLINE void AtomicReadMemcpy<sizeof(size_t)>(void* to,
+ const void* from) {
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(to) & (sizeof(size_t) - 1));
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(from) & (sizeof(size_t) - 1));
+ *reinterpret_cast<size_t*>(to) =
+ AsAtomicPtr(reinterpret_cast<const size_t*>(from))
+ ->load(std::memory_order_relaxed);
+}
+
+template <>
+ALWAYS_INLINE void AtomicReadMemcpy<2 * sizeof(size_t)>(void* to,
+ const void* from) {
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(to) & (sizeof(size_t) - 1));
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(from) & (sizeof(size_t) - 1));
+ *reinterpret_cast<size_t*>(to) =
+ AsAtomicPtr(reinterpret_cast<const size_t*>(from))
+ ->load(std::memory_order_relaxed);
+ *(reinterpret_cast<size_t*>(to) + 1) =
+ AsAtomicPtr(reinterpret_cast<const size_t*>(from) + 1)
+ ->load(std::memory_order_relaxed);
+}
+
+template <>
+ALWAYS_INLINE void AtomicReadMemcpy<3 * sizeof(size_t)>(void* to,
+ const void* from) {
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(to) & (sizeof(size_t) - 1));
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(from) & (sizeof(size_t) - 1));
+ *reinterpret_cast<size_t*>(to) =
+ AsAtomicPtr(reinterpret_cast<const size_t*>(from))
+ ->load(std::memory_order_relaxed);
+ *(reinterpret_cast<size_t*>(to) + 1) =
+ AsAtomicPtr(reinterpret_cast<const size_t*>(from) + 1)
+ ->load(std::memory_order_relaxed);
+ *(reinterpret_cast<size_t*>(to) + 2) =
+ AsAtomicPtr(reinterpret_cast<const size_t*>(from) + 2)
+ ->load(std::memory_order_relaxed);
+}
+
+// Copies |bytes| bytes from |from| to |to| using atomic writes. Assumes |to|
+// and |from| are size_t-aligned and point to buffers of size |bytes|. Note
+// that atomicity is guaranteed only per word, not for the entire |bytes|
+// bytes as a whole. When copying arrays of elements, If |to| and |from| are
+// overlapping, should move the elements one by one.
+WTF_EXPORT void AtomicWriteMemcpy(void* to, const void* from, size_t bytes);
+template <size_t bytes>
+ALWAYS_INLINE void AtomicWriteMemcpy(void* to, const void* from) {
+ static_assert(bytes > 0, "Number of copied bytes should be greater than 0");
+ AtomicWriteMemcpy(to, from, bytes);
+}
+
+// AtomicReadMemcpy specializations:
+
+#if defined(ARCH_CPU_X86_64)
+template <>
+ALWAYS_INLINE void AtomicWriteMemcpy<sizeof(uint32_t)>(void* to,
+ const void* from) {
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(to) & (sizeof(uint32_t) - 1));
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(from) & (sizeof(uint32_t) - 1));
+ AsAtomicPtr(reinterpret_cast<uint32_t*>(to))
+ ->store(*reinterpret_cast<const uint32_t*>(from),
+ std::memory_order_relaxed);
+}
+#endif // ARCH_CPU_X86_64
+
+template <>
+ALWAYS_INLINE void AtomicWriteMemcpy<sizeof(size_t)>(void* to,
+ const void* from) {
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(to) & (sizeof(size_t) - 1));
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(from) & (sizeof(size_t) - 1));
+ AsAtomicPtr(reinterpret_cast<size_t*>(to))
+ ->store(*reinterpret_cast<const size_t*>(from),
+ std::memory_order_relaxed);
+}
+
+template <>
+ALWAYS_INLINE void AtomicWriteMemcpy<2 * sizeof(size_t)>(void* to,
+ const void* from) {
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(to) & (sizeof(size_t) - 1));
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(from) & (sizeof(size_t) - 1));
+ AsAtomicPtr(reinterpret_cast<size_t*>(to))
+ ->store(*reinterpret_cast<const size_t*>(from),
+ std::memory_order_relaxed);
+ AsAtomicPtr(reinterpret_cast<size_t*>(to) + 1)
+ ->store(*(reinterpret_cast<const size_t*>(from) + 1),
+ std::memory_order_relaxed);
+}
+
+template <>
+ALWAYS_INLINE void AtomicWriteMemcpy<3 * sizeof(size_t)>(void* to,
+ const void* from) {
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(to) & (sizeof(size_t) - 1));
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(from) & (sizeof(size_t) - 1));
+ AsAtomicPtr(reinterpret_cast<size_t*>(to))
+ ->store(*reinterpret_cast<const size_t*>(from),
+ std::memory_order_relaxed);
+ AsAtomicPtr(reinterpret_cast<size_t*>(to) + 1)
+ ->store(*(reinterpret_cast<const size_t*>(from) + 1),
+ std::memory_order_relaxed);
+ AsAtomicPtr(reinterpret_cast<size_t*>(to) + 2)
+ ->store(*(reinterpret_cast<const size_t*>(from) + 2),
+ std::memory_order_relaxed);
+}
+
+// Set the first |bytes| bytes of |buf| to 0 using atomic writes. Assumes |buf|
+// is size_t-aligned and points to a buffer of size at least |bytes|. Note
+// that atomicity is guaranteed only per word, not for the entire |bytes| bytes
+// as a whole.
+WTF_EXPORT void AtomicMemzero(void* buf, size_t bytes);
+
+template <size_t bytes>
+ALWAYS_INLINE void AtomicMemzero(void* buf) {
+ static_assert(bytes > 0, "Number of copied bytes should be greater than 0");
+ AtomicMemzero(buf, bytes);
+}
+
+// AtomicReadMemcpy specializations:
+
+#if defined(ARCH_CPU_X86_64)
+template <>
+ALWAYS_INLINE void AtomicMemzero<sizeof(uint32_t)>(void* buf) {
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(buf) & (sizeof(uint32_t) - 1));
+ AsAtomicPtr(reinterpret_cast<uint32_t*>(buf))
+ ->store(0, std::memory_order_relaxed);
+}
+#endif // ARCH_CPU_X86_64
+
+template <>
+ALWAYS_INLINE void AtomicMemzero<sizeof(size_t)>(void* buf) {
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(buf) & (sizeof(size_t) - 1));
+ AsAtomicPtr(reinterpret_cast<size_t*>(buf))
+ ->store(0, std::memory_order_relaxed);
+}
+
+template <>
+ALWAYS_INLINE void AtomicMemzero<2 * sizeof(size_t)>(void* buf) {
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(buf) & (sizeof(size_t) - 1));
+ AsAtomicPtr(reinterpret_cast<size_t*>(buf))
+ ->store(0, std::memory_order_relaxed);
+ AsAtomicPtr(reinterpret_cast<size_t*>(buf) + 1)
+ ->store(0, std::memory_order_relaxed);
+}
+
+template <>
+ALWAYS_INLINE void AtomicMemzero<3 * sizeof(size_t)>(void* buf) {
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(buf) & (sizeof(size_t) - 1));
+ AsAtomicPtr(reinterpret_cast<size_t*>(buf))
+ ->store(0, std::memory_order_relaxed);
+ AsAtomicPtr(reinterpret_cast<size_t*>(buf) + 1)
+ ->store(0, std::memory_order_relaxed);
+ AsAtomicPtr(reinterpret_cast<size_t*>(buf) + 2)
+ ->store(0, std::memory_order_relaxed);
+}
+
+// Swaps values using atomic writes.
+template <typename T>
+ALWAYS_INLINE void AtomicWriteSwap(T& lhs, T& rhs) {
+ T tmp_val = rhs;
+ AsAtomicPtr(&rhs)->store(lhs, std::memory_order_relaxed);
+ AsAtomicPtr(&lhs)->store(tmp_val, std::memory_order_relaxed);
+}
+
} // namespace WTF
// This version of placement new omits a 0 check.
@@ -156,20 +358,4 @@ inline void* operator new(size_t, NotNullTag, void* location) {
return location;
}
-#if defined(__clang__) && __has_attribute(uninitialized)
-// Attribute "uninitialized" disables -ftrivial-auto-var-init=pattern for
-// the specified variable.
-//
-// -ftrivial-auto-var-init is security risk mitigation feature, so attribute
-// should not be used "just in case", but only to fix real performance
-// bottlenecks when other approaches do not work. In general the compiler is
-// quite effective at eliminating unneeded initializations introduced by the
-// flag, e.g. when they are followed by actual initialization by a program.
-// However if compiler optimization fails and code refactoring is hard, the
-// attribute can be used as a workaround.
-#define STACK_UNINITIALIZED __attribute__((uninitialized))
-#else
-#define STACK_UNINITIALIZED
-#endif
-
#endif /* WTF_Allocator_h */
diff --git a/chromium/third_party/blink/renderer/platform/wtf/allocator/atomic_operations_test.cc b/chromium/third_party/blink/renderer/platform/wtf/allocator/atomic_operations_test.cc
new file mode 100644
index 00000000000..819b3bff584
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/wtf/allocator/atomic_operations_test.cc
@@ -0,0 +1,139 @@
+// 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/wtf/allocator/allocator.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace WTF {
+
+class AtomicOperationsTest : public ::testing::Test {};
+
+template <size_t buffer_size, typename CopyMethod>
+void TestCopyImpl(CopyMethod copy) {
+ alignas(sizeof(size_t)) unsigned char src[buffer_size];
+ for (size_t i = 0; i < buffer_size; ++i)
+ src[i] = static_cast<char>(i + 1);
+ // Allocating extra memory before and after the buffer to make sure the
+ // atomic memcpy doesn't exceed the buffer in any direction.
+ alignas(sizeof(size_t)) unsigned char tgt[buffer_size + (2 * sizeof(size_t))];
+ memset(tgt, 0, buffer_size + (2 * sizeof(size_t)));
+ copy(tgt + sizeof(size_t), src);
+ // Check nothing before the buffer was changed
+ EXPECT_EQ(0u, *reinterpret_cast<size_t*>(&tgt[0]));
+ // Check buffer was copied correctly
+ EXPECT_TRUE(!memcmp(src, tgt + sizeof(size_t), buffer_size));
+ // Check nothing after the buffer was changed
+ EXPECT_EQ(0u, *reinterpret_cast<size_t*>(&tgt[sizeof(size_t) + buffer_size]));
+}
+
+// Tests for AtomicReadMemcpy
+template <size_t buffer_size>
+void TestAtomicReadMemcpy() {
+ TestCopyImpl<buffer_size>(AtomicReadMemcpy<buffer_size>);
+}
+
+TEST_F(AtomicOperationsTest, AtomicReadMemcpy_UINT8T) {
+ TestAtomicReadMemcpy<sizeof(uint8_t)>();
+}
+TEST_F(AtomicOperationsTest, AtomicReadMemcpy_UINT16T) {
+ TestAtomicReadMemcpy<sizeof(uint16_t)>();
+}
+TEST_F(AtomicOperationsTest, AtomicReadMemcpy_UINT32T) {
+ TestAtomicReadMemcpy<sizeof(uint32_t)>();
+}
+TEST_F(AtomicOperationsTest, AtomicReadMemcpy_UINT64T) {
+ TestAtomicReadMemcpy<sizeof(uint64_t)>();
+}
+
+TEST_F(AtomicOperationsTest, AtomicReadMemcpy_17Bytes) {
+ TestAtomicReadMemcpy<17>();
+}
+TEST_F(AtomicOperationsTest, AtomicReadMemcpy_34Bytes) {
+ TestAtomicReadMemcpy<34>();
+}
+TEST_F(AtomicOperationsTest, AtomicReadMemcpy_68Bytes) {
+ TestAtomicReadMemcpy<68>();
+}
+TEST_F(AtomicOperationsTest, AtomicReadMemcpy_127Bytes) {
+ TestAtomicReadMemcpy<127>();
+}
+
+// Tests for AtomicWriteMemcpy
+template <size_t buffer_size>
+void TestAtomicWriteMemcpy() {
+ TestCopyImpl<buffer_size>(AtomicWriteMemcpy<buffer_size>);
+}
+
+TEST_F(AtomicOperationsTest, AtomicWriteMemcpy_UINT8T) {
+ TestAtomicWriteMemcpy<sizeof(uint8_t)>();
+}
+TEST_F(AtomicOperationsTest, AtomicWriteMemcpy_UINT16T) {
+ TestAtomicWriteMemcpy<sizeof(uint16_t)>();
+}
+TEST_F(AtomicOperationsTest, AtomicWriteMemcpy_UINT32T) {
+ TestAtomicWriteMemcpy<sizeof(uint32_t)>();
+}
+TEST_F(AtomicOperationsTest, AtomicWriteMemcpy_UINT64T) {
+ TestAtomicWriteMemcpy<sizeof(uint64_t)>();
+}
+
+TEST_F(AtomicOperationsTest, AtomicWriteMemcpy_17Bytes) {
+ TestAtomicWriteMemcpy<17>();
+}
+TEST_F(AtomicOperationsTest, AtomicWriteMemcpy_34Bytes) {
+ TestAtomicWriteMemcpy<34>();
+}
+TEST_F(AtomicOperationsTest, AtomicWriteMemcpy_68Bytes) {
+ TestAtomicWriteMemcpy<68>();
+}
+TEST_F(AtomicOperationsTest, AtomicWriteMemcpy_127Bytes) {
+ TestAtomicWriteMemcpy<127>();
+}
+
+// Tests for AtomicMemzero
+template <size_t buffer_size>
+void TestAtomicMemzero() {
+ // Allocating extra memory before and after the buffer to make sure the
+ // AtomicMemzero doesn't exceed the buffer in any direction.
+ alignas(sizeof(size_t)) unsigned char buf[buffer_size + (2 * sizeof(size_t))];
+ memset(buf, ~uint8_t{0}, buffer_size + (2 * sizeof(size_t)));
+ AtomicMemzero<buffer_size>(buf + sizeof(size_t));
+ // Check nothing before the buffer was changed
+ EXPECT_EQ(~size_t{0}, *reinterpret_cast<size_t*>(&buf[0]));
+ // Check buffer was copied correctly
+ static const unsigned char for_comparison[buffer_size] = {0};
+ EXPECT_TRUE(!memcmp(buf + sizeof(size_t), for_comparison, buffer_size));
+ // Check nothing after the buffer was changed
+ EXPECT_EQ(~size_t{0},
+ *reinterpret_cast<size_t*>(&buf[sizeof(size_t) + buffer_size]));
+}
+
+TEST_F(AtomicOperationsTest, AtomicMemzero_UINT8T) {
+ TestAtomicMemzero<sizeof(uint8_t)>();
+}
+TEST_F(AtomicOperationsTest, AtomicMemzero_UINT16T) {
+ TestAtomicMemzero<sizeof(uint16_t)>();
+}
+TEST_F(AtomicOperationsTest, AtomicMemzero_UINT32T) {
+ TestAtomicMemzero<sizeof(uint32_t)>();
+}
+TEST_F(AtomicOperationsTest, AtomicMemzero_UINT64T) {
+ TestAtomicMemzero<sizeof(uint64_t)>();
+}
+
+TEST_F(AtomicOperationsTest, AtomicMemzero_17Bytes) {
+ TestAtomicMemzero<17>();
+}
+TEST_F(AtomicOperationsTest, AtomicMemzero_34Bytes) {
+ TestAtomicMemzero<34>();
+}
+TEST_F(AtomicOperationsTest, AtomicMemzero_68Bytes) {
+ TestAtomicMemzero<68>();
+}
+TEST_F(AtomicOperationsTest, AtomicMemzero_127Bytes) {
+ TestAtomicMemzero<127>();
+}
+
+} // namespace WTF
diff --git a/chromium/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h b/chromium/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h
index 143b0584ce5..e1bc3a994e4 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h
@@ -76,14 +76,16 @@ class WTF_EXPORT PartitionAllocator {
Free(ptr); // Not the system free, the one from this class.
}
- static void TraceMarkedBackingStore(void*) {}
- static void BackingWriteBarrier(void*) {}
- template <typename>
- static void BackingWriteBarrierForHashTable(void*) {}
+ static void TraceBackingStoreIfMarked(const void*) {}
+ template <typename T>
+ static void BackingWriteBarrier(T**) {}
+ template <typename, typename T>
+ static void BackingWriteBarrierForHashTable(T**) {}
static bool IsAllocationAllowed() { return true; }
static bool IsObjectResurrectionForbidden() { return false; }
static bool IsSweepForbidden() { return false; }
+ static bool IsIncrementalMarking() { return false; }
static void EnterGCForbiddenScope() {}
static void LeaveGCForbiddenScope() {}
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 cde57169e59..abb17cad6d9 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.cc
@@ -36,7 +36,6 @@
#include "base/allocator/partition_allocator/partition_alloc.h"
#include "base/allocator/partition_allocator/partition_root_base.h"
#include "base/debug/alias.h"
-#include "base/lazy_instance.h"
#include "third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h"
#include "third_party/blink/renderer/platform/wtf/wtf.h"
@@ -45,63 +44,54 @@ namespace WTF {
const char* const Partitions::kAllocatedObjectPoolName =
"partition_alloc/allocated_objects";
-static base::LazyInstance<base::subtle::SpinLock>::Leaky initialization_lock_ =
- LAZY_INSTANCE_INITIALIZER;
bool Partitions::initialized_ = false;
-// These statics are inlined, so cannot be LazyInstances. We create
-// LazyInstances below, and then set the pointers correctly in Initialize().
+// 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;
-static base::LazyInstance<base::PartitionAllocatorGeneric>::Leaky
- lazy_fast_malloc = LAZY_INSTANCE_INITIALIZER;
-static base::LazyInstance<base::PartitionAllocatorGeneric>::Leaky
- lazy_array_buffer = LAZY_INSTANCE_INITIALIZER;
-static base::LazyInstance<base::PartitionAllocatorGeneric>::Leaky lazy_buffer =
- LAZY_INSTANCE_INITIALIZER;
-static base::LazyInstance<base::SizeSpecificPartitionAllocator<1024>>::Leaky
- lazy_layout = LAZY_INSTANCE_INITIALIZER;
-
+// static
void Partitions::Initialize() {
- base::subtle::SpinLock::Guard guard(initialization_lock_.Get());
-
- if (!initialized_) {
- base::PartitionAllocatorGeneric* fast_malloc_allocator =
- lazy_fast_malloc.Pointer();
- base::PartitionAllocatorGeneric* array_buffer_allocator =
- lazy_array_buffer.Pointer();
- base::PartitionAllocatorGeneric* buffer_allocator = lazy_buffer.Pointer();
- base::SizeSpecificPartitionAllocator<1024>* layout_allocator =
- lazy_layout.Pointer();
-
- base::PartitionAllocGlobalInit(&Partitions::HandleOutOfMemory);
- fast_malloc_allocator->init();
- array_buffer_allocator->init();
- buffer_allocator->init();
- layout_allocator->init();
-
- fast_malloc_root_ = fast_malloc_allocator->root();
- array_buffer_root_ = array_buffer_allocator->root();
- buffer_root_ = buffer_allocator->root();
- layout_root_ = layout_allocator->root();
-
- initialized_ = true;
- }
+ static bool initialized = InitializeOnce();
+ DCHECK(initialized);
+}
+
+// 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{};
+
+ base::PartitionAllocGlobalInit(&Partitions::HandleOutOfMemory);
+
+ fast_malloc_allocator.init();
+ array_buffer_allocator.init();
+ buffer_allocator.init();
+ layout_allocator.init();
+
+ fast_malloc_root_ = fast_malloc_allocator.root();
+ array_buffer_root_ = array_buffer_allocator.root();
+ buffer_root_ = buffer_allocator.root();
+ layout_root_ = layout_allocator.root();
+
+ initialized_ = true;
+ return initialized_;
}
// static
void Partitions::StartPeriodicReclaim(
scoped_refptr<base::SequencedTaskRunner> task_runner) {
CHECK(IsMainThread());
- if (!initialized_)
- return;
+ DCHECK(initialized_);
base::PartitionAllocMemoryReclaimer::Instance()->Start(task_runner);
}
+// static
void Partitions::DumpMemoryStats(
bool is_light_dump,
base::PartitionStatsDumper* partition_stats_dumper) {
@@ -141,6 +131,7 @@ class LightPartitionStatsDumperImpl : public base::PartitionStatsDumper {
} // namespace
+// static
size_t Partitions::TotalSizeOfCommittedPages() {
DCHECK(initialized_);
size_t total_size = 0;
@@ -151,118 +142,128 @@ size_t Partitions::TotalSizeOfCommittedPages() {
return total_size;
}
+// static
size_t Partitions::TotalActiveBytes() {
LightPartitionStatsDumperImpl dumper;
WTF::Partitions::DumpMemoryStats(true, &dumper);
return dumper.TotalActiveBytes();
}
-static NOINLINE void PartitionsOutOfMemoryUsing2G() {
+static NOINLINE void PartitionsOutOfMemoryUsing2G(size_t size) {
size_t signature = 2UL * 1024 * 1024 * 1024;
base::debug::Alias(&signature);
- OOM_CRASH();
+ OOM_CRASH(size);
}
-static NOINLINE void PartitionsOutOfMemoryUsing1G() {
+static NOINLINE void PartitionsOutOfMemoryUsing1G(size_t size) {
size_t signature = 1UL * 1024 * 1024 * 1024;
base::debug::Alias(&signature);
- OOM_CRASH();
+ OOM_CRASH(size);
}
-static NOINLINE void PartitionsOutOfMemoryUsing512M() {
+static NOINLINE void PartitionsOutOfMemoryUsing512M(size_t size) {
size_t signature = 512 * 1024 * 1024;
base::debug::Alias(&signature);
- OOM_CRASH();
+ OOM_CRASH(size);
}
-static NOINLINE void PartitionsOutOfMemoryUsing256M() {
+static NOINLINE void PartitionsOutOfMemoryUsing256M(size_t size) {
size_t signature = 256 * 1024 * 1024;
base::debug::Alias(&signature);
- OOM_CRASH();
+ OOM_CRASH(size);
}
-static NOINLINE void PartitionsOutOfMemoryUsing128M() {
+static NOINLINE void PartitionsOutOfMemoryUsing128M(size_t size) {
size_t signature = 128 * 1024 * 1024;
base::debug::Alias(&signature);
- OOM_CRASH();
+ OOM_CRASH(size);
}
-static NOINLINE void PartitionsOutOfMemoryUsing64M() {
+static NOINLINE void PartitionsOutOfMemoryUsing64M(size_t size) {
size_t signature = 64 * 1024 * 1024;
base::debug::Alias(&signature);
- OOM_CRASH();
+ OOM_CRASH(size);
}
-static NOINLINE void PartitionsOutOfMemoryUsing32M() {
+static NOINLINE void PartitionsOutOfMemoryUsing32M(size_t size) {
size_t signature = 32 * 1024 * 1024;
base::debug::Alias(&signature);
- OOM_CRASH();
+ OOM_CRASH(size);
}
-static NOINLINE void PartitionsOutOfMemoryUsing16M() {
+static NOINLINE void PartitionsOutOfMemoryUsing16M(size_t size) {
size_t signature = 16 * 1024 * 1024;
base::debug::Alias(&signature);
- OOM_CRASH();
+ OOM_CRASH(size);
}
-static NOINLINE void PartitionsOutOfMemoryUsingLessThan16M() {
+static NOINLINE void PartitionsOutOfMemoryUsingLessThan16M(size_t size) {
size_t signature = 16 * 1024 * 1024 - 1;
base::debug::Alias(&signature);
- DLOG(FATAL) << "ParitionAlloc: out of memory with < 16M usage (error:"
+ DLOG(FATAL) << "PartitionAlloc: out of memory with < 16M usage (error:"
<< base::GetAllocPageErrorCode() << ")";
+ OOM_CRASH(size);
}
+// static
void* Partitions::BufferMalloc(size_t n, const char* type_name) {
return BufferPartition()->Alloc(n, type_name);
}
+// static
void* Partitions::BufferTryRealloc(void* p, size_t n, const char* type_name) {
return BufferPartition()->TryRealloc(p, n, type_name);
}
+// static
void Partitions::BufferFree(void* p) {
BufferPartition()->Free(p);
}
+// static
size_t Partitions::BufferActualSize(size_t n) {
return BufferPartition()->ActualSize(n);
}
+// static
void* Partitions::FastMalloc(size_t n, const char* type_name) {
return FastMallocPartition()->Alloc(n, type_name);
}
+// static
void* Partitions::FastZeroedMalloc(size_t n, const char* type_name) {
return FastMallocPartition()->AllocFlags(base::PartitionAllocZeroFill, n,
type_name);
}
+// static
void Partitions::FastFree(void* p) {
FastMallocPartition()->Free(p);
}
-void Partitions::HandleOutOfMemory() {
+// static
+void Partitions::HandleOutOfMemory(size_t size) {
volatile size_t total_usage = TotalSizeOfCommittedPages();
uint32_t alloc_page_error_code = base::GetAllocPageErrorCode();
base::debug::Alias(&alloc_page_error_code);
if (total_usage >= 2UL * 1024 * 1024 * 1024)
- PartitionsOutOfMemoryUsing2G();
+ PartitionsOutOfMemoryUsing2G(size);
if (total_usage >= 1UL * 1024 * 1024 * 1024)
- PartitionsOutOfMemoryUsing1G();
+ PartitionsOutOfMemoryUsing1G(size);
if (total_usage >= 512 * 1024 * 1024)
- PartitionsOutOfMemoryUsing512M();
+ PartitionsOutOfMemoryUsing512M(size);
if (total_usage >= 256 * 1024 * 1024)
- PartitionsOutOfMemoryUsing256M();
+ PartitionsOutOfMemoryUsing256M(size);
if (total_usage >= 128 * 1024 * 1024)
- PartitionsOutOfMemoryUsing128M();
+ PartitionsOutOfMemoryUsing128M(size);
if (total_usage >= 64 * 1024 * 1024)
- PartitionsOutOfMemoryUsing64M();
+ PartitionsOutOfMemoryUsing64M(size);
if (total_usage >= 32 * 1024 * 1024)
- PartitionsOutOfMemoryUsing32M();
+ PartitionsOutOfMemoryUsing32M(size);
if (total_usage >= 16 * 1024 * 1024)
- PartitionsOutOfMemoryUsing16M();
- PartitionsOutOfMemoryUsingLessThan16M();
+ PartitionsOutOfMemoryUsing16M(size);
+ PartitionsOutOfMemoryUsingLessThan16M(size);
}
} // namespace WTF
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 48e833a2467..4dcc3564ed8 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/allocator/partitions.h
@@ -50,6 +50,7 @@ class WTF_EXPORT Partitions {
// memory snapshots.
static const char* const kAllocatedObjectPoolName;
+ // Should be called on the thread which is or will become the main one.
static void Initialize();
static void StartPeriodicReclaim(
scoped_refptr<base::SequencedTaskRunner> task_runner);
@@ -90,7 +91,7 @@ class WTF_EXPORT Partitions {
static void* FastZeroedMalloc(size_t n, const char* type_name);
static void FastFree(void* p);
- static void HandleOutOfMemory();
+ static void HandleOutOfMemory(size_t size);
private:
ALWAYS_INLINE static base::PartitionRootGeneric* FastMallocPartition() {
@@ -98,8 +99,9 @@ class WTF_EXPORT Partitions {
return fast_malloc_root_;
}
- static bool initialized_;
+ static bool InitializeOnce();
+ static bool initialized_;
// See Allocator.md for a description of these partitions.
static base::PartitionRootGeneric* fast_malloc_root_;
static base::PartitionRootGeneric* array_buffer_root_;
diff --git a/chromium/third_party/blink/renderer/platform/wtf/bit_field.h b/chromium/third_party/blink/renderer/platform/wtf/bit_field.h
new file mode 100644
index 00000000000..e65e183b475
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/wtf/bit_field.h
@@ -0,0 +1,153 @@
+// 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_BIT_FIELD_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_BIT_FIELD_H_
+
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+
+namespace WTF {
+
+enum class BitFieldValueConstness {
+ kNonConst,
+ kConst,
+};
+
+namespace internal {
+
+template <class BitFieldType>
+class BitFieldBase;
+
+// Helper class for defining values in a bit field. This helper provides
+// utilities to read, write and update the value in the bit field.
+template <class ValueType,
+ size_t offset,
+ size_t size,
+ class BitFieldType,
+ BitFieldValueConstness is_const = BitFieldValueConstness::kNonConst>
+class BitFieldValue final {
+ static_assert(std::is_fundamental<ValueType>::value,
+ "Fields in a bit field must be of a primitive type.");
+ static_assert(std::is_fundamental<BitFieldType>::value,
+ "Bit fields must be of a primitive type.");
+ static_assert(std::is_unsigned<BitFieldType>::value,
+ "Bit field must be of an unsigned type");
+ static_assert(sizeof(ValueType) <= sizeof(BitFieldType),
+ "Value in bit field cannot be bigger than the bit field");
+ static_assert(
+ offset < 8 * sizeof(BitFieldType),
+ "Field offset in bit field must be smaller than the bit field size");
+ static_assert(
+ size < 8 * sizeof(BitFieldType),
+ "Field size in bit field must be smaller than the bit field size");
+ static_assert(offset + size <= 8 * sizeof(BitFieldType),
+ "Field in bit field cannot overflow the bit field");
+ static_assert(size > 0, "Bit field fields cannot have 0 size.");
+
+ public:
+ using Type = ValueType;
+
+ template <class OtherValueType,
+ int other_size,
+ BitFieldValueConstness other_is_const =
+ BitFieldValueConstness::kNonConst>
+ using DefineNextValue = BitFieldValue<OtherValueType,
+ offset + size,
+ other_size,
+ BitFieldType,
+ other_is_const>;
+
+ // Create a bit field with the given value.
+ static constexpr BitFieldType encode(ValueType value) {
+ DCHECK(is_valid(value));
+ return static_cast<BitFieldType>(value) << offset;
+ }
+
+ // Update a bit field with the given value.
+ static constexpr BitFieldType update(BitFieldType previous, ValueType value) {
+ return (previous & ~kMask) | encode(value);
+ }
+
+ // Read the value from the bit field.
+ static constexpr ValueType decode(BitFieldType value) {
+ return static_cast<ValueType>((value & kMask) >> offset);
+ }
+
+ private:
+ static constexpr BitFieldValueConstness kIsConst = is_const;
+
+ static constexpr BitFieldType kValidationMask =
+ (BitFieldType{1} << size) - BitFieldType{1};
+ static constexpr BitFieldType kMask = (kValidationMask) << offset;
+ static_assert(kMask != 0, "Mask in which all bits are 0 is not allowed.");
+ static_assert(~kMask != 0, "Mask in which all bits are 1 is not allowed.");
+
+ // Confirm that the provided value fits into the bit field.
+ static constexpr bool is_valid(ValueType value) {
+ return (static_cast<BitFieldType>(value) & ~kValidationMask) == 0;
+ }
+
+ friend class BitFieldBase<BitFieldType>;
+};
+
+} // namespace internal
+
+// BitField intended to be used by a single thread.
+template <class BitFieldType>
+class WTF_EXPORT SingleThreadedBitField {
+ static_assert(std::is_fundamental<BitFieldType>::value,
+ "Bit fields must be of a primitive type.");
+ static_assert(std::is_unsigned<BitFieldType>::value,
+ "Bit field must be of an unsigned type");
+
+ public:
+ template <class Type,
+ int size,
+ BitFieldValueConstness is_const = BitFieldValueConstness::kNonConst>
+ using DefineFirstValue =
+ internal::BitFieldValue<Type, 0, size, BitFieldType, is_const>;
+
+ explicit SingleThreadedBitField() : SingleThreadedBitField(0) {}
+ explicit SingleThreadedBitField(BitFieldType bits) : bits_(bits) {}
+
+ template <typename Value>
+ typename Value::Type get() const {
+ return Value::decode(bits_);
+ }
+
+ template <typename Value>
+ void set(typename Value::Type value) {
+ bits_ = Value::update(bits_, value);
+ }
+
+ protected:
+ BitFieldType bits_;
+};
+
+// BitField that can be written by a single thread but read by multiple threads.
+template <class BitFieldType>
+class WTF_EXPORT ConcurrentlyReadBitField
+ : public SingleThreadedBitField<BitFieldType> {
+ using Base = SingleThreadedBitField<BitFieldType>;
+ using Base::bits_;
+
+ public:
+ explicit ConcurrentlyReadBitField() : Base(0) {}
+ explicit ConcurrentlyReadBitField(BitFieldType bits) : Base(bits) {}
+
+ template <typename Value>
+ typename Value::Type get_concurrently() const {
+ return Value::decode(AsAtomicPtr(&bits_)->load(std::memory_order_relaxed));
+ }
+
+ template <typename Value>
+ void set(typename Value::Type value) {
+ AsAtomicPtr(&bits_)->store(Value::update(bits_, value),
+ std::memory_order_relaxed);
+ }
+};
+
+} // namespace WTF
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_BIT_FIELD_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/bit_field_test.cc b/chromium/third_party/blink/renderer/platform/wtf/bit_field_test.cc
new file mode 100644
index 00000000000..795db25fbe5
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/wtf/bit_field_test.cc
@@ -0,0 +1,105 @@
+// 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/wtf/bit_field.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace WTF {
+
+class BitFieldTest : public ::testing::Test {};
+
+TEST_F(BitFieldTest, BitFieldDefaultCtor) {
+ using BitField = SingleThreadedBitField<uint32_t>;
+ using Value1 = BitField::DefineFirstValue<uint32_t, 31>;
+ using Value2 = Value1::DefineNextValue<uint32_t, 1>;
+
+ SingleThreadedBitField<uint32_t> bit_field;
+ EXPECT_EQ(0u, bit_field.get<Value1>());
+ EXPECT_EQ(0u, bit_field.get<Value2>());
+}
+
+TEST_F(BitFieldTest, BitFieldCtor) {
+ using BitField = SingleThreadedBitField<uint32_t>;
+ using Value1 = BitField::DefineFirstValue<uint32_t, 31>;
+ using Value2 = Value1::DefineNextValue<uint32_t, 1>;
+
+ SingleThreadedBitField<uint32_t> bit_field(0xdeadbeef);
+ EXPECT_EQ(0x5eadbeefu, bit_field.get<Value1>());
+ EXPECT_EQ(1u, bit_field.get<Value2>());
+}
+
+TEST_F(BitFieldTest, SplitBitField) {
+ using BitField = SingleThreadedBitField<uint32_t>;
+ using Value1 = BitField::DefineFirstValue<uint16_t, 16>;
+ using Value2 = Value1::DefineNextValue<uint16_t, 8>;
+ using Value3 = Value2::DefineNextValue<uint16_t, 8>;
+
+ SingleThreadedBitField<uint32_t> bit_field(0xdeadbeef);
+ EXPECT_EQ(0xde, bit_field.get<Value3>());
+ EXPECT_EQ(0xad, bit_field.get<Value2>());
+ EXPECT_EQ(0xbeef, bit_field.get<Value1>());
+}
+
+TEST_F(BitFieldTest, BitFieldBits) {
+ using BitField = SingleThreadedBitField<uint8_t>;
+ using Value1 = BitField::DefineFirstValue<bool, 1>;
+ using Value2 = Value1::DefineNextValue<bool, 1>;
+ using Value3 = Value2::DefineNextValue<bool, 1>;
+ using Value4 = Value3::DefineNextValue<bool, 1>;
+ using Value5 = Value4::DefineNextValue<bool, 1>;
+ using Value6 = Value5::DefineNextValue<bool, 1>;
+ using Value7 = Value6::DefineNextValue<bool, 1>;
+ using Value8 = Value7::DefineNextValue<bool, 1>;
+
+ SingleThreadedBitField<uint32_t> bit_field(0b10101010);
+ EXPECT_FALSE(bit_field.get<Value1>());
+ EXPECT_TRUE(bit_field.get<Value2>());
+ EXPECT_FALSE(bit_field.get<Value3>());
+ EXPECT_TRUE(bit_field.get<Value4>());
+ EXPECT_FALSE(bit_field.get<Value5>());
+ EXPECT_TRUE(bit_field.get<Value6>());
+ EXPECT_FALSE(bit_field.get<Value7>());
+ EXPECT_TRUE(bit_field.get<Value8>());
+}
+
+TEST_F(BitFieldTest, BitFieldSetValue) {
+ using BitField = SingleThreadedBitField<uint32_t>;
+ using Value1 = BitField::DefineFirstValue<uint16_t, 16>;
+ using Value2 = Value1::DefineNextValue<uint16_t, 16>;
+
+ SingleThreadedBitField<uint32_t> bit_field;
+ CHECK_EQ(0u, bit_field.get<Value1>());
+ CHECK_EQ(0u, bit_field.get<Value2>());
+ bit_field.set<Value1>(1337);
+ EXPECT_EQ(1337u, bit_field.get<Value1>());
+ EXPECT_EQ(0u, bit_field.get<Value2>());
+}
+
+TEST_F(BitFieldTest, ConcurrentBitFieldGettersReturnTheSame) {
+ using BitField = SingleThreadedBitField<uint32_t>;
+ using Value1 = BitField::DefineFirstValue<uint16_t, 16>;
+ using Value2 = Value1::DefineNextValue<uint16_t, 16>;
+
+ ConcurrentlyReadBitField<uint32_t> bit_field(0xdeadbeef);
+ CHECK_EQ(0xbeef, bit_field.get<Value1>());
+ CHECK_EQ(0xdead, bit_field.get<Value2>());
+ EXPECT_EQ(bit_field.get_concurrently<Value1>(), bit_field.get<Value1>());
+ EXPECT_EQ(bit_field.get_concurrently<Value2>(), bit_field.get<Value2>());
+}
+
+TEST_F(BitFieldTest, ConcurrentBitFieldSetValue) {
+ using BitField = SingleThreadedBitField<uint32_t>;
+ using Value1 = BitField::DefineFirstValue<uint16_t, 16>;
+ using Value2 = Value1::DefineNextValue<uint16_t, 16>;
+
+ ConcurrentlyReadBitField<uint32_t> bit_field;
+ CHECK_EQ(0u, bit_field.get_concurrently<Value1>());
+ CHECK_EQ(0u, bit_field.get_concurrently<Value2>());
+ bit_field.set<Value1>(1337);
+ EXPECT_EQ(1337u, bit_field.get_concurrently<Value1>());
+ EXPECT_EQ(0u, bit_field.get_concurrently<Value2>());
+}
+
+} // namespace WTF
diff --git a/chromium/third_party/blink/renderer/platform/wtf/construct_traits.h b/chromium/third_party/blink/renderer/platform/wtf/construct_traits.h
index 7812accbc0b..02741c5c9c6 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/construct_traits.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/construct_traits.h
@@ -11,9 +11,9 @@
namespace WTF {
-// ConstructTraits is used to construct elements in WTF collections. All
-// in-place constructions that may assign Oilpan objects must be dispatched
-// through ConstructAndNotifyElement.
+// ConstructTraits is used to construct elements in WTF collections.
+// All in-place constructions that may assign Oilpan objects must be
+// dispatched through ConstructAndNotifyElement.
template <typename T, typename Traits, typename Allocator>
class ConstructTraits {
STATIC_ONLY(ConstructTraits);
diff --git a/chromium/third_party/blink/renderer/platform/wtf/cross_thread_copier.h b/chromium/third_party/blink/renderer/platform/wtf/cross_thread_copier.h
index 51b1575473f..1aeaf9b843b 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/cross_thread_copier.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/cross_thread_copier.h
@@ -69,6 +69,12 @@ struct SyncToken;
namespace mojo {
template <typename Interface>
class PendingReceiver;
+template <typename Interface>
+class PendingRemote;
+template <typename Interface>
+class PendingAssociatedRemote;
+template <typename Interface>
+class PendingAssociatedReceiver;
}
namespace WTF {
@@ -80,6 +86,15 @@ struct CrossThreadCopierPassThrough {
static Type Copy(const T& parameter) { return parameter; }
};
+template <typename T>
+struct CrossThreadCopierByValuePassThrough {
+ STATIC_ONLY(CrossThreadCopierByValuePassThrough);
+ typedef T Type;
+ static Type Copy(T receiver) {
+ return receiver; // This is in fact a move.
+ }
+};
+
template <typename T, bool isArithmeticOrEnum>
struct CrossThreadCopierBase;
@@ -273,12 +288,31 @@ struct CrossThreadCopier<String> {
};
template <typename Interface>
-struct CrossThreadCopier<mojo::PendingReceiver<Interface>> {
+struct CrossThreadCopier<mojo::PendingReceiver<Interface>>
+ : public CrossThreadCopierByValuePassThrough<
+ mojo::PendingReceiver<Interface>> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+template <typename Interface>
+struct CrossThreadCopier<mojo::PendingRemote<Interface>>
+ : public CrossThreadCopierByValuePassThrough<
+ mojo::PendingRemote<Interface>> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+template <typename Interface>
+struct CrossThreadCopier<mojo::PendingAssociatedRemote<Interface>>
+ : public CrossThreadCopierByValuePassThrough<
+ mojo::PendingAssociatedRemote<Interface>> {
+ STATIC_ONLY(CrossThreadCopier);
+};
+
+template <typename Interface>
+struct CrossThreadCopier<mojo::PendingAssociatedReceiver<Interface>>
+ : public CrossThreadCopierByValuePassThrough<
+ mojo::PendingAssociatedReceiver<Interface>> {
STATIC_ONLY(CrossThreadCopier);
- using Type = mojo::PendingReceiver<Interface>;
- static Type Copy(Type receiver) {
- return receiver; // This is in fact a move.
- }
};
template <>
diff --git a/chromium/third_party/blink/renderer/platform/wtf/cross_thread_functional.h b/chromium/third_party/blink/renderer/platform/wtf/cross_thread_functional.h
index 86f58560098..973b8138f7d 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/cross_thread_functional.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/cross_thread_functional.h
@@ -75,10 +75,10 @@ auto CrossThreadBindRepeating(FunctionType&& function, Ps&&... parameters) {
std::decay_t<Ps>...>::ok,
"A bound argument uses a bad pattern.");
return internal::MakeCrossThreadFunction(
- base::Bind(internal::CoerceFunctorForCrossThreadBind(
- std::forward<FunctionType>(function)),
- CrossThreadCopier<std::decay_t<Ps>>::Copy(
- std::forward<Ps>(parameters))...));
+ base::BindRepeating(internal::CoerceFunctorForCrossThreadBind(
+ std::forward<FunctionType>(function)),
+ CrossThreadCopier<std::decay_t<Ps>>::Copy(
+ std::forward<Ps>(parameters))...));
}
template <typename FunctionType, typename... Ps>
diff --git a/chromium/third_party/blink/renderer/platform/wtf/deque.h b/chromium/third_party/blink/renderer/platform/wtf/deque.h
index e3e444e701b..4f2d25a8895 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/deque.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/deque.h
@@ -146,7 +146,7 @@ class Deque : public ConditionalDestructor<Deque<T, INLINE_CAPACITY, Allocator>,
void clear();
template <typename VisitorDispatcher, typename A = Allocator>
- std::enable_if_t<A::kIsGarbageCollected> Trace(VisitorDispatcher);
+ std::enable_if_t<A::kIsGarbageCollected> Trace(VisitorDispatcher) const;
static_assert(!std::is_polymorphic<T>::value ||
!VectorTraits<T>::kCanInitializeWithMemset,
@@ -162,6 +162,7 @@ class Deque : public ConditionalDestructor<Deque<T, INLINE_CAPACITY, Allocator>,
protected:
T** GetBufferSlot() { return buffer_.BufferSlot(); }
+ const T* const* GetBufferSlot() const { return buffer_.BufferSlot(); }
private:
friend class DequeIteratorBase<T, inlineCapacity, Allocator>;
@@ -169,8 +170,11 @@ class Deque : public ConditionalDestructor<Deque<T, INLINE_CAPACITY, Allocator>,
class BackingBuffer : public VectorBuffer<T, INLINE_CAPACITY, Allocator> {
private:
using Base = VectorBuffer<T, INLINE_CAPACITY, Allocator>;
+ using Base::BufferSafe;
using Base::size_;
+ friend class Deque;
+
public:
BackingBuffer() : Base() {}
explicit BackingBuffer(wtf_size_t capacity) : Base(capacity) {}
@@ -236,6 +240,7 @@ class DequeIterator : public DequeIteratorBase<T, inlineCapacity, Allocator> {
typedef T& reference;
typedef std::bidirectional_iterator_tag iterator_category;
+ DequeIterator() = default;
DequeIterator(Deque<T, inlineCapacity, Allocator>* deque, wtf_size_t index)
: Base(deque, index) {}
@@ -676,39 +681,23 @@ inline T* DequeIteratorBase<T, inlineCapacity, Allocator>::Before() const {
template <typename T, wtf_size_t inlineCapacity, typename Allocator>
template <typename VisitorDispatcher, typename A>
std::enable_if_t<A::kIsGarbageCollected>
-Deque<T, inlineCapacity, Allocator>::Trace(VisitorDispatcher visitor) {
+Deque<T, inlineCapacity, Allocator>::Trace(VisitorDispatcher visitor) const {
+ // Bail out for concurrent marking.
+ if (visitor->ConcurrentTracingBailOut(
+ {this, [](blink::Visitor* visitor, const void* object) {
+ reinterpret_cast<const Deque<T, inlineCapacity, Allocator>*>(
+ object)
+ ->Trace(visitor);
+ }}))
+ return;
+
+ static_assert(inlineCapacity == 0,
+ "Heap allocated Deque should not use inline buffer");
static_assert(Allocator::kIsGarbageCollected,
"Garbage collector must be enabled.");
- if (buffer_.HasOutOfLineBuffer()) {
- Allocator::TraceVectorBacking(visitor, buffer_.Buffer(),
- buffer_.BufferSlot());
- } else {
- Allocator::TraceVectorBacking(visitor, static_cast<T*>(nullptr),
- buffer_.BufferSlot());
- const T* buffer_begin = buffer_.Buffer();
- const T* end = buffer_begin + end_;
- if (IsTraceableInCollectionTrait<VectorTraits<T>>::value) {
- if (start_ <= end_) {
- for (const T* buffer_entry = buffer_begin + start_; buffer_entry != end;
- buffer_entry++) {
- Allocator::template Trace<T, VectorTraits<T>>(
- visitor, *const_cast<T*>(buffer_entry));
- }
- } else {
- for (const T* buffer_entry = buffer_begin; buffer_entry != end;
- buffer_entry++) {
- Allocator::template Trace<T, VectorTraits<T>>(
- visitor, *const_cast<T*>(buffer_entry));
- }
- const T* buffer_end = buffer_.Buffer() + buffer_.capacity();
- for (const T* buffer_entry = buffer_begin + start_;
- buffer_entry != buffer_end; buffer_entry++) {
- Allocator::template Trace<T, VectorTraits<T>>(
- visitor, *const_cast<T*>(buffer_entry));
- }
- }
- }
- }
+ const T* buffer = buffer_.BufferSafe();
+ DCHECK(!buffer || buffer_.IsOutOfLineBuffer(buffer));
+ Allocator::TraceVectorBacking(visitor, buffer, buffer_.BufferSlot());
}
template <typename T, wtf_size_t inlineCapacity, typename Allocator>
diff --git a/chromium/third_party/blink/renderer/platform/wtf/hash_counted_set.h b/chromium/third_party/blink/renderer/platform/wtf/hash_counted_set.h
index 9e15db75c15..23d62960ec9 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/hash_counted_set.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/hash_counted_set.h
@@ -106,7 +106,8 @@ class HashCountedSet {
Vector<Value> AsVector() const;
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 {
impl_.Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/platform/wtf/hash_map.h b/chromium/third_party/blink/renderer/platform/wtf/hash_map.h
index 46b39e0697f..88fc20f0ea1 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/hash_map.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/hash_map.h
@@ -22,6 +22,7 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_HASH_MAP_H_
#include <initializer_list>
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h"
#include "third_party/blink/renderer/platform/wtf/construct_traits.h"
#include "third_party/blink/renderer/platform/wtf/hash_table.h"
@@ -43,6 +44,12 @@ struct KeyValuePairKeyExtractor {
static const typename T::KeyType& Extract(const T& p) {
return p.key;
}
+ // Assumes out points to a buffer of size at least sizeof(T::KeyType).
+ template <typename T>
+ static const typename T::KeyType& ExtractSafe(const T& p, void* out) {
+ AtomicReadMemcpy<sizeof(typename T::KeyType)>(out, &p.key);
+ return *reinterpret_cast<typename T::KeyType*>(out);
+ }
};
// Note: empty or deleted key values are not allowed, using them may lead to
@@ -202,7 +209,8 @@ class HashMap {
static bool IsValidKey(const IncomingKeyType&);
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 {
impl_.Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/platform/wtf/hash_set.h b/chromium/third_party/blink/renderer/platform/wtf/hash_set.h
index d7cdeeddf1c..abef9643fb0 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/hash_set.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/hash_set.h
@@ -22,6 +22,7 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_HASH_SET_H_
#include <initializer_list>
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h"
#include "third_party/blink/renderer/platform/wtf/hash_table.h"
#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
@@ -134,7 +135,8 @@ class HashSet {
ValueType TakeAny();
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 {
impl_.Trace(visitor);
}
@@ -151,6 +153,12 @@ struct IdentityExtractor {
static const T& Extract(const T& t) {
return t;
}
+ // Assumes out points to a buffer of size at least sizeof(T).
+ template <typename T>
+ static const T& ExtractSafe(const T& t, void* out) {
+ AtomicReadMemcpy<sizeof(T)>(out, &t);
+ return *reinterpret_cast<T*>(out);
+ }
};
template <typename Translator>
diff --git a/chromium/third_party/blink/renderer/platform/wtf/hash_table.h b/chromium/third_party/blink/renderer/platform/wtf/hash_table.h
index 472e2232846..1d195f1218b 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/hash_table.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/hash_table.h
@@ -23,9 +23,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_HASH_TABLE_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_HASH_TABLE_H_
-#include <atomic>
#include <memory>
+#include "base/bits.h"
#include "base/numerics/checked_math.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h"
@@ -92,13 +92,6 @@
#endif
#endif
-namespace {
-template <typename T>
-ALWAYS_INLINE std::atomic<T>& AsAtomic(T& t) {
- return reinterpret_cast<std::atomic<T>&>(t);
-}
-} // namespace
-
namespace WTF {
// This is for tracing inside collections that have special support for weak
@@ -144,7 +137,7 @@ struct WTF_EXPORT HashTableStats {
static HashTableStats& instance();
template <typename VisitorDispatcher>
- void trace(VisitorDispatcher) {}
+ void trace(VisitorDispatcher) const {}
private:
void RecordCollisionAtCountWithoutLock(int count);
@@ -657,15 +650,32 @@ struct HashTableAddResult final {
template <typename Value, typename Extractor, typename KeyTraits>
struct HashTableHelper {
+ template <typename T>
+ struct AddConstToPtrType {
+ using type = T;
+ };
+ template <typename T>
+ struct AddConstToPtrType<T*> {
+ using type = const T*;
+ };
+
+ using Key = typename AddConstToPtrType<typename KeyTraits::TraitType>::type;
+
STATIC_ONLY(HashTableHelper);
- static bool IsEmptyBucket(const Value& value) {
- return IsHashTraitsEmptyValue<KeyTraits>(Extractor::Extract(value));
+ static bool IsEmptyBucket(const Key& key) {
+ return IsHashTraitsEmptyValue<KeyTraits>(key);
}
- static bool IsDeletedBucket(const Value& value) {
- return KeyTraits::IsDeletedValue(Extractor::Extract(value));
+ static bool IsDeletedBucket(const Key& key) {
+ return KeyTraits::IsDeletedValue(key);
}
static bool IsEmptyOrDeletedBucket(const Value& value) {
- return IsEmptyBucket(value) || IsDeletedBucket(value);
+ const Key& key = Extractor::Extract(value);
+ return IsEmptyBucket(key) || IsDeletedBucket(key);
+ }
+ static bool IsEmptyOrDeletedBucketSafe(const Value& value) {
+ alignas(std::max(alignof(Key), sizeof(size_t))) char buf[sizeof(Key)];
+ const Key& key = Extractor::ExtractSafe(value, &buf);
+ return IsEmptyBucket(key) || IsDeletedBucket(key);
}
};
@@ -846,7 +856,7 @@ class HashTable final
ValueType** GetBufferSlot() { return &table_; }
template <typename VisitorDispatcher, typename A = Allocator>
- std::enable_if_t<A::kIsGarbageCollected> Trace(VisitorDispatcher);
+ std::enable_if_t<A::kIsGarbageCollected> Trace(VisitorDispatcher) const;
#if DCHECK_IS_ON()
void EnterAccessForbiddenScope() {
@@ -953,6 +963,22 @@ class HashTable final
void ClearEnqueued() { queue_flag_ = false; }
bool Enqueued() { return queue_flag_; }
+ // Constructor for hash tables with raw storage.
+ struct RawStorageTag {};
+ HashTable(RawStorageTag, ValueType* table, unsigned size)
+ : table_(table),
+ table_size_(size),
+ key_count_(0),
+ deleted_count_(0),
+ queue_flag_(0)
+#if DCHECK_IS_ON()
+ ,
+ access_forbidden_(0),
+ modifications_(0)
+#endif
+ {
+ }
+
ValueType* table_;
unsigned table_size_;
unsigned key_count_;
@@ -1664,7 +1690,17 @@ void HashTable<Key,
KeyTraits,
Allocator>::DeleteAllBucketsAndDeallocate(ValueType* table,
unsigned size) {
- if (!std::is_trivially_destructible<ValueType>::value) {
+ // We delete a bucket in the following cases:
+ // - It is not trivially destructible.
+ // - The table is weak (thus garbage collected) and we are currently marking.
+ // This is to handle the case where a backing store is removed from the
+ // HashTable after HashTable has been enqueued for processing. If we remove
+ // the backing in that case it stays unprocessed which upsets the marking
+ // verifier that checks that all backings are in consistent state.
+ const bool needs_bucket_deletion =
+ !std::is_trivially_destructible<ValueType>::value ||
+ (WTF::IsWeak<ValueType>::value && Allocator::IsIncrementalMarking());
+ if (needs_bucket_deletion) {
for (unsigned i = 0; i < size; ++i) {
// This code is called when the hash table is cleared or resized. We
// have allocated a new backing store and we need to run the
@@ -1751,7 +1787,7 @@ HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::
}
}
table_ = temporary_table;
- Allocator::template BackingWriteBarrierForHashTable<HashTable>(table_);
+ Allocator::template BackingWriteBarrierForHashTable<HashTable>(&table_);
if (Traits::kEmptyValueIsZero) {
memset(original_table, 0, new_table_size * sizeof(ValueType));
@@ -1761,10 +1797,6 @@ HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::
}
new_entry = RehashTo(original_table, new_table_size, new_entry);
- EnterAccessForbiddenScope();
- DeleteAllBucketsAndDeallocate(temporary_table, old_table_size);
- LeaveAccessForbiddenScope();
-
return new_entry;
}
@@ -1778,41 +1810,50 @@ template <typename Key,
Value*
HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::
RehashTo(ValueType* new_table, unsigned new_table_size, Value* entry) {
- unsigned old_table_size = table_size_;
- ValueType* old_table = table_;
-
#if DUMP_HASHTABLE_STATS
- if (old_table_size != 0) {
+ if (table_size_ != 0) {
HashTableStats::instance().numRehashes.fetch_add(1,
std::memory_order_relaxed);
}
#endif
#if DUMP_HASHTABLE_STATS_PER_TABLE
- if (old_table_size != 0)
+ if (table_size_ != 0)
stats_->numRehashes.fetch_add(1, std::memory_order_relaxed);
#endif
- AsAtomic<ValueType*>(table_).store(new_table, std::memory_order_relaxed);
- Allocator::template BackingWriteBarrierForHashTable<HashTable>(new_table);
- table_size_ = new_table_size;
+ HashTable new_hash_table(RawStorageTag{}, new_table, new_table_size);
Value* new_entry = nullptr;
- for (unsigned i = 0; i != old_table_size; ++i) {
- if (IsEmptyOrDeletedBucket(old_table[i])) {
- DCHECK_NE(&old_table[i], entry);
+ for (unsigned i = 0; i != table_size_; ++i) {
+ if (IsEmptyOrDeletedBucket(table_[i])) {
+ DCHECK_NE(&table_[i], entry);
continue;
}
- Value* reinserted_entry = Reinsert(std::move(old_table[i]));
- if (&old_table[i] == entry) {
+ Value* reinserted_entry = new_hash_table.Reinsert(std::move(table_[i]));
+ if (&table_[i] == entry) {
DCHECK(!new_entry);
new_entry = reinserted_entry;
}
}
- // Rescan the contents of the backing store as no write barriers were emitted
- // during re-insertion. Traits::NeedsToForbidGCOnMove ensures that no
- // garbage collection is triggered during moving.
- Allocator::TraceMarkedBackingStore(new_table);
+
+ Allocator::TraceBackingStoreIfMarked(new_hash_table.table_);
+
+ ValueType* old_table = table_;
+ unsigned old_table_size = table_size_;
+
+ // This swaps the newly allocated buffer with the current one. The store to
+ // the current table has to be atomic to prevent races with concurrent marker.
+ AsAtomicPtr(&table_)->store(new_hash_table.table_, std::memory_order_relaxed);
+ Allocator::template BackingWriteBarrierForHashTable<HashTable>(&table_);
+ table_size_ = new_table_size;
+
+ new_hash_table.table_ = old_table;
+ new_hash_table.table_size_ = old_table_size;
+
+ // Explicitly clear since garbage collected HashTables don't do this on
+ // destruction.
+ new_hash_table.clear();
deleted_count_ = 0;
@@ -1835,7 +1876,6 @@ Value*
HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::
Rehash(unsigned new_table_size, Value* entry) {
unsigned old_table_size = table_size_;
- ValueType* old_table = table_;
#if DUMP_HASHTABLE_STATS
if (old_table_size != 0) {
@@ -1862,10 +1902,6 @@ HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::
ValueType* new_table = AllocateTable(new_table_size);
Value* new_entry = RehashTo(new_table, new_table_size, entry);
- EnterAccessForbiddenScope();
- DeleteAllBucketsAndDeallocate(old_table, old_table_size);
- LeaveAccessForbiddenScope();
-
return new_entry;
}
@@ -1890,7 +1926,7 @@ void HashTable<Key,
EnterAccessForbiddenScope();
DeleteAllBucketsAndDeallocate(table_, table_size_);
LeaveAccessForbiddenScope();
- table_ = nullptr;
+ AsAtomicPtr(&table_)->store(nullptr, std::memory_order_relaxed);
table_size_ = 0;
key_count_ = 0;
}
@@ -1976,11 +2012,17 @@ void HashTable<Key,
// race). Atomic reads are not needed here because this method is only called
// on the mutator thread, which is also the only one that writes to them, so
// there is *no* risk of data races when reading.
- Value* tmp_table = other.table_;
- AsAtomic<Value*>(other.table_).store(table_, std::memory_order_relaxed);
- AsAtomic<Value*>(table_).store(tmp_table, std::memory_order_relaxed);
- Allocator::template BackingWriteBarrierForHashTable<HashTable>(table_);
- Allocator::template BackingWriteBarrierForHashTable<HashTable>(other.table_);
+ AtomicWriteSwap(table_, other.table_);
+ Allocator::template BackingWriteBarrierForHashTable<HashTable>(&table_);
+ Allocator::template BackingWriteBarrierForHashTable<HashTable>(&other.table_);
+ if (IsWeak<ValueType>::value) {
+ // Weak processing is omitted when no backing store is present. In case such
+ // an empty table is later on used it needs to be strongified.
+ if (table_)
+ Allocator::TraceBackingStoreIfMarked(table_);
+ if (other.table_)
+ Allocator::TraceBackingStoreIfMarked(other.table_);
+ }
std::swap(table_size_, other.table_size_);
std::swap(key_count_, other.key_count_);
// std::swap does not work for bit fields.
@@ -2038,7 +2080,8 @@ template <WeakHandlingFlag weakHandlingFlag,
typename Allocator>
struct WeakProcessingHashTableHelper {
STATIC_ONLY(WeakProcessingHashTableHelper);
- static void Process(const typename Allocator::WeakCallbackInfo&, void*) {}
+ static void Process(const typename Allocator::WeakCallbackInfo&,
+ const void*) {}
};
template <typename Key,
@@ -2069,8 +2112,9 @@ struct WeakProcessingHashTableHelper<kWeakHandling,
// Used for purely weak and for weak-and-strong tables (ephemerons).
static void Process(const typename Allocator::WeakCallbackInfo&,
- void* parameter) {
- HashTableType* table = reinterpret_cast<HashTableType*>(parameter);
+ const void* parameter) {
+ HashTableType* table =
+ reinterpret_cast<HashTableType*>(const_cast<void*>(parameter));
// During incremental marking, the table may be freed after the callback has
// been registered.
if (!table->table_)
@@ -2105,12 +2149,22 @@ template <typename Key,
template <typename VisitorDispatcher, typename A>
std::enable_if_t<A::kIsGarbageCollected>
HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::
- Trace(VisitorDispatcher visitor) {
+ Trace(VisitorDispatcher visitor) const {
+ // bail out for concurrent marking
+ if (visitor->ConcurrentTracingBailOut(
+ {this, [](blink::Visitor* visitor, const void* object) {
+ reinterpret_cast<
+ const HashTable<Key, Value, Extractor, HashFunctions, Traits,
+ KeyTraits, Allocator>*>(object)
+ ->Trace(visitor);
+ }}))
+ return;
+
static_assert(WTF::IsWeak<ValueType>::value ||
IsTraceableInCollectionTrait<Traits>::value,
"Value should not be traced");
- ValueType* table =
- AsAtomic<ValueType*>(table_).load(std::memory_order_relaxed);
+ const ValueType* table =
+ AsAtomicPtr(&table_)->load(std::memory_order_relaxed);
if (!WTF::IsWeak<ValueType>::value) {
// Strong HashTable.
Allocator::template TraceHashTableBackingStrongly<ValueType, HashTable>(
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 fe2bea5d8d8..58833a13d2b 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/hash_traits.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/hash_traits.h
@@ -22,7 +22,6 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_HASH_TRAITS_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_HASH_TRAITS_H_
-#include <string.h> // For memset.
#include <limits>
#include <memory>
#include <type_traits>
@@ -43,6 +42,27 @@ struct EnumOrGenericHashTraits;
template <typename T>
struct HashTraits;
+namespace {
+template <typename T, bool use_atomic_writes = IsTraceable<T>::value>
+void ClearMemoryAtomically(T* slot, size_t size) {
+ size_t* address = reinterpret_cast<size_t*>(slot);
+ // This method is called for clearing hash table entires that are removed. In
+ // case Oilpan concurrent marking is tracing the hash table at the same time,
+ // there might be a data race between the marker reading the entry and zeroing
+ // the entry. Using atomic reads here resolves any possible races.
+ // Note that sizeof(T) might not be a multiple of sizeof(size_t). The last
+ // sizeof(T)%sizeof(size_t) bytes don't require atomic write as it cannot hold
+ // a pointer (i.e it will not be traceable).
+ if (use_atomic_writes) {
+ for (; size >= sizeof(size_t); size -= sizeof(size_t), ++address) {
+ WTF::AsAtomicPtr(address)->store(0, std::memory_order_relaxed);
+ }
+ }
+ DCHECK(!use_atomic_writes || (size < sizeof(size_t)));
+ memset(address, 0, size);
+}
+} // namespace
+
template <typename T>
struct GenericHashTraitsBase<false, T> {
// The emptyValueIsZero flag is used to optimize allocation of empty hash
@@ -196,7 +216,7 @@ struct HashTraits<P*> : GenericHashTraits<P*> {
static void ConstructDeletedValue(P*& slot, bool) {
slot = reinterpret_cast<P*>(-1);
}
- static bool IsDeletedValue(P* value) {
+ static bool IsDeletedValue(const P* value) {
return value == reinterpret_cast<P*>(-1);
}
};
@@ -374,8 +394,9 @@ struct PairHashTraits
// at a later point, the same assumptions around memory zeroing must
// hold as they did at the initial allocation. Therefore we zero the
// value part of the slot here for GC collections.
- if (zero_value)
- memset(reinterpret_cast<void*>(&slot.second), 0, sizeof(slot.second));
+ if (zero_value) {
+ ClearMemoryAtomically(&slot.second, sizeof(slot.second));
+ }
}
static bool IsDeletedValue(const TraitType& value) {
return FirstTraits::IsDeletedValue(value.first);
@@ -446,8 +467,9 @@ struct KeyValuePairHashTraits
static void ConstructDeletedValue(TraitType& slot, bool zero_value) {
KeyTraits::ConstructDeletedValue(slot.key, zero_value);
// See similar code in this file for why we need to do this.
- if (zero_value)
- memset(reinterpret_cast<void*>(&slot.value), 0, sizeof(slot.value));
+ if (zero_value) {
+ ClearMemoryAtomically(&slot.value, sizeof(slot.value));
+ }
}
static bool IsDeletedValue(const TraitType& value) {
return KeyTraits::IsDeletedValue(value.key);
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 9c12afcda68..0c4308e3ee1 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
@@ -25,8 +25,10 @@
#include "base/macros.h"
#include "third_party/blink/renderer/platform/wtf/allocator/partition_allocator.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/sanitizers.h"
+#include "third_party/blink/renderer/platform/wtf/vector_backed_linked_list.h"
namespace WTF {
@@ -49,20 +51,51 @@ template <typename Value,
class LinkedHashSet;
template <typename LinkedHashSet>
-class LinkedHashSetIterator;
-template <typename LinkedHashSet>
class LinkedHashSetConstIterator;
template <typename LinkedHashSet>
-class LinkedHashSetReverseIterator;
-template <typename LinkedHashSet>
class LinkedHashSetConstReverseIterator;
-template <typename Value, typename HashFunctions, typename Allocator>
+template <typename Value, typename HashFunctions>
struct LinkedHashSetTranslator;
-template <typename Value, typename Allocator>
+template <typename Value>
struct LinkedHashSetExtractor;
template <typename Value, typename ValueTraits, typename Allocator>
struct LinkedHashSetTraits;
+class LinkedHashSetNodeBase;
+
+class LinkedHashSetNodeBasePointer {
+ public:
+ LinkedHashSetNodeBasePointer(LinkedHashSetNodeBase* node) : node_(node) {}
+
+ LinkedHashSetNodeBasePointer& operator=(
+ const LinkedHashSetNodeBasePointer& other) {
+ SetSafe(other);
+ return *this;
+ }
+
+ LinkedHashSetNodeBasePointer& operator=(LinkedHashSetNodeBase* other) {
+ SetSafe(other);
+ return *this;
+ }
+
+ LinkedHashSetNodeBasePointer& operator=(std::nullptr_t) {
+ SetSafe(nullptr);
+ return *this;
+ }
+
+ LinkedHashSetNodeBase* Get() const { return node_; }
+ explicit operator bool() const { return Get(); }
+ operator LinkedHashSetNodeBase*() const { return Get(); }
+ LinkedHashSetNodeBase* operator->() const { return Get(); }
+ LinkedHashSetNodeBase& operator*() const { return *Get(); }
+
+ private:
+ void SetSafe(LinkedHashSetNodeBase* node) {
+ AsAtomicPtr(&node_)->store(node, std::memory_order_relaxed);
+ }
+
+ LinkedHashSetNodeBase* node_ = nullptr;
+};
class LinkedHashSetNodeBase {
DISALLOW_NEW();
@@ -75,10 +108,16 @@ class LinkedHashSetNodeBase {
if (!next_)
return;
DCHECK(prev_);
- DCHECK(next_->prev_ == this);
- DCHECK(prev_->next_ == this);
- next_->prev_ = prev_;
- prev_->next_ = next_;
+ {
+ AsanUnpoisonScope unpoison_scope(next_, sizeof(LinkedHashSetNodeBase));
+ DCHECK(next_->prev_ == this);
+ next_->prev_ = prev_;
+ }
+ {
+ AsanUnpoisonScope unpoison_scope(prev_, sizeof(LinkedHashSetNodeBase));
+ DCHECK(prev_->next_ == this);
+ prev_->next_ = next_;
+ }
}
~LinkedHashSetNodeBase() { Unlink(); }
@@ -111,8 +150,8 @@ class LinkedHashSetNodeBase {
DCHECK((prev && next) || (!prev && !next));
}
- LinkedHashSetNodeBase* prev_;
- LinkedHashSetNodeBase* next_;
+ LinkedHashSetNodeBasePointer prev_;
+ LinkedHashSetNodeBasePointer next_;
protected:
// If we take a copy of a node we can't copy the next and prev pointers,
@@ -177,8 +216,7 @@ class LinkedHashSet {
typedef TraitsArg Traits;
typedef LinkedHashSetNode<Value> Node;
typedef LinkedHashSetNodeBase NodeBase;
- typedef LinkedHashSetTranslator<Value, HashFunctions, Allocator>
- NodeHashFunctions;
+ typedef LinkedHashSetTranslator<Value, HashFunctions> NodeHashFunctions;
typedef LinkedHashSetTraits<Value, Traits, Allocator> NodeHashTraits;
typedef HashTable<Node,
@@ -191,13 +229,11 @@ class LinkedHashSet {
ImplType;
public:
- typedef LinkedHashSetIterator<LinkedHashSet> iterator;
- friend class LinkedHashSetIterator<LinkedHashSet>;
+ typedef LinkedHashSetConstIterator<LinkedHashSet> iterator;
typedef LinkedHashSetConstIterator<LinkedHashSet> const_iterator;
friend class LinkedHashSetConstIterator<LinkedHashSet>;
- typedef LinkedHashSetReverseIterator<LinkedHashSet> reverse_iterator;
- friend class LinkedHashSetReverseIterator<LinkedHashSet>;
+ typedef LinkedHashSetConstReverseIterator<LinkedHashSet> reverse_iterator;
typedef LinkedHashSetConstReverseIterator<LinkedHashSet>
const_reverse_iterator;
friend class LinkedHashSetConstReverseIterator<LinkedHashSet>;
@@ -210,7 +246,7 @@ class LinkedHashSet {
: stored_value(&hash_table_add_result.stored_value->value_),
is_new_entry(hash_table_add_result.is_new_entry) {}
- Value* stored_value;
+ const Value* stored_value;
bool is_new_entry;
};
@@ -277,13 +313,6 @@ class LinkedHashSet {
template <typename IncomingValueType>
AddResult insert(IncomingValueType&&);
- // Same as insert() except that the return value is an
- // iterator. Useful in cases where it's needed to have the
- // same return value as find() and where it's not possible to
- // use a pointer to the storedValue.
- template <typename IncomingValueType>
- iterator AddReturnIterator(IncomingValueType&&);
-
// Add the value to the end of the collection. If the value was already in
// the list, it is moved to the end.
template <typename IncomingValueType>
@@ -298,13 +327,13 @@ class LinkedHashSet {
AddResult InsertBefore(ValuePeekInType before_value,
IncomingValueType&& new_value);
template <typename IncomingValueType>
- AddResult InsertBefore(iterator it, IncomingValueType&& new_value) {
+ AddResult InsertBefore(const_iterator it, IncomingValueType&& new_value) {
return impl_.template insert<NodeHashFunctions>(
std::forward<IncomingValueType>(new_value), it.GetNode());
}
void erase(ValuePeekInType);
- void erase(iterator);
+ void erase(const_iterator);
void clear() { impl_.clear(); }
template <typename Collection>
void RemoveAll(const Collection& other) {
@@ -312,13 +341,24 @@ class LinkedHashSet {
}
template <typename VisitorDispatcher>
- void Trace(VisitorDispatcher visitor) {
+ void Trace(VisitorDispatcher visitor) const {
+ if (visitor->ConcurrentTracingBailOut(
+ {this, [](blink::Visitor* visitor, const void* object) {
+ reinterpret_cast<const LinkedHashSet<ValueArg, HashFunctions,
+ TraitsArg, Allocator>*>(
+ object)
+ ->Trace(visitor);
+ }}))
+ return;
+
impl_.Trace(visitor);
// Should the underlying table be moved by GC, register a callback
// that fixes up the interior pointers that the (Heap)LinkedHashSet keeps.
- if (impl_.table_) {
+ const auto* table =
+ AsAtomicPtr(&impl_.table_)->load(std::memory_order_relaxed);
+ if (table) {
Allocator::RegisterBackingStoreCallback(
- visitor, impl_.table_,
+ visitor, table,
NodeHashTraits::template MoveBackingCallback<ImplType>);
}
}
@@ -336,13 +376,13 @@ class LinkedHashSet {
private:
Node* Anchor() { return reinterpret_cast<Node*>(&anchor_); }
const Node* Anchor() const { return reinterpret_cast<const Node*>(&anchor_); }
- Node* FirstNode() { return reinterpret_cast<Node*>(anchor_.next_); }
+ Node* FirstNode() { return reinterpret_cast<Node*>(anchor_.next_.Get()); }
const Node* FirstNode() const {
- return reinterpret_cast<const Node*>(anchor_.next_);
+ return reinterpret_cast<const Node*>(anchor_.next_.Get());
}
- Node* LastNode() { return reinterpret_cast<Node*>(anchor_.prev_); }
+ Node* LastNode() { return reinterpret_cast<Node*>(anchor_.prev_.Get()); }
const Node* LastNode() const {
- return reinterpret_cast<const Node*>(anchor_.prev_);
+ return reinterpret_cast<const Node*>(anchor_.prev_.Get());
}
iterator MakeIterator(const Node* position) {
@@ -362,7 +402,7 @@ class LinkedHashSet {
NodeBase anchor_;
};
-template <typename Value, typename HashFunctions, typename Allocator>
+template <typename Value, typename HashFunctions>
struct LinkedHashSetTranslator {
STATIC_ONLY(LinkedHashSetTranslator);
typedef LinkedHashSetNode<Value> Node;
@@ -395,7 +435,7 @@ struct LinkedHashSetTranslator {
static const bool safe_to_compare_to_empty_or_deleted = false;
};
-template <typename Value, typename Allocator>
+template <typename Value>
struct LinkedHashSetExtractor {
STATIC_ONLY(LinkedHashSetExtractor);
static const Value& Extract(const LinkedHashSetNode<Value>& node) {
@@ -449,10 +489,14 @@ struct LinkedHashSetTraits
}
template <typename HashTable>
- static void MoveBackingCallback(void* from, void* to, size_t size) {
+ static void MoveBackingCallback(const void* const_from,
+ const void* const_to,
+ size_t size) {
// Note: the hash table move may have been overlapping; linearly scan the
// entire table and fixup interior pointers into the old region with
// correspondingly offset ones into the new.
+ void* from = const_cast<void*>(const_from);
+ void* to = const_cast<void*>(const_to);
const size_t table_size = size / sizeof(Node);
Node* table = reinterpret_cast<Node*>(to);
NodeBase* from_start = reinterpret_cast<NodeBase*>(from);
@@ -464,7 +508,7 @@ struct LinkedHashSetTraits
if (HashTable::IsEmptyOrDeletedBucket(node))
continue;
if (node.next_ >= from_start && node.next_ < from_end) {
- const size_t diff = reinterpret_cast<uintptr_t>(node.next_) -
+ const size_t diff = reinterpret_cast<uintptr_t>(node.next_.Get()) -
reinterpret_cast<uintptr_t>(from);
node.next_ =
reinterpret_cast<NodeBase*>(reinterpret_cast<uintptr_t>(to) + diff);
@@ -473,7 +517,7 @@ struct LinkedHashSetTraits
anchor_node = node.next_;
}
if (node.prev_ >= from_start && node.prev_ < from_end) {
- const size_t diff = reinterpret_cast<uintptr_t>(node.prev_) -
+ const size_t diff = reinterpret_cast<uintptr_t>(node.prev_.Get()) -
reinterpret_cast<uintptr_t>(from);
node.prev_ =
reinterpret_cast<NodeBase*>(reinterpret_cast<uintptr_t>(to) + diff);
@@ -490,15 +534,17 @@ struct LinkedHashSetTraits
}
{
DCHECK(anchor_node->prev_ >= from_start && anchor_node->prev_ < from_end);
- const size_t diff = reinterpret_cast<uintptr_t>(anchor_node->prev_) -
- reinterpret_cast<uintptr_t>(from);
+ const size_t diff =
+ reinterpret_cast<uintptr_t>(anchor_node->prev_.Get()) -
+ reinterpret_cast<uintptr_t>(from);
anchor_node->prev_ =
reinterpret_cast<NodeBase*>(reinterpret_cast<uintptr_t>(to) + diff);
}
{
DCHECK(anchor_node->next_ >= from_start && anchor_node->next_ < from_end);
- const size_t diff = reinterpret_cast<uintptr_t>(anchor_node->next_) -
- reinterpret_cast<uintptr_t>(from);
+ const size_t diff =
+ reinterpret_cast<uintptr_t>(anchor_node->next_.Get()) -
+ reinterpret_cast<uintptr_t>(from);
anchor_node->next_ =
reinterpret_cast<NodeBase*>(reinterpret_cast<uintptr_t>(to) + diff);
}
@@ -506,59 +552,6 @@ struct LinkedHashSetTraits
};
template <typename LinkedHashSetType>
-class LinkedHashSetIterator {
- DISALLOW_NEW();
-
- private:
- typedef typename LinkedHashSetType::Node Node;
- typedef typename LinkedHashSetType::Traits Traits;
-
- typedef typename LinkedHashSetType::Value& ReferenceType;
- typedef typename LinkedHashSetType::Value* PointerType;
-
- typedef LinkedHashSetConstIterator<LinkedHashSetType> const_iterator;
-
- Node* GetNode() { return const_cast<Node*>(iterator_.GetNode()); }
-
- protected:
- LinkedHashSetIterator(const Node* position, LinkedHashSetType* container)
- : iterator_(position, container) {}
-
- public:
- // Default copy, assignment and destructor are OK.
-
- PointerType Get() const { return const_cast<PointerType>(iterator_.Get()); }
- ReferenceType operator*() const { return *Get(); }
- PointerType operator->() const { return Get(); }
-
- LinkedHashSetIterator& operator++() {
- ++iterator_;
- return *this;
- }
- LinkedHashSetIterator& operator--() {
- --iterator_;
- return *this;
- }
-
- // Postfix ++ and -- intentionally omitted.
-
- // Comparison.
- bool operator==(const LinkedHashSetIterator& other) const {
- return iterator_ == other.iterator_;
- }
- bool operator!=(const LinkedHashSetIterator& other) const {
- return iterator_ != other.iterator_;
- }
-
- operator const_iterator() const { return iterator_; }
-
- protected:
- const_iterator iterator_;
- template <typename T, typename U, typename V, typename W>
- friend class LinkedHashSet;
-};
-
-template <typename LinkedHashSetType>
class LinkedHashSetConstIterator {
DISALLOW_NEW();
@@ -569,7 +562,9 @@ class LinkedHashSetConstIterator {
typedef const typename LinkedHashSetType::Value& ReferenceType;
typedef const typename LinkedHashSetType::Value* PointerType;
- const Node* GetNode() const { return static_cast<const Node*>(position_); }
+ Node* GetNode() const {
+ return const_cast<Node*>(static_cast<const Node*>(position_));
+ }
protected:
LinkedHashSetConstIterator(const LinkedHashSetNodeBase* position,
@@ -628,42 +623,6 @@ class LinkedHashSetConstIterator {
#endif
template <typename T, typename U, typename V, typename W>
friend class LinkedHashSet;
- friend class LinkedHashSetIterator<LinkedHashSetType>;
-};
-
-template <typename LinkedHashSetType>
-class LinkedHashSetReverseIterator
- : public LinkedHashSetIterator<LinkedHashSetType> {
- typedef LinkedHashSetReverseIterator<LinkedHashSetType> reverse_iterator;
- typedef LinkedHashSetIterator<LinkedHashSetType> Superclass;
- typedef LinkedHashSetConstReverseIterator<LinkedHashSetType>
- const_reverse_iterator;
- typedef typename LinkedHashSetType::Node Node;
-
- protected:
- LinkedHashSetReverseIterator(const Node* position,
- LinkedHashSetType* container)
- : Superclass(position, container) {}
-
- public:
- LinkedHashSetReverseIterator& operator++() {
- Superclass::operator--();
- return *this;
- }
- LinkedHashSetReverseIterator& operator--() {
- Superclass::operator++();
- return *this;
- }
-
- // Postfix ++ and -- intentionally omitted.
-
- operator const_reverse_iterator() const {
- return *reinterpret_cast<const_reverse_iterator*>(
- const_cast<reverse_iterator*>(this));
- }
-
- template <typename T, typename U, typename V, typename W>
- friend class LinkedHashSet;
};
template <typename LinkedHashSetType>
@@ -797,7 +756,7 @@ inline const T& LinkedHashSet<T, U, V, W>::front() const {
template <typename T, typename U, typename V, typename W>
inline void LinkedHashSet<T, U, V, W>::RemoveFirst() {
DCHECK(!IsEmpty());
- impl_.erase(static_cast<Node*>(anchor_.next_));
+ impl_.erase(static_cast<Node*>(anchor_.next_.Get()));
}
template <typename T, typename U, typename V, typename W>
@@ -815,7 +774,7 @@ inline const T& LinkedHashSet<T, U, V, W>::back() const {
template <typename T, typename U, typename V, typename W>
inline void LinkedHashSet<T, U, V, W>::pop_back() {
DCHECK(!IsEmpty());
- impl_.erase(static_cast<Node*>(anchor_.prev_));
+ impl_.erase(static_cast<Node*>(anchor_.prev_.Get()));
}
template <typename T, typename U, typename V, typename W>
@@ -903,16 +862,6 @@ LinkedHashSet<Value, HashFunctions, Traits, Allocator>::insert(
template <typename T, typename U, typename V, typename W>
template <typename IncomingValueType>
-typename LinkedHashSet<T, U, V, W>::iterator
-LinkedHashSet<T, U, V, W>::AddReturnIterator(IncomingValueType&& value) {
- typename ImplType::AddResult result =
- impl_.template insert<NodeHashFunctions>(
- std::forward<IncomingValueType>(value), &anchor_);
- return MakeIterator(result.stored_value);
-}
-
-template <typename T, typename U, typename V, typename W>
-template <typename IncomingValueType>
typename LinkedHashSet<T, U, V, W>::AddResult
LinkedHashSet<T, U, V, W>::AppendOrMoveToLast(IncomingValueType&& value) {
typename ImplType::AddResult result =
@@ -951,7 +900,7 @@ LinkedHashSet<T, U, V, W>::InsertBefore(ValuePeekInType before_value,
}
template <typename T, typename U, typename V, typename W>
-inline void LinkedHashSet<T, U, V, W>::erase(iterator it) {
+inline void LinkedHashSet<T, U, V, W>::erase(const_iterator it) {
if (it == end())
return;
impl_.erase(it.GetNode());
@@ -964,20 +913,284 @@ inline void LinkedHashSet<T, U, V, W>::erase(ValuePeekInType value) {
template <typename T, typename Allocator>
inline void swap(LinkedHashSetNode<T>& a, LinkedHashSetNode<T>& b) {
- typedef LinkedHashSetNodeBase Base;
// The key and value cannot be swapped atomically, and it would be
// wrong to have a GC when only one was swapped and the other still
// contained garbage (eg. from a previous use of the same slot).
// Therefore we forbid a GC until both the key and the value are
// swapped.
Allocator::EnterGCForbiddenScope();
- swap(static_cast<Base&>(a), static_cast<Base&>(b));
+ swap(static_cast<LinkedHashSetNodeBase&>(a),
+ static_cast<LinkedHashSetNodeBase&>(b));
swap(a.value_, b.value_);
Allocator::LeaveGCForbiddenScope();
}
+// TODO(keinakashima): replace existing LinkedHashSet with NewLinkedHashSet
+// after completion
+
+// This class is still experimental. Do not use this class.
+
+// LinkedHashSet provides a Set interface like HashSet, but also has a
+// predictable iteration order. It has O(1) insertion, removal, and test for
+// containership. It maintains a linked list through its contents such that
+// iterating it yields values in the order in which they were inserted.
+// The linked list is implementing in a vector (with links being indexes instead
+// of pointers), to simplify the move of backing during GC compaction.
+
+// TODO(keinakashima): implement NewLinkedHashTraits (now we cannot insert
+// deleted/empty value) and add it to template parameter
+
+template <typename ValueArg, typename Allocator = PartitionAllocator>
+class NewLinkedHashSet {
+ USE_ALLOCATOR(NewLinkedHashSet, Allocator);
+
+ private:
+ using Value = ValueArg;
+ using Map = HashMap<Value,
+ wtf_size_t,
+ typename DefaultHash<Value>::Hash,
+ HashTraits<Value>,
+ HashTraits<wtf_size_t>,
+ Allocator>;
+ using ListType = VectorBackedLinkedList<Value, Allocator>;
+
+ public:
+ using iterator = typename ListType::const_iterator;
+ using reverse_iterator = typename ListType::const_reverse_iterator;
+ using const_iterator = typename ListType::const_iterator;
+ using const_reverse_iterator = typename ListType::const_reverse_iterator;
+
+ // TODO(keinakashima): add security check
+ struct AddResult final {
+ STACK_ALLOCATED();
+
+ public:
+ AddResult(const Value* stored_value, bool is_new_entry)
+ : stored_value(stored_value), is_new_entry(is_new_entry) {}
+ const Value* stored_value;
+ bool is_new_entry;
+ };
+
+ typedef typename HashTraits<Value>::PeekInType ValuePeekInType;
+
+ NewLinkedHashSet();
+ NewLinkedHashSet(const NewLinkedHashSet&) = default;
+ NewLinkedHashSet(NewLinkedHashSet&&) = default;
+ NewLinkedHashSet& operator=(const NewLinkedHashSet&) = default;
+ NewLinkedHashSet& operator=(NewLinkedHashSet&&) = default;
+
+ ~NewLinkedHashSet() = default;
+
+ void Swap(NewLinkedHashSet&);
+
+ wtf_size_t size() const { return list_.size(); }
+ bool IsEmpty() const { return list_.empty(); }
+
+ iterator begin() { return list_.begin(); }
+ const_iterator begin() const { return list_.cbegin(); }
+ const_iterator cbegin() const { return list_.cbegin(); }
+ iterator end() { return list_.end(); }
+ const_iterator end() const { return list_.cend(); }
+ const_iterator cend() const { return list_.cend(); }
+
+ reverse_iterator rbegin() { return list_.rbegin(); }
+ const_reverse_iterator rbegin() const { return list_.crbegin(); }
+ const_reverse_iterator crbegin() const { return list_.crbegin(); }
+ reverse_iterator rend() { return list_.rend(); }
+ const_reverse_iterator rend() const { return list_.crend(); }
+ const_reverse_iterator crend() const { return list_.crend(); }
+
+ const Value& front() const { return list_.front(); }
+ const Value& back() const { return list_.back(); }
+
+ iterator find(ValuePeekInType);
+ const_iterator find(ValuePeekInType) const;
+ bool Contains(ValuePeekInType) const;
+
+ template <typename IncomingValueType>
+ AddResult insert(IncomingValueType&&);
+
+ // If |value| already exists in the set, nothing happens.
+ // If |before_value| doesn't exist in the set, appends |value|.
+ template <typename IncomingValueType>
+ AddResult InsertBefore(ValuePeekInType before_value,
+ IncomingValueType&& value);
+
+ template <typename IncomingValueType>
+ AddResult InsertBefore(const_iterator it, IncomingValueType&& value);
+
+ template <typename IncomingValueType>
+ AddResult AppendOrMoveToLast(IncomingValueType&&);
+
+ template <typename IncomingValueType>
+ AddResult PrependOrMoveToFirst(IncomingValueType&&);
+
+ void erase(ValuePeekInType);
+ void erase(const_iterator);
+ void RemoveFirst();
+ void pop_back();
+
+ void clear() {
+ value_to_index_.clear();
+ list_.clear();
+ }
+
+ template <typename VisitorDispatcher, typename A = Allocator>
+ std::enable_if_t<A::kIsGarbageCollected> Trace(VisitorDispatcher visitor) {
+ value_to_index_.Trace(visitor);
+ list_.Trace(visitor);
+ }
+
+ private:
+ enum class MoveType {
+ kMoveIfValueExists,
+ kDontMove,
+ };
+
+ template <typename IncomingValueType>
+ AddResult InsertOrMoveBefore(const_iterator, IncomingValueType&&, MoveType);
+
+ Map value_to_index_;
+ ListType list_;
+};
+
+template <typename T, typename Allocator>
+inline NewLinkedHashSet<T, Allocator>::NewLinkedHashSet() {
+ static_assert(Allocator::kIsGarbageCollected ||
+ !IsPointerToGarbageCollectedType<T>::value,
+ "Cannot put raw pointers to garbage-collected classes into "
+ "an off-heap NewLinkedHashSet. Use "
+ "HeapNewLinkedHashSet<Member<T>> instead.");
+}
+
+template <typename T, typename Allocator>
+inline void NewLinkedHashSet<T, Allocator>::Swap(NewLinkedHashSet& other) {
+ value_to_index_.swap(other.value_to_index_);
+ list_.swap(other.list_);
+}
+
+template <typename T, typename Allocator>
+typename NewLinkedHashSet<T, Allocator>::iterator
+NewLinkedHashSet<T, Allocator>::find(ValuePeekInType value) {
+ typename Map::const_iterator it = value_to_index_.find(value);
+
+ if (it == value_to_index_.end())
+ return end();
+ return list_.MakeIterator(it->value);
+}
+
+template <typename T, typename Allocator>
+typename NewLinkedHashSet<T, Allocator>::const_iterator
+NewLinkedHashSet<T, Allocator>::find(ValuePeekInType value) const {
+ typename Map::const_iterator it = value_to_index_.find(value);
+
+ if (it == value_to_index_.end())
+ return end();
+ return list_.MakeConstIterator(it->value);
+}
+
+template <typename T, typename Allocator>
+bool NewLinkedHashSet<T, Allocator>::Contains(ValuePeekInType value) const {
+ return value_to_index_.Contains(value);
+}
+
+template <typename T, typename Allocator>
+template <typename IncomingValueType>
+typename NewLinkedHashSet<T, Allocator>::AddResult
+NewLinkedHashSet<T, Allocator>::insert(IncomingValueType&& value) {
+ return InsertOrMoveBefore(end(), std::forward<IncomingValueType>(value),
+ MoveType::kDontMove);
+}
+
+template <typename T, typename Allocator>
+template <typename IncomingValueType>
+typename NewLinkedHashSet<T, Allocator>::AddResult
+NewLinkedHashSet<T, Allocator>::InsertBefore(ValuePeekInType before_value,
+ IncomingValueType&& value) {
+ return InsertOrMoveBefore(find(before_value),
+ std::forward<IncomingValueType>(value),
+ MoveType::kDontMove);
+}
+
+template <typename T, typename Allocator>
+template <typename IncomingValueType>
+typename NewLinkedHashSet<T, Allocator>::AddResult
+NewLinkedHashSet<T, Allocator>::InsertBefore(const_iterator it,
+ IncomingValueType&& value) {
+ return InsertOrMoveBefore(it, std::forward<IncomingValueType>(value),
+ MoveType::kDontMove);
+}
+
+template <typename T, typename Allocator>
+template <typename IncomingValueType>
+typename NewLinkedHashSet<T, Allocator>::AddResult
+NewLinkedHashSet<T, Allocator>::AppendOrMoveToLast(IncomingValueType&& value) {
+ return InsertOrMoveBefore(end(), std::forward<IncomingValueType>(value),
+ MoveType::kMoveIfValueExists);
+}
+
+template <typename T, typename Allocator>
+template <typename IncomingValueType>
+typename NewLinkedHashSet<T, Allocator>::AddResult
+NewLinkedHashSet<T, Allocator>::PrependOrMoveToFirst(
+ IncomingValueType&& value) {
+ return InsertOrMoveBefore(begin(), std::forward<IncomingValueType>(value),
+ MoveType::kMoveIfValueExists);
+}
+
+template <typename T, typename Allocator>
+inline void NewLinkedHashSet<T, Allocator>::erase(ValuePeekInType value) {
+ erase(find(value));
+}
+
+template <typename T, typename Allocator>
+inline void NewLinkedHashSet<T, Allocator>::erase(const_iterator it) {
+ if (it == end())
+ return;
+ value_to_index_.erase(*it);
+ list_.erase(it);
+}
+
+template <typename T, typename Allocator>
+inline void NewLinkedHashSet<T, Allocator>::RemoveFirst() {
+ DCHECK(!IsEmpty());
+ erase(begin());
+}
+
+template <typename T, typename Allocator>
+inline void NewLinkedHashSet<T, Allocator>::pop_back() {
+ DCHECK(!IsEmpty());
+ erase(--end());
+}
+
+template <typename T, typename Allocator>
+template <typename IncomingValueType>
+typename NewLinkedHashSet<T, Allocator>::AddResult
+NewLinkedHashSet<T, Allocator>::InsertOrMoveBefore(const_iterator position,
+ IncomingValueType&& value,
+ MoveType type) {
+ typename Map::AddResult result = value_to_index_.insert(value, kNotFound);
+
+ if (result.is_new_entry) {
+ const_iterator stored_position_iterator =
+ list_.insert(position, std::forward<IncomingValueType>(value));
+ result.stored_value->value = stored_position_iterator.GetIndex();
+ return AddResult(stored_position_iterator.Get(), true);
+ }
+
+ const_iterator stored_position_iterator =
+ list_.MakeConstIterator(result.stored_value->value);
+ if (type == MoveType::kDontMove)
+ return AddResult(stored_position_iterator.Get(), false);
+
+ const_iterator moved_position_iterator =
+ list_.MoveTo(stored_position_iterator, position);
+ return AddResult(moved_position_iterator.Get(), false);
+}
+
} // namespace WTF
using WTF::LinkedHashSet;
+using WTF::NewLinkedHashSet;
#endif /* WTF_LinkedHashSet_h */
diff --git a/chromium/third_party/blink/renderer/platform/wtf/linked_hash_set_test.cc b/chromium/third_party/blink/renderer/platform/wtf/linked_hash_set_test.cc
new file mode 100644
index 00000000000..bcfb0be1d0f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/wtf/linked_hash_set_test.cc
@@ -0,0 +1,463 @@
+// 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/wtf/linked_hash_set.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_test_helper.h"
+
+namespace WTF {
+
+TEST(NewLinkedHashSetTest, CopyConstructAndAssignInt) {
+ NewLinkedHashSet<int> set1;
+ EXPECT_EQ(set1.size(), 0u);
+ EXPECT_TRUE(set1.IsEmpty());
+ set1.insert(1);
+ set1.insert(2);
+ set1.insert(3);
+ EXPECT_EQ(set1.size(), 3u);
+ NewLinkedHashSet<int> set2(set1);
+ EXPECT_EQ(set2.size(), 3u);
+ NewLinkedHashSet<int> set3;
+ EXPECT_EQ(set3.size(), 0u);
+ set3 = set2;
+ EXPECT_EQ(set3.size(), 3u);
+ auto it1 = set1.begin();
+ auto it2 = set2.begin();
+ auto it3 = set3.begin();
+ for (int i = 0; i < 3; i++) {
+ EXPECT_EQ(*it1, i + 1);
+ EXPECT_EQ(*it2, i + 1);
+ EXPECT_EQ(*it3, i + 1);
+ ++it1;
+ ++it2;
+ ++it3;
+ }
+}
+
+TEST(NewLinkedHashSetTest, CopyConstructAndAssignIntPtr) {
+ NewLinkedHashSet<int*> set1;
+ EXPECT_EQ(set1.size(), 0u);
+ EXPECT_TRUE(set1.IsEmpty());
+ std::unique_ptr<int> int1 = std::make_unique<int>(1);
+ std::unique_ptr<int> int2 = std::make_unique<int>(2);
+ std::unique_ptr<int> int3 = std::make_unique<int>(3);
+ set1.insert(int1.get());
+ set1.insert(int2.get());
+ set1.insert(int3.get());
+ EXPECT_EQ(set1.size(), 3u);
+ NewLinkedHashSet<int*> set2(set1);
+ EXPECT_EQ(set2.size(), 3u);
+ NewLinkedHashSet<int*> set3;
+ EXPECT_EQ(set3.size(), 0u);
+ set3 = set2;
+ EXPECT_EQ(set3.size(), 3u);
+ auto it1 = set1.begin();
+ auto it2 = set2.begin();
+ auto it3 = set3.begin();
+ for (int i = 0; i < 3; i++) {
+ EXPECT_EQ(**it1, i + 1);
+ EXPECT_EQ(**it2, i + 1);
+ EXPECT_EQ(**it3, i + 1);
+ ++it1;
+ ++it2;
+ ++it3;
+ }
+
+ for (int* ptr : set1)
+ *ptr += 1000;
+ it1 = set1.begin();
+ it2 = set2.begin();
+ it3 = set3.begin();
+ for (int i = 0; i < 3; i++) {
+ EXPECT_EQ(**it1, i + 1001);
+ EXPECT_EQ(**it2, i + 1001);
+ EXPECT_EQ(**it3, i + 1001);
+ ++it1;
+ ++it2;
+ ++it3;
+ }
+}
+
+TEST(NewLinkedHashSetTest, CopyConstructAndAssignString) {
+ NewLinkedHashSet<String> set1;
+ EXPECT_EQ(set1.size(), 0u);
+ EXPECT_TRUE(set1.IsEmpty());
+ set1.insert("1");
+ set1.insert("2");
+ set1.insert("3");
+ EXPECT_EQ(set1.size(), 3u);
+ NewLinkedHashSet<String> set2(set1);
+ EXPECT_EQ(set2.size(), 3u);
+ NewLinkedHashSet<String> set3;
+ EXPECT_EQ(set3.size(), 0u);
+ set3 = set2;
+ EXPECT_EQ(set3.size(), 3u);
+ auto it1 = set1.begin();
+ auto it2 = set2.begin();
+ auto it3 = set3.begin();
+ for (int i = 0; i < 3; i++) {
+ EXPECT_EQ(*it1, String(Vector<UChar>({'1' + i})));
+ EXPECT_EQ(*it2, String(Vector<UChar>({'1' + i})));
+ EXPECT_EQ(*it3, String(Vector<UChar>({'1' + i})));
+ ++it1;
+ ++it2;
+ ++it3;
+ }
+}
+
+TEST(NewLinkedHashSetTest, MoveConstructAndAssignInt) {
+ NewLinkedHashSet<ValueInstanceCount<int>> set1;
+ EXPECT_EQ(set1.size(), 0u);
+ EXPECT_TRUE(set1.IsEmpty());
+ int counter1 = 0;
+ int counter2 = 0;
+ int counter3 = 0;
+ set1.insert(ValueInstanceCount<int>(&counter1, 1));
+ set1.insert(ValueInstanceCount<int>(&counter2, 2));
+ set1.insert(ValueInstanceCount<int>(&counter3, 3));
+ EXPECT_EQ(set1.size(), 3u);
+ NewLinkedHashSet<ValueInstanceCount<int>> set2(std::move(set1));
+ EXPECT_EQ(set2.size(), 3u);
+ NewLinkedHashSet<ValueInstanceCount<int>> set3;
+ EXPECT_EQ(set3.size(), 0u);
+ set3 = std::move(set2);
+ EXPECT_EQ(set3.size(), 3u);
+ auto it = set3.begin();
+ for (int i = 0; i < 3; i++) {
+ EXPECT_EQ(it->Value(), i + 1);
+ ++it;
+ }
+
+ // Only move constructors were used, each object is only in set3.
+ // Count 2x because each set uses hash map and vector.
+ EXPECT_EQ(counter1, 2);
+ EXPECT_EQ(counter2, 2);
+ EXPECT_EQ(counter3, 2);
+
+ NewLinkedHashSet<ValueInstanceCount<int>> set4(set3);
+ // Copy constructor was used, each object is in set3 and set4.
+ EXPECT_EQ(counter1, 4);
+ EXPECT_EQ(counter2, 4);
+ EXPECT_EQ(counter3, 4);
+}
+
+TEST(NewLinkedHashSetTest, MoveConstructAndAssignString) {
+ NewLinkedHashSet<ValueInstanceCount<String>> set1;
+ EXPECT_EQ(set1.size(), 0u);
+ EXPECT_TRUE(set1.IsEmpty());
+ int counter1 = 0;
+ int counter2 = 0;
+ int counter3 = 0;
+ set1.insert(ValueInstanceCount<String>(&counter1, "1"));
+ set1.insert(ValueInstanceCount<String>(&counter2, "2"));
+ set1.insert(ValueInstanceCount<String>(&counter3, "3"));
+ EXPECT_EQ(set1.size(), 3u);
+ NewLinkedHashSet<ValueInstanceCount<String>> set2(std::move(set1));
+ EXPECT_EQ(set2.size(), 3u);
+ NewLinkedHashSet<ValueInstanceCount<String>> set3;
+ EXPECT_EQ(set3.size(), 0u);
+ set3 = std::move(set2);
+ EXPECT_EQ(set3.size(), 3u);
+ auto it = set3.begin();
+ for (int i = 0; i < 3; i++) {
+ EXPECT_EQ(it->Value(), String(Vector<UChar>({'1' + i})));
+ ++it;
+ }
+
+ // Only move constructors were used, each object is only in set3.
+ // Count 2x because each set uses hash map and vector.
+ EXPECT_EQ(counter1, 2);
+ EXPECT_EQ(counter2, 2);
+ EXPECT_EQ(counter3, 2);
+
+ NewLinkedHashSet<ValueInstanceCount<String>> set4(set3);
+ // Copy constructor was used, each object is in set3 and set4.
+ EXPECT_EQ(counter1, 4);
+ EXPECT_EQ(counter2, 4);
+ EXPECT_EQ(counter3, 4);
+}
+
+TEST(NewLinkedHashSetTest, Iterator) {
+ using Set = NewLinkedHashSet<int>;
+ Set set;
+ EXPECT_TRUE(set.begin() == set.end());
+ EXPECT_TRUE(set.rbegin() == set.rend());
+}
+
+TEST(NewLinkedHashSetTest, FrontAndBack) {
+ using Set = NewLinkedHashSet<int>;
+ Set set;
+ EXPECT_EQ(set.size(), 0u);
+ EXPECT_TRUE(set.IsEmpty());
+
+ set.PrependOrMoveToFirst(1);
+ EXPECT_EQ(set.front(), 1);
+ EXPECT_EQ(set.back(), 1);
+
+ set.insert(2);
+ EXPECT_EQ(set.front(), 1);
+ EXPECT_EQ(set.back(), 2);
+
+ set.AppendOrMoveToLast(3);
+ EXPECT_EQ(set.front(), 1);
+ EXPECT_EQ(set.back(), 3);
+
+ set.PrependOrMoveToFirst(3);
+ EXPECT_EQ(set.front(), 3);
+ EXPECT_EQ(set.back(), 2);
+
+ set.AppendOrMoveToLast(1);
+ EXPECT_EQ(set.front(), 3);
+ EXPECT_EQ(set.back(), 1);
+}
+
+TEST(NewLinkedHashSetTest, FindAndContains) {
+ using Set = NewLinkedHashSet<int>;
+ Set set;
+ set.insert(2);
+ set.AppendOrMoveToLast(2);
+ set.PrependOrMoveToFirst(1);
+ set.insert(3);
+ set.AppendOrMoveToLast(4);
+ set.insert(5);
+
+ int i = 1;
+ for (auto element : set) {
+ EXPECT_EQ(element, i);
+ i++;
+ }
+
+ Set::const_iterator it = set.find(2);
+ EXPECT_EQ(*it, 2);
+ it = set.find(3);
+ EXPECT_EQ(*it, 3);
+ it = set.find(10);
+ EXPECT_TRUE(it == set.end());
+
+ EXPECT_TRUE(set.Contains(1));
+ EXPECT_TRUE(set.Contains(2));
+ EXPECT_TRUE(set.Contains(3));
+ EXPECT_TRUE(set.Contains(4));
+ EXPECT_TRUE(set.Contains(5));
+
+ EXPECT_FALSE(set.Contains(10));
+}
+
+TEST(NewLinkedHashSetTest, Insert) {
+ using Set = NewLinkedHashSet<int>;
+ Set set;
+ Set::AddResult result = set.insert(1);
+ EXPECT_TRUE(result.is_new_entry);
+ EXPECT_EQ(*result.stored_value, 1);
+
+ result = set.insert(1);
+ EXPECT_FALSE(result.is_new_entry);
+ EXPECT_EQ(*result.stored_value, 1);
+
+ result = set.insert(2);
+ EXPECT_TRUE(result.is_new_entry);
+ EXPECT_EQ(*result.stored_value, 2);
+
+ result = set.insert(3);
+ EXPECT_TRUE(result.is_new_entry);
+ EXPECT_EQ(*result.stored_value, 3);
+
+ result = set.insert(2);
+ EXPECT_FALSE(result.is_new_entry);
+ EXPECT_EQ(*result.stored_value, 2);
+
+ Set::const_iterator it = set.begin();
+ EXPECT_EQ(*it, 1);
+ ++it;
+ EXPECT_EQ(*it, 2);
+ ++it;
+ EXPECT_EQ(*it, 3);
+ ++it;
+ EXPECT_TRUE(it == set.end());
+}
+
+TEST(NewLinkedHashSetTest, InsertBefore) {
+ using Set = NewLinkedHashSet<int>;
+ Set set;
+
+ set.InsertBefore(set.begin(), 1);
+ set.InsertBefore(10, 3);
+ set.InsertBefore(3, 2);
+ set.InsertBefore(set.end(), 6);
+ set.InsertBefore(--set.end(), 5);
+ set.InsertBefore(5, 4);
+
+ Set::const_iterator it = set.begin();
+ EXPECT_EQ(*it, 1);
+ ++it;
+ EXPECT_EQ(*it, 2);
+ ++it;
+ EXPECT_EQ(*it, 3);
+ ++it;
+ EXPECT_EQ(*it, 4);
+ ++it;
+ EXPECT_EQ(*it, 5);
+ ++it;
+ EXPECT_EQ(*it, 6);
+ ++it;
+ EXPECT_TRUE(it == set.end());
+}
+
+TEST(NewLinkedHashSetTest, AppendOrMoveToLast) {
+ using Set = NewLinkedHashSet<int>;
+ Set set;
+ Set::AddResult result = set.AppendOrMoveToLast(1);
+ EXPECT_TRUE(result.is_new_entry);
+ EXPECT_EQ(*result.stored_value, 1);
+
+ result = set.AppendOrMoveToLast(2);
+ EXPECT_TRUE(result.is_new_entry);
+ EXPECT_EQ(*result.stored_value, 2);
+
+ result = set.AppendOrMoveToLast(1);
+ EXPECT_FALSE(result.is_new_entry);
+ EXPECT_EQ(*result.stored_value, 1);
+
+ result = set.AppendOrMoveToLast(3);
+ EXPECT_TRUE(result.is_new_entry);
+ EXPECT_EQ(*result.stored_value, 3);
+
+ Set::const_iterator it = set.begin();
+ EXPECT_EQ(*it, 2);
+ ++it;
+ EXPECT_EQ(*it, 1);
+ ++it;
+ EXPECT_EQ(*it, 3);
+}
+
+TEST(NewLinkedHashSetTest, PrependOrMoveToFirst) {
+ using Set = NewLinkedHashSet<int>;
+ Set set;
+ Set::AddResult result = set.PrependOrMoveToFirst(1);
+ EXPECT_TRUE(result.is_new_entry);
+ EXPECT_EQ(*result.stored_value, 1);
+
+ result = set.PrependOrMoveToFirst(2);
+ EXPECT_TRUE(result.is_new_entry);
+ EXPECT_EQ(*result.stored_value, 2);
+
+ result = set.PrependOrMoveToFirst(1);
+ EXPECT_FALSE(result.is_new_entry);
+ EXPECT_EQ(*result.stored_value, 1);
+
+ result = set.PrependOrMoveToFirst(3);
+ EXPECT_TRUE(result.is_new_entry);
+ EXPECT_EQ(*result.stored_value, 3);
+
+ Set::const_iterator it = set.begin();
+ EXPECT_EQ(*it, 3);
+ ++it;
+ EXPECT_EQ(*it, 1);
+ ++it;
+ EXPECT_EQ(*it, 2);
+}
+
+TEST(NewLinkedHashSetTest, Erase) {
+ using Set = NewLinkedHashSet<int>;
+ Set set;
+ set.insert(1);
+ set.insert(2);
+ set.insert(3);
+ set.insert(4);
+ set.insert(5);
+
+ Set::const_iterator it = set.begin();
+ ++it;
+ set.erase(it);
+ it = set.begin();
+ EXPECT_EQ(*it, 1);
+ ++it;
+ EXPECT_EQ(*it, 3);
+ ++it;
+ EXPECT_EQ(*it, 4);
+ ++it;
+ EXPECT_EQ(*it, 5);
+
+ set.erase(3);
+ it = set.begin();
+ EXPECT_EQ(*it, 1);
+ ++it;
+ EXPECT_EQ(*it, 4);
+ ++it;
+ EXPECT_EQ(*it, 5);
+
+ set.insert(6);
+ it = set.begin();
+ EXPECT_EQ(*it, 1);
+ ++it;
+ EXPECT_EQ(*it, 4);
+ ++it;
+ EXPECT_EQ(*it, 5);
+ ++it;
+ EXPECT_EQ(*it, 6);
+}
+
+TEST(NewLinkedHashSetTest, RemoveFirst) {
+ using Set = NewLinkedHashSet<int>;
+ Set set;
+ set.insert(1);
+ set.insert(2);
+ set.insert(3);
+
+ set.RemoveFirst();
+ Set::const_iterator it = set.begin();
+ EXPECT_EQ(*it, 2);
+ ++it;
+ EXPECT_EQ(*it, 3);
+
+ set.RemoveFirst();
+ it = set.begin();
+ EXPECT_EQ(*it, 3);
+
+ set.RemoveFirst();
+ EXPECT_TRUE(set.begin() == set.end());
+}
+
+TEST(NewLinkedHashSetTest, pop_back) {
+ using Set = NewLinkedHashSet<int>;
+ Set set;
+ set.insert(1);
+ set.insert(2);
+ set.insert(3);
+
+ set.pop_back();
+ Set::const_iterator it = set.begin();
+ EXPECT_EQ(*it, 1);
+ ++it;
+ EXPECT_EQ(*it, 2);
+
+ set.pop_back();
+ it = set.begin();
+ EXPECT_EQ(*it, 1);
+
+ set.pop_back();
+ EXPECT_TRUE(set.begin() == set.end());
+}
+
+TEST(NewLinkedHashSetTest, Clear) {
+ using Set = NewLinkedHashSet<int>;
+ Set set;
+ set.insert(1);
+ set.insert(2);
+ set.insert(3);
+
+ set.clear();
+ EXPECT_TRUE(set.begin() == set.end());
+
+ set.insert(1);
+ Set::const_iterator it = set.begin();
+ EXPECT_EQ(*it, 1);
+ ++it;
+ EXPECT_TRUE(it == set.end());
+}
+
+} // namespace WTF
diff --git a/chromium/third_party/blink/renderer/platform/wtf/list_hash_set.h b/chromium/third_party/blink/renderer/platform/wtf/list_hash_set.h
index 39fd2a0dfdb..2792dbc6b97 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/list_hash_set.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/list_hash_set.h
@@ -58,7 +58,7 @@ class ListHashSetReverseIterator;
template <typename Set>
class ListHashSetConstReverseIterator;
-template <typename ValueArg>
+template <typename ValueArg, typename Allocator>
class ListHashSetNodeBase;
template <typename ValueArg, typename Allocator>
class ListHashSetNode;
@@ -70,6 +70,17 @@ struct ListHashSetNodeHashFunctions;
template <typename HashArg>
struct ListHashSetTranslator;
+template <typename Value, typename Allocator>
+struct ListHashSetTraits
+ : public HashTraits<ListHashSetNode<Value, Allocator>*> {
+ using Node = ListHashSetNode<Value, Allocator>;
+
+ static void ConstructDeletedValue(Node*& slot, bool) {
+ AsAtomicPtr(&slot)->store(reinterpret_cast<Node*>(-1),
+ std::memory_order_relaxed);
+ }
+};
+
// Note that for a ListHashSet you cannot specify the HashTraits as a template
// argument. It uses the default hash traits for the ValueArg type.
template <typename ValueArg,
@@ -85,7 +96,7 @@ class ListHashSet
USE_ALLOCATOR(ListHashSet, Allocator);
typedef ListHashSetNode<ValueArg, Allocator> Node;
- typedef HashTraits<Node*> NodeTraits;
+ typedef ListHashSetTraits<ValueArg, Allocator> NodeTraits;
typedef ListHashSetNodeHashFunctions<HashArg> NodeHash;
typedef ListHashSetTranslator<HashArg> BaseTranslator;
@@ -137,14 +148,9 @@ class ListHashSet
public:
friend class ListHashSet<ValueArg, inlineCapacity, HashArg, AllocatorArg>;
AddResult(Node* node, bool is_new_entry)
- : stored_value(&node->value_),
- is_new_entry(is_new_entry),
- node_(node) {}
+ : stored_value(&node->value_), is_new_entry(is_new_entry) {}
ValueType* stored_value;
bool is_new_entry;
-
- private:
- Node* node_;
};
ListHashSet();
@@ -201,12 +207,6 @@ class ListHashSet
template <typename IncomingValueType>
AddResult insert(IncomingValueType&&);
- // Same as insert() except that the return value is an iterator. Useful in
- // cases where it's needed to have the same return value as find() and where
- // it's not possible to use a pointer to the storedValue.
- template <typename IncomingValueType>
- iterator AddReturnIterator(IncomingValueType&&);
-
// Add the value to the end of the collection. If the value was already in
// the list, it is moved to the end.
template <typename IncomingValueType>
@@ -235,8 +235,8 @@ class ListHashSet
ValueType Take(ValuePeekInType);
ValueType TakeFirst();
- template <typename VisitorDispatcher>
- void Trace(VisitorDispatcher);
+ template <typename VisitorDispatcher, typename A = AllocatorArg>
+ std::enable_if_t<A::kIsGarbageCollected> Trace(VisitorDispatcher) const;
protected:
typename ImplType::ValueType** GetBufferSlot() {
@@ -272,10 +272,62 @@ class ListHashSet
typename Allocator::AllocatorProvider allocator_provider_;
};
+template <typename T, typename Allocator>
+class ListHashSetNodeBasePointer {
+ using NodeType = ListHashSetNodeBase<T, Allocator>;
+
+ public:
+ ListHashSetNodeBasePointer& operator=(
+ const ListHashSetNodeBasePointer& other) {
+ SetSafe(other);
+ return *this;
+ }
+
+ template <typename U>
+ ListHashSetNodeBasePointer& operator=(
+ const ListHashSetNodeBasePointer<U, Allocator>& other) {
+ SetSafe(other);
+ return *this;
+ }
+
+ template <typename U>
+ ListHashSetNodeBasePointer& operator=(U* other) {
+ SetSafe(other);
+ return *this;
+ }
+
+ ListHashSetNodeBasePointer& operator=(std::nullptr_t) {
+ SetSafe(nullptr);
+ return *this;
+ }
+
+ NodeType* Get() const { return node_; }
+ explicit operator bool() const { return Get(); }
+ operator NodeType*() const { return Get(); }
+ NodeType* operator->() const { return Get(); }
+ NodeType& operator*() const { return *Get(); }
+
+ private:
+ void SetSafe(NodeType* node) {
+ AsAtomicPtr(&node_)->store(node, std::memory_order_relaxed);
+ }
+
+ NodeType* GetSafe() const {
+ if (Allocator::kIsGarbageCollected)
+ return AsAtomicPtr(&node_)->load(std::memory_order_relaxed);
+ return node_;
+ }
+
+ NodeType* node_ = nullptr;
+
+ template <typename ValueArg, typename AllocatorArg>
+ friend class ListHashSetNode;
+};
+
// ListHashSetNode has this base class to hold the members because the MSVC
// compiler otherwise gets into circular template dependencies when trying to do
// sizeof on a node.
-template <typename ValueArg>
+template <typename ValueArg, typename Allocator>
class ListHashSetNodeBase {
DISALLOW_NEW();
@@ -285,8 +337,8 @@ class ListHashSetNodeBase {
public:
ValueArg value_;
- ListHashSetNodeBase* prev_ = nullptr;
- ListHashSetNodeBase* next_ = nullptr;
+ ListHashSetNodeBasePointer<ValueArg, Allocator> prev_;
+ ListHashSetNodeBasePointer<ValueArg, Allocator> next_;
#if DCHECK_IS_ON()
bool is_allocated_ = true;
#endif
@@ -297,7 +349,7 @@ template <typename ValueArg, size_t inlineCapacity>
struct ListHashSetAllocator : public PartitionAllocator {
typedef PartitionAllocator TableAllocator;
typedef ListHashSetNode<ValueArg, ListHashSetAllocator> Node;
- typedef ListHashSetNodeBase<ValueArg> NodeBase;
+ typedef ListHashSetNodeBase<ValueArg, ListHashSetAllocator> NodeBase;
class AllocatorProvider {
DISALLOW_NEW();
@@ -382,7 +434,7 @@ struct ListHashSetAllocator : public PartitionAllocator {
bool InPool(Node* node) { return node >= Pool() && node < PastPool(); }
template <typename VisitorDispatcher>
- static void TraceValue(VisitorDispatcher, Node*) {}
+ static void TraceValue(VisitorDispatcher, const Node*) {}
private:
Node* Pool() { return reinterpret_cast_ptr<Node*>(pool_); }
@@ -402,19 +454,19 @@ struct ListHashSetAllocator : public PartitionAllocator {
};
template <typename ValueArg, typename AllocatorArg>
-class ListHashSetNode : public ListHashSetNodeBase<ValueArg> {
+class ListHashSetNode : public ListHashSetNodeBase<ValueArg, AllocatorArg> {
public:
typedef AllocatorArg NodeAllocator;
typedef ValueArg Value;
template <typename U>
ListHashSetNode(U&& value)
- : ListHashSetNodeBase<ValueArg>(std::forward<U>(value)) {}
+ : ListHashSetNodeBase<ValueArg, AllocatorArg>(std::forward<U>(value)) {}
void* operator new(size_t, NodeAllocator* allocator) {
- static_assert(
- sizeof(ListHashSetNode) == sizeof(ListHashSetNodeBase<ValueArg>),
- "please add any fields to the base");
+ static_assert(sizeof(ListHashSetNode) ==
+ sizeof(ListHashSetNodeBase<ValueArg, AllocatorArg>),
+ "please add any fields to the base");
return allocator->AllocateNode();
}
@@ -452,7 +504,16 @@ class ListHashSetNode : public ListHashSetNodeBase<ValueArg> {
}
template <typename VisitorDispatcher, typename A = NodeAllocator>
- std::enable_if_t<A::kIsGarbageCollected> Trace(VisitorDispatcher visitor) {
+ std::enable_if_t<A::kIsGarbageCollected> Trace(
+ VisitorDispatcher visitor) const {
+ if (visitor->ConcurrentTracingBailOut(
+ {this, [](blink::Visitor* visitor, const void* object) {
+ reinterpret_cast<const ListHashSetNode<ValueArg, AllocatorArg>*>(
+ object)
+ ->Trace(visitor);
+ }}))
+ return;
+
// The conservative stack scan can find nodes that have been removed
// from the set and destructed. We don't need to trace these, and it
// would be wrong to do so, because the class will not expect the trace
@@ -460,18 +521,20 @@ class ListHashSetNode : public ListHashSetNodeBase<ValueArg> {
// node from the ListHashSet while an iterator is positioned at that
// node, so there should be no valid pointers from the stack to a
// destructed node.
- if (WasAlreadyDestructed())
+ if (WasAlreadyDestructedSafe())
return;
NodeAllocator::TraceValue(visitor, this);
- visitor->Trace(Next());
- visitor->Trace(Prev());
+ visitor->Trace(
+ reinterpret_cast<const ListHashSetNode*>(this->next_.GetSafe()));
+ visitor->Trace(
+ reinterpret_cast<const ListHashSetNode*>(this->prev_.GetSafe()));
}
ListHashSetNode* Next() const {
- return reinterpret_cast<ListHashSetNode*>(this->next_);
+ return reinterpret_cast<ListHashSetNode*>(this->next_.Get());
}
ListHashSetNode* Prev() const {
- return reinterpret_cast<ListHashSetNode*>(this->prev_);
+ return reinterpret_cast<ListHashSetNode*>(this->prev_.Get());
}
// Don't add fields here, the ListHashSetNodeBase and this should have the
@@ -483,6 +546,12 @@ class ListHashSetNode : public ListHashSetNodeBase<ValueArg> {
template <typename HashArg>
friend struct ListHashSetNodeHashFunctions;
+
+ private:
+ bool WasAlreadyDestructedSafe() const {
+ DCHECK(NodeAllocator::kIsGarbageCollected);
+ return this->prev_.GetSafe() == UnlinkedNodePointer();
+ }
};
template <typename HashArg>
@@ -544,7 +613,7 @@ class ListHashSetIterator {
operator const_iterator() const { return iterator_; }
template <typename VisitorDispatcher>
- void Trace(VisitorDispatcher visitor) {
+ void Trace(VisitorDispatcher visitor) const {
iterator_.Trace(visitor);
}
@@ -606,7 +675,7 @@ class ListHashSetConstIterator {
}
template <typename VisitorDispatcher>
- void Trace(VisitorDispatcher visitor) {
+ void Trace(VisitorDispatcher visitor) const {
visitor->Trace(*set_);
visitor->Trace(position_);
}
@@ -666,7 +735,7 @@ class ListHashSetReverseIterator {
operator const_reverse_iterator() const { return iterator_; }
template <typename VisitorDispatcher>
- void Trace(VisitorDispatcher visitor) {
+ void Trace(VisitorDispatcher visitor) const {
iterator_.trace(visitor);
}
@@ -728,7 +797,7 @@ class ListHashSetConstReverseIterator {
}
template <typename VisitorDispatcher>
- void Trace(VisitorDispatcher visitor) {
+ void Trace(VisitorDispatcher visitor) const {
visitor->Trace(*set_);
visitor->Trace(position_);
}
@@ -756,7 +825,9 @@ struct ListHashSetTranslator {
}
template <typename T, typename U, typename V>
static void Translate(T*& location, U&& key, const V& allocator) {
- location = new (const_cast<V*>(&allocator)) T(std::forward<U>(key));
+ AsAtomicPtr(&location)->store(new (const_cast<V*>(&allocator))
+ T(std::forward<U>(key)),
+ std::memory_order_relaxed);
}
};
@@ -939,14 +1010,6 @@ ListHashSet<T, inlineCapacity, U, V>::insert(IncomingValueType&& value) {
template <typename T, size_t inlineCapacity, typename U, typename V>
template <typename IncomingValueType>
-typename ListHashSet<T, inlineCapacity, U, V>::iterator
-ListHashSet<T, inlineCapacity, U, V>::AddReturnIterator(
- IncomingValueType&& value) {
- return MakeIterator(insert(std::forward<IncomingValueType>(value)).node_);
-}
-
-template <typename T, size_t inlineCapacity, typename U, typename V>
-template <typename IncomingValueType>
typename ListHashSet<T, inlineCapacity, U, V>::AddResult
ListHashSet<T, inlineCapacity, U, V>::AppendOrMoveToLast(
IncomingValueType&& value) {
@@ -1125,8 +1188,17 @@ void ListHashSet<T, inlineCapacity, U, V>::DeleteAllNodes() {
}
template <typename T, size_t inlineCapacity, typename U, typename V>
-template <typename VisitorDispatcher>
-void ListHashSet<T, inlineCapacity, U, V>::Trace(VisitorDispatcher visitor) {
+template <typename VisitorDispatcher, typename A>
+std::enable_if_t<A::kIsGarbageCollected>
+ListHashSet<T, inlineCapacity, U, V>::Trace(VisitorDispatcher visitor) const {
+ if (visitor->ConcurrentTracingBailOut(
+ {this, [](blink::Visitor* visitor, const void* object) {
+ reinterpret_cast<const ListHashSet<T, inlineCapacity, U, V>*>(
+ object)
+ ->Trace(visitor);
+ }}))
+ return;
+
static_assert(!IsWeak<T>::value,
"HeapListHashSet does not support weakness, consider using "
"HeapLinkedHashSet instead.");
diff --git a/chromium/third_party/blink/renderer/platform/wtf/list_hash_set_test.cc b/chromium/third_party/blink/renderer/platform/wtf/list_hash_set_test.cc
index cd1be0089b9..f9cb5f8270c 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/list_hash_set_test.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/list_hash_set_test.cc
@@ -41,12 +41,17 @@ namespace {
template <typename Set>
class ListOrLinkedHashSetTest : public testing::Test {};
-using SetTypes =
- testing::Types<ListHashSet<int>, ListHashSet<int, 1>, LinkedHashSet<int>>;
+using SetTypes = testing::Types<ListHashSet<int>,
+ ListHashSet<int, 1>,
+ LinkedHashSet<int>,
+ NewLinkedHashSet<int>>;
TYPED_TEST_SUITE(ListOrLinkedHashSetTest, SetTypes);
TYPED_TEST(ListOrLinkedHashSetTest, RemoveFirst) {
using Set = TypeParam;
+ // TODO(bartekn): Make the test work. Fails due to empty value.
+ if (std::is_same<Set, NewLinkedHashSet<int>>::value)
+ return;
Set list;
list.insert(-1);
list.insert(0);
@@ -197,6 +202,9 @@ TYPED_TEST(ListOrLinkedHashSetTest, PrependOrMoveToLastWithDuplicates) {
TYPED_TEST(ListOrLinkedHashSetTest, Find) {
using Set = TypeParam;
+ // TODO(bartekn): Make the test work. Fails due to empty value.
+ if (std::is_same<Set, NewLinkedHashSet<int>>::value)
+ return;
Set set;
set.insert(-1);
set.insert(0);
@@ -228,6 +236,9 @@ TYPED_TEST(ListOrLinkedHashSetTest, Find) {
TYPED_TEST(ListOrLinkedHashSetTest, InsertBefore) {
using Set = TypeParam;
+ // TODO(bartekn): Make the test work. Fails due to empty value.
+ if (std::is_same<Set, NewLinkedHashSet<int>>::value)
+ return;
bool can_modify_while_iterating =
!std::is_same<Set, LinkedHashSet<int>>::value;
Set set;
@@ -273,54 +284,6 @@ TYPED_TEST(ListOrLinkedHashSetTest, InsertBefore) {
EXPECT_EQ(7u, set.size());
}
-TYPED_TEST(ListOrLinkedHashSetTest, AddReturnIterator) {
- using Set = TypeParam;
- bool can_modify_while_iterating =
- !std::is_same<Set, LinkedHashSet<int>>::value;
- Set set;
- set.insert(-1);
- set.insert(0);
- set.insert(1);
- set.insert(2);
-
- typename Set::iterator it = set.AddReturnIterator(3);
- EXPECT_EQ(3, *it);
- --it;
- EXPECT_EQ(2, *it);
- EXPECT_EQ(5u, set.size());
- --it;
- EXPECT_EQ(1, *it);
- --it;
- EXPECT_EQ(0, *it);
- it = set.AddReturnIterator(4);
- if (can_modify_while_iterating) {
- set.erase(3);
- set.erase(2);
- set.erase(1);
- set.erase(0);
- set.erase(-1);
- EXPECT_EQ(1u, set.size());
- }
- EXPECT_EQ(4, *it);
- ++it;
- EXPECT_EQ(it, set.end());
- --it;
- EXPECT_EQ(4, *it);
- if (can_modify_while_iterating) {
- set.InsertBefore(it, -1);
- set.InsertBefore(it, 0);
- set.InsertBefore(it, 1);
- set.InsertBefore(it, 2);
- set.InsertBefore(it, 3);
- }
- EXPECT_EQ(6u, set.size());
- it = set.AddReturnIterator(5);
- EXPECT_EQ(7u, set.size());
- set.erase(it);
- EXPECT_EQ(6u, set.size());
- EXPECT_EQ(4, set.back());
-}
-
TYPED_TEST(ListOrLinkedHashSetTest, Swap) {
using Set = TypeParam;
int num = 10;
@@ -409,11 +372,17 @@ class ListOrLinkedHashSetRefPtrTest : public testing::Test {};
using RefPtrSetTypes =
testing::Types<ListHashSet<scoped_refptr<DummyRefCounted>>,
ListHashSet<scoped_refptr<DummyRefCounted>, 1>,
- LinkedHashSet<scoped_refptr<DummyRefCounted>>>;
+ LinkedHashSet<scoped_refptr<DummyRefCounted>>,
+ NewLinkedHashSet<scoped_refptr<DummyRefCounted>>>;
TYPED_TEST_SUITE(ListOrLinkedHashSetRefPtrTest, RefPtrSetTypes);
TYPED_TEST(ListOrLinkedHashSetRefPtrTest, WithRefPtr) {
using Set = TypeParam;
+ int expected = 1;
+ // NewLinkedHashSet stores each object twice.
+ if (std::is_same<Set,
+ NewLinkedHashSet<scoped_refptr<DummyRefCounted>>>::value)
+ expected = 2;
bool is_deleted = false;
DummyRefCounted::ref_invokes_count_ = 0;
scoped_refptr<DummyRefCounted> ptr =
@@ -423,24 +392,24 @@ TYPED_TEST(ListOrLinkedHashSetRefPtrTest, WithRefPtr) {
Set set;
set.insert(ptr);
// Referenced only once (to store a copy in the container).
- EXPECT_EQ(1, DummyRefCounted::ref_invokes_count_);
+ EXPECT_EQ(expected, DummyRefCounted::ref_invokes_count_);
EXPECT_EQ(ptr, set.front());
- EXPECT_EQ(1, DummyRefCounted::ref_invokes_count_);
+ EXPECT_EQ(expected, DummyRefCounted::ref_invokes_count_);
DummyRefCounted* raw_ptr = ptr.get();
EXPECT_TRUE(set.Contains(ptr));
EXPECT_TRUE(set.Contains(raw_ptr));
- EXPECT_EQ(1, DummyRefCounted::ref_invokes_count_);
+ EXPECT_EQ(expected, DummyRefCounted::ref_invokes_count_);
ptr = nullptr;
EXPECT_FALSE(is_deleted);
- EXPECT_EQ(1, DummyRefCounted::ref_invokes_count_);
+ EXPECT_EQ(expected, DummyRefCounted::ref_invokes_count_);
set.erase(raw_ptr);
EXPECT_TRUE(is_deleted);
- EXPECT_EQ(1, DummyRefCounted::ref_invokes_count_);
+ EXPECT_EQ(expected, DummyRefCounted::ref_invokes_count_);
}
TYPED_TEST(ListOrLinkedHashSetRefPtrTest, ExerciseValuePeekInType) {
@@ -460,11 +429,10 @@ TYPED_TEST(ListOrLinkedHashSetRefPtrTest, ExerciseValuePeekInType) {
const Set& const_set(set);
const_set.find(ptr);
EXPECT_TRUE(set.Contains(ptr));
- typename Set::iterator it = set.AddReturnIterator(ptr);
+ set.insert(ptr);
set.AppendOrMoveToLast(ptr);
set.PrependOrMoveToFirst(ptr);
set.InsertBefore(ptr, ptr);
- set.InsertBefore(it, ptr);
EXPECT_EQ(1u, set.size());
set.insert(ptr2);
ptr2 = nullptr;
@@ -516,6 +484,7 @@ struct ComplexityTranslator {
template <typename Set>
class ListOrLinkedHashSetTranslatorTest : public testing::Test {};
+// TODO(bartekn): Add NewLinkedHashSet once it supports custom hash function.
using TranslatorSetTypes =
testing::Types<ListHashSet<Complicated, 256, ComplicatedHashFunctions>,
ListHashSet<Complicated, 1, ComplicatedHashFunctions>,
@@ -625,7 +594,8 @@ class ListOrLinkedHashSetCountCopyTest : public testing::Test {};
using CountCopySetTypes = testing::Types<ListHashSet<CountCopy>,
ListHashSet<CountCopy, 1>,
- LinkedHashSet<CountCopy>>;
+ LinkedHashSet<CountCopy>,
+ NewLinkedHashSet<CountCopy>>;
TYPED_TEST_SUITE(ListOrLinkedHashSetCountCopyTest, CountCopySetTypes);
TYPED_TEST(ListOrLinkedHashSetCountCopyTest,
@@ -655,6 +625,7 @@ TYPED_TEST(ListOrLinkedHashSetCountCopyTest, MoveAssignmentShouldNotMakeACopy) {
template <typename Set>
class ListOrLinkedHashSetMoveOnlyTest : public testing::Test {};
+// TODO(bartekn): Add NewLinkedHashSet once it supports move-only type.
using MoveOnlySetTypes = testing::Types<ListHashSet<MoveOnlyHashValue>,
ListHashSet<MoveOnlyHashValue, 1>,
LinkedHashSet<MoveOnlyHashValue>>;
@@ -685,14 +656,6 @@ TYPED_TEST(ListOrLinkedHashSetMoveOnlyTest, MoveOnlyValue) {
EXPECT_TRUE(iter == set.end());
// ListHashSet and LinkedHashSet have several flavors of add().
- iter = set.AddReturnIterator(MoveOnlyHashValue(2, 2));
- EXPECT_EQ(2, iter->Value());
- EXPECT_EQ(2, iter->Id());
-
- iter = set.AddReturnIterator(MoveOnlyHashValue(2, 222));
- EXPECT_EQ(2, iter->Value());
- EXPECT_EQ(2, iter->Id());
-
{
AddResult add_result = set.AppendOrMoveToLast(MoveOnlyHashValue(3, 3));
EXPECT_TRUE(add_result.is_new_entry);
@@ -758,6 +721,7 @@ struct DefaultHash<InvalidZeroValue> {
template <typename Set>
class ListOrLinkedHashSetInvalidZeroTest : public testing::Test {};
+// TODO(bartekn): Add NewLinkedHashSet once it supports custom hash traits.
using InvalidZeroValueSetTypes =
testing::Types<ListHashSet<InvalidZeroValue>,
ListHashSet<InvalidZeroValue, 1>,
diff --git a/chromium/third_party/blink/renderer/platform/wtf/lru_cache.h b/chromium/third_party/blink/renderer/platform/wtf/lru_cache.h
new file mode 100644
index 00000000000..c2d27f0e430
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/wtf/lru_cache.h
@@ -0,0 +1,148 @@
+// 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_LRU_CACHE_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_LRU_CACHE_H_
+
+#include <memory>
+
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+#include "third_party/blink/renderer/platform/wtf/construct_traits.h"
+#include "third_party/blink/renderer/platform/wtf/doubly_linked_list.h"
+#include "third_party/blink/renderer/platform/wtf/hash_map.h"
+#include "third_party/blink/renderer/platform/wtf/hash_table_deleted_value_type.h"
+
+namespace WTF {
+
+// LruCache is a simple least-recently-used cache based on HashMap and
+// DoublyLinkedList. Useful in situations where caching by using a HashMap is
+// desirable but needs to be limited in size to not grow out of proportions.
+// LruCache uses a HashMap to store cache entries, and uses a DoublyLinkedList
+// in parallel to keep track of the age of entries. Accessing an entry using
+// Get() refreshes its age, Put() places a new entry into the HashMap with
+// youngest age as well. The least recently used entry of the list is pruned
+// when a Put() call would otherwise exceed the max_size limit.
+//
+// Example:
+// const size_t kMaxSize = 2;
+// LruCache<uint16_t, String> my_cache(kMaxSize);
+// my_cache.Put(13, "first string");
+// my_cache.Put(42, "second string");
+// my_cache.Put(256, "third string");
+// my_cache.Get(13) // -> nullptr, has been removed due to kMaxSize == 2.
+// my_cache.Get(42) // -> String* "second string"
+// my_cache.Get(256) // -> String* "third_string"
+//
+// See lru_cache_test.cc for more examples.
+template <typename KeyArg,
+ typename MappedArg,
+ typename HashArg = typename DefaultHash<KeyArg>::Hash,
+ typename KeyTraitsArg = HashTraits<KeyArg>>
+class LruCache {
+ USING_FAST_MALLOC(LruCache);
+
+ private:
+ class MappedListNodeWithKey final
+ : public DoublyLinkedListNode<MappedListNodeWithKey> {
+ USING_FAST_MALLOC(MappedListNodeWithKey);
+
+ public:
+ friend class DoublyLinkedListNode<MappedListNodeWithKey>;
+
+ MappedListNodeWithKey(const KeyArg& key, MappedArg&& mapped_arg)
+ : key_(key), mapped_value_(std::move(mapped_arg)) {}
+
+ MappedArg* Value() { return &mapped_value_; }
+
+ void SetValue(MappedArg&& mapped_arg) {
+ mapped_value_ = std::move(mapped_arg);
+ }
+
+ const KeyArg& Key() const { return key_; }
+
+ private:
+ KeyArg key_;
+ MappedArg mapped_value_;
+ MappedListNodeWithKey* prev_{nullptr};
+ MappedListNodeWithKey* next_{nullptr};
+ };
+
+ using MappedListNode = std::unique_ptr<MappedListNodeWithKey>;
+
+ using HashMapType = HashMap<KeyArg, MappedListNode, HashArg, KeyTraitsArg>;
+
+ public:
+ LruCache(size_t max_size) : max_size_(max_size) {
+ static_assert(!IsGarbageCollectedType<KeyArg>::value ||
+ !IsGarbageCollectedType<MappedArg>::value,
+ "Cannot use LruCache<> with garbage collected types.");
+ CHECK_GT(max_size_, 0u);
+ }
+
+ // Retrieve cache entry under |key| if it exists and refresh its age.
+ // Returns: pointer to cache entry or nullptr if no entry is found for that
+ // key.
+ MappedArg* Get(const KeyArg& key) {
+ if (map_.IsEmpty())
+ return nullptr;
+
+ typename HashMapType::iterator find_result = map_.find(key);
+ if (find_result == map_.end())
+ return nullptr;
+
+ // Move result to beginning of list.
+ MappedListNodeWithKey* node = find_result->value.get();
+ ordering_.Remove(node);
+ ordering_.Push(node);
+ return find_result->value->Value();
+ }
+
+ // Place entry in cache as new / youngest. Multiple calls to Put() with an
+ // identical key but differing MappedArg will override the stored value and
+ // refresh the age.
+ void Put(const KeyArg& key, MappedArg&& arg) {
+ {
+ typename HashMapType::iterator find_result = map_.find(key);
+ if (find_result != map_.end()) {
+ find_result->value->SetValue(std::move(arg));
+ ordering_.Remove(find_result->value.get());
+ ordering_.Push(find_result->value.get());
+ } else {
+ auto list_node =
+ std::make_unique<MappedListNodeWithKey>(key, std::move(arg));
+ typename HashMapType::AddResult add_result =
+ map_.insert(key, std::move(list_node));
+ DCHECK(add_result.is_new_entry);
+ ordering_.Push(add_result.stored_value->value.get());
+ }
+ }
+
+ if (map_.size() > max_size_) {
+ RemoveLeastRecentlyUsed();
+ }
+ }
+
+ // Clear the cache, remove all elements.
+ void Clear() {
+ map_.clear();
+ ordering_.Clear();
+ }
+
+ size_t size() { return map_.size(); }
+
+ private:
+ void RemoveLeastRecentlyUsed() {
+ MappedListNodeWithKey* tail = ordering_.Tail();
+ ordering_.Remove(tail);
+ map_.erase(tail->Key());
+ }
+
+ HashMapType map_;
+ DoublyLinkedList<MappedListNodeWithKey> ordering_;
+ size_t max_size_;
+};
+
+} // namespace WTF
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_LRU_CACHE_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/lru_cache_test.cc b/chromium/third_party/blink/renderer/platform/wtf/lru_cache_test.cc
new file mode 100644
index 00000000000..914b15db53f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/wtf/lru_cache_test.cc
@@ -0,0 +1,110 @@
+// 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/wtf/lru_cache.h"
+
+#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace WTF {
+
+TEST(LruCacheTest, TestEmpty) {
+ LruCache<int, int> test_cache(1);
+ EXPECT_EQ(test_cache.Get(0), nullptr);
+}
+
+TEST(LruCacheTest, TestInstantiation) {
+ const int kMaxSize = 10;
+ const int kOffset = 1000;
+ LruCache<int, int> test_cache(kMaxSize);
+ EXPECT_EQ(test_cache.size(), 0u);
+ for (size_t i = 1; i < kMaxSize * 10; ++i) {
+ test_cache.Put(i, kOffset + i);
+ }
+ EXPECT_EQ(test_cache.size(), kMaxSize * 1u);
+ EXPECT_EQ(*test_cache.Get(kMaxSize * 10 - 1), kOffset + (kMaxSize * 10 - 1));
+ EXPECT_EQ(*test_cache.Get(kMaxSize * 10 - 2), kOffset + (kMaxSize * 10 - 2));
+ EXPECT_EQ(test_cache.Get(89), nullptr);
+ EXPECT_EQ(test_cache.Get(1), nullptr);
+ test_cache.Clear();
+ EXPECT_EQ(test_cache.size(), 0u);
+}
+
+TEST(LruCacheTest, TestString) {
+ const size_t kMaxSize = 4;
+ const char* test_strings[] = {"1_testing", "2_LruCache", "3_using",
+ "4_several", "5_random", "6_strings"};
+ LruCache<uint16_t, String> test_cache(kMaxSize);
+ uint16_t counter = 1;
+ EXPECT_EQ(test_cache.size(), 0u);
+ for (auto* test_string : test_strings) {
+ test_cache.Put(counter, test_string);
+ counter++;
+ }
+ EXPECT_EQ(test_cache.size(), kMaxSize);
+ EXPECT_EQ(test_cache.Get(1), nullptr);
+ EXPECT_EQ(test_cache.Get(2), nullptr);
+ EXPECT_EQ(*test_cache.Get(3), String(test_strings[2]));
+ EXPECT_EQ(*test_cache.Get(4), String(test_strings[3]));
+ EXPECT_EQ(*test_cache.Get(5), String(test_strings[4]));
+ EXPECT_EQ(*test_cache.Get(6), String(test_strings[5]));
+ test_cache.Put(1, test_strings[0]);
+ EXPECT_EQ(*test_cache.Get(1), String(test_strings[0]));
+ EXPECT_EQ(test_cache.Get(3), nullptr);
+ EXPECT_EQ(*test_cache.Get(4), String(test_strings[3]));
+ EXPECT_EQ(*test_cache.Get(5), String(test_strings[4]));
+ EXPECT_EQ(*test_cache.Get(6), String(test_strings[5]));
+ test_cache.Clear();
+ EXPECT_EQ(test_cache.size(), 0u);
+}
+
+TEST(LruCacheTest, TestOverrideKey) {
+ const size_t kMaxSize = 2;
+ const char* test_strings[] = {"original_value", "override"};
+ LruCache<uint16_t, String> test_cache(kMaxSize);
+ EXPECT_EQ(test_cache.size(), 0u);
+ test_cache.Put(1, test_strings[0]);
+ test_cache.Put(1, test_strings[1]);
+ EXPECT_EQ(*test_cache.Get(1), String(test_strings[1]));
+}
+
+TEST(LruCacheTest, StringToVector) {
+ const size_t kMaxSize = 4u;
+ LruCache<String, Vector<String>> typeface_cache(kMaxSize);
+
+ struct FontFallbackExample {
+ String locale;
+ String typeface_name;
+ } example_typefaces[] = {{"en_us", "Arial"},
+ {"ko", "Malgun Gothic"},
+ {"ja", "Yu Gothic UI"},
+ {"en_us", "Times New Roman"},
+ {"en_us", "Calibri"},
+ {"km", "Leelawadee UI"},
+ {"zh-Hans", "Microsoft Yahei UI"},
+ {"bn", "Nirmala UI"}};
+ for (auto& example : example_typefaces) {
+ Vector<String>* cache_for_locale = typeface_cache.Get(example.locale);
+ if (cache_for_locale) {
+ cache_for_locale->push_back(example.typeface_name);
+ } else {
+ Vector<String> new_cache_for_locale;
+ new_cache_for_locale.push_back(example.typeface_name);
+ typeface_cache.Put(String(example.locale),
+ std::move(new_cache_for_locale));
+ }
+ }
+ Vector<String>* vector_for_latin = typeface_cache.Get("en_us");
+ EXPECT_TRUE(vector_for_latin);
+ EXPECT_EQ(vector_for_latin->size(), 3u);
+ EXPECT_EQ(typeface_cache.Get("zh-Hant"), nullptr);
+ EXPECT_EQ(typeface_cache.Get("ko"), nullptr);
+ EXPECT_EQ(typeface_cache.Get("ja"), nullptr);
+}
+
+} // namespace WTF
diff --git a/chromium/third_party/blink/renderer/platform/wtf/pod_interval.h b/chromium/third_party/blink/renderer/platform/wtf/pod_interval.h
index 93a5a345991..ef6972acf3d 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/pod_interval.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/pod_interval.h
@@ -86,11 +86,11 @@ class PODInterval {
// UserData type is a pointer or other type which can be initialized
// with 0.
PODInterval(const T& low, const T& high)
- : low_(low), high_(high), data_(0), max_high_(high) {}
+ : low_(low), high_(high), data_(0), min_low_(low), max_high_(high) {}
// Constructor from two endpoints plus explicit user data.
PODInterval(const T& low, const T& high, const UserData data)
- : low_(low), high_(high), data_(data), max_high_(high) {}
+ : low_(low), high_(high), data_(data), min_low_(low), max_high_(high) {}
const T& Low() const { return low_; }
const T& High() const { return high_; }
@@ -119,6 +119,9 @@ class PODInterval {
Data() == other.Data());
}
+ const T& MinLow() const { return min_low_; }
+ void SetMinLow(const T& min_low) { min_low_ = min_low; }
+
const T& MaxHigh() const { return max_high_; }
void SetMaxHigh(const T& max_high) { max_high_ = max_high; }
@@ -132,6 +135,8 @@ class PODInterval {
builder.Append(ValueToString<T>::ToString(High()));
builder.Append("), data=");
builder.Append(ValueToString<UserData>::ToString(Data()));
+ builder.Append(", minLow=");
+ builder.Append(ValueToString<T>::ToString(MinLow()));
builder.Append(", maxHigh=");
builder.Append(ValueToString<T>::ToString(MaxHigh()));
builder.Append(']');
@@ -148,6 +153,7 @@ class PODInterval {
#else
UserData data_;
#endif
+ T min_low_;
T max_high_;
};
diff --git a/chromium/third_party/blink/renderer/platform/wtf/pod_interval_tree.h b/chromium/third_party/blink/renderer/platform/wtf/pod_interval_tree.h
index 79af877b225..7db780f2500 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/pod_interval_tree.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/pod_interval_tree.h
@@ -27,6 +27,7 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_POD_INTERVAL_TREE_H_
#include "base/macros.h"
+#include "base/optional.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/pod_arena.h"
#include "third_party/blink/renderer/platform/wtf/pod_interval.h"
@@ -105,14 +106,14 @@ class PODIntervalTree final : public PODRedBlackTree<PODInterval<T, UserData>> {
// Explicit dereference of "this" required because of
// inheritance rules in template classes.
IntervalSearchAdapterType adapter(result, interval.Low(), interval.High());
- SearchForOverlapsFrom<IntervalSearchAdapterType>(this->Root(), adapter);
+ SearchForOverlapsFrom(this->Root(), adapter);
}
template <class AdapterType>
void AllOverlapsWithAdapter(AdapterType& adapter) const {
// Explicit dereference of "this" required because of
// inheritance rules in template classes.
- SearchForOverlapsFrom<AdapterType>(this->Root(), adapter);
+ SearchForOverlapsFrom(this->Root(), adapter);
}
// Helper to create interval objects.
@@ -127,7 +128,13 @@ class PODIntervalTree final : public PODRedBlackTree<PODInterval<T, UserData>> {
return false;
if (!this->Root())
return true;
- return CheckInvariantsFromNode(this->Root(), nullptr);
+ return CheckInvariantsFromNode(this->Root());
+ }
+
+ // Returns the next interval point (start or end) after the given starting
+ // point (non-inclusive). If there is no such point, returns |base::nullopt|.
+ base::Optional<T> NextIntervalPoint(T start) const {
+ return NextIntervalPoint(start, this->Root());
}
private:
@@ -144,102 +151,184 @@ class PODIntervalTree final : public PODRedBlackTree<PODInterval<T, UserData>> {
// interval to the result vector. The intervals are sorted by
// increasing low endpoint.
template <class AdapterType>
- DISABLE_CFI_PERF void SearchForOverlapsFrom(IntervalNode* node,
- AdapterType& adapter) const {
- if (!node)
+ DISABLE_CFI_PERF static void SearchForOverlapsFrom(IntervalNode const* node,
+ AdapterType& adapter) {
+ // This is phrased this way to avoid the need for operator
+ // <= on type T.
+ if (!node || adapter.HighValue() < node->Data().MinLow() ||
+ node->Data().MaxHigh() < adapter.LowValue()) {
return;
+ }
// Because the intervals are sorted by left endpoint, inorder
// traversal produces results sorted as desired.
- // See whether we need to traverse the left subtree.
- IntervalNode* left = node->Left();
- if (left
- // This is phrased this way to avoid the need for operator
- // <= on type T.
- && !(left->Data().MaxHigh() < adapter.LowValue()))
- SearchForOverlapsFrom<AdapterType>(left, adapter);
+ // Attempt to traverse left subtree
+ SearchForOverlapsFrom(node->Left(), adapter);
// Check for overlap with current node.
adapter.CollectIfNeeded(node->Data());
- // See whether we need to traverse the right subtree.
- // This is phrased this way to avoid the need for operator <=
- // on type T.
- if (!(adapter.HighValue() < node->Data().Low()))
- SearchForOverlapsFrom<AdapterType>(node->Right(), adapter);
+ // Attempt to traverse right subtree
+ SearchForOverlapsFrom(node->Right(), adapter);
+ }
+
+ static base::Optional<T> NextIntervalPoint(T start,
+ IntervalNode const* node) {
+ // If this node doesn't exist or is entirely out of scope, just return. This
+ // prevents recursing deeper than necessary on the left.
+ if (!node || node->Data().MaxHigh() < start) {
+ return base::nullopt;
+ }
+ // Easy shortcut: If the lowest point in this subtree is in scope, just
+ // return that. This prevents recursing deeper than necessary on the right.
+ if (start < node->Data().MinLow()) {
+ return node->Data().MinLow();
+ }
+
+ auto left_candidate = NextIntervalPoint(start, node->Left());
+
+ // If the current node's low point isn't out of scope, we don't even need to
+ // look at the right branch.
+ if (start < node->Data().Low()) {
+ if (left_candidate.has_value()) {
+ return std::min(node->Data().Low(), left_candidate.value());
+ } else {
+ return node->Data().Low();
+ }
+ }
+
+ // If the current node's high point is in scope, consider that against the
+ // left branch
+ base::Optional<T> current_candidate;
+ if (start < node->Data().High()) {
+ if (left_candidate.has_value()) {
+ current_candidate =
+ std::min(node->Data().High(), left_candidate.value());
+ } else {
+ current_candidate = node->Data().High();
+ }
+ } else {
+ current_candidate = left_candidate;
+ }
+
+ // If the current (and left) nodes fail, tail-recurse on the right node
+ if (!current_candidate.has_value()) {
+ return NextIntervalPoint(start, node->Right());
+ }
+
+ // Otherwise, pick the min between the |current_candidate| and the right
+ // node
+ auto right_candidate = NextIntervalPoint(start, node->Right());
+ if (right_candidate.has_value()) {
+ return std::min(current_candidate.value(), right_candidate.value());
+ } else {
+ return current_candidate;
+ }
}
bool UpdateNode(IntervalNode* node) override {
- // Would use const T&, but need to reassign this reference in this
- // function.
- const T* cur_max = &node->Data().High();
+ T cur_max(node->Data().High());
+ T cur_min(node->Data().Low());
+
IntervalNode* left = node->Left();
if (left) {
- if (*cur_max < left->Data().MaxHigh())
- cur_max = &left->Data().MaxHigh();
+ // Left node will always have a lower MinLow than the right node, so just
+ // reassign immediately.
+ cur_min = left->Data().MinLow();
+ cur_max = std::max(cur_max, left->Data().MaxHigh());
}
+
IntervalNode* right = node->Right();
if (right) {
- if (*cur_max < right->Data().MaxHigh())
- cur_max = &right->Data().MaxHigh();
+ // Right node will always have greater min than current node or left
+ // branch, so don't bother checking it.
+ cur_max = std::max(cur_max, right->Data().MaxHigh());
}
- // This is phrased like this to avoid needing operator!= on type T.
- if (!(*cur_max == node->Data().MaxHigh())) {
- node->Data().SetMaxHigh(*cur_max);
- return true;
+
+ bool updated = false;
+ if (!(cur_min == node->Data().MinLow())) {
+ node->Data().SetMinLow(cur_min);
+ updated = true;
+ }
+ if (!(cur_max == node->Data().MaxHigh())) {
+ node->Data().SetMaxHigh(cur_max);
+ updated = true;
}
- return false;
+
+ return updated;
}
- bool CheckInvariantsFromNode(IntervalNode* node, T* current_max_value) const {
- // These assignments are only done in order to avoid requiring
- // a default constructor on type T.
- T left_max_value(node->Data().MaxHigh());
- T right_max_value(node->Data().MaxHigh());
- IntervalNode* left = node->Left();
- IntervalNode* right = node->Right();
+ static bool CheckInvariantsFromNode(IntervalNode const* node) {
+ IntervalNode const* left = node->Left();
+ IntervalNode const* right = node->Right();
+
+ T observed_min_value(node->Data().Low());
+ T observed_max_value(node->Data().High());
+
if (left) {
- if (!CheckInvariantsFromNode(left, &left_max_value))
+ // Ensure left branch is entirely valid
+ if (!CheckInvariantsFromNode(left)) {
+ return false;
+ }
+ // Ensure that this node's MinLow is equal to MinLow of the left branch
+ if (!(left->Data().MinLow() == node->Data().MinLow())) {
+ LogVerificationFailedAtNode(node);
return false;
+ }
+ // Ensure that this node's MaxHigh is at least MaxHigh of left branch
+ if (node->Data().MaxHigh() < left->Data().MaxHigh()) {
+ LogVerificationFailedAtNode(node);
+ return false;
+ }
+
+ observed_min_value = left->Data().MinLow();
+ observed_max_value = std::max(observed_max_value, left->Data().MaxHigh());
}
+
if (right) {
- if (!CheckInvariantsFromNode(right, &right_max_value))
+ // Ensure right branch is entirely valid
+ if (!CheckInvariantsFromNode(right)) {
return false;
+ }
+ // Ensure this node's MinLow is not greater than the right node's MinLow
+ if (right->Data().MinLow() < node->Data().MinLow()) {
+ LogVerificationFailedAtNode(node);
+ return false;
+ }
+ // Ensure that this node's MaxHigh is at least MaxHigh of right branch
+ if (node->Data().MaxHigh() < right->Data().MaxHigh()) {
+ LogVerificationFailedAtNode(node);
+ return false;
+ }
+
+ observed_max_value =
+ std::max(observed_max_value, right->Data().MaxHigh());
}
- if (!left && !right) {
- // Base case.
- if (current_max_value)
- *current_max_value = node->Data().High();
- return (node->Data().High() == node->Data().MaxHigh());
- }
- T local_max_value(node->Data().MaxHigh());
- if (!left || !right) {
- if (left)
- local_max_value = left_max_value;
- else
- local_max_value = right_max_value;
- } else {
- local_max_value =
- (left_max_value < right_max_value) ? right_max_value : left_max_value;
+
+ // Ensure this node's MinLow is the min we actually observed
+ if (!(observed_min_value == node->Data().MinLow())) {
+ LogVerificationFailedAtNode(node);
+ return false;
}
- if (local_max_value < node->Data().High())
- local_max_value = node->Data().High();
- if (!(local_max_value == node->Data().MaxHigh())) {
-#ifndef NDEBUG
- String local_max_value_string =
- ValueToString<T>::ToString(local_max_value);
- DLOG(ERROR) << "PODIntervalTree verification failed at node " << node
- << ": localMaxValue=" << local_max_value_string
- << " and data=" << node->Data().ToString();
-#endif
+ // Ensure that this node's MaxHigh is the max we actually observed
+ if (!(observed_max_value == node->Data().MaxHigh())) {
+ LogVerificationFailedAtNode(node);
return false;
}
- if (current_max_value)
- *current_max_value = local_max_value;
+
return true;
}
+#ifndef NDEBUG
+ static void LogVerificationFailedAtNode(IntervalNode const* node) {
+ DLOG(ERROR) << "PODIntervalTree verification failed at node " << node
+ << ": data=" << node->Data().ToString();
+ }
+#else
+ static void LogVerificationFailedAtNode(IntervalNode const*) {}
+#endif
+
DISALLOW_COPY_AND_ASSIGN(PODIntervalTree);
};
diff --git a/chromium/third_party/blink/renderer/platform/wtf/pod_interval_tree_test.cc b/chromium/third_party/blink/renderer/platform/wtf/pod_interval_tree_test.cc
index ad4ffa6f016..cdf01a2b602 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/pod_interval_tree_test.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/pod_interval_tree_test.cc
@@ -57,11 +57,26 @@ TEST(PODIntervalTreeTest, TestInsertionAndQuery) {
PODIntervalTree<float> tree;
tree.Add(PODInterval<float>(2, 4));
ASSERT_TRUE(tree.CheckInvariants());
- Vector<PODInterval<float>> result =
+ Vector<PODInterval<float>> overlap =
tree.AllOverlaps(PODInterval<float>(1, 3));
- EXPECT_EQ(1U, result.size());
- EXPECT_EQ(2, result[0].Low());
- EXPECT_EQ(4, result[0].High());
+ EXPECT_EQ(1U, overlap.size());
+ EXPECT_EQ(2, overlap[0].Low());
+ EXPECT_EQ(4, overlap[0].High());
+
+ auto next_point = tree.NextIntervalPoint(1);
+ EXPECT_TRUE(next_point.has_value());
+ EXPECT_EQ(2, next_point.value());
+
+ next_point = tree.NextIntervalPoint(2);
+ EXPECT_TRUE(next_point.has_value());
+ EXPECT_EQ(4, next_point.value());
+
+ next_point = tree.NextIntervalPoint(3);
+ EXPECT_TRUE(next_point.has_value());
+ EXPECT_EQ(4, next_point.value());
+
+ next_point = tree.NextIntervalPoint(4);
+ EXPECT_FALSE(next_point.has_value());
}
TEST(PODIntervalTreeTest, TestQueryAgainstZeroSizeInterval) {
@@ -214,7 +229,7 @@ void TreeInsertionAndDeletionTest(int32_t seed, int tree_size) {
tree.Add(interval);
#ifdef DEBUG_INSERTION_AND_DELETION_TEST
DLOG(ERROR) << "*** Adding element "
- << ValueToString<PODInterval<int>>::string(interval);
+ << ValueToString<PODInterval<int>>::ToString(interval);
#endif
added_elements.push_back(interval);
}
@@ -224,8 +239,8 @@ void TreeInsertionAndDeletionTest(int32_t seed, int tree_size) {
int index = NextRandom(added_elements.size());
#ifdef DEBUG_INSERTION_AND_DELETION_TEST
DLOG(ERROR) << "*** Removing element "
- << ValueToString<PODInterval<int>>::string(
- addedElements[index]);
+ << ValueToString<PODInterval<int>>::ToString(
+ added_elements[index]);
#endif
ASSERT_TRUE(tree.Contains(added_elements[index]))
<< "Test failed for seed " << seed;
@@ -247,8 +262,8 @@ void TreeInsertionAndDeletionTest(int32_t seed, int tree_size) {
int index = NextRandom(removed_elements.size());
#ifdef DEBUG_INSERTION_AND_DELETION_TEST
DLOG(ERROR) << "*** Adding element "
- << ValueToString<PODInterval<int>>::string(
- removedElements[index]);
+ << ValueToString<PODInterval<int>>::ToString(
+ removed_elements[index]);
#endif
tree.Add(removed_elements[index]);
added_elements.push_back(removed_elements[index]);
@@ -257,8 +272,8 @@ void TreeInsertionAndDeletionTest(int32_t seed, int tree_size) {
int index = NextRandom(added_elements.size());
#ifdef DEBUG_INSERTION_AND_DELETION_TEST
DLOG(ERROR) << "*** Removing element "
- << ValueToString<PODInterval<int>>::string(
- addedElements[index]);
+ << ValueToString<PODInterval<int>>::ToString(
+ added_elements[index]);
#endif
ASSERT_TRUE(tree.Contains(added_elements[index]))
<< "Test failed for seed " << seed;
diff --git a/chromium/third_party/blink/renderer/platform/wtf/pod_red_black_tree.h b/chromium/third_party/blink/renderer/platform/wtf/pod_red_black_tree.h
index 2ba83d373e1..d4b7a8a6b9c 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/pod_red_black_tree.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/pod_red_black_tree.h
@@ -256,6 +256,7 @@ class PODRedBlackTree {
// Fetches the user data.
T& Data() { return data_; }
+ T const& Data() const { return data_; }
// Copies all user-level fields from the source node, but not
// internal fields. For example, the base implementation of this
@@ -265,13 +266,16 @@ class PODRedBlackTree {
// superclass implementation.
virtual void CopyFrom(Node* src) { data_ = src->Data(); }
- Node* Left() const { return left_; }
+ Node* Left() { return left_; }
+ Node const* Left() const { return left_; }
void SetLeft(Node* node) { left_ = node; }
- Node* Right() const { return right_; }
+ Node const* Right() const { return right_; }
+ Node* Right() { return right_; }
void SetRight(Node* node) { right_ = node; }
- Node* Parent() const { return parent_; }
+ Node const* Parent() const { return parent_; }
+ Node* Parent() { return parent_; }
void SetParent(Node* node) { parent_ = node; }
private:
diff --git a/chromium/third_party/blink/renderer/platform/wtf/sanitizers.h b/chromium/third_party/blink/renderer/platform/wtf/sanitizers.h
index 847424195f8..1916939fb30 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/sanitizers.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/sanitizers.h
@@ -11,12 +11,36 @@
#define ASAN_REGION_IS_POISONED(addr, size) \
__asan_region_is_poisoned(addr, size)
#define NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
+class AsanUnpoisonScope {
+ public:
+ AsanUnpoisonScope(const void* addr, size_t size)
+ : addr_(addr), size_(size), was_poisoned_(false) {
+ if (!ASAN_REGION_IS_POISONED(const_cast<void*>(addr_), size_))
+ return;
+ ASAN_UNPOISON_MEMORY_REGION(addr_, size_);
+ was_poisoned_ = true;
+ }
+ ~AsanUnpoisonScope() {
+ if (was_poisoned_)
+ ASAN_POISON_MEMORY_REGION(addr_, size_);
+ }
+
+ private:
+ const void* addr_;
+ size_t size_;
+ bool was_poisoned_;
+};
#else
#define ASAN_POISON_MEMORY_REGION(addr, size) ((void)(addr), (void)(size))
#define ASAN_UNPOISON_MEMORY_REGION(addr, size) ((void)(addr), (void)(size))
#define ASAN_REGION_IS_POISONED(addr, size) \
((void)(addr), (void)(size), (void*)nullptr)
#define NO_SANITIZE_ADDRESS
+class AsanUnpoisonScope {
+ public:
+ AsanUnpoisonScope(const void*, size_t) {}
+ ~AsanUnpoisonScope() {}
+};
#endif
#if defined(LEAK_SANITIZER)
diff --git a/chromium/third_party/blink/renderer/platform/wtf/shared_buffer.cc b/chromium/third_party/blink/renderer/platform/wtf/shared_buffer.cc
index 9d3eb78f42a..cb8c3f8ad3b 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/shared_buffer.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/shared_buffer.cc
@@ -28,6 +28,7 @@
#include <memory>
+#include "base/numerics/safe_conversions.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/text/unicode.h"
#include "third_party/blink/renderer/platform/wtf/text/utf8.h"
@@ -171,7 +172,8 @@ SharedBuffer::Iterator SharedBuffer::end() const {
}
void SharedBuffer::MergeSegmentsIntoBuffer() {
- wtf_size_t bytes_left = size_ - buffer_.size();
+ wtf_size_t bytes_left =
+ base::checked_cast<wtf_size_t>(size_ - buffer_.size());
for (const auto& segment : segments_) {
wtf_size_t bytes_to_copy = std::min<wtf_size_t>(bytes_left, kSegmentSize);
buffer_.Append(segment.get(), bytes_to_copy);
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 b2421649ff3..1aaaa1c60d2 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/stack_util.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/stack_util.cc
@@ -24,12 +24,11 @@ size_t GetUnderestimatedStackSize() {
// and its size is different from the value which APIs tells us.
#if defined(ADDRESS_SANITIZER)
return 0;
-#endif
// FIXME: On Mac OSX and Linux, this method cannot estimate stack size
// correctly for the main thread.
-#if defined(__GLIBC__) || defined(OS_ANDROID) || defined(OS_FREEBSD) || \
+#elif defined(__GLIBC__) || defined(OS_ANDROID) || defined(OS_FREEBSD) || \
defined(OS_FUCHSIA)
// pthread_getattr_np() can fail if the thread is not invoked by
// pthread_create() (e.g., the main thread of blink_unittests).
diff --git a/chromium/third_party/blink/renderer/platform/wtf/testing/run_all_tests.cc b/chromium/third_party/blink/renderer/platform/wtf/testing/run_all_tests.cc
index 5a8c45de8a1..4a54c7d144f 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/testing/run_all_tests.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/testing/run_all_tests.cc
@@ -35,6 +35,6 @@
int main(int argc, char** argv) {
WTF::Partitions::Initialize();
- WTF::Initialize(nullptr);
+ WTF::Initialize();
return base::RunUnitTestsUsingBaseTestSuite(argc, argv);
}
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/string_builder.h b/chromium/third_party/blink/renderer/platform/wtf/text/string_builder.h
index a853cc40e4d..1af520552af 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/string_builder.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/string_builder.h
@@ -160,6 +160,14 @@ class WTF_EXPORT StringBuilder {
AtomicString ToAtomicString();
String Substring(unsigned start, unsigned length) const;
+ operator StringView() const {
+ if (Is8Bit()) {
+ return StringView(Characters8(), length());
+ } else {
+ return StringView(Characters16(), length());
+ }
+ }
+
unsigned length() const { return length_; }
bool IsEmpty() const { return !length_; }
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 2e992dfac85..a02a45ef137 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
@@ -701,6 +701,15 @@ wtf_size_t StringImpl::HexToUIntStrict(bool* ok) {
NumberParsingOptions::kStrict, ok);
}
+uint64_t StringImpl::HexToUInt64Strict(bool* ok) {
+ if (Is8Bit()) {
+ return HexCharactersToUInt64(Characters8(), length_,
+ NumberParsingOptions::kStrict, ok);
+ }
+ return HexCharactersToUInt64(Characters16(), length_,
+ NumberParsingOptions::kStrict, ok);
+}
+
int64_t StringImpl::ToInt64(NumberParsingOptions options, bool* ok) const {
if (Is8Bit())
return CharactersToInt64(Characters8(), length_, options, ok);
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/string_impl.h b/chromium/third_party/blink/renderer/platform/wtf/text/string_impl.h
index 4228268fcf3..2083ac0ffe3 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/string_impl.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/string_impl.h
@@ -345,6 +345,7 @@ class WTF_EXPORT StringImpl {
uint64_t ToUInt64(NumberParsingOptions, bool* ok) const;
wtf_size_t HexToUIntStrict(bool* ok);
+ uint64_t HexToUInt64Strict(bool* ok);
// FIXME: Like NumberParsingOptions::kStrict, these give false for "ok" when
// there is trailing garbage. Like NumberParsingOptions::kLoose, these return
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/string_to_number.cc b/chromium/third_party/blink/renderer/platform/wtf/text/string_to_number.cc
index d00bd2605f6..d915df41740 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/string_to_number.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/string_to_number.cc
@@ -175,6 +175,20 @@ unsigned HexCharactersToUInt(const UChar* data,
return ToIntegralType<unsigned, UChar, 16>(data, length, options, ok);
}
+uint64_t HexCharactersToUInt64(const LChar* data,
+ size_t length,
+ NumberParsingOptions options,
+ bool* ok) {
+ return ToIntegralType<uint64_t, LChar, 16>(data, length, options, ok);
+}
+
+uint64_t HexCharactersToUInt64(const UChar* data,
+ size_t length,
+ NumberParsingOptions options,
+ bool* ok) {
+ return ToIntegralType<uint64_t, UChar, 16>(data, length, options, ok);
+}
+
int CharactersToInt(const LChar* data,
size_t length,
NumberParsingOptions options,
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/string_to_number.h b/chromium/third_party/blink/renderer/platform/wtf/text/string_to_number.h
index ae9fdedebe7..f6e78041261 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/string_to_number.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/string_to_number.h
@@ -40,6 +40,14 @@ WTF_EXPORT unsigned HexCharactersToUInt(const UChar*,
size_t,
NumberParsingOptions,
bool* ok);
+WTF_EXPORT uint64_t HexCharactersToUInt64(const UChar*,
+ size_t,
+ NumberParsingOptions,
+ bool* ok);
+WTF_EXPORT uint64_t HexCharactersToUInt64(const LChar*,
+ size_t,
+ NumberParsingOptions,
+ bool* ok);
WTF_EXPORT unsigned CharactersToUInt(const LChar*,
size_t,
NumberParsingOptions,
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 3d92473d79e..06611ab2a58 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
@@ -58,12 +58,12 @@ class WTF_EXPORT StringView {
StringView(StringImpl&, unsigned offset);
StringView(StringImpl&, unsigned offset, unsigned length);
- // From a String, implemented in String.h
+ // From a String, implemented in wtf_string.h
inline StringView(const String&, unsigned offset, unsigned length);
inline StringView(const String&, unsigned offset);
inline StringView(const String&);
- // From an AtomicString, implemented in AtomicString.h
+ // From an AtomicString, implemented in atomic_string.h
inline StringView(const AtomicString&, unsigned offset, unsigned length);
inline StringView(const AtomicString&, unsigned offset);
inline StringView(const AtomicString&);
@@ -253,6 +253,15 @@ WTF_EXPORT bool DeprecatedEqualIgnoringCaseAndNullity(const StringView&,
WTF_EXPORT bool EqualIgnoringASCIICase(const StringView&, const StringView&);
+template <size_t N>
+inline bool EqualIgnoringASCIICase(const StringView& a,
+ const char (&literal)[N]) {
+ if (a.length() != N - 1 || (N == 1 && a.IsNull()))
+ return false;
+ return a.Is8Bit() ? EqualIgnoringASCIICase(a.Characters8(), literal, N - 1)
+ : EqualIgnoringASCIICase(a.Characters16(), literal, N - 1);
+}
+
// TODO(esprehn): Can't make this an overload of WTF::equal since that makes
// calls to equal() that pass literal strings ambiguous. Figure out if we can
// replace all the callers with equalStringView and then rename it to equal().
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/string_view_test.cc b/chromium/third_party/blink/renderer/platform/wtf/text/string_view_test.cc
index 924e1d55a99..143fd2b7813 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/string_view_test.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/string_view_test.cc
@@ -460,4 +460,30 @@ TEST(StringViewTest, EqualIgnoringASCIICase) {
EXPECT_TRUE(EqualIgnoringASCIICase(StringView(""), ""));
}
+TEST(StringViewTest, DeprecatedEqualIgnoringCase) {
+ constexpr UChar kLongSAndKelvin[] = {0x017F, 0x212A, 0};
+ EXPECT_TRUE(DeprecatedEqualIgnoringCase("SK", kLongSAndKelvin));
+ EXPECT_TRUE(DeprecatedEqualIgnoringCase("sk", kLongSAndKelvin));
+
+ // Turkish-specific mappings are not applied.
+ constexpr UChar kSmallDotlessI[] = {0x0131, 0};
+ constexpr UChar kCapitalDotI[] = {0x0130, 0};
+ EXPECT_FALSE(DeprecatedEqualIgnoringCase("i", kSmallDotlessI));
+ EXPECT_FALSE(DeprecatedEqualIgnoringCase("i", kCapitalDotI));
+
+ // DeprecatedEqualIgnoringCase() has length-equality check.
+ constexpr UChar kSmallSharpS[] = {0x00DF, 0};
+ constexpr UChar kCapitalSharpS[] = {0x1E9E, 0};
+ EXPECT_FALSE(DeprecatedEqualIgnoringCase("ss", kSmallSharpS));
+ EXPECT_FALSE(DeprecatedEqualIgnoringCase("SS", kSmallSharpS));
+ EXPECT_FALSE(DeprecatedEqualIgnoringCase("ss", kCapitalSharpS));
+ EXPECT_FALSE(DeprecatedEqualIgnoringCase("SS", kCapitalSharpS));
+ constexpr UChar kLigatureFFI[] = {0xFB03, 0};
+ EXPECT_FALSE(DeprecatedEqualIgnoringCase("ffi", kLigatureFFI));
+
+ constexpr UChar kLigatureFFIAndSSSS[] = {0xFB03, 's', 's', 's', 's', 0};
+ constexpr UChar kFFIAndSharpSs[] = {'f', 'f', 'i', 0x00DF, 0x00DF, 0};
+ EXPECT_TRUE(DeprecatedEqualIgnoringCase(kLigatureFFIAndSSSS, kFFIAndSharpSs));
+}
+
} // 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 b6926170494..3d4f4108d57 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
@@ -82,7 +82,7 @@ class WTF_EXPORT TextCodec {
struct EncodeIntoResult {
wtf_size_t code_units_read;
- wtf_size_t bytes_written;
+ size_t bytes_written;
};
String Decode(const char* str,
@@ -108,14 +108,14 @@ class WTF_EXPORT TextCodec {
virtual EncodeIntoResult EncodeInto(const LChar*,
wtf_size_t length,
unsigned char* destination,
- wtf_size_t capacity) {
+ size_t capacity) {
NOTREACHED();
return EncodeIntoResult{0, 0};
}
virtual EncodeIntoResult EncodeInto(const UChar*,
wtf_size_t length,
unsigned char* destination,
- wtf_size_t capacity) {
+ size_t capacity) {
NOTREACHED();
return EncodeIntoResult{0, 0};
}
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/text_codec_utf8.cc b/chromium/third_party/blink/renderer/platform/wtf/text/text_codec_utf8.cc
index 6874eca2d10..71fc2ac2aae 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/text_codec_utf8.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/text_codec_utf8.cc
@@ -497,7 +497,7 @@ TextCodec::EncodeIntoResult TextCodecUTF8::EncodeIntoCommon(
const CharType* characters,
wtf_size_t length,
unsigned char* destination,
- wtf_size_t capacity) {
+ size_t capacity) {
TextCodec::EncodeIntoResult encode_into_result{0, 0};
wtf_size_t i = 0;
@@ -544,7 +544,7 @@ TextCodec::EncodeIntoResult TextCodecUTF8::EncodeInto(
const UChar* characters,
wtf_size_t length,
unsigned char* destination,
- wtf_size_t capacity) {
+ size_t capacity) {
return EncodeIntoCommon(characters, length, destination, capacity);
}
@@ -552,7 +552,7 @@ TextCodec::EncodeIntoResult TextCodecUTF8::EncodeInto(
const LChar* characters,
wtf_size_t length,
unsigned char* destination,
- wtf_size_t capacity) {
+ size_t capacity) {
return EncodeIntoCommon(characters, length, destination, capacity);
}
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/text_codec_utf8.h b/chromium/third_party/blink/renderer/platform/wtf/text/text_codec_utf8.h
index 688a40439b6..65806a9beb1 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/text_codec_utf8.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/text_codec_utf8.h
@@ -62,11 +62,11 @@ class TextCodecUTF8 : public TextCodec {
EncodeIntoResult EncodeInto(const UChar*,
wtf_size_t length,
unsigned char* destination,
- wtf_size_t capacity) override;
+ size_t capacity) override;
EncodeIntoResult EncodeInto(const LChar*,
wtf_size_t length,
unsigned char* destination,
- wtf_size_t capacity) override;
+ size_t capacity) override;
template <typename CharType>
std::string EncodeCommon(const CharType* characters, wtf_size_t length);
@@ -74,7 +74,7 @@ class TextCodecUTF8 : public TextCodec {
EncodeIntoResult EncodeIntoCommon(const CharType* characters,
wtf_size_t length,
unsigned char* destination,
- wtf_size_t capacity);
+ size_t capacity);
template <typename CharType>
bool HandlePartialSequence(CharType*& destination,
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/wtf_string.cc b/chromium/third_party/blink/renderer/platform/wtf/text/wtf_string.cc
index 5d7213c8503..c32a41c8f00 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/wtf_string.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/wtf_string.cc
@@ -295,6 +295,15 @@ unsigned String::HexToUIntStrict(bool* ok) const {
return impl_->HexToUIntStrict(ok);
}
+uint64_t String::HexToUInt64Strict(bool* ok) const {
+ if (!impl_) {
+ if (ok)
+ *ok = false;
+ return 0;
+ }
+ return impl_->HexToUInt64Strict(ok);
+}
+
int64_t String::ToInt64Strict(bool* ok) const {
if (!impl_) {
if (ok)
diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/wtf_string.h b/chromium/third_party/blink/renderer/platform/wtf/text/wtf_string.h
index df24384c5be..a50371b7b56 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/text/wtf_string.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/text/wtf_string.h
@@ -422,6 +422,7 @@ class WTF_EXPORT String {
int ToIntStrict(bool* ok = nullptr) const;
unsigned ToUIntStrict(bool* ok = nullptr) const;
unsigned HexToUIntStrict(bool* ok) const;
+ uint64_t HexToUInt64Strict(bool* ok) const;
int64_t ToInt64Strict(bool* ok = nullptr) const;
uint64_t ToUInt64Strict(bool* ok = nullptr) const;
diff --git a/chromium/third_party/blink/renderer/platform/wtf/threading.cc b/chromium/third_party/blink/renderer/platform/wtf/threading.cc
index 828eee6c27c..d6636df7991 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/threading.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/threading.cc
@@ -29,6 +29,10 @@ bool IsBeforeThreadCreated() {
void WillCreateThread() {
g_thread_created = true;
}
+
+void SetIsBeforeThreadCreatedForTest() {
+ g_thread_created = false;
+}
#endif
ThreadSpecific<Threading>* Threading::static_data_;
diff --git a/chromium/third_party/blink/renderer/platform/wtf/threading.h b/chromium/third_party/blink/renderer/platform/wtf/threading.h
index 197bfe06e53..0a21c3fb321 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/threading.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/threading.h
@@ -48,6 +48,7 @@ WTF_EXPORT base::PlatformThreadId CurrentThread();
#if DCHECK_IS_ON()
WTF_EXPORT bool IsBeforeThreadCreated();
WTF_EXPORT void WillCreateThread();
+WTF_EXPORT void SetIsBeforeThreadCreatedForTest();
#endif
class AtomicStringTable;
diff --git a/chromium/third_party/blink/renderer/platform/wtf/threading_primitives_test.cc b/chromium/third_party/blink/renderer/platform/wtf/threading_primitives_test.cc
index 6ce2b8bb560..2393e012756 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/threading_primitives_test.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/threading_primitives_test.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/scoped_blocking_call.h"
+#include "base/threading/scoped_blocking_call_internal.h"
#include "base/threading/thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/third_party/blink/renderer/platform/wtf/vector.h b/chromium/third_party/blink/renderer/platform/wtf/vector.h
index 1b321ec9462..632d30883c9 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/vector.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/vector.h
@@ -108,7 +108,7 @@ template <typename T>
struct VectorUnusedSlotClearer<true, T> {
STATIC_ONLY(VectorUnusedSlotClearer);
static void Clear(T* begin, T* end) {
- memset(reinterpret_cast<void*>(begin), 0, sizeof(T) * (end - begin));
+ AtomicMemzero(reinterpret_cast<void*>(begin), sizeof(T) * (end - begin));
}
#if DCHECK_IS_ON()
@@ -204,14 +204,40 @@ struct VectorMover<true, T, Allocator> {
Traits::NotifyNewElements(dst, src_end - src);
}
}
+
+ template <bool = Allocator::kIsGarbageCollected>
+ static void MoveOverlappingImpl(const T* src, const T* src_end, T* dst);
+ template <>
+ static void MoveOverlappingImpl<false>(const T* src,
+ const T* src_end,
+ T* dst) {
+ memmove(dst, src,
+ reinterpret_cast<const char*>(src_end) -
+ reinterpret_cast<const char*>(src));
+ }
+ template <>
+ static void MoveOverlappingImpl<true>(const T* src,
+ const T* src_end,
+ T* dst) {
+ if (src == dst)
+ return;
+ if (dst < src) {
+ for (; src < src_end; ++src, ++dst)
+ AtomicWriteMemcpy<sizeof(T)>(dst, src);
+ } else {
+ --src_end;
+ T* dst_end = dst + (src_end - src);
+ for (; src_end >= src; --src_end, --dst_end)
+ AtomicWriteMemcpy<sizeof(T)>(dst_end, src_end);
+ }
+ }
+
static void MoveOverlapping(const T* src,
const T* src_end,
T* dst,
bool has_inline_buffer) {
if (LIKELY(dst && src)) {
- memmove(dst, src,
- reinterpret_cast<const char*>(src_end) -
- reinterpret_cast<const char*>(src));
+ MoveOverlappingImpl(src, src_end, dst);
if (has_inline_buffer)
Traits::NotifyNewElements(dst, src_end - src);
}
@@ -407,13 +433,15 @@ class VectorBufferBase {
DCHECK_LE(new_capacity,
Allocator::template MaxElementCountInBackingStore<T>());
size_t size_to_allocate = AllocationSize(new_capacity);
- buffer_ = Allocator::template AllocateVectorBacking<T>(size_to_allocate);
+ AsAtomicPtr(&buffer_)->store(
+ Allocator::template AllocateVectorBacking<T>(size_to_allocate),
+ std::memory_order_relaxed);
capacity_ = static_cast<wtf_size_t>(size_to_allocate / sizeof(T));
}
void AllocateBuffer(wtf_size_t new_capacity) {
AllocateBufferNoBarrier(new_capacity);
- Allocator::BackingWriteBarrier(buffer_);
+ Allocator::BackingWriteBarrier(&buffer_);
}
size_t AllocationSize(size_t capacity) const {
@@ -446,7 +474,7 @@ class VectorBufferBase {
}
void MoveBufferInto(VectorBufferBase& other) {
- other.buffer_ = buffer_;
+ AsAtomicPtr(&other.buffer_)->store(buffer_, std::memory_order_relaxed);
other.capacity_ = capacity_;
}
@@ -481,6 +509,10 @@ class VectorBufferBase {
return buffer_ == reinterpret_cast<T*>(-1);
}
+ const T* BufferSafe() const {
+ return AsAtomicPtr(&buffer_)->load(std::memory_order_relaxed);
+ }
+
T* buffer_;
wtf_size_t capacity_;
wtf_size_t size_;
@@ -540,7 +572,7 @@ class VectorBuffer<T, 0, Allocator> : protected VectorBufferBase<T, Allocator> {
}
void ResetBufferPointer() {
- buffer_ = nullptr;
+ AsAtomicPtr(&buffer_)->store(nullptr, std::memory_order_relaxed);
capacity_ = 0;
}
@@ -551,11 +583,11 @@ class VectorBuffer<T, 0, Allocator> : protected VectorBufferBase<T, Allocator> {
OffsetRange other_hole) {
static_assert(VectorTraits<T>::kCanSwapUsingCopyOrMove,
"Cannot swap using copy or move.");
- std::swap(buffer_, other.buffer_);
+ AtomicWriteSwap(buffer_, other.buffer_);
std::swap(capacity_, other.capacity_);
std::swap(size_, other.size_);
- Allocator::BackingWriteBarrier(buffer_);
- Allocator::BackingWriteBarrier(other.buffer_);
+ Allocator::BackingWriteBarrier(&buffer_);
+ Allocator::BackingWriteBarrier(&other.buffer_);
}
using Base::AllocateBuffer;
@@ -570,14 +602,19 @@ class VectorBuffer<T, 0, Allocator> : protected VectorBufferBase<T, Allocator> {
bool HasOutOfLineBuffer() const {
// When inlineCapacity is 0 we have an out of line buffer if we have a
// buffer.
- return Buffer();
+ return IsOutOfLineBuffer(Buffer());
}
T** BufferSlot() { return &buffer_; }
+ const T* const* BufferSlot() const { return &buffer_; }
protected:
+ using Base::BufferSafe;
+
using Base::size_;
+ bool IsOutOfLineBuffer(const T* buffer) const { return buffer; }
+
private:
using Base::buffer_;
using Base::capacity_;
@@ -648,7 +685,7 @@ class VectorBuffer : protected VectorBufferBase<T, Allocator> {
}
void ResetBufferPointer() {
- buffer_ = InlineBuffer();
+ AsAtomicPtr(&buffer_)->store(InlineBuffer(), std::memory_order_relaxed);
capacity_ = inlineCapacity;
}
@@ -694,8 +731,8 @@ class VectorBuffer : protected VectorBufferBase<T, Allocator> {
std::swap(buffer_, other.buffer_);
std::swap(capacity_, other.capacity_);
std::swap(size_, other.size_);
- Allocator::BackingWriteBarrier(buffer_);
- Allocator::BackingWriteBarrier(other.buffer_);
+ Allocator::BackingWriteBarrier(&buffer_);
+ Allocator::BackingWriteBarrier(&other.buffer_);
return;
}
@@ -756,7 +793,7 @@ class VectorBuffer : protected VectorBufferBase<T, Allocator> {
other.buffer_ = other.InlineBuffer();
std::swap(size_, other.size_);
ANNOTATE_NEW_BUFFER(other.buffer_, inlineCapacity, other.size_);
- Allocator::BackingWriteBarrier(buffer_);
+ Allocator::BackingWriteBarrier(&buffer_);
} else if (!this_source_begin &&
other_source_begin) { // Their buffer is inline, ours is not.
DCHECK_NE(Buffer(), InlineBuffer());
@@ -766,7 +803,7 @@ class VectorBuffer : protected VectorBufferBase<T, Allocator> {
buffer_ = InlineBuffer();
std::swap(size_, other.size_);
ANNOTATE_NEW_BUFFER(buffer_, inlineCapacity, size_);
- Allocator::BackingWriteBarrier(other.buffer_);
+ Allocator::BackingWriteBarrier(&other.buffer_);
} else { // Both buffers are inline.
DCHECK(this_source_begin);
DCHECK(other_source_begin);
@@ -850,15 +887,20 @@ class VectorBuffer : protected VectorBufferBase<T, Allocator> {
using Base::Buffer;
using Base::capacity;
- bool HasOutOfLineBuffer() const {
- return Buffer() && Buffer() != InlineBuffer();
- }
+ bool HasOutOfLineBuffer() const { return IsOutOfLineBuffer(Buffer()); }
T** BufferSlot() { return &buffer_; }
+ const T* const* BufferSlot() const { return &buffer_; }
protected:
+ using Base::BufferSafe;
+
using Base::size_;
+ bool IsOutOfLineBuffer(const T* buffer) const {
+ return buffer && buffer != InlineBuffer();
+ }
+
private:
using Base::buffer_;
using Base::capacity_;
@@ -1237,6 +1279,9 @@ class Vector
void EraseAt(wtf_size_t position);
void EraseAt(wtf_size_t position, wtf_size_t length);
iterator erase(iterator position);
+ iterator erase(iterator first, iterator last);
+ // This is to prevent compilation of deprecated calls like 'vector.erase(0)'.
+ void erase(std::nullptr_t) = delete;
// Remove the last element. Unlike remove(), (1) this function is fast, and
// (2) only iterators pointing to the last element will be invalidated. Other
@@ -1254,8 +1299,15 @@ class Vector
// or copy-initialize all the elements.
//
// Fill(value) is a synonym for Fill(value, size()).
- void Fill(const T&, wtf_size_t);
- void Fill(const T& val) { Fill(val, size()); }
+ //
+ // The implementation of Fill uses std::fill which is not yet supported for
+ // garbage collected vectors.
+ template <typename A = Allocator>
+ std::enable_if_t<!A::kIsGarbageCollected> Fill(const T&, wtf_size_t);
+ template <typename A = Allocator>
+ std::enable_if_t<!A::kIsGarbageCollected> Fill(const T& val) {
+ Fill(val, size());
+ }
// Swap two vectors quickly.
void swap(Vector& other) {
@@ -1291,7 +1343,7 @@ class Vector
}
template <typename VisitorDispatcher, typename A = Allocator>
- std::enable_if_t<A::kIsGarbageCollected> Trace(VisitorDispatcher);
+ std::enable_if_t<A::kIsGarbageCollected> Trace(VisitorDispatcher) const;
class GCForbiddenScope {
STACK_ALLOCATED();
@@ -1306,6 +1358,7 @@ class Vector
using Base::ClearUnusedSlots;
T** GetBufferSlot() { return Base::BufferSlot(); }
+ const T* const* GetBufferSlot() const { return Base::BufferSlot(); }
private:
void ExpandCapacity(wtf_size_t new_min_capacity);
@@ -1326,14 +1379,12 @@ class Vector
void ReallocateBuffer(wtf_size_t);
- // This is to prevent compilation of deprecated calls like 'vector.erase(0)'.
- void erase(std::nullptr_t) = delete;
-
- using Base::size_;
- using Base::Buffer;
- using Base::SwapVectorBuffer;
using Base::AllocateBuffer;
using Base::AllocationSize;
+ using Base::Buffer;
+ using Base::BufferSafe;
+ using Base::size_;
+ using Base::SwapVectorBuffer;
};
//
@@ -1550,8 +1601,9 @@ wtf_size_t Vector<T, inlineCapacity, Allocator>::ReverseFind(
}
template <typename T, wtf_size_t inlineCapacity, typename Allocator>
-void Vector<T, inlineCapacity, Allocator>::Fill(const T& val,
- wtf_size_t new_size) {
+template <typename A>
+std::enable_if_t<!A::kIsGarbageCollected>
+Vector<T, inlineCapacity, Allocator>::Fill(const T& val, wtf_size_t new_size) {
if (size() > new_size) {
Shrink(new_size);
} else if (new_size > capacity()) {
@@ -1922,6 +1974,17 @@ inline auto Vector<T, inlineCapacity, Allocator>::erase(iterator position)
}
template <typename T, wtf_size_t inlineCapacity, typename Allocator>
+inline auto Vector<T, inlineCapacity, Allocator>::erase(iterator first,
+ iterator last)
+ -> iterator {
+ DCHECK_LE(first, last);
+ const wtf_size_t index = static_cast<wtf_size_t>(first - begin());
+ const wtf_size_t diff = std::distance(first, last);
+ EraseAt(index, diff);
+ return begin() + index;
+}
+
+template <typename T, wtf_size_t inlineCapacity, typename Allocator>
inline void Vector<T, inlineCapacity, Allocator>::EraseAt(wtf_size_t position,
wtf_size_t length) {
SECURITY_DCHECK(position <= size());
@@ -1976,29 +2039,37 @@ inline bool operator!=(const Vector<T, inlineCapacityA, Allocator>& a,
template <typename T, wtf_size_t inlineCapacity, typename Allocator>
template <typename VisitorDispatcher, typename A>
std::enable_if_t<A::kIsGarbageCollected>
-Vector<T, inlineCapacity, Allocator>::Trace(VisitorDispatcher visitor) {
+Vector<T, inlineCapacity, Allocator>::Trace(VisitorDispatcher visitor) const {
+ // Bail out for concurrent marking.
+ if (visitor->ConcurrentTracingBailOut(
+ {this, [](blink::Visitor* visitor, const void* object) {
+ reinterpret_cast<const Vector<T, inlineCapacity, Allocator>*>(
+ object)
+ ->Trace(visitor);
+ }}))
+ return;
+
static_assert(Allocator::kIsGarbageCollected,
"Garbage collector must be enabled.");
- if (this->HasOutOfLineBuffer()) {
- Allocator::TraceVectorBacking(visitor, Buffer(), Base::BufferSlot());
+ const T* buffer = BufferSafe();
+ if (Base::IsOutOfLineBuffer(buffer)) {
+ Allocator::TraceVectorBacking(visitor, buffer, Base::BufferSlot());
} else {
// We should not visit inline buffers, but we still need to register the
// slot for heap compaction. So, we pass nullptr to this method.
Allocator::TraceVectorBacking(visitor, static_cast<T*>(nullptr),
Base::BufferSlot());
- if (!Buffer())
+ if (!buffer)
return;
// Inline buffer requires tracing immediately.
- const T* buffer_begin = Buffer();
- const T* buffer_end = Buffer() + size();
+ const T* buffer_begin = buffer;
+ const T* buffer_end = buffer + size();
if (IsTraceableInCollectionTrait<VectorTraits<T>>::value) {
for (const T* buffer_entry = buffer_begin; buffer_entry != buffer_end;
buffer_entry++) {
- Allocator::template Trace<T, VectorTraits<T>>(
- visitor, *const_cast<T*>(buffer_entry));
+ Allocator::template Trace<T, VectorTraits<T>>(visitor, *buffer_entry);
}
- CheckUnusedSlots(Buffer() + size(), Buffer() + capacity());
}
}
}
@@ -2035,7 +2106,7 @@ void Vector<T, inlineCapacity, Allocator>::ReallocateBuffer(
ANNOTATE_DELETE_BUFFER(begin(), capacity(), size_);
Base::DeallocateBuffer(begin());
buffer.MoveBufferInto(*this);
- Allocator::BackingWriteBarrier(begin());
+ Allocator::BackingWriteBarrier(Base::BufferSlot());
}
} // namespace WTF
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
new file mode 100644
index 00000000000..60383b8ac53
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/wtf/vector_backed_linked_list.h
@@ -0,0 +1,597 @@
+// 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_VECTOR_BACKED_LINKED_LIST_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_VECTOR_BACKED_LINKED_LIST_H_
+
+#include "base/macros.h"
+#include "third_party/blink/renderer/platform/wtf/allocator/partition_allocator.h"
+#include "third_party/blink/renderer/platform/wtf/hash_traits.h"
+#include "third_party/blink/renderer/platform/wtf/sanitizers.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace WTF {
+
+template <typename VectorBackedLinkedListType>
+class VectorBackedLinkedListIterator;
+template <typename VectorBackedLinkedListType>
+class VectorBackedLinkedListConstIterator;
+template <typename VectorBackedLinkedListType>
+class VectorBackedLinkedListReverseIterator;
+template <typename VectorBackedLinkedListType>
+class VectorBackedLinkedListConstReverseIterator;
+
+template <typename ValueType, typename Allocator>
+class VectorBackedLinkedListNode {
+ USE_ALLOCATOR(VectorBackedLinkedListNode, Allocator);
+
+ public:
+ VectorBackedLinkedListNode() = delete;
+
+ VectorBackedLinkedListNode(wtf_size_t prev_index, wtf_size_t next_index)
+ : prev_index_(prev_index), next_index_(next_index) {}
+
+ VectorBackedLinkedListNode(wtf_size_t prev_index,
+ wtf_size_t next_index,
+ const ValueType& value)
+ : prev_index_(prev_index), next_index_(next_index), value_(value) {}
+
+ VectorBackedLinkedListNode(wtf_size_t prev_index,
+ wtf_size_t next_index,
+ ValueType&& value)
+ : prev_index_(prev_index),
+ next_index_(next_index),
+ value_(std::move(value)) {}
+
+ VectorBackedLinkedListNode(const VectorBackedLinkedListNode& other) = default;
+ VectorBackedLinkedListNode(VectorBackedLinkedListNode&& other) = default;
+ VectorBackedLinkedListNode& operator=(
+ const VectorBackedLinkedListNode& other) = default;
+ VectorBackedLinkedListNode& operator=(VectorBackedLinkedListNode&& other) =
+ default;
+
+ template <typename VisitorDispathcer, typename A = Allocator>
+ std::enable_if_t<A::kIsGarbageCollected> Trace(VisitorDispathcer visitor) {
+ visitor->Trace(value_);
+ }
+
+ // Those indices can be initialized with |kNotFound| (not with 0), since
+ // VectorBackedLinkedList won't be initialized with memset.
+ wtf_size_t prev_index_ = kNotFound;
+ wtf_size_t next_index_ = kNotFound;
+ ValueType value_ = HashTraits<ValueType>::EmptyValue();
+};
+
+template <typename ValueType, typename Allocator>
+struct VectorTraits<VectorBackedLinkedListNode<ValueType, Allocator>>
+ : VectorTraitsBase<VectorBackedLinkedListNode<ValueType, Allocator>> {
+ STATIC_ONLY(VectorTraits);
+
+ static const bool kNeedsDestruction =
+ VectorTraits<ValueType>::kNeedsDestruction;
+ // VectorBackedLinkedList can't be initialized with memset, because we use
+ // kNotFound as sentinel value.
+ static const bool kCanInitializeWithMemset = false;
+ static const bool kCanClearUnusedSlotsWithMemset =
+ VectorTraits<ValueType>::kCanClearUnusedSlotsWithMemset;
+ static const bool kCanCopyWithMemcpy =
+ VectorTraits<ValueType>::kCanCopyWithMemcpy;
+ static const bool kCanMoveWithMemcpy =
+ VectorTraits<ValueType>::kCanMoveWithMemcpy;
+
+ // Needs to be shadowing because |VectorTraitsBase::IsDeletedValue| uses call
+ // by value, which means we need to define copy constructor of
+ // |VectorBackedLinkedList|. We can remove this function if we change
+ // |VectorTraitsBase::IsDeletedValue| to use call by reference.
+ static bool IsDeletedValue(
+ const VectorBackedLinkedListNode<ValueType, Allocator>& node) {
+ NOTREACHED();
+ return false;
+ }
+};
+
+// VectorBackedLinkedList maintains a linked list through its contents such that
+// iterating it yields values in the order in which they were inserted.
+// The linked list is implementing in a vector (with links being indexes instead
+// of pointers), to simplify the move of backing during GC compaction.
+template <typename ValueType, typename Allocator = PartitionAllocator>
+class VectorBackedLinkedList {
+ USE_ALLOCATOR(VectorBackedLinkedList, Allocator);
+
+ private:
+ using Node = VectorBackedLinkedListNode<ValueType, Allocator>;
+ using VectorType = Vector<Node, 0, Allocator>;
+
+ public:
+ using Value = ValueType;
+ using iterator = VectorBackedLinkedListIterator<VectorBackedLinkedList>;
+ using const_iterator =
+ VectorBackedLinkedListConstIterator<VectorBackedLinkedList>;
+ friend class VectorBackedLinkedListConstIterator<VectorBackedLinkedList>;
+ using reverse_iterator =
+ VectorBackedLinkedListReverseIterator<VectorBackedLinkedList>;
+ using const_reverse_iterator =
+ VectorBackedLinkedListConstReverseIterator<VectorBackedLinkedList>;
+
+ VectorBackedLinkedList();
+
+ VectorBackedLinkedList(const VectorBackedLinkedList&) = default;
+ VectorBackedLinkedList(VectorBackedLinkedList&&) = default;
+ VectorBackedLinkedList& operator=(const VectorBackedLinkedList&) = default;
+ VectorBackedLinkedList& operator=(VectorBackedLinkedList&&) = default;
+
+ ~VectorBackedLinkedList() = default;
+
+ void swap(VectorBackedLinkedList&);
+
+ bool empty() const { return size_ == 0; }
+ wtf_size_t size() const { return size_; }
+
+ iterator begin() { return MakeIterator(UsedFirstIndex()); }
+ const_iterator begin() const { return MakeConstIterator(UsedFirstIndex()); }
+ const_iterator cbegin() const { return MakeConstIterator(UsedFirstIndex()); }
+ iterator end() { return MakeIterator(anchor_index_); }
+ const_iterator end() const { return MakeConstIterator(anchor_index_); }
+ const_iterator cend() const { return MakeConstIterator(anchor_index_); }
+ reverse_iterator rbegin() { return MakeReverseIterator(UsedLastIndex()); }
+ const_reverse_iterator rbegin() const {
+ return MakeConstReverseIterator(UsedLastIndex());
+ }
+ const_reverse_iterator crbegin() const {
+ return MakeConstReverseIterator(UsedLastIndex());
+ }
+ reverse_iterator rend() { return MakeReverseIterator(anchor_index_); }
+ const_reverse_iterator rend() const {
+ return MakeConstReverseIterator(anchor_index_);
+ }
+ const_reverse_iterator crend() const {
+ return MakeConstReverseIterator(anchor_index_);
+ }
+
+ Value& front();
+ const Value& front() const;
+ Value& back();
+ const Value& back() const;
+
+ template <typename IncomingValueType>
+ iterator insert(const_iterator position, IncomingValueType&& value);
+
+ template <typename IncomingValueType>
+ void push_front(IncomingValueType&& value) {
+ insert(cbegin(), std::forward<IncomingValueType>(value));
+ }
+
+ template <typename IncomingValueType>
+ void push_back(IncomingValueType&& value) {
+ insert(cend(), std::forward<IncomingValueType>(value));
+ }
+
+ // Moves |target| right before |new_position| in a linked list. This operation
+ // is executed by just updating indices of related nodes.
+ iterator MoveTo(const_iterator target, const_iterator new_position);
+
+ iterator erase(const_iterator);
+
+ void pop_front() {
+ DCHECK(!empty());
+ erase(cbegin());
+ }
+ void pop_back() {
+ DCHECK(!empty());
+ erase(--cend());
+ }
+
+ // Removes all elements in a linked list.
+ void clear() {
+ RegisterModification();
+ nodes_.clear();
+ // Reinserts anchor so that we can insert elements after this operation.
+ nodes_.push_back(Node(anchor_index_, anchor_index_));
+ free_head_index_ = anchor_index_;
+ size_ = 0;
+ }
+
+ template <typename VisitorDispatcher, typename A = Allocator>
+ std::enable_if_t<A::kIsGarbageCollected> Trace(VisitorDispatcher visitor) {
+ nodes_.Trace(visitor);
+ }
+
+#if DCHECK_IS_ON()
+ int64_t Modifications() const { return modifications_; }
+ void RegisterModification() { modifications_++; }
+ void CheckModifications(int64_t mods) const {
+ // VectorBackedLinkedList iterators get invalidated when the container is
+ // modified.
+ DCHECK_EQ(mods, modifications_);
+ }
+#else
+ ALWAYS_INLINE int64_t Modifications() const { return 0; }
+ ALWAYS_INLINE void RegisterModification() {}
+ ALWAYS_INLINE void CheckModifications() const {}
+#endif
+
+ private:
+ bool IsFreeListEmpty() const { return free_head_index_ == anchor_index_; }
+
+ wtf_size_t UsedFirstIndex() const {
+ return nodes_[anchor_index_].next_index_;
+ }
+ wtf_size_t UsedLastIndex() const { return nodes_[anchor_index_].prev_index_; }
+
+ iterator MakeIterator(wtf_size_t index) { return iterator(index, this); }
+ const_iterator MakeConstIterator(wtf_size_t index) const {
+ return const_iterator(index, this);
+ }
+ reverse_iterator MakeReverseIterator(wtf_size_t index) {
+ return reverse_iterator(index, this);
+ }
+ const_reverse_iterator MakeConstReverseIterator(wtf_size_t index) const {
+ return const_reverse_iterator(index, this);
+ }
+
+ bool IsIndexValid(wtf_size_t index) const {
+ return 0 <= index && index < nodes_.size();
+ }
+
+ bool IsAnchor(wtf_size_t index) const { return index == anchor_index_; }
+
+ void Unlink(const Node&);
+
+ VectorType nodes_;
+ static constexpr wtf_size_t anchor_index_ = 0;
+ // Anchor is not included in the free list, but it serves as the list's
+ // terminator.
+ wtf_size_t free_head_index_ = anchor_index_;
+ wtf_size_t size_ = 0;
+#if DCHECK_IS_ON()
+ int64_t modifications_ = 0;
+#endif
+
+ template <typename T, typename U>
+ friend class NewLinkedHashSet;
+};
+
+template <typename VectorBackedLinkedListType>
+class VectorBackedLinkedListIterator {
+ DISALLOW_NEW();
+ using ReferenceType = typename VectorBackedLinkedListType::Value&;
+ using PointerType = typename VectorBackedLinkedListType::Value*;
+ using const_iterator =
+ VectorBackedLinkedListConstIterator<VectorBackedLinkedListType>;
+
+ public:
+ ReferenceType operator*() const { return *Get(); }
+ PointerType operator->() const { return Get(); }
+
+ VectorBackedLinkedListIterator& operator++() {
+ ++iterator_;
+ return *this;
+ }
+
+ VectorBackedLinkedListIterator& operator--() {
+ --iterator_;
+ return *this;
+ }
+
+ VectorBackedLinkedListIterator& operator++(int) = delete;
+ VectorBackedLinkedListIterator& operator--(int) = delete;
+
+ bool operator==(const VectorBackedLinkedListIterator& other) const {
+ return iterator_ == other.iterator_;
+ }
+
+ bool operator!=(const VectorBackedLinkedListIterator& other) const {
+ return !(*this == other);
+ }
+
+ operator const_iterator() const { return iterator_; }
+
+ private:
+ VectorBackedLinkedListIterator(wtf_size_t index,
+ VectorBackedLinkedListType* container)
+ : iterator_(index, container) {}
+
+ PointerType Get() const { return const_cast<PointerType>(iterator_.Get()); }
+ wtf_size_t GetIndex() const { return iterator_.GetIndex(); }
+
+ const_iterator iterator_;
+
+ template <typename T, typename Allocator>
+ friend class VectorBackedLinkedList;
+};
+
+template <typename VectorBackedLinkedListType>
+class VectorBackedLinkedListConstIterator {
+ DISALLOW_NEW();
+ using ReferenceType = const typename VectorBackedLinkedListType::Value&;
+ using PointerType = const typename VectorBackedLinkedListType::Value*;
+ using Node = typename VectorBackedLinkedListType::Node;
+
+ public:
+ PointerType Get() const {
+ DCHECK(container_->IsIndexValid(index_));
+ DCHECK(!container_->IsAnchor(index_));
+ CheckModifications();
+ const Node& node = container_->nodes_[index_];
+ return &node.value_;
+ }
+
+ ReferenceType operator*() const { return *Get(); }
+ PointerType operator->() const { return Get(); }
+
+ wtf_size_t GetIndex() const { return index_; }
+
+ VectorBackedLinkedListConstIterator& operator++() {
+ DCHECK(container_->IsIndexValid(index_));
+ CheckModifications();
+ index_ = container_->nodes_[index_].next_index_;
+ DCHECK(container_->IsIndexValid(index_));
+ return *this;
+ }
+
+ VectorBackedLinkedListConstIterator& operator--() {
+ DCHECK(container_->IsIndexValid(index_));
+ CheckModifications();
+ index_ = container_->nodes_[index_].prev_index_;
+ DCHECK(container_->IsIndexValid(index_));
+ return *this;
+ }
+
+ VectorBackedLinkedListConstIterator operator++(int) = delete;
+ VectorBackedLinkedListConstIterator operator--(int) = delete;
+
+ bool operator==(const VectorBackedLinkedListConstIterator& other) const {
+ DCHECK_EQ(container_, other.container_);
+ return index_ == other.index_ && container_ == other.container_;
+ }
+
+ bool operator!=(const VectorBackedLinkedListConstIterator& other) const {
+ return !(*this == other);
+ }
+
+ protected:
+ VectorBackedLinkedListConstIterator(
+ wtf_size_t index,
+ const VectorBackedLinkedListType* container)
+ : index_(index),
+ container_(container)
+#if DCHECK_IS_ON()
+ ,
+ container_modifications_(container->modifications_)
+#endif
+ {
+ DCHECK(container_->IsIndexValid(index_));
+ }
+
+ private:
+ wtf_size_t index_;
+ const VectorBackedLinkedListType* container_;
+#if DCHECK_IS_ON()
+ void CheckModifications() const {
+ container_->CheckModifications(container_modifications_);
+ }
+ int64_t container_modifications_;
+#else
+ void CheckModifications() const {}
+#endif
+
+ template <typename T, typename Allocator>
+ friend class VectorBackedLinkedList;
+ friend class VectorBackedLinkedListIterator<VectorBackedLinkedListType>;
+};
+
+template <typename VectorBackedLinkedListType>
+class VectorBackedLinkedListReverseIterator {
+ using ReferenceType = typename VectorBackedLinkedListType::Value&;
+ using PointerType = typename VectorBackedLinkedListType::Value*;
+ using const_reverse_iterator =
+ VectorBackedLinkedListConstReverseIterator<VectorBackedLinkedListType>;
+
+ public:
+ ReferenceType operator*() const { return *Get(); }
+ PointerType operator->() const { return Get(); }
+
+ VectorBackedLinkedListReverseIterator& operator++() {
+ ++iterator_;
+ return *this;
+ }
+
+ VectorBackedLinkedListReverseIterator& operator--() {
+ --iterator_;
+ return *this;
+ }
+
+ VectorBackedLinkedListReverseIterator& operator++(int) = delete;
+ VectorBackedLinkedListReverseIterator& operator--(int) = delete;
+
+ bool operator==(const VectorBackedLinkedListReverseIterator& other) const {
+ return iterator_ == other.iterator_;
+ }
+
+ bool operator!=(const VectorBackedLinkedListReverseIterator& other) const {
+ return !(*this == other);
+ }
+
+ operator const_reverse_iterator() const { return iterator_; }
+
+ private:
+ VectorBackedLinkedListReverseIterator(wtf_size_t index,
+ VectorBackedLinkedListType* container)
+ : iterator_(index, container) {}
+
+ PointerType Get() const { return const_cast<PointerType>(iterator_.Get()); }
+ wtf_size_t GetIndex() const { return iterator_.GetIndex(); }
+
+ const_reverse_iterator iterator_;
+
+ template <typename T, typename Allocator>
+ friend class VectorBackedLinkedList;
+};
+
+template <typename VectorBackedLinkedListType>
+class VectorBackedLinkedListConstReverseIterator
+ : public VectorBackedLinkedListConstIterator<VectorBackedLinkedListType> {
+ using Superclass =
+ VectorBackedLinkedListConstIterator<VectorBackedLinkedListType>;
+
+ public:
+ VectorBackedLinkedListConstReverseIterator& operator++() {
+ Superclass::operator--();
+ return *this;
+ }
+
+ VectorBackedLinkedListConstReverseIterator& operator--() {
+ Superclass::operator++();
+ return *this;
+ }
+
+ VectorBackedLinkedListConstReverseIterator operator++(int) = delete;
+ VectorBackedLinkedListConstReverseIterator operator--(int) = delete;
+
+ private:
+ VectorBackedLinkedListConstReverseIterator(
+ wtf_size_t index,
+ const VectorBackedLinkedListType* container)
+ : Superclass(index, container) {}
+
+ template <typename T, typename Allocator>
+ friend class VectorBackedLinkedList;
+ friend class VectorBackedLinkedListReverseIterator<
+ VectorBackedLinkedListType>;
+};
+
+template <typename T, typename Allocator>
+VectorBackedLinkedList<T, Allocator>::VectorBackedLinkedList() {
+ // First inserts anchor, which serves as the beginning and the end of
+ // the used list.
+ nodes_.push_back(Node(anchor_index_, anchor_index_));
+}
+
+template <typename T, typename Allocator>
+inline void VectorBackedLinkedList<T, Allocator>::swap(
+ VectorBackedLinkedList& other) {
+ nodes_.swap(other.nodes_);
+ std::swap(free_head_index_, other.free_head_index_);
+ std::swap(size_, other.size_);
+#if DCHECK_IS_ON()
+ std::swap(modifications_, other.modifications_);
+#endif
+}
+
+template <typename T, typename Allocator>
+T& VectorBackedLinkedList<T, Allocator>::front() {
+ DCHECK(!empty());
+ return nodes_[UsedFirstIndex()].value_;
+}
+
+template <typename T, typename Allocator>
+const T& VectorBackedLinkedList<T, Allocator>::front() const {
+ DCHECK(!empty());
+ return nodes_[UsedFirstIndex()].value_;
+}
+
+template <typename T, typename Allocator>
+T& VectorBackedLinkedList<T, Allocator>::back() {
+ DCHECK(!empty());
+ return nodes_[UsedLastIndex()].value_;
+}
+
+template <typename T, typename Allocator>
+const T& VectorBackedLinkedList<T, Allocator>::back() const {
+ DCHECK(!empty());
+ return nodes_[UsedLastIndex()].value_;
+}
+
+template <typename T, typename Allocator>
+template <typename IncomingValueType>
+typename VectorBackedLinkedList<T, Allocator>::iterator
+VectorBackedLinkedList<T, Allocator>::insert(const_iterator position,
+ IncomingValueType&& value) {
+ RegisterModification();
+ wtf_size_t position_index = position.GetIndex();
+ wtf_size_t prev_index = nodes_[position_index].prev_index_;
+
+ wtf_size_t new_entry_index;
+ if (IsFreeListEmpty()) {
+ new_entry_index = nodes_.size();
+ nodes_.push_back(Node(prev_index, position_index,
+ std::forward<IncomingValueType>(value)));
+ } else {
+ new_entry_index = free_head_index_;
+ Node& free_head = nodes_[free_head_index_];
+ free_head_index_ = free_head.next_index_;
+ free_head = Node(prev_index, position_index,
+ std::forward<IncomingValueType>(value));
+ }
+ nodes_[prev_index].next_index_ = new_entry_index;
+ nodes_[position_index].prev_index_ = new_entry_index;
+ size_++;
+ return iterator(new_entry_index, this);
+}
+
+template <typename T, typename Allocator>
+typename VectorBackedLinkedList<T, Allocator>::iterator
+VectorBackedLinkedList<T, Allocator>::MoveTo(const_iterator target,
+ const_iterator new_position) {
+ DCHECK(target != end());
+ RegisterModification();
+
+ wtf_size_t target_index = target.GetIndex();
+ if (target == new_position)
+ return MakeIterator(target_index);
+
+ Node& target_node = nodes_[target_index];
+ wtf_size_t new_position_index = new_position.GetIndex();
+ Node& new_position_node = nodes_[new_position_index];
+ wtf_size_t prev_index = new_position_node.prev_index_;
+
+ if (prev_index == target_index)
+ return MakeIterator(target_index);
+
+ Unlink(target_node);
+
+ nodes_[prev_index].next_index_ = target_index;
+ new_position_node.prev_index_ = target_index;
+ target_node.prev_index_ = prev_index;
+ target_node.next_index_ = new_position_index;
+ return MakeIterator(target_index);
+}
+
+template <typename T, typename Allocator>
+typename VectorBackedLinkedList<T, Allocator>::iterator
+VectorBackedLinkedList<T, Allocator>::erase(const_iterator position) {
+ DCHECK(position != end());
+ RegisterModification();
+ wtf_size_t position_index = position.GetIndex();
+ Node& node = nodes_[position_index];
+ wtf_size_t next_index = node.next_index_;
+
+ Unlink(node);
+ node.value_ = HashTraits<T>::EmptyValue();
+
+ node.next_index_ = free_head_index_;
+ node.prev_index_ = kNotFound;
+ free_head_index_ = position_index;
+
+ size_--;
+ return iterator(next_index, this);
+}
+
+template <typename T, typename Allocator>
+void VectorBackedLinkedList<T, Allocator>::Unlink(const Node& node) {
+ wtf_size_t prev_index = node.prev_index_;
+ wtf_size_t next_index = node.next_index_;
+
+ Node& prev_node = nodes_[prev_index];
+ Node& next_node = nodes_[next_index];
+
+ prev_node.next_index_ = next_index;
+ next_node.prev_index_ = prev_index;
+}
+
+} // namespace WTF
+
+using WTF::VectorBackedLinkedList;
+
+#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_VECTOR_BACKED_LINKED_LIST_H_
diff --git a/chromium/third_party/blink/renderer/platform/wtf/vector_backed_linked_list_test.cc b/chromium/third_party/blink/renderer/platform/wtf/vector_backed_linked_list_test.cc
new file mode 100644
index 00000000000..4d7b743c02b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/wtf/vector_backed_linked_list_test.cc
@@ -0,0 +1,508 @@
+// 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/wtf/vector_backed_linked_list.h"
+
+#include "base/memory/ptr_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/wtf_test_helper.h"
+
+namespace WTF {
+
+TEST(VectorBackedLinkedListTest, Insert) {
+ using List = VectorBackedLinkedList<int>;
+ List list;
+
+ EXPECT_TRUE(list.empty());
+ EXPECT_TRUE(list.begin() == list.end());
+ list.insert(list.end(), 1);
+ list.insert(list.begin(), -2);
+ list.insert(list.end(), 2);
+
+ List::iterator it = list.begin();
+ EXPECT_EQ(*it, -2);
+ ++it;
+ EXPECT_EQ(*it, 1);
+ ++it;
+ EXPECT_EQ(*it, 2);
+
+ it = list.insert(++list.begin(), 0);
+ list.insert(it, -1);
+
+ EXPECT_EQ(list.front(), -2);
+ EXPECT_EQ(list.back(), 2);
+ EXPECT_EQ(list.size(), 5u);
+
+ int i = -2;
+ for (auto element : list) {
+ EXPECT_EQ(element, i);
+ i++;
+ }
+}
+
+TEST(VectorBackedLinkedList, PushFront) {
+ using List = VectorBackedLinkedList<int>;
+ List list;
+
+ EXPECT_TRUE(list.empty());
+ list.push_front(3);
+ EXPECT_EQ(list.front(), 3);
+ list.push_front(2);
+ EXPECT_EQ(list.front(), 2);
+ list.push_front(1);
+ EXPECT_EQ(list.front(), 1);
+
+ int i = 1;
+ for (auto element : list) {
+ EXPECT_EQ(element, i);
+ i++;
+ }
+}
+
+TEST(VectorBackedLinkedList, PushBack) {
+ using List = VectorBackedLinkedList<int>;
+ List list;
+
+ EXPECT_TRUE(list.empty());
+ list.push_back(1);
+ EXPECT_EQ(list.back(), 1);
+ list.push_back(2);
+ EXPECT_EQ(list.back(), 2);
+ list.push_back(3);
+ EXPECT_EQ(list.back(), 3);
+
+ int i = 1;
+ for (auto element : list) {
+ EXPECT_EQ(element, i);
+ i++;
+ }
+}
+
+TEST(VectorBackedLinkedList, MoveTo) {
+ using List = VectorBackedLinkedList<int>;
+ List list;
+
+ list.push_back(1);
+ list.MoveTo(list.begin(), list.end());
+ List::iterator it = list.begin();
+ EXPECT_EQ(*it, 1);
+ list.push_back(2);
+ list.push_back(3);
+
+ List::iterator target = list.begin();
+ list.MoveTo(target, list.end()); // {2, 3, 1}
+
+ it = list.begin();
+ EXPECT_EQ(*it, 2);
+ ++it;
+ EXPECT_EQ(*it, 3);
+ ++it;
+ EXPECT_EQ(*it, 1);
+ --it;
+
+ target = it;
+ list.MoveTo(target, list.begin()); // {3, 2, 1}
+ it = list.begin();
+ EXPECT_EQ(*it, 3);
+ ++it;
+ EXPECT_EQ(*it, 2);
+ ++it;
+ EXPECT_EQ(*it, 1);
+
+ target = it;
+ list.MoveTo(target, --it); // {3, 1, 2}
+ it = list.begin();
+ EXPECT_EQ(*it, 3);
+ ++it;
+ EXPECT_EQ(*it, 1);
+ ++it;
+ EXPECT_EQ(*it, 2);
+
+ list.MoveTo(list.begin(), list.begin());
+ it = list.begin();
+ EXPECT_EQ(*it, 3);
+ ++it;
+ EXPECT_EQ(*it, 1);
+ ++it;
+ EXPECT_EQ(*it, 2);
+
+ target = list.begin();
+ List::iterator position = ++list.begin();
+ list.MoveTo(target, position);
+ it = list.begin();
+ EXPECT_EQ(*it, 3);
+ ++it;
+ EXPECT_EQ(*it, 1);
+ ++it;
+ EXPECT_EQ(*it, 2);
+}
+
+TEST(VectorBackedLinkedList, Erase) {
+ using List = VectorBackedLinkedList<int>;
+ List list;
+
+ List::iterator it = list.insert(list.end(), 1);
+ EXPECT_EQ(*it, 1);
+ list.push_back(2);
+ list.push_back(3);
+ list.push_back(4);
+ list.push_back(5);
+ EXPECT_EQ(list.size(), 5u);
+
+ int i = 1;
+ for (auto element : list) {
+ EXPECT_EQ(element, i);
+ i++;
+ }
+
+ List::iterator target = list.begin();
+ ++target;
+ it = list.erase(target); // list = {1, 3, 4, 5}
+ EXPECT_EQ(*it, 3);
+ EXPECT_EQ(list.size(), 4u);
+ it = list.erase(++it); // list = {1, 3, 5}
+ EXPECT_EQ(*it, 5);
+ EXPECT_EQ(list.size(), 3u);
+
+ it = list.erase(list.begin()); // list = {3, 5}
+ EXPECT_EQ(*it, 3);
+ EXPECT_EQ(list.size(), 2u);
+
+ it = list.begin();
+ EXPECT_EQ(*it, 3);
+ ++it;
+ EXPECT_EQ(*it, 5);
+ ++it;
+ EXPECT_TRUE(it == list.end());
+
+ list.push_back(6);
+ EXPECT_EQ(list.front(), 3);
+ EXPECT_EQ(list.back(), 6);
+}
+
+TEST(VectorBackedLinkedList, PopFront) {
+ using List = VectorBackedLinkedList<int>;
+ List list;
+
+ list.push_back(1);
+ list.push_back(2);
+ list.push_back(3);
+
+ int i = 1;
+ for (auto element : list) {
+ EXPECT_EQ(element, i);
+ i++;
+ }
+
+ list.pop_front();
+ EXPECT_EQ(list.front(), 2);
+ EXPECT_EQ(list.back(), 3);
+ EXPECT_EQ(list.size(), 2u);
+
+ list.pop_front();
+ EXPECT_EQ(list.front(), 3);
+ EXPECT_EQ(list.back(), 3);
+ EXPECT_EQ(list.size(), 1u);
+
+ list.pop_front();
+ EXPECT_TRUE(list.empty());
+}
+
+TEST(VectorBackedLinkedList, PopBack) {
+ using List = VectorBackedLinkedList<int>;
+ List list;
+
+ list.push_back(1);
+ list.push_back(2);
+ list.push_back(3);
+
+ list.pop_back();
+ EXPECT_EQ(list.front(), 1);
+ EXPECT_EQ(list.back(), 2);
+ EXPECT_EQ(list.size(), 2u);
+
+ list.pop_back();
+ EXPECT_EQ(list.front(), 1);
+ EXPECT_EQ(list.back(), 1);
+ EXPECT_EQ(list.size(), 1u);
+
+ list.pop_back();
+ EXPECT_TRUE(list.empty());
+}
+
+TEST(VectorBackedLinkedList, Clear) {
+ using List = VectorBackedLinkedList<int>;
+ List list;
+
+ list.push_back(1);
+ list.push_back(2);
+ list.push_back(3);
+
+ EXPECT_EQ(list.size(), 3u);
+
+ list.clear();
+ EXPECT_EQ(list.size(), 0u);
+ EXPECT_TRUE(list.empty());
+
+ EXPECT_TRUE(list.begin() == list.end());
+ list.push_back(1);
+ EXPECT_EQ(list.front(), 1);
+ EXPECT_EQ(list.back(), 1);
+ EXPECT_EQ(list.size(), 1u);
+}
+
+TEST(VectorBackedLinkedList, Iterator) {
+ using List = VectorBackedLinkedList<int>;
+ List list;
+
+ list.push_back(1);
+ list.push_back(2);
+ list.push_back(3);
+
+ List::iterator it = list.begin();
+
+ EXPECT_EQ(*it, 1);
+ ++it;
+ EXPECT_EQ(*it, 2);
+ ++it;
+ EXPECT_EQ(*it, 3);
+ *it = 4; // list: {1, 2, 4}
+ EXPECT_EQ(list.back(), 4);
+ ++it;
+ EXPECT_TRUE(it == list.end());
+ --it;
+ --it;
+ --it;
+ EXPECT_TRUE(it == list.begin());
+ EXPECT_EQ(list.front(), 1);
+ *it = 0;
+ EXPECT_EQ(list.front(), 0); // list: {0, 2, 4}
+
+ List::reverse_iterator rit = list.rbegin();
+
+ EXPECT_EQ(*rit, 4);
+ ++rit;
+ EXPECT_EQ(*rit, 2);
+ ++rit;
+ EXPECT_EQ(*rit, 0);
+ EXPECT_FALSE(rit == list.rend());
+ *rit = 1; // list: {1, 2, 4}
+ EXPECT_EQ(list.front(), 1);
+ ++rit;
+ EXPECT_TRUE(rit == list.rend());
+ --rit;
+ EXPECT_EQ(*rit, 1);
+}
+
+TEST(VectorBackedLinkedList, ConstIterator) {
+ using List = VectorBackedLinkedList<int>;
+ List list;
+
+ list.push_back(1);
+ list.push_back(2);
+ list.push_back(3);
+
+ List::const_iterator cit = list.cbegin();
+
+ EXPECT_EQ(*cit, 1);
+ ++cit;
+ EXPECT_EQ(*cit, 2);
+ ++cit;
+ EXPECT_EQ(*cit, 3);
+ ++cit;
+ EXPECT_TRUE(cit == list.cend());
+ --cit;
+ --cit;
+ --cit;
+ EXPECT_TRUE(cit == list.cbegin());
+ EXPECT_EQ(list.front(), 1);
+
+ List::const_reverse_iterator crit = list.crbegin();
+
+ EXPECT_EQ(*crit, 3);
+ ++crit;
+ EXPECT_EQ(*crit, 2);
+ ++crit;
+ EXPECT_EQ(*crit, 1);
+ ++crit;
+ EXPECT_TRUE(crit == list.crend());
+ --crit;
+ EXPECT_EQ(*crit, 1);
+}
+
+TEST(VectorBackedLinkedList, String) {
+ using List = VectorBackedLinkedList<String>;
+ List list;
+
+ EXPECT_TRUE(list.empty());
+
+ list.push_back("b");
+ list.push_front("a");
+ list.push_back("c");
+
+ EXPECT_EQ(list.front(), "a");
+ EXPECT_EQ(list.back(), "c");
+ EXPECT_EQ(list.size(), 3u);
+
+ List::iterator it = list.begin();
+ EXPECT_EQ(*it, "a");
+ ++it;
+ EXPECT_EQ(*it, "b");
+ List::iterator target = it;
+ ++it;
+ EXPECT_EQ(*it, "c");
+ ++it;
+ EXPECT_TRUE(it == list.end());
+ --it;
+ EXPECT_EQ(*it, "c");
+ --it;
+ --it;
+ EXPECT_TRUE(it == list.begin());
+
+ list.erase(target);
+ it = list.begin();
+ EXPECT_EQ(*it, "a");
+ ++it;
+ EXPECT_EQ(*it, "c");
+ ++it;
+ EXPECT_TRUE(it == list.end());
+
+ list.pop_back();
+ EXPECT_EQ(list.front(), "a");
+ EXPECT_EQ(list.back(), "a");
+ EXPECT_EQ(list.size(), 1u);
+
+ list.push_front("c");
+ it = list.begin();
+ EXPECT_EQ(*it, "c");
+ ++it;
+ EXPECT_EQ(*it, "a");
+ ++it;
+ EXPECT_TRUE(it == list.end());
+
+ list.clear();
+ EXPECT_TRUE(list.empty());
+ EXPECT_TRUE(list.begin() == list.end());
+
+ list.push_front("a");
+ EXPECT_EQ(list.size(), 1u);
+ EXPECT_EQ(list.front(), "a");
+ list.pop_back();
+ EXPECT_TRUE(list.empty());
+}
+
+TEST(VectorBackedLinkedList, UniquePtr) {
+ using List = VectorBackedLinkedList<std::unique_ptr<Dummy>>;
+ List list;
+
+ bool deleted1 = false, deleted2 = false, deleted3 = false;
+ std::unique_ptr<Dummy> ptr1 = std::make_unique<Dummy>(deleted1);
+ std::unique_ptr<Dummy> ptr2 = std::make_unique<Dummy>(deleted2);
+ std::unique_ptr<Dummy> ptr3 = std::make_unique<Dummy>(deleted3);
+
+ Dummy* raw_ptr1 = ptr1.get();
+ Dummy* raw_ptr2 = ptr2.get();
+ Dummy* raw_ptr3 = ptr3.get();
+
+ list.push_front(std::move(ptr1));
+ list.push_back(std::move(ptr3));
+ List::iterator it = list.begin();
+ ++it;
+ it = list.insert(it, std::move(ptr2));
+ EXPECT_EQ(it->get(), raw_ptr2);
+
+ EXPECT_EQ(list.size(), 3u);
+ EXPECT_EQ((list.front()).get(), raw_ptr1);
+ EXPECT_EQ((list.back()).get(), raw_ptr3);
+
+ it = list.begin();
+ EXPECT_EQ(it->get(), raw_ptr1);
+ ++it;
+ EXPECT_EQ(it->get(), raw_ptr2);
+ List::iterator target = it;
+ ++it;
+ EXPECT_EQ(it->get(), raw_ptr3);
+ ++it;
+ EXPECT_TRUE(it == list.end());
+ --it;
+ EXPECT_EQ(it->get(), raw_ptr3);
+ --it;
+ --it;
+ EXPECT_TRUE(it == list.begin());
+
+ list.erase(target);
+ EXPECT_FALSE(deleted1);
+ EXPECT_TRUE(deleted2);
+ EXPECT_FALSE(deleted3);
+ EXPECT_EQ(list.size(), 2u);
+ it = list.begin();
+ EXPECT_EQ(it->get(), raw_ptr1);
+ ++it;
+ EXPECT_EQ(it->get(), raw_ptr3);
+ ++it;
+ EXPECT_TRUE(it == list.end());
+
+ list.pop_front();
+ EXPECT_TRUE(deleted1);
+ EXPECT_TRUE(deleted2);
+ EXPECT_FALSE(deleted3);
+ EXPECT_EQ(list.size(), 1u);
+ it = list.begin();
+ EXPECT_EQ(it->get(), raw_ptr3);
+ ++it;
+ EXPECT_TRUE(it == list.end());
+
+ list.pop_back();
+ EXPECT_TRUE(deleted1);
+ EXPECT_TRUE(deleted2);
+ EXPECT_TRUE(deleted3);
+ EXPECT_TRUE(list.empty());
+
+ bool deleted4 = false, deleted5 = false, deleted6 = false;
+ std::unique_ptr<Dummy> ptr4 = std::make_unique<Dummy>(deleted4);
+ std::unique_ptr<Dummy> ptr5 = std::make_unique<Dummy>(deleted5);
+ std::unique_ptr<Dummy> ptr6 = std::make_unique<Dummy>(deleted6);
+
+ Dummy* raw_ptr4 = ptr4.get();
+ Dummy* raw_ptr5 = ptr5.get();
+ Dummy* raw_ptr6 = ptr6.get();
+
+ list.push_back(std::move(ptr4));
+ list.push_back(std::move(ptr5));
+ list.push_back(std::move(ptr6));
+
+ it = list.end();
+ --it;
+ list.MoveTo(list.begin(), it);
+ it = list.begin();
+ EXPECT_EQ(it->get(), raw_ptr5);
+ ++it;
+ EXPECT_EQ(it->get(), raw_ptr4);
+ ++it;
+ EXPECT_EQ(it->get(), raw_ptr6);
+
+ list.MoveTo(list.begin(), list.begin());
+ it = list.begin();
+ EXPECT_EQ(it->get(), raw_ptr5);
+ ++it;
+ EXPECT_EQ(it->get(), raw_ptr4);
+ ++it;
+ EXPECT_EQ(it->get(), raw_ptr6);
+
+ EXPECT_FALSE(deleted4);
+ EXPECT_FALSE(deleted5);
+ EXPECT_FALSE(deleted6);
+
+ list.clear();
+ EXPECT_TRUE(list.empty());
+ EXPECT_EQ(list.size(), 0u);
+
+ EXPECT_TRUE(deleted4);
+ EXPECT_TRUE(deleted5);
+ EXPECT_TRUE(deleted6);
+}
+
+} // namespace WTF
diff --git a/chromium/third_party/blink/renderer/platform/wtf/vector_test.cc b/chromium/third_party/blink/renderer/platform/wtf/vector_test.cc
index 788cc2bb12d..1e5fd403ed8 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/vector_test.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/vector_test.cc
@@ -101,22 +101,34 @@ TEST(VectorTest, EraseAtIndex) {
}
TEST(VectorTest, Erase) {
- Vector<int> int_vector({0, 1, 2, 3});
+ Vector<int> int_vector({0, 1, 2, 3, 4, 5});
- EXPECT_EQ(4u, int_vector.size());
+ EXPECT_EQ(6u, int_vector.size());
EXPECT_EQ(0, int_vector[0]);
EXPECT_EQ(1, int_vector[1]);
EXPECT_EQ(2, int_vector[2]);
EXPECT_EQ(3, int_vector[3]);
+ EXPECT_EQ(4, int_vector[4]);
+ EXPECT_EQ(5, int_vector[5]);
auto* first = int_vector.erase(int_vector.begin());
- EXPECT_EQ(3u, int_vector.size());
+ EXPECT_EQ(5u, int_vector.size());
EXPECT_EQ(1, *first);
EXPECT_EQ(int_vector.begin(), first);
- auto* last = std::lower_bound(int_vector.begin(), int_vector.end(), 3);
+ auto* last = std::lower_bound(int_vector.begin(), int_vector.end(), 5);
auto* end = int_vector.erase(last);
+ EXPECT_EQ(4u, int_vector.size());
+ EXPECT_EQ(int_vector.end(), end);
+
+ auto* item2 = std::lower_bound(int_vector.begin(), int_vector.end(), 2);
+ auto* item4 = int_vector.erase(item2, item2 + 2);
EXPECT_EQ(2u, int_vector.size());
+ EXPECT_EQ(4, *item4);
+
+ last = std::lower_bound(int_vector.begin(), int_vector.end(), 4);
+ end = int_vector.erase(last, int_vector.end());
+ EXPECT_EQ(1u, int_vector.size());
EXPECT_EQ(int_vector.end(), end);
}
diff --git a/chromium/third_party/blink/renderer/platform/wtf/wtf.cc b/chromium/third_party/blink/renderer/platform/wtf/wtf.cc
index c98254eec1d..c928e55082b 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/wtf.cc
+++ b/chromium/third_party/blink/renderer/platform/wtf/wtf.cc
@@ -45,23 +45,13 @@
namespace WTF {
bool g_initialized;
-void (*g_call_on_main_thread_function)(MainThreadFunction, void*);
base::PlatformThreadId g_main_thread_identifier;
-namespace internal {
-
-void CallOnMainThread(MainThreadFunction* function, void* context) {
- (*g_call_on_main_thread_function)(function, context);
-}
-
-} // namespace internal
-
bool IsMainThread() {
return CurrentThread() == g_main_thread_identifier;
}
-void Initialize(void (*call_on_main_thread_function)(MainThreadFunction,
- void*)) {
+void Initialize() {
// WTF, and Blink in general, cannot handle being re-initialized.
// Make that explicit here.
CHECK(!g_initialized);
@@ -75,7 +65,6 @@ void Initialize(void (*call_on_main_thread_function)(MainThreadFunction,
double_conversion::DoubleToStringConverter::EcmaScriptConverter();
internal::GetDoubleConverter();
- g_call_on_main_thread_function = call_on_main_thread_function;
internal::InitializeMainThreadStackEstimate();
AtomicString::Init();
StringStatics::Init();
diff --git a/chromium/third_party/blink/renderer/platform/wtf/wtf.h b/chromium/third_party/blink/renderer/platform/wtf/wtf.h
index 5bd960aa773..418cfca41eb 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/wtf.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/wtf.h
@@ -36,18 +36,13 @@
namespace WTF {
-typedef void MainThreadFunction(void*);
WTF_EXPORT extern base::PlatformThreadId g_main_thread_identifier;
// This function must be called exactly once from the main thread before using
// anything else in WTF.
-WTF_EXPORT void Initialize(void (*)(MainThreadFunction, void*));
+WTF_EXPORT void Initialize();
WTF_EXPORT bool IsMainThread();
-namespace internal {
-void CallOnMainThread(MainThreadFunction*, void* context);
-} // namespace internal
-
} // namespace WTF
using WTF::IsMainThread;
diff --git a/chromium/third_party/blink/renderer/platform/wtf/wtf_test_helper.h b/chromium/third_party/blink/renderer/platform/wtf/wtf_test_helper.h
index 8f31365dcd0..35b1e73c81f 100644
--- a/chromium/third_party/blink/renderer/platform/wtf/wtf_test_helper.h
+++ b/chromium/third_party/blink/renderer/platform/wtf/wtf_test_helper.h
@@ -5,6 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_WTF_TEST_HELPER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_WTF_TEST_HELPER_H_
+#include <type_traits>
+
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -177,6 +179,75 @@ struct DefaultHash<CountCopy> {
using Hash = CountCopyHash;
};
+template <typename T>
+class ValueInstanceCount final {
+ public:
+ ValueInstanceCount() : counter_(nullptr), value_(T()) {}
+ explicit ValueInstanceCount(int* counter, T value = T())
+ : counter_(counter), value_(value) {
+ DCHECK(counter_);
+ *counter = 1;
+ }
+ ValueInstanceCount(const ValueInstanceCount& other)
+ : counter_(other.counter_), value_(other.value_) {
+ if (counter_)
+ ++*counter_;
+ }
+ ValueInstanceCount& operator=(const ValueInstanceCount& other) {
+ counter_ = other.counter_;
+ value_ = other.value_;
+ if (counter_)
+ ++*counter_;
+ return *this;
+ }
+ ~ValueInstanceCount() {
+ if (counter_)
+ --*counter_;
+ }
+
+ const int* Counter() const { return counter_; }
+ const T& Value() const { return value_; }
+
+ private:
+ int* counter_;
+ T value_;
+};
+
+template <typename T>
+struct ValueInstanceCountHashTraits
+ : public GenericHashTraits<ValueInstanceCount<T>> {
+ static const bool kEmptyValueIsZero = false;
+ static const bool kHasIsEmptyValueFunction = true;
+ static bool IsEmptyValue(const ValueInstanceCount<T>& value) {
+ return !value.Counter();
+ }
+ static void ConstructDeletedValue(ValueInstanceCount<T>& slot, bool) {}
+ static bool IsDeletedValue(const ValueInstanceCount<T>& value) {
+ return false;
+ }
+};
+
+template <typename T>
+struct ValueInstanceCountHash : public PtrHash<const int*> {
+ static unsigned GetHash(const ValueInstanceCount<T>& value) {
+ return PtrHash<const int>::GetHash(value.Counter());
+ }
+ static bool Equal(const ValueInstanceCount<T>& left,
+ const ValueInstanceCount<T>& right) {
+ return PtrHash<const int>::Equal(left.Counter(), right.Counter());
+ }
+ static const bool safe_to_compare_to_empty_or_deleted = true;
+};
+
+template <typename T>
+struct HashTraits<ValueInstanceCount<T>>
+ : public ValueInstanceCountHashTraits<T> {};
+
+template <typename T>
+struct DefaultHash<ValueInstanceCount<T>> {
+ using Hash = ValueInstanceCountHash<T>;
+};
+
class DummyRefCounted : public RefCounted<DummyRefCounted> {
public:
DummyRefCounted(bool& is_deleted) : is_deleted_(is_deleted) {